Index: /gsdl/stable/.gstermrc
===================================================================
--- /gsdl/stable/.gstermrc	(revision 20131)
+++ /gsdl/stable/.gstermrc	(revision 20131)
@@ -0,0 +1,16 @@
+source ~/.bashrc
+function ncd {
+	if  [ "$1" == "" ]; then
+		if [ "$GSDLHOME" != "" ]; then
+			cd $GSDLHOME
+		fi
+	else
+		cd "$*"
+	fi
+
+	PS1=$(echo $PWD|sed "s!$GSDLHOME!Greenstone!")'> '
+}
+alias cd=ncd
+
+cd $GSDLHOME
+
Index: /gsdl/stable/GSI-Makefile
===================================================================
--- /gsdl/stable/GSI-Makefile	(revision 20131)
+++ /gsdl/stable/GSI-Makefile	(revision 20131)
@@ -0,0 +1,61 @@
+###########################################################################
+#
+# GSI-Makefile -- Greenstone Server Interface makefile
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# execute as: make -f GSI-Makefile <command>
+# where command is any of the following make targets
+
+test-gsdlhome:
+	./gsicontrol.sh test-gsdlhome:
+
+configure-cgi:
+	./gsicontrol.sh configure-cgi
+
+configure-admin:
+	./gsicontrol.sh configure-admin
+
+configure-apache:
+	./gsicontrol.sh configure-apache
+
+configure-web:
+	./gsicontrol.sh configure-web
+
+web-status:
+	./gsicontrol.sh web-status
+
+web-start:
+	./gsicontrol.sh web-start
+
+web-restart:
+	./gsicontrol.sh web-restart
+
+web-graceful:
+	./gsicontrol.sh graceful
+
+web-stop-tested:
+	./gsicontrol.sh web-stop-tested
+
+web-stop:
+	./gsicontrol.sh web-stop
Index: /gsdl/stable/Install.txt
===================================================================
--- /gsdl/stable/Install.txt	(revision 20131)
+++ /gsdl/stable/Install.txt	(revision 20131)
@@ -0,0 +1,92 @@
+Note: more up-to-date notes may be available on our website, at
+ http://wiki.greenstone.org/wiki/index.php/Installing_Greenstone
+
+The following instructions assume the top level Greenstone folder is called
+Greenstone (which is the standard name used for Greenstone 2 releases). 
+If you have got Greenstone from SVN, the top level directory will be gsdl. 
+
+The Greenstone Librarian Interface (GLI) code will be in the gli folder inside
+the Greenstone folder. If you are using SVN and you want to use the GLI to 
+build collections, you'll need to check it out by running
+ svn checkout http://svn.greenstone.org/gli/trunk gli
+in the Greenstone folder.
+
+-- Compiling and installing on Unix --
+
+cd to the top level Greenstone directory (i.e. the directory 
+where this file lives) and perform the following three steps.
+
+1. ./configure
+2. make
+3. make install
+
+This will install the library.cgi and oaiserver.cgi executables to 
+Greenstone/cgi-bin. 
+If you want to run Greenstone from a system 
+cgi-bin directory you'll need to move the library executable and 
+gsdlsite.cfg from Greenstone/cgi-bin to your system cgi-bin.
+
+Note that the Greenstone directory structure is important to the operation
+of the software. Therefore the --prefix, --bindir etc. options to configure
+make no sense and will have no effect. If you want Greenstone to be
+installed somewhere specific (say /usr/local) you'll need to move the
+entire Greenstone directory there.
+
+You'll need to install Apache and set it up to serve Greenstone. Then you'll need to edit Greenstone/cgi-bin/gsdlsite.cfg. See 
+http://wiki.greenstone.org/wiki/index.php/Setting_up_an_Apache_Web_Server_for_Greenstone_2_Walkthrough
+for more details.  
+
+To compile the GLI, cd to the gli directory and run makegli.sh
+
+-- Compiling on Windows --
+
+Greenstone has been successfully compiled using Microsoft Visual C++
+versions 4.2, 6.0 and 2005. If anyone succeeds in compiling Greenstone with
+another compiler (or another version of VC++) we'd appreciate hearing about
+it at greenstone-devel@list.scms.waikato.ac.nz
+
+The major difference between compiling with VC++ 4.2 compared with 
+VC++ 6.0/2005 is that 4.2 must use the STLport standard template library 
+(packaged with Greenstone) while VC++ 6.0/2005 may use its own built in 
+STL implementation.
+
+Perform the following steps to compile and install Greenstone. Note that
+some parts of the process described are specific to one or other of the two
+compilation options mentioned above. These steps are marked as such.
+
+1. Unzip the following zip archives (into the directories in which the
+   zip files themselves are contained).
+
+   * Greenstone\common-src\indexers\packages\windows\iconv\iconv.zip
+   * Greenstone\common-src\packages\windows\gdbm\gdbm.zip
+   * Greenstone\common-src\packages\windows\crypt\crypt.zip
+   * Greenstone\common-src\packages\windows\expat\expat.zip
+   * Greenstone\common-src\packages\windows\stlport\stlport.zip (VC++ 4.2 only)
+
+2. To use VC++ command line tools you may need to execute the
+   MSDEV\BIN\VCVARS32.BAT batch file to set up your environment.
+
+3. cd to the top level Greenstone directory (i.e. the directory where 
+   this file lives).
+
+4. compile the web library (library.cgi) and OAI server (oaiserver.cgi) with
+   "nmake /f win32.mak GSDL_VC4=1" (VC++ 4.2)
+   or
+   "nmake /f win32.mak" (VC++ 6.0/2005)
+
+5. compile the local library (server.exe) with
+   "nmake /f win32.mak GSDL_VC4=1 LOCAL_LIBRARY=1" (VC++ 4.2)
+   or
+   "nmake /f win32.mak LOCAL_LIBRARY=1" (VC++ 6.0/2005)
+
+This will install library.cgi and oaiserver.cgi to the Greenstone\cgi-bin 
+directory and server.exe to the top level Greenstone directory. 
+
+To run the web library you'll need to set up a web server to serve Greenstone. Then you'll need to edit Greenstone\cgi-bin\gsdlsite.cfg. See 
+http://wiki.greenstone.org/wiki/index.php/Setting_up_an_Apache_Web_Server_for_Greenstone_2_Walkthrough
+for more details about using Apache, or 
+http://wiki.greenstone.org/wiki/index.php/Installing_Greenstone#How_do_I_use_Greenstone.27s_web_library_with_IIS.3F
+for more details about using IIS.
+
+To compile the GLI, cd to the gli directory and run makegli.bat.
+
Index: /gsdl/stable/Makefile.in
===================================================================
--- /gsdl/stable/Makefile.in	(revision 20131)
+++ /gsdl/stable/Makefile.in	(revision 20131)
@@ -0,0 +1,119 @@
+###########################################################################
+#
+# Makefile -- gsdl
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+srcdir = @srcdir@
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+@SET_MAKE@
+CC = @CC@
+CXX = @CXX@
+CFLAGS = @CFLAGS@
+CXXFLAGS = @CXXFLAGS@
+LIBS   = @LIBS@
+MDEFINES =
+
+GSDLOS = @gsdlos@
+
+COMPILE = $(CC) -c
+
+SOURCES = 
+
+OBJECTS = 
+
+ALLFILES = $(OBJECTS)
+
+SPECIAL_COMPILEDIRS = common-src
+COMPILEDIRS = build-src runtime-src
+
+SPECIAL_INSTALLDIRS = common-src
+INSTALLDIRS = build-src runtime-src
+
+MODULEDIRS = @MODULEDIRS@
+
+
+# we don't want to compile the jni stuff in indexers for gs2
+all:
+	for odir in $(SPECIAL_COMPILEDIRS); do \
+	echo making gs2 in $$odir; \
+	(cd $$odir && $(MAKE) $(MDEFINES) gs2) || exit 1; \
+	done
+	for odir in $(COMPILEDIRS) $(MODULEDIRS); do \
+	  echo making $@ in $$odir; \
+	  (cd $$odir && $(MAKE) $(MDEFINES) $@) || exit 1; \
+	done
+
+install: all
+	for idir in $(SPECIAL_INSTALLDIRS); do \
+	  echo installing $$idir; \
+	  (cd $$idir && $(MAKE) install-gs2) || exit 1; \
+	done
+	for idir in $(INSTALLDIRS); do \
+	  echo installing $$idir; \
+	  (cd $$idir && $(MAKE) install) || exit 1; \
+	done
+
+apache-for-dist:
+	(cd runtime-src/packages && $(MAKE) apache-for-dist) || exit 1;
+
+# include the Greenstone Server Interface Makefile here
+include GSI-Makefile
+
+distclean: clean
+	rm -f Makefile config.cache config.h config.log stamp-h config.status
+	for subdir in $(SPECIAL_COMPILEDIRS) $(COMPILEDIRS); do \
+	  echo cleaning $@ in $$subdir; \
+	  (cd $$subdir && $(MAKE) distclean) || exit 1; \
+	done
+
+clean:
+	for subdir in $(SPECIAL_COMPILEDIRS) $(COMPILEDIRS); do \
+	  echo cleaning $@ in $$subdir; \
+	  (cd $$subdir && $(MAKE) clean) || exit 1; \
+	done
+
+# commented out - jrm21 Dec 2004 - can get confused by cvs timestamps
+# (and might run the wrong version of autoconf)
+#
+## For an explanation of the following Makefile rules, see node
+## `Automatic Remaking' in GNU Autoconf documentation.
+#Makefile: Makefile.in config.status
+#	CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+#config.status: configure
+#	./config.status --recheck
+#configure: configure.in aclocal.m4
+#	cd $(srcdir) && autoconf
+#
+#config.h: stamp-h
+#stamp-h: config.h.in config.status
+#	CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status
+#config.h.in: stamp-h.in
+#stamp-h.in: configure.in aclocal.m4 acconfig.h
+#	cd $(srcdir) && autoheader
+#	$(TOUCH) $(srcdir)/stamp-h.in
+
+
+
Index: /gsdl/stable/acconfig.h
===================================================================
--- /gsdl/stable/acconfig.h	(revision 20131)
+++ /gsdl/stable/acconfig.h	(revision 20131)
@@ -0,0 +1,50 @@
+/* Special definitions for mg, processed by autoheader.
+   Created by [TS:Aug/95] 
+   by grepping for AC_DEFINE on configure.in and using the appropriate defs 
+   of acconfig.h used by GNU tar.
+*/
+
+/* Define to the name of the distribution.  */
+#undef PACKAGE
+
+/* Define to the version of the distribution.  */
+#undef VERSION
+
+/* Define if `union wait' is the type of the first arg to wait functions.  */
+#undef HAVE_UNION_WAIT
+
+/* Define to 1 if you have the valloc function.  */
+#undef HAVE_VALLOC
+
+/* Define to 1 if ANSI function prototypes are usable.  */
+#undef PROTOTYPES
+ 
+/* Define to 1 for better use of the debugging malloc library.  See
+   site ftp.antaire.com in antaire/src, file dmalloc/dmalloc.tar.gz.  */
+#undef WITH_DMALLOC
+ 
+/* Define to 1 if GNU regex should be used instead of GNU rx.  */
+#undef WITH_REGEX
+
+/* Some braindead header files do not have the requ'd function declarations */
+#undef HAVE_FGETC_DECL
+#undef HAVE_FREAD_DECL
+
+/* See if have this field in the prstatus_t structure */
+/* It stores the size of the process heap */
+#undef HAVE_PR_BRKSIZE
+
+/* Define FASTCGI if needsbe */
+#undef USE_FASTCGI
+
+/* Define USE_CORBA if needsbe */
+#undef USE_CORBA
+
+/* Define MICO_DIR if needsbe */
+#undef MICO_DIR
+
+/* Define MICO_VERSION if required */
+#undef MICO_VERSION
+
+
+
Index: /gsdl/stable/aclocal.m4
===================================================================
--- /gsdl/stable/aclocal.m4	(revision 20131)
+++ /gsdl/stable/aclocal.m4	(revision 20131)
@@ -0,0 +1,140 @@
+# Local additions to Autoconf macros.
+# Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+# François Pinard <pinard@iro.umontreal.ca>, 1992.
+
+# [TS:Aug/95] - chopped out the NLS stuff which I don't support
+
+## ------------------------------- ##
+## Check for function prototypes.  ##
+## ------------------------------- ##
+
+AC_DEFUN(fp_C_PROTOTYPES,
+[AC_REQUIRE([fp_PROG_CC_STDC])
+AC_MSG_CHECKING([for function prototypes])
+if test "$ac_cv_prog_cc_stdc" != no; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(PROTOTYPES)
+  U= ANSI2KNR=
+else
+  AC_MSG_RESULT(no)
+  U=_ ANSI2KNR=ansi2knr
+fi
+AC_SUBST(U)dnl
+AC_SUBST(ANSI2KNR)dnl
+])
+
+## ----------------------------------------- ##
+## ANSIfy the C compiler whenever possible.  ##
+## ----------------------------------------- ##
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so.  This macro tries various
+# options that select ANSI C on some system or another.  It considers the
+# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and
+# handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{ac_cv_prog_cc_stdc} is set to @samp{no}.  If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN(fp_PROG_CC_STDC,
+[AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
+AC_CACHE_VAL(ac_cv_prog_cc_stdc,
+[ac_cv_prog_cc_stdc=no
+ac_save_CFLAGS="$CFLAGS"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX			-Aa -D_HPUX_SOURCE
+# SVR4			-Xc
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" -Xc
+do
+  CFLAGS="$ac_save_CFLAGS $ac_arg"
+  AC_TRY_COMPILE(
+[#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif	
+], [int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};],
+[ac_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CFLAGS="$ac_save_CFLAGS"
+])
+AC_MSG_RESULT($ac_cv_prog_cc_stdc)
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno) ;;
+  *) CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+])
+
+## --------------------------------------------------------- ##
+## Use AC_PROG_INSTALL, supplementing it with INSTALL_SCRIPT ##
+## substitution.					     ##
+## --------------------------------------------------------- ##
+
+AC_DEFUN(fp_PROG_INSTALL,
+[AC_PROG_INSTALL
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL} -m 755'
+AC_SUBST(INSTALL_SCRIPT)dnl
+])
+
+## ----------------------------------- ##
+## Check if --with-dmalloc was given.  ##
+## ----------------------------------- ##
+
+# I just checked, and GNU rx seems to work fine with a slightly
+# modified GNU m4.  So, I put out the test below in my aclocal.m4,
+# and will try to use it in my things.  The idea is to distribute
+# rx.[hc] and regex.[hc] together, for a while.  The WITH_REGEX symbol
+# (which should also be documented in acconfig.h) is used to decide
+# which of regex.h or rx.h should be included in the application.
+#
+# If `./configure --with-regex' is given, the package will use
+# the older regex.  Else, a check is made to see if rx is already
+# installed, as with newer Linux'es.  If not found, the package will
+# use the rx from the distribution.  If found, the package will use
+# the system's rx which, on Linux at least, will result in a smaller
+# executable file.
+
+AC_DEFUN(fp_WITH_DMALLOC,
+[AC_MSG_CHECKING(if malloc debugging is wanted)
+AC_ARG_WITH(dmalloc,
+[  --with-dmalloc          use dmalloc, as in
+                          ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz],
+[if test "$withval" = yes; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(WITH_DMALLOC)
+  LIBS="$LIBS -ldmalloc"
+  LDFLAGS="$LDFLAGS -g"
+else
+  AC_MSG_RESULT(no)
+fi], [AC_MSG_RESULT(no)])
+])
+
+## --------------------------------- ##
+## Check if --with-regex was given.  ##
+## --------------------------------- ##
+
+AC_DEFUN(fp_WITH_REGEX,
+[AC_MSG_CHECKING(which of rx or regex is wanted)
+AC_ARG_WITH(regex,
+[  --with-regex            use older regex in lieu of GNU rx for matching],
+[if test "$withval" = yes; then
+  ac_with_regex=1
+  AC_MSG_RESULT(regex)
+  AC_DEFINE(WITH_REGEX)
+  AC_LIBOBJ([regex])
+fi])
+if test -z "$ac_with_regex"; then
+  AC_MSG_RESULT(rx)
+  AC_CHECK_FUNC(re_rx_search, , [AC_LIBOBJ([rx])])
+fi
+])
Index: /gsdl/stable/bin/java/xalan-license.txt
===================================================================
--- /gsdl/stable/bin/java/xalan-license.txt	(revision 20131)
+++ /gsdl/stable/bin/java/xalan-license.txt	(revision 20131)
@@ -0,0 +1,57 @@
+Xalan version 2.4 is licensed under the Apache Software License, version 1.1.
+
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * 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. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xalan" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
+ * ITS 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999, Lotus
+ * Development Corporation., http://www.lotus.com.  For more
+ * information on the Apache Software Foundation, please see
+ * http://www.apache.org/.
+ */
Index: /gsdl/stable/bin/script/anonymiselog.pl
===================================================================
--- /gsdl/stable/bin/script/anonymiselog.pl	(revision 20131)
+++ /gsdl/stable/bin/script/anonymiselog.pl	(revision 20131)
@@ -0,0 +1,120 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# anonymiselog.pl -- anonymise a log file by MD5 hashing all IP addresses
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+use MD5;
+
+
+sub main
+{
+    # Get the name of the log file to process
+    local $logfilename = shift(@_);
+
+    # Check that the necessary arguments were supplied
+    if (!$logfilename) {
+	print STDERR "Usage: anonymiselog.pl <logfile-name>\n";
+	die "Error: Required argument missing.\n";
+    }
+
+    # Open the log file
+    open(LOG_FILE, "<$logfilename") or die "Error: Could not open log file $logfilename.\n";
+
+    # Open the output file
+    local $outfilename = $logfilename . ".anon";
+    open(OUT_FILE, ">$outfilename") or die "Error: Could not write file $outfilename.\n"; 
+
+    # Create a new MD5 (RSA Data Security Inc. MD5 Message Digest) object
+    local $md5 = new MD5;
+
+    # Process the log, one line at a time
+    local $entry = "";
+    while (<LOG_FILE>) {
+	local $line = $_;
+	# print "Line: $line";
+
+	# If this line starts a new entry, process the previous one
+	if ($line =~ /^\//) {
+	    print OUT_FILE &anonymise_log_entry($entry);
+	    $entry = "";
+	}
+
+	# Remove trailing whitespace, and skip blank lines
+	$line =~ s/(\s*)$//;
+	next if ($line =~ /^$/);
+
+	$entry = $entry . $line;
+    }
+
+    # Process the last entry
+    print OUT_FILE &anonymise_log_entry($entry);
+
+    # All done
+    close(LOG_FILE);
+    close(OUT_FILE);
+}
+
+
+sub anonymise_log_entry
+{
+    local $entry = shift(@_);
+    return "" if ($entry eq "");
+
+    # Parse the IP address from the entry
+    $entry =~ /^\S+\s((\w|-|\.)+)\s\[/;
+    if (!defined($1)) {
+	print STDERR "Could not extract IP address from entry: $entry\n";
+	return "";
+    }
+
+    # Casefold the IP address, hash using MD5, and take the last 16 characters
+    local $ipaddress = $1;
+    $ipaddress =~ tr/A-Z/a-z/;
+    local $hashedaddress = substr($md5->hexhash($ipaddress), -16);
+
+    # Replace the IP address with the hashed value
+    $entry =~ s/$ipaddress/$hashedaddress/ig;
+
+    # Parse the Greenstone user identifier (z variable) from the entry
+    $entry =~ /\sz=((\w|-|\.)+)/;
+    if (!defined($1)) {
+	print STDERR "No z variable in entry: $entry\n";
+	return "";
+    }
+
+    # Casefold the Greenstone user ID, hash using MD5, and take the last 16 characters
+    local $gsuserid = $1;
+    $gsuserid =~ tr/A-Z/a-z/;
+    local $hasheduserid = substr($md5->hexhash($gsuserid), -16);
+
+    # Replace the Greenstone user ID with the hashed value
+    $entry =~ s/$gsuserid/$hasheduserid/ig;
+    return $entry . "\n";
+}
+
+
+&main(@ARGV);
Index: /gsdl/stable/bin/script/build
===================================================================
--- /gsdl/stable/bin/script/build	(revision 20131)
+++ /gsdl/stable/bin/script/build	(revision 20131)
@@ -0,0 +1,731 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# build --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2000 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# This perl script may be called directly or by running build.bat on
+# windows (build.bat is in bin\windows)
+
+# Note that this script has grown over time and now has many options for
+# use when called from within the collector. If it appears to
+# over-complicate things a little, that's why.
+
+package build;
+
+use strict;
+no strict 'refs';
+
+use FileHandle;
+use File::Copy;
+
+BEGIN {
+
+    die "GSDLHOME not set - did you remember to source setup.bash (unix) or " .
+	"run setup.bat (windows)?\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set - did you remember to source setup.bash (unix) or " .
+	"run setup.bat (windows)?\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+
+    STDOUT->autoflush(1);
+    STDERR->autoflush(1);
+}
+
+use lib qq($ENV{'GSDLHOME'}/perllib/cpan);
+use Mail::Sendmail;
+use parsargv;
+use util;
+use cfgread;
+
+# set up path - this allows for paths not to be supplied to system calls
+# and overcomes problems when GSDLHOME contains spaces (double quoting
+# the call doesn't work on win2k and probably other variants of winnt)
+my $path_separator = ":";
+$path_separator = ";" if $ENV{'GSDLOS'} =~ /^windows$/;
+$ENV{'PATH'} = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}) .
+    $path_separator . &util::filename_cat($ENV{'GSDLHOME'}, "bin", "script") .
+    $path_separator . $ENV{'PATH'};
+
+# all the input option variables
+my ($optionfile, $indextype, $append, $manifest, $remove_archives, $remove_import, $buildtype, $maxdocs, @download, $collectdir, $site, $dontinstall, $save_archives, $out, $make_writable, $log_events, $event_log_file, $email_events, $mail_server, $statsfile, $event_header);
+
+&parse_args (\@ARGV);
+
+my ($collection) = @ARGV;
+
+if (!defined $collection || $collection !~ /\w/) {
+    print STDERR "You must specify a collection to build\n";
+    &print_usage();
+    die "\n";
+}
+
+if ($optionfile =~ /\w/) {
+    open (OPTIONS, $optionfile) || die "Couldn't open $optionfile\n";
+    my $line = [];
+    my $options = [];
+    while (defined ($line = &cfgread::read_cfg_line ('build::OPTIONS'))) {
+	push (@$options, @$line);
+    }
+    close OPTIONS;
+    &parse_args ($options);
+}
+
+if ($maxdocs == -1) {
+    $maxdocs = "";
+} else {
+    $maxdocs = "-maxdocs $maxdocs";
+}
+
+my $cdir = $collectdir;
+if (defined $site && $site =~ /\w/)
+{
+    die "GSDL3HOME not set." unless $ENV{'GSDL3HOME'};
+    $cdir = &util::filename_cat ($ENV{'GSDL3HOME'}, "sites", $site, "collect") unless $collectdir =~ /\w/;
+}
+else
+{
+    $cdir = &util::filename_cat ($ENV{'GSDLHOME'}, "collect") unless $collectdir =~ /\w/;
+}
+
+my $importdir = &util::filename_cat ($cdir, $collection, "import");
+my $archivedir = &util::filename_cat ($cdir, $collection, "archives");
+my $buildingdir = &util::filename_cat ($cdir, $collection, "building");
+my $indexdir = &util::filename_cat ($cdir, $collection, "index");
+my $bindir = &util::filename_cat ($ENV{'GSDLHOME'}, "bin");
+
+my $use_out = 0;
+my $outfile = $out;
+if ($out !~ /^(STDERR|STDOUT)$/i) {
+    open (OUT, ">$out") || die "Couldn't open output file $out\n";
+    $out = "OUT";
+    
+    # delete any existing .final file
+    &util::rm ("$outfile.final") if -e "$outfile.final";
+
+    $use_out = 1;
+}
+$out->autoflush(1);
+
+# delete any .kill file left laying around from a previously aborted build
+if (-e &util::filename_cat ($cdir, $collection, ".kill")) {
+    &util::rm (&util::filename_cat ($cdir, $collection, ".kill"));
+}
+
+# get maintainer email address from main.cfg
+my $maintainer = "NULL";
+my $main_cfg = &util::filename_cat ($ENV{'GSDLHOME'}, "etc", "main.cfg");
+my $cfgdata = &cfgread::read_cfg_file ($main_cfg, "maintainer");
+if (defined $cfgdata->{'maintainer'} && $cfgdata->{'maintainer'} =~ /\w/) {
+    $maintainer = $cfgdata->{'maintainer'};
+}
+# if maintainer is "NULL" email_events should be disabled
+if ($maintainer =~ /^NULL$/i) {
+    $email_events = "";
+}
+
+&main();
+
+if ($use_out) {
+    close OUT;
+
+    # if we've created a build log we'll copy it to the collection's etc
+    # directory
+    my ($etcdir);
+    if ($dontinstall) {
+	$etcdir = &util::filename_cat($collectdir, "etc", "build.log");
+    } else {
+	$etcdir = &util::filename_cat($ENV{'GSDLHOME'}, "collect", $collection, "etc", "build.log");
+    }
+    
+    &util::cp($outfile, $etcdir);
+}
+
+sub print_usage {
+    print STDOUT "\n";
+    print STDOUT "build: Builds a Greenstone collection (i.e. runs import.pl and buildcol.pl\n";
+    print STDOUT "       then copies the resulting indexes to the correct place).\n\n";
+    print STDOUT "  usage: $0 [options] collection-name\n\n";
+    print STDOUT "  options:\n";
+    print STDOUT "   -optionfile file        Get options from file, useful on systems where\n";
+    print STDOUT "                           long command lines may cause problems\n";
+    print STDOUT "   -indextype mg|mgpp|lucene \n";
+    print STDERR "                           Specify the type of indexer used in this collection\n";
+    print STDERR "                           If -append is used then -indextype is needed to \n";
+    print STDERR "                           determine how to run buildcol.pl as well as update\n";
+    print STDERR "                           'building' and 'index' according.\n";
+    print STDOUT "   -append                 Add new files to existing collection\n";
+    print STDOUT "   -manifest               Use manifest.xml file to determine which files to process.\n";
+    print STDOUT "   -remove_archives        Remove archives directory after successfully\n";
+    print STDOUT "                           building the collection.\n";
+    print STDOUT "   -remove_import          Remove import directory after successfully\n";
+    print STDOUT "                           importing the collection.\n";
+    print STDOUT "   -buildtype build|import If 'build' attempt to build directly\n";
+    print STDOUT "                           from archives directory (bypassing import\n";
+    print STDOUT "                           stage). Defaults to 'import'\n";
+    print STDOUT "   -maxdocs number         Maximum number of documents to build\n";
+    print STDOUT "   -download directory     Directory (or file) to get import documents from.\n";
+    print STDOUT "                           There may be multiple download directories and they\n";
+    print STDOUT "                           may be of type http://, ftp://, or file://\n";
+    print STDOUT "                           Note that any existing import directory will be\n";
+    print STDOUT "                           deleted to make way for the downloaded data if\n";
+    print STDOUT "                           a -download option is supplied\n";
+    print STDOUT "   -collectdir directory   Collection directory (defaults to " .
+	&util::filename_cat($ENV{'GSDLHOME'}). "collect for Greenstone2;\n";
+    print STDOUT"                            for Greenstone3 use -site option and then collectdir default will be\n";
+    print STDOUT "                            set to the collect folder within that site.)\n";
+    print STDOUT "   -site                   Specify the site within a Greenstone3 installation to use.\n";
+    print STDOUT "   -dontinstall            Only applicable if -collectdir is set to something\n";
+    print STDOUT "                           other than the default. -dontinstall will suppress\n";
+    print STDOUT "                           the default behaviour which is to install the\n";
+    print STDOUT "                           collection to the gsdl/collect directory once it has\n";
+    print STDOUT "                           been built.\n";
+    print STDOUT "   -save_archives          Create a copy of the existing archives directory\n";
+    print STDOUT "                           called archives.org\n";
+    print STDOUT "   -out                    Filename or handle to print output status to.\n";
+    print STDOUT "                           The default is STDERR\n";
+    print STDOUT "   -statsfile name         Filename or handle to print import statistics to.\n";
+    print STDOUT "                           The default is STDERR\n";
+    print STDOUT "   -make_writable          If set build will make the collection and any\n";
+    print STDOUT "                           temporary files it created globally writable after\n";
+    print STDOUT "                           it finishes\n";
+    print STDOUT "   -log_events             Log important events (collection built successfully\n";
+    print STDOUT "                           etc.) to event_log_file\n";
+    print STDOUT "   -event_log_file file    File to append important events to (defaults to\n";
+    print STDOUT "                           " . &util::filename_cat ($ENV{'GSDLHOME'}, "etc", "events.txt") . "\n";
+    print STDOUT "   -email_events addr      Comma separated list of email addresses to mail\n";
+    print STDOUT "                           details of important collection building events\n";
+    print STDOUT "   -mail_server server     The outgoing (SMTP) mail server to be used by\n";
+    print STDOUT "                           email_events. email_events will be disabled if\n";
+    print STDOUT "                           mail_server isn't set\n";
+    print STDOUT "   -event_header file      File containing a header to go on any event\n";
+    print STDOUT "                           messages. If not specified build will create a\n";
+    print STDOUT "                           generic header\n\n";
+    print STDOUT "  [Type \"build | more\" if this help text scrolled off your screen]";
+    print STDOUT "\n" unless $ENV{'GSDLOS'} =~ /^windows$/i;
+}
+
+sub main {
+
+    if ($save_archives && -d $archivedir) {
+	print $out "caching original archives to ${archivedir}.org\n";
+	&util::cp_r ($archivedir, "${archivedir}.org");
+    }
+
+    # do the download thing if we have any -download options
+    if (scalar (@download)) {
+	# remove any existing import data
+	if (&has_content ($importdir)) {
+	    print $out "build: WARNING: removing contents of $importdir\n";
+	    &util::rm_r ($importdir);
+	}
+	
+	foreach my $download_dir (@download) {
+
+	    # remove any leading or trailing whitespace from filenames (just in case)
+	    $download_dir =~ s/^\s+//;
+	    $download_dir =~ s/\s+$//;
+	    
+	    if ($download_dir =~ /^(http|ftp):\/\//) {
+		# use wget to mirror http or ftp urls
+		# options used are:
+		#  -P = the directory to download documents to
+		#  -np = don't ascend to parent directories. this means that only documents
+		#        that live in the same directory or below on the same server as
+		#        the given url will be downloaded
+		#  -nv = not too verbose
+		#  -r = recursively mirror
+		#  -N = use time-stamping to see if an up-to-date local copy of each 
+		#       file already exists. this may be useful if wget fails and 
+		#       is restarted
+		#  -l inf = infinite recursion depth
+		#  -R "*\?*" = don't download cgi based urls
+		#  -o = the output file to write download status to (only used if the -out
+		#       option was given to build)
+
+		my $download_cmd = "perl -S gsWget.pl -P \"$importdir\" -np -nv";
+		$download_cmd .= " -r -N -l inf -R \"*\\?*\"";
+		$download_cmd .= " -o \"$outfile.download\"" if $use_out;
+		$download_cmd .= " \"$download_dir\"";
+		system ($download_cmd);
+
+		# note that wget obeys the robot rules. this means that it will have
+		# downloaded a robots.txt file if one was present. since it's unlikely 
+		# anyone really wants to include it in a collection we'll delete it.
+		# robots.txt shouldn't be more than two directories deep (I think it will 
+		# always be exactly two deep but will look for it in the top directory too)
+		# so that's as far as we'll go looking for it.
+		if (opendir (DIR, $importdir)) {
+		    my @files = readdir DIR;
+		    closedir DIR;
+		    foreach my $file (@files) {
+			next if $file =~ /^\.\.?$/;
+			if ($file =~ /^robots.txt$/i) {
+			    &util::rm (&util::filename_cat ($importdir, $file));
+			    last;
+			} else {
+			    $file = &util::filename_cat ($importdir, $file);
+			    if (-d $file) {
+				if (opendir (DIR, $file)) {
+				    my @files2 = readdir DIR;
+				    closedir DIR;
+				    foreach my $file2 (@files2) {
+					if ($file2 =~ /^robots.txt$/i) {
+					    &util::rm (&util::filename_cat ($file, $file2));
+					    last;
+					}
+				    }
+				}
+			    }
+			}
+		    }
+		}
+
+		# if using output directory append the file download output to it
+		&append_file ($out, "$outfile.download");
+		
+	    } else {
+		# we assume anything not beginning with http:// or ftp://
+		# is a file or directory on the local file system.
+		$download_dir =~ s/^file:(\/\/)?//;
+		$download_dir =~ s/^\s+//; # may be whitespace between "file://" and the rest
+		
+		if (-e $download_dir) {
+		    # copy download_dir and all it contains to the import directory
+		    my $download_cmd = "perl -S filecopy.pl";
+		    $download_cmd .= " -collectdir \"$collectdir\"" if $collectdir =~ /\w/;
+		    $download_cmd .= " -site \"$site\"" if $site =~ /\w/;
+		    $download_cmd .= " -out \"$outfile.download\"" if $use_out;
+		    $download_cmd .= " \"" . $download_dir . "\" " . $collection;
+
+		    my $download_status = system ($download_cmd);
+		    if ($download_status > 0) 
+		    {
+			die "Failed to execute: $download_cmd\n";
+		    }
+
+
+		    # if using output directory append the file download output to it
+		    &append_file ($out, "$outfile.download");
+		} else {
+		    print $out "WARNING: '$download_dir' does not exist\n";
+		}
+	    }
+	}
+    }
+
+    `echo $importdir ; ls $importdir `;
+
+    if (-e &util::filename_cat ($archivedir, "archiveinf-doc.gdb")) {
+	if (&has_content ($importdir)) {
+	    if ($buildtype eq "build") {
+		&gsdl_build();
+	    } else {
+		&gsdl_import();
+		&gsdl_build();
+	    }
+	} else {
+	    # there are archives but no import, build directly from archives
+	    print $out "build: no import material was found, building directly\n";
+	    print $out "       from archives\n";
+	    &gsdl_build();
+	}
+    } else {
+	if (&has_content ($importdir)) {
+	    if ($buildtype eq "build") {
+		print $out "build: can't build directly from archives as no\n";
+		print $out "       imported archives exist (did you forget to\n";
+		print $out "       move the contents of $collection/import to\n";
+		print $out "       collection/archives?)\n";
+	    }
+	    &gsdl_import();
+	    if (&has_content ($archivedir, "^archiveinf-doc.gdb\$")) {
+		&gsdl_build();
+	    } else {
+		my $msg = "build: ERROR: The collection could not be built as no\n";
+		$msg .=   "       valid data was imported. Are at least some of\n";
+		$msg .=   "       the files you imported in a format that can be\n";
+		$msg .=   "       processed by the specified Greenstone plugins?\n";
+		print $out $msg;
+		&log_event ($msg);
+		&final_out (6) if $use_out;
+		die "\n";
+	    }
+	} else {
+	    # no import or archives
+	    my $msg = "build: ERROR: The collection could not be built as it contains no data.\n";
+	    print $out $msg;
+	    &log_event ($msg);
+	    &final_out (1) if $use_out;
+	    die "\n";
+	}
+    }
+
+    if ($collectdir ne "" && !$dontinstall) {
+	
+	my $install_collectdir;
+	if (defined $ENV{'GSDL3HOME'})
+	{
+	    
+	    if ((defined $site) && ($site ne ""))
+	    {
+		$install_collectdir = &util::filename_cat ($ENV{'GSDL3HOME'}, "sites", $site, "collect");
+	    }
+	    else 
+	    {
+		my $msg = "build: ERROR: Need to specify the site within the Greenstone3 installation.";
+		print $out $msg;
+		&log_event ($msg);
+		&final_out (6) if $use_out;
+		die "\n";
+	    }
+	}
+	else
+	{
+	    $install_collectdir = &util::filename_cat ($ENV{'GSDLHOME'}, "collect");
+	}
+
+	if (!&util::filenames_equal ($collectdir, $install_collectdir)) {
+	    
+	    # install collection to gsdl/collect
+	    print $out "installing the $collection collection\n";
+	    my $newdir = &util::filename_cat ($install_collectdir, $collection);
+	    my $olddir = &util::filename_cat ($collectdir, $collection);
+	    if (-d $newdir) {
+		my $msg = "build: Could not install collection as $newdir\n" .
+		    "       already exists. Collection will remain at\n$olddir\n";
+
+		print $out $msg;
+		&log_event ($msg);
+		&final_out (4) if $use_out;
+		die "\n";
+	    }
+	    if (!&File::Copy::move ($olddir, $newdir)) {
+		my $msg = "build: Failed to install collection to $newdir\n" .
+		    "       Collection will remain at $olddir\n";
+		print $out $msg;
+		&log_event ($msg);
+		&final_out (5) if $use_out;
+		die "\n";
+	    }
+	}
+    }
+
+    &log_event ("The $collection collection was built successfully\n");
+    &final_out (0) if $use_out;
+}
+
+sub gsdl_import {
+
+    print $out "importing the $collection collection\n\n";
+
+    my $import_cmd = "perl -S import.pl";
+    $import_cmd .= " -out \"$outfile.import\"" if $use_out;
+    if ($append) {
+	$import_cmd .= " -keepold";
+	if (not $manifest) {
+	    # if we are appending, with no manifest, assume incremental
+	    $import_cmd .= " -incremental";
+	}
+    } else {
+	$import_cmd .= " -removeold";
+    }
+
+    $import_cmd .= " -manifest manifest.xml" if ($manifest);
+    $import_cmd .= " -site \"$site\"" if $site =~ /\w/;
+    $import_cmd .= " -collectdir \"$collectdir\"" if $collectdir =~ /\w/;
+    $import_cmd .= " -statsfile \"$statsfile\"" if $statsfile =~ /\w/;
+    $import_cmd .= " $maxdocs $collection";
+
+    system ($import_cmd);
+    # if using output directory append the import output to it
+    &append_file ($out, "$outfile.import");
+
+    if (-e &util::filename_cat ($archivedir, "archiveinf-doc.gdb")) {
+	print $out "$collection collection imported successfully\n\n";
+	if ($remove_import) {
+	    print $out "removing import directory ($importdir)\n";
+	    &util::rm_r ($importdir);
+	}
+    } else {
+	print $out `ls $archivedir`;
+
+	my $msg = "build: ERROR: import.pl failed\n";
+	print $out "\n$msg";
+	&log_event ($msg);
+	&final_out (2) if $use_out;
+	die "\n";
+    }
+}
+
+sub gsdl_build {
+
+    print $out "building the $collection collection\n\n";
+
+    my $build_cmd = "perl -S buildcol.pl";
+
+    my $removeold = 1;
+    if ($append) {
+	if ($indextype eq "lucene") {
+	    $build_cmd .= " -keepold -incremental -builddir $indexdir";
+	    $removeold = 0;
+	}
+	else {
+	    $build_cmd .= " -removeold";
+	}
+    }
+    else {
+	$build_cmd .= " -removeold";
+    }
+
+    $build_cmd .= " -out \"$outfile.build\"" if $use_out;
+    $build_cmd .= " -site \"$site\"" if $site =~ /\w/;
+    $build_cmd .= " -collectdir \"$collectdir\"" if $collectdir =~ /\w/;
+    $build_cmd .= " $maxdocs $collection";
+    system ($build_cmd);
+    # if using output directory append the buildcol output to it
+    &append_file ($out, "$outfile.build");
+
+    my @db_exts = ( ".ldb", ".bdb", ".gdb", ".db" );
+    my $build_ok = 0;
+    foreach my $db_ext (@db_exts) {
+	if ($removeold && (-e &util::filename_cat ($buildingdir, "text", "$collection$db_ext"))) {
+	    $build_ok = 1;
+	    last;
+	}
+	if (($removeold==0) && (-e &util::filename_cat ($indexdir, "text", "$collection$db_ext"))) {
+	    $build_ok = 1;
+	    last;
+	}
+    }
+
+    if ($build_ok) {
+	print $out "$collection collection built successfully\n\n";
+	if ($remove_archives) {
+	    print $out "removing archives directory ($archivedir)\n";
+	    &util::rm_r ($archivedir);
+	}
+    } else {
+	my $msg = "build: ERROR: buildcol.pl failed\n";
+	print $out "\n$msg";
+	&log_event ($msg);
+	&final_out (3) if $use_out;
+	die "\n";
+    }
+
+    if ($removeold) {
+	# replace old indexes with new ones
+	if (&has_content ($indexdir)) {
+	    print $out "removing old indexes\n";
+	    &util::rm_r ($indexdir);
+	}
+	rmdir ($indexdir) if -d $indexdir;
+	&File::Copy::move ($buildingdir, $indexdir);
+    }
+    else {
+	# Do nothing. We have built into index dir rather than building dir
+    }
+
+    # remove the cached archives
+    if ($save_archives && -d "${archivedir}.org") {
+	&util::rm_r ("${archivedir}.org");
+    }
+}
+
+# return 1 if $dir directory contains any files or sub-directories (other
+# than those specified in the $ignore regular expression)
+sub has_content {
+    my ($dir, $ignore) = @_;
+
+    if (!-d $dir) {return 0;}
+    
+    opendir (DIR, $dir) || return 0;
+    my @files = readdir DIR;
+    closedir DIR;
+    
+    foreach my $file (@files) {
+	if ($file !~ /^\.{1,2}$/) {
+	    return 1 unless (defined $ignore && $file =~ /$ignore/);
+	}
+    }
+
+    return 0;
+}
+
+sub append_file {
+    my ($handle, $file) = @_;
+
+    open (FILE, $file) || return;
+    undef $/;
+    print $handle <FILE>;
+    $/ = "\n";
+    close FILE;
+    &util::rm ($file);
+}
+
+# creates a file called $outfile.final and writes an output code to it.
+# An output code of 0 specifies that there was no error
+sub final_out {
+    my ($exit_code) = @_;
+
+    if ($use_out && (!-e "$outfile.final")) {
+
+	if (open (FINAL, ">$outfile.final")) {
+	    print FINAL $exit_code;
+	    close FINAL;
+	}
+    }
+}
+
+sub log_event {
+    my ($msg) = @_;
+
+    return unless ($log_events || $email_events);
+
+    # get the event header
+    my $eheader = "[Build Event]\n";
+    $eheader .= "Date: " . scalar localtime() . "\n";
+    if ($event_header ne "" && open (HEADER, $event_header)) {
+	undef $/;
+	$eheader .= <HEADER>;
+	$/ = "\n";
+	close HEADER;
+    } else {
+	$eheader .= "Collection: $collection\n";
+	$eheader .= "GSDLHOME: $ENV{'GSDLHOME'}\n";
+	$eheader .= "Build Location: $collectdir\n";
+    }
+    
+    if ($log_events) {
+	my $fail = 0;
+	# append the event to the event log file
+	if ($event_log_file eq "" || !open (LOG, ">>$event_log_file")) {
+	    # log file defaults to $GSDLHOME/etc/events.txt
+	    $event_log_file = &util::filename_cat ($ENV{'GSDLHOME'}, "etc", "events.txt");
+	    if (!open (LOG, ">>$event_log_file")) {
+		print $out "build: ERROR: Couldn't open event log file $event_log_file\n";
+		$fail = 1;
+	    }
+	}
+	if (!$fail) {
+	    print LOG $eheader;
+	    print LOG $msg;
+	    print LOG "\n";
+	    close LOG;
+	}
+    }
+    
+    if ($email_events) {
+	# if mail_server isn't set email_events does nothing
+	if ($mail_server eq "") {
+	    print $out "build: WARNING: mail_server was not set - email_events option was ignored\n";
+	    return;
+	}
+	
+	my %mail = ('SMTP' => $mail_server, 
+		    'To' => $email_events,
+		    'From' => $maintainer,
+		    'Subject' => 'Greenstone Build Event'
+		    );
+	$mail{'Message'} = $eheader . $msg;
+	
+	if (!sendmail %mail) {
+	    print $out "build: ERROR sending mail to $email_events\n";
+	    print $out "'$Mail::Sendmail::error'\n";
+	}
+    }
+}
+
+
+sub parse_args {
+    my ($argref) = @_;
+
+    if (!parsargv::parse($argref, 
+			 'optionfile/.*/', \$optionfile,
+			 'indextype/^(mg|mgpp|lucene)$/mg', \$indextype,
+			 'append', \$append,
+			 'manifest', \$manifest,
+			 'remove_archives', \$remove_archives,
+			 'remove_import', \$remove_import,
+			 'buildtype/^(build|import)$/import', \$buildtype,
+			 'maxdocs/^\-?\d+/-1', \$maxdocs,
+			 'download/.+', \@download,
+			 'collectdir/.*/', \$collectdir,
+			 'site/.*/', \$site,
+			 'dontinstall', \$dontinstall,
+			 'save_archives', \$save_archives,
+			 'out/.*/STDERR', \$out,
+			 'make_writable', \$make_writable,
+			 'log_events', \$log_events,
+			 'event_log_file/.*/', \$event_log_file,
+			 'email_events/.*/', \$email_events,
+			 'mail_server/.*/', \$mail_server,
+			 'statsfile/.*/STDERR', \$statsfile,
+			 'event_header/.*/', \$event_header)) {
+	
+	&print_usage();
+	die "\n";
+    }
+}
+
+
+END {
+
+    if ($make_writable) {
+	# chmod a+rw new collection
+	my $installed_collection = &util::filename_cat($ENV{'GSDLHOME'}, "collect", $collection);
+	&recursive_chmod($installed_collection);
+
+	# chmod a+rw anything we've left laying about in the tmp directory
+	if (($collectdir ne "") && 	
+	    (!&util::filenames_equal ($collectdir, &util::filename_cat($ENV{'GSDLHOME'}, "collect")))) {
+	    &recursive_chmod($collectdir);
+	}
+    }
+
+    # this will produce a .final file if one doesn't exist yet - that
+    # should only happen if there's been an error somewhere in the perl
+    # code
+    &final_out(7);
+
+    sub recursive_chmod {
+	my ($dir) = @_;
+	return unless -d $dir;
+
+	chmod (0777, $dir);
+
+	opendir (DIR, $dir) || die;
+	my @files = readdir DIR;
+	closedir DIR;
+	
+	foreach my $file (@files) {
+	    next if $file =~ /^\.\.?$/;
+	    $file = &util::filename_cat($dir, $file);
+	    if (-d $file) {
+		&recursive_chmod ($file);
+	    } else {
+		chmod (0777, $file);
+	    }
+	}
+    }
+}
Index: /gsdl/stable/bin/script/buildcol.pl
===================================================================
--- /gsdl/stable/bin/script/buildcol.pl	(revision 20131)
+++ /gsdl/stable/bin/script/buildcol.pl	(revision 20131)
@@ -0,0 +1,595 @@
+#!/usr/bin/perl -w
+
+## @file buildcol.pl
+# This program will build a particular collection.
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# @author New Zealand Digital Library Project unless otherwise stated
+# @copy 1999 New Zealand Digital Library Project
+#
+package buildcol;
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan/XML/XPath");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugins");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/classify");
+
+    if (defined $ENV{'GSDLEXTS'}) {
+	my @extensions = split(/:/,$ENV{'GSDLEXTS'});
+	foreach my $e (@extensions) {
+	    my $ext_prefix = "$ENV{'GSDLHOME'}/ext/$e";
+
+	    unshift (@INC, "$ext_prefix/perllib");
+	    unshift (@INC, "$ext_prefix/perllib/cpan");
+	    unshift (@INC, "$ext_prefix/perllib/plugins");
+	    unshift (@INC, "$ext_prefix/perllib/plugouts");
+	    unshift (@INC, "$ext_prefix/perllib/classify");
+	}
+    }
+}
+
+use colcfg;
+use util;
+use scriptutil;
+use FileHandle;
+use gsprintf;
+use printusage;
+use parse2;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and vice versa
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+
+
+my $mode_list =
+    [ { 'name' => "all",
+        'desc' => "{buildcol.mode.all}" },
+      { 'name' => "compress_text",
+        'desc' => "{buildcol.mode.compress_text}" },
+      { 'name' => "build_index",
+        'desc' => "{buildcol.mode.build_index}" },
+      { 'name' => "infodb",
+        'desc' => "{buildcol.mode.infodb}" } ];
+
+my $sec_index_list = 
+    [ {'name' => "never",
+       'desc' => "{buildcol.sections_index_document_metadata.never}" },
+      {'name' => "always",
+       'desc' => "{buildcol.sections_index_document_metadata.always}" },
+      {'name' => "unless_section_metadata_exists",
+       'desc' => "{buildcol.sections_index_document_metadata.unless_section_metadata_exists}" }
+      ];
+
+my $arguments =
+    [ { 'name' => "remove_empty_classifications",
+	'desc' => "{buildcol.remove_empty_classifications}",
+	'type' => "flag",
+	'reqd' => "no",
+	'modegli' => "2" },
+      { 'name' => "archivedir",
+	'desc' => "{buildcol.archivedir}",
+	'type' => "string",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "builddir",
+	'desc' => "{buildcol.builddir}",
+	'type' => "string",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+#     { 'name' => "cachedir",
+#	'desc' => "{buildcol.cachedir}",
+#	'type' => "string",
+#	'reqd' => "no" },
+      { 'name' => "collectdir",
+	'desc' => "{buildcol.collectdir}",
+	'type' => "string",
+	# parsearg left "" as default
+	#'deft' => &util::filename_cat ($ENV{'GSDLHOME'}, "collect"),
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "site",
+	'desc' => "{buildcol.site}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "debug",
+	'desc' => "{buildcol.debug}",
+	'type' => "flag",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "faillog",
+	'desc' => "{buildcol.faillog}",
+	'type' => "string",
+	# parsearg left "" as default
+	#'deft' => &util::filename_cat("<collectdir>", "colname", "etc", "fail.log"),
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "index",
+	'desc' => "{buildcol.index}",
+	'type' => "string",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "incremental",
+	'desc' => "{buildcol.incremental}",
+	'type' => "flag",
+	'hiddengli' => "yes" },
+      { 'name' => "keepold",
+	'desc' => "{buildcol.keepold}",
+	'type' => "flag",
+	'reqd' => "no",
+        #'modegli' => "3",
+	'hiddengli' => "yes" },
+      { 'name' => "removeold",
+	'desc' => "{buildcol.removeold}",
+	'type' => "flag",
+	'reqd' => "no",
+	#'modegli' => "3",
+	'hiddengli' => "yes"  },
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "maxdocs",
+	'desc' => "{buildcol.maxdocs}",
+	'type' => "int",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "maxnumeric",
+	'desc' => "{buildcol.maxnumeric}",
+	'type' => "int",
+	'reqd' => "no",
+	'deft' => "4",
+	'range' => "4,512",
+	'modegli' => "3" },
+      { 'name' => "mode",
+	'desc' => "{buildcol.mode}",
+	'type' => "enum",
+	'list' => $mode_list,
+	# parsearg left "" as default
+#	'deft' => "all",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "no_strip_html",
+	'desc' => "{buildcol.no_strip_html}",
+	'type' => "flag",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "no_text",
+	'desc' => "{buildcol.no_text}",
+	'type' => "flag",
+	'reqd' => "no",
+	'modegli' => "2" },
+      { 'name' => "sections_index_document_metadata",
+	'desc' => "{buildcol.sections_index_document_metadata}",
+	'type' => "enum",
+	'list' => $sec_index_list,
+	'reqd' => "no",
+	'modegli' => "2" },
+      { 'name' => "out",
+	'desc' => "{buildcol.out}",
+	'type' => "string",
+	'deft' => "STDERR",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "verbosity",
+	'desc' => "{buildcol.verbosity}",
+	'type' => "int",
+	# parsearg left "" as default
+	#'deft' => "2",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "gli",
+	'desc' => "",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "xml",
+	'desc' => "{scripts.xml}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "disable_OAI",
+        'desc' => "{buildcol.disable_OAI}",
+        'type' => "flag",
+        'reqd' => "no",
+        'modegli' => "2",
+	'hiddengli' => "yes" },
+      ];
+
+my $options = { 'name' => "buildcol.pl",
+		'desc' => "{buildcol.desc}",
+		'args' => $arguments };
+
+
+# globals
+my $collection;
+my $configfilename;
+my $out;
+
+# used to signify "gs2"(default) or "gs3"
+my $gs_mode = "gs2";
+
+## @method gsprintf()
+#  Print a string to the screen after looking it up from a locale dependant
+#  strings file. This function is losely based on the idea of resource
+#  bundles as used in Java.
+#
+#  @param  $error The STDERR stream.
+#  @param  $text The string containing GS keys that should be replaced with
+#                their locale dependant equivilents.
+#  @param  $out The output stream.
+#  @return The locale-based string to output.
+#
+sub gsprintf()
+{
+    return &gsprintf::gsprintf(@_);
+}
+## gsprintf() ##
+
+&main();
+
+## @method main()
+#
+#  [Parses up and validates the arguments to the build process before creating
+#  the appropriate build process to do the actual work - John]
+#
+#  @note Added true incremental support - John Thompson, DL Consulting Ltd.
+#  @note There were several bugs regarding using directories other than 
+#        "import" or "archives" during import and build quashed. - John 
+#        Thompson, DL Consulting Ltd.
+#
+#  @param  $incremental If true indicates this build should not regenerate all
+#                       the index and metadata files, and should instead just
+#                       append the information found in the archives directory
+#                       to the existing files. If this requires some complex
+#                       work so as to correctly insert into a classifier so be
+#                       it. Of course none of this is done here - instead the
+#                       incremental argument is passed to the document
+#                       processor.
+#
+sub main
+{
+    # command line args
+    my ($verbosity, $archivedir, $cachedir, $builddir, $site, $maxdocs, 
+	$debug, $mode, $indexname, $removeold, $keepold, $incremental, 
+	$remove_empty_classifications,
+	$collectdir, $build, $type, $textindex,
+	$no_strip_html, $no_text, $faillog, $gli, $index, $language,
+	$sections_index_document_metadata, $maxnumeric,
+	$disable_OAI);
+
+    my $xml = 0;
+    my $hashParsingResult = {};
+    # general options available to all plugins
+    my $intArgLeftinAfterParsing = parse2::parse(\@ARGV,$arguments,$hashParsingResult,"allow_extra_options");
+
+    # If parse returns -1 then something has gone wrong
+    if ($intArgLeftinAfterParsing == -1)
+    {
+	&PrintUsage::print_txt_usage($options, "{buildcol.params}");
+	die "\n";
+    }
+    
+    foreach my $strVariable (keys %$hashParsingResult)
+    {
+	eval "\$$strVariable = \$hashParsingResult->{\"\$strVariable\"}";
+    }
+
+    # If $language has been specified, load the appropriate resource bundle
+    # (Otherwise, the default resource bundle will be loaded automatically)
+    if ($language && $language =~ /\S/) {
+	&gsprintf::load_language_specific_resource_bundle($language);
+    }
+
+    if ($xml) {
+        &PrintUsage::print_xml_usage($options);
+	print "\n";
+	return;
+    }
+
+    if ($gli) { # the gli wants strings to be in UTF-8
+	&gsprintf::output_strings_in_UTF8; 
+    }
+
+    # now check that we had exactly one leftover arg, which should be 
+    # the collection name. We don't want to do this earlier, cos 
+    # -xml arg doesn't need a collection name
+    # Or if the user specified -h, then we output the usage also
+    if ($intArgLeftinAfterParsing != 1 || (@ARGV && $ARGV[0] =~ /^\-+h/))
+    {
+	&PrintUsage::print_txt_usage($options, "{buildcol.params}");
+	die "\n";
+    }
+    
+    $textindex = "";
+    my $close_out = 0;
+    if ($out !~ /^(STDERR|STDOUT)$/i) {
+	open (OUT, ">$out") ||
+	    (&gsprintf(STDERR, "{common.cannot_open_output_file}\n", $out) && die);
+	$out = "buildcol::OUT";
+	$close_out = 1;
+    }
+    $out->autoflush(1);
+
+    # get and check the collection
+    if (($collection = &colcfg::use_collection($site, @ARGV, $collectdir)) eq "") {
+	&PrintUsage::print_txt_usage($options, "{buildcol.params}");
+	die "\n";
+    }
+
+    if ($faillog eq "") {
+	$faillog = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "etc", "fail.log");
+    }
+    # note that we're appending to the faillog here (import.pl clears it each time)
+    # this could potentially create a situation where the faillog keeps being added 
+    # to over multiple builds (if the import process is being skipped)
+    open (FAILLOG, ">>$faillog") ||
+	(&gsprintf(STDERR, "{common.cannot_open_fail_log}\n", $faillog) && die);
+    $faillog = 'buildcol::FAILLOG';
+    $faillog->autoflush(1);
+
+    unshift (@INC, "$ENV{'GSDLCOLLECTDIR'}/perllib");
+    # Don't know why this didn't already happen, but now collection specific
+    # classify and plugins directory also added to include path
+    unshift (@INC, "$ENV{'GSDLCOLLECTDIR'}/perllib/classify");
+    unshift (@INC, "$ENV{'GSDLCOLLECTDIR'}/perllib/plugins");
+
+    # Read in the collection configuration file.
+    my ($collectcfg, $buildtype); 
+    ($configfilename, $gs_mode) = &colcfg::get_collect_cfg_name($out);
+    $collectcfg = &colcfg::read_collection_cfg ($configfilename, $gs_mode);
+
+    if ($verbosity !~ /\d+/) {
+	if (defined $collectcfg->{'verbosity'} && $collectcfg->{'verbosity'} =~ /\d+/) {
+	    $verbosity = $collectcfg->{'verbosity'};
+	} else {
+	    $verbosity = 2; # the default
+	}
+    }
+    # we use searchtype for determining buildtype, but for old versions, use buildtype
+    if (defined $collectcfg->{'buildtype'}) {
+	$buildtype = $collectcfg->{'buildtype'};
+    } elsif (defined $collectcfg->{'searchtypes'} || defined $collectcfg->{'searchtype'}) {
+	$buildtype = "mgpp";
+    } else {
+	$buildtype = "mg"; #mg is the default
+    }
+    if (defined $collectcfg->{'archivedir'} && $archivedir eq "") {
+	$archivedir = $collectcfg->{'archivedir'};
+    }
+    if (defined $collectcfg->{'cachedir'} && $cachedir eq "") {
+	$cachedir = $collectcfg->{'cachedir'};
+    }
+    if (defined $collectcfg->{'builddir'} && $builddir eq "") {
+	$builddir = $collectcfg->{'builddir'};
+    }
+    if ($maxdocs !~ /\-?\d+/) {
+	if (defined $collectcfg->{'maxdocs'} && $collectcfg->{'maxdocs'} =~ /\-?\d+/) {
+	    $maxdocs = $collectcfg->{'maxdocs'};
+	} else {
+	    $maxdocs = -1; # the default
+	}
+    }
+    if (defined $collectcfg->{'maxnumeric'} && $collectcfg->{'maxnumeric'} =~ /\d+/) {
+	$maxnumeric = $collectcfg->{'maxnumeric'};
+    } 
+    
+    if ($maxnumeric < 4 || $maxnumeric > 512) {
+	$maxnumeric = 4;
+    }
+    
+    if (defined $collectcfg->{'debug'} && $collectcfg->{'debug'} =~ /^true$/i) {
+	$debug = 1;
+    }
+    if ($mode !~ /^(all|compress_text|build_index|infodb)$/) {
+	if (defined $collectcfg->{'mode'} && $collectcfg->{'mode'} =~ /^(all|compress_text|build_index|infodb)$/) {
+	    $mode = $collectcfg->{'mode'};
+	} else {
+	    $mode = "all"; # the default
+	}
+    }
+    if (defined $collectcfg->{'index'} && $indexname eq "") {
+	$indexname = $collectcfg->{'index'};
+    }
+    if (defined $collectcfg->{'no_text'} && $no_text == 0) {
+	if ($collectcfg->{'no_text'} =~ /^true$/i) {
+	    $no_text = 1;
+	}
+    }
+    if (defined $collectcfg->{'no_strip_html'} && $no_strip_html == 0) {
+	if ($collectcfg->{'no_strip_html'} =~ /^true$/i) {
+	    $no_strip_html = 1;
+	}
+    }
+    if (defined $collectcfg->{'remove_empty_classifications'} && $remove_empty_classifications == 0) {
+	if ($collectcfg->{'remove_empty_classifications'} =~ /^true$/i) {
+	    $remove_empty_classifications = 1;
+	}
+    }
+    
+    if ($buildtype eq "mgpp" && defined $collectcfg->{'textcompress'}) {
+	$textindex = $collectcfg->{'textcompress'};
+    }
+    if (defined $collectcfg->{'gli'} && $collectcfg->{'gli'} =~ /^true$/i) {
+	$gli = 1;
+    }
+
+    if ($sections_index_document_metadata !~ /\S/ && defined $collectcfg->{'sections_index_document_metadata'}) {
+	$sections_index_document_metadata = $collectcfg->{'sections_index_document_metadata'};
+    }
+    
+    if ($sections_index_document_metadata !~ /^(never|always|unless_section_metadata_exists)$/) {
+	$sections_index_document_metadata = "never";
+    }
+    
+    ($removeold, $keepold, $incremental) = &scriptutil::check_removeold_and_keepold($removeold, $keepold, $incremental, "building", $collectcfg);
+ 
+    $gli = 0 unless defined $gli;
+
+    # If the disable_OAI flag is not present, the option $disable_OAI with the value of 0 will be passed to basebuilder.pm
+    $disable_OAI = 0 unless defined $disable_OAI;
+    
+    # New argument to track whether build is incremental
+    $incremental = 0 unless defined $incremental;
+
+    print STDERR "<Build>\n" if $gli;
+
+    #set the text index
+    if (($buildtype eq "mgpp") || ($buildtype eq "lucene")) {
+	if ($textindex eq "") {
+	    $textindex = "text";
+	}
+    }
+    else {
+	$textindex = "section:text";
+    }
+
+    # fill in the default archives and building directories if none
+    # were supplied, turn all \ into / and remove trailing /
+
+    my ($realarchivedir, $realbuilddir);
+    # Modified so that the archivedir, if provided as an argument, is made
+    # absolute if it isn't already
+    if ($archivedir eq "")
+      {
+        $archivedir = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "archives");
+      }
+    else
+      {
+        $archivedir = &util::make_absolute($ENV{'GSDLCOLLECTDIR'}, $archivedir);
+      }
+    # End Mod
+    $archivedir =~ s/[\\\/]+/\//g;
+    $archivedir =~ s/\/$//;
+
+    if ($builddir eq "") {
+	$builddir = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "building");
+	if ($incremental) {
+	    &gsprintf($out, "{buildcol.incremental_default_builddir}\n");
+	}
+    }
+    $builddir =~ s/[\\\/]+/\//g;
+    $builddir =~ s/\/$//;
+
+    # update the archive cache if needed
+    if ($cachedir) {
+	&gsprintf($out, "{buildcol.updating_archive_cache}\n")
+	    if ($verbosity >= 1);
+
+	$cachedir =~ s/[\\\/]+$//;
+	$cachedir .= "/collect/$collection" unless 
+	    $cachedir =~ /collect\/$collection/;
+
+	$realarchivedir = "$cachedir/archives";
+	$realbuilddir = "$cachedir/building";
+	&util::mk_all_dir ($realarchivedir);
+	&util::mk_all_dir ($realbuilddir);
+	&util::cachedir ($archivedir, $realarchivedir, $verbosity);
+
+    } else {
+	$realarchivedir = $archivedir;
+	$realbuilddir = $builddir;
+    }
+
+    # build it in realbuilddir
+    &util::mk_all_dir ($realbuilddir);
+
+    my ($buildertype, $builderdir,  $builder);
+    # if a builder class has been created for this collection, use it
+    # otherwise, use the mg or mgpp builder
+    if (-e "$ENV{'GSDLCOLLECTDIR'}/custom/${collection}/perllib/custombuilder.pm") {
+	$builderdir = "$ENV{'GSDLCOLLECTDIR'}/custom/${collection}/perllib";
+	$buildertype = "custombuilder";
+    } elsif (-e "$ENV{'GSDLCOLLECTDIR'}/perllib/custombuilder.pm") {
+	$builderdir = "$ENV{'GSDLCOLLECTDIR'}/perllib";
+	$buildertype = "custombuilder";
+    } elsif (-e "$ENV{'GSDLCOLLECTDIR'}/perllib/${collection}builder.pm") {
+	$builderdir = "$ENV{'GSDLCOLLECTDIR'}/perllib";
+	$buildertype = "${collection}builder";
+    } else {
+	$builderdir = "$ENV{'GSDLHOME'}/perllib";
+	if ($buildtype eq "lucene") {
+	    $buildertype = "lucenebuilder";
+	}
+	elsif ($buildtype eq "mgpp") {
+	    $buildertype = "mgppbuilder";
+	}
+	else {
+	    $buildertype = "mgbuilder";
+	}
+    }
+	
+    require "$builderdir/$buildertype.pm";
+
+    eval("\$builder = new $buildertype(\$collection, " .
+	 "\$realarchivedir, \$realbuilddir, \$verbosity, " .
+	 "\$maxdocs, \$debug, \$keepold, \$incremental, " .
+	 "\$remove_empty_classifications, " .
+	 "\$out, \$no_text, \$faillog, \$gli, \$disable_OAI)");
+    die "$@" if $@;
+
+    $builder->init();
+    $builder->set_maxnumeric($maxnumeric);
+    
+    if (($buildertype eq "mgppbuilder") && $no_strip_html) {
+	$builder->set_strip_html(0);
+    }
+    if ($sections_index_document_metadata ne "never") {
+	$builder->set_sections_index_document_metadata($sections_index_document_metadata);
+    }
+        
+    if ($mode =~ /^all$/i) {
+	$builder->compress_text($textindex);
+	$builder->build_indexes($indexname);
+	$builder->make_infodatabase();
+	$builder->collect_specific();
+    } elsif ($mode =~ /^compress_text$/i) {
+	$builder->compress_text($textindex);
+    } elsif ($mode =~ /^build_index$/i) {
+	$builder->build_indexes($indexname);	
+    } elsif ($mode =~ /^infodb$/i) {
+	$builder->make_infodatabase();
+    } else {
+	(&gsprintf(STDERR, "{buildcol.unknown_mode}\n", $mode) && die);
+    }
+
+    $builder->make_auxiliary_files() if !$debug;
+    $builder->deinit();
+    
+    if (($realbuilddir ne $builddir) && !$debug) {
+	&gsprintf($out, "{buildcol.copying_back_cached_build}\n")
+	    if ($verbosity >= 1);
+	&util::rm_r ($builddir);
+	&util::cp_r ($realbuilddir, $builddir);
+    }
+
+    close OUT if $close_out;
+    close FAILLOG;
+
+    print STDERR "</Build>\n" if $gli;
+}
+## main() ##
+
+
Index: /gsdl/stable/bin/script/cancel_build.pl
===================================================================
--- /gsdl/stable/bin/script/cancel_build.pl	(revision 20131)
+++ /gsdl/stable/bin/script/cancel_build.pl	(revision 20131)
@@ -0,0 +1,123 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# cancel_build.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2000 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will create a .kill file within the GSDLCOLLECTDIR/collect-name
+# directory which will cause any import.pl or buildcol.pl processes running
+# on that collection to abort.
+# It then cleans any mess left laying around the collection (including the
+# import directory !!).
+# cancel_build.pl is really only intended to be called from within the 
+# library's collectoraction and isn't much use for anything else. As such it
+# should be rewritten in C++ one day and included in the collectoraction 
+# itself.
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use util;
+use parsargv;
+use File::Copy;
+
+sub print_usage {
+    print STDERR "\n";
+    print STDERR "cancel_build.pl: Cancel a build in progress. This script is\n";
+    print STDERR "                 called from the collector and is not intended\n";
+    print STDERR "                 for general use.\n\n";
+    print STDERR "  usage: $0 [options] collection-name\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -collectdir directory  Collection directory (defaults to " .
+	&util::filename_cat ($ENV{'GSDLHOME'}, "collect") . ")\n\n";
+}
+
+&main();
+
+sub main {
+    if (!parsargv::parse(\@ARGV, 'collectdir/.*/', \$collectdir)) {
+	&print_usage();
+	die "\n";
+    }
+
+    my $collection = pop @ARGV;
+    if (!defined $collection || $collection !~ /\w/) {
+	print STDERR "no collection specified\n";
+	&print_usage();
+	die "\n";
+    }
+
+    my $cdir = &util::filename_cat ($collectdir, $collection);
+    if ($collectdir eq "") {
+	$collectdir = &util::filename_cat ($ENV{'GSDLHOME'}, "collect");
+	$cdir = &util::filename_cat ($collectdir, $collection);
+    } elsif (!-d $cdir) {
+	$cdir = &util::filename_cat ($ENV{'GSDLHOME'}, "collect", $collection);
+    }
+
+    if (! -d $cdir) {
+	print STDERR "Collection does not exist ($cdir)\n";
+	exit (1);
+    }
+
+    # create .kill file
+    my $killfile = &util::filename_cat ($cdir, ".kill");
+    if (!open (KILLFILE, ">$killfile")) {
+	print STDERR "Couldn't create .kill file ($killfile)\n";
+	exit (1);
+    }
+    print KILLFILE "kill $collection\n";
+    close KILLFILE;
+
+    sleep (2); # just give it a chance to die gracefully;
+
+    # remove archives, building, and import directories
+    &util::rm_r (&util::filename_cat ($cdir, "import"));
+    &util::rm_r (&util::filename_cat ($cdir, "building"));
+    &util::rm_r (&util::filename_cat ($cdir, "archives"));
+
+    # remove any other temporary files that may have been left laying around
+    # by the build
+    my $buildfile = &util::filename_cat ($collectdir, ".build");
+    &util::rm ($buildfile) if -e $buildfile;
+    my $bldfile = &util::filename_cat ($collectdir, "$collection.bld");
+    &util::rm ($bldfile) if -e $bldfile;
+    my $bldfile_d = &util::filename_cat ($collectdir, "$collection.bld.download");
+    &util::rm ($bldfile_d) if -e $bldfile_d;
+    my $bldfile_i = &util::filename_cat ($collectdir, "$collection.bld.import");
+    &util::rm ($bldfile_i) if -e $bldfile_i;
+    my $bldfile_b = &util::filename_cat ($collectdir, "$collection.bld.build");
+    &util::rm ($bldfile_b) if -e $bldfile_b;
+    my $bldfile_f = &util::filename_cat ($collectdir, "$collection.bld.final");
+    &util::rm ($bldfile_f) if -e $bldfile_f;
+    
+    # if there's an archives.org directory, rename it back to archives
+    if (-d &util::filename_cat ($cdir, "archives.org")) {
+	&File::Copy::move (&util::filename_cat ($cdir, "archives.org"),
+			   &util::filename_cat ($cdir, "archives"));
+    }
+}
Index: /gsdl/stable/bin/script/checkwritability.bat
===================================================================
--- /gsdl/stable/bin/script/checkwritability.bat	(revision 20131)
+++ /gsdl/stable/bin/script/checkwritability.bat	(revision 20131)
@@ -0,0 +1,75 @@
+@echo off
+
+if "%GSDLHOME%" == "" goto EnvNotSet
+
+REM test if we have write permission on the greenstone install directory
+echo.
+echo Checking if GSDLHOME is writable...
+echo This is a temporary file. It is safe to delete it. > "%GSDLHOME%\etc\testing.tmp"
+if not exist "%GSDLHOME%\etc\testing.tmp" goto CantWrite
+del "%GSDLHOME%\etc\testing.tmp"
+echo GSDLHOME has write permission for the current user.
+echo.
+goto TheEnd
+
+:CantWrite
+echo.
+echo.
+echo.
+echo -----------------------------------
+
+if "%GSDLLANG%" == "en" echo  WARNING: CANNOT WRITE TO GSDLHOME
+if "%GSDLLANG%" == "es" echo  ATENCIÃN: NO PUEDE ESCRIBIR EN EL DIRECTORIO RAÃZ DE GREENSTONE.
+if "%GSDLLANG%" == "fr" echo  AVERTISSEMENT: ECRIRE IMPOSSIBLE DANS LE DOSSIER D'ACCUEIL DE GREENSTONE
+if "%GSDLLANG%" == "ru" echo  ÐÐÐÐÐÐÐÐ: ÐÐÐÐÐÐÐÐÐÐ ÐÐ¡Ð£Ð©ÐÐ¡Ð¢ÐÐÐ¢Ð¬ ÐÐÐÐÐ¡Ð¬ Ð ÐÐÐÐÐšÐÐ®Ð® ÐÐÐÐÐ£ GREENSTONE
+
+echo -----------------------------------
+If "%GSDLLANG%" == "en" echo Greenstone needs write permission for the Greenstone home folder,
+if "%GSDLLANG%" == "en" echo which is %GSDLHOME%,
+if "%GSDLLANG%" == "en" echo but right now it does not.
+if "%GSDLLANG%" == "en" echo Please grant "Full Control" for this folder (and all subfolders)  
+if "%GSDLLANG%" == "en" echo to the current user (%username%) and try again.
+
+if "%GSDLLANG%" == "es" echo Greenstone necesita permiso de escritura en el directorio:
+if "%GSDLLANG%" == "es" echo %GSDLHOME%,
+if "%GSDLLANG%" == "es" echo pero no lo tiene.
+if "%GSDLLANG%" == "es" echo Por favor, concÃ©dale âControl completoâ al usuario actual (%username%), 
+if "%GSDLLANG%" == "es" echo y vuelva a intentarlo.
+
+if "%GSDLLANG%" == "fr" echo Greenstone nÃ©cessite une autorisation d'Ã©criture dans le dossier 
+if "%GSDLLANG%" == "fr" echo principal de Greenstone: %GSDLHOME%,
+if "%GSDLLANG%" == "fr" echo mais pour l'instant cette autorisation n'existe pas.
+if "%GSDLLANG%" == "fr" echo Autorisez le Â«Â ContrÃŽle TotalÂ Â» sur ce dossier (et sur tous les sous-dossiers)
+if "%GSDLLANG%" == "fr" echo pour l'utilisateur courant (%username%) puis re-essayez.
+
+if "%GSDLLANG%" == "ru" echo Greenstone ÑÑÐµÐ±ÑÐµÑÑÑ ÑÐ°Ð·ÑÐµÑÐµÐœÐžÐµ ÐœÐ° Ð·Ð°Ð¿ÐžÑÑ Ð² ÐŽÐŸÐŒÐ°ÑÐœÑÑ Ð¿Ð°Ð¿ÐºÑ %GSDLHOME%,
+if "%GSDLLANG%" == "ru" echo Ð² ÐŽÐ°ÐœÐœÑÐ¹ ÐŒÐŸÐŒÐµÐœÑ Ð·Ð°Ð¿ÐžÑÑ Ð² ÐŽÐŸÐŒÐ°ÑÐœÑÑ Ð¿Ð°Ð¿ÐºÑ Ð·Ð°Ð¿ÑÐµÑÐµÐœÐ°.
+if "%GSDLLANG%" == "ru" echo ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ° ÑÑÑÐ°ÐœÐŸÐ²ÐžÑÐµ ÐÐŸÐ»ÐœÑÐ¹ ÐŽÐŸÑÑÑÐ¿ ÐŽÐ»Ñ Ð¿Ð°Ð¿ÐºÐž (Ðž Ð²ÑÐµÑ
+ Ð²Ð»ÐŸÐ¶ÐµÐœÐœÑÑ
+ Ð¿Ð°Ð¿ÐŸÐº)
+if "%GSDLLANG%" == "ru" echo ÐŽÐ»Ñ ÑÐµÐºÑÑÐµÐ³ÐŸ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ (%username%) Ðž Ð¿ÐŸÐ¿ÑÐŸÐ±ÑÐ¹ÑÐµ Ð·Ð°ÐœÐŸÐ²ÐŸ.
+
+echo.
+
+if "%GSDLLANG%" == "en" echo (Alternatively, re-install Greenstone to a location where you have Full
+if "%GSDLLANG%" == "en" echo Control already, such as a your home folder or 'My Documents'.)
+
+if "%GSDLLANG%" == "es" echo (Alternativamente, reinstale Greenstone en una localizaciÃ³n en la que tenga âControl completoâ, 
+if "%GSDLLANG%" == "es" echo como su directorio raÃ­z o âMis documentosâ).
+
+if "%GSDLLANG%" == "fr" echo (Alternativement, re-installez Greenstone Ã  l'emplacement oÃ¹ vous avez dÃ©jÃ  le Â«Â ContrÃŽle TotalÂ Â», 
+if "%GSDLLANG%" == "fr" echo comme votre dossier d'accueil ou  "Mes Documents".)
+
+if "%GSDLLANG%" == "ru" echo (ÐÐžÐ±ÐŸ, Ð¿ÐµÑÐµÑÑÑÐ°ÐœÐŸÐ²ÐžÑÐµ Greenstone Ð² ÑÑ Ð¿Ð°Ð¿ÐºÑ, Ðº ÐºÐŸÑÐŸÑÐŸÐ¹ ÐÑ ÑÐ¶Ðµ ÐžÐŒÐµÐµÑÐµ Ð¿ÐŸÐ»ÐœÑÐ¹ ÐŽÐŸÑÑÑÐ¿, 
+if "%GSDLLANG%" == "ru" echo ÐœÐ°Ð¿ÑÐžÐŒÐµÑ Ð² ÑÐ²ÐŸÑ ÐŽÐŸÐŒÐ°ÑÐœÑÑ Ð¿Ð°Ð¿ÐºÑ ÐžÐ»Ðž Ð² Ð¿Ð°Ð¿ÐºÑ "ÐÐŸÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÑ".)
+
+echo.
+echo.
+echo.
+echo.
+goto TheEnd
+
+:EnvNotSet
+echo GSDLHOME not set
+
+:TheEnd
Index: /gsdl/stable/bin/script/classinfo.pl
===================================================================
--- /gsdl/stable/bin/script/classinfo.pl	(revision 20131)
+++ /gsdl/stable/bin/script/classinfo.pl	(revision 20131)
@@ -0,0 +1,218 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# classinfo.pl -- provide information about classifiers
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+use strict;
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/classify");
+
+    if (defined $ENV{'GSDLEXTS'}) {
+	my @extensions = split(/:/,$ENV{'GSDLEXTS'});
+	foreach my $e (@extensions) {
+	    my $ext_prefix = "$ENV{'GSDLHOME'}/ext/$e";
+
+	    unshift (@INC, "$ext_prefix/perllib");
+	    unshift (@INC, "$ext_prefix/perllib/cpan");
+	    unshift (@INC, "$ext_prefix/perllib/plugins");
+	    unshift (@INC, "$ext_prefix/perllib/plugouts");
+	    unshift (@INC, "$ext_prefix/perllib/classify");
+	}
+    }
+}
+
+use classify;
+use util;
+use gsprintf;
+use printusage;
+
+use parse2;
+
+my $arguments =
+    [ { 'name' => "collection",
+	'desc' => "{classinfo.collection}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "xml",
+	'desc' => "{scripts.xml}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "listall",
+	'desc' => "{scripts.listall}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "describeall",
+	'desc' => "{scripts.describeall}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no" } ];
+
+my $options = { 'name' => "classinfo.pl",
+		'desc' => "{classinfo.desc}",
+		'args' => $arguments };
+
+sub gsprintf
+{
+    return &gsprintf::gsprintf(@_);
+}
+
+sub main {
+    my $collection = "";
+    my $xml = 0;
+    my $listall = 0;
+    my $describeall = 0;
+    my $language;
+
+    my $hashParsingResult = {};
+    # general options available to all classifiers
+    my $intArgLeftinAfterParsing = parse2::parse(\@ARGV,$arguments,$hashParsingResult,"allow_extra_options");
+    # parse returns -1 if an error occurred
+    if($intArgLeftinAfterParsing == -1)
+    {
+	&PrintUsage::print_txt_usage($options, "{classinfo.params}");
+	die "\n";
+    }
+
+    foreach my $strVariable (keys %$hashParsingResult)
+    {
+	eval "\$$strVariable = \$hashParsingResult->{\"\$strVariable\"}";
+    }
+    # If $language has been specified, load the appropriate resource bundle
+    # (Otherwise, the default resource bundle will be loaded automatically)
+    if ($language) {
+	&gsprintf::load_language_specific_resource_bundle($language);
+    }
+    
+    # If there is not exactly 1 argument left (classifier name), then the arguments were wrong
+    # If the user specified -h, then we output the usage also
+    if((@ARGV && $ARGV[0] =~ /^\-+h/) )
+    {
+	PrintUsage::print_txt_usage($options, "{classinfo.params}");  
+        die "\n";
+    }
+
+    # If there is not exactly 1 argument left (classifier name), then the arguments were wrong (apart from if we had listall or describeall set)
+    if ($listall == 0 && $describeall ==0 && $intArgLeftinAfterParsing == 0) {
+	gsprintf(STDERR, "{classinfo.no_classifier_name}\n\n");
+	PrintUsage::print_txt_usage($options, "{classinfo.params}", 1);
+	die "\n";
+    }
+	
+    # we had some arguments that we weren't expecting
+    if ($intArgLeftinAfterParsing > 1) {
+	pop(@ARGV); # assume that the last arg is the classifier name
+	gsprintf(STDERR, "{common.invalid_options}\n\n", join (',', @ARGV));
+	PrintUsage::print_txt_usage($options, "{classinfo.params}", 1);
+	die "\n";
+    }
+
+    # Get classifier
+    my $classifier = shift (@ARGV);
+    if (defined $classifier) {
+	$classifier =~ s/\.pm$//; # allow xxx.pm as the argument
+    }
+
+    # make sure the classifier is loaded from the correct location - a hack.
+    if ($collection ne "") {
+	$ENV{'GSDLCOLLECTDIR'} = &util::filename_cat ($ENV{'GSDLHOME'}, "collect", $collection);
+    } else {
+	$ENV{'GSDLCOLLECTDIR'} = $ENV{'GSDLHOME'};
+    }
+ 
+    if ($listall || $describeall) {
+	my $classify_dir = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "perllib", "classify");
+	my @classifier_list = ();
+	if (opendir (INDIR, $classify_dir)) {
+	    @classifier_list = grep (/\.pm$/, readdir (INDIR));
+	    closedir (INDIR);
+	}
+
+	if ((defined $ENV{'GSDLEXTS'}) && ($collection eq "")) {
+	    my @extensions = split(/:/,$ENV{'GSDLEXTS'});
+	    foreach my $e (@extensions) {
+		my $ext_prefix = &util::filename_cat($ENV{'GSDLHOME'},"ext",$e);
+		my $ext_classify_dir = &util::filename_cat($ext_prefix, "perllib", "classify");
+
+		if (opendir (INDIR, $ext_classify_dir)) {
+		    my @ext_classifier_list = grep (/\.pm$/, readdir (INDIR));
+		    closedir (INDIR);
+
+		    push(@classifier_list,@ext_classifier_list);
+		}
+
+	    }
+	}
+
+	print STDERR "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+	print STDERR "<ClassifyList length=\"" . scalar(@classifier_list) . "\">\n";
+	foreach my $classifier (@classifier_list) {
+	    $classifier =~ s/\.pm$//;
+	    my $classifierobj = &classify::load_classifier_for_info ($classifier);
+	    if ($describeall) {
+		$classifierobj->print_xml_usage(0);
+	    }
+	    else {
+		$classifierobj->print_xml_usage(0, 1);
+	    }
+	}
+	print STDERR "</ClassifyList>\n";
+    }
+    else {
+	&print_single_classifier($classifier, $xml, 1);
+    }
+}
+
+
+sub print_single_classifier {
+    my ($classifier, $xml, $header) = @_;
+    my $classobj = &classify::load_classifier_for_info ($classifier);
+    if ($xml) {
+	$classobj->print_xml_usage($header);
+    }
+    else {
+	&gsprintf(STDERR, "\n{classinfo.passing_options}\n\n");
+	&gsprintf(STDERR, "{classinfo.option_types}:\n\n");
+	&gsprintf(STDERR, "{classinfo.specific_options}\n\n");
+	&gsprintf(STDERR, "{classinfo.general_options}\n\n");
+	&gsprintf(STDERR, "$classifier {classinfo.info}:\n\n");
+	
+	$classobj->print_txt_usage();
+    }
+    
+}
+
+
+&main ();
Index: /gsdl/stable/bin/script/cleantmp.pl
===================================================================
--- /gsdl/stable/bin/script/cleantmp.pl	(revision 20131)
+++ /gsdl/stable/bin/script/cleantmp.pl	(revision 20131)
@@ -0,0 +1,80 @@
+#!/usr/bin/perl
+
+###########################################################################
+#
+# cleantmp.pl
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# cleantmp.pl cleans up the gsdl/tmp directory
+# it's intended mainly for use by the collectoraction
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use parsargv;
+use util;
+
+sub print_usage {
+    print STDERR "\n";
+    print STDERR "cleantmp.pl: Cleans up the Greenstone tmp directory by deleting anything\n";
+    print STDERR "             more than -expire_days days old.\n\n";
+    print STDERR "\n  usage: $0 [options]\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -expire_days number   The number of days old information in the tmp\n";
+    print STDERR "                         directory must be before it is removed (defaults\n";
+    print STDERR "                         to 7 days)\n\n";
+}
+
+&main ();
+
+sub main {
+    
+    if (!parsargv::parse(\@ARGV, 'expire_days/\d/7', \$expire_days)) {
+	&print_usage();
+	die "\n";
+    }
+
+    my $current_time = time;
+    my $expire_time = ($current_time - ($expire_days*60*60*24));
+
+    my $tmpdir = &util::filename_cat ($ENV{'GSDLHOME'}, "tmp");
+
+    opendir (TMP, $tmpdir) || die "cleantmp.pl: couldn't open $tmpdir\n";
+    my @files = readdir TMP;
+    closedir TMP;
+
+    foreach $file (@files) {
+	next if ($file =~ /^\.\.$/);
+
+	if ($file =~ /^tbuild/) {
+	    my $thisfile = &util::filename_cat ($tmpdir, $file);
+	    my @stats = stat ($thisfile);
+	    if ($stats[9] < $expire_time) {
+		&util::rm_r ($thisfile);
+	    }
+	}
+    }
+}
Index: /gsdl/stable/bin/script/convert_collection.pl
===================================================================
--- /gsdl/stable/bin/script/convert_collection.pl	(revision 20131)
+++ /gsdl/stable/bin/script/convert_collection.pl	(revision 20131)
@@ -0,0 +1,112 @@
+#! /usr/bin/perl -w
+
+# converts an old style humanity collection which uses an index.txt file to
+# use a single metadata.xml file instead
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use util;
+use cfgread;
+
+my $collection = $ARGV[0];
+my $collectdir = &util::filename_cat($ENV{'GSDLHOME'}, "collect", $collection);
+my $importdir = &util::filename_cat($collectdir, "import");
+
+die unless -d $importdir;
+
+# new import structure will be created in "import.new" directory
+my $importnewdir = $importdir . ".new";
+`mkdir $importnewdir`;
+
+
+# read in index.txt file and generate metadata.xml, in the process
+# converting the html files and copying them across to the import.new
+# directory
+
+my $metadata_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
+$metadata_xml .= "<!DOCTYPE DirectoryMetadata SYSTEM " .
+    "\"http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd\">\n";
+$metadata_xml .= "<DirectoryMetadata>\n\n";
+
+my $index_txt = &util::filename_cat($importdir, "index.txt");
+
+open (INDEXTXT, $index_txt) || die;
+
+my $line = [];
+my @fields = ();
+my $count = 0;
+while (defined ($line = cfgread::read_cfg_line("main::INDEXTXT"))) {
+
+#    last if $count > 10;
+
+    if ($line->[0] eq "key:") {
+	shift @$line;
+	@fields = @$line;
+    } else {
+	
+	my $jobnumber = shift @$line;
+	&new_document($jobnumber);
+	$count ++;
+
+	my $i = 0;
+	for ($i = 0; $i < scalar(@$line); $i++) {
+	    if ($line->[$i] =~ /^<([^>]+)>(.*)$/) {
+		&set_metadata($1, $2);
+	    } else {
+		if (defined ($fields[$i])) {
+		    &set_metadata($fields[$i], $line->[$i]);
+		} else {
+		    print STDERR "error 1\n";
+		}
+	    }
+	}
+
+	$metadata_xml .= "    </Description>\n";
+	$metadata_xml .= "  </FileSet>\n\n";
+    }
+}
+close INDEXTXT;
+
+$metadata_xml .= "</DirectoryMetadata>\n";
+
+my $metafile = &util::filename_cat($importnewdir, "metadata.xml");
+open (META, ">$metafile") || die;
+print META $metadata_xml;
+close META;
+
+
+sub new_document {
+    my ($jobnumber) = @_;
+
+    print STDERR "creating new document ($jobnumber)\n";
+
+    my $docdir = &util::filename_cat($importdir, $jobnumber);
+    die unless -d $docdir;
+
+    # copy whole directory across to import.new
+    $jobnumber =~ s/^.*?\///;
+    my $newdocdir = &util::filename_cat($importnewdir, $jobnumber);
+    die if -e $newdocdir;
+    `cp -r $docdir $newdocdir`;
+
+    # convert the htm file to use the new syntax
+    my $htmfile = &util::filename_cat($newdocdir, "$jobnumber.htm");
+    die unless -e $htmfile;
+    `convert_toc.pl < $htmfile > $htmfile.new`;
+    `mv $htmfile.new $htmfile`;
+
+    # update metadata.xml
+    $metadata_xml .= "  <FileSet>\n";
+    $metadata_xml .= "    <FileName>$jobnumber</FileName>\n";
+    $metadata_xml .= "    <Description>\n";
+}
+
+sub set_metadata {
+    my ($key, $value) = @_;
+
+    $metadata_xml .= "      <Metadata name=\"$key\" mode=\"accumulate\">$value</Metadata>\n";
+}
Index: /gsdl/stable/bin/script/convert_toc.pl
===================================================================
--- /gsdl/stable/bin/script/convert_toc.pl	(revision 20131)
+++ /gsdl/stable/bin/script/convert_toc.pl	(revision 20131)
@@ -0,0 +1,124 @@
+#! /usr/bin/perl -w
+
+# convert_toc.pl converts old <<TOC>> marked up files to use the new
+# <Section> syntax (suitable for processing by HTMLPlug -description_tags
+
+use File::Basename;
+
+my $level = 0;
+
+sub main {
+  open STDIN, "<$ARGV[0]" or die "$ARGV[0]: $!\n";
+  open STDOUT, ">$ARGV[1]" or die "$ARGV[1]: $!\n";
+
+  my $dirname = &File::Basename::dirname($ARGV[0]);
+
+  my $content = "";
+  
+  while (<STDIN>) {
+    $_ =~ s/[\cJ\cM]+$/\n/;
+    $content .= $_;
+  }
+
+  # fix images
+  $content =~ s/&lt;&lt;I&gt;&gt;\s*(\w+\.(?:png|jpe?g|gif))\s*(.*?)<\/p>/rename_image_old($1, $2, $dirname)/iegs;
+  $content =~ s/<img\s+src=\"?(\w+\.(?:png|jpe?g|gif))\"?/rename_image($1, $dirname)/iegs;
+
+  # process section title
+  $content =~ s/(?:<P[^>]*>|<BR>)(?:\s*<\/?[^>]*>)*?&lt;&lt;TOC(\d+)&gt;&gt;(.*?)(?=<\/?P[^>]*>|<BR>)/
+      process_toc ($1, $2)/sige;
+
+  # close the remaining sections
+  my $section_ending = "<!--\n";
+  for (my $j = 0; $j < $level; $j++) {
+    $section_ending .= "</Section>\n";
+  }
+  $section_ending .= "-->\n";
+  $content =~ s/(<\/body>)/$section_ending.$1/sie;
+
+  print STDOUT $content;
+  close STDOUT; close STDIN;
+}
+
+sub process_toc {
+  my ($thislevel, $title) = @_;
+  my $toc = '';
+ 
+  $title =~ s/<[^>]+>//sg;
+  $title =~ s/^\s+//s;
+  $title =~ s/\s+$//s;
+  $title =~ s/\n/ /sg;
+
+  $toc .= "\n<!--\n";
+
+  if ($thislevel <= $level) {
+    for (my $i = 0; $i < ($level-$thislevel+1); $i++) {
+	$toc .= "</Section>\n";
+    }
+  }
+
+  $toc .= "<Section>\n".
+	"  <Description>\n".
+	"    <Metadata name=\"Title\">$title</Metadata>\n".
+	"  </Description>\n".
+	"-->\n";
+
+  $level = $thislevel;
+
+  return $toc;
+}
+
+sub rename_image_old {
+    my ($image_name, $following_text, $dirname) = @_;
+
+    &rename_image($image_name, $dirname);
+
+    return "<center><img src=\"$image_name\"><br>$following_text<\/center><\/p>\n";
+}
+
+
+# may need to rename image files if case isn't consistent
+# (i.e. collections prepared on windows may have images named
+# AAA.GIF which are linked into the HTML as aaa.gif)
+sub rename_image {
+    my ($image_name, $dirname) = @_;
+
+
+    if (!-e "$dirname/$image_name") {
+
+	my ($pre, $ext) = $image_name =~ /^([^\.]+)\.(.*)$/;
+	my $image_name_uc = uc($image_name);
+	my $image_name_lc = lc($image_name);
+	my $image_name_ul = uc($pre) . "." . lc($ext);
+	my $image_name_lu = lc($pre) . "." . uc($ext);
+
+	if (-e "$dirname/$image_name_uc") {
+	    print STDERR "renaming $dirname/$image_name_uc --> $dirname/$image_name\n";
+	    rename ("$dirname/$image_name_uc", "$dirname/$image_name");
+
+	} elsif (-e "$dirname/$image_name_lc") {
+	    print STDERR "renaming $dirname/$image_name_lc --> $dirname/$image_name\n";
+	    rename ("$dirname/$image_name_lc", "$dirname/$image_name");
+	
+	} elsif (-e "$dirname/$image_name_ul") {
+	    print STDERR "renaming $dirname/$image_name_ul --> $dirname/$image_name\n";
+	    rename ("$dirname/$image_name_ul", "$dirname/$image_name");
+	
+	} elsif (-e "$dirname/$image_name_lu") {
+	    print STDERR "renaming $dirname/$image_name_lu --> $dirname/$image_name\n";
+	    rename ("$dirname/$image_name_lu", "$dirname/$image_name");
+	
+	} else {
+	    print STDERR "ERROR**** $dirname/$image_name could not be found\n";
+	    if (open (ERROR, ">>error.txt")) {
+		print ERROR "ERROR**** $dirname/$image_name could not be found\n";
+		close ERROR;
+	    }
+	}
+    }
+    return "<img src=\"$image_name\"";
+}
+
+
+
+&main;
Index: /gsdl/stable/bin/script/convert_toc_dir.pl
===================================================================
--- /gsdl/stable/bin/script/convert_toc_dir.pl	(revision 20131)
+++ /gsdl/stable/bin/script/convert_toc_dir.pl	(revision 20131)
@@ -0,0 +1,41 @@
+#! /usr/bin/perl -w
+
+# run convert_toc.pl on any html files found in the directory passed in on
+# the command line (or any subdirs).
+
+die "\$GSDLOS not set !\n" if (!defined $ENV{GSDLOS});
+my ($move, $separator);
+if ($ENV{GSDLOS} eq "windows") {
+  $move = "move";
+  $separator = "\\";
+} else {
+  $move = "mv";
+  $separator = "/";
+}
+
+&recurse($ARGV[0]);
+
+sub recurse {
+    my ($dir) = @_;
+
+    if (!-d $dir) {
+	print STDERR "ERROR: $dir isn't a directory\n";
+	return;
+    }
+
+    opendir (DIR, $dir) || die;
+    my @files = readdir DIR;
+    closedir DIR;
+
+    foreach my $file (@files) {
+	next if $file =~ /^\.\.?$/;
+	my $fullpath = "$dir$separator$file";
+	if (-d $fullpath) {
+	    &recurse($fullpath);
+	} elsif ($file =~ /\.html?$/i) {
+	    print STDERR "converting $fullpath\n";
+	    `convert_toc.pl $fullpath $fullpath.new`;
+	    `$move $fullpath.new $fullpath`;
+	}
+    }
+}
Index: /gsdl/stable/bin/script/delcol.pl
===================================================================
--- /gsdl/stable/bin/script/delcol.pl	(revision 20131)
+++ /gsdl/stable/bin/script/delcol.pl	(revision 20131)
@@ -0,0 +1,87 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# delcol.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use util;
+use parsargv;
+
+sub print_usage {
+    print STDERR "\n";
+    print STDERR "delcol.pl: Deletes (forever) a collection.\n\n";
+    print STDERR "  usage: $0 [options] collection-name\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -f                     Force deletion of collection without prompting\n\n";
+}
+
+&main();
+
+sub main {
+    my $force = 0;
+    if (!parsargv::parse(\@ARGV, 'f', \$force)) {
+	&print_usage();
+	die "\n";
+    }
+
+    # get and check the collection name
+    if (($collection = &util::use_collection(@ARGV)) eq "") {
+	&print_usage();
+	exit (1);
+    }
+
+    if (!$force) {
+	print STDOUT "Are you sure you want to completely remove the $collection collection?\n";
+	print STDOUT "(the $ENV{'GSDLCOLLECTDIR'} directory will be deleted). [y/n]\n";
+	my $in = <STDIN>;
+	if ($in !~ /^y(es)?$/i) {
+	    print STDOUT "Deletion of $collection collection cancelled\n";
+	    exit (0);
+	}
+    }
+    # delete any temporary files that are laying around
+    my $tmpdir = &util::filename_cat ($ENV{'GSDLHOME'}, "tmp");
+    if (opendir (TMPDIR, $tmpdir)) {
+	my @tmpfiles = readdir (TMPDIR);
+	closedir TMPDIR;
+	map { &util::rm(&util::filename_cat($tmpdir, $_)) if $_ =~ /^$collection/; } @tmpfiles;
+    }
+
+    &util::rm_r ($ENV{'GSDLCOLLECTDIR'});
+
+    # check if everything was deleted successfully
+    if (-d $ENV{'GSDLCOLLECTDIR'}) {
+	print STDERR "\ndelcol.pl WARNING: Not all files in $ENV{'GSDLCOLLECTDIR'} could\n";
+	print STDERR "be deleted\n";
+	exit (2);
+    }
+
+    print STDERR "$collection collection successfully deleted\n";
+    exit (0);
+}
Index: /gsdl/stable/bin/script/downloadfrom.pl
===================================================================
--- /gsdl/stable/bin/script/downloadfrom.pl	(revision 20131)
+++ /gsdl/stable/bin/script/downloadfrom.pl	(revision 20131)
@@ -0,0 +1,159 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# downloadfrom.pl -- program to download files from an external server
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package downloadfrom;
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/downloaders");         
+}
+
+use strict;
+no strict 'subs';
+use parse2;
+use download;
+use gsprintf 'gsprintf';
+use printusage;
+
+my $download_mode_list = 
+    [ { 'name' => "Web",
+        'desc' => "{downloadfrom.download_mode.Web}",
+	'downloadname' => "WebDownload" },
+	  { 'name' => "MediaWiki",
+	  	'desc' => "{downloadfrom.download_mode.MediaWiki}",
+	  	'downloadname' => "MediaWikiDownload" },
+      { 'name' => "OAI",
+        'desc' => "{downloadfrom.download_mode.OAI}",
+	'downloadname' => "OAIDownload" },
+      { 'name' => "Z3950",
+        'desc' => "{downloadfrom.download_mode.Z3950}",
+	'downloadname' => "Z3950Download" },
+      { 'name' => "SRW",
+        'desc' => "{downloadfrom.download_mode.SRW}",
+	'downloadname' => "SRWDownload" } ];
+
+my $arguments = 
+    [ { 'name' => "download_mode",
+	'desc' => "{downloadfrom.download_mode}",
+	'type' => "enum",
+	'list' => $download_mode_list,
+	'reqd' => "yes" },
+      { 'name' => "cache_dir",
+	'desc' => "{downloadfrom.cache_dir}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "gli",
+	'desc' => "",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "info", ,  
+	'desc' => "{downloadfrom.info}",  
+	'type' => "flag",
+	'reqd' => "no"}
+      ];
+
+my $options = { 'name' => "downloadfrom.pl",
+		'desc' => "{downloadfrom.desc}",
+		'args' => $arguments };
+
+
+# This function return the coresponding mode with a given mode string.
+sub findMode
+{
+    my ($strInput) = @_;
+
+    foreach my $hashMode (@$download_mode_list)
+    {
+	if($strInput eq $hashMode->{'name'})
+	{
+	    return $hashMode->{'downloadname'};
+	}
+    }
+    return "";
+}
+
+# main program
+sub main
+{
+    
+   my $hashOptions = {};
+   my ($strMode,$objMode,$pntArg);
+   $pntArg = \@ARGV;
+
+   # Parsing the General options for downloadfrom.pl, 
+   # this parsing operation will allow extra options, 
+   # since there might be some arguments for Download.
+   # extra arguments will be detected by the Downloads
+   parse2::parse(\@ARGV,$arguments,$hashOptions,"allow_extra_options");
+   # hashOptions: This is a hash map which maps to 
+   #              downloadfrom's arguments
+   #              $hashOptions->{'cache_dir'}
+   #              $hashOptions->{'download_mode'}
+   #              $hashOptions->{'gli'}
+   #              $hashOptions->{'info'}
+
+   $strMode = &findMode($hashOptions->{'download_mode'});
+  
+    if ($strMode eq "") {
+       &gsprintf(STDERR, "{downloadfrom.incorrect_mode}\n");
+       &PrintUsage::print_txt_usage($options, "{downloadfrom.params}");
+       die "\n";
+
+   }
+   $objMode = &download::load_download($strMode, $pntArg);
+   
+   if($hashOptions->{'info'})
+    {
+    
+	my $blnResult = &download::get_information($objMode);
+    }
+    else
+    {
+	print "downloadfrom.pl start gathering data by using $strMode...\n\n";
+	
+	# need to remove trailing slash from cache dir
+	if (defined $hashOptions->{'cache_dir'}) {
+	    $hashOptions->{'cache_dir'} =~ s/[\/\\]$//;
+	}
+	my $blnResult = &download::process($objMode,$hashOptions);
+	
+	($blnResult eq "true")?
+	    print  "\ndownloadfrom.pl has completed data gathering\n":
+	    print "\ndownloadfrom.pl has failed to gather data\n";
+    } 
+
+     
+}
+
+
+&main();
+
+
Index: /gsdl/stable/bin/script/downloadinfo.pl
===================================================================
--- /gsdl/stable/bin/script/downloadinfo.pl	(revision 20131)
+++ /gsdl/stable/bin/script/downloadinfo.pl	(revision 20131)
@@ -0,0 +1,206 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# downloadinfo.pl -- prints out information about a download module
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+use strict;
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/downloaders");
+}
+
+use download;
+use util;
+use gsprintf;
+use printusage;
+use parse2;
+
+my $arguments =
+    [ { 'name' => "collection",
+	'desc' => "{downloadinfo.collection}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "xml",
+	'desc' => "{scripts.xml}",
+	'type' => "flag",
+	'reqd' => "no"},
+      { 'name' => "listall",
+	'desc' => "{scripts.listall}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "describeall",
+	'desc' => "{scripts.describeall}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no" } ];
+
+my $options = { 'name' => "downloadinfo.pl",
+		'desc' => "{downloadinfo.desc}",
+		'args' => $arguments };
+
+sub gsprintf
+{
+    return &gsprintf::gsprintf(@_);
+}
+
+
+sub main {
+	
+    my $collection = "";
+    my $xml = 0;
+    my $listall = 0;
+    my $describeall = 0;
+    my ($language, $encoding);
+    my $hashParsingResult = {};
+    my $unparsed_args = parse2::parse(\@ARGV,$arguments,$hashParsingResult,"allow_extra_options");
+
+    # parse returns -1 on error
+    if ($unparsed_args == -1) {
+	PrintUsage::print_txt_usage($options, "{downloadinfo.params}");
+	die "\n";
+    }
+
+    foreach my $strVariable (keys %$hashParsingResult)
+    {
+	my $value = $hashParsingResult->{$strVariable};
+	# test to make sure the variable name is 'safe'
+	if ($strVariable !~ /^\w+$/) {
+ 	    die "variable name '$strVariable' isn't safe!";
+	}
+	eval "\$$strVariable = \$value";
+    }
+    
+    # if language wasn't specified, see if it is set in the environment
+    # (LC_ALL or LANG)
+    if (!$language && ($_=$ENV{'LC_ALL'} or $_=$ENV{'LANG'})) {
+	m/^([^\.]+)\.?(.*)/;
+	$language=$1;
+	$encoding=$2; # might be undef...
+# gsprintf::load_language* thinks "fr" is completely different to "fr_FR"...
+	$language =~ s/_.*$//;
+    }
+
+    # If $language has been set, load the appropriate resource bundle
+    # (Otherwise, the default resource bundle will be loaded automatically)
+    if ($language) {
+	gsprintf::load_language_specific_resource_bundle($language);
+	if ($encoding) {
+	    $encoding =~ tr/-/_/;
+	    $encoding = lc($encoding);
+	    $encoding =~ s/utf_8/utf8/; # special
+	    $gsprintf::specialoutputencoding=$encoding;
+	}
+    }
+    
+    # If there is not exactly one argument left (download name), then the arguments were wrong
+    # Or if the user specified -h, then we output the usage also
+
+    if((@ARGV && $ARGV[0] =~ /^\-+h/) )
+    {
+	PrintUsage::print_txt_usage($options, "{downloadinfo.params}");
+	die "\n";
+    }
+    
+    # If there is not exactly 1 argument left (download name), then the arguments were wrong (apart from if we had listall or describeall set)
+    if ($listall == 0 && $describeall ==0 && $unparsed_args == 0) {
+	gsprintf(STDERR, "{downloadinfo.no_download_name}\n\n");
+	PrintUsage::print_txt_usage($options, "{downloadinfo.params}", 1);
+	die "\n";
+    }
+
+    # we had some arguments that we weren't expecting
+    if ($unparsed_args > 1) {
+	pop(@ARGV); # assume that the last arg is the download name
+	gsprintf(STDERR, "{common.invalid_options}\n\n", join (',', @ARGV));
+	PrintUsage::print_txt_usage($options, "{downloadinfo.params}", 1);
+	die "\n";
+    }
+    my $download_name = shift (@ARGV);
+    if (defined $download_name) {
+	$download_name =~ s/\.pm$//; # allow xxx.pm as the argument
+    }
+
+    if ($collection ne "") {
+	$ENV{'GSDLCOLLECTDIR'} = &util::filename_cat ($ENV{'GSDLHOME'}, "collect", $collection);
+    } else {
+	$ENV{'GSDLCOLLECTDIR'} = $ENV{'GSDLHOME'};
+    }
+
+    if ($listall || $describeall) {
+	my $downloaders_dir = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "perllib", "downloaders");
+	my @downloader_list = ();
+	if (opendir (INDIR, $downloaders_dir)) {
+	    @downloader_list = grep (/Download\.pm$/, readdir (INDIR));
+	    closedir (INDIR);
+	}
+
+	print STDERR "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+	print STDERR "<DownloadList length=\"" . scalar(@downloader_list) . "\">\n";
+	foreach my $downloader (@downloader_list) {
+	    $downloader =~ s/\.pm$//;
+	    my $downloaderobj = &download::load_download ($downloader);
+	    if ($describeall) {
+		$downloaderobj->print_xml_usage(0);
+	    }
+	    else {
+		$downloaderobj->print_xml_usage(0, 1);
+	    }
+	}
+	print STDERR "</DownloadList>\n";
+    }
+    else {
+	&print_single_download($download_name, $xml, 1);
+    }
+}
+
+
+sub print_single_download {
+    my ($download, $xml, $header) = @_;
+    my @options  = ("-gsdlinfo");
+    my $downloadobj = &download::load_download ($download, \@options );
+    if ($xml) {
+	$downloadobj->print_xml_usage($header);
+    }
+    else {
+	gsprintf(STDERR, "{downloadinfo.option_types}:\n\n");
+	gsprintf(STDERR, "{downloadinfo.specific_options}\n\n");
+	gsprintf(STDERR, "{downloadinfo.general_options}\n\n");
+	gsprintf(STDERR, "$download {common.info}:\n\n");
+	
+	$downloadobj->print_txt_usage();
+    }
+    
+}
+
+&main ();
Index: /gsdl/stable/bin/script/expand_macros.pl
===================================================================
--- /gsdl/stable/bin/script/expand_macros.pl	(revision 20131)
+++ /gsdl/stable/bin/script/expand_macros.pl	(revision 20131)
@@ -0,0 +1,1300 @@
+#! /usr/bin/perl
+
+##################################################################################
+#                                                                                #
+# expand_macros.pl -- recursively expand greenstone macros / 1080805 - 1230106   #
+#                                                                                #
+# Copyright (C) 2005,2006 Jens Wille <j_wille at gmx.net>                        #
+#                                                                                #
+# This program is free software; you can redistribute it and/or                  #
+# modify it under the terms of the GNU General Public License                    #
+# as published by the Free Software Foundation; either version 2                 #
+# of the License, or (at your option) any later version.                         #
+#                                                                                #
+# This program is distributed in the hope that it will be useful,                #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of                 #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                  #
+# GNU General Public License for more details.                                   #
+#                                                                                #
+# You should have received a copy of the GNU General Public License              #
+# along with this program; if not, write to the Free Software                    #
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.    #
+#                                                                                #
+##################################################################################
+
+#
+# expand_macros.pl reads in specified greenstone macro files and prints the
+# definitions of requested macros and recursively the definitions of macros
+# used within these definitions.
+#
+#
+# FEATURES:
+#
+# - generic:
+#
+#   - additional/collection-specific macro files can be included
+#
+#   - macros set within the server can be included (though this might not be
+#     of much help without reading the respective source file)
+#
+# - "interactive browse mode" where you can select which macro (and from which
+#   package) to display next.
+#
+#   - readline support and persistent history
+#
+#   - interactive commands
+#
+#   - read files from within interactive browse mode
+#
+# - batch mode only:
+#
+#   - search for macros that use certain macros ("reverse" search)
+#
+#   - search for strings (regular expressions) in macro definitions
+#
+#
+# TODO:
+#
+# - add "reverse search" and "string search" for browse mode
+#
+# - handle macro options better (v, c, l, ...?)
+#
+# - implement some kind of "persistent" macro db (so that it doesn't need to be
+#   built each and every time)
+#
+#
+# KNOWN ISSUES:
+#
+# - for a sufficiently large file (> 12288 bytes == 12 k) (paged-)read will quit
+#   the program if not scrolled until the end of the file => SIGPIPE: broken pipe!
+#   SOLVED: the PIPE signal will simply be IGNOREd
+#
+
+use strict;
+use warnings;
+
+use Getopt::Long          qw(GetOptions);
+
+use File::Basename        qw(basename dirname);
+use File::Spec::Functions qw(catdir catfile curdir);
+
+use IO::Handle            qw(autoflush);
+STDOUT->autoflush(1);
+
+use Term::ReadLine;
+
+
+### progname and version
+
+my $NAME    = basename $0;
+my $VERSION = '0.22';
+
+
+### global patterns
+
+# my understanding of greenstone macro names:
+#   - enclosed in underscores ('_')
+#   - starts with a letter ([:alpha:])
+#   - followed by alphanumeric characters ([:alnum:])
+#     (consequently, it doesn't start with a number and
+#     particularly isn't a macro parameter, i.e. something like _1_)
+#   - also we might need to take care of escaped underscores ('\_')
+#
+#   => does this fit??? (see '<gsdl-source>/src/lib/display.cpp' for details,
+#      in particular the 'displayclass::loadparammacros' method)
+my $MACRO_PATTERN       = '[[:alpha:]][[:alnum:]]*';
+
+# package names: letters
+my $PACKAGE_NAME        = '[[:alpha:]]+';
+
+# package specification: package name followed by a colon (':')
+my $PACKAGE_PATTERN     = $PACKAGE_NAME . ':';
+
+# beginning/end of macro specification: underscore ('_'), not escaped,
+# i.e. not preceded by a backslash ('\')
+# (need to double-escape backslash here!)
+my $MACRO_AFFIX         = '(?<!\\\)_';
+
+# beginning of macro definition: opening curly bracket ('{')
+my $DEFINITION_START    = '\{';
+
+# end of macro definition: closing curly bracket ('}'), not escaped,
+# i.e. not preceded by a backslash ('\')
+# (need to double-escape backslash here!)
+my $DEFINITION_END      = '(?<!\\\)\}';
+
+# package declaration: 'package' (plus package name)
+my $PACKAGE_DECLARATION = 'package';
+
+
+### command line arguments
+
+# variable initialisation and default values
+my %ARG = (
+  'verbose'     => 0,
+  'version'     => 0,
+  'depth'       => 0,
+  'short'       => 0,
+  'reverse'     => 0,
+  'interactive' => 0,
+  'paged'       => 0,
+  'pager'       => $ENV{'PAGER'} || 'less',
+  'histfile'    => catfile($ENV{'HOME'} || curdir, '.expand_macros.history'),
+  'histsize'    => 100,
+  'macro_dirs'  => [catdir($ENV{'GSDLHOME'}, 'macros')],
+  'source_dir'  => $ENV{'GSDLSOURCE'} || '',
+  'args'        => []
+);
+
+# global vars
+my $TERM         = '';
+my $CURRENT_FILE = '';
+
+# usage information and help text
+my $USAGE = <<HERE_USAGE;
+usage:
+    $NAME [generic-options] [-s] [-d <depth>] [-r] {_[<package>:]<macro>_|<query>} ...
+    $NAME [generic-options] {-b|-i} [-p]
+    $NAME [-h|-?|--help]
+
+    generic options are: [-v] [-e <directory>,...] [-n <version>]
+HERE_USAGE
+
+my $HELP = <<HERE_HELP;
+$NAME: recursively expand greenstone macros (v$VERSION)
+
+$USAGE
+
+generic options:
+
+    -h, -?, --help                   display this help and exit
+    -v,     --verbose                output some extra information/warnings
+
+    {-e|--extra} <directory>,...     paths to extra macro directories, comma-separated list
+                                     [default directory: '$ARG{'macro_dirs'}[0]']
+
+            --source <directory>     path to greenstone source directory, so that macros which are
+                                     set within the server will be included
+                                     [default: '$ARG{'source_dir'}']
+                                     NOTE: you can set an environment variable GSDLSOURCE instead
+
+    {-n|--show-version} <version>    print only macro definitions for specified version (0=graphic/1=text)
+                                     [default: '$ARG{'version'}', set to '-1' for 'all']
+
+    -s,     --short                  short output, i.e. only macro names, no content
+
+
+batch mode:
+
+    {-d|--depth} <depth>             how deep to recurse through macros
+                                     [default: '$ARG{'depth'}', set to '-1' for 'unlimited']
+
+    -r,     --reverse                reverse search, recursively outputs the macros which use the specified macro
+
+    all non-option arguments will be treated as
+      - macro names (denoted by surrounding underscores '_')
+        or
+      - regular expressions to search for in macro definitions (otherwise)
+
+    (you can restrict your macro name query to a certain package by prepending the macro name with '<package-name>:')
+
+    EXAMPLES:
+
+      get definition of the 'pagescriptextra' macro
+      > $NAME _pagescriptextra_
+
+      get definition of the 'pagescriptextra' macro, package 'query' only
+      > $NAME _query:pagescriptextra_
+
+      get definition of the 'pagescriptextra' macro, package 'query' only -- and recursively get definitions of
+      macros used within that definition (up to level 2)
+      > $NAME -d 2 _query:pagescriptextra_
+
+      get all the macros that use the 'pagescriptextra' macro (names only)
+      > $NAME -r -s _pagescriptextra_
+
+
+interactive browse mode:
+
+    -b, -i, --browse                 interactive browse mode, allows you to select what to display next
+
+    -p,     --paged                  data output will be passed to a pager
+                                     [default: '$ARG{'pager'}']
+            --pager <pager>          pass paged output to specified pager instead of above named default
+
+            --histfile <file>        path to history file to keep history between sessions
+                                     [default: '$ARG{'histfile'}']
+            --histsize <num>         maximum number of lines to keep in histfile
+                                     [default: '$ARG{'histsize'}']
+                                     NOTE: in case you don\'t want the history to be stored you may set
+                                           <histfile> to '' or <histsize> to '0'
+                                           (however, this does not remove any existing history files)
+
+
+NOTE: for this script to run your greenstone environment needs to be set up (GSDLHOME set)
+HERE_HELP
+
+my $HELP_INTERACTIVE = <<HERE_HELP;
+$NAME: expand greenstone macros in ***interactive browse mode*** (v$VERSION)
+
+
+usage instructions:
+
+    - commands are equal to command line options, except that they start with a dot '.'
+      (NOTE: not all command line options are available as commands, see list below)
+
+    - commands that take an optional argument ([...]) will print their current value if
+      that argument is omitted (you can also use '.c' or '.config' to get a full overview)
+
+    - you can run several commands at once by separating them with semicolons
+
+    - you can quit the program at any time by hitting <ctrl>+d (<ctrl>+z on windows), or
+      by typing '.q', or '.quit'
+
+
+commands:
+
+    .h, .?, .help                    display this help
+
+    .q,     .quit                    exit program
+
+    .                                redisplay current stage
+
+    ..                               return to previous stage (same as leaving empty)
+
+    ..., .t, .top                    return to top to enter new macro name
+
+    {.n|.show-version} [<version>]   print only macro definitions for specified version (0=graphic/1=text)
+                                     [default: '0', set to '-1' for 'all']
+
+    .s,     .short                   short output, i.e. only macro names, no content
+
+    .p,     .paged                   data output will be passed to a pager
+                                     [default: '$ARG{'pager'}']
+            .pager [<pager>]         pass paged output to specified pager instead of above named default
+
+    .r,     .read [<file>]           display the contents of the specified file (by default the last file we came across)
+    .pr,    .paged-read [<file>]     same, but paged (without turning on paged mode permanently)
+
+    .c,     .config                  display current configuration
+HERE_HELP
+
+# allow for bundling of options
+Getopt::Long::Configure ("bundling");
+
+# parse arguments
+GetOptions( 'help|h|?'         => sub { print "$HELP\n"; exit 0 },
+            'verbose|v'        => \$ARG{'verbose'},
+            'only-version|n=i' => \$ARG{'version'},
+            'extra|e=s'        => \@{$ARG{'macro_dirs'}},
+            'source=s'         => \$ARG{'source_dir'},
+            'depth|d=i'        => \$ARG{'depth'},
+            'short|s'          => \$ARG{'short'},
+            'reverse|r'        => \$ARG{'reverse'},
+            'browse|b|i'       => \$ARG{'interactive'},
+            'paged|p'          => \$ARG{'paged'},
+            'pager=s'          => \$ARG{'pager'},
+            'histfile=s'       => \$ARG{'histfile'},
+            'histsize=i'       => \$ARG{'histsize'},
+            '<>'               => sub { push(@{$ARG{'args'}} => @_) } )
+  or die "$USAGE\n";
+
+
+### some sanity checks (dunno which one to check first ;-)
+
+# need one of our "actions": batch, query or interactive
+# ("batch" requiring at least one macro name or regexp specified)
+unless (@{$ARG{'args'}} || $ARG{'interactive'}) {
+  warn "$USAGE";
+
+  warn <<HERE_WARN unless $ENV{'GSDLHOME'};
+
+GSDLHOME not set!
+
+for this script to run your greenstone environment needs to be set up. please
+change into the directory where greenstone has been installed and run/source
+the appropriate setup script.
+HERE_WARN
+
+  die "\n";
+}
+
+# need GSDLHOME for default macro directory
+# (does also allow to have the script in gsdl bin path)
+die "GSDLHOME not set! please change into the directory where greenstone has been installed and run/source the appropriate setup script.\n"
+  unless $ENV{'GSDLHOME'};
+
+## need one of our "actions": batch, query or interactive
+# ("batch" requiring at least one macro name or regexp specified)
+#die "$USAGE\n"
+#  unless @{$ARG{'args'}} || $ARG{'interactive'};
+
+
+### action!
+
+# build hash of macro information
+my %macro_db = build_db();
+die "macro db empty!\n"
+  unless %macro_db;
+
+unless ($ARG{'interactive'}) {
+  # batch mode
+
+  my $n = 0;
+  foreach my $arg (@{$ARG{'args'}}) {
+    if ($arg =~ s/^$MACRO_AFFIX((?:$PACKAGE_PATTERN)?$MACRO_PATTERN)$MACRO_AFFIX$/$1/) {
+      # macro
+
+      print "*** macro: $arg", ($ARG{'reverse'} ? ' (reverse) ' : ' '), "***\n\n";
+
+      unless ($ARG{'reverse'}) {
+        # "normal" search
+
+        get_macro($arg);
+      }
+      else {
+        # "reverse" search
+
+        # get the macros that use the specified macro
+        my @refs = get_r_macros($arg);
+        print "no macro referencing '$arg'\n\n"
+          unless @refs;
+
+        # now recurse those macros
+        get_macro($_)
+          foreach @refs;
+      }
+    }
+    else {
+      # query
+
+      print "*** query: $arg", ($ARG{'reverse'} ? ' (reverse) ' : ' '), "***\n\n";
+
+      # get the macros that match the specified query
+      my @macros = get_r_macros($arg, 1);
+      print "no matches for '$arg'\n", ($ARG{'short'} ? '' : "\n")
+        unless @macros;
+
+      # now print those macros
+      get_macro($_)
+        foreach @macros;
+    }
+
+    # print separator _between_ requested macros (i.e. everytime but the last time)
+    # (need to add extra newline for short display)
+    print(($ARG{'short'} ? "\n" : ''), '-' x 80, "\n\n")
+      unless ++$n >= @{$ARG{'args'}};
+  }
+}
+else {
+  # interactive browse mode
+
+  # ignore 'broken pipe' error
+  $SIG{'PIPE'} = 'IGNORE';
+
+  # get the pager executable (no need to test if not in "paged" mode)
+  get_pager()
+    if $ARG{'paged'};
+
+  # create new Term::ReadLine object
+  $TERM = Term::ReadLine->new($NAME);
+
+  # don't want the prompt underlined
+  $TERM->ornaments(0);
+  # don't want autohistory (can't set autohistory explicitly, so use this "workaround")
+  $TERM->MinLine(undef);
+
+  # restore history
+  readhist();
+
+  # print help hint
+  print <<HERE_HINT;
+entered '$NAME' in ***interactive browse mode*** (v$VERSION)
+[you can get help at any time by typing '.h', '.?', or '.help']
+
+HERE_HINT
+
+  # repeat until explicit exit
+  while (1) {
+    my $macro = prompt("enter macro name (without package specification) [leave empty to quit]\n> ");
+
+    # remove surrounding '_'
+    $macro =~ s/^_//;
+    $macro =~ s/_$//;
+
+    exit 0 unless length $macro;                    # normal exit
+    next   if     $macro eq '0' || $macro eq '-1';  # a command was executed
+
+    # now get all packages for given macro, and begin recursion...
+    recurse_packages($macro);
+  }
+
+  # can't expect anything down here to be executed
+}
+
+END {
+  if ($ARG{'interactive'}) {
+    # save history
+    savehist();
+  }
+}
+
+
+### that's it ;-)
+
+exit 0;
+
+
+### subroutines
+
+# <sub build_db>
+# build hash of macro information ("macro db")
+#
+# hash structure:
+#   macro
+#   -> package
+#      -> {'0=graphic'|'1=text'}
+#         -> 'file'
+#         -> 'line'
+#         -> 'content'
+#
+# usage:
+#   %macro_db = build_db()
+#
+#  => macro_db: returned hash ("macro db")
+#
+sub build_db {
+  my %macro_db = ();
+  my @dm_list  = ();
+  my ($n, $m) = (0, 0);
+
+  # get all macro files (*.dm) from specified directories
+  foreach my $dir (@{$ARG{'macro_dirs'}}) {
+    opendir(DIR, "$dir")
+      or die "can't read macro directory '$dir': $!\n";
+
+    push(@dm_list => map { $_ = catfile($dir, $_) } grep { /\.dm$/ } readdir(DIR));
+
+    closedir DIR;
+  }
+
+  # now parse each macro file and build hash
+  foreach my $dm (sort @dm_list) {
+    open(DM, "< $dm")
+      or die "can't open macro file '$dm': $!\n";
+
+    my ($name, $content, $version, $curpkg, $contd)
+     = ('',    '',       '0',      '',      0);
+
+    while (my $line = <DM>) {
+      chomp($line);
+      next unless length $line;      # skip empty lines
+      next if     $line =~ /^\s*$/;  # skip "empty" lines
+      next if     $line =~ /^\s*#/;  # skip comments (hope this doesn't affect
+                                     # cases we actually wanted to keep)
+
+      if    ($line =~ /^$PACKAGE_DECLARATION\s*($PACKAGE_NAME)/) {
+        # remember the current package we are in
+        $curpkg = $1;
+      }
+      elsif ($line =~ /$MACRO_AFFIX($MACRO_PATTERN)$MACRO_AFFIX\s*(\[v=1\])?\s*$DEFINITION_START\s*(.*)/) {
+        # start of macro definition
+        $n++;
+
+        $name    = $1;
+        $version = (defined $2 && $2 eq '[v=1]') ? '1' : '0';
+        $content = $3 || '';
+
+        # don't include unnecessary version, unless we're interactive (where version may change during session)
+        next if $ARG{'version'} ne '-1' && $version ne $ARG{'version'} && ! $ARG{'interactive'};
+
+        if (exists $macro_db{$name}->{$curpkg}->{$version}) {
+          # everytime a macro definition already exists, it's simply
+          # overwritten - but we can give a warning
+          # (this might also serve debugging purposes)
+          $m++;
+
+          warn <<HERE_WARN if $ARG{'verbose'};
+duplicate definition of macro '$curpkg:$name' [v=$version] at '$dm', line $.
+(previously defined at $macro_db{$name}->{$curpkg}->{$version}->{'file'}, line $macro_db{$name}->{$curpkg}->{$version}->{'line'})
+HERE_WARN
+        }
+
+        # store the information we got so far
+        $macro_db{$name}->{$curpkg}->{$version}->{'file'}    = $dm;
+        $macro_db{$name}->{$curpkg}->{$version}->{'line'}    = $.;
+        $macro_db{$name}->{$curpkg}->{$version}->{'content'} = [$content] if length $content;
+
+        # is the macro definition already finished?
+        $contd = ($content =~ s/\s*$DEFINITION_END.*//) ? 0 : 1;
+      }
+      elsif ($contd) {
+        # continuation of macro definition
+
+        # store additional content
+        push(@{$macro_db{$name}->{$curpkg}->{$version}->{'content'}} => $line);
+
+        # is the macro definition already finished?
+        $contd = ($line =~ s/\s*$DEFINITION_END.*//) ? 0 : 1;
+      }
+      else {
+        # something else...
+
+        ($name, $content) = ('', '');
+      }
+    }
+
+    close DM;
+  }
+
+  # get server macros (overwriting already read macros)
+  if (length $ARG{'source_dir'}) {
+    if (-r $ARG{'source_dir'}) {
+      my $recpt_dir = catdir($ARG{'source_dir'}, 'src', 'src', 'recpt');
+      my @cpp_list  = ();
+
+      opendir(DIR, "$recpt_dir")
+        or die "can't read receptionist's source directory '$recpt_dir': $!\n";
+
+      push(@cpp_list => map { $_ = catfile($recpt_dir, $_) } grep { /\.cpp$/ } readdir(DIR));
+
+      close DIR;
+
+      foreach my $cpp (@cpp_list) {
+        open(CPP, "< $cpp")
+          or die "can't open source file '$cpp': $!\n";
+
+        my $args  = '';
+        my $contd = 0;
+        while (my $line = <CPP>) {
+          next unless $line =~ /disp\.setmacro\s*\((.*)/ || $contd;
+
+          unless (defined $1) {
+            $contd = 1;
+            next;
+          }
+
+          my $string = $1;
+
+          if    ($string =~ s/\);\s*$//) {
+            $args .= $string;
+            my ($name, $package, $value) = split(/\s*,\s*/ => $args, 3);
+
+            $name    =~ s/^\s*["']?//;
+            $name    =~ s/["']?\s*$//;
+            $package =~ s/^\s*["']?//;
+            $package =~ s/["']?\s*$//;
+
+            $package = 'Global'
+              if $package eq 'displayclass::defaultpackage';
+
+            $macro_db{$name}->{$package}->{'0'}->{'file'}    = 'SERVER: ' . $cpp;
+            $macro_db{$name}->{$package}->{'0'}->{'line'}    = $.;
+            $macro_db{$name}->{$package}->{'0'}->{'content'} = [$value];
+
+            $args = '';
+            ++$n;
+            $contd = 0;
+          }
+          elsif ($contd) {
+            $args .= ' ' . $string;
+          }
+          else {
+            $contd = 1;
+          }
+        }
+
+        close CPP;
+      }
+    }
+    else {
+      warn "can't find source directory '$ARG{'source_dir'}'! server macros will not be included\n";
+    }
+  }
+
+  # print some statistics
+  print "$n total macro definitions, $m duplicates\n"
+    if $ARG{'verbose'};
+
+  # we stored all information there is so we can return it
+  return %macro_db;
+}
+# </sub build_db>
+
+# <sub get_macro>
+# recursively print macro information
+#
+# usage:
+#   get_macro($macro[, $level])
+#
+#   macro:    macro name (optionally including package specification)
+#   level:    recursion level (optional)
+#
+#   => VOID CONTEXT
+#
+sub get_macro {
+  my ($macro, $level) = @_;
+  $level ||= 0;
+
+  # indent output according to recursion level
+  my $indent  = '    ' x $level;
+
+  # get all the packages which our macro is defined in
+  ($macro, my @packages) = get_packages($macro, $indent);
+  return unless @packages;
+
+  # macro definitions may occur in several packages so we display them all
+  # (unless a certain package was explicitly specified)
+  foreach my $pkg (@packages) {
+    foreach my $version (sort keys %{$macro_db{$macro}->{$pkg}}) {
+      print "$indent* $pkg:$macro [v=$version] ($macro_db{$macro}->{$pkg}->{$version}->{'file'}, line $macro_db{$macro}->{$pkg}->{$version}->{'line'})\n";
+
+      my $content = '';
+      # some macros are defined, but don't have any content
+      if (defined $macro_db{$macro}->{$pkg}->{$version}->{'content'}) {
+        # for batch display we condense the output a little bit...
+        map { s/^\s*//; s/\s*$// } @{$macro_db{$macro}->{$pkg}->{$version}->{'content'}};
+        # ...and put it on a single line
+        $content = join(' ' => @{$macro_db{$macro}->{$pkg}->{$version}->{'content'}});
+      }
+      print "$indent  { $content }\n\n"
+        unless $ARG{'short'};
+        # short display only, i.e. no content
+        # of the macro's definition
+
+      # only go (deeper) into referenced macros if we
+      # haven't reached the specified recursion level
+      if ($ARG{'depth'} eq '-1' || $level < $ARG{'depth'}) {
+        # get (referencing|referenced) macros...
+        my @refs = $ARG{'reverse'}
+                 ? get_r_macros($macro)
+                 : get_macros($content);
+
+        # ...and recurse above them (with increased recursion level)
+        foreach my $ref (@refs) {
+          get_macro($ref, $level + 1);
+        }
+      }
+    }
+  }
+}
+# </sub get_macro>
+
+# <sub get_macros>
+# returns a list of macros extracted from a content string
+# or a boolean value if a macro name was specified
+#
+# usage:
+#   @macros  = get_macros($content)
+#   $boolean = get_macros($content, $macro)
+#
+#   content: content string
+#   macro:   macro name
+#
+#   => macros:  list of macros
+#   => boolean: boolean value (true = 1 / false = empty list)
+#
+sub get_macros {
+  my ($content, $macro) = @_;
+  my @macro_list = ();
+  my %seen       = ();
+
+  # get each macro reference in the string
+  # (for macro name considerations see above)
+  while ($content =~ /$MACRO_AFFIX((?:$PACKAGE_PATTERN)?$MACRO_PATTERN)$MACRO_AFFIX/g) {
+    my $m = $1;
+
+                           # we want to skip some macros that have no content anyway (defined
+                           # from within the server) - unless we're doing a "reverse" search
+    next if $seen{$m}++ || ($m =~ /^(cgiarg.*|histvalue\d+|if|httpimg|httpweb|gwcgi|(decoded)?compressedoptions)$/i
+                            && ! $ARG{'reverse'});
+
+    if (defined $macro) {
+      # is this the macro we wanted? then the current
+      # macro uses it => return true
+      return 1 if $m =~ /^(?:$PACKAGE_PATTERN)?$macro$/;
+    }
+    else {
+      # add macro to our list
+      push(@macro_list => $m);
+    }
+  }
+
+  # return the list of used macros
+  # (this evaluates to false (empty list) if there are no further
+  # macro calls or if this macro doesn't use the sought-after macro)
+  return sort @macro_list;
+}
+# </sub get_macros>
+
+# <sub get_r_macros>
+# returns a list of macro names which reference ("use") the
+# specified macro or match the query
+#
+# usage:
+#   @macros = get_r_macros($macro)
+#   @macros = get_r_macros($query, $is_query)
+#
+#   macro:    macro name
+#   query:    query string (regular expression)
+#   is_query: boolean value to indicate whether arg is a query or a macro
+#
+#   => macros: list of macros
+#
+sub get_r_macros {
+  my ($arg, $query) = @_;
+  $query ||= 0;
+  my %refs = ();
+
+  # need to test each single macro's...
+  foreach my $m (sort keys %macro_db) {
+    # ...each single package
+    foreach my $p (sort keys %{$macro_db{$m}}) {
+      foreach my $v (sort keys %{$macro_db{$m}->{$p}}) {
+        my $pm = "$p:$m";  # include package information in the macro name!
+
+        # does this macro have any content?
+        if (defined $macro_db{$m}->{$p}->{$v}->{'content'}) {
+          # stringify content!
+          my $content = join(' ' => @{$macro_db{$m}->{$p}->{$v}->{'content'}});
+
+          if ($query) {
+            # search regexp
+            $refs{$pm}++ if $content =~ /$arg/;
+          }
+          else {
+            # search macro
+            $refs{$pm}++ if get_macros($content, $arg);
+          }
+        }
+      }
+    }
+  }
+
+  # now we have all the macros which use our sought-after
+  return sort keys %refs;
+}
+# </sub get_r_macros>
+
+# <sub recurse_packages>
+# recurse all packages for a given macro
+#
+# usage:
+#   recurse_packages($macro)
+#
+#   macro:    macro name (any package specification will be dropped)
+#
+#   => VOID CONTEXT
+#
+sub recurse_packages {
+  my ($macro) = @_;
+
+  # repeat until explicit break/exit
+  while (1) {
+    # get all the packages which our macro is defined in
+    #($macro, my @packages) = get_packages($macro);
+    #return unless @packages;
+    my @packages = ();
+
+    my $n = 0;
+    my $package = '';
+    # ask for user's selection...
+    do {
+      # get all the packages which our macro is defined in
+      ($macro, @packages) = get_packages($macro);
+      return unless @packages;
+
+      # ask for user's selection...
+      print "select package for macro '$macro' [leave empty to return]\n";
+      foreach my $pkg (@packages) {
+        printf "    [%d]%s %s\n", ++$n, " " x (4 - length $n), $pkg;
+      }
+      $package = prompt();
+      $n = 0;
+    # ...until we return...
+    } until ($package eq '' || $package eq '-1'
+         # ...or a valid number is provided
+         || ($package =~ /^\d+$/ && $package > 0 && $package <= @packages));
+
+    return unless length $package;          # return to previous stage
+    return '-1'   if     $package eq '-1';  # return to top
+
+    # set selected package
+    $package = $packages[$package - 1];
+
+    foreach my $version (sort keys %{$macro_db{$macro}->{$package}}) {
+                  # all versions
+      next unless $ARG{'version'} eq '-1'
+                  # desired version
+               || $version eq $ARG{'version'}
+                  # fallback to 'graphic'
+               || ($version eq '0' && ! exists $macro_db{$macro}->{$package}->{'1'});
+
+                    # some macros are defined, but don't have any content
+      my $content = defined $macro_db{$macro}->{$package}->{$version}->{'content'}
+                    # now we want to retain the original structure
+                  ? join("\n" => @{$macro_db{$macro}->{$package}->{$version}->{'content'}})
+                  : '';
+
+      ($CURRENT_FILE = $macro_db{$macro}->{$package}->{$version}->{'file'}) =~ s/^SERVER: //;
+
+      my $content_string = "* $package:$macro [v=$version] ($macro_db{$macro}->{$package}->{$version}->{'file'}, line $macro_db{$macro}->{$package}->{$version}->{'line'})\n";
+      $content_string   .= "{ $content }\n"
+        unless $ARG{'short'};
+
+      print_output($content_string);
+
+      # now on to the macros referenced within this one
+      my $return = recurse_macros($content);
+
+      return $return if defined $return;
+    }
+  }
+}
+# </sub recurse_packages>
+
+# <sub get_packages>
+# returns list of packages for specified macro, also returns
+# modified macro name (without surrounding '_' and package specification)
+#
+# usage:
+#   ($macro, @packages) = get_packages($macro)
+#
+#   macro:    macro name
+#
+#   => macro:    modified macro name
+#   => packages: list of packages
+#
+sub get_packages {
+  my ($macro, $indent) = @_;
+  $indent ||= '';
+
+  # save original macro name (including package specification)
+  my $omacro = $macro;
+
+  my @packages = ();
+
+  if ($macro =~ /^($PACKAGE_PATTERN)?$MACRO_PATTERN$/) {
+    # valid macro name
+
+    # strip off package specification
+    my $package = ($macro =~ s/^($PACKAGE_NAME)://) ? $1 : '';
+
+    if (exists $macro_db{$macro}) {
+      # valid/existing macro
+
+      unless ($ARG{'interactive'}) {
+        if (length $package) {
+          # account for package specification
+
+          @packages = ($package)
+            if exists $macro_db{$macro}->{$package};
+        }
+        else {
+          # get all packages otherwise
+
+          @packages = sort keys %{$macro_db{$macro}};
+        }
+      }
+      else {
+        foreach my $pkg (sort keys %{$macro_db{$macro}}) {
+          push(@packages => $pkg)
+               # all versions
+            if $ARG{'version'} eq '-1'
+               # desired version
+            || exists $macro_db{$macro}->{$pkg}->{$ARG{'version'}}
+               # fallback to 'graphic'
+            || exists $macro_db{$macro}->{$pkg}->{'0'};
+        }
+      }
+    }
+  }
+  else {
+    # invalid macro name
+
+    warn "invalid macro name '$macro'!\n";
+    return;  # skip it
+  }
+
+  # no packages - no definition
+  unless (@packages) {
+    print "$indent- $omacro\n$indent  no definition for macro!\n\n";
+    return;  # skip it
+  }
+
+  # return modified macro name and packages found
+  return $macro, sort @packages;
+}
+# </sub get_packages>
+
+# <sub recurse_macros>
+# recurse all macros for a given content string
+#
+# usage:
+#   recurse_macros($content)
+#
+#   content:  content string
+#
+#   => VOID CONTEXT
+#
+sub recurse_macros {
+  my ($content) = @_;
+
+  # repeat until explicit break/exit
+  while (1) {
+    # get all the macros referenced within the current one
+    my @macros = get_macros($content);
+    return unless @macros;
+
+    my $n = 0;
+    my $macro = ''; 
+    # ask for user's selection...
+    do {
+      print "select macro [leave empty to return]\n";
+      foreach my $m (@macros) {
+        printf "    [%d]%s %s\n", ++$n, " " x (4 - length $n), $m;
+      }
+      $macro = prompt();
+      $n = 0;
+    # ...until we return...
+    } until ($macro eq '' || $macro eq '-1'
+         # ...or a valid number is provided
+         || ($macro =~ /^\d+$/ && $macro > 0 && $macro <= @macros));
+
+    return unless length $macro;          # return to previous stage
+    return '-1'   if     $macro eq '-1';  # return to top
+
+    # set selected macro
+    $macro = $macros[$macro - 1];
+
+    # now we want all the macro's packages again
+    my $return = recurse_packages($macro);
+
+    return $return if defined $return;
+  }
+}
+# </sub recurse_macros>
+
+# <sub prompt>
+# prompt for user input
+#
+# usage:
+#   $reply = prompt([$prompt])
+#
+#   prompt:  optional prompt (default: '> ')
+#
+#   => reply: user input
+#
+sub prompt {
+  my $prompt = shift || '> ';
+  my $term   = $TERM;
+
+  # read user input
+  my $reply = $term->readline($prompt);
+
+  if (defined $reply) {
+    # add input to history, unless it's just a number
+    $term->addhistory($reply)
+      if $reply =~ /[[:alpha:]]/;
+
+    if ($reply =~ s/^\s*["']*\s*\././) {
+      # execute command
+      my $return = parse_command($reply);
+
+      return $return if defined $return;
+    }
+    else {
+      return $reply;
+    }
+  }
+
+  # allow for exiting by hitting <ctrl>+d,
+  # or quitting by command (.q, .quit)
+  die "\n";
+}
+# </sub prompt>
+
+# <sub print_output>
+# print output, paged or not
+#
+# usage:
+#   print_output($output)
+#   print_output(@output)
+#
+#   output: text to print
+#
+#   => VOID CONTEXT
+#
+sub print_output {
+  my $output = join('' => @_);
+
+  if ($ARG{'paged'}) {
+    # pass output to pager
+    open(PAGER, "| $ARG{'pager'}")
+      or die "can't open pipe to '$ARG{'pager'}': $!";
+
+    print PAGER "$output";
+
+    close PAGER;
+  }
+  else {
+    # print to standard out...
+    print "\n$output\n";
+
+    # ...and wait for user reaction to continue
+    wait_for_user();
+  }
+}
+# </sub print_output>
+
+# <sub wait_for_user>
+# wait for user reaction to continue
+#
+# usage:
+#   wait_for_user()
+#
+#   => VOID CONTEXT
+#
+sub wait_for_user {
+  print "[press key to continue]";
+  print "\n" if <STDIN>;
+}
+# </sub wait_for_user>
+
+# <sub parse_command>
+# prompt for user input
+#
+# usage:
+#   parse_command($command_line)
+#
+#   command_line: command string
+#
+#   => VOID CONTEXT
+#
+sub parse_command {
+  my $command_line = shift;
+  my @commands = split(/\s*;\s*/ => $command_line);
+
+  my $return = 0;
+
+  foreach my $command (@commands) {
+    my $msg = "command executed: '$command'";
+
+    $command =~ s/^\.//;
+    $command =~ s/^(\w+)["']*/$1/;
+    $command =~ s/\s*$//;
+
+    if    ($command =~ /^(h|\?|help)$/) {
+      print "$HELP_INTERACTIVE\n";
+
+      # wait for user reaction to continue
+      wait_for_user();
+
+      next;
+    }
+    elsif ($command =~ /^(q|quit)$/) {
+      return undef;
+    }
+    elsif ($command =~ /^(\.)$/) {
+      $return = '';
+
+      next;
+    }
+    elsif ($command =~ /^(\..|t|top)$/) {
+      $return = '-1';
+
+      next;
+    }
+    elsif ($command =~ /^(n|show-version)(?:\s+["']*(0|1|-1)["']*)?$/) {
+      $ARG{'version'} = $2
+        if defined $2;
+
+      $msg = "'version' " . (defined $2 ? '' : 'is currently ') . "set to: '$ARG{'version'}'";
+    }
+    elsif ($command =~ /^(s|short)$/) {
+      $ARG{'short'} = ! $ARG{'short'};
+
+      $msg = "'short' output " . ($ARG{'short'} ? 'en' : 'dis') . "abled";
+    }
+    elsif ($command =~ /^(p|paged)$/) {
+      $ARG{'pager'} = get_pager();
+      $ARG{'paged'} = ! $ARG{'paged'}
+        if -x $ARG{'pager'};
+
+      $msg = "'paged' output " . ($ARG{'paged'} ? 'en' : 'dis') . "abled";
+    }
+    elsif ($command =~ /^(pager)(?:\s+["']*(\w+)["']*)?$/) {
+      $ARG{'pager'} = get_pager($2)
+        if defined $2;
+
+      $msg = "'pager' " . (defined $2 ? '' : 'is currently ') . "set to: '$ARG{'pager'}'";
+    }
+    elsif ($command =~ /^(p|paged-)?(r|read)(?:\s+(["']?.+["']?))?$/) {
+      my $paged = $1 || '';
+      my $file  = $3 || $CURRENT_FILE;
+      $CURRENT_FILE = $file;
+
+      if (-r $file) {
+        open(FILE, "< $file")
+          or die "can't open file '$file': $!\n";
+
+        my @lines = <FILE>;
+
+        close FILE;
+
+        my $previous_paged = $ARG{'paged'};
+        $ARG{'paged'}      = 1 if $paged;
+
+        #print_output("$file:\n\n", @lines);
+        print_output(@lines);
+
+        $ARG{'paged'}      = $previous_paged;
+
+        next;
+      }
+
+      $msg = "can't find file '$file'";
+    }
+    elsif ($command =~ /^(c|config)$/) {
+      my $short = $ARG{'short'} ? 'enabled' : 'disabled';
+      my $paged = $ARG{'paged'} ? 'enabled' : 'disabled';
+
+      $msg = <<HERE_MSG;
+current configuration for '$NAME - interactive browse mode':
+
+'version':         $ARG{'version'}
+'short' output:    $short
+'paged' output:    $paged
+'pager':           $ARG{'pager'}
+current file:      $CURRENT_FILE
+HERE_MSG
+    }
+    elsif (length $command) {
+      $msg = "invalid command: .$command";
+    }
+    else {
+      # probably the '.' command
+      $return = 0;
+
+      next;
+    }
+
+    print "% $msg\n";
+  }
+
+  return $return;
+}
+# </sub parse_command>
+
+# <sub readhist>
+# read history from histfile
+#
+# usage:
+#   readhist();
+#
+#   => VOID CONTEXT
+#
+sub readhist {
+  my $term = $TERM;
+
+  if (-r $ARG{'histfile'}) {
+    open(HIST, "< $ARG{'histfile'}")
+      or die "can't open histfile '$ARG{'histfile'}': $!\n";
+
+    while (<HIST>) {
+      chomp;
+      $term->AddHistory($_);
+    }
+
+    close HIST;
+
+    warn "history restored from '$ARG{'histfile'}'\n"
+      if $ARG{'verbose'};
+  }
+  else {
+    warn "history could not be restored (maybe no/wrong history file specified)\n"
+      if $ARG{'verbose'};
+  }
+}
+# </sub readhist>
+
+# <sub savehist>
+# save history to histfile
+#
+# usage:
+#   savehist();
+#
+#   => VOID CONTEXT
+#
+sub savehist {
+  return unless length $ARG{'histfile'} && $ARG{'histsize'};
+
+  my $term = $TERM;
+
+  return unless length $term;
+
+  if (-w $ARG{'histfile'} || (! -e $ARG{'histfile'} && -w dirname $ARG{'histfile'})) {
+    my @history = $term->GetHistory;
+
+    # drop (consecutive) duplicate entries
+    my @unified  = ();
+    my $previous = '';
+    foreach my $element (@history) {
+      push(@unified => $element)
+        unless $element eq $previous;
+      $previous = $element;
+    }
+    @history = @unified;
+
+    # cut history to specified maximum number of entries
+    splice(@history, 0, @history - $ARG{'histsize'})
+      if @history > $ARG{'histsize'};
+
+    open(HIST, "> $ARG{'histfile'}")
+      or die "can't open history file '$ARG{'histfile'}' for writing: $!\n";
+
+    {
+    local $, = "\n";
+
+    print HIST @history, "";
+    }
+
+    close HIST;
+
+    warn "history written to '$ARG{'histfile'}'\n"
+      if $ARG{'verbose'};
+  }
+  else {
+    warn "history could not be written (maybe no history file specified, or history file not writable)\n"
+      if $ARG{'verbose'};
+  }
+}
+# </sub savehist>
+
+# <sub get_pager>
+# get pager executable
+#
+# usage:
+#   $pager = get_pager([$candidate]);
+#
+#   canidate: candidate for pager executable (defaulting to $ARG{'pager'})
+#
+#   => pager: pager executable
+#
+sub get_pager {
+  my $candidate = shift || $ARG{'pager'};
+
+  return $candidate if -x $candidate;
+
+  # get first pager executable in PATH
+  foreach my $path (split(':' => $ENV{'PATH'})) {
+    return catfile($path, $candidate) if -x catfile($path, $candidate);
+  }
+
+  # still no executable!
+  warn "can't find pager '$candidate'! disabling 'paged' output\n";
+  $ARG{'paged'} = 0;
+
+  return '-1';
+}
+# </sub get_pager>
Index: /gsdl/stable/bin/script/explode_metadata_database.pl
===================================================================
--- /gsdl/stable/bin/script/explode_metadata_database.pl	(revision 20131)
+++ /gsdl/stable/bin/script/explode_metadata_database.pl	(revision 20131)
@@ -0,0 +1,616 @@
+#!/usr/bin/perl -w
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugins");
+}
+
+use strict;
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+no strict 'refs'; # allow filehandles to be variables and vice versa
+
+use encodings;
+use printusage;
+use parse2;
+use colcfg;
+
+use FileHandle;
+
+use File::Spec;
+use File::Basename;
+
+my $unicode_list =
+    [ { 'name' => "auto",
+	'desc' => "{ReadTextFile.input_encoding.auto}" },
+      { 'name' => "ascii",
+	'desc' => "{BasePlugin.encoding.ascii}" },
+      { 'name' => "utf8",
+	'desc' => "{BasePlugin.encoding.utf8}" },
+      { 'name' => "unicode",
+	'desc' => "{BasePlugin.encoding.unicode}" } ];
+
+my $e = $encodings::encodings;
+foreach my $enc (sort {$e->{$a}->{'name'} cmp $e->{$b}->{'name'}} keys (%$e)) 
+{
+    my $hashEncode =
+    {'name' => $enc,
+     'desc' => $e->{$enc}->{'name'}};
+    
+    push(@{$unicode_list},$hashEncode);
+}
+
+my $arguments = 
+    [ 
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "plugin",
+	'desc' => "{explode.plugin}",
+	'type' => "string",
+	'reqd' => "yes",
+	'hiddengli' => "yes"},
+      { 'name' => "input_encoding",
+	'desc' => "{explode.encoding}",
+	'type' => "enum",
+	'deft' => "auto",
+	'list' => $unicode_list,
+	'reqd' => "no" },
+      { 'name' => "metadata_set",
+	'desc' => "{explode.metadata_set}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "document_field",
+	'desc' => "{explode.document_field}",
+	'type' => "string",
+	'reqd' => "no"},
+       { 'name' => "document_prefix",
+	'desc' => "{explode.document_prefix}",
+	'type' => "string",
+	'reqd' => "no"},
+      { 'name' => "document_suffix",
+	'desc' => "{explode.document_suffix}",
+	'type' => "string",
+	'reqd' => "no"},
+      { 'name' => "records_per_folder",
+	'desc' => "{explode.records_per_folder}",
+	'type' => "int",
+	'range' => "0,",
+	'deft' => "100",
+	'reqd' => "no" },
+      { 'name' => "collection",
+	'desc' => "{explode.collection}",
+	'type' => "string",
+	'reqd' => "no",
+	'hiddengli' => "yes"},
+      { 'name' => "use_collection_plugin_options",
+	'desc' => "{explode.use_collection_plugin_options}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes"},
+      { 'name' => "plugin_options",
+	'desc' => "{explode.plugin_options}",
+	'type' => "string",
+	'reqd' => "no",
+	'hiddengli' => "yes"},
+      { 'name' => "verbosity",
+	'desc' => "{import.verbosity}",
+	'type' => "int",
+	'range' => "0,",
+	'deft' => "1",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "xml",
+	'desc' => "",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" }
+      ];
+	
+my $options = { 'name' => "explode_metadata_database.pl",
+		'desc' => "{explode.desc}",
+		'args' => $arguments };
+
+
+
+sub main
+{
+    my ($language, $input_encoding, $metadata_set, $plugin, 
+	$document_field, $document_prefix, $document_suffix, $records_per_folder, $plugin_options, $collection, $use_collection_plugin_options, $verbosity);
+
+    my $xml = 0;
+
+    my $hashParsingResult = {};
+    # parse the options
+    my $intArgLeftinAfterParsing = parse2::parse(\@ARGV,$arguments,$hashParsingResult,"allow_extra_options");
+
+    # If parse returns -1 then something has gone wrong
+    if ($intArgLeftinAfterParsing == -1)
+    {
+	&PrintUsage::print_txt_usage($options, "{explode.params}");
+	die "\n";
+    }
+
+    foreach my $strVariable (keys %$hashParsingResult)
+    {
+	eval "\$$strVariable = \$hashParsingResult->{\"\$strVariable\"}";
+    }
+
+    # If $language has been specified, load the appropriate resource bundle
+    # (Otherwise, the default resource bundle will be loaded automatically)
+    if ($language && $language =~ /\S/) {
+	&gsprintf::load_language_specific_resource_bundle($language);
+    }
+
+    if ($xml) {
+        &PrintUsage::print_xml_usage($options);
+	print "\n";
+	return;
+    }
+
+    
+    # There should one arg left after parsing (the filename)
+    # Or the user may have specified -h, in which case we output the usage
+    if($intArgLeftinAfterParsing != 1 || (@ARGV && $ARGV[0] =~ /^\-+h/))
+    {
+	&PrintUsage::print_txt_usage($options, "{explode.params}");
+	die "\n";
+    }
+
+    # The metadata database filename is the first value that remains after the options have been parsed out
+    my $filename = $ARGV[0];
+    if (!defined $filename || $filename !~ /\w/) { 
+	&PrintUsage::print_txt_usage($options, "{explode.params}");
+	print STDERR "You need to specify a filename";
+	die "\n";
+    }
+    # check that file exists
+    if (!-e $filename) {
+	print STDERR "File $filename doesn't exist...\n";
+	die "\n";
+    }
+    # check required options
+    if (!defined $plugin || $plugin !~ /\w/) {
+	&PrintUsage::print_txt_usage($options, "{explode.params}");
+	print STDERR "You need to specify a plugin";
+	die "\n";
+    }
+    
+    # check metadata set
+    if (defined $metadata_set && $metadata_set =~ /\w/) {
+	$metadata_set .= ".";
+    } else {
+	$metadata_set = "";
+    }
+    if (defined $collection && $collection =~ /\w/) {
+	if (($collection = &colcfg::use_collection("", $collection, "")) eq "") {
+	    print STDERR "Collection $collection does not exist\n";
+	    die "\n";
+	}
+    } else {
+	undef $collection;
+    }
+    
+    if ($use_collection_plugin_options) {
+	if (defined $plugin_options && $plugin_options =~ /\w/) {
+	    print STDERR "Error: you cannot have -use_collection_plugin_options and -plugin_options set at the same time\n";
+	    die "\n";
+	}
+	if (not defined $collection) {
+	    print STDERR "Error: you must specify a collection using -collection to use -use_collection_plugin_options\n";
+	    die "\n";
+	}
+    }
+    my $plugobj;
+    require "$plugin.pm";
+
+    my $plugin_options_string = "";
+    if ($use_collection_plugin_options) {
+	# read in the collect.cfg file
+	# Read in the collection configuration file.
+	my ($configfilename, $gs_mode) = &colcfg::get_collect_cfg_name(STDERR);
+	my $collectcfg = &colcfg::read_collect_cfg ($configfilename, $gs_mode);
+	$plugin_options_string = &get_plugin_options($collectcfg, $plugin);
+    }
+    elsif (defined $plugin_options && $plugin_options =~ /\w/) {
+	my @options = split(/\s/, $plugin_options);
+	map { $_ = "\"$_\"" unless $_ =~ /^\"/; } @options;
+	$plugin_options_string= join (",", @options);
+    }
+
+    if ($plugin_options_string eq "") {
+	eval ("\$plugobj = new $plugin()");
+	die "$@" if $@;
+    } else {
+	eval ("\$plugobj = new $plugin([], [$plugin_options_string])");
+	die "$@" if $@;
+    } 
+    
+    # ...and initialize it
+    $plugobj->init($verbosity, "STDERR", "STDERR");
+
+    if ($input_encoding eq "auto") {
+	($language, $input_encoding) = $plugobj->textcat_get_language_encoding ($filename);
+    }	    
+
+    # Create a directory to store the document files...
+    my ($exploded_base_dir) = ($filename =~ /(.*)\.[^\.]+$/);
+
+    my $orig_base_dir = &File::Basename::dirname($filename);
+
+
+    my $split_exp = $plugobj->{'split_exp'};
+    if (defined $split_exp) {
+	# Read in file, and then split and process individual records
+
+	my $text = "";
+	# Use the plugin's read_file function to avoid duplicating code
+	$plugobj->read_file($filename, $input_encoding, undef, \$text);
+	# is there any text in the file??
+	die "\n" unless length($text);
+
+	# Split the text into records, using the plugin's split_exp
+
+	my @metadata_records = split(/$split_exp/, $text);
+	my $total_num_records = scalar(@metadata_records);
+	print STDERR "Number of records: $total_num_records\n";
+	
+	# Write the metadata from each record to the metadata.xml file
+	my $record_number = 1;
+	my $documents_directory;
+	foreach my $record_text (@metadata_records) {
+	    
+	    # Check if we need to start a new directory for these records
+	    check_need_new_directory($exploded_base_dir,$record_number,
+				     $records_per_folder,$total_num_records,
+				     \$documents_directory);
+	    # Use the plugin's process function to avoid duplicating code
+	    my $doc_obj = new doc($filename, "nonindexed_doc", $plugobj->get_file_rename_method());
+	    $plugobj->process(\$record_text, undef, undef, $filename, undef, $doc_obj, 0);
+	    
+	    
+	    # Try to get a doc to attach the metadata to
+	    # If no match found, create a dummy .nul file
+	    attach_metadata_or_make_nul_doc($document_field, $doc_obj, $record_number,
+				       $documents_directory, $orig_base_dir,
+				       $document_prefix, $document_suffix, $metadata_set, $verbosity);
+	    	    
+	    
+	    check_close_directory($record_number,$records_per_folder,$total_num_records);
+	    
+	    $record_number = $record_number + 1;
+	}
+    }
+    else {
+	# Call metadata_read to set up associated metadata 
+
+	my $pluginfo = undef;
+	my $block_hash = {};
+
+	my $processor = undef;
+	my $maxdocs = undef;
+	my $gli = undef;
+
+	my $extrametakeys = [];
+	my $extrametadata = {};
+	my $extrametafile = {};
+
+	$plugobj->metadata_read($pluginfo, "", $filename, $block_hash,   
+				$extrametakeys, $extrametadata, $extrametafile,
+				$processor, $maxdocs, $gli);
+
+	my $total_num_records = scalar (@$extrametakeys);
+	print STDERR "Number of records: $total_num_records\n";
+	my $record_number = 1;
+	my $documents_directory;
+	foreach my $record (@$extrametakeys) {
+	    &check_need_new_directory($exploded_base_dir, $record_number, $records_per_folder, $total_num_records, \$documents_directory);
+	    
+	    # Attach metadata to object
+	    # => use the plugin's extra_metadata function to avoid duplicating code
+	    my $doc_obj = new doc($filename, "nonindexed_doc", $plugobj->get_file_rename_method());
+	    # all the metadata has been extracted into extrametadata
+	    $plugobj->extra_metadata ($doc_obj, $doc_obj->get_top_section(), $extrametadata->{$record});
+
+	    # Try to get a doc to attach the metadata to
+	    # If no match found, create a dummy .nul file
+	    attach_metadata_or_make_nul_doc($document_field, $doc_obj, $record_number, $documents_directory, $orig_base_dir, $document_prefix, $document_suffix, $metadata_set, $verbosity);
+	    
+	    &check_close_directory($record_number,$records_per_folder,$total_num_records);
+	    
+	    $record_number = $record_number + 1;
+
+	}
+    }
+
+    # Explode means just that: the original file is deleted
+    &util::rm($filename);
+    $plugobj->clean_up_after_exploding();
+
+}
+
+
+sub need_new_directory
+{
+    my ($exploded_base_dir) = @_;
+    
+    my $documents_directory = $exploded_base_dir;
+
+    if (-d $documents_directory) {
+	die "Error: document directory $documents_directory already exists (bailing).\n";
+    }
+    &util::mk_dir($documents_directory);
+
+    my $documents_metadata_xml_file = &util::filename_cat($documents_directory, "metadata.xml");
+    if (-e $documents_metadata_xml_file) {
+	die "Error: documents metadata.xml file $documents_metadata_xml_file already exists (bailing).\n";
+    }
+
+    # Start the metadata.xml file
+    open(METADATA_XML_FILE, ">$documents_metadata_xml_file");
+    print METADATA_XML_FILE
+	"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" .
+	"<!DOCTYPE DirectoryMetadata SYSTEM \"http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd\">\n" .
+	"<DirectoryMetadata>\n";
+
+    return $documents_directory;
+}
+
+sub check_need_new_directory
+{
+    my ($exploded_base_dir,$record_number, $records_per_folder,
+	$total_num_records, $documents_dir_ref) = @_;
+    
+
+    # Check if we need to start a new directory for these records
+    if (($record_number % $records_per_folder) == 1) {
+	my $documents_directory = $exploded_base_dir;
+
+	if ($total_num_records > $records_per_folder) {
+	    $documents_directory .= "." . sprintf("%8.8d", $record_number);
+	}
+
+	$$documents_dir_ref = need_new_directory($documents_directory);
+    }
+}
+
+
+
+
+
+sub attach_metadata_or_make_nul_doc
+{
+    my ($document_field, $doc_obj, $record_number, 
+	$documents_directory, $orig_base_dir,
+	$document_prefix, $document_suffix, $metadata_set, $verbosity) = @_;
+
+    my $record_metadata = $doc_obj->get_all_metadata($doc_obj->get_top_section());
+    my $document_file;
+
+    # try to get a doc to attach the metadata to
+    if (defined $document_field) {
+	foreach my $pair (@$record_metadata) {
+	    my ($field, $value) = (@$pair);
+
+	    $value =~ s/\\\\/\\/g;
+	    my $document_file_full;
+
+	    # Does this metadata element specify a document to obtain?
+	    if ($field eq $document_field) {
+		if(-d $document_prefix && $document_prefix !~ m@^(http|ftp|https)://@ ) {
+		    # if the document-prefix refers to a directory but not URL, ensure it has a file-separator at the end
+		    # by first of all stripping any trailing slash and then always ensuring one is used through filename_cat
+		    $document_prefix =~ s/(\/|\\)$//;
+		    $document_file_full = &util::filename_cat($document_prefix, "$value$document_suffix");
+		} else { # the doc prefix may also contain the prefix of the actual *filename* following the directory
+		    $document_file_full = $document_prefix . $value . $document_suffix;
+		}
+
+		# this either downloads/copies the document, or creates a nul file for it.
+		$document_file = &obtain_document($document_file_full, $documents_directory, $orig_base_dir, $verbosity);
+		&write_metadata_xml_file_entry(METADATA_XML_FILE, $document_file, $record_metadata, $metadata_set);
+	    }
+	}
+    }
+    
+    # Create a dummy .nul file if we haven't obtained a document (or null file) for this record
+    if (not defined $document_file) {
+
+	if (defined ($record_number)) {
+	    $document_file = sprintf("%8.8d", $record_number) . ".nul";
+	}
+	else {
+	    $document_file = "doc.nul";
+	}
+	open(DUMMY_FILE, ">$documents_directory/$document_file");
+	close(DUMMY_FILE);
+	&write_metadata_xml_file_entry(METADATA_XML_FILE, $document_file, $record_metadata, $metadata_set);
+    }
+
+}
+
+sub close_directory
+{
+    # Finish and close the metadata.xml file
+    print METADATA_XML_FILE "\n</DirectoryMetadata>\n";
+    close(METADATA_XML_FILE);
+
+}
+
+
+sub check_close_directory
+{
+    my ($record_number,$records_per_folder,$total_num_records) = @_;
+
+    if (($record_number % $records_per_folder) == 0 || $record_number == $total_num_records) {
+	# Finish and close the metadata.xml file
+	close_directory();
+    }
+}
+	    
+
+
+sub write_metadata_xml_file_entry
+{
+    my $metadata_xml_file = shift(@_);
+    my $file_name = shift(@_);
+    my $record_metadata = shift(@_);
+    my $meta_prefix = shift(@_);
+    
+    # Make $file_name XML-safe
+    $file_name =~ s/&/&amp;/g;
+    $file_name =~ s/</&lt;/g;
+    $file_name =~ s/>/&gt;/g;
+
+    # Convert $file_name into a regular expression that matches it
+    $file_name =~ s/\./\\\./g;
+    $file_name =~ s/\(/\\\(/g;
+    $file_name =~ s/\)/\\\)/g;
+    $file_name =~ s/\{/\\\{/g;
+    $file_name =~ s/\}/\\\}/g;
+    $file_name =~ s/\[/\\\[/g;
+    $file_name =~ s/\]/\\\]/g;
+    
+    print $metadata_xml_file
+	"\n" .
+        "  <FileSet>\n" .
+	"    <FileName>$file_name</FileName>\n" .
+	"    <Description>\n";
+
+    foreach my $pair (@$record_metadata) {
+	my ($field, $value) = (@$pair);
+
+	# We're only interested in metadata from the database
+	next if ($field eq "lastmodified");
+	next if ($field eq "gsdlsourcefilename");
+	next if ($field eq "gsdldoctype");
+	next if ($field eq "FileFormat");
+
+	# Ignore the ^all metadata, since it will be invalid if the source metadata is changed
+	next if ($field =~ /\^all$/);  # ISISPlug specific!
+
+	# Square brackets in metadata values need to be escaped so they don't confuse Greenstone/GLI
+	$value =~ s/\[/&\#091;/g;
+	$value =~ s/\]/&\#093;/g;
+
+	# Make $value XML-safe
+	$value =~ s/&/&amp;/g;  # May mess up existing entities!
+	$value =~ s/</&lt;/g;
+	$value =~ s/>/&gt;/g;
+
+	# we are not allowed & in xml except in entities. 
+	# if there are undefined entities then parsing will also crap out.
+	# should we be checking for them too?
+	# this may not get all possibilities
+	# $value =~ s/&([^;\s]*(\s|$))/&amp;$1/g;
+
+	# do we already have a namespace specified?
+	my $full_field = $field;
+	if ($meta_prefix ne "") {
+	    $full_field =~ s/^\w+\.//;
+	    $full_field = $meta_prefix.$full_field;
+	}
+
+	print $metadata_xml_file "      <Metadata mode=\"accumulate\" name=\"$full_field\">$value</Metadata>\n";
+    }
+
+    print $metadata_xml_file
+	"    </Description>\n" .
+	    "  </FileSet>\n";
+}
+
+sub obtain_document
+{
+    my ($document_file_full,$documents_directory,$orig_base_dir,$verbosity) = @_;
+    
+    print STDERR "Obtaining document file $document_file_full...\n" if ($verbosity > 1);
+
+    my $document_file_name;
+    my $local_document_file;
+
+    # Document specified is on the web
+    if ($document_file_full =~ /^https?:/ || $document_file_full =~ /^ftp:/) {
+	$document_file_full =~ /([^\/]+)$/;
+	$document_file_name = $1;
+	$local_document_file = &util::filename_cat($documents_directory, $document_file_name);
+
+	my $wget_options = "--quiet";
+	$wget_options = "--verbose" if ($verbosity > 2);
+	$wget_options .= " --timestamping";  # Only re-download files if they're newer
+	my $wget_command = "wget $wget_options \"$document_file_full\" --output-document \"$local_document_file\"";
+	`$wget_command`;
+
+	# Check the document was obtained successfully
+	if (!-e $local_document_file) {
+	    print STDERR "WARNING: Could not obtain document file $document_file_full\n";
+	}
+    }
+    # Document specified is on the disk
+    else {
+	# convert the dirseps in filepath to correct dir sep for OS
+	$document_file_full = &util::filename_cat($document_file_full);
+	my $dir_sep = &util::get_os_dirsep();
+
+	$document_file_full =~ m/(.+$dir_sep)?(.*)$/;
+	$document_file_name = $2;
+
+
+	my $is_absolute = File::Spec->file_name_is_absolute($document_file_full);
+	print STDERR "doc file full = $document_file_full\n";
+
+	if (!$is_absolute) {
+	    $document_file_full 
+		= &util::filename_cat($orig_base_dir,$document_file_full);
+	}
+
+	$local_document_file = &util::filename_cat($documents_directory, $document_file_name);
+
+	if (-e $document_file_full) {
+	    &util::cp($document_file_full, $documents_directory);
+	}
+	
+	# Check the document was obtained successfully
+	if (!-e $local_document_file) {
+	    print STDERR "WARNING: Could not obtain document file $document_file_full\n";
+	}
+	else {
+	    $orig_base_dir =~ s/\\/\\\\/g; # escape windows style slashes for the regex below
+	    if ($document_file_full =~ m/^$orig_base_dir.*/) {
+		# file local to metadata record
+		# => copy has been made successfully, so remove original
+		&util::rm($document_file_full);
+	    }
+	}
+    }
+
+    # If the document wasn't obtained successfully, create a .nul file for it
+    if (!-e $local_document_file) {
+	$document_file_name .= ".nul";
+	open(NULL_FILE, ">$local_document_file.nul");
+	close(NULL_FILE);
+	print STDERR "Creating a nul document $document_file_name\n";
+    }
+
+    return $document_file_name;
+}
+
+sub get_plugin_options {
+    my ($collectcfg, $plugin)  = @_;
+    
+    my $plugin_list = $collectcfg ->{'plugin'};
+    
+    foreach my $pluginoptions (@$plugin_list) {
+	my $pluginname = shift @$pluginoptions;
+	next unless $pluginname eq $plugin;
+	map { $_ = "\"$_\""; } @$pluginoptions;
+	my $options = join (",", @$pluginoptions);
+	return $options;
+    }
+    return "";
+}
+
+&main(@ARGV);
+
Index: /gsdl/stable/bin/script/export.pl
===================================================================
--- /gsdl/stable/bin/script/export.pl	(revision 20131)
+++ /gsdl/stable/bin/script/export.pl	(revision 20131)
@@ -0,0 +1,654 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# export.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2004 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will export a particular collection into a specific Format (e.g. METS or DSpace)
+
+package export;
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugins");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugouts");
+
+    if (defined $ENV{'GSDLEXTS'}) {
+	my @extensions = split(/:/,$ENV{'GSDLEXTS'});
+	foreach my $e (@extensions) {
+	    my $ext_prefix = "$ENV{'GSDLHOME'}/ext/$e";
+
+	    unshift (@INC, "$ext_prefix/perllib");
+	    unshift (@INC, "$ext_prefix/perllib/cpan");
+	    unshift (@INC, "$ext_prefix/perllib/plugins");
+	    unshift (@INC, "$ext_prefix/perllib/plugouts");
+	}
+    }
+}
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and vice versa
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+
+use arcinfo;
+use colcfg;
+use plugin;
+use plugout;
+use manifest;
+use util;
+use scriptutil;
+use FileHandle;
+use gsprintf 'gsprintf';
+use printusage;
+use parse2;
+
+
+my $oidtype_list = 
+    [ { 'name' => "hash",
+        'desc' => "{import.OIDtype.hash}" },
+      { 'name' => "assigned",
+        'desc' => "{import.OIDtype.assigned}" },
+      { 'name' => "incremental",
+        'desc' => "{import.OIDtype.incremental}" },
+      { 'name' => "dirname",
+        'desc' => "{import.OIDtype.dirname}" } ];
+
+# what format to export as
+my $saveas_list = 
+    [ { 'name' => "GreenstoneMETS",
+        'desc' => "{export.saveas.GreenstoneMETS}"},
+      { 'name' => "FedoraMETS",
+        'desc' => "{export.saveas.FedoraMETS}"},
+      { 'name' => "MARCXML",
+        'desc' => "{export.saveas.MARCXML}"},
+      { 'name' => "DSpace",
+        'desc' => "{export.saveas.DSpace}" }
+     ];
+
+
+# Possible attributes for each argument
+# name: The name of the argument
+# desc: A description (or more likely a reference to a description) for this argument
+# type: The type of control used to represent the argument. Options include: string, int, flag, regexp, metadata, language, enum etc
+# reqd: Is this argument required?
+# hiddengli: Is this argument hidden in GLI?
+# modegli: The lowest detail mode this argument is visible at in GLI
+
+my $saveas_argument =
+      { 'name' => "saveas",
+	'desc' => "{export.saveas}",
+	'type' => "enum",
+	'list' => $saveas_list,
+	'deft' => "GreenstoneMETS",
+	'reqd' => "no",
+	'modegli' => "3" };
+
+
+my $arguments = 
+    [ 
+      $saveas_argument,
+      { 'name' => "exportdir",
+	'desc' => "{export.exportdir}",
+	'type' => "string",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "importdir",
+	'desc' => "{import.importdir}",
+	'type' => "string",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "collectdir",
+	'desc' => "{export.collectdir}",
+	'type' => "string",
+	# parsearg left "" as default
+	#'deft' => &util::filename_cat ($ENV{'GSDLHOME'}, "collect"),
+	'deft' => "",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "site",
+	'desc' => "{import.site}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+     { 'name' => "manifest",
+	'desc' => "{import.manifest}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "listall",
+	'desc' => "{export.listall}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "debug",
+	'desc' => "{export.debug}",
+	'type' => "flag",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "faillog",
+	'desc' => "{export.faillog}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no",
+        'modegli' => "3" },
+      # does this make sense?
+#      { 'name' => "incremental",
+#	'desc' => "{import.incremental}",
+#	'type' => "flag",
+#	'hiddengli' => "yes" },
+      { 'name' => "keepold",
+	'desc' => "{export.keepold}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "removeold",
+	'desc' => "{export.removeold}",
+	'type' => "flag",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "maxdocs",
+	'desc' => "{export.maxdocs}",
+	'type' => "int",
+	'reqd' => "no",
+	'range' => "1,",
+	'modegli' => "1" },
+      { 'name' => "OIDtype",
+	'desc' => "{import.OIDtype}",
+	'type' => "enum",
+	'list' => $oidtype_list,
+	# parsearg left "" as default
+	#'deft' => "hash",
+	'reqd' => "no",
+	'modegli' => "2" },
+      { 'name' => "OIDmetadata",
+	'desc' => "{import.OIDmetadata}",
+	'type' => "string",
+	#'type' => "metadata", #doesn't work properly in GLI
+	'deft' => "dc.Identifier",
+	'reqd' => "no",
+	'modegli' => "2" },
+      { 'name' => "out",
+	'desc' => "{export.out}",
+	'type' => "string",
+	'deft' => "STDERR",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "statsfile",
+	'desc' => "{export.statsfile}",
+	'type' => "string",
+	'deft' => "STDERR",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "xsltfile",
+	'desc' => "{BasPlugout.xslt_file}",
+	'type' => "string",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "xslt_txt",
+	'desc' => "{METSPlugout.xslt_txt}",
+	'type' => "string",
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "xslt_mets",
+	'desc' => "{METSPlugout.xslt_mets}",
+	'type' => "string",
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "fedora_namespace",
+	'desc' => "{FedoraMETSPlugout.fedora_namespace}",
+	'type' => "string",
+	'deft' => "greenstone",
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "mapping_file",
+	'desc' => "{MARCXMLPlugout.mapping_file}",
+	'type' => "string",
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "group_marc",
+	'desc' => "{MARCXMLPlugout.group}",
+	'type' => "flag",
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "verbosity",
+	'desc' => "{export.verbosity}",
+	'type' => "int",
+	'range' => "0,3",
+	'deft' => "2",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "gli",
+	'desc' => "{scripts.gli}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "xml",
+	'desc' => "{scripts.xml}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" }
+      ];
+
+my $options = { 'name' => "export.pl",
+		'desc' => "{export.desc}",
+		'args' => $arguments };
+
+my $listall_options = { 'name' => "export.pl",
+		        'desc' => "{export.desc}",
+		        'args' => [ $saveas_argument ] };
+
+
+&main();
+
+sub main {
+    # params
+    my ($language, $verbosity, $debug,
+	$collectdir, $importdir, $exportdir, $site, $manifest, 
+	$incremental, $keepold, $removeold,
+	$saveas,
+	$OIDtype, $OIDmetadata,
+	$maxdocs, $statsfile, 
+	$out, $faillog, $gli, $listall, 
+	# plugout specific ones
+	$mapping_file, $xsltfile, 
+	$xslt_mets, $xslt_txt, $fedora_namespace, $group_marc);
+
+    my $xml = 0;
+    
+    # other vars
+    my ($configfilename, $collection, $collectcfg,
+	$expinfo_doc_filename, $export_info, 
+	$gs_mode, 
+	$processor, $pluginfo);
+
+    my $service = "export";
+
+    my $hashParsingResult = {};
+    # general options available to all plugins
+    my $intArgLeftinAfterParsing = parse2::parse(\@ARGV,$arguments,$hashParsingResult,"allow_extra_options");
+    
+    # If parse returns -1 then something has gone wrong
+    if ($intArgLeftinAfterParsing == -1)
+    {
+	&PrintUsage::print_txt_usage($options, "{export.params}");
+	die "\n";
+    }
+
+    foreach my $strVariable (keys %$hashParsingResult)
+    {
+	eval "\$$strVariable = \$hashParsingResult->{\"\$strVariable\"}";
+    }
+
+    
+    # these are options used by other things - we just set default values
+    # undef means will be set from config file if there
+    my $gzip = undef; 
+
+    # If $language has been specified, load the appropriate resource bundle
+    # (Otherwise, the default resource bundle will be loaded automatically)
+    if ($language && $language =~ /\S/) {
+	&gsprintf::load_language_specific_resource_bundle($language);
+    }
+
+    if ($listall) {
+	if ($xml) {
+	    &PrintUsage::print_xml_usage($listall_options);
+	}
+	else
+	{
+	    &PrintUsage::print_txt_usage($listall_options,"{export.params}");
+	}
+	die "\n";
+    }
+    
+    if ($xml) {
+        &PrintUsage::print_xml_usage($options);
+	die "\n";
+    }
+
+    if ($gli) { # the gli wants strings to be in UTF-8
+	&gsprintf::output_strings_in_UTF8; 
+    }
+
+    # now check that we had exactly one leftover arg, which should be 
+    # the collection name. We don't want to do this earlier, cos 
+    # -xml arg doesn't need a collection name
+    # Or if the user specified -h, then we output the usage also
+    if ($intArgLeftinAfterParsing != 1 || (@ARGV && $ARGV[0] =~ /^\-+h/))
+    {
+	&PrintUsage::print_txt_usage($options, "{export.params}");
+	die "\n";
+    }
+
+    my $close_out = 0;
+    if ($out !~ /^(STDERR|STDOUT)$/i) {
+	open (OUT, ">$out") ||
+	    (&gsprintf(STDERR, "{common.cannot_open_output_file}\n", $out) && die);
+	$out = 'export::OUT';
+	$close_out = 1;
+    }
+    $out->autoflush(1);
+
+    # get and check the collection name
+    if (($collection = &colcfg::use_collection($site, @ARGV, $collectdir)) eq "") {
+	&PrintUsage::print_txt_usage($options, "{export.params}");
+	die "\n";
+    }
+    # add collection's perllib dir  into include path in 
+    # case we have collection specific modules
+    unshift (@INC, "$ENV{'GSDLCOLLECTDIR'}/perllib");
+	
+    # check that we can open the faillog
+    if ($faillog eq "") {
+	$faillog = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "etc", "fail.log");
+    }
+    open (FAILLOG, ">$faillog") ||
+	(&gsprintf(STDERR, "{export.cannot_open_fail_log}\n", $faillog) && die);
+    my $faillogname = $faillog;
+    $faillog = 'export::FAILLOG';
+    $faillog->autoflush(1);
+	    
+    # Read in the collection configuration file.
+    ($configfilename, $gs_mode) = &colcfg::get_collect_cfg_name($out);
+    $collectcfg = &colcfg::read_collection_cfg ($configfilename, $gs_mode);
+    
+    if (defined $collectcfg->{'importdir'} && $importdir eq "") {
+	$importdir = $collectcfg->{'importdir'};
+    }
+    if (defined $collectcfg->{'exportdir'} && $exportdir eq "") {
+	$exportdir = $collectcfg->{'exportdir'};
+    }
+
+    # fill in the default import and export directories if none
+    # were supplied, turn all \ into / and remove trailing /
+    $importdir = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "import") if $importdir eq "";
+    $importdir =~ s/[\\\/]+/\//g;
+    $importdir =~ s/\/$//;
+    if (!-e $importdir) {
+	&gsprintf($out, "{import.no_import_dir}\n\n", $importdir);
+	die "\n";
+    }
+
+    $exportdir = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "export") if $exportdir eq "";
+    $exportdir =~ s/[\\\/]+/\//g;
+    $exportdir =~ s/\/$//;
+    
+    my $plugins = [];
+    if (defined $collectcfg->{'plugin'}) {
+	$plugins = $collectcfg->{'plugin'};
+    }
+    # some global options for the plugins    	    
+    my @global_opts = ();
+
+    if ($verbosity !~ /\d+/) {
+	if (defined $collectcfg->{'verbosity'} && $collectcfg->{'verbosity'} =~ /\d+/) {
+	    $verbosity = $collectcfg->{'verbosity'};
+	} else {
+	    $verbosity = 2; # the default
+	}
+    }
+    
+    if (defined $collectcfg->{'gzip'} && !$gzip) {
+	if ($collectcfg->{'gzip'} =~ /^true$/i) {
+	    $gzip = 1;
+	}
+    }
+    if ($maxdocs !~ /\-?\d+/) {
+	if (defined $collectcfg->{'maxdocs'} && $collectcfg->{'maxdocs'} =~ /\-?\d+/) {
+	    $maxdocs = $collectcfg->{'maxdocs'};
+	} else {
+	    $maxdocs = -1; # the default
+	}
+    }
+    
+    if (!defined $OIDtype || ($OIDtype !~ /^(hash|incremental|assigned|dirname)$/)) {
+	if (defined $collectcfg->{'OIDtype'} && $collectcfg->{'OIDtype'} =~ /^(hash|incremental|assigned|dirname)$/) {
+	    $OIDtype = $collectcfg->{'OIDtype'};
+	} else {
+	    $OIDtype = "hash"; # the default
+	}
+    }
+
+    if (defined $collectcfg->{'debug'} && $collectcfg->{'debug'} =~ /^true$/i) {
+	$debug = 1;
+    }
+    if (defined $collectcfg->{'gli'} && $collectcfg->{'gli'} =~ /^true$/i) {
+	$gli = 1;
+    }
+    $gli = 0 unless defined $gli;
+
+    # check keepold and removeold
+    ($removeold, $keepold, $incremental) = &scriptutil::check_removeold_and_keepold($removeold, $keepold, $incremental, "export", $collectcfg);
+
+    print STDERR "<export>\n" if $gli;
+	
+    my $manifest_lookup = new manifest();
+    if ($manifest ne "") {	
+	my $manifest_filename = $manifest;
+
+	if ($manifest_filename !~ m/^[\\\/]/) {
+	    $manifest_filename = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, $manifest_filename);
+	}
+
+	$manifest =~ s/[\\\/]+/\//g;
+	$manifest =~ s/\/$//;
+
+	$manifest_lookup->parse($manifest_filename);
+    }
+    
+    # load all the plugins
+    $pluginfo = &plugin::load_plugins ($plugins, $verbosity, $out, $faillog, \@global_opts);
+	    
+    if (scalar(@$pluginfo) == 0) {
+	&gsprintf($out, "{import.no_plugins_loaded}\n");
+	die "\n";
+    }
+    
+    # remove the old contents of the export directory if needed
+    if ($removeold && -e $exportdir) {
+	&gsprintf($out, "{export.removing_export}\n");
+	&util::rm_r ($exportdir);
+    }
+    
+    # create the export dir if needed
+    &util::mk_all_dir($exportdir);
+    
+    # read the export information file
+    # If saveas=DSpace, a "contents" file will be created, otherwise "export.inf"
+    
+    # the plugouts should be doing this!!
+    if ($saveas eq "DSpace"){
+	$expinfo_doc_filename = &util::filename_cat ($exportdir, "contents");
+    } elsif ($saveas =~ m/^.*METS$/ || $saveas eq "MARC" ) {
+##	$expinfo_doc_filename = &util::filename_cat ($exportdir, "export.inf");
+	my $doc_db = "archiveinf-doc";
+	$expinfo_doc_filename = &util::filename_cat ($exportdir, $doc_db);
+	&util::rename_gdbm_file($expinfo_doc_filename); # ensures gdb in case we have an existing legacy ldb one - can this happen?
+	$expinfo_doc_filename .= ".gdb";
+
+    }
+	    
+    $export_info = new arcinfo();
+    $export_info -> load_info ($expinfo_doc_filename);	
+	    
+    my ($plugout); 
+    if (defined $collectcfg->{'plugout'} && $collectcfg->{'plugout'} =~ /^(.*METS|DSpace|MARCXML)Plugout/) {
+	$plugout = $collectcfg->{'plugout'};
+    }
+    else{
+	if ($saveas !~ /^(.*METS|DSpace|MARCXML)$/) {
+	    push @$plugout,"GreenstoneMETSPlugout";
+	}
+	else{
+	    push @$plugout,$saveas."Plugout";
+	}
+    }
+    
+    my $plugout_name = $plugout->[0];
+	    
+    push @$plugout,("-output_info",$export_info) if (defined $export_info); 
+    push @$plugout,("-verbosity",$verbosity) if (defined $verbosity);
+    push @$plugout,("-debug") if ($debug);
+    push @$plugout,("-gzip_output",$gzip) if (defined $gzip);
+    push @$plugout,("-output_handle",$out) if (defined $out);
+    push @$plugout,("-xslt_file",$xsltfile) if (defined $xsltfile);
+    push @$plugout,("-group") if ($group_marc && $plugout_name =~ m/^MARCXMLPlugout$/);
+    push @$plugout,("-mapping_file",$mapping_file) if (defined $mapping_file && $plugout_name =~ m/^MARCXMLPlugout$/);
+    push @$plugout,("-xslt_mets",$xslt_mets) if (defined $xslt_mets && $plugout_name =~ m/^.*METSPlugout$/);
+    push @$plugout,("-xslt_txt",$xslt_txt) if (defined $xslt_txt && $plugout_name =~ m/^.*METSPlugout$/);
+    push @$plugout,("-fedora_namespace",$fedora_namespace) if (defined $fedora_namespace && $plugout_name eq "FedoraMETSPlugout");
+    
+    $processor = &plugout::load_plugout($plugout);    
+    $processor->setoutputdir ($exportdir);
+	    
+    $processor->set_OIDtype ($OIDtype, $OIDmetadata);
+	    
+    &plugin::begin($pluginfo, $importdir, $processor, $maxdocs, $gli);
+	    
+    if ($manifest eq "") {
+	# process the import directory
+	my $block_hash = {};
+	my $metadata = {};
+	# gobal blocking pass may set up some metadata
+	&plugin::file_block_read($pluginfo, $importdir, "", $block_hash, $metadata, $gli);
+	&plugin::read ($pluginfo, $importdir, "", $block_hash, $metadata, $processor, $maxdocs, 0, $gli);
+    } 
+    else {
+	# process any files marked for exporting
+	foreach my $file (keys %{$manifest_lookup->{'index'}}) {
+	    &plugin::read ($pluginfo, $importdir, $file, {}, {}, $processor, $maxdocs, 0, $gli);
+	}
+    }
+
+    if ($saveas eq "FedoraMETS") {
+	# create collection "doc obj" for Fedora that contains
+	# collection-level metadata
+	
+	my $doc_obj = new doc($configfilename,"nonindexed_doc");
+	$doc_obj->set_OID("collection");
+	
+	my $col_name = undef;
+	my $col_meta = $collectcfg->{'collectionmeta'};
+	
+	if (defined $col_meta) {
+	    
+	    store_collectionmeta($col_meta,"collectionname",$doc_obj); # in GS3 this is a collection's name
+	    store_collectionmeta($col_meta,"collectionextra",$doc_obj); # in GS3 this is a collection's description
+	    
+	}
+	$processor->process($doc_obj);
+    }
+	    
+    &plugin::end($pluginfo, $processor);
+
+    &plugin::deinit($pluginfo, $processor);
+	    
+    # write out the export information file
+    #$processor->close_file_output() if $groupsize > 1;
+    $processor->close_group_output() if $processor->is_group();
+
+    if (($saveas =~ m/^.*METS$/) || ($saveas eq "MARC")) {
+	# Not all export types need this (e.g. DSpace)
+	$export_info->save_info($expinfo_doc_filename);
+    }
+	    
+    # write out export stats
+    my $close_stats = 0;
+    if ($statsfile !~ /^(STDERR|STDOUT)$/i) {
+	if (open (STATS, ">$statsfile")) {
+	    $statsfile = 'import::STATS';
+	    $close_stats = 1;
+	} else {
+	    &gsprintf($out, "{import.cannot_open_stats_file}", $statsfile);
+	    &gsprintf($out, "{import.stats_backup}\n");
+	    $statsfile = 'STDERR';
+	}
+    }
+
+    &gsprintf($out, "\n");
+    &gsprintf($out, "*********************************************\n");
+    &gsprintf($out, "{export.complete}\n");
+    &gsprintf($out, "*********************************************\n");
+   
+    &plugin::write_stats($pluginfo, $statsfile, $faillogname, $gli);
+    if ($close_stats) {
+	close STATS;
+    }
+    
+    close OUT if $close_out;
+    close FAILLOG;
+}
+
+
+sub store_collectionmeta
+{
+    my ($collectionmeta,$field,$doc_obj) = @_;
+
+    my $section = $doc_obj->get_top_section();
+
+    my $field_hash = $collectionmeta->{$field};
+
+    foreach my $k (keys %$field_hash) 
+    {
+	my $val = $field_hash->{$k};
+
+	### print STDERR "*** $k = $field_hash->{$k}\n";
+
+	my $md_label = "ex.$field";
+
+
+	if ($k =~ m/^\[l=(.*?)\]$/)
+	{
+
+	    my $md_suffix = $1;
+	    $md_label .= "^$md_suffix";
+	}
+
+
+	$doc_obj->add_utf8_metadata($section,$md_label, $val);
+	
+	# see collConfigxml.pm: GS2's "collectionextra" is called "description" in GS3,
+	# while "collectionname" in GS2 is called "name" in GS3.
+	# Variable $nameMap variable in collConfigxml.pm maps between GS2 and GS3
+	if (($md_label eq "ex.collectionname^en") || ($md_label eq "ex.collectionname"))
+	{
+	    $doc_obj->add_utf8_metadata($section,"dc.Title", $val);
+	}
+
+    }
+}
+
+
+
+
Index: /gsdl/stable/bin/script/exportcol.pl
===================================================================
--- /gsdl/stable/bin/script/exportcol.pl	(revision 20131)
+++ /gsdl/stable/bin/script/exportcol.pl	(revision 20131)
@@ -0,0 +1,374 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# exportcol.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and vice versa
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+
+use util;
+use parse2;
+use printusage;
+
+my $arguments = 
+    [ 
+      { 'name' => "cdname",
+	'desc' => "{exportcol.cdname}",
+	'type' => "string",
+	'deft' => "Greenstone Collections",
+	'reqd' => "no" }, 
+      { 'name' => "cddir",
+	'desc' => "{exportcol.cddir}",
+	'type' => "string",
+	'deft' => "exported_collections",
+	'reqd' => "no" },
+      { 'name' => "noinstall",
+	'desc' => "{exportcol.noinstall}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "out",
+	'desc' => "{exportcol.out}",
+	'type' => "string",
+	'deft' => "STDERR",
+	'reqd' => "no" },
+      { 'name' => "xml",
+	'desc' => "{scripts.xml}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "gli",
+	'desc' => "",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+
+      ];
+
+my $options = { 'name' => "exportcol.pl",
+		'desc' => "{exportcol.desc}",
+		'args' => $arguments };
+
+sub gsprintf
+{
+    return &gsprintf::gsprintf(@_);
+}
+
+
+&main();
+
+sub main {
+    my ($language, $out, $cdname, $cddir);
+    
+    my $noinstall = 0;
+    my $xml = 0;
+    my $gli = 0;
+
+    my $hashParsingResult = {};
+
+    # parse options
+    my $intArgLeftinAfterParsing = parse2::parse(\@ARGV,$arguments,$hashParsingResult,"allow_extra_options");
+
+    # If parse returns -1 then something has gone wrong
+    if ($intArgLeftinAfterParsing == -1)
+    {
+	&PrintUsage::print_txt_usage($options, "{exportcol.params}");
+	die "\n";
+    }
+    
+    foreach my $strVariable (keys %$hashParsingResult)
+    {
+	eval "\$$strVariable = \$hashParsingResult->{\"\$strVariable\"}";
+    }
+    
+    # If $language has been specified, load the appropriate resource bundle
+    # (Otherwise, the default resource bundle will be loaded automatically)
+    if ($language && $language =~ /\S/) {
+	&gsprintf::load_language_specific_resource_bundle($language);
+    }
+    
+    if ($xml) {
+        &PrintUsage::print_xml_usage($options);
+	print "\n";
+	return;
+    }
+    
+    if ($gli) { # the gli wants strings to be in UTF-8
+	&gsprintf::output_strings_in_UTF8; 
+    }
+    
+    # can have more than one collection name,  
+    # if the first extra option is -h, then output the help
+    if (scalar(@ARGV) == 0 || (@ARGV && $ARGV[0] =~ /^\-+h/)) {
+	&PrintUsage::print_txt_usage($options, "{exportcol.params}");
+	die "\n";
+    }
+
+    my @coll_list = @ARGV;
+
+    my $close_out = 0;
+    if ($out !~ /^(STDERR|STDOUT)$/i) {
+	open (OUT, ">$out") || 
+	    (&gsprintf(STDERR, "{common.cannot_open_output_file}\n", $out) && die);
+	$out = 'main::OUT';
+	$close_out = 1;
+    }
+
+    # first we do a quick check to see if the export coll function has been 
+    # installed
+    my $gssetupexe = &util::filename_cat ($ENV{'GSDLHOME'}, "bin", "windows", "gssetup.exe"); 
+    if (!-e $gssetupexe) {
+	&gsprintf($out, "{exportcol.fail} {exportcol.export_coll_not_installed}\n");
+	die "\n";
+    }
+
+    # check each collection
+    my @valid_coll_list = ();
+    foreach my $c (@coll_list) {
+	my $colldir = &util::filename_cat ($ENV{'GSDLHOME'}, "collect", $c);
+	if (! -d $colldir) {
+	    &gsprintf($out, "{exportcol.coll_not_found}\n", $c, $colldir);
+	    next;
+	}
+	my $colindexdir = &util::filename_cat ($colldir, "index");
+	my $coletcdir = &util::filename_cat ($colldir, "etc");
+	if ((!-d $colindexdir) || (!-d $coletcdir)) {
+	    &gsprintf($out, "{exportcol.coll_dirs_not_found}\n", $c);
+	    &gsprintf($out, "  $colindexdir\n");
+	    &gsprintf($out, "  $coletcdir\n");
+	    next;
+	}
+	# the collection seems ok, we add it to the valid coll list
+	push @valid_coll_list, $c;
+    }
+
+    if (not @valid_coll_list) {
+	# no valid colls left
+	&gsprintf($out, "{exportcol.fail} {exportcol.no_valid_colls}\n");
+	die "\n";
+    }
+
+    # create exported directory
+    my $topdir = &util::filename_cat ($ENV{'GSDLHOME'}, "tmp", $cddir);
+    &util::mk_all_dir ($topdir);
+    if (!-d $topdir) {
+	&gsprintf($out, "{exportcol.fail} {exportcol.couldnt_create_dir}\n", $topdir);
+	die "\n";
+    }
+
+    # we create either a self installing cd, or one that runs off the cd (and
+    # doesn't install anything
+
+    # create all the directories - we assume that if we created the top dir ok,
+    # then all the other mkdirs will go ok
+    my $gsdldir;
+    if ($noinstall) {
+	$gsdldir = $topdir;
+    } 
+    else {
+	$gsdldir = &util::filename_cat ($topdir, "gsdl");
+	&util::mk_all_dir ($gsdldir);
+    }
+    
+    my $collectdir = &util::filename_cat ($gsdldir, "collect");
+    &util::mk_all_dir ($collectdir);
+    my $etcdir = &util::filename_cat ($gsdldir, "etc");
+    &util::mk_all_dir ($etcdir);
+
+    #create the config files
+    if (!$noinstall) {
+	# create the install.cfg file
+	my $installcfg = &util::filename_cat ($topdir, "install.cfg");
+	if (!open (INSTALLCFG, ">$installcfg")) {
+	    &gsprintf($out, "{exportcol.fail} {exportcol.couldnt_create_file}\n", $installcfg);
+	    die "\n";
+	}
+	print INSTALLCFG "CompanyName:New Zealand Digital Library\n";
+	print INSTALLCFG "CollectionName:$cdname\n";
+	print INSTALLCFG "CollectionDirName:$cdname\n";
+	print INSTALLCFG "CollectionVersion:1.0\n";
+	print INSTALLCFG "CollectionVolume:1\n";
+	print INSTALLCFG "ProgramGroupName:Greenstone\n";
+	close INSTALLCFG;
+	
+	# create the manifest.cfg file
+	my $manifestcfg = &util::filename_cat ($topdir, "manifest.cfg");
+	if (!open (MANIFESTCFG, ">$manifestcfg")) {
+	    &gsprintf($out, "{exportcol.fail} {exportcol.couldnt_create_file}\n", $manifestcfg);
+	    die "\n";
+	}
+	print MANIFESTCFG "all:\n";
+	print MANIFESTCFG "  {library} {collection}\n\n";
+	print MANIFESTCFG "library:\n";
+	print MANIFESTCFG "  server.exe\n\n";
+	print MANIFESTCFG "database:\n";
+	print MANIFESTCFG '  etc ';
+	foreach my $c (@valid_coll_list) {
+	    print MANIFESTCFG "collect\\$c\\index\\text\\$c.gdb ";
+	}
+	print MANIFESTCFG "\n\n";
+	print MANIFESTCFG "collection:\n";
+	print MANIFESTCFG "  collect etc macros mappings web\n";
+	close MANIFESTCFG;
+	
+    }	
+
+    #create the autorun.inf file
+    my $autoruninf = &util::filename_cat ($topdir, "Autorun.inf");
+    if (!open (AUTORUNINF, ">$autoruninf")) {
+	&gsprintf($out, "{exportcol.fail} {exportcol.couldnt_create_file}\n", $autoruninf);
+	die "\n";
+    }
+    
+    print AUTORUNINF "[autorun]\n";
+    if ($noinstall) {
+	print AUTORUNINF "OPEN=server.exe\n";
+    } else {
+	print AUTORUNINF "OPEN=Setup.exe\n";
+    }
+    close AUTORUNINF;
+    
+    # copy the necessary stuff from GSDLHOME
+    my $webdir = &util::filename_cat ($ENV{'GSDLHOME'}, "web");
+    my $macrosdir = &util::filename_cat ($ENV{'GSDLHOME'}, "macros");
+    my $mappingsdir = &util::filename_cat ($ENV{'GSDLHOME'}, "mappings");
+    my $maincfg = &util::filename_cat ($ENV{'GSDLHOME'}, "etc", "main.cfg");
+    my $serverexe = &util::filename_cat ($ENV{'GSDLHOME'}, "bin", "windows", "server.exe");
+    my $setupexe = &util::filename_cat ($ENV{'GSDLHOME'}, "bin", "windows", "Setup.exe");
+
+    if ((!-d $webdir) || (!-d $macrosdir) || (!-d $mappingsdir) || (!-e $maincfg) ||
+	(!-e $serverexe) || (!-e $gssetupexe) || (!-e $setupexe)) {
+	&gsprintf($out, "{exportcol.fail} {exportcol.non_exist_files}\n");
+	&gsprintf($out, "  $webdir\n");
+	&gsprintf($out, "  $macrosdir\n");
+	&gsprintf($out, "  $mappingsdir\n");
+	&gsprintf($out, "  $maincfg\n");
+	&gsprintf($out, "  $serverexe\n");
+	&gsprintf($out, "  $gssetupexe\n");
+	&gsprintf($out, "  $setupexe\n");
+	die "\n";
+    }
+
+    &util::cp_r ($webdir, $gsdldir);
+    &util::cp_r ($macrosdir, $gsdldir);
+    &util::cp_r ($mappingsdir, $gsdldir);
+    &util::cp ($maincfg, $etcdir);
+    &util::cp ($serverexe, $gsdldir);
+
+    if (!$noinstall) {
+	&util::cp ($gssetupexe, $topdir);
+	&util::cp ($setupexe, $topdir);
+    }	
+    
+    # now change the home.dm macro file to a simple version
+    my $newmacrodir = &util::filename_cat ($gsdldir, "macros");
+    my $exporthome = &util::filename_cat ($newmacrodir, "exported_home.dm");
+    my $oldhome = &util::filename_cat ($newmacrodir, "home.dm");
+    if (-e $exporthome) {
+	&util::rm($oldhome);
+	&util::mv($exporthome, $oldhome);
+    }
+
+    # copy the collections over 
+    foreach my $c (@valid_coll_list) {
+	#old directories
+	my $colldir = &util::filename_cat ($ENV{'GSDLHOME'}, "collect", $c);
+	my $colindexdir = &util::filename_cat ($colldir, "index");
+	my $coletcdir = &util::filename_cat ($colldir, "etc");
+	my $colmacrosdir = &util::filename_cat ($colldir, "macros");
+	my $colimagesdir = &util::filename_cat ($colldir, "images");
+	my $colscriptdir = &util::filename_cat ($colldir, "script");
+	my $coljavadir = &util::filename_cat ($colldir, "java");
+	my $colstyledir = &util::filename_cat ($colldir, "style");
+	my $colflashdir = &util::filename_cat ($colldir, "flash");
+
+	# new coll directory
+	my $newcoldir = &util::filename_cat ($collectdir, $c);
+
+	&util::mk_all_dir ($newcoldir);
+	&util::cp_r ($colindexdir, $newcoldir);
+	&util::rename_gdbm_file(&util::filename_cat ($newcoldir, "index", "text", $c));
+	&util::cp_r ($coletcdir, $newcoldir);
+	&util::cp_r ($colmacrosdir, $newcoldir) if (-e $colmacrosdir);
+	&util::cp_r ($colimagesdir, $newcoldir) if (-e $colimagesdir);
+	&util::cp_r ($colscriptdir, $newcoldir) if (-e $colscriptdir);
+	&util::cp_r ($coljavadir, $newcoldir) if (-e $coljavadir);
+	&util::cp_r ($colstyledir, $newcoldir) if (-e $colstyledir);
+	&util::cp_r ($colflashdir, $newcoldir) if (-e $colflashdir);
+
+	# now we need to check the collect.cfg file to make sure it's public
+	my $collectcfg = &util::filename_cat ($newcoldir, "etc", "collect.cfg");
+	open INFILE, "<$collectcfg";
+	open OUTFILE, ">$collectcfg.tmp";
+	my $line;
+	while ($line = <INFILE>) {
+	    if ($line =~ /^\s*public\s+false/) {
+		print OUTFILE "public\ttrue\n";
+		last; # stop matching once we have found the line
+	    } else {
+		print OUTFILE "$line";
+	    }
+	}
+	# continue with no checking
+	while ($line = <INFILE>) {
+	    print OUTFILE "$line";
+	}
+	close INFILE;
+	close OUTFILE;
+	&util::mv("$collectcfg.tmp", $collectcfg);
+    }
+    &gsprintf($out, "{exportcol.success}");
+
+    my $successcolls = "";
+    my $first = 1;
+    foreach my $c (@valid_coll_list) {
+	if ($first) {
+	    $first=0;
+	} else {
+	    $successcolls .=", ";
+	}
+	$successcolls .= "$c";
+    }
+
+    my $gsdl_home = $ENV{'GSDLHOME'};
+    my $portable_topdir = $topdir;
+    # Disabled this because it isn't currently useful (the GLI applet doesn't do exporting)
+    # It doesn't work on Windows, either
+    # $portable_topdir =~ s/$gsdl_home/\$GSDLHOME/g;
+
+    &gsprintf($out, "{exportcol.output_dir}\n", $successcolls, $portable_topdir);
+    &gsprintf($out, "exportcol.pl succeeded:{exportcol.instructions}\n");
+    close OUT if $close_out;
+}
+
Index: /gsdl/stable/bin/script/extract_text.pl
===================================================================
--- /gsdl/stable/bin/script/extract_text.pl	(revision 20131)
+++ /gsdl/stable/bin/script/extract_text.pl	(revision 20131)
@@ -0,0 +1,147 @@
+#! /usr/bin/perl -w
+
+# extract_text.pl extracts the text from macro files, install scripts
+# etc. for translation.
+
+# output is currently to a tab separated list, suitable for importing into
+# excel.
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+}
+
+my $installsh = "$ENV{'GSDLHOME'}/Install.sh";
+my $macrosdir = "$ENV{'GSDLHOME'}/macros";
+my $installshield = 'C:/My Installations/is_gsdl_cdrom/String Tables/0009-English/value.shl';
+
+my $texthash = {};
+
+# first extract all the itextn variables from Install.sh
+open (INSTALLSH, $installsh) || die;
+undef $/;
+my $file = <INSTALLSH>;
+$/ = "\n";
+close INSTALLSH;
+
+$texthash->{'install_sh'} = {};
+while ($file =~ s/^(itext\d+)=\"(.*?)(?<!\\)\"//sm) {
+    my $key = $1;
+    my $value = $2;
+    $value =~ s/\n/\\n/gs;
+    $value =~ s/\t/\\t/gs;
+    if (defined ($texthash->{'install_sh'}->{$key})) {
+	print STDERR "ERROR: $1 already defined\n";
+    }
+    $texthash->{'install_sh'}->{$key} = $value;
+}
+
+
+# now grab the text from the macro files
+$texthash->{'macros'} = {};
+
+# english.dm
+&grab_macros("$macrosdir/english.dm");
+# english2.dm
+&grab_macros("$macrosdir/english2.dm");
+
+
+# text from installshield installation
+$texthash->{'installshield'} = {};
+open (ISHIELD, $installshield) || die;
+my $line = "";
+my $textserver = {};
+while (defined ($line = <ISHIELD>)) {
+    next unless ($line =~ /\w/);
+    last if $line =~ /^\[General\]/;
+    next if $line =~ /^\[/;
+
+    $line =~ s/\n/\\n/gs;
+    $line =~ s/\t/\\t/gs;
+
+    if ($line =~ /^(TEXT_SERVERTXT_\d+)=(.*)$/) {
+	$textserver->{$1} = $2;
+    } else {
+	$line =~ /^([^=]+)=(.*)$/;
+	$texthash->{'installshield'}->{$1} = $2;
+    }
+}
+close ISHIELD;
+my $tserver = "";
+foreach my $stext (sort keys %{$textserver}) {
+    $tserver .= $textserver->{$stext};
+}
+$texthash->{'installshield'}->{'TEXT_SERVERTXT'} = $tserver;
+
+# print out the result
+foreach my $type (keys (%$texthash)) {
+    print STDOUT "type:\t$type\n";
+    foreach my $key (sort keys (%{$texthash->{$type}})) {
+	print STDOUT "$key\t$texthash->{$type}->{$key}\n";
+    }
+}
+
+sub grab_macros {
+    my ($filename) = @_;
+
+    my $line = "";
+    my $pack = "Global";
+    my $macroname = "";
+    my $macrovalue = "";
+    open (FILE, $filename) || die;
+    while (defined ($line = <FILE>)) {
+	if ($line =~ /^package (\w+)/) {
+	    $pack = $1;
+	    $macroname = "";
+	    $macrovalue = "";
+	    next;
+	}
+
+	if ($line =~ /^_([^_\s]+)_\s*(?:\[[^\]]*\])?\s*\{(.*)$/s) {
+	    die "ERROR 1\n" if ($macroname ne "" || $macrovalue ne "");
+	    $macroname = $1;
+	    $macrovalue = $2 if defined $2;
+	    if ($macrovalue =~ s/^(.*?)(?<!\\)\}/$1/) {
+		&addmacro($pack, \$macroname, \$macrovalue);
+	    }		
+	} elsif ($macroname ne "") {
+	    if ($line =~ /^(.*?)(?<!\\)\}/) {
+		$macrovalue .= $1 if defined $1;
+		&addmacro($pack, \$macroname, \$macrovalue);
+	    } else {
+		$macrovalue .= $line;
+	    }
+	} elsif ($line =~ /^\#\# \"([^\"]+)\" \#\# \w+ \#\# (\w+) \#\#/) {
+	    my $imagename = "image:$2";
+	    my $imagetext = $1;
+	    &addmacro($pack, \$imagename, \$imagetext);
+	}
+    }
+    close FILE;
+}
+
+sub addmacro {
+    my ($pack, $nameref, $valref) = @_;
+
+    if ($$nameref !~ /^(httpicon|width|height)/) {
+
+	my $name = "$pack:$$nameref";
+	
+	if (defined ($texthash->{'macros'}->{$name})) {
+	    print STDERR "ERROR: $name already defined\n";	
+	}
+
+
+	$$valref =~ s/\n/\\n/gs;
+	$$valref =~ s/\t/\\t/gs;
+
+	$texthash->{'macros'}->{$name} = $$valref;
+    }
+
+    else {
+#	print STDERR "ignoring $$nameref\n";
+    }
+
+    $$nameref = "";
+    $$valref = "";
+}
Index: /gsdl/stable/bin/script/filecopy.pl
===================================================================
--- /gsdl/stable/bin/script/filecopy.pl	(revision 20131)
+++ /gsdl/stable/bin/script/filecopy.pl	(revision 20131)
@@ -0,0 +1,195 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# filecopy.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will "download" the specified files/directories
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use util;
+use parsargv;
+use File::stat;
+use File::Basename;
+use FileHandle;
+
+sub print_usage {
+    print STDERR "\n";
+    print STDERR "filecopy.pl: Recursively copies files into a collections import directory.\n\n";
+    print STDERR "\n  usage: $0 [options] [directories] collection-name\n\n";
+
+    print STDERR "  options:\n";
+    print STDERR "   -follow_links           Follow symbolic links when recursing directory\n";
+    print STDERR "                           structure\n";
+    print STDOUT "   -collectdir directory   Collection directory (defaults to " .
+	&util::filename_cat($ENV{'GSDLHOME'}). "collect for Greenstone2;\n";
+    print STDOUT"                            for Greenstone3 use -site option and then collectdir default will be\n";
+    print STDOUT "                            set to the collect folder within that site.)\n";
+    print STDOUT "   -site                   Specify the site within a Greenstone3 installation to use.\n";
+    print STDERR "   -out                    Filename or handle to print output status to.\n";
+    print STDERR "                           The default is STDERR\n\n";
+}
+
+sub get_file_list {
+    my $dirhash = shift @_;
+    my $filehash = shift @_;
+    my $dirname = shift @_;
+
+    my $full_importname 
+	= &util::filename_cat($collectdir, $dirname, "import");
+
+    # check for .kill file
+    if (-e &util::filename_cat($collectdir, $dirname, ".kill")) {
+	print $out "filecopy.pl killed by .kill file\n";
+	die "\n";
+    }
+
+    foreach my $file (@_) {
+
+	$file =~ s/^\"//;
+	$file =~ s/\"$//;
+
+	if (!$follow_links && -l $file) {
+	    # do nothing as we don't want to follow symbolic links
+
+	} elsif (-d $file) {
+	    my $dst_dir = &get_dst_dir ($full_importname, $file);
+	    # add this directory to the list to be created
+	    $dirhash->{$dst_dir} = 1;
+
+	    # read in dir
+            if (!opendir (DIR, $file)) {
+                print $out "Error: Could not open directory $file\n";
+            } else {
+                my @sub_files = grep (!/^\.\.?$/, readdir (DIR));
+                closedir DIR;
+		map { $_ = &util::filename_cat($file, $_); } @sub_files;
+		&get_file_list($dirhash, $filehash, $dirname, @sub_files);
+	    }
+
+	} else {
+	    my $dst_file = &get_dst_dir ($full_importname, $file);
+
+	    # make sure files directory is included in dirhash
+	    $dirhash->{File::Basename::dirname($dst_file)} = 1;
+
+	    if (-e $dst_file) {
+		# if destination file exists already we'll only copy it if
+		# the source file is newer
+		my $src_stat = stat($file);
+		my $dst_stat = stat($dst_file);
+		$filehash->{$file} = $dst_file if ($src_stat->mtime > $dst_stat->mtime);
+	    } else {
+		$filehash->{$file} = $dst_file;
+	    }
+	}
+    }
+}
+
+
+sub main {
+
+    if (!parsargv::parse(\@ARGV, 
+			 'follow_links', \$follow_links,
+			 'collectdir/.*/', \$collectdir,
+			 'site/.*/', \$site,
+			 'out/.*/STDERR', \$out)) {
+	&print_usage();
+	die "\n";
+    }
+
+
+    if (defined $site && $site =~ /\w/ )
+    {
+	die "GSDL3HOME not set." unless $ENV{'GSDL3HOME'};
+	$collectdir = &util::filename_cat ($ENV{'GSDL3HOME'}, "sites", $site, "collect") unless $collectdir =~ /\w/;
+    }
+    else
+    {
+	$collectdir = &util::filename_cat ($ENV{'GSDLHOME'}, "collect") unless $collectdir =~ /\w/;
+    }
+
+    my $collection = pop @ARGV;
+
+    my $close_out = 0;
+    if ($out !~ /^(STDERR|STDOUT)$/i) {
+	open (OUT, ">$out") || die "Couldn't open output file $out\n";
+	$out = OUT;
+	$close_out = 1;
+    }
+    $out->autoflush(1);
+
+    # first compile a list of all the files we want to copy (we do it this
+    # way rather than simply copying the files as we recurse the directory
+    # structure to avoid nasty infinite recursion if the directory we're
+    # copying to happens to be a subdirectory of one of the directories
+    # we're copying from)
+    my $dirhash = {};
+    my $filehash = {};
+    &get_file_list($dirhash, $filehash, $collection, @ARGV);
+
+    # create all the required destination directories
+    my $count = 0;
+    foreach my $dir (keys %$dirhash) {
+	# check for .kill file
+	if (($count ++ % 20 == 0) &&
+	    (-e &util::filename_cat($collectdir, $collection, ".kill"))) {
+	    print $out "filecopy.pl killed by .kill file\n";
+	    die "\n";
+	}
+	&util::mk_all_dir($dir);
+    }
+
+    # copy all the files
+    foreach my $file (keys %$filehash) {
+	# check for .kill file
+	if (($count ++ % 20 == 0) &&
+	    (-e &util::filename_cat($collectdir, $collection, ".kill"))) {
+	    print $out "filecopy.pl killed by .kill file\n";
+	    die "\n";
+	}
+	print $out "copying $file --> $filehash->{$file}\n";
+	&util::cp($file, $filehash->{$file});
+    }
+
+    close OUT if $close_out;
+    return 0;
+}
+
+sub get_dst_dir {
+    my ($full_importname, $dir) = @_;
+
+    if ($ENV{'GSDLOS'} eq "windows") {
+	# don't want windows filenames like c:\gsdl\...\import\c:\dir
+	$dir =~ s/^[a-z]:[\\\/]//i;
+    }
+    return &util::filename_cat($full_importname, $dir);
+}
+
+&main();
Index: /gsdl/stable/bin/script/full-buildcol.pl
===================================================================
--- /gsdl/stable/bin/script/full-buildcol.pl	(revision 20131)
+++ /gsdl/stable/bin/script/full-buildcol.pl	(revision 20131)
@@ -0,0 +1,61 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# full-buildcol.pl -- runs buildcol.pl with -removeold option on
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2009 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will "buildcol" (or re-"buildcol") a collection from scratch
+# Runs:        buildcol.pl -removeold ...
+
+BEGIN {
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+}
+
+use strict;
+
+my $quoted_argv = join(" ", map { "\"$_\"" } @ARGV);
+
+
+my $buildcol_cmd = "buildcol.pl -removeold $quoted_argv";
+if($ENV{'GSDLOS'} =~ m/windows/) {
+    if($ENV{'PERLPATH'}) {
+	# need to ensure that the path to perl is quoted (in case there's spaces in it)
+	$buildcol_cmd = "\"$ENV{'PERLPATH'}\\Perl.exe\" -S $buildcol_cmd";
+    } else {
+	$buildcol_cmd = "perl -S $buildcol_cmd";
+    }
+}
+
+my $buildcol_status = system($buildcol_cmd)/256;
+
+if ($buildcol_status != 0) {
+    print STDERR "Error: Failed to run: $buildcol_cmd\n";
+    print STDERR "       $!\n" if ($! ne "");
+    exit(-1);
+}
+
+
+
+
Index: /gsdl/stable/bin/script/full-import.pl
===================================================================
--- /gsdl/stable/bin/script/full-import.pl	(revision 20131)
+++ /gsdl/stable/bin/script/full-import.pl	(revision 20131)
@@ -0,0 +1,60 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# full-import.pl -- runs import.pl with -removeold option on
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2009 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will import (or re-import) a collection from scratch
+# Runs:        import.pl -removeold ...
+
+
+BEGIN {
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+}
+
+use strict;
+
+my $quoted_argv = join(" ", map { "\"$_\"" } @ARGV);
+
+my $import_cmd = "import.pl -removeold $quoted_argv";
+if($ENV{'GSDLOS'} =~ m/windows/) {
+    if($ENV{'PERLPATH'}) {
+	# need to ensure that the path to perl is quoted (in case there's spaces in it)
+	$import_cmd = "\"$ENV{'PERLPATH'}\\Perl.exe\" -S $import_cmd";
+    } else {
+	$import_cmd = "perl -S $import_cmd";
+    }
+}
+
+my $import_status = system($import_cmd)/256;
+
+if ($import_status != 0) {
+    print STDERR "Error: Failed to run: $import_cmd\n";
+    print STDERR "       $!\n" if ($! ne "");
+    exit(-1);
+}
+
+
+
Index: /gsdl/stable/bin/script/full-rebuild.pl
===================================================================
--- /gsdl/stable/bin/script/full-rebuild.pl	(revision 20131)
+++ /gsdl/stable/bin/script/full-rebuild.pl	(revision 20131)
@@ -0,0 +1,164 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# full-rebuild.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2009 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will rebuild a collection from scratch
+# Runs:        full-import.pl -removeold ...
+# Followed by: full-buildcol.pl -removeold ...
+# (assumming import.pl did not end with an error)
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+
+use strict;
+
+use util;
+
+sub main
+{
+    my ($argc,@argv) = @_;
+
+    if (($argc==0)  || (($argc==1) && ($argv[0] =~ m/^--?h(elp)?$/))) {
+	my ($progname) = ($0 =~ m/^.*\/(.*?)$/);
+
+	print STDERR "\n";
+	print STDERR "Usage: $progname [option shared between import.pl and buildcol.pl] collection\n";
+	print STDERR "\n";
+
+	exit(-1);
+    }
+	
+
+    my $collect = pop @argv;
+
+
+    my @filtered_argv = ();
+
+    my $collect_dir = undef;
+    my $build_dir  = undef;
+
+    while (my $arg = shift @argv) {
+	if ($arg eq "-collectdir") {
+	    $collect_dir = shift @argv;
+	    push(@filtered_argv,$arg,$collect_dir);
+	}
+	elsif ($arg eq "-builddir") {
+	    $build_dir = shift @argv;
+	    push(@filtered_argv,$arg,$build_dir);
+	}
+	else {
+	    push(@filtered_argv,$arg);
+	}
+    }
+
+
+    if (!defined $collect_dir) {
+	$collect_dir = &util::filename_cat($ENV{'GSDLHOME'},"collect");
+    }
+    my $this_collect_dir = &util::filename_cat($collect_dir,$collect);
+
+    if (!-d $this_collect_dir) {
+	print STDERR "Error: $collect_dir does not exist\n";
+	exit(-1);
+    }
+
+
+    if (!defined $build_dir) {
+	$build_dir = &util::filename_cat($this_collect_dir,"building");
+	push(@filtered_argv,"-builddir",$build_dir);
+    }
+
+    
+    my $quoted_argv = join(" ", map { "\"$_\"" } @argv);
+    
+    my $final_status = 0;
+
+    my $launch_cmd = "";
+    if($ENV{'GSDLOS'} =~ m/windows/) {
+	if($ENV{'PERLPATH'}) {
+	    # need to ensure that the path to perl is quoted (in case there's spaces in it)
+	    $launch_cmd = "\"$ENV{'PERLPATH'}\\Perl.exe\" -S ";
+	} else {
+	    $launch_cmd = "perl -S ";
+	}
+    }
+    
+    print "\n";
+    print "************************\n";
+    print "* Running  Import  Stage\n";
+    print "************************\n";
+
+    my $import_cmd = $launch_cmd . "full-import.pl $quoted_argv \"$collect\"";
+
+    my $import_status = system($import_cmd)/256;
+    
+    if ($import_status == 0) {
+	print "\n";
+	print "************************\n";
+	print "* Running Buildcol Stage\n";
+	print "************************\n";
+	
+	my $buildcol_cmd = $launch_cmd . "full-buildcol.pl $quoted_argv \"$collect\"";
+	my $buildcol_status = system($buildcol_cmd)/256;
+	if ($buildcol_status == 0) {
+	    my $index_dir = &util::filename_cat($this_collect_dir,"index");
+	    
+	    if (-e $index_dir) {
+		print "\n";
+		print "************************\n";
+		print "* Removing \"index\"\n";
+		print "************************\n";
+		
+		&util::rm_r($index_dir);
+	    }
+
+	    print "\n";
+	    print "************************\n";
+	    print "* Moving \"building\" -> \"index\"\n";
+	    print "************************\n";
+
+	    &util::mv($build_dir,$index_dir);
+
+	}
+	else {
+	    $final_status = $buildcol_status;
+	}
+    }
+    else {
+	$final_status = $import_status;
+    }
+    
+    exit($final_status);
+}
+
+&main(scalar(@ARGV),@ARGV);
+
Index: /gsdl/stable/bin/script/g2f-buildcol.pl
===================================================================
--- /gsdl/stable/bin/script/g2f-buildcol.pl	(revision 20131)
+++ /gsdl/stable/bin/script/g2f-buildcol.pl	(revision 20131)
@@ -0,0 +1,238 @@
+#!/usr/bin/perl -w
+
+BEGIN 
+{
+    if (!defined $ENV{'GSDLHOME'}) {
+	print STDERR "Environment variable GSDLHOME not set.\n";
+	print STDERR "  Have you sourced Greenstone's 'setup.bash' file?\n";
+	exit 1;
+    }
+
+    if (!defined $ENV{'JAVA_HOME'}) {
+	print STDERR "Environment variable JAVA_HOME not set.\n";
+	print STDERR "Needed by Fedora command line scripts.\n";
+	exit 1;
+    }
+
+    $ENV{'FEDORA_HOSTNAME'} = "localhost" if (!defined $ENV{'FEDORA_HOSTNAME'});
+    $ENV{'FEDORA_SERVER_PORT'} = "8080" if (!defined $ENV{'FEDORA_SERVER_PORT'});
+    $ENV{'FEDORA_USER'}     = "fedoraAdmin" if (!defined $ENV{'FEDORA_USER'});
+    $ENV{'FEDORA_PASS'}     = "fedoraAdmin" if (!defined $ENV{'FEDORA_PASS'});
+    $ENV{'FEDORA_PROTOCOL'} = "http" if (!defined $ENV{'FEDORA_PROTOCOL'});
+    $ENV{'FEDORA_PID_NAMESPACE'} = "greenstone" if (!defined $ENV{'FEDORA_PID_NAMESPACE'});
+
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/");
+
+}
+
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and vice versa
+no strict 'subs'; # allow barewords (e.g. STDERR) as function arguments
+
+use util;
+use gsprintf 'gsprintf';
+use printusage;
+use parse2;
+
+use g2futil;
+
+
+my $arguments = 
+    [ 
+      { 'name' => "verbosity",
+	'desc' => "Level of verbosity generated",
+	'type' => "string",
+	'deft' => '1',
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "hostname",
+	'desc' => "Domain hostname of Fedora server",
+	'type' => "string",
+	'deft' => $ENV{'FEDORA_HOSTNAME'},
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "port",
+	'desc' => "Port that the Fedora server is running on.",
+	'type' => "string",
+	'deft' => $ENV{'FEDORA_SERVER_PORT'},
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "username",
+	'desc' => "Fedora admin username",
+	'type' => "string",
+	'deft' => $ENV{'FEDORA_USER'},
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "password",
+	'desc' => "Fedora admin password",
+	'type' => "string",
+	'deft' => $ENV{'FEDORA_PASS'},
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "protocol",
+	'desc' => "Fedora protocol, e.g. 'http' or 'https'",
+	'type' => "string",
+	'deft' => $ENV{'FEDORA_PROTOCOL'},
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "pidnamespace",
+	'desc' => "Fedora prefix for PIDs",
+	'type' => "string",
+	'deft' => $ENV{'FEDORA_PID_NAMESPACE'},
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "gli",
+	'desc' => "",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "xml",
+	'desc' => "{scripts.xml}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "removeold",
+	'desc' => "{import.removeold}",
+	'type' => "flag",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "collectdir",
+	'desc' => "{import.collectdir}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no",
+	'hiddengli' => "yes" }
+      ];
+
+my $prog_options 
+    = { 'name' => "g2fbuildcol.pl",
+	'desc' => "Ingest Greenstone directory of FedoraMETS documents into Fedora",
+	'args' => $arguments };
+
+
+sub main
+{
+    my (@ARGV) = @_;
+
+    my $GSDLHOME = $ENV{'GSDLHOME'};
+
+
+    my $options = {};
+    # general options available to all plugins
+    my $intArgLeftinAfterParsing = parse2::parse(\@ARGV,$arguments,$options,"allow_extra_options");
+
+    # Something went wrong with parsing
+    if ($intArgLeftinAfterParsing ==-1)
+    {
+	&PrintUsage::print_txt_usage($prog_options, "[options] greenstone-col");
+	die "\n";
+    }
+
+    my $xml = $options->{'xml'};
+    my $gli = $options->{'gli'};
+
+    if ($intArgLeftinAfterParsing != 1)
+    {
+	if ($xml) {
+	    &PrintUsage::print_xml_usage($prog_options);
+	    print "\n";
+	    return;
+	}
+	else {
+	    &PrintUsage::print_txt_usage($prog_options, "[options] greenstone-col");
+	    print "\n";
+	    return;
+	}
+	    
+    }
+
+    my $gs_col = $ARGV[0];
+
+    my $verbosity = $options->{'verbosity'};
+    my $hostname  = $options->{'hostname'};
+    my $port      = $options->{'port'};
+    my $username  = $options->{'username'};
+    my $password  = $options->{'password'};
+    my $protocol  = $options->{'protocol'};
+    my $pid_namespace = $options->{'pidnamespace'};
+
+    # The following are needed in the FedoraMETS plugout
+    $ENV{'FEDORA_HOSTNAME'} = $hostname;
+    $ENV{'FEDORA_SERVER_PORT'} = $port;
+
+    my $collectdir = $options->{'collectdir'};
+
+    if (!$collectdir) {
+	##    my $collect_dir = util::filename_cat($ENV{'GREENSTONE3_HOME'},
+	##					 "web","sites","localsite","collect");
+
+
+	$collectdir = util::filename_cat($ENV{'GSDLHOME'},"collect");
+    }
+
+    my $full_gs_col = util::filename_cat($collectdir,$gs_col);
+
+
+    if (!-e $full_gs_col ) {
+	print STDERR "Unable to find Greenstone collection $full_gs_col\n";
+	exit 1;
+    }
+
+##    my $archives_dir = &util::filename_cat($full_gs_col,"archives");
+    my $export_dir = &util::filename_cat($full_gs_col,"export");
+
+
+    print "***\n";
+    print "* Ingesting Greenstone processed files into Fedora $pid_namespace\n";
+    print "***\n";
+
+    # Following falls foul of Schematron rule checking
+    my $fd_add_prog = "fedora-ingest";
+#    my $fd_add_cmd;
+#    $fd_add_args  = "dir $export_dir O metslikefedora1 $hostname:$port $username $password \\\n";
+#    $fd_add_args .= "  \"Automated_ingest_by_gs2fed.pl\"";
+
+#    &g2futil::run_cmd($fd_add_prog,$fd_add_args,$options);
+
+
+    # => Ingest individually!
+
+    if (opendir(DIR, $export_dir)) {
+	closedir DIR;
+	## my @hash_dirs = grep { /\.dir$/ } readdir(DIR);
+	my @hash_dirs = &g2futil::get_all_hash_dirs($export_dir);
+
+
+	# for each hash dir, purge its respective PID
+	foreach my $hd (@hash_dirs) {
+
+	    my $docmets_filename 
+		= &util::filename_cat($hd,"docmets.xml");
+
+	    print STDERR "<Build>\n" if $gli;
+
+	    print "Ingesting $docmets_filename\n";
+
+	    &g2futil::run_ingest($docmets_filename,$options);
+	    print STDERR "</Build>\n" if $gli;
+
+	}	    
+    }
+    else {
+	print STDERR "Error: Unable to open directory $export_dir: $!\n";
+	exit;
+    }
+
+
+}
+
+&main(@ARGV);
+
+
+
Index: /gsdl/stable/bin/script/g2f-import.pl
===================================================================
--- /gsdl/stable/bin/script/g2f-import.pl	(revision 20131)
+++ /gsdl/stable/bin/script/g2f-import.pl	(revision 20131)
@@ -0,0 +1,263 @@
+#!/usr/bin/perl -w
+
+BEGIN 
+{
+    if (!defined $ENV{'GSDLHOME'}) {
+	print STDERR "Environment variable GSDLHOME not set.\n";
+	print STDERR "  Have you sourced Greenstone's 'setup.bash' file?\n";
+	exit 1;
+    }
+
+    $ENV{'FEDORA_HOSTNAME'} = "localhost" if (!defined $ENV{'FEDORA_HOSTNAME'});
+    $ENV{'FEDORA_SERVER_PORT'} = "8080" if (!defined $ENV{'FEDORA_SERVER_PORT'});
+    $ENV{'FEDORA_USER'}     = "fedoraAdmin" if (!defined $ENV{'FEDORA_USER'});
+    $ENV{'FEDORA_PASS'}     = "fedoraAdmin" if (!defined $ENV{'FEDORA_PASS'});
+    $ENV{'FEDORA_PROTOCOL'} = "http" if (!defined $ENV{'FEDORA_PROTOCOL'});
+    $ENV{'FEDORA_PID_NAMESPACE'} = "greenstone" if (!defined $ENV{'FEDORA_PID_NAMESPACE'});
+
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/");
+}
+
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and vice versa
+no strict 'subs'; # allow barewords (e.g. STDERR) as function arguments
+
+use util;
+use gsprintf 'gsprintf';
+use printusage;
+use parse2;
+
+
+use g2futil;
+
+
+my $arguments = 
+    [ 
+      { 'name' => "verbosity",
+	'desc' => "{import.verbosity}",
+	'type' => "string",
+	'deft' => '1',
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "hostname",
+	'desc' => "Domain hostname of Fedora server",
+	'type' => "string",
+	'deft' => $ENV{'FEDORA_HOSTNAME'},
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "port",
+	'desc' => "Port that the Fedora server is running on.",
+	'type' => "string",
+	'deft' => $ENV{'FEDORA_SERVER_PORT'},
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "username",
+	'desc' => "Fedora admin username",
+	'type' => "string",
+	'deft' => $ENV{'FEDORA_USER'},
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "password",
+	'desc' => "Fedora admin password",
+	'type' => "string",
+	'deft' => $ENV{'FEDORA_PASS'},
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "protocol",
+	'desc' => "Fedora protocol, e.g. 'http' or 'https'",
+	'type' => "string",
+	'deft' => $ENV{'FEDORA_PROTOCOL'},
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "pidnamespace",
+	'desc' => "Fedora prefix for PIDs",
+	'type' => "string",
+	'deft' => $ENV{'FEDORA_PID_NAMESPACE'},
+	'reqd' => "no",
+        'hiddengli' => "no" },
+      { 'name' => "maxdocs",
+	'desc' => "{import.maxdocs}",
+	'type' => "int",
+	'reqd' => "no",
+	'range' => "1,",
+	'modegli' => "1" },
+      { 'name' => "gli",
+	'desc' => "",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "xml",
+	'desc' => "{scripts.xml}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "removeold",
+	'desc' => "{import.removeold}",
+	'type' => "flag",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "collectdir",
+	'desc' => "{import.collectdir}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+
+
+      ];
+
+my $prog_options 
+    = { 'name' => "g2fimport.pl",
+	'desc' => "Generate Fedora METS format using Greenstone document processing capabilities",
+	'args' => $arguments };
+
+
+sub main
+{
+    my (@ARGV) = @_;
+
+    my $GSDLHOME = $ENV{'GSDLHOME'};
+
+
+    my $options = {};
+    # general options available to all plugins
+    my $intArgLeftinAfterParsing = parse2::parse(\@ARGV,$arguments,$options,"allow_extra_options");
+
+    # Something went wrong with parsing
+    if ($intArgLeftinAfterParsing ==-1)
+    {
+	&PrintUsage::print_txt_usage($prog_options, "[options] greenstone-col");
+	die "\n";
+    }
+
+    my $xml = $options->{'xml'};
+    my $gli = $options->{'gli'};
+
+    if ($intArgLeftinAfterParsing != 1)
+    {
+	if ($xml) {
+	    &PrintUsage::print_xml_usage($prog_options);
+	    print "\n";
+	    return;
+	}
+	else {
+	    &PrintUsage::print_txt_usage($prog_options, "[options] greenstone-col");
+	    print "\n";
+	    return;
+	}
+	    
+    }
+
+    if ($gli) { # the gli wants strings to be in UTF-8
+	&gsprintf::output_strings_in_UTF8; 
+    }
+
+    my $gs_col = $ARGV[0];
+
+    my $verbosity = $options->{'verbosity'};
+    my $hostname  = $options->{'hostname'}; 
+    my $port      = $options->{'port'};
+    my $username  = $options->{'username'};
+    my $password  = $options->{'password'};
+    my $protocol  = $options->{'protocol'};
+    my $pid_namespace = $options->{'pidnamespace'};
+
+    # The following are needed in the FedoraMETS plugout
+    $ENV{'FEDORA_HOSTNAME'} = $hostname;
+    $ENV{'FEDORA_SERVER_PORT'} = $port;
+
+    my $language   = $options->{'language'};
+    my $collectdir = $options->{'collectdir'};
+    my $removeold  = $options->{'removeold'};
+    my $maxdocs    = $options->{'maxdocs'};
+
+    if (!$collectdir) {
+	# Explicitly set one
+
+	##  $collectdir = util::filename_cat($ENV{'GREENSTONE3_HOME'},
+	##			 "web","sites","localsite","collect");
+
+	$collectdir = &util::filename_cat($ENV{'GSDLHOME'},"collect");
+
+    }
+
+    # method that will tell Fedora where the ultimate output of g2f-import and g2f-build
+    # will be found: Points Fedora to the collect directory where FedoraMETS will be output.
+    &g2futil::write_gsdl_xml_file($hostname, $collectdir, $options);
+
+    my $full_gs_col = &util::filename_cat($collectdir,$gs_col);
+
+    if (!-e $full_gs_col ) {
+	print STDERR "Unable to find Greenstone collection $full_gs_col\n";
+	exit 1;
+    }
+
+    my $export_dir = &util::filename_cat($full_gs_col,"export");
+
+    if ( -e $export_dir ) {
+        print "***\n";
+	print "* Updating existing Greenstone $gs_col objects from Fedora $pid_namespace\n";
+        print "***\n";
+
+	# readdir
+	if (opendir(DIR, $export_dir)) {
+
+	    closedir DIR;
+	    my @hash_dirs = &g2futil::get_all_hash_dirs($export_dir,$maxdocs);
+
+	    # for each hash dir, purge its respective PID
+	    foreach my $full_hd (@hash_dirs) {
+
+		my $hash_id = &g2futil::get_hash_id($full_hd);
+
+		next if !defined $hash_id;
+
+		my $pid = "$pid_namespace:$gs_col-$hash_id";
+
+		my $dsinfo_status = &g2futil::run_datastore_info($pid,$options);
+
+		if ($dsinfo_status == 0) {
+		    print "  $pid being updated.\n";	    
+		    &g2futil::run_purge($pid,$options);
+		}
+		else {
+		    print "  $pid not present.\n";
+		}
+	    }	    
+	}
+	else {
+	    print STDERR "Error: Unable to open directory $export_dir: $!\n";
+	    exit;
+	}
+    }
+
+    print "***\n";
+    print "* Processing $gs_col into FedoraMETS format\n";
+    print "***\n";
+
+    my $gs_export_opts = "-saveas FedoraMETS -fedora_namespace $pid_namespace -verbosity $verbosity";
+
+    $gs_export_opts .= " -gli" if ($gli);
+
+    $gs_export_opts .= " -language $language" if ($language);
+    $gs_export_opts .= " -collectdir \"$collectdir\"" if ($collectdir);
+    $gs_export_opts .= " -removeold" if ($removeold);
+    $gs_export_opts .= " -maxdocs $maxdocs" if ($maxdocs);
+
+    $gs_export_opts .= " -exportdir \"$export_dir\"";
+
+    my $gs_export_arguments = "$gs_export_opts $gs_col";
+
+    &g2futil::run_cmd("export.pl", $gs_export_arguments, $options);
+}
+
+&main(@ARGV);
+
+
+
Index: /gsdl/stable/bin/script/getdocument.pl
===================================================================
--- /gsdl/stable/bin/script/getdocument.pl	(revision 20131)
+++ /gsdl/stable/bin/script/getdocument.pl	(revision 20131)
@@ -0,0 +1,32 @@
+#!/usr/bin/perl -w
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/bin/script");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+    unshift (@INC, "$ENV{'GSDLHOME'}/collect/lld/perllib");
+}
+
+use util;
+
+use IncrementalBuild; # Include John's incremental building API
+
+# Ensure the collection specific binaries are on the search path
+my $path_separator = ":";
+$ENV{'PATH'} = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}) .
+$path_separator . &util::filename_cat($ENV{'GSDLHOME'}, "bin", "script") .
+$path_separator . $ENV{'PATH'};
+
+if(!$ARGV[0] || !$ARGV[1]) {
+  print STDERR "Usage: getdocument <collection> <oid>\n";
+  exit;
+}
+
+my $collection = $ARGV[0];
+my $oid = $ARGV[1];
+
+&IncrementalBuild::getDocumentAsXML($collection, $oid);
+
+exit;
Index: /gsdl/stable/bin/script/gimp/flash_button-1.2.pl
===================================================================
--- /gsdl/stable/bin/script/gimp/flash_button-1.2.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gimp/flash_button-1.2.pl	(revision 20131)
@@ -0,0 +1,382 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# flash_button.pl 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# Modified by Rachid Ben Kaddour <qben@oce.nl> for gimp1.2
+
+# flash_button.pl generates all the flashy javascript type
+# buttons used by Greenstone
+# these are the buttons described in macro files as:
+# top_nav_button
+# nav_bar_button
+# document_button
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use Gimp qw/:auto :DEFAULT/;
+use parsargv;
+use util;
+
+# set trace level to watch functions as they are executed
+#Gimp::set_trace(TRACE_ALL);
+#Gimp::set_trace(TRACE_CALL);
+
+my $gsdl_yellow = "#D2B464";
+my $black = "#000000";
+
+my ($cfg_file, $width, $height, $text, $filenamestem, $fixed_width,
+    $width_space, $whitespace, $dont_center, $bgcolor, $fontcolor, 
+    $fontsize, $fontfoundry, $fontname, $fontweight, $fontslant, $fontwidth, 
+    $fontspacing, $fontregistry, $fontencoding, $image_dir);
+
+sub print_usage {
+    print STDERR "\n  usage: $0 [options]\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -cfg_file file        configuration file containing one or more\n";
+    print STDERR "                         sets of the following options - use to create\n";
+    print STDERR "                         batches of images\n";
+    print STDERR "   -image_dir directory  directory to create images in [`pwd`]\n";
+    print STDERR "                         this should be full path to existing directory\n";
+    print STDERR "   -width number         width of button [65]\n";
+    print STDERR "   -height number        height of button [30]\n";
+    print STDERR "   -text string          button text\n";
+    print STDERR "   -filenamestem string  filename - two images will be produced -\n";
+    print STDERR "                         filenamestemon.gif and filenamestemof.gif\n";
+    print STDERR "   -fixed_width          fix width of image - if this isn't set\n";
+    print STDERR "                         image will be cropped with with width_space\n";
+    print STDERR "                         space at each side of text\n";
+    print STDERR "   -width_space number   width in pixels of blank space to leave at left\n";
+    print STDERR "                         and right edges of text [1]\n";
+    print STDERR "   -whitespace           add 1 pixel of white space at left and right edges\n";
+    print STDERR "                         of image\n";
+    print STDERR "   -dont_center          don't center text horizontally (only applicable if\n";
+    print STDERR "                         image is fixed width\n";
+    print STDERR "   -bgcolor hex_value    background color of button [$gsdl_yellow]\n";
+    print STDERR "   -fontcolor hex_value  text color [$black]\n";
+    print STDERR "   -fontsize number      font point size [10]\n";
+    print STDERR "   -foundry string       [*]\n";
+    print STDERR "   -fontname string      [lucida]\n";
+    print STDERR "   -fontweight string    [medium]\n";
+    print STDERR "   -fontslant            [r]\n";
+    print STDERR "   -fontwidth            [*]\n";
+    print STDERR "   -fontspacing          [*]\n\n";
+    print STDERR "   -fontregistry         [*]\n\n";
+    print STDERR "   -fontencoding         [*]\n\n";
+}
+
+sub reset_options {
+    $image_dir = "./";
+    $width = 65;
+    $height = 30;
+    $text = "";
+    $filenamestem = "";
+    $fixed_width = 0;
+    $width_space = 1;
+    $whitespace = 0;
+    $dont_center = 0;
+    $bgcolor = $gsdl_yellow;
+    $fontcolor = $black;
+    $fontsize = 10;
+    $fontfoundry = "*";
+    $fontname = "lucida";
+    $fontweight = "medium";
+    $fontslant = "r";
+    $fontwidth = "*";
+    $fontspacing = "*";
+    $fontregistry = "*";
+    $fontencoding = "*";
+}
+
+sub gsdl_flash_button {
+
+    if (!parsargv::parse(\@ARGV, 
+			 'cfg_file/.*/', \$cfg_file,
+			 'image_dir/.*/./', \$image_dir,
+			 'width/^\d+$/65', \$width,
+			 'height/^\d+$/30', \$height,
+			 'text/.*/', \$text,
+			 'filenamestem/.*', \$filenamestem,
+			 'fixed_width', \$fixed_width,
+			 'width_space/^\d+$/1', \$width_space,
+			 'whitespace', \$whitespace,
+			 'dont_center', \$dont_center,
+			 "bgcolor/#[0-9A-Fa-f]{6}/$gsdl_yellow", \$bgcolor,
+			 "fontcolor/#[0-9A-Fa-f]{6}/$black", \$fontcolor,
+			 'fontsize/^\d+$/10', \$fontsize,
+			 'foundry/.*/*', \$fontfoundry,
+			 'fontname/.*/lucida', \$fontname,
+			 'fontweight/.*/medium', \$fontweight,
+			 'fontslant/.*/r', \$fontslant,
+			 'fontwidth/.*/*', \$fontwidth,
+			 'fontspacing/.*/*', \$fontspacing,
+			 'fontregistry/.*/*', \$fontregistry,
+			 'fontencoding/.*/*', \$fontencoding)) {
+	&print_usage();
+	die "flash_button.pl: incorrect options\n";
+    }
+
+    # will create wherever gimp was started up from if we don't do this
+    if ($image_dir eq "./") {
+	$image_dir = `pwd`;
+	chomp $image_dir;
+    }
+
+    # replace any '\n' occurring in text with carriage return
+    $text =~ s/\\n/\n/gi;
+    
+    if ($cfg_file =~ /\w/) {
+	
+	open (CONF, $cfg_file) || die "couldn't open cfg_file $cfg_file\n";
+	while (1) {
+
+	    &reset_options ();
+	
+	    # read image configuration entry
+	    my $status = &read_config_entry (CONF);
+	    if ($filenamestem !~ /\w/) {
+		if ($status) {last;}
+		else {next;}
+	    }
+
+	    &produce_images (0);
+	    if ($status) {last;}
+	}
+
+	close CONF;
+
+    } else {
+
+	&produce_images (0);
+
+    }
+}
+
+sub produce_images {
+    my ($off_img) = @_;
+    
+    # create image, set background color etc.
+    my ($image, $backlayer) = &create_image ($off_img);
+    
+    # set the text if there is any
+    if (length($text)) {
+
+	my $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1, 
+				   $fontsize, PIXELS, $fontfoundry, $fontname, $fontweight, 
+				   $fontslant, $fontwidth, $fontspacing, $fontregistry, $fontencoding);
+
+	my $textwidth = gimp_drawable_width($textlayer);
+	my $textheight = gimp_drawable_height($textlayer);
+
+	# check that text fits within image
+	if ($textheight > $height) {
+	    die "'$text' at fontsize of $fontsize pixels does not fit within image\n" . 
+		"$height pixels high. Decrease fontsize or increase image height\n";
+	}
+
+	my $spacers = $width_space * 2;
+	$spacers += 2 if $whitespace;
+
+	if (!$fixed_width || $textwidth > $width) {
+
+	    if ($fixed_width) {
+		print STDERR "WARNING (flash_button.pl): '$text' does not fit within $width pixel fixed width ";
+		print STDERR "image. Image width was increased to ",$textwidth + $spacers, " pixels\n";
+	    }
+	    
+	    $width = $textwidth + $spacers;
+
+	    # recreate image in new size
+	    ($image, $backlayer) = &create_image ($off_img);
+	    $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1, 
+				    $fontsize, PIXELS, $fontfoundry, $fontname, $fontweight, 
+				    $fontslant, $fontwidth, $fontspacing, $fontregistry, $fontencoding);
+	    
+	}
+
+	my $y_offset = ($height-$textheight)-int($fontsize/5);
+	my $halfdescenders = "";
+
+	# Russian half descenders (KOI8-R)
+	# -- Uncomment if generating Russian images using KOI8-R encoded text --
+	# $halfdescenders .= chr(195) . chr(253);  # Checked
+	# $halfdescenders .= chr(196) . chr(198) . chr(221) . chr(227) . chr(228); # Unchecked
+
+	# Kazakh (and Russian) half descenders (Helvetica Kazakh font)
+	# -- Uncomment if generating Kazakh or Russian images using text encoded to match
+	#      a Kazakh Helvetica font:
+        #        http://www.unesco.kz/ci/projects/greenstone/kazakh_fonts/helv_k.ttf
+	#    Mapping for this encoding is: mapping/from_uc/kazakh.ump --
+	# $halfdescenders .= chr(178) . chr(179) . chr(187);             # Kazakh specific
+	# $halfdescenders .= chr(196) . chr(214) . chr(217) . chr(228);  # Generic Russian
+	# $halfdescenders .= chr(244) . chr(246) . chr(249);
+
+	# -- Uncomment if generating images using a font with half descenders --
+	# if ($text =~ /[$halfdescenders]/) {
+	    # half descenders - put text at fontsize/10 pixels above bottom
+	    # $y_offset = ($height-$textheight)-int($fontsize/10);
+	# }
+
+	my $descenders = "";
+
+	# Russian descenders (KOI8-R)
+	# -- Uncomment if generating Russian images using KOI8-R encoded text --
+	# $descenders .= chr(210) . chr(213);
+
+	# Kazakh (and Russian) descenders (Helvetica Kazakh font)
+	# -- Uncomment if generating Kazakh or Russian images using text encoded to match
+	#      a Kazakh Helvetica font:
+        #        http://www.unesco.kz/ci/projects/greenstone/kazakh_fonts/helv_k.ttf
+	#    Mapping for this encoding is: mapping/from_uc/kazakh.ump --
+	# $descenders .= chr(189) . chr(190);  # Kazakh specific
+	# $descenders .= chr(240) . chr(243);  # Generic Russian
+
+	if ($text =~ /[gjpqyJ$descenders]/) { ## capital J is a descender in lucida font
+	    # descenders - put text at bottom of image, otherwise 
+	    # go for fontsize/5 pixels above bottom. This is kind of hacky 
+	    # and may need some playing with for different fonts/fontsizes
+	    $y_offset = $height-$textheight;
+	}
+
+	if ($fixed_width) {
+	    if ($dont_center) {
+		# don't center text horizontally (start it width_space pixels from left edge)
+		my $x_offset = $width_space;
+		$x_offset += 1 if $whitespace;
+		gimp_layer_set_offsets ($textlayer, $x_offset, $y_offset);
+	    } else {
+		gimp_layer_set_offsets ($textlayer, ($width-$textwidth)/2, $y_offset);
+	    }
+	} else {
+	    gimp_layer_set_offsets ($textlayer, $spacers / 2, $y_offset); 
+	}
+    }
+    
+    # add pixel of whitespace to each edge if required
+    if ($whitespace) {
+	gimp_rect_select ($image, 0, 0, 1, $height, 0, 0, 0);
+	gimp_edit_clear ($backlayer);
+	gimp_selection_none ($image);
+	gimp_rect_select ($image, $width-1, 0, 1, $height, 0, 0, 0);
+	gimp_edit_clear ($backlayer);
+	gimp_selection_none ($image);
+    }
+    
+    # flatten the image
+    my $finishedlayer = gimp_image_flatten ($image);
+    
+    # make indexed colour 
+    gimp_convert_indexed ($image, NO_DITHER, MAKE_PALETTE, 256, 0, 1,"");
+    
+    # save image
+    my $filename = $filenamestem . "on.gif";
+    $filename = $filenamestem . "of.gif" if $off_img;
+    $filename = &util::filename_cat ($image_dir, $filename);
+
+    gimp_file_save (RUN_NONINTERACTIVE, $image, $finishedlayer, $filename, $filename);
+
+    &produce_images (1) unless $off_img;    
+}
+
+sub create_image {
+    my ($off_img) = @_;
+
+    # create the image
+    my $image = gimp_image_new ($width, $height, RGB_IMAGE);
+    
+    # background layer
+    my $backlayer = gimp_layer_new ($image, $width, $height, RGB_IMAGE, 
+				    "BGLayer", 100, NORMAL_MODE);
+    
+    # add the background layer
+    gimp_image_add_layer ($image, $backlayer, 0);
+    
+    # set colour of background
+    gimp_palette_set_foreground ($bgcolor);
+    
+    # clear the background
+    gimp_selection_all ($image);
+    gimp_edit_clear ($backlayer);
+    gimp_selection_none ($image);
+    
+    # create the gradient background
+    gimp_blend ($backlayer, 0, NORMAL_MODE, LINEAR, 70, 0, REPEAT_NONE, 0, 0, 0, 5, $height-3, 5, 0);
+    
+    # adjust lightness of "off" gif
+    gimp_hue_saturation ($backlayer, 0, 0, 100, 0) if $off_img;
+
+    # set colour of text
+    gimp_palette_set_foreground ($fontcolor);
+
+    return ($image, $backlayer);
+}
+
+# returns 1 if this is the last entry,
+sub read_config_entry {
+    my ($handle) = @_;
+
+    my $line = "";
+    while (defined ($line = <$handle>)) {
+	next unless $line =~ /\w/;
+	my @line = ();
+	if ($line =~ /^\-+/) {return 0;}
+	$line =~ s/^\#.*$//;   # remove comments
+	$line =~ s/\cM|\cJ//g; # remove end-of-line characters
+	$line =~ s/^\s+//;     # remove initial white space
+	while ($line =~ s/\s*(\"[^\"]*\"|\'[^\']*\'|\S+)\s*//) {
+	    if (defined $1) {
+		# remove any enclosing quotes
+		my $entry = $1;
+		$entry =~ s/^([\"\'])(.*)\1$/$2/;
+
+		# substitute any environment variables
+		$entry =~ s/\$(\w+)/$ENV{$1}/g;
+		$entry =~ s/\$\{(\w+)\}/$ENV{$1}/g;
+		
+		push (@line, $entry);
+	    } else {
+		push (@line, "");
+	    }
+	}
+	if (scalar (@line) == 2 && defined ${$line[0]}) {
+	    ${$line[0]} = $line[1];
+	}
+    }
+    return 1;
+}
+    
+sub query {
+
+  gimp_install_procedure("gsdl_flash_button", "create flashy javascript buttons for gsdl",
+                        "", "Stefan Boddie", "Stefan Boddie", "2000-03-10",
+                        "<Toolbox>/Xtns/gsdl_flash_button", "*", &PROC_EXTENSION,
+                        [[PARAM_INT32, "run_mode", "Interactive, [non-interactive]"]], []);
+}
+
+Gimp::on_net { gsdl_flash_button; };
+exit main;
Index: /gsdl/stable/bin/script/gimp/flash_button.pl
===================================================================
--- /gsdl/stable/bin/script/gimp/flash_button.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gimp/flash_button.pl	(revision 20131)
@@ -0,0 +1,351 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# flash_button.pl 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# flash_button.pl generates all the flashy javascript type
+# buttons used by Greenstone
+# these are the buttons described in macro files as:
+# top_nav_button
+# nav_bar_button
+# document_button
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use Gimp;
+use parsargv;
+use util;
+use unicode;
+
+
+# set trace level to watch functions as they are executed
+#Gimp::set_trace(TRACE_ALL);
+#Gimp::set_trace(TRACE_CALL);
+
+my $gsdl_yellow = "#D2B464";
+my $black = "#000000";
+
+my ($cfg_file, $width, $height, $text, $filenamestem, $fixed_width,
+    $width_space, $whitespace, $dont_center, $bgcolor, $fontcolor, 
+    $fontsize, $foundry, $fontname, $fontweight, $fontslant, $fontwidth, 
+    $fontspacing, $image_dir);
+
+sub print_usage {
+    print STDERR "\n  usage: $0 [options]\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -cfg_file file        configuration file containing one or more\n";
+    print STDERR "                         sets of the following options - use to create\n";
+    print STDERR "                         batches of images\n";
+    print STDERR "   -image_dir directory  directory to create images in [`pwd`]\n";
+    print STDERR "                         this should be full path to existing directory\n";
+    print STDERR "   -width number         width of button [65]\n";
+    print STDERR "   -height number        height of button [30]\n";
+    print STDERR "   -text string          button text\n";
+    print STDERR "   -filenamestem string  filename - two images will be produced -\n";
+    print STDERR "                         filenamestemon.gif and filenamestemof.gif\n";
+    print STDERR "   -fixed_width          fix width of image - if this isn't set\n";
+    print STDERR "                         image will be cropped with with width_space\n";
+    print STDERR "                         space at each side of text\n";
+    print STDERR "   -width_space number   width in pixels of blank space to leave at left\n";
+    print STDERR "                         and right edges of text [1]\n";
+    print STDERR "   -whitespace           add 1 pixel of white space at left and right edges\n";
+    print STDERR "                         of image\n";
+    print STDERR "   -dont_center          don't center text horizontally (only applicable if\n";
+    print STDERR "                         image is fixed width\n";
+    print STDERR "   -bgcolor hex_value    background color of button [$gsdl_yellow]\n";
+    print STDERR "   -fontcolor hex_value  text color [$black]\n";
+    print STDERR "   -fontsize number      font point size [10]\n";
+    print STDERR "   -foundry string       [*]\n";
+    print STDERR "   -fontname string      [lucida]\n";
+    print STDERR "   -fontweight string    [medium]\n";
+    print STDERR "   -fontslant            [r]\n";
+    print STDERR "   -fontwidth            [*]\n";
+    print STDERR "   -fontspacing          [*]\n\n";
+}
+
+sub reset_options {
+    $image_dir = "./";
+    $width = 65;
+    $height = 30;
+    $text = "";
+    $filenamestem = "";
+    $fixed_width = 0;
+    $width_space = 1;
+    $whitespace = 0;
+    $dont_center = 0;
+    $bgcolor = $gsdl_yellow;
+    $fontcolor = $black;
+    $fontsize = 10;
+    $foundry = "*";
+    $fontname = "lucida";
+    $fontweight = "medium";
+    $fontslant = "r";
+    $fontwidth = "*";
+    $fontspacing = "*";
+}
+
+sub gsdl_flash_button {
+
+    if (!parsargv::parse(\@ARGV, 
+			 'cfg_file/.*/', \$cfg_file,
+			 'image_dir/.*/./', \$image_dir,
+			 'width/^\d+$/65', \$width,
+			 'height/^\d+$/30', \$height,
+			 'text/.*/', \$text,
+			 'filenamestem/.*', \$filenamestem,
+			 'fixed_width', \$fixed_width,
+			 'width_space/^\d+$/1', \$width_space,
+			 'whitespace', \$whitespace,
+			 'dont_center', \$dont_center,
+			 "bgcolor/#[0-9A-Fa-f]{6}/$gsdl_yellow", \$bgcolor,
+			 "fontcolor/#[0-9A-Fa-f]{6}/$black", \$fontcolor,
+			 'fontsize/^\d+$/10', \$fontsize,
+			 'foundry/.*/*', \$foundry,
+			 'fontname/.*/lucida', \$fontname,
+			 'fontweight/.*/medium', \$fontweight,
+			 'fontslant/.*/r', \$fontslant,
+			 'fontwidth/.*/*', \$fontwidth,
+			 'fontspacing/.*/*', \$fontspacing)) {
+	&print_usage();
+	die "flash_button.pl: incorrect options\n";
+    }
+
+    # will create wherever gimp was started up from if we don't do this
+    if ($image_dir eq "./") {
+	$image_dir = `pwd`;
+	chomp $image_dir;
+    }
+
+    # replace any '\n' occurring in text with carriage return
+    $text =~ s/\\n/\n/gi;
+
+    if ($cfg_file =~ /\w/) {
+	
+	open (CONF, $cfg_file) || die "couldn't open cfg_file $cfg_file\n";
+	while (1) {
+
+	    &reset_options ();
+	
+	    # read image configuration entry
+	    my $status = &read_config_entry (CONF);
+	    if ($filenamestem !~ /\w/) {
+		if ($status) {last;}
+		else {next;}
+	    }
+
+	    &produce_images (0);
+	    if ($status) {last;}
+	}
+
+	close CONF;
+
+    } else {
+
+	&produce_images (0);
+
+    }
+}
+
+sub produce_images {
+    my ($off_img) = @_;
+    
+    # create image, set background color etc.
+    my ($image, $backlayer) = &create_image ($off_img);
+    
+    # set the text if there is any
+    if (length($text)) {
+
+	my $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1, 
+				   $fontsize, PIXELS, $foundry, $fontname, $fontweight, 
+				   $fontslant, $fontwidth, $fontspacing);
+	
+
+	my $textwidth = gimp_drawable_width($textlayer);
+	my $textheight = gimp_drawable_height($textlayer);
+
+	# check that text fits within image
+	if ($textheight > $height) {
+	    die "'$text' at fontsize of $fontsize pixels does not fit within image\n" . 
+		"$height pixels high. Decrease fontsize or increase image height\n";
+	}
+
+	my $spacers = $width_space * 2;
+	$spacers += 2 if $whitespace;
+
+	if (!$fixed_width || $textwidth > $width) {
+
+	    if ($fixed_width) {
+		print STDERR "WARNING (flash_button.pl): '$text' does not fit within $width pixel fixed width ";
+		print STDERR "image. Image width was increased to ",$textwidth + $spacers, " pixels\n";
+	    }
+	    
+	    $width = $textwidth + $spacers;
+
+	    # recreate image in new size
+	    ($image, $backlayer) = &create_image ($off_img);
+	    $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1, 
+				    $fontsize, PIXELS, $foundry, $fontname, $fontweight, 
+				    $fontslant, $fontwidth, $fontspacing);
+	    
+	}
+
+	my $y_offset = ($height-$textheight)-int($fontsize/5);
+
+	my $descenders = "";
+
+	# russian descenders (KOI8-R)
+	# $descenders .= chr(0xD2);
+	# $descenders .= chr(0xD5);
+
+	if ($text =~ /[gjpqyJ$descenders]/) { ## capital J is a descender in lucida font
+	    # descenders - put text at bottom of image, otherwise 
+	    # go for fontsize/5 pixels above bottom. This is kind of hacky 
+	    # and may need some playing with for different fonts/fontsizes
+	    $y_offset = $height-$textheight;
+	}
+
+	if ($fixed_width) {
+	    if ($dont_center) {
+		# don't center text horizontally (start it width_space pixels from left edge)
+		my $x_offset = $width_space;
+		$x_offset += 1 if $whitespace;
+		gimp_layer_set_offsets ($textlayer, $x_offset, $y_offset);
+	    } else {
+		gimp_layer_set_offsets ($textlayer, ($width-$textwidth)/2, $y_offset);
+	    }
+	} else {
+	    gimp_layer_set_offsets ($textlayer, $spacers / 2, $y_offset); 
+	}
+    }
+    
+    # add pixel of whitespace to each edge if required
+    if ($whitespace) {
+	gimp_rect_select ($image, 0, 0, 1, $height, 0, 0, 0);
+	gimp_edit_clear ($image, $backlayer);
+	gimp_selection_none ($image);
+	gimp_rect_select ($image, $width-1, 0, 1, $height, 0, 0, 0);
+	gimp_edit_clear ($image, $backlayer);
+	gimp_selection_none ($image);
+    }
+    
+    # flatten the image
+    my $finishedlayer = gimp_image_flatten ($image);
+    
+    # make indexed colour 
+    gimp_convert_indexed ($image, 0, 256);
+    
+    # save image
+    my $filename = $filenamestem . "on.gif";
+    $filename = $filenamestem . "of.gif" if $off_img;
+    $filename = &util::filename_cat ($image_dir, $filename);
+
+    gimp_file_save (RUN_NONINTERACTIVE, $image, $finishedlayer, $filename, $filename);
+
+    &produce_images (1) unless $off_img;    
+}
+
+sub create_image {
+    my ($off_img) = @_;
+
+    # create the image
+    my $image = gimp_image_new ($width, $height, RGB_IMAGE);
+    
+    # background layer
+    my $backlayer = gimp_layer_new ($image, $width, $height, RGB_IMAGE, 
+				    "BGLayer", 100, NORMAL_MODE);
+    
+    # add the background layer
+    gimp_image_add_layer ($image, $backlayer, 0);
+    
+    # set colour of background
+    gimp_palette_set_foreground ($bgcolor);
+    
+    # clear the background
+    gimp_selection_all ($image);
+    gimp_edit_clear ($image, $backlayer);
+    gimp_selection_none ($image);
+    
+    # create the gradient background
+    gimp_blend ($image, $backlayer, 0, NORMAL_MODE, LINEAR, 70, 0, REPEAT_NONE, 0, 0, 0, 5, $height-3, 5, 0);
+    
+    # adjust lightness of "off" gif
+    gimp_hue_saturation ($image, $backlayer, 0, 0, 100, 0) if $off_img;
+
+    # set colour of text
+    gimp_palette_set_foreground ($fontcolor);
+
+    return ($image, $backlayer);
+}
+
+# returns 1 if this is the last entry,
+sub read_config_entry {
+    my ($handle) = @_;
+
+    my $line = "";
+    while (defined ($line = <$handle>)) {
+	next unless $line =~ /\w/;
+	my @line = ();
+	if ($line =~ /^\-+/) {return 0;}
+	$line =~ s/^\#.*$//;   # remove comments
+	$line =~ s/\cM|\cJ//g; # remove end-of-line characters
+	$line =~ s/^\s+//;     # remove initial white space
+	while ($line =~ s/\s*(\"[^\"]*\"|\'[^\']*\'|\S+)\s*//) {
+	    if (defined $1) {
+		# remove any enclosing quotes
+		my $entry = $1;
+		$entry =~ s/^([\"\'])(.*)\1$/$2/;
+
+		# substitute any environment variables
+		$entry =~ s/\$(\w+)/$ENV{$1}/g;
+		$entry =~ s/\$\{(\w+)\}/$ENV{$1}/g;
+		
+		push (@line, $entry);
+	    } else {
+		push (@line, "");
+	    }
+	}
+	if (scalar (@line) == 2 && defined ${$line[0]}) {
+	    ${$line[0]} = $line[1];
+	}
+    }
+    return 1;
+}
+    
+sub query {
+
+  gimp_install_procedure("gsdl_flash_button", "create flashy javascript buttons for gsdl",
+                        "", "Stefan Boddie", "Stefan Boddie", "2000-03-10",
+                        "<Toolbox>/Xtns/gsdl_flash_button", "*", &PROC_EXTENSION,
+                        [[PARAM_INT32, "run_mode", "Interactive, [non-interactive]"]], []);
+}
+
+sub net {
+  gsdl_flash_button;
+}
+
+exit main;
Index: /gsdl/stable/bin/script/gimp/green_bar-1.2.pl
===================================================================
--- /gsdl/stable/bin/script/gimp/green_bar-1.2.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gimp/green_bar-1.2.pl	(revision 20131)
@@ -0,0 +1,342 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# green_bar.pl 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# Modified by Rachid Ben Kaddour <qben@oce.nl> for gimp1.2
+
+# green_bar.pl generates all the black on green gradient background
+# images used by Greenstone. 
+# these are the icons described in macro files as:
+# green version of nav_bar_button
+# green_bar_left_aligned
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use Gimp qw/:auto :DEFAULT/;
+use parsargv;
+use util;
+use unicode;
+
+# set trace level to watch functions as they are executed
+#Gimp::set_trace(TRACE_ALL);
+#Gimp::set_trace(TRACE_CALL);
+
+my $gsdl_green = "#96c19b";
+my $black = "#000000";
+
+my ($cfg_file, $width, $height, $text, $filename, $width_space, 
+    $dont_center, $bgcolor, $fontcolor, $fontsize, $foundry, $fontname, 
+    $fontweight, $fontslant, $fontwidth, $fontspacing, $fontregistry, $fontencoding, $image_dir);
+
+sub print_usage {
+    print STDERR "\n  usage: $0 [options] macrofile\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -cfg_file file        configuration file containing one or more\n";
+    print STDERR "                         sets of the following options - use to create\n";
+    print STDERR "                         batches of images\n";
+    print STDERR "   -image_dir directory  directory to create images in [`pwd`]\n";
+    print STDERR "                         this should be full path to existing directory\n";
+    print STDERR "   -width number         width of bar [87]\n";
+    print STDERR "   -height number        height of bar [17]\n";
+    print STDERR "   -text string          icon text\n";
+    print STDERR "   -filename string      filename of resulting image\n";
+    print STDERR "   -width_space number   width in pixels of blank space to leave at left\n";
+    print STDERR "                         and right edges of text [1]\n";
+    print STDERR "   -dont_center          don't center text horizontally\n";
+    print STDERR "   -bgcolor hex_value    background color of bar [$gsdl_green]\n";
+    print STDERR "   -fontcolor hex_value  text color [$black]\n";
+    print STDERR "   -fontsize number      font point size [17]\n";
+    print STDERR "   -foundry string       [*]\n";
+    print STDERR "   -fontname string      [lucida]\n";
+    print STDERR "   -fontweight string    [medium]\n";
+    print STDERR "   -fontslant            [r]\n";
+    print STDERR "   -fontwidth            [*]\n";
+    print STDERR "   -fontspacing          [*]\n";
+    print STDERR "   -fontregistry         [*]\n";
+    print STDERR "   -fontencoding         [*]\n\n";
+}
+
+sub reset_options {
+    $image_dir = "./";
+    $width = 87;
+    $height = 17;
+    $text = "";
+    $filename = "";
+    $width_space = 1;
+    $dont_center = 0;
+    $bgcolor = $gsdl_green;
+    $fontcolor = $black;
+    $fontsize = 17;
+    $foundry = "*";
+    $fontname = "lucida";
+    $fontweight = "medium";
+    $fontslant = "r";
+    $fontwidth = "*";
+    $fontspacing = "*";
+    $fontregistry = "*";
+    $fontencoding = "*";
+}
+
+sub gsdl_green_bar {
+
+    if (!parsargv::parse(\@ARGV, 
+			 'cfg_file/.*/', \$cfg_file,
+			 'image_dir/.*/./', \$image_dir,
+			 'width/^\d+$/87', \$width,
+			 'height/^\d+$/17', \$height,
+			 'text/.*/', \$text,
+			 'filename/.*', \$filename,
+			 'width_space/^\d+$/1', \$width_space,
+			 'dont_center', \$dont_center,
+			 "bgcolor/#[0-9A-Fa-f]{6}/$gsdl_green", \$bgcolor,
+			 "fontcolor/#[0-9A-Fa-f]{6}/$black", \$fontcolor,
+			 'fontsize/^\d+$/17', \$fontsize,
+			 'foundry/.*/*', \$foundry,
+			 'fontname/.*/lucida', \$fontname,
+			 'fontweight/.*/medium', \$fontweight,
+			 'fontslant/.*/r', \$fontslant,
+			 'fontwidth/.*/*', \$fontwidth,
+			 'fontregistry/.*/*', \$fontregistry,
+			 'fontencoding/.*/*', \$fontencoding,
+			 'fontspacing/.*/*', \$fontspacing)) {
+	&print_usage();
+	die "green_bar.pl: incorrect options\n";
+    }
+
+    # will create wherever gimp was started up from if we don't do this
+    if ($image_dir eq "./") {
+	$image_dir = `pwd`;
+	chomp $image_dir;
+    }
+    
+    if ($cfg_file =~ /\w/) {
+	
+	open (CONF, $cfg_file) || die "couldn't open cfg_file $cfg_file\n";
+	while (1) {
+
+	    &reset_options ();
+	
+	    # read image configuration entry
+	    my $status = &read_config_entry (CONF);
+	    if ($filename !~ /\w/) {
+		if ($status) {last;}
+		else {next;}
+	    }
+
+	    &produce_image ();
+	    if ($status) {last;}
+	}
+
+	close CONF;
+
+    } else {
+
+	&produce_image ();
+
+    }
+}
+
+sub produce_image {
+    
+    # create image, set background color etc.
+    my ($image, $backlayer) = &create_image ();
+    
+    # set the text if there is any
+    if (length($text)) {
+
+	my $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1, 
+				   $fontsize, PIXELS, $foundry, $fontname, $fontweight, 
+				   $fontslant, $fontwidth, $fontspacing, $fontregistry, $fontencoding);
+	
+
+	my $textwidth = gimp_drawable_width($textlayer);
+	my $textheight = gimp_drawable_height($textlayer);
+
+	# check that text fits within image
+	if ($textheight > $height) {
+	    die "'$text' at fontsize of $fontsize pixels does not fit within image\n" . 
+		"$height pixels high. Decrease fontsize or increase image height\n";
+	}
+
+	my $spacers = $width_space * 2;
+
+	if ($textwidth > $width) {
+
+	    print STDERR "WARNING (green_bar.pl): '$text' does not fit within $width pixel fixed width ";
+	    print STDERR "image. Image width was increased to ",$textwidth + $spacers, " pixels\n";
+	    
+	    $width = $textwidth + $spacers;
+
+	    # recreate image in new size
+	    ($image, $backlayer) = &create_image ();
+	    $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1, 
+				    $fontsize, PIXELS, $foundry, $fontname, $fontweight, 
+				    $fontslant, $fontwidth, $fontspacing, $fontregistry, $fontencoding);
+	    
+	}
+
+	my $y_offset = ($height-$textheight)-int($fontsize/5);
+
+	my $halfdescenders = "";
+
+	# Russian half descenders (KOI8-R)
+	# -- Uncomment if generating Russian images using KOI8-R encoded text --
+	# $halfdescenders .= chr(195) . chr(253);  # Checked
+	# $halfdescenders .= chr(196) . chr(198) . chr(221) . chr(227) . chr(228); # Unchecked
+
+	# Kazakh (and Russian) half descenders (Helvetica Kazakh font)
+	# -- Uncomment if generating Kazakh or Russian images using text encoded to match
+	#      a Kazakh Helvetica font:
+        #        http://www.unesco.kz/ci/projects/greenstone/kazakh_fonts/helv_k.ttf
+	#    Mapping for this encoding is: mapping/from_uc/kazakh.ump --
+	# $halfdescenders .= chr(178) . chr(179) . chr(187);             # Kazakh specific
+	# $halfdescenders .= chr(196) . chr(214) . chr(217) . chr(228);  # Generic Russian
+	# $halfdescenders .= chr(244) . chr(246) . chr(249);
+
+	# -- Uncomment if generating images using a font with half descenders --
+	# if ($text =~ /[$halfdescenders]/) {
+	    # half descenders - put text at fontsize/10 pixels above bottom
+	    # $y_offset = ($height-$textheight)-int($fontsize/10);
+	# }
+
+	my $descenders = "";
+
+	# Russian descenders (KOI8-R)
+	# -- Uncomment if generating Russian images using KOI8-R encoded text --
+	# $descenders .= chr(210) . chr(213);
+
+	# Kazakh (and Russian) descenders (Helvetica Kazakh font)
+	# -- Uncomment if generating Kazakh or Russian images using text encoded to match
+	#      a Kazakh Helvetica font:
+        #        http://www.unesco.kz/ci/projects/greenstone/kazakh_fonts/helv_k.ttf
+	#    Mapping for this encoding is: mapping/from_uc/kazakh.ump --
+	# $descenders .= chr(189) . chr(190);  # Kazakh specific
+	# $descenders .= chr(240) . chr(243);  # Generic Russian
+
+	if ($text =~ /[gjpqyJ$descenders]/) { ## capital J is a descender in lucida font
+	    # descenders - put text at bottom of image, otherwise 
+	    # go for fontsize/5 pixels above bottom. This is kind of hacky 
+	    # and may need some playing with for different fonts/fontsizes
+	    $y_offset = $height-$textheight;
+	}
+
+	if ($dont_center) {
+	    # don't center text horizontally (start it width_space pixels from left edge)
+	    my $x_offset = $width_space;
+	    gimp_layer_set_offsets ($textlayer, $x_offset, $y_offset);
+	} else {
+	    gimp_layer_set_offsets ($textlayer, ($width-$textwidth)/2, $y_offset);
+	}
+    }
+    
+    # flatten the image
+    my $finishedlayer = gimp_image_flatten ($image);
+    
+    # make indexed colour 
+    gimp_convert_indexed ($image, NO_DITHER, MAKE_PALETTE, 256, 0, 1,"");
+    
+    # save image
+    $filename = &util::filename_cat ($image_dir, $filename);
+
+    gimp_file_save (RUN_NONINTERACTIVE, $image, $finishedlayer, $filename, $filename);
+
+}
+
+sub create_image {
+    # create the image
+    my $image = gimp_image_new ($width, $height, RGB_IMAGE);
+    
+    # background layer
+    my $backlayer = gimp_layer_new ($image, $width, $height, RGB_IMAGE, 
+				    "BGLayer", 100, NORMAL_MODE);
+    
+    # add the background layer
+    gimp_image_add_layer ($image, $backlayer, 0);
+    
+    # set colour of background
+    gimp_palette_set_foreground ($bgcolor);
+    
+    # clear the background
+    gimp_selection_all ($image);
+    gimp_edit_clear ($backlayer);
+    gimp_selection_none ($image);
+    
+    # create the gradient background
+    gimp_blend ($backlayer, 0, NORMAL_MODE, LINEAR, 70, 0, REPEAT_NONE, 0, 0, 0, 5, $height-3, 5, 0);
+
+    # set colour of text
+    gimp_palette_set_foreground ($fontcolor);
+
+    return ($image, $backlayer);
+}
+
+# returns 1 if this is the last entry,
+sub read_config_entry {
+    my ($handle) = @_;
+
+    my $line = "";
+    while (defined ($line = <$handle>)) {
+	next unless $line =~ /\w/;
+	my @line = ();
+	if ($line =~ /^\-+/) {return 0;}
+	$line =~ s/^\#.*$//;   # remove comments
+	$line =~ s/\cM|\cJ//g; # remove end-of-line characters
+	$line =~ s/^\s+//;     # remove initial white space
+	while ($line =~ s/\s*(\"[^\"]*\"|\'[^\']*\'|\S+)\s*//) {
+	    if (defined $1) {
+		# remove any enclosing quotes
+		my $entry = $1;
+		$entry =~ s/^([\"\'])(.*)\1$/$2/;
+
+		# substitute any environment variables
+		$entry =~ s/\$(\w+)/$ENV{$1}/g;
+		$entry =~ s/\$\{(\w+)\}/$ENV{$1}/g;
+		
+		push (@line, $entry);
+	    } else {
+		push (@line, "");
+	    }
+	}
+	if (scalar (@line) == 2 && defined ${$line[0]}) {
+	    ${$line[0]} = $line[1];
+	}
+    }
+    return 1;
+}
+    
+sub query {
+
+  gimp_install_procedure("gsdl_green_bar", "create green bar icons for gsdl",
+                        "", "Stefan Boddie", "Stefan Boddie", "2000-03-10",
+                        "<Toolbox>/Xtns/gsdl_green_bar", "*", &PROC_EXTENSION,
+                        [[PARAM_INT32, "run_mode", "Interactive, [non-interactive]"]], []);
+}
+
+Gimp::on_net { gsdl_green_bar; };
+exit main;
Index: /gsdl/stable/bin/script/gimp/green_bar.pl
===================================================================
--- /gsdl/stable/bin/script/gimp/green_bar.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gimp/green_bar.pl	(revision 20131)
@@ -0,0 +1,307 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# green_bar.pl 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# green_bar.pl generates all the black on green gradient background
+# images used by Greenstone. 
+# these are the icons described in macro files as:
+# green version of nav_bar_button
+# green_bar_left_aligned
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use Gimp;
+use parsargv;
+use util;
+use unicode;
+
+# set trace level to watch functions as they are executed
+#Gimp::set_trace(TRACE_ALL);
+#Gimp::set_trace(TRACE_CALL);
+
+my $gsdl_green = "#96c19b";
+my $black = "#000000";
+
+my ($cfg_file, $width, $height, $text, $filename, $width_space, 
+    $dont_center, $bgcolor, $fontcolor, $fontsize, $foundry, $fontname, 
+    $fontweight, $fontslant, $fontwidth, $fontspacing, $image_dir);
+
+sub print_usage {
+    print STDERR "\n  usage: $0 [options] macrofile\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -cfg_file file        configuration file containing one or more\n";
+    print STDERR "                         sets of the following options - use to create\n";
+    print STDERR "                         batches of images\n";
+    print STDERR "   -image_dir directory  directory to create images in [`pwd`]\n";
+    print STDERR "                         this should be full path to existing directory\n";
+    print STDERR "   -width number         width of bar [87]\n";
+    print STDERR "   -height number        height of bar [17]\n";
+    print STDERR "   -text string          icon text\n";
+    print STDERR "   -filename string      filename of resulting image\n";
+    print STDERR "   -width_space number   width in pixels of blank space to leave at left\n";
+    print STDERR "                         and right edges of text [1]\n";
+    print STDERR "   -dont_center          don't center text horizontally\n";
+    print STDERR "   -bgcolor hex_value    background color of bar [$gsdl_green]\n";
+    print STDERR "   -fontcolor hex_value  text color [$black]\n";
+    print STDERR "   -fontsize number      font point size [17]\n";
+    print STDERR "   -foundry string       [*]\n";
+    print STDERR "   -fontname string      [lucida]\n";
+    print STDERR "   -fontweight string    [medium]\n";
+    print STDERR "   -fontslant            [r]\n";
+    print STDERR "   -fontwidth            [*]\n";
+    print STDERR "   -fontspacing          [*]\n\n";
+}
+
+sub reset_options {
+    $image_dir = "./";
+    $width = 87;
+    $height = 17;
+    $text = "";
+    $filename = "";
+    $width_space = 1;
+    $dont_center = 0;
+    $bgcolor = $gsdl_green;
+    $fontcolor = $black;
+    $fontsize = 17;
+    $foundry = "*";
+    $fontname = "lucida";
+    $fontweight = "medium";
+    $fontslant = "r";
+    $fontwidth = "*";
+    $fontspacing = "*";
+}
+
+sub gsdl_green_bar {
+
+    if (!parsargv::parse(\@ARGV, 
+			 'cfg_file/.*/', \$cfg_file,
+			 'image_dir/.*/./', \$image_dir,
+			 'width/^\d+$/87', \$width,
+			 'height/^\d+$/17', \$height,
+			 'text/.*/', \$text,
+			 'filename/.*', \$filename,
+			 'width_space/^\d+$/1', \$width_space,
+			 'dont_center', \$dont_center,
+			 "bgcolor/#[0-9A-Fa-f]{6}/$gsdl_green", \$bgcolor,
+			 "fontcolor/#[0-9A-Fa-f]{6}/$black", \$fontcolor,
+			 'fontsize/^\d+$/17', \$fontsize,
+			 'foundry/.*/*', \$foundry,
+			 'fontname/.*/lucida', \$fontname,
+			 'fontweight/.*/medium', \$fontweight,
+			 'fontslant/.*/r', \$fontslant,
+			 'fontwidth/.*/*', \$fontwidth,
+			 'fontspacing/.*/*', \$fontspacing)) {
+	&print_usage();
+	die "green_bar.pl: incorrect options\n";
+    }
+
+    # will create wherever gimp was started up from if we don't do this
+    if ($image_dir eq "./") {
+	$image_dir = `pwd`;
+	chomp $image_dir;
+    }
+    
+    if ($cfg_file =~ /\w/) {
+	
+	open (CONF, $cfg_file) || die "couldn't open cfg_file $cfg_file\n";
+	while (1) {
+
+	    &reset_options ();
+	
+	    # read image configuration entry
+	    my $status = &read_config_entry (CONF);
+	    if ($filename !~ /\w/) {
+		if ($status) {last;}
+		else {next;}
+	    }
+
+	    &produce_image ();
+	    if ($status) {last;}
+	}
+
+	close CONF;
+
+    } else {
+
+	&produce_image ();
+
+    }
+}
+
+sub produce_image {
+    
+    # create image, set background color etc.
+    my ($image, $backlayer) = &create_image ();
+    
+    # set the text if there is any
+    if (length($text)) {
+
+	my $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1, 
+				   $fontsize, PIXELS, $foundry, $fontname, $fontweight, 
+				   $fontslant, $fontwidth, $fontspacing);
+	
+
+	my $textwidth = gimp_drawable_width($textlayer);
+	my $textheight = gimp_drawable_height($textlayer);
+
+	# check that text fits within image
+	if ($textheight > $height) {
+	    die "'$text' at fontsize of $fontsize pixels does not fit within image\n" . 
+		"$height pixels high. Decrease fontsize or increase image height\n";
+	}
+
+	my $spacers = $width_space * 2;
+
+	if ($textwidth > $width) {
+
+	    print STDERR "WARNING (green_bar.pl): '$text' does not fit within $width pixel fixed width ";
+	    print STDERR "image. Image width was increased to ",$textwidth + $spacers, " pixels\n";
+	    
+	    $width = $textwidth + $spacers;
+
+	    # recreate image in new size
+	    ($image, $backlayer) = &create_image ();
+	    $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1, 
+				    $fontsize, PIXELS, $foundry, $fontname, $fontweight, 
+				    $fontslant, $fontwidth, $fontspacing);
+	    
+	}
+
+	my $y_offset = ($height-$textheight)-int($fontsize/5);
+
+	my $descenders = "";
+
+	# russian descenders (KOI8-R)
+	# $descenders .= chr(0xD2);
+	# $descenders .= chr(0xD5);
+
+	if ($text =~ /[gjpqyJ$descenders]/) { ## capital J is a descender in lucida font
+	    # descenders - put text at bottom of image, otherwise 
+	    # go for fontsize/5 pixels above bottom. This is kind of hacky 
+	    # and may need some playing with for different fonts/fontsizes
+	    $y_offset = $height-$textheight;
+	}
+
+	if ($dont_center) {
+	    # don't center text horizontally (start it width_space pixels from left edge)
+	    my $x_offset = $width_space;
+	    gimp_layer_set_offsets ($textlayer, $x_offset, $y_offset);
+	} else {
+	    gimp_layer_set_offsets ($textlayer, ($width-$textwidth)/2, $y_offset);
+	}
+    }
+    
+    # flatten the image
+    my $finishedlayer = gimp_image_flatten ($image);
+    
+    # make indexed colour 
+    gimp_convert_indexed ($image, 0, 256);
+    
+    # save image
+    $filename = &util::filename_cat ($image_dir, $filename);
+
+    gimp_file_save (RUN_NONINTERACTIVE, $image, $finishedlayer, $filename, $filename);
+
+}
+
+sub create_image {
+    # create the image
+    my $image = gimp_image_new ($width, $height, RGB_IMAGE);
+    
+    # background layer
+    my $backlayer = gimp_layer_new ($image, $width, $height, RGB_IMAGE, 
+				    "BGLayer", 100, NORMAL_MODE);
+    
+    # add the background layer
+    gimp_image_add_layer ($image, $backlayer, 0);
+    
+    # set colour of background
+    gimp_palette_set_foreground ($bgcolor);
+    
+    # clear the background
+    gimp_selection_all ($image);
+    gimp_edit_clear ($image, $backlayer);
+    gimp_selection_none ($image);
+    
+    # create the gradient background
+    gimp_blend ($image, $backlayer, 0, NORMAL_MODE, LINEAR, 70, 0, REPEAT_NONE, 0, 0, 0, 5, $height-3, 5, 0);
+
+    # set colour of text
+    gimp_palette_set_foreground ($fontcolor);
+
+    return ($image, $backlayer);
+}
+
+# returns 1 if this is the last entry,
+sub read_config_entry {
+    my ($handle) = @_;
+
+    my $line = "";
+    while (defined ($line = <$handle>)) {
+	next unless $line =~ /\w/;
+	my @line = ();
+	if ($line =~ /^\-+/) {return 0;}
+	$line =~ s/^\#.*$//;   # remove comments
+	$line =~ s/\cM|\cJ//g; # remove end-of-line characters
+	$line =~ s/^\s+//;     # remove initial white space
+	while ($line =~ s/\s*(\"[^\"]*\"|\'[^\']*\'|\S+)\s*//) {
+	    if (defined $1) {
+		# remove any enclosing quotes
+		my $entry = $1;
+		$entry =~ s/^([\"\'])(.*)\1$/$2/;
+
+		# substitute any environment variables
+		$entry =~ s/\$(\w+)/$ENV{$1}/g;
+		$entry =~ s/\$\{(\w+)\}/$ENV{$1}/g;
+		
+		push (@line, $entry);
+	    } else {
+		push (@line, "");
+	    }
+	}
+	if (scalar (@line) == 2 && defined ${$line[0]}) {
+	    ${$line[0]} = $line[1];
+	}
+    }
+    return 1;
+}
+    
+sub query {
+
+  gimp_install_procedure("gsdl_green_bar", "create green bar icons for gsdl",
+                        "", "Stefan Boddie", "Stefan Boddie", "2000-03-10",
+                        "<Toolbox>/Xtns/gsdl_green_bar", "*", &PROC_EXTENSION,
+                        [[PARAM_INT32, "run_mode", "Interactive, [non-interactive]"]], []);
+}
+
+sub net {
+  gsdl_green_bar;
+}
+
+exit main;
Index: /gsdl/stable/bin/script/gimp/green_bar_g12.pl
===================================================================
--- /gsdl/stable/bin/script/gimp/green_bar_g12.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gimp/green_bar_g12.pl	(revision 20131)
@@ -0,0 +1,309 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# green_bar.pl 
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# green_bar.pl 
+#
+# This script generates the black on green gradient background images
+# used by Greenstone.  these are the icons described in macro files as:
+# green version of nav_bar_button green_bar_left_aligned
+#
+# This version has been rewritten for the GIMP Version 1.2.  You
+# should be able to run it if you install gimp 1.2 with perl support.
+# In Debian this means running "apt-get install gimp1.2 gimp1.2perl"
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use Gimp ":auto";
+use Gimp::Fu; 
+
+use util;
+use unicode;
+
+# set trace level to watch functions as they are executed
+#Gimp::set_trace(TRACE_ALL);
+#Gimp::set_trace(TRACE_CALL);
+
+my $gsdl_green = "#96c19b";
+my $black      = "#000000";
+my $white      = "#FFFFFF";
+
+my ($current_dir) = `pwd`;
+chomp($current_dir);
+
+my ($cfg_file, $width, $height, $text, $filename, $width_space, 
+    $alignment, $fgcolor, $bgcolor, $fontcolor, $fontsize, $foundry, $fontname, 
+    $fontweight, $fontslant, $fontwidth, $fontspacing, $image_dir);
+
+sub reset_options {
+    $image_dir = "./";
+    $width = 87;
+    $height = 17;
+    $text = "";
+    $filename = "";
+    $width_space = 1;
+    $alignment = "eft";
+    $fgcolor = $white;
+    $bgcolor = $gsdl_green;
+    $fontcolor = $black;
+    $fontsize = 17;
+    $foundry = "*";
+    $fontname = "lucida";
+    $fontweight = "medium";
+    $fontslant = "r";
+    $fontwidth = "*";
+    $fontspacing = "*";
+}
+
+sub gsdl_green_bar {
+
+    ($text, $filename, $image_dir, $width, $height, $fgcolor, $bgcolor,
+    $fontcolor, $fontsize, $alignment, , $width_space, $foundry,
+    $fontname, $fontweight, $fontslant, $fontwidth, $fontspacing,
+    $cfg_file) = @_;
+
+    # Read a configuration file
+    if ($cfg_file =~ /\w/) {
+	
+	open (CONF, $cfg_file) || die "couldn't open cfg_file $cfg_file\n";
+	while (1) {
+
+	    &reset_options ();
+	
+	    # read image configuration entry
+	    my $status = &read_config_entry (CONF);
+	    if ($filename !~ /\w/) {
+		if ($status) {last;}
+		else {next;}
+	    }
+
+	    &produce_image ();
+	    if ($status) {last;}
+	}
+
+	close CONF;
+
+    }
+
+    # Produce an image based onlyon command-line parameters
+    else {
+
+	&produce_image ();
+
+    }
+}
+
+
+sub produce_image {
+
+    # Create background image
+    my ($image, $backlayer) = &create_image ();
+
+    # set the text if there is any
+    if (length($text)) {
+
+	my $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1, 
+				   $fontsize, PIXELS, $foundry, $fontname, $fontweight, 
+				   $fontslant, $fontwidth, $fontspacing, "*", "*");
+	
+
+	my $textwidth = gimp_drawable_width($textlayer);
+	my $textheight = gimp_drawable_height($textlayer);
+
+	# check that text fits within image
+	if ($textheight > $height) {
+	    die "'$text' at fontsize of $fontsize pixels does not fit within image\n" . 
+		"$height pixels high. Decrease fontsize or increase image height\n";
+	}
+
+	my $spacers = $width_space * 2;
+
+	if ($textwidth > $width) {
+
+	    print STDERR "WARNING (green_bar.pl): '$text' does not fit within $width pixel fixed width ";
+	    print STDERR "image. Image width was increased to ",$textwidth + $spacers, " pixels\n";
+	
+	    $width = $textwidth + $spacers;
+
+	    # recreate image in new size
+	    ($image, $backlayer) = &create_image ();
+	    $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1,
+				    $fontsize, PIXELS, $foundry, $fontname, $fontweight,
+				    $fontslant, $fontwidth, $fontspacing, "*", "*");
+	
+	}
+
+	my $y_offset = ($height-$textheight)-int($fontsize/5);
+
+	my $descenders = "";
+
+	# russian descenders (KOI8-R)
+	# $descenders .= chr(0xD2);
+	# $descenders .= chr(0xD5);
+
+	if ($text =~ /[gjpqyJ$descenders]/) { ## capital J is a descender in lucida font
+	    # descenders - put text at bottom of image, otherwise 
+	    # go for fontsize/5 pixels above bottom. This is kind of hacky 
+	    # and may need some playing with for different fonts/fontsizes
+	    $y_offset = $height-$textheight;
+	}
+
+	if ($alignment =~ /^l/i) {
+	    # align text to the left
+	    my $x_offset = $width_space;
+	    gimp_layer_set_offsets ($textlayer, $x_offset, $y_offset);
+	} elsif ($alignment =~ /^r/i) {
+	    # right alignment
+	    gimp_layer_set_offsets ($textlayer, ($width-($textwidth+$width_space)), $y_offset);
+	} else {
+	    # center alignment (the default)
+	    gimp_layer_set_offsets ($textlayer, ($width-$textwidth)/2, $y_offset);
+	}
+    }
+
+    # flatten the image
+    my $finishedlayer = gimp_image_flatten ($image);
+
+    # make indexed colour 
+    if ($filename =~ /\.gif$/i) {
+        # make indexed colour (may need to do this for 
+        # other formats as well as gif)
+        gimp_convert_indexed ($image, 0, MAKE_PALETTE, 256, 0, 0, "");
+    }
+
+    # save image
+    $filename = &util::filename_cat ($image_dir, $filename);
+    gimp_file_save (RUN_NONINTERACTIVE, $image, $finishedlayer, $filename, $filename);
+}
+
+
+sub create_image {
+    # create the image
+    my $image = gimp_image_new ($width, $height, RGB_IMAGE);
+
+    # background layer
+    my $backlayer = gimp_layer_new ($image, $width, $height, RGB_IMAGE, 
+				    "BGLayer", 100, NORMAL_MODE);
+
+    # add the background layer
+    gimp_image_add_layer ($image, $backlayer, 0);
+
+    # set colour of background
+    gimp_palette_set_foreground ($bgcolor);
+    gimp_palette_set_background ($fgcolor);
+
+    # clear the background
+    gimp_selection_all ($image);
+    gimp_edit_clear ($backlayer);
+    gimp_selection_none ($image);
+
+    # create the gradient background
+    gimp_blend ($backlayer, 0, NORMAL_MODE, LINEAR, 70, 0, REPEAT_NONE, 0, 0, 0, 5, $height-3, 5, 0);
+
+    # set colour of text
+    gimp_palette_set_foreground ($fontcolor);
+
+    return ($image, $backlayer);
+}
+
+# returns 1 if this is the last entry,
+sub read_config_entry {
+    my ($handle) = @_;
+
+    my $line = "";
+    while (defined ($line = <$handle>)) {
+	next unless $line =~ /\w/;
+	my @line = ();
+	if ($line =~ /^\-+/) {return 0;}
+	$line =~ s/^\#.*$//;   # remove comments
+	$line =~ s/\cM|\cJ//g; # remove end-of-line characters
+	$line =~ s/^\s+//;     # remove initial white space
+	while ($line =~ s/\s*(\"[^\"]*\"|\'[^\']*\'|\S+)\s*//) {
+	    if (defined $1) {
+		# remove any enclosing quotes
+		my $entry = $1;
+		$entry =~ s/^([\"\'])(.*)\1$/$2/;
+
+		# substitute any environment variables
+		$entry =~ s/\$(\w+)/$ENV{$1}/g;
+		$entry =~ s/\$\{(\w+)\}/$ENV{$1}/g;
+		
+		push (@line, $entry);
+	    } else {
+		push (@line, "");
+	    }
+	}
+	if (scalar (@line) == 2 && defined ${$line[0]}) {
+	    ${$line[0]} = $line[1];
+	}
+    }
+    return 1;
+}
+
+
+register("gsdl_green_bar", 
+	 "Create green bar icons for gsdl (gimp version 1.2)",
+	 "",
+	 "Stefan Boddie (1.0) and Gordon Paynter (1.2)",
+	 "Copyright 2000 Stefan Boddie and The New Zealand Digital Library Project",
+	 "2000-07-05",
+	 "<Toolbox>/Xtns/gsdl_green_bar", 
+	 "*",
+	 [
+           [PF_STRING, "text",        "Text appearing on bar", "greenstone"],
+
+           [PF_STRING, "filename",    "Output file", "green_bar.png"],
+           [PF_STRING, "image_dir",   "Directory to create images in", $current_dir],
+
+           [PF_INT,    "width",      "Width of the bar",  640],
+           [PF_INT,    "height",     "Height of the bar", 17],
+           [PF_STRING, "fgcolor",   "Foreground colour (top) of bar", $white],
+           [PF_STRING, "bgcolor",   "Background colour (bottom) of bar", $gsdl_green],
+           [PF_STRING, "fontcolor", "Colour of text on bar", $black],
+           [PF_INT,    "fontsize",  "Font size",    17],
+
+           [PF_STRING, "alignment",     "Alignment of text on the bar (left, center or right)", "left"],
+           [PF_INT,    "padding_space", "Space around the text",                   5],
+
+           [PF_STRING, "foundry",     "Font foundry", "*"],
+           [PF_STRING, "fontname",    "Font name",    "lucida"],
+           [PF_STRING, "fontweight",  "Font weight",  "medium"],
+           [PF_STRING, "fontslant",   "Font slant",   "r"],
+           [PF_STRING, "fontwidth",   "Font width",   "*"],
+           [PF_STRING, "fontspacing", "Font spacing", "*"],
+
+           [PF_STRING, "cfg_file",    "Configuration file", ""]
+
+         ], 
+         \&gsdl_green_bar);
+
+
+exit main;
Index: /gsdl/stable/bin/script/gimp/title_icon-1.2.pl
===================================================================
--- /gsdl/stable/bin/script/gimp/title_icon-1.2.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gimp/title_icon-1.2.pl	(revision 20131)
@@ -0,0 +1,407 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# title_icon.pl 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# Modified by Rachid Ben Kaddour <qben@oce.nl> for gimp1.2
+
+# title_icon.pl generates all the green_title type icons and 
+# collection icons for Greenstone
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use Gimp qw/:auto :DEFAULT/;
+use parsargv;
+use util;
+use unicode;
+
+# set trace level to watch functions as they are executed
+#Gimp::set_trace(TRACE_ALL);
+#Gimp::set_trace(TRACE_CALL);
+
+my $gsdl_green = "#96c19b";
+my $black = "#000000";
+
+
+local ($cfg_file, $size, $imagefile, $width, $height, $imageheight, $stripecolor, $stripewidth, 
+       $stripe_alignment, $i_transparency, $text, $text_alignment, $filename, $textspace_x, 
+       $textspace_y, $bgcolor, $fontcolor, $fontsize, $minfontsize, $foundry, $fontname, 
+       $fontweight, $fontslant, $fontwidth, $fontspacing, $fontregistry, $fontencoding, $image_dir, $dont_wrap);
+
+sub print_usage {
+    print STDERR "\n  usage: $0 [options] macrofile\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -cfg_file file         configuration file containing one or more\n";
+    print STDERR "                          sets of the following options - use to create\n";
+    print STDERR "                          batches of images\n";
+    print STDERR "   -size number           the overall size ratio of the image (i.e. a size\n";
+    print STDERR "                          of 2 will create an image twice the default size)\n";
+    print STDERR "   -image_dir directory   directory to create images in [`pwd`]\n";
+    print STDERR "                          this should be full path to existing directory\n";
+    print STDERR "   -imagefile             filename of image to embed within new icon\n";
+    print STDERR "   -width number          width of icon [150]\n";
+    print STDERR "   -height number         height of icon [44]\n";
+    print STDERR "   -imageheight number    this is the height of the image if the image contains\n";
+    print STDERR "                          an image (like collection icons) [110]\n";
+    print STDERR "   -stripecolor hex_value color of vertical stripe [$gsdl_green]\n";
+    print STDERR "   -stripewidth           width of vertical stripe [40]\n";
+    print STDERR "   -stripe_alignment      alignment of vertical stripe (left or right) [left]\n";
+    print STDERR "   -i_transparency number transparency of image within icon (0 > transparent > 100) [60]\n"; 
+    print STDERR "   -text string           image text\n";
+    print STDERR "   -text_alignment        alignment of text (left or right) [left]\n";
+    print STDERR "   -filename string       filename of resulting image\n";
+    print STDERR "   -textspace_x number    space in pixels between left/right edge of image and\n";
+    print STDERR "                          left/right edge of text [3]\n";
+    print STDERR "   -textspace_y number    space in pixels between top of image and top of\n";
+    print STDERR "                          text [3]\n";
+    print STDERR "   -bgcolor hex_value     background color of icon [$gsdl_green]\n";
+    print STDERR "   -fontcolor hex_value   text color [$black]\n";
+    print STDERR "   -fontsize number       font point size [17]\n";
+    print STDERR "   -minfontsize number    minimum point size font will be reduced to fit image [10]\n";
+    print STDERR "   -foundry string        [*]\n";
+    print STDERR "   -fontname string       [lucida]\n";
+    print STDERR "   -fontweight string     [medium]\n";
+    print STDERR "   -fontslant             [r]\n";
+    print STDERR "   -fontwidth             [*]\n";
+    print STDERR "   -fontspacing           [*]\n";
+    print STDERR "   -fontregistry          [*]\n";
+    print STDERR "   -fontencoding          [*]\n";
+    print STDERR "   -dont_wrap             don't attempt to wrap text\n\n";
+}
+
+sub reset_options {
+    $image_dir = "./";
+    $imagefile = "";
+    $width = int (150 * $size);
+    $height = int (44 * $size);
+    $imageheight = int (110 * $size);
+    $stripecolor = $gsdl_green;
+    $stripewidth = int (40 * $size);
+    $stripe_alignment = "left";
+    $i_transparency = 60;
+    $text = "";
+    $text_alignment = "left";
+    $filename = "";
+    $textspace_x = int (3 * $size);
+    $textspace_y = int (3 * $size);
+    $bgcolor = $gsdl_green;
+    $fontcolor = $black;
+    $fontsize = int (17 * $size);
+    $minfontsize = int (10 * $size);
+    $foundry = "*";
+    $fontname = "lucida";
+    $fontweight = "medium";
+    $fontslant = "r";
+    $fontwidth = "*";
+    $fontspacing = "*";
+    $fontregistry = "*";
+    $fontencoding = "*";
+}
+
+sub gsdl_title_icon {
+
+    if (!parsargv::parse(\@ARGV, 
+			 'cfg_file/.*/', \$cfg_file,
+			 'size/\d+/1', \$size,
+			 'image_dir/.*/./', \$image_dir,
+			 'imagefile/.*/', \$imagefile,
+			 'width/^\d+$/150', \$width,
+			 'height/^\d+$/44', \$height,
+			 'imageheight/^\d+$/110', \$imageheight,
+			 "stripecolor/#[0-9A-Fa-f]{6}/$gsdl_green", \$stripecolor,
+			 'stripewidth/^\d+$/40', \$stripewidth,
+			 'stripe_alignment/^(left|right)$/left', \$stripe_alignment,
+			 'i_transparency/^\d+$/60', \$i_transparency,
+			 'text/.*/', \$text,
+			 'text_alignment/^(left|right)$/left', \$text_alignment,
+			 'filename/.*', \$filename,
+			 'textspace_x/^\d+$/3', \$textspace_x,
+			 'textspace_y/^\d+$/3', \$textspace_y,
+			 "bgcolor/#[0-9A-Fa-f]{6}/$gsdl_green", \$bgcolor,
+			 "fontcolor/#[0-9A-Fa-f]{6}/$black", \$fontcolor,
+			 'fontsize/^\d+$/17', \$fontsize,
+			 'minfontsize/^\d+$/10', \$minfontsize,
+			 'foundry/.*/*', \$foundry,
+			 'fontname/.*/lucida', \$fontname,
+			 'fontweight/.*/medium', \$fontweight,
+			 'fontslant/.*/r', \$fontslant,
+			 'fontwidth/.*/*', \$fontwidth,
+			 'fontspacing/.*/*', \$fontspacing,
+			 'fontregistry/.*/*', \$fontregistry,
+			 'fontencoding/.*/*', \$fontencoding,
+			 'dont_wrap', \$dont_wrap)) {
+	&print_usage();
+	die "title_icon.pl: incorrect options\n";
+    }
+
+    # will create wherever gimp was started up from if we don't do this
+    if ($image_dir eq "./") {
+	$image_dir = `pwd`;
+	chomp $image_dir;
+    }
+
+    if ($cfg_file =~ /\w/) {
+	
+	open (CONF, $cfg_file) || die "couldn't open cfg_file $cfg_file\n";
+	while (1) {
+
+	    &reset_options ();
+	
+	    # read image configuration entry
+	    my $status = &read_config_entry (CONF);
+	    if ($filename !~ /\w/) {
+		if ($status) {last;}
+		else {next;}
+	    }
+
+	    &produce_image ();
+	    if ($status) {last;}
+	}
+
+	close CONF;
+
+    } else {
+
+	&produce_image ();
+
+    }
+}
+
+sub produce_image {
+
+    &adjust_args ();
+    &wrap_text () unless $dont_wrap;
+
+    my $use_image = 0;
+    if ($imagefile =~ /\w/) {
+	if (!-r $imagefile) {
+	    print STDERR "WARNING (title_icon.pl): imagefile '$imagefile cannot be ";
+	    print STDERR "read - $filename will be created without the use of an image file\n";
+	} else {
+	    $use_image = 1;
+	    $height = $imageheight;
+	}
+    }
+
+    # create the image
+    my $image = gimp_image_new ($width, $height, RGB_IMAGE);
+	
+    # background layer
+    my $backlayer = gimp_layer_new ($image, $width, $height, RGB_IMAGE, 
+				    "BGLayer", 100, NORMAL_MODE);
+	
+    # add the background layer
+    gimp_image_add_layer ($image, $backlayer, 0);
+	
+    # set colour of stripe
+    gimp_palette_set_foreground ($stripecolor);
+	
+    # clear the background
+    gimp_selection_all ($image);
+    gimp_edit_clear ($backlayer);
+    gimp_selection_none ($image);
+	
+    # fill in stripe
+    if ($stripe_alignment eq "left") {
+	gimp_rect_select ($image, 0, 0, $stripewidth, $height, 0, 0, 0);
+    } else {
+	gimp_rect_select ($image, $width-$stripewidth, 0, $stripewidth, $height, 0, 0, 0);
+    }
+    gimp_bucket_fill ($backlayer, FG_BUCKET_FILL, NORMAL_MODE, 100, 0, 1, 0, 0);
+    gimp_selection_none ($image);
+
+    # get image file (image goes on opposite side to stripe)
+    if ($use_image) {
+	my $rimage = gimp_file_load (RUN_NONINTERACTIVE, $imagefile, $imagefile);
+	my $rdraw = gimp_image_active_drawable ($rimage);
+	gimp_scale ($rdraw, 1, 0, 0, $width-$stripewidth, $height);
+	gimp_edit_copy ($rdraw);
+	
+	my $imagelayer = gimp_layer_new ($image, $width, $height, RGB_IMAGE, 
+					 "ImageLayer", $i_transparency, NORMAL_MODE);
+	
+	gimp_image_add_layer ($image, $imagelayer, 0);
+	
+	# clear the new layer
+	gimp_selection_all ($image);
+	gimp_edit_clear ($imagelayer);
+	gimp_selection_none ($image);
+	
+	my $flayer = gimp_edit_paste ($imagelayer, 1); 
+	if ($stripe_alignment eq "left") {
+	    gimp_layer_set_offsets($flayer, $stripewidth, 0);
+	    gimp_layer_set_offsets($imagelayer, $stripewidth, 0);
+	} else {
+	    gimp_layer_set_offsets($flayer, 0, 0);
+	    gimp_layer_set_offsets($imagelayer, 0, 0);
+	}
+
+	$backlayer = gimp_image_flatten ($image);
+    }
+	
+    # set colour of text
+    gimp_palette_set_foreground ($fontcolor);
+	
+    # set the text if there is any
+    my ($textlayer, $textheight, $textwidth);
+    my $fsize = $fontsize;
+    if (length($text)) {
+	$text =~ s/\\n/\n/gi;
+
+	while (1) {
+
+	    $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1, $fsize, 
+				    PIXELS, $foundry, $fontname, $fontweight, $fontslant, 
+				    $fontwidth, $fontspacing, $fontregistry, $fontencoding);
+	    
+	    # check that text fits within image
+	    $textwidth = gimp_drawable_width($textlayer);
+	    $textheight = gimp_drawable_height($textlayer);
+	    if ((($textwidth + $textspace_x) > $width) || 
+		(($textheight + $textspace_y) > $height)) {
+		if ($fsize < $minfontsize) {
+		    die "Error (title_icon.pl): text '$text' doesn't fit on ${width}x${height} image " .
+			"(minimum font size tried: $minfontsize\n";
+		} else {
+		    gimp_selection_all ($image);
+		    gimp_edit_clear ($textlayer);
+		    gimp_selection_none ($image);
+		    $fsize --;
+		    print STDERR "WARNING (title_icon.pl): '$text' doesn't fit: reducing font size to $fsize\n";
+		}
+	    } else {
+		last;
+	    }
+	}
+	
+	# align text
+	if ($text_alignment eq "left") {
+	    gimp_layer_set_offsets ($textlayer, $textspace_x, $textspace_y);
+	} else {
+	    gimp_layer_set_offsets ($textlayer, ($width-$textwidth)-$textspace_x, $textspace_y);
+	}
+    }
+    
+    # flatten the image
+    my $finishedlayer = gimp_image_flatten ($image);
+	
+    if ($filename =~ /\.gif$/i) {
+	# make indexed colour (may need to do this for 
+	# other formats as well as gif)
+	gimp_convert_indexed ($image, NO_DITHER, MAKE_PALETTE, 256, 0, 1, "");
+    }
+	
+    # save image
+    my $filename = &util::filename_cat ($image_dir, $filename);
+    if ($filename =~ /\.jpe?g$/i) {
+	# gimp_file_save doesn't appear to work properly for jpegs
+	file_jpeg_save (RUN_NONINTERACTIVE, $image, $finishedlayer, 
+			$filename, $filename, 0.8, 0, 1);
+    } else {
+	gimp_file_save (RUN_NONINTERACTIVE, $image, $finishedlayer, 
+			$filename, $filename);
+    }
+}
+
+# returns 1 if this is the last entry,
+sub read_config_entry {
+    my ($handle) = @_;
+
+    my $line = "";
+    while (defined ($line = <$handle>)) {
+	next unless $line =~ /\w/;
+	my @line = ();
+	if ($line =~ /^\-+/) {return 0;}
+	$line =~ s/^\#.*$//;   # remove comments
+	$line =~ s/\cM|\cJ//g; # remove end-of-line characters
+	$line =~ s/^\s+//;     # remove initial white space
+	while ($line =~ s/\s*(\"[^\"]*\"|\'[^\']*\'|\S+)\s*//) {
+	    if (defined $1) {
+		# remove any enclosing quotes
+		my $entry = $1;
+		$entry =~ s/^([\"\'])(.*)\1$/$2/;
+
+		# substitute any environment variables
+		$entry =~ s/\$(\w+)/$ENV{$1}/g;
+		$entry =~ s/\$\{(\w+)\}/$ENV{$1}/g;
+		
+		push (@line, $entry);
+	    } else {
+		push (@line, "");
+	    }
+	}
+	if (scalar (@line) == 2 && defined ${$line[0]}) {
+	    ${$line[0]} = $line[1];
+	}
+    }
+    return 1;
+}
+
+# adjust arguments that are effected by the size argument
+sub adjust_args {    
+
+    if ($size != 1) {
+	my @size_args = ('width', 'height', 'imageheight', 'stripewidth',
+			 'textspace_x', 'textspace_y', 'fontsize', 'minfontsize');
+	foreach $arg (@size_args) {
+	    $$arg = int ($$arg * $size);
+	}
+    }
+}
+
+sub wrap_text {
+
+    # don't wrap text if it already contains carriage returns
+    return if $text =~ /\n/;
+
+    # the following assumes that all words are less than $wrap_length long
+    my $wrap_length = 14;
+
+    my $new_text = "";
+    while (length ($text) >= $wrap_length) {
+	my $line = substr ($text, 0, $wrap_length);
+	$text =~ s/^\Q$line\E//;
+	$line =~ s/\s([^\s]*)$/\n/;
+	$text = $1 . $text;
+	$new_text .= $line;
+    }
+    $new_text .= $text;
+    $text = $new_text;
+}
+    
+sub query {
+
+  gimp_install_procedure("gsdl_title_icon", "create title icons for gsdl",
+                        "", "Stefan Boddie", "Stefan Boddie", "2000-03-10",
+                        "<Toolbox>/Xtns/gsdl_title_icon", "*", &PROC_EXTENSION,
+                        [[PARAM_INT32, "run_mode", "Interactive, [non-interactive]"]], []);
+}
+
+Gimp::on_net { gsdl_title_icon; };
+exit main;
+
Index: /gsdl/stable/bin/script/gimp/title_icon.pl
===================================================================
--- /gsdl/stable/bin/script/gimp/title_icon.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gimp/title_icon.pl	(revision 20131)
@@ -0,0 +1,399 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# title_icon.pl 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# title_icon.pl generates all the green_title type icons and 
+# collection icons for Greenstone
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use Gimp;
+use parsargv;
+use util;
+use unicode;
+
+# set trace level to watch functions as they are executed
+#Gimp::set_trace(TRACE_ALL);
+#Gimp::set_trace(TRACE_CALL);
+
+my $gsdl_green = "#96c19b";
+my $black = "#000000";
+
+
+local ($cfg_file, $size, $imagefile, $width, $height, $imageheight, $stripecolor, $stripewidth, 
+       $stripe_alignment, $i_transparency, $text, $text_alignment, $filename, $textspace_x, 
+       $textspace_y, $bgcolor, $fontcolor, $fontsize, $minfontsize, $foundry, $fontname, 
+       $fontweight, $fontslant, $fontwidth, $fontspacing, $image_dir, $dont_wrap);
+
+sub print_usage {
+    print STDERR "\n  usage: $0 [options] macrofile\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -cfg_file file         configuration file containing one or more\n";
+    print STDERR "                          sets of the following options - use to create\n";
+    print STDERR "                          batches of images\n";
+    print STDERR "   -size number           the overall size ratio of the image (i.e. a size\n";
+    print STDERR "                          of 2 will create an image twice the default size)\n";
+    print STDERR "   -image_dir directory   directory to create images in [`pwd`]\n";
+    print STDERR "                          this should be full path to existing directory\n";
+    print STDERR "   -imagefile             filename of image to embed within new icon\n";
+    print STDERR "   -width number          width of icon [150]\n";
+    print STDERR "   -height number         height of icon [44]\n";
+    print STDERR "   -imageheight number    this is the height of the image if the image contains\n";
+    print STDERR "                          an image (like collection icons) [110]\n";
+    print STDERR "   -stripecolor hex_value color of vertical stripe [$gsdl_green]\n";
+    print STDERR "   -stripewidth           width of vertical stripe [40]\n";
+    print STDERR "   -stripe_alignment      alignment of vertical stripe (left or right) [left]\n";
+    print STDERR "   -i_transparency number transparency of image within icon (0 > transparent > 100) [60]\n"; 
+    print STDERR "   -text string           image text\n";
+    print STDERR "   -text_alignment        alignment of text (left or right) [left]\n";
+    print STDERR "   -filename string       filename of resulting image\n";
+    print STDERR "   -textspace_x number    space in pixels between left/right edge of image and\n";
+    print STDERR "                          left/right edge of text [3]\n";
+    print STDERR "   -textspace_y number    space in pixels between top of image and top of\n";
+    print STDERR "                          text [3]\n";
+    print STDERR "   -bgcolor hex_value     background color of icon [$gsdl_green]\n";
+    print STDERR "   -fontcolor hex_value   text color [$black]\n";
+    print STDERR "   -fontsize number       font point size [17]\n";
+    print STDERR "   -minfontsize number    minimum point size font will be reduced to fit image [10]\n";
+    print STDERR "   -foundry string        [*]\n";
+    print STDERR "   -fontname string       [lucida]\n";
+    print STDERR "   -fontweight string     [medium]\n";
+    print STDERR "   -fontslant             [r]\n";
+    print STDERR "   -fontwidth             [*]\n";
+    print STDERR "   -fontspacing           [*]\n";
+    print STDERR "   -dont_wrap             don't attempt to wrap text\n\n";
+}
+
+sub reset_options {
+    $image_dir = "./";
+    $imagefile = "";
+    $width = int (150 * $size);
+    $height = int (44 * $size);
+    $imageheight = int (110 * $size);
+    $stripecolor = $gsdl_green;
+    $stripewidth = int (40 * $size);
+    $stripe_alignment = "left";
+    $i_transparency = 60;
+    $text = "";
+    $text_alignment = "left";
+    $filename = "";
+    $textspace_x = int (3 * $size);
+    $textspace_y = int (3 * $size);
+    $bgcolor = $gsdl_green;
+    $fontcolor = $black;
+    $fontsize = int (17 * $size);
+    $minfontsize = int (10 * $size);
+    $foundry = "*";
+    $fontname = "lucida";
+    $fontweight = "medium";
+    $fontslant = "r";
+    $fontwidth = "*";
+    $fontspacing = "*";
+}
+
+sub gsdl_title_icon {
+
+    if (!parsargv::parse(\@ARGV, 
+			 'cfg_file/.*/', \$cfg_file,
+			 'size/\d+/1', \$size,
+			 'image_dir/.*/./', \$image_dir,
+			 'imagefile/.*/', \$imagefile,
+			 'width/^\d+$/150', \$width,
+			 'height/^\d+$/44', \$height,
+			 'imageheight/^\d+$/110', \$imageheight,
+			 "stripecolor/#[0-9A-Fa-f]{6}/$gsdl_green", \$stripecolor,
+			 'stripewidth/^\d+$/40', \$stripewidth,
+			 'stripe_alignment/^(left|right)$/left', \$stripe_alignment,
+			 'i_transparency/^\d+$/60', \$i_transparency,
+			 'text/.*/', \$text,
+			 'text_alignment/^(left|right)$/left', \$text_alignment,
+			 'filename/.*', \$filename,
+			 'textspace_x/^\d+$/3', \$textspace_x,
+			 'textspace_y/^\d+$/3', \$textspace_y,
+			 "bgcolor/#[0-9A-Fa-f]{6}/$gsdl_green", \$bgcolor,
+			 "fontcolor/#[0-9A-Fa-f]{6}/$black", \$fontcolor,
+			 'fontsize/^\d+$/17', \$fontsize,
+			 'minfontsize/^\d+$/10', \$minfontsize,
+			 'foundry/.*/*', \$foundry,
+			 'fontname/.*/lucida', \$fontname,
+			 'fontweight/.*/medium', \$fontweight,
+			 'fontslant/.*/r', \$fontslant,
+			 'fontwidth/.*/*', \$fontwidth,
+			 'fontspacing/.*/*', \$fontspacing,
+			 'dont_wrap', \$dont_wrap)) {
+	&print_usage();
+	die "title_icon.pl: incorrect options\n";
+    }
+
+    # will create wherever gimp was started up from if we don't do this
+    if ($image_dir eq "./") {
+	$image_dir = `pwd`;
+	chomp $image_dir;
+    }
+
+    if ($cfg_file =~ /\w/) {
+	
+	open (CONF, $cfg_file) || die "couldn't open cfg_file $cfg_file\n";
+	while (1) {
+
+	    &reset_options ();
+	
+	    # read image configuration entry
+	    my $status = &read_config_entry (CONF);
+	    if ($filename !~ /\w/) {
+		if ($status) {last;}
+		else {next;}
+	    }
+
+	    &produce_image ();
+	    if ($status) {last;}
+	}
+
+	close CONF;
+
+    } else {
+
+	&produce_image ();
+
+    }
+}
+
+sub produce_image {
+
+    &adjust_args ();
+    &wrap_text () unless $dont_wrap;
+
+    my $use_image = 0;
+    if ($imagefile =~ /\w/) {
+	if (!-r $imagefile) {
+	    print STDERR "WARNING (title_icon.pl): imagefile '$imagefile cannot be ";
+	    print STDERR "read - $filename will be created without the use of an image file\n";
+	} else {
+	    $use_image = 1;
+	    $height = $imageheight;
+	}
+    }
+
+    # create the image
+    my $image = gimp_image_new ($width, $height, RGB_IMAGE);
+	
+    # background layer
+    my $backlayer = gimp_layer_new ($image, $width, $height, RGB_IMAGE, 
+				    "BGLayer", 100, NORMAL_MODE);
+	
+    # add the background layer
+    gimp_image_add_layer ($image, $backlayer, 0);
+	
+    # set colour of stripe
+    gimp_palette_set_foreground ($stripecolor);
+	
+    # clear the background
+    gimp_selection_all ($image);
+    gimp_edit_clear ($image, $backlayer);
+    gimp_selection_none ($image);
+	
+    # fill in stripe
+    if ($stripe_alignment eq "left") {
+	gimp_rect_select ($image, 0, 0, $stripewidth, $height, 0, 0, 0);
+    } else {
+	gimp_rect_select ($image, $width-$stripewidth, 0, $stripewidth, $height, 0, 0, 0);
+    }
+    gimp_bucket_fill ($image, $backlayer, FG_BUCKET_FILL, NORMAL_MODE, 100, 0, 1, 0, 0);
+    gimp_selection_none ($image);
+	
+    # get image file (image goes on opposite side to stripe)
+    if ($use_image) {
+	my $rimage = gimp_file_load (RUN_NONINTERACTIVE, $imagefile, $imagefile);
+	my $rdraw = gimp_image_active_drawable ($rimage);
+	gimp_scale ($rimage, $rdraw, 1, 0, 0, $width-$stripewidth, $height);
+	gimp_edit_copy ($rimage, $rdraw);
+	
+	my $imagelayer = gimp_layer_new ($image, $width, $height, RGB_IMAGE, 
+					 "ImageLayer", $i_transparency, NORMAL_MODE);
+	
+	gimp_image_add_layer ($image, $imagelayer, 0);
+	
+	# clear the new layer
+	gimp_selection_all ($image);
+	gimp_edit_clear ($image, $imagelayer);
+	gimp_selection_none ($image);
+	
+	my $flayer = gimp_edit_paste ($image, $imagelayer, 1); 
+	if ($stripe_alignment eq "left") {
+	    gimp_layer_set_offsets($flayer, $stripewidth, 0);
+	    gimp_layer_set_offsets($imagelayer, $stripewidth, 0);
+	} else {
+	    gimp_layer_set_offsets($flayer, 0, 0);
+	    gimp_layer_set_offsets($imagelayer, 0, 0);
+	}
+    }
+	
+    # set colour of text
+    gimp_palette_set_foreground ($fontcolor);
+	
+    # set the text if there is any
+    my ($textlayer, $textheight, $textwidth);
+    my $fsize = $fontsize;
+    if (length($text)) {
+	$text =~ s/\\n/\n/gi;
+
+	while (1) {
+	    $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1, $fsize, 
+				    PIXELS, $foundry, $fontname, $fontweight, $fontslant, 
+				    $fontwidth, $fontspacing);
+	    
+	    # check that text fits within image
+	    $textwidth = gimp_drawable_width($textlayer);
+	    $textheight = gimp_drawable_height($textlayer);
+	    if ((($textwidth + $textspace_x) > $width) || 
+		(($textheight + $textspace_y) > $height)) {
+		if ($fsize < $minfontsize) {
+		    die "Error (title_icon.pl): text '$text' doesn't fit on ${width}x${height} image " .
+			"(minimum font size tried: $minfontsize\n";
+		} else {
+		    gimp_selection_all ($image);
+		    gimp_edit_clear ($image, $textlayer);
+		    gimp_selection_none ($image);
+		    $fsize --;
+		    print STDERR "WARNING (title_icon.pl): '$text' doesn't fit: reducing font size to $fsize\n";
+		}
+	    } else {
+		last;
+	    }
+	}
+	
+	# align text
+	if ($text_alignment eq "left") {
+	    gimp_layer_set_offsets ($textlayer, $textspace_x, $textspace_y);
+	} else {
+	    gimp_layer_set_offsets ($textlayer, ($width-$textwidth)-$textspace_x, $textspace_y);
+	}
+    }
+    
+    # flatten the image
+    my $finishedlayer = gimp_image_flatten ($image);
+	
+    if ($filename =~ /\.gif$/i) {
+	# make indexed colour (may need to do this for 
+	# other formats as well as gif)
+	gimp_convert_indexed ($image, 0, 256);
+    }
+	
+    # save image
+    my $filename = &util::filename_cat ($image_dir, $filename);
+    if ($filename =~ /\.jpe?g$/i) {
+	# gimp_file_save doesn't appear to work properly for jpegs
+	file_jpeg_save (RUN_NONINTERACTIVE, $image, $finishedlayer, 
+			$filename, $filename, 0.8, 0, 1);
+    } else {
+	gimp_file_save (RUN_NONINTERACTIVE, $image, $finishedlayer, 
+			$filename, $filename);
+    }
+}
+
+# returns 1 if this is the last entry,
+sub read_config_entry {
+    my ($handle) = @_;
+
+    my $line = "";
+    while (defined ($line = <$handle>)) {
+	next unless $line =~ /\w/;
+	my @line = ();
+	if ($line =~ /^\-+/) {return 0;}
+	$line =~ s/^\#.*$//;   # remove comments
+	$line =~ s/\cM|\cJ//g; # remove end-of-line characters
+	$line =~ s/^\s+//;     # remove initial white space
+	while ($line =~ s/\s*(\"[^\"]*\"|\'[^\']*\'|\S+)\s*//) {
+	    if (defined $1) {
+		# remove any enclosing quotes
+		my $entry = $1;
+		$entry =~ s/^([\"\'])(.*)\1$/$2/;
+
+		# substitute any environment variables
+		$entry =~ s/\$(\w+)/$ENV{$1}/g;
+		$entry =~ s/\$\{(\w+)\}/$ENV{$1}/g;
+		
+		push (@line, $entry);
+	    } else {
+		push (@line, "");
+	    }
+	}
+	if (scalar (@line) == 2 && defined ${$line[0]}) {
+	    ${$line[0]} = $line[1];
+	}
+    }
+    return 1;
+}
+
+# adjust arguments that are effected by the size argument
+sub adjust_args {    
+
+    if ($size != 1) {
+	my @size_args = ('width', 'height', 'imageheight', 'stripewidth',
+			 'textspace_x', 'textspace_y', 'fontsize', 'minfontsize');
+	foreach $arg (@size_args) {
+	    $$arg = int ($$arg * $size);
+	}
+    }
+}
+
+sub wrap_text {
+
+    # don't wrap text if it already contains carriage returns
+    return if $text =~ /\n/;
+
+    # the following assumes that all words are less than $wrap_length long
+    my $wrap_length = 14;
+
+    my $new_text = "";
+    while (length ($text) >= $wrap_length) {
+	my $line = substr ($text, 0, $wrap_length);
+	$text =~ s/^$line//;
+	$line =~ s/\s([^\s]*)$/\n/;
+	$text = $1 . $text;
+	$new_text .= $line;
+    }
+    $new_text .= $text;
+    $text = $new_text;
+}
+    
+sub query {
+
+  gimp_install_procedure("gsdl_title_icon", "create title icons for gsdl",
+                        "", "Stefan Boddie", "Stefan Boddie", "2000-03-10",
+                        "<Toolbox>/Xtns/gsdl_title_icon", "*", &PROC_EXTENSION,
+                        [[PARAM_INT32, "run_mode", "Interactive, [non-interactive]"]], []);
+}
+
+sub net {
+  gsdl_title_icon;
+}
+
+exit main;
+
Index: /gsdl/stable/bin/script/gimp/title_icon_g12.pl
===================================================================
--- /gsdl/stable/bin/script/gimp/title_icon_g12.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gimp/title_icon_g12.pl	(revision 20131)
@@ -0,0 +1,380 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# title_icon.pl
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# title_icon.pl
+#
+# This script generates collection title icons for greenstone.
+#
+# This version has been rewritten for the GIMP Version 1.2.  You
+# should be able to run it if you install gimp 1.2 with perl support.
+# In Debian this means running "apt-get install gimp1.2 gimp1.2perl"
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use Gimp ":auto";
+use Gimp::Fu; 
+
+use util;
+use unicode;
+
+# set trace level to watch functions as they are executed
+#Gimp::set_trace(TRACE_ALL);
+#Gimp::set_trace(TRACE_CALL);
+
+my $gsdl_green = "#96c19b";
+my $black = "#000000";
+my $white      = "#FFFFFF";
+
+my ($current_dir) = `pwd`;
+chomp($current_dir);
+
+
+my ($text, $filename, $image_dir, $size, $width, $height,
+    $stripecolor, $stripewidth, $stripe_alignment, $textspace_x,
+    $textspace_y, $dont_wrap, $imagefile, $imageheight, $i_transparency,
+    $bgcolor, $fontcolor, $fontsize, $minfontsize, $text_alignment,
+    $foundry, $fontname, $fontweight, $fontslant, $fontwidth,
+    $fontspacing, $cfg_file);
+
+sub reset_options {
+    $image_dir = "./";
+    $imagefile = "";
+    $width = int (150 * $size);
+    $height = int (44 * $size);
+    $imageheight = int (110 * $size);
+    $stripecolor = $gsdl_green;
+    $stripewidth = int (40 * $size);
+    $stripe_alignment = "left";
+    $i_transparency = 60;
+    $text = "";
+    $text_alignment = "left";
+    $filename = "";
+    $textspace_x = int (3 * $size);
+    $textspace_y = int (3 * $size);
+    $bgcolor = $gsdl_green;
+    $fontcolor = $black;
+    $fontsize = int (17 * $size);
+    $minfontsize = int (10 * $size);
+    $foundry = "*";
+    $fontname = "lucida";
+    $fontweight = "medium";
+    $fontslant = "r";
+    $fontwidth = "*";
+    $fontspacing = "*";
+}
+
+sub gsdl_title_icon {
+
+    ($text, $filename, $image_dir, $size, $width, $height,
+     $stripecolor, $stripewidth, $stripe_alignment, $textspace_x,
+     $textspace_y, $dont_wrap, $imagefile, $imageheight, $i_transparency,
+     $bgcolor, $fontcolor, $fontsize, $minfontsize, $text_alignment,
+     $foundry, $fontname, $fontweight, $fontslant, $fontwidth,
+     $fontspacing, $cfg_file) = @_;
+
+    # Create images using a configuration file
+    if ($cfg_file =~ /\w/) {
+	
+	open (CONF, $cfg_file) || die "couldn't open cfg_file $cfg_file\n";
+	while (1) {
+
+	    &reset_options ();
+	
+	    # read image configuration entry
+	    my $status = &read_config_entry (CONF);
+	    if ($filename !~ /\w/) {
+		if ($status) {last;}
+		else {next;}
+	    }
+	    &produce_image ();
+	    if ($status) {last;}
+	}
+	close CONF;
+    }
+
+    # Create a single image from the parameters we have
+    else {
+	&produce_image ();
+    }
+
+}
+
+sub produce_image {
+
+    &adjust_args ();
+    &wrap_text () unless $dont_wrap;
+
+    my $use_image = 0;
+    if ($imagefile =~ /\w/) {
+	if (!-r $imagefile) {
+	    print STDERR "WARNING (title_icon.pl): imagefile '$imagefile cannot be ";
+	    print STDERR "read - $filename will be created without the use of an image file\n";
+	} else {
+	    $use_image = 1;
+	    $height = $imageheight;
+	}
+    }
+
+    # create the image
+    my $image = gimp_image_new ($width, $height, RGB_IMAGE);
+	
+    # create and add the background layer
+    my $backlayer = gimp_layer_new ($image, $width, $height, RGB_IMAGE, 
+				    "BGLayer", 100, NORMAL_MODE);
+    gimp_image_add_layer ($image, $backlayer, 0);
+	
+    # clear the background
+    gimp_selection_all ($image);
+    gimp_edit_clear ($backlayer);
+    gimp_selection_none ($image);
+	
+    # fill in stripe
+    if ($stripewidth > 0) {
+        gimp_palette_set_foreground ($stripecolor);
+	if ($stripe_alignment eq "left") {
+	  gimp_rect_select ($image, 0, 0, $stripewidth, $height, 0, 0, 0);
+	} else {
+	  gimp_rect_select ($image, $width-$stripewidth, 0, $stripewidth, $height, 0, 0, 0);
+	}
+	gimp_bucket_fill ($backlayer, FG_BUCKET_FILL, NORMAL_MODE, 100, 0, 1, 0, 0);
+	gimp_selection_none ($image);
+    }
+
+    # get image file (image goes on opposite side to stripe)
+    if ($use_image) {
+	my $rimage = gimp_file_load (RUN_NONINTERACTIVE, $imagefile, $imagefile);
+	my $rdraw = gimp_image_active_drawable ($rimage);
+	gimp_scale ($rdraw, 1, 0, 0, $width-$stripewidth, $height);
+	gimp_edit_copy ($rdraw);
+	
+	# add the background image layer
+	my $imagelayer = gimp_layer_new ($image, $width, $height, RGB_IMAGE, 
+					 "ImageLayer", $i_transparency, NORMAL_MODE);
+	gimp_image_add_layer ($image, $imagelayer, 0);
+	
+	# clear the new layer
+	gimp_selection_all ($image);
+	gimp_edit_clear ($imagelayer);
+	gimp_selection_none ($image);
+	
+	my $flayer = gimp_edit_paste ($imagelayer, 1); 
+	if ($stripe_alignment eq "left") {
+	    gimp_layer_set_offsets($flayer, $stripewidth, 0);
+	    gimp_layer_set_offsets($imagelayer, $stripewidth, 0);
+	} else {
+	    gimp_layer_set_offsets($flayer, 0, 0);
+	    gimp_layer_set_offsets($imagelayer, 0, 0);
+	}
+    }
+
+    # flatten the image (otherwise the text will be "behind" the image)
+    $backlayer = gimp_image_flatten ($image);
+
+    # set colour of text
+    gimp_palette_set_foreground ($fontcolor);
+	
+    # set the text if there is any
+    my ($textlayer, $textheight, $textwidth);
+    my $fsize = $fontsize;
+    if (length($text)) {
+	$text =~ s/\\n/\n/gi;
+
+	while (1) {
+	    $textlayer = gimp_text ($image, $backlayer, 0, 0, $text, 0, 1, $fsize, 
+				    PIXELS, $foundry, $fontname, $fontweight, $fontslant, 
+				    $fontwidth, $fontspacing, "*", "*");
+	
+	    # check that text fits within image
+	    $textwidth = gimp_drawable_width($textlayer);
+	    $textheight = gimp_drawable_height($textlayer);
+	    if ((($textwidth + $textspace_x) > $width) || 
+		(($textheight + $textspace_y) > $height)) {
+		if ($fsize < $minfontsize) {
+		    die "Error (title_icon.pl): text '$text' doesn't fit on ${width}x${height} image " .
+			"(minimum font size tried: $minfontsize\n";
+		} else {
+		    gimp_selection_all ($image);
+		    gimp_edit_clear ($image, $textlayer);
+		    gimp_selection_none ($image);
+		    $fsize --;
+		    print STDERR "WARNING (title_icon.pl): '$text' doesn't fit: reducing font size to $fsize\n";
+		}
+	    } else {
+		last;
+	    }
+	}
+	
+	# align text
+	if ($text_alignment eq "left") {
+	    gimp_layer_set_offsets ($textlayer, $textspace_x, $textspace_y);
+	} else {
+	    gimp_layer_set_offsets ($textlayer, ($width-$textwidth)-$textspace_x, $textspace_y);
+	}
+    }
+
+    # flatten the image
+    my $finishedlayer = gimp_image_flatten ($image);
+	
+    if ($filename =~ /\.gif$/i) {
+	# make indexed colour (may need to do this for 
+	# other formats as well as gif)
+	gimp_convert_indexed ($image, 0, 256);
+    }
+	
+    # save image
+    my $filename = &util::filename_cat ($image_dir, $filename);
+    gimp_file_save (RUN_NONINTERACTIVE, $image, $finishedlayer, $filename, $filename);
+}
+
+# returns 1 if this is the last entry,
+sub read_config_entry {
+    my ($handle) = @_;
+
+    my $line = "";
+    while (defined ($line = <$handle>)) {
+	next unless $line =~ /\w/;
+	my @line = ();
+	if ($line =~ /^\-+/) {return 0;}
+	$line =~ s/^\#.*$//;   # remove comments
+	$line =~ s/\cM|\cJ//g; # remove end-of-line characters
+	$line =~ s/^\s+//;     # remove initial white space
+	while ($line =~ s/\s*(\"[^\"]*\"|\'[^\']*\'|\S+)\s*//) {
+	    if (defined $1) {
+		# remove any enclosing quotes
+		my $entry = $1;
+		$entry =~ s/^([\"\'])(.*)\1$/$2/;
+
+		# substitute any environment variables
+		$entry =~ s/\$(\w+)/$ENV{$1}/g;
+		$entry =~ s/\$\{(\w+)\}/$ENV{$1}/g;
+		
+		push (@line, $entry);
+	    } else {
+		push (@line, "");
+	    }
+	}
+	if (scalar (@line) == 2 && defined ${$line[0]}) {
+	    ${$line[0]} = $line[1];
+	}
+    }
+    return 1;
+}
+
+# adjust arguments that are effected by the size argument
+sub adjust_args {
+
+    if ($size != 1) {
+        $width *= $size;
+        $height *= $size;
+	$imageheight *= $size;
+	$stripewidth *= $size;
+	$textspace_x *= $size;
+	$textspace_y *= $size;
+	$fontsize *= $size;
+	$minfontsize *= $size;
+    }
+}
+
+sub wrap_text {
+
+    # don't wrap text if it already contains carriage returns
+    return if $text =~ /\n/;
+
+    # the following assumes that all words are less than $wrap_length long
+    my $wrap_length = 14;
+
+    my $new_text = "";
+    while (length ($text) >= $wrap_length) {
+	my $line = substr ($text, 0, $wrap_length);
+	$text =~ s/^$line//;
+	$line =~ s/\s([^\s]*)$/\n/;
+	$text = $1 . $text;
+	$new_text .= $line;
+    }
+    $new_text .= $text;
+    $text = $new_text;
+}
+
+
+register("gsdl_title_icon", 
+	 "Create title icons for gsdl (gimp version 1.2)",
+	 "", 
+	 "Stefan Boddie (1.0) and Gordon Paynter (1.2)",
+	 "Copyright 1999-2001 The New Zealand Digital Library Project",
+	 "2000-03-10",
+	 "<Toolbox>/Xtns/gsdl_title_icon", 
+	 "*",
+	 [
+           [PF_STRING, "text",      "Text appearing on icon", "greenstone collection"],
+
+           [PF_STRING, "filename",  "Output file", "title_icon.png"],
+           [PF_STRING, "image_dir", "Directory to create images in", $current_dir],
+
+           [PF_INT,    "size_ratio", "Size factor: a factor of 2 doulbles image size",  1],
+           [PF_INT,    "width",      "Width of the icon",  150],
+           [PF_INT,    "height",     "Height of the icon", 44],
+
+           [PF_STRING, "stripecolor", "Colour of the stripe", $gsdl_green],
+           [PF_INT,    "stripewidth", "Width of the stripe",  40],
+           [PF_STRING, "stripealign", "Alignment of stripe (left or right)", "left"],
+
+           [PF_INT,    "text_x_offset",    "Distance from left of image to text", 3],
+           [PF_INT,    "text_y_offset",    "Distance from top of image to text",  3],
+           [PF_STRING, "dont_wrap",        "don't attempt to wrap text", ""],
+
+           [PF_STRING, "imagefile",   "Filename of background image", ""],
+           [PF_INT,    "imageheight", "Height of background image", 110],
+           [PF_INT,    "imagetransp", "Transparency of background image (1-100)", 60],
+
+#           [PF_STRING, "fgcolor",     "Foreground colour (top) of bar", $white],
+           [PF_STRING, "bgcolor",     "Background colour (bottom) of bar", $gsdl_green],
+           [PF_STRING, "fontcolor",   "Colour of text on bar", $black],
+           [PF_INT,    "fontsize",    "Font size",    17],
+           [PF_INT,    "minfontsize", "Minimum font size if scaling required",    10],
+
+           [PF_STRING, "alignment",     "Alignment of text on the icon (left or right)", "left"],
+
+           [PF_STRING, "foundry",     "Font foundry", "*"],
+           [PF_STRING, "fontname",    "Font name",    "lucida"],
+           [PF_STRING, "fontweight",  "Font weight",  "medium"],
+           [PF_STRING, "fontslant",   "Font slant",   "r"],
+           [PF_STRING, "fontwidth",   "Font width",   "*"],
+           [PF_STRING, "fontspacing", "Font spacing", "*"],
+
+           [PF_STRING, "cfg_file",    "Configuration file", ""]
+
+         ], 
+         \&gsdl_title_icon);
+
+
+exit main;
+
+
Index: /gsdl/stable/bin/script/grab_collection.pl
===================================================================
--- /gsdl/stable/bin/script/grab_collection.pl	(revision 20131)
+++ /gsdl/stable/bin/script/grab_collection.pl	(revision 20131)
@@ -0,0 +1,570 @@
+#!/usr/bin/perl -w
+
+
+# Both this script and its associated process_html.pl were written by
+# Marcel ?, while a student at Waikato University. Unfortunately he
+# was very new to perl at the time so the code is neither as clean nor
+# as fast as it could be (I've cleaned up a few of the more serious
+# bottlenecks -- it could do with alot more work though).  The code
+# does work though, if a little slowly. It's not ready for primetime
+# however and is included in the Greenstone source tree mostly so that
+# I don't lose it. -- Stefan - 24 Jul 2001
+
+
+# This script will download an entire collection (and its associated pictures and files) 
+# and store them in a temporary directory ($outputdir). 
+# A second script (process_html.pl) can be then be used to 'rebuild' the collection and link all the
+# downloaded pages and pictures together into a usable static collection.
+
+# This script will generate a number of text files required by the second script
+# and for possible recovery, namely:
+# - links.txt        - contains all the http links that were downloaded
+# - images.txt       - contains a list of all the images that were downloaded  
+# - image_dirs.txt   - contains a list of all the image-prefixes that need to be wiped from the html files
+#                      (otherwise you won't get to see any pictures)
+
+# Both this script and the html processing script have a recovery feature built in, they can continue from wherever
+# they left off, but this only works if $outputdir and $finaldir are set to different values.
+   
+# This is where all the downloaded html files end up, eg. 'temp_html/'
+my $outputdir  = 'temp_html/';
+# This is where all the processed html files (and the pictures) will end up eg. 'my_static_collection/'
+my $finaldir   = 'envl_collection/';
+
+# This is where we start our mirroring
+$address = 'http://nowhere.com/cgi-bin/library?a=p&p=about&c=demo&u=1';
+
+
+# whatever is specified in $option will be attached to the end of each html link before it is downloaded.
+# eg. "&u=1" to disable various features in the greenstone collections that are not needed with a static
+#            collection.
+# another example : "&l=nl" to set the entire collection to dutch (NetherLands :)  
+my $option = "&u=1";
+
+# Most OS have a limit on the maximum amount of files per directory (or folder).
+# A static collection can easily contain >3000 html files. Putting all those files
+# into one single directory is just asking for trouble. It's also very unwieldy ;^)
+# Hence...this value will set how much html files will be stored in one directory. 
+# These directories themselves will be numbered, 
+# so if $dir_entries = 500 then the directories will be "0/", "500/", "1000/", "1500/", "2000/", etc. 
+my $dir_entries = 250;
+
+# Occasionally a page occurs which contains no data (because &cl is not set) This option fixes that. 
+my $fix_empty_pages = "&cl=CL1";
+
+# These are the files that wget will download.
+# more can be added if necessary.
+my @graphic_formats = ('.gif','.jpg','.bmp','.png','.pdf','.mov','.mpeg','.jpeg','.rm');
+
+# ---------------------------------------[ System specific options ]----------------------------------------------------
+
+# The lynx variable specifies the command line for the lynx web browser
+# -- This is what I use under dos/win32
+# my $lynx = 'e:\lynx_w32\lynx -cfg=e:\lynx_w32\lynx.cfg';
+
+# -- This is what I use under linux
+my $lynx = 'lynx';
+
+# and the same for the wget utility
+my $wget = 'wget';
+
+# NB: There is one other linux specific command all the way at the end of this script, where I've used 'cp' to copy a file.       
+
+# Another NB: When saving the dl-ed html files to disk, I've set lynx to dump the html-source to the standard output,
+#             which I then simply redirect to a target file, BUT
+#             this does not work under DOS/win32. Redirecting standard output in a script causes it to be displayed on
+#             the screen instead. The easiest way to get around this I found was by doing the actual redirection in a simple
+#             batch file (say grab.bat), which contains the following line:
+#             @e:\lynx_w32\lynx -cfg=e:\lynx_w32\lynx.cfg -dump -source "%1" > %2 
+#
+#             Then replace line nr 326 -> 'system ("$kommand > $target");' with 'system("grab.bat $address $target");'
+#             Not a very elegant solution, but it works :) 
+
+#------------------------------------------------------------------------------------------------------------------------
+
+my %image_list;
+my $image_pointer = 0;
+
+my %linkz_list;
+my %short_linkz_list;
+my $linkz_pointer = 0;
+
+my %image_dirs_list;
+my $image_dirs_pointer = 0;
+
+my $numberdir = 0;
+
+my $start_time = (times)[0];
+
+# check if directories exist and create them if necessary..
+if ((-e $outputdir)&&(-d $outputdir)) 
+{ 
+    print " ** ",$outputdir," directory already exists..\n"; 
+}
+else
+{
+    print " ** Creating ",$outputdir," directory..\n";
+    mkdir($outputdir, 0777) or die " Cannot create output directory: $!\n";
+}
+
+if ((-e $finaldir)&&(-d $finaldir))
+{ 
+    print " ** ",$finaldir," directory already exists..\n";
+}
+else
+{
+    print " ** Creating ",$finaldir," directory..\n";
+    mkdir($finaldir, 0777) or die " Cannot create final directory: $!\n";
+}
+
+#-----------------------------------------------------------------------------------------------
+# No need to start from scratch everytime, we can recover/continue from wherever we left off
+# simply by checking which html files have been created
+#-----------------------------------------------------------------------------------------------
+
+$linknumber    = 0;                    # used to name/number the dl-ed html files
+
+my $failed     = 0;
+while ($failed == 0)
+{
+    if ($linknumber % $dir_entries == 0) 
+	{
+	    if (!((-e $outputdir.$linknumber)&&(-d $outputdir.$linknumber)))
+	    {
+		$failed++;
+		mkdir($outputdir.$linknumber, 0777) or print " ** Cannot create ",$outputdir.$linknumber, "!: $!\n";
+	    }
+	    $numberdir = $linknumber;
+	}
+
+    $check_file = $outputdir.$numberdir."/".$linknumber.".html";
+    if ((-e $check_file)&&($failed == 0)) 
+    { 
+	$linknumber++;
+    } 
+    else
+    {
+	$failed++;
+	# I'm subtracting 1 from the starting link, 
+	# just in case it only loaded half the page ;^)
+	if($linknumber>0) 
+	{ 
+	    $linknumber--; 
+	}
+	print " Will start downloading at number $linknumber \n";
+    }
+}
+
+# if we're starting from scratch, then we might as well nuke the links file
+#if ($linknumber == 0) 
+#{ 
+#    print " Starting from scratch - clobbering the old text files...\n";
+#    if (-e 'links.txt')
+#    {
+#	print "   Removing links.txt...\n";   
+#	unlink <links.txt> or print " ** Cannot delete links textfile: $!\n";
+#    }
+#    if (-e 'images.txt')
+#    {
+#	print "   Removing images.txt...\n";
+#	unlink <images.txt> or print " ** Cannot delete images textfile: $!\n";
+#    }
+#    if (-e 'image_dirs.txt')
+#    {
+#	print "   Removing image_dirs.txt...\n";
+#	unlink <image_dirs.txt> or print " ** Cannot delete image_dirs textfile: $!\n";
+#    }
+#}
+
+# if we're NOT starting from scratch, then read in old links from links text file
+# and grab the old image-links as well...
+if ($linknumber != 0)
+{
+    # load the old links from links.txt, if it doesn't exist, then give up :(
+    my $this = "";
+    my $that = "";
+    open (CHECK, "links.txt") or die " ** Cannot find/open links.txt file!: $! **\n";
+    while(eof CHECK == 0)
+    {
+	while($this ne "\n")
+	{
+	    read CHECK, $this ,1;
+	    $that = $that.$this;   
+	}
+	$linkz_list[$linkz_pointer] = $that;
+	
+	for my $search(0 .. (length($that) - 3))
+	{
+	    if((substr($that, $search, 3) eq '?a=')||(substr($that, $search, 3) eq '&a='))
+	    {
+		$short_linkz_list[$linkz_pointer] = substr($that, $search);
+		last;
+	    }
+	}
+	$linkz_pointer++;
+	$that = ""; $this = "";
+    }
+    close(CHECK);
+    print "- I found ",($#linkz_list + 1)," links in links.txt -\n";
+    
+    #make sure that we start dl-ing the correct first page 
+    $address = $linkz_list[$linknumber];
+
+    # load the old image links from image.txt (if it doesn't exist, no big deal ;)
+    my $im_this = "";
+    my $im_that = "";
+    open (IMAGES, "images.txt") || print " ** Cannot find/open images.txt file! : $! **\n";
+    while(eof IMAGES == 0)
+    {
+	while($im_this ne "\n")
+	{
+	    read IMAGES, $im_this ,1;
+	    $im_that = $im_that.$im_this;   
+	}
+	$image_list[$image_pointer] = $im_that;
+	$image_pointer++;
+	$im_that = ""; $im_this = "";
+    }
+    close(IMAGES);
+    print "- I found ",($#image_list + 1)," picture-links in images.txt -\n";
+
+    #..and last but not least, load any image_dirs from image_dirs.txt
+    # again, if its not there, no big deal :)
+    my $imd_this = "";
+    my $imd_that = "";
+    open (IMAGE_DIR, "image_dirs.txt") || print " ** Cannot find/open image_dirs.txt file!: $! **\n";
+    while(eof IMAGE_DIR == 0)
+    {
+	while($imd_this ne "\n")
+	{
+	    read IMAGE_DIR, $imd_this ,1;
+	    $imd_that = $imd_that.$imd_this;   
+	}
+	$image_dirs_list[$image_dirs_pointer] = $imd_that;
+	$image_dirs_pointer++;
+	$imd_that = ""; $imd_this = "";
+    }
+    close(IMAGE_DIR);
+    print "- I found ",($#image_dirs_list + 1)," picture directories in image_dirs.txt -\n";
+}
+
+#  Just keep going till we can find no more new links
+while(($#linkz_list < 0)||($#linkz_list+1 > $linknumber)) 
+{
+
+    # This line specifies the command line for the lynx web browser
+    my $kommand = $lynx.' -dump -image_links "'.$address.'"';
+
+    # dump page into text-array and find starting-point of the references/links
+    chomp(@data=`$kommand`);
+    for my $i(0 .. $#data)
+    {
+	if ($data[$i] eq "References") {
+	    $here = $i;}
+    }
+    $here = $here+2;
+
+    # process references/links
+    for $i($here .. $#data){
+
+	$its_an_image = 0;	     	
+    
+	#chop-off refs leading number&spaces (eg. '1. http://www.cs.waikato.ac.nz')
+	#                                          ^^^
+	
+#	$temp = substr($data[$i],3);
+#	@temp = split(/ /, $temp, 2);
+    
+	#check if the last 4 characters of the link equal .gif .jpg .png .bmp .pdf .mov .mpeg etc etc
+    
+#	for my $g(0 .. $#graphic_formats)
+#	{
+#	    if(substr($temp[1],(length($graphic_formats[$g]) * -1)) eq $graphic_formats[$g])
+#	    {
+#		$its_an_image = 1;
+#	    }
+#	}
+
+	$data[$i] =~ s/^\s*\d+\.\s+//;
+	if ($data[$i] =~ /\.(gif|jpe?g|png|bmp|pdf|mov|mpe?g|rm)$/i) {
+	    $its_an_image = 1;
+	}
+
+	# ignore mailto urls
+	if ($data[$i] !~ /mailto:/i) {
+	
+	    #----------- the link is NOT an image ----------------		
+	    if ($its_an_image == 0)
+	    { 
+		&its_a_link($data[$i], $outputdir);
+	    }
+
+	    #----------- the link IS an image ----------------
+	    if ($its_an_image != 0)
+	    { 
+		&its_an_image($data[$i], $finaldir); 
+	    }
+	}
+    }	
+
+    # save the web page to disk (in the appropriate numbered directory)
+    $kommand = $lynx.' -dump -source "'.$address.'"';
+
+    if ($linknumber % $dir_entries == 0) 
+    {
+	if ((-e $outputdir.$linknumber)&&(-d $outputdir.$linknumber))
+	{
+	    print " ** ",$outputdir.$linknumber, " - Directory allready exists.\n";
+	}
+	else
+	{
+	    mkdir($outputdir.$linknumber, 0777) or print " ** Cannot create ",$outputdir.$linknumber, "!: $!\n";
+	    mkdir($finaldir.$linknumber, 0777)  or print " ** Cannot create ",$outputdir.$linknumber, "!: $!\n";
+	}
+	$numberdir = $linknumber;
+    }
+    my $target = $outputdir.$numberdir."/".$linknumber.".html";
+
+    #---------------------------------------------------------------------------------------------------------------
+    # NOTE: This next command will NOT work under win32/dos, as redirecting standard output in a script causes it to
+    #       be dumped straight to the screen as opposed to into the target file.
+    #---------------------------------------------------------------------------------------------------------------
+    system ("$kommand > $target");
+    #---------------------------------------------------------------------------------------------------------------
+
+    print " Saved $target\n";
+
+    $linknumber++;
+
+    $address = $linkz_list[$linknumber];
+}
+
+my $end_time = (times)[0];
+
+print "\n\n\n *----------------------------*\n";
+print " |  Whew! Task completed! :-D |\n";
+print " *----------------------------*\n";
+printf"  Script took %.2f CPU seconds to complete ;^)\n", $end_time - $start_time;
+print "\n\n"; 
+print "  Now execute the  process_html.pl  script to link the downloaded collection together.\n";
+print "  Please do make sure that it is executed with the same options as this script ;-)\n";
+
+sub its_a_link 
+{
+    local($found) = @_;
+#    local($ok = 0, $kommand);
+    local($kommand);
+    local $short_link = "";
+
+    return if ($found =~ /\#.*$/);
+
+    # attach the custom options
+    $found .= $option;
+    
+    #little bit of trickery here - check if there is a &d= option present in the link
+    #if there is, then wipe the &cl= option!
+    #This should cut down multiple copies by 75%!!
+    
+    #but, if there is no &d option, and the &cl option is not set, then we have to set the &cl option to something
+    #otherwise we get pages which contain no data :\
+
+    if ($found =~ /[&\?]a=d/) {
+	if ($found =~ /[&\?]d=/) {
+	    $found =~ s/[&\?]cl=[^&]*//;
+	} elsif ($found !~ /[&\?]cl=/) {
+	    $found .= $fix_empty_pages;
+	}
+    }
+
+    # we also want to sort out any xxx.pr OIDs that we come across
+    $found =~ s/([&\?](cl|d)=.*?)\.\d+\.pr/$1/g;
+
+    # attach the EOL character.
+    $found = $found."\n";
+
+
+    # the hard way !!!
+#    for my $search(0 .. (length($found) - 3))
+#    {
+#	if((substr($found, $search, 3) eq '?d=')||(substr($found, $search, 3) eq '&d='))
+#	{
+#	    for my $second_search(0 .. (length($found) - 4))  
+#	    {
+#		if((substr($found, $second_search, 4) eq '?cl=')||(substr($found, $second_search, 4) eq '&cl='))
+#		{
+#		    for my $third_search(($second_search + 3) .. (length($found) - 1))
+#		    {
+#			if((substr($found, $third_search, 1)) eq '&')
+#			{
+#			    substr($found, $second_search, $third_search - $second_search) = ""; 
+#			    last;
+#			}
+#		    }
+#		    last;
+#		}
+#	    } 
+#	    last;
+#	}
+#	else
+#	{
+#	    if( $search == (length($found) - 3))
+#	    {
+#		for my $second_search(0 .. (length($found) - 4))  
+#		{
+#		    if((substr($found, $second_search, 4) eq '?cl=')||(substr($found, $second_search, 4) eq '&cl='))
+#		    {
+#			for my $third_search(($second_search + 3) .. (length($found) - 1))
+#			{
+#			    if((substr($found, $third_search, 1)) eq '&')
+#			    {
+#				if (substr($found, $second_search, $third_search - $second_search) eq '&cl=')
+#				{
+#				    substr($found, $second_search, $third_search - $second_search) = $fix_empty_pages;	
+#				}
+#				last;
+#			    }
+#			}
+#			last;
+#		    }
+#		} 
+#	    }
+#	}
+#    }
+    
+    # grab the last part of the link (ignoring the start and the &e option)
+#    for my $search(0 .. (length($found) - 3))
+#    {
+#	if((substr($found, $search, 3) eq '?a=')||(substr($found, $search, 3) eq '&a='))
+#	{
+#	    $short_link = substr($found, $search);
+#	    last;
+#	}
+#    }
+
+    ($short_link) = $found =~ /\?(.*)$/;
+    $short_link =~ s/(^|&)e=[^&]*/$1/;
+
+    
+    # this filters out multiple copies of for example the help page, which has #something at the end of its links
+    # now do this first with regular expression above -- Stefan
+
+#    for my $search(0 .. length($found))
+#    {
+#	if ((substr($found, $search, 1)) eq '#')
+#	{
+#	    $ok++;
+#	    last;
+#	}
+#    }
+ 
+
+   
+    # compare the found link to the links we've stored in the arrays (compares both full link and partial link)
+    for my $search(0 .. $#linkz_list)
+    {
+	return if ($found eq $linkz_list[$search]);
+	return if ($short_link eq $short_linkz_list[$search]);
+    }
+		    
+    # if found link is not in links array, add it
+    open (DUMP, ">>links.txt") or die " ** Can't open links.txt!: $!\n";
+    print DUMP $found;
+    close(DUMP);
+    
+    $linkz_list[$linkz_pointer] = $found;
+    $short_linkz_list[$linkz_pointer] = $short_link;
+    $linkz_pointer++;
+}
+
+sub do_image_dirs
+{
+    local($found) = @_;
+    my $count = 0;
+    my @br_index;
+    my $image_dir = "";
+    my $new_dir = 0;
+
+    for my $search(1 .. (length($found) - 1 ))
+    {
+	$bracket = substr($found, ($search * - 1), 1);
+	if ($bracket eq '/')
+	{
+	    $count++;
+	    $br_index[$count] = $search;
+	}
+	if($count == 2) 
+	{
+	    $image_dir = substr($found, ($br_index[2] * -1) , ($br_index[2] - $br_index[1]));
+	}
+    }
+    
+    my $dirs_to_wipe = substr($found, $br_index[$#br_index - 2] * - 1, $br_index[$#br_index - 2] - $br_index[2] + 1)."\n";
+    
+    for my $counter(0 .. $#image_dirs_list)
+    {
+	if($dirs_to_wipe eq $image_dirs_list[$counter])
+	{
+	    $new_dir++;
+	}
+    }
+    
+    if ($new_dir == 0)
+    {
+	open (IMAGE_DIRS, ">>image_dirs.txt") or die " ** Can't open image_dirs.txt!: $!\n";
+	print IMAGE_DIRS $dirs_to_wipe;
+	close(IMAGE_DIRS);
+	$image_dirs_list[$image_dirs_pointer] = $dirs_to_wipe;
+	$image_dirs_pointer++;
+    }
+
+    print "   ",substr($finaldir, 0 ,length($finaldir) - 1).$image_dir.substr($found, ($br_index[1] * - 1), length($found) - (length($found) - $br_index[1])),"\n";	    
+    
+    return $image_dir;
+}
+
+sub its_an_image 
+{
+    local($found, $outpdir) = @_;
+    local($kommand);
+    my $new = 0;
+    
+    my $temp_found = $found . "\n";
+
+    # check if the image is in the list
+    for my $counter(0 .. $#image_list)
+    {
+	if($temp_found eq $image_list[$counter])
+	{
+	    $new++;
+	}
+    }
+    
+    # only download the image if its not in the list..
+    if($new == 0)
+    {    
+	my $image_dir = &do_image_dirs;
+	my $temp_outputdir = $outpdir;
+	if (substr($temp_outputdir, -1, 1) eq "/")
+	{
+	    substr($temp_outputdir, -1, 1) = "";
+	}
+	
+	# wget is set to 'q - quiet' and 'nc - dont clobber existing files'
+	$kommand = $wget.' -qnc --directory-prefix='.$temp_outputdir.$image_dir.' "'.$found.'"';
+	system ("$kommand");
+        
+	open (IMAGES, ">>images.txt") or die " ** Can't open images.txt!: $!\n";
+	print IMAGES $temp_found;
+	close(IMAGES);
+	
+	$image_list[$image_pointer] = $temp_found;
+	$image_pointer++;
+	
+        # grab corresponding ON pictures for navigation bar if we've just dl-ed the OFF picture
+	if(substr($found , -6) eq "of.gif") 
+	{
+	    substr($found, -6, 6) = "on.gif";
+	    &its_an_image($found, $outpdir);
+	}
+    }    
+}
Index: /gsdl/stable/bin/script/gsConvert.pl
===================================================================
--- /gsdl/stable/bin/script/gsConvert.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gsConvert.pl	(revision 20131)
@@ -0,0 +1,1398 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# gsConvert.pl -- convert documents to HTML or TEXT format
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2002 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# gsConvert.pl converts documents in a range of formats to HTML or TEXT
+# by exploiting third-party programs.  The sources of these are usually found
+# in the $GSDLHOME/packages directory, and the executables should live in
+# $GSDLHOME/bin/$GSDLOS (which is on the search path).
+#
+# Currently, we can convert the following formats by using external
+# conversion utilities:
+# Microsoft Word (versions 2,6,7 [==95?], 8[==97?], 9[==2000?]), RTF,
+# Adobe PDF, PostScript, MS PowerPoint (95 and 97), and MS Excel (95 and 97).
+#
+# We can try to convert any file to text with a perl implementation of the
+# UNIX strings command.
+#
+# We try to convert Postscript files to text using "gs" which is often on
+# *nix machines. We fall back to performing weak text extraction by using
+# regular expressions.
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use parsargv;
+use util;
+use Cwd;
+use File::Basename;
+
+# Are we running on WinNT or Win2000 (or later)?
+my $is_winnt_2000=eval {require Win32; return (Win32::IsWinNT()); return 0;};
+if (!defined($is_winnt_2000)) {$is_winnt_2000=0;}
+
+my $use_strings;
+my $pdf_complex;
+my $pdf_nohidden;
+my $pdf_zoom;
+my $pdf_ignore_images;
+my $pdf_allow_images_only;
+my $windows_scripting;
+
+sub print_usage
+{
+    print STDERR "\n";
+    print STDERR "gsConvert.pl: Converts documents in a range of formats to html\n";
+    print STDERR "              or text using third-party programs.\n\n";
+    print STDERR "  usage: $0 [options] filename\n";
+    print STDERR "  options:\n\t-type\tdoc|dot|pdf|ps|ppt|rtf|xls\t(input file type)\n";
+    print STDERR "\t-errlog\t<filename>\t(append err messages)\n";
+    print STDERR "\t-output\tauto|html|text|pagedimage_jpg|pagedimage_gif|pagedimage_png\t(output file type)\n";
+    print STDERR "\t-timeout\t<max cpu seconds>\t(ulimit on unix systems)\n";
+    print STDERR "\t-use_strings\tuse strings to extract text if conversion fails\n";
+    print STDERR "\t-windows_scripting\tuse windows script when converting Microsoft Word and PPT via VB script\n";
+    print STDERR "\t-pdf_complex\tuse complex output when converting PDF to HTML\n";
+    print STDERR "\t-pdf_nohidden\tDon't attempt to extract hidden text from PDF files\n";
+    print STDERR "\t-pdf_ignore_images\tdon't attempt to extract images when\n";
+    print STDERR "\t\tconverting PDF to HTML\n";
+    print STDERR "\t-pdf_allow_images_only\tallow images only (continue even if no text is present when converting to HTML)\n";
+    print STDERR "\t-pdf_zoom\tfactor by which to zoom PDF (only useful if\n";
+    print STDERR "\t\t-pdf_complex is set\n";
+    exit(1);
+}
+
+my $faillogfile="";
+my $timeout=0;
+
+sub main
+{
+    my (@ARGV) = @_;
+    my ($input_type,$output_type,$verbose);
+
+    # read command-line arguments
+    if (!parsargv::parse(\@ARGV,
+			 'type/(doc|dot|pdf|ps|ppt|rtf|xls)/', \$input_type,
+			 '/errlog/.*/', \$faillogfile,
+			 'output/(auto|html|text|pagedimage).*/', \$output_type,
+			 'timeout/\d+/0',\$timeout,
+			 'verbose/\d+/0', \$verbose,
+			 'use_strings', \$use_strings,
+			 'windows_scripting',\$windows_scripting,
+			 'pdf_complex', \$pdf_complex,
+			 'pdf_ignore_images', \$pdf_ignore_images,
+			 'pdf_allow_images_only', \$pdf_allow_images_only,
+			 'pdf_nohidden', \$pdf_nohidden,
+			 'pdf_zoom/\d+/2', \$pdf_zoom
+			 ))
+    {
+	print_usage();
+    }
+      
+    # Make sure the input file exists and can be opened for reading
+    if (scalar(@ARGV!=1)) {
+	print_usage();
+    }
+
+    my $input_filename = $ARGV[0];
+    if (!-r $input_filename) {
+	print STDERR "Error: unable to open $input_filename for reading\n";
+	exit(1);
+    }
+
+    # Deduce filenames
+    my ($tailname,$dirname,$suffix) 
+	= File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
+    my $output_filestem = &util::filename_cat($dirname, "$tailname");
+
+    if ($input_type eq "")
+    {
+	$input_type = lc (substr($suffix,1,length($suffix)-1));
+    }
+    
+    # Change to temporary working directory
+    my $stored_dir = cwd();
+    chdir ($dirname) || die "Unable to change to directory $dirname";
+
+    # Select convert utility
+    if (!defined $input_type) {
+	print STDERR "Error: No filename extension or input type defined\n";
+	exit(1);
+    } 
+    elsif ($input_type eq "doc" || $input_type eq "dot") {
+	print &convertDOC($input_filename, $output_filestem, $output_type);
+	print "\n";
+    } 
+    elsif ($input_type eq "rtf") {
+	print &convertRTF($input_filename, $output_filestem, $output_type);
+	print "\n";
+    } 
+    elsif ($input_type eq "pdf") {
+	print &convertPDF($dirname, $input_filename, $output_filestem, $output_type);
+	print "\n";
+    } 
+    elsif ($input_type eq "ps") {
+	print &convertPS($input_filename, $output_filestem, $output_type);
+	print "\n";
+    } 
+    elsif ($input_type eq "ppt") {
+	print &convertPPT($input_filename, $output_filestem, $output_type);
+	print "\n";
+    } 
+    elsif ($input_type eq "xls") {
+	print &convertXLS($input_filename, $output_filestem, $output_type);
+	print "\n";
+    } 
+    else {
+	print STDERR "Error: Unable to convert type '$input_type'\n";
+	exit(1);
+    }
+    
+    # restore to original working directory
+    chdir ($stored_dir) || die "Unable to return to directory $stored_dir";
+
+}
+
+&main(@ARGV);
+
+
+
+# Document-type conversion functions
+#
+# The following functions attempt to convert documents from their
+# input type to the specified output type.  If no output type was
+# given, then they first attempt HTML, and then TEXT.
+#
+# Each returns the output type ("html" or "text") or "fail" if no 
+# conversion is possible.
+
+# Convert a Microsoft word document
+
+sub convertDOC {
+    ($input_filename, $output_filestem, $output_type) = @_;
+
+    # Many .doc files are not in fact word documents!
+    my $realtype = &find_docfile_type($input_filename);
+
+    if ($realtype eq "word6" || $realtype eq "word7" || $realtype eq "word8") {
+	return &convertWord678($input_filename, $output_filestem, $output_type);
+    } elsif ($realtype eq "rtf") {
+	return &convertRTF($input_filename, $output_filestem, $output_type);
+    } else {
+	return &convertAnything($input_filename, $output_filestem, $output_type);
+    }
+}
+
+# Convert a Microsoft word 6/7/8 document
+
+sub convertWord678 {
+    ($input_filename, $output_filestem, $output_type) = @_;
+
+    my $success = 0;
+    if (!$output_type || ($output_type =~ m/html/i)){
+	if ($windows_scripting) {
+	    $success = &native_doc_to_html($input_filename, $output_filestem);
+	}
+	else {
+	    $success = &doc_to_html($input_filename, $output_filestem);	   
+	}
+	if ($success) {
+	   return "html";
+	}
+    }
+    return &convertAnything($input_filename, $output_filestem, $output_type);
+}
+
+
+# Convert a Rich Text Format (RTF) file
+
+sub convertRTF {
+    ($input_filename, $output_filestem, $output_type) = @_;
+
+    my $success = 0;
+
+    # Attempt specialised conversion to HTML
+    if (!$output_type || ($output_type =~ m/html/i)) {
+
+	if ($windows_scripting) {
+	    $success = &native_doc_to_html($input_filename, $output_filestem);
+	}
+	else {
+	    $success = &rtf_to_html($input_filename, $output_filestem);
+	}
+	if ($success) {
+	    return "html";
+	}
+    }
+
+# rtf is so ugly that's it's not worth running strings over.
+# One day I'll write some quick'n'dirty regexps to try to extract text - jrm21
+#    return &convertAnything($input_filename, $output_filestem, $output_type);
+    return "fail";
+}
+
+
+# Convert an unidentified file
+
+sub convertAnything {
+    ($input_filename, $output_filestem, $output_type) = @_;
+    
+    my $success = 0;
+  
+    # Attempt simple conversion to HTML
+    if (!$output_type || ($output_type =~ m/html/i)) {
+	$success = &any_to_html($input_filename, $output_filestem);
+	if ($success) {
+	    return "html";
+	}
+    }
+
+    # Convert to text
+    if (!$output_type || ($output_type =~ m/text/i)) {
+	$success = &any_to_text($input_filename, $output_filestem);
+	if ($success) {
+	    return "text";
+	}
+    }
+    return "fail";
+}
+
+
+
+# Convert an Adobe PDF document
+
+sub convertPDF {
+    my ($dirname, $input_filename, $output_filestem, $output_type) = @_;
+
+    my $success = 0;
+    $output_type =~ s/.*\-(.*)/$1/i;
+    # Attempt coversion to Image
+    if ($output_type =~ m/jp?g|gif|png/i) {
+	$success = &pdfps_to_img($dirname, $input_filename, $output_filestem, $output_type);
+	if ($success){
+	    return "item";
+	}
+    }
+
+    # Attempt conversion to HTML
+    if (!$output_type || ($output_type =~ m/html/i)) {
+	$success = &pdf_to_html($dirname, $input_filename, $output_filestem);
+	if ($success) {
+	    return "html";
+	}
+    }
+
+    # Attempt conversion to TEXT
+    if (!$output_type || ($output_type =~ m/text/i)) {
+	$success = &pdf_to_text($dirname, $input_filename, $output_filestem);
+	if ($success) {
+	    return "text";
+	}
+    }
+
+    return "fail";
+
+}
+
+
+# Convert an Adobe PostScript document
+
+sub convertPS {
+    ($input_filename, $output_filestem, $output_type) = @_;
+
+    my $success = 0;
+    $output_type =~ s/.*\-(.*)/$1/i;
+    # Attempt coversion to Image
+    if ($output_type =~ m/jp?g|gif|png/i) {
+	$success = &pdfps_to_img($dirname, $input_filename, $output_filestem, $output_type);
+	if ($success){
+	    return "item";
+	}
+    }
+
+    # Attempt conversion to TEXT
+    if (!$output_type || ($output_type =~ m/text/i)) {
+	$success = &ps_to_text($input_filename, $output_filestem);
+	if ($success) {
+	    return "text";
+	}
+    }
+    return "fail";
+}
+
+
+sub convertPPT {
+    my ($input_filename, $output_filestem, $output_type) = @_;
+    my $success = 0;
+
+    my $ppt_convert_type = "";
+    #if (!$output_type || $windows_scripting || ($output_type !~ m/html/i) || ($output_type !~ m/text/i)){
+    if ($windows_scripting && ($output_type !~ m/html/i) && ($output_type !~ m/text/i)){
+	if ($output_type =~ m/gif/i) {
+	    $ppt_convert_type = "-g";
+	} elsif ($output_type =~ m/jp?g/i){
+	    $ppt_convert_type = "-j";
+	} elsif ($output_type =~ m/png/i){
+	    $ppt_convert_type = "-p";
+	}
+	my $vbScript = &util::filename_cat($ENV{'GSDLHOME'}, "bin",
+					   $ENV{'GSDLOS'}, "pptextract");
+	$vbScript = "pptextract" if ($ENV{'GSDLOS'} =~ m/^windows$/i);
+			
+	$cmd = "";
+	if ($timeout) {$cmd = "ulimit -t $timeout;";}
+	# if the converting directory has already existed
+	if (-d $output_filestem) {
+	    print STDERR "**The conversion directory has existed\n";
+	    return "item";
+	} else {
+	    $cmd .=  "$vbScript $ppt_convert_type \"$input_filename\" \"$output_filestem\"";
+	    $cmd .= " 2>\"$output_filestem.err\""
+		if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
+	    if (system($cmd) !=0) {
+		print STDERR "Powerpoint VB Scripting convert failed\n";
+	    } else {
+		return "item";
+	    }
+	}
+    } elsif (!$output_type || ($output_type =~ m/html/i)) {
+	# Attempt conversion to HTML
+	#if (!$output_type || ($output_type =~ m/html/i)) {
+	# formulate the command
+	$cmd = "";
+	$cmd .= "perl -S ppttohtml.pl ";
+	$cmd .= " \"$input_filename\" \"$output_filestem.html\"";
+	$cmd .= " 2>\"$output_filestem.err\""
+	    if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
+
+	# execute the command
+	$!=0;
+	if (system($cmd)!=0)
+	{
+	    print STDERR "Powerpoint 95/97 converter failed $!\n";
+	} else {
+	    return "html";
+	}
+    } 
+
+    $success = &any_to_text($input_filename, $output_filestem);
+    if ($success) {
+	return "text";
+    }
+    
+    return "fail";
+}
+
+
+sub convertXLS {
+    my ($input_filename, $output_filestem, $output_type) = @_;
+
+    my $success = 0;
+
+    # Attempt conversion to HTML
+    if (!$output_type || ($output_type =~ m/html/i)) {
+	# formulate the command
+	$cmd = "";
+	$cmd .= "perl -S xlstohtml.pl ";
+	$cmd .= " \"$input_filename\" \"$output_filestem.html\"";
+	$cmd .= " 2>\"$output_filestem.err\""
+	    if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
+	
+	
+	# execute the command
+	$!=0;
+	if (system($cmd)!=0)
+	{
+	    print STDERR "Excel 95/97 converter failed $!\n";
+	} else {
+	    return "html";
+	}
+    }
+
+    $success = &any_to_text($input_filename, $output_filestem);
+    if ($success) {
+	return "text";
+    }
+
+    return "fail";
+}
+
+
+
+# Find the real type of a .doc file
+#
+# We seem to have a lot of files with a .doc extension that are .rtf 
+# files or Word 5 files.  This function attempts to tell the difference.
+sub find_docfile_type {
+    ($input_filename) = @_;
+    
+    open(CHK, "<$input_filename");
+    binmode(CHK);
+    my $line = "";
+    my $first = 1;
+
+    while (<CHK>) {
+    
+	$line = $_;
+
+	if ($first) {
+	    # check to see if this is an rtf file
+	    if ($line =~ m/^\{\\rtf/) {
+		close(CHK);
+		return "rtf";
+	    }
+	    $first = 0;
+	}
+	
+	# is this is a word 6/7/8 document?
+	if ($line =~ m/Word\.Document\.([678])/) {
+	    close(CHK);
+	    return "word$1";
+	}
+
+    }
+
+    return "unknown";
+}
+
+
+# Specific type-to-type conversions
+#
+# Each of the following functions attempts to convert a document from 
+# a specific format to another.  If they succeed they return 1 and leave 
+# the output document(s) in the appropriate place; if they fail they 
+# return 0 and delete any working files.
+
+
+# Attempt to convert a word document to html with the wv program
+sub doc_to_html {
+    ($input_filename, $output_filestem) = @_;
+
+    my $wvWare = &util::filename_cat($ENV{'GSDLHOME'}, "bin", 
+				     $ENV{'GSDLOS'}, "wvWare");
+
+    # don't include path on windows (to avoid having to play about
+    # with quoting when GSDLHOME might contain spaces) but assume
+    # that the PATH is set up correctly
+    $wvWare = "wvWare" if ($ENV{'GSDLOS'} =~ m/^windows$/i);
+
+    my $wv_conf = &util::filename_cat($ENV{'GSDLHOME'}, "etc", 
+				      "packages", "wv", "wvHtml.xml");
+    
+    # Added the following to work with replace_srcdoc_with_html.pl:
+    # Make wvWare put any associated (image) files of the word doc into
+    # folder docname-without-extention_files. This folder should be at
+    # the same level as the html file generated from the doc. 
+    # wvWare will take care of proper interlinking. 
+
+    # This step is necessary for replace_srcdoc_with_html.pl which will 
+    # move the html and associated files into the import folder. We
+    # want to ensure that the associated files won't overwrite similarly
+    # named items already in import. Hence we put them in a folder first
+    # (to which the html links properly) and that will allow
+    # replace_srcdoc_with_html.pl to move them safely to /import.
+
+    # To do all this, we need to use wvWare's --dir and --basename options
+    # where dir is the full path to the image folder directory and
+    # basename is the full path to the image folder appended to the name 
+    # which is to be prepended to every image file:
+    # eg. if the images were to have names like sample0.jpg to sampleN.jpg,
+    # then the basename is "/full/path/to/imgdir/sample". 
+    # In this case, basename is the full path to and name of the document.
+    # HOWEVER: basename always takes full path, not relative url, so
+    # the greenstone browser is unable to display the images (absolute paths
+    # cause it to give an "external link" message)
+    # See http://osdir.com/ml/lib.wvware.devel/2002-11/msg00014.html
+    # and http://rpmfind.net/linux/RPM/freshmeat/rpms/wv/wv-0.5.44-1.i386.html
+    # "added --dir option to wvHtml so that pictures can be placed in
+    # a seperate directory"
+    # "running wvWare through IMP to view word documents as html. It gets
+    # invoked like this:
+    # wvWare --dir=/tmp-wvWare --basename=/tmp-wvWare/img$$- $tmp_word >$tmp_output"
+    
+    # toppath is the folder where html is generated
+    # docname is the name (without extension) of the html to be generated
+    # suffix (extension) is thrown away
+    my ($docname, $toppath) 
+	= &File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
+
+    # We want the image folder generated to have the same name as windows
+    # would generate ($windows_scripting) when it converts from word to html.
+    # That is, foldername=docname_files
+    my $assoc_dir = &util::filename_cat($toppath, $docname."_files");
+    #print "assoc_dir: ".$assoc_dir."\n";  # same as "$output_filestem._files"
+    
+    # ensure this image directory exists
+    # if it exists already, just delete and recreate
+    if(-e $assoc_dir) { 
+	&util::rm_r($assoc_dir);
+    }  
+    &util::mk_dir($assoc_dir);
+
+    # the images are all going to be called image0, image1,..., imageN
+    my $img_basenames = &util::filename_cat($assoc_dir, $docname);
+    
+    #print STDERR "****toppath: $toppath\n****docname: $docname\n;
+    #print STDERR "****img_basenames: $img_basenames\n" if($img_basenames);
+    #print STDERR "****assoc_dir: $assoc_dir\n" if($assoc_dir);
+
+    my $cmd = "";
+    if ($timeout) {$cmd = "ulimit -t $timeout;";}
+    # wvWare's --dir and --basename options for image directory. 
+    # Replaced the next line with the *2 lines* following it:
+               # $cmd .= "$wvWare --charset utf-8 --config \"$wv_conf\"";
+    $cmd .= "$wvWare --dir \"$assoc_dir\" --basename \"$img_basenames\""; 
+    $cmd .= " --charset utf-8 --config \"$wv_conf\"";
+    $cmd .= " \"$input_filename\" > \"$output_filestem.html\"";
+
+    # redirecting STDERR is a bad idea on windows 95/98
+    $cmd .= " 2> \"$output_filestem.err\""
+	if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
+    # execute the command
+    $!=0;
+    if (system($cmd)!=0)
+    {
+	print STDERR "Error executing wv converter:$!\n";
+	if (-s "$output_filestem.err") {
+	    open (ERRFILE, "<$output_filestem.err");
+
+	    my $write_to_fail_log=0;
+	    if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile")))
+	    {$write_to_fail_log=1;}
+
+	    my $line;
+	    while ($line=<ERRFILE>) {
+		if ($line =~ m/\w/) {
+		    print STDERR "$line";
+		    print FAILLOG "$line" if ($write_to_fail_log);
+		}
+		if ($line !~ m/startup error/) {next;}
+		print STDERR " (given an invalid .DOC file?)\n";
+		print FAILLOG " (given an invalid .DOC file?)\n"
+		if ($write_to_fail_log);
+		
+	    } # while ERRFILE
+	    close FAILLOG if ($write_to_fail_log);
+	}
+	return 0; # we can try any_to_text
+    }
+
+    # Was the conversion successful?
+
+    if (-s "$output_filestem.html") { # if file has non-zero size (i.e. it has contents)
+	open(TMP, "$output_filestem.html");
+	$line = <TMP>;
+	close(TMP);
+	if ($line && $line =~ m/DOCTYPE HTML/) {
+	    &util::rm("$output_filestem.err") if -e "$output_filestem.err";    
+
+	    # Inserted this code to remove the images directory if it was still empty after 
+	    # the html was generated (in case there were no images in the word document)
+	    if (&util::is_dir_empty($assoc_dir)) {
+		#print STDERR "***gsConvert.pl: Image dir $assoc_dir is empty, removing***\n";
+		&util::rm_r($assoc_dir);
+	    } else { # there was an image folder (it was generated)
+		# Therefore, the html file generated contains absolute links to the images
+		# Replace them with relative links instead, so the folder can be moved elsewhere
+		&make_links_to_assocdir_relative($toppath, $docname, "$output_filestem.html", $assoc_dir, $docname."_files");	
+	    }
+	    return 1;
+	}
+    }
+	
+    # If here, an error of some sort occurred
+    &util::rm("$output_filestem.html") if -e "$output_filestem.html";
+    if (-e "$output_filestem.err") {
+	if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile"))) {
+	    open (ERRLOG,"$output_filestem.err");
+	    while (<ERRLOG>) {print FAILLOG $_;}
+	    close FAILLOG;
+	    close ERRLOG;
+	}
+	&util::rm("$output_filestem.err");
+    }
+    
+    return 0;
+}
+
+# Method to work with doc_to_html - Word docs might contain images.
+# When such word docs are converted with wvWare, we make it generate a 
+# <filename>_files folder with the associated images, while the html file
+# <filename> refers to the images using absolute paths to <filename>_files.
+# This method reads in that html file and replaces all the absolute paths to 
+# the images in <filename>_files with the relative paths to the images from
+# that folder. (I.e. with <filename>_files/<imagename.ext>).
+sub make_links_to_assocdir_relative{
+    # toppath is the top-level folder in which the html file we're going to be fixing resides
+    # docname is just the name (without extension) of the html file
+    # html_file is the full path to the html file: /full/path/docname.html
+    # assoc_dir_path is toppath/docname_files
+    # assoc_dirname is the directory name of the folder with associated imgs: docname_files
+    my ($toppath, $docname, $html_file, $assoc_dir_path, $assoc_dirname) = @_;
+
+    # 1. Read all the contents of the html into a string
+    # open the original file for reading
+    unless(open(FIN, "<$html_file")) { 
+	print STDERR "gsConvert.pl: Unable to open $html_file for reading absolute urls...ERROR: $!\n";
+	return 0;
+    }
+    # From http://perl.plover.com/local.html
+    # "It's cheaper to read the file all at once, without all the splitting and reassembling. 
+    # (Some people call this slurping the file.) Perl has a special feature to support this: 
+    # If the $/ variable is undefined, the <...> operator will read the entire file all at once"
+    my $html_contents;
+    {
+	local $/ = undef;        # Read entire file at once
+	$html_contents = <FIN>;  # Now file is read in as one single 'line'
+    }
+    close(FIN); # close the file
+    #print STDERR $html_contents;
+   
+    # 2. Replace (substitute) *all* ocurrences of the assoc_dir_path in a hrefs and img src
+    # values with assoc_dirname
+    # At the end: g means substitute all occurrences (global), while s at the end means treat 
+    # all new lines as a regular space. This interacts with g to consider all the lines 
+    # together as a single line so that multi-occurrences can be replaced.
+
+    # we can't just replace $assoc_dir_path with $assoc_dir
+    # $assoc_dir_path represents a regular expression that needs to be replaced
+    # if it contains ., -, [, ], or Windows style backslashes in paths  -- which all have special
+    # meaning in Perl regular expressions -- we need to escape these first
+    my $safe_reg_expression = $assoc_dir_path;
+    $safe_reg_expression =~ s/\\/\\\\/g;
+    $safe_reg_expression =~ s/\./\\./g;
+    $safe_reg_expression =~ s/\-/\\-/g;
+    $safe_reg_expression =~ s/\[/\\[/g;
+    $safe_reg_expression =~ s/\]/\\]/g;
+    $safe_reg_expression =~ s/ /%20/g; # wvWare put %20 in place of space, so we need to change our prefix to match
+
+    # The following regular expression substitution looks for <a or <image, followed by any other 
+    # attributes and values until it comes to the FIRST (indicated by ?) href= or src= 
+    # followed by " or ' no quotes at all around path, followed by the associated folder's pathname 
+    # followed by characters (for the img filename), then finally the optional closing quotes 
+    # in " or ' form, followed by any other attributes and values until the first > to end the tag.
+    # The substitution: all the parts preceding associated folder's pathname are retained,
+    # the associated folder path name is replaced by associated folder directory name
+    # and the rest upto and including the closing > tag is retained.
+    # The sg at the end of the pattern match treats all of html_contents as a single line (s) 
+    # and performs a global replace (g) meaning that all occurrences that match in that single line
+    # are substituted.
+    $html_contents =~ s/(<(a|img).*?(href|src)=(\"|\')?)$safe_reg_expression(.*?(\"|\')?.*?>)/$1$assoc_dirname$5/sg;
+               #$html_contents =~ s/$safe_reg_expression/$assoc_dirname/gs; # this works, used as fall-back
+    # now replace any %20 chars in filenames of href or src attributes to use literal space ' '. Calls a function for this
+    $html_contents =~ s/(<(a|img).*?(href|src)=(\"|\')?)(.*)(.*?(\"|\')?.*?>)/&post_process_assocfile_urls($1, $5, $6)/sge;
+
+    #print STDERR "****assoc_dirname: $assoc_dirname***\n";
+    #print STDERR "****safe_reg_expression: $safe_reg_expression***\n";
+   
+    # delete the original file and recreate it
+    my $copy_of_filename = $html_file;
+    &util::rm($copy_of_filename); # deleted the file
+
+    # Recreate the original file for writing the updated contents
+    unless(open(FOUT, ">$html_file")) {  # open it as a new file for writing
+	print STDERR "gsConvert.pl: Unable to open $html_file for writing relative links...ERROR: $!\n";
+	return 0;
+    }
+
+    # write out the updated contents and close the file
+    print FOUT $html_contents;
+    close(FOUT);
+    return 1;
+}
+
+# Utility routine to make sure HTML plugin gets img src/href link pathnames that contain 
+# url slashes (/) instead of windows-style backwards slashes, and to convert all %20 
+# introduced in link pathnames by wvWare into space again. Converts all percent signs
+# introduced by URL encoding filenames generated into %25 in these url links referencing them
+sub post_process_assocfile_urls
+{
+    my ($pre, $text, $post) = @_;
+
+    $text =~ s/%20/ /g; # Convert %20s to space and not underscore since underscores mess with incremental rebuild 
+    # $text =~ s/%20/_/g; # reinstated this line, since we no longer replace spaces with %20. We replace them with underscores
+    $text =~ s/\\/\//g;
+    $text =~ s/%/%25/g;
+
+    return "$pre$text$post";
+}
+
+# Attempt to convert a word document to html with the word2html scripting program
+sub native_doc_to_html {
+    ($input_filename, $output_filestem) = @_;
+
+    my $vbScript = &util::filename_cat($ENV{'GSDLHOME'}, "bin",
+				       $ENV{'GSDLOS'}, "word2html");
+
+    $vbScript = "word2html" if ($ENV{'GSDLOS'} =~ m/^windows$/i);
+    if (-e "$output_filestem.html") {
+	print STDERR "*** The conversion file has existed\n";
+	return 1;
+    }
+
+    my $cmd = "";
+    if ($timeout) {$cmd = "ulimit -t $timeout;";}
+    #$cmd .= "$vbScript \"$input_filename\" \"$output_filestem.html\"";
+    #$cmd .=  "$vbScript $input_filename $output_filestem.html";
+    $cmd .=  "$vbScript \"$input_filename\" \"$output_filestem.html\"";
+
+    # redirecting STDERR
+    $cmd .= " 2> \"$output_filestem.err\""
+	if ($ENV {'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
+    
+    # execute the command
+    $!=0;
+    if (system($cmd)!=0)
+    {
+	print STDERR "Error executing word2Html converter:$!\n";
+	if (-s "$output_filestem.err") {
+	    open (ERRFILE, "<$output_filestem.err");
+	    
+	    my $write_to_fail_log=0;
+	    if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile")))
+	    {$write_to_fail_log=1;}
+
+	    my $line;
+	    while ($line=<ERRFILE>) {
+		if ($line =~ m/\w/) {
+		    print STDERR "$line";
+		    print FAILLOG "$line" if ($write_to_fail_log);
+		}
+		if ($line !~ m/startup error/) {next;}
+		print STDERR " (given an invalid .DOC file?)\n";
+		print FAILLOG " (given an invalid .DOC file?)\n"
+		if ($write_to_fail_log);
+		
+	    } # while ERRFILE
+	    close FAILLOG if ($write_to_fail_log);
+	}
+	return 0; # we can try any_to_text
+    }
+
+    # Was the conversion successful?
+    if (-s "$output_filestem.html") {
+	open(TMP, "$output_filestem.html");
+	$line = <TMP>;
+	close(TMP);
+	if ($line && $line =~ m/html/) {
+	    &util::rm("$output_filestem.err") if -e "$output_filestem.err";
+	    return 1;
+	}
+    }
+	
+    # If here, an error of some sort occurred
+    &util::rm("$output_filestem.html") if -e "$output_filestem.html";
+    if (-e "$output_filestem.err") {
+	if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile"))) {
+	    open (ERRLOG,"$output_filestem.err");
+	    while (<ERRLOG>) {print FAILLOG $_;}
+	    close FAILLOG;
+	    close ERRLOG;
+	}
+	&util::rm("$output_filestem.err");
+    }
+    return 0;
+}
+
+# Attempt to convert an RTF document to html with rtftohtml
+
+sub rtf_to_html {
+    my ($input_filename, $output_filestem) = @_;
+
+    # formulate the command
+    $cmd = "";
+    if ($timeout) {$cmd = "ulimit -t $timeout;";}
+    $cmd .= "rtftohtml";
+    #$cmd .= "rtf-converter";
+
+    $cmd .= " -o \"$output_filestem.html\" \"$input_filename\"";
+
+    $cmd .= " 2>\"$output_filestem.err\""
+        if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000);
+
+
+    # execute the command
+    $!=0;
+    if (system($cmd)!=0)
+    {
+	print STDERR "Error executing rtf converter $!\n";
+	# don't currently bother printing out error log...
+	# keep going, in case it still created an HTML file...
+    }
+
+    # Was the conversion successful?
+    my $was_successful=0;
+    if (-s "$output_filestem.html") {
+	# make sure we have some content other than header
+	open (HTML, "$output_filestem.html"); # what to do if fail?
+	my $line;
+	my $past_header=0;
+	while ($line=<HTML>) {
+
+	    if ($past_header == 0) {
+		if ($line =~ m/<body>/) {$past_header=1;}
+		next;
+	    }
+
+	    $line =~ s/<[^>]+>//g;
+	    if ($line =~ m/\w/ && $past_header) {  # we found some content...
+		$was_successful=1;
+		last;
+	    }
+	}
+	close HTML;
+    }
+
+    if ($was_successful) {
+	&util::rm("$output_filestem.err")
+	    if (-e "$output_filestem.err");
+	# insert the (modified) table of contents, if it exists.
+	if (-e "${output_filestem}_ToC.html") {
+	    &util::mv("$output_filestem.html","$output_filestem.src");
+	    my $open_failed=0;
+	    open HTMLSRC, "$output_filestem.src" || ++$open_failed;
+	    open TOC, "${output_filestem}_ToC.html" || ++$open_failed;
+	    open HTML, ">$output_filestem.html" || ++$open_failed;
+	    
+	    if ($open_failed) {
+		close HTMLSRC;
+		close TOC;
+		close HTML;
+		&util::mv("$output_filestem.src","$output_filestem.html");
+		return 1;
+	    }
+
+	    # print out header info from src html.
+	    while (defined($_ = <HTMLSRC>) && $_ =~ m/\w/) {
+		print HTML "$_";
+	    }
+
+	    # print out table of contents, making links relative
+	    <TOC>; <TOC>; # ignore first 2 lines
+	    print HTML scalar(<TOC>); # line 3 = "<ol>\n"
+	    my $line;
+	    while ($line=<TOC>) {
+		$line =~ s@</body></html>$@@ ; # only last line has this
+		# make link relative
+		$line =~ s@href=\"[^\#]+@href=\"@;
+		print HTML $line;
+	    }
+	    close TOC;
+
+	    # rest of html src
+	    while (<HTMLSRC>) {
+		print HTML $_;
+	    }
+	    close HTMLSRC;
+	    close HTML;
+
+	    &util::rm("${output_filestem}_ToC.html");
+	    &util::rm("${output_filestem}.src");
+	}
+	# we don't yet do anything with footnotes ($output_filestem_fn.html) :(
+	return 1; # success
+    }
+
+    if (-e "$output_filestem.err") {
+	if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile")))
+	{
+	    print FAILLOG "Error - rtftohtml - couldn't extract text\n";
+	    #print FAILLOG "Error - rtf-converter - couldn't extract text\n";
+	    print FAILLOG " (rtf file might be too recent):\n";
+	    open (ERRLOG, "$output_filestem.err");
+	    while (<ERRLOG>) {print FAILLOG $_;}
+	    close ERRLOG;
+	    close FAILLOG;
+	}
+	&util::rm("$output_filestem.err");
+    }
+
+    &util::rm("$output_filestem.html") if (-e "$output_filestem.html");
+
+    return 0;
+}
+
+
+# Convert a pdf file to html with the pdftohtml command
+
+sub pdf_to_html {
+    my ($dirname, $input_filename, $output_filestem) = @_;
+
+    $cmd = "";
+    if ($timeout) {$cmd = "ulimit -t $timeout;";}
+    $cmd .= "perl -S pdftohtml.pl -zoom $pdf_zoom";
+    $cmd .= " -c" if ($pdf_complex);
+    $cmd .= " -i" if ($pdf_ignore_images);
+    $cmd .= " -a" if ($pdf_allow_images_only);
+    $cmd .= " -hidden" unless ($pdf_nohidden);
+    $cmd .= " \"$input_filename\" \"$output_filestem\"";
+    
+    if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000) {
+	$cmd .= " > \"$output_filestem.out\" 2> \"$output_filestem.err\"";
+    } else {
+	$cmd .= " > \"$output_filestem.err\"";
+    }
+
+    $!=0;
+
+    my $retval=system($cmd);
+    if ($retval!=0)
+    {
+	print STDERR "Error executing pdftohtml.pl";
+	if ($!) {print STDERR ": $!";} 
+	print STDERR "\n";
+    }
+
+    # make sure the converter made something
+    if ($retval!=0 || ! -s "$output_filestem.html")
+    {
+	&util::rm("$output_filestem.out") if (-e "$output_filestem.out");
+	# print out the converter's std err, if any
+	if (-s "$output_filestem.err") {
+	    open (ERRLOG, "$output_filestem.err") || die "$!";
+	    print STDERR "pdftohtml error log:\n";
+	    while (<ERRLOG>) {
+		print STDERR "$_";
+	    }
+	    close ERRLOG;
+	}
+	&util::rm("$output_filestem.html") if (-e "$output_filestem.html");
+	if (-e "$output_filestem.err") {
+	    if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile")))
+	    {
+		open (ERRLOG, "$output_filestem.err");
+		while (<ERRLOG>) {print FAILLOG $_;}
+		close ERRLOG;
+		close FAILLOG;
+	    }	
+	    &util::rm("$output_filestem.err");
+	}
+	return 0;
+    }
+
+    &util::rm("$output_filestem.err") if (-e "$output_filestem.err");
+    &util::rm("$output_filestem.out") if (-e "$output_filestem.out");
+    return 1;
+}
+
+# Convert a pdf file to various types of image with the convert command
+
+sub pdfps_to_img {
+    my ($dirname, $input_filename, $output_filestem, $output_type) = @_;
+
+    # Check that ImageMagick is installed and available on the path (except for Windows 95/98)
+    if (!($ENV{'GSDLOS'} eq "windows" && !Win32::IsWinNT())) {
+	my $result = `identify 2>&1`;
+	if ($? == -1 || $? == 256) {  # Linux and Windows return different values for "program not found"
+	    #ImageMagick is not installed, thus the convert utility is not available. 
+	    print STDERR "*** ImageMagick is not installed, the convert utility is not available. Unable to convert PDF/PS to images\n";
+	    return 0;
+	}
+    }
+
+    $cmd = "";
+    if ($timeout) {$cmd = "ulimit -t $timeout;";}
+    $output_type =~ s/.*\_(.*)/$1/i;
+    $cmd .= "perl -S pdfpstoimg.pl -convert_to $output_type \"$input_filename\" \"$output_filestem\"";
+    if ($ENV{'GSDLOS'} !~ m/^windows$/i || $is_winnt_2000) {
+	$cmd .= " > \"$output_filestem.out\" 2> \"$output_filestem.err\"";
+    } else {
+	$cmd .= " > \"$output_filestem.err\"";
+    }
+
+    # don't include path on windows (to avoid having to play about
+    # with quoting when GSDLHOME might contain spaces) but assume
+    # that the PATH is set up correctly
+    $!=0;
+    my $retval=system($cmd);
+    if ($retval!=0)
+    {
+	print STDERR "Error executing pdftoimg.pl";
+	if ($!) {print STDERR ": $!";} 
+	print STDERR "\n";
+    }
+
+    #make sure the converter made something
+    #if ($retval !=0) || ! -s "$output_filestem")
+    if ($retval !=0) 
+    {
+	&util::rm("$output_filestem.out") if (-e "$output_filestem.out");
+	#print out the converter's std err, if any
+	if (-s "$output_filestem.err") {
+	    open (ERRLOG, "$output_filestem.err") || die "$!";
+	    print STDERR "pdfpstoimg error log:\n";
+	    while (<ERRLOG>) {
+		print STDERR "$_";
+	    }
+	    close ERRLOG;
+	}
+	#&util::rm("$output_filestem.html") if (-e "$output_filestem.html");
+	if (-e "$output_filestem.err") {
+	    if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile")))
+	    {
+		open (ERRLOG, "$output_filestem.err");
+		while (<ERRLOG>) {print FAILLOG $_;}
+		close ERRLOG;
+		close FAILLOG;
+	   }	
+	    &util::rm("$output_filestem.err");
+	}
+	return 0;
+    }
+    &util::rm("$output_filestem.err") if (-e "$output_filestem.err");
+    &util::rm("$output_filestem.out") if (-e "$output_filestem.out");
+    return 1;
+}
+
+# Convert a PDF file to text with the pdftotext command
+
+sub pdf_to_text {
+    my ($dirname, $input_filename, $output_filestem) = @_;
+
+    my $cmd = "pdftotext \"$input_filename\" \"$output_filestem.text\"";
+
+    if ($ENV{'GSDLOS'} !~ m/^windows$/i) {
+	$cmd .= " > \"$output_filestem.out\" 2> \"$output_filestem.err\"";
+    } else {
+	$cmd .= " > \"$output_filestem.err\"";
+    }
+    
+    if (system($cmd)!=0)
+    {
+	print STDERR "Error executing $cmd: $!\n";
+	&util::rm("$output_filestem.text") if (-e "$output_filestem.text");
+    }
+
+    # make sure there is some extracted text.
+    if (-e "$output_filestem.text") {
+	open (EXTR_TEXT, "$output_filestem.text") || warn "open: $!";
+	binmode(EXTR_TEXT); # just in case...
+	my $line="";
+	my $seen_text=0;
+	while (($seen_text==0) && ($line=<EXTR_TEXT>)) {
+	    if ($line=~ m/\w/) {$seen_text=1;}
+	}
+	close EXTR_TEXT;
+	if ($seen_text==0) { # no text was extracted
+	    print STDERR "Error: pdftotext found no text\n";
+	    &util::rm("$output_filestem.text");
+	}
+    }
+
+    # make sure the converter made something
+    if (! -s "$output_filestem.text")
+    {
+	# print out the converters std err, if any
+	if (-s "$output_filestem.err") {
+	    open (ERRLOG, "$output_filestem.err") || die "$!";
+	    print STDERR "pdftotext error log:\n";
+	    while (<ERRLOG>) {
+		print STDERR "$_";
+	    }
+	    close ERRLOG;
+	}
+	# does this converter create a .out file?
+	&util::rm("$output_filestem.out") if (-e "$output_filestem.out");
+	&util::rm("$output_filestem.text") if (-e "$output_filestem.text");
+	if (-e "$output_filestem.err") {
+	    if ($faillogfile ne "" && defined(open(FAILLOG,">>$faillogfile")))
+	    {
+		open (ERRLOG,"$output_filestem.err");
+		while (<ERRLOG>) {print FAILLOG $_;}
+		close ERRLOG;
+		close FAILLOG;
+	    }
+	    &util::rm("$output_filestem.err");
+	}
+	return 0;
+    }
+    &util::rm("$output_filestem.err") if (-e "$output_filestem.err");
+    return 1;
+}
+
+# Convert a PostScript document to text
+# note - just using "ps2ascii" isn't good enough, as it
+# returns 0 for a postscript interpreter error. ps2ascii is just
+# a wrapper to "gs" anyway, so we use that cmd here.
+
+sub ps_to_text {
+    my ($input_filename, $output_filestem) = @_;
+
+    my $error = "";
+
+    # if we're on windows we'll fall straight through without attempting
+    # to use gs
+    if ($ENV{'GSDLOS'} =~ m/^windows$/i) {
+	$error = "Windows does not support gs";
+
+    } else {
+	my $cmd = "";
+	if ($timeout) {$cmd = "ulimit -t $timeout; ";}
+	$cmd .= "gs -q -dNODISPLAY -dNOBIND -dWRITESYSTEMDICT -dSIMPLE -c save ";
+	$cmd .= "-f ps2ascii.ps \"$input_filename\" -c quit > \"$output_filestem.text\"";
+	#$cmd .= "pstotext -output \"$output_filestem.text\" $input_filename\"";
+	$cmd .= " 2> $output_filestem.err";
+	$!=0;
+
+	my $retcode=system($cmd);
+	$retcode = $? >> 8;  # see man perlfunc - system for this...
+	# if system returns -1 | 127 (couldn't start program), look at $! for message
+
+	if ($retcode!=0) {if ($!) {$error=$!;} else {$error="couldn't run.\n";}}
+	elsif (! -e "$output_filestem.text") {
+	    $error="did not create output file.\n";
+	}
+	else 
+	{   # make sure the interpreter didn't get an error. It is technically
+	    # possible for the actual text to start with this, but....
+	    open PSOUT, "$output_filestem.text";
+	    if (<PSOUT> =~ m/^Error: (.*)/) {
+		$error="interpreter error - \"$1\"";
+	    }
+	    close PSOUT;
+	}
+    }
+
+    if ($error ne "")
+    {
+	print STDERR "Warning: Error executing gs: $error\n";
+	&util::rm("$output_filestem.text") if (-e "$output_filestem.text");
+
+	if ("$faillogfile" ne "" && defined(open (FAILLOG, ">>$faillogfile")))
+	{
+	    print FAILLOG "gs - $error\n";
+	    if (-e "$output_filestem.err") {
+		open(ERRLOG, "$output_filestem.err");
+		while (<ERRLOG>) {print FAILLOG $_;}
+		close ERRLOG;
+	    }
+	    close FAILLOG;
+	}
+	&util::rm("$output_filestem.err") if (-e "$output_filestem.err");
+
+
+	# Fine then. We'll just do a lousy job by ourselves...
+	# Based on 5-line regexp sed script found at:
+	# http://snark.ptc.spbu.ru/mail-archives/lout/brown/msg00003.html
+	# 
+	print STDERR "Stripping text from postscript\n";
+	my $errorcode=0;
+	open (IN, "$input_filename") 
+	    ||  ($errorcode=1, warn "Couldn't read file: $!");
+	open (OUT, ">$output_filestem.text") 
+	    ||  ($errorcode=1, warn "Couldn't write file: $!");
+	if ($errorcode) {print STDERR "errors\n";return 0;}
+	
+	my $text="";  # this is for whole .ps file...
+	$text = join('', <IN>); # see man perlport, under "System Resources"
+	close IN;
+
+	# Make sure this is a ps file...
+	if ($text !~ m/^%!/) {
+	    print STDERR "Bad postscript header: not '%!'\n";
+	    if ($faillogfile ne "" && defined(open(FAILLOG, ">>$faillogfile")))
+	    {
+		print FAILLOG "Bad postscript header: not '%!'\n";
+		close FAILLOG;
+	    }
+	    return 0;
+	}
+
+	# if ps has Page data, then use it to delete all stuff before it.
+	$text =~ s/^.*?%%Page:.*?\n//s; # treat string as single line
+	
+	# remove all leading non-data stuff
+	$text =~ s/^.*?\(//s;
+
+	# remove all newline chars for easier processing
+	$text =~ s/\n//g;
+	
+	# Big assumption here - assume that if any co-ordinates are
+	# given, then we are at the end of a sentence.
+	$text =~ s/\)-?\d+\ -?\d+/\) \(\n\)/g;
+
+	# special characters--
+	$text =~ s/\(\|\)/\(\ - \)/g; # j -> em-dash?
+
+	# ? ps text formatting (eg italics?) ?
+	$text =~ s/Fn\(f\)/\(\{\)/g; # f -> {
+	$text =~ s/Fn\(g\)/\(\}\)/g; # g -> }
+	$text =~ s/Fn\(j\)/\(\|\)/g; # j -> |
+	# default - remove the rest
+	$text =~ s/\ ?F.\((.+?)\)/\($1\)/g;
+
+	# attempt to add whitespace between words... 
+	# this is based purely on observation, and may be completely wrong...
+	$text =~ s/([^F])[defghijkuy]\(/$1 \( /g;
+	# eg I notice "b(" is sometimes NOT a space if preceded by a 
+	# negative number.
+	$text =~ s/\)\d+ ?b\(/\) \( /g;
+
+	# change quoted braces to brackets
+	$text =~ s/([^\\])\\\(/$1\{/g;
+	$text =~ s/([^\\])\\\)/$1\}/g ;
+
+	# remove everything that is not between braces
+	$text =~ s/\)([^\(\)])+?\(//sg ;
+	
+	# remove any Trailer eof stuff.
+	$text =~ s/\)[^\)]*$//sg;
+
+	### ligatures have special characters...
+	$text =~ s/\\013/ff/g;
+	$text =~ s/\\014/fi/g;
+	$text =~ s/\\015/fl/g;
+	$text =~ s/\\016/ffi/g;
+	$text =~ s/\\214/fi/g;
+	$text =~ s/\\215/fl/g;
+	$text =~ s/\\017/\n\* /g; # asterisk?
+	$text =~ s/\\023/\023/g;  # e acute ('e)
+	$text =~ s/\\177/\252/g;  # u"
+#	$text =~ s/ ?? /\344/g;  # a"
+
+	print OUT "$text";
+	close OUT;
+    }
+    # wrap the text - use a minimum length. ie, first space after this length.
+    my $wrap_length=72;
+    &util::mv("$output_filestem.text", "$output_filestem.text.tmp");
+    open INFILE, "$output_filestem.text.tmp" ||
+	die "Couldn't open file: $!";
+    open OUTFILE, ">$output_filestem.text" ||
+	die "Couldn't open file for writing: $!";
+    my $line="";
+    while ($line=<INFILE>) {
+	while (length($line)>0) {
+	    if (length($line)>$wrap_length) {
+		$line =~ s/^(.{$wrap_length}[^\s]*)\s*//;
+		print OUTFILE "$1\n";
+	    } else {
+		print OUTFILE "$line";
+		$line="";
+	    }
+	}
+    }
+    close INFILE;
+    close OUTFILE;
+    &util::rm("$output_filestem.text.tmp");
+
+    &util::rm("$output_filestem.err") if (-e "$output_filestem.err");
+    return 1;
+}
+
+
+# Convert any file to HTML with a crude perl implementation of the
+# UNIX strings command.
+
+sub any_to_html {
+    ($input_filename, $output_filestem) = @_;
+
+    # First generate a text file
+    return 0 unless (&any_to_text($input_filename, $output_filestem));
+
+    # create an HTML file from the text file
+    open(TEXT, "<$output_filestem.text");
+    open(HTML, ">$output_filestem.html");
+
+    print HTML "<html><head>\n";
+    print HTML "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html\">\n";
+    print HTML "<META NAME=\"GENERATOR\" CONTENT=\"Greenstone any_to_html\">\n";
+    print HTML "</head><body>\n\n";
+
+    my $line;
+    while ($line=<TEXT>) { 
+	$line =~ s/</&lt;/g;
+	$line =~ s/>/&gt;/g;
+	if ($line =~ m/^\s*$/) {
+	    print HTML "<p>";
+	} else {
+	    print HTML "<br> ", $line;
+	}
+    }
+    print HTML "\n</body></html>\n";
+
+    close HTML;
+    close TEXT;
+
+    &util::rm("$output_filestem.text") if (-e "$output_filestem.text");
+    return 1;
+}
+
+# Convert any file to TEXT with a crude perl implementation of the
+# UNIX strings command.
+# Note - this assumes ascii charsets :(		(jrm21)
+
+sub any_to_text {
+    ($input_filename, $output_filestem) = @_;
+
+    if (!$use_strings) {
+      return 0;
+    }
+
+    print STDERR "\n**** In any to text****\n\n";
+    open(IN, "<$input_filename") || return 0;
+    binmode(IN);
+    open(OUT, ">$output_filestem.text") || return 0;
+
+    my ($line);
+    my $output_line_count = 0;
+    while (<IN>) { 
+	$line = $_;
+
+	# delete anything that isn't a printable character
+	$line =~ s/[^\040-\176]+/\n/sg;
+
+	# delete any string less than 10 characters long
+	$line =~ s/^.{0,9}$/\n/mg;
+	while ($line =~ m/^.{1,9}$/m) {
+	    $line =~ s/^.{0,9}$/\n/mg;
+	    $line =~ s/\n+/\n/sg;
+	}
+
+	# remove extraneous whitespace
+	$line =~ s/\n+/\n/gs;
+	$line =~ s/^\n//gs;
+
+	# output whatever is left
+	if ($line =~ m/[^\n ]/) {
+	    print OUT $line;
+	    ++$output_line_count;
+	}
+    }
+
+    close OUT;
+    close IN;
+
+    if ($output_line_count) { # try to protect against binary only formats
+	return 1;
+    }
+
+    &util::rm("$output_filestem.text");
+    return 0;
+
+}
Index: /gsdl/stable/bin/script/gsWget.pl
===================================================================
--- /gsdl/stable/bin/script/gsWget.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gsWget.pl	(revision 20131)
@@ -0,0 +1,72 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will download the specified urls (http:, ftp: and file:)
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use util;
+
+# wget should live in the Greenstone directory structure
+# we'll bail if we can't find it
+my $exe = &util::get_os_exe ();
+my $cmd = &util::filename_cat ($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "wget");
+$cmd .= $exe;
+if (! -e "$cmd") {
+    die "gsWget.pl failed: $cmd doesn't exist\n";
+}
+
+# if on windows we expect wget to already be on the path -
+# this allows us to avoid problems when GSDLHOME contains spaces
+# (double quoting the call doesn't work on win2000)
+if ($ENV{'GSDLOS'} =~ /^windows$/) {
+    $cmd = "wget";
+}
+
+# command-line parameters
+my @quoted_argv = map { "\"$_\"" } @ARGV;
+my $args = join(' ', @quoted_argv);
+$cmd .= " $args";
+
+# run the command
+my $status = system($cmd);
+
+# We should check the error status of wget; unfortunately this
+# is set to 1 even when we exit successfully, so we ignore it.
+#
+#$status /= 256;
+#if ($status != 0) {
+#    print STDERR "Error executing $cmd: $!\n";
+#    exit($status);
+#}
+
+print "\nDone: $cmd\n";
Index: /gsdl/stable/bin/script/gsdlinfo.pl
===================================================================
--- /gsdl/stable/bin/script/gsdlinfo.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gsdlinfo.pl	(revision 20131)
@@ -0,0 +1,142 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# gsdlinfo.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# This program will look to see what collections are installed
+# under this file system
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use parsargv;
+use colcfg;
+
+if (scalar(@ARGV) && ($ARGV[0] eq "--help" || $ARGV[0] eq "-h")) {
+    print STDERR "\n";
+    print STDERR "gsdlinfo.pl: Prints information on any Greenstone collections\n";
+    print STDERR "             found on the local file system.\n\n";
+    exit;
+}
+
+
+# the collection information is stored as an array of hashes
+# (one hash for each collection). The hash contains all the 
+# information in the collect and build configuration files
+
+
+# read in all the collection configuration information
+
+opendir (DIR, "$ENV{'GSDLHOME'}/collect") ||
+    die "ERROR - couldn't read the directory $ENV{'GSDLHOME'}/collect\n";
+@dir = readdir (DIR);
+closedir (DIR);
+
+@collections = ();
+foreach $dir (@dir) {
+    if ($dir =~ /^(\..*|modelcol|CVS)$/) {
+	# do nothing
+
+    } else {
+	# read in the collection configuration file
+	my $collectcfg = {};
+	if (-e "$ENV{'GSDLHOME'}/collect/$dir/etc/collect.cfg") {
+	    $collectcfg = &colcfg::read_collect_cfg ("$ENV{'GSDLHOME'}/collect/$dir/etc/collect.cfg");
+	}
+	$collectcfg->{'collection'} = $dir;
+
+	# read in the build configuration file
+	my $buildcfg = {};
+	if (-e "$ENV{'GSDLHOME'}/collect/$dir/index/build.cfg") {
+	    $buildcfg = &colcfg::read_build_cfg ("$ENV{'GSDLHOME'}/collect/$dir/index/build.cfg");
+	}
+
+	# add the merged configuration files to the current list of collections
+	push (@collections, {%$collectcfg, %$buildcfg});
+    }
+}
+
+
+# do any sorting requested
+
+
+# print out the collection information
+
+# {'creator'}->string
+# {'maintainer'}->array of strings
+# {'public'}->string
+# {'beta'}->string
+# {'key'}->string
+# {'indexes'}->array of strings
+# {'defaultindex'}->string
+# {'builddate'}->string
+# {'metadata'}->array of strings
+# {'languages'}->array of strings
+# {'numdocs'}->string
+# {'numwords'}->string
+# {'numbytes'}->string
+
+print "\n";
+foreach $info (@collections) {
+    if (defined $info->{'collection'}) {
+	$collection = $info->{'collection'};
+	if (defined $info->{'public'}) {
+	    $public = $info->{'public'};
+	} else {
+	    $public = "?";
+	}
+	if (defined $info->{'beta'}) {
+	    $beta = $info->{'beta'};
+	} else {
+	    $beta = "?";
+	}
+	if (defined $info->{'numdocs'}) {
+	    $numdocs = $info->{'numdocs'};
+	} else {
+	    $numdocs = "?";
+	}
+	if (defined $info->{'numbytes'}) {
+	    $numMbytes = int(($info->{'numbytes'}/1024.0/1024.0)*1000)/1000.0;
+	} else {
+	    $numMbytes = "?";
+	}
+	write;
+    }
+}
+print "\n";
+
+exit;
+
+format STDOUT_TOP = 
+  name   public  beta   documents  size (Mbytes)
+-------- ------ ------ ----------- -------------
+.
+
+format STDOUT = 
+@>>>>>>> @>>>>> @>>>>> @>>>>>>>>>> @>>>>>>>>>>>>
+$collection, $public, $beta, $numdocs, $numMbytes
+.
Index: /gsdl/stable/bin/script/gsw3mir.pl
===================================================================
--- /gsdl/stable/bin/script/gsw3mir.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gsw3mir.pl	(revision 20131)
@@ -0,0 +1,52 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# urldownload.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will download the specified urls (http:, ftp: and file:)
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan/lib");
+    $ENV{'PATH'} = "$ENV{'GSDLHOME'}/perllib/cpan/bin:$ENV{'PATH'}";
+}
+
+my @quoted_argv = map { "\"$_\"" } @ARGV;
+
+my $args = join(' ', @quoted_argv);
+$cmd = "w3mir $args";
+
+my $status = system($cmd);
+$status /= 256;
+if ($status != 0)
+{
+    print STDERR "Error: failed to execute $cmd\n";
+    exit($status);
+}
+
Index: /gsdl/stable/bin/script/gti-process-spreadsheet.pl
===================================================================
--- /gsdl/stable/bin/script/gti-process-spreadsheet.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gti-process-spreadsheet.pl	(revision 20131)
@@ -0,0 +1,114 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# gti-process-excel-xml.pl
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2005 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+use strict;
+
+
+sub main
+{
+    # Required parameter: the path of the spreadsheet file saved in UTF-16 Excel text format
+    my $utf16_excel_txt_file_path = shift(@_);
+    if (!defined($utf16_excel_txt_file_path)) {
+	die "Usage: gti-process-spreadsheet.pl <txt-file-path>\n";
+    }
+
+    # Ensure the UTF-16 Excel text file exists
+    if (!-f $utf16_excel_txt_file_path) {
+	die "Error: UTF-16 Excel text file $utf16_excel_txt_file_path does not exist.\n";
+    }
+
+    # Convert the Excel text file from UTF-16 to UTF-8
+    my $excel_txt_file_path = $utf16_excel_txt_file_path . "-utf8";
+    if (!-f $excel_txt_file_path) {
+	# Only bother if the file doesn't already exist
+	`iconv -f UTF-16 -t UTF-8 $utf16_excel_txt_file_path -o $excel_txt_file_path`;
+    }
+
+    # Read the (UTF-8) Excel Unicode text file data
+    open(EXCEL_TXT_FILE, $excel_txt_file_path);
+    my @excel_txt_file_lines = <EXCEL_TXT_FILE>;
+    my $excel_txt_file_data = join("", @excel_txt_file_lines);
+    close(EXCEL_TXT_FILE);
+
+    # Remove any nasty carriage returns
+    $excel_txt_file_data =~ s/\r//g;
+
+    # Make sure the first line is where we want it, and remove all stray whitespace
+    $excel_txt_file_data =~ s/^(\n)*/\n\n/;
+    $excel_txt_file_data =~ s/\n(\s*)\n/\n\n/g;
+
+    # Split into chunks
+    my @chunks = split(/\n\nsource::/, $excel_txt_file_data);
+    shift(@chunks);  # Ignore the first (empty) chunk
+    print STDERR "Number of chunks: " . scalar(@chunks) . "\n";
+
+    # Check we've split the chunks correctly
+    my $total_number_of_chunks = ($excel_txt_file_data =~ s/source::/source::/g);
+    if (scalar(@chunks) != $total_number_of_chunks) {
+	die "Error: Expected $total_number_of_chunks chunks but only have " . scalar(@chunks) . " from splitting";
+    }
+
+    # Process each submitted chunk
+    foreach my $chunk (@chunks) {
+ 	my $source_file_chunk = (split(/\ntarget::/, $chunk))[0];
+ 	my $target_file_chunk = (split(/\ntarget::/, $chunk))[1];
+
+ 	# Parse the chunk key and chunk text
+ 	$source_file_chunk =~ /^(\S+)\s+((.|\n)*)$/;
+ 	my $source_file_chunk_key = $1;
+ 	my $source_file_chunk_text = $2;
+ 	$target_file_chunk =~ /^(\S+)\s+((.|\n)*)$/;
+ 	my $target_file_chunk_key = $1;
+ 	my $target_file_chunk_text = $2;
+
+ 	# Remove the quotes around multiline chunks
+ 	if ($source_file_chunk_text =~ /^\"/ && $source_file_chunk_text =~ /\"$/) {
+ 	    $source_file_chunk_text =~ s/^\"//;
+ 	    $source_file_chunk_text =~ s/\"$//;
+ 	}
+ 	if ($target_file_chunk_text =~ /^\"/ && $target_file_chunk_text =~ /\"$/) {
+ 	    $target_file_chunk_text =~ s/^\"//;
+ 	    $target_file_chunk_text =~ s/\"$//;
+ 	}
+
+        # Remove the blank space Excel adds at the start of each line
+ 	$source_file_chunk_text =~ s/\n /\n/g;
+ 	$target_file_chunk_text =~ s/\n /\n/g;
+
+ 	# Remove Excel's doubled-up quotes
+ 	$source_file_chunk_text =~ s/\"\"/\"/g;
+ 	$target_file_chunk_text =~ s/\"\"/\"/g;
+
+ 	print "<SourceFileText key=\"" . $source_file_chunk_key . "\">\n" . $source_file_chunk_text . "\n</SourceFileText>\n";
+ 	print "<TargetFileText key=\"" . $target_file_chunk_key . "\">\n" . $target_file_chunk_text . "\n</TargetFileText>\n";
+    }
+}
+
+
+&main(@ARGV);
Index: /gsdl/stable/bin/script/gti.pl
===================================================================
--- /gsdl/stable/bin/script/gti.pl	(revision 20131)
+++ /gsdl/stable/bin/script/gti.pl	(revision 20131)
@@ -0,0 +1,1862 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# gti.pl
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2005 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+
+use iso639;
+use strict;
+use util;
+
+
+#my $anonymous_cvs_root = ":pserver:cvs_anon\@cvs.scms.waikato.ac.nz:2402/usr/local/global-cvs/gsdl-src";
+#my $anonymous_svn_root = "http://http://svn.greenstone.org/gsdl/trunk/";
+my $gsdl_root_directory = "$ENV{'GSDLHOME'}";
+my $gti_log_file = &util::filename_cat($gsdl_root_directory, "etc", "gti.log");
+my $source_language_code = "en";  # This is non-negiotable
+
+my $gti_translation_files =
+    [ # Greenstone macrofiles
+      { 'key' => "coredm",
+	'file_type' => "macrofile",
+	'source_file' => "macros/english.dm",
+	'target_file' => "macros/{bn:bengali;fa:farsi;gd:gaelic;id:indo;lv:latvian;pt-br:port-br;pt-pt:port-pt;zh-tr:chinese-trad;iso_639_1_target_language_name}.dm" },
+      { 'key' => "auxdm",
+	'file_type' => "macrofile",
+	'source_file' => "macros/english2.dm",
+	'target_file' => "macros/{bn:bengali;fa:farsi;gd:gaelic;id:indo;lv:latvian;pt-br:port-br;pt-pt:port-pt;zh-tr:chinese-trad;iso_639_1_target_language_name}2.dm" },
+
+      # GLI dictionary
+      { 'key' => "glidict",
+	'file_type' => "resource_bundle",
+	'source_file' => "gli/classes/dictionary.properties",
+	'target_file' => "gli/classes/dictionary_{target_language_code}.properties" },
+
+      # GLI help
+      { 'key' => "glihelp",
+	'file_type' => "greenstone_xml",
+	'source_file' => "gli/help/en/help.xml",
+	'target_file' => "gli/help/{target_language_code}/help.xml" },
+
+      # Greenstone Perl modules
+      { 'key' => "perlmodules",
+	'file_type' => "resource_bundle",
+	'source_file' => "perllib/strings.properties",
+	'target_file' => "perllib/strings_{target_language_code}.properties" },
+
+      # Greenstone tutorial exercises
+      # { 'key' => "tutorials",
+	# 'file_type' => "greenstone_xml",
+	# 'source_file' => "gsdl-documentation/tutorials/xml-source/tutorial_en.xml",
+	# 'target_file' => "gsdl-documentation/tutorials/xml-source/tutorial_{target_language_code}.xml" },
+
+      # new Greenstone.org
+      { 'key' => "greenorg",
+        'file_type' => "resource_bundle",
+        'source_file' => "greenstoneorg/website/classes/Gsc.properties",
+        'target_file' => "greenstoneorg/website/classes/Gsc_{iso_639_1_target_language_name}.properties" 
+	# 'file_type' => "macrofile",
+	# 'source_file' => "greenorg/macros/english.dm",
+	# 'target_file' => "greenorg/macros/{iso_639_1_target_language_name}.dm" 
+      }
+
+      # { 'key' => "gs3interface",
+	#'file_type' => "resource_bundle",
+	#'source_file' => "greenstone3",
+	#'target_file' => "greenstone3"
+      #}
+    ];
+
+my @gs3_interface_files = ("AbstractBrowse", "AbstractGS2FieldSearch", "Authentication", "CrossCollectionSearch", "GATEServices", "GS2Construct", "GS2LuceneSearch", "interface_default", "interface_nzdl", "IViaSearch", "LuceneSearch", "MapRetrieve", "MapSearch", "metadata_names", "PhindPhraseBrowse", "QBRWebServicesHelp", "Visualizer");
+
+
+sub main
+{
+    # Get the command to process, and any arguments
+    my $gti_command = shift(@_);
+    my @gti_command_arguments = @_;
+    my $module = $_[1];
+
+    # Open the GTI log file for appending, or write to STDERR if that fails
+    if (!open(GTI_LOG, ">>$gti_log_file")) {
+	open(GTI_LOG, ">&STDERR");
+    }
+
+    # Log the command that launched this script
+    &log_message("Command: $0 @ARGV");
+
+    # Check that a command was supplied
+    if (!$gti_command) {
+	&throw_fatal_error("Missing command.");
+    }      
+
+    # Process the command
+    if ($gti_command =~ /^get-all-chunks$/i) {
+	# Check that GS3 interface is the target
+	if ($module eq "gs3interface") {	   
+	    print &get_all_chunks_for_gs3(@gti_command_arguments);
+	} else {
+	    print &get_all_chunks(@gti_command_arguments);
+	}
+    }
+    if ($gti_command =~ /^get-first-n-chunks-requiring-work$/i) {
+	if ($module eq "gs3interface") {	   
+	    print &get_first_n_chunks_requiring_work_for_gs3(@gti_command_arguments);
+	} else {
+	    print &get_first_n_chunks_requiring_work(@gti_command_arguments);
+	}
+    }
+    if ($gti_command =~ /^get-language-status$/i) {
+	print &get_language_status(@gti_command_arguments);       
+    }
+    if ($gti_command =~ /^search-chunks$/i) {
+	print &search_chunks(@gti_command_arguments);
+    }
+    if ($gti_command =~ /^submit-translations$/i) {
+	# This command cannot produce any output since it reads input
+	&submit_translations(@gti_command_arguments);
+    }
+    if ($gti_command =~ /^create-glihelp-zip-file$/i) {
+	# This command cannot produce any output since it reads input
+	&create_glihelp_zip_file(@gti_command_arguments);
+    }
+#    else {
+	# The command was not recognized
+	#&throw_fatal_error("Unknown command \"$gti_command\".");
+    #}
+}
+
+
+sub throw_fatal_error
+{
+    my $error_message = shift(@_);
+
+    # Write an XML error response
+    print "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+    print "<GTIResponse>\n";
+    print "  <GTIError time=\"" . time() . "\">" . $error_message . "</GTIError>\n";
+    print "</GTIResponse>\n";
+
+    # Log the error message, then die
+    &log_message("Error: $error_message");
+    die "\n";
+}
+
+
+sub log_message
+{
+    my $log_message = shift(@_);
+    print GTI_LOG time() . " -- " . $log_message . "\n";
+}
+
+
+sub get_all_chunks
+{
+    # The code of the target language (ensure it is lowercase)
+    my $target_language_code = lc(shift(@_));
+    # The key of the file to translate (ensure it is lowercase)
+    my $translation_file_key = lc(shift(@_));
+
+    # Check that the necessary arguments were supplied
+    if (!$target_language_code || !$translation_file_key) {
+	&throw_fatal_error("Missing command argument.");
+    }
+
+    # Get (and check) the translation configuration
+    my ($source_file, $target_file, $translation_file_type)
+	= &get_translation_configuration($target_language_code, $translation_file_key);
+
+    # Parse the source language and target language files
+    my $source_file_path = &util::filename_cat($gsdl_root_directory, $source_file);
+    my @source_file_lines = &read_file_lines($source_file_path);
+    my %source_file_key_to_line_mapping = &build_key_to_line_mapping(\@source_file_lines, $translation_file_type);
+    
+    my $target_file_path = &util::filename_cat($gsdl_root_directory, $target_file);
+    my @target_file_lines = &read_file_lines($target_file_path);
+    my %target_file_key_to_line_mapping = &build_key_to_line_mapping(\@target_file_lines, $translation_file_type);
+
+    # Filter out any automatically translated chunks
+    foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
+	if (&is_chunk_automatically_translated($chunk_key, $translation_file_type)) {
+	    delete $source_file_key_to_line_mapping{$chunk_key};
+	    delete $target_file_key_to_line_mapping{$chunk_key};
+	}
+    }
+
+    my %source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+    my %target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+    &log_message("Number of source chunks: " . scalar(keys(%source_file_key_to_text_mapping)));
+    &log_message("Number of target chunks: " . scalar(keys(%target_file_key_to_text_mapping)));
+
+    my %source_file_key_to_last_update_date_mapping = &build_key_to_last_update_date_mapping($source_file, \@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+    my %target_file_key_to_last_update_date_mapping = &build_key_to_last_update_date_mapping($target_file, \@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+
+    my $xml_response = &create_xml_response_for_all_chunks($translation_file_key, $target_file, \%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping, \%source_file_key_to_last_update_date_mapping, \%target_file_key_to_last_update_date_mapping);   
+    
+    return $xml_response;
+}
+
+
+sub get_first_n_chunks_requiring_work
+{
+    # The code of the target language (ensure it is lowercase)
+    my $target_language_code = lc(shift(@_));
+    # The key of the file to translate (ensure it is lowercase)
+    my $translation_file_key = lc(shift(@_));
+    # The number of chunks to return (defaults to one if not specified)
+    my $num_chunks_to_return = shift(@_) || "1";
+
+    # Check that the necessary arguments were supplied
+    if (!$target_language_code || !$translation_file_key) {
+	&throw_fatal_error("Missing command argument.");
+    }
+
+    # Get (and check) the translation configuration
+    my ($source_file, $target_file, $translation_file_type)
+	= &get_translation_configuration($target_language_code, $translation_file_key);
+
+    # Parse the source language and target language files
+    my $source_file_path = &util::filename_cat($gsdl_root_directory, $source_file);
+    my @source_file_lines = &read_file_lines($source_file_path);
+    my %source_file_key_to_line_mapping = &build_key_to_line_mapping(\@source_file_lines, $translation_file_type);
+    
+    my $target_file_path = &util::filename_cat($gsdl_root_directory, $target_file);
+    my @target_file_lines = &read_file_lines($target_file_path);
+    my %target_file_key_to_line_mapping = &build_key_to_line_mapping(\@target_file_lines, $translation_file_type);
+
+    # Filter out any automatically translated chunks
+    foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
+	if (&is_chunk_automatically_translated($chunk_key, $translation_file_type)) {
+	    delete $source_file_key_to_line_mapping{$chunk_key};
+	    delete $target_file_key_to_line_mapping{$chunk_key};
+	}
+    }
+
+    my %source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+    my %target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+    &log_message("Number of source chunks: " . scalar(keys(%source_file_key_to_text_mapping)));
+    &log_message("Number of target chunks: " . scalar(keys(%target_file_key_to_text_mapping)));
+
+    # Determine the target file chunks requiring translation
+    my @target_file_keys_requiring_translation = &determine_chunks_requiring_translation(\%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping);
+    &log_message("Number of target chunks requiring translation: " . scalar(@target_file_keys_requiring_translation));
+
+    # Determine the target file chunks requiring updating
+    my %source_file_key_to_last_update_date_mapping = &build_key_to_last_update_date_mapping($source_file, \@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+    my %target_file_key_to_last_update_date_mapping = &build_key_to_last_update_date_mapping($target_file, \@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+    my @target_file_keys_requiring_updating = &determine_chunks_requiring_updating(\%source_file_key_to_last_update_date_mapping, \%target_file_key_to_last_update_date_mapping);
+    &log_message("Number of target chunks requiring updating: " . scalar(@target_file_keys_requiring_updating));
+
+    my $xml_response = &create_xml_response_for_chunks_requiring_work($translation_file_key, $target_file, scalar(keys(%source_file_key_to_text_mapping)), \@target_file_keys_requiring_translation, \@target_file_keys_requiring_updating, $num_chunks_to_return, \%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping, \%source_file_key_to_last_update_date_mapping, \%target_file_key_to_last_update_date_mapping);   
+    
+    return $xml_response;
+}
+
+
+sub get_language_status
+{
+    # The code of the target language (ensure it is lowercase)
+    my $target_language_code = lc(shift(@_));
+
+    # Check that the necessary arguments were supplied
+    if (!$target_language_code) {
+	&throw_fatal_error("Missing command argument.");
+    }
+
+    # Form an XML response to the command
+    my $xml_response = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+    $xml_response .= "<GTIResponse>\n";
+    $xml_response .= "  <LanguageStatus code=\"$target_language_code\">\n";
+
+    foreach my $translation_file (@$gti_translation_files) {	
+	my ($num_source_chunks, $num_target_chunks, $num_chunks_requiring_translation, $num_chunks_requiring_updating) = 0;
+	my $target_file_name = "";
+	
+	if ($translation_file->{'key'} eq "gs3interface") {
+	    my (%source_file_key_to_text_mapping, %target_file_key_to_text_mapping, %source_file_key_to_last_update_date_mapping, %target_file_key_to_last_update_date_mapping ) = ();
+	    &build_gs3_configuration($target_language_code, \%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping, \%source_file_key_to_last_update_date_mapping, \%target_file_key_to_last_update_date_mapping );    
+	    
+	    my @target_file_keys_requiring_translation = &determine_chunks_requiring_translation(\%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping);	    
+	    my @target_file_keys_requiring_updating = &determine_chunks_requiring_updating(\%source_file_key_to_last_update_date_mapping, \%target_file_key_to_last_update_date_mapping);
+
+	    $num_source_chunks = scalar(keys(%source_file_key_to_text_mapping));
+	    $num_target_chunks = scalar(keys(%target_file_key_to_text_mapping));
+	    $num_chunks_requiring_translation = scalar(@target_file_keys_requiring_translation);
+	    $num_chunks_requiring_updating = scalar(@target_file_keys_requiring_updating);
+	}
+	else {
+	    # Get (and check) the translation configuration
+	    my ($source_file, $target_file, $translation_file_type) = &get_translation_configuration($target_language_code, $translation_file->{'key'});
+	    $target_file_name = $target_file;
+
+	    # Parse the source language and target language files
+	    my $source_file_path = &util::filename_cat($gsdl_root_directory, $source_file);
+	    my @source_file_lines = &read_file_lines($source_file_path);
+	    my %source_file_key_to_line_mapping = &build_key_to_line_mapping(\@source_file_lines, $translation_file_type);
+
+	    my $target_file_path = &util::filename_cat($gsdl_root_directory, $target_file);
+	    my @target_file_lines = &read_file_lines($target_file_path);
+	    my %target_file_key_to_line_mapping = &build_key_to_line_mapping(\@target_file_lines, $translation_file_type);
+
+	    # Filter out any automatically translated chunks
+	    foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
+		if (&is_chunk_automatically_translated($chunk_key, $translation_file_type)) {
+		    delete $source_file_key_to_line_mapping{$chunk_key};
+		    delete $target_file_key_to_line_mapping{$chunk_key};
+		}
+	    }
+
+	    my %source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+	    my %target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+
+	    # Determine the target file chunks requiring translation
+	    my @target_file_keys_requiring_translation = &determine_chunks_requiring_translation(\%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping);	    
+
+	    # Determine the target file chunks requiring updating
+	    my @target_file_keys_requiring_updating = ();
+	    if (-e $target_file_path) {
+		my %source_file_key_to_last_update_date_mapping = &build_key_to_last_update_date_mapping($source_file, \@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+		my %target_file_key_to_last_update_date_mapping = &build_key_to_last_update_date_mapping($target_file, \@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+		@target_file_keys_requiring_updating = &determine_chunks_requiring_updating(\%source_file_key_to_last_update_date_mapping, \%target_file_key_to_last_update_date_mapping);		
+	    }
+
+	    $num_source_chunks = scalar(keys(%source_file_key_to_text_mapping));
+	    $num_target_chunks = scalar(keys(%target_file_key_to_text_mapping));
+	    $num_chunks_requiring_translation = scalar(@target_file_keys_requiring_translation);
+	    $num_chunks_requiring_updating = scalar(@target_file_keys_requiring_updating);
+	}
+	
+	&log_message("Status of " . $translation_file->{'key'});
+	&log_message("Number of source chunks: " . $num_source_chunks);
+	&log_message("Number of target chunks: " . $num_target_chunks);
+	&log_message("Number of target chunks requiring translation: " . $num_chunks_requiring_translation);
+	&log_message("Number of target chunks requiring updating: " . $num_chunks_requiring_updating);
+
+	$xml_response .= "    <TranslationFile"
+	    . " key=\"" . $translation_file->{'key'} . "\""
+	    . " target_file_path=\"" . $target_file_name . "\""
+	    . " num_chunks_translated=\"" . ($num_source_chunks - $num_chunks_requiring_translation) . "\""
+	    . " num_chunks_requiring_translation=\"" . $num_chunks_requiring_translation . "\""
+	    . " num_chunks_requiring_updating=\"" . $num_chunks_requiring_updating . "\"\/>\n";
+    }
+
+    $xml_response .= "  </LanguageStatus>\n";
+
+    $xml_response .= "</GTIResponse>\n";
+    return $xml_response;
+}
+
+
+sub search_chunks
+{
+    # The code of the target language (ensure it is lowercase)
+    my $target_language_code = lc(shift(@_));
+    # The key of the file to translate (ensure it is lowercase)
+    my $translation_file_key = lc(shift(@_));
+    # The query string
+    my $query_string = join(' ', @_);
+
+    # Check that the necessary arguments were supplied
+    if (!$target_language_code || !$translation_file_key || !$query_string) {
+	&throw_fatal_error("Missing command argument.");
+    }
+
+    my ($source_file, $target_file, $translation_file_type) = ();
+    my %source_file_key_to_text_mapping = ();
+    my %target_file_key_to_text_mapping = ();
+    
+    
+    if ($translation_file_key ne "gs3interface") {
+	# Get (and check) the translation configuration
+	($source_file, $target_file, $translation_file_type) = &get_translation_configuration($target_language_code, $translation_file_key);
+
+	# Parse the source language and target language files
+	my $source_file_path = &util::filename_cat($gsdl_root_directory, $source_file);
+	my @source_file_lines = &read_file_lines($source_file_path);
+	my %source_file_key_to_line_mapping = &build_key_to_line_mapping(\@source_file_lines, $translation_file_type);
+
+	my $target_file_path = &util::filename_cat($gsdl_root_directory, $target_file);
+	my @target_file_lines = &read_file_lines($target_file_path);
+	my %target_file_key_to_line_mapping = &build_key_to_line_mapping(\@target_file_lines, $translation_file_type);
+
+	# Filter out any automatically translated chunks
+	foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
+	    if (&is_chunk_automatically_translated($chunk_key, $translation_file_type)) {
+		delete $source_file_key_to_line_mapping{$chunk_key};
+		delete $target_file_key_to_line_mapping{$chunk_key};
+	    }
+	}
+
+	%source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+	%target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+    }
+    else {
+	# Not needed in this case
+	my (%source_file_key_to_gti_command_mapping, %target_file_key_to_gti_command_mapping) = ();
+	&build_gs3_configuration($target_language_code, \%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping,
+				 \%source_file_key_to_gti_command_mapping, \%target_file_key_to_gti_command_mapping);
+    }
+
+    &log_message("Number of source chunks: " . scalar(keys(%source_file_key_to_text_mapping)));
+    &log_message("Number of target chunks: " . scalar(keys(%target_file_key_to_text_mapping)));
+
+    # Determine the target file chunks matching the query
+    my @target_file_keys_matching_query = ();
+    foreach my $chunk_key (keys(%target_file_key_to_text_mapping)) {
+	my $target_file_text = $target_file_key_to_text_mapping{$chunk_key};
+	if ($target_file_text =~ /$query_string/i) {
+	    # &log_message("Chunk with key $chunk_key matches query.");
+	    push(@target_file_keys_matching_query, $chunk_key);
+	}
+    }
+
+    # Form an XML response to the command
+    my $xml_response = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+    $xml_response .= "<GTIResponse>\n";
+
+    $xml_response .= "  <ChunksMatchingQuery size=\"" . scalar(@target_file_keys_matching_query) . "\">\n";
+    foreach my $chunk_key (@target_file_keys_matching_query) {
+ 	my $target_file_chunk_text = &make_text_xml_safe($target_file_key_to_text_mapping{$chunk_key});
+
+ 	$xml_response .= "    <Chunk key=\"$chunk_key\">\n";
+ 	$xml_response .= "      <TargetFileText>$target_file_chunk_text</TargetFileText>\n";
+ 	$xml_response .= "    </Chunk>\n";
+    }
+    $xml_response .= "  </ChunksMatchingQuery>\n";
+
+    $xml_response .= "</GTIResponse>\n";
+    return $xml_response;
+}
+
+
+sub submit_translations
+{
+    # The code of the target language (ensure it is lowercase)
+    my $target_language_code = lc(shift(@_));
+    # The key of the file to translate (ensure it is lowercase)
+    my $translation_file_key = lc(shift(@_));
+    # The username of the translation submitter
+    my $submitter_username = shift(@_);
+    # Whether to submit a target chunk even if it hasn't changed
+    my $force_submission_flag = shift(@_);
+
+    # Check that the necessary arguments were supplied
+    if (!$target_language_code || !$translation_file_key || !$submitter_username) {
+	&log_message("Fatal error (but cannot be thrown): Missing command argument.");
+	die "\n";
+    }
+    
+    my %source_file_key_to_text_mapping = ();
+    my %source_file_key_to_gti_comment_mapping = ();
+    my %target_file_key_to_text_mapping = ();
+    my %target_file_key_to_gti_comment_mapping = ();
+
+    my (@source_file_lines, @target_file_lines) = ();
+    my ($source_file, $target_file, $translation_file_type);
+
+    
+    if ($translation_file_key ne "gs3interface") {
+	# Get (and check) the translation configuration
+	($source_file, $target_file, $translation_file_type)
+	    = &get_translation_configuration($target_language_code, $translation_file_key);
+
+	# Parse the source language and target language files
+	@source_file_lines = &read_file_lines(&util::filename_cat($gsdl_root_directory, $source_file));
+	my %source_file_key_to_line_mapping = &build_key_to_line_mapping(\@source_file_lines, $translation_file_type);
+	%source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+	%source_file_key_to_gti_comment_mapping = &build_key_to_gti_comment_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);	
+
+	@target_file_lines = &read_file_lines(&util::filename_cat($gsdl_root_directory, $target_file));
+	my %target_file_key_to_line_mapping = &build_key_to_line_mapping(\@target_file_lines, $translation_file_type);
+	%target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+	%target_file_key_to_gti_comment_mapping = &build_key_to_gti_comment_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);	
+    } 
+    else {
+	&build_gs3_configuration($target_language_code, \%source_file_key_to_text_mapping, \%target_file_key_to_text_mapping, 
+				 \%source_file_key_to_gti_comment_mapping, \%target_file_key_to_gti_comment_mapping);
+    }
+    &log_message("Number of source chunks: " . scalar(keys(%source_file_key_to_text_mapping)));
+    &log_message("Number of target chunks: " . scalar(keys(%target_file_key_to_text_mapping)));
+
+    # Submission date
+    my $day = (localtime)[3];
+    my $month = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")[(localtime)[4]];
+    my $year = (localtime)[5] + 1900;
+    my $submission_date = "$day-$month-$year";
+
+    open(SUBMISSION, "-");
+    my @submission_lines = <SUBMISSION>;
+    close(SUBMISSION);
+
+    # Remove any nasty carriage returns
+    # &log_message("Submission:");
+    foreach my $submission_line (@submission_lines) {
+	$submission_line =~ s/\r$//;
+	#&log_message("  $submission_line");
+    }
+
+    my %source_file_key_to_submission_mapping = ();
+    my %target_file_key_to_submission_mapping = ();
+    for (my $i = 0; $i < scalar(@submission_lines); $i++) {
+	# Read source file part of submission
+	if ($submission_lines[$i] =~ /^\<SourceFileText key=\"(.+)\"\>/) {
+	    my $chunk_key = $1;
+
+	    # Read the source file text
+	    my $source_file_chunk_text = "";
+	    $i++;
+	    while ($i < scalar(@submission_lines) && $submission_lines[$i] !~ /^\<\/SourceFileText\>/) {
+		$source_file_chunk_text .= $submission_lines[$i];
+ 		$i++;
+	    }
+	    $source_file_chunk_text =~ s/\n$//;  # Strip the extra newline character added
+	    $source_file_chunk_text = &unmake_text_xml_safe($source_file_chunk_text);
+
+	    #&log_message("Source file key: $chunk_key");
+	    #&log_message("Source file text: $source_file_chunk_text");
+	    $source_file_key_to_submission_mapping{$chunk_key} = $source_file_chunk_text;
+	}
+
+	# Read target file part of submission
+	if ($submission_lines[$i] =~ /^\<TargetFileText key=\"(.+)\"\>/) {
+	    my $chunk_key = $1;
+
+	    # Read the target file text
+	    my $target_file_chunk_text = "";
+	    $i++;
+	    while ($i < scalar(@submission_lines) && $submission_lines[$i] !~ /^\<\/TargetFileText\>/) {
+		$target_file_chunk_text .= $submission_lines[$i];
+ 		$i++;
+	    }
+	    $target_file_chunk_text =~ s/\n$//;  # Strip the extra newline character added
+	    $target_file_chunk_text = &unmake_text_xml_safe($target_file_chunk_text);
+
+	    #&log_message("Target file key: $chunk_key");
+	    #&log_message("Target file text: $target_file_chunk_text");
+	    $target_file_key_to_submission_mapping{$chunk_key} = $target_file_chunk_text;
+	}
+    }
+
+    # -----------------------------------------
+    #   Validate the translation submissions
+    # -----------------------------------------
+
+    # Check that the translations are valid
+    foreach my $chunk_key (keys(%source_file_key_to_submission_mapping)) {
+	# Make sure the submitted chunk still exists in the source file
+	if (!defined($source_file_key_to_text_mapping{$chunk_key})) {
+	    &log_message("Warning: Source chunk $chunk_key no longer exists (ignoring submission).");
+	    delete $source_file_key_to_submission_mapping{$chunk_key};
+	    delete $target_file_key_to_submission_mapping{$chunk_key};
+	    next;
+	}
+
+	# Make sure the submitted source chunk matches the source file chunk
+	if ($source_file_key_to_submission_mapping{$chunk_key} ne &unmake_text_xml_safe($source_file_key_to_text_mapping{$chunk_key})) {
+	    &log_message("Warning: Source chunk $chunk_key has changed (ignoring submission).");
+	    &log_message("Submission source: $source_file_key_to_submission_mapping{$chunk_key}");
+	    &log_message("      Source text: $source_file_key_to_text_mapping{$chunk_key}");
+	    delete $source_file_key_to_submission_mapping{$chunk_key};
+	    delete $target_file_key_to_submission_mapping{$chunk_key};
+	    next;
+	}
+    }
+
+    # Apply the submitted translations
+    foreach my $chunk_key (keys(%target_file_key_to_submission_mapping)) {
+	# Only apply the submission if it is a change, unless -force_submission has been specified
+	if ($force_submission_flag || !defined($target_file_key_to_text_mapping{$chunk_key}) || $target_file_key_to_submission_mapping{$chunk_key} ne $target_file_key_to_text_mapping{$chunk_key}) {
+	    $target_file_key_to_text_mapping{$chunk_key} = $target_file_key_to_submission_mapping{$chunk_key};
+	    $target_file_key_to_gti_comment_mapping{$chunk_key} = "Updated $submission_date by $submitter_username";
+	}
+    }
+    
+    if ($translation_file_key ne "gs3interface") {
+	eval "&write_translated_${translation_file_type}(\$source_file, \\\@source_file_lines, \\\%source_file_key_to_text_mapping, \$target_file, \\\@target_file_lines, \\\%target_file_key_to_text_mapping, \\\%target_file_key_to_gti_comment_mapping, \$target_language_code)";
+    } else {
+	eval "&write_translated_gs3interface(\\\%source_file_key_to_text_mapping, \\\%target_file_key_to_text_mapping, \\\%target_file_key_to_gti_comment_mapping, \$target_language_code)";
+    }
+}
+
+
+sub create_glihelp_zip_file
+{
+    my $target_language_code = shift(@_);
+    my $translation_file_key = "glihelp";
+    
+    &log_message("Creating GLI Help zip file for $target_language_code");
+
+    my ($source_file, $target_file, $translation_file_type) = &get_translation_data_for($target_language_code, $translation_file_key);    
+    
+    my $classpath = &util::filename_cat($gsdl_root_directory, "gti-lib");
+    if ( ! -e $classpath) {
+	&throw_fatal_error("$classpath doesn't exist! Need the files in this directory (ApplyXLST and its related files) to create the zip file for GLI Help");
+    }    
+    
+    my $gli_help_directory = &util::filename_cat($gsdl_root_directory, "gli");
+    $gli_help_directory = &util::filename_cat($gli_help_directory, "help");
+    
+    my $gen_many_html_xsl_filepath = &util::filename_cat($gli_help_directory, "gen-many-html.xsl");
+    if ( ! -e $gen_many_html_xsl_filepath) {
+	&throw_fatal_error("$gen_many_html_xsl_filepath doesn't exist! Need this file to create the zip file for GLI Help");
+    }
+
+    my $gen_index_xml_xsl_filepath = &util::filename_cat($gli_help_directory, "gen-index-xml.xsl");   
+    my $split_script_filepath = &util::filename_cat($gli_help_directory, "splithelpdocument.pl");   
+    
+    my $target_file_directory = &util::filename_cat($gli_help_directory, $target_language_code);
+    $target_file_directory = $target_file_directory."/";
+
+    my $target_filepath = &util::filename_cat($gsdl_root_directory, $target_file);
+    my $cmd = "/opt/jdk1.6.0/bin/java -cp $classpath:$classpath/xalan.jar ApplyXSLT $target_language_code $gen_many_html_xsl_filepath $target_filepath | perl -S $split_script_filepath $target_file_directory";
+    my $response = `$cmd`;
+    &log_message($cmd);
+    &log_message($response);    
+    &log_message("Created HTML operational files");
+    
+    $cmd = "/opt/jdk1.6.0/bin/java -cp $classpath:$classpath/xalan.jar ApplyXSLT $target_language_code $gen_index_xml_xsl_filepath $target_filepath > " . $target_file_directory . "help_index.xml"; # 2>/dev/null";
+    $response = `$cmd`;
+    &log_message($cmd);
+    &log_message($response);    
+    &log_message("Created xml index file");
+
+    my $zip_file_path = "/greenstone/custom/gti/" . $target_language_code . "_GLIHelp.zip";
+    $cmd = "zip -rj $zip_file_path $target_file_directory -i \*.htm \*.xml";
+    $response = `$cmd`;
+    &log_message($cmd);
+    &log_message($response);    
+    &log_message("Created the zip file");
+}
+
+
+sub get_translation_configuration
+{
+    # Get the code of the target language
+    my $target_language_code = shift(@_);
+    # Get the key of the file to translate
+    my $translation_file_key = shift(@_);
+
+    # Read the translation data from the gti.cfg file
+    my ($source_file, $target_file, $translation_file_type) =
+	&get_translation_data_for($target_language_code, $translation_file_key);
+
+    # Check that the file to translate is defined in the gti.cfg file
+    if (!$source_file || !$target_file || !$translation_file_type) {
+	&throw_fatal_error("Missing or incomplete specification for translation file \"$translation_file_key\" in gti.pl.");
+    }
+
+    # Check that the source file exists
+    my $source_file_path = &util::filename_cat($gsdl_root_directory, $source_file);
+    if (!-e $source_file_path) {
+	&throw_fatal_error("Source file $source_file_path does not exist.");
+    }
+
+    # Check that the source file is up to date
+    # The "2>/dev/null" is very important! If it is missing this will never return when run from the receptionist
+    # unless ($translation_file_is_not_in_cvs) {
+	#my $source_file_cvs_status = `cd $gsdl_root_directory; cvs -d $anonymous_cvs_root update $source_file 2>/dev/null`;
+        my $source_file_cvs_status = `cd $gsdl_root_directory; svn status $source_file 2>/dev/null`;
+	if ($source_file_cvs_status =~ /^C /) {
+	    &throw_fatal_error("Source file $source_file_path conflicts with the repository.");
+	}
+	if ($source_file_cvs_status =~ /^M /) {
+	    &throw_fatal_error("Source file $source_file_path contains uncommitted changes.");
+	}
+    # }
+
+    return ($source_file, $target_file, $translation_file_type);
+}
+
+
+sub get_translation_data_for
+{
+    my ($target_language_code, $translation_file_key) = @_;
+
+    foreach my $translation_file (@$gti_translation_files) {
+	# If this isn't the correct translation file, move onto the next one
+	next if ($translation_file_key ne $translation_file->{'key'});
+
+	# Resolve the target language file
+	my $target_language_file = $translation_file->{'target_file'};
+	if ($target_language_file =~ /(\{.+\;.+\})/) {
+	    my $unresolved_target_language_file_part = $1;
+
+	    # Check for a special case for the target language code
+	    if ($unresolved_target_language_file_part =~ /(\{|\;)$target_language_code:([^\;]+)(\;|\})/) {
+		my $resolved_target_language_file_part = $2;
+		$target_language_file =~ s/$unresolved_target_language_file_part/$resolved_target_language_file_part/;
+	    }
+	    # Otherwise use the last part as the default value
+	    else {
+		my ($default_target_language_file_part) = $unresolved_target_language_file_part =~ /([^\;]+)\}/;
+		$target_language_file =~ s/$unresolved_target_language_file_part/\{$default_target_language_file_part\}/;		    
+	    }
+	}
+
+	# Resolve instances of {iso_639_1_target_language_name}
+	my $iso_639_1_target_language_name = $iso639::fromiso639{$target_language_code};
+	$iso_639_1_target_language_name =~ tr/A-Z/a-z/ if $iso_639_1_target_language_name;
+	$target_language_file =~ s/\{iso_639_1_target_language_name\}/$iso_639_1_target_language_name/g;
+
+	# Resolve instances of {target_language_code}
+	$target_language_file =~ s/\{target_language_code\}/$target_language_code/g;
+
+	return ($translation_file->{'source_file'}, $target_language_file, $translation_file->{'file_type'});
+    }
+
+    return ();
+}
+
+
+sub read_file_lines
+{
+    my ($file_path) = @_;
+
+    if (!open(FILE_IN, "<$file_path")) {
+	&log_message("Note: Could not open file $file_path.");
+	return ();
+    }
+    my @file_lines = <FILE_IN>;
+    close(FILE_IN);
+
+    return @file_lines;
+}
+
+
+sub build_key_to_line_mapping
+{
+    my ($file_lines, $translation_file_type) = @_;
+    eval "return &build_key_to_line_mapping_for_${translation_file_type}(\@\$file_lines)";
+}
+
+
+sub build_key_to_text_mapping
+{
+    my ($file_lines, $key_to_line_mapping, $translation_file_type) = @_;
+
+    my %key_to_text_mapping = ();
+    foreach my $chunk_key (keys(%$key_to_line_mapping)) {
+	my $chunk_starting_line = (split(/-/, $key_to_line_mapping->{$chunk_key}))[0];
+	my $chunk_finishing_line = (split(/-/, $key_to_line_mapping->{$chunk_key}))[1];
+
+	my $chunk_text = @$file_lines[$chunk_starting_line];
+	for (my $l = ($chunk_starting_line + 1); $l <= $chunk_finishing_line; $l++) {
+	    $chunk_text .= @$file_lines[$l];
+	}
+
+	# Map from chunk key to text
+	eval "\$key_to_text_mapping{\${chunk_key}} = &import_chunk_from_${translation_file_type}(\$chunk_text)";
+    }
+
+    return %key_to_text_mapping;
+}
+
+
+sub build_key_to_last_update_date_mapping
+{
+    my ($file, $file_lines, $key_to_line_mapping, $translation_file_type) = @_;
+
+    # If the files aren't in CVS then we can't tell anything about what needs updating
+    # return () if ($translation_file_is_not_in_cvs);
+
+    # Build a mapping from key to CVS date
+    # Need to be careful with this mapping because the chunk keys won't necessarily all be valid
+    my %key_to_cvs_date_mapping = &build_key_to_cvs_date_mapping($file, $translation_file_type);
+
+    # Build a mapping from key to comment date
+    my %key_to_gti_comment_mapping = &build_key_to_gti_comment_mapping($file_lines, $key_to_line_mapping, $translation_file_type);
+
+    # Build a mapping from key to last update date (the latter of the CVS date and comment date)
+    my %key_to_last_update_date_mapping = ();
+    foreach my $chunk_key (keys(%$key_to_line_mapping)) {
+	# Use the CVS date as a starting point
+	my $chunk_cvs_date = $key_to_cvs_date_mapping{$chunk_key};
+	$key_to_last_update_date_mapping{$chunk_key} = $chunk_cvs_date;
+
+	# If a comment date exists and it is after the CVS date, use that instead
+        # need to convert the comment date format to SVN format
+	my $chunk_gti_comment = $key_to_gti_comment_mapping{$chunk_key};
+	if (defined($chunk_gti_comment) && $chunk_gti_comment =~ /(\d?\d-\D\D\D-\d\d\d\d)/) {
+	    my $chunk_comment_date = $1;            
+	    # if the changes were made on 2009 Jan 27, ie. tidying up the GTI commands following each fragment, 
+	    # then should use the GTI comment date instead
+	    # if ((!defined($chunk_cvs_date) || &is_date_after($chunk_comment_date, $chunk_cvs_date))) {
+	    if ((!defined($chunk_cvs_date) || &is_date_after($chunk_comment_date, $chunk_cvs_date) 
+		 || (&is_date_after($chunk_cvs_date,$chunk_comment_date) && ($chunk_cvs_date eq "2009-01-27" || $chunk_cvs_date eq "2009-01-28")))) {
+		$key_to_last_update_date_mapping{$chunk_key} = $chunk_comment_date;
+		
+		# &log_message("cvs date: $chunk_cvs_date, comment date: $chunk_comment_date");
+		# die;
+	    }
+	}
+    }
+
+    return %key_to_last_update_date_mapping;
+}
+
+
+sub build_key_to_cvs_date_mapping
+{
+    my ($filename, $translation_file_type) = @_;
+
+    # Use CVS to annotate each line of the file with the date it was last edited
+    # The "2>/dev/null" is very important! If it is missing this will never return when run from the receptionist
+    # my $cvs_annotated_file = `cd $gsdl_root_directory; cvs -d $anonymous_cvs_root annotate -F $filename 2>/dev/null`;    
+    # my $cvs_annotated_file = `cd $gsdl_root_directory; export PATH=.:/research/lh92/programs/subversion/bin; svn annotate -v --force $filename`;
+    my $cvs_annotated_file = `cd $gsdl_root_directory; svn annotate -v $filename`;
+    
+    my @cvs_annotated_file_lines = split(/\n/, $cvs_annotated_file);
+
+    my @cvs_annotated_file_lines_date = ();
+    foreach my $cvs_annotated_file_line (@cvs_annotated_file_lines) {
+	# Extract the date from the CVS annotation at the front
+        # cvs format : 07-Jun-02
+        # svn format : 2007-07-16
+	# $cvs_annotated_file_line =~ s/^\S+\s+\(\S+\s+(\S+)\):\s//;
+        $cvs_annotated_file_line =~ s/^\s+\S+\s+\S+\s(\S+)//; 
+        
+        push(@cvs_annotated_file_lines_date, $1);
+        
+        # trim extra date information in svn annotation format
+        # 15:42:49 +1200 (Wed, 21 Jun 2006)
+        $cvs_annotated_file_line =~ s/^\s+\S+\s\S+\s\((.+?)\)\s//; 
+    }    
+    
+    # Build a key to line mapping for the CVS annotated file, for matching the chunk key to the CVS date
+    my %key_to_line_mapping = &build_key_to_line_mapping(\@cvs_annotated_file_lines, $translation_file_type);
+        
+    my %key_to_cvs_date_mapping = ();
+    foreach my $chunk_key (keys(%key_to_line_mapping)) {
+ 	my $chunk_starting_line = (split(/-/, $key_to_line_mapping{$chunk_key}))[0];
+ 	my $chunk_finishing_line = (split(/-/, $key_to_line_mapping{$chunk_key}))[1];
+                
+ 	# Find the date this chunk was last edited, from the CVS annotation
+ 	my $chunk_date = $cvs_annotated_file_lines_date[$chunk_starting_line];        
+ 	for (my $l = ($chunk_starting_line + 1); $l <= $chunk_finishing_line; $l++) {
+ 	    if (&is_date_after($cvs_annotated_file_lines_date[$l], $chunk_date)) {
+ 		# This part of the chunk has been updated more recently
+ 		$chunk_date = $cvs_annotated_file_lines_date[$l];
+ 		
+ 	    }
+ 	}
+
+ 	# Map from chunk key to CVS date
+ 	$key_to_cvs_date_mapping{$chunk_key} = $chunk_date;
+    }
+
+    return %key_to_cvs_date_mapping;
+}
+
+
+sub build_key_to_gti_comment_mapping
+{
+    my ($file_lines, $key_to_line_mapping, $translation_file_type) = @_;
+
+    my %key_to_gti_comment_mapping = ();
+    foreach my $chunk_key (keys(%$key_to_line_mapping)) {
+	my $chunk_starting_line = (split(/-/, $key_to_line_mapping->{$chunk_key}))[0];
+	my $chunk_finishing_line = (split(/-/, $key_to_line_mapping->{$chunk_key}))[1];
+
+	my $chunk_text = @$file_lines[$chunk_starting_line];
+	for (my $l = ($chunk_starting_line + 1); $l <= $chunk_finishing_line; $l++) {
+	    $chunk_text .= @$file_lines[$l];
+	}
+
+	# Map from chunk key to GTI comment
+	my $chunk_gti_comment;
+	eval "\$chunk_gti_comment = &get_${translation_file_type}_chunk_gti_comment(\$chunk_text)";
+	$key_to_gti_comment_mapping{$chunk_key} = $chunk_gti_comment if (defined($chunk_gti_comment));
+    }
+
+    return %key_to_gti_comment_mapping;
+}
+
+
+sub determine_chunks_requiring_translation
+{
+    my $source_file_key_to_text_mapping = shift(@_);
+    my $target_file_key_to_text_mapping = shift(@_);
+
+    # Chunks needing translation are those in the source file with no translation in the target file
+    my @target_file_keys_requiring_translation = ();
+    foreach my $chunk_key (keys(%$source_file_key_to_text_mapping)) {
+	if ($source_file_key_to_text_mapping->{$chunk_key} && !$target_file_key_to_text_mapping->{$chunk_key}) {
+	    # &log_message("Chunk with key $chunk_key needs translating.");
+	    push(@target_file_keys_requiring_translation, $chunk_key);
+	}
+    }
+
+    return @target_file_keys_requiring_translation;
+}
+
+
+sub determine_chunks_requiring_updating
+{
+    my $source_file_key_to_last_update_date_mapping = shift(@_);
+    my $target_file_key_to_last_update_date_mapping = shift(@_);
+
+    # Chunks needing updating are those in the target file that have been more recently edited in the source file
+    my @target_file_keys_requiring_updating = ();
+    foreach my $chunk_key (keys(%$source_file_key_to_last_update_date_mapping)) {
+	my $source_chunk_last_update_date = $source_file_key_to_last_update_date_mapping->{$chunk_key};
+ 	my $target_chunk_last_update_date = $target_file_key_to_last_update_date_mapping->{$chunk_key};
+        
+        # print "key: $chunk_key\nsource date : $source_chunk_last_update_date\ntarget date : $target_chunk_last_update_date\nafter? ". &is_date_after($source_chunk_last_update_date, $target_chunk_last_update_date) . "\n\n";        
+                	
+        if (defined($target_chunk_last_update_date) && &is_date_after($source_chunk_last_update_date, $target_chunk_last_update_date)) {
+	    # &log_message("Chunk with key $chunk_key needs updating.");
+	    push(@target_file_keys_requiring_updating, $chunk_key);
+ 	}
+    }
+
+    return @target_file_keys_requiring_updating;
+}
+
+
+sub is_chunk_automatically_translated
+{
+    my ($chunk_key, $translation_file_type) = @_;
+    eval "return &is_${translation_file_type}_chunk_automatically_translated(\$chunk_key)";
+}
+
+
+sub make_text_xml_safe
+{
+    my $text = shift(@_);
+    $text =~ s/\&/\&amp\;/g;
+    $text =~ s/\&amp\;lt\;/\&amp\;amp\;lt\;/g;
+    $text =~ s/\&amp\;gt\;/\&amp\;amp\;gt\;/g;
+    $text =~ s/\&amp\;rarr\;/\&amp\;amp\;rarr\;/g;
+    $text =~ s/\&amp\;mdash\;/\&amp\;amp\;mdash\;/g;
+    $text =~ s/</\&lt\;/g;
+    $text =~ s/>/\&gt\;/g;
+    return $text;
+}
+
+
+sub unmake_text_xml_safe
+{
+    my $text = shift(@_);
+    $text =~ s/\&lt\;/</g;
+    $text =~ s/\&gt\;/>/g;
+    $text =~ s/\&amp\;/\&/g;
+    return $text;
+}
+
+
+# Returns 1 if $date1 is after $date2, 0 otherwise
+sub is_date_after_cvs
+{
+    my ($date1, $date2) = @_;
+    my %months = ("Jan", 1, "Feb", 2, "Mar", 3, "Apr",  4, "May",  5, "Jun",  6,
+		  "Jul", 7, "Aug", 8, "Sep", 9, "Oct", 10, "Nov", 11, "Dec", 12);
+
+	if(!defined $date1) {
+		return 1;
+	}
+
+    my @date1parts = split(/-/, $date1);
+    my @date2parts = split(/-/, $date2);
+
+    # Compare year - nasty because we have rolled over into a new century
+    my $year1 = $date1parts[2];
+    if ($year1 < 80) {
+		$year1 += 2000;
+    }
+    my $year2 = $date2parts[2];
+    if ($year2 < 80) {
+		$year2 += 2000;
+    }
+
+    # Compare year
+    if ($year1 > $year2) {
+	return 1;
+    }
+    elsif ($year1 == $year2) {
+	# Year is the same, so compare month
+	if ($months{$date1parts[1]} > $months{$date2parts[1]}) {
+	    return 1;
+	}
+	elsif ($months{$date1parts[1]} == $months{$date2parts[1]}) {
+	    # Month is the same, so compare day
+	    if ($date1parts[0] > $date2parts[0]) {
+		return 1;
+	    }
+	}
+    }
+
+    return 0;
+}
+
+sub is_date_after
+{
+    my ($date1, $date2) = @_;
+    
+    if(!defined $date1) {
+      return 1;
+    }
+    if(!defined $date2) {
+      return 0;
+    }
+    
+    # 16-Aug-2006
+    if($date1=~ /(\d+?)-(\S\S\S)-(\d\d\d\d)/){
+       my %months = ("Jan", "01", "Feb", "02", "Mar", "03", "Apr",  "04", "May",  "05", "Jun",  "06",
+		  "Jul", "07", "Aug", "08", "Sep", "09", "Oct", "10", "Nov", "11", "Dec", "12");
+       $date1=$3 . "-" . $months{$2} . "-" . $1;
+       # print "** converted date1: $date1\n";
+    }
+    if($date2=~ /(\d+?)-(\S\S\S)-(\d\d\d\d)/){
+       my %months = ("Jan", "01", "Feb", "02", "Mar", "03", "Apr",  "04", "May",  "05", "Jun",  "06",
+		  "Jul", "07", "Aug", "08", "Sep", "09", "Oct", "10", "Nov", "11", "Dec", "12");
+       $date2=$3 . "-" . $months{$2} . "-" . $1;
+       # print "** converted date2: $date2\n";
+    }
+    
+    
+    # 2006-08-16
+    my @date1parts = split(/-/, $date1);
+    my @date2parts = split(/-/, $date2);
+    
+    # Compare year
+    if ($date1parts[0] > $date2parts[0]) {
+	return 1;
+    }
+    elsif ($date1parts[0] == $date2parts[0]) {
+	# Year is the same, so compare month
+	if ($date1parts[1] > $date2parts[1]) {
+	    return 1;
+	}
+	elsif ($date1parts[1] == $date2parts[1]) {
+	    # Month is the same, so compare day
+	    if ($date1parts[2] > $date2parts[2]) {
+		return 1;
+	    }
+	}
+    }    
+    
+    return 0;
+}
+
+
+sub create_xml_response_for_chunks_requiring_work
+{
+    my ($translation_file_key, $target_file, $total_num_chunks, $target_files_keys_requiring_translation, $target_files_keys_requiring_updating, $num_chunks_to_return, $source_files_key_to_text_mapping, $target_files_key_to_text_mapping, $source_files_key_to_last_update_date_mapping, $target_files_key_to_last_update_date_mapping) = @_;
+
+    # Form an XML response to the command
+    my $xml_response = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+    $xml_response .= "<GTIResponse>\n";
+    $xml_response .= "  <TranslationFile"
+	. " key=\"" . $translation_file_key . "\""
+	. " target_file_path=\"" . $target_file . "\""
+	. " num_chunks_translated=\"" . ($total_num_chunks - scalar(@$target_files_keys_requiring_translation)) . "\""
+	. " num_chunks_requiring_translation=\"" . scalar(@$target_files_keys_requiring_translation) . "\""
+	. " num_chunks_requiring_updating=\"" . scalar(@$target_files_keys_requiring_updating) . "\"\/>\n";
+
+    # Do chunks requiring translation first
+    if ($num_chunks_to_return > scalar(@$target_files_keys_requiring_translation)) {
+	$xml_response .= "  <ChunksRequiringTranslation size=\"" . scalar(@$target_files_keys_requiring_translation) . "\">\n";
+    }
+    else {
+	$xml_response .= "  <ChunksRequiringTranslation size=\"" . $num_chunks_to_return . "\">\n";
+    }
+
+    my @sorted_chunk_keys = sort (@$target_files_keys_requiring_translation);
+    foreach my $chunk_key (@sorted_chunk_keys) {
+	last if ($num_chunks_to_return == 0);
+
+	my $source_file_chunk_date = $source_files_key_to_last_update_date_mapping->{$chunk_key} || "";
+	my $source_file_chunk_text = &make_text_xml_safe($source_files_key_to_text_mapping->{$chunk_key});	
+	
+	$xml_response .= "    <Chunk key=\"" . &make_text_xml_safe($chunk_key) . "\">\n";
+	$xml_response .= "      <SourceFileText date=\"$source_file_chunk_date\">$source_file_chunk_text</SourceFileText>\n";	
+	$xml_response .= "      <TargetFileText></TargetFileText>\n";
+	$xml_response .= "    </Chunk>\n";
+
+	$num_chunks_to_return--;
+    }
+
+    $xml_response .= "  </ChunksRequiringTranslation>\n";
+
+    # Then do chunks requiring updating
+    if ($num_chunks_to_return > scalar(@$target_files_keys_requiring_updating)) {
+	$xml_response .= "  <ChunksRequiringUpdating size=\"" . scalar(@$target_files_keys_requiring_updating) . "\">\n";
+    }
+    else {
+	$xml_response .= "  <ChunksRequiringUpdating size=\"" . $num_chunks_to_return . "\">\n";
+    }
+        
+    # foreach my $chunk_key (@target_file_keys_requiring_updating) {
+    @sorted_chunk_keys = sort (@$target_files_keys_requiring_updating);
+    foreach my $chunk_key (@sorted_chunk_keys) {
+	last if ($num_chunks_to_return == 0);
+
+	my $source_file_chunk_date = $source_files_key_to_last_update_date_mapping->{$chunk_key} || "";
+	my $source_file_chunk_text = &make_text_xml_safe($source_files_key_to_text_mapping->{$chunk_key});
+	my $target_file_chunk_date = $target_files_key_to_last_update_date_mapping->{$chunk_key} || "";
+	my $target_file_chunk_text = &make_text_xml_safe($target_files_key_to_text_mapping->{$chunk_key});
+
+	$xml_response .= "    <Chunk key=\"" . &make_text_xml_safe($chunk_key) . "\">\n";	
+	$xml_response .= "      <SourceFileText date=\"$source_file_chunk_date\">$source_file_chunk_text</SourceFileText>\n";
+	$xml_response .= "      <TargetFileText date=\"$target_file_chunk_date\">$target_file_chunk_text</TargetFileText>\n";
+	$xml_response .= "    </Chunk>\n";
+
+	$num_chunks_to_return--;
+    }
+
+    $xml_response .= "  </ChunksRequiringUpdating>\n";
+
+    $xml_response .= "</GTIResponse>\n";
+
+    return $xml_response;
+}
+
+
+sub create_xml_response_for_all_chunks
+{
+    my ($translation_file_key, $target_file, $source_file_key_to_text_mapping, $target_file_key_to_text_mapping, $source_file_key_to_last_update_date_mapping, $target_file_key_to_last_update_date_mapping) = @_;
+
+    # Form an XML response to the command
+    my $xml_response = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+    $xml_response .= "<GTIResponse>\n";
+    $xml_response .= "  <TranslationFile"
+	. " key=\"" . $translation_file_key . "\""
+	. " target_file_path=\"" . $target_file . "\"\/>\n";
+    
+    # Do all the chunks
+    $xml_response .= "  <Chunks size=\"" . scalar(keys(%$source_file_key_to_text_mapping)) . "\">\n";
+
+    my @sorted_chunk_keys = sort (keys(%$source_file_key_to_text_mapping));
+    foreach my $chunk_key (@sorted_chunk_keys) {
+	my $source_file_chunk_date = $source_file_key_to_last_update_date_mapping->{$chunk_key} || "";
+	my $source_file_chunk_text = &make_text_xml_safe($source_file_key_to_text_mapping->{$chunk_key});
+
+	$xml_response .= "    <Chunk key=\"" . &make_text_xml_safe($chunk_key) . "\">\n";
+	$xml_response .= "      <SourceFileText date=\"$source_file_chunk_date\">$source_file_chunk_text</SourceFileText>\n";
+	if (defined($target_file_key_to_text_mapping->{$chunk_key})) {
+	    my $target_file_chunk_date = $target_file_key_to_last_update_date_mapping->{$chunk_key} || "";
+	    my $target_file_chunk_text = &make_text_xml_safe($target_file_key_to_text_mapping->{$chunk_key});
+	    $xml_response .= "      <TargetFileText date=\"$target_file_chunk_date\">$target_file_chunk_text</TargetFileText>\n";
+	}
+	else {
+	    $xml_response .= "      <TargetFileText></TargetFileText>\n";
+	}
+
+	$xml_response .= "    </Chunk>\n";
+    }
+    $xml_response .= "  </Chunks>\n";
+    
+    $xml_response .= "</GTIResponse>\n";
+    return $xml_response;
+}
+
+
+
+# ==========================================================================================
+#   MACROFILE FUNCTIONS
+
+sub build_key_to_line_mapping_for_macrofile
+{
+    my (@file_lines) = @_;
+
+    my $macro_package;
+    my %chunk_key_to_line_mapping = ();
+    # Process the contents of the file, line by line
+    for (my $i = 0; $i < scalar(@file_lines); $i++) {
+	my $line = $file_lines[$i];
+	$line =~ s/(\s*)$//;  # Remove any nasty whitespace, carriage returns etc.
+
+	# Check if a new package is being defined
+	if ($line =~ m/^package\s+(.+)/) {
+	    $macro_package = $1;
+	}
+
+	# Line contains a macro name
+	elsif ($line =~ m/^(_\w+_)/) {
+	    my $macro_key = $1;
+	    $line =~ s/\s*([^\\]\#[^\}]+)?$//;  # Remove any comments and nasty whitespace
+
+	    # While there is still text of the macro to go...
+	    my $startline = $i;
+	    while ($line !~ /\}$/) {
+		$i++;
+		if ($i == scalar(@file_lines)) {
+		    &throw_fatal_error("Could not find end of macro $macro_key.");
+		}
+		$line = $file_lines[$i];
+		$line =~ s/\s*([^\\]\#[^\}]+)?$//;  # Remove any comments and nasty whitespace
+	    }
+
+	    # The chunk key consists of the package name and the macro key
+	    my $chunk_key = $macro_package . "." . $macro_key;
+	    # Map from chunk key to line
+	    $chunk_key_to_line_mapping{$chunk_key} = $startline . "-" . $i;
+	}
+
+	# Icon: line in format ## "image text" ## image_type ## macro_name ##
+	elsif ($line =~ m/^\#\# .* \#\# .* \#\# (.*) \#\#/) {
+	    # The chunk key consists of package name and macro key
+	    my $chunk_key = $macro_package . "." . $1;
+	    # Map from chunk key to line
+	    $chunk_key_to_line_mapping{$chunk_key} = $i . "-" . $i;
+	}
+    }
+
+    return %chunk_key_to_line_mapping;
+}
+
+
+sub import_chunk_from_macrofile
+{
+    my ($chunk_text) = @_;
+
+    # Is this an icon macro??
+    if ($chunk_text =~ /^\#\# (.*)/) {
+	# Extract image macro text
+	$chunk_text =~ /^\#\#\s+([^\#]+)\s+\#\#/;
+	$chunk_text = $1;
+
+	# Remove enclosing quotes
+	$chunk_text =~ s/^\"//;
+	$chunk_text =~ s/\"$//;
+    }
+
+    # No, so it must be a text macro
+    else {
+	# Remove macro key
+	$chunk_text =~ s/^_([^_]+)_(\s*)//;
+
+	# Remove language specifier
+	$chunk_text =~ s/^\[l=.*\](\s*)//;
+
+	# Remove braces enclosing text
+	$chunk_text =~ s/^{(\s*)((.|\n)*)}(\s*)(\#.+\s*)?/$2/;
+    }
+
+    return $chunk_text;
+}
+
+
+sub get_macrofile_chunk_gti_comment
+{
+    my ($chunk_text) = @_;
+
+    # Check for an "Updated DD-MMM-YYYY" comment at the end of the chunk
+    if ($chunk_text =~ /\#\s+(Updated\s+\d?\d-\D\D\D-\d\d\d\d.*)\s*$/i) {
+	return $1;
+    }
+
+    return undef;
+}
+
+
+sub is_macrofile_chunk_automatically_translated
+{
+    my ($chunk_key) = @_;
+
+    # The _httpiconX_, _widthX_ and _heightX_ image macros are automatically translated
+    if ($chunk_key =~ /\._(httpicon|width|height)/) {
+	return 1;
+    }
+
+    return 0;
+}
+
+
+# Use the source file to generate a target file that is formatted the same
+sub write_translated_macrofile
+{
+    my $source_file = shift(@_);  # Not used
+    my @source_file_lines = @{shift(@_)};
+    my $source_file_key_to_text_mapping = shift(@_);
+    my $target_file = shift(@_);
+    my @target_file_lines = @{shift(@_)};
+    my $target_file_key_to_text_mapping = shift(@_);
+    my $target_file_key_to_gti_comment_mapping = shift(@_);
+    my $target_language_code = shift(@_);
+
+    # Build a mapping from source file line to chunk key
+    my %source_file_key_to_line_mapping = &build_key_to_line_mapping_for_macrofile(@source_file_lines);
+    my %source_file_line_to_key_mapping = ();
+    foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
+	$source_file_line_to_key_mapping{$source_file_key_to_line_mapping{$chunk_key}} = $chunk_key;
+    }
+    my @source_file_line_keys = (sort sort_by_line (keys(%source_file_line_to_key_mapping)));
+    my $source_file_line_number = 0;
+
+    # Build a mapping from target file line to chunk key
+    my %target_file_key_to_line_mapping = &build_key_to_line_mapping_for_macrofile(@target_file_lines);
+    my %target_file_line_to_key_mapping = ();
+    foreach my $chunk_key (keys(%target_file_key_to_line_mapping)) {
+	$target_file_line_to_key_mapping{$target_file_key_to_line_mapping{$chunk_key}} = $chunk_key;
+    }
+    my @target_file_line_keys = (sort sort_by_line (keys(%target_file_line_to_key_mapping)));
+
+    # Write the new target file
+    my $target_file_path = &util::filename_cat($gsdl_root_directory, $target_file);
+    if (!open(TARGET_FILE, ">$target_file_path")) {
+	&throw_fatal_error("Could not write target file $target_file_path.");
+    }
+
+    # Use the header from the target file, to keep language and author information
+    if (scalar(@target_file_line_keys) > 0) {
+	my $target_file_line_number = 0;
+ 	my $target_file_chunk_starting_line_number = (split(/-/, $target_file_line_keys[0]))[0];
+ 	while ($target_file_line_number < $target_file_chunk_starting_line_number) {
+	    my $target_file_line = $target_file_lines[$target_file_line_number];
+	    last if ($target_file_line =~ /^\# -- Missing translation: /);  # We don't want to get into the macros
+ 	    print TARGET_FILE $target_file_line;
+ 	    $target_file_line_number++;
+ 	}
+
+	$source_file_line_number = (split(/-/, $source_file_line_keys[0]))[0];
+    }
+
+    # Model the new target file on the source file, with the target file translations
+    foreach my $line_key (@source_file_line_keys) {
+ 	# Fill in the gaps before this chunk starts
+ 	my $source_file_chunk_starting_line_number = (split(/-/, $line_key))[0];
+ 	my $source_file_chunk_finishing_line_number = (split(/-/, $line_key))[1];
+ 	while ($source_file_line_number < $source_file_chunk_starting_line_number) {
+ 	    print TARGET_FILE $source_file_lines[$source_file_line_number];
+ 	    $source_file_line_number++;
+ 	}
+ 	$source_file_line_number = $source_file_chunk_finishing_line_number + 1;
+
+	my $chunk_key = $source_file_line_to_key_mapping{$line_key};
+	my $source_file_chunk_text = $source_file_key_to_text_mapping->{$chunk_key};
+	my $target_file_chunk_text = $target_file_key_to_text_mapping->{$chunk_key} || "";
+
+	my $macrofile_key = $chunk_key;
+	$macrofile_key =~ s/^(.+?)\.//;
+
+	# If no translation exists for this chunk, show this, and move on
+	if ($source_file_chunk_text ne "" && $target_file_chunk_text eq "") {
+	    print TARGET_FILE "# -- Missing translation: $macrofile_key\n";
+	    next;
+	}
+
+ 	# Grab the source chunk text
+ 	my $source_file_chunk = $source_file_lines[$source_file_chunk_starting_line_number];
+ 	for (my $l = ($source_file_chunk_starting_line_number + 1); $l <= $source_file_chunk_finishing_line_number; $l++) {
+ 	    $source_file_chunk .= $source_file_lines[$l];
+ 	}
+
+ 	# Is this an icon macro??
+ 	if ($source_file_chunk =~ /^\#\# (.*)/) {
+ 	    # Escape any newline and question mark characters so the source text is replaced correctly
+ 	    $source_file_chunk_text =~ s/\\/\\\\/g;
+	    $source_file_chunk_text =~ s/\?/\\\?/g;
+
+	    # Build the new target chunk from the source chunk
+	    my $target_file_chunk = $source_file_chunk;
+	    $target_file_chunk =~ s/$source_file_chunk_text/$target_file_chunk_text/;
+	    $target_file_chunk =~ s/(\s)*$//;
+	    print TARGET_FILE "$target_file_chunk";
+ 	}
+
+ 	# No, it is just a normal text macro
+ 	else {
+ 	    print TARGET_FILE "$macrofile_key [l=$target_language_code] {$target_file_chunk_text}";
+ 	}
+
+	# Add the "updated" comment, if one exists
+	if ($target_file_key_to_gti_comment_mapping->{$chunk_key}) {
+	    print TARGET_FILE "  # " . $target_file_key_to_gti_comment_mapping->{$chunk_key};
+	}
+	print TARGET_FILE "\n";
+    }
+
+    close(TARGET_FILE);
+}
+
+
+sub sort_by_line
+{
+    return ((split(/-/, $a))[0] <=> (split(/-/, $b))[0]);
+}
+
+
+# ==========================================================================================
+#   RESOURCE BUNDLE FUNCTIONS
+
+sub build_key_to_line_mapping_for_resource_bundle
+{
+    my (@file_lines) = @_;
+
+    my %chunk_key_to_line_mapping = ();
+    for (my $i = 0; $i < scalar(@file_lines); $i++) {
+	my $line = $file_lines[$i];
+	$line =~ s/(\s*)$//;  # Remove any nasty whitespace, carriage returns etc.
+
+	# Line contains a dictionary string
+	if ($line =~ /^(\S+?)[:|=](.*)$/) {
+	    my $chunk_key = $1;
+
+	    # Map from chunk key to line
+	    $chunk_key_to_line_mapping{$chunk_key} = $i . "-" . $i;
+	}
+    }
+
+    return %chunk_key_to_line_mapping;
+}
+
+
+sub import_chunk_from_resource_bundle
+{
+    my ($chunk_text) = @_;
+
+    # Simple: just remove string key
+    $chunk_text =~ s/^(\S+?)[:|=](\s*)//;
+    $chunk_text =~ s/(\s*)$//;  # Remove any nasty whitespace, carriage returns etc.
+    $chunk_text =~ s/(\s*)\#\s+Updated\s+(\d?\d-\D\D\D-\d\d\d\d.*)\s*$//i;
+
+    return $chunk_text;
+}
+
+
+sub get_resource_bundle_chunk_gti_comment
+{
+    my ($chunk_text) = @_;
+
+    # Check for an "Updated DD-MMM-YYYY" comment at the end of the chunk
+    if ($chunk_text =~ /\#\s+(Updated\s+\d?\d-\D\D\D-\d\d\d\d.*)\s*$/i) {
+	return $1;
+    }
+
+    return undef;
+}
+
+
+sub is_resource_bundle_chunk_automatically_translated
+{
+    # No resource bundle chunks are automatically translated
+    return 0;
+}
+
+
+sub write_translated_resource_bundle
+{
+    my $source_file = shift(@_);  # Not used
+    my @source_file_lines = @{shift(@_)};
+    my $source_file_key_to_text_mapping = shift(@_);
+    my $target_file = shift(@_);
+    my @target_file_lines = @{shift(@_)};  # Not used
+    my $target_file_key_to_text_mapping = shift(@_);
+    my $target_file_key_to_gti_comment_mapping = shift(@_);
+    my $target_language_code = shift(@_);  # Not used
+
+    # Build a mapping from chunk key to source file line, and from source file line to chunk key
+    my %source_file_key_to_line_mapping = &build_key_to_line_mapping_for_resource_bundle(@source_file_lines);
+    my %source_file_line_to_key_mapping = ();
+    foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
+	$source_file_line_to_key_mapping{$source_file_key_to_line_mapping{$chunk_key}} = $chunk_key;
+    }
+
+    # Write the new target file
+    my $target_file_path = &util::filename_cat($gsdl_root_directory, $target_file);
+    if (!open(TARGET_FILE, ">$target_file_path")) {
+	&throw_fatal_error("Could not write target file $target_file_path.");
+    }
+
+    # Model the new target file on the source file, with the target file translations
+    my $source_file_line_number = 0;
+    foreach my $line_key (sort sort_by_line (keys(%source_file_line_to_key_mapping))) {
+ 	# Fill in the gaps before this chunk starts
+ 	my $source_file_chunk_starting_line_number = (split(/-/, $line_key))[0];
+ 	my $source_file_chunk_finishing_line_number = (split(/-/, $line_key))[1];
+ 	while ($source_file_line_number < $source_file_chunk_starting_line_number) {
+ 	    print TARGET_FILE $source_file_lines[$source_file_line_number];
+ 	    $source_file_line_number++;
+ 	}
+ 	$source_file_line_number = $source_file_chunk_finishing_line_number + 1;
+
+	my $chunk_key = $source_file_line_to_key_mapping{$line_key};
+	my $source_file_chunk_text = $source_file_key_to_text_mapping->{$chunk_key};
+	my $target_file_chunk_text = $target_file_key_to_text_mapping->{$chunk_key} || "";
+
+	# If no translation exists for this chunk, show this, and move on
+	if ($source_file_chunk_text ne "" && $target_file_chunk_text eq "") {
+	    print TARGET_FILE "# -- Missing translation: $chunk_key\n";
+	    next;
+	}
+
+	print TARGET_FILE "$chunk_key:$target_file_chunk_text";
+	if ($target_file_key_to_gti_comment_mapping->{$chunk_key}) {
+	    print TARGET_FILE "  # " . $target_file_key_to_gti_comment_mapping->{$chunk_key};
+	}
+	print TARGET_FILE "\n";
+    }
+
+    close(TARGET_FILE);
+}
+
+
+# ==========================================================================================
+#   GREENSTONE XML FUNCTIONS
+
+sub build_key_to_line_mapping_for_greenstone_xml
+{
+    my (@file_lines) = @_;
+
+    my %chunk_key_to_line_mapping = ();
+    for (my $i = 0; $i < scalar(@file_lines); $i++) {
+	my $line = $file_lines[$i];
+	$line =~ s/(\s*)$//;  # Remove any nasty whitespace, carriage returns etc.
+
+	# Line contains a string to translate
+	if ($line =~ /^\s*<Text id=\"(.*?)\">/) {
+	    my $chunk_key = $1;
+	    $line =~ s/\s*$//;  # Remove any nasty whitespace
+	    $line =~ s/<Updated date=\"\d?\d-\D\D\D-\d\d\d\d.*\"\/>$//;
+
+	    # While there is still text of the string to go...
+	    my $startline = $i;
+	    while ($line !~ /<\/Text>$/) {
+		$i++;
+		if ($i == scalar(@file_lines)) {
+		    &throw_fatal_error("Could not find end of string $chunk_key.");
+		}
+		$line = $file_lines[$i];
+		$line =~ s/\s*$//;  # Remove any nasty whitespace
+		$line =~ s/<Updated date=\"\d?\d-\D\D\D-\d\d\d\d.*\"\/>$//;
+	    }
+
+	    # Map from chunk key to line
+	    if (!defined($chunk_key_to_line_mapping{$chunk_key})) {
+		$chunk_key_to_line_mapping{$chunk_key} = $startline . "-" . $i;
+	    }
+	    else {
+		&throw_fatal_error("Duplicate key $chunk_key.");
+	    }
+	}
+    }
+
+    return %chunk_key_to_line_mapping;
+}
+
+
+sub import_chunk_from_greenstone_xml
+{
+    my ($chunk_text) = @_;
+
+    # Simple: just remove the Text tags
+    $chunk_text =~ s/^\s*<Text id=\"(.*?)\">(\s*)//;
+    $chunk_text =~ s/<Updated date=\"\d?\d-\D\D\D-\d\d\d\d.*\"\/>$//;
+    $chunk_text =~ s/<\/Text>$//;
+
+    return $chunk_text;
+}
+
+
+sub get_greenstone_xml_chunk_gti_comment
+{
+    my ($chunk_text) = @_;
+
+    # Check for an "Updated DD-MMM-YYYY" comment at the end of the chunk
+    if ($chunk_text =~ /<Updated date=\"(\d?\d-\D\D\D-\d\d\d\d.*)\"\/>$/i) {
+	return $1;
+    }
+
+    return undef;
+}
+
+
+sub is_greenstone_xml_chunk_automatically_translated
+{
+    # No greenstone XML chunks are automatically translated
+    return 0;
+}
+
+
+sub write_translated_greenstone_xml
+{
+    my $source_file = shift(@_);  # Not used
+    my @source_file_lines = @{shift(@_)};
+    my $source_file_key_to_text_mapping = shift(@_);
+    my $target_file = shift(@_);
+    my @target_file_lines = @{shift(@_)};  # Not used
+    my $target_file_key_to_text_mapping = shift(@_);
+    my $target_file_key_to_gti_comment_mapping = shift(@_);
+    my $target_language_code = shift(@_);  # Not used
+
+    # Build a mapping from chunk key to source file line, and from source file line to chunk key
+    my %source_file_key_to_line_mapping = &build_key_to_line_mapping_for_greenstone_xml(@source_file_lines);
+    my %source_file_line_to_key_mapping = ();
+    foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
+	$source_file_line_to_key_mapping{$source_file_key_to_line_mapping{$chunk_key}} = $chunk_key;
+    }
+
+    # Write the new target file
+    my $target_file_path = &util::filename_cat($gsdl_root_directory, $target_file);
+    if (!open(TARGET_FILE, ">$target_file_path")) {
+	&throw_fatal_error("Could not write target file $target_file_path.");
+    }
+
+    # Model the new target file on the source file, with the target file translations
+    my $source_file_line_number = 0;
+    foreach my $line_key (sort sort_by_line (keys(%source_file_line_to_key_mapping))) {
+ 	# Fill in the gaps before this chunk starts
+ 	my $source_file_chunk_starting_line_number = (split(/-/, $line_key))[0];
+ 	my $source_file_chunk_finishing_line_number = (split(/-/, $line_key))[1];
+ 	while ($source_file_line_number < $source_file_chunk_starting_line_number) {
+ 	    print TARGET_FILE $source_file_lines[$source_file_line_number];
+ 	    $source_file_line_number++;
+ 	}
+ 	$source_file_line_number = $source_file_chunk_finishing_line_number + 1;
+
+	my $chunk_key = $source_file_line_to_key_mapping{$line_key};
+	my $source_file_chunk_text = $source_file_key_to_text_mapping->{$chunk_key};
+	my $target_file_chunk_text = $target_file_key_to_text_mapping->{$chunk_key} || "";
+	$target_file_chunk_text =~ s/(\n)*$//g;
+
+	# If no translation exists for this chunk, show this, and move on
+	if ($source_file_chunk_text ne "" && $target_file_chunk_text eq "") {
+	    print TARGET_FILE "<!-- Missing translation: $chunk_key -->\n";
+	    next;
+	}
+
+	print TARGET_FILE "<Text id=\"$chunk_key\">$target_file_chunk_text</Text>";
+	if ($target_file_key_to_gti_comment_mapping->{$chunk_key}) {
+	    my $chunk_gti_comment = $target_file_key_to_gti_comment_mapping->{$chunk_key};
+	    $chunk_gti_comment =~ s/^Updated //;
+	    print TARGET_FILE "<Updated date=\"" . $chunk_gti_comment . "\"\/>";
+	}
+	print TARGET_FILE "\n";
+    }
+
+    # Fill in the end of the file
+    while ($source_file_line_number < scalar(@source_file_lines)) {
+	print TARGET_FILE $source_file_lines[$source_file_line_number];
+	$source_file_line_number++;
+    }
+
+    close(TARGET_FILE);
+}
+
+
+# ==========================================================================================
+#   GREENSTONE3 FUNCTIONS
+
+sub get_all_chunks_for_gs3
+{
+    # The code of the target language (ensure it is lowercase)
+    my $target_language_code = lc(shift(@_));
+    my $translation_file_key = lc(shift(@_));
+
+    # Check that the necessary arguments were supplied
+    if (!$target_language_code) {
+	&throw_fatal_error("Missing command argument.");
+    }
+
+    # Get (and check) the translation configuration
+    # my ($source_file_dir, $target_file, $translation_file_type) = &get_translation_configuration($target_language_code, $translation_file_key);
+    
+    my %source_files_key_to_text_mapping = ();
+    my %target_files_key_to_text_mapping = ();
+    my %source_files_key_to_last_update_date_mapping = ();
+    my %target_files_key_to_last_update_date_mapping = ();
+
+    &build_gs3_configuration($target_language_code, \%source_files_key_to_text_mapping, \%target_files_key_to_text_mapping, \%source_files_key_to_last_update_date_mapping, \%target_files_key_to_last_update_date_mapping);
+
+    &log_message("Total number of source chunks: " . scalar(keys(%source_files_key_to_text_mapping)));
+    &log_message("Total number of target chunks: " . scalar(keys(%target_files_key_to_text_mapping)));
+
+    my $xml_response = &create_xml_response_for_all_chunks($translation_file_key, "", \%source_files_key_to_text_mapping, \%target_files_key_to_text_mapping, \%source_files_key_to_last_update_date_mapping, \%target_files_key_to_last_update_date_mapping);   
+    return $xml_response;
+}
+
+
+sub get_first_n_chunks_requiring_work_for_gs3
+{
+    # The code of the target language (ensure it is lowercase)
+    my $target_language_code = lc(shift(@_));
+    # The key of the file to translate (ensure it is lowercase)
+    my $translation_file_key = lc(shift(@_));
+    # The number of chunks to return (defaults to one if not specified)
+    my $num_chunks_to_return = shift(@_) || "1";
+    
+    # Check that the necessary arguments were supplied
+    if (!$target_language_code || !$translation_file_key) {
+	&throw_fatal_error("Missing command argument.");
+    }
+    
+    my %source_files_key_to_text_mapping = ();
+    my %target_files_key_to_text_mapping = ();
+    my %source_files_key_to_last_update_date_mapping = ();
+    my %target_files_key_to_last_update_date_mapping = ();
+
+    &build_gs3_configuration($target_language_code, \%source_files_key_to_text_mapping, \%target_files_key_to_text_mapping, 
+			     \%source_files_key_to_last_update_date_mapping, \%target_files_key_to_last_update_date_mapping);
+    
+    # Determine the target file chunks requiring translation
+    my @target_files_keys_requiring_translation = &determine_chunks_requiring_translation(\%source_files_key_to_text_mapping, \%target_files_key_to_text_mapping);    
+    # Determine the target file chunks requiring updating
+    my @target_files_keys_requiring_updating = &determine_chunks_requiring_updating(\%source_files_key_to_last_update_date_mapping, \%target_files_key_to_last_update_date_mapping);
+    &log_message("Total number of target chunks requiring translation: " . scalar(@target_files_keys_requiring_translation));
+    &log_message("Total number of target chunks requiring updating: " . scalar(@target_files_keys_requiring_updating));
+
+    my $xml_response = &create_xml_response_for_chunks_requiring_work($translation_file_key, "", scalar(keys(%source_files_key_to_text_mapping)),
+								      \@target_files_keys_requiring_translation, \@target_files_keys_requiring_updating,
+								      $num_chunks_to_return, \%source_files_key_to_text_mapping, \%target_files_key_to_text_mapping,
+								      \%source_files_key_to_last_update_date_mapping, \%target_files_key_to_last_update_date_mapping);
+   
+    return $xml_response;
+}
+
+
+
+sub build_gs3_configuration
+{
+    my ($target_language_code, $source_files_key_to_text_mapping, $target_files_key_to_text_mapping,
+	$source_files_key_to_gti_comment_mapping, $target_files_key_to_gti_comment_mapping) = @_;
+    
+    my $source_file_directory = "greenstone3";
+    my $translation_file_type = "resource_bundle";
+
+    foreach my $interface_file_key (@gs3_interface_files) {
+
+	&log_message("Greenstone 3 interface file: " . $interface_file_key);
+
+	# Parse the source language and target language files
+	my $source_file = &util::filename_cat($source_file_directory, $interface_file_key.".properties");
+	my @source_file_lines = &read_file_lines(&util::filename_cat($gsdl_root_directory, $source_file));
+	my %source_file_key_to_line_mapping = &build_key_to_line_mapping(\@source_file_lines, $translation_file_type);
+	my %source_file_key_to_text_mapping = &build_key_to_text_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);
+	my %source_file_key_to_gti_comment_mapping = &build_key_to_gti_comment_mapping(\@source_file_lines, \%source_file_key_to_line_mapping, $translation_file_type);	
+	
+	my $target_file = &util::filename_cat($source_file_directory, $interface_file_key."_".$target_language_code.".properties");
+	my @target_file_lines = &read_file_lines(&util::filename_cat($gsdl_root_directory, $target_file));
+	my %target_file_key_to_line_mapping = &build_key_to_line_mapping(\@target_file_lines, $translation_file_type);
+	my %target_file_key_to_text_mapping = &build_key_to_text_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+	my %target_file_key_to_gti_comment_mapping = &build_key_to_gti_comment_mapping(\@target_file_lines, \%target_file_key_to_line_mapping, $translation_file_type);
+
+
+	# Filter out any automatically translated chunks
+	foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
+	    if (&is_chunk_automatically_translated($chunk_key, $translation_file_type)) {
+		delete $source_file_key_to_line_mapping{$chunk_key};
+		delete $target_file_key_to_line_mapping{$chunk_key};
+	    }
+	}
+
+	&log_message("Number of source chunks: " . scalar(keys(%source_file_key_to_text_mapping)));
+	&log_message("Number of target chunks: " . scalar(keys(%target_file_key_to_text_mapping)));
+
+	foreach my $chunk_key (keys(%source_file_key_to_text_mapping)) {
+	    my $global_chunk_key = "$interface_file_key.$chunk_key";
+	    $source_files_key_to_text_mapping->{$global_chunk_key} = $source_file_key_to_text_mapping{$chunk_key};
+	    $source_files_key_to_gti_comment_mapping->{$global_chunk_key} = $source_file_key_to_gti_comment_mapping{$chunk_key};
+
+	    if (defined $target_file_key_to_text_mapping{$chunk_key}) {
+		$target_files_key_to_text_mapping->{$global_chunk_key} = $target_file_key_to_text_mapping{$chunk_key};
+		$target_files_key_to_gti_comment_mapping->{$global_chunk_key} = $target_file_key_to_gti_comment_mapping{$chunk_key};
+	    }
+	}	
+    }
+}
+
+
+sub write_translated_gs3interface
+{
+    my $source_file_key_to_text_mapping = shift(@_);
+    my $target_file_key_to_text_mapping = shift(@_);
+    my $target_file_key_to_gti_comment_mapping = shift(@_);
+    my $target_language_code = shift(@_);
+    
+    my @sorted_chunk_keys = sort (keys(%$source_file_key_to_text_mapping));
+
+    my %translated_interface_file_keys = ();
+    foreach my $chunk_key (keys(%$target_file_key_to_text_mapping)) {
+	$chunk_key =~ /^([^\.]+)?\.(.*)$/;
+	if (!defined $translated_interface_file_keys{$1}) {
+	    &log_message("Updated interface file: " . $1);	
+	    $translated_interface_file_keys{$1}="";
+	}
+    }
+    &log_message("Updated interface files: " . scalar(keys(%translated_interface_file_keys)));
+    
+    my $source_file_directory = "greenstone3";    
+    
+    foreach my $interface_file_key (keys(%translated_interface_file_keys)) {
+	
+	# Build a mapping from chunk key to source file line, and from source file line to chunk key
+	my $source_file = &util::filename_cat($source_file_directory, "$interface_file_key.properties");
+	my @source_file_lines = &read_file_lines(&util::filename_cat($gsdl_root_directory, $source_file));
+	my %source_file_key_to_line_mapping = &build_key_to_line_mapping_for_resource_bundle(@source_file_lines);
+	my %source_file_line_to_key_mapping = ();
+	foreach my $chunk_key (keys(%source_file_key_to_line_mapping)) {
+	    $source_file_line_to_key_mapping{$source_file_key_to_line_mapping{$chunk_key}} = $chunk_key;
+	}
+	
+	# Write the new target file
+	my $target_file = &util::filename_cat($source_file_directory, $interface_file_key . "_" . $target_language_code . ".properties");
+	my $target_file_path = &util::filename_cat($gsdl_root_directory, $target_file);
+	if (!open(TARGET_FILE, ">$target_file_path")) {
+	    &throw_fatal_error("Could not write target file $target_file_path.");
+	}
+
+	# Model the new target file on the source file, with the target file translations
+	my $source_file_line_number = 0;
+	foreach my $line_key (sort sort_by_line (keys(%source_file_line_to_key_mapping))) {
+	    # Fill in the gaps before this chunk starts
+	    my $source_file_chunk_starting_line_number = (split(/-/, $line_key))[0];
+	    my $source_file_chunk_finishing_line_number = (split(/-/, $line_key))[1];
+	    while ($source_file_line_number < $source_file_chunk_starting_line_number) {
+		print TARGET_FILE $source_file_lines[$source_file_line_number];
+		$source_file_line_number++;
+	    }
+	    $source_file_line_number = $source_file_chunk_finishing_line_number + 1;
+
+	    my $chunk_key = $source_file_line_to_key_mapping{$line_key};
+	    my $global_chunk_key = "$interface_file_key.$chunk_key";
+	    my $source_file_chunk_text = $source_file_key_to_text_mapping->{$global_chunk_key};
+	    my $target_file_chunk_text = $target_file_key_to_text_mapping->{$global_chunk_key} || "";
+
+	    # If no translation exists for this chunk, show this, and move on
+	    if ($source_file_chunk_text ne "" && $target_file_chunk_text eq "") {
+		print TARGET_FILE "# -- Missing translation: $chunk_key\n";
+		next;
+	    }
+
+	    print TARGET_FILE "$chunk_key:$target_file_chunk_text";
+	    if ($target_file_key_to_gti_comment_mapping->{$global_chunk_key}) {
+		print TARGET_FILE "  # " . $target_file_key_to_gti_comment_mapping->{$global_chunk_key};
+		}
+	    print TARGET_FILE "\n";
+	}
+
+	close(TARGET_FILE);	
+    }           
+}
+
+&main(@ARGV);
Index: /gsdl/stable/bin/script/import.pl
===================================================================
--- /gsdl/stable/bin/script/import.pl	(revision 20131)
+++ /gsdl/stable/bin/script/import.pl	(revision 20131)
@@ -0,0 +1,725 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# import.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will import a number of files into a particular collection
+
+package import;
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugins");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugouts");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/classify");
+
+    if (defined $ENV{'GSDLEXTS'}) {
+	my @extensions = split(/:/,$ENV{'GSDLEXTS'});
+	foreach my $e (@extensions) {
+	    my $ext_prefix = "$ENV{'GSDLHOME'}/ext/$e";
+
+	    unshift (@INC, "$ext_prefix/perllib");
+	    unshift (@INC, "$ext_prefix/perllib/cpan");
+	    unshift (@INC, "$ext_prefix/perllib/plugins");
+	    unshift (@INC, "$ext_prefix/perllib/plugouts");
+	    unshift (@INC, "$ext_prefix/perllib/classify");
+	}
+    }
+}
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and vice versa
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+
+use arcinfo;
+use colcfg;
+use plugin;
+use plugout;
+use manifest;
+use inexport;
+use util;
+use scriptutil;
+use FileHandle;
+use gsprintf 'gsprintf';
+use printusage;
+use parse2;
+
+
+
+my $oidtype_list = 
+    [ { 'name' => "hash",
+        'desc' => "{import.OIDtype.hash}" },
+      { 'name' => "assigned",
+        'desc' => "{import.OIDtype.assigned}" },
+      { 'name' => "incremental",
+        'desc' => "{import.OIDtype.incremental}" },
+      { 'name' => "dirname",
+        'desc' => "{import.OIDtype.dirname}" } ];
+
+
+# used to control output file format
+my $saveas_list = 
+    [ { 'name' => "GreenstoneXML",
+        'desc' => "{export.saveas.GreenstoneXML}"},
+      { 'name' => "GreenstoneMETS",
+        'desc' => "{export.saveas.GreenstoneMETS}"},
+      ];
+
+
+# Possible attributes for each argument
+# name: The name of the argument
+# desc: A description (or more likely a reference to a description) for this argument
+# type: The type of control used to represent the argument. Options include: string, int, flag, regexp, metadata, language, enum etc
+# reqd: Is this argument required?
+# hiddengli: Is this argument hidden in GLI?
+# modegli: The lowest detail mode this argument is visible at in GLI
+
+my $saveas_argument
+    = { 'name' => "saveas",
+	'desc' => "{import.saveas}",
+	'type' => "enum",
+	'list' => $saveas_list,
+	'deft' => "GreenstoneXML",
+	'reqd' => "no",
+	'modegli' => "3" };
+
+
+my $arguments = 
+    [ 
+      $saveas_argument,
+      { 'name' => "archivedir",
+	'desc' => "{import.archivedir}",
+	'type' => "string",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "importdir",
+	'desc' => "{import.importdir}",
+	'type' => "string",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "collectdir",
+	'desc' => "{import.collectdir}",
+	'type' => "string",
+	# parsearg left "" as default
+	#'deft' => &util::filename_cat ($ENV{'GSDLHOME'}, "collect"),
+	'deft' => "",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "site",
+	'desc' => "{import.site}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "manifest",
+	'desc' => "{import.manifest}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "debug",
+	'desc' => "{import.debug}",
+	'type' => "flag",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "faillog",
+	'desc' => "{import.faillog}",
+	'type' => "string",
+	# parsearg left "" as default
+	#'deft' => &util::filename_cat("&lt;collectdir&gt;", "colname", "etc", "fail.log"),
+	'deft' => "",
+	'reqd' => "no",
+        'modegli' => "3" },
+      { 'name' => "incremental",
+	'desc' => "{import.incremental}",
+	'type' => "flag",
+	'hiddengli' => "yes" },
+      { 'name' => "keepold",
+	'desc' => "{import.keepold}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "removeold",
+	'desc' => "{import.removeold}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "maxdocs",
+	'desc' => "{import.maxdocs}",
+	'type' => "int",
+	'reqd' => "no",
+	# parsearg left "" as default
+	#'deft' => "-1",
+	'range' => "1,",
+	'modegli' => "1" },
+      # don't set the default to hash - want to allow this to come from
+      # entry in collect.cfg but want to override it here 
+      { 'name' => "OIDtype",
+	'desc' => "{import.OIDtype}",
+	'type' => "enum",
+	'list' => $oidtype_list,
+	# parsearg left "" as default
+	#'deft' => "hash",
+	'reqd' => "no",
+	'modegli' => "2" },
+      { 'name' => "OIDmetadata",
+	'desc' => "{import.OIDmetadata}",
+	'type' => "string",
+	# 'type' => "metadata", #doesn't work properly in GLI
+	# parsearg left "" as default
+	#'deft' => "dc.Identifier",
+	'reqd' => "no",
+	'modegli' => "2" },
+      { 'name' => "out",
+	'desc' => "{import.out}",
+	'type' => "string",
+	'deft' => "STDERR",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "sortmeta",
+	'desc' => "{import.sortmeta}",
+	'type' => "string",
+	#'type' => "metadata", #doesn't work properly in GLI
+	'reqd' => "no",
+	'modegli' => "2" },
+      { 'name' => "reversesort",
+	'desc' => "{import.reversesort}",
+	'type' => "flag",
+	'reqd' => "no",
+	'modegli' => "2" },
+      { 'name' => "removeprefix",
+	'desc' => "{BasClas.removeprefix}",
+	'type' => "regexp",
+	'deft' => "",
+	'reqd' => "no", 
+	'modegli' => "3" },
+      { 'name' => "removesuffix",
+	'desc' => "{BasClas.removesuffix}",
+	'type' => "regexp",
+	'deft' => "",
+	'reqd' => "no",
+	'modegli' => "3" }, 
+      { 'name' => "groupsize",
+	'desc' => "{import.groupsize}",
+	'type' => "int",
+	'deft' => "1",
+	'reqd' => "no",
+	'modegli' => "2" },
+      { 'name' => "gzip",
+	'desc' => "{import.gzip}",
+	'type' => "flag",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "statsfile",
+	'desc' => "{import.statsfile}",
+	'type' => "string",
+	'deft' => "STDERR",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "verbosity",
+	'desc' => "{import.verbosity}",
+	'type' => "int",
+	'range' => "0,",
+	# parsearg left "" as default
+	#'deft' => "2",
+	'reqd' => "no",
+	'modegli' => "3" },
+      { 'name' => "gli",
+	'desc' => "{scripts.gli}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "xml",
+	'desc' => "{scripts.xml}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" }];
+
+my $options = { 'name' => "import.pl",
+		'desc' => "{import.desc}",
+		'args' => $arguments };
+
+
+&main();
+
+sub main {
+    # params
+    my ($language, $verbosity, $debug,
+	$collectdir, $importdir, $archivedir, $site, $manifest, 
+	$incremental, $keepold, $removeold, 
+	$saveas,
+	$OIDtype, $OIDmetadata, 
+	$maxdocs, $statsfile,
+	$out, $faillog, $gli,
+	$gzip, $groupsize, 
+	$sortmeta, $reversesort, $removeprefix, $removesuffix 
+	);
+
+    my $xml = 0;
+
+    # other vars
+    my ($configfilename, $collection, $collectcfg, 
+	$arcinfo_doc_filename, $arcinfo_src_filename, $archive_info, 
+	$gs_mode,
+	$processor, $pluginfo);
+
+    my $service = "import";
+
+    my $hashParsingResult = {};
+    # general options available to all plugins
+    my $intArgLeftinAfterParsing = parse2::parse(\@ARGV,$arguments,$hashParsingResult,"allow_extra_options");
+    # Parse returns -1 if something has gone wrong
+    if ($intArgLeftinAfterParsing == -1)
+    {
+	&PrintUsage::print_txt_usage($options, "{import.params}");
+	die "\n";
+    }
+    
+    foreach my $strVariable (keys %$hashParsingResult)
+    {
+	eval "\$$strVariable = \$hashParsingResult->{\"\$strVariable\"}";
+    }
+
+    # If $language has been specified, load the appropriate resource bundle
+    # (Otherwise, the default resource bundle will be loaded automatically)
+    if ($language && $language =~ /\S/) {
+	&gsprintf::load_language_specific_resource_bundle($language);
+    }
+
+    if ($xml) {
+        &PrintUsage::print_xml_usage($options);
+	print "\n";
+	return;
+    }
+
+    if ($gli) { # the gli wants strings to be in UTF-8
+	&gsprintf::output_strings_in_UTF8; 
+    }
+    
+    # now check that we had exactly one leftover arg, which should be 
+    # the collection name. We don't want to do this earlier, cos 
+    # -xml arg doesn't need a collection name
+    # Or if the user specified -h, then we output the usage also
+    if ($intArgLeftinAfterParsing != 1 || (@ARGV && $ARGV[0] =~ /^\-+h/))
+    {
+	&PrintUsage::print_txt_usage($options, "{import.params}");
+	die "\n";
+    }
+
+    my $close_out = 0;
+    if ($out !~ /^(STDERR|STDOUT)$/i) {
+	open (OUT, ">$out") ||
+	    (&gsprintf(STDERR, "{common.cannot_open_output_file}: $!\n", $out) && die);
+	$out = 'import::OUT';
+	$close_out = 1;
+    }
+    $out->autoflush(1);
+
+    # get and check the collection name
+    if (($collection = &colcfg::use_collection($site, @ARGV, $collectdir)) eq "") {
+	&PrintUsage::print_txt_usage($options, "{import.params}");
+	die "\n";
+    }
+
+    # add collection's perllib dir  into include path in 
+    # case we have collection specific modules
+    unshift (@INC, "$ENV{'GSDLCOLLECTDIR'}/perllib");
+
+    # check that we can open the faillog
+    if ($faillog eq "") {
+	$faillog = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "etc", "fail.log");
+    }
+    open (FAILLOG, ">$faillog") ||
+	(&gsprintf(STDERR, "{import.cannot_open_fail_log}\n", $faillog) && die);
+
+    
+    my $faillogname = $faillog;
+    $faillog = 'import::FAILLOG';
+    $faillog->autoflush(1);
+    
+    # Read in the collection configuration file.
+    ($configfilename, $gs_mode) = &colcfg::get_collect_cfg_name($out);
+    $collectcfg = &colcfg::read_collection_cfg ($configfilename, $gs_mode);
+
+    if (defined $collectcfg->{'importdir'} && $importdir eq "") {
+	$importdir = $collectcfg->{'importdir'};
+    }
+    if (defined $collectcfg->{'archivedir'} && $archivedir eq "") {
+	$archivedir = $collectcfg->{'archivedir'};
+    }
+    # fill in the default import and archives directories if none
+    # were supplied, turn all \ into / and remove trailing /
+    $importdir = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "import") if $importdir eq "";
+    $importdir =~ s/[\\\/]+/\//g;
+    $importdir =~ s/\/$//;
+    if (!-e $importdir) {
+	&gsprintf($out, "{import.no_import_dir}\n\n", $importdir);
+	die "\n";
+    }
+
+    $archivedir = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "archives") if $archivedir eq "";
+    $archivedir =~ s/[\\\/]+/\//g;
+    $archivedir =~ s/\/$//;
+
+    my $plugins = [];
+    if (defined $collectcfg->{'plugin'}) {
+	$plugins = $collectcfg->{'plugin'};
+    }
+    #some global options for the plugins
+    my @global_opts = ();
+
+    if ($verbosity !~ /\d+/) {
+	if (defined $collectcfg->{'verbosity'} && $collectcfg->{'verbosity'} =~ /\d+/) {
+	    $verbosity = $collectcfg->{'verbosity'};
+	} else {
+	    $verbosity = 2; # the default
+	}
+    }
+    if (defined $collectcfg->{'manifest'} && $manifest eq "") {
+	$manifest = $collectcfg->{'manifest'};
+    }
+
+    if (defined $collectcfg->{'gzip'} && !$gzip) {
+	if ($collectcfg->{'gzip'} =~ /^true$/i) {
+	    $gzip = 1;
+	}
+    }
+
+    if ($maxdocs !~ /\-?\d+/) {
+	if (defined $collectcfg->{'maxdocs'} && $collectcfg->{'maxdocs'} =~ /\-?\d+/) {
+	    $maxdocs = $collectcfg->{'maxdocs'};
+	} else {
+	    $maxdocs = -1; # the default
+	}
+    }
+    if ($groupsize == 1) {
+	if (defined $collectcfg->{'groupsize'} && $collectcfg->{'groupsize'} =~ /\d+/) {
+	    $groupsize = $collectcfg->{'groupsize'};
+	}
+    }
+
+    if (!defined $OIDtype || ($OIDtype !~ /^(hash|incremental|assigned|dirname)$/ )) {
+	if (defined $collectcfg->{'OIDtype'} && $collectcfg->{'OIDtype'} =~ /^(hash|incremental|assigned|dirname)$/) {
+	    $OIDtype = $collectcfg->{'OIDtype'};
+	} else {
+	    $OIDtype = "hash"; # the default
+	}
+    }
+
+    if ((!defined $OIDmetadata) || ($OIDmetadata eq "")) {
+	if (defined $collectcfg->{'OIDmetadata'}) {
+	    $OIDmetadata = $collectcfg->{'OIDmetadata'};
+	} else {
+	    $OIDmetadata = "dc.Identifier"; # the default
+	}
+    }
+
+    if (defined $collectcfg->{'sortmeta'} && (!defined $sortmeta || $sortmeta eq "")) {
+	$sortmeta = $collectcfg->{'sortmeta'};
+    }
+    # sortmeta cannot be used with group size
+    $sortmeta = undef unless defined $sortmeta && $sortmeta =~ /\S/;
+    if (defined $sortmeta && $groupsize > 1) {
+	&gsprintf($out, "{import.cannot_sort}\n\n");
+	$sortmeta = undef;
+    }
+    
+    if (defined $sortmeta) {
+	if (defined $collectcfg->{'reversesort'} && $collectcfg->{'reversesort'} =~ /^true$/i) {
+	    $reversesort = 1;
+	}
+    } else {
+	# reversesort only valid with sortmeta
+	$reversesort = 0;
+    }
+    if (defined $collectcfg->{'removeprefix'} && $removeprefix eq "") {
+	$removeprefix = $collectcfg->{'removeprefix'};
+    }
+    
+    if (defined $collectcfg->{'removesuffix'} && $removesuffix eq "") {
+	$removesuffix = $collectcfg->{'removesuffix'};
+    }
+    if (defined $collectcfg->{'debug'} && $collectcfg->{'debug'} =~ /^true$/i) {
+	$debug = 1;
+    }
+    if (defined $collectcfg->{'gli'} && $collectcfg->{'gli'} =~ /^true$/i) {
+	$gli = 1;
+    }
+    $gli = 0 unless defined $gli;
+       
+    # check keepold and removeold
+    ($removeold, $keepold, $incremental) = &scriptutil::check_removeold_and_keepold($removeold, $keepold, $incremental, "archives", $collectcfg);
+ 
+
+    print STDERR "<Import>\n" if $gli;
+    
+    my $manifest_lookup = new manifest();
+    if ($manifest ne "") {	
+	my $manifest_filename = $manifest;
+
+	if ($manifest_filename !~ m/^[\\\/]/) {
+	    $manifest_filename = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, $manifest_filename);
+	}
+
+	$manifest =~ s/[\\\/]+/\//g;
+	$manifest =~ s/\/$//;
+
+	$manifest_lookup->parse($manifest_filename);
+    }
+
+
+    # load all the plugins
+    $pluginfo = &plugin::load_plugins ($plugins, $verbosity, $out, $faillog, \@global_opts, $incremental);
+    if (scalar(@$pluginfo) == 0) {
+	&gsprintf($out, "{import.no_plugins_loaded}\n");
+	die "\n";
+    }
+
+    # remove the old contents of the archives directory (and tmp directory) if needed
+    if ($removeold) {
+	if (-e $archivedir) {
+	    &gsprintf($out, "{import.removing_archives}\n");
+	    &util::rm_r ($archivedir);
+	}
+	my $tmpdir = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "tmp");
+	$tmpdir =~ s/[\\\/]+/\//g;
+	$tmpdir =~ s/\/$//;
+	if (-e $tmpdir) {
+	    &gsprintf($out, "{import.removing_tmpdir}\n");
+	    &util::rm_r ($tmpdir);
+	}
+    }
+    # create the archives dir if needed
+    &util::mk_all_dir($archivedir);
+
+    # read the archive information file
+##  $arcinfo_doc_filename = &util::filename_cat ($archivedir, "archives.inf");
+    
+    $arcinfo_doc_filename = &util::filename_cat ($archivedir, "archiveinf-doc");
+    &util::rename_gdbm_file($arcinfo_doc_filename); # ensures gdb
+    $arcinfo_doc_filename .= ".gdb";
+    
+    $arcinfo_src_filename = &util::filename_cat ($archivedir, "archiveinf-src");   
+    &util::rename_gdbm_file($arcinfo_src_filename); # ensures gdb
+    $arcinfo_src_filename .= ".gdb";
+
+						    
+    $archive_info = new arcinfo ();
+    $archive_info->load_info ($arcinfo_doc_filename);
+    if ($reversesort) {
+	$archive_info->reverse_sort();
+    }
+
+    if ($manifest eq "") {
+	# Load in list of files in import folder from last import (if present)
+	$archive_info->load_prev_import_filelist ($arcinfo_src_filename);
+    }
+
+    ####Use Plugout####
+    my ($plugout); 
+    if (defined $collectcfg->{'plugout'}) {
+	# If a plugout was specified in the collect.cfg file, assume it is sensible
+	# We can't check the name because it could be anything, if it is a custom plugout
+	$plugout = $collectcfg->{'plugout'};
+    }
+    else{
+	if ($saveas !~ /^(GreenstoneXML|GreenstoneMETS)$/) {
+	    push @$plugout,"GreenstoneXMLPlugout";
+	}
+	else{
+	    push @$plugout,$saveas."Plugout";
+	}
+    }
+
+    push @$plugout,("-output_info",$archive_info) if (defined $archive_info); 
+    push @$plugout,("-verbosity",$verbosity) if (defined $verbosity);
+    push @$plugout,("-gzip_output") if ($gzip);
+    push @$plugout,("-group_size",$groupsize) if (defined $groupsize);
+    push @$plugout,("-output_handle",$out) if (defined $out);
+    push @$plugout,("-debug") if ($debug);
+    
+    $processor = &plugout::load_plugout($plugout);                        
+    $processor->setoutputdir ($archivedir);
+    $processor->set_sortmeta ($sortmeta, $removeprefix, $removesuffix) if defined $sortmeta;
+    $processor->set_OIDtype ($OIDtype, $OIDmetadata);
+    
+    &plugin::begin($pluginfo, $importdir, $processor, $maxdocs, $gli);
+
+    if ($manifest eq "") {
+	# process the import directory
+	my $block_hash = {};
+	my $metadata = {};
+	# gobal blocking pass may set up some metadata
+	&plugin::file_block_read($pluginfo, $importdir, "", $block_hash, $metadata, $gli);
+
+
+	if (!$removeold) {
+
+	    &inexport::prime_doc_oid_count($archivedir);
+
+
+	    # Can now work out which files were new, already existed, and have
+	    # been deleted
+	    
+	    &inexport::new_vs_old_import_diff($archive_info,$block_hash,$importdir);
+	    
+	    my @deleted_files = sort keys %{$block_hash->{'deleted_files'}};
+	    # Filter out any in gsdl/tmp area
+	    my @filtered_deleted_files = ();
+	    my $gsdl_tmp_area = &util::filename_cat($ENV{'GSDLHOME'}, "tmp");
+	    my $collect_tmp_area = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "tmp");
+	    $gsdl_tmp_area = &util::filename_to_regex($gsdl_tmp_area);
+	    $collect_tmp_area = &util::filename_to_regex($collect_tmp_area);
+
+
+	    foreach my $df (@deleted_files) {
+		next if ($df =~ m/^$gsdl_tmp_area/);
+		next if ($df =~ m/^$collect_tmp_area/);
+		
+		push(@filtered_deleted_files,$df);
+	    }
+
+	    
+	    @deleted_files = @filtered_deleted_files;
+
+	    if (scalar(@deleted_files>0)) {
+		print STDERR "Files deleted since last import:\n  ";
+		print STDERR join("\n  ",@deleted_files), "\n";
+	    }
+	    
+	    my @new_files = sort keys %{$block_hash->{'new_files'}};
+	    if (scalar(@new_files>0)) {
+		print STDERR "New files since last import:\n  ";
+		print STDERR join("\n  ",@new_files), "\n";
+	    }
+	    
+	    &inexport::mark_docs_for_deletion($archive_info,$block_hash,\@deleted_files,
+					      $archivedir,$verbosity);
+
+	    &inexport::mark_docs_for_reindex($archive_info,$block_hash,
+					     $archivedir,$verbosity);
+
+	    my @reindex_files = sort keys %{$block_hash->{'reindex_files'}};
+
+	    if (scalar(@reindex_files>0)) {
+		print STDERR "Files to reindex since last import:\n  ";
+		print STDERR join("\n  ",@reindex_files), "\n";
+	    }
+
+
+	    # not sure if the following will work -- wil the metadata datastructure be correctly initialized
+	    # in the right order?
+#	    foreach my $file (@new_files, @reindex_files) {
+#		&plugin::read ($pluginfo, $importdir, $file, $block_hash, $metadata, $processor, $maxdocs, 0, $gli);
+#	    }
+
+
+	    # Play it safe, and run through the entire folder, only processing new or edited files
+	    &plugin::read ($pluginfo, $importdir, "", $block_hash, $metadata, $processor, $maxdocs, 0, $gli);
+
+	}
+	else {
+	    &plugin::read ($pluginfo, $importdir, "", $block_hash, $metadata, $processor, $maxdocs, 0, $gli);
+	}
+
+    }
+    else
+    {
+	# process any files marked for importing
+	foreach my $file (keys %{$manifest_lookup->{'import'}}) {
+	    &plugin::read ($pluginfo, $importdir, $file, {}, {}, $processor, $maxdocs, 0, $gli);
+	}
+
+	my @deleted_files = keys %{$manifest_lookup->{'delete'}};
+
+	&inexport::mark_docs_for_deletion($archive_info,{},\@deleted_files,$archivedir);
+    }
+
+    &plugin::end($pluginfo, $processor);
+
+    &plugin::deinit($pluginfo, $processor);
+
+    # Store the value of OIDCount (used in doc.pm) so it can be
+    # restored correctly to this value on an incremental build
+    &inexport::store_doc_oid_count($archivedir);
+
+    # write out the archive information file
+    $processor->close_file_output() if $groupsize > 1;
+    $processor->close_group_output() if $processor->is_group();
+
+# The following 'if' statement is in the export.pl version of the script,
+# The reason for the 'if' statement is now given in export.pl
+# Unclear at this point if the same should be done here
+##    if (($saveas =~ m/^.*METS$/) || ($saveas eq "MARC")) {
+	# Not all export types need this (e.g. DSpace)
+
+	# should we still do this in debug mode??
+
+    # for backwards compatability with archvies.inf file
+    if ($arcinfo_doc_filename =~ m/\.inf$/) {
+	$archive_info->save_info($arcinfo_doc_filename);
+    }
+    else {
+	$archive_info->save_revinfo_gdbm($arcinfo_src_filename);
+    }
+
+
+##    }
+    
+    # write out import stats
+    my $close_stats = 0;
+    if ($statsfile !~ /^(STDERR|STDOUT)$/i) {
+	if (open (STATS, ">$statsfile")) {
+	    $statsfile = 'import::STATS';
+	    $close_stats = 1;
+	} else {
+	    &gsprintf($out, "{import.cannot_open_stats_file}", $statsfile);
+	    &gsprintf($out, "{import.stats_backup}\n");
+	    $statsfile = 'STDERR';
+	}
+    }
+
+    &gsprintf($out, "\n");
+    &gsprintf($out, "*********************************************\n");
+    &gsprintf($out, "{import.complete}\n");
+    &gsprintf($out, "*********************************************\n");
+
+    &plugin::write_stats($pluginfo, $statsfile, $faillogname, $gli);
+    if ($close_stats) {
+	close STATS;
+    }
+
+    close OUT if $close_out;
+    close FAILLOG;
+}
Index: /gsdl/stable/bin/script/importfrom.pl
===================================================================
--- /gsdl/stable/bin/script/importfrom.pl	(revision 20131)
+++ /gsdl/stable/bin/script/importfrom.pl	(revision 20131)
@@ -0,0 +1,453 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# importfrom.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will contact the named DL server
+#  and export its metadata and (optionally) it documents.
+
+# Currently only designed for OAI exporting
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use colcfg;
+use util;
+use parsargv;
+use FileHandle;
+
+my $wgetopt = "";
+
+my $num_processed = 0;
+
+sub print_usage {
+    print STDERR "\n  usage: $0 [options] collection-name\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -verbosity number      0=none, 3=lots\n";
+    print STDERR "   -getdoc                Also download if source document if present\n";
+    print STDERR "   -importdir directory   Where the original material lives\n";
+    print STDERR "   -keepold               Will not destroy the current contents of the\n";
+    print STDERR "                          import directory (the default)\n";
+    print STDERR "   -removeold             Will remove the old contents of the import\n";
+    print STDERR "                          directory -- use with care\n";
+    print STDERR "   -gzip                  Use gzip to compress exported documents\n";
+    print STDERR "                          (don't forget to include ZIPPlugin in your plugin\n";
+    print STDERR "   -maxdocs number        Maximum number of documents to import\n";
+    print STDERR "   -debug                 Print imported text to STDOUT\n";
+    print STDERR "   -collectdir directory  Collection directory (defaults to " .
+	&util::filename_cat ($ENV{'GSDLHOME'}, "collect") . ")\n";
+    print STDERR "   -out                   Filename or handle to print output status to.\n";
+    print STDERR "                          The default is STDERR\n\n";
+}
+
+
+
+sub xml_pretty_print
+{
+    my ($text,$out,$verbosity) = @_;
+
+    if (system("xmllint --version >/dev/null 2>&1")!=0) {
+	if ($verbosity>1) {
+	    print STDERR "Warning: Unable to find xmllint for pretty printing.\n";
+	    print STDERR "         XML will be shown verbatim.\n\n";
+	}
+	print $out $text;
+    }
+    else {
+
+	if (!open (PPOUT,"|xmllint --format -")) {
+	    print STDERR "Error running xmllint: $!\n\n";
+	    print $out $text;
+	    return;
+	}
+
+	print PPOUT $text;
+	close(PPOUT);
+    }
+}
+
+sub wget_oai_url 
+{
+    my ($wget_cmd,$out,$verbosity) = @_;
+
+    if ($verbosity>2) {
+	print $out "  $wget_cmd\n";
+    }
+
+    open (OAIIN,"$wget_cmd |")
+	|| die "wget request failed: $!\n";
+ 
+    my $li_record = "";
+
+    my $line;
+    while (defined($line=<OAIIN>))
+    {
+	$li_record .= $line;
+	# print $out $line;
+    }
+
+    close(OAIIN);
+
+    return $li_record;
+}
+
+sub oai_info
+{
+    my ($base_url,$out,$verbosity) = @_;
+
+    my $base_wget_cmd = "wget $wgetopt -q -O - \"$base_url?_OPTS_\"";
+ 
+    my $identify = "verb=Identify";
+    my $list_sets = "verb=ListSets";
+    my $list_md_formats = "ListMetadataFormats"; # not currently used
+
+    my $identify_cmd = $base_wget_cmd;
+    $identify_cmd =~ s/_OPTS_/$identify/;
+    print $out "-------------------\n";
+    print $out "General Information\n";
+    print $out "-------------------\n";
+    my $identify_text = wget_oai_url($identify_cmd,$out,$verbosity);
+    xml_pretty_print($identify_text,$out,$verbosity);
+
+    
+    my $list_sets_cmd = $base_wget_cmd;
+    $list_sets_cmd =~ s/_OPTS_/$list_sets/;
+    print $out "-------------------\n";
+    print $out "Set Information\n";
+    print $out "-------------------\n";
+    my $list_sets_text = wget_oai_url($list_sets_cmd,$out,$verbosity);
+    xml_pretty_print($list_sets_text,$out,$verbosity);
+}
+
+
+sub get_oai_ids
+{
+    my ($base_url, $set, $format, $out, $verbosity) = @_;
+
+    print $out "Requesting list of identifiers ...\n";
+    
+    my $base_wget_cmd = "wget $wgetopt -q -O - \"$base_url?_OPTS_\"";
+    my $identifiers_cmd = $base_wget_cmd;
+
+    my $identifiers_opts = "verb=ListIdentifiers&metadataPrefix=$format";
+
+    if (defined $set && ($set ne "")) {
+	$identifiers_opts .= "&set=$set";
+    }
+
+    $identifiers_cmd =~ s/_OPTS_/$identifiers_opts/;
+
+    my $li_record = wget_oai_url($identifiers_cmd,$out,$verbosity);
+
+    print $out "... Done.\n";
+
+    return $li_record;
+}
+
+sub parse_oai_ids
+{
+    my ($li_record, $out, $verbosity) = @_;
+
+    # extract identifier list
+    $li_record =~ s/^.*?<identifier>/<identifier>/s;
+    $li_record =~ s/^(.*<\/identifier>).*$/$1/s;
+
+    my @ids = ();
+
+    while ($li_record =~ m/<identifier>(.*?)<\/identifier>(.*)$/s)
+    {
+	$li_record = $2;
+	push(@ids,$1);
+    }
+
+    return \@ids;
+}
+
+
+sub dir_file_split
+{
+    my ($file) = @_;
+
+    my @dirs = split("/",$file);
+    my $local_file = pop(@dirs);
+    my $sub_dirs = join("/",@dirs);
+
+    return ($sub_dirs,$local_file);
+}
+
+sub get_oai_document
+{
+    my ($doc_url,$output_dir, $out) = @_;
+
+    my ($id_dir,$id_fname) = dir_file_split($doc_url);
+
+    print $out "Getting document $doc_url\n";
+
+    &util::mk_dir($output_dir)  if (!-e "$output_dir");
+
+    my $full_id_fname = &util::filename_cat($output_dir,$id_fname);
+
+    my $wget_cmd = "wget $wgetopt --quiet -O \"$full_id_fname\" \"$doc_url\"";
+
+    if (system($wget_cmd)!=0) {
+	print STDERR "Error: failed to execute $wget_cmd\n";
+	return 0;
+    }
+
+    return 1;    
+}
+
+sub get_oai_records
+{
+    my ($base_url,$format, $ids,$output_dir, $get_id, $maxdocs, $out) = @_;
+
+    my $doc_count = 0;
+
+    my $i;
+    foreach $i ( @$ids )
+    {
+	# wget it;
+	my $url = "$base_url?verb=GetRecord&metadataPrefix=$format";
+	$url .= "&identifier=$i";
+	print $out "Downloading metadata record for $i\n";
+
+        my $i_url = $i; #convert OAI set separators (:) to directory sep
+        $i_url =~ s/:/\//g;
+	my $file_i_url = "$output_dir/$i_url.oai";
+
+	my $ds = &util::get_dirsep();
+	my $i_os = $i; #convert OAI set separators (:) to OS dir sep
+	$i_os =~ s/:/$ds/g;
+	my $file_i = &util::filename_cat($output_dir,"$i_os.oai");
+
+	# obtain record
+	my $wget_cmd = "wget $wgetopt -q -O - \"$url\"";
+
+	open (OAIIN,"$wget_cmd|")
+	    || die "wget request failed: $!\n";
+	my $i_record = "";
+	
+	my $line;
+	while (defined($line=<OAIIN>))
+	{
+	    $i_record .= $line;
+	}
+
+	close(OAIIN);
+
+	$num_processed++;
+	
+	# prepare subdirectory for record (if needed)
+	my ($i_dir,$unused) = dir_file_split($file_i_url);
+
+	&util::mk_all_dir($i_dir);
+
+	# look out for identifier tag in metadata section
+	if ($i_record =~ m/<metadata>(.*)<\/metadata>/s)
+	{
+	    my $m_record = $1;
+
+	    if ($get_id)
+	    {
+		my $got_doc = 0;
+
+		my @url_matches = ($m_record =~ m/<(?:dc:)?identifier>(.*?)<\/(?:dc:)?identifier>/gs);
+		foreach my $doc_url (@url_matches) 
+		{
+		    if ($doc_url =~ m/^(http|ftp):/) {
+
+			my $revised_doc_url = $doc_url;
+##			$revised_doc_url =~ s/hdl\.handle\.net/mcgonagall.cs.waikato.ac.nz:8080\/dspace\/handle/;
+			
+			my $srcdocs_dir = &util::filename_cat($i_dir,"srcdocs");
+
+			if (get_oai_document($revised_doc_url,$srcdocs_dir, $out)) {			   
+
+			    $got_doc = 1;
+			    my ($id_dir,$id_fname) = dir_file_split($revised_doc_url);
+			    
+			    $i_record =~ s/<metadata>(.*?)<(dc:)?identifier>$doc_url<\/(dc:)?identifier>(.*?)<\/metadata>/<metadata>$1<OrigURL>$doc_url<\/OrigURL>\n   <identifier>srcdocs\/$id_fname<\/identifier>$4<\/metadata>/s;
+			    
+			}
+		    }
+
+		    if (!$got_doc) {
+			$i_record =~ s/<metadata>(.*?)<(dc:)?identifier>$doc_url<\/(dc:)?identifier>(.*?)<\/metadata>/<metadata>$1<OrigIdentifier>$doc_url<\/OrigIdentifier>$4<\/metadata>/s;
+		    }
+		}
+	    }
+	}
+
+	# save record 
+	open (OAIOUT,">$file_i")
+	    || die "Unable to save oai metadata record: $!\n";
+	print OAIOUT $i_record;
+	close(OAIOUT);
+
+	$doc_count++;
+	last if ($doc_count == $maxdocs);
+    }
+}
+
+
+sub main {
+    my ($verbosity, $importdir, $keepold, 
+	$getdoc, $acquire_info, $acquire_set,
+	$removeold, $gzip, $groupsize, $debug, $maxdocs, $collection,
+	$configfilename, $collectcfg,
+	$out, $collectdir);
+
+    if (!parsargv::parse(\@ARGV, 
+			 'verbosity/\d+/2', \$verbosity,
+			 'getdoc', \$getdoc,
+			 'info', \$acquire_info,
+			 'importdir/.*/', \$importdir,
+			 'keepold', \$keepold,
+			 'removeold', \$removeold,
+			 'gzip', \$gzip,
+			 'debug', \$debug,
+			 'maxdocs/^\-?\d+/-1', \$maxdocs,
+			 'collectdir/.*/', \$collectdir,
+			 'out/.*/STDERR', \$out)) {
+	&print_usage();
+	die "\n";
+    }
+
+    my $close_out = 0;
+    if ($out !~ /^(STDERR|STDOUT)$/i) {
+	open (OUT, ">$out") || die "Couldn't open output file $out\n";
+	$out = 'import::OUT';
+	$close_out = 1;
+    }
+    $out->autoflush(1);
+
+    # set removeold to false if it has been defined
+    $removeold = 0 if ($keepold);
+
+    # get and check the collection name
+    if (($collection = &util::use_collection(@ARGV, $collectdir)) eq "") {
+	&print_usage();
+	die "\n";
+    }
+
+
+    # get acquire list
+    my $acquire = [];
+    $configfilename = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "etc", "collect.cfg");
+    if (-e $configfilename) {
+	$collectcfg = &colcfg::read_collect_cfg ($configfilename);
+	if (defined $collectcfg->{'acquire'}) {
+	    $acquire = $collectcfg->{'acquire'};
+	}
+	if (defined $collectcfg->{'importdir'} && $importdir eq "") {
+	    $importdir = $collectcfg->{'importdir'};
+	}
+	if (defined $collectcfg->{'removeold'}) {
+	    if ($collectcfg->{'removeold'} =~ /^true$/i && !$keepold) {
+		$removeold = 1;
+	    }
+	    if ($collectcfg->{'removeold'} =~ /^false$/i && !$removeold) {
+		$removeold = 0;
+	    }
+	}
+    } else {
+	die "Couldn't find the configuration file $configfilename\n";
+    }
+    
+    # fill in the default import directory if none
+    # were supplied, turn all \ into / and remove trailing /
+    $importdir = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "import") if $importdir eq "";
+    $importdir =~ s/[\\\/]+/\//g;
+    $importdir =~ s/\/$//;
+
+    # remove the old contents of the import directory if needed
+    if ($removeold && -e $importdir) {
+	print $out "Warning - removing current contents of the import directory\n";
+	print $out "          in preparation for the acquire\n";
+	&util::rm_r ($importdir);
+    }
+
+    my $e;
+    foreach $e ( @$acquire )
+    {
+	my $acquire_type = shift @$e;
+	my $acquire_src = undef;
+
+	if ($acquire_type ne "OAI") {
+	    print STDERR "Warning: $acquire_type not currently supported. Skipping.\n";
+	    next;
+	}
+
+	my $store_getdoc = $getdoc;
+
+	if (!parsargv::parse($e, 
+			     'getdoc',  \$getdoc,
+			     'set/.*/', \$acquire_set,
+			     'format/.*/oai_dc', \$metadata_format,
+			     'src/.*/', \$acquire_src)) {
+	    &print_usage();
+	    die "\n";
+	}
+
+	if (!defined $acquire_src) {
+	    print STDERR "Warning: Not -src flag defined.  Skipping.\n";
+	    next;
+	}
+
+	if (defined $acquire_info && ($acquire_info)) {
+	    oai_info($acquire_src,$out,$verbosity);
+	    next;
+	}
+
+	print $out "$acquire_type Acquire: from $acquire_src\n";
+
+	my $li_record = get_oai_ids($acquire_src,$acquire_set,$metadata_format,
+				    $out,$verbosity);
+	my $ids = parse_oai_ids($li_record,$out,$verbosity);
+
+	get_oai_records($acquire_src,$metadata_format, $ids,$importdir, 
+			$getdoc, $maxdocs, $out);
+	$getdoc = $store_getdoc;
+    }
+
+    print "\nNumber of documents processed: $num_processed\n";
+
+    close OUT if $close_out;
+}
+
+
+&main();
+
+
+
+
+
+
+
+
Index: /gsdl/stable/bin/script/incremental-buildcol.pl
===================================================================
--- /gsdl/stable/bin/script/incremental-buildcol.pl	(revision 20131)
+++ /gsdl/stable/bin/script/incremental-buildcol.pl	(revision 20131)
@@ -0,0 +1,178 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# incremental-buildcol.pl -- runs buildcol.pl with -incremental on
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2009 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program is designed to support incremental building of Greenstone
+# Runs:        buildcol.pl -incremental -builddir GSDLHOME/collect/$collect/index ...
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and vice versa
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+
+use util;
+use colcfg;
+
+sub main
+{
+    my ($argc,@argv) = @_;
+
+    if (($argc==0)  || (($argc==1) && ($argv[0] =~ m/^--?h(elp)?$/))) {
+	my ($progname) = ($0 =~ m/^.*\/(.*?)$/);
+
+
+	print STDERR "\n";
+	print STDERR "Usage: $progname [buildcol.pl options] collection\n";
+	print STDERR "\n";
+
+	exit(-1);
+    }
+
+
+    my $collect = pop @argv;
+
+    my @filtered_argv = ();
+
+    my $collect_dir = undef;
+    my $build_dir  = undef;
+    my $site = undef;
+
+    while (my $arg = shift @argv) {
+	if ($arg eq "-collectdir") {
+	    $collect_dir = shift @argv;
+	    push(@filtered_argv,$arg,$collect_dir);
+	}
+	elsif ($arg eq "-builddir") {
+	    $build_dir = shift @argv;
+	    push(@filtered_argv,$arg,$build_dir);
+	}
+	elsif ($arg eq "-site") {
+	    $site = shift @argv;
+	    push(@filtered_argv,$arg,$site);
+	}
+	else {
+	    push(@filtered_argv,$arg);
+	}
+    }
+
+
+    if (!defined $collect_dir) {
+	$collect_dir = &util::filename_cat($ENV{'GSDLHOME'},"collect");
+    }
+    my $this_collect_dir = &util::filename_cat($collect_dir,$collect);
+
+    if (!-d $this_collect_dir) {
+	print STDERR "Error: $collect_dir does not exist\n";
+	exit(-1);
+    }
+
+
+    if (!defined $build_dir) {
+	# Yes this is intentional that 'build_dir' points to "index"
+	$build_dir = &util::filename_cat($this_collect_dir,"index");
+	push(@filtered_argv,"-builddir",$build_dir);
+    }
+
+    my $quoted_argv = join(" ", map { "\"$_\"" } @filtered_argv);
+    
+    my $buildcol_cmd = "buildcol.pl";
+    if($ENV{'GSDLOS'} =~ m/windows/) {
+	if($ENV{'PERLPATH'}) {
+	    # need to ensure that the path to perl is quoted (in case there's spaces in it)
+	    $buildcol_cmd = "\"$ENV{'PERLPATH'}\\Perl.exe\" -S $buildcol_cmd";
+	} else {
+	    $buildcol_cmd = "perl -S $buildcol_cmd";
+	}
+    }
+
+    if ((&colcfg::use_collection($site, $collect, $collect_dir)) eq "") {
+	print STDERR "Unable to use collection \"$collect\" within \"$collect_dir\"\n";
+	exit -1;
+    }
+    # Read in the collection configuration file.
+    my ($collect_cfg_filename, $gs_mode) = &colcfg::get_collect_cfg_name(STDERR);
+	
+    my $collectcfg = &colcfg::read_collection_cfg ($collect_cfg_filename,$gs_mode);
+
+    # look for build.cfg/buildConfig.xml
+    my $build_cfg_filename ="";
+
+    if ($gs_mode eq "gs2") {
+	$build_cfg_filename = &util::filename_cat($build_dir,"build.cfg");
+    } else {
+	$build_cfg_filename = &util::filename_cat($build_dir, "buildConfig.xml");
+    }
+    
+    if (-e $build_cfg_filename) {
+
+	# figure out if there has been a change of indexer 
+	# (e.g. collect.cfg now says lucene, but build.cfg says mgpp)
+
+	my $buildcfg = &colcfg::read_building_cfg ($build_cfg_filename, $gs_mode);
+	if ($buildcfg->{'buildtype'} ne $collectcfg->{'buildtype'}) {
+	    print STDERR "*****\n";
+	    print STDERR "* Change of indexer detected. Switching to full buildcol.pl.\n";
+	    print STDERR "*****\n";
+	    $buildcol_cmd .= " -removeold";
+	}
+	else {
+
+	    $buildcol_cmd .= " -incremental";
+	}
+    }
+    else {
+	# build.cfg doesn't exit
+	print STDERR "*****\n";
+	print STDERR "* First time built. Switching to full buildcol.pl.\n";
+	print STDERR "*****\n";
+	$buildcol_cmd .= " -removeold";
+    }
+
+    
+    $buildcol_cmd .= " $quoted_argv \"$collect\"";
+    
+    my $buildcol_status = system($buildcol_cmd)/256;
+    
+    if ($buildcol_status != 0) {
+	print STDERR "Error: Failed to run: $buildcol_cmd\n";
+	print STDERR "       $!\n" if ($! ne "");
+	exit(-1);
+    }
+}
+
+&main(scalar(@ARGV),@ARGV);
+
+
+
+
Index: /gsdl/stable/bin/script/incremental-import.pl
===================================================================
--- /gsdl/stable/bin/script/incremental-import.pl	(revision 20131)
+++ /gsdl/stable/bin/script/incremental-import.pl	(revision 20131)
@@ -0,0 +1,141 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# full-import.pl -- runs import.pl with -incremental option on
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2009 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program is designed to support incremental building of Greenstone
+# Runs:        import.pl -incremental ...
+
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+
+use strict;
+
+use util;
+
+
+sub main
+{
+    my ($argc,@argv) = @_;
+
+    if (($argc==0)  || (($argc==1) && ($argv[0] =~ m/^--?h(elp)?$/))) {
+	my ($progname) = ($0 =~ m/^.*\/(.*?)$/);
+
+
+	print STDERR "\n";
+	print STDERR "Usage: $progname [import.pl options] collection\n";
+	print STDERR "\n";
+
+	exit(-1);
+    }
+
+
+    my $collect = pop @argv;
+
+    my @filtered_argv = ();
+
+    my $collect_dir = undef;
+    my $archive_dir  = undef;
+
+    while (my $arg = shift @argv) {
+	# No actual filtering happens at the moment (@filterd_argv == @argv)
+	# Useful to do it this way if we want incremental-import.pl
+	# to start accepting its own arguments that are different to import.pl
+	
+	if ($arg eq "-collectdir") {
+	    $collect_dir = shift @argv;
+	    push(@filtered_argv,$arg,$collect_dir);
+	}
+	elsif ($arg eq "-archivedir") {
+	    $archive_dir = shift @argv;
+	    push(@filtered_argv,$arg,$archive_dir);
+	}
+	else {
+	    push(@filtered_argv,$arg);
+	}
+    }
+
+    if (!defined $collect_dir) {
+	$collect_dir = &util::filename_cat($ENV{'GSDLHOME'},"collect");
+    }
+    my $this_collect_dir = &util::filename_cat($collect_dir,$collect);
+
+    if (!-d $this_collect_dir) {
+	print STDERR "Error: $this_collect_dir does not exist\n";
+	exit(-1);
+    }
+
+
+    if (!defined $archive_dir) {
+	$archive_dir = &util::filename_cat($this_collect_dir,"archives");
+    }
+    
+    my $archiveinf_doc = &util::filename_cat($archive_dir,"archiveinf-doc");
+    &util::rename_gdbm_file($archiveinf_doc); # ensure gdb
+    $archiveinf_doc .= ".gdb";
+    my $quoted_argv = join(" ", map { "\"$_\"" } @filtered_argv);
+    
+
+    my $import_cmd = "import.pl";
+    if($ENV{'GSDLOS'} =~ m/windows/) {
+	if($ENV{'PERLPATH'}) {
+	    # need to ensure that the path to perl is quoted (in case there's spaces in it)
+	    $import_cmd = "\"$ENV{'PERLPATH'}\\Perl.exe\" -S $import_cmd";
+	} else {
+	    $import_cmd = "perl -S $import_cmd";
+	}
+    }
+    if (-e $archiveinf_doc) {
+	$import_cmd .= " -incremental";
+	
+    }
+    else {
+###	print STDERR "$archiveinf_doc does not exist.\n";
+	print STDERR "*****\n";
+	print STDERR "First time import. Switching to full import.pl.\n";
+	print STDERR "*****\n";
+	$import_cmd .= " -removeold";
+    }
+
+    $import_cmd .= " $quoted_argv \"$collect\"";
+
+    
+    my $import_status = system($import_cmd)/256;
+    
+    if ($import_status != 0) {
+	print STDERR "Error: Failed to run: $import_cmd\n";
+	print STDERR "       $!\n" if ($! ne "");
+	exit(-1);
+    }
+}
+
+&main(scalar(@ARGV),@ARGV);
Index: /gsdl/stable/bin/script/incremental-rebuild.pl
===================================================================
--- /gsdl/stable/bin/script/incremental-rebuild.pl	(revision 20131)
+++ /gsdl/stable/bin/script/incremental-rebuild.pl	(revision 20131)
@@ -0,0 +1,107 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# incremental-rebuild.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2009 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will incrementally rebuild a collection 
+# Runs:        incremental-import.pl -incremental ...
+# Followed by: incremental-buildcol.pl -incremental -builddir index ...
+# (assumming import.pl did not end with an error)
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+
+use strict;
+
+use util;
+
+sub main
+{
+    my ($argc,@argv) = @_;
+
+    if (($argc==0)  || (($argc==1) && ($argv[0] =~ m/^--?h(elp)?$/))) {
+	my ($progname) = ($0 =~ m/^.*\/(.*?)$/);
+
+	print STDERR "\n";
+	print STDERR "Usage: $progname [shared import.pl and buildcol.pl options] collection\n";
+	print STDERR "\n";
+
+	exit(-1);
+    }
+	
+
+    my $collect = pop @argv;
+
+    my $quoted_argv = join(" ", map { "\"$_\"" } @argv);
+    
+    my $final_status = 0;
+    
+    my $launch_cmd = "";
+    if($ENV{'GSDLOS'} =~ m/windows/) {
+	if($ENV{'PERLPATH'}) {
+	    # need to ensure that the path to perl is quoted (in case there's spaces in it)
+	    $launch_cmd = "\"$ENV{'PERLPATH'}\\Perl.exe\" -S ";
+	} else {
+	    $launch_cmd = "perl -S ";
+	}
+    }
+
+    print "\n";
+    print "************************\n";
+    print "* Running  Import  Stage\n";
+    print "************************\n";
+    
+    my $import_cmd = $launch_cmd . "incremental-import.pl $quoted_argv \"$collect\"";
+    
+    my $import_status = system($import_cmd)/256;
+    
+    if ($import_status == 0) {
+	print "\n";
+	print "************************\n";
+	print "* Running Buildcol Stage\n";
+	print "************************\n";
+	
+
+	my $buildcol_cmd = $launch_cmd . "incremental-buildcol.pl $quoted_argv \"$collect\"";
+	my $buildcol_status = system($buildcol_cmd)/256;
+	if ($buildcol_status != 0) {
+	    $final_status = $buildcol_status;
+	}
+    }
+    else {
+	$final_status = $import_status;
+    }
+    
+    exit($final_status);
+}
+
+&main(scalar(@ARGV),@ARGV);
+
Index: /gsdl/stable/bin/script/indexes/Core.pm
===================================================================
--- /gsdl/stable/bin/script/indexes/Core.pm	(revision 20131)
+++ /gsdl/stable/bin/script/indexes/Core.pm	(revision 20131)
@@ -0,0 +1,895 @@
+#
+# PDF::Core.pm, version 1.11 February 2000 antro
+#
+# Copyright (c) 1998 - 2000 Antonio Rosella Italy antro@tiscalinet.it, Johannes Blach dw235@yahoo.com 
+#
+# Free usage under the same Perl Licence condition.
+#
+
+package PDF::Core;
+
+$PDF::Core::VERSION = "1.11";
+
+=pod
+
+=head1 NAME
+
+PDF::Core - Core Library for PDF library
+
+=head1 SYNOPSIS
+
+  use PDF::Core;
+
+  $pdf=PDF::Core->new ;
+  $pdf=PDF->new(filename);
+
+  $res= $pdf->GetObject($ref);
+
+  $name = UnQuoteName($pdfname);							  
+  $string = UnQuoteString($pdfstring);							  
+
+  $pdfname = QuoteName($name);							  
+  $pdfhexstring = QuoteHexString($string);
+  $pdfstring = QuoteString($string);
+
+  $obj = PDFGetPrimitive (filehandle, \$offset);
+  $line = PDFGetLine (filehandle, \$offset);
+  
+
+=head1 DESCRIPTION
+
+The main purpose of the PDF::Core library is to provide the data structure
+and the constructor for the more general PDF library.
+
+=cut
+
+require 5.005;
+use strict;
+use Carp;
+use Exporter ();
+
+use vars qw(@ISA @EXPORT_OK $UseObjectCache);
+
+@ISA = qw(Exporter);
+
+@EXPORT_OK = qw( GetObject );
+
+#
+# Object caching
+#
+# If this variable is true, all processed objects will be added to the
+# object cache. If only header information of a PDF are read or very
+# big PDF are processed, turning off the cache reduces the memory usage.
+#
+$UseObjectCache = 1;
+
+
+#################################################################
+#
+# Helper functions
+#
+#################################################################
+
+=pod
+
+=head1 Helper functions
+
+This functions are not part of the class, but perform useful services.
+
+=cut
+
+#
+# Modification by johi: 18.12.1999
+#
+
+#################################################################
+=pod
+
+=head2 UnQuoteName ( string )
+
+This function processes quoted characters in a PDF-name. PDF-names returned by
+B<GetObject> are already processed by this function.
+
+Returns a string.
+
+=cut
+
+sub UnQuoteName ($)
+	{
+	my $value = shift;
+	$value =~ s/#([\da-f]{2})/chr(hex($1))/ige;
+	return $value;
+	}
+
+#################################################################
+=pod
+
+=head2 UnQuoteString ( string )
+
+This function extracts the text from PDF-strings and PDF-hexstrings.
+It will process all quoted characters and remove the enclosing braces.
+
+WARNING: The current version doesn't handle unicode strings properly.
+
+Returns a string.
+
+=cut
+
+sub UnQuoteString ($)
+	{
+#
+# Translate quoted character. 
+#
+	my $param = shift;
+	my $value;
+	if (($value) = $param =~ m/^<(.*)>$/)
+		{
+		$value =~ tr/0-9A-Fa-f//cd;
+		$value .= "0" if (length ($value) % 2);
+		$value =~ s/([\da-f]{2})/chr(hex($1))/ige;
+		}
+	elsif (($value) = $param =~ m/^\((.*)\)$/)
+		{
+		my %quoted = ("n" => "\n", "r" => "\r",
+					  "t" => "\t", "b" => "\b",
+					  "f" => "\f", "\\" => "\\",
+					  "(" => "(", ")" => ")");
+		$value =~ s/\\([nrtbf\\()]|[0-7]{1,3})/
+		defined ($quoted{$1}) ? $quoted{$1} : chr(oct($1))/gex;
+		}
+	else
+		{
+		$value = $param;
+		}
+
+	return $value;
+	}
+
+#################################################################
+=pod
+
+=head2 QuoteName ( string )
+
+This function quotes problematic characters in a PDF-name. This
+function should be used before writing a PDF-name back to a PDF-file.
+
+Returns a string.
+
+=cut
+
+sub QuoteName ($)
+	{
+	my $value = shift;
+	$value =~ s/(?<!\A)([\x00-\x20\x7f-\xff%()\[\]<>\/{}#])/
+						 sprintf ("#%2.2X", ord($1))/gex;
+	return $value;
+	}
+
+#################################################################
+=pod
+
+=head2 QuoteHexString ( string )
+
+This function translates a string into a PDF-hexstring. 
+
+Returns a string.
+
+=cut
+
+sub QuoteHexString ($)
+	{
+	my $value = shift;
+
+	$value =~ s/(.)/sprintf ("%2.2X", ord($1))/ge;
+	return ("<" . $value . ">");
+	}
+
+#################################################################
+=pod
+
+=head2 QuoteString ( string )
+
+This function translates a string into a PDF-string. Problematic
+character will be quoted.
+
+WARNING: The current version doesn't handle unicode strings properly.
+
+Returns a string.
+
+=cut
+
+sub QuoteString ($)
+	{
+	#
+	# Only \character style quotes will be added. The really important
+	# characters to quote are: ()\
+	# 
+	my $value = shift;
+
+	my %quote = ("\n" => "\\n", "\r" => "\\r",
+				  "\t" => "\\t", "\b" => "\\b",
+				  "\f" => "\\f", "\\" => "\\\\",
+				  "(" => "\\(", ")" => "\\)");
+	$value =~ s/([\n\r\t\b\f\\()])/$quote{$1}/g;
+	return ("(" . $value . ")");
+	}
+
+#################################################################
+=pod
+
+=head2 PDFGetPrimitive ( filehandle, offset )
+
+This internal function is used while parsing a PDF-file. If you are
+not writing extentions for this library and are parsing some special
+parts of the PDF-file, stay away and use B<GetObject> instead.
+
+This function has many quirks and limitations. Check the source for details.
+
+=cut
+
+sub PDFGetPrimitive (*\$)
+	{
+	my $fd = shift;
+	my $offset = shift;
+
+	binmode $fd;
+	seek $fd, $$offset, 0;
+
+	my $state = 0;
+	my $buffer;
+	my @collector;
+	my $lastchar;
+
+	while ()
+		{
+		# File offset is positioned on start of stream.
+		last if ($state == -4);
+
+		$state = 0;
+
+		# Process last element
+		if ($#collector >= 0)
+			{
+			my $lastvalue = $collector[$#collector];
+			
+			if ($lastvalue eq "R")
+				{
+				# Process references
+				if ($#collector >= 2
+					&& $collector[$#collector - 1] =~ m/\d+/
+					&& $collector[$#collector - 2] =~ m/\d+/)
+					{
+					$collector[$#collector - 2] .= join (" ", 
+						"", @collector[$#collector - 1, $#collector]);
+					$#collector -= 2; 
+					}
+				else
+					{
+					carp "Bad reference at offset ", $$offset;
+					}
+				}
+			elsif ($lastvalue eq "endobj")
+				{
+				# End of object
+				last;
+				}
+			elsif ($lastvalue eq "stream")
+				{
+				# End of object
+				$state = -4;
+				}
+			}
+		
+		# Set state for next element
+		if ($buffer eq "[") 
+			{
+			# Read array
+			$buffer = "";
+			push @collector, [ PDFGetPrimitive ($fd, $offset) ];
+			}
+		elsif ($buffer eq "<<")
+			{
+			# Read dictionary
+			$buffer = "";
+			push @collector, { PDFGetPrimitive ($fd, $offset) };
+			}
+		elsif ($buffer eq "(") 
+			{
+			# Here comes a string
+			$state = 1;
+			$lastchar = "";
+			}
+		elsif ($buffer eq "<") 
+			{
+			# Here comes a hex string
+			$state = -1;
+			}
+		elsif ($buffer eq ">")
+			{
+			# Wait for next > to terminate dictionary
+			$state = -2;
+			}
+		elsif ($buffer eq "%")
+			{
+			# Skip comments
+			$state = -3;
+			$buffer = "";
+			}
+		elsif ($buffer eq "]")
+			{
+			last;
+			}
+		elsif ($buffer eq ">>")
+			{
+			last;
+			}
+
+		# Read next item
+		while (read ($fd, $_, 1))
+			{
+			$$offset++;
+
+			if ($state == 0)
+				{
+				# Normal mode
+				if (m/[^\x00-\x20\x7f-\xff%()\[\]<>\/]/)
+					{
+					# Normal character inside a name or number
+					$buffer .= $_;
+					}
+				elsif (m/[\/\(\[\]\<\>%]/)
+					{
+					if ($buffer ne "")
+						{
+						# A new item starts
+						if ($buffer =~ m/^\//)
+							{
+							push @collector, UnQuoteName ($buffer);
+							}
+						else
+							{
+							push @collector, $buffer;
+							}
+						}
+					$buffer = $_;
+					last;
+					}
+				elsif (m/\s/)
+					{
+					# All kind of whitespaces are ignored
+					if ($buffer ne "")
+						{
+						# The old item is done starts
+						if ($buffer =~ m/^\//)
+							{
+							push @collector, UnQuoteName ($buffer);
+							}
+						else
+							{
+							push @collector, $buffer;
+							}
+						$buffer = "";
+						last;
+						}
+					}
+				else
+					{
+					# Strange character. Should not exist.
+					# Complain and move on.
+					carp "Strange character '", $_, "' at offset ",
+					$$offset, " in mode ", $state, " detected";
+					$buffer .= $_;
+					}
+				}
+			elsif ($state > 0)
+				{
+				# We have a string
+
+				if ($lastchar =~ m/\\[\r\n]+/ && m/[^\r\n]/)
+					{
+					# Clean up after line continuation
+					$lastchar = "";
+					}
+
+				if ($lastchar =~ m/\\[\r\n]*/)
+					{
+					# Process character after backslash
+					if (m/[\r\n]/)
+						{
+						# end of line
+						$lastchar .= $_;
+						}
+					else
+						{
+						# Just a quote
+						$buffer .= $lastchar . $_;
+						$lastchar = "";
+						}
+					}
+				else
+					{
+					if ($_ eq "\\")
+						{
+						# Quoted string starts
+						$lastchar = $_;
+						}
+					elsif ($_ eq "(")
+						{
+						# Count braces
+						$buffer .= $_;
+						$state ++;
+						}
+					elsif ($_ eq ")")
+						{
+						# End of string
+						$buffer .= $_;
+						unless (-- $state)
+							{
+							push @collector, $buffer;
+							$buffer = "";
+							last;
+							}
+						}
+					else
+						{
+						$buffer .= $_;
+						}
+					}
+				}
+			elsif ($state == -1)
+				{
+				if (m/[0-9a-f\s]/i)
+					{
+					# Hex character
+					$buffer .= $_;
+					}
+				elsif ($_ eq ">")
+					{
+					# End of string
+					$buffer .= $_;
+					push @collector, $buffer;
+					$buffer = "";
+					last;
+					}
+				elsif ($_ eq "<" && $buffer eq "<")
+					{
+					# This is not a string, but a dictionary instead
+					$buffer .= $_;
+					last;
+					}
+				else
+					{
+					# Should not be there. Complain and add it to the $buffer
+					carp "Bad character '", $_ , "' in hex string";
+					$buffer .= $_;
+					}
+				}
+			elsif ($state == -2)
+				{
+				# Wait for second > to terminate dictionary
+
+				# Some sanity checks
+				carp "Character '", $_, "' appeared while waiting for '>'" 
+				if ($_ ne ">");
+				carp "Buffer contains '", $buffer, "' and not '>'" 
+				if ($buffer ne ">");
+
+				$buffer = ">>";
+				last;
+				}
+			elsif ($state == -3)
+				{
+				# Skip comments;
+				last if (m/[\r\n]/);
+				}
+			elsif ($state == -4)
+				{
+				# Wait for newline to start stream
+
+				if ($_ eq "\n")
+					{
+					# Some sanity checks
+					carp "Text '", $buffer, 
+					"' appeared while waiting for start of stream" 
+					if ($buffer ne "");
+
+					$buffer = "";
+					last;
+					}
+				elsif (m/\S/)
+					{
+					$buffer .= $_;
+					}
+				}
+			else
+				{
+				# Unhandled status. Complain and reset
+				carp "Unhandled status ", $state;
+				}
+			}
+		if ($_ eq "")
+			{
+			# Unhandled status. Complain and reset
+			carp "Premature end of file reached";
+			
+			if ($buffer ne "")
+				{
+				push @collector, $buffer;
+				$buffer = "";
+				}
+			last;
+			}
+		}
+
+	return @collector;
+	}
+
+#################################################################
+=pod
+
+=head2 PDFGetline ( filehandle, offset )
+
+This internal function was used to read a line from a PDF-file. It has
+many limitations and you should stay away from it, if you don't know
+what you are doing. Use B<GetObject> or B<PDFGetPrimitive> instead.
+
+=cut
+
+sub PDFGetline {
+#
+# BUG WARNING:
+#
+# This function returns only one line, which doesn't mean anything most of the
+# time. Except for the fileheader and the xref-table, linebreaks can (and will!)
+# occur everywhere in a PDF and are just whitespace. You may find only part of a
+# PDF-primitve on one line, or more than one of them.
+#
+# If you want to read PDF-Primitves, use the function PDFGetPrimitive instead.
+#
+    my $fd = shift;
+    my $offset=shift;
+
+    my $buffer;
+    my $endflag=1;
+
+    binmode $fd;
+    seek $fd, $$offset, 0;
+
+    read($fd,$buffer,2);
+    $buffer =~ s/^\r?\n?// ;
+
+    $$offset +=2;
+
+    while ($endflag) {
+      read($fd,$_,1);
+      $$offset++;
+      $endflag = 0 if ( $_ eq "\r" || $_ eq "\n");
+      $buffer = $buffer . $_ ;
+    }
+    return $buffer;
+	}
+
+#################################################################
+#
+# Constructors
+#
+#################################################################
+
+=pod
+
+=head1 Constructor
+
+=cut
+
+#################################################################
+=pod
+
+=head2 new ( [ filename ] )
+
+This is the constructor of a new PDF object. If the filename is
+missing, it returns an empty PDF descriptor ( can be filled with
+$pdf->TargetFile). Otherwise, It acts as the B<PDF::Parse::TargetFile>
+method.
+
+=cut
+
+sub new {
+
+	my %PDF_Fields = (
+		  File_Name => undef, # Name of file
+		  File_Handler => undef, # Open handle to file
+		  Header => undef, # Identification string
+
+		  Objects => [], # Offset of objects
+		  Gen_Num => [], # Genereation number of objects
+		  Object_Length => [],	# Length of processed objects
+		  Object_Cache => {}, # Cache for objects.
+		  Page => [], # Information about all pages. Useful.
+
+		  Updated => 0,	# Is the PDF updated 
+		  Last_XRef_Offset => undef, # File offset of active Xref table
+		  Trailer => {}, # Content of active trailer
+		  Info => {}, # Content of active info object
+		  Catalog => {}, # Content of catalog
+		  PageTree => {}, # Content of root page
+		  );
+my $that = shift;
+my $class=ref($that) || $that ;
+  my $self = \%PDF_Fields ;
+  my $buf2=bless $self, $class;
+  if ( @_ ) { 			# I have the filename
+    $buf2->TargetFile($_[0]) ; 
+  }
+  return bless $self, $class;
+};
+
+#################################################################
+sub DESTROY {
+#
+# Close the file if not empty
+#
+  my $self = shift;
+  close ( $self->{File_Handler} ) if $self->{File_Handler} ;
+}
+
+#################################################################
+#
+# Methods
+#
+#################################################################
+
+=pod
+
+=head1 Methods
+
+The available methods are:
+
+=cut
+
+#################################################################
+=pod
+
+=head2 GetObject (reference)
+
+This methods returns the PDF-object for B<reference>. The string
+B<reference> must match the regular expression /^\d+ \d+ R$/,
+where the first number is the object number, the second number the
+generation number.
+
+The return value is a PDF-primitive, the type depends on the content
+of the object:
+
+=over
+
+=item B<undef>
+
+The object could not be found or an error. Not all referenced objects
+need to be present in a PDF-file. This value can be ignored.
+
+=item B<Hash Reference>
+
+If (UNIVERSAL::isa ($retval, "HASH") is true, the object is a
+PDF-dictionary. The keys of the hash should be either a PDF name (eg:
+/MediaBox) or a generated value like Stream_Offset. Everything else is
+an error.
+
+The values of the hash can be any PDF-primitive, including PDF-arrays
+and other dictionaries.
+
+This is the most common value returned by GetObject. If the key
+Stream_Offset exists, the dictionary is followed by stream data,
+starting at the file offeset indicated by this value.
+
+=item B<Array Reference>
+
+If (UNIVERSAL::isa ($retval, "ARRAY") is true, the object is a
+PDF-array. Each element may be of a different type, and may contain
+further references to arrays or any other PDF-primitive.
+
+=item B<String matching /^\d+ \d+ R$/>
+
+This is a reference to another PDF-Object. This value can be passed to
+GetObject. This kind of value may appear instead of most other types.
+Some PDF-writing programs seem to have special fun writing references
+when a simple number is expected. If the final number is need, use
+code like this to resolve references:
+
+while ($len =~ m/^\d+ \d+ R$/) {$len = $self->GetObject ($len);	}
+
+Example: 22 0 R
+
+=item B<String matching /^\//>
+
+This is a Name in a PDF dictionary. This string is already processed
+by B<UnQuotName> and may differ from the value in the PDF-file. In
+some very old andstrange non-standard PDF-files, this may lead to
+confusion.
+
+Example: /MediaBox
+
+=item B<String matching /^\(.*\)$/>
+
+This is a string. It may contain newlines, quoted characters und other
+strange stuff. Use PDF::UnQuoteString to extract the text.
+
+Example: (This is\na string with two \(2\) lines.)
+
+=item B<String matching /^E<lt>.*E<gt>$/>
+
+This is a hex encoded string. Use PDF::UnQuoteString to extract the text.
+
+Example: E<lt>48 45 4c4C4 F1cE<gt>
+
+=item B<String matching /^[\d.\+\-]+$/>
+
+This is probably a number.
+
+Example: 611
+
+=item B<String matching none of the above>
+
+this is either a PDF bareword (eg. true, false, ...) or a value
+generated by this method like Stream_Offset.
+
+Example: true
+
+=back
+
+To improve performance GetObject uses an internal cache for objects.
+Repeated requests for the same objects are not read form the file but
+satisfied from the cache. With the Variable B<$PDF::Core::UseObjectCache>,
+the caching mechanism can be turned off.
+
+B<WARNING>
+
+Special care must be taken, when returned objects are modified. If the
+object contains sub-objects, the sub-objects are not duplicated and
+all changes affect all other copies of this object. Use your own copy,
+if you need to modify those values.
+
+=cut
+
+sub GetObject (\*$;$)
+	{
+	my $self = shift;
+	my $ref = shift;
+	my $force = shift;
+
+#
+# Is PDF file open?
+#
+	croak "PDF-file not open." unless ($self->{"File_Handler"});
+
+#
+# Check reference
+#
+	my ($ind, $gen);
+	unless (($ind,$gen) = $ref =~ m/^(\d+) (\d+) R$/)
+		{
+		carp "Bad object reference '", $_, "'";
+		return undef;
+		}
+	if ($ind > $#{$self->{"Gen_Num"}} || $self->{"Gen_Num"}[$ind] != $gen)
+		{
+		#
+		# The page does not exist. According to the PDF specification,
+		# this is not an error.
+		#
+		return undef;
+		}
+
+	# Remove leading zero for cache key.
+	$ind += 0;
+	# Check cache
+	if ($UseObjectCache && ! $force
+		&& defined($self->{"Object_Cache"}{$ind}))
+		{
+		return $self->{"Object_Cache"}{$ind};
+		}
+
+	my $offset = $self->{"Objects"}[$ind];
+	my @data = PDFGetPrimitive ($self->{"File_Handler"}, $offset);
+
+	unless ($#data == 4  && $data[0] == $ind 
+		&& $data[1] == $gen && $data[2] eq "obj")
+		{
+		carp "Object mismatch: Got '", join (" ", @data[0..2]),
+		"' instead of '", join (" ", $ind, $gen, "obj"), "'";
+		return;
+		}
+
+	#
+	# An object is not always a dictionary. In such cases,
+	# adding additional keys breaks the content.
+	#
+	if (UNIVERSAL::isa ($data[3], "HASH"))
+		{
+		if ($data[4] eq "stream")
+			{
+			#
+			# Find end of a stream object
+			#
+			$data[3]{"Stream_Offset"} = $offset;
+			my $len = $data[3]{"/Length"};
+
+			# Length can be a reference to another object. 
+			# Resolve references in this case till something else appears.
+			while ($len =~ m/^\d+ \d+ R$/)
+				{
+				$len = $self->GetObject ($len);
+				}
+
+			# Skip stream
+			if ($len =~ m/^\d+$/)
+				{
+				$offset += $len;
+				}
+			else
+				{
+				carp "Strange: /Length resolves to '", $len, "' in object ", 
+				join (" ", @data[0..2]);
+				}
+
+			my @enddata = PDFGetPrimitive ($self->{"File_Handler"}, $offset);
+			$data[4] = $enddata[$#enddata];
+			}
+		}
+
+	#
+	# Save length of object.
+	#
+	$self->{"Object_Length"}[$ind] = $offset - $self->{"Objects"}[$ind];
+
+	carp "Bad object termination '", $data[4], "' in object ", 
+	join (" ", @data[0..2]) if ($data[4] ne "endobj");
+	
+
+	# Update cache
+	$self->{"Object_Cache"}{$ind} = $data[3] if ($UseObjectCache);
+
+	return $data[3];
+	}
+
+#
+# End of Modification by johi: 18.12.1999
+#
+#################################################################
+
+
+1;
+__END__
+
+=pod
+
+=head1 Variables
+
+Available variables are:
+
+=over 4
+
+=item B<$PDF::Core::VERSION>
+
+Contains the version of the library installed
+
+=item B<$PDF::Core::UseObjectCache>
+
+If this variable is true, all processed objects will be added to the
+object cache. If only header information of a PDF are read or very big
+PDF are processed, turning off the cache reduces the memory usage.
+
+=back 4
+
+=head1 Copyright
+
+  Copyright (c) 1998 - 2000 Antonio Rosella Italy antro@tiscalinet.it, Johannes Blach dw235@yahoo.com 
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 Availability
+
+The latest version of this library is likely to be available from:
+
+http://www.geocities.com/CapeCanaveral/Hangar/4794/
+
+=cut
Index: /gsdl/stable/bin/script/indexes/PDF.pm
===================================================================
--- /gsdl/stable/bin/script/indexes/PDF.pm	(revision 20131)
+++ /gsdl/stable/bin/script/indexes/PDF.pm	(revision 20131)
@@ -0,0 +1,153 @@
+#
+# PDF.pm, version 1.11 February 2000 antro
+#
+# Copyright (c) 1998 - 2000 Antonio Rosella Italy antro@tiscalinet.it, Johannes Blach dw235@yahoo.com 
+#
+# Free usage under the same Perl Licence condition.
+#
+
+package PDF;
+
+$PDF::VERSION = "1.11";
+
+require 5.005;
+
+#require PDF::Core;  
+#require PDF::Parse; 
+require Core;  
+require Parse;
+ 
+use strict;
+use Carp;
+use Exporter ();
+
+use vars qw(@ISA $Verbose);
+
+#
+# Verbose off by default
+#
+$Verbose = 0;
+
+@ISA = qw(Exporter PDF::Core PDF::Parse);
+
+1;
+
+__END__
+
+=head1 NAME
+
+PDF - Library for PDF access and manipulation in Perl
+
+=head1 SYNOPSIS
+
+  use PDF;
+
+  $pdf=PDF->new ;
+  $pdf=PDF->new(filename);
+
+  $result=$pdf->TargetFile( filename );
+
+  print "is a pdf file\n" if ( $pdf->IsaPDF ) ;
+  print "Has ",$pdf->Pages," Pages \n";
+  print "Use a PDF Version  ",$pdf->Version ," \n";
+  print "and it is crypted  " if ( $pdf->IscryptedPDF) ;
+
+  print "filename with title",$pdf->GetInfo("Title"),"\n";
+  print "and with subject ",$pdf->GetInfo("Subject"),"\n";
+  print "was written by ",$pdf->GetInfo("Author"),"\n";
+  print "in date ",$pdf->GetInfo("CreationDate"),"\n";
+  print "using ",$pdf->GetInfo("Creator"),"\n";
+  print "and converted with ",$pdf->GetInfo("Producer"),"\n";
+  print "The last modification occurred ",$pdf->GetInfo("ModDate"),"\n";
+  print "The associated keywords are ",$pdf->GetInfo("Keywords"),"\n";
+
+  my (startx,starty, endx,endy) = $pdf->PageSize ($page) ;
+
+=head1 DESCRIPTION
+
+The main purpose of the PDF library is to provide classes and
+functions that allow to read and manipulate PDF files with perl. PDF
+stands for Portable Document Format and is a format proposed by Adobe.
+A full description of this format can be found in the B<Portable
+Document Reference Manual> by B<Adobe Systems Inc.>. For more details
+about PDF, refer to:
+
+B<http://www.adobe.com/>
+
+The main idea is to provide some "basic" modules for access 
+the information contained in a PDF file. Even if at this
+moment is in an early development stage, the scripts in the 
+example directory show that it is usable. 
+
+B<is_pdf> script test a list of files in order divide the PDF file
+from the non PDF using the info provided by the files 
+themselves. It doesn't use the I<.pdf> extension, it uses the information
+contained in the file.
+
+B<pdf_version> returns the PDF level used for writing a file.
+
+B<pdf_pages> gives the number of pages of a PDF file. 
+
+B<pagedump.pl> prints some information about individual pages in a
+PDF-file. Although the information as such are not very useful, it
+demontrates well some more complex aspects of the library. Check the
+function B<doprint> in this program on how to handle all possible data
+occuring in a PDF.
+
+The library is now splitted in 2 section :
+
+B<PDF::Core> that contains the data structure, the constructor and low
+level access fuctions;
+
+B<PDF::Parse> all kind of functions to parse the PDF-files and
+provide information about the content.
+
+Check the help-files of these modules for more details.
+
+=head1 Variables
+
+There are 2 variables that can be accessed:
+
+=over 4
+
+`=item B<$PDF::VERSION>
+
+Contain the version of the library installed.
+
+=item B<$PDF::Verbose>
+
+This variable is false by default. Change the value if you want 
+more verbose output messages from library.
+
+=back 4
+
+=head1 Copyright
+
+  Copyright (c) 1998 - 2000 Antonio Rosella Italy antro@tiscalinet.it, Johannes Blach dw235@yahoo.com 
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 Availability
+
+The latest version of this library is likely to be available from:
+
+http://www.geocities.com/CapeCanaveral/Hangar/4794/
+
+and at any CPAN mirror
+
+=head1 Greetings
+
+Fabrizio Pivari ( pivari@geocities.com ) for all the suggestions about life, the universe and everything.
+Brad Appleton ( bradapp@enteract.com ) for his suggestions about the module organization.
+Thomas Drillich for the iso latin1 support 
+Ross Moore ( ross@ics.mq.edu.au ) for ReadInfo fix
+
+=cut
+
+
+
+
+
+
+
Index: /gsdl/stable/bin/script/indexes/Parse.pm
===================================================================
--- /gsdl/stable/bin/script/indexes/Parse.pm	(revision 20131)
+++ /gsdl/stable/bin/script/indexes/Parse.pm	(revision 20131)
@@ -0,0 +1,513 @@
+#
+# PDF::Parse.pm, version 1.11 February 2000 antro
+#
+# Copyright (c) 1998 - 2000 Antonio Rosella Italy antro@tiscalinet.it, Johannes Blach dw235@yahoo.com 
+#
+# Free usage under the same Perl Licence condition.
+#
+
+package PDF::Parse;
+
+$PDF::Parse::VERSION = "1.11";
+
+=pod
+
+=head1 NAME
+
+PDF::Parse - Library with parsing functions for PDF library
+
+=head1 SYNOPSIS
+
+  use PDF::Parse;
+
+  $pdf->TargetFile($filename);
+  $pdf->LoadPageInfo;
+
+  $version = $pdf->Version;
+  $bool = $pdf->IsaPDF;
+  $bool = $pdf->IscryptPDF;
+
+  $info = $pdf->GetInfo ($key);
+  $pagenum = $pdf->Pages;
+
+  @size = $pdf->PageSize ($page);
+  # or
+  @size = $pdf->PageSize;
+
+  $rotation = $pdf->PageRotation ($page);
+  # or
+  $rotation = $pdf->PageRotation;
+
+=head1 DESCRIPTION
+
+The main purpose of the PDF::Parse library is to provide parsing functions
+for the more general PDF library.
+
+=head1 Methods
+
+The available methods are:
+
+=cut
+
+require 5.005;
+#require PDF::Core;
+require Core;
+
+use strict;
+use Carp;
+use Exporter ();
+
+use vars qw(@ISA @EXPORT_OK);
+
+@ISA = qw(Exporter PDF::Core);
+
+@EXPORT_OK = qw( LoadPageInfo GetInfo TargetFile
+				 Pages PageSize PageRotation IsaPDF
+				 Version IscryptPDF );
+
+#################################################################
+sub ReadCrossReference_pass1 {
+  my $fd = shift;
+  my $offset=shift;
+  my $self=shift;
+
+  my $initial_number;
+  my $obj_counter=0;
+  my $global_obj_counter=0;
+  my $buf;
+
+  binmode $fd;
+
+  $_=PDF::Core::PDFGetline ($fd,\$offset);
+
+  die "Can't read cross-reference section, according to trailer\n" if ! /xref\r?\n?/  ;
+
+  while () {
+    $_=PDF::Core::PDFGetline ($fd,\$offset);
+    s/^\n//;
+    s/^\r//;
+    last if (m/\btrailer\b/) ;
+#
+# An Object
+#
+    /^\d+\s+\d+\s+n\r?\n?/ && do { my $buf =$_;
+	       my $ind = $initial_number + ($obj_counter++);
+               ( not defined $self->{Objects}[$ind] )&& 
+		  do { $self->{Objects}[$ind] = int substr($buf,0,10);
+		       $self->{Gen_Num}[$ind] = int substr($buf,11,5);
+		     };
+	       $_=$buf;
+	       s/^.{18}//; 
+	       next ;
+   }; 
+#
+# A Freed Object
+#
+    /^\d+\s+\d+\s+f\r?\n?/ && do { my $buf =$_;
+   	       my $objects_generation_nr = substr($buf,11,5);
+	       my $Num=substr($buf,0,10);
+	       my $ind = $initial_number + ($obj_counter++);
+	       # $ind = $ind . "_" . $objects_generation_nr;
+		       $self->{Objects}[$ind] = - $Num;
+		       $self->{Gen_Num}[$ind] = $objects_generation_nr;
+		       $_=$buf;
+		       s/^.{18}//; 
+		       next ;
+     };
+#
+# A subsection
+#
+    /^\d+\s+\d+\r?\n?/  && do { 
+ 	my $buf = $_ ; 
+ 	 $initial_number = $buf; 
+ 	 $initial_number=~ s/^(\d+)\s+\d+\r?\n?.*/$1/; 
+	 $global_obj_counter += $obj_counter;
+ 	 $obj_counter=0; 
+	 next ;
+    };
+  }
+
+  $global_obj_counter +=$obj_counter;
+#
+# Now the trailer for updates 
+#
+
+#
+# Skip to start of dictionary.
+#
+    until (m/<</)
+		{
+		$_=PDF::Core::PDFGetline ($fd,\$offset);
+		}
+
+#
+# Read the dictionary
+#
+    my %trailer = ( PDF::Core::PDFGetPrimitive ($fd, $offset) );
+
+    if ($self->{"Trailer"}{"/Root"} eq "")
+		{
+		$self->{"Trailer"} = \%trailer;
+		#
+		# This code is here for backward compatibility only. If the content
+		# of the root trailer is needed, use $self->{"Trailer"} instead.
+		#
+		$self->{"Cross_Reference_Size"} = $trailer{"/Size"};
+		$self->{"Root_Object"} = $trailer{"/Root"};
+		$self->{"Crypt_Object"} = $trailer{"/Encrypt"};
+		}
+	if ($trailer{"/Prev"} =~ m/^\d+$/)
+		{  
+  		$self->{"Updated"} = 1;
+		my $old_seek = tell $fd;
+		$global_obj_counter += ReadCrossReference_pass1 ($fd,
+            $trailer{"/Prev"}, $self );
+		seek $fd, $old_seek, 0;
+		}
+
+
+  return $global_obj_counter;
+}
+
+#################################################################
+sub LoadPageSubtree (\*$;%)
+	{
+	my $self = shift;
+	my $ref = shift;
+	my %inheritance = @_ ;
+
+	my $data = $self->GetObject ($ref);
+
+	# Check which attributes are inherited. Adobe did not add any new
+	# inherited attributes in version 1.2 or later, so this list is
+	# complete.
+
+	# Do simple values.
+	foreach my $key ("/Rotate", "/Dur", "/Hid", "/Trans", 
+			 "/MediaBox", "/CropBox") {
+
+	    if (defined ($data->{$key})){
+
+		# Check if it is an indirect reference
+		if ($data->{$key} =~ m/^\d+ \d+ R$/) {
+		    
+		    my $dataref = $data->{$key};
+
+		    do {
+
+			$dataref = $self->GetObject ($dataref);
+
+		    } while ($dataref =~ m/^\d+ \d+ R$/);
+
+		    if (UNIVERSAL::isa ($data, "ARRAY")){
+
+			$inheritance{$key} = [];
+
+			foreach my $i (@{$data}){
+			    # Each element may be a reference.
+			    while ($i =~ m/^\d+ \d+ R$/){
+				$i = $self->GetObject ($i);
+			    }
+			    
+			    push @{$inheritance{$key}}, $i;
+			}
+		    } else {
+			$inheritance{$key} = $dataref;
+		    }
+		} else { #not an indirect reference
+		    $inheritance{$key} = $data->{$key};
+		}
+	    }
+	}
+	
+	# If this objects contains ressources, replace information in inheritance
+	$inheritance{"Resource_Object"} = $data->{"/Resources"}
+	    if (defined ($data->{"/Resources"}));
+
+	if ($data->{"/Type"} eq "/Pages")
+		{
+		# It's just an intermediate Node
+		foreach my $kid (@{$data->{"/Kids"}})
+			{
+			$self->LoadPageSubtree ($kid, %inheritance);
+			}
+		}
+	elsif ($data->{"/Type"} eq "/Page")
+		{
+		# We have a real page!
+		$inheritance{"Page_Object"} = $ref;
+		push @{$self->{"Page"}}, +{ %inheritance };
+		}
+	else
+		{
+		# Strange stuff. Complain and discard.
+		carp "While loading pages got object of type '", $data->{"/Type"}, "'";
+		}
+	}
+
+#################################################################
+=pod
+
+=head2 TargetFile ( filename )
+
+This method links the filename to the pdf descriptor and parses all
+kind of header information.
+
+=cut
+
+sub TargetFile {
+  my $self = shift;
+  my $file = shift;
+
+  croak "Already linked to the file ",$self->{File_Name},"\n" 
+      if $self->{File_Name} ;
+  
+  my $offset;
+
+  if ( $file ) {
+    open(FILE, "< $file") or croak "can't open $file: $!";
+    binmode FILE;
+    $self->{File_Name} = $file ;
+    $self->{File_Handler} = \*FILE;
+    my $buf;
+    read(FILE,$buf,4);
+    if ( $buf ne "%PDF" ) {
+     print "File $_[0] is not PDF compliant !\n" if $PDF::Verbose ;
+     return 0 ;
+    }
+    read(FILE,$buf,4);
+    $buf =~ s/-//;
+    $self->{Header}= $buf;
+    seek FILE,-50,2;
+    read( FILE, $offset, 50 );
+    $offset =~ s/[^s]*startxref\r?\n?(\d*)\r?\n?%%EOF\r?\n?/$1/;
+
+	$self->{"Last_XRef_Offset"} = $offset;
+    ReadCrossReference_pass1 (\*FILE, $offset, $self);
+	$self->{"Info"} = $self->GetObject ($self->{"Trailer"}{"/Info"});
+	$self->{"Catalog"} = $self->GetObject ($self->{"Trailer"}{"/Root"});
+	$self->{"PageTree"} = $self->GetObject ($self->{"Catalog"}{"/Pages"});
+    return 1;
+  } else {
+    croak "I need a file name (!)";
+	}
+}
+
+#################################################################
+=pod
+
+=head2 LoadPageInfo
+
+This function loads the information for all pages. This process can
+take some time for big PDF-files.
+
+=cut
+
+sub LoadPageInfo (\*)
+	{
+	my $self = shift;
+
+	# Reset Page Array
+	$#{$self->{"Page"}} = -1;
+
+	# Recurse
+	$self->LoadPageSubtree ($self->{"Catalog"}{"/Pages"});
+	}								
+
+
+
+#################################################################
+=pod
+
+=head2 Version
+
+Returns the PDF version used for writing the object file.
+
+=cut
+
+sub Version { 
+  return ($_[0]->{Header}); 
+}
+
+#################################################################
+=pod
+
+=head2 IsaPDF
+
+Returns true, if the file could be parsed and is a PDF-file.
+
+=cut
+
+sub IsaPDF { 
+  return ($_[0]->{Header} != undef) ; 
+}
+
+#################################################################
+=pod
+
+=head2 IscryptPDF
+
+Returns true if the PDF contains a crypt object. This indicates that
+the data of the PDF-File is encrypted. In this case, not all function
+work as expected.
+
+=cut
+
+sub IscryptPDF { 
+  return ($_[0]->{Crypt_Object} != undef) ; 
+}
+
+#################################################################
+=pod
+
+=head2 GetInfo ( key )
+
+Returns the various information contained in the info section of a PDF
+file (if present). A PDF file can have:
+
+  a title ==> GetInfo ("Title")
+  a subject ==> GetInfo ("Subject")
+  an author ==> GetInfo("Author")
+  a creation date ==> GetInfo("CreationDate")
+  a creator ==> GetInfo("Creator")
+  a producer ==> GetInfo("Producer")
+  a modification date ==> GetInfo("ModDate")
+  some keywords ==> GetInfo("Keywords")
+
+=cut
+
+sub GetInfo (\*$)
+	{
+	my $self = shift;
+	my $type = shift;
+
+	return PDF::Core::UnQuoteString ($self->{"Info"}{"/" . $type})
+	}
+
+#################################################################
+=pod
+
+=head2 Pages
+
+Returns the number of pages of the PDF-file.
+
+=cut
+
+sub Pages 
+	{
+	my $self = shift;
+
+	return $self->{"PageTree"}{"/Count"};
+	}
+
+
+
+#################################################################
+=pod
+
+=head2 PageSize ( [ page ] )
+
+Returns the size of a page in the PDF-file. If no parameter is given,
+the default size of the root page will be returned. This value may be
+overridden for any page.
+
+If the size of an individual page is requested and the page data is
+not already loaded, the method B<LoadPageInfo> will be executed. This
+may take some time for large PDF-files. The size of the root page is
+always available and will never execute B<LoadPageInfo>.
+
+=cut
+
+sub PageSize (;$)
+	{
+	my $self = shift;
+	my $page = shift;
+
+	if ($page > 0)
+		{
+		return undef if ($page > $self->{"PageTree"}{"/Count"});
+		$self->LoadPageInfo unless ($#{$self->{"Page"}} >= 0);
+		
+		return @{$self->{"Page"}[$page - 1]{"/MediaBox"}}
+		if (defined $self->{"Page"}[$page - 1]{"/MediaBox"});
+		}
+	else
+		{
+		return @{$self->{"PageTree"}{"/MediaBox"}}
+		if (defined $self->{"PageTree"}{"/MediaBox"});
+		}
+
+	return undef;
+	}
+
+
+#################################################################
+=pod
+
+=head2 PageRotation ( [ page ] )
+
+Returns the rotation of a page in the PDF-file. If no parameter is given,
+the default rotation of the root page will be returned. This value may be
+overridden for any page.
+
+If the rotation of an individual page is requested and the page data is
+not already loaded, the method B<LoadPageInfo> will be executed. This
+may take some time for large PDF-files. The rotation of the root page is
+always available and will never execute B<LoadPageInfo>.
+
+=cut
+sub PageRotation (;$)
+	{
+	my $self = shift;
+	my $page = shift;
+
+	my $rotate = 0;
+
+	if ($page > 0)
+		{
+		return undef if ($page > $self->{"PageTree"}{"/Count"});
+		$self->LoadPageInfo unless ($#{$self->{"Page"}} >= 0);
+		
+		$rotate = $self->{"Page"}[$page - 1]{"/Rotate"};
+		}
+	else
+		{
+		$rotate = $self->{"PageTree"}{"/Rotate"};
+		}
+
+	print "Rotation ", 0 + $rotate if ($PDF::Verbose);
+
+	return 0 + $rotate;
+	}
+#################################################################
+1;
+__END__
+
+=head1 Variables
+
+The only available variable is :
+
+=over
+
+=item B<$PDF::Parse::VERSION>
+
+Contains the version of the library installed
+
+=back
+
+
+=head1 Copyright
+
+  Copyright (c) 1998 - 2000 Antonio Rosella Italy antro@tiscalinet.it, Johannes Blach dw235@yahoo.com 
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 Availability
+
+The latest version of this library is likely to be available from:
+
+http://www.geocities.com/CapeCanaveral/Hangar/4794/
+
+=cut
+
Index: /gsdl/stable/bin/script/indexes/amend_pdf.pl
===================================================================
--- /gsdl/stable/bin/script/indexes/amend_pdf.pl	(revision 20131)
+++ /gsdl/stable/bin/script/indexes/amend_pdf.pl	(revision 20131)
@@ -0,0 +1,682 @@
+#!/usr/bin/perl
+#Jessica Thurston
+#usage: perl amend_pdf.pl filename
+#This program takes a pdf file 'filename'
+#and modifys it to include outline entries
+#(bookmarks).  
+#This is achieved using a pdf library which
+#parses the pdf file into objects allowing 
+#this script to more easily manipulate the pdf
+#objects and then modify the file by means
+#of incremental updates. (modifys the necessary
+#pdf objects and appends them to the end of 
+#the file, then updates the xreference table and
+#trailer). This library can be downloaded at
+# http://www.sanface.com/PDF-lib/
+#A file url.txt stored in the same
+#directory is read containing two columns of data:
+#title of related pdf document     url of related pdf document
+#The pdf document is modified so that the title of the
+#related pdf documents are displayed as bookmarks and
+#when the user clicks on it the web browser opens at
+#the url stored in the same column of url.txt.
+#
+#This program was designed to be used with the Greenstone
+#digital library in the following ways:
+#-When a user has built a collection containing
+# pdf documents, they have a choice of either displaying
+# the page in the web browser in gml form or saving the
+# original pdf document to view in an acrobat pdf reader.
+#-The related document file url.txt can be downloaded
+# in the same way if the user has included in the format
+# string for that page (ie search list) in the collection 
+# configuration file [urllink] related documents [/urllink].  
+# This will create a html link 'related documents' which 
+# when clicked on will enable the user to save a file url.txt 
+# containing the related documents for that particular document. 
+#-This file has been written upon running the perl script
+# relationPDF.pl which will also amend the gml documents to 
+# include the 'urllink' information enabling the user to 
+# include the related document links in config file format 
+# strings.
+#-So once this related doc info has been included the user
+# can download both the pdf file (doc.pdf) and the related
+# document file for that particluar document (url.txt).
+#-perl amend_pdf.pl doc.pdf is then run in the command line
+# modifying the pdf document to the desired effect.  
+#bugs:
+#-cannot be run more than once on the same file
+#-doesn't make use of free objects (free objects
+# are quite unlikely though, I didn't come across
+# any while looking through pdfs)
+#-many other things I haven't bothered testing
+
+use Carp;
+use Getopt::Long;
+use PDF;
+
+$objects = 0;
+$offsets = 1;
+
+
+#for each command line argument add the outlines
+#contained in url.txt
+#foreach (@ARGV) {
+#    create_outlines($_); 
+#}
+
+if(defined $ARGV[0]){
+    $pdf_document = $ARGV[0];
+} else {
+    print STDERR "You must supply pdf document filename\n";
+    return;
+}
+if(defined $ARGV[1]){
+    $related_docs = $ARGV[1];
+} else {
+print STDERR "You must supply related document filename\n";
+return;
+}
+create_outlines($pdf_document); 
+
+exit(1);
+
+
+#this function first checks to see is the file is indeed
+#a pdf file - if not then exits. If it is a pdf then it
+#checks to see if it is encrypted. If it is then exits.
+#Next we check if the outlines dictionary exists in the
+#document catalog. 
+#-If the outline entry exists but there are no actual outlines
+# present then call add_outlines but pass on the existing
+# outline dictionary.
+#-otherwise call modify_outlines to modify the existing outline
+# structure to include new outlines.
+#If outlines dictionary doesn't exist call add_outlines.
+sub create_outlines {
+
+  my $filename = shift;
+
+  #parse pdf filename
+  my @filelist = split("/", $filename);
+  my $file = pop @filelist;
+
+  print STDERR "pdf file to be manipulated: $file\n";
+  print STDERR "pdf file to be saved: tmp_$file\n";
+
+  #make a copy of that file in this directory
+  print STDERR "cp $filename $file\n"; 
+  `cp $filename $file\n`; 
+  `cp $filename tmp_$file\n`; 
+
+  #create and parse a new 'pdf' object
+  my $PDFfile = PDF->new($file);  
+
+  #if it is a pdf file
+  if ($PDFfile->{"Header"}){
+
+      if($PDFfile->IscryptPDF){
+	  #an encrypted file so cannot continue with
+	  #adding the related doc outlines to it 
+	  print STDERR "file \"$file\" is encrypted \n"; 
+	  return;
+      }
+
+      #display some relevant information about the document
+      print STDERR "Author: ", $PDFfile->GetInfo ("Author"), "\n"; 
+      print STDERR "Title: ", $PDFfile->GetInfo ("Title"), "\n"; 
+      print STDERR "Subject: ", $PDFfile->GetInfo ("Subject"), "\n"; 
+      print STDERR "Updated: ", $PDFfile->{"Updated"}, "\n";
+     
+      #if the pdf document already includes an outline dictionary
+      if (defined $PDFfile->{"Catalog"}{"/Outlines"}) {
+
+	  #get the outline object from the indirect ref
+	  my $outline_data = $PDFfile->GetObject($PDFfile->{"Catalog"}{"/Outlines"});
+	  #obtain the number of existing outlines
+	  $PDFfile->{"Outlines"}{"/Count"} = $outline_data->{"/Count"};
+	  print STDERR "number of existing outlines: $PDFfile->{\"Outlines\"}{\"/Count\"}\n";
+
+	  #this means that the pdf file had an outline dictionary but
+	  #did not actually include any outlines.
+	  if($PDFfile->{"Outlines"}{"/Count"} == 0){
+	      #obtain object number of outline dictionary and pass to add_outlines
+	      my $dictionary = split(/\s/, $PDFfile->{"Catalog"}{"/Outlines"});
+	     
+	      add_outlines($PDFfile, $file, $dictionary);
+	  } else { 
+	      #collect other outline data to pass to modify_outlines
+	      $PDFfile->{"Outlines"}{"/First"} = $outline_data->{"/First"};
+	      $PDFfile->{"Outlines"}{"/Last"} = $outline_data->{"/Last"};
+
+	      #modify last outline entry
+	      modify_outlines($outline_data, $PDFfile, $file);
+	  }
+      } else { #there was no outline dictionary thus no outlines so add some
+	  print STDERR "no bookmarks in \"$file\" \n"; 
+	  add_outlines($PDFfile, $file, 0);
+      }
+  } else { #the file was not a pdf file
+      print STDERR "$file is not a pdf file!!\n"; 
+  }
+
+
+  #copy back the file we modified and the saved copy 
+  my $copypath = join("/", @filelist);
+  print STDERR "cp $file $filename\n"; 
+  print STDERR "cp tmp_$file $copypath/tmp_$file\n"; 
+  `cp $file $filename\n`; 
+  `cp tmp_$file $copypath/tmp_$file\n`; 
+
+  #remove the copy of that file in this directory
+  #print STDERR "rm $file\n"; 
+  `rm $file\n`;  
+  `rm tmp_$file\n`; 
+}
+
+
+#add_outlines function recieves following params
+#PDF file information, filename of pdf file, outline dictionary
+#(if outline dict. is 0 that means it must be created).
+#First the function decides if we are to create new dictionary
+#or not. Next read in the url file. Open up the pdf document.
+#Modify the catalog so that it includes the outline dictionary
+#(this is done even if the catalog doesn't need modifying 
+# so that the objects in the objects/offset table will not
+# be all mucked up when it comes time to write the xreference
+# table)
+#Then append outline dictionary to end of file (either modified
+#or created). Then append the top heirarchy related document
+#outline.  Then the new file url bookmarks. Call  xref_table
+#to write new xreference table. Call trailer to write new trailer.
+
+#table[0][0] - document catalog
+#table[0][1] - document catalog offset
+#table[1][0] - outline dictionary
+#table[1][1] - outline dictionary offset
+#table[2][0] - related document outline
+#table[2][1] - related document outline offset
+#table[3][0] etc - url outlines, read from file
+#table[3][1] etc - url outlines offset, read from file
+
+sub add_outlines (*\$){
+    
+ my $PDFfile = shift; 
+ my $file = shift; 
+
+ my @table;
+ $table[1][$objects] = shift;
+
+ #read in file of url's
+ my @urls = read_file(); 
+ my $url_num = $#urls + 1;
+ 
+ #if outline dictionary was not present in catalog
+ if ($table[1][$objects] == 0){ #get new object number for new dictionary
+     $table[1][$objects] = $PDFfile->{"Trailer"}{"/Size"}; #outline dictionary to be created
+     $table[2][$objects] = $table[1][$objects] + 1; #related document outline
+ } else { #else get object number for related doc outline to be appended
+     $table[2][$objects] = $PDFfile->{"Trailer"}{"/Size"}; #related document outline
+ }
+ 
+ #open up pdf file for appending
+ open(FILE, ">> $file") or croak "can't open $file: $!"; 
+ binmode \*FILE;
+ 
+ #obtain object number and offset for the document catalog
+ $table[0][$objects] = split(/\s/, $PDFfile->{"Trailer"}{"/Root"});
+ $table[0][$offsets] = tell \*FILE;
+
+ #print the modified or original catalog back to the file (appended)
+ print FILE "$table[0][$objects] 0 obj
+";
+ print FILE "<<
+";
+ print FILE "/Pages $PDFfile->{\"Catalog\"}{\"/Pages\"}
+";
+ print FILE "/Outlines $table[1][$objects] 0 R
+"; #only line actually added
+ print FILE "/Type /Catalog
+";
+ print FILE "/DefaultGray $PDFfile->{\"Catalog\"}{\"/DefaultGray\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/DefaultGray"}));
+ print FILE "/DefaultRGB $PDFfile->{\"Catalog\"}{\"/DefaultRGB\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/DefaultRGB"}));
+ print FILE "/PageLabels $PDFfile->{\"Catalog\"}{\"/PageLabels\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/PageLabels"}));
+ print FILE "/Names $PDFfile->{\"Catalog\"}{\"/Names\"}
+" 
+     if (defined ($PDFfile->{"Catalog"}{"/Names"}));
+ print FILE "/Dests $PDFfile->{\"Catalog\"}{\"/Dests\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/Dests"}));
+ print FILE "/ViewerPreferences $PDFfile->{\"Catalog\"}{\"/ViewerPreferences\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/ViewerPreferences"}));
+ print FILE "/PageLayout $PDFfile->{\"Catalog\"}{\"/PageLayout\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/PageLayout"}));
+ print FILE "/PageMode $PDFfile->{\"Catalog\"}{\"/PageMode\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/PageMode"}));
+ print FILE "/Threads $PDFfile->{\"Catalog\"}{\"/Threads\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/Threads"}));
+ print FILE "/OpenAction $PDFfile->{\"Catalog\"}{\"/OpenAction\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/OpenAction"}));
+ print FILE "/URI $PDFfile->{\"Catalog\"}{\"/URI\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/URI"}));
+ print FILE "/Acroform $PDFfile->{\"Catalog\"}{\"/Acroform\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/Acroform"}));
+ print FILE "/StructTreeRoot $PDFfile->{\"Catalog\"}{\"/StructTreeRoot\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/StructTreeRoot"}));
+ print FILE "/SpiderInfo $PDFfile->{\"Catalog\"}{\"/SpiderInfo\"}
+"
+     if (defined ($PDFfile->{"Catalog"}{"/SpiderInfo"}));
+ print FILE ">>
+";
+ print FILE "endobj
+";
+ 
+ #obtain offset for outline dictionary
+ $table[1][$offsets] = tell \*FILE;
+
+ #append newly created outline dictionary
+ print FILE "$table[1][$objects] 0 obj
+";
+ print FILE "<<
+";
+ print FILE "/Type /Outlines
+";
+ print FILE "/Count ", $url_num + 1, "
+";
+ print FILE "/First $table[2][$objects] 0 R
+";
+ print FILE "/Last $table[2][$objects] 0 R
+";
+ print FILE ">>
+";
+ print FILE "endobj
+";
+
+
+ #get the related document outline object num and offset
+ my $obj = $table[2][$objects]; 
+ $table[2][$offsets] = tell \*FILE;
+
+ #append the top heirarchy related document outline to file 
+ print FILE "$table[2][$objects] 0 obj
+";
+ print FILE "<<
+";
+ print FILE "/Title (Related Documents)
+";
+ print FILE "/Parent $table[1][$objects] 0 R
+";
+ print FILE "/Count ", $url_num, "
+";
+ print FILE "/First ", $obj + 1, " 0 R
+";
+ print FILE "/Last ", $table[2][$objects] + $url_num, " 0 R
+";
+ print FILE ">>
+";
+ print FILE "endobj
+";
+
+ my $ind = 3;
+ $obj++;
+
+ 
+ #store the object nums and offsets of the new related document
+ #outlines and write them to the file (must be outline with
+ #an action eg go to specific url)
+ for $i ( 0 .. $#urls ) {
+     $table[$ind][$offsets] = tell \*FILE; 
+     $table[$ind][$objects] = $obj; 
+     print FILE "$obj 0 obj
+";
+     print FILE "<<
+";
+     print FILE "/Title ($urls[$i][0])
+"; 
+     print FILE "/Parent $table[2][$objects] 0 R
+";
+     print FILE "/Next ", $obj + 1, " 0 R
+" if (($obj + 1) <= ($table[2][$objects] + $url_num)); 
+     print FILE "/Prev ", $obj - 1, " 0 R
+" if(($obj - 1) != ($table[2][$objects]));
+     print FILE "/A << /Type /Action
+";
+     print FILE "/S /URI
+"; 
+     print FILE "/URI ($urls[$i][1])
+"; 
+     print FILE ">>
+";
+     print FILE ">>
+";
+     print FILE "endobj
+";
+     $obj++;
+     $ind++; 
+ }
+
+
+ #append new X-reference table 
+ my $xref_offset = tell \*FILE;
+ xref_table(\*FILE, $url_num, @table);
+
+ #print trailer 
+ trailer(\*FILE, $PDFfile, $obj); 
+ print FILE "$xref_offset
+";
+ print FILE "%%EOF
+"; 
+
+ #close FILE;
+}
+
+#modify_outlines function recieves following params
+#PDF file information, outline data, pdf filename
+#First the function obtains the object data for the
+#last outline entry. Next read in the url file. 
+#Open up the pdf document.Then append the modified 
+#outline dictionary to end of file. Next append the
+#modified last outline.  Then append the 
+#top heirarchy related document outline.  Then the 
+#new file url bookmarks. Call  xref_table
+#to write new xreference table. 
+#Call trailer to write new trailer.
+
+#table[0][0] - outline dictionary
+#table[0][1] - outline dictionary offset
+#table[1][0] - last outline
+#table[1][1] - last outline offset
+#table[2][0] - related document outline
+#table[2][1] - related document outline offset
+#table[3][0] etc - url outlines, read from file
+#table[3][1] etc - url outlines offset, read from file
+
+sub modify_outlines (*\$){
+
+    my ($outline_data, $PDFfile, $file) = @_;
+
+    #collect the data for the last outline (which must be modified)
+    $PDFfile->{"Outlines"}{"/Last"} = $outline_data->{"/Last"};
+    my $last_data = $PDFfile->GetObject($PDFfile->{"Outlines"}{"/Last"});  
+
+    #read in file of url's
+    my @urls = read_file(); 
+    my $url_num = $#urls + 1;
+ 
+    my @table;
+
+    #This number is the number to use for the next created object
+    #eg the related doc heirarchy
+    $table[2][$objects] = $PDFfile->{"Trailer"}{"/Size"};
+  
+    #open up the pdf file for appending
+    open(FILE, ">> $file") or croak "can't open $file: $!"; 
+    binmode \*FILE;
+    
+    #store the object number and offset of the outline dictionary
+    $table[0][$objects] = split(/\s/, $PDFfile->{"Catalog"}{"/Outlines"});
+    $table[0][$offsets] = tell \*FILE;
+   
+    #write the outline dictionary back to the file (appending)
+    print FILE "$table[0][$objects] 0 obj
+";
+    print FILE "<<
+";
+    print FILE "/Type /Outlines
+";
+    print FILE "/Count ", $PDFfile->{"Outlines"}{"/Count"} + 1, "
+"
+	if (defined ($PDFfile->{"Outlines"}{"/Count"}));
+    print FILE "/First $PDFfile->{\"Outlines\"}{\"/First\"}
+"
+	if (defined ($PDFfile->{"Outlines"}{"/First"}));
+    print FILE "/Last $table[2][$objects] 0 R
+";
+    print FILE ">>
+";
+    print FILE "endobj
+";
+    
+    #store the last outline entry object num and file offset
+    my @last_entry = split(/\s/, $PDFfile->{"Outlines"}{"/Last"});
+    $table[1][$objects] = $last_entry[0]; 
+    $table[1][$offsets] = tell \*FILE; 
+
+    #append modified last outline entry
+    print FILE "$table[1][$objects] 0 obj
+";
+    print FILE "<<
+";
+    print FILE "/Title $last_data->{\"/Title\"}
+";
+    print FILE "/Dest $last_data->{\"/Dest\"}
+" if(defined $last_data->{"/Dest"});
+    print FILE "/Parent $last_data->{\"/Parent\"}
+";
+    print FILE "/Prev $last_data->{\"/Prev\"}
+";
+    print FILE "/Next $table[2][$objects] 0 R
+";
+    print FILE "/First $last_data->{\"/First\"}
+" if(defined $last_data->{"/First"});
+    print FILE "/Last $last_data->{\"/Last\"}
+" if(defined $last_data->{"/Last"});
+    print FILE "/Count $last_data->{\"/Count\"}
+"if(defined $last_data->{"/Count"});
+    print FILE "/A $last_data->{\"/A\"}
+" if(defined $last_data->{"/A"});
+    print FILE "/SE $last_data->{\"/SE\"}
+" if(defined $last_data->{"/SE"});
+    print FILE ">>
+";
+    print FILE "endobj
+";
+    
+    #store the object num and offset of the related
+    #document top level outline
+    my $obj = $table[2][$objects] + 1;
+    $table[2][$offsets] = tell \*FILE;
+
+    #append related document top level outline
+    print FILE "$table[2][$objects] 0 obj
+";
+    print FILE "<<
+";
+    print FILE "/Title (Related Documents)
+"; 
+    print FILE "/Parent $last_data->{\"/Parent\"}
+";
+    print FILE "/Count ", $url_num, "
+";
+    print FILE "/First $obj 0 R
+";
+    print FILE "/Last ", $table[2][$objects] + $url_num , " 0 R
+";
+    print FILE ">>
+";
+    print FILE "endobj
+";
+    
+   
+    my $ind = 3;
+
+    #store the object nums and offsets of the new related document
+    #outlines and write them to the file (must be outline with
+    #an action eg go to specific url)
+    for $i ( 0 .. $#urls ) { 
+	$table[$ind][$objects] = $obj;  
+	$table[$ind][$offsets] = tell \*FILE; 
+	print FILE "$obj 0 obj
+";
+	print FILE "<<
+";
+	print FILE "/Title ($urls[$i][0])
+"; 
+	print FILE "/Parent $table[2][$objects] 0 R
+";
+	print FILE "/Next ", $obj + 1, " 0 R
+" if (($obj + 1) <= ($table[2][$objects] + $url_num)); 
+	print FILE "/Prev ", $obj - 1, " 0 R
+" if (($obj - 1) != ($table[2][$objects]));
+	print FILE "/A << /Type /Action
+";
+	print FILE "/S /URI
+"; 
+	print FILE "/URI ($urls[$i][1])
+"; 
+	print FILE ">>
+";
+	print FILE ">>
+";
+	print FILE "endobj
+";
+	$obj++;
+	$ind++;
+    }
+    
+    #append new X-reference table
+    my $xref_offset = tell \*FILE;   
+    xref_table(\*FILE, $url_num, @table); 
+  
+    #print trailer  
+    trailer(\*FILE, $PDFfile, $obj);
+    print FILE "$xref_offset
+";
+    print FILE "%%EOF
+"; 
+
+    close FILE;
+
+}
+
+
+#This function reads a file 'url.txt' which contains
+#two columns of data in the following format:
+#related document title    related document url
+#each array of title, url is stored in an array
+#(to obtain the title of the first related  
+#document in the file)
+#eg table[1st related document][title] 
+#(to obtain the url of the second related 
+#document in the file)
+#eg table[2nd related document][url]
+#this table is then returned to the calling 
+#function.
+sub read_file {
+
+    #create two-dimensional array for urls
+    my @urls;
+
+    #open up url.txt to start reading
+    open(URL, "$related_docs") or croak "Can't open $related_docs: $!"; 
+
+    my $counter = 0;
+
+    #read in url.txt and store into the arry
+    while (<URL>){
+	chomp;
+	if(/([^\t]*)\t(.*)/){ 
+	    push @urls, [ split ]; #split on /s into arrays of arrays
+	}
+    }
+
+    close URL;
+
+    return (@urls);
+
+}
+
+ 
+#this function takes as parameters the filehandle
+#to the pdf document, the number of related documents
+#to this pdf doc and a table of object numbers and
+#their offsets. Using this information it writes
+#(appends) a new xreference table to the pdf 
+#document. 
+
+sub xref_table  (*\$) {
+    
+    my ($fd, $num, @table) = @_;
+    my $offset;
+
+    #print the new xref table (append to file)
+    print $fd "xref
+";
+    print $fd "0 1 
+";
+    print $fd "0000000000 65535 f 
+";
+    print $fd "$table[0][$objects] 1 
+";
+    $offset = '0'x(10-length($table[0][$offsets])).$table[0][$offsets];
+    print $fd "$offset 00000 n 
+";
+    print $fd "$table[1][$objects] 1 
+"; 
+    $offset = '0'x(10-length($table[1][$offsets])).$table[1][$offsets];
+    print $fd "$offset 00000 n 
+";
+    print $fd "$table[2][$objects] ", $num + 1, " 
+"; 
+    for $i ( 2 .. ($num + 2) ) { #add 2 on because already written 2 to file
+	$offset = '0'x(10-length($table[$i][$offsets])).$table[$i][$offsets];
+	print $fd "$offset 00000 n 
+";
+    }
+    
+}
+
+
+#This function recieves as parameters the filehandle
+#to the pdf document, parsed information about the
+#document and the new size (last object number + 1)
+#of the pdf file.  Using this information it appends
+#a new trailer to the end of the pdf document.
+
+sub trailer  (*\$) {
+
+    my ($fd, $PDFfile, $new_size) = @_;
+
+    #append the new trailer to the end of the file
+    print $fd "trailer
+";
+    print $fd "<<
+";
+    print $fd "/Size ", $new_size, "
+";
+    print $fd "/Root $PDFfile->{\"Trailer\"}{\"/Root\"}
+";
+    print $fd "/Info $PDFfile->{\"Trailer\"}{\"/Info\"}
+" 
+	if (defined ($PDFfile->{"Trailer"}{"/Info"}));
+    print $fd "/ID [$PDFfile->{\"Trailer\"}{\"/ID\"}[0]$PDFfile->{\"Trailer\"}{\"/ID\"}[1]]
+"
+	if (defined ($PDFfile->{"Trailer"}{"/ID"}));
+    print $fd "/Prev $PDFfile->{\"Last_XRef_Offset\"}
+";
+    print $fd "/Encrypt $PDFfile->{\"Trailer\"}{\"/Encrypt\"}
+"
+	if (defined ($PDFfile->{"Trailer"}{"/Encrypt"}));
+    print $fd ">>
+";
+    print $fd "startxref
+";
+   
+}
+
+
+
Index: /gsdl/stable/bin/script/indexes/buildkpi.pl
===================================================================
--- /gsdl/stable/bin/script/indexes/buildkpi.pl	(revision 20131)
+++ /gsdl/stable/bin/script/indexes/buildkpi.pl	(revision 20131)
@@ -0,0 +1,491 @@
+#! /user/bin/perl 
+
+#usage: perl buildkpi.pl [-R] [collection] [collection] etc
+#
+#-r or -R will remove previous index files so that you may build new ones
+#
+#The program performs the following tasks:
+#-gathers the specified collections on the command line OR
+#-gathers the directories of all the collections in the collect directory, this is all
+# the directories apart from CVS, modelcol, . and .. which are not collections.
+#-It then retrieves the archive.inf file from the archive directory of each collection
+# to obtain the unique file ID and filepath of every document in the collection
+#-Then parse through each doc.gml stored in filepath to gather information
+#-From each file collect kea phrases and/or stems
+#-Determine the number of kea phrases and stems for each document 
+#-Search for the kea phrases in the numbered phrase index. If a phrase is not there then 
+# the program will write the kea phrase to the phrase index . 
+#-Search for the kea phrases in the keyphrase to document index. If the phrase is there, 
+# it will increment the number of documents that the keyphrase appears in and replace that
+# then append the hash ID to the list of documents in the entry. If the phrase is not there 
+# then the program will write the kea phrase to the phrase index.
+#-Then write document ID, no of phrase, phrase number from index followed by number of times 
+# phrase appears into the document_keyphrase index
+
+$gsdlhome = $ENV{'GSDLHOME'};
+
+require "getopts.pl";
+&Getopts('R'); #process option arguments
+
+
+#collections may be specified in the command line
+#otherwise, all collections will be used to build
+#the indexes.  
+if(@ARGV){
+
+    @directories = @ARGV;
+
+} else { #open collect directory and get a list of all collections
+    opendir(DIR, "$gsdlhome/collect");
+    @directories = grep(!/(^\.|(CVS)|(modelcol))/, readdir(DIR));
+    closedir(DIR);
+}
+
+
+#directory to store indexes in using collection names
+$dirname = "";
+foreach $collection (sort @directories){
+    $dirname .= $collection."_";
+}
+$dirname .= "indexes";
+print STDERR "directory name: $dirname\n";
+
+#if option R remove all previous indexes
+if($opt_R == 1){ #remove indexes
+    print STDERR "\nremoving $gsdlhome/bin/script/indexes/$dirname/keyphrase_index.txt\n";
+    print STDERR "removing $gsdlhome/bin/script/indexes/$dirname/keyphrase_document.txt\n";
+    print STDERR "removing $gsdlhome/bin/script/indexes/$dirname/document_keyphrase.txt\n";
+    system("rm $gsdlhome/bin/script/indexes/$dirname/keyphrase_document.txt");   
+    system("rm $gsdlhome/bin/script/indexes/$dirname/document_keyphrase.txt"); 
+    system("rm $gsdlhome/bin/script/indexes/$dirname/keyphrase_index.txt");
+} 
+
+#create the new directory, display an error message if the directory
+#already exists.
+`mkdir --verbose $gsdlhome/bin/script/indexes/$dirname`;
+
+#for each collection specified to build indexes for
+foreach $collection (@directories){
+
+    print STDERR "\nBUILDING INDEXES FOR COLLECTION $collection\n\n";
+
+    my @filelist;
+
+    #archives.inf contains a list of unique hash ID's of each file and file paths
+    open(INFO, "$gsdlhome/collect/$collection/archives/archives.inf")
+	or die "$gsdlhome/collect/$collection/archives/archives.inf could not be opened.";
+
+    while(<INFO>){ #get each line of text from archives.inf (OID \t filepath)
+	chomp;
+	push(@filelist, $_);
+    }
+
+    foreach $file (@filelist){ #add each document to the indexes
+	build_index($file, $collection);
+    }
+}
+
+#This function opens the file in the filepath sent as an argument.  From this it obtains 
+#the kea and/or stem data, and then searches for these phrases in the file, counting and storing 
+#how many times each phrase appears. The data is then sent to function keyphrase_document 
+#with arguments hash ID, kea phrases and stem phrases to build the keyphrase_document index.
+#The function which builds the document_keyphrase index is then passed the hash ID, the kea 
+#phrases and/or the stemmed phrases and the array/s which hold the number of times each phrase
+#appears in the document so that the data it has collected can be written to document_ keyphrase
+#index.
+
+sub build_index {
+
+    my $args = shift(@_);
+    my $collection = shift(@_);
+    my ($ID, $filepath) = split(/\t/, $args);
+    my $keaS = "";
+    my $stemsS = "";
+    my @kea_phrase_counts = 0;
+    my @stem_phrase_counts = 0;
+    my $text = "";
+
+    print STDERR "\nID: $ID\n";
+    print STDERR "filepath: $filepath\n";
+
+    #open file to extract keyphrase information
+    open(FILE, "$gsdlhome/collect/$collection/archives/$filepath")
+	or die "$gsdlhome/collect/$collection/archives/$filepath could not be opened.";
+
+    #patterns to search for so that we can extract the kea information
+    my $kea_search = ".* kea=\"([^\"]*)\"";
+    my $stem_search = "stems=\"([^\"]*)\"";
+
+    while(<FILE>){ #get kea and stem data and store
+	chomp;
+	$keaS = $1 if (/$kea_search/);
+	$stemsS = $1 if (/$stem_search/);
+    }
+
+    close(FILE);
+    
+    print STDERR "Kea: $keaS\n";
+    print STDERR "stems: $stemsS\n";
+
+    my @kea = split(", ", $keaS);
+    my @stems = split(", ", $stemsS);
+
+    if(@kea && @stems){ #if the data exists
+	
+	#open the filepath to the current document
+	open(FILE, "$gsdlhome/collect/$collection/archives/$filepath")
+	    or die "$gsdlhome/collect/$collection/archives/$filepath could not be opened.";
+	
+	while(<FILE>){ #get the text
+	    chomp;
+	    $text .= $_;
+	}
+ 
+	#chop out all things in angled brackets
+	$text =~ s/(<[^>]*>)//g;
+
+	#initilise counts
+	for($i=0; $i<=$#kea; $i++){
+	    $kea_phrase_counts[$i] = 0;
+	}
+	
+	for($i=0; $i<=$#stems; $i++){
+	    $stem_phrase_counts[$i] = 0;
+	}
+
+	print STDERR "counting number of kea phrases in document...\n";
+
+	#using regular expressions generated from kea-reg and stem-reg
+	#count how many of each phrase appear in the document
+	$text_copy = $text;
+	for($i=0; $i<=$#kea; $i++){ #search for text with kea phrases
+	    my $phrase = $kea[$i];
+	    $reg = &kea_reg(split(/\s+/, $phrase));
+	    while($text_copy =~ s/$reg//i){
+		$kea_phrase_counts[$i]++; #count the number of kea phrases 
+	    } 
+	    $text_copy = $text;
+	}  
+
+	print STDERR "counting number of stemmed phrases in document...\n";
+
+	$text_copy = $text;
+	for($i=0; $i<=$#stems; $i++){ #search for text with stem phrases
+	    my $stem = $stems[$i];
+	    $reg = &stem_reg(split(/\s+/, $stem));
+	    while($text_copy =~ s/$reg//i){
+		$stem_phrase_counts[$i]++; #count the number of stem phrases
+	    } 
+	    $text_copy = $text;
+	}
+
+	
+	#write data to keyphrase_document index
+	&keyphrase_document($ID, $keaS, $stemsS); 
+	
+	#write data to document_keyphrase index
+	$kea_counts = join(", ", @kea_phrase_counts);
+	$stem_counts = join(", ", @stem_phrase_counts);
+	&document_keyphrase($ID, $keaS, $stemsS, $kea_counts, $stem_counts);
+	
+    } else { 
+	print STDERR "No kea data was found in file $filepath\n";
+    }
+
+}
+
+#returns a regular expression designed to 
+#search for stems in text
+#eg 'agri cari'
+#    agri followed by 0 or more non-whitespace characters
+#         followed by one or more whitespace OR 0 or 1 non-whitespace characters
+#    cari followed by 0 or more non-whitespace characters
+#modified from original by Stephen Lundy 
+
+sub stem_reg {
+   
+    $regexp = "";
+
+    $l = @_;
+
+    if ($l > 0) {
+        $s = shift;
+        $regexp = "$s\\S*";
+
+        if ($l-1 > 0) {
+            foreach $s (@_) {
+                $regexp .= "(\\s+|\\S?)$s\\S*";
+            }
+        }
+    }
+
+    return $regexp;
+}
+
+#returns a regular expression designed to 
+#search for phrases in text
+#eg 'agris caris'
+#    agris followed by 0 or 1 non-whitespace characters OR
+#          followed by one or more whitespace 
+#    caris followed by 0 or 1 non-whitespace characters
+#modified from original by Stephen Lundy 
+
+sub kea_reg {
+    $regexp = "";
+
+    $l = @_;
+
+    if ($l > 0) {
+        $s = shift;
+        #$regexp = "$s(\\S?)";
+	$regexp = "$s(\\s+|\\S?)";
+
+        if ($l-1 > 0) {
+            foreach $s (@_) {
+                $regexp .= "$s(\\s+|\\S?)";
+            }
+        }
+    }
+
+    return $regexp;
+}
+
+
+#This function is passed as arguments a list of kea phrases and/or stems. Its purpose is to 
+#check in the keyphrase index file for each phrase and determine whether or not an entry has
+#been made for that phrase and an index number assigned to it. If there has not been an entry
+#made then an index number is assigned to the phrase and it is written to the file.  This 
+#function is called by document_keyphrase and keyphrase_document.  Each line in the file has
+#this form:
+#-phrase index number:phrase
+#This function then returns a table of pairs of the phrases that were sent as arguments to it
+#{phrase => phrase index number}.
+ 
+sub keyphrase_index_search {
+
+    my $phrases = shift(@_); 
+    my @phrases = split(", ", $phrases);
+    my %table;
+    my $index = 1;
+    my $create_new_index = 0;
+
+    print STDERR "searching keyphrase index...\n";
+
+    #initilise table of phrases and index numbers
+    foreach $phrase (@phrases){
+	$table{"$phrase"} = "0";
+    }
+
+    #open keyphrase index for appending data and for reading
+    open(INDEX_OUT, ">>$gsdlhome/bin/script/indexes/$dirname/keyphrase_index.txt");
+    open(INDEX_IN, "$gsdlhome/bin/script/indexes/$dirname/keyphrase_index.txt")
+	or $create_new_index = 1;
+
+    if($create_new_index == 0){
+	#if the index already exists read in the phrases
+	while(<INDEX_IN>){
+	    chomp;
+	    foreach $phrase (@phrases){
+		if(/(\d+):$phrase/){
+		    $index = $1;
+		    $table{"$phrase"} = "$index";
+		}
+	    }
+	    $index++; #new starting index (one + the last index)
+	}
+
+	close(INDEX_IN);
+
+    }
+
+    #add new phrases to the phrase index
+    foreach $phrase (keys %table){
+	if($table{"$phrase"} eq "0"){
+	    print INDEX_OUT "$index:$phrase\n";
+	    $table{"$phrase"} = "$index"; 
+	    $index++;
+	}
+    }
+
+    close(INDEX_OUT);
+    return %table;
+}
+
+#This function is passed as arguments file hash ID and a list of kea phrases and/or stems
+#that exist for that particular file.  Its purpose is to write to the keyphrase_document
+#index a line for the document it has been sent:
+#-phrase index number:number of documents it appears in|ID
+sub keyphrase_document{
+
+    my ($ID, $kea, $stems) = @_;
+    my $text = ""; 
+    my @textlist;
+    my $create_new_index = 0;
+
+    print STDERR "writing to keyphrase_document.txt...\n";
+
+    #get table of phrases and phrase indexes 
+    my %table = keyphrase_index_search($kea.", ".$stems); 
+    
+  
+    #open index for reading
+    open(INDEX_IN, "$gsdlhome/bin/script/indexes/$dirname/keyphrase_document.txt")
+	or $create_new_index = 1;
+
+    #read in document if file exists
+    if($create_new_index == 0){
+
+	while(<INDEX_IN>){
+	    $text .= $_;
+	}
+
+	close(INDEX_IN);
+
+	#split text into lines
+	@textlist = split(/\n/, $text);
+
+    } 
+
+    #open index for output
+    open(INDEX_OUT, ">$gsdlhome/bin/script/indexes/$dirname/keyphrase_document.txt");
+
+    if($create_new_index == 0){ #amend existing index
+	
+	foreach $line (@textlist){
+	    foreach $phrase (keys %table){
+		if($line =~ /(\d+):(\d+)(.*)/){ #all lines of this form
+		    $index = $1;
+		    if($table{"$phrase"} eq "$index") { #if phrase exists in index
+			$ids = $3; #get all doc IDs for that keyphrase
+			if($ids !~ /$ID/){ #if doc ID not already included
+			    $num_docs = $2;
+			    $num_docs++; #increment number of docs
+			    $line = "$index:$num_docs$3|$ID"; #line to append to index
+			    $table{"$phrase"} = "0"; 
+			}
+		    }
+		}
+	    }
+	    print INDEX_OUT "$line\n";
+	}
+    }
+
+    #add new phrases to the index
+    foreach $phrase (keys %table){ #write 'phrase index:1:file ID
+	if($table{"$phrase"} ne "0"){
+	    my $line = "$table{$phrase}:1:$ID";
+	    print INDEX_OUT "$line\n"; 
+	}
+    }
+
+    close(INDEX_OUT);
+
+}
+
+#This function is passed as arguments file hash ID and a list of kea phrases and/or stems
+#that exist for that particular file and a list of the number of times each kea and/or stem
+#phrase appear in that document.  Its purpose is to write to the document_keyphrase
+#index a line for the document it has been sent:
+#-file ID:number of phrases and/or stems appear in the document
+#      |pairs of 'phrase index,number of times the phrase appears in the document' 
+sub document_keyphrase {
+
+    my ($ID, $keaS, $stemsS, $kea_c, $stem_c) = @_;
+    my $text = "";
+    my @textlist;
+    my %phrases;
+    my $create_new_index = 0;
+
+    print STDERR "writing to document_keyphrase.txt...\n";
+
+    #split phrase counts into arrays
+    my @kea_counts = split(", ", $kea_c);
+    my @stem_counts = split(", ", $stem_c);
+  
+    #get table of phrases and phrase indexes
+    my %table = keyphrase_index_search($keaS.", ".$stemsS);
+
+    #split phrases into arrays
+    my @kea = split(", ", $keaS);
+    my @stems = split(", ", $stemsS);
+
+    #build new phrases dictionary
+    for($i=0; $i<=$#kea; $i++){
+	my $phrase = $table{"$kea[$i]"};
+	if($kea_counts[$i] > 0){
+	    $phrases{"$phrase"} = "$kea_counts[$i]";
+	} else {
+	    $phrases{"$phrase"} = 1;
+	}
+    } 
+    for($i=0; $i<=$#stems; $i++){
+	my $phrase = $table{"$stems[$i]"};
+	if($stem_counts[$i] > 0){
+	    $phrases{"$phrase"} = "$stem_counts[$i]";
+	} else {
+	    $phrases{"$phrase"} = 1;
+	}
+    }   
+    my @num = keys %phrases;
+    my $phrasenum = $#num + 1; #number of phrases in doc
+
+    #open index for reading
+    open(INDEX_IN, "$gsdlhome/bin/script/indexes/$dirname/document_keyphrase.txt")
+	or $create_new_index = 1;
+
+     
+    if($create_new_index == 0){ #index doesn't need to be created
+
+	while(<INDEX_IN>){
+	    $text .= $_;
+	}
+
+	close(INDEX_IN);
+	
+	#split text into lines
+	@textlist = split(/\n/, $text);
+
+    }  
+
+
+    #must write this line to the file
+    #document ID:num of phrases|phrase index, number of times phrases appears
+    my $newline = "$ID:$phrasenum";
+    foreach $phrase (keys %phrases){
+	$newline .= "|$phrase,$phrases{$phrase}";
+    }
+
+    #open index for output
+    open(INDEX_OUT, ">$gsdlhome/bin/script/indexes/$dirname/document_keyphrase.txt");
+
+    if($create_new_index == 1){ #create a new index
+
+	print INDEX_OUT "$newline\n";
+
+    } else {
+
+	#if ID is already in the file write line overtop incase
+	#someone has modified the file.  Otherwise add the line
+	#to the end of the file
+	my $found = 0;
+
+	foreach $line (@textlist){
+	    if($line =~ /([^:]+):(.*)/){ #all lines should follow this pattern
+		$id = $1;
+		if($ID eq $id){ #id is already in the file
+		    print INDEX_OUT "$newline\n"; #print line overtop
+		    $found = 1;
+		} else {
+		    print INDEX_OUT "$line\n"; #print old line out
+		}
+	    }
+	}
+
+	print INDEX_OUT "$newline\n" if ($found == 0); #append new line to end of file 
+
+    }
+
+    close(INDEX_OUT);
+
+}
+
Index: /gsdl/stable/bin/script/indexes/buildkpiK.pl
===================================================================
--- /gsdl/stable/bin/script/indexes/buildkpiK.pl	(revision 20131)
+++ /gsdl/stable/bin/script/indexes/buildkpiK.pl	(revision 20131)
@@ -0,0 +1,411 @@
+#! /user/bin/perl 
+
+#usage: perl buildkpiK.pl [-R] [collection] [collection] etc
+#
+#-r or -R will remove previous index files so that you may build new ones
+#
+#The program performs the following tasks:
+#-gathers the specified collections on the command line OR
+#-gathers the directories of all the collections in the collect directory, this is all
+# the directories apart from CVS, modelcol, . and .. which are not collections.
+#-It then retrieves the archive.inf file from the archive directory of each collection
+# to obtain the unique file ID and filepath of every document in the collection
+#-Then parse through each doc.gml stored in filepath to gather information
+#-From each file collect kea phrases. 
+#-Determine the number of kea phrases for each document 
+#-Search for the kea phrases in the numbered phrase index. If a phrase is not there then 
+# the program will write the kea phrase to the phrase index . 
+#-Search for the kea phrases in the keyphrase to document index. If the phrase is there, 
+# it will increment the number of documents that the keyphrase appears in and replace that
+# then append the hash ID to the list of documents in the entry. If the phrase is not there 
+# then the program will write the kea phrase to the phrase index.
+#-Then write document ID, no of phrase, phrase number from index followed by number of times 
+# phrase appears into the document_keyphrase index
+
+$gsdlhome = $ENV{'GSDLHOME'};
+$collection;
+
+require "getopts.pl";
+&Getopts('R'); #process option arguments
+
+#if option R remove all previous indexes
+if($opt_R == 1){ #remove indexes
+    print STDERR "\nremoving $gsdlhome/bin/script/indexes/keyphrase_index.txt\n";
+    print STDERR "removing $gsdlhome/bin/script/indexes/keyphrase_document.txt\n";
+    print STDERR "removing $gsdlhome/bin/script/indexes/document_keyphrase.txt\n";
+    system("rm $gsdlhome/bin/script/indexes/keyphrase_document.txt");   
+    system("rm $gsdlhome/bin/script/indexes/document_keyphrase.txt"); 
+    system("rm $gsdlhome/bin/script/indexes/keyphrase_index.txt");
+}
+
+#collections may be specified in the command line
+#otherwise, all collections will be used to build
+#the indexes.  
+if(@ARGV){
+
+    @directories = @ARGV;
+
+} else { #open collect directory and get a list of all collections
+    opendir(DIR, "$gsdlhome/collect");
+    @directories = grep(!/(^\.|(CVS)|(modelcol))/, readdir(DIR));
+    closedir(DIR);
+}
+
+#for each collection specified to build indexes for
+foreach $collection (@directories){
+
+    my @filelist;
+
+    #archives.inf contains a list of unique hash ID's of each file and file paths
+    open(INFO, "$gsdlhome/collect/$collection/archives/archives.inf")
+	or die "$gsdlhome/collect/$collection/archives/archives.inf could not be opened.";
+
+    while(<INFO>){ #get each line of text from archives.inf (OID \t filepath)
+	chomp;
+	push(@filelist, $_);
+    }
+
+    foreach $file (@filelist){ #add each document to the indexes
+	build_index($file, $collection);
+    }
+}
+
+#This function opens the file in the filepath sent as an argument.  From this it obtains 
+#the kea data, and then searches for these phrases in the file, counting and storing 
+#how many times each phrase appears. The data is then sent to function keyphrase_document 
+#with arguments hash ID, kea phrases to build the keyphrase_document index.
+#The function which builds the document_keyphrase index is then passed the hash ID, the kea 
+#phrases and the array/s which hold the number of times each phrase
+#appears in the document so that the data it has collected can be written to document_ keyphrase
+#index.
+
+sub build_index {
+
+    my $args = shift(@_);
+    my $collection = shift(@_);
+    my ($ID, $filepath) = split(/\t/, $args);
+    my $keaS = "";
+    my @kea_phrase_counts = 0;
+    my $text = "";
+
+    print STDERR "\nID: $ID\n";
+    print STDERR "filepath: $filepath\n";
+
+    #open file to extract keyphrase information
+    open(FILE, "$gsdlhome/collect/$collection/archives/$filepath")
+	or die "$gsdlhome/collect/$collection/archives/$filepath could not be opened.";
+
+    #patterns to search for so that we can extract the kea information
+    my $kea_search = ".* kea=\"([^\"]*)\"";
+
+    while(<FILE>){ #get kea and stem data and store
+	chomp;
+	$keaS = $1 if (/$kea_search/);
+    }
+
+    close(FILE);
+    
+    print STDERR "Kea: $keaS\n";
+
+    my @kea = split(", ", $keaS);
+
+    if(@kea){ #if the data exists
+	
+	#open the filepath to the current document
+	open(FILE, "$gsdlhome/collect/$collection/archives/$filepath")
+	    or die "$gsdlhome/collect/$collection/archives/$filepath could not be opened.";
+	
+	while(<FILE>){ #get the text
+	    chomp;
+	    $text .= $_;
+	}
+ 
+	#chop out all things in angled brackets
+	$text =~ s/(<[^>]*>)//g;
+
+	#initilise counts
+	for($i=0; $i<=$#kea; $i++){
+	    $kea_phrase_counts[$i] = 0;
+	}
+	
+	
+	#using regular expressions generated from kea-reg 
+	#count how many of each phrase appear in the document
+	$text_copy = $text;
+	for($i=0; $i<=$#kea; $i++){ #search for text with kea phrases
+	    my $phrase = $kea[$i];
+	    $reg = &kea_reg(split(/\s+/, $phrase));
+	    while($text_copy =~ s/$reg//i){
+		$kea_phrase_counts[$i]++; #count the number of kea phrases 
+	    } 
+	    $text_copy = $text;
+	}  
+	
+	#write data to keyphrase_document index
+	&keyphrase_document($ID, $keaS); 
+	
+	#write data to document_keyphrase index
+	$kea_counts = join(", ", @kea_phrase_counts);
+	&document_keyphrase($ID, $keaS, $kea_counts);
+	
+    } else { 
+	print STDERR "No kea data was found in file $filepath\n";
+    }
+
+}
+
+
+#returns a regular expression designed to 
+#search for phrases in text
+#eg 'agris caris'
+#    agris followed by 0 or 1 non-whitespace characters OR
+#          followed by one or more whitespace 
+#    caris followed by 0 or 1 non-whitespace characters
+#modified from original by Stephen Lundy 
+
+sub kea_reg {
+    $regexp = "";
+
+    $l = @_;
+
+    if ($l > 0) {
+        $s = shift;
+        #$regexp = "$s(\\S?)";
+	$regexp = "$s(\\s+|\\S?)";
+
+        if ($l-1 > 0) {
+            foreach $s (@_) {
+                $regexp .= "$s(\\s+|\\S?)";
+            }
+        }
+    }
+
+    return $regexp;
+}
+
+
+#This function is passed as arguments a list of kea phrases and/or stems. Its purpose is to 
+#check in the keyphrase index file for each phrase and determine whether or not an entry has
+#been made for that phrase and an index number assigned to it. If there has not been an entry
+#made then an index number is assigned to the phrase and it is written to the file.  This 
+#function is called by document_keyphrase and keyphrase_document.  Each line in the file has
+#this form:
+#-phrase index number:phrase
+#This function then returns a table of pairs of the phrases that were sent as arguments to it
+#{phrase => phrase index number}.
+ 
+sub keyphrase_index_search {
+
+    my $phrases = shift(@_);
+    my @phrases = split(", ", $phrases);
+    my %table;
+    my $index = 1;
+    my $create_new_index = 0;
+
+    print STDERR "searching keyphrase index...\n";
+
+    #initilise table of phrases and index numbers
+    foreach $phrase (@phrases){
+	$table{"$phrase"} = "0";
+    }
+
+    #open keyphrase index for appending data and for reading
+    open(INDEX_OUT, ">>$gsdlhome/bin/script/indexes/keyphrase_index.txt");
+    open(INDEX_IN, "$gsdlhome/bin/script/indexes/keyphrase_index.txt")
+	or $create_new_index = 1;
+
+    if($create_new_index == 0){
+	#if the index already exists read in the phrases
+	while(<INDEX_IN>){
+	    chomp;
+	    foreach $phrase (@phrases){
+		if(/(\d+):$phrase/){
+		    $index = $1;
+		    $table{"$phrase"} = "$index";
+		}
+	    }
+	    $index++; #new starting index (one + the last index)
+	}
+
+	close(INDEX_IN);
+
+    }
+
+    #add new phrases to the phrase index
+    foreach $phrase (keys %table){
+	if($table{"$phrase"} eq "0"){
+	    print INDEX_OUT "$index:$phrase\n";
+	    $table{"$phrase"} = "$index"; 
+	    $index++;
+	}
+    }
+
+    close(INDEX_OUT);
+    return %table;
+}
+
+#This function is passed as arguments file hash ID and a list of kea phrases
+#that exist for that particular file.  Its purpose is to write to the keyphrase_document
+#index a line for the document it has been sent:
+#-phrase index number:number of documents it appears in|ID
+sub keyphrase_document{
+
+    my ($ID, $kea) = @_;
+    my $text = ""; 
+    my @textlist;
+    my $create_new_index = 0;
+
+    print STDERR "writing to keyphrase_document.txt...\n";
+
+    #get table of phrases and phrase indexes 
+    my %table = keyphrase_index_search($kea); 
+    
+  
+    #open index for reading
+    open(INDEX_IN, "$gsdlhome/bin/script/indexes/keyphrase_document.txt")
+	or $create_new_index = 1;
+
+    #read in document if file exists
+    if($create_new_index == 0){
+
+	while(<INDEX_IN>){
+	    $text .= $_;
+	}
+
+	close(INDEX_IN);
+
+	#split text into lines
+	@textlist = split(/\n/, $text);
+
+    } 
+
+    #open index for output
+    open(INDEX_OUT, ">$gsdlhome/bin/script/indexes/keyphrase_document.txt");
+
+    if($create_new_index == 0){ #amend existing index
+	
+	foreach $line (@textlist){
+	    foreach $phrase (keys %table){
+		if($line =~ /(\d+):(\d+)(.*)/){ #all lines of this form
+		    $index = $1;
+		    if($table{"$phrase"} eq "$index") { #if phrase exists in index
+			$ids = $3; #get all doc IDs for that keyphrase
+			if($ids !~ /$ID/){ #if doc ID not already included
+			    $num_docs = $2;
+			    $num_docs++; #increment number of docs
+			    $line = "$index:$num_docs$3|$ID"; #line to append to index
+			    $table{"$phrase"} = "0"; 
+			}
+		    }
+		}
+	    }
+	    print INDEX_OUT "$line\n";
+	}
+    }
+
+    #add new phrases to the index
+    foreach $phrase (keys %table){ #write 'phrase index:1:file ID
+	if($table{"$phrase"} ne "0"){
+	    my $line = "$table{$phrase}:1:$ID";
+	    print INDEX_OUT "$line\n"; 
+	}
+    }
+
+    close(INDEX_OUT);
+
+}
+
+#This function is passed as arguments file hash ID and a list of kea phrases and/or stems
+#that exist for that particular file and a list of the number of times each kea and/or stem
+#phrase appear in that document.  Its purpose is to write to the document_keyphrase
+#index a line for the document it has been sent:
+#-file ID:number of phrases and/or stems appear in the document
+#      |pairs of 'phrase index,number of times the phrase appears in the document' 
+sub document_keyphrase {
+
+    my ($ID, $keaS, $kea_c) = @_;
+    my $text = "";
+    my @textlist;
+    my %phrases;
+    my $create_new_index = 0;
+
+    print STDERR "writing to document_keyphrase.txt...\n";
+
+    #split phrase counts into arrays
+    my @kea_counts = split(", ", $kea_c);
+  
+    #get table of phrases and phrase indexes
+    my %table = keyphrase_index_search($keaS);
+
+    #split phrases into arrays
+    my @kea = split(", ", $keaS);
+
+    #build new phrases dictionary
+    for($i=0; $i<=$#kea; $i++){
+	my $phrase = $table{"$kea[$i]"};
+	$phrases{"$phrase"} = "$kea_counts[$i]";
+    } 
+   
+    my @num = keys %phrases;
+    my $phrasenum = $#num + 1; #number of phrases in doc
+
+    #open index for reading
+    open(INDEX_IN, "$gsdlhome/bin/script/indexes/document_keyphrase.txt")
+	or $create_new_index = 1;
+
+     
+    if($create_new_index == 0){ #index doesn't need to be created
+
+	while(<INDEX_IN>){
+	    $text .= $_;
+	}
+
+	close(INDEX_IN);
+	
+	#split text into lines
+	@textlist = split(/\n/, $text);
+
+    }  
+
+
+    #must write this line to the file
+    #'document ID:num of phrases|phrase index, number of times phrases appears
+    my $newline = "$ID:$phrasenum";
+    foreach $phrase (keys %phrases){
+	$newline .= "|$phrase,$phrases{$phrase}";
+    }
+
+    #open index for output
+    open(INDEX_OUT, ">$gsdlhome/bin/script/indexes/document_keyphrase.txt");
+
+    if($create_new_index == 1){ #create a new index
+
+	print INDEX_OUT "$newline\n";
+
+    } else {
+
+	#if ID is already in the file write line overtop incase
+	#someone has modified the file.  Otherwise add the line
+	#to the end of the file
+	my $found = 0;
+
+	foreach $line (@textlist){
+	    if($line =~ /([^:]+):(.*)/){ #all lines should follow this pattern
+		$id = $1;
+		if($ID eq $id){ #id is already in the file
+		    print INDEX_OUT "$newline\n"; #print line overtop
+		    $found = 1;
+		} else {
+		    print INDEX_OUT "$line\n"; #print old line out
+		}
+	    }
+	}
+
+	print INDEX_OUT "$newline\n" if ($found == 0); #append new line to end of file 
+
+    }
+
+    close(INDEX_OUT);
+
+}
+
Index: /gsdl/stable/bin/script/indexes/buildkpiS.pl
===================================================================
--- /gsdl/stable/bin/script/indexes/buildkpiS.pl	(revision 20131)
+++ /gsdl/stable/bin/script/indexes/buildkpiS.pl	(revision 20131)
@@ -0,0 +1,420 @@
+#! /user/bin/perl 
+
+#usage: perl buildkpiS.pl [-R] [collection] [collection] etc
+#
+#-r or -R will remove previous index files so that you may build new ones
+#
+#The program performs the following tasks:
+#-gathers the specified collections on the command line OR
+#-gathers the directories of all the collections in the collect directory, this is all
+# the directories apart from CVS, modelcol, . and .. which are not collections.
+#-It then retrieves the archive.inf file from the archive directory of each collection
+# to obtain the unique file ID and filepath of every document in the collection
+#-Then parse through each doc.gml stored in filepath to gather information
+#-From each file collect stems of kea keyphrases.
+#-Determine the number of keyphrase stems for each document 
+#-Search for the keyphrase stems in the numbered phrase index. If a phrase is not there then 
+# the program will write the keyphrase stem to the phrase index . 
+#-Search for the keyphrase stem in the keyphrase to document index. If the stem is there, 
+# it will increment the number of documents that the keyphrase stem appears in and replace that
+# then append the hash ID to the list of documents in the entry. If the stem is not there 
+# then the program will write the stem to the phrase index.
+#-Then write document ID, no of phrase, phrase number from index followed by number of times 
+# phrase appears into the document_keyphrase index
+
+$gsdlhome = $ENV{'GSDLHOME'};
+$collection;
+
+require "getopts.pl";
+&Getopts('R'); #process option arguments
+
+#if option R remove all previous indexes
+if($opt_R == 1){ #remove indexes
+    print STDERR "\nremoving $gsdlhome/bin/script/indexes/keyphrase_index.txt\n";
+    print STDERR "removing $gsdlhome/bin/script/indexes/keyphrase_document.txt\n";
+    print STDERR "removing $gsdlhome/bin/script/indexes/document_keyphrase.txt\n";
+    system("rm $gsdlhome/bin/script/indexes/keyphrase_document.txt");   
+    system("rm $gsdlhome/bin/script/indexes/document_keyphrase.txt"); 
+    system("rm $gsdlhome/bin/script/indexes/keyphrase_index.txt");
+}
+
+#collections may be specified in the command line
+#otherwise, all collections will be used to build
+#the indexes.  
+if(@ARGV){
+
+    @directories = @ARGV;
+
+} else { #open collect directory and get a list of all collections
+    opendir(DIR, "$gsdlhome/collect");
+    @directories = grep(!/(^\.|(CVS)|(modelcol))/, readdir(DIR));
+    closedir(DIR);
+}
+
+#for each collection specified to build indexes for
+foreach $collection (@directories){
+
+    my @filelist;
+
+    #archives.inf contains a list of unique hash ID's of each file and file paths
+    open(INFO, "$gsdlhome/collect/$collection/archives/archives.inf")
+	or die "$gsdlhome/collect/$collection/archives/archives.inf could not be opened.";
+
+    while(<INFO>){ #get each line of text from archives.inf (OID \t filepath)
+	chomp;
+	push(@filelist, $_);
+    }
+
+    foreach $file (@filelist){ #add each document to the indexes
+	build_index($file, $collection);
+    }
+}
+
+#This function opens the file in the filepath sent as an argument.  From this it obtains 
+#the kea and/or stem data, and then searches for these phrases in the file, counting and storing 
+#how many times each phrase appears. The data is then sent to function keyphrase_document 
+#with arguments hash ID, kea phrases and stem phrases to build the keyphrase_document index.
+#The function which builds the document_keyphrase index is then passed the hash ID, the kea 
+#phrases and/or the stemmed phrases and the array/s which hold the number of times each phrase
+#appears in the document so that the data it has collected can be written to document_ keyphrase
+#index.
+
+sub build_index {
+
+    my $args = shift(@_);
+    my $collection = shift(@_);
+    my ($ID, $filepath) = split(/\t/, $args);
+    my $stemsS = "";
+    my @stem_phrase_counts = 0;
+    my $text = "";
+
+    print STDERR "\nID: $ID\n";
+    print STDERR "filepath: $filepath\n";
+
+    #open file to extract keyphrase information
+    open(FILE, "$gsdlhome/collect/$collection/archives/$filepath")
+	or die "$gsdlhome/collect/$collection/archives/$filepath could not be opened.";
+
+    #patterns to search for so that we can extract the kea information
+    my $stem_search = "stems=\"([^\"]*)\"";
+
+    while(<FILE>){ #get kea and stem data and store
+	chomp;
+	$stemsS = $1 if (/$stem_search/);
+    }
+
+    close(FILE);
+    
+    print STDERR "stems: $stemsS\n";
+
+    my @stems = split(", ", $stemsS);
+
+    if(@stems){ #if the data exists
+	
+	#open the filepath to the current document
+	open(FILE, "$gsdlhome/collect/$collection/archives/$filepath")
+	    or die "$gsdlhome/collect/$collection/archives/$filepath could not be opened.";
+	
+	while(<FILE>){ #get the text
+	    chomp;
+	    $text .= $_;
+	}
+ 
+	#chop out all things in angled brackets
+	$text =~ s/(<[^>]*>)//g;
+
+	#initilise counts
+	for($i=0; $i<=$#stems; $i++){
+	    $stem_phrase_counts[$i] = 0;
+	}
+	
+	#using regular expressions generated from stem-reg
+	#count how many of each phrase appear in the document
+	
+	$text_copy = $text;
+	for($i=0; $i<=$#stems; $i++){ #search for text with stem phrases
+	    my $stem = $stems[$i];
+	    $reg = &stem_reg(split(/\s+/, $stem));
+	    while($text_copy =~ s/$reg//i){
+		$stem_phrase_counts[$i]++; #count the number of stem phrases
+	    } 
+	    $text_copy = $text;
+	}
+
+	
+	#write data to keyphrase_document index
+	&keyphrase_document($ID, $stemsS); 
+	
+	#write data to document_keyphrase index
+	$stem_counts = join(", ", @stem_phrase_counts);
+	&document_keyphrase($ID, $stemsS, $stem_counts);
+	
+    } else { 
+	print STDERR "No stem data was found in file $filepath\n";
+    }
+
+}
+
+#returns a regular expression designed to 
+#search for stems in text
+#eg 'agri cari'
+#    agri followed by 0 or more non-whitespace characters
+#         followed by one or more whitespace OR 0 or 1 non-whitespace characters
+#    cari followed by 0 or more non-whitespace characters
+#modified from original by Stephen Lundy 
+
+sub stem_reg {
+   
+    $regexp = "";
+
+    $l = @_;
+
+    if ($l > 0) {
+        $s = shift;
+        $regexp = "$s\\S*";
+
+        if ($l-1 > 0) {
+            foreach $s (@_) {
+                $regexp .= "(\\s+|\\S?)$s\\S*";
+            }
+        }
+    }
+
+    return $regexp;
+}
+
+
+
+#This function is passed as arguments a list of kea phrase stems. Its purpose is to 
+#check in the keyphrase index file for each phrase and determine whether or not an entry has
+#been made for that phrase and an index number assigned to it. If there has not been an entry
+#made then an index number is assigned to the phrase and it is written to the file.  This 
+#function is called by document_keyphrase and keyphrase_document.  Each line in the file has
+#this form:
+#-phrase index number:phrase
+#This function then returns a table of pairs of the phrases that were sent as arguments to it
+#{phrase => phrase index number}.
+ 
+sub keyphrase_index_search {
+
+    my $phrases = shift(@_);
+    my @phrases = split(", ", $phrases);
+    my %table;
+    my $index = 1;
+    my $create_new_index = 0;
+
+    print STDERR "searching keyphrase index...\n";
+
+    #initilise table of phrases and index numbers
+    foreach $phrase (@phrases){
+	$table{"$phrase"} = "0";
+    }
+
+    #open keyphrase index for appending data and for reading
+    open(INDEX_OUT, ">>$gsdlhome/bin/script/indexes/keyphrase_index.txt");
+    open(INDEX_IN, "$gsdlhome/bin/script/indexes/keyphrase_index.txt")
+	or $create_new_index = 1;
+
+    if($create_new_index == 0){
+	#if the index already exists read in the phrases
+	while(<INDEX_IN>){
+	    chomp;
+	    foreach $phrase (@phrases){
+		if(/(\d+):$phrase/){
+		    $index = $1;
+		    $table{"$phrase"} = "$index";
+		}
+	    }
+	    $index++; #new starting index (one + the last index)
+	}
+
+	close(INDEX_IN);
+
+    }
+
+    #add new phrases to the phrase index
+    foreach $phrase (keys %table){
+	if($table{"$phrase"} eq "0"){
+	    print INDEX_OUT "$index:$phrase\n";
+	    $table{"$phrase"} = "$index"; 
+	    $index++;
+	}
+    }
+
+    close(INDEX_OUT);
+    return %table;
+}
+
+#This function is passed as arguments file hash ID and a list of kea phrases and/or stems
+#that exist for that particular file.  Its purpose is to write to the keyphrase_document
+#index a line for the document it has been sent:
+#-phrase index number:number of documents it appears in|ID
+sub keyphrase_document{
+
+    my ($ID, $stems) = @_;
+    my $text = ""; 
+    my @textlist;
+    my $create_new_index = 0;
+
+    print STDERR "writing to keyphrase_document.txt...\n";
+
+    #get table of phrases and phrase indexes 
+    my %table = keyphrase_index_search($stems); 
+    
+  
+    #open index for reading
+    open(INDEX_IN, "$gsdlhome/bin/script/indexes/keyphrase_document.txt")
+	or $create_new_index = 1;
+
+    #read in document if file exists
+    if($create_new_index == 0){
+
+	while(<INDEX_IN>){
+	    $text .= $_;
+	}
+
+	close(INDEX_IN);
+
+	#split text into lines
+	@textlist = split(/\n/, $text);
+
+    } 
+
+    #open index for output
+    open(INDEX_OUT, ">$gsdlhome/bin/script/indexes/keyphrase_document.txt");
+
+    if($create_new_index == 0){ #amend existing index
+	
+	foreach $line (@textlist){
+	    foreach $phrase (keys %table){
+		if($line =~ /(\d+):(\d+)(.*)/){ #all lines of this form
+		    $index = $1;
+		    if($table{"$phrase"} eq "$index") { #if phrase exists in index
+			$ids = $3; #get all doc IDs for that keyphrase
+			if($ids !~ /$ID/){ #if doc ID not already included
+			    $num_docs = $2;
+			    $num_docs++; #increment number of docs
+			    $line = "$index:$num_docs$3|$ID"; #line to append to index
+			    $table{"$phrase"} = "0"; 
+			}
+		    }
+		}
+	    }
+	    print INDEX_OUT "$line\n";
+	}
+    }
+
+    #add new phrases to the index
+    foreach $phrase (keys %table){ #write 'phrase index:1:file ID
+	if($table{"$phrase"} ne "0"){
+	    my $line = "$table{$phrase}:1:$ID";
+	    print INDEX_OUT "$line\n"; 
+	}
+    }
+
+    close(INDEX_OUT);
+
+}
+
+#This function is passed as arguments file hash ID and a list of kea phrase stems
+#that exist for that particular file and a list of the number of times each stem
+#phrase appear in that document.  Its purpose is to write to the document_keyphrase
+#index a line for the document it has been sent:
+#-file ID:number of phrases and/or stems appear in the document
+#      |pairs of 'phrase index,number of times the phrase appears in the document' 
+sub document_keyphrase {
+
+    my ($ID, $stemsS, $stem_c) = @_;
+    my $text = "";
+    my @textlist;
+    my %phrases;
+    my $create_new_index = 0;
+
+    print STDERR "writing to document_keyphrase.txt...\n";
+
+    #split phrase counts into arrays
+    my @stem_counts = split(", ", $stem_c);
+  
+    #get table of phrases and phrase indexes
+    my %table = keyphrase_index_search($stemsS);
+
+    #split phrases into arrays
+    my @stems = split(", ", $stemsS);
+
+    #build new phrases dictionary
+    for($i=0; $i<=$#stems; $i++){
+	my $phrase = $table{"$stems[$i]"};
+	$phrases{"$phrase"} = "$stem_counts[$i]";
+    }   
+    my @num = keys %phrases;
+    my $phrasenum = $#num + 1; #number of phrases in doc
+
+    #open index for reading
+    open(INDEX_IN, "$gsdlhome/bin/script/indexes/document_keyphrase.txt")
+	or $create_new_index = 1;
+
+     
+    if($create_new_index == 0){ #index doesn't need to be created
+
+	while(<INDEX_IN>){
+	    $text .= $_;
+	}
+
+	close(INDEX_IN);
+	
+	#split text into lines
+	@textlist = split(/\n/, $text);
+
+    }  
+
+
+    #must write this line to the file
+    #'document ID:num of phrases|phrase index, number of times phrases appears
+    my $newline = "$ID:$phrasenum";
+    foreach $phrase (keys %phrases){
+	$newline .= "|$phrase,$phrases{$phrase}";
+    }
+
+    #open index for output
+    open(INDEX_OUT, ">$gsdlhome/bin/script/indexes/document_keyphrase.txt");
+
+    if($create_new_index == 1){ #create a new index
+
+	print INDEX_OUT "$newline\n";
+
+    } else {
+
+	#if ID is already in the file write line overtop incase
+	#someone has modified the file.  Otherwise add the line
+	#to the end of the file
+	my $found = 0;
+
+	foreach $line (@textlist){
+	    if($line =~ /([^:]+):(.*)/){ #all lines should follow this pattern
+		$id = $1;
+		if($ID eq $id){ #id is already in the file
+		    print INDEX_OUT "$newline\n"; #print line overtop
+		    $found = 1;
+		} else {
+		    print INDEX_OUT "$line\n"; #print old line out
+		}
+	    }
+	}
+
+	print INDEX_OUT "$newline\n" if ($found == 0); #append new line to end of file 
+
+    }
+
+    close(INDEX_OUT);
+
+}
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/bin/script/indexes/relation.pl
===================================================================
--- /gsdl/stable/bin/script/indexes/relation.pl	(revision 20131)
+++ /gsdl/stable/bin/script/indexes/relation.pl	(revision 20131)
@@ -0,0 +1,414 @@
+#!/usr/bin/perl
+
+#data structures used:
+#-document_keyphrase
+#%document_phrases = ("hashID" => {"phrase" => "number of occurrences"})
+#-keyphrase_document 
+#%phrases_document = ("phrase" => "no. of docs phrase occurs in")
+
+#after calculation relational data, it will amend gml files
+#to include this data while writing to a file ID_relatedlinks.txt
+#the html links of the related files
+#if option p is set then the user wishes to add the related documents
+#as bookmarks to the pdf file
+
+require "getopts.pl";
+&Getopts('N:P'); #process option arguments
+
+
+$gsdlhome = $ENV{'GSDLHOME'};
+@directories; #list of directories for the collections
+%phrases_document; #hash storing phrase index => no. of documents with phrase in it
+%document_phrases; #hash of hashes ID => {phrase number => no. of phrases in ID}
+$N = 0; #number of documents in the index (presumably in the collection)
+%cosine_matrix; #2-dimensional matrix, for each pair of documents stores a cosine measure
+$number_of_files = 1; #by default the top related file is returned
+$do_pdfs = 0;
+
+if($opt_N =~ /(\d)+/){ #if flag is set then return top N docs
+    $number_of_files = $opt_N;
+}
+
+#get server name and httpprefix
+$httpprefix;
+$servername = "nzdl2.cs.waikato.ac.nz"; #should be localhost
+
+if($opt_P == 1){ #if flag is set 
+    $do_pdfs = 1;
+    
+    #get the httpprefix from gsdlsite.cfg
+    open(CFG, "$gsdlhome/cgi-bin/gsdlsite.cfg") 
+	or die "$gsdlhome/cgi-bin/gsdlsite.cfg could not be opened";
+    
+    while(<CFG>){
+	chomp;
+	if(/httpprefix \/(.+)/){
+	    $httpprefix = $1; 
+	}
+    }
+    close CFG;
+}
+
+if(@ARGV){
+
+    @directories = @ARGV;
+
+} else { #open collect directory and get a list of all collections
+    opendir(DIR, "$gsdlhome/collect");
+    @directories = grep(!/(^\.|(CVS)|(modelcol))/, readdir(DIR));
+    closedir(DIR);
+}
+
+
+
+#get the name of the directory the index will be stored in
+$dirname = "";
+foreach $collection (sort @directories){
+    $dirname .= $collection."_";
+}
+$dirname .= "indexes";
+print STDERR "directory name: $dirname\n";
+
+#open keyphrases_document.txt
+open(KEY_FILE, "$gsdlhome/bin/script/indexes/$dirname/keyphrase_document.txt") 
+    or die "$gsdlhome/bin/script/indexes/$dirname/keyphrase_document.txt could not be opened";
+
+print STDERR "\nreading keyphrase_document.txt...\n";
+
+#read a list of phrase indexes and number of documents that phrase appears in 
+while(<KEY_FILE>){
+    chomp;
+    if(/(\d+)\:(\d+)(.*)/){ #all lines should be of this form
+	my $phrase_index = $1;
+	my $doc_num = $2;
+	$phrases_document{"$phrase_index"} = "$doc_num"; #build keyphrase hash
+    }
+}
+
+close(KEY_FILE); 
+
+print STDERR "\nreading document_keyphrase.txt...\n";
+
+#open document_keyphrases.txt
+open(DOC_FILE, "$gsdlhome/bin/script/indexes/$dirname/document_keyphrase.txt") 
+    or die "$gsdlhome/bin/script/indexes/$dirname/document_keyphrase.txt could not be opened";
+
+#read a list of documents and the phrases that appear in them (& how many times they appear)
+while(<DOC_FILE>){
+    chomp;
+    my %document;
+    if(/(\w+)\:(\d+)((\|\d+,\d+)+)/){ #every line in the index of this form
+	my $ID = $1;
+	my $pairs = $3;
+	while ($pairs =~ s/\|(\d+),(\d+)//) { #this is the list of keyphrases and numbers
+	    my $phrase_index = $1;
+	    my $num_phrase = $2;
+	    $document{"$phrase_index"} = "$num_phrase"; #table to be stored in another table
+	}
+	$document_phrases{"$ID"} = ({%document});	  
+	$N++; #number of documents in the collection (which have kea metadata)
+    }
+}
+
+close(DOC_FILE);
+ 
+#we do not want to recalculate measures ie if we have already calculated
+#doc1 & doc2 we do not then want to calculate doc2 & doc1
+#to achieve this we must first sort the list of ids so that both lists
+#of documents will be in the same order (otherwise hash tables return values in 
+#no particular order). We then compare each document in the left 
+#column below against the documents in the right column:
+
+#doc0 -> 
+#doc1 -> doc0 
+#doc2 -> doc0, doc 1 
+#doc3 -> doc0, doc 1, doc 2 
+#doc4 -> doc0, doc 1, doc 2, doc 3 
+#doc5 -> doc0, doc 1, doc 2, doc 3, doc 4 
+#etc
+
+#this way we are not recalculating the same value and also not
+#comparing each document to itself (which would result in the
+#value 1) thus more than halving the processing time.
+
+print STDERR "\ncalculating cosine measures for $N documents...\n";
+
+$count = 0;
+@ids = sort keys(%document_phrases);
+
+#repeat for all pairs of documents
+foreach $id1 (sort keys(%document_phrases)) { 
+    my %table;
+   
+    for($i=0; $i<$count; $i++){ #calculate the cosine measure and store
+	my $cosine_measure = &compare_docs($id1, $ids[$i]); 
+	$table{"$ids[$i]"} = "$cosine_measure";  	
+    }
+    $cosine_matrix{"$id1"} = ({%table});
+    $count++; #each iteration the number of documents to compare against expands by 1
+}
+
+&addtogml(); #add the relational data we have just gathered to the documents gml files
+
+   
+#this function takes as an argument two document IDs and uses these to extract the
+#keyphrases from the document_keyphrase data structure.  It then calculates a 
+#'measure of relativity' [0-1] with which we can establish how similar the two
+#documents are to each other. (0-not related, 1-same document).  The equation 
+#used to establish this similarity:
+#
+#                     for all phrases 
+#                     in both d1, d2 (fd1p * loge(N/fp) (fd2p * loge(N/fp) 
+#  cosine(d1, d2) = --------------------------------------------------------------
+#                     sqrt(sum of phrases in d1(fd1p * loge(N/fp))) * 
+#                     sqrt(sum of phrases in d2(fd2p * loge(N/fp))) 
+#
+#where d1 and d2 are lists of keyphrase and represent documents
+#fd1p is the frequency that phrase p occurs in document d1
+#fd2p is the frequency that phrase p occurs in document d2
+#fp is the number of documents that have p as a keyphrase
+#N is the number of documents in the collection 
+sub compare_docs {
+
+  
+    my $ID1 = shift(@_); #ID for document one 
+    my $ID2 = shift(@_); #ID for document two
+  
+    my @phrases; #a list of phrases in document 1 and document 2
+    my @phrases1; #a list of phrases in document 1
+    my @phrases2; #a list of phrases in document 2
+    
+    
+    foreach $phrase (keys %{ $document_phrases{$ID1}}) { #list of phrases in doc1
+	push(@phrases1, $phrase);
+    } 
+    foreach $phrase (keys %{ $document_phrases{$ID2}}) { #list of phrases in doc2
+	push(@phrases2, $phrase);
+    }
+    foreach $phrase1 (@phrases1) { #list holds intersection of doc1 and doc2
+	foreach $phrase2 (@phrases2) {
+	    push(@phrases, $phrase1) if ($phrase1 == $phrase2);
+	}
+    }
+ 
+#COSINE MEASURE
+    my $wqtwdt= 0; 
+   
+    foreach $phrase (@phrases){ #for all phrases ocurring in d1 and d2
+	#the frequency that phrase occurs in document d1
+	$fd1p = $document_phrases{$ID1}{$phrase}; 
+	
+	#log base e(N/the number of documents that have phrase as a keyphrase)
+	$log_freq = log($N/$phrases_document{$phrase});
+	
+	#the frequency that phrase occurs in document d2
+	$fd2p = $document_phrases{$ID2}{$phrase};
+	$sum = ($fd1p * $log_freq) * ($fd2p * $log_freq);
+	$wqtwdt += $sum;
+    }
+  
+   
+    my $wd = 0; #stores the calculation for wd
+
+    foreach $phrase (@phrases1){ #for all phrases ocurring in d1 and d2
+	#the frequency that phrase occurs in document d1
+	$fd1p = $document_phrases{$ID1}{$phrase};
+	
+	#log base e($N/the number of documents that have phrase as a keyphrase)
+	$log_freq = log($N/$phrases_document{$phrase});
+	$sum = $fd1p * $log_freq;
+	$wd += ($sum * $sum); #sum squared
+    }
+
+   
+    my $wq = 0; #stores the calculation for wq
+ 
+    foreach $phrase (@phrases2){ #for all phrases ocurring in d2
+	#the frequency that phrase occurs in document d2
+	$fd2p = $document_phrases{$ID2}{$phrase};
+
+	#log base e($N/the number of documents that have phrase as a keyphrase)
+	$log_freq = log($N/$phrases_document{$phrase});
+	$sum = $fd2p * $log_freq;
+	$wq += ($sum * $sum); #sum squared 
+    }
+   
+    my $wdwq = sqrt($wq)  * sqrt($wd);  
+    my $cosine = $wqtwdt / $wdwq;
+    
+    return $cosine;
+	
+}
+   
+#this function adds the relational data we have collected to the gml files
+sub addtogml {
+
+ print STDERR "\nadding relational data to $N gml documents...\n\n";
+ my @doclist;
+ my %filetable;
+ my $pattern = "kea="; #pattern to search for to find where to insert relation data
+
+ #open archive info for each collecticollection
+ foreach $collection (@directories){
+
+     open(INFO, "$gsdlhome/collect/$collection/archives/archives.inf") 
+	 or die "$gsdlhome/collect/$collection/archives/archives.inf could not be opened";
+     
+     #read a list of ID's and pathnames into a file table
+     while(<INFO>){
+	 chomp;
+	 my %idtable;
+	 my $ID;
+	 if(/(\w+)(\s+)([\w\.\/]+)/){ #format of the line
+	     $ID = $1;
+	     $path = $3;
+	     $idtable{"$path"} = "$collection";
+	 }
+	 $filetable{"$ID"} = ({%idtable});
+     } 
+  
+     close(INFO);
+ }
+
+ 
+
+ #for each id in the matrix calculate a list of related documents
+ foreach $id (keys %cosine_matrix){    
+    
+     @doclist = &calculate_list($id); #gets list of documents with most relevant scores
+
+     my @path = keys %{$filetable{$id}}; #get filepath for document
+     my $collection = $filetable{$id}{$path[0]};
+     
+     #open gml file to amend for each collection
+     open(FILE, "$gsdlhome/collect/$collection/archives/$path[0]") 
+	 or die "$gsdlhome/collect/$collection/archives/$path[0] could not be opened";
+     
+     #read the gml file into text
+     $text = ""; 
+     while(<FILE>){
+	 $text .= $_;
+     }
+     
+     close(FILE);
+     
+     #delete previous relational data and urllinks to files storing rel doc links
+     $text =~ s/(\s)+relation=\"([^\"]*)\"//g;
+     $text =~ s/(\s)+urllink=\"([^\"]*)\"//g;
+     $text =~ s/(\s)+\/urllink=\"([^\"]*)\"//g;
+     
+     #if we want to insert each relation item as 'relation1="id" relation2="id"'
+     #$count = 1; #insert each item in the list
+     #foreach $item (@doclist){ #insert list into text
+     #	 $text =~ s/(\s)($pattern)/ relation$count=\"$item\" $2/g;
+     #	 $count++;
+     #} 
+     
+     #or relation="id, id, id"
+     #my $relation = join(",", @doclist);
+
+     #if pdf flag is set then delete pdf url document
+     if($do_pdfs == 1){ 
+	 my $dirpath = $path[0];
+	 $dirpath =~ s/(^(\/doc\.gml))*\/doc\.(gml)/$1/;
+ 	 `rm $gsdlhome/collect/$collection/index/assoc/$dirpath/url.txt`; 
+     }
+
+     my $title = "related document";
+     $title = $2 if($text =~ /(\s)+Title=\"([^\"]*)\"/g);
+   
+     #relation="collection,id collection,id"
+     my @relationlist;
+     my $relation = "";
+     foreach $doc (@doclist){
+	 my @p = keys %{$filetable{$doc}};
+	 my $collect = $filetable{$doc}{$p[0]};
+	 push(@relationlist, "$collect,$doc");
+
+	 #write pdf docs to file
+	 if($do_pdfs == 1){
+	     my @rel_path = keys %{$filetable{$doc}};
+	     &write_related_urls($title, $collection, $path[0], $collect, $rel_path[0]);
+	 }
+     }
+  
+     #modify the text to include relation data
+     $relation = join(" ", @relationlist); 
+     $text =~ s/($pattern)/ relation=\"$relation\" $1/g;
+
+     #open gml file to write back new text
+     open(FILE, ">$gsdlhome/collect/$collection/archives/$path[0]") or print STDERR "NO!!!!\n";
+     print FILE "$text"; #write back text
+     close(FILE);
+
+     #amend the pdf file 
+     if($do_pdfs == 1){
+	 my $pdf_path = $path[0];
+	 $pdf_path =~ s/(^(\/doc\.gml))*\/doc\.(gml)/$1/;
+	 `perl amend_pdf.pl $gsdlhome/collect/$collection/index/assoc/$pdf_path/doc.pdf $gsdlhome/collect/$collection/index/assoc/$pdf_path/url.txt\n`;
+     }
+ } 
+}
+
+#this function builds a list of cosine measures for each
+#document and sorts the list of ids each measure belongs to
+#in reverse order (ie docs with greatest cosine measure first)
+#returns the list calculated
+sub calculate_list {
+   
+    my $document = shift(@_);
+    my %measures;
+    my @doclist;
+    
+    
+    #find the top $number_of_files for $document  
+    foreach $id (keys %{$cosine_matrix{$document}}){ 
+	    $measures{"$cosine_matrix{$document}{$id}"} = "$id";
+    }
+    
+    my @list = reverse sort {$a<=>$b} keys %measures;
+
+    #list is as big as specified in command line (default is 1)
+    for($i = 0; $i<$number_of_files; $i++){ 
+	my $id = $measures{$list[$i]};
+	push(@doclist, $id) if($id ne "");
+    }
+
+    return @doclist;
+}
+
+
+sub write_related_urls {
+
+    
+ #need server name eg nzdl2.cs.waikato.ac.nz
+ #localhost should work but doesn't on this computer?
+ #open up config file to read httpprefix
+ #get collection name of related document
+ #get hash directory of related document
+ #write http://nzdl2.cs.waikato.ac.nz/httpprefix/collectionname/index/assoc/directory/doc.pdf
+
+ my ($title, $collection, $path, $collect, $rel_path) = @_;
+
+ $rel_path =~ s/(^(\/doc\.gml))*\/doc\.(gml)/$1/;
+ $path =~ s/(^(\/doc\.gml))*\/doc\.(gml)/$1/;
+ 
+ print STDERR "writing related pdf urls to file ";
+ print STDERR "$gsdlhome/collect/$collection/index/assoc/$path/url.txt...\n";
+ 
+ open(URL, ">>$gsdlhome/collect/$collection/index/assoc/$path/url.txt") 
+     or open(URL, ">$gsdlhome/collect/$collection/index/assoc/$path/url.txt")
+	 or print STDERR "This file $title is not a pdf file\n";
+
+ print URL "$title\t"; 
+ print URL "http://$servername/$httpprefix/collect/$collect/index/assoc/$rel_path/doc.pdf\n";
+ close URL;
+
+}
+
+
+
+
+
+
+
Index: /gsdl/stable/bin/script/lucene_passes.pl
===================================================================
--- /gsdl/stable/bin/script/lucene_passes.pl	(revision 20131)
+++ /gsdl/stable/bin/script/lucene_passes.pl	(revision 20131)
@@ -0,0 +1,216 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# lucene_passes.pl -- perl wrapper, akin to mgpp_passes, for Lucene
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+
+use strict;
+use util;
+
+
+sub open_java_lucene
+{
+  my ($doc_tag_level,$full_builddir,$indexdir,$java_lucene_options) = @_;
+
+  # Is there a collection-specific bin/java/LuceneWrapper.jar file?
+  my $bin_java = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"bin","java");
+  my $classpath = &util::filename_cat($bin_java,"LuceneWrapper.jar");
+  if (!-f $classpath)
+  {
+      # No, so use the Greenstone one
+      $bin_java = &util::filename_cat($ENV{'GSDLHOME'},"bin","java");
+      $classpath = &util::filename_cat($bin_java,"LuceneWrapper.jar");
+  }
+
+  my $java_lucene = "java -classpath \"$classpath\" org.greenstone.LuceneWrapper.GS2LuceneIndexer";
+  my $java_cmd = "$java_lucene $java_lucene_options $doc_tag_level \"$full_builddir\" $indexdir";
+
+  open (PIPEOUT, "| $java_cmd") or die "lucene_passes.pl - couldn't run $java_cmd\n";
+}
+
+
+sub close_java_lucene
+{
+  close(PIPEOUT);
+}
+
+
+sub save_xml_doc
+{
+    my ($full_textdir,$output_filename,$doc_xml) = @_;
+
+    my $dir_sep = &util::get_os_dirsep();
+
+    my $full_output_filename = &util::filename_cat($full_textdir,$output_filename);
+    my ($full_output_dir) = ($full_output_filename =~ m/^(.*$dir_sep)/x);
+    &util::mk_all_dir($full_output_dir);
+
+    open(DOCOUT,">$full_output_filename")
+	|| die "Unable to open $full_output_filename";
+
+    print DOCOUT $doc_xml;
+    close(DOCOUT);
+
+    my @secs =  ($doc_xml =~ m/<Sec\s+gs2:id="\d+"\s*>.*?<\/Sec>/sg);
+}
+
+
+sub compress_xml_doc
+{
+    my ($full_textdir,$output_filename) = @_;
+
+    my $full_output_filename
+	= &util::filename_cat($full_textdir,$output_filename);
+
+    `gzip $full_output_filename`;
+}
+
+
+# This appears to be the callback that gets the xml stream during the
+# build process, so I need to intercept it here and call my XML RPC
+# to insert into the Lucene database.
+sub monitor_xml_stream
+{
+    my ($mode, $full_textdir) = @_;
+
+    my $doc_xml = "";
+    my $output_filename = "";
+
+    my $line;
+    while (defined ($line = <STDIN>)) {
+	$doc_xml .= $line;
+	if ($line =~ m/^<Doc.+file=\"(.*?)\".*>$/) {
+	    $output_filename = $1;
+	    
+	}
+	
+	if ($line =~ m/^<\/Doc>$/) {
+	    if ($mode eq "text") {
+		save_xml_doc($full_textdir,$output_filename,$doc_xml);
+	    } elsif ($mode eq "index") {
+		# notify lucene indexer
+
+		# SAX parser seems to be sensitive to blank lines
+		# => remove them
+		$doc_xml =~ s/\n+/\n/g;
+
+#		 print STDERR $doc_xml;
+
+##	    print PIPEOUT "$output_filename\n";
+
+		print PIPEOUT "$doc_xml";
+
+
+		#save_xml_doc($full_textdir, "$output_filename.txt", $doc_xml);
+	    }
+	    # compress file
+###	    compress_xml_doc($full_textdir,$output_filename);
+
+	    $doc_xml = "";
+	    $output_filename = "";
+	}
+    }
+}
+
+
+# /** This checks the arguments on the command line, filters the
+#  *  unknown command line arguments and then calls the open_java_lucene
+#  *  function to begin processing. Most of the arguments are passed on
+#  *  the command line of the java wrapper.
+#  *
+#  */
+sub main
+{
+  my (@argv) = @_;
+  my $argc = scalar(@argv);
+
+  my $java_lucene_options = "";
+  my @filtered_argv = ();
+
+  my $i = 0;
+  while ($i<$argc) {
+    if ($argv[$i] =~ m/^\-(.*)$/) {
+
+      my $option = $1;
+
+      # -removeold causes the existing index to be overwritten
+      if ($option eq "removeold") {
+        print STDERR "\n-removeold set\n";
+        $java_lucene_options .= "-removeold ";
+      }
+      # -verbosity <num>
+      elsif ($option eq "verbosity") {
+        $i++;
+        if ($i<$argc)
+	{
+	  $java_lucene_options .= "-verbosity " . $argv[$i];
+        }
+      }
+      else {
+        print STDERR "Unrecognised minus option: -$option\n";
+      }
+    }
+    else {
+        push(@filtered_argv,$argv[$i]);
+    }
+    $i++;
+  }
+
+  my $filtered_argc = scalar(@filtered_argv);
+
+  if ($filtered_argc < 4) {
+    print STDERR "Usage: lucene_passes.pl [-removeold|-verbosity num] \"text\"|\"index\" doc-tag-level build-dir index-name\n";
+    exit 1;
+  }
+
+  my $mode = $filtered_argv[0];
+  my $doc_tag_level = $filtered_argv[1];
+  my $full_builddir = $filtered_argv[2];
+  my $indexdir      = $filtered_argv[3];
+###    print STDERR "**** ARGS = ", join(" ", @argv), "\n";
+
+  # We only need the Lucene handle opened if we are indexing the documents, not if we are just storing the text
+  if ($mode eq "index") {
+    open_java_lucene($doc_tag_level, $full_builddir, $indexdir, $java_lucene_options);
+  }
+
+  print STDERR "Monitoring for input!\n";
+  my $full_textdir = &util::filename_cat($full_builddir,"text");
+  monitor_xml_stream($mode, $full_textdir);
+
+  if ($mode eq "index") {
+    close_java_lucene();
+  }
+}
+
+
+&main(@ARGV);
Index: /gsdl/stable/bin/script/lucene_query.pl
===================================================================
--- /gsdl/stable/bin/script/lucene_query.pl	(revision 20131)
+++ /gsdl/stable/bin/script/lucene_query.pl	(revision 20131)
@@ -0,0 +1,171 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# lucene_query.pl -- perl wrapper to initiate query using Lucene
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use strict;
+use util;
+
+my $PROGNAME = $0;
+$PROGNAME =~ s/^.*\/(.*)$/$1/;
+
+
+sub get_java_path()
+{
+    # Check the JAVA_HOME environment variable first
+    if (defined $ENV{'JAVA_HOME'}) {
+	my $java_home = $ENV{'JAVA_HOME'};
+	$java_home =~ s/\/$//;  # Remove trailing slash if present (Unix specific)
+	return &util::filename_cat($java_home, "bin", "java");
+    }
+
+    # Hope that Java is on the PATH
+    return "java";
+}
+
+sub open_java_lucene
+{
+    my $full_indexdir = shift(@_);
+    my $fuzziness = shift(@_);
+    my $filter_string = shift(@_);
+    my $sort_field = shift(@_);
+    my $dco = shift(@_);
+    my $start_results = shift(@_);
+    my $end_results = shift(@_);
+    my $out_file = shift(@_);
+
+    my $java = &get_java_path();
+    my $classpath = &util::filename_cat($ENV{'GSDLHOME'}, "bin", "java", "LuceneWrapper.jar");
+    my $java_lucene = "\"$java\" -classpath \"$classpath\" org.greenstone.LuceneWrapper.GS2LuceneQuery";
+
+    my $cmd = "| " . $java_lucene . " \"" . $full_indexdir . "\"";
+    if (defined($fuzziness)) {
+        $cmd .= " -fuzziness " . $fuzziness;
+    }
+    if (defined($filter_string)) {
+	$cmd .= " -filter \"" . $filter_string . "\"";
+    }
+    if (defined($sort_field)) {
+        $cmd .= " -sort " . $sort_field;
+    }
+    if (defined($dco)) {
+        $cmd .= " -dco " . $dco;
+    }
+    if (defined($start_results)) {
+        $cmd .= " -startresults " . $start_results;
+    }
+    if (defined($end_results)) {
+        $cmd .= " -endresults " . $end_results;
+    }
+    if (defined($out_file)) {
+	$cmd .= " > \"" . $out_file . "\"";
+    }
+    # print STDERR $cmd . "\n";
+
+    if (!open (PIPEOUT, $cmd)) {
+	die "$PROGNAME - couldn't run $cmd\n";
+    }
+}
+
+sub close_java_lucene
+{
+    close(PIPEOUT);
+}
+
+sub main
+{
+    my (@argv) = @_;
+    my $argc = scalar(@argv);
+    if ($argc == 0) {
+	print STDERR "Usage: $PROGNAME full-index-dir [query] [-fuzziness value] [-filter filter_string] [-sort sort_field] [-dco AND|OR] [-startresults number -endresults number] [-out out_file]\n";
+	exit 1;
+    }
+
+    my $full_indexdir = shift(@argv);
+    my $query = undef;
+    my $fuzziness = undef;
+    my $filter_string = undef;
+    my $sort_field = undef;
+    my $dco = undef;
+    my $start_results = undef;
+    my $end_results = undef;
+    my $out_file = undef;
+    for (my $i = 0; $i < scalar(@argv); $i++)
+    {
+	if ($argv[$i] eq "-fuzziness") {
+	    $i++;
+	    $fuzziness = $argv[$i];
+	}
+        elsif ($argv[$i] eq "-filter") {
+            $i++;
+            $filter_string = $argv[$i];
+	}
+        elsif ($argv[$i] eq "-sort") {
+            $i++;
+            $sort_field = $argv[$i];
+	}
+        elsif ($argv[$i] eq "-dco") {
+            $i++;
+            $dco = $argv[$i];
+	}
+        elsif ($argv[$i] eq "-startresults") {
+            $i++;
+            $start_results = $argv[$i];
+	}
+        elsif ($argv[$i] eq "-endresults") {
+            $i++;
+            $end_results = $argv[$i];
+	}
+        elsif ($argv[$i] eq "-out") {
+            $i++;
+            $out_file = $argv[$i];
+	}
+        else {
+            $query = $argv[$i];
+	}
+    }
+
+    open_java_lucene($full_indexdir, $fuzziness, $filter_string, $sort_field, $dco, $start_results, $end_results, $out_file);
+
+    if (defined $query) {
+	print PIPEOUT "$query\n";
+    }
+    else {
+	while (defined (my $line = <STDIN>)) {
+	    print PIPEOUT $line;
+	}
+    }
+
+    close_java_lucene();
+}
+
+&main(@ARGV);
Index: /gsdl/stable/bin/script/makemapfile.pl
===================================================================
--- /gsdl/stable/bin/script/makemapfile.pl	(revision 20131)
+++ /gsdl/stable/bin/script/makemapfile.pl	(revision 20131)
@@ -0,0 +1,188 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# makemapfile.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use parsargv;
+use util;
+
+# %translations is of the form:
+#
+# encodings{encodingname-encodingname}->blocktranslation
+# blocktranslation->[[0-255],[256-511], ..., [65280-65535]]
+#
+# Any of the top translation blocks can point to an undefined
+# value. This data structure aims to allow fast translation and 
+# efficient storage.
+%translations = ();
+
+# @array256 is used for initialisation, there must be
+# a better way...
+@array256 = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+
+&main();
+
+sub print_usage {
+    print STDERR "\n";
+    print STDERR "makemapfile.pl: Creates unicode map (.ump) files from plain\n";
+    print STDERR "                text code pages.\n\n";
+    print STDERR "  usage: $0 [options]\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -encoding name\n";
+    print STDERR "   -mapfile  text file from which to create binary ump file\n\n";
+}
+
+sub main {
+    if (!parsargv::parse(\@ARGV, 
+			 'encoding/.+', \$encoding,
+			 'mapfile/.+', \$mapfile)) {
+	&print_usage();
+	die "\n";
+    }
+
+    if (!&loadencoding ($encoding, $mapfile)) {
+	die "couldn't load encoding $encoding";
+    }
+
+    # write out map files
+    &writemapfile ("$encoding-unicode", $encoding, 1);
+    &writemapfile ("unicode-$encoding", $encoding, 0);
+}
+
+sub writemapfile {
+    my ($encoding, $filename, $tounicode) = @_;
+
+    $filename .= ".ump"; # unicode map file
+    if ($tounicode) {
+	$filename = &util::filename_cat ($ENV{'GSDLHOME'}, "mappings", "to_uc", $filename);
+    } else {
+	$filename = &util::filename_cat ($ENV{'GSDLHOME'}, "mappings", "from_uc", $filename);
+    }
+
+    die "translation not defined" if (!defined $translations{$encoding});
+    my $block = $translations{$encoding};
+
+    print "writing $filename\n";
+    open (MAPFILE, ">" . $filename) || die;
+    binmode (MAPFILE);
+
+    my ($i, $j);
+    for ($i=0; $i<256; $i++) {
+	if (ref ($block->[$i]) eq "ARRAY") {
+	    print MAPFILE pack ("C", $i);
+	    for ($j=0; $j<256; $j++) {
+		# unsigned short in network order
+		print MAPFILE pack ("CC", int($block->[$i]->[$j] / 256), 
+				    $block->[$i]->[$j] % 256);
+	    }
+	}
+    }
+    close (MAPFILE);
+}
+
+# loadencoding expects the mapfile to contain (at least) two
+# tab-separated fields. The first field is the mapped value
+# and the second field is the unicode value.
+#
+# It returns 1 if successful, 0 if unsuccessful
+sub loadencoding {
+    my ($encoding, $mapfile) = @_;
+    
+    my $to = "$encoding-unicode";
+    my $from = "unicode-$encoding";
+
+    # check to see if the encoding has already been loaded
+    if (defined $translations{$to} && defined $translations{$from}) {
+	return 1;
+    }
+
+    return 0 unless open (MAPFILE, $mapfile);
+
+    my ($line, @line);
+    $translations{$to} = [@array256];
+    $translations{$from} = [@array256];
+    while (defined ($line = <MAPFILE>)) {
+	chomp $line;
+	# remove comments
+	$line =~ s/\#.*$//;
+	next unless $line =~ /\S/;
+
+	# split the line into fields and do a few
+	# simple sanity checks
+	@line = split (/\t/, $line);
+	next unless (scalar(@line) >= 2 &&
+		     $line[0] =~ /^0x/ &&
+		     $line[1] =~ /^0x/);
+
+	my $char = hex($line[0]);
+	my $unic = hex($line[1]);
+
+	# might need this for some versions of gb but not gbk
+#	$char = $char | 0x8080 unless ($encoding =~ /gbk/i);
+
+	&addchartrans ($translations{$to}, $char, $unic);
+	&addchartrans ($translations{$from}, $unic, $char);
+    }
+
+    close (MAPFILE);
+
+    return 1;
+}
+
+# addchartrans adds one character translation to a translation block.
+# It also simplifies the translation block if possible.
+sub addchartrans {
+    my ($block, $from, $to) = @_;
+    my $i = 0;
+
+    my $high = ($from / 256) % 256;
+    my $low = $from % 256;
+
+    if (ref ($block->[$high]) ne "ARRAY") {
+	$block->[$high] = [@array256];
+    }
+    $block->[$high]->[$low] = $to;
+}
Index: /gsdl/stable/bin/script/mirror.pl
===================================================================
--- /gsdl/stable/bin/script/mirror.pl	(revision 20131)
+++ /gsdl/stable/bin/script/mirror.pl	(revision 20131)
@@ -0,0 +1,144 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# mirror.pl
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program uses w3mirror to mirror a web site.  It looks for a
+# mirror program configuration files in etc, and if it finds them then
+# it runs the mirroring software using this configuration file, and placing
+# the mirror in the import directory.
+#
+# mirror.pl can use the w3mirror program or the wget program if they are
+# installed.
+#
+# To use w3mirror, the configuration file must be in etc/w3mir.cfg.
+# To use GNU wget, the configuration file (i.e. a wgetrc file) must
+# be in etc/wget.cfg and a file of the URLs to read in etc/wget.url
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugins");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/classify");
+}
+
+use arcinfo;
+use colcfg;
+use util;
+use parsargv;
+
+sub print_usage {
+    print STDERR "\n";
+    print STDERR "mirror.pl: Uses w3mir or wget to sync a collections import data\n";
+    print STDERR "           with a website.\n\n";
+    print STDERR "  usage: $0 [options] collection-name\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -verbosity number      0=none, 3=lots\n";
+    print STDERR "   -importdir directory   Where to place the mirrored material\n";
+}
+
+
+&main ();
+
+sub main {
+    my ($verbosity, $importdir, $etcdir, 
+        $collection, $configfilename, $collectcfg);
+
+    if (!parsargv::parse(\@ARGV, 
+			 'verbosity/\d+/2', \$verbosity,
+			 'importdir/.*/', \$importdir )) {
+	&print_usage();
+	die "\n";
+    }
+
+    # get and check the collection name
+    if (($collection = &util::use_collection(@ARGV)) eq "") {
+	&print_usage();
+	die "\n";
+    }
+
+    # get the etc directory
+    $etcdir = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "etc");
+    
+    # check the collection configuration file for options
+    my $interval = 0;
+    $configfilename = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, 
+					   "etc", "collect.cfg");
+    if (-e $configfilename) {
+	$collectcfg = &colcfg::read_collect_cfg ($configfilename);
+	if (defined $collectcfg->{'importdir'} && $importdir eq "") {
+	    $importdir = $collectcfg->{'importdir'};
+	}
+    } else {
+	die "Couldn't find the configuration file $configfilename\n";
+    }
+    
+    # fill in the default import directories if none
+    # were supplied, turn all \ into / and remove trailing /
+    $importdir = "$ENV{'GSDLCOLLECTDIR'}/import" if $importdir eq "";
+    $importdir =~ s/[\\\/]+/\//g;
+    $importdir =~ s/\/$//;
+
+    # make sure there is an import directory
+    if (! -e "$importdir") {
+	&util::mk_dir($importdir);
+    }
+
+    # if w3mir.cfg exists, 
+    # then we are using w3mirror to mirror the remote site
+    if (-e "$etcdir/w3mir.cfg") {
+
+	# run the mirror program from the import directory
+	my  $cmd = "cd $importdir; ";
+	$cmd .= "perl -S gsw3mir.pl -cfgfile $etcdir/w3mir.cfg";
+	# print "\n$cmd\n";
+	`$cmd`;
+
+    } 
+
+    # if wget.cfg and wget.url both exist, 
+    # then we are using GNU wget to mirror the remote site
+    elsif ((-e "$etcdir/wget.cfg") && (-e "$etcdir/wget.url")) {
+	$ENV{WGETRC} = "$etcdir/wget.cfg";
+	my $cmd = "perl -S gsWget.pl --input-file=$etcdir/wget.url --directory-prefix=$importdir";
+	system($cmd);
+    }
+
+    # otherwise, there are no mirror copnfiguration files
+    else {
+	die "Couldn't find the mirror configuration files in $etcdir\n";
+    }
+
+
+}
+
+
+
+
+
+
Index: /gsdl/stable/bin/script/mkcol.pl
===================================================================
--- /gsdl/stable/bin/script/mkcol.pl	(revision 20131)
+++ /gsdl/stable/bin/script/mkcol.pl	(revision 20131)
@@ -0,0 +1,426 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# mkcol.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will setup a new collection from a model one. It does this by
+# copying the model, moving files to have the correct names, and replacing
+# text within the files to match the parameters.
+
+package mkcol;
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use parse2;
+use util;
+use cfgread;
+use gsprintf 'gsprintf';
+use printusage;
+
+use strict;
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+
+my $public_list = 
+    [ { 'name' => "true",
+	'desc' => "{mkcol.public.true}"},
+      { 'name' => "false",
+	'desc' => "{mkcol.public.false}"} 
+      ];
+
+my $win31compat_list = 
+    [ { 'name' => "true",
+	'desc' => "{mkcol.win31compat.true}"},
+      { 'name' => "false",
+	'desc' => "{mkcol.win31compat.false}"} 
+      ];
+
+my $arguments =
+    [ { 'name' => "creator",
+	'desc' => "{mkcol.creator}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "optionfile",
+	'desc' => "{mkcol.optionfile}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "maintainer",
+	'desc' => "{mkcol.maintainer}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "gs3mode",
+	'desc' => "{mkcol.gs3mode}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "group",
+	'desc' => "{mkcol.group}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "collectdir",
+	'desc' => "{mkcol.collectdir}",
+	'type' => "string",
+	'reqd' => "no" }, # For gs3, this collectdir must be provided.
+      { 'name' => "site",
+	'desc' => "{mkcol.site}",
+	'type' => "string",
+	'reqd' => "no" }, # For gs3, this collectdir must be provided.
+      { 'name' => "public",
+	'desc' => "{mkcol.public}",
+	'type' => "enum",
+	'deft' => "true",
+	'list' => $public_list,
+	'reqd' => "no" },
+      { 'name' => "title",
+	'desc' => "{mkcol.title}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "about",
+	'desc' => "{mkcol.about}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "plugin",
+	'desc' => "{mkcol.plugin}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "quiet",
+	'desc' => "{mkcol.quiet}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "win31compat",
+	'desc' => "{mkcol.win31compat}",
+	'type' => "enum",
+	'deft' => "false",
+	'list' => $win31compat_list,
+	'reqd' => "no" },
+      { 'name' => "gli",
+	'desc' => "",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "xml",
+	'desc' => "{scripts.xml}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" }
+      ];
+
+my $options = { 'name' => "mkcol.pl",
+		'desc' => "{mkcol.desc}",
+		'args' => $arguments };
+
+# options
+my ($creator, $optionfile, $maintainer, $gs3mode, $group, $collectdir, $site, 
+    $public, 
+    $title, $about, $plugin, $quiet, $language, $win31compat, $gli);
+
+#other variables
+my ($collection, $capcollection, 
+    $collection_tail, $capcollection_tail, 
+    $pluginstring, @plugin);
+
+&main();
+
+
+sub traverse_dir
+{
+    my ($modeldir, $coldir) = @_;
+    my ($newfile, @filetext);
+
+    if (!(-e $coldir)) {
+	
+
+	my $store_umask = umask(0002);
+	my $mkdir_ok = mkdir ($coldir, 0777);
+	umask($store_umask);
+
+	if (!$mkdir_ok) 
+	{
+	    die "$!";
+	}
+    }
+
+    opendir(DIR, $modeldir) ||
+	(&gsprintf(STDERR, "{common.cannot_read}\n", $modeldir) && die);
+    my @files = grep(!/^(\.\.?|CVS|\.svn)$/, readdir(DIR));
+    closedir(DIR);
+
+    foreach my $file (@files)
+    {
+	if ($file =~ /^macros$/) {
+	    
+	    # don't want macros folder for gs3mode
+	    next if $gs3mode;
+	}
+	if ($file =~ /^import$/) {
+	    # don't want import for group
+	    next if $group;
+	}
+	
+	my $thisfile = &util::filename_cat ($modeldir, $file);
+
+	if (-d $thisfile) {
+	    my $colfiledir = &util::filename_cat ($coldir, $file);
+	    traverse_dir ($thisfile, $colfiledir);
+
+	} else {
+
+	    next if ($file =~ /~$/);
+
+	    my $destfile = $file;
+	    $destfile =~ s/^modelcol/$collection/;
+	    $destfile =~ s/^MODELCOL/$capcollection/;
+
+	    # There are three configuration files in modelcol directory:
+	    # collect.cfg, group.cfg and collectionConfig.xml.
+	    # If it is gs2, copy relevant collect.cfg or group.cfg file; if gs3, copy collectionConfig.xml.
+	    
+	    if ($file =~ /^collect\.cfg$/) {
+		next if ($gs3mode || $group);
+	    }
+	    elsif ($file =~ /^group\.cfg$/) {
+		next unless $group;
+		$destfile =~ s/group\.cfg/collect\.cfg/;
+	    }
+	    elsif ($file =~ /^collectionConfig\.xml$/) {
+		next unless $gs3mode;
+	    }
+	    
+	    &gsprintf(STDOUT, "{mkcol.doing_replacements}\n", $destfile)
+		unless $quiet;
+	    $destfile = &util::filename_cat ($coldir, $destfile);
+
+	    open (INFILE, $thisfile) || 
+		(&gsprintf(STDERR, "{common.cannot_read_file}\n", $thisfile) && die);
+	    open (OUTFILE, ">$destfile") ||
+		(&gsprintf(STDERR, "{common.cannot_create_file}\n", $destfile) && die);
+
+	    while (defined (my $line = <INFILE>)) {
+		$line =~ s/\*\*collection\*\*/$collection_tail/g;
+		$line =~ s/\*\*COLLECTION\*\*/$capcollection_tail/g;
+		$line =~ s/\*\*creator\*\*/$creator/g;
+		$line =~ s/\*\*maintainer\*\*/$maintainer/g;
+		$line =~ s/\*\*public\*\*/$public/g;
+		$line =~ s/\*\*title\*\*/$title/g;
+		$line =~ s/\*\*about\*\*/$about/g;
+		if (!$gs3mode) {
+		   $line =~ s/\*\*plugins\*\*/$pluginstring/g;
+		 }
+
+		print OUTFILE $line;
+	    }
+	    
+	    close (OUTFILE);
+	    close (INFILE);
+	}
+    }
+}
+
+
+sub main {
+    
+    my $xml = 0;
+    
+
+    my $hashParsingResult = {};
+    my $intArgLeftinAfterParsing = parse2::parse(\@ARGV,$arguments,$hashParsingResult,"allow_extra_options");
+    
+    # If parse returns -1 then something has gone wrong
+    if ($intArgLeftinAfterParsing == -1)
+    {
+	&PrintUsage::print_txt_usage($options, "{mkcol.params}");
+	die "\n";
+    }
+    
+    foreach my $strVariable (keys %$hashParsingResult)
+    {
+	eval "\$$strVariable = \$hashParsingResult->{\"\$strVariable\"}";
+    }
+
+    # If $language has been specified, load the appropriate resource bundle
+    # (Otherwise, the default resource bundle will be loaded automatically)
+    if ($language && $language =~ /\S/) {
+	&gsprintf::load_language_specific_resource_bundle($language);
+    }
+
+    if ($xml) {
+	&PrintUsage::print_xml_usage($options);
+	print "\n";
+	return;
+    }
+
+    if ($gli) { # the gli wants strings to be in UTF-8
+	&gsprintf::output_strings_in_UTF8; 
+    }
+
+    # now check that we had exactly one leftover arg, which should be 
+    # the collection name. We don't want to do this earlier, cos 
+    # -xml arg doesn't need a collection name
+    # Or if the user specified -h, then we output the usage also
+    if ($intArgLeftinAfterParsing != 1 || (@ARGV && $ARGV[0] =~ /^\-+h/))
+    {
+	&PrintUsage::print_txt_usage($options, "{mkcol.params}");
+	die "\n";
+    }
+
+    if ($optionfile =~ /\w/) {
+	open (OPTIONS, $optionfile) ||
+	    (&gsprintf(STDERR, "{common.cannot_open}\n", $optionfile) && die);
+	my $line = [];
+	my $options = [];
+	while (defined ($line = &cfgread::read_cfg_line ('mkcol::OPTIONS'))) {
+	    push (@$options, @$line);
+	}
+	close OPTIONS;
+	my $optionsParsingResult = {};
+	if (parse2::parse($options,$arguments,$optionsParsingResult) == -1) {
+	    &PrintUsage::print_txt_usage($options, "{mkcol.params}");
+	    die "\n";
+	}
+	    
+	foreach my $strVariable (keys %$optionsParsingResult)
+	{
+	    eval "\$$strVariable = \$optionsParsingResult->{\"\$strVariable\"}";
+	}
+    }
+    
+    # load default plugins if none were on command line
+    if (!scalar(@plugin)) {
+	@plugin = (ZIPPlugin,GreenstoneXMLPlugin,TextPlugin,HTMLPlugin,EmailPlugin,
+		   PDFPlugin,RTFPlugin,WordPlugin,PostScriptPlugin,PowerPointPlugin,ExcelPlugin,ImagePlugin,ISISPlugin,NulPlugin,MetadataXMLPlugin,ArchivesInfPlugin,DirectoryPlugin);
+    }
+
+    # get and check the collection name
+    ($collection) = @ARGV;
+
+    # get capitalised version of the collection
+    $capcollection = $collection;
+    $capcollection =~ tr/a-z/A-Z/;
+
+    $collection_tail = &util::get_dirsep_tail($collection);
+    $capcollection_tail = &util::get_dirsep_tail($capcollection);
+
+
+    if (!defined($collection)) {
+	&gsprintf(STDOUT, "{mkcol.no_colname}\n");
+	&PrintUsage::print_txt_usage($options, "{mkcol.params}");
+	die "\n";
+    }
+
+    if (($win31compat eq "true") && (length($collection_tail)) > 8) {
+	&gsprintf(STDOUT, "{mkcol.long_colname}\n");
+	die "\n";
+    }
+
+    if ($collection eq "modelcol") {
+	&gsprintf(STDOUT, "{mkcol.bad_name_modelcol}\n");
+	die "\n";
+    }
+
+    if ($collection_tail eq "CVS") {
+	&gsprintf(STDOUT, "{mkcol.bad_name_cvs}\n");
+	die "\n";
+    }
+
+    if ($collection_tail eq ".svn") {
+	&gsprintf(STDOUT, "{mkcol.bad_name_svn}\n");
+	die "\n";
+    }
+
+    if (defined($creator) && (!defined($maintainer) || $maintainer eq "")) {
+	$maintainer = $creator;
+    }
+
+    $public = "true" unless defined $public;
+
+    if (!defined($title) || $title eq "") {
+	$title = $collection_tail;
+    }
+
+    if ($gs3mode && $group) {
+	&gsprintf(STDERR,"{mkcol.group_not_valid_in_gs3}\n");
+	die "\n";
+    }
+
+    # get the strings to include.
+    $pluginstring = "";
+    foreach my $plug (@plugin) {
+	$pluginstring .= "plugin         $plug\n";
+    }
+
+    my $mdir = &util::filename_cat ($ENV{'GSDLHOME'}, "collect", "modelcol");
+    my $cdir;
+    if (defined $collectdir && $collectdir =~ /\w/) {
+	if (!-d $collectdir) {
+	    &gsprintf(STDOUT, "{mkcol.no_collectdir}\n", $collectdir);
+	    die "\n";
+	}
+	$cdir = &util::filename_cat ($collectdir, $collection);
+    } else {
+      if (!$gs3mode) {
+	$cdir = &util::filename_cat ($ENV{'GSDLHOME'}, "collect", $collection);
+      }else {
+	  if (defined $site && $site =~ /\w/) {
+	      die "GSDL3HOME not set\n" unless defined $ENV{'GSDL3HOME'};
+
+	      $cdir  = &util::filename_cat($ENV{'GSDL3HOME'}, "sites", $site, "collect");
+	      if (!-d $cdir) {
+		  &gsprintf(STDOUT, "{mkcol.no_collectdir}\n", $cdir);
+		  die "\n";
+	      }
+	      $cdir = &util::filename_cat ($cdir, $collection);
+	  } else {
+	    &gsprintf(STDOUT, "{mkcol.no_collectdir_specified}\n");
+	    die "\n";
+	}
+      }
+    }
+
+    # make sure the model collection exists
+    (&gsprintf(STDERR, "{mkcol.cannot_find_modelcol}\n", $mdir) && die) unless (-d $mdir);
+
+    # make sure this collection does not already exist
+    if (-e $cdir) {
+	&gsprintf(STDOUT, "{mkcol.col_already_exists}\n");
+	die "\n";
+    }
+
+    # start creating the collection
+    &gsprintf(STDOUT, "\n{mkcol.creating_col}...\n", $collection)
+	unless $quiet;
+
+    &traverse_dir ($mdir, $cdir);
+    &gsprintf(STDOUT, "\n{mkcol.success}\n", $cdir)
+	unless $quiet;
+}
+
+
Index: /gsdl/stable/bin/script/nightly.pl
===================================================================
--- /gsdl/stable/bin/script/nightly.pl	(revision 20131)
+++ /gsdl/stable/bin/script/nightly.pl	(revision 20131)
@@ -0,0 +1,102 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# nightly.pl
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program will find all the collections under $GSDLHOME/collect
+# and use the update.pl script to update them all.  It should be run
+# every night to keep mirror collections up-to-date.
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugins");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/classify");
+}
+
+use arcinfo;
+use colcfg;
+use util;
+use parsargv;
+
+sub print_usage {
+    print STDERR "\n";
+    print STDERR "nightly.pl: Attempts to update all Greenstone collections found on\n";
+    print STDERR "            the local filesystem by calling update.pl for each of\n";
+    print STDERR "            them.\n\n";
+    print STDERR "  usage: $0 [options]\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -verbosity number      0=none, 3=lots\n";
+    print STDERR "   -importdir directory   Where to place the mirrored material\n";
+    print STDERR "   -archivedir directory  Where the converted material ends up\n";
+}
+
+
+&main ();
+
+sub main {
+    my ($verbosity, $collectdir, $name, $collection);
+
+    if (!parsargv::parse(\@ARGV, 
+			 'verbosity/\d+/2', \$verbosity )) {
+	&print_usage();
+	die "\n";
+    }
+
+
+    # get the contents of the collect directory
+    $collectdir =  &util::filename_cat($ENV{'GSDLHOME'}, "collect");
+    opendir(CDIR, $collectdir) || die "Cannot open $collectdir: $!";
+    my @files = readdir(CDIR);
+    closedir CDIR;
+
+
+    # update each collection
+    foreach $name (@files) {
+
+	$collection = &util::filename_cat($collectdir, $name);
+
+	# igore entries for "." and ".."
+	next unless ($name =~ /[^\.]/);
+
+	# ignore modelcol
+	next if ($name eq "modelcol");
+
+	# ignore entries that are not directories
+	next unless (-d $collection);
+
+	# ignore directories that do not have a subdir called etc
+	next unless (-d &util::filename_cat($collection, "etc"));
+
+	print "Updating: $name\n";
+	print `update.pl $name`;
+	
+    }
+
+}
Index: /gsdl/stable/bin/script/pdfpstoimg.pl
===================================================================
--- /gsdl/stable/bin/script/pdfpstoimg.pl	(revision 20131)
+++ /gsdl/stable/bin/script/pdfpstoimg.pl	(revision 20131)
@@ -0,0 +1,155 @@
+#!/usr/bin/perl -w
+
+
+###########################################################################
+#
+# pdfpstoimg.pl -- convert PDF or PS documents to various types of Image format
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+# pdfpstoimg.pl is a wrapper for running the ImageMagick 'convert' utility 
+# which converts PDF and PS documents to various types of image (e.g. PNG, 
+# GIF, JPEG format). We then create an item file to join the images together
+# into a document. The item file will be processed by PagedImagePlugin
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use parsargv;
+use util;
+use Cwd;
+use File::Basename;
+
+sub print_usage {
+    print STDERR  
+	("pdfpstoimg.pl wrapper for converting PDF or PS files to a series of images.\n",
+	 "Usage: pdfpstoimg.pl [options] <PDF/PS-file> <output-filestem>>\n",
+	 "Options:\n",
+	 "\t-convert_to\toutput image type (gif, jpg, png) \n"
+	 );
+    exit (1);
+}
+
+sub main {
+    my (@ARGV) = @_;
+    my ($convert_to);
+    
+    # read command-line arguments so that
+    # you can change the command in this script
+    if (!parsargv::parse(\@ARGV,
+			 'convert_to/.*/^', \$convert_to,
+			 )) {
+    	print_usage();
+    }
+    
+    # Make sure the user has specified both input and output files
+    if (scalar(@ARGV) != 2) {
+	print_usage();
+    }
+    
+    my $input_filename = $ARGV[0];
+    my $output_filestem = $ARGV[1];
+    
+    # test that the directories exist to create the output file, or
+    # we should exit immediately. 
+    &util::mk_dir($output_filestem) if (!-e $output_filestem);
+	    
+    my @dir = split (/(\/|\\)/, $input_filename);
+    my $input_basename = pop(@dir);
+    $input_basename =~ s/\.(pdf|ps)$//i;
+    my $dir = join ("", @dir);
+
+    if (!-r $input_filename) {
+	print STDERR "Error: unable to open $input_filename for reading\n";
+	exit(1);
+    }
+    # don't include path on windows (to avoid having to play about
+    # with quoting when GSDLHOME might contain spaces) but assume
+    # that the PATH is set up correctly.
+    $cmd = "convert";
+
+    my $output_filename = &util::filename_cat($output_filestem, $input_basename);
+    if ($convert_to eq "gif") {
+	$cmd .= " \"$input_filename\" \"$output_filename-%02d.$convert_to\"";
+    } else {
+	$cmd .= " \"$input_filename\" \"$output_filename.$convert_to\"";
+    }	
+ 
+    # system() returns -1 if it can't run, otherwise it's $cmds ret val.
+    # note we return 0 if the file is "encrypted"
+    $!=0;
+    if (system($cmd)!=0) {
+	print STDERR "Convert error for $input_filename $!\n";
+	# leave these for gsConvert.pl...
+	#&util::rm("$output_filestem.text") if (-e "$output_filestem.text");
+	#&util::rm("$output_filestem.err") if (-e "$output_filestem.err");
+	return 1;
+    } else {
+	# command execute successfully
+	create_itemfile($output_filestem, $input_basename, $convert_to);
+    }
+    return 0;
+}
+
+sub create_itemfile
+{
+    my ($output_dir, $convert_basename, $convert_to) = @_;
+    opendir(DIR, $output_dir) || die "can't opendir $output_dir: $!";  
+    my $item_file = $output_dir."/".$convert_basename.".item";
+    open(FILE,">$item_file");
+    
+    print FILE "<PagedDocument>\n";
+
+    my $page_num = "";
+    @dir_files = grep {-f "$output_dir/$_"} readdir(DIR);
+
+    # Sort files in the directory by page_num    
+    sub page_number {
+	my ($dir) = @_;
+	my ($pagenum) =($dir =~ m/^.*[-\.](\d+)(\.(jpg|gif|png))?$/i);
+	
+	$pagenum = 1 unless defined $pagenum;
+	return $pagenum;
+    }
+
+    # sort the files in the directory in the order of page_num rather than lexically. 
+    @dir_files = sort { page_number($a) <=> page_number($b) } @dir_files;
+
+    foreach my $file (@dir_files){
+	$page_num = page_number($file)+1; # image numbers start at 0, so add 1
+	if ($file !~ /\.item/i){
+	    print FILE "   <Page pagenum=\"$page_num\" imgfile=\"$file\" txtfile=\"\"/>\n";
+	} 
+    }
+
+    print FILE "</PagedDocument>\n";
+    closedir DIR;
+    return "";
+}
+
+# indicate our error status, 0 = success
+exit (&main(@ARGV));
+
+
+
Index: /gsdl/stable/bin/script/pdftohtml.pl
===================================================================
--- /gsdl/stable/bin/script/pdftohtml.pl	(revision 20131)
+++ /gsdl/stable/bin/script/pdftohtml.pl	(revision 20131)
@@ -0,0 +1,267 @@
+#!/usr/bin/perl -w
+
+
+###########################################################################
+#
+# pdftohtml.pl -- convert PDF documents to HTML format
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# pdftohtml.pl is a wrapper for running pdftohtml utility which converts
+# PDF documents to HTML, and converts images to PNG format for display in
+# the HTML pages generated
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use parsargv;
+use util;
+use Cwd;
+use File::Basename;
+
+sub print_usage {
+# note - we don't actually ever use most of these options...
+print STDERR  
+    ("pdftohtml.pl wrapper for pdftohtml.\n",
+     "Usage: pdftohtml [options] <PDF-file> <html-file>\n",
+     "Options:\n",
+     "\t-i\tignore images (don't extract)\n",
+     "\t-a\tallow images only (continue even if no text is present)\n",
+     "\t-c\tproduce complex output (requires ghostscript)\n",
+     "\t-hidden\tExtract hidden text\n",
+     "\t-zoom\tfactor by which to zoom the PDF (only useful if -c is set)\n"
+     );
+exit (1);
+}
+
+sub main {
+    my (@ARGV) = @_;
+    my ($allow_no_text, $ignore_images, $complex, $zoom, $hidden);
+    
+    # read command-line arguments so that
+    # you can change the command in this script
+    if (!parsargv::parse(\@ARGV,
+			 'a', \$allow_no_text,
+			 'i', \$ignore_images,
+			 'c', \$complex,
+			 'hidden', \$hidden,
+			 'zoom/\d+/2', \$zoom,
+			 ))
+    {
+	print_usage();
+    }
+
+    # Make sure the input file exists and can be opened for reading
+    if (scalar(@ARGV) != 2) {
+	print_usage();
+    }
+
+    my $input_filename = $ARGV[0];
+    my $output_filestem = $ARGV[1];
+
+    $output_filestem =~ s/\.html$//i; # pdftohtml adds this suffix
+
+    # test that the directories exist to create the output file, or
+    # we should exit immediately. (File:: is included by util.pm)
+    my $output_dir =  File::Basename::dirname($output_filestem);
+    if (! -d $output_dir || ! -w $output_dir) {
+	die "pdftohtml.pl: cannot write to directory $output_dir\n";
+    }
+
+    my @dir = split (/(\/|\\)/, $input_filename);
+    my $input_basename = pop(@dir);
+    $input_basename =~ s/\.pdf//i;
+    my $dir = join ("", @dir);
+
+    if (!-r $input_filename) {
+	print STDERR "Error: unable to open $input_filename for reading\n";
+	exit(1);
+    }
+
+    # Heuristical code removed due to pdftohtml being "fixed" to not
+    # create bitmaps for each char in some pdfs. However, this means we
+    # now create .html files even if we can't extract any text. We should
+    # check for that now instead someday...
+
+
+    # formulate the command
+    my $cmd = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "pdftohtml");
+
+    # don't include path on windows (to avoid having to play about
+    # with quoting when GSDLHOME might contain spaces) but assume
+    # that the PATH is set up correctly.
+    $cmd = "pdftohtml" if ($ENV{'GSDLOS'} =~ /^windows$/);
+
+    $cmd .= " -i" if ($ignore_images);
+    $cmd .= " -c" if ($complex);
+    $cmd .= " -hidden" if ($hidden);
+    $cmd .= " -zoom $zoom";
+    $cmd .= " -noframes -p -enc UTF-8 \"$input_filename\" \"$output_filestem.html\"";
+
+# system() returns -1 if it can't run, otherwise it's $cmds ret val.
+    # note we return 0 if the file is "encrypted"
+    $!=0;
+    if (system($cmd)!=0) {
+	print STDERR "pdftohtml error for $input_filename $!\n";
+	# leave these for gsConvert.pl...
+	#&util::rm("$output_filestem.text") if (-e "$output_filestem.text");
+	#&util::rm("$output_filestem.err") if (-e "$output_filestem.err");
+	return 1;
+    }
+
+    if (! -e "$output_filestem.html") {
+	return 1;
+    }
+
+# post-process to remove </b><b> and </i><i>, as these break up
+# words, screwing up indexing and searching.
+# At the same time, check that our .html file has some textual content.
+    &util::mv("$output_filestem.html","$output_filestem.html.tmp");
+    $!=0;
+    open INFILE, "$output_filestem.html.tmp" ||
+	die "Couldn't open file: $!";
+    open OUTFILE, ">$output_filestem.html" ||
+	die "Couldn't open file for writing: $!";
+    my $line;
+    my $seen_textual_content=$allow_no_text;
+    # check for unicode byte-order marker at the start of the file
+    $line = <INFILE>;
+    $line =~ s#\376\377##g;
+    while ($line) {
+	$line =~ s#</b><b>##g;
+	$line =~ s#</i><i>##g;
+	$line =~ s#\\#\\\\#g; # until macro language parsing is fixed...
+# check for any extracted text
+	if ($seen_textual_content == 0) {
+	    my $tmp_line=$line;
+	    $tmp_line =~ s/<[^>]*>//g;
+	    $tmp_line =~ s/Page\s\d+//;
+	    $tmp_line =~ s/\s*//g;
+	    if ($tmp_line ne "") {
+		$seen_textual_content=1;
+	    }
+	    # special - added to remove the filename from the title
+	    # this should be in the header, before we see "textual content"
+	    if ($line =~ m@<title>(.*?)</title>@i) {
+		my $title=$1;
+		
+		# is this title the name of a filename?
+		if (-r "$title.pdf" || -r "$title.html") {
+		    # remove the title
+		    $line =~ s@<title>.*?</title>@<title></title>\n<META NAME=\"filename\" CONTENT=\"$title\">@i;
+		}
+	    }
+	}
+
+	# relative hrefs to own document...
+	$line =~ s@href=\"$input_basename\.html\#@href=\"\#@go;
+# escape underscores, but not if they're inside tags (eg img/href names)
+	my $inatag = 0; # allow multi-line tags
+	if ($line =~ /_/) {
+	    my @parts=split('_',$line);
+	    my $lastpart=pop @parts;
+	    foreach my $part (@parts) {
+		if ($part =~ /<[^>]*$/) { # if we're starting a tag...
+		    $inatag=1;
+		} elsif ($part =~ />[^<]*$/) { # closing a tag
+		    $inatag=0;
+		}
+		if ($inatag) {
+		    $part.='_';
+		} else {
+		    $part.="&#95;";
+		}
+	    }
+	    $line=join('',@parts,$lastpart);
+	}
+
+	print OUTFILE $line;
+	$line = <INFILE>;
+    }
+    close INFILE;
+    close OUTFILE;
+    &util::rm("$output_filestem.html.tmp");
+
+    # Need to convert images from PPM format to PNG format
+    my @images;
+
+    my $directory=$output_filestem;
+    $directory =~ s@[^\/]*$@@;    # assume filename has no embedded slashes...
+    # newer versions of pdftohtml don't seem to do images this way anymore?
+    if (open (IMAGES, "${directory}images.log") || 
+	open (IMAGES, "${directory}image.log")) {
+	while (<IMAGES>) {
+	    push (@images, $_);
+	}
+	close IMAGES;
+	&util::rm("${directory}image.log") if (-e "${directory}image.log");
+
+    }
+
+    # no need to go any further if there is no text extracted from pdf.
+    if ($seen_textual_content == 0) {
+	print STDERR "Error: PDF contains no extractable text\n";
+	# remove images...
+	for $image (@images) {
+	    chomp($image);
+	    &util::rm("${directory}$image");
+	}
+	return 1;
+    }
+
+
+
+    for $image (@images) {
+	chomp($image);
+	my $cmd = "";
+	if ($ENV{'GSDLOS'} =~ /^windows/i) {
+	    $cmd = "pnmtopng \"${directory}$image\"";
+	    if (system($cmd)!=0) {
+		print STDERR "Error executing $cmd\n";
+		#return 1; # not sure about whether to leave this one in or take it out
+		next;
+	    }
+	} else {
+	    my @nameparts = split(/\./, $image);
+	    my $image_base = shift(@nameparts);
+	    $cmd = "pnmtopng \"${directory}$image\" > \"${directory}$image_base.png\" 2>/dev/null";
+	    if (system($cmd)!=0) {
+		$cmd = "convert \"${directory}$image\" \"${directory}$image_base.png\" 2>/dev/null";
+		if (system($cmd)!=0) {
+		    print STDERR "Cannot convert $image into PNG format (tried `pnmtopng' and `convert')...\n";
+		    #return 1; # not sure about whether to leave this one in or take it out
+		    next;
+		}
+	    }
+	}
+	&util::rm($image);
+    }
+
+    return 0;
+}
+
+# indicate our error status, 0 = success
+exit (&main(@ARGV));
+
Index: /gsdl/stable/bin/script/ping.pl
===================================================================
--- /gsdl/stable/bin/script/ping.pl	(revision 20131)
+++ /gsdl/stable/bin/script/ping.pl	(revision 20131)
@@ -0,0 +1,74 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# ping.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan/Ping");
+}
+
+
+require LWP::UserAgent;
+use parsargv;
+
+&main();
+
+sub print_usage {
+    print STDERR "\n";
+    print STDERR "ping.pl: Ping http or ftp URL to see if it's accessable.\n\n";
+    print STDERR "  usage: $0 [options] URL\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -quiet   Quiet operation\n\n";
+}
+
+sub main {
+
+    my ($quiet);
+    if (!parsargv::parse(\@ARGV, 'quiet', \$quiet)) {
+	&print_usage();
+	die "\n";
+    }
+
+    if (!scalar(@ARGV)) {
+	print STDERR "ERROR: no URL was provided\n";
+	die "\n";
+    }
+
+    $ua = new LWP::UserAgent;
+    $ua->timeout(60);
+    $request = new HTTP::Request('HEAD', $ARGV[0]);
+    $response = $ua->request($request);
+    
+    if ($response->is_success) {
+	print STDERR "$ARGV[0] ping succeeded\n" unless $quiet;
+	exit 0;
+    } else {
+	print STDERR "$ARGV[0] ping failed\n" unless $quiet;
+	exit 1;
+    }
+}
Index: /gsdl/stable/bin/script/pluginfo.pl
===================================================================
--- /gsdl/stable/bin/script/pluginfo.pl	(revision 20131)
+++ /gsdl/stable/bin/script/pluginfo.pl	(revision 20131)
@@ -0,0 +1,237 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# pluginfo.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# This program will print info about a plugin
+
+use strict;
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugins");
+
+    if (defined $ENV{'GSDLEXTS'}) {
+	my @extensions = split(/:/,$ENV{'GSDLEXTS'});
+	foreach my $e (@extensions) {
+	    my $ext_prefix = "$ENV{'GSDLHOME'}/ext/$e";
+
+	    unshift (@INC, "$ext_prefix/perllib");
+	    unshift (@INC, "$ext_prefix/perllib/cpan");
+	    unshift (@INC, "$ext_prefix/perllib/plugins");
+	    unshift (@INC, "$ext_prefix/perllib/plugouts");
+	    unshift (@INC, "$ext_prefix/perllib/classify");
+	}
+    }
+}
+
+use plugin;
+use util;
+use gsprintf;
+use printusage;
+use parse2;
+
+my $arguments =
+    [ { 'name' => "collection",
+	'desc' => "{pluginfo.collection}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "xml",
+	'desc' => "{scripts.xml}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "listall",
+	'desc' => "{scripts.listall}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "describeall",
+	'desc' => "{scripts.describeall}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no" } ];
+
+my $options = { 'name' => "pluginfo.pl",
+		'desc' => "{pluginfo.desc}",
+		'args' => $arguments };
+
+sub gsprintf
+{
+    return &gsprintf::gsprintf(@_);
+}
+
+
+sub main {
+    my $collection = "";
+    my $xml = 0;
+    my $listall = 0;
+    my $describeall = 0;
+    my ($language, $encoding);
+
+    my $hashParsingResult = {};
+    # general options available to all plugins
+    my $unparsed_args = parse2::parse(\@ARGV,$arguments,$hashParsingResult,"allow_extra_options");
+    # parse returns -1 if an error occurred
+    if ($unparsed_args == -1) {
+	
+	PrintUsage::print_txt_usage($options, "{pluginfo.params}");
+ 	die "\n";
+    }
+    
+    foreach my $strVariable (keys %$hashParsingResult)
+    {
+	my $value = $hashParsingResult->{$strVariable};
+	# test to make sure the variable name is 'safe'
+	if ($strVariable !~ /^\w+$/) {
+ 	    die "variable name '$strVariable' isn't safe!";
+	}
+	eval "\$$strVariable = \$value";
+    }
+
+    # if language wasn't specified, see if it is set in the environment
+    # (LC_ALL or LANG)
+    if (!$language && ($_=$ENV{'LC_ALL'} or $_=$ENV{'LANG'})) {
+	m/^([^\.]+)\.?(.*)/;
+	$language=$1;
+	$encoding=$2; # might be undef...
+# gsprintf::load_language* thinks "fr" is completely different to "fr_FR"...
+	$language =~ s/_.*$//;
+    }
+
+    # If $language has been set, load the appropriate resource bundle
+    # (Otherwise, the default resource bundle will be loaded automatically)
+    if ($language) {
+	gsprintf::load_language_specific_resource_bundle($language);
+	if ($encoding) {
+	    $encoding =~ tr/-/_/;
+	    $encoding = lc($encoding);
+	    $encoding =~ s/utf_8/utf8/; # special
+	    $gsprintf::specialoutputencoding=$encoding;
+	}
+    }
+
+    # If there is not exactly 1 argument left (plugin name), then the arguments were wrong
+    # If the user specified -h, then we output the usage also
+    if((@ARGV && $ARGV[0] =~ /^\-+h/) )
+    {
+	PrintUsage::print_txt_usage($options, "{pluginfo.params}");  
+        die "\n";
+    }
+
+    # If there is not exactly 1 argument left (plugin name), then the arguments were wrong (apart from if we had listall or describeall set)
+    if ($listall == 0 && $describeall ==0 && $unparsed_args == 0) {
+	gsprintf(STDERR, "{pluginfo.no_plugin_name}\n\n");
+	PrintUsage::print_txt_usage($options, "{pluginfo.params}", 1);
+	die "\n";
+    }
+
+    # we had some arguments that we weren't expecting
+    if ($unparsed_args > 1) {
+	pop(@ARGV); # assume that the last arg is the plugin name
+	gsprintf(STDERR, "{common.invalid_options}\n\n", join (',', @ARGV));
+	PrintUsage::print_txt_usage($options, "{pluginfo.params}", 1);
+	die "\n";
+    }
+	
+    my $plugin = shift (@ARGV);
+    if (defined $plugin) {
+	$plugin =~ s/\.pm$//; # allow xxxPlugin.pm as the argument
+    }
+
+    if ($collection ne "") {
+	$ENV{'GSDLCOLLECTDIR'} = &util::filename_cat ($ENV{'GSDLHOME'}, "collect", $collection);
+    } else {
+	$ENV{'GSDLCOLLECTDIR'} = $ENV{'GSDLHOME'};
+    }
+
+    if ($listall || $describeall) {
+	my $plugins_dir = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "perllib", "plugins");
+	my @plugin_list = ();
+	if (opendir (INDIR, $plugins_dir)) {
+	    @plugin_list = grep (/Plugin\.pm$/, readdir (INDIR));
+	    closedir (INDIR);
+	}
+
+	if ((defined $ENV{'GSDLEXTS'}) && ($collection eq "")) {
+	    my @extensions = split(/:/,$ENV{'GSDLEXTS'});
+	    foreach my $e (@extensions) {
+		my $ext_prefix = &util::filename_cat($ENV{'GSDLHOME'},"ext",$e);
+		my $ext_plugins_dir = &util::filename_cat($ext_prefix, "perllib", "plugins");
+
+		if (opendir (INDIR, $ext_plugins_dir)) {
+		    my @ext_plugin_list = grep (/Plugin\.pm$/, readdir (INDIR));
+		    closedir (INDIR);
+
+		    push(@plugin_list,@ext_plugin_list);
+		}
+
+	    }
+	}
+
+	print STDERR "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+	print STDERR "<PluginList length=\"" . scalar(@plugin_list) . "\">\n";
+	foreach my $plugin (@plugin_list) {
+	    $plugin =~ s/\.pm$//;
+	    my $plugobj = &plugin::load_plugin_for_info ($plugin);
+	    if ($describeall) {
+		$plugobj->print_xml_usage(0);
+	    }
+	    else {
+		$plugobj->print_xml_usage(0, 1);
+	    }
+	}
+	print STDERR "</PluginList>\n";
+    }
+    else {
+	&print_single_plugin($plugin, $xml, 1);
+    }
+}
+
+
+sub print_single_plugin {
+    my ($plugin, $xml, $header) = @_;
+    my $plugobj = &plugin::load_plugin_for_info ($plugin);
+    if ($xml) {
+	$plugobj->print_xml_usage($header);
+    }
+    else {
+	gsprintf(STDERR, "\n{pluginfo.passing_options}\n\n");
+	gsprintf(STDERR, "{pluginfo.option_types}:\n\n");
+	gsprintf(STDERR, "{pluginfo.specific_options}\n\n");
+	gsprintf(STDERR, "{pluginfo.general_options}\n\n");
+	gsprintf(STDERR, "$plugin {pluginfo.info}:\n\n");
+	
+	$plugobj->print_txt_usage();
+    }
+    
+}
+
+&main ();
Index: /gsdl/stable/bin/script/plugoutinfo.pl
===================================================================
--- /gsdl/stable/bin/script/plugoutinfo.pl	(revision 20131)
+++ /gsdl/stable/bin/script/plugoutinfo.pl	(revision 20131)
@@ -0,0 +1,221 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# plugoutinfo.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# This program will print info about a plugout
+
+use strict;
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugouts");
+}
+
+use plugout;
+use util;
+use gsprintf;
+use printusage;
+use parse2;
+
+my $arguments =
+    [ { 'name' => "collection",
+	'desc' => "{plugoutinfo.collection}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "xml",
+	'desc' => "{scripts.xml}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "listall",
+	'desc' => "{scripts.listall}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "describeall",
+	'desc' => "{scripts.describeall}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no" } ];
+
+my $options = { 'name' => "plugoutinfo.pl",
+		'desc' => "{plugoutinfo.desc}",
+		'args' => $arguments };
+
+sub gsprintf
+{
+    return &gsprintf::gsprintf(@_);
+}
+
+
+sub main {
+    my $collection = "";
+    my $xml = 0;
+    my $listall = 0;
+    my $describeall = 0;
+    my ($language, $encoding);
+
+    my $hashParsingResult = {};
+    # general options available to all plugouts
+    my $unparsed_args = parse2::parse(\@ARGV,$arguments,$hashParsingResult,"allow_extra_options");
+
+    # parse returns -1 if an error occurred
+    if ($unparsed_args == -1) {
+	
+	PrintUsage::print_txt_usage($options, "{plugoutinfo.params}");
+ 	die "\n";
+    }
+    
+    foreach my $strVariable (keys %$hashParsingResult)
+    {
+	my $value = $hashParsingResult->{$strVariable};
+	# test to make sure the variable name is 'safe'
+	if ($strVariable !~ /^\w+$/) {
+ 	    die "variable name '$strVariable' isn't safe!";
+	}
+	eval "\$$strVariable = \$value";
+        
+    }
+ 
+    # if language wasn't specified, see if it is set in the environment
+    # (LC_ALL or LANG)
+    if (!$language && ($_=$ENV{'LC_ALL'} or $_=$ENV{'LANG'})) {
+	m/^([^\.]+)\.?(.*)/;
+	$language=$1;
+	$encoding=$2; # might be undef...
+# gsprintf::load_language* thinks "fr" is completely different to "fr_FR"...
+	$language =~ s/_.*$//;
+    }
+
+    # If $language has been set, load the appropriate resource bundle
+    # (Otherwise, the default resource bundle will be loaded automatically)
+    if ($language) {
+	gsprintf::load_language_specific_resource_bundle($language);
+	if ($encoding) {
+	    $encoding =~ tr/-/_/;
+	    $encoding = lc($encoding);
+	    $encoding =~ s/utf_8/utf8/; # special
+	    $gsprintf::specialoutputencoding=$encoding;
+	}
+    }
+
+    # If there is not exactly 1 argument left (plugout name), then the arguments were wrong
+    # Or if the user specified -h, then we output the usage also
+    if(@ARGV && $ARGV[0] =~ /^\-+h/ )
+    {
+	PrintUsage::print_txt_usage($options, "{plugoutinfo.params}");  
+        die "\n";
+    }
+
+    # If there is not exactly 1 argument left (plugout name), then the arguments were wrong (apart from if we had listall or describeall set)
+    if ($listall == 0 && $describeall ==0 && $unparsed_args == 0) {
+	gsprintf(STDERR, "{plugoutinfo.no_plugout_name}\n\n");
+	PrintUsage::print_txt_usage($options, "{plugoutinfo.params}", 1);
+	die "\n";
+    }
+
+    # we had some arguments that we weren't expecting
+    if ($unparsed_args > 1) {
+	pop(@ARGV); # assume that the last arg is the plugout name
+	gsprintf(STDERR, "{common.invalid_options}\n\n", join (',', @ARGV));
+	PrintUsage::print_txt_usage($options, "{plugoutinfo.params}", 1);
+	die "\n";
+    }
+
+    my $plugout_name = shift (@ARGV);
+
+    if (defined $plugout_name) {
+	$plugout_name =~ s/\.pm$//; # allow xxxPlugout.pm as the argument
+    }
+
+    if ($collection ne "") {
+	$ENV{'GSDLCOLLECTDIR'} = &util::filename_cat ($ENV{'GSDLHOME'}, "collect", $collection);
+    } else {
+	$ENV{'GSDLCOLLECTDIR'} = $ENV{'GSDLHOME'};
+    }
+
+    if ($listall || $describeall) {
+	my $plugouts_dir = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "perllib", "plugouts");
+	my @plugout_list = ();
+	if (opendir (INDIR, $plugouts_dir)) {
+	    @plugout_list = grep (/Plugout\.pm$/, readdir (INDIR));
+	    closedir (INDIR);
+	}
+
+	print STDERR "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+	print STDERR "<PlugoutList length=\"" . scalar(@plugout_list) . "\">\n";
+	foreach my $plugout_name (@plugout_list) {
+	    $plugout_name =~ s/\.pm$//;
+	    my $plugout;
+	    push @$plugout,$plugout_name; 
+	    my $plugoutobj = &plugout::load_plugout ($plugout);
+	    if ($describeall) {
+		$plugoutobj->print_xml_usage(0);
+	    }
+	    else {
+		$plugoutobj->print_xml_usage(0, 1);
+	    }
+	    
+	}
+	print STDERR "</PlugoutList>\n";
+    }
+    else {
+	&print_single_plugout($plugout_name, $xml, 1);
+    }
+
+  
+}
+
+
+sub print_single_plugout {
+    my ($plugout_name, $xml, $header) = @_;
+    my $plugout;
+
+    push @$plugout,$plugout_name;
+
+    my $plugoutobj = &plugout::load_plugout($plugout);
+
+    if ($xml) {
+	$plugoutobj->print_xml_usage($header);
+    }
+    else {
+	gsprintf(STDERR, "\n{plugoutinfo.passing_options}\n\n");
+	gsprintf(STDERR, "{plugoutinfo.option_types}:\n\n");
+	gsprintf(STDERR, "{plugoutinfo.specific_options}\n\n");
+	gsprintf(STDERR, "{plugoutinfo.general_options}\n\n");
+	gsprintf(STDERR, "$plugout_name {plugoutinfo.info}:\n\n");
+	
+	$plugoutobj->print_txt_usage();
+    }
+    
+}
+
+&main ();
Index: /gsdl/stable/bin/script/ppttohtml.pl
===================================================================
--- /gsdl/stable/bin/script/ppttohtml.pl	(revision 20131)
+++ /gsdl/stable/bin/script/ppttohtml.pl	(revision 20131)
@@ -0,0 +1,68 @@
+eval 'exec perl -x -- $0 $@'
+    if 0;
+#! perl
+# line 6
+
+sub usage() {
+    print "$0 <input.ppt> <output.html>\n";
+}
+
+
+if (@ARGV != 2) {
+    usage();
+    exit(1);
+}
+my $input_ppt=shift;
+my $output_html=shift;
+
+# try to find ppthtml binary in GSDLHOME
+my $ppthtml_binary="ppthtml";
+my $GSDLOS=$ENV{'GSDLOS'};
+my $GSDLHOME=$ENV{'GSDLHOME'};
+if ($GSDLOS =~ /^windows$/i) {
+    $ppthtml_binary.=".exe";
+}
+
+# assume it is on the path if running under windows, in case GSDLHOME
+# has a space
+if ($GSDLOS !~ /windows/i && -x "$GSDLHOME/bin/$GSDLOS/$ppthtml_binary") {
+    $ppthtml_binary="$GSDLHOME/bin/$GSDLOS/$ppthtml_binary";
+}
+
+if (! -r $input_ppt) {
+    print STDERR "Unable to read file `$input_ppt'\n";
+    exit (1);
+}
+
+my $return_value=
+    system("$ppthtml_binary \"$input_ppt\" > \"$output_html\"");
+
+if ($return_value != 0) {
+    exit (1);
+}
+
+# Ok, we made an html file. Check to see if it has any content, and remove
+# the little nag link at the the bottom.
+my $html="";
+open (HTML, "$output_html") || die "Can't read file:$!";
+$html=join('', <HTML>);
+close HTML;
+
+$html =~ s@<hr><FONT SIZE=-1>Created with.*\n</BODY></HTML>$@</BODY></HTML>@s;
+
+# if we are using the file name as the title, then get rid of it,
+# as HTMLPlug will use the first 100 chars instead if there's no title.
+$html =~ s@<title>.*?\.ppt</title>@<title></title>@i;
+
+my $tmp=$html;
+$tmp =~ s/^.*?<BODY>//ms;
+$tmp =~ s/(&nbsp;)|\s//gims;
+if ($tmp !~ m/(>[^<]+<)/) {
+    print STDERR "No text found in extracted html file!\n";
+    exit(1);
+}
+open (NEWHTML, ">$output_html") || die "Can't create file:$!";
+print NEWHTML $html;
+close NEWHTML;
+exit (0);
+
Index: /gsdl/stable/bin/script/process_html.pl
===================================================================
--- /gsdl/stable/bin/script/process_html.pl	(revision 20131)
+++ /gsdl/stable/bin/script/process_html.pl	(revision 20131)
@@ -0,0 +1,393 @@
+#!/usr/bin/perl -w
+
+
+# Both this script and its associated process_html.pl were written by
+# Marcel ?, while a student at Waikato University. Unfortunately he
+# was very new to perl at the time so the code is neither as clean nor
+# as fast as it could be (I've cleaned up a few of the more serious
+# bottlenecks -- it could do with alot more work though).  The code
+# does work though, if a little slowly. It's not ready for primetime
+# however and is included in the Greenstone source tree mostly so that
+# I don't lose it. -- Stefan - 24 Jul 2001
+
+
+# This script rebuilds the static collection by linking all the downloaded html files
+# back together. 
+# It searches through html files and replaces links it recognizes from the links.txt file 
+# with the apropriate html file name (eg 1.html, 2.html etc)
+# This script also updates the links for the pictures.
+
+# This is where all the dl-ed html files are located, eg. 'temp_html/'
+my $outputdir  = 'temp_html/';
+
+# This is where all the processed files end up (don't want to overwrite originals ;) eg. 'my_static_collection/'
+my $finaldir   = 'envl_collection/';
+
+# If any options where used (such as &u=1) when the html files where dl-ed then please specify them here.
+my $option = "&u=1";
+
+# Please ensure these two options match the settings used when downloading the collection :)
+my $dir_entries = 250;
+my $fix_empty_pages = '&cl=CL1';
+
+#-------------------------------------------------------------------------------------------------
+
+# global arrays used to store links, links-index & html-filenames
+my %filez;
+my %out_filez;
+my %linkz;
+my %short_linkz1;
+my %short_linkz2;
+my %short_linkz3;
+my %linkz_index;
+#my %remove_these;
+my $remove_these = "";
+
+sub processfiles
+{
+    local($start_here) = @_;
+
+    for my $file($start_here .. $#filez)
+    {
+	if((-e $filez[$file])&&(-s $filez[$file]))
+	{
+	    open (FILE, $filez[$file]) or die "can't open ", $filez[$file],": $! \n";
+	    
+	    print " $filez[$file] ";
+	    
+	    undef $/;
+	    my $content_of_file = <FILE>;
+	    $/ = "\n";
+	    close(FILE);
+	    
+	    #quick & nasty fix for the 'open book' link
+	    local $quick_fix1 = "&cl=\"";
+	    local $quick_fix2 = "&cl=\'";
+	    
+	    $content_of_file =~ s/$quick_fix1/$fix_empty_pages\"/g;
+	    $content_of_file =~ s/$quick_fix2/$fix_empty_pages\'/g;
+	    
+	    for my $link(0 .. $#linkz)
+	    {
+		my $new_link = $linkz_index[$link].".html";
+		
+		if($short_linkz3[$link] ne "")
+		{
+		    $content_of_file =~ s/$short_linkz1[$link].*?$short_linkz2[$link].*?${short_linkz3[$link]}[^\"\'\s\>]*/$new_link/g;
+		}
+		else
+		{
+			$content_of_file =~ s/$short_linkz1[$link].*${short_linkz2[$link]}[^\"\'\s\>]*/$new_link/g;
+		}
+	    }
+    
+            $content_of_file =~ s/(["'])$remove_these/$1..\//g;
+	    open (TEMP, ">temp.html") or die "can't open temp.html: $! \n";
+	    print TEMP $content_of_file;
+	    close(TEMP);
+	    rename("temp.html", $out_filez[$file]) or die "cannot create", $out_filez[$file],": $! \n";
+	    print " --> $out_filez[$file]";
+	    print "..done\n";
+	}
+	else
+	{
+	    last;    # bomb out of loop. Done.
+	}
+    }
+     print " *** Done, cannot find any more files to process ***\n";
+}
+
+# the switch variable there so that I can create a couple of additional arrays without having to write an entirely new function :-)
+# 0 = off, 1 = on (puts values into %linkz_index, %short_linkz1 and %short_linkz2)
+sub sort_array_by_length
+{
+    local (*foo, $switch) = @_;
+    my $total = $#foo;
+    my %temp_linkz;
+    my $shortest = 999999;
+    my $longest = 0;
+
+    if ($switch != 0)
+    {
+	print "Processing linkz (chopping, slicing, dicing and sorting :-)...";
+    }
+
+    for my $counter(0 .. $total)
+    {
+	if (length($foo[$counter]) < $shortest)
+	{
+	    $shortest = length($foo[$counter]);   
+	    $temp_linkz[$total] = $foo[$counter];
+	}
+	if (length($foo[$counter]) > $longest)
+	{
+	    $longest = length($foo[$counter]);   
+	}  
+    }        
+    
+    $backward = $total;
+    for my $l($shortest .. $longest)
+    {      
+	local $numberdir = 0;
+	for my $counter(0 .. $total)
+	{
+	    if ($counter % $dir_entries == 0)
+	    {
+		$numberdir = $counter;
+	    }
+
+	    if(length($foo[$counter]) == $l)
+	    {
+		$temp_linkz[$backward] = $foo[$counter];
+		if ($switch != 0)
+		{ 
+		    $linkz_index[$backward] = "../".$numberdir."/".$counter;
+		    my $d_offset = 0;
+		    for my $search(0 .. (length($foo[$counter]) - 3))
+		    {
+			if((substr($foo[$counter], $search, 3) eq '?e=')||(substr($foo[$counter], $search, 3) eq '&e='))
+			{
+			    $short_linkz1[$backward] = substr($foo[$counter], 0, $search);
+			}
+			
+			for my $second_search($search .. length($foo[$counter]))
+			{
+			    if((substr($foo[$counter], $second_search, 3) eq '?d=')||(substr($foo[$counter], $second_search, 3) eq '&d='))
+			    {
+				$short_linkz3[$backward] = substr($foo[$counter], $second_search);
+				$d_offset = $second_search;
+				last;
+			    }
+			}
+			
+			if(substr($foo[$counter], $search, 3) eq '?a=')
+			{
+			    $short_linkz1[$backward] = substr($foo[$counter], 0, $search);
+			    if($d_offset > 0)
+			    {
+				$short_linkz2[$backward] = substr($foo[$counter], $search, $d_offset - $search);
+			    }
+			    else
+			    {
+				$short_linkz2[$backward] = substr($foo[$counter], $search);
+			    }
+			}
+			
+			if(substr($foo[$counter], $search, 3) eq '&a=')
+			{
+			    if($d_offset > 0)
+			    {
+				$short_linkz2[$backward] = substr($foo[$counter], $search, $d_offset - $search);
+			    }
+			    else
+			    {
+				$short_linkz2[$backward] = substr($foo[$counter], $search);
+			    }
+			}
+		    } 
+		}
+		$backward--;
+	    }
+	}
+    }    
+    # copy the sorted temp_array over the original array (must be a better way of doing this :\ )
+    for my $counter(0 .. $total)
+    {    
+	$foo[$counter] = $temp_linkz[$counter];
+    }
+    if ($switch != 0)
+    {
+	print "done!\n";
+    }
+}
+
+sub how_much_to_chop
+{
+    local($link) = @_;
+    my $bracket_counter = 0;
+    my $chop_offset = 0;
+
+    for my $search(0 .. length($link))
+    {
+	if (substr($link, $search, 1) eq '/')
+	{
+	    $bracket_counter++;   
+	}
+	if ($bracket_counter == 2)
+	{
+	    $chop_offset = $search + 1;
+	} 
+    }
+    return $chop_offset;
+}
+
+my $start_time = (times)[0]; 
+
+#-----------------------------------------------------------------------------------------------
+# No need to start from scratch everytime, we can recover/continue from wherever we left off
+# simply by checking which html files have been created
+#-----------------------------------------------------------------------------------------------
+my $linknumber = 0;
+my $failed     = 0;
+my $check_file = "";
+my $numberdir = 0;
+
+if($outputdir ne $finaldir)
+{
+    while ($failed == 0)
+    {
+	if ($linknumber % $dir_entries == 0) 
+	{
+	    if (!((-e $finaldir.$linknumber)&&(-d $finaldir.$linknumber)))
+	    {
+		$failed++;
+		mkdir($finaldir.$linknumber, 0777) or die " ** Cannot create ",$finaldir.$linknumber, "!: $!\n";
+	    }
+	    $numberdir = $linknumber;
+	}
+	
+	$check_file = $finaldir.$numberdir."/".$linknumber.".html";
+	if ((-e $check_file)&&($failed == 0)) 
+	{ 
+	    $linknumber++;
+	} 
+	else
+	{
+	    $failed++;
+	    # I'm subtracting 1 from the starting link, 
+	    # just in case it only loaded half the page ;^)
+	    if($linknumber>0) 
+	    { 
+		$linknumber--; 
+	    }
+	    print " Will start processing at number $linknumber \n";
+	}
+    }
+}
+my $i = 0;
+my $that = "";
+my $offset = 0;
+
+#read in old links from links text file
+open (CHECK, "links.txt") || die " ** Cannot find/open links text file!: $!\n";
+while (defined ($that = <CHECK>)) {
+    
+    if ($i == 0)
+    {  
+	#chop off the first bit
+	$offset = &how_much_to_chop($that); 
+	print " Offset has been set to: ",$offset,"\n";
+	print " This next bit will be ignored for all links in the links.txt file:\n";
+	print "  -->",substr($that,0,$offset),"<--\n";
+    }
+    
+    $that = substr($that, $offset);
+    
+    #Wipe-out the EOL character
+#    if (substr($that, -1) eq "\n") { substr($that, -1) = ""; }
+    chomp $that;
+    
+    #this wipes the options
+#    if (length($option) != 0)
+#    {	    
+#	substr($that, (length($option)) * -1) = "";
+#    }
+    $that =~ s/$option//;
+    
+    $linkz[$i] = $that;
+    
+    $short_linkz1[$i] = "";
+    $short_linkz2[$i] = "";
+    $short_linkz3[$i] = "";
+    
+    for my $search(0 .. (length($that) - 3))
+    {
+	if((substr($that, $search, 3) eq '?e=')||(substr($that, $search, 3) eq '&e='))
+	{
+	    $short_linkz1[$i] = substr($that, 0, $search);
+	}
+	
+	if(substr($that, $search, 3) eq '?a=')
+	{
+	    $short_linkz1[$i] = substr($that, 0, $search);
+	    $short_linkz2[$i] = substr($that, $search);
+	}
+	if(substr($that, $search, 3) eq '&a=')
+	{
+	    $short_linkz2[$i] = substr($that, $search);
+	}
+    }
+    $i++;
+    
+    if ($i % $dir_entries == 0)
+    {
+	if (!((-e $finaldir.$i)&&(-d $finaldir.$i)))
+	{
+	    mkdir($finaldir.$i, 0777) or die " ** Cannot create ",$finaldir.$i, "!: $!\n";
+	}
+    }
+}
+close(CHECK);
+
+print " - I found ",$i, " links in the links text file -\n";
+
+&sort_array_by_length(*linkz, 1);
+
+$numberdir = 0;
+
+for my $z(0 .. ($i - 1))
+{
+    if($z % $dir_entries == 0)
+    {
+	$numberdir = $z;
+    }
+    $filez[$z] = $outputdir.$numberdir."/".$z.".html";
+    $out_filez[$z] = $finaldir.$numberdir."/".$z.".html";
+}
+
+# ..and last but not least, load any image_dirs from image_dirs.txt
+my $imd_that = "";
+#my $image_dirs_pointer = 0;
+
+my @tmp_arr = ();
+open (IMAGE_DIR, "image_dirs.txt") || die " ** HEY! Cannot find/open image_dirs.txt file! : $! **\n";
+while(defined ($imd_that = <IMAGE_DIR>))
+{
+    chomp $imd_that;
+    push(@tmp_array, $imd_that);
+}
+close IMAGE_DIR;
+
+$remove_these = "(" . join ("|", sort {length $b <=> length $a} @tmp_array) . ")"; 
+
+#print " - I found ",($#remove_these + 1)," picture directories in image_dirs.txt -\n";
+#&sort_array_by_length(*remove_these, 0);
+
+print "-" x 20, "\n";
+print "  Here we go...\n";
+print "-" x 20, "\n";
+
+&processfiles($linknumber);
+
+my $end_time = (times)[0];
+print "\n\n\n *----------------------------*\n";
+print " |  Whew! Task completed! :-D |\n";
+print " *----------------------------*\n";
+printf"  Script took %.2f CPU seconds to complete ;^)\n", $end_time - $start_time;
+print "\n\n"; 
+print " Now there's a few things left to do...load up ",$finaldir, "0/0.html in your webbrowser and\n";
+print " make sure everything works.\n"; 
+print " The grab_collection script will have generated 3 text files that can be removed, namely:\n";
+print " - links.txt \n";
+print " - images.txt \n";
+print " - image_dirs.txt \n\n";
+if ($outputdir ne $finaldir)
+{
+    print "And then finally you can also delete the ",$outputdir," directory.\n\n";
+}
+
+
+
+
+
+
Index: /gsdl/stable/bin/script/removedocument.pl
===================================================================
--- /gsdl/stable/bin/script/removedocument.pl	(revision 20131)
+++ /gsdl/stable/bin/script/removedocument.pl	(revision 20131)
@@ -0,0 +1,32 @@
+#!/usr/bin/perl -w
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/bin/script");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+    unshift (@INC, "$ENV{'GSDLHOME'}/collect/lld/perllib");
+}
+
+use util;
+
+use IncrementalBuildUtils; # Include John's incremental building API
+
+# Ensure the collection specific binaries are on the search path
+my $path_separator = ":";
+$ENV{'PATH'} = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}) .
+$path_separator . &util::filename_cat($ENV{'GSDLHOME'}, "bin", "script") .
+$path_separator . $ENV{'PATH'};
+
+if(!$ARGV[0] || !$ARGV[1]) {
+  print STDERR "Usage: removedocument <collection> <oid>\n";
+  exit;
+}
+
+my $collection = $ARGV[0];
+my $oid = $ARGV[1];
+
+&IncrementalBuildUtils::deleteDocument($collection, $oid);
+
+exit;
Index: /gsdl/stable/bin/script/replace_srcdoc_with_html.pl
===================================================================
--- /gsdl/stable/bin/script/replace_srcdoc_with_html.pl	(revision 20131)
+++ /gsdl/stable/bin/script/replace_srcdoc_with_html.pl	(revision 20131)
@@ -0,0 +1,223 @@
+#!/usr/bin/perl -w
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugins");
+}
+
+use strict;
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+no strict 'refs'; # allow filehandles to be variables and vice versa
+
+use encodings;
+use printusage;
+use parse2;
+use FileHandle;
+
+my $arguments = 
+    [ 
+      { 'name' => "language",
+	'desc' => "{scripts.language}",
+	'type' => "string",
+	'reqd' => "no",
+        'hiddengli' => "yes" },
+      { 'name' => "plugin",
+	'desc' => "{srcreplace.plugin}",
+	'type' => "string",
+	'reqd' => "yes",
+	'hiddengli' => "yes"},
+      { 'name' => "verbosity",
+	'desc' => "{import.verbosity}",
+	'type' => "int",
+	'range' => "0,",
+	'deft' => "1",
+	'reqd' => "no",
+	'modegli' => "3" },
+      # Do not remove the following option, it's a flag for generating the xml of the options
+      # It WILL be used!
+      { 'name' => "xml", # run with -xml, the output generated should be valid XML.  Used from GLI
+	'desc' => "",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" }
+      ];
+	
+my $options = { 'name' => "replace_srcdoc_with_html.pl",
+		'desc' => "{srcreplace.desc}",
+		'args' => $arguments };
+
+	    
+sub main
+{
+    my ($language, $plugin, $verbosity);
+
+    my $xml = 0;
+
+    my $hashParsingResult = {};
+
+ 
+    # parse the options
+    my $intArgLeftinAfterParsing = parse2::parse(\@ARGV,$arguments,$hashParsingResult,"allow_extra_options");
+
+    # If parse returns -1 then something has gone wrong
+    if ($intArgLeftinAfterParsing == -1)
+    {
+	&PrintUsage::print_txt_usage($options, "{srcreplace.params}");
+	die "\n";
+    }
+
+    foreach my $strVariable (keys %$hashParsingResult)
+    {
+	eval "\$$strVariable = \$hashParsingResult->{\"\$strVariable\"}";
+    }
+
+    # If $language has been specified, load the appropriate resource bundle
+    # (Otherwise, the default resource bundle will be loaded automatically)
+    if ($language && $language =~ /\S/) {
+	&gsprintf::load_language_specific_resource_bundle($language);
+    }
+
+    if ($xml) {
+        &PrintUsage::print_xml_usage($options);
+	print "\n";
+	return;
+    }
+
+    # There should be one arg left after parsing (the filename)
+    # Or the user may have specified -h, in which case we output the usage
+    if($intArgLeftinAfterParsing != 1 || (@ARGV && $ARGV[0] =~ /^\-+h/))
+    {
+	&PrintUsage::print_txt_usage($options, "{srcreplace.params}");
+	die "\n";
+    }
+
+    # The filename of the document to be replaced is the first value 
+    # that remains after the options have been parsed out
+    my $filename = $ARGV[0];
+    if (!defined $filename || $filename !~ /\w/) { 	
+	
+	&PrintUsage::print_txt_usage($options, "{srcreplace.params}");
+	print STDERR "You need to specify a filename\n";
+	die "\n";
+    }
+    # check that file exists
+    if (!-e $filename) {
+	print STDERR "File $filename doesn't exist...\n";
+	die "\n";
+    }
+    # check required options
+    if (!defined $plugin || $plugin !~ /\w/) {
+	&PrintUsage::print_txt_usage($options, "{srcreplace.params}");
+	print STDERR "You need to specify a plugin";
+	die "\n";
+    }
+
+    # ConvertToPlug.pm's subclasses should be available here through GLI,
+    # but in cmdline version, these should be supplied
+    my $plugobj;
+    require "$plugin.pm";
+    eval ("\$plugobj = new $plugin()");
+    die "$@" if $@;
+
+    # ...and initialize it
+    $plugobj->init(1, "STDERR", "STDERR");
+    
+    # find the import directory, where we want to create it in. This is where the file
+    # passed as parameter by GLI is located.
+   
+    # derive tmp filename from input filename
+    my ($tailname, $import_dir, $suffix)
+	= &File::Basename::fileparse($filename, "\\.[^\\.]+\$");
+
+    # Use the plugin's tmp_area_convert_file function to avoid duplicating code.
+    # This method returns the name of the output file. In the case of Word docs,
+    # if converted with windows_scripting a "filename_files" folder might have been
+    # created for associated files. Same situation when using wvware with gsConvert.pl.
+    # (When old gsConvert.pl was used, wvware created no separate directory, instead files
+    # associated with the html generated would be at the same level in the tmp folder
+    # where the output file was created.) Now it's the same no matter whether wvware
+    # or windows_scripting did the conversion of the Word doc to html.
+    my $output_filename = $plugobj->tmp_area_convert_file("html", $filename);    
+
+
+    # if something went wrong, then tmp_area_convert_file returns "", but can also check
+    # for whether the output file exists or not
+    if(!-e $output_filename || $output_filename eq "") { 
+	# if no output html file was created, then die so that GLI displays error message
+	print STDERR "***replace_srcdoc_with_html.pl: no output file created for $filename ***\n";
+	die "No html file created for $filename. Replacement did not take place\n"; # Program NEEDS to die here, 
+	# else the error that occurred is not transmitted to GLI and it thinks instead that execution was fine
+	#return 0; # error code 0 for false <- NO, needs to die, not return!
+    }
+    #else:
+
+    # now, find out what to move:
+    # it may be a single file, or, if it is a word doc, it may also have an image folder
+    # which has the name "filename-without-extension_files"
+    my ($tmp_name, $tmp_dir, $ext) = &File::Basename::fileparse($output_filename, "\\.[^\\.]+\$");
+
+    # the name of the folder of associated files (which may or may not exist) in the tmp dir
+    my $assoc_folder = &util::filename_cat($tmp_dir, $tmp_name."_files");
+ 
+    # Need to check for naming collisions: in case there is already a file or folder 
+    # in the import directory by the name of those we want to move there from the tmp folder
+    # First need to work out the full paths to any assoc folder if it were copied into the 
+    # import directory, and the main html file if it were copied into the import folder:
+    my $new_assoc_folder = &util::filename_cat($import_dir,  $tmp_name."_files"); 
+    my $new_file = &util::filename_cat($import_dir,  $tmp_name.$ext); 
+
+    # If there is an image folder, any naming collisions now would mean that the links of 
+    # the html file to the image folder would break if we changed the assoc_folder's name. 
+    # Therefore, in such a case this process dies after deleting both the file and assoc_folder.
+    if(-e $assoc_folder && -e $new_assoc_folder) {
+	# so an associated folder was generated, AND a folder by that name already exists
+	# in the import folder where we want to copy the generated folder to.
+	&util::rm($output_filename);
+	&util::rm_r($assoc_folder); # we know directory exists, so remove dir
+	die "Image folder $new_assoc_folder already exists.\nDeleting generated file and folder, else links to images will break.\n";
+    } 
+    # Finally, check that no file already exists with the same name as the generated stand-alone
+    # file. Have to do this *after* checking for name collisions with any assoc_folder, because
+    # that also tries to remove any output files.
+    if(-e $new_file) { # a file by that name already exists, delete the generated file
+	&util::rm($output_filename);
+	die "File $new_file already exists. Deleting generated file.\n";
+    }
+
+    # Now we know we have no file name collisions. We 'move' the html file by copying its
+    # contents over and ensuring that these contents are utf8. If we don't do this, PDFs
+    # replaced by html may fail, whereas those converted with PDFPlug will have succeeded.
+    open(FIN,"<$output_filename") or die "replace_srcdoc_with_html.pl: Unable to open $output_filename to ensure utf8...ERROR: $!\n";
+    my $html_contents;
+    {
+	local $/ = undef;        # Read entire file at once
+	$html_contents = <FIN>;  # Now file is read in as one single 'line'
+	&unicode::ensure_utf8(\$html_contents); # turn any high bytes that aren't valid utf-8 into utf-8.
+    }
+    close(FIN); 
+
+    # write the utf8 contents to the new file and delete the original.
+    open(FOUT, ">$new_file") or die "replace_srcdoc_with_html.pl: Unable to open $new_file for writing out utf8 html...ERROR: $!\n";
+    print FOUT $html_contents;
+    close(FOUT);
+    &util::rm($output_filename);
+    
+    # move any associated folders containing associated files too
+    if(-e $assoc_folder) { 
+	#print STDERR "****Folder for associated files is $assoc_folder\n";
+	    #&util::mv($assoc_folder, $import_dir); # doesn't work for me
+	&util::cp_r($assoc_folder, $import_dir);
+	&util::rm_r($assoc_folder);
+    }   
+
+    # Now we can remove the source doc permanently (there are no assocdirs for source doc)
+    &util::rm($filename);
+
+    # need this output statement here, as GShell.java's runRemote() sets status to CANCELLED
+    # if there is no output! (Therefore, it only had this adverse affect when running GSDL remotely) 
+    # Do something useful with it: return the new filename without extension, used by remote GS server
+    print STDOUT "$tmp_name\n"; 
+}
+&main(@ARGV);
Index: /gsdl/stable/bin/script/schedule.pl
===================================================================
--- /gsdl/stable/bin/script/schedule.pl	(revision 20131)
+++ /gsdl/stable/bin/script/schedule.pl	(revision 20131)
@@ -0,0 +1,595 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# schedule.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package schedule;
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugins");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugouts");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/classify");
+
+    if (defined $ENV{'GSDLEXTS'}) {
+	my @extensions = split(/:/,$ENV{'GSDLEXTS'});
+	foreach my $e (@extensions) {
+	    my $ext_prefix = "$ENV{'GSDLHOME'}/ext/$e";
+
+	    unshift (@INC, "$ext_prefix/perllib");
+	    unshift (@INC, "$ext_prefix/perllib/cpan");
+	}
+    }
+}
+
+use strict; 
+no strict 'refs'; 
+no strict 'subs'; 
+
+use FileHandle; 
+use Fcntl; 
+use printusage; 
+use parse2; 
+use parse3;
+use gsprintf 'gsprintf';
+if($ENV{'GSDLOS'} eq "windows") {
+	eval("require \"Win32.pm\" "); 
+}
+
+my $frequency_list = 
+    [  { 'name' => "hourly",
+         'desc' =>  "{schedule.frequency.hourly}" }, 
+       { 'name' => "daily",
+         'desc' =>  "{schedule.frequency.daily}" }, 
+       { 'name' => "weekly",
+         'desc' =>  "{schedule.frequency.weekly}" } 
+     ];
+
+my $action_list = 
+    [  { 'name' => "add",
+         'desc' =>  "{schedule.action.add}" }, 
+       { 'name' => "update",
+         'desc' =>  "{schedule.action.update}" }, 
+       { 'name' => "delete",
+         'desc' =>  "{schedule.action.delete}" } 
+     ];
+
+my $arguments = 
+    [
+     { 'name' => "schedule", 
+       'desc' => "{schedule.schedule}",
+       'type' => "flag", 
+       'reqd' => "no", 
+       'modegli' => "3" }, 
+      { 'name' => "frequency", 
+       'desc' => "{schedule.frequency}",
+       'type' => "enum",
+       'list' => $frequency_list, 
+       'deft' => "daily", 
+       'reqd' => "no", 
+       'modegli' => "3" }, 
+     { 'name' => "action", 
+       'desc' => "{schedule.action}",
+       'type' => "enum", 
+       'list' => $action_list, 
+       'deft' => "add", 
+       'reqd' => "no", 
+       'modegli' => "3" },
+     { 'name' => "import", 
+       'desc' => "{schedule.import}",
+       'type' => "quotestr", 
+       'deft' => "", 
+       'reqd' => "yes", 
+       'hiddengli' => "yes" },
+     { 'name' => "build", 
+       'desc' => "{schedule.build}",
+       'type' => "quotestr", 
+       'deft' => "", 
+       'reqd' => "yes", 
+       'hiddengli' => "yes" }, 
+     { 'name' => "colname", 
+       'desc' => "{schedule.colname}",
+       'type' => "string", 
+       'deft' => "", 
+       'reqd' => "no", 
+       'hiddengli' => "yes" }, 
+     { 'name' => "xml", 
+       'desc' => "{scripts.xml}",
+       'type' => "flag", 
+       'reqd' => "no", 
+       'hiddengli' => "yes" },
+     { 'name' => "language", 
+       'desc' => "{scripts.language}",
+       'type' => "string", 
+       'reqd' => "no", 
+       'hiddengli' => "yes" },
+     { 'name' => "email", 
+       'desc' => "{schedule.email}",
+       'type' => "flag", 
+       'reqd' => "no", 
+       'modegli' => "3" },
+     { 'name' => "toaddr", 
+       'desc' => "{schedule.toaddr}",
+       'type' => "string", 
+       'reqd' => "no", 
+       'deft' => "", 
+       'modegli' => "3" },
+     { 'name' => "fromaddr", 
+       'desc' => "{schedule.fromaddr}",
+       'type' => "string",
+       'deft' => "", 
+       'reqd' => "no",
+       'modegli' => "3" },
+     { 'name' => "smtp", 
+       'desc' => "{schedule.smtp}",
+       'type' => "string",
+       'deft' => "",
+       'reqd' => "no", 
+       'modegli' => "3" },
+     { 'name' => "out",
+        'desc' => "{schedule.out}",
+        'type' => "string",
+        'deft' => "STDERR",
+        'reqd' => "no",
+        'hiddengli' => "yes" },
+     { 'name' => "gli",
+        'desc' => "{schedule.gli}",
+        'type' => "flag",
+        'reqd' => "no",
+        'hiddengli' => "yes" }
+     ];
+
+
+my $options = { 'name' => "schedule.pl",
+		'desc' => "Interaction with Cron",
+		'args' => $arguments };
+
+&main(); 
+
+sub main { 
+
+    #params
+    my ($action, $frequency, $import, $build, $colname, $xml, $language, 
+        $email, $toaddr, $fromaddr, $smtp, $gli, $out);
+
+    #other vars
+    my ($i,$numArgs,$os,$erase,$erase2,$copy,$newpl,$gsdl,$path,$cronf,
+        $nf,$of,$opf, $cronstr, $ecmd,$ecmd2, $record, $cronrec,$ncronf);
+
+    #some defaults
+    $action = "add";   
+    $frequency = "hourly"; 
+    $import = ""; 
+    $build = ""; 
+    $colname = "";
+    $xml = 0; 
+    $email = 0;
+    $gli = 0; 
+    $language = ""; 
+    $out = "STDERR"; 
+
+
+    $gsdl = $ENV{'GSDLHOME'};
+    $os = $ENV{'GSDLOS'};
+    $path = $ENV{'PATH'}; 
+
+    my $service = "schedule"; 
+
+    #For this to work, we need to know if -gli exists
+ 
+    $numArgs=$#ARGV+1; 
+    $i = 0; 
+    while($i < $numArgs)
+    {
+	if($ARGV[$i] =~ /gli/) {
+	    $gli = 1; 
+	}
+	$i++; 
+    } 
+
+    #We are using two different parsers here, because the GLI in linux (and probably darwin) will not take
+    #an entire double-quoted string as an argument, while if schedule.pl is 
+    #executed from the command line, the entire double-quoted string is taken
+    #as an argument. For Windows, it seems that it does. 
+    my $hashParsingResult = {}; 
+    my $intArgLeftAfterParsing; 
+    if($gli && ($os eq "linux" || $os eq "darwin")) {  
+	$intArgLeftAfterParsing = parse3::parse(\@ARGV, $arguments, $hashParsingResult, "allow_extra_options"); 
+    } else {
+	$intArgLeftAfterParsing = parse2::parse(\@ARGV, $arguments, $hashParsingResult, "allow_extra_options"); 
+
+    } 
+
+    #check for extra options
+    if ($intArgLeftAfterParsing == -1 || $intArgLeftAfterParsing > 0 || (@ARGV && $ARGV[0] =~ /^\-+h/))
+    {
+        &PrintUsage::print_txt_usage($options, "{schedule.params}");
+        die "\n";
+    }
+
+    foreach my $strVariable (keys %$hashParsingResult)
+    {
+        eval "\$$strVariable = \$hashParsingResult->{\"\$strVariable\"}";
+    }
+  
+    if ($xml) {
+	    &PrintUsage::print_xml_usage($options); 
+	    print "\n"; 
+	    return; 
+
+    }
+
+    if ($gli) { # the gli wants strings to be in UTF-8
+        &gsprintf::output_strings_in_UTF8; 
+    }
+
+    if($action eq "add" || $action eq "update") { 
+	if($email) {
+	    if($smtp eq "" || $toaddr eq "" || $fromaddr eq "" || $smtp =~ /^-/ || $toaddr =~ /^-/ || $fromaddr =~ /^-/) {
+		&gsprintf($out, "{schedule.error.email} \n"); 
+		die "\n"; 
+	    }
+	
+
+	    if($import eq "" || $build eq "") { 
+		&gsprintf($out, "{schedule.error.importbuild} \n");
+		die "\n"; 
+	    }
+	}
+    } 
+    if($colname eq "") { 
+	 &gsprintf($out, "{schedule.error.colname} \n");
+	 die "\n"; 
+    }
+
+    #not sure if this is always set? 
+    #language may be passed in too
+    if($language eq "" && exists($ENV{'GSDLLANG'}))  {
+        $language = $ENV{'GSDLLANG'}; 
+    }
+    elsif($language eq "")  {
+	$language = "en"; 
+    } 
+
+    $newpl = "cron.pl"; 
+
+    if($action eq "delete") {
+
+	print STDERR "<Delete>\n" if $gli; 
+
+	if($os =~ /^linux$/ || $os =~ /^darwin$/) { 
+	        system("\\rm $gsdl/collect/$colname/$newpl 2>/dev/null");
+		system("\\rm $gsdl/collect/$colname/cronjob 2>/dev/null"); 
+	} else {  #in windows
+
+	        system("del $gsdl\\\\collect\\\\$colname\\\\$newpl 2>nul");  #nul is windows equivalent to /dev/null
+
+	} 
+
+
+	&gsprintf($out, "{schedule.deleted}\n");
+    } 
+    else {
+	#For the Scheduling monitor
+	print STDERR "<Schedule>\n" if $gli; 
+
+	if ($os =~ /^linux$/ || $os =~ /^darwin$/) {
+ 
+	    $import = $import." 2>$gsdl/collect/$colname/log/\$logfile";
+	    $build = $build." 2>>$gsdl/collect/$colname/log/\$logfile"; 
+	    $erase = "\\\\rm -r $gsdl/collect/$colname/index 2>>$gsdl/collect/$colname/log/\$logfile";
+	    $erase2 = "mkdir $gsdl/collect/$colname/index 2>>$gsdl/collect/$colname/log/\$logfile";  
+	    $copy = "mv $gsdl/collect/$colname/building/* $gsdl/collect/$colname/index/ 2>>$gsdl/collect/$colname/log/\$logfile";
+	    if($email) {
+		#first,we need to add backslashes before the 'at' symbol. 
+		$toaddr =~ s/\@/\\\@/g; 
+		$fromaddr =~ s/\@/\\\@/g; 
+
+		$ecmd = "$gsdl/bin/script/sendmail.pl -to $toaddr -from $fromaddr -smtp $smtp -msgfile $gsdl/collect/$colname/log/\$logfile -subject \\\"Results of build for collection $colname\\\" 2>>$gsdl/collect/$colname/log/\$logfile"; 
+
+		$ecmd2 = "$gsdl/bin/script/sendmail.pl -to $toaddr -from $fromaddr -smtp $smtp -msgfile $gsdl/etc/cronlock.txt -subject \\\"Results of build for collection $colname\\\" 2>>$gsdl/collect/$colname/log/\$logfile"; 	       
+	    }
+   
+	} else {   #in windows
+
+	    $gsdl =~ s/\\/\\\\/g; 
+	    $path =~ s/\\/\\\\/g; 
+
+	    $import =~ s/\\/\\\\/g;
+	    $build =~ s/\\/\\\\/g; 
+
+  	    $import =~ s/exe/exe\\\"/g;
+	    $import =~ s/pl/pl\\\"/g; 
+  	    $build =~ s/exe/exe\\\"/g;
+	    $build =~ s/pl/pl\\\"/g;  
+
+
+	    my $prompt = substr($gsdl,0,2); 
+
+	    $import =~ s/$prompt/\\\"$prompt/g; 
+	    $build =~ s/$prompt/\\\"$prompt/g; 
+
+	    #not the best solution - won't work if someone chooses something weird
+	    $import =~ s/\\collect/\\collect\\\"/; 
+            $build =~ s/\\collect/\\collect\\\"/; 
+
+	    $import = "$import 2>\\\"$gsdl\\\\collect\\\\$colname\\\\log\\\\\$logfile\\\" "; 
+	    $build = "$build 2>>\\\"$gsdl\\\\collect\\\\$colname\\\\log\\\\\$logfile\\\" "; 
+
+
+	    $erase = "rd \\\/S \\\/Q \\\"$gsdl\\\\collect\\\\$colname\\\\index\\\" 2>>\\\"$gsdl\\\\collect\\\\$colname\\\\log\\\\\$logfile\\\" "; 
+	    $erase2 = "md \\\"$gsdl\\\\collect\\\\$colname\\\\index\\\" 2>>\\\"$gsdl\\\\collect\\\\$colname\\\\log\\\\\$logfile\\\" "; 
+	    $copy = "xcopy \\\/E \\\/Y \\\"$gsdl\\\\collect\\\\$colname\\\\building\\\\*\\\" \\\"$gsdl\\\\collect\\\\$colname\\\\index\\\\\\\" >>\\\"$gsdl\\\\collect\\\\$colname\\\\log\\\\\$logfile\\\" ";
+	    if($email) {
+		$toaddr =~ s/\@/\\\@/g; 
+		$fromaddr =~ s/\@/\\\@/g; 
+		$ecmd = "\\\"$gsdl\\\\bin\\\\windows\\\\perl\\\\bin\\\\perl.exe\\\" -S \\\"$gsdl\\\\bin\\\\script\\\\sendmail.pl\\\" -to $toaddr -from $fromaddr -smtp $smtp -msgfile \\\"$gsdl\\\\collect\\\\$colname\\\\log\\\\\$logfile\\\" -subject \\\"Results of build for collection $colname\\\" >>\\\"$gsdl\\\\collect\\\\$colname\\\\log\\\\\$logfile\\\" "; 
+
+		$ecmd2 = "\\\"$gsdl\\\\bin\\\\windows\\\\perl\\\\bin\\\\perl.exe\\\" -S \\\"$gsdl\\\\bin\\\\script\\\\sendmail.pl\\\" -to $toaddr -from $fromaddr -smtp $smtp -msgfile \\\"$gsdl\\\\etc\\\\cronlock.txt\\\" -subject \\\"Results of build for collection $colname\\\" >>\\\"$gsdl\\\\collect\\\\$colname\\\\log\\\\\$logfile\\\" "; 	       
+	    }
+	}
+
+
+	$nf = new FileHandle() ||
+            (&gsprintf(STDERR, "{common.cannot_open_output_file}: $!\n", $out) && die);
+
+	open($nf, ">$gsdl/collect/$colname/$newpl") ||
+            (&gsprintf(STDERR, "{common.cannot_open_output_file}: $!\n", $out) && die);
+ 
+	
+	print $nf "\#!/usr/bin/perl"; 
+	print $nf "\n\n"; 
+
+
+	#we need to set environment variables for import and build
+	print $nf "\$ENV{'GSDLHOME'}=\"$gsdl\"\;\n"; 
+	print $nf "\$ENV{'GSDLOS'}=\"$os\"\;\n";
+	print $nf "\$ENV{'GSDLLANG'}=\"$language\"\;\n";  
+	print $nf "\$ENV{'PATH'}=\"$path\"\;\n";  
+
+	print $nf "\$logfile = \"cron\".time\(\).\".txt\"\;\n";
+
+	if($os =~ /^windows$/) {
+		print $nf "if\(-e \\\"$gsdl\\\\collect\\\\$colname\\\\etc\\\\cron.lck\\\" \"\)\{ \n"; 
+	} else { 
+		print $nf "if\(-e \"$gsdl/collect/$colname/etc/cron.lck\"\) \{ \n";
+	}
+	if($email) { 
+	    print $nf "    system(\"$ecmd2\")\;\n"; 
+	}
+	else { 
+	    if($os eq "windows") { 
+		print $nf "    system(\"more \\\"$gsdl\\\\etc\\\\cronlock.txt\\\" >\\\"$gsdl\\\\collect\\\\$colname\\\\log\\\\\$logfile\\\"\"\)\;\n";
+	    } else {
+		print $nf "    system(\"more $gsdl/etc/cronlock/txt > $gsdl/collect/$colname/log/\$logfile \"\)\;\n"; 
+	    }
+
+	}
+        print $nf "\} else \{\n";
+
+	if($os eq "linux" || $os eq "darwin")  {
+	    $import =~ s/\"//; 
+	    $import =~ s/\"//;
+	    $build =~ s/\"//; 
+	    $build =~ s/\"//; 
+	}
+       
+	if($os =~ /^windows$/) {
+		print $nf "system(\"echo lock \>\\\"$gsdl\\\\collect\\\\$colname\\\\etc\\\\cron.lck\\\"\")\;\n"; 
+	} else { 
+		print $nf "system(\"echo lock >$gsdl/collect/$colname/etc/cron.lck\")\;\n"; 
+	}
+
+	print $nf "	system(\"$import\")\;\n";
+	print $nf "	system(\"$build\")\;\n"; 
+
+	print $nf "	system(\"$erase\")\;\n"; 
+	print $nf "	system(\"$erase2\")\;\n"; 
+
+	print $nf "	system(\"$copy\")\;\n";
+	if($email)  {
+	    print $nf "	system(\"$ecmd\")\;\n"; 
+	}
+
+
+	#need to set permissions in linux
+	if($os =~ /^linux$/ || $os =~ /^darwin$/) {
+	    print $nf "system(\"chmod -R 755 $gsdl/collect/$colname/index/*\")\;\n";
+	    print $nf "system(\"\\\\rm $gsdl/collect/$colname/etc/cron.lck\")\;\n"; 
+	} else { 
+            print $nf "system(\"del \\\"$gsdl\\\\collect\\\\$colname\\\\etc\\\\cron.lck\\\" \")\;\n"; 
+	}
+
+
+
+        print $nf "\}\n"; 
+
+	close($nf); 
+	if($os =~ /^linux$/ || $os =~ /^darwin$/) {
+	    system("chmod 755 $gsdl/collect/$colname/cron.pl"); 
+	}
+
+	&gsprintf($out, "{schedule.scheduled}\n");
+    }
+
+    #next, we need to create a crontab file.  For now, a crontab will be set up
+    #to run at midnight either nightly or weekly.  
+    $gsdl =~ s/\\\\/\\/g;
+    if ($os =~ /^linux$/ || $os =~ /^darwin$/)
+    {
+	$cronf="cronjob"; 
+	open($nf, ">$gsdl/collect/$colname/$cronf") ||
+            (&gsprintf(STDERR, "{common.cannot_open_output_file}: $!\n", $out) && die);
+
+	#see if there is an existing crontab
+	system("crontab -l >$gsdl/collect/$colname/outfile 2>/dev/null"); 
+
+	$opf = new FileHandle(); 
+	open($opf, "$gsdl/collect/$colname/outfile")   ||
+            (&gsprintf(STDERR, "{common.cannot_open_output_file}: $!\n", $out) && die);
+	$record = <$opf>;  
+
+	#if there is an existing crontab file
+	#preserve all records and change existing record for 
+	#current collection
+	if ($record) 
+	{
+	    do
+	    {
+		if($record !~ /$colname/)
+		{
+		    print $nf $record; 
+		} 
+	    } while($record = <$opf>); 
+
+	    close($opf); 
+	}
+
+
+	if($action =~ /^add$/ || $action =~ /^update$/)
+	{
+	    if($frequency eq "hourly") {
+		$cronrec = "50 * * * * $gsdl/collect/$colname/cron.pl";
+	    }
+	    elsif($frequency eq "daily") {
+		$cronrec = "00 0 * * * $gsdl/collect/$colname/cron.pl";
+	    }
+	    elsif($frequency eq "weekly") {
+		$cronrec = "59 11 * * 0 $gsdl/collect/$colname/cron.pl";
+	    }
+
+	    $cronrec = $cronrec." 2>/dev/null\n"; 
+	
+	    print $nf $cronrec; 
+	}
+
+	close($nf); 
+
+	#this makes the cronjob official
+	#still needs to be done for existing records
+	system("crontab $gsdl/collect/$colname/$cronf 2>/dev/null"); 
+
+	#cleanup
+	system("\\rm $gsdl/collect/$colname/outfile"); 
+	system("\\rm $gsdl/collect/$colname/$cronf");
+
+	if($action eq "add" || $action eq "update")  {
+	    &gsprintf($out, "{schedule.cron}\n");
+	}
+
+    } else {  
+
+    #for windows, we will put crontab file in the same place.  some limitations
+    #1) the absolute path to greenstone cannot have spaces if one is going to do this
+    #2) cron.exe needs to be started manually before doing this
+    #3) greenstone may have to be shut down completely to do this or lock problems occur
+
+	$cronf="crontab";  #pycron.exe expects this filename!
+	$ncronf="crontab.new"; 
+	#check to see if crontab file exists
+	if(-e "$gsdl/collect/$cronf")
+	{
+		
+		open($of, "$gsdl/collect/$cronf") ||
+            (&gsprintf(STDERR, "{common.cannot_open_output_file}: $!\n", $out) && die);
+
+
+		open($nf, ">$gsdl/collect/$ncronf")  ||
+            (&gsprintf(STDERR, "{common.cannot_open_output_file}: $!\n", $out) && die);
+
+		while($record = <$of>)
+		{
+	 		if($record !~ /$colname/)
+			{
+			    print $nf $record; 
+			}
+		} 
+		close($of);
+		close($nf);
+
+		system("del \"$gsdl\\collect\\$cronf\""); 
+		system("move \"$gsdl\\collect\\$ncronf\" \"$gsdl\\collect\\$cronf\""); 
+		
+		
+		my $shortf = Win32::GetShortPathName($gsdl); 
+
+		my $command = "$shortf\\bin\\windows\\silentstart $shortf\\bin\\windows\\perl\\bin\\perl $shortf\\collect\\$colname\\cron.pl\n"; 
+		
+		if($action =~ /^add$/ || $action =~ /^update$/)
+		{
+		    open($nf, ">>$gsdl/collect/$cronf") ||
+            (&gsprintf(STDERR, "{common.cannot_open_output_file}: $!\n", $out) && die);
+
+		    if($frequency eq "hourly") {
+			print $nf "50 * * * * $command";
+		    }
+		    elsif($frequency eq "daily") {
+			print $nf "00 0 * * * $command";
+		    }
+		    elsif($frequency eq "weekly") {
+			print $nf "59 11 * * 0 $command";
+		    }
+		    close($nf);
+		}
+
+	} else {	
+
+	    my $shortf = Win32::GetShortPathName($gsdl); 
+
+	    my $command = "$shortf\\bin\\windows\\silentstart $shortf\\bin\\windows\\perl\\bin\\perl $shortf\\collect\\$colname\\cron.pl\n"; 
+		
+
+	    if($action =~ /^add$/ || $action =~ /^update$/)
+	    {
+		open($nf, ">$gsdl/collect/$cronf") ||
+            (&gsprintf(STDERR, "{common.cannot_open_output_file}: $!\n", $out) && die);
+		if($frequency eq "hourly") {
+	 	   print $nf "50 * * * * $command";
+		}
+		elsif($frequency eq "daily") {
+		    print $nf "00 0 * * * $command";
+		}
+		elsif($frequency eq "weekly") {
+		    print $nf "59 11 * * 0 $command";
+		}
+
+		close($nf); 
+	    }
+	}
+
+	if($action eq "update" || $action eq "add") { 
+	    &gsprintf($out, "{schedule.cron}\n");
+	}
+    }
+
+    #For the scheduling monitor
+    print STDERR "<Done>\n" if $gli; 
+
+ 
+
+} #end sub main
Index: /gsdl/stable/bin/script/sendmail.pl
===================================================================
--- /gsdl/stable/bin/script/sendmail.pl	(revision 20131)
+++ /gsdl/stable/bin/script/sendmail.pl	(revision 20131)
@@ -0,0 +1,92 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# sendmail.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2000 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# sendmail.pl is a simple wrapper around the Sendmail perl module written
+# by Milivoj Ivkovic <mi@alma.ch>
+
+# Input is either read from STDIN or, if the -msgfile option is set, read
+# from the given file.
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use lib qq($ENV{'GSDLHOME'}/perllib/cpan);
+use Mail::Sendmail;
+use parsargv;
+
+if (!parsargv::parse(\@ARGV, 
+		     'to/@', \$to,
+		     'from/@', \$from,
+		     'subject/.*/', \$subject,
+		     'html', \$html,
+		     'smtp/.*', \$smtp,
+		     'msgfile/.*/', \$msgfile)) {
+    print STDERR "\n";
+    print STDERR "sendmail.pl: A simple platform independant mail sending program.\n\n";
+    print STDERR "  usage: $0 [options]\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -to addr      Comma separated list of mail recipients\n";
+    print STDERR "   -from addr    Address of message sender\n";
+    print STDERR "   -subject str  Optional subject line\n";   
+    print STDERR "   -html         Send message as HTML\n";
+    print STDERR "   -smtp server  The outgoing (SMTP) mail server\n";
+    print STDERR "   -msgfile file A file from which message to be sent is read.\n";
+    print STDERR "                 If not set message will be read in from STDIN\n";
+    die "\n";
+}
+
+my %mail = ('SMTP' => $smtp, 
+	    'To' => $to,
+	    'From' => $from,
+	    'Subject' => $subject,
+	    );
+
+my $msg = "";
+if ($msgfile ne "") {
+    if (!open (MSGFILE, $msgfile)) {
+	print STDERR "ERROR: Failed to open $msgfile. Message was not sent\n";
+	exit (-1);
+    }
+    undef $/;
+    $msg = <MSGFILE>;
+    $/ = "\n";
+    close MSGFILE;
+} else {
+    $msg = <STDIN>;
+}
+
+$mail{'Content-type'} = "text/html; charset=\"iso-8859-1\"" if ($html);
+$mail{'Message'} = $msg;
+	
+if (!sendmail %mail) {
+    print STDERR "ERROR: Failed to send message\n";
+    print STDERR "'$Mail::Sendmail::error'\n";
+    exit (-1);
+}
Index: /gsdl/stable/bin/script/set_metadata.pl
===================================================================
--- /gsdl/stable/bin/script/set_metadata.pl	(revision 20131)
+++ /gsdl/stable/bin/script/set_metadata.pl	(revision 20131)
@@ -0,0 +1,51 @@
+#!/usr/bin/perl -w
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/bin/script");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use doc;
+use strict;
+# Include John's incremental building API
+use IncrementalBuildUtils;
+use IncrementalDocument;
+
+if (!$ARGV[0] || !$ARGV[1] || !$ARGV[2] || !$ARGV[3] || !$ARGV[4] || ($ARGV[3] eq "REPLACE" && !$ARGV[5])) {
+  print STDERR "Usage: set_metadata <collection> <oid> <metadata_field> (REPLACE <old_value> <new_value> | (ADD|REMOVE) <value>)\n";
+  print STDERR "[you tried: set_metadata ";
+  foreach my $arg (@$ARGV) {
+    print STDERR $arg . " ";
+  }
+  print STDERR "]\n";
+  exit;
+}
+
+my $collection = $ARGV[0];
+my $oid        = $ARGV[1];
+my $field      = $ARGV[2];
+my $action     = $ARGV[3];
+my $a_value    = $ARGV[4];
+my $b_value    = "";
+if ($action eq "REPLACE")
+{
+  $b_value     = $ARGV[5];
+}
+
+# We pass a 1 to force the indexes to be updated too.
+if ($action eq "ADD")
+{
+  &IncrementalBuildUtils::setDocumentMetadata($collection, $oid, $field, "", $a_value, 1);
+}
+elsif ($action eq "REMOVE")
+{
+  &IncrementalBuildUtils::setDocumentMetadata($collection, $oid, $field, $a_value, "", 1);
+}
+elsif ($action eq "REPLACE")
+{
+  &IncrementalBuildUtils::setDocumentMetadata($collection, $oid, $field, $a_value, $b_value, 1);
+}
+
+exit;
Index: /gsdl/stable/bin/script/translate.pl
===================================================================
--- /gsdl/stable/bin/script/translate.pl	(revision 20131)
+++ /gsdl/stable/bin/script/translate.pl	(revision 20131)
@@ -0,0 +1,488 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# translate.pl 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# translate.pl takes a translated macro file (filename passed in on command
+# line) and generates any images required by it. Check out english.dm for
+# an example of the format translate.pl expects
+
+# translate.pl uses gimp to generate images so needs gimp installed and set
+# up for scripting with perl
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+}
+
+use Gimp qw/:auto :DEFAULT/;
+use parsargv;
+use util;
+use unicode;
+
+# these html entities will be translated correctly when occurring in 
+# images. Any entities not in this list will not.
+my %rmap = ('auml' => chr (228),
+	    'euml' => chr (235),
+	    'iuml' => chr (239),
+	    'ouml' => chr (246),
+	    'uuml' => chr (252),
+	    'Auml' => chr (196),
+	    'Euml' => chr (203),
+	    'Iuml' => chr (207),
+	    'Ouml' => chr (214),
+	    'Uuml' => chr (220),
+	    'szlig' => chr (223),
+	    'aacute' => chr (225),
+	    'eacute' => chr (233),
+	    'iacute' => chr (237),
+	    'oacute' => chr (243),
+	    'uacute' => chr (250),
+	    'Aacute' => chr (193),
+	    'Eacute' => chr (201),
+	    'Iacute' => chr (205),
+	    'Oacute' => chr (211),
+	    'Uacute' => chr (218),
+	    'agrave' => chr (224),
+	    'egrave' => chr (232),
+	    'igrave' => chr (236),
+	    'ograve' => chr (242),
+	    'ugrave' => chr (249),
+	    'Agrave' => chr (192),
+	    'Egrave' => chr (200),
+	    'Igrave' => chr (204),
+	    'Ograve' => chr (210),
+	    'Ugrave' => chr (217),
+	    'ntilde' => chr (241),
+	    'Ntilde' => chr (209),
+	    'atilde' => chr (227),
+	    'Atilde' => chr (195),
+	    'otilde' => chr (245),
+	    'Otilde' => chr (213),
+	    'ccedil' => chr (231),
+	    'Ccedil' => chr (199),
+	    'ecirc' => chr (234),
+	    'Ecirc' => chr (202),
+	    'acirc' => chr (226),
+	    'Acirc' => chr (194),
+	    );
+
+my $hand_made = 0;
+
+sub print_usage {
+    print STDERR "\n";
+    print STDERR "translate.pl: Uses gimp to generate any images required by a\n";
+    print STDERR "              Greenstone macro file.\n\n";
+    print STDERR "  usage: $0 [options] macrofile\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -save_orig_file       edited macrofile will be written to\n";
+    print STDERR "                         macrofile.new leaving macrofile unchanged\n";
+    print STDERR "   -language_symbol      ISO abbreviation of language (e.g. German=de,\n";
+    print STDERR "                         French=fr, Maori=mi)\n";
+    print STDERR "   -image_dir directory  full path to directory in which to create images\n";
+    print STDERR "                         (defaults to `pwd`/images)\n\n";
+}
+
+sub gsdl_translate {
+
+    if (!parsargv::parse(\@ARGV, 
+			 'save_orig_file', \$save_orig_file,
+			 'language_symbol/[A-Za-z]{2}', \$language_symbol,
+			 'image_dir/.*/images', \$image_dir)) {
+	&print_usage();
+	die "\n";
+    }
+
+    if ($image_dir eq "images") {
+	$image_dir = `pwd`;
+	chomp $image_dir;
+	$image_dir = &util::filename_cat ($image_dir, "images");
+    }
+
+    if (!defined $ARGV[0]) {
+	print STDERR "no macro file supplied\n\n";
+	&print_usage();
+	die "\n";
+    }
+    my $macrofile = $ARGV[0];
+    die "\nmacrofile $macrofile does not exist\n\n" unless -e $macrofile;
+
+    if (!-e $image_dir) {
+	mkdir ($image_dir, 511) || die "\ncouldn't create image_dir $image_dir\n\n";
+    }
+
+    open (INPUT, $macrofile) || die "\ncouldn't open $macrofile for reading\n\n";
+    open (OUTPUT, ">$macrofile.new") || die "\ncouldn't open temporary file $macrofile.new for writing\n\n";
+
+    &parse_file (INPUT, OUTPUT);
+
+    close OUTPUT;
+    close INPUT;
+
+    if (!$save_orig_file) {
+	`mv $macrofile.new $macrofile`;
+    }
+
+    print STDERR "\n\n";
+    print STDERR "translation of macro file $macrofile completed\n";
+    print STDERR "the translated macro file is $macrofile.new\n" if $save_orig_file;
+    print STDERR "\n";
+    if ($hand_made) {
+	print STDERR "$hand_made hand made images were found within $macrofile,\n";
+	print STDERR "these will need to be made by hand (grep $macrofile for 'hand_made'\n\n";
+    }
+    print STDERR "To add your new interface translation to Greenstone you'll need to:\n";
+    print STDERR "  1. Copy your new macro file to your GSDLHOME/macros directory\n";
+    print STDERR "  2. Add your new macro file to the macrofiles list in your\n";
+    print STDERR "     GSDLHOME/etc/main.cfg configuration file\n";
+    print STDERR "  3. Copy your newly created images from $image_dir to \n";
+    print STDERR "     GSDLHOME/images/$language_symbol/\n\n";
+    print STDERR "Access your new interface language by setting the language (l) cgi\n";
+    print STDERR "argument to '$language_symbol'\n\n";
+
+}
+
+sub parse_file {
+    my ($input, $output) = @_;
+
+    undef $/;
+    my $dmfile = <$input>;
+    $/ = "\n";
+
+    # process all the images
+
+    $dmfile =~ s/(?:^|\n)\#\#\s*\"([^\"]*)\"\s*\#\#\s*([^\s\#]*)\s*\#\#\s*([^\s\#]*)\s*\#\#(.*?)(?=(\n\#|\s*\Z))/&process_image ($1, $2, $3, $4)/esg;
+
+    # add language parameter to each macro
+    $dmfile =~ s/(\n\s*)(_[^_]*_)\s*(\[[^\]]*\])?\s*\{/$1 . &add_language_param ($2, $3)/esg;
+    
+    print $output $dmfile;
+}
+
+sub process_image {
+    my ($text, $image_type, $image_name, $image_macros) = @_;
+
+    my $origtext = $text;
+
+    $text =~ s/&(\d{3,4});/chr($1)/ge;
+    $text =~ s/&([^;]*);/$rmap{$1}/g;
+
+    # Default font is set by the individual scripts (flash_button-1.2.pl etc), usually lucida
+    my $fontchoice = "";
+
+    # special case for Kazakh images (can also handle Russian) - encode to match Kazakh font
+    if ($language_symbol eq "kz") {  # || $language_symbol eq "ru") {
+	$text = &unicode::unicode2singlebyte(&unicode::utf82unicode($text), "kazakh");
+	$fontchoice = " -foundry 2rebels -fontname \"helv kaz\"";
+    }
+    # special case for Russian images - font is koi8-r encoded
+    elsif ($language_symbol eq "ru") {
+	$text = &unicode::unicode2singlebyte(&unicode::utf82unicode($text), "koi8_r");
+	$fontchoice = " -foundry cronyx -fontname helvetica";
+    }
+    # special case for Thai images
+    elsif ($language_symbol eq "th") {
+	$text = &unicode::unicode2singlebyte(&unicode::utf82unicode($text), "windows_874");
+	$fontchoice = " -foundry monotype -fontname BrowalliaUPC -fontregistry tis620";
+    }
+    # special case for Ukrainian images - font is windows_1251 encoded 
+    elsif ($language_symbol eq "uk") {
+	$text = &unicode::unicode2singlebyte(&unicode::utf82unicode($text), "windows_1251");
+	$fontchoice = " -foundry rfx -fontname serene";
+    }
+
+    # edit image macros
+    $image_macros =~ s/(_httpimg_\/)(?:[^\/\}]*\/)?([^\}]*\.(?:gif|jpe?g|png))/$1$language_symbol\/$2/gs;
+
+    if ($image_type eq "top_nav_button") {
+
+	# generate images
+	my $options = "-text \"$text\" -filenamestem $image_name -image_dir $image_dir";
+	$options .= " -height 20 -whitespace";
+	$options .= $fontchoice;
+
+	# special case for Kazakh images (can also handle Russian)
+	if ($language_symbol eq "kz") {  # || $language_symbol eq "ru") {
+	    $options .= " -fontsize 10 -fontweight bold";
+	}
+	# special case for Russian images
+	elsif ($language_symbol eq "ru") {
+	    $options .= " -fontsize 10 -fontweight bold";
+	}
+	# special case for Thai images
+	elsif ($language_symbol eq "th") {
+	    $options .= " -fontsize 20 -fontweight bold";  # Browallia
+	}
+	# special case for Ukrainian images
+	elsif ($language_symbol eq "uk") {
+	    $options .= " -fontsize 10";
+	}
+	else {
+	    $options .= " -fontsize 12";
+	}
+	`$ENV{'GSDLHOME'}/bin/script/gimp/flash_button-1.2.pl $options`;
+
+	# get width of new images and edit width macro
+	# my $fullfilename = &util::filename_cat ($image_dir, "${image_name}on.gif");
+	# &process_width_macro ($fullfilename, $image_name, \$image_macros);
+
+    }
+    elsif ($image_type eq "nav_bar_button") {
+
+	# generate on and off images
+	my $options = "-text \"$text\" -filenamestem $image_name -image_dir $image_dir";
+	$options .= " -height 17 -fixed_width -width 87";
+	$options .= $fontchoice;
+
+	# special case for Thai images
+	if ($language_symbol eq "th") {
+	    $options .= " -fontsize 18 -fontweight bold";  # Browallia
+	}
+	else {
+	    $options .= " -fontsize 17";
+	}
+
+	`$ENV{'GSDLHOME'}/bin/script/gimp/flash_button-1.2.pl $options`;
+
+	# generate green image
+	$options = "-text \"$text\" -filenamestem ${image_name}gr -image_dir $image_dir";
+	$options .= " -height 17 -fixed_width -width 87";
+	$options .= " -bgcolor \"#96c19b\"";
+	$options .= $fontchoice;
+
+	# special case for Thai images
+	if ($language_symbol eq "th") {
+	    $options .= " -fontsize 18 -fontweight bold";  # Browallia
+	}
+	else {
+	    $options .= " -fontsize 17";
+	}
+
+	`$ENV{'GSDLHOME'}/bin/script/gimp/flash_button-1.2.pl $options`;
+
+	# delete the unused light image
+	unlink(util::filename_cat($image_dir, "${image_name}gr" . "of.gif"));
+
+	# rename the dark image
+	&util::mv(util::filename_cat($image_dir, "${image_name}gr" . "on.gif"),
+		util::filename_cat($image_dir, "$image_name" . "gr.gif"));
+
+	# get width of new images and edit width macro
+	my $fullfilename = &util::filename_cat ($image_dir, "${image_name}on.gif");
+	&process_width_macro ($fullfilename, $image_name, \$image_macros);
+
+    }
+    elsif ($image_type eq "document_button") {
+
+	# generate on and off images
+	my $options = "-text \"$text\" -filenamestem $image_name -image_dir $image_dir";
+	$options .= " -fixed_width -whitespace";
+	$options .= $fontchoice;
+
+	# special case for Kazakh images (can also handle Russian)
+	if ($language_symbol eq "kz") {  # || $language_symbol eq "ru") {
+	    $options .= " -fontsize 8";
+	}
+	# special case for Russian images
+	elsif ($language_symbol eq "ru") {
+	    $options .= " -fontsize 8";
+	}
+	# special case for Thai images
+	elsif ($language_symbol eq "th") {
+	    $options .= " -fontsize 22 -fontweight bold";  # Browallia
+	}
+	# special case for Ukrainian images
+	elsif ($language_symbol eq "uk") {
+	    $options .= " -fontsize 8";
+	}
+	`$ENV{'GSDLHOME'}/bin/script/gimp/flash_button-1.2.pl $options`;
+
+	# get width of new images and edit width macro
+	# my $fullfilename = &util::filename_cat ($image_dir, "${image_name}on.gif");
+	# &process_width_macro ($fullfilename, $image_name, \$image_macros);
+
+    }
+    elsif ($image_type eq "collector_bar_button") {
+
+	$text =~ s/\\n/\n/g;
+	if ($text !~ /\n/) {
+	    # Format the text so it is centered, one word per line
+	    local @textparts = split(/[ \t\n]+/, $text);
+	    local $maxlength = 0;
+	    for ($i = 0; $i < scalar(@textparts); $i++) {
+		if (length($textparts[$i]) > $maxlength) {
+		    $maxlength = length($textparts[$i]);
+		}
+	    }
+	    $text = "";
+	    for ($i = 0; $i < scalar(@textparts); $i++) {
+		if (length($textparts[$i]) < $maxlength) {
+		    $text .= ' ' x ((($maxlength - length($textparts[$i])) / 2) + 1);
+		}
+		$text .= $textparts[$i] . "\n";
+	    }
+	}
+
+	# generate on and off images (yellow)
+	my $options = "-text \"$text\" -filenamestem yc$image_name -image_dir $image_dir";
+	$options .= " -width 77 -height 26 -fixed_width -whitespace -fontsize 13";
+	$options .= $fontchoice;
+
+	`$ENV{'GSDLHOME'}/bin/script/gimp/flash_button-1.2.pl $options`;
+
+	# generate on and off images (green)
+	$options = "-text \"$text\" -filenamestem gc$image_name -image_dir $image_dir";
+	$options .= " -width 77 -height 26 -fixed_width -whitespace -fontsize 13";
+	$options .= " -bgcolor \"#96c19b\"";
+	$options .= $fontchoice;
+
+	`$ENV{'GSDLHOME'}/bin/script/gimp/flash_button-1.2.pl $options`;
+
+	# generate on and off images (grey) - only the light image (off) is used
+	$options = "-text \"$text\" -filenamestem nc$image_name -image_dir $image_dir";
+	$options .= " -width 77 -height 26 -fixed_width -whitespace -fontsize 13";
+	$options .= " -bgcolor \"#7E7E7E\" -fontcolor \"#a0a0a0\"";
+	$options .= $fontchoice;
+
+	`$ENV{'GSDLHOME'}/bin/script/gimp/flash_button-1.2.pl $options`;
+
+	# delete the unused dark image
+	unlink(util::filename_cat($image_dir, "nc$image_name" . "on.gif"));
+
+    }
+    elsif ($image_type eq "green_bar_left_aligned") {
+
+	# generate green bar image (we're assuming these bars are always 537
+	# pixels and are never stretched by excess text
+	my $options = "-text \"$text\" -filename ${image_name}.gif -image_dir $image_dir";
+	$options .= " -dont_center -width 537 -width_space 15";
+	$options .= $fontchoice;
+
+	# special case for Thai images
+	if ($language_symbol eq "th") {
+	    $options .= " -fontsize 18 -fontweight bold";  # Browallia
+	}
+
+	`$ENV{'GSDLHOME'}/bin/script/gimp/green_bar-1.2.pl $options`;
+
+    }
+    elsif ($image_type eq "green_title") {
+	
+	# read the width if it is specified in $image_macros
+        my ($width) = $image_macros =~ /_width${image_name}x?_\s*[^\{]*\{(\d+)\}/;
+        $width = 200 unless ($width);
+
+        # generate green title image
+	my $options = "-text \"$text\" -filename ${image_name}.gif -image_dir $image_dir";
+	$options .= " -width $width -height 57 -stripe_alignment right -text_alignment right";
+        $options .= $fontchoice;
+
+        # special case for Thai images
+        if ($language_symbol eq "th") {
+	    $options .= " -fontsize 50 -fontweight bold";  # Browallia
+	}
+        else {
+	    $options .= " -fontsize 26 -fontweight bold";
+	}
+
+	`$ENV{'GSDLHOME'}/bin/script/gimp/title_icon-1.2.pl $options`;
+
+	# get width of resulting image and edit _width..._ macro in $image_macros
+        # (no longer needed since we always resize to the width read from $image_macros.)
+        # my $fullfilename = &util::filename_cat ($image_dir, "${image_name}.gif");
+	# &process_width_macro ($fullfilename, $image_name, \$image_macros);
+
+    }
+    elsif ($image_type eq "hand_made") {
+
+	$hand_made ++;
+
+    }
+    else {
+	
+	print STDERR "WARNING (translate.pl): unknown image type found ($image_type)\n";
+
+    }
+
+    return "\n\#\# \"$origtext\" \#\# $image_type \#\# $image_name \#\#$image_macros";
+}
+
+sub process_width_macro {
+    my ($filename, $image_name, $image_macros) = @_;
+
+    my $img_info = &get_img_info ($filename);
+    $$image_macros =~ s/(_width${image_name}x?_\s*(?:\[[^\]]*\])?\s*\{)(\d+)(\})/$1$img_info->{'width'}$3/s;
+}
+
+sub add_language_param {
+    my ($macroname, $paramlist) = @_;
+
+    my $first = 1;
+    if (defined $paramlist) {
+	$paramlist =~ s/^\[//;
+	$paramlist =~ s/\]$//;
+	my @params = split /\,/, $paramlist;
+	$paramlist = "";
+	foreach $param (@params) {
+	    # remove any existing language parameter
+	    if ($param !~ /^l=/) {
+		$paramlist .= "," unless $first;
+		$paramlist .= $param;
+		$first = 0;
+	    }
+	}
+    }
+    $paramlist .= "," unless $first;
+    $paramlist .= "l=" . $language_symbol;
+    return "$macroname [$paramlist] {";
+}
+
+sub get_img_info {
+    my ($imagefile) = @_;
+    my %info = ();
+
+    if (!-r $imagefile) {
+	print STDERR "ERROR (translate.pl): couldn't open $imagefile to get dimensions\n";
+	$info{'width'} = 0;
+	$info{'height'} = 0;
+    } else {
+	my $image = gimp_file_load (RUN_NONINTERACTIVE, $imagefile, $imagefile);
+	$info{'width'} = gimp_image_width ($image);
+	$info{'height'} = gimp_image_height ($image);
+    }
+
+    return \%info;
+}
+
+sub query {
+
+  gimp_install_procedure("gsdl_translate", "translate macro files and create images",
+                        "", "Stefan Boddie", "Stefan Boddie", "2000-03-14",
+                        "<Toolbox>/Xtns/gsdl_translate", "*", &PROC_EXTENSION,
+                        [[PARAM_INT32, "run_mode", "Interactive, [non-interactive]"]], []);
+}
+
+Gimp::on_net {   gsdl_translate; };
+exit main;
Index: /gsdl/stable/bin/script/txtgz-to-gdbm.pl
===================================================================
--- /gsdl/stable/bin/script/txtgz-to-gdbm.pl	(revision 20131)
+++ /gsdl/stable/bin/script/txtgz-to-gdbm.pl	(revision 20131)
@@ -0,0 +1,59 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# txtgz-to-gdbm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This script invokes gzip to unzip the textual database. It is necessary, 
+# since the C++ code that directly invokes it fails on Windows. The added
+# benefit of doing this via the perl script here is that if an external
+# webserver was used (such as Apache), it will probably still work.
+
+
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and vice versa
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+
+my $txtgz_filename = $ARGV[0];
+my $gdbm_filename = $ARGV[1];
+
+	
+if (scalar(@ARGV)!=2) {
+    my ($prog_name) = ($0 =~ m/^.*\/(.*?)$/);
+
+    print STDERR "Usage: $prog_name txtgz_filename gdbm_filename\n";
+    exit -1;
+}
+
+my $cmd = "gzip --decompress --to-stdout \"$txtgz_filename\" | txt2db \"$gdbm_filename\"";
+
+my $ret_status = system($cmd);
+
+#print STDERR "***## system error message $!\n";
+#print STDERR "***## ret status = $ret_status\n";
+
+#return $ret_status;
+
Index: /gsdl/stable/bin/script/unbuildv1.pl
===================================================================
--- /gsdl/stable/bin/script/unbuildv1.pl	(revision 20131)
+++ /gsdl/stable/bin/script/unbuildv1.pl	(revision 20131)
@@ -0,0 +1,747 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# unbuildv1.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# this program will decompress all the text from a built index
+# and return it to gml format - this version of the program is designed to
+# work on collections built with the first version of the greenstone software
+# it extracts the browse classifications from the gdbm file, and recreates 
+# them. It also creates a default collect.cfg file.
+
+# To run, this program needs the old archive directory (called archives),
+# the index directory with the text and one other index, not paragraphs!! -
+# use one of the section indexes. Also needs the build.cfg file (in the
+# index dir) - used in creating a collect.cfg file. If build.cfg is not
+# present, the parts of the collect.cfg file relating to indexes will not
+# be entered.
+
+# Stefan altered this script slightly August 2002 to use
+# $GSDLHOME/bin/$GSDLOS/mgquery_old instead of the old mgquery in
+# nzdl-1.2. mgquery_old is a statically linked binary compiled from
+# mg-1.3d. It was compiled with SHORT_SUFFIX set so doesn't need the index
+# file extensions to be altered. 
+# Also changed the command line options a little.
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    $FileHandle = 'FH000';
+}
+
+use doc;
+use util;
+use parsargv;
+use FileHandle;
+use English;
+use cfgread;
+use unicode;
+use plugout;
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+
+# globals
+$collection = "";  # the collection name
+$index = "";  # the selected index (like stt/unu)
+$textdir = ""; # the textdir (like text/unu)
+$toplevelinfo = []; #list of document OIDs
+%infodb = (); #hash into GDBM file
+$classifyinfo = []; # list of classifications
+$doc_classif_info = {};  # hash of OIDs->classifications they belong to
+$collect_cfg = {}; #data for the configuration file
+$mgread = ++$FileHandle;
+$mgwrite = ++$FileHandle;
+
+sub print_usage {
+    print STDERR "\n  usage: $0 [options]\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -verbosity number      0=none, 3=lots\n";
+    print STDERR "   -old directory         The directory in which the old collection lives\n";
+    print STDERR "   -new directory         The directory in which to put the new collection\n";
+}
+
+&main ();
+
+sub main {
+    if (!parsargv::parse(\@ARGV, 
+			 'verbosity/\d+/2', \$verbosity,
+			 'old/.*/', \$old,
+			 'new/.*/', \$new)) {
+	&print_usage();
+	die "\n";
+    }
+
+    die "$old does not exist\n\n" unless (-d $old);
+    my $old_indexdir = &util::filename_cat($old, "index");
+    my $old_archivedir = &util::filename_cat($old, "archives");
+
+    my $new_archivedir = &util::filename_cat($new, "archives");
+    my $new_etcdir = &util::filename_cat($new, "etc");
+    if (!-e $new_archivedir) {
+	&util::mk_all_dir($new_archivedir);
+    }
+    if (!(-d $new_etcdir)) {
+	&util::mk_all_dir($new_etcdir);
+    }
+
+    my $gdbmfile = &get_gdbmfile($old_indexdir); # sets $collection and $textdir
+    &set_index($old_indexdir);  # sets $index (just chooses one index)
+
+    my $buildcfgfile = &util::filename_cat($old_indexdir, "build.cfg");
+    my $colcfgfile = &util::filename_cat($new_etcdir, "collect.cfg");
+
+    # don't need this but giving it a value stops an annoying undefined
+    # value warning
+    $ENV{'GSDLCOLLECTDIR'} = 'tmp';
+
+    &add_default_cfg();
+    &add_index_cfg($buildcfgfile);
+
+    # work out all the classifications from the gdbm file, info for each doc
+    # (ie which classifications they belong to, are kept in $doc_classif_info
+    &get_classifyinfo($gdbmfile); #puts a list of classifications into classifyinfo
+    &get_toplevel_OID($gdbmfile); # puts a list of the top level document OIDs into $toplevelinfo
+
+    # read ldb file into %infodb
+    &read_gdbm($gdbmfile);
+
+    #this makes the files specifying the hierarchy of subjects, titles etc
+    foreach my $classify (@$classifyinfo) {
+	&make_info_file($new_etcdir, $classify);
+    }
+    
+    # write out the collect.cfg
+    &output_cfg_file($colcfgfile);
+
+    &openmg($old_indexdir);
+
+    # read the archive information file
+    my $archive_info_filename = &util::filename_cat ($new_archivedir, "archives.inf");
+    my $archive_info = new arcinfo ();
+
+    my $opts = [];
+    push @$opts,("-output_info",$archive_info); 
+
+    $processor = &plugout::load_plugout("GreenstoneXMLPlugout",$opts); 
+    $processor->setoutputdir ($new_archivedir);
+
+    my ($doc_obj, $hashref, $children);
+    print STDERR "processing documents now\n" if $verbosity >=2;
+    foreach $oid (@$toplevelinfo) {
+	$value = $infodb{$oid};
+	$hashref={};
+	$children = [];
+	&get_metadata($value, $hashref);
+	$doc_obj = new doc ();
+	$doc_obj->set_OID($oid);
+	my ($olddir) = $hashref->{'archivedir'}; # old dir for this doc, where images are stored
+	$top = $doc_obj->get_top_section();
+	&add_section_content ($doc_obj, $top, $hashref, $olddir);
+	&add_classification_metadata($oid, $doc_obj, $top);
+	&add_cover_image($doc_obj, $old_archivedir, $olddir);
+	&get_children($hashref, $children);
+	&recurse_sections($doc_obj, $children, $oid, $top, $olddir) if (defined ($children));
+
+	#change OID to new format
+	$doc_obj->delete_OID();
+	$doc_obj->set_OID();
+	$processor->process($doc_obj);
+#	last;
+    }
+    print STDERR "\n";
+   
+    &closemg();
+
+    # write out the archive information file
+    $archive_info->save_info($archive_info_filename);
+   
+    
+}
+
+# returns the path to the gdbm info database - also
+# sets the $collection and $textdir global variable
+sub get_gdbmfile {
+    my ($indexdir) = @_;
+    my ($gdbmfile);
+
+    opendir (DIR, $indexdir) || die "Couldn't open directory $indexdir\n\n";
+    my @conts = readdir DIR;
+    close DIR;
+
+    foreach $file (@conts) {
+	if ($file =~ /text$/) {
+	    $textdir = $file;
+	    last;
+	}
+    }
+    die "No text directory found in $indexdir\n\n" 
+	unless defined $textdir && $textdir =~ /text$/;
+
+    $gdbmfile = &util::filename_cat ($indexdir, $textdir);
+
+    opendir (DIR, $gdbmfile) || die "Couldn't open directory $gdbmfile\n\n";
+    @conts = readdir DIR;
+    close DIR;
+
+    foreach my $file (@conts) {
+	if ($file =~ /^(.*?)\.(?:ldb|bdb)$/) {
+	    $collection = $1;
+	    $gdbmfile = &util::filename_cat ($gdbmfile, $file);
+	    last;
+	}
+    }
+    
+    if (defined $collection && $collection =~ /\w/) {
+	$textdir = &util::filename_cat ($textdir, $collection);
+    } else {
+	die "collection global wasn't set\n";
+    }
+    return $gdbmfile if (-e $gdbmfile);
+    die "Couldn't find gdbm info database in $indexdir\n\n";
+}
+
+
+#this function will probably need to be changed for any different file formats
+sub get_toplevel_OID {
+    my ($gdbmfile) = @_;
+
+    open (DB2TXT, "db2txt $gdbmfile |") || die "couldn't open pipe to db2txt\n";
+    print STDERR "Finding all top level sections from $gdbmfile\n" if $verbosity >= 2;
+
+    $/ = '-' x 70;
+    my $entry = "";
+    while (defined ($entry = <DB2TXT>)) {
+	next unless $entry =~ /\w/;  #ignore blank entries
+	$entry =~ s/\n+/\\n/g;  # replace multiple \n with single \n
+	my ($key, $value) = $entry =~ /\[([^\]]*)\](.*)/;
+
+	next unless ($key =~ /B\.\d*$/); # assumes top level OID is like
+	                                 # B.12
+
+	push( @$toplevelinfo, $key);
+   
+    }
+
+    $/ = "\n";
+}
+    
+# gets all the metadata from a gdbm file entry, and puts it into a hashref
+#this has changed for old style formats
+sub get_metadata {
+
+    my ($gdb_str_ref, $hashref) = @_;
+#    print STDERR $gdb_str_ref;
+    my @entries = split(/\n/, $gdb_str_ref);
+
+    my $hastext = 1;
+    foreach $entry (@entries) {
+	
+	my($key, $value) = ($entry =~ /^<([^>]*)>(.*?)$/ );
+
+	next if ($key eq "p");
+	next if ($key eq "j");
+	
+	$key = "Title" if $key eq "t";
+	$key = "docnum" if $key eq "d";	
+	if ($key eq "o") {
+	    $key = "archivedir";
+	    $value =~ s/HASH/hash/;
+	}
+	if ($key eq "c") {
+	    $key = "contains";
+	    $hastext=0;}
+
+	$$hashref{$key} .= $value;
+						  
+    }
+    
+    $$hashref{'hastxt'} = $hastext;
+
+}					  
+
+# takes a hashref containing the metadata for a gdbmfile entry, and
+# extracts the childrens numbers (from the 'contains' entry).  assumes
+# format is like B.14.1:B.24.2:B.24.3 returns a list like 1 2 3 4
+sub get_children {	
+    my ($hashref, $children) = @_; 
+
+    my $childs = $hashref->{'contains'};
+    if (defined ($childs)) {
+	@xchildren = split /\:/, $childs;
+	foreach $kid (@xchildren) {
+	    my ($child)= $kid =~ /\.([^\.]*)(?:\\n|$)/;
+	    push (@$children, $child);
+	}
+#	print STDERR "children are: ", @$children;
+    }
+    else {
+	$children = [];
+    }
+}
+
+#takes a hashref containing the metadata for a gdbmfile entry, and extracts 
+#the childrens numbers (from the 'contains' entry).	
+#assumes format is like B.14.1:B.24.2:B.24.3
+#returns a list with the full child name ie B.14.1 B.14.2 etc
+#used for classification stuff
+sub get_whole_children {	
+
+    my ($hashref, $children) = @_; 
+
+    my $childs = $hashref->{'contains'};
+    if (defined ($childs)) {
+	@$children = split /\:/, $childs;
+	#print STDERR "children are: ", @$children;
+    }
+    else {
+	$children = [];
+    }
+}
+    
+sub recurse_sections {
+    my ($doc_obj, $children, $parentoid, $parentsection, $olddir) = @_;
+
+    foreach $child (sort numerically @$children) {
+	$doc_obj->create_named_section("$parentsection.$child");
+	my $value = $infodb{"$parentoid.$child"};
+	my $hashref={};
+	&get_metadata($value, $hashref); # get childs metadata
+	my $newchildren = [];
+	&get_children($hashref, $newchildren); # get childs children
+	#add content fo rcurrent section
+	&add_section_content($doc_obj, "$parentsection.$child", $hashref, $olddir);
+	# process all the children if there are any
+	&recurse_sections($doc_obj, $newchildren, "$parentoid.$child", "$parentsection.$child", $olddir)
+	    if (defined ($newchildren));
+    }
+}					     
+
+sub add_section_content {
+    my ($doc_obj, $cursection, $hashref, $olddir) = @_;
+    
+    foreach $key (keys %$hashref) {
+	#dont need to store these metadata
+	next if $key =~ /(contains|docnum|hastxt|doctype|archivedir|classifytype)/i;
+	my @items = split /@/, $hashref->{$key};
+	map {$doc_obj->add_metadata ($cursection, $key, $_); } @items;
+	
+    }
+
+    my ($hastext) = $hashref->{'hastxt'} =~ /(0|1)/;
+    if ($hastext) {
+	
+	my ($docnum)= $hashref->{'docnum'} =~ /(\d*)/;
+	my $text = &get_text($docnum);
+	$doc_obj->add_text ($cursection, $text);
+	
+	my (@images) = $text =~ /<img.*?src=\"([^\"]*)\"[^>]*>/g;
+	
+	if (scalar(@images)>0) {
+	    
+	    foreach $img (@images) {
+		my ($assoc_file) = $img =~ /([^\/\\]*\..*)$/; #the name of the image
+		$img =~ s/_httpcollection_/$old/; #replace _httpcollection_ with path to old collection
+		$olddir =~ s/HASH/hash/;
+		$img =~ s/_thisOID_/$olddir/; #replace _thisOID_ with old archivedir name   #the path to the image
+		$img = lc $img; # doc names and path upper case in file, lower
+		# case in directory
+		if (-e $img) {
+		    $doc_obj->associate_file($img, $assoc_file);
+		} else {
+		    print STDERR "WARNING: $img does not exist\n";
+		}
+	    }
+	    
+	}
+    }
+}
+
+
+sub add_classification_metadata {
+
+    my ($oid, $doc_obj, $cursection) = @_;
+    
+    if (defined $doc_classif_info->{$oid}) {
+
+	$hashref = $doc_classif_info->{$oid};
+	
+	foreach $key (keys %$hashref) {
+	    my @items = @{$hashref->{$key}};
+	    map {$doc_obj->add_metadata ($cursection, $key, $_); } @items;
+	}
+    }
+}
+# picks up the cover image "cover.jpg" from the old archives directory.
+sub add_cover_image {
+    my ($doc_obj, $archivedir, $olddir) =  @_;
+    $assoc_file = "cover.jpg";
+    $img = &util::filename_cat($archivedir, $olddir, $assoc_file);
+
+    if (-e $img) {
+	$doc_obj->associate_file($img, $assoc_file);
+    } else {
+	print STDERR "WARNING: couldn't find $img\n";
+    }
+}
+
+sub set_index {
+    my ($indexdir) = @_;
+
+    # check that $collection has been set
+    die "collection global was not set\n"
+	unless defined $collection && $collection =~ /\w/;
+
+    # find an index (just use first non-text and non-paragraph directory we
+    # come across in $indexdir)
+    opendir (INDEXDIR, $indexdir) || die "couldn't open directory $indexdir\n";
+    my @indexes = readdir INDEXDIR;
+    close INDEXDIR;
+    foreach $i (@indexes) {
+	next if $i =~ /text$/i || $i =~ /\./ || $i =~ /^p/i;
+	$index = &util::filename_cat ($i, $collection);
+	last;
+    }
+}
+
+
+#########################################################################
+
+################ functions involving mg ################################
+sub get_text {
+    my ($docnum) = @_;
+
+    print STDERR "." if $verbosity >= 2;
+    &mgcommand ($docnum);
+
+   <$mgread>;	# eat the document separator
+
+    my $text = "";
+    my $line = "";
+
+    while (defined ($line = <$mgread>))
+    {
+	last if $line =~ /^<\/mg>/;
+	$text .= $line;
+    }
+
+    # Read in the last statement, which should be:
+    #  "dd documents retrieved."
+    <$mgread>;
+
+    return $text;
+}
+
+
+sub numerically {$a <=> $b;}
+
+
+
+# mg stuff
+
+sub openmg {
+    my ($indexdir) = @_;
+
+    die "Unable to start mgquery." unless
+	&openpipe($mgread, $mgwrite, "mgquery_old -d $indexdir -f $index -t $textdir");
+
+    $mgwrite->autoflush();
+    &mgcommand('.set expert true');
+    &mgcommand('.set terminator "</mg>\n"');
+    &mgcommand('.set mode text');
+    &mgcommand('.set query docnums');
+    &mgcommand('.set term_freq off');
+}
+
+sub closemg {
+    &mgcommand (".quit");
+    close($mgread);
+    close($mgwrite);
+}
+
+sub mgcommand {
+    my ($command) = @_;
+
+    return if $command =~ /^\s*$/;  #whitespace
+    #print STDERR "command: $command\n";
+    print $mgwrite "$command\n";
+
+    # eat up the command executed which is echoed
+    <$mgread>;
+}
+
+# openpipe(READ, WRITE, CMD)
+# 
+# Like open2, except CMD's stderr is also redirected.
+# 
+sub openpipe
+{
+    my ($read, $write, $cmd) = @_;
+    my ($child_read, $child_write);
+
+    $child_read = ++$FileHandle;
+    $child_write = ++$FileHandle;
+
+    pipe($read, $child_write) || die "Failed pipe($read, $child_write): $!";
+    pipe($child_read, $write) || die "Failed pipe($child_read, $write): $!";
+    my $pid;
+
+    if (($pid = fork) < 0) {
+        die "Failed fork: $!";
+    } elsif ($pid == 0) {
+        close($read);
+        close($write);
+        open(STDIN, "<&$child_read");
+        open(STDOUT, ">&$child_write");
+        open(STDERR, ">&$child_write");
+        exec($cmd);
+        die "Failed exec $cmd: $!";
+    }
+
+    close($child_read);
+    close($child_write);
+
+    $write->autoflush();
+    $read->autoflush();
+
+    return 1;
+}
+
+
+######################################################################
+
+############# functions to do with the classificaiton stuff ##########
+sub get_classifyinfo {
+    my ($gdbmfile) = @_;
+
+    open (DB2TXT, "db2txt $gdbmfile |") || die "couldn't open pipe to db2txt\n";
+    print STDERR "Finding all classification sections from $gdbmfile\n" ;
+
+    $/ = '-' x 70;
+    my $entry = "";
+    while (defined ($entry = <DB2TXT>)) {
+	next unless $entry =~ /\w/;  #ignore blank entries
+	$entry =~ s/\n+/\\n/g;  # replace multiple \n with single \n
+	my ($key, $value) = $entry =~ /\[([^\]]*)\](.*)/;
+
+	next unless ($key =~/^[A-Z]$/); # assumes classification OID is like
+	                                 # C or T etc
+
+	push( @$classifyinfo, $key);
+   
+    }
+
+    $/ = "\n";
+}
+
+#this creates the classification files needed for the hierarchy classifier
+#used for subjects, titles, orgs etc
+#also adds in entries to the collect_cfg hash    
+sub make_info_file {
+    my ($etcdir, $classifier) = @_;
+    my $info_file = "";
+
+    $info_file = &util::filename_cat($etcdir, "CL.${classifier}.txt");
+    $classifier_name = "CL.$classifier";
+    print STDERR "classification $classifier will be called CL.$classifier\n";
+
+    open (OUTDOC, ">$info_file" ) || die  "couldn't open file $info_file\n";
+	
+    my $entry = $infodb{$classifier};
+    #print STDERR "entry = $entry\n";
+    my $hashref = {};
+    &get_metadata($entry, $hashref);
+    my $children=[];
+    &get_whole_children($hashref, $children);
+    foreach $child (@$children) {
+	&process_entry(OUTDOC, $classifier_name, $child);
+    }
+  
+    close OUTDOC;
+    
+    &add_classify_cfg($classifier, $classifier_name, $info_file);
+    
+}
+
+
+sub process_entry {
+    my ($handle, $classifier_name, $classify_id) = @_;
+
+    my $value = $infodb{$classify_id};
+    my $hashref={};
+    &get_metadata($value, $hashref);
+    my $title = $hashref->{'Title'};
+
+    &add_line($handle, $classify_id, $title);
+    
+    my $children = [];
+    &get_whole_children($hashref, $children);
+    foreach $child (@$children) {
+	if (&is_document($child)) {
+	    &add_doc_metadata($child, $classifier_name, $classify_id);
+	}
+	else {
+	    &process_entry($handle, $classifier_name, $child);
+	}
+    }
+}
+
+sub add_doc_metadata {
+    my ($doc_id, $classifier_name, $classifier_id) = @_;
+
+    #add entry to doc database
+    #print STDERR "at doc level, docnum=$classify_id\n";
+    $doc_classif_info->{$doc_id}={} unless defined $doc_classif_info->{$doc_id};
+    $doc_classif_info->{$doc_id}->{$classifier_name}=[] unless
+	defined $doc_classif_info->{$doc_id}->{$classifier_name};
+    push (@{$doc_classif_info->{$doc_id}->{$classifier_name}}, $classifier_id); 
+}
+
+sub add_line {
+    my ($handle, $classify_id, $title) = @_;
+    $title = &unicode::ascii2utf8(\$title);
+    my ($num) = $classify_id =~ /^[A-Z]\.(.*)$/; #remove the C. from the front
+    print $handle "$classify_id\t$num\t\"$title\"\n";
+}
+
+sub is_document {
+    my ($oid) = @_;
+    return 1 if $oid =~ /^B\.\d/;
+    return 0;
+}
+    
+########################################################################
+
+########## stuff for producing collect.cfg file ###########################
+
+sub add_default_cfg {
+
+    $username=`whoami`;
+    $username=`logname` unless defined $username;
+    $username="a_user" unless defined $username;
+    $username =~ s/\n//;
+    $collect_cfg->{'creator'}="$username\@cs.waikato.ac.nz";
+    $collect_cfg->{'maintainer'}="$username\@cs.waikato.ac.nz";
+    $collect_cfg->{'public'}="true";
+    
+    $collect_cfg->{'plugin'}=[];
+    push (@{$collect_cfg->{'plugin'}}, ["GreenstoneXMLPlugin"]);
+    push (@{$collect_cfg->{'plugin'}}, ["ArchivesInfPlugin"]);
+    push (@{$collect_cfg->{'plugin'}}, ["DirectoryPlugin"]);
+
+    $collect_cfg->{'format'}={};
+    $collect_cfg->{'format'}->{'DocumentImages'}="true";
+    $collect_cfg->{'format'}->{'DocumentText'} = 
+	"\"<h3>[Title]</h3>\\\\n\\\\n<p>[Text]\"";
+    $collect_cfg->{'format'}->{'SearchVList'} =
+	"\"<td valign=top>[link][icon][/link]</td><td>{If}{[parent(All': '):Title],[parent(All': '):Title]:}[link][Title][/link]</td>\"";
+
+    $collect_cfg->{'collectionmeta'}={};
+    $collect_cfg->{'collectionmeta'}->{'collectionname'}="\"$collection\"";
+    $collect_cfg->{'collectionmeta'}->{'iconcollection'}="\"_httpprefix_/collect/$collection/images/$collection.gif\"";
+    $collect_cfg->{'collectionmeta'}->{'iconcollectionsmall'}="\"_httpprefix_/collect/$collection/images/${collection}sm.gif\"";
+    $collect_cfg->{'collectionmeta'}->{'collectionextra'} = "\"This is a collection rebuilt from CDROM.\"";
+
+}
+
+sub add_index_cfg {
+  my ($buildfile) = @_;
+
+  my $data={};
+  $collect_cfg->{'indexes'}=[];
+  if (-e $buildfile) {
+      $data=&cfgread::read_cfg_file($buildfile, '^(this)$', '^(indexmap)$'); 
+      foreach my $i (@{$data->{'indexmap'}}) {
+          my ($thisindex, $abbrev)= split (/\-\>/, $i);
+          push (@{$collect_cfg->{'indexes'}}, $thisindex);
+	  $collect_cfg->{'defaultindex'} = $thisindex unless defined 
+	      $collect_cfg->{'defaultindex'};
+          $name=&get_index_name($thisindex);
+	  $thisindex=".$thisindex";
+          $collect_cfg->{'collectionmeta'}->{$thisindex} = "\"$name\"";
+      } 
+  }
+  else {
+      print STDERR "Couldn't read $buildfile, could not add index data to configuration file\n";
+  }
+
+}
+
+sub get_index_name {
+    my ($thisindex) = @_;
+    return "paragraphs" if $thisindex =~ /paragraph/;
+    return "chapters" if $thisindex =~ /section.*text/;
+    return "titles" if $thisindex =~ /Title/;
+    return "other";
+}
+
+sub add_classify_cfg {
+
+    my ($classify, $metadata, $file) = @_;
+    $collect_cfg->{'classify'} = [] unless defined $collect_cfg->{'classify'};
+
+    my ($title);
+    $title = "Howto" if $classify eq 'H';
+    $title = "Subject" if $classify eq 'C';
+    $title = "Organization" if $classify eq 'O';
+    $title = "Title" if $classify eq 'T';
+    $title = "Other" unless defined $title;
+
+    my ($filename) = $file =~ /\/([^\/]*)$/;
+    my $entry = "Hierarchy -hfile $filename -metadata $metadata -buttonname $title -sort Title";
+    $entry .= " -hlist_at_top" if $title eq "Title";
+    push (@{$collect_cfg->{'classify'}},[$entry]);
+   
+
+}
+
+sub output_cfg_file {
+
+    my ($collfile) = @_;
+    &cfgread::write_cfg_file($collfile, $collect_cfg, 
+			     '^(creator|maintainer|public|beta|defaultindex)$',
+                            '^(indexes)$', '^(format|collectionmeta)$',
+                            '^(plugin|classify)$');
+}
+
+sub read_gdbm {
+    my ($filename) = @_;
+
+    open (PIPEIN, "db2txt \"$filename\" |") || die "couldn't open pipe from db2txt\n";
+    my $line = ""; my $key = ""; my $value = "";
+    while (defined ($line = <PIPEIN>)) {
+	if ($line =~ /^\[([^\]]+)\]$/) {
+	    $key = $1;
+	} elsif ($line =~ /^-{70}$/) {
+	    $infodb{$key} = $value;
+	    $value = "";
+	    $key = "";
+	} else {
+	    $value .= $line;
+	}
+    }
+    close PIPEIN;
+}
Index: /gsdl/stable/bin/script/unbuildv2.pl
===================================================================
--- /gsdl/stable/bin/script/unbuildv2.pl	(revision 20131)
+++ /gsdl/stable/bin/script/unbuildv2.pl	(revision 20131)
@@ -0,0 +1,788 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# unbuildv2.pl --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# this program will decompress all the text from a built index
+# and return it to gml format -
+#this is based on the format current in Nov 1999. (version two)
+
+# Stefan updated unbuildv1.pl in August 2002 but unbuildv2.pl was not
+# updated. It probably needs some work done before using.
+
+# Katherine updated this but apparently it still doesn't work.
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    $FileHandle = 'FH000';
+}
+
+use dbutil;
+use doc;
+use util;
+use parsargv;
+use GDBM_File;
+use FileHandle;
+use English;
+use cfgread;
+use unicode;
+use plugout;
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+
+# globals
+$collection = "";  # the collection name
+$index = "";  # the selected index (like stt/unu)
+$textdir = ""; # the textdir (like text/unu)
+$toplevelinfo = []; #list of document OIDs
+%infodb = (); #hash into GDBM file
+$classifyinfo = []; # list of classifications
+$doc_classif_info = {};  # hash of OIDs->classifications they belong to
+$collect_cfg = {}; #data for the configuration file
+
+$mgread = ++$FileHandle;
+$mgwrite = ++$FileHandle;
+
+
+
+sub print_usage {
+    print STDERR "\n  usage: $0 [options]\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -verbosity number      0=none, 3=lots\n";
+    print STDERR "   -indexdir directory    The index to be decompressed (defaults to ./index)\n";
+    print STDERR "   -archivedir directory  Where the converted material ends up (defaults to ./archives.new\n";
+    print STDERR "   -removeold             Will remove the old contents of the archives\n";
+    print STDERR "                          directory -- use with care\n\n";
+}
+
+&main ();
+
+sub main {
+    if (!parsargv::parse(\@ARGV, 
+			 'verbosity/\d+/2', \$verbosity,
+			 'indexdir/.*/index', \$indexdir,
+			 'archivedir/.*/archives.new', \$archivedir,
+			 'removeold', \$removeold)) {
+	&print_usage();
+	die "\n";
+    }
+
+    die "indexdir $indexdir does not exist\n\n" unless (-d $indexdir);
+    $indexdir =~ s/\/$//;
+    if (-d $archivedir) {
+	if ($removeold) {
+	    print STDERR "Warning - removing current contents of the archives directory $archivedir\n";
+	    print STDERR "          in preparation for the import\n";
+	    sleep(5); # just in case...
+	    &util::rm_r ($archivedir);
+	}
+    } else {
+	&util::mk_all_dir ($archivedir);
+    }
+
+    $etcdir = "./etc";
+    if (!(-d $etcdir)) {
+	&util::mk_all_dir ($etcdir);
+    }
+
+
+    my $gdbmfile = &get_gdbmfile ($indexdir); #sets $collection and $textdir
+    &set_index ();  # sets $index (just chooses one index)
+
+
+    my $buildcfgfile = &util::filename_cat($indexdir, "build.cfg");
+    my $colcfgfile = &util::filename_cat($etcdir, "collect.cfg");
+
+    &add_default_cfg();
+    &add_index_cfg($buildcfgfile);
+
+
+    #work out all the classifications from the gdbm file, info for each doc
+#(ie which classifications they belong to, are kept in $doc_classif_info
+    &get_classifyinfo ($gdbmfile); #puts a list of classifications into classifyinfo
+
+    &get_toplevel_OID ($gdbmfile); # puts a list of the top level document OIDs into $toplevelinfo
+
+    #tie (%infodb, "GDBM_File", $gdbmfile, 1, 0);
+    
+    #read ldb file into %infodb
+    &dbutil::read_infodb_file("gdbm", $gdbmfile, \%infodb);
+
+    #this makes the files specifying the hierarchy of subjects, titles etc
+    foreach $classify (@$classifyinfo) {
+	
+	&make_info_file($classify);
+
+    }
+
+    
+    #write out the collect.cfg
+    &output_cfg_file($colcfgfile);
+
+    &openmg ();
+
+    # read the archive information file
+    my $archive_info_filename = &util::filename_cat ($archivedir, "archives.inf");
+    my $archive_info = new arcinfo ();
+
+    my $opts = [];
+    push @$opts,("-output_info",$archive_info); 
+
+    $processor = &plugout::load_plugout("GreenstoneXMLPlugout",$opts); 
+    $processor->setoutputdir ($new_archivedir);
+
+    my ($doc_obj, $hashref, $children);
+    print STDERR "processing documents now\n" if $verbosity >=2;
+    foreach $oid (@$toplevelinfo) {
+	$value = $infodb{$oid};
+	$hashref={};
+	$children = [];
+	&get_metadata($value, $hashref);
+	$doc_obj = new doc ();
+	$doc_obj->set_OID($oid);
+	my ($olddir) = $hashref->{'archivedir'}; # old dir for this doc, where images are stored
+	$top = $doc_obj->get_top_section();
+	&add_section_content ($doc_obj, $top, $hashref, $olddir);
+	&add_classification_metadata($oid, $doc_obj, $top);
+	&add_cover_image($doc_obj, $olddir);
+	&get_children($hashref, $children);
+	&recurse_sections($doc_obj, $children, $oid, $top, $olddir);
+	$processor->process($doc_obj);
+	
+    }
+    print STDERR "\n";
+   
+    &closemg();
+
+    # write out the archive information file
+    $archive_info->save_info($archive_info_filename);
+}
+
+# returns the path to the gdbm info database - also
+# sets the $collection and $textdir global variable
+sub get_gdbmfile {
+    my ($indexdir) = @_;
+    my ($gdbmfile);
+
+    opendir (DIR, $indexdir) || die "Couldn't open directory $indexdir\n\n";
+    my @conts = readdir DIR;
+    close DIR;
+
+    foreach $file (@conts) {
+	if ($file =~ /text$/) {
+	    $textdir = $file;
+	    last;
+	}
+    }
+    die "No text directory found in $indexdir\n\n" 
+	unless defined $textdir && $textdir =~ /text$/;
+
+    $gdbmfile = &util::filename_cat ($indexdir, $textdir);
+
+    opendir (DIR, $gdbmfile) || die "Couldn't open directory $gdbmfile\n\n";
+    @conts = readdir DIR;
+    close DIR;
+
+    foreach $file (@conts) {
+	if ($file =~ /^(.*?)\.(?:ldb|bdb)$/) {
+	    $collection = $1;
+	    $gdbmfile = &util::filename_cat ($gdbmfile, $file);
+	    last;
+	}
+    }
+    
+    if (defined $collection && $collection =~ /\w/) {
+	$textdir = &util::filename_cat ($textdir, $collection);
+    } else {
+	die "collection global wasn't set\n";
+    }
+    return $gdbmfile if (-e $gdbmfile);
+    die "Couldn't find gdbm info database in $indexdir\n\n";
+}
+
+
+sub get_toplevel_OID {
+    my ($gdbmfile) = @_;
+
+    open (DB2TXT, "db2txt $gdbmfile |") || die "couldn't open pipe to db2txt\n";
+    print STDERR "Finding all top level sections from $gdbmfile\n" if $verbosity >= 2;
+
+    $/ = '-' x 70;
+    my $entry = "";
+    while (defined ($entry = <DB2TXT>)) {
+	next unless $entry =~ /\w/;  #ignore blank entries
+	$entry =~ s/\n+/\\n/g;  # replace multiple \n with single \n
+	my ($key, $value) = $entry =~ /\[([^\]]*)\](.*)/;
+
+	next if ($key =~ /\./); #ignore any lower level entries
+	next if ($key =~ /^CL/); #ignore classification entries
+	next if ($value =~ /<section>/); #ignore docnum->OID entries
+	next if ($value =~ /<docoid>/); #ignore strange s133->OID entries
+	next if ($key !~ /\d/); #ignore collection, browse entries
+
+	push( @$toplevelinfo, $key);
+   
+    }
+
+    $/ = "\n";
+    #print STDERR "toplevel sections are: ", join ("\n", @$toplevelinfo);
+    #print STDERR "\n";
+}
+    
+# gets all the metadata from a gdbm file entry, and puts it into a hashref
+sub get_metadata {
+    
+    my ($gdb_str_ref, $hashref) = @_;
+    my @entries = split(/\n/, $gdb_str_ref);
+    foreach $entry (@entries) {
+	my($key, $value) = ($entry =~ /^<([^>]*)>(.*?)$/ );
+	$$hashref{$key} .= '@' if defined $$hashref{$key};
+	$$hashref{$key} .= $value;
+	
+    }
+   
+    
+}					  
+
+#takes a hashref containing the metadata for a gdbmfile entry, and extracts 
+#the childrens numbers (from the 'contains' entry).	
+#assumes format is ".1;".2;".3
+sub get_children {	
+    my ($hashref, $children) = @_; 
+
+    $childs = $hashref->{'contains'};
+    if (defined ($childs)) {
+	$childs =~ s/\@$//;  #remove trailing @
+	$childs =~ s/^\"\.//; #remove initial ".
+	@$children = split /\;\"\./, $childs;
+	
+    }
+    else {
+	  $children = [];
+      }
+}
+	
+#takes a hashref containing the metadata for a gdbmfile entry, and extracts 
+#the childrens numbers (from the 'contains' entry).	
+#assumes format is ".1;".2;".3
+#returns a list with the full child name ie HASH0123...ac.1 HASH0123...ac.2 
+#etc
+#used for classification stuff
+sub get_whole_children {	
+
+    my ($parentoid, $hashref, $children) = @_; 
+    
+    my $childs = $hashref->{'contains'};
+    my @items;
+    if (defined ($childs)) {
+	$childs =~ s/\@$//;  #remove trailing @
+	@items = split /\;/, $childs; #split on ;
+	foreach $item (@items) {
+	    $item =~ s/^\"/$parentoid/; # replace " with parentoid
+	    push (@$children, "$item");
+	}
+    }
+    else {
+	  $children = [];
+      }
+}
+
+    
+sub recurse_sections {
+    my ($doc_obj, $children, $parentoid, $parentsection, $olddir) = @_;
+
+    foreach $child (sort numerically @$children) {
+	$doc_obj->create_named_section("$parentsection.$child");
+	my $value = $infodb{"$parentoid.$child"};
+	my $hashref={};
+	&get_metadata($value, $hashref); # get childs metadata
+	my $newchildren = [];
+	&get_children($hashref, $newchildren); # get childs children
+	#add content fo rcurrent section
+	&add_section_content($doc_obj, "$parentsection.$child", $hashref, $olddir);
+	# process all the children if there are any
+	&recurse_sections($doc_obj, $newchildren, "$parentoid.$child", "$parentsection.$child", $olddir)
+	    if (defined ($newchildren));
+    }
+
+
+}					     
+
+sub add_section_content {
+    my ($doc_obj, $cursection, $hashref, $olddir) = @_;
+ 
+    foreach $key (keys %$hashref) {
+	#dont need to store these metadata
+	next if $key =~ /(contains|docnum|hastxt|doctype|archivedir|classifytype)/i;
+	my @items = split /@/, $hashref->{$key};
+	map {$doc_obj->add_metadata ($cursection, $key, $_); } @items;
+
+    }
+    my ($docnum)= $hashref->{'docnum'} =~ /(\d*)/;
+    my ($hastext) =$hashref->{'hastxt'} =~ /(0|1)/;
+
+    my $images=[];
+    if ($hastext) {
+	my $text = &get_text($docnum);
+    
+	#my (@images) = $text =~ /<img.*?src=\"([^\"]*)\"[^>]*>/g;
+    
+	# in text replace path to image with _httpdocimg_/blah.gif
+	#while ($text =~ s/(<img.*?src=\")([^\"]*)(\"[^>]*>)/
+	#   $1.&get_img($2, \@images).$3/sgei) {
+	$text =~ s/(<img.*?src=\")([^\"]*)(\"[^>]*>)/
+	    $1.&get_img($2,$images).$3/sgei;
+    
+	$doc_obj->add_text ($cursection, $text);
+	
+	if (scalar(@$images)>0) {
+	    
+	    foreach $img (@$images) {
+		my ($assoc_file) = $img =~ /([^\/\\]*\..*)$/; #the name of the image
+		$img =~ s/_httpcollection_/\./; #replace _httpcollection_ with .
+		$img =~ s/_thisOID_/$olddir/; #replace _thisOID_ with old archivedir name
+		
+		$doc_obj->associate_file($img, $assoc_file);
+	    }
+	}
+    }
+}
+
+
+
+sub get_img {
+    my ($path, $images) = @_;
+    my $img = "_httpdocimg_/";
+    my ($imgname) = $path =~ /([^\/\\]*\..*)$/;
+    push (@$images, $path);
+    $img .= $imgname;
+    return $img;
+}
+    
+
+sub add_classification_metadata {
+
+    my ($oid, $doc_obj, $cursection) = @_;
+    
+    if (defined $doc_classif_info->{$oid}) {
+
+	my $hashref = $doc_classif_info->{$oid};
+	
+	foreach $key (keys %$hashref) {
+	    my @items = @{$hashref->{$key}};
+	    map {$doc_obj->add_metadata ($cursection, $key, $_); } @items;
+	}
+    }
+}
+
+# picks up the cover image "cover.jpg" from the old archives directory.
+sub add_cover_image {
+
+    my ($doc_obj, $olddir) =  @_;
+    $assoc_file = "cover.jpg";
+    $img = "archives/$olddir/$assoc_file";
+
+
+    if (-e $img) {
+	$doc_obj->associate_file($img, $assoc_file);
+    }
+}
+
+
+
+sub set_index {
+    # check that $collection has been set
+    die "collection global was not set\n"
+	unless defined $collection && $collection =~ /\w/;
+
+    # find an index (just use first non-text directory we come across in $indexdir)
+    opendir (INDEXDIR, $indexdir) || die "couldn't open directory $indexdir\n";
+    my @indexes = readdir INDEXDIR;
+    close INDEXDIR;
+    foreach $i (@indexes) {
+	next if $i =~ /text$/i || $i =~ /\./ || $i =~ /assoc$/i;
+	$index = &util::filename_cat ($i, $collection);
+	last;
+    }
+}
+
+
+#########################################################################
+
+################ functions involving mg ################################
+
+sub get_text {
+    my ($docnum) = @_;
+
+    print STDERR "." if $verbosity >= 2;
+    &mgcommand ($docnum);
+
+   <$mgread>;	# eat the document separator
+
+    my $text = "";
+    my $line = "";
+
+    while (defined ($line = <$mgread>))
+    {
+	last if $line =~ /^<\/mg>/;
+	$text .= $line;
+    }
+
+    # Read in the last statement, which should be:
+    #  "dd documents retrieved."
+    <$mgread>;
+
+    return $text;
+}
+
+sub numerically {$a <=> $b;}
+
+
+
+sub openmg {
+
+    #print STDERR "index: $index\n";
+
+    die "Unable to start mgquery." unless
+	&openpipe($mgread, $mgwrite,
+		 "mgquery -d $indexdir -f $index -t $textdir");
+
+    $mgwrite->autoflush();
+
+    &mgcommand('.set expert true');
+    &mgcommand('.set terminator "</mg>\n"');
+    &mgcommand('.set mode text');
+    &mgcommand('.set query docnums');
+    &mgcommand('.set term_freq off');
+    &mgcommand('.set briefstats off');
+    &mgcommand('.set memstats off');
+    &mgcommand('.set sizestats off');
+    &mgcommand('.set timestats off');
+}
+
+sub closemg {
+    &mgcommand (".quit");
+    close($mgread);
+    close($mgwrite);
+}
+
+sub mgcommand {
+    my ($command) = @_;
+
+    return if $command =~ /^\s*$/;  #whitespace
+    #print STDERR "command: $command\n";
+    print $mgwrite "$command\n";
+
+    # eat up the command executed which is echoed
+    <$mgread>;
+}
+
+# openpipe(READ, WRITE, CMD)
+# 
+# Like open2, except CMD's stderr is also redirected.
+# 
+sub openpipe
+{
+    my ($read, $write, $cmd) = @_;
+    my ($child_read, $child_write);
+
+    $child_read = ++$FileHandle;
+    $child_write = ++$FileHandle;
+
+    pipe($read, $child_write) || die "Failed pipe($read, $child_write): $!";
+    pipe($child_read, $write) || die "Failed pipe($child_read, $write): $!";
+    my $pid;
+
+    if (($pid = fork) < 0) {
+        die "Failed fork: $!";
+    } elsif ($pid == 0) {
+        close($read);
+        close($write);
+        open(STDIN, "<&$child_read");
+        open(STDOUT, ">&$child_write");
+        open(STDERR, ">&$child_write");
+        exec($cmd);
+        die "Failed exec $cmd: $!";
+    }
+
+    close($child_read);
+    close($child_write);
+
+    $write->autoflush();
+    $read->autoflush();
+
+    return 1;
+}
+
+
+
+
+######################################################################
+
+############# functions to do with the classification stuff ##########
+
+#returns the top level classification oids
+sub get_classifyinfo {
+    my ($gdbmfile) = @_;
+
+    open (DB2TXT, "db2txt $gdbmfile |") || die "couldn't open pipe to db2txt\n";
+    print STDERR "Finding all classification sections from $gdbmfile\n" ;
+
+    $/ = '-' x 70;
+    my $entry = "";
+    while (defined ($entry = <DB2TXT>)) {
+	next unless $entry =~ /\w/;  #ignore blank entries
+	$entry =~ s/\n+/\\n/g;  # replace multiple \n with single \n
+	my ($key, $value) = $entry =~ /\[([^\]]*)\](.*)/;
+
+	next unless ($key =~/^CL\d$/); # assumes classification OID is like
+	                                 # CL1 or CL2 etc
+
+	push( @$classifyinfo, $key);
+   
+    }
+
+    $/ = "\n";
+    #print STDERR "classifications are: ", join(", ", @$classifyinfo);
+    #print STDERR "\n";
+    
+}
+
+#this creates the classification files needed for the hierarchy classifier
+#used for subjects, titles, orgs etc
+#also adds in entries to the collect_cfg hash    
+sub make_info_file {
+
+    my ($classifier) = @_;
+    my $info_file = "";
+    my $entry = $infodb{$classifier};
+
+    my $hashref = {};
+    &get_metadata($entry, $hashref);
+   
+    my $classifier_name = "CL".$hashref->{'Title'}; #like CLSubject
+    $classifier_name =~ s/\@$//; #remove trailing @
+   
+    # check children - if there is a classifier node at this level, 
+    # use a hierarchy, otherwise use an AZList.
+    
+    my $children=[];
+    my $hierarchy = 0;
+    &get_whole_children($classifier, $hashref, $children); #returns a list of the child ids
+    foreach $child(@$children) {
+	if(not &is_document($child)) {
+	    $hierarchy = 1;
+	    last;
+	}
+    }
+
+    if (!$hierarchy) {
+	&add_classify_cfg_list($classifier_name);
+    }else { #there is a hierarchy so create a file
+	$info_file = "./etc/$classifier_name.txt";
+
+	print STDERR "classification $classifier will be called $classifier_name\n";
+
+	open (OUTDOC, "> $info_file" ) || die  "couldn't open file $info_file\n";
+	
+	foreach $child (@$children) {
+	    &process_entry(OUTDOC, $classifier_name, $child);
+	}
+	
+	close OUTDOC;
+    
+	&add_classify_cfg($classifier, $classifier_name, $info_file);
+    }
+}
+
+
+sub process_entry {
+    my ($handle, $classifier_name, $classify_id) = @_;
+    my $value = $infodb{$classify_id};
+    
+    my $hashref={};
+    &get_metadata($value, $hashref);
+    my $title = $hashref->{'Title'};
+    $title =~ s/\@$//; #remove trailing @
+    &add_line($handle, $classify_id, $title);
+    
+    my $children = [];
+    &get_whole_children($classify_id, $hashref, $children);
+    foreach $child (@$children) {
+	if (&is_document($child)) {
+	    &add_doc_metadata($child, $classifier_name, $title);
+	}else {
+	    &process_entry($handle, $classifier_name, $child);
+	}
+    }
+    
+}
+    
+
+
+sub add_doc_metadata {
+
+    my ($doc_id, $classifier_name, $classifier_id) = @_;
+
+	#add entry to doc database
+	#print STDERR "at doc level, docnum=$classify_id\n";
+
+    $doc_classif_info->{$doc_id}={} unless defined $doc_classif_info->{$doc_id};
+    $doc_classif_info->{$doc_id}->{$classifier_name}=[] unless
+	defined $doc_classif_info->{$doc_id}->{$classifier_name};
+    push (@{$doc_classif_info->{$doc_id}->{$classifier_name}}, $classifier_id); 
+
+}
+
+
+
+
+sub add_line {
+
+    my ($handle, $classify_id, $title) = @_;
+    #print STDERR "classify id= $classify_id, title= $title\n";
+    $title = &unicode::ascii2utf8(\$title);
+    my ($num) = $classify_id =~ /^CL\d\.(.*)$/; #remove the CL1. from the front
+    
+    print $handle "\"$title\"\t$num\t\"$title\"\n";
+
+
+}
+
+sub is_document {
+    my ($oid) = @_;
+    return 1 if $oid =~ /^HASH/i;
+    return 0;
+}
+    
+########################################################################
+
+########## stuff for producing collect.cfg file ###########################
+
+sub add_default_cfg {
+
+    $username=`whoami`;
+    $username=`logname` unless defined $username;
+    $username="a_user" unless defined $username;
+    $username =~ s/\n//;
+    $collect_cfg->{'creator'}="$username\@cs.waikato.ac.nz";
+    $collect_cfg->{'maintainer'}="$username\@cs.waikato.ac.nz";
+    $collect_cfg->{'public'}="true";
+    $collect_cfg->{'beta'}="true";
+    
+    $collect_cfg->{'plugin'}=[];
+    push (@{$collect_cfg->{'plugin'}}, ["GreenstoneXMLPlugin"]);
+    push (@{$collect_cfg->{'plugin'}}, ["ArchivesInfPlugin"]);
+    push (@{$collect_cfg->{'plugin'}}, ["DirectoryPlugin"]);
+
+    $collect_cfg->{'format'}={};
+    $collect_cfg->{'format'}->{'DocumentImages'}="true";
+    $collect_cfg->{'format'}->{'DocumentText'} = 
+	"\"<h3>[Title]</h3>\\\\n\\\\n<p>[Text]\"";
+    $collect_cfg->{'format'}->{'SearchVList'} =
+	"\"<td valign=top>[link][icon][/link]</td><td>{If}{[parent(All': '):Title],[parent(All': '):Title]:}[link][Title][/link]</td>\"";
+
+    $collect_cfg->{'collectionmeta'}={};
+    $collect_cfg->{'collectionmeta'}->{'collectionname'}="\"$collection\"";
+    $collect_cfg->{'collectionmeta'}->{'iconcollection'}="\"_httpprefix_/collect/$collection/images/$collection.gif\"";
+    $collect_cfg->{'collectionmeta'}->{'iconcollectionsmall'}="\"_httpprefix_/collect/$collection/images/${collection}sm.gif\"";
+    $collect_cfg->{'collectionmeta'}->{'collectionextra'} = "\"This is a collection rebuilt from CDROM.\"";
+
+}
+
+sub add_index_cfg {
+  my ($buildfile) = @_;
+
+  my $data={};
+  $collect_cfg->{'indexes'}=[];
+  if (-e $buildfile) {
+      $data=&cfgread::read_cfg_file($buildfile, '^(this)$', '^(indexmap)$'); 
+      foreach $i (@{$data->{'indexmap'}}) {
+          ($thisindex, $abbrev)= split ("\-\>", $i);
+          push (@{$collect_cfg->{'indexes'}}, $thisindex);
+	  $collect_cfg->{'defaultindex'} = $thisindex unless defined 
+	      $collect_cfg->{'defaultindex'};
+          $name=&get_index_name($thisindex);
+	  $thisindex=".$thisindex";
+          $collect_cfg->{'collectionmeta'}->{$thisindex} = "\"$name\"";
+      } 
+  }
+  else {
+      print STDERR "Couldn't read $buildfile, could not add index data to configuration file\n";
+  }
+
+}
+
+sub get_index_name {
+    my ($thisindex) = @_;
+    return "paragraphs" if $thisindex =~ /paragraph/;
+    return "chapters" if $thisindex =~ /section.*text/;
+    return "titles" if $thisindex =~ /Title/;
+    return "other";
+}
+
+sub add_classify_cfg {
+
+    my ($classify, $classifier_name, $file) = @_;
+    $collect_cfg->{'classify'} = [] unless defined $collect_cfg->{'classify'};
+
+    my ($title) = $classifier_name =~ /^CL(.*)$/;
+    my ($filename) = $file =~ /\/([^\/]*)$/;
+    my $entry = "Hierarchy -hfile $filename -metadata $classifier_name -buttonname $title -sort Title";
+    push (@{$collect_cfg->{'classify'}},[$entry]);
+   
+
+}
+
+sub add_classify_cfg_list {
+
+    my ($classifier) = @_;
+    $collect_cfg->{'classify'} = [] unless defined $collect_cfg->{'classify'};
+    my ($title) = $classifier =~ /^CL(.*)$/;
+    my $entry = "AZList -metadata $classifier -buttonname $title";
+    push (@{$collect_cfg->{'classify'}},[$entry]);
+}    
+
+sub output_cfg_file {
+
+    my ($collfile) = @_;
+    
+    if (-e $collfile) { #collect.cfg already exists
+	$collfile .= ".new";
+    }
+    &cfgread::write_cfg_file($collfile, $collect_cfg, 
+			     '^(creator|maintainer|public|beta|defaultindex)$',
+                            '^(indexes)$', '^(format|collectionmeta)$',
+                            '^(plugin|classify)$');
+
+
+
+}
+
+
Index: /gsdl/stable/bin/script/update.pl
===================================================================
--- /gsdl/stable/bin/script/update.pl	(revision 20131)
+++ /gsdl/stable/bin/script/update.pl	(revision 20131)
@@ -0,0 +1,196 @@
+#!/usr/bin/perl -w
+
+###########################################################################
+#
+# update.pl
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This program updates any collections that are based on mirrors of
+# web sites after a certain interval.  It first checks that the
+# collection is a mirrored collection and whether it is time to 
+# update the collection.  If so, it updates the mirror with 
+# mirror.pl; then imports the collection with import.pl; then 
+# builds the collection with buildcol.pl; then replaces the 
+# existing index directory with the new building directory.
+# The etc/mirror.log file stores the STDOUT output.
+
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugins");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/classify");
+}
+
+use arcinfo;
+use colcfg;
+use util;
+use parsargv;
+
+sub print_usage {
+    print STDERR "\n";
+    print STDERR "update.pl: Updates a collection if it has been set up to mirror\n";
+    print STDERR "           a website. Calls mirror.pl to do the mirroring.\n\n";
+    print STDERR "  usage: $0 [options] collection-name\n\n";
+    print STDERR "  options:\n";
+    print STDERR "   -verbosity number      0=none, 3=lots\n";
+    print STDERR "   -importdir directory   Where to place the mirrored material\n";
+    print STDERR "   -archivedir directory  Where the converted material ends up\n";
+}
+
+
+&main ();
+
+sub main {
+    my ($verbosity, $importdir, $archivedir, $builddir, $indexdir, $etcdir, 
+	$mirror, $interval, $logfile,
+        $collection, $configfilename, $collectcfg);
+
+    if (!parsargv::parse(\@ARGV, 
+			 'verbosity/\d+/2', \$verbosity,
+			 'importdir/.*/', \$importdir,
+			 'archivedir/.*/', \$archivedir )) {
+	&print_usage();
+	die "\n";
+    }
+
+    # get and check the collection name
+    if (($collection = &util::use_collection(@ARGV)) eq "") {
+	&print_usage();
+	die "\n";
+    }
+
+    # check the configuration file for options
+    $configfilename = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "etc/collect.cfg");
+    if (-e $configfilename) {
+	$collectcfg = &colcfg::read_collect_cfg ($configfilename);
+	if (defined $collectcfg->{'importdir'} && $importdir eq "") {
+	    $importdir = $collectcfg->{'importdir'};
+	}
+	if (defined $collectcfg->{'archivedir'} && $archivedir eq "") {
+	    $archivedir = $collectcfg->{'archivedir'};
+	}
+	if (defined $collectcfg->{'mirror'}) {
+	    $mirror = $collectcfg->{'mirror'};
+	}
+    } else {
+	die "Couldn't find the configuration file $configfilename\n";
+    }
+    
+    # fill in the default import and archives directories if none
+    # were supplied, turn all \ into / and remove trailing /
+    $importdir = "$ENV{'GSDLCOLLECTDIR'}/import" if $importdir eq "";
+    $importdir =~ s/[\\\/]+/\//g;
+    $importdir =~ s/\/$//;
+    $archivedir = "$ENV{'GSDLCOLLECTDIR'}/archives" if $archivedir eq "";
+    $archivedir =~ s/[\\\/]+/\//g;
+    $archivedir =~ s/\/$//;
+
+    $indexdir = "$ENV{'GSDLCOLLECTDIR'}/index";
+    $builddir = "$ENV{'GSDLCOLLECTDIR'}/building";
+    $etcdir = "$ENV{'GSDLCOLLECTDIR'}/etc";
+    $logfile = "$etcdir/mirror.log";
+
+    # if there is no mirror information, we're all done
+    if (!defined($mirror)) {
+	print "No mirror command in $configfilename\n";
+	exit;
+    }
+
+    # read the mirror interval
+    if (($#$mirror == 1) && ($$mirror[0] =~ /interval/)){
+	$interval = $$mirror[1];
+    } else {
+	die "Malformed mirror information: use \"mirror interval N\"\n" .
+	    "where N is the number of days between mirrors.\n";
+    }
+
+    # make sure there is an import directory
+    if (! -e "$importdir") {
+	&util::mk_dir($importdir);
+    }
+
+    print "archives directory: $archivedir\n";
+    print "  import directory: $importdir\n";
+    print "     etc directory: $etcdir\n";
+    print "          interval: $interval days\n";
+
+    # how many days is it since the last mirror
+    my $seconds = 0;
+    if (-e "$logfile") {
+	my $now = time;
+	my @stats = stat("$logfile");
+	my $then = $stats[9];
+	# calculate the number of days since the last mirror
+	$seconds = $now - $then;
+    }
+    my $days = (($seconds / 3600) / 24);
+
+    # Is it too soon to start mirroring?
+    if (($seconds > 0) && ($interval > $days)) {
+	printf "Mirror not started: only %.1f days have passed\n", $days;
+	exit;
+    }
+    
+    # Mirror the remote site
+    open(WLOG, ">$logfile");
+    print WLOG "Starting mirror at " . time . "\n\n";
+    
+    my $command = "mirror.pl $collection";
+    print WLOG "Executing: $command\n";
+    print WLOG `$command`;
+    
+    # Import the collection
+    print WLOG "\n\nStarting import at " . time . "\n\n";
+    $command = "import.pl -removeold $collection";
+    print WLOG "Executing: $command\n";
+    print WLOG `$command`;
+
+    # Build the collection
+    print WLOG "\n\nStarting buildcol.pl at " . time . "\n\n";
+    $command = "buildcol.pl $collection";
+    print WLOG "Executing: $command\n";
+    print WLOG `$command`;
+
+    # Renaming the building directory to index
+    print WLOG "\n\nRenaming building directory at " . time . "\n\n";
+    if (-e $indexdir) {
+	&util::mv($indexdir, "$indexdir.old");
+	&util::mv($builddir, $indexdir);
+	&util::rm_r ("$indexdir.old");
+    } else {
+	&util::mv($builddir, $indexdir);
+    }
+
+
+    close WLOG;
+    
+}
+
+
+
+
+
Index: /gsdl/stable/bin/script/xlstohtml.pl
===================================================================
--- /gsdl/stable/bin/script/xlstohtml.pl	(revision 20131)
+++ /gsdl/stable/bin/script/xlstohtml.pl	(revision 20131)
@@ -0,0 +1,69 @@
+eval 'exec perl -x -- $0 $@'
+    if 0;
+#! perl
+# line 6
+
+sub usage() {
+    print "$0 <input.xls> <output.html>\n";
+}
+
+
+if (@ARGV != 2) {
+    usage();
+    exit(1);
+}
+my $input_xls=shift;
+my $output_html=shift;
+
+# try to find xlhtml binary in GSDLHOME
+my $xlhtml_binary="xlhtml";
+my $GSDLOS=$ENV{'GSDLOS'};
+my $GSDLHOME=$ENV{'GSDLHOME'};
+if ($GSDLOS =~ /^windows/i) {
+    $xlhtml_binary.=".exe";
+}
+
+# Trouble happens if there are spaces in GSDLHOME. Assume that on windows
+# the program is found in the path.
+if ($GSDLOS !~ /windows/i && -x "$GSDLHOME/bin/$GSDLOS/$xlhtml_binary") {
+    $xlhtml_binary="$GSDLHOME/bin/$GSDLOS/$xlhtml_binary";
+}
+
+if (! -r $input_xls) {
+    print STDERR "Unable to read file `$input_xls'\n";
+    exit (1);
+}
+
+my $return_value=
+    system("$xlhtml_binary \"$input_xls\" > \"$output_html\"");
+
+if ($return_value != 0) {
+    exit (1);
+}
+
+# Ok, we made an html file. Check to see if it has any content, and remove
+# the little nag link at the the bottom.
+my $html="";
+open (HTML, "$output_html") || die "Can't read file:$!";
+$html=join('', <HTML>);
+close HTML;
+
+$html =~ s@<hr><FONT SIZE=-1>Created with.*\n</BODY></HTML>$@</BODY></HTML>@s;
+
+# xlHtml uses the filename as the title.
+# HTMLPlug will use the first 100 chars instead if there's no title.
+# Don't know if that's a good idea with a spreadsheet, though...
+$html =~ s@<title>.*?\.xls</title>@<title></title>@i;
+
+my $tmp=$html;
+$tmp =~ s/^.*?<BODY>//ms;
+$tmp =~ s/(&nbsp;)|\s//gims;
+if ($tmp !~ m/(>[^<]+<)/) {
+    print STDERR "No text found in extracted html file!\n";
+    exit(1);
+}
+open (NEWHTML, ">$output_html") || die "Can't create file:$!";
+print NEWHTML $html;
+close NEWHTML;
+exit (0);
+
Index: /gsdl/stable/build-src/Makefile.in
===================================================================
--- /gsdl/stable/build-src/Makefile.in	(revision 20131)
+++ /gsdl/stable/build-src/Makefile.in	(revision 20131)
@@ -0,0 +1,103 @@
+###########################################################################
+#
+# Makefile -- gsdl buildtime code
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+srcdir = @srcdir@
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+@SET_MAKE@
+CC = @CC@
+CXX = @CXX@
+CFLAGS = @CFLAGS@
+CXXFLAGS = @CXXFLAGS@
+LIBS   = @LIBS@
+MDEFINES =
+
+GSDLOS = @gsdlos@
+
+COMPILE = $(CC) -c
+
+SOURCES = 
+
+OBJECTS = 
+
+ALLFILES = $(OBJECTS)
+
+# all directories should be compiled
+COMPILEDIRS = packages src/hashfile src/phind/generate 
+# a subset of the directories get installed
+INSTALLDIRS = packages src/hashfile src/phind/generate
+
+MODULEDIRS = @MODULEDIRS@
+
+
+all:
+	for odir in $(COMPILEDIRS) $(MODULEDIRS); do \
+	  echo making $@ in $$odir; \
+	  (cd $$odir && $(MAKE) $(MDEFINES) $@) || exit 1; \
+	done
+
+install: all
+	for idir in $(INSTALLDIRS); do \
+	  echo installing $$idir; \
+	  (cd $$idir && $(MAKE) install) || exit 1; \
+	done
+
+distclean: clean
+	rm -f Makefile config.cache config.h config.log stamp-h config.status
+	for subdir in $(COMPILEDIRS); do \
+	  echo cleaning $@ in $$subdir; \
+	  (cd $$subdir && $(MAKE) distclean) || exit 1; \
+	done
+
+clean:
+	for subdir in $(COMPILEDIRS); do \
+	  echo cleaning $@ in $$subdir; \
+	  (cd $$subdir && $(MAKE) clean) || exit 1; \
+	done
+
+# commented out - jrm21 Dec 2004 - can get confused by cvs timestamps
+# (and might run the wrong version of autoconf)
+#
+## For an explanation of the following Makefile rules, see node
+## `Automatic Remaking' in GNU Autoconf documentation.
+#Makefile: Makefile.in config.status
+#	CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+#config.status: configure
+#	./config.status --recheck
+#configure: configure.in aclocal.m4
+#	cd $(srcdir) && autoconf
+#
+#config.h: stamp-h
+#stamp-h: config.h.in config.status
+#	CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status
+#config.h.in: stamp-h.in
+#stamp-h.in: configure.in aclocal.m4 acconfig.h
+#	cd $(srcdir) && autoheader
+#	$(TOUCH) $(srcdir)/stamp-h.in
+
+
+
Index: /gsdl/stable/build-src/aclocal.m4
===================================================================
--- /gsdl/stable/build-src/aclocal.m4	(revision 20131)
+++ /gsdl/stable/build-src/aclocal.m4	(revision 20131)
@@ -0,0 +1,140 @@
+# Local additions to Autoconf macros.
+# Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+# François Pinard <pinard@iro.umontreal.ca>, 1992.
+
+# [TS:Aug/95] - chopped out the NLS stuff which I don't support
+
+## ------------------------------- ##
+## Check for function prototypes.  ##
+## ------------------------------- ##
+
+AC_DEFUN(fp_C_PROTOTYPES,
+[AC_REQUIRE([fp_PROG_CC_STDC])
+AC_MSG_CHECKING([for function prototypes])
+if test "$ac_cv_prog_cc_stdc" != no; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(PROTOTYPES)
+  U= ANSI2KNR=
+else
+  AC_MSG_RESULT(no)
+  U=_ ANSI2KNR=ansi2knr
+fi
+AC_SUBST(U)dnl
+AC_SUBST(ANSI2KNR)dnl
+])
+
+## ----------------------------------------- ##
+## ANSIfy the C compiler whenever possible.  ##
+## ----------------------------------------- ##
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so.  This macro tries various
+# options that select ANSI C on some system or another.  It considers the
+# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and
+# handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{ac_cv_prog_cc_stdc} is set to @samp{no}.  If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN(fp_PROG_CC_STDC,
+[AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
+AC_CACHE_VAL(ac_cv_prog_cc_stdc,
+[ac_cv_prog_cc_stdc=no
+ac_save_CFLAGS="$CFLAGS"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX			-Aa -D_HPUX_SOURCE
+# SVR4			-Xc
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" -Xc
+do
+  CFLAGS="$ac_save_CFLAGS $ac_arg"
+  AC_TRY_COMPILE(
+[#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif	
+], [int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};],
+[ac_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CFLAGS="$ac_save_CFLAGS"
+])
+AC_MSG_RESULT($ac_cv_prog_cc_stdc)
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno) ;;
+  *) CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+])
+
+## --------------------------------------------------------- ##
+## Use AC_PROG_INSTALL, supplementing it with INSTALL_SCRIPT ##
+## substitution.					     ##
+## --------------------------------------------------------- ##
+
+AC_DEFUN(fp_PROG_INSTALL,
+[AC_PROG_INSTALL
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL} -m 755'
+AC_SUBST(INSTALL_SCRIPT)dnl
+])
+
+## ----------------------------------- ##
+## Check if --with-dmalloc was given.  ##
+## ----------------------------------- ##
+
+# I just checked, and GNU rx seems to work fine with a slightly
+# modified GNU m4.  So, I put out the test below in my aclocal.m4,
+# and will try to use it in my things.  The idea is to distribute
+# rx.[hc] and regex.[hc] together, for a while.  The WITH_REGEX symbol
+# (which should also be documented in acconfig.h) is used to decide
+# which of regex.h or rx.h should be included in the application.
+#
+# If `./configure --with-regex' is given, the package will use
+# the older regex.  Else, a check is made to see if rx is already
+# installed, as with newer Linux'es.  If not found, the package will
+# use the rx from the distribution.  If found, the package will use
+# the system's rx which, on Linux at least, will result in a smaller
+# executable file.
+
+AC_DEFUN(fp_WITH_DMALLOC,
+[AC_MSG_CHECKING(if malloc debugging is wanted)
+AC_ARG_WITH(dmalloc,
+[  --with-dmalloc          use dmalloc, as in
+                          ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz],
+[if test "$withval" = yes; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(WITH_DMALLOC)
+  LIBS="$LIBS -ldmalloc"
+  LDFLAGS="$LDFLAGS -g"
+else
+  AC_MSG_RESULT(no)
+fi], [AC_MSG_RESULT(no)])
+])
+
+## --------------------------------- ##
+## Check if --with-regex was given.  ##
+## --------------------------------- ##
+
+AC_DEFUN(fp_WITH_REGEX,
+[AC_MSG_CHECKING(which of rx or regex is wanted)
+AC_ARG_WITH(regex,
+[  --with-regex            use older regex in lieu of GNU rx for matching],
+[if test "$withval" = yes; then
+  ac_with_regex=1
+  AC_MSG_RESULT(regex)
+  AC_DEFINE(WITH_REGEX)
+  AC_LIBOBJ([regex])
+fi])
+if test -z "$ac_with_regex"; then
+  AC_MSG_RESULT(rx)
+  AC_CHECK_FUNC(re_rx_search, , [AC_LIBOBJ([rx])])
+fi
+])
Index: /gsdl/stable/build-src/config.h.in
===================================================================
--- /gsdl/stable/build-src/config.h.in	(revision 20131)
+++ /gsdl/stable/build-src/config.h.in	(revision 20131)
@@ -0,0 +1,217 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+#ifndef _GSDL_CONFIG_H
+#define _GSDL_CONFIG_H
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+#undef _ALL_SOURCE
+#endif
+
+/* Define if using alloca.c.  */
+#undef C_ALLOCA
+
+/* Define if big endian */
+#undef WORDS_BIGENDIAN
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro.  */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+#undef HAVE_ALLOCA_H
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+#undef HAVE_DOPRNT
+
+/* Define if you have the vprintf function.  */
+#undef HAVE_VPRINTF
+
+/* Define if on MINIX.  */
+#undef _MINIX
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+#undef off_t
+
+/* Define if the system does not provide POSIX.1 features except
+   with this defined.  */
+#undef _POSIX_1_SOURCE
+
+/* Define if you need to in order for stat and other things to work.  */
+#undef _POSIX_SOURCE
+
+/* Define as the return type of signal handlers (int or void).  */
+#undef RETSIGTYPE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm.  */
+#undef TM_IN_SYS_TIME
+
+/* Define to the name of the distribution.  */
+#undef PACKAGE
+
+/* Define to the version of the distribution.  */
+#undef VERSION
+
+/* Define to 1 if you have the valloc function.  */
+#undef HAVE_VALLOC
+
+/* Define to 1 if ANSI function prototypes are usable.  */
+#undef PROTOTYPES
+
+/* Define if you don't want to use long long's with GCC */
+#undef DISABLE_LONG_LONG
+ 
+/* Define to 1 for better use of the debugging malloc library.  See
+   site ftp.antaire.com in antaire/src, file dmalloc/dmalloc.tar.gz.  */
+#undef WITH_DMALLOC
+
+ 
+/* Define to 1 if GNU regex should be used instead of GNU rx.  */
+#undef WITH_REGEX
+
+/* Some braindead header files do not have the requ'd function declarations */
+#undef HAVE_FGETC_DECL
+#undef HAVE_FREAD_DECL
+
+/* See if have this field in the prstatus_t structure */
+/* It stores the size of the process heap */
+#undef HAVE_PR_BRKSIZE
+
+/* Define FASTCGI if needsbe */
+#undef USE_FASTCGI
+
+/* Define USE_CORBA if needsbe */
+#undef USE_CORBA
+
+/* Define MICO_DIR if needsbe */
+#undef MICO_DIR
+
+/* Define MICO_VERSION if required */
+#undef MICO_VERSION
+
+/* Define if you have the ftime function.  */
+#undef HAVE_FTIME
+
+/* Define if you have the ftruncate function.  */
+#undef HAVE_FTRUNCATE
+
+/* Define if you have the getpagesize function.  */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the getrusage function.  */
+#undef HAVE_GETRUSAGE
+
+/* Define if you have the mallinfo function.  */
+#undef HAVE_MALLINFO
+
+/* Define if you have the select function.  */
+#undef HAVE_SELECT
+
+/* Define if you have the setbuffer function.  */
+#undef HAVE_SETBUFFER
+
+/* Define if you have the strcasecmp function.  */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strerror function.  */
+#undef HAVE_STRERROR
+
+/* Define if you have the strftime function.  */
+#undef HAVE_STRFTIME
+
+/* Define if you have the strstr function.  */
+#undef HAVE_STRSTR
+
+/* Define if you have the strtol function.  */
+#undef HAVE_STRTOL
+
+/* Define if you have the times function.  */
+#undef HAVE_TIMES
+
+/* Define if you have the valloc function.  */
+#undef HAVE_VALLOC
+
+/* Define if you have the <crypt.h> header file.  */
+#undef HAVE_CRYPT_H
+
+/* Define if you have the <dirent.h> header file.  */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <fcntl.h> header file.  */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <limits.h> header file.  */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <memory.h> header file.  */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <ndir.h> header file.  */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <string.h> header file.  */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/dir.h> header file.  */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/ndir.h> header file.  */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/procfs.h> header file.  */
+#undef HAVE_SYS_PROCFS_H
+
+/* Define if you have the <sys/time.h> header file.  */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <unistd.h> header file.  */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the crypt library (-lcrypt).  */
+#undef HAVE_LIBCRYPT
+
+/* Define if you have the g library (-lg).  */
+#undef HAVE_LIBG
+
+/* Define if you have the gdbm library (-lgdbm).  */
+#undef HAVE_LIBGDBM
+
+/* Define if you have the m library (-lm).  */
+#undef HAVE_LIBM
+
+/* Define if you have the stdc++ library (-lstdc++).  */
+#undef HAVE_LIBSTDC__
+
+/* Define if you have gettext (eg glibc) */
+#undef ENABLE_NLS
+
+/* Define if big endian */
+#undef WORDS_BIGENDIAN
+
+#endif /* _GSDL_CONFIG_H */
Index: /gsdl/stable/build-src/configtest.pl
===================================================================
--- /gsdl/stable/build-src/configtest.pl	(revision 20131)
+++ /gsdl/stable/build-src/configtest.pl	(revision 20131)
@@ -0,0 +1,1 @@
+print $]
Index: /gsdl/stable/build-src/configure
===================================================================
--- /gsdl/stable/build-src/configure	(revision 20131)
+++ /gsdl/stable/build-src/configure	(revision 20131)
@@ -0,0 +1,8624 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subdirs_all="$ac_subdirs_all packages"
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS PACKAGE VERSION USE_FASTCGI USE_LANGACTION USE_CORBA MICO_DIR USE_Z3950 USE_YAZ ENABLE_ACCENTFOLD USE_SQLITE LDFLAGS CFLAGS CC CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX AWK YACC build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB COMPAT32BITFLAGS MICO_VER CPP EGREP U ANSI2KNR ALLOCA LIBOBJS STATIC gsdlos MODULEDIRS subdirs LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CXX_set=${CXX+set}
+ac_env_CXX_value=$CXX
+ac_cv_env_CXX_set=${CXX+set}
+ac_cv_env_CXX_value=$CXX
+ac_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_env_CXXFLAGS_value=$CXXFLAGS
+ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_cv_env_CXXFLAGS_value=$CXXFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-corba          Enable CORBA support
+  --enable-z3950          Enable Z39.50 client support
+  --disable-yaz           Disable YAZ compilation
+  --disable-accentfold    Disable Accent Folding for MGPP
+  --disable-sqlite        Disable SQLite support
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-micodir          Use installed MICO directory
+  --with-dmalloc          use dmalloc, as in
+                          ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz
+  --with-regex            use older regex in lieu of GNU rx for matching
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers config.h"
+
+
+
+PACKAGE=gsdl
+VERSION=2.82-svn
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+
+
+
+USE_FASTCGI=0
+if test USE_FASTCGI = 1; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_FASTCGI 1
+_ACEOF
+
+
+fi
+
+if test USE_LANGACTION = 1; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_LANGACTION 1
+_ACEOF
+
+
+fi
+
+# Check whether --enable-corba or --disable-corba was given.
+if test "${enable_corba+set}" = set; then
+  enableval="$enable_corba"
+  USE_CORBA=1
+else
+  USE_CORBA=0
+fi;
+cat >>confdefs.h <<_ACEOF
+#define USE_CORBA $USE_CORBA
+_ACEOF
+
+
+
+
+# Check whether --with-micodir or --without-micodir was given.
+if test "${with_micodir+set}" = set; then
+  withval="$with_micodir"
+  MICO_DIR=$enableval
+else
+  MICO_DIR="default"
+fi;
+cat >>confdefs.h <<_ACEOF
+#define MICO_DIR "$MICO_DIR"
+_ACEOF
+
+
+
+# Check whether --enable-z3950 or --disable-z3950 was given.
+if test "${enable_z3950+set}" = set; then
+  enableval="$enable_z3950"
+  USE_Z3950=1
+else
+  USE_Z3950=0
+fi;
+if test USE_Z3950 = 1; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_Z3950 $USE_Z3950
+_ACEOF
+
+
+fi
+
+# Check whether --enable-yaz or --disable-yaz was given.
+if test "${enable_yaz+set}" = set; then
+  enableval="$enable_yaz"
+  USE_YAZ=0
+else
+  USE_YAZ=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define USE_YAZ $USE_YAZ
+_ACEOF
+
+
+
+# Check whether --enable-accentfold or --disable-accentfold was given.
+if test "${enable_accentfold+set}" = set; then
+  enableval="$enable_accentfold"
+  ENABLE_ACCENTFOLD=0
+else
+  ENABLE_ACCENTFOLD=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define ENABLE_ACCENTFOLD $ENABLE_ACCENTFOLD
+_ACEOF
+
+
+
+# Check whether --enable-sqlite or --disable-sqlite was given.
+if test "${enable_sqlite+set}" = set; then
+  enableval="$enable_sqlite"
+  USE_SQLITE=0
+else
+  USE_SQLITE=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define USE_SQLITE $USE_SQLITE
+_ACEOF
+
+
+
+LDFLAGS=$LDFLAGS
+
+if test -z "$CFLAGS"; then
+CFLAGS=-O2
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+	;;
+    conftest.$ac_ext )
+	# This is the source file.
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
+    * )
+	break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  export ac_cv_exeext
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX 10.20 and later	-Ae
+# HP-UX older versions	-Aa -D_HPUX_SOURCE
+# SVR4			-Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CXX" && break
+done
+test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
+
+  CXX=$ac_ct_CXX
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cxx_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+for ac_prog in 'bison -y' byacc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_YACC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_YACC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+  echo "$as_me:$LINENO: result: $YACC" >&5
+echo "${ECHO_T}$YACC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6
+if test "${ac_cv_target+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_target_alias=$target_alias
+test "x$ac_cv_target_alias" = "x" &&
+  ac_cv_target_alias=$ac_cv_host_alias
+ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6
+target=$ac_cv_target
+target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+	@echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+echo "$as_me:$LINENO: checking to see if architecture is 64-bit" >&5
+echo $ECHO_N "checking to see if architecture is 64-bit... $ECHO_C" >&6
+arch_64bit=no
+case "$host_cpu" in
+x86_64) arch_64bit=yes ;;
+esac
+
+if test "$arch_64bit" = yes; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS="-m32"
+  fi
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS=
+  fi
+fi
+export COMPAT32BITFLAGS
+
+
+
+#moved CORBA MICO directory test to get version of MICO
+if test $USE_CORBA = 1; then
+
+if test $MICO_DIR = "default"; then
+#do something
+MICO_INC="-I packages/mico/mico/include"
+else
+#build the micotest program
+MICO_INC= ""
+if test $MICO_DIR != yes; then
+MICO_INC="-I $MICO_DIR"
+fi
+fi
+
+#get MICO_VER value
+sh -c "$CC -c micotest.cpp -o micotest.o $MICO_INC 2>&1" > /dev/null
+sh -c "$CC -o micotest micotest.o -lstdc++ 2>&1" > /dev/null
+MICO_VER=`./micotest` || MICO_VER=2.3.5
+sh -c "rm micotest"
+sh -c "rm micotest.o"
+
+#do test of MICO_VER
+if test MICO_VER != 0; then
+cat >>confdefs.h <<\_ACEOF
+#define MICO_VER 1
+_ACEOF
+
+
+fi
+#end USE_CORBA test
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+
+echo "$as_me:$LINENO: checking for AIX" >&5
+echo $ECHO_N "checking for AIX... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef _AIX
+  yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+cat >>confdefs.h <<\_ACEOF
+#define _ALL_SOURCE 1
+_ACEOF
+
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest*
+
+
+echo "$as_me:$LINENO: checking for library containing strerror" >&5
+echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6
+if test "${ac_cv_search_strerror+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_strerror=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char strerror ();
+int
+main ()
+{
+strerror ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_strerror="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_strerror" = no; then
+  for ac_lib in cposix; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char strerror ();
+int
+main ()
+{
+strerror ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_strerror="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5
+echo "${ECHO_T}$ac_cv_search_strerror" >&6
+if test "$ac_cv_search_strerror" != no; then
+  test "$ac_cv_search_strerror" = "none required" || LIBS="$ac_cv_search_strerror $LIBS"
+
+fi
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for minix/config.h" >&5
+echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
+echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking minix/config.h usability" >&5
+echo $ECHO_N "checking minix/config.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <minix/config.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking minix/config.h presence" >&5
+echo $ECHO_N "checking minix/config.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <minix/config.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: minix/config.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: minix/config.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for minix/config.h" >&5
+echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_minix_config_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
+echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6
+
+fi
+if test $ac_cv_header_minix_config_h = yes; then
+  MINIX=yes
+else
+  MINIX=
+fi
+
+
+if test "$MINIX" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_SOURCE 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_1_SOURCE 2
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _MINIX 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for ${CC-cc} option to accept ANSI C" >&5
+echo $ECHO_N "checking for ${CC-cc} option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CFLAGS="$CFLAGS"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX			-Aa -D_HPUX_SOURCE
+# SVR4			-Xc
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" -Xc
+do
+  CFLAGS="$ac_save_CFLAGS $ac_arg"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif
+
+int
+main ()
+{
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc="$ac_arg"; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+CFLAGS="$ac_save_CFLAGS"
+
+fi
+
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno) ;;
+  *) CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+
+echo "$as_me:$LINENO: checking for function prototypes" >&5
+echo $ECHO_N "checking for function prototypes... $ECHO_C" >&6
+if test "$ac_cv_prog_cc_stdc" != no; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  cat >>confdefs.h <<\_ACEOF
+#define PROTOTYPES 1
+_ACEOF
+
+  U= ANSI2KNR=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  U=_ ANSI2KNR=ansi2knr
+fi
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6
+if test "${ac_cv_type_off_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((off_t *) 0)
+  return 0;
+if (sizeof (off_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_off_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_off_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
+if test $ac_cv_type_off_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((size_t *) 0)
+  return 0;
+if (sizeof (size_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_size_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_size_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+if test $ac_cv_type_size_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+if test "${ac_cv_header_time+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_time=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_time=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6
+if test $ac_cv_header_time = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TIME_WITH_SYS_TIME 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5
+echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6
+if test "${ac_cv_struct_tm+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <time.h>
+
+int
+main ()
+{
+struct tm *tp; tp->tm_sec;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_struct_tm=time.h
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5
+echo "${ECHO_T}$ac_cv_struct_tm" >&6
+if test $ac_cv_struct_tm = sys/time.h; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TM_IN_SYS_TIME 1
+_ACEOF
+
+fi
+
+
+if test "$ac_cv_prog_cc_stdc" = '-Xc'; then
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+int
+main ()
+{
+ FILE *rubbish = popen("yes", "r");
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+CC="`echo $CC | sed 's/-Xc/-Xa/'`"    ac_cv_prog_cc_stdc='-Xa'
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+
+echo "$as_me:$LINENO: checking for main in -lg" >&5
+echo $ECHO_N "checking for main in -lg... $ECHO_C" >&6
+if test "${ac_cv_lib_g_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lg  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_g_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_g_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_g_main" >&5
+echo "${ECHO_T}$ac_cv_lib_g_main" >&6
+if test $ac_cv_lib_g_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBG 1
+_ACEOF
+
+  LIBS="-lg $LIBS"
+
+fi
+ac_cv_lib_g=ac_cv_lib_g_main
+
+
+echo "$as_me:$LINENO: checking for main in -lm" >&5
+echo $ECHO_N "checking for main in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5
+echo "${ECHO_T}$ac_cv_lib_m_main" >&6
+if test $ac_cv_lib_m_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+fi
+ac_cv_lib_m=ac_cv_lib_m_main
+
+
+echo "$as_me:$LINENO: checking for main in -lcrypt" >&5
+echo $ECHO_N "checking for main in -lcrypt... $ECHO_C" >&6
+if test "${ac_cv_lib_crypt_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypt_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypt_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_main" >&5
+echo "${ECHO_T}$ac_cv_lib_crypt_main" >&6
+if test $ac_cv_lib_crypt_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCRYPT 1
+_ACEOF
+
+  LIBS="-lcrypt $LIBS"
+
+fi
+ac_cv_lib_crypt=ac_cv_lib_crypt_main
+
+if test $ENABLE_ACCENTFOLD = 1; then
+
+echo "$as_me:$LINENO: checking for main in -liconv" >&5
+echo $ECHO_N "checking for main in -liconv... $ECHO_C" >&6
+if test "${ac_cv_lib_iconv_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-liconv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_iconv_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_iconv_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_iconv_main" >&5
+echo "${ECHO_T}$ac_cv_lib_iconv_main" >&6
+if test $ac_cv_lib_iconv_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBICONV 1
+_ACEOF
+
+  LIBS="-liconv $LIBS"
+
+fi
+ac_cv_lib_iconv=ac_cv_lib_iconv_main
+
+fi
+
+
+
+
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5
+echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in dir; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+else
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in x; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+fi
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+
+
+for ac_header in fcntl.h limits.h sys/time.h unistd.h crypt.h string.h memory.h sys/procfs.h sys/stat.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "fread" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_FREAD_DECL 1
+_ACEOF
+
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "fgetc" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_FGETC_DECL 1
+_ACEOF
+
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/procfs.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "pr_brksize" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_PR_BRKSIZE 1
+_ACEOF
+
+fi
+rm -f conftest*
+
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+echo "$as_me:$LINENO: checking for working alloca.h" >&5
+echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6
+if test "${ac_cv_working_alloca_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_working_alloca_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_working_alloca_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5
+echo "${ECHO_T}$ac_cv_working_alloca_h" >&6
+if test $ac_cv_working_alloca_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA_H 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for alloca" >&5
+echo $ECHO_N "checking for alloca... $ECHO_C" >&6
+if test "${ac_cv_func_alloca_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  if HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_alloca_works=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_alloca_works=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5
+echo "${ECHO_T}$ac_cv_func_alloca_works" >&6
+
+if test $ac_cv_func_alloca_works = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA 1
+_ACEOF
+
+else
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble.  Some versions do not even contain alloca or
+# contain a buggy version.  If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=alloca.$ac_objext
+
+cat >>confdefs.h <<\_ACEOF
+#define C_ALLOCA 1
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5
+echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6
+if test "${ac_cv_os_cray+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "webecray" >/dev/null 2>&1; then
+  ac_cv_os_cray=yes
+else
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5
+echo "${ECHO_T}$ac_cv_os_cray" >&6
+if test $ac_cv_os_cray = yes; then
+  for ac_func in _getb67 GETB67 getb67; do
+    as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+    break
+fi
+
+  done
+fi
+
+echo "$as_me:$LINENO: checking stack direction for C alloca" >&5
+echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6
+if test "${ac_cv_c_stack_direction+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_c_stack_direction=0
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+  exit (find_stack_direction () < 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_stack_direction=1
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5
+echo "${ECHO_T}$ac_cv_c_stack_direction" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+if test $ac_cv_c_compiler_gnu = yes; then
+    echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5
+echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6
+if test "${ac_cv_prog_gcc_traditional+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+else
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5
+echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+echo "$as_me:$LINENO: checking return type of signal handlers" >&5
+echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
+if test "${ac_cv_type_signal+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+# undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_signal=void
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_signal=int
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
+echo "${ECHO_T}$ac_cv_type_signal" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+
+for ac_func in vprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+echo "$as_me:$LINENO: checking for _doprnt" >&5
+echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6
+if test "${ac_cv_func__doprnt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define _doprnt to an innocuous variant, in case <limits.h> declares _doprnt.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define _doprnt innocuous__doprnt
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _doprnt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef _doprnt
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char _doprnt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+char (*f) () = _doprnt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != _doprnt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func__doprnt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func__doprnt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5
+echo "${ECHO_T}$ac_cv_func__doprnt" >&6
+if test $ac_cv_func__doprnt = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DOPRNT 1
+_ACEOF
+
+fi
+
+fi
+done
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_func in ftime select strftime strtol getrusage times mallinfo setbuffer getpagesize strerror
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+for ac_func in ftruncate strstr strcasecmp
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+echo "$as_me:$LINENO: checking for textdomain" >&5
+echo $ECHO_N "checking for textdomain... $ECHO_C" >&6
+if test "${ac_cv_func_textdomain+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define textdomain to an innocuous variant, in case <limits.h> declares textdomain.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define textdomain innocuous_textdomain
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char textdomain (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef textdomain
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char textdomain ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_textdomain) || defined (__stub___textdomain)
+choke me
+#else
+char (*f) () = textdomain;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != textdomain;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_textdomain=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_textdomain=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_textdomain" >&5
+echo "${ECHO_T}$ac_cv_func_textdomain" >&6
+if test $ac_cv_func_textdomain = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define ENABLE_NLS  1
+_ACEOF
+
+fi
+
+
+# *** Custom checking (based on GNU tar configure.in) ***
+# ---------------------------------------------------------------------------
+echo "$as_me:$LINENO: checking for HP-UX needing gmalloc" >&5
+echo $ECHO_N "checking for HP-UX needing gmalloc... $ECHO_C" >&6
+if test "`(uname -s) 2> /dev/null`" = 'HP-UX'; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  case $LIBOBJS in
+    "gmalloc.$ac_objext"   | \
+  *" gmalloc.$ac_objext"   | \
+    "gmalloc.$ac_objext "* | \
+  *" gmalloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS gmalloc.$ac_objext" ;;
+esac
+
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_VALLOC 1
+_ACEOF
+
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+for ac_func in valloc
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+fi
+
+# we cannot generate static libraries under Darwin
+echo "$as_me:$LINENO: checking for Apple MacOS X/Darwin" >&5
+echo $ECHO_N "checking for Apple MacOS X/Darwin... $ECHO_C" >&6
+if test "`(uname -s) 2> /dev/null`" = 'Darwin'; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  STATIC=""
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  STATIC="-static "
+fi
+
+
+echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5
+echo $ECHO_N "checking if malloc debugging is wanted... $ECHO_C" >&6
+
+# Check whether --with-dmalloc or --without-dmalloc was given.
+if test "${with_dmalloc+set}" = set; then
+  withval="$with_dmalloc"
+  if test "$withval" = yes; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  cat >>confdefs.h <<\_ACEOF
+#define WITH_DMALLOC 1
+_ACEOF
+
+  LIBS="$LIBS -ldmalloc"
+  LDFLAGS="$LDFLAGS -g"
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+echo "$as_me:$LINENO: checking which of rx or regex is wanted" >&5
+echo $ECHO_N "checking which of rx or regex is wanted... $ECHO_C" >&6
+
+# Check whether --with-regex or --without-regex was given.
+if test "${with_regex+set}" = set; then
+  withval="$with_regex"
+  if test "$withval" = yes; then
+  ac_with_regex=1
+  echo "$as_me:$LINENO: result: regex" >&5
+echo "${ECHO_T}regex" >&6
+  cat >>confdefs.h <<\_ACEOF
+#define WITH_REGEX 1
+_ACEOF
+
+  case $LIBOBJS in
+    "regex.$ac_objext"   | \
+  *" regex.$ac_objext"   | \
+    "regex.$ac_objext "* | \
+  *" regex.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS regex.$ac_objext" ;;
+esac
+
+fi
+fi;
+if test -z "$ac_with_regex"; then
+  echo "$as_me:$LINENO: result: rx" >&5
+echo "${ECHO_T}rx" >&6
+  echo "$as_me:$LINENO: checking for re_rx_search" >&5
+echo $ECHO_N "checking for re_rx_search... $ECHO_C" >&6
+if test "${ac_cv_func_re_rx_search+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define re_rx_search to an innocuous variant, in case <limits.h> declares re_rx_search.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define re_rx_search innocuous_re_rx_search
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char re_rx_search (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef re_rx_search
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char re_rx_search ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_re_rx_search) || defined (__stub___re_rx_search)
+choke me
+#else
+char (*f) () = re_rx_search;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != re_rx_search;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_re_rx_search=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_re_rx_search=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_re_rx_search" >&5
+echo "${ECHO_T}$ac_cv_func_re_rx_search" >&6
+if test $ac_cv_func_re_rx_search = yes; then
+  :
+else
+  case $LIBOBJS in
+    "rx.$ac_objext"   | \
+  *" rx.$ac_objext"   | \
+    "rx.$ac_objext "* | \
+  *" rx.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS rx.$ac_objext" ;;
+esac
+
+fi
+
+fi
+
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+  case $LIBOBJS in
+    "xmalloc.$ac_objext"   | \
+  *" xmalloc.$ac_objext"   | \
+    "xmalloc.$ac_objext "* | \
+  *" xmalloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS xmalloc.$ac_objext" ;;
+esac
+
+  case $LIBOBJS in
+    "error.$ac_objext"   | \
+  *" error.$ac_objext"   | \
+    "error.$ac_objext "* | \
+  *" error.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS error.$ac_objext" ;;
+esac
+
+fi
+
+
+# ---------------------------------------------------------------------------
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking that Perl 5 is available" >&5
+echo $ECHO_N "checking that Perl 5 is available... $ECHO_C" >&6
+success="no"
+pl_path="$PATH"
+IFS="${IFS=   }"; pl_save_ifs="$IFS"; IFS=":"
+for pl_dir in $pl_path; do
+  test -z "$pl_dir" && pl_dir=.
+  if test -x $pl_dir/perl; then
+    success="yes"
+    break
+  fi
+done
+IFS="$pl_save_ifs"
+
+if test $success = "yes"; then
+try=`perl configtest.pl` || try="0"
+try=`expr $try \> 5.000`
+if test $try = "1"; then
+echo "$as_me:$LINENO: result: \"yes\"" >&5
+echo "${ECHO_T}\"yes\"" >&6
+else
+success="no"
+fi
+fi
+
+if test $success = "no"; then
+echo "$as_me:$LINENO: result: \"no\"" >&5
+echo "${ECHO_T}\"no\"" >&6
+{ { echo "$as_me:$LINENO: error: \"Perl 5 not available - cannot install\"" >&5
+echo "$as_me: error: \"Perl 5 not available - cannot install\"" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+success=no
+echo "$as_me:$LINENO: checking \"whether STL library has known faults\"" >&5
+echo $ECHO_N "checking \"whether STL library has known faults\"... $ECHO_C" >&6
+
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <vector>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  success=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $success = "no"; then
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <vector.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  success="yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test $success = "no"; then
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ospace\\std\\vector>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  success="yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test $success = yes; then
+echo "$as_me:$LINENO: result: \"no\"" >&5
+echo "${ECHO_T}\"no\"" >&6
+else
+echo "$as_me:$LINENO: result: \"yes\"" >&5
+echo "${ECHO_T}\"yes\"" >&6
+{ { echo "$as_me:$LINENO: error: \"STL Broken - Obtain newer version of GNU C Compiler\"" >&5
+echo "$as_me: error: \"STL Broken - Obtain newer version of GNU C Compiler\"" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+gsdlos=`uname | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+# check for running bash under cygwin
+ if test "`echo $gsdlos | sed 's/cygwin//'`" != "$gsdlos" ;
+ then
+  gsdlos=windows
+ fi
+
+
+# check for endianness
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+main ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+  case $LIBOBJS in
+    "xmalloc.o.$ac_objext"   | \
+  *" xmalloc.o.$ac_objext"   | \
+    "xmalloc.o.$ac_objext "* | \
+  *" xmalloc.o.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS xmalloc.o.$ac_objext" ;;
+esac
+
+  case $LIBOBJS in
+    "error.$ac_objext"   | \
+  *" error.$ac_objext"   | \
+    "error.$ac_objext "* | \
+  *" error.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS error.$ac_objext" ;;
+esac
+
+fi
+
+# ---------------------------------------------------------------------------
+
+moduleDirs=""
+MODULEDIRS=""
+if test -d modules ; then
+  for x in `find modules -mindepth 1 -maxdepth 2`; do
+    if test -d "$x"; then
+      d="$x/Makefile.in"
+      if test -e "$d"; then
+          moduleDirs="$moduleDirs $x/Makefile"
+        MODULEDIRS="$MODULEDIRS $x"
+      fi
+    fi
+  done
+  echo "Making $moduleDirs in modules directory"
+
+fi
+
+
+# ---------------------------------------------------------------------------
+
+
+subdirs="$subdirs packages"
+
+
+# the list of folders in the src folder
+srclist="src/hashfile/Makefile \
+         src/phind/generate/Makefile"
+
+                                        ac_config_files="$ac_config_files packages/Makefile Makefile $srclist $moduleDirs"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "packages/Makefile" ) CONFIG_FILES="$CONFIG_FILES packages/Makefile" ;;
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "$srclist" ) CONFIG_FILES="$CONFIG_FILES $srclist" ;;
+  "$moduleDirs" ) CONFIG_FILES="$CONFIG_FILES $moduleDirs" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@USE_FASTCGI@,$USE_FASTCGI,;t t
+s,@USE_LANGACTION@,$USE_LANGACTION,;t t
+s,@USE_CORBA@,$USE_CORBA,;t t
+s,@MICO_DIR@,$MICO_DIR,;t t
+s,@USE_Z3950@,$USE_Z3950,;t t
+s,@USE_YAZ@,$USE_YAZ,;t t
+s,@ENABLE_ACCENTFOLD@,$ENABLE_ACCENTFOLD,;t t
+s,@USE_SQLITE@,$USE_SQLITE,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@CC@,$CC,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CXX@,$CXX,;t t
+s,@CXXFLAGS@,$CXXFLAGS,;t t
+s,@ac_ct_CXX@,$ac_ct_CXX,;t t
+s,@AWK@,$AWK,;t t
+s,@YACC@,$YACC,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@target@,$target,;t t
+s,@target_cpu@,$target_cpu,;t t
+s,@target_vendor@,$target_vendor,;t t
+s,@target_os@,$target_os,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@LN_S@,$LN_S,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@COMPAT32BITFLAGS@,$COMPAT32BITFLAGS,;t t
+s,@MICO_VER@,$MICO_VER,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@U@,$U,;t t
+s,@ANSI2KNR@,$ANSI2KNR,;t t
+s,@ALLOCA@,$ALLOCA,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@STATIC@,$STATIC,;t t
+s,@gsdlos@,$gsdlos,;t t
+s,@MODULEDIRS@,$MODULEDIRS,;t t
+s,@subdirs@,$subdirs,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+#
+# CONFIG_SUBDIRS section.
+#
+if test "$no_recursion" != yes; then
+
+  # Remove --cache-file and --srcdir arguments so they do not pile up.
+  ac_sub_configure_args=
+  ac_prev=
+  for ac_arg in $ac_configure_args; do
+    if test -n "$ac_prev"; then
+      ac_prev=
+      continue
+    fi
+    case $ac_arg in
+    -cache-file | --cache-file | --cache-fil | --cache-fi \
+    | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+      ac_prev=cache_file ;;
+    -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+    | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \
+    | --c=*)
+      ;;
+    --config-cache | -C)
+      ;;
+    -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+      ac_prev=srcdir ;;
+    -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+      ;;
+    -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+      ac_prev=prefix ;;
+    -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+      ;;
+    *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+    esac
+  done
+
+  # Always prepend --prefix to ensure using the same prefix
+  # in subdir configurations.
+  ac_sub_configure_args="--prefix=$prefix $ac_sub_configure_args"
+
+  ac_popdir=`pwd`
+  for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue
+
+    # Do not complain, so a configure script can configure whichever
+    # parts of a large source tree are present.
+    test -d $srcdir/$ac_dir || continue
+
+    { echo "$as_me:$LINENO: configuring in $ac_dir" >&5
+echo "$as_me: configuring in $ac_dir" >&6;}
+    { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+    cd $ac_dir
+
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      ac_sub_configure="$SHELL '$ac_srcdir/configure.gnu'"
+    elif test -f $ac_srcdir/configure; then
+      ac_sub_configure="$SHELL '$ac_srcdir/configure'"
+    elif test -f $ac_srcdir/configure.in; then
+      ac_sub_configure=$ac_configure
+    else
+      { echo "$as_me:$LINENO: WARNING: no configuration information is in $ac_dir" >&5
+echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
+      ac_sub_configure=
+    fi
+
+    # The recursion is here.
+    if test -n "$ac_sub_configure"; then
+      # Make the cache file name correct relative to the subdirectory.
+      case $cache_file in
+      [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;;
+      *) # Relative path.
+	ac_sub_cache_file=$ac_top_builddir$cache_file ;;
+      esac
+
+      { echo "$as_me:$LINENO: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
+echo "$as_me: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
+      # The eval makes quoting arguments work.
+      eval $ac_sub_configure $ac_sub_configure_args \
+	   --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir ||
+	{ { echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5
+echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+
+    cd $ac_popdir
+  done
+fi
+
+
+
Index: /gsdl/stable/build-src/configure.in
===================================================================
--- /gsdl/stable/build-src/configure.in	(revision 20131)
+++ /gsdl/stable/build-src/configure.in	(revision 20131)
@@ -0,0 +1,380 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl Use autoconf-2.59 or later... it might not work anymore with
+dnl the older 2.1x versions - jrm21 12/2004
+AC_INIT()
+AC_CONFIG_HEADER(config.h)
+
+
+PACKAGE=gsdl
+VERSION=2.82-svn
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+dnl
+dnl Set use of fast cgi
+dnl
+USE_FASTCGI=0
+if test USE_FASTCGI = 1; then
+AC_DEFINE(USE_FASTCGI)
+AC_SUBST(USE_FASTCGI)
+fi
+
+dnl
+dnl Set use of langaction
+dnl
+dnl USE_LANGACTION=0
+if test USE_LANGACTION = 1; then
+AC_DEFINE(USE_LANGACTION)
+AC_SUBST(USE_LANGACTION)
+fi
+
+dnl
+dnl Set use of corba
+dnl
+AC_ARG_ENABLE(corba, [  --enable-corba          Enable CORBA support], USE_CORBA=1, USE_CORBA=0)
+AC_DEFINE_UNQUOTED(USE_CORBA, $USE_CORBA)
+AC_SUBST(USE_CORBA)
+
+AC_ARG_WITH(micodir, [  --with-micodir          Use installed MICO directory], MICO_DIR=$enableval, MICO_DIR="default")
+AC_DEFINE_UNQUOTED(MICO_DIR, "$MICO_DIR")
+AC_SUBST(MICO_DIR)
+
+dnl
+dnl Set use of z39.50
+dnl
+AC_ARG_ENABLE(z3950, [  --enable-z3950          Enable Z39.50 client support], USE_Z3950=1, USE_Z3950=0)
+if test USE_Z3950 = 1; then
+AC_DEFINE(USE_Z3950, $USE_Z3950)
+AC_SUBST(USE_Z3950)
+fi
+
+dnl
+dnl Set use of yaz - now compiled by default even when z3950 support not required
+dnl
+AC_ARG_ENABLE(yaz, [  --disable-yaz           Disable YAZ compilation], USE_YAZ=0, USE_YAZ=1)
+dnl if test USE_YAZ = 1; then
+AC_DEFINE(USE_YAZ, $USE_YAZ)
+AC_SUBST(USE_YAZ)
+dnl fi
+
+dnl 
+dnl disable compilation of accent folding stuff for mgpp (and one day mg)
+dnl
+AC_ARG_ENABLE(accentfold, [  --disable-accentfold    Disable Accent Folding for MGPP], ENABLE_ACCENTFOLD=0, ENABLE_ACCENTFOLD=1)
+AC_DEFINE(ENABLE_ACCENTFOLD, $ENABLE_ACCENTFOLD)
+AC_SUBST(ENABLE_ACCENTFOLD)
+
+dnl
+dnl Set use of SQLite (enabled by default)
+dnl
+AC_ARG_ENABLE(sqlite, [  --disable-sqlite        Disable SQLite support], USE_SQLITE=0, USE_SQLITE=1)
+AC_DEFINE(USE_SQLITE, $USE_SQLITE)
+AC_SUBST(USE_SQLITE)
+
+dnl Checks for programs.
+LDFLAGS=$LDFLAGS
+AC_SUBST(LDFLAGS)
+dnl only set CFLAGS if not already set in environment
+if test -z "$CFLAGS"; then
+CFLAGS=-O2
+fi
+AC_SUBST(CFLAGS)
+
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_AWK
+AC_PROG_YACC
+dnl get $target_cpu, $target_vendor, and $target_os
+dnl (as well as host_*)
+AC_CANONICAL_SYSTEM
+dnl do we actually want this? It adds a prefix based on host, system etc
+dnl AC_ARG_PROGRAM
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+
+AC_MSG_CHECKING(to see if architecture is 64-bit)
+arch_64bit=no
+case "$host_cpu" in
+x86_64) arch_64bit=yes ;;
+esac
+
+if test "$arch_64bit" = yes; then
+  AC_MSG_RESULT(yes)
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS="-m32"
+  fi
+else
+  AC_MSG_RESULT(no)
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS=
+  fi
+fi
+export COMPAT32BITFLAGS
+AC_SUBST(COMPAT32BITFLAGS)
+
+
+#moved CORBA MICO directory test to get version of MICO
+if test $USE_CORBA = 1; then
+
+if test $MICO_DIR = "default"; then
+#do something
+MICO_INC="-I packages/mico/mico/include"
+else
+#build the micotest program
+MICO_INC= ""
+if test $MICO_DIR != yes; then
+MICO_INC="-I $MICO_DIR"
+fi
+fi
+
+#get MICO_VER value
+sh -c "$CC -c micotest.cpp -o micotest.o $MICO_INC 2>&1" > /dev/null
+sh -c "$CC -o micotest micotest.o -lstdc++ 2>&1" > /dev/null
+MICO_VER=`./micotest` || MICO_VER=2.3.5
+sh -c "rm micotest"
+sh -c "rm micotest.o"
+
+#do test of MICO_VER
+if test MICO_VER != 0; then
+AC_DEFINE(MICO_VER)
+AC_SUBST(MICO_VER)
+fi
+#end USE_CORBA test
+fi
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_AIX
+AC_ISC_POSIX
+AC_MINIX
+fp_C_PROTOTYPES
+AC_C_CONST
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl --- This should be in the stdc checking -----------------
+if test "$ac_cv_prog_cc_stdc" = '-Xc'; then
+dnl The Pyramids running SMP_DC.OSx on MIPS r3000 chips with
+dnl /usr/opt/cc3.11/bin/cc treat -Xc as full ANSI mode - no POSIX or
+dnl XOPEN extensions (like popen).
+dnl Unfortunately -D_{XOPEN,POSIX}_SOURCE can't provide all that mg
+dnl needs. So drop back to -Xa
+AC_TRY_COMPILE(
+[#include <stdio.h>
+], [ FILE *rubbish = popen("yes", "r"); ],,
+[CC="`echo $CC | sed 's/-Xc/-Xa/'`"    ac_cv_prog_cc_stdc='-Xa'])
+fi
+dnl ----------------------
+
+
+dnl Checks for libraries.
+dnl check for -lg:
+AC_HAVE_LIBRARY(g)
+dnl check for -lm:
+AC_HAVE_LIBRARY(m)
+dnl check for -lcrypt:
+AC_HAVE_LIBRARY(crypt)
+if test $ENABLE_ACCENTFOLD = 1; then
+AC_HAVE_LIBRARY(iconv)
+fi
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h limits.h sys/time.h unistd.h crypt.h string.h memory.h sys/procfs.h sys/stat.h)
+AC_EGREP_HEADER(fread, stdio.h, AC_DEFINE(HAVE_FREAD_DECL))
+AC_EGREP_HEADER(fgetc, stdio.h, AC_DEFINE(HAVE_FGETC_DECL))
+AC_EGREP_HEADER(pr_brksize, sys/procfs.h, AC_DEFINE(HAVE_PR_BRKSIZE))
+
+dnl Checks for library functions.
+AC_FUNC_ALLOCA
+AC_PROG_GCC_TRADITIONAL
+AC_TYPE_SIGNAL
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(ftime select strftime strtol getrusage times mallinfo setbuffer getpagesize strerror)
+AC_REPLACE_FUNCS(ftruncate strstr strcasecmp)
+
+dnl see if gettext is in libc. (try the textdomain() function).
+AC_CHECK_FUNC(textdomain, AC_DEFINE(ENABLE_NLS ,1) )
+
+# *** Custom checking (based on GNU tar configure.in) ***
+# ---------------------------------------------------------------------------
+AC_MSG_CHECKING(for HP-UX needing gmalloc)
+if test "`(uname -s) 2> /dev/null`" = 'HP-UX'; then
+  AC_MSG_RESULT(yes)
+  AC_LIBOBJ([gmalloc])
+  AC_DEFINE(HAVE_VALLOC)
+else
+  AC_MSG_RESULT(no)
+  AC_CHECK_FUNCS(valloc)
+fi
+
+# we cannot generate static libraries under Darwin
+AC_MSG_CHECKING(for Apple MacOS X/Darwin)
+if test "`(uname -s) 2> /dev/null`" = 'Darwin'; then
+  AC_MSG_RESULT(yes)
+  STATIC=""
+else
+  AC_MSG_RESULT(no)
+  STATIC="-static "
+fi
+AC_SUBST(STATIC)
+
+fp_WITH_DMALLOC
+fp_WITH_REGEX
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+dnl    support functions for alloca.c
+  AC_LIBOBJ([xmalloc])
+  AC_LIBOBJ([error])
+fi
+
+
+# ---------------------------------------------------------------------------
+
+dnl
+dnl Switch into C++
+dnl
+AC_LANG_CPLUSPLUS
+
+dnl
+dnl Now check that Perl is actually around, and can be found
+dnl
+AC_MSG_CHECKING(that Perl 5 is available)
+success="no"
+pl_path="$PATH"
+IFS="${IFS=   }"; pl_save_ifs="$IFS"; IFS=":"
+for pl_dir in $pl_path; do
+  test -z "$pl_dir" && pl_dir=.
+  if test -x $pl_dir/perl; then
+    success="yes"
+    break
+  fi
+done
+IFS="$pl_save_ifs"
+
+dnl
+dnl Perl actually can be run; now we see if it is version 5 by
+dnl running a sample script (which returns a "clean" version number
+dnl and then tests the result using expr.  If perl errors in some
+dnl way (eg. broken Perl executable, missing script), we set a failure
+dnl value ("0") and then proceed as best we can
+dnl
+if test $success = "yes"; then
+try=`perl configtest.pl` || try="0"
+try=`expr $try \> 5.000`
+if test $try = "1"; then
+AC_MSG_RESULT("yes")
+else
+success="no"
+fi
+fi
+
+if test $success = "no"; then
+AC_MSG_RESULT("no")
+AC_MSG_ERROR("Perl 5 not available - cannot install")
+fi
+
+dnl
+dnl Check if the STL library has any known faults;
+dnl In GCC 2.7.2.x series, some STL library headers are missing
+dnl a file called "new" which is referred to by other headers
+dnl (eg. vector/vector.h); if this applies, then all use of the
+dnl STL will cause a compile fail, so we'd better let the user
+dnl know now, before things really go wrong!
+dnl
+success=no
+AC_MSG_CHECKING("whether STL library has known faults")
+
+dnl - first shot, try simple good old vector on its own
+AC_TRY_COMPILE(
+[#include <vector>
+], 
+[],
+success=yes,
+)
+
+dnl - try using the .h equivalent
+if test $success = "no"; then
+AC_TRY_COMPILE(
+[#include <vector.h>
+], 
+[],
+success="yes",
+)
+fi
+
+dnl - now try for the objectspace headers
+if test $success = "no"; then
+AC_TRY_COMPILE(
+[#include <ospace\\std\\vector>
+], 
+[],
+success="yes",
+)
+fi
+
+if test $success = yes; then
+AC_MSG_RESULT("no")
+else
+AC_MSG_RESULT("yes")
+AC_MSG_ERROR("STL Broken - Obtain newer version of GNU C Compiler")
+fi
+
+gsdlos=`uname | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+# check for running bash under cygwin
+ if test "`echo $gsdlos | sed 's/cygwin//'`" != "$gsdlos" ;
+ then
+  gsdlos=windows
+ fi
+AC_SUBST(gsdlos)
+
+# check for endianness
+AC_C_BIGENDIAN
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+dnl    support functions for alloca.c
+  AC_LIBOBJ([xmalloc.o])
+  AC_LIBOBJ([error])
+fi
+
+# ---------------------------------------------------------------------------
+
+dnl
+dnl Locate all children of the modules folder
+dnl
+moduleDirs=""
+MODULEDIRS=""
+if test -d modules ; then
+  for x in `find modules -mindepth 1 -maxdepth 2`; do
+    if test -d "$x"; then
+      d="$x/Makefile.in"
+      if test -e "$d"; then
+  dnl      echo $d
+        moduleDirs="$moduleDirs $x/Makefile"
+        MODULEDIRS="$MODULEDIRS $x"
+      fi
+    fi
+  done
+  echo "Making $moduleDirs in modules directory"
+  AC_SUBST(MODULEDIRS)
+fi
+
+
+# ---------------------------------------------------------------------------
+AC_CONFIG_SUBDIRS(packages)
+
+# the list of folders in the src folder
+srclist="src/hashfile/Makefile \
+         src/phind/generate/Makefile"
+
+AC_OUTPUT(packages/Makefile Makefile $srclist $moduleDirs)
+
+
Index: /gsdl/stable/build-src/packages/Makefile
===================================================================
--- /gsdl/stable/build-src/packages/Makefile	(revision 20131)
+++ /gsdl/stable/build-src/packages/Makefile	(revision 20131)
@@ -0,0 +1,58 @@
+###########################################################################
+#
+# Makefile -- Makefile for packages included with Greenstone buildtime
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2000 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# PACKAGEDIRS contains the packages that we want to make and install.  It
+# is assumed that each package will have at least four rules: all, install,
+# clean, and distclean.
+PACKAGEDIRS =	wv/wv-gs rtftohtml/rtftohtml_src pdftohtml/pdftohtml_gs \
+		wget/wget-1.11.4 cpan/XML-Parser-2.34 \
+		xlhtml/xlhtml-0.4.9.0 isis-gdl html-tidy/tidy
+
+
+all:
+	for odir in $(PACKAGEDIRS); do \
+          echo making $@ in $$odir; \
+          (cd $$odir && $(MAKE) $(MDEFINES) $@) || exit 1; \
+        done
+
+install:
+	for idir in $(PACKAGEDIRS); do \
+          echo installing $$idir; \
+          (cd $$idir && $(MAKE) install) || exit 1; \
+        done
+
+clean:
+	for subdir in $(PACKAGEDIRS); do \
+          echo cleaning $@ in $$subdir; \
+          (cd $$subdir && $(MAKE) clean || exit 0) ; \
+        done
+
+distclean:
+	for subdir in $(PACKAGEDIRS); do \
+          echo cleaning $@ in $$subdir; \
+          (cd $$subdir && $(MAKE) distclean || exit 0) ; \
+        done
Index: /gsdl/stable/build-src/packages/Makefile.in
===================================================================
--- /gsdl/stable/build-src/packages/Makefile.in	(revision 20131)
+++ /gsdl/stable/build-src/packages/Makefile.in	(revision 20131)
@@ -0,0 +1,58 @@
+###########################################################################
+#
+# Makefile -- Makefile for packages included with Greenstone buildtime
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2000 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# PACKAGEDIRS contains the packages that we want to make and install.  It
+# is assumed that each package will have at least four rules: all, install,
+# clean, and distclean.
+PACKAGEDIRS =	wv/wv-gs rtftohtml/rtftohtml_src pdftohtml/pdftohtml_gs \
+		wget/wget-1.11.4 cpan/XML-Parser-2.34 \
+		xlhtml/xlhtml-0.4.9.0 isis-gdl html-tidy/tidy
+
+
+all:
+	for odir in $(PACKAGEDIRS); do \
+          echo making $@ in $$odir; \
+          (cd $$odir && $(MAKE) $(MDEFINES) $@) || exit 1; \
+        done
+
+install:
+	for idir in $(PACKAGEDIRS); do \
+          echo installing $$idir; \
+          (cd $$idir && $(MAKE) install) || exit 1; \
+        done
+
+clean:
+	for subdir in $(PACKAGEDIRS); do \
+          echo cleaning $@ in $$subdir; \
+          (cd $$subdir && $(MAKE) clean || exit 0) ; \
+        done
+
+distclean:
+	for subdir in $(PACKAGEDIRS); do \
+          echo cleaning $@ in $$subdir; \
+          (cd $$subdir && $(MAKE) distclean || exit 0) ; \
+        done
Index: /gsdl/stable/build-src/packages/configure
===================================================================
--- /gsdl/stable/build-src/packages/configure	(revision 20131)
+++ /gsdl/stable/build-src/packages/configure	(revision 20131)
@@ -0,0 +1,206 @@
+#! /bin/sh
+
+PACKAGES=`pwd`
+cd ../..
+GSDLHOME=`pwd`
+cd $PACKAGES
+
+GSDLOS=`uname -s |tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+# check for running bash under cygwin
+if test "`echo $GSDLOS | sed 's/cygwin//'`" != "$GSDLOS" ;
+then
+ GSDLOS=windows
+fi
+
+prefix=""
+bindir=""
+HOSTTARGETFLAGS=""
+
+# only some of the packages can take environment variables as options to 
+# configure 
+# format is VAR=value, e.g "LDFLAGS=-static"
+ENVIRONMENT=""
+
+# SQLite support enabled by default, can switch it off with --disable-sqlite
+USE_SQLITE=true
+# yaz compilation enabled by default, can switch it off with --disable-yaz
+USE_YAZ=true
+# z3950 server disabled by default, switch it on with --enable-z3950
+USE_Z3950=false
+# CORBA support disabled by default, switch it on with --enable-corba
+USE_CORBA=false
+MICO_DIR=default
+
+# parse any arguments given from toplevel configure
+while test $# -ne 0; do
+    case "$1" in
+	--cache-file=*)
+	    cache_filename=`echo $1 | sed s/--cache-file=//`
+	    # turn relative path into an absolute path
+	    cache_dir=`echo $cache_filename | sed 's@/[^/]*$@@'`
+	    cache_dir=`cd $cache_dir 2>/dev/null && pwd`
+
+	    cache_basefile=`echo $cache_filename | sed 's@.*/@@'`
+	    cache_file="$cache_dir/$cache_basefile"
+	    if test ! -f "$cache_file"; then
+		CACHE_FILE=""
+	    else
+		CACHE_FILE="--cache-file=$cache_file"
+	    fi
+	    ;;
+	--disable-sqlite)
+	    USE_SQLITE=false
+	    ;;
+	--disable-yaz)
+	    USE_YAZ=false
+	    ;;
+	--enable-z3950)
+	    USE_Z3950=true
+	    ;;
+	--enable-corba)
+	    USE_CORBA=true
+	    ;;
+	--with-micodir=*)
+	    if test $1 = ""; then
+	      $1 = "default"
+            fi
+	    MICO_DIR=$1
+	    ;;       
+	--prefix=*)
+	    prefix=`echo $1 | sed s/--prefix=//`
+	    ;;
+	--bindir=*)
+	    # where to install binaries to
+	    bindir=`echo $1 | sed s/--bindir=//`
+	    # turn relative path into an absolute path
+	    if test -d "$bindir" ; then
+	      bindir=`cd "$bindir" ; pwd `
+	      cd "$PACKAGES"
+	    elif test -z `echo $bindir | sed '/^\// p;D'` ; then
+	      rel_bindir="`echo $bindir | sed s@/.*@@`"
+	      cd "$rel_bindir"
+	      bindir="`pwd`/`echo $bindir | sed s@^[^/]*/@@`"
+	      cd "$PACKAGES"
+	    else
+	      # bindir doesn't exist, and isn't relative
+	      true
+	    fi
+	    ;;
+	--host=* | --target=*)
+	    HOSTTARGETFLAGS="$HOSTTARGETFLAGS $1"
+	    ;;
+	*)
+	    # ignore all other options for now
+	    ;;
+    esac
+    shift
+done
+
+# note! Our GSDL package currently always installs into it's source
+# directory, ignoring any --prefix given to configure.
+# When this is fixed, uncomment the relevant lines below...
+
+##if test -z "$prefix" ; then
+prefix="${GSDLHOME}"
+##fi
+
+##if test -z "$bindir" ; then
+bindir="${prefix}/bin/$GSDLOS"
+##fi
+
+# This loads the top configure's cache file, with variables already set.
+if test -f "$cache_file" ; then
+  . $cache_file
+fi
+
+# we assume that gzip and tar are on the search path.
+# non-GNU versions of tar don't take the -z option.
+
+
+# configure the wvWare Word document converter
+echo ""
+echo "Configuring wvWare"
+echo ""
+
+cd "$PACKAGES/wv"
+gzip -dc wv-0.7.1-gs.tar.gz | tar -xf -
+# datadir is for default location of wvHtml.xml config file
+cd wv-gs && \
+./configure $CACHE_FILE --prefix=$PACKAGES/wv --bindir="$bindir" --datadir="$prefix/etc/packages" $HOSTTARGETFLAGS
+
+# configure the pdftohtml converter
+echo ""
+echo "Configuring pdftohtml"
+echo ""
+
+cd "$PACKAGES/pdftohtml"
+gzip -dc pdftohtml_0_36_gs.tar.gz | tar -xf -
+cd pdftohtml_gs && \
+./configure $CACHE_FILE --prefix="$prefix" --bindir="$bindir" $HOSTTARGETFLAGS $ENVIRONMENT
+
+# rtftohtml converter
+echo ""
+echo "Configuring rtftohtml"
+echo ""
+
+cd "$PACKAGES/rtftohtml"
+gzip -dc rtftohtml-gs.tar.gz | tar -xf -
+cd rtftohtml_src && \
+./configure $CACHE_FILE --prefix="$prefix" --bindir="$bindir" $HOSTTARGETFLAGS
+
+
+
+# configure wget
+echo ""
+echo "Configuring wget"
+echo ""
+cd "$PACKAGES/wget"
+gzip -dc wget.tar.gz | tar -xf -
+cd "$PACKAGES/wget/wget-1.11.4" && \
+./configure $CACHE_FILE --prefix=$PACKAGES/wget --bindir="$bindir" $HOSTTARGETFLAGS
+
+
+# configure XML::Parser perl module
+echo ""
+echo "Configuring XML::Parser"
+echo ""
+cd "$PACKAGES/cpan"
+perl_dir=`echo 'my $vn = $]; $vn =~ s/5\.00(\d).*$/perl-5.$1/; print "$vn" ' | perl`
+gzip -dc XML-Parser-2.34.tar.gz | tar -xf -
+cd "$PACKAGES/cpan/XML-Parser-2.34" && \
+perl Makefile.PL \
+  PREFIX="$GSDLHOME/perllib/cpan/XML" \
+  INSTALLSITELIB="$GSDLHOME/perllib/cpan/$perl_dir" \
+  INSTALLSITEARCH="$GSDLHOME/perllib/cpan/$perl_dir" \
+  INSTALLMAN1DIR="$GSDLHOME/perllib/cpan/$perl_dir" \
+  INSTALLMAN3DIR="$GSDLHOME/perllib/cpan/$perl_dir" \
+  SITEPREFIX="$GSDLHOME/perllib/cpan" \
+  EXPATINCPATH="$GSDLHOME/common-src/packages/expat/include" \
+  EXPATLIBPATH="$GSDLHOME/common-src/packages/expat/lib" 
+
+# configure powerpoint converter
+echo ""
+echo "Configuring xlhtml (powerpoint & excel converter)"
+echo ""
+cd "$PACKAGES/xlhtml"
+gzip -dc xlhtml-0.4.9.0-gs.tar.gz | tar -xf -
+cd xlhtml-0.4.9.0 && \
+./configure $CACHE_FILE --prefix="$prefix" --bindir="$bindir" $HOSTTARGETFLAGS
+
+
+# configure IsisGdl program
+echo ""
+echo "Configuring IsisGdl (CDS/ISIS database reader)"
+echo ""
+cd "$PACKAGES/isis-gdl" && \
+./configure $CACHE_FILE --prefix="$prefix" --bindir="$bindir" $HOSTTARGETFLAGS $ENVIRONMENT
+
+# configure HTMLTidy program
+echo ""
+echo "Configuring HTMLTidy"
+echo ""
+cd "$PACKAGES/html-tidy"
+gzip -dc tidy.tgz | tar -xf -
+cd "$PACKAGES/html-tidy/tidy" && \
+./configure $CACHE_FILE --prefix="$prefix" --bindir="$bindir" $HOSTTARGETFLAGS $ENVIRONMENT
+
Index: /gsdl/stable/build-src/packages/cpan/README
===================================================================
--- /gsdl/stable/build-src/packages/cpan/README	(revision 20131)
+++ /gsdl/stable/build-src/packages/cpan/README	(revision 20131)
@@ -0,0 +1,42 @@
+This directory contains perl modules from cpan for use with the Greenstone
+collection building code. After a "make install" these modules will be
+installed to the gsdl/perllib/cpan directory.
+
+Note that pure perl modules (i.e. those not containing any C code to
+compile) don't need building so they don't live in the packages directory
+tree (they live in perllib/cpan).
+
+
+The following modules are currently included:
+
+XML::Parser: Copyright (c) 1998-2000 Larry Wall and Clark Cooper
+ 
+ - Version 2.34
+
+  Originally, we used Version 2.27 cut down a bit for size, plus
+  a few modifications to Makefile.PL.  See below.
+
+
+HISTORY
+-------
+
+Mar 2005
+
+XML::Parser
+
+ - Version 2.34 and version 2.27
+added MAKEFILE_OLD => 'Makefile' to the Makefile.PL WriteMakeFile directive.
+previously, doing a make clean renamed the Makefile to Makefile.old, so then
+a make wouldn't work. Now Makefile gets renamed to Makefile. Hopefully this
+won't stuff anything else up.
+ 
+< Aug 2004
+
+XML::Parser: Copyright (c) 1998-2000 Larry Wall and Clark Cooper
+
+- Version 2.27 - as downloaded from cpan.org but with a few files removed
+  (to minimize the size of the tarball we distribute) and minor Greenstone
+  specific modifications to Makefile.PL. Originally used version 2.29 but
+  it appeared to be incompatible with perl 5.6.1.
+
+
Index: /gsdl/stable/build-src/packages/html-tidy/readme-tidy.txt
===================================================================
--- /gsdl/stable/build-src/packages/html-tidy/readme-tidy.txt	(revision 20131)
+++ /gsdl/stable/build-src/packages/html-tidy/readme-tidy.txt	(revision 20131)
@@ -0,0 +1,10 @@
+This is HTML Tidy, which was based at:
+	http://www.w3.org/People/Raggett/tidy/
+
+It has now been maintained by Source Forge, and is currently based at:
+	http://tidy.sourceforge.net/
+
+We're currently using the source created at 4 August 2000 which is Dave Raggett's latest version of HTML Tidy.
+
+Veronica Liesaputra
+February 2007
Index: /gsdl/stable/build-src/packages/isis-gdl/AbstractIsisDb.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/AbstractIsisDb.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/AbstractIsisDb.h	(revision 20131)
@@ -0,0 +1,171 @@
+/**********************************************************************
+ *
+ * AbstractIsisDb.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+///////////////////////////////////////////////////////////////////////////////////
+// AbstractIsisDb.h -- Abstract Base Class Definitions for an ISIS db
+//
+//
+// The objective is to provide an interface for creating families of Isis
+// db without specifying their concrete classes. 
+// ABSTRACT FACTORY PATTERN is used.
+//
+// Author: J-C Dauphin, UNESCO, August 2000
+///////////////////////////////////////////////////////////////////////////////////
+ 
+#ifndef __ABSTRACT_ISISDB_H__
+#define __ABSTRACT_ISISDB_H__
+
+#include <vector>
+#include "IsisDef.h"
+#include "mytchar.h"
+
+
+/////////////////////////////////////////////////////////////////////////////////// 
+//   Abstract Base Class, set the DB interface. All db concrete classes must be
+//   derived from this class.
+//
+// Note that this abstract base class can be extended by specifying abstract base
+// classes for class class MfFile, class XrfFile, class CFdtCWorksheet, 
+// class CDisplayFormat, class CFieldSelectTable, class CSortTable, 
+// class MfRecord and struct SMfHeader. Pure virtual methods would then be added
+// in the class AbstractIsisDbFactory:
+//
+// 	virtual AbstractMfFile* makeMfFile() = 0;
+//	virtual AbstractXrfFile* makeXrfFile() = 0;
+//  ................
+ 
+
+class MfFile;
+class XrfFile;
+class CFdt; // Forward 
+
+class CWorksheet;
+class CDisplayFormat;
+class CFieldSelectTable;
+class CSortTable;
+class MfRecord;
+struct SMfHeader;
+ 
+class AbstractIsisDb 
+{
+protected:
+	ustring    	name;
+
+    MfFile*   mf_;   // Has-a master file
+    XrfFile*  xf_;   // Has-a cross ref file
+    CFdt*     fdt_;  // Has-a FDT
+
+    std::vector<CWorksheet*>            apWS_;   // Worksheets
+    std::vector<CDisplayFormat*>        apDFMT_; // Display formats
+    std::vector<CFieldSelectTable*>     apFST_;  // Field Select Tables
+    std::vector<CSortTable*>            apST_;   // Sort Tables   
+    
+public:
+	AbstractIsisDb() { };                    // Trivial default C++ constructor
+	virtual ~AbstractIsisDb() { };           // Trivial C++ destructor
+
+// Opening the database
+   virtual int OpenDb(const TCHAR *fname, FileSystem::AccessMode mode =
+	                                          FileSystem::FILE_READWRITE) = 0; 
+// Creating the database
+   virtual int CreateDb(const TCHAR* fname) = 0;
+
+// Closing the database
+   virtual void CloseDb()   = 0;    // Close the db
+   virtual void ClearDb()   = 0;    // Clear the db
+   virtual void DestroyDb() = 0;    // Delete the db
+
+// Recovery
+   virtual bool IsDamaged() = 0;   // Test if the database is damaged
+   virtual bool Recover()   = 0;   // Recover the db
+
+// Transactions
+   virtual void BeginTransaction()     = 0;   // Begin a transaction
+   virtual void CommitTRansaction()    = 0;   // Commit a transaction
+   virtual void RollbackTransaction()  = 0;   // Rollback a transaction
+   virtual bool InTransaction()        = 0;   // Test if transaction is pending
+
+// (FDT)
+   virtual void SetFdt(CFdt *pFdt) { fdt_ = pFdt; }
+   virtual CFdt* GetFdt() { return fdt_; }
+
+//  worksheets (WORKSHEETS). 
+// (used to create/update the master records of the db)
+   virtual void SetWorksheetAt(int i, CWorksheet* pWS) { apWS_.insert(apWS_.begin()+i, pWS); }
+   virtual CWorksheet* GetWorksheetAt(int i)           { return apWS_[i]; }
+   virtual void RemoveWorksheetAt(int i)               { apWS_.erase(apWS_.begin()+i); }
+
+// display formats (DISPLAY FORMATS).
+// (used for specifying the formatting requirements for either on-line
+// display of records during searching or for the generation of printed
+// output documents.
+   virtual void SetDisplayFormatAt(int i, CDisplayFormat* pDFMT) { apDFMT_.insert(apDFMT_.begin()+i, pDFMT); }
+   virtual CDisplayFormat* GetDisplayFormatAt(int i)             { return apDFMT_[i]; }
+   virtual void RemoveDisplayFormatAt(int i)                     { apDFMT_.erase(apDFMT_.begin()+i); }
+
+// Field Select Table (FST).
+// One FST defines the fields of the database to be made searchable
+// through the inverted dile.
+   virtual void SetFieldSelectTableAt(int i, CFieldSelectTable* pFST) { apFST_.insert(apFST_.begin()+i, pFST); }
+   virtual CFieldSelectTable* GetFieldSelectTableAt(int i)            { return apFST_[i]; }
+   virtual void RemoveFieldSelectTableAt(int i)                       { apFST_.erase(apFST_.begin()+i); }
+
+   virtual void CreateIndex(int i) = 0;
+   virtual void DropIndex(int i)   = 0;
+
+// Sort Select Table (SST).
+// One FST defines the fields of the database to be made searchable
+// through the inverted dile.
+
+   virtual void SetSortTableAt(int i, CSortTable* pST) { apST_.insert(apST_.begin()+i, pST); }
+   virtual CSortTable* GetSortTableAt(int i)           { return apST_[i]; }
+   virtual void RemoveSortTableAt(int i)               { apST_.erase(apST_.begin()+i); }
+
+   virtual void  CreateDbRecord(MfRecord &m) = 0;
+   virtual void  UpdateDbRecord(MfRecord &m) = 0;
+   
+   virtual int   ReadDbRecord(long mfn, MfRecord &m) = 0;
+   virtual int   ReadNextDbRecord(MfRecord &m)       = 0;
+   
+   virtual bool  DeleteRecord(long mfn)              = 0;
+
+   virtual void  PrintDbRecord(MfRecord &m)          = 0;
+   virtual void  PrintDbHdr()                        = 0;
+
+   virtual long GetNextMfn() = 0;
+   virtual long GetNextActiveMfn(long mfn=-1) = 0;
+
+   virtual SMfHeader& GetSMfHeader() = 0;
+   virtual _TCHAR *GetIdxFileName()  = 0;
+ 
+
+};
+ 
+class AbstractIsisDbFactory
+{
+public:
+	virtual AbstractIsisDb* MakeIsisDb() = 0;
+};
+#endif   // __ABSTRACT_ISISDB_H__
Index: /gsdl/stable/build-src/packages/isis-gdl/BlkFile.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/BlkFile.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/BlkFile.h	(revision 20131)
@@ -0,0 +1,155 @@
+/**********************************************************************
+ *
+ * BlkFile.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+//////////////////////////////////////////////////////////////////////
+//  BLKFILE.H
+//
+//  Class for accessing a file per blocks of blksize bytes, blocks
+//  are sequential from 1 to nblock.
+//                                                                       
+//////////////////////////////////////////////////////////////////////
+ 
+#ifndef _BLKFILE_H_
+#define _BLKFILE_H_
+#include "CacheMan.h"
+#include "File.h"
+ 
+//////////////////////////
+// Block I/O file class
+//
+ 
+ 
+ 
+class BlkFile : public CFileBase
+{
+public:
+   enum { blk_size = 512 };
+protected:
+   unsigned     blkSize_;      // Block Size
+   CacheManager cache_;
+public:
+   BlkFile(int bs=BlkFile::blk_size);
+   BlkFile(const _TCHAR *fname, int bs=BlkFile::blk_size);
+   virtual FileError Close();
+   virtual ~BlkFile();
+   virtual void ReadBlk(void* d, long b);
+   virtual void WriteBlk(void* d, long b);
+   virtual void ReadBlk(void* d);
+   virtual void WriteBlk(void* d);
+
+   void SetBlockSize(int blockSize) { blkSize_ = blockSize; }
+   int  GetBlockSize() { return blkSize_; }
+};
+ 
+////////////////////////////////////////
+ 
+inline BlkFile::BlkFile(int bs) :
+// Makes a Blocked File object that isn't connected to a file
+// Block size is bs
+CFileBase(), blkSize_(bs)
+{
+	cache_.Create(bs, 40);
+	cache_.Connect(this);
+   // Nothing more to do
+}
+ 
+ 
+////////////////////////////////////////
+ 
+inline BlkFile::BlkFile(const _TCHAR *fname, int bs) :
+// Makes a Blocked File object connected to a file
+// Block size is bs
+CFileBase(), blkSize_(bs), cache_(bs, 20)
+{
+	CFileBase::Open(fname, FileSystem::FILE_READWRITE);
+	cache_.Create(bs, 40);
+	cache_.Connect(this);
+   // Nothing more to do
+}
+ 
+////////////////////////////////////////
+ 
+inline BlkFile::~BlkFile()
+// Destructor  for BlkFile object
+{
+	cache_.Disconnect();
+   // Nothing more to do
+}
+ 
+////////////////////////////////////////////
+
+
+inline FileError BlkFile::Close()
+{
+	if (IsOpen())
+	    cache_.Invalidate();
+	return CFileBase::Close();
+}
+////////////////////////////////////////
+ 
+inline void BlkFile::ReadBlk(void* d, long b)
+// Reads block number b into d, b is in range [1:NBLOCK]
+{
+	ASSERT(d!=NULL && b>0);
+	//TRACE("\nBlkFile::ReadBlk -- %s Read Block %ld", file_name, b);
+    //CFileBase::Fetch(d, blkSize_, (b-1)*blkSize_);
+	cache_.Read((b-1)*blkSize_, d);
+}
+ 
+////////////////////////////////////////
+ 
+inline void BlkFile::WriteBlk(void* d, long b)
+// Writes blksize bytes from d at block number b
+{
+	ASSERT(d!=NULL && b>0);
+	//TRACE("\nBlkFile::WriteBlk -- %s Write Block %ld", file_name, b);
+    //CFileBase::Store(d, blkSize_, (b-1)*blkSize_);
+	cache_.Write((b-1)*blkSize_, d);
+}
+ 
+ 
+////////////////////////////////////////
+ 
+inline void BlkFile::ReadBlk(void* d)
+// Reads block at current address into d
+{
+	ASSERT(d!=NULL);
+    //CFileBase::Fetch(d, blkSize_);
+	long addr = CFileBase::FilePosition();
+	cache_.Read(addr, d);
+}
+ 
+////////////////////////////////////////
+ 
+inline void BlkFile::WriteBlk(void* d)
+// Writes blkSize_ bytes from d at current address
+{
+	ASSERT(d!=NULL);
+    //CFileBase::Store(d, blkSize_);
+	long addr = CFileBase::FilePosition();
+	cache_.Write(addr, d);
+}
+ 
+#endif
Index: /gsdl/stable/build-src/packages/isis-gdl/CRC32.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/CRC32.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/CRC32.cpp	(revision 20131)
@@ -0,0 +1,170 @@
+/**********************************************************************
+ *
+ * CRC32.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////
+// CRC32.cpp --
+//  
+// The CRC32 functions (Cyclic Redundancy Check) are used to
+// calculate a sophisticated checksum based on the algebra of
+// polynomials. The Cyclic Redundancy Check, is a way to detect
+// bit errors that occur during data storage or transmission.
+// The CRC-32 algorithm operates on a block of data as a single
+// large numerical value. The algorithm divides this large value
+// by the CRC-32 polynomial or generator polynomial, leaving the
+// remainder 32-bit, which is the checksum. 
+//
+// #include "stdafx.h" 
+#include <iomanip>
+#include "CRC32.h"
+#include "CRCTab.h"
+
+unsigned long CalcCRC32(const char *buf, unsigned len)
+// Calculate a 32-bit CRC for a raw pattern of bytes.
+// Returns a 32-bit checksum.
+{
+ unsigned long CRC=0xffffffffL;
+ unsigned int n = len;
+
+ while(n--) 
+   CRC=crc32tab[(CRC ^ (*buf++)) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL);
+
+ return CRC ^ 0xffffffffL;
+}
+
+unsigned long CalcCRC32(char *buf, unsigned len)
+// Calculate a 32-bit CRC for a raw pattern of bytes.
+// Returns a 32-bit checksum.
+{
+ unsigned long CRC=0xffffffffL;
+ unsigned int n = len;
+ char *p = (char *)buf;
+ while(n--) 
+   CRC=crc32tab[(CRC ^ (*p++)) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL);
+
+ return CRC ^ 0xffffffffL;
+}
+
+unsigned long CalcCRC32(unsigned char c, unsigned long CRC)
+// Calculate a 32-bit CRC table value for a single byte.
+// NOTE: The initial CRC value must be set to 0xffffffffL
+// and the final 32-bit value that must be XOR'ed with
+// 0xffffffffL to obtain the checksum.
+{
+  unsigned int i;
+  i = (unsigned int)c;
+  i &= 0xFF; // Reset all the bits
+  CRC=crc32tab[(CRC ^ i) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL);
+  return CRC;
+}
+
+unsigned long CalcCRC32(std::fstream &infile)
+// Calculate a 32-bit CRC for a file. Assumes the stream
+// is already open. Returns a 32-bit checksum.
+{
+ unsigned long CRC=0xffffffffL;
+#ifdef _WIN32
+ char c;
+#else
+ unsigned char c;
+#endif
+ unsigned int i;
+
+ // Rewind to the start of the stream
+ infile.clear(); 
+ infile.seekg(0, std::ios::beg);
+ infile.seekp(0, std::ios::beg);
+
+ while(!infile.eof()) {
+   c=infile.get();
+   i = (unsigned int)c;
+   i &= 0xFF; // Reset all the bits
+   if(infile.eof()) break;
+   CRC=crc32tab[(CRC ^ i) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL);
+ }
+ return CRC ^ 0xffffffffL;
+}
+
+#ifdef __USE_CRC32_TABLE_FUNCTIONS__
+int MakeCRC32(ostream &stream)
+// Write a CRC 32 table for a byte-wise 32-bit CRC calculation
+// based on the Autodin/Ethernet/ADCCP polynomial of 0x4C11DB7:
+// 0000 0100 1100 0001 0001 1101 1011 0111 (binary) or a poly of
+// x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7 +x^5+x^4+x^2+x^1+x^0
+// In this representation the coefficient of x^0 is stored in the 
+// MSB of the 32-bit word and the coefficient of x^31 is stored in 
+// the LSB. Thus 0x4C11DB7 becomes 0xEDB88320:
+// 1110 1101 1011 1000 1000 0011 0010 0000 (binary)
+
+// Adding the polynomials is performed using an exclusive-or, and
+// multiplying a polynomial by x is a right shift by one. If the 
+// polynomial is called "p", and each byte is represented as polynomial
+// "q", with the lowest power in the most significant bit (so the byte
+// 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) 
+// mod "p", where "a" mod "b" means the remainder after dividing "a" by
+// "b". This calculation is done using the shift-register method of
+// multiplying and taking the remainder. The register is initialized
+// to zero, and for each incoming bit, x^32 is added mod "p" to the
+// register if the bit is a one (where x^32 mod p is p+x^32 = x^26+...+1),
+// and the register is multiplied mod "p" by "x" (which is shifting right
+// by one and adding x^32 mod "p" if the bit shifted out is a one.) This
+// algorithm starts with the highest power (least significant bit) of "q"
+// and repeats for all eight bits of "q".
+{
+  unsigned long c; // CRC shift register 
+  unsigned long e; // Polynomial exclusive-or pattern 
+  int i;           // Counter for all possible eight bit values 
+  int k;           // Byte being shifted into crc apparatus 
+
+  // Terms of polynomial defining this crc (except x^32): 
+  static const int p[14] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+  // Make exclusive-or pattern from polynomial 
+  e = 0;
+  for (i = 0; i < sizeof(p)/sizeof(int); i++)
+    e |= 1L << (31 - p[i]);
+
+  // Compute and print table of CRC's, five per line 
+  stream << endl;
+  stream << "  0x00000000U";
+  for (i = 1; i < 256; i++)
+  {
+    c = 0;
+    for (k = i | 256; k != 1; k >>= 1)
+    {
+      c = c & 1 ? (c >> 1) ^ e : c >> 1;
+      if (k & 1)
+        c ^= e;
+    }
+
+    if(i % 5)
+      stream << ", 0x" << setfill('0') << setw(8) << hex << c << "U";
+    else
+      stream << "," << endl << "  0x" << setfill('0') << setw(8) << hex
+	     << c << "U";
+  }
+  stream << endl;
+  return 1;
+}
+#endif // __USE_CRC32_TABLE_FUNCTIONS__
Index: /gsdl/stable/build-src/packages/isis-gdl/CRC32.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/CRC32.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/CRC32.h	(revision 20131)
@@ -0,0 +1,52 @@
+/**********************************************************************
+ *
+ * CRC32.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////
+// CRC32.H
+//
+// The CRC32 functions (Cyclic Redundancy Check) are used to
+// calculate a sophisticated checksum based on the algebra of
+// polynomials. The Cyclic Redundancy Check, is a way to detect
+// bit errors that occur during data storage or transmission.
+// The CRC-32 algorithm operates on a block of data as a single
+// large numerical value. The algorithm divides this large value
+// by the CRC-32 polynomial or generator polynomial, leaving the
+// remainder 32-bit, which is the checksum. 
+#ifndef __CRC32_H__
+#define __CRC32_H__
+
+#include <fstream>
+
+unsigned long CalcCRC32(char *buf, unsigned len);
+unsigned long CalcCRC32(const char *buf, unsigned len);
+unsigned long CalcCRC32(unsigned char c, unsigned long CRC);
+unsigned long CalcCRC32(std::fstream &infile);
+
+#ifdef __USE_CRC32_TABLE_FUNCTIONS__
+#include <iostream>
+int makeCRC32(std::ostream &stream);
+#endif
+
+#endif  // __CRC32_H__
Index: /gsdl/stable/build-src/packages/isis-gdl/CRCTab.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/CRCTab.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/CRCTab.h	(revision 20131)
@@ -0,0 +1,100 @@
+/**********************************************************************
+ *
+ * CRCTab.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////
+// CRCTAB.H --
+
+// CRC 32 table of all possible single-byte values. The table is
+// the CRC of all possible eight bit values. This is all the info
+// needed to generate 32-bit CRC's on data one a byte at a time 
+// for all combinations of CRC register values and incoming bytes.   
+// This table was generated with the makeCRC32() function. It is
+// based on the Autodin/Ethernet/ADCCP polynomial of 0x4C11DB7:
+// 0000 0100 1100 0001 0001 1101 1011 0111 (binary) or a poly of
+// x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7 +x^5+x^4+x^2+x^1+x^0
+// In this representation the coefficient of x^0 is stored in the 
+// MSB of the 32-bit word and the coefficient of x^31 is stored in 
+// the LSB. Thus 0x4C11DB7 becomes 0xEDB88320:
+// 1110 1101 1011 1000 1000 0011 0010 0000 (binary)
+
+#ifndef __CRC32_TABLE_HPP__
+#define __CRC32_TABLE_HPP__
+
+const unsigned long crc32tab[256] = {
+  0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,
+  0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,
+  0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U,
+  0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU,
+  0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U,
+  0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U,
+  0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U,
+  0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU,
+  0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U,
+  0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU,
+  0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U,
+  0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
+  0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U,
+  0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU,
+  0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU,
+  0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U,
+  0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU,
+  0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U,
+  0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U,
+  0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U,
+  0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU,
+  0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U,
+  0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U,
+  0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
+  0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U,
+  0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U,
+  0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U,
+  0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
+  0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U,
+  0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU,
+  0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU,
+  0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U,
+  0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U,
+  0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU,
+  0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU,
+  0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
+  0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU,
+  0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U,
+  0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU,
+  0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U,
+  0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU,
+  0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
+  0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U,
+  0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU,
+  0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U,
+  0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U,
+  0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U,
+  0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
+  0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U,
+  0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U,
+  0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
+  0x2d02ef8dU
+};
+
+#endif // __CRC32_TABLE_HPP__
Index: /gsdl/stable/build-src/packages/isis-gdl/CacheMan.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/CacheMan.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/CacheMan.cpp	(revision 20131)
@@ -0,0 +1,213 @@
+/**********************************************************************
+ *
+ * CacheMan.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#include "stdafx.h"
+#include "File.h"
+
+#include "CacheMan.h"
+
+
+CacheManager::CacheManager()
+{
+	maxblocks_ = 0;
+}
+CacheManager::CacheManager(unsigned blocksz, unsigned mxblks)
+{
+	PRECONDITION(maxblocks_ == 0);
+	maxblocks_ = mxblks;
+	nused_     = 0;
+	blocksize_ = blocksz;
+	buff_      = new char[blocksize_*maxblocks_];
+	diskAddrs_ = new FileSystem::FAU_t[maxblocks_];
+	useCounts_ = new unsigned[maxblocks_];
+	theFile_   = NULL;
+}
+/*
+ * Construct a cache manager for blocks of size blocksz and mxblks buffers
+ */
+void CacheManager::Create(unsigned blocksz, unsigned mxblks)
+{
+	PRECONDITION(maxblocks_ == 0);
+	maxblocks_ = mxblks;
+	nused_     = 0;
+	blocksize_ = blocksz;
+	buff_      = new char[blocksize_*maxblocks_];
+	diskAddrs_ = new FileSystem::FAU_t[maxblocks_];
+	useCounts_ = new unsigned[maxblocks_];
+	theFile_   = NULL;
+}
+
+//
+// Connect to a CFileBase
+//
+void CacheManager::Connect(CFileBase* file)
+{
+	PRECONDITION(nused_ == 0);
+	theFile_   = file;
+}
+//
+// Disconnect the cache from the CFileBase
+//
+void CacheManager::Disconnect()
+{
+	if (theFile_)
+	{
+		if (theFile_->IsOpen())
+		    Flush();
+	}
+	theFile_   = NULL;
+}
+
+void CacheManager::Erase()
+{
+	Disconnect();
+	delete[] useCounts_;
+	delete[] diskAddrs_;
+	delete[] buff_;
+	maxblocks_ = 0;
+}
+
+
+CacheManager::~CacheManager()
+{
+	Disconnect();
+	delete[] useCounts_;
+	delete[] diskAddrs_;
+	delete[] buff_;
+}
+
+bool CacheManager::Flush()
+{
+	PRECONDITION(theFile_ != NULL && theFile_->IsOpen());
+	// Because we use "write through", this is all that's necessary:
+	if (theFile_->Flush() == FILE_NO_ERROR)
+		return true;
+	return false;
+}
+
+void CacheManager::Invalidate()
+{
+	nused_ = 0;
+}
+
+bool CacheManager::Read(FileSystem::FAU_t locn, void* dat)
+{
+	PRECONDITION(dat != NULL);
+	size_t islot = AgeAndFindSlot(locn);
+	
+	if (islot == INVALID_NPOS)
+	{
+        // Not in buffer;  we'll have to read it in from disk.
+	    // Get a free slot.
+		if ((islot = GetFreeSlot()) == INVALID_NPOS)
+			return false;
+		diskAddrs_[islot] = locn;
+		if (!(theFile_->SeekTo(locn) == locn) || 
+			!(theFile_->Fetch(buff_ + islot*blocksize_, blocksize_) == FILE_NO_ERROR))
+			return false;
+	}
+	useCounts_[islot] = 0;
+	memcpy(dat, buff_ + islot*blocksize_, blocksize_);
+	return true;
+}
+
+bool CacheManager::Write(FileSystem::FAU_t locn, void* dat)
+{
+	PRECONDITION(dat != NULL);
+	PRECONDITION(theFile_->ReadyForWriting());
+	size_t islot = AgeAndFindSlot(locn);
+	
+	if (islot == INVALID_NPOS)
+	{
+        // Not in buffer; find a free slot.
+		if ((islot = GetFreeSlot()) == INVALID_NPOS)
+			return false;
+		diskAddrs_[islot] = locn;
+	}
+	
+	useCounts_[islot] = 0;
+	memcpy(buff_ + islot*blocksize_, dat, blocksize_);
+	if ((theFile_->SeekTo(locn) == locn) &&
+		(theFile_->Store(buff_ + islot*blocksize_, blocksize_) == FILE_NO_ERROR))
+		return true;
+	return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// Private helper functions	
+
+size_t CacheManager::AgeAndFindSlot(FileSystem::FAU_t locn)
+{
+	size_t islot = INVALID_NPOS;
+	for (register unsigned i = 0; i < nused_; i++)
+	{
+		if (diskAddrs_[i] == locn)
+			islot = i;
+		useCounts_[i]++;		// Age the blocks
+	}
+	return islot;
+}
+
+bool CacheManager::Flush(unsigned)
+{
+	if (theFile_->Flush() == FILE_NO_ERROR)
+		return true;
+	return false;
+}
+
+size_t CacheManager::GetFreeSlot()
+{
+	size_t islot;
+	
+	if (nused_ < maxblocks_)
+	{
+		islot = nused_++;		// Found an unused slot.
+	}
+	else 
+	{
+		// No free slots; get the Least Recently Used block
+		islot = LRU();
+
+		if (theFile_->ReadyForWriting())
+			if (!Flush(islot))
+			    islot = INVALID_NPOS;
+	}
+	return islot;
+}
+
+size_t CacheManager::LRU() const
+{
+	size_t islot = 0;
+	unsigned maxCount = useCounts_[0];
+	for (register unsigned i = 1; i < nused_; i++)
+	{
+		if (useCounts_[i] > maxCount)
+		{
+			maxCount = useCounts_[islot = i]; 
+		}
+	}
+	return islot;
+}
Index: /gsdl/stable/build-src/packages/isis-gdl/CacheMan.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/CacheMan.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/CacheMan.h	(revision 20131)
@@ -0,0 +1,71 @@
+/**********************************************************************
+ *
+ * CacheMan.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef __CACHEMAN_H__
+#define __CACHEMAN_H__
+
+
+#include "File.h"
+
+class CacheManager
+{
+private:
+	
+	CFileBase*	       theFile_;
+	unsigned		   maxblocks_;  // Max # blocks in buff_er
+	unsigned		   nused_;	    // Number being used.
+	unsigned		   blocksize_;  // Size of a block
+	FileSystem::FAU_t* diskAddrs_;  // Its disk address
+	unsigned*		   useCounts_;  // Use count for the block
+	char*			   buff_;	    // The set of blocks.
+	
+public:
+	
+	CacheManager();
+	CacheManager(unsigned blocksz, unsigned mxblks);
+
+	~CacheManager();
+	
+	void        Create(unsigned blocksz, unsigned mxblks = 10);
+	void        Erase();
+	
+	void        Connect(CFileBase* file);
+	void        Disconnect();
+	bool  		Flush();	        // Perform any pending writes.
+	void		Invalidate();	    // Invalidate the entire cache
+	bool  		Read (FileSystem::FAU_t locn, void* dat);
+	bool  		Write(FileSystem::FAU_t locn, void* dat);
+	
+private:
+	
+	CacheManager(const CacheManager&);          // Private to insure no copies
+	void		operator=(const CacheManager&); // Ditto
+	size_t		AgeAndFindSlot(FileSystem::FAU_t);
+	bool  		Flush(unsigned);
+	size_t		GetFreeSlot();
+	size_t		LRU() const; // Find least recently used block
+};
+
+#endif
Index: /gsdl/stable/build-src/packages/isis-gdl/Checking.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/Checking.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/Checking.cpp	(revision 20131)
@@ -0,0 +1,65 @@
+/**********************************************************************
+ *
+ * Checking.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+// Checking -- 
+//               
+
+
+#include "stdafx.h"
+#include "File.h"
+#include "Master.h"
+#include "MFFile.h"
+#include "Checking.h"
+
+using namespace Checking;
+//---------------------------------------------------------------------
+// Checking::CheckMfHeader(const char *mfname, SMfHeader *mfh)
+//
+// Invariant to be respected by the mf header
+//---------------------------------------------------------------------
+void Checking::CheckMfHeader(const _TCHAR *mfname, SMfHeader &mfh)
+{
+	long size = FileSystem::FileSize(mfname);
+	TRACE(_T("\nsize=%ld "), size);
+	long mfSize = mfh.nxtmfb_ * MFBLKSIZE;
+	//ASSERT(size == mfSize);
+	ASSERT(mfh.nxtmfp_>0 && mfh.nxtmfp_<=MFBLKSIZE);
+	ASSERT(mfh.mftype_ == USERMST);
+	ASSERT(mfh.nxtmfn_>0);
+	ASSERT(mfh.ctlmfn_ == 0);
+	//assert(mfh.reccnt == 0);
+	//assert(mfh.mfcxx1 == 0);
+	//assert(mfh.mfcxx2 == 0);
+	//assert(mfh.mfcxx3 == 0);
+}
+
+void Checking::CheckMfRecordHeader(long addr)
+{
+
+}
+
+using namespace std;
Index: /gsdl/stable/build-src/packages/isis-gdl/Checking.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/Checking.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/Checking.h	(revision 20131)
@@ -0,0 +1,34 @@
+/**********************************************************************
+ *
+ * Checking.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/////////////////////////////////////////////////////////////////////////////////
+// Checking.h --
+
+
+namespace Checking {
+   void CheckMfHeader(const _TCHAR *mfname, SMfHeader &mfh);
+   void CheckMfRecordHeader(long addr);
+
+}
Index: /gsdl/stable/build-src/packages/isis-gdl/Compat.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/Compat.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/Compat.h	(revision 20131)
@@ -0,0 +1,140 @@
+/**********************************************************************
+ *
+ * Compat.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef _WIN32
+
+#include <string>
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+#include <stdio.h>
+#include <sys/stat.h>
+
+#define TCHAR  char
+#define BOOL   bool
+#define WORD   unsigned short
+#define DWORD  unsigned long
+#define INT32  int
+#define UINT32 unsigned int
+#define LONG   long int
+#define TRUE   true
+#define FALSE  false
+
+#define _MAX_PATH 512
+#define SHRT_MAX  32732
+
+/* Formatted i/o */
+
+#define _tprintf    printf
+#define _ftprintf   fprintf
+#define _stprintf   sprintf
+#define _sntprintf  _snprintf
+#define _vtprintf   vprintf
+#define _vftprintf  vfprintf
+#define _vstprintf  vsprintf
+#define _vsntprintf _vsnprintf
+#define _tscanf     scanf
+#define _ftscanf    fscanf
+#define _stscanf    sscanf
+/* String conversion functions */
+
+#define _tcstod     strtod
+#define _tcstol     strtol
+#define _tcstoul    strtoul
+
+#define _itot       _itoa
+#define _ltot       _ltoa
+#define _ultot      _ultoa
+#define _ttoi       atoi
+#define _ttol       atol
+
+#define _ttoi64     _atoi64
+#define _i64tot     _i64toa
+#define _ui64tot    _ui64toa
+/* String functions */
+
+/* Note that _mbscat, _mbscpy and _mbsdup are functionally equivalent to 
+   strcat, strcpy and strdup, respectively. */
+
+#define _tcscat     strcat
+#define _tcscpy     strcpy
+#define _tcsdup     _strdup
+
+#define _tcslen     strlen
+#define _tcsxfrm    strxfrm
+
+
+// #define assert
+#define ASSERT
+#define AssertFailed
+
+// #define _T(par) par
+#define LPCTSTR const char *
+#define LPTSTR char *
+#define FAR
+#define TRACE
+#define PRECONDITION
+#define SIZE_T size_t
+
+
+
+#endif
+#define MoveMemory memmove
+#define ZeroMemory(p,size) memset(p,0,size)
+
+
+inline void fix_endianness(short int& x)
+{
+#if !defined(LITTLE_ENDIAN)
+  if (x < 0) {
+    unsigned short int ux = (unsigned short int) x;
+    x = (ux>>8) | 
+        (ux<<8);
+  }
+  else {
+    x = (x>>8) | 
+        (x<<8);
+  }
+#endif
+}
+
+inline void fix_endianness(long int& x)
+{
+#if !defined(LITTLE_ENDIAN)
+  if (x < 0) {
+    unsigned long ux = (unsigned long) x;
+    x = (ux>>24) | 
+      ((ux<<8) & 0x00FF0000) |
+      ((ux>>8) & 0x0000FF00) |
+      (ux<<24);
+  }
+  else {
+    x = (x>>24) | 
+      ((x<<8) & 0x00FF0000) |
+      ((x>>8) & 0x0000FF00) |
+      (x<<24);
+  }
+#endif
+}
Index: /gsdl/stable/build-src/packages/isis-gdl/DLLCode.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/DLLCode.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/DLLCode.h	(revision 20131)
@@ -0,0 +1,74 @@
+/**********************************************************************
+ *
+ * DLLCode.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/////////////////////////////////////////////////////////////////////////////
+// DLLCODE.H - include file used by all platforms to define macros required 
+//             to build static and dynamic libraries.
+//             The DLLCODE.H file is included in every include file extending
+//             the visibility of the macros defined here to the every source
+//             code file. 
+
+
+#ifndef __DLL_CODE_H__
+#define __DLL_CODE_H__
+
+#if defined (__MSVC_DLL__) // Defines the entry point for the DLL application
+//--------------------------------------------------------------------------
+// The following ifdef block is the standard way of creating macros which 
+// make exporting from a DLL simpler. All files within this DLL are compiled 
+// with the DLL_CODE_EXPORTS  symbol defined on the command line. This 
+// symbol should not be defined on any project that uses this DLL. This way 
+// any other project whose source files include this file see DLL_CODE_API 
+// functions as being imported from a DLL, whereas this DLL sees symbols
+// defined with this macro as being exported.
+//---------------------------------------------------------------------------
+#ifdef DLL_CODE_EXPORTS
+#define DLL_CODE_API __declspec(dllexport)
+#else
+#define DLL_CODE_API __declspec(dllimport)
+#endif
+#else // Macro used for non DLL code
+#define DLL_CODE_API
+#endif // __MSVC_DLL__
+
+// Force ANSI compatibility for Visual C++ .NET
+#if defined (__MSDEVNET__) && !defined (__USE_ANSI_CPP__)
+#define __USE_ANSI_CPP__
+#endif // __MSDEVNET__
+
+// Force ANSI compatibility for BCC32
+#if defined (__BCC32__) && !defined (__USE_ANSI_CPP__)
+#define __USE_ANSI_CPP__
+#endif // __BCC32__
+
+#if defined (__USE_ANSI_CPP__)
+// Macro used to define the std name space used by the ANSI 
+// Standard C++ library.
+#define GXSTD std
+#else // Use the old Standard C++ library by default  
+#define GXSTD
+#endif // __USE_ANSI_CPP__
+
+#endif // __DLL_CODE_H__
Index: /gsdl/stable/build-src/packages/isis-gdl/Debug.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/Debug.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/Debug.cpp	(revision 20131)
@@ -0,0 +1,213 @@
+#include "stdafx.h"
+#include "Debug.h"
+
+//---------------------------------------------------------------
+//
+// AssertFailed
+//
+//---------------------------------------------------------------
+#if DEBUG || ASSERTS_THROW
+void AssertFailed(const char* expr, const char* file, int line)
+{
+	/*
+	_TCHAR mesg[512];							
+
+	const char* fileName = file + strlen(file);		// strip off path
+	while (fileName > file && fileName[-1] != '\\')
+		--fileName;
+
+	_stprintf(mesg, _T("ASSERT(%s) in '%s' at line %d failed."), expr, fileName, line);
+	
+	MSG msg;							// remove pending quit messages so the message box displays
+	bool quitting = (bool) ::PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
+
+	UINT32 flags = MB_OK +				// just an OK button
+				   MB_ICONERROR +		// display the icon for errors
+				   MB_DEFBUTTON1 +		// select the OK button
+				   MB_TASKMODAL +		// don't let the user do anything else in the app
+				   MB_SETFOREGROUND;	// bring the app to the front
+
+	(void) MessageBox(NULL, mesg, NULL, flags);
+//#if DEBUG
+//	if (gBreakOnAssert)
+//		BreakStrToDebugger(mesg);
+//#endif
+
+//#if ASSERTS_THROW
+	CString text = L"Internal (Assert) Error: ";
+	AfxThrowUserException( ); 
+//#endif
+*/
+}
+#endif	// DEBUG || ASSERTS_THROW
+
+
+//---------------------------------------------------------------
+//
+// RequireFailed
+//
+//---------------------------------------------------------------
+#if !DEBUG
+void RequireFailed(const char* expr, const char* file, int line)
+{
+	/*
+	char mesg[512];							
+
+	const char* fileName = file + strlen(file);		// strip off path
+	while (fileName > file && fileName[-1] != '\\')
+		--fileName;
+
+	sprintf(mesg, "There has been a fatal error in '%s' at line %d.", fileName, line);
+
+	MSG msg;							// remove pending quit messages so the message box displays
+	bool quitting = (bool) ::PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
+
+	UINT32 flags = MB_OK +				// just an OK button
+				   MB_ICONERROR +		// display the icon for errors
+				   MB_DEFBUTTON1 +		// select the OK button
+				   MB_TASKMODAL +		// don't let the user do anything else in the app
+				   MB_SETFOREGROUND;	// bring the app to the front
+
+	(void) MessageBox(NULL, mesg, NULL, flags);
+
+	abort();
+	*/
+}
+#endif // !DEBUG
+
+//---------------------------------------------------------------
+//
+// ToStr (bool)
+//
+//---------------------------------------------------------------
+std::wstring ToStr(bool value)
+{
+	return value ? L"true" : L"false";
+}
+
+
+//---------------------------------------------------------------
+//
+// ToStr (char)
+//
+//---------------------------------------------------------------
+std::wstring ToStr(char value)
+{
+	wchar_t str[32];							
+	::swprintf(str, L"%c", value);
+	
+	return str;
+}
+
+
+//---------------------------------------------------------------
+//
+// ToStr (int16, int32)
+//
+//---------------------------------------------------------------
+std::wstring ToStr(int16_t value, int32_t fieldWidth)
+{
+	wchar_t str[32];							
+	::swprintf(str, L"%*d", fieldWidth, value);
+	
+	return str;
+}
+
+
+//---------------------------------------------------------------
+//
+// ToStr (uint16, int32)
+//
+//---------------------------------------------------------------
+std::wstring ToStr(uint16_t value, int32_t fieldWidth)
+{
+	wchar_t str[32];							
+	::swprintf(str, L"%*d", fieldWidth, value);
+	
+	return str;
+}
+
+
+//---------------------------------------------------------------
+//
+// ToStr (int32, int32)
+//
+//---------------------------------------------------------------
+std::wstring ToStr(int32_t value, int32_t fieldWidth)
+{
+	wchar_t str[32];							
+	::swprintf(str, L"%*ld", fieldWidth, value);
+	
+	return str;
+}
+
+
+//---------------------------------------------------------------
+//
+// ToStr (uint32, int32)
+//
+//---------------------------------------------------------------
+std::wstring ToStr(uint32_t value, int32_t fieldWidth)
+{
+	wchar_t str[32];							
+	::swprintf(str, L"%*lu", fieldWidth, value);
+	
+	return str;
+}
+
+
+//---------------------------------------------------------------
+//
+// ToStr (float, int32)
+//
+//---------------------------------------------------------------
+std::wstring ToStr(float value, int32_t precision)
+{
+	wchar_t str[32];							
+	::swprintf(str, L"%.*f", precision, value);
+	
+	return str;
+}
+
+
+//---------------------------------------------------------------
+//
+// ToStr (double, int32)
+//
+//---------------------------------------------------------------
+std::wstring ToStr(double_t value, int32_t precision)
+{
+	wchar_t str[32];							
+	::swprintf(str, L"%.*f", precision, value);
+	
+	return str;
+}
+
+
+//---------------------------------------------------------------
+//
+// ToStr (const char*)
+//
+//---------------------------------------------------------------
+std::wstring ToStr(const char* value)
+{
+	wchar_t str[2048];							
+	::swprintf(str, L"%s", value);
+	
+	return str;
+}
+
+
+//---------------------------------------------------------------
+//
+// ToStr (std::string)
+//
+//---------------------------------------------------------------
+std::wstring ToStr(const std::string& value)
+{
+	wchar_t str[2048];							
+	::swprintf(str, L"%s", value.c_str());
+	
+	return str;
+}
+
Index: /gsdl/stable/build-src/packages/isis-gdl/Debug.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/Debug.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/Debug.h	(revision 20131)
@@ -0,0 +1,161 @@
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+//	Abstract:	This file provides the following macros:
+//
+//				ASSERT(p) - If p is false and DEBUG is true drops into the 
+//				debugger, if ASSERTS_THROW is true throws a XAssertException exception.
+//
+//				VERIFY(p) - Like ASSERT except that p is evaluated in release builds.
+//
+//				REQUIRE(p) - Like VERIFY except that it exits the app if the test fails
+//				(this is needed because the boot strap code can't safely throw).
+//
+//				COMPILE_CHECK(p) - An ASSERT that fires at compile time. This is useful
+//				for doing things like verifying the layout of items within a struct.
+//				Note that this check is also done in release builds.
+//
+//				DEBUGSTR(formatStr, n1, n2, ...) - Drops into the debugger and
+//				displays a string.
+//
+//				TRACE(formatStr, n1, n2, ...) - Writes a string to a debug window
+//				without suspending the program.
+//
+//				TRACEFLOW(category, formatStr, n1, n2, ...) - Like TRACE, but with 
+//				the addition of a category string. The category string allows users 
+//				to turn off entire categories of messages. Note that DEBUGSTR, TRACE, 
+//				and TRACEFLOW may be used with boolean expressions by tacking an _IF 
+//				on the end (eg DEBUGSTR_IF(x < 0, "Sqrt was passed a negative argument.")).
+//
+//				PRECONDITION(p)  - Used in conjunction with POSTCONDITION to verify 
+//				the integrity of an object: each public method should include one call to 
+//				PRECONDITION and another to POSTCONDITION. The idea here is to check to 
+//				see if the object stays in a valid state given valid arguments. Note that 
+//				these macros call a method named Invariant. This method should use ASSERT's 
+//				to check to see if the object is in a sane state. See ZInvariant.h for
+//				more details.
+//
+//				CHECK_INVARIANT() - Calls the Invariant. This is useful in ctors because
+//				PRECONDITION doesn't call the dtor (PRECONDITION constructs an object on
+//				the stack which calls the Invariant when the function exits).
+
+#pragma once      // Open only once per build
+
+#define RUNTIME_EXPORT 
+
+RUNTIME_EXPORT std::wstring ToStr(bool value);				// I originally used iostreams, but that caused a ridiculous amount of bloat in object files (but much less so in the exe)
+RUNTIME_EXPORT std::wstring ToStr(char value);
+inline 		   std::wstring ToStr(wchar_t value)						{return std::wstring(1, value);}
+RUNTIME_EXPORT std::wstring ToStr(int16_t value, int32_t fieldWidth = 1);
+RUNTIME_EXPORT std::wstring ToStr(uint16_t value, int32_t fieldWidth = 1);
+RUNTIME_EXPORT std::wstring ToStr(int32_t value, int32_t fieldWidth = 1);
+RUNTIME_EXPORT std::wstring ToStr(uint32_t value, int32_t fieldWidth = 1);
+RUNTIME_EXPORT std::wstring ToStr(float value, int32_t precision = 6);
+RUNTIME_EXPORT std::wstring ToStr(double_t value, int32_t precision = 6);
+RUNTIME_EXPORT std::wstring ToStr(const char* value);
+inline 		   std::wstring ToStr(const wchar_t* value)					{return value;}
+RUNTIME_EXPORT std::wstring ToStr(const std::string& value);
+inline 		   std::wstring ToStr(const std::wstring& value)			{return value;}
+
+
+#ifdef _DEBUG
+	#define	DEBUG					1
+#else		
+	#define	DEBUG					0
+	
+	#if	!defined(NDEBUG)
+		#define	NDEBUG							// used by <assert.h>
+	#endif
+#endif
+
+#ifndef ASSERTS_THROW
+#define ASSERTS_THROW				0			
+#endif
+// #define ASSERTS_THROW               1
+// Synch with ANSI definitions.
+#if DEBUG && defined(NDEBUG)
+	#error DEBUG and NDEBUG are out of sync!
+#endif
+
+#if !DEBUG && !defined(NDEBUG)
+	#error DEBUG and NDEBUG are out of sync!
+#endif
+
+// Synch with MSVC.
+#if _MSC_VER && DEBUG != defined(_DEBUG)
+	#error DEBUG and _DEBUG are out of sync!
+#endif
+
+#ifndef _lint
+	#define COMPILE_CHECK(p)	{struct _CC {char a[(p) ? 1 : -1];};} (void) 0
+#else
+	#define COMPILE_CHECK(p)					
+#endif
+
+#if DEBUG
+	
+	void AssertFailed(const char* expr, const char* file, int line);
+	
+	#undef assert
+
+	#define ASSERT(p)					do {if (!(p)) AssertFailed(#p, __FILE__, __LINE__);} while (false)
+
+	#define ASSERT_IF(p, x)				do {if ((p) && !(x)) AssertFailed(#x, __FILE__, __LINE__);} while (false)
+	#define assert(p) 					ASSERT(p)
+	#define VERIFY(p)					ASSERT(p)
+	#define REQUIRE(p)					ASSERT(p)
+
+	#define	PRECONDITION(p)				ASSERT(p)
+	#define	POSTCONDITION(p)			ASSERT(p)
+
+    #ifdef NO_NESTED_QUOTES
+          #define PRECONDITION2(a,b)	ASSERT(a)
+          #define POSTCONDITION2(a,b)	ASSERT(a)
+    #else
+          #define PRECONDITION2(a,b)	ASSERT((b, (a) !=0))
+          #define POSTCONDITION2(a,b)	ASSERT((b, (a) !=0))
+    #endif
+
+#else	// #if DEBUG
+
+
+	#if ASSERTS_THROW
+		void AssertFailed(const char*, const char*, int);
+
+		#define ASSERT(p)				do {if (!(p)) AssertFailed(#p, __FILE__, __LINE__);} while (false)
+
+		#define ASSERT_IF(p, x)			do {if ((p) && !(x)) AssertFailed(#x, __FILE__, __LINE__);} while (false)
+		#define VERIFY(p)				ASSERT(p)
+
+		#define	PRECONDITION(p)			ASSERT(p)
+		#define	POSTCONDITION(p)		ASSERT(p)
+
+        #define PRECONDITION2(a,b)	    ASSERT(a)
+        #define POSTCONDITION2(a,b)	    ASSERT(a)
+	#else
+		#define	ASSERT(p)				((void) 0)
+
+		#define	ASSERT_IF(p, x)			((void) 0)
+		#define VERIFY(p)				do {if (p) 0;} while (false)
+
+		#define	PRECONDITION(p)			((void) 0)
+		#define	POSTCONDITION(p)		((void) 0)
+
+        #define PRECONDITION2(a,b)
+        #define POSTCONDITION2(a,b)
+	#endif
+
+	void RequireFailed(const char*, const char*, int);
+	
+	#define REQUIRE(p)					do {if (!(p)) RequireFailed(#p, __FILE__, __LINE__);} while (false)
+
+
+#endif	// DEBUG
+
+#ifdef _CONSOLE
+#define TRACE
+#endif
+	
+
+
+#endif /* __DEBUG_H__ */
Index: /gsdl/stable/build-src/packages/isis-gdl/Fdt.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/Fdt.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/Fdt.cpp	(revision 20131)
@@ -0,0 +1,536 @@
+/**********************************************************************
+ *
+ * Fdt.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+//  fdt.cpp
+
+#include "stdafx.h"
+#include "Fdt.h"
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <sstream>
+#include <stdio.h>
+
+//////////////////////////////
+ 
+CFdt::CFdt()   
+// Constructor
+{
+   InitData();
+   InitFields();
+}
+
+//////////////////////////////
+
+CFdt::~CFdt()
+{
+	for (int i = 0; i < m_nFieldCount; i++)
+	{
+#ifndef _WIN32
+		CFieldDef* p = (CFieldDef*) m_fieldArray[i];
+#else
+		CFieldDef* p = (CFieldDef*) m_fieldArray.at(i);
+#endif
+    	delete p;
+	}
+	m_fieldArray.clear();
+
+	Close();
+}
+
+////////////////////////////
+
+bool CFdt::Open(const _TCHAR *szFileName, bool readOnly)
+{
+	if (!m_bIsEmpty)
+		Close();
+	m_sFileName = szFileName;
+	if (!Load(szFileName))
+	{
+		Close();
+		return false;
+	}
+
+	m_bReadOnly = readOnly;
+	return Seek(0);   // 
+}
+
+
+
+
+//////////////////////////////
+
+void CFdt::InitData()
+{
+   m_iCurrentRecord = -1;
+   m_sFileName.erase();
+   
+   m_bReadOnly = false;
+   m_bIsEmpty  = true;
+   m_fdtEntry.Clear();
+   m_bDirty    = false;
+   m_aFdt.clear();
+   m_asPrelude.clear();
+   // Suppose the fdt is empty and we are 
+   // going to append 
+   m_bAppend = true;
+}
+
+//////////////////////////////
+
+void CFdt::Close()
+{
+	if (!m_bIsEmpty)
+		DeleteContents();
+
+    InitData();        // Reset data members   
+	m_bIsEmpty = true;
+}
+
+////////////////////////////////////
+ 
+void CFdt::DeleteContents()
+// Delete the fdt data structures
+{
+    m_aFdt.clear();
+  
+}
+
+
+
+bool CFdt::Load(const _TCHAR *dbaseName)
+{
+	std::ifstream in((const char*)dbaseName);
+	if (!in)
+    {
+//#ifdef _WIN32
+//	   CString strMsg;
+//		strMsg.Format(_T("Error opening %s for reading. "), dbaseName);
+//		AfxMessageBox(strMsg, MB_OK | MB_ICONEXCLAMATION);
+//#else
+		std::cout << _T("Error opening") << dbaseName << _T("for reading") << std::endl;
+//#endif
+		return false;
+    }
+
+
+	std::string s;
+
+    while (std::getline(in,s) && s.substr(0,3) != "***")
+    {
+		m_asPrelude.push_back(s);
+    }
+
+    while (std::getline(in,s))
+    {
+        CFdtEntry e;
+        strncpy(e.name, s.c_str(), FDT_NAME_LENG);
+	    e.name[FDT_NAME_LENG] = _T('\0');
+	    for (int i=FDT_NAME_LENG-1; e.name[i]==_T(' '); e.name[i--]=_T('\0'))
+		   ;
+        if (s[FDT_NAME_LENG] == _T(' '))        //no subfield delimiters spec.
+		 	e.subfields[0] = _T('\0');
+	    else
+		{
+		 	strncpy(e.subfields, s.c_str()+FDT_NAME_LENG, FDT_SFLD_LENG);
+			e.subfields[FDT_SFLD_LENG] = _T('\0');
+			for (int i= FDT_SFLD_LENG-1; e.subfields[i]==_T(' '); e.subfields[i--]='\0')
+				 ;
+		}
+	    sscanf(s.c_str() + FDT_NAME_LENG + FDT_SFLD_LENG, "%d %d %d %d",
+										  &e.tag, &e.len, &e.type, &e.rep);
+	    m_aFdt.push_back(e);
+    }
+    in.close();
+    return true;
+}
+
+		
+		
+		
+
+
+// Define the fields used for the dictionary
+
+static CFieldDef fdtFields[7] =  { 
+   {"Name",       'C', 30, 30, 0, 0, 30},
+   {"Subfields",  'C', 20, 20, 0, 30, 20},
+   {"Tag",        'N', 4, 4, 0,50, 4},
+   {"Len",        'N', 4, 4, 0,54, 4},
+   {"Type",       'N', 1, 1, 0,58, 4},
+   {"Rep",        'C', 1, 1, 0,62, 4},
+   {0,             0, 0, 0, 0, 0, 0}
+}; 
+
+
+
+
+
+
+//+----------------------------------------------------------------
+//
+// Member:     Store(const char* fileName)
+//
+// Synopsis:   Store dictionary tables on a file
+//
+// Parameters: 
+//
+//     fileName -- Full path of dictionary file
+// 
+//-----------------------------------------------------------------   
+
+void FormatFdtEntry(CFdtEntry &e, ustring &s)
+{
+#ifdef _WIN32
+	ustringstream ost;
+
+	ost.setf(std::ios_base::left, std::ios_base::adjustfield);
+	ost << std::setw(30) << e.name << std::setw(20) << e.subfields;
+	ost.setf(std::ios_base::internal,std::ios_base::adjustfield);
+	ost << " " << e.tag << " " << e.len << " " << e.type << " " << e.rep;
+	s = ost.str();
+#endif
+}
+
+void CFdt::Store(const char* fileName)
+{
+	if (m_bDirty)
+	{
+		Flush();
+		m_bDirty = false;
+	}
+
+	std::ofstream out((const char *) fileName);
+	TRACE(_T("\n<CFdt::Store> fileName=%s"),fileName);
+	for (int i=0; i<m_asPrelude.size(); i++)
+		out << m_asPrelude[i] << std::endl;
+	
+	out << "***" << std::endl;
+
+	ustring s;
+#ifdef _WIN32
+	for (i=0; i< m_aFdt.size(); i++)
+#else
+	for (int i=0; i< m_aFdt.size(); i++)
+#endif
+	{
+		FormatFdtEntry(m_aFdt[i], s);
+		out << s << std::endl;
+	}
+    out.close();
+
+}
+
+//////////////////////////////
+
+int CFdt::InitFields ()
+{
+	m_nFieldCount = 0;
+
+	for (int i = 0; fdtFields[i].width != 0; i++)
+	{
+		CFieldDef* fld = (CFieldDef*) new CFieldDef();
+		//TRACE("\n<CFdt::InitFields>i=%d after new",i);
+		//TRACE("<CFdt::InitFields>After SetAtGrow");
+		strcpy(fld->name, fdtFields[i].name);
+		fld->type          = fdtFields[i].type;
+		fld->len           = fdtFields[i].len;
+		fld->width         = fdtFields[i].width;
+		fld->decimals      = fdtFields[i].decimals;
+		fld->offset        = fdtFields[i].offset;
+		fld->display_width = fdtFields[i].display_width;
+
+		int l = strlen(fld->name);
+		if (fld->width < l)
+			fld->width = static_cast<short>(l);
+
+		m_fieldArray.push_back(fld);
+		m_nFieldCount++;
+	}
+	//TRACE("\n<CFdt::InitFields>InitField After loop");
+	return 1;
+}
+
+////////////////////////////////////////////////////////////////////
+
+CFieldDef* CFdt::GetField(int n) const
+// Returns field info
+{
+	ASSERT(n >= 0 && n <= m_nFieldCount);
+#ifndef _WIN32
+	return (CFieldDef*) m_fieldArray[n];
+#else
+	return (CFieldDef*) m_fieldArray.at(n);
+#endif
+}
+
+/////////////////////////////////////////////////////////////////////
+// Methods for accessing and maintaining the list of CDictTRecords 
+// pointers
+
+////////////////////////////
+// First the List Accessors
+////////////////////////////
+
+CFdtEntry CFdt::GetAt(int i)
+{
+#ifndef _WIN32
+	return m_aFdt[i];
+#else
+	return m_aFdt.at(i);
+#endif
+
+}
+
+
+//////////////////////////
+
+const CFdtEntry CFdt::GetAt(int i) const
+{
+#ifndef _WIN32
+	return m_aFdt[i];
+#else
+	return m_aFdt.at(i);
+#endif
+}
+
+//////////////////////////
+// And now the modifiers
+//////////////////////////
+
+int CFdt::Append(CFdtEntry& e)
+{
+	int n = m_aFdt.size();
+	m_aFdt.push_back(e);
+    m_iCurrentRecord = -1;
+    m_bIsEmpty = false;
+
+    return m_aFdt.size();
+}
+
+
+/**-------------------------------------------------------------------
+ * RemoveAt(int i)
+ *
+ *--------------------------------------------------------------------
+ */
+void CFdt::RemoveAt(int i)
+{
+
+	m_aFdt.erase(m_aFdt.begin()+i);
+    m_iCurrentRecord = -1;
+}
+
+/**-------------------------------------------------------------------
+ * SetAt(int i, CFdtEntry& e)
+ *
+ *--------------------------------------------------------------------
+ */
+void CFdt::SetAt(int i, CFdtEntry& e)
+{
+
+	m_aFdt[i] = e;
+	// Force reloading
+    m_iCurrentRecord = -1;
+}
+
+/////////////////////////////////////////////////////////////////
+// 
+// We use a buffer "m_fdtEntry" to hold the content of the current
+// fdt entry. This buffer is filled by the "Seek" member function
+// as follow:
+//
+
+//////////////////////////////
+
+bool CFdt::Seek(long iRecord)
+{
+
+	// move to new record and flush changes of previous record
+	if (iRecord < 0 || iRecord > GetRecordCount())
+		return false;
+	else if (iRecord == m_iCurrentRecord)
+		return true;
+
+	if (m_iCurrentRecord != -1 &&  m_bDirty)
+		Flush();
+	if (m_bDirty)
+	   /*AfxMessageBox(_T("Seek Alert Modification not saved"))*/;
+	m_iCurrentRecord = iRecord;
+	
+	if (iRecord == GetRecordCount())
+	{
+		m_fdtEntry.Clear();
+        m_bAppend = true;
+	}
+	else
+	{
+		TRACE(_T("\n<CFdt::Seek> Load iRecord=%d GetRecordCount()=%d"), iRecord, GetRecordCount());
+		m_fdtEntry = GetAt(iRecord);
+		m_bAppend = false;
+	}
+    m_bDirty = false;
+	return true;
+}
+
+
+
+//+------------------------------------------------------------------
+//
+// Member:   Flush()
+//
+// Synopsis: Moves the changes made to the current record from
+//           the buffer to the dictionary data structure so that
+//           they are effective.
+//-------------------------------------------------------------------    
+
+void CFdt::Flush()
+{
+	if (m_iCurrentRecord == GetRecordCount())
+	{
+		Append(m_fdtEntry); 
+	}
+	else
+	{
+		SetAt(m_iCurrentRecord, m_fdtEntry);
+	}
+	m_bDirty = false;
+}
+
+//////////////////////////////////////////////////////////////
+// Get the value of field n for the current record
+//
+
+bool CFdt::GetValue(int n, std::string& result) 
+// Read value from buffer
+{
+	ASSERT(n >= 0 && n <= m_nFieldCount);
+    ASSERT(m_iCurrentRecord >= 0 && m_iCurrentRecord <= GetRecordCount());
+	
+	if (!(n >= 0 && n <= m_nFieldCount))
+		return false;
+
+	result.erase();
+
+	std::ostringstream os;
+    switch (n)
+	{
+	    case 0:       // Field Name
+			os << m_fdtEntry.name;
+			result = os.str();
+		    break;
+	    case 1:       // Subfields
+			os << m_fdtEntry.subfields;
+			result = os.str();
+		    break;
+	    case 2:       // Tag
+		  	if (m_fdtEntry.tag == 0)
+				result = "";
+			else
+			{
+			    os << m_fdtEntry.tag;
+			    result = os.str();
+			}
+		    break;
+	    case 3:       // length
+		  	if (m_fdtEntry.len == 0)
+				result = "";
+			else
+			{
+			    os << m_fdtEntry.len;
+			    result = os.str();
+			}
+		    break;
+	    case 4:       // type
+		  	if (m_fdtEntry.type == 0)
+				result = "";
+			else
+			{
+			    os << m_fdtEntry.type;
+			    result = os.str();
+			}
+		    break;
+	    case 5:       // Rep
+		  	if (m_fdtEntry.rep == 0)
+				result = "";
+			else
+			{
+			    os << m_fdtEntry.rep;
+			    result = os.str();
+			}
+		    break;
+	}
+	return true;
+}
+
+
+//////////////////////////////
+
+bool CFdt::SetValue(int n, const char* pszValue)
+// Write value to buffer
+{
+	ASSERT(n >= 0 && n <= m_nFieldCount);
+    ASSERT(m_iCurrentRecord >= 0 && m_iCurrentRecord <= GetRecordCount());
+
+	if (m_bReadOnly)
+		return false;
+
+	if (!(n >= 0 && n <= m_nFieldCount))
+		return false;
+
+    bool bEmpty = true;
+
+
+	switch (n) 
+	{
+	case 0:       // Name
+		strcpy(m_fdtEntry.name,(const char*)pszValue);
+	//	TRACE("\nvalue=%s num=%d",pszValue,m_tRecord.num);
+		break;
+	case 1:       // Subfields
+		strcpy(m_fdtEntry.subfields,(const char*)pszValue);
+	//	TRACE("\nvalue=%s name=%d",pszValue,m_tRecord.name);
+		break;
+	case 2:       // Tag
+		m_fdtEntry.tag = _ttoi(pszValue);
+	//	TRACE("\nvalue=%s loc=%d",pszValue,m_tRecord.loc);
+		break;
+	case 3:       // Len
+		m_fdtEntry.len = _ttoi(pszValue);
+	//	TRACE("\nvalue=%s wid=%d",pszValue,m_tRecord.wid);
+		break;
+	case 4:       // Type
+		m_fdtEntry.type = _ttoi(pszValue);
+		break;
+	case 5:       // Rep
+		m_fdtEntry.type = _ttoi(pszValue);
+		break;
+	}
+	m_bDirty = true;
+	
+	return true;
+}
+
Index: /gsdl/stable/build-src/packages/isis-gdl/Fdt.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/Fdt.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/Fdt.h	(revision 20131)
@@ -0,0 +1,172 @@
+/**********************************************************************
+ *
+ * Fdt.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////
+// Fdt.h
+
+#ifndef __FDT_H__
+#define __FDT_H__
+
+#include <vector>
+#include "mytchar.h"
+
+#define FDT_NAME_LENG    30     // maximum name length in FDT_FILE
+#define FDT_SFLD_LENG    20    // maximum subfield length in FDT_FILE
+
+#ifndef __CFIELDDEF__
+#define __CFIELDDEF__
+
+class CFieldDef
+{
+public:
+	enum FieldType {
+		charField       = 'C',
+		dateField       = 'D',
+		numericField    = 'N',
+		logicalField    = 'L',
+		memoField       = 'M'
+	};
+
+	char  name[31];   // dbf field names are 10 chars long max.
+		// If this application is compiled with _UNICODE switch,
+		// the field name will be converted to wide chars
+		// when the column header is displayed in the grid.
+	char  type;
+	short len;
+	short width;
+	short decimals;
+	int   offset;
+	short display_width;
+};
+#endif // __CFIELDDEF__
+
+
+
+class CFdtEntry
+{
+public:
+	CFdtEntry() :  tag(0), len(0), type(0), rep(0) 
+	{ name[0] = '\0'; subfields[0] = '\0'; }
+    void Clear()
+	{
+		tag = len = type = rep = 0;
+        name[0] = '\0'; subfields[0] = '\0';
+	}
+    char    name[FDT_NAME_LENG+1];
+    char    subfields[FDT_SFLD_LENG+1];
+    int      tag;
+    int      len;
+    int      type;     //X=0
+    int      rep;      //repeatable 1, non rep. 0
+   CFdtEntry& operator=(const CFdtEntry& rhs)
+   {
+	   if (&name[0] != &rhs.name[0])
+	   {
+		   Copy(rhs);
+	   }
+	   return *this;
+   }
+
+   void Copy(const CFdtEntry &rhs)
+   {
+	   strcpy(name, rhs.name);
+	   strcpy(subfields, rhs.subfields);
+	   tag  = rhs.tag;
+	   len  = rhs.len;
+	   type = rhs.type;
+	   rep  = rhs.rep;
+   }
+};
+
+
+void FormatFdtEntry(CFdtEntry &e, ustring &s);
+
+
+
+class CFdt
+{
+protected:
+	std::vector<CFdtEntry>  m_aFdt;
+    int                     m_nFieldCount;       // Num. of fields
+	std::vector<CFieldDef*> m_fieldArray;        // Array with fields
+
+	long        m_iCurrentRecord;    // Current read record stored in
+	CFdtEntry   m_fdtEntry;
+	bool        m_bReadOnly;
+	bool        m_bIsEmpty;
+	bool        m_bDirty;            // True if m_fdtEntry modified 
+	bool        m_bAppend;
+public:
+	ustring  m_sFileName;              // Fdt full pathname
+	std::vector<std::string> m_asPrelude;  // What is bef ***
+public:
+	CFdt();          
+	virtual ~CFdt();
+
+	bool      Load(const _TCHAR *fname);
+	int       GetEntryCount() { return m_aFdt.size(); }
+
+	CFdtEntry GetEntryAt(int i) 
+	{ 
+      #ifdef _WIN32
+	     return m_aFdt.at(i); 
+      #else
+	     return m_aFdt[i];
+      #endif
+	}
+
+	int       GetFieldCount() { return  m_nFieldCount; }
+
+    bool      Open(const char* szFileName, bool readOnly=true);
+
+    void InitData();
+
+    void Close();
+ 
+    void DeleteContents();
+
+    void Store(const char* fileName);
+    int InitFields ();
+
+    CFieldDef* GetField(int n) const;
+
+    CFdtEntry GetAt(int i);
+
+    const CFdtEntry GetAt(int i) const;
+
+    int Append(CFdtEntry& e);
+
+    void RemoveAt(int i);
+    void SetAt(int i, CFdtEntry& e);
+
+    bool Seek(long iRecord);
+    void Flush();
+    bool GetValue(int n, std::string& result);
+    bool SetValue(int n, const char* pszValue);
+
+	int GetRecordCount() { return m_aFdt.size(); }
+};
+
+#endif
Index: /gsdl/stable/build-src/packages/isis-gdl/File.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/File.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/File.cpp	(revision 20131)
@@ -0,0 +1,618 @@
+/**********************************************************************
+ *
+ * File.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////
+// File.cpp   File object methods
+////////////////////////////////////////////////////////////
+#include "stdafx.h"
+
+ 
+#include <assert.h>
+#include "CRC32.h"
+#include "File.h"
+
+
+
+
+static TCHAR closed_file_name[] = _T("closed-file");
+
+static const int MaxExceptionMessages = 34;
+static const TCHAR *fileExceptionMsg[MaxExceptionMessages] =
+{
+  _T("File exception: No exception reported"),               // FILE_NO_ERROR
+  _T("File exception: Checksum error"),                      // FILE_CHECKSUM_ERROR
+  _T("File exception: Error closing file"),                  // FILE_CLOSE_ERROR
+  _T("File exception: File is corrupted"),
+  _T("File exception: Error creating file"),                 // FILE_CREATION_ERROR
+  _T("File exception: File already exists"),                 // FILE_EXISTS
+  _T("File exception: Trying to use a closed file"),         // FILE_NOT_OPEN_ERROR
+  _T("File exception: File not ready for reading/writing"),  // FILE_NOT_READY
+  _T("File exception: Could not write to file"),             // FILE_NOT_WRITEABLE
+  _T("File exception: Error opening file"),                  // FILE_OPEN_ERROR
+  _T("File exception: Cannot obtain a file position"),       // FILE_POSITION_ERROR
+  _T("File exception: Error reading from file"),             // FILE_READ_ERROR
+  _T("File exception: Error seeking in file"),               // FILE_SEEK_ERROR
+  _T("File exception: Error writing to file"),               // FILE_WRITE_ERROR
+
+  _T("Fmgr exception: No database open"),                    // FMGR_NO_DATABASE_OPEN
+  _T("Fmgr exception: No such file exists"),                 // FMGR_NO_FILE_EXISTS
+  _T("Fmgr exception: No objects exist"),                    // FMGR_NO_OBJECTS_EXIST
+  _T("Fmgr exception: Accessing a null pointer"),            // FMGR_NULL_PTR
+  _T("Fmgr exception: Object already exists"),               // FMGR_OBJECT_EXISTS
+  _T("Fmgr exception: Another object is referencing this file"), // FMGR_OBJECT_EXISTS
+  _T("Fmgr exception: Math overflow error"),                 // FMGR_OVERFLOW
+  _T("Fmgr exception: Parse error"),                         // FMGR_PARSE_ERROR
+  _T("Fmgr exception: Invalid path"),                        // FMGR_PATH_ERROR
+  _T("Fmgr exception: Trying to write to a read-only file"), // FMGR_READ_ONLY_FILE
+  _T("Fmgr exception: Stack empty"),                         // FMGR_STACK_EMPTY
+  _T("Fmgr exception: Stack full"),                          // FMGR_STACK_FULL
+  _T("Fmgr exception: Synchronization Error"),               // FMGR_SYNC_ERROR    
+  _T("Fmgr exception: Math under-flow error"),               // FMGR_UNDERFLOW
+  _T("Fmgr exception: Wrong file type"),                     // FMGR_WRONG_FILE_TYPE
+  
+  // Persistent lock error messages
+  _T("Fmgr exception: Invalid lock type specified"),          // FMGR_INVALID_LOCK_TYPE
+  _T("Fmgr exception: Cannot access the file lock header"),   // FMGR_FILELOCK_ACCESS_ERROR
+  _T("Fmgr exception: Cannot lock the file"),                 // FMGR_FILELOCK_ERROR
+  _T("Fmgr exception: Cannot access the record lock header"), // FMGR_RECORDLOCK_ACCESS_ERROR
+  _T("Fmgr exception: Cannot lock the specified record")      // FMGR_RECORDLOCK_ERROR
+};
+ 
+//---------------------------------------------------------------------------
+// CFileBase::CFileBase()
+//
+// Default constructor, makes a File object that isn't attached to a file
+//--------------------------------------------------------------------------- 
+CFileBase::CFileBase()
+{
+    _tcscpy(file_name, closed_file_name); // Set the initial file name
+    fp = 0;
+
+    // Reset the last reported error and the file status members
+    file_error        = FILE_NO_ERROR;
+    is_open           = 0;
+    is_ok             = 0;
+    ready_for_reading = 0;
+    ready_for_writing = 0;
+}
+  
+//---------------------------------------------------------------------------
+// CFileBase::~CFileBase()
+//
+// Destructor for CFileBase file object
+//--------------------------------------------------------------------------- 
+CFileBase::~CFileBase()
+{
+	Close();
+}
+
+//---------------------------------------------------------------------------
+// const char* CFileBase::FileExceptionMessage()
+//
+// Returns a null terminated string that can / be used to log or print a
+// file exception.
+//---------------------------------------------------------------------------
+const TCHAR *CFileBase::FileExceptionMessage()
+{
+	assert(file_error<MaxExceptionMessages);
+    return fileExceptionMsg[file_error];
+}
+ 
+//--------------------------------------------------------------------------------
+// int Create(const char* fname)
+//
+// Creates a new file, truncate the file if it already exists. The file open for
+// Read/Write access. 
+// Returns a non-zero value to indicate an error condition or zero if successful.
+//--------------------------------------------------------------------------------
+FileError CFileBase::Create(const TCHAR *fname)
+{
+    // Close any open files 
+    if (Close() != FILE_NO_ERROR) 
+		return file_error;
+	
+    // Create and truncate existing files
+    fp = FileSystem::Create(fname);
+	
+    if (fp == 0)
+	{
+		is_ok             = 0;
+		is_open           = 0;
+		ready_for_writing = 0;
+		ready_for_reading = 0;
+		file_error        = FILE_CREATION_ERROR;
+#ifdef __CPP_EXCEPTIONS__
+		throw CFileBaseException(file_error);
+#else
+		return file_error;
+#endif
+	}
+	else
+	{
+		is_open           = 1;
+		is_ok             = 1;
+		ready_for_writing = 1;
+		ready_for_reading = 1;
+		last_operation    = IO_READ;
+		_tcscpy(file_name, fname);
+	}
+	
+	// Returns 0 if the file was successfully created and opened.
+	return file_error = FILE_NO_ERROR; 
+}
+ 
+//----------------------------------------------------------------------------------------
+// FileError CFileBase::Open(const TCHAR *fname, FileSystem::AccessMode mode
+//                                               /* = FileSystem::FILE_READWRITE */ )
+//
+// Open an existing file. The "mode" variable determines if the file is opened for
+// read only or read/write access.  Returns a non-zero value to indicate an error
+// condition or zero if successful.
+// NOTE: This version of the open functions will only accept:
+// FILE_READONLY and FILE_READWRITE access modes.
+//---------------------------------------------------------------------------------------
+FileError CFileBase::Open(const TCHAR *fname, FileSystem::AccessMode mode /* = FileSystem::FILE_READWRITE */)
+{
+	// Close any open files
+	if (Close() != FILE_NO_ERROR) 
+		return file_error;
+	
+	if (mode == FileSystem::FILE_READONLY)
+	{   // Open with read only access
+		ready_for_reading = 1;
+		ready_for_writing = 0;
+		fp = FileSystem::Open(fname, FileSystem::FILE_READONLY);
+	}
+	else
+	{   // Open with read/write access
+		ready_for_reading = 1;
+		ready_for_writing = 1;
+		fp = FileSystem::Open(fname, FileSystem::FILE_READWRITE);
+	}
+    
+	if (fp == 0)
+	{
+		ready_for_reading = 0;
+		ready_for_writing = 0;
+		file_error        = FILE_OPEN_ERROR;
+#ifdef __CPP_EXCEPTIONS__
+		throw CFileBaseException(file_error);
+#else
+		return file_error;
+#endif
+	}
+	else
+	{
+		is_open         = 1;
+		is_ok           = 1;
+		last_operation  = IO_WRITE;
+		_tcscpy(file_name, fname);
+	}
+	return file_error = FILE_NO_ERROR;
+}
+ 
+//--------------------------------------------------------------------------------
+// void CFileBase::Close()
+//
+// Close the open database file. Returns a non-zero value
+// to indicate an error condition or zero if successful.
+//--------------------------------------------------------------------------------
+FileError CFileBase::Close()
+{
+   if (IsOpen()) 
+   {
+       if (FileSystem::Close(fp) != 0) 
+	   {
+		   file_error = FILE_CLOSE_ERROR;
+#ifdef __CPP_EXCEPTIONS__
+		   throw CFileBaseException(file_error);
+#else
+		   return file_error;
+#endif
+	   }
+       _tcscpy(file_name, closed_file_name); // Set the initial file name
+   }
+
+   is_open           = 0;
+   is_ok             = 0;
+   ready_for_reading = 0;
+   ready_for_writing = 0;
+   fp                = 0; // Reset the file pointer to zero after the file is closed
+
+   return file_error = FILE_NO_ERROR; 
+}
+
+//----------------------------------------------------------------------------------
+// FileError CFileBase::Seek(FAU offset, FileSystem::SeekMode mode)
+//
+// Seek to the specified offset starting at the beginning (SEEK_SET), end (SEEK_END)
+// or current offset (SEEK_CUR). Returns a non-zero value to indicate an error
+// condition or zero if successful.
+//----------------------------------------------------------------------------------
+FileError CFileBase::Seek(FileSystem::FAU_t offset, FileSystem::SeekMode mode)
+{
+	if (IsOK()) 
+	{
+		if (FileSystem::Seek(fp, offset, mode) == (isis::int32_t) - 1)
+		{
+			file_error = FILE_SEEK_ERROR;
+#ifdef __CPP_EXCEPTIONS__
+			throw CFileBaseException(file_error);
+#else
+			return file_error;
+#endif
+		}
+		last_operation = IO_SEEK;
+	}
+	else 
+	{
+		file_error = FILE_NOT_READY;
+#ifdef __CPP_EXCEPTIONS__
+		throw CFileBaseException(file_error);
+#else
+		return file_error;
+#endif
+	}
+	return file_error = FILE_NO_ERROR;
+}
+
+//----------------------------------------------------------------------------------
+// FAU CFileBase::SeekTo(FileSystem::FAU_t file_address)
+//
+// Seek to the specified address, optimizing the seek operation by moving the 
+// file position indicator based on the current stream position. Returns the
+// current file position after performing the seek operation.
+//----------------------------------------------------------------------------------
+FileSystem::FAU_t CFileBase::SeekTo(FileSystem::FAU_t file_address)
+{
+	// Get the current stream position
+	FileSystem::StreamPos pos = FilePosition();
+	
+	if (file_address == CURRADDR) 
+	{   // Do not perform a seek operation
+		return pos;
+	}
+	else if (file_address > pos)
+	{   // Seek forward to the specified address
+		FileSystem::StreamPos offset = file_address - pos;
+		Seek(offset, FileSystem::FILE_SEEK_CUR);
+	}
+	else if (file_address < pos) 
+	{   // Seek backward to the specified address
+		Seek(file_address, FileSystem::FILE_SEEK_BEG);
+	}
+	else 
+	{  // Current file position equals the specified address
+		// Find current the position
+		Seek((FileSystem::FAU_t)0, FileSystem::FILE_SEEK_CUR);
+	}
+	
+	return FilePosition(); // Return current file position after seeking
+}
+
+//-------------------------------------------------------------------------------
+// FileError Store(const void* buf, isis::uint32_t nBytes,
+//                             FAU file_addres = CFileBase::CURRADDR,
+//			                   int flush = 1, int bit_test = 1);
+//
+// Write a specific number of bytes from a memory buffer to a specified file
+// offset. If the "flush" variable is true, the file buffers will be flushed to
+// disk with each write operation. If the bit_test variable if true, the CRC of 
+// the buffer will be compared to the CRC of the actual bytes written to disk.
+// Returns a non-zero value to indicate an error condition or zero if successful.
+//
+// void* buf         - Pointer to the user-supplied buffer that is to receive
+//                     the data read from the file.
+// isis::uint32_t nBytes - The maximum number of bytes to be read from the 
+//                     file.  Note that an CFileBase is always a binary file,
+//                     so a CR/LF pair will always be read or written as two bytes.
+// FAU file_address  - The file byte address. The address is always interpreted to 
+//                     be from the beginning of the file, unless dwAddr is equal 
+//                     to CURRADDR, which means from the current position.
+//------------------------------------------------------------------------------- 
+FileError CFileBase::Store(const void* buf, isis::uint32_t nBytes,
+						   FileSystem::FAU_t file_address /*= CURRADDR */, 
+						   int flush_flag /* = 1 */,
+						   int bit_test /* = 1 */)
+{
+    FileSystem::FAU_t buf_address;
+	
+    if (ReadyForWriting())
+	{
+        if (file_address == CURRADDR)
+		{
+			if (last_operation == IO_READ)
+			{
+				if (Seek(0, FileSystem::FILE_SEEK_CUR) != FILE_NO_ERROR)
+					return file_error;
+			}
+		}
+        else
+		{
+			if (Seek(file_address, FileSystem::FILE_SEEK_BEG) != FILE_NO_ERROR)
+				return file_error;
+		}
+		
+        buf_address = FilePosition(); 
+		
+        if (file_error != FILE_NO_ERROR)
+			return file_error;
+		
+        if (FileSystem::Write(fp, buf, nBytes) != nBytes)
+		{
+			file_error = FILE_WRITE_ERROR;
+#ifdef __CPP_EXCEPTIONS__
+			throw CFileBaseException(file_error);
+#else
+			return file_error;
+#endif
+		}
+        last_operation = IO_WRITE;
+	}
+    else
+	{
+        file_error = FILE_NOT_WRITEABLE;
+#ifdef __CPP_EXCEPTIONS__
+        throw CFileBaseException(file_error);
+#else
+        return file_error;
+#endif
+	} 
+	
+    // Allow application to flush disk buffers after each write
+    // operation to ensure the file data stays in sync during multiple
+    // file access.
+    if (flush_flag)
+	{  
+		if (FileSystem::Flush(fp) != FILE_NO_ERROR)
+		{
+			file_error = FILE_WRITE_ERROR;
+#ifdef __CPP_EXCEPTIONS__
+			throw CFileBaseException(file_error);
+#else
+			return file_error;
+#endif
+		}
+        if (Seek(0, FileSystem::FILE_SEEK_CUR) != FILE_NO_ERROR)
+			return file_error;
+	}
+	
+    if (bit_test) 
+	{
+        isis::uint32_t w_csum = CalcCRC32((char* ) buf, nBytes);
+        isis::uint32_t r_csum = CalcChecksum(nBytes, buf_address);
+		
+		// Check for file errors
+		
+		if (file_error != FILE_NO_ERROR)
+			return file_error;
+		
+		if (w_csum ^ r_csum)
+		{
+			file_error = FILE_CHECKSUM_ERROR;
+#ifdef __CPP_EXCEPTIONS__
+			throw CFileBaseException(file_error);
+#else
+			return file_error;
+#endif
+		}
+	}
+	return file_error = FILE_NO_ERROR;	
+}
+ 
+//-------------------------------------------------------------------------------
+// FileError CFileBase::Fetch(void* buf, isis::uint32_t nBytes, FAU file_addres
+//                                                  /* = CFileBase::CURRADDR */)
+//
+// Read a specified number of bytes from the specified file offset into a memory
+// buffer. Returns a non-zero value to indicate an error condition or zero if
+// successful.
+// void* buf         - Pointer to the user-supplied buffer that is to receive
+//                     the data read from the file.
+// isis::uint32_t nBytes - The maximum number of bytes to be read from the file. 
+//                     Note that an CFileBase is always a binary file, so a 
+//                     CR/LF pair will always be read or written as two bytes.
+// FAU file_addres   - The file byte address. The address is always interpreted 
+//                     to be from the beginning of the file, unless dwAddr is 
+//                     equal to CURRADDR, which means from the current position.
+//------------------------------------------------------------------------------- 
+FileError CFileBase::Fetch(void* buf, isis::uint32_t nBytes, 
+						   FileSystem::FAU_t file_address /* = CFileBase::CURRADDR */)
+{
+    if (IsOK())
+	{
+        if (file_address == CURRADDR)
+		{
+            if (last_operation == IO_WRITE)
+			{
+	           if (Seek(0, FileSystem::FILE_SEEK_CUR) != FILE_NO_ERROR) 
+				   return file_error;
+			}
+		}
+        else
+		{
+            if (Seek(file_address, FileSystem::FILE_SEEK_BEG) != FILE_NO_ERROR)
+              	return file_error;
+		}
+
+		//TRACE("\nFetchfile_address=%ld nBytes=%u",file_address, nBytes);
+        if (FileSystem::Read(fp, buf, nBytes) != nBytes)
+		{
+            file_error = FILE_READ_ERROR;
+#ifdef __CPP_EXCEPTIONS__
+            throw CFileBaseException(file_error);
+#else
+            return file_error;
+#endif
+		}
+        last_operation = IO_READ;
+	}
+    else 
+	{
+        file_error = FILE_NOT_READY;
+#ifdef __CPP_EXCEPTIONS__
+        throw CFileBaseException(file_error);
+#else
+        return file_error;
+#endif
+	}
+
+    return file_error = FILE_NO_ERROR;
+}
+//------------------------------------------------------------------------------- 
+// FileError Flush()
+//
+// Flush any open disk buffers. Returns a non-zero value to indicate an error
+// condition or zero if successful.
+//------------------------------------------------------------------------------- 
+FileError CFileBase::Flush()
+{
+	PRECONDITION(ReadyForWriting());
+	if (FileSystem::Flush(fp) != FILE_NO_ERROR)
+	{
+		file_error = FILE_WRITE_ERROR;
+#ifdef __CPP_EXCEPTIONS__
+		throw CFileBaseException(file_error);
+#else
+		return file_error;
+#endif
+	}
+	Seek((FileSystem::FAU_t)0, FileSystem::FILE_SEEK_CUR);
+	return file_error = FILE_NO_ERROR;
+}
+
+
+//------------------------------------------------------------------------------- 
+// StreamPos CFileBase::FilePosition()
+//
+// Returns the current file position or -1 to indicate an error condition.
+//------------------------------------------------------------------------------- 
+FileSystem::StreamPos CFileBase::FilePosition()
+{
+   if (!IsOK())
+   {
+      file_error = FILE_NOT_READY;
+#ifdef __CPP_EXCEPTIONS__
+      throw CFileBase();
+#else
+      return (StreamPos) - 1;
+#endif
+   }
+
+   FileSystem::StreamPos pos = FileSystem::Tell(fp);
+   if (pos < 0)
+   {
+      file_error = FILE_POSITION_ERROR;
+#ifdef __CPP_EXCEPTIONS__
+      throw CFileBaseException(file_error);
+#else
+      return (StreamPos) - 1;
+#endif
+   }
+   return pos;
+}
+
+//------------------------------------------------------------------------------- 
+// isis::uint32_t CFileBase::CalcChecksum(isis::uint32_t bytes, FAU file_address, 
+//                                                         int mem_alloc)
+//
+// Calculate a 32-bit CRC checksum for a given number of bytes starting at the
+// specified address. Returns a 32-bit CRC value. If the mem_alloc variable is
+// true, a buffer equal to the specified number of bytes will be created in
+// memory. If the mem_alloc variable is false or memory allocation fails, the CRC
+// will be calculated byte by byte starting at the specified address. 
+// NOTE: the calling function must check for disk file errors.
+// Returns the CRC value.
+//------------------------------------------------------------------------------- 
+
+isis::uint32_t CFileBase::CalcChecksum(isis::uint32_t bytes, FileSystem::FAU_t file_address, int mem_alloc)
+{
+   isis::uint32_t CRC;
+   isis::uint32_t len = bytes;
+   unsigned char data;
+   char *buf = 0;  
+
+   // Create a buffer equal to the object length
+   if (mem_alloc) 
+	   buf = new char[bytes]; 
+
+   if (buf)
+   {
+      if (IsOK())
+	  {
+         if (Fetch(buf, bytes, file_address) != FILE_NO_ERROR) return 0;
+         CRC = CalcCRC32(buf, bytes);
+         delete[] buf;
+	  }
+   }
+   else
+   {
+      if (IsOK())
+	  {
+          // Seek to the specified file address
+          SeekTo(file_address);
+          if (file_error != FILE_NO_ERROR) return 0; 
+          CRC = 0xffffffffL;
+          while (len--)
+		  {
+	         if (Fetch(&data, sizeof(data)) != FILE_NO_ERROR) return 0;
+	         CRC = CalcCRC32(data, CRC);
+		  }
+          CRC ^= 0xffffffffL;
+	  }
+   }
+
+   return CRC; 
+}
+///////////////////////////////////////////////////////////////////////////
+// General purpose file utilites 
+//
+int CFileBase::Exists(const TCHAR *fname)
+// Returns true if the file exists
+{
+	return FileSystem::Exists(fname);
+}
+
+FileSystem::FAU_t CFileBase::FileSize(const TCHAR *fname)
+// Returns the file size. Use after file has been closed
+// and re-opened to ensure that all the buffers are flushed
+// to disk. Returns -1 to indicate an error condition.
+{
+	return (FileSystem::FAU_t) FileSystem::FileSize(fname);
+}
+
+int CFileBase::CanOpenForWriting(const TCHAR *fname)
+// Returns true if the file is opened
+{
+	return 1;
+	//return FileSystem::CanOpenForWriting(fname);
+}
+
+int CFileBase::CanOpenReadOnly(const TCHAR *fname)
+// Returns true if the file is opened
+{
+	return 1;
+	//return FileSystem::CanOpenReadOnly(fname);
+}
Index: /gsdl/stable/build-src/packages/isis-gdl/File.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/File.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/File.h	(revision 20131)
@@ -0,0 +1,188 @@
+/**********************************************************************
+ *
+ * File.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+// File.h -- File Base class
+// 
+//////////////////////////////////////////////////////////////////////////
+ 
+
+ 
+#ifndef __FILE_BASE__
+#define __FILE_BASE__
+
+#include "FileSystem.h"
+# define __CPP_EXCEPTIONS__ 1
+
+// CRC-32 checksum used to detect bit errors
+typedef unsigned long Checksum;
+
+
+// Constants for file operations and stream position 
+const int MaxNameLength             = 512;        // Max length of names buffers
+const FileSystem::FAU_t StartOfFile = (FileSystem::FAU_t)0; // First byte in the file
+const FileSystem::FAU_t CURRADDR    = (FileSystem::FAU_t)-1;// Indicates current location
+const isis::uint32_t CheckWord      = 0xfefefefe;           // Default synchronization word
+const isis::int32_t  FSListCorrupt  = (FileSystem::FAU_t)-1;// Free space list is corrupt
+
+
+//------------------
+// File  error codes
+//------------------
+enum FileError { 
+  FILE_NO_ERROR = 0,   // No errors reported
+  FILE_CHECKSUM_ERROR, // Checksum Error
+  FILE_CLOSE_ERROR,    // Error closing file
+  FILE_CORRUPT,        // File corrupted
+  FILE_CREATION_ERROR, // Error creating file
+  FILE_EXISTS,         // File already exists
+  FILE_NOT_OPEN_ERROR, // Trying to use a closed file
+  FILE_NOT_READY,      // File not ready (failed or closed file)
+  FILE_NOT_WRITEABLE,  // Could not write to file 
+  FILE_OPEN_ERROR,     // Error opening file
+  FILE_POSITION_ERROR, // Cannot obtain the current file position
+  FILE_READ_ERROR,     // Error reading file  
+  FILE_SEEK_ERROR,     // Error seeking in file
+  FILE_WRITE_ERROR,    // Error writing to file
+
+  FMGR_NO_DATABASE_OPEN,    // No database open
+  FMGR_NO_FILE_EXISTS,      // No such file exists
+  FMGR_NO_OBJECTS_EXIST,    // No objects exist
+  FMGR_NULL_PTR,            // Accessing a null pointer 
+  FMGR_OBJECT_EXISTS,       // Object already exists
+  FMGR_OPEN_FILE_REFERENCE, // Another object is referencing this file
+  FMGR_OVERFLOW,            // Math overflow
+  FMGR_PARSE_ERROR,         // Parse error
+  FMGR_PATH_ERROR,          // Invalid path
+  FMGR_READ_ONLY_FILE,      // Trying to write to read-only file
+  FMGR_STACK_EMPTY,         // Stack empty
+  FMGR_STACK_FULL,          // Stack full
+  FMGR_SYNC_ERROR,          // Synchronization Error
+  FMGR_UNDERFLOW,           // Math under-flow
+  FMGR_WRONG_FILE_TYPE,     // Wrong file type
+
+  // Persistent lock error codes
+  FMGR_INVALID_LOCK_TYPE,        // Invalid lock type specified
+  FMGR_FILELOCK_ACCESS_ERROR,    // The file lock cannot be accessed
+  FMGR_FILELOCK_ERROR,           // Error locking the file
+  FMGR_RECORDLOCK_ACCESS_ERROR,  // The record lock cannot be accessed
+  FMGR_RECORDLOCK_ERROR          // Error locking a record};
+
+
+};
+
+
+
+
+class DLL_CODE_API CFileBase 
+{
+protected:
+    // File I/O operation codes
+  enum IO_Op { 
+     IO_READ,         // A read was performed
+     IO_WRITE,        // A write operation was performed
+     IO_REWIND,       // A rewind operation was performed
+     IO_NO_OPERATION, // No operation was performed
+     IO_SEEK          // A seek operation was preformed 
+  };
+
+  _TCHAR            file_name[MaxNameLength];  // Open file name
+  FileSystem::FPTR* fp;                        // Stream file handle
+  IO_Op             last_operation;            // Last I/O operation preformed
+  FileError         file_error;                // Last reported file error
+
+  // File status members
+  int is_ok;             // Used to signal a fatal error condition
+  int is_open;           // True if the file is open
+  int ready_for_reading; // True if the file is ready for reading
+  int ready_for_writing; // True if the file is ready for writing
+
+
+public:
+   CFileBase();
+   virtual ~CFileBase();
+
+public: // File functions
+   virtual FileError Create(const TCHAR *fname);
+   virtual FileError Open(const TCHAR *fname, FileSystem::AccessMode mode = FileSystem::FILE_READWRITE); 
+   virtual FileError Close();
+   
+   FileError         Seek(FileSystem::FAU_t offset, FileSystem::SeekMode mode = FileSystem::FILE_SEEK_BEG);
+ 
+   FileError         Fetch(void* buf, isis::uint32_t nBytes, FileSystem::FAU_t file_addres = CURRADDR);
+   FileError         Store(const void* buf, isis::uint32_t nBytes, FileSystem::FAU_t file_address = CURRADDR,
+			                int flush_flag = 1, int bit_test = 1);
+
+   FileSystem::FAU_t     SeekTo(FileSystem::FAU_t file_address);
+   FileSystem::StreamPos FilePosition();
+
+   FileError Flush();
+
+   _TCHAR *FileName() { return file_name; }
+
+public: // 32-bit CRC checksum routines 
+  isis::uint32_t CalcChecksum(isis::uint32_t bytes, FileSystem::FAU_t file_address, int mem_alloc = 1);
+
+public:  // File Status functions
+  int IsOK()                  { return ((is_ok == 1) && (is_open == 1)); }
+  int IsOK()            const { return ((is_ok == 1) && (is_open == 1)); }
+  int IsOpen()                { return ((is_ok == 1) && (is_open == 1)); }
+  int IsOpen()          const { return ((is_ok == 1) && (is_open == 1)); }
+  int ReadyForReading()       { return ready_for_reading == 1; }
+  int ReadyForReading() const { return ready_for_reading == 1; }
+  int ReadyForWriting()       { return ready_for_writing == 1; }
+  int ReadyForWriting() const { return ready_for_writing == 1; }
+
+public:  // Exception handling functions
+  FileError   GetFileError()              { return file_error; }
+  FileError   GetFileError() const        { return file_error; }
+  void        SetFileError(FileError err) { file_error = err; }
+  void        ResetFileError()            { file_error = FILE_NO_ERROR; }
+  const TCHAR *FileExceptionMessage();
+
+public: // General purpose file utilities
+  static int Exists(const TCHAR *fname);
+  static FileSystem::FAU_t FileSize(const TCHAR *fname);
+  static int CanOpenForWriting(const TCHAR *fname);
+  static int CanOpenReadOnly(const TCHAR *fname);
+  
+};
+
+
+#ifdef __CPP_EXCEPTIONS__
+// Class declarations for exceptions representing program errors. 
+// This implementation is provided for use C++'s built-in exception
+// handling routines.
+
+class CFileBaseException 
+{
+	int error_;
+public:
+	CFileBaseException(int error) { error_ = error; }
+};  
+
+#endif // __CPP_EXCEPTIONS__
+ 
+#endif   // __FILE_BASE__
Index: /gsdl/stable/build-src/packages/isis-gdl/FileSystem.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/FileSystem.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/FileSystem.cpp	(revision 20131)
@@ -0,0 +1,482 @@
+/**********************************************************************
+ *
+ * FileSystem.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+// FileSystem -- The generic file pointer routines are a collection of member
+//               functions used to wrap  the underlying file system.
+
+
+#include "errno.h"
+#include "stdafx.h"
+#include "FileSystem.h"
+
+
+using namespace FileSystem;
+//---------------------------------------------------------------------
+// FileSystem::FPTR *Create(const _TCHAR *fname)
+//
+// Create a new file and truncate existing files.
+// Returns a null value if the file cannot be
+// created.
+//---------------------------------------------------------------------
+DLL_CODE_API FileSystem::FPTR *FileSystem::Create(const char *fname)
+{
+#if defined(__64_BIT_FILE_SYSTEM__)
+	return FS64Create(fname);
+	
+#elif defined(__WIN32__) && defined(__NTFS__)
+	FPTR *stream = new FPTR;
+	if (!stream)
+		return 0;
+	stream->fptr = CreateFile(fname, 
+		GENERIC_READ | GENERIC_WRITE, 
+		FILE_SHARE_READ | FILE_SHARE_WRITE, 
+		NULL, // No security
+		CREATE_ALWAYS, 
+		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+		NULL // No attr. template 
+		);
+	
+	if (stream->fptr == INVALID_HANDLE_VALUE)
+	{
+		delete stream;
+		return 0;
+	}
+	return stream;
+	
+#else // Use the 32-bit stdio version by default
+	FPTR *stream = new FPTR;
+	if (!stream)
+		return 0;
+	stream->fptr = fopen(fname, "w+b");
+	if (stream->fptr == 0)
+	{
+		delete stream; // 01/30/2002: Prevent memory leak
+		return 0;
+	}
+	return stream;
+#endif
+}
+
+//---------------------------------------------------------------------
+// FileSystem::FPTR *Open(const _TCHAR *fname, FileSystemAccessMode mode)
+//
+// Open an existing file. The "mode" variable determines if the file
+// is opened for read only or read/write access. Returns a null value
+// if the specified file cannot be opened. NOTE: This version of the
+// open functions will only accept: FILE_READONLY and FILE_READWRITE
+// access modes.
+//---------------------------------------------------------------------
+DLL_CODE_API FileSystem::FPTR *FileSystem::Open(const char *fname, FileSystem::AccessMode mode)
+{
+#if defined(__64_BIT_FILE_SYSTEM__)
+	return FSOpen(fname, mode);
+	
+#elif defined(__WIN32__) && defined(__NTFS__)
+	FPTR *stream = new FPTR;
+	if (!stream)
+		return 0;
+	if (mode == FILE_READONLY)
+	{
+		// Open for read only access
+		stream->fptr = CreateFile(fname, 
+			GENERIC_READ,
+			FILE_SHARE_READ | FILE_SHARE_WRITE, 
+			NULL, // No security
+			OPEN_EXISTING, 
+			FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 
+			NULL // No attr. template 
+			);
+		if (stream->fptr == INVALID_HANDLE_VALUE)
+		{
+			delete stream;
+			return 0;
+		}
+	}
+	else 
+	{ // Open for read/write access
+		stream->fptr = CreateFile(fname, 
+			GENERIC_READ | GENERIC_WRITE, 
+			FILE_SHARE_READ | FILE_SHARE_WRITE, 
+			NULL, // No security 
+			OPEN_EXISTING, 
+			FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 
+			NULL // No attr. template 
+			);
+		
+		if (stream->fptr == INVALID_HANDLE_VALUE)
+		{
+			delete stream;
+			return 0;
+		}
+	}
+	return stream;
+	
+#else // Use the 32-bit stdio version by default
+	FPTR *stream = new FPTR;
+	if (!stream)
+		return 0;
+	
+	if (mode == FILE_READONLY)
+	{
+		// Open for read only access
+		stream->fptr = fopen(fname, "rb");
+		if (stream->fptr == 0)
+		{
+			delete stream; // 01/30/2002: Prevent memory leak
+			return 0;
+		}
+	}
+	else 
+	{ // Open for read/write access
+		stream->fptr = fopen(fname, "r+b");
+		if (stream->fptr == 0)
+		{
+			delete stream; // 01/30/2002: Prevent memory leak
+			return 0;
+		}
+	}
+	return stream;
+#endif
+}
+
+//---------------------------------------------------------------------
+// int Close(FileSystem::FPTR *stream)
+//
+// Close an open file. Returns a non-zero value to  indicate an error 
+// condition or zero if successful.
+//---------------------------------------------------------------------
+DLL_CODE_API int FileSystem::Close(FPTR *stream)
+{
+	if (!stream)
+		return 0; // The file stream is not open
+	
+#if defined(__64_BIT_FILE_SYSTEM__)
+	return FS64Close(stream);
+	
+#elif defined(__WIN32__) && defined(__NTFS__)
+	if (!CloseHandle(stream->fptr))
+		return 1;
+	delete stream;
+	stream = 0;
+	return 0;
+	
+#else // Use the 32-bit stdio version by default
+	if (fclose(stream->fptr) != 0)
+		return 1;
+	delete stream;
+	stream = 0; // 02/02/2002: Set pointer to zero after releasing it
+	return 0;
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// int Flush(FileSystem::FPTR *stream)
+//
+// Flush the any open disk buffers. Returns a non-zero value to indicate
+// an error // condition or zero if successful. 
+//
+// ATTENTION: ****MS VC++*** YOU SHOULD LINK YOUR APPLICATION WITH COMMODE.OBJ 
+// file. COMMODE.OBJ changes the global commit flag such that 
+// calling fflush() or _flushall() commits the file buffer to disk.
+// The Windows NT operating system provides the WIN32 API FlushFileBuffers().
+// The _commit() function included with the Visual C++ 32-bit Edition 
+// CRT calls FlushFileBuffers to write buffered data to disk. 
+//-----------------------------------------------------------------------------
+DLL_CODE_API int FileSystem::Flush(FPTR *stream)
+{
+	if (!stream)
+		return 0; // The file stream is not open
+	
+#if defined(__64_BIT_FILE_SYSTEM__)
+	return FS64Flush(stream);
+	
+#elif defined(__WIN32__) && defined(__NTFS__)
+	if (!FlushFileBuffers(stream->fptr))
+		return 1;
+	return 0;
+	
+#else // Use the 32-bit stdio version by default
+	int ret = fflush(stream->fptr);
+	if (ret != 0)
+	{
+		TRACE("\nerrno=%d\n\n\n", errno);
+		return 1;       // Error
+	}
+	else
+		return 0;
+#endif
+}
+
+//---------------------------------------------------------------------
+// int Read(FileSystem::FPTR *stream, void *buf, isis::uint32_t bytes)
+//
+// Read a specified number of bytes from the current file position
+// into a memory buffer. Returns the total number if bytes read from the
+// file.
+//---------------------------------------------------------------------
+DLL_CODE_API isis::ulong32_t FileSystem::Read(FPTR *stream, void *buf, 
+											  isis::ulong32_t bytes)
+{
+	if (!stream)
+		return (isis::ulong32_t)0; // The file stream is not open
+	
+#if defined(__64_BIT_FILE_SYSTEM__)
+	return FS64Read(stream, buf, bytes);
+	
+#elif defined(__WIN32__) && defined(__NTFS__)
+	DWORD bytes_read; 
+	if (!ReadFile(stream->fptr, (LPVOID)buf, (DWORD)bytes, &bytes_read, NULL))
+	{
+		return (isis::ulong32_t)0;
+	}
+	return (isis::ulong32_t)bytes_read;
+	
+#else // Use the 32-bit stdio version by default
+	return (isis::ulong32_t)fread((unsigned char *)buf, 1, bytes, stream->fptr);
+#endif
+}
+//---------------------------------------------------------------------
+// int Write(FileSystem::FPTR *stream, const void *buf, isis::uint32_t bytes) 
+//
+// Write a specific number of bytes from a memory buffer to the
+// current file position. Returns the total number if bytes written
+// to the file.
+//---------------------------------------------------------------------
+DLL_CODE_API isis::ulong32_t FileSystem::Write(FPTR *stream, const void *buf, 
+				                   isis::ulong32_t bytes) 
+{
+	if (!stream)
+		return (isis::ulong32_t)0; // The file stream is not open
+	
+#if defined(__64_BIT_FILE_SYSTEM__)
+	return FS64Write(stream, buf, bytes);
+	
+#elif defined(__WIN32__) && defined(__NTFS__)
+	DWORD bytes_moved; 
+	if (!WriteFile(stream->fptr, (LPVOID)buf, (DWORD)bytes, &bytes_moved, NULL))
+	{
+		return (isis::ulong32_t)0;
+	}
+	return (isis::ulong32_t)bytes_moved;
+	
+#else // Use the 32-bit stdio version by default
+	return (isis::ulong32_t)fwrite((const unsigned char *)buf, 1, bytes, stream->fptr);
+#endif
+}
+//---------------------------------------------------------------------------
+// isis::int32_t Seek(FileSystem::FPTR *stream, isis::int32_t offset,  FileSystemSeekMode mode)
+//
+// Seek to the specified offset starting at the beginning (SEEK_SET),
+// end (SEEK_END) or current offset (SEEK_CUR). Returns a negative 1
+// to indicate an error condition or the current stream position if
+// successful.
+//----------------------------------------------------------------------------
+DLL_CODE_API FAU_t FileSystem::Seek(FPTR *stream, FAU_t offset, FileSystem::SeekMode mode)
+{
+	if (!stream)
+		return (FAU_t) - 1; // The file stream is not open
+	
+#if defined(__64_BIT_FILE_SYSTEM__)
+	return FS64Seek(stream, offset, mode);
+	
+#elif defined(__WIN32__) && defined(__NTFS__)
+	if (mode == FILE_SEEK_BEG)
+	{
+		return (FAU_t)SetFilePointer(stream->fptr, offset, NULL, FILE_BEGIN);
+	}
+	else if (mode == FILE_SEEK_CUR)
+	{
+		return (FAU_t)SetFilePointer(stream->fptr, offset, NULL, FILE_CURRENT);
+	}
+	else if (mode == FILE_SEEK_END)
+	{
+		return (FAU_t)SetFilePointer(stream->fptr, offset, NULL, FILE_END);
+	}
+	else 
+	{ // An invalid seek mode was specified
+		return (FAU_t) - 1;
+	}
+	
+#else // Use the 32-bit stdio version by default
+	if (mode == FILE_SEEK_BEG)
+	{
+		return fseek(stream->fptr, offset, SEEK_SET);
+	}
+	else if (mode == FILE_SEEK_CUR)
+	{
+		return fseek(stream->fptr, offset, SEEK_CUR);
+	}
+	else if (mode == FILE_SEEK_END)
+	{
+		return fseek(stream->fptr, offset, SEEK_CUR);
+	}
+	else 
+	{ // An invalid seek mode was specified
+		return (FAU_t) - 1;
+	}
+#endif
+}
+//----------------------------------------------------------------------------
+// isis::int32_t Tell(FileSystem::FPTR *stream)
+//
+//----------------------------------------------------------------------------
+DLL_CODE_API FAU_t FileSystem::Tell(FPTR *stream)
+{
+	if (!stream)
+		return (FAU_t) - 1; // The file stream is not open
+	
+#if defined(__64_BIT_FILE_SYSTEM__)
+	return FS64Tell(stream);
+	
+#elif defined(__WIN32__) && defined(__NTFS__)
+	return (__LWORD__)SetFilePointer(stream->fptr, 0, NULL, FILE_CURRENT);
+	
+#else // Use the 32-bit stdio version by default
+	return ftell(stream->fptr);
+#endif
+}
+
+//----------------------------------------------------------------------------
+// int Exists(const char *fname)
+//
+// Returns true if the specified file exists.
+//----------------------------------------------------------------------------
+DLL_CODE_API int FileSystem::Exists(const char *fname)
+// Returns true if the specified file exists.
+{
+#if defined(__64_BIT_FILE_SYSTEM__)
+	return FS64Exists(fname);
+	
+#elif defined(__WIN32__) && defined(__NTFS__)
+	HANDLE hFile = CreateFile(fname, 
+		GENERIC_READ,
+		FILE_SHARE_READ | FILE_SHARE_WRITE, 
+		NULL, // No security
+		OPEN_EXISTING, 
+		FILE_ATTRIBUTE_NORMAL, 
+		NULL // No attr. template
+		);
+	
+	if (hFile == INVALID_HANDLE_VALUE)
+	{
+		return 0;
+	}
+	
+	CloseHandle(hFile);
+	return 1;
+	
+#else // Use the 32-bit stdio version by default
+	struct stat buf;
+	return stat(fname, &buf) ==(FAU_t)0;
+#endif
+}
+
+
+
+//----------------------------------------------------------------------------
+// FAU_t FileSize(const _TCHAR *fname)
+//
+// Returns the length of the specified file or negative 1 to indicate an
+// error condition.
+//----------------------------------------------------------------------------
+DLL_CODE_API FAU_t FileSystem::FileSize(const char *fname)
+{
+#if defined(__64_BIT_FILE_SYSTEM__)
+	return FS64FileSize(fname);
+	
+#elif defined(__WIN32__) && defined(__NTFS__)
+	HANDLE hFile = CreateFile(fname, 
+		GENERIC_READ,
+		FILE_SHARE_READ | FILE_SHARE_WRITE, 
+		NULL, // No security
+		OPEN_EXISTING, 
+		FILE_ATTRIBUTE_NORMAL, 
+		NULL // No attr. template 
+		);
+	
+	// Could not open the specified file
+	if (hFile == INVALID_HANDLE_VALUE)
+	{
+		return (FAU_t) - 1;
+	}
+	
+	BY_HANDLE_FILE_INFORMATION info;
+	
+	if (GetFileInformationByHandle(hFile, &info) == 0)
+	{
+		return (FAU_t) - 1;
+	}
+	CloseHandle(hFile);
+	return (FAU_t)info.nFileSizeLow;;
+	
+#else // Use the 32-bit stdio version by default
+	struct stat buf;
+	int result = stat(fname, &buf);
+	if (result != 0)
+		return -1;
+	return buf.st_size;
+#endif
+}
+
+//  #include <io.h>
+//  #include <share.h>
+
+
+//  int FileSystem::CanOpenForWriting(const _TCHAR *fname)
+//  {
+//  	// Try to open for writing
+//  	int fd = _tsopen(fname, _O_WRONLY | O_BINARY, _SH_DENYWR);
+//  	if (fd == -1)
+//  		return 0;
+//  	_close(fd);
+//  	return 1;
+//  }
+
+//  int FileSystem::CanOpenReadOnly(const _TCHAR *fname)
+//  {
+//  	// Try to open for read only
+//  	int fd = _tsopen(fname, _O_RDONLY | O_BINARY, _SH_DENYNO);
+//  	if (fd == -1)
+//  		return 0;
+//  	_close(fd);
+//  	return 1;
+//  }
+
+//----------------------------------------------------------------------------
+// int IsReadOnly(const _TCHAR* fname)
+//
+// Returns true if the specified file is read only.
+//----------------------------------------------------------------------------
+//  int FileSystem::IsReadOnly(const _TCHAR *fname)
+//  {
+//  	struct _stat buf;
+//  	_tstat(fname, &buf);
+//  	if (buf.st_mode & S_IWRITE)
+//  		return 0;
+//  	return 1;
+//  }
+
Index: /gsdl/stable/build-src/packages/isis-gdl/FileSystem.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/FileSystem.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/FileSystem.h	(revision 20131)
@@ -0,0 +1,121 @@
+/**********************************************************************
+ *
+ * FileSystem.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////
+// FileSystem.h -- The generic file pointer routines are a collection of member
+//                 functions used to wrap  the underlying file system.
+
+//
+
+  
+#ifndef __FILE_SYSTEM__
+#define __FILE_SYSTEM__
+
+// Non-platform specific include files
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include "DLLCode.h"
+#include "IsisTypes.h"
+
+namespace FileSystem {
+	
+// ----------------
+// Type definitions 
+// ----------------
+// typedefs for 64-bit and 32-bit file operations and stream position
+#if defined (__64_BIT_FILE_SYSTEM__)
+    typedef isis::int64_t FAU;       // 64-bit File Address Unit, physical file address type
+    typedef isis::int64_t FAU_t;     // Native 64-bit FAU type
+    typedef isis::int64_t StreamPos; // 64-bit stream position
+#else // Use the 32-bit version by default
+	typedef isis::int32_t FAU;       // 32-bit File Address Unit, physical file address type
+	typedef isis::int32_t FAU_t;     // Native 32-bit FAU type
+	typedef isis::int32_t StreamPos; // 32-bit stream position
+#endif
+
+
+// Select the underlying file system 
+#if defined (__64_BIT_FILE_SYSTEM__)
+	#include "FS64.H"              // WIN32 will always use NTFS for large files
+	typedef  FPTR64 FPTR;
+
+
+#elif defined (__WIN32__) && defined (__NTFS__)
+	// WIN32 file I/O API
+	#include <windows.h>
+	#include <io.h>
+	#include <string.h>
+	#include <stdlib.h>
+	#include <fcntl.h>
+	#include <sys/types.h>
+	#include <sys/stat.h>
+	#include <stdio.h>
+	#include "gxdtypes.h"
+	#include "gxheader.h"
+
+	struct DLL_CODE_API FPTR { // Platform specific file pointer type
+		HANDLE fptr;
+	};
+
+#else // Use the stdio version by default. Common to all platforms.
+	// Non-platform specific stdio include files
+	#include <string.h>
+	#include <stdlib.h>
+	#include <fcntl.h>
+	#include <sys/types.h>
+	#include <sys/stat.h>
+	#include <stdio.h>
+	#include "IsisTypes.h"
+	//#include "gxheader.h"
+
+	struct DLL_CODE_API FPTR { // File pointer type
+		 FILE *fptr;
+	};
+#endif // File system type
+
+
+
+    // NOTE: Any underlying file system used must provide the basic
+    // functionallity defined here.
+    DLL_CODE_API FPTR            *Create(const char  *fname);
+    DLL_CODE_API FPTR            *Open(const char *fname, AccessMode mode);
+    DLL_CODE_API int             Close(FPTR *stream);
+    DLL_CODE_API int             Flush(FPTR *stream);
+    DLL_CODE_API isis::ulong32_t Read(FPTR *stream, void *buf, isis::ulong32_t bytes);
+    DLL_CODE_API isis::ulong32_t Write(FPTR *stream, const void *buf, isis::ulong32_t bytes);
+    DLL_CODE_API FAU_t           Seek(FPTR *stream, FAU_t, SeekMode mode);
+    DLL_CODE_API FAU_t           Tell(FPTR *stream);
+    DLL_CODE_API int             Exists(const _TCHAR *fname);
+    DLL_CODE_API FAU_t           FileSize(const _TCHAR *fname);
+    // DLL_CODE_API int             CanOpenForWriting(const _TCHAR *fname);
+    // DLL_CODE_API int             CanOpenReadOnly(const _TCHAR *fname);
+    // DLL_CODE_API int             IsReadOnly(const _TCHAR *fname);
+}
+
+#endif // __FILE_SYSTEM__
Index: /gsdl/stable/build-src/packages/isis-gdl/IErrors.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/IErrors.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/IErrors.cpp	(revision 20131)
@@ -0,0 +1,113 @@
+/**********************************************************************
+ *
+ * IErrors.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////
+// Error.cpp
+
+// #include "stdafx.h"
+// The Error functions and classes are used to catch and/or
+// record database exceptions that occur during run-time. This
+// implementation can be used with or without C++ built-in exception
+// handling. If C++ exception handling is not enabled with the
+// __CPP_EXCEPTIONS__ macro, then the vbDatabaseError enumerated
+// constants can be used to record database errors.
+#include "IErrors.h"
+
+// NOTE: This array must contain the same number of exceptions as the
+// IsisError enumeration. 
+const int MaxExceptionMessages = 57;
+const char* isisExceptionMessages[MaxExceptionMessages] = {
+  "Database exception: No exception reported",               // None
+  "Database exception: Invalid error code reported",         // Invalid
+  "Database exception: Memory exhausted",
+  "Database exception: Error opening xrf file",
+  "Database exception: Error creating xrf file",
+  "Database exception: Error reading xrf file",
+  "Database exception: Error writing xrf file",
+  "Database exception: xrf file is corrupted",
+  "Database exception: xrf file, invalid block",
+  "Database exception: xrf file, invalid status",
+  "Database exception: Error creating an existing mf file",
+  "Database exception: Error opening mf file",
+  "Database exception: Error opening mf file",
+  "Database exception: Error creating mf file",
+  "Database exception: Error reading mf file",
+  "Database exception: Error writing mf file",
+  "Database exception: Access Violation",                    // AccessViolation
+  "Database exception: Assertion failed",                    // AssertError
+  "Database exception: Wrong object type",                   // BadClassID
+  "Database exception: Bad object address",                  // BadObjectAddress
+  "Database exception: Bad reference",                       // BadReference
+  "Database exception: Cache full",                          // CacheFull
+  "Database exception: Checksum error",                      // ChecksumError
+  "Database exception: Divide by zero error",                // DivideByZero
+  "Database exception: Unexpected end of file was reached",  // EOFError
+  "Database exception: Error closing file",                  // FileCloseError
+  "Database exception: File is corrupt",                     // FileCorrupt
+  "Database exception: Error creating file",                 // CreationError
+  "Database exception: File already exists",                 // FileExists
+  "Database exception: Trying to use a closed file",         // FileNotOpenError
+  "Database exception: File not ready for reading/writing",  // FileNotReady
+  "Database exception: Could not write to file",             // NotWriteable
+  "Database exception: Error opening file",                  // FileOpenError
+  "Database exception: Cannot obtain a file position",       // FilePostionError
+  "Database exception: Error reading from file",             // FileReadError
+  "Database exception: Error seeking in file",               // FileSeekError
+  "Database exception: Error writing to file",               // FileWriteError
+  "Database exception: No database open",                    // NoDatabaseOpen
+  "Database exception: No such file exists",                 // NoFileExists
+  "Database exception: No objects exist",                    // NoObjectsExist
+  "Database exception: Accessing a null pointer",            // NullPtr
+  "Database exception: Object already exists",               // ObjectExists
+  "Database exception: Another object is referencing this file", // Referenced
+  "Database exception: Math overflow error",                 // OverFlow
+  "Database exception: Parse error",                         // ParseError
+  "Database exception: Invalid path",                        // PathError
+  "Database exception: Trying to write to a read-only file", // ReadOnlyFile
+  "Database exception: Stack empty",                         // StackEmpty
+  "Database exception: Stack full",                          // StackFull
+  "Database exception: Synchronization Error",               // SyncError    
+  "Database exception: Math under-flow error",               // UnderFlow
+  "Database exception: Wrong file type",                     // WrongFileType
+
+  // Persistent lock error messages
+  "Database exception: Invalid lock type specified",          // LOCK_TYPE
+  "Database exception: Cannot access the file lock header",   // FLK_ACCESS
+  "Database exception: Cannot lock the file",                 // FLK_ERROR
+  "Database exception: Cannot access the record lock header", // RLK_ACCESS
+  "Database exception: Cannot lock the specified record"      // RLK_ERROR
+};
+
+const char *isisExceptionMessage(IsisError err)
+// Standalone function that returns a null terminated string that can
+// be use to log or print a database exception message.
+{
+  int error = (int)err;
+  if(error > MaxExceptionMessages) error = ISIS_INVALID_CODE;
+
+  // Find the corresponding message in the exception array
+  return isisExceptionMessages[error];
+}
+
Index: /gsdl/stable/build-src/packages/isis-gdl/IErrors.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/IErrors.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/IErrors.h	(revision 20131)
@@ -0,0 +1,104 @@
+/**********************************************************************
+ *
+ * IErrors.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef __ISIS_ERROR_H__
+#define __ISIS_ERROR_H__
+
+enum IsisError { // Database error codes
+  ISIS_NO_ERROR = 0,        // No errors reported
+  ISIS_INVALID_CODE,
+  ISIS_BAD_ALLOC,
+  ISIS_XRF_OPEN_ERROR,      // Xrf open error
+  ISIS_XRF_CREATE_ERROR,    // Xrf creation error
+  ISIS_XRF_READ_ERROR,      // Xrf read error
+  ISIS_XRF_WRITE_ERROR,     // Xrf write error
+  ISIS_XRF_CORRUPT,         // Xrf corrupted
+  ISIS_XRF_INVALID_BLOCK,   // Xrf invalid block
+  ISIS_XRF_INVALID_STATUS,  // Xrf invalid status
+  ISIS_MF_ALREADY_EXIST_ERROR, // Attempt to create an existing mf
+  ISIS_MF_OPEN_ERROR,       // Mf open error
+  ISIS_MF_CREATE_ERROR,     // Mf creation error
+  ISIS_MF_READ_ERROR,       // Mf read error
+  ISIS_MF_WRITE_ERROR,      // Mf write error 
+  ISIS_ASSERT_ERROR,        // Assertion failed
+  ISIS_BAD_CLASS_ID,        // Wrong object type
+  ISIS_BAD_OBJECT_ADDRESS,  // Bad object address  ISIS_BAD_REFERENCE,       // Bad Reference
+  ISIS_CACHE_FULL,          // Cache full
+  ISIS_CHECKSUM_ERROR,      // Checksum Error
+  ISIS_DIVIDEBY_ZERO,       // Divide By Zero Error
+  ISIS_EOF_ERROR,           // Unexpected end of file
+  ISIS_FILE_CLOSE_ERROR,    // Error closing file
+  ISIS_FILE_CORRUPT,        // File corrupted
+  ISIS_FILE_CREATION_ERROR, // Error creating file
+  ISIS_FILE_EXISTS,         // File already exists
+  ISIS_FILE_NOT_OPEN_ERROR, // Trying to use a closed file
+  ISIS_FILE_NOT_READY,      // File not ready (failed or closed file)
+  ISIS_FILE_NOT_WRITEABLE,  // Could not write to file 
+  ISIS_FILE_OPEN_ERROR,     // Error opening file
+  ISIS_FILE_POSITION_ERROR, // Cannot obtain the current file position
+  ISIS_FILE_READ_ERROR,     // Error reading file  
+  ISIS_FILE_SEEK_ERROR,     // Error seeking in file
+  ISIS_FILE_WRITE_ERROR,    // Error writing to file
+  ISIS_NO_DATABASE_OPEN,    // No database open
+  ISIS_NO_FILE_EXISTS,      // No such file exists
+  ISIS_NO_OBJECTS_EXIST,    // No objects exist
+  ISIS_NULL_PTR,            // Accessing a null pointer 
+  ISIS_OBJECT_EXISTS,       // Object already exists
+  ISIS_OPEN_FILE_REFERENCE, // Another object is referencing this file
+  ISIS_OVERFLOW,            // Math overflow
+  ISIS_PARSE_ERROR,         // Parse error
+  ISIS_PATH_ERROR,          // Invalid path
+  ISIS_READ_ONLY_FILE,      // Trying to write to read-only file
+  ISIS_STACK_EMPTY,         // Stack empty
+  ISIS_STACK_FULL,          // Stack full
+  ISIS_SYNC_ERROR,          // Synchronization Error
+  ISIS_UNDERFLOW,           // Math under-flow
+  ISIS_WRONG_FILE_TYPE,     // Wrong file type
+
+  // Persistent lock error codes
+  ISIS_INVALID_LOCK_TYPE,        // Invalid lock type specified
+  ISIS_MFLOCK_ACCESS_ERROR,    // The file lock cannot be accessed
+  ISIS_MFLOCK_ERROR,           // Error locking the file
+  ISIS_RECORDLOCK_ACCESS_ERROR,  // The record lock cannot be accessed
+  ISIS_RECORDLOCK_ERROR          // Error locking a record
+};
+
+// Standalone functions use to report database errors
+const char *isisExceptionMessage(IsisError err);
+
+#ifdef __CPP_EXCEPTIONS__
+// Class declarations for exceptions representing program errors. 
+// This implementation is provided for use C++'s built-in exception
+// handling routines.
+
+// A fatal file error condition has been reached. All database engine
+// calls must catch this exception and evaluate it by testing the
+// vbDatabase or vbDatabase64 internal error variable.
+class CIsisException { };  
+
+#endif // __CPP_EXCEPTIONS__
+
+#endif // __ISIS_ERROR_H__
Index: /gsdl/stable/build-src/packages/isis-gdl/IsisDb.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/IsisDb.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/IsisDb.cpp	(revision 20131)
@@ -0,0 +1,252 @@
+/**********************************************************************
+ *
+ * IsisDb.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////
+// ISISDB: Isis Master file methods
+////////////////////////////////////////////////////////////
+#include "stdafx.h"
+#include "IsisDb.h"
+#include "XRFFile.h"
+
+
+
+//-------------------------------------------------------------------------------- 
+// IsisDb::IsisDb()
+//
+// Constructor, Makes an ISIS Data Base object that isn't connected to a Master 
+// file, Cross Reference file and Fdt.
+//-------------------------------------------------------------------------------
+IsisDb::IsisDb()
+{
+	bReadOnly_ = false;
+	try
+	{
+        mf_  = new MfFile;
+	    xf_  = new XrfFile; 
+	    fdt_ = new CFdt;
+	}
+	catch(std::bad_alloc)
+	{
+		throw CIsisDbException(ISIS_BAD_ALLOC, __FILE__, __LINE__);
+	}
+}
+ 
+//////////////////////////////
+ 
+IsisDb::~IsisDb( )
+{
+   delete mf_; delete xf_; delete fdt_;
+}
+ 
+ 
+//////////////////////////////
+ 
+int IsisDb::CreateDb(const TCHAR *fname)
+{
+   name = fname;
+   MkNames();
+   int rc = ISIS_NO_ERROR;
+
+   // We should not try to create a mf_ which already exist!
+   if (CFileBase::Exists(mfname_))
+   {
+	   throw CIsisDbException(ISIS_MF_ALREADY_EXIST_ERROR, __FILE__, __LINE__);
+   }
+   else
+   {
+       try
+	   {
+           rc = mf_->CreateMf(mfname_, USERMST);   
+           rc = xf_->CreateXrf(xrfname_);
+           rc = fdt_->Load(fdtname_);
+	   }
+       catch(CIsisDbException)
+	   {
+    	   throw CIsisDbException(ISIS_MF_OPEN_ERROR, __FILE__, __LINE__);
+	   }
+   }
+   
+   return rc;
+}
+ 
+ 
+//////////////////////////////
+ 
+void IsisDb::CloseDb()
+{
+   mf_->CloseMf();
+   xf_->Close();
+}
+ 
+//////////////////////////////
+ 
+void IsisDb::MkNames()
+// Make file names
+{
+    const _TCHAR *s = name.c_str();
+	_TCHAR *ps = new _TCHAR[_tcslen(s)+1];
+	_tcscpy(ps, s);
+	_TCHAR * tmp = _tcsrchr(ps, _T('.'));
+	assert(tmp != NULL);
+    // Terminate the string at the last dot 
+    *tmp = _T('\0');
+
+   _tcscpy(mfname_,ps);
+   _tcscat(mfname_,_T(".mst"));
+   _tcscpy(xrfname_,ps);
+   _tcscat(xrfname_,_T(".xrf"));
+   _tcscpy(fdtname_,ps);
+   _tcscat(fdtname_,_T(".fdt"));
+   _tcscpy(idxname_,ps);
+   _tcscat(idxname_,_T(".idx"));
+   delete[] ps;
+}
+ 
+//////////////////////////////
+ 
+int IsisDb::OpenDb(const TCHAR *fname,  FileSystem::AccessMode mode
+				                              /* = FileSystem::FILE_READWRITE */)
+{
+   name = fname;
+   MkNames();
+   int rc;
+   try
+   {
+     // if (FileSystem::IsReadOnly(mfname_))
+     //	   mode = FileSystem::FILE_READONLY;
+       rc = mf_->OpenMf(mfname_, mode);
+       rc = xf_->OpenXrf(xrfname_, mode);
+       rc = fdt_->Load(fdtname_);
+   }
+   catch(CIsisDbException)
+   {
+	   throw CIsisDbException(ISIS_MF_OPEN_ERROR, __FILE__, __LINE__);
+   }
+
+   return rc;
+}
+ 
+//----------------------------------------------------------------------------------
+// int  IsisDb::ReadDbRecord(long mfn, MfRecord &m)
+//
+// This function reads Master File record with MFN "mfn" into m
+//
+// Returns the status of the record: 
+// Active=0, LogicalyDeleted=1, PhysicalyDeleted=2, EndOfFile=-1, NewRecord = 3
+//----------------------------------------------------------------------------------
+int  IsisDb::ReadDbRecord(long mfn, MfRecord &m)
+{
+   long mfb;
+   int mfp;
+   int status;
+   bool rc;
+
+   try
+   {
+       status = xf_->GetMfp(mfn, mfb, mfp);
+       if (status == Active || status == LogicalyDeleted)
+	       if (!mf_->ReadMfRecord(mfb, mfp, m))
+			   status = -1;    // Error in reading the record!
+   }
+   catch(CIsisDbException)
+   {
+	   throw CIsisDbException(ISIS_MF_OPEN_ERROR, __FILE__, __LINE__);
+   }
+   return status;
+}
+ 
+//--------------------------------------------------------------------------------
+// void CreateDbRecord(MfRecord &m)
+//
+// Create a new record at the end of the master file. The Master file address is
+// set into the pair mfb/mfp and the XRF file is updated.
+//---------------------------------------------------------------------------------
+ void IsisDb::CreateDbRecord(MfRecord &m)
+{
+ 
+}
+
+//--------------------------------------------------------------------------------
+// void CreateDbRecordWithMfn(MfRecord &m)
+//
+// Create a new record at the end of the master file. The Master file address is
+// set into the pair mfb/mfp and the XRF file is updated.
+//---------------------------------------------------------------------------------
+ void IsisDb::CreateDbRecordWithMfn(MfRecord &m)
+{
+ 
+}
+
+ 
+//----------------------------------------------------------------------------------
+// void  UpdateDbRecord(MfRecord &m)
+//
+// Update of existing records. Whenever a record is updated, the system writes
+// the record back to the master file. Where it is written depends on the status
+// of the record when it was initially read.
+//
+//----------------------------------------------------------------------------------
+ void  IsisDb::UpdateDbRecord(MfRecord &m)
+{
+}
+//----------------------------------------------------------------------------------
+// int  IsisDb::DeleteRecord(long mfn)
+//
+// This function logically deletes a Master File record with MFN "mfn".
+// On XRF, xrfmfb is negative and on MST, status is set to 1
+//
+// Returns true if successful 
+//----------------------------------------------------------------------------------
+bool  IsisDb::DeleteRecord(long mfn)
+{
+
+   return false;
+}
+
+long  IsisDb::GetNextActiveMfn(long mfn /* = -1 */)
+{
+	if (mfn == -1)
+		mfn = 1;
+	else
+		mfn++;
+	long  mfb;
+	int  mfp;
+	int iRet = xf_->GetMfp(mfn, mfb, mfp);
+	while (iRet != Active && iRet != EndOfFile)
+	{
+		mfn++;
+        iRet = xf_->GetMfp(mfn, mfb, mfp);
+	}
+	if (iRet == EndOfFile)
+		return 0;
+	else
+		return mfn;
+}
+	
+_TCHAR *IsisDb::GetIdxFileName()
+{
+	return idxname_;
+}
+
Index: /gsdl/stable/build-src/packages/isis-gdl/IsisDb.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/IsisDb.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/IsisDb.h	(revision 20131)
@@ -0,0 +1,130 @@
+/**********************************************************************
+ *
+ * IsisDb.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////
+// Isisdb.h : Class Definition for an ISIS db
+////////////////////////////////////////////////////////////
+ 
+#ifndef __ISISDB_H__
+#define __ISISDB_H__
+
+#include "AbstractIsisDb.h"
+#include "IsisDef.h"
+#ifndef _MFFILE_H_
+#include "MFFile.h"
+#endif
+
+ 
+class IsisDb : public AbstractIsisDb
+{
+	friend class CDBaseFile;
+
+	bool  bReadOnly_;
+    TCHAR xrfname_[_MAX_PATH];
+    TCHAR mfname_[_MAX_PATH];
+    TCHAR fdtname_[_MAX_PATH];
+    TCHAR idxname_[_MAX_PATH];
+protected:
+   void MkNames();
+public:
+   IsisDb();
+   virtual ~IsisDb( );
+   int OpenDb(const TCHAR *fname, FileSystem::AccessMode mode =
+	                                          FileSystem::FILE_READWRITE);
+   int CreateDb(const TCHAR *fname);
+
+
+// Closing the database
+   virtual void CloseDb();       // Close the db
+
+   virtual void ClearDb()   { }    // Clear the db
+   virtual void DestroyDb() { }  // Delete the db
+
+// Recovery
+   virtual bool IsDamaged() { return false;}   // Test if the database is damaged
+   virtual bool Recover()   { return true; }   // Recover the db
+
+// Transactions
+   virtual void BeginTransaction()    { }  // Begin a transaction
+   virtual void CommitTRansaction()   { }  // Commit a transaction
+   virtual void RollbackTransaction() { }  // Rollback a transaction
+   virtual bool InTransaction()       { return false; }  // Test if transaction is pending
+
+   virtual void CreateIndex(int i) { }
+   virtual void DropIndex(int i)   { }
+
+   void  CreateDbRecord(MfRecord &m);
+   void  CreateDbRecordWithMfn(MfRecord &m);
+   void  UpdateDbRecord(MfRecord &m);
+   bool  DeleteRecord(long mfn);
+   int   ReadDbRecord(long mfn, MfRecord &m);
+   int   ReadNextDbRecord(MfRecord &m);
+   void  PrintDbRecord(MfRecord &m);
+   void  PrintDbHdr();
+
+   void SetNextMfn(long mfn) { mf_->setNextMfn(mfn); }
+   long GetNextMfn()        { return mf_->GetNextMfn(); }
+   long GetNextActiveMfn(long mfn=-1);
+
+   SMfHeader& GetSMfHeader() { return mf_->GetSMfHeader(); }
+   _TCHAR *GetIdxFileName();
+
+   bool IsReadOnly() { return bReadOnly_; }
+};
+ 
+//////////////////////////////
+ 
+inline int IsisDb::ReadNextDbRecord(MfRecord &m)
+{
+   return 1;
+}
+ 
+//////////////////////////////
+ 
+inline void  IsisDb::PrintDbRecord(MfRecord &m)
+{
+   mf_->PrintMfRecord(m);
+}
+ 
+//////////////////////////////
+ 
+inline void  IsisDb::PrintDbHdr()
+{
+   mf_->PrintMfHdr();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+class IsisDbFactory : public AbstractIsisDbFactory
+{
+public:
+	virtual AbstractIsisDb* MakeIsisDb() { return new IsisDb(); }
+};
+
+/////////////////////////////////////////////////////////////////////////////////
+
+
+
+#endif
Index: /gsdl/stable/build-src/packages/isis-gdl/IsisDef.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/IsisDef.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/IsisDef.h	(revision 20131)
@@ -0,0 +1,138 @@
+/**********************************************************************
+ *
+ * IsisDef.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef __ISIS_DEFINITION_H__
+#define __ISIS_DEFINITION_H__
+
+// disable warning C4786: symbol greater than 255 character,
+// okay to ignore
+#pragma warning(disable: 4786)
+
+#ifndef __ISIS_TYPE_H__
+#include "IsisTypes.h"
+#endif
+
+#include <sstream>
+
+typedef std::string ustring;
+typedef std::string cstring;
+// typedef std::wstring awstring;
+typedef std::stringstream ustringstream;
+typedef std::stringstream cstringstream;
+typedef wchar_t WCHAR;
+
+
+const size_t INVALID_NPOS = ~(size_t)0;
+
+namespace FileSystem {
+    // Generic File access/open mode enumeration
+    enum AccessMode { 
+       FILE_READONLY,   // Open file with read access only
+       FILE_WRITEONLY,  // Open file with write access only
+       FILE_READWRITE,  // Open file with read and write access
+       FILE_CREATE,     // Create the file if it does not exist
+       FILE_NO_CREATE,  // Do not create the file if it does not exist
+       FILE_TRUNCATE,   // Truncate the file  
+       FILE_APPEND,     // Append to the file
+       FILE_SHARE,      // Enable file sharing  (Platform specific)
+       FILE_EXCLUSIVE   // Disable file sharing (Platform specific)
+	};
+
+
+    // Generic File seek mode enumeration
+    enum SeekMode { 
+      FILE_SEEK_BEG, // Seek starting from the beginning of the file
+      FILE_SEEK_CUR, // Seek starting from the current location
+      FILE_SEEK_END  // Seek starting from the end of the file
+    };
+};
+
+#ifndef __FILE_SYSTEM__
+#include "FileSystem.h"
+#endif
+
+#ifndef __FILE_BASE__
+#include "File.h"
+#endif
+
+#ifndef __ISIS_ERROR_H__
+#include "IErrors.h"
+#endif
+
+#ifdef _WIN32
+#ifndef __DEBUG_H__
+#define _DEBUG
+#define _CONSOLE
+#include "debug.h"
+#endif
+#endif
+
+#ifndef __ABSTRACT_ISISDB_H__
+#include "AbstractIsisDb.h"
+#endif
+
+#ifndef __ISISDB_H__
+#include "IsisDb.h"
+#endif
+
+
+#ifndef __MASTER_RECORD_H__
+#include "Master.h"
+#endif
+
+#ifndef __FDT_H__
+#include "Fdt.h"
+#endif
+
+
+enum { RecordDeleted=0, RecordUpdated=1, RecordCreated=2};
+enum { Active=0, LogicalyDeleted=1, PhysicalyDeleted=2,
+       EndOfFile=-1, NewRecord = 3 };
+
+
+
+
+// Class declarations for exceptions representing program errors. 
+// This implementation is provided for use C++'s built-in exception
+// handling routines.
+
+class CIsisDbException { 
+public:
+	int m_iError;
+	CIsisDbException(const int iError, const char* file_name, const long line_number) 
+	{
+		m_iError = iError;
+#ifdef _WIN32
+		AssertFailed(isisExceptionMessage((IsisError) m_iError), file_name, line_number);
+#else
+		std::cout << isisExceptionMessage((IsisError) m_iError) << file_name
+			      << " Line=" << line_number;
+#endif
+	}
+};  
+
+
+#endif // __ISIS_DEFINITION_H__
Index: /gsdl/stable/build-src/packages/isis-gdl/IsisGdl.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/IsisGdl.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/IsisGdl.cpp	(revision 20131)
@@ -0,0 +1,135 @@
+/**********************************************************************
+ *
+ * IsisGdl.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+// IsisGdl.cpp : Defines the entry point for the console application.
+//
+
+#include "stdafx.h"
+#include "IsisDb.h"
+#include <iostream>
+
+void PausePrg()
+{
+	std::cout << "\n";
+	std::cout << "Press enter to continue..." << "\n";
+	std::cin.get();
+}
+
+void ClearInputStream(std::istream &s)
+// Used to clear istream
+{
+	char c;
+	s.clear();
+	while(s.get(c) && c != '\n') { ; }
+}
+
+// Should be called with the master file name as parameter
+// IsisGdl "full_path\master_file_name" 
+// IsisGdl C:\IsisGdl\cds.mst for ex
+
+
+int main(int argc, _TCHAR* argv[])
+{
+
+	if (argc < 2 || argc > 3)
+	{
+		std::cout << "usage: IsisGdl [-include_logically_deleted_records] master_file_full_name" << std::endl;
+		return 1;
+	}
+	// Instantiation of the IsisDb Object
+	IsisDb db;
+	try
+	{
+		// The file name should be prefixed with the full path
+		// and should be the master file name with extension ".mst"
+		// "C:\IsisGdl\cds.mst" for ex
+		db.OpenDb(argv[argc - 1]);
+	}
+	catch(CIsisDbException e)
+	{
+		std::string msg = "Cannot open isis db: ";
+		msg += argv[argc - 1];
+		msg += isisExceptionMessage((IsisError) e.m_iError);
+		std::cerr<< msg << std::endl;
+		return false;
+	}
+
+	// Create a Master File object without the Field Definition
+	// Information
+	MfRecord mfr(0); 
+
+	// Extract the number of the next master file number to
+	// assign
+	const long nextMfn = db.GetNextMfn();
+
+
+
+	// Browse the master file in increasing order of Master
+	// file numbers (MFN is the record ID)
+	for (long i=1; i<nextMfn; i++)
+	{
+
+		int status = db.ReadDbRecord(i, mfr);
+
+		if (status == Active || (strcmp(argv[1], "-include_logically_deleted_records") == 0 && status == LogicalyDeleted))
+		{
+			// If the record is physically on the master file
+			// then get the vector of field tags.
+			
+			// 1) Repetitive fields have the same tag and are stored in
+			//    a single field but are separated by the "%" char
+			// 2) Subfields are separated by "^"letter (^a ^b ^c ...)
+			//
+			// 3) Terms or Phrases between "<>" are terms/Phrases to 
+			//    index
+			std::vector<int> vf = mfr.GetFieldTags();
+			std::cout << "----------" << std::endl;
+			  //				      << "mfn=" << i  
+				// 	  << " nvf=" << vf.size() << std::endl;
+
+			for (int j=0; j<vf.size(); j++)
+			{
+				std::string stemp;
+				// Special case when tag is <=0
+				if (vf[j]<=0 || vf[j]>SHRT_MAX)
+					continue;
+				// Extract the field with tag contained into vf[j]
+				bool rc = mfr.GetField(vf[j], stemp);
+				if (rc)
+				{
+					std::cout << "tag=" << vf[j]
+					          << " data=" << stemp << std::endl;
+				}
+			}
+
+		}
+		else
+			continue;
+		// PausePrg();
+
+	}
+	return 0;
+}
+
Index: /gsdl/stable/build-src/packages/isis-gdl/IsisTypes.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/IsisTypes.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/IsisTypes.h	(revision 20131)
@@ -0,0 +1,98 @@
+/**********************************************************************
+ *
+ * IsisTypes.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+///////////////////////////////////////////////////////////////////////////////
+//  isisType.h 
+
+
+#ifndef __ISIS_TYPE_H__
+#define __ISIS_TYPE_H__
+
+#include "DLLCode.h"
+
+#ifdef __USE_ISOC99 // get double_t type from math.h
+#include <math.h>
+#endif
+namespace isis
+{
+
+
+// ----------------------------------------
+// Type definitions common to all platforms
+// ----------------------------------------
+typedef char            int8_t;    // 8-bit signed value
+typedef unsigned char   uint8_t;   // 8-bit unsigned value
+typedef int             int32_t;   // Word size (4 bytes)
+typedef unsigned int    uint32_t;  // Unsigned word size (4 bytes)
+typedef long            long32_t;  // Long word (4 bytes)
+typedef unsigned long   ulong32_t; // Unsigned long word (4 bytes)
+typedef short           int16_t;   // short word (2 bytes)
+typedef unsigned short  uint16_t;  // Unsigned short word (2 bytes)
+#ifndef __USE_ISOC99 // gnu lic math.h has a double_t
+typedef double          double_t;  // Double precision floating point (8 bytes)
+#endif
+
+
+// --------------------------------------------------------------
+// Platform/compiler specific INT64 types
+// --------------------------------------------------------------
+#if defined (__64_BIT_FILE_SYSTEM__)
+#include "TYPES64.H" 
+#endif
+} // namespace isis
+
+namespace isis
+{
+    typedef  isis::int16_t  db_t;
+    typedef  isis::int16_t  server_t;
+    typedef  isis::int16_t  IsisClientId;
+    typedef  isis::uint32_t mfn_t;
+}
+// typedef char            int8_t;    // 8-bit signed value
+typedef unsigned char   uint8_t;   // 8-bit unsigned value
+typedef int             int32_t;   // Word size (4 bytes)
+typedef unsigned int    uint32_t;  // Unsigned word size (4 bytes)
+typedef long            long32_t;  // Long word (4 bytes)
+typedef unsigned long   ulong32_t; // Unsigned long word (4 bytes)
+typedef short           int16_t;   // short word (2 bytes)
+typedef unsigned short  uint16_t;  // Unsigned short word (2 bytes)
+#ifndef __USE_ISOC99 // gnu lic math.h has a double_t
+typedef double     double_t;  // Double precision floating point (8 bytes) // ****
+#endif
+
+typedef uint32_t        xrf_page_no_t;
+
+typedef uint32_t        mst_page_no_t;
+typedef uint16_t        mst_offset_t;
+typedef uint32_t        mfn_t;
+typedef uint32_t        mfrl_t;
+
+typedef isis::uint32_t file_size_t;
+
+
+#endif // __ISIS_TYPE_H__
+
+
+
Index: /gsdl/stable/build-src/packages/isis-gdl/IsisUtil.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/IsisUtil.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/IsisUtil.cpp	(revision 20131)
@@ -0,0 +1,183 @@
+/**********************************************************************
+ *
+ * IsisUtil.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "stdafx.h"
+#include "IsisUtil.h" 
+#include <algorithm>
+
+
+//---------------------------------------------------------------------------------
+// bool RepFieldSep(TCHAR c)
+//
+// This function is a predicate that takes a TCHAR and returns a value that indicates
+// if that TCHAR is a repeteable field separator.
+//----------------------------------------------------------------------------------
+bool RepFieldSep(char c)
+{
+	return (c == SYSRSEP);
+}
+
+//--------------------------------------------------------------------------------
+// vector<string> SplitOccurences(const cstring& s)
+//
+// This function takes as input a string which contains a field and return a 
+// vector<string> which will contain an entry for each field occurence.
+//--------------------------------------------------------------------------------
+std::vector<cstring> SplitOccurences(const cstring& s)
+{
+	typedef cstring::const_iterator iter;
+	std::vector<cstring> ret;
+
+	iter i = s.begin();
+	//TRACE("\ni=%s",i);
+	while (i != s.end())
+	{
+		// find end of occurence
+		iter j = std::find_if(i,s.end(),RepFieldSep);
+
+		// copy the characters in [i, j]
+		ret.push_back(cstring(i, j));
+		//TRACE("\ni=%s j=%s string(i,j)=%s", i, j, string(i,j).c_str());
+
+		i = j;
+		if (j != s.end())
+		    i++;
+	}
+	return ret;
+}
+
+
+bool WSubFieldSep(WCHAR c)
+{
+	return (c == SUBFIELD_SEP);
+}
+
+//--------------------------------------------------------------------------------
+// vector<cstring> SplitSubfields(const cstring& s, TCHAR sc)
+//
+// This function takes as input a string which contains a field and return a 
+// vector<string> which will contain an entry for each subfield occurrence.
+//--------------------------------------------------------------------------------
+std::vector<cstring> SplitSubfields(const cstring& s, TCHAR sc/*=0*/)
+{
+	typedef cstring::const_iterator iter;
+	std::vector<cstring> ret;
+
+	iter i= s.begin();
+	iter j;
+	while (i < s.end())
+	{
+		// Look for subfield separator (^)
+		iter k =  std::find_if(i ,s.end(),WSubFieldSep);
+		if (k == s.end())
+		{
+			j = s.end(); // separator not found
+		}
+		else
+		{
+			// Special case when field is terminated by "^x" or "^"
+			if (k==s.end()-1 || k==s.end()-2)
+				break;
+			i = k + 2;  // separator found, skip next char
+			assert(i<s.end());
+			j = std::find_if(i ,s.end() ,WSubFieldSep);
+		}
+		ret.push_back(cstring(i, j));
+		i = j;
+	}
+	return ret;
+}
+
+
+//--------------------------------------------------------------------------------
+// vector<string> SplitOccurences(const awstring& s)
+//
+// This function takes as input a string which contains a field and return a 
+// vector<string> which will contain an entry for each field occurence.
+//--------------------------------------------------------------------------------
+//  std::vector<awstring> SplitOccurences(const awstring& s)
+//  {
+//  	typedef awstring::const_iterator iter;
+//  	std::vector<awstring> ret;
+
+//  	iter i = s.begin();
+//  	//TRACE("\ni=%s",i);
+//  	while (i != s.end())
+//  	{
+//  		// find end of occurence
+//  		iter j = std::find_if(i,s.end(),RepFieldSep);
+
+//  		// copy the characters in [i, j]
+//  		ret.push_back(awstring(i, j));
+//  		//TRACE("\ni=%s j=%s string(i,j)=%s", i, j, string(i,j).c_str());
+
+//  		i = j;
+//  		if (j != s.end())
+//  		    i++;
+//  	}
+//  	return ret;
+//  }
+
+
+bool SubFieldSep(TCHAR c)
+{
+	return (c == SUBFIELD_SEP);
+}
+
+//--------------------------------------------------------------------------------
+// vector<awstring> SplitSubfields(const awstring& s, TCHAR sc)
+//
+// This function takes as input a string which contains a field and return a 
+// vector<string> which will contain an entry for each subfield occurrence.
+//--------------------------------------------------------------------------------
+//  std::vector<awstring> SplitSubfields(const awstring& s, TCHAR sc/*=0*/)
+//  {
+//  	typedef awstring::const_iterator iter;
+//  	std::vector<awstring> ret;
+
+//  	iter i = s.begin();
+//  	//TRACE("\ni=%s",i);
+//  	bool found=false;
+//  	while (i != s.end())
+//  	{
+//  		// find index of subfield separator (^)
+//  		iter j = std::find_if(i,s.end(),SubFieldSep);
+//  		if (found && j<s.end()-1)
+//  		{
+//  		    // copy the characters in [i, j]
+//  			ret.push_back(awstring(i+1, j));
+//  		}
+//  		if (sc==0 || s.at(j-s.begin()+1)==sc)
+//  		    found = true;
+//  		else
+//  		    found = false;
+
+
+//  		i = j+1;
+//  		if (j != s.end())
+//  		    i++;
+//  	}
+//  	return ret;
+//  }
Index: /gsdl/stable/build-src/packages/isis-gdl/IsisUtil.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/IsisUtil.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/IsisUtil.h	(revision 20131)
@@ -0,0 +1,35 @@
+/**********************************************************************
+ *
+ * IsisUtil.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef __ISIS_UTIL__
+#define __ISIS_UTIL__
+#include <vector>
+#include <string>
+std::vector<cstring> SplitOccurences(const cstring &s);
+// std::vector<awstring> SplitOccurences(const awstring &s);
+
+std::vector<cstring> SplitSubfields(const cstring &s, TCHAR sc=0);
+// std::vector<awstring> SplitSubfields(const awstring &s, TCHAR sc=0);
+#endif // __ISIS_UTIL_
Index: /gsdl/stable/build-src/packages/isis-gdl/MFFile.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/MFFile.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/MFFile.cpp	(revision 20131)
@@ -0,0 +1,479 @@
+/**********************************************************************
+ *
+ * MFFile.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////
+// MfFile.cpp : Master file object methods using blocked I/O
+//
+////////////////////////////////////////////////////////////
+#include "stdafx.h"
+#include "IsisDb.h"
+#include "Checking.h"
+
+
+
+//---------------------------------------------------------------------------------- 
+// MfFile::MfFile() :
+//
+// Constructor, makes a Masterfile object that isn't connected to a file
+//---------------------------------------------------------------------------------- 
+MfFile::MfFile() : BlkFile(), hdr_created_(false), nextaddr_(MFCTLLEN)
+{
+    lastWrittenBlock_ = -1;
+}
+ 
+//----------------------------------------------------------------------------------
+// int MfFile::OpenMf(const TCHAR *fname, 
+//                    FileSystem::AccessMode mode /* = FileSystem::FILE_READWRITE */)
+//
+// Opens a Masterfile object
+//---------------------------------------------------------------------------------- 
+int MfFile::OpenMf(const TCHAR *fname, FileSystem::AccessMode mode
+				                              /* = FileSystem::FILE_READWRITE */)
+{
+  TCHAR mstFileName[_MAX_PATH];
+  _tcscpy(mstFileName, fname);
+
+  if (!CFileBase::Exists(mstFileName)) {
+    mstFileName[strlen(mstFileName) - 3] = 'M';
+    mstFileName[strlen(mstFileName) - 2] = 'S';
+    mstFileName[strlen(mstFileName) - 1] = 'T';
+  }
+
+	int rc;
+	try
+	{
+	    rc = CFileBase::Open(mstFileName, mode);
+		hdr_created_ = true;
+	    ReadMfHdr();
+		PrintMfHdr();
+		Checking::CheckMfHeader(mstFileName, mfh_);
+	}
+	catch (CFileBaseException e)
+	{
+        throw CIsisDbException(ISIS_MF_OPEN_ERROR, __FILE__, __LINE__);
+	}
+    return rc;
+}
+ 
+//----------------------------------------------------------------------------------
+// int MfFile::createMf(const TCHAR *fname, int  type)
+//
+// Creates a Masterfile object
+//---------------------------------------------------------------------------------- 
+int MfFile::CreateMf(const TCHAR *fname, int  type)
+{
+    return 0;
+}
+ 
+//////////////////////////////
+MfFile::~MfFile()
+{
+}
+ 
+//----------------------------------------------------------------------------------
+// void  MfFile::ReadMfRecord(long mfb, int mfp, MfRecord &m)
+//
+// Reads the master file record beginning at address (mfb,mfp) into m
+//----------------------------------------------------------------------------------
+bool  MfFile::ReadMfRecord(long mfb, int mfp, MfRecord &m)
+{
+	return m.Read(*this, mfb, mfp);
+}
+
+//-------------------------------------------------------------------------------
+//  void WriteMfRecord(long mfb, int mfp, MfRecord &m)
+//
+//  Helper protected method, which writes the Master file record m at address 
+//  (mfb, mfp)   mfb (1:MAXMFB),   mfp (0: MFBLKSIZE)
+//-------------------------------------------------------------------------------
+void  MfFile::WriteMfRecord(long mfb, int mfp, MfRecord &m)
+{
+	m.Write(*this, mfb, mfp);
+} 
+
+
+//--------------------------------------------------------------------------------
+// void CreateMfRecord(MfRecord &m, long &mfb, int &mfp)
+//
+//  Create a new record. The MFN to be assigned is obtained from the field nxtmfn_
+//  in the Master file header. Then addMfRecord is called for adding the record
+//  at the end of the master file, at the position indicated by the fields
+//  nxtmfb_/nxtmfb_. The next MFN to be assigned is updated.
+//
+//--------------------------------------------------------------------------------
+void  MfFile::CreateMfRecord(MfRecord &m, long &mfb, int &mfp)
+{
+}
+
+void  MfFile::AppendNewBlock()
+{
+}
+
+//--------------------------------------------------------------------------------
+// void AddMfRecord(MfRecord &m, long &mfb, int &mfp)
+//
+// Add the record at the end of the master file, at the position indicated by
+// the fields nxtmfb_/nxtmfp_. (nxtmfp_ is in range [1:MFBLKSIZE])
+// Return the address where the record was stored into mfb & mfp
+//--------------------------------------------------------------------------------
+void  MfFile::AddMfRecord(MfRecord &m, long &mfb, int &mfp)
+{
+}
+ 
+ 
+//--------------------------------------------------------------------------------
+// void UpdateMfRecord(MfRecord &m, long &mfb, int &mfp)
+//
+// Update a Master file record.If possible, i.e. if the record length was not
+// increased, the record is written back at its original location otherwise it is
+// written at the end of the file. In both cases, MFBWB/MFBWP are not changed.
+// 
+//--------------------------------------------------------------------------------
+void  MfFile::UpdateMfRecord(MfRecord &m, long &mfb, int &mfp)
+{
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////
+// methods for dumping file and record headers
+
+ 
+void MfFile::PrintMfHdr(SMfHeader &h)
+// Prints header record
+{
+}
+ 
+//////////////////////////////
+ 
+void MfFile::PrintMfRecord(MfRecord &m)
+// Print a master file record structure
+{
+	m.Dump();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Methods for accessing records directly
+ 
+//----------------------------------------------------------------------------------
+// void MfFile::ReadMfRecord(long daddr, MfRecord &m)
+//
+// Reads a master file record into the master record object m.
+// Non blocked version
+//----------------------------------------------------------------------------------
+void MfFile::ReadMfRecord(long daddr, MfRecord &m)
+{
+	m.Clear();
+    ReadLeader(daddr, m);       // Read record leader (Leader is added to record)
+	m.ExtractSubLeader();
+    
+	//TRACE("\nReadMfRecord -- mfn=%ld mfrl=%d", m.GetMfn(), m.GetMfrl());
+	//assert(m.CheckIntegrity());
+	int mfrl = m.GetMfrl();
+	if (mfrl < 0) mfrl = -mfrl; 	// mfrl can be negative!!!!
+	char* p = new char[mfrl];
+    CFileBase::Fetch(p, mfrl, daddr);
+	m.AddToRecord(p+GetLeaderSize(), mfrl-GetLeaderSize());
+	delete[] p;
+    nextaddr_ += mfrl;
+ 	int mfb = nextaddr_ / MFBLKSIZE + 1;
+    int mfp = nextaddr_ % MFBLKSIZE;
+    if (mfp > MFBLKSIZE - GetMinLeaderSize())
+	{
+		mfb++;
+	    mfp = 0;
+	}
+	nextaddr_ = (mfb-1)*MFBLKSIZE + mfp;
+	m.DecomposeRecord();
+}
+
+//---------------------------------------------------------------------------------
+// void  MfFile::WriteMfRecord(long daddr, MfRecord &m)
+//
+// Stores Master record object m to disk address daddr
+// Non blocked version
+//---------------------------------------------------------------------------------
+void  MfFile::WriteMfRecord(long daddr, MfRecord &m)
+{
+}
+/////////////////////////////////////////////////////////////////////////////////////
+// Master file locking methods
+
+
+ 
+//-----------------------------------------------------------------------------------
+// void MfFile::InitFileLockHdr(SMfLockHeader &hdr)
+//
+// Initialize a the lock header for a newly constructed file lock header.
+//-----------------------------------------------------------------------------------
+void MfFile::InitFileLockHdr(SMfLockHeader &hdr)
+{
+	hdr.lockProtect_ = (uint32_t)0;
+	hdr.readLock_    = (uint32_t)0;
+	hdr.writeLock_   = (uint32_t)0;
+}
+
+//-----------------------------------------------------------------------------------
+// FileError MfFile::WriteFileLockHdr(const SMfLockHeader &hdr)
+//
+// Write the lock header to the file. 
+// Returns a non-zero value to indicate an error condition or zero if successful.
+//-----------------------------------------------------------------------------------
+FileError MfFile::WriteFileLockHdr(const SMfLockHeader &hdr)
+{
+	
+	return CFileBase::Store(&hdr, sizeof(SMfLockHeader), sizeof(SMfHeader));
+}
+
+//-----------------------------------------------------------------------------------
+// FileError MfFile::ReadFileLockHdr(SMfLockHeader &hdr)
+//
+// Read the lock header from the file.
+// Returns a non-zero value to indicate an error condition or zero if successful.
+//-----------------------------------------------------------------------------------
+FileError MfFile::ReadFileLockHdr(SMfLockHeader &hdr)
+{
+	
+	return CFileBase::Fetch(&hdr, sizeof(SMfLockHeader), sizeof(SMfHeader));
+}
+
+//-----------------------------------------------------------------------------------
+// int MfFile::LockFile(CFileMgrLockType l_type) 
+//
+// Lock the file and set the lock access mode to shared or exclusive.
+// Returns a non-zero value if the file cannot be locked or the lock variable cannot
+// be changed because it is exclusive or another thread is currently updating it. 
+//-----------------------------------------------------------------------------------
+int MfFile::LockFile(MfLockType l_type) 
+{
+	// Read the file lock to ensure that this file has a lock header
+	// and to keep the header in sync during multiple file access.
+	SMfLockHeader lock_header;
+	if (ReadFileLockHdr(lock_header) != FILE_NO_ERROR)
+		return fileError_;
+	
+	// Cannot modifiy this lock until the thread holding it releases the
+	// lock header.
+	if (lock_header.lockProtect_ != 0)
+	{
+		fileError_ = ISIS_MFLOCK_ACCESS_ERROR;
+#ifdef __CPP_EXCEPTIONS__
+		throw CFileBaseException(fileError_);
+#else
+		return fileError_;
+#endif
+	}
+	
+	switch (l_type)
+	{
+		case MF_WRITE_LOCK :
+			// Cannot obtain an exclusive lock until all the threads in the
+			// read lock queue have finished
+			if ((lock_header.readLock_ != 0) || 
+				(lock_header.writeLock_ != 0))
+			{
+				fileError_ = ISIS_MFLOCK_ERROR;
+	#ifdef __CPP_EXCEPTIONS__
+				throw CFileBaseException(fileError_);
+	#else
+				return fileError_;
+	#endif
+			}
+			else 
+			{
+				lock_header.writeLock_ = 1;
+			}
+			
+			lock_header.lockProtect_ = 1;
+			if (CFileBase::Store(&lock_header.lockProtect_, sizeof(uint32_t),
+				sizeof(SMfHeader)) != FILE_NO_ERROR)
+				return fileError_;
+			
+			// Skip over the read lock member
+			SeekTo(sizeof(SMfHeader) + (sizeof(uint32_t) * 2));
+			if (CFileBase::Store(&lock_header.writeLock_, sizeof(uint32_t)) !=
+				FILE_NO_ERROR)
+				return fileError_;
+			
+			lock_header.lockProtect_ = (uint32_t)0;
+			if (CFileBase::Store(&lock_header.lockProtect_, sizeof(uint32_t),
+				sizeof(SMfHeader)) != FILE_NO_ERROR)
+				return fileError_;
+			break;
+			
+		case MF_READ_LOCK :
+			// This lock is exclusively owned and cannot be read locked
+			// until the thread holding this lock release the exclusive lock.
+			if (lock_header.writeLock_ == 1)
+			{
+				fileError_ = ISIS_MFLOCK_ERROR;
+	#ifdef __CPP_EXCEPTIONS__
+				throw CFileBaseException(fileError_);
+	#else
+				return fileError_;
+	#endif
+			}
+			
+			if (lock_header.readLock_ < 0xFFFFFFFF)
+			{
+				lock_header.readLock_++;
+			}
+			else 
+			{
+				fileError_ = ISIS_MFLOCK_ERROR;
+	#ifdef __CPP_EXCEPTIONS__
+				throw CFileBaseException(fileError_);
+	#else
+				return fileError_;
+	#endif
+			}
+			
+			lock_header.lockProtect_ = 1;
+			if (CFileBase::Store(&lock_header.lockProtect_, sizeof(uint32_t),
+				sizeof(SMfHeader)) != FILE_NO_ERROR)
+				return fileError_;
+			
+			if (CFileBase::Store(&lock_header.readLock_, sizeof(uint32_t)) !=
+				FILE_NO_ERROR)
+				return fileError_; 
+			
+			lock_header.lockProtect_ = (uint32_t)0;
+			if (CFileBase::Store(&lock_header.lockProtect_, sizeof(uint32_t),
+				sizeof(SMfHeader)) != FILE_NO_ERROR)
+				return fileError_;
+			break;
+			
+		default: // Invalid lock type specified
+			fileError_ =  ISIS_INVALID_LOCK_TYPE;
+	#ifdef __CPP_EXCEPTIONS__
+			throw CFileBaseException(fileError_);
+	#else
+			return fileError_;
+	#endif
+	}
+	
+	return fileError_ = fileError_ = FILE_NO_ERROR;
+}
+
+//-----------------------------------------------------------------------------------
+// int MfFile::UnlockFile(CFileMgrLockType l_type)
+//
+// Unlock the file. Returns a non-zero value if the file cannot be unlocked or the
+// lock variable cannot be changed because it is exclusive or another thread is
+// currently updating it. 
+//-----------------------------------------------------------------------------------
+int MfFile::UnlockFile(MfLockType l_type)
+{
+	
+	// Read the file lock to ensure that this file has a lock header
+	// and to keep the header in sync during multiple file access.
+	SMfLockHeader lock_header;
+	if (ReadFileLockHdr(lock_header) != FILE_NO_ERROR)
+		return fileError_;
+	
+	// Cannot modifiy this lock until the thread holding it releases the
+	// lock header.
+	if (lock_header.lockProtect_ != 0)
+	{
+		fileError_ = ISIS_MFLOCK_ACCESS_ERROR;
+#ifdef __CPP_EXCEPTIONS__
+		throw CFileBaseException(fileError_);
+#else
+		return fileError_;
+#endif
+	}
+	
+	switch (l_type)
+	{
+		case MF_WRITE_LOCK :
+			if (lock_header.writeLock_ == 0)
+				return FILE_NO_ERROR;
+			else
+				lock_header.writeLock_ = 0;
+			
+			lock_header.lockProtect_ = 1;
+			if (CFileBase::Store(&lock_header.lockProtect_, sizeof(uint32_t),
+				sizeof(SMfHeader)) != FILE_NO_ERROR)
+				return fileError_;
+			
+			// Skip over the read lock member
+			SeekTo(sizeof(SMfHeader) + (sizeof(uint32_t) * 2));
+			if (CFileBase::Store(&lock_header.writeLock_, sizeof(uint32_t)) !=
+				FILE_NO_ERROR)
+				return fileError_;
+			
+			lock_header.lockProtect_ = (uint32_t)0;
+			if (CFileBase::Store(&lock_header.lockProtect_, sizeof(uint32_t),
+				sizeof(SMfHeader)) != FILE_NO_ERROR)
+				return fileError_;
+			break;
+			
+		case MF_READ_LOCK :
+			if (lock_header.readLock_ == 0)      // This record is not locked
+				return fileError_ = FILE_NO_ERROR;
+			else if (lock_header.readLock_  > 0) // Prevent read lock rollover
+				lock_header.readLock_--;
+			else
+				lock_header.readLock_ = 0;
+			
+			lock_header.lockProtect_ = 1;
+			if (CFileBase::Store(&lock_header.lockProtect_, sizeof(uint32_t),
+				sizeof(SMfHeader)) != FILE_NO_ERROR)
+				return fileError_;
+			
+			if (CFileBase::Store(&lock_header.readLock_, sizeof(uint32_t)) !=
+				FILE_NO_ERROR)
+				return fileError_; 
+			
+			lock_header.lockProtect_ = (uint32_t)0;
+			if (CFileBase::Store(&lock_header.lockProtect_, sizeof(uint32_t),
+				sizeof(SMfHeader)) != FILE_NO_ERROR)
+				return fileError_;
+			break;
+			
+		default: // Invalid lock type specified
+			fileError_ =  FMGR_INVALID_LOCK_TYPE;
+	#ifdef __CPP_EXCEPTIONS__
+			throw CFileBaseException(fileError_);
+	#else
+			return fileError_;
+	#endif
+	}
+	
+	return fileError_ = fileError_ = FILE_NO_ERROR;
+}
+
+//-----------------------------------------------------------------------------------
+// FileError MfFile::ResetFileLock()
+//
+// Reset the file's lock header. This function will clear all the file lock fields
+// without testing the lock or the lock protect. Returns a non-zero value to indicate
+// an error condition or zero if successful.
+//-----------------------------------------------------------------------------------
+FileError MfFile::ResetFileLock()
+{
+	SMfLockHeader lock_header;
+	InitFileLockHdr(lock_header);
+	return WriteFileLockHdr(lock_header);
+}
Index: /gsdl/stable/build-src/packages/isis-gdl/MFFile.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/MFFile.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/MFFile.h	(revision 20131)
@@ -0,0 +1,338 @@
+/**********************************************************************
+ *
+ * MFFile.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////
+// MFFILE.H: Class definition for blocked I/O on the master
+//           file
+////////////////////////////////////////////////////////////
+ 
+#ifndef _MFFILE_H_
+#define _MFFILE_H_
+#ifndef _MASTER_H_
+#include "Master.h"
+#endif
+#ifndef _BLKFILE_H_
+#include "BlkFile.h"
+#endif
+#include <string>
+
+enum MfLockType
+{
+	MF_READ_LOCK,
+	MF_WRITE_LOCK
+};
+
+struct SMfLockHeader
+{
+	long lockProtect_; // Serialize access to the file lock members
+	long readLock_;    // Shared (or read_only) file lock
+	long writeLock_;   // Exclusive (or write-only) file lock
+
+	SMfLockHeader() : lockProtect_(0), readLock_(0), writeLock_(0)
+	{}
+};
+
+enum  { USERMST=0, MSGMST=1 };
+//  binary  hex
+//  ------  ---
+//  0000    0
+//  0001    1
+//  0010    2
+//  0011    3
+
+class MfAddress
+{
+private:
+	long  m_mfb;
+	short m_mfp;
+	char  m_status;
+public:
+	MfAddress() { m_status = 0x00; }
+	MfAddress(long mfb, short mfp)
+	{ ASSERT(mfb>0); ASSERT(mfp>=0); m_mfb = mfb; m_mfp = mfp; m_status = 0x03; }
+
+	long getMfb()          { ASSERT(m_status & 0x01); return m_mfb; }
+	short getMfp()         { ASSERT(m_status & 0x02); return m_mfp; } 
+
+	void setMfb(long mfb)  { ASSERT(mfb>0);  m_mfb = mfb; m_status |= 0x01; }
+	void setMfp(short mfp) { ASSERT(mfp>=0); m_mfp = mfp; m_status |= 0x02; }
+	bool isValid()         { return (m_status == 0x03); }
+};
+ 
+/////////////////////////////////////////////////////////////////////////
+// Master File header record aggregate structure
+//
+struct  SMfHeader 
+{
+   ISIS_LONG   ctlmfn_;    // Always 0
+   ISIS_LONG   nxtmfn_;    // MFN to be assigned to next record created
+   ISIS_LONG   nxtmfb_;    // Last block number allocated (1st is 1)
+   ISIS_INT    nxtmfp_;    // Offset to next available position in last block (1:MFBLKSIZE)
+   ISIS_INT    mftype_;    // Type of master file (USERMST or MSGMST)
+   ISIS_LONG   reccnt_;
+   ISIS_LONG   mfcxx1_;
+   ISIS_LONG   mfcxx2_;
+   ISIS_LONG   mfcxx3_;
+public:
+   SMfHeader(const char *dbname="");
+   ~SMfHeader()                 { }
+};
+ 
+//--------------------------------------------------------------------------
+// SMfHeader::SMfHeader(const char *dbname /* ="" */)
+//
+// Default constructor, initializes the Master file header to default values
+//--------------------------------------------------------------------------
+inline SMfHeader::SMfHeader(const char *dbname /* ="" */)
+{
+   ctlmfn_ = 0;
+   nxtmfn_ = 1L;
+   nxtmfb_ = 1L;
+   nxtmfp_ = MFCTLLEN+1;
+   mftype_ = USERMST;
+   reccnt_ = mfcxx1_=mfcxx2_=mfcxx3_=0;
+}
+ 
+//////////////////////
+// Master file class
+//
+class MfFile : public BlkFile  
+{
+   friend class IsisDb;
+   friend class MfRecord;
+
+protected:
+   SMfHeader mfh_;            // Header structure
+   long nextaddr_;            // Address of next record
+   char buf_[MFBLKSIZE];      // Buffer to hold 1 Master File block
+   bool hdr_created_;         // True if 1st block exists
+   int  fileError_;
+   long lastWrittenBlock_;
+
+protected:  
+   void WriteMfRecord(long mfb, int mfp, MfRecord &r);
+   void AppendNewBlock();
+
+public:
+   void setNextMfn(long mfn)       // Set MFN to be assigned to next record created
+   { mfh_.nxtmfn_ = mfn; }
+
+protected:
+   void setNextMfb(long nxtmfb_)  // Set last block number allocated (1st is 1)
+   { mfh_.nxtmfb_ = nxtmfb_; }
+   void setNextMfp(int nxtmfp_)   // Set offset to next available position in last block
+   { mfh_.nxtmfp_ = nxtmfp_; }
+   int setm_mftype(int mftype_)     // Set type of master file (USERMST or MSGMST)
+   { mfh_.mftype_ = mftype_; }     
+   virtual void ReadBlk(void* d, long b)  { BlkFile::ReadBlk(d, b);  }
+   virtual void WriteBlk(void* d, long b) { BlkFile::WriteBlk(d, b); }
+   void ReadMfHdr(SMfHeader &h);
+   void ReadMfHdr();
+   void WriteMfHdr(SMfHeader &h);
+   void WriteMfHdr();
+   void SetLastWrittenBlock(long b) { lastWrittenBlock_ = b; }
+public:
+   MfFile();
+   virtual ~MfFile();
+
+   int  OpenMf(const TCHAR* name, FileSystem::AccessMode mode = FileSystem::FILE_READWRITE);
+   int  CreateMf(const TCHAR* name, int MSTtype = USERMST);
+   void CloseMf() { if (ReadyForWriting()) WriteMfHdr(); Close(); }
+
+   // Accessors for the Master File Header
+   long GetNextMfn()        // Get MFN to be assigned to next record created
+   { return mfh_.nxtmfn_; }
+   long GetNextMfb()        // Get last block number allocated (1st is 1)
+   { return mfh_.nxtmfb_; }
+   int GetNextMfp()         // Get offset to next available position in last block
+   { return mfh_.nxtmfp_; }
+   int GetMftype()          // Get type of master file (USERMST or MSGMST)
+   { return mfh_.mftype_; }   
+   SMfHeader& GetSMfHeader() { return mfh_; }
+
+
+   void CreateMfRecord(MfRecord &m, long &mfb, int &mfp);
+   void AddMfRecord(MfRecord &m, long &mfb, int &mfp);
+   void UpdateMfRecord(MfRecord &m, long &mfb, int &mfp);
+   bool ReadMfRecord(long mfb, int mfp, MfRecord &r);
+
+   void ReadMfRecord(long addr, MfRecord &r);
+   void WriteMfRecord(long addr, MfRecord &r);
+   void RewindMf();
+   bool ReadMfNext(MfRecord &r);
+   void WriteMfNext(MfRecord &r);
+   void ReadLeader(long daddr, MfRecord& m)
+   {
+	   m.ReadLeader(*this, daddr);
+   }
+
+
+   void LockMfHdr();
+   void UnlockMfHdr();
+   void LockMfr(long mfn);
+   void UnlockMfr(long mfn);
+
+public: // File lock functions
+	void InitFileLockHdr(SMfLockHeader &hdr);
+	FileError ResetFileLock();
+	FileError WriteFileLockHdr(const SMfLockHeader &hdr);
+	FileError ReadFileLockHdr(SMfLockHeader &hdr);
+	int LockFile(MfLockType l_type = MF_WRITE_LOCK);
+	int UnlockFile(MfLockType l_type = MF_WRITE_LOCK);
+
+
+   void PrintMfRecord(MfRecord &r);
+   void PrintMfHdr(SMfHeader &h);
+   void PrintMfHdr();
+};
+ 
+
+class CMfIterator
+{
+	const MfFile& m_mf;
+	long cur;
+public:
+	CMfIterator(const MfFile& mf) : m_mf(mf) { }
+
+	bool More() const;
+	void Advance();
+
+	MfRecord Current() 
+	{ 
+		MfRecord mfr(NULL);
+		
+		return mfr;
+	}
+};
+
+ 
+//////////////////////////////
+ 
+inline void  MfFile::LockMfHdr()
+//  Locks the master file header record
+{
+	double_t dwPos   = 0;
+	double_t dwCount = sizeof(SMfHeader);
+	//CFile::LockRange(dwPos, dwCount);
+}
+ 
+//////////////////////////////
+ 
+inline void MfFile::UnlockMfHdr()
+//  Unlocks the master file header record
+{
+	double_t dwPos   = 0;
+	double_t dwCount = sizeof(SMfHeader);
+	//CFile::UnlockRange(dwPos, dwCount);
+}
+ 
+//////////////////////////////
+
+inline void MfFile::ReadMfHdr()
+//  Reads the master file header record
+{
+   ReadBlk(buf_, 1L);
+   TRACE(_T("\nsizeof(SMfHeader)=%d"), sizeof(SMfHeader));
+   ::MoveMemory(&mfh_, buf_, sizeof(SMfHeader));
+
+   fix_endianness(mfh_.ctlmfn_);
+   fix_endianness(mfh_.nxtmfn_);
+   fix_endianness(mfh_.nxtmfb_);
+   fix_endianness(mfh_.nxtmfp_);
+   fix_endianness(mfh_.mftype_);
+   fix_endianness(mfh_.reccnt_);
+   fix_endianness(mfh_.mfcxx1_);
+   fix_endianness(mfh_.mfcxx2_);
+   fix_endianness(mfh_.mfcxx3_);
+}
+ 
+//////////////////////////////
+ 
+inline void MfFile::WriteMfHdr()
+//  Updates the master file header record
+{
+    if (hdr_created_) 
+	   ReadBlk(buf_, 1L);
+    TRACE(_T("\nsizeof(SMfHeader)=%d"), sizeof(SMfHeader));
+    ::MoveMemory(buf_, &mfh_, sizeof(SMfHeader));
+    WriteBlk(buf_, 1L);
+}
+ 
+ 
+//////////////////////////////
+ 
+inline void MfFile::ReadMfHdr(SMfHeader &h)
+//  Reads the master file header record
+{
+   ReadBlk(buf_, 1L);
+   ::MoveMemory(&h, buf_, sizeof(SMfHeader));
+
+   fix_endianness(h.ctlmfn_);
+   fix_endianness(h.nxtmfn_);
+   fix_endianness(h.nxtmfb_);
+   fix_endianness(h.nxtmfp_);
+   fix_endianness(h.mftype_);
+   fix_endianness(h.reccnt_);
+   fix_endianness(h.mfcxx1_);
+   fix_endianness(h.mfcxx2_);
+   fix_endianness(h.mfcxx3_);
+}
+ 
+//////////////////////////////
+ 
+inline void MfFile::WriteMfHdr(SMfHeader &h)
+//  Updates the master file header record
+{
+   if (hdr_created_)
+	   ReadBlk(buf_, 1L);
+   ::MoveMemory(buf_, &h, sizeof(SMfHeader));
+   WriteBlk(buf_, 1L);
+}
+ 
+ 
+inline void MfFile::PrintMfHdr()
+{
+   PrintMfHdr(mfh_);
+}
+ 
+//////////////////////////////
+ 
+inline bool MfFile::ReadMfNext(MfRecord &r)
+// Reads the next physically record
+{
+	if (nextaddr_ >= CFileBase::FileSize(file_name))
+	    return false;
+   ReadMfRecord(nextaddr_, r);
+   return true;
+}
+ 
+//////////////////////////////
+ 
+inline void MfFile::WriteMfNext(MfRecord &r)
+// Writes physically at next position
+{
+   WriteMfRecord(nextaddr_, r);
+}
+#endif
Index: /gsdl/stable/build-src/packages/isis-gdl/Makefile.in
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/Makefile.in	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/Makefile.in	(revision 20131)
@@ -0,0 +1,33 @@
+prefix	    = @prefix@
+exec_prefix = @exec_prefix@
+bindir	    = @bindir@
+
+CXX	    = @CXX@
+CXXFLAGS    = @CXXFLAGS@
+EXEEXT	    = @EXEEXT@
+
+INSTALL     = @INSTALL@
+
+LDFLAGS     = @LDFLAGS@
+
+ISIS_OBJS   = IsisGdl.o CacheMan.o Checking.o CRC32.o Fdt.o File.o \
+              FileSystem.o IErrors.o IsisDb.o IsisUtil.o Master.o MFFile.o \
+              stdafx.o Unimarc.o XRFFile.o
+
+
+all: IsisGdl$(EXEEXT)
+
+IsisGdl$(EXEEXT): $(ISIS_OBJS)
+	$(CXX) -o IsisGdl$(EXEEXT) $(ISIS_OBJS) $(LDFLAGS)
+
+$(ISIS_OBJS) :%.o :%.cpp
+	$(CXX) -c $(CXXFLAGS) -o $@ $<
+
+install: all
+	$(INSTALL) IsisGdl$(EXEEXT) $(bindir)
+
+clean:
+	rm -f IsisGdl$(EXEEXT) $(ISIS_OBJS)
+
+distclean: clean
+	rm -f Makefile config.status config.cache config.log
Index: /gsdl/stable/build-src/packages/isis-gdl/Master.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/Master.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/Master.cpp	(revision 20131)
@@ -0,0 +1,1084 @@
+/**********************************************************************
+ *
+ * Master.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////
+//  MASTER.CPP: Master file record object methods
+//                                                                        
+////////////////////////////////////////////////////////////
+#include "stdafx.h"
+#include <iomanip>
+#include "XRFFile.h"
+#include "IsisUtil.h" 
+#include "Master.h"
+#include "MFFile.h"
+#include "IsisDb.h"
+#include "Unimarc.h"
+#include <algorithm>
+
+
+using namespace std;
+
+   
+
+char MfRecord::m_buf[MFBLKSIZE];      // Buffer to hold 1 File block
+
+
+
+/////////////////////////////////////////////////////////////////////
+// LeaderAndDirectory methods
+
+int LeaderAndDirectory::GetFieldSize()
+{
+	int field_len = 0;
+	for (int i=0; i!=nvf_; ++i)
+		field_len  += dir_[i].len_;
+	return field_len;
+}
+
+bool LeaderAndDirectory::operator==(const LeaderAndDirectory& rhs) const
+{
+    if (mfn_ != rhs.mfn_)         // Master file number
+		return false;
+    if (mfrl_ != rhs.mfrl_)       // Record length
+		return false;
+	if (mfbwb_ != rhs.mfbwb_)     // Backward pointer block number
+		return false;
+    if (mfbwp_ != rhs.mfbwp_)     // Backward pointer offset
+		return false;
+    if (base_ != rhs.base_)       // Offset to begining of variable fields
+		return false;
+    if (nvf_ != rhs.nvf_)         // Number of directory entries
+		return false;
+    if (status_ != rhs.status_)   // 1 = DELETED
+		return false;
+	for(std::vector<DirEntry>::size_type i=0; i!=nvf_; i++) // Directory
+	{
+		if (dir_[i]!=rhs.dir_[i])
+		    return false;
+	}
+    return true;
+}
+
+bool LeaderAndDirectory::operator!=(const LeaderAndDirectory& rhs) const
+{
+    if (mfn_ != rhs.mfn_)         // Master file number
+		return true;
+    if (mfrl_ != rhs.mfrl_)       // Record length
+		return true;
+	if (mfbwb_ != rhs.mfbwb_)     // Backward pointer block number
+		return true;
+    if (mfbwp_ != rhs.mfbwp_)     // Backward pointer offset
+		return true;
+    if (base_ != rhs.base_)       // Offset to begining of variable fields
+		return true;
+    if (nvf_ != rhs.nvf_)         // Number of directory entries
+		return true;
+    if (status_ != rhs.status_)   // 1 = DELETED
+		return true;
+	for(std::vector<DirEntry>::size_type i=0; i!=nvf_; i++) // Directory
+	{
+		if (dir_[i]!=rhs.dir_[i])
+		    return true;
+	}
+    return false;
+}
+//-------------------------------------------------------------------------------
+// ostream& operator<<(ostream& s, const LeaderAndDirectory& leader_directory)
+//
+// Overloaded instance of the output operator for LeaderAndDirectory objects
+//---------------------------------------------------------------------------------
+cstringstream& operator<<(cstringstream& s, const LeaderAndDirectory& leader_directory)
+{
+	s.write((char *) &leader_directory.mfn_,    sizeof(ISIS_LONG));
+	s.write((char *) &leader_directory.mfrl_,   sizeof(ISIS_INT));
+	s.write((char *) &leader_directory.mfbwb_,  sizeof(ISIS_LONG));
+	s.write((char *) &leader_directory.mfbwp_,  sizeof(ISIS_INT));
+#ifdef UNIX_BIREME
+	ISIS_INT dummy = 0;
+	s.write((char *) &dummy,   sizeof(ISIS_INT));
+#endif
+
+	s.write((char *) &leader_directory.base_,   sizeof(ISIS_INT));
+	s.write((char *) &leader_directory.nvf_,    sizeof(ISIS_INT));
+	s.write((char *) &leader_directory.status_, sizeof(ISIS_INT));
+
+	int n = leader_directory.dir_.size();
+    assert(n==leader_directory.nvf_);	
+	for(vector<DirEntry>::size_type i=0; i!=leader_directory.dir_.size(); i++)
+	{
+	     assert(leader_directory.dir_[i].tag_>0 && leader_directory.dir_[i].tag_<SHRT_MAX);
+		 DirEntry de = leader_directory.dir_[i];
+         s.write((char *) &de, GetDirEntrySize());
+	}
+	
+	return s;
+}
+
+//----------------------------------------------------------------------------------
+// istream& operator>>(istream& s, LeaderAndDirectory& leader_directory)
+//
+// Overloaded instance of the input operator for LeaderAndDirectory objects
+//----------------------------------------------------------------------------------
+cstringstream& operator>>(cstringstream& s, LeaderAndDirectory& leader_directory)
+{
+	if (!s.good()) return s;
+
+	ios::iostate err = ios::goodbit;
+	try
+	{
+		s.read((char *) &leader_directory.mfn_,    sizeof(ISIS_LONG));
+	    s.read((char *) &leader_directory.mfrl_,   sizeof(ISIS_INT));
+	    s.read((char *) &leader_directory.mfbwb_,  sizeof(ISIS_LONG));
+	    s.read((char *) &leader_directory.mfbwp_,  sizeof(ISIS_INT));
+#ifdef UNIX_BIREME
+	    ISIS_INT dummy;
+	    s.read((char *) &dummy,   sizeof(ISIS_INT));
+#endif
+	    s.read((char *) &leader_directory.base_,   sizeof(ISIS_INT));
+	    s.read((char *) &leader_directory.nvf_,    sizeof(ISIS_INT));
+	    s.read((char *) &leader_directory.status_, sizeof(ISIS_INT));
+
+	    fix_endianness(leader_directory.mfn_);
+	    fix_endianness(leader_directory.mfrl_);
+	    fix_endianness(leader_directory.mfbwb_);
+	    fix_endianness(leader_directory.mfbwp_);
+	    fix_endianness(leader_directory.base_);
+	    fix_endianness(leader_directory.nvf_);
+	    fix_endianness(leader_directory.status_);
+
+		if (!leader_directory.dir_.empty())
+			leader_directory.dir_.clear();
+
+		// Try to recover if nvf_ = 0
+		if (leader_directory.nvf_==0)
+			leader_directory.nvf_ = (leader_directory.base_ - GetLeaderSize()) / GetDirEntrySize();
+
+		if (leader_directory.nvf_>0)
+		{
+			for(vector<DirEntry>::size_type i=0; i!=leader_directory.nvf_; i++)
+			{
+				DirEntry de;
+		        s.read((char *) &de, GetDirEntrySize());
+			    fix_endianness(de.tag_);
+			    fix_endianness(de.pos_);
+			    fix_endianness(de.len_);
+			    // Don't check integrity of directory entries here
+			    leader_directory.dir_.push_back(de);
+			}
+
+		}
+	}
+	catch(bad_alloc&)
+	{
+		err |= ios::badbit;
+		ios::iostate exception_mask = s.exceptions();
+		if (  (exception_mask & ios::failbit) &&
+			!(exception_mask & ios::badbit))
+		{
+			s.setstate(err);
+		}
+		else if (exception_mask & ios::badbit)
+		{
+		  s.setstate(err);
+		  // try { s.setstate(err); }
+		  // catch( ios::failure& ) { }
+			throw;
+		
+		}
+	}
+    catch(...)
+	{
+		err |= ios::failbit;
+		ios::iostate exception_mask = s.exceptions();
+		if ( (exception_mask & ios::badbit) &&
+			(err & ios::badbit))
+		{
+			s.setstate(err);
+		}
+		else if (exception_mask & ios::failbit)
+		{
+		  s.setstate(err);
+		  // try { s.setstate(err); }
+		  // catch( ios::failure& ) { }
+			throw;
+
+		}
+	}
+
+	if (err) s.setstate(err);
+	return s;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////
+//
+
+//  void MfRecord::Copy(UMfRecord& rhs)           
+//  {
+//  	Clear();
+//  	pFdt_      = rhs.pFdt_;
+//      state_     = Record_Created;
+	
+//  	// 1 - Prepare the LeaderAndDirectory, directory, end data part
+//  	int n   = 0;
+//  	int pos = 0;
+
+//  	cstring all_fields_mb;
+//      leader_directory_.dir_.clear();	
+//  	all_fields_mb.erase();
+//  	for (vector<int>::size_type i=0; i!=rhs.tags_.size(); ++i)
+//  	{
+//  		bool bRep = false;
+//  		if (rhs.pFdt_)
+//  		{
+//  			if (rhs.pFdt_->GetEntryAt(i).rep)
+//  			   bRep = true;
+//  		}
+//  		// Get the field, all occurences combined
+//  		int tag = rhs.tags_[i];
+//  	    awstring ws;
+//  		bool rc = rhs.GetField(tag, ws);
+//  		vector<awstring> occ;
+//  		if (bRep)
+//  			vector<awstring> occ = SplitOccurences(ws);
+//  		else
+//  			occ.push_back(ws);
+//          // one entry per occurence
+//  		int nocc = occ.size();
+//  		for (vector<awstring>::size_type j=0; j!= nocc; ++j)
+//  		{
+//  			DirEntry de;
+//  			de.tag_ = tag;
+//  			de.pos_ = pos;
+//  			cstring cs; // For storing the unicode string
+//  			de.len_ = UnicodeToCodePage(occ[j], cs);
+//              leader_directory_.dir_.push_back(de);
+//  			all_fields_mb += cs;
+//  			n++;
+//  			pos += occ[j].length();
+			
+//  		}
+//  	}
+
+//  	leader_directory_.nvf_  = n;
+//  	leader_directory_.base_ = GetLeaderSize() + leader_directory_.nvf_*GetDirEntrySize();
+//  	leader_directory_.mfrl_ = ComputeMfrl();
+
+//  	// 2   - Make record
+
+//  	record_.erase(); // Empty the record
+
+//  	// Prepare the binary part, note that this part must be  independent
+//  	// of the character set.
+
+//  	cstringstream ost(std::ios::out | std::ios::binary);   
+//  	ost << leader_directory_;   // Output the LeaderAndDirectory to a string
+
+	
+//  	AddToRecord(ost.str().c_str(), ost.str().length());
+
+//  	// Here comes the part which is dependent from the character set,
+//  	// the data itself.
+//  	AddToRecord((char*)all_fields_mb.c_str(), all_fields_mb.length());
+
+//  	DecomposeRecord();
+//  }
+
+//  MfRecord::MfRecord(const UMfRecord& rhs)     // Copy constructor
+//  { 
+//     Copy(rhs);
+//  }
+
+//  MfRecord& MfRecord::operator=(const UMfRecord& rhs) // Assignment
+//  {
+//     if (&leader_directory_ != &rhs.leader_directory_)
+//     {
+//     	   Copy(rhs);
+//     }
+//     return *this;
+//  }
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Accessors
+ 
+ 
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Methods working on the in memory image of the record
+ 
+//-------------------------------------------------------------------------------
+// bool  MfRecord::GetField(int tag, string& s)
+//
+// This function takes as input a tag and will place the field into the string
+// s. It will return true if the field exists and false otherwise.
+//-------------------------------------------------------------------------------
+bool  MfRecord::GetField(int tag, ustring& s)
+{
+	PRECONDITION(tag>=0 && tag < SHRT_MAX);
+
+	map<int, ustring>::iterator it = fields_.find(tag);
+
+	bool ret = false;
+	if (it != fields_.end())
+	{
+		s   = it->second;
+		ret = true;
+	}
+	return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////
+// Modifiers, They synchronize the record structure with the internal structures
+
+
+//---------------------------------------------------------------------------------
+// AddField --- Add a field to the master record structure.
+//            
+//--------------------------------------------------------------------------------- 
+bool MfRecord::AddField(int tag, ustring& s)
+{
+	PRECONDITION(tag>=0 && tag < SHRT_MAX);
+
+	map<int, ustring>::iterator it = fields_.find(tag);
+
+	bool ret = false;
+	if (it == fields_.end())
+	{
+		fields_.insert(make_pair(tag, s));
+		tags_.push_back(tag);
+		sort(tags_.begin(), tags_.end());
+		ret = true;
+		ComposeRecord();
+	}
+	return ret;
+}
+//---------------------------------------------------------------------------------
+// AddOccurence --- Add an occurence to an existing field.
+//--------------------------------------------------------------------------------- 
+bool MfRecord::AddOccurence(int tag, ustring& o)
+{
+	PRECONDITION(tag>=0 && tag < SHRT_MAX);
+
+	map<int, ustring>::iterator it = fields_.find(tag);
+
+	bool ret = false;
+	if (it != fields_.end())
+	{
+	    it->second += SYSRSEP;
+		it->second += o;
+		ret = true;
+		ComposeRecord();
+	}
+	return ret;
+}
+
+//-----------------------------------------------------------------------------
+// bool  MfRecord::DeleteField(int tag)
+//
+//-----------------------------------------------------------------------------
+bool  MfRecord::DeleteField(int tag)
+{
+	PRECONDITION(tag>=0 && tag < SHRT_MAX);
+
+	map<int, ustring>::iterator it = fields_.find(tag);
+
+	bool ret = false;
+	if (it != fields_.end())
+	{
+		fields_.erase(it);
+		ret = true;
+		vector<int>::iterator j = find(tags_.begin(), tags_.end(), tag);
+		if (j != tags_.end())
+			tags_.erase(j);
+		ComposeRecord();
+	}
+	return ret;
+}
+
+//-------------------------------------------------------------------------------
+// bool ReplaceField(int tag, string& s)
+//
+//-------------------------------------------------------------------------------
+bool MfRecord::ReplaceField(int tag, ustring& s)
+{
+    
+	PRECONDITION(tag>=0 && tag < SHRT_MAX);
+
+	map<int, ustring>::iterator it = fields_.find(tag);
+
+	bool ret = false;
+	if (it != fields_.end())
+	{
+		it->second  = s;
+		ret         = true;
+	}
+	else
+		AddField(tag, s);
+	ComposeRecord();
+
+	return ret;
+}
+
+ustring MfRecord::GetAllFields()
+{
+	cstring all_fields; // As a string of ANSI characters
+	all_fields.erase();
+	all_fields = record_.substr(GetBase(), GetFieldSize());
+	return ustring(all_fields);
+}
+
+void MfRecord::ConvertToAnsi()
+{
+	/*
+	int mfrl = GetMfrl();
+	int size1 = record_.length();
+	if (GetFieldSize()==0)
+		return;
+	cstring s = record_.substr(GetBase(), GetFieldSize());
+	CString cs(s.c_str());
+	cs.OemToAnsi();
+	TRACE("\nbase=%d GetFieldSize=%d",GetBase(),GetFieldSize());
+	record_.replace(GetBase(),GetBase()+GetFieldSize(),
+		                                 cs.GetBuffer(GetFieldSize()));
+	int size2 = record_.length();
+	cs.ReleaseBuffer();
+	int padding = size1-size2;
+	for (int i=0; i<padding; i++)
+		record_ += " ";
+*/
+}
+
+long MfRecord::GetDirectorySize()
+{
+	return (GetNvf()*GetDirEntrySize());
+}
+
+long MfRecord::ComputeMfrl()
+{
+	return (GetLeaderSize() + GetDirectorySize() + GetFieldSize());
+}
+
+//--------------------------------------------------------------------------------------
+// void MfRecord::ComposeRecord()
+//
+// Build the record into continuous bytes for output
+//--------------------------------------------------------------------------------------
+void MfRecord::ComposeRecord()
+{
+	PRECONDITION(tags_.size() == fields_.size());
+	
+	// 1 - Prepare the LeaderAndDirectory, directory, end data part
+	int n   = 0;
+	int pos = 0;
+
+	ustring all_fields;
+    leader_directory_.dir_.clear();	
+	all_fields.erase();
+	for (vector<int>::size_type i=0; i!=tags_.size(); ++i)
+	{
+		int tag = tags_[i];
+		bool bRep = false;
+		if (pFdt_)
+		{
+			if (pFdt_->GetEntryAt(i).rep)
+			   bRep = true;
+		}
+		vector<ustring> occ;
+		if (bRep)
+			vector<ustring> occ = SplitOccurences(fields_[tags_[i]]);
+		else
+			occ.push_back(fields_[tags_[i]]);
+        // one entry per occurence
+		int nocc = occ.size();
+		for (vector<ustring>::size_type j=0; j!= nocc; ++j)
+		{
+			DirEntry de;
+			de.tag_ = tag;
+			de.pos_ = pos;
+			de.len_ = occ[j].length();
+            leader_directory_.dir_.push_back(de);
+			all_fields += occ[j];
+			n++;
+			pos += occ[j].length();
+			
+		}
+	}
+
+	leader_directory_.nvf_  = n;
+	leader_directory_.base_ = GetLeaderSize() + leader_directory_.nvf_*GetDirEntrySize();
+	leader_directory_.mfrl_ = ComputeMfrl();
+
+	// 2   - Make record
+
+	record_.erase(); // Empty the record
+
+	// Prepare the binary part, note that this part must be  independent
+	// of the character set.
+
+	cstringstream ost(std::ios::out | std::ios::binary);   
+	ost << leader_directory_;   // Output the LeaderAndDirectory to a string
+
+	
+	AddToRecord(ost.str().c_str(), ost.str().length());
+
+	// Here comes the part which is dependent from the character set,
+	// the data itself.
+	cstring all_fields_ansi(all_fields); 
+	AddToRecord(all_fields_ansi.c_str(), all_fields_ansi.length());
+	
+}
+
+//-------------------------------
+// Helper functions for decompose
+//-------------------------------
+
+bool MfRecord::CheckLeaderAndDirectory()
+{
+	if (GetMfrl() < 0)                  // Negative mfrl
+	{
+		//VLOG("DecomposeRecord -  Warning! Negative mfrl - mfn=%d", GetMfn());
+		SetMfrl(-GetMfrl());
+	}
+
+	if (GetMfrl()<=GetBase())
+	{
+		//VLOG("DecomposeRecord - Error! mfn=%d GetMfrl()=%d > GetBase()=%d", 
+		//	  GetMfn(),  GetMfrl(), GetBase());
+		return false;
+	}
+
+	
+
+	if (GetLeaderSize()>GetBase())
+	{
+		//VLOG("DecomposeRecord - Error! mfn=%d GetLeaderSize()=%d > GetBase()=%d", 
+		//	  GetMfn(),  GetLeaderSize(), GetBase());
+		return false;
+	}
+	if (GetNvf()==0) 
+	{
+	    // Null nvf      
+		//VLOG("DecomposeRecord -  Warning! mfn=%d nvf=0", GetMfn());
+		//SetNvf((GetBase() - GetLeaderSize()) / GetDirEntrySize());
+		return false;
+	}
+
+	if (GetMfn()<=0 || GetMfrl()<=0 || GetBase()<0 || GetNvf()<0 || GetStatus()< 0) 
+	{
+		//VLOG("DecomposeRecord - Error! mfn=%d GetMfrl()=%d GetLeaderSize()=%d GetBase()=%d GetNvf()=%d GetStatus()=%d", 
+		//      GetMfn(), GetMfrl(), GetLeaderSize(), GetBase(), GetNvf(), GetStatus());
+		return false;
+	}
+
+
+	int base = GetLeaderSize() + leader_directory_.nvf_*GetDirEntrySize();
+
+	if (record_.length() <= base)
+	{
+        //VLOG("DecomposeRecord - Error! mfn=%d record_.length()=%d < base=%d",
+		//	 GetMfn(), record_.length(), base);
+		return false;
+	}
+
+	int field_len = 0;
+	for (int i=0; i!=GetNvf(); ++i)
+	{
+		if (GetFieldTag(i)<0 || GetFieldTag(i)>SHRT_MAX ||
+			GetFieldPos(i)<0 || GetFieldPos(i)>SHRT_MAX ||
+			GetFieldLen(i)<0 || GetFieldLen(i)>SHRT_MAX)
+		{
+            //VLOG("DecomposeRecord - Error! mfn=%d Bad dir entry i=%d tag=%d pos=%d len=%d",
+			//    	GetMfn(), GetFieldTag(i), GetFieldPos(i), GetFieldLen(i));
+			return false;
+		}
+		field_len  += GetFieldLen(i);
+	}
+	
+    for (int j=0; j!=GetNvf(); ++j)
+	{
+		if (GetFieldPos(j)>=field_len || GetFieldPos(j)+GetFieldLen(j)>field_len)
+		{
+            //VLOG("DecomposeRecord - Error! mfn=%d Bad dir entry j=%d tag=%d pos=%d len=%d",
+			//    	GetMfn(), GetFieldTag(j), GetFieldPos(j), GetFieldLen(j));
+			return false;
+		}
+	}
+	// Check for bad values
+    if (GetBase() != base)	
+		SetBase(base);
+	
+	if (record_.length() < base + field_len)
+	{
+        //VLOG("DecomposeRecord - Error! mfn=%d record_.length()=%d < base=%d + field_len=%d",
+        //GetMfn(), record_.length(), base, field_len);  
+		return false;
+	}
+	return true;
+}
+
+void MfRecord::MakeTagToFieldMap()
+{
+	cstring all_fields_ansi;
+	all_fields_ansi.erase();
+	all_fields_ansi = record_.substr(leader_directory_.base_, GetFieldSize());
+	PRECONDITION(fields_.empty() && tags_.empty());
+
+
+	// Build the map from tags to fields
+	for (int i=0; i!=GetNvf(); ++i)
+	{
+		//int    all_len = all_fields.length();
+		//if (pos>all_len || pos+len>all_len)
+		//	return false;
+		cstring field_ansi = 
+			   all_fields_ansi.substr(GetFieldPos(i), GetFieldLen(i));
+		ustring field(field_ansi);
+	    map<int, ustring>::iterator it = fields_.find(GetFieldTag(i));
+	    if (it != fields_.end())
+		{
+			// Repeatable field, several occ
+		    it->second += SYSRSEP;
+			it->second += field;
+		}
+		else
+		{
+		    fields_.insert(make_pair(GetFieldTag(i), field));
+			
+		}
+		
+	}
+}
+void MfRecord::MakeTagVector()
+{
+	// Build a vector of tags
+	map<int, ustring>::const_iterator it;
+    for ( it = fields_.begin(); it != fields_.end(); ++it )
+		tags_.push_back(it->first);
+
+	// Sort in ascending order
+	sort(tags_.begin(), tags_.end());
+}
+
+
+//--------------------------------------------------------------------------------------
+// bool MfRecord::DecomposeRecord()
+//
+// Make a memory version of the record to facilitate manipulations.
+//--------------------------------------------------------------------------------------
+bool MfRecord::DecomposeRecord()
+{
+	PRECONDITION(!record_.empty());
+
+	if (record_.length() <= GetLeaderSize())
+	{
+		//VLOG("DecomposeRecord - Error! record_.length()=%d < GetLeaderSize()=%d",record_.length(), GetLeaderSize());
+		return false;
+	}
+
+	// Input the LeaderAndDirectory from a string
+    cstringstream ist(record_,cstringstream::in|cstringstream::binary);
+	if (!(ist >> leader_directory_))
+		return false;
+
+	if (!CheckLeaderAndDirectory())
+	{
+		//VLOG("Record rejected mfn=%ld", GetMfn());
+		return false;
+	}
+
+	//VLOG("Record accepted mfn=%ld", GetMfn());
+
+    MakeTagToFieldMap();
+    MakeTagVector();
+
+	return true;
+}
+
+
+
+void MfRecord::ExtractSubLeader()
+{
+	//PRECONDITION(!record_.empty() && record_.length()>=sizeof(leader_directory_.mfn_)+sizeof(leader_directory_.mfrl_));
+
+	leader_directory_.mfn_  = *(reinterpret_cast<ISIS_LONG*>((char *) record_.c_str()));
+	leader_directory_.mfrl_ = *(reinterpret_cast<ISIS_INT*> ((char *)(record_.c_str()+sizeof(ISIS_LONG))));
+	fix_endianness(leader_directory_.mfn_);
+	fix_endianness(leader_directory_.mfrl_);
+	if (leader_directory_.mfrl_ < 0) leader_directory_.mfrl_ = -leader_directory_.mfrl_; 	// mfrl can be negative!!!!
+
+	//POSTCONDITION(leader_directory_.mfn_>0 && leader_directory_.mfrl_>=0);
+}
+
+bool MfRecord::CheckLeader()
+{
+	int leader_size = GetLeaderSize();
+	if (leader_directory_.mfn_<=0)
+		return false;
+	if (abs(leader_directory_.mfrl_)<leader_size)
+		return false;
+	return true;
+}
+
+
+bool MfRecord::CheckIntegrity()
+{
+	int leader_size = GetLeaderSize();
+	if (leader_directory_.mfn_<=0)
+		return false;
+	if (abs(leader_directory_.mfrl_)<leader_size)
+		return false;
+	if (leader_directory_.nvf_<0)
+		return false;
+	//if (leader_directory_.base_ != leader_directory_size + leader_directory_.nvf_*sizeof(MAXDIRL))
+	//	return false;
+	if (leader_directory_.status_ == 1)
+		return true;
+	else if (leader_directory_.status_ == 0)
+		return true;
+	else
+		return false;
+
+	return true;
+}
+ 
+
+void  MfRecord::Dump()
+{
+
+	ustringstream os;
+    os.str("");
+
+
+    os <<  "\n================= entry in MfRecord::Dump==============";
+    os <<  "\n   MFN      " << GetMfn();
+    os <<  "\n   MFRL     " << GetMfrl();
+    os <<  "\n   MFBWB    " << GetMfbwb();
+    os <<  "\n   MFBWP    " << GetMfbwp();
+    os <<  "\n   BASE     " << GetBase();
+    os <<  "\n   NVF      " << GetNvf();
+    os <<  "\n   STATUS   " << GetStatus();
+ 	//TRACE(os.str().c_str());
+
+
+	for (int i=0; i<GetNvf(); i++)
+	{
+		  ustring stemp;
+		  bool rc = GetField(GetDirEntry(i).tag_, stemp);
+		  int len;
+		  if (rc)
+		  {
+		       len = 50;
+		       if (stemp.length()<len)
+			      len = stemp.length();
+		  }
+		  ustring fld = (rc==false) ? _T("Empty") : stemp.substr(0,len);
+	      os.str("");
+		  os << _T(" tag=") << ISIS_INT(GetDirEntry(i).tag_)
+             << _T(" pos=") << ISIS_INT(GetDirEntry(i).pos_)
+			 << _T(" len=") << ISIS_INT(GetDirEntry(i).len_)
+			 << _T(" ")     << fld.c_str() << std::endl; 
+          TRACE(_T("\n%s"),os.str().c_str());   
+	  }
+
+      TRACE("\n---------------- exit in MfRecord::Dump-------------");
+}
+
+
+
+
+bool MfRecord::CheckRecord()
+{
+	PRECONDITION(!record_.empty());
+
+	if (record_.length() < GetLeaderSize())
+	{
+		TRACE(_T("\nWrong LeaderAndDirectory in record!"));
+		return false;
+	}
+
+    cstringstream ist(record_,cstringstream::in|cstringstream::binary);
+
+	LeaderAndDirectory leader_directory;
+	ist >> leader_directory;
+
+	if (leader_directory.mfrl_ < 0)                  // Negative mfrl
+	{
+		//VLOG("CheckRecord -  Warning! Negative mfrl - mfn=%d", GetMfn());
+	}
+	
+	if (leader_directory.nvf_<=0) 
+	{
+		//VLOG("CheckRecord -  Warning! mfn=%d nvf=0", leader_directory.mfn_);
+	}
+
+	if (leader_directory.mfn_<=0 || leader_directory.mfrl_<=0 ||
+		leader_directory.base_<0 || leader_directory.nvf_ < 0 ||
+		leader_directory.status_ < 0) 
+	{
+		//VLOG("CheckRecord - Corrupted record! leader_directory.mfn_=%d leader_directory.mfrl_=%d leader_directory.base_=%d leader_directory.nvf_=%d leader_directory.status_=%d",
+        //      leader_directory.mfn_, leader_directory.mfrl_,
+		//	  leader_directory.base_, leader_directory.nvf_,
+		//	  leader_directory.status_);
+		return false;
+	}
+
+
+	int base = GetLeaderSize() + GetDirectorySize();
+
+	if (record_.length() < base)
+	{
+		//VLOG("CheckRecord - Corrupted record! mfn=%d record_.length()=%d base=%d",
+		//	  leader_directory.mfn_, record_.length(), base);
+		return false;
+	}
+
+	int field_len = 0;
+	for (int i=0; i!=leader_directory.nvf_; ++i)
+	{
+		DirEntry de = leader_directory.dir_[i];
+//  		if (de.tag_<0 || de.tag_>SHRT_MAX || de.pos_<0 || de.pos_>SHRT_MAX || de.len_<0 || de.len_>SHRT_MAX)
+//  		{
+//  		    //VLOG("CheckRecord - Corrupted record! mfn=%d tag=%d pos=%d len=%d",
+//  			//	  leader_directory.mfn_, de.tag_, de.pos_, de.len_);
+//  			return false;
+//  		}
+		if (i>0)
+		{
+			if(de.pos_ != leader_directory.dir_[i-1].pos_+leader_directory.dir_[i-1].len_)
+			{
+		    //VLOG("CheckRecord - Position not consistent - mfn=%d",
+			//	  leader_directory.mfn_);
+			return false;
+			}
+		}
+		field_len  += de.len_;
+	}
+	
+
+	// Check for bad values
+    if (leader_directory.base_ != base)	
+		leader_directory.base_ = base;
+	
+	if (record_.length() < base + field_len)
+	{
+		    //VLOG("CheckRecord - Corrupted record, record length < base+field_len  - mfn=%ld",
+			//	  leader_directory.mfn_);
+		return false;
+	}
+
+	return true;
+}
+
+void MfRecord::ReadLeader(MfFile& f, long daddr)
+{
+    int leader_size = GetLeaderSize();
+    char* buffer = new char[leader_size];
+    f.Fetch(buffer, leader_size, daddr);  // Read record leader
+    Clear();
+    AddToRecord(buffer, leader_size);
+    delete[] buffer;
+}
+
+bool  MfRecord::Read(MfFile& f, long mfb, int mfp)
+{
+    //TRACE("\nMfFile::ReadMfRecord -- mfb=%ld mfp=%d", mfb, mfp);
+	PRECONDITION(mfb>0 && mfb<=MAXMFB);
+    long  blk;
+    int   mfrr, offs, l;
+
+	try
+	{
+		Clear();
+	    // Save original mfb, mfp pair into m
+	    SetMfbRead(mfb);
+	    SetMfpRead(mfp);
+	    SetState(MfRecord::Record_Read);
+
+	    // Be sure that mfp is in range [0:MFBLKSIZE-1]
+	    mfp = mfp%MFBLKSIZE;
+		assert(mfp>=0 && mfp<MFBLKSIZE);
+        //TRACE("\nMfFile::ReadMfRecord - mfb=%ld mfp=%d", mfb, mfp);
+
+		// 1 - Read block where record starts 
+        f.ReadBlk(m_buf,mfb);                    
+
+        blk = mfb;
+		// 2 - Extract the record leader (Mfn+Mfrl) from the block buffer, the 
+		//     record leader cannot be split on two  consecutive blocks.
+        int len = GetSubLeaderSize(); // Mfn + Mfrl
+		ASSERT(mfp+len<MFBLKSIZE);
+
+        AddToRecord(m_buf+mfp, len); // Move 1st 6 bytes  (Mfn+Mfrl)
+		ExtractSubLeader();
+
+		// 3 - Continue to transfer data for building the MfRecord object
+        int mflen = GetMfrl();                // Get record length
+	    SetMflenRead(mflen);                  // Save it 
+        //TRACE("\nMfFile::readMfRecord - After reading leader mfn=%ld mflen=%d",GetMfn(), mflen);
+        mfrr = mflen - len;                     // Not yet moved
+        l = (mfrr > (f.GetBlockSize()-(mfp+len)))      // What remains to move
+            ? (f.GetBlockSize()-(mfp+len)) : mfrr;         // in this block
+        offs = len;
+        AddToRecord(m_buf+mfp+len, l); // Move-it
+        mfrr -= l;
+        while (mfrr>0)                        // Record continues on next block ?
+		{                
+            f.ReadBlk(m_buf,++blk);             // Yes read next block
+            offs += l;
+            l = (mfrr > f.GetBlockSize()) ? f.GetBlockSize() : mfrr;
+            AddToRecord(m_buf, l); // Move data
+            mfrr -= l;
+		}
+	    //TRACE("\nMfFile::ReadMfRecord -- mfb=%ld mfp=%d nvf=%d", mfb, mfp, GetNvf());
+	}
+	catch (CFileBaseException e)
+	{
+        throw CIsisDbException(ISIS_MF_READ_ERROR, __FILE__, __LINE__);
+	}
+
+	return DecomposeRecord();
+}
+
+
+void  MfRecord::Write(MfFile& f, long mfb, int mfp)
+{
+	TRACE(_T("\nMfFile::writeMfRecord - mfb=%ld mfp=%d"), mfb, mfp);
+	PRECONDITION(mfb>0 && mfb <= MAXMFB);
+	// Be sure that mfp is in range [0:MFBLKSIZE-1]
+	mfp = mfp%MFBLKSIZE;
+	
+    long hiblk = f.GetNextMfb(); // Highest block number in master file
+	
+    int s  = 0;              // Index in master file record [0:mfrl-1]
+    int d  = mfp;            // Index in block buffer [0:bsize-1]
+    long b = mfb;            // Starting block number
+	
+    // Adjust record length
+	int padding = GetMfrl() % MFALIGN;
+	if (padding>0)
+	{
+		SetMfrl(GetMfrl() + padding);
+		for (int i=0; i<padding;i++)
+			AddToRecord(" ", 1);
+	}
+	
+    int mfrl = GetMfrl();
+    TRACE(_T("\nMfFile::writeMfRecord - b=%ld d=%d mfrl=%ld hiblk=%ld"), b, d, mfrl, hiblk);
+    TRACE(_T("\nBefore writing->"));
+	do 
+    {
+		if (b <= hiblk)        
+			f.ReadBlk(m_buf, b);
+		else
+			::memset(m_buf, ' ', MFBLKSIZE);
+		
+		while (d < MFBLKSIZE && s < mfrl)
+			m_buf[d++] = record_.at(s++);
+		if (d >= MFBLKSIZE) 
+		{
+			TRACE(_T("MfFile::WriteMfRecord - Before WriteBlk b=%ld"), b);
+			f.SetLastWrittenBlock(b);
+			f.WriteBlk(m_buf, b++);
+			// Reset m_buf pos
+			d = 0;
+		}
+	} while (s < mfrl);
+	
+    // Write last block
+	if (d == 0)
+		::memset(m_buf, ' ', MFBLKSIZE); // Should be an empty block
+	
+	f.WriteBlk(m_buf, b);       
+	f.SetLastWrittenBlock(b);
+} 
+
+void IntToChar(int value, int width, std::string& s)
+{
+	std::ostringstream ost;
+
+#ifdef _WIN32
+	ost.setf(std::ios_base::right, std::ios_base::adjustfield);
+#endif
+	ost << std::setw(width) 
+		<< std::setfill('0') 
+		<< value;
+	s = ost.str();
+}
+//--------------------------------------------------------------------------------------
+// void MfRecord::MakeISORecord(std::string& s)
+//
+// Build the record into continuous bytes for output
+//--------------------------------------------------------------------------------------
+void MfRecord::MakeISORecord(std::string& s)
+{
+	std::string    tmp;
+
+	MarcLeader l;
+
+	// 1 - Complete the leader (base and record length), output the directory 
+	//     to a string and prepare a string with the data fields
+	int base = MARC_LEADER_LEN + GetNvf()*MARC_DIRENT_LEN + 1;
+	IntToChar(base, 5, tmp);
+	strncpy(l.base_ ,tmp.c_str(),5);
+
+	DirectoryEntry mde;
+	ustring    all_fields;
+	all_fields.erase();
+	ostringstream  osd;     // Output the directory to a string
+	int pos = 0; 
+	for (int i=0; i!=GetNvf(); ++i)
+	{
+		IntToChar(GetFieldTag(i), 3, tmp); 
+		strncpy(mde.tag_,tmp.c_str(),3);
+		int len = GetFieldLen(i)+1;  // Include space for separator
+		IntToChar(len, 4, tmp);
+		strncpy(mde.len_, tmp.c_str(), 4);
+		IntToChar(pos, 5, tmp);
+		strncpy(mde.scp_, tmp.c_str(), 5);
+		osd << mde; 
+		pos += len;
+
+		cstring field = record_.substr(GetBase()+GetFieldPos(i), GetFieldLen(i));
+		all_fields += ustring(field);
+		all_fields += FIELDTERM;
+	}
+	// (+2) ->Field sep at end of directory and record sep
+    int reclen =  MARC_LEADER_LEN + GetNvf()*MARC_DIRENT_LEN + pos +2;
+	IntToChar(reclen, 5, tmp);
+	strncpy(l.lreclen_,tmp.c_str(),5);
+
+
+	ostringstream osl;     // Output the Leader to a string
+	osl << l;
+
+	// 2   - Make record
+	s.erase();       // Empty the record
+    s += osl.str();  // Add the leader
+	s += osd.str();  // Add the directory
+	s += FIELDTERM;  // Separator
+	s += cstring(all_fields); // Data part
+	s += RECTERM;
+		
+}
Index: /gsdl/stable/build-src/packages/isis-gdl/Master.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/Master.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/Master.h	(revision 20131)
@@ -0,0 +1,609 @@
+/**********************************************************************
+ *
+ * Master.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+///////////////////////////////////////                                   */
+//  Master.h: Master File Record object
+///////////////////////////////////////                                   */
+ 
+#ifndef __MASTER_RECORD_H__
+#define __MASTER_RECORD_H__
+
+#include "BlkFile.h"
+#include <vector>
+#include <map>
+#include <sstream>
+
+
+ 
+// Length in bytes of master file header 
+#define MFCTLLEN sizeof(SMfHeader)+sizeof(SMfHeader) // Length in bytes of master file header
+
+const int MFALIGN   =    2;   // Master file record alignment
+const int MFBLKSIZE =  512;   // Master file block size
+ 
+typedef short int ISIS_INT;
+typedef long  int ISIS_LONG;
+
+#ifdef UNIX_BIREME
+    //Length of Leader in master record
+	inline 	int GetLeaderSize()
+	{
+		return (2*sizeof(ISIS_LONG)+6*sizeof(ISIS_INT));
+	}
+    // Mini Leader length guaranteed to be in same block
+	inline 	int GetMinLeaderSize()
+	{ 
+		return (2*sizeof(ISIS_LONG)+4*sizeof(ISIS_INT));
+	}
+#else
+    //Length of Leader in master record
+	inline 	int GetLeaderSize() 
+	{
+		return (2*sizeof(ISIS_LONG)+5*sizeof(ISIS_INT)); 
+	}
+    // Mini Leader length guaranteed to be in same block
+	inline 	int GetMinLeaderSize()
+	{ 
+		return (2*sizeof(ISIS_LONG)+3*sizeof(ISIS_INT));
+	}
+#endif
+
+// Size of Mfn and Mfrl in the leader part
+inline int GetSubLeaderSize() { return sizeof(ISIS_LONG)+sizeof(ISIS_INT); }
+ 
+inline int GetDirEntrySize() { return (3*sizeof(ISIS_INT)); }
+ 
+ 
+const TCHAR SYSRSEP      =  TCHAR('%'); // Repeatable field separator
+const TCHAR SUBFIELD_SEP =  TCHAR('^'); // Subfield separator
+
+////////////////////////////////////////
+// Directory entry aggregate structure
+//
+struct DirEntry  
+{
+   ISIS_INT  tag_;
+   ISIS_INT  pos_;
+   ISIS_INT  len_;
+   DirEntry() 
+	   : tag_(0), pos_(0), len_ (0) {  }
+
+   DirEntry(ISIS_INT tag, ISIS_INT pos, ISIS_INT len)
+	   : tag_(tag), pos_(pos), len_ (len) {  }
+   bool operator==(const DirEntry& rhs) const
+   {
+	   if (tag_!=rhs.tag_ || pos_!=rhs.pos_ || len_!=rhs.len_)
+		   return false;
+	   return true;
+   }
+   bool operator!=(const DirEntry& rhs) const
+   {
+	   if (tag_!=rhs.tag_ || pos_!=rhs.pos_ || len_!=rhs.len_)
+		   return true;
+	   return false;
+   }
+
+};
+ 
+
+//////////////////////////////////////////////////////////////////////////
+// Data Master record aggregate structure
+//
+struct LeaderAndDirectory 
+{
+   ISIS_LONG        mfn_;            // Master file number
+   ISIS_INT         mfrl_;           // Record length
+   ISIS_LONG        mfbwb_;          // Backward pointer block number
+   ISIS_INT         mfbwp_;          // Backward pointer offset
+   ISIS_INT         base_;           // Offset to begining of variable fields
+   ISIS_INT         nvf_;            // Number of directory entries
+   ISIS_INT         status_;         // 1 = DELETED
+   std::vector<DirEntry> dir_;            // Directory
+
+   LeaderAndDirectory()
+   {
+	   Clear();
+   }
+   LeaderAndDirectory(const LeaderAndDirectory& src)
+   {
+	   Copy(src);
+   }
+
+   LeaderAndDirectory& operator=(const LeaderAndDirectory& rhs)
+   {
+	   if (&mfn_ != &rhs.mfn_)
+	   {
+		   Copy(rhs);
+	   }
+	   return *this;
+   }
+
+   void Copy(const LeaderAndDirectory& rhs)
+   {
+	   mfn_    = rhs.mfn_;
+	   mfrl_   = rhs.mfrl_;
+	   mfbwb_  = rhs.mfbwb_;
+	   mfbwp_  = rhs.mfbwp_;
+       base_   = rhs.base_;
+       nvf_    = rhs.nvf_;
+	   status_ = rhs.status_;
+	   dir_    = rhs.dir_;
+   }
+   void Clear()
+   {
+	   mfn_ = mfrl_ = mfbwb_ = mfbwp_ = base_ = nvf_ = status_ = 0;
+	   dir_.clear();
+   }
+
+   bool operator==(const LeaderAndDirectory& rhs) const;
+   bool operator!=(const LeaderAndDirectory& rhs) const;
+   int GetFieldSize();
+};
+
+cstringstream& operator<<(cstringstream& s, const LeaderAndDirectory& leader);
+cstringstream& operator>>(cstringstream& s, LeaderAndDirectory& leader);
+
+////////////////////////////////////////////////////////////
+//
+ 
+/////////////////////////////////
+// Data master file record class
+//
+
+typedef std::map<int, ustring> TAG2FIELD;
+class MfFile;
+class MstFile;
+class IsisDb;
+class ACE_InputCDR;
+class ACE_OutputCDR;
+class UMfRecord;
+
+
+class  MfRecord
+{
+	friend class MfFile;
+	friend class MstFile;
+	friend class IsisDb;
+	friend class UMfRecord;
+    friend int operator>>(ACE_InputCDR& cdr, MfRecord& mfr);
+    friend int operator<<(ACE_OutputCDR& cdr, MfRecord& mfr);
+protected:
+
+	CFdt*                pFdt_;        // Use a copy of the FDT
+	cstring              record_;      // Record in continuous storage
+	                                   // always as ANSI!
+	
+	LeaderAndDirectory           leader_directory_;
+	
+	TAG2FIELD        fields_;
+	std::vector<int> tags_;
+    static char      m_buf[MFBLKSIZE];      // Buffer to hold 1 File block
+
+protected: // Additional data
+	short int state_;         // Record state in memory
+	long      mfb_read_;      // Record was read at Block number [1...]
+	int       mfp_read_;      // Record was read at position in block
+	int       mflen_read_;    // Record length was when record read 
+
+protected:
+   void         Copy(const MfRecord& rhs); 
+   
+   void         AddToRecord(const char* p, int len);
+   int          AddDirEntry(const DirEntry& d);
+   int          AddDirEntry(int tag, int pos, int len);
+   int          DelDirEntry(int i);
+   void         SetMfrl(int mfrl);
+   void         SetMfbwb(long mfbwb);
+   void         SetMfbwp(int mfbwp);
+   void         SetBase(int base);
+   void         SetNvf(int nvf);
+   void         SetStatus(int s);
+   int          SetDirEntry(int i, int tag, int pos, int len);
+   int          SetDirEntry(int i, const DirEntry& d);
+   void         SetMfbRead(long b);
+   void         SetMfpRead(int pos);
+   void         SetMflenRead(int len);
+
+ 
+   void         SetSubLeaderAndDirectory(const char* p, int len);
+
+
+   void         MakeTagToFieldMap();
+   void         MakeTagVector();
+
+   long         ComputeMfrl();
+
+   void         Copy(UMfRecord& rhs);           
+public:
+	enum { Record_Empty, Record_Read, Record_Changed, Record_Created };
+
+public:
+   //-----------------
+   // Public Interface
+   //-----------------
+   MfRecord(CFdt* pFdt=NULL);                // Default constructor   
+   virtual ~MfRecord();                      // Destructor
+
+   MfRecord(const MfRecord& rhs);            // Copy constructor
+   MfRecord& operator=(const MfRecord& rhs); // Assignment
+ 
+   MfRecord(const UMfRecord& umfr);
+   MfRecord& operator=(const UMfRecord& rhs);
+
+   void Clear();
+   void ClearData();
+
+
+   void ReadLeader(MfFile& f, long daddr);
+   bool Read (MfFile& f, long mfb, int mfp);
+   void Write(MfFile& f, long mfb, int mfp);
+
+   void MakeISORecord(std::string& s);
+ 
+   long         GetMfn()           const; // Get MFN
+   int          GetMfrl()          const; // Get Master File Record Length
+   long         GetMfbwb()         const; // Get Master File Backward Block number
+   int          GetMfbwp()         const; // Get Master File Backward block position
+   int          GetBase()          const; // Get Variable fields starting byte
+   int          GetNvf()           const; // Get Number of entries in the directory
+   int          GetStatus()        const; // Get Record Status
+   DirEntry     GetDirEntry(int i) const; // Get a reference to the ieme directory entry
+   int          GetState()         const; // Get record state in memory
+   long         GetMfbRead()       const;
+   int          GetMfpRead()       const;
+   int          GetMflenRead()     const;
+
+   ustring     GetAllFields(); // ANSI or UNICODE
+   cstring     GetRecordAsString() { return record_; }
+   const char* GetRecord()         { return record_.c_str(); }
+   int         GetRecordLength()   { return record_.length(); }
+
+   void        ConvertToAnsi();
+
+
+   bool         GetField(int tag, std::string& s);  // Get field content for field with tag "tag" 
+   bool         AddField(int tag, std::string& s);
+   bool         DeleteField(int tag);
+   bool         ReplaceField(int tag, std::string& s);
+   bool         AddOccurence(int tag, std::string& o);
+
+   int          GetFieldTag(int i);
+   int          GetFieldPos(int i);
+   int          GetFieldLen(int i);
+ 
+   void         SetMfn(long mfn);
+   void         SetState(int s);
+
+   long         GetDirectorySize();
+   int          GetFieldSize()     { return leader_directory_.GetFieldSize(); }
+
+   std::vector<int>  GetFieldTags(); // Get tags of fields in increasing order,
+                                     // Occurences made only 1 field
+   void         ExtractSubLeader();
+   void         ExtractLeader();
+   bool         CheckIntegrity();
+   bool         CheckLeader();
+   bool         CheckLeaderAndDirectory(); 
+
+   bool operator==(const MfRecord& rhs) const
+   {
+	   return (record_ == rhs.record_); 
+   }
+   bool operator!=(const MfRecord& rhs) const
+   {
+	   return (record_ != rhs.record_); 
+   }
+
+   void         SetRecord(const char *s) { record_ = s;  DecomposeRecord();}
+   void         SetRecord(const cstring &s) 
+				{ record_ = s;  DecomposeRecord();}
+   void         ComposeRecord();
+   bool         DecomposeRecord();
+
+   bool         CheckRecord();
+   void         Dump();
+} ;
+ 
+//////////////////////////////
+ 
+
+
+
+inline void MfRecord::AddToRecord(const char* p, int len)
+{
+	record_ += cstring(p,len);
+} 
+
+/////////////////////////////
+
+inline MfRecord::MfRecord(CFdt* pFdt) 
+// Makes a Master file Record object
+{
+	Clear();
+	pFdt_ = pFdt;
+   // Nothing more to do
+}
+ 
+inline void MfRecord::Copy(const MfRecord& rhs)           
+{
+   record_     = rhs.record_;
+   leader_directory_     = rhs.leader_directory_;
+   fields_     = rhs.fields_;
+   state_      = rhs.state_;
+   mfb_read_   = rhs.mfb_read_;
+   mfp_read_   = rhs.mfp_read_;
+   mflen_read_ = rhs.mflen_read_;
+   tags_       = rhs.tags_;         
+	pFdt_      = rhs.pFdt_;
+}
+
+inline MfRecord::MfRecord(const MfRecord& rhs)     // Copy constructor
+{ 
+   Copy(rhs);
+}
+
+inline MfRecord& MfRecord::operator=(const MfRecord& rhs) // Assignment
+{
+   if (&leader_directory_ != &rhs.leader_directory_)
+   {
+   	   Copy(rhs);
+   }
+   return *this;
+}
+ 
+inline void MfRecord::Clear()
+{
+   tags_.clear();
+   record_.erase();
+   leader_directory_.Clear();
+   fields_.clear();
+   SetBase(GetLeaderSize());
+   SetMfrl(GetLeaderSize());
+   state_ = Record_Empty;
+   mfb_read_ = mfp_read_ = mflen_read_ = 0;
+   pFdt_ = NULL;
+}
+
+// Clear the data part but keep other info intact so that
+// it appears as an empty record
+inline void MfRecord::ClearData()
+{
+   tags_.clear();
+   record_.erase();
+   leader_directory_.Clear();
+   fields_.clear();
+   SetBase(GetLeaderSize());
+   SetMfrl(GetLeaderSize());
+}
+
+
+//////////////////////////////
+ 
+inline MfRecord::~MfRecord()
+{
+}
+ 
+//////////////////////////////
+ 
+inline long MfRecord::GetMfn() const
+// Returns Master file number
+{
+   return leader_directory_.mfn_;
+}
+ 
+//////////////////////////////
+ 
+inline int MfRecord::GetMfrl() const
+// Returns Master file record length
+{
+   return leader_directory_.mfrl_;
+}
+ 
+//////////////////////////////
+ 
+inline long MfRecord::GetMfbwb() const
+// Returns backward pointer block number
+{
+   return leader_directory_.mfbwb_;
+}
+ 
+//////////////////////////////
+ 
+inline int MfRecord::GetMfbwp() const
+// Returns backward pointer offset
+{
+   return leader_directory_.mfbwp_;
+}
+ 
+//////////////////////////////
+ 
+inline int MfRecord::GetBase() const
+// Returns base value to field data
+{
+    return leader_directory_.base_;
+}
+ 
+//////////////////////////////
+ 
+inline int MfRecord::GetNvf() const
+// Returns the number of directory entries
+// in the master file record
+{
+   return leader_directory_.nvf_;
+}
+
+//////////////////////////////
+ 
+inline int MfRecord::GetStatus() const
+// Returns the status of the record
+{
+   return leader_directory_.status_;
+}
+
+//////////////////////////////
+ 
+ 
+//////////////////////////////
+ 
+inline DirEntry MfRecord::GetDirEntry(int i) const
+// Returns the ith dir entry
+{
+   return leader_directory_.dir_[i];
+} 
+
+//////////////////////////////
+ 
+inline int MfRecord::GetState() const
+{
+   return state_;
+} 
+
+//////////////////////////////
+ 
+inline long MfRecord::GetMfbRead() const
+{
+   return mfb_read_;
+} 
+//////////////////////////////
+ 
+inline int MfRecord::GetMfpRead() const
+{
+   return mfp_read_;
+} 
+    
+//////////////////////////////
+ 
+// Get tags of fields in increasing order,
+inline std::vector<int> MfRecord::GetFieldTags()
+{
+	PRECONDITION(tags_.size() == fields_.size());
+	return tags_;
+}
+//////////////////////////////
+ 
+inline int MfRecord::GetMflenRead() const
+{
+   return mflen_read_;
+} 
+    
+///////////////////////////////////////////////////////////////////////////////
+ 
+inline void MfRecord::SetMfn(long mfn)
+// Set Master file number
+{
+	assert(mfn>0);
+    leader_directory_.mfn_ = mfn;
+}
+//////////////////////////////
+ 
+inline void MfRecord::SetMfrl(int mfrl)
+// Set Master file record length
+{
+	assert(mfrl>0);
+    leader_directory_.mfrl_ = mfrl;
+}
+//////////////////////////////
+ 
+inline void MfRecord::SetMfbwb(long mfbwb)
+// Sets backward pointer block number to mfbwb
+{
+	assert(mfbwb>=0);
+    leader_directory_.mfbwb_ = mfbwb;
+}
+
+//////////////////////////////
+ 
+inline void MfRecord::SetMfbwp(int mfbwp)
+// Sets backward pointer block offset to mfbwp
+{
+	assert(mfbwp>=0);
+    leader_directory_.mfbwp_ = mfbwp;
+}
+//////////////////////////////
+ 
+inline void  MfRecord::SetBase(int base)
+// Sets the base value in the record aggregate
+{
+	assert(base>=0);
+    leader_directory_.base_ = base;
+}
+
+//////////////////////////////
+ 
+inline void MfRecord::SetNvf(int nvf)
+// Sets the number of entries in the directory part
+{
+	assert(nvf>=0);
+    leader_directory_.nvf_ = nvf;
+}
+ 
+//////////////////////////////
+ 
+inline void MfRecord::SetStatus(int s)
+// Sets the status of the record
+{
+   leader_directory_.status_ = s;
+}
+ 
+//////////////////////////////
+ 
+inline void MfRecord::SetState(int s)
+// Sets the status of the record
+{
+	assert(s==MfRecord::Record_Empty || s==MfRecord::Record_Read 
+		|| s==MfRecord::Record_Changed || s==MfRecord::Record_Created);
+   state_ = s;
+}
+
+inline void MfRecord::SetMfbRead(long b)
+{
+	mfb_read_ = b;
+}
+
+inline void MfRecord::SetMfpRead(int pos)
+{
+	mfp_read_ = pos;
+}
+
+inline void MfRecord::SetMflenRead(int len)
+{
+	mflen_read_ = len;
+}
+
+inline int MfRecord::GetFieldTag(int i)
+{
+	return leader_directory_.dir_[i].tag_;
+}
+inline int MfRecord::GetFieldPos(int i)
+{
+	return leader_directory_.dir_[i].pos_;
+}
+
+inline int MfRecord::GetFieldLen(int i)
+{
+	return leader_directory_.dir_[i].len_;
+}
+
+#endif
Index: /gsdl/stable/build-src/packages/isis-gdl/Unimarc.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/Unimarc.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/Unimarc.cpp	(revision 20131)
@@ -0,0 +1,620 @@
+/**********************************************************************
+ *
+ * Unimarc.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "stdafx.h"
+
+///////////////////////////////////////////////////////////////////////////////////
+// MarcRecord - This class can instantiate objects that represent a MARC
+//              bibilographic record and includes methods for manipulating the 
+//              record.
+//
+//             example:
+//
+//	#include "Unimarc.h"
+//
+//     // Create a MarcRecord object with a raw MARC record
+//     MarcRecord mr(buf,1)
+//     mr.PrettyFormat("The title is %245, which is the field with tag 245");
+#include <vector>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "Unimarc.h"
+
+//-------------------------------------------------------------------------------
+// ostream& operator<<(ostream& s, const MarcLeader& leader)
+//
+// Overloaded instance of the output operator for MarcLeader objects
+//---------------------------------------------------------------------------------
+std::ostream& operator<<(std::ostream& s, const MarcLeader& leader)
+{
+	s.write(leader.lreclen_, 5);	// Logical record length
+	s.write(&leader.status_, 1);	// Record status  
+	s.write(&leader.type_, 1);		// Type of record
+	s.write(&leader.bibLevel_, 1);	// Bibliographic level
+	s.write(&leader.ctrlType_, 1);	// Type of control
+	s.write(&leader.undPos_, 1);	// Undefined character position
+	s.write(&leader.indCount_, 1);	// Indicator count
+	s.write(&leader.scd_, 1);		// Subfield code count
+	s.write(leader.base_, 5);   	// Base address of data
+	s.write(&leader.encLevel_, 1);	// Encoding level
+	s.write(&leader.dcf_, 1);		// Descriptive cataloging form
+	s.write(&leader.lrr_, 1);		// Linked record requirement
+	  // Directory  entry map
+	s.write(&leader.llof_, 1);		// Length of the length-of-field portion
+	s.write(&leader.lscp_, 1);		// Length of starting-character-position portion
+	s.write(&leader.lidp_, 1);		// Length of implementation-defined portion
+	s.write(&leader.uep_, 1);		// Undefined entry map character position
+	return s;
+}
+
+//----------------------------------------------------------------------------------
+// istream& operator>>(istream& s, const MarcLeader& leader)
+//
+// Overloaded instance of the input operator for MarcLeader objects
+//----------------------------------------------------------------------------------
+std::istream& operator>>(std::istream& s, MarcLeader& leader)
+{
+	s.read(leader.lreclen_, 5);	    // Logical record length
+	s.read(&leader.status_, 1);	    // Record status  
+	s.read(&leader.type_, 1);		// Type of record
+	s.read(&leader.bibLevel_, 1);	// Bibliographic level
+	s.read(&leader.ctrlType_, 1);	// Type of control
+	s.read(&leader.undPos_, 1);	    // Undefined character position
+	s.read(&leader.indCount_, 1);	// Indicator count
+	s.read(&leader.scd_, 1);		// Subfield code count
+	s.read(leader.base_, 5);   	    // Base address of data
+	s.read(&leader.encLevel_, 1);	// Encoding level
+	s.read(&leader.dcf_, 1);		// Descriptive cataloging form
+	s.read(&leader.lrr_, 1);		// Linked record requirement
+	  // Directory  entry map
+	s.read(&leader.llof_, 1);		// Length of the length-of-field portion
+	s.read(&leader.lscp_, 1);		// Length of starting-character-position portion
+	s.read(&leader.lidp_, 1);		// Length of implementation-defined portion
+	s.read(&leader.uep_, 1);		// Undefined entry map character position
+	return s;
+}
+
+/************************************************************************
+Local prototypes
+ ***********************************************************************/
+static void Printx(FILE *fp, char *s, int x);
+
+//----------------------------------------------------------------------
+// MarcRecord::MarcRecord(char *data, int length, int copyData)
+// 
+// Constructor that creates a new MarcRecord object. 
+// data is raw marc record data for a single record.  If copyData is 1, 
+// data is encapsulated within this object.  If 0, does not copy data and 
+// responsibility falls to caller to maintain data pointer.
+//----------------------------------------------------------------------
+MarcRecord::MarcRecord(char* data, int length, int copyData)
+{
+	encapsulated_ = copyData;
+	
+	/* encapsulate or set pointer to data */
+	if (encapsulated_)
+	{
+		data_ = new char[length + 1]; 
+		memcpy(data_, data, length);
+		data_[length] = '\0';
+	}
+	else
+		data = data;
+	
+	// Lay leader overlay onto data
+	leader_ = *(MarcLeader *) (data_);
+	
+	// Parse the record.  sets dirCount_, directory_ 
+	if (!ParseMarcRecord()) 
+	{
+		// marcRecord_destroy(m);
+		// return NULL;
+	}
+}
+
+//----------------------------------------------------------------------
+// void MarcRecord::~MarcRecord()
+//
+// Destructor, destroys a MarcRecord object and all used resources.
+//----------------------------------------------------------------------
+MarcRecord::~MarcRecord()
+{
+	if ((encapsulated_) && (data_))
+		delete[] data_;
+
+	for (std::vector<MarcDirectoryEntry>::size_type i=0; i!=directory_.size(); ++i)
+		directory_[i].field_.erase(directory_[i].field_.begin(),directory_[i].field_.end());
+	directory_.erase(directory_.begin(),directory_.end());
+}
+
+#define MARC_STATE_IDLE 0
+#define MARC_STATE_TAG 1
+#define MARC_STATE_WIDTH 2
+//----------------------------------------------------------------------
+// int MarcRecord::PrettyFormat(char* format, char* buf, int maxlen)
+//
+//  Formats the contents of the marc record according to a format string.
+//  Useful for generating a buffer to pretty-print the record.
+//  format contains a format-specifier string.  The format-specifier string
+//  is kindof like printf's, except the only control character is '%'.
+//  Following the '%' should be the integer MARC field code as defined in 
+//  the (huge) list of available MARC fields from the library of congress
+//  (http://lcweb.loc.gov/marc/).  buf is a previously allocated 
+// buffer into which the pretty version will be copied.  maxlen is the max 
+// length to write into buf.  After call, buf contains pretty formatted text.
+//----------------------------------------------------------------------
+int MarcRecord::PrettyFormat(char* format, char* buf, int maxlen)
+{
+	char b[1024];
+	int bufpos = 0, fmtpos = 0;
+	
+	b[0] = '\0';
+	buf[0] = '\0';
+	
+	for (; format[fmtpos] != '\0'; )
+	{
+		switch (format[fmtpos])
+		{
+			case '%': 
+				{
+					char tag[4];
+					strncpy(tag, (char *)(format + fmtpos + 1), 3);
+					tag[3] = '\0';
+					GetSubField(tag, format[fmtpos + 4], b,	sizeof(b) - 1);
+					if (*b)
+					{
+						int l = strlen(b);
+						strncat(buf, b, maxlen - bufpos - 1);
+						bufpos += l;
+						if (bufpos >= maxlen)
+						{
+							buf[maxlen - 1] = '\0';
+							return maxlen;
+						}
+					}
+					fmtpos += 5;
+					break;
+				}
+			default:
+				buf[bufpos] = format[fmtpos];
+				bufpos++;
+				fmtpos++;
+				buf[bufpos] = '\0';
+				break;
+		}
+	}
+	return bufpos;
+}
+
+//----------------------------------------------------------------------
+// int MarcRecord::GetField(char* tag, char* buf, int maxlen)
+//
+// append all subfields in a field together. 
+//----------------------------------------------------------------------
+int MarcRecord::GetField(char* tag, char* buf, int maxlen)
+{
+	int remain = maxlen - 1;
+	
+	buf[0] = '\0';
+	
+	if ((tag == NULL) || (*tag == '\0'))
+		return 0;
+	
+	for (std::vector<MarcDirectoryEntry>::size_type i=0; i!=directory_.size(); ++i)
+	{
+		if (!strncmp(tag, directory_[i].tag_, strlen(tag)))
+		{
+			for (std::vector<MarcField>::size_type j=0; j!=directory_[i].field_.size(); ++j)
+			{
+				int flen = directory_[i].field_[j].len_;
+				if (flen > remain)
+				{
+					strncat(buf, directory_[i].field_[j].data_ + 1, remain);
+					buf[maxlen] = '\0';
+					return 1;
+				}
+				else 
+				{
+					strncat(buf, directory_[i].field_[j].data_ + 1, flen);
+					remain -= flen;
+				}
+			}
+			return 1;
+		}
+	}
+	return 0;
+}
+
+//----------------------------------------------------------------------
+// int MarcRecord::GetSubFields(char* tag, char subtag, char* buf, int maxlen)
+//
+// append all fields with a certain subfield together.
+//----------------------------------------------------------------------
+int MarcRecord::GetSubFields(char* tag, char subtag, char* buf, int maxlen)
+{
+	int remain = maxlen - 1;
+	
+	buf[0] = '\0';
+	
+	if ((tag == NULL) || (*tag == '\0'))
+		return 0;
+	
+	for (std::vector<MarcDirectoryEntry>::size_type i=0; i!=directory_.size(); ++i)
+	{
+		if (!strncmp(tag, directory_[i].tag_, strlen(tag)))
+		{
+			for (std::vector<MarcField>::size_type j=0; j!=directory_[i].field_.size(); ++j)
+			{
+				if (*(directory_[i].field_[j].data_) == subtag)
+				{
+					int flen = directory_[i].field_[j].len_;
+					if (flen > remain)
+					{
+						strncpy(buf, directory_[i].field_[j].data_ + 1, remain);
+						buf[maxlen] = '\0';
+						return 1;
+					}
+					else 
+					{
+						strcpy(buf, directory_[i].field_[j].data_ + 1);
+						remain -= flen;
+					}
+				}
+			}
+		}
+	}
+	return 0;
+}
+
+int MarcRecord::HasField(char* tag)
+{
+	
+	for (std::vector<MarcDirectoryEntry>::size_type i=0; i!=directory_.size(); ++i)
+		if (!strncmp(tag, directory_[i].tag_, strlen(tag)))
+			return 1;
+		
+		return 0;
+}
+
+int MarcRecord::HasSubField(char* tag, char subtag)
+{
+	
+	for (std::vector<MarcDirectoryEntry>::size_type i=0; i!=directory_.size(); ++i)
+		if (!strncmp(tag, directory_[i].tag_, strlen(tag)))
+			for (std::vector<MarcField>::size_type j=0; j!=directory_[i].field_.size(); ++j)
+				if (*directory_[i].field_[j].data_ == subtag)
+					return 1;
+				return 0;
+}
+
+int MarcRecord::GetSubField(char *tag, char subtag, char *buf, 	int maxlen)
+{
+	
+	buf[0] = '\0';
+	
+	if ((tag == NULL) || (*tag == '\0'))
+		return 0;
+	
+	for (std::vector<MarcDirectoryEntry>::size_type i=0; i!=directory_.size(); ++i)
+	{
+		if (!strncmp(tag, directory_[i].tag_, strlen(tag)))
+		{
+			for (std::vector<MarcField>::size_type j=0; j!=directory_[i].field_.size(); ++j)
+			{
+				if (*(directory_[i].field_[j].data_) == subtag)
+				{
+					int l = directory_[i].field_[j].len_ - 1 > maxlen ? maxlen : directory_[i].field_[j].len_ - 1;
+					strncpy(buf, directory_[i].field_[j].data_ + 1, l);
+					buf[l] = '\0';
+					return 1;
+				}
+			}
+		}
+	}
+	return 0;
+}
+
+
+int GetNum(char *s, int n)
+{
+	char nbuf[10]; /* no more than 9 digits */
+	
+	strncpy(&nbuf[0], s, n);
+	nbuf[n] = '\0';
+	return (atoi(nbuf));
+}
+
+void MarcRecord::Dump()
+{
+	int dc = 0, fc = 0;
+	
+	printf("tags: ");
+	for (std::vector<MarcDirectoryEntry>::size_type i=0; i!=directory_.size(); ++i)
+	{
+		Printx(stdout, directory_[i].tag_, 3);
+		dc++;
+		for (std::vector<MarcField>::size_type j=0; j!=directory_[i].field_.size(); ++j)
+		{
+			if (directory_[i].field_[j].data_)
+			{
+				putchar((unsigned long)directory_[i].field_[j].data_);
+			}
+			fc++;
+			/*
+			printx(stdout, (char*)f->data + 1, f->len);
+			printf("\n"); */
+		}
+		printf(",");
+	}
+	putchar('\n');
+}
+
+
+
+
+
+void MarcRecord::PrintDetailed(FILE *fp)
+{
+	int count, i;
+	
+	fprintf(fp, "RecordLength:\t\t%i\n", GetNum(leader_.lreclen_, 5));
+	fprintf(fp, "RecordStatus:\t\t%c\n", leader_.status_);
+	fprintf(fp, "RecordType:\t\t%c\n", leader_.type_);
+	fprintf(fp, "BibLevel:\t\t%c\n", leader_.bibLevel_);
+	fprintf(fp, "ControlType:\t\t%c\n", leader_.ctrlType_);
+	fprintf(fp, "UndefCharPos:\t\t%c\n", leader_.undPos_);
+	fprintf(fp, "IndCount:\t\t%i\n", GetNum(&leader_.indCount_, 1));
+	fprintf(fp, "SubCodeCount:\t\t%i\n", GetNum(&leader_.scd_, 1));
+	fprintf(fp, "DataBaseAddr:\t\t%i\n", GetNum(leader_.base_, 5));
+	fprintf(fp, "EncodingLevel:\t\t%c\n", leader_.encLevel_);
+	fprintf(fp, "DescCatForm:\t\t%c\n", leader_.dcf_);
+	fprintf(fp, "LinkedRecReq:\t\t%c\n", leader_.lrr_);
+	fprintf(fp, "LengthOf LengthOfField:\t%i\n", GetNum(&leader_.llof_, 1));
+	fprintf(fp, "LengthOf StartCharPos:\t%i\n", GetNum(&leader_.lscp_, 1));
+	fprintf(fp, "LengthOf ImpDefined:\t%i\n", GetNum(&leader_.lidp_, 1));
+	fprintf(fp, "UndefinedEntry:\t\t%i\n", GetNum(&leader_.uep_, 1));
+	
+	count = (GetNum(leader_.base_, 5) - MARC_LEADER_LEN) / MARC_DIRENT_LEN;
+	for (i = 0; i < count; i++)
+	{
+		DirectoryEntry dir = *(DirectoryEntry*)(data_+MARC_LEADER_LEN+(i*MARC_DIRENT_LEN));
+		fprintf(fp, "\n");
+		fprintf(fp, "Tag:\t\t");
+		Printx(fp, dir.tag_, 3);
+		fprintf(fp, "\nLength:\t\t%i\n", GetNum(dir.len_, 4));
+		fprintf(fp, "StartPos:\t%i\n", GetNum(dir.scp_, 5));
+		fprintf(fp, "Data:\t\t");
+		Printx(fp, (char *)(data_ + GetNum(leader_.base_, 5) + GetNum(dir.scp_, 5)), GetNum(dir.len_, 4));
+		fprintf(fp, "\n");
+	}
+}
+
+/*
+desc:		parses the marc record and builds appropriate data structures in m
+
+params:
+
+	m		newly created marcRecord
+	
+returns:
+
+	1 on success
+	0 on parse or memory failure
+*/
+int MarcRecord::ParseMarcRecord()
+{
+	dirCount_ = (GetNum(leader_.base_, 5) - MARC_LEADER_LEN) / MARC_DIRENT_LEN;
+	
+	// For each MarcDirectory entry, create list of subfields
+	MarcDirectoryEntry dir_entry;
+	for (int i = 0; i < dirCount_; i++)
+	{
+		char*  data;
+		// Extract the directory component
+		DirectoryEntry dir_entry = *(DirectoryEntry*)(data_+MARC_LEADER_LEN+(i*MARC_DIRENT_LEN));
+
+		MarcDirectoryEntry marc_dir_entry;
+		
+		// Get a pointer to the data for this MarcDirectory
+		data = (char *)(data_ + GetNum(leader_.base_, 5) + GetNum(dir_entry.scp_, 5));
+		
+		// set the tag for this MarcDirectory 
+		marc_dir_entry.tag_ = dir_entry.tag_;
+		
+		/* add the list of subfields for this MarcDirectory */
+		if (!AddSubFields(marc_dir_entry, data))
+			return 0;
+		directory_.push_back(marc_dir_entry);
+		
+	}
+	
+	return 1;
+}
+
+void Printx(FILE* fp, char* s, int x)
+{
+	int i;
+	for (i = 0; i < x; i++)
+		fprintf(fp, "%c", s[i]);
+}
+
+//----------------------------------------------------------------------
+// int MarcRecord::AddSubFields(MarcDirectory& d, char* b)
+//
+// Parses and adds subfields to MarcDirectory
+//
+// params:
+//
+//	d		MarcDirectory to which subfields are added
+//	b		buffer of data for d
+//
+// returns:
+//
+//	1 on success
+//	0 on parse or memory error
+//----------------------------------------------------------------------
+int MarcRecord::AddSubFields(MarcDirectoryEntry& d, char* b)
+{
+	char *p, *start;
+	int cont = 1, length = 0;
+	
+	/* create new field */
+	MarcField field;
+	
+	
+	start = b;
+	for (p = b; ((*p != '\0') && (cont == 1)); p = (char *)p + 1)
+	{
+		switch (*p)
+		{
+			case SUBFDELIM:
+				/* end of current subfield, but more exist */
+				
+				/* set length and pointer to data for this field */
+				field.len_  = length;
+				field.data_ = start;
+				d.field_.push_back(field);
+				/* by definition, there should be more subfields, but we'll
+				check for NULL just in case
+				*/
+				if (*p + 1)
+				{
+				}
+				else 
+				{
+					/* uh oh */
+					return 0;
+				}
+				length = 0;
+				start = (char *)p + 1;
+				break;
+			case FIELDTERM:
+				/* end of subfield list */
+				
+				/* set length and pointer to data for this field */
+				field.len_  = length;
+				field.data_ = start;
+				d.field_.push_back(field);
+				
+				/* break out of loop */
+				cont = 0;
+				break;
+			case RECTERM:
+				/* end of record */
+				cont = 0;
+				break;
+			default:
+				/* regular character */			
+				length++;
+				break;
+		}
+	}
+	return 1;
+}
+
+void MarcRecord::Format(char *buf, int maxlen, int format)
+{
+	char b[1024];
+	char date[24];
+	char title[128];
+	
+	b[0] = '\0';
+	buf[0] = '\0';
+	
+	/* FIXME: get rid of this debugging crap sometime */
+	Dump();
+	
+	switch (format)
+	{
+		case MARC_FMT_BRIEF: 
+			{
+				GetSubField("245", 'a', title, 	sizeof(title) - 1);
+				GetSubField("260", 'c', date, sizeof(date) - 1);
+				if ((strlen(date) + strlen(title) + 2) <=(size_t)maxlen)
+				{
+					sprintf(buf, "%s %s", date, title);
+				}
+				else 
+				{
+					/* FIXME: we're overflowing the buffer! */
+				}
+				break;
+			}
+		case MARC_FMT_FULL: 
+			{
+				int dc = 0, fc = 0;
+				int remain = maxlen;
+				
+	            for (std::vector<MarcDirectoryEntry>::size_type i=0; i!=directory_.size(); ++i)
+				{
+					dc++;
+		            for (std::vector<MarcField>::size_type j=0; j!=directory_[i].field_.size(); ++j)
+					{
+						fc++;
+						if ((directory_[i].field_[j].len_ + 2) > remain)
+						{
+							strncat(buf, (char *)directory_[i].field_[j].data_ + 1, remain - 2);
+							* (buf + remain - 2) = '\n';
+							* (buf + remain - 1) = '\0';
+							/* we're out of room in the buffer. */
+							return;
+						}
+						if (directory_[i].field_[j].len_ > 0)
+						{
+							strncat(buf, (char*)directory_[i].field_[j].data_ + 1, directory_[i].field_[j].len_);
+							strncat(buf, "\n\0", 2);
+							remain -=(directory_[i].field_[j].len_ + 2);
+						}
+					} 
+				}
+				/*
+				marcRecord_getSubField(m, "245", 'a', title, 
+				sizeof(title) - 1);
+				marcRecord_getSubField(m, "245", 'a', title, 
+				sizeof(title) - 1);
+				marcRecord_getSubField(m, "260", 'c', date, 
+				sizeof(date) - 1);
+				sprintf(buf, "%s %s", date, title);
+				*/
+				break;
+			}
+		default:
+			break;
+	}
+}
+
+int MarcRecord::RecordLength()
+{
+	register int l = 0;
+	
+	
+	for (std::vector<MarcDirectoryEntry>::size_type i=0; i!=directory_.size(); ++i)
+		for (std::vector<MarcField>::size_type j=0; j!=directory_[i].field_.size(); ++j)
+			l += directory_[i].field_[i].len_;
+		
+        return l;
+}
+
Index: /gsdl/stable/build-src/packages/isis-gdl/Unimarc.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/Unimarc.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/Unimarc.h	(revision 20131)
@@ -0,0 +1,175 @@
+/**********************************************************************
+ *
+ * Unimarc.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef MARC_RECORD
+#define MARC_RECORD
+
+#define SUBFDELIM '\037'   // %
+#define FIELDTERM '\036'   // $
+#define RECTERM   '\035'   // # sharp
+
+#define MARC_LEADER_LEN 24
+#define MARC_DIRENT_LEN 12
+
+#define MARC_FMT_BRIEF 0
+#define MARC_FMT_FULL 1
+
+//---------------------
+// UNIMARC Record Label
+//---------------------
+struct  MarcLeader
+{
+	char	lreclen_[5];	/* logical record length */
+	char	status_;		/* record status_ */
+	char	type_;			/* type_ of record */
+	char	bibLevel_;	    /* bibliographic level */
+	char	ctrlType_;	    /* type_ of control */
+	char	undPos_;		/* undefined character position */
+	char	indCount_;	    /* indicator count */
+	char	scd_;			/* subfield code count */
+	char	base_[5];		/* base_ address of data */
+	char	encLevel_;	    /* encoding level */
+	char	dcf_;			/* descriptive cataloging form */
+	char	lrr_;			/* linked record requirement */
+	char	llof_;			/* length of the length-of-field portion */
+	char	lscp_;			/* length of starting-character-position portion */
+	char	lidp_;			/* length of implementation-defined portion */
+	char	uep_;			/* undefined entry map character position */
+
+	MarcLeader()
+	{
+		lreclen_[0]=' ';
+		lreclen_[1]=' ';
+		lreclen_[2]=' ';
+		lreclen_[3]=' ';
+		lreclen_[4]=' ';
+		status_   = '0';     // New record
+        type_     = '0';     // Language materials, printed
+	    bibLevel_ = '0';	     // Monographic
+	    ctrlType_ = '0';     // Hierarchical relationship undefined
+	    undPos_   = '0';     // Undefined, contains a blank
+	    indCount_ = '0';     // Invariably 2 in UNIMARC
+	    scd_      = '0';     // Invariably 2 in UNIMARC
+	    base_[0]  = ' ';     // Base_ address of data
+		base_[1]  = ' ';
+		base_[2]  = ' ';
+		base_[3]  = ' ';
+		base_[4]  = ' ';
+	    encLevel_ = '0';     // (Blank) full level
+	    dcf_      = '0';     // (Blank) record is in full ISBD form
+	    lrr_      = '0';     // Undefined, contains a blank
+	    llof_     = '4';     // Length of the length-of-field portion
+	    lscp_     = '5';     // Length of starting-character-position portion 
+	    lidp_     = '0';     // Length of implementation-defined portion
+	    uep_      = '0';     // Undefined, contains a blank
+	}
+
+   friend std::ostream& operator<<(std::ostream& s, const MarcLeader& leader);
+   friend std::istream& operator>>(std::istream& s, MarcLeader& leader);
+};
+
+//----------------
+// Directory entry
+//----------------
+struct DirectoryEntry
+{
+	char	tag_[3];		/* tag */
+	char	len_[4];		/* field length */
+	char	scp_[5];		/* starting character position */
+   friend std::ostream& operator<<(std::ostream& s, const DirectoryEntry& de);
+   friend std::istream& operator>>(std::istream& s, DirectoryEntry& leader);
+};
+inline std::istream& operator>>(std::istream& s, DirectoryEntry& de)
+{
+	s.read(de.tag_, 3);
+	s.read(de.len_, 4);
+	s.read(de.scp_, 5);
+	return s;
+}
+inline std::ostream& operator<<(std::ostream& s, const DirectoryEntry& de)
+{
+	s.write(de.tag_, 3);
+	s.write(de.len_, 4);
+	s.write(de.scp_, 5);
+	return s;
+}
+
+
+
+//------------------
+// Subfield item 
+//------------------
+struct MarcField
+{
+	int			len_;
+	char*       data_;
+};
+
+//-------------------
+// Directory entry
+//-------------------
+struct MarcDirectoryEntry
+{
+	char*                  tag_;
+	std::vector<MarcField> field_;
+};
+
+
+//---------------------------
+// UNIMARC record structure 
+//---------------------------
+
+class MarcRecord
+{
+protected:
+	MarcLeader      leader_;
+	char*           data_;
+	int			    length_;
+	int				dirCount_;
+	int				encapsulated_;
+	std::vector<MarcDirectoryEntry>   directory_;
+	
+    int ParseMarcRecord();
+    int AddSubFields(MarcDirectoryEntry& d, char* b);
+public:
+    MarcRecord(char* data, int length, int copyData);
+    ~MarcRecord();
+    void PrintDetailed(FILE* fp);
+    void Get(char* buf,int maxlen,int format);
+    int  GetSubField(char* tag, char subtag, char* buf, int maxlen);
+    int  GetField(char* tag, char* buf, int maxlen);
+    int  GetSubFields(char* tag, char subtag, char* buf, int maxlen);
+
+    int  HasField(char* tag);
+    int  HasSubField(char* tag, char subtag);
+
+    void Format(char* buf, int maxlen, int format);
+    int  RecordLength();
+    int  PrettyFormat(char* format, char* buf, int maxlen);
+
+    void Dump ();
+};
+#endif
Index: /gsdl/stable/build-src/packages/isis-gdl/XRFFile.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/XRFFile.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/XRFFile.cpp	(revision 20131)
@@ -0,0 +1,305 @@
+/**********************************************************************
+ *
+ * XRFFile.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////
+// XrfFile.cpp: XrfFile object methods
+//
+////////////////////////////////////////////////////////////
+#include "stdafx.h"
+#include "XRFFile.h"
+
+
+
+//-----------------------------------------------------------------------------------
+// IsisError  XrfFile::OpenXrf(const _TCHAR *fname, FileSystem::AccessMode mode
+//				                              /* = FileSystem::FILE_READWRITE */)
+//
+// Open xrf_ file with file name fname 
+//-----------------------------------------------------------------------------------
+IsisError  XrfFile::OpenXrf(const _TCHAR *fname, FileSystem::AccessMode mode
+				                              /* = FileSystem::FILE_READWRITE */)
+{
+  TCHAR xrfFileName[_MAX_PATH];
+  _tcscpy(xrfFileName, fname);
+
+  if (!CFileBase::Exists(xrfFileName)) {
+    xrfFileName[strlen(xrfFileName) - 3] = 'X';
+    xrfFileName[strlen(xrfFileName) - 2] = 'R';
+    xrfFileName[strlen(xrfFileName) - 1] = 'F';
+  }
+
+    IsisError isis_error;
+    xrfa_->xrfpos_ = -1;   // No block into buffer
+	try {
+        FileError rc = CFileBase::Open(xrfFileName, mode);
+	}
+	catch(CFileBaseException)
+	{
+		isis_error = ISIS_XRF_OPEN_ERROR;
+        throw CIsisDbException(isis_error, __FILE__, __LINE__); 
+	}
+  	long file_size   = CFileBase::FileSize(file_name);
+	
+	last_block_  = file_size/XRFBLKSIZE;
+
+	if (last_block_<1 || last_block_*XRFBLKSIZE != file_size)
+	{
+		isis_error =  ISIS_XRF_CORRUPT;
+        throw CIsisDbException(isis_error, __FILE__, __LINE__); 
+	}
+
+	return ISIS_NO_ERROR;
+}
+ 
+//////////////////////////////
+ 
+ 
+IsisError  XrfFile::CreateXrf(const _TCHAR *fname)
+// Creates an xrf_ file
+{
+    IsisError isis_error;
+	try 
+	{
+        FileError rc = CFileBase::Create(fname);
+    	// Initialize an empty block and write-it
+		xrfa_->Init();
+        xrfa_->xrfpos_ = 1; // Block number
+		xrfa_->xrfeof_ = 1; // Last xrf_ block
+        last_block_    = 1;		
+        WriteXrf(1L);
+	}
+	catch(CFileBaseException)
+	{
+		isis_error = ISIS_XRF_CREATE_ERROR;
+        throw CIsisDbException(isis_error, __FILE__, __LINE__);
+	}
+	
+    return ISIS_NO_ERROR;
+}
+//-----------------------------------------------------------------------------------
+// IsisError  XrfFile::CreateXrf(const _TCHAR *fname, long nextMfn)
+//
+// Special xrf_ file creation for building xrf_ blocks of an existing mst
+//-----------------------------------------------------------------------------------
+IsisError  XrfFile::CreateXrf(const _TCHAR *fname, long nextMfn)
+// Creates an xrf_ file
+{
+    IsisError isis_error;
+    long nBlocks = (nextMfn-1)/MAXTIV + 1;       // Number of blocks to allocate
+	try 
+	{
+        FileError rc = CFileBase::Create(fname);
+		xrfa_->Init();
+    	// Initialize an empty block and write-it
+		for (int iBlock=1; iBlock<= nBlocks; iBlock++)
+		{
+			TRACE("\niBlock=%d", iBlock);
+			xrfa_->xrfpos_ = iBlock;
+			xrfa_->xrfeof_ = 0;
+			if (iBlock == nBlocks)
+			    xrfa_->xrfeof_ = 1;
+
+			WriteXrf(iBlock);
+		}
+	}
+	catch(CFileBaseException)
+	{
+		isis_error = ISIS_XRF_CREATE_ERROR;
+        throw CIsisDbException(isis_error, __FILE__, __LINE__);
+	}
+
+    last_block_ = nBlocks;	
+    return ISIS_NO_ERROR;
+}
+
+//------------------------------------------------------------------------------
+// void XrfFile::UnPack(void)
+//
+// Unpack addresses of master file records. The current packed XRF block 
+// contained in xrf_ structure will be unpacked in xrfa_ structure.
+//
+//  A master file address is packed as follow: addr = mfb*2048 + mfp
+//
+//  2048 = 2**11 e.g. mfp->[0:2047] and block number -> [1: 2**20]
+//  2**20 = 1 048 576
+//
+// As we can put 127 addresses per block, then the limit on number of records
+// is 127 * 1 048 576
+//------------------------------------------------------------------------------
+void XrfFile::UnPack(void)
+{
+   fix_endianness(xrf_->xrfpos_);
+
+   xrfa_->xrfpos_ = xrf_->xrfpos_;
+   if (xrfa_->xrfpos_ < 0)
+   {
+      xrfa_->xrfpos_ = - xrf_->xrfpos_;
+      xrfa_->xrfeof_ = 1;
+   }
+   else
+      xrfa_->xrfeof_ = 0;
+ 
+   for (int i=0; i<MAXTIV; i++)
+   {
+      long j = xrf_->xrftiv_[i];             // Packed value
+      fix_endianness(j);
+      bool b = (j < 0);
+      if (b)
+         j = - j;
+      xrfa_->xrftiv_[i].xrfmfb_ = int(j / 2048L);   // Unpack block number
+      if (b)
+         xrfa_->xrftiv_[i].xrfmfb_ = -xrfa_->xrftiv_[i].xrfmfb_;
+      xrfa_->xrftiv_[i].xrfmfp_ = int(j % 2048L);   // Unpack offset
+   }
+}
+ 
+//------------------------------------------------------------------------------
+// void XrfFile::Pack(void)
+//
+// Pack addresses of master file records. The current unpacked XRF block 
+// contained in xrfa_ will be packed in xrf_ structure.
+//------------------------------------------------------------------------------
+void XrfFile::Pack(void)
+{
+   long j = xrfa_->xrfpos_;
+   if (xrfa_->xrfeof_ != 0)
+      j = -j;
+   xrf_->xrfpos_ = j;
+
+ 
+   for (int i=0; i<MAXTIV; i++)
+   {
+      j = xrfa_->xrftiv_[i].xrfmfb_;    // Unpacked block number
+      int b = (j < 0);
+      if (b)
+         j = - j;
+      //-------------------------------------------
+      // pack block number and offset in a long int
+      //-------------------------------------------
+      j = j * 2048 + xrfa_->xrftiv_[i].xrfmfp_;
+      if (b) j = -j;
+      xrf_->xrftiv_[i] = j;     // Put value in xrf_
+   }
+}
+ 
+//------------------------------------------------------------------------------
+// int XrfFile::GetMfp(long mfn, long& mfb, int& mfp)
+//
+// Gets the address of master file data record with MFN "mfn" by accessing the 
+// xrf_ file). mfb is the master file block number [1:NBLK] and mfp is the offset
+// in the master file block where the record starts [0:BLKSIZE-1]
+//
+//  Returns   Active              = Record active
+//            LogicalyDeleted     = Record logically deleted
+//            PhysicalyDeleted    = Record physically deleted
+//            EndOfFile
+//  Note: mfp can be >=      than BLKSIZE if the inverted file
+//  wasn't updated, then true mfp is mfp%BLKSIZE
+//------------------------------------------------------------------------------
+int XrfFile::GetMfp(long mfn, long& mfb, int& mfp)
+{
+	PRECONDITION(mfn>0);
+	PRECONDITION(last_block_>0);
+    int  comp;
+    long comb;
+    int  rc;
+	
+    long psxrf=(mfn-1)/MAXTIV+1;       // Block number
+	if (psxrf > last_block_)
+	{
+        rc = EndOfFile;                // Inexistent record (eof)
+		return rc;
+		throw CIsisDbException(ISIS_XRF_INVALID_BLOCK, __FILE__, __LINE__);
+	}
+    if (psxrf != xrfa_->xrfpos_) 
+	{                                  // If current block in xrf_ different
+		try
+		{
+            ReadXrf(psxrf);            // then read the block
+		}
+		catch (CFileBaseException e)
+		{
+            throw CIsisDbException(ISIS_XRF_READ_ERROR, __FILE__, __LINE__);
+		}
+
+    }
+    int i = int((mfn-1) % MAXTIV);     // Index
+    comb = xrfa_->xrftiv_[i].xrfmfb_;     // Master file block #
+    comp = xrfa_->xrftiv_[i].xrfmfp_;     // Offset in block
+
+	if (comb > 0)
+        rc = Active;                   // Record active 
+    else if (comb < 0 && comp > 0)
+        rc = LogicalyDeleted;          // Record logicaly deleted 
+	else if (comb == -1 && comp == 0)
+        rc = PhysicalyDeleted;         // Record physically deleted 
+    else if (comb == 0 && comp == 0)
+        rc = EndOfFile;                // Inexistent record (eof)
+	else
+	{
+        throw CIsisDbException(ISIS_XRF_INVALID_STATUS, __FILE__, __LINE__); 
+	}
+    mfb = labs(comb);
+    mfp = comp;
+	if (rc == Active)
+	{
+	    ASSERT(mfb>0 && mfb <= MAXMFB);
+		ASSERT(mfp>=0 && mfp < 2048);
+	    int mfpTemp = mfp%XRFBLKSIZE;
+	    ASSERT(mfpTemp>=0 && mfpTemp<XRFBLKSIZE);
+	}
+    return(rc);
+}
+ 
+void XrfFile::Grow(long from_lastb, long to_lastb)
+{
+	for (long i=from_lastb+1; i<=to_lastb; i++)
+	{
+        //--------------------
+        // append empty blocks
+        //--------------------
+ 		xrfa_->Init();
+		xrfa_->xrfpos_ = i;
+		xrfa_->xrfeof_ = (i==to_lastb) ? 1 : 0; // Eof flag
+	    try
+		{
+           WriteXrf(i);           // Write xrf_ at block address xrfb
+		}
+		catch (CFileBaseException)
+		{
+			throw(ISIS_XRF_WRITE_ERROR);
+		}
+	}
+}
+ 
+//------------------------------------------------------------------------------
+// void XrfFile::PutMfp(long mfn, long mfb, int mfp, int status)
+//
+// Puts the address of a master file record (mfb,mfp) as the address for MFN 
+// "mfn" in xrf_ file
+//------------------------------------------------------------------------------
+void XrfFile::PutMfp(long mfn, long mfb, int mfp, int status)
+{
+}
Index: /gsdl/stable/build-src/packages/isis-gdl/XRFFile.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/XRFFile.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/XRFFile.h	(revision 20131)
@@ -0,0 +1,151 @@
+/**********************************************************************
+ *
+ * XRFFile.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+////////////////////////////////////////////////////////////
+// XRFFILE.H : Cross Ref File object
+//
+////////////////////////////////////////////////////////////
+ 
+#ifndef _XRFFILE_H_
+#define _XRFFILE_H_
+#ifndef _BLKFILE_H_
+#include "blkfile.h"
+#endif
+#include <assert.h>
+#include "IErrors.h"
+ 
+const int MAXTIV     =     127; //  # of XRF entries per block
+const int XRFBLKSIZE =     512; //
+const int MAXMFB     = 1048576; 
+
+ 
+ 
+/////////////////////////////////////////
+// Cross reference file data structures
+//
+ 
+ 
+struct MSTA_ENTRY                 // Unpacked MST address
+{             
+   long       xrfmfb_;             // Master file block
+   short int  xrfmfp_;             // Offset
+} ;
+ 
+struct XRFA                       // To strore unpacked addresses
+{                
+   long          xrfpos_;          // Block number on xrf_ file or -1 if empty
+   short int     xrfeof_;          // 1 if last block of xrf_ file
+   MSTA_ENTRY xrftiv_[MAXTIV];     // MAXTIV unpacked MST addresses
+
+   XRFA() { Init(); }
+
+   void Init()
+   {
+	   xrfeof_ = 0;              // Not eof
+	   xrfpos_ = -1;             // empty   
+	   for (int i=0; i<MAXTIV; i++)
+	   {
+		   xrftiv_[i].xrfmfb_  = -1;
+	       xrftiv_[i].xrfmfp_  = 0;
+	   }
+   }
+
+
+} ;
+ 
+struct XRF                       // To store packed addresses
+{                                // for reading and wrting
+   long xrfpos_;                  // block number on xrf_ file
+   long xrftiv_[MAXTIV];          // MAXTIV packed MST addresses 
+} ;
+ 
+///////////////////
+// XrfFile class
+//
+
+ 
+class XrfFile : public BlkFile 
+{
+private:
+   XRF*  xrf_;             // Buffer to store packed addresses
+   XRFA* xrfa_;            // Buffer to store unpacked addresses
+   long  last_block_;      // Should always contain the last allocated block
+   
+   void ReadXrf(long b);
+   void WriteXrf(long b);
+   void UnPack();
+   void Pack();
+   void Grow(long from_lastb, long to_lastb);
+public:
+   XrfFile();
+   IsisError OpenXrf(const _TCHAR *fname,
+	                 FileSystem::AccessMode mode = FileSystem::FILE_READWRITE);
+   IsisError CreateXrf(const _TCHAR *fname);
+   IsisError CreateXrf(const _TCHAR *fname, long nextMfn);
+  ~XrfFile();
+   int  GetMfp(long mfn, long& mfb, int& mfp);
+   void PutMfp(long mfn, long mfb, int mfp, int status);
+};
+ 
+//////////////////////////////
+ 
+inline XrfFile::XrfFile()  :
+// Makes a XrfFile object that isn't connected to a file
+   xrf_(new XRF),
+   xrfa_(new XRFA)
+{
+   last_block_ = -1;   // Not yet initialize
+   // Nothing more to do
+}
+ 
+//////////////////////////////
+ 
+ 
+inline XrfFile::~XrfFile()
+{
+   if (xrf_)  delete xrf_;
+   if (xrfa_) delete xrfa_;
+}
+ 
+//////////////////////////////
+ 
+inline void XrfFile::ReadXrf(long b)
+// Reads block # b into xrf_ buffer
+{
+	assert(b>0);
+    ReadBlk(xrf_, b);
+    UnPack();
+}
+ 
+//////////////////////////////
+ 
+inline void XrfFile::WriteXrf(long b)
+// Writes the content of xrf_ buffer as block number b
+{
+	assert(b>0);
+    Pack();
+    WriteBlk(xrf_, b);
+}
+#endif
Index: /gsdl/stable/build-src/packages/isis-gdl/configure
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/configure	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/configure	(revision 20131)
@@ -0,0 +1,2828 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_default_prefix=../../..
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CXX_set=${CXX+set}
+ac_env_CXX_value=$CXX
+ac_cv_env_CXX_set=${CXX+set}
+ac_cv_env_CXX_value=$CXX
+ac_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_env_CXXFLAGS_value=$CXXFLAGS
+ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_cv_env_CXXFLAGS_value=$CXXFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Some influential environment variables:
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in ../../.. $srcdir/../../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in ../../.. $srcdir/../../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in ../../.. $srcdir/../../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CXX" && break
+done
+test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
+
+  CXX=$ac_ct_CXX
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5
+echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+	;;
+    conftest.$ac_ext )
+	# This is the source file.
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
+    * )
+	break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C++ compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C++ compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5
+echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  export ac_cv_exeext
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cxx_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+          ac_config_files="$ac_config_files Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\),-D\1=\2,g
+t quote
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[	 `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CXX@,$CXX,;t t
+s,@CXXFLAGS@,$CXXFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CXX@,$ac_ct_CXX,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
Index: /gsdl/stable/build-src/packages/isis-gdl/configure.in
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/configure.in	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/configure.in	(revision 20131)
@@ -0,0 +1,19 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT()
+
+dnl  default installation
+dnl will be overridden by command-line args from packages/configure
+AC_PREFIX_DEFAULT(../../..)
+
+dnl this uses the config.guess, config.sub and install-sh from gsdl.
+AC_CONFIG_AUX_DIR(../../..)
+
+dnl compiler - need c++
+AC_PROG_CXX
+
+dnl Windows extension
+AC_EXEEXT
+
+AC_PROG_INSTALL
+
+AC_OUTPUT(Makefile)
Index: /gsdl/stable/build-src/packages/isis-gdl/mytchar.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/mytchar.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/mytchar.h	(revision 20131)
@@ -0,0 +1,35 @@
+/**********************************************************************
+ *
+ * mytchar.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef __MY_TCHAR__
+#define __MY_TCHAR__
+
+#include "tchar.h"
+
+#ifndef _WIN32
+typedef wchar_t TCHAR;
+#endif
+
+#endif
Index: /gsdl/stable/build-src/packages/isis-gdl/stdafx.cpp
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/stdafx.cpp	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/stdafx.cpp	(revision 20131)
@@ -0,0 +1,33 @@
+/**********************************************************************
+ *
+ * stdafx.cpp
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+// stdafx.cpp : source file that includes just the standard includes
+// IsisGdl.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
Index: /gsdl/stable/build-src/packages/isis-gdl/stdafx.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/stdafx.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/stdafx.h	(revision 20131)
@@ -0,0 +1,40 @@
+/**********************************************************************
+ *
+ * stdafx.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+// #pragma once
+
+
+#include <iostream>
+#include <assert.h>
+#include "mytchar.h"
+#include "Compat.h"
+// TODO: reference additional headers your program requires here
+#include "IsisDef.h"
+
Index: /gsdl/stable/build-src/packages/isis-gdl/tchar.h
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/tchar.h	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/tchar.h	(revision 20131)
@@ -0,0 +1,1046 @@
+/**********************************************************************
+ *
+ * tchar.h
+ * Copyright (C) 2003  UNESCO
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/***
+*tchar.h - definitions for generic international text functions
+*
+*       Copyright (c) 1991-1997, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+*       Definitions for generic international functions, mostly defines
+*       which map string/formatted-io/ctype functions to char, wchar_t, or
+*       MBCS versions.  To be used for compatibility between single-byte,
+*       multi-byte and Unicode text models.
+*
+*       [Public]
+*
+****/
+
+#if     _MSC_VER > 1000 /*IFSTRIP=IGN*/
+#pragma once
+#endif
+
+#ifndef _INC_TCHAR
+#define _INC_TCHAR
+
+#ifdef  _MSC_VER
+#pragma warning(disable:4514)       /* disable unwanted C++ /W4 warning */
+/* #pragma warning(default:4514) */ /* use this to reenable, if necessary */
+#endif  /* _MSC_VER */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+/* Define __cdecl for non-Microsoft compilers */
+
+#if     ( !defined(_MSC_VER) && !defined(__cdecl) )
+#define __cdecl
+#endif
+
+
+/* Define _CRTIMP */
+
+#ifndef _CRTIMP
+#ifdef  CRTDLL
+#define _CRTIMP __declspec(dllexport)
+#else   /* ndef CRTDLL */
+#ifdef  _DLL
+#define _CRTIMP __declspec(dllimport)
+#else   /* ndef _DLL */
+#define _CRTIMP
+#endif  /* _DLL */
+#endif  /* CRTDLL */
+#endif  /* _CRTIMP */
+
+
+#define _ftcscat    _tcscat
+#define _ftcschr    _tcschr
+#define _ftcscpy    _tcscpy
+#define _ftcscspn   _tcscspn
+#define _ftcslen    _tcslen
+#define _ftcsncat   _tcsncat
+#define _ftcsncpy   _tcsncpy
+#define _ftcspbrk   _tcspbrk
+#define _ftcsrchr   _tcsrchr
+#define _ftcsspn    _tcsspn
+#define _ftcsstr    _tcsstr
+#define _ftcstok    _tcstok
+
+#define _ftcsdup    _tcsdup
+#define _ftcsnset   _tcsnset
+#define _ftcsrev    _tcsrev
+#define _ftcsset    _tcsset
+
+#define _ftcscmp      _tcscmp
+#define _ftcsicmp     _tcsicmp
+#define _ftcsnccmp    _tcsnccmp
+#define _ftcsncmp     _tcsncmp
+#define _ftcsncicmp   _tcsncicmp
+#define _ftcsnicmp    _tcsnicmp
+
+#define _ftcscoll     _tcscoll
+#define _ftcsicoll    _tcsicoll
+#define _ftcsnccoll   _tcsnccoll
+#define _ftcsncoll    _tcsncoll
+#define _ftcsncicoll  _tcsncicoll
+#define _ftcsnicoll   _tcsnicoll
+
+/* Redundant "logical-character" mappings */
+
+#define _ftcsclen   _tcsclen
+#define _ftcsnccat  _tcsnccat
+#define _ftcsnccpy  _tcsnccpy
+#define _ftcsncset  _tcsncset
+
+#define _ftcsdec    _tcsdec
+#define _ftcsinc    _tcsinc
+#define _ftcsnbcnt  _tcsnbcnt
+#define _ftcsnccnt  _tcsnccnt
+#define _ftcsnextc  _tcsnextc
+#define _ftcsninc   _tcsninc
+#define _ftcsspnp   _tcsspnp
+
+#define _ftcslwr    _tcslwr
+#define _ftcsupr    _tcsupr
+
+#define _ftclen     _tclen
+#define _ftccpy     _tccpy
+#define _ftccmp     _tccmp
+
+
+#ifdef  _UNICODE
+
+#ifdef  __cplusplus
+}   /* ... extern "C" */
+#endif
+
+/* ++++++++++++++++++++ UNICODE ++++++++++++++++++++ */
+
+#include <wchar.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifndef _WCTYPE_T_DEFINED
+typedef wchar_t wint_t;
+typedef wchar_t wctype_t;
+#define _WCTYPE_T_DEFINED
+#endif
+
+#ifndef __TCHAR_DEFINED
+typedef wchar_t     _TCHAR;
+typedef wchar_t     _TSCHAR;
+typedef wchar_t     _TUCHAR;
+typedef wchar_t     _TXCHAR;
+typedef wint_t      _TINT;
+#define __TCHAR_DEFINED
+#endif
+
+#ifndef _TCHAR_DEFINED
+#if     !__STDC__
+typedef wchar_t     TCHAR;
+#endif
+#define _TCHAR_DEFINED
+#endif
+
+#define _TEOF       WEOF
+
+#define __T(x)      L ## x
+
+
+/* Program */
+
+#define _tmain      wmain
+#define _tWinMain   wWinMain
+#define _tenviron   _wenviron
+#define __targv     __wargv
+
+/* Formatted i/o */
+
+#define _tprintf    wprintf
+#define _ftprintf   fwprintf
+#define _stprintf   swprintf
+#define _sntprintf  _snwprintf
+#define _vtprintf   vwprintf
+#define _vftprintf  vfwprintf
+#define _vstprintf  vswprintf
+#define _vsntprintf _vsnwprintf
+#define _tscanf     wscanf
+#define _ftscanf    fwscanf
+#define _stscanf    swscanf
+
+
+/* Unformatted i/o */
+
+#define _fgettc     fgetwc
+#define _fgettchar  _fgetwchar
+#define _fgetts     fgetws
+#define _fputtc     fputwc
+#define _fputtchar  _fputwchar
+#define _fputts     fputws
+#define _gettc      getwc
+#define _gettchar   getwchar
+#define _getts      _getws
+#define _puttc      putwc
+#define _puttchar   putwchar
+#define _putts      _putws
+#define _ungettc    ungetwc
+
+
+/* String conversion functions */
+
+#define _tcstod     wcstod
+#define _tcstol     wcstol
+#define _tcstoul    wcstoul
+
+#define _itot       _itow
+#define _ltot       _ltow
+#define _ultot      _ultow
+#define _ttoi       _wtoi
+#define _ttol       _wtol
+
+#define _ttoi64     _wtoi64
+#define _i64tot     _i64tow
+#define _ui64tot    _ui64tow
+
+/* String functions */
+
+#define _tcscat     wcscat
+#define _tcschr     wcschr
+#define _tcscpy     wcscpy
+#define _tcscspn    wcscspn
+#define _tcslen     wcslen
+#define _tcsncat    wcsncat
+#define _tcsncpy    wcsncpy
+#define _tcspbrk    wcspbrk
+#define _tcsrchr    wcsrchr
+#define _tcsspn     wcsspn
+#define _tcsstr     wcsstr
+#define _tcstok     wcstok
+
+#define _tcsdup     _wcsdup
+#define _tcsnset    _wcsnset
+#define _tcsrev     _wcsrev
+#define _tcsset     _wcsset
+
+#define _tcscmp     wcscmp
+#define _tcsicmp    _wcsicmp
+#define _tcsnccmp   wcsncmp
+#define _tcsncmp    wcsncmp
+#define _tcsncicmp  _wcsnicmp
+#define _tcsnicmp   _wcsnicmp
+
+#define _tcscoll    wcscoll
+#define _tcsicoll   _wcsicoll
+#define _tcsnccoll  _wcsncoll
+#define _tcsncoll   _wcsncoll
+#define _tcsncicoll _wcsnicoll
+#define _tcsnicoll  _wcsnicoll
+
+
+/* Execute functions */
+
+#define _texecl     _wexecl
+#define _texecle    _wexecle
+#define _texeclp    _wexeclp
+#define _texeclpe   _wexeclpe
+#define _texecv     _wexecv
+#define _texecve    _wexecve
+#define _texecvp    _wexecvp
+#define _texecvpe   _wexecvpe
+
+#define _tspawnl    _wspawnl
+#define _tspawnle   _wspawnle
+#define _tspawnlp   _wspawnlp
+#define _tspawnlpe  _wspawnlpe
+#define _tspawnv    _wspawnv
+#define _tspawnve   _wspawnve
+#define _tspawnvp   _wspawnvp
+#define _tspawnvp   _wspawnvp
+#define _tspawnvpe  _wspawnvpe
+
+#define _tsystem    _wsystem
+
+
+/* Time functions */
+
+#define _tasctime   _wasctime
+#define _tctime     _wctime
+#define _tstrdate   _wstrdate
+#define _tstrtime   _wstrtime
+#define _tutime     _wutime
+#define _tcsftime   wcsftime
+
+
+/* Directory functions */
+
+#define _tchdir     _wchdir
+#define _tgetcwd    _wgetcwd
+#define _tgetdcwd   _wgetdcwd
+#define _tmkdir     _wmkdir
+#define _trmdir     _wrmdir
+
+
+/* Environment/Path functions */
+
+#define _tfullpath  _wfullpath
+#define _tgetenv    _wgetenv
+#define _tmakepath  _wmakepath
+#define _tputenv    _wputenv
+#define _tsearchenv _wsearchenv
+#define _tsplitpath _wsplitpath
+
+
+/* Stdio functions */
+
+#define _tfdopen    _wfdopen
+#define _tfsopen    _wfsopen
+#define _tfopen     _wfopen
+#define _tfreopen   _wfreopen
+#define _tperror    _wperror
+#define _tpopen     _wpopen
+#define _ttempnam   _wtempnam
+#define _ttmpnam    _wtmpnam
+
+
+/* Io functions */
+
+#define _taccess    _waccess
+#define _tchmod     _wchmod
+#define _tcreat     _wcreat
+#define _tfindfirst _wfindfirst
+#define _tfindfirsti64  _wfindfirsti64
+#define _tfindnext  _wfindnext
+#define _tfindnexti64   _wfindnexti64
+#define _tmktemp    _wmktemp
+#define _topen      _wopen
+#define _tremove    _wremove
+#define _trename    _wrename
+#define _tsopen     _wsopen
+#define _tunlink    _wunlink
+
+#define _tfinddata_t    _wfinddata_t
+#define _tfinddatai64_t _wfinddatai64_t
+
+
+/* Stat functions */
+
+#define _tstat      _wstat
+#define _tstati64   _wstati64
+
+
+/* Setlocale functions */
+
+#define _tsetlocale _wsetlocale
+
+
+/* Redundant "logical-character" mappings */
+
+#define _tcsclen    wcslen
+#define _tcsnccat   wcsncat
+#define _tcsnccpy   wcsncpy
+#define _tcsncset   _wcsnset
+
+#define _tcsdec     _wcsdec
+#define _tcsinc     _wcsinc
+#define _tcsnbcnt   _wcsncnt
+#define _tcsnccnt   _wcsncnt
+#define _tcsnextc   _wcsnextc
+#define _tcsninc    _wcsninc
+#define _tcsspnp    _wcsspnp
+
+#define _tcslwr     _wcslwr
+#define _tcsupr     _wcsupr
+#define _tcsxfrm    wcsxfrm
+
+
+#if     (__STDC__ || defined(_NO_INLINING)) && !defined(_M_M68K)
+#define _tclen(_pc) (1)
+#define _tccpy(_pc1,_cpc2) ((*(_pc1) = *(_cpc2)))
+#define _tccmp(_cpc1,_cpc2) ((*(_cpc1))-(*(_cpc2)))
+#else   /* __STDC__ */
+__inline size_t __cdecl _tclen(const wchar_t *_cpc) { return (_cpc,1); }
+__inline void __cdecl _tccpy(wchar_t *_pc1, const wchar_t *_cpc2) { *_pc1 = (wchar_t)*_cpc2; }
+__inline int __cdecl _tccmp(const wchar_t *_cpc1, const wchar_t *_cpc2) { return (int) ((*_cpc1)-(*_cpc2)); }
+#endif  /* __STDC__ */
+
+
+/* ctype functions */
+
+#define _istalnum   iswalnum
+#define _istalpha   iswalpha
+#define _istascii   iswascii
+#define _istcntrl   iswcntrl
+#define _istdigit   iswdigit
+#define _istgraph   iswgraph
+#define _istlower   iswlower
+#define _istprint   iswprint
+#define _istpunct   iswpunct
+#define _istspace   iswspace
+#define _istupper   iswupper
+#define _istxdigit  iswxdigit
+
+#define _totupper   towupper
+#define _totlower   towlower
+
+#define _istlegal(_c)   (1)
+#define _istlead(_c)    (0)
+#define _istleadbyte(_c)    (0)
+
+
+#if     (__STDC__ || defined(_NO_INLINING)) && !defined(_M_M68K)
+#define _wcsdec(_cpc1, _cpc2) ((_cpc1)>=(_cpc2) ? NULL : (_cpc2)-1)
+#define _wcsinc(_pc)    ((_pc)+1)
+#define _wcsnextc(_cpc) ((unsigned int) *(_cpc))
+#define _wcsninc(_pc, _sz) (((_pc)+(_sz)))
+#define _wcsncnt(_cpc, _sz) ((wcslen(_cpc)>_sz) ? _sz : wcslen(_cpc))
+#define _wcsspnp(_cpc1, _cpc2) ((*((_cpc1)+wcsspn(_cpc1,_cpc2))) ? ((_cpc1)+wcsspn(_cpc1,_cpc2)) : NULL)
+#else   /* __STDC__ */
+__inline wchar_t * __cdecl _wcsdec(const wchar_t * _cpc1, const wchar_t * _cpc2) { return (wchar_t *)((_cpc1)>=(_cpc2) ? NULL : ((_cpc2)-1)); }
+__inline wchar_t * __cdecl _wcsinc(const wchar_t * _pc) { return (wchar_t *)(_pc+1); }
+__inline unsigned int __cdecl _wcsnextc(const wchar_t * _cpc) { return (unsigned int)*_cpc; }
+__inline wchar_t * __cdecl _wcsninc(const wchar_t * _pc, size_t _sz) { return (wchar_t *)(_pc+_sz); }
+__inline size_t __cdecl _wcsncnt( const wchar_t * _cpc, size_t _sz) { size_t len; len = wcslen(_cpc); return (len>_sz) ? _sz : len; }
+__inline wchar_t * __cdecl _wcsspnp( const wchar_t * _cpc1, const wchar_t * _cpc2) { return (*(_cpc1 += wcsspn(_cpc1,_cpc2))!='\0') ? (wchar_t*)_cpc1 : NULL; }
+#endif  /* __STDC__ */
+
+
+#else   /* ndef _UNICODE */
+
+/* ++++++++++++++++++++ SBCS and MBCS ++++++++++++++++++++ */
+
+#ifdef  __cplusplus
+}   /* ... extern "C" */
+#endif
+
+#include <string.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+#define _TEOF       EOF
+
+#define __T(x)      x
+
+
+/* Program */
+
+#define _tmain      main
+#define _tWinMain   WinMain
+#ifdef  _POSIX_
+#define _tenviron   environ
+#else
+#define _tenviron  _environ
+#endif
+#define __targv     __argv
+
+
+/* Formatted i/o */
+
+#define _tprintf    printf
+#define _ftprintf   fprintf
+#define _stprintf   sprintf
+#define _sntprintf  _snprintf
+#define _vtprintf   vprintf
+#define _vftprintf  vfprintf
+#define _vstprintf  vsprintf
+#define _vsntprintf _vsnprintf
+#define _tscanf     scanf
+#define _ftscanf    fscanf
+#define _stscanf    sscanf
+
+
+/* Unformatted i/o */
+
+#define _fgettc     fgetc
+#define _fgettchar  _fgetchar
+#define _fgetts     fgets
+#define _fputtc     fputc
+#define _fputtchar  _fputchar
+#define _fputts     fputs
+#define _gettc      getc
+#define _gettchar   getchar
+#define _getts      gets
+#define _puttc      putc
+#define _puttchar   putchar
+#define _putts      puts
+#define _ungettc    ungetc
+
+
+/* String conversion functions */
+
+#define _tcstod     strtod
+#define _tcstol     strtol
+#define _tcstoul    strtoul
+
+#define _itot       _itoa
+#define _ltot       _ltoa
+#define _ultot      _ultoa
+#define _ttoi       atoi
+#define _ttol       atol
+
+#define _ttoi64     _atoi64
+#define _i64tot     _i64toa
+#define _ui64tot    _ui64toa
+
+/* String functions */
+
+/* Note that _mbscat, _mbscpy and _mbsdup are functionally equivalent to 
+   strcat, strcpy and strdup, respectively. */
+
+#define _tcscat     strcat
+#define _tcscpy     strcpy
+#define _tcsdup     _strdup
+
+#define _tcslen     strlen
+#define _tcsxfrm    strxfrm
+
+
+/* Execute functions */
+
+#define _texecl     _execl
+#define _texecle    _execle
+#define _texeclp    _execlp
+#define _texeclpe   _execlpe
+#define _texecv     _execv
+#define _texecve    _execve
+#define _texecvp    _execvp
+#define _texecvpe   _execvpe
+
+#define _tspawnl    _spawnl
+#define _tspawnle   _spawnle
+#define _tspawnlp   _spawnlp
+#define _tspawnlpe  _spawnlpe
+#define _tspawnv    _spawnv
+#define _tspawnve   _spawnve
+#define _tspawnvp   _spawnvp
+#define _tspawnvpe  _spawnvpe
+
+#define _tsystem    system
+
+
+/* Time functions */
+
+#define _tasctime   asctime
+#define _tctime     ctime
+#define _tstrdate   _strdate
+#define _tstrtime   _strtime
+#define _tutime     _utime
+#define _tcsftime   strftime
+
+
+/* Directory functions */
+
+#define _tchdir     _chdir
+#define _tgetcwd    _getcwd
+#define _tgetdcwd   _getdcwd
+#define _tmkdir     _mkdir
+#define _trmdir     _rmdir
+
+
+/* Environment/Path functions */
+
+#define _tfullpath  _fullpath
+#define _tgetenv    getenv
+#define _tmakepath  _makepath
+#define _tputenv    _putenv
+#define _tsearchenv _searchenv
+#define _tsplitpath _splitpath
+
+
+/* Stdio functions */
+
+#ifdef  _POSIX_
+#define _tfdopen    fdopen
+#else
+#define _tfdopen    _fdopen
+#endif
+#define _tfsopen    _fsopen
+#define _tfopen     fopen
+#define _tfreopen   freopen
+#define _tperror    perror
+#define _tpopen     _popen
+#define _ttempnam   _tempnam
+#define _ttmpnam    tmpnam
+
+
+/* Io functions */
+
+#define _tchmod     _chmod
+#define _tcreat     _creat
+#define _tfindfirst _findfirst
+#define _tfindfirsti64  _findfirsti64
+#define _tfindnext  _findnext
+#define _tfindnexti64   _findnexti64
+#define _tmktemp    _mktemp
+
+#ifdef  _POSIX_
+#define _topen      open
+#define _taccess    access
+#else
+#define _topen      _open
+#define _taccess    _access
+#endif
+
+#define _tremove    remove
+#define _trename    rename
+#define _tsopen     _sopen
+#define _tunlink    _unlink
+
+#define _tfinddata_t    _finddata_t
+#define _tfinddatai64_t _finddatai64_t
+
+
+/* ctype functions */
+
+#define _istascii   isascii
+#define _istcntrl   iscntrl
+#define _istxdigit  isxdigit
+
+
+/* Stat functions */
+
+#define _tstat      _stat
+#define _tstati64   _stati64
+
+
+/* Setlocale functions */
+
+#define _tsetlocale setlocale
+
+
+#ifdef  _MBCS
+
+/* ++++++++++++++++++++ MBCS ++++++++++++++++++++ */
+
+#ifdef  __cplusplus
+}   /* ... extern "C" */
+#endif
+
+#include <mbstring.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+#ifndef __TCHAR_DEFINED
+typedef char            _TCHAR;
+typedef signed char     _TSCHAR;
+typedef unsigned char   _TUCHAR;
+typedef unsigned char   _TXCHAR;
+typedef unsigned int    _TINT;
+#define __TCHAR_DEFINED
+#endif
+
+#ifndef _TCHAR_DEFINED
+#if     !__STDC__
+typedef char            TCHAR;
+#endif
+#define _TCHAR_DEFINED
+#endif
+
+
+#ifdef  _MB_MAP_DIRECT
+
+/* use mb functions directly - types must match */
+
+/* String functions */
+
+#define _tcschr     _mbschr
+#define _tcscspn    _mbscspn
+#define _tcsncat    _mbsnbcat
+#define _tcsncpy    _mbsnbcpy
+#define _tcspbrk    _mbspbrk
+#define _tcsrchr    _mbsrchr
+#define _tcsspn     _mbsspn
+#define _tcsstr     _mbsstr
+#define _tcstok     _mbstok
+
+#define _tcsnset    _mbsnbset
+#define _tcsrev     _mbsrev
+#define _tcsset     _mbsset
+
+#define _tcscmp     _mbscmp
+#define _tcsicmp    _mbsicmp
+#define _tcsnccmp   _mbsncmp
+#define _tcsncmp    _mbsnbcmp
+#define _tcsncicmp  _mbsnicmp
+#define _tcsnicmp   _mbsnbicmp
+
+#define _tcscoll    _mbscoll
+#define _tcsicoll   _mbsicoll
+#define _tcsnccoll  _mbsncoll
+#define _tcsncoll   _mbsnbcoll
+#define _tcsncicoll _mbsnicoll
+#define _tcsnicoll  _mbsnbicoll
+
+
+/* "logical-character" mappings */
+
+#define _tcsclen    _mbslen
+#define _tcsnccat   _mbsncat
+#define _tcsnccpy   _mbsncpy
+#define _tcsncset   _mbsnset
+
+
+/* MBCS-specific mappings */
+
+#define _tcsdec     _mbsdec
+#define _tcsinc     _mbsinc
+#define _tcsnbcnt   _mbsnbcnt
+#define _tcsnccnt   _mbsnccnt
+#define _tcsnextc   _mbsnextc
+#define _tcsninc    _mbsninc
+#define _tcsspnp    _mbsspnp
+
+#define _tcslwr     _mbslwr
+#define _tcsupr     _mbsupr
+
+#define _tclen      _mbclen
+#define _tccpy      _mbccpy
+
+#define _tccmp(_cpuc1,_cpuc2)   _tcsnccmp(_cpuc1,_cpuc2,1)
+
+
+#else /* _MB_MAP_DIRECT */
+
+#if     (__STDC__ || defined(_NO_INLINING)) && !defined(_M_M68K)
+
+/* use type-safe linked-in function thunks */
+
+/* String functions */
+
+_CRTIMP char * __cdecl _tcschr(const char *, unsigned int);
+_CRTIMP size_t __cdecl _tcscspn(const char *, const char *);
+_CRTIMP char * __cdecl _tcsncat(char *, const char *, size_t);
+_CRTIMP char * __cdecl _tcsncpy(char *, const char *, size_t);
+_CRTIMP char * __cdecl _tcspbrk(const char *, const char *);
+_CRTIMP char * __cdecl _tcsrchr(const char *, int);
+_CRTIMP size_t __cdecl _tcsspn(const char *, const char *);
+_CRTIMP char * __cdecl _tcsstr(const char *, const char *);
+_CRTIMP char * __cdecl _tcstok(char *, const char *);
+
+_CRTIMP char * __cdecl _tcsnset(char *, unsigned int, size_t);
+_CRTIMP char * __cdecl _tcsrev(char *);
+_CRTIMP char * __cdecl _tcsset(char *, unsigned int);
+
+_CRTIMP int __cdecl _tcscmp(const char *, const char *);
+_CRTIMP int __cdecl _tcsicmp(const char *, const char *);
+_CRTIMP int __cdecl _tcsnccmp(const char *, const char *, size_t);
+_CRTIMP int __cdecl _tcsncmp(const char *, const char *, size_t);
+_CRTIMP int __cdecl _tcsncicmp(const char *, const char *, size_t);
+_CRTIMP int __cdecl _tcsnicmp(const char *, const char *, size_t);
+
+_CRTIMP int __cdecl _tcscoll(const char *, const char *);
+_CRTIMP int __cdecl _tcsicoll(const char *, const char *);
+_CRTIMP int __cdecl _tcsnccoll(const char *, const char *, size_t);
+_CRTIMP int __cdecl _tcsncoll(const char *, const char *, size_t);
+_CRTIMP int __cdecl _tcsncicoll(const char *, const char *, size_t);
+_CRTIMP int __cdecl _tcsnicoll(const char *, const char *, size_t);
+
+
+/* "logical-character" mappings */
+
+_CRTIMP size_t __cdecl _tcsclen(const char *);
+_CRTIMP char * __cdecl _tcsnccat(char *, const char *, size_t);
+_CRTIMP char * __cdecl _tcsnccpy(char *, const char *, size_t);
+_CRTIMP char * __cdecl _tcsncset(char *, unsigned int, size_t);
+
+
+/* MBCS-specific mappings */
+
+_CRTIMP char * __cdecl _tcsdec(const char *, const char *);
+_CRTIMP char * __cdecl _tcsinc(const char *);
+_CRTIMP size_t __cdecl _tcsnbcnt(const char *, size_t);
+_CRTIMP size_t __cdecl _tcsnccnt(const char *, size_t);
+_CRTIMP unsigned int __cdecl _tcsnextc (const char *);
+_CRTIMP char * __cdecl _tcsninc(const char *, size_t);
+_CRTIMP char * __cdecl _tcsspnp(const char *, const char *);
+
+_CRTIMP char * __cdecl _tcslwr(char *);
+_CRTIMP char * __cdecl _tcsupr(char *);
+
+_CRTIMP size_t __cdecl _tclen(const char *);
+_CRTIMP void __cdecl _tccpy(char *, const char *);
+
+
+#else   /* __STDC__ */
+
+/* the default: use type-safe inline function thunks */
+
+#define _PUC    unsigned char *
+#define _CPUC   const unsigned char *
+#define _PC     char *
+#define _CPC    const char *
+#define _UI     unsigned int
+
+
+/* String functions */
+
+__inline _PC _tcschr(_CPC _s1,_UI _c) {return (_PC)_mbschr((_CPUC)_s1,_c);}
+__inline size_t _tcscspn(_CPC _s1,_CPC _s2) {return _mbscspn((_CPUC)_s1,(_CPUC)_s2);}
+__inline _PC _tcsncat(_PC _s1,_CPC _s2,size_t _n) {return (_PC)_mbsnbcat((_PUC)_s1,(_CPUC)_s2,_n);}
+__inline _PC _tcsncpy(_PC _s1,_CPC _s2,size_t _n) {return (_PC)_mbsnbcpy((_PUC)_s1,(_CPUC)_s2,_n);}
+__inline _PC _tcspbrk(_CPC _s1,_CPC _s2) {return (_PC)_mbspbrk((_CPUC)_s1,(_CPUC)_s2);}
+__inline _PC _tcsrchr(_CPC _s1,_UI _c) {return (_PC)_mbsrchr((_CPUC)_s1,_c);}
+__inline size_t _tcsspn(_CPC _s1,_CPC _s2) {return _mbsspn((_CPUC)_s1,(_CPUC)_s2);}
+__inline _PC _tcsstr(_CPC _s1,_CPC _s2) {return (_PC)_mbsstr((_CPUC)_s1,(_CPUC)_s2);}
+__inline _PC _tcstok(_PC _s1,_CPC _s2) {return (_PC)_mbstok((_PUC)_s1,(_CPUC)_s2);}
+
+__inline _PC _tcsnset(_PC _s1,_UI _c,size_t _n) {return (_PC)_mbsnbset((_PUC)_s1,_c,_n);}
+__inline _PC _tcsrev(_PC _s1) {return (_PC)_mbsrev((_PUC)_s1);}
+__inline _PC _tcsset(_PC _s1,_UI _c) {return (_PC)_mbsset((_PUC)_s1,_c);}
+
+__inline int _tcscmp(_CPC _s1,_CPC _s2) {return _mbscmp((_CPUC)_s1,(_CPUC)_s2);}
+__inline int _tcsicmp(_CPC _s1,_CPC _s2) {return _mbsicmp((_CPUC)_s1,(_CPUC)_s2);}
+__inline int _tcsnccmp(_CPC _s1,_CPC _s2,size_t _n) {return _mbsncmp((_CPUC)_s1,(_CPUC)_s2,_n);}
+__inline int _tcsncmp(_CPC _s1,_CPC _s2,size_t _n) {return _mbsnbcmp((_CPUC)_s1,(_CPUC)_s2,_n);}
+__inline int _tcsncicmp(_CPC _s1,_CPC _s2,size_t _n) {return _mbsnicmp((_CPUC)_s1,(_CPUC)_s2,_n);}
+__inline int _tcsnicmp(_CPC _s1,_CPC _s2,size_t _n) {return _mbsnbicmp((_CPUC)_s1,(_CPUC)_s2,_n);}
+
+__inline int _tcscoll(_CPC _s1,_CPC _s2) {return _mbscoll((_CPUC)_s1,(_CPUC)_s2);}
+__inline int _tcsicoll(_CPC _s1,_CPC _s2) {return _mbsicoll((_CPUC)_s1,(_CPUC)_s2);}
+__inline int _tcsnccoll(_CPC _s1,_CPC _s2,size_t _n) {return _mbsncoll((_CPUC)_s1,(_CPUC)_s2,_n);}
+__inline int _tcsncoll(_CPC _s1,_CPC _s2,size_t _n) {return _mbsnbcoll((_CPUC)_s1,(_CPUC)_s2,_n);}
+__inline int _tcsncicoll(_CPC _s1,_CPC _s2,size_t _n) {return _mbsnicoll((_CPUC)_s1,(_CPUC)_s2,_n);}
+__inline int _tcsnicoll(_CPC _s1,_CPC _s2,size_t _n) {return _mbsnbicoll((_CPUC)_s1,(_CPUC)_s2,_n);}
+
+
+/* "logical-character" mappings */
+
+__inline size_t _tcsclen(_CPC _s1) {return _mbslen((_CPUC)_s1);}
+__inline _PC _tcsnccat(_PC _s1,_CPC _s2,size_t _n) {return (_PC)_mbsncat((_PUC)_s1,(_CPUC)_s2,_n);}
+__inline _PC _tcsnccpy(_PC _s1,_CPC _s2,size_t _n) {return (_PC)_mbsncpy((_PUC)_s1,(_CPUC)_s2,_n);}
+__inline _PC _tcsncset(_PC _s1,_UI _c,size_t _n) {return (_PC)_mbsnset((_PUC)_s1,_c,_n);}
+
+
+/* MBCS-specific mappings */
+
+__inline _PC _tcsdec(_CPC _s1,_CPC _s2) {return (_PC)_mbsdec((_CPUC)_s1,(_CPUC)_s2);}
+__inline _PC _tcsinc(_CPC _s1) {return (_PC)_mbsinc((_CPUC)_s1);}
+__inline size_t _tcsnbcnt(_CPC _s1,size_t _n) {return _mbsnbcnt((_CPUC)_s1,_n);}
+__inline size_t _tcsnccnt(_CPC _s1,size_t _n) {return _mbsnccnt((_CPUC)_s1,_n);}
+__inline _PC _tcsninc(_CPC _s1,size_t _n) {return (_PC)_mbsninc((_CPUC)_s1,_n);}
+__inline _PC _tcsspnp(_CPC _s1,_CPC _s2) {return (_PC)_mbsspnp((_CPUC)_s1,(_CPUC)_s2);}
+__inline _PC _tcslwr(_PC _s1) {return (_PC)_mbslwr((_PUC)_s1);}
+__inline _PC _tcsupr(_PC _s1) {return (_PC)_mbsupr((_PUC)_s1);}
+
+__inline size_t _tclen(_CPC _s1) {return _mbclen((_CPUC)_s1);}
+__inline void _tccpy(_PC _s1,_CPC _s2) {_mbccpy((_PUC)_s1,(_CPUC)_s2); return;}
+
+
+/* inline helper */
+__inline _UI _tcsnextc(_CPC _s1) {_UI _n=0; if (_ismbblead((_UI)*(_PUC)_s1)) _n=((_UI)*_s1++)<<8; _n+=(_UI)*_s1; return(_n);}
+
+
+#endif  /* __STDC__ */
+
+#endif  /* _MB_MAP_DIRECT */
+
+
+/* MBCS-specific mappings */
+
+#define _tccmp(_cp1,_cp2)   _tcsnccmp(_cp1,_cp2,1)
+
+
+/* ctype functions */
+
+#define _istalnum   _ismbcalnum
+#define _istalpha   _ismbcalpha
+#define _istdigit   _ismbcdigit
+#define _istgraph   _ismbcgraph
+#define _istlegal   _ismbclegal
+#define _istlower   _ismbclower
+#define _istprint   _ismbcprint
+#define _istpunct   _ismbcpunct
+#define _istspace   _ismbcspace
+#define _istupper   _ismbcupper
+
+#define _totupper   _mbctoupper
+#define _totlower   _mbctolower
+
+#define _istlead    _ismbblead
+#define _istleadbyte    isleadbyte
+
+#else   /* !_MBCS */
+
+/* ++++++++++++++++++++ SBCS ++++++++++++++++++++ */
+
+
+#ifndef __TCHAR_DEFINED
+typedef char            _TCHAR;
+typedef signed char     _TSCHAR;
+typedef unsigned char   _TUCHAR;
+typedef char            _TXCHAR;
+typedef int             _TINT;
+#define __TCHAR_DEFINED
+#endif
+
+#ifndef _TCHAR_DEFINED
+#if     !__STDC__
+typedef char            TCHAR;
+#endif
+#define _TCHAR_DEFINED
+#endif
+
+
+/* String functions */
+
+#define _tcschr     strchr
+#define _tcscspn    strcspn
+#define _tcsncat    strncat
+#define _tcsncpy    strncpy
+#define _tcspbrk    strpbrk
+#define _tcsrchr    strrchr
+#define _tcsspn     strspn
+#define _tcsstr     strstr
+#define _tcstok     strtok
+
+#define _tcsnset    _strnset
+#define _tcsrev     _strrev
+#define _tcsset     _strset
+
+#define _tcscmp     strcmp
+#define _tcsicmp    _stricmp
+#define _tcsnccmp   strncmp
+#define _tcsncmp    strncmp
+#define _tcsncicmp  _strnicmp
+#define _tcsnicmp   _strnicmp
+
+#define _tcscoll    strcoll
+#define _tcsicoll   _stricoll
+#define _tcsnccoll  _strncoll
+#define _tcsncoll   _strncoll
+#define _tcsncicoll _strnicoll
+#define _tcsnicoll  _strnicoll
+
+
+/* "logical-character" mappings */
+
+#define _tcsclen    strlen
+#define _tcsnccat   strncat
+#define _tcsnccpy   strncpy
+#define _tcsncset   _strnset
+
+
+/* MBCS-specific functions */
+
+#define _tcsdec     _strdec
+#define _tcsinc     _strinc
+#define _tcsnbcnt   _strncnt
+#define _tcsnccnt   _strncnt
+#define _tcsnextc   _strnextc
+#define _tcsninc    _strninc
+#define _tcsspnp    _strspnp
+
+#define _tcslwr     _strlwr
+#define _tcsupr     _strupr
+#define _tcsxfrm    strxfrm
+
+#define _istlead(_c)    (0)
+#define _istleadbyte(_c)    (0)
+
+#if     (__STDC__ || defined(_NO_INLINING)) && !defined(_M_M68K)
+#define _tclen(_pc) (1)
+#define _tccpy(_pc1,_cpc2) (*(_pc1) = *(_cpc2))
+#define _tccmp(_cpc1,_cpc2) (((unsigned char)*(_cpc1))-((unsigned char)*(_cpc2)))
+#else   /* __STDC__ */
+__inline size_t __cdecl _tclen(const char *_cpc) { return (_cpc,1); }
+__inline void __cdecl _tccpy(char *_pc1, const char *_cpc2) { *_pc1 = *_cpc2; }
+__inline int __cdecl _tccmp(const char *_cpc1, const char *_cpc2) { return (int) (((unsigned char)*_cpc1)-((unsigned char)*_cpc2)); }
+#endif  /* __STDC__ */
+
+
+/* ctype-functions */
+
+#define _istalnum   isalnum
+#define _istalpha   isalpha
+#define _istdigit   isdigit
+#define _istgraph   isgraph
+#define _istlower   islower
+#define _istprint   isprint
+#define _istpunct   ispunct
+#define _istspace   isspace
+#define _istupper   isupper
+
+#define _totupper   toupper
+#define _totlower   tolower
+
+#define _istlegal(_c)   (1)
+
+
+/* the following is optional if functional versions are available */
+
+/* define NULL pointer value */
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL    0
+#else
+#define NULL    ((void *)0)
+#endif
+#endif
+
+
+#if     (__STDC__ || defined(_NO_INLINING)) && !defined(_M_M68K)
+#define _strdec(_cpc1, _cpc2) ((_cpc1)>=(_cpc2) ? NULL : (_cpc2)-1)
+#define _strinc(_pc)    ((_pc)+1)
+#define _strnextc(_cpc) ((unsigned int) *(_cpc))
+#define _strninc(_pc, _sz) (((_pc)+(_sz)))
+#define _strncnt(_cpc, _sz) ((strlen(_cpc)>_sz) ? _sz : strlen(_cpc))
+#define _strspnp(_cpc1, _cpc2) ((*((_cpc1)+strspn(_cpc1,_cpc2))) ? ((_cpc1)+strspn(_cpc1,_cpc2)) : NULL)
+#else   /* __STDC__ */
+__inline char * __cdecl _strdec(const char * _cpc1, const char * _cpc2) { return (char *)((_cpc1)>=(_cpc2) ? NULL : (_cpc2-1)); }
+__inline char * __cdecl _strinc(const char * _pc) { return (char *)(_pc+1); }
+__inline unsigned int __cdecl _strnextc(const char * _cpc) { return (unsigned int)*_cpc; }
+__inline char * __cdecl _strninc(const char * _pc, size_t _sz) { return (char *)(_pc+_sz); }
+__inline size_t __cdecl _strncnt( const char * _cpc, size_t _sz) { size_t len; len = strlen(_cpc); return (len>_sz) ? _sz : len; }
+__inline char * __cdecl _strspnp( const char * _cpc1, const char * _cpc2) { return (*(_cpc1 += strspn(_cpc1,_cpc2))!='\0') ? (char*)_cpc1 : NULL; }
+#endif  /* __STDC__ */
+
+
+#endif  /* _MBCS */
+
+#endif  /* _UNICODE */
+
+
+/* Generic text macros to be used with string literals and character constants.
+   Will also allow symbolic constants that resolve to same. */
+
+#define _T(x)       __T(x)
+#define _TEXT(x)    __T(x)
+
+
+#ifdef  __cplusplus
+}   /* ... extern "C" */
+#endif
+
+#endif  /* _INC_TCHAR */
Index: /gsdl/stable/build-src/packages/isis-gdl/win32.mak
===================================================================
--- /gsdl/stable/build-src/packages/isis-gdl/win32.mak	(revision 20131)
+++ /gsdl/stable/build-src/packages/isis-gdl/win32.mak	(revision 20131)
@@ -0,0 +1,74 @@
+# ISIS-GDL
+
+GSDLHOME = ..\..\..
+
+CC = cl
+AR = lib
+
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+!IF $(DLL)
+CXXFLAGS = $(CXXFLAGS) -MD 
+!ELSE
+!IF ($(DLLDEBUG))
+CXXFLAGS = $(CXXFLAGS) -MDd
+!ENDIF
+!ENDIF
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) -nologo $(LDFLAGS)
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $<
+
+ANSI2KNR = 
+o = .obj
+e = .exe
+
+HEADERS = AbstractIsisDb.h  CacheMan.h  Debug.h IErrors.h IsisUtil.h  \
+	XRFFile.h BlkFile.h Checking.h  Fdt.h IsisDb.h MFFile.h  mytchar.h \
+	CRC32.h Compat.h  File.h IsisDef.h  Master.h  stdafx.h \
+	CRCTab.h  DLLCode.h FileSystem.h  IsisTypes.h Unimarc.h  tchar.h
+
+
+SOURCES = CRC32.cpp Debug.cpp  FileSystem.cpp  IsisGdl.cpp Master.cpp  \
+	 stdafx.cpp CacheMan.cpp  Fdt.cpp  IErrors.cpp IsisUtil.cpp  \
+	 Unimarc.cpp Checking.cpp File.cpp IsisDb.cpp MFFile.cpp XRFFile.cpp
+
+OBJECTS = IsisGdl$o CacheMan$o Checking$o CRC32$o Fdt$o File$o Debug$o \
+	FileSystem$o IErrors$o IsisDb$o IsisUtil$o Master$o MFFile$o \
+	stdafx$o Unimarc$o XRFFile$o
+
+EXEC = IsisGdl$e
+
+DEFS = 
+
+all: $(EXEC)
+
+install: $(EXEC)
+	if NOT EXIST "$(GSDLHOME)\bin\windows" mkdir "$(GSDLHOME)\bin\windows"
+	copy $(EXEC) "$(GSDLHOME)\bin\windows"
+
+clean:
+	del *.obj
+	del $(EXEC)
+
+IsisGdl$e: $(OBJECTS) $(LIBS)
+	  $(LINK) $(OBJECTS) $(LIBS)
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/ACKNOWLEDGMENTS
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/ACKNOWLEDGMENTS	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/ACKNOWLEDGMENTS	(revision 20131)
@@ -0,0 +1,2 @@
+This product includes software developed by the
+Apache Software Foundation (http://www.apache.org/).
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/COPYING
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/COPYING	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/COPYING	(revision 20131)
@@ -0,0 +1,345 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 		59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+	Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/Counter.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/Counter.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/Counter.java	(revision 20131)
@@ -0,0 +1,73 @@
+/*
+ *    Counter.java
+ *    Copyright (C) 2000 Eibe Frank
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.io.*;
+
+/**
+ * Class that implements a simple counter.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version 1.0
+ */
+public class Counter implements Serializable {
+  
+  /** Integer value stored */
+    private int m_val = 1;
+  
+  /**
+   * Initializes the counter to 1
+   */
+  public Counter() {
+    
+    m_val = 1;
+  }
+  
+  /**
+   * Initializes the counter to the given value
+   */
+  public Counter(int val) {
+    
+    m_val = val;
+  }
+  
+  /**
+   * Increments the counter.
+   */
+  public void increment() {
+    
+    m_val++;
+  }
+  
+  /**
+   * Gets the value.
+   * @return the value
+   */
+  public int value() {
+    
+    return m_val;
+  }
+  
+  /**
+   * Returns string containing value.
+   */
+  public String toString() {
+    
+    return String.valueOf(m_val);
+  }
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/GermanStemmer.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/GermanStemmer.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/GermanStemmer.java	(revision 20131)
@@ -0,0 +1,309 @@
+
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * 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. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache Lucene" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache Lucene", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
+ * ITS 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+/**
+ * A stemmer for German words. The algorithm is based on the report
+ * "A Fast and Simple Stemming Algorithm for German Words" by Jörg
+ * Caumanns (joerg.caumanns@isst.fhg.de).
+ *
+ * Changed stem() from protected to public.
+ * Changed coding for umlaute to unicode.
+ *
+ * @author    Gerhard Schwarz
+ * @version   $Id$
+ */
+public class GermanStemmer extends Stemmer
+{
+    /**
+     * Buffer for the terms while stemming them.
+     */
+    private StringBuffer sb = new StringBuffer();
+
+    /**
+     * Indicates if a term is handled as a noun.
+     */
+    private boolean uppercase = false;
+
+    /**
+     * Amount of characters that are removed with <tt>substitute()</tt> while stemming.
+     */
+    private int substCount = 0;
+
+    /**
+     * Stemms the given term to an unique <tt>discriminator</tt>.
+     *
+     * @param term  The term that should be stemmed.
+     * @return      Discriminator for <tt>term</tt>
+     */
+    public String stem( String term )
+    {
+	// Mark a possible noun.
+	uppercase = Character.isUpperCase( term.charAt( 0 ) );
+	// Use lowercase for medium stemming.
+	term = term.toLowerCase();
+	if ( !isStemmable( term ) )
+	    return term;
+	// Reset the StringBuffer.
+	sb.delete( 0, sb.length() );
+	sb.insert( 0, term );
+	// Stemming starts here...
+	substitute( sb );
+	strip( sb );
+	optimize( sb );
+	resubstitute( sb );
+	removeParticleDenotion( sb );
+	return sb.toString();
+    }
+
+    /**
+     * Checks if a term could be stemmed.
+     *
+     * @return  true if, and only if, the given term consists in letters.
+     */
+    private boolean isStemmable( String term )
+    {
+	for ( int c = 0; c < term.length(); c++ ) {
+	    if ( !Character.isLetter( term.charAt( c ) ) ) return false;
+	}
+	return true;
+    }
+
+    /**
+     * suffix stripping (stemming) on the current term. The stripping is reduced
+     * to the seven "base" suffixes "e", "s", "n", "t", "em", "er" and * "nd",
+     * from which all regular suffixes are build of. The simplification causes
+     * some overstemming, and way more irregular stems, but still provides unique.
+     * discriminators in the most of those cases.
+     * The algorithm is context free, except of the length restrictions.
+     */
+    private void strip( StringBuffer buffer )
+    {
+	boolean doMore = true;
+	while ( doMore && buffer.length() > 3 ) {
+	    if ( ( buffer.length() + substCount > 5 ) &&
+		buffer.substring( buffer.length() - 2, buffer.length() ).equals( "nd" ) )
+	    {
+		buffer.delete( buffer.length() - 2, buffer.length() );
+	    }
+	    else if ( ( buffer.length() + substCount > 4 ) &&
+		buffer.substring( buffer.length() - 2, buffer.length() ).equals( "em" ) ) {
+		buffer.delete( buffer.length() - 2, buffer.length() );
+	    }
+	    else if ( ( buffer.length() + substCount > 4 ) &&
+		buffer.substring( buffer.length() - 2, buffer.length() ).equals( "er" ) ) {
+		buffer.delete( buffer.length() - 2, buffer.length() );
+	    }
+	    else if ( buffer.charAt( buffer.length() - 1 ) == 'e' ) {
+		buffer.deleteCharAt( buffer.length() - 1 );
+	    }
+	    else if ( buffer.charAt( buffer.length() - 1 ) == 's' ) {
+		buffer.deleteCharAt( buffer.length() - 1 );
+	    }
+	    else if ( buffer.charAt( buffer.length() - 1 ) == 'n' ) {
+		buffer.deleteCharAt( buffer.length() - 1 );
+	    }
+	    // "t" occurs only as suffix of verbs.
+	    else if ( buffer.charAt( buffer.length() - 1 ) == 't' && !uppercase ) {
+		buffer.deleteCharAt( buffer.length() - 1 );
+	    }
+	    else {
+		doMore = false;
+	    }
+	}
+    }
+
+    /**
+     * Does some optimizations on the term. This optimisations are
+     * contextual.
+     */
+    private void optimize( StringBuffer buffer )
+    {
+	// Additional step for female plurals of professions and inhabitants.
+	if ( buffer.length() > 5 && buffer.substring( buffer.length() - 5, buffer.length() ).equals( "erin*" ) ) {
+	    buffer.deleteCharAt( buffer.length() -1 );
+	    strip( buffer );
+	}
+	// Additional step for irregular plural nouns like "Matrizen -> Matrix".
+	if ( buffer.charAt( buffer.length() - 1 ) == ( 'z' ) ) {
+	    buffer.setCharAt( buffer.length() - 1, 'x' );
+	}
+    }
+
+    /**
+     * Removes a particle denotion ("ge") from a term.
+     */
+    private void removeParticleDenotion( StringBuffer buffer )
+    {
+	if ( buffer.length() > 4 ) {
+	    for ( int c = 0; c < buffer.length() - 3; c++ ) {
+		if ( buffer.substring( c, c + 4 ).equals( "gege" ) ) {
+		    buffer.delete( c, c + 2 );
+		    return;
+		}
+	    }
+	}
+    }
+
+    /**
+     * Do some substitutions for the term to reduce overstemming:
+     *
+     * - Substitute Umlauts with their corresponding vowel: äöü -> aou,
+     *   "ß" is substituted by "ss"
+     * - Substitute a second char of a pair of equal characters with
+     *   an asterisk: ?? -> ?*
+     * - Substitute some common character combinations with a token:
+     *   sch/ch/ei/ie/ig/st -> $/§/%/&/#/!
+     */
+    private void substitute( StringBuffer buffer )
+    {
+	substCount = 0;
+	for ( int c = 0; c < buffer.length(); c++ ) {
+	    // Replace the second char of a pair of the equal characters with an asterisk
+	    if ( c > 0 && buffer.charAt( c ) == buffer.charAt ( c - 1 )  ) {
+		buffer.setCharAt( c, '*' );
+	    }
+	    // Substitute Umlauts.
+	    else if ( buffer.charAt( c ) == '\u00E4' ) {
+		buffer.setCharAt( c, 'a' );
+	    }
+	    else if ( buffer.charAt( c ) == '\u00F6' ) {
+		buffer.setCharAt( c, 'o' );
+	    }
+	    else if ( buffer.charAt( c ) == '\u00FC' ) {
+		buffer.setCharAt( c, 'u' );
+	    }
+	    // Take care that at least one character is left left side from the current one
+	    if ( c < buffer.length() - 1 ) {
+		if ( buffer.charAt( c ) == '\u00DF' ) {
+		    buffer.setCharAt( c, 's' );
+		    buffer.insert( c + 1, 's' );
+		    substCount++;
+		}
+		// Masking several common character combinations with an token
+		else if ( ( c < buffer.length() - 2 ) && buffer.charAt( c ) == 's' &&
+		    buffer.charAt( c + 1 ) == 'c' && buffer.charAt( c + 2 ) == 'h' )
+		{
+		    buffer.setCharAt( c, '$' );
+		    buffer.delete( c + 1, c + 3 );
+		    substCount =+ 2;
+		}
+		else if ( buffer.charAt( c ) == 'c' && buffer.charAt( c + 1 ) == 'h' ) {
+		    buffer.setCharAt( c, '§' );
+		    buffer.deleteCharAt( c + 1 );
+		    substCount++;
+		}
+		else if ( buffer.charAt( c ) == 'e' && buffer.charAt( c + 1 ) == 'i' ) {
+		    buffer.setCharAt( c, '%' );
+		    buffer.deleteCharAt( c + 1 );
+		    substCount++;
+		}
+		else if ( buffer.charAt( c ) == 'i' && buffer.charAt( c + 1 ) == 'e' ) {
+		    buffer.setCharAt( c, '&' );
+		    buffer.deleteCharAt( c + 1 );
+		    substCount++;
+		}
+		else if ( buffer.charAt( c ) == 'i' && buffer.charAt( c + 1 ) == 'g' ) {
+		    buffer.setCharAt( c, '#' );
+		    buffer.deleteCharAt( c + 1 );
+		    substCount++;
+		}
+		else if ( buffer.charAt( c ) == 's' && buffer.charAt( c + 1 ) == 't' ) {
+		    buffer.setCharAt( c, '!' );
+		    buffer.deleteCharAt( c + 1 );
+		    substCount++;
+		}
+	    }
+	}
+    }
+
+    /**
+     * Undoes the changes made by substitute(). That are character pairs and
+     * character combinations. Umlauts will remain as their corresponding vowel,
+     * as "ß" remains as "ss".
+     */
+    private void resubstitute( StringBuffer buffer )
+    {
+	for ( int c = 0; c < buffer.length(); c++ ) {
+	    if ( buffer.charAt( c ) == '*' ) {
+		char x = buffer.charAt( c - 1 );
+		buffer.setCharAt( c, x );
+	    }
+	    else if ( buffer.charAt( c ) == '$' ) {
+		buffer.setCharAt( c, 's' );
+		buffer.insert( c + 1, new char[]{'c', 'h'}, 0, 2 );
+	    }
+	    else if ( buffer.charAt( c ) == '§' ) {
+		buffer.setCharAt( c, 'c' );
+		buffer.insert( c + 1, 'h' );
+	    }
+	    else if ( buffer.charAt( c ) == '%' ) {
+		buffer.setCharAt( c, 'e' );
+		buffer.insert( c + 1, 'i' );
+	    }
+	    else if ( buffer.charAt( c ) == '&' ) {
+		buffer.setCharAt( c, 'i' );
+		buffer.insert( c + 1, 'e' );
+	    }
+	    else if ( buffer.charAt( c ) == '#' ) {
+		buffer.setCharAt( c, 'i' );
+		buffer.insert( c + 1, 'g' );
+	    }
+	    else if ( buffer.charAt( c ) == '!' ) {
+		buffer.setCharAt( c, 's' );
+		buffer.insert( c + 1, 't' );
+	    }
+	}
+    }
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/IteratedLovinsStemmer.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/IteratedLovinsStemmer.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/IteratedLovinsStemmer.java	(revision 20131)
@@ -0,0 +1,76 @@
+/*
+ *    IteratedLovinsStemmer.java
+ *    Copyright (C) 2001 Eibe Frank
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.util.*;
+
+/**
+ * Implements the iterated version of the Lovins stemmer.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version 1.0
+ */
+public class IteratedLovinsStemmer extends LovinsStemmer {
+
+  /**
+   * Iterated stemming of the given word.
+   */
+  public String stem(String str) {
+
+    if (str.length() <= 2) {
+      return str;
+    }
+    String stemmed = super.stem(str);
+    while (!stemmed.equals(str)) {
+      str = stemmed;
+      stemmed = super.stem(stemmed);
+    }
+    return stemmed;
+  }
+
+  /**
+   * Stems text coming into stdin and writes it to stdout.
+   */
+  public static void main(String[] ops) {
+
+    IteratedLovinsStemmer ls = new IteratedLovinsStemmer();
+
+    try {
+      int num;
+      StringBuffer wordBuffer = new StringBuffer();
+      while ((num = System.in.read()) != -1) {
+	char c = (char)num;
+	if (((num >= (int)'A') && (num <= (int)'Z')) ||
+	    ((num >= (int)'a') && (num <= (int)'z'))) {
+	  wordBuffer.append(c);
+	} else {
+	  if (wordBuffer.length() > 0) {
+	    System.out.print(ls.stem(wordBuffer.toString().
+				     toLowerCase()));
+	    wordBuffer = new StringBuffer();
+	  }
+	  System.out.print(c);
+	}
+      }
+    } catch (Exception e) {
+      System.err.println(e.getMessage());
+    }
+  }
+}
+    
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/KEAFilter.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/KEAFilter.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/KEAFilter.java	(revision 20131)
@@ -0,0 +1,1496 @@
+/*
+ *    KEAFilter.java
+ *    Copyright (C) 2000, 2001 Eibe Frank
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.util.*;
+import java.io.*;
+
+import weka.core.*;
+import weka.filters.*;
+import weka.classifiers.*;
+
+/**
+ * This filter converts the incoming data into data appropriate for
+ * keyphrase classification. It assumes that the dataset contains two
+ * string attributes. The first attribute should contain the text of a
+ * document. The second attribute should contain the keyphrases
+ * associated with that document (if present). 
+ *
+ * The filter converts every instance (i.e. document) into a set of
+ * instances, one for each word-based n-gram in the document. The
+ * string attribute representing the document is replaced by some
+ * numeric features, the estimated probability of each n-gram being a
+ * keyphrase, and the rank of this phrase in the document according to
+ * the probability.  Each new instances also has a class value
+ * associated with it. The class is "true" if the n-gram is a true
+ * keyphrase, and "false" otherwise. Of course, if the input document
+ * doesn't come with author-assigned keyphrases, the class values for
+ * that document will be missing.  
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version 1.0
+  */
+public class KEAFilter extends Filter implements OptionHandler {
+
+  /** Index of attribute containing the documents */
+  private int m_DocumentAtt = 0;
+
+  /** Index of attribute containing the keyphrases */
+  private int m_KeyphrasesAtt = 1;
+
+  /** The maximum length of phrases */
+  private int m_MaxPhraseLength = 3;
+
+  /** The minimum length of phrases */
+  private int m_MinPhraseLength = 1;
+
+  /** Is keyphrase frequency attribute being used? */
+  private boolean m_KFused = false;
+
+  /** Flag for debugging mode */
+  private boolean m_Debug = false;
+
+  /** Determines whether internal periods are allowed */
+  private boolean m_DisallowInternalPeriods = false;
+
+  /** The minimum number of occurences of a phrase */
+  private int m_MinNumOccur = 2;
+
+  /** The number of features describing a phrase */
+  private int m_NumFeatures = 2;
+
+  /* Indices of attributes in m_ClassifierData */
+  private int m_TfidfIndex = 0;
+  private int m_FirstOccurIndex = 1;
+  private int m_KeyFreqIndex = 2;
+
+  /** The punctuation filter used by this filter */
+  private KEAPhraseFilter m_PunctFilter = null;
+
+  /** The numbers filter used by this filter */
+  private NumbersFilter m_NumbersFilter = null;
+ 
+  /** The actual classifier used to compute probabilities */
+  private DistributionClassifier m_Classifier = null;
+
+  /** The dictionary containing the document frequencies */
+  private HashMap m_Dictionary = null;
+
+  /** The dictionary containing the keyphrases */
+  private HashMap m_KeyphraseDictionary = null;
+
+  /** The number of documents in the global frequencies corpus */
+  private int m_NumDocs = 0;
+
+  /** Template for the classifier data */
+  private Instances m_ClassifierData = null;
+
+  /** The stemmer to be used */
+  private Stemmer m_Stemmer = new IteratedLovinsStemmer();
+
+  /** The list of stop words to be used */
+  private Stopwords m_Stopwords = new StopwordsEnglish();
+
+  /** Determines whether check for proper nouns is performed */
+  private boolean m_CheckForProperNouns = true;
+
+  /**
+   * Get the M_CheckProperNouns value.
+   * @return the M_CheckProperNouns value.
+   */
+  public boolean getCheckForProperNouns() {
+    return m_CheckForProperNouns;
+  }
+
+  /**
+   * Set the M_CheckProperNouns value.
+   * @param newM_CheckProperNouns The new M_CheckProperNouns value.
+   */
+  public void setCheckForProperNouns(boolean newM_CheckProperNouns) {
+    this.m_CheckForProperNouns = newM_CheckProperNouns;
+  }
+  
+  /**
+   * Get the M_Stopwords value.
+   * @return the M_Stopwords value.
+   */
+  public Stopwords getStopwords() {
+    return m_Stopwords;
+  }
+
+  /**
+   * Set the M_Stopwords value.
+   * @param newM_Stopwords The new M_Stopwords value.
+   */
+  public void setStopwords(Stopwords newM_Stopwords) {
+    this.m_Stopwords = newM_Stopwords;
+  }
+
+  
+  /**
+   * Get the Stemmer value.
+   * @return the Stemmer value.
+   */
+  public Stemmer getStemmer() {
+
+    return m_Stemmer;
+  }
+
+  /**
+   * Set the Stemmer value.
+   * @param newStemmer The new Stemmer value.
+   */
+  public void setStemmer(Stemmer newStemmer) {
+
+    this.m_Stemmer = newStemmer;
+  }
+
+  /**
+   * Get the value of MinNumOccur.
+   *
+   * @return Value of MinNumOccur.
+   */
+  public int getMinNumOccur() {
+    
+    return m_MinNumOccur;
+  }
+  
+  /**
+   * Set the value of MinNumOccur.
+   *
+   * @param newMinNumOccur Value to assign to MinNumOccur.
+   */
+  public void setMinNumOccur(int newMinNumOccur) {
+    
+    m_MinNumOccur = newMinNumOccur;
+  }
+  
+  /**
+   * Get the value of MaxPhraseLength.
+   *
+   * @return Value of MaxPhraseLength.
+   */
+  public int getMaxPhraseLength() {
+    
+    return m_MaxPhraseLength;
+  }
+  
+  /**
+   * Set the value of MaxPhraseLength.
+   *
+   * @param newMaxPhraseLength Value to assign to MaxPhraseLength.
+   */
+  public void setMaxPhraseLength(int newMaxPhraseLength) {
+    
+    m_MaxPhraseLength = newMaxPhraseLength;
+  }
+  
+  /**
+   * Get the value of MinPhraseLength.
+   *
+   * @return Value of MinPhraseLength.
+   */
+  public int getMinPhraseLength() {
+    
+    return m_MinPhraseLength;
+  }
+  
+  /**
+   * Set the value of MinPhraseLength.
+   *
+   * @param newMinPhraseLength Value to assign to MinPhraseLength.
+   */
+  public void setMinPhraseLength(int newMinPhraseLength) {
+    
+    m_MinPhraseLength = newMinPhraseLength;
+  }
+
+  /**
+   * Returns the index of the stemmed phrases in the output ARFF file.
+   */
+  public int getStemmedPhraseIndex() {
+
+    return m_DocumentAtt;
+  }
+
+  /**
+   * Returns the index of the unstemmed phrases in the output ARFF file.
+   */
+  public int getUnstemmedPhraseIndex() {
+
+    return m_DocumentAtt + 1;
+  }
+
+  /**
+   * Returns the index of the phrases' probabilities in the output ARFF file.
+   */
+  public int getProbabilityIndex() {
+
+    int index = m_DocumentAtt + 4;
+
+    if (m_Debug) {
+      if (m_KFused) {
+	index++;
+      }
+    }
+    return index;
+  }
+
+  /**
+   * Returns the index of the phrases' ranks in the output ARFF file.
+   */
+  public int getRankIndex() {
+
+    return getProbabilityIndex() + 1;
+  }
+
+  /**
+   * Get the value of DocumentAtt.
+   *
+   * @return Value of DocumentAtt.
+   */
+  public int getDocumentAtt() {
+    
+    return m_DocumentAtt;
+  }
+  
+  /**
+   * Set the value of DocumentAtt.
+   *
+   * @param newDocumentAtt Value to assign to DocumentAtt.
+   */
+  public void setDocumentAtt(int newDocumentAtt) {
+    
+    m_DocumentAtt = newDocumentAtt;
+  }
+  
+  /**
+   * Get the value of KeyphraseAtt.
+   *
+   * @return Value of KeyphraseAtt.
+   */
+  public int getKeyphrasesAtt() {
+    
+    return m_KeyphrasesAtt;
+  }
+  
+  /**
+   * Set the value of KeyphrasesAtt.
+   *
+   * @param newKeyphrasesAtt Value to assign to KeyphrasesAtt.
+   */
+  public void setKeyphrasesAtt(int newKeyphrasesAtt) {
+    
+    m_KeyphrasesAtt = newKeyphrasesAtt;
+  }
+  
+  
+  /**
+   * Get the value of Debug.
+   *
+   * @return Value of Debug.
+   */
+  public boolean getDebug() {
+    
+    return m_Debug;
+  }
+  
+  /**
+   * Set the value of Debug.
+   *
+   * @param newDebug Value to assign to Debug.
+   */
+  public void setDebug(boolean newDebug) {
+    
+    m_Debug = newDebug;
+  }
+
+  /**
+   * Sets whether keyphrase frequency attribute is used.
+   */
+  public void setKFused(boolean flag) {
+
+    m_KFused = flag;
+    if (flag) {
+      m_NumFeatures = 3;
+    } else {
+      m_NumFeatures = 2;
+    }
+  }
+
+  /**
+   * Gets whether keyphrase frequency attribute is used.
+   */
+  public boolean getKFused() {
+
+    return m_KFused;
+  }
+
+  /**
+   * Get whether the supplied columns are to be processed
+   *
+   * @return true if the supplied columns won't be processed
+   */
+  public boolean getDisallowInternalPeriods() {
+
+    return m_DisallowInternalPeriods;
+  }
+
+  /**
+   * Set whether selected columns should be processed. If true the 
+   * selected columns won't be processed.
+   *
+   * @param invert the new invert setting
+   */
+  public void setDisallowInternalPeriods(boolean disallow) {
+
+    m_DisallowInternalPeriods = disallow;
+  }
+
+  /**
+   * Parses a given list of options controlling the behaviour of this object.
+   * Valid options are:<p>
+   *
+   * -K<br>
+   * Specifies whether keyphrase frequency statistic is used.<p>
+   *
+   * -M length<br>
+   * Sets the maximum phrase length (default: 3).<p>
+   *
+   * -L length<br>
+   * Sets the minimum phrase length (default: 1).<p>
+   *
+   * -D<br>
+   * Turns debugging mode on.<p>
+   *
+   * -I index<br>
+   * Sets the index of the attribute containing the documents (default: 0).<p>
+   *
+   * -J index<br>
+   * Sets the index of the attribute containing the keyphrases (default: 1).<p>
+   *
+   * -P<br>
+   * Disallow internal periods <p>
+   *
+   * -O number<br>
+   * The minimum number of times a phrase needs to occur (default: 2). <p>
+   *
+   * @param options the list of options as an array of strings
+   * @exception Exception if an option is not supported
+   */
+  public void setOptions(String[] options) throws Exception {
+
+    setKFused(Utils.getFlag('K', options));
+    setDebug(Utils.getFlag('D', options));
+    String docAttIndexString = Utils.getOption('I', options);
+    if (docAttIndexString.length() > 0) {
+      setDocumentAtt(Integer.parseInt(docAttIndexString) - 1);
+    } else {
+      setDocumentAtt(0);
+    }
+    String keyphraseAttIndexString = Utils.getOption('J', options);
+    if (keyphraseAttIndexString.length() > 0) {
+      setKeyphrasesAtt(Integer.parseInt(keyphraseAttIndexString) - 1);
+    } else {
+      setKeyphrasesAtt(1);
+    }
+    String maxPhraseLengthString = Utils.getOption('M', options);
+    if (maxPhraseLengthString.length() > 0) {
+      setMaxPhraseLength(Integer.parseInt(maxPhraseLengthString));
+    } else {
+      setMaxPhraseLength(3);
+    }
+    String minPhraseLengthString = Utils.getOption('M', options);
+    if (minPhraseLengthString.length() > 0) {
+      setMinPhraseLength(Integer.parseInt(minPhraseLengthString));
+    } else {
+      setMinPhraseLength(1);
+    }
+    String minNumOccurString = Utils.getOption('O', options);
+    if (minNumOccurString.length() > 0) {
+      setMinNumOccur(Integer.parseInt(minNumOccurString));
+    } else {
+      setMinNumOccur(2);
+    }
+    setDisallowInternalPeriods(Utils.getFlag('P', options));
+   }
+
+  /**
+   * Gets the current settings of the filter.
+   *
+   * @return an array of strings suitable for passing to setOptions
+   */
+  public String [] getOptions() {
+
+    String [] options = new String [13];
+    int current = 0;
+
+    if (getKFused()) {
+      options[current++] = "-K";
+    }
+    if (getDebug()) {
+      options[current++] = "-D";
+    }
+    options[current++] = "-I"; 
+    options[current++] = "" + (getDocumentAtt() + 1);
+    options[current++] = "-J"; 
+    options[current++] = "" + (getKeyphrasesAtt() + 1);
+    options[current++] = "-M"; 
+    options[current++] = "" + (getMaxPhraseLength());
+    options[current++] = "-L"; 
+    options[current++] = "" + (getMinPhraseLength());
+    options[current++] = "-O"; 
+    options[current++] = "" + (getMinNumOccur());
+
+    if (getDisallowInternalPeriods()) {
+      options[current++] = "-P";
+    }
+
+    while (current < options.length) {
+      options[current++] = "";
+    }
+    return options;
+  }
+
+  /**
+   * Returns an enumeration describing the available options
+   *
+   * @return an enumeration of all the available options
+   */
+  public Enumeration listOptions() {
+
+    Vector newVector = new Vector(7);
+
+    newVector.addElement(new Option(
+	      "\tSpecifies whether keyphrase frequency statistic is used.",
+              "K", 0, "-K"));
+    newVector.addElement(new Option(
+	      "\tSets the maximum phrase length (default: 3).",
+              "M", 1, "-M <length>"));
+    newVector.addElement(new Option(
+	      "\tSets the minimum phrase length (default: 1).",
+              "L", 1, "-L <length>"));
+    newVector.addElement(new Option(
+	      "\tTurns debugging mode on.",
+              "D", 0, "-D"));
+    newVector.addElement(new Option(
+	      "\tSets the index of the document attribute (default: 0).",
+              "I", 1, "-I"));
+    newVector.addElement(new Option(
+	      "\tSets the index of the keyphrase attribute (default: 1).",
+              "J", 1, "-J"));
+    newVector.addElement(new Option(
+	      "\tDisallow internal periods.",
+              "P", 0, "-P"));
+    newVector.addElement(new Option(
+	      "\tSet the minimum number of occurences (default: 2).",
+              "O", 1, "-O"));
+
+    return newVector.elements();
+  }
+
+  /**
+   * Returns a string describing this filter
+   *
+   * @return a description of the filter suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String globalInfo() {
+    return "Converts incoming data into data appropriate for " +
+      "keyphrase classification.";
+  }
+
+  /**
+   * Sets the format of the input instances.
+   *
+   * @param instanceInfo an Instances object containing the input
+   * instance structure (any instances contained in the object are
+   * ignored - only the structure is required).
+   * @return true if the outputFormat may be collected immediately 
+   */
+  public boolean setInputFormat(Instances instanceInfo) throws Exception {
+
+    if (instanceInfo.classIndex() >= 0) {
+      throw new Exception("Don't know what do to if class index set!");
+    }
+    if (!instanceInfo.attribute(m_KeyphrasesAtt).isString() ||
+	!instanceInfo.attribute(m_DocumentAtt).isString()) {
+      throw new Exception("Keyphrase attribute and document attribute " +
+			  "need to be string attributes.");
+    }
+    m_PunctFilter = new KEAPhraseFilter();
+    int[] arr = new int[1];
+    arr[0] = m_DocumentAtt;
+    m_PunctFilter.setAttributeIndicesArray(arr);
+    m_PunctFilter.setInputFormat(instanceInfo);
+    m_PunctFilter.setDisallowInternalPeriods(getDisallowInternalPeriods());
+    m_NumbersFilter = new NumbersFilter();
+    m_NumbersFilter.setInputFormat(m_PunctFilter.getOutputFormat());
+    super.setInputFormat(m_NumbersFilter.getOutputFormat());
+    return false;
+  }
+
+  /**
+   * Input an instance for filtering. Ordinarily the instance is processed
+   * and made available for output immediately. Some filters require all
+   * instances be read before producing output.
+   *
+   * @param instance the input instance
+   * @return true if the filtered instance may now be
+   * collected with output().
+   * @exception Exception if the input instance was not of the correct 
+   * format or if there was a problem with the filtering.
+   */
+  public boolean input(Instance instance) throws Exception {
+
+    if (getInputFormat() == null) {
+      throw new Exception("No input instance format defined");
+    }
+    if (m_NewBatch) {
+      resetQueue();
+      m_NewBatch = false;
+    }
+
+    if (m_Debug) {
+      System.err.println("-- Reading instance");
+    }
+
+    m_PunctFilter.input(instance);
+    m_PunctFilter.batchFinished();
+    instance = m_PunctFilter.output();
+
+    m_NumbersFilter.input(instance);
+    m_NumbersFilter.batchFinished();
+    instance = m_NumbersFilter.output();
+    
+    if (m_Dictionary == null) {
+      bufferInput(instance);
+      return false;
+    } else {
+      FastVector vector = convertInstance(instance, false);
+      Enumeration enum = vector.elements();
+      while (enum.hasMoreElements()) {
+	Instance inst = (Instance)enum.nextElement();
+	push(inst);
+      }
+      return true;
+    }
+  }
+
+  /**
+   * Signify that this batch of input to the filter is finished. 
+   * If the filter requires all instances prior to filtering,
+   * output() may now be called to retrieve the filtered instances.
+   *
+   * @return true if there are instances pending output
+   * @exception Exception if no input structure has been defined
+   */
+  public boolean batchFinished() throws Exception {
+
+    if (getInputFormat() == null) {
+      throw new Exception("No input instance format defined");
+    }
+    if (m_Dictionary == null) {
+      buildGlobalDictionaries();
+      buildClassifier();
+      convertPendingInstances();
+    } 
+    flushInput();
+    m_NewBatch = true;
+    return (numPendingOutput() != 0);
+  }
+
+  /**
+   * Builds the global dictionaries.
+   */
+  private void buildGlobalDictionaries() throws Exception {
+
+    if (m_Debug) {
+      System.err.println("--- Building global dictionaries");
+    }
+    
+    // Build dictionary of n-grams with associated
+    // document frequencies
+    m_Dictionary = new HashMap();
+    for (int i = 0; i < getInputFormat().numInstances(); i++) {
+      String str = getInputFormat().instance(i).stringValue(m_DocumentAtt);
+      HashMap hash = getPhrasesForDictionary(str);
+      Iterator it = hash.keySet().iterator();
+      while (it.hasNext()) {
+	String phrase = (String)it.next();
+	Counter counter = (Counter)m_Dictionary.get(phrase);
+	if (counter == null) {
+	  m_Dictionary.put(phrase, new Counter());
+	} else {
+	  counter.increment();
+	}
+      }
+    }
+    
+    if (m_KFused) {
+      
+      // Build dictionary of n-grams that occur as keyphrases
+      // with associated keyphrase frequencies
+      m_KeyphraseDictionary = new HashMap();
+      for (int i = 0; i < getInputFormat().numInstances(); i++) {
+	String str = getInputFormat().instance(i).stringValue(m_KeyphrasesAtt);
+	HashMap hash = getGivenKeyphrases(str, false);
+	if (hash != null) {
+	  Iterator it = hash.keySet().iterator();
+	  while (it.hasNext()) {
+	    String phrase = (String)it.next();
+	    Counter counter = (Counter)m_KeyphraseDictionary.get(phrase);
+	    if (counter == null) {
+	      m_KeyphraseDictionary.put(phrase, new Counter());
+	    } else {
+	      counter.increment();
+	    }
+	  }
+	}
+      }
+    } else {
+      m_KeyphraseDictionary = null;
+    }
+    
+    // Set the number of documents in the global corpus
+    m_NumDocs = getInputFormat().numInstances();
+  }
+ 
+  /**
+   * Builds the classifier.
+   */
+  private void buildClassifier() throws Exception {
+    
+    // Generate input format for classifier
+    FastVector atts = new FastVector();
+    for (int i = 0; i < getInputFormat().numAttributes(); i++) {
+      if (i == m_DocumentAtt) {
+	atts.addElement(new Attribute("TFxIDF"));
+	atts.addElement(new Attribute("First_occurrence"));
+	if (m_KFused) {
+	  atts.addElement(new Attribute("Keyphrase_frequency"));
+	}
+      } else if (i == m_KeyphrasesAtt) {
+	FastVector vals = new FastVector(2);
+	vals.addElement("False");
+	vals.addElement("True");
+	atts.addElement(new Attribute("Keyphrase?", vals));
+      } 
+    }
+    m_ClassifierData = new Instances("ClassifierData", atts, 0);
+    m_ClassifierData.setClassIndex(m_NumFeatures);
+    
+    if (m_Debug) {
+      System.err.println("--- Converting instances for classifier");
+    }
+    
+    // Convert pending input instances into data for classifier
+    for(int i = 0; i < getInputFormat().numInstances(); i++) {
+      Instance current = getInputFormat().instance(i);
+
+      // Get the key phrases for the document
+      String keyphrases = current.stringValue(m_KeyphrasesAtt);
+      HashMap hashKeyphrases = getGivenKeyphrases(keyphrases, false);
+      HashMap hashKeysEval = getGivenKeyphrases(keyphrases, true);
+
+      // Get the phrases for the document
+      HashMap hash = new HashMap();
+      int length = getPhrases(hash, current.stringValue(m_DocumentAtt));
+
+      // Compute the feature values for each phrase and
+      // add the instance to the data for the classifier
+      Iterator it = hash.keySet().iterator();
+      while (it.hasNext()) {
+	String phrase = (String)it.next();
+	FastVector phraseInfo = (FastVector)hash.get(phrase);
+	double[] vals =  featVals(phrase, phraseInfo, true,
+				  hashKeysEval, hashKeyphrases, length);
+	Instance inst = new Instance(current.weight(), vals);
+	m_ClassifierData.add(inst);
+      }
+    }
+    
+    if (m_Debug) {
+      System.err.println("--- Building classifier");
+    }
+    
+    // Build classifier
+    FilteredClassifier fclass = new FilteredClassifier();
+    fclass.setClassifier(new weka.classifiers.NaiveBayesSimple());
+    fclass.setFilter(new DiscretizeFilter());
+    m_Classifier = fclass;
+    m_Classifier.buildClassifier(m_ClassifierData);
+
+    if (m_Debug) {
+      System.err.println(m_Classifier);
+    }
+
+    // Save space
+    m_ClassifierData = new Instances(m_ClassifierData, 0);
+  }
+
+  /** 
+   * Conmputes the feature values for a given phrase.
+   */
+  private double[] featVals(String phrase, FastVector phraseInfo, 
+			    boolean training, HashMap hashKeysEval,
+			    HashMap hashKeyphrases, int length) {
+
+    // Compute feature values
+    Counter counterLocal = (Counter)phraseInfo.elementAt(1);
+    double[] newInst = new double[m_NumFeatures + 1];
+	  
+    // Compute TFxIDF
+    Counter counterGlobal = (Counter)m_Dictionary.get(phrase);
+    double localVal = counterLocal.value(), globalVal = 0;
+    if (counterGlobal != null) {
+      globalVal = counterGlobal.value();
+      if (training) {
+	globalVal = globalVal - 1;
+      }
+    }
+    
+    // Just devide by length to get approximation of probability
+    // that phrase in document is our phrase
+    newInst[m_TfidfIndex] = (localVal / ((double)length)) *
+      (-Math.log((globalVal + 1)/ ((double)m_NumDocs + 1)));
+	  
+    // Compute first occurrence
+    Counter counterFirst = (Counter)phraseInfo.elementAt(0);
+    newInst[m_FirstOccurIndex] = (double)counterFirst.value() /
+      (double)length;
+    
+    // Is keyphrase frequency attribute being used?
+    if (m_KFused) {
+      Counter keyphraseC = (Counter)m_KeyphraseDictionary.get(phrase);
+      if ((training) && (hashKeyphrases != null) &&
+	  (hashKeyphrases.containsKey(phrase))) {
+	newInst[m_KeyFreqIndex] = keyphraseC.value() - 1;
+      } else {
+	if (keyphraseC != null) {
+	  newInst[m_KeyFreqIndex] = keyphraseC.value();
+	} else {
+	  newInst[m_KeyFreqIndex] = 0;
+	}
+      }
+    }
+
+    // Compute class value
+    String phraseInEvalFormat = evalFormat((String)phraseInfo.elementAt(2));
+    if (hashKeysEval == null) { // no author-assigned keyphrases
+      newInst[m_NumFeatures] = Instance.missingValue();
+    } else if (!hashKeysEval.containsKey(phraseInEvalFormat)) {
+      newInst[m_NumFeatures] = 0; // No keyphrase
+    } else {
+      hashKeysEval.remove(phraseInEvalFormat);
+      newInst[m_NumFeatures] = 1; // Keyphrase
+    }
+    return newInst;
+  }
+
+  /**
+   * Sets output format and converts pending input instances.
+   */
+  private void convertPendingInstances() throws Exception {
+
+    if (m_Debug) {
+      System.err.println("--- Converting pending instances");
+    }
+    
+    // Create output format for filter
+    FastVector atts = new FastVector();
+    for (int i = 0; i < getInputFormat().numAttributes(); i++) {
+      if (i == m_DocumentAtt) {
+	atts.addElement(new Attribute("N-gram", null));
+	atts.addElement(new Attribute("N-gram-original", null));
+	atts.addElement(new Attribute("TFxIDF"));
+	atts.addElement(new Attribute("First_occurrence"));
+	if (m_Debug) {
+	  if (m_KFused) {
+	    atts.addElement(new Attribute("Keyphrase_frequency"));
+	  }
+	}
+	atts.addElement(new Attribute("Probability"));
+	atts.addElement(new Attribute("Rank"));
+      } else if (i == m_KeyphrasesAtt) {
+	FastVector vals = new FastVector(2);
+	vals.addElement("False");
+	vals.addElement("True");
+	atts.addElement(new Attribute("Keyphrase?", vals));
+      } else {
+	atts.addElement(getInputFormat().attribute(i));
+      }
+    }
+    Instances outFormat = new Instances("KEAdata", atts, 0);
+    setOutputFormat(outFormat);
+    
+    // Convert pending input instances into output data
+    for(int i = 0; i < getInputFormat().numInstances(); i++) {
+      Instance current = getInputFormat().instance(i);
+      FastVector vector = convertInstance(current, true);
+      Enumeration enum = vector.elements();
+      while (enum.hasMoreElements()) {
+	Instance inst = (Instance)enum.nextElement();
+	push(inst);
+      }
+    }
+  } 
+
+  /**
+   * Converts an instance.
+   */
+  private FastVector convertInstance(Instance instance, boolean training) 
+    throws Exception {
+
+    FastVector vector = new FastVector();
+
+    if (m_Debug) {
+      System.err.println("-- Converting instance");
+    }
+
+    // Get the key phrases for the document
+    HashMap hashKeyphrases = null;
+    HashMap hashKeysEval = null;
+    if (!instance.isMissing(m_KeyphrasesAtt)) {
+      String keyphrases = instance.stringValue(m_KeyphrasesAtt);
+      hashKeyphrases = getGivenKeyphrases(keyphrases, false);
+      hashKeysEval = getGivenKeyphrases(keyphrases, true);
+    }
+
+    // Get the phrases for the document
+    HashMap hash = new HashMap();
+    int length = getPhrases(hash, instance.stringValue(m_DocumentAtt));
+
+    // Compute number of extra attributes
+    int numFeatures = 5;
+    if (m_Debug) {
+      if (m_KFused) {
+	numFeatures = numFeatures + 1;
+      }
+    } 
+
+    // Set indices of key attributes
+    int phraseAttIndex = m_DocumentAtt;
+    int tfidfAttIndex = m_DocumentAtt + 2;
+    int distAttIndex = m_DocumentAtt + 3;
+    int probsAttIndex = m_DocumentAtt + numFeatures - 1;
+
+    // Go through the phrases and convert them into instances
+    Iterator it = hash.keySet().iterator();
+    while (it.hasNext()) {
+      String phrase = (String)it.next();
+      FastVector phraseInfo = (FastVector)hash.get(phrase);
+      double[] vals =  featVals(phrase, phraseInfo, training,
+				hashKeysEval, hashKeyphrases, length);
+      Instance inst = new Instance(instance.weight(), vals);
+      inst.setDataset(m_ClassifierData);
+
+      // Get probability of phrase being key phrase
+      double[] probs = m_Classifier.distributionForInstance(inst);
+      double prob = probs[1];
+
+      // Compute attribute values for final instance
+      double[] newInst = 
+	new double[instance.numAttributes() + numFeatures];
+      int pos = 0;
+      for (int i = 0; i < instance.numAttributes(); i++) {
+	if (i == m_DocumentAtt) {
+	    
+	  // Add phrase
+	  int index = outputFormatPeek().attribute(pos).
+	    addStringValue(phrase);
+	  newInst[pos++] = index;
+	  
+	  // Add original version
+	  index = outputFormatPeek().attribute(pos).
+	    addStringValue((String)phraseInfo.elementAt(2));
+	  newInst[pos++] = index;
+
+	  // Add TFxIDF
+	  newInst[pos++] = inst.value(m_TfidfIndex);
+	    
+	  // Add distance
+	  newInst[pos++] = inst.value(m_FirstOccurIndex);
+
+	    // Add other features
+	  if (m_Debug) {
+	    if (m_KFused) {
+	      newInst[pos++] = inst.value(m_KeyFreqIndex);
+	    }
+	  }
+
+	  // Add probability 
+	  probsAttIndex = pos;
+	  newInst[pos++] = prob;
+
+	  // Set rank to missing (computed below)
+	  newInst[pos++] = Instance.missingValue();
+	} else if (i == m_KeyphrasesAtt) {
+	  newInst[pos++] = inst.classValue();
+	} else {
+	  newInst[pos++] = instance.value(i);
+	}
+      }
+      Instance ins = new Instance(instance.weight(), newInst);
+      ins.setDataset(outputFormatPeek());
+      vector.addElement(ins);
+    }
+
+    // Add dummy instances for keyphrases that don't occur
+    // in the document
+    if (hashKeysEval != null) {
+      Iterator phrases = hashKeysEval.keySet().iterator();
+      while (phrases.hasNext()) {
+	String phrase = (String)phrases.next();
+	double[] newInst = 
+	  new double[instance.numAttributes() + numFeatures];
+	int pos = 0;
+	for (int i = 0; i < instance.numAttributes(); i++) {
+	  if (i == m_DocumentAtt) {
+	    
+	    // Add phrase
+	    int index = outputFormatPeek().attribute(pos).
+	      addStringValue(phrase);
+	    newInst[pos++] = (double)index;
+	    
+	    // Add original version
+	    index = outputFormatPeek().attribute(pos).
+	      addStringValue((String)hashKeysEval.get(phrase));
+	    newInst[pos++] = (double)index;
+	    
+	    // Add TFxIDF
+	    newInst[pos++] = Instance.missingValue();
+	    
+	    // Add distance
+	    newInst[pos++] = Instance.missingValue();
+	      
+	    // Add other features
+	    if (m_Debug) {
+	      if (m_KFused) {
+		newInst[pos++] = Instance.missingValue();
+	      }
+	    }
+
+	    // Add probability and rank
+	    newInst[pos++] = -Double.MAX_VALUE;
+	    newInst[pos++] = Instance.missingValue();
+	  } else if (i == m_KeyphrasesAtt) {
+	    newInst[pos++] = 1; // Keyphrase
+	  } else {
+	    newInst[pos++] = instance.value(i);
+	  } 
+	}
+	Instance inst = new Instance(instance.weight(), newInst);
+	inst.setDataset(outputFormatPeek());
+	vector.addElement(inst);
+      }
+    }
+
+    // Sort phrases according to their distance (stable sort)
+    double[] vals = new double[vector.size()];
+    for (int i = 0; i < vals.length; i++) {
+      vals[i] = ((Instance)vector.elementAt(i)).value(distAttIndex);
+    }
+    FastVector newVector = new FastVector(vector.size());
+    int[] sortedIndices = Utils.stableSort(vals);
+    for (int i = 0; i < vals.length; i++) {
+      newVector.addElement(vector.elementAt(sortedIndices[i]));
+    }
+    vector = newVector;
+
+    // Sort phrases according to their tfxidf value (stable sort)
+    for (int i = 0; i < vals.length; i++) {
+      vals[i] = -((Instance)vector.elementAt(i)).value(tfidfAttIndex);
+    }
+    newVector = new FastVector(vector.size());
+    sortedIndices = Utils.stableSort(vals);
+    for (int i = 0; i < vals.length; i++) {
+      newVector.addElement(vector.elementAt(sortedIndices[i]));
+    }
+    vector = newVector;
+
+    // Sort phrases according to their probability (stable sort)
+    for (int i = 0; i < vals.length; i++) {
+      vals[i] = 1 - ((Instance)vector.elementAt(i)).value(probsAttIndex);
+    }
+    newVector = new FastVector(vector.size());
+    sortedIndices = Utils.stableSort(vals);
+    for (int i = 0; i < vals.length; i++) {
+      newVector.addElement(vector.elementAt(sortedIndices[i]));
+    }
+    vector = newVector;
+
+    // Compute rank of phrases. Check for subphrases that are ranked
+    // lower than superphrases and assign probability -1 and set the
+    // rank to Integer.MAX_VALUE
+    int rank = 1;
+    for (int i = 0; i < vals.length; i++) {
+      Instance currentInstance = (Instance)vector.elementAt(i);
+
+      // Short cut: if phrase very unlikely make rank very low and continue
+      if (Utils.grOrEq(vals[i], 1.0)) {
+	currentInstance.setValue(probsAttIndex + 1, Integer.MAX_VALUE);
+	continue;
+      }
+
+      // Otherwise look for super phrase starting with first phrase
+      // in list that has same probability, TFxIDF value, and distance as
+      // current phrase. We do this to catch all superphrases
+      // that have same probability, TFxIDF value and distance as current phrase.
+      int startInd = i;
+      while (startInd < vals.length) {
+	Instance inst = (Instance)vector.elementAt(startInd);
+	if ((inst.value(tfidfAttIndex) != 
+	     currentInstance.value(tfidfAttIndex)) ||
+	    (inst.value(probsAttIndex) != 
+	     currentInstance.value(probsAttIndex)) ||
+	    (inst.value(distAttIndex) !=
+	     currentInstance.value(distAttIndex))) {
+	  break;
+	}
+	startInd++;
+      }
+      String val = currentInstance.stringValue(phraseAttIndex);
+      boolean foundSuperphrase = false;
+      for (int j = startInd - 1; j >= 0; j--) {
+	if (j != i) {
+	  Instance candidate = (Instance)vector.elementAt(j);
+	  String potSuperphrase = candidate.stringValue(phraseAttIndex);
+	  if (val.length() <= potSuperphrase.length()) {
+	    if (KEAFilter.contains(val, potSuperphrase)) {
+	      foundSuperphrase = true;
+	      break;
+	    }
+	  }
+	}
+      }
+      if (foundSuperphrase) {
+	currentInstance.setValue(probsAttIndex + 1, Integer.MAX_VALUE);
+      } else {
+	currentInstance.setValue(probsAttIndex + 1, rank++);
+      }
+    }
+    return vector;
+  }
+    
+  /** 
+   * Checks whether one phrase is a subphrase of another phrase.
+   */
+  private static boolean contains(String sub, String sup) {
+
+    int i = 0;
+    while (i + sub.length() - 1 < sup.length()) {
+      int j;
+      for (j = 0; j < sub.length(); j++) {
+	if (sub.charAt(j) != sup.charAt(i + j)) {
+	  break;
+	}
+      }
+      if (j == sub.length()) {
+	if ((i + j) < sup.length()) {
+	  if (sup.charAt(i + j) == ' ') {
+	    return true;
+	  } else {
+	    return false;
+	  }
+	} else {
+	  return true;
+	}
+      }
+
+      // Skip forward to next space
+      do {
+	i++;
+      } while ((i < sup.length()) && (sup.charAt(i) != ' '));
+      i++;
+    }
+    return false;
+  }
+
+  /**
+   * Returns a hashtable. Fills the hashtable
+   * with the stemmed n-grams occuring in the given string
+   * (as keys) and the number of times it occurs.
+   */
+  private HashMap getPhrasesForDictionary(String str) {
+
+    String[] buffer = new String[m_MaxPhraseLength];
+    HashMap hash = new HashMap();
+
+    StringTokenizer tok = new StringTokenizer(str, "\n");
+    while (tok.hasMoreTokens()) {
+      String phrase = tok.nextToken();
+      int numSeen = 0;
+      StringTokenizer wordTok = new StringTokenizer(phrase, " ");
+      while (wordTok.hasMoreTokens()) {
+	String word = wordTok.nextToken();
+	
+	// Store word in buffer
+	for (int i = 0; i < m_MaxPhraseLength - 1; i++) {
+	  buffer[i] = buffer[i + 1];
+	}
+	buffer[m_MaxPhraseLength - 1] = word;
+	
+	// How many are buffered?
+	numSeen++;
+	if (numSeen > m_MaxPhraseLength) {
+	  numSeen = m_MaxPhraseLength;
+	}
+	
+	// Don't consider phrases that end with a stop word
+	if (m_Stopwords.isStopword(buffer[m_MaxPhraseLength - 1])) {
+	  continue;
+	}
+	
+	// Loop through buffer and add phrases to hashtable
+	StringBuffer phraseBuffer = new StringBuffer();
+	for (int i = 1; i <= numSeen; i++) {
+	  if (i > 1) {
+	    phraseBuffer.insert(0, ' ');
+	  }
+	  phraseBuffer.insert(0, buffer[m_MaxPhraseLength - i]);
+	  
+	  // Don't consider phrases that begin with a stop word
+	  if ((i > 1) && 
+	      (m_Stopwords.isStopword(buffer[m_MaxPhraseLength - i]))) {
+	    continue;
+	  }
+	  
+	  // Only consider phrases with minimum length
+	  if (i >= m_MinPhraseLength) {
+	    
+	    // Stem string
+	    String orig = phraseBuffer.toString();
+	    String internal = internalFormat(orig);
+	    Counter count = (Counter)hash.get(internal);
+	    if (count == null) {
+	      hash.put(internal, new Counter());
+	    } else {
+	      count.increment();
+	    }
+	    
+	    // Add components if phrase is single word before
+	    // conversion into internal format (i.e. error-correcting)
+	    /*if ((orig.indexOf(' ') == -1) &&
+	      (internal.indexOf(' ') != -1)) {
+	      StringTokenizer tokW = new StringTokenizer(internal, " ");
+	      while (tokW.hasMoreTokens()) {
+	      String comp = (String)tokW.nextToken();
+	      Counter countW = (Counter)hash.get(comp);
+	      if (countW == null) {
+	      hash.put(comp, new Counter());
+	      } else {
+	      countW.increment();
+	      }
+	      }
+	      }*/
+	  }
+	}
+      }
+    }
+    return hash;
+  }
+
+  /**
+   * Expects an empty hashtable. Fills the hashtable
+   * with the stemmed n-grams occuring in the given string
+   * (as keys). Stores the position, the number of occurences,
+   * and the most commonly occurring orgininal version of
+   * each n-gram.
+   *
+   * N-grams that occur less than m_MinNumOccur are not used.
+   *
+   * Returns the total number of words (!) in the string.
+   */
+  private int getPhrases(HashMap hash, String str) {
+
+    String[] buffer = new String[m_MaxPhraseLength];
+    
+    StringTokenizer tok = new StringTokenizer(str, "\n");
+    int pos = 1; 
+    while (tok.hasMoreTokens()) {
+      String phrase = tok.nextToken();
+      int numSeen = 0;
+      StringTokenizer wordTok = new StringTokenizer(phrase, " ");
+      while (wordTok.hasMoreTokens()) {
+	String word = wordTok.nextToken();
+	
+	// Store word in buffer
+	for (int i = 0; i < m_MaxPhraseLength - 1; i++) {
+	  buffer[i] = buffer[i + 1];
+	}
+	buffer[m_MaxPhraseLength - 1] = word;
+	
+	// How many are buffered?
+	numSeen++;
+	if (numSeen > m_MaxPhraseLength) {
+	  numSeen = m_MaxPhraseLength;
+	}
+	
+	// Don't consider phrases that end with a stop word
+	if (m_Stopwords.isStopword(buffer[m_MaxPhraseLength - 1])) {
+	  pos++;
+	  continue;
+	}
+	
+	// Loop through buffer and add phrases to hashtable
+	StringBuffer phraseBuffer = new StringBuffer();
+	for (int i = 1; i <= numSeen; i++) {
+	  if (i > 1) {
+	    phraseBuffer.insert(0, ' ');
+	  }
+	  phraseBuffer.insert(0, buffer[m_MaxPhraseLength - i]);
+	  
+	  // Don't consider phrases that begin with a stop word
+	  if ((i > 1) && 
+	      (m_Stopwords.isStopword(buffer[m_MaxPhraseLength - i]))) {
+	    continue;
+	  }
+	  
+	  // Only consider phrases with minimum length
+	  if (i >= m_MinPhraseLength) {
+	    
+	    // Stem string
+	    String phrStr = phraseBuffer.toString();
+	    String internal = internalFormat(phrStr);
+	    FastVector vec = (FastVector)hash.get(internal);
+	    if (vec == null) {
+	      vec = new FastVector(3);
+	      
+	      // HashMap for storing all versions
+	      HashMap secHash = new HashMap();
+	      secHash.put(phrStr, new Counter());
+	      
+	      // Update hashtable with all the info
+	      vec.addElement(new Counter(pos + 1 - i));
+	      vec.addElement(new Counter());
+	      vec.addElement(secHash);
+	      hash.put(internal, vec);
+	    } else {
+	      
+	      // Update number of occurrences
+	      ((Counter)((FastVector)vec).elementAt(1)).increment();
+	      
+	      // Update hashtable storing different versions
+	      HashMap secHash = (HashMap)vec.elementAt(2);
+	      Counter count = (Counter)secHash.get(phrStr);
+	      if (count == null) {
+		secHash.put(phrStr, new Counter());
+	      } else {
+		count.increment();
+	      }
+	    }
+	  }
+	}
+	pos++;
+      }
+    }
+    
+    // Replace secondary hashtables with most commonly occurring
+    // version of each phrase (canonical) form. Delete all words
+    // that are proper nouns.
+    Iterator phrases = hash.keySet().iterator();
+    while (phrases.hasNext()) {
+      String phrase = (String)phrases.next();
+      FastVector info = (FastVector)hash.get(phrase);
+
+      // Occurring less than m_MinNumOccur?
+      if (((Counter)((FastVector)info).elementAt(1)).value() < m_MinNumOccur) {
+	phrases.remove();
+	continue;
+      }
+
+      // Get canonical form
+      String canForm = canonicalForm((HashMap)info.elementAt(2));
+      if (canForm == null) {
+	phrases.remove();
+      } else {
+	info.setElementAt(canForm, 2);
+      }
+    }
+    return pos;
+  }
+
+  /**
+   * Create canonical form of phrase.
+   */
+  private String canonicalForm(HashMap secHash) {
+
+    int max = 0; String bestVersion = null;
+    boolean allFullyHyphenated = true;
+    int num = 0;
+    Iterator versions = secHash.keySet().iterator();
+    while (versions.hasNext()) {
+      num++;
+      String version = (String)versions.next();
+
+      // Are all the words joined up?
+      if (!isFullyHyphenated(version)) {
+	allFullyHyphenated = false;
+      }
+
+      // Check for how often this version occurs
+      Counter count = (Counter)secHash.get(version);
+      if (count.value() > max) {
+	max = count.value();
+	bestVersion = version;
+      }
+    }
+    if ((getCheckForProperNouns()) && (num == 1) && properNoun(bestVersion)) {
+    //if (allProperNouns) {
+      return null;
+    } else {
+      if (isFullyHyphenated(bestVersion) &&
+	  !allFullyHyphenated) {
+	bestVersion = bestVersion.replace('-', ' ');
+      }
+      return bestVersion;
+    }
+  }
+
+  /**
+   * Checks whether the given phrase is
+   * fully hyphenated.
+   */
+  private boolean isFullyHyphenated(String str) {
+    
+    return (str.indexOf(' ') == -1);
+  }
+
+  /**
+   * Checks whether the given string is a 
+   * proper noun.
+   *
+   * @return true if it is a potential proper noun
+   */
+  private static boolean properNoun(String str) {
+
+    // Is it more than one word?
+    if (str.indexOf(' ') != -1) {
+      return false;
+    }
+
+    // Does it start with an upper-case character?
+    if (Character.isLowerCase(str.charAt(0))) {
+      return false;
+    } 
+
+    // Is there at least one character that's
+    // not upper-case?
+    for (int i = 1; i < str.length(); i++) {
+      /*if (Character.isUpperCase(str.charAt(i))) {
+	return false;
+	}*/
+      if (!Character.isUpperCase(str.charAt(i))) {
+	return true;
+      }
+    }
+    //return true;
+    return false;
+  }
+
+  /**
+   * Generates the evaluation format of a phrase.
+   */
+  private String evalFormat(String str) {
+    
+    return m_Stemmer.stemString(str);
+  }
+
+  /** 
+   * Generates the internal format of a phrase.
+   */
+  private String internalFormat(String str) {
+
+    // Remove some non-alphanumeric characters
+    str = str.replace('-', ' ');
+    str = str.replace('/', ' ');
+    str = str.replace('&', ' ');
+
+    // Stem string
+    return m_Stemmer.stemString(str);
+  }
+
+  /**
+   * Gets all the phrases in the given string and puts them into the
+   * hashtable.  Also stores the original version of the stemmed
+   * phrase in the hash table.  
+   */
+  private HashMap getGivenKeyphrases(String str,
+				       boolean forEval) {
+
+    FastVector vector = new FastVector();
+    HashMap hash = new HashMap();
+    
+    StringTokenizer tok = new StringTokenizer(str, "\n");
+    while (tok.hasMoreTokens()) {
+      String orig = tok.nextToken();
+      orig = orig.trim();
+      if (orig.length() > 0) {
+	String modified;
+	if (!forEval) {
+	  modified = internalFormat(orig);
+	} else {
+	  modified = evalFormat(orig);
+	}
+	if (!hash.containsKey(modified)) {
+	  hash.put(modified, orig);
+	} else {
+	  if (forEval) {
+	    System.err.println("WARNING: stem of author-assigned keyphrase " +
+			       orig + " matches existing stem (skipping it)!");
+	  }
+	}
+      }
+    }
+    if (hash.size() == 0) {
+      return null;
+    } else {
+      return hash;
+    }
+  }
+
+  /**
+   * Main method for testing this class.
+   *
+   * @param argv should contain arguments to the filter: use -h for help
+   */
+  public static void main(String [] argv) {
+    
+    try {
+      if (Utils.getFlag('b', argv)) {
+	Filter.batchFilterFile(new KEAFilter(), argv);
+      } else {
+	Filter.filterFile(new KEAFilter(), argv);
+      }
+    } catch (Exception ex) {
+      System.out.println(ex.getMessage());
+    }
+  }
+}
+
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/KEAKeyphraseExtractor.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/KEAKeyphraseExtractor.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/KEAKeyphraseExtractor.java	(revision 20131)
@@ -0,0 +1,532 @@
+/*
+ *    KEAKeyphraseExtractor.java
+ *    Copyright (C) 2001 Eibe Frank
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+import java.io.*;
+import java.util.*;
+import weka.core.*;
+import weka.filters.*;
+
+/**
+ * Extracts keyphrases from the documents in a given directory.
+ * Assumes that the file names for the documents end with ".txt".
+ * Puts extracted keyphrases into corresponding files ending with
+ * ".key" (if those are not already present). Optionally an encoding
+ * for the documents/keyphrases can be defined (e.g. for Chinese
+ * text). Documents for which ".key" exists, are used for evaluation.
+ *
+ * Valid options are:<p>
+ *
+ * -l "directory name"<br>
+ * Specifies name of directory.<p>
+ *
+ * -m "model name"<br>
+ * Specifies name of model.<p>
+ *
+ * -e "encoding"<br>
+ * Specifies encoding.<p>
+ *
+ * -n <br>
+ * Specifies number of phrases to be output (default: 5).<p>
+ *
+ * -d<br>
+ * Turns debugging mode on.<p>
+ *
+ * -a<br>
+ * Also write stemmed phrase and score into ".key" file.<p>
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version 1.0
+ */
+public class KEAKeyphraseExtractor implements OptionHandler {
+  
+  /** Name of directory */
+  String m_dirName = null;
+  
+  /** Name of model */
+  String m_modelName = null;
+
+  /** Encoding */
+  String m_encoding = "default";
+
+  /** Debugging mode? */
+  boolean m_debug = false;
+
+  /** The KEA filter object */
+  KEAFilter m_KEAFilter = null;
+  
+  /** The number of phrases to extract. */
+  int m_numPhrases = 5;
+
+  /** Also write stemmed phrase and score into .key file. */
+  boolean m_AdditionalInfo = false;
+  
+  /**
+   * Get the value of AdditionalInfo.
+   *
+   * @return Value of AdditionalInfo.
+   */
+  public boolean getAdditionalInfo() {
+    
+    return m_AdditionalInfo;
+  }
+  
+  /**
+   * Set the value of AdditionalInfo.
+   *
+   * @param newAdditionalInfo Value to assign to AdditionalInfo.
+   */
+  public void setAdditionalInfo(boolean newAdditionalInfo) {
+    
+    m_AdditionalInfo = newAdditionalInfo;
+  }
+  
+  /**
+   * Get the value of numPhrases.
+   *
+   * @return Value of numPhrases.
+   */
+  public int getNumPhrases() {
+    
+    return m_numPhrases;
+  }
+  
+  /**
+   * Set the value of numPhrases.
+   *
+   * @param newnumPhrases Value to assign to numPhrases.
+   */
+  public void setNumPhrases(int newnumPhrases) {
+    
+    m_numPhrases = newnumPhrases;
+  }
+  
+  /**
+   * Get the value of debug.
+   *
+   * @return Value of debug.
+   */
+  public boolean getDebug() {
+    
+    return m_debug;
+  }
+  
+  /**
+   * Set the value of debug.
+   *
+   * @param newdebug Value to assign to debug.
+   */
+  public void setDebug(boolean newdebug) {
+    
+    m_debug = newdebug;
+  }
+  
+  /**
+   * Get the value of encoding.
+   *
+   * @return Value of encoding.
+   */
+  public String getEncoding() {
+    
+    return m_encoding;
+  }
+  
+  /**
+   * Set the value of encoding.
+   *
+   * @param newencoding Value to assign to encoding.
+   */
+  public void setEncoding(String newencoding) {
+    
+    m_encoding = newencoding;
+  }
+  
+  /**
+   * Get the value of modelName.
+   *
+   * @return Value of modelName.
+   */
+  public String getModelName() {
+    
+    return m_modelName;
+  }
+  
+  /**
+   * Set the value of modelName.
+   *
+   * @param newmodelName Value to assign to modelName.
+   */
+  public void setModelName(String newmodelName) {
+    
+    m_modelName = newmodelName;
+  }
+  
+  /**
+   * Get the value of dirName.
+   *
+   * @return Value of dirName.
+   */
+  public String getDirName() {
+    
+    return m_dirName;
+  }
+  
+  /**
+   * Set the value of dirName.
+   *
+   * @param newdirName Value to assign to dirName.
+   */
+  public void setDirName(String newdirName) {
+    
+    m_dirName = newdirName;
+  }
+  
+  /**
+   * Parses a given list of options controlling the behaviour of this object.
+   * Valid options are:<p>
+   *
+   * -l "directory name"<br>
+   * Specifies name of directory.<p>
+   *
+   * -m "model name"<br>
+   * Specifies name of model.<p>
+   *
+   * -e "encoding"<br>
+   * Specifies encoding.<p>
+   *
+   * -n<br>
+   * Specifies number of phrases to be output (default: 5).<p>
+   *
+   * -d<br>
+   * Turns debugging mode on.<p>
+   *
+   * -a<br>
+   * Also write stemmed phrase and score into ".key" file.<p>
+   *
+   * @param options the list of options as an array of strings
+   * @exception Exception if an option is not supported
+   */
+  public void setOptions(String[] options) throws Exception {
+
+    String dirName = Utils.getOption('l', options);
+    if (dirName.length() > 0) {
+      setDirName(dirName);
+    } else {
+      setDirName(null);
+      throw new Exception("Name of directory required argument.");
+    }
+    String modelName = Utils.getOption('m', options);
+    if (modelName.length() > 0) {
+      setModelName(modelName);
+    } else {
+      setModelName(null);
+      throw new Exception("Name of model required argument.");
+    }
+    String encoding = Utils.getOption('e', options);
+    if (encoding.length() > 0) {
+      setEncoding(encoding);
+    } else {
+      setEncoding("default");
+    }
+    String numPhrases = Utils.getOption('n', options);
+    if (numPhrases.length() > 0) {
+      setNumPhrases(Integer.parseInt(numPhrases));
+    } else {
+      setNumPhrases(5);
+    }
+    setDebug(Utils.getFlag('d', options));
+    setAdditionalInfo(Utils.getFlag('a', options));
+    Utils.checkForRemainingOptions(options);
+   }
+
+  /**
+   * Gets the current option settings.
+   *
+   * @return an array of strings suitable for passing to setOptions
+   */
+  public String [] getOptions() {
+
+    String [] options = new String [10];
+    int current = 0;
+
+    options[current++] = "-l"; 
+    options[current++] = "" + (getDirName());
+    options[current++] = "-m"; 
+    options[current++] = "" + (getModelName());
+    options[current++] = "-e"; 
+    options[current++] = "" + (getEncoding());
+    options[current++] = "-n"; 
+    options[current++] = "" + (getNumPhrases());
+    if (getDebug()) {
+      options[current++] = "-d";
+    }
+    if (getAdditionalInfo()) {
+      options[current++] = "-a";
+    }
+
+    while (current < options.length) {
+      options[current++] = "";
+    }
+    return options;
+  }
+
+  /**
+   * Returns an enumeration describing the available options.
+   *
+   * @return an enumeration of all the available options
+   */
+  public Enumeration listOptions() {
+
+    Vector newVector = new Vector(6);
+
+    newVector.addElement(new Option(
+	      "\tSpecifies name of directory.",
+              "l", 1, "-l <directory name>"));
+    newVector.addElement(new Option(
+	      "\tSpecifies name of model.",
+              "m", 1, "-m <model name>"));
+    newVector.addElement(new Option(
+	      "\tSpecifies encoding.",
+              "e", 1, "-e <encoding>"));
+    newVector.addElement(new Option(
+	      "\tSpecifies number of phrases to be output (default: 5).",
+              "n", 1, "-n"));
+    newVector.addElement(new Option(
+	      "\tTurns debugging mode on.",
+              "d", 0, "-d"));
+    newVector.addElement(new Option(
+	      "\tAlso write stemmed phrase and score into \".key\" file.",
+              "a", 0, "-a"));
+
+    return newVector.elements();
+  }
+
+  /**
+   * Collects the stems of the file names.
+   */
+  public Hashtable collectStems() throws Exception {
+
+    Hashtable stems = new Hashtable();
+
+    try {
+      File dir = new File(m_dirName);
+      String[] files = dir.list();
+      for (int i = 0; i < files.length; i++) {
+	if (files[i].endsWith(".txt")) {
+	  String stem = files[i].substring(0, files[i].length() - 4);
+	  if (!stems.containsKey(stem)) {
+	    stems.put(stem, new Double(0));
+	  }
+	}
+      }
+    } catch (Exception e) {
+      throw new Exception("Problem opening directory " + m_dirName);
+    }
+    return stems;
+  }
+
+  /**
+   * Builds the model from the files
+   */
+  public void extractKeyphrases(Hashtable stems) throws Exception {
+    
+    Vector stats = new Vector();
+
+    // Check whether there is actually any data
+    if (stems.size() == 0) {
+      throw new Exception("Couldn't find any data!");
+    }
+
+    FastVector atts = new FastVector(2);
+    atts.addElement(new Attribute("doc", null));
+    atts.addElement(new Attribute("keyphrases", null));
+    Instances data = new Instances("keyphrase_training_data", atts, 0);
+
+    // Extract keyphrases
+    Enumeration elem = stems.keys();
+    while (elem.hasMoreElements()) {
+      String str = (String)elem.nextElement();
+      double[] newInst = new double[2];
+      try {
+	File txt = new File(m_dirName + "/" + str + ".txt");
+	InputStreamReader is;
+	if (!m_encoding.equals("default")) {
+	  is = new InputStreamReader(new FileInputStream(txt), m_encoding);
+	} else {
+	  is = new InputStreamReader(new FileInputStream(txt));
+	}
+	StringBuffer txtStr = new StringBuffer();
+	int c;
+	while ((c = is.read()) != -1) {
+	  txtStr.append((char)c);
+	}
+	newInst[0] = (double)data.attribute(0).addStringValue(txtStr.toString());
+      } catch (Exception e) {
+	if (m_debug) {
+	  System.err.println("Can't read document " + str + ".txt");
+	}
+	newInst[0] = Instance.missingValue();
+      }
+      try {
+	File key = new File(m_dirName + "/" + str + ".key");
+	InputStreamReader is; 
+	if (!m_encoding.equals("default")) {
+	  is = new InputStreamReader(new FileInputStream(key), m_encoding);
+	} else {
+	  is = new InputStreamReader(new FileInputStream(key));
+	}
+	StringBuffer keyStr = new StringBuffer();
+	int c;
+	while ((c = is.read()) != -1) {
+	  keyStr.append((char)c);
+	}      
+	newInst[1] = (double)data.attribute(1).addStringValue(keyStr.toString());
+      } catch (Exception e) {
+	if (m_debug) {
+	  System.err.println("No keyphrases for stem " + str + ".");
+	}
+	newInst[1] = Instance.missingValue();
+      }
+      data.add(new Instance(1.0, newInst));
+      m_KEAFilter.input(data.instance(0));
+      data = data.stringFreeStructure();
+      if (m_debug) {
+	System.err.println("-- Document: " + str);
+      }
+      Instance[] topRankedInstances = new Instance[m_numPhrases];
+      Instance inst;
+      while ((inst = m_KEAFilter.output()) != null) {
+	int index = (int)inst.value(m_KEAFilter.getRankIndex()) - 1;
+	if (index < m_numPhrases) {
+	  topRankedInstances[index] = inst;
+	}
+      }
+      if (m_debug) {
+	System.err.println("-- Keyphrases and feature values:");
+      }
+      FileOutputStream out = null;
+      PrintWriter printer = null; 
+      File key = new File(m_dirName + "/" + str + ".key");
+      if (!key.exists()) {
+	out = new FileOutputStream(m_dirName + "/" + str + ".key");
+	if (!m_encoding.equals("default")) {
+	  printer = new PrintWriter(new OutputStreamWriter(out, m_encoding));
+	} else {
+	  printer = new PrintWriter(out);
+	}
+      }
+      double numExtracted = 0, numCorrect = 0;
+      for (int i = 0; i < m_numPhrases; i++) {
+	if (topRankedInstances[i] != null) {
+	  if (!topRankedInstances[i].
+	      isMissing(topRankedInstances[i].numAttributes() - 1)) {
+	    numExtracted += 1.0;
+	  }
+	  if ((int)topRankedInstances[i].
+	      value(topRankedInstances[i].numAttributes() - 1) == 
+	      topRankedInstances[i].
+	      attribute(topRankedInstances[i].numAttributes() - 1).
+	      indexOfValue("True")) {
+	    numCorrect += 1.0;
+	  }
+	  if (printer != null) {
+	    printer.print(topRankedInstances[i].
+			  stringValue(m_KEAFilter.getUnstemmedPhraseIndex()));
+	    if (m_AdditionalInfo) {
+	      printer.print("\t");
+	      printer.print(topRankedInstances[i].
+			  stringValue(m_KEAFilter.getStemmedPhraseIndex()));
+	      printer.print("\t");
+	      printer.print(Utils.
+			    doubleToString(topRankedInstances[i].
+					   value(m_KEAFilter.
+						 getProbabilityIndex()), 4));
+	    }
+	    printer.println();
+	  }
+	  if (m_debug) {
+	    System.err.println(topRankedInstances[i]);
+	  }
+	}
+      }
+      if (numExtracted > 0) {
+	if (m_debug) {
+	  System.err.println("-- " + numCorrect + " correct");
+	}
+	stats.addElement(new Double(numCorrect));
+      }
+      if (printer != null) {
+	printer.flush();
+	printer.close();
+	out.close();
+      }
+    }
+    double[] st = new double[stats.size()];
+    for (int i = 0; i < stats.size(); i++) {
+      st[i] = ((Double)stats.elementAt(i)).doubleValue();
+    }
+    double avg = Utils.mean(st);
+    double stdDev = Math.sqrt(Utils.variance(st));
+    System.err.println("Avg. number of correct keyphrases: " +
+		       Utils.doubleToString(avg, 2) + " +/- " + 
+		       Utils.doubleToString(stdDev, 2));
+    System.err.println("Based on " + stats.size() + " documents");
+    m_KEAFilter.batchFinished();
+  }
+  
+  /** 
+   * Loads the extraction model from the file.
+   */
+  public void loadModel() throws Exception {
+    
+    BufferedInputStream inStream =
+      new BufferedInputStream(new FileInputStream(m_modelName));
+    ObjectInputStream in = new ObjectInputStream(inStream);
+    m_KEAFilter = (KEAFilter)in.readObject();
+    in.close();
+  }
+  
+  /**
+   * The main method.  
+   */
+  public static void main(String[] ops) {
+    
+    KEAKeyphraseExtractor kmb = new KEAKeyphraseExtractor();
+    try {
+      kmb.setOptions(ops);
+      System.err.print("Extracting keyphrases with options: ");
+      String[] optionSettings = kmb.getOptions();
+      for (int i = 0; i < optionSettings.length; i++) {
+	System.err.print(optionSettings[i] + " ");
+      }
+      System.err.println();
+      kmb.loadModel();
+      kmb.extractKeyphrases(kmb.collectStems());
+    } catch (Exception e) {
+      e.printStackTrace();
+      System.err.println(e.getMessage());
+      System.err.println("\nOptions:\n");
+      Enumeration enum = kmb.listOptions();
+      while (enum.hasMoreElements()) {
+	Option option = (Option) enum.nextElement();
+	System.err.println(option.synopsis());
+	System.err.println(option.description());
+      }
+    }
+  }
+}
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/KEAModelBuilder.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/KEAModelBuilder.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/KEAModelBuilder.java	(revision 20131)
@@ -0,0 +1,689 @@
+/*
+ *    KEAModelBuilder.java
+ *    Copyright (C) 2001 Eibe Frank
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.io.*;
+import java.util.*;
+import weka.core.*;
+import weka.filters.*;
+
+/**
+ * Builds a keyphrase extraction model from the documents in a given
+ * directory.  Assumes that the file names for the documents end with
+ * ".txt".  Assumes that files containing corresponding
+ * author-assigned keyphrases end with ".key". Optionally an encoding
+ * for the documents/keyphrases can be defined (e.g. for Chinese
+ * text).
+ *
+ * Valid options are:<p>
+ *
+ * -l "directory name"<br>
+ * Specifies name of directory.<p>
+ *
+ * -m "model name"<br>
+ * Specifies name of model.<p>
+ *
+ * -e "encoding"<br>
+ * Specifies encoding.<p>
+ *
+ * -d<br>
+ * Turns debugging mode on.<p>
+ *
+ * -k<br>
+ * Use keyphrase frequency statistic.<p>
+ *
+ * -p<br>
+ * Disallow internal periods.<p>
+ *
+ * -x "length"<br>
+ * Sets maximum phrase length (default: 3).<p>
+ *
+ * -y "length"<br>
+ * Sets minimum phrase length (default: 1).<p>
+ *
+ * -o "number"<br>
+ * The minimum number of times a phrase needs to occur (default: 2). <p>
+ *
+ * -s "name of class implementing list of stop words"<br>
+ * Sets list of stop words to used (default: StopwordsEnglish).<p>
+ *
+ * -t "name of class implementing stemmer"<br>
+ * Sets stemmer to use (default: IteratedLovinsStemmer). <p>
+ *
+ * -n<br>
+ * Do not check for proper nouns. <p>
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version 1.0
+ */
+public class KEAModelBuilder implements OptionHandler {
+  
+  /** Name of directory */
+  String m_dirName = null;
+  
+  /** Name of model */
+  String m_modelName = null;
+
+  /** Encoding */
+  String m_encoding = "default";
+
+  /** Debugging mode? */
+  boolean m_debug = false;
+
+  /** Use keyphrase frequency attribute? */
+  boolean m_useKFrequency = false;
+
+  /** Disallow internal periods? */
+  boolean m_disallowIPeriods = false;
+
+  /** The maximum length of phrases */
+  private int m_MaxPhraseLength = 3;
+
+  /** The minimum length of phrases */
+  private int m_MinPhraseLength = 1;
+
+  /** The minimum number of occurences of a phrase */
+  private int m_MinNumOccur = 2;
+
+  /** The KEA filter object */
+  KEAFilter m_KEAFilter = null;
+
+  /** The stemmer to be used */
+  private Stemmer m_Stemmer = new IteratedLovinsStemmer();
+
+  /** The list of stop words to be used */
+  private Stopwords m_Stopwords = new StopwordsEnglish();
+
+  /** Determines whether check for proper nouns is performed */
+  private boolean m_CheckForProperNouns = true;
+
+  /**
+   * Get the M_CheckProperNouns value.
+   * @return the M_CheckProperNouns value.
+   */
+  public boolean getCheckForProperNouns() {
+    return m_CheckForProperNouns;
+  }
+
+  /**
+   * Set the M_CheckProperNouns value.
+   * @param newM_CheckProperNouns The new M_CheckProperNouns value.
+   */
+  public void setCheckForProperNouns(boolean newM_CheckProperNouns) {
+    this.m_CheckForProperNouns = newM_CheckProperNouns;
+  }
+
+  /**
+   * Get the M_Stopwords value.
+   * @return the M_Stopwords value.
+   */
+  public Stopwords getStopwords() {
+
+    return m_Stopwords;
+  }
+
+  /**
+   * Set the M_Stopwords value.
+   * @param newM_Stopwords The new M_Stopwords value.
+   */
+  public void setStopwords(Stopwords newM_Stopwords) {
+
+    this.m_Stopwords = newM_Stopwords;
+  }
+
+  
+  /**
+   * Get the Stemmer value.
+   * @return the Stemmer value.
+   */
+  public Stemmer getStemmer() {
+
+    return m_Stemmer;
+  }
+
+  /**
+   * Set the Stemmer value.
+   * @param newStemmer The new Stemmer value.
+   */
+  public void setStemmer(Stemmer newStemmer) {
+
+    this.m_Stemmer = newStemmer;
+  }
+  
+  /**
+   * Get the value of MinNumOccur.
+   *
+   * @return Value of MinNumOccur.
+   */
+  public int getMinNumOccur() {
+    
+    return m_MinNumOccur;
+  }
+  
+  /**
+   * Set the value of MinNumOccur.
+   *
+   * @param newMinNumOccur Value to assign to MinNumOccur.
+   */
+  public void setMinNumOccur(int newMinNumOccur) {
+    
+    m_MinNumOccur = newMinNumOccur;
+  }
+  
+  /**
+   * Get the value of MaxPhraseLength.
+   *
+   * @return Value of MaxPhraseLength.
+   */
+  public int getMaxPhraseLength() {
+    
+    return m_MaxPhraseLength;
+  }
+  
+  /**
+   * Set the value of MaxPhraseLength.
+   *
+   * @param newMaxPhraseLength Value to assign to MaxPhraseLength.
+   */
+  public void setMaxPhraseLength(int newMaxPhraseLength) {
+    
+    m_MaxPhraseLength = newMaxPhraseLength;
+  }
+  
+  /**
+   * Get the value of MinPhraseLength.
+   *
+   * @return Value of MinPhraseLength.
+   */
+  public int getMinPhraseLength() {
+    
+    return m_MinPhraseLength;
+  }
+  
+  /**
+   * Set the value of MinPhraseLength.
+   *
+   * @param newMinPhraseLength Value to assign to MinPhraseLength.
+   */
+  public void setMinPhraseLength(int newMinPhraseLength) {
+    
+    m_MinPhraseLength = newMinPhraseLength;
+  }
+  
+  /**
+   * Get the value of disallowIPeriods.
+   *
+   * @return Value of disallowIPeriods.
+   */
+  public boolean getDisallowIPeriods() {
+    
+    return m_disallowIPeriods;
+  }
+  
+  /**
+   * Set the value of disallowIPeriods.
+   *
+   * @param newdisallowIPeriods Value to assign to disallowIPeriods.
+   */
+  public void setDisallowIPeriods(boolean newdisallowIPeriods) {
+    
+    m_disallowIPeriods = newdisallowIPeriods;
+  }
+  
+  /**
+   * Get the value of useKFrequency.
+   *
+   * @return Value of useKFrequency.
+   */
+  public boolean getUseKFrequency() {
+    
+    return m_useKFrequency;
+  }
+  
+  /**
+   * Set the value of useKFrequency.
+   *
+   * @param newuseKFrequency Value to assign to useKFrequency.
+   */
+  public void setUseKFrequency(boolean newuseKFrequency) {
+    
+    m_useKFrequency = newuseKFrequency;
+  }
+  
+  /**
+   * Get the value of debug.
+   *
+   * @return Value of debug.
+   */
+  public boolean getDebug() {
+    
+    return m_debug;
+  }
+  
+  /**
+   * Set the value of debug.
+   *
+   * @param newdebug Value to assign to debug.
+   */
+  public void setDebug(boolean newdebug) {
+    
+    m_debug = newdebug;
+  }
+  
+  /**
+   * Get the value of encoding.
+   *
+   * @return Value of encoding.
+   */
+  public String getEncoding() {
+    
+    return m_encoding;
+  }
+  
+  /**
+   * Set the value of encoding.
+   *
+   * @param newencoding Value to assign to encoding.
+   */
+  public void setEncoding(String newencoding) {
+    
+    m_encoding = newencoding;
+  }
+  
+  /**
+   * Get the value of modelName.
+   *
+   * @return Value of modelName.
+   */
+  public String getModelName() {
+    
+    return m_modelName;
+  }
+  
+  /**
+   * Set the value of modelName.
+   *
+   * @param newmodelName Value to assign to modelName.
+   */
+  public void setModelName(String newmodelName) {
+    
+    m_modelName = newmodelName;
+  }
+  
+  /**
+   * Get the value of dirName.
+   *
+   * @return Value of dirName.
+   */
+  public String getDirName() {
+    
+    return m_dirName;
+  }
+  
+  /**
+   * Set the value of dirName.
+   *
+   * @param newdirName Value to assign to dirName.
+   */
+  public void setDirName(String newdirName) {
+    
+    m_dirName = newdirName;
+  }
+  
+  /**
+   * Parses a given list of options controlling the behaviour of this object.
+   * Valid options are:<p>
+   *
+   * -l "directory name" <br>
+   * Specifies name of directory.<p>
+   *
+   * -m "model name" <br>
+   * Specifies name of model.<p>
+   *
+   * -e "encoding" <br>
+   * Specifies encoding.<p>
+   *
+   * -d<br>
+   * Turns debugging mode on.<p>
+   *
+   * -k<br>
+   * Use keyphrase frequency statistic.<p>
+   *
+   * -p<br>
+   * Disallow internal periods. <p>
+   *
+   * -x "length"<br>
+   * Sets maximum phrase length (default: 3).<p>
+   *
+   * -y "length"<br>
+   * Sets minimum phrase length (default: 3).<p>
+   *
+   * -o "number"<br>
+   * The minimum number of times a phrase needs to occur (default: 2). <p>
+   *
+   * -s "name of class implementing list of stop words"<br>
+   * Sets list of stop words to used (default: StopwordsEnglish).<p>
+   *
+   * -t "name of class implementing stemmer"<br>
+   * Sets stemmer to use (default: IteratedLovinsStemmer). <p>
+   *
+   * -n<br>
+   * Do not check for proper nouns. <p>
+   *
+   * @param options the list of options as an array of strings
+   * @exception Exception if an option is not supported
+   */
+  public void setOptions(String[] options) throws Exception {
+
+    String dirName = Utils.getOption('l', options);
+    if (dirName.length() > 0) {
+      setDirName(dirName);
+    } else {
+      setDirName(null);
+      throw new Exception("Name of directory required argument.");
+    }
+    String modelName = Utils.getOption('m', options);
+    if (modelName.length() > 0) {
+      setModelName(modelName);
+    } else {
+      setModelName(null);
+      throw new Exception("Name of model required argument.");
+    }
+    String encoding = Utils.getOption('e', options);
+    if (encoding.length() > 0) {
+      setEncoding(encoding);
+    } else {
+      setEncoding("default");
+    }
+    String maxPhraseLengthString = Utils.getOption('x', options);
+    if (maxPhraseLengthString.length() > 0) {
+      setMaxPhraseLength(Integer.parseInt(maxPhraseLengthString));
+    } else {
+      setMaxPhraseLength(3);
+    }
+    String minPhraseLengthString = Utils.getOption('y', options);
+    if (minPhraseLengthString.length() > 0) {
+      setMinPhraseLength(Integer.parseInt(minPhraseLengthString));
+    } else {
+      setMinPhraseLength(1);
+    }
+    String minNumOccurString = Utils.getOption('o', options);
+    if (minNumOccurString.length() > 0) {
+      setMinNumOccur(Integer.parseInt(minNumOccurString));
+    } else {
+      setMinNumOccur(2);
+    }
+    String stopwordsString = Utils.getOption('s', options);
+    if (stopwordsString.length() > 0) {
+      setStopwords((Stopwords)Class.forName(stopwordsString).newInstance());
+    }
+    String stemmerString = Utils.getOption('t', options);
+    if (stemmerString.length() > 0) {
+      setStemmer((Stemmer)Class.forName(stemmerString).newInstance());
+    }
+    setDebug(Utils.getFlag('d', options));
+    setUseKFrequency(Utils.getFlag('k', options));
+    setDisallowIPeriods(Utils.getFlag('p', options));
+    setCheckForProperNouns(!Utils.getFlag('n', options));
+    Utils.checkForRemainingOptions(options);
+   }
+
+  /**
+   * Gets the current option settings.
+   *
+   * @return an array of strings suitable for passing to setOptions
+   */
+  public String [] getOptions() {
+
+    String [] options = new String [20];
+    int current = 0;
+
+    options[current++] = "-l"; 
+    options[current++] = "" + (getDirName());
+    options[current++] = "-m"; 
+    options[current++] = "" + (getModelName());
+    options[current++] = "-e"; 
+    options[current++] = "" + (getEncoding());
+    if (getUseKFrequency()) {
+      options[current++] = "-k";
+    }
+    if (getDebug()) {
+      options[current++] = "-d";
+    }
+    if (getDisallowIPeriods()) {
+      options[current++] = "-p";
+    }
+    options[current++] = "-x"; 
+    options[current++] = "" + (getMaxPhraseLength());
+    options[current++] = "-y"; 
+    options[current++] = "" + (getMinPhraseLength());
+    options[current++] = "-o"; 
+    options[current++] = "" + (getMinNumOccur());
+    options[current++] = "-s"; 
+    options[current++] = "" + (getStopwords().getClass().getName());
+    options[current++] = "-t"; 
+    options[current++] = "" + (getStemmer().getClass().getName());
+    if (getCheckForProperNouns()) {
+      options[current++] = "-n";
+    }
+
+    while (current < options.length) {
+      options[current++] = "";
+    }
+    return options;
+  }
+
+  /**
+   * Returns an enumeration describing the available options.
+   *
+   * @return an enumeration of all the available options
+   */
+  public Enumeration listOptions() {
+
+    Vector newVector = new Vector(12);
+
+    newVector.addElement(new Option(
+	      "\tSpecifies name of directory.",
+              "l", 1, "-l <directory name>"));
+    newVector.addElement(new Option(
+	      "\tSpecifies name of model.",
+              "m", 1, "-m <model name>"));
+    newVector.addElement(new Option(
+	      "\tSpecifies encoding.",
+              "e", 1, "-e <encoding>"));
+    newVector.addElement(new Option(
+	      "\tTurns debugging mode on.",
+              "d", 0, "-d"));
+    newVector.addElement(new Option(
+	      "\tUse keyphrase frequency statistic.",
+              "k", 0, "-k"));
+    newVector.addElement(new Option(
+	      "\tDisallow internal periods.",
+              "p", 0, "-p"));
+    newVector.addElement(new Option(
+	      "\tSets the maximum phrase length (default: 3).",
+              "x", 1, "-x <length>"));
+    newVector.addElement(new Option(
+	      "\tSets the minimum phrase length (default: 1).",
+              "y", 1, "-y <length>"));
+    newVector.addElement(new Option(
+	      "\tSet the minimum number of occurences (default: 2).",
+              "o", 1, "-o"));
+    newVector.addElement(new Option(
+	      "\tSets the list of stopwords to use (default: StopwordsEnglish).",
+              "s", 1, "-s <name of stopwords class>"));
+    newVector.addElement(new Option(
+	      "\tSet the stemmer to use (default: IteratedLovinsStemmer).",
+              "t", 1, "-t <name of stemmer class>"));
+    newVector.addElement(new Option(
+	      "\tDo not check for proper nouns.",
+              "n", 0, "-n"));
+ 
+    return newVector.elements();
+  }
+
+  /**
+   * Collects the stems of the file names.
+   */
+  public Hashtable collectStems() throws Exception {
+
+    Hashtable stems = new Hashtable();
+
+    try {
+      File dir = new File(m_dirName);
+      String[] files = dir.list();
+      for (int i = 0; i < files.length; i++) {
+	if (files[i].endsWith(".key") ||
+	    files[i].endsWith(".txt")) {
+	  String stem = files[i].substring(0, files[i].length() - 4);
+	  if (!stems.containsKey(stem)) {
+	    stems.put(stem, new Double(0));
+	  }
+	}
+      }
+    } catch (Exception e) {
+      throw new Exception("Problem opening directory " + m_dirName);
+    }
+    return stems;
+  }
+
+  /**
+   * Builds the model from the files
+   */
+  public void buildModel(Hashtable stems) throws Exception {
+    
+    // Check whether there is actually any data
+    if (stems.size() == 0) {
+      throw new Exception("Couldn't find any data!");
+    }
+
+    FastVector atts = new FastVector(2);
+    atts.addElement(new Attribute("doc", null));
+    atts.addElement(new Attribute("keyphrases", null));
+    Instances data = new Instances("keyphrase_training_data", atts, 0);
+
+    // Build model
+    m_KEAFilter = new KEAFilter();
+    m_KEAFilter.setDebug(m_debug);
+    m_KEAFilter.setDisallowInternalPeriods(getDisallowIPeriods());
+    m_KEAFilter.setKFused(getUseKFrequency());
+    m_KEAFilter.setMaxPhraseLength(getMaxPhraseLength());
+    m_KEAFilter.setMinPhraseLength(getMinPhraseLength());
+    m_KEAFilter.setMinNumOccur(getMinNumOccur());
+    m_KEAFilter.setInputFormat(data);
+    m_KEAFilter.setStemmer(getStemmer());
+    m_KEAFilter.setStopwords(getStopwords());
+    m_KEAFilter.setCheckForProperNouns(getCheckForProperNouns());
+    Enumeration elem = stems.keys();
+    while (elem.hasMoreElements()) {
+      String str = (String)elem.nextElement();
+      double[] newInst = new double[2];
+      try {
+	File txt = new File(m_dirName + "/" + str + ".txt");
+	InputStreamReader is;
+	if (!m_encoding.equals("default")) {
+	  is = new InputStreamReader(new FileInputStream(txt), m_encoding);
+	} else {
+	  is = new InputStreamReader(new FileInputStream(txt));
+	}
+	StringBuffer txtStr = new StringBuffer();
+	int c;
+	while ((c = is.read()) != -1) {
+	  txtStr.append((char)c);
+	}
+	newInst[0] = (double)data.attribute(0).addStringValue(txtStr.toString());
+      } catch (Exception e) {
+	if (m_debug) {
+	  System.err.println("Can't find document for stem " + str + ".");
+	}
+	newInst[0] = Instance.missingValue();
+      }
+      try {
+	File key = new File(m_dirName + "/" + str + ".key");
+	InputStreamReader is; 
+	if (!m_encoding.equals("default")) {
+	  is = new InputStreamReader(new FileInputStream(key), m_encoding);
+	} else {
+	  is = new InputStreamReader(new FileInputStream(key));
+	}
+	StringBuffer keyStr = new StringBuffer();
+	int c;
+	while ((c = is.read()) != -1) {
+	  keyStr.append((char)c);
+	}      
+	newInst[1] = (double)data.attribute(1).addStringValue(keyStr.toString());
+      } catch (Exception e) {
+	if (m_debug) {
+	  System.err.println("Can't find keyphrases for stem " + str + ".");
+	}
+	newInst[1] = Instance.missingValue();
+      }
+      data.add(new Instance(1.0, newInst));
+      m_KEAFilter.input(data.instance(0));
+      data = data.stringFreeStructure();
+    }
+    m_KEAFilter.batchFinished();
+    
+    // Get rid of instances in filter
+    Instance dummy;
+    while ((dummy = m_KEAFilter.output()) != null) {};
+  }
+  
+  /** 
+   * Saves the extraction model to the file.
+   */
+  public void saveModel() throws Exception {
+    
+    BufferedOutputStream bufferedOut = 
+      new BufferedOutputStream(new FileOutputStream(m_modelName));
+    ObjectOutputStream out = new ObjectOutputStream(bufferedOut);
+    out.writeObject(m_KEAFilter);
+    out.flush();
+    out.close();
+  }
+  
+  /**
+   * The main method.  
+   */
+  public static void main(String[] ops) {
+    
+    KEAModelBuilder kmb = new KEAModelBuilder();
+    try {
+      kmb.setOptions(ops);
+      System.err.print("Building model with options: ");
+      String[] optionSettings = kmb.getOptions();
+      for (int i = 0; i < optionSettings.length; i++) {
+	System.err.print(optionSettings[i] + " ");
+      }
+      System.err.println();
+      kmb.buildModel(kmb.collectStems());
+      kmb.saveModel();
+    } catch (Exception e) {
+      e.printStackTrace();
+      System.err.println(e.getMessage());
+      System.err.println("\nOptions:\n");
+      Enumeration enum = kmb.listOptions();
+      while (enum.hasMoreElements()) {
+	Option option = (Option) enum.nextElement();
+	System.err.println(option.synopsis());
+	System.err.println(option.description());
+      }
+    }
+  }
+}
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/KEAPhraseFilter.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/KEAPhraseFilter.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/KEAPhraseFilter.java	(revision 20131)
@@ -0,0 +1,487 @@
+/*
+ *    KEAPhraseFilter.java
+ *    Copyright (C) 2001 Eibe Frank
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.util.*;
+
+import weka.core.*;
+import weka.filters.*;
+
+/**
+ * This filter splits the text in selected string
+ * attributes into phrases. The resulting
+ * string attributes contain these phrases
+ * separated by '\n' characters.
+ *
+ * Phrases are identified according to the
+ * following definitions:
+ * 
+ * A phrase is a sequence of words interrupted
+ * only by sequences of whitespace characters,
+ * where each sequence of whitespace characters
+ * contains at most one '\n'.
+ *
+ * A word is a sequence of letters or digits
+ * that contains at least one letter, with
+ * the following exceptions:
+ *
+ * a) '.', '@', '_', '&', '/', '-' are allowed
+ * if surrounded by letters or digits,
+ *
+ * b) '\'' is allowed if preceeded by a letter
+ * or digit,
+ * 
+ * c) '-', '/' are also allowed if succeeded by
+ * whitespace characters followed by another
+ * word. In that case the whitespace characters
+ * will be deleted.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version 1.0
+ */
+public class KEAPhraseFilter extends Filter implements OptionHandler {
+
+  /** Stores which columns to select as a funky range */
+  protected Range m_SelectCols = new Range();
+
+  /** Determines whether internal periods are allowed */
+  protected boolean m_DisallowInternalPeriods = false;
+
+  /**
+   * Returns a string describing this filter
+   *
+   * @return a description of the filter suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String globalInfo() {
+    return "This filter splits the text contained " +
+      "by the selected string attributes into phrases.";
+  }
+
+  /**
+   * Returns an enumeration describing the available options
+   *
+   * @return an enumeration of all the available options
+   */
+  public Enumeration listOptions() {
+
+    Vector newVector = new Vector(3);
+
+    newVector.addElement(new Option(
+              "\tSpecify list of attributes to process. First and last are valid\n"
+	      +"\tindexes. (default none)",
+              "R", 1, "-R <index1,index2-index4,...>"));
+    newVector.addElement(new Option(
+	      "\tInvert matching sense",
+              "V", 0, "-V"));
+    newVector.addElement(new Option(
+	      "\tDisallow internal periods",
+              "P", 0, "-P"));
+
+    return newVector.elements();
+  }
+
+  /**
+   * Parses a given list of options controlling the behaviour of this object.
+   * Valid options are:<p>
+   *
+   * -R index1,index2-index4,...<br>
+   * Specify list of attributes to process. First and last are valid indexes.
+   * (default none)<p>
+   *
+   * -V<br>
+   * Invert matching sense <p>
+   *
+   * -P<br>
+   * Disallow internal periods <p>
+   *
+   * @param options the list of options as an array of strings
+   * @exception Exception if an option is not supported
+   */
+  public void setOptions(String[] options) throws Exception {
+
+    String list = Utils.getOption('R', options);
+    if (list.length() != 0) {
+      setAttributeIndices(list);
+    }
+    setInvertSelection(Utils.getFlag('V', options));
+
+    setDisallowInternalPeriods(Utils.getFlag('P', options));
+    
+    if (getInputFormat() != null) {
+      setInputFormat(getInputFormat());
+    }
+  }
+
+  /**
+   * Gets the current settings of the filter.
+   *
+   * @return an array of strings suitable for passing to setOptions
+   */
+  public String [] getOptions() {
+
+    String [] options = new String [4];
+    int current = 0;
+
+    if (getInvertSelection()) {
+      options[current++] = "-V";
+    }
+    if (getDisallowInternalPeriods()) {
+      options[current++] = "-P";
+    }
+    if (!getAttributeIndices().equals("")) {
+      options[current++] = "-R"; options[current++] = getAttributeIndices();
+    }
+
+    while (current < options.length) {
+      options[current++] = "";
+    }
+    return options;
+  }
+
+  /**
+   * Sets the format of the input instances.
+   *
+   * @param instanceInfo an Instances object containing the input
+   * instance structure (any instances contained in the object are
+   * ignored - only the structure is required).
+   * @return true if the outputFormat may be collected immediately 
+   */
+  public boolean setInputFormat(Instances instanceInfo) throws Exception {
+
+    super.setInputFormat(instanceInfo);
+    setOutputFormat(instanceInfo);
+    m_SelectCols.setUpper(instanceInfo.numAttributes() - 1);
+
+    return true;
+  }
+
+  /**
+   * Input an instance for filtering. Ordinarily the instance is processed
+   * and made available for output immediately. Some filters require all
+   * instances be read before producing output.
+   *
+   * @param instance the input instance
+   * @return true if the filtered instance may now be
+   * collected with output().
+   * @exception Exception if the input instance was not of the correct 
+   * format or if there was a problem with the filtering.
+   */
+  public boolean input(Instance instance) throws Exception {
+
+    if (getInputFormat() == null) {
+      throw new Exception("No input instance format defined");
+    }
+    if (m_NewBatch) {
+      resetQueue();
+      m_NewBatch = false;
+    }
+    convertInstance(instance);
+    return true;
+  }
+
+  /**
+   * Signify that this batch of input to the filter is finished. If
+   * the filter requires all instances prior to filtering, output()
+   * may now be called to retrieve the filtered instances. Any
+   * subsequent instances filtered should be filtered based on setting
+   * obtained from the first batch (unless the inputFormat has been
+   * re-assigned or new options have been set). This default
+   * implementation assumes all instance processing occurs during
+   * inputFormat() and input().
+   *
+   * @return true if there are instances pending output
+   * @exception NullPointerException if no input structure has been defined,
+   * @exception Exception if there was a problem finishing the batch.
+   */
+  public boolean batchFinished() throws Exception {
+
+    if (getInputFormat() == null) {
+      throw new NullPointerException("No input instance format defined");
+    }
+    m_NewBatch = true;
+    return (numPendingOutput() != 0);
+  }
+
+  /**
+   * Main method for testing this class.
+   *
+   * @param argv should contain arguments to the filter: use -h for help
+   */
+  public static void main(String [] argv) {
+    
+    try {
+      if (Utils.getFlag('b', argv)) {
+	Filter.batchFilterFile(new KEAPhraseFilter(), argv);
+      } else {
+	Filter.filterFile(new KEAPhraseFilter(), argv);
+      }
+    } catch (Exception ex) {
+      System.out.println(ex.getMessage());
+    }
+  }
+ 
+  /** 
+   * Converts an instance by removing all non-alphanumeric characters
+   * from its string attribute values.
+   */
+  private void convertInstance(Instance instance) throws Exception {
+  
+    double[] instVals = new double[instance.numAttributes()];
+
+    for (int i = 0; i < instance.numAttributes(); i++) {
+      if (!instance.attribute(i).isString() || 
+	  instance.isMissing(i)) {
+	instVals[i] = instance.value(i);
+      } else {
+	if (!m_SelectCols.isInRange(i)) {
+	  int index = getOutputFormat().attribute(i).
+	    addStringValue(instance.stringValue(i));
+	  instVals[i] = (double)index;
+	  continue;
+	}
+	String str = instance.stringValue(i);
+	StringBuffer resultStr = new StringBuffer();
+	int j = 0;
+	boolean phraseStart = true;
+	boolean seenNewLine = false;
+	boolean haveSeenHyphen = false;
+	boolean haveSeenSlash = false;
+	while (j < str.length()) {
+	  boolean isWord = false;
+	  boolean potNumber = false;
+	  int startj = j;
+	  while (j < str.length()) {
+	    char ch = str.charAt(j);
+	    if (Character.isLetterOrDigit(ch)) {
+	      potNumber = true;
+	      if (Character.isLetter(ch)) {
+		isWord = true;
+	      }
+	      j++;
+	    } else if ((!m_DisallowInternalPeriods && (ch == '.')) ||
+		       (ch == '@') ||
+		       (ch == '_') ||
+		       (ch == '&') ||
+		       (ch == '/') ||
+		       (ch == '-')) {
+	      if ((j > 0) && (j  + 1 < str.length()) &&
+		  Character.isLetterOrDigit(str.charAt(j - 1)) &&
+		  Character.isLetterOrDigit(str.charAt(j + 1))) {
+		j++;
+	      } else {
+		break;
+	      }
+	    } else if (ch == '\'') {
+	      if ((j > 0) &&
+		  Character.isLetterOrDigit(str.charAt(j - 1))) {
+		j++;
+	      } else {
+		break;
+	      }
+	    } else {
+	      break;
+	    }
+	  }
+	  if (isWord == true) {
+	    if (!phraseStart) {
+	      if (haveSeenHyphen) {
+		resultStr.append('-');
+	      } else if (haveSeenSlash) {
+		resultStr.append('/');
+	      } else {
+		resultStr.append(' ');
+	      }
+	    }
+	    resultStr.append(str.substring(startj, j));
+	    if (j == str.length()) {
+	      break;
+	    }
+	    phraseStart = false;
+	    seenNewLine = false;
+	    haveSeenHyphen = false;
+	    haveSeenSlash = false;
+	    if (Character.isWhitespace(str.charAt(j))) {
+	      if (str.charAt(j) == '\n') {
+		seenNewLine = true;
+	      } 
+	    } else if (str.charAt(j) == '-') {
+	      haveSeenHyphen = true;
+	    } else if (str.charAt(j) == '/') {
+	      haveSeenSlash = true;
+	    } else {
+	      phraseStart = true;
+	      resultStr.append('\n');
+	    }
+	    j++;
+	  } else if (j == str.length()) {
+	    break;
+	  } else if (str.charAt(j) == '\n') {
+	    if (seenNewLine) {
+	      if (phraseStart == false) {
+		resultStr.append('\n');
+		phraseStart = true;
+	      }
+	    } else if (potNumber) {
+	      if (phraseStart == false) {
+		phraseStart = true;
+		resultStr.append('\n');
+	      }
+	    }
+	    seenNewLine = true;
+	    j++;
+	  } else if (Character.isWhitespace(str.charAt(j))) {
+	    if (potNumber) {
+	      if (phraseStart == false) {
+		phraseStart = true;
+		resultStr.append('\n');
+	      }
+	    }
+	    j++;
+	  } else {
+	    if (phraseStart == false) {
+	      resultStr.append('\n');
+	      phraseStart = true;
+	    }
+	    j++;
+	  }
+	}
+	int index = getOutputFormat().attribute(i).
+	  addStringValue(resultStr.toString());
+	instVals[i] = (double)index;
+      }
+    }
+    Instance inst = new Instance(instance.weight(), instVals);
+    inst.setDataset(getOutputFormat());
+    push(inst);
+  }
+
+  /**
+   * Returns the tip text for this property
+   *
+   * @return tip text for this property suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String invertSelectionTipText() {
+
+    return "If set to false, the specified attributes will be processed;"
+      + " If set to true, specified attributes won't be processed.";
+  }
+
+  /**
+   * Get whether the supplied columns are to be processed
+   *
+   * @return true if the supplied columns won't be processed
+   */
+  public boolean getInvertSelection() {
+
+    return m_SelectCols.getInvert();
+  }
+
+  /**
+   * Set whether selected columns should be processed. If true the 
+   * selected columns won't be processed.
+   *
+   * @param invert the new invert setting
+   */
+  public void setInvertSelection(boolean invert) {
+
+    m_SelectCols.setInvert(invert);
+  }
+
+  /**
+   * Returns the tip text for this property
+   *
+   * @return tip text for this property suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String disallowInternalPeriodsTipText() {
+
+    return "If set to false, internal periods are allowed.";
+  }
+
+  /**
+   * Get whether the supplied columns are to be processed
+   *
+   * @return true if the supplied columns won't be processed
+   */
+  public boolean getDisallowInternalPeriods() {
+
+    return m_DisallowInternalPeriods;
+  }
+
+  /**
+   * Set whether selected columns should be processed. If true the 
+   * selected columns won't be processed.
+   *
+   * @param invert the new invert setting
+   */
+  public void setDisallowInternalPeriods(boolean disallow) {
+
+    m_DisallowInternalPeriods = disallow;
+  }
+
+  /**
+   * Returns the tip text for this property
+   *
+   * @return tip text for this property suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String attributeIndicesTipText() {
+
+    return "Specify range of attributes to act on."
+      + " This is a comma separated list of attribute indices, with"
+      + " \"first\" and \"last\" valid values. Specify an inclusive"
+      + " range with \"-\". E.g: \"first-3,5,6-10,last\".";
+  }
+
+  /**
+   * Get the current range selection.
+   *
+   * @return a string containing a comma separated list of ranges
+   */
+  public String getAttributeIndices() {
+
+    return m_SelectCols.getRanges();
+  }
+
+  /**
+   * Set which attributes are to be processed
+   *
+   * @param rangeList a string representing the list of attributes.  Since
+   * the string will typically come from a user, attributes are indexed from
+   * 1. <br>
+   * eg: first-3,5,6-last
+   */
+  public void setAttributeIndices(String rangeList) {
+
+    m_SelectCols.setRanges(rangeList);
+  }
+
+  /**
+   * Set which attributes are to be processed
+   *
+   * @param attributes an array containing indexes of attributes to select.
+   * Since the array will typically come from a program, attributes are indexed
+   * from 0.
+   */
+  public void setAttributeIndicesArray(int [] attributes) {
+    
+    setAttributeIndices(Range.indicesToRangeList(attributes));
+  }
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/LovinsStemmer.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/LovinsStemmer.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/LovinsStemmer.java	(revision 20131)
@@ -0,0 +1,890 @@
+/*
+ *    LovinsStemmer.java
+ *    Copyright (C) 2001 Eibe Frank
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.util.*;
+import java.io.*;
+
+/** 
+ * Implements the Lovins stemmer.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version 1.0
+ */
+public class LovinsStemmer extends Stemmer implements Serializable {
+
+  /** C version compatibility mode (emulates bugs
+      in original C implementation) */
+  private static boolean m_CompMode = true;
+
+  /** The hash tables containing the list of endings. */
+  private static HashMap m_l11 = null;
+  private static HashMap m_l10 = null;
+  private static HashMap m_l9 = null;
+  private static HashMap m_l8 = null;
+  private static HashMap m_l7 = null;
+  private static HashMap m_l6 = null;
+  private static HashMap m_l5 = null;
+  private static HashMap m_l4 = null;
+  private static HashMap m_l3 = null;
+  private static HashMap m_l2 = null;
+  private static HashMap m_l1 = null;
+
+  static {
+
+    m_l11 = new HashMap();
+    m_l11.put("alistically", "B");
+    m_l11.put("arizability", "A");
+    m_l11.put("izationally", "B");
+    m_l10 = new HashMap();
+    m_l10.put("antialness", "A");
+    m_l10.put("arisations", "A");
+    m_l10.put("arizations", "A");
+    m_l10.put("entialness", "A");
+    m_l9 = new HashMap();
+    m_l9.put("allically", "C");
+    m_l9.put("antaneous", "A");
+    m_l9.put("antiality", "A");
+    m_l9.put("arisation", "A");
+    m_l9.put("arization", "A");
+    m_l9.put("ationally", "B");
+    m_l9.put("ativeness", "A");
+    m_l9.put("eableness", "E");
+    m_l9.put("entations", "A");
+    m_l9.put("entiality", "A");
+    m_l9.put("entialize", "A");
+    m_l9.put("entiation", "A");
+    m_l9.put("ionalness", "A");
+    m_l9.put("istically", "A");
+    m_l9.put("itousness", "A");
+    m_l9.put("izability", "A");
+    m_l9.put("izational", "A");
+    m_l8 = new HashMap();
+    m_l8.put("ableness", "A");
+    m_l8.put("arizable", "A");
+    m_l8.put("entation", "A");
+    m_l8.put("entially", "A");
+    m_l8.put("eousness", "A");
+    m_l8.put("ibleness", "A");
+    m_l8.put("icalness", "A");
+    m_l8.put("ionalism", "A");
+    m_l8.put("ionality", "A");
+    m_l8.put("ionalize", "A");
+    m_l8.put("iousness", "A");
+    m_l8.put("izations", "A");
+    m_l8.put("lessness", "A");
+    m_l7 = new HashMap();
+    m_l7.put("ability", "A");
+    m_l7.put("aically", "A");
+    m_l7.put("alistic", "B");
+    m_l7.put("alities", "A");
+    m_l7.put("ariness", "E");
+    m_l7.put("aristic", "A");
+    m_l7.put("arizing", "A");
+    m_l7.put("ateness", "A");
+    m_l7.put("atingly", "A");
+    m_l7.put("ational", "B");
+    m_l7.put("atively", "A");
+    m_l7.put("ativism", "A");
+    m_l7.put("elihood", "E");
+    m_l7.put("encible", "A");
+    m_l7.put("entally", "A");
+    m_l7.put("entials", "A");
+    m_l7.put("entiate", "A");
+    m_l7.put("entness", "A");
+    m_l7.put("fulness", "A");
+    m_l7.put("ibility", "A");
+    m_l7.put("icalism", "A");
+    m_l7.put("icalist", "A");
+    m_l7.put("icality", "A");
+    m_l7.put("icalize", "A");
+    m_l7.put("ication", "G");
+    m_l7.put("icianry", "A");
+    m_l7.put("ination", "A");
+    m_l7.put("ingness", "A");
+    m_l7.put("ionally", "A");
+    m_l7.put("isation", "A");
+    m_l7.put("ishness", "A");
+    m_l7.put("istical", "A");
+    m_l7.put("iteness", "A");
+    m_l7.put("iveness", "A");
+    m_l7.put("ivistic", "A");
+    m_l7.put("ivities", "A");
+    m_l7.put("ization", "F");
+    m_l7.put("izement", "A");
+    m_l7.put("oidally", "A");
+    m_l7.put("ousness", "A");
+    m_l6 = new HashMap();
+    m_l6.put("aceous", "A");
+    m_l6.put("acious", "B");
+    m_l6.put("action", "G");
+    m_l6.put("alness", "A");
+    m_l6.put("ancial", "A");
+    m_l6.put("ancies", "A");
+    m_l6.put("ancing", "B");
+    m_l6.put("ariser", "A");
+    m_l6.put("arized", "A");
+    m_l6.put("arizer", "A");
+    m_l6.put("atable", "A");
+    m_l6.put("ations", "B");
+    m_l6.put("atives", "A");
+    m_l6.put("eature", "Z");
+    m_l6.put("efully", "A");
+    m_l6.put("encies", "A");
+    m_l6.put("encing", "A");
+    m_l6.put("ential", "A");
+    m_l6.put("enting", "C");
+    m_l6.put("entist", "A");
+    m_l6.put("eously", "A");
+    m_l6.put("ialist", "A");
+    m_l6.put("iality", "A");
+    m_l6.put("ialize", "A");
+    m_l6.put("ically", "A");
+    m_l6.put("icance", "A");
+    m_l6.put("icians", "A");
+    m_l6.put("icists", "A");
+    m_l6.put("ifully", "A");
+    m_l6.put("ionals", "A");
+    m_l6.put("ionate", "D");
+    m_l6.put("ioning", "A");
+    m_l6.put("ionist", "A");
+    m_l6.put("iously", "A");
+    m_l6.put("istics", "A");
+    m_l6.put("izable", "E");
+    m_l6.put("lessly", "A");
+    m_l6.put("nesses", "A");
+    m_l6.put("oidism", "A");
+    m_l5 = new HashMap();
+    m_l5.put("acies", "A");
+    m_l5.put("acity", "A");
+    m_l5.put("aging", "B");
+    m_l5.put("aical", "A");
+    if (!m_CompMode) {
+      m_l5.put("alist", "A");
+    }
+    m_l5.put("alism", "B");
+    m_l5.put("ality", "A");
+    m_l5.put("alize", "A");
+    m_l5.put("allic", "b");
+    m_l5.put("anced", "B");
+    m_l5.put("ances", "B");
+    m_l5.put("antic", "C");
+    m_l5.put("arial", "A");
+    m_l5.put("aries", "A");
+    m_l5.put("arily", "A");
+    m_l5.put("arity", "B");
+    m_l5.put("arize", "A");
+    m_l5.put("aroid", "A");
+    m_l5.put("ately", "A");
+    m_l5.put("ating", "I");
+    m_l5.put("ation", "B");
+    m_l5.put("ative", "A");
+    m_l5.put("ators", "A");
+    m_l5.put("atory", "A");
+    m_l5.put("ature", "E");
+    m_l5.put("early", "Y");
+    m_l5.put("ehood", "A");
+    m_l5.put("eless", "A");
+    if (!m_CompMode) {
+      m_l5.put("elily", "A");
+    } else {
+      m_l5.put("elity", "A");
+    }
+    m_l5.put("ement", "A");
+    m_l5.put("enced", "A");
+    m_l5.put("ences", "A");
+    m_l5.put("eness", "E");
+    m_l5.put("ening", "E");
+    m_l5.put("ental", "A");
+    m_l5.put("ented", "C");
+    m_l5.put("ently", "A");
+    m_l5.put("fully", "A");
+    m_l5.put("ially", "A");
+    m_l5.put("icant", "A");
+    m_l5.put("ician", "A");
+    m_l5.put("icide", "A");
+    m_l5.put("icism", "A");
+    m_l5.put("icist", "A");
+    m_l5.put("icity", "A");
+    m_l5.put("idine", "I");
+    m_l5.put("iedly", "A");
+    m_l5.put("ihood", "A");
+    m_l5.put("inate", "A");
+    m_l5.put("iness", "A");
+    m_l5.put("ingly", "B");
+    m_l5.put("inism", "J");
+    m_l5.put("inity", "c");
+    m_l5.put("ional", "A");
+    m_l5.put("ioned", "A");
+    m_l5.put("ished", "A");
+    m_l5.put("istic", "A");
+    m_l5.put("ities", "A");
+    m_l5.put("itous", "A");
+    m_l5.put("ively", "A");
+    m_l5.put("ivity", "A");
+    m_l5.put("izers", "F");
+    m_l5.put("izing", "F");
+    m_l5.put("oidal", "A");
+    m_l5.put("oides", "A");
+    m_l5.put("otide", "A");
+    m_l5.put("ously", "A");
+    m_l4 = new HashMap();
+    m_l4.put("able", "A");
+    m_l4.put("ably", "A");
+    m_l4.put("ages", "B");
+    m_l4.put("ally", "B");
+    m_l4.put("ance", "B");
+    m_l4.put("ancy", "B");
+    m_l4.put("ants", "B");
+    m_l4.put("aric", "A");
+    m_l4.put("arly", "K");
+    m_l4.put("ated", "I");
+    m_l4.put("ates", "A");
+    m_l4.put("atic", "B");
+    m_l4.put("ator", "A");
+    m_l4.put("ealy", "Y");
+    m_l4.put("edly", "E");
+    m_l4.put("eful", "A");
+    m_l4.put("eity", "A");
+    m_l4.put("ence", "A");
+    m_l4.put("ency", "A");
+    m_l4.put("ened", "E");
+    m_l4.put("enly", "E");
+    m_l4.put("eous", "A");
+    m_l4.put("hood", "A");
+    m_l4.put("ials", "A");
+    m_l4.put("ians", "A");
+    m_l4.put("ible", "A");
+    m_l4.put("ibly", "A");
+    m_l4.put("ical", "A");
+    m_l4.put("ides", "L");
+    m_l4.put("iers", "A");
+    m_l4.put("iful", "A");
+    m_l4.put("ines", "M");
+    m_l4.put("ings", "N");
+    m_l4.put("ions", "B");
+    m_l4.put("ious", "A");
+    m_l4.put("isms", "B");
+    m_l4.put("ists", "A");
+    m_l4.put("itic", "H");
+    m_l4.put("ized", "F");
+    m_l4.put("izer", "F");
+    m_l4.put("less", "A");
+    m_l4.put("lily", "A");
+    m_l4.put("ness", "A");
+    m_l4.put("ogen", "A");
+    m_l4.put("ward", "A");
+    m_l4.put("wise", "A");
+    m_l4.put("ying", "B");
+    m_l4.put("yish", "A");
+    m_l3 = new HashMap();
+    m_l3.put("acy", "A");
+    m_l3.put("age", "B");
+    m_l3.put("aic", "A");
+    m_l3.put("als", "b");
+    m_l3.put("ant", "B");
+    m_l3.put("ars", "O");
+    m_l3.put("ary", "F");
+    m_l3.put("ata", "A");
+    m_l3.put("ate", "A");
+    m_l3.put("eal", "Y");
+    m_l3.put("ear", "Y");
+    m_l3.put("ely", "E");
+    m_l3.put("ene", "E");
+    m_l3.put("ent", "C");
+    m_l3.put("ery", "E");
+    m_l3.put("ese", "A");
+    m_l3.put("ful", "A");
+    m_l3.put("ial", "A");
+    m_l3.put("ian", "A");
+    m_l3.put("ics", "A");
+    m_l3.put("ide", "L");
+    m_l3.put("ied", "A");
+    m_l3.put("ier", "A");
+    m_l3.put("ies", "P");
+    m_l3.put("ily", "A");
+    m_l3.put("ine", "M");
+    m_l3.put("ing", "N");
+    m_l3.put("ion", "Q");
+    m_l3.put("ish", "C");
+    m_l3.put("ism", "B");
+    m_l3.put("ist", "A");
+    m_l3.put("ite", "a");
+    m_l3.put("ity", "A");
+    m_l3.put("ium", "A");
+    m_l3.put("ive", "A");
+    m_l3.put("ize", "F");
+    m_l3.put("oid", "A");
+    m_l3.put("one", "R");
+    m_l3.put("ous", "A");
+    m_l2 = new HashMap();
+    m_l2.put("ae", "A"); 
+    m_l2.put("al", "b");
+    m_l2.put("ar", "X");
+    m_l2.put("as", "B");
+    m_l2.put("ed", "E");
+    m_l2.put("en", "F");
+    m_l2.put("es", "E");
+    m_l2.put("ia", "A");
+    m_l2.put("ic", "A");
+    m_l2.put("is", "A");
+    m_l2.put("ly", "B");
+    m_l2.put("on", "S");
+    m_l2.put("or", "T");
+    m_l2.put("um", "U");
+    m_l2.put("us", "V");
+    m_l2.put("yl", "R");
+    m_l2.put("s\'", "A");
+    m_l2.put("\'s", "A");
+    m_l1 = new HashMap();
+    m_l1.put("a", "A");
+    m_l1.put("e", "A");
+    m_l1.put("i", "A");
+    m_l1.put("o", "A");
+    m_l1.put("s", "W");
+    m_l1.put("y", "B");	
+  }
+
+  /**
+   * Finds and removes ending from given word.
+   */
+  private String removeEnding(String word) {
+
+    int length = word.length();
+    int el = 11;
+
+    while (el > 0) {
+      if (length - el > 1) {
+	String ending = word.substring(length - el);
+	String conditionCode = null;
+	switch (el) {
+	case 11: conditionCode = (String)m_l11.get(ending);
+	  break;
+	case 10: conditionCode = (String)m_l10.get(ending);
+	  break; 
+	case 9: conditionCode = (String)m_l9.get(ending);
+	  break;
+	case 8: conditionCode = (String)m_l8.get(ending);
+	  break;   
+	case 7: conditionCode = (String)m_l7.get(ending);
+	  break;   
+	case 6: conditionCode = (String)m_l6.get(ending);
+	  break;   
+	case 5: conditionCode = (String)m_l5.get(ending);
+	  break;   
+	case 4: conditionCode = (String)m_l4.get(ending);
+	  break;   
+	case 3: conditionCode = (String)m_l3.get(ending);
+	  break;   
+	case 2: conditionCode = (String)m_l2.get(ending);
+	  break;   
+	case 1: conditionCode = (String)m_l1.get(ending);
+	  break;   
+	default:
+	}
+	if (conditionCode != null) {
+	  switch (conditionCode.charAt(0)) {
+	  case 'A':
+	    return word.substring(0, length - el);
+	  case 'B':
+	    if (length - el > 2) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'C':
+	    if (length - el > 3) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'D':
+	    if (length - el > 4) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'E':
+	    if (word.charAt(length - el - 1) != 'e') {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'F':
+	    if ((length - el > 2) &&
+		(word.charAt(length - el - 1) != 'e')) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'G':
+	    if ((length - el > 2) &&
+		(word.charAt(length - el - 1) == 'f')) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'H':
+	    if ((word.charAt(length - el - 1) == 't') ||
+		((word.charAt(length - el - 1) == 'l') &&
+		 (word.charAt(length - el - 2) == 'l'))) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'I':
+	    if ((word.charAt(length - el - 1) != 'o') &&
+		(word.charAt(length - el - 1) != 'e')) { 
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'J':
+	    if ((word.charAt(length - el - 1) != 'a') &&
+		(word.charAt(length - el - 1) != 'e')) { 
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'K':
+	    if ((length - el > 2) &&
+		((word.charAt(length - el - 1) == 'l') ||
+		 (word.charAt(length - el - 1) == 'i') ||
+		 ((word.charAt(length - el - 1) == 'e') &&
+		  (word.charAt(length - el - 3) == 'u')))) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'L':
+	    if ((word.charAt(length - el - 1) != 'u') &&
+		(word.charAt(length - el - 1) != 'x') &&
+		((word.charAt(length - el - 1) != 's') ||
+		 (word.charAt(length - el - 2) == 'o'))) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'M':
+	    if ((word.charAt(length - el - 1) != 'a') &&
+		(word.charAt(length - el - 1) != 'c') &&
+		(word.charAt(length - el - 1) != 'e') &&
+		(word.charAt(length - el - 1) != 'm')) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'N':
+	    if ((length - el > 3) || 
+		((length - el == 3) &&
+		 ((word.charAt(length - el - 3) != 's')))) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'O':
+	    if ((word.charAt(length - el - 1) == 'l') ||
+		(word.charAt(length - el - 1) == 'i')) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'P':
+	    if (word.charAt(length - el - 1) != 'c') {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'Q':
+	    if ((length - el > 2) &&
+		(word.charAt(length - el - 1) != 'l') &&
+		(word.charAt(length - el - 1) != 'n')) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'R':
+	    if ((word.charAt(length - el - 1) == 'n') ||
+		(word.charAt(length - el - 1) == 'r')) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'S':
+	    if (((word.charAt(length - el - 1) == 'r') &&
+		 (word.charAt(length - el - 2) == 'd')) ||
+		((word.charAt(length - el - 1) == 't') &&
+		 (word.charAt(length - el - 2) != 't'))) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'T':
+	    if ((word.charAt(length - el - 1) == 's') ||
+		((word.charAt(length - el - 1) == 't') &&
+		 (word.charAt(length - el - 2) != 'o'))) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'U':
+	    if ((word.charAt(length - el - 1) == 'l') ||
+		(word.charAt(length - el - 1) == 'm') ||
+		(word.charAt(length - el - 1) == 'n') ||
+		(word.charAt(length - el - 1) == 'r')) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'V':
+	    if (word.charAt(length - el - 1) == 'c') {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'W':
+	    if ((word.charAt(length - el - 1) != 's') &&
+		(word.charAt(length - el - 1) != 'u')) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'X':
+	    if ((word.charAt(length - el - 1) == 'l') ||
+		(word.charAt(length - el - 1) == 'i') ||
+		((length - el > 2) &&
+		 (word.charAt(length - el - 1) == 'e') &&
+		 (word.charAt(length - el - 3) == 'u'))) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'Y':
+	    if ((word.charAt(length - el - 1) == 'n') &&
+		(word.charAt(length - el - 2) == 'i')) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'Z':
+	    if (word.charAt(length - el - 1) != 'f') {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'a':
+	    if ((word.charAt(length - el - 1) == 'd') ||
+		(word.charAt(length - el - 1) == 'f') ||
+		(((word.charAt(length - el - 1) == 'h') &&
+		  (word.charAt(length - el - 2) == 'p'))) ||
+		(((word.charAt(length - el - 1) == 'h') &&
+		  (word.charAt(length - el - 2) == 't'))) ||
+		(word.charAt(length - el - 1) == 'l') ||
+		(((word.charAt(length - el - 1) == 'r') &&
+		  (word.charAt(length - el - 2) == 'e'))) ||
+		(((word.charAt(length - el - 1) == 'r') &&
+		  (word.charAt(length - el - 2) == 'o'))) ||
+		(((word.charAt(length - el - 1) == 's') &&
+		  (word.charAt(length - el - 2) == 'e'))) ||
+		(word.charAt(length - el - 1) == 't')) {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  case 'b':
+	    if (m_CompMode) {
+	      if (((length - el == 3 ) &&
+		   (!((word.charAt(length - el - 1) == 't') &&
+		      (word.charAt(length - el - 2) == 'e') &&
+		      (word.charAt(length - el - 3) == 'm')))) ||
+		  ((length - el > 3) &&
+		   (!((word.charAt(length - el - 1) == 't') &&
+		      (word.charAt(length - el - 2) == 's') &&
+		      (word.charAt(length - el - 3) == 'y') &&
+		      (word.charAt(length - el - 4) == 'r'))))) {
+		return word.substring(0, length - el);
+	      }
+	    } else {
+	      if ((length - el > 2) &&
+		  (!((word.charAt(length - el - 1) == 't') &&
+		     (word.charAt(length - el - 2) == 'e') &&
+		     (word.charAt(length - el - 3) == 'm'))) &&
+		  ((length - el < 4) ||
+		   (!((word.charAt(length - el - 1) == 't') &&
+		      (word.charAt(length - el - 2) == 's') &&
+		      (word.charAt(length - el - 3) == 'y') &&
+		      (word.charAt(length - el - 4) == 'r'))))) {
+		return word.substring(0, length - el);
+	      }
+	    } 
+	    break;
+	  case 'c':
+	    if (word.charAt(length - el - 1) == 'l') {
+	      return word.substring(0, length - el);
+	    }
+	    break;
+	  default:
+	    throw new IllegalArgumentException("Fatal error.");
+	  }
+	}
+      }
+      el--;
+    }
+    return word;
+  }
+
+  /**
+   * Recodes ending of given word.
+   */
+  private String recodeEnding(String word) {
+
+    int lastPos = word.length() - 1;
+
+    // Rule 1
+    if (word.endsWith("bb") ||
+	word.endsWith("dd") ||
+	word.endsWith("gg") ||
+	word.endsWith("ll") ||
+	word.endsWith("mm") ||
+	word.endsWith("nn") ||
+	word.endsWith("pp") ||
+	word.endsWith("rr") ||
+	word.endsWith("ss") ||
+	word.endsWith("tt")) {
+      word = word.substring(0, lastPos);
+      lastPos--;
+    }
+
+    // Rule 2
+    if (word.endsWith("iev")) {
+      word = word.substring(0, lastPos - 2).concat("ief");
+    }
+
+    // Rule 3
+    if (word.endsWith("uct")) {
+      word = word.substring(0, lastPos - 2).concat("uc");
+      lastPos--;
+    }
+
+    // Rule 4
+    if (word.endsWith("umpt")) {
+      word = word.substring(0, lastPos - 3).concat("um");
+      lastPos -= 2;
+    }
+
+    // Rule 5
+    if (word.endsWith("rpt")) {
+      word = word.substring(0, lastPos - 2).concat("rb");
+      lastPos--;
+    }
+
+    // Rule 6
+    if (word.endsWith("urs")) {
+      word = word.substring(0, lastPos - 2).concat("ur");
+      lastPos--;
+    }
+
+    // Rule 7
+    if (word.endsWith("istr")) {
+      word = word.substring(0, lastPos - 3).concat("ister");
+      lastPos++;
+    }
+ 
+    // Rule 7a
+    if (word.endsWith("metr")) {
+      word = word.substring(0, lastPos - 3).concat("meter");
+      lastPos++;
+    }
+
+    // Rule 8
+    if (word.endsWith("olv")) {
+      word = word.substring(0, lastPos - 2).concat("olut");
+      lastPos++;
+    }
+ 
+    // Rule 9
+    if (word.endsWith("ul")) {
+      if ((lastPos - 2 < 0) ||
+	  ((word.charAt(lastPos - 2) != 'a') &&
+	   (word.charAt(lastPos - 2) != 'i') &&
+	   (word.charAt(lastPos - 2) != 'o'))) {
+	word = word.substring(0, lastPos - 1).concat("l");
+	lastPos--;
+      }
+    }
+
+    // Rule 10
+    if (word.endsWith("bex")) {
+      word = word.substring(0, lastPos - 2).concat("bic");
+    }
+
+    // Rule 11
+    if (word.endsWith("dex")) {
+      word = word.substring(0, lastPos - 2).concat("dic");
+    }
+
+    // Rule 12
+    if (word.endsWith("pex")) {
+      word = word.substring(0, lastPos - 2).concat("pic");
+    }
+
+    // Rule 13
+    if (word.endsWith("tex")) {
+      word = word.substring(0, lastPos - 2).concat("tic");
+    }
+
+    // Rule 14
+    if (word.endsWith("ax")) {
+      word = word.substring(0, lastPos - 1).concat("ac");
+    }
+
+    // Rule 15
+    if (word.endsWith("ex")) {
+      word = word.substring(0, lastPos - 1).concat("ec");
+    }
+
+    // Rule 16
+    if (word.endsWith("ix")) {
+      word = word.substring(0, lastPos - 1).concat("ic");
+    }
+
+    // Rule 17
+    if (word.endsWith("lux")) {
+      word = word.substring(0, lastPos - 2).concat("luc");
+    }
+
+    // Rule 18
+    if (word.endsWith("uad")) {
+      word = word.substring(0, lastPos - 2).concat("uas");
+    }
+
+    // Rule 19
+    if (word.endsWith("vad")) {
+      word = word.substring(0, lastPos - 2).concat("vas");
+    }
+
+    // Rule 20
+    if (word.endsWith("cid")) {
+      word = word.substring(0, lastPos - 2).concat("cis");
+    }
+
+    // Rule 21
+    if (word.endsWith("lid")) {
+      word = word.substring(0, lastPos - 2).concat("lis");
+    }
+
+    // Rule 22
+    if (word.endsWith("erid")) {
+      word = word.substring(0, lastPos - 3).concat("eris");
+    }
+
+    // Rule 23
+    if (word.endsWith("pand")) {
+      word = word.substring(0, lastPos - 3).concat("pans");
+    }
+ 
+    // Rule 24
+    if (word.endsWith("end")) {
+      if ((lastPos - 3 < 0) ||
+	   (word.charAt(lastPos - 3) != 's')) {
+	word = word.substring(0, lastPos - 2).concat("ens");
+      }
+    }
+
+    // Rule 25
+    if (word.endsWith("ond")) {
+      word = word.substring(0, lastPos - 2).concat("ons");
+    }
+
+    // Rule 26
+    if (word.endsWith("lud")) {
+      word = word.substring(0, lastPos - 2).concat("lus");
+    }
+
+    // Rule 27
+    if (word.endsWith("rud")) {
+      word = word.substring(0, lastPos - 2).concat("rus");
+    }
+
+    // Rule 28
+    if (word.endsWith("her")) {
+      if ((lastPos - 3 < 0) ||
+	  ((word.charAt(lastPos - 3) != 'p') &&
+	   (word.charAt(lastPos - 3) != 't'))) {
+	word = word.substring(0, lastPos - 2).concat("hes");
+      }
+    }
+
+    // Rule 29
+    if (word.endsWith("mit")) {
+      word = word.substring(0, lastPos - 2).concat("mis");
+    }
+
+    // Rule 30
+    if (word.endsWith("end")) {
+      if ((lastPos - 3 < 0) ||
+	  (word.charAt(lastPos - 3) != 'm')) {
+	word = word.substring(0, lastPos - 2).concat("ens");
+      }
+    }
+
+    // Rule 31
+    if (word.endsWith("ert")) {
+      word = word.substring(0, lastPos - 2).concat("ers");
+    }
+
+    // Rule 32
+    if (word.endsWith("et")) {
+      if ((lastPos - 2 < 0) ||
+	  (word.charAt(lastPos - 2) != 'n')) {
+	word = word.substring(0, lastPos - 1).concat("es");
+      }
+    }
+
+    // Rule 33
+    if (word.endsWith("yt")) {
+      word = word.substring(0, lastPos - 1).concat("ys");
+    }
+
+    // Rule 34
+    if (word.endsWith("yz")) {
+      word = word.substring(0, lastPos - 1).concat("ys");
+    }
+
+    return word;
+  }
+
+  /**
+   * Returns the stemmed version of the given word.
+   * 
+   * @param word a string consisting of a single word
+   */
+  public String stem(String word) {
+
+    if (word.length() > 2) {
+      return recodeEnding(removeEnding(word.toLowerCase()));
+    } else {
+      return word.toLowerCase();
+    }
+  }
+
+  /**
+   * Stems text coming into stdin and writes it to stdout.
+   */
+  public static void main(String[] ops) {
+
+    LovinsStemmer ls = new LovinsStemmer();
+
+    try {
+      int num;
+      StringBuffer wordBuffer = new StringBuffer();
+      while ((num = System.in.read()) != -1) {
+	char c = (char)num;
+	if (((num >= (int)'A') && (num <= (int)'Z')) ||
+	    ((num >= (int)'a') && (num <= (int)'z'))) {
+	  wordBuffer.append(c);
+	} else {
+	  if (wordBuffer.length() > 0) {
+	    System.out.print(ls.stem(wordBuffer.toString().
+				     toLowerCase()));
+	    wordBuffer = new StringBuffer();
+	  }
+	  System.out.print(c);
+	}
+      }
+    } catch (Exception e) {
+      System.err.println(e.getMessage());
+    }
+  }
+}
+    
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/NumbersFilter.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/NumbersFilter.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/NumbersFilter.java	(revision 20131)
@@ -0,0 +1,182 @@
+/*
+ *    NumbersFilter.java
+ *    Copyright (C) 2000 Eibe Frank
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import weka.core.*;
+import weka.filters.*;
+
+import java.util.*;
+
+/**
+ * Removes all numbers from all the string attributes in the given
+ * dataset. Assumes that words are separated by whitespace.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version 1.0
+ */
+public class NumbersFilter extends Filter {
+
+  /**
+   * Returns a string describing this filter
+   *
+   * @return a description of the filter suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String globalInfo() {
+      return "Removes all numbers from all the string attributes in " +
+      "the given dataset. Assumes that words are separated by whitespace.";
+  }
+
+  /**
+   * Signify that this batch of input to the filter is finished. If
+   * the filter requires all instances prior to filtering, output()
+   * may now be called to retrieve the filtered instances. Any
+   * subsequent instances filtered should be filtered based on setting
+   * obtained from the first batch (unless the inputFormat has been
+   * re-assigned or new options have been set). This default
+   * implementation assumes all instance processing occurs during
+   * inputFormat() and input().
+   *
+   * @return true if there are instances pending output
+   * @exception NullPointerException if no input structure has been defined,
+   * @exception Exception if there was a problem finishing the batch.
+   */
+  public boolean batchFinished() throws Exception {
+
+    if (getInputFormat() == null) {
+      throw new NullPointerException("No input instance format defined");
+    }
+    m_NewBatch = true;
+    return (numPendingOutput() != 0);
+  }
+
+  /**
+   * Sets the format of the input instances.
+   *
+   * @param instanceInfo an Instances object containing the input
+   * instance structure (any instances contained in the object are
+   * ignored - only the structure is required).
+   * @return true if the outputFormat may be collected immediately 
+   */
+  public boolean setInputFormat(Instances instanceInfo) throws Exception {
+
+    super.setInputFormat(instanceInfo);
+    setOutputFormat(instanceInfo);
+    return true;
+  }
+
+  /**
+   * Input an instance for filtering. Ordinarily the instance is processed
+   * and made available for output immediately. Some filters require all
+   * instances be read before producing output.
+   *
+   * @param instance the input instance
+   * @return true if the filtered instance may now be
+   * collected with output().
+   * @exception Exception if the input instance was not of the correct 
+   * format or if there was a problem with the filtering.
+   */
+  public boolean input(Instance instance) throws Exception {
+
+    if (getInputFormat() == null) {
+      throw new Exception("No input instance format defined");
+    }
+    if (m_NewBatch) {
+      resetQueue();
+      m_NewBatch = false;
+    }
+    convertInstance(instance);
+    return true;
+  }
+
+  /**
+   * Main method for testing this class.
+   *
+   * @param argv should contain arguments to the filter: use -h for help
+   */
+  public static void main(String [] argv) {
+    
+    try {
+      if (Utils.getFlag('b', argv)) {
+	Filter.batchFilterFile(new NumbersFilter(), argv);
+      } else {
+	Filter.filterFile(new NumbersFilter(), argv);
+      }
+    } catch (Exception ex) {
+      System.out.println(ex.getMessage());
+    }
+  }
+ 
+  /** 
+   * Converts an instance. A phrase boundary is inserted where
+   * a number is found.
+   */
+  private void convertInstance(Instance instance) throws Exception {
+  
+    double[] instVals = new double[instance.numAttributes()];
+
+    for (int i = 0; i < instance.numAttributes(); i++) {
+      if ((!instance.attribute(i).isString()) || instance.isMissing(i)) {
+	instVals[i] = instance.value(i);
+      } else {
+	String str = instance.stringValue(i);
+	StringBuffer resultStr = new StringBuffer();
+	StringTokenizer tok = new StringTokenizer(str, " \t\n", true);
+	while (tok.hasMoreTokens()) {
+	  String token = tok.nextToken();
+
+	  // Everything that doesn't contain at least
+	  // one letter is considered to be a number
+	  boolean isNumber = true;
+	  for (int j = 0; j < token.length(); j++) {
+	    if (Character.isLetter(token.charAt(j))) {
+	      isNumber = false;
+	      break;
+	    }
+	  }
+	  if (!isNumber) {
+	    resultStr.append(token);
+	  } else {
+	    if (token.equals(" ") || token.equals("\t") ||
+		token.equals("\n")) {
+	      resultStr.append(token);
+	    } else {
+	      resultStr.append(" \n ");
+	    }
+	  }
+	}
+	int index = getOutputFormat().attribute(i).addStringValue(resultStr.toString());
+	instVals[i] = (double)index;
+      }
+    }
+    Instance inst = new Instance(instance.weight(), instVals);
+    inst.setDataset(getOutputFormat());
+    push(inst);
+  }
+}
+
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/README
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/README	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/README	(revision 20131)
@@ -0,0 +1,284 @@
+=====================================================================
+                                                                       
+                              ======                                   
+                              README                                   
+                              ======                                   
+                                                                       
+                             KEA 3.0
+                          18 March 2004
+                                                                       
+           Java Programs for Automatic Keyphrase Extraction
+                                                                       
+               Copyright (C) 2000, 2001, 2004  Eibe Frank
+
+                   email: eibe@cs.waikato.ac.nz            
+                                                                       
+=====================================================================
+
+Contents:
+---------
+
+1. Installation
+
+2. Getting started
+
+   - Building a keyphrase extraction model
+   - Extracting keyphrases
+   - Important comment
+
+3. Examples
+
+4. Other documentation
+
+5. Copyright
+
+----------------------------------------------------------------------
+
+NOTE:
+-----
+
+This distribution includes a cut-down version of WEKA, the GPL'ed
+machine learning workbench available from 
+
+  http://www.cs.waikato.ac.nz/ml/weka.
+
+----------------------------------------------------------------------
+
+1. Installation:
+----------------
+
+KEA is implemented as a set of Java classes (located in the same
+directory as this README file). To run KEA you need to tell the Java
+Virtual Machine where to look for KEA classes.  One possible way of
+doing this is to add the directory that contains this README file to
+the CLASSPATH environment variable that is used by the Java Virtual
+Machine.
+
+Under Linux you would do the following:
+
+a) Set KEAHOME to be the directory which contains this README.
+
+b) Add $KEAHOME to your CLASSPATH environment variable.
+
+The on-line documentation (generated from the source code) is located
+in the doc directory. You might want to do the following to have the
+documentation handy in you web browser:
+
+c) Bookmark $KEAHOME/doc/packages.html in your web browser.
+
+----------------------------------------------------------------------
+
+2. Getting started:
+-------------------
+
+Building a keyphrase extraction model
+=====================================
+
+To extract keyphrases for new documents, you first need to build a KEA
+keyphrase extraction model from a set of documents (preferably from
+the same domain) for which you have author- assigned keyphrases. To
+this end you have to go through the following steps:
+
+a) Create a directory, called, for example, "training_documents",
+   containing the documents that you want to use for training the
+   keyphrase extractor.
+
+b) Rename the document files in that directory so that they end with
+   the suffix ".txt".
+
+c) Delete the author-assigned keyphrases from those documents
+   and put them into separate ".key" files. For example, if
+   your document file is called doc1.txt, move the keyphrases
+   into a new file called "doc1.key". It is important that
+   you put each keyphrase on a separate line in the .key file!
+
+d) Build the keyphrase extraction model by running the
+   KEAModelBuilder:
+
+   java KEAModelBuilder -l <name_of_directory> -m <name_of_model>
+
+   This will use the documents in <name_of_directory> to build a
+   keyphrase extraction model and save it in <name_of_model>.
+
+KEAModelBuilder has a few other options that you can view if you run
+KEAModelBuilder without any arguments. Here is a list of all the
+options:
+
+-l <directory name>
+	Specifies name of directory.
+-m <model name>
+	Specifies name of model.
+-e <encoding>
+	Specifies encoding.
+-d
+	Turns debugging mode on.
+-k
+	Use keyphrase frequency statistic.
+-p
+	Disallow internal periods.
+-x <length>
+	Sets the maximum phrase length (default: 3).
+-y <length>
+	Sets the minimum phrase length (default: 1).
+-o <number>
+	The minimum number of times a phrase needs to occur 
+	(default: 2).
+-s <name of stopwords class>
+        Sets the list of stopwords to use (default: StopwordsEnglish).
+-t <name of stemmer class>
+        Set the stemmer to use (default: IteratedLovinsStemmer).
+-n
+        Do not check for proper nouns.
+   
+The -e option allows you to specify a different character encoding
+supported by Java. For example, to extract keyphrases from Chinese
+documents encoded using GBK, you would use specify "-e GBK" as an
+argument.
+
+The -d option generates some output that shows the progress of the
+model builder.
+
+If -k is set, the keyphrase frequency attribute is used in the
+model. For more info on this, have a look at the paper on
+"Domain-specific keyphrase extraction" listed below. Using this option
+improves accuracy if the domain of the documents for which you want to
+extract keyphrases is the same as the domain of the training
+documents. In other words, if you want to extract keyphrases from
+papers on radiology, and your training documents are about radiology,
+you should use this option.
+
+If -p is set, KEA does not consider phrases with internal periods as
+candidate keyphrases. It is important to use this if a full stop is
+not always followed by white space in the documents.
+
+Using -s and -t you can set different classes for stopword detection
+and stemming respectively (for languages other than English).
+
+Using -d you turn KEA's heuristic for detecting proper nouns off. This
+is important for languages like German, where all nouns start with an
+uppercase letter, not just proper nouns.
+
+Extracting keyphrases
+=====================
+
+To extract keyphrases for some documents, put them into an empty
+directory. Then rename them so that they end with the suffix ".txt".
+
+If you've previously built a keyphrase extraction model you can now
+apply keyphrases for these documents using:
+
+java KEAKeyphraseExtractor -l <name_of_directory> -m <name_of_model>
+
+This will create a ".key" file for each document in the
+directory. Each file will contain five extracted keyphrases for the
+corresponding document.
+
+If a ".key" file is already present it won't be overwritten.  Instead,
+the keyphrases present in that file will be used to evaluate the
+extraction model. The stemmed extracted phrases are compared to the
+stemmed versions of the phrases in the ".key"
+file. KEAKeyphraseExtractor reports the number of hits among the total
+number of extracted phrases for those documents that have associated
+".key" files in the directory.
+
+KEAKeyphraseExtractor has a few options. Here they are:
+
+-l <directory name>
+	Specifies name of directory.
+-m <model name>
+	Specifies name of model.
+-e <encoding>
+	Specifies encoding.
+-n
+	Specifies number of phrases to be output (default: 5).
+-d
+	Turns debugging mode on.
+-a
+	Also write stemmed phrase and score into ".key" file.
+
+Important comment
+-----------------
+
+To get good results, it is important that the input text for KEA is as
+"clean" as possible. That means html tags etc. in the input documents
+need to be deleted before the model is built and before keyphrases are
+extracted from new documents.
+
+----------------------------------------------------------------------
+
+3. Examples:
+------------
+
+The directory contains two example collections, each split up into a
+train and test directory. Note that these collections are only
+included to show how the system can be applied to actual documents.
+Due to the lack of data, the accuracy isn't very good on either
+example collection.
+
+Collection A
+------------
+
+A collection of abstracts taken from computer science technical
+reports:
+
+   CSTR_abstracts_train
+   CSTR_abstracts_test
+
+To build a model from the training data, try:
+
+   java KEAModelBuilder -l CSTR_abstracts_train -m CSTR_abstracts_model
+
+To evaluate that model on the test data, try:
+
+   java KEAKeyphraseExtractor -l CSTR_abstracts_test -m CSTR_abstracts_model
+
+Collection B
+------------
+
+A small collection of Chinese documents (in GBK encoding):
+
+   Journals_train
+   Journals_test
+
+To build a model from the training data, try:
+
+   java KEAModelBuilder -l Chinese_train -m Chinese_model -e GBK
+
+To evaluate that model on the test data, try:
+
+   java KEAKeyphraseExtractor -l Chinese_test -m Chinese_model -e GBK 
+
+----------------------------------------------------------------------
+
+4. Other documentation:
+-----------------------
+
+There are several papers on the KEA algorithm, listed below. Note that
+this implementation differs slightly from the version described in the
+papers, mainly in the pre-processing step (i.e. in the way candidate
+keyphrases are generated). For more info on the new method please
+consult the online documentation.
+
+Witten I.H., Paynter G.W., Frank E., Gutwin C. and Nevill-Manning
+C.G. (2000) "KEA: Practical automatic keyphrase extraction." Working
+Paper 00/5, Department of Computer Science, The University of Waikato.
+
+Witten I.H., Paynter G.W., Frank E., Gutwin C. and Nevill-Manning
+C.G. (1999) "KEA: Practical automatic keyphrase extraction." Proc. DL
+'99, pp. 254-256. (Poster presentation.)
+
+Frank E., Paynter G.W., Witten I.H., Gutwin C. and Nevill-Manning
+C.G. (1999) "Domain-specific keyphrase extraction" Proc. Sixteenth
+International Joint Conference on Artificial Intelligence, Morgan
+Kaufmann Publishers, San Francisco, CA, pp. 668-673.
+
+-----------------------------------------------------------------------
+
+5. Copyright:
+-------------
+
+KEA is distributed under the GNU public license. Please read the file
+COPYING.
+
+-----------------------------------------------------------------------
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/Stemmer.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/Stemmer.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/Stemmer.java	(revision 20131)
@@ -0,0 +1,68 @@
+/*
+ *    Stemmer.java
+ *    Copyright (C) 2001 Eibe Frank
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * Abstract class for stemmers.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version 1.0
+ */
+public abstract class Stemmer implements Serializable {
+
+  /**
+   * Iterated stemming of the given word.
+   */
+  public abstract String stem(String str);
+
+  /**
+   * Stems everything in the given string.
+   */
+  public String stemString(String str) {
+
+    StringBuffer result = new StringBuffer();
+    int start = -1;
+    for (int j = 0; j < str.length(); j++) {
+      char c = str.charAt(j);
+      if (Character.isLetterOrDigit(c)) {
+	if (start == -1) {
+	  start = j;
+	}
+      } else if (c == '\'') {
+	if (start == -1) {
+	  result.append(c);
+	}
+      } else {
+	if (start != -1) {
+	  result.append(stem(str.substring(start, j)));
+	  start = -1;
+	}
+	result.append(c);
+      }
+    }
+    if (start != -1) {
+      result.append(stem(str.substring(start, str.length())));
+    }
+    return result.toString();  
+  }
+}
+    
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/Stopwords.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/Stopwords.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/Stopwords.java	(revision 20131)
@@ -0,0 +1,38 @@
+/*
+ *    Stopwords.java
+ *    Copyright (C) 2001 Eibe Frank
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * Class that can test whether a given string is a stop word.
+ * Lowercases all words before the test.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version 1.0
+ */
+public abstract class Stopwords implements Serializable {
+  
+  /** 
+   * Returns true if the given string is a stop word.
+   */
+  public abstract boolean isStopword(String str);
+}
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/StopwordsEnglish.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/StopwordsEnglish.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/StopwordsEnglish.java	(revision 20131)
@@ -0,0 +1,504 @@
+/*
+ *    StopwordsEnglish.java
+ *    Copyright (C) 2001 Eibe Frank
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.util.*;
+
+/**
+ * Class that can test whether a given string is a stop word.
+ * Lowercases all words before the test.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version 1.0
+ */
+public class StopwordsEnglish extends Stopwords {
+  
+  /** The hashtable containing the list of stopwords */
+  private static Hashtable m_Stopwords = null;
+
+  static {
+   
+    if (m_Stopwords == null) {
+      m_Stopwords = new Hashtable();
+      Double dummy = new Double(0);
+      
+      m_Stopwords.put("a", dummy);
+      m_Stopwords.put("abaft", dummy);
+      m_Stopwords.put("aboard", dummy);
+      m_Stopwords.put("about", dummy);
+      m_Stopwords.put("above", dummy);
+      m_Stopwords.put("across", dummy);
+      m_Stopwords.put("afore", dummy);
+      m_Stopwords.put("aforesaid", dummy);
+      m_Stopwords.put("after", dummy);
+      m_Stopwords.put("again", dummy);
+      m_Stopwords.put("against", dummy);
+      m_Stopwords.put("agin", dummy);
+      m_Stopwords.put("ago", dummy);
+      m_Stopwords.put("aint", dummy);
+      m_Stopwords.put("albeit", dummy);
+      m_Stopwords.put("all", dummy);
+      m_Stopwords.put("almost", dummy);
+      m_Stopwords.put("alone", dummy);
+      m_Stopwords.put("along", dummy);
+      m_Stopwords.put("alongside", dummy);
+      m_Stopwords.put("already", dummy);
+      m_Stopwords.put("also", dummy);
+      m_Stopwords.put("although", dummy);
+      m_Stopwords.put("always", dummy);
+      m_Stopwords.put("am", dummy);
+      m_Stopwords.put("american", dummy);
+      m_Stopwords.put("amid", dummy);
+      m_Stopwords.put("amidst", dummy);
+      m_Stopwords.put("among", dummy);
+      m_Stopwords.put("amongst", dummy);
+      m_Stopwords.put("an", dummy);
+      m_Stopwords.put("and", dummy);
+      m_Stopwords.put("anent", dummy);
+      m_Stopwords.put("another", dummy);
+      m_Stopwords.put("any", dummy);
+      m_Stopwords.put("anybody", dummy);
+      m_Stopwords.put("anyone", dummy);
+      m_Stopwords.put("anything", dummy);
+      m_Stopwords.put("are", dummy);
+      m_Stopwords.put("aren't", dummy);
+      m_Stopwords.put("around", dummy);
+      m_Stopwords.put("as", dummy);
+      m_Stopwords.put("aslant", dummy);
+      m_Stopwords.put("astride", dummy);
+      m_Stopwords.put("at", dummy);
+      m_Stopwords.put("athwart", dummy);
+      m_Stopwords.put("away", dummy);
+      m_Stopwords.put("b", dummy);
+      m_Stopwords.put("back", dummy);
+      m_Stopwords.put("bar", dummy);
+      m_Stopwords.put("barring", dummy);
+      m_Stopwords.put("be", dummy);
+      m_Stopwords.put("because", dummy);
+      m_Stopwords.put("been", dummy);
+      m_Stopwords.put("before", dummy);
+      m_Stopwords.put("behind", dummy);
+      m_Stopwords.put("being", dummy);
+      m_Stopwords.put("below", dummy);
+      m_Stopwords.put("beneath", dummy);
+      m_Stopwords.put("beside", dummy);
+      m_Stopwords.put("besides", dummy);
+      m_Stopwords.put("best", dummy);
+      m_Stopwords.put("better", dummy);
+      m_Stopwords.put("between", dummy);
+      m_Stopwords.put("betwixt", dummy);
+      m_Stopwords.put("beyond", dummy);
+      m_Stopwords.put("both", dummy);
+      m_Stopwords.put("but", dummy);
+      m_Stopwords.put("by", dummy);
+      m_Stopwords.put("c", dummy);
+      m_Stopwords.put("can", dummy);
+      m_Stopwords.put("cannot", dummy);
+      m_Stopwords.put("can't", dummy);
+      m_Stopwords.put("certain", dummy);
+      m_Stopwords.put("circa", dummy);
+      m_Stopwords.put("close", dummy);
+      m_Stopwords.put("concerning", dummy);
+      m_Stopwords.put("considering", dummy);
+      m_Stopwords.put("cos", dummy);
+      m_Stopwords.put("could", dummy);
+      m_Stopwords.put("couldn't", dummy);
+      m_Stopwords.put("couldst", dummy);
+      m_Stopwords.put("d", dummy);
+      m_Stopwords.put("dare", dummy);
+      m_Stopwords.put("dared", dummy);
+      m_Stopwords.put("daren't", dummy);
+      m_Stopwords.put("dares", dummy);
+      m_Stopwords.put("daring", dummy);
+      m_Stopwords.put("despite", dummy);
+      m_Stopwords.put("did", dummy);
+      m_Stopwords.put("didn't", dummy);
+      m_Stopwords.put("different", dummy);
+      m_Stopwords.put("directly", dummy);
+      m_Stopwords.put("do", dummy);
+      m_Stopwords.put("does", dummy);
+      m_Stopwords.put("doesn't", dummy);
+      m_Stopwords.put("doing", dummy);
+      m_Stopwords.put("done", dummy);
+      m_Stopwords.put("don't", dummy);
+      m_Stopwords.put("dost", dummy);
+      m_Stopwords.put("doth", dummy);
+      m_Stopwords.put("down", dummy);
+      m_Stopwords.put("during", dummy);
+      m_Stopwords.put("durst", dummy);
+      m_Stopwords.put("e", dummy);
+      m_Stopwords.put("each", dummy);
+      m_Stopwords.put("early", dummy);
+      m_Stopwords.put("either", dummy);
+      m_Stopwords.put("em", dummy);
+      m_Stopwords.put("english", dummy);
+      m_Stopwords.put("enough", dummy);
+      m_Stopwords.put("ere", dummy);
+      m_Stopwords.put("even", dummy);
+      m_Stopwords.put("ever", dummy);
+      m_Stopwords.put("every", dummy);
+      m_Stopwords.put("everybody", dummy);
+      m_Stopwords.put("everyone", dummy);
+      m_Stopwords.put("everything", dummy);
+      m_Stopwords.put("except", dummy);
+      m_Stopwords.put("excepting", dummy);
+      m_Stopwords.put("f", dummy);
+      m_Stopwords.put("failing", dummy);
+      m_Stopwords.put("far", dummy);
+      m_Stopwords.put("few", dummy);
+      m_Stopwords.put("first", dummy);
+      m_Stopwords.put("five", dummy);
+      m_Stopwords.put("following", dummy);
+      m_Stopwords.put("for", dummy);
+      m_Stopwords.put("four", dummy);
+      m_Stopwords.put("from", dummy);
+      m_Stopwords.put("g", dummy);
+      m_Stopwords.put("gonna", dummy);
+      m_Stopwords.put("gotta", dummy);
+      m_Stopwords.put("h", dummy);
+      m_Stopwords.put("had", dummy);
+      m_Stopwords.put("hadn't", dummy);
+      m_Stopwords.put("hard", dummy);
+      m_Stopwords.put("has", dummy);
+      m_Stopwords.put("hasn't", dummy);
+      m_Stopwords.put("hast", dummy);
+      m_Stopwords.put("hath", dummy);
+      m_Stopwords.put("have", dummy);
+      m_Stopwords.put("haven't", dummy);
+      m_Stopwords.put("having", dummy);
+      m_Stopwords.put("he", dummy);
+      m_Stopwords.put("he'd", dummy);
+      m_Stopwords.put("he'll", dummy);
+      m_Stopwords.put("her", dummy);
+      m_Stopwords.put("here", dummy);
+      m_Stopwords.put("here's", dummy);
+      m_Stopwords.put("hers", dummy);
+      m_Stopwords.put("herself", dummy);
+      m_Stopwords.put("he's", dummy);
+      m_Stopwords.put("high", dummy);
+      m_Stopwords.put("him", dummy);
+      m_Stopwords.put("himself", dummy);
+      m_Stopwords.put("his", dummy);
+      m_Stopwords.put("home", dummy);
+      m_Stopwords.put("how", dummy);
+      m_Stopwords.put("howbeit", dummy);
+      m_Stopwords.put("however", dummy);
+      m_Stopwords.put("how's", dummy);
+      m_Stopwords.put("i", dummy);
+      m_Stopwords.put("id", dummy);
+      m_Stopwords.put("if", dummy);
+      m_Stopwords.put("ill", dummy);
+      m_Stopwords.put("i'm", dummy);
+      m_Stopwords.put("immediately", dummy);
+      m_Stopwords.put("important", dummy);
+      m_Stopwords.put("in", dummy);
+      m_Stopwords.put("inside", dummy);
+      m_Stopwords.put("instantly", dummy);
+      m_Stopwords.put("into", dummy);
+      m_Stopwords.put("is", dummy);
+      m_Stopwords.put("isn't", dummy);
+      m_Stopwords.put("it", dummy);
+      m_Stopwords.put("it'll", dummy);
+      m_Stopwords.put("it's", dummy);
+      m_Stopwords.put("its", dummy);
+      m_Stopwords.put("itself", dummy);
+      m_Stopwords.put("i've", dummy);
+      m_Stopwords.put("j", dummy);
+      m_Stopwords.put("just", dummy);
+      m_Stopwords.put("k", dummy);
+      m_Stopwords.put("l", dummy);
+      m_Stopwords.put("large", dummy);
+      m_Stopwords.put("last", dummy);
+      m_Stopwords.put("later", dummy);
+      m_Stopwords.put("least", dummy);
+      m_Stopwords.put("left", dummy);
+      m_Stopwords.put("less", dummy);
+      m_Stopwords.put("lest", dummy);
+      m_Stopwords.put("let's", dummy);
+      m_Stopwords.put("like", dummy);
+      m_Stopwords.put("likewise", dummy);
+      m_Stopwords.put("little", dummy);
+      m_Stopwords.put("living", dummy);
+      m_Stopwords.put("long", dummy);
+      m_Stopwords.put("m", dummy);
+      m_Stopwords.put("many", dummy);
+      m_Stopwords.put("may", dummy);
+      m_Stopwords.put("mayn't", dummy);
+      m_Stopwords.put("me", dummy);
+      m_Stopwords.put("mid", dummy);
+      m_Stopwords.put("midst", dummy);
+      m_Stopwords.put("might", dummy);
+      m_Stopwords.put("mightn't", dummy);
+      m_Stopwords.put("mine", dummy);
+      m_Stopwords.put("minus", dummy);
+      m_Stopwords.put("more", dummy);
+      m_Stopwords.put("most", dummy);
+      m_Stopwords.put("much", dummy);
+      m_Stopwords.put("must", dummy);
+      m_Stopwords.put("mustn't", dummy);
+      m_Stopwords.put("my", dummy);
+      m_Stopwords.put("myself", dummy);
+      m_Stopwords.put("n", dummy);
+      m_Stopwords.put("near", dummy);
+      m_Stopwords.put("'neath", dummy);
+      m_Stopwords.put("need", dummy);
+      m_Stopwords.put("needed", dummy);
+      m_Stopwords.put("needing", dummy);
+      m_Stopwords.put("needn't", dummy);
+      m_Stopwords.put("needs", dummy);
+      m_Stopwords.put("neither", dummy);
+      m_Stopwords.put("never", dummy);
+      m_Stopwords.put("nevertheless", dummy);
+      m_Stopwords.put("new", dummy);
+      m_Stopwords.put("next", dummy);
+      m_Stopwords.put("nigh", dummy);
+      m_Stopwords.put("nigher", dummy);
+      m_Stopwords.put("nighest", dummy);
+      m_Stopwords.put("nisi", dummy);
+      m_Stopwords.put("no", dummy);
+      m_Stopwords.put("no-one", dummy);
+      m_Stopwords.put("nobody", dummy);
+      m_Stopwords.put("none", dummy);
+      m_Stopwords.put("nor", dummy);
+      m_Stopwords.put("not", dummy);
+      m_Stopwords.put("nothing", dummy);
+      m_Stopwords.put("notwithstanding", dummy);
+      m_Stopwords.put("now", dummy);
+      m_Stopwords.put("o", dummy);
+      m_Stopwords.put("o'er", dummy);
+      m_Stopwords.put("of", dummy);
+      m_Stopwords.put("off", dummy);
+      m_Stopwords.put("often", dummy);
+      m_Stopwords.put("on", dummy);
+      m_Stopwords.put("once", dummy);
+      m_Stopwords.put("one", dummy);
+      m_Stopwords.put("oneself", dummy);
+      m_Stopwords.put("only", dummy);
+      m_Stopwords.put("onto", dummy);
+      m_Stopwords.put("open", dummy);
+      m_Stopwords.put("or", dummy);
+      m_Stopwords.put("other", dummy);
+      m_Stopwords.put("otherwise", dummy);
+      m_Stopwords.put("ought", dummy);
+      m_Stopwords.put("oughtn't", dummy);
+      m_Stopwords.put("our", dummy);
+      m_Stopwords.put("ours", dummy);
+      m_Stopwords.put("ourselves", dummy);
+      m_Stopwords.put("out", dummy);
+      m_Stopwords.put("outside", dummy);
+      m_Stopwords.put("over", dummy);
+      m_Stopwords.put("own", dummy);
+      m_Stopwords.put("p", dummy);
+      m_Stopwords.put("past", dummy);
+      m_Stopwords.put("pending", dummy);
+      m_Stopwords.put("per", dummy);
+      m_Stopwords.put("perhaps", dummy);
+      m_Stopwords.put("plus", dummy);
+      m_Stopwords.put("possible", dummy);
+      m_Stopwords.put("present", dummy);
+      m_Stopwords.put("probably", dummy);
+      m_Stopwords.put("provided", dummy);
+      m_Stopwords.put("providing", dummy);
+      m_Stopwords.put("public", dummy);
+      m_Stopwords.put("q", dummy);
+      m_Stopwords.put("qua", dummy);
+      m_Stopwords.put("quite", dummy);
+      m_Stopwords.put("r", dummy);
+      m_Stopwords.put("rather", dummy);
+      m_Stopwords.put("re", dummy);
+      m_Stopwords.put("real", dummy);
+      m_Stopwords.put("really", dummy);
+      m_Stopwords.put("respecting", dummy);
+      m_Stopwords.put("right", dummy);
+      m_Stopwords.put("round", dummy);
+      m_Stopwords.put("s", dummy);
+      m_Stopwords.put("same", dummy);
+      m_Stopwords.put("sans", dummy);
+      m_Stopwords.put("save", dummy);
+      m_Stopwords.put("saving", dummy);
+      m_Stopwords.put("second", dummy);
+      m_Stopwords.put("several", dummy);
+      m_Stopwords.put("shall", dummy);
+      m_Stopwords.put("shalt", dummy);
+      m_Stopwords.put("shan't", dummy);
+      m_Stopwords.put("she", dummy);
+      m_Stopwords.put("shed", dummy);
+      m_Stopwords.put("shell", dummy);
+      m_Stopwords.put("she's", dummy);
+      m_Stopwords.put("short", dummy);
+      m_Stopwords.put("should", dummy);
+      m_Stopwords.put("shouldn't", dummy);
+      m_Stopwords.put("since", dummy);
+      m_Stopwords.put("six", dummy);
+      m_Stopwords.put("small", dummy);
+      m_Stopwords.put("so", dummy);
+      m_Stopwords.put("some", dummy);
+      m_Stopwords.put("somebody", dummy);
+      m_Stopwords.put("someone", dummy);
+      m_Stopwords.put("something", dummy);
+      m_Stopwords.put("sometimes", dummy);
+      m_Stopwords.put("soon", dummy);
+      m_Stopwords.put("special", dummy);
+      m_Stopwords.put("still", dummy);
+      m_Stopwords.put("such", dummy);
+      m_Stopwords.put("summat", dummy);
+      m_Stopwords.put("supposing", dummy);
+      m_Stopwords.put("sure", dummy);
+      m_Stopwords.put("t", dummy);
+      m_Stopwords.put("than", dummy);
+      m_Stopwords.put("that", dummy);
+      m_Stopwords.put("that'd", dummy);
+      m_Stopwords.put("that'll", dummy);
+      m_Stopwords.put("that's", dummy);
+      m_Stopwords.put("the", dummy);
+      m_Stopwords.put("thee", dummy);
+      m_Stopwords.put("their", dummy);
+      m_Stopwords.put("theirs", dummy);
+      m_Stopwords.put("their's", dummy);
+      m_Stopwords.put("them", dummy);
+      m_Stopwords.put("themselves", dummy);
+      m_Stopwords.put("then", dummy);
+      m_Stopwords.put("there", dummy);
+      m_Stopwords.put("there's", dummy);
+      m_Stopwords.put("these", dummy);
+      m_Stopwords.put("they", dummy);
+      m_Stopwords.put("they'd", dummy);
+      m_Stopwords.put("they'll", dummy);
+      m_Stopwords.put("they're", dummy);
+      m_Stopwords.put("they've", dummy);
+      m_Stopwords.put("thine", dummy);
+      m_Stopwords.put("this", dummy);
+      m_Stopwords.put("tho", dummy);
+      m_Stopwords.put("those", dummy);
+      m_Stopwords.put("thou", dummy);
+      m_Stopwords.put("though", dummy);
+      m_Stopwords.put("three", dummy);
+      m_Stopwords.put("thro'", dummy);
+      m_Stopwords.put("through", dummy);
+      m_Stopwords.put("throughout", dummy);
+      m_Stopwords.put("thru", dummy);
+      m_Stopwords.put("thyself", dummy);
+      m_Stopwords.put("till", dummy);
+      m_Stopwords.put("to", dummy);
+      m_Stopwords.put("today", dummy);
+      m_Stopwords.put("together", dummy);
+      m_Stopwords.put("too", dummy);
+      m_Stopwords.put("touching", dummy);
+      m_Stopwords.put("toward", dummy);
+      m_Stopwords.put("towards", dummy);
+      m_Stopwords.put("true", dummy);
+      m_Stopwords.put("'twas", dummy);
+      m_Stopwords.put("'tween", dummy);
+      m_Stopwords.put("'twere", dummy);
+      m_Stopwords.put("'twill", dummy);
+      m_Stopwords.put("'twixt", dummy);
+      m_Stopwords.put("two", dummy);
+      m_Stopwords.put("'twould", dummy);
+      m_Stopwords.put("u", dummy);
+      m_Stopwords.put("under", dummy);
+      m_Stopwords.put("underneath", dummy);
+      m_Stopwords.put("unless", dummy);
+      m_Stopwords.put("unlike", dummy);
+      m_Stopwords.put("until", dummy);
+      m_Stopwords.put("unto", dummy);
+      m_Stopwords.put("up", dummy);
+      m_Stopwords.put("upon", dummy);
+      m_Stopwords.put("us", dummy);
+      m_Stopwords.put("used", dummy);
+      m_Stopwords.put("usually", dummy);
+      m_Stopwords.put("v", dummy);
+      m_Stopwords.put("versus", dummy);
+      m_Stopwords.put("very", dummy);
+      m_Stopwords.put("via", dummy);
+      m_Stopwords.put("vice", dummy);
+      m_Stopwords.put("vis-a-vis", dummy);
+      m_Stopwords.put("w", dummy);
+      m_Stopwords.put("wanna", dummy);
+      m_Stopwords.put("wanting", dummy);
+      m_Stopwords.put("was", dummy);
+      m_Stopwords.put("wasn't", dummy);
+      m_Stopwords.put("way", dummy);
+      m_Stopwords.put("we", dummy);
+      m_Stopwords.put("we'd", dummy);
+      m_Stopwords.put("well", dummy);
+      m_Stopwords.put("were", dummy);
+      m_Stopwords.put("weren't", dummy);
+      m_Stopwords.put("wert", dummy);
+      m_Stopwords.put("we've", dummy);
+      m_Stopwords.put("what", dummy);
+      m_Stopwords.put("whatever", dummy);
+      m_Stopwords.put("what'll", dummy);
+      m_Stopwords.put("what's", dummy);
+      m_Stopwords.put("when", dummy);
+      m_Stopwords.put("whencesoever", dummy);
+      m_Stopwords.put("whenever", dummy);
+      m_Stopwords.put("when's", dummy);
+      m_Stopwords.put("whereas", dummy);
+      m_Stopwords.put("where's", dummy);
+      m_Stopwords.put("whether", dummy);
+      m_Stopwords.put("which", dummy);
+      m_Stopwords.put("whichever", dummy);
+      m_Stopwords.put("whichsoever", dummy);
+      m_Stopwords.put("while", dummy);
+      m_Stopwords.put("whilst", dummy);
+      m_Stopwords.put("who", dummy);
+      m_Stopwords.put("who'd", dummy);
+      m_Stopwords.put("whoever", dummy);
+      m_Stopwords.put("whole", dummy);
+      m_Stopwords.put("who'll", dummy);
+      m_Stopwords.put("whom", dummy);
+      m_Stopwords.put("whore", dummy);
+      m_Stopwords.put("who's", dummy);
+      m_Stopwords.put("whose", dummy);
+      m_Stopwords.put("whoso", dummy);
+      m_Stopwords.put("whosoever", dummy);
+      m_Stopwords.put("will", dummy);
+      m_Stopwords.put("with", dummy);
+      m_Stopwords.put("within", dummy);
+      m_Stopwords.put("without", dummy);
+      m_Stopwords.put("wont", dummy);
+      m_Stopwords.put("would", dummy);
+      m_Stopwords.put("wouldn't", dummy);
+      m_Stopwords.put("wouldst", dummy);
+      m_Stopwords.put("x", dummy);
+      m_Stopwords.put("y", dummy);
+      m_Stopwords.put("ye", dummy);
+      m_Stopwords.put("yet", dummy);
+      m_Stopwords.put("you", dummy);
+      m_Stopwords.put("you'd", dummy);
+      m_Stopwords.put("you'll", dummy);
+      m_Stopwords.put("your", dummy);
+      m_Stopwords.put("you're", dummy);
+      m_Stopwords.put("yours", dummy);
+      m_Stopwords.put("yourself", dummy);
+      m_Stopwords.put("yourselves", dummy);
+      m_Stopwords.put("you've", dummy);
+      m_Stopwords.put("z", dummy);
+    }
+  }
+  
+  /** 
+   * Returns true if the given string is a stop word.
+   */
+  public boolean isStopword(String str) {
+
+    return m_Stopwords.containsKey(str.toLowerCase());
+  }
+}
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/StopwordsGerman.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/StopwordsGerman.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/StopwordsGerman.java	(revision 20131)
@@ -0,0 +1,330 @@
+/*
+ *    StopwordsGerman.java
+ *    Copyright (C) 2001 Eibe Frank
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.util.*;
+
+/**
+ * Class that can test whether a given string is a stop word.
+ * Lowercases all words before the test.
+ *
+ * This list of German stop words has been obtained from
+ * http://snowball.tartarus.org/german/stop.txt
+ *
+ * But I have deleted/changed some words that I haven't seen before.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version 1.0
+ */
+public class StopwordsGerman extends Stopwords {
+  
+  /** The hashtable containing the list of stopwords */
+  private static Hashtable m_Stopwords = null;
+
+  static {
+   
+    if (m_Stopwords == null) {
+      m_Stopwords = new Hashtable();
+      Double dummy = new Double(0);
+
+      m_Stopwords.put("aber", dummy);
+
+      m_Stopwords.put("alle", dummy);
+      m_Stopwords.put("allem", dummy);
+      m_Stopwords.put("allen", dummy);
+      m_Stopwords.put("aller", dummy);
+      m_Stopwords.put("alles", dummy);
+
+      m_Stopwords.put("als", dummy);
+      m_Stopwords.put("also", dummy);
+      m_Stopwords.put("am", dummy);
+      m_Stopwords.put("an", dummy);
+
+      m_Stopwords.put("ander", dummy);
+      m_Stopwords.put("andere", dummy);
+      m_Stopwords.put("anderem", dummy);
+      m_Stopwords.put("anderen", dummy);
+      m_Stopwords.put("anderer", dummy);
+      m_Stopwords.put("anderes", dummy);
+      m_Stopwords.put("anderm", dummy);
+      m_Stopwords.put("andern", dummy);
+      m_Stopwords.put("anders", dummy);
+
+      m_Stopwords.put("auch", dummy);
+      m_Stopwords.put("auf", dummy);
+      m_Stopwords.put("aus", dummy);
+      m_Stopwords.put("bei", dummy);
+      m_Stopwords.put("bin", dummy);
+      m_Stopwords.put("bis", dummy);
+      m_Stopwords.put("bist", dummy);
+      m_Stopwords.put("da", dummy);
+      m_Stopwords.put("damit", dummy);
+      m_Stopwords.put("dann", dummy);
+      
+      m_Stopwords.put("der", dummy);
+      m_Stopwords.put("den", dummy);
+      m_Stopwords.put("des", dummy);
+      m_Stopwords.put("dem", dummy);
+      m_Stopwords.put("die", dummy);
+      m_Stopwords.put("das", dummy);
+
+      m_Stopwords.put("da\u00df", dummy);
+
+      m_Stopwords.put("derselbe", dummy);
+      m_Stopwords.put("derselben", dummy);
+      m_Stopwords.put("denselben", dummy);
+      m_Stopwords.put("desselben", dummy);
+      m_Stopwords.put("demselben", dummy);
+      m_Stopwords.put("dieselbe", dummy);
+      m_Stopwords.put("dieselben", dummy);
+      m_Stopwords.put("dasselbe", dummy);
+
+      m_Stopwords.put("dazu", dummy);
+
+      m_Stopwords.put("dein", dummy);
+      m_Stopwords.put("deine", dummy);
+      m_Stopwords.put("deinem", dummy);
+      m_Stopwords.put("deinen", dummy);
+      m_Stopwords.put("deiner", dummy);
+      m_Stopwords.put("deines", dummy);
+
+      m_Stopwords.put("denn", dummy);
+      
+      m_Stopwords.put("derer", dummy);
+      m_Stopwords.put("dessen", dummy);
+      
+      m_Stopwords.put("dich", dummy);
+      m_Stopwords.put("dir", dummy);
+      m_Stopwords.put("du", dummy);
+
+      m_Stopwords.put("dies", dummy);
+      m_Stopwords.put("diese", dummy);
+      m_Stopwords.put("diesem", dummy);
+      m_Stopwords.put("diesen", dummy);
+      m_Stopwords.put("dieser", dummy);
+      m_Stopwords.put("dieses", dummy);
+
+      m_Stopwords.put("doch", dummy);
+      m_Stopwords.put("dort", dummy);
+
+      m_Stopwords.put("durch", dummy);
+
+      m_Stopwords.put("ein", dummy);
+      m_Stopwords.put("eine", dummy);
+      m_Stopwords.put("einem", dummy);
+      m_Stopwords.put("einen", dummy);
+      m_Stopwords.put("einer", dummy);
+      m_Stopwords.put("eines", dummy);
+
+      m_Stopwords.put("einig", dummy);
+      m_Stopwords.put("einige", dummy);
+      m_Stopwords.put("einigem", dummy);
+      m_Stopwords.put("einigen", dummy);
+      m_Stopwords.put("einiger", dummy);
+      m_Stopwords.put("einiges", dummy);
+
+      m_Stopwords.put("einmal", dummy);
+
+      m_Stopwords.put("er", dummy);
+      m_Stopwords.put("ihn", dummy);
+      m_Stopwords.put("ihm", dummy);
+
+      m_Stopwords.put("es", dummy);
+      m_Stopwords.put("etwas", dummy);
+
+      m_Stopwords.put("euer", dummy);
+      m_Stopwords.put("eure", dummy);
+      m_Stopwords.put("eurem", dummy);
+      m_Stopwords.put("euren", dummy);
+      m_Stopwords.put("eurer", dummy);
+      m_Stopwords.put("eures", dummy);
+
+      m_Stopwords.put("f\u00fcr", dummy);
+      m_Stopwords.put("gegen", dummy);
+      m_Stopwords.put("gewesen", dummy);
+      m_Stopwords.put("hab", dummy);
+      m_Stopwords.put("habe", dummy);
+      m_Stopwords.put("haben", dummy);
+      m_Stopwords.put("hat", dummy);
+      m_Stopwords.put("hatte", dummy);
+      m_Stopwords.put("hatten", dummy);
+      m_Stopwords.put("hier", dummy);
+      m_Stopwords.put("hin", dummy);
+      m_Stopwords.put("hinter", dummy);
+      
+      m_Stopwords.put("ich", dummy);
+      m_Stopwords.put("mich", dummy);
+      m_Stopwords.put("mir", dummy);
+
+      m_Stopwords.put("ihr", dummy);
+      m_Stopwords.put("ihre", dummy);
+      m_Stopwords.put("ihrem", dummy);
+      m_Stopwords.put("ihren", dummy);
+      m_Stopwords.put("ihrer", dummy);
+      m_Stopwords.put("ihres", dummy);
+      m_Stopwords.put("euch", dummy);
+
+      m_Stopwords.put("im", dummy);
+      m_Stopwords.put("in", dummy);
+      m_Stopwords.put("indem", dummy);
+      m_Stopwords.put("ins", dummy);
+      m_Stopwords.put("ist", dummy);
+
+      m_Stopwords.put("jede", dummy);
+      m_Stopwords.put("jedem", dummy);
+      m_Stopwords.put("jeden", dummy);
+      m_Stopwords.put("jeder", dummy);
+      m_Stopwords.put("jedes", dummy);
+
+      m_Stopwords.put("jene", dummy);
+      m_Stopwords.put("jenem", dummy);
+      m_Stopwords.put("jenen", dummy);
+      m_Stopwords.put("jener", dummy);
+      m_Stopwords.put("jenes", dummy);
+
+      m_Stopwords.put("jetzt", dummy);
+      m_Stopwords.put("kann", dummy);
+
+      m_Stopwords.put("kein", dummy);
+      m_Stopwords.put("keine", dummy);
+      m_Stopwords.put("keinem", dummy);
+      m_Stopwords.put("keinen", dummy);
+      m_Stopwords.put("keiner", dummy);
+      m_Stopwords.put("keines", dummy);
+
+      m_Stopwords.put("k\u00f6nnen", dummy);
+      m_Stopwords.put("k\u00f6nnte", dummy);
+      m_Stopwords.put("machen", dummy);
+      m_Stopwords.put("man", dummy);
+
+      m_Stopwords.put("manche", dummy);
+      m_Stopwords.put("manchem", dummy);
+      m_Stopwords.put("manchen", dummy);
+      m_Stopwords.put("mancher", dummy);
+      m_Stopwords.put("manches", dummy);
+
+      m_Stopwords.put("mein", dummy);
+      m_Stopwords.put("meine", dummy);
+      m_Stopwords.put("meinem", dummy);
+      m_Stopwords.put("meinen", dummy);
+      m_Stopwords.put("meiner", dummy);
+      m_Stopwords.put("meines", dummy);
+
+      m_Stopwords.put("mit", dummy);
+      m_Stopwords.put("muss", dummy);
+      m_Stopwords.put("musste", dummy);
+      m_Stopwords.put("nach", dummy);
+      m_Stopwords.put("nicht", dummy);
+      m_Stopwords.put("nichts", dummy);
+      m_Stopwords.put("noch", dummy);
+      m_Stopwords.put("nun", dummy);
+      m_Stopwords.put("nur", dummy);
+      m_Stopwords.put("ob", dummy);
+      m_Stopwords.put("oder", dummy);
+      m_Stopwords.put("ohne", dummy);
+      m_Stopwords.put("sehr", dummy);
+
+      m_Stopwords.put("sein", dummy);
+      m_Stopwords.put("seine", dummy);
+      m_Stopwords.put("seinem", dummy);
+      m_Stopwords.put("seinen", dummy);
+      m_Stopwords.put("seiner", dummy);
+      m_Stopwords.put("seines", dummy);
+
+      m_Stopwords.put("selbst", dummy);
+      m_Stopwords.put("sich", dummy);
+      
+      m_Stopwords.put("sie", dummy);
+      m_Stopwords.put("ihnen", dummy);
+
+      m_Stopwords.put("sind", dummy);
+      m_Stopwords.put("so", dummy);
+
+      m_Stopwords.put("solche", dummy);
+      m_Stopwords.put("solchem", dummy);
+      m_Stopwords.put("solchen", dummy);
+      m_Stopwords.put("solcher", dummy);
+      m_Stopwords.put("solches", dummy);
+
+      m_Stopwords.put("soll", dummy);
+      m_Stopwords.put("sollte", dummy);
+      m_Stopwords.put("sondern", dummy);
+      m_Stopwords.put("sonst", dummy);
+      m_Stopwords.put("\00fcber", dummy);
+      m_Stopwords.put("um", dummy);
+      m_Stopwords.put("und", dummy);
+
+      m_Stopwords.put("uns", dummy);
+      m_Stopwords.put("unser", dummy);
+      m_Stopwords.put("unserem", dummy);
+      m_Stopwords.put("unseren", dummy);
+      m_Stopwords.put("unsere", dummy);
+      m_Stopwords.put("unseres", dummy);
+
+      m_Stopwords.put("unter", dummy);
+      m_Stopwords.put("viel", dummy);
+      m_Stopwords.put("vom", dummy);
+      m_Stopwords.put("von", dummy);
+      m_Stopwords.put("vor", dummy);
+      m_Stopwords.put("w\u00e4hrend", dummy);
+      m_Stopwords.put("war", dummy);
+      m_Stopwords.put("waren", dummy);
+      m_Stopwords.put("warst", dummy);
+      m_Stopwords.put("was", dummy);
+      m_Stopwords.put("weg", dummy);
+      m_Stopwords.put("weil", dummy);
+      m_Stopwords.put("weiter", dummy);
+
+      m_Stopwords.put("welche", dummy);
+      m_Stopwords.put("welchem", dummy);
+      m_Stopwords.put("welchen", dummy);
+      m_Stopwords.put("welcher", dummy);
+      m_Stopwords.put("welches", dummy);
+
+      m_Stopwords.put("wenn", dummy);
+      m_Stopwords.put("werde", dummy);
+      m_Stopwords.put("werden", dummy);
+      m_Stopwords.put("wie", dummy);
+      m_Stopwords.put("wieder", dummy);
+      m_Stopwords.put("will", dummy);
+      m_Stopwords.put("wir", dummy);
+      m_Stopwords.put("wird", dummy);
+      m_Stopwords.put("wirst", dummy);
+      m_Stopwords.put("wo", dummy);
+      m_Stopwords.put("wollen", dummy);
+      m_Stopwords.put("wollte", dummy);
+      m_Stopwords.put("w\u00fcrde", dummy);
+      m_Stopwords.put("w\u00fcrden", dummy);
+      m_Stopwords.put("zu", dummy);
+      m_Stopwords.put("zum", dummy);
+      m_Stopwords.put("zur", dummy);
+      m_Stopwords.put("zwar", dummy);
+      m_Stopwords.put("zwischen", dummy);
+    }
+  }
+  
+  /** 
+   * Returns true if the given string is a stop word.
+   */
+  public boolean isStopword(String str) {
+
+    return m_Stopwords.containsKey(str.toLowerCase());
+  }
+}
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/Counter.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/Counter.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/Counter.html	(revision 20131)
@@ -0,0 +1,318 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:48 NZDT 2004 -->
+<TITLE>
+Counter
+</TITLE>
+<META NAME="keywords" CONTENT="Counter,Counter class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="Counter";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="GermanStemmer.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Counter.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class Counter</H2>
+<PRE>
+java.lang.Object
+  |
+  +--<B>Counter</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>Counter</B><DT>extends java.lang.Object<DT>implements java.io.Serializable</DL>
+
+<P>
+Class that implements a simple counter.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="serialized-form.html" TARGET="Counter">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="Counter.html#Counter()">Counter</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initializes the counter to 1</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="Counter.html#Counter(int)">Counter</A></B>(int&nbsp;val)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Initializes the counter to the given value</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="Counter.html#increment()">increment</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Increments the counter.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="Counter.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns string containing value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="Counter.html#value()">value</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the value.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="Counter()"><!-- --></A><H3>
+Counter</H3>
+<PRE>
+public <B>Counter</B>()</PRE>
+<DL>
+<DD>Initializes the counter to 1
+<P>
+</DL>
+<HR>
+
+<A NAME="Counter(int)"><!-- --></A><H3>
+Counter</H3>
+<PRE>
+public <B>Counter</B>(int&nbsp;val)</PRE>
+<DL>
+<DD>Initializes the counter to the given value
+<P>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="increment()"><!-- --></A><H3>
+increment</H3>
+<PRE>
+public void <B>increment</B>()</PRE>
+<DL>
+<DD>Increments the counter.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="value()"><!-- --></A><H3>
+value</H3>
+<PRE>
+public int <B>value</B>()</PRE>
+<DL>
+<DD>Gets the value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the value</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public java.lang.String <B>toString</B>()</PRE>
+<DL>
+<DD>Returns string containing value.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>toString</CODE> in class <CODE>java.lang.Object</CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV CLASS&nbsp;
+&nbsp;<A HREF="GermanStemmer.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Counter.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/GermanStemmer.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/GermanStemmer.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/GermanStemmer.html	(revision 20131)
@@ -0,0 +1,268 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:49 NZDT 2004 -->
+<TITLE>
+GermanStemmer
+</TITLE>
+<META NAME="keywords" CONTENT="GermanStemmer,GermanStemmer class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="GermanStemmer";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="Counter.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="IteratedLovinsStemmer.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="GermanStemmer.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class GermanStemmer</H2>
+<PRE>
+java.lang.Object
+  |
+  +--<A HREF="Stemmer.html">Stemmer</A>
+        |
+        +--<B>GermanStemmer</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>GermanStemmer</B><DT>extends <A HREF="Stemmer.html">Stemmer</A></DL>
+
+<P>
+A stemmer for German words. The algorithm is based on the report
+ "A Fast and Simple Stemming Algorithm for German Words" by Jörg
+ Caumanns (joerg.caumanns@isst.fhg.de).
+
+ Changed stem() from protected to public.
+ Changed coding for umlaute to unicode.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="serialized-form.html" TARGET="GermanStemmer">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="GermanStemmer.html#GermanStemmer()">GermanStemmer</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="GermanStemmer.html#stem(java.lang.String)">stem</A></B>(java.lang.String&nbsp;term)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stemms the given term to an unique <tt>discriminator</tt>.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_Stemmer"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class <A HREF="Stemmer.html">Stemmer</A></B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="Stemmer.html#stemString(java.lang.String)">stemString</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="GermanStemmer()"><!-- --></A><H3>
+GermanStemmer</H3>
+<PRE>
+public <B>GermanStemmer</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="stem(java.lang.String)"><!-- --></A><H3>
+stem</H3>
+<PRE>
+public java.lang.String <B>stem</B>(java.lang.String&nbsp;term)</PRE>
+<DL>
+<DD>Stemms the given term to an unique <tt>discriminator</tt>.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="Stemmer.html#stem(java.lang.String)">stem</A></CODE> in class <CODE><A HREF="Stemmer.html">Stemmer</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>term</CODE> - The term that should be stemmed.
+<DT><B>Returns:</B><DD>Discriminator for <tt>term</tt></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="Counter.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="IteratedLovinsStemmer.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="GermanStemmer.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/IteratedLovinsStemmer.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/IteratedLovinsStemmer.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/IteratedLovinsStemmer.html	(revision 20131)
@@ -0,0 +1,285 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:49 NZDT 2004 -->
+<TITLE>
+IteratedLovinsStemmer
+</TITLE>
+<META NAME="keywords" CONTENT="IteratedLovinsStemmer,IteratedLovinsStemmer class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="IteratedLovinsStemmer";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="GermanStemmer.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="KEAFilter.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="IteratedLovinsStemmer.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class IteratedLovinsStemmer</H2>
+<PRE>
+java.lang.Object
+  |
+  +--<A HREF="Stemmer.html">Stemmer</A>
+        |
+        +--<A HREF="LovinsStemmer.html">LovinsStemmer</A>
+              |
+              +--<B>IteratedLovinsStemmer</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>IteratedLovinsStemmer</B><DT>extends <A HREF="LovinsStemmer.html">LovinsStemmer</A></DL>
+
+<P>
+Implements the iterated version of the Lovins stemmer.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="serialized-form.html" TARGET="IteratedLovinsStemmer">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="IteratedLovinsStemmer.html#IteratedLovinsStemmer()">IteratedLovinsStemmer</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="IteratedLovinsStemmer.html#main(java.lang.String[])">main</A></B>(java.lang.String[]&nbsp;ops)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stems text coming into stdin and writes it to stdout.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="IteratedLovinsStemmer.html#stem(java.lang.String)">stem</A></B>(java.lang.String&nbsp;str)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Iterated stemming of the given word.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_Stemmer"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class <A HREF="Stemmer.html">Stemmer</A></B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="Stemmer.html#stemString(java.lang.String)">stemString</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="IteratedLovinsStemmer()"><!-- --></A><H3>
+IteratedLovinsStemmer</H3>
+<PRE>
+public <B>IteratedLovinsStemmer</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="stem(java.lang.String)"><!-- --></A><H3>
+stem</H3>
+<PRE>
+public java.lang.String <B>stem</B>(java.lang.String&nbsp;str)</PRE>
+<DL>
+<DD>Iterated stemming of the given word.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE><A HREF="LovinsStemmer.html#stem(java.lang.String)">stem</A></CODE> in class <CODE><A HREF="LovinsStemmer.html">LovinsStemmer</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>str</CODE> - a string consisting of a single word</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(java.lang.String[]&nbsp;ops)</PRE>
+<DL>
+<DD>Stems text coming into stdin and writes it to stdout.
+<P>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="GermanStemmer.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="KEAFilter.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="IteratedLovinsStemmer.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/KEAFilter.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/KEAFilter.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/KEAFilter.html	(revision 20131)
@@ -0,0 +1,1147 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:49 NZDT 2004 -->
+<TITLE>
+KEAFilter
+</TITLE>
+<META NAME="keywords" CONTENT="KEAFilter,KEAFilter class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="KEAFilter";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="IteratedLovinsStemmer.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="KEAKeyphraseExtractor.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="KEAFilter.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#fields_inherited_from_class_weka.filters.Filter">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class KEAFilter</H2>
+<PRE>
+java.lang.Object
+  |
+  +--weka.filters.Filter
+        |
+        +--<B>KEAFilter</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>weka.core.OptionHandler, java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>KEAFilter</B><DT>extends weka.filters.Filter<DT>implements weka.core.OptionHandler</DL>
+
+<P>
+This filter converts the incoming data into data appropriate for
+ keyphrase classification. It assumes that the dataset contains two
+ string attributes. The first attribute should contain the text of a
+ document. The second attribute should contain the keyphrases
+ associated with that document (if present). 
+
+ The filter converts every instance (i.e. document) into a set of
+ instances, one for each word-based n-gram in the document. The
+ string attribute representing the document is replaced by some
+ numeric features, the estimated probability of each n-gram being a
+ keyphrase, and the rank of this phrase in the document according to
+ the probability.  Each new instances also has a class value
+ associated with it. The class is "true" if the n-gram is a true
+ keyphrase, and "false" otherwise. Of course, if the input document
+ doesn't come with author-assigned keyphrases, the class values for
+ that document will be missing.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="serialized-form.html" TARGET="KEAFilter">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_weka.filters.Filter"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Fields inherited from class weka.filters.Filter</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>m_NewBatch</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="KEAFilter.html#KEAFilter()">KEAFilter</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#batchFinished()">batchFinished</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Signify that this batch of input to the filter is finished.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getCheckForProperNouns()">getCheckForProperNouns</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the M_CheckProperNouns value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getDebug()">getDebug</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of Debug.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getDisallowInternalPeriods()">getDisallowInternalPeriods</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get whether the supplied columns are to be processed</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getDocumentAtt()">getDocumentAtt</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of DocumentAtt.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getKeyphrasesAtt()">getKeyphrasesAtt</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of KeyphraseAtt.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getKFused()">getKFused</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets whether keyphrase frequency attribute is used.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getMaxPhraseLength()">getMaxPhraseLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of MaxPhraseLength.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getMinNumOccur()">getMinNumOccur</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of MinNumOccur.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getMinPhraseLength()">getMinPhraseLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of MinPhraseLength.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getOptions()">getOptions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the current settings of the filter.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getProbabilityIndex()">getProbabilityIndex</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the index of the phrases' probabilities in the output ARFF file.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getRankIndex()">getRankIndex</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the index of the phrases' ranks in the output ARFF file.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getStemmedPhraseIndex()">getStemmedPhraseIndex</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the index of the stemmed phrases in the output ARFF file.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;Stemmer</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getStemmer()">getStemmer</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the Stemmer value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;Stopwords</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getStopwords()">getStopwords</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the M_Stopwords value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#getUnstemmedPhraseIndex()">getUnstemmedPhraseIndex</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the index of the unstemmed phrases in the output ARFF file.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#globalInfo()">globalInfo</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a string describing this filter</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#input(weka.core.Instance)">input</A></B>(weka.core.Instance&nbsp;instance)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Input an instance for filtering.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Enumeration</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#listOptions()">listOptions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an enumeration describing the available options</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#main(java.lang.String[])">main</A></B>(java.lang.String[]&nbsp;argv)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main method for testing this class.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setCheckForProperNouns(boolean)">setCheckForProperNouns</A></B>(boolean&nbsp;newM_CheckProperNouns)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the M_CheckProperNouns value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setDebug(boolean)">setDebug</A></B>(boolean&nbsp;newDebug)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of Debug.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setDisallowInternalPeriods(boolean)">setDisallowInternalPeriods</A></B>(boolean&nbsp;disallow)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set whether selected columns should be processed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setDocumentAtt(int)">setDocumentAtt</A></B>(int&nbsp;newDocumentAtt)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of DocumentAtt.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setInputFormat(weka.core.Instances)">setInputFormat</A></B>(weka.core.Instances&nbsp;instanceInfo)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the format of the input instances.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setKeyphrasesAtt(int)">setKeyphrasesAtt</A></B>(int&nbsp;newKeyphrasesAtt)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of KeyphrasesAtt.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setKFused(boolean)">setKFused</A></B>(boolean&nbsp;flag)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets whether keyphrase frequency attribute is used.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setMaxPhraseLength(int)">setMaxPhraseLength</A></B>(int&nbsp;newMaxPhraseLength)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of MaxPhraseLength.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setMinNumOccur(int)">setMinNumOccur</A></B>(int&nbsp;newMinNumOccur)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of MinNumOccur.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setMinPhraseLength(int)">setMinPhraseLength</A></B>(int&nbsp;newMinPhraseLength)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of MinPhraseLength.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setOptions(java.lang.String[])">setOptions</A></B>(java.lang.String[]&nbsp;options)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parses a given list of options controlling the behaviour of this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setStemmer(Stemmer)">setStemmer</A></B>(Stemmer&nbsp;newStemmer)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the Stemmer value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAFilter.html#setStopwords(Stopwords)">setStopwords</A></B>(Stopwords&nbsp;newM_Stopwords)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the M_Stopwords value.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_weka.filters.Filter"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class weka.filters.Filter</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>batchFilterFile, bufferInput, copyStringValues, copyStringValues, filterFile, flushInput, getInputFormat, getInputStringIndex, getOutputFormat, getOutputStringIndex, getStringIndices, inputFormat, isOutputFormatDefined, numPendingOutput, output, outputFormat, outputFormatPeek, outputPeek, push, resetQueue, setOutputFormat, useFilter</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="KEAFilter()"><!-- --></A><H3>
+KEAFilter</H3>
+<PRE>
+public <B>KEAFilter</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="getCheckForProperNouns()"><!-- --></A><H3>
+getCheckForProperNouns</H3>
+<PRE>
+public boolean <B>getCheckForProperNouns</B>()</PRE>
+<DL>
+<DD>Get the M_CheckProperNouns value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the M_CheckProperNouns value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCheckForProperNouns(boolean)"><!-- --></A><H3>
+setCheckForProperNouns</H3>
+<PRE>
+public void <B>setCheckForProperNouns</B>(boolean&nbsp;newM_CheckProperNouns)</PRE>
+<DL>
+<DD>Set the M_CheckProperNouns value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newM_CheckProperNouns</CODE> - The new M_CheckProperNouns value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getStopwords()"><!-- --></A><H3>
+getStopwords</H3>
+<PRE>
+public Stopwords <B>getStopwords</B>()</PRE>
+<DL>
+<DD>Get the M_Stopwords value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the M_Stopwords value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setStopwords(Stopwords)"><!-- --></A><H3>
+setStopwords</H3>
+<PRE>
+public void <B>setStopwords</B>(Stopwords&nbsp;newM_Stopwords)</PRE>
+<DL>
+<DD>Set the M_Stopwords value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newM_Stopwords</CODE> - The new M_Stopwords value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getStemmer()"><!-- --></A><H3>
+getStemmer</H3>
+<PRE>
+public Stemmer <B>getStemmer</B>()</PRE>
+<DL>
+<DD>Get the Stemmer value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the Stemmer value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setStemmer(Stemmer)"><!-- --></A><H3>
+setStemmer</H3>
+<PRE>
+public void <B>setStemmer</B>(Stemmer&nbsp;newStemmer)</PRE>
+<DL>
+<DD>Set the Stemmer value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newStemmer</CODE> - The new Stemmer value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMinNumOccur()"><!-- --></A><H3>
+getMinNumOccur</H3>
+<PRE>
+public int <B>getMinNumOccur</B>()</PRE>
+<DL>
+<DD>Get the value of MinNumOccur.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of MinNumOccur.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setMinNumOccur(int)"><!-- --></A><H3>
+setMinNumOccur</H3>
+<PRE>
+public void <B>setMinNumOccur</B>(int&nbsp;newMinNumOccur)</PRE>
+<DL>
+<DD>Set the value of MinNumOccur.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newMinNumOccur</CODE> - Value to assign to MinNumOccur.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxPhraseLength()"><!-- --></A><H3>
+getMaxPhraseLength</H3>
+<PRE>
+public int <B>getMaxPhraseLength</B>()</PRE>
+<DL>
+<DD>Get the value of MaxPhraseLength.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of MaxPhraseLength.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setMaxPhraseLength(int)"><!-- --></A><H3>
+setMaxPhraseLength</H3>
+<PRE>
+public void <B>setMaxPhraseLength</B>(int&nbsp;newMaxPhraseLength)</PRE>
+<DL>
+<DD>Set the value of MaxPhraseLength.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newMaxPhraseLength</CODE> - Value to assign to MaxPhraseLength.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMinPhraseLength()"><!-- --></A><H3>
+getMinPhraseLength</H3>
+<PRE>
+public int <B>getMinPhraseLength</B>()</PRE>
+<DL>
+<DD>Get the value of MinPhraseLength.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of MinPhraseLength.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setMinPhraseLength(int)"><!-- --></A><H3>
+setMinPhraseLength</H3>
+<PRE>
+public void <B>setMinPhraseLength</B>(int&nbsp;newMinPhraseLength)</PRE>
+<DL>
+<DD>Set the value of MinPhraseLength.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newMinPhraseLength</CODE> - Value to assign to MinPhraseLength.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getStemmedPhraseIndex()"><!-- --></A><H3>
+getStemmedPhraseIndex</H3>
+<PRE>
+public int <B>getStemmedPhraseIndex</B>()</PRE>
+<DL>
+<DD>Returns the index of the stemmed phrases in the output ARFF file.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getUnstemmedPhraseIndex()"><!-- --></A><H3>
+getUnstemmedPhraseIndex</H3>
+<PRE>
+public int <B>getUnstemmedPhraseIndex</B>()</PRE>
+<DL>
+<DD>Returns the index of the unstemmed phrases in the output ARFF file.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getProbabilityIndex()"><!-- --></A><H3>
+getProbabilityIndex</H3>
+<PRE>
+public int <B>getProbabilityIndex</B>()</PRE>
+<DL>
+<DD>Returns the index of the phrases' probabilities in the output ARFF file.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getRankIndex()"><!-- --></A><H3>
+getRankIndex</H3>
+<PRE>
+public int <B>getRankIndex</B>()</PRE>
+<DL>
+<DD>Returns the index of the phrases' ranks in the output ARFF file.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDocumentAtt()"><!-- --></A><H3>
+getDocumentAtt</H3>
+<PRE>
+public int <B>getDocumentAtt</B>()</PRE>
+<DL>
+<DD>Get the value of DocumentAtt.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of DocumentAtt.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDocumentAtt(int)"><!-- --></A><H3>
+setDocumentAtt</H3>
+<PRE>
+public void <B>setDocumentAtt</B>(int&nbsp;newDocumentAtt)</PRE>
+<DL>
+<DD>Set the value of DocumentAtt.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newDocumentAtt</CODE> - Value to assign to DocumentAtt.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getKeyphrasesAtt()"><!-- --></A><H3>
+getKeyphrasesAtt</H3>
+<PRE>
+public int <B>getKeyphrasesAtt</B>()</PRE>
+<DL>
+<DD>Get the value of KeyphraseAtt.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of KeyphraseAtt.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setKeyphrasesAtt(int)"><!-- --></A><H3>
+setKeyphrasesAtt</H3>
+<PRE>
+public void <B>setKeyphrasesAtt</B>(int&nbsp;newKeyphrasesAtt)</PRE>
+<DL>
+<DD>Set the value of KeyphrasesAtt.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newKeyphrasesAtt</CODE> - Value to assign to KeyphrasesAtt.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDebug()"><!-- --></A><H3>
+getDebug</H3>
+<PRE>
+public boolean <B>getDebug</B>()</PRE>
+<DL>
+<DD>Get the value of Debug.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of Debug.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDebug(boolean)"><!-- --></A><H3>
+setDebug</H3>
+<PRE>
+public void <B>setDebug</B>(boolean&nbsp;newDebug)</PRE>
+<DL>
+<DD>Set the value of Debug.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newDebug</CODE> - Value to assign to Debug.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setKFused(boolean)"><!-- --></A><H3>
+setKFused</H3>
+<PRE>
+public void <B>setKFused</B>(boolean&nbsp;flag)</PRE>
+<DL>
+<DD>Sets whether keyphrase frequency attribute is used.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getKFused()"><!-- --></A><H3>
+getKFused</H3>
+<PRE>
+public boolean <B>getKFused</B>()</PRE>
+<DL>
+<DD>Gets whether keyphrase frequency attribute is used.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDisallowInternalPeriods()"><!-- --></A><H3>
+getDisallowInternalPeriods</H3>
+<PRE>
+public boolean <B>getDisallowInternalPeriods</B>()</PRE>
+<DL>
+<DD>Get whether the supplied columns are to be processed
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if the supplied columns won't be processed</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDisallowInternalPeriods(boolean)"><!-- --></A><H3>
+setDisallowInternalPeriods</H3>
+<PRE>
+public void <B>setDisallowInternalPeriods</B>(boolean&nbsp;disallow)</PRE>
+<DL>
+<DD>Set whether selected columns should be processed. If true the 
+ selected columns won't be processed.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setOptions(java.lang.String[])"><!-- --></A><H3>
+setOptions</H3>
+<PRE>
+public void <B>setOptions</B>(java.lang.String[]&nbsp;options)
+                throws java.lang.Exception</PRE>
+<DL>
+<DD>Parses a given list of options controlling the behaviour of this object.
+ Valid options are:<p>
+
+ -K<br>
+ Specifies whether keyphrase frequency statistic is used.<p>
+
+ -M length<br>
+ Sets the maximum phrase length (default: 3).<p>
+
+ -L length<br>
+ Sets the minimum phrase length (default: 1).<p>
+
+ -D<br>
+ Turns debugging mode on.<p>
+
+ -I index<br>
+ Sets the index of the attribute containing the documents (default: 0).<p>
+
+ -J index<br>
+ Sets the index of the attribute containing the keyphrases (default: 1).<p>
+
+ -P<br>
+ Disallow internal periods <p>
+
+ -O number<br>
+ The minimum number of times a phrase needs to occur (default: 2). <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>setOptions</CODE> in interface <CODE>weka.core.OptionHandler</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>options</CODE> - the list of options as an array of strings
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.Exception</CODE> - if an option is not supported</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getOptions()"><!-- --></A><H3>
+getOptions</H3>
+<PRE>
+public java.lang.String[] <B>getOptions</B>()</PRE>
+<DL>
+<DD>Gets the current settings of the filter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>getOptions</CODE> in interface <CODE>weka.core.OptionHandler</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an array of strings suitable for passing to setOptions</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="listOptions()"><!-- --></A><H3>
+listOptions</H3>
+<PRE>
+public java.util.Enumeration <B>listOptions</B>()</PRE>
+<DL>
+<DD>Returns an enumeration describing the available options
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>listOptions</CODE> in interface <CODE>weka.core.OptionHandler</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an enumeration of all the available options</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="globalInfo()"><!-- --></A><H3>
+globalInfo</H3>
+<PRE>
+public java.lang.String <B>globalInfo</B>()</PRE>
+<DL>
+<DD>Returns a string describing this filter
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a description of the filter suitable for
+ displaying in the explorer/experimenter gui</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setInputFormat(weka.core.Instances)"><!-- --></A><H3>
+setInputFormat</H3>
+<PRE>
+public boolean <B>setInputFormat</B>(weka.core.Instances&nbsp;instanceInfo)
+                       throws java.lang.Exception</PRE>
+<DL>
+<DD>Sets the format of the input instances.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>setInputFormat</CODE> in class <CODE>weka.filters.Filter</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>instanceInfo</CODE> - an Instances object containing the input
+ instance structure (any instances contained in the object are
+ ignored - only the structure is required).
+<DT><B>Returns:</B><DD>true if the outputFormat may be collected immediately
+<DD><CODE>java.lang.Exception</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="input(weka.core.Instance)"><!-- --></A><H3>
+input</H3>
+<PRE>
+public boolean <B>input</B>(weka.core.Instance&nbsp;instance)
+              throws java.lang.Exception</PRE>
+<DL>
+<DD>Input an instance for filtering. Ordinarily the instance is processed
+ and made available for output immediately. Some filters require all
+ instances be read before producing output.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>input</CODE> in class <CODE>weka.filters.Filter</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>instance</CODE> - the input instance
+<DT><B>Returns:</B><DD>true if the filtered instance may now be
+ collected with output().
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.Exception</CODE> - if the input instance was not of the correct 
+ format or if there was a problem with the filtering.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="batchFinished()"><!-- --></A><H3>
+batchFinished</H3>
+<PRE>
+public boolean <B>batchFinished</B>()
+                      throws java.lang.Exception</PRE>
+<DL>
+<DD>Signify that this batch of input to the filter is finished. 
+ If the filter requires all instances prior to filtering,
+ output() may now be called to retrieve the filtered instances.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>batchFinished</CODE> in class <CODE>weka.filters.Filter</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if there are instances pending output
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.Exception</CODE> - if no input structure has been defined</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(java.lang.String[]&nbsp;argv)</PRE>
+<DL>
+<DD>Main method for testing this class.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>argv</CODE> - should contain arguments to the filter: use -h for help</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="IteratedLovinsStemmer.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="KEAKeyphraseExtractor.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="KEAFilter.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#fields_inherited_from_class_weka.filters.Filter">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/KEAKeyphraseExtractor.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/KEAKeyphraseExtractor.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/KEAKeyphraseExtractor.html	(revision 20131)
@@ -0,0 +1,742 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:49 NZDT 2004 -->
+<TITLE>
+KEAKeyphraseExtractor
+</TITLE>
+<META NAME="keywords" CONTENT="KEAKeyphraseExtractor,KEAKeyphraseExtractor class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="KEAKeyphraseExtractor";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="KEAFilter.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="KEAModelBuilder.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="KEAKeyphraseExtractor.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class KEAKeyphraseExtractor</H2>
+<PRE>
+java.lang.Object
+  |
+  +--<B>KEAKeyphraseExtractor</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>weka.core.OptionHandler</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>KEAKeyphraseExtractor</B><DT>extends java.lang.Object<DT>implements weka.core.OptionHandler</DL>
+
+<P>
+Extracts keyphrases from the documents in a given directory.
+ Assumes that the file names for the documents end with ".txt".
+ Puts extracted keyphrases into corresponding files ending with
+ ".key" (if those are not already present). Optionally an encoding
+ for the documents/keyphrases can be defined (e.g. for Chinese
+ text). Documents for which ".key" exists, are used for evaluation.
+
+ Valid options are:<p>
+
+ -l "directory name"<br>
+ Specifies name of directory.<p>
+
+ -m "model name"<br>
+ Specifies name of model.<p>
+
+ -e "encoding"<br>
+ Specifies encoding.<p>
+
+ -n <br>
+ Specifies number of phrases to be output (default: 5).<p>
+
+ -d<br>
+ Turns debugging mode on.<p>
+
+ -a<br>
+ Also write stemmed phrase and score into ".key" file.<p>
+<P>
+
+<P>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#KEAKeyphraseExtractor()">KEAKeyphraseExtractor</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Hashtable</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#collectStems()">collectStems</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Collects the stems of the file names.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#extractKeyphrases(java.util.Hashtable)">extractKeyphrases</A></B>(java.util.Hashtable&nbsp;stems)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Builds the model from the files</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#getAdditionalInfo()">getAdditionalInfo</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of AdditionalInfo.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#getDebug()">getDebug</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of debug.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#getDirName()">getDirName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of dirName.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#getEncoding()">getEncoding</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of encoding.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#getModelName()">getModelName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of modelName.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#getNumPhrases()">getNumPhrases</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of numPhrases.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#getOptions()">getOptions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the current option settings.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Enumeration</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#listOptions()">listOptions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an enumeration describing the available options.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#loadModel()">loadModel</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Loads the extraction model from the file.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#main(java.lang.String[])">main</A></B>(java.lang.String[]&nbsp;ops)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The main method.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#setAdditionalInfo(boolean)">setAdditionalInfo</A></B>(boolean&nbsp;newAdditionalInfo)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of AdditionalInfo.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#setDebug(boolean)">setDebug</A></B>(boolean&nbsp;newdebug)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of debug.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#setDirName(java.lang.String)">setDirName</A></B>(java.lang.String&nbsp;newdirName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of dirName.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#setEncoding(java.lang.String)">setEncoding</A></B>(java.lang.String&nbsp;newencoding)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of encoding.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#setModelName(java.lang.String)">setModelName</A></B>(java.lang.String&nbsp;newmodelName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of modelName.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#setNumPhrases(int)">setNumPhrases</A></B>(int&nbsp;newnumPhrases)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of numPhrases.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAKeyphraseExtractor.html#setOptions(java.lang.String[])">setOptions</A></B>(java.lang.String[]&nbsp;options)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parses a given list of options controlling the behaviour of this object.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="KEAKeyphraseExtractor()"><!-- --></A><H3>
+KEAKeyphraseExtractor</H3>
+<PRE>
+public <B>KEAKeyphraseExtractor</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="getAdditionalInfo()"><!-- --></A><H3>
+getAdditionalInfo</H3>
+<PRE>
+public boolean <B>getAdditionalInfo</B>()</PRE>
+<DL>
+<DD>Get the value of AdditionalInfo.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of AdditionalInfo.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAdditionalInfo(boolean)"><!-- --></A><H3>
+setAdditionalInfo</H3>
+<PRE>
+public void <B>setAdditionalInfo</B>(boolean&nbsp;newAdditionalInfo)</PRE>
+<DL>
+<DD>Set the value of AdditionalInfo.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newAdditionalInfo</CODE> - Value to assign to AdditionalInfo.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNumPhrases()"><!-- --></A><H3>
+getNumPhrases</H3>
+<PRE>
+public int <B>getNumPhrases</B>()</PRE>
+<DL>
+<DD>Get the value of numPhrases.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of numPhrases.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setNumPhrases(int)"><!-- --></A><H3>
+setNumPhrases</H3>
+<PRE>
+public void <B>setNumPhrases</B>(int&nbsp;newnumPhrases)</PRE>
+<DL>
+<DD>Set the value of numPhrases.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newnumPhrases</CODE> - Value to assign to numPhrases.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDebug()"><!-- --></A><H3>
+getDebug</H3>
+<PRE>
+public boolean <B>getDebug</B>()</PRE>
+<DL>
+<DD>Get the value of debug.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of debug.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDebug(boolean)"><!-- --></A><H3>
+setDebug</H3>
+<PRE>
+public void <B>setDebug</B>(boolean&nbsp;newdebug)</PRE>
+<DL>
+<DD>Set the value of debug.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newdebug</CODE> - Value to assign to debug.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getEncoding()"><!-- --></A><H3>
+getEncoding</H3>
+<PRE>
+public java.lang.String <B>getEncoding</B>()</PRE>
+<DL>
+<DD>Get the value of encoding.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of encoding.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setEncoding(java.lang.String)"><!-- --></A><H3>
+setEncoding</H3>
+<PRE>
+public void <B>setEncoding</B>(java.lang.String&nbsp;newencoding)</PRE>
+<DL>
+<DD>Set the value of encoding.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newencoding</CODE> - Value to assign to encoding.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getModelName()"><!-- --></A><H3>
+getModelName</H3>
+<PRE>
+public java.lang.String <B>getModelName</B>()</PRE>
+<DL>
+<DD>Get the value of modelName.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of modelName.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setModelName(java.lang.String)"><!-- --></A><H3>
+setModelName</H3>
+<PRE>
+public void <B>setModelName</B>(java.lang.String&nbsp;newmodelName)</PRE>
+<DL>
+<DD>Set the value of modelName.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newmodelName</CODE> - Value to assign to modelName.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDirName()"><!-- --></A><H3>
+getDirName</H3>
+<PRE>
+public java.lang.String <B>getDirName</B>()</PRE>
+<DL>
+<DD>Get the value of dirName.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of dirName.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDirName(java.lang.String)"><!-- --></A><H3>
+setDirName</H3>
+<PRE>
+public void <B>setDirName</B>(java.lang.String&nbsp;newdirName)</PRE>
+<DL>
+<DD>Set the value of dirName.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newdirName</CODE> - Value to assign to dirName.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setOptions(java.lang.String[])"><!-- --></A><H3>
+setOptions</H3>
+<PRE>
+public void <B>setOptions</B>(java.lang.String[]&nbsp;options)
+                throws java.lang.Exception</PRE>
+<DL>
+<DD>Parses a given list of options controlling the behaviour of this object.
+ Valid options are:<p>
+
+ -l "directory name"<br>
+ Specifies name of directory.<p>
+
+ -m "model name"<br>
+ Specifies name of model.<p>
+
+ -e "encoding"<br>
+ Specifies encoding.<p>
+
+ -n<br>
+ Specifies number of phrases to be output (default: 5).<p>
+
+ -d<br>
+ Turns debugging mode on.<p>
+
+ -a<br>
+ Also write stemmed phrase and score into ".key" file.<p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>setOptions</CODE> in interface <CODE>weka.core.OptionHandler</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>options</CODE> - the list of options as an array of strings
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.Exception</CODE> - if an option is not supported</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getOptions()"><!-- --></A><H3>
+getOptions</H3>
+<PRE>
+public java.lang.String[] <B>getOptions</B>()</PRE>
+<DL>
+<DD>Gets the current option settings.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>getOptions</CODE> in interface <CODE>weka.core.OptionHandler</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an array of strings suitable for passing to setOptions</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="listOptions()"><!-- --></A><H3>
+listOptions</H3>
+<PRE>
+public java.util.Enumeration <B>listOptions</B>()</PRE>
+<DL>
+<DD>Returns an enumeration describing the available options.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>listOptions</CODE> in interface <CODE>weka.core.OptionHandler</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an enumeration of all the available options</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="collectStems()"><!-- --></A><H3>
+collectStems</H3>
+<PRE>
+public java.util.Hashtable <B>collectStems</B>()
+                                 throws java.lang.Exception</PRE>
+<DL>
+<DD>Collects the stems of the file names.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DD><CODE>java.lang.Exception</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="extractKeyphrases(java.util.Hashtable)"><!-- --></A><H3>
+extractKeyphrases</H3>
+<PRE>
+public void <B>extractKeyphrases</B>(java.util.Hashtable&nbsp;stems)
+                       throws java.lang.Exception</PRE>
+<DL>
+<DD>Builds the model from the files
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DD><CODE>java.lang.Exception</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="loadModel()"><!-- --></A><H3>
+loadModel</H3>
+<PRE>
+public void <B>loadModel</B>()
+               throws java.lang.Exception</PRE>
+<DL>
+<DD>Loads the extraction model from the file.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DD><CODE>java.lang.Exception</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(java.lang.String[]&nbsp;ops)</PRE>
+<DL>
+<DD>The main method.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="KEAFilter.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="KEAModelBuilder.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="KEAKeyphraseExtractor.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/KEAModelBuilder.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/KEAModelBuilder.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/KEAModelBuilder.html	(revision 20131)
@@ -0,0 +1,1072 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:49 NZDT 2004 -->
+<TITLE>
+KEAModelBuilder
+</TITLE>
+<META NAME="keywords" CONTENT="KEAModelBuilder,KEAModelBuilder class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="KEAModelBuilder";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="KEAKeyphraseExtractor.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="KEAPhraseFilter.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="KEAModelBuilder.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class KEAModelBuilder</H2>
+<PRE>
+java.lang.Object
+  |
+  +--<B>KEAModelBuilder</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>weka.core.OptionHandler</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>KEAModelBuilder</B><DT>extends java.lang.Object<DT>implements weka.core.OptionHandler</DL>
+
+<P>
+Builds a keyphrase extraction model from the documents in a given
+ directory.  Assumes that the file names for the documents end with
+ ".txt".  Assumes that files containing corresponding
+ author-assigned keyphrases end with ".key". Optionally an encoding
+ for the documents/keyphrases can be defined (e.g. for Chinese
+ text).
+
+ Valid options are:<p>
+
+ -l "directory name"<br>
+ Specifies name of directory.<p>
+
+ -m "model name"<br>
+ Specifies name of model.<p>
+
+ -e "encoding"<br>
+ Specifies encoding.<p>
+
+ -d<br>
+ Turns debugging mode on.<p>
+
+ -k<br>
+ Use keyphrase frequency statistic.<p>
+
+ -p<br>
+ Disallow internal periods.<p>
+
+ -x "length"<br>
+ Sets maximum phrase length (default: 3).<p>
+
+ -y "length"<br>
+ Sets minimum phrase length (default: 1).<p>
+
+ -o "number"<br>
+ The minimum number of times a phrase needs to occur (default: 2). <p>
+
+ -s "name of class implementing list of stop words"<br>
+ Sets list of stop words to used (default: StopwordsEnglish).<p>
+
+ -t "name of class implementing stemmer"<br>
+ Sets stemmer to use (default: IteratedLovinsStemmer). <p>
+
+ -n<br>
+ Do not check for proper nouns. <p>
+<P>
+
+<P>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="KEAModelBuilder.html#KEAModelBuilder()">KEAModelBuilder</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#buildModel(java.util.Hashtable)">buildModel</A></B>(java.util.Hashtable&nbsp;stems)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Builds the model from the files</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Hashtable</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#collectStems()">collectStems</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Collects the stems of the file names.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getCheckForProperNouns()">getCheckForProperNouns</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the M_CheckProperNouns value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getDebug()">getDebug</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of debug.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getDirName()">getDirName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of dirName.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getDisallowIPeriods()">getDisallowIPeriods</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of disallowIPeriods.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getEncoding()">getEncoding</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of encoding.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getMaxPhraseLength()">getMaxPhraseLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of MaxPhraseLength.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getMinNumOccur()">getMinNumOccur</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of MinNumOccur.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getMinPhraseLength()">getMinPhraseLength</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of MinPhraseLength.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getModelName()">getModelName</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of modelName.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getOptions()">getOptions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the current option settings.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;Stemmer</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getStemmer()">getStemmer</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the Stemmer value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;Stopwords</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getStopwords()">getStopwords</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the M_Stopwords value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#getUseKFrequency()">getUseKFrequency</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the value of useKFrequency.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Enumeration</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#listOptions()">listOptions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an enumeration describing the available options.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#main(java.lang.String[])">main</A></B>(java.lang.String[]&nbsp;ops)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The main method.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#saveModel()">saveModel</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Saves the extraction model to the file.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setCheckForProperNouns(boolean)">setCheckForProperNouns</A></B>(boolean&nbsp;newM_CheckProperNouns)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the M_CheckProperNouns value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setDebug(boolean)">setDebug</A></B>(boolean&nbsp;newdebug)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of debug.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setDirName(java.lang.String)">setDirName</A></B>(java.lang.String&nbsp;newdirName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of dirName.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setDisallowIPeriods(boolean)">setDisallowIPeriods</A></B>(boolean&nbsp;newdisallowIPeriods)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of disallowIPeriods.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setEncoding(java.lang.String)">setEncoding</A></B>(java.lang.String&nbsp;newencoding)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of encoding.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setMaxPhraseLength(int)">setMaxPhraseLength</A></B>(int&nbsp;newMaxPhraseLength)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of MaxPhraseLength.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setMinNumOccur(int)">setMinNumOccur</A></B>(int&nbsp;newMinNumOccur)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of MinNumOccur.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setMinPhraseLength(int)">setMinPhraseLength</A></B>(int&nbsp;newMinPhraseLength)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of MinPhraseLength.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setModelName(java.lang.String)">setModelName</A></B>(java.lang.String&nbsp;newmodelName)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of modelName.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setOptions(java.lang.String[])">setOptions</A></B>(java.lang.String[]&nbsp;options)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parses a given list of options controlling the behaviour of this object.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setStemmer(Stemmer)">setStemmer</A></B>(Stemmer&nbsp;newStemmer)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the Stemmer value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setStopwords(Stopwords)">setStopwords</A></B>(Stopwords&nbsp;newM_Stopwords)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the M_Stopwords value.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAModelBuilder.html#setUseKFrequency(boolean)">setUseKFrequency</A></B>(boolean&nbsp;newuseKFrequency)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set the value of useKFrequency.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="KEAModelBuilder()"><!-- --></A><H3>
+KEAModelBuilder</H3>
+<PRE>
+public <B>KEAModelBuilder</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="getCheckForProperNouns()"><!-- --></A><H3>
+getCheckForProperNouns</H3>
+<PRE>
+public boolean <B>getCheckForProperNouns</B>()</PRE>
+<DL>
+<DD>Get the M_CheckProperNouns value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the M_CheckProperNouns value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setCheckForProperNouns(boolean)"><!-- --></A><H3>
+setCheckForProperNouns</H3>
+<PRE>
+public void <B>setCheckForProperNouns</B>(boolean&nbsp;newM_CheckProperNouns)</PRE>
+<DL>
+<DD>Set the M_CheckProperNouns value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newM_CheckProperNouns</CODE> - The new M_CheckProperNouns value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getStopwords()"><!-- --></A><H3>
+getStopwords</H3>
+<PRE>
+public Stopwords <B>getStopwords</B>()</PRE>
+<DL>
+<DD>Get the M_Stopwords value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the M_Stopwords value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setStopwords(Stopwords)"><!-- --></A><H3>
+setStopwords</H3>
+<PRE>
+public void <B>setStopwords</B>(Stopwords&nbsp;newM_Stopwords)</PRE>
+<DL>
+<DD>Set the M_Stopwords value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newM_Stopwords</CODE> - The new M_Stopwords value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getStemmer()"><!-- --></A><H3>
+getStemmer</H3>
+<PRE>
+public Stemmer <B>getStemmer</B>()</PRE>
+<DL>
+<DD>Get the Stemmer value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>the Stemmer value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setStemmer(Stemmer)"><!-- --></A><H3>
+setStemmer</H3>
+<PRE>
+public void <B>setStemmer</B>(Stemmer&nbsp;newStemmer)</PRE>
+<DL>
+<DD>Set the Stemmer value.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newStemmer</CODE> - The new Stemmer value.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMinNumOccur()"><!-- --></A><H3>
+getMinNumOccur</H3>
+<PRE>
+public int <B>getMinNumOccur</B>()</PRE>
+<DL>
+<DD>Get the value of MinNumOccur.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of MinNumOccur.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setMinNumOccur(int)"><!-- --></A><H3>
+setMinNumOccur</H3>
+<PRE>
+public void <B>setMinNumOccur</B>(int&nbsp;newMinNumOccur)</PRE>
+<DL>
+<DD>Set the value of MinNumOccur.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newMinNumOccur</CODE> - Value to assign to MinNumOccur.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMaxPhraseLength()"><!-- --></A><H3>
+getMaxPhraseLength</H3>
+<PRE>
+public int <B>getMaxPhraseLength</B>()</PRE>
+<DL>
+<DD>Get the value of MaxPhraseLength.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of MaxPhraseLength.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setMaxPhraseLength(int)"><!-- --></A><H3>
+setMaxPhraseLength</H3>
+<PRE>
+public void <B>setMaxPhraseLength</B>(int&nbsp;newMaxPhraseLength)</PRE>
+<DL>
+<DD>Set the value of MaxPhraseLength.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newMaxPhraseLength</CODE> - Value to assign to MaxPhraseLength.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMinPhraseLength()"><!-- --></A><H3>
+getMinPhraseLength</H3>
+<PRE>
+public int <B>getMinPhraseLength</B>()</PRE>
+<DL>
+<DD>Get the value of MinPhraseLength.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of MinPhraseLength.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setMinPhraseLength(int)"><!-- --></A><H3>
+setMinPhraseLength</H3>
+<PRE>
+public void <B>setMinPhraseLength</B>(int&nbsp;newMinPhraseLength)</PRE>
+<DL>
+<DD>Set the value of MinPhraseLength.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newMinPhraseLength</CODE> - Value to assign to MinPhraseLength.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDisallowIPeriods()"><!-- --></A><H3>
+getDisallowIPeriods</H3>
+<PRE>
+public boolean <B>getDisallowIPeriods</B>()</PRE>
+<DL>
+<DD>Get the value of disallowIPeriods.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of disallowIPeriods.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDisallowIPeriods(boolean)"><!-- --></A><H3>
+setDisallowIPeriods</H3>
+<PRE>
+public void <B>setDisallowIPeriods</B>(boolean&nbsp;newdisallowIPeriods)</PRE>
+<DL>
+<DD>Set the value of disallowIPeriods.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newdisallowIPeriods</CODE> - Value to assign to disallowIPeriods.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getUseKFrequency()"><!-- --></A><H3>
+getUseKFrequency</H3>
+<PRE>
+public boolean <B>getUseKFrequency</B>()</PRE>
+<DL>
+<DD>Get the value of useKFrequency.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of useKFrequency.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setUseKFrequency(boolean)"><!-- --></A><H3>
+setUseKFrequency</H3>
+<PRE>
+public void <B>setUseKFrequency</B>(boolean&nbsp;newuseKFrequency)</PRE>
+<DL>
+<DD>Set the value of useKFrequency.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newuseKFrequency</CODE> - Value to assign to useKFrequency.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDebug()"><!-- --></A><H3>
+getDebug</H3>
+<PRE>
+public boolean <B>getDebug</B>()</PRE>
+<DL>
+<DD>Get the value of debug.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of debug.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDebug(boolean)"><!-- --></A><H3>
+setDebug</H3>
+<PRE>
+public void <B>setDebug</B>(boolean&nbsp;newdebug)</PRE>
+<DL>
+<DD>Set the value of debug.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newdebug</CODE> - Value to assign to debug.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getEncoding()"><!-- --></A><H3>
+getEncoding</H3>
+<PRE>
+public java.lang.String <B>getEncoding</B>()</PRE>
+<DL>
+<DD>Get the value of encoding.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of encoding.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setEncoding(java.lang.String)"><!-- --></A><H3>
+setEncoding</H3>
+<PRE>
+public void <B>setEncoding</B>(java.lang.String&nbsp;newencoding)</PRE>
+<DL>
+<DD>Set the value of encoding.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newencoding</CODE> - Value to assign to encoding.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getModelName()"><!-- --></A><H3>
+getModelName</H3>
+<PRE>
+public java.lang.String <B>getModelName</B>()</PRE>
+<DL>
+<DD>Get the value of modelName.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of modelName.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setModelName(java.lang.String)"><!-- --></A><H3>
+setModelName</H3>
+<PRE>
+public void <B>setModelName</B>(java.lang.String&nbsp;newmodelName)</PRE>
+<DL>
+<DD>Set the value of modelName.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newmodelName</CODE> - Value to assign to modelName.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDirName()"><!-- --></A><H3>
+getDirName</H3>
+<PRE>
+public java.lang.String <B>getDirName</B>()</PRE>
+<DL>
+<DD>Get the value of dirName.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>Value of dirName.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDirName(java.lang.String)"><!-- --></A><H3>
+setDirName</H3>
+<PRE>
+public void <B>setDirName</B>(java.lang.String&nbsp;newdirName)</PRE>
+<DL>
+<DD>Set the value of dirName.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>newdirName</CODE> - Value to assign to dirName.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setOptions(java.lang.String[])"><!-- --></A><H3>
+setOptions</H3>
+<PRE>
+public void <B>setOptions</B>(java.lang.String[]&nbsp;options)
+                throws java.lang.Exception</PRE>
+<DL>
+<DD>Parses a given list of options controlling the behaviour of this object.
+ Valid options are:<p>
+
+ -l "directory name" <br>
+ Specifies name of directory.<p>
+
+ -m "model name" <br>
+ Specifies name of model.<p>
+
+ -e "encoding" <br>
+ Specifies encoding.<p>
+
+ -d<br>
+ Turns debugging mode on.<p>
+
+ -k<br>
+ Use keyphrase frequency statistic.<p>
+
+ -p<br>
+ Disallow internal periods. <p>
+
+ -x "length"<br>
+ Sets maximum phrase length (default: 3).<p>
+
+ -y "length"<br>
+ Sets minimum phrase length (default: 3).<p>
+
+ -o "number"<br>
+ The minimum number of times a phrase needs to occur (default: 2). <p>
+
+ -s "name of class implementing list of stop words"<br>
+ Sets list of stop words to used (default: StopwordsEnglish).<p>
+
+ -t "name of class implementing stemmer"<br>
+ Sets stemmer to use (default: IteratedLovinsStemmer). <p>
+
+ -n<br>
+ Do not check for proper nouns. <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>setOptions</CODE> in interface <CODE>weka.core.OptionHandler</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>options</CODE> - the list of options as an array of strings
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.Exception</CODE> - if an option is not supported</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getOptions()"><!-- --></A><H3>
+getOptions</H3>
+<PRE>
+public java.lang.String[] <B>getOptions</B>()</PRE>
+<DL>
+<DD>Gets the current option settings.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>getOptions</CODE> in interface <CODE>weka.core.OptionHandler</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an array of strings suitable for passing to setOptions</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="listOptions()"><!-- --></A><H3>
+listOptions</H3>
+<PRE>
+public java.util.Enumeration <B>listOptions</B>()</PRE>
+<DL>
+<DD>Returns an enumeration describing the available options.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>listOptions</CODE> in interface <CODE>weka.core.OptionHandler</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an enumeration of all the available options</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="collectStems()"><!-- --></A><H3>
+collectStems</H3>
+<PRE>
+public java.util.Hashtable <B>collectStems</B>()
+                                 throws java.lang.Exception</PRE>
+<DL>
+<DD>Collects the stems of the file names.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DD><CODE>java.lang.Exception</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="buildModel(java.util.Hashtable)"><!-- --></A><H3>
+buildModel</H3>
+<PRE>
+public void <B>buildModel</B>(java.util.Hashtable&nbsp;stems)
+                throws java.lang.Exception</PRE>
+<DL>
+<DD>Builds the model from the files
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DD><CODE>java.lang.Exception</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="saveModel()"><!-- --></A><H3>
+saveModel</H3>
+<PRE>
+public void <B>saveModel</B>()
+               throws java.lang.Exception</PRE>
+<DL>
+<DD>Saves the extraction model to the file.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DD><CODE>java.lang.Exception</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(java.lang.String[]&nbsp;ops)</PRE>
+<DL>
+<DD>The main method.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="KEAKeyphraseExtractor.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="KEAPhraseFilter.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="KEAModelBuilder.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/KEAPhraseFilter.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/KEAPhraseFilter.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/KEAPhraseFilter.html	(revision 20131)
@@ -0,0 +1,817 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:49 NZDT 2004 -->
+<TITLE>
+KEAPhraseFilter
+</TITLE>
+<META NAME="keywords" CONTENT="KEAPhraseFilter,KEAPhraseFilter class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="KEAPhraseFilter";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="KEAModelBuilder.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="LovinsStemmer.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="KEAPhraseFilter.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class KEAPhraseFilter</H2>
+<PRE>
+java.lang.Object
+  |
+  +--weka.filters.Filter
+        |
+        +--<B>KEAPhraseFilter</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>weka.core.OptionHandler, java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>KEAPhraseFilter</B><DT>extends weka.filters.Filter<DT>implements weka.core.OptionHandler</DL>
+
+<P>
+This filter splits the text in selected string
+ attributes into phrases. The resulting
+ string attributes contain these phrases
+ separated by '\n' characters.
+
+ Phrases are identified according to the
+ following definitions:
+ 
+ A phrase is a sequence of words interrupted
+ only by sequences of whitespace characters,
+ where each sequence of whitespace characters
+ contains at most one '\n'.
+
+ A word is a sequence of letters or digits
+ that contains at least one letter, with
+ the following exceptions:
+
+ a) '.', '@', '_', '&', '/', '-' are allowed
+ if surrounded by letters or digits,
+
+ b) '\'' is allowed if preceeded by a letter
+ or digit,
+ 
+ c) '-', '/' are also allowed if succeeded by
+ whitespace characters followed by another
+ word. In that case the whitespace characters
+ will be deleted.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="serialized-form.html" TARGET="KEAPhraseFilter">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#m_DisallowInternalPeriods">m_DisallowInternalPeriods</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Determines whether internal periods are allowed</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>protected &nbsp;weka.core.Range</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#m_SelectCols">m_SelectCols</A></B></CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stores which columns to select as a funky range</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_weka.filters.Filter"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Fields inherited from class weka.filters.Filter</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>m_NewBatch</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#KEAPhraseFilter()">KEAPhraseFilter</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#attributeIndicesTipText()">attributeIndicesTipText</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the tip text for this property</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#batchFinished()">batchFinished</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Signify that this batch of input to the filter is finished.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#disallowInternalPeriodsTipText()">disallowInternalPeriodsTipText</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the tip text for this property</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#getAttributeIndices()">getAttributeIndices</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get the current range selection.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#getDisallowInternalPeriods()">getDisallowInternalPeriods</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get whether the supplied columns are to be processed</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#getInvertSelection()">getInvertSelection</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get whether the supplied columns are to be processed</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#getOptions()">getOptions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gets the current settings of the filter.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#globalInfo()">globalInfo</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a string describing this filter</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#input(weka.core.Instance)">input</A></B>(weka.core.Instance&nbsp;instance)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Input an instance for filtering.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#invertSelectionTipText()">invertSelectionTipText</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the tip text for this property</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.util.Enumeration</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#listOptions()">listOptions</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns an enumeration describing the available options</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#main(java.lang.String[])">main</A></B>(java.lang.String[]&nbsp;argv)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main method for testing this class.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#setAttributeIndices(java.lang.String)">setAttributeIndices</A></B>(java.lang.String&nbsp;rangeList)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set which attributes are to be processed</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#setAttributeIndicesArray(int[])">setAttributeIndicesArray</A></B>(int[]&nbsp;attributes)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set which attributes are to be processed</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#setDisallowInternalPeriods(boolean)">setDisallowInternalPeriods</A></B>(boolean&nbsp;disallow)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set whether selected columns should be processed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#setInputFormat(weka.core.Instances)">setInputFormat</A></B>(weka.core.Instances&nbsp;instanceInfo)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the format of the input instances.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#setInvertSelection(boolean)">setInvertSelection</A></B>(boolean&nbsp;invert)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set whether selected columns should be processed.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="KEAPhraseFilter.html#setOptions(java.lang.String[])">setOptions</A></B>(java.lang.String[]&nbsp;options)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Parses a given list of options controlling the behaviour of this object.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_weka.filters.Filter"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class weka.filters.Filter</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>batchFilterFile, bufferInput, copyStringValues, copyStringValues, filterFile, flushInput, getInputFormat, getInputStringIndex, getOutputFormat, getOutputStringIndex, getStringIndices, inputFormat, isOutputFormatDefined, numPendingOutput, output, outputFormat, outputFormatPeek, outputPeek, push, resetQueue, setOutputFormat, useFilter</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="m_SelectCols"><!-- --></A><H3>
+m_SelectCols</H3>
+<PRE>
+protected weka.core.Range <B>m_SelectCols</B></PRE>
+<DL>
+<DD>Stores which columns to select as a funky range
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<A NAME="m_DisallowInternalPeriods"><!-- --></A><H3>
+m_DisallowInternalPeriods</H3>
+<PRE>
+protected boolean <B>m_DisallowInternalPeriods</B></PRE>
+<DL>
+<DD>Determines whether internal periods are allowed
+<P>
+<DL>
+</DL>
+</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="KEAPhraseFilter()"><!-- --></A><H3>
+KEAPhraseFilter</H3>
+<PRE>
+public <B>KEAPhraseFilter</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="globalInfo()"><!-- --></A><H3>
+globalInfo</H3>
+<PRE>
+public java.lang.String <B>globalInfo</B>()</PRE>
+<DL>
+<DD>Returns a string describing this filter
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a description of the filter suitable for
+ displaying in the explorer/experimenter gui</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="listOptions()"><!-- --></A><H3>
+listOptions</H3>
+<PRE>
+public java.util.Enumeration <B>listOptions</B>()</PRE>
+<DL>
+<DD>Returns an enumeration describing the available options
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>listOptions</CODE> in interface <CODE>weka.core.OptionHandler</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an enumeration of all the available options</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setOptions(java.lang.String[])"><!-- --></A><H3>
+setOptions</H3>
+<PRE>
+public void <B>setOptions</B>(java.lang.String[]&nbsp;options)
+                throws java.lang.Exception</PRE>
+<DL>
+<DD>Parses a given list of options controlling the behaviour of this object.
+ Valid options are:<p>
+
+ -R index1,index2-index4,...<br>
+ Specify list of attributes to process. First and last are valid indexes.
+ (default none)<p>
+
+ -V<br>
+ Invert matching sense <p>
+
+ -P<br>
+ Disallow internal periods <p>
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>setOptions</CODE> in interface <CODE>weka.core.OptionHandler</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>options</CODE> - the list of options as an array of strings
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.Exception</CODE> - if an option is not supported</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getOptions()"><!-- --></A><H3>
+getOptions</H3>
+<PRE>
+public java.lang.String[] <B>getOptions</B>()</PRE>
+<DL>
+<DD>Gets the current settings of the filter.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE>getOptions</CODE> in interface <CODE>weka.core.OptionHandler</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>an array of strings suitable for passing to setOptions</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setInputFormat(weka.core.Instances)"><!-- --></A><H3>
+setInputFormat</H3>
+<PRE>
+public boolean <B>setInputFormat</B>(weka.core.Instances&nbsp;instanceInfo)
+                       throws java.lang.Exception</PRE>
+<DL>
+<DD>Sets the format of the input instances.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>setInputFormat</CODE> in class <CODE>weka.filters.Filter</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>instanceInfo</CODE> - an Instances object containing the input
+ instance structure (any instances contained in the object are
+ ignored - only the structure is required).
+<DT><B>Returns:</B><DD>true if the outputFormat may be collected immediately
+<DD><CODE>java.lang.Exception</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="input(weka.core.Instance)"><!-- --></A><H3>
+input</H3>
+<PRE>
+public boolean <B>input</B>(weka.core.Instance&nbsp;instance)
+              throws java.lang.Exception</PRE>
+<DL>
+<DD>Input an instance for filtering. Ordinarily the instance is processed
+ and made available for output immediately. Some filters require all
+ instances be read before producing output.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>input</CODE> in class <CODE>weka.filters.Filter</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>instance</CODE> - the input instance
+<DT><B>Returns:</B><DD>true if the filtered instance may now be
+ collected with output().
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.Exception</CODE> - if the input instance was not of the correct 
+ format or if there was a problem with the filtering.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="batchFinished()"><!-- --></A><H3>
+batchFinished</H3>
+<PRE>
+public boolean <B>batchFinished</B>()
+                      throws java.lang.Exception</PRE>
+<DL>
+<DD>Signify that this batch of input to the filter is finished. If
+ the filter requires all instances prior to filtering, output()
+ may now be called to retrieve the filtered instances. Any
+ subsequent instances filtered should be filtered based on setting
+ obtained from the first batch (unless the inputFormat has been
+ re-assigned or new options have been set). This default
+ implementation assumes all instance processing occurs during
+ inputFormat() and input().
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>batchFinished</CODE> in class <CODE>weka.filters.Filter</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if there are instances pending output
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.NullPointerException</CODE> - if no input structure has been defined,
+<DD><CODE>java.lang.Exception</CODE> - if there was a problem finishing the batch.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(java.lang.String[]&nbsp;argv)</PRE>
+<DL>
+<DD>Main method for testing this class.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>argv</CODE> - should contain arguments to the filter: use -h for help</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="invertSelectionTipText()"><!-- --></A><H3>
+invertSelectionTipText</H3>
+<PRE>
+public java.lang.String <B>invertSelectionTipText</B>()</PRE>
+<DL>
+<DD>Returns the tip text for this property
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>tip text for this property suitable for
+ displaying in the explorer/experimenter gui</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getInvertSelection()"><!-- --></A><H3>
+getInvertSelection</H3>
+<PRE>
+public boolean <B>getInvertSelection</B>()</PRE>
+<DL>
+<DD>Get whether the supplied columns are to be processed
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if the supplied columns won't be processed</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setInvertSelection(boolean)"><!-- --></A><H3>
+setInvertSelection</H3>
+<PRE>
+public void <B>setInvertSelection</B>(boolean&nbsp;invert)</PRE>
+<DL>
+<DD>Set whether selected columns should be processed. If true the 
+ selected columns won't be processed.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>invert</CODE> - the new invert setting</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="disallowInternalPeriodsTipText()"><!-- --></A><H3>
+disallowInternalPeriodsTipText</H3>
+<PRE>
+public java.lang.String <B>disallowInternalPeriodsTipText</B>()</PRE>
+<DL>
+<DD>Returns the tip text for this property
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>tip text for this property suitable for
+ displaying in the explorer/experimenter gui</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getDisallowInternalPeriods()"><!-- --></A><H3>
+getDisallowInternalPeriods</H3>
+<PRE>
+public boolean <B>getDisallowInternalPeriods</B>()</PRE>
+<DL>
+<DD>Get whether the supplied columns are to be processed
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if the supplied columns won't be processed</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setDisallowInternalPeriods(boolean)"><!-- --></A><H3>
+setDisallowInternalPeriods</H3>
+<PRE>
+public void <B>setDisallowInternalPeriods</B>(boolean&nbsp;disallow)</PRE>
+<DL>
+<DD>Set whether selected columns should be processed. If true the 
+ selected columns won't be processed.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="attributeIndicesTipText()"><!-- --></A><H3>
+attributeIndicesTipText</H3>
+<PRE>
+public java.lang.String <B>attributeIndicesTipText</B>()</PRE>
+<DL>
+<DD>Returns the tip text for this property
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>tip text for this property suitable for
+ displaying in the explorer/experimenter gui</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAttributeIndices()"><!-- --></A><H3>
+getAttributeIndices</H3>
+<PRE>
+public java.lang.String <B>getAttributeIndices</B>()</PRE>
+<DL>
+<DD>Get the current range selection.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a string containing a comma separated list of ranges</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAttributeIndices(java.lang.String)"><!-- --></A><H3>
+setAttributeIndices</H3>
+<PRE>
+public void <B>setAttributeIndices</B>(java.lang.String&nbsp;rangeList)</PRE>
+<DL>
+<DD>Set which attributes are to be processed
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>rangeList</CODE> - a string representing the list of attributes.  Since
+ the string will typically come from a user, attributes are indexed from
+ 1. <br>
+ eg: first-3,5,6-last</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setAttributeIndicesArray(int[])"><!-- --></A><H3>
+setAttributeIndicesArray</H3>
+<PRE>
+public void <B>setAttributeIndicesArray</B>(int[]&nbsp;attributes)</PRE>
+<DL>
+<DD>Set which attributes are to be processed
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>attributes</CODE> - an array containing indexes of attributes to select.
+ Since the array will typically come from a program, attributes are indexed
+ from 0.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="KEAModelBuilder.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="LovinsStemmer.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="KEAPhraseFilter.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#field_summary">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;<A HREF="#field_detail">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/LovinsStemmer.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/LovinsStemmer.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/LovinsStemmer.html	(revision 20131)
@@ -0,0 +1,289 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:50 NZDT 2004 -->
+<TITLE>
+LovinsStemmer
+</TITLE>
+<META NAME="keywords" CONTENT="LovinsStemmer,LovinsStemmer class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="LovinsStemmer";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="KEAPhraseFilter.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="NumbersFilter.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="LovinsStemmer.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class LovinsStemmer</H2>
+<PRE>
+java.lang.Object
+  |
+  +--<A HREF="Stemmer.html">Stemmer</A>
+        |
+        +--<B>LovinsStemmer</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<DL>
+<DT><B>Direct Known Subclasses:</B> <DD><A HREF="IteratedLovinsStemmer.html">IteratedLovinsStemmer</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>LovinsStemmer</B><DT>extends <A HREF="Stemmer.html">Stemmer</A><DT>implements java.io.Serializable</DL>
+
+<P>
+Implements the Lovins stemmer.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="serialized-form.html" TARGET="LovinsStemmer">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="LovinsStemmer.html#LovinsStemmer()">LovinsStemmer</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="LovinsStemmer.html#main(java.lang.String[])">main</A></B>(java.lang.String[]&nbsp;ops)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stems text coming into stdin and writes it to stdout.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="LovinsStemmer.html#stem(java.lang.String)">stem</A></B>(java.lang.String&nbsp;word)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns the stemmed version of the given word.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_Stemmer"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class <A HREF="Stemmer.html">Stemmer</A></B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="Stemmer.html#stemString(java.lang.String)">stemString</A></CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="LovinsStemmer()"><!-- --></A><H3>
+LovinsStemmer</H3>
+<PRE>
+public <B>LovinsStemmer</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="stem(java.lang.String)"><!-- --></A><H3>
+stem</H3>
+<PRE>
+public java.lang.String <B>stem</B>(java.lang.String&nbsp;word)</PRE>
+<DL>
+<DD>Returns the stemmed version of the given word.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="Stemmer.html#stem(java.lang.String)">stem</A></CODE> in class <CODE><A HREF="Stemmer.html">Stemmer</A></CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>word</CODE> - a string consisting of a single word</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(java.lang.String[]&nbsp;ops)</PRE>
+<DL>
+<DD>Stems text coming into stdin and writes it to stdout.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="KEAPhraseFilter.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="NumbersFilter.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="LovinsStemmer.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/NumbersFilter.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/NumbersFilter.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/NumbersFilter.html	(revision 20131)
@@ -0,0 +1,396 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:50 NZDT 2004 -->
+<TITLE>
+NumbersFilter
+</TITLE>
+<META NAME="keywords" CONTENT="NumbersFilter,NumbersFilter class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="NumbersFilter";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="LovinsStemmer.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="Stemmer.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="NumbersFilter.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#fields_inherited_from_class_weka.filters.Filter">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class NumbersFilter</H2>
+<PRE>
+java.lang.Object
+  |
+  +--weka.filters.Filter
+        |
+        +--<B>NumbersFilter</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>NumbersFilter</B><DT>extends weka.filters.Filter</DL>
+
+<P>
+Removes all numbers from all the string attributes in the given
+ dataset. Assumes that words are separated by whitespace.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="serialized-form.html" TARGET="NumbersFilter">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="fields_inherited_from_class_weka.filters.Filter"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Fields inherited from class weka.filters.Filter</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>m_NewBatch</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="NumbersFilter.html#NumbersFilter()">NumbersFilter</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="NumbersFilter.html#batchFinished()">batchFinished</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Signify that this batch of input to the filter is finished.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="NumbersFilter.html#globalInfo()">globalInfo</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a string describing this filter</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="NumbersFilter.html#input(weka.core.Instance)">input</A></B>(weka.core.Instance&nbsp;instance)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Input an instance for filtering.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static&nbsp;void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="NumbersFilter.html#main(java.lang.String[])">main</A></B>(java.lang.String[]&nbsp;argv)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main method for testing this class.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="NumbersFilter.html#setInputFormat(weka.core.Instances)">setInputFormat</A></B>(weka.core.Instances&nbsp;instanceInfo)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sets the format of the input instances.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_weka.filters.Filter"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class weka.filters.Filter</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>batchFilterFile, bufferInput, copyStringValues, copyStringValues, filterFile, flushInput, getInputFormat, getInputStringIndex, getOutputFormat, getOutputStringIndex, getStringIndices, inputFormat, isOutputFormatDefined, numPendingOutput, output, outputFormat, outputFormatPeek, outputPeek, push, resetQueue, setOutputFormat, useFilter</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="NumbersFilter()"><!-- --></A><H3>
+NumbersFilter</H3>
+<PRE>
+public <B>NumbersFilter</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="globalInfo()"><!-- --></A><H3>
+globalInfo</H3>
+<PRE>
+public java.lang.String <B>globalInfo</B>()</PRE>
+<DL>
+<DD>Returns a string describing this filter
+<P>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>a description of the filter suitable for
+ displaying in the explorer/experimenter gui</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="batchFinished()"><!-- --></A><H3>
+batchFinished</H3>
+<PRE>
+public boolean <B>batchFinished</B>()
+                      throws java.lang.Exception</PRE>
+<DL>
+<DD>Signify that this batch of input to the filter is finished. If
+ the filter requires all instances prior to filtering, output()
+ may now be called to retrieve the filtered instances. Any
+ subsequent instances filtered should be filtered based on setting
+ obtained from the first batch (unless the inputFormat has been
+ re-assigned or new options have been set). This default
+ implementation assumes all instance processing occurs during
+ inputFormat() and input().
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>batchFinished</CODE> in class <CODE>weka.filters.Filter</CODE></DL>
+</DD>
+<DD><DL>
+
+<DT><B>Returns:</B><DD>true if there are instances pending output
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.NullPointerException</CODE> - if no input structure has been defined,
+<DD><CODE>java.lang.Exception</CODE> - if there was a problem finishing the batch.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setInputFormat(weka.core.Instances)"><!-- --></A><H3>
+setInputFormat</H3>
+<PRE>
+public boolean <B>setInputFormat</B>(weka.core.Instances&nbsp;instanceInfo)
+                       throws java.lang.Exception</PRE>
+<DL>
+<DD>Sets the format of the input instances.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>setInputFormat</CODE> in class <CODE>weka.filters.Filter</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>instanceInfo</CODE> - an Instances object containing the input
+ instance structure (any instances contained in the object are
+ ignored - only the structure is required).
+<DT><B>Returns:</B><DD>true if the outputFormat may be collected immediately
+<DD><CODE>java.lang.Exception</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="input(weka.core.Instance)"><!-- --></A><H3>
+input</H3>
+<PRE>
+public boolean <B>input</B>(weka.core.Instance&nbsp;instance)
+              throws java.lang.Exception</PRE>
+<DL>
+<DD>Input an instance for filtering. Ordinarily the instance is processed
+ and made available for output immediately. Some filters require all
+ instances be read before producing output.
+<P>
+<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>input</CODE> in class <CODE>weka.filters.Filter</CODE></DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>instance</CODE> - the input instance
+<DT><B>Returns:</B><DD>true if the filtered instance may now be
+ collected with output().
+<DT><B>Throws:</B>
+<DD><CODE>java.lang.Exception</CODE> - if the input instance was not of the correct 
+ format or if there was a problem with the filtering.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(java.lang.String[]&nbsp;argv)</PRE>
+<DL>
+<DD>Main method for testing this class.
+<P>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>argv</CODE> - should contain arguments to the filter: use -h for help</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="LovinsStemmer.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="Stemmer.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="NumbersFilter.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;<A HREF="#fields_inherited_from_class_weka.filters.Filter">FIELD</A>&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/Stemmer.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/Stemmer.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/Stemmer.html	(revision 20131)
@@ -0,0 +1,278 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:50 NZDT 2004 -->
+<TITLE>
+Stemmer
+</TITLE>
+<META NAME="keywords" CONTENT="Stemmer,Stemmer class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="Stemmer";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="NumbersFilter.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="Stopwords.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Stemmer.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class Stemmer</H2>
+<PRE>
+java.lang.Object
+  |
+  +--<B>Stemmer</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<DL>
+<DT><B>Direct Known Subclasses:</B> <DD><A HREF="GermanStemmer.html">GermanStemmer</A>, <A HREF="LovinsStemmer.html">LovinsStemmer</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public abstract class <B>Stemmer</B><DT>extends java.lang.Object<DT>implements java.io.Serializable</DL>
+
+<P>
+Abstract class for stemmers.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="serialized-form.html" TARGET="Stemmer">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="Stemmer.html#Stemmer()">Stemmer</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>abstract &nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="Stemmer.html#stem(java.lang.String)">stem</A></B>(java.lang.String&nbsp;str)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Iterated stemming of the given word.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="Stemmer.html#stemString(java.lang.String)">stemString</A></B>(java.lang.String&nbsp;str)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stems everything in the given string.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="Stemmer()"><!-- --></A><H3>
+Stemmer</H3>
+<PRE>
+public <B>Stemmer</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="stem(java.lang.String)"><!-- --></A><H3>
+stem</H3>
+<PRE>
+public abstract java.lang.String <B>stem</B>(java.lang.String&nbsp;str)</PRE>
+<DL>
+<DD>Iterated stemming of the given word.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="stemString(java.lang.String)"><!-- --></A><H3>
+stemString</H3>
+<PRE>
+public java.lang.String <B>stemString</B>(java.lang.String&nbsp;str)</PRE>
+<DL>
+<DD>Stems everything in the given string.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="NumbersFilter.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="Stopwords.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Stemmer.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/Stopwords.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/Stopwords.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/Stopwords.html	(revision 20131)
@@ -0,0 +1,255 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:50 NZDT 2004 -->
+<TITLE>
+Stopwords
+</TITLE>
+<META NAME="keywords" CONTENT="Stopwords,Stopwords class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="Stopwords";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="Stemmer.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="StopwordsEnglish.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Stopwords.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class Stopwords</H2>
+<PRE>
+java.lang.Object
+  |
+  +--<B>Stopwords</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<DL>
+<DT><B>Direct Known Subclasses:</B> <DD><A HREF="StopwordsEnglish.html">StopwordsEnglish</A>, <A HREF="StopwordsGerman.html">StopwordsGerman</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public abstract class <B>Stopwords</B><DT>extends java.lang.Object<DT>implements java.io.Serializable</DL>
+
+<P>
+Class that can test whether a given string is a stop word.
+ Lowercases all words before the test.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="serialized-form.html" TARGET="Stopwords">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="Stopwords.html#Stopwords()">Stopwords</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>abstract &nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="Stopwords.html#isStopword(java.lang.String)">isStopword</A></B>(java.lang.String&nbsp;str)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if the given string is a stop word.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="Stopwords()"><!-- --></A><H3>
+Stopwords</H3>
+<PRE>
+public <B>Stopwords</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="isStopword(java.lang.String)"><!-- --></A><H3>
+isStopword</H3>
+<PRE>
+public abstract boolean <B>isStopword</B>(java.lang.String&nbsp;str)</PRE>
+<DL>
+<DD>Returns true if the given string is a stop word.
+<P>
+<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="Stemmer.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="StopwordsEnglish.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="Stopwords.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/StopwordsEnglish.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/StopwordsEnglish.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/StopwordsEnglish.html	(revision 20131)
@@ -0,0 +1,254 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:50 NZDT 2004 -->
+<TITLE>
+StopwordsEnglish
+</TITLE>
+<META NAME="keywords" CONTENT="StopwordsEnglish,StopwordsEnglish class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="StopwordsEnglish";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="Stopwords.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="StopwordsGerman.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="StopwordsEnglish.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class StopwordsEnglish</H2>
+<PRE>
+java.lang.Object
+  |
+  +--<A HREF="Stopwords.html">Stopwords</A>
+        |
+        +--<B>StopwordsEnglish</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>StopwordsEnglish</B><DT>extends <A HREF="Stopwords.html">Stopwords</A></DL>
+
+<P>
+Class that can test whether a given string is a stop word.
+ Lowercases all words before the test.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="serialized-form.html" TARGET="StopwordsEnglish">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="StopwordsEnglish.html#StopwordsEnglish()">StopwordsEnglish</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="StopwordsEnglish.html#isStopword(java.lang.String)">isStopword</A></B>(java.lang.String&nbsp;str)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if the given string is a stop word.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="StopwordsEnglish()"><!-- --></A><H3>
+StopwordsEnglish</H3>
+<PRE>
+public <B>StopwordsEnglish</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="isStopword(java.lang.String)"><!-- --></A><H3>
+isStopword</H3>
+<PRE>
+public boolean <B>isStopword</B>(java.lang.String&nbsp;str)</PRE>
+<DL>
+<DD>Returns true if the given string is a stop word.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="Stopwords.html#isStopword(java.lang.String)">isStopword</A></CODE> in class <CODE><A HREF="Stopwords.html">Stopwords</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="Stopwords.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;<A HREF="StopwordsGerman.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="StopwordsEnglish.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/StopwordsGerman.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/StopwordsGerman.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/StopwordsGerman.html	(revision 20131)
@@ -0,0 +1,259 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:50 NZDT 2004 -->
+<TITLE>
+StopwordsGerman
+</TITLE>
+<META NAME="keywords" CONTENT="StopwordsGerman,StopwordsGerman class">
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="StopwordsGerman";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="StopwordsEnglish.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="StopwordsGerman.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+Class StopwordsGerman</H2>
+<PRE>
+java.lang.Object
+  |
+  +--<A HREF="Stopwords.html">Stopwords</A>
+        |
+        +--<B>StopwordsGerman</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>StopwordsGerman</B><DT>extends <A HREF="Stopwords.html">Stopwords</A></DL>
+
+<P>
+Class that can test whether a given string is a stop word.
+ Lowercases all words before the test.
+
+ This list of German stop words has been obtained from
+ http://snowball.tartarus.org/german/stop.txt
+
+ But I have deleted/changed some words that I haven't seen before.
+<P>
+
+<P>
+<DL>
+<DT><B>See Also:</B><DD><A HREF="serialized-form.html" TARGET="StopwordsGerman">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="StopwordsGerman.html#StopwordsGerman()">StopwordsGerman</A></B>()</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>&nbsp;boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="StopwordsGerman.html#isStopword(java.lang.String)">isStopword</A></B>(java.lang.String&nbsp;str)</CODE>
+
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns true if the given string is a stop word.</TD>
+</TR>
+</TABLE>
+&nbsp;<A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+&nbsp;
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="StopwordsGerman()"><!-- --></A><H3>
+StopwordsGerman</H3>
+<PRE>
+public <B>StopwordsGerman</B>()</PRE>
+<DL>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="isStopword(java.lang.String)"><!-- --></A><H3>
+isStopword</H3>
+<PRE>
+public boolean <B>isStopword</B>(java.lang.String&nbsp;str)</PRE>
+<DL>
+<DD>Returns true if the given string is a stop word.
+<P>
+<DD><DL>
+<DT><B>Specified by:</B><DD><CODE><A HREF="Stopwords.html#isStopword(java.lang.String)">isStopword</A></CODE> in class <CODE><A HREF="Stopwords.html">Stopwords</A></CODE></DL>
+</DD>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">      <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;<A HREF="StopwordsEnglish.html"><B>PREV CLASS</B></A>&nbsp;
+&nbsp;NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="StopwordsGerman.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+  SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_summary">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL:&nbsp;FIELD&nbsp;|&nbsp;<A HREF="#constructor_detail">CONSTR</A>&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/allclasses-frame.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/allclasses-frame.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/allclasses-frame.html	(revision 20131)
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:48 NZDT 2004 -->
+<TITLE>
+All Classes
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="All Classes";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+<FONT size="+1" CLASS="FrameHeadingFont">
+<B>All Classes</B></FONT>
+<BR>
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="Counter.html" TARGET="classFrame">Counter</A>
+<BR>
+<A HREF="GermanStemmer.html" TARGET="classFrame">GermanStemmer</A>
+<BR>
+<A HREF="IteratedLovinsStemmer.html" TARGET="classFrame">IteratedLovinsStemmer</A>
+<BR>
+<A HREF="KEAFilter.html" TARGET="classFrame">KEAFilter</A>
+<BR>
+<A HREF="KEAKeyphraseExtractor.html" TARGET="classFrame">KEAKeyphraseExtractor</A>
+<BR>
+<A HREF="KEAModelBuilder.html" TARGET="classFrame">KEAModelBuilder</A>
+<BR>
+<A HREF="KEAPhraseFilter.html" TARGET="classFrame">KEAPhraseFilter</A>
+<BR>
+<A HREF="LovinsStemmer.html" TARGET="classFrame">LovinsStemmer</A>
+<BR>
+<A HREF="NumbersFilter.html" TARGET="classFrame">NumbersFilter</A>
+<BR>
+<A HREF="Stemmer.html" TARGET="classFrame">Stemmer</A>
+<BR>
+<A HREF="Stopwords.html" TARGET="classFrame">Stopwords</A>
+<BR>
+<A HREF="StopwordsEnglish.html" TARGET="classFrame">StopwordsEnglish</A>
+<BR>
+<A HREF="StopwordsGerman.html" TARGET="classFrame">StopwordsGerman</A>
+<BR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/allclasses-noframe.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/allclasses-noframe.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/allclasses-noframe.html	(revision 20131)
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:48 NZDT 2004 -->
+<TITLE>
+All Classes
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="All Classes";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+<FONT size="+1" CLASS="FrameHeadingFont">
+<B>All Classes</B></FONT>
+<BR>
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="Counter.html" TARGET="">Counter</A>
+<BR>
+<A HREF="GermanStemmer.html" TARGET="">GermanStemmer</A>
+<BR>
+<A HREF="IteratedLovinsStemmer.html" TARGET="">IteratedLovinsStemmer</A>
+<BR>
+<A HREF="KEAFilter.html" TARGET="">KEAFilter</A>
+<BR>
+<A HREF="KEAKeyphraseExtractor.html" TARGET="">KEAKeyphraseExtractor</A>
+<BR>
+<A HREF="KEAModelBuilder.html" TARGET="">KEAModelBuilder</A>
+<BR>
+<A HREF="KEAPhraseFilter.html" TARGET="">KEAPhraseFilter</A>
+<BR>
+<A HREF="LovinsStemmer.html" TARGET="">LovinsStemmer</A>
+<BR>
+<A HREF="NumbersFilter.html" TARGET="">NumbersFilter</A>
+<BR>
+<A HREF="Stemmer.html" TARGET="">Stemmer</A>
+<BR>
+<A HREF="Stopwords.html" TARGET="">Stopwords</A>
+<BR>
+<A HREF="StopwordsEnglish.html" TARGET="">StopwordsEnglish</A>
+<BR>
+<A HREF="StopwordsGerman.html" TARGET="">StopwordsGerman</A>
+<BR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/constant-values.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/constant-values.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/constant-values.html	(revision 20131)
@@ -0,0 +1,123 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:47 NZDT 2004 -->
+<TITLE>
+Constant Field Values
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="Constant Field Values";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="constant-values.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H1>
+Constant Field Values</H1>
+</CENTER>
+<HR SIZE="4" NOSHADE>
+<B>Contents</B><UL>
+</UL>
+
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="constant-values.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/deprecated-list.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/deprecated-list.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/deprecated-list.html	(revision 20131)
@@ -0,0 +1,119 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:48 NZDT 2004 -->
+<TITLE>
+Deprecated List
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="Deprecated List";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Deprecated</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="deprecated-list.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Deprecated API</B></H2>
+</CENTER>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Deprecated</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="deprecated-list.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/help-doc.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/help-doc.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/help-doc.html	(revision 20131)
@@ -0,0 +1,168 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:50 NZDT 2004 -->
+<TITLE>
+API Help
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="API Help";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="help-doc.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H1>
+How This API Document Is Organized</H1>
+</CENTER>
+This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.<H3>
+Package</H3>
+<BLOCKQUOTE>
+
+<P>
+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:<UL>
+<LI>Interfaces (italic)<LI>Classes<LI>Exceptions<LI>Errors</UL>
+</BLOCKQUOTE>
+<H3>
+Class/Interface</H3>
+<BLOCKQUOTE>
+
+<P>
+Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:<UL>
+<LI>Class inheritance diagram<LI>Direct Subclasses<LI>All Known Subinterfaces<LI>All Known Implementing Classes<LI>Class/interface declaration<LI>Class/interface description
+<P>
+<LI>Nested Class Summary<LI>Field Summary<LI>Constructor Summary<LI>Method Summary
+<P>
+<LI>Field Detail<LI>Constructor Detail<LI>Method Detail</UL>
+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.</BLOCKQUOTE>
+<H3>
+Tree (Class Hierarchy)</H3>
+<BLOCKQUOTE>
+There is a <A HREF="overview-tree.html">Class Hierarchy</A> page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with <code>java.lang.Object</code>. The interfaces do not inherit from <code>java.lang.Object</code>.<UL>
+<LI>When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.<LI>When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.</UL>
+</BLOCKQUOTE>
+<H3>
+Deprecated API</H3>
+<BLOCKQUOTE>
+The <A HREF="deprecated-list.html">Deprecated API</A> page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.</BLOCKQUOTE>
+<H3>
+Index</H3>
+<BLOCKQUOTE>
+The <A HREF="index-all.html">Index</A> contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.</BLOCKQUOTE>
+<H3>
+Prev/Next</H3>
+These links take you to the next or previous class, interface, package, or related page.<H3>
+Frames/No Frames</H3>
+These links show and hide the HTML frames.  All pages are available with or without frames.
+<P>
+<H3>
+Serialized Form</H3>
+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
+<P>
+<FONT SIZE="-1">
+<EM>
+This help file applies to API documentation generated using the standard doclet.</EM>
+</FONT>
+<BR>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="help-doc.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/index-all.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/index-all.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/index-all.html	(revision 20131)
@@ -0,0 +1,596 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:48 NZDT 2004 -->
+<TITLE>
+Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="Index";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="index-all.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="#_A_">A</A> <A HREF="#_B_">B</A> <A HREF="#_C_">C</A> <A HREF="#_D_">D</A> <A HREF="#_E_">E</A> <A HREF="#_G_">G</A> <A HREF="#_I_">I</A> <A HREF="#_K_">K</A> <A HREF="#_L_">L</A> <A HREF="#_M_">M</A> <A HREF="#_N_">N</A> <A HREF="#_S_">S</A> <A HREF="#_T_">T</A> <A HREF="#_V_">V</A> <HR>
+<A NAME="_A_"><!-- --></A><H2>
+<B>A</B></H2>
+<DL>
+<DT><A HREF="KEAPhraseFilter.html#attributeIndicesTipText()"><B>attributeIndicesTipText()</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Returns the tip text for this property
+</DL>
+<HR>
+<A NAME="_B_"><!-- --></A><H2>
+<B>B</B></H2>
+<DL>
+<DT><A HREF="KEAFilter.html#batchFinished()"><B>batchFinished()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Signify that this batch of input to the filter is finished.
+<DT><A HREF="KEAPhraseFilter.html#batchFinished()"><B>batchFinished()</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Signify that this batch of input to the filter is finished.
+<DT><A HREF="NumbersFilter.html#batchFinished()"><B>batchFinished()</B></A> - 
+Method in class <A HREF="NumbersFilter.html">NumbersFilter</A>
+<DD>Signify that this batch of input to the filter is finished.
+<DT><A HREF="KEAModelBuilder.html#buildModel(java.util.Hashtable)"><B>buildModel(Hashtable)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Builds the model from the files
+</DL>
+<HR>
+<A NAME="_C_"><!-- --></A><H2>
+<B>C</B></H2>
+<DL>
+<DT><A HREF="KEAKeyphraseExtractor.html#collectStems()"><B>collectStems()</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Collects the stems of the file names.
+<DT><A HREF="KEAModelBuilder.html#collectStems()"><B>collectStems()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Collects the stems of the file names.
+<DT><A HREF="Counter.html"><B>Counter</B></A> - class <A HREF="Counter.html">Counter</A>.<DD>Class that implements a simple counter.<DT><A HREF="Counter.html#Counter()"><B>Counter()</B></A> - 
+Constructor for class <A HREF="Counter.html">Counter</A>
+<DD>Initializes the counter to 1
+<DT><A HREF="Counter.html#Counter(int)"><B>Counter(int)</B></A> - 
+Constructor for class <A HREF="Counter.html">Counter</A>
+<DD>Initializes the counter to the given value
+</DL>
+<HR>
+<A NAME="_D_"><!-- --></A><H2>
+<B>D</B></H2>
+<DL>
+<DT><A HREF="KEAPhraseFilter.html#disallowInternalPeriodsTipText()"><B>disallowInternalPeriodsTipText()</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Returns the tip text for this property
+</DL>
+<HR>
+<A NAME="_E_"><!-- --></A><H2>
+<B>E</B></H2>
+<DL>
+<DT><A HREF="KEAKeyphraseExtractor.html#extractKeyphrases(java.util.Hashtable)"><B>extractKeyphrases(Hashtable)</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Builds the model from the files
+</DL>
+<HR>
+<A NAME="_G_"><!-- --></A><H2>
+<B>G</B></H2>
+<DL>
+<DT><A HREF="GermanStemmer.html"><B>GermanStemmer</B></A> - class <A HREF="GermanStemmer.html">GermanStemmer</A>.<DD>A stemmer for German words.<DT><A HREF="GermanStemmer.html#GermanStemmer()"><B>GermanStemmer()</B></A> - 
+Constructor for class <A HREF="GermanStemmer.html">GermanStemmer</A>
+<DD>&nbsp;
+<DT><A HREF="KEAKeyphraseExtractor.html#getAdditionalInfo()"><B>getAdditionalInfo()</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Get the value of AdditionalInfo.
+<DT><A HREF="KEAPhraseFilter.html#getAttributeIndices()"><B>getAttributeIndices()</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Get the current range selection.
+<DT><A HREF="KEAFilter.html#getCheckForProperNouns()"><B>getCheckForProperNouns()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Get the M_CheckProperNouns value.
+<DT><A HREF="KEAModelBuilder.html#getCheckForProperNouns()"><B>getCheckForProperNouns()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Get the M_CheckProperNouns value.
+<DT><A HREF="KEAFilter.html#getDebug()"><B>getDebug()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Get the value of Debug.
+<DT><A HREF="KEAKeyphraseExtractor.html#getDebug()"><B>getDebug()</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Get the value of debug.
+<DT><A HREF="KEAModelBuilder.html#getDebug()"><B>getDebug()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Get the value of debug.
+<DT><A HREF="KEAKeyphraseExtractor.html#getDirName()"><B>getDirName()</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Get the value of dirName.
+<DT><A HREF="KEAModelBuilder.html#getDirName()"><B>getDirName()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Get the value of dirName.
+<DT><A HREF="KEAFilter.html#getDisallowInternalPeriods()"><B>getDisallowInternalPeriods()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Get whether the supplied columns are to be processed
+<DT><A HREF="KEAPhraseFilter.html#getDisallowInternalPeriods()"><B>getDisallowInternalPeriods()</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Get whether the supplied columns are to be processed
+<DT><A HREF="KEAModelBuilder.html#getDisallowIPeriods()"><B>getDisallowIPeriods()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Get the value of disallowIPeriods.
+<DT><A HREF="KEAFilter.html#getDocumentAtt()"><B>getDocumentAtt()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Get the value of DocumentAtt.
+<DT><A HREF="KEAKeyphraseExtractor.html#getEncoding()"><B>getEncoding()</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Get the value of encoding.
+<DT><A HREF="KEAModelBuilder.html#getEncoding()"><B>getEncoding()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Get the value of encoding.
+<DT><A HREF="KEAPhraseFilter.html#getInvertSelection()"><B>getInvertSelection()</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Get whether the supplied columns are to be processed
+<DT><A HREF="KEAFilter.html#getKeyphrasesAtt()"><B>getKeyphrasesAtt()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Get the value of KeyphraseAtt.
+<DT><A HREF="KEAFilter.html#getKFused()"><B>getKFused()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Gets whether keyphrase frequency attribute is used.
+<DT><A HREF="KEAFilter.html#getMaxPhraseLength()"><B>getMaxPhraseLength()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Get the value of MaxPhraseLength.
+<DT><A HREF="KEAModelBuilder.html#getMaxPhraseLength()"><B>getMaxPhraseLength()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Get the value of MaxPhraseLength.
+<DT><A HREF="KEAFilter.html#getMinNumOccur()"><B>getMinNumOccur()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Get the value of MinNumOccur.
+<DT><A HREF="KEAModelBuilder.html#getMinNumOccur()"><B>getMinNumOccur()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Get the value of MinNumOccur.
+<DT><A HREF="KEAFilter.html#getMinPhraseLength()"><B>getMinPhraseLength()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Get the value of MinPhraseLength.
+<DT><A HREF="KEAModelBuilder.html#getMinPhraseLength()"><B>getMinPhraseLength()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Get the value of MinPhraseLength.
+<DT><A HREF="KEAKeyphraseExtractor.html#getModelName()"><B>getModelName()</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Get the value of modelName.
+<DT><A HREF="KEAModelBuilder.html#getModelName()"><B>getModelName()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Get the value of modelName.
+<DT><A HREF="KEAKeyphraseExtractor.html#getNumPhrases()"><B>getNumPhrases()</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Get the value of numPhrases.
+<DT><A HREF="KEAFilter.html#getOptions()"><B>getOptions()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Gets the current settings of the filter.
+<DT><A HREF="KEAKeyphraseExtractor.html#getOptions()"><B>getOptions()</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Gets the current option settings.
+<DT><A HREF="KEAModelBuilder.html#getOptions()"><B>getOptions()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Gets the current option settings.
+<DT><A HREF="KEAPhraseFilter.html#getOptions()"><B>getOptions()</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Gets the current settings of the filter.
+<DT><A HREF="KEAFilter.html#getProbabilityIndex()"><B>getProbabilityIndex()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Returns the index of the phrases' probabilities in the output ARFF file.
+<DT><A HREF="KEAFilter.html#getRankIndex()"><B>getRankIndex()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Returns the index of the phrases' ranks in the output ARFF file.
+<DT><A HREF="KEAFilter.html#getStemmedPhraseIndex()"><B>getStemmedPhraseIndex()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Returns the index of the stemmed phrases in the output ARFF file.
+<DT><A HREF="KEAFilter.html#getStemmer()"><B>getStemmer()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Get the Stemmer value.
+<DT><A HREF="KEAModelBuilder.html#getStemmer()"><B>getStemmer()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Get the Stemmer value.
+<DT><A HREF="KEAFilter.html#getStopwords()"><B>getStopwords()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Get the M_Stopwords value.
+<DT><A HREF="KEAModelBuilder.html#getStopwords()"><B>getStopwords()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Get the M_Stopwords value.
+<DT><A HREF="KEAFilter.html#getUnstemmedPhraseIndex()"><B>getUnstemmedPhraseIndex()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Returns the index of the unstemmed phrases in the output ARFF file.
+<DT><A HREF="KEAModelBuilder.html#getUseKFrequency()"><B>getUseKFrequency()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Get the value of useKFrequency.
+<DT><A HREF="KEAFilter.html#globalInfo()"><B>globalInfo()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Returns a string describing this filter
+<DT><A HREF="KEAPhraseFilter.html#globalInfo()"><B>globalInfo()</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Returns a string describing this filter
+<DT><A HREF="NumbersFilter.html#globalInfo()"><B>globalInfo()</B></A> - 
+Method in class <A HREF="NumbersFilter.html">NumbersFilter</A>
+<DD>Returns a string describing this filter
+</DL>
+<HR>
+<A NAME="_I_"><!-- --></A><H2>
+<B>I</B></H2>
+<DL>
+<DT><A HREF="Counter.html#increment()"><B>increment()</B></A> - 
+Method in class <A HREF="Counter.html">Counter</A>
+<DD>Increments the counter.
+<DT><A HREF="KEAFilter.html#input(weka.core.Instance)"><B>input(Instance)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Input an instance for filtering.
+<DT><A HREF="KEAPhraseFilter.html#input(weka.core.Instance)"><B>input(Instance)</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Input an instance for filtering.
+<DT><A HREF="NumbersFilter.html#input(weka.core.Instance)"><B>input(Instance)</B></A> - 
+Method in class <A HREF="NumbersFilter.html">NumbersFilter</A>
+<DD>Input an instance for filtering.
+<DT><A HREF="KEAPhraseFilter.html#invertSelectionTipText()"><B>invertSelectionTipText()</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Returns the tip text for this property
+<DT><A HREF="Stopwords.html#isStopword(java.lang.String)"><B>isStopword(String)</B></A> - 
+Method in class <A HREF="Stopwords.html">Stopwords</A>
+<DD>Returns true if the given string is a stop word.
+<DT><A HREF="StopwordsEnglish.html#isStopword(java.lang.String)"><B>isStopword(String)</B></A> - 
+Method in class <A HREF="StopwordsEnglish.html">StopwordsEnglish</A>
+<DD>Returns true if the given string is a stop word.
+<DT><A HREF="StopwordsGerman.html#isStopword(java.lang.String)"><B>isStopword(String)</B></A> - 
+Method in class <A HREF="StopwordsGerman.html">StopwordsGerman</A>
+<DD>Returns true if the given string is a stop word.
+<DT><A HREF="IteratedLovinsStemmer.html"><B>IteratedLovinsStemmer</B></A> - class <A HREF="IteratedLovinsStemmer.html">IteratedLovinsStemmer</A>.<DD>Implements the iterated version of the Lovins stemmer.<DT><A HREF="IteratedLovinsStemmer.html#IteratedLovinsStemmer()"><B>IteratedLovinsStemmer()</B></A> - 
+Constructor for class <A HREF="IteratedLovinsStemmer.html">IteratedLovinsStemmer</A>
+<DD>&nbsp;
+</DL>
+<HR>
+<A NAME="_K_"><!-- --></A><H2>
+<B>K</B></H2>
+<DL>
+<DT><A HREF="KEAFilter.html"><B>KEAFilter</B></A> - class <A HREF="KEAFilter.html">KEAFilter</A>.<DD>This filter converts the incoming data into data appropriate for
+ keyphrase classification.<DT><A HREF="KEAFilter.html#KEAFilter()"><B>KEAFilter()</B></A> - 
+Constructor for class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>&nbsp;
+<DT><A HREF="KEAKeyphraseExtractor.html"><B>KEAKeyphraseExtractor</B></A> - class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>.<DD>Extracts keyphrases from the documents in a given directory.<DT><A HREF="KEAKeyphraseExtractor.html#KEAKeyphraseExtractor()"><B>KEAKeyphraseExtractor()</B></A> - 
+Constructor for class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>&nbsp;
+<DT><A HREF="KEAModelBuilder.html"><B>KEAModelBuilder</B></A> - class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>.<DD>Builds a keyphrase extraction model from the documents in a given
+ directory.<DT><A HREF="KEAModelBuilder.html#KEAModelBuilder()"><B>KEAModelBuilder()</B></A> - 
+Constructor for class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>&nbsp;
+<DT><A HREF="KEAPhraseFilter.html"><B>KEAPhraseFilter</B></A> - class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>.<DD>This filter splits the text in selected string
+ attributes into phrases.<DT><A HREF="KEAPhraseFilter.html#KEAPhraseFilter()"><B>KEAPhraseFilter()</B></A> - 
+Constructor for class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>&nbsp;
+</DL>
+<HR>
+<A NAME="_L_"><!-- --></A><H2>
+<B>L</B></H2>
+<DL>
+<DT><A HREF="KEAFilter.html#listOptions()"><B>listOptions()</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Returns an enumeration describing the available options
+<DT><A HREF="KEAKeyphraseExtractor.html#listOptions()"><B>listOptions()</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Returns an enumeration describing the available options.
+<DT><A HREF="KEAModelBuilder.html#listOptions()"><B>listOptions()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Returns an enumeration describing the available options.
+<DT><A HREF="KEAPhraseFilter.html#listOptions()"><B>listOptions()</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Returns an enumeration describing the available options
+<DT><A HREF="KEAKeyphraseExtractor.html#loadModel()"><B>loadModel()</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Loads the extraction model from the file.
+<DT><A HREF="LovinsStemmer.html"><B>LovinsStemmer</B></A> - class <A HREF="LovinsStemmer.html">LovinsStemmer</A>.<DD>Implements the Lovins stemmer.<DT><A HREF="LovinsStemmer.html#LovinsStemmer()"><B>LovinsStemmer()</B></A> - 
+Constructor for class <A HREF="LovinsStemmer.html">LovinsStemmer</A>
+<DD>&nbsp;
+</DL>
+<HR>
+<A NAME="_M_"><!-- --></A><H2>
+<B>M</B></H2>
+<DL>
+<DT><A HREF="KEAPhraseFilter.html#m_DisallowInternalPeriods"><B>m_DisallowInternalPeriods</B></A> - 
+Variable in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Determines whether internal periods are allowed
+<DT><A HREF="KEAPhraseFilter.html#m_SelectCols"><B>m_SelectCols</B></A> - 
+Variable in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Stores which columns to select as a funky range
+<DT><A HREF="IteratedLovinsStemmer.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class <A HREF="IteratedLovinsStemmer.html">IteratedLovinsStemmer</A>
+<DD>Stems text coming into stdin and writes it to stdout.
+<DT><A HREF="KEAFilter.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Main method for testing this class.
+<DT><A HREF="KEAKeyphraseExtractor.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>The main method.
+<DT><A HREF="KEAModelBuilder.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>The main method.
+<DT><A HREF="KEAPhraseFilter.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Main method for testing this class.
+<DT><A HREF="LovinsStemmer.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class <A HREF="LovinsStemmer.html">LovinsStemmer</A>
+<DD>Stems text coming into stdin and writes it to stdout.
+<DT><A HREF="NumbersFilter.html#main(java.lang.String[])"><B>main(String[])</B></A> - 
+Static method in class <A HREF="NumbersFilter.html">NumbersFilter</A>
+<DD>Main method for testing this class.
+</DL>
+<HR>
+<A NAME="_N_"><!-- --></A><H2>
+<B>N</B></H2>
+<DL>
+<DT><A HREF="NumbersFilter.html"><B>NumbersFilter</B></A> - class <A HREF="NumbersFilter.html">NumbersFilter</A>.<DD>Removes all numbers from all the string attributes in the given
+ dataset.<DT><A HREF="NumbersFilter.html#NumbersFilter()"><B>NumbersFilter()</B></A> - 
+Constructor for class <A HREF="NumbersFilter.html">NumbersFilter</A>
+<DD>&nbsp;
+</DL>
+<HR>
+<A NAME="_S_"><!-- --></A><H2>
+<B>S</B></H2>
+<DL>
+<DT><A HREF="KEAModelBuilder.html#saveModel()"><B>saveModel()</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Saves the extraction model to the file.
+<DT><A HREF="KEAKeyphraseExtractor.html#setAdditionalInfo(boolean)"><B>setAdditionalInfo(boolean)</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Set the value of AdditionalInfo.
+<DT><A HREF="KEAPhraseFilter.html#setAttributeIndices(java.lang.String)"><B>setAttributeIndices(String)</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Set which attributes are to be processed
+<DT><A HREF="KEAPhraseFilter.html#setAttributeIndicesArray(int[])"><B>setAttributeIndicesArray(int[])</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Set which attributes are to be processed
+<DT><A HREF="KEAFilter.html#setCheckForProperNouns(boolean)"><B>setCheckForProperNouns(boolean)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Set the M_CheckProperNouns value.
+<DT><A HREF="KEAModelBuilder.html#setCheckForProperNouns(boolean)"><B>setCheckForProperNouns(boolean)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Set the M_CheckProperNouns value.
+<DT><A HREF="KEAFilter.html#setDebug(boolean)"><B>setDebug(boolean)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Set the value of Debug.
+<DT><A HREF="KEAKeyphraseExtractor.html#setDebug(boolean)"><B>setDebug(boolean)</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Set the value of debug.
+<DT><A HREF="KEAModelBuilder.html#setDebug(boolean)"><B>setDebug(boolean)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Set the value of debug.
+<DT><A HREF="KEAKeyphraseExtractor.html#setDirName(java.lang.String)"><B>setDirName(String)</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Set the value of dirName.
+<DT><A HREF="KEAModelBuilder.html#setDirName(java.lang.String)"><B>setDirName(String)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Set the value of dirName.
+<DT><A HREF="KEAFilter.html#setDisallowInternalPeriods(boolean)"><B>setDisallowInternalPeriods(boolean)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Set whether selected columns should be processed.
+<DT><A HREF="KEAPhraseFilter.html#setDisallowInternalPeriods(boolean)"><B>setDisallowInternalPeriods(boolean)</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Set whether selected columns should be processed.
+<DT><A HREF="KEAModelBuilder.html#setDisallowIPeriods(boolean)"><B>setDisallowIPeriods(boolean)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Set the value of disallowIPeriods.
+<DT><A HREF="KEAFilter.html#setDocumentAtt(int)"><B>setDocumentAtt(int)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Set the value of DocumentAtt.
+<DT><A HREF="KEAKeyphraseExtractor.html#setEncoding(java.lang.String)"><B>setEncoding(String)</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Set the value of encoding.
+<DT><A HREF="KEAModelBuilder.html#setEncoding(java.lang.String)"><B>setEncoding(String)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Set the value of encoding.
+<DT><A HREF="KEAFilter.html#setInputFormat(weka.core.Instances)"><B>setInputFormat(Instances)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Sets the format of the input instances.
+<DT><A HREF="KEAPhraseFilter.html#setInputFormat(weka.core.Instances)"><B>setInputFormat(Instances)</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Sets the format of the input instances.
+<DT><A HREF="NumbersFilter.html#setInputFormat(weka.core.Instances)"><B>setInputFormat(Instances)</B></A> - 
+Method in class <A HREF="NumbersFilter.html">NumbersFilter</A>
+<DD>Sets the format of the input instances.
+<DT><A HREF="KEAPhraseFilter.html#setInvertSelection(boolean)"><B>setInvertSelection(boolean)</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Set whether selected columns should be processed.
+<DT><A HREF="KEAFilter.html#setKeyphrasesAtt(int)"><B>setKeyphrasesAtt(int)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Set the value of KeyphrasesAtt.
+<DT><A HREF="KEAFilter.html#setKFused(boolean)"><B>setKFused(boolean)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Sets whether keyphrase frequency attribute is used.
+<DT><A HREF="KEAFilter.html#setMaxPhraseLength(int)"><B>setMaxPhraseLength(int)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Set the value of MaxPhraseLength.
+<DT><A HREF="KEAModelBuilder.html#setMaxPhraseLength(int)"><B>setMaxPhraseLength(int)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Set the value of MaxPhraseLength.
+<DT><A HREF="KEAFilter.html#setMinNumOccur(int)"><B>setMinNumOccur(int)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Set the value of MinNumOccur.
+<DT><A HREF="KEAModelBuilder.html#setMinNumOccur(int)"><B>setMinNumOccur(int)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Set the value of MinNumOccur.
+<DT><A HREF="KEAFilter.html#setMinPhraseLength(int)"><B>setMinPhraseLength(int)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Set the value of MinPhraseLength.
+<DT><A HREF="KEAModelBuilder.html#setMinPhraseLength(int)"><B>setMinPhraseLength(int)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Set the value of MinPhraseLength.
+<DT><A HREF="KEAKeyphraseExtractor.html#setModelName(java.lang.String)"><B>setModelName(String)</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Set the value of modelName.
+<DT><A HREF="KEAModelBuilder.html#setModelName(java.lang.String)"><B>setModelName(String)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Set the value of modelName.
+<DT><A HREF="KEAKeyphraseExtractor.html#setNumPhrases(int)"><B>setNumPhrases(int)</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Set the value of numPhrases.
+<DT><A HREF="KEAFilter.html#setOptions(java.lang.String[])"><B>setOptions(String[])</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Parses a given list of options controlling the behaviour of this object.
+<DT><A HREF="KEAKeyphraseExtractor.html#setOptions(java.lang.String[])"><B>setOptions(String[])</B></A> - 
+Method in class <A HREF="KEAKeyphraseExtractor.html">KEAKeyphraseExtractor</A>
+<DD>Parses a given list of options controlling the behaviour of this object.
+<DT><A HREF="KEAModelBuilder.html#setOptions(java.lang.String[])"><B>setOptions(String[])</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Parses a given list of options controlling the behaviour of this object.
+<DT><A HREF="KEAPhraseFilter.html#setOptions(java.lang.String[])"><B>setOptions(String[])</B></A> - 
+Method in class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A>
+<DD>Parses a given list of options controlling the behaviour of this object.
+<DT><A HREF="KEAFilter.html#setStemmer(Stemmer)"><B>setStemmer(Stemmer)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Set the Stemmer value.
+<DT><A HREF="KEAModelBuilder.html#setStemmer(Stemmer)"><B>setStemmer(Stemmer)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Set the Stemmer value.
+<DT><A HREF="KEAFilter.html#setStopwords(Stopwords)"><B>setStopwords(Stopwords)</B></A> - 
+Method in class <A HREF="KEAFilter.html">KEAFilter</A>
+<DD>Set the M_Stopwords value.
+<DT><A HREF="KEAModelBuilder.html#setStopwords(Stopwords)"><B>setStopwords(Stopwords)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Set the M_Stopwords value.
+<DT><A HREF="KEAModelBuilder.html#setUseKFrequency(boolean)"><B>setUseKFrequency(boolean)</B></A> - 
+Method in class <A HREF="KEAModelBuilder.html">KEAModelBuilder</A>
+<DD>Set the value of useKFrequency.
+<DT><A HREF="GermanStemmer.html#stem(java.lang.String)"><B>stem(String)</B></A> - 
+Method in class <A HREF="GermanStemmer.html">GermanStemmer</A>
+<DD>Stemms the given term to an unique <tt>discriminator</tt>.
+<DT><A HREF="IteratedLovinsStemmer.html#stem(java.lang.String)"><B>stem(String)</B></A> - 
+Method in class <A HREF="IteratedLovinsStemmer.html">IteratedLovinsStemmer</A>
+<DD>Iterated stemming of the given word.
+<DT><A HREF="LovinsStemmer.html#stem(java.lang.String)"><B>stem(String)</B></A> - 
+Method in class <A HREF="LovinsStemmer.html">LovinsStemmer</A>
+<DD>Returns the stemmed version of the given word.
+<DT><A HREF="Stemmer.html#stem(java.lang.String)"><B>stem(String)</B></A> - 
+Method in class <A HREF="Stemmer.html">Stemmer</A>
+<DD>Iterated stemming of the given word.
+<DT><A HREF="Stemmer.html"><B>Stemmer</B></A> - class <A HREF="Stemmer.html">Stemmer</A>.<DD>Abstract class for stemmers.<DT><A HREF="Stemmer.html#Stemmer()"><B>Stemmer()</B></A> - 
+Constructor for class <A HREF="Stemmer.html">Stemmer</A>
+<DD>&nbsp;
+<DT><A HREF="Stemmer.html#stemString(java.lang.String)"><B>stemString(String)</B></A> - 
+Method in class <A HREF="Stemmer.html">Stemmer</A>
+<DD>Stems everything in the given string.
+<DT><A HREF="Stopwords.html"><B>Stopwords</B></A> - class <A HREF="Stopwords.html">Stopwords</A>.<DD>Class that can test whether a given string is a stop word.<DT><A HREF="Stopwords.html#Stopwords()"><B>Stopwords()</B></A> - 
+Constructor for class <A HREF="Stopwords.html">Stopwords</A>
+<DD>&nbsp;
+<DT><A HREF="StopwordsEnglish.html"><B>StopwordsEnglish</B></A> - class <A HREF="StopwordsEnglish.html">StopwordsEnglish</A>.<DD>Class that can test whether a given string is a stop word.<DT><A HREF="StopwordsEnglish.html#StopwordsEnglish()"><B>StopwordsEnglish()</B></A> - 
+Constructor for class <A HREF="StopwordsEnglish.html">StopwordsEnglish</A>
+<DD>&nbsp;
+<DT><A HREF="StopwordsGerman.html"><B>StopwordsGerman</B></A> - class <A HREF="StopwordsGerman.html">StopwordsGerman</A>.<DD>Class that can test whether a given string is a stop word.<DT><A HREF="StopwordsGerman.html#StopwordsGerman()"><B>StopwordsGerman()</B></A> - 
+Constructor for class <A HREF="StopwordsGerman.html">StopwordsGerman</A>
+<DD>&nbsp;
+</DL>
+<HR>
+<A NAME="_T_"><!-- --></A><H2>
+<B>T</B></H2>
+<DL>
+<DT><A HREF="Counter.html#toString()"><B>toString()</B></A> - 
+Method in class <A HREF="Counter.html">Counter</A>
+<DD>Returns string containing value.
+</DL>
+<HR>
+<A NAME="_V_"><!-- --></A><H2>
+<B>V</B></H2>
+<DL>
+<DT><A HREF="Counter.html#value()"><B>value()</B></A> - 
+Method in class <A HREF="Counter.html">Counter</A>
+<DD>Gets the value.
+</DL>
+<HR>
+<A HREF="#_A_">A</A> <A HREF="#_B_">B</A> <A HREF="#_C_">C</A> <A HREF="#_D_">D</A> <A HREF="#_E_">E</A> <A HREF="#_G_">G</A> <A HREF="#_I_">I</A> <A HREF="#_K_">K</A> <A HREF="#_L_">L</A> <A HREF="#_M_">M</A> <A HREF="#_N_">N</A> <A HREF="#_S_">S</A> <A HREF="#_T_">T</A> <A HREF="#_V_">V</A> 
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="index-all.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/index.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/index.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/index.html	(revision 20131)
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:48 NZDT 2004-->
+<TITLE>
+Generated Documentation (Untitled)
+</TITLE>
+</HEAD>
+<FRAMESET cols="20%,80%">
+<FRAME src="allclasses-frame.html" name="packageFrame">
+<FRAME src="Counter.html" name="classFrame">
+</FRAMESET>
+<NOFRAMES>
+<H2>
+Frame Alert</H2>
+
+<P>
+This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+<BR>
+Link to<A HREF="Counter.html">Non-frame version.</A></NOFRAMES>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/overview-tree.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/overview-tree.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/overview-tree.html	(revision 20131)
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:48 NZDT 2004 -->
+<TITLE>
+Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="Class Hierarchy";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="overview-tree.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For All Packages</H2>
+</CENTER>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class <A HREF="Counter.html"><B>Counter</B></A> (implements java.io.Serializable)
+<LI TYPE="circle">class weka.filters.Filter (implements java.io.Serializable)
+<UL>
+<LI TYPE="circle">class <A HREF="KEAFilter.html"><B>KEAFilter</B></A> (implements weka.core.OptionHandler)
+<LI TYPE="circle">class <A HREF="KEAPhraseFilter.html"><B>KEAPhraseFilter</B></A> (implements weka.core.OptionHandler)
+<LI TYPE="circle">class <A HREF="NumbersFilter.html"><B>NumbersFilter</B></A></UL>
+<LI TYPE="circle">class <A HREF="KEAKeyphraseExtractor.html"><B>KEAKeyphraseExtractor</B></A> (implements weka.core.OptionHandler)
+<LI TYPE="circle">class <A HREF="KEAModelBuilder.html"><B>KEAModelBuilder</B></A> (implements weka.core.OptionHandler)
+<LI TYPE="circle">class <A HREF="Stemmer.html"><B>Stemmer</B></A> (implements java.io.Serializable)
+<UL>
+<LI TYPE="circle">class <A HREF="GermanStemmer.html"><B>GermanStemmer</B></A><LI TYPE="circle">class <A HREF="LovinsStemmer.html"><B>LovinsStemmer</B></A> (implements java.io.Serializable)
+<UL>
+<LI TYPE="circle">class <A HREF="IteratedLovinsStemmer.html"><B>IteratedLovinsStemmer</B></A></UL>
+</UL>
+<LI TYPE="circle">class <A HREF="Stopwords.html"><B>Stopwords</B></A> (implements java.io.Serializable)
+<UL>
+<LI TYPE="circle">class <A HREF="StopwordsEnglish.html"><B>StopwordsEnglish</B></A><LI TYPE="circle">class <A HREF="StopwordsGerman.html"><B>StopwordsGerman</B></A></UL>
+</UL>
+</UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="overview-tree.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/package-list
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/package-list	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/package-list	(revision 20131)
@@ -0,0 +1,1 @@
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/packages.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/packages.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/packages.html	(revision 20131)
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:48 NZDT 2004 -->
+<TITLE>
+
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<BR>
+
+<BR>
+
+<BR>
+<CENTER>
+The front page has been relocated.Please see:
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="index.html">Frame version</A>
+<BR>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<A HREF="Counter.html">Non-frame version.</A></CENTER>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/serialized-form.html
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/serialized-form.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/serialized-form.html	(revision 20131)
@@ -0,0 +1,604 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Fri Mar 19 17:50:50 NZDT 2004 -->
+<TITLE>
+Serialized Form
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<SCRIPT>
+function asd()
+{
+parent.document.title="Serialized Form";
+}
+</SCRIPT>
+<BODY BGCOLOR="white" onload="asd();">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="serialized-form.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H1>
+Serialized Form</H1>
+</CENTER>
+<A NAME="Counter"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="Counter.html">Counter</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TD>
+</TR>
+</TABLE>
+
+<H3>
+m_val</H3>
+<PRE>
+int <B>m_val</B></PRE>
+<DL>
+<DD>Integer value stored
+<P>
+<DL>
+</DL>
+</DL>
+
+<P>
+<HR SIZE="4" NOSHADE>
+<A NAME="GermanStemmer"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="GermanStemmer.html">GermanStemmer</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TD>
+</TR>
+</TABLE>
+
+<H3>
+sb</H3>
+<PRE>
+java.lang.StringBuffer <B>sb</B></PRE>
+<DL>
+<DD>Buffer for the terms while stemming them.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+uppercase</H3>
+<PRE>
+boolean <B>uppercase</B></PRE>
+<DL>
+<DD>Indicates if a term is handled as a noun.
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+substCount</H3>
+<PRE>
+int <B>substCount</B></PRE>
+<DL>
+<DD>Amount of characters that are removed with <tt>substitute()</tt> while stemming.
+<P>
+<DL>
+</DL>
+</DL>
+
+<P>
+<HR SIZE="4" NOSHADE>
+<A NAME="IteratedLovinsStemmer"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="IteratedLovinsStemmer.html">IteratedLovinsStemmer</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<HR SIZE="4" NOSHADE>
+<A NAME="KEAFilter"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="KEAFilter.html">KEAFilter</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TD>
+</TR>
+</TABLE>
+
+<H3>
+m_DocumentAtt</H3>
+<PRE>
+int <B>m_DocumentAtt</B></PRE>
+<DL>
+<DD>Index of attribute containing the documents
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_KeyphrasesAtt</H3>
+<PRE>
+int <B>m_KeyphrasesAtt</B></PRE>
+<DL>
+<DD>Index of attribute containing the keyphrases
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_MaxPhraseLength</H3>
+<PRE>
+int <B>m_MaxPhraseLength</B></PRE>
+<DL>
+<DD>The maximum length of phrases
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_MinPhraseLength</H3>
+<PRE>
+int <B>m_MinPhraseLength</B></PRE>
+<DL>
+<DD>The minimum length of phrases
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_KFused</H3>
+<PRE>
+boolean <B>m_KFused</B></PRE>
+<DL>
+<DD>Is keyphrase frequency attribute being used?
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_Debug</H3>
+<PRE>
+boolean <B>m_Debug</B></PRE>
+<DL>
+<DD>Flag for debugging mode
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_DisallowInternalPeriods</H3>
+<PRE>
+boolean <B>m_DisallowInternalPeriods</B></PRE>
+<DL>
+<DD>Determines whether internal periods are allowed
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_MinNumOccur</H3>
+<PRE>
+int <B>m_MinNumOccur</B></PRE>
+<DL>
+<DD>The minimum number of occurences of a phrase
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_NumFeatures</H3>
+<PRE>
+int <B>m_NumFeatures</B></PRE>
+<DL>
+<DD>The number of features describing a phrase
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_TfidfIndex</H3>
+<PRE>
+int <B>m_TfidfIndex</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_FirstOccurIndex</H3>
+<PRE>
+int <B>m_FirstOccurIndex</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_KeyFreqIndex</H3>
+<PRE>
+int <B>m_KeyFreqIndex</B></PRE>
+<DL>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_PunctFilter</H3>
+<PRE>
+KEAPhraseFilter <B>m_PunctFilter</B></PRE>
+<DL>
+<DD>The punctuation filter used by this filter
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_NumbersFilter</H3>
+<PRE>
+NumbersFilter <B>m_NumbersFilter</B></PRE>
+<DL>
+<DD>The numbers filter used by this filter
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_Classifier</H3>
+<PRE>
+weka.classifiers.DistributionClassifier <B>m_Classifier</B></PRE>
+<DL>
+<DD>The actual classifier used to compute probabilities
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_Dictionary</H3>
+<PRE>
+java.util.HashMap <B>m_Dictionary</B></PRE>
+<DL>
+<DD>The dictionary containing the document frequencies
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_KeyphraseDictionary</H3>
+<PRE>
+java.util.HashMap <B>m_KeyphraseDictionary</B></PRE>
+<DL>
+<DD>The dictionary containing the keyphrases
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_NumDocs</H3>
+<PRE>
+int <B>m_NumDocs</B></PRE>
+<DL>
+<DD>The number of documents in the global frequencies corpus
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_ClassifierData</H3>
+<PRE>
+weka.core.Instances <B>m_ClassifierData</B></PRE>
+<DL>
+<DD>Template for the classifier data
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_Stemmer</H3>
+<PRE>
+Stemmer <B>m_Stemmer</B></PRE>
+<DL>
+<DD>The stemmer to be used
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_Stopwords</H3>
+<PRE>
+Stopwords <B>m_Stopwords</B></PRE>
+<DL>
+<DD>The list of stop words to be used
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_CheckForProperNouns</H3>
+<PRE>
+boolean <B>m_CheckForProperNouns</B></PRE>
+<DL>
+<DD>Determines whether check for proper nouns is performed
+<P>
+<DL>
+</DL>
+</DL>
+
+<P>
+<HR SIZE="4" NOSHADE>
+<A NAME="KEAPhraseFilter"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="KEAPhraseFilter.html">KEAPhraseFilter</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TD>
+</TR>
+</TABLE>
+
+<H3>
+m_SelectCols</H3>
+<PRE>
+weka.core.Range <B>m_SelectCols</B></PRE>
+<DL>
+<DD>Stores which columns to select as a funky range
+<P>
+<DL>
+</DL>
+</DL>
+<HR>
+
+<H3>
+m_DisallowInternalPeriods</H3>
+<PRE>
+boolean <B>m_DisallowInternalPeriods</B></PRE>
+<DL>
+<DD>Determines whether internal periods are allowed
+<P>
+<DL>
+</DL>
+</DL>
+
+<P>
+<HR SIZE="4" NOSHADE>
+<A NAME="LovinsStemmer"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="LovinsStemmer.html">LovinsStemmer</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<HR SIZE="4" NOSHADE>
+<A NAME="NumbersFilter"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="NumbersFilter.html">NumbersFilter</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<HR SIZE="4" NOSHADE>
+<A NAME="Stemmer"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="Stemmer.html">Stemmer</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<HR SIZE="4" NOSHADE>
+<A NAME="Stopwords"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="Stopwords.html">Stopwords</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<HR SIZE="4" NOSHADE>
+<A NAME="StopwordsEnglish"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="StopwordsEnglish.html">StopwordsEnglish</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<HR SIZE="4" NOSHADE>
+<A NAME="StopwordsGerman"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="StopwordsGerman.html">StopwordsGerman</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+  <TR ALIGN="center" VALIGN="top">
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
+  <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1">    <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
+  </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+&nbsp;PREV&nbsp;
+&nbsp;NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+  <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>  &nbsp;
+&nbsp;<A HREF="serialized-form.html" TARGET="_top"><B>NO FRAMES</B></A>  &nbsp;
+&nbsp;
+<SCRIPT>
+  <!--
+  if(window==top) {
+    document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
+  }
+  //-->
+</SCRIPT>
+<NOSCRIPT>
+<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
+</NOSCRIPT>
+</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/doc/stylesheet.css
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/doc/stylesheet.css	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/doc/stylesheet.css	(revision 20131)
@@ -0,0 +1,29 @@
+/* Javadoc style sheet */
+
+/* Define colors, fonts and other style attributes here to override the defaults */
+
+/* Page background color */
+body { background-color: #FFFFFF }
+
+/* Table colors */
+.TableHeadingColor     { background: #CCCCFF } /* Dark mauve */
+.TableSubHeadingColor  { background: #EEEEFF } /* Light mauve */
+.TableRowColor         { background: #FFFFFF } /* White */
+
+/* Font used in left-hand frame lists */
+.FrameTitleFont   { font-size: 10pts; font-family: Helvetica, Arial, san-serif }
+.FrameHeadingFont { font-size: 10pts; font-family: Helvetica, Arial, san-serif }
+.FrameItemFont    { font-size: 10pts; font-family: Helvetica, Arial, san-serif }
+
+/* Example of smaller, sans-serif font in frames */
+/* .FrameItemFont  { font-size: 10pt; font-family: Helvetica, Arial, sans-serif } */
+
+/* Navigation bar fonts and colors */
+.NavBarCell1    { background-color:#EEEEFF;}/* Light mauve */
+.NavBarCell1Rev { background-color:#00008B;}/* Dark Blue */
+.NavBarFont1    { font-family: Arial, Helvetica, sans-serif; color:#000000;}
+.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}
+
+.NavBarCell2    { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
+.NavBarCell3    { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/classifiers/Classifier.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/classifiers/Classifier.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/classifiers/Classifier.java	(revision 20131)
@@ -0,0 +1,115 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    Classifier.java
+ *    Copyright (C) 1999 Eibe Frank, Len Trigg
+ *
+ */
+
+package weka.classifiers;
+
+import java.io.Serializable;
+import weka.core.Instance;
+import weka.core.Instances;
+import weka.core.SerializedObject;
+import weka.core.Utils;
+
+
+/** 
+ * Abstract classifier. All schemes for numeric or nominal prediction in
+ * Weka extend this class.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @author Len Trigg (trigg@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public abstract class Classifier implements Cloneable, Serializable {
+ 
+  /**
+   * Generates a classifier. Must initialize all fields of the classifier
+   * that are not being set via options (ie. multiple calls of buildClassifier
+   * must always lead to the same result). Must not change the dataset
+   * in any way.
+   *
+   * @param data set of instances serving as training data 
+   * @exception Exception if the classifier has not been 
+   * generated successfully
+   */
+  public abstract void buildClassifier(Instances data) throws Exception;
+
+  /**
+   * Classifies a given instance.
+   *
+   * @param instance the instance to be classified
+   * @return index of the predicted class as a double
+   * if the class is nominal, otherwise the predicted value
+   * @exception Exception if instance could not be classified
+   * successfully
+   */
+  public abstract double classifyInstance(Instance instance) throws Exception; 
+
+
+  
+  /**
+   * Creates a new instance of a classifier given it's class name and
+   * (optional) arguments to pass to it's setOptions method. If the
+   * classifier implements OptionHandler and the options parameter is
+   * non-null, the classifier will have it's options set.
+   *
+   * @param classifierName the fully qualified class name of the classifier
+   * @param options an array of options suitable for passing to setOptions. May
+   * be null.
+   * @return the newly created classifier, ready for use.
+   * @exception Exception if the classifier name is invalid, or the options
+   * supplied are not acceptable to the classifier
+   */
+  public static Classifier forName(String classifierName,
+				   String [] options) throws Exception {
+
+    return (Classifier)Utils.forName(Classifier.class,
+				     classifierName,
+				     options);
+  }
+
+  /**
+   * Creates copies of the current classifier, which can then
+   * be used for boosting etc. Note that this method now uses
+   * Serialization to perform a deep copy, so the Classifier
+   * object must be fully Serializable. Any currently built model
+   * will now be copied as well.
+   *
+   * @param model an example classifier to copy
+   * @param num the number of classifiers copies to create.
+   * @return an array of classifiers.
+   * @exception Exception if an error occurs
+   */
+  public static Classifier [] makeCopies(Classifier model,
+					 int num) throws Exception {
+
+    if (model == null) {
+      throw new Exception("No model classifier set");
+    }
+    Classifier [] classifiers = new Classifier [num];
+    SerializedObject so = new SerializedObject(model);
+    for(int i = 0; i < classifiers.length; i++) {
+      classifiers[i] = (Classifier) so.getObject();
+    }
+    return classifiers;
+  }
+
+}
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/classifiers/DistributionClassifier.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/classifiers/DistributionClassifier.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/classifiers/DistributionClassifier.java	(revision 20131)
@@ -0,0 +1,92 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    DistributionClassifier.java
+ *    Copyright (C) 1999 Eibe Frank, Len Trigg
+ *
+ */
+
+package weka.classifiers;
+
+import weka.core.*;
+
+/** 
+ * Abstract classification model that produces (for each test instance)
+ * an estimate of the membership in each class 
+ * (ie. a probability distribution).
+ *
+ * @author   Eibe Frank (trigg@cs.waikato.ac.nz)
+ * @author   Len Trigg (trigg@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public abstract class DistributionClassifier extends Classifier {
+
+  /**
+   * Predicts the class memberships for a given instance. If
+   * an instance is unclassified, the returned array elements
+   * must be all zero. If the class is numeric, the array
+   * must consist of only one element, which contains the
+   * predicted value.
+   *
+   * @param instance the instance to be classified
+   * @return an array containing the estimated membership 
+   * probabilities of the test instance in each class (this 
+   * should sum to at most 1)
+   * @exception Exception if distribution could not be 
+   * computed successfully
+   */
+  public abstract double[] distributionForInstance(Instance instance) 
+       throws Exception;
+
+  /**
+   * Classifies the given test instance. The instance has to belong to a
+   * dataset when it's being classified.
+   *
+   * @param instance the instance to be classified
+   * @return the predicted most likely class for the instance or 
+   * Instance.missingValue() if no prediction is made
+   * @exception Exception if an error occurred during the prediction
+   */
+  public double classifyInstance(Instance instance) throws Exception {
+
+    double [] dist = distributionForInstance(instance);
+    if (dist == null) {
+      throw new Exception("Null distribution predicted");
+    }
+    switch (instance.classAttribute().type()) {
+    case Attribute.NOMINAL:
+      double max = 0;
+      int maxIndex = 0;
+      
+      for (int i = 0; i < dist.length; i++) {
+	if (dist[i] > max) {
+	  maxIndex = i;
+	  max = dist[i];
+	}
+      }
+      if (max > 0) {
+	return maxIndex;
+      } else {
+	return Instance.missingValue();
+      }
+    case Attribute.NUMERIC:
+      return dist[0];
+    default:
+      return Instance.missingValue();
+    }
+  }
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/classifiers/FilteredClassifier.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/classifiers/FilteredClassifier.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/classifiers/FilteredClassifier.java	(revision 20131)
@@ -0,0 +1,374 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    FilteredClassifier.java
+ *    Copyright (C) 1999 Len Trigg
+ *
+ */
+
+package weka.classifiers;
+
+import java.util.Enumeration;
+import java.util.Vector;
+import weka.core.Instance;
+import weka.core.Instances;
+import weka.core.Option;
+import weka.core.OptionHandler;
+import weka.core.Utils;
+import weka.filters.Filter;
+import weka.core.Attribute;
+
+
+/**
+ * Class for running an arbitrary classifier on data that has been passed
+ * through an arbitrary filter.<p>
+ *
+ * Valid options from the command line are:<p>
+ *
+ * -B classifierstring <br>
+ * Classifierstring should contain the full class name of a classifier
+ * followed by options to the classifier.
+ * (required).<p>
+ *
+ * -F filterstring <br>
+ * Filterstring should contain the full class name of a filter
+ * followed by options to the filter.
+ * (required).<p>
+ *
+ * @author Len Trigg (trigg@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public class FilteredClassifier extends DistributionClassifier
+  implements OptionHandler {
+
+  /** The classifier */
+  protected Classifier m_Classifier = new weka.classifiers.NaiveBayesSimple();
+
+  /** The filter */
+  protected Filter m_Filter = new weka.filters.DiscretizeFilter();
+
+  /** The instance structure of the filtered instances */
+  protected Instances m_FilteredInstances;
+  
+  /**
+   * Default constructor specifying NaiveBayesSimple as the classifier and
+   * DiscretizeFilter as the filter. Both of these are just placeholders
+   * for more useful selections.
+   */
+  public FilteredClassifier() {
+
+    this(new weka.classifiers.NaiveBayesSimple(), 
+	 new weka.filters.DiscretizeFilter());
+  }
+
+  /**
+   * Constructor that specifies the subclassifier and filter to use.
+   *
+   * @param classifier the Classifier to receive filtered instances.
+   * @param filter the Filter that will process instances before
+   * passing to the Classifier.
+   */
+  public FilteredClassifier(Classifier classifier, Filter filter) {
+
+    m_Classifier = classifier;
+    m_Filter = filter;
+  }
+
+  /**
+   * Returns an enumeration describing the available options
+   *
+   * @return an enumeration of all the available options
+   */
+  public Enumeration listOptions() {
+
+    Vector newVector = new Vector(2);
+
+    newVector.addElement(new Option(
+	      "\tFull class name of classifier to use, followed\n"
+	      + "\tby scheme options. (required)\n"
+	      + "\teg: \"weka.classifiers.NaiveBayes -D\"",
+	      "B", 1, "-B <classifier specification>"));
+    newVector.addElement(new Option(
+	      "\tFull class name of filter to use, followed\n"
+	      + "\tby filter options. (required)\n"
+	      + "\teg: \"weka.filters.AttributeFilter -V -R 1,2\"",
+	      "F", 1, "-F <filter specification>"));
+    return newVector.elements();
+  }
+
+  /**
+   * Parses a given list of options. Valid options are:<p>
+   *
+   * -B classifierstring <br>
+   * Classifierstring should contain the full class name of a classifier
+   * followed by options to the classifier.
+   * (required).<p>
+   *
+   * -F filterstring <br>
+   * Filterstring should contain the full class name of a filter
+   * followed by options to the filter.
+   * (required).<p>
+   *
+   * @param options the list of options as an array of strings
+   * @exception Exception if an option is not supported
+   */
+  public void setOptions(String[] options) throws Exception {
+
+    String classifierString = Utils.getOption('B', options);
+    if (classifierString.length() == 0) {
+      throw new Exception("A classifier must be specified"
+			  + " with the -B option.");
+    }
+    String [] classifierSpec = Utils.splitOptions(classifierString);
+    if (classifierSpec.length == 0) {
+      throw new Exception("Invalid classifier specification string");
+    }
+    String classifierName = classifierSpec[0];
+    classifierSpec[0] = "";
+    setClassifier(Classifier.forName(classifierName, classifierSpec));
+    
+    // Same for filter
+    String filterString = Utils.getOption('F', options);
+    if (filterString.length() == 0) {
+      throw new Exception("A filter must be specified"
+			  + " with the -F option.");
+    }
+    String [] filterSpec = Utils.splitOptions(filterString);
+    if (filterSpec.length == 0) {
+      throw new Exception("Invalid filter specification string");
+    }
+    String filterName = filterSpec[0];
+    filterSpec[0] = "";
+    setFilter((Filter) Utils.forName(Filter.class, filterName, filterSpec));
+  }
+
+  /**
+   * Gets the current settings of the Classifier.
+   *
+   * @return an array of strings suitable for passing to setOptions
+   */
+  public String [] getOptions() {
+
+    String [] options = new String [4];
+    int current = 0;
+
+    options[current++] = "-B";
+    options[current++] = "" + getClassifierSpec();
+
+    // Same for filter
+    options[current++] = "-F";
+    options[current++] = "" + getFilterSpec();
+    
+    while (current < options.length) {
+      options[current++] = "";
+    }
+    return options;
+  }
+
+  /**
+   * Sets the classifier
+   *
+   * @param classifier the classifier with all options set.
+   */
+  public void setClassifier(Classifier classifier) {
+
+    m_Classifier = classifier;
+  }
+
+  /**
+   * Gets the classifier used.
+   *
+   * @return the classifier
+   */
+  public Classifier getClassifier() {
+
+    return m_Classifier;
+  }
+  
+  /**
+   * Gets the classifier specification string, which contains the class name of
+   * the classifier and any options to the classifier
+   *
+   * @return the classifier string.
+   */
+  protected String getClassifierSpec() {
+    
+    Classifier c = getClassifier();
+    if (c instanceof OptionHandler) {
+      return c.getClass().getName() + " "
+	+ Utils.joinOptions(((OptionHandler)c).getOptions());
+    }
+    return c.getClass().getName();
+  }
+
+  /**
+   * Sets the filter
+   *
+   * @param filter the filter with all options set.
+   */
+  public void setFilter(Filter filter) {
+
+    m_Filter = filter;
+  }
+
+  /**
+   * Gets the filter used.
+   *
+   * @return the filter
+   */
+  public Filter getFilter() {
+
+    return m_Filter;
+  }
+  
+  /**
+   * Gets the filter specification string, which contains the class name of
+   * the filter and any options to the filter
+   *
+   * @return the filter string.
+   */
+  protected String getFilterSpec() {
+    
+    Filter c = getFilter();
+    if (c instanceof OptionHandler) {
+      return c.getClass().getName() + " "
+	+ Utils.joinOptions(((OptionHandler)c).getOptions());
+    }
+    return c.getClass().getName();
+  }
+
+  /**
+   * Build the classifier on the filtered data.
+   *
+   * @param data the training data
+   * @exception Exception if the classifier could not be built successfully
+   */
+  public void buildClassifier(Instances data) throws Exception {
+
+    if (m_Classifier == null) {
+      throw new Exception("No base classifiers have been set!");
+    }
+    /*
+    String fname = m_Filter.getClass().getName();
+    fname = fname.substring(fname.lastIndexOf('.') + 1);
+    util.Timer t = util.Timer.getTimer("FilteredClassifier::" + fname);
+    t.start();
+    */
+    m_Filter.setInputFormat(data);
+    data = Filter.useFilter(data, m_Filter);
+    //t.stop();
+    m_FilteredInstances = data.stringFreeStructure();
+    m_Classifier.buildClassifier(data);
+  }
+
+  /**
+   * Classifies a given instance after filtering.
+   *
+   * @param instance the instance to be classified
+   * @exception Exception if instance could not be classified
+   * successfully
+   */
+  public double [] distributionForInstance(Instance instance)
+    throws Exception {
+
+    /*
+      System.err.println("FilteredClassifier:: " 
+                         + m_Filter.getClass().getName()
+                         + " in: " + instance);
+    */
+    if (m_Filter.numPendingOutput() > 0) {
+      throw new Exception("Filter output queue not empty!");
+    }
+    /*
+    String fname = m_Filter.getClass().getName();
+    fname = fname.substring(fname.lastIndexOf('.') + 1);
+    util.Timer t = util.Timer.getTimer("FilteredClassifier::" + fname);
+    t.start();
+    */
+    if (!m_Filter.input(instance)) {
+      throw new Exception("Filter didn't make the test instance"
+			  + " immediately available!");
+    }
+    m_Filter.batchFinished();
+    Instance newInstance = m_Filter.output();
+    //t.stop();
+    /*
+    System.err.println("FilteredClassifier:: " 
+                       + m_Filter.getClass().getName()
+                       + " out: " + newInstance);
+    */
+    if (m_Classifier instanceof DistributionClassifier) {
+      return ((DistributionClassifier)m_Classifier)
+	.distributionForInstance(newInstance);
+    }
+    double pred = m_Classifier.classifyInstance(newInstance);
+    double [] result = new double [m_FilteredInstances.numClasses()];
+    if (Instance.isMissingValue(pred)) {
+      return result;
+    }
+    switch (instance.classAttribute().type()) {
+    case Attribute.NOMINAL:
+      result[(int) pred] = 1.0;
+      break;
+    case Attribute.NUMERIC:
+      result[0] = pred;
+      break;
+    default:
+      throw new Exception("Unknown class type");
+    }
+    return result;
+  }
+
+  /**
+   * Output a representation of this classifier
+   */
+  public String toString() {
+
+    if (m_FilteredInstances == null) {
+      return "FilteredClassifier: No model built yet.";
+    }
+
+    String result = "FilteredClassifier using "
+      + getClassifierSpec()
+      + " on data filtered through "
+      + getFilterSpec()
+      + "\n\nFiltered Header\n"
+      + m_FilteredInstances.toString()
+      + "\n\nClassifier Model\n"
+      + m_Classifier.toString();
+    return result;
+  }
+
+
+  /**
+   * Main method for testing this class.
+   *
+   * @param argv should contain the following arguments:
+   * -t training file [-T test file] [-c class index]
+   */
+  public static void main(String [] argv) {
+
+    try {
+      System.out.println("Evaluation disabled!");
+      //System.out.println(Evaluation.evaluateModel(new FilteredClassifier(),
+      //					  argv));
+    } catch (Exception e) {
+      System.err.println(e.getMessage());
+    }
+  }
+
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/classifiers/NaiveBayesSimple.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/classifiers/NaiveBayesSimple.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/classifiers/NaiveBayesSimple.java	(revision 20131)
@@ -0,0 +1,331 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    NaiveBayesSimple.java
+ *    Copyright (C) 1999 Eibe Frank
+ *
+ */
+
+package weka.classifiers;
+
+import java.io.*;
+import java.util.*;
+import weka.core.*;
+
+/**
+ * Class for building and using a simple Naive Bayes classifier.
+ * Numeric attributes are modelled by a normal distribution. For more
+ * information, see<p>
+ *
+ * Richard Duda and Peter Hart (1973).<i>Pattern
+ * Classification and Scene Analysis</i>. Wiley, New York.
+
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version $Revision$ 
+*/
+public class NaiveBayesSimple extends DistributionClassifier {
+
+  /** All the counts for nominal attributes. */
+  private double [][][] m_Counts;
+  
+  /** The means for numeric attributes. */
+  private double [][] m_Means;
+
+  /** The standard deviations for numeric attributes. */
+  private double [][] m_Devs;
+
+  /** The prior probabilities of the classes. */
+  private double [] m_Priors;
+
+  /** The instances used for training. */
+  private Instances m_Instances;
+
+  /** Constant for normal distribution. */
+  private static double NORM_CONST = Math.sqrt(2 * Math.PI);
+
+  /**
+   * Generates the classifier.
+   *
+   * @param instances set of instances serving as training data 
+   * @exception Exception if the classifier has not been generated successfully
+   */
+  public void buildClassifier(Instances instances) throws Exception {
+
+    int attIndex = 0;
+    double sum;
+    
+    if (instances.checkForStringAttributes()) {
+      throw new Exception("Can't handle string attributes!");
+    }
+    if (instances.classAttribute().isNumeric()) {
+      throw new Exception("Naive Bayes: Class is numeric!");
+    }
+    
+    m_Instances = new Instances(instances, 0);
+    
+    // Reserve space
+    m_Counts = new double[instances.numClasses()]
+      [instances.numAttributes() - 1][0];
+    m_Means = new double[instances.numClasses()]
+      [instances.numAttributes() - 1];
+    m_Devs = new double[instances.numClasses()]
+      [instances.numAttributes() - 1];
+    m_Priors = new double[instances.numClasses()];
+    Enumeration enum = instances.enumerateAttributes();
+    while (enum.hasMoreElements()) {
+      Attribute attribute = (Attribute) enum.nextElement();
+      if (attribute.isNominal()) {
+	for (int j = 0; j < instances.numClasses(); j++) {
+	  m_Counts[j][attIndex] = new double[attribute.numValues()];
+	}
+      } else {
+	for (int j = 0; j < instances.numClasses(); j++) {
+	  m_Counts[j][attIndex] = new double[1];
+	}
+      }
+      attIndex++;
+    }
+    
+    // Compute counts and sums
+    Enumeration enumInsts = instances.enumerateInstances();
+    while (enumInsts.hasMoreElements()) {
+      Instance instance = (Instance) enumInsts.nextElement();
+      if (!instance.classIsMissing()) {
+	Enumeration enumAtts = instances.enumerateAttributes();
+	attIndex = 0;
+	while (enumAtts.hasMoreElements()) {
+	  Attribute attribute = (Attribute) enumAtts.nextElement();
+	  if (!instance.isMissing(attribute)) {
+	    if (attribute.isNominal()) {
+	      m_Counts[(int)instance.classValue()][attIndex]
+		[(int)instance.value(attribute)]++;
+	    } else {
+	      m_Means[(int)instance.classValue()][attIndex] +=
+		instance.value(attribute);
+	      m_Counts[(int)instance.classValue()][attIndex][0]++;
+	    }
+	  }
+	  attIndex++;
+	}
+	m_Priors[(int)instance.classValue()]++;
+      }
+    }
+    
+    // Compute means
+    Enumeration enumAtts = instances.enumerateAttributes();
+    attIndex = 0;
+    while (enumAtts.hasMoreElements()) {
+      Attribute attribute = (Attribute) enumAtts.nextElement();
+      if (attribute.isNumeric()) {
+	for (int j = 0; j < instances.numClasses(); j++) {
+	  if (m_Counts[j][attIndex][0] < 2) {
+	    throw new Exception("attribute " + attribute.name() +
+				": less than two values for class " +
+				instances.classAttribute().value(j));
+	  }
+	  m_Means[j][attIndex] /= m_Counts[j][attIndex][0];
+	}
+      }
+      attIndex++;
+    }    
+    
+    // Compute standard deviations
+    enumInsts = instances.enumerateInstances();
+    while (enumInsts.hasMoreElements()) {
+      Instance instance = 
+	(Instance) enumInsts.nextElement();
+      if (!instance.classIsMissing()) {
+	enumAtts = instances.enumerateAttributes();
+	attIndex = 0;
+	while (enumAtts.hasMoreElements()) {
+	  Attribute attribute = (Attribute) enumAtts.nextElement();
+	  if (!instance.isMissing(attribute)) {
+	    if (attribute.isNumeric()) {
+	      m_Devs[(int)instance.classValue()][attIndex] +=
+		(m_Means[(int)instance.classValue()][attIndex]-
+		 instance.value(attribute))*
+		(m_Means[(int)instance.classValue()][attIndex]-
+		 instance.value(attribute));
+	    }
+	  }
+	  attIndex++;
+	}
+      }
+    }
+    enumAtts = instances.enumerateAttributes();
+    attIndex = 0;
+    while (enumAtts.hasMoreElements()) {
+      Attribute attribute = (Attribute) enumAtts.nextElement();
+      if (attribute.isNumeric()) {
+	for (int j = 0; j < instances.numClasses(); j++) {
+	  if (m_Devs[j][attIndex] <= 0) {
+	    throw new Exception("attribute " + attribute.name() +
+				": standard deviation is 0 for class " +
+				instances.classAttribute().value(j));
+	  }
+	  else {
+	    m_Devs[j][attIndex] /= m_Counts[j][attIndex][0] - 1;
+	    m_Devs[j][attIndex] = Math.sqrt(m_Devs[j][attIndex]);
+	  }
+	}
+      }
+      attIndex++;
+    } 
+    
+    // Normalize counts
+    enumAtts = instances.enumerateAttributes();
+    attIndex = 0;
+    while (enumAtts.hasMoreElements()) {
+      Attribute attribute = (Attribute) enumAtts.nextElement();
+      if (attribute.isNominal()) {
+	for (int j = 0; j < instances.numClasses(); j++) {
+	  sum = Utils.sum(m_Counts[j][attIndex]);
+	  for (int i = 0; i < attribute.numValues(); i++) {
+	    m_Counts[j][attIndex][i] =
+	      (m_Counts[j][attIndex][i] + 1) 
+	      / (sum + (double)attribute.numValues());
+	  }
+	}
+      }
+      attIndex++;
+    }
+    
+    // Normalize priors
+    sum = Utils.sum(m_Priors);
+    for (int j = 0; j < instances.numClasses(); j++)
+      m_Priors[j] = (m_Priors[j] + 1) 
+	/ (sum + (double)instances.numClasses());
+  }
+
+  /**
+   * Calculates the class membership probabilities for the given test instance.
+   *
+   * @param instance the instance to be classified
+   * @return predicted class probability distribution
+   * @exception Exception if distribution can't be computed
+   */
+  public double[] distributionForInstance(Instance instance) throws Exception {
+    
+    double [] probs = new double[instance.numClasses()];
+    int attIndex;
+    
+    for (int j = 0; j < instance.numClasses(); j++) {
+      probs[j] = 1;
+      Enumeration enumAtts = instance.enumerateAttributes();
+      attIndex = 0;
+      while (enumAtts.hasMoreElements()) {
+	Attribute attribute = (Attribute) enumAtts.nextElement();
+	if (!instance.isMissing(attribute)) {
+	  if (attribute.isNominal()) {
+	    probs[j] *= m_Counts[j][attIndex][(int)instance.value(attribute)];
+	  } else {
+	    probs[j] *= normalDens(instance.value(attribute),
+				   m_Means[j][attIndex],
+				   m_Devs[j][attIndex]);}
+	}
+	attIndex++;
+      }
+      probs[j] *= m_Priors[j];
+    }
+    
+    // Normalize probabilities
+    Utils.normalize(probs);
+
+    return probs;
+  }
+
+  /**
+   * Returns a description of the classifier.
+   *
+   * @return a description of the classifier as a string.
+   */
+  public String toString() {
+
+    if (m_Instances == null) {
+      return "Naive Bayes (simple): No model built yet.";
+    }
+    try {
+      StringBuffer text = new StringBuffer("Naive Bayes (simple)");
+      int attIndex;
+      
+      for (int i = 0; i < m_Instances.numClasses(); i++) {
+	text.append("\n\nClass " + m_Instances.classAttribute().value(i) 
+		    + ": P(C) = " 
+		    + Utils.doubleToString(m_Priors[i], 10, 8)
+		    + "\n\n");
+	Enumeration enumAtts = m_Instances.enumerateAttributes();
+	attIndex = 0;
+	while (enumAtts.hasMoreElements()) {
+	  Attribute attribute = (Attribute) enumAtts.nextElement();
+	  text.append("Attribute " + attribute.name() + "\n");
+	  if (attribute.isNominal()) {
+	    for (int j = 0; j < attribute.numValues(); j++) {
+	      text.append(attribute.value(j) + "\t");
+	    }
+	    text.append("\n");
+	    for (int j = 0; j < attribute.numValues(); j++)
+	      text.append(Utils.
+			  doubleToString(m_Counts[i][attIndex][j], 10, 8)
+			  + "\t");
+	  } else {
+	    text.append("Mean: " + Utils.
+			doubleToString(m_Means[i][attIndex], 10, 8) + "\t");
+	    text.append("Standard Deviation: " 
+			+ Utils.doubleToString(m_Devs[i][attIndex], 10, 8));
+	  }
+	  text.append("\n\n");
+	  attIndex++;
+	}
+      }
+      
+      return text.toString();
+    } catch (Exception e) {
+      return "Can't print Naive Bayes classifier!";
+    }
+  }
+
+  /**
+   * Density function of normal distribution.
+   */
+  private double normalDens(double x, double mean, double stdDev) {
+    
+    double diff = x - mean;
+    
+    return (1 / (NORM_CONST * stdDev)) 
+      * Math.exp(-(diff * diff / (2 * stdDev * stdDev)));
+  }
+
+  /**
+   * Main method for testing this class.
+   *
+   * @param argv the options
+   */
+  public static void main(String [] argv) {
+
+    Classifier scheme;
+
+    try {
+      scheme = new NaiveBayesSimple();
+      System.out.println("Evaluation disabled!");
+      //System.out.println(Evaluation.evaluateModel(scheme, argv));
+    } catch (Exception e) {
+      System.err.println(e.getMessage());
+    }
+  }
+}
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Attribute.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Attribute.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Attribute.java	(revision 20131)
@@ -0,0 +1,682 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    Attribute.java
+ *    Copyright (C) 1999 Eibe Frank
+ *
+ */
+
+package weka.core;
+
+import java.io.*;
+import java.util.*;
+
+/** 
+ * Class for handling an attribute. Once an attribute has been created,
+ * it can't be changed. <p>
+ *
+ * Three attribute types are supported:
+ * <ul>
+ *    <li> numeric: <ul>
+ *         This type of attribute represents a floating-point number.
+ *    </ul>
+ *    <li> nominal: <ul>
+ *         This type of attribute represents a fixed set of nominal values.
+ *    </ul>
+ *    <li> string: <ul>
+ *         This type of attribute represents a dynamically expanding set of
+ *         nominal values. String attributes are not used by the learning
+ *         schemes in Weka. They can be used, for example,  to store an 
+ *         identifier with each instance in a dataset.
+ *    </ul>
+ * </ul>
+ * Typical usage (code from the main() method of this class): <p>
+ *
+ * <code>
+ * ... <br>
+ *
+ * // Create numeric attributes "length" and "weight" <br>
+ * Attribute length = new Attribute("length"); <br>
+ * Attribute weight = new Attribute("weight"); <br><br>
+ * 
+ * // Create vector to hold nominal values "first", "second", "third" <br>
+ * FastVector my_nominal_values = new FastVector(3); <br>
+ * my_nominal_values.addElement("first"); <br>
+ * my_nominal_values.addElement("second"); <br>
+ * my_nominal_values.addElement("third"); <br><br>
+ *
+ * // Create nominal attribute "position" <br>
+ * Attribute position = new Attribute("position", my_nominal_values);<br>
+ *
+ * ... <br>
+ * </code><p>
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public class Attribute implements Copyable, Serializable {
+
+  /** Constant set for numeric attributes. */
+  public final static int NUMERIC = 0;
+
+  /** Constant set for nominal attributes. */
+  public final static int NOMINAL = 1;
+
+  /** Constant set for attributes with string values. */
+  public final static int STRING = 2;
+
+  /** Strings longer than this will be stored compressed. */
+  private final static int STRING_COMPRESS_THRESHOLD = 200;
+  //private final static int STRING_COMPRESS_THRESHOLD = Integer.MAX_VALUE;
+
+  /** The attribute's name. */
+  private String m_Name;
+
+  /** The attribute's type. */
+  private int m_Type;
+
+  /** The attribute's values (if nominal or string). */
+  private FastVector m_Values;
+
+  /** Mapping of values to indices (if nominal or string). */
+  private Hashtable m_Hashtable;
+
+  /** The attribute's index. */
+  private int m_Index;
+
+  /**
+   * Constructor for a numeric attribute.
+   *
+   * @param attributeName the name for the attribute
+   */
+  public Attribute(String attributeName) {
+
+    m_Name = attributeName;
+    m_Index = -1;
+    m_Values = null;
+    m_Hashtable = null;
+    m_Type = NUMERIC;
+  }
+
+  /**
+   * Constructor for nominal attributes and string attributes.
+   * If a null vector of attribute values is passed to the method,
+   * the attribute is assumed to be a string.
+   *
+   * @param attributeName the name for the attribute
+   * @param attributeValues a vector of strings denoting the 
+   * attribute values. Null if the attribute is a string attribute.
+   */
+  public Attribute(String attributeName, 
+		   FastVector attributeValues) {
+
+    m_Name = attributeName;
+    m_Index = -1;
+    if (attributeValues == null) {
+      m_Values = new FastVector();
+      m_Hashtable = new Hashtable();
+      m_Type = STRING;
+    } else {
+      m_Values = (FastVector) attributeValues.copy();
+      m_Hashtable = new Hashtable(m_Values.size());
+      for (int i = 0; i < m_Values.size(); i++) {
+	m_Hashtable.put(m_Values.elementAt(i), new Integer(i));
+      }
+      m_Type = NOMINAL;
+    }
+  }
+
+  /**
+   * Produces a shallow copy of this attribute.
+   *
+   * @return a copy of this attribute with the same index
+   */
+  public Object copy() {
+
+    Attribute copy = new Attribute(m_Name);
+
+    copy.m_Index = m_Index;
+    if (!isNominal() && !isString())
+      return copy;
+    copy.m_Type = m_Type;
+    copy.m_Values = m_Values;
+    copy.m_Hashtable = m_Hashtable;
+ 
+    return copy;
+  }
+
+  /**
+   * Returns an enumeration of all the attribute's values if
+   * the attribute is nominal or a string, null otherwise. 
+   *
+   * @return enumeration of all the attribute's values
+   */
+  public final Enumeration enumerateValues() {
+
+    if (isNominal() || isString()) {
+      final Enumeration ee = m_Values.elements();
+      return new Enumeration () {
+          public boolean hasMoreElements() {
+            return ee.hasMoreElements();
+          }
+          public Object nextElement() {
+            Object oo = ee.nextElement();
+            if (oo instanceof SerializedObject) {
+              return ((SerializedObject)oo).getObject();
+            } else {
+              return oo;
+            }
+          }
+        };
+    }
+    return null;
+  }
+
+  /**
+   * Tests if given attribute is equal to this attribute.
+   *
+   * @param other the Object to be compared to this attribute
+   * @return true if the given attribute is equal to this attribute
+   */
+  public final boolean equals(Object other) {
+
+    if ((other == null) || !(other.getClass().equals(this.getClass()))) {
+      return false;
+    }
+    Attribute att = (Attribute) other;
+    if (!m_Name.equals(att.m_Name)) {
+      return false;
+    }
+    if (isNumeric() && att.isNumeric()) {
+      return true;
+    }
+    if (isNumeric() || att.isNumeric()) {
+      return false;
+    }
+    if (m_Values.size() != att.m_Values.size()) {
+      return false;
+    }
+    for (int i = 0; i < m_Values.size(); i++) {
+      if (!m_Values.elementAt(i).equals(att.m_Values.elementAt(i))) {
+	return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Returns the index of this attribute.
+   *
+   * @return the index of this attribute
+   */
+  public final int index() {
+
+    return m_Index;
+  }
+
+  /**
+   * Returns the index of a given attribute value. (The index of
+   * the first occurence of this value.)
+   *
+   * @param value the value for which the index is to be returned
+   * @return the index of the given attribute value if attribute
+   * is nominal or a string, -1 if it is numeric or the value 
+   * can't be found
+   */
+  public final int indexOfValue(String value) {
+
+    if (!isNominal() && !isString())
+      return -1;
+    Object store = value;
+    if (value.length() > STRING_COMPRESS_THRESHOLD) {
+      try {
+        store = new SerializedObject(value, true);
+      } catch (Exception ex) {
+        System.err.println("Couldn't compress string attribute value -"
+                           + " searching uncompressed.");
+      }
+    }
+    Integer val = (Integer)m_Hashtable.get(store);
+    if (val == null) {
+      throw new IllegalArgumentException("Value \"" + value + 
+					 "\" not found in attribute " +
+					 "declaration!");
+    } else {
+      return val.intValue();
+    }
+  }
+
+  /**
+   * Test if the attribute is nominal.
+   *
+   * @return true if the attribute is nominal
+   */
+  public final boolean isNominal() {
+
+    return (m_Type == NOMINAL);
+  }
+
+  /**
+   * Tests if the attribute is numeric.
+   *
+   * @return true if the attribute is numeric
+   */
+  public final boolean isNumeric() {
+
+    return (m_Type == NUMERIC);
+  }
+
+  /**
+   * Tests if the attribute is a string.
+   *
+   * @return true if the attribute is a string
+   */
+  public final boolean isString() {
+
+    return (m_Type == STRING);
+  }
+
+  /**
+   * Returns the attribute's name.
+   *
+   * @return the attribute's name as a string
+   */
+  public final String name() {
+
+    return m_Name;
+  }
+  
+  /**
+   * Returns the number of attribute values. Returns 0 for numeric attributes.
+   *
+   * @return the number of attribute values
+   */
+  public final int numValues() {
+
+    if (!isNominal() && !isString()) {
+      return 0;
+    } else {
+      return m_Values.size();
+    }
+  }
+
+  /**
+   * Returns a description of this attribute in ARFF format. Quotes
+   * strings if they contain whitespace characters, or if they
+   * are a question mark.
+   *
+   * @return a description of this attribute as a string
+   */
+  public final String toString() {
+    
+    StringBuffer text = new StringBuffer();
+    
+    text.append("@attribute " + Utils.quote(m_Name) + " ");
+    if (isNominal()) {
+      text.append('{');
+      Enumeration enum = enumerateValues();
+      while (enum.hasMoreElements()) {
+	text.append(Utils.quote((String) enum.nextElement()));
+	if (enum.hasMoreElements())
+	  text.append(',');
+      }
+      text.append('}');
+    } else {
+      if (isNumeric()) {
+	text.append("numeric");
+      } else {
+	text.append("string");
+      }
+    }
+    return text.toString();
+  }
+
+  /**
+   * Returns the attribute's type as an integer.
+   *
+   * @returns the attribute's type.
+   */
+  public final int type() {
+
+    return m_Type;
+  }
+
+  /**
+   * Returns a value of a nominal or string attribute. 
+   * Returns an empty string if the attribute is neither
+   * nominal nor a string attribute.
+   *
+   * @param valIndex the value's index
+   * @return the attribute's value as a string
+   */
+  public final String value(int valIndex) {
+    
+    if (!isNominal() && !isString()) {
+      return "";
+    } else {
+      Object val = m_Values.elementAt(valIndex);
+      
+      // If we're storing strings compressed, uncompress it.
+      if (val instanceof SerializedObject) {
+        val = ((SerializedObject)val).getObject();
+      }
+      return (String) val;
+    }
+  }
+
+  /**
+   * Constructor for a numeric attribute with a particular index.
+   *
+   * @param attributeName the name for the attribute
+   * @param index the attribute's index
+   */
+  Attribute(String attributeName, int index) {
+
+    this(attributeName);
+
+    m_Index = index;
+  }
+
+  /**
+   * Constructor for nominal attributes and string attributes with
+   * a particular index.
+   * If a null vector of attribute values is passed to the method,
+   * the attribute is assumed to be a string.
+   *
+   * @param attributeName the name for the attribute
+   * @param attributeValues a vector of strings denoting the attribute values.
+   * Null if the attribute is a string attribute.
+   * @param index the attribute's index
+   */
+  Attribute(String attributeName, FastVector attributeValues, 
+	    int index) {
+
+    this(attributeName, attributeValues);
+
+    m_Index = index;
+  }
+
+  /**
+   * Adds a string value to the list of valid strings for attributes
+   * of type STRING and returns the index of the string.
+   *
+   * @param value The string value to add
+   * @return the index assigned to the string, or -1 if the attribute is not
+   * of type Attribute.STRING 
+   */
+  public int addStringValue(String value) {
+
+    if (!isString()) {
+      return -1;
+    }
+    Object store = value;
+
+    if (value.length() > STRING_COMPRESS_THRESHOLD) {
+      try {
+        store = new SerializedObject(value, true);
+      } catch (Exception ex) {
+        System.err.println("Couldn't compress string attribute value -"
+                           + " storing uncompressed.");
+      }
+    }
+    Integer index = (Integer)m_Hashtable.get(store);
+    if (index != null) {
+      return index.intValue();
+    } else {
+      int intIndex = m_Values.size();
+      m_Values.addElement(store);
+      m_Hashtable.put(store, new Integer(intIndex));
+      return intIndex;
+    }
+  }
+
+  /**
+   * Adds a string value to the list of valid strings for attributes
+   * of type STRING and returns the index of the string. This method is
+   * more efficient than addStringValue(String) for long strings.
+   *
+   * @param src The Attribute containing the string value to add.
+   * @param int index the index of the string value in the source attribute.
+   * @return the index assigned to the string, or -1 if the attribute is not
+   * of type Attribute.STRING 
+   */
+  public int addStringValue(Attribute src, int index) {
+
+    if (!isString()) {
+      return -1;
+    }
+    Object store = src.m_Values.elementAt(index);
+    Integer oldIndex = (Integer)m_Hashtable.get(store);
+    if (oldIndex != null) {
+      return oldIndex.intValue();
+    } else {
+      int intIndex = m_Values.size();
+      m_Values.addElement(store);
+      m_Hashtable.put(store, new Integer(intIndex));
+      return intIndex;
+    }
+  }
+
+  /**
+   * Adds an attribute value. Creates a fresh list of attribute
+   * values before adding it.
+   *
+   * @param value the attribute value
+   */
+  final void addValue(String value) {
+
+    m_Values = (FastVector)m_Values.copy();
+    m_Hashtable = (Hashtable)m_Hashtable.clone();
+    forceAddValue(value);
+  }
+
+  /**
+   * Produces a shallow copy of this attribute with a new name.
+   *
+   * @param newName the name of the new attribute
+   * @return a copy of this attribute with the same index
+   */
+  final Attribute copy(String newName) {
+
+    Attribute copy = new Attribute(newName);
+
+    copy.m_Index = m_Index;
+    if (!isNominal() && !isString())
+      return copy;
+    copy.m_Type = m_Type;
+    copy.m_Values = m_Values;
+    copy.m_Hashtable = m_Hashtable;
+ 
+    return copy;
+  }
+
+  /**
+   * Removes a value of a nominal or string attribute. Creates a 
+   * fresh list of attribute values before removing it.
+   *
+   * @param index the value's index
+   * @exception IllegalArgumentException if the attribute is not nominal
+   */
+  final void delete(int index) {
+    
+    if (!isNominal() && !isString()) 
+      throw new IllegalArgumentException("Can only remove value of" +
+                                         "nominal or string attribute!");
+    else {
+      m_Values = (FastVector)m_Values.copy();
+      m_Values.removeElementAt(index);
+      Hashtable hash = new Hashtable(m_Hashtable.size());
+      Enumeration enum = hash.keys();
+      while (enum.hasMoreElements()) {
+	String string = (String)enum.nextElement();
+	Integer valIndexObject = (Integer)m_Hashtable.get(string);
+	int valIndex = valIndexObject.intValue();
+	if (valIndex > index) {
+	  hash.put(string, new Integer(valIndex - 1));
+	} else if (valIndex < index) {
+	  hash.put(string, valIndexObject);
+	}
+      }
+      m_Hashtable = hash;
+    }
+  }
+
+  /**
+   * Adds an attribute value.
+   *
+   * @param value the attribute value
+   */
+  final void forceAddValue(String value) {
+
+    Object store = value;
+    if (value.length() > STRING_COMPRESS_THRESHOLD) {
+      try {
+        store = new SerializedObject(value, true);
+      } catch (Exception ex) {
+        System.err.println("Couldn't compress string attribute value -"
+                           + " storing uncompressed.");
+      }
+    }
+    m_Values.addElement(store);
+    m_Hashtable.put(store, new Integer(m_Values.size() - 1));
+  }
+
+  /**
+   * Sets the index of this attribute.
+   *
+   * @param the index of this attribute
+   */
+  final void setIndex(int index) {
+
+    m_Index = index;
+  }
+
+  /**
+   * Sets a value of a nominal attribute or string attribute.
+   * Creates a fresh list of attribute values before it is set.
+   *
+   * @param index the value's index
+   * @param string the value
+   * @exception IllegalArgumentException if the attribute is not nominal or 
+   * string.
+   */
+  final void setValue(int index, String string) {
+
+    if (!isNominal() && !isString()) {
+      throw new IllegalArgumentException("Can only set value of nominal"+
+                                         "or string attribute!");
+    } else {
+      m_Values = (FastVector)m_Values.copy();
+      m_Hashtable = (Hashtable)m_Hashtable.clone();
+      Object store = string;
+      if (string.length() > STRING_COMPRESS_THRESHOLD) {
+        try {
+          store = new SerializedObject(string, true);
+        } catch (Exception ex) {
+          System.err.println("Couldn't compress string attribute value -"
+                             + " storing uncompressed.");
+        }
+      }
+      m_Hashtable.remove(m_Values.elementAt(index));
+      m_Values.setElementAt(store, index);
+      m_Hashtable.put(store, new Integer(index));
+    }
+  }
+
+  /**
+   * Simple main method for testing this class.
+   */
+  public static void main(String[] ops) {
+
+    try {
+      
+      // Create numeric attributes "length" and "weight"
+      Attribute length = new Attribute("length");
+      Attribute weight = new Attribute("weight");
+      
+      // Create vector to hold nominal values "first", "second", "third" 
+      FastVector my_nominal_values = new FastVector(3); 
+      my_nominal_values.addElement("first"); 
+      my_nominal_values.addElement("second"); 
+      my_nominal_values.addElement("third"); 
+      
+      // Create nominal attribute "position" 
+      Attribute position = new Attribute("position", my_nominal_values);
+
+      // Print the name of "position"
+      System.out.println("Name of \"position\": " + position.name());
+
+      // Print the values of "position"
+      Enumeration attValues = position.enumerateValues();
+      while (attValues.hasMoreElements()) {
+	String string = (String)attValues.nextElement();
+	System.out.println("Value of \"position\": " + string);
+      }
+
+      // Shallow copy attribute "position"
+      Attribute copy = (Attribute) position.copy();
+
+      // Test if attributes are the same
+      System.out.println("Copy is the same as original: " + copy.equals(position));
+
+      // Print index of attribute "weight" (should be unset: -1)
+      System.out.println("Index of attribute \"weight\" (should be -1): " + 
+			 weight.index());
+
+      // Print index of value "first" of attribute "position"
+      System.out.println("Index of value \"first\" of \"position\" (should be 0): " +
+			 position.indexOfValue("first"));
+
+      // Tests type of attribute "position"
+      System.out.println("\"position\" is numeric: " + position.isNumeric());
+      System.out.println("\"position\" is nominal: " + position.isNominal());
+      System.out.println("\"position\" is string: " + position.isString());
+
+      // Prints name of attribute "position"
+      System.out.println("Name of \"position\": " + position.name());
+    
+      // Prints number of values of attribute "position"
+      System.out.println("Number of values for \"position\": " + position.numValues());
+
+      // Prints the values (againg)
+      for (int i = 0; i < position.numValues(); i++) {
+	System.out.println("Value " + i + ": " + position.value(i));
+      }
+
+      // Prints the attribute "position" in ARFF format
+      System.out.println(position);
+
+      // Checks type of attribute "position" using constants
+      switch (position.type()) {
+      case Attribute.NUMERIC:
+	System.out.println("\"position\" is numeric");
+	break;
+      case Attribute.NOMINAL:
+	System.out.println("\"position\" is nominal");
+	break;
+      case Attribute.STRING:
+	System.out.println("\"position\" is string");
+	break;
+      default:
+	System.out.println("\"position\" has unknown type");
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+}
+  
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/AttributeStats.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/AttributeStats.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/AttributeStats.java	(revision 20131)
@@ -0,0 +1,136 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    AttributeStats.java
+ *    Copyright (C) 1999 Len Trigg
+ *
+ */
+
+package weka.core;
+
+/**
+ * A Utility class that contains summary information on an
+ * the values that appear in a dataset for a particular attribute.
+ *
+ * @author <a href="mailto:len@webmind.com">Len Trigg</a>
+ * @version $Revision$
+ */
+public class AttributeStats {    
+  
+  /** The number of int-like values */
+  public int intCount = 0;
+  
+  /** The number of real-like values (i.e. have a fractional part) */
+  public int realCount = 0;
+  
+  /** The number of missing values */
+  public int missingCount = 0;
+  
+  /** The number of distinct values */
+  public int distinctCount = 0;
+  
+  /** The number of values that only appear once */
+  public int uniqueCount = 0;
+  
+  /** The total number of values (i.e. number of instances) */
+  public int totalCount = 0;
+  
+  /** Stats on numeric value distributions */
+  // perhaps Stats should be moved from weka.experiment to weka.core
+  public weka.experiment.Stats numericStats;
+  
+  /** Counts of each nominal value */
+  public int [] nominalCounts;
+    
+  /**
+   * Updates the counters for one more observed distinct value.
+   *
+   * @param value the value that has just been seen
+   * @param count the number of times the value appeared
+   */
+  protected void addDistinct(double value, int count) {
+    
+    if (count > 0) {
+      if (count == 1) {
+	uniqueCount++;
+	}
+      if (Utils.eq(value, (double)((int)value))) {
+	intCount += count;
+      } else {
+	realCount += count;
+      }
+      if (nominalCounts != null) {
+	nominalCounts[(int)value] = count;
+      }
+      if (numericStats != null) {
+	  numericStats.add(value, count);
+	  numericStats.calculateDerived();
+      }
+    }
+    distinctCount++;
+  }
+
+  /**
+   * Returns a human readable representation of this AttributeStats instance.
+   *
+   * @return a String represtinging these AttributeStats.
+   */
+  public String toString() {
+
+    StringBuffer sb = new StringBuffer();
+    sb.append(Utils.padLeft("Type", 4)).append(Utils.padLeft("Nom", 5));
+    sb.append(Utils.padLeft("Int", 5)).append(Utils.padLeft("Real", 5));
+    sb.append(Utils.padLeft("Missing", 12));
+    sb.append(Utils.padLeft("Unique", 12));
+    sb.append(Utils.padLeft("Dist", 6));
+    if (nominalCounts != null) {
+      sb.append(' ');
+      for (int i = 0; i < nominalCounts.length; i++) {
+        sb.append(Utils.padLeft("C[" + i + "]", 5));
+      }
+    }
+    sb.append('\n');
+
+    long percent;
+    percent = Math.round(100.0 * intCount / totalCount);
+    if (nominalCounts != null) {
+      sb.append(Utils.padLeft("Nom", 4)).append(' ');
+      sb.append(Utils.padLeft("" + percent, 3)).append("% ");
+      sb.append(Utils.padLeft("" + 0, 3)).append("% ");
+    } else {
+      sb.append(Utils.padLeft("Num", 4)).append(' ');
+      sb.append(Utils.padLeft("" + 0, 3)).append("% ");
+      sb.append(Utils.padLeft("" + percent, 3)).append("% ");
+    }
+    percent = Math.round(100.0 * realCount / totalCount);
+    sb.append(Utils.padLeft("" + percent, 3)).append("% ");
+    sb.append(Utils.padLeft("" + missingCount, 5)).append(" /");
+    percent = Math.round(100.0 * missingCount / totalCount);
+    sb.append(Utils.padLeft("" + percent, 3)).append("% ");
+    sb.append(Utils.padLeft("" + uniqueCount, 5)).append(" /");
+    percent = Math.round(100.0 * uniqueCount / totalCount);
+    sb.append(Utils.padLeft("" + percent, 3)).append("% ");
+    sb.append(Utils.padLeft("" + distinctCount, 5)).append(' ');
+    if (nominalCounts != null) {
+      for (int i = 0; i < nominalCounts.length; i++) {
+        sb.append(Utils.padLeft("" + nominalCounts[i], 5));
+      }
+    }
+    sb.append('\n');
+    return sb.toString();
+  }
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/ContingencyTables.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/ContingencyTables.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/ContingencyTables.java	(revision 20131)
@@ -0,0 +1,635 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    ContingencyTables.java
+ *    Copyright (C) 1999 Eibe Frank
+ *
+ */
+
+package weka.core;
+
+/**
+ * Class implementing some statistical routines for contingency tables.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public class ContingencyTables {
+
+  /** The natural logarithm of 2 */
+  private static double log2 = Math.log(2);
+
+  /**
+   * Returns chi-squared probability for a given matrix.
+   *
+   * @param matrix the contigency table
+   * @param yates is Yates' correction to be used?
+   * @return the chi-squared probability
+   */
+
+  public static double chiSquared(double [][] matrix, boolean yates) {
+
+    int df = (matrix.length - 1) * (matrix[0].length - 1);
+
+    return Statistics.chiSquaredProbability(chiVal(matrix, yates), df);
+  }
+
+  /**
+   * Computes chi-squared statistic for a contingency table.
+   *
+   * @param matrix the contigency table
+   * @param yates is Yates' correction to be used?
+   * @return the value of the chi-squared statistic
+   */
+  public static double chiVal(double [][] matrix, boolean useYates) {
+    
+    int df, nrows, ncols, row, col;
+    double[] rtotal, ctotal;
+    double expect = 0, chival = 0, n = 0;
+    boolean yates = true;
+    
+    nrows = matrix.length;
+    ncols = matrix[0].length;
+    rtotal = new double [nrows];
+    ctotal = new double [ncols];
+    for (row = 0; row < nrows; row++) {
+      for (col = 0; col < ncols; col++) {
+	rtotal[row] += matrix[row][col];
+	ctotal[col] += matrix[row][col];
+	n += matrix[row][col];
+      }
+    }
+    df = (nrows - 1)*(ncols - 1);
+    if ((df > 1) || (!useYates)) {
+      yates = false;
+    } else if (df <= 0) {
+      return 0;
+    }
+    chival = 0.0;
+    for (row = 0; row < nrows; row++) {
+      if (Utils.gr(rtotal[row], 0)) {
+	for (col = 0; col < ncols; col++) {
+	  if (Utils.gr(ctotal[col], 0)) {
+	    expect = (ctotal[col] * rtotal[row]) / n;
+	    chival += chiCell (matrix[row][col], expect, yates);
+	  }
+	}
+      }
+    }
+    return chival;
+  }
+
+  /**
+   * Tests if Cochran's criterion is fullfilled for the given
+   * contingency table. Rows and columns with all zeros are not considered
+   * relevant.
+   *
+   * @param matrix the contigency table to be tested
+   * @return true if contingency table is ok, false if not
+   */
+  public static boolean cochransCriterion(double[][] matrix) {
+
+    double[] rtotal, ctotal;
+    double n = 0, expect, smallfreq = 5;
+    int smallcount = 0, nonZeroRows = 0, nonZeroColumns = 0, nrows, ncols, 
+      row, col;
+
+    nrows = matrix.length;
+    ncols = matrix[0].length;
+
+    rtotal = new double [nrows];
+    ctotal = new double [ncols];
+    for (row = 0; row < nrows; row++) {
+      for (col = 0; col < ncols; col++) {
+	rtotal[row] += matrix[row][col];
+	ctotal[col] += matrix[row][col];
+	n += matrix[row][col];
+      }
+    }
+    for (row = 0; row < nrows; row++) {
+      if (Utils.gr(rtotal[row], 0)) {
+	nonZeroRows++;
+      }
+    }
+    for (col = 0; col < ncols; col++) {
+      if (Utils.gr(ctotal[col], 0)) {
+	nonZeroColumns++;
+      }
+    }
+    for (row = 0; row < nrows; row++) {
+      if (Utils.gr(rtotal[row], 0)) {
+	for (col = 0; col < ncols; col++) {
+	  if (Utils.gr(ctotal[col], 0)) {
+	    expect = (ctotal[col] * rtotal[row]) / n;
+	    if (Utils.sm(expect, smallfreq)) {
+	      if (Utils.sm(expect, 1)) {
+		return false;
+	      } else {
+		smallcount++;
+		if (smallcount > (nonZeroRows * nonZeroColumns) / smallfreq) {
+		  return false;
+		}
+	      }
+	    }
+	  }
+	}
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Computes Cramer's V for a contingency table.
+   *
+   * @param matrix the contingency table
+   * @return Cramer's V
+   */
+  public static double CramersV(double [][] matrix) {
+
+    int row, col, nrows,ncols, min;
+    double n = 0;
+    
+    nrows = matrix.length;
+    ncols = matrix[0].length;
+    for (row = 0; row < nrows; row++) {
+      for (col = 0; col < ncols; col++) {
+	n += matrix[row][col];
+      }
+    }
+    min = nrows < ncols ? nrows-1 : ncols-1;
+    if ((min == 0) || Utils.eq(n, 0))
+      return 0;
+    return Math.sqrt(chiVal(matrix, false) / (n * (double)min)); 
+  } 
+
+  /**
+   * Computes the entropy of the given array.
+   *
+   * @param array the array
+   * @return the entropy
+   */
+  public static double entropy(double[] array) {
+
+    double returnValue = 0, sum = 0;
+
+    for (int i = 0; i < array.length; i++) {
+      returnValue -= lnFunc(array[i]);
+      sum += array[i];
+    }
+    if (Utils.eq(sum, 0)) {
+      return 0;
+    } else {
+      return (returnValue + lnFunc(sum)) / (sum * log2);
+    }
+  }
+
+  /**
+   * Computes conditional entropy of the rows given
+   * the columns.
+   *
+   * @param matrix the contingency table
+   * @return the conditional entropy of the rows given the columns
+   */
+  public static double entropyConditionedOnColumns(double[][] matrix) {
+    
+    double returnValue = 0, sumForColumn, total = 0;
+
+    for (int j = 0; j < matrix[0].length; j++) {
+      sumForColumn = 0;
+      for (int i = 0; i < matrix.length; i++) {
+	returnValue = returnValue + lnFunc(matrix[i][j]);
+	sumForColumn += matrix[i][j];
+      }
+      returnValue = returnValue - lnFunc(sumForColumn);
+      total += sumForColumn;
+    }
+    if (Utils.eq(total, 0)) {
+      return 0;
+    }
+    return -returnValue / (total * log2);
+  }
+
+  /**
+   * Computes conditional entropy of the columns given
+   * the rows.
+   *
+   * @param matrix the contingency table
+   * @return the conditional entropy of the columns given the rows
+   */
+  public static double entropyConditionedOnRows(double[][] matrix) {
+    
+    double returnValue = 0, sumForRow, total = 0;
+
+    for (int i = 0; i < matrix.length; i++) {
+      sumForRow = 0;
+      for (int j = 0; j < matrix[0].length; j++) {
+	returnValue = returnValue + lnFunc(matrix[i][j]);
+	sumForRow += matrix[i][j];
+      }
+      returnValue = returnValue - lnFunc(sumForRow);
+      total += sumForRow;
+    }
+    if (Utils.eq(total, 0)) {
+      return 0;
+    }
+    return -returnValue / (total * log2);
+  }
+
+  /**
+   * Computes conditional entropy of the columns given the rows
+   * of the test matrix with respect to the train matrix. Uses a
+   * Laplace prior. Does NOT normalize the entropy.
+   *
+   * @param train the train matrix 
+   * @param test the test matrix
+   * @param the number of symbols for Laplace
+   * @return the entropy
+   */
+  public static double entropyConditionedOnRows(double[][] train, 
+						double[][] test,
+						double numClasses) {
+    
+    double returnValue = 0, trainSumForRow, testSumForRow, testSum = 0;
+
+    for (int i = 0; i < test.length; i++) {
+      trainSumForRow = 0;
+      testSumForRow = 0;
+      for (int j = 0; j < test[0].length; j++) {
+	returnValue -= test[i][j] * Math.log(train[i][j] + 1);
+	trainSumForRow += train[i][j];
+	testSumForRow += test[i][j];
+      }
+      testSum = testSumForRow;
+      returnValue += testSumForRow * Math.log(trainSumForRow + 
+					     numClasses);
+    }
+    return returnValue / (testSum * log2);
+  }
+
+  /**
+   * Computes the rows' entropy for the given contingency table.
+   *
+   * @param matrix the contingency table
+   * @return the rows' entropy
+   */
+  public static double entropyOverRows(double[][] matrix) {
+    
+    double returnValue = 0, sumForRow, total = 0;
+
+    for (int i = 0; i < matrix.length; i++) {
+      sumForRow = 0;
+      for (int j = 0; j < matrix[0].length; j++) {
+	sumForRow += matrix[i][j];
+      }
+      returnValue = returnValue - lnFunc(sumForRow);
+      total += sumForRow;
+    }
+    if (Utils.eq(total, 0)) {
+      return 0;
+    }
+    return (returnValue + lnFunc(total)) / (total * log2);
+  }
+
+  /**
+   * Computes the columns' entropy for the given contingency table.
+   *
+   * @param matrix the contingency table
+   * @return the columns' entropy
+   */
+  public static double entropyOverColumns(double[][] matrix){
+    
+    double returnValue = 0, sumForColumn, total = 0;
+
+    for (int j = 0; j < matrix[0].length; j++){
+      sumForColumn = 0;
+      for (int i = 0; i < matrix.length; i++) {
+	sumForColumn += matrix[i][j];
+      }
+      returnValue = returnValue - lnFunc(sumForColumn);
+      total += sumForColumn;
+    }
+    if (Utils.eq(total, 0)) {
+      return 0;
+    }
+    return (returnValue + lnFunc(total)) / (total * log2);
+  }
+
+  /**
+   * Computes gain ratio for contingency table (split on rows).
+   * Returns Double.MAX_VALUE if the split entropy is 0.
+   *
+   * @param matrix the contingency table
+   * @return the gain ratio
+   */
+  public static double gainRatio(double[][] matrix){
+    
+    double preSplit = 0, postSplit = 0, splitEnt = 0,
+      sumForRow, sumForColumn, total = 0, infoGain;
+
+    // Compute entropy before split
+    for (int i = 0; i < matrix[0].length; i++) {
+      sumForColumn = 0;
+      for (int j = 0; j < matrix.length; j++) 
+	sumForColumn += matrix[j][i];
+      preSplit += lnFunc(sumForColumn);
+      total += sumForColumn;
+    }
+    preSplit -= lnFunc(total);
+
+    // Compute entropy after split and split entropy
+    for (int i = 0; i < matrix.length; i++) {
+      sumForRow = 0;
+      for (int j = 0; j < matrix[0].length; j++) {
+	postSplit += lnFunc(matrix[i][j]);
+	sumForRow += matrix[i][j];
+      }
+      splitEnt += lnFunc(sumForRow);
+    }
+    postSplit -= splitEnt;
+    splitEnt -= lnFunc(total);
+
+    infoGain = preSplit - postSplit;
+    if (Utils.eq(splitEnt, 0))
+      return 0;
+    return infoGain / splitEnt;
+  }
+
+  /**
+   * Returns negative base 2 logarithm of multiple hypergeometric
+   * probability for a contingency table.
+   *
+   * @param matrix the contingency table
+   * @return the log of the hypergeometric probability of the contingency table 
+   */
+  public static double log2MultipleHypergeometric(double[][] matrix) {
+
+    double sum = 0, sumForRow, sumForColumn, total = 0;
+
+    for (int i = 0; i < matrix.length; i++) {
+      sumForRow = 0;
+      for (int j = 0; j < matrix[i].length; j++) {
+	sumForRow += matrix[i][j];
+      }
+      sum += SpecialFunctions.lnFactorial(sumForRow);
+      total += sumForRow;
+    }
+    for (int j = 0; j < matrix[0].length; j++) {
+      sumForColumn = 0;
+      for (int i = 0; i < matrix.length; i++) {
+	sumForColumn += matrix [i][j];
+      }
+      sum += SpecialFunctions.lnFactorial(sumForColumn);
+    }
+    for (int i = 0; i < matrix.length; i++) {
+      for (int j = 0; j < matrix[i].length; j++) {
+	sum -= SpecialFunctions.lnFactorial(matrix[i][j]);
+      }
+    }
+    sum -= SpecialFunctions.lnFactorial(total);
+    return -sum / log2;
+  }
+
+  /**
+   * Reduces a matrix by deleting all zero rows and columns.
+   *
+   * @param matrix the matrix to be reduced
+   * @param the matrix with all zero rows and columns deleted
+   */
+  public static double[][] reduceMatrix(double[][] matrix) {
+
+    int row, col, currCol, currRow, nrows, ncols, 
+      nonZeroRows = 0, nonZeroColumns = 0;
+    double[] rtotal, ctotal;
+    double[][] newMatrix;
+
+    nrows = matrix.length;
+    ncols = matrix[0].length;
+    rtotal = new double [nrows];
+    ctotal = new double [ncols];
+    for (row = 0; row < nrows; row++) {
+      for (col = 0; col < ncols; col++) {
+	rtotal[row] += matrix[row][col];
+	ctotal[col] += matrix[row][col];
+      }
+    }
+    for (row = 0; row < nrows; row++) {
+      if (Utils.gr(rtotal[row],0)) {
+	nonZeroRows++;
+      }
+    }
+    for (col = 0; col < ncols; col++) {
+      if (Utils.gr(ctotal[col],0)) {
+	nonZeroColumns++;
+      }
+    }
+    newMatrix = new double[nonZeroRows][nonZeroColumns];
+    currRow = 0;
+    for (row = 0; row < nrows; row++) {
+      if (Utils.gr(rtotal[row],0)) {
+	currCol = 0;
+	for (col = 0; col < ncols; col++) {
+	  if (Utils.gr(ctotal[col],0)) {
+	    newMatrix[currRow][currCol] = matrix[row][col];
+	    currCol++;
+	  }
+	}
+	currRow++;
+      }
+    }
+    return newMatrix;
+  }
+    
+   /**
+    * Calculates the symmetrical uncertainty for base 2.
+    *
+    * @param matrix the contingency table
+    * @return the calculated symmetrical uncertainty
+    *
+    */
+  public static double symmetricalUncertainty(double matrix[][]) {
+
+    double sumForColumn, sumForRow, total = 0, columnEntropy = 0, 
+      rowEntropy = 0, entropyConditionedOnRows = 0, infoGain = 0;
+
+    // Compute entropy for columns
+    for (int i = 0; i < matrix[0].length; i++) {
+      sumForColumn = 0;
+      for (int j = 0; j < matrix.length; j++) {
+	sumForColumn += matrix[j][i];
+      }
+      columnEntropy += lnFunc(sumForColumn);
+      total += sumForColumn;
+    }
+    columnEntropy -= lnFunc(total);
+
+    // Compute entropy for rows and conditional entropy
+    for (int i = 0; i < matrix.length; i++) {
+      sumForRow = 0;
+      for (int j = 0; j < matrix[0].length; j++) { 
+	sumForRow += matrix[i][j];
+	entropyConditionedOnRows += lnFunc(matrix[i][j]);
+      }
+      rowEntropy += lnFunc(sumForRow);
+    }
+    entropyConditionedOnRows -= rowEntropy;
+    rowEntropy -= lnFunc(total);
+    infoGain = columnEntropy - entropyConditionedOnRows;
+    if (Utils.eq(columnEntropy, 0) || Utils.eq(rowEntropy, 0))
+      return 0;
+    return 2.0 * (infoGain / (columnEntropy + rowEntropy));
+  }
+
+  /**
+   * Computes Goodman and Kruskal's tau-value for a contingency table.
+   *
+   * @param matrix the contingency table
+   * @param Goodman and Kruskal's tau-value
+   */
+  public static double tauVal(double[][] matrix) {
+    
+    int nrows, ncols, row, col;
+    double [] ctotal;
+    double maxcol = 0, max, maxtotal = 0, n = 0;
+    
+    nrows = matrix.length;
+    ncols = matrix[0].length;
+    ctotal = new double [ncols];
+    for (row = 0; row < nrows; row++) {
+      max = 0;
+      for (col = 0; col < ncols; col++) {
+	if (Utils.gr(matrix[row][col], max)) 
+	  max = matrix[row][col];
+	ctotal[col] += matrix[row][col];
+	n += matrix[row][col];
+      }
+      maxtotal += max;
+    }
+    if (Utils.eq(n, 0)) {
+      return 0;
+    }
+    maxcol = ctotal[Utils.maxIndex(ctotal)];
+    return (maxtotal - maxcol)/(n - maxcol);
+  }
+
+  /**
+   * Help method for computing entropy.
+   */
+  private static double lnFunc(double num){
+    
+    // Constant hard coded for efficiency reasons
+    if (num < 1e-6) {
+      return 0;
+    } else {
+      return num * Math.log(num);
+    }
+  }
+  
+  /**
+   * Computes chi-value for one cell in matrix.
+   * From Gary Perlman's unixstat.
+   */
+  private static double chiCell(double freq, double expect, boolean yates){
+
+    double  diff = freq - expect;
+       
+    if (yates) {
+      diff = Math.abs (diff) - 0.5;
+      if (diff < 0.0) { // over-correction
+	diff = 0.0;
+      }
+    }
+    if (Math.abs(expect) < 10e-10) {
+      return (0.0);
+    } else {
+      return (diff * diff / expect);
+    }
+  }
+
+  /**
+   * Main method for testing this class.
+   */
+  public static void main(String[] ops) {
+
+    double[] firstRow = {10, 5, 20};
+    double[] secondRow = {2, 10, 6};
+    double[] thirdRow = {5, 10, 10};
+    double[][] matrix = new double[3][0];
+
+    matrix[0] = firstRow; matrix[1] = secondRow; matrix[2] = thirdRow;
+    for (int i = 0; i < matrix.length; i++) {
+      for (int j = 0; j < matrix[i].length; j++) {
+	System.out.print(matrix[i][j] + " ");
+      }
+      System.out.println();
+    }
+    System.out.println("Chi-squared probability: " +
+		       ContingencyTables.chiSquared(matrix, false));
+    System.out.println("Chi-squared value: " +
+		       ContingencyTables.chiVal(matrix, false));
+    System.out.println("Cochran's criterion fullfilled: " +
+		       ContingencyTables.cochransCriterion(matrix));
+    System.out.println("Cramer's V: " +
+		       ContingencyTables.CramersV(matrix));
+    System.out.println("Entropy of first row: " +
+		       ContingencyTables.entropy(firstRow));
+    System.out.println("Entropy conditioned on columns: " +
+		       ContingencyTables.entropyConditionedOnColumns(matrix));
+    System.out.println("Entropy conditioned on rows: " +
+		       ContingencyTables.entropyConditionedOnRows(matrix));
+    System.out.println("Entropy conditioned on rows (with Laplace): " +
+		       ContingencyTables.entropyConditionedOnRows(matrix, matrix, 3));
+    System.out.println("Entropy of rows: " +
+		       ContingencyTables.entropyOverRows(matrix));
+    System.out.println("Entropy of columns: " +
+		       ContingencyTables.entropyOverColumns(matrix));
+    System.out.println("Gain ratio: " +
+		       ContingencyTables.gainRatio(matrix));
+    System.out.println("Negative log2 of multiple hypergeometric probability: " +
+		       ContingencyTables.log2MultipleHypergeometric(matrix));
+    System.out.println("Symmetrical uncertainty: " +
+		       ContingencyTables.symmetricalUncertainty(matrix));
+    System.out.println("Tau value: " +
+		       ContingencyTables.tauVal(matrix));
+    double[][] newMatrix = new double[3][3];
+    newMatrix[0][0] = 1; newMatrix[0][1] = 0; newMatrix[0][2] = 1;
+    newMatrix[1][0] = 0; newMatrix[1][1] = 0; newMatrix[1][2] = 0;
+    newMatrix[2][0] = 1; newMatrix[2][1] = 0; newMatrix[2][2] = 1;
+    System.out.println("Matrix with empty row and column: ");
+    for (int i = 0; i < newMatrix.length; i++) {
+      for (int j = 0; j < newMatrix[i].length; j++) {
+	System.out.print(newMatrix[i][j] + " ");
+      }
+      System.out.println();
+    }
+    System.out.println("Reduced matrix: ");
+    newMatrix = ContingencyTables.reduceMatrix(newMatrix);
+    for (int i = 0; i < newMatrix.length; i++) {
+      for (int j = 0; j < newMatrix[i].length; j++) {
+	System.out.print(newMatrix[i][j] + " ");
+      }
+      System.out.println();
+    }
+  }
+}
+
+
+
+
+
+
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Copyable.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Copyable.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Copyable.java	(revision 20131)
@@ -0,0 +1,41 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    Copyable.java
+ *    Copyright (C) 1999 Eibe Frank
+ *
+ */
+
+package weka.core;
+
+/**
+ * Interface implemented by classes that can produce "shallow" copies
+ * of their objects. (As opposed to clone(), which is supposed to
+ * produce a "deep" copy.)
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public interface Copyable {
+
+  /**
+   * This method produces a shallow copy of an object.
+   * It does the same as the clone() method in Object, which also produces
+   * a shallow copy.
+   */
+  public Object copy();
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/FastVector.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/FastVector.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/FastVector.java	(revision 20131)
@@ -0,0 +1,432 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    FastVector.java
+ *    Copyright (C) 1999 Eibe Frank
+ *
+ */
+
+package weka.core;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * Implements a fast vector class without synchronized
+ * methods. Replaces java.util.Vector. (Synchronized methods tend to
+ * be slow.)
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version $Revision$ */
+public class FastVector implements Copyable, Serializable {
+
+  /**
+   * Class for enumerating the vector's elements.
+   */
+  public class FastVectorEnumeration implements Enumeration {
+
+    /** The counter. */
+    private int m_Counter;
+
+    /** The vector. */
+    private FastVector m_Vector;
+
+    /** Special element. Skipped during enumeration. */
+    private int m_SpecialElement;
+
+    /**
+     * Constructs an enumeration.
+     *
+     * @param vector the vector which is to be enumerated
+     */
+    public FastVectorEnumeration(FastVector vector) {
+
+      m_Counter = 0;
+      m_Vector = vector;
+      m_SpecialElement = -1;
+    }
+
+    /**
+     * Constructs an enumeration with a special element.
+     * The special element is skipped during the enumeration.
+     *
+     * @param vector the vector which is to be enumerated
+     * @param special the index of the special element
+     */
+    public FastVectorEnumeration(FastVector vector, int special) {
+
+      m_Vector = vector;
+      m_SpecialElement = special;
+      if (special == 0) {
+	m_Counter = 1;
+      } else {
+	m_Counter = 0;
+      }
+    }
+
+
+    /**
+     * Tests if there are any more elements to enumerate.
+     *
+     * @return true if there are some elements left
+     */
+    public final boolean hasMoreElements() {
+
+      if (m_Counter < m_Vector.size()) {
+	return true;
+      }
+      return false;
+    }
+
+    /**
+     * Returns the next element.
+     *
+     * @return the next element to be enumerated
+     */
+    public final Object nextElement() {
+  
+      Object result = m_Vector.elementAt(m_Counter);
+
+      m_Counter++;
+      if (m_Counter == m_SpecialElement) {
+	m_Counter++;
+      }
+      return result;
+    }
+  }
+
+  /** The array of objects. */
+  private Object[] m_Objects;
+
+  /** The current size; */
+  private int m_Size;
+
+  /** The capacity increment */
+  private int m_CapacityIncrement;
+  
+  /** The capacity multiplier. */
+  private double m_CapacityMultiplier;
+
+  /**
+   * Constructs an empty vector with initial
+   * capacity zero.
+   */
+  public FastVector() {
+  
+    m_Objects = new Object[0];
+    m_Size = 0;
+    m_CapacityIncrement = 1;
+    m_CapacityMultiplier = 2;
+  }
+
+  /**
+   * Constructs a vector with the given capacity.
+   *
+   * @param capacity the vector's initial capacity
+   */
+  public FastVector(int capacity) {
+
+    m_Objects = new Object[capacity];
+    m_Size = 0;
+    m_CapacityIncrement = 1;
+    m_CapacityMultiplier = 2;
+  }
+
+  /**
+   * Constructs a vector with the given capacity, capacity 
+   * increment and capacity mulitplier.
+   *
+   * @param capacity the vector's initial capacity
+   */
+  public FastVector(int capacity, int capIncrement, 
+		    double capMultiplier) {
+
+    m_Objects = new Object[capacity];
+    m_Size = 0;
+    m_CapacityIncrement = capIncrement;
+    m_CapacityMultiplier = capMultiplier;
+  }
+
+  /**
+   * Adds an element to this vector. Increases its
+   * capacity if its not large enough.
+   *
+   * @param element the element to add
+   */
+  public final void addElement(Object element) {
+
+    Object[] newObjects;
+
+    if (m_Size == m_Objects.length) {
+      newObjects = new Object[(int)m_CapacityMultiplier *
+			     (m_Objects.length +
+			      m_CapacityIncrement)];
+      System.arraycopy(m_Objects, 0, newObjects, 0, m_Size);
+      m_Objects = newObjects;
+    }
+    m_Objects[m_Size] = element;
+    m_Size++;
+  }
+
+  /**
+   * Returns the capacity of the vector.
+   *
+   * @return the capacity of the vector
+   */
+  public final int capacity() {
+  
+    return m_Objects.length;
+  }
+
+  /**
+   * Produces a shallow copy of this vector.
+   *
+   * @return the new vector
+   */
+  public final Object copy() {
+
+    FastVector copy = new FastVector(m_Objects.length, 
+				     m_CapacityIncrement,
+				     m_CapacityMultiplier);
+    copy.m_Size = m_Size;
+    System.arraycopy(m_Objects, 0, copy.m_Objects, 0, m_Size);
+    return copy;
+  }
+
+  /**
+   * Clones the vector and shallow copies all its elements.
+   * The elements have to implement the Copyable interface.
+   * 
+   * @return the new vector
+   */
+  public final Object copyElements() {
+
+    FastVector copy = new FastVector(m_Objects.length, 
+				     m_CapacityIncrement,
+				     m_CapacityMultiplier);
+    copy.m_Size = m_Size;
+    for (int i = 0; i < m_Size; i++) {
+      copy.m_Objects[i] = ((Copyable)m_Objects[i]).copy();
+    }
+    return copy;
+  }
+
+  /**
+   * Returns the element at the given position.
+   *
+   * @param index the element's index
+   * @return the element with the given index
+   */
+  public final Object elementAt(int index) {
+
+    return m_Objects[index];
+  }
+
+  /**
+   * Returns an enumeration of this vector.
+   *
+   * @return an enumeration of this vector
+   */
+  public final Enumeration elements() {
+  
+    return new FastVectorEnumeration(this);
+  }
+
+  /**
+   * Returns an enumeration of this vector, skipping the
+   * element with the given index.
+   *
+   * @param index the element to skip
+   * @return an enumeration of this vector
+   */
+  public final Enumeration elements(int index) {
+  
+    return new FastVectorEnumeration(this, index);
+  }
+
+  /**
+   * Returns the first element of the vector.
+   *
+   * @return the first element of the vector
+   */
+  public final Object firstElement() {
+
+    return m_Objects[0];
+  }
+
+  /**
+   * Searches for the first occurence of the given argument, 
+   * testing for equality using the equals method. 
+   *
+   * @param element the element to be found
+   * @return the index of the first occurrence of the argument 
+   * in this vector; returns -1 if the object is not found
+   */
+  public final int indexOf(Object element) {
+
+    for (int i = 0; i < m_Size; i++) {
+      if (element.equals(m_Objects[i])) {
+	return i;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Inserts an element at the given position.
+   *
+   * @param element the element to be inserted
+   * @param index the element's index
+   */
+  public final void insertElementAt(Object element, int index) {
+
+    Object[] newObjects;
+
+    if (m_Size < m_Objects.length) {
+      System.arraycopy(m_Objects, index, m_Objects, index + 1, 
+                       m_Size - index);
+      m_Objects[index] = element;
+    } else {
+      newObjects = new Object[(int)m_CapacityMultiplier *
+			     (m_Objects.length +
+			      m_CapacityIncrement)];
+      System.arraycopy(m_Objects, 0, newObjects, 0, index);
+      newObjects[index] = element;
+      System.arraycopy(m_Objects, index, newObjects, index + 1,
+		       m_Size - index);
+      m_Objects = newObjects;
+    }
+    m_Size++;
+  }
+
+  /**
+   * Returns the last element of the vector.
+   *
+   * @return the last element of the vector
+   */
+  public final Object lastElement() {
+
+    return m_Objects[m_Size - 1];
+  }
+
+  /**
+   * Deletes an element from this vector.
+   *
+   * @param index the index of the element to be deleted
+   */
+  public final void removeElementAt(int index) {
+
+    System.arraycopy(m_Objects, index + 1, m_Objects, index, 
+                     m_Size - index - 1);
+    m_Size--;
+  }
+
+  /**
+   * Removes all components from this vector and sets its 
+   * size to zero. 
+   */
+  public final void removeAllElements() {
+
+    m_Objects = new Object[m_Objects.length];
+    m_Size = 0;
+  }
+
+  /**
+   * Appends all elements of the supplied vector to this vector.
+   *
+   * @param toAppend the FastVector containing elements to append.
+   */
+  public final void appendElements(FastVector toAppend) {
+
+    setCapacity(size() + toAppend.size());
+    System.arraycopy(toAppend.m_Objects, 0, m_Objects, size(), toAppend.size());
+    m_Size = m_Objects.length;
+  }
+
+  /** 
+   * Returns all the elements of this vector as an array
+   *
+   * @param an array containing all the elements of this vector
+   */
+  public final Object [] toArray() {
+
+    Object [] newObjects = new Object[size()];
+    System.arraycopy(m_Objects, 0, newObjects, 0, size());
+    return newObjects;
+  }
+
+  /**
+   * Sets the vector's capacity to the given value.
+   *
+   * @param capacity the new capacity
+   */
+  public final void setCapacity(int capacity) {
+
+    Object[] newObjects = new Object[capacity];
+   
+    System.arraycopy(m_Objects, 0, newObjects, 0, Math.min(capacity, m_Size));
+    m_Objects = newObjects;
+    if (m_Objects.length < m_Size)
+      m_Size = m_Objects.length;
+  }
+
+  /**
+   * Sets the element at the given index.
+   *
+   * @param element the element to be put into the vector
+   * @param index the index at which the element is to be placed
+   */
+  public final void setElementAt(Object element, int index) {
+
+    m_Objects[index] = element;
+  }
+
+  /**
+   * Returns the vector's current size.
+   *
+   * @return the vector's current size
+   */
+  public final int size() {
+
+    return m_Size;
+  }
+
+  /**
+   * Swaps two elements in the vector.
+   *
+   * @param first index of the first element
+   * @param second index of the second element
+   */
+  public final void swap(int first, int second) {
+
+    Object help = m_Objects[first];
+
+    m_Objects[first] = m_Objects[second];
+    m_Objects[second] = help;
+  }
+
+  /**
+   * Sets the vector's capacity to its size.
+   */
+  public final void trimToSize() {
+
+    Object[] newObjects = new Object[m_Size];
+    
+    System.arraycopy(m_Objects, 0, newObjects, 0, m_Size);
+    m_Objects = newObjects;
+  }
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Instance.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Instance.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Instance.java	(revision 20131)
@@ -0,0 +1,1064 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    Instance.java
+ *    Copyright (C) 1999 Eibe Frank
+ *
+ */
+
+package weka.core;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * Class for handling an instance. All values (numeric, nominal, or
+ * string) are internally stored as floating-point numbers. If an
+ * attribute is nominal (or a string), the stored value is the index
+ * of the corresponding nominal (or string) value in the attribute's
+ * definition. We have chosen this approach in favor of a more elegant
+ * object-oriented approach because it is much faster. <p>
+ *
+ * Typical usage (code from the main() method of this class): <p>
+ *
+ * <code>
+ * ... <br>
+ *      
+ * // Create empty instance with three attribute values <br>
+ * Instance inst = new Instance(3); <br><br>
+ *     
+ * // Set instance's values for the attributes "length", "weight", and "position"<br>
+ * inst.setValue(length, 5.3); <br>
+ * inst.setValue(weight, 300); <br>
+ * inst.setValue(position, "first"); <br><br>
+ *   
+ * // Set instance's dataset to be the dataset "race" <br>
+ * inst.setDataset(race); <br><br>
+ *   
+ * // Print the instance <br>
+ * System.out.println("The instance: " + inst); <br>
+ *
+ * ... <br>
+ * </code><p>
+ *
+ * All methods that change an instance are safe, ie. a change of an
+ * instance does not affect any other instances. All methods that
+ * change an instance's attribute values clone the attribute value
+ * vector before it is changed. If your application heavily modifies
+ * instance values, it may be faster to create a new instance from scratch.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version $Revision$ 
+ */
+public class Instance implements Copyable, Serializable {
+  
+  /** Constant representing a missing value. */
+  protected final static double MISSING_VALUE = Double.NaN;
+
+  /** 
+   * The dataset the instance has access to.  Null if the instance
+   * doesn't have access to any dataset.  Only if an instance has
+   * access to a dataset, it knows about the actual attribute types.  
+   */
+  protected Instances m_Dataset;
+
+  /** The instance's attribute values. */
+  protected double[] m_AttValues;
+
+  /** The instance's weight. */
+  protected double m_Weight;
+
+  /**
+   * Constructor that copies the attribute values and the weight from
+   * the given instance. Reference to the dataset is set to null.
+   * (ie. the instance doesn't have access to information about the
+   * attribute types)
+   *
+   * @param instance the instance from which the attribute
+   * values and the weight are to be copied 
+   */
+  public Instance(Instance instance) {
+    
+    m_AttValues = instance.m_AttValues;
+    m_Weight = instance.m_Weight;
+    m_Dataset = null;
+  }
+
+  /**
+   * Constructor that inititalizes instance variable with given
+   * values. Reference to the dataset is set to null. (ie. the instance
+   * doesn't have access to information about the attribute types)
+   *
+   * @param weight the instance's weight
+   * @param attValues a vector of attribute values 
+   */
+  public Instance(double weight, double[] attValues){
+    
+    m_AttValues = attValues;
+    m_Weight = weight;
+    m_Dataset = null;
+  }
+
+  /**
+   * Constructor of an instance that sets weight to one, all values to
+   * be missing, and the reference to the dataset to null. (ie. the instance
+   * doesn't have access to information about the attribute types)
+   *
+   * @param numAttributes the size of the instance 
+   */
+  public Instance(int numAttributes) {
+    
+    m_AttValues = new double[numAttributes];
+    for (int i = 0; i < m_AttValues.length; i++) {
+      m_AttValues[i] = MISSING_VALUE;
+    }
+    m_Weight = 1;
+    m_Dataset = null;
+  }
+
+  /**
+   * Returns the attribute with the given index.
+   *
+   * @param index the attribute's index
+   * @return the attribute at the given position
+   * @exception UnassignedDatasetException if instance doesn't have access to a
+   * dataset
+   */ 
+  public Attribute attribute(int index) {
+   
+    if (m_Dataset == null) {
+      throw new UnassignedDatasetException("Instance doesn't have access to a dataset!");
+    }
+    return m_Dataset.attribute(index);
+  }
+
+  /**
+   * Returns the attribute with the given index. Does the same
+   * thing as attribute().
+   *
+   * @param indexOfIndex the index of the attribute's index 
+   * @return the attribute at the given position
+   * @exception UnassignedDatasetException if instance doesn't have access to a
+   * dataset
+   */ 
+  public Attribute attributeSparse(int indexOfIndex) {
+   
+    if (m_Dataset == null) {
+      throw new UnassignedDatasetException("Instance doesn't have access to a dataset!");
+    }
+    return m_Dataset.attribute(indexOfIndex);
+  }
+
+  /**
+   * Returns class attribute.
+   *
+   * @return the class attribute
+   * @exception UnassignedDatasetException if the class is not set or the
+   * instance doesn't have access to a dataset
+   */
+  public Attribute classAttribute() {
+
+    if (m_Dataset == null) {
+      throw new UnassignedDatasetException("Instance doesn't have access to a dataset!");
+    }
+    return m_Dataset.classAttribute();
+  }
+
+  /**
+   * Returns the class attribute's index.
+   *
+   * @return the class index as an integer 
+   * @exception UnassignedDatasetException if instance doesn't have access to a dataset 
+   */
+  public int classIndex() {
+    
+    if (m_Dataset == null) {
+      throw new UnassignedDatasetException("Instance doesn't have access to a dataset!");
+    }
+    return m_Dataset.classIndex();
+  }
+
+  /**
+   * Tests if an instance's class is missing.
+   *
+   * @return true if the instance's class is missing
+   * @exception UnassignedClassException if the class is not set or the instance doesn't
+   * have access to a dataset
+   */
+  public boolean classIsMissing() {
+
+    if (classIndex() < 0) {
+      throw new UnassignedClassException("Class is not set!");
+    }
+    return isMissing(classIndex());
+  }
+
+  /**
+   * Returns an instance's class value in internal format. (ie. as a
+   * floating-point number)
+   *
+   * @return the corresponding value as a double (If the 
+   * corresponding attribute is nominal (or a string) then it returns the 
+   * value's index as a double).
+   * @exception UnassignedClassException if the class is not set or the instance doesn't
+   * have access to a dataset 
+   */
+  public double classValue() {
+    
+    if (classIndex() < 0) {
+      throw new UnassignedClassException("Class is not set!");
+    }
+    return value(classIndex());
+  }
+
+  /**
+   * Produces a shallow copy of this instance. The copy has
+   * access to the same dataset. (if you want to make a copy
+   * that doesn't have access to the dataset, use 
+   * <code>new Instance(instance)</code>
+   *
+   * @return the shallow copy
+   */
+  public Object copy() {
+
+    Instance result = new Instance(this);
+    result.m_Dataset = m_Dataset;
+    return result;
+  }
+
+  /**
+   * Returns the dataset this instance has access to. (ie. obtains
+   * information about attribute types from) Null if the instance
+   * doesn't have access to a dataset.
+   *
+   * @return the dataset the instance has accesss to
+   */
+  public Instances dataset() {
+
+    return m_Dataset;
+  }
+
+  /**
+   * Deletes an attribute at the given position (0 to 
+   * numAttributes() - 1). Only succeeds if the instance does not
+   * have access to any dataset because otherwise inconsistencies
+   * could be introduced.
+   *
+   * @param pos the attribute's position
+   * @exception RuntimeException if the instance has access to a
+   * dataset 
+   */
+  public void deleteAttributeAt(int position) {
+
+    if (m_Dataset != null) {
+      throw new RuntimeException("Instance has access to a dataset!");
+    }
+    forceDeleteAttributeAt(position);
+  }
+
+  /**
+   * Returns an enumeration of all the attributes.
+   *
+   * @return enumeration of all the attributes
+   * @exception UnassignedDatasetException if the instance doesn't
+   * have access to a dataset 
+   */
+  public Enumeration enumerateAttributes() {
+
+    if (m_Dataset == null) {
+      throw new UnassignedDatasetException("Instance doesn't have access to a dataset!");
+    }
+    return m_Dataset.enumerateAttributes();
+  }
+
+  /**
+   * Tests if the headers of two instances are equivalent.
+   *
+   * @param instance another instance
+   * @return true if the header of the given instance is 
+   * equivalent to this instance's header
+   * @exception UnassignedDatasetException if instance doesn't have access to any
+   * dataset
+   */
+  public boolean equalHeaders(Instance inst) {
+
+    if (m_Dataset == null) {
+      throw new UnassignedDatasetException("Instance doesn't have access to a dataset!");
+    }
+    return m_Dataset.equalHeaders(inst.m_Dataset);
+  }
+
+  /**
+   * Returns the index of the attribute stored at the given position.
+   * Just returns the given value.
+   *
+   * @param position the position 
+   * @return the index of the attribute stored at the given position
+   */
+  public int index(int position) {
+
+    return position;
+  }
+
+  /**
+   * Inserts an attribute at the given position (0 to 
+   * numAttributes()). Only succeeds if the instance does not
+   * have access to any dataset because otherwise inconsistencies
+   * could be introduced.
+   *
+   * @param pos the attribute's position
+   * @exception RuntimeException if the instance has accesss to a
+   * dataset
+   * @exception IllegalArgumentException if the position is out of range
+   */
+  public void insertAttributeAt(int position) {
+
+    if (m_Dataset != null) {
+      throw new RuntimeException("Instance has accesss to a dataset!");
+    }
+    if ((position < 0) ||
+	(position > numAttributes())) {
+      throw new IllegalArgumentException("Can't insert attribute: index out "+
+                                         "of range");
+    }
+    forceInsertAttributeAt(position);
+  }
+
+  /**
+   * Tests if a specific value is "missing".
+   *
+   * @param attIndex the attribute's index
+   */
+  public boolean isMissing(int attIndex) {
+
+    if (Double.isNaN(m_AttValues[attIndex])) {
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Tests if a specific value is "missing". Does
+   * the same thing as isMissing() if applied to an Instance.
+   *
+   * @param indexOfIndex the index of the attribute's index 
+   */
+  public boolean isMissingSparse(int indexOfIndex) {
+
+    if (Double.isNaN(m_AttValues[indexOfIndex])) {
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Tests if a specific value is "missing".
+   * The given attribute has to belong to a dataset.
+   *
+   * @param att the attribute
+   */
+  public boolean isMissing(Attribute att) {
+
+    return isMissing(att.index());
+  }
+
+  /**
+   * Tests if the given value codes "missing".
+   *
+   * @param val the value to be tested
+   * @return true if val codes "missing"
+   */
+  public static boolean isMissingValue(double val) {
+
+    return Double.isNaN(val);
+  }
+
+  /**
+   * Merges this instance with the given instance and returns
+   * the result. Dataset is set to null.
+   *
+   * @param inst the instance to be merged with this one
+   * @return the merged instances
+   */
+  public Instance mergeInstance(Instance inst) {
+
+    int m = 0;
+    double [] newVals = new double[numAttributes() + inst.numAttributes()];
+    for (int j = 0; j < numAttributes(); j++, m++) {
+      newVals[m] = value(j);
+    }
+    for (int j = 0; j < inst.numAttributes(); j++, m++) {
+      newVals[m] = inst.value(j);
+    }
+    return new Instance(1.0, newVals);
+  }
+
+  /**
+   * Returns the double that codes "missing".
+   *
+   * @return the double that codes "missing"
+   */
+  public static double missingValue() {
+
+    return MISSING_VALUE;
+  }
+
+  /**
+   * Returns the number of attributes.
+   *
+   * @return the number of attributes as an integer
+   */
+  public int numAttributes() {
+
+    return m_AttValues.length;
+  }
+
+  /**
+   * Returns the number of class labels.
+   *
+   * @return the number of class labels as an integer if the 
+   * class attribute is nominal, 1 otherwise.
+   * @exception UnassignedDatasetException if instance doesn't have access to any
+   * dataset
+   */
+  public int numClasses() {
+    
+    if (m_Dataset == null) {
+      throw new UnassignedDatasetException("Instance doesn't have access to a dataset!");
+    }
+    return m_Dataset.numClasses();
+  }
+
+  /**
+   * Returns the number of values present. Always the same as numAttributes().
+   *
+   * @return the number of values
+   */
+  public int numValues() {
+
+    return m_AttValues.length;
+  }
+
+  /** 
+   * Replaces all missing values in the instance with the
+   * values contained in the given array. A deep copy of
+   * the vector of attribute values is performed before the
+   * values are replaced.
+   *
+   * @param array containing the means and modes
+   * @exception IllegalArgumentException if numbers of attributes are unequal
+   */
+  public void replaceMissingValues(double[] array) {
+	 
+    if ((array == null) || 
+	(array.length != m_AttValues.length)) {
+      throw new IllegalArgumentException("Unequal number of attributes!");
+    }
+    freshAttributeVector();
+    for (int i = 0; i < m_AttValues.length; i++) {
+      if (isMissing(i)) {
+	m_AttValues[i] = array[i];
+      }
+    }
+  }
+
+  /**
+   * Sets the class value of an instance to be "missing". A deep copy of
+   * the vector of attribute values is performed before the
+   * value is set to be missing.
+   *
+   * @exception UnassignedClassException if the class is not set
+   * @exception UnassignedDatasetException if the instance doesn't
+   * have access to a dataset
+   */
+  public void setClassMissing() {
+
+    if (classIndex() < 0) {
+      throw new UnassignedClassException("Class is not set!");
+    }
+    setMissing(classIndex());
+  }
+
+  /**
+   * Sets the class value of an instance to the given value (internal
+   * floating-point format).  A deep copy of the vector of attribute
+   * values is performed before the value is set.
+   *
+   * @param value the new attribute value (If the corresponding
+   * attribute is nominal (or a string) then this is the new value's
+   * index as a double).  
+   * @exception UnassignedClassException if the class is not set
+   * @exception UnaddignedDatasetException if the instance doesn't
+   * have access to a dataset 
+   */
+  public void setClassValue(double value) {
+
+    if (classIndex() < 0) {
+      throw new UnassignedClassException("Class is not set!");
+    }
+    setValue(classIndex(), value);
+  }
+
+  /**
+   * Sets the class value of an instance to the given value. A deep
+   * copy of the vector of attribute values is performed before the
+   * value is set.
+   *
+   * @param value the new class value (If the class
+   * is a string attribute and the value can't be found,
+   * the value is added to the attribute).
+   * @exception UnassignedClassException if the class is not set
+   * @exception UnassignedDatasetException if the dataset is not set
+   * @exception IllegalArgumentException if the attribute is not
+   * nominal or a string, or the value couldn't be found for a nominal
+   * attribute 
+   */
+  public final void setClassValue(String value) {
+
+    if (classIndex() < 0) {
+      throw new UnassignedClassException("Class is not set!");
+    }
+    setValue(classIndex(), value);
+  }
+
+  /**
+   * Sets the reference to the dataset. Does not check if the instance
+   * is compatible with the dataset. Note: the dataset does not know
+   * about this instance. If the structure of the dataset's header
+   * gets changed, this instance will not be adjusted automatically.
+   *
+   * @param instances the reference to the dataset 
+   */
+  public final void setDataset(Instances instances) {
+    
+    m_Dataset = instances;
+  }
+
+  /**
+   * Sets a specific value to be "missing". Performs a deep copy
+   * of the vector of attribute values before the value is set to
+   * be missing.
+   *
+   * @param attIndex the attribute's index
+   */
+  public final void setMissing(int attIndex) {
+
+    setValue(attIndex, MISSING_VALUE);
+  }
+
+  /**
+   * Sets a specific value to be "missing". Performs a deep copy
+   * of the vector of attribute values before the value is set to
+   * be missing. The given attribute has to belong to a dataset.
+   *
+   * @param att the attribute
+   */
+  public final void setMissing(Attribute att) {
+
+    setMissing(att.index());
+  }
+
+  /**
+   * Sets a specific value in the instance to the given value 
+   * (internal floating-point format). Performs a deep copy
+   * of the vector of attribute values before the value is set.
+   *
+   * @param attIndex the attribute's index 
+   * @param value the new attribute value (If the corresponding
+   * attribute is nominal (or a string) then this is the new value's
+   * index as a double).  
+   */
+  public void setValue(int attIndex, double value) {
+    
+    freshAttributeVector();
+    m_AttValues[attIndex] = value;
+  }
+
+  /**
+   * Sets a specific value in the instance to the given value 
+   * (internal floating-point format). Performs a deep copy
+   * of the vector of attribute values before the value is set.
+   * Does exactly the same thing as setValue().
+   *
+   * @param indexOfIndex the index of the attribute's index 
+   * @param value the new attribute value (If the corresponding
+   * attribute is nominal (or a string) then this is the new value's
+   * index as a double).  
+   */
+  public void setValueSparse(int indexOfIndex, double value) {
+    
+    freshAttributeVector();
+    m_AttValues[indexOfIndex] = value;
+  }
+
+  /**
+   * Sets a value of a nominal or string attribute to the given
+   * value. Performs a deep copy of the vector of attribute values
+   * before the value is set.
+   *
+   * @param attIndex the attribute's index
+   * @param value the new attribute value (If the attribute
+   * is a string attribute and the value can't be found,
+   * the value is added to the attribute).
+   * @exception UnassignedDatasetException if the dataset is not set
+   * @exception IllegalArgumentException if the selected
+   * attribute is not nominal or a string, or the supplied value couldn't 
+   * be found for a nominal attribute 
+   */
+  public final void setValue(int attIndex, String value) {
+    
+    int valIndex;
+
+    if (m_Dataset == null) {
+      throw new UnassignedDatasetException("Instance doesn't have access to a dataset!");
+    }
+    if (!attribute(attIndex).isNominal() &&
+	!attribute(attIndex).isString()) {
+      throw new IllegalArgumentException("Attribute neither nominal nor string!");
+    }
+    valIndex = attribute(attIndex).indexOfValue(value);
+    if (valIndex == -1) {
+      if (attribute(attIndex).isNominal()) {
+	throw new IllegalArgumentException("Value not defined for given nominal attribute!");
+      } else {
+	attribute(attIndex).forceAddValue(value);
+	valIndex = attribute(attIndex).indexOfValue(value);
+      }
+    }
+    setValue(attIndex, (double)valIndex); 
+  }
+
+  /**
+   * Sets a specific value in the instance to the given value
+   * (internal floating-point format). Performs a deep copy of the
+   * vector of attribute values before the value is set, so if you are
+   * planning on calling setValue many times it may be faster to
+   * create a new instance using toDoubleArray.  The given attribute
+   * has to belong to a dataset.
+   *
+   * @param att the attribute 
+   * @param value the new attribute value (If the corresponding
+   * attribute is nominal (or a string) then this is the new value's
+   * index as a double).  
+   */
+  public final void setValue(Attribute att, double value) {
+
+    setValue(att.index(), value);
+  }
+
+  /**
+   * Sets a value of an nominal or string attribute to the given
+   * value. Performs a deep copy of the vector of attribute values
+   * before the value is set, so if you are planning on calling setValue many
+   * times it may be faster to create a new instance using toDoubleArray.
+   * The given attribute has to belong to a dataset.
+   *
+   * @param att the attribute
+   * @param value the new attribute value (If the attribute
+   * is a string attribute and the value can't be found,
+   * the value is added to the attribute).
+   * @exception IllegalArgumentException if the the attribute is not
+   * nominal or a string, or the value couldn't be found for a nominal
+   * attribute 
+   */
+  public final void setValue(Attribute att, String value) {
+
+    if (!att.isNominal() &&
+	!att.isString()) {
+      throw new IllegalArgumentException("Attribute neither nominal nor string!");
+    }
+    int valIndex = att.indexOfValue(value);
+    if (valIndex == -1) {
+      if (att.isNominal()) {
+	throw new IllegalArgumentException("Value not defined for given nominal attribute!");
+      } else {
+	att.forceAddValue(value);
+	valIndex = att.indexOfValue(value);
+      }
+    }
+    setValue(att.index(), (double)valIndex);
+  }
+
+  /**
+   * Sets the weight of an instance.
+   *
+   * @param weight the weight
+   */
+  public final void setWeight(double weight) {
+
+    m_Weight = weight;
+  }
+
+  /** 
+   * Returns the value of a nominal (or string) attribute
+   * for the instance.
+   *
+   * @param attIndex the attribute's index
+   * @return the value as a string
+   * @exception IllegalArgumentException if the attribute is not a nominal
+   * (or string) attribute.
+   * @exception UnassignedDatasetException if the instance doesn't belong
+   * to a dataset.
+   */
+  public final String stringValue(int attIndex) {
+
+    if (m_Dataset == null) {
+      throw new UnassignedDatasetException("Instance doesn't have access to a dataset!");
+    } 
+    if (!m_Dataset.attribute(attIndex).isNominal() &&
+	!m_Dataset.attribute(attIndex).isString()) {
+      throw new IllegalArgumentException("Attribute neither nominal nor string!");
+    }
+    return m_Dataset.attribute(attIndex).
+      value((int) value(attIndex));
+  }
+
+  /** 
+   * Returns the value of a nominal (or string) attribute
+   * for the instance.
+   *
+   * @param att the attribute
+   * @return the value as a string
+   * @exception IllegalArgumentException if the attribute is not a nominal
+   * (or string) attribute.
+   * @exception UnassignedDatasetException if the instance doesn't belong
+   * to a dataset.
+   */
+  public final String stringValue(Attribute att) {
+
+    return stringValue(att.index());
+  }
+
+  /**
+   * Returns the values of each attribute as an array of doubles.
+   *
+   * @return an array containing all the instance attribute values
+   */
+  public double[] toDoubleArray() {
+
+    double[] newValues = new double[m_AttValues.length];
+    System.arraycopy(m_AttValues, 0, newValues, 0, 
+		     m_AttValues.length);
+    return newValues;
+  }
+
+  /**
+   * Returns the description of one instance. If the instance
+   * doesn't have access to a dataset, it returns the internal
+   * floating-point values. Quotes string
+   * values that contain whitespace characters.
+   *
+   * @return the instance's description as a string
+   */
+  public String toString() {
+
+    StringBuffer text = new StringBuffer();
+    
+    for (int i = 0; i < m_AttValues.length; i++) {
+      if (i > 0) text.append(",");
+      text.append(toString(i));
+    }
+
+    return text.toString();
+  }
+
+  /**
+   * Returns the description of one value of the instance as a 
+   * string. If the instance doesn't have access to a dataset, it 
+   * returns the internal floating-point value. Quotes string
+   * values that contain whitespace characters, or if they
+   * are a question mark.
+   *
+   * @param attIndex the attribute's index
+   * @return the value's description as a string
+   */
+  public final String toString(int attIndex) {
+
+   StringBuffer text = new StringBuffer();
+   
+   if (isMissing(attIndex)) {
+     text.append("?");
+   } else {
+     if (m_Dataset == null) {
+       text.append(Utils.doubleToString(m_AttValues[attIndex],6));
+     } else {
+       if (m_Dataset.attribute(attIndex).isNominal() || 
+	   m_Dataset.attribute(attIndex).isString()) {
+         text.append(Utils.quote(stringValue(attIndex)));
+       } else {
+	 text.append(Utils.doubleToString(value(attIndex),6));
+       }
+     }
+   }
+   return text.toString();
+  }
+
+  /**
+   * Returns the description of one value of the instance as a 
+   * string. If the instance doesn't have access to a dataset it 
+   * returns the internal floating-point value. Quotes string
+   * values that contain whitespace characters, or if they
+   * are a question mark.
+   * The given attribute has to belong to a dataset.
+   *
+   * @param att the attribute
+   * @return the value's description as a string
+   */
+  public final String toString(Attribute att) {
+   
+   return toString(att.index());
+  }
+
+  /**
+   * Returns an instance's attribute value in internal format.
+   *
+   * @param attIndex the attribute's index
+   * @return the specified value as a double (If the corresponding
+   * attribute is nominal (or a string) then it returns the value's index as a 
+   * double).
+   */
+  public double value(int attIndex) {
+
+    return m_AttValues[attIndex];
+  }
+
+  /**
+   * Returns an instance's attribute value in internal format.
+   * Does exactly the same thing as value() if applied to an Instance.
+   *
+   * @param indexOfIndex the index of the attribute's index
+   * @return the specified value as a double (If the corresponding
+   * attribute is nominal (or a string) then it returns the value's index as a 
+   * double).
+   */
+  public double valueSparse(int indexOfIndex) {
+
+    return m_AttValues[indexOfIndex];
+  }  
+
+  /**
+   * Returns an instance's attribute value in internal format.
+   * The given attribute has to belong to a dataset.
+   *
+   * @param att the attribute
+   * @return the specified value as a double (If the corresponding
+   * attribute is nominal (or a string) then it returns the value's index as a
+   * double).
+   */
+  public double value(Attribute att) {
+
+    return value(att.index());
+  }
+
+  /**
+   * Returns the instance's weight.
+   *
+   * @return the instance's weight as a double
+   */
+  public final double weight() {
+
+    return m_Weight;
+  }
+
+  /**
+   * Deletes an attribute at the given position (0 to 
+   * numAttributes() - 1).
+   *
+   * @param pos the attribute's position
+   */
+
+  void forceDeleteAttributeAt(int position) {
+
+    double[] newValues = new double[m_AttValues.length - 1];
+
+    System.arraycopy(m_AttValues, 0, newValues, 0, position);
+    if (position < m_AttValues.length - 1) {
+      System.arraycopy(m_AttValues, position + 1, 
+		       newValues, position, 
+		       m_AttValues.length - (position + 1));
+    }
+    m_AttValues = newValues;
+  }
+
+  /**
+   * Inserts an attribute at the given position
+   * (0 to numAttributes()) and sets its value to be missing. 
+   *
+   * @param pos the attribute's position
+   */
+  void forceInsertAttributeAt(int position)  {
+
+    double[] newValues = new double[m_AttValues.length + 1];
+
+    System.arraycopy(m_AttValues, 0, newValues, 0, position);
+    newValues[position] = MISSING_VALUE;
+    System.arraycopy(m_AttValues, position, newValues, 
+		     position + 1, m_AttValues.length - position);
+    m_AttValues = newValues;
+  }
+
+  /**
+   * Private constructor for subclasses. Does nothing.
+   */
+  protected Instance() {
+  }
+
+  /**
+   * Clones the attribute vector of the instance and
+   * overwrites it with the clone.
+   */
+  private void freshAttributeVector() {
+
+    m_AttValues = toDoubleArray();
+  }
+
+  /**
+   * Main method for testing this class.
+   */
+  public static void main(String[] options) {
+
+    try {
+
+      // Create numeric attributes "length" and "weight"
+      Attribute length = new Attribute("length");
+      Attribute weight = new Attribute("weight");
+      
+      // Create vector to hold nominal values "first", "second", "third" 
+      FastVector my_nominal_values = new FastVector(3); 
+      my_nominal_values.addElement("first"); 
+      my_nominal_values.addElement("second"); 
+      my_nominal_values.addElement("third"); 
+      
+      // Create nominal attribute "position" 
+      Attribute position = new Attribute("position", my_nominal_values);
+      
+      // Create vector of the above attributes 
+      FastVector attributes = new FastVector(3);
+      attributes.addElement(length);
+      attributes.addElement(weight);
+      attributes.addElement(position);
+      
+      // Create the empty dataset "race" with above attributes
+      Instances race = new Instances("race", attributes, 0);
+      
+      // Make position the class attribute
+      race.setClassIndex(position.index());
+      
+      // Create empty instance with three attribute values
+      Instance inst = new Instance(3);
+      
+      // Set instance's values for the attributes "length", "weight", and "position"
+      inst.setValue(length, 5.3);
+      inst.setValue(weight, 300);
+      inst.setValue(position, "first");
+      
+      // Set instance's dataset to be the dataset "race"
+      inst.setDataset(race);
+      
+      // Print the instance
+      System.out.println("The instance: " + inst);
+      
+      // Print the first attribute
+      System.out.println("First attribute: " + inst.attribute(0));
+      
+      // Print the class attribute
+      System.out.println("Class attribute: " + inst.classAttribute());
+      
+      // Print the class index
+      System.out.println("Class index: " + inst.classIndex());
+      
+      // Say if class is missing
+      System.out.println("Class is missing: " + inst.classIsMissing());
+      
+      // Print the instance's class value in internal format
+      System.out.println("Class value (internal format): " + inst.classValue());
+      
+      // Print a shallow copy of this instance
+      Instance copy = (Instance) inst.copy();
+      System.out.println("Shallow copy: " + copy);
+      
+      // Set dataset for shallow copy
+      copy.setDataset(inst.dataset());
+      System.out.println("Shallow copy with dataset set: " + copy);
+      
+      // Unset dataset for copy, delete first attribute, and insert it again
+      copy.setDataset(null);
+      copy.deleteAttributeAt(0);
+      copy.insertAttributeAt(0);
+      copy.setDataset(inst.dataset());
+      System.out.println("Copy with first attribute deleted and inserted: " + copy); 
+      
+      // Enumerate attributes (leaving out the class attribute)
+      System.out.println("Enumerating attributes (leaving out class):");
+      Enumeration enum = inst.enumerateAttributes();
+      while (enum.hasMoreElements()) {
+	Attribute att = (Attribute) enum.nextElement();
+	System.out.println(att);
+      }
+      
+      // Headers are equivalent?
+      System.out.println("Header of original and copy equivalent: " +
+			 inst.equalHeaders(copy));
+
+      // Test for missing values
+      System.out.println("Length of copy missing: " + copy.isMissing(length));
+      System.out.println("Weight of copy missing: " + copy.isMissing(weight.index()));
+      System.out.println("Length of copy missing: " + 
+			 Instance.isMissingValue(copy.value(length)));
+      System.out.println("Missing value coded as: " + Instance.missingValue());
+
+      // Prints number of attributes and classes
+      System.out.println("Number of attributes: " + copy.numAttributes());
+      System.out.println("Number of classes: " + copy.numClasses());
+
+      // Replace missing values
+      double[] meansAndModes = {2, 3, 0};
+      copy.replaceMissingValues(meansAndModes);
+      System.out.println("Copy with missing value replaced: " + copy);
+
+      // Setting and getting values and weights
+      copy.setClassMissing();
+      System.out.println("Copy with missing class: " + copy);
+      copy.setClassValue(0);
+      System.out.println("Copy with class value set to first value: " + copy);
+      copy.setClassValue("third");
+      System.out.println("Copy with class value set to \"third\": " + copy);
+      copy.setMissing(1);
+      System.out.println("Copy with second attribute set to be missing: " + copy);
+      copy.setMissing(length);
+      System.out.println("Copy with length set to be missing: " + copy);
+      copy.setValue(0, 0);
+      System.out.println("Copy with first attribute set to 0: " + copy);
+      copy.setValue(weight, 1);
+      System.out.println("Copy with weight attribute set to 1: " + copy);
+      copy.setValue(position, "second");
+      System.out.println("Copy with position set to \"second\": " + copy);
+      copy.setValue(2, "first");
+      System.out.println("Copy with last attribute set to \"first\": " + copy);
+      System.out.println("Current weight of instance copy: " + copy.weight());
+      copy.setWeight(2);
+      System.out.println("Current weight of instance copy (set to 2): " + copy.weight());
+      System.out.println("Last value of copy: " + copy.toString(2));
+      System.out.println("Value of position for copy: " + copy.toString(position));
+      System.out.println("Last value of copy (internal format): " + copy.value(2));
+      System.out.println("Value of position for copy (internal format): " + 
+			 copy.value(position));
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Instances.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Instances.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Instances.java	(revision 20131)
@@ -0,0 +1,2150 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    Instances.java
+ *    Copyright (C) 1999 Eibe Frank
+ *
+ */
+
+package weka.core;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Class for handling an ordered set of weighted instances. <p>
+ *
+ * Typical usage (code from the main() method of this class): <p>
+ *
+ * <code>
+ * ... <br>
+ * 
+ * // Read all the instances in the file <br>
+ * reader = new FileReader(filename); <br>
+ * instances = new Instances(reader); <br><br>
+ *
+ * // Make the last attribute be the class <br>
+ * instances.setClassIndex(instances.numAttributes() - 1); <br><br>
+ * 
+ * // Print header and instances. <br>
+ * System.out.println("\nDataset:\n"); <br> 
+ * System.out.println(instances); <br><br>
+ *
+ * ... <br>
+ * </code><p>
+ *
+ * All methods that change a set of instances are safe, ie. a change
+ * of a set of instances does not affect any other sets of
+ * instances. All methods that change a datasets's attribute
+ * information clone the dataset before it is changed.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @author Len Trigg (trigg@cs.waikato.ac.nz)
+ * @version $Revision$ 
+ */
+public class Instances implements Serializable {
+ 
+  /** The filename extension that should be used for arff files */
+  public static String FILE_EXTENSION = ".arff";
+
+  /** The dataset's name. */
+  protected String m_RelationName;         
+
+  /** The attribute information. */
+  protected FastVector m_Attributes;
+
+  /** The instances. */
+  protected FastVector m_Instances;
+
+  /** The class attribute's index */
+  protected int m_ClassIndex;
+
+  /** Buffer of values for sparse instance */
+  protected double[] m_ValueBuffer;
+
+  /** Buffer of indices for sparse instance */
+  protected int[] m_IndicesBuffer;
+
+  /**
+   * Reads an ARFF file from a reader, and assigns a weight of
+   * one to each instance. Lets the index of the class 
+   * attribute be undefined (negative).
+   *
+   * @param reader the reader
+   * @exception IOException if the ARFF file is not read 
+   * successfully
+   */
+  public Instances(Reader reader) throws IOException {
+
+    StreamTokenizer tokenizer;
+
+    tokenizer = new StreamTokenizer(reader);
+    initTokenizer(tokenizer);
+    readHeader(tokenizer);
+    m_ClassIndex = -1;
+    m_Instances = new FastVector(1000);
+    while (getInstance(tokenizer, true)) {};
+    compactify();
+  }
+ 
+  /**
+   * Reads the header of an ARFF file from a reader and 
+   * reserves space for the given number of instances. Lets
+   * the class index be undefined (negative).
+   *
+   * @param reader the reader
+   * @param capacity the capacity
+   * @exception IllegalArgumentException if the header is not read successfully
+   * or the capacity is negative.
+   * @exception IOException if there is a problem with the reader.
+   */
+   public Instances(Reader reader, int capacity) throws IOException {
+
+    StreamTokenizer tokenizer;
+
+    if (capacity < 0) {
+      throw new IllegalArgumentException("Capacity has to be positive!");
+    }
+    tokenizer = new StreamTokenizer(reader); 
+    initTokenizer(tokenizer);
+    readHeader(tokenizer);
+    m_ClassIndex = -1;
+    m_Instances = new FastVector(capacity);
+  }
+
+  /**
+   * Constructor copying all instances and references to
+   * the header information from the given set of instances.
+   *
+   * @param instances the set to be copied
+   */
+  public Instances(Instances dataset) {
+
+    this(dataset, dataset.numInstances());
+
+    dataset.copyInstances(0, this, dataset.numInstances());
+  }
+
+  /**
+   * Constructor creating an empty set of instances. Copies references
+   * to the header information from the given set of instances. Sets
+   * the capacity of the set of instances to 0 if its negative.
+   *
+   * @param instances the instances from which the header 
+   * information is to be taken
+   * @param capacity the capacity of the new dataset 
+   */
+  public Instances(Instances dataset, int capacity) {
+    
+    if (capacity < 0) {
+      capacity = 0;
+    }
+    
+    // Strings only have to be "shallow" copied because
+    // they can't be modified.
+    m_ClassIndex = dataset.m_ClassIndex;
+    m_RelationName = dataset.m_RelationName;
+    m_Attributes = dataset.m_Attributes;
+    m_Instances = new FastVector(capacity);
+  }
+
+  /**
+   * Creates a new set of instances by copying a 
+   * subset of another set.
+   *
+   * @param source the set of instances from which a subset 
+   * is to be created
+   * @param first the index of the first instance to be copied
+   * @param toCopy the number of instances to be copied
+   * @exception IllegalArgumentException if first and toCopy are out of range
+   */
+  public Instances(Instances source, int first, int toCopy) {
+    
+    this(source, toCopy);
+
+    if ((first < 0) || ((first + toCopy) > source.numInstances())) {
+      throw new IllegalArgumentException("Parameters first and/or toCopy out "+
+                                         "of range");
+    }
+    source.copyInstances(first, this, toCopy);
+  }
+
+  /**
+   * Creates an empty set of instances. Uses the given
+   * attribute information. Sets the capacity of the set of 
+   * instances to 0 if its negative. Given attribute information
+   * must not be changed after this constructor has been used.
+   *
+   * @param name the name of the relation
+   * @param attInfo the attribute information
+   * @param capacity the capacity of the set
+   */
+  public Instances(String name, FastVector attInfo, int capacity) {
+
+    m_RelationName = name;
+    m_ClassIndex = -1;
+    m_Attributes = attInfo;
+    for (int i = 0; i < numAttributes(); i++) {
+      attribute(i).setIndex(i);
+    }
+    m_Instances = new FastVector(capacity);
+  }
+ 
+  /**
+   * Create a copy of the structure, but "cleanse" string types (i.e.
+   * doesn't contain references to the strings seen in the past).
+   *
+   * @return a copy of the instance structure.
+   */
+  public Instances stringFreeStructure() {
+
+    FastVector atts = (FastVector)m_Attributes.copy();
+    for (int i = 0 ; i < atts.size(); i++) {
+      Attribute att = (Attribute)atts.elementAt(i);
+      if (att.type() == Attribute.STRING) {
+        atts.setElementAt(new Attribute(att.name(), null), i);
+      }
+    }
+    Instances result = new Instances(relationName(), atts, 0);
+    result.m_ClassIndex = m_ClassIndex;
+    return result;
+  }
+
+  /**
+   * Adds one instance to the end of the set. 
+   * Shallow copies instance before it is added. Increases the
+   * size of the dataset if it is not large enough. Does not
+   * check if the instance is compatible with the dataset.
+   *
+   * @param instance the instance to be added
+   */
+  public final void add(Instance instance) {
+
+    Instance newInstance = (Instance)instance.copy();
+
+    newInstance.setDataset(this);
+    m_Instances.addElement(newInstance);
+  }
+
+  /**
+   * Returns an attribute.
+   *
+   * @param index the attribute's index
+   * @return the attribute at the given position
+   */ 
+  public final Attribute attribute(int index) {
+    
+    return (Attribute) m_Attributes.elementAt(index);
+  }
+
+  /**
+   * Returns an attribute given its name. If there is more than
+   * one attribute with the same name, it returns the first one.
+   * Returns null if the attribute can't be found.
+   *
+   * @param name the attribute's name
+   * @return the attribute with the given name, null if the
+   * attribute can't be found
+   */ 
+  public final Attribute attribute(String name) {
+    
+    for (int i = 0; i < numAttributes(); i++) {
+      if (attribute(i).name().equals(name)) {
+	return attribute(i);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Checks for string attributes in the dataset
+   *
+   * @return true if string attributes are present, false otherwise
+   */
+  public boolean checkForStringAttributes() {
+
+    int i = 0;
+   
+    while (i < m_Attributes.size()) {
+      if (attribute(i++).isString()) {
+	return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Checks if the given instance is compatible
+   * with this dataset. Only looks at the size of
+   * the instance and the ranges of the values for 
+   * nominal and string attributes.
+   *
+   * @return true if the instance is compatible with the dataset 
+   */
+  public final boolean checkInstance(Instance instance) {
+
+    if (instance.numAttributes() != numAttributes()) {
+      return false;
+    }
+    for (int i = 0; i < numAttributes(); i++) {
+      if (instance.isMissing(i)) {
+	continue;
+      } else if (attribute(i).isNominal() ||
+		 attribute(i).isString()) {
+	if (!(Utils.eq(instance.value(i),
+		       (double)(int)instance.value(i)))) {
+	  return false;
+	} else if (Utils.sm(instance.value(i), 0) ||
+		   Utils.gr(instance.value(i),
+			    attribute(i).numValues())) {
+	  return false;
+	}
+      }
+    }
+    return true;
+  }
+	
+  /**
+   * Returns the class attribute.
+   *
+   * @return the class attribute
+   * @exception UnassignedClassException if the class is not set
+   */
+  public final Attribute classAttribute() {
+
+    if (m_ClassIndex < 0) {
+      throw new UnassignedClassException("Class index is negative (not set)!");
+    }
+    return attribute(m_ClassIndex);
+  }
+
+  /**
+   * Returns the class attribute's index. Returns negative number
+   * if it's undefined.
+   *
+   * @return the class index as an integer
+   */
+  public final int classIndex() {
+    
+    return m_ClassIndex;
+  }
+ 
+  /**
+   * Compactifies the set of instances. Decreases the capacity of
+   * the set so that it matches the number of instances in the set.
+   */
+  public final void compactify() {
+
+    m_Instances.trimToSize();
+  }
+
+  /**
+   * Removes all instances from the set.
+   */
+  public final void delete() {
+    
+    m_Instances = new FastVector();
+  }
+
+  /**
+   * Removes an instance at the given position from the set.
+   *
+   * @param index the instance's position
+   */
+  public final void delete(int index) {
+    
+    m_Instances.removeElementAt(index);
+  }
+
+  /**
+   * Deletes an attribute at the given position 
+   * (0 to numAttributes() - 1). A deep copy of the attribute
+   * information is performed before the attribute is deleted.
+   *
+   * @param pos the attribute's position
+   * @exception IllegalArgumentException if the given index is out of range or the
+   * class attribute is being deleted
+   */
+  public void deleteAttributeAt(int position) {
+	 
+    if ((position < 0) || (position >= m_Attributes.size())) {
+      throw new IllegalArgumentException("Index out of range");
+    }
+    if (position == m_ClassIndex) {
+      throw new IllegalArgumentException("Can't delete class attribute");
+    }
+    freshAttributeInfo();
+    if (m_ClassIndex > position) {
+      m_ClassIndex--;
+    }
+    m_Attributes.removeElementAt(position);
+    for (int i = position; i < m_Attributes.size(); i++) {
+      Attribute current = (Attribute)m_Attributes.elementAt(i);
+      current.setIndex(current.index() - 1);
+    }
+    for (int i = 0; i < numInstances(); i++) {
+      instance(i).forceDeleteAttributeAt(position); 
+    }
+  }
+
+  /**
+   * Deletes all string attributes in the dataset. A deep copy of the attribute
+   * information is performed before an attribute is deleted.
+   *
+   * @exception IllegalArgumentException if string attribute couldn't be 
+   * successfully deleted (probably because it is the class attribute).
+   */
+  public void deleteStringAttributes() {
+
+    int i = 0;
+    while (i < m_Attributes.size()) {
+      if (attribute(i).isString()) {
+	deleteAttributeAt(i);
+      } else {
+	i++;
+      }
+    }
+  }
+
+  /**
+   * Removes all instances with missing values for a particular
+   * attribute from the dataset.
+   *
+   * @param attIndex the attribute's index
+   */
+  public final void deleteWithMissing(int attIndex) {
+
+    FastVector newInstances = new FastVector(numInstances());
+
+    for (int i = 0; i < numInstances(); i++) {
+      if (!instance(i).isMissing(attIndex)) {
+	newInstances.addElement(instance(i));
+      }
+    }
+    m_Instances = newInstances;
+  }
+
+  /**
+   * Removes all instances with missing values for a particular
+   * attribute from the dataset.
+   *
+   * @param att the attribute
+   */
+  public final void deleteWithMissing(Attribute att) {
+
+    deleteWithMissing(att.index());
+  }
+
+  /**
+   * Removes all instances with a missing class value
+   * from the dataset.
+   *
+   * @exception UnassignedClassException if class is not set
+   */
+  public final void deleteWithMissingClass() {
+
+    if (m_ClassIndex < 0) {
+      throw new UnassignedClassException("Class index is negative (not set)!");
+    }
+    deleteWithMissing(m_ClassIndex);
+  }
+
+  /**
+   * Returns an enumeration of all the attributes.
+   *
+   * @return enumeration of all the attributes.
+   */
+  public Enumeration enumerateAttributes() {
+
+    return m_Attributes.elements(m_ClassIndex);
+  }
+
+  /**
+   * Returns an enumeration of all instances in the dataset.
+   *
+   * @return enumeration of all instances in the dataset
+   */
+  public final Enumeration enumerateInstances() {
+
+    return m_Instances.elements();
+  }
+
+  /**
+   * Checks if two headers are equivalent.
+   *
+   * @param dataset another dataset
+   * @return true if the header of the given dataset is equivalent 
+   * to this header
+   */
+  public final boolean equalHeaders(Instances dataset){
+
+    // Check class and all attributes
+    if (m_ClassIndex != dataset.m_ClassIndex) {
+      return false;
+    }
+    if (m_Attributes.size() != dataset.m_Attributes.size()) {
+      return false;
+    }
+    for (int i = 0; i < m_Attributes.size(); i++) {
+      if (!(attribute(i).equals(dataset.attribute(i)))) {
+	return false;
+      }
+    }
+    return true;
+  }
+ 
+  /**
+   * Returns the first instance in the set.
+   *
+   * @return the first instance in the set
+   */
+  public final Instance firstInstance() {
+    
+    return (Instance)m_Instances.firstElement();
+  }
+ 
+  /**
+   * Inserts an attribute at the given position (0 to 
+   * numAttributes()) and sets all values to be missing.
+   * Shallow copies the attribute before it is inserted, and performs
+   * a deep copy of the existing attribute information.
+   *
+   * @param att the attribute to be inserted
+   * @param pos the attribute's position
+   * @exception IllegalArgumentException if the given index is out of range
+   */
+  public void insertAttributeAt(Attribute att, int position) {
+	 
+    if ((position < 0) ||
+	(position > m_Attributes.size())) {
+      throw new IllegalArgumentException("Index out of range");
+    }
+    att = (Attribute)att.copy();
+    freshAttributeInfo();
+    att.setIndex(position);
+    m_Attributes.insertElementAt(att, position);
+    for (int i = position + 1; i < m_Attributes.size(); i++) {
+      Attribute current = (Attribute)m_Attributes.elementAt(i);
+      current.setIndex(current.index() + 1);
+    }
+    for (int i = 0; i < numInstances(); i++) {
+      instance(i).forceInsertAttributeAt(position);
+    }
+    if (m_ClassIndex >= position) {
+      m_ClassIndex++;
+    }
+  }
+
+  /**
+   * Returns the instance at the given position.
+   *
+   * @param index the instance's index
+   * @return the instance at the given position
+   */
+  public final Instance instance(int index) {
+
+    return (Instance)m_Instances.elementAt(index);
+  }
+
+  /**
+   * Returns the last instance in the set.
+   *
+   * @return the last instance in the set
+   */
+  public final Instance lastInstance() {
+    
+    return (Instance)m_Instances.lastElement();
+  }
+
+  /**
+   * Returns the mean (mode) for a numeric (nominal) attribute as
+   * a floating-point value. Returns 0 if the attribute is neither nominal nor 
+   * numeric. If all values are missing it returns zero.
+   *
+   * @param attIndex the attribute's index
+   * @return the mean or the mode
+   */
+  public final double meanOrMode(int attIndex) {
+
+    double result, found;
+    int [] counts;
+
+    if (attribute(attIndex).isNumeric()) {
+      result = found = 0;
+      for (int j = 0; j < numInstances(); j++) {
+	if (!instance(j).isMissing(attIndex)) {
+	  found += instance(j).weight();
+	  result += instance(j).weight()*instance(j).value(attIndex);
+	}
+      }
+      if (Utils.eq(found, 0)) {
+	return 0;
+      } else {
+	return result / found;
+      }
+    } else if (attribute(attIndex).isNominal()) {
+      counts = new int[attribute(attIndex).numValues()];
+      for (int j = 0; j < numInstances(); j++) {
+	if (!instance(j).isMissing(attIndex)) {
+	  counts[(int) instance(j).value(attIndex)] += instance(j).weight();
+	}
+      }
+      return (double)Utils.maxIndex(counts);
+    } else {
+      return 0;
+    }
+  }
+
+  /**
+   * Returns the mean (mode) for a numeric (nominal) attribute as a
+   * floating-point value.  Returns 0 if the attribute is neither
+   * nominal nor numeric.  If all values are missing it returns zero.
+   *
+   * @param att the attribute
+   * @return the mean or the mode 
+   */
+  public final double meanOrMode(Attribute att) {
+
+    return meanOrMode(att.index());
+  }
+
+  /**
+   * Returns the number of attributes.
+   *
+   * @return the number of attributes as an integer
+   */
+  public final int numAttributes() {
+
+    return m_Attributes.size();
+  }
+
+  /**
+   * Returns the number of class labels.
+   *
+   * @return the number of class labels as an integer if the class 
+   * attribute is nominal, 1 otherwise.
+   * @exception UnassignedClassException if the class is not set
+   */
+  public final int numClasses() {
+    
+    if (m_ClassIndex < 0) {
+      throw new UnassignedClassException("Class index is negative (not set)!");
+    }
+    if (!classAttribute().isNominal()) {
+      return 1;
+    } else {
+      return classAttribute().numValues();
+    }
+  }
+
+  /**
+   * Returns the number of distinct values of a given attribute.
+   * Returns the number of instances if the attribute is a
+   * string attribute. The value 'missing' is not counted.
+   *
+   * @param attIndex the attribute
+   * @return the number of distinct values of a given attribute
+   */
+  public final int numDistinctValues(int attIndex) {
+
+    if (attribute(attIndex).isNumeric()) {
+      double [] attVals = attributeToDoubleArray(attIndex);
+      int [] sorted = Utils.sort(attVals);
+      double prev = 0;
+      int counter = 0;
+      for (int i = 0; i < sorted.length; i++) {
+	Instance current = instance(sorted[i]);
+	if (current.isMissing(attIndex)) {
+	  break;
+	}
+	if ((i == 0) || 
+	    Utils.gr(current.value(attIndex), prev)) {
+	  prev = current.value(attIndex);
+	  counter++;
+	}
+      }
+      return counter;
+    } else {
+      return attribute(attIndex).numValues();
+    }
+  }
+
+  /**
+   * Returns the number of distinct values of a given attribute.
+   * Returns the number of instances if the attribute is a
+   * string attribute. The value 'missing' is not counted.
+   *
+   * @param att the attribute
+   * @return the number of distinct values of a given attribute
+   */
+  public final int numDistinctValues(Attribute att) {
+
+    return numDistinctValues(att.index());
+  }
+  
+  /**
+   * Returns the number of instances in the dataset.
+   *
+   * @return the number of instances in the dataset as an integer
+   */
+  public final int numInstances() {
+
+    return m_Instances.size();
+  }
+
+  /**
+   * Shuffles the instances in the set so that they are ordered 
+   * randomly.
+   *
+   * @param random a random number generator
+   */
+  public final void randomize(Random random) {
+
+    for (int j = numInstances() - 1; j > 0; j--)
+      swap(j,(int)(random.nextDouble()*(double)j));
+  }
+
+  /**
+   * Reads a single instance from the reader and appends it
+   * to the dataset.  Automatically expands the dataset if it
+   * is not large enough to hold the instance. This method does
+   * not check for carriage return at the end of the line.
+   *
+   * @param reader the reader 
+   * @return false if end of file has been reached
+   * @exception IOException if the information is not read 
+   * successfully
+   */ 
+  public final boolean readInstance(Reader reader) 
+       throws IOException {
+
+    StreamTokenizer tokenizer = new StreamTokenizer(reader);
+    
+    initTokenizer(tokenizer);
+    return getInstance(tokenizer, false);
+  }    
+
+  /**
+   * Returns the relation's name.
+   *
+   * @return the relation's name as a string
+   */
+  public final String relationName() {
+
+    return m_RelationName;
+  }
+
+  /**
+   * Renames an attribute. This change only affects this
+   * dataset.
+   *
+   * @param att the attribute's index
+   * @param name the new name
+   */
+  public final void renameAttribute(int att, String name) {
+
+    Attribute newAtt = attribute(att).copy(name);
+    FastVector newVec = new FastVector(numAttributes());
+
+    for (int i = 0; i < numAttributes(); i++) {
+      if (i == att) {
+	newVec.addElement(newAtt);
+      } else {
+	newVec.addElement(attribute(i));
+      }
+    }
+    m_Attributes = newVec;
+  }
+
+  /**
+   * Renames an attribute. This change only affects this
+   * dataset.
+   *
+   * @param att the attribute
+   * @param name the new name
+   */
+  public final void renameAttribute(Attribute att, String name) {
+
+    renameAttribute(att.index(), name);
+  }
+
+  /**
+   * Renames the value of a nominal (or string) attribute value. This
+   * change only affects this dataset.
+   *
+   * @param att the attribute's index
+   * @param val the value's index
+   * @param name the new name 
+   */
+  public final void renameAttributeValue(int att, int val, String name) {
+
+    Attribute newAtt = (Attribute)attribute(att).copy();
+    FastVector newVec = new FastVector(numAttributes());
+
+    newAtt.setValue(val, name);
+    for (int i = 0; i < numAttributes(); i++) {
+      if (i == att) {
+	newVec.addElement(newAtt);
+      } else {
+	newVec.addElement(attribute(i));
+      }
+    }
+    m_Attributes = newVec;
+  }
+
+  /**
+   * Renames the value of a nominal (or string) attribute value. This
+   * change only affects this dataset.
+   *
+   * @param att the attribute
+   * @param val the value
+   * @param name the new name
+   */
+  public final void renameAttributeValue(Attribute att, String val, 
+                                         String name) {
+
+    renameAttributeValue(att.index(), att.indexOfValue(val), name);
+  }
+
+  /**
+   * Creates a new dataset of the same size using random sampling
+   * with replacement.
+   *
+   * @param random a random number generator
+   * @return the new dataset
+   */
+  public final Instances resample(Random random) {
+
+    Instances newData = new Instances(this, numInstances());
+    while (newData.numInstances() < numInstances()) {
+      int i = (int) (random.nextDouble() * (double) numInstances());
+      newData.add(instance(i));
+    }
+    return newData;
+  }
+
+  /**
+   * Creates a new dataset of the same size using random sampling
+   * with replacement according to the current instance weights. The
+   * weights of the instances in the new dataset are set to one.
+   *
+   * @param random a random number generator
+   * @return the new dataset
+   */
+  public final Instances resampleWithWeights(Random random) {
+
+    double [] weights = new double[numInstances()];
+    boolean foundOne = false;
+    for (int i = 0; i < weights.length; i++) {
+      weights[i] = instance(i).weight();
+      if (!Utils.eq(weights[i], weights[0])) {
+        foundOne = true;
+      }
+    }
+    if (foundOne) {
+      return resampleWithWeights(random, weights);
+    } else {
+      return new Instances(this);
+    }
+  }
+
+
+  /**
+   * Creates a new dataset of the same size using random sampling
+   * with replacement according to the given weight vector. The
+   * weights of the instances in the new dataset are set to one.
+   * The length of the weight vector has to be the same as the
+   * number of instances in the dataset, and all weights have to
+   * be positive.
+   *
+   * @param random a random number generator
+   * @param weights the weight vector
+   * @return the new dataset
+   * @exception IllegalArgumentException if the weights array is of the wrong
+   * length or contains negative weights.
+   */
+  public final Instances resampleWithWeights(Random random, 
+					     double[] weights) {
+
+    if (weights.length != numInstances()) {
+      throw new IllegalArgumentException("weights.length != numInstances.");
+    }
+    Instances newData = new Instances(this, numInstances());
+    double[] probabilities = new double[numInstances()];
+    double sumProbs = 0, sumOfWeights = Utils.sum(weights);
+    for (int i = 0; i < numInstances(); i++) {
+      sumProbs += random.nextDouble();
+      probabilities[i] = sumProbs;
+    }
+    Utils.normalize(probabilities, sumProbs / sumOfWeights);
+
+    // Make sure that rounding errors don't mess things up
+    probabilities[numInstances() - 1] = sumOfWeights;
+    int k = 0; int l = 0;
+    sumProbs = 0;
+    while ((k < numInstances() && (l < numInstances()))) {
+      if (weights[l] < 0) {
+	throw new IllegalArgumentException("Weights have to be positive.");
+      }
+      sumProbs += weights[l];
+      while ((k < numInstances()) &&
+	     (probabilities[k] <= sumProbs)) { 
+	newData.add(instance(l));
+	newData.instance(k).setWeight(1);
+	k++;
+      }
+      l++;
+    }
+    return newData;
+  }
+
+  /** 
+   * Sets the class attribute.
+   *
+   * @param att attribute to be the class
+   */
+  public final void setClass(Attribute att) {
+
+    m_ClassIndex = att.index();
+  }
+
+  /** 
+   * Sets the class index of the set.
+   * If the class index is negative there is assumed to be no class.
+   * (ie. it is undefined)
+   *
+   * @param classIndex the new class index
+   * @exception IllegalArgumentException if the class index is too big or < 0
+   */
+  public final void setClassIndex(int classIndex) {
+
+    if (classIndex >= numAttributes()) {
+      throw new IllegalArgumentException("Invalid class index: " + classIndex);
+    }
+    m_ClassIndex = classIndex;
+  }
+
+  /**
+   * Sets the relation's name.
+   *
+   * @param newName the new relation name.
+   */
+  public final void setRelationName(String newName) {
+    
+    m_RelationName = newName;
+  }
+
+  /**
+   * Sorts the instances based on an attribute. For numeric attributes, 
+   * instances are sorted in ascending order. For nominal attributes, 
+   * instances are sorted based on the attribute label ordering 
+   * specified in the header. Instances with missing values for the 
+   * attribute are placed at the end of the dataset.
+   *
+   * @param attIndex the attribute's index
+   */
+  public final void sort(int attIndex) {
+
+    int i,j;
+
+    // move all instances with missing values to end
+    j = numInstances() - 1;
+    i = 0;
+    while (i <= j) {
+      if (instance(j).isMissing(attIndex)) {
+	j--;
+      } else {
+	if (instance(i).isMissing(attIndex)) {
+	  swap(i,j);
+	  j--;
+	}
+	i++;
+      }
+    }
+    quickSort(attIndex, 0, j);
+  }
+
+  /**
+   * Sorts the instances based on an attribute. For numeric attributes, 
+   * instances are sorted into ascending order. For nominal attributes, 
+   * instances are sorted based on the attribute label ordering 
+   * specified in the header. Instances with missing values for the 
+   * attribute are placed at the end of the dataset.
+   *
+   * @param att the attribute
+   */
+  public final void sort(Attribute att) {
+
+    sort(att.index());
+  }
+
+  /**
+   * Stratifies a set of instances according to its class values 
+   * if the class attribute is nominal (so that afterwards a 
+   * stratified cross-validation can be performed).
+   *
+   * @param numFolds the number of folds in the cross-validation
+   * @exception UnassignedClassException if the class is not set
+   */
+  public final void stratify(int numFolds) {
+    
+    if (numFolds <= 0) {
+      throw new IllegalArgumentException("Number of folds must be greater than 1");
+    }
+    if (m_ClassIndex < 0) {
+      throw new UnassignedClassException("Class index is negative (not set)!");
+    }
+    if (classAttribute().isNominal()) {
+
+      // sort by class
+      int index = 1;
+      while (index < numInstances()) {
+	Instance instance1 = instance(index - 1);
+	for (int j = index; j < numInstances(); j++) {
+	  Instance instance2 = instance(j);
+	  if ((instance1.classValue() == instance2.classValue()) ||
+	      (instance1.classIsMissing() && 
+	       instance2.classIsMissing())) {
+	    swap(index,j);
+	    index++;
+	  }
+	}
+	index++;
+      }
+      stratStep(numFolds);
+    }
+  }
+ 
+  /**
+   * Computes the sum of all the instances' weights.
+   *
+   * @return the sum of all the instances' weights as a double
+   */
+  public final double sumOfWeights() {
+    
+    double sum = 0;
+
+    for (int i = 0; i < numInstances(); i++) {
+      sum += instance(i).weight();
+    }
+    return sum;
+  }
+
+  /**
+   * Creates the test set for one fold of a cross-validation on 
+   * the dataset.
+   *
+   * @param numFolds the number of folds in the cross-validation. Must
+   * be greater than 1.
+   * @param numFold 0 for the first fold, 1 for the second, ...
+   * @return the test set as a set of weighted instances
+   * @exception IllegalArgumentException if the number of folds is less than 2
+   * or greater than the number of instances.
+   */
+  public Instances testCV(int numFolds, int numFold) {
+
+    int numInstForFold, first, offset;
+    Instances test;
+    
+    if (numFolds < 2) {
+      throw new IllegalArgumentException("Number of folds must be at least 2!");
+    }
+    if (numFolds > numInstances()) {
+      throw new IllegalArgumentException("Can't have more folds than instances!");
+    }
+    numInstForFold = numInstances() / numFolds;
+    if (numFold < numInstances() % numFolds){
+      numInstForFold++;
+      offset = numFold;
+    }else
+      offset = numInstances() % numFolds;
+    test = new Instances(this, numInstForFold);
+    first = numFold * (numInstances() / numFolds) + offset;
+    copyInstances(first, test, numInstForFold);
+    return test;
+  }
+ 
+  /**
+   * Returns the dataset as a string in ARFF format. Strings
+   * are quoted if they contain whitespace characters, or if they
+   * are a question mark.
+   *
+   * @return the dataset in ARFF format as a string
+   */
+  public final String toString() {
+    
+    StringBuffer text = new StringBuffer();
+    
+    text.append("@relation " + Utils.quote(m_RelationName) + "\n\n");
+    for (int i = 0; i < numAttributes(); i++) {
+      text.append(attribute(i) + "\n");
+    }
+    text.append("\n@data\n");
+    for (int i = 0; i < numInstances(); i++) {
+      text.append(instance(i));
+      if (i < numInstances() - 1) {
+	text.append('\n');
+      }
+    }
+    return text.toString();
+  }
+
+  /**
+   * Creates the training set for one fold of a cross-validation 
+   * on the dataset.
+   *
+   * @param numFolds the number of folds in the cross-validation. Must
+   * be greater than 1.
+   * @param numFold 0 for the first fold, 1 for the second, ...
+   * @return the training set as a set of weighted 
+   * instances
+   * @exception IllegalArgumentException if the number of folds is less than 2
+   * or greater than the number of instances.
+   */
+  public Instances trainCV(int numFolds, int numFold) {
+
+    int numInstForFold, first, offset;
+    Instances train;
+ 
+    if (numFolds < 2) {
+      throw new IllegalArgumentException("Number of folds must be at least 2!");
+    }
+    if (numFolds > numInstances()) {
+      throw new IllegalArgumentException("Can't have more folds than instances!");
+    }
+    numInstForFold = numInstances() / numFolds;
+    if (numFold < numInstances() % numFolds) {
+      numInstForFold++;
+      offset = numFold;
+    }else
+      offset = numInstances() % numFolds;
+    train = new Instances(this, numInstances() - numInstForFold);
+    first = numFold * (numInstances() / numFolds) + offset;
+    copyInstances(0, train, first);
+    copyInstances(first + numInstForFold, train,
+		  numInstances() - first - numInstForFold);
+
+    return train;
+  }
+
+  /**
+   * Computes the variance for a numeric attribute.
+   *
+   * @param attIndex the numeric attribute
+   * @return the variance if the attribute is numeric
+   * @exception IllegalArgumentException if the attribute is not numeric
+   */
+  public final double variance(int attIndex) {
+  
+    double sum = 0, sumSquared = 0, sumOfWeights = 0;
+
+    if (!attribute(attIndex).isNumeric()) {
+      throw new IllegalArgumentException("Can't compute variance because attribute is " +
+			  "not numeric!");
+    }
+    for (int i = 0; i < numInstances(); i++) {
+      if (!instance(i).isMissing(attIndex)) {
+	sum += instance(i).weight() * 
+	  instance(i).value(attIndex);
+	sumSquared += instance(i).weight() * 
+	  instance(i).value(attIndex) *
+	  instance(i).value(attIndex);
+	sumOfWeights += instance(i).weight();
+      }
+    }
+    if (Utils.smOrEq(sumOfWeights, 1)) {
+      return 0;
+    }
+    return (sumSquared - (sum * sum / sumOfWeights)) / 
+      (sumOfWeights - 1);
+  }
+
+  /**
+   * Computes the variance for a numeric attribute.
+   *
+   * @param att the numeric attribute
+   * @return the variance if the attribute is numeric
+   * @exception IllegalArgumentException if the attribute is not numeric
+   */
+  public final double variance(Attribute att) {
+    
+    return variance(att.index());
+  }
+  
+  /**
+   * Calculates summary statistics on the values that appear in this
+   * set of instances for a specified attribute.
+   *
+   * @param index the index of the attribute to summarize.
+   * @return an AttributeStats object with it's fields calculated.
+   */
+  public AttributeStats attributeStats(int index) {
+
+    AttributeStats result = new AttributeStats();
+    if (attribute(index).isNominal()) {
+      result.nominalCounts = new int [attribute(index).numValues()];
+    }
+    if (attribute(index).isNumeric()) {
+      result.numericStats = new weka.experiment.Stats();
+    }
+    result.totalCount = numInstances();
+
+    double [] attVals = attributeToDoubleArray(index);
+    int [] sorted = Utils.sort(attVals);
+    int currentCount = 0;
+    double prev = Instance.missingValue();
+    for (int j = 0; j < numInstances(); j++) {
+      Instance current = instance(sorted[j]);
+      if (current.isMissing(index)) {
+	result.missingCount = numInstances() - j;
+	break;
+      }
+      if (Utils.eq(current.value(index), prev)) {
+	currentCount++;
+      } else {
+	result.addDistinct(prev, currentCount);
+	currentCount = 1;
+	prev = current.value(index);
+      }
+    }
+    result.addDistinct(prev, currentCount);
+    result.distinctCount--; // So we don't count "missing" as a value 
+    return result;
+  }
+  
+  /**
+   * Gets the value of all instances in this dataset for a particular
+   * attribute. Useful in conjunction with Utils.sort to allow iterating
+   * through the dataset in sorted order for some attribute.
+   *
+   * @param index the index of the attribute.
+   * @return an array containing the value of the desired attribute for
+   * each instance in the dataset. 
+   */
+  public double [] attributeToDoubleArray(int index) {
+
+    double [] result = new double[numInstances()];
+    for (int i = 0; i < result.length; i++) {
+      result[i] = instance(i).value(index);
+    }
+    return result;
+  }
+
+  /**
+   * Generates a string summarizing the set of instances. Gives a breakdown
+   * for each attribute indicating the number of missing/discrete/unique
+   * values and other information.
+   *
+   * @return a string summarizing the dataset
+   */
+  public String toSummaryString() {
+
+    StringBuffer result = new StringBuffer();
+    result.append("Relation Name:  ").append(relationName()).append('\n');
+    result.append("Num Instances:  ").append(numInstances()).append('\n');
+    result.append("Num Attributes: ").append(numAttributes()).append('\n');
+    result.append('\n');
+
+    result.append(Utils.padLeft("", 5)).append(Utils.padRight("Name", 25));
+    result.append(Utils.padLeft("Type", 5)).append(Utils.padLeft("Nom", 5));
+    result.append(Utils.padLeft("Int", 5)).append(Utils.padLeft("Real", 5));
+    result.append(Utils.padLeft("Missing", 12));
+    result.append(Utils.padLeft("Unique", 12));
+    result.append(Utils.padLeft("Dist", 6)).append('\n');
+    for (int i = 0; i < numAttributes(); i++) {
+      Attribute a = attribute(i);
+      AttributeStats as = attributeStats(i);
+      result.append(Utils.padLeft("" + (i + 1), 4)).append(' ');
+      result.append(Utils.padRight(a.name(), 25)).append(' ');
+      long percent;
+      switch (a.type()) {
+      case Attribute.NOMINAL:
+	result.append(Utils.padLeft("Nom", 4)).append(' ');
+	percent = Math.round(100.0 * as.intCount / as.totalCount);
+	result.append(Utils.padLeft("" + percent, 3)).append("% ");
+	result.append(Utils.padLeft("" + 0, 3)).append("% ");
+	percent = Math.round(100.0 * as.realCount / as.totalCount);
+	result.append(Utils.padLeft("" + percent, 3)).append("% ");
+	break;
+      case Attribute.NUMERIC:
+	result.append(Utils.padLeft("Num", 4)).append(' ');
+	result.append(Utils.padLeft("" + 0, 3)).append("% ");
+	percent = Math.round(100.0 * as.intCount / as.totalCount);
+	result.append(Utils.padLeft("" + percent, 3)).append("% ");
+	percent = Math.round(100.0 * as.realCount / as.totalCount);
+	result.append(Utils.padLeft("" + percent, 3)).append("% ");
+	break;
+      case Attribute.STRING:
+	result.append(Utils.padLeft("Str", 4)).append(' ');
+	percent = Math.round(100.0 * as.intCount / as.totalCount);
+	result.append(Utils.padLeft("" + percent, 3)).append("% ");
+	result.append(Utils.padLeft("" + 0, 3)).append("% ");
+	percent = Math.round(100.0 * as.realCount / as.totalCount);
+	result.append(Utils.padLeft("" + percent, 3)).append("% ");
+	break;
+      default:
+	result.append(Utils.padLeft("???", 4)).append(' ');
+	result.append(Utils.padLeft("" + 0, 3)).append("% ");
+	percent = Math.round(100.0 * as.intCount / as.totalCount);
+	result.append(Utils.padLeft("" + percent, 3)).append("% ");
+	percent = Math.round(100.0 * as.realCount / as.totalCount);
+	result.append(Utils.padLeft("" + percent, 3)).append("% ");
+	break;
+      }
+      result.append(Utils.padLeft("" + as.missingCount, 5)).append(" /");
+      percent = Math.round(100.0 * as.missingCount / as.totalCount);
+      result.append(Utils.padLeft("" + percent, 3)).append("% ");
+      result.append(Utils.padLeft("" + as.uniqueCount, 5)).append(" /");
+      percent = Math.round(100.0 * as.uniqueCount / as.totalCount);
+      result.append(Utils.padLeft("" + percent, 3)).append("% ");
+      result.append(Utils.padLeft("" + as.distinctCount, 5)).append(' ');
+      result.append('\n');
+    }
+    return result.toString();
+  }
+  
+  /**
+   * Reads a single instance using the tokenizer and appends it
+   * to the dataset. Automatically expands the dataset if it
+   * is not large enough to hold the instance.
+   *
+   * @param tokenizer the tokenizer to be used
+   * @param flag if method should test for carriage return after 
+   * each instance
+   * @return false if end of file has been reached
+   * @exception IOException if the information is not read 
+   * successfully
+   */ 
+  protected boolean getInstance(StreamTokenizer tokenizer, 
+				boolean flag) 
+       throws IOException {
+    
+    // Check if any attributes have been declared.
+    if (m_Attributes.size() == 0) {
+      errms(tokenizer,"no header information available");
+    }
+
+    // Check if end of file reached.
+    getFirstToken(tokenizer);
+    if (tokenizer.ttype == StreamTokenizer.TT_EOF) {
+      return false;
+    }
+    
+    // Parse instance
+    if (tokenizer.ttype == '{') {
+      return getInstanceSparse(tokenizer, flag);
+    } else {
+      return getInstanceFull(tokenizer, flag);
+    }
+  }
+
+  /**
+   * Reads a single instance using the tokenizer and appends it
+   * to the dataset. Automatically expands the dataset if it
+   * is not large enough to hold the instance.
+   *
+   * @param tokenizer the tokenizer to be used
+   * @param flag if method should test for carriage return after 
+   * each instance
+   * @return false if end of file has been reached
+   * @exception IOException if the information is not read 
+   * successfully
+   */ 
+  protected boolean getInstanceSparse(StreamTokenizer tokenizer, 
+				      boolean flag) 
+       throws IOException {
+
+    int valIndex, numValues = 0, maxIndex = -1;
+    
+    // Get values
+    do {
+      
+      // Get index
+      getIndex(tokenizer);
+      if (tokenizer.ttype == '}') {
+	break;
+      }
+       
+      // Is index valid?
+      try{
+	m_IndicesBuffer[numValues] = Integer.valueOf(tokenizer.sval).intValue();
+      } catch (NumberFormatException e) {
+	errms(tokenizer,"index number expected");
+      }
+      if (m_IndicesBuffer[numValues] <= maxIndex) {
+	errms(tokenizer,"indices have to be ordered");
+      }
+      if ((m_IndicesBuffer[numValues] < 0) || 
+	  (m_IndicesBuffer[numValues] >= numAttributes())) {
+	errms(tokenizer,"index out of bounds");
+      }
+      maxIndex = m_IndicesBuffer[numValues];
+
+      // Get value;
+      getNextToken(tokenizer);
+
+      // Check if value is missing.
+      if  (tokenizer.ttype == '?') {
+	m_ValueBuffer[numValues] = Instance.missingValue();
+      } else {
+
+	// Check if token is valid.
+	if (tokenizer.ttype != StreamTokenizer.TT_WORD) {
+	  errms(tokenizer,"not a valid value");
+	}
+	if (attribute(m_IndicesBuffer[numValues]).isNominal()) {
+	  
+	  // Check if value appears in header.
+	  valIndex = 
+	    attribute(m_IndicesBuffer[numValues]).indexOfValue(tokenizer.sval);
+	  if (valIndex == -1) {
+	    errms(tokenizer,"nominal value not declared in header");
+	  }
+	  m_ValueBuffer[numValues] = (double)valIndex;
+	} else if (attribute(m_IndicesBuffer[numValues]).isNumeric()) {
+	  
+	  // Check if value is really a number.
+	  try{
+	    m_ValueBuffer[numValues] = Double.valueOf(tokenizer.sval).
+	      doubleValue();
+	  } catch (NumberFormatException e) {
+	    errms(tokenizer,"number expected");
+	  }
+	} else { 
+	  m_ValueBuffer[numValues] = 
+	    attribute(m_IndicesBuffer[numValues]).addStringValue(tokenizer.sval);
+	}
+      }
+      numValues++;
+    } while (true);
+    if (flag) {
+      getLastToken(tokenizer,true);
+    }
+      
+    // Add instance to dataset
+    double[] tempValues = new double[numValues];
+    int[] tempIndices = new int[numValues];
+    System.arraycopy(m_ValueBuffer, 0, tempValues, 0, numValues);
+    System.arraycopy(m_IndicesBuffer, 0, tempIndices, 0, numValues);
+    add(new SparseInstance(1, tempValues, tempIndices, numAttributes()));
+    return true;
+  }
+
+  /**
+   * Reads a single instance using the tokenizer and appends it
+   * to the dataset. Automatically expands the dataset if it
+   * is not large enough to hold the instance.
+   *
+   * @param tokenizer the tokenizer to be used
+   * @param flag if method should test for carriage return after 
+   * each instance
+   * @return false if end of file has been reached
+   * @exception IOException if the information is not read 
+   * successfully
+   */ 
+  protected boolean getInstanceFull(StreamTokenizer tokenizer, 
+				    boolean flag) 
+       throws IOException {
+
+    double[] instance = new double[numAttributes()];
+    int index;
+    
+    // Get values for all attributes.
+    for (int i = 0; i < numAttributes(); i++){
+      
+      // Get next token
+      if (i > 0) {
+	getNextToken(tokenizer);
+      }
+            
+      // Check if value is missing.
+      if  (tokenizer.ttype == '?') {
+	instance[i] = Instance.missingValue();
+      } else {
+
+	// Check if token is valid.
+	if (tokenizer.ttype != StreamTokenizer.TT_WORD) {
+	  errms(tokenizer,"not a valid value");
+	}
+	if (attribute(i).isNominal()) {
+	  
+	  // Check if value appears in header.
+	  index = attribute(i).indexOfValue(tokenizer.sval);
+	  if (index == -1) {
+	    errms(tokenizer,"nominal value not declared in header");
+	  }
+	  instance[i] = (double)index;
+	} else if (attribute(i).isNumeric()) {
+	  
+	  // Check if value is really a number.
+	  try{
+	    instance[i] = Double.valueOf(tokenizer.sval).
+	      doubleValue();
+	  } catch (NumberFormatException e) {
+	    errms(tokenizer,"number expected");
+	  }
+	} else { 
+	  instance[i] = attribute(i).addStringValue(tokenizer.sval);
+	}
+      }
+    }
+    if (flag) {
+      getLastToken(tokenizer,true);
+    }
+      
+    // Add instance to dataset
+    add(new Instance(1, instance));
+    return true;
+  }
+
+  /**
+   * Reads and stores header of an ARFF file.
+   *
+   * @param tokenizer the stream tokenizer
+   * @exception IOException if the information is not read 
+   * successfully
+   */ 
+  protected void readHeader(StreamTokenizer tokenizer) 
+     throws IOException{
+    
+    String attributeName;
+    FastVector attributeValues;
+    int i;
+
+    // Get name of relation.
+    getFirstToken(tokenizer);
+    if (tokenizer.ttype == StreamTokenizer.TT_EOF) {
+      errms(tokenizer,"premature end of file");
+    }
+    if (tokenizer.sval.equalsIgnoreCase("@relation")){
+      getNextToken(tokenizer);
+      m_RelationName = tokenizer.sval;
+      getLastToken(tokenizer,false);
+    } else {
+      errms(tokenizer,"keyword @relation expected");
+    }
+
+    // Create vectors to hold information temporarily.
+    m_Attributes = new FastVector();
+ 
+    // Get attribute declarations.
+    getFirstToken(tokenizer);
+    if (tokenizer.ttype == StreamTokenizer.TT_EOF) {
+      errms(tokenizer,"premature end of file");
+    }
+    while (tokenizer.sval.equalsIgnoreCase("@attribute")) {
+
+      // Get attribute name.
+      getNextToken(tokenizer);
+      attributeName = tokenizer.sval;
+      getNextToken(tokenizer);
+
+      // Check if attribute is nominal.
+      if (tokenizer.ttype == StreamTokenizer.TT_WORD) {
+
+	// Attribute is real, integer, or string.
+	if (tokenizer.sval.equalsIgnoreCase("real") ||
+	    tokenizer.sval.equalsIgnoreCase("integer") ||
+	    tokenizer.sval.equalsIgnoreCase("numeric")) {
+	  m_Attributes.addElement(new Attribute(attributeName,
+						 numAttributes()));
+	  readTillEOL(tokenizer);
+	} else if (tokenizer.sval.equalsIgnoreCase("string")) {
+	  m_Attributes.
+	    addElement(new Attribute(attributeName, null,
+				     numAttributes()));
+	  readTillEOL(tokenizer);
+	} else {
+	  errms(tokenizer,"no valid attribute type or invalid "+
+		"enumeration");
+	}
+      } else {
+
+	// Attribute is nominal.
+	attributeValues = new FastVector();
+	tokenizer.pushBack();
+	
+	// Get values for nominal attribute.
+	if (tokenizer.nextToken() != '{') {
+	  errms(tokenizer,"{ expected at beginning of enumeration");
+	}
+	while (tokenizer.nextToken() != '}') {
+	  if (tokenizer.ttype == StreamTokenizer.TT_EOL) {
+	    errms(tokenizer,"} expected at end of enumeration");
+	  } else {
+	    attributeValues.addElement(tokenizer.sval);
+	  }
+	}
+	if (attributeValues.size() == 0) {
+	  errms(tokenizer,"no nominal values found");
+	}
+	m_Attributes.
+	  addElement(new Attribute(attributeName, attributeValues,
+				   numAttributes()));
+      }
+      getLastToken(tokenizer,false);
+      getFirstToken(tokenizer);
+      if (tokenizer.ttype == StreamTokenizer.TT_EOF)
+	errms(tokenizer,"premature end of file");
+    }
+
+    // Check if data part follows. We can't easily check for EOL.
+    if (!tokenizer.sval.equalsIgnoreCase("@data")) {
+      errms(tokenizer,"keyword @data expected");
+    }
+    
+    // Check if any attributes have been declared.
+    if (m_Attributes.size() == 0) {
+      errms(tokenizer,"no attributes declared");
+    }
+
+    // Allocate buffers in case sparse instances have to be read
+    m_ValueBuffer = new double[numAttributes()];
+    m_IndicesBuffer = new int[numAttributes()];
+  }
+
+  /**
+   * Copies instances from one set to the end of another 
+   * one.
+   *
+   * @param source the source of the instances
+   * @param from the position of the first instance to be copied
+   * @param dest the destination for the instances
+   * @param num the number of instances to be copied
+   */
+  private void copyInstances(int from, Instances dest, int num) {
+    
+    for (int i = 0; i < num; i++) {
+      dest.add(instance(from + i));
+    }
+  }
+  
+  /**
+   * Throws error message with line number and last token read.
+   *
+   * @param theMsg the error message to be thrown
+   * @param tokenizer the stream tokenizer
+   * @throws IOExcpetion containing the error message
+   */
+  private void errms(StreamTokenizer tokenizer, String theMsg) 
+       throws IOException {
+    
+    throw new IOException(theMsg + ", read " + tokenizer.toString());
+  }
+  
+  /**
+   * Replaces the attribute information by a clone of
+   * itself.
+   */
+  private void freshAttributeInfo() {
+
+    m_Attributes = (FastVector) m_Attributes.copyElements();
+  }
+
+  /**
+   * Gets next token, skipping empty lines.
+   *
+   * @param tokenizer the stream tokenizer
+   * @exception IOException if reading the next token fails
+   */
+  private void getFirstToken(StreamTokenizer tokenizer) 
+    throws IOException{
+    
+    while (tokenizer.nextToken() == StreamTokenizer.TT_EOL){};
+    if ((tokenizer.ttype == '\'') ||
+	(tokenizer.ttype == '"')) {
+      tokenizer.ttype = StreamTokenizer.TT_WORD;
+    } else if ((tokenizer.ttype == StreamTokenizer.TT_WORD) &&
+	       (tokenizer.sval.equals("?"))){
+      tokenizer.ttype = '?';
+    }
+  }
+
+  /**
+   * Gets index, checking for a premature and of line.
+   *
+   * @param tokenizer the stream tokenizer
+   * @exception IOException if it finds a premature end of line
+   */
+  private void getIndex(StreamTokenizer tokenizer) throws IOException{
+    
+    if (tokenizer.nextToken() == StreamTokenizer.TT_EOL) {
+      errms(tokenizer,"premature end of line");
+    }
+    if (tokenizer.ttype == StreamTokenizer.TT_EOF) {
+      errms(tokenizer,"premature end of file");
+    }
+  }
+  
+  /**
+   * Gets token and checks if its end of line.
+   *
+   * @param tokenizer the stream tokenizer
+   * @exception IOException if it doesn't find an end of line
+   */
+  private void getLastToken(StreamTokenizer tokenizer, boolean endOfFileOk) 
+       throws IOException{
+
+    if ((tokenizer.nextToken() != StreamTokenizer.TT_EOL) &&
+	((tokenizer.nextToken() != StreamTokenizer.TT_EOF) || !endOfFileOk)) {
+      errms(tokenizer,"end of line expected");
+    }
+  }
+
+  /**
+   * Gets next token, checking for a premature and of line.
+   *
+   * @param tokenizer the stream tokenizer
+   * @exception IOException if it finds a premature end of line
+   */
+  private void getNextToken(StreamTokenizer tokenizer) 
+       throws IOException{
+    
+    if (tokenizer.nextToken() == StreamTokenizer.TT_EOL) {
+      errms(tokenizer,"premature end of line");
+    }
+    if (tokenizer.ttype == StreamTokenizer.TT_EOF) {
+      errms(tokenizer,"premature end of file");
+    } else if ((tokenizer.ttype == '\'') ||
+	       (tokenizer.ttype == '"')) {
+      tokenizer.ttype = StreamTokenizer.TT_WORD;
+    } else if ((tokenizer.ttype == StreamTokenizer.TT_WORD) &&
+	       (tokenizer.sval.equals("?"))){
+      tokenizer.ttype = '?';
+    }
+  }
+	
+  /**
+   * Initializes the StreamTokenizer used for reading the ARFF file.
+   *
+   * @param tokenizer the stream tokenizer
+   */
+  private void initTokenizer(StreamTokenizer tokenizer){
+
+    tokenizer.resetSyntax();         
+    tokenizer.whitespaceChars(0, ' ');    
+    tokenizer.wordChars(' '+1,'\u00FF');
+    tokenizer.whitespaceChars(',',',');
+    tokenizer.commentChar('%');
+    tokenizer.quoteChar('"');
+    tokenizer.quoteChar('\'');
+    tokenizer.ordinaryChar('{');
+    tokenizer.ordinaryChar('}');
+    tokenizer.eolIsSignificant(true);
+  }
+ 
+  /**
+   * Returns string including all instances, their weights and
+   * their indices in the original dataset.
+   *
+   * @return description of instance and its weight as a string
+   */
+  private String instancesAndWeights(){
+
+    StringBuffer text = new StringBuffer();
+
+    for (int i = 0; i < numInstances(); i++) {
+      text.append(instance(i) + " " + instance(i).weight());
+      if (i < numInstances() - 1) {
+	text.append("\n");
+      }
+    }
+    return text.toString();
+  }
+  
+  /**
+   * Implements quicksort.
+   *
+   * @param attIndex the attribute's index
+   * @param lo0 the first index of the subset to be sorted
+   * @param hi0 the last index of the subset to be sorted
+   */
+  private void quickSort(int attIndex, int lo0, int hi0) {
+    
+    int lo = lo0, hi = hi0;
+    double mid, midPlus, midMinus;
+    
+    if (hi0 > lo0) {
+      
+      // Arbitrarily establishing partition element as the 
+      // midpoint of the array.
+      mid = instance((lo0 + hi0) / 2).value(attIndex);
+      midPlus = mid + 1e-6;
+      midMinus = mid - 1e-6;
+
+      // loop through the array until indices cross
+      while(lo <= hi) {
+	
+	// find the first element that is greater than or equal to 
+	// the partition element starting from the left Index.
+	while ((instance(lo).value(attIndex) < 
+		midMinus) && (lo < hi0)) {
+	  ++lo;
+	}
+	
+	// find an element that is smaller than or equal to
+	// the partition element starting from the right Index.
+	while ((instance(hi).value(attIndex)  > 
+		midPlus) && (hi > lo0)) {
+	  --hi;
+	}
+	
+	// if the indexes have not crossed, swap
+	if(lo <= hi) {
+	  swap(lo,hi);
+	  ++lo;
+	  --hi;
+	}
+      }
+      
+      // If the right index has not reached the left side of array
+      // must now sort the left partition.
+      if(lo0 < hi) {
+	quickSort(attIndex,lo0,hi);
+      }
+      
+      // If the left index has not reached the right side of array
+      // must now sort the right partition.
+      if(lo < hi0) {
+	quickSort(attIndex,lo,hi0);
+      }
+    }
+  }
+
+  /**
+   * Reads and skips all tokens before next end of line token.
+   *
+   * @param tokenizer the stream tokenizer
+   */
+  private void readTillEOL(StreamTokenizer tokenizer) 
+       throws IOException{
+    
+    while (tokenizer.nextToken() != StreamTokenizer.TT_EOL) {};
+    tokenizer.pushBack();
+  }
+
+  /**
+   * Help function needed for stratification of set.
+   *
+   * @param numFolds the number of folds for the stratification
+   */
+  private void stratStep (int numFolds){
+    
+    FastVector newVec = new FastVector(m_Instances.capacity());
+    int start = 0, j;
+
+    // create stratified batch
+    while (newVec.size() < numInstances()) {
+      j = start;
+      while (j < numInstances()) {
+	newVec.addElement(instance(j));
+	j = j + numFolds;
+      }
+      start++;
+    }
+    m_Instances = newVec;
+  }
+  
+  /**
+   * Swaps two instances in the set.
+   *
+   * @param i the first instance's index
+   * @param j the second instance's index
+   */
+  private void swap(int i, int j){
+    
+    m_Instances.swap(i, j);
+  }
+
+  /**
+   * Merges two sets of Instances together. The resulting set will have
+   * all the attributes of the first set plus all the attributes of the 
+   * second set. The number of instances in both sets must be the same.
+   *
+   * @param first the first set of Instances
+   * @param second the second set of Instances
+   * @return the merged set of Instances
+   * @exception IllegalArgumentException if the datasets are not the same size
+   */
+  public static Instances mergeInstances(Instances first, Instances second) {
+
+    if (first.numInstances() != second.numInstances()) {
+      throw new IllegalArgumentException("Instance sets must be of the same size");
+    }
+
+    // Create the vector of merged attributes
+    FastVector newAttributes = new FastVector();
+    for (int i = 0; i < first.numAttributes(); i++) {
+      newAttributes.addElement(first.attribute(i));
+    }
+    for (int i = 0; i < second.numAttributes(); i++) {
+      newAttributes.addElement(second.attribute(i));
+    }
+    
+    // Create the set of Instances
+    Instances merged = new Instances(first.relationName() + '_'
+				     + second.relationName(), 
+				     newAttributes, 
+				     first.numInstances());
+    // Merge each instance
+    for (int i = 0; i < first.numInstances(); i++) {
+      merged.add(first.instance(i).mergeInstance(second.instance(i)));
+    }
+    return merged;
+  }
+
+  /**
+   * Method for testing this class.
+   *
+   * @param argv should contain one element: the name of an ARFF file
+   */
+  public static void test(String [] argv) {
+
+    Instances instances, secondInstances, train, test, transformed, empty;
+    Instance instance;
+    Random random = new Random(2);
+    Reader reader;
+    int start, num;
+    double newWeight;
+    FastVector testAtts, testVals;
+    int i,j;
+    
+    try{
+      if (argv.length > 1) {
+	throw (new Exception("Usage: Instances [<filename>]"));
+      }
+      
+      // Creating set of instances from scratch
+      testVals = new FastVector(2);
+      testVals.addElement("first_value");
+      testVals.addElement("second_value");
+      testAtts = new FastVector(2);
+      testAtts.addElement(new Attribute("nominal_attribute", testVals));
+      testAtts.addElement(new Attribute("numeric_attribute"));
+      instances = new Instances("test_set", testAtts, 10);
+      instances.add(new Instance(instances.numAttributes()));
+      instances.add(new Instance(instances.numAttributes()));
+      instances.add(new Instance(instances.numAttributes()));
+      instances.setClassIndex(0);
+      System.out.println("\nSet of instances created from scratch:\n");
+      System.out.println(instances);
+      
+      if (argv.length == 1) {
+	String filename = argv[0];
+	reader = new FileReader(filename);
+	
+	// Read first five instances and print them
+	System.out.println("\nFirst five instances from file:\n");
+	instances = new Instances(reader, 1);
+	instances.setClassIndex(instances.numAttributes() - 1);
+	i = 0;
+	while ((i < 5) && (instances.readInstance(reader))) {
+	  i++;
+	}
+	System.out.println(instances);
+
+	// Read all the instances in the file
+	reader = new FileReader(filename);
+	instances = new Instances(reader);
+
+	// Make the last attribute be the class 
+	instances.setClassIndex(instances.numAttributes() - 1);
+	
+	// Print header and instances.
+	System.out.println("\nDataset:\n");
+	System.out.println(instances);
+	System.out.println("\nClass index: "+instances.classIndex());
+      }
+      
+      // Test basic methods based on class index.
+      System.out.println("\nClass name: "+instances.classAttribute().name());
+      System.out.println("\nClass index: "+instances.classIndex());
+      System.out.println("\nClass is nominal: " +
+			 instances.classAttribute().isNominal());
+      System.out.println("\nClass is numeric: " +
+			 instances.classAttribute().isNumeric());
+      System.out.println("\nClasses:\n");
+      for (i = 0; i < instances.numClasses(); i++) {
+	System.out.println(instances.classAttribute().value(i));
+      }
+      System.out.println("\nClass values and labels of instances:\n");
+      for (i = 0; i < instances.numInstances(); i++) {
+	Instance inst = instances.instance(i);
+	System.out.print(inst.classValue() + "\t");
+	System.out.print(inst.toString(inst.classIndex()));
+	if (instances.instance(i).classIsMissing()) {
+	  System.out.println("\tis missing");
+	} else {
+	  System.out.println();
+	}
+      }
+      
+      // Create random weights.
+      System.out.println("\nCreating random weights for instances.");
+      for (i = 0; i < instances.numInstances(); i++) {
+	instances.instance(i).setWeight(random.nextDouble()); 
+      }
+      
+      // Print all instances and their weights (and the sum of weights).
+      System.out.println("\nInstances and their weights:\n");
+      System.out.println(instances.instancesAndWeights());
+      System.out.print("\nSum of weights: ");
+      System.out.println(instances.sumOfWeights());
+      
+      // Insert an attribute
+      secondInstances = new Instances(instances);
+      Attribute testAtt = new Attribute("Inserted");
+      secondInstances.insertAttributeAt(testAtt, 0);
+      System.out.println("\nSet with inserted attribute:\n");
+      System.out.println(secondInstances);
+      System.out.println("\nClass name: "
+			 + secondInstances.classAttribute().name());
+      
+      // Delete the attribute
+      secondInstances.deleteAttributeAt(0);
+      System.out.println("\nSet with attribute deleted:\n");
+      System.out.println(secondInstances);
+      System.out.println("\nClass name: "
+			 + secondInstances.classAttribute().name());
+      
+      // Test if headers are equal
+      System.out.println("\nHeaders equal: "+
+			 instances.equalHeaders(secondInstances) + "\n");
+      
+      // Print data in internal format.
+      System.out.println("\nData (internal values):\n");
+      for (i = 0; i < instances.numInstances(); i++) {
+	for (j = 0; j < instances.numAttributes(); j++) {
+	  if (instances.instance(i).isMissing(j)) {
+	    System.out.print("? ");
+	  } else {
+	    System.out.print(instances.instance(i).value(j) + " ");
+	  }
+	}
+	System.out.println();
+      }
+      
+      // Just print header
+      System.out.println("\nEmpty dataset:\n");
+      empty = new Instances(instances, 0);
+      System.out.println(empty);
+      System.out.println("\nClass name: "+empty.classAttribute().name());
+
+      // Create copy and rename an attribute and a value (if possible)
+      if (empty.classAttribute().isNominal()) {
+	Instances copy = new Instances(empty, 0);
+	copy.renameAttribute(copy.classAttribute(), "new_name");
+	copy.renameAttributeValue(copy.classAttribute(), 
+				  copy.classAttribute().value(0), 
+				  "new_val_name");
+	System.out.println("\nDataset with names changed:\n" + copy);
+	System.out.println("\nOriginal dataset:\n" + empty);
+      }
+
+      // Create and prints subset of instances.
+      start = instances.numInstances() / 4;
+      num = instances.numInstances() / 2;
+      System.out.print("\nSubset of dataset: ");
+      System.out.println(num + " instances from " + (start + 1) 
+			 + ". instance");
+      secondInstances = new Instances(instances, start, num);
+      System.out.println("\nClass name: "
+			 + secondInstances.classAttribute().name());
+
+      // Print all instances and their weights (and the sum of weights).
+      System.out.println("\nInstances and their weights:\n");
+      System.out.println(secondInstances.instancesAndWeights());
+      System.out.print("\nSum of weights: ");
+      System.out.println(secondInstances.sumOfWeights());
+      
+      // Create and print training and test sets for 3-fold
+      // cross-validation.
+      System.out.println("\nTrain and test folds for 3-fold CV:");
+      if (instances.classAttribute().isNominal()) {
+	instances.stratify(3);
+      }
+      for (j = 0; j < 3; j++) {
+        train = instances.trainCV(3,j);
+	test = instances.testCV(3,j);
+                      
+	// Print all instances and their weights (and the sum of weights).
+	System.out.println("\nTrain: ");
+	System.out.println("\nInstances and their weights:\n");
+	System.out.println(train.instancesAndWeights());
+	System.out.print("\nSum of weights: ");
+	System.out.println(train.sumOfWeights());
+	System.out.println("\nClass name: "+train.classAttribute().name());
+	System.out.println("\nTest: ");
+	System.out.println("\nInstances and their weights:\n");
+	System.out.println(test.instancesAndWeights());
+	System.out.print("\nSum of weights: ");
+	System.out.println(test.sumOfWeights());
+	System.out.println("\nClass name: "+test.classAttribute().name());
+      }
+
+      // Randomize instances and print them.
+      System.out.println("\nRandomized dataset:");
+      instances.randomize(random);
+      
+      // Print all instances and their weights (and the sum of weights).
+      System.out.println("\nInstances and their weights:\n");
+      System.out.println(instances.instancesAndWeights());
+      System.out.print("\nSum of weights: ");
+      System.out.println(instances.sumOfWeights());
+
+      // Sort instances according to first attribute and
+      // print them.
+      System.out.print("\nInstances sorted according to first attribute:\n ");
+      instances.sort(0);
+        
+      // Print all instances and their weights (and the sum of weights).
+      System.out.println("\nInstances and their weights:\n");
+      System.out.println(instances.instancesAndWeights());
+      System.out.print("\nSum of weights: ");
+      System.out.println(instances.sumOfWeights());
+    } catch (Exception e) {
+      e.printStackTrace(); 
+    }
+  }
+
+  /**
+   * Main method for this class -- just prints a summary of a set
+   * of instances.
+   *
+   * @param argv should contain one element: the name of an ARFF file
+   */
+  public static void main(String [] args) {
+
+    try {
+      Reader r = null;
+      if (args.length > 1) {
+	throw (new Exception("Usage: Instances <filename>"));
+      } else if (args.length == 0) {
+        r = new BufferedReader(new InputStreamReader(System.in));
+      } else {
+        r = new BufferedReader(new FileReader(args[0]));
+      }
+      Instances i = new Instances(r);
+      System.out.println(i.toSummaryString());
+    } catch (Exception ex) {
+      System.err.println(ex.getMessage());
+    }
+  }
+}
+
+     
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Option.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Option.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Option.java	(revision 20131)
@@ -0,0 +1,105 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    Option.java
+ *    Copyright (C) 1999 Eibe Frank
+ *
+ */
+
+package weka.core;
+
+/** 
+ * Class to store information about an option. <p>
+ *
+ * Typical usage: <p>
+ *
+ * <code>Option myOption = new Option("Uses extended mode.", "E", 0, "-E")); </code><p>
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public class Option {
+
+  /** What does this option do? */
+  private String m_Description;
+
+  /** The synopsis. */
+  private String m_Synopsis;
+
+  /** What's the option's name? */
+  private String m_Name;
+
+  /** How many arguments does it take? */
+  private int m_NumArguments;
+
+  /**
+   * Creates new option with the given parameters.
+   *
+   * @String description the option's description
+   * @String name the option's name
+   * @String numArguments the number of arguments
+   */
+  public Option(String description, String name, 
+		int numArguments, String synopsis) {
+  
+    m_Description = description;
+    m_Name = name;
+    m_NumArguments = numArguments;
+    m_Synopsis = synopsis;
+  }
+
+  /**
+   * Returns the option's description.
+   *
+   * @return the option's description
+   */
+  public String description() {
+  
+    return m_Description;
+  }
+
+  /**
+   * Returns the option's name.
+   *
+   * @return the option's name
+   */
+  public String name() {
+
+    return m_Name;
+  }
+
+  /**
+   * Returns the option's number of arguments.
+   *
+   * @return the option's number of arguments
+   */
+  public int numArguments() {
+  
+    return m_NumArguments;
+  }
+
+  /**
+   * Returns the option's synopsis.
+   *
+   * @return the option's synopsis
+   */
+  public String synopsis() {
+  
+    return m_Synopsis;
+  }
+}
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/OptionHandler.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/OptionHandler.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/OptionHandler.java	(revision 20131)
@@ -0,0 +1,67 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    OptionHandler.java
+ *    Copyright (C) 1999 Eibe Frank,Len Trigg
+ *
+ */
+
+package weka.core;
+
+import java.util.*;
+
+/** 
+ * Interface to something that understands options.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @author Len Trigg (trigg@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public interface OptionHandler {
+
+  /**
+   * Returns an enumeration of all the available options.
+   *
+   * @return an enumeration of all available options
+   */
+  public Enumeration listOptions();
+
+  /**
+   * Sets the OptionHandler's options using the given list. All options
+   * will be set (or reset) during this call (i.e. incremental setting
+   * of options is not possible).
+   *
+   * @param options the list of options as an array of strings
+   * @exception Exception if an option is not supported
+   */
+  public void setOptions(String[] options) throws Exception;
+
+  /**
+   * Gets the current option settings for the OptionHandler.
+   *
+   * @return the list of current option settings as an array of strings
+   */
+  public String[] getOptions();
+}
+
+
+
+
+
+
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Queue.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Queue.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Queue.java	(revision 20131)
@@ -0,0 +1,229 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    Queue.java
+ *    Copyright (C) 1999 Len Trigg
+ *
+ */
+
+package weka.core;
+
+import java.io.*;
+
+/** 
+ * Class representing a FIFO queue.
+ *
+ * @author Len Trigg (trigg@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public class Queue extends Object implements Serializable {
+
+  /**
+   * Represents one node in the queue.
+   */
+  protected class QueueNode implements Serializable {
+
+    /** The next node in the queue */
+    protected QueueNode m_Next;
+
+    /** The nodes contents */
+    protected Object m_Contents;
+
+    /** 
+     * Creates a queue node with the given contents 
+     */
+    public QueueNode(Object contents) {
+
+      m_Contents = contents;
+      next(null);
+    }
+
+    /**
+     * Sets the next node in the queue, and returns it.
+     */
+    public QueueNode next(QueueNode next) {
+
+      return m_Next = next;
+    }
+
+    /**
+     * Gets the next node in the queue. 
+     */
+    public QueueNode next() {
+
+      return m_Next;
+    }
+
+    /**
+     * Sets the contents of the node.
+     */
+    public Object contents(Object contents) {
+
+      return m_Contents = contents;
+    }
+
+    /**
+     * Returns the contents in the node.
+     */
+    public Object contents() {
+
+      return m_Contents;
+    }
+  }
+
+  /** Store a reference to the head of the queue */
+  protected QueueNode m_Head = null;
+
+  /** Store a reference to the tail of the queue */
+  protected QueueNode m_Tail = null;
+
+  /** Store the current number of elements in the queue */
+  protected int m_Size = 0;
+
+  /**
+   * Removes all objects from the queue.
+   */
+  public final synchronized void removeAllElements() {
+
+    m_Size = 0;
+    m_Head = null;
+    m_Tail = null;
+  }
+
+  /**
+   * Appends an object to the back of the queue.
+   *
+   * @param item the object to be appended
+   * @return the object appended
+   */
+  public synchronized Object push(Object item) {
+
+    QueueNode newNode = new QueueNode(item);
+    if (m_Head == null) {
+      m_Head = m_Tail = newNode;
+    } else {
+      m_Tail = m_Tail.next(newNode);
+    }
+    m_Size++;
+    return item;
+  }
+
+  /**
+   * Pops an object from the front of the queue.
+   *
+   * @return the object at the front of the queue
+   * @exception RuntimeException if the queue is empty
+   */
+  public synchronized Object pop() {
+
+    if (m_Head == null) {
+      throw new RuntimeException("Queue is empty");
+    }
+    Object retval = m_Head.contents();
+    m_Size--;
+    m_Head = m_Head.next();
+    if (m_Head == null) {
+      m_Tail = null;
+    }
+    return retval;
+  }
+
+  /**
+   * Gets object from the front of the queue.
+   *
+   * @return the object at the front of the queue
+   * @exception RuntimeException if the queue is empty
+   */
+  public synchronized Object peek() {
+    
+    if (m_Head == null) {
+      throw new RuntimeException("Queue is empty");
+    }
+    return m_Head.contents();
+  }
+
+  /**
+   * Checks if queue is empty.
+   * 
+   * @return true if queue is empty
+   */
+  public boolean empty() {
+
+    return (m_Head == null);
+  }
+
+  /** 
+   * Gets queue's size.
+   *
+   * @return size of queue
+   */
+  public int size() {
+
+    return m_Size;
+  }
+
+  /**
+   * Produces textual description of queue.
+   *
+   * @return textual description of queue
+   */
+  public String toString() {
+
+    String retval = "Queue Contents "+m_Size+" elements\n";
+    QueueNode current = m_Head;
+    if (current == null) {
+      return retval + "Empty\n";
+    } else {
+      while (current != null) {
+	retval += current.contents().toString()+"\n";
+	current = current.next();
+      }
+    }
+    return retval;
+  }
+
+  /**
+   * Main method for testing this class.
+   *
+   * @param argv a set of strings that are pushed on a test queue
+   */
+  public static void main(String [] argv) {
+
+    try {
+      Queue queue = new Queue();
+      for(int i = 0; i < argv.length; i++) {
+	queue.push(argv[i]);
+      }
+      System.out.println("After Pushing");
+      System.out.println(queue.toString());
+      System.out.println("Popping...");
+      while (!queue.empty()) {
+	System.out.println(queue.pop().toString());
+      }
+    } catch (Exception ex) {
+      System.out.println(ex.getMessage());
+    }
+  }
+}
+
+
+
+
+
+
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Range.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Range.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Range.java	(revision 20131)
@@ -0,0 +1,439 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    Range.java
+ *    Copyright (C) 1999 Len Trigg
+ *
+ */
+
+package weka.core;
+
+import java.io.*;
+import java.util.*;
+
+/** 
+ * Class representing a range of cardinal numbers. The range is set by a 
+ * string representation such as: <P>
+ *
+ * <code>
+ *   all
+ *   first-last
+ *   1,2,3,4
+ * </code> <P>
+ * or combinations thereof. The range is internally converted from
+ * 1-based to 0-based (so methods that set or get numbers not in string
+ * format should use 0-based numbers).
+ *
+ * @author Len Trigg (trigg@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public class Range implements Serializable {
+
+  /** Record the string representations of the columns to delete */
+  Vector m_RangeStrings = new Vector();
+
+  /** Whether matching should be inverted */
+  boolean m_Invert;
+
+  /** The array of flags for whether an column is selected */
+  boolean [] m_SelectFlags;
+
+  /** Store the maximum value permitted in the range. -1 indicates that
+      no upper value has been set */
+  int m_Upper = -1;
+
+  /** Default constructor. */
+  public Range() {
+  }
+
+  /**
+   * Constructor to set initial range.
+   *
+   * @param rangeList the initial range
+   * @exception IllegalArgumentException if the range list is invalid
+   */
+  public Range(String rangeList) {
+
+    setRanges(rangeList);
+  }
+
+  /**
+   * Sets the value of "last".
+   *
+   * @param newUpper the value of "last"
+   */
+  public void setUpper(int newUpper) {
+
+    if (newUpper >= 0) {
+      m_Upper = newUpper;
+      setFlags();
+    }
+  }
+  
+  /**
+   * Gets whether the range sense is inverted, i.e. all <i>except</i>
+   * the values included by the range string are selected.
+   * 
+   * @return whether the matching sense is inverted
+   */
+  public boolean getInvert() {
+
+    return m_Invert;
+  }
+
+  /**
+   * Sets whether the range sense is inverted, i.e. all <i>except</i>
+   * the values included by the range string are selected.
+   * 
+   * @param newSetting true if the matching sense is inverted
+   */
+  public void setInvert(boolean newSetting) {
+
+    m_Invert = newSetting;
+  }
+
+  /**
+   * Gets the string representing the selected range of values
+   *
+   * @return the range selection string
+   */
+  public String getRanges() {
+
+    String result = null;
+    Enumeration enum = m_RangeStrings.elements();
+    while (enum.hasMoreElements()) {
+      if (result == null) {
+	result = (String)enum.nextElement();
+      } else {
+	result += ',' + (String)enum.nextElement();
+      }
+    }
+    return (result == null) ? "" : result;
+  }
+
+  /**
+   * Sets the ranges from a string representation.
+   *
+   * @param rangeList the comma separated list of ranges. The empty
+   * string sets the range to empty.
+   * @exception IllegalArgumentException if the rangeList was not well formed
+   */
+  public void setRanges(String rangeList) {
+
+    Vector ranges = new Vector (10);
+
+    // Split the rangeList up into the vector
+    while (!rangeList.equals("")) {
+      String range = rangeList.trim();
+      int commaLoc = rangeList.indexOf(',');
+      if (commaLoc != -1) {
+	range = rangeList.substring(0, commaLoc).trim();
+	rangeList = rangeList.substring(commaLoc + 1).trim();
+      } else {
+	rangeList = "";
+      }
+      if (!range.equals("")) {
+	if (isValidRange(range)) {
+	  ranges.addElement(range);
+	} else {
+	  throw new IllegalArgumentException("Invalid range list at " + range
+                                             + rangeList);
+	}
+      }
+    }
+    m_RangeStrings = ranges;
+    
+    if (m_Upper >= 0) {
+      setFlags();
+    }
+  }
+
+  /**
+   * Gets whether the supplied cardinal number is included in the current
+   * range.
+   *
+   * @param index the number of interest
+   * @return true if index is in the current range
+   * @exception RuntimeException if the upper limit of the range hasn't been defined
+   */
+  public boolean isInRange(int index) {
+
+    if (m_Upper == -1) {
+      throw new RuntimeException("No upper limit has been specified for range");
+    }
+    if (m_Invert) {
+      return !m_SelectFlags[index];
+    } else {
+      return m_SelectFlags[index];
+    }
+  }
+
+  /**
+   * Constructs a representation of the current range. Being a string
+   * representation, the numbers are based from 1.
+   * 
+   * @return the string representation of the current range
+   */
+  public String toString() {
+
+    if (m_RangeStrings.size() == 0) {
+      return "Empty";
+    }
+    String result ="Strings: ";
+    Enumeration enum = m_RangeStrings.elements();
+    while (enum.hasMoreElements()) {
+      result += (String)enum.nextElement() + " ";
+    }
+    result += "\n";
+
+    result += "Invert: " + m_Invert + "\n";
+
+    try {
+      if (m_Upper == -1) {
+	throw new RuntimeException("Upper limit has not been specified");
+      }
+      String cols = null;
+      for (int i = 0; i < m_SelectFlags.length; i++) {
+	if (isInRange(i)) {
+	  if (cols == null) {
+	    cols = "Cols: " + (i + 1);
+	  } else {
+	    cols += "," + (i + 1);
+	  }
+	}
+      }
+      if (cols != null) {
+	result += cols + "\n";
+      }
+    } catch (Exception ex) {
+      result += ex.getMessage();
+    }
+    return result;
+  }
+
+  /**
+   * Gets an array containing all the selected values, in the order
+   * that they were selected (or ascending order if range inversion is on)
+   *
+   * @return the array of selected values
+   * @exception RuntimeException if the upper limit of the range hasn't been defined
+   */
+  public int [] getSelection() {
+
+    if (m_Upper == -1) {
+      throw new RuntimeException("No upper limit has been specified for range");
+    }
+    int [] selectIndices = new int [m_Upper + 1];
+    int numSelected = 0;
+    if (m_Invert)
+    {
+      for (int i = 0; i <= m_Upper; i++) {
+	if (!m_SelectFlags[i]) {
+	  selectIndices[numSelected++] = i;
+	}
+      }
+    }
+    else
+    {
+      Enumeration enum = m_RangeStrings.elements();
+      while (enum.hasMoreElements()) {
+	String currentRange = (String)enum.nextElement();
+	int start = rangeLower(currentRange);
+	int end = rangeUpper(currentRange);
+	for (int i = start; (i <= m_Upper) && (i <= end); i++) {
+	  if (m_SelectFlags[i]) {
+	    selectIndices[numSelected++] = i;
+	  }
+	}
+      }
+    }
+    int [] result = new int [numSelected];
+    System.arraycopy(selectIndices, 0, result, 0, numSelected);
+    return result;
+  }
+
+  /**
+   * Creates a string representation of the indices in the supplied array.
+   *
+   * @param indices an array containing indices to select.
+   * Since the array will typically come from a program, indices are assumed
+   * from 0, and thus will have 1 added in the String representation.
+   */
+  public static String indicesToRangeList(int []indices) {
+
+    StringBuffer rl = new StringBuffer();
+    int last = -2;
+    boolean range = false;
+    for(int i = 0; i < indices.length; i++) {
+      if (i == 0) {
+	rl.append(indices[i] + 1);
+      } else if (indices[i] == last) {
+        range = true;
+      } else {
+        if (range) {
+          rl.append('-').append(last);
+          range = false;
+        }
+	rl.append(',').append(indices[i] + 1);
+      }
+      last = indices[i] + 1;
+    }
+    if (range) {
+      rl.append('-').append(last);
+    }
+    return rl.toString();
+  }
+
+  /** Sets the flags array. */
+  protected void setFlags() {
+
+    m_SelectFlags = new boolean [m_Upper + 1];
+    Enumeration enum = m_RangeStrings.elements();
+    while (enum.hasMoreElements()) {
+      String currentRange = (String)enum.nextElement();
+      int start = rangeLower(currentRange);
+      int end = rangeUpper(currentRange);
+      for (int i = start; (i <= m_Upper) && (i <= end); i++) {
+	m_SelectFlags[i] = true;
+      }
+    }
+  }
+
+
+  /**
+   * Translates a single string selection into it's internal 0-based equivalent
+   *
+   * @param single the string representing the selection (eg: 1 first last)
+   * @return the number corresponding to the selected value
+   */
+  protected int rangeSingle(String single) {
+
+    if (single.toLowerCase().equals("first")) {
+      return 0;
+    }
+    if (single.toLowerCase().equals("last")) {
+      return m_Upper;
+    }
+    int index = Integer.parseInt(single) - 1;
+    if (index < 0) {
+      index = 0;
+    }
+    if (index > m_Upper) {
+      index = m_Upper;
+    }
+    return index;
+  }
+
+  /**
+   * Translates a range into it's lower index.
+   *
+   * @param range the string representation of the range
+   * @return the lower index of the range
+   */
+  protected int rangeLower(String range) {
+
+    int hyphenIndex;
+    if ((hyphenIndex = range.indexOf('-')) >= 0) {
+      return Math.min(rangeLower(range.substring(0, hyphenIndex)),
+		       rangeLower(range.substring(hyphenIndex + 1)));
+    }
+    return rangeSingle(range);
+  }
+
+  /**
+   * Translates a range into it's upper index. Must only be called once
+   * setUpper has been called.
+   *
+   * @param range the string representation of the range
+   * @return the upper index of the range
+   */
+  protected int rangeUpper(String range) {
+
+    int hyphenIndex;
+    if ((hyphenIndex = range.indexOf('-')) >= 0) {
+      return Math.max(rangeUpper(range.substring(0, hyphenIndex)),
+		       rangeUpper(range.substring(hyphenIndex + 1)));
+    }
+    return rangeSingle(range);
+  }
+
+  /**
+   * Determines if a string represents a valid index or simple range.
+   * Examples: <code>first  last   2   first-last  first-4  4-last</code>
+   * Doesn't check that a < b for a-b
+   *
+   * @param range
+   * @return true if the range is valid
+   */
+  protected boolean isValidRange(String range) {
+
+    if (range == null) {
+      return false;
+    }
+    int hyphenIndex;
+    if ((hyphenIndex = range.indexOf('-')) >= 0) {
+      if (isValidRange(range.substring(0, hyphenIndex)) &&
+	  isValidRange(range.substring(hyphenIndex + 1))) {
+	return true;
+      }
+      return false;
+    }
+    if (range.toLowerCase().equals("first")) {
+      return true;
+    }
+    if (range.toLowerCase().equals("last")) {
+      return true;
+    }
+    try {
+      int index = Integer.parseInt(range);
+      if (index > 0) {
+	return true;
+      }
+      return false;
+    } catch (NumberFormatException ex) {
+      return false;
+    }
+  }
+
+  /**
+   * Main method for testing this class.
+   *
+   * @param argv one parameter: a test range specification
+   */
+  public static void main(String [] argv) {
+
+    try {
+      if (argv.length == 0) {
+	throw new Exception("Usage: Range <rangespec>");
+      }
+      Range range = new Range();
+      range.setRanges(argv[0]);
+      range.setUpper(9);
+      range.setInvert(false);
+      System.out.println("Input: " + argv[0] + "\n"
+			 + range.toString());
+      int [] rangeIndices = range.getSelection();
+      for (int i = 0; i < rangeIndices.length; i++)
+	System.out.print(" " + (rangeIndices[i] + 1));
+      System.out.println("");
+    } catch (Exception ex) {
+      System.out.println(ex.getMessage());
+    }
+  }
+}
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/SerializedObject.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/SerializedObject.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/SerializedObject.java	(revision 20131)
@@ -0,0 +1,249 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    SerializedObject.java
+ *    Copyright (C) 2000 Webmind Inc.
+ *
+ */
+
+package weka.core;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * This class stores an object serialized in memory. It allows compression,
+ * to be used to conserve memory (for example, when storing large strings
+ * in memory), or can be used as a mechanism for deep copying objects.
+ *
+ * @author Len Trigg (len@intelligenesis.net)
+ * @version $Revision$
+ */
+public class SerializedObject implements Serializable {
+
+  /** Stores the serialized object */
+  private byte [] m_Serialized;
+
+  /** True if the object has been compressed during storage */
+  private boolean m_Compressed;
+
+  /**
+   * Serializes the supplied object into a byte array without compression.
+   *
+   * @param obj the Object to serialize.
+   * @exception Exception if the object is not Serializable.
+   */
+  public SerializedObject(Object obj) throws Exception {
+
+    this(obj, false);
+  }
+
+  /**
+   * Serializes the supplied object into a byte array.
+   *
+   * @param obj the Object to serialize.
+   * @param compress true if the object should be stored compressed.
+   * @exception Exception if the object is not Serializable.
+   */
+  public SerializedObject(Object obj, boolean compress) throws Exception {
+
+    //System.err.print("."); System.err.flush();
+    m_Compressed = compress;
+    m_Serialized = toByteArray(obj, m_Compressed);
+  }
+
+  /**
+   * Serializes the supplied object to a byte array.
+   *
+   * @param obj the Object to serialize
+   * @param compress true if the object should be compressed.
+   * @return the byte array containing the serialized object.
+   * @exception Exception if the object is not Serializable.
+   */
+  protected static byte [] toByteArray(Object obj, boolean compress) 
+    throws Exception {
+
+    ByteArrayOutputStream bo = new ByteArrayOutputStream();
+    OutputStream os = bo;
+    if (compress) {
+      os = new GZIPOutputStream(os);
+    }
+    os = new BufferedOutputStream(os);
+    ObjectOutputStream oo = new ObjectOutputStream(os);
+    oo.writeObject(obj);
+    oo.close();
+    return bo.toByteArray();
+  }
+
+  /**
+   * Gets the object stored in this SerializedObject. The object returned
+   * will be a deep copy of the original stored object.
+   *
+   * @return the deserialized Object.
+   */
+  public Object getObject() {
+    try {
+      InputStream is = new ByteArrayInputStream(m_Serialized);
+      if (m_Compressed) {
+        is = new GZIPInputStream(is);
+      }
+      is = new BufferedInputStream(is);
+      ObjectInputStream oi = new ObjectInputStream(is);
+      Object result = oi.readObject();
+      oi.close();
+      return result;
+    } catch (Exception ex) {
+      ex.printStackTrace();
+    }
+    return null;
+  }
+
+  /**
+   * Compares this object with another for equality.
+   *
+   * @param other the other Object.
+   * @return true if the objects are equal.
+   */
+  public final boolean equals(Object other) {
+
+    // Check class type
+    if ((other == null) || !(other.getClass().equals(this.getClass()))) {
+      return false;
+    }
+    // Check serialized length
+    byte [] os = ((SerializedObject)other).m_Serialized;
+    if (os.length != m_Serialized.length) {
+      return false;
+    }
+    // Check serialized contents
+    for (int i = 0; i < m_Serialized.length; i++) {
+      if (m_Serialized[i] != os[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Returns a hashcode for this object.
+   *
+   * @return the hashcode for this object.
+   */
+  public final int hashCode() {
+    
+    return m_Serialized.length;
+  }
+
+  /**
+   * Returns a text representation of the state of this object.
+   *
+   * @return a String representing this object.
+   */
+  public String toString() {
+    
+    return (m_Compressed ? "Compressed object: " : "Uncompressed object: ")
+      + m_Serialized.length + " bytes";
+  }
+
+  /**
+   * Test routine, reads text from stdin and measures memory usage
+   */
+  public static void main2(String []args) {
+
+    try {
+      Runtime r = Runtime.getRuntime();
+      r.gc();
+      java.io.LineNumberReader lnr = new java.io.LineNumberReader(new java.io.InputStreamReader(System.in));
+      StringBuffer sb = new StringBuffer();
+      String line;
+      while ((line = lnr.readLine()) != null) {
+        sb.append(line).append('\n');
+      }
+      String text = sb.toString();
+      //System.err.println("TEXT:");
+      //System.err.println(text);
+      r.gc();
+
+      System.err.print("TOTAL: " + r.totalMemory());
+      System.err.println("\tFREE: " + r.freeMemory());
+      long used = r.totalMemory() - r.freeMemory();
+      
+      // convert to a compressedobject
+      SerializedObject co = new SerializedObject(text, true);
+
+      System.err.print("TOTAL: " + r.totalMemory());
+      System.err.println("\tFREE: " + r.freeMemory());
+      r.gc();
+      long used1 = r.totalMemory() - r.freeMemory();
+      long csize = used1 - used;
+      System.err.println("CompressedSize = " + csize);
+
+      String newstr = (String)co.getObject();
+      r.gc();
+      System.err.print("TOTAL: " + r.totalMemory());
+      System.err.println("\tFREE: " + r.freeMemory());
+      long used2 = r.totalMemory() - r.freeMemory();
+      long usize = used2 - used1;
+      System.err.println("UncompressedSize = " + usize);
+
+      // A couple of references to the original objects
+      // so they don't get freed prematurely and muck up the
+      // measurements.
+      newstr = newstr.toLowerCase();
+      text = text.toLowerCase();
+      System.err.println("Byte array: " + co.toString());
+      System.err.println("Length of text: " + text.length());
+    } catch (Exception ex) {
+      ex.printStackTrace();
+    }
+  }
+
+
+  /**
+   * Test routine, reads an arff file from stdin and measures memory usage
+   * (the arff file should have long string attribute values)
+   */
+  public static void main(String []args) {
+
+    try {
+      Runtime r = Runtime.getRuntime();
+      r.gc();
+      System.err.print("TOTAL: " + r.totalMemory());
+      System.err.println("\tFREE: " + r.freeMemory());
+      long used = r.totalMemory() - r.freeMemory();
+      Instances inst = new Instances(new java.io.BufferedReader(new java.io.InputStreamReader(System.in)));
+      r.gc();
+      long used1 = r.totalMemory() - r.freeMemory();
+      long csize = used1 - used;
+      System.err.print("\nTOTAL: " + r.totalMemory());
+      System.err.println("\tFREE: " + r.freeMemory());
+      System.err.println("size = " + csize);
+      int blah = inst.numAttributes();
+    } catch (Exception ex) {
+      ex.printStackTrace();
+    }
+  }
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/SparseInstance.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/SparseInstance.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/SparseInstance.java	(revision 20131)
@@ -0,0 +1,773 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    SparseInstance.java
+ *    Copyright (C) 2000 Eibe Frank
+ *
+ */
+
+package weka.core;
+
+import java.util.*;
+import java.io.*;
+
+/**
+ * Class for storing an instance as a sparse vector. A sparse instance
+ * only requires storage for those attribute values that are non-zero.
+ * Since the objective is to reduce storage requirements for datasets
+ * with large numbers of default values, this also includes nominal
+ * attributes -- the first nominal value (i.e. that which has index 0)
+ * will not require explicit storage, so rearrange your nominal attribute
+ * value orderings if necessary. Missing values will be stored
+ * explicitly.
+ */
+public class SparseInstance extends Instance {
+
+  /** The index of the attribute associated with each stored value. */
+  protected int[] m_Indices;
+
+  /** The maximum number of values that can be stored. */
+  protected int m_NumAttributes;
+
+  protected SparseInstance() {
+
+  }
+
+  /**
+   * Constructor that generates a sparse instance from the given
+   * instance. Reference to the dataset is set to null.
+   * (ie. the instance doesn't have access to information about the
+   * attribute types)
+   *
+   * @param instance the instance from which the attribute values
+   * and the weight are to be copied
+   */
+  public SparseInstance(Instance instance) {
+    
+    m_Weight = instance.m_Weight;
+    m_Dataset = null;
+    m_NumAttributes = instance.numAttributes();
+    if (instance instanceof SparseInstance) {
+      m_AttValues = ((SparseInstance)instance).m_AttValues;
+      m_Indices = ((SparseInstance)instance).m_Indices;
+    } else {
+      double[] tempValues = new double[instance.numAttributes()];
+      int[] tempIndices = new int[instance.numAttributes()];
+      int vals = 0;
+      for (int i = 0; i < instance.numAttributes(); i++) {
+	if (instance.value(i) != 0) {
+	  tempValues[vals] = instance.value(i);
+	  tempIndices[vals] = i;
+	  vals++;
+	}
+      }
+      m_AttValues = new double[vals];
+      m_Indices = new int[vals];
+      System.arraycopy(tempValues, 0, m_AttValues, 0, vals);
+      System.arraycopy(tempIndices, 0, m_Indices, 0, vals);
+    }
+  }
+
+  /**
+   * Constructor that copies the info from the given instance. 
+   * Reference to the dataset is set to null.
+   * (ie. the instance doesn't have access to information about the
+   * attribute types)
+   *
+   * @param instance the instance from which the attribute
+   * info is to be copied 
+   */
+  public SparseInstance(SparseInstance instance) {
+    
+    m_AttValues = instance.m_AttValues;
+    m_Indices = instance.m_Indices;
+    m_Weight = instance.m_Weight;
+    m_NumAttributes = instance.m_NumAttributes;
+    m_Dataset = null;
+  }
+
+  /**
+   * Constructor that generates a sparse instance from the given
+   * parameters. Reference to the dataset is set to null.
+   * (ie. the instance doesn't have access to information about the
+   * attribute types)
+   *
+   * @param weight the instance's weight
+   * @param attValues a vector of attribute values 
+   */
+  public SparseInstance(double weight, double[] attValues) {
+    
+    m_Weight = weight;
+    m_Dataset = null;
+    m_NumAttributes = attValues.length;
+    double[] tempValues = new double[m_NumAttributes];
+    int[] tempIndices = new int[m_NumAttributes];
+    int vals = 0;
+    for (int i = 0; i < m_NumAttributes; i++) {
+      if (attValues[i] != 0) {
+	tempValues[vals] = attValues[i];
+	tempIndices[vals] = i;
+	vals++;
+      }
+    }
+    m_AttValues = new double[vals];
+    m_Indices = new int[vals];
+    System.arraycopy(tempValues, 0, m_AttValues, 0, vals);
+    System.arraycopy(tempIndices, 0, m_Indices, 0, vals);
+  }
+  
+  /**
+   * Constructor that inititalizes instance variable with given
+   * values. Reference to the dataset is set to null. (ie. the instance
+   * doesn't have access to information about the attribute types)
+   *
+   * @param weight the instance's weight
+   * @param attValues a vector of attribute values (just the ones to be stored)
+   * @param indices the indices of the given values in the full vector
+   * @param maxNumValues the maximium number of values that can be stored
+   */
+  public SparseInstance(double weight, double[] attValues,
+			int[] indices, int maxNumValues){
+    
+    int vals = 0; 
+    m_AttValues = new double [attValues.length];
+    m_Indices = new int [indices.length];
+    for (int i = 0; i < attValues.length; i++) {
+      if (attValues[i] != 0) {
+        m_AttValues[vals] = attValues[i];
+        m_Indices[vals] = indices[i];
+        vals++;
+      }
+    }
+    if (vals != attValues.length) {
+      // Need to truncate.
+      double [] newVals = new double[vals];
+      System.arraycopy(m_AttValues, 0, newVals, 0, vals);
+      m_AttValues = newVals;
+      int [] newIndices = new int[vals];
+      System.arraycopy(m_Indices, 0, newIndices, 0, vals);
+      m_Indices = newIndices;
+    }
+    m_Weight = weight;
+    m_NumAttributes = maxNumValues;
+    m_Dataset = null;
+  }
+
+  /**
+   * Constructor of an instance that sets weight to one, all values to
+   * be missing, and the reference to the dataset to null. (ie. the instance
+   * doesn't have access to information about the attribute types)
+   *
+   * @param numAttributes the size of the instance 
+   */
+  public SparseInstance(int numAttributes) {
+    
+    m_AttValues = new double[numAttributes];
+    m_NumAttributes = numAttributes;
+    m_Indices = new int[numAttributes];
+    for (int i = 0; i < m_AttValues.length; i++) {
+      m_AttValues[i] = MISSING_VALUE;
+      m_Indices[i] = i;
+    }
+    m_Weight = 1;
+    m_Dataset = null;
+  }
+
+  /**
+   * Returns the attribute associated with the internal index. 
+   *
+   * @param indexOfIndex the index of the attribute's index 
+   * @return the attribute at the given position
+   * @exception UnassignedDatasetException if instance doesn't have access to a
+   * dataset
+   */ 
+  public Attribute attributeSparse(int indexOfIndex) {
+   
+    if (m_Dataset == null) {
+      throw new UnassignedDatasetException("Instance doesn't have access to a dataset!");
+    }
+    return m_Dataset.attribute(m_Indices[indexOfIndex]);
+  }
+
+  /**
+   * Produces a shallow copy of this instance. The copy has
+   * access to the same dataset. (if you want to make a copy
+   * that doesn't have access to the dataset, use 
+   * <code>new SparseInstance(instance)</code>
+   *
+   * @return the shallow copy
+   */
+  public Object copy() {
+
+    Instance result = new SparseInstance(this);
+    result.m_Dataset = m_Dataset;
+    return result;
+  }
+
+  /**
+   * Returns the index of the attribute stored at the given position.
+   *
+   * @param position the position 
+   * @return the index of the attribute stored at the given position
+   */
+  public int index(int position) {
+
+    return m_Indices[position];
+  }
+
+  /**
+   * Tests if a specific value is "missing".
+   *
+   * @param attIndex the attribute's index
+   */
+  public boolean isMissing(int attIndex) {
+
+    if (Double.isNaN(value(attIndex))) {
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Locates the greatest index that is not greater than the
+   * given index.
+   *
+   * @return the internal index of the attribute index. Returns
+   * -1 if no index with this property couldn't be found
+   */
+  public int locateIndex(int index) {
+
+    int min = 0, max = m_Indices.length - 1;
+
+    // Binary search
+    while (max >= min) {
+      int current = (max + min) / 2;
+      if (m_Indices[current] > index) {
+	max = current - 1;
+      } else if (m_Indices[current] < index) {
+	min = current + 1;
+      } else {
+	return current;
+      }
+    }
+    return max;
+  }
+
+  /**
+   * Merges this instance with the given instance and returns
+   * the result. Dataset is set to null.
+   *
+   * @param inst the instance to be merged with this one
+   * @return the merged instances
+   */
+  public Instance mergeInstance(Instance inst) {
+
+    double[] values = new double[numValues() + inst.numValues()];
+    int[] indices = new int[numValues() + inst.numValues()];
+
+    int m = 0;
+    for (int j = 0; j < numValues(); j++, m++) {
+      values[m] = valueSparse(j);
+      indices[m] = index(j);
+    }
+    for (int j = 0; j < inst.numValues(); j++, m++) {
+      values[m] = inst.valueSparse(j);
+      indices[m] = inst.index(j) + inst.numAttributes();
+    }
+    
+    return new SparseInstance(1.0, values, indices, numAttributes() +
+			      inst.numAttributes());
+  }
+
+  /**
+   * Returns the number of attributes.
+   *
+   * @return the number of attributes as an integer
+   */
+  public int numAttributes() {
+
+    return m_NumAttributes;
+  }
+
+  /**
+   * Returns the number of values in the sparse vector.
+   *
+   * @return the number of values
+   */
+  public int numValues() {
+
+    return m_Indices.length;
+  }
+
+  /** 
+   * Replaces all missing values in the instance with the 
+   * values contained in the given array. A deep copy of
+   * the vector of attribute values is performed before the
+   * values are replaced.
+   *
+   * @param array containing the means and modes
+   * @exception IllegalArgumentException if numbers of attributes are unequal
+   */
+  public void replaceMissingValues(double[] array) {
+	 
+    if ((array == null) || (array.length != m_NumAttributes)) {
+      throw new IllegalArgumentException("Unequal number of attributes!");
+    }
+    double[] tempValues = new double[m_AttValues.length];
+    int[] tempIndices = new int[m_AttValues.length];
+    int vals = 0;
+    for (int i = 0; i < m_AttValues.length; i++) {
+      if (isMissingValue(m_AttValues[i])) {
+	if (array[m_Indices[i]] != 0) {
+	  tempValues[vals] = array[m_Indices[i]];
+	  tempIndices[vals] = m_Indices[i];
+	  vals++;
+	} 
+      } else {
+	tempValues[vals] = m_AttValues[i];
+	tempIndices[vals] = m_Indices[i];
+	vals++;
+      }
+    }
+    m_AttValues = new double[vals];
+    m_Indices = new int[vals];
+    System.arraycopy(tempValues, 0, m_AttValues, 0, vals);
+    System.arraycopy(tempIndices, 0, m_Indices, 0, vals);
+  }
+
+  /**
+   * Sets a specific value in the instance to the given value 
+   * (internal floating-point format). Performs a deep copy
+   * of the vector of attribute values before the value is set.
+   *
+   * @param attIndex the attribute's index 
+   * @param value the new attribute value (If the corresponding
+   * attribute is nominal (or a string) then this is the new value's
+   * index as a double).  
+   */
+  public void setValue(int attIndex, double value) {
+
+    int index = locateIndex(attIndex);
+    
+    if ((index >= 0) && (m_Indices[index] == attIndex)) {
+      if (value != 0) {
+	double[] tempValues = new double[m_AttValues.length];
+	System.arraycopy(m_AttValues, 0, tempValues, 0, m_AttValues.length);
+	tempValues[index] = value;
+	m_AttValues = tempValues;
+      } else {
+	double[] tempValues = new double[m_AttValues.length - 1];
+	int[] tempIndices = new int[m_Indices.length - 1];
+	System.arraycopy(m_AttValues, 0, tempValues, 0, index);
+	System.arraycopy(m_Indices, 0, tempIndices, 0, index);
+	System.arraycopy(m_AttValues, index + 1, tempValues, index, 
+			 m_AttValues.length - index - 1);
+	System.arraycopy(m_Indices, index + 1, tempIndices, index, 
+			 m_Indices.length - index - 1);
+	m_AttValues = tempValues;
+	m_Indices = tempIndices;
+      }
+    } else {
+      if (value != 0) {
+	double[] tempValues = new double[m_AttValues.length + 1];
+	int[] tempIndices = new int[m_Indices.length + 1];
+	System.arraycopy(m_AttValues, 0, tempValues, 0, index + 1);
+	System.arraycopy(m_Indices, 0, tempIndices, 0, index + 1);
+	tempIndices[index + 1] = attIndex;
+	tempValues[index + 1] = value;
+	System.arraycopy(m_AttValues, index + 1, tempValues, index + 2, 
+			 m_AttValues.length - index - 1);
+	System.arraycopy(m_Indices, index + 1, tempIndices, index + 2, 
+			 m_Indices.length - index - 1);
+	m_AttValues = tempValues;
+	m_Indices = tempIndices;
+      }
+    }
+  }
+
+  /**
+   * Sets a specific value in the instance to the given value 
+   * (internal floating-point format). Performs a deep copy
+   * of the vector of attribute values before the value is set.
+   *
+   * @param indexOfIndex the index of the attribute's index 
+   * @param value the new attribute value (If the corresponding
+   * attribute is nominal (or a string) then this is the new value's
+   * index as a double).  
+   */
+  public void setValueSparse(int indexOfIndex, double value) {
+
+    if (value != 0) {
+      double[] tempValues = new double[m_AttValues.length];
+      System.arraycopy(m_AttValues, 0, tempValues, 0, m_AttValues.length);
+      m_AttValues = tempValues;
+      m_AttValues[indexOfIndex] = value;
+    } else {
+      double[] tempValues = new double[m_AttValues.length - 1];
+      int[] tempIndices = new int[m_Indices.length - 1];
+      System.arraycopy(m_AttValues, 0, tempValues, 0, indexOfIndex);
+      System.arraycopy(m_Indices, 0, tempIndices, 0, indexOfIndex);
+      System.arraycopy(m_AttValues, indexOfIndex + 1, tempValues, indexOfIndex, 
+		       m_AttValues.length - indexOfIndex - 1);
+      System.arraycopy(m_Indices, indexOfIndex + 1, tempIndices, indexOfIndex, 
+		       m_Indices.length - indexOfIndex - 1);
+      m_AttValues = tempValues;
+      m_Indices = tempIndices;
+    }
+  }
+
+  /**
+   * Returns the values of each attribute as an array of doubles.
+   *
+   * @return an array containing all the instance attribute values
+   */
+  public double[] toDoubleArray() {
+
+    double[] newValues = new double[m_NumAttributes];
+    for (int i = 0; i < m_AttValues.length; i++) {
+      newValues[m_Indices[i]] = m_AttValues[i];
+    }
+    return newValues;
+  }
+
+  /**
+   * Returns the description of one instance in sparse format. 
+   * If the instance doesn't have access to a dataset, it returns the 
+   * internal floating-point values. Quotes string values that contain 
+   * whitespace characters.
+   *
+   * @return the instance's description as a string
+   */
+  public String toString() {
+
+    StringBuffer text = new StringBuffer();
+    
+    text.append('{');
+    for (int i = 0; i < m_Indices.length; i++) {
+      if (i > 0) text.append(",");
+      if (isMissingValue(m_AttValues[i])) {
+	text.append(m_Indices[i] + " ?");
+      } else {
+	if (m_Dataset == null) {
+	  text.append(m_Indices[i] + " " + 
+		      Utils.doubleToString(m_AttValues[i],6));
+	} else {
+	  if (m_Dataset.attribute(m_Indices[i]).isNominal() || 
+	      m_Dataset.attribute(m_Indices[i]).isString()) {
+	    try {
+	      text.append(m_Indices[i] + " " +
+			  Utils.quote(m_Dataset.attribute(m_Indices[i]).
+				      value((int)valueSparse(i))));
+	    } catch (Exception e) {
+              e.printStackTrace();
+              System.err.println(new Instances(m_Dataset, 0));
+              System.err.println("Att:" + m_Indices[i] + " Val:" + valueSparse(i));
+	      throw new Error("This should never happen!");
+	    }
+	  } else {
+	    text.append(m_Indices[i] + " " +
+			Utils.doubleToString(m_AttValues[i],6));
+	  }
+	}
+      }
+    }
+    text.append('}');
+    return text.toString();
+  }
+
+  /**
+   * Returns an instance's attribute value in internal format.
+   *
+   * @param attIndex the attribute's index
+   * @return the specified value as a double (If the corresponding
+   * attribute is nominal (or a string) then it returns the value's index as a 
+   * double).
+   */
+  public double value(int attIndex) {
+
+    int index = locateIndex(attIndex);
+    if ((index >= 0) && (m_Indices[index] == attIndex)) {
+      return m_AttValues[index];
+    } else {
+      return 0.0;
+    }
+  }  
+
+  /**
+   * Deletes an attribute at the given position (0 to 
+   * numAttributes() - 1).
+   *
+   * @param pos the attribute's position
+   */
+  void forceDeleteAttributeAt(int position) {
+
+    int index = locateIndex(position);
+
+    m_NumAttributes--;
+    if ((index >= 0) && (m_Indices[index] == position)) {
+      int[] tempIndices = new int[m_Indices.length - 1];
+      double[] tempValues = new double[m_AttValues.length - 1];
+      System.arraycopy(m_Indices, 0, tempIndices, 0, index);
+      System.arraycopy(m_AttValues, 0, tempValues, 0, index);
+      for (int i = index; i < m_Indices.length - 1; i++) {
+	tempIndices[i] = m_Indices[i + 1] - 1;
+	tempValues[i] = m_AttValues[i + 1];
+      }
+      m_Indices = tempIndices;
+      m_AttValues = tempValues;
+    } else {
+      int[] tempIndices = new int[m_Indices.length];
+      double[] tempValues = new double[m_AttValues.length];
+      System.arraycopy(m_Indices, 0, tempIndices, 0, index + 1);
+      System.arraycopy(m_AttValues, 0, tempValues, 0, index + 1);
+      for (int i = index + 1; i < m_Indices.length - 1; i++) {
+	tempIndices[i] = m_Indices[i] - 1;
+	tempValues[i] = m_AttValues[i];
+      }
+      m_Indices = tempIndices;
+      m_AttValues = tempValues;
+    }
+  }
+
+  /**
+   * Inserts an attribute at the given position
+   * (0 to numAttributes()) and sets its value to be missing. 
+   *
+   * @param pos the attribute's position
+   */
+  void forceInsertAttributeAt(int position)  {
+
+    int index = locateIndex(position);
+
+    m_NumAttributes++;
+    if ((index >= 0) && (m_Indices[index] == position)) {
+      int[] tempIndices = new int[m_Indices.length + 1];
+      double[] tempValues = new double[m_AttValues.length + 1];
+      System.arraycopy(m_Indices, 0, tempIndices, 0, index);
+      System.arraycopy(m_AttValues, 0, tempValues, 0, index);
+      tempIndices[index] = position;
+      tempValues[index] = MISSING_VALUE;
+      for (int i = index; i < m_Indices.length; i++) {
+	tempIndices[i + 1] = m_Indices[i] + 1;
+	tempValues[i + 1] = m_AttValues[i];
+      }
+      m_Indices = tempIndices;
+      m_AttValues = tempValues;
+    } else {
+      int[] tempIndices = new int[m_Indices.length + 1];
+      double[] tempValues = new double[m_AttValues.length + 1];
+      System.arraycopy(m_Indices, 0, tempIndices, 0, index + 1);
+      System.arraycopy(m_AttValues, 0, tempValues, 0, index + 1);
+      tempIndices[index + 1] = position;
+      tempValues[index + 1] = MISSING_VALUE;
+      for (int i = index + 1; i < m_Indices.length; i++) {
+	tempIndices[i + 1] = m_Indices[i] + 1;
+	tempValues[i + 1] = m_AttValues[i];
+      }
+      m_Indices = tempIndices;
+      m_AttValues = tempValues;
+    }
+  }
+
+  /**
+   * Main method for testing this class.
+   */
+  public static void main(String[] options) {
+
+    try {
+
+      // Create numeric attributes "length" and "weight"
+      Attribute length = new Attribute("length");
+      Attribute weight = new Attribute("weight");
+      
+      // Create vector to hold nominal values "first", "second", "third" 
+      FastVector my_nominal_values = new FastVector(3); 
+      my_nominal_values.addElement("first"); 
+      my_nominal_values.addElement("second"); 
+      my_nominal_values.addElement("third"); 
+      
+      // Create nominal attribute "position" 
+      Attribute position = new Attribute("position", my_nominal_values);
+      
+      // Create vector of the above attributes 
+      FastVector attributes = new FastVector(3);
+      attributes.addElement(length);
+      attributes.addElement(weight);
+      attributes.addElement(position);
+      
+      // Create the empty dataset "race" with above attributes
+      Instances race = new Instances("race", attributes, 0);
+      
+      // Make position the class attribute
+      race.setClassIndex(position.index());
+      
+      // Create empty instance with three attribute values
+      SparseInstance inst = new SparseInstance(3);
+      
+      // Set instance's values for the attributes "length", "weight", and "position"
+      inst.setValue(length, 5.3);
+      inst.setValue(weight, 300);
+      inst.setValue(position, "first");
+      
+      // Set instance's dataset to be the dataset "race"
+      inst.setDataset(race);
+      
+      // Print the instance
+      System.out.println("The instance: " + inst);
+      
+      // Print the first attribute
+      System.out.println("First attribute: " + inst.attribute(0));
+      
+      // Print the class attribute
+      System.out.println("Class attribute: " + inst.classAttribute());
+      
+      // Print the class index
+      System.out.println("Class index: " + inst.classIndex());
+      
+      // Say if class is missing
+      System.out.println("Class is missing: " + inst.classIsMissing());
+      
+      // Print the instance's class value in internal format
+      System.out.println("Class value (internal format): " + inst.classValue());
+      
+      // Print a shallow copy of this instance
+      SparseInstance copy = (SparseInstance) inst.copy();
+      System.out.println("Shallow copy: " + copy);
+      
+      // Set dataset for shallow copy
+      copy.setDataset(inst.dataset());
+      System.out.println("Shallow copy with dataset set: " + copy);
+
+      // Print out all values in internal format
+      System.out.print("All stored values in internal format: ");
+      for (int i = 0; i < inst.numValues(); i++) {
+	if (i > 0) {
+	  System.out.print(",");
+	}
+	System.out.print(inst.valueSparse(i));
+      }
+      System.out.println();
+
+      // Set all values to zero
+      System.out.print("All values set to zero: ");
+      while (inst.numValues() > 0) {
+	inst.setValueSparse(0, 0);
+      }
+      for (int i = 0; i < inst.numValues(); i++) {
+	if (i > 0) {
+	  System.out.print(",");
+	}
+	System.out.print(inst.valueSparse(i));
+      }
+      System.out.println();
+
+      // Set all values to one
+      System.out.print("All values set to one: ");
+      for (int i = 0; i < inst.numAttributes(); i++) {
+	inst.setValue(i, 1);
+      }
+      for (int i = 0; i < inst.numValues(); i++) {
+	if (i > 0) {
+	  System.out.print(",");
+	}
+	System.out.print(inst.valueSparse(i));
+      }
+      System.out.println();
+
+      // Unset dataset for copy, delete first attribute, and insert it again
+      copy.setDataset(null);
+      copy.deleteAttributeAt(0);
+      copy.insertAttributeAt(0);
+      copy.setDataset(inst.dataset());
+      System.out.println("Copy with first attribute deleted and inserted: " + copy); 
+
+      // Same for second attribute
+      copy.setDataset(null);
+      copy.deleteAttributeAt(1);
+      copy.insertAttributeAt(1);
+      copy.setDataset(inst.dataset());
+      System.out.println("Copy with second attribute deleted and inserted: " + copy); 
+
+      // Same for last attribute
+      copy.setDataset(null);
+      copy.deleteAttributeAt(2);
+      copy.insertAttributeAt(2);
+      copy.setDataset(inst.dataset());
+      System.out.println("Copy with third attribute deleted and inserted: " + copy); 
+      
+      // Enumerate attributes (leaving out the class attribute)
+      System.out.println("Enumerating attributes (leaving out class):");
+      Enumeration enum = inst.enumerateAttributes();
+      while (enum.hasMoreElements()) {
+	Attribute att = (Attribute) enum.nextElement();
+	System.out.println(att);
+      }
+      
+      // Headers are equivalent?
+      System.out.println("Header of original and copy equivalent: " +
+			 inst.equalHeaders(copy));
+
+      // Test for missing values
+      System.out.println("Length of copy missing: " + copy.isMissing(length));
+      System.out.println("Weight of copy missing: " + copy.isMissing(weight.index()));
+      System.out.println("Length of copy missing: " + 
+			 Instance.isMissingValue(copy.value(length)));
+      System.out.println("Missing value coded as: " + Instance.missingValue());
+
+      // Prints number of attributes and classes
+      System.out.println("Number of attributes: " + copy.numAttributes());
+      System.out.println("Number of classes: " + copy.numClasses());
+
+      // Replace missing values
+      double[] meansAndModes = {2, 3, 0};
+      copy.replaceMissingValues(meansAndModes);
+      System.out.println("Copy with missing value replaced: " + copy);
+
+      // Setting and getting values and weights
+      copy.setClassMissing();
+      System.out.println("Copy with missing class: " + copy);
+      copy.setClassValue(0);
+      System.out.println("Copy with class value set to first value: " + copy);
+      copy.setClassValue("third");
+      System.out.println("Copy with class value set to \"third\": " + copy);
+      copy.setMissing(1);
+      System.out.println("Copy with second attribute set to be missing: " + copy);
+      copy.setMissing(length);
+      System.out.println("Copy with length set to be missing: " + copy);
+      copy.setValue(0, 0);
+      System.out.println("Copy with first attribute set to 0: " + copy);
+      copy.setValue(weight, 1);
+      System.out.println("Copy with weight attribute set to 1: " + copy);
+      copy.setValue(position, "second");
+      System.out.println("Copy with position set to \"second\": " + copy);
+      copy.setValue(2, "first");
+      System.out.println("Copy with last attribute set to \"first\": " + copy);
+      System.out.println("Current weight of instance copy: " + copy.weight());
+      copy.setWeight(2);
+      System.out.println("Current weight of instance copy (set to 2): " + copy.weight());
+      System.out.println("Last value of copy: " + copy.toString(2));
+      System.out.println("Value of position for copy: " + copy.toString(position));
+      System.out.println("Last value of copy (internal format): " + copy.value(2));
+      System.out.println("Value of position for copy (internal format): " + 
+			 copy.value(position));
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+}
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/SpecialFunctions.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/SpecialFunctions.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/SpecialFunctions.java	(revision 20131)
@@ -0,0 +1,127 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    SpecialFunctions.java
+ *    Copyright (C) 1999 Eibe Frank
+ *
+ */
+
+package weka.core;
+
+import java.lang.Math;
+
+/**
+ * Class implementing some mathematical functions.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public final class SpecialFunctions {
+
+  /** Some constants */
+  private static double log2 = Math.log(2);
+  private static double[] cofLogGamma = {76.18009172947146,-86.50532032941677,
+					 24.01409824083091,-1.231739572450155,
+					 0.1208650973866179e-2,-0.5395239384953e-5};
+
+  /**
+   * Returns natural logarithm of factorial using gamma function.
+   *
+   * @param x the value
+   * @return natural logarithm of factorial
+   */
+  public static double lnFactorial(double x){
+
+    return lnGamma(x+1);
+  }
+
+  /**
+   * Returns natural logarithm of gamma function. Converted to java
+   * from Numerical Recipes in C.
+   *
+   * @param x the value
+   * @return natural logarithm of gamma function
+   */
+  public static double lnGamma(double x){
+    
+    double y,tmp,ser;
+    int j;
+    
+    y=x;
+    tmp=x+5.5;
+    tmp -= (x+0.5)*Math.log(tmp);
+    ser=1.000000000190015;
+    for (j=0;j<=5;j++) {
+      ser += cofLogGamma[j]/++y;
+    }
+    return -tmp+Math.log(2.5066282746310005*ser/x);
+  }
+
+  /**
+   * Returns base 2 logarithm of binomial coefficient using gamma function.
+   *
+   * @param a upper part of binomial coefficient
+   * @param b lower part
+   * @return the base 2 logarithm of the binominal coefficient a over b
+   */
+  public static double log2Binomial(double a, double b) throws ArithmeticException{
+    
+    if (Utils.gr(b,a)) {
+      throw new ArithmeticException("Can't compute binomial coefficient.");
+    }
+    return (lnFactorial(a)-lnFactorial(b)-lnFactorial(a-b))/log2;
+  }
+
+  /**
+   * Returns base 2 logarithm of multinomial using gamma function.
+   *
+   * @param a upper part of multinomial coefficient
+   * @param bs lower part
+   * @return multinomial coefficient of a over the bs
+   */
+  public static double log2Multinomial(double a, double[] bs)
+       throws ArithmeticException{
+    
+    double sum = 0;
+    int i;
+    
+    for (i=0;i<bs.length;i++) {
+      if (Utils.gr(bs[i],a)) {
+	throw 
+	  new ArithmeticException("Can't compute multinomial coefficient.");
+      } else {
+	sum = sum+lnFactorial(bs[i]);
+      }
+    }
+    return (lnFactorial(a)-sum)/log2;
+  }
+
+  /**
+   * Main method for testing this class.
+   */
+  public static void main(String[] ops) {
+
+    double[] doubles = {1, 2, 3};
+
+    System.out.println("6!: " + Math.exp(SpecialFunctions.lnFactorial(6)));
+    System.out.println("lnGamma(6): "+ SpecialFunctions.lnGamma(6));
+    System.out.println("Binomial 6 over 2: " +
+		       Math.pow(2, SpecialFunctions.log2Binomial(6, 2)));
+    System.out.println("Multinomial 6 over 1, 2, 3: " +
+		       Math.pow(2, SpecialFunctions.log2Multinomial(6, doubles)));
+  }    
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Statistics.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Statistics.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Statistics.java	(revision 20131)
@@ -0,0 +1,280 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    Statistics.java
+ *    Copyright (C) 1999 Eibe Frank
+ *
+ */
+
+package weka.core;
+
+/**
+ * Class implementing some distributions, tests, etc. Most of the
+ * code is adapted from Gary Perlman's unixstat.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public class Statistics {
+
+  /** Some constants */
+  private static double logSqrtPi = Math.log(Math.sqrt(Math.PI));
+  private static double rezSqrtPi = 1/Math.sqrt(Math.PI);
+  private static double bigx = 20.0;
+
+  /**
+   * Computes standard error for observed values of a binomial
+   * random variable.
+   *
+   * @param p the probability of success
+   * @param n the size of the sample
+   * @return the standard error
+   */
+  public static double binomialStandardError(double p, int n) {
+
+    if (n == 0) {
+      return 0; 
+    }
+    return Math.sqrt((p*(1-p))/(double) n);
+  }
+
+  /**
+   * Returns chi-squared probability for given value and degrees
+   * of freedom. (The probability that the chi-squared variate
+   * will be greater than x for the given degrees of freedom.)
+   * Adapted from unixstat by Gary Perlman.
+   *
+   * @param x the value
+   * @param df the number of degrees of freedom
+   */
+  public static double chiSquaredProbability(double x, int df) {
+
+    double a, y = 0, s, e, c, z, val;
+    boolean even;
+   
+    if (x <= 0 || df < 1)
+      return (1);
+    a = 0.5 * x;
+    even = (((int)(2*(df/2))) == df);
+    if (df > 1)
+      y = Math.exp(-a); //((-a < -bigx) ? 0.0 : Math.exp (-a));
+    s = (even ? y : (2.0 * normalProbability(-Math.sqrt (x))));
+    if (df > 2){
+      x = 0.5 * (df - 1.0);
+      z = (even ? 1.0 : 0.5);
+      if (a > bigx){
+	e = (even ? 0.0 : logSqrtPi);
+	c = Math.log (a);
+	while (z <= x){
+	  e = Math.log (z) + e;
+	  val = c*z-a-e;
+	  s += Math.exp (val); //((val < -bigx) ? 0.0 : Math.exp (val));
+	  z += 1.0;
+	}
+	return (s);
+      }else{
+	e = (even ? 1.0 : (rezSqrtPi / Math.sqrt (a)));
+	c = 0.0;
+	while (z <= x){
+	  e = e * (a / z);
+	  c = c + e;
+	  z += 1.0;
+	}
+	return (c * y + s);
+      }
+    }else{
+      return (s);
+    }
+  }
+
+  /**
+   * Critical value for given probability of F-distribution.
+   * Adapted from unixstat by Gary Perlman.
+   *
+   * @param p the probability
+   * @param df1 the first number of degrees of freedom
+   * @param df2 the second number of degrees of freedom
+   * @return the critical value for the given probability
+   */
+  public static double FCriticalValue(double p, int df1, int df2) {
+
+    double  fval;
+    double  maxf = 99999.0;     /* maximum possible F ratio */
+    double  minf = .000001;     /* minimum possible F ratio */
+    
+    if (p <= 0.0 || p >= 1.0)
+      return (0.0);
+    
+    fval = 1.0 / p; /* the smaller the p, the larger the F */
+    
+    while (Math.abs (maxf - minf) > .000001) {
+      if (FProbability(fval, df1, df2) < p) /* F too large */
+	maxf = fval;
+      else /* F too small */
+	minf = fval;
+      fval = (maxf + minf) * 0.5;
+    }
+    
+    return (fval);
+  }
+
+  /**
+   * Computes probability of F-ratio.
+   * Adapted from unixstat by Gary Perlman.
+   * Collected Algorithms of the CACM 
+   * Algorithm 322
+   * Egon Dorrer
+   *
+   * @param F the F-ratio
+   * @param df1 the first number of degrees of freedom
+   * @param df2 the second number of degrees of freedom
+   * @return the probability of the F-ratio.
+   */
+  public static double FProbability(double F, int df1, int df2) {
+
+    int     i, j;
+    int     a, b;
+    double  w, y, z, d, p;
+
+    if ((Math.abs(F) < 10e-10) || df1 <= 0 || df2 <= 0)
+      return (1.0);
+    a = (df1%2 == 1) ? 1 : 2;
+    b = (df2%2 == 1) ? 1 : 2;
+    w = (F * df1) / df2;
+    z = 1.0 / (1.0 + w);
+    if (a == 1)
+      if (b == 1) {
+	p = Math.sqrt (w);
+	y = 1/Math.PI; /* 1 / 3.14159 */
+	d = y * z / p;
+	p = 2.0 * y * Math.atan (p);
+      } else {
+	p = Math.sqrt (w * z);
+	d = 0.5 * p * z / w;
+      } else if (b == 1) {
+	p = Math.sqrt (z);
+	d = 0.5 * z * p;
+	p = 1.0 - p;
+      } else {
+	d = z * z;
+	p = w * z;
+      }
+    y = 2.0 * w / z;
+    for (j = b + 2; j <= df2; j += 2) {
+      d *= (1.0 + a / (j - 2.0)) * z;
+      p = (a == 1 ? p + d * y / (j - 1.0) : (p + w) * z);
+    }
+    y = w * z;
+    z = 2.0 / z;
+    b = df2 - 2;
+    for (i = a + 2; i <= df1; i += 2) {
+      j = i + b;
+      d *= y * j / (i - 2.0);
+      p -= z * d / j;
+    }
+    
+    // correction for approximation errors suggested in certification
+    if (p < 0.0)
+      p = 0.0;
+    else if (p > 1.0)
+      p = 1.0;
+    return (1.0-p);
+  }
+  
+  /**
+   * Returns probability that the standardized normal variate Z (mean = 0, standard
+   * deviation = 1) is less than z.
+   * Adapted from unixstat by Gary Perlman.
+   *
+   * @param the z-value
+   * @return the probability of the z value according to the normal pdf
+   */
+  public static double normalProbability(double z) {
+
+    double  y, x, w;
+    
+    if (z == 0.0)
+      x = 0.0;
+    else{
+      y = 0.5 * Math.abs (z);
+      if (y >= 3.0)
+	x = 1.0;
+      else if (y < 1.0){
+	w = y*y;
+	x = ((((((((0.000124818987 * w
+                   -0.001075204047) * w +0.005198775019) * w
+                   -0.019198292004) * w +0.059054035642) * w
+                   -0.151968751364) * w +0.319152932694) * w
+                   -0.531923007300) * w +0.797884560593) * y * 2.0;
+      }else{
+	y -= 2.0;
+	x = (((((((((((((-0.000045255659 * y
+                         +0.000152529290) * y -0.000019538132) * y
+                         -0.000676904986) * y +0.001390604284) * y
+                         -0.000794620820) * y -0.002034254874) * y
+                         +0.006549791214) * y -0.010557625006) * y
+                         +0.011630447319) * y -0.009279453341) * y
+                         +0.005353579108) * y -0.002141268741) * y
+                         +0.000535310849) * y +0.999936657524;
+      }
+    }
+  
+    return (z > 0.0 ? ((x + 1.0) / 2.0) : ((1.0 - x) / 2.0));
+  }
+
+  /**
+   * Computes absolute size of half of a student-t confidence interval 
+   * for given degrees of freedom, probability, and observed value.
+   *
+   * @param df the number of degrees of freedom
+   * @param p the probability
+   * @param se the observed value
+   * @return absolute size of half of a student-t confidence interval
+   */
+  public static double studentTConfidenceInterval(int df, double p,
+						  double se) {
+
+    return Math.sqrt(FCriticalValue(p, 1, df))*se;
+  }
+
+  /**
+   * Main method for testing this class.
+   */
+  public static void main(String[] ops) {
+
+    System.out.println("Binomial standard error (0.5, 100): " + 
+		       Statistics.binomialStandardError(0.5, 100));
+    System.out.println("Chi-squared probability (2.558, 10): " +
+		       Statistics.chiSquaredProbability(2.558, 10));
+    System.out.println("Normal probability (0.2): " +
+		       Statistics.normalProbability(0.2));
+    System.out.println("F critical value (0.05, 4, 5): " +
+		       Statistics.FCriticalValue(0.05, 4, 5));
+    System.out.println("F probability (5.1922, 4, 5): " +
+		       Statistics.FProbability(5.1922, 4, 5));
+    System.out.println("Student-t confidence interval (9, 0.01, 2): " +
+		       Statistics.studentTConfidenceInterval(9, 0.01, 2));
+  }
+}
+
+
+
+
+
+
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/UnassignedClassException.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/UnassignedClassException.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/UnassignedClassException.java	(revision 20131)
@@ -0,0 +1,52 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    UnassignedClassException.java
+ *    Copyright (C) 2001 Webmind Corp.
+ */
+
+package weka.core;
+
+/**
+ * <code>UnassignedClassException</code> is used when
+ * a method requires access to the Attribute designated as 
+ * the class attribute in a set of Instances, but the Instances does not
+ * have any class attribute assigned (such as by setClassIndex()).
+ *
+ * @author <a href="mailto:len@webmind.com">Len Trigg</a>
+ * @version $Revision$
+ */
+public class UnassignedClassException extends RuntimeException {
+
+  /**
+   * Creates a new <code>UnassignedClassException</code> instance
+   * with no detail message.
+   */
+  public UnassignedClassException() { 
+    super(); 
+  }
+
+  /**
+   * Creates a new <code>UnassignedClassException</code> instance
+   * with a specified message.
+   *
+   * @param messagae a <code>String</code> containing the message.
+   */
+  public UnassignedClassException(String message) { 
+    super(message); 
+  }
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/UnassignedDatasetException.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/UnassignedDatasetException.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/UnassignedDatasetException.java	(revision 20131)
@@ -0,0 +1,53 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    UnassignedDatasetException.java
+ *    Copyright (C) 2001 Webmind Corp.
+ */
+
+package weka.core;
+
+/**
+ * <code>UnassignedDatasetException</code> is used when
+ * a method of an Instance is called that requires access to
+ * the Instance structure, but that the Instance does not contain
+ * a reference to any Instances (as set by Instance.setDataset(), or when
+ * an Instance is added to a set of Instances)).
+ *
+ * @author <a href="mailto:len@webmind.com">Len Trigg</a>
+ * @version $Revision$
+ */
+public class UnassignedDatasetException extends RuntimeException {
+
+  /**
+   * Creates a new <code>UnassignedDatasetException</code> instance
+   * with no detail message.
+   */
+  public UnassignedDatasetException() { 
+    super(); 
+  }
+
+  /**
+   * Creates a new <code>UnassignedDatasetException</code> instance
+   * with a specified message.
+   *
+   * @param messagae a <code>String</code> containing the message.
+   */
+  public UnassignedDatasetException(String message) { 
+    super(message); 
+  }
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/UnsupportedClassTypeException.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/UnsupportedClassTypeException.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/UnsupportedClassTypeException.java	(revision 20131)
@@ -0,0 +1,51 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    UnsupportedClassTypeException.java
+ *    Copyright (C) 2001 Webmind Corp.
+ */
+
+package weka.core;
+
+/**
+ * <code>UnsupportedClassTypeException</code> is used in situations
+ * where the throwing object is not able to accept Instances with the
+ * supplied structure, because the class Attribute is of the wrong type.
+ *
+ * @author <a href="mailto:len@webmind.com">Len Trigg</a>
+ * @version $Revision$
+ */
+public class UnsupportedClassTypeException extends WekaException {
+
+  /**
+   * Creates a new <code>UnsupportedClassTypeException</code> instance
+   * with no detail message.
+   */
+  public UnsupportedClassTypeException() { 
+    super(); 
+  }
+
+  /**
+   * Creates a new <code>UnsupportedClassTypeException</code> instance
+   * with a specified message.
+   *
+   * @param messagae a <code>String</code> containing the message.
+   */
+  public UnsupportedClassTypeException(String message) { 
+    super(message); 
+  }
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Utils.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Utils.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/Utils.java	(revision 20131)
@@ -0,0 +1,1384 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    Utils.java
+ *    Copyright (C) 1999 Eibe Frank,Len Trigg,Yong Wang
+ *
+ */
+
+package weka.core;
+
+import java.lang.Math;
+import java.util.StringTokenizer;
+import java.util.Properties;
+import java.io.File;
+import java.io.FileInputStream;
+
+/**
+ * Class implementing some simple utility methods.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @author Yong Wang (yongwang@cs.waikato.ac.nz)
+ * @author Len Trigg (trigg@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public final class Utils {
+
+  /** The natural logarithm of 2. */
+  public static double log2 = Math.log(2);
+
+  /** The small deviation allowed in double comparisons */
+  public static double SMALL = 1e-6;
+
+  
+  /**
+   * Reads properties that inherit from three locations. Properties
+   * are first defined in the system resource location (i.e. in the
+   * CLASSPATH).  These default properties must exist. Properties
+   * defined in the users home directory (optional) override default
+   * settings. Properties defined in the current directory (optional)
+   * override all these settings.
+   *
+   * @param resourceName the location of the resource that should be
+   * loaded.  e.g.: "weka/core/Utils.props". (The use of hardcoded
+   * forward slashes here is OK - see
+   * jdk1.1/docs/guide/misc/resources.html) This routine will also
+   * look for the file (in this case) "Utils.props" in the users home
+   * directory and the current directory.
+   * @return the Properties
+   * @exception Exception if no default properties are defined, or if
+   * an error occurs reading the properties files.  
+   */
+  public static Properties readProperties(String resourceName)
+    throws Exception{
+
+    Properties defaultProps = new Properties();
+    try {
+      // Apparently hardcoded slashes are OK here
+      // jdk1.1/docs/guide/misc/resources.html
+      defaultProps.load(ClassLoader.getSystemResourceAsStream(resourceName));
+    } catch (Exception ex) {
+/*      throw new Exception("Problem reading default properties: "
+	+ ex.getMessage()); */
+      System.err.println("Warning, unable to load properties file from "
+			 +"system resource (Utils.java)");
+    }
+
+    // Hardcoded slash is OK here
+    // eg: see jdk1.1/docs/guide/misc/resources.html
+    int slInd = resourceName.lastIndexOf('/');
+    if (slInd != -1) {
+      resourceName = resourceName.substring(slInd + 1);
+    }
+
+    // Allow a properties file in the home directory to override
+    Properties userProps = new Properties(defaultProps);    
+    File propFile = new File(System.getProperties().getProperty("user.home")
+                             + File.separatorChar
+                             + resourceName);
+    if (propFile.exists()) {
+      try {
+        userProps.load(new FileInputStream(propFile));
+      } catch (Exception ex) {
+        throw new Exception("Problem reading user properties: " + propFile);
+      }
+    }
+
+    // Allow a properties file in the current directory to override
+    Properties localProps = new Properties(userProps);
+    propFile = new File(resourceName);
+    if (propFile.exists()) {
+      try {
+        localProps.load(new FileInputStream(propFile));
+      } catch (Exception ex) {
+        throw new Exception("Problem reading local properties: " + propFile);
+      }
+    }
+    
+    return localProps;
+  }
+
+  /**
+   * Returns the correlation coefficient of two double vectors.
+   *
+   * @param y1 double vector 1
+   * @param y2 double vector 2
+   * @param n the length of two double vectors
+   * @return the correlation coefficient
+   */
+  public final static double correlation(double y1[],double y2[],int n) {
+
+    int i;
+    double av1 = 0.0, av2 = 0.0, y11 = 0.0, y22 = 0.0, y12 = 0.0, c;
+    
+    if (n <= 1) {
+      return 1.0;
+    }
+    for (i = 0; i < n; i++) {
+      av1 += y1[i];
+      av2 += y2[i];
+    }
+    av1 /= (double) n;
+    av2 /= (double) n;
+    for (i = 0; i < n; i++) {
+      y11 += (y1[i] - av1) * (y1[i] - av1);
+      y22 += (y2[i] - av2) * (y2[i] - av2);
+      y12 += (y1[i] - av1) * (y2[i] - av2);
+    }
+    if (y11 * y22 == 0.0) {
+      c=1.0;
+    } else {
+      c = y12 / Math.sqrt(Math.abs(y11 * y22));
+    }
+    
+    return c;
+  }
+
+  /**
+   * Removes all occurrences of a string from another string.
+   *
+   * @param inString the string to remove substrings from.
+   * @param substring the substring to remove.
+   * @return the input string with occurrences of substring removed.
+   */
+  public static String removeSubstring(String inString, String substring) {
+
+    StringBuffer result = new StringBuffer();
+    int oldLoc = 0, loc = 0;
+    while ((loc = inString.indexOf(substring, oldLoc))!= -1) {
+      result.append(inString.substring(oldLoc, loc));
+      oldLoc = loc + substring.length();
+    }
+    result.append(inString.substring(oldLoc));
+    return result.toString();
+  }
+
+  /**
+   * Replaces with a new string, all occurrences of a string from 
+   * another string.
+   *
+   * @param inString the string to replace substrings in.
+   * @param substring the substring to replace.
+   * @param replaceString the replacement substring
+   * @return the input string with occurrences of substring replaced.
+   */
+  public static String replaceSubstring(String inString, String subString,
+					String replaceString) {
+
+    StringBuffer result = new StringBuffer();
+    int oldLoc = 0, loc = 0;
+    while ((loc = inString.indexOf(subString, oldLoc))!= -1) {
+      result.append(inString.substring(oldLoc, loc));
+      result.append(replaceString);
+      oldLoc = loc + subString.length();
+    }
+    result.append(inString.substring(oldLoc));
+    return result.toString();
+  }
+
+
+  /**
+   * Pads a string to a specified length, inserting spaces on the left
+   * as required. If the string is too long, characters are removed (from
+   * the right).
+   *
+   * @param inString the input string
+   * @param length the desired length of the output string
+   * @return the output string
+   */
+  public static String padLeft(String inString, int length) {
+
+    return fixStringLength(inString, length, false);
+  }
+  
+  /**
+   * Pads a string to a specified length, inserting spaces on the right
+   * as required. If the string is too long, characters are removed (from
+   * the right).
+   *
+   * @param inString the input string
+   * @param length the desired length of the output string
+   * @return the output string
+   */
+  public static String padRight(String inString, int length) {
+
+    return fixStringLength(inString, length, true);
+  }
+  
+  /**
+   * Pads a string to a specified length, inserting spaces as
+   * required. If the string is too long, characters are removed (from
+   * the right).
+   *
+   * @param inString the input string
+   * @param length the desired length of the output string
+   * @param right true if inserted spaces should be added to the right
+   * @return the output string
+   */
+  private static String fixStringLength(String inString, int length,
+					boolean right) {
+
+    if (inString.length() < length) {
+      while (inString.length() < length) {
+	inString = (right ? inString.concat(" ") : " ".concat(inString));
+      }
+    } else if (inString.length() > length) {
+      inString = inString.substring(0, length);
+    }
+    return inString;
+  }
+ 
+  /**
+   * Rounds a double and converts it into String.
+   *
+   * @param value the double value
+   * @param afterDecimalPoint the (maximum) number of digits permitted
+   * after the decimal point
+   * @return the double as a formatted string
+   */
+  public static String doubleToString(double value, int afterDecimalPoint) {
+    
+    StringBuffer stringBuffer;
+    double temp;
+    int i,dotPosition;
+    long precisionValue;
+    
+    temp = value * Math.pow(10.0, afterDecimalPoint);
+    if (Math.abs(temp) < Long.MAX_VALUE) {
+      precisionValue = 	(temp > 0) ? (long)(temp + 0.5) 
+                                   : -(long)(Math.abs(temp) + 0.5);
+      if (precisionValue == 0) {
+	stringBuffer = new StringBuffer(String.valueOf(0));
+      } else {
+	stringBuffer = new StringBuffer(String.valueOf(precisionValue));
+      }
+      if (afterDecimalPoint == 0) {
+	return stringBuffer.toString();
+      }
+      dotPosition = stringBuffer.length() - afterDecimalPoint;
+      while (((precisionValue < 0) && (dotPosition < 1)) ||
+	     (dotPosition < 0)) {
+	if (precisionValue < 0) {
+	  stringBuffer.insert(1, 0);
+	} else {
+	  stringBuffer.insert(0, 0);
+	}
+	dotPosition++;
+      }
+      stringBuffer.insert(dotPosition, '.');
+      if ((precisionValue < 0) && (stringBuffer.charAt(1) == '.')) {
+	stringBuffer.insert(1, 0);
+      } else if (stringBuffer.charAt(0) == '.') {
+	stringBuffer.insert(0, 0);
+      }
+      int currentPos = stringBuffer.length() - 1;
+      while ((currentPos > dotPosition) &&
+	     (stringBuffer.charAt(currentPos) == '0')) {
+	stringBuffer.setCharAt(currentPos--, ' ');
+      }
+      if (stringBuffer.charAt(currentPos) == '.') {
+	stringBuffer.setCharAt(currentPos, ' ');
+      }
+      
+      return stringBuffer.toString().trim();
+    }
+    return new String("" + value);
+  }
+
+  /**
+   * Rounds a double and converts it into a formatted decimal-justified String.
+   * Trailing 0's are replaced with spaces.
+   *
+   * @param value the double value
+   * @param width the width of the string
+   * @param afterDecimalPoint the number of digits after the decimal point
+   * @return the double as a formatted string
+   */
+  public static String doubleToString(double value, int width,
+				      int afterDecimalPoint) {
+    
+    String tempString = doubleToString(value, afterDecimalPoint);
+    char[] result;
+    int dotPosition;
+
+    if ((afterDecimalPoint >= width) 
+        || (tempString.indexOf('E') != -1)) { // Protects sci notation
+      return tempString;
+    }
+
+    // Initialize result
+    result = new char[width];
+    for (int i = 0; i < result.length; i++) {
+      result[i] = ' ';
+    }
+
+    if (afterDecimalPoint > 0) {
+      // Get position of decimal point and insert decimal point
+      dotPosition = tempString.indexOf('.');
+      if (dotPosition == -1) {
+	dotPosition = tempString.length();
+      } else {
+	result[width - afterDecimalPoint - 1] = '.';
+      }
+    } else {
+      dotPosition = tempString.length();
+    }
+    
+
+    int offset = width - afterDecimalPoint - dotPosition;
+    if (afterDecimalPoint > 0) {
+      offset--;
+    }
+
+    // Not enough room to decimal align within the supplied width
+    if (offset < 0) {
+      return tempString;
+    }
+
+    // Copy characters before decimal point
+    for (int i = 0; i < dotPosition; i++) {
+      result[offset + i] = tempString.charAt(i);
+    }
+
+    // Copy characters after decimal point
+    for (int i = dotPosition + 1; i < tempString.length(); i++) {
+      result[offset + i] = tempString.charAt(i);
+    }
+
+    return new String(result);
+  }
+
+  /**
+   * Tests if a is equal to b.
+   *
+   * @param a a double
+   * @param b a double
+   */
+  public static boolean eq(double a, double b){
+    
+    return (a - b < SMALL) && (b - a < SMALL); 
+  }
+
+  /**
+   * Checks if the given array contains any non-empty options.
+   *
+   * @param strings an array of strings
+   * @exception Exception if there are any non-empty options
+   */
+  public static void checkForRemainingOptions(String [] options) 
+    throws Exception {
+    
+    int illegalOptionsFound = 0;
+    StringBuffer text = new StringBuffer();
+
+    if (options == null) {
+      return;
+    }
+    for (int i = 0; i < options.length; i++) {
+      if (options[i].length() > 0) {
+	illegalOptionsFound++;
+	text.append(options[i] + ' ');
+      }
+    }
+    if (illegalOptionsFound > 0) {
+      throw new Exception("Illegal options: " + text);
+    }
+  }
+  
+  /**
+   * Checks if the given array contains the flag "-Char". Stops
+   * searching at the first marker "--". If the flag is found,
+   * it is replaced with the empty string.
+   *
+   * @param flag the character indicating the flag.
+   * @param strings the array of strings containing all the options.
+   * @return true if the flag was found
+   * @exception Exception if an illegal option was found
+   */
+
+  public static boolean getFlag(char flag, String [] options) 
+    throws Exception {
+
+    if (options == null) {
+      return false;
+    }
+    for (int i = 0; i < options.length; i++) {
+      if ((options[i].length() > 1) && (options[i].charAt(0) == '-')) {
+	try {
+	  Double dummy = Double.valueOf(options[i]);
+	} catch (NumberFormatException e) {
+	  if (options[i].length() > 2) {
+	    throw new Exception("Illegal option: " + options[i]);
+	  }
+	  if (options[i].charAt(1) == flag) {
+	    options[i] = "";
+	    return true;
+	  }
+	  if (options[i].charAt(1) == '-') {
+	    return false;
+	  }
+	}
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Gets an option indicated by a flag "-Char" from the given array
+   * of strings. Stops searching at the first marker "--". Replaces 
+   * flag and option with empty strings.
+   *
+   * @param flag the character indicating the option.
+   * @param options the array of strings containing all the options.
+   * @return the indicated option or an empty string
+   * @exception Exception if the option indicated by the flag can't be found
+   */
+  public static String getOption(char flag, String [] options) 
+    throws Exception {
+
+    String newString;
+
+    if (options == null)
+      return "";
+    for (int i = 0; i < options.length; i++) {
+      if ((options[i].length() > 0) && (options[i].charAt(0) == '-')) {
+	
+	// Check if it is a negative number
+	try {
+	  Double dummy = Double.valueOf(options[i]);
+	} catch (NumberFormatException e) {
+	  if (options[i].length() > 2) {
+	    throw new Exception("Illegal option: " + options[i]);
+	  }
+	  if (options[i].charAt(1) == flag) {
+	    if (i + 1 == options.length) {
+	      throw new Exception("No value given for -" + flag + " option.");
+	    }
+	    options[i] = "";
+	    newString = new String(options[i + 1]);
+	    options[i + 1] = "";
+	    return newString;
+	  }
+	  if (options[i].charAt(1) == '-') {
+	    return "";
+	  }
+	}
+      }
+    }
+    return "";
+  }
+
+  /**
+   * Quotes a string if it contains special characters.
+   * 
+   * The following rules are applied:
+   *
+   * A character is backquoted version of it is one 
+   * of <tt>" ' % \ \n \r \t</tt>.
+   *
+   * A string is enclosed within single quotes if a character has been
+   * backquoted using the previous rule above or contains 
+   * <tt>{ }</tt> or is exactly equal to the strings 
+   * <tt>, ? space or ""</tt> (empty string).
+   *
+   * A quoted question mark distinguishes it from the missing value which
+   * is represented as an unquoted question mark in arff files.
+   *
+   * @param string the string to be quoted
+   * @return the string (possibly quoted)
+   */
+  public static String quote(String string) {
+      boolean quote = false;
+
+      // backquote the following characters 
+      if ((string.indexOf('\n') != -1) || (string.indexOf('\r') != -1) || 
+	  (string.indexOf('\'') != -1) || (string.indexOf('"') != -1) || 
+	  (string.indexOf('\\') != -1) || 
+	  (string.indexOf('\t') != -1) || (string.indexOf('%') != -1)) {
+	  string = backQuoteChars(string);
+	  quote = true;
+      }
+
+      // Enclose the string in 's if the string contains a recently added
+      // backquote or contains one of the following characters.
+      if((quote == true) || 
+	 (string.indexOf('{') != -1) || (string.indexOf('}') != -1) ||
+	 (string.indexOf(',') != -1) || (string.equals("?")) ||
+	 (string.indexOf(' ') != -1) || (string.equals(""))) {
+	  string = ("'".concat(string)).concat("'");
+      }
+
+      return string;
+  }
+
+  /**
+   * Converts carriage returns and new lines in a string into \r and \n.
+   * Backquotes the following characters: ` " \ \t and %
+   * @param string the string
+   * @return the converted string
+   */
+  public static String backQuoteChars(String string) {
+
+    int index;
+    StringBuffer newStringBuffer;
+
+    // replace each of the following characters with the backquoted version
+    char   charsFind[] =    {'\\',   '\'',  '\t',  '"',    '%'};
+    String charsReplace[] = {"\\\\", "\\'", "\\t", "\\\"", "\\%"};
+    for(int i = 0; i < charsFind.length; i++) {
+	if (string.indexOf(charsFind[i]) != -1 ) {
+	    newStringBuffer = new StringBuffer();
+	    while ((index = string.indexOf(charsFind[i])) != -1) {
+		if (index > 0) {
+		    newStringBuffer.append(string.substring(0, index));
+		}
+		newStringBuffer.append(charsReplace[i]);
+		if ((index + 1) < string.length()) {
+		    string = string.substring(index + 1);
+		} else {
+		    string = "";
+		}
+	    }
+	    newStringBuffer.append(string);
+	    string = newStringBuffer.toString();
+	}
+    }
+
+    return Utils.convertNewLines(string);
+  }
+
+  /**
+   * Converts carriage returns and new lines in a string into \r and \n.
+   * @param string the string
+   * @return the converted string
+   */
+  public static String convertNewLines(String string) {
+    
+    int index;
+
+    // Replace with \n
+    StringBuffer newStringBuffer = new StringBuffer();
+    while ((index = string.indexOf('\n')) != -1) {
+      if (index > 0) {
+	newStringBuffer.append(string.substring(0, index));
+      }
+      newStringBuffer.append('\\');
+      newStringBuffer.append('n');
+      if ((index + 1) < string.length()) {
+	string = string.substring(index + 1);
+      } else {
+	string = "";
+      }
+    }
+    newStringBuffer.append(string);
+    string = newStringBuffer.toString();
+
+    // Replace with \r
+    newStringBuffer = new StringBuffer();
+    while ((index = string.indexOf('\r')) != -1) {
+      if (index > 0) {
+	newStringBuffer.append(string.substring(0, index));
+      }
+      newStringBuffer.append('\\');
+      newStringBuffer.append('r');
+      if ((index + 1) < string.length()){
+	string = string.substring(index + 1);
+      } else {
+	string = "";
+      }
+    }
+    newStringBuffer.append(string);
+    return newStringBuffer.toString();
+  }
+    
+
+  /**
+   * Returns the secondary set of options (if any) contained in
+   * the supplied options array. The secondary set is defined to
+   * be any options after the first "--". These options are removed from
+   * the original options array.
+   *
+   * @param options the input array of options
+   * @return the array of secondary options
+   */
+  public static String [] partitionOptions(String [] options) {
+
+    for (int i = 0; i < options.length; i++) {
+      if (options[i].equals("--")) {
+	options[i++] = "";
+	String [] result = new String [options.length - i];
+	for (int j = i; j < options.length; j++) {
+	  result[j - i] = options[j];
+	  options[j] = "";
+	}
+	return result;
+      }
+    }
+    return new String [0];
+  }
+
+  /**
+   * Split up a string containing options into an array of strings,
+   * one for each option.
+   *
+   * @param optionString the string containing the options
+   * @return the array of options
+   */
+  public static String [] splitOptions(String optionString) {
+
+    FastVector optionsVec = new FastVector();
+    StringTokenizer st = new StringTokenizer(optionString);
+    while (st.hasMoreTokens())
+      optionsVec.addElement(st.nextToken());
+
+    String [] options = new String[optionsVec.size()];
+    for (int i = 0; i < optionsVec.size(); i++) {
+      options[i] = (String)optionsVec.elementAt(i);
+    }
+    return options;
+  }
+
+  /**
+   * Joins all the options in an option array into a single string,
+   * as might be used on the command line.
+   *
+   * @param optionArray the array of options
+   * @return the string containing all options.
+   */
+  public static String joinOptions(String [] optionArray) {
+
+    String optionString = "";
+    for (int i = 0; i < optionArray.length; i++) {
+      if (optionArray[i].equals("")) {
+	continue;
+      }
+      if (optionArray[i].indexOf(' ') != -1) {
+	optionString += '"' + optionArray[i] + '"';
+      } else {
+	optionString += optionArray[i];
+      }
+      optionString += " ";
+    }
+    return optionString.trim();
+  }
+  
+  /**
+   * Creates a new instance of an object given it's class name and
+   * (optional) arguments to pass to it's setOptions method. If the
+   * object implements OptionHandler and the options parameter is
+   * non-null, the object will have it's options set. Example use:<p>
+   *
+   * <code> <pre>
+   * String classifierName = Utils.getOption('W', options);
+   * Classifier c = (Classifier)Utils.forName(Classifier.class,
+   *                                          classifierName,
+   *                                          options);
+   * setClassifier(c);
+   * </pre></code>
+   *
+   * @param classType the class that the instantiated object should
+   * be assignable to -- an exception is thrown if this is not the case
+   * @param className the fully qualified class name of the object
+   * @param options an array of options suitable for passing to setOptions. May
+   * be null. Any options accepted by the object will be removed from the
+   * array.
+   * @return the newly created object, ready for use.
+   * @exception Exception if the class name is invalid, or if the
+   * class is not assignable to the desired class type, or the options
+   * supplied are not acceptable to the object
+   */
+  public static Object forName(Class classType,
+			       String className,
+			       String [] options) throws Exception {
+
+    Class c = null;
+    try {
+      c = Class.forName(className);
+    } catch (Exception ex) {
+      throw new Exception("Can't find class called: " + className);
+    }
+    if (!classType.isAssignableFrom(c)) {
+      throw new Exception(classType.getName() + " is not assignable from "
+			  + className);
+    }
+    Object o = c.newInstance();
+    if ((o instanceof OptionHandler)
+	&& (options != null)) {
+      ((OptionHandler)o).setOptions(options);
+      Utils.checkForRemainingOptions(options);
+    }
+    return o;
+  }
+
+  /**
+   * Computes entropy for an array of integers.
+   *
+   * @param counts array of counts
+   * @returns - a log2 a - b log2 b - c log2 c + (a+b+c) log2 (a+b+c)
+   * when given array [a b c]
+   */
+  public static double info(int counts[]) {
+    
+    int total = 0; int c;
+    double x = 0;
+    for (int j = 0; j < counts.length; j++) {
+      x -= xlogx(counts[j]);
+      total += counts[j];
+    }
+    return x + xlogx(total);
+  }
+
+  /**
+   * Tests if a is smaller or equal to b.
+   *
+   * @param a a double
+   * @param b a double
+   */
+  public static boolean smOrEq(double a,double b) {
+    
+    return (a-b < SMALL);
+  }
+
+  /**
+   * Tests if a is greater or equal to b.
+   *
+   * @param a a double
+   * @param b a double
+   */
+  public static boolean grOrEq(double a,double b) {
+    
+    return (b-a < SMALL);
+  }
+  
+  /**
+   * Tests if a is smaller than b.
+   *
+   * @param a a double
+   * @param b a double
+   */
+  public static boolean sm(double a,double b) {
+    
+    return (b-a > SMALL);
+  }
+
+  /**
+   * Tests if a is smaller than b.
+   *
+   * @param a a double
+   * @param b a double 
+   */
+  public static boolean gr(double a,double b) {
+    
+    return (a-b > SMALL);
+  }
+
+  /**
+   * Returns the logarithm of a for base 2.
+   *
+   * @param a a double
+   */
+  public static double log2(double a) {
+    
+    return Math.log(a) / log2;
+  }
+
+  /**
+   * Returns index of maximum element in a given
+   * array of doubles. First maximum is returned.
+   *
+   * @param doubles the array of doubles
+   * @return the index of the maximum element
+   */
+  public static int maxIndex(double [] doubles) {
+
+    double maximum = 0;
+    int maxIndex = 0;
+
+    for (int i = 0; i < doubles.length; i++) {
+      if ((i == 0) || (doubles[i] > maximum)) {
+	maxIndex = i;
+	maximum = doubles[i];
+      }
+    }
+
+    return maxIndex;
+  }
+
+  /**
+   * Returns index of maximum element in a given
+   * array of integers. First maximum is returned.
+   *
+   * @param ints the array of integers
+   * @return the index of the maximum element
+   */
+  public static int maxIndex(int [] ints) {
+
+    int maximum = 0;
+    int maxIndex = 0;
+
+    for (int i = 0; i < ints.length; i++) {
+      if ((i == 0) || (ints[i] > maximum)) {
+	maxIndex = i;
+	maximum = ints[i];
+      }
+    }
+
+    return maxIndex;
+  }
+
+  /**
+   * Computes the mean for an array of doubles.
+   *
+   * @param vector the array
+   * @return the mean
+   */
+  public static double mean(double[] vector) {
+  
+    double sum = 0;
+
+    if (vector.length == 0) {
+      return 0;
+    }
+    for (int i = 0; i < vector.length; i++) {
+      sum += vector[i];
+    }
+    return sum / (double) vector.length;
+  }
+
+  /**
+   * Returns index of minimum element in a given
+   * array of integers. First minimum is returned.
+   *
+   * @param ints the array of integers
+   * @return the index of the minimum element
+   */
+  public static int minIndex(int [] ints) {
+
+    int minimum = 0;
+    int minIndex = 0;
+
+    for (int i = 0; i < ints.length; i++) {
+      if ((i == 0) || (ints[i] < minimum)) {
+	minIndex = i;
+	minimum = ints[i];
+      }
+    }
+
+    return minIndex;
+  }
+
+  /**
+   * Returns index of minimum element in a given
+   * array of doubles. First minimum is returned.
+   *
+   * @param doubles the array of doubles
+   * @return the index of the minimum element
+   */
+  public static int minIndex(double [] doubles) {
+
+    double minimum = 0;
+    int minIndex = 0;
+
+    for (int i = 0; i < doubles.length; i++) {
+      if ((i == 0) || (doubles[i] < minimum)) {
+	minIndex = i;
+	minimum = doubles[i];
+      }
+    }
+
+    return minIndex;
+  }
+
+  /**
+   * Normalizes the doubles in the array by their sum.
+   *
+   * @param doubles the array of double
+   * @exception IllegalArgumentException if sum is Zero or NaN
+   */
+  public static void normalize(double[] doubles) {
+
+    double sum = 0;
+    for (int i = 0; i < doubles.length; i++) {
+      sum += doubles[i];
+    }
+    normalize(doubles, sum);
+  }
+
+  /**
+   * Normalizes the doubles in the array using the given value.
+   *
+   * @param doubles the array of double
+   * @param sum the value by which the doubles are to be normalized
+   * @exception IllegalArgumentException if sum is zero or NaN
+   */
+  public static void normalize(double[] doubles, double sum) {
+
+    if (Double.isNaN(sum)) {
+      throw new IllegalArgumentException("Can't normalize array. Sum is NaN.");
+    }
+    if (sum == 0) {
+      // Maybe this should just be a return.
+      throw new IllegalArgumentException("Can't normalize array. Sum is zero.");
+    }
+    for (int i = 0; i < doubles.length; i++) {
+      doubles[i] /= sum;
+    }
+  }
+
+  /**
+   * Rounds a double to the next nearest integer value. The JDK version
+   * of it doesn't work properly.
+   *
+   * @param value the double value
+   * @return the resulting integer value
+   */
+  public static int round(double value) {
+
+    int roundedValue = value > 0
+      ? (int)(value + 0.5)
+      : -(int)(Math.abs(value) + 0.5);
+    
+    return roundedValue;
+  }
+
+  /**
+   * Rounds a double to the given number of decimal places.
+   *
+   * @param value the double value
+   * @param afterDecimalPoint the number of digits after the decimal point
+   * @return the double rounded to the given precision
+   */
+  public static double roundDouble(double value,int afterDecimalPoint) {
+
+    double mask = Math.pow(10.0, (double)afterDecimalPoint);
+
+    return (double)(Math.round(value * mask)) / mask;
+  }
+
+  /**
+   * Sorts a given array of integers in ascending order and returns an 
+   * array of integers with the positions of the elements of the original 
+   * array in the sorted array. The sort is stable. (Equal elements remain
+   * in their original order.)
+   *
+   * @param array this array is not changed by the method!
+   * @return an array of integers with the positions in the sorted
+   * array.
+   */
+  public static int[] sort(int [] array) {
+
+    int [] index = new int[array.length];
+    int [] newIndex = new int[array.length];
+    int [] helpIndex;
+    int numEqual;
+    
+    for (int i = 0; i < index.length; i++) {
+      index[i] = i;
+    }
+    quickSort(array, index, 0, array.length - 1);
+
+    // Make sort stable
+    int i = 0;
+    while (i < index.length) {
+      numEqual = 1;
+      for (int j = i + 1; ((j < index.length)
+			   && (array[index[i]] == array[index[j]]));
+	   j++) {
+	numEqual++;
+      }
+      if (numEqual > 1) {
+	helpIndex = new int[numEqual];
+	for (int j = 0; j < numEqual; j++) {
+	  helpIndex[j] = i + j;
+	}
+	quickSort(index, helpIndex, 0, numEqual - 1);
+	for (int j = 0; j < numEqual; j++) {
+	  newIndex[i + j] = index[helpIndex[j]];
+	}
+	i += numEqual;
+      } else {
+	newIndex[i] = index[i];
+	i++;
+      }
+    }
+    return newIndex;
+  }
+
+  /**
+   * Sorts a given array of doubles in ascending order and returns an
+   * array of integers with the positions of the elements of the
+   * original array in the sorted array. NOTE THESE CHANGES: the sort
+   * is no longer stable and it doesn't use safe floating-point
+   * comparisons anymore. Occurrences of Double.NaN are treated as 
+   * Double.MAX_VALUE
+   *
+   * @param array this array is not changed by the method!
+   * @return an array of integers with the positions in the sorted
+   * array.  
+   */
+  public static int[] sort(double [] array) {
+
+    int [] index = new int[array.length];
+    array = (double [])array.clone();
+    for (int i = 0; i < index.length; i++) {
+      index[i] = i;
+      if (Double.isNaN(array[i])) {
+        array[i] = Double.MAX_VALUE;
+      }
+    }
+    quickSort(array, index, 0, array.length - 1);
+    return index;
+  }
+
+  /**
+   * Sorts a given array of doubles in ascending order and returns an 
+   * array of integers with the positions of the elements of the original 
+   * array in the sorted array. The sort is stable (Equal elements remain
+   * in their original order.) Occurrences of Double.NaN are treated as 
+   * Double.MAX_VALUE
+   *
+   * @param array this array is not changed by the method!
+   * @return an array of integers with the positions in the sorted
+   * array.
+   */
+  public static int[] stableSort(double [] array){
+
+    int [] index = new int[array.length];
+    int [] newIndex = new int[array.length];
+    int [] helpIndex;
+    int numEqual;
+    
+    array = (double [])array.clone();
+    for (int i = 0; i < index.length; i++) {
+      index[i] = i;
+      if (Double.isNaN(array[i])) {
+        array[i] = Double.MAX_VALUE;
+      }
+    }
+    quickSort(array,index,0,array.length-1);
+
+    // Make sort stable
+
+    int i = 0;
+    while (i < index.length) {
+      numEqual = 1;
+      for (int j = i+1; ((j < index.length) && Utils.eq(array[index[i]],
+							array[index[j]])); j++)
+	numEqual++;
+      if (numEqual > 1) {
+	helpIndex = new int[numEqual];
+	for (int j = 0; j < numEqual; j++)
+	  helpIndex[j] = i+j;
+	quickSort(index, helpIndex, 0, numEqual-1);
+	for (int j = 0; j < numEqual; j++) 
+	  newIndex[i+j] = index[helpIndex[j]];
+	i += numEqual;
+      } else {
+	newIndex[i] = index[i];
+	i++;
+      }
+    }
+
+    return newIndex;
+  }
+
+  /**
+   * Computes the variance for an array of doubles.
+   *
+   * @param vector the array
+   * @return the variance
+   */
+  public static double variance(double[] vector) {
+  
+    double sum = 0, sumSquared = 0;
+
+    if (vector.length <= 1) {
+      return 0;
+    }
+    for (int i = 0; i < vector.length; i++) {
+      sum += vector[i];
+      sumSquared += (vector[i] * vector[i]);
+    }
+    return (sumSquared - (sum * sum / (double) vector.length)) / 
+      (double) (vector.length - 1);
+  }
+
+  /**
+   * Computes the sum of the elements of an array of doubles.
+   *
+   * @param doubles the array of double
+   * @returns the sum of the elements
+   */
+  public static double sum(double[] doubles) {
+
+    double sum = 0;
+
+    for (int i = 0; i < doubles.length; i++) {
+      sum += doubles[i];
+    }
+    return sum;
+  }
+
+  /**
+   * Computes the sum of the elements of an array of integers.
+   *
+   * @param ints the array of integers
+   * @returns the sum of the elements
+   */
+  public static int sum(int[] ints) {
+
+    int sum = 0;
+
+    for (int i = 0; i < ints.length; i++) {
+      sum += ints[i];
+    }
+    return sum;
+  }
+
+  /**
+   * Returns c*log2(c) for a given integer value c.
+   *
+   * @param c an integer value
+   * @returns c*log2(c) (but is careful to return 0 if c is 0)
+   */
+  public static double xlogx(int c) {
+    
+    if (c == 0) {
+      return 0.0;
+    }
+    return c * Utils.log2((double) c);
+  }
+
+  /**
+   * Implements quicksort for an array of indices.
+   *
+   * @param array the array of integers to be sorted
+   * @param index the index which should contain the positions in the
+   * sorted array
+   * @param lo0 the first index of the subset to be sorted
+   * @param hi0 the last index of the subset to be sorted
+   */
+  private static void quickSort(int [] array, int [] index,
+				int lo0, int hi0) {
+
+    int lo = lo0;
+    int hi = hi0;
+    int mid;
+    int help;
+    
+    if (hi0 > lo0) {
+      
+      // Arbitrarily establishing partition element as the midpoint of
+      // the array.
+      mid = array[index[(lo0 + hi0) / 2]];
+
+      // loop through the array until indices cross
+      while (lo <= hi) {
+	
+	// find the first element that is greater than or equal to  
+	// the partition element starting from the left Index.
+	while ((array[index[lo]] < mid) && (lo < hi0)) {
+	  ++lo;
+	}
+	
+	// find an element that is smaller than or equal to 
+	// the partition element starting from the right Index.
+	while ((array[index[hi]] > mid) && (hi > lo0)) {
+	  --hi;
+	}
+	
+	// if the indexes have not crossed, swap
+	if (lo <= hi) {
+	  help = index[lo];
+	  index[lo] = index[hi];
+	  index[hi] = help;
+	  ++lo;
+	  --hi;
+	}
+      }
+      
+      // If the right index has not reached the left side of array
+      // must now sort the left partition.
+      if (lo0 < hi) {
+	quickSort(array, index, lo0, hi);
+      }
+      
+      // If the left index has not reached the right side of array
+      // must now sort the right partition.
+      if (lo < hi0) {
+	quickSort(array, index, lo, hi0);
+      }
+    }
+  }
+
+  /**
+   * Implements unsafe quicksort for an array of indices.
+   *
+   * @param array the array of doubles to be sorted
+   * @param index the index which should contain the positions in the
+   * sorted array
+   * @param lo0 the first index of the subset to be sorted
+   * @param hi0 the last index of the subset to be sorted
+   */
+  private static void quickSort(double [] array, int [] index, int lo0, int hi0) {
+
+    int lo = lo0;
+    int hi = hi0;
+    double mid;
+    int help;
+    
+    if (hi0 > lo0) {
+      
+      // Arbitrarily establishing partition element as the midpoint of
+      // the array.
+      mid = array[index[(lo0 + hi0) / 2]];
+
+      // loop through the array until indices cross
+      while (lo <= hi) {
+	
+	// find the first element that is greater than or equal to  
+	// the partition element starting from the left Index.
+	while ((array[index[lo]] < mid) && (lo < hi0)) {
+	  ++lo;
+	}
+	
+	// find an element that is smaller than or equal to 
+	// the partition element starting from the right Index.
+	while ((array[index[hi]] > mid) && (hi > lo0)) {
+	  --hi;
+	}
+	
+	// if the indexes have not crossed, swap
+	if (lo <= hi) {
+	  help = index[lo];
+	  index[lo] = index[hi];
+	  index[hi] = help;
+	  ++lo;
+	  --hi;
+	}
+      }
+      
+      // If the right index has not reached the left side of array
+      // must now sort the left partition.
+      if (lo0 < hi) {
+	quickSort(array, index, lo0, hi);
+      }
+      
+      // If the left index has not reached the right side of array
+      // must now sort the right partition.
+      if (lo < hi0) {
+	quickSort(array, index, lo, hi0);
+      }
+    }
+  }
+
+  /**
+   * Main method for testing this class.
+   *
+   * @param ops some dummy options
+   */
+  public static void main(String[] ops) {
+
+    double[] doubles = {4.5, 6.7, Double.NaN, 3.4, 4.8, 1.2, 3.4};
+    int[] ints = {12, 6, 2, 18, 16, 6, 7, 5};
+
+    try {
+
+      // Option handling
+      System.out.println("First option split up:");
+      if (ops.length > 0) {
+	String[] firstOptionSplitUp = Utils.splitOptions(ops[0]);
+	for (int i = 0; i < firstOptionSplitUp.length; i ++) {
+	  System.out.println(firstOptionSplitUp[i]);
+	}
+      }					       
+      System.out.println("Partitioned options: ");
+      String[] partitionedOptions = Utils.partitionOptions(ops);
+      for (int i  = 0; i < partitionedOptions.length; i++) {
+	System.out.println(partitionedOptions[i]);
+      }
+      System.out.println("Get flag -f: " + Utils.getFlag('f', ops));
+      System.out.println("Get option -o: " + Utils.getOption('o', ops));
+      System.out.println("Checking for remaining options... ");
+      Utils.checkForRemainingOptions(ops);
+      
+      // Statistics
+      System.out.println("Original array (doubles): ");
+      for (int i = 0; i < doubles.length; i++) {
+	System.out.print(doubles[i] + " ");
+      }
+      System.out.println();
+      System.out.println("Original array (ints): ");
+      for (int i = 0; i < ints.length; i++) {
+	System.out.print(ints[i] + " ");
+      }
+      System.out.println();
+      System.out.println("Correlation: " + Utils.correlation(doubles, doubles, 
+							     doubles.length));
+      System.out.println("Mean: " + Utils.mean(doubles));
+      System.out.println("Variance: " + Utils.variance(doubles));
+      System.out.println("Sum (doubles): " + Utils.sum(doubles));
+      System.out.println("Sum (ints): " + Utils.sum(ints));
+      System.out.println("Max index (doubles): " + Utils.maxIndex(doubles));
+      System.out.println("Max index (ints): " + Utils.maxIndex(ints));
+      System.out.println("Min index (doubles): " + Utils.minIndex(doubles));
+      System.out.println("Min index (ints): " + Utils.minIndex(ints));
+      
+      // Sorting and normalizing
+      System.out.println("Sorted array (doubles): ");
+      int[] sorted = Utils.sort(doubles);
+      for (int i = 0; i < doubles.length; i++) {
+	System.out.print(doubles[sorted[i]] + " ");
+      }
+      System.out.println();
+      System.out.println("Normalized array (doubles): ");
+      Utils.normalize(doubles);
+      for (int i = 0; i < doubles.length; i++) {
+	System.out.print(doubles[i] + " ");
+      }
+      System.out.println();
+      System.out.println("Normalized again (doubles): ");
+      Utils.normalize(doubles, Utils.sum(doubles));
+      for (int i = 0; i < doubles.length; i++) {
+	System.out.print(doubles[i] + " ");
+      }
+      System.out.println();
+      
+      // Pretty-printing
+      System.out.println("-4.58: " + Utils.doubleToString(-4.57826535, 2));
+      System.out.println("-6.78: " + Utils.doubleToString(-6.78214234, 6,2));
+      
+      // Comparisons
+      System.out.println("5.70001 == 5.7 ? " + Utils.eq(5.70001, 5.7));
+      System.out.println("5.70001 > 5.7 ? " + Utils.gr(5.70001, 5.7));
+      System.out.println("5.70001 >= 5.7 ? " + Utils.grOrEq(5.70001, 5.7));
+      System.out.println("5.7 < 5.70001 ? " + Utils.sm(5.7, 5.70001));
+      System.out.println("5.7 <= 5.70001 ? " + Utils.smOrEq(5.7, 5.70001));
+      
+      // Math
+      System.out.println("Info (ints): " + Utils.info(ints));
+      System.out.println("log2(4.6): " + Utils.log2(4.6));
+      System.out.println("5 * log(5): " + Utils.xlogx(5));
+      System.out.println("5.5 rounded: " + Utils.round(5.5));
+      System.out.println("5.55555 rounded to 2 decimal places: " + 
+			 Utils.roundDouble(5.55555, 2));
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+}
+  
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/WeightedInstancesHandler.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/WeightedInstancesHandler.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/WeightedInstancesHandler.java	(revision 20131)
@@ -0,0 +1,43 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    WeightedInstancesHandler.java
+ *    Copyright (C) 1999 Eibe Frank
+ *
+ */
+
+package weka.core;
+
+/** 
+ * Interface to something that makes use of the information provided
+ * by instance weights.
+ *
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version $Revision$ 
+*/
+public interface WeightedInstancesHandler {
+
+  // Nothing in here, because the class is just used as an indicator
+}
+
+
+
+
+
+
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/WekaException.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/WekaException.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/core/WekaException.java	(revision 20131)
@@ -0,0 +1,50 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    WekaException.java
+ *    Copyright (C) 2001 Webmind Corp.
+ */
+
+package weka.core;
+
+/**
+ * <code>WekaException</code> is used when some Weka-specific
+ * checked exception must be raised.
+ *
+ * @author <a href="mailto:len@webmind.com">Len Trigg</a>
+ * @version $Revision$
+ */
+public class WekaException extends Exception {
+
+  /**
+   * Creates a new <code>WekaException</code> instance
+   * with no detail message.
+   */
+  public WekaException() { 
+    super(); 
+  }
+
+  /**
+   * Creates a new <code>WekaException</code> instance
+   * with a specified message.
+   *
+   * @param messagae a <code>String</code> containing the message.
+   */
+  public WekaException(String message) { 
+    super(message); 
+  }
+}
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/experiment/Stats.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/experiment/Stats.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/experiment/Stats.java	(revision 20131)
@@ -0,0 +1,188 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    Stats.java
+ *    Copyright (C) 1999 Len Trigg
+ *
+ */
+
+
+package weka.experiment;
+import weka.core.Utils;
+
+/**
+ * A class to store simple statistics
+ *
+ * @author Len Trigg (trigg@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public class Stats {
+  
+  /** The number of values seen */
+  public double count = 0;
+
+  /** The sum of values seen */
+  public double sum = 0;
+
+  /** The sum of values squared seen */
+  public double sumSq = 0;
+
+  /** The std deviation of values at the last calculateDerived() call */    
+  public double stdDev = Double.NaN;
+
+  /** The mean of values at the last calculateDerived() call */    
+  public double mean = Double.NaN;
+
+  /** The minimum value seen, or Double.NaN if no values seen */
+  public double min = Double.NaN;
+
+  /** The maximum value seen, or Double.NaN if no values seen */
+  public double max = Double.NaN;
+    
+  /**
+   * Adds a value to the observed values
+   *
+   * @param value the observed value
+   */
+  public void add(double value) {
+
+    add(value, 1);
+  }
+
+  /**
+   * Adds a value that has been seen n times to the observed values
+   *
+   * @param value the observed value
+   * @param n the number of times to add value
+   */
+  public void add(double value, double n) {
+
+    sum += value * n;
+    sumSq += value * value * n;
+    count += n;
+    if (Double.isNaN(min)) {
+      min = max = value;
+    } else if (value < min) {
+      min = value;
+    } else if (value > max) {
+      max = value;
+    }
+  }
+
+  /**
+   * Removes a value to the observed values (no checking is done
+   * that the value being removed was actually added). 
+   *
+   * @param value the observed value
+   */
+  public void subtract(double value) {
+
+    sum -= value;
+    sumSq -= value * value;
+    count --;
+  }
+
+  /**
+   * Tells the object to calculate any statistics that don't have their
+   * values automatically updated during add. Currently updates the mean
+   * and standard deviation.
+   */
+  public void calculateDerived() {
+
+    mean = Double.NaN;
+    stdDev = Double.NaN;
+    if (count > 0) {
+      mean = sum / count;
+      stdDev = Double.POSITIVE_INFINITY;
+      if (count > 1) {
+	stdDev = sumSq - (sum * sum) / count;
+	stdDev /= (count - 1);
+        if (stdDev < 0) {
+          System.err.println("Warning: stdDev value = " + stdDev 
+                             + " -- rounded to zero.");
+          stdDev = 0;
+        }
+	stdDev = Math.sqrt(stdDev);
+      }
+    }
+  }
+    
+  /**
+   * Returns a string summarising the stats so far.
+   *
+   * @return the summary string
+   */
+  public String toString() {
+
+    calculateDerived();
+    return
+      "Count   " + Utils.doubleToString(count, 8) + '\n'
+      + "Min     " + Utils.doubleToString(min, 8) + '\n'
+      + "Max     " + Utils.doubleToString(max, 8) + '\n'
+      + "Sum     " + Utils.doubleToString(sum, 8) + '\n'
+      + "SumSq   " + Utils.doubleToString(sumSq, 8) + '\n'
+      + "Mean    " + Utils.doubleToString(mean, 8) + '\n'
+      + "StdDev  " + Utils.doubleToString(stdDev, 8) + '\n';
+  }
+
+  /**
+   * Tests the paired stats object from the command line.
+   * reads line from stdin, expecting two values per line.
+   *
+   * @param args ignored.
+   */
+  public static void main(String [] args) {
+
+    try {
+      Stats ps = new Stats();
+      java.io.LineNumberReader r = new java.io.LineNumberReader(
+				   new java.io.InputStreamReader(System.in));
+      String line;
+      while ((line = r.readLine()) != null) {
+        line = line.trim();
+        if (line.equals("") || line.startsWith("@") || line.startsWith("%")) {
+          continue;
+        }
+	java.util.StringTokenizer s 
+          = new java.util.StringTokenizer(line, " ,\t\n\r\f");
+	int count = 0;
+	double v1 = 0;
+	while (s.hasMoreTokens()) {
+	  double val = (new Double(s.nextToken())).doubleValue();
+	  if (count == 0) {
+	    v1 = val;
+	  } else {
+            System.err.println("MSG: Too many values in line \"" 
+                               + line + "\", skipped.");
+	    break;
+	  }
+	  count++;
+	}
+        if (count == 1) {
+          ps.add(v1);
+        }
+      }
+      ps.calculateDerived();
+      System.err.println(ps);
+    } catch (Exception ex) {
+      ex.printStackTrace();
+      System.err.println(ex.getMessage());
+    }
+  }
+
+} // Stats
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/filters/DiscretizeFilter.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/filters/DiscretizeFilter.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/filters/DiscretizeFilter.java	(revision 20131)
@@ -0,0 +1,1292 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *    DiscretizeFilter.java
+ *    Copyright (C) 1999 Eibe Frank,Len Trigg
+ *
+ */
+
+
+package weka.filters;
+
+import java.io.*;
+import java.util.*;
+import weka.core.*;
+
+/** 
+ * An instance filter that discretizes a range of numeric attributes in 
+ * the dataset into nominal attributes. Discretization can be either by 
+ * simple binning, or by Fayyad & Irani's MDL method (the default).<p>
+ *
+ * Valid filter-specific options are: <p>
+ *
+ * -B num <br>
+ * Specifies the (maximum) number of bins to divide numeric attributes into.
+ * (default: class-based discretisation).<p>
+ *
+ * -F <br>
+ * Use equal-frequency instead of equal-width discretization if 
+ * class-based discretisation is turned off.<p>
+ *
+ * -O <br>
+ * Optimize the number of bins using a leave-one-out estimate of the 
+ * entropy (for equal-width binning).<p>
+ *
+ * -R col1,col2-col4,... <br>
+ * Specifies list of columns to Discretize. First
+ * and last are valid indexes. (default: none) <p>
+ *
+ * -V <br>
+ * Invert matching sense.<p>
+ *
+ * -D <br>
+ * Make binary nominal attributes. <p>
+ *
+ * -E <br>
+ * Use better encoding of split point for MDL. <p>
+ *   
+ * -K <br>
+ * Use Kononeko's MDL criterion. <p>
+ * 
+ * @author Len Trigg (trigg@cs.waikato.ac.nz)
+ * @author Eibe Frank (eibe@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public class DiscretizeFilter extends Filter 
+  implements OptionHandler, WeightedInstancesHandler {
+
+  /** Stores which columns to Discretize */
+  protected Range m_DiscretizeCols = new Range();
+
+  /** The number of bins to divide the attribute into */
+  protected int m_NumBins = 10;
+
+  /** Store the current cutpoints */
+  protected double [][] m_CutPoints = null;
+
+  /** True if discretisation will be done by MDL rather than binning */
+  protected boolean m_UseMDL = true;
+
+  /** Output binary attributes for discretized attributes. */
+  protected boolean m_MakeBinary = false;
+
+  /** Use better encoding of split point for MDL. */
+  protected boolean m_UseBetterEncoding = false;
+
+  /** Use Kononenko's MDL criterion instead of Fayyad et al.'s */
+  protected boolean m_UseKononenko = false;
+
+  /** Find the number of bins using cross-validated entropy. */
+  protected boolean m_FindNumBins = false;
+
+  /** Use equal-frequency binning if unsupervised discretization turned on */
+  protected boolean m_UseEqualFrequency = false;
+
+  /** Constructor - initialises the filter */
+  public DiscretizeFilter() {
+
+    setAttributeIndices("first-last");
+  }
+
+
+  /**
+   * Gets an enumeration describing the available options
+   *
+   * @return an enumeration of all the available options
+   */
+  public Enumeration listOptions() {
+
+    Vector newVector = new Vector(7);
+
+    newVector.addElement(new Option(
+              "\tSpecifies the (maximum) number of bins to divide numeric"
+	      + " attributes into.\n"
+	      + "\t(default class-based discretization)",
+              "B", 1, "-B <num>"));
+
+    newVector.addElement(new Option(
+              "\tUse equal-frequency instead of equal-width with\n"+
+	      "\tunsupervised discretization.",
+              "F", 0, "-F"));
+
+    newVector.addElement(new Option(
+              "\tOptimize number of bins using leave-one-out estimate\n"+
+	      "\tof estimated entropy (for equal-width discretization).",
+              "O", 0, "-O"));
+
+    /* If we decide to implement loading and saving cutfiles like 
+     * the C Discretizer (which is probably not necessary)
+    newVector.addElement(new Option(
+              "\tSpecify that the cutpoints should be loaded from a file.",
+              "L", 1, "-L <file>"));
+    newVector.addElement(new Option(
+              "\tSpecify that the chosen cutpoints should be saved to a file.",
+              "S", 1, "-S <file>"));
+    */
+
+    newVector.addElement(new Option(
+              "\tSpecifies list of columns to Discretize. First"
+	      + " and last are valid indexes.\n"
+	      + "\t(default none)",
+              "R", 1, "-R <col1,col2-col4,...>"));
+
+    newVector.addElement(new Option(
+              "\tInvert matching sense of column indexes.",
+              "V", 0, "-V"));
+
+    newVector.addElement(new Option(
+              "\tOutput binary attributes for discretized attributes.",
+              "D", 0, "-D"));
+
+    newVector.addElement(new Option(
+              "\tUse better encoding of split point for MDL.",
+              "E", 0, "-E"));
+
+    newVector.addElement(new Option(
+              "\tUse Kononenko's MDL criterion.",
+              "K", 0, "-K"));
+
+    return newVector.elements();
+  }
+
+
+  /**
+   * Parses the options for this object. Valid options are: <p>
+   *
+   * -B num <br>
+   * Specifies the (maximum) number of bins to divide numeric attributes into.
+   * (default class-based discretisation).<p>
+   *
+   * -F <br>
+   * Use equal-frequency instead of equal-width discretization if 
+   * class-based discretisation is turned off.<p>
+   *
+   * -O <br>
+   * Optimize the number of bins using a leave-one-out estimate of the 
+   * entropy (for equal-width binning).<p>
+   *
+   * -R col1,col2-col4,... <br>
+   * Specifies list of columns to Discretize. First
+   * and last are valid indexes. (default none) <p>
+   *
+   * -V <br>
+   * Invert matching sense.<p>
+   *
+   * -D <br>
+   * Make binary nominal attributes. <p>
+   *
+   * -E <br>
+   * Use better encoding of split point for MDL. <p>
+   *   
+   * -K <br>
+   * Use Kononeko's MDL criterion. <p>
+   * 
+   * @param options the list of options as an array of strings
+   * @exception Exception if an option is not supported
+   */
+  public void setOptions(String[] options) throws Exception {
+
+    setMakeBinary(Utils.getFlag('D', options));
+    setUseEqualFrequency(Utils.getFlag('F', options));
+    setUseBetterEncoding(Utils.getFlag('E', options));
+    setUseKononenko(Utils.getFlag('K', options));
+    setFindNumBins(Utils.getFlag('O', options));
+    setInvertSelection(Utils.getFlag('V', options));
+    setUseMDL(true);
+
+    String numBins = Utils.getOption('B', options);
+    if (numBins.length() != 0) {
+      setBins(Integer.parseInt(numBins));
+      setUseMDL(false);
+    } else {
+      setBins(10);
+    }
+    
+    String convertList = Utils.getOption('R', options);
+    if (convertList.length() != 0) {
+      setAttributeIndices(convertList);
+    } else {
+      setAttributeIndices("first-last");
+    }
+
+    if (getInputFormat() != null) {
+      setInputFormat(getInputFormat());
+    }
+  }
+  /**
+   * Gets the current settings of the filter.
+   *
+   * @return an array of strings suitable for passing to setOptions
+   */
+  public String [] getOptions() {
+
+    String [] options = new String [12];
+    int current = 0;
+
+    if (getMakeBinary()) {
+      options[current++] = "-D";
+    }
+    if (getUseEqualFrequency()) {
+      options[current++] = "-F";
+    }
+    if (getUseBetterEncoding()) {
+      options[current++] = "-E";
+    }
+    if (getUseKononenko()) {
+      options[current++] = "-K";
+    }
+    if (getFindNumBins()) {
+      options[current++] = "-O";
+    }
+    if (getInvertSelection()) {
+      options[current++] = "-V";
+    }
+    if (!getUseMDL()) {
+      options[current++] = "-B"; options[current++] = "" + getBins();
+    }
+    if (!getAttributeIndices().equals("")) {
+      options[current++] = "-R"; options[current++] = getAttributeIndices();
+    }
+    while (current < options.length) {
+      options[current++] = "";
+    }
+    return options;
+  }
+
+
+  /**
+   * Sets the format of the input instances.
+   *
+   * @param instanceInfo an Instances object containing the input instance
+   * structure (any instances contained in the object are ignored - only the
+   * structure is required).
+   * @return true if the outputFormat may be collected immediately
+   * @exception Exception if the input format can't be set successfully
+   */
+  public boolean setInputFormat(Instances instanceInfo) throws Exception {
+
+    super.setInputFormat(instanceInfo);
+
+    m_DiscretizeCols.setUpper(instanceInfo.numAttributes() - 1);
+    m_CutPoints = null;
+    if (m_UseMDL) {
+      if (instanceInfo.classIndex() < 0) {
+	throw new UnassignedClassException("Cannot use class-based discretization: "
+                                           + "no class assigned to the dataset");
+      }
+      if (!instanceInfo.classAttribute().isNominal()) {
+	throw new UnsupportedClassTypeException("Supervised discretization not possible:"
+                                                + " class is not nominal!");
+      }
+    } else {
+      if (getFindNumBins() && getUseEqualFrequency()) {
+	throw new IllegalArgumentException("Bin number optimization in conjunction "+
+					   "with equal-frequency binning not implemented.");
+      }
+    }
+
+    // If we implement loading cutfiles, then load 
+    //them here and set the output format
+    return false;
+  }
+
+  
+
+  /**
+   * Input an instance for filtering. Ordinarily the instance is processed
+   * and made available for output immediately. Some filters require all
+   * instances be read before producing output.
+   *
+   * @param instance the input instance
+   * @return true if the filtered instance may now be
+   * collected with output().
+   * @exception IllegalStateException if no input format has been defined.
+   */
+  public boolean input(Instance instance) {
+
+    if (getInputFormat() == null) {
+      throw new IllegalStateException("No input instance format defined");
+    }
+    if (m_NewBatch) {
+      resetQueue();
+      m_NewBatch = false;
+    }
+    
+    if (m_CutPoints != null) {
+      convertInstance(instance);
+      return true;
+    }
+
+    bufferInput(instance);
+    return false;
+  }
+
+
+  /**
+   * Signifies that this batch of input to the filter is finished. If the 
+   * filter requires all instances prior to filtering, output() may now 
+   * be called to retrieve the filtered instances.
+   *
+   * @return true if there are instances pending output
+   * @exception IllegalStateException if no input structure has been defined
+   */
+  public boolean batchFinished() {
+
+    if (getInputFormat() == null) {
+      throw new IllegalStateException("No input instance format defined");
+    }
+    if (m_CutPoints == null) {
+      calculateCutPoints();
+
+      setOutputFormat();
+
+      // If we implement saving cutfiles, save the cuts here
+
+      // Convert pending input instances
+      for(int i = 0; i < getInputFormat().numInstances(); i++) {
+	convertInstance(getInputFormat().instance(i));
+      }
+    } 
+    flushInput();
+
+    m_NewBatch = true;
+    return (numPendingOutput() != 0);
+  }
+
+  /**
+   * Returns a string describing this filter
+   *
+   * @return a description of the filter suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String globalInfo() {
+
+    return "An instance filter that discretizes a range of numeric"
+      + " attributes in the dataset into nominal attributes."
+      + " Discretization can be either by simple binning, or by"
+      + " Fayyad & Irani's MDL method (the default).";
+  }
+  
+  /**
+   * Returns the tip text for this property
+   *
+   * @return tip text for this property suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String findNumBinsTipText() {
+
+    return "Optimize number of equal-width bins using leave-one-out.";
+  }
+
+  /**
+   * Get the value of FindNumBins.
+   *
+   * @return Value of FindNumBins.
+   */
+  public boolean getFindNumBins() {
+    
+    return m_FindNumBins;
+  }
+  
+  /**
+   * Set the value of FindNumBins.
+   *
+   * @param newFindNumBins Value to assign to FindNumBins.
+   */
+  public void setFindNumBins(boolean newFindNumBins) {
+    
+    m_FindNumBins = newFindNumBins;
+  }
+  
+  /**
+   * Returns the tip text for this property
+   *
+   * @return tip text for this property suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String makeBinaryTipText() {
+
+    return "Make resulting attributes binary.";
+  }
+
+  /**
+   * Gets whether binary attributes should be made for discretized ones.
+   *
+   * @return true if attributes will be binarized
+   */
+  public boolean getMakeBinary() {
+
+    return m_MakeBinary;
+  }
+
+  /** 
+   * Sets whether binary attributes should be made for discretized ones.
+   *
+   * @param makeBinary if binary attributes are to be made
+   */
+  public void setMakeBinary(boolean makeBinary) {
+
+    m_MakeBinary = makeBinary;
+  }
+
+  /**
+   * Returns the tip text for this property
+   *
+   * @return tip text for this property suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String useMDLTipText() {
+
+    return "Use class-based discretization. If set to false, does"
+      + " not require a class attribute, and uses a fixed number"
+      + " of bins (according to bins setting).";
+  }
+
+  /**
+   * Gets whether MDL will be used as the discretisation method.
+   *
+   * @return true if so, false if fixed bins should be used.
+   */
+  public boolean getUseMDL() {
+
+    return m_UseMDL;
+  }
+
+  /** 
+   * Sets whether MDL will be used as the discretisation method.
+   *
+   * @param useMDL true if MDL should be used, false if fixed bins should
+   * be used.
+   */
+  public void setUseMDL(boolean useMDL) {
+
+    m_UseMDL = useMDL;
+  }
+
+  /**
+   * Returns the tip text for this property
+   *
+   * @return tip text for this property suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String useKononenkoTipText() {
+
+    return "Use Kononenko's MDL criterion. If set to false"
+      + " uses the Fayyad & Irani criterion.";
+  }
+  
+  /**
+   * Get the value of UseEqualFrequency.
+   *
+   * @return Value of UseEqualFrequency.
+   */
+  public boolean getUseEqualFrequency() {
+    
+    return m_UseEqualFrequency;
+  }
+  
+  /**
+   * Set the value of UseEqualFrequency.
+   *
+   * @param newUseEqualFrequency Value to assign to UseEqualFrequency.
+   */
+  public void setUseEqualFrequency(boolean newUseEqualFrequency) {
+    
+    m_UseEqualFrequency = newUseEqualFrequency;
+  }
+  
+  /**
+   * Gets whether Kononenko's MDL criterion is to be used.
+   *
+   * @return true if Kononenko's criterion will be used.
+   */
+  public boolean getUseKononenko() {
+
+    return m_UseKononenko;
+  }
+
+  /** 
+   * Sets whether Kononenko's MDL criterion is to be used.
+   *
+   * @param useKon true if Kononenko's one is to be used
+   */
+  public void setUseKononenko(boolean useKon) {
+
+    m_UseKononenko = useKon;
+  }
+
+  /**
+   * Returns the tip text for this property
+   *
+   * @return tip text for this property suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String useBetterEncodingTipText() {
+
+    return "Uses a more efficient split point encoding.";
+  }
+
+  /**
+   * Gets whether better encoding is to be used for MDL.
+   *
+   * @return true if the better MDL encoding will be used
+   */
+  public boolean getUseBetterEncoding() {
+
+    return m_UseBetterEncoding;
+  }
+
+  /** 
+   * Sets whether better encoding is to be used for MDL.
+   *
+   * @param useBetterEncoding true if better encoding to be used.
+   */
+  public void setUseBetterEncoding(boolean useBetterEncoding) {
+
+    m_UseBetterEncoding = useBetterEncoding;
+  }
+
+  /**
+   * Returns the tip text for this property
+   *
+   * @return tip text for this property suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String binsTipText() {
+
+    return "Number of bins for class-blind discretisation. This"
+      + " setting is ignored if MDL-based discretisation is used.";
+  }
+
+  /**
+   * Gets the number of bins numeric attributes will be divided into
+   *
+   * @return the number of bins.
+   */
+  public int getBins() {
+
+    return m_NumBins;
+  }
+
+  /**
+   * Sets the number of bins to divide each selected numeric attribute into
+   *
+   * @param numBins the number of bins
+   */
+  public void setBins(int numBins) {
+
+    m_NumBins = numBins;
+  }
+
+  /**
+   * Returns the tip text for this property
+   *
+   * @return tip text for this property suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String invertSelectionTipText() {
+
+    return "Set attribute selection mode. If false, only selected"
+      + " (numeric) attributes in the range will be discretized; if"
+      + " true, only non-selected attributes will be discretized.";
+  }
+
+  /**
+   * Gets whether the supplied columns are to be removed or kept
+   *
+   * @return true if the supplied columns will be kept
+   */
+  public boolean getInvertSelection() {
+
+    return m_DiscretizeCols.getInvert();
+  }
+
+  /**
+   * Sets whether selected columns should be removed or kept. If true the 
+   * selected columns are kept and unselected columns are deleted. If false
+   * selected columns are deleted and unselected columns are kept.
+   *
+   * @param invert the new invert setting
+   */
+  public void setInvertSelection(boolean invert) {
+
+    m_DiscretizeCols.setInvert(invert);
+  }
+
+  /**
+   * Returns the tip text for this property
+   *
+   * @return tip text for this property suitable for
+   * displaying in the explorer/experimenter gui
+   */
+  public String attributeIndicesTipText() {
+    return "Specify range of attributes to act on."
+      + " This is a comma separated list of attribute indices, with"
+      + " \"first\" and \"last\" valid values. Specify an inclusive"
+      + " range with \"-\". E.g: \"first-3,5,6-10,last\".";
+  }
+
+  /**
+   * Gets the current range selection
+   *
+   * @return a string containing a comma separated list of ranges
+   */
+  public String getAttributeIndices() {
+
+    return m_DiscretizeCols.getRanges();
+  }
+
+  /**
+   * Sets which attributes are to be Discretized (only numeric
+   * attributes among the selection will be Discretized).
+   *
+   * @param rangeList a string representing the list of attributes. Since
+   * the string will typically come from a user, attributes are indexed from
+   * 1. <br>
+   * eg: first-3,5,6-last
+   * @exception IllegalArgumentException if an invalid range list is supplied 
+   */
+  public void setAttributeIndices(String rangeList) {
+
+    m_DiscretizeCols.setRanges(rangeList);
+  }
+
+  /**
+   * Sets which attributes are to be Discretized (only numeric
+   * attributes among the selection will be Discretized).
+   *
+   * @param attributes an array containing indexes of attributes to Discretize.
+   * Since the array will typically come from a program, attributes are indexed
+   * from 0.
+   * @exception IllegalArgumentException if an invalid set of ranges
+   * is supplied 
+   */
+  public void setAttributeIndicesArray(int [] attributes) {
+
+    setAttributeIndices(Range.indicesToRangeList(attributes));
+  }
+
+  /**
+   * Gets the cut points for an attribute
+   *
+   * @param the index (from 0) of the attribute to get the cut points of
+   * @return an array containing the cutpoints (or null if the
+   * attribute requested isn't being Discretized
+   */
+  public double [] getCutPoints(int attributeIndex) {
+
+    if (m_CutPoints == null) {
+      return null;
+    }
+    return m_CutPoints[attributeIndex];
+  }
+
+  /** Generate the cutpoints for each attribute */
+  protected void calculateCutPoints() {
+
+    Instances copy = null;
+
+    m_CutPoints = new double [getInputFormat().numAttributes()] [];
+    for(int i = getInputFormat().numAttributes() - 1; i >= 0; i--) {
+      if ((m_DiscretizeCols.isInRange(i)) && 
+	  (getInputFormat().attribute(i).isNumeric())) {
+	if (m_UseMDL) {
+
+	  // Use copy to preserve order
+	  if (copy == null) {
+	    copy = new Instances(getInputFormat());
+	  }
+	  calculateCutPointsByMDL(i, copy);
+	} else {
+	  if (m_FindNumBins) {
+	    findNumBins(i);
+	  } else if (!m_UseEqualFrequency) {
+	    calculateCutPointsByEqualWidthBinning(i);
+	  } else {
+	    calculateCutPointsByEqualFrequencyBinning(i);
+	  }
+	}
+      }
+    }
+  }
+
+  /**
+   * Set cutpoints for a single attribute using MDL.
+   *
+   * @param index the index of the attribute to set cutpoints for
+   */
+  protected void calculateCutPointsByMDL(int index,
+					 Instances data) {
+
+    // Sort instances
+    data.sort(data.attribute(index));
+
+    // Find first instances that's missing
+    int firstMissing = data.numInstances();
+    for (int i = 0; i < data.numInstances(); i++) {
+      if (data.instance(i).isMissing(index)) {
+        firstMissing = i;
+        break;
+      }
+    }
+    m_CutPoints[index] = cutPointsForSubset(data, index, 0, firstMissing);
+  }
+
+  /** Test using Kononenko's MDL criterion. */
+  private boolean KononenkosMDL(double[] priorCounts,
+				double[][] bestCounts,
+				double numInstances,
+				int numCutPoints) {
+
+    double distPrior, instPrior, distAfter = 0, sum, instAfter = 0;
+    double before, after;
+    int numClassesTotal;
+
+    // Number of classes occuring in the set
+    numClassesTotal = 0;
+    for (int i = 0; i < priorCounts.length; i++) {
+      if (priorCounts[i] > 0) {
+	numClassesTotal++;
+      }
+    }
+
+    // Encode distribution prior to split
+    distPrior = SpecialFunctions.log2Binomial(numInstances 
+					      + numClassesTotal - 1,
+					      numClassesTotal - 1);
+
+    // Encode instances prior to split.
+    instPrior = SpecialFunctions.log2Multinomial(numInstances,
+						 priorCounts);
+
+    before = instPrior + distPrior;
+
+    // Encode distributions and instances after split.
+    for (int i = 0; i < bestCounts.length; i++) {
+      sum = Utils.sum(bestCounts[i]);
+      distAfter += SpecialFunctions.log2Binomial(sum + numClassesTotal - 1,
+						 numClassesTotal - 1);
+      instAfter += SpecialFunctions.log2Multinomial(sum,
+						    bestCounts[i]);
+    }
+
+    // Coding cost after split
+    after = Utils.log2(numCutPoints) + distAfter + instAfter;
+
+    // Check if split is to be accepted
+    return (Utils.gr(before, after));
+  }
+
+
+  /** Test using Fayyad and Irani's MDL criterion. */
+  private boolean FayyadAndIranisMDL(double[] priorCounts,
+				     double[][] bestCounts,
+				     double numInstances,
+				     int numCutPoints) {
+
+    double priorEntropy, entropy, gain; 
+    double entropyLeft, entropyRight, delta;
+    int numClassesTotal, numClassesRight, numClassesLeft;
+
+    // Compute entropy before split.
+    priorEntropy = ContingencyTables.entropy(priorCounts);
+
+    // Compute entropy after split.
+    entropy = ContingencyTables.entropyConditionedOnRows(bestCounts);
+
+    // Compute information gain.
+    gain = priorEntropy - entropy;
+
+    // Number of classes occuring in the set
+    numClassesTotal = 0;
+    for (int i = 0; i < priorCounts.length; i++) {
+      if (priorCounts[i] > 0) {
+	numClassesTotal++;
+      }
+    }
+
+    // Number of classes occuring in the left subset
+    numClassesLeft = 0;
+    for (int i = 0; i < bestCounts[0].length; i++) {
+      if (bestCounts[0][i] > 0) {
+	numClassesLeft++;
+      }
+    }
+
+    // Number of classes occuring in the right subset
+    numClassesRight = 0;
+    for (int i = 0; i < bestCounts[1].length; i++) {
+      if (bestCounts[1][i] > 0) {
+	numClassesRight++;
+      }
+    }
+
+    // Entropy of the left and the right subsets
+    entropyLeft = ContingencyTables.entropy(bestCounts[0]);
+    entropyRight = ContingencyTables.entropy(bestCounts[1]);
+
+    // Compute terms for MDL formula
+    delta = Utils.log2(Math.pow(3, numClassesTotal) - 2) - 
+      (((double) numClassesTotal * priorEntropy) - 
+       (numClassesRight * entropyRight) - 
+       (numClassesLeft * entropyLeft));
+
+    // Check if split is to be accepted
+    return (Utils.gr(gain, (Utils.log2(numCutPoints) + delta) /
+		     (double)numInstances));
+  }
+    
+
+  /** Selects cutpoints for sorted subset. */
+  private double[] cutPointsForSubset(Instances instances, int attIndex, 
+				      int first, int lastPlusOne) { 
+
+    double[][] counts, bestCounts;
+    double[] priorCounts, left, right, cutPoints;
+    double currentCutPoint = -Double.MAX_VALUE, bestCutPoint = -1, 
+      currentEntropy, bestEntropy, priorEntropy, gain;
+    int bestIndex = -1, numInstances = 0, numCutPoints = 0;
+
+    // Compute number of instances in set
+    if ((lastPlusOne - first) < 2) {
+      return null;
+    }
+
+    // Compute class counts.
+    counts = new double[2][instances.numClasses()];
+    for (int i = first; i < lastPlusOne; i++) {
+      numInstances += instances.instance(i).weight();
+      counts[1][(int)instances.instance(i).classValue()] +=
+	instances.instance(i).weight();
+    }
+
+    // Save prior counts
+    priorCounts = new double[instances.numClasses()];
+    System.arraycopy(counts[1], 0, priorCounts, 0, 
+		     instances.numClasses());
+
+    // Entropy of the full set
+    priorEntropy = ContingencyTables.entropy(priorCounts);
+    bestEntropy = priorEntropy;
+    
+    // Find best entropy.
+    bestCounts = new double[2][instances.numClasses()];
+    for (int i = first; i < (lastPlusOne - 1); i++) {
+      counts[0][(int)instances.instance(i).classValue()] +=
+	instances.instance(i).weight();
+      counts[1][(int)instances.instance(i).classValue()] -=
+	instances.instance(i).weight();
+      if (Utils.sm(instances.instance(i).value(attIndex), 
+		   instances.instance(i + 1).value(attIndex))) {
+	currentCutPoint = instances.instance(i).value(attIndex); //+ 
+	//instances.instance(i + 1).value(attIndex)) / 2.0;
+	currentEntropy = ContingencyTables.entropyConditionedOnRows(counts);
+	if (Utils.sm(currentEntropy, bestEntropy)) {
+	  bestCutPoint = currentCutPoint;
+	  bestEntropy = currentEntropy;
+	  bestIndex = i;
+	  System.arraycopy(counts[0], 0, 
+			   bestCounts[0], 0, instances.numClasses());
+	  System.arraycopy(counts[1], 0, 
+			   bestCounts[1], 0, instances.numClasses()); 
+	}
+	numCutPoints++;
+      }
+    }
+
+    // Use worse encoding?
+    if (!m_UseBetterEncoding) {
+      numCutPoints = (lastPlusOne - first) - 1;
+    }
+
+    // Checks if gain is zero
+    gain = priorEntropy - bestEntropy;
+    if (Utils.eq(gain, 0)) {
+      return null;
+    }
+
+    // Check if split is to be accepted
+    if ((m_UseKononenko && KononenkosMDL(priorCounts, bestCounts,
+					 numInstances, numCutPoints)) ||
+	(!m_UseKononenko && FayyadAndIranisMDL(priorCounts, bestCounts,
+					       numInstances, numCutPoints))) {
+      
+      // Select split points for the left and right subsets
+      left = cutPointsForSubset(instances, attIndex, first, bestIndex + 1);
+      right = cutPointsForSubset(instances, attIndex, 
+				 bestIndex + 1, lastPlusOne);
+      
+      // Merge cutpoints and return them
+      if ((left == null) && (right) == null) {
+	cutPoints = new double[1];
+	cutPoints[0] = bestCutPoint;
+      } else if (right == null) {
+	cutPoints = new double[left.length + 1];
+	System.arraycopy(left, 0, cutPoints, 0, left.length);
+	cutPoints[left.length] = bestCutPoint;
+      } else if (left == null) {
+	cutPoints = new double[1 + right.length];
+	cutPoints[0] = bestCutPoint;
+	System.arraycopy(right, 0, cutPoints, 1, right.length);
+      } else {
+	cutPoints =  new double[left.length + right.length + 1];
+	cutPoints = new double[left.length + right.length + 1];
+	System.arraycopy(left, 0, cutPoints, 0, left.length);
+	cutPoints[left.length] = bestCutPoint;
+	System.arraycopy(right, 0, cutPoints, left.length + 1, right.length);
+      }
+      
+      return cutPoints;
+    } else
+      return null;
+  }
+ 
+  /**
+   * Set cutpoints for a single attribute.
+   *
+   * @param index the index of the attribute to set cutpoints for
+   */
+  protected void calculateCutPointsByEqualWidthBinning(int index) {
+
+    // Scan for max and min values
+    double max = 0, min = 1, currentVal;
+    Instance currentInstance;
+    for(int i = 0; i < getInputFormat().numInstances(); i++) {
+      currentInstance = getInputFormat().instance(i);
+      if (!currentInstance.isMissing(index)) {
+	currentVal = currentInstance.value(index);
+	if (max < min) {
+	  max = min = currentVal;
+	}
+	if (currentVal > max) {
+	  max = currentVal;
+	}
+	if (currentVal < min) {
+	  min = currentVal;
+	}
+      }
+    }
+    double binWidth = (max - min) / m_NumBins;
+    double [] cutPoints = null;
+    if ((m_NumBins > 1) && (binWidth > 0)) {
+      cutPoints = new double [m_NumBins - 1];
+      for(int i = 1; i < m_NumBins; i++) {
+	cutPoints[i - 1] = min + binWidth * i;
+      }
+    }
+    m_CutPoints[index] = cutPoints;
+  }
+ 
+  /**
+   * Set cutpoints for a single attribute.
+   *
+   * @param index the index of the attribute to set cutpoints for
+   */
+  protected void calculateCutPointsByEqualFrequencyBinning(int index) {
+
+    // Copy data so that it can be sorted
+    Instances data = new Instances(getInputFormat());
+
+    // Sort input data
+    data.sort(index);
+
+    // Compute weight of instances without missing values
+    double sumOfWeights = 0;
+    for (int i = 0; i < data.numInstances(); i++) {
+      if (data.instance(i).isMissing(index)) {
+	break;
+      } else {
+	sumOfWeights += data.instance(i).weight();
+      }
+    }
+    double freq = sumOfWeights / m_NumBins;
+
+    // Compute break points
+    double[] cutPoints = new double[m_NumBins - 1];
+    double counter = 0;
+    int cpindex = 0;
+    for (int i = 0; i < data.numInstances() - 1; i++) {
+
+      // Stop if value missing
+      if (data.instance(i).isMissing(index)) {
+	break;
+      }
+      counter += data.instance(i).weight();
+
+      // Do we have a potential breakpoint?
+      if (data.instance(i).value(index) < 
+	  data.instance(i + 1).value(index)) {
+	if (counter >= freq) {
+	  cutPoints[cpindex] = (data.instance(i).value(index) +
+				data.instance(i + 1).value(index)) / 2;
+	  cpindex++;
+	  counter = counter - freq;
+	}
+      }
+    }
+
+    // Did we find any cutpoints?
+    if (cpindex == 0) {
+      m_CutPoints[index] = null;
+    } else {
+      double[] cp = new double[cpindex];
+      for (int i = 0; i < cpindex; i++) {
+	cp[i] = cutPoints[i];
+      }
+      m_CutPoints[index] = cp;
+    }
+  }
+
+  /**
+   * Optimizes the number of bins using leave-one-out cross-validation.
+   *
+   * @param index the attribute index
+   */
+  protected void findNumBins(int index) {
+
+    double min = Double.MAX_VALUE, max = -Double.MIN_VALUE, binWidth = 0, 
+      entropy, bestEntropy = Double.MAX_VALUE, currentVal;
+    double[] distribution;
+    int bestNumBins  = 1;
+    Instance currentInstance;
+
+    // Find minimum and maximum
+    for (int i = 0; i < getInputFormat().numInstances(); i++) {
+      currentInstance = getInputFormat().instance(i);
+      if (!currentInstance.isMissing(index)) {
+	currentVal = currentInstance.value(index);
+	if (currentVal > max) {
+	  max = currentVal;
+	}
+	if (currentVal < min) {
+	  min = currentVal;
+	}
+      }
+    }
+
+    // Find best number of bins
+    for (int i = 0; i < m_NumBins; i++) {
+      distribution = new double[i + 1];
+      binWidth = (max - min) / (i + 1);
+
+      // Compute distribution
+      for (int j = 0; j < getInputFormat().numInstances(); j++) {
+	currentInstance = getInputFormat().instance(j);
+	if (!currentInstance.isMissing(index)) {
+	  for (int k = 0; k < i + 1; k++) {
+	    if (currentInstance.value(index) <= 
+		(min + (((double)k + 1) * binWidth))) {
+	      distribution[k] += currentInstance.weight();
+	      break;
+	    }
+	  }
+	}
+      }
+
+      // Compute cross-validated entropy
+      entropy = 0;
+      for (int k = 0; k < i + 1; k++) {
+	if (distribution[k] < 2) {
+	  entropy = Double.MAX_VALUE;
+	  break;
+	}
+	entropy -= distribution[k] * Math.log((distribution[k] - 1) / 
+					      binWidth);
+      }
+
+      // Best entropy so far?
+      if (entropy < bestEntropy) {
+	bestEntropy = entropy;
+	bestNumBins = i + 1;
+      }
+    }
+
+    // Compute cut points
+    double [] cutPoints = null;
+    if ((bestNumBins > 1) && (binWidth > 0)) {
+      cutPoints = new double [bestNumBins - 1];
+      for(int i = 1; i < bestNumBins; i++) {
+	cutPoints[i - 1] = min + binWidth * i;
+      }
+    }
+    m_CutPoints[index] = cutPoints;
+   }
+
+  /**
+   * Set the output format. Takes the currently defined cutpoints and 
+   * m_InputFormat and calls setOutputFormat(Instances) appropriately.
+   */
+  protected void setOutputFormat() {
+
+    if (m_CutPoints == null) {
+      setOutputFormat(null);
+      return;
+    }
+    FastVector attributes = new FastVector(getInputFormat().numAttributes());
+    int classIndex = getInputFormat().classIndex();
+    for(int i = 0; i < getInputFormat().numAttributes(); i++) {
+      if ((m_DiscretizeCols.isInRange(i)) 
+	  && (getInputFormat().attribute(i).isNumeric())) {
+	if (!m_MakeBinary) {
+	  FastVector attribValues = new FastVector(1);
+	  if (m_CutPoints[i] == null) {
+	    attribValues.addElement("'All'");
+	  } else {
+	    for(int j = 0; j <= m_CutPoints[i].length; j++) {
+	      if (j == 0) {
+		attribValues.addElement("'(-inf-"
+			+ Utils.doubleToString(m_CutPoints[i][j], 6) + "]'");
+	      } else if (j == m_CutPoints[i].length) {
+		attribValues.addElement("'("
+			+ Utils.doubleToString(m_CutPoints[i][j - 1], 6) 
+					+ "-inf)'");
+	      } else {
+		attribValues.addElement("'("
+			+ Utils.doubleToString(m_CutPoints[i][j - 1], 6) + "-"
+			+ Utils.doubleToString(m_CutPoints[i][j], 6) + "]'");
+	      }
+	    }
+	  }
+	  attributes.addElement(new Attribute(getInputFormat().
+					      attribute(i).name(),
+					      attribValues));
+	} else {
+	  if (m_CutPoints[i] == null) {
+	    FastVector attribValues = new FastVector(1);
+	    attribValues.addElement("'All'");
+	    attributes.addElement(new Attribute(getInputFormat().
+						attribute(i).name(),
+						attribValues));
+	  } else {
+	    if (i < getInputFormat().classIndex()) {
+	      classIndex += m_CutPoints[i].length - 1;
+	    }
+	    for(int j = 0; j < m_CutPoints[i].length; j++) {
+	      FastVector attribValues = new FastVector(2);
+	      attribValues.addElement("'(-inf-"
+		      + Utils.doubleToString(m_CutPoints[i][j], 6) + "]'");
+	      attribValues.addElement("'("
+		      + Utils.doubleToString(m_CutPoints[i][j], 6) + "-inf)'");
+	      attributes.addElement(new Attribute(getInputFormat().
+						  attribute(i).name(),
+						  attribValues));
+	    }
+	  }
+	}
+      } else {
+	attributes.addElement(getInputFormat().attribute(i).copy());
+      }
+    }
+    Instances outputFormat = 
+      new Instances(getInputFormat().relationName(), attributes, 0);
+    outputFormat.setClassIndex(classIndex);
+    setOutputFormat(outputFormat);
+  }
+
+  /**
+   * Convert a single instance over. The converted instance is added to 
+   * the end of the output queue.
+   *
+   * @param instance the instance to convert
+   */
+  protected void convertInstance(Instance instance) {
+
+    int index = 0;
+    double [] vals = new double [outputFormatPeek().numAttributes()];
+    // Copy and convert the values
+    for(int i = 0; i < getInputFormat().numAttributes(); i++) {
+      if (m_DiscretizeCols.isInRange(i) && 
+	  getInputFormat().attribute(i).isNumeric()) {
+	int j;
+	double currentVal = instance.value(i);
+	if (m_CutPoints[i] == null) {
+	  if (instance.isMissing(i)) {
+	    vals[index] = Instance.missingValue();
+	  } else {
+	    vals[index] = 0;
+	  }
+	  index++;
+	} else {
+	  if (!m_MakeBinary) {
+	    if (instance.isMissing(i)) {
+	      vals[index] = Instance.missingValue();
+	    } else {
+	      for (j = 0; j < m_CutPoints[i].length; j++) {
+		if (currentVal <= m_CutPoints[i][j]) {
+		  break;
+		}
+	      }
+              vals[index] = j;
+	    }
+	    index++;
+	  } else {
+	    for (j = 0; j < m_CutPoints[i].length; j++) {
+	      if (instance.isMissing(i)) {
+                vals[index] = Instance.missingValue();
+	      } else if (currentVal <= m_CutPoints[i][j]) {
+                vals[index] = 0;
+	      } else {
+                vals[index] = 1;
+	      }
+	      index++;
+	    }
+	  }   
+	}
+      } else {
+        vals[index] = instance.value(i);
+	index++;
+      }
+    }
+    
+    Instance inst = null;
+    if (instance instanceof SparseInstance) {
+      inst = new SparseInstance(instance.weight(), vals);
+    } else {
+      inst = new Instance(instance.weight(), vals);
+    }
+    copyStringValues(inst, false, instance.dataset(), getInputStringIndex(),
+                     getOutputFormat(), getOutputStringIndex());
+    inst.setDataset(getOutputFormat());
+    push(inst);
+  }
+
+  /**
+   * Main method for testing this class.
+   *
+   * @param argv should contain arguments to the filter: use -h for help
+   */
+  public static void main(String [] argv) {
+
+    try {
+      if (Utils.getFlag('b', argv)) {
+ 	Filter.batchFilterFile(new DiscretizeFilter(), argv);
+      } else {
+	Filter.filterFile(new DiscretizeFilter(), argv);
+      }
+    } catch (Exception ex) {
+      System.out.println(ex.getMessage());
+    }
+  }
+}
+
+
+
+
+
+
+
+
Index: /gsdl/stable/build-src/packages/kea/kea-3.0/weka/filters/Filter.java
===================================================================
--- /gsdl/stable/build-src/packages/kea/kea-3.0/weka/filters/Filter.java	(revision 20131)
+++ /gsdl/stable/build-src/packages/kea/kea-3.0/weka/filters/Filter.java	(revision 20131)
@@ -0,0 +1,934 @@
+/*
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ *    Filter.java
+ *    Copyright (C) 1999 Len Trigg
+ *
+ */
+
+
+package weka.filters;
+
+import java.io.BufferedReader;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Serializable;
+import java.util.Enumeration;
+import weka.core.Attribute;
+import weka.core.Instance;
+import weka.core.Instances;
+import weka.core.Option;
+import weka.core.OptionHandler;
+import weka.core.Queue;
+import weka.core.Utils;
+
+/** 
+ * An abstract class for instance filters: objects that take instances
+ * as input, carry out some transformation on the instance and then
+ * output the instance. The method implementations in this class
+ * assume that most of the work will be done in the methods overridden
+ * by subclasses.<p>
+ *
+ * A simple example of filter use. This example doesn't remove
+ * instances from the output queue until all instances have been
+ * input, so has higher memory consumption than an approach that
+ * uses output instances as they are made available:<p>
+ *
+ * <code> <pre>
+ *  Filter filter = ..some type of filter..
+ *  Instances instances = ..some instances..
+ *  for (int i = 0; i < data.numInstances(); i++) {
+ *    filter.input(data.instance(i));
+ *  }
+ *  filter.batchFinished();
+ *  Instances newData = filter.outputFormat();
+ *  Instance processed;
+ *  while ((processed = filter.output()) != null) {
+ *    newData.add(processed);
+ *  }
+ *  ..do something with newData..
+ * </pre> </code>
+ *
+ * @author Len Trigg (trigg@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public abstract class Filter implements Serializable {
+
+  /*
+   * Filter refactoring TODO:
+   *
+   * - Update all filters to use getOutputFormat and setInputFormat
+   * instead of outputFormat, outputFormatPeek and inputFormat.
+   * - Update users of filters to use getOutputFormat and setInputFormat
+   * - remove outputFormat, outputFormatPeek and inputFormat
+   *
+   */
+
+  /** Debugging mode */
+  private boolean m_Debug = false;
+
+  /** The output format for instances */
+  private Instances m_OutputFormat = null;
+
+  /** The output instance queue */
+  private Queue m_OutputQueue = null;
+
+  /** Indices of string attributes in the output format */
+  private int [] m_OutputStringAtts = null;
+
+  /** Indices of string attributes in the input format */
+  private int [] m_InputStringAtts = null;
+
+  /** The input format for instances */
+  private Instances m_InputFormat = null;
+
+  /** Record whether the filter is at the start of a batch */
+  protected boolean m_NewBatch = true;
+
+  /**
+   * Sets the format of output instances. The derived class should use this
+   * method once it has determined the outputformat. The 
+   * output queue is cleared.
+   *
+   * @param outputFormat the new output format
+   */
+  protected void setOutputFormat(Instances outputFormat) {
+
+    if (outputFormat != null) {
+      m_OutputFormat = outputFormat.stringFreeStructure();
+      m_OutputStringAtts = getStringIndices(m_OutputFormat);
+
+      // Rename the attribute
+      String relationName = outputFormat.relationName() 
+        + "-" + this.getClass().getName();
+      if (this instanceof OptionHandler) {
+        String [] options = ((OptionHandler)this).getOptions();
+        for (int i = 0; i < options.length; i++) {
+          relationName += options[i].trim();
+        }
+      }
+      m_OutputFormat.setRelationName(relationName);
+    } else {
+      m_OutputFormat = null;
+    }
+    m_OutputQueue = new Queue();
+  }
+
+  /**
+   * Gets the currently set inputformat instances. This dataset may contain
+   * buffered instances.
+   *
+   * @return the input Instances.
+   */
+  protected Instances getInputFormat() {
+
+    return m_InputFormat;
+  }
+
+  /**
+   * Returns a reference to the current output format without
+   * copying it.
+   *
+   * @return a reference to the current output format
+   */
+  protected Instances outputFormatPeek() {
+
+    return m_OutputFormat;
+  }
+
+  /**
+   * Adds an output instance to the queue. The derived class should use this
+   * method for each output instance it makes available. 
+   *
+   * @param instance the instance to be added to the queue
+   */
+  protected void push(Instance instance) {
+
+    if (instance != null) {
+      copyStringValues(instance, m_OutputFormat, m_OutputStringAtts);
+      instance.setDataset(m_OutputFormat);
+      m_OutputQueue.push(instance);
+    }
+  }
+
+  /**
+   * Clears the output queue.
+   */
+  protected void resetQueue() {
+
+    m_OutputQueue = new Queue();
+  }
+
+  /**
+   * Adds the supplied input instance to the inputformat dataset for
+   * later processing.  Use this method rather than
+   * getInputFormat().add(instance). Or else.
+   *
+   * @param instance the <code>Instance</code> to buffer.  
+   */
+  protected void bufferInput(Instance instance) {
+
+    if (instance != null) {
+      copyStringValues(instance, m_InputFormat, m_InputStringAtts);
+      instance.setDataset(m_InputFormat);
+      m_InputFormat.add(instance);
+    }
+  }
+
+  /**
+   * Returns an array containing the indices of all string attributes in the
+   * input format. This index is created during setInputFormat()
+   *
+   * @return an array containing the indices of string attributes in the 
+   * input dataset.
+   */
+  protected int [] getInputStringIndex() {
+
+    return m_InputStringAtts;
+  }
+
+  /**
+   * Returns an array containing the indices of all string attributes in the
+   * output format. This index is created during setOutputFormat()
+   *
+   * @return an array containing the indices of string attributes in the 
+   * output dataset.
+   */
+  protected int [] getOutputStringIndex() {
+
+    return m_OutputStringAtts;
+  }
+
+  /**
+   * Copies string values contained in the instance copied to a new
+   * dataset. The Instance must already be assigned to a dataset. This
+   * dataset and the destination dataset must have the same structure.
+   *
+   * @param instance the Instance containing the string values to copy.
+   * @param destDataset the destination set of Instances
+   * @param strAtts an array containing the indices of any string attributes
+   * in the dataset.  
+   */
+  private void copyStringValues(Instance inst, Instances destDataset, 
+                                int []strAtts) {
+
+    if (strAtts.length == 0) {
+      return;
+    }
+    if (inst.dataset() == null) {
+      throw new IllegalArgumentException("Instance has no dataset assigned!!");
+    } else if (inst.dataset().numAttributes() != destDataset.numAttributes()) {
+      throw new IllegalArgumentException("Src and Dest differ in # of attributes!!");
+    } 
+    copyStringValues(inst, true, inst.dataset(), strAtts,
+                     destDataset, strAtts);
+  }
+
+  /**
+   * Takes string values referenced by an Instance and copies them from a
+   * source dataset to a destination dataset. The instance references are
+   * updated to be valid for the destination dataset. The instance may have the 
+   * structure (i.e. number and attribute position) of either dataset (this
+   * affects where references are obtained from). The source dataset must
+   * have the same structure as the filter input format and the destination
+   * must have the same structure as the filter output format.
+   *
+   * @param instance the instance containing references to strings in the source
+   * dataset that will have references updated to be valid for the destination
+   * dataset.
+   * @param instSrcCompat true if the instance structure is the same as the
+   * source, or false if it is the same as the destination
+   * @param srcDataset the dataset for which the current instance string
+   * references are valid (after any position mapping if needed)
+   * @param destDataset the dataset for which the current instance string
+   * references need to be inserted (after any position mapping if needed)
+   */
+  protected void copyStringValues(Instance instance, boolean instSrcCompat,
+                                  Instances srcDataset, Instances destDataset) {
+
+    copyStringValues(instance, instSrcCompat, srcDataset, m_InputStringAtts,
+                     destDataset, m_OutputStringAtts);
+  }
+
+  /**
+   * Takes string values referenced by an Instance and copies them from a
+   * source dataset to a destination dataset. The instance references are
+   * updated to be valid for the destination dataset. The instance may have the 
+   * structure (i.e. number and attribute position) of either dataset (this
+   * affects where references are obtained from). Only works if the number
+   * of string attributes is the same in both indices (implicitly these string
+   * attributes should be semantically same but just with shifted positions).
+   *
+   * @param instance the instance containing references to strings in the source
+   * dataset that will have references updated to be valid for the destination
+   * dataset.
+   * @param instSrcCompat true if the instance structure is the same as the
+   * source, or false if it is the same as the destination (i.e. which of the
+   * string attribute indices contains the correct locations for this instance).
+   * @param srcDataset the dataset for which the current instance string
+   * references are valid (after any position mapping if needed)
+   * @param srcStrAtts an array containing the indices of string attributes
+   * in the source datset.
+   * @param destDataset the dataset for which the current instance string
+   * references need to be inserted (after any position mapping if needed)
+   * @param destStrAtts an array containing the indices of string attributes
+   * in the destination datset.
+   */
+  protected void copyStringValues(Instance instance, boolean instSrcCompat,
+                                  Instances srcDataset, int []srcStrAtts,
+                                  Instances destDataset, int []destStrAtts) {
+    if (srcDataset == destDataset) {
+      return;
+    }
+    if (srcStrAtts.length != destStrAtts.length) {
+      throw new IllegalArgumentException("Src and Dest string indices differ in length!!");
+    }
+    for (int i = 0; i < srcStrAtts.length; i++) {
+      int instIndex = instSrcCompat ? srcStrAtts[i] : destStrAtts[i];
+      Attribute src = srcDataset.attribute(srcStrAtts[i]);
+      Attribute dest = destDataset.attribute(destStrAtts[i]);
+      if (!instance.isMissing(instIndex)) {
+        //System.err.println(instance.value(srcIndex) 
+        //                   + " " + src.numValues()
+        //                   + " " + dest.numValues());
+        int valIndex = dest.addStringValue(src, (int)instance.value(instIndex));
+        // setValue here shouldn't be too slow here unless your dataset has
+        // squillions of string attributes
+        instance.setValue(instIndex, (double)valIndex);
+      }
+    }
+  }
+
+  /**
+   * This will remove all buffered instances from the inputformat dataset.
+   * Use this method rather than getInputFormat().delete();
+   */
+  protected void flushInput() {
+
+    if (m_InputStringAtts.length > 0) {
+      m_InputFormat = m_InputFormat.stringFreeStructure();
+    } else {
+      // This more efficient than new Instances(m_InputFormat, 0);
+      m_InputFormat.delete();
+    }
+  }
+
+  /**
+   * @deprecated use <code>setInputFormat(Instances)</code> instead.
+   */
+  public boolean inputFormat(Instances instanceInfo) throws Exception {
+
+    return setInputFormat(instanceInfo);
+  }
+
+  /**
+   * Sets the format of the input instances. If the filter is able to
+   * determine the output format before seeing any input instances, it
+   * does so here. This default implementation clears the output format
+   * and output queue, and the new batch flag is set. Overriders should
+   * call <code>super.setInputFormat(Instances)</code>
+   *
+   * @param instanceInfo an Instances object containing the input instance
+   * structure (any instances contained in the object are ignored - only the
+   * structure is required).
+   * @return true if the outputFormat may be collected immediately
+   * @exception Exception if the inputFormat can't be set successfully 
+   */
+  public boolean setInputFormat(Instances instanceInfo) throws Exception {
+
+    m_InputFormat = instanceInfo.stringFreeStructure();
+    m_InputStringAtts = getStringIndices(instanceInfo);
+    m_OutputFormat = null;
+    m_OutputQueue = new Queue();
+    m_NewBatch = true;
+    return false;
+  }
+
+  /**
+   * @deprecated use <code>getOutputFormat()</code> instead.
+   */
+  public final Instances outputFormat() {
+
+    return getOutputFormat();
+  }
+
+  /**
+   * Gets the format of the output instances. This should only be called
+   * after input() or batchFinished() has returned true. The relation
+   * name of the output instances should be changed to reflect the
+   * action of the filter (eg: add the filter name and options).
+   *
+   * @return an Instances object containing the output instance
+   * structure only.
+   * @exception NullPointerException if no input structure has been
+   * defined (or the output format hasn't been determined yet) 
+   */
+  public final Instances getOutputFormat() {
+
+    if (m_OutputFormat == null) {
+      throw new NullPointerException("No output format defined.");
+    }
+    return new Instances(m_OutputFormat, 0);
+  }
+
+  /**
+   * Input an instance for filtering. Ordinarily the instance is
+   * processed and made available for output immediately. Some filters
+   * require all instances be read before producing output, in which
+   * case output instances should be collected after calling
+   * batchFinished(). If the input marks the start of a new batch, the
+   * output queue is cleared. This default implementation assumes all
+   * instance conversion will occur when batchFinished() is called.
+   *
+   * @param instance the input instance
+   * @return true if the filtered instance may now be
+   * collected with output().
+   * @exception NullPointerException if the input format has not been
+   * defined.
+   * @exception Exception if the input instance was not of the correct 
+   * format or if there was a problem with the filtering.  
+   */
+  public boolean input(Instance instance) throws Exception {
+
+    if (m_InputFormat == null) {
+      throw new NullPointerException("No input instance format defined");
+    }
+    if (m_NewBatch) {
+      m_OutputQueue = new Queue();
+      m_NewBatch = false;
+    }
+    bufferInput(instance);
+    return false;
+  }
+
+  /**
+   * Signify that this batch of input to the filter is finished. If
+   * the filter requires all instances prior to filtering, output()
+   * may now be called to retrieve the filtered instances. Any
+   * subsequent instances filtered should be filtered based on setting
+   * obtained from the first batch (unless the inputFormat has been
+   * re-assigned or new options have been set). This default
+   * implementation assumes all instance processing occurs during
+   * inputFormat() and input().
+   *
+   * @return true if there are instances pending output
+   * @exception NullPointerException if no input structure has been defined,
+   * @exception Exception if there was a problem finishing the batch.
+   */
+  public boolean batchFinished() throws Exception {
+
+    if (m_InputFormat == null) {
+      throw new NullPointerException("No input instance format defined");
+    }
+    flushInput();
+    m_NewBatch = true;
+    return (numPendingOutput() != 0);
+  }
+
+
+  /**
+   * Output an instance after filtering and remove from the output queue.
+   *
+   * @return the instance that has most recently been filtered (or null if
+   * the queue is empty).
+   * @exception NullPointerException if no output structure has been defined
+   */
+  public Instance output() {
+
+    if (m_OutputFormat == null) {
+      throw new NullPointerException("No output instance format defined");
+    }
+    if (m_OutputQueue.empty()) {
+      return null;
+    }
+    Instance result = (Instance)m_OutputQueue.pop();
+    // Clear out references to old strings occasionally
+    if (m_OutputQueue.empty() && m_NewBatch) {
+      if (m_OutputStringAtts.length > 0) {
+        m_OutputFormat = m_OutputFormat.stringFreeStructure();
+      }
+    }
+    return result;
+  }
+  
+  /**
+   * Output an instance after filtering but do not remove from the
+   * output queue.
+   *
+   * @return the instance that has most recently been filtered (or null if
+   * the queue is empty).
+   * @exception NullPointerException if no input structure has been defined 
+   */
+  public Instance outputPeek() {
+
+    if (m_OutputFormat == null) {
+      throw new NullPointerException("No output instance format defined");
+    }
+    if (m_OutputQueue.empty()) {
+      return null;
+    }
+    Instance result = (Instance)m_OutputQueue.peek();
+    return result;
+  }
+
+  /**
+   * Returns the number of instances pending output
+   *
+   * @return the number of instances  pending output
+   * @exception NullPointerException if no input structure has been defined
+   */
+  public int numPendingOutput() {
+
+    if (m_OutputFormat == null) {
+      throw new NullPointerException("No output instance format defined");
+    }
+    return m_OutputQueue.size();
+  }
+
+  /**
+   * Returns whether the output format is ready to be collected
+   *
+   * @return true if the output format is set
+   */
+  public boolean isOutputFormatDefined() {
+
+    return (m_OutputFormat != null);
+  }
+
+  /**
+   * Gets an array containing the indices of all string attributes.
+   *
+   * @param insts the Instances to scan for string attributes. 
+   * @return an array containing the indices of string attributes in
+   * the input structure. Will be zero-length if there are no
+   * string attributes
+   */
+  protected int [] getStringIndices(Instances insts) {
+    
+    // Scan through getting the indices of String attributes
+    int [] index = new int [insts.numAttributes()];
+    int indexSize = 0;
+    for (int i = 0; i < insts.numAttributes(); i++) {
+      if (insts.attribute(i).type() == Attribute.STRING) {
+        index[indexSize++] = i;
+      }
+    }
+    int [] result = new int [indexSize];
+    System.arraycopy(index, 0, result, 0, indexSize);
+    return result;
+  }
+  
+  /**
+   * Filters an entire set of instances through a filter and returns
+   * the new set. 
+   *
+   * @param data the data to be filtered
+   * @param filter the filter to be used
+   * @return the filtered set of data
+   * @exception Exception if the filter can't be used successfully
+   */
+  public static Instances useFilter(Instances data,
+				    Filter filter) throws Exception {
+    /*
+    System.err.println(filter.getClass().getName() 
+                       + " in:" + data.numInstances());
+    */
+    for (int i = 0; i < data.numInstances(); i++) {
+      filter.input(data.instance(i));
+    }
+    filter.batchFinished();
+    Instances newData = filter.getOutputFormat();
+    Instance processed;
+    while ((processed = filter.output()) != null) {
+      newData.add(processed);
+    }
+
+    /*
+    System.err.println(filter.getClass().getName() 
+                       + " out:" + newData.numInstances());
+    */
+    return newData;
+  }
+
+  /**
+   * Method for testing filters.
+   *
+   * @param argv should contain the following arguments: <br>
+   * -i input_file <br>
+   * -o output_file <br>
+   * -c class_index <br>
+   * or -h for help on options
+   * @exception Exception if something goes wrong or the user requests help on
+   * command options
+   */
+  public static void filterFile(Filter filter, String [] options) 
+    throws Exception {
+
+    boolean debug = false;
+    Instances data = null;
+    Reader input = null;
+    PrintWriter output = null;
+    boolean helpRequest;
+
+    try {
+       helpRequest = Utils.getFlag('h', options);
+
+      if (Utils.getFlag('d', options)) {
+	debug = true;
+      }
+      String infileName = Utils.getOption('i', options);
+      String outfileName = Utils.getOption('o', options); 
+      String classIndex = Utils.getOption('c', options);
+      
+      if (filter instanceof OptionHandler) {
+	((OptionHandler)filter).setOptions(options);
+      }
+
+      Utils.checkForRemainingOptions(options);
+      if (helpRequest) {
+	throw new Exception("Help requested.\n");
+      }
+      if (infileName.length() != 0) {
+	input = new BufferedReader(new FileReader(infileName));
+      } else {
+	input = new BufferedReader(new InputStreamReader(System.in));
+      }
+      if (outfileName.length() != 0) {
+	output = new PrintWriter(new FileOutputStream(outfileName));
+      } else { 
+	output = new PrintWriter(System.out);
+      }
+
+      data = new Instances(input, 1);
+      if (classIndex.length() != 0) {
+	if (classIndex.equals("first")) {
+	  data.setClassIndex(0);
+	} else if (classIndex.equals("last")) {
+	  data.setClassIndex(data.numAttributes() - 1);
+	} else {
+	  data.setClassIndex(Integer.parseInt(classIndex) - 1);
+	}
+      }
+    } catch (Exception ex) {
+      String filterOptions = "";
+      // Output the error and also the valid options
+      if (filter instanceof OptionHandler) {
+	filterOptions += "\nFilter options:\n\n";
+	Enumeration enum = ((OptionHandler)filter).listOptions();
+	while (enum.hasMoreElements()) {
+	  Option option = (Option) enum.nextElement();
+	  filterOptions += option.synopsis() + '\n'
+	    + option.description() + "\n";
+	}
+      }
+
+      String genericOptions = "\nGeneral options:\n\n"
+	+ "-h\n"
+	+ "\tGet help on available options.\n"
+	+ "\t(use -b -h for help on batch mode.)\n"
+	+ "-i <file>\n"
+	+ "\tThe name of the file containing input instances.\n"
+	+ "\tIf not supplied then instances will be read from stdin.\n"
+	+ "-o <file>\n"
+	+ "\tThe name of the file output instances will be written to.\n"
+	+ "\tIf not supplied then instances will be written to stdout.\n"
+	+ "-c <class index>\n"
+	+ "\tThe number of the attribute to use as the class.\n"
+	+ "\t\"first\" and \"last\" are also valid entries.\n"
+	+ "\tIf not supplied then no class is assigned.\n";
+
+      throw new Exception('\n' + ex.getMessage()
+			  + filterOptions+genericOptions);
+    }
+    
+    if (debug) {
+      System.err.println("Setting input format");
+    }
+    boolean printedHeader = false;
+    if (filter.setInputFormat(data)) {
+      if (debug) {
+	System.err.println("Getting output format");
+      }
+      output.println(filter.getOutputFormat().toString());
+      printedHeader = true;
+    }
+    
+    // Pass all the instances to the filter
+    while (data.readInstance(input)) {
+      if (debug) {
+	System.err.println("Input instance to filter");
+      }
+      if (filter.input(data.instance(0))) {
+	if (debug) {
+	  System.err.println("Filter said collect immediately");
+	}
+	if (!printedHeader) {
+	  throw new Error("Filter didn't return true from setInputFormat() "
+			  + "earlier!");
+	}
+	if (debug) {
+	  System.err.println("Getting output instance");
+	}
+	output.println(filter.output().toString());
+      }
+      data.delete(0);
+    }
+    
+    // Say that input has finished, and print any pending output instances
+    if (debug) {
+      System.err.println("Setting end of batch");
+    }
+    if (filter.batchFinished()) {
+      if (debug) {
+	System.err.println("Filter said collect output");
+      }
+      if (!printedHeader) {
+	if (debug) {
+	  System.err.println("Getting output format");
+	}
+	output.println(filter.getOutputFormat().toString());
+      }
+      if (debug) {
+	System.err.println("Getting output instance");
+      }
+      while (filter.numPendingOutput() > 0) {
+	output.println(filter.output().toString());
+	if (debug){
+	  System.err.println("Getting output instance");
+	}
+      }
+    }
+    if (debug) {
+      System.err.println("Done");
+    }
+    
+    if (output != null) {
+      output.close();
+    }
+  }
+
+  /**
+   * Method for testing filters ability to process multiple batches.
+   *
+   * @param argv should contain the following arguments:<br>
+   * -i (first) input file <br>
+   * -o (first) output file <br>
+   * -r (second) input file <br>
+   * -s (second) output file <br>
+   * -c class_index <br>
+   * or -h for help on options
+   * @exception Exception if something goes wrong or the user requests help on
+   * command options
+   */
+  public static void batchFilterFile(Filter filter, String [] options) 
+    throws Exception {
+
+    Instances firstData = null;
+    Instances secondData = null;
+    Reader firstInput = null;
+    Reader secondInput = null;
+    PrintWriter firstOutput = null;
+    PrintWriter secondOutput = null;
+    boolean helpRequest;
+    try {
+      helpRequest = Utils.getFlag('h', options);
+
+      String fileName = Utils.getOption('i', options); 
+      if (fileName.length() != 0) {
+	firstInput = new BufferedReader(new FileReader(fileName));
+      } else {
+	throw new Exception("No first input file given.\n");
+      }
+
+      fileName = Utils.getOption('r', options); 
+      if (fileName.length() != 0) {
+	secondInput = new BufferedReader(new FileReader(fileName));
+      } else {
+	throw new Exception("No second input file given.\n");
+      }
+
+      fileName = Utils.getOption('o', options); 
+      if (fileName.length() != 0) {
+	firstOutput = new PrintWriter(new FileOutputStream(fileName));
+      } else {
+	firstOutput = new PrintWriter(System.out);
+      }
+      
+      fileName = Utils.getOption('s', options); 
+      if (fileName.length() != 0) {
+	secondOutput = new PrintWriter(new FileOutputStream(fileName));
+      } else {
+	secondOutput = new PrintWriter(System.out);
+      }
+      String classIndex = Utils.getOption('c', options);
+
+      if (filter instanceof OptionHandler) {
+	((OptionHandler)filter).setOptions(options);
+      }
+      Utils.checkForRemainingOptions(options);
+      
+      if (helpRequest) {
+	throw new Exception("Help requested.\n");
+      }
+      firstData = new Instances(firstInput, 1);
+      secondData = new Instances(secondInput, 1);
+      if (!secondData.equalHeaders(firstData)) {
+	throw new Exception("Input file formats differ.\n");
+      }
+      if (classIndex.length() != 0) {
+	if (classIndex.equals("first")) {
+	  firstData.setClassIndex(0);
+	  secondData.setClassIndex(0);
+	} else if (classIndex.equals("last")) {
+	  firstData.setClassIndex(firstData.numAttributes() - 1);
+	  secondData.setClassIndex(secondData.numAttributes() - 1);
+	} else {
+	  firstData.setClassIndex(Integer.parseInt(classIndex) - 1);
+	  secondData.setClassIndex(Integer.parseInt(classIndex) - 1);
+	}
+      }
+    } catch (Exception ex) {
+      String filterOptions = "";
+      // Output the error and also the valid options
+      if (filter instanceof OptionHandler) {
+	filterOptions += "\nFilter options:\n\n";
+	Enumeration enum = ((OptionHandler)filter).listOptions();
+	while (enum.hasMoreElements()) {
+	  Option option = (Option) enum.nextElement();
+	  filterOptions += option.synopsis() + '\n'
+	    + option.description() + "\n";
+	}
+      }
+
+      String genericOptions = "\nGeneral options:\n\n"
+	+ "-h\n"
+	+ "\tGet help on available options.\n"
+	+ "-i <filename>\n"
+	+ "\tThe file containing first input instances.\n"
+	+ "-o <filename>\n"
+	+ "\tThe file first output instances will be written to.\n"
+	+ "-r <filename>\n"
+	+ "\tThe file containing second input instances.\n"
+	+ "-s <filename>\n"
+	+ "\tThe file second output instances will be written to.\n"
+	+ "-c <class index>\n"
+	+ "\tThe number of the attribute to use as the class.\n"
+	+ "\t\"first\" and \"last\" are also valid entries.\n"
+	+ "\tIf not supplied then no class is assigned.\n";
+
+      throw new Exception('\n' + ex.getMessage()
+			  + filterOptions+genericOptions);
+    }
+    boolean printedHeader = false;
+    if (filter.setInputFormat(firstData)) {
+      firstOutput.println(filter.getOutputFormat().toString());
+      printedHeader = true;
+    }
+    
+    // Pass all the instances to the filter
+    while (firstData.readInstance(firstInput)) {
+      if (filter.input(firstData.instance(0))) {
+	if (!printedHeader) {
+	  throw new Error("Filter didn't return true from setInputFormat() "
+			  + "earlier!");
+	}
+	firstOutput.println(filter.output().toString());
+      }
+      firstData.delete(0);
+    }
+    
+    // Say that input has finished, and print any pending output instances
+    if (filter.batchFinished()) {
+      if (!printedHeader) {
+	firstOutput.println(filter.getOutputFormat().toString());
+      }
+      while (filter.numPendingOutput() > 0) {
+	firstOutput.println(filter.output().toString());
+      }
+    }
+    
+    if (firstOutput != null) {
+      firstOutput.close();
+    }    
+    printedHeader = false;
+    if (filter.isOutputFormatDefined()) {
+      secondOutput.println(filter.getOutputFormat().toString());
+      printedHeader = true;
+    }
+    // Pass all the second instances to the filter
+    while (secondData.readInstance(secondInput)) {
+      if (filter.input(secondData.instance(0))) {
+	if (!printedHeader) {
+	  throw new Error("Filter didn't return true from"
+			  + " isOutputFormatDefined() earlier!");
+	}
+	secondOutput.println(filter.output().toString());
+      }
+      secondData.delete(0);
+    }
+    
+    // Say that input has finished, and print any pending output instances
+    if (filter.batchFinished()) {
+      if (!printedHeader) {
+	secondOutput.println(filter.getOutputFormat().toString());
+      }
+      while (filter.numPendingOutput() > 0) {
+	secondOutput.println(filter.output().toString());
+      }
+    }
+    if (secondOutput != null) {
+      secondOutput.close();
+    }
+  }
+
+  /**
+   * Main method for testing this class.
+   *
+   * @param argv should contain arguments to the filter: use -h for help
+   */
+  public static void main(String [] args) {
+    
+    try {
+      if (args.length == 0) {
+        throw new Exception("First argument must be the class name of a Filter");
+      }
+      String fname = args[0];
+      Filter f = (Filter)Class.forName(fname).newInstance();
+      args[0] = "";
+      if (Utils.getFlag('b', args)) {
+	Filter.batchFilterFile(f, args);
+      } else {
+	Filter.filterFile(f, args);
+      }
+    } catch (Exception ex) {
+      ex.printStackTrace();
+      System.out.println(ex.getMessage());
+    }
+  }
+}
+
+
+
+
+
+
+
+
Index: /gsdl/stable/build-src/packages/pdftohtml/readme-gs.txt
===================================================================
--- /gsdl/stable/build-src/packages/pdftohtml/readme-gs.txt	(revision 20131)
+++ /gsdl/stable/build-src/packages/pdftohtml/readme-gs.txt	(revision 20131)
@@ -0,0 +1,16 @@
+This is pdftohtml, which was based at:
+     http://www.ra.informatik.uni-stuttgart.de/~gosho/pdftohtml/
+
+It has recently been picked up again, and is currently based at:
+    http://pdftohtml.sourceforge.net/
+
+We're currently using version 0.34 as downloaded from
+http://pdftohtml.sourceforge.net. The only alterations made to the source
+package were to remove some "CVS" directories and tidy up the makefiles
+slightly (to use ./configure as with the rest of Greenstone).
+
+Also, the #pragma statements were removed to work around a compiler bug
+on Mac OS X.
+
+Stefan Boddie
+December 2002
Index: /gsdl/stable/build-src/packages/rtftohtml/rtftohtml-gs.txt
===================================================================
--- /gsdl/stable/build-src/packages/rtftohtml/rtftohtml-gs.txt	(revision 20131)
+++ /gsdl/stable/build-src/packages/rtftohtml/rtftohtml-gs.txt	(revision 20131)
@@ -0,0 +1,56 @@
+RTF TO HTML
+-----------
+
+This is based on version 2.7.5 of rtftohtml, which was last modified in
+November, 1994.
+It contains the text:
+###
+Initial Implementation by Chris Hector (cjh@cray.com)
+(c) 1994 by Chris Hector
+May be freely distributed.
+This translator was based on rtfskel.
+###
+The last known email address I can find for him is <cjh@cray.com>.
+I think that <chris@sunpack.com> might reach him, but I'm not sure.
+
+
+Versions 3.0 of rtftohtml and up are released under a shareware license,
+and available from http://www.logictran.com (although it now has a new
+name). You can download a free binary version of the software for most
+platforms from this site.
+
+
+
+
+rtftohtml is based on RTF Tools, which is (c) April 1994 by Paul DuBois
+<dubois@primate.wisc.edu>
+
+RTF Tools has the notice:
+##
+Distribution Availability
+This software may be redistributed without restriction and used for any
+purpose whatsoever.
+##
+
+The supplied version understands RTF version 1.2, while the
+latest version of the specification is RTF 1.6 (May 1999).
+
+I have added some of the newer rtf codes that were preventing some files from
+being parsed properly, but they are not acted on. Most of them do not
+actually affect the content anyway. Depending on how the rtf was created,
+there might be tags that cause us to trip up and fail. If you have
+rtf files that Greenstone is not extracting text from, please send me
+some email (jrm21@cs.waikato.ac.nz).
+
+Note - we extract but do not convert Windows Metafile Format (.wmf) images.
+On unix systems, these can be converted with newer versions of ImageMagick
+(ie "convert" version 4.2.9 or newer).
+Also, libwmf (for unix and windows) is available for conversion at:
+http://wvware.sourceforge.net/projects/libwmf.html
+but we do not include it here due to its dependencies
+(eg libttf for truetype fonts).
+
+Embedded images such as jpegs and pngs are extracted fine, though.
+
+John McPherson (jrm21@cs.waikato.ac.nz)
+June 2001.
Index: /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/Base64.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/Base64.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/Base64.pm	(revision 20131)
@@ -0,0 +1,198 @@
+#
+# $Id$
+
+package MIME::Base64;
+
+=head1 NAME
+
+MIME::Base64 - Encoding and decoding of base64 strings
+
+=head1 SYNOPSIS
+
+ use MIME::Base64;
+
+ $encoded = encode_base64('Aladdin:open sesame');
+ $decoded = decode_base64($encoded);
+
+=head1 DESCRIPTION
+
+This module provides functions to encode and decode strings into the
+Base64 encoding specified in RFC 2045 - I<MIME (Multipurpose Internet
+Mail Extensions)>. The Base64 encoding is designed to represent
+arbitrary sequences of octets in a form that need not be humanly
+readable. A 65-character subset ([A-Za-z0-9+/=]) of US-ASCII is used,
+enabling 6 bits to be represented per printable character.
+
+The following functions are provided:
+
+=over 4
+
+=item encode_base64($str, [$eol])
+
+Encode data by calling the encode_base64() function.  The first
+argument is the string to encode.  The second argument is the line
+ending sequence to use (it is optional and defaults to C<"\n">).  The
+returned encoded string is broken into lines of no more than 76
+characters each and it will end with $eol unless it is empty.  Pass an
+empty string as second argument if you do not want the encoded string
+broken into lines.
+
+=item decode_base64($str)
+
+Decode a base64 string by calling the decode_base64() function.  This
+function takes a single argument which is the string to decode and
+returns the decoded data.
+
+Any character not part of the 65-character base64 subset set is
+silently ignored.  Characters occuring after a '=' padding character
+are never decoded.
+
+If the length of the string to decode (after ignoring
+non-base64 chars) is not a multiple of 4 or padding occurs too ealy,
+then a warning is generated if perl is running under C<-w>.
+
+=back
+
+If you prefer not to import these routines into your namespace you can
+call them as:
+
+    use MIME::Base64 ();
+    $encoded = MIME::Base64::encode($decoded);
+    $decoded = MIME::Base64::decode($encoded);
+
+=head1 DIAGNOSTICS
+
+The following warnings might be generated if perl is invoked with the
+C<-w> switch:
+
+=over 4
+
+=item Premature end of base64 data
+
+The number of characters to decode is not a multiple of 4.  Legal
+base64 data should be padded with one or two "=" characters to make
+its length a multiple of 4.  The decoded result will anyway be as if
+the padding was there.
+
+=item Premature padding of base64 data
+
+The '=' padding character occurs as the first or second character
+in a base64 quartet.
+
+=back
+
+=head1 EXAMPLES
+
+If you want to encode a large file, you should encode it in chunks
+that are a multiple of 57 bytes.  This ensures that the base64 lines
+line up and that you do not end up with padding in the middle. 57
+bytes of data fills one complete base64 line (76 == 57*4/3):
+
+   use MIME::Base64 qw(encode_base64);
+
+   open(FILE, "/var/log/wtmp") or die "$!";
+   while (read(FILE, $buf, 60*57)) {
+       print encode_base64($buf);
+   }
+
+or if you know you have enough memory
+
+   use MIME::Base64 qw(encode_base64);
+   local($/) = undef;  # slurp
+   print encode_base64(<STDIN>);
+
+=head1 COPYRIGHT
+
+Copyright 1995-1999 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+Distantly based on LWP::Base64 written by Martijn Koster
+<m.koster@nexor.co.uk> and Joerg Reichelt <j.reichelt@nexor.co.uk> and
+code posted to comp.lang.perl <3pd2lp$6gf@wsinti07.win.tue.nl> by Hans
+Mulder <hansm@wsinti07.win.tue.nl>
+
+The XS implementation use code from metamail.  Copyright 1991 Bell
+Communications Research, Inc. (Bellcore)
+
+=cut
+
+use strict;
+use vars qw(@ISA @EXPORT $VERSION $OLD_CODE);
+
+require Exporter;
+require DynaLoader;
+@ISA = qw(Exporter DynaLoader);
+@EXPORT = qw(encode_base64 decode_base64);
+
+$VERSION = '2.11';
+
+eval { bootstrap MIME::Base64 $VERSION; };
+if ($@) {
+    # can't bootstrap XS implementation, use perl implementation
+    *encode_base64 = \&old_encode_base64;
+    *decode_base64 = \&old_decode_base64;
+
+    $OLD_CODE = $@;
+    #warn $@ if $^W;
+}
+
+# Historically this module has been implemented as pure perl code.
+# The XS implementation runs about 20 times faster, but the Perl
+# code might be more portable, so it is still here.
+
+use integer;
+
+sub old_encode_base64 ($;$)
+{
+    my $res = "";
+    my $eol = $_[1];
+    $eol = "\n" unless defined $eol;
+    pos($_[0]) = 0;                          # ensure start at the beginning
+    while ($_[0] =~ /(.{1,45})/gs) {
+	$res .= substr(pack('u', $1), 1);
+	chop($res);
+    }
+    $res =~ tr|` -_|AA-Za-z0-9+/|;               # `# help emacs
+    # fix padding at the end
+    my $padding = (3 - length($_[0]) % 3) % 3;
+    $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
+    # break encoded string into lines of no more than 76 characters each
+    if (length $eol) {
+	$res =~ s/(.{1,76})/$1$eol/g;
+    }
+    $res;
+}
+
+
+sub old_decode_base64 ($)
+{
+    local($^W) = 0; # unpack("u",...) gives bogus warning in 5.00[123]
+
+    my $str = shift;
+    my $res = "";
+
+    $str =~ tr|A-Za-z0-9+=/||cd;            # remove non-base64 chars
+    if (length($str) % 4) {
+	require Carp;
+	Carp::carp("Length of base64 data not a multiple of 4")
+    }
+    $str =~ s/=+$//;                        # remove padding
+    $str =~ tr|A-Za-z0-9+/| -_|;            # convert to uuencoded format
+    while ($str =~ /(.{1,60})/gs) {
+	my $len = chr(32 + length($1)*3/4); # compute length byte
+	$res .= unpack("u", $len . $1 );    # uudecode
+    }
+    $res;
+}
+
+# Set up aliases so that these functions also can be called as
+#
+#    MIME::Base64::encode();
+#    MIME::Base64::decode();
+
+*encode = \&encode_base64;
+*decode = \&decode_base64;
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/Base64.xs
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/Base64.xs	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/Base64.xs	(revision 20131)
@@ -0,0 +1,215 @@
+/* $Id$
+
+Copyright 1997-1998 Gisle Aas
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+
+The tables and some of the code that used to be here was borrowed from
+metamail, which comes with this message:
+
+  Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
+
+  Permission to use, copy, modify, and distribute this material 
+  for any purpose and without fee is hereby granted, provided 
+  that the above copyright notice and this permission notice 
+  appear in all copies, and that the name of Bellcore not be 
+  used in advertising or publicity pertaining to this 
+  material without the specific, prior written permission 
+  of an authorized representative of Bellcore.	BELLCORE 
+  MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY 
+  OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS", 
+  WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
+
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#ifdef __cplusplus
+}
+#endif
+
+#include "patchlevel.h"
+#if PATCHLEVEL <= 4 && !defined(PL_dowarn)
+   #define PL_dowarn dowarn
+#endif
+
+#define MAX_LINE  76 /* size of encoded lines */
+
+static char basis_64[] =
+   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+#define XX      255	/* illegal base64 char */
+#define EQ      254	/* padding */
+#define INVALID XX
+
+static unsigned char index_64[256] = {
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,62, XX,XX,XX,63,
+    52,53,54,55, 56,57,58,59, 60,61,XX,XX, XX,EQ,XX,XX,
+    XX, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
+    15,16,17,18, 19,20,21,22, 23,24,25,XX, XX,XX,XX,XX,
+    XX,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
+    41,42,43,44, 45,46,47,48, 49,50,51,XX, XX,XX,XX,XX,
+
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+};
+
+
+
+MODULE = MIME::Base64		PACKAGE = MIME::Base64
+
+SV*
+encode_base64(sv,...)
+	SV* sv
+	PROTOTYPE: $;$
+
+	PREINIT:
+	char *str;     /* string to encode */
+	SSize_t len;   /* length of the string */
+	char *eol;     /* the end-of-line sequence to use */
+	STRLEN eollen; /* length of the EOL sequence */
+	char *r;       /* result string */
+	STRLEN rlen;   /* length of result string */
+	unsigned char c1, c2, c3;
+	int chunk;
+
+	CODE:
+	str = SvPV(sv, rlen); /* SvPV(sv, len) gives warning for signed len */
+	len = (SSize_t)rlen;
+
+	/* set up EOL from the second argument if present, default to "\n" */
+	if (items > 1 && SvOK(ST(1))) {
+	    eol = SvPV(ST(1), eollen);
+	} else {
+	    eol = "\n";
+	    eollen = 1;
+	}
+
+	/* calculate the length of the result */
+	rlen = (len+2) / 3 * 4;	 /* encoded bytes */
+	if (rlen) {
+	    /* add space for EOL */
+	    rlen += ((rlen-1) / MAX_LINE + 1) * eollen;
+	}
+
+	/* allocate a result buffer */
+	RETVAL = newSV(rlen ? rlen : 1);
+	SvPOK_on(RETVAL);	
+	SvCUR_set(RETVAL, rlen);
+	r = SvPVX(RETVAL);
+
+	/* encode */
+	for (chunk=0; len > 0; len -= 3, chunk++) {
+	    if (chunk == (MAX_LINE/4)) {
+		char *c = eol;
+		char *e = eol + eollen;
+		while (c < e)
+		    *r++ = *c++;
+		chunk = 0;
+	    }
+	    c1 = *str++;
+	    c2 = *str++;
+	    *r++ = basis_64[c1>>2];
+	    *r++ = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
+	    if (len > 2) {
+		c3 = *str++;
+		*r++ = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
+		*r++ = basis_64[c3 & 0x3F];
+	    } else if (len == 2) {
+		*r++ = basis_64[(c2 & 0xF) << 2];
+		*r++ = '=';
+	    } else { /* len == 1 */
+		*r++ = '=';
+		*r++ = '=';
+	    }
+	}
+	if (rlen) {
+	    /* append eol to the result string */
+	    char *c = eol;
+	    char *e = eol + eollen;
+	    while (c < e)
+		*r++ = *c++;
+	}
+	*r = '\0';  /* every SV in perl should be NUL-terminated */
+
+	OUTPUT:
+	RETVAL
+
+SV*
+decode_base64(sv)
+	SV* sv
+	PROTOTYPE: $
+
+	PREINIT:
+	STRLEN len;
+	register unsigned char *str = (unsigned char*)SvPV(sv, len);
+	unsigned char const* end = str + len;
+	char *r;
+	unsigned char c[4];
+
+	CODE:
+	{
+	    /* always enough, but might be too much */
+	    STRLEN rlen = len * 3 / 4;
+	    RETVAL = newSV(rlen ? rlen : 1);
+	}
+        SvPOK_on(RETVAL);
+        r = SvPVX(RETVAL);
+
+	while (str < end) {
+	    int i = 0;
+            do {
+		unsigned char uc = index_64[*str++];
+		if (uc != INVALID)
+		    c[i++] = uc;
+
+		if (str == end) {
+		    if (i < 4) {
+			if (i && PL_dowarn)
+			    warn("Premature end of base64 data");
+			if (i < 2) goto thats_it;
+			if (i == 2) c[2] = EQ;
+			c[3] = EQ;
+		    }
+		    break;
+		}
+            } while (i < 4);
+	    
+	    if (c[0] == EQ || c[1] == EQ) {
+		if (PL_dowarn) warn("Premature padding of base64 data");
+		break;
+            }
+	    /* printf("c0=%d,c1=%d,c2=%d,c3=%d\n", c[0],c[1],c[2],c[3]);/**/
+
+	    *r++ = (c[0] << 2) | ((c[1] & 0x30) >> 4);
+
+	    if (c[2] == EQ)
+		break;
+	    *r++ = ((c[1] & 0x0F) << 4) | ((c[2] & 0x3C) >> 2);
+
+	    if (c[3] == EQ)
+		break;
+	    *r++ = ((c[2] & 0x03) << 6) | c[3];
+	}
+
+      thats_it:
+	SvCUR_set(RETVAL, r - SvPVX(RETVAL));
+	*r = '\0';
+
+	OUTPUT:
+	RETVAL
Index: /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/Changes
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/Changes	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/Changes	(revision 20131)
@@ -0,0 +1,119 @@
+1998-02-27   Gisle Aas <gisle@aas.no>
+
+   Release 2.11
+
+   Fixed bogues "Premature end of base64 data" warning.  Bug spotted
+   by Dwayne Jacques Fontenot.
+
+   Workaround for Redhat shipping trial releases of perl.
+
+
+
+1998-12-18   Gisle Aas <aas@sn.no>
+
+   Release 2.10
+
+   A tweak that should make compilation with some old perl5.00[23]
+   perls better.
+
+   A cast that make some compilers more happy.
+
+
+
+1998-11-13   Gisle Aas <aas@sn.no>
+
+   Release 2.09
+
+   The 2.08 release did not compile with perl5.005_53, because
+   all simple globals now need to be prefixed with "PL_".
+
+
+
+1998-10-22   Gisle Aas <aas@sn.no>
+
+   Release 2.08
+
+   Found another tweak to speed up decode_base64() with another 3%.
+
+   Improved MIME::Base64 documentation a little.
+
+
+
+1998-10-21   Gisle Aas <aas@sn.no>
+
+   Release 2.07
+
+   Faster and smarter C implementation of the decode_base64()
+   function.  The new decode_base64() was 25% faster when tested
+   on Linux, i586, gcc -O2.
+
+
+
+1998-07-15   Gisle Aas <aas@sn.no>
+
+   Release 2.06
+
+   The decode_base64() implemented in pure perl will only carp
+   (not croak) if length of data to decode is not a multiple 4.  This
+   actually made 'make test' fail after 'rm Base64.xs'.
+
+
+
+1998-01-27   Gisle Aas <aas@sn.no>
+
+   Release 2.05
+
+   The decode_base64() would previously allocate a too short buffer for the
+   result string when the trailing "==" padding was missing in the string to
+   be decoded.
+
+   The encode_base64() now allocate one byte less space in the result
+   strings returned.
+
+
+
+1997-12-02   Gisle Aas <aas@sn.no>
+
+   Release 2.04
+
+   Documentation expanded a bit.
+
+
+
+1997-07-10   Gisle Aas <aas@sn.no>
+
+   Release 2.03
+
+   Decode_base64() doesn't croak on premature ended data any more.
+   A warning is generated instead if running under -w.
+   
+
+
+1997-06-27   Gisle Aas <aas@sn.no>
+
+   Release 2.02
+
+   QuotedPrint fix by Roderick Schertler <roderick@argon.org>:
+
+      - Long lines were not broken unless they're at the beginning
+        of the text
+
+      - Lines near but not over 76 chars were broken when they
+        shouldn't be
+
+
+
+1997-06-13   Gisle Aas <aas@sn.no>
+
+   Release 2.01
+
+   Base64.xs: Avoid type convertion warnings with some compilers
+
+   Minor documentation updates
+
+
+
+1997-04-24   Gisle Aas <aas@sn.no>
+
+   Release 2.00, based on libwww-perl-5.08.
+
Index: /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/INSTALL.w3mir
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/INSTALL.w3mir	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/INSTALL.w3mir	(revision 20131)
@@ -0,0 +1,27 @@
+- You also have to get the MIME-Base64 package
+  (http://www.perl.com/CPAN/modules/by-module/MIME/)
+
+- Unpack it:
+
+    gzip -dc MIME-Base64-*.tar.gz | tar xvBf -
+
+- Install it:
+
+    cd MIME-Base64-*
+
+  Then, as above, either
+
+    perl Makefile.PL
+
+  or
+
+    perl Makefile.PL PREFIX=/some/dir
+
+  Continue:
+
+    make
+    make test      (it should print 'All tests successful.')
+    make install
+
+  Now MIME-Base64 should be installed and working.
+
Index: /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/MANIFEST
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/MANIFEST	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/MANIFEST	(revision 20131)
@@ -0,0 +1,9 @@
+Base64.pm	Bootstrap and perl implementation of MIME::Base64
+Base64.xs	Encoder and decoder written in C
+Changes		What's new
+MANIFEST	This file
+Makefile.PL	Writes the Makefile
+QuotedPrint.pm  MIME::QuotedPrint module, encoder and decoder
+README		Please do!
+t/base64.t	Test that it works
+t/quoted-print.t
Index: /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/Makefile.PL
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/Makefile.PL	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/Makefile.PL	(revision 20131)
@@ -0,0 +1,8 @@
+require 5.002;
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+    NAME	 => 'MIME::Base64',
+    VERSION_FROM => 'Base64.pm',
+    dist         => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
+);
Index: /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/QuotedPrint.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/QuotedPrint.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/QuotedPrint.pm	(revision 20131)
@@ -0,0 +1,115 @@
+#
+# $Id$
+
+package MIME::QuotedPrint;
+
+=head1 NAME
+
+MIME::QuotedPrint - Encoding and decoding of quoted-printable strings
+
+=head1 SYNOPSIS
+
+ use MIME::QuotedPrint;
+
+ $encoded = encode_qp($decoded);
+ $decoded = decode_qp($encoded);
+
+=head1 DESCRIPTION
+
+This module provides functions to encode and decode strings into the
+Quoted-Printable encoding specified in RFC 2045 - I<MIME (Multipurpose
+Internet Mail Extensions)>.  The Quoted-Printable encoding is intended
+to represent data that largely consists of bytes that correspond to
+printable characters in the ASCII character set.  Non-printable
+characters (as defined by english americans) are represented by a
+triplet consisting of the character "=" followed by two hexadecimal
+digits.
+
+The following functions are provided:
+
+=over 4
+
+=item encode_qp($str)
+
+This function will return an encoded version of the string given as
+argument.
+
+Note that encode_qp() does not change newlines C<"\n"> to the CRLF
+sequence even though this might be considered the right thing to do
+(RFC 2045 (Q-P Rule #4)).
+
+=item decode_qp($str);
+
+This function will return the plain text version of the string given
+as argument.
+
+=back
+
+
+If you prefer not to import these routines into your namespace you can
+call them as:
+
+  use MIME::QuotedPrint ();
+  $encoded = MIME::QuotedPrint::encode($decoded);
+  $decoded = MIME::QuotedPrint::decode($encoded);
+
+=head1 COPYRIGHT
+
+Copyright 1995-1997 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
+
+use strict;
+use vars qw(@ISA @EXPORT $VERSION);
+
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(encode_qp decode_qp);
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+
+sub encode_qp ($)
+{
+    my $res = shift;
+    $res =~ s/([^ \t\n!-<>-~])/sprintf("=%02X", ord($1))/eg;  # rule #2,#3
+    $res =~ s/([ \t]+)$/
+      join('', map { sprintf("=%02X", ord($_)) }
+		   split('', $1)
+      )/egm;                        # rule #3 (encode whitespace at eol)
+
+    # rule #5 (lines must be shorter than 76 chars, but we are not allowed
+    # to break =XX escapes.  This makes things complicated :-( )
+    my $brokenlines = "";
+    $brokenlines .= "$1=\n"
+	while $res =~ s/(.*?^[^\n]{73} (?:
+		 [^=\n]{2} (?! [^=\n]{0,1} $) # 75 not followed by .?\n
+		|[^=\n]    (?! [^=\n]{0,2} $) # 74 not followed by .?.?\n
+		|          (?! [^=\n]{0,3} $) # 73 not followed by .?.?.?\n
+	    ))//xsm;
+
+    "$brokenlines$res";
+}
+
+
+sub decode_qp ($)
+{
+    my $res = shift;
+    $res =~ s/[ \t]+?(\r?\n)/$1/g;  # rule #3 (trailing space must be deleted)
+    $res =~ s/=\r?\n//g;            # rule #5 (soft line breaks)
+    $res =~ s/=([\da-fA-F]{2})/pack("C", hex($1))/ge;
+    $res;
+}
+
+# Set up aliases so that these functions also can be called as
+#
+# MIME::QuotedPrint::encode();
+# MIME::QuotedPrint::decode();
+
+*encode = \&encode_qp;
+*decode = \&decode_qp;
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/README
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/README	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/README	(revision 20131)
@@ -0,0 +1,38 @@
+This package contains a base64 encoder/decoder and a quoted-printable
+encoder/decoder.  These encoding methods are specified in RFC 2045 -
+MIME (Multipurpose Internet Mail Extensions).
+
+The Base64 encoding is designed to represent arbitrary sequences of
+octets in a form that need not be humanly readable. A 65-character
+subset ([A-Za-z0-9+/=]) of US-ASCII is used, enabling 6 bits to be
+represented per printable character.
+
+The quoted-printable encoding is intended to represent data that
+largely consists of bytes that correspond to printable characters in
+the ASCII character set.  Non-printable characters are represented by
+a triplet consisting of the character "=" followed by two hexadecimal
+digits.
+
+The MIME::Base64 and MIME::QuotedPrint modules used to be part of
+libwww-perl package.  They are now distributed separately (as this
+package).  The main improvement is that the base64 encoder/decoder is
+implemented by XS functions.  This makes it about 20 times faster than
+the old implementation as pure Perl.
+
+In order to install and use this package you will need Perl version
+5.002 or better.  Installation as usual:
+
+   perl Makefile.PL
+   make
+   make test
+   make install
+
+The library can also be installed without XS support (for instance because
+you don't have a working C compiler installed).  Simply remove the Base64.xs
+file before running 'perl Makefile.PL' and everything should work the same,
+although encoding and decoding will be much slower.
+
+Copyright 1995-1999 Gisle Aas <gisle@aas.no>
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
Index: /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/install.sh
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/install.sh	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/install.sh	(revision 20131)
@@ -0,0 +1,10 @@
+#!/bin/sh -v
+
+export PERL5LIB=$GSDLHOME/perllib/cpan/lib:$PERL5LIB
+export PATH=$GSDLHOME/perllib/cpan/bin:$PATH
+
+perl Makefile.PL PREFIX=$GSDLHOME/perllib/cpan
+
+make
+make test
+make install
Index: /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/t/base64.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/t/base64.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/t/base64.t	(revision 20131)
@@ -0,0 +1,362 @@
+use MIME::Base64;
+
+print "1..282\n";
+
+print "Testing MIME::Base64-", $MIME::Base64::VERSION, "\n";
+
+$testno = 1;
+
+encodeTest();
+decodeTest();
+
+# This used to generate a warning
+print "not " unless decode_base64(encode_base64("foo")) eq "foo";
+print "ok ", $testno++, "\n";
+
+sub encodeTest
+{
+    print "encode test\n";
+
+    my @encode_tests = (
+        [''    => ''],
+	['a'   => 'YQ=='],
+	['aa'  => 'YWE='],
+	['aaa' => 'YWFh'],
+
+	['aaa' => 'YWFh'],
+	['aaa' => 'YWFh'],
+	['aaa' => 'YWFh'],
+
+	["\000\377" => "AP8="],
+	["\377\000" => "/wA="],
+	["\000\000\000" => "AAAA"],
+
+	# from HTTP spec
+	['Aladdin:open sesame' => 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='],
+
+	['a' x 100 => 'YWFh' x 33 . 'YQ=='],
+
+	['Multipurpose Internet Mail Extensions: The Base64 Content-Transfer-Encoding is designed to represent sequences of octets in a form that is not humanly readable. '
+	=> "TXVsdGlwdXJwb3NlIEludGVybmV0IE1haWwgRXh0ZW5zaW9uczogVGhlIEJhc2U2NCBDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nIGlzIGRlc2lnbmVkIHRvIHJlcHJlc2VudCBzZXF1ZW5jZXMgb2Ygb2N0ZXRzIGluIGEgZm9ybSB0aGF0IGlzIG5vdCBodW1hbmx5IHJlYWRhYmxlLiA="],
+
+	# All values
+	["\000" => "AA=="],
+	["\001" => "AQ=="],
+	["\002" => "Ag=="],
+	["\003" => "Aw=="],
+	["\004" => "BA=="],
+	["\005" => "BQ=="],
+	["\006" => "Bg=="],
+	["\007" => "Bw=="],
+	["\010" => "CA=="],
+	["\011" => "CQ=="],
+	["\012" => "Cg=="],
+	["\013" => "Cw=="],
+	["\014" => "DA=="],
+	["\015" => "DQ=="],
+	["\016" => "Dg=="],
+	["\017" => "Dw=="],
+	["\020" => "EA=="],
+	["\021" => "EQ=="],
+	["\022" => "Eg=="],
+	["\023" => "Ew=="],
+	["\024" => "FA=="],
+	["\025" => "FQ=="],
+	["\026" => "Fg=="],
+	["\027" => "Fw=="],
+	["\030" => "GA=="],
+	["\031" => "GQ=="],
+	["\032" => "Gg=="],
+	["\033" => "Gw=="],
+	["\034" => "HA=="],
+	["\035" => "HQ=="],
+	["\036" => "Hg=="],
+	["\037" => "Hw=="],
+	["\040" => "IA=="],
+	["\041" => "IQ=="],
+	["\042" => "Ig=="],
+	["\043" => "Iw=="],
+	["\044" => "JA=="],
+	["\045" => "JQ=="],
+	["\046" => "Jg=="],
+	["\047" => "Jw=="],
+	["\050" => "KA=="],
+	["\051" => "KQ=="],
+	["\052" => "Kg=="],
+	["\053" => "Kw=="],
+	["\054" => "LA=="],
+	["\055" => "LQ=="],
+	["\056" => "Lg=="],
+	["\057" => "Lw=="],
+	["\060" => "MA=="],
+	["\061" => "MQ=="],
+	["\062" => "Mg=="],
+	["\063" => "Mw=="],
+	["\064" => "NA=="],
+	["\065" => "NQ=="],
+	["\066" => "Ng=="],
+	["\067" => "Nw=="],
+	["\070" => "OA=="],
+	["\071" => "OQ=="],
+	["\072" => "Og=="],
+	["\073" => "Ow=="],
+	["\074" => "PA=="],
+	["\075" => "PQ=="],
+	["\076" => "Pg=="],
+	["\077" => "Pw=="],
+	["\100" => "QA=="],
+	["\101" => "QQ=="],
+	["\102" => "Qg=="],
+	["\103" => "Qw=="],
+	["\104" => "RA=="],
+	["\105" => "RQ=="],
+	["\106" => "Rg=="],
+	["\107" => "Rw=="],
+	["\110" => "SA=="],
+	["\111" => "SQ=="],
+	["\112" => "Sg=="],
+	["\113" => "Sw=="],
+	["\114" => "TA=="],
+	["\115" => "TQ=="],
+	["\116" => "Tg=="],
+	["\117" => "Tw=="],
+	["\120" => "UA=="],
+	["\121" => "UQ=="],
+	["\122" => "Ug=="],
+	["\123" => "Uw=="],
+	["\124" => "VA=="],
+	["\125" => "VQ=="],
+	["\126" => "Vg=="],
+	["\127" => "Vw=="],
+	["\130" => "WA=="],
+	["\131" => "WQ=="],
+	["\132" => "Wg=="],
+	["\133" => "Ww=="],
+	["\134" => "XA=="],
+	["\135" => "XQ=="],
+	["\136" => "Xg=="],
+	["\137" => "Xw=="],
+	["\140" => "YA=="],
+	["\141" => "YQ=="],
+	["\142" => "Yg=="],
+	["\143" => "Yw=="],
+	["\144" => "ZA=="],
+	["\145" => "ZQ=="],
+	["\146" => "Zg=="],
+	["\147" => "Zw=="],
+	["\150" => "aA=="],
+	["\151" => "aQ=="],
+	["\152" => "ag=="],
+	["\153" => "aw=="],
+	["\154" => "bA=="],
+	["\155" => "bQ=="],
+	["\156" => "bg=="],
+	["\157" => "bw=="],
+	["\160" => "cA=="],
+	["\161" => "cQ=="],
+	["\162" => "cg=="],
+	["\163" => "cw=="],
+	["\164" => "dA=="],
+	["\165" => "dQ=="],
+	["\166" => "dg=="],
+	["\167" => "dw=="],
+	["\170" => "eA=="],
+	["\171" => "eQ=="],
+	["\172" => "eg=="],
+	["\173" => "ew=="],
+	["\174" => "fA=="],
+	["\175" => "fQ=="],
+	["\176" => "fg=="],
+	["\177" => "fw=="],
+	["\200" => "gA=="],
+	["\201" => "gQ=="],
+	["\202" => "gg=="],
+	["\203" => "gw=="],
+	["\204" => "hA=="],
+	["\205" => "hQ=="],
+	["\206" => "hg=="],
+	["\207" => "hw=="],
+	["\210" => "iA=="],
+	["\211" => "iQ=="],
+	["\212" => "ig=="],
+	["\213" => "iw=="],
+	["\214" => "jA=="],
+	["\215" => "jQ=="],
+	["\216" => "jg=="],
+	["\217" => "jw=="],
+	["\220" => "kA=="],
+	["\221" => "kQ=="],
+	["\222" => "kg=="],
+	["\223" => "kw=="],
+	["\224" => "lA=="],
+	["\225" => "lQ=="],
+	["\226" => "lg=="],
+	["\227" => "lw=="],
+	["\230" => "mA=="],
+	["\231" => "mQ=="],
+	["\232" => "mg=="],
+	["\233" => "mw=="],
+	["\234" => "nA=="],
+	["\235" => "nQ=="],
+	["\236" => "ng=="],
+	["\237" => "nw=="],
+	["\240" => "oA=="],
+	["\241" => "oQ=="],
+	["\242" => "og=="],
+	["\243" => "ow=="],
+	["\244" => "pA=="],
+	["\245" => "pQ=="],
+	["\246" => "pg=="],
+	["\247" => "pw=="],
+	["\250" => "qA=="],
+	["\251" => "qQ=="],
+	["\252" => "qg=="],
+	["\253" => "qw=="],
+	["\254" => "rA=="],
+	["\255" => "rQ=="],
+	["\256" => "rg=="],
+	["\257" => "rw=="],
+	["\260" => "sA=="],
+	["\261" => "sQ=="],
+	["\262" => "sg=="],
+	["\263" => "sw=="],
+	["\264" => "tA=="],
+	["\265" => "tQ=="],
+	["\266" => "tg=="],
+	["\267" => "tw=="],
+	["\270" => "uA=="],
+	["\271" => "uQ=="],
+	["\272" => "ug=="],
+	["\273" => "uw=="],
+	["\274" => "vA=="],
+	["\275" => "vQ=="],
+	["\276" => "vg=="],
+	["\277" => "vw=="],
+	["\300" => "wA=="],
+	["\301" => "wQ=="],
+	["\302" => "wg=="],
+	["\303" => "ww=="],
+	["\304" => "xA=="],
+	["\305" => "xQ=="],
+	["\306" => "xg=="],
+	["\307" => "xw=="],
+	["\310" => "yA=="],
+	["\311" => "yQ=="],
+	["\312" => "yg=="],
+	["\313" => "yw=="],
+	["\314" => "zA=="],
+	["\315" => "zQ=="],
+	["\316" => "zg=="],
+	["\317" => "zw=="],
+	["\320" => "0A=="],
+	["\321" => "0Q=="],
+	["\322" => "0g=="],
+	["\323" => "0w=="],
+	["\324" => "1A=="],
+	["\325" => "1Q=="],
+	["\326" => "1g=="],
+	["\327" => "1w=="],
+	["\330" => "2A=="],
+	["\331" => "2Q=="],
+	["\332" => "2g=="],
+	["\333" => "2w=="],
+	["\334" => "3A=="],
+	["\335" => "3Q=="],
+	["\336" => "3g=="],
+	["\337" => "3w=="],
+	["\340" => "4A=="],
+	["\341" => "4Q=="],
+	["\342" => "4g=="],
+	["\343" => "4w=="],
+	["\344" => "5A=="],
+	["\345" => "5Q=="],
+	["\346" => "5g=="],
+	["\347" => "5w=="],
+	["\350" => "6A=="],
+	["\351" => "6Q=="],
+	["\352" => "6g=="],
+	["\353" => "6w=="],
+	["\354" => "7A=="],
+	["\355" => "7Q=="],
+	["\356" => "7g=="],
+	["\357" => "7w=="],
+	["\360" => "8A=="],
+	["\361" => "8Q=="],
+	["\362" => "8g=="],
+	["\363" => "8w=="],
+	["\364" => "9A=="],
+	["\365" => "9Q=="],
+	["\366" => "9g=="],
+	["\367" => "9w=="],
+	["\370" => "+A=="],
+	["\371" => "+Q=="],
+	["\372" => "+g=="],
+	["\373" => "+w=="],
+	["\374" => "/A=="],
+	["\375" => "/Q=="],
+	["\376" => "/g=="],
+	["\377" => "/w=="],
+    );
+
+    for $test (@encode_tests) {
+	my($plain, $expected) = ($$test[0], $$test[1]);
+
+	my $encoded = encode_base64($plain, '');
+	if ($encoded ne $expected) {
+	    print "test $testno ($plain): expected $expected, got $encoded\n";
+            print "not ";
+	}
+	my $decoded = decode_base64($encoded);
+	if ($decoded ne $plain) {
+	    print "test $testno ($plain): expected $expected, got $encoded\n";
+            print "not ";
+	}
+
+	# Try the old C versions too
+	if ($encoded ne MIME::Base64::old_encode_base64($plain, '')) {
+	    print "old_encode_base64 give different result.\n";
+	    print "not ";
+        }
+	if ($plain ne MIME::Base64::old_decode_base64($encoded)) {
+	    print "old_decode_base64 give different result.\n";
+	    print "not ";
+        }
+		
+	print "ok $testno\n";
+	$testno++;
+    }
+}
+
+sub decodeTest
+{
+    print "decode test:\n";
+    local $SIG{__WARN__} = sub { print $_[0] };  # avoid warnings on stderr
+
+    my @decode_tests = (
+	['YWE='   => 'aa'],
+	[' YWE='  => 'aa'],
+	['Y WE='  => 'aa'],
+	['YWE= '  => 'aa'],
+	["Y\nW\r\nE=" => 'aa'],
+
+	# These will generate some warnings
+        ['YWE=====' => 'aa'],    # extra padding
+	['YWE'      => 'aa'],    # missing padding
+        ['YWFh====' => 'aaa'],
+        ['YQ'       => 'a'],
+        ['Y'        => ''],
+        [''         => ''],
+        [undef()    => ''],
+    );
+
+    for $test (@decode_tests) {
+	my($encoded, $expected) = ($$test[0], $$test[1]);
+
+	my $decoded = decode_base64($encoded);
+	if ($decoded ne $expected) {
+	    die "test $testno ($encoded): expected $expected, got $decoded\n";
+	}
+	print "ok $testno\n";
+	$testno++;
+    }
+}
Index: /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/t/quoted-print.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/t/quoted-print.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/MIME-Base64-2.11/t/quoted-print.t	(revision 20131)
@@ -0,0 +1,106 @@
+#!/local/bin/perl -w
+
+use MIME::QuotedPrint;
+
+$x70 = "x" x 70;
+
+@tests =
+  (
+   # plain ascii should not be encoded
+   ["quoted printable"  =>
+    "quoted printable"],
+
+   # 8-bit chars should be encoded
+   ["våre kjære norske tegn bør æres" =>
+    "v=E5re kj=E6re norske tegn b=F8r =E6res"],
+
+   # trailing space should be encoded
+   ["  " => "=20=20"],
+   ["\tt\t" => "\tt=09"],
+   ["test  \ntest\n\t \t \n" => "test=20=20\ntest\n=09=20=09=20\n"],
+
+   # "=" is special an should be decoded
+   ["=\n" => "=3D\n"],
+   ["\0\xff" => "=00=FF"],
+
+   # Very long lines should be broken (not more than 76 chars
+   ["The Quoted-Printable encoding is intended to represent data that largly consists of octets that correspond to printable characters in the ASCII character set." =>
+    "The Quoted-Printable encoding is intended to represent data that largly con=
+sists of octets that correspond to printable characters in the ASCII charac=
+ter set."
+    ],
+
+   # Long lines after short lines were broken through 2.01.
+   ["short line
+In America, any boy may become president and I suppose that's just one of the risks he takes. -- Adlai Stevenson" =>
+    "short line
+In America, any boy may become president and I suppose that's just one of t=
+he risks he takes. -- Adlai Stevenson"],
+
+   # My (roderick@argon.org) first crack at fixing that bug failed for
+   # multiple long lines.
+   ["College football is a game which would be much more interesting if the faculty played instead of the students, and even more interesting if the
+trustees played.  There would be a great increase in broken arms, legs, and necks, and simultaneously an appreciable diminution in the loss to humanity. -- H. L. Mencken" =>
+    "College football is a game which would be much more interesting if the facu=
+lty played instead of the students, and even more interesting if the
+trustees played.  There would be a great increase in broken arms, legs, and=
+ necks, and simultaneously an appreciable diminution in the loss to humanit=
+y. -- H. L. Mencken"],
+
+   # Don't break a line that's near but not over 76 chars.
+   ["$x70!23"		=> "$x70!23"],
+   ["$x70!234"		=> "$x70!234"],
+   ["$x70!2345"		=> "$x70!2345"],
+   ["$x70!23456"	=> "$x70!23456"],
+   ["$x70!23\n"		=> "$x70!23\n"],
+   ["$x70!234\n"	=> "$x70!234\n"],
+   ["$x70!2345\n"	=> "$x70!2345\n"],
+   ["$x70!23456\n"	=> "$x70!23456\n"],
+
+   # Not allowed to break =XX escapes using soft line break
+   ["$x70===xxxx" => "$x70=3D=\n=3D=3Dxxxx"],
+   ["$x70!===xxx" => "$x70!=3D=\n=3D=3Dxxx"],
+   ["$x70!!===xx" => "$x70!!=3D=\n=3D=3Dxx"],
+   ["$x70!!!===x" => "$x70!!!=\n=3D=3D=3Dx"],
+   #                            ^
+   #                    70123456|
+   #                           max
+   #                        line width
+);
+
+$notests = @tests + 2;
+print "1..$notests\n";
+
+$testno = 0;
+for (@tests) {
+    $testno++;
+    ($plain, $encoded) = @$_;
+    $x = encode_qp($plain);
+    if ($x ne $encoded) {
+	print "Encode test failed\n";
+	print "Got:      '$x'\n";
+	print "Expected: '$encoded'\n";
+	print "not ok $testno\n";
+	next;
+    }
+    $x = decode_qp($encoded);
+    if ($x ne $plain) {
+	print "Decode test failed\n";
+	print "Got:      '$x'\n";
+	print "Expected: '$plain'\n";
+	print "not ok $testno\n";
+	next;
+    }
+    print "ok $testno\n";
+}
+
+# Some extra testing for a case that was wrong until libwww-perl-5.09
+print "not " unless decode_qp("foo  \n\nfoo =\n\nfoo=20\n\n") eq
+                                "foo\n\nfoo \nfoo \n\n";
+$testno++; print "ok $testno\n";
+
+# Same test but with "\r\n" terminated lines
+print "not " unless decode_qp("foo  \r\n\r\nfoo =\r\n\r\nfoo=20\r\n\r\n") eq
+                                "foo\r\n\r\nfoo \r\nfoo \r\n\r\n";
+$testno++; print "ok $testno\n";
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/ChangeLog
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/ChangeLog	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/ChangeLog	(revision 20131)
@@ -0,0 +1,1535 @@
+Tue Aug  4 1998   Gisle Aas <aas@sn.no>
+
+ o  Release 5.36
+
+ o  The lwp-download script will call $ua->env_proxy now.
+
+ o  The lwp-request script allows content types (specified with the -c
+    option) with optional parameters like: multipart/mixed; boundary="--".
+
+ o  LWP::UserAgent will lowercase all authentication parameter names
+    before passing it to the authentication module.  Previous releases
+    ignored parameters like; Realm="Foo" (bacause Realm contained
+    upper case letters).
+
+ o  LWP::Protocol::ftp test for If-Modified-Since was wrong.
+
+ o  How the $url->abs method works can now be configured with the global
+    variables $URI::URL::ABS_ALLOW_RELATIVE_SCHEME and
+    $URI::URL::ABS_REMOTE_LEADING_DOTS.
+
+ o  The anonymous password guesser for ftp URLs will now call the external
+    `whoami` program any more.  Patch by Charles C. Fu <ccwf@bacchus.com>.
+
+ o  LWP::Protocol::http now allow dynamic requests without any
+    Content-Length specified when Content-Type is multipart/*
+
+ o  HTTP::Request::Common can now upload infinite files.
+    (Controlled by the $DYNAMIC_FILE_UPLOAD configuration variable.)
+
+
+
+Fri Jul 10 1998   Gisle Aas <aas@sn.no>
+
+ o  Release 5.35
+
+ o  More lwp-rget patches from David D. Kilzer <ddkilzer@madison.dseg.ti.com>.
+    Adds the following new options: --iis, --keepext, --tolower
+
+ o  LWP::MediaTypes patches from MacEachern <dougm@pobox.com>.  Adds new
+    functions: add_type(), add_encoding(), read_media_types()
+
+
+
+Tue Jul  7 1998   Gisle Aas <aas@sn.no>
+
+ o  Release 5.34
+
+ o  LWP::Protocol::ftp now try to use the MDTM command to support
+    the Last-Modified response header as well as
+    If-Modified-Since in requests.  Original and final patch by
+    Charles C. Fu <ccwf@bacchus.com>
+
+ o  $url->path_components will not escape "." any more.
+
+ o  WWW::RobotRules will now work for Mac text files too (lines delimited
+    by CR only).  Patch by Olly Betts <olly@muscat.co.uk>
+
+ o  lwp-rget support <area ..> links too.
+
+
+
+Thu May  7 1998   Gisle Aas <aas@sn.no>
+
+ o  Release 5.33
+
+ o  LWP::Simple::get() did try to handle too many of the 3xx
+    codes as redirect when it bypasses full LWP.
+
+ o  LWP::UserAgent->mirror will now use utime(2) to set the
+    file modification time corresponding to the Last-Modified
+    header.
+
+ o  LWP::Protocol::http will not modify the HTTP::Request that
+    it is processing.  This avoids sticky Host header for
+    redirects.
+
+ o  URI::Heuristic and lwp-download documentation update.
+
+
+
+Wed Apr 15 1998   Gisle Aas <aas@sn.no>
+
+ o  Release 5.32
+
+ o  Much improved HTTP::Daemon class. We now support persistent
+    connections.  Changes include:
+       - $c->get_request can be told to return after reading and
+         parsing headers only.
+       - $c->reason (new method)
+       - $c->read_buffer (new method)
+       - $c->proto_ge (new method)
+       - $c->force_last_request (new method)
+       - $c->send_response now support CODE reference content
+         and will use chunked transfer encoding for HTTP/1.1 clients.
+       - expanded the documentation.
+
+
+
+Fri Apr 10 1998   Gisle Aas <aas@sn.no>
+
+ o  Release 5.31
+
+ o  Makefile.PL now checks that HTML::HeadParser is present.
+
+ o  Updated HTTP::Cookies according to draft-ietf-http-state-man-mec-08.txt
+    It now supports the .local domain and value less 'port' attribute in
+    the Set-Cookie2 header.
+
+ o  HTTP::Headers update:
+       - $h->content_type now always return a defined value
+       - $h->header($field) will now concatenate multi-valued header
+         fields with "," as separator in scalar context.
+
+ o  HTTP::Request::Common update:
+       - used to destroy the content of the  hash/array arguments
+         passed to its constructor functions.
+       - allow a hash reference to specify form-data content.
+       - you can override Content-Disposition for form-data now.
+       - set content-encoding for files if applicable
+       - default boundary string is now always "--000"
+
+ o  LWP::UserAgent will not follow more than 13 redirects
+    automatically.
+
+
+
+Wed Apr  1 1998   Gisle Aas <aas@sn.no>
+
+ o  Release 5.30
+
+ o  Unbundled the following modules:
+
+       * HTML-Parser  (HTML::Parser, HTML::Entites, HTML::LinkExtor,...)
+       * HTML-Tree    (HTML::Element, HTML::TreeBuilder,...)
+       * Font-AFM     (Font::AFM, Font::Metrics::*)
+       * File-CounterFile
+
+ o  Simplified internal structure of HTML::Headers.  Hopefully,
+    nobody will notice.
+
+ o  New modules HTTP::Headers::Auth,  HTTP::Headers::ETag that adds
+    additional convenience methods to the HTTP::Headers class.
+
+ o  Removed split_etag_list() from HTTP::Headers::Util, in the hope
+    that nobody had starting using it.
+
+
+
+Tue Mar 24 1998   Gisle Aas <aas@sn.no>
+
+ o  Release 5.22
+
+ o  HTTP::Cookies made more compatible with Netscape cookies.  Allow
+    the domain to match host, allow dots in the part of the hostname
+    not covered by domain.  Don't quote the cookie value even when it
+    contains non-token chars.  Based on patch from Kartik Subbarao
+    <subbarao@computer.org>.
+
+ o  Updated HTTP::Status to reflect <draft-ietf-http-v11-spec-rev-03>.
+    RC_MOVED_TEMPORARILY renamed to RC_FOUND.  Added codes
+    RC_TEMPORARY_REDIRECT (307) and RC_EXPECTATION_FAILED (417).
+    Slightly more documentation too.
+
+ o  The split_header_words() function HTTP::Headers::Util could go
+    into infinite loop on some header values.  Implemented split_etag_list()
+    too.  Added more documentation and test script for this module.
+
+ o  LWP::Simple now switch to full LWP implementation even for systems
+    that force all environment keys to be upper case.  Modification
+    suggested by Dale Couch <dcouch@training.orl.lmco.com>.
+
+ o  LWP::UserAgent allows redirects to a relative URL with scheme to be
+    made.  Suggested by Chris W. Unger <cunger@cas.org>.
+
+ o  Applied dtd2pm.pl patches from <peterm@zeta.org.au>.  It can now
+    extract information from the HTML40.dtd
+
+
+
+Thu Mar 12 1998   Gisle Aas <aas@sn.no>
+
+ o  Release 5.21
+
+ o  lwp-rget patches from David D. Kilzer <ddkilzer@madison.dseg.ti.com>
+    (modified by Gisle).  Support the --hier  and the --auth options
+    and <frame>s.
+
+ o  File::CounterFile protect against bad $/ and $\ as suggested
+    by Frank Hoehne.
+ 
+ o  File::Listing used "next" when return was more appropriate.
+    Patch by erik@mediator.uni-c.dk.
+
+ o  HTML::Element support for multiple boolean attributes for a single
+    element.  Patch by Philip Guenther.
+
+ o  Can set $HTTP::Headers::TRANSLATE_UNDERSCORE to FALSE value to
+    suppress tr/_/-/ of header keys.
+
+ o  LWP::Protocol::http will not initialize the Host header if it is
+    already set. Patch by Ed Jordan.
+
+ o  LWP::Protocol::http did not handle responses with no header lines
+    correctly.  Patch by Daniel Buenzli <buenzli@rzu.unizh.ch>
+
+ o  $url->rel() handles path segments without leading "/" better.
+
+
+
+Fri Feb 13 1998   Gisle Aas <aas@sn.no>
+
+ o  Release 5.20
+
+ o  Fixed the "500 Offset outside string" bug that affected perl
+    5.004_03 and older version of Perl.
+
+ o  Fixed a documentation typo spotted by Michael Quaranta
+    <quaranta@vnet.IBM.COM>
+
+ o  HTTP::Date: Protect against croaking from timegm/timelocal.
+
+
+
+Mon Jan 26 1998   Gisle Aas <aas@sn.no>
+
+ o  Release 5.19
+
+ o  HTML::Parser does not call $self->text() callback for empty text
+    any more.
+
+ o  LWP::Protocol::https was noisy when connections failed and the
+    script was running with '-w' (noise inherited from IO::Socket::INET)
+
+ o  $ua->use_alarm(BOOL) now gives a warning if running with -w
+
+
+
+Tue Jan 20 1998   Gisle Aas <aas@sn.no>
+
+ o  Developer release 5.18_05
+
+ o  HTTPS support based on my Crypt-SSLeay module.  The Net-SSLeay module
+    is not supported any more.
+
+ o  lwp-request documentation typo spotted Martijn Koster.
+
+ o  Removed superfluous \\ in the URI::Escape regex. This was also
+    spotted by Martijn.
+
+ o  File::Listing now handles timezones correctly.
+
+ o  Added $VERSION to modules that was missing it.
+
+ o  Added 'use strict' to several modules that was missing it.
+
+ o  LWP::Protocol::http now adds the Client-Peer header to responses and
+    has hooks for more callbacks.
+
+ o  LWP::Protocol::https adds Client-SSL-Cipher, Client-SSL-Cert-Subject
+    and Client-SSL-Cert-Issuer headers to the response.  The requests can
+    also be made conditional based on the peer certificate using the
+    If-SSL-Cert-Subject header in requests.
+
+ o  HTML::Parse is back.  (It was even used in lwpcook.pod)
+
+
+
+Wed Dec 17 1997   Gisle Aas <aas@sn.no>
+
+ o  Developer release 5.18_04
+
+ o  Makefile.PL fix based on report from Pon Hwa Lin <koala@fragment.com>
+
+ o  lwp-request will now print the response code message with -s and -S
+    options.
+
+ o  Hide IO::Socket::INET noise when running under -w
+
+ o  Don't set 'Content-Length: 0' in HTTP requests.
+
+ o  LWP::Protocol::http now calls LWP::Debug::conns again
+
+
+
+Tue Dec 16 1997   Gisle Aas <aas@sn.no>
+
+ o  Developer release 5.18_03
+
+ o  Got rid of alarms() and replaced LWP::Socket with IO::Socket::INET.
+    New protocol implementations for http, https, gopher, nntp.
+    $ua->use_alarm() is now a noop.
+
+ o  LWP::Protocol::ftp patch from  Tony Finch <fanf@demon.net>.
+
+ o  Removed depreciated modules from the distibution; HTML::Parse,
+    LWP::Socket, LWP::SecureSocket, LWP::IO, LWP::TkIO.
+
+
+
+Fri Dec 12 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.18
+
+ o  HTTP authorization patches from Tony Finch <fanf@demon.net>.
+    Allows "user:pass@" in HTTP URLs.
+
+ o  HTML::Parser patch by Brian McCauley <B.A.McCauley@bham.ac.uk>.
+    Pass original text to end() method.
+
+ o  The HTML::Parser->netscape_buggy_comment method is depreciated.
+    Use HTML::Parser->strict_comment instead.  The default value
+    has changed with the name.
+
+ o  Some HTML::Parser optimization tweaks.
+
+ o  New module named HTML::Filter
+
+ o  Updated HTTP::Headers to the latest HTTP spec.  Added knowledge
+    about the "Trailer", "Expect", "TE", "Accept-Range" headers.
+    "Public" header is gone.
+
+ o  Added some more header convenience methods: if_unmodified_since,
+    content_language, and proxy_authorization methods.
+
+ o  HTTP::{Request,Response}->clone can handle subclasses now.
+
+ o  HTTP::Request->url() can now undefine the URL.
+
+ o  HTTP::{Request,Response}->as_string format looks more like
+    the HTTP protocol formatting now.  Dashed lines above and
+    below is gone.
+
+ o  Documented HTTP::Response->status_line method
+
+ o  Compressed HTML::Response->error_as_HTML output
+
+ o  HTTP::Status updated to latest HTTP spec.  Added 
+    RC_REQUEST_RANGE_NOT_SATISFIABLE (416)
+
+
+
+Tue Dec  2 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.17
+
+ o  All authentication handling moved out of LWP::UserAgent and into
+    LWP::Authen::Basic and LWP::Authen::Digest.  We now also support
+    PROXY_AUTHENTICATION_REQUIRED responses.
+
+ o  HTML::Formatter will always add a blank line for <br>.
+
+ o  Avoid use of uninitialized value in HTTP::Daemon.
+
+ o  HTTP::Date allows seconds when recognizing 'ls -l' dates.  This
+    allows us to parse syslog time stamps.
+
+ o  HTTP::Request::Common::POST allows a hash reference as second
+    argument (in addition to an array reference).
+
+ o  LWP::Simple will initialize the $ua if it is exported.
+
+ o  Various documentation updates.
+
+
+
+Fri Nov 21 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.16
+
+ o  LWP::Simple::head() would die in array context because str2time
+    was not imported any more.
+
+ o  HTTP::Daemon->accept now takes an optional package argument like
+    IO::Socket->accept does.
+
+ o  Made HTTP::Request and HTTP::Response subclassable.
+
+ o  Added Proxy-Authorization example to lwpcook.
+
+
+
+Thu Nov  6 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.15
+
+ o  New module URI::Heuristic
+
+ o  The lwp-request script now use URI::Heuristic for it's URL arguments.
+    It means that 'lwp-request perl' will not get a file called "./perl"
+    but will fetch the page "http://www.perl.com" or something similar.
+    If you want to get the file you have to prefix it with "./".  Full
+    URLs are never affected by this.
+
+ o  LWP::Simple::get() will bypass LWP for simple HTTP requests.  This
+    should make it somewhat faster.
+
+ o  LWP::RobotUA has a new method called $ua->use_sleep() that
+    controls how niceness towards the servers are enforced.
+    Previously $ua->use_alarm() used to control this, but this did
+    not work well on Win32 systems.
+
+ o  URI::URL::rel() will handle URLs to a fragment within the same
+    document better. Initial patch from Nicolai Langfeldt
+    <janl@math.uio.no>.
+
+ o  HTML::Element don't consider </th>, </tr> and </td> optional any
+    more.  I wonder how Netscape managed to not implement this
+    correctly all this time.
+
+ o  Added lots of modern tags to HTML::AsSubs.
+
+ o  HTTP::Request::Common will read uploaded files in binmode().
+    This should be better for Win32 systems.  Contributed by
+    <Steve_Kilbane@cegelecproj.co.uk>.
+
+
+
+Sun Oct 12 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.14
+
+ o  HTML::Formatter patches from Andreas Gustafsson <gson@araneus.fi>.
+    The formatters handling of whitespace is much better now.  Thanks!
+
+ o  HTML::FormatText: can specify margins in the constructor.
+
+ o  URI::URL: the base will be absolutized internally now.
+
+ o  URI::URL will take advantage of void context provided by perl5.004.
+    This means that using $u->path and $u->query should be safer now.
+
+ o  URI::URL->print_on defaults to STDERR now (used to be STDOUT).
+
+ o  URI::URL: removed version 3 compatibility stuff ($COMPAT_VER_3).
+
+ o  $ua->mirror should work better on dosish systems (can not
+    rename when target file exists).
+
+ o  Typo in lwp-download prevented it from compiling.
+
+ o  Some minor documentations typos corrected.
+
+
+
+Sat Sep 20 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.13
+
+ o  Brand new module called HTTP::Cookies.  It stores cookies
+    (Set-Cookie and Set-Cookie2 headers) from responses and can
+    create appropriate Cookie headers for requests.  It can also
+    share cookie files with Netscape.
+
+ o  LWP::UserAgent now support the cookie_jar() attribute.  When
+    set to an HTTP::Cookies object, it will automatically manage
+    the cookies sent to the servers.  Off by default.
+
+ o  New header utility functions in HTTP::Headers::Util.
+
+ o  Win32 and OS/2 patches for the lwp-xxx utilities.  Turn on
+    binary mode by default (option to turn it off), avoid modifying $0,
+    and don't be confused about suffixes in the script names.
+    Contributed by Ben Coleman <bcoleman@mindspring.com>
+
+ o  OpenVMS patch for Font:AFM by Brad Hughes <brad@tmc.naecker.com>
+
+
+
+Fri Sep  5 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.12
+
+ o  decode_entities() would sometimes introduce ";" after
+    things that looked like they were entities.
+
+ o  HTML::LinkExtor knows about <applet code="...">
+
+ o  Patch from Gary Shea <shea@gtsdesign.com> that makes the
+    tests work even if perl is not called "perl"
+
+ o  HTTP::Date handles 12:00PM correctly now. Patch from
+    William York <william@mathworks.com>
+
+ o  HTTP::Request::Common don't quote the boundary string for
+    multipart/form-data messages any more.
+
+ o  Font::AFM works for encodings where .notdef is defined to
+    have some size.  Documentation and efficiency update.
+
+
+
+Wed Aug  6 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.11
+
+ o  Perl version 5.004 is now required for libwww-perl.
+
+ o  Win32 patches from Gurusamy Sarathy <gsar@engin.umich.edu>.
+    Now passes all tests on that platform.
+
+ o  HTTPS support contributed by Josh Kronengold <mneme@mcny.com>
+
+ o  Support hex entities &#xFF;  HTML::Entities::(en|de)code only
+    modify their argument in void context.
+
+ o  Fixed formatter bug with <font> tags which did not specify size.
+
+ o  Better HTML::HeadParser documentation
+
+ o  Fixed HTML::LinkExtor documentation typo spotted by Martijn.
+
+ o  HTTP::Request::Common now use CRLF for multipart/form-data
+
+
+
+Fri Jun 20 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.10
+
+ o  Make '+' a reserved URL character.  Decode unescaped '+' as
+    space in $url->query_form().
+
+ o  Use $Config{d_alarm} to determine default for $ua->use_alarm()
+
+
+
+Tue Jun 10 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.09
+
+ o  Removed the MIME modules from the distribution.  They are distributed
+    separately now.
+
+ o  Added a new module called HTTP::Request::Common
+
+ o  Improved HTTP::Status documentation.  It is now also possible
+    to import the is_client_error/is_server_error functions.
+
+ o  LWP::MediaTypes::guess_media_type() can now take an optional
+    HTTP::Header parameter.
+
+ o  LWP::Protocol ensures that scheme is legal as module name.
+
+ o  LWP::Protocol::http is not as strict when trying to verify the
+    method name.  It now also accepts responses without a message
+    on the status line.
+
+ o  WWW::RobotRules::AnyDBM_File: Some DBMs fail to allow multiple
+    opens of the same file.  Patch from Mark James <jamesm@skate.org>
+
+ o  Created Bundle::LWP
+
+
+
+Sat Apr  5 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.08
+
+ o  Made libwww-perl warning compatible with upcoming perl5.004beta2
+    (aka 5.003_98)
+
+ o  encode_base64() did not work properly if pos() of the string to
+    encode was different from 0.
+
+ o  HTML::Parser was confused about "</" when it did not start an end tag.
+
+ o  HTML::FormatPS will provide ISOLatin1Encoding in its output.
+
+ o  Calling HTML::LinkExtor->links will clear out old links.
+
+ o  url()->rel($base) would ignore the $base argument.
+
+ o  Don't croak() when setting url()->path().
+
+
+
+Tue Feb 11 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.07
+
+ o  Can limit the size of the response content with $ua->max_size()
+
+ o  Added time2iso() functions to HTTP::Date.
+
+ o  Made LWP::Protocol::http more portable to the MacPerl. /./ match
+    different things on MacPerl.
+
+
+
+Mon Jan 27 1997   Gisle Aas <aas@sn.no>
+
+ o  Release 5.06
+
+ o  URI::URL is now compatible with perl5.004 overloading.
+
+ o  HTML::HeadParser makes X-Meta-Name headers for <meta> elements
+    that does not specify an 'http-equiv' attribute.
+
+ o  URI::URL::ftp does not die if Net::Domain is not installed and
+    you ask for an anonymous username or password.
+
+ o  WWW::RobotRules:  The robots.txt parser did not ignore comment lines
+    as it should.
+
+ o  LWP::Protocol::http is more forgiving towards servers that return
+    bad responses.
+
+ o  Allow "?" before search string in gopher URLs.
+
+ o  LWP::Protocol::file did not escape funny filenames when generating
+    HTML directory listings.
+
+ o  LWP::Protocol::ftp now gets the Content-Encoding correct. 'CODE'
+    content in PUT requests also work now.
+
+ o  Relative locations in redirects did not work with URI::URL::strict.
+
+ o  OS/2 portability patches from Ilya Zakharevich
+
+ o  LWP::Authen::* patch from Doug MacEachern
+
+ o  Support experimental data:- URLs
+
+ o  Some tests (those using HTTP::Daemon) now die more gracefully if
+    IO::* modules is not installed.
+
+
+
+Wed Dec  4 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5.05
+
+ o  LWP::UserAgent::simple_request: local($SIG{__DIE__}) protects us
+    against user defined die handlers.
+ 	
+ o  Use Net::Domain (instead of Sys::Hostname) to determine FQDN.  It
+    is used by URI::URL when it determines anonymous ftp login address.
+	
+ o  lwp-download: New program in the bin directory
+
+ o  HTML::Parser: Allow '_' in attribute names.  This makes it possible
+    to parse Netscape's bookmarks.html file.
+
+ o  HTTP::Daemon: Fixed chunked transfer encoding and multipart content
+    in get_request().  Support HTTP/0.9 clients.
+
+ o  Don't clobber regex variables when HTTP::Message delegates methods
+    to the header.
+
+ o  Base64::decode_base64 now checks that the length input string to
+    decode is a multiple of 4.
+
+ o  t/robot/rules-dbm.t clean up better and will use AnyDBM for dumping
+
+ o  File::CounterFile: $/ strikes again by Andreas König
+
+ o  File::Listing updates from William York <william@mathworks.com>. We
+    can now parse the MS-Windows ftp server listings.
+
+ o  HTTP::Date now supports the MS-Windows 'dir' date format.  Patch by
+    William York.
+
+ o  LWP::MediaTypes::media_suffix will return first type in scalar context.
+
+
+
+Tue Oct 22 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5.04
+
+ o  Added HTTP::Daemon.  This is a HTTP/1.1 server class.  This means
+    that libwww-perl no longer is a client library only.  The HTTP::Daemon
+    is also used in the new test suite.
+
+ o  HTTP::Message support the protocol() method.  Used by HTTP::Daemon.
+
+ o  HTTP::Response can be constructed with a header and content as
+    argument.
+
+ o  Typo corrections in the documentation.
+
+ o  File::Listing::parse_dir accepts "GMT" as timezone now.
+
+ o  HTML::Parser will call the start() method with two new parameters;
+    $attrseq, $origtext.
+
+ o  Integrated HTML::FormatPS patches from
+    Jim Stern <jstern@world.northgrum.com>
+
+ o  Class modules don't inherit from AutoLoader any more.  They just
+    import the AUTOLOAD method.
+
+ o  LWP::Protocol will untaints scheme before loading protocol module.
+
+ o  Digest does not send "opaque" if it was not present in the request.
+    The "Extension" header is not returned any more.
+
+ o  New method: $url->crack that will return a list of the various
+    elements in a URI::URL.
+
+ o  WWW::RobotRules did not use the agent() method when determining
+    who we are.  This affected WWW::RobotRules::AnyDBM_File parsing
+    for robots.txt.  Visit count did not increment for
+    WWW::RobotRules::InCore.
+
+
+
+Tue Oct  1 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5.03
+
+ o  Hakan Ardo's persistent robot rules is now part of the standard
+    distribution.  This is still experimental and might change in the
+    future.  It includes the new WWW::RobotRules::AnyDBM_File class
+    and updates to LWP::RobotUA.
+
+ o  HTML::Parser now supports buggy Netscape comment parsing.  Enable
+    it by calling $p->netscape_buggy_comment(1).  The previous version
+    of the parser could also (under very unlucky and unlikely
+    circumstances) call the $self->comment() method several times for
+    the same comment text.
+
+ o  HTML::Parser: Use new $p->eof to signal end of document instead of
+    $p->parse(undef).
+
+ o  HTML::Element::starttag() is now smarter about which quotes it
+    use around attribute values.
+
+ o  New HTTP::Response methods: current_age(), freshness_lifetime(),
+    is_fresh(), fresh_until().
+
+ o  HTTP::Message:  New method ($mess->content_ref) which will return
+    a reference to the current content.
+
+ o  URI::URL:  New method ($url->rel) which does the opposite of abs().
+    Example: url("http://host/a/b/c", "http://host/c/d/e")->rel would
+    return url("../../a/b/c", "http://host/c/d/e").  This was
+    suggested by Nicolai Langfeldt <janl@ifi.uio.no>
+
+ o  URI::URL:  $url->query_form can now take array references as value
+    specification.  For instance: $url->query_form(foo => ['bar', 'baz']
+
+ o  Avoid '"my" variable $var masks earlier declaration in same scope'
+    warnings in perl5.003_05.
+
+
+
+Wed Sep 11 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5.02
+
+ o  lwp-rget:  Initialize proxy settings from envirionment
+
+ o  HTML::Entities::encode_entities: Don't encode $ and %
+
+ o  HTML::LinkExtor::links: Now works when no links were found.
+
+ o  HTTP::Headers::as_string: Allow \n in header value
+
+
+
+Tue Aug  1 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5.01.
+
+ o  Updated ftp protocol module to be compatible with Net::FTP 
+    version 2.00 (the version found in libnet-1.00)
+
+ o  New HTML parser module called HTML::LinkExtor
+
+ o  Various documentation typo corrections.  Most of these contributed
+    by Bob Dalgleish.
+
+ o  HTML::HeadParser updates 'Content-Base' instead of 'Base'.  It also
+    updates the 'Link' header based on <link ...>
+
+ o  HTTP::Headers and HTTP::Status updated according to
+    draft-ietf-http-v11-spec-06
+
+ o  HTTP::Headers can now use "_" as alternative to "-" in field names.
+
+ o  HTTP::Response::base now looks for 'Content-Base',
+    'Content-Location' and 'Base' headers.
+
+ o  Avoid warning in LWP::MediaTypes if $ENV{HOME} is not defined.
+
+ o  The new $ua->parse_head() method can be used to turn off
+    automatic initialization of response headers from the <HEAD>
+    section of HTML documents.
+
+ o  Added eq() method for URI::URL objects
+
+ o  The HTML::Formatter recovers even if a handle method is not defined
+    for all tags found during traversal
+
+
+
+Sun May 26 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5.00.
+
+ o  LWP::Simple::head() now return something useful in scalar context.
+
+ o  Rewritten the HTML::Parse stuff.  Introduced the HTML::Parser class
+    that will tokenize a HTML document.  The rest of the old
+    HTML::Parse functionality has moved to HTML::TreeBuilder class.
+    Note, that the HTML stuff is still alpha.
+
+ o  Implemented HTML::HeadParser.  This is a lightweight parser for
+    the <HEAD> section of a HTML document.
+
+ o  HTML::Element had problem with presenting things like <foo
+    bar="bar">.
+
+ o  HTML::Entities: Included additional ISO-8859/1 entities listed in
+    RFC1866.
+
+ o  HTML::AsSubs exported 'header' instead of 'head'
+
+ o  We know about a few more of the HTML 3.2 element.
+
+ o  HTTP::Date had problems with years before 1970, because Time::Local
+    went into an infinite loop.  Check for this.
+
+ o  Added $header->title method.
+
+ o  Made $header->authorization_basic return "uname:passwd" in scalar
+    context
+
+ o  LWP::Protocol::collect() will let the HTML::HeadParser look at the
+    document content as it arrives.  This will initialize headers from
+    elements like <base href="...">, <title>...</title> and <meta
+    http-equiv="..." ...>.
+
+ o  Simplified $response->base implementation, because we don't have
+    to look into the content any more.
+
+ o  Added -quiet option to lwp-rget
+
+ o  Typo fixes and some documentation additions.
+
+
+
+Thu May  9 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5b13
+
+ o  Made URI::URL::strict(0) the default.  I got tired of all this
+    eval { } stuff just to recover.  The URI::URL::strict'ness also
+    determine if calling some standard method that happens to be
+    illegal for some protocol scheme will croak or just be ignored.
+
+ o  Ensure correct $INPUT_RECORD_SEPARATOR and $OUTPUT_RECORD_SEPARATOR
+    at places where we <> or print.
+
+ o  Always localize $_ before any 'while(<FILE>) {}'-loops
+
+ o  Implemented $protocol->collect_once() and simplified several
+    of the protocol implementations by using it.
+
+ o  The HTML parser used to get it wrong if you were unlucky about the
+    breakup of the text. An example of broken behaviour was this:
+
+        $html = parse_html "<!-- A comment -";
+        $html = parse_html "-> and some text.";
+
+ o  The HTML parser does not ignore whitespace-only text any more.
+
+ o  HTML::Parse warnings are now optional and turned off by default.
+
+ o  New start for $html->as_HTML().
+
+ o  Fixed some typos
+
+
+
+Wed Apr 24 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5b12
+
+ o  New utility program called 'lwp-rget'.
+
+ o  $response->base was broken for HTML documents
+
+ o  New fancy LWP::Debug import() method.  Can now turn on debugging with
+    "use LWP::Debug '+';"
+
+ o  Trap exceptions (die) from the response callback routine
+
+ o  The RobotUA now requires an e-mail address of the person reponsible
+    for the robot.
+
+ o  New $ua->from() method.
+
+ o  Support for gopher Index-Search (gopher type '7' requests).
+    Contributed by Harry Bochner <bochner@das.harvard.edu>
+
+ o  Cleaned up white-space usage in the source.
+
+
+
+Wed Apr  3 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5b11
+
+ o  Implemented a NNTP protocol module.  The library can now fetch and
+    post news articles.
+
+ o  More documentation
+
+ o  Don't look at the URI header for redirects
+
+ o  New $res->base() method for HTTP::Responses
+
+ o  Graham Barr's patch to File::Listing to make it more OO internally
+
+ o  content_type() return value is canonicalized
+
+ o  $ua->request() does not die on bad URLs any more
+
+ o  LWP::MediaTypes merge all media.types files that if finds
+
+ o  FTP request with content to file or callback did not work
+
+ o  The value of HTTP Host: header is now $url->netloc;
+
+ o  The URI::URL constructor now accept URLs wrapped up in "<>"
+
+ o  $url->abs() now has a second optional argument that makes it accept
+    that relative URLs can have scheme, i.e. treat "http:img.gif" as a
+    relative URL.
+
+ o  Added prototypes to the HTTP::Status::is_xxx() functions
+
+ o  Added prototypes to the MIME:: encoding/decoding functions
+
+ o  Always return scheme for mailto and news URLs (as_string)
+
+ o  RobotRules patches from Henry A Rowley.
+
+ o  More tests
+
+ o  <SMALL> and <BIG> again
+
+
+
+Thu Mar 14 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5b10
+
+ o  GET ftp://host/doc was never successful for normal files.
+
+ o  LWP::Socket: read_until() did not notice EOF condidtion.  I.e. if
+    a HTTP server closed the connection before any output was generated,
+    the we continued to read 0 bytes in a busy loop until the alarm()
+    killed us.
+
+ o  Added support for Digest Access Authentication.  Contributed by
+    Doug MacEachern <dougm@osf.org>.
+
+ o  Makefile.PL: check for MD5 library
+
+ o  No longer print message content in HTTP::Response::error_as_HTML()
+
+ o  Access to "file:/path" gave warning when the envirionment variable
+    no_proxy was set.
+
+ o  The http-post test sends a Content-Type header.  Some servers hang
+    if this header is missing.
+
+ o  HTML::Parse:
+     -   allow <SMALL> and <BIG> tags
+     -   allow empty attribute values
+
+
+
+Tue Mar  5 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5b9
+
+ o  Started to write on the libwww-perl cookbook (lwpcook.pod)
+
+ o  The URI::URL module now exports the function url().  This is an
+    alternative (easy to use) constructor function.
+
+ o  Expanding relative file URLs starting with "#" did not work.
+
+ o  Fixed autoloaded DESTROY problem by adding empty DESTROY routine
+    to URI::URL.
+
+ o  Does not try generate password for ftp-URLs unless the username is
+    "anonymous" or "ftp"
+
+ o  The LWP::Simple user agent proxy settings are intialized from
+    the proxy environment variables. 
+
+ o  LWP::Protocol::ftp: Use the Net::FTP library to access ftp servers.
+    Convert directories to HTML on request (Accept: text/html).
+
+ o  New module HTTP::Negotiate
+
+ o  New module File::Listing
+
+ o  HTTP::Date::str2time can parse a few more formats, like the 'ls -l'
+    format and ISO 8601.  The function now also takes an optional second
+    parameter which specify a default time zone.
+
+ o  Added prototypes to the HTTP::Date functions.
+
+ o  The library adds a timestamp to responses ("Client-Date")
+
+ o  HTTP::Status:  Updated to proposed HTTP/1.1
+
+ o  HTTP::Headers: Updated to proposed HTTP/1.1
+
+ o  LWP::Protocol::http:  Updated to HTTP/1.1 methods
+
+ o  Took out stringify overloading in HTML::Element.
+
+
+
+Mon Feb 26 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5b8
+
+ o  Renamed functions using thisStyleOfNames to this_style_of_names.
+    Provided a script called 'update_from_5b7'
+
+ o  Renamed the 'request' and 'mirror' scripts to 'lwp-request' and
+    'lwp-mirror'.  The GET, POST, HEAD aliases for 'lwp-request' are
+    the same.
+
+ o  Implemented LWP::RobotUA
+
+ o  Class name for RobotRules did not match the file name
+
+ o  URI::URL
+      - perl5.002gamma is required (because use vars).
+      - The leading slash in now part of the path if it is present.
+      - More documentation
+      - Use AutoLoader to speed things up.
+      - New class URI::URL::_login and made telnet, rlogin, tn3270
+        subclasses from this one.
+      - URI::URL::wais is better supported.
+      - URI::URL::news is better supported.
+      - New URI::URL::mailto methods: user/host
+
+ o  HTTP::Date::time2str now works correctly with '0' as argument
+
+ o  HTTP::Message delegates unknown methods to the headers.
+
+ o  HTTP::Request::uri is an alias for HTTP::Request::url.  Can set
+    the URL to undef.
+
+ o  Added convenience methods to HTTP::Headers for easy access to
+    frequently used headers.
+
+ o  Simplified LWP::Debug
+
+ o  Use standard AutoLoader for LWP::IO functions.
+
+ o  Played with the profiler (Devel::DProf) and made some things
+    go quicker.
+
+ o  Included the File::CounterFile module.  Excluded Mail::Cap module
+    as it is also part of the MailTools package.
+
+
+
+Mon Feb  5 1996   Gisle Aas <aas@sn.no>
+
+ o  Release 5b7
+
+ o  Perl5.002 is required now
+
+ o  Rewrite of the URI::URL module (version 4.00)
+      - escaping/unsafe stuff redone (and removed)
+      - URI::URL::_generic moved out of URL.pm
+      - netloc, path, params, query is now stored internally in escaped form
+      - new methods for URI::URL::_generic are:
+           epath
+           eparams
+           equery
+	   path_components
+           absolute_path
+      - new methods for URI::URL::http are:
+           keywords
+           query_form
+      - new methods for URI::URL::file are:
+           newlocal
+           local_path
+           unix_path
+           dos_path
+           mac_path
+           vms_path
+
+ o  URI::Escape now semi-compile regular expressions (by evaling an
+    anonymous sub).  Same techinque is also used in HTML::Entities.
+
+ o  HTTP::Date parser rewritten using regular expressions.
+
+ o  HTTP::Headers->as_string() now croaks if any field values
+    contain newline.
+
+ o  HTTP::Status constants use empty prototype.
+
+ o  Font metrics moved to a new subdirectory (lib/Font/Metrics)
+
+ o  Don't use the VERSION script any more (even if it was very clever)
+
+ o  HTML::Entities will now export the names decode_entities() and
+    encode_entities().
+
+ o  Andreas Koenig's black patch to HTML::Element.
+
+ o  The HTML::Formatter now knows about <menu> and <dir> tags
+
+ o  The construct "defined ref($arg)" did not work on perl5.002
+    becase ref now always return something defined.
+
+ o  LWP::UserAgent sends by default an 'User-Agent' header.
+
+ o  LWP::Simple sends 'User-Agent' header to servers.
+
+ o  Updated the LWP::Socket module to use the new Socket.pm interface.
+
+ o  LWP::Protocol::http sends the new HTTP/1.1 'Host' header.
+
+ o  LWP::Protocol::file use $url->local_path to get a file to open.
+    It also inserts a <BASE> tag in directories instead of a redirect.
+
+ o  MIME::Base64 routines can be called as MIME::Base64::encode() and
+    MIME::Base64::decode().  Same kind of thing for QuotedPrint.
+
+
+
+Mon Nov  6 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Release 5b6
+
+ o  Installation should work better for those that still runs
+    perl4 as 'perl'.  The mirror script is not installed by
+    default.
+
+ o  LWP::Socket::_getaddress() Numerical IP adresses did not work.
+
+ o  LWP::Socket::pushback() did not work.  This also avoids the bad
+    pp_select() core dump from perl.
+
+ o  LWP::IO now also selects on socket exceptions.
+
+ o  HTML::Parse:  Ignore <!DOCTYPE ...> regardless for case.  Some
+    bad insertElement() calls made infinite loops.
+
+ o  The uri.t test works better for places where /tmp is a sym-link.
+
+
+
+Sat Sep 16 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Release 5b5
+
+ o  newlocal URI::URL does not put "//localhost" into the URLs any
+    longer.
+
+ o  The request program: New -o option to reformat the HTML code
+    New -C option to provide credentials on the command line.
+    The -b option never worked.
+
+ o  LWP::Protocol::file now returns redirect for access to directories
+    where the trailing slash is missing.
+
+
+
+Thu Sep 14 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Speedups and bug fixes in the HTML parser.  The parser now
+    understands some more depreciated tags (like <xmp> and <listing>).
+
+ o  HTML::Elements are now stingified using perl overloading.
+    The interface to the traverse() callback has changed.
+
+ o  Implemented HTML formatters for plain text and Postscript.
+
+ o  Added lib/Font stuff to support the Postscript formatter.
+
+ o  Inspired by Tim Bunce, I implemented the HTML::AsSubs module.
+    Don't know if it is really useful.
+
+ o  The local/get test does not use /etc/passwd any more.
+
+
+
+Thu Sep  7 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Changed package name to libwww-perl-5xx
+
+ o  Made LWP::Protocol::ftp actually transfer data
+
+ o  Implemented methods for LWP::Socket to act as a server:
+    bind(), listen(), accept(), getsockname(), host(), port()
+
+
+
+Wed Sep  6 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Release 0.04
+
+ o  Implemented modules to parse HTML.
+
+
+
+Mon Sep  4 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Implemented Mail::Cap which will become part of the MailTools
+    package.
+
+ o  Moved Base64 to MIME::Base64.  Reimplemented MIME::Base64 by using
+    [un]pack("u",...)   Implemented LWP::MIME::QuotedPrint for
+    completness sake.  Routine names has changed as suggested by Tim
+    Bunce.
+
+ o  LWP::MediaType reads default types from media.types file.
+    guessMediaType() now also returns encodings.  New function mediaSuffix()
+
+ o  Pass $url to $ua->getBasicCredentials().  This also fixes security
+    hole with the old implementation of getBasicCredentials().
+
+ o  LWP::Protocol::file now sets Content-Encoding headers
+
+ o  Allow request content to be provided by a callback routine.
+
+ o  Fix bug that prevented response callback to work.  The first parameter
+    (data) is no longer a reference, because $_[0] is already a reference.
+    Don't callback unless successful response.  Callbacks during redirects
+    was confusing.
+
+ o  URI::URL.  Remove port from netloc if it is the default port.
+    Don't use anything, just require.
+
+ o  HTTP::Message->addContent() does not need a reference parameter.
+
+ o  LWP::Socket->open() has been renamed top LWP::Socket->connect()
+    LWP::Socket->close has gone.  Implemented new method LWP::Socket->read()
+    that returns as fast as it has some data to offer.  Implemented
+    LWP::Socket->pushback().
+
+ o  Does not die in LWP::UserAgent->request()
+
+ o  LWP::Socket now use LWP::IO for low level IO
+
+ o  Implemented LWP::TkIO as a replacement module for LWP::IO when using Tk.
+
+
+
+Thu Aug 17 1995   Gisle Aas <aas@oslonett.no>
+
+ o  $ua->redirectOK() for checking redirects
+
+ o  reorganized tests in the "t" directory.
+
+
+
+Fri Aug 11 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Release 0.03
+
+ o  Included RobotRules.pm from Martijn Koster
+
+
+
+Thu Aug 10 1995   Gisle Aas <aas@oslonett.no>
+
+ o  New module URI::Escape (URI::URL use this module for default
+    escaping) that provide the uri_escape() and uri_unescape()
+    functions.
+
+ o  Setting $url->scheme now changes the class of the object.
+
+ o  Made $httpurl->user() and $httpurl->password() illegal.
+    Likewise for other URL schemes.
+
+
+
+
+Wed Aug  9 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Reorganisation as discussed on <libwww-perl@ics.uci.edu>
+       LWP::Date       --> HTTP::Date
+       LWP::MIMEheader --> HTTP::Headers
+       LWP::StatusCode --> HTTP::Status
+       LWP::Message    --> HTTP::Message
+       LWP::Request    --> HTTP::Request
+       LWP::Response   --> HTTP::Response
+       LWP::MIMEtypes  --> LWP::MediaTypes
+
+ o  HTTP::Date parses ctime format with missing timezone as suggested
+    by Roy Fielding <fielding@beach.w3.org>
+
+ o  HTTP::Status and LWP::MediaTypes exports their functions by default.
+
+ o  Splitted up the URI::URL module.  Schemes are implemented by separate
+    files that are autoloaded when used.  Self test moved to "t/uri.t".
+
+
+       
+Mon Aug  7 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Applied patch from Marc Hedlund <hedlund@best.com>
+       - Update the @header_order according to the August 3rd draft.
+       - Added Response Header fields: 'Location', 'Public', 'Retry-After',
+         'Server', and 'WWW-Authenticate'.
+       - Moved 'unknown header' handling from &scan to &header. The old
+         implementation was forcing all unknown header-words to begin with
+	 an uppercase (as it should be), but disallowed other uppercase
+	 letters.
+       - updates the status code messages under the August
+         3rd HTTP/1.0 draft.  '203' became 'Non-Authoritative Information',
+	 '303' became 'See Other', and a new code,
+	 '411 Authorization Refused', was added.
+
+ o  Can remove multiple headers with single removeHeader() call in MIMEheader.
+
+ o  Can assign multiple field/value pairs in header() method of MIMEheader.
+
+ o  A field with multiple values is printed as separate values in
+    MIMEheader::as_string().
+
+ o  LWP::Response contain new attributes: previous() and request().  These
+    attributes are updated by the UserAgent.
+
+ o  Appended \n to some die statements in Socket so that line numbers are
+    suppressed in error messages.
+
+ o  Made UserAgent::clone work for reference members
+
+ o  Check for redirect loops and multiple authorization failures by
+    examination of the response chain.
+
+ o  Use "\015\012" instead of "\r\n" in protocol modules.  Some systems
+    define \r and \n differently.
+
+ o  request program can now handle documents that needs autorization by
+    prompting the user for username/password. Added new -S option to print
+    request/response chain.
+
+
+  
+Tue Jul 25 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Release 0.02
+
+ o  Included URI::URL in the release
+
+
+
+Mon Jul 24 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Incorporated Makemake.PL and VERSION from Andreas Koenig <koenig@mind.de>
+    As a result of this the following things have changed:
+       - programs in "bin" are extracted from .PL-files
+       - reintroduced "lib"
+       - "test" has been renamed as "t"
+       - test programs in "t" has been made Test::Harness compatible
+       - we now have a MANIFEST file
+       - no more need fro update_version, make-dist, lwp-install
+
+ o  Renamed bin/get to bin/request.  Links to it are now all upper case.
+
+ o  Proxy support in bin/request (provided by Martijn Koster)
+
+ o  UserAgent can now load proxy settings from environment
+
+ o  LWP::Protocol::ftp is under way but not really finished
+
+
+
+Tue Jul 18 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Implemented LWP::Protocol::gopher
+
+ o  Implemented LWP::Protocol::mailto
+
+ o  Fixed proxy typo
+
+
+
+Mon Jul 17 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Made release 0.01
+
+
+
+Mon Jul 17 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Don't loose first line of HTTP/0.9 requests
+
+ o  LWP::Socket use syswrite() for writing
+
+ o  Added RC_* documentation to LWP::StatusCode
+
+ o  LWP::Date now use hash to look up month numbers
+
+ o  Added -f option to "get"
+
+ o  Untabify
+
+ o  Added a "TODO" list
+
+ o  Fixed various typos
+
+
+
+Fri Jul 14 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Reorganized directories.  Moved LWP.pm up.  Moved file.pm and http.pm
+    into the LWP::Protocol direcotory.  Moved LWP out of the lib directory
+    and removed lib.
+
+ o  Implemented the "get" and "mirror" scripts in the "bin" directory.
+
+ o  Implemented "install-lwp", "update_version" and "make-dist".  The library
+    version number is found in the VERSION file.
+
+ o  Always adds 1900 to the year in LWP::Date
+
+ o  In LWP::MIMEheader:  Implemented clone(), removeHeader() and scan() 
+    methods.  Reimplemented asString.  Removed asMIME().  Moved "Good
+    Practice" into this file, and reimplemented it.
+
+ o  Moved "header" and "content" into LWP::Message class.  This change made
+    LWP::Request and LWP::Response much simpler.  Made clone() method
+    actually work.
+
+ o  LWP::Protocol::implementor does not die if it cannot load package.
+
+ o  Moved UserAgent convenience methods into LWP::Simple.  Made LWP::Simple
+    export LWP::StatusCode symbols and functions.
+
+ o  Implemented $ua->isProtocolSupported($scheme) method.
+
+ o  Nicer directory listing in LWP::Protocol::file.pm
+
+ o  Rely on URI::URL 3.00 behaviour for $url->full_path
+
+ o  Library version number now in LWP.pm.  You should be able to say
+    "use LWP 1.0;" if you need at least this version.
+
+ o  Various cleanups and arranging layout as I like it.  Use fooBar-style
+    (as opposed to foo_bar stype) everywhere.  This means that as_string()
+    now is called asString().
+
+ o  Added more documentation.
+
+
+
+Wed Jun 14 1995   Gisle Aas <aas@oslonett.no>
+
+ o  Removed lot of rendundant & before function calls.
+
+ o  $this --> $self
+
+ o  &collector passes content as a reference, don't want to copy so much
+
+ o  parameterlist to collect callback has been rearranged
+
+ o  Response::addContent gets a reference to the data
+
+ o  Added some callback documentation to UserAgent.pm
+
+ o  Protocol::file now uses the collector
+
+ o  Introduced LWP::Simple
+
+
+
+Sun Jun 11 1995   Martijn Koster <m.koster@nexor.co.uk>
+
+ o  Added basic authentication support
+
+ o  Added mirroring of single documents
+
+ o  Change Protocol construction from whacky URL.pm (constructor returns
+    subclass) to more normal C++'ish way.
+
+
+
+Wed June 7 1995   Martijn Koster <m.koster@nexor.co.uk>
+
+ o  Minor cleanups from printed code inspection
+
+
+
+Wed May 24 1995   Martijn Koster <m.koster@nexor.co.uk>
+
+ o  Added redirection resolution
+
+ o  Added optional autoloading of protocols
+
+
+
+Tue May 23 1995   Martijn Koster <m.koster@nexor.co.uk>
+
+ o  Separated socket stuff into separate module
+
+ o  Added HTTP proxy support
+
+ o  Made alarm handling optional
+
+ o  Added a LWP::Message for completeness sake
+
+ o  Added LWP::MemberMixin to reduce code duplication
+
+ o  Cosmetic changes to LWP::Date
+
+ o  Renamed LWP::Error to LWP::StatusCode
+
+ o  Renamed LWP::MIME to LWP::MIMEtype
+
+ o  Changed the tests to cope with all this
+
+It's getting there...
+
+
+
+Mon May 22 1995   Martijn Koster <m.koster@nexor.co.uk>
+
+ o  Changed the socket reading to use sysread.  This will have to go
+    into a module of its own.
+
+
+
+Thu 18 May 1995   Martijn Koster <m.koster@nexor.co.uk>
+
+ o  Mentioned on libwww-perl that I had changed the classes around lots.
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/INSTALL.w3mir
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/INSTALL.w3mir	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/INSTALL.w3mir	(revision 20131)
@@ -0,0 +1,48 @@
+
+- Get libwww-perl from CPAN 
+  (http://www.perl.com/CPAN/modules/by-module/WWW/).  W3mir does not work
+  with LWP 5.40 and later versions.  Please get an earlier version.
+  It also does not work with the new URI package.  Use the URI package
+  enclosed in the older LWP.
+
+- Unpack it:
+
+    gzip -dc libwww-perl-*.tar.gz | tar xvBf -
+
+- Install it.  W3mir does not require the whole libwww-perl package and
+  all the packages that goes with it to work so you may follow these
+  install instructions instead of the libwww-perl install instructions
+  to get an easier install which will work with w3mir.
+
+    cd libwww-perl-*
+
+  Are you going to install it in the standard perl place (you need to
+  be the system administrator to do this)? If so:
+
+    perl Makefile.PL
+
+  If not (if you are a user):
+
+    perl Makefile.PL PREFIX=/some/dir
+
+  /some/dir could be ~ (as in your home directory).
+
+  IF you are installing an old LWP just for w3mir you can install both
+  the old LWP, the Base64 module and w3mir in a special PREFIX
+  separate from your usual install PREFIX.  This ensures that w3mir will
+  access the older version of LWP and that other software will access
+  the newer version.  If you do this make sure you install all of LWP,
+  Base64 and w3mir with the same PREFIX.
+
+  This step might produce some complaints;  A standard perl
+  installation will typically get messages about missing these
+  modules: IO::Socket, NET::FTP and MD5.  None of these need be
+  installed to run w3mir and so any error messages about these may
+  safely be ignored.
+
+    make
+    make test      (robot/ua and local/http might fail, that's OK)
+    make install
+
+  Now libwww-perl should be installed and working.
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/MANIFEST
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/MANIFEST	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/MANIFEST	(revision 20131)
@@ -0,0 +1,106 @@
+ChangeLog			History of this package
+MANIFEST			This file
+Makefile.PL			Makefile generator
+README				Get you started with this package
+TODO				The To-Do list for the library
+bin/lwp-download.PL             Writes bin/lwp-download script
+bin/lwp-mirror.PL		Writes bin/lwp-mirror script
+bin/lwp-request.PL		Writes bin/lwp-request script
+bin/lwp-rget.PL			Writes bin/lwp-rget script
+lwpcook.pod			Libwww-perl examples
+lib/Bundle/LWP.pm               Defines prereq modules
+lib/File/Listing.pm		Parse directory listings
+lib/HTTP/Cookies.pm             Cookie storage and management
+lib/HTTP/Daemon.pm		A simple httpd
+lib/HTTP/Date.pm		Date conversion routines
+lib/HTTP/Headers.pm		Class encapsulating HTTP Message headers
+lib/HTTP/Headers/Auth.pm	Some methods that deal with authorization.
+lib/HTTP/Headers/ETag.pm	Some methods that deal with entity tags
+lib/HTTP/Headers/Util.pm        Some utility functions for header values.
+lib/HTTP/Message.pm		Class encapsulating HTTP messages
+lib/HTTP/Negotiate.pm		Evaluate HTTP content negotiation algoritm
+lib/HTTP/Request.pm		Class encapsulating HTTP Requests
+lib/HTTP/Request/Common.pm      Generate common requests
+lib/HTTP/Response.pm		Class encapsulating HTTP Responses
+lib/HTTP/Status.pm		HTTP Status code processing
+lib/LWP.pm			Includes what you need
+lib/LWP/Authen/Basic.pm		Basic authentication scheme
+lib/LWP/Authen/Digest.pm	Digest authentication scheme
+lib/LWP/Debug.pm		Debugging support
+lib/LWP/MediaTypes.pm		Library for guessing media types
+lib/LWP/MemberMixin.pm		Helps you access %$self
+lib/LWP/Protocol.pm		Virtual base class for LWP protocols
+lib/LWP/Protocol/data.pm        Access to data URLs
+lib/LWP/Protocol/file.pm	Access local files
+lib/LWP/Protocol/ftp.pm		Access with the FTP protocol
+lib/LWP/Protocol/gopher.pm	Access with the Gopher protocol
+lib/LWP/Protocol/http.pm	Access with HTTP protocol
+lib/LWP/Protocol/https.pm	Access with HTTP protocol over SSL
+lib/LWP/Protocol/mailto.pm	Allows you to POST mail using sendmail
+lib/LWP/Protocol/nntp.pm	Handles access to news: and nntp: URLs
+lib/LWP/RobotUA.pm		Easy creation of conforming robots
+lib/LWP/Simple.pm		Procedural LWP interface
+lib/LWP/UserAgent.pm		A WWW UserAgent class
+lib/LWP/media.types		Mapping from file extentions media types
+lib/URI/Escape.pm		General URI escaping functions
+lib/URI/Heuristic.pm            User friendly URLs
+lib/URI/URL.pm			Class encapsulating URLs
+lib/URI/URL/_generic.pm		Implements generic hierarchical RL (RFC 1808)
+lib/URI/URL/_login.pm		Base class for telnet, tn3270 and rlogin
+lib/URI/URL/data.pm             Implements data URLs
+lib/URI/URL/file.pm		Implements file URLs
+lib/URI/URL/finger.pm		Implements finger URLs
+lib/URI/URL/ftp.pm		Implements ftp URLs
+lib/URI/URL/gopher.pm		Implements gopher URLs
+lib/URI/URL/http.pm		Implements http URLs
+lib/URI/URL/https.pm		Implements https URLs
+lib/URI/URL/mailto.pm		Implements mailto URLs
+lib/URI/URL/news.pm		Implements news URLs
+lib/URI/URL/nntp.pm		Implements nntp URLs
+lib/URI/URL/prospero.pm		Implements prospero URLs
+lib/URI/URL/rlogin.pm		Implements rlogin URLs
+lib/URI/URL/telnet.pm		Implements telnet URLs
+lib/URI/URL/tn3270.pm		Implements tn3270 URLs
+lib/URI/URL/wais.pm		Implements wais URLs
+lib/URI/URL/webster.pm		Implements webster URLs
+lib/URI/URL/whois.pm		Implements whois URLs
+lib/WWW/RobotRules.pm		Parse robot.txt files
+lib/WWW/RobotRules/AnyDBM_File.pm	Persistent robot rules
+t/README			How to run and set up tests
+t/TEST				Run tests
+t/base/common-req.t		Test HTTP::Request::Common module
+t/base/cookies.t                Test HTTP::Cookies module
+t/base/date.t			Test HTTP::Date module
+t/base/headers.t		Test HTTP::Headers module
+t/base/headers-auth.t		Test HTTP::Headers::Auth module
+t/base/headers-etag.t		Test HTTP::Headers::ETag module
+t/base/headers-util.t		Test HTTP::Headers::Util module
+t/base/listing.t		Test File::Listing module
+t/base/mediatypes.t		Test LWP::MediaTypes module
+t/base/message.t		Test HTTP::Request/HTTP::Response
+t/base/negotiate.t		Test HTTP::Negotiation module
+t/base/response.t		Test additional HTTP::Response methods
+t/base/status.t			Test HTTP::Status module
+t/local/autoload.t		Test autoloading of LWP::Protocol modules
+t/local/get.t			Try to get a local file
+t/local/http.t			Test http to local server
+t/local/protosub.t              Test with other protocol module
+t/net/cgi-bin/moved
+t/net/cgi-bin/nph-slowdata
+t/net/cgi-bin/slowread
+t/net/cgi-bin/test
+t/net/cgi-bin/timeout
+t/net/config.pl.dist		Suggested configuration for net tests
+t/net/http-get.t
+t/net/http-post.t
+t/net/http-timeout.t
+t/net/mirror.t
+t/net/moved.t
+t/net/proxy.t
+t/robot/rules-dbm.t		Test WWW::RobotRules::AnyDBM_File
+t/robot/rules.t			Test WWW::RobotRules
+t/robot/ua.t			Test LWP::RobotUA
+t/uri/abs-config.t              Test URI::URL configuration variables
+t/uri/base.t			Test URI::URL module
+t/uri/rel-base.t		Test URI::URL module some more
+t/uri/heuristic.t               Test URI::Heuristic module
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/Makefile.PL
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/Makefile.PL	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/Makefile.PL	(revision 20131)
@@ -0,0 +1,184 @@
+# This -*- perl -*- script writes the Makefile for libwww-perl
+# $Id$
+
+require 5.004;
+use strict;
+
+#--- Configuration section ---
+
+my @programs_to_install = qw(lwp-request lwp-mirror lwp-rget lwp-download);
+my @request_aliases     = qw(GET HEAD POST);
+
+#--- End Configuration - You should not have to change anything below this line
+
+
+# Allow us to suppress all program installation with the -n (library only)
+# option.  This is for those that don't want to mess with the configuration
+# section of this file.
+use Getopt::Std;
+use vars qw($opt_n);
+unless (getopts("n")) {
+    die "Usage: $0 [-n]\n";
+}
+@programs_to_install = () if $opt_n;
+
+
+# Check for non-standard modules that are used by this library.
+$| = 1;
+my $missing_modules = 0;
+
+print "Checking for HTML::Parser..";
+eval {
+    require HTML::HeadParser;
+};
+if ($@) {
+    print " failed\n";
+    $missing_modules++;
+    print <<EOT;
+$@
+The HTML::Parser is needed to extract correct <BASE> information from
+HTML so that we can resolv relative links correctly.
+
+EOT
+    sleep(2);  # Don't hurry too much
+} else {
+    print " ok\n";
+}
+
+print "Checking for MIME::Base64..";
+eval {
+    require MIME::Base64;
+    #MIME::Base64->require_version('2.00');
+};
+if ($@) {
+    print " failed\n";
+    $missing_modules++;
+    print <<EOT;
+$@
+The Base64 encoding is used in authentication headers in HTTP.
+
+EOT
+    sleep(2);  # Don't hurry too much
+} else {
+    print " ok\n";
+}
+
+print "Checking for Net::FTP......";
+eval {
+    require Net::FTP;
+    Net::FTP->require_version('2.00');
+};
+if ($@) {
+    print " failed\n";
+    $missing_modules++;
+    print <<EOT;
+$@
+The libwww-perl library normally use the Net::FTP module when
+accessing ftp servers.  You would have to install this package or
+configure your application to use a proxy server for making ftp
+requests work.  Net::FTP is part of the 'libnet' distribution.
+
+EOT
+    sleep(2);  # Don't hurry too much
+} else {
+    print " ok\n";
+}
+
+print "Checking for MD5 ..........";
+eval {
+    require MD5;
+};
+if ($@) {
+    print " failed\n";
+    $missing_modules++;
+    print <<EOT;
+$@
+The MD5 library is needed if you want to be able use the experimental
+"Digest Access Authentication" scheme.  Since very few servers
+implement this authentication scheme, you should normally not worry
+too much about this.
+
+EOT
+} else {
+    print " ok\n";
+}
+
+print <<EOT if $missing_modules;
+The missing modules can be obtained from CPAN.  Visit
+<URL:http://www.perl.com/CPAN/> to find a CPAN site near you.
+
+EOT
+
+
+# Ok, now it is time to really generate the Makefile
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+   NAME          => 'libwww-perl',
+   VERSION_FROM  => 'lib/LWP.pm',
+   PL_FILES      => { map {("bin/$_.PL" => "bin/$_")} @programs_to_install },
+   EXE_FILES     => [ map {"bin/$_"} @programs_to_install ],
+   'clean'       => { FILES => '$(EXE_FILES)' },
+   'dist'        => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
+);
+
+
+
+package MY;
+
+sub postamble
+{
+    my @m;
+    if (@request_aliases && grep($_ eq 'lwp-request', @programs_to_install)) {
+	push @m, "all ::\n";
+	if ($^O eq 'MSWin32') {
+	    push @m, "\t\$(FULLPERL) -e \"use Config; chdir q[\$(INST_EXE)]; "
+		    ."foreach (qw(@request_aliases)) { \" \\\n";
+	    push @m, <<'EOT';
+	-e "unlink \"$$_\"; " \
+	-e "system(\"copy lwp-request $$_\") && die; }"
+EOT
+	} else {
+	    push @m, "\t\$(FULLPERL) -e 'use Config; chdir q{\$(INST_EXE)}; "
+		    ."foreach (qw(@request_aliases)) {' \\\n";
+	    push @m, <<'EOT';
+	-e 'unlink "$$_";' \
+	-e 'system("$$Config{\"lns\"} lwp-request $$_") && die; }'
+EOT
+	}
+    }
+    join "", @m;
+}
+
+# What happens when we say 'make test'
+sub test
+{
+    q(
+TEST_VERBOSE=0
+
+test: all
+	$(FULLPERL) t/TEST $(TEST_VERBOSE)
+
+);
+}
+
+
+# Determine things that should *not* be installed
+sub libscan
+{
+    my($self, $path) = @_;
+    return '' if $path =~ m/.(pl|dtd|sgml)$/;
+    return '' if $path =~ m:\bCVS/:;
+    return '' if $path =~ m/~$/;
+    $path;
+}
+
+# Pass libwww-perl version number to pod2man
+sub manifypods
+{
+    my $self = shift;
+    my $ver = $self->{VERSION} || "";
+    local($_) = $self->SUPER::manifypods(@_);
+    s/pod2man\s*$/pod2man --release libwww-perl-$ver/m;
+    $_;
+}
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/README
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/README	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/README	(revision 20131)
@@ -0,0 +1,124 @@
+                     L I B W W W - P E R L - 5
+                   -----------------------------
+
+Libwww-perl is a collection of Perl modules which provides a simple
+and consistent programming interface (API) to the World-Wide Web.  The
+main focus of the library is to provide classes and functions that
+allow you to write WWW clients, thus libwww-perl said to be a WWW
+client library. The library also contain modules that are of more
+general use and even classes that helps you implement simple HTTP
+servers.
+
+There are actually two versions of libwww-perl: one for Perl4, and one
+for Perl5. Both have a similar architecture, loosely based on the CERN
+Library of Common Code (nowadays known as 'w3c-libwww').
+
+The Perl4 version is still(?) maintained by Roy Fielding, and was the
+basis for tools such as MOMSpider. The perl4 version of libwww-perl
+and much more information about its libraries can be found at:
+http://www.ics.uci.edu/pub/websoft/libwww-perl/
+
+The Perl5 version (this package) is a complete rewrite for Perl5: the
+code is organized in Modules, provides an Object Oriented API, is
+updated for the latest HTTP and URL specification, and offers some
+extended functionality.
+
+Full HTTP/1.1 support is on its way.  Alpha releases of the LWPng
+package is currently available from CPAN.
+
+
+PREREQUISITES
+
+In order to install and use this package you will need Perl version
+5.004 or better.  Some modules within this package depend on other
+packages that are distributed separately from Perl.  We recommend that
+you have the following packages installed before you install
+libwww-perl:
+
+  MIME-Base64
+  HTML-Parser
+  libnet
+  MD5
+
+These packages should be available on CPAN.
+
+If you want to access sites using the https protocol, then you need to
+install the Crypt-SSLeay modules first.  (The Net::SSLeay module is not
+supported any more.)
+
+
+INSTALLATION
+
+You install libwww-perl, as you would install any perl module library,
+by running these commands:
+
+   perl Makefile.PL
+   make
+   make test
+   make install
+
+You can edit the configuration section of Makefile.PL to select which
+programs to install in addition to the library itself.  If you don't
+want to install any programs (only the library files) and don't want
+to mess with the Makefile.PL then pass the '-n' option to Makefile.PL:
+
+   perl Makefile.PL -n
+
+If you want to install a private copy of libwww-perl in your home
+directory, then you should try to produce the initial Makefile with
+something like this command:
+
+  perl Makefile.PL LIB=~/perl
+
+The Makefile.PL program will start out by checking your perl
+installation for a few packages that are recommended to be installed
+together with libwww-perl.
+
+Optional network tests are _not_ enabled automatically when you unpack
+this package.  Consult the t/README file for instructions on how to
+enable these tests.
+
+
+DOCUMENTATION
+
+See lib/LWP.pm for an overview of the library. See ChangeLog for
+recent changes.  POD style documentation is included in all modules
+and scripts.  These are normally converted to manual pages and
+installed as part of the "make install" process.  You should also be
+able to use the 'perldoc' utility to extract and read documentation
+from the module files directly.
+
+
+SUPPORT
+
+Question about how to use this library should be directed to the
+comp.lang.perl.modules USENET Newsgroup.  Bug reports and suggestions
+for improvements can be sendt to the <libwww-perl@ics.uci.edu> mailing
+list.  This mailing list is also the place for general discussions and
+development of the libwww-perl package.
+
+You can join the mailing list by sending a message to
+<libwww-perl-request@ics.uci.edu> with "Subscribe" as subject.
+            ^^^^^^^^
+
+AVAILABILITY
+
+The latest version of libwww-perl should always be available from:
+
+     http://www.linpro.no/lwp/
+
+The library is also available from the Comprehensive Perl Archive
+Network (CPAN).  Visit <URL:http://www.perl.com/CPAN/> to find a CPAN
+site near you.
+
+
+COPYRIGHT
+
+  © 1995-1998 Gisle Aas. All rights reserved.
+  © 1995 Martijn Koster. All rights reserved.
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+
+Enjoy!
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/TODO
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/TODO	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/TODO	(revision 20131)
@@ -0,0 +1,46 @@
+                                            $Date$
+
+This is a list over things that we plan to implement in libwww-perl-5.
+The order of items does not reflect priority.
+
+  o  HTTP/1.1 support is on its way.  This also includes support of
+     multiple parallel connections.  Take a look at LWPng (aka
+     libwww-perl-6).
+
+  o  Provide initial credentials so that we don't always have to get a
+     401 response first.  Both for Basic and Digest authentication.  This
+     is in fact implemented for LWPng.
+
+  o  HTTP::Request::Common::POST() should be able to create large
+     file upload requests by making a closure content.
+
+  o  Support PICS??
+
+  o  Cache previous ftp connections.  "Keep-Alive"?
+
+  o  Support MOVE, DELETE method for ftp.
+
+  o  Support If-Modified-Since for ftp.
+
+  o  Use Mail::Send to implement LWP::Protocol::mailto.  Today we just
+     invoke sendmail directly, which is not very portable.
+
+  o  The lwp-request -o processing should check for Content-Encoding as
+     well as Content-Type.
+
+  o  The lwp-request script should optionally consult Mail::Cap for
+     handling of media types.
+
+  o  The lwp-request script should use the callback interface so that it
+     prints data as it is received.
+
+  o  The lwp-mirror script should be able to work recursively.
+
+  o  Include more useful programs
+
+  o  More documentation
+
+  o  More tests
+
+  o  Fix bugs, if there are any...
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/bin/lwp-download.PL
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/bin/lwp-download.PL	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/bin/lwp-download.PL	(revision 20131)
@@ -0,0 +1,248 @@
+use Config;
+use File::Basename qw(basename dirname);
+chdir(dirname($0));
+($file = basename($0)) =~ s/\.PL$//;
+$file =~ s/\.pl$//
+	if ($Config{'osname'} eq 'VMS' or
+	    $Config{'osname'} eq 'OS2');  # "case-forgiving"
+open OUT,">$file" or die "Can't create $file: $!";
+chmod(0755, $file);
+print "Extracting $file (with variable substitutions)\n";
+
+print OUT <<"!GROK!THIS!";
+$Config{'startperl'} -w
+
+!GROK!THIS!
+
+print OUT <<'!NO!SUBS!';
+# $Id$
+
+=head1 NAME
+
+lwp-download - fetch large files from the net
+
+=head1 SYNOPSIS
+
+ lwp-download [-a] <url> [<local file>]
+
+=head1 DESCRIPTION
+
+The I<lwp-download> program will down load the document specified by the URL
+given as the first command line argument to a local file.  The local
+filename used to save the document is guessed from the URL unless
+specified as the second command line argument.
+
+The I<lwp-download> program is implemented using the I<libwww-perl>
+library.  It is better suited to down load big files than the
+I<lwp-request> program because it does not store the file in memory.
+Another benefit is that it will keep you updated about its progress
+and that you don't have much options to worry about.
+
+Use the C<-a> option to save the file in text (ascii) mode.  Might make a
+difference on dosish systems.
+
+=head1 EXAMPLE
+
+Fetch the newest and greatest perl version:
+
+ $ lwp-download http://www.perl.com/CPAN/src/latest.tar.gz
+ Saving to 'latest.tar.gz'...
+ 1.47 MB received in 22 seconds (68.7 KB/sec)
+
+=head1 AUTHOR
+
+Gisle Aas <gisle@aas.no>
+
+=cut
+
+use LWP::UserAgent;
+use LWP::MediaTypes;
+use URI::URL;
+use strict;
+
+my $progname = $0;
+$progname =~ s,.*/,,;    # only basename left in progname
+$progname =~ s/\.\w*$//; # strip extension if any
+
+#parse option
+use Getopt::Std;
+my %opts;
+unless (getopts('a', \%opts)) {
+    usage();
+}
+my $opt_a = $opts{a}; # save in binary mode
+
+my $url = url(shift || usage());
+my $argfile = shift;
+
+my $ua = new LWP::UserAgent;
+
+$ua->agent("lwp-download/0.1 " . $ua->agent);
+$ua->env_proxy;
+
+my $req = new HTTP::Request GET => $url;
+
+my $file;      # name of file we download into
+my $length;    # total number of bytes to download
+my $flength;   # formatted length
+my $size = 0;  # number of bytes received
+my $start_t;   # start time of download
+my $last_dur;  # time of last callback
+
+my $shown = 0; # have we called the show() function yet
+
+$SIG{INT} = sub { die "Interrupted\n"; };
+
+$| = 1;  # autoflush
+
+my $res = $ua->request($req,
+  sub {
+      unless($file) {
+	  my $res = $_[1];
+	  unless ($argfile) {
+	      # must find a suitable name to use.  First thing
+	      # to do is to look for the "Content-Disposition"
+	      # header defined by RFC1806.  This is also supported
+	      # by Netscape
+	      my $cd = $res->header("Content-Disposition");
+	      if ($cd && $cd =~ /\bfilename\s*=\s*(\S+)/) {
+		  $file = $1;
+		  $file =~ s/;$//;
+		  $file =~ s/^([\"\'])(.*)\1$/$2/;
+	      }
+		
+	      # if this fails we try to make something from the URL
+	      unless ($file) {
+		  my $req = $res->request;  # now always there
+		  my $rurl = $req ? $req->url : $url;
+		  
+		  $file = ($rurl->path_components)[-1];
+		  unless (length $file) {
+		      $file = "index";
+		      my $suffix = media_suffix($res->content_type);
+		      $file .= ".$suffix" if $suffix;
+		  } elsif ($rurl->scheme eq 'ftp' ||
+			   $file =~ /\.tgz$/      ||
+			   $file =~ /\.tar(\.(Z|gz))?$/
+			  ) {
+		      # leave the filename as it was
+		  } else {
+		      my $ct = guess_media_type($file);
+		      unless ($ct eq $res->content_type) {
+			  # need a better suffix for this type
+			  my $suffix = media_suffix($res->content_type);
+			  $file .= ".$suffix" if $suffix;
+		      }
+		  }
+	      }
+
+	      # Check if the file is already present
+	      if (-f $file && -t) {
+		  print "Overwrite $file? [y] ";
+		  my $ans = <STDIN>;
+		  exit if !defined($ans) || !($ans =~ /^y?\n/);
+	      } else {
+		  print "Saving to '$file'...\n";
+	      }
+	  } else {
+	      $file = $argfile;
+	  }
+	  open(FILE, ">$file") || die "Can't open $file: $!";
+          binmode FILE unless $opt_a;
+	  $length = $res->content_length;
+	  $flength = fbytes($length) if defined $length;
+	  $start_t = time;
+	  $last_dur = 0;
+      }
+      $size += length($_[0]);
+      print FILE $_[0];
+      if (defined $length) {
+	  my $dur  = time - $start_t;
+	  if ($dur != $last_dur) {  # don't update too often
+	      $last_dur = $dur;
+	      my $perc = $size / $length;
+	      my $speed;
+	      $speed = fbytes($size/$dur) . "/sec" if $dur > 3;
+	      my $secs_left = fduration($dur/$perc - $dur);
+	      $perc = int($perc*100);
+	      my $show = "$perc% of $flength";
+	      $show .= " (at $speed, $secs_left remaining)" if $speed;
+	      show($show);
+	  }
+      } else {
+	  show( fbytes($size) . " received");
+      }
+  }
+);
+
+if ($res->is_success || $res->message =~ /^Interrupted/) {
+    show("");  # clear text
+    print "\r";
+    print fbytes($size);
+    print " of ", fbytes($length) if defined($length) && $length != $size;
+    print " received";
+    my $dur = time - $start_t;
+    if ($dur) {
+	my $speed = fbytes($size/$dur) . "/sec";
+	print " in ", fduration($dur), " ($speed)";
+    }
+    print "\n";
+    my $died = $res->header("X-Died");
+    if ($died || !$res->is_success) {
+	if (-t) {
+	    print "Transfer aborted.  Delete $file? [n] ";
+	    my $ans = <STDIN>;
+	    unlink($file) if defined($ans) && $ans =~ /^y\n/;
+	} else {
+	    print "Transfer aborted, $file kept\n";
+	}
+    }
+} else {
+    print "\n" if $shown;
+    print "$progname: Can't download: ", $res->code, " ", $res->message, "\n";
+    exit 1;
+}
+
+
+sub fbytes
+{
+    my $n = int(shift);
+    if ($n >= 1024 * 1024) {
+	return sprintf "%.3g MB", $n / (1024.0 * 1024);
+    } elsif ($n >= 1024) {
+	return sprintf "%.3g KB", $n / 1024.0;
+    } else {
+	return "$n bytes";
+    }
+}
+
+sub fduration
+{
+    use integer;
+    my $secs = int(shift);
+    my $hours = $secs / (60*60);
+    $secs -= $hours * 60*60;
+    my $mins = $secs / 60;
+    $secs %= 60;
+    if ($hours) {
+	return "$hours hours $mins minutes";
+    } elsif ($mins >= 2) {
+	return "$mins minutes";
+    } else {
+	$secs += $mins * 60;
+	return "$secs seconds";
+    }
+}
+
+sub show
+{
+    my $mess = shift;
+    print "\r$mess", (" " x (75 - length $mess));
+    $shown++;
+}
+
+sub usage
+{
+    die "Usage: $progname [-a] <url> [<lpath>]\n";
+}
+!NO!SUBS!
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/bin/lwp-mirror.PL
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/bin/lwp-mirror.PL	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/bin/lwp-mirror.PL	(revision 20131)
@@ -0,0 +1,120 @@
+use Config;
+use File::Basename qw(basename dirname);
+chdir(dirname($0));
+($file = basename($0)) =~ s/\.PL$//;
+$file =~ s/\.pl$//
+	if ($Config{'osname'} eq 'VMS' or
+	    $Config{'osname'} eq 'OS2');  # "case-forgiving"
+open OUT,">$file" or die "Can't create $file: $!";
+chmod(0755, $file);
+print "Extracting $file (with variable substitutions)\n";
+
+print OUT <<"!GROK!THIS!";
+$Config{'startperl'} -w
+
+!GROK!THIS!
+
+print OUT <<'!NO!SUBS!';
+# $Id$
+#
+# Simple mirror utility using LWP
+
+=head1 NAME
+
+lwp-mirror - Simple mirror utility for WWW
+
+=head1 SYNOPSIS
+
+ lwp-mirror [-v] [-t timeout] <url> <local file>
+
+=head1 DESCRIPTION
+
+This program can be used to mirror a document from a WWW server.  The
+document is only transfered if the remote copy is newer than the local
+copy.  If the local copy is newer nothing happens.
+
+Use the C<-v> option to print the version number of this program.
+
+The timeout value specified with the C<-t> option.  The timeout value
+is the time that the program will wait for response from the remote
+server before it fails.  The default unit for the timeout value is
+seconds.  You might append "m" or "h" to the timeout value to make it
+minutes or hours, repectively.
+
+Because this program is implemented using the LWP library, it only
+supports the protocols that LWP supports.
+
+=head1 SEE ALSO
+
+L<lwp-request>, L<LWP>
+
+=head1 AUTHOR
+
+Gisle Aas <aas@a.sn.no>
+
+=cut
+
+
+use LWP::Simple;
+use Getopt::Std;
+
+$progname = $0;
+$progname =~ s,.*/,,;  # use basename only
+$progname =~ s/\.\w*$//; #strip extension if any
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+$opt_h = undef;  # print usage
+$opt_v = undef;  # print version
+$opt_t = undef;  # timeout
+
+unless (getopts("hvt:")) {
+    usage();
+}
+
+if ($opt_v) {
+    require LWP;
+    my $DISTNAME = 'libwww-perl-' . LWP::Version();
+    die <<"EOT";
+This is lwp-mirror version $VERSION ($DISTNAME)
+
+Copyright 1995-1996, Gisle Aas.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+EOT
+}
+
+$url  = shift or usage();
+$file = shift or usage();
+usage() if $opt_h or @ARGV;
+
+if (defined $opt_t) {
+    $opt_t =~ /^(\d+)([smh])?/;
+    die "$progname: Illegal timeout value!\n" unless defined $1;
+    $timeout = $1;
+    $timeout *= 60   if ($2 eq "m");
+    $timeout *= 3600 if ($2 eq "h");
+    $LWP::Simple::ua->timeout($timeout);
+}
+
+$rc = mirror($url, $file);
+
+if ($rc == 304) {
+    print STDERR "$progname: $file is up to date\n"
+} elsif (!is_success($rc)) {
+    print STDERR "$progname: $rc ", status_message($rc), "   ($url)\n";
+    exit 1;
+}
+exit;
+
+
+sub usage
+{
+    die <<"EOT";
+Usage: $progname [-options] <url> <file>
+    -v           print version number of program
+    -t <timeout> Set timeout value
+EOT
+}
+!NO!SUBS!
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/bin/lwp-request.PL
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/bin/lwp-request.PL	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/bin/lwp-request.PL	(revision 20131)
@@ -0,0 +1,521 @@
+use Config;
+use File::Basename qw(basename dirname);
+chdir(dirname($0));
+($file = basename($0)) =~ s/\.PL$//;
+$file =~ s/\.pl$//
+	if ($Config{'osname'} eq 'VMS' or
+	    $Config{'osname'} eq 'OS2');  # "case-forgiving"
+open OUT,">$file" or die "Can't create $file: $!";
+chmod(0755, $file);
+print "Extracting $file (with variable substitutions)\n";
+
+print OUT <<"!GROK!THIS!";
+$Config{'startperl'} -w
+
+!GROK!THIS!
+
+print OUT <<'!NO!SUBS!';
+# $Id$
+#
+# Simple user agent using LWP library.
+
+=head1 NAME
+
+lwp-request, GET, HEAD, POST - Simple WWW user agent
+
+=head1 SYNOPSIS
+
+ lwp-request [-aeEdvhx] [-m method] [-b <base URL>] [-t <timeout>]
+             [-i <if-modified-since>] [-c <content-type>] [-C <credentials>]
+             [-p <proxy-url>] [-o <format>] <url>...
+
+=head1 DESCRIPTION
+
+This program can be used to send requests to WWW servers and your
+local file system. The request content for POST, PUT and CHECKIN
+methods is read from stdin.  The content of the response is printed on
+stdout.  Error messages are printed on stderr.  The program returns a
+status value indicating the number of URLs that failed.
+
+The options are:
+
+=over 4
+
+=item -m <method>
+
+Set which method to use for the request.  If this option is not used,
+then the method is derived from the name of the program.
+
+=item -f
+
+Force request through, even if the program believes that the method is
+illegal.  The server will probably reject the request.
+
+=item -b <url>
+
+This URL will be used as the base URL for the URLs that the method is
+applied to.  The base URL only takes effect for relative URLs.  If you
+do not provide this option and the URLs are relative, then they will
+be treated as files in the local file system.
+
+=item -t <timeout>
+
+Set the timeout value for the requests.  The timeout is the amount of
+time that the program will wait for a response from the remote server
+before it fails.  The default unit for the timeout value is seconds.
+You might append "m" or "h" to the timeout value to make it minutes or
+hours, respectively.  The default timeout is '3m', i.e. 3 minutes.
+
+=item -i <time>
+
+Set the If-Modified-Since header in the request. If I<time> it the
+name of a file, use the modification timestamp for this file. If
+I<time> is not a file, it is parsed as a literal date. Take a look at
+L<HTTP::Date> for recogniced formats.
+
+=item -c <content-type>
+
+Set the Content-Type for the request.  This option is only allowed for
+requests that take a content, i.e. POST, PUT and CHECKIN.  You can
+force methods to take content by using the C<-f> option together with
+C<-c>.  The default Content-Type for POST is
+C<application/x-www-form-urlencoded>.  The default Content-type for
+the others is C<text/plain>.
+
+=item -p <proxy-url>
+
+Set the proxy to be used for the requests.  The program also loads
+proxy settings from the environment.  You can disable this with the
+C<-P> option.
+
+=item -C <username>:<password>
+
+Provide credentials for documents that are protected by Basic
+Authentication.  If the document is protected and you did not specify
+the username and password with this option, then you will be prompted
+to provide these values.
+
+=back
+
+The following options controls what is displayed by the program:
+
+=over 4
+
+=item -u
+
+Print request method and absolute URL as requests are made.
+
+=item -U
+
+Print request headers in addition to request method and absolute URL.
+
+=item -s
+
+Print response status code.  This option is always on for HEAD requests.
+
+=item -S
+
+Print response status chain. This shows redirect and autorization
+requests that are handled by the library.
+
+=item -e
+
+Print response headers.  This option is always on for HEAD requests.
+
+=item -d
+
+Do B<not> print the content of the response.
+
+=item -o <format>
+
+Process HTML content in various ways before printing it.  If the
+content type of the response is not HTML, then this option has no
+effect.  The legal format values are; I<text>, I<ps>, I<links>,
+I<html> and I<dump>.
+
+If you specify the I<text> format then the HTML will be formatted as
+plain latin1 text.  If you specify the I<ps> format then it will be
+formatted as Postscript.
+
+The I<links> format will output all links found in the HTML document.
+Relative links will be expanded to absolute ones.
+
+The I<html> format will reformat the HTML code and the I<dump> format
+will just dump the HTML syntax tree.
+
+=item -v
+
+Print the version number of the program and quit.
+
+=item -h
+
+Print usage message and quit.
+
+=item -x
+
+Extra debugging output.
+
+=item -a
+
+Set text(ascii) mode for content input and output.  If this option is not 
+used, content input and output is done in binary mode.
+
+=back
+
+Because this program is implemented using the LWP library, it will
+only support the protocols that LWP supports.
+
+=head1 SEE ALSO
+
+L<lwp-mirror>, L<LWP>
+
+=head1 COPYRIGHT
+
+Copyright 1995-1997 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 AUTHOR
+
+Gisle Aas <aas@sn.no>
+
+=cut
+
+$progname = $0;
+$progname =~ s,.*/,,;  # use basename only
+$progname =~ s/\.\w*$//; # strip extension, if any
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+
+require LWP;
+require LWP::Debug;
+require URI::URL;
+
+use URI::Heuristic qw(uf_url);
+
+use HTTP::Status qw(status_message);
+use HTTP::Date qw(time2str str2time);
+
+
+# This table lists the methods that are allowed.  It should really be
+# a superset for all methods supported for every scheme that may be
+# supported by the library.  Currently it might be a bit too HTTP
+# specific.  You might use the -f option to force a method through.
+#
+# "" = No content in request, "C" = Needs content in request
+#
+%allowed_methods = (
+    GET        => "",
+    HEAD       => "",
+    POST       => "C",
+    PUT        => "C",
+    DELETE     => "",
+    TRACE      => "",
+    OPTIONS    => "",
+);
+
+
+# We make our own specialization of LWP::UserAgent that asks for
+# user/password if document is protected.
+{
+    package RequestAgent;
+    @ISA = qw(LWP::UserAgent);
+
+    sub new
+    { 
+	my $self = LWP::UserAgent::new(@_);
+	$self->agent("lwp-request/$main::VERSION");
+	$self;
+    }
+
+    sub get_basic_credentials
+    {
+	my($self, $realm, $uri) = @_;
+	if ($main::opt_C) {
+	    return split(':', $main::opt_C, 2);
+	} elsif (-t) {
+	    my $netloc = $uri->netloc;
+	    print "Enter username for $realm at $netloc: ";
+	    my $user = <STDIN>;
+	    chomp($user);
+	    return (undef, undef) unless length $user;
+	    print "Password: ";
+	    system("stty -echo");
+	    my $password = <STDIN>;
+	    system("stty echo");
+	    print "\n";  # because we disabled echo
+	    chomp($password);
+	    return ($user, $password);
+	} else {
+	    return (undef, undef)
+	}
+    }
+}
+
+$method = uc(lc($progname) eq "lwp-request" ? "GET" : $progname);
+
+# Parse command line
+use Getopt::Std;
+
+$opt_a = undef;  # content i/o in text(ascii) mode
+$opt_m = undef;  # set method
+$opt_f = undef;  # make request even if method is not in %allowed_methods
+$opt_b = undef;  # base url
+$opt_t = undef;  # timeout
+$opt_i = undef;  # if-modified-since
+$opt_c = undef;  # content type for POST
+$opt_C = undef;  # credidentials for basic authorization
+
+$opt_u = undef;  # display method, URL and headers of request
+$opt_U = undef;  # display request headers also
+$opt_s = undef;  # display status code
+$opt_S = undef;  # display whole chain of status codes
+$opt_e = undef;  # display response headers (default for HEAD)
+$opt_d = undef;  # don't display content
+
+$opt_h = undef;  # print usage
+$opt_v = undef;  # print version
+
+$opt_x = undef;  # extra debugging info
+$opt_p = undef;  # proxy URL
+$opt_P = undef;  # don't load proxy setting from environment
+
+$opt_o = undef;  # output format
+
+unless (getopts("axhvuUsSedPp:b:t:i:c:C:m:fo:")) {
+    usage();
+}
+
+if ($opt_v) {
+    require LWP;
+    my $DISTNAME = 'libwww-perl-' . LWP::Version();
+    die <<"EOT";
+This is lwp-request version $VERSION ($DISTNAME)
+
+Copyright 1995-1997, Gisle Aas.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+EOT
+}
+
+usage() if $opt_h || !@ARGV;
+
+LWP::Debug::level('+') if $opt_x;
+
+# Create the user agent object
+$ua = new RequestAgent;
+
+# Load proxy settings from *_proxy environment variables.
+$ua->env_proxy unless $opt_P;
+
+$method = uc($opt_m) if defined $opt_m;
+
+if ($opt_f) {
+    if ($opt_c) {
+        $allowed_methods{$method} = "C";  # force content
+    } else {
+        $allowed_methods{$method} = "";
+    }
+} elsif (!defined $allowed_methods{$method}) {
+    die "$progname: $method is not an allowed method\n";
+}
+
+if ($method eq "HEAD") {
+    $opt_s = 1;
+    $opt_e = 1 unless $opt_d;
+    $opt_d = 1;
+}
+
+if (defined $opt_t) {
+    $opt_t =~ /^(\d+)([smh])?/;
+    die "$progname: Illegal timeout value!\n" unless defined $1;
+    $timeout = $1;
+    $timeout *= 60   if ($2 eq "m");
+    $timeout *= 3600 if ($2 eq "h");
+    $ua->timeout($timeout);
+}
+
+if (defined $opt_i) {
+    if (-e $opt_i) {
+        $time = (stat _)[9];
+    } else {
+        $time = str2time($opt_i);
+        die "$progname: Illegal time syntax for -i option\n"
+            unless defined $time;
+    }
+    $opt_i = time2str($time);
+}
+
+$content = undef;
+if ($allowed_methods{$method} eq "C") {
+    # This request needs some content
+    unless (defined $opt_c) {
+        # set default content type
+        $opt_c = ($method eq "POST") ?
+              "application/x-www-form-urlencoded"
+            : "text/plain";
+    } else {
+        die "$progname: Illegal Content-type format\n"
+            unless $opt_c =~ m,^[\w\-]+/[\w\-]+(?:\s*;.*)?$,
+    }
+    print "Please enter content ($opt_c) to be ${method}ed:\n"
+        if -t;
+    binmode STDIN unless -t or $opt_a;
+    $content = join("", <STDIN>);
+} else {
+    die "$progname: Can't set Content-type for $method requests\n"
+        if defined $opt_c;
+}
+
+# Set up a request.  We will use the same request object for all URLs.
+$request = new HTTP::Request $method;
+$request->header('If-Modified-Since', $opt_i) if defined $opt_i;
+#$request->header('Accept', '*/*');
+if ($opt_c) { # will always be set for request that wants content
+    $request->header('Content-Type', $opt_c);
+    $request->header('Content-Length', length $content);  # Not really needed
+    $request->content($content);
+}
+
+
+$errors = 0;
+
+# Ok, now we perform the requests, one URL at a time
+while ($url = shift) {
+    # Create the URL object, but protect us against bad URLs
+    eval {
+	if ($url =~ /^\w+:/ || $opt_b) {  # is there any scheme specification
+	    $url = URI::URL->new($url, $opt_b);
+	} else {
+	    $url = uf_url($url);
+        }
+    };
+    if ($@) {
+	$@ =~ s/at\s+\S+\s+line\s\d+//;
+	print STDERR $@;
+	$errors++;
+	next;
+    }
+
+    $ua->proxy($url->scheme, $opt_p) if $opt_p;
+
+    # Send the request and get a response back from the server
+    $request->url($url);
+    $response = $ua->request($request);
+
+    if ($opt_u || $opt_U) {
+        my $url = $response->request->url->as_string;
+        print "$method $url\n";
+        print $response->request->headers_as_string, "\n" if $opt_U;
+    }
+
+    if ($opt_S) {
+	printResponseChain($response);
+    } elsif ($opt_s) {
+        print $response->status_line, "\n";
+    }
+
+    if ($opt_e) {
+        # Display headers
+        print $response->headers_as_string;
+        print "\n";  # separate headers and content
+    }
+
+    if ($response->is_success) {
+	unless ($opt_d) {
+	    if ($opt_o &&
+		$response->content_type eq 'text/html') {
+		require HTML::Parse;
+		my $html = HTML::Parse::parse_html($response->content);
+		{
+		    $opt_o eq 'ps' && do {
+			require HTML::FormatPS;
+			my $f = new HTML::FormatPS;
+			print $f->format($html);
+			last;
+		    };
+		    $opt_o eq 'text' && do {
+			require HTML::FormatText;
+			my $f = new HTML::FormatText;
+			print $f->format($html);
+			last;
+		    };
+		    $opt_o eq 'html' && do {
+			print $html->as_HTML;
+			last;
+		    };
+		    $opt_o eq 'links' && do {
+			my $base = $response->base;
+			for ( @{ $html->extract_links } ) {
+			    my($link, $elem) = @$_;
+			    my $tag = uc $elem->tag;
+			    $link = new URI::URL $link, $base;
+			    print "$tag\t", $link->abs->as_string, "\n";
+			}
+			last;
+		    };
+		    $opt_o eq 'dump' && do {
+			$html->dump;
+			last;
+		    };
+		    # It is bad to not notice this before now :-(
+		    die "Illegal -o option value ($opt_o)\n";
+		}
+	    } else {
+                binmode STDOUT unless $opt_a;
+		print $response->content;
+	    }
+	}
+    } else {
+        print STDERR $response->error_as_HTML unless $opt_d;
+        $errors++;
+    }
+}
+
+exit $errors;
+
+
+sub printResponseChain
+{
+    my($response) = @_;
+    return unless defined $response;
+    printResponseChain($response->previous);
+    my $method = $response->request->method;
+    my $url = $response->request->url->as_string;
+    my $code = $response->code;
+    print "$method $url --> ", $response->status_line, "\n";
+}
+
+
+sub usage
+{
+    die <<"EOT";
+Usage: $progname [-options] <url>...
+    -m <method>   use method for the request (default is '$method')
+    -f            make request even if $progname believes method is illegal
+    -b <base>     Use the specified URL as base
+    -t <timeout>  Set timeout value
+    -i <time>     Set the If-Modified-Since header on the request
+    -c <conttype> use this content-type for POST, PUT, CHECKIN
+    -a            Use text mode for content I/O
+    -p <proxyurl> use this as a proxy
+    -P            don't load proxy settings from environment
+
+    -u            Display method and URL before any response
+    -U            Display request headers (implies -u)
+    -s            Display response status code
+    -S            Display response status chain
+    -e            Display response headers
+    -d            Do not display content
+    -o <format>   Process HTML content in various ways
+
+    -v            Show program version
+    -h            Print this message
+
+    -x            Extra debugging output
+EOT
+}
+!NO!SUBS!
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/bin/lwp-rget.PL
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/bin/lwp-rget.PL	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/bin/lwp-rget.PL	(revision 20131)
@@ -0,0 +1,600 @@
+use Config;
+use File::Basename qw(basename dirname);
+chdir(dirname($0));
+($file = basename($0)) =~ s/\.PL$//;
+$file =~ s/\.pl$//
+	if ($Config{'osname'} eq 'VMS' or
+	    $Config{'osname'} eq 'OS2');  # "case-forgiving"
+open OUT,">$file" or die "Can't create $file: $!";
+chmod(0755, $file);
+print "Extracting $file (with variable substitutions)\n";
+
+print OUT <<"!GROK!THIS!";
+$Config{'startperl'} -w
+
+!GROK!THIS!
+
+print OUT <<'!NO!SUBS!';
+#line 18
+
+=head1 NAME
+
+lwp-rget - Retrieve WWW documents recursively
+
+=head1 SYNOPSIS
+
+ lwp-rget [--verbose] [--auth=USER:PASS] [--depth=N] [--hier] [--iis]
+	  [--keepext=mime/type[,mime/type]] [--limit=N] [--nospace]
+	  [--prefix=URL] [--sleep=N] [--tolower] <URL>
+ lwp-rget --version
+
+=head1 DESCRIPTION
+
+This program will retrieve a document and store it in a local file.  It
+will follow any links found in the document and store these documents
+as well, patching links so that they refer to these local copies.
+This process continues until there are no more unvisited links or the
+process is stopped by the one or more of the limits which can be
+controlled by the command line arguments.
+
+This program is useful if you want to make a local copy of a
+collection of documents or want to do web reading off-line.
+
+All documents are stored as plain files in the current directory. The
+file names chosen are derived from the last component of URL paths.
+
+The options are:
+
+=over 3
+
+=item --auth=USER:PASS<n>
+
+Set the authentication credentials to user "USER" and password "PASS" if
+any restricted parts of the web site are hit.  If there are restricted
+parts of the web site and authentication credentials are not available,
+those pages will not be downloaded.
+
+=item --depth=I<n>
+
+Limit the recursive level. Embedded images are always loaded, even if
+they fall outside the I<--depth>. This means that one can use
+I<--depth=0> in order to fetch a single document together with all
+inline graphics.
+
+The default depth is 5.
+
+=item --hier
+
+Download files into a hierarchy that mimics the web site structure.
+The default is to put all files in the current directory.
+
+=item --iis
+
+Sends an "Accept: */*" on all URL requests as a workaround for a bug in
+IIS 2.0.  If no Accept MIME header is present, IIS 2.0 returns with a
+"406 No acceptable objects were found" error.  Also converts any back
+slashes (\\) in URLs to forward slashes (/).
+
+=item --keepext=I<mime/type[,mime/type]>
+
+Keeps the current extension for the list MIME types.  Useful when
+downloading text/plain documents that shouldn't all be translated to
+*.txt files.
+
+=item --limit=I<n>
+
+Limit the number of documents to get.  The default limit is 50.
+
+=item --nospace
+
+Changes spaces in all URLs to underscore characters (_).  Useful when
+downloading files from sites serving URLs with spaces in them.	Does not
+remove spaces from fragments, e.g., "file.html#somewhere in here".
+
+=item --prefix=I<url_prefix>
+
+Limit the links to follow. Only URLs that start the prefix string are
+followed.
+
+The default prefix is set as the "directory" of the initial URL to
+follow.	 For instance if we start lwp-rget with the URL
+C<http://www.sn.no/foo/bar.html>, then prefix will be set to
+C<http://www.sn.no/foo/>.
+
+Use C<--prefix=''> if you don't want the fetching to be limited by any
+prefix.
+
+=item --sleep=I<n>
+
+Sleep I<n> seconds before retrieving each document. This options allows
+you to go slowly, not loading the server you visiting too much.
+
+=item --tolower
+
+Translates all links to lowercase.  Useful when downloading files from
+IIS since it does not serve files in a case sensitive manner.
+
+=item --verbose
+
+Make more noise while running.
+
+=item --quiet
+
+Don't make any noise.
+
+=item --version
+
+Print program version number and quit.
+
+=item --help
+
+Print the usage message and quit.
+
+=back
+
+Before the program exits the name of the file, where the initial URL
+is stored, is printed on stdout.  All used filenames are also printed
+on stderr as they are loaded.  This printing can be suppressed with
+the I<--quiet> option.
+
+=head1 SEE ALSO
+
+L<lwp-request>, L<LWP>
+
+=head1 AUTHOR
+
+Gisle Aas <aas@sn.no>
+
+=cut
+
+use strict;
+
+use Getopt::Long    qw(GetOptions);
+use URI::URL	    qw(url);
+use LWP::MediaTypes qw(media_suffix);
+
+use vars qw($VERSION);
+use vars qw($MAX_DEPTH $MAX_DOCS $PREFIX $VERBOSE $QUIET $SLEEP $HIER $AUTH $IIS $TOLOWER $NOSPACE %KEEPEXT);
+
+my $progname = $0;
+$progname =~ s|.*/||;  # only basename left
+$progname =~ s/\.\w*$//; #strip extension if any
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+#$Getopt::Long::debug = 1;
+#$Getopt::Long::ignorecase = 0;
+
+# Defaults
+$MAX_DEPTH = 5;
+$MAX_DOCS  = 50;
+
+GetOptions('version'  => \&print_version,
+	   'help'     => \&usage,
+	   'depth=i'  => \$MAX_DEPTH,
+	   'limit=i'  => \$MAX_DOCS,
+	   'verbose!' => \$VERBOSE,
+	   'quiet!'   => \$QUIET,
+	   'sleep=i'  => \$SLEEP,
+	   'prefix:s' => \$PREFIX,
+	   'hier'     => \$HIER,
+	   'auth=s'   => \$AUTH,
+	   'iis'      => \$IIS,
+	   'tolower'  => \$TOLOWER,
+	   'nospace'  => \$NOSPACE,
+	   'keepext=s' => \$KEEPEXT{'OPT'},
+	  ) || usage();
+
+sub print_version {
+    require LWP;
+    my $DISTNAME = 'libwww-perl-' . LWP::Version();
+    print <<"EOT";
+This is lwp-rget version $VERSION ($DISTNAME)
+
+Copyright 1996-1998, Gisle Aas.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+EOT
+    exit 0;
+}
+
+my $start_url = shift || usage();
+usage() if @ARGV;
+
+require LWP::UserAgent;
+my $ua = new LWP::UserAgent;
+$ua->agent("$progname/$VERSION " . $ua->agent);
+$ua->env_proxy;
+
+unless (defined $PREFIX) {
+    $PREFIX = url($start_url);	 # limit to URLs below this one
+    eval {
+	$PREFIX->eparams(undef);
+	$PREFIX->equery(undef);
+    };
+
+    $_ = $PREFIX->epath;
+    s|[^/]+$||;
+    $PREFIX->epath($_);
+    $PREFIX = $PREFIX->as_string;
+}
+
+%KEEPEXT = map { lc($_) => 1 } split(/\s*,\s*/, $KEEPEXT{'OPT'});
+
+print <<"" if $VERBOSE;
+START	  = $start_url
+MAX_DEPTH = $MAX_DEPTH
+MAX_DOCS  = $MAX_DOCS
+PREFIX	  = $PREFIX
+
+
+my $no_docs = 0;
+my %seen = ();	   # mapping from URL => local_file
+
+my $filename = fetch($start_url);
+print "$filename\n" unless $QUIET;
+
+sub fetch
+{
+    my($url, $type, $depth) = @_;
+
+    # Fix http://sitename.com/../blah/blah.html to
+    #	  http://sitename.com/blah/blah.html
+    $url = $url->as_string if (ref($url));
+    while ($url =~ s#(https?://[^/]+/)\.\.\/#$1#) {}
+
+    # Fix backslashes (\) in URL if $IIS defined
+    $url = fix_backslashes($url) if (defined $IIS);
+
+    $url = url($url) unless ref($url);
+    $type  ||= 'a';
+    # Might be the background attribute
+    $type = 'img' if ($type eq 'body' || $type eq 'td');
+    $depth ||= 0;
+
+    # Print the URL before we start checking...
+    my $out = (" " x $depth) . $url . " ";
+    $out .= "." x (60 - length($out));
+    print STDERR $out . " " if $VERBOSE;
+
+    # Can't get mailto things
+    if ($url->scheme eq 'mailto') {
+	print STDERR "*skipping mailto*\n" if $VERBOSE;
+	return $url->as_string;
+    }
+
+    # The $plain_url is a URL without the fragment part
+    my $plain_url = $url->clone;
+    $plain_url->frag(undef);
+
+    # Check PREFIX, but not for <IMG ...> links
+    if ($type ne 'img' and  $url->as_string !~ /^\Q$PREFIX/o) {
+	print STDERR "*outsider*\n" if $VERBOSE;
+	return $url->as_string;
+    }
+
+    # Translate URL to lowercase if $TOLOWER defined
+    $plain_url = to_lower($plain_url) if (defined $TOLOWER);
+
+    # If we already have it, then there is nothing to be done
+    my $seen = $seen{$plain_url->as_string};
+    if ($seen) {
+	my $frag = $url->frag;
+	$seen .= "#$frag" if defined($frag);
+	$seen = protect_frag_spaces($seen);
+	print STDERR "$seen (again)\n" if $VERBOSE;
+	return $seen;
+    }
+
+    # Too much or too deep
+    if ($depth > $MAX_DEPTH and $type ne 'img') {
+	print STDERR "*too deep*\n" if $VERBOSE;
+	return $url;
+    }
+    if ($no_docs > $MAX_DOCS) {
+	print STDERR "*too many*\n" if $VERBOSE;
+	return $url;
+    }
+
+    # Fetch document 
+    $no_docs++;
+    sleep($SLEEP) if $SLEEP;
+    my $req = HTTP::Request->new(GET => $url);
+    # See: http://ftp.sunet.se/pub/NT/mirror-microsoft/kb/Q163/7/74.TXT
+    $req->header ('Accept', '*/*') if (defined $IIS);  # GIF/JPG from IIS 2.0
+    $req->authorization_basic(split (/:/, $AUTH)) if (defined $AUTH);
+    my $res = $ua->request($req);
+
+    # Check outcome
+    if ($res->is_success) {
+	my $doc = $res->content;
+	my $ct = $res->content_type;
+	my $name = find_name($res->request->url, $ct);
+	print STDERR "$name\n" unless $QUIET;
+	$seen{$plain_url->as_string} = $name;
+
+	# If the file is HTML, then we look for internal links
+	if ($ct eq "text/html") {
+	    # Save an unprosessed version of the HTML document.	 This
+	    # both reserves the name used, and it also ensures that we
+	    # don't loose everything if this program is killed before
+	    # we finish.
+	    save($name, $doc);
+	    my $base = $res->base;
+
+	    # Follow and substitute links...
+	    $doc =~
+s/
+  (
+    <(img|a|body|area|frame|td)\b   # some interesting tag
+    [^>]+			    # still inside tag (not strictly correct)
+    \b(?:src|href|background)	    # some link attribute
+    \s*=\s*			    # =
+  )
+    (?:				    # scope of OR-ing
+	 (")([^"]*)"	|	    # value in double quotes  OR
+	 (')([^']*)'	|	    # value in single quotes  OR
+	    ([^\s>]+)		    # quoteless value
+    )
+/
+  new_link($1, lc($2), $3||$5, $4||$6||$7, $base, $name, $depth+1)
+/giex;
+	   # XXX
+	   # The regular expression above is not strictly correct.
+	   # It is not really possible to parse HTML with a single
+	   # regular expression, but it is faster.  Tags that might
+	   # confuse us include:
+	   #	<a alt="href" href=link.html>
+	   #	<a alt=">" href="link.html">
+	   #
+	}
+	save($name, $doc);
+	return $name;
+    } else {
+	print STDERR $res->code . " " . $res->message . "\n" if $VERBOSE;
+	$seen{$plain_url->as_string} = $url->as_string;
+	return $url->as_string;
+    }
+}
+
+sub new_link
+{
+    my($pre, $type, $quote, $url, $base, $localbase, $depth) = @_;
+
+    $url = protect_frag_spaces($url);
+
+    $url = fetch(url($url, $base)->abs, $type, $depth);
+    $url = url("file:$url", "file:$localbase")->rel
+	unless $url =~ /^[.+\-\w]+:/;
+
+    $url = unprotect_frag_spaces($url);
+
+    return $pre . $quote . $url . $quote;
+}
+
+
+sub protect_frag_spaces
+{
+    my ($url) = @_;
+
+    $url = $url->as_string if (ref($url));
+
+    if ($url =~ m/^([^#]*#)(.+)$/)
+    {
+      my ($base, $frag) = ($1, $2);
+      $frag =~ s/ /%20/g;
+      $url = $base . $frag;
+    }
+
+    return $url;
+}
+
+
+sub unprotect_frag_spaces
+{
+    my ($url) = @_;
+
+    $url = $url->as_string if (ref($url));
+
+    if ($url =~ m/^([^#]*#)(.+)$/)
+    {
+      my ($base, $frag) = ($1, $2);
+      $frag =~ s/%20/ /g;
+      $url = $base . $frag;
+    }
+
+    return $url;
+}
+
+
+sub fix_backslashes
+{
+    my ($url) = @_;
+    my ($base, $frag);
+
+    $url = $url->as_string if (ref($url));
+
+    if ($url =~ m/([^#]+)(#.*)/)
+    {
+      ($base, $frag) = ($1, $2);
+    }
+    else
+    {
+      $base = $url;
+      $frag = "";
+    }
+
+    $base =~ tr/\\/\//;
+    $base =~ s/%5[cC]/\//g;	# URL-encoded back slash is %5C
+
+    return $base . $frag;
+}
+
+
+sub to_lower
+{
+    my ($url) = @_;
+    my $was_object = 0;
+
+    if (ref($url))
+    {
+      $url = $url->as_string;
+      $was_object = 1;
+    }
+
+    if ($url =~ m/([^#]+)(#.*)/)
+    {
+      $url = lc($1) . $2;
+    }
+    else
+    {
+      $url = lc($url);
+    }
+
+    if ($was_object == 1)
+    {
+      return url($url);
+    }
+    else
+    {
+      return $url;
+    }
+}
+
+
+sub translate_spaces
+{
+    my ($url) = @_;
+    my ($base, $frag);
+
+    $url = $url->as_string if (ref($url));
+
+    if ($url =~ m/([^#]+)(#.*)/)
+    {
+      ($base, $frag) = ($1, $2);
+    }
+    else
+    {
+      $base = $url;
+      $frag = "";
+    }
+
+    $base =~ s/^ *//;	# Remove initial spaces from base
+    $base =~ s/ *$//;	# Remove trailing spaces from base
+
+    $base =~ tr/ /_/;
+    $base =~ s/%20/_/g; # URL-encoded space is %20
+
+    return $base . $frag;
+}
+
+
+sub mkdirp
+{
+    my($directory, $mode) = @_;
+    my @dirs = split(/\//, $directory);
+    my $path = shift(@dirs);   # build it as we go
+    my $result = 1;   # assume it will work
+
+    unless (-d $path) {
+	$result &&= mkdir($path, $mode);
+    }
+
+    foreach (@dirs) {
+	$path .= "/$_";
+	if ( ! -d $path) {
+	    $result &&= mkdir($path, $mode);
+	}
+    }
+
+    return $result;
+}
+
+
+sub find_name
+{
+    my($url, $type) = @_;
+    #print "find_name($url, $type)\n";
+
+    # Translate spaces in URL to underscores (_) if $NOSPACE defined
+    $url = translate_spaces($url) if (defined $NOSPACE);
+
+    # Translate URL to lowercase if $TOLOWER defined
+    $url = to_lower($url) if (defined $TOLOWER);
+
+    $url = url($url) unless ref($url);
+
+    my $path = $url->path;
+
+    # trim path until only the basename is left
+    $path =~ s|(.*/)||;
+    my $dirname = ".$1";
+    if (!$HIER) {
+	$dirname = "";
+    } elsif (! -d $dirname) {
+	mkdirp($dirname, 0775);
+    }
+
+    my $extra = "";  # something to make the name unique
+    my $suffix;
+
+    if ($KEEPEXT{lc($type)}) {
+        $suffix = ($path =~ m/\.(.*)/) ? $1 : "";
+    } else {
+        $suffix = media_suffix($type);
+    }
+
+    $path =~ s|\..*||;	# trim suffix
+    $path = "index" unless length $path;
+
+    while (1) {
+	# Construct a new file name
+	my $file = $dirname . $path . $extra;
+	$file .= ".$suffix" if $suffix;
+	# Check if it is unique
+	return $file unless -f $file;
+
+	# Try something extra
+	unless ($extra) {
+	    $extra = "001";
+	    next;
+	}
+	$extra++;
+    }
+}
+
+
+sub save
+{
+    my $name = shift;
+    #print "save($name,...)\n";
+    open(FILE, ">$name") || die "Can't save $name: $!";
+    binmode FILE;
+    print FILE $_[0];
+    close(FILE);
+}
+
+
+sub usage
+{
+    die <<"";
+Usage: $progname [options] <URL>
+Allowed options are:
+  --auth=USER:PASS  Set authentication credentials for web site
+  --depth=N	    Maximum depth to traverse (default is $MAX_DEPTH)
+  --hier	    Download into hierarchy (not all files into cwd)
+  --iis		    Workaround IIS 2.0 bug by sending "Accept: */*" MIME
+		    header; translates backslashes (\\) to forward slashes (/)
+  --keepext=type    Keep file extension for MIME types (comma-separated list)
+  --limit=N	    A limit on the number documents to get (default is $MAX_DOCS)
+  --nospace	    Translate spaces URLs (not #fragments) to underscores (_)
+  --version	    Print version number and quit
+  --verbose	    More output
+  --quiet	    No output
+  --sleep=SECS	    Sleep between gets, ie. go slowly
+  --prefix=PREFIX   Limit URLs to follow to those which begin with PREFIX
+  --tolower	    Translate all URLs to lowercase (useful with IIS servers)
+
+}
+!NO!SUBS!
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/install.sh
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/install.sh	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/install.sh	(revision 20131)
@@ -0,0 +1,10 @@
+#!/bin/sh -v
+
+export PERL5LIB=$GSDLHOME/perllib/cpan/lib:$PERL5LIB
+export PATH=$GSDLHOME/perllib/cpan/bin:$PATH
+
+perl Makefile.PL PREFIX=$GSDLHOME/perllib/cpan
+
+make
+make test
+make install
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/Bundle/LWP.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/Bundle/LWP.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/Bundle/LWP.pm	(revision 20131)
@@ -0,0 +1,38 @@
+package Bundle::LWP;
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+1;
+
+__END__
+
+=head1 NAME
+
+Bundle::LWP - A bundle to install all libwww-perl related modules
+
+=head1 SYNOPSIS
+
+ perl -MCPAN -e 'install Bundle::LWP'
+
+=head1 CONTENTS
+
+Net::FTP 2.00      - If you want ftp://-support
+
+MIME::Base64       - Used in authentication headers
+
+MD5                - Needed to do Digest authentication
+
+HTML::HeadParser   - To get the correct $res->base
+
+LWP                - The reason why you need the modules above
+
+=head1 DESCRIPTION
+
+This bundle defines all reqreq modules for libwww-perl.
+
+
+=head1 AUTHOR
+
+Gisle Aas E<lt>aas@sn.no>
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/File/Listing.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/File/Listing.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/File/Listing.pm	(revision 20131)
@@ -0,0 +1,314 @@
+#
+# $Id$
+
+package File::Listing;
+
+sub Version { $VERSION; }
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+=head1 NAME
+
+parse_dir - parse directory listing
+
+=head1 SYNOPSIS
+
+ use File::Listing;
+ for (parse_dir(`ls -l`)) {
+     ($name, $type, $size, $mtime, $mode) = @$_;
+     next if $type ne 'f'; # plain file
+     #...
+ }
+
+ # directory listing can also be read from a file
+ open(LISTING, "zcat ls-lR.gz|");
+ $dir = parse_dir(\*LISTING, '+0000');
+
+=head1 DESCRIPTION
+
+The parse_dir() routine can be used to parse directory
+listings. Currently it only understand Unix C<'ls -l'> and C<'ls -lR'>
+format.  It should eventually be able to most things you might get
+back from a ftp server file listing (LIST command), i.e. VMS listings,
+NT listings, DOS listings,...
+
+The first parameter to parse_dir() is the directory listing to parse.
+It can be a scalar, a reference to an array of directory lines or a
+glob representing a filehandle to read the directory listing from.
+
+The second parameter is the time zone to use when parsing time stamps
+in the listing. If this value is undefined, then the local time zone is
+assumed.
+
+The third parameter is the type of listing to assume.  The values will
+be strings like 'unix', 'vms', 'dos'.  Currently only 'unix' is
+implemented and this is also the default value.  Ideally, the listing
+type should be determined automatically.
+
+The fourth parameter specify how unparseable lines should be treated.
+Values can be 'ignore', 'warn' or a code reference.  Warn means that
+the perl warn() function will be called.  If a code reference is
+passed, then this routine will be called and the return value from it
+will be incorporated in the listing.  The default is 'ignore'.
+
+Only the first parameter is mandatory.  The parse_dir() prototype is
+($;$$$).
+
+The return value from parse_dir() is a list of directory entries.  In
+scalar context the return value is a reference to the list.  The
+directory entries are represented by an array consisting of [
+$filename, $filetype, $filesize, $filetime, $filemode ].  The
+$filetype value is one of the letters 'f', 'd', 'l' or '?'.  The
+$filetime value is converted to seconds since Jan 1, 1970.  The
+$filemode is a bitmask like the mode returned by stat().
+
+=head1 CREDITS
+
+Based on lsparse.pl (from Lee McLoughlin's ftp mirror package) and
+Net::FTP's parse_dir (Graham Barr).
+
+=cut
+
+require Exporter;
+@ISA = qw(Exporter);
+
+@EXPORT = qw(parse_dir);
+
+use strict;
+
+use Carp ();
+use HTTP::Date qw(str2time);
+
+sub parse_dir ($;$$$)
+{
+   my($dir, $tz, $fstype, $error) = @_;
+
+   $fstype ||= 'unix';
+   $fstype = "File::Listing::" . lc $fstype;
+
+   my @args = $_[0];
+   push(@args, $tz) if(@_ >= 2);
+   push(@args, $error) if(@_ >= 4);
+
+   $fstype->parse(@args);
+}
+
+sub line { Carp::croak("Not implemented yet"); }
+sub init { } # Dummy sub
+
+sub file_mode ($)
+{
+    # This routine was originally borrowed from Graham Barr's
+    # Net::FTP package.
+
+    local $_ = shift;
+    my $mode = 0;
+    my($type,$ch);
+
+    s/^(.)// and $type = $1;
+
+    while (/(.)/g) {
+	$mode <<= 1;
+	$mode |= 1 if $1 ne "-" &&
+		      $1 ne 'S' &&
+		      $1 ne 't' &&
+		      $1 ne 'T';
+    }
+
+    $type eq "d" and $mode |= 0040000 or	# Directory
+      $type eq "l" and $mode |= 0120000 or	# Symbolic Link
+	$mode |= 0100000;			# Regular File
+
+    $mode |= 0004000 if /^...s....../i;
+    $mode |= 0002000 if /^......s.../i;
+    $mode |= 0001000 if /^.........t/i;
+
+    $mode;
+}
+
+sub parse
+{
+   my($pkg, $dir, $tz, $error) = @_;
+
+   # First let's try to determine what kind of dir parameter we have
+   # received.  We allow both listings, reference to arrays and
+   # file handles to read from.
+
+   if (ref($dir) eq 'ARRAY') {
+       # Already splitted up
+   } elsif (ref($dir) eq 'GLOB') {
+       # A file handle
+   } elsif (ref($dir)) {
+      Carp::croak("Illegal argument to parse_dir()");
+   } elsif ($dir =~ /^\*\w+(::\w+)+$/) {
+      # This scalar looks like a file handle, so we assume it is
+   } else {
+      # A normal scalar listing
+      $dir = [ split(/\n/, $dir) ];
+   }
+
+   $pkg->init();
+
+   my @files = ();
+   if (ref($dir) eq 'ARRAY') {
+       for (@$dir) {
+	   push(@files, $pkg->line($_, $tz, $error));
+       }
+   } else {
+       local($_);
+       while (<$dir>) {
+	   chomp;
+	   push(@files, $pkg->line($_, $tz, $error));
+       }
+   }
+   wantarray ? @files : \@files;
+}
+
+
+package File::Listing::unix;
+
+use HTTP::Date qw(str2time);
+
+# A place to remember current directory from last line parsed.
+use vars qw($curdir);
+no strict qw(vars);
+
+@ISA = qw(File::Listing);
+
+
+sub init
+{
+    $curdir = '';
+}
+
+sub line
+{
+    shift; # package name
+    local($_) = shift;
+    my($tz, $error) = @_;
+
+    s/\015//g;
+    #study;
+
+    my ($kind, $size, $date, $name);
+    if (($kind, $size, $date, $name) =
+	/^([\-FlrwxsStTdD]{10})                   # Type and permission bits
+	 .*                                       # Graps
+	 \D(\d+)                                  # File size
+	 \s+                                      # Some space
+	 (\w{3}\s+\d+\s+(?:\d{1,2}:\d{2}|\d{4}))  # Date
+	 \s+                                      # Some more space
+	 (.*)$                                    # File name
+	/x )
+
+    {
+	return if $name eq '.' || $name eq '..';
+	$name = "$curdir/$name" if length $curdir;
+	my $type = '?';
+	if ($kind =~ /^l/ && $name =~ /(.*) -> (.*)/ ) {
+	    $name = $1;
+	    $type = "l $2";
+	} elsif ($kind =~ /^[\-F]/) { # (hopefully) a regular file
+	    $type = 'f';
+	} elsif ($kind =~ /^[dD]/) {
+	    $type = 'd';
+	    $size = undef;  # Don't believe the reported size
+	}
+	return [$name, $type, $size, str2time($date, $tz), 
+              File::Listing::file_mode($kind)];
+
+    } elsif (/^(.+):$/ && !/^[dcbsp].*\s.*\s.*:$/ ) {
+	my $dir = $1;
+	return () if $dir eq '.';
+	$curdir = $dir;
+	return ();
+    } elsif (/^[Tt]otal\s+(\d+)$/ || /^\s*$/) {
+	return ();
+    } elsif (/not found/    || # OSF1, HPUX, and SunOS return
+             # "$file not found"
+             /No such file/ || # IRIX returns
+             # "UX:ls: ERROR: Cannot access $file: No such file or directory"
+                               # Solaris returns
+             # "$file: No such file or directory"
+             /cannot find/     # Windows NT returns
+             # "The system cannot find the path specified."
+             ) {
+	return () unless defined $error;
+	&$error($_) if ref($error) eq 'CODE';
+	warn "Error: $_\n" if $error eq 'warn';
+	return ();
+    } elsif ($_ eq '') {       # AIX, and Linux return nothing
+	return () unless defined $error;
+	&$error("No such file or directory") if ref($error) eq 'CODE';
+	warn "Warning: No such file or directory\n" if $error eq 'warn';
+	return ();
+    } else {
+        # parse failed, check if the dosftp parse understands it
+        return(File::Listing::dosftp->line($_,$tz,$error));
+    }
+
+}
+
+package File::Listing::dosftp;
+
+use HTTP::Date qw(str2time);
+
+# A place to remember current directory from last line parsed.
+use vars qw($curdir);
+no strict qw(vars);
+
+@ISA = qw(File::Listing);
+
+sub init
+{
+    $curdir = '';
+}
+
+sub line
+{
+    shift; # package name
+    local($_) = shift;
+    my($tz, $error) = @_;
+
+    s/\015//g;
+
+    my ($kind, $size, $date, $name);
+
+    # 02-05-96  10:48AM                 1415 src.slf
+    # 09-10-96  09:18AM       <DIR>          sl_util
+    if (($date,$size_or_dir,$name) =
+        /^(\d\d-\d\d-\d\d\s+\d\d:\d\d\wM)         # Date and time info
+         \s+                                      # Some space
+         (<\w{3}>|\d+)                            # Dir or Size
+         \s+                                      # Some more space
+         (.+)$                                    # File name
+        /x )
+    {
+	return if $name eq '.' || $name eq '..';
+	$name = "$curdir/$name" if length $curdir;
+	my $type = '?';
+	if ($size_or_dir eq '<DIR>') {
+	    $type = "d";
+            $size = ""; # directories have no size in the pc listing
+        } else {
+	    $type = 'f';
+            $size = $size_or_dir;
+	}
+	return [$name, $type, $size, str2time($date, $tz),
+              File::Listing::file_mode($kind)];
+
+    } else {
+	return () unless defined $error;
+	&$error($_) if ref($error) eq 'CODE';
+	warn "Can't parse: $_\n" if $error eq 'warn';
+	return ();
+    }
+
+}
+
+package File::Listing::vms;
+@File::Listing::unix::ISA = qw(File::Listing);
+
+package File::Listing::netware;
+@File::Listing::unix::ISA = qw(File::Listing);
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Cookies.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Cookies.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Cookies.pm	(revision 20131)
@@ -0,0 +1,725 @@
+package HTTP::Cookies;
+
+# Based on draft-ietf-http-state-man-mec-08.txt and
+# http://www.netscape.com/newsref/std/cookie_spec.html
+
+use strict;
+use HTTP::Date qw(str2time time2str);
+use HTTP::Headers::Util qw(split_header_words join_header_words);
+use LWP::Debug ();
+
+use vars qw($VERSION);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+=head1 NAME
+
+HTTP::Cookies - Cookie storage and management
+
+=head1 SYNOPSIS
+
+ use HTTP::Cookies;
+ $cookie_jar = HTTP::Cookies->new;
+
+ $cookie_jar->add_cookie_header($request);
+ $cookie_jar->extract_cookies($response);
+
+=head1 DESCRIPTION
+
+Cookies are a general mechanism which server side connections can use
+to both store and retrieve information on the client side of the
+connection.  For more information about cookies referrer to
+<URL:http://www.netscape.com/newsref/std/cookie_spec.html> and
+<URL:http://www.cookiecentral.com/>.  This module also implements the
+new style cookies as described in I<draft-ietf-http-state-man-mec-08.txt>.
+The two variants of cookies is supposed to be able to coexist happily.
+
+Instances of the class I<HTTP::Cookies> are able to store a collection
+of Set-Cookie2: and Set-Cookie:-headers and is able to use this
+information to initialize Cookie-headers in I<HTTP::Request> objects.
+The state of the I<HTTP::Cookies> can be saved and restored from
+files.
+
+=head1 METHODS
+
+The following methods are provided:
+
+=over 4
+
+=cut
+
+# A HTTP::Cookies object is a hash.  The main attribute is the
+# COOKIES 3 level hash:  $self->{COOKIES}{$domain}{$path}{$key}.
+
+
+=item $cookie_jar = HTTP::Cookies->new;
+
+The constructor.  Takes hash style parameters.  The following
+parameters are recognized:
+
+  file:            name of the file to restore and save cookies to
+  autosave:        should we save during destruction (bool)
+  ignore_discard:  save even cookies that are requested to be discarded (bool)
+
+Future parameters might include (not yet implemented):
+
+  max_cookies               300
+  max_cookies_per_domain    20
+  max_cookie_size           4096
+
+  no_cookies   list of domain names that we never return cookies to
+
+=cut
+
+sub new
+{
+    my $class = shift;
+    my $self = bless {
+	COOKIES => {},
+    }, $class;
+    my %cnf = @_;
+    for (keys %cnf) {
+	$self->{lc($_)} = $cnf{$_};
+    }
+    $self->load;
+    $self;
+}
+
+
+=item $cookie_jar->add_cookie_header($request);
+
+The add_cookie_header() method will set the appropriate Cookie:-header
+for the I<HTTP::Request> object given as argument.  The $request must
+have a valid url() attribute before this method is called.
+
+=cut
+
+sub add_cookie_header
+{
+    my $self = shift;
+    my $request = shift || return;
+    my $url = $request->url;
+    my $domain = $url->host;
+    $domain = "$domain.local" unless $domain =~ /\./;
+    my $secure_request = ($url->scheme eq "https");
+    my $req_path = $url->epath;
+    my $req_port = $url->port;
+    my $now = time();
+    $self->_normalize_path($req_path) if $req_path =~ /%/;
+
+    my @cval;    # cookie values for the "Cookie" header
+    my $set_ver;
+
+    while (($domain =~ tr/././) >= 2 || # must be at least 2 dots
+           $domain =~ /\.local$/)
+    {
+
+        LWP::Debug::debug("Checking $domain for cookies");
+	my $cookies = $self->{COOKIES}{$domain};
+	next unless $cookies;
+
+	# Want to add cookies corresponding to the most specific paths
+	# first (i.e. longest path first)
+	my $path;
+	for $path (sort {length($b) <=> length($a) } keys %$cookies) {
+            LWP::Debug::debug("- checking cookie path=$path");
+	    if (index($req_path, $path) != 0) {
+	        LWP::Debug::debug("  path $path:$req_path does not fit");
+		next;
+	    }
+
+	    my($key,$array);
+	    while (($key,$array) = each %{$cookies->{$path}}) {
+		my($version,$val,$port,$path_spec,$secure,$expires) = @$array;
+	        LWP::Debug::debug(" - checking cookie $key=$val");
+		if ($secure && !$secure_request) {
+		    LWP::Debug::debug("   not a secure requests");
+		    next;
+		}
+		if ($expires && $expires < $now) {
+		    LWP::Debug::debug("   expired");
+		    next;
+		}
+		if ($port) {
+		    my $found;
+		    if ($port =~ s/^_//) {
+			# The correponding Set-Cookie attribute was empty
+			$found++ if $port eq $req_port;
+			$port = "";
+		    } else {
+			my $p;
+			for $p (split(/,/, $port)) {
+			    $found++, last if $p eq $req_port;
+			}
+		    }
+		    unless ($found) {
+		        LWP::Debug::debug("   port $port:$req_port does not fit");
+			next;
+		    }
+		}
+	        LWP::Debug::debug("   it's a match");
+
+		# set version number of cookie header.
+	        # XXX: What should it be if multiple matching
+                #      Set-Cookie headers have different versions themselves
+		if (!$set_ver++) {
+		    if ($version >= 1) {
+			push(@cval, "\$Version=$version");
+		    } else {
+			$request->header(Cookie2 => "\$Version=1");
+		    }
+		}
+
+		# do we need to quote the value
+		if ($val =~ /\W/ && $version) {
+		    $val =~ s/([\\\"])/\\$1/g;
+		    $val = qq("$val");
+		}
+
+		# and finally remember this cookie
+		push(@cval, "$key=$val");
+		if ($version >= 1) {
+		    push(@cval, qq(\$Path="$path"))     if $path_spec;
+		    push(@cval, qq(\$Domain="$domain")) if $domain =~ /^\./;
+		    if (defined $port) {
+			my $p = '$Port';
+			$p .= qq(="$port") if length $port;
+			push(@cval, $p);
+		    }
+		}
+
+	    }
+        }
+
+    } continue {
+	# Try with a more general domain:  www.sol.no ==> .sol.no
+	$domain =~ s/^\.?[^.]*//;
+    }
+
+    $request->header(Cookie => join("; ", @cval)) if @cval;
+
+    $request;
+}
+
+
+=item $cookie_jar->extract_cookies($response);
+
+The extract_cookies() method will look for Set-Cookie: and
+Set-Cookie2:-headers in the I<HTTP::Response> object passed as
+argument.  If some of these headers are found they are used to update
+the state of the $cookie_jar.
+
+=cut
+
+sub extract_cookies
+{
+    my $self = shift;
+    my $response = shift || return;
+    my @set = split_header_words($response->_header("Set-Cookie2"));
+    my $netscape_cookies;
+    unless (@set) {
+	@set = $response->_header("Set-Cookie");
+	return $response unless @set;
+	$netscape_cookies++;
+    }
+
+    my $url = $response->request->url;
+    my $req_host = $url->host;
+    $req_host = "$req_host.local" unless $req_host =~ /\./;
+    my $req_port = $url->port;
+    my $req_path = $url->epath;
+    $self->_normalize_path($req_path) if $req_path =~ /%/;
+    
+    if ($netscape_cookies) {
+	# The old Netscape cookie format for Set-Cookie
+        # http://www.netscape.com/newsref/std/cookie_spec.html
+	# can for instance contain an unquoted "," in the expires
+	# field, so we have to use this ad-hoc parser.
+	my $now = time();
+	my @old = @set;
+	@set = ();
+	my $set;
+	for $set (@old) {
+	    my @cur;
+	    my $param;
+	    my $expires;
+	    for $param (split(/\s*;\s*/, $set)) {
+		my($k,$v) = split(/\s*=\s*/, $param, 2);
+		#print "$k => $v\n";
+		my $lc = lc($k);
+		if ($lc eq "expires") {
+		    push(@cur, "Max-Age" => str2time($v) - $now);
+		    $expires++;
+		} else {
+		    push(@cur, $k => $v);
+		}
+	    }
+	    push(@cur, "Port" => $req_port);
+	    push(@cur, "Discard" => undef) unless $expires;
+	    push(@cur, "Version" => 0);
+	    push(@set, \@cur);
+	}
+    }
+
+  SET_COOKIE:
+    for my $set (@set) {
+	next unless @$set >= 2;
+
+	my $key = shift @$set;
+	my $val = shift @$set;
+
+        LWP::Debug::debug("Set cookie $key => $val");
+
+	my %hash;
+	while (@$set) {
+	    my $k = shift @$set;
+	    my $v = shift @$set;
+	    my $lc = lc($k);
+	    # don't loose case distinction for unknown fields
+	    $k = $lc if $lc =~ /^(?:discard|domain|max-age|
+                                    path|port|secure|version)$/x;
+	    if ($k eq "discard" || $k eq "secure") {
+		$v = 1 unless defined $v;
+	    }
+	    next if exists $hash{$k};  # only first value is signigicant
+	    $hash{$k} = $v;
+	};
+
+	my %orig_hash = %hash;
+	my $version   = delete $hash{version};
+	$version = 1 unless defined($version);
+	my $discard   = delete $hash{discard};
+	my $secure    = delete $hash{secure};
+	my $maxage    = delete $hash{'max-age'};
+
+	# Check domain
+	my $domain  = delete $hash{domain};
+	if (defined($domain) && $domain ne $req_host) {
+	    if ($domain !~ /\./ && $domain ne "local") {
+	        LWP::Debug::debug("Domain $domain contains no dot");
+		next SET_COOKIE;
+	    }
+	    $domain = ".$domain" unless $domain =~ /^\./;
+	    if ($domain =~ /\.\d+$/) {
+	        LWP::Debug::debug("IP-address $domain illeagal as domain");
+		next SET_COOKIE;
+	    }
+	    my $len = length($domain);
+	    unless (substr($req_host, -$len) eq $domain) {
+	        LWP::Debug::debug("Domain $domain does not match host $req_host");
+		next SET_COOKIE;
+	    }
+	    my $hostpre = substr($req_host, 0, length($req_host) - $len);
+	    if ($hostpre =~ /\./ && !$netscape_cookies) {
+	        LWP::Debug::debug("Host prefix contain a dot: $hostpre => $domain");
+		next SET_COOKIE;
+	    }
+	} else {
+	    $domain = $req_host;
+	}
+
+	my $path = delete $hash{path};
+	my $path_spec;
+	if (defined $path) {
+	    $path_spec++;
+	    $self->_normalize_path($path) if $path =~ /%/;
+	    if (!$netscape_cookies &&
+                substr($req_path, 0, length($path)) ne $path) {
+	        LWP::Debug::debug("Path $path is not a prefix of $req_path");
+		next SET_COOKIE;
+	    }
+	} else {
+	    $path = $req_path;
+	    $path =~ s,/[^/]*$,,;
+	    $path = "/" unless length($path);
+	}
+
+	my $port;
+	if (exists $hash{port}) {
+	    $port = delete $hash{port};
+	    if (defined $port) {
+		$port =~ s/\s+//g;
+		my $found;
+		for my $p (split(/,/, $port)) {
+		    unless ($p =~ /^\d+$/) {
+		      LWP::Debug::debug("Bad port $port (not numeric)");
+			next SET_COOKIE;
+		    }
+		    $found++ if $p eq $req_port;
+		}
+		unless ($found) {
+		    LWP::Debug::debug("Request port ($req_port) not found in $port");
+		    next SET_COOKIE;
+		}
+	    } else {
+		$port = "_$req_port";
+	    }
+	}
+	$self->set_cookie($version,$key,$val,$path,$domain,$port,$path_spec,$secure,$maxage,$discard, \%hash)
+	    if $self->set_cookie_ok(\%orig_hash);
+    }
+
+    $response;
+}
+
+sub set_cookie_ok { 1 };
+
+=item $cookie_jar->set_cookie($version, $key, $val, $path, $domain, $port, $path_spec, $secure, $maxage, $discard, \%rest)
+
+The set_cookie() method updates the state of the $cookie_jar.  The
+$key, $val, $domain, $port and $path arguments are strings.  The
+$path_spec, $secure, $discard arguments are boolean values. The $maxage
+value is a number indicating number of seconds that this cookie will
+live.  A value <= 0 will delete this cookie.  The %rest are a place
+for various other attributes like "Comment" and "CommentURL".
+
+=cut
+
+sub set_cookie
+{
+    my $self = shift;
+    my($version,
+       $key, $val, $path, $domain, $port,
+       $path_spec, $secure, $maxage, $discard, $rest) = @_;
+
+    # there must always be at least 2 dots in a domain
+    return $self if ($domain =~ tr/././) < 2 &&
+                     $domain !~ /\.local$/;
+
+    # path and key can not be empty (key can't start with '$')
+    return $self if !defined($path) || $path !~ m,^/, ||
+	            !defined($key)  || $key  !~ m,[^\$],;
+
+    # ensure legal port
+    if (defined $port) {
+	return $self unless $port =~ /^_?\d+(?:,\d+)*$/;
+    }
+
+    my $expires;
+    if (defined $maxage) {
+	if ($maxage <= 0) {
+	    delete $self->{COOKIES}{$domain}{$path}{$key};
+	    return $self;
+	}
+	$expires = time() + $maxage;
+    }
+    $version = 0 unless defined $version;
+
+    my @array = ($version, $val,$port,
+		 $path_spec,
+		 $secure, $expires, $discard);
+    push(@array, {%$rest}) if defined($rest) && %$rest;
+    # trim off undefined values at end
+    pop(@array) while !defined $array[-1];
+
+    $self->{COOKIES}{$domain}{$path}{$key} = \@array;
+    $self;
+}
+
+=item $cookie_jar->save( [$file] );
+
+Calling this method file save the state of the $cookie_jar to a file.
+The state can then be restored later using the load() method.  If a
+filename is not specified we will use the name specified during
+construction.  If the attribute I<ignore_discared> is set, then we
+will even save cookies that are marked to be discarded.
+
+The default is to save a sequence of "Set-Cookie3" lines.  The
+"Set-Cookie3" is a proprietary LWP format, not known to be compatible
+with any other browser.  The I<HTTP::Cookies::Netscape> sub-class can
+be used to save in a format compatible with Netscape.
+
+=cut
+
+sub save
+{
+    my $self = shift;
+    my $file = shift || $self->{'file'} || return;
+    local(*FILE);
+    open(FILE, ">$file") or die "Can't open $file: $!";
+    print FILE "#LWP-Cookies-1.0\n";
+    print FILE $self->as_string(!$self->{ignore_discard});
+    close(FILE);
+    1;
+}
+
+=item $cookie_jar->load( [$file] );
+
+This method will read the cookies from the file and add them to the
+$cookie_jar.  The file must be in the format written by the save()
+method.
+
+=cut
+
+sub load
+{
+    my $self = shift;
+    my $file = shift || $self->{'file'} || return;
+    local(*FILE, $_);
+    open(FILE, $file) or return;
+    my $magic = <FILE>;
+    unless ($magic =~ /^\#LWP-Cookies-(\d+\.\d+)/) {
+	warn "$file does not seem to contain cookies";
+	return;
+    }
+    while (<FILE>) {
+	next unless s/^Set-Cookie3:\s*//;
+	chomp;
+	my $cookie;
+	for $cookie (split_header_words($_)) {
+	    my($key,$val) = splice(@$cookie, 0, 2);
+	    my %hash;
+	    while (@$cookie) {
+		my $k = shift @$cookie;
+		my $v = shift @$cookie;
+		$hash{$k} = $v;
+	    }
+	    my $version   = delete $hash{version};
+	    my $path      = delete $hash{path};
+	    my $domain    = delete $hash{domain};
+	    my $port      = delete $hash{port};
+	    my $expires   = str2time(delete $hash{expires});
+
+	    my $path_spec = exists $hash{path_spec}; delete $hash{path_spec};
+	    my $secure    = exists $hash{secure};    delete $hash{secure};
+	    my $discard   = exists $hash{discard};   delete $hash{discard};
+
+	    my @array =	($version,$val,$port,
+			 $path_spec,$secure,$expires,$discard);
+	    push(@array, \%hash) if %hash;
+	    $self->{COOKIES}{$domain}{$path}{$key} = \@array;
+	}
+    }
+    close(FILE);
+    1;
+}
+
+=item $cookie_jar->revert;
+
+Will revert to the state of last save.
+
+=cut
+
+sub revert
+{
+    my $self = shift;
+    $self->clear->load;
+    $self;
+}
+
+=item $cookie_jar->clear( [$domain, [$path, [$key] ] ]);
+
+Invoking this method without arguments will empty the whole
+$cookie_jar.  If given a single argument only cookies belonging to
+that domain will be removed.  If given two arguments, cookies
+belonging to the specified path within that domain is removed.  If
+given three arguments, then the cookie with the specified key, path
+and domain is removed.
+
+=cut
+
+sub clear
+{
+    my $self = shift;
+    if (@_ == 0) {
+	$self->{COOKIES} = {};
+    } elsif (@_ == 1) {
+	delete $self->{COOKIES}{$_[0]};
+    } elsif (@_ == 2) {
+	delete $self->{COOKIES}{$_[0]}{$_[1]};
+    } elsif (@_ == 3) {
+	delete $self->{COOKIES}{$_[0]}{$_[1]}{$_[2]};
+    } else {
+	require Carp;
+        Carp::carp('Usage: $c->clear([domain [,path [,key]]])');
+    }
+    $self;
+}
+
+sub DESTROY
+{
+    my $self = shift;
+    $self->save if $self->{'autosave'};
+}
+
+
+=item $cookie_jar->scan( \&callback );
+
+The argument is a subroutine that will be invoked for each cookie
+stored within the $cookie_jar.  The subroutine will be invoked with
+the following arguments:
+
+  0  version
+  1  key
+  2  val
+  3  path
+  4  domain
+  5  port
+  6  path_spec
+  7  secure
+  8  expires
+  9  discard
+ 10  hash
+
+=cut
+
+sub scan
+{
+    my($self, $cb) = @_;
+    my($domain,$path,$key);
+    for $domain (sort keys %{$self->{COOKIES}}) {
+	for $path (sort keys %{$self->{COOKIES}{$domain}}) {
+	    for $key (sort keys %{$self->{COOKIES}{$domain}{$path}}) {
+		my($version,$val,$port,$path_spec,
+		   $secure,$expires,$discard,$rest) =
+		       @{$self->{COOKIES}{$domain}{$path}{$key}};
+		$rest = {} unless defined($rest);
+		&$cb($version,$key,$val,$path,$domain,$port,
+		     $path_spec,$secure,$expires,$discard,$rest);
+	    }
+	}
+    }
+}
+
+=item $cookie_jar->as_string( [$skip_discard] );
+
+The as_string() method will return the state of the $cookie_jar
+represented as a sequence of "Set-Cookie3" header lines separated by
+"\n".  If given a argument that is TRUE, it will not return lines for
+cookies with the I<Discard> attribute.
+
+=cut
+
+sub as_string
+{
+    my($self, $skip_discard) = @_;
+    my @res;
+    $self->scan(sub {
+	my($version,$key,$val,$path,$domain,$port,
+	   $path_spec,$secure,$expires,$discard,$rest) = @_;
+	return if $discard && $skip_discard;
+	my @h = ($key, $val);
+	push(@h, "path", $path);
+	push(@h, "domain" => $domain);
+	push(@h, "port" => $port) if defined $port;
+	push(@h, "path_spec" => undef) if $path_spec;
+	push(@h, "secure" => undef) if $secure;
+	push(@h, "expires" => HTTP::Date::time2isoz($expires)) if $expires;
+	push(@h, "discard" => undef) if $discard;
+	my $k;
+	for $k (sort keys %$rest) {
+	    push(@h, $k, $rest->{$k});
+	}
+	push(@h, "version" => $version);
+	push(@res, "Set-Cookie3: " . join_header_words(\@h));
+    });
+    join("\n", @res, "");
+}
+
+
+sub _normalize_path  # so that plain string compare can be used
+{
+    shift;  # $self
+    my $x;
+    $_[0] =~ s/%([0-9a-fA-F][0-9a-fA-F])/
+	         $x = uc($1);
+                 $x eq "2F" || $x eq "25" ? "%$x" :
+                                            pack("c", hex($x));
+              /eg;
+    $_[0] =~ s/([\0-\x20\x7f-\xff])/sprintf("%%%02X",ord($1))/eg;
+}
+
+
+
+=back
+
+=head1 SUB CLASSES
+
+We also provide a subclass called I<HTTP::Cookies::Netscape> which make
+cookie loading and saving compatible with Netscape cookie files.  You
+should be able to have LWP share Netscape's cookies by constructing
+your $cookie_jar like this:
+
+ $cookie_jar = HTTP::Cookies::Netscape->new(
+                   File     => "$ENV{HOME}/.netscape/cookies",
+                   AutoSave => 1,
+               );
+
+Please note that the Netscape cookie file format is not able to store
+all the information available in the Set-Cookie2 headers, so you will
+probably loose some information if you save using this format.
+
+=cut
+
+package HTTP::Cookies::Netscape;
+
+use vars qw(@ISA);
+@ISA=qw(HTTP::Cookies);
+
+sub load
+{
+    my($self, $file) = @_;
+    $file ||= $self->{'file'} || return;
+    local(*FILE, $_);
+    my @cookies;
+    open(FILE, $file) || return;
+    my $magic = <FILE>;
+    unless ($magic =~ /^\# Netscape HTTP Cookie File/) {
+	warn "$file does not look like a netscape cookies file" if $^W;
+	close(FILE);
+	return;
+    }
+    my $now = time();
+    while (<FILE>) {
+	next if /^\s*\#/;
+	next if /^\s*$/;
+	chomp;
+	my($domain,$bool1,$path,$secure, $expires,$key,$val) = split(/\t/, $_);
+	$secure = ($secure eq "TRUE");
+	$self->set_cookie(undef,$key,$val,$path,$domain,undef,
+			  0,$secure,$expires-$now, 0);
+    }
+    close(FILE);
+    1;
+}
+
+sub save
+{
+    my($self, $file) = @_;
+    $file ||= $self->{'file'} || return;
+    local(*FILE, $_);
+    open(FILE, ">$file") || return;
+
+    print FILE <<EOT;
+# Netscape HTTP Cookie File
+# http://www.netscape.com/newsref/std/cookie_spec.html
+# This is a generated file!  Do not edit.
+
+EOT
+
+    my $now = time;
+    $self->scan(sub {
+	my($version,$key,$val,$path,$domain,$port,
+	   $path_spec,$secure,$expires,$discard,$rest) = @_;
+	return if $discard && !$self->{ignore_discard};
+	$expires ||= 0;
+	return if $now > $expires;
+	$secure = $secure ? "TRUE" : "FALSE";
+	my $bool = $domain =~ /^\./ ? "TRUE" : "FALSE";
+	print FILE join("\t", $domain, $bool, $path, $secure, $expires, $key, $val), "\n";
+    });
+    close(FILE);
+    1;
+}
+
+1;
+
+__END__
+
+=head1 COPYRIGHT
+
+Copyright 1997, Gisle Aas
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Daemon.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Daemon.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Daemon.pm	(revision 20131)
@@ -0,0 +1,805 @@
+# $Id$
+#
+
+use strict;
+
+package HTTP::Daemon;
+
+=head1 NAME
+
+HTTP::Daemon - a simple http server class
+
+=head1 SYNOPSIS
+
+  use HTTP::Daemon;
+  use HTTP::Status;
+
+  my $d = new HTTP::Daemon;
+  print "Please contact me at: <URL:", $d->url, ">\n";
+  while (my $c = $d->accept) {
+      while (my $r = $c->get_request) {
+	  if ($r->method eq 'GET' and $r->url->path eq "/xyzzy") {
+              # remember, this is *not* recommened practice :-)
+	      $c->send_file_response("/etc/passwd");
+	  } else {
+	      $c->send_error(RC_FORBIDDEN)
+	  }
+      }
+      $c->close;
+      undef($c);
+  }
+
+=head1 DESCRIPTION
+
+Instances of the I<HTTP::Daemon> class are HTTP/1.1 servers that
+listens on a socket for incoming requests. The I<HTTP::Daemon> is a
+sub-class of I<IO::Socket::INET>, so you can do socket operations
+directly on it too.
+
+The accept() method will return when a connection from a client is
+available. The returned value will be a reference to a object of the
+I<HTTP::Daemon::ClientConn> class which is another I<IO::Socket::INET>
+subclass. Calling the get_request() method on this object will read
+data from the client and return an I<HTTP::Request> object reference.
+
+This HTTP daemon does not fork(2) for you.  Your application, i.e. the
+user of the I<HTTP::Daemon> is reponsible for forking if that is
+desirable.  Also note that the user is responsible for generating
+responses that conforms to the HTTP/1.1 protocol.  The
+I<HTTP::Daemon::ClientConn> provide some methods that make this easier.
+
+=head1 METHODS
+
+The following is a list of methods that are new (or enhanced) relative
+to the I<IO::Socket::INET> base class.
+
+=over 4
+
+=cut
+
+
+use vars qw($VERSION @ISA $PROTO $DEBUG);
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+use IO::Socket ();
+@ISA=qw(IO::Socket::INET);
+
+$PROTO = "HTTP/1.1";
+
+=item $d = new HTTP::Daemon
+
+The object constructor takes the same parameters as the
+I<IO::Socket::INET> constructor.  It can be called without specifying
+any parameters. The daemon will then set up a listen queue of 5
+connections and allocate some random port number.  A server that want
+to bind to some specific address on the standard HTTP port will be
+constructed like this:
+
+  $d = new HTTP::Daemon
+        LocalAddr => 'www.someplace.com',
+        LocalPort => 80;
+
+=cut
+
+sub new
+{
+    my($class, %args) = @_;
+    $args{Listen} ||= 5;
+    $args{Proto}  ||= 'tcp';
+    my $self = $class->SUPER::new(%args);
+    return undef unless $self;
+
+    my $host = $args{LocalAddr};
+    unless ($host) {
+	require Sys::Hostname;
+	$host = Sys::Hostname::hostname();
+    }
+    ${*$self}{'httpd_server_name'} = $host;
+    $self;
+}
+
+
+=item $c = $d->accept([$pkg])
+
+Same as I<IO::Socket::accept> but will return an
+I<HTTP::Daemon::ClientConn> reference by default.  It will return
+undef if you have specified a timeout and no connection is made within
+that time.
+
+=cut
+
+sub accept
+{
+    my $self = shift;
+    my $pkg = shift || "HTTP::Daemon::ClientConn";
+    my $sock = $self->SUPER::accept($pkg);
+    ${*$sock}{'httpd_daemon'} = $self if $sock;
+    $sock;
+}
+
+
+=item $d->url
+
+Returns a URL string that can be used to access the server root.
+
+=cut
+
+sub url
+{
+    my $self = shift;
+    my $url = "http://";
+    $url .= ${*$self}{'httpd_server_name'};
+    my $port = $self->sockport;
+    $url .= ":$port" if $port != 80;
+    $url .= "/";
+    $url;
+}
+
+
+=item $d->product_tokens
+
+Returns the name that this server will use to identify itself.  This
+is the string that is sent with the I<Server> response header.  The
+main reason to have this method is that subclasses can override it if
+they want to use another product name.
+
+=cut
+
+sub product_tokens
+{
+    "libwww-perl-daemon/$HTTP::Daemon::VERSION";
+}
+
+
+package HTTP::Daemon::ClientConn;
+
+use vars qw(@ISA $DEBUG);
+use IO::Socket ();
+@ISA=qw(IO::Socket::INET);
+*DEBUG = \$HTTP::Daemon::DEBUG;
+
+use HTTP::Request  ();
+use HTTP::Response ();
+use HTTP::Status;
+use HTTP::Date qw(time2str);
+use URI::URL qw(url);
+use LWP::MediaTypes qw(guess_media_type);
+use Carp ();
+
+my $CRLF = "\015\012";   # "\r\n" is not portable
+my $HTTP_1_0 = _http_version("HTTP/1.0");
+my $HTTP_1_1 = _http_version("HTTP/1.1");
+
+=back
+
+The I<HTTP::Daemon::ClientConn> is also a I<IO::Socket::INET>
+subclass. Instances of this class are returned by the accept() method
+of the I<HTTP::Daemon>.  The following additional methods are
+provided:
+
+=over 4
+
+=item $c->get_request([$headers_only])
+
+This method will read data from the client and turn it into a
+I<HTTP::Request> object which is then returned.  It returns C<undef>
+if reading of the request fails.  If it fails, then the
+I<HTTP::Daemon::ClientConn> object ($c) should be discarded, and you
+should not call this method again.  The $c->reason method might give
+you some information on why $c->get_request returned C<undef>.
+
+The $c->get_request method support HTTP/1.1 request content bodies,
+including I<chunked> transfer encoding with footer and self delimiting
+I<multipart/*> content types.
+
+The $c->get_request method will normally not return until the whole
+request has been received from the client.  This might not be what you
+want if the request is an upload of a multi-mega-byte file (and with
+chunked transfer encoding HTTP can even support infinite request
+messages - uploading live audio for instance).  If you pass a TRUE
+value as the $headers_only argument, then $c->get_request will return
+immediately after parsing the request headers and you are responsible
+for reading the rest of the request content (and if you are going to
+call $c->get_request again on the same connection you better read the
+correct number of bytes).
+
+=cut
+
+sub get_request
+{
+    my($self, $only_headers) = @_;
+    if (${*$self}{'httpd_nomore'}) {
+        $self->reason("No more requests from this connection");
+	return;
+    }
+
+    $self->reason("");
+    my $buf = ${*$self}{'httpd_rbuf'};
+    $buf = "" unless defined $buf;
+    
+    my $timeout = $ {*$self}{'io_socket_timeout'};
+    my $fdset = "";
+    vec($fdset, $self->fileno, 1) = 1;
+    local($_);
+
+  READ_HEADER:
+    while (1) {
+	# loop until we have the whole header in $buf
+	$buf =~ s/^(?:\015?\012)+//;  # ignore leading blank lines
+	if ($buf =~ /\012/) {  # potential, has at least one line
+	    if ($buf =~ /^\w+[^\012]+HTTP\/\d+\.\d+\015?\012/) {
+		if ($buf =~ /\015?\012\015?\012/) {
+		    last READ_HEADER;  # we have it
+		} elsif (length($buf) > 16*1024) {
+		    $self->send_error(413); # REQUEST_ENTITY_TOO_LARGE
+		    $self->reason("Very long header");
+		    return;
+		}
+	    } else {
+		last READ_HEADER;  # HTTP/0.9 client
+	    }
+	} elsif (length($buf) > 16*1024) {
+	    $self->send_error(414); # REQUEST_URI_TOO_LARGE
+	    $self->reason("Very long first line");
+	    return;
+	}
+	print STDERR "Need more data for complete header\n" if $DEBUG;
+	return unless $self->_need_more($buf, $timeout, $fdset);
+    }
+    if ($buf !~ s/^(\w+)[ \t]+(\S+)(?:[ \t]+(HTTP\/\d+\.\d+))?[^\012]*\012//) {
+	$self->send_error(400);  # BAD_REQUEST
+	$self->reason("Bad request line");
+	return;
+    }
+    my $proto = $3 || "HTTP/0.9";
+    my $r = HTTP::Request->new($1, url($2, $self->daemon->url));
+    $r->protocol($proto);
+    ${*$self}{'httpd_client_proto'} = $proto = _http_version($proto);
+
+    if ($proto >= $HTTP_1_0) {
+	# we expect to find some headers
+	my($key, $val);
+      HEADER:
+	while ($buf =~ s/^([^\012]*)\012//) {
+	    $_ = $1;
+	    s/\015$//;
+	    if (/^([\w\-]+)\s*:\s*(.*)/) {
+		$r->push_header($key, $val) if $key;
+		($key, $val) = ($1, $2);
+	    } elsif (/^\s+(.*)/) {
+		$val .= " $1";
+	    } else {
+		last HEADER;
+	    }
+	}
+	$r->push_header($key, $val) if $key;
+    }
+
+    my $conn = $r->header('Connection');
+    if ($proto >= $HTTP_1_1) {
+	${*$self}{'httpd_nomore'}++ if $conn && lc($conn) =~ /\bclose\b/;
+    } else {
+	${*$self}{'httpd_nomore'}++ unless $conn &&
+                                           lc($conn) =~ /\bkeep-alive\b/;
+    }
+
+    if ($only_headers) {
+	${*$self}{'httpd_rbuf'} = $buf;
+        return $r;
+    }
+
+    # Find out how much content to read
+    my $te  = $r->header('Transfer-Encoding');
+    my $ct  = $r->header('Content-Type');
+    my $len = $r->header('Content-Length');
+
+    if ($te && lc($te) eq 'chunked') {
+	# Handle chunked transfer encoding
+	my $body = "";
+      CHUNK:
+	while (1) {
+	    print STDERR "Chunked\n" if $DEBUG;
+	    if ($buf =~ s/^([^\012]*)\012//) {
+		my $chunk_head = $1;
+		unless ($chunk_head =~ /^([0-9A-Fa-f]+)/) {
+		    $self->send_error(400);
+		    $self->reason("Bad chunk header $chunk_head");
+		    return;
+		}
+		my $size = hex($1);
+		last CHUNK if $size == 0;
+
+		my $missing = $size - length($buf) + 2; # 2=CRLF at chunk end
+		# must read until we have a complete chunk
+		while ($missing > 0) {
+		    print STDERR "Need $missing more bytes\n" if $DEBUG;
+		    my $n = $self->_need_more($buf, $timeout, $fdset);
+		    return unless $n;
+		    $missing -= $n;
+		}
+		$body .= substr($buf, 0, $size);
+		substr($buf, 0, $size+2) = '';
+
+	    } else {
+		# need more data in order to have a complete chunk header
+		return unless $self->_need_more($buf, $timeout, $fdset);
+	    }
+	}
+	$r->content($body);
+
+	# pretend it was a normal entity body
+	$r->remove_header('Transfer-Encoding');
+	$r->header('Content-Length', length($body));
+
+	my($key, $val);
+      FOOTER:
+	while (1) {
+	    if ($buf !~ /\012/) {
+		# need at least one line to look at
+		return unless $self->_need_more($buf, $timeout, $fdset);
+	    } else {
+		$buf =~ s/^([^\012]*)\012//;
+		$_ = $1;
+		s/\015$//;
+		if (/^([\w\-]+)\s*:\s*(.*)/) {
+		    $r->push_header($key, $val) if $key;
+		    ($key, $val) = ($1, $2);
+		} elsif (/^\s+(.*)/) {
+		    $val .= " $1";
+		} elsif (!length) {
+		    last FOOTER;
+		} else {
+		    $self->reason("Bad footer syntax");
+		    return;
+		}
+	    }
+	}
+	$r->push_header($key, $val) if $key;
+
+    } elsif ($te) {
+	$self->send_error(501); 	# Unknown transfer encoding
+	$self->reason("Unknown transfer encoding '$te'");
+	return;
+
+    } elsif ($ct && lc($ct) =~ m/^multipart\/\w+\s*;.*boundary\s*=\s*(\w+)/) {
+	# Handle multipart content type
+	my $boundary = "$CRLF--$1--$CRLF";
+	my $index;
+	while (1) {
+	    $index = index($buf, $boundary);
+	    last if $index >= 0;
+	    # end marker not yet found
+	    return unless $self->_need_more($buf, $timeout, $fdset);
+	}
+	$index += length($boundary);
+	$r->content(substr($buf, 0, $index));
+	substr($buf, 0, $index) = '';
+
+    } elsif ($len) {
+	# Plain body specified by "Content-Length"
+	my $missing = $len - length($buf);
+	while ($missing > 0) {
+	    print "Need $missing more bytes of content\n" if $DEBUG;
+	    my $n = $self->_need_more($buf, $timeout, $fdset);
+	    return unless $n;
+	    $missing -= $n;
+	}
+	if (length($buf) > $len) {
+	    $r->content(substr($buf,0,$len));
+	    substr($buf, 0, $len) = '';
+	} else {
+	    $r->content($buf);
+	    $buf='';
+	}
+    }
+    ${*$self}{'httpd_rbuf'} = $buf;
+
+    $r;
+}
+
+sub _need_more
+{
+    my $self = shift;
+    #my($buf,$timeout,$fdset) = @_;
+    if ($_[1]) {
+	my($timeout, $fdset) = @_[1,2];
+	print STDERR "select(,,,$timeout)\n" if $DEBUG;
+	my $n = select($fdset,undef,undef,$timeout);
+	unless ($n) {
+	    $self->reason(defined($n) ? "Timeout" : "select: $!");
+	    return;
+	}
+    }
+    print STDERR "sysread()\n" if $DEBUG;
+    my $n = sysread($self, $_[0], 2048, length($_[0]));
+    $self->reason(defined($n) ? "Client closed" : "sysread: $!") unless $n;
+    $n;
+}
+
+=item $c->read_buffer([$new_value])
+
+Bytes read by $c->get_request, but not used are placed in the I<read
+buffer>.  The next time $c->get_request is called it will consume the
+bytes in this buffer before reading more data from the network
+connection itself.  The read buffer is invalid after $c->get_request
+has returned an undefined value.
+
+If you handle the reading of the request content yourself you need to
+empty this buffer before you read more and you need to place
+unconsumed bytes here.  You also need this buffer if you implement
+services like I<101 Switching Protocols>.
+
+This method always return the old buffer content and can optionally
+update the buffer content if you pass it an argument.
+
+=cut
+
+sub read_buffer
+{
+    my $self = shift;
+    my $old = ${*$self}{'httpd_rbuf'};
+    if (@_) {
+	${*$self}{'httpd_rbuf'} = shift;
+    }
+    $old;
+}
+
+
+=item $c->reason
+
+When $c->get_request returns C<undef> you can obtain a short string
+describing why it happened by calling $c->reason.
+
+=cut
+
+sub reason
+{
+    my $self = shift;
+    my $old = ${*$self}{'httpd_reason'};
+    if (@_) {
+        ${*$self}{'httpd_reason'} = shift;
+    }
+    $old;
+}
+
+
+=item $c->proto_ge($proto)
+
+Returns TRUE if the client announced a protocol with version number
+greater or equal to the given argument.  The $proto argument can be a
+string like "HTTP/1.1" or just "1.1".
+
+=cut
+
+sub proto_ge
+{
+    my $self = shift;
+    ${*$self}{'httpd_client_proto'} >= _http_version(shift);
+}
+
+sub _http_version
+{
+    local($_) = shift;
+    return 0 unless m,^(?:HTTP/)?(\d+)\.(\d+)$,i;
+    $1 * 1000 + $2;
+}
+
+=item $c->antique_client
+
+Returns TRUE if the client speaks the HTTP/0.9 protocol.  No status
+code and no headers should be returned to such a client.  This should
+be the same as !$c->proto_ge("HTTP/1.0").
+
+=cut
+
+sub antique_client
+{
+    my $self = shift;
+    ${*$self}{'httpd_client_proto'} < $HTTP_1_0;
+}
+
+
+=item $c->force_last_request
+
+Make sure that $c->get_request will not try to read more requests off
+this connection.  If you generate a response that is not self
+delimiting, then you should signal this fact by calling this method.
+
+This attribute is turned on automatically if the client announce
+protocol HTTP/1.0 or worse and does not include a "Connection:
+Keep-Alive" header.  It is also turned on automatically when HTTP/1.1
+or better clients send the "Connection: close" request header.
+
+=cut
+
+sub force_last_request
+{
+    my $self = shift;
+    ${*$self}{'httpd_nomore'}++;
+}
+
+
+=item $c->send_status_line( [$code, [$mess, [$proto]]] )
+
+Sends the status line back to the client.  If $code is omitted 200 is
+assumed.  If $mess is omitted, then a message corresponding to $code
+is inserted.  If $proto is missing the content of the
+$HTTP::Daemon::PROTO variable is used.
+
+=cut
+
+sub send_status_line
+{
+    my($self, $status, $message, $proto) = @_;
+    return if $self->antique_client;
+    $status  ||= RC_OK;
+    $message ||= status_message($status) || "";
+    $proto   ||= $HTTP::Daemon::PROTO || "HTTP/1.1";
+    print $self "$proto $status $message$CRLF";
+}
+
+=item $c->send_crlf
+
+Send the CRLF sequence to the client.
+
+=cut
+
+
+sub send_crlf
+{
+    my $self = shift;
+    print $self $CRLF;
+}
+
+
+=item $c->send_basic_header( [$code, [$mess, [$proto]]] )
+
+Sends the status line and the "Date:" and "Server:" headers back to
+the client.  This header is assumed to be continued and does not end
+with an empty CRLF line.
+
+=cut
+
+sub send_basic_header
+{
+    my $self = shift;
+    return if $self->antique_client;
+    $self->send_status_line(@_);
+    print $self "Date: ", time2str(time), $CRLF;
+    my $product = $self->daemon->product_tokens;
+    print $self "Server: $product$CRLF" if $product;
+}
+
+
+=item $c->send_response( [$res] )
+
+Takes a I<HTTP::Response> object as parameter and write it back to the
+client as the response.  We try hard to make sure that the response is
+self delimiting so that the connection can stay persistent for further
+request/response exchanges.
+
+The content attribute of the I<HTTP::Response> object can be a normal
+string or a subroutine reference.  If it is a subroutine, then
+whatever this callback routine returns will be written back to the
+client as the response content.  The routine will be called until it
+return an undefined or empty value.  If the client is HTTP/1.1 aware
+then we will use the chunked transfer encoding for the response.
+
+=cut
+
+sub send_response
+{
+    my $self = shift;
+    my $res = shift;
+    if (!ref $res) {
+	$res ||= RC_OK;
+	$res = HTTP::Response->new($res, @_);
+    }
+    my $content = $res->content;
+    my $chunked;
+    unless ($self->antique_client) {
+	my $code = $res->code;
+	$self->send_basic_header($code, $res->message, $res->protocol);
+	if ($code =~ /^(1\d\d|[23]04)$/) {
+	    # make sure content is empty
+	    $res->remove_header("Content-Length");
+	    $content = "";
+	} elsif ($res->request && $res->request->method eq "HEAD") {
+	    # probably OK
+	} elsif (ref($content) eq "CODE") {
+	    if ($self->proto_ge("HTTP/1.1")) {
+		$res->push_header("Transfer-Encoding" => "chunked");
+		$chunked++;
+	    } else {
+		$self->force_last_request;
+	    }
+	} elsif (length($content)) {
+	    $res->header("Content-Length" => length($content));
+	} else {
+	    $self->force_last_request;
+	}
+	print $self $res->headers_as_string($CRLF);
+	print $self $CRLF;  # separates headers and content
+    }
+    if (ref($content) eq "CODE") {
+	while (1) {
+	    my $chunk = &$content();
+	    last unless defined($chunk) && length($chunk);
+	    if ($chunked) {
+		printf $self "%x%s%s%s", length($chunk), $CRLF, $chunk, $CRLF;
+	    } else {
+		print $self $chunk;
+	    }
+	}
+	print $self "0$CRLF$CRLF" if $chunked;  # no trailers either
+    } elsif (length $content) {
+	print $self $content;
+    }
+}
+
+
+=item $c->send_redirect( $loc, [$code, [$entity_body]] )
+
+Sends a redirect response back to the client.  The location ($loc) can
+be an absolute or a relative URL. The $code must be one the redirect
+status codes, and it defaults to "301 Moved Permanently"
+
+=cut
+
+sub send_redirect
+{
+    my($self, $loc, $status, $content) = @_;
+    $status ||= RC_MOVED_PERMANENTLY;
+    Carp::croak("Status '$status' is not redirect") unless is_redirect($status);
+    $self->send_basic_header($status);
+    $loc = url($loc, $self->daemon->url) unless ref($loc);
+    $loc = $loc->abs;
+    print $self "Location: $loc$CRLF";
+    if ($content) {
+	my $ct = $content =~ /^\s*</ ? "text/html" : "text/plain";
+	print $self "Content-Type: $ct$CRLF";
+    }
+    print $self $CRLF;
+    print $self $content if $content;
+    $self->force_last_request;  # no use keeping the connection open
+}
+
+
+=item $c->send_error( [$code, [$error_message]] )
+
+Send an error response back to the client.  If the $code is missing a
+"Bad Request" error is reported.  The $error_message is a string that
+is incorporated in the body of the HTML entity body.
+
+=cut
+
+sub send_error
+{
+    my($self, $status, $error) = @_;
+    $status ||= RC_BAD_REQUEST;
+    Carp::croak("Status '$status' is not an error") unless is_error($status);
+    my $mess = status_message($status);
+    $error  ||= "";
+    $mess = <<EOT;
+<title>$status $mess</title>
+<h1>$status $mess</h1>
+$error
+EOT
+    unless ($self->antique_client) {
+        $self->send_basic_header($status);
+        print $self "Content-Type: text/html$CRLF";
+	print $self "Content-Length: " . length($mess) . $CRLF;
+        print $self $CRLF;
+    }
+    print $self $mess;
+    $status;
+}
+
+
+=item $c->send_file_response($filename)
+
+Send back a response with the specified $filename as content.  If the
+file happen to be a directory we will try to generate an HTML index
+of it.
+
+=cut
+
+sub send_file_response
+{
+    my($self, $file) = @_;
+    if (-d $file) {
+	$self->send_dir($file);
+    } elsif (-f _) {
+	# plain file
+	local(*F);
+	sysopen(F, $file, 0) or 
+	  return $self->send_error(RC_FORBIDDEN);
+	my($ct,$ce) = guess_media_type($file);
+	my($size,$mtime) = (stat _)[7,9];
+	unless ($self->antique_client) {
+	    $self->send_basic_header;
+	    print $self "Content-Type: $ct$CRLF";
+	    print $self "Content-Encoding: $ce$CRLF" if $ce;
+	    print $self "Content-Length: $size$CRLF" if $size;
+	    print $self "Last-Modified: ", time2str($mtime), "$CRLF" if $mtime;
+	    print $self $CRLF;
+	}
+	$self->send_file(\*F);
+	return RC_OK;
+    } else {
+	$self->send_error(RC_NOT_FOUND);
+    }
+}
+
+
+sub send_dir
+{
+    my($self, $dir) = @_;
+    $self->send_error(RC_NOT_FOUND) unless -d $dir;
+    $self->send_error(RC_NOT_IMPLEMENTED);
+}
+
+
+=item $c->send_file($fd);
+
+Copies the file back to the client.  The file can be a string (which
+will be interpreted as a filename) or a reference to an I<IO::Handle>
+or glob.
+
+=cut
+
+sub send_file
+{
+    my($self, $file) = @_;
+    my $opened = 0;
+    if (!ref($file)) {
+	local(*F);
+	open(F, $file) || return undef;
+	binmode(F);
+	$file = \*F;
+	$opened++;
+    }
+    my $cnt = 0;
+    my $buf = "";
+    my $n;
+    while ($n = sysread($file, $buf, 8*1024)) {
+	last if !$n;
+	$cnt += $n;
+	print $self $buf;
+    }
+    close($file) if $opened;
+    $cnt;
+}
+
+
+=item $c->daemon
+
+Return a reference to the corresponding I<HTTP::Daemon> object.
+
+=cut
+
+sub daemon
+{
+    my $self = shift;
+    ${*$self}{'httpd_daemon'};
+}
+
+=back
+
+=head1 SEE ALSO
+
+RFC 2068
+
+L<IO::Socket>, L<Apache>
+
+=head1 COPYRIGHT
+
+Copyright 1996-1998, Gisle Aas
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Date.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Date.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Date.pm	(revision 20131)
@@ -0,0 +1,330 @@
+# $Id$
+#
+package HTTP::Date;
+
+=head1 NAME
+
+HTTP::Date - date conversion routines
+
+=head1 SYNOPSIS
+
+ use HTTP::Date;
+
+ $string = time2str($time);    # Format as GMT ASCII time
+ $time = str2time($string);    # convert ASCII date to machine time
+
+=head1 DESCRIPTION
+
+This module provides two functions that deal with the HTTP date
+format.  The following functions are provided:
+
+=over 4
+
+=item time2str([$time])
+
+The time2str() function converts a machine time (seconds since epoch)
+to a string.  If the function is called without an argument, it will
+use the current time.
+
+The string returned is in the format defined by the HTTP/1.0
+specification.  This is a fixed length subset of the format defined by
+RFC 1123, represented in Universal Time (GMT).  An example of this
+format is:
+
+   Thu, 03 Feb 1994 17:09:00 GMT
+
+=item str2time($str [, $zone])
+
+The str2time() function converts a string to machine time.  It returns
+C<undef> if the format is unrecognized, or the year is not between 1970
+and 2038.  The function is able to parse the following formats:
+
+ "Wed, 09 Feb 1994 22:23:32 GMT"       -- HTTP format
+ "Thu Feb  3 17:03:55 GMT 1994"        -- ctime(3) format
+ "Thu Feb  3 00:00:00 1994",           -- ANSI C asctime() format
+ "Tuesday, 08-Feb-94 14:15:29 GMT"     -- old rfc850 HTTP format
+ "Tuesday, 08-Feb-1994 14:15:29 GMT"   -- broken rfc850 HTTP format
+
+ "03/Feb/1994:17:03:55 -0700"   -- common logfile format
+ "09 Feb 1994 22:23:32 GMT"     -- HTTP format (no weekday)
+ "08-Feb-94 14:15:29 GMT"       -- rfc850 format (no weekday)
+ "08-Feb-1994 14:15:29 GMT"     -- broken rfc850 format (no weekday)
+
+ "1994-02-03 14:15:29 -0100"    -- ISO 8601 format
+ "1994-02-03 14:15:29"          -- zone is optional
+ "1994-02-03"                   -- only date
+ "1994-02-03T14:15:29"          -- Use T as separator
+ "19940203T141529Z"             -- ISO 8601 compact format
+ "19940203"                     -- only date
+
+ "08-Feb-94"         -- old rfc850 HTTP format    (no weekday, no time)
+ "08-Feb-1994"       -- broken rfc850 HTTP format (no weekday, no time)
+ "09 Feb 1994"       -- proposed new HTTP format  (no weekday, no time)
+ "03/Feb/1994"       -- common logfile format     (no time, no offset)
+
+ "Feb  3  1994"      -- Unix 'ls -l' format
+ "Feb  3 17:03"      -- Unix 'ls -l' format
+
+ "11-15-96  03:52PM" -- Windows 'dir' format
+
+The parser ignores leading and trailing whitespace.  It also allow the
+seconds to be missing and the month to be numerical in most formats.
+
+The str2time() function takes an optional second argument that
+specifies the default time zone to use when converting the date.  This
+zone specification should be numerical (like "-0800" or "+0100") or
+"GMT".  This parameter is ignored if the zone is specified in the date
+string itself.  It this parameter is missing, and the date string
+format does not contain any zone specification then the local time
+zone is assumed.
+
+If the year is missing, then we assume that the date is the first
+matching date I<before> current time.
+
+=back
+
+=head1 BUGS
+
+Non-numerical time zones (like MET, PST) are all treated like GMT.
+Do not use them.  HTTP does not use them.
+
+The str2time() function has been told how to parse far too many
+formats.  This makes the module name misleading. To be sure it is
+really misleading you can also import the time2iso() and time2isoz()
+functions.  They work like time2str() but produce ISO-8601 formated
+strings (YYYY-MM-DD hh:mm:ss).
+
+=head1 COPYRIGHT
+
+Copyright 1995-1997, Gisle Aas
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
+
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+sub Version { $VERSION; }
+
+require 5.002;
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(time2str str2time);
+@EXPORT_OK = qw(time2iso time2isoz);
+
+use Time::Local ();
+
+use strict;
+use vars qw(@DoW @MoY %MoY);
+
+#@DoW = qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday);
+@DoW = qw(Sun Mon Tue Wed Thu Fri Sat);
+@MoY = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
+# Build %MoY hash
+my $i = 0;
+foreach(@MoY) {
+   $MoY{lc $_} = $i++;
+}
+
+my($current_month, $current_year) = (localtime)[4, 5];
+
+
+
+
+sub time2str (;$)
+{
+   my $time = shift;
+   $time = time unless defined $time;
+   my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($time);
+   sprintf("%s, %02d %s %04d %02d:%02d:%02d GMT",
+	   $DoW[$wday],
+	   $mday, $MoY[$mon], $year+1900,
+	   $hour, $min, $sec);
+}
+
+
+
+sub str2time ($;$)
+{
+   local($_) = shift;
+   return undef unless defined;
+   my($default_zone) = @_;
+
+   # Remove useless weekday, if it exists
+   s/^\s*(?:sun|mon|tue|wed|thu|fri|sat)\w*,?\s*//i;
+
+   my($day, $mon, $yr, $hr, $min, $sec, $tz, $aorp);
+   my $offset = 0;  # used when compensating for timezone
+
+ PARSEDATE: {
+      # Then we are able to check for most of the formats with this regexp
+      ($day,$mon,$yr,$hr,$min,$sec,$tz) =
+	/^\s*
+	 (\d\d?)               # day
+	    (?:\s+|[-\/])
+	 (\w+)                 # month
+	    (?:\s+|[-\/])
+	 (\d+)                 # year
+	 (?:
+	       (?:\s+|:)       # separator before clock
+	    (\d\d?):(\d\d)     # hour:min
+	    (?::(\d\d))?       # optional seconds
+	 )?                    # optional clock
+	    \s*
+	 ([-+]?\d{2,4}|GMT|gmt)? # timezone
+	    \s*$
+	/x
+	  and last PARSEDATE;
+
+      # Try the ctime and asctime format
+      ($mon, $day, $hr, $min, $sec, $tz, $yr) =
+	/^\s*                  # allow intial whitespace
+	 (\w{1,3})             # month
+	    \s+
+	 (\d\d?)               # day
+	    \s+
+	 (\d\d?):(\d\d)        # hour:min
+	 (?::(\d\d))?          # optional seconds
+	    \s+
+	 (?:(GMT|gmt)\s+)?     # optional GMT timezone
+	 (\d+)                 # year
+	    \s*$               # allow trailing whitespace
+	/x
+	  and last PARSEDATE;
+
+      # Then the Unix 'ls -l' date format
+      ($mon, $day, $yr, $hr, $min, $sec) =
+	/^\s*
+	 (\w{3})               # month
+	    \s+
+	 (\d\d?)               # day
+	    \s+
+	 (?:
+	    (\d\d\d\d) |       # year
+	    (\d{1,2}):(\d{2})  # hour:min
+            (?::(\d\d))?       # optional seconds
+	 )
+	 \s*$
+       /x
+	 and last PARSEDATE;
+
+      # ISO 8601 format '1996-02-29 12:00:00 -0100' and variants
+      ($yr, $mon, $day, $hr, $min, $sec, $tz) =
+	/^\s*
+	  (\d{4})              # year
+	     [-\/]?
+	  (\d\d?)              # numerical month
+	     [-\/]?
+	  (\d\d?)              # day
+	 (?:
+	       (?:\s+|:|T|-)   # separator before clock
+	    (\d\d?):?(\d\d)    # hour:min
+	    (?::?(\d\d))?      # optional seconds
+	 )?                    # optional clock
+	    \s*
+	 ([-+]?\d\d?:?(:?\d\d)?
+	  |Z|z)?               # timezone  (Z is "zero meridian", i.e. GMT)
+	    \s*$
+	/x
+	  and last PARSEDATE;
+
+      # Windows 'dir' 11-12-96  03:52PM
+      ($mon, $day, $yr, $hr, $min, $aorp) =
+        /^\s*
+          (\d{2})                # numerical month
+             -
+          (\d{2})                # day
+             -
+          (\d{2})                # year
+             \s+
+          (\d\d?):(\d\d)([apAP][mM])  # hour:min AM or PM
+             \s*$
+        /x
+          and last PARSEDATE;
+
+      # If it is not recognized by now we give up
+      return undef;
+   }
+
+   # Translate month name to number
+   if ($mon =~ /^\d+$/) {
+     # numeric month
+     return undef if $mon < 1 || $mon > 12;
+     $mon--;
+   } else {
+     $mon = lc $mon;
+     return undef unless exists $MoY{$mon};
+     $mon = $MoY{$mon};
+   }
+
+   # If the year is missing, we assume some date before the current,
+   # because these date are mostly present on "ls -l" listings.
+   unless (defined $yr) {
+	$yr = $current_year;
+	$yr-- if $mon > $current_month;
+    }
+
+   # Then we check if the year is acceptable
+   return undef if $yr > 99 && $yr < 1900;  # We ignore these years
+   $yr += 100 if $yr < 50;  # a stupid thing to do???
+   $yr -= 1900 if $yr >= 1900;
+   # The $yr is now relative to 1900 (as expected by timelocal())
+
+   # timelocal() seems to go into an infinite loop if it is given out
+   # of range parameters.  Let's check the year at least.
+
+   # Epoch counter maxes out in year 2038, assuming "time_t" is 32 bit
+   return undef if $yr > 138;
+   return undef if $yr <  70;  # 1970 is Unix epoch
+
+   # Compensate for AM/PM
+   if ($aorp) {
+       $aorp = uc $aorp;
+       $hr = 0 if $hr == 12 && $aorp eq 'AM';
+       $hr += 12 if $aorp eq 'PM' && $hr != 12;
+   }
+
+   # Make sure things are defined
+   for ($sec, $min, $hr) {  $_ = 0 unless defined   }
+
+   # Should we compensate for the timezone?
+   $tz = $default_zone unless defined $tz;
+   return eval {Time::Local::timelocal($sec, $min, $hr, $day, $mon, $yr)}
+     unless defined $tz;
+
+   # We can calculate offset for numerical time zones
+   if ($tz =~ /^([-+])?(\d\d?):?(\d\d)?$/) {
+       $offset = 3600 * $2;
+       $offset += 60 * $3 if $3;
+       $offset *= -1 if $1 && $1 ne '-';
+   }
+   eval{Time::Local::timegm($sec, $min, $hr, $day, $mon, $yr) + $offset};
+}
+
+
+
+# And then some bloat because I happen to like the ISO 8601 time
+# format.
+
+sub time2iso (;$)
+{
+   my $time = shift;
+   $time = time unless defined $time;
+   my($sec,$min,$hour,$mday,$mon,$year) = localtime($time);
+   sprintf("%04d-%02d-%02d %02d:%02d:%02d",
+	   $year+1900, $mon+1, $mday, $hour, $min, $sec);
+}
+
+
+sub time2isoz (;$)
+{
+    my $time = shift;
+    $time = time unless defined $time;
+    my($sec,$min,$hour,$mday,$mon,$year) = gmtime($time);
+    sprintf("%04d-%02d-%02d %02d:%02d:%02dZ",
+            $year+1900, $mon+1, $mday, $hour, $min, $sec);
+}
+
+1;
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Headers.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Headers.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Headers.pm	(revision 20131)
@@ -0,0 +1,540 @@
+#
+# $Id$
+
+package HTTP::Headers;
+
+=head1 NAME
+
+HTTP::Headers - Class encapsulating HTTP Message headers
+
+=head1 SYNOPSIS
+
+ require HTTP::Headers;
+ $h = new HTTP::Headers;
+
+=head1 DESCRIPTION
+
+The C<HTTP::Headers> class encapsulates HTTP-style message headers.
+The headers consist of attribute-value pairs, which may be repeated,
+and which are printed in a particular order.
+
+Instances of this class are usually created as member variables of the
+C<HTTP::Request> and C<HTTP::Response> classes, internal to the
+library.
+
+The following methods are available:
+
+=over 4
+
+=cut
+
+use strict;
+use vars qw($VERSION $TRANSLATE_UNDERSCORE);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+use Carp ();
+
+# Could not use the AutoLoader becase several of the method names are
+# not unique in the first 8 characters.
+#use SelfLoader;
+
+
+# "Good Practice" order of HTTP message headers:
+#    - General-Headers
+#    - Request-Headers
+#    - Response-Headers
+#    - Entity-Headers
+# (From draft-ietf-http-v11-spec-rev-01, Nov 21, 1997)
+
+my @header_order = qw(
+   Cache-Control Connection Date Pragma Transfer-Encoding Upgrade Trailer Via
+
+   Accept Accept-Charset Accept-Encoding Accept-Language
+   Authorization Expect From Host
+   If-Modified-Since If-Match If-None-Match If-Range If-Unmodified-Since
+   Max-Forwards Proxy-Authorization Range Referer TE User-Agent
+
+   Accept-Ranges Age Location Proxy-Authenticate Retry-After Server Vary
+   Warning WWW-Authenticate
+
+   Allow Content-Base Content-Encoding Content-Language Content-Length
+   Content-Location Content-MD5 Content-Range Content-Type
+   ETag Expires Last-Modified
+);
+
+# Make alternative representations of @header_order.  This is used
+# for sorting and case matching.
+my $i = 0;
+my %header_order;
+my %standard_case;
+for (@header_order) {
+    my $lc = lc $_;
+    $header_order{$lc} = $i++;
+    $standard_case{$lc} = $_;
+}
+
+$TRANSLATE_UNDERSCORE = 1 unless defined $TRANSLATE_UNDERSCORE;
+
+
+
+=item $h = new HTTP::Headers
+
+Constructs a new C<HTTP::Headers> object.  You might pass some initial
+attribute-value pairs as parameters to the constructor.  I<E.g.>:
+
+ $h = new HTTP::Headers
+     Date         => 'Thu, 03 Feb 1994 00:00:00 GMT',
+     Content_Type => 'text/html; version=3.2',
+     Content_Base => 'http://www.sn.no/';
+
+=cut
+
+sub new
+{
+    my($class) = shift;
+    my $self = bless {}, $class;
+    $self->header(@_); # set up initial headers
+    $self;
+}
+
+
+=item $h->header($field [=> $value],...)
+
+Get or set the value of a header.  The header field name is not case
+sensitive.  To make the life easier for perl users who wants to avoid
+quoting before the => operator, you can use '_' as a synonym for '-'
+in header names (this behaviour can be suppressed by setting
+$HTTP::Headers::TRANSLATE_UNDERSCORE to a FALSE value).
+
+The header() method accepts multiple ($field => $value) pairs, so you
+can update several fields with a single invocation.
+
+The optional $value argument may be a scalar or a reference to a list
+of scalars. If the $value argument is undefined or not given, then the
+header is not modified.
+
+The old value of the last of the $field values is returned.
+Multi-valued fields will be concatenated with "," as separator in
+scalar context.
+
+ $header->header(MIME_Version => '1.0',
+		 User_Agent   => 'My-Web-Client/0.01');
+ $header->header(Accept => "text/html, text/plain, image/*");
+ $header->header(Accept => [qw(text/html text/plain image/*)]);
+ @accepts = $header->header('Accept');
+
+=cut
+
+sub header
+{
+    my $self = shift;
+    my($field, $val, @old);
+    while (($field, $val) = splice(@_, 0, 2)) {
+	@old = $self->_header($field, $val);
+    }
+    return @old if wantarray;
+    return $old[0] if @old <= 1;
+    join(", ", @old);
+}
+
+sub _header
+{
+    my($self, $field, $val, $push) = @_;
+    $field =~ tr/_/-/ if $TRANSLATE_UNDERSCORE;
+
+    # $push is only used interally sub push_header
+    Carp::croak('Need a field name') unless length($field);
+
+    my $lc_field = lc $field;
+    unless(defined $standard_case{$lc_field}) {
+	# generate a %stadard_case entry for this field
+	$field =~ s/\b(\w)/\u$1/g;
+	$standard_case{$lc_field} = $field;
+    }
+
+    my $h = $self->{$lc_field};
+    my @old = ref($h) ? @$h : (defined($h) ? ($h) : ());
+
+    if (defined $val) {
+	my @new = $push ? @old : ();
+	if (!ref($val)) {
+	    push(@new, $val);
+	} elsif (ref($val) eq 'ARRAY') {
+	    push(@new, @$val);
+	} else {
+	    Carp::croak("Unexpected field value $val");
+	}
+	$self->{$lc_field} = @new > 1 ? \@new : $new[0];
+    }
+    @old;
+}
+
+
+# Compare function which makes it easy to sort headers in the
+# recommended "Good Practice" order.
+sub _header_cmp
+{
+    # Unknown headers are assign a large value so that they are
+    # sorted last.  This also helps avoiding a warning from -w
+    # about comparing undefined values.
+    $header_order{$a} = 999 unless defined $header_order{$a};
+    $header_order{$b} = 999 unless defined $header_order{$b};
+
+    $header_order{$a} <=> $header_order{$b} || $a cmp $b;
+}
+
+
+=item $h->scan(\&doit)
+
+Apply a subroutine to each header in turn.  The callback routine is
+called with two parameters; the name of the field and a single value.
+If the header has more than one value, then the routine is called once
+for each value.  The field name passed to the callback routine has
+case as suggested by HTTP Spec, and the headers will be visited in the
+recommended "Good Practice" order.
+
+=cut
+
+sub scan
+{
+    my($self, $sub) = @_;
+    my $key;
+    foreach $key (sort _header_cmp keys %$self) {
+        next if $key =~ /^_/;
+	my $vals = $self->{$key};
+	if (ref($vals)) {
+	    my $val;
+	    for $val (@$vals) {
+		&$sub($standard_case{$key} || $key, $val);
+	    }
+	} else {
+	    &$sub($standard_case{$key} || $key, $vals);
+	}
+    }
+}
+
+
+=item $h->as_string([$endl])
+
+Return the header fields as a formatted MIME header.  Since it
+internally uses the C<scan()> method to build the string, the result
+will use case as suggested by HTTP Spec, and it will follow
+recommended "Good Practice" of ordering the header fieds.  Long header
+values are not folded. 
+
+The optional parameter specifies the line ending sequence to use.  The
+default is C<"\n">.  Embedded "\n" characters in the header will be
+substitued with this line ending sequence.
+
+=cut
+
+sub as_string
+{
+    my($self, $endl) = @_;
+    $endl = "\n" unless defined $endl;
+
+    my @result = ();
+    $self->scan(sub {
+	my($field, $val) = @_;
+	if ($val =~ /\n/) {
+	    # must handle header values with embedded newlines with care
+	    $val =~ s/\s+$//;          # trailing newlines and space must go
+	    $val =~ s/\n\n+/\n/g;      # no empty lines
+	    $val =~ s/\n([^\040\t])/\n $1/g;  # intial space for continuation
+	    $val =~ s/\n/$endl/g;      # substitute with requested line ending
+	}
+	push(@result, "$field: $val");
+    });
+
+    join($endl, @result, '');
+}
+
+
+# The remaining functions should autoloaded only when needed
+
+# A bug in 5.002gamma makes it risky to have POD text inside the
+# autoloaded section of the code, so we keep the documentation before
+# the __DATA__ token.
+
+=item $h->push_header($field, $val)
+
+Add a new field value of the specified header.  The header field name
+is not case sensitive.  The field need not already have a
+value. Previous values for the same field are retained.  The argument
+may be a scalar or a reference to a list of scalars.
+
+ $header->push_header(Accept => 'image/jpeg');
+
+=item $h->remove_header($field,...)
+
+This function removes the headers with the specified names.
+
+=item $h->clone
+
+Returns a copy of this HTTP::Headers object.
+
+=back
+
+=head1 CONVENIENCE METHODS
+
+The most frequently used headers can also be accessed through the
+following convenience methods.  These methods can both be used to read
+and to set the value of a header.  The header value is set if you pass
+an argument to the method.  The old header value is always returned.
+
+Methods that deal with dates/times always convert their value to system
+time (seconds since Jan 1, 1970) and they also expect this kind of
+value when the header value is set.
+
+=over 4
+
+=item $h->date
+
+This header represents the date and time at which the message was
+originated. I<E.g.>:
+
+  $h->date(time);  # set current date
+
+=item $h->expires
+
+This header gives the date and time after which the entity should be
+considered stale.
+
+=item $h->if_modified_since
+
+=item $h->if_unmodified_since
+
+This header is used to make a request conditional.  If the requested
+resource has (not) been modified since the time specified in this field,
+then the server will return a C<"304 Not Modified"> response instead of
+the document itself.
+
+=item $h->last_modified
+
+This header indicates the date and time at which the resource was last
+modified. I<E.g.>:
+
+  # check if document is more than 1 hour old
+  if ($h->last_modified < time - 60*60) {
+	...
+  }
+
+=item $h->content_type
+
+The Content-Type header field indicates the media type of the message
+content. I<E.g.>:
+
+  $h->content_type('text/html');
+
+The value returned will be converted to lower case, and potential
+parameters will be chopped off and returned as a separate value if in
+an array context.  This makes it safe to do the following:
+
+  if ($h->content_type eq 'text/html') {
+     # we enter this place even if the real header value happens to
+     # be 'TEXT/HTML; version=3.0'
+     ...
+  }
+
+=item $h->content_encoding
+
+The Content-Encoding header field is used as a modifier to the
+media type.  When present, its value indicates what additional
+encoding mechanism has been applied to the resource.
+
+=item $h->content_length
+
+A decimal number indicating the size in bytes of the message content.
+
+=item $h->content_language
+
+The natural language(s) of the intended audience for the message
+content.  The value is one or more language tags as defined by RFC
+1766.  Eg. "no" for Norwegian and "en-US" for US-English.
+
+=item $h->title
+
+The title of the document.  In libwww-perl this header will be
+initialized automatically from the E<lt>TITLE>...E<lt>/TITLE> element
+of HTML documents.  I<This header is no longer part of the HTTP
+standard.>
+
+=item $h->user_agent
+
+This header field is used in request messages and contains information
+about the user agent originating the request.  I<E.g.>:
+
+  $h->user_agent('Mozilla/1.2');
+
+=item $h->server
+
+The server header field contains information about the software being
+used by the originating server program handling the request.
+
+=item $h->from
+
+This header should contain an Internet e-mail address for the human
+user who controls the requesting user agent.  The address should be
+machine-usable, as defined by RFC822.  E.g.:
+
+  $h->from('Gisle Aas <aas@sn.no>');
+
+=item $h->referer
+
+Used to specify the address (URI) of the document from which the
+requested resouce address was obtained.
+
+=item $h->www_authenticate
+
+This header must be included as part of a "401 Unauthorized" response.
+The field value consist of a challenge that indicates the
+authentication scheme and parameters applicable to the requested URI.
+
+=item $h->proxy_authenticate
+
+This header must be included in a "407 Proxy Authentication Required"
+response.
+
+=item $h->authorization
+
+=item $h->proxy_authorization
+
+A user agent that wishes to authenticate itself with a server or a
+proxy, may do so by including these headers.
+
+=item $h->authorization_basic
+
+This method is used to get or set an authorization header that use the
+"Basic Authentication Scheme".  In array context it will return two
+values; the user name and the password.  In scalar context it will
+return I<"uname:password"> as a single string value.
+
+When used to set the header value, it expects two arguments.  I<E.g.>:
+
+  $h->authorization_basic($uname, $password);
+
+The method will croak if the $uname contains a colon ':'.
+
+=item $h->proxy_authorization_basic
+
+Same as authorization_basic() but will set the "Proxy-Authorization"
+header instead.
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 1995-1998 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
+
+1;
+
+#__DATA__
+
+sub clone
+{
+    my $self = shift;
+    my $clone = new HTTP::Headers;
+    $self->scan(sub { $clone->push_header(@_);} );
+    $clone;
+}
+
+sub push_header
+{
+    Carp::croak('Usage: $h->push_header($field, $val)') if @_ != 3;
+    shift->_header(@_, 'PUSH');
+}
+
+
+sub remove_header
+{
+    my($self, @fields) = @_;
+    my $field;
+    foreach $field (@fields) {
+	$field =~ tr/_/-/ if $TRANSLATE_UNDERSCORE;
+	delete $self->{lc $field};
+    }
+}
+
+# Convenience access functions
+
+sub _date_header
+{
+    require HTTP::Date;
+    my($self, $header, $time) = @_;
+    my($old) = $self->_header($header);
+    if (defined $time) {
+	$self->_header($header, HTTP::Date::time2str($time));
+    }
+    HTTP::Date::str2time($old);
+}
+
+sub date                { shift->_date_header('Date',                @_); }
+sub expires             { shift->_date_header('Expires',             @_); }
+sub if_modified_since   { shift->_date_header('If-Modified-Since',   @_); }
+sub if_unmodified_since { shift->_date_header('If-Unmodified-Since', @_); }
+sub last_modified       { shift->_date_header('Last-Modified',       @_); }
+
+# This is used as a private LWP extention.  The Client-Date header is
+# added as a timestamp to a response when it has been received.
+sub client_date         { shift->_date_header('Client-Date',         @_); }
+
+# The retry_after field is dual format (can also be a expressed as
+# number of seconds from now), so we don't provide an easy way to
+# access it until we have know how both these interfaces can be
+# addressed.  One possibility is to return a negative value for
+# relative seconds and a positive value for epoch based time values.
+#sub retry_after       { shift->_date_header('Retry-After',       @_); }
+
+sub content_type      {
+  my $ct = (shift->_header('Content-Type', @_))[0];
+  return '' unless defined($ct) && length($ct);
+  my @ct = split(/\s*;\s*/, lc($ct));
+  wantarray ? @ct : $ct[0];
+}
+
+sub title             { (shift->_header('Title',            @_))[0] }
+sub content_encoding  { (shift->_header('Content-Encoding', @_))[0] }
+sub content_language  { (shift->_header('Content-Language', @_))[0] }
+sub content_length    { (shift->_header('Content-Length',   @_))[0] }
+
+sub user_agent        { (shift->_header('User-Agent',       @_))[0] }
+sub server            { (shift->_header('Server',           @_))[0] }
+
+sub from              { (shift->_header('From',             @_))[0] }
+sub referer           { (shift->_header('Referer',          @_))[0] }
+sub warning           { (shift->_header('Warning',          @_))[0] }
+
+sub www_authenticate  { (shift->_header('WWW-Authenticate', @_))[0] }
+sub authorization     { (shift->_header('Authorization',    @_))[0] }
+
+sub proxy_authenticate  { (shift->_header('Proxy-Authenticate',  @_))[0] }
+sub proxy_authorization { (shift->_header('Proxy-Authorization', @_))[0] }
+
+sub authorization_basic       { shift->_basic_auth("Authorization",       @_) }
+sub proxy_authorization_basic { shift->_basic_auth("Proxy-Authorization", @_) }
+
+sub _basic_auth {
+    require MIME::Base64;
+    my($self, $h, $user, $passwd) = @_;
+    my($old) = $self->_header($h);
+    if (defined $user) {
+	Carp::croak("Basic authorization user name can't contain ':'")
+	  if $user =~ /:/;
+	$passwd = '' unless defined $passwd;
+	$self->_header($h => 'Basic ' .
+                             MIME::Base64::encode("$user:$passwd", ''));
+    }
+    if (defined $old && $old =~ s/^\s*Basic\s+//) {
+	my $val = MIME::Base64::decode($old);
+	return $val unless wantarray;
+	return split(/:/, $val, 2);
+    }
+    return;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Headers/Auth.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Headers/Auth.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Headers/Auth.pm	(revision 20131)
@@ -0,0 +1,94 @@
+package HTTP::Headers::Auth;
+
+use strict;
+use vars qw($VERSION);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+require HTTP::Headers;
+package HTTP::Headers;
+
+BEGIN {
+    # we provide a new (and better) implementations below
+    undef(&www_authenticate);
+    undef(&proxy_authenticate);
+}
+
+require HTTP::Headers::Util;
+
+sub _parse_authenticate
+{
+    my @ret;
+    for (HTTP::Headers::Util::split_header_words(@_)) {
+	if (!defined($_->[1])) {
+	    # this is a new auth scheme
+	    push(@ret, lc(shift @$_) => {});
+	    shift @$_;
+	}
+	if (@ret) {
+	    # this a new parameter pair for the last auth scheme
+	    while (@$_) {
+		my $k = lc(shift @$_);
+		my $v = shift @$_;
+	        $ret[-1]{$k} = $v;
+	    }
+	} else {
+	    # something wrong, parameter pair without any scheme seen
+	    # IGNORE
+	}
+    }
+    @ret;
+}
+
+sub _authenticate
+{
+    my $self = shift;
+    my $header = shift;
+    my @old = $self->_header($header);
+    if (@_) {
+	$self->remove_header($header);
+	my @new = @_;
+	while (@new) {
+	    my $a_scheme = shift(@new);
+	    if ($a_scheme =~ /\s/) {
+		# assume complete valid value, pass it through
+		$self->push_header($header, $a_scheme);
+	    } else {
+		my @param;
+		if (@new) {
+		    my $p = $new[0];
+		    if (ref($p) eq "ARRAY") {
+			@param = @$p;
+			shift(@new);
+		    } elsif (ref($p) eq "HASH") {
+			@param = %$p;
+			shift(@new);
+		    }
+		}
+		my $val = ucfirst(lc($a_scheme));
+		if (@param) {
+		    my $sep = " ";
+		    while (@param) {
+			my $k = shift @param;
+			my $v = shift @param;
+			if ($v =~ /[^0-9a-zA-Z]/ || lc($k) eq "realm") {
+			    # must quote the value
+			    $v =~ s,([\\\"]),\\$1,g;
+			    $v = qq("$v");
+			}
+			$val .= "$sep$k=$v";
+			$sep = ", ";
+		    }
+		}
+		$self->push_header($header, $val);
+	    }
+	}
+    }
+    return unless defined wantarray;
+    wantarray ? _parse_authenticate(@old) : join(", ", @old);
+}
+
+
+sub www_authenticate    { shift->_authenticate("WWW-Authenticate", @_)   }
+sub proxy_authenticate  { shift->_authenticate("Proxy-Authenticate", @_) }
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Headers/ETag.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Headers/ETag.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Headers/ETag.pm	(revision 20131)
@@ -0,0 +1,88 @@
+package HTTP::Header::ETag;
+
+use strict;
+use vars qw($VERSION);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+require HTTP::Date;
+
+require HTTP::Headers;
+package HTTP::Headers;
+
+sub _etags
+{
+    my $self = shift;
+    my $header = shift;
+    my @old = _split_etag_list($self->_header($header));
+    if (@_) {
+	$self->_header($header => join(", ", _split_etag_list(@_)));
+    }
+    wantarray ? @old : join(", ", @old);
+}
+
+sub etag          { shift->_etags("ETag", @_); }
+sub if_match      { shift->_etags("If-Match", @_); }
+sub if_none_match { shift->_etags("If-None-Match", @_); }
+
+sub if_range {
+    # Either a date or an entity-tag
+    my $self = shift;
+    my @old = $self->_header("If-Range");
+    if (@_) {
+	my $new = shift;
+	if (!defined $new) {
+	    $self->remove_header("If-Range");
+	} elsif ($new =~ /^\d+$/) {
+	    $self->_date_header("If-Range", $new);
+	} else {
+	    $self->_etags("If-Range", $new);
+	}
+    }
+    return unless defined(wantarray);
+    for (@old) {
+	my $t = HTTP::Date::str2time($_);
+	$_ = $t if $t;
+    }
+    wantarray ? @old : join(", ", @old);
+}
+
+
+# Split a list of entity tag values.  The return value is a list
+# consisting of one element per entity tag.  Suitable for parsing
+# headers like C<If-Match>, C<If-None-Match>.  You might even want to
+# use it on C<ETag> and C<If-Range> entity tag values, because it will
+# normalize them to the common form.
+#
+#  entity-tag	  = [ weak ] opaque-tag
+#  weak		  = "W/"
+#  opaque-tag	  = quoted-string
+
+
+sub _split_etag_list
+{
+    my(@val) = @_;
+    my @res;
+    for (@val) {
+        while (length) {
+            my $weak = "";
+	    $weak = "W/" if s,^\s*[wW]/,,;
+            my $etag = "";
+	    if (s/^\s*(\"[^\"\\]*(?:\\.[^\"\\]*)*\")//) {
+		push(@res, "$weak$1");
+            } elsif (s/^\s*,//) {
+                push(@res, qq(W/"")) if $weak;
+            } elsif (s/^\s*([^,\s]+)//) {
+                $etag = $1;
+		$etag =~ s/([\"\\])/\\$1/g;
+	        push(@res, qq($weak"$etag"));
+            } elsif (s/^\s+// || !length) {
+                push(@res, qq(W/"")) if $weak;
+            } else {
+	 	die "This should not happen: '$_'";
+            }
+        }
+   }
+   @res;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Headers/Util.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Headers/Util.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Headers/Util.pm	(revision 20131)
@@ -0,0 +1,180 @@
+package HTTP::Headers::Util;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT_OK);
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+require Exporter;
+@ISA=qw(Exporter);
+
+@EXPORT_OK=qw(split_header_words join_header_words);
+
+=head1 NAME
+
+HTTP::Headers::Util - Header value parsing utility functions
+
+=head1 SYNOPSIS
+
+  use HTTP::Headers::Util qw(split_header_words);
+  @values = split_header_words($h->header("Content-Type"));
+
+=head1 DESCRIPTION
+
+This module provide a few functions that helps parsing and
+construction of valid HTTP header values.  None of the functions are
+exported by default.
+
+The following functions are provided:
+
+=over 4
+
+
+=item split_header_words( @header_values )
+
+This function will parse the header values given as argument into a
+list of anonymous arrays containing key/value pairs.  The function
+know how to deal with ",", ";" and "=" as well as quoted values after
+"=".  A list of space separated tokens are parsed as if they were
+separated by ";".
+
+If the @header_values passed as argument contains multiple values,
+then they are treated as if they were a single value separated by
+comma ",".
+
+This means that this function is useful to parse header fields that
+follow this syntax (BNF as from the HTTP/1.1 specification, but we relax
+the requirement for tokens).
+
+  headers           = #header
+  header            = (token | parameter) *( [";"] (token | parameter))
+
+  token             = 1*<any CHAR except CTLs or separators>
+  separators        = "(" | ")" | "<" | ">" | "@"
+                    | "," | ";" | ":" | "\" | <">
+                    | "/" | "[" | "]" | "?" | "="
+                    | "{" | "}" | SP | HT
+
+  quoted-string     = ( <"> *(qdtext | quoted-pair ) <"> )
+  qdtext            = <any TEXT except <">>
+  quoted-pair       = "\" CHAR
+
+  parameter         = attribute "=" value
+  attribute         = token
+  value             = token | quoted-string
+
+Each I<header> is represented by an anonymous array of key/value
+pairs.  If a token is recognized then the value will be C<undef>.
+Syntactically incorrect headers will not necessary be parsed as you
+would want.
+
+This is easier to describe with some examples:
+
+   split_header_words('foo="bar"; port="80,81"; discard, bar=baz')
+   split_header_words('text/html; charset="iso-8859-1");
+   split_header_words('Basic realm="\"foo\\bar\""');
+
+will return
+
+   [foo=>'bar', port=>'80,81', discard=> undef], [bar=>'baz' ]
+   ['text/html' => undef, charset => 'iso-8859-1']
+   [Basic => undef, realm => '"foo\bar"']
+
+=cut
+
+
+sub split_header_words
+{
+    my(@val) = @_;
+    my @res;
+    for (@val) {
+	my @cur;
+	while (length) {
+	    if (s/^\s*(=*[^\s=;,]+)//) {  # 'token' or parameter 'attribute'
+		push(@cur, $1);
+		# a quoted value
+		if (s/^\s*=\s*\"([^\"\\]*(?:\\.[^\"\\]*)*)\"//) {
+		    my $val = $1;
+		    $val =~ s/\\(.)/$1/g;
+		    push(@cur, $val);
+		# some unquoted value
+		} elsif (s/^\s*=\s*([^;,\s]*)//) {
+		    my $val = $1;
+		    $val =~ s/\s+$//;
+		    push(@cur, $val);
+		# no value, a lone token
+		} else {
+		    push(@cur, undef);
+		}
+	    } elsif (s/^\s*,//) {
+		push(@res, [@cur]) if @cur;
+		@cur = ();
+	    } elsif (s/^\s*;// || s/^\s+//) {
+		# continue
+	    } else {
+		die "This should not happen: '$_'";
+	    }
+	}
+	push(@res, \@cur) if @cur;
+    }
+    @res;
+}
+
+
+=item join_header_words( @arrays )
+
+This will do the opposite convertion of what split_header_words()
+does.  It takes a list of anonymous arrays as argument (or a list of
+key/value pairs) and produce a single header value.  Attribute values
+are quoted if needed.
+
+Example:
+
+   join_header_words(["text/plain" => undef, charset => "iso-8859/1"]);
+   join_header_words(""text/plain" => undef, charset => "iso-8859/1");
+
+will both return the string:
+
+   text/plain; charset="iso-8859/1"
+
+=cut
+
+sub join_header_words
+{
+    @_ = ([@_]) if @_ && !ref($_[0]);
+    my @res;
+    for (@_) {
+	my @cur = @$_;
+	my @attr;
+	while (@cur) {
+	    my $k = shift @cur;
+	    my $v = shift @cur;
+	    if (defined $v) {
+		if ($v =~ /^\w+$/) {
+		    $k .= "=$v";
+		} else {
+		    $v =~ s/([\"\\])/\\$1/g;  # escape " and \
+		    $k .= qq(="$v");
+		}
+	    }
+	    push(@attr, $k);
+	}
+	push(@res, join("; ", @attr)) if @attr;
+    }
+    join(", ", @res);
+}
+
+1;
+
+__END__
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 1997-1998, Gisle Aas
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Message.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Message.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Message.pm	(revision 20131)
@@ -0,0 +1,208 @@
+#
+# $Id$
+
+package HTTP::Message;
+
+=head1 NAME
+
+HTTP::Message - Class encapsulating HTTP messages
+
+=head1 SYNOPSIS
+
+ package HTTP::Request;  # or HTTP::Response
+ require HTTP::Message;
+ @ISA=qw(HTTP::Message);
+
+=head1 DESCRIPTION
+
+A C<HTTP::Message> object contains some headers and a content (body).
+The class is abstract, i.e. it only used as a base class for
+C<HTTP::Request> and C<HTTP::Response> and should never instantiated
+as itself.
+
+The following methods are available:
+
+=over 4
+
+=cut
+
+#####################################################################
+
+require HTTP::Headers;
+require Carp;
+use strict;
+use vars qw($VERSION $AUTOLOAD);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+=item $mess = new HTTP::Message;
+
+This is the object constructor.  It should only be called internally
+by this library.  External code should construct C<HTTP::Request> or
+C<HTTP::Response> objects.
+
+=cut
+
+sub new
+{
+    my($class, $header, $content) = @_;
+    if (defined $header) {
+	Carp::croak("Bad header argument") unless ref $header;
+	$header = $header->clone;
+    } else {
+	$header = HTTP::Headers->new;
+    }
+    $content = '' unless defined $content;
+    bless {
+	'_headers' => $header,
+	'_content' => $content,
+    }, $class;
+}
+
+
+=item $mess->clone()
+
+Returns a copy of the object.
+
+=cut
+
+sub clone
+{
+    my $self  = shift;
+    my $clone = HTTP::Message->new($self->{'_headers'}, $self->{'_content'});
+    $clone;
+}
+
+=item $mess->protocol([$proto])
+
+Sets the HTTP protocol used for the message.  The protocol() is a string
+like "HTTP/1.0" or "HTTP/1.1".
+
+=cut
+
+sub protocol { shift->_elem('_protocol',  @_); }
+
+=item $mess->content([$content])
+
+The content() method sets the content if an argument is given.  If no
+argument is given the content is not touched.  In either case the
+previous content is returned.
+
+=item $mess->add_content($data)
+
+The add_content() methods appends more data to the end of the previous
+content.
+
+=cut
+
+sub content   { shift->_elem('_content',  @_); }
+
+sub add_content
+{
+    my $self = shift;
+    if (ref($_[0])) {
+	$self->{'_content'} .= ${$_[0]};  # for backwards compatability
+    } else {
+	$self->{'_content'} .= $_[0];
+    }
+}
+
+=item $mess->content_ref
+
+The content_ref() method will return a reference to content string.
+It can be more efficient to access the content this way if the content
+is huge, and it can be used for direct manipulation of the content,
+for instance:
+
+  ${$res->content_ref} =~ s/\bfoo\b/bar/g;
+
+=cut
+
+sub content_ref
+{
+    my $self = shift;
+    \$self->{'_content'};
+}
+
+sub as_string
+{
+    "";  # To be overridden in subclasses
+}
+
+=item $mess->headers;
+
+Return the embedded HTTP::Headers object.
+
+=item $mess->headers_as_string([$endl])
+
+Call the HTTP::Headers->as_string() method for the headers in the
+message.
+
+=cut
+
+sub headers            { shift->{'_headers'};                }
+sub headers_as_string  { shift->{'_headers'}->as_string(@_); }
+
+=back
+
+All unknown C<HTTP::Message> methods are delegated to the
+C<HTTP::Headers> object that is part of every message.  This allows
+convenient access to these methods.  Refer to L<HTTP::Headers> for
+details of these methods:
+
+  $mess->header($field => $val);
+  $mess->scan(\&doit);
+  $mess->push_header($field => $val);
+  $mess->remove_header($field);
+
+  $mess->date;
+  $mess->expires;
+  $mess->if_modified_since;
+  $mess->if_unmodified_since;
+  $mess->last_modified;
+  $mess->content_type;
+  $mess->content_encoding;
+  $mess->content_length;
+  $mess->content_language
+  $mess->title;
+  $mess->user_agent;
+  $mess->server;
+  $mess->from;
+  $mess->referer;
+  $mess->www_authenticate;
+  $mess->authorization;
+  $mess->proxy_authorization;
+  $mess->authorization_basic;
+  $mess->proxy_authorization_basic;
+
+=cut
+
+
+# delegate all other method calls the the _headers object.
+sub AUTOLOAD
+{
+    my $self = shift;
+    my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::')+2);
+    return if $method eq "DESTROY";
+    $self->{'_headers'}->$method(@_);
+}
+
+# Private method to access members in %$self
+sub _elem
+{
+    my $self = shift;
+    my $elem = shift;
+    my $old = $self->{$elem};
+    $self->{$elem} = $_[0] if @_;
+    return $old;
+}
+
+1;
+
+=head1 COPYRIGHT
+
+Copyright 1995-1997 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Negotiate.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Negotiate.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Negotiate.pm	(revision 20131)
@@ -0,0 +1,505 @@
+# $Id$
+#
+
+package HTTP::Negotiate;
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+sub Version { $VERSION; }
+
+require 5.002;
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(choose);
+
+require HTTP::Headers;
+
+$DEBUG = 0;
+
+sub choose ($;$)
+{
+    my($variants, $request) = @_;
+    my(%accept);
+
+    unless (defined $request) {
+	# Create a request object from the CGI envirionment variables
+	$request = new HTTP::Headers;
+	$request->header('Accept', $ENV{HTTP_ACCEPT})
+	  if $ENV{HTTP_ACCEPT};
+	$request->header('Accept-Charset', $ENV{HTTP_ACCEPT_CHARSET})
+	  if $ENV{HTTP_ACCEPT_CHARSET};
+	$request->header('Accept-Encoding', $ENV{HTTP_ACCEPT_ENCODING})
+	  if $ENV{HTTP_ACCEPT_ENCODING};
+	$request->header('Accept-Language', $ENV{HTTP_ACCEPT_LANGUAGE})
+	  if $ENV{HTTP_ACCEPT_LANGUAGE};
+    }
+
+    # Get all Accept values from the request.  Build a hash initialized
+    # like this:
+    #
+    #   %accept = ( type =>     { 'audio/*'     => { q => 0.2, mbx => 20000 },
+    #                             'audio/basic' => { q => 1 },
+    #                           },
+    #               language => { 'no'          => { q => 1 },
+    #                           }
+    #             );
+
+    $request->scan(sub {
+	my($key, $val) = @_;
+	return unless $key =~ s/^Accept-?//;
+	my $type = lc $key;
+	$type = "type" unless length $key;
+	$val =~ s/\s+//g;
+	my $name;
+	for $name (split(/,/, $val)) {
+	    my(%param, $param);
+	    if ($name =~ s/;(.*)//) {
+		for $param (split(/;/, $1)) {
+		    my ($pk, $pv) = split(/=/, $param, 2);
+		    $param{$pk} = $pv;
+		}
+	    }
+	    $name = lc $name;
+	    if (defined $param{'q'}) {
+		$param{'q'} = 1 if $param{'q'} > 1;
+		$param{'q'} = 0 if $param{'q'} < 0;
+	    } else {
+		$param{'q'} = 1;
+	    }
+
+	    $param{'q'} = 1 unless defined $param{'q'};
+	    $accept{$type}{$name} = \%param;
+	}
+    });
+
+    # Check if any of the variants specify a language.  We do this
+    # because it influence how we treat those without (they default to
+    # 0.5 instead of 1).
+    my $any_lang = 0;
+    for $var (@$variants) {
+	if ($var->[5]) {
+	    $any_lang = 1;
+	    last;
+	}
+    }
+
+    if ($DEBUG) {
+	print "Netgotiantion parameters in the request\n";
+	for $type (keys %accept) {
+	    print " $type:\n";
+	    for $name (keys %{$accept{$type}}) {
+		print "    $name\n";
+		for $pv (keys %{$accept{$type}{$name}}) {
+		    print "      $pv = $accept{$type}{$name}{$pv}\n";
+		}
+	    }
+	}
+    }
+
+    my @Q = ();  # This is where we collect the results of the
+		 # quality calcualtions
+
+    # Calculate quality for all the variant's that are available.
+    for (@$variants) {
+	my($id, $qs, $ct, $enc, $cs, $lang, $bs) = @$_;
+	$qs = 1 unless defined $qs;
+	$bs = 0 unless defined $bs;
+	if ($DEBUG) {
+	    print "\nEvaluating $id ($ct)\n";
+	    printf "  qs   = %.3f\n", $qs;
+	    print  "  enc  = $enc\n"  if $enc && !ref($enc);
+	    print  "  enc  = @$enc\n" if $enc && ref($enc);
+	    print  "  cs   = $cs\n"   if $cs;
+	    print  "  lang = $lang\n" if $lang;
+	    print  "  bs   = $bs\n"   if $bs;
+	}
+
+	# Calculate encoding quality
+	my $qe = 1;
+	# If the variant has no assignes Content-Encoding, or if no
+	# Accept-Encoding field is present, then the value assigned
+	# is "qe=1".  If *all* of the variant's content encoddings
+	# are listed in the Accept-Encoding field, then the value
+	# assigned is "qw=1".  If *any* of the variant's content
+	# encodings are not listed in the provided Accept-Encoding
+	# field, then the value assigned is "qe=0"
+	if (exists $accept{'encoding'} && $enc) {
+	    my @enc = ref($enc) ? @$enc : ($enc);
+	    for (@enc) {
+		print "Is encoding $_ accepted? " if $DEBUG;
+		unless(exists $accept{'encoding'}{$_}) {
+		    print "no\n" if $DEBUG;
+		    $qe = 0;
+		    last;
+		} else {
+		    print "yes\n" if $DEBUG;
+		}
+	    }
+	}
+
+	# Calculate charset quality
+	my $qc  = 1;
+	# If the variant's media-type has not charset parameter,
+	# or the variant's charset is US-ASCII, or if no Accept-Charset
+	# field is present, then the value assigned is "qc=1".  If the
+	# variantæs charset is listed in the Accept-Charset field,
+	# then the value assigned is "qc=1.  Otherwise, if the variant's
+	# charset is not listed in the provided Accept-Encoding field,
+	# then the value assigned is "qc=0".
+	if (exists $accept{'charset'} && $cs && $cs ne 'us-ascii' ) {
+	    $qc = 0 unless $accept{'charset'}{$cs};
+	}
+
+	# Calculate language quality
+	my $ql  = 1;
+	if ($lang && exists $accept{'language'}) {
+	    my @lang = ref($lang) ? @$lang : ($lang);
+	    # If any of the variant's content languages are listed
+	    # in the Accept-Language field, the the value assigned is
+	    # the maximus of the "q" paramet values for thos language
+	    # tags.
+	    my $q = undef;
+	    for (@lang) {
+		next unless exists $accept{'language'}{$_};
+		my $this_q = $accept{'language'}{$_}{'q'};
+		$q = $this_q unless defined $q;
+		$q = $this_q if $this_q > $q;
+	    }
+	    unless (defined $q) {
+		# If there was no exact match and at least one of
+		# the Accept-Language field values is a complete
+		# subtag prefix of the content language tag(s), then
+		# the "q" parameter value of the largest matching
+		# prefix is used.
+		my $selected = undef;
+		for $al (keys %{ $accept{'language'} }) {
+		    if (substr($lang, 0, length($al)) eq $al) {
+			$selected = $al unless defined $selected;
+			$selected = $al if length($al) > length($selected);
+		    }
+		}
+		$q = $accept{'language'}{$selected}{'q'} if $selected;
+
+		# If none of the variant's content language tags or
+		# tag prefixes are listed in the provided
+		# Accept-Language field, then the value assigned
+		# is "ql=0.001"
+		$q = 0.001 unless defined $q;
+	    }
+	    $ql = $q;
+	} else {
+	    $ql = 0.5 if $any_lang && exists $accept{'language'};
+	}
+
+	my $q   = 1;
+	my $mbx = undef;
+	# If no Accept field is given, then the value assigned is "q=1".
+	# If at least one listed media range matches the variant's media
+	# type, then the "q" parameter value assigned to the most specific
+	# of those matched is used (e.g. "text/html;version=3.0" is more
+	# specific than "text/html", which is more specific than "text/*",
+	# which in turn is more specific than "*/*"). If not media range
+	# in the provided Accept field matches the variant's media type,
+	# then the value assigned is "q=0".
+	if (exists $accept{'type'} && $ct) {
+	    # First we clean up our content-type
+	    $ct =~ s/\s+//g;
+	    my $params = "";
+	    $params = $1 if $ct =~ s/;(.*)//;
+	    my($type, $subtype) = split("/", $ct, 2);
+	    my %param = ();
+	    for $param (split(/;/, $params)) {
+		my($pk,$pv) = split(/=/, $param, 2);
+		$param{$pk} = $pv;
+	    }
+
+	    my $sel_q = undef;
+	    my $sel_mbx = undef;
+	    my $sel_specificness = 0;
+
+	    ACCEPT_TYPE:
+	    for $at (keys %{ $accept{'type'} }) {
+		print "Consider $at...\n" if $DEBUG;
+		my($at_type, $at_subtype) = split("/", $at, 2);
+		# Is it a match on the type
+		next if $at_type    ne '*' && $at_type    ne $type;
+		next if $at_subtype ne '*' && $at_subtype ne $subtype;
+		my $specificness = 0;
+		$specificness++ if $at_type ne '*';
+		$specificness++ if $at_subtype ne '*';
+		# Let's see if content-type parameters also match
+		while (($pk, $pv) = each %param) {
+		    print "Check if $pk = $pv is true\n" if $DEBUG;
+		    next unless exists $accept{'type'}{$at}{$pk};
+		    next ACCEPT_TYPE
+		      unless $accept{'type'}{$at}{$pk} eq $pv;
+		    print "yes it is!!\n" if $DEBUG;
+		    $specificness++;
+		}
+		print "Hurray, type match with specificness = $specificness\n"
+		  if $DEBUG;
+
+		if (!defined($sel_q) || $sel_specificness < $specificness) {
+		    $sel_q   = $accept{'type'}{$at}{'q'};
+		    $sel_mbx = $accept{'type'}{$at}{'mbx'};
+		    $sel_specificness = $specificness;
+		}
+	    }
+	    $q   = $sel_q || 0;
+	    $mbx = $sel_mbx;
+	}
+
+	my $Q;
+	if (!defined($mbx) || $mbx >= $bs) {
+	    $Q = $qs * $qe * $qc * $ql * $q;
+	} else {
+	    $Q = 0;
+	    print "Variant's size is too large ==> Q=0\n" if $DEBUG;
+	}
+
+	if ($DEBUG) {
+	    $mbx = "undef" unless defined $mbx;
+	    printf "Q=%.3f", $Q;
+	    print "  (q=$q, mbx=$mbx, qe=$qe, qc=$qc, ql=$ql, qs=$qs)\n";
+	}
+
+	push(@Q, [$id, $Q, $bs]);
+    }
+
+
+    @Q = sort { $b->[1] <=> $a->[1] || $a->[2] <=> $b->[2] } @Q;
+
+    return @Q if wantarray;
+    return undef unless @Q;
+    return undef if $Q[0][1] == 0;
+    $Q[0][0];
+}
+
+1;
+
+__END__
+
+
+=head1 NAME
+
+choose - choose a variant of a document to serve (HTTP content negotiation)
+
+=head1 SYNOPSIS
+
+ use HTTP::Negotiate;
+
+ #  ID       QS     Content-Type   Encoding Char-Set        Lang   Size
+ $variants =
+  [['var1',  1.000, 'text/html',   undef,   'iso-8859-1',   'en',   3000],
+   ['var2',  0.950, 'text/plain',  'gzip',  'us-ascii',     'no',    400],
+   ['var3',  0.3,   'image/gif',   undef,   undef,          undef, 43555],
+  ];
+
+ @prefered = choose($variants, $request_headers);
+ $the_one  = choose($variants);
+
+=head1 DESCRIPTION
+
+This module provide a complete implementation of the HTTP content
+negotiation algorithm specified in F<draft-ietf-http-v11-spec-00.ps>
+chapter 12.  Content negotiation allows for the selection of a
+preferred content representation based upon attributes of the
+negotiable variants and the value of the various Accept* header fields
+in the request.
+
+The variants are ordered by preference by calling the function
+choose().
+
+The first parameter is a description of the variants that we can
+choose among.  The variants are described by a reference to an array.
+Each element in this array is an array with the values [$id, $qs,
+$content_type, $content_encoding, $charset, $content_language,
+$content_length].  The meaning of these values are described
+below. The $content_encoding and $content_language can be either a
+single scalar value or an array reference if there are several values.
+
+The second optional parameter is a reference to the request headers.
+This is used to look for "Accept*" headers.  You can pass a reference
+to either a HTTP::Request or a HTTP::Headers object.  If this
+parameter is missing, then the accept specification is initialized
+from the CGI environment variables HTTP_ACCEPT, HTTP_ACCEPT_CHARSET,
+HTTP_ACCEPT_ENCODING and HTTP_ACCEPT_LANGUAGE.
+
+In array context, choose() returns a list of variant
+identifier/calculated quality pairs.  The values are sorted by
+quality, highest quality first.  If the calculated quality is the same
+for two variants, then they are sorted by size (smallest first). I<E.g.>:
+
+  (['var1' => 1], ['var2', 0.3], ['var3' => 0]);
+
+Note that also zero quality variants are included in the return list
+even if these should never be served to the client.
+
+In scalar context, it returns the identifier of the variant with the
+highest score or C<undef> if none have non-zero quality.
+
+If the $HTTP::Negotiate::DEBUG variable is set to TRUE, then a lot of
+noise is generated on STDOUT during evaluation of choose().
+
+=head1 VARIANTS
+
+A variant is described by a list of the following values.  If the
+attribute does not make sense or is unknown for a variant, then use
+C<undef> instead.
+
+=over 3
+
+=item identifier
+
+This is just some string that you use as a name for the variant.  The
+identifier of the preferred variant is returned by choose().
+
+=item qs
+
+This is a number between 0.000 and 1.000 that describes the "source
+quality".  This is what F<draft-ietf-http-v11-spec-00.ps> says about this
+value:
+
+Source quality is measured by the content provider as representing the
+amount of degradation from the original source.  For example, a
+picture in JPEG form would have a lower qs when translated to the XBM
+format, and much lower qs when translated to an ASCII-art
+representation.  Note, however, that this is a function of the source
+- an original piece of ASCII-art may degrade in quality if it is
+captured in JPEG form.  The qs values should be assigned to each
+variant by the content provider; if no qs value has been assigned, the
+default is generally "qs=1".
+
+=item content-type
+
+This is the media type of the variant.  The media type does not
+include a charset attribute, but might contain other parameters.
+Examples are:
+
+  text/html
+  text/html;version=2.0
+  text/plain
+  image/gif
+  image/jpg
+
+=item content-encoding
+
+This is one or more content encodings that has been applied to the
+variant.  The content encoding is generally used as a modifier to the
+content media type.  The most common content encodings are:
+
+  gzip
+  compress
+
+=item content-charset
+
+This is the character set used when the variant contains textual
+content.  The charset value should generally be C<undef> or one of these:
+
+  us-ascii
+  iso-8859-1 ... iso-8859-9
+  iso-2022-jp
+  iso-2022-jp-2
+  iso-2022-kr
+  unicode-1-1
+  unicode-1-1-utf-7
+  unicode-1-1-utf-8
+
+=item content-language
+
+This describes one or more languages that are used in the variant.
+Language is described like this in F<draft-ietf-http-v11-spec-00.ps>: A
+language is in this context a natural language spoken, written, or
+otherwise conveyed by human beings for communication of information to
+other human beings.  Computer languages are explicitly excluded.
+
+The language tags are the same as those defined by RFC-1766.  Examples
+are:
+
+  no               Norwegian
+  en               International English
+  en-US            US English
+  en-cockney
+
+=item content-length
+
+This is the number of bytes used to represent the content.
+
+=back
+
+=head1 ACCEPT HEADERS
+
+The following Accept* headers can be used for describing content
+preferences in a request (This description is an edited extract from
+F<draft-ietf-http-v11-spec-00.ps>):
+
+=over 3
+
+=item Accept
+
+This header can be used to indicate a list of media ranges which are
+acceptable as a reponse to the request.  The "*" character is used to
+group media types into ranges, with "*/*" indicating all media types
+and "type/*" indicating all subtypes of that type.
+
+The parameter q is used to indicate the quality factor, which
+represents the user's preference for that range of media types.  The
+parameter mbx gives the maximum acceptable size of the response
+content. The default values are: q=1 and mbx=infinity. If no Accept
+header is present, then the client accepts all media types with q=1.
+
+For example:
+
+  Accept: audio/*;q=0.2;mbx=200000, audio/basic
+
+would mean: "I prefer audio/basic (of any size), but send me any audio
+type if it is the best available after an 80% mark-down in quality and
+its size is less than 200000 bytes"
+
+
+=item Accept-Charset
+
+Used to indicate what character sets are acceptable for the response.
+The "us-ascii" character set is assumed to be acceptable for all user
+agents.  If no Accept-Charset field is given, the default is that any
+charset is acceptable.  Example:
+
+  Accept-Charset: iso-8859-1, unicode-1-1
+
+
+=item Accept-Encoding
+
+Restricts the Content-Encoding values which are acceptable in the
+response.  If no Accept-Encoding field is present, the server may
+assume that the client will accept any content encoding.  An empty
+Accept-Encoding means that no content encoding is acceptable.  Example:
+
+  Accept-Encoding: compress, gzip
+
+
+=item Accept-Language
+
+This field is similar to Accept, but restrict the set of natural
+languages that are preferred as a response.  Each language may be
+given an associated quality value which represents an estimate of the
+user's comprehension of that language.  For example:
+
+  Accept-Language: no, en-gb;q=0.8, de;q=0.55
+
+would mean: "I prefer Norwegian, but will accept British English (with
+80% comprehension) or German (with 55% comprehension).
+
+=back
+
+
+=head1 COPYRIGHT
+
+Copyright 1996, Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 AUTHOR
+
+Gisle Aas <aas@sn.no>
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Request.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Request.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Request.pm	(revision 20131)
@@ -0,0 +1,160 @@
+#
+# $Id$
+
+package HTTP::Request;
+
+=head1 NAME
+
+HTTP::Request - Class encapsulating HTTP Requests
+
+=head1 SYNOPSIS
+
+ require HTTP::Request;
+ $request = HTTP::Request->new(GET => 'http://www.oslonett.no/');
+
+=head1 DESCRIPTION
+
+C<HTTP::Request> is a class encapsulating HTTP style requests,
+consisting of a request line, some headers, and some (potentially empty)
+content. Note that the LWP library also uses this HTTP style requests
+for non-HTTP protocols.
+
+Instances of this class are usually passed to the C<request()> method
+of an C<LWP::UserAgent> object:
+
+ $ua = LWP::UserAgent->new;
+ $request = HTTP::Request->new(GET => 'http://www.oslonett.no/');
+ $response = $ua->request($request);
+
+C<HTTP::Request> is a subclass of C<HTTP::Message> and therefore
+inherits its methods.  The inherited methods often used are header(),
+push_header(), remove_header(), headers_as_string() and content().
+See L<HTTP::Message> for details.
+
+The following additional methods are available:
+
+=over 4
+
+=cut
+
+require HTTP::Message;
+@ISA = qw(HTTP::Message);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+use URI::URL ();
+use strict;
+
+=item $r = HTTP::Request->new($method, $url, [$header, [$content]])
+
+Constructs a new C<HTTP::Request> object describing a request on the
+object C<$url> using method C<$method>.  The C<$url> argument can be
+either a string, or a reference to a C<URI::URL> object.  The $header
+argument should be a reference to an C<HTTP::Headers> object.
+
+=cut
+
+sub new
+{
+    my($class, $method, $url, $header, $content) = @_;
+    my $self = $class->SUPER::new($header, $content);
+    $self->method($method);
+    $self->url($url);
+    $self;
+}
+
+
+sub clone
+{
+    my $self = shift;
+    my $clone = bless $self->SUPER::clone, ref($self);
+    $clone->method($self->method);
+    $clone->url($self->url);
+    $clone;
+}
+
+
+=item $r->method([$val])
+
+=item $r->url([$val])
+
+These methods provide public access to the member variables containing
+respectively the method of the request and the URL object of the
+request.
+
+If an argument is given the member variable is given that as its new
+value. If no argument is given the value is not touched. In either
+case the previous value is returned.
+
+The url() method accept both a reference to a URI::URL object and a
+string as its argument.  If a string is given, then it should be
+parseable as an absolute URL.
+
+=cut
+
+sub method  { shift->_elem('_method', @_); }
+
+sub url
+{
+    my $self = shift;
+    my $old = $self->{'_url'};
+    if (@_) {
+	my $url = shift;
+	if (!defined $url) {
+	    # that's ok
+	} elsif (ref $url) {
+	    $url = $url->abs;
+	} else {
+	    $url = eval { URI::URL->new($url) };
+	}
+	$self->{'_url'} = $url;
+    }
+    $old;
+}
+
+*uri = \&url;  # this is the same for now
+
+=item $r->as_string()
+
+Method returning a textual representation of the request.
+Mainly useful for debugging purposes. It takes no arguments.
+
+=cut
+
+sub as_string
+{
+    my $self = shift;
+    my @result;
+    #push(@result, "---- $self -----");
+    my $req_line = $self->method || "[NO METHOD]";
+    my $url = $self->url;
+    $url = (defined $url) ? $url->as_string : "[NO URL]";
+    $req_line .= " $url";
+    my $proto = $self->protocol;
+    $req_line .= " $proto" if $proto;
+
+    push(@result, $req_line);
+    push(@result, $self->headers_as_string);
+    my $content = $self->content;
+    if (defined $content) {
+	push(@result, $content);
+    }
+    #push(@result, ("-" x 40));
+    join("\n", @result, "");
+}
+
+1;
+
+=back
+
+=head1 SEE ALSO
+
+L<HTTP::Headers>, L<HTTP::Message>, L<HTTP::Request::Common>
+
+=head1 COPYRIGHT
+
+Copyright 1995-1998 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Request/Common.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Request/Common.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Request/Common.pm	(revision 20131)
@@ -0,0 +1,389 @@
+# $Id$
+#
+package HTTP::Request::Common;
+
+use strict;
+use vars qw(@EXPORT @EXPORT_OK $VERSION $DYNAMIC_FILE_UPLOAD);
+
+$DYNAMIC_FILE_UPLOAD ||= 0;  # make it defined (don't know why)
+
+require Exporter;
+*import = \&Exporter::import;
+@EXPORT =qw(GET HEAD PUT POST);
+@EXPORT_OK = qw($DYNAMIC_FILE_UPLOAD);
+
+require HTTP::Request;
+use Carp();
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+my $CRLF = "\015\012";   # "\r\n" is not portable
+
+sub GET  { _simple_req('GET',  @_); }
+sub HEAD { _simple_req('HEAD', @_); }
+sub PUT  { _simple_req('PUT' , @_); }
+
+sub POST
+{
+    my $url = shift;
+    my $req = HTTP::Request->new(POST => $url);
+    my $content;
+    $content = shift if @_ and ref $_[0];
+    my($k, $v);
+    while (($k,$v) = splice(@_, 0, 2)) {
+	if (lc($k) eq 'content') {
+	    $content = $v;
+	} else {
+	    $req->push_header($k, $v);
+	}
+    }
+    my $ct = $req->header('Content-Type');
+    unless ($ct) {
+	$ct = 'application/x-www-form-urlencoded';
+    } elsif ($ct eq 'form-data') {
+	$ct = 'multipart/form-data';
+    }
+
+    if (ref $content) {
+	if (lc($ct) eq 'multipart/form-data') {    #XXX: boundary="..."
+	    my $boundary;
+	    ($content, $boundary) = form_data($content, $boundary);
+	    $boundary = qq("$boundary") if $boundary =~ /\W/;
+	    $ct = qq(multipart/form-data; boundary=$boundary);
+	} else {
+	    # We use a temporary URI::URL object to format
+	    # the application/x-www-form-urlencoded content.
+	    require URI::URL;
+	    my $url = URI::URL->new('http:');
+	    $url->query_form(ref($content) eq "HASH" ? %$content : @$content);
+	    $content = $url->equery;
+	}
+    }
+
+    $req->header('Content-Type' => $ct);  # might be redundant
+    if (defined($content)) {
+	$req->header('Content-Length' =>
+		     length($content)) unless ref($content);
+	$req->content($content);
+    }
+    $req;
+}
+
+
+sub _simple_req
+{
+    my($method, $url) = splice(@_, 0, 2);
+    my $req = HTTP::Request->new($method => $url);
+    my($k, $v);
+    while (($k,$v) = splice(@_, 0, 2)) {
+	if (lc($k) eq 'content') {
+	    $req->add_content($v);
+	} else {
+	    $req->push_header($k, $v);
+	}
+    }
+    $req;
+}
+
+
+sub form_data   # RFC1867
+{
+    my($data, $boundary) = @_;
+    my @data = ref($data) eq "HASH" ? %$data : @$data;  # copy
+    my $fhparts;
+    my @parts;
+    my($k,$v);
+    while (($k,$v) = splice(@data, 0, 2)) {
+	if (!ref($v)) {
+	    $k =~ s/([\\\"])/\\$1/g;  # escape quotes and backslashes
+	    push(@parts,
+		 qq(Content-Disposition: form-data; name="$k"$CRLF$CRLF$v));
+	} else {
+	    my($file, $usename, @headers) = @$v;
+	    unless (defined $usename) {
+		$usename = $file;
+		$usename =~ s,.*/,, if defined($usename);
+	    }
+	    my $disp = qq(form-data; name="$k");
+	    $disp .= qq(; filename="$usename") if $usename;
+	    my $content = "";
+	    my $h = HTTP::Headers->new(@headers);
+	    my $ct = $h->header("Content-Type");
+	    if ($file) {
+		require Symbol;
+		my $fh = Symbol::gensym();
+		open($fh, $file) or Carp::croak("Can't open file $file: $!");
+		binmode($fh);
+		if ($DYNAMIC_FILE_UPLOAD) {
+		    # will read file later
+		    $content = $fh;
+		} else {
+		    local($/) = undef; # slurp files
+		    $content = <$fh>;
+		    close($fh);
+		    $h->header("Content-Length" => length($content));
+		}
+		unless ($ct) {
+		    require LWP::MediaTypes;
+		    $ct = LWP::MediaTypes::guess_media_type($file, $h);
+		}
+	    }
+	    if ($h->header("Content-Disposition")) {
+		# just to get it sorted first
+		$disp = $h->header("Content-Disposition");
+		$h->remove_header("Content-Disposition");
+	    }
+	    if ($h->header("Content")) {
+		$content = $h->header("Content");
+		$h->remove_header("Content");
+	    }
+	    my $head = join($CRLF, "Content-Disposition: $disp",
+			           $h->as_string($CRLF),
+			           "");
+	    if (ref $content) {
+		push(@parts, [$head, $content]);
+		$fhparts++;
+	    } else {
+		push(@parts, $head . $content);
+	    }
+	}
+    }
+    return "" unless @parts;
+
+    my $content;
+    if ($fhparts) {
+	$boundary = boundary(10) # hopefully enough randomness
+	    unless $boundary;
+
+	# add the boundaries to the @parts array
+	for (1..@parts-1) {
+	    splice(@parts, $_*2-1, 0, "$CRLF--$boundary$CRLF");
+	}
+	unshift(@parts, "--$boundary$CRLF");
+	push(@parts, "$CRLF--$boundary--$CRLF");
+
+	# set up a closure that will return content piecemeal
+	$content = sub {
+	    for (;;) {
+		return unless @parts;
+		my $p = shift @parts;
+		unless (ref $p) {
+		    $p .= shift @parts while @parts && !ref($parts[0]);
+		    return $p;
+		}
+		my($buf, $fh) = @$p;
+		my $n = read($fh, $buf, 2048, length($buf));
+		if ($n) {
+		    unshift(@parts, ["", $fh]);
+		} else {
+		    close($fh);
+		}
+		return $buf if length $buf;
+	    }
+	};
+
+    } else {
+	$boundary = boundary() unless $boundary;
+
+	my $bno = 0;
+      CHECK_BOUNDARY:
+	{
+	    for (@parts) {
+		if (index($_, "--$boundary") >= 0) {
+		    # must have a better boundary
+		    #warn "Need something better that '$boundary' as boundary\n";
+		    $boundary = boundary(++$bno);
+		    redo CHECK_BOUNDARY;
+		}
+	    }
+	    last;
+	}
+	$content = "--$boundary$CRLF" .
+	           join("$CRLF--$boundary$CRLF", @parts) .
+		   "$CRLF--$boundary--$CRLF";
+    }
+
+    wantarray ? ($content, $boundary) : $content;
+}
+
+
+sub boundary
+{
+    my $size = shift || return "000";
+    require MIME::Base64;
+    my $b = MIME::Base64::encode(join("", map chr(rand(256)), 1..$size*3), "");
+    $b =~ s/[\W]/X/g;  # ensure alnum only
+    $b;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+HTTP::Request::Common - Construct common HTTP::Request objects
+
+=head1 SYNOPSIS
+
+  use HTTP::Request::Common;
+  $ua = LWP::UserAgent->new;
+  $ua->request(GET 'http://www.sn.no/');
+  $ua->request(POST 'http://somewhere/foo', [foo => bar, bar => foo]);
+
+=head1 DESCRIPTION
+
+This module provide functions that return newly created HTTP::Request
+objects.  These functions are usually more convenient to use than the
+standard HTTP::Request constructor for these common requests.  The
+following functions are provided.
+
+=over 4
+
+=item GET $url, Header => Value,...
+
+The GET() function returns a HTTP::Request object initialized with the
+GET method and the specified URL.  Without additional arguments it
+is exactly equivalent to the following call
+
+  HTTP::Request->new(GET => $url)
+
+but is less clutter.  It also reads better when used together with the
+LWP::UserAgent->request() method:
+
+  my $ua = new LWP::UserAgent;
+  my $res = $ua->request(GET 'http://www.sn.no')
+  if ($res->is_success) { ...
+
+You can also initialize the header values in the request by specifying
+some key/value pairs as optional arguments.  For instance:
+
+  $ua->request(GET 'http://www.sn.no',
+	           If_Match => 'foo',
+                   From     => 'gisle@aas.no',
+              );
+
+A header key called 'Content' is special and when seen the value will
+initialize the content part of the request instead of setting a header.
+
+=item HEAD $url, [Header => Value,...]
+
+Like GET() but the method in the request is HEAD.
+
+=item PUT $url, [Header => Value,...]
+
+Like GET() but the method in the request is PUT.
+
+=item POST $url, [$form_ref], [Header => Value,...]
+
+This works mostly like GET() with POST as method, but this function
+also takes a second optional array or hash reference parameter
+($form_ref).  This argument can be used to pass key/value pairs for
+the form content.  By default we will initialize a request using the
+C<application/x-www-form-urlencoded> content type.  This means that
+you can emulate a HTML E<lt>form> POSTing like this:
+
+  POST 'http://www.perl.org/survey.cgi',
+       [ name   => 'Gisle Aas',
+         email  => 'gisle@aas.no',
+         gender => 'M',
+         born   => '1964',
+         perc   => '3%',
+       ];
+
+This will create a HTTP::Request object that looks like this:
+
+  POST http://www.perl.org/survey.cgi
+  Content-Length: 66
+  Content-Type: application/x-www-form-urlencoded
+
+  name=Gisle%20Aas&email=gisle%40aas.no&gender=M&born=1964&perc=3%25
+
+The POST method also supports the C<multipart/form-data> content used
+for I<Form-based File Upload> as specified in RFC 1867.  You trigger
+this content format by specifying a content type of C<'form-data'> as
+one of the request headers.  If one of the values in the $form_ref is
+an array reference, then it is treated as a file part specification
+with the following interpretation:
+
+  [ $file, $filename, Header => Value... ]
+
+The first value in the array ($file) is the name of a file to open.
+This file will be read an its content placed in the request.  The
+routine will croak if the file can't be opened.  Use an C<undef> as $file
+value if you want to specify the content directly.  The $filename is
+the filename to report in the request.  If this value is undefined,
+then the basename of the $file will be used.  You can specify an empty
+string as $filename if you don't want any filename in the request.
+
+Sending my F<~/.profile> to the survey used as example above can be
+achieved by this:
+
+  POST 'http://www.perl.org/survey.cgi',
+       Content_Type => 'form-data',
+       Content      => [ name  => 'Gisle Aas',
+                         email => 'gisle@aas.no',
+                         gender => 'M',
+                         born   => '1964',
+                         init   => ["$ENV{HOME}/.profile"],
+                       ]
+
+This will create a HTTP::Request object that almost looks this (the
+boundary and the content of your F<~/.profile> is likely to be
+different):
+
+  POST http://www.perl.org/survey.cgi
+  Content-Length: 388
+  Content-Type: multipart/form-data; boundary="6G+f"
+
+  --6G+f
+  Content-Disposition: form-data; name="name"
+  
+  Gisle Aas
+  --6G+f
+  Content-Disposition: form-data; name="email"
+  
+  gisle@aas.no
+  --6G+f
+  Content-Disposition: form-data; name="gender"
+  
+  M
+  --6G+f
+  Content-Disposition: form-data; name="born"
+  
+  1964
+  --6G+f
+  Content-Disposition: form-data; name="init"; filename=".profile"
+  Content-Type: text/plain
+  
+  PATH=/local/perl/bin:$PATH
+  export PATH
+
+  --6G+f--
+
+If you set the $DYNAMIC_FILE_UPLOAD variable (exportable) to some TRUE
+value, then you get back a request object with a subroutine closure as
+the content attribute.  This subroutine will read the content of any
+files on demand and return it in suitable chunks.  This allow you to
+upload arbitrary big files without using lots of memory.  You can even
+upload infinite files like F</dev/audio> if you wish.  Another
+difference is that there will be no Content-Length header defined for
+the request if you use this feature.  Not all servers (or server
+applications) like this.
+
+=back
+
+=head1 SEE ALSO
+
+L<HTTP::Request>, L<LWP::UserAgent>
+
+
+=head1 COPYRIGHT
+
+Copyright 1997-1998, Gisle Aas
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Response.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Response.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Response.pm	(revision 20131)
@@ -0,0 +1,396 @@
+#
+# $Id$
+
+package HTTP::Response;
+
+
+=head1 NAME
+
+HTTP::Response - Class encapsulating HTTP Responses
+
+=head1 SYNOPSIS
+
+ require HTTP::Response;
+
+=head1 DESCRIPTION
+
+The C<HTTP::Response> class encapsulate HTTP style responses.  A
+response consist of a response line, some headers, and a (potential
+empty) content. Note that the LWP library will use HTTP style
+responses also for non-HTTP protocol schemes.
+
+Instances of this class are usually created and returned by the
+C<request()> method of an C<LWP::UserAgent> object:
+
+ #...
+ $response = $ua->request($request)
+ if ($response->is_success) {
+     print $response->content;
+ } else {
+     print $response->error_as_HTML;
+ }
+
+C<HTTP::Response> is a subclass of C<HTTP::Message> and therefore
+inherits its methods.  The inherited methods often used are header(),
+push_header(), remove_header(), headers_as_string(), and content().
+The header convenience methods are also available.  See
+L<HTTP::Message> for details.
+
+The following additional methods are available:
+
+=over 4
+
+=cut
+
+
+require HTTP::Message;
+@ISA = qw(HTTP::Message);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+use HTTP::Status ();
+use URI::URL ();
+use strict;
+
+
+=item $r = HTTP::Response->new($rc, [$msg, [$header, [$content]]])
+
+Constructs a new C<HTTP::Response> object describing a response with
+response code C<$rc> and optional message C<$msg>.  The message is a
+short human readable single line string that explains the response
+code.
+
+=cut
+
+sub new
+{
+    my($class, $rc, $msg, $header, $content) = @_;
+    my $self = $class->SUPER::new($header, $content);
+    $self->code($rc);
+    $self->message($msg);
+    $self;
+}
+
+
+sub clone
+{
+    my $self = shift;
+    my $clone = bless $self->SUPER::clone, ref($self);
+    $clone->code($self->code);
+    $clone->message($self->message);
+    $clone->request($self->request->clone) if $self->request;
+    # we don't clone previous
+    $clone;
+}
+
+=item $r->code([$code])
+
+=item $r->message([$message])
+
+=item $r->request([$request])
+
+=item $r->previous([$previousResponse])
+
+These methods provide public access to the member variables.  The
+first two containing respectively the response code and the message
+of the response.
+
+The request attribute is a reference the request that gave this
+response.  It does not have to be the same request as passed to the
+$ua->request() method, because there might have been redirects and
+authorization retries in between.
+
+The previous attribute is used to link together chains of responses.
+You get chains of responses if the first response is redirect or
+unauthorized.
+
+=cut
+
+sub code      { shift->_elem('_rc',      @_); }
+sub message   { shift->_elem('_msg',     @_); }
+sub previous  { shift->_elem('_previous',@_); }
+sub request   { shift->_elem('_request', @_); }
+
+=item $r->status_line
+
+Returns the string "E<lt>code> E<lt>message>".  If the message attribute
+is not set then the official name of E<lt>code> (see L<HTTP::Status>)
+is substituted.
+
+=cut
+
+sub status_line
+{
+    my $self = shift;
+    my $code = $self->{'_rc'}  || "000";
+    my $mess = $self->{'_msg'} || HTTP::Status::status_message($code) || "?";
+    return "$code $mess";
+}
+
+=item $r->base
+
+Returns the base URL for this response.  The return value will be a
+reference to a URI::URL object.
+
+The base URL is obtained from one the following sources (in priority
+order):
+
+=over 4
+
+=item 1.
+
+Embedded in the document content, for instance <BASE HREF="...">
+in HTML documents.
+
+=item 2.
+
+A "Content-Base:" or a "Content-Location:" header in the response.
+
+For backwards compatability with older HTTP implementations we will
+also look for the "Base:" header.
+
+
+=item 3.
+
+The URL used to request this response. This might not be the original
+URL that was passed to $ua->request() method, because we might have
+received some redirect responses first.
+
+=back
+
+When the LWP protocol modules produce the HTTP::Response object, then
+any base URL embedded in the document (step 1) will already have
+initialized the "Content-Base:" header. This means that this method
+only perform the last 2 steps (the content is not always available
+either).
+
+=cut
+
+sub base
+{
+    my $self = shift;
+    my $base = $self->header('Content-Base')     ||  # HTTP/1.1
+               $self->header('Content-Location') ||  # HTTP/1.1
+               $self->header('Base')             ||  # backwards compatability HTTP/1.0
+               $self->request->url;
+    $base = URI::URL->new($base) unless ref $base;
+    $base;
+}
+
+
+=item $r->as_string
+
+Method returning a textual representation of the response.  Mainly
+useful for debugging purposes. It takes no arguments.
+
+=cut
+
+sub as_string
+{
+    require HTTP::Status;
+    my $self = shift;
+    my @result;
+    #push(@result, "---- $self ----");
+    my $code = $self->code;
+    my $status_message = HTTP::Status::status_message($code) || "Unknown code";
+    my $message = $self->message || "";
+
+    my $status_line = "$code";
+    my $proto = $self->protocol;
+    $status_line = "$proto $status_line" if $proto;
+    $status_line .= " ($status_message)" if $status_message ne $message;
+    $status_line .= " $message";
+    push(@result, $status_line);
+    push(@result, $self->headers_as_string);
+    my $content = $self->content;
+    if (defined $content) {
+	push(@result, $content);
+    }
+    #push(@result, ("-" x 40));
+    join("\n", @result, "");
+}
+
+=item $r->is_info
+
+=item $r->is_success
+
+=item $r->is_redirect
+
+=item $r->is_error
+
+These methods indicate if the response was informational, sucessful, a
+redirection, or an error.
+
+=cut
+
+sub is_info     { HTTP::Status::is_info     (shift->{'_rc'}); }
+sub is_success  { HTTP::Status::is_success  (shift->{'_rc'}); }
+sub is_redirect { HTTP::Status::is_redirect (shift->{'_rc'}); }
+sub is_error    { HTTP::Status::is_error    (shift->{'_rc'}); }
+
+
+=item $r->error_as_HTML()
+
+Return a string containing a complete HTML document indicating what
+error occurred.  This method should only be called when $r->is_error
+is TRUE.
+
+=cut
+
+sub error_as_HTML
+{
+    my $self = shift;
+    my $title = 'An Error Occurred';
+    my $body  = $self->status_line;
+    return <<EOM;
+<HTML>
+<HEAD><TITLE>$title</TITLE></HEAD>
+<BODY>
+<H1>$title</h1>
+$body
+</BODY>
+</HTML>
+EOM
+}
+
+
+=item $r->current_age
+
+This function will calculate the "current age" of the response as
+specified by E<lt>draft-ietf-http-v11-spec-07> section 13.2.3.  The
+age of a response is the time since it was sent by the origin server.
+The returned value is a number representing the age in seconds.
+
+=cut
+
+sub current_age
+{
+    my $self = shift;
+    # Implementation of <draft-ietf-http-v11-spec-07> section 13.2.3
+    # (age calculations)
+    my $response_time = $self->client_date;
+    my $date = $self->date;
+
+    my $age = 0;
+    if ($response_time && $date) {
+	$age = $response_time - $date;  # apparent_age
+	$age = 0 if $age < 0;
+    }
+
+    my $age_v = $self->header('Age');
+    if ($age_v && $age_v > $age) {
+	$age = $age_v;   # corrected_received_age
+    }
+
+    my $request = $self->request;
+    if ($request) {
+	my $request_time = $request->date;
+	if ($request_time) {
+	    # Add response_delay to age to get 'corrected_initial_age'
+	    $age += $response_time - $request_time;
+	}
+    }
+    if ($response_time) {
+	$age += time - $response_time;
+    }
+    return $age;
+}
+
+
+=item $r->freshness_lifetime
+
+This function will calculate the "freshness lifetime" of the response
+as specified by E<lt>draft-ietf-http-v11-spec-07> section 13.2.4.  The
+"freshness lifetime" is the length of time between the generation of a
+response and its expiration time.  The returned value is a number
+representing the freshness lifetime in seconds.
+
+If the response does not contain an "Expires" or a "Cache-Control"
+header, then this function will apply some simple heuristic based on
+'Last-Modified' to determine a suitable lifetime.
+
+=cut
+
+sub freshness_lifetime
+{
+    my $self = shift;
+
+    # First look for the Cache-Control: max-age=n header
+    my @cc = $self->header('Cache-Control');
+    if (@cc) {
+	my $cc;
+	for $cc (@cc) {
+	    my $cc_dir;
+	    for $cc_dir (split(/\s*,\s*/, $cc)) {
+		if ($cc_dir =~ /max-age\s*=\s*(\d+)/i) {
+		    return $1;
+		}
+	    }
+	}
+    }
+
+    # Next possibility is to look at the "Expires" header
+    my $date = $self->date || $self->client_date || time;      
+    my $expires = $self->expires;
+    unless ($expires) {
+	# Must apply heuristic expiration
+	my $last_modified = $self->last_modified;
+	if ($last_modified) {
+	    my $h_exp = ($date - $last_modified) * 0.10;  # 10% since last-mod
+	    if ($h_exp < 60) {
+		return 60;  # minimum
+	    } elsif ($h_exp > 24 * 3600) {
+		# Should give a warning if more than 24 hours according to
+		# <draft-ietf-http-v11-spec-07> section 13.2.4, but I don't
+		# know how to do it from this function interface, so I just
+		# make this the maximum value.
+		return 24 * 3600;
+	    }
+	    return $h_exp;
+	} else {
+	    return 3600;  # 1 hour is fallback when all else fails
+	}
+    }
+    return $expires - $date;
+}
+
+
+=item $r->is_fresh
+
+Returns TRUE if the response is fresh, based on the values of
+freshness_lifetime() and current_age().  If the response is not longer
+fresh, then it has to be refetched or revalidated by the origin
+server.
+
+=cut
+
+sub is_fresh
+{
+    my $self = shift;
+    $self->freshness_lifetime > $self->current_age;
+}
+
+
+=item $r->fresh_until
+
+Returns the time when this entiy is no longer fresh.
+
+=cut
+
+sub fresh_until
+{
+    my $self = shift;
+    return $self->freshness_lifetime - $self->current_age + time;
+}
+
+1;
+
+=back 
+
+=head1 COPYRIGHT
+
+Copyright 1995-1997 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Status.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Status.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/HTTP/Status.pm	(revision 20131)
@@ -0,0 +1,233 @@
+#
+# $Id$
+
+package HTTP::Status;
+
+use strict;
+require 5.002;   # becase we use prototypes
+
+=head1 NAME
+
+HTTP::Status - HTTP Status code processing
+
+=head1 SYNOPSIS
+
+ use HTTP::Status;
+
+ if ($rc != RC_OK) {
+     print status_message($rc), "\n";
+ }
+
+ if (is_success($rc)) { ... }
+ if (is_error($rc)) { ... }
+ if (is_redirect($rc)) { ... }
+
+=head1 DESCRIPTION
+
+I<HTTP::Status> is a library of routines for defining and
+classification of HTTP status codes for libwww-perl.  Status codes are
+used to encode the overall outcome of a HTTP response message.  Codes
+correspond to those defined in F<draft-ietf-http-v11-spec-rev-03> (an
+update to RFC 2068).
+
+=head1 CONSTANTS
+
+The following constant functions can be used as mnemonic status code
+names:
+
+   RC_CONTINUE				(100)
+   RC_SWITCHING_PROTOCOLS		(101)
+
+   RC_OK				(200)
+   RC_CREATED				(201)
+   RC_ACCEPTED				(202)
+   RC_NON_AUTHORITATIVE_INFORMATION	(203)
+   RC_NO_CONTENT			(204)
+   RC_RESET_CONTENT			(205)
+   RC_PARTIAL_CONTENT			(206)
+
+   RC_MULTIPLE_CHOICES			(300)
+   RC_MOVED_PERMANENTLY			(301)
+   RC_FOUND				(302)
+   RC_SEE_OTHER				(303)
+   RC_NOT_MODIFIED			(304)
+   RC_USE_PROXY				(305)
+   RC_TEMPORARY_REDIRECT		(307)
+
+   RC_BAD_REQUEST			(400)
+   RC_UNAUTHORIZED			(401)
+   RC_PAYMENT_REQUIRED			(402)
+   RC_FORBIDDEN				(403)
+   RC_NOT_FOUND				(404)
+   RC_METHOD_NOT_ALLOWED		(405)
+   RC_NOT_ACCEPTABLE			(406)
+   RC_PROXY_AUTHENTICATION_REQUIRED	(407)
+   RC_REQUEST_TIMEOUT			(408)
+   RC_CONFLICT				(409)
+   RC_GONE				(410)
+   RC_LENGTH_REQUIRED			(411)
+   RC_PRECONDITION_FAILED		(412)
+   RC_REQUEST_ENTITY_TOO_LARGE		(413)
+   RC_REQUEST_URI_TOO_LARGE		(414)
+   RC_UNSUPPORTED_MEDIA_TYPE		(415)
+   RC_REQUEST_RANGE_NOT_SATISFIABLE     (416)
+   RC_EXPECTATION_FAILED		(417)
+
+   RC_INTERNAL_SERVER_ERROR		(500)
+   RC_NOT_IMPLEMENTED			(501)
+   RC_BAD_GATEWAY			(502)
+   RC_SERVICE_UNAVAILABLE		(503)
+   RC_GATEWAY_TIMEOUT			(504)
+   RC_HTTP_VERSION_NOT_SUPPORTED	(505)
+
+=cut
+
+#####################################################################
+
+use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
+
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(is_info is_success is_redirect is_error status_message);
+@EXPORT_OK = qw(is_client_error is_server_error);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+# Note also addition of mnemonics to @EXPORT below
+
+my %StatusCode = (
+    100 => 'Continue',
+    101 => 'Switching Protocols',
+    200 => 'OK',
+    201 => 'Created',
+    202 => 'Accepted',
+    203 => 'Non-Authoritative Information',
+    204 => 'No Content',
+    205 => 'Reset Content',
+    206 => 'Partial Content',
+    300 => 'Multiple Choices',
+    301 => 'Moved Permanently',
+    302 => 'Found',
+    303 => 'See Other',
+    304 => 'Not Modified',
+    305 => 'Use Proxy',
+    307 => 'Temporary Redirect',
+    400 => 'Bad Request',
+    401 => 'Unauthorized',
+    402 => 'Payment Required',
+    403 => 'Forbidden',
+    404 => 'Not Found',
+    405 => 'Method Not Allowed',
+    406 => 'Not Acceptable',
+    407 => 'Proxy Authentication Required',
+    408 => 'Request Timeout',
+    409 => 'Conflict',
+    410 => 'Gone',
+    411 => 'Length Required',
+    412 => 'Precondition Failed',
+    413 => 'Request Entity Too Large',
+    414 => 'Request-URI Too Large',
+    415 => 'Unsupported Media Type',
+    416 => 'Request Range Not Satisfiable',
+    417 => 'Expectation Failed',
+    500 => 'Internal Server Error',
+    501 => 'Not Implemented',
+    502 => 'Bad Gateway',
+    503 => 'Service Unavailable',
+    504 => 'Gateway Timeout',
+    505 => 'HTTP Version Not Supported',
+);
+
+my $mnemonicCode = '';
+my ($code, $message);
+while (($code, $message) = each %StatusCode) {
+    # create mnemonic subroutines
+    $message =~ tr/a-z \-/A-Z__/;
+    $mnemonicCode .= "sub RC_$message () { $code }\t";
+    # make them exportable
+    $mnemonicCode .= "push(\@EXPORT, 'RC_$message');\n";
+}
+# warn $mnemonicCode; # for development
+eval $mnemonicCode; # only one eval for speed
+die if $@;
+
+# backwards compatibility
+*RC_MOVED_TEMPORARILY = \&RC_FOUND;  # 302 was renamed in the standard
+push(@EXPORT, "RC_MOVED_TEMPORARILY");
+
+
+=head1 FUNCTIONS
+
+The following additional functions are provided.  Most of them are
+exported by default.
+
+=over 4
+
+=item status_message($code)
+
+The status_message() function will translate status codes to human
+readable strings. The string is the same as found in the constant
+names above.  If the $code is unknown, then C<undef> is returned.
+
+=cut
+
+sub status_message ($)
+{
+    $StatusCode{$_[0]};
+}
+
+=item is_info($code)
+
+Return TRUE if C<$code> is an I<Informational> status code.  This
+class of status code indicates a provisional response which can't have
+any content.
+
+=item is_success($code)
+
+Return TRUE if C<$code> is a I<Successful> status code.
+
+=item is_redirect($code)
+
+Return TRUE if C<$code> is a I<Redirection> status code. This class of
+status code indicates that further action needs to be taken by the
+user agent in order to fulfill the request.
+
+=item is_error($code)
+
+Return TRUE if C<$code> is an I<Error> status code.  The function
+return TRUE for both client error or a server error status codes.
+
+=item is_client_error($code)
+
+Return TRUE if C<$code> is an I<Client Error> status code. This class
+of status code is intended for cases in which the client seems to have
+erred.
+
+This function is B<not> exported by default.
+
+=item is_server_error($code)
+
+Return TRUE if C<$code> is an I<Server Error> status code. This class
+of status codes is intended for cases in which the server is aware
+that it has erred or is incapable of performing the request.
+
+This function is B<not> exported by default.
+
+=back
+
+=cut
+
+sub is_info         ($) { $_[0] >= 100 && $_[0] < 200; }
+sub is_success      ($) { $_[0] >= 200 && $_[0] < 300; }
+sub is_redirect     ($) { $_[0] >= 300 && $_[0] < 400; }
+sub is_error        ($) { $_[0] >= 400 && $_[0] < 600; }
+sub is_client_error ($) { $_[0] >= 400 && $_[0] < 500; }
+sub is_server_error ($) { $_[0] >= 500 && $_[0] < 600; }
+
+1;
+
+=head1 BUGS
+
+Wished @EXPORT_OK had been used instead of @EXPORT in the beginning.
+Now too much is exported by default.
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP.pm	(revision 20131)
@@ -0,0 +1,593 @@
+#
+# $Id$
+
+package LWP;
+
+$VERSION = "5.36";
+sub Version { $VERSION; }
+
+require 5.004;
+require LWP::UserAgent;  # this should load everything you need
+
+1;
+
+__END__
+
+=head1 NAME
+
+LWP - Library for WWW access in Perl
+
+=head1 SYNOPSIS
+
+  use LWP;
+  print "This is libwww-perl-$LWP::VERSION\n";
+
+
+=head1 DESCRIPTION
+
+Libwww-perl is a collection of Perl modules which provides a simple
+and consistent programming interface (API) to the World-Wide Web.  The
+main focus of the library is to provide classes and functions that
+allow you to write WWW clients, thus libwww-perl said to be a WWW
+client library. The library also contain modules that are of more
+general use.
+
+Most modules in this library are object oriented.  The user
+agent, requests sent and responses received from the WWW server are
+all represented by objects.  This makes a simple and powerful
+interface to these services.  The interface should be easy to extend
+and customize for your needs.
+
+The main features of the library are:
+
+=over 3
+
+=item *
+
+Contains various reusable components (modules) that can be
+used separately or together.
+
+=item *
+
+Provides an object oriented model of HTTP-style communication.  Within
+this framework we currently support access to http, https, gopher, ftp, news,
+file, and mailto resources.
+
+=item *
+
+The library be used through the full object oriented interface or
+through a very simple procedural interface.
+
+=item *
+
+Support the basic and digest authorization schemes.
+
+=item *
+
+Transparent redirect handling.
+
+=item *
+
+Supports access through proxy servers.
+
+=item *
+
+URL handling (both absolute and relative URLs are supported).
+
+=item *
+
+A parser for F<robots.txt> files and a framework for constructing robots.
+
+=item *
+
+The library can cooperate with Tk.  A simple Tk-based GUI browser
+called 'tkweb' is distributed with the Tk extension for perl.
+
+=item *
+
+An implementation of the HTTP content negotiation algorithm that can
+be used both in protocol modules and in server scripts (like CGI
+scripts).
+
+=item *
+
+It can deal with HTTP cookies.
+
+=item *
+
+A simple command line client application called C<lwp-request>.
+
+=back
+
+
+=head1 HTTP STYLE COMMUNICATION
+
+
+The libwww-perl library is based on HTTP style communication. This
+section try to describe what that means.
+
+Let us start with this quote from the HTTP specification document
+<URL:http://www.w3.org/pub/WWW/Protocols/>:
+
+=over 3
+
+=item
+
+The HTTP protocol is based on a request/response paradigm. A client
+establishes a connection with a server and sends a request to the
+server in the form of a request method, URI, and protocol version,
+followed by a MIME-like message containing request modifiers, client
+information, and possible body content. The server responds with a
+status line, including the message's protocol version and a success or
+error code, followed by a MIME-like message containing server
+information, entity meta-information, and possible body content.
+
+=back
+
+What this means to libwww-perl is that communication always take place
+through these steps: First a I<request> object is created and
+configured. This object is then passed to a server and we get a
+I<response> object in return that we can examine. A request is always
+independent of any previous requests, i.e. the service is stateless.
+The same simple model is used for any kind of service we want to
+access.
+
+For example, if we want to fetch a document from a remote file server,
+then we send it a request that contains a name for that document and
+the response will contain the document itself.  If we access a search
+engine, then the content of the request will contain the query
+parameters and the response will contain the query result.  If we want
+to send a mail message to somebody then we send a request object which
+contains our message to the mail server and the response object will
+contain an acknowledgment that tells us that the message has been
+accepted and will be forwarded to the recipient(s).
+
+It is as simple as that!
+
+
+=head2 The Request Object
+
+The request object has the class name C<HTTP::Request> in
+libwww-perl. The fact that the class name use C<HTTP::> as a name
+prefix only implies that we use the HTTP model of communication. It
+does not limit the kind of services we can try to pass this I<request>
+to.  For instance, we will send C<HTTP::Request>s both to ftp and
+gopher servers, as well as to the local file system.
+
+The main attributes of the request objects are:
+
+=over 3
+
+=item *
+
+The B<method> is a short string that tells what kind of
+request this is.  The most used methods are B<GET>, B<PUT>,
+B<POST> and B<HEAD>.
+
+=item *
+
+The B<url> is a string denoting the protocol, server and
+the name of the "document" we want to access.  The B<url> might
+also encode various other parameters.
+
+=item *
+
+The B<headers> contain additional information about the
+request and can also used to describe the content.  The headers
+is a set of keyword/value pairs.
+
+=item *
+
+The B<content> is an arbitrary amount of data.
+
+=back
+
+=head2 The Response Object
+
+The response object has the class name C<HTTP::Response> in
+libwww-perl.  The main attributes of objects of this class are:
+
+=over 3
+
+=item *
+
+The B<code> is a numerical value that encode the overall
+outcome of the request.
+
+=item *
+
+The B<message> is a short (human readable) string that
+corresponds to the I<code>.
+
+=item *
+
+The B<headers> contain additional information about the
+response and they also describe the content.
+
+=item *
+
+The B<content> is an arbitrary amount of data.
+
+=back
+
+Since we don't want to handle all possible I<code> values directly in
+our programs, the libwww-perl response object have methods that can be
+used to query what kind of response this is.  The most commonly used
+response classification methods are:
+
+=over 3
+
+=item is_success()
+
+The request was was successfully received, understood or accepted.
+
+=item is_error()
+
+The request failed.  The server or the resource might not be
+available, access to the resource might be denied or other things might
+have failed for some reason.
+
+=back
+
+=head2 The User Agent
+
+Let us assume that we have created a I<request> object. What do we
+actually do with it in order to receive a I<response>?
+
+The answer is that you pass it on to a I<user agent> object and this
+object will take care of all the things that need to be done
+(low-level communication and error handling). The user agent will give
+you back a I<response> object. The user agent represents your
+application on the network and it provides you with an interface that
+can accept I<requests> and will return I<responses>.
+
+You should think about the user agent as an interface layer between
+your application code and the network.  Through this interface you are
+able to access the various servers on the network.
+
+The libwww-perl class name for the user agent is
+C<LWP::UserAgent>. Every libwww-perl application that wants to
+communicate should create at least one object of this kind. The main
+method provided by this object is request(). This method takes an
+C<HTTP::Request> object as argument and will (eventually) return a
+C<HTTP::Response> object.
+
+The user agent has many other attributes that lets you
+configure how it will interact with the network and with your
+application code.
+
+=over 3
+
+=item *
+
+The B<timeout> specify how much time we give remote servers in
+creating responses before the library disconnect and creates an
+internal I<timeout> response.
+
+=item *
+
+The B<agent> specify the name that your application should use when it
+presents itself on the network.
+
+=item *
+
+The B<from> attribute can be set to the e-mail address of the person
+responsible for running the application.  If this is set, then the
+address will be sent to the servers with every request.
+
+=item *
+
+The B<parse_head> specify whether we should initialize response
+headers from the E<lt>head> section of HTML documents.
+
+=item *
+
+The B<proxy> and B<no_proxy> specify if and when communication should
+go through a proxy server. <URL:http://www.w3.org/pub/WWW/Proxies/>
+
+=item *
+
+The B<credentials> provide a way to set up user names and
+passwords that is needed to access certain services.
+
+=back
+
+Many applications would want even more control over how they interact
+with the network and they get this by specializing the
+C<LWP::UserAgent> by sub-classing.  The library provide a
+specialization called C<LWP::RobotUA> that is used by robot
+applications.
+
+=head2 An Example
+
+This example shows how the user agent, a request and a response are
+represented in actual perl code:
+
+  # Create a user agent object
+  use LWP::UserAgent;
+  $ua = new LWP::UserAgent;
+  $ua->agent("AgentName/0.1 " . $ua->agent);
+
+  # Create a request
+  my $req = new HTTP::Request POST => 'http://www.perl.com/cgi-bin/BugGlimpse';
+  $req->content_type('application/x-www-form-urlencoded');
+  $req->content('match=www&errors=0');
+
+  # Pass request to the user agent and get a response back
+  my $res = $ua->request($req);
+
+  # Check the outcome of the response
+  if ($res->is_success) {
+      print $res->content;
+  } else {
+      print "Bad luck this time\n";
+  }
+
+The $ua is created once when the application starts up.  New request
+objects are normally created for each request sent.
+
+
+=head1 NETWORK SUPPORT
+
+This section goes through the various protocol schemes and describe
+the HTTP style methods that are supported and the headers that might
+have any effect.
+
+For all requests, a "User-Agent" header is added and initialized from
+the $ua->agent value before the request is handed to the network
+layer.  In the same way, a "From" header is initialized from the
+$ua->from value.
+
+For all responses, the library will add a header called "Client-Date".
+This header will encode the time when the response was received by
+your application.  This format and semantics of the header is just
+like the server created "Date" header.  You can also encounter other
+"Client-XXX" headers.  They are all generated by the library
+internally and not something really passed on from the servers.
+
+=head2 HTTP Requests
+
+HTTP request are really just handed off to an HTTP server and it will
+decide what happens.  Few servers implement methods beside the usual
+"GET", "HEAD", "POST" and "PUT" but CGI-scripts can really implement
+any method they like.
+
+If the server is not available then the library will generate an
+internal error response.
+
+The library automatically adds a "Host" and a "Content-Length" header
+to the HTTP request before it is sent over the network.
+
+For GET request you might want to add the "If-Modified-Since" header
+to make the request conditional.
+
+For POST request you should add the "Content-Type" header.  When you
+try to emulate HTML E<lt>FORM> handling you should usually let the value
+of the "Content-Type" header be "application/x-www-form-urlencoded".
+See L<lwpcook> for examples of this.
+
+The libwww-perl HTTP implementation currently support the HTTP/1.0
+protocol.  HTTP/0.9 servers are also handled correctly.
+
+The library allows you to access proxy server through HTTP.  This
+means that you can set up the library to forward all types of request
+through the HTTP protocol module.  See L<LWP::UserAgent> for
+documentation of this.
+
+
+=head2 HTTPS Requests
+
+HTTPS requests are HTTP requests over an encrypted network connection
+using the SSL protocol developed by Netscape.  Everything about HTTP
+requests above also hold for HTTPS requests.  In addition the library
+will add the headers "Client-SSL-Cipher", "Client-SSL-Cert-Subject" and
+"Client-SSL-Cert-Issuer" to the response.  These headers denote the
+encryption method used and the name of the server owner.
+
+The request can contain the header "If-SSL-Cert-Subject" in order to
+make the request conditional on the content of the server certificate.
+If the certificate subject does not match, no request is sent to the
+server and an internally generated error response is returned.  The
+value of the "If-SSL-Cert-Subject" header is interpreted as a Perl
+regular expression.
+
+
+=head2 FTP Requests
+
+The library currently support GET, HEAD and PUT requests.  GET will
+retrieve a file or a directory listing from an FTP server.  PUT will
+store a file on a ftp server.
+
+You can specify a ftp account for servers that want this in addition
+user name and password.  This is specified by passing an "Account"
+header in the request.
+
+User name/password can be specified using basic authorization or be
+encoded in the URL.  Bad logins return an UNAUTHORIZED response with
+"WWW-Authenticate: Basic" and can be treated as basic authorization
+for HTTP.
+
+The library support ftp ASCII transfer mode by specifying the "type=a"
+parameter in the URL.
+
+Directory listings are by default returned unprocessed (as returned
+from the ftp server) with the content media type reported to be
+"text/ftp-dir-listing". The C<File::Listing> module provide functionality
+for parsing of these directory listing.
+
+The ftp module is also able to convert directory listings to HTML and
+this can be requested via the standard HTTP content negotiation
+mechanisms (add an "Accept: text/html" header in the request if you
+want this).
+
+The normal file retrievals, the "Content-Type" is guessed based on the
+file name suffix. See L<LWP::MediaTypes>.
+
+The "If-Modified-Since" request header works for servers that implement
+the MDTM command.  It will probably not work for directory listings though.
+
+Example:
+
+  $req = HTTP::Request->new(GET => 'ftp://me:passwd@ftp.some.where.com/');
+  $req->header(Accept => "text/html, */*;q=0.1");
+
+=head2 News Requests
+
+Access to the USENET News system is implemented through the NNTP
+protocol.  The name of the news server is obtained from the
+NNTP_SERVER environment variable and defaults to "news".  It is not
+possible to specify the hostname of the NNTP server in the news:-URLs.
+
+The library support GET and HEAD to retrieve news articles through the
+NNTP protocol.  You can also post articles to newsgroups by using
+(surprise!) the POST method.
+
+GET on newsgroups is not implemented yet.
+
+Examples:
+
+  $req = HTTP::Request->new(GET => 'news:abc1234@a.sn.no');
+
+  $req = HTTP::Request->new(POST => 'news:comp.lang.perl.test');
+  $req->header(Subject => 'This is a test',
+               From    => 'me@some.where.org');
+  $req->content(<<EOT);
+  This is the content of the message that we are sending to
+  the world.
+  EOT
+
+
+=head2 Gopher Request
+
+The library supports the GET and HEAD method for gopher request.  All
+request header values are ignored.  HEAD cheats and will return a
+response without even talking to server.
+
+Gopher menus are always converted to HTML.
+
+The response "Content-Type" is generated from the document type
+encoded (as the first letter) in the request URL path itself.
+
+Example:
+
+  $req = HTTP::Request->new(GET => 'gopher://gopher.sn.no/');
+
+
+
+=head2 File Request
+
+The library supports GET and HEAD methods for file requests.  The
+"If-Modified-Since" header is supported.  All other headers are
+ignored.  The I<host> component of the file URL must be empty or set
+to "localhost".  Any other I<host> value will be treated as an error.
+
+Directories are always converted to an HTML document.  For normal
+files, the "Content-Type" and "Content-Encoding" in the response are
+guessed based on the file suffix.
+
+Example:
+
+  $req = HTTP::Request->new(GET => 'file:/etc/passwd');
+
+
+=head2 Mailto Request
+
+You can send (aka "POST") mail messages using the library.  All
+headers specified for the request are passed on to the mail system.
+The "To" header is initialized from the mail address in the URL.
+
+Example:
+
+  $req = HTTP::Request->new(POST => 'mailto:libwww-perl-request@ics.uci.edu');
+  $req->header(Subject => "subscribe");
+  $req->content("Please subscribe me to the libwww-perl mailing list!\n");
+
+
+=head1 OVERVIEW OF CLASSES AND PACKAGES
+
+This table should give you a quick overview of the classes provided by the
+library. Indentation shows class inheritance.
+
+ LWP::MemberMixin   -- Access to member variables of Perl5 classes
+   LWP::UserAgent   -- WWW user agent class
+     LWP::RobotUA   -- When developing a robot applications
+   LWP::Protocol          -- Interface to various protocol schemes
+     LWP::Protocol::http  -- http:// access
+     LWP::Protocol::file  -- file:// access
+     LWP::Protocol::ftp   -- ftp:// access
+     ...
+
+ LWP::Authen::Basic -- Handle 401 and 407 responses
+ LWP::Authen::Digest
+
+ HTTP::Headers      -- MIME/RFC822 style header (used by HTTP::Message)
+ HTTP::Message      -- HTTP style message
+   HTTP::Request    -- HTTP request
+   HTTP::Response   -- HTTP response
+ HTTP::Daemon       -- A HTTP server class
+
+ URI::URL           -- Uniform Resource Locators
+
+ WWW::RobotRules    -- Parse robots.txt files
+   WWW::RobotRules::AnyDBM_File -- Persistent RobotRules
+
+The following modules provide various functions and definitions.
+
+ LWP                -- This file.  Library version number and documentation.
+ LWP::MediaTypes    -- MIME types configuration (text/html etc.)
+ LWP::Debug         -- Debug logging module
+ LWP::Simple        -- Simplified procedural interface for common functions
+ HTTP::Status       -- HTTP status code (200 OK etc)
+ HTTP::Date         -- Date parsing module for HTTP date formats
+ HTTP::Negotiate    -- HTTP content negotiation calculation
+ File::Listing      -- Parse directory listings
+
+
+=head1 MORE DOCUMENTATION
+
+All modules contain detailed information on the interfaces they
+provide.  The I<lwpcook> manpage is the libwww-perl cookbook that contain
+examples of typical usage of the library.  You might want to take a
+look at how the scripts C<lwp-request>, C<lwp-rget> and C<lwp-mirror>
+are implemented.
+
+=head1 BUGS
+
+The library can not handle multiple simultaneous requests yet.  Also,
+check out what's left in the TODO file.
+
+=head1 ACKNOWLEDGEMENTS
+
+This package owes a lot in motivation, design, and code, to the
+libwww-perl library for Perl 4, maintained by Roy Fielding
+E<lt>fielding@ics.uci.edu>.
+
+That package used work from Alberto Accomazzi, James Casey, Brooks
+Cutter, Martijn Koster, Oscar Nierstrasz, Mel Melchner, Gertjan van
+Oosten, Jared Rhine, Jack Shirazi, Gene Spafford, Marc VanHeyningen,
+Steven E. Brenner, Marion Hakanson, Waldemar Kebsch, Tony Sanders, and
+Larry Wall; see the libwww-perl-0.40 library for details.
+
+The primary architect for this Perl 5 library is Martijn Koster and
+Gisle Aas, with lots of help from Graham Barr, Tim Bunce, Andreas
+Koenig, Jared Rhine, and Jack Shirazi.
+
+
+=head1 COPYRIGHT
+
+  Copyright 1995-1998, Gisle Aas
+  Copyright 1995, Martijn Koster
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 AVAILABILITY
+
+The latest version of this library is likely to be available from:
+
+ http://www.sn.no/libwww-perl/
+
+The best place to discuss this code is on the
+<libwww-perl@ics.uci.edu> mailing list.
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Authen/Basic.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Authen/Basic.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Authen/Basic.pm	(revision 20131)
@@ -0,0 +1,36 @@
+package LWP::Authen::Basic;
+use strict;
+
+require MIME::Base64;
+
+sub authenticate
+{
+    my($class, $ua, $proxy, $auth_param, $response,
+       $request, $arg, $size) = @_;
+
+    my($user, $pass) = $ua->get_basic_credentials($auth_param->{realm},
+                                                  $request->url, $proxy);
+    return $response unless defined $user and defined $pass;
+
+    my $auth_header = $proxy ? "Proxy-Authorization" : "Authorization";
+    my $auth_value = "Basic " . MIME::Base64::encode("$user:$pass", "");
+
+    # Need to check this isn't a repeated fail!
+    my $r = $response;
+    while ($r) {
+	my $auth = $r->request->header($auth_header);
+	if ($auth && $auth eq $auth_value) {
+	    # here we know this failed before
+	    $response->header("Client-Warning" =>
+			      "Credentials for '$user' failed before");
+	    return $response;
+	}
+	$r = $r->previous;
+    }
+
+    my $referral = $request->clone;
+    $referral->header($auth_header => $auth_value);
+    return $ua->request($referral, $arg, $size, $response);
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Authen/Digest.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Authen/Digest.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Authen/Digest.pm	(revision 20131)
@@ -0,0 +1,73 @@
+package LWP::Authen::Digest;
+use strict;
+
+require MD5;
+
+sub authenticate
+{
+    my($class, $ua, $proxy, $auth_param, $response,
+       $request, $arg, $size) = @_;
+
+    my($user, $pass) = $ua->get_basic_credentials($auth_param->{realm},
+                                                  $request->url, $proxy);
+    return $response unless defined $user and defined $pass;
+
+    my $md5 = new MD5;
+
+    my(@digest);
+    $md5->add(join(":", $user, $auth_param->{realm}, $pass));
+    push(@digest, $md5->hexdigest);
+    $md5->reset;
+
+    push(@digest, $auth_param->{nonce});
+
+    $md5->add(join(":", $request->method, $request->url->path));
+    push(@digest, $md5->hexdigest);
+    $md5->reset;
+
+    $md5->add(join(":", @digest));
+    my($digest) = $md5->hexdigest;
+    $md5->reset;
+
+    my %resp = map { $_ => $auth_param->{$_} } qw(realm nonce opaque);
+    @resp{qw(username uri response)} = ($user, $request->url->path, $digest);
+
+    my(@order) = qw(username realm nonce uri response);
+    if($request->method =~ /^(?:POST|PUT)$/) {
+	$md5->add($request->content);
+	my $content = $md5->hexdigest;
+	$md5->reset;
+	$md5->add(join(":", @digest[0..1], $content));
+	$md5->reset;
+	$resp{"message-digest"} = $md5->hexdigest;
+	push(@order, "message-digest");
+    }
+    push(@order, "opaque");
+    my @pairs;
+    for (@order) {
+	next unless defined $resp{$_};
+	push(@pairs, "$_=" . qq("$resp{$_}"));
+    }
+
+    my $auth_header = $proxy ? "Proxy-Authorization" : "Authorization";
+    my $auth_value  = "Digest " . join(", ", @pairs);
+    
+    # Need to check this isn't a repeated fail!
+    my $r = $response;
+    while ($r) {
+	my $auth = $r->request->header($auth_header);
+	if ($auth && $auth eq $auth_value) {
+	    # here we know this failed before
+	    $response->header("Client-Warning" =>
+			      "Credentials for '$user' failed before");
+	    return $response;
+	}
+	$r = $r->previous;
+    }
+
+    my $referral = $request->clone;
+    $referral->header($auth_header => $auth_value);
+    return $ua->request($referral, $arg, $size, $response);
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Debug.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Debug.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Debug.pm	(revision 20131)
@@ -0,0 +1,129 @@
+#!/usr/local/bin/perl -w
+#
+# $Id$
+#
+package LWP::Debug;
+
+=head1 NAME
+
+LWP::Debug - debug routines for the libwww-perl library
+
+=head1 SYNOPSIS
+
+ use LWP::Debug qw(+ -conns);
+
+ # Used internally in the library
+ LWP::Debug::trace('send()');
+ LWP::Debug::debug('url ok');
+ LWP::Debug::conns("read $n bytes: $data");
+
+=head1 DESCRIPTION
+
+LWP::Debug provides tracing facilities. The trace(), debug() and
+conns() function are called within the library and they log
+information at increasing levels of detail. Which level of detail is
+actually printed is controlled with the C<level()> function.
+
+The following functions are available:
+
+=over 4
+
+=item level(...)
+
+The C<level()> function controls the level of detail being
+logged. Passing '+' or '-' indicates full and no logging
+respectively. Inidividual levels can switched on and of by passing the
+name of the level with a '+' or '-' prepended.  The levels are:
+
+  trace   : trace function calls
+  debug   : print debug messages
+  conns   : show all data transfered over the connections
+
+The LWP::Debug module provide a special import() method that allows
+you to pass the level() arguments with initial use statement.  If a
+use argument start with '+' or '-' then it is passed to the level
+function, else the name is exported as usual.  The following two
+statements are thus equivalent (if you ignore that the second pollutes
+your namespace):
+
+  use LWP::Debug qw(+);
+  use LWP::Debug qw(level); level('+');
+
+=item trace($msg)
+
+The C<trace()> function is used for tracing function
+calls. The package and calling subroutine name is
+printed along with the passed argument. This should
+be called at the start of every major function.
+
+=item debug($msg)
+
+The C<debug()> function is used for high-granularity
+reporting of state in functions.
+
+=item conns($msg)
+
+The C<conns()> function is used to show data being
+transferred over the connections. This may generate
+considerable output.
+
+=back
+
+=cut
+
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(level trace debug conns);
+
+use Carp ();
+
+my @levels = qw(trace debug conns);
+%current_level = ();
+
+sub import
+{
+    my $pack = shift;
+    my $callpkg = caller(0);
+    my @symbols = ();
+    my @levels = ();
+    for (@_) {
+	if (/^[-+]/) {
+	    push(@levels, $_);
+	} else {
+	    push(@symbols, $_);
+	}
+    }
+    Exporter::export($pack, $callpkg, @symbols);
+    level(@levels);
+}
+
+sub level
+{
+    for (@_) {
+	if ($_ eq '+') {              # all on
+	    # switch on all levels
+	    %current_level = map { $_ => 1 } @levels;
+	} elsif ($_ eq '-') {           # all off
+	    %current_level = ();
+	} elsif (/^([-+])(\w+)$/) {
+	    $current_level{$2} = $1 eq '+';
+	} else {
+	    Carp::croak("Illegal level format $_");
+	}
+    }
+}
+
+sub trace  { _log(@_) if $current_level{'trace'}; }
+sub debug  { _log(@_) if $current_level{'debug'}; }
+sub conns  { _log(@_) if $current_level{'conns'}; }
+
+sub _log
+{
+    my $msg = shift;
+    $msg .= "\n" unless $msg =~ /\n$/;  # ensure trailing "\n"
+
+    my($package,$filename,$line,$sub) = caller(2);
+    print STDERR "$sub: $msg";
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/MediaTypes.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/MediaTypes.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/MediaTypes.pm	(revision 20131)
@@ -0,0 +1,298 @@
+#
+# $Id$
+
+package LWP::MediaTypes;
+
+=head1 NAME
+
+LWP::MediaTypes - guess media type for a file or a URL
+
+=head1 SYNOPSIS
+
+ use LWP::MediaTypes qw(guess_media_type);
+ $type = guess_media_type("/tmp/foo.gif");
+
+=head1 DESCRIPTION
+
+This module provides functions for handling of media (also known as
+MIME) types and encodings.  The mapping from file extentions to media
+types is defined by the F<media.types> file.  If the F<~/.media.types>
+file exist it is used as a replacement.
+For backwards compatability we will also look for F<~/.mime.types>.
+
+The following functions are exported by default:
+
+=over 4
+
+=cut
+
+####################################################################
+
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(guess_media_type media_suffix);
+@EXPORT_OK = qw(add_type add_encoding);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+require LWP::Debug;
+use strict;
+
+# note: These hashes will also be filled with the entries found in
+# the 'media.types' file.
+
+my %suffixType = (
+    'txt'   => 'text/plain',
+    'html'  => 'text/html',
+    'gif'   => 'image/gif',
+    'jpg'   => 'image/jpeg',
+);
+
+my %suffixExt = (
+    'text/plain' => 'txt',
+    'text/html'  => 'h',
+    'image/gif'  => 'gif',
+    'image/jpeg' => 'jpg',
+);
+
+#XXX: there should be some way to define this in the media.types files.
+my %suffixEncoding = (
+    'Z'   => 'compress',
+    'gz'  => 'gzip',
+    'hqx' => 'x-hqx',
+    'uu'  => 'x-uuencode',
+    'z'   => 'x-pack'
+);
+
+sub _dump {
+    require Data::Dumper;
+    Data::Dumper->new([\%suffixType, \%suffixExt, \%suffixEncoding],
+		      [qw(*suffixType *suffixExt *suffixEncoding)])->Dump;
+}
+
+read_media_types();
+
+
+
+=item guess_media_type($filename_or_url, [$header_to_modify])
+
+This function tries to guess media type and encoding for given file.
+It returns the content-type, which is a string like C<"text/html">.
+In array context it also returns any content-encodings applied (in the
+order used to encode the file).  You can pass a URI::URL object
+reference, instead of the file name, as the first parameter too.
+
+If the type can not be deduced from looking at the file name only,
+then guess_media_type() will let the C<-T> Perl operator take a look.
+If this works (and C<-T> returns a TRUE value) then we return
+I<text/plain> as the type, otherwise we return
+I<application/octet-stream> as the type.
+
+The optional second argument should be a reference to a HTTP::Headers
+object (or any object that implement the $obj->header method in a
+similar way).  When present we will set the values of the
+'Content-Type' and 'Content-Encoding' for this header.
+
+=cut
+
+sub guess_media_type
+{
+    my($file, $header) = @_;
+    return undef unless defined $file;
+
+    my $fullname;
+    if (ref($file)) {
+	# assume URI::URL object
+	$file = $file->path;
+	#XXX should handle non http:, file: or ftp: URLs differently
+    } else {
+	$fullname = $file;  # enable peek at actual file
+    }
+
+    my @encoding = ();
+    my $ct = undef;
+    for (file_exts($file)) {
+	# first check this dot part as encoding spec
+	if (exists $suffixEncoding{$_}) {
+	    unshift(@encoding, $suffixEncoding{$_});
+	    next;
+	}
+	if (exists $suffixEncoding{lc $_}) {
+	    unshift(@encoding, $suffixEncoding{lc $_});
+	    next;
+	}
+
+	# check content-type
+	if (exists $suffixType{$_}) {
+	    $ct = $suffixType{$_};
+	    last;
+	}
+	if (exists $suffixType{lc $_}) {
+	    $ct = $suffixType{lc $_};
+	    last;
+	}
+
+	# don't know nothing about this dot part, bail out
+	last;
+    }
+    unless (defined $ct) {
+	# Take a look at the file
+	if (defined $fullname) {
+	    $ct = (-T $fullname) ? "text/plain" : "application/octet-stream";
+	} else {
+	    $ct = "application/octet-stream";
+	}
+    }
+
+    if ($header) {
+	$header->header('Content-Type' => $ct);
+	$header->header('Content-Encoding' => \@encoding) if @encoding;
+    }
+
+    wantarray ? ($ct, @encoding) : $ct;
+}
+
+
+=item media_suffix($type,...)
+
+This function will return all suffixes that can be used to denote the
+specified media type(s).  Wildcard types can be used.  In scalar
+context it will return the first suffix found.
+
+Examples:
+
+  @suffixes = media_suffix('image/*', 'audio/basic');
+  $suffix = media_suffix('text/html');
+
+=cut
+
+sub media_suffix {
+    if (!wantarray && @_ == 1 && $_[0] !~ /\*/) {
+	return $suffixExt{$_[0]};
+    }
+    my(@type) = @_;
+    my(@suffix, $ext, $type);
+    foreach (@type) {
+	if (s/\*/.*/) {
+	    while(($ext,$type) = each(%suffixType)) {
+		push(@suffix, $ext) if $type =~ /^$_$/;
+	    }
+	} else {
+	    while(($ext,$type) = each(%suffixType)) {
+		push(@suffix, $ext) if $type eq $_;
+	    }
+	}
+    }
+    wantarray ? @suffix : $suffix[0];
+}
+
+
+sub file_exts 
+{
+    my($file) = @_;
+    $file =~ s,.*/,,;   # only basename left
+    my @parts = reverse split(/\./, $file);
+    pop(@parts);        # never concider first part
+    @parts;
+}
+
+
+=back
+
+The following functions are only exported by explict request:
+
+=over 4
+
+=item add_type($type, @exts)
+
+Associate a list of file extensions with the given media type.
+
+Example:
+
+    add_type("x-world/x-vrml" => qw(wrl vrml));
+
+=cut
+
+sub add_type 
+{
+    my($type, @exts) = @_;
+    for my $ext (@exts) {
+	$ext =~ s/^\.//;
+	$suffixType{$ext} = $type;
+    }
+    $suffixExt{$type} = $exts[0] if @exts;
+}
+
+
+=item add_encoding($type, @ext)
+
+Associate a list of file extensions with and encoding type.
+
+Example:
+
+ add_encoding("x-gzip" => "gz");
+
+=cut
+
+sub add_encoding
+{
+    my($type, @exts) = @_;
+    for my $ext (@exts) {
+	$ext =~ s/^\.//;
+	$suffixEncoding{$ext} = $type;
+    }
+}
+
+
+=item read_media_types(@files)
+
+Parse a media types file from disk and add the type mappings found there.
+
+Example:
+
+    read_media_types("conf/mime.types");
+
+=cut
+
+sub read_media_types 
+{
+    my(@files) = @_;
+
+    local($/, $_) = ("\n", undef);  # ensure correct $INPUT_RECORD_SEPARATOR
+
+    my @priv_files = ();
+    push(@priv_files, "$ENV{HOME}/.media.types", "$ENV{HOME}/.mime.types")
+	if defined $ENV{HOME};  # Some doesn't have a home (for instance Win32)
+
+    # Try to locate "media.types" file, and initialize %suffixType from it
+    my $typefile;
+    unless (@files) {
+	@files = map {"$_/LWP/media.types"} @INC;
+	push @files, @priv_files;
+    }
+    for $typefile (@files) {
+	local(*TYPE);
+	open(TYPE, $typefile) || next;
+        LWP::Debug::debug("Reading media types from $typefile");
+	while (<TYPE>) {
+	    next if /^\s*#/; # comment line
+	    next if /^\s*$/; # blank line
+	    s/#.*//;         # remove end-of-line comments
+	    my($type, @exts) = split(' ', $_);
+	    add_type($type, @exts);
+	}
+	close(TYPE);
+    }
+}
+
+1;
+
+=back 
+
+=head1 COPYRIGHT
+
+Copyright 1995-1998 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/MemberMixin.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/MemberMixin.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/MemberMixin.pm	(revision 20131)
@@ -0,0 +1,46 @@
+#
+# $Id$
+
+package LWP::MemberMixin;
+
+=head1 NAME
+
+LWP::MemberMixin - Member access mixin class
+
+=head1 SYNOPSIS
+
+ package Foo;
+ require LWP::MemberMixin;
+ @ISA=qw(LWP::MemberMixin);
+
+=head1 DESCRIPTION
+
+A mixin class to get methods that provide easy access to member
+variables in the %$self.
+Ideally there should be better Perl langauge support for this.
+
+There is only one method provided:
+
+=over 4
+
+=item _elem($elem [, $val])
+
+Internal method to get/set the value of member variable
+C<$elem>. If C<$val> is defined it is used as the new value
+for the member variable.  If it is undefined the current
+value is not touched. In both cases the previous value of
+the member variable is returned.
+
+=back
+
+=cut
+
+sub _elem
+{
+    my($self, $elem, $val) = @_;
+    my $old = $self->{$elem};
+    $self->{$elem} = $val if defined $val;
+    return $old;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol.pm	(revision 20131)
@@ -0,0 +1,303 @@
+# $Id$
+
+package LWP::Protocol;
+
+=head1 NAME
+
+LWP::Protocol - Base class for LWP protocols
+
+=head1 SYNOPSIS
+
+ package LWP::Protocol::foo;
+ require LWP::Protocol;
+ @ISA=qw(LWP::Protocol);
+
+=head1 DESCRIPTION
+
+This class is used a the base class for all protocol implementations
+supported by the LWP library.
+
+When creating an instance of this class using
+C<LWP::Protocol::create($url)>, and you get an initialised subclass
+appropriate for that access method. In other words, the
+LWP::Protocol::create() function calls the constructor for one of its
+subclasses.
+
+All derived LWP::Protocol classes need to override the request()
+method which is used to service a request. The overridden method can
+make use of the collect() function to collect together chunks of data
+as it is received.
+
+The following methods and functions are provided:
+
+=over 4
+
+=cut
+
+#####################################################################
+
+require LWP::MemberMixin;
+@ISA = qw(LWP::MemberMixin);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+use strict;
+use Carp ();
+use HTTP::Status 'RC_INTERNAL_SERVER_ERROR';
+require HTML::HeadParser;
+
+my %ImplementedBy = (); # scheme => classname
+
+
+=item $prot = new HTTP::Protocol;
+
+The LWP::Protocol constructor is inherited by subclasses. As this is a
+virtual base class this method should B<not> be called directly.
+
+=cut
+
+sub new
+{
+    my($class) = @_;
+
+    my $self = bless {
+	'timeout' => 0,
+	'parse_head' => 1,
+    }, $class;
+    $self;
+}
+
+
+=item $prot = LWP::Protocol::create($url)
+
+Create an object of the class implementing the protocol to handle the
+given scheme. This is a function, not a method. It is more an object
+factory than a constructor. This is the function user agents should
+use to access protocols.
+
+=cut
+
+sub create
+{
+    my $scheme = shift;
+    my $impclass = LWP::Protocol::implementor($scheme) or
+	Carp::croak("Protocol scheme '$scheme' is not supported");
+
+    # hand-off to scheme specific implementation sub-class
+    return $impclass->new($scheme);
+}
+
+
+=item $class = LWP::Protocol::implementor($scheme, [$class])
+
+Get and/or set implementor class for a scheme.  Returns '' if the
+specified scheme is not supported.
+
+=cut
+
+sub implementor
+{
+    my($scheme, $impclass) = @_;
+
+    if ($impclass) {
+	$ImplementedBy{$scheme} = $impclass;
+    }
+    my $ic = $ImplementedBy{$scheme};
+    return $ic if $ic;
+
+    return '' unless $scheme =~ /^([.+\-\w]+)$/;  # check valid URL schemes
+    $scheme = $1; # untaint
+    $scheme =~ s/[.+\-]/_/g;  # make it a legal module name
+
+    # scheme not yet known, look for a 'use'd implementation
+    $ic = "LWP::Protocol::$scheme";  # default location
+    $ic = "LWP::Protocol::nntp" if $scheme eq 'news'; #XXX ugly hack
+    no strict 'refs';
+    # check we actually have one for the scheme:
+    unless (defined @{"${ic}::ISA"}) {
+	# try to autoload it
+	eval "require $ic";
+	if ($@) {
+	    if ($@ =~ /^Can't locate/) { #' #emacs get confused by '
+		$ic = '';
+	    } else {
+		die "$@\n";
+	    }
+	}
+    }
+    $ImplementedBy{$scheme} = $ic if $ic;
+    $ic;
+}
+
+
+=item $prot->request(...)
+
+ $response = $protocol->request($request, $proxy, undef);
+ $response = $protocol->request($request, $proxy, '/tmp/sss');
+ $response = $protocol->request($request, $proxy, \&callback, 1024);
+
+Dispactches a request over the protocol, and returns a response
+object. This method needs to be overridden in subclasses.  Referer to
+L<LWP::UserAgent> for description of the arguments.
+
+=cut
+
+sub request
+{
+    my($self, $request, $proxy, $arg, $size, $timeout) = @_;
+    Carp::croak('LWP::Protocol::request() needs to be overridden in subclasses');
+}
+
+
+=item $prot->timeout($seconds)
+
+Get and set the timeout value in seconds
+
+
+=item $prot->parse_head($yesno)
+
+Should we initialize response headers from the <head> section of HTML
+documents.
+
+=cut
+
+sub timeout    { shift->_elem('timeout',    @_); }
+sub parse_head { shift->_elem('parse_head', @_); }
+sub max_size   { shift->_elem('max_size',   @_); }
+
+
+=item $prot->collect($arg, $response, $collector)
+
+Called to collect the content of a request, and process it
+appropriately into a scalar, file, or by calling a callback.  If $arg
+is undefined, then the content is stored within the $response.  If
+$arg is a simple scalar, then $arg is interpreted as a file name and
+the content is written to this file.  If $arg is a reference to a
+routine, then content is passed to this routine.
+
+The $collector is a routine that will be called and which is
+reponsible for returning pieces (as ref to scalar) of the content to
+process.  The $collector signals EOF by returning a reference to an
+empty sting.
+
+The return value from collect() is the $response object reference.
+
+B<Note:> We will only use the callback or file argument if
+$response->is_success().  This avoids sendig content data for
+redirects and authentization responses to the callback which would be
+confusing.
+
+=cut
+
+sub collect
+{
+    my ($self, $arg, $response, $collector) = @_;
+    my $content;
+    my($parse_head, $timeout, $max_size) =
+      @{$self}{qw(parse_head timeout max_size)};
+
+    my $parser;
+    if ($parse_head && $response->content_type eq 'text/html') {
+	$parser = HTML::HeadParser->new($response->{'_headers'});
+    }
+    my $content_size = 0;
+
+    if (!defined($arg) || !$response->is_success) {
+	# scalar
+	while ($content = &$collector, length $$content) {
+	    if ($parser) {
+		$parser->parse($$content) or undef($parser);
+	    }
+	    LWP::Debug::debug("read " . length($$content) . " bytes");
+	    $response->add_content($$content);
+	    $content_size += length($$content);
+	    if ($max_size && $content_size > $max_size) {
+		LWP::Debug::debug("Aborting because size limit exceeded");
+		my $tot = $response->header("Content-Length") || 0;
+		$response->header("X-Content-Range", "bytes 0-$content_size/$tot");
+		last;
+	    }
+	}
+    }
+    elsif (!ref($arg)) {
+	# filename
+	open(OUT, ">$arg") or
+	    return new HTTP::Response RC_INTERNAL_SERVER_ERROR,
+			  "Cannot write to '$arg': $!";
+        binmode(OUT);
+        local($\) = ""; # ensure standard $OUTPUT_RECORD_SEPARATOR
+	while ($content = &$collector, length $$content) {
+	    if ($parser) {
+		$parser->parse($$content) or undef($parser);
+	    }
+	    LWP::Debug::debug("read " . length($$content) . " bytes");
+	    print OUT $$content;
+	    $content_size += length($$content);
+	    if ($max_size && $content_size > $max_size) {
+		LWP::Debug::debug("Aborting because size limit exceeded");
+		my $tot = $response->header("Content-Length") || 0;
+		$response->header("X-Content-Range", "bytes 0-$content_size/$tot");
+		last;
+	    }
+	}
+	close(OUT);
+    }
+    elsif (ref($arg) eq 'CODE') {
+	# read into callback
+	while ($content = &$collector, length $$content) {
+	    if ($parser) {
+		$parser->parse($$content) or undef($parser);
+	    }
+	    LWP::Debug::debug("read " . length($$content) . " bytes");
+            eval {
+		&$arg($$content, $response, $self);
+	    };
+	    if ($@) {
+	        chomp($@);
+		$response->header('X-Died' => $@);
+		last;
+	    }
+	}
+    }
+    else {
+	return new HTTP::Response RC_INTERNAL_SERVER_ERROR,
+				  "Unexpected collect argument  '$arg'";
+    }
+    $response;
+}
+
+
+=item $prot->collect_once($arg, $response, $content)
+
+Can be called when the whole response content is available as
+$content.  This will invoke collect() with a collector callback that
+returns a reference to $content the first time and an empty string the
+next.
+
+=cut
+
+sub collect_once
+{
+    my($self, $arg, $response) = @_;
+    my $content = \ $_[3];
+    my $first = 1;
+    $self->collect($arg, $response, sub {
+	return $content if $first--;
+	return \ "";
+    });
+}
+
+1;
+
+=head1 SEE ALSO
+
+Inspect the F<LWP/Protocol/file.pm> and F<LWP/Protocol/http.pm> files
+for examples of usage.
+
+=head1 COPYRIGHT
+
+Copyright 1995-1997 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/data.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/data.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/data.pm	(revision 20131)
@@ -0,0 +1,53 @@
+#
+# $Id$
+#
+# Implements access to data:-URLs as specified in
+# draft-masinter-url-data-02.txt
+
+package LWP::Protocol::data;
+
+require HTTP::Response;
+require HTTP::Status;
+
+require LWP::Protocol;
+@ISA = qw(LWP::Protocol);
+
+use HTTP::Date qw(time2str);
+require LWP;  # needs version number
+
+sub request
+{
+    my($self, $request, $proxy, $arg, $size) = @_;
+
+    # check proxy
+    if (defined $proxy)
+    {
+	return new HTTP::Response &HTTP::Status::RC_BAD_REQUEST,
+				  'You can not proxy with data';
+    }
+
+    # check method
+    if ($request->method ne 'GET') {
+	return new HTTP::Response &HTTP::Status::RC_BAD_REQUEST,
+				  'Library does not allow method ' .
+				  "$method for 'data:' URLs";
+    }
+
+    my $url = $request->url;
+    my $response = new HTTP::Response &HTTP::Status::RC_OK, "Document follows";
+
+    my($media_type, $params) = $url->media_type;
+    $media_type .= ";$params" if $params;
+
+    my $data = $url->data;
+    $response->header('Content-Type'   => $media_type,
+		      'Content-Length' => length($data),
+		      'Date'           => time2str(time),
+		      'Server'         => "libwww-perl-internal/$LWP::VERSION"
+		     );
+    $response->content($data);
+
+    return $response;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/file.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/file.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/file.pm	(revision 20131)
@@ -0,0 +1,154 @@
+#
+# $Id$
+
+package LWP::Protocol::file;
+
+require LWP::Protocol;
+require LWP::MediaTypes;
+require HTTP::Request;
+require HTTP::Response;
+require HTTP::Status;
+require HTTP::Date;
+
+require URI::Escape;
+require HTML::Entities;
+
+use Carp;
+
+@ISA = qw(LWP::Protocol);
+
+
+sub request
+{
+    my($self, $request, $proxy, $arg, $size) = @_;
+
+    LWP::Debug::trace('()');
+
+    $size = 4096 unless defined $size and $size > 0;
+
+    # check proxy
+    if (defined $proxy)
+    {
+	return new HTTP::Response &HTTP::Status::RC_BAD_REQUEST,
+				  'You can not proxy through the filesystem';
+    }
+
+    # check method
+    $method = $request->method;
+
+    unless ($method eq 'GET' || $method eq 'HEAD') {
+	return new HTTP::Response &HTTP::Status::RC_BAD_REQUEST,
+				  'Library does not allow method ' .
+				  "$method for 'file:' URLs";
+    }
+
+    # check url
+    my $url = $request->url;
+
+    my $scheme = $url->scheme;
+    if ($scheme ne 'file') {
+	return new HTTP::Response &HTTP::Status::RC_INTERNAL_SERVER_ERROR,
+				  "LWP::file::request called for '$scheme'";
+    }
+
+    my $host = $url->host;
+    if ($host and $host !~ /^localhost$/i) {
+	return new HTTP::Response &HTTP::Status::RC_BAD_REQUEST_CLIENT,
+				  'Only file://localhost/ allowed';
+    }
+
+    # URL OK, look at file
+    my $path  = $url->local_path;
+
+    # test file exists and is readable
+    unless (-e $path) {
+	return new HTTP::Response &HTTP::Status::RC_NOT_FOUND,
+				  "File `$path' does not exist";
+    }
+    unless (-r _) {
+	return new HTTP::Response &HTTP::Status::RC_FORBIDDEN,
+				  'User does not have read permission';
+    }
+
+    # looks like file exists
+    my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$filesize,
+       $atime,$mtime,$ctime,$blksize,$blocks)
+	    = stat(_);
+
+    # XXX should check Accept headers?
+
+    # check if-modified-since
+    my $ims = $request->header('If-Modified-Since');
+    if (defined $ims) {
+	my $time = HTTP::Date::str2time($ims);
+	if (defined $time and $time >= $mtime) {
+	    return new HTTP::Response &HTTP::Status::RC_NOT_MODIFIED,
+				      "$method $path";
+	}
+    }
+
+    # Ok, should be an OK response by now...
+    $response = new HTTP::Response &HTTP::Status::RC_OK;
+
+    # fill in response headers
+    $response->header('Last-Modified', HTTP::Date::time2str($mtime));
+
+    if (-d _) {         # If the path is a directory, process it
+	# generate the HTML for directory
+	opendir(D, $path) or
+	   return new HTTP::Response &HTTP::Status::RC_INTERNAL_SERVER_ERROR,
+				     "Cannot read directory '$path': $!";
+	my(@files) = sort readdir(D);
+	closedir(D);
+
+	# Make directory listing
+	for (@files) {
+	    $_ .= "/" if -d "$path/$_";
+	    my $furl = URI::Escape::uri_escape($_);
+	    my $desc = HTML::Entities::encode($_);
+	    $_ = qq{<LI><A HREF="$furl">$desc</A>};
+	}
+	# Ensure that the base URL is "/" terminated
+	my $base = $url->clone;
+	unless ($base->epath =~ m|/$|) {
+	    $base->epath($base->epath . "/");
+	}
+	my $html = join("\n",
+			"<HTML>\n<HEAD>",
+			"<TITLE>Directory $path</TITLE>",
+			"<BASE HREF=\"$base\">",
+			"</HEAD>\n<BODY>",
+			"<H1>Directory listing of $path</H1>",
+			"<UL>", @files, "</UL>",
+			"</BODY>\n</HTML>\n");
+
+	$response->header('Content-Type',   'text/html');
+	$response->header('Content-Length', length $html);
+
+	return $self->collect_once($arg, $response, $html);
+
+    } else {            # path is a regular file
+	my($type, @enc) = LWP::MediaTypes::guess_media_type($path);
+	$response->header('Content-Type',   $type) if $type;
+	$response->header('Content-Length', $filesize);
+	for (@enc) {
+	    $response->push_header('Content-Encoding', $_);
+	}
+
+	# read the file
+	open(F, $path) or return new
+	   HTTP::Response(&HTTP::Status::RC_INTERNAL_SERVER_ERROR,
+			  "Cannot read file '$path': $!");
+	$response =  $self->collect($arg, $response, sub {
+	    my $content = "";
+	    my $bytes = sysread(F, $content, $size);
+	    return \$content if $bytes > 0;
+	    return \ "";
+	});
+	close(F);
+    }
+
+    $response;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/ftp.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/ftp.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/ftp.pm	(revision 20131)
@@ -0,0 +1,396 @@
+#
+# $Id$
+
+# Implementation of the ftp protocol (RFC 959). We let the Net::FTP
+# package do all the dirty work.
+
+package LWP::Protocol::ftp;
+
+use Carp ();
+
+use HTTP::Status ();
+use HTTP::Negotiate ();
+use HTTP::Response ();
+use LWP::MediaTypes ();
+use File::Listing ();
+
+require LWP::Protocol;
+@ISA = qw(LWP::Protocol);
+
+use strict;
+eval {
+    require Net::FTP;
+    Net::FTP->require_version(2.00);
+};
+my $init_failed = $@;
+
+
+sub request
+{
+    my($self, $request, $proxy, $arg, $size, $timeout) = @_;
+
+    $size = 4096 unless $size;
+
+    LWP::Debug::trace('()');
+
+    # check proxy
+    if (defined $proxy)
+    {
+	return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,
+				   'You can not proxy through the ftp');
+    }
+
+    my $url = $request->url;
+    if ($url->scheme ne 'ftp') {
+	my $scheme = $url->scheme;
+	return HTTP::Response->new(&HTTP::Status::RC_INTERNAL_SERVER_ERROR,
+		       "LWP::Protocol::ftp::request called for '$scheme'");
+    }
+
+    # check method
+    my $method = $request->method;
+
+    unless ($method eq 'GET' || $method eq 'HEAD' || $method eq 'PUT') {
+	return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,
+				   'Library does not allow method ' .
+				   "$method for 'ftp:' URLs");
+    }
+
+    if ($init_failed) {
+	return HTTP::Response->new(&HTTP::Status::RC_INTERNAL_SERVER_ERROR,
+				   $init_failed);
+    }
+
+    my $host     = $url->host;
+    my $port     = $url->port;
+    my $user     = $url->user;
+    my $password = $url->password;
+
+    # If a basic autorization header is present than we prefer these over
+    # the username/password specified in the URL.
+    {
+	my($u,$p) = $request->authorization_basic;
+	if (defined $u) {
+	    $user = $u;
+	    $password = $p;
+	}
+    }
+
+    # We allow the account to be specified in the "Account" header
+    my $acct     = $request->header('Account');
+
+    # try to make a connection
+    my $ftp = Net::FTP->new($host, Port => $port);
+    unless ($ftp) {
+       $@ =~ s/^Net::FTP: //;
+       return HTTP::Response->new(&HTTP::Status::RC_INTERNAL_SERVER_ERROR, $@);
+    }
+
+    # Create an initial response object
+    my $response = HTTP::Response->new(&HTTP::Status::RC_OK,
+				       "Document follows");
+    $response->request($request);
+
+    my $mess = $ftp->message;  # welcome message
+    LWP::Debug::debug($mess);
+    $mess =~ s|\n.*||s; # only first line left
+    $mess =~ s|\s*ready\.?$||;
+    # Make the version number more HTTP like
+    $mess =~ s|\s*\(Version\s*|/| and $mess =~ s|\)$||;
+    $response->header("Server", $mess);
+
+    $ftp->timeout($timeout) if $timeout;
+
+    LWP::Debug::debug("Logging in as $user (password $password)...");
+    unless ($ftp->login($user, $password, $acct)) {
+	# Unauthorized.  Let's fake a RC_UNAUTHORIZED response
+	my $res =  HTTP::Response->new(&HTTP::Status::RC_UNAUTHORIZED,
+				       scalar($ftp->message));
+	$res->header("WWW-Authenticate", qq(Basic Realm="FTP login"));
+	return $res;
+    }
+    LWP::Debug::debug($ftp->message);
+
+    # Get & fix the path
+    my @path =  $url->path_components;
+    shift(@path);  # There will always be an empty first component
+    pop(@path) while @path && $path[-1] eq '';  # remove empty tailing comps
+    my $remote_file = pop(@path);
+    $remote_file = '' unless defined $remote_file;
+
+    my $params = $url->params;
+    if (defined($params) && $params eq 'type=a') {
+	$ftp->ascii;
+    } else {
+	$ftp->binary;
+    }
+
+    for (@path) {
+	LWP::Debug::debug("CWD $_");
+	unless ($ftp->cwd($_)) {
+	    return HTTP::Response->new(&HTTP::Status::RC_NOT_FOUND,
+				       "Can't chdir to $_");
+	}
+    }
+
+    if ($method eq 'GET' || $method eq 'HEAD') {
+	LWP::Debug::debug("MDTM");
+	if (my $mod_time = $ftp->mdtm($remote_file)) {
+	    $response->last_modified($mod_time);
+	    if (my $ims = $request->if_modified_since) {
+		if ($mod_time <= $ims) {
+		    $response->code(&HTTP::Status::RC_NOT_MODIFIED);
+		    $response->message("Not modified");
+		    return $response;
+		}
+	    }
+	}
+
+	my $data;  # the data handle
+	LWP::Debug::debug("retrieve file?");
+	if (length($remote_file) and $data = $ftp->retr($remote_file)) {
+	    my($type, @enc) = LWP::MediaTypes::guess_media_type($remote_file);
+	    $response->header('Content-Type',   $type) if $type;
+	    for (@enc) {
+		$response->push_header('Content-Encoding', $_);
+	    }
+	    my $mess = $ftp->message;
+	    LWP::Debug::debug($mess);
+	    if ($mess =~ /\((\d+)\s+bytes\)/) {
+		$response->header('Content-Length', "$1");
+	    }
+
+	    if ($method ne 'HEAD') {
+		# Read data from server
+		$response = $self->collect($arg, $response, sub {
+		    my $content = '';
+		    my $result = $data->read($content, $size);
+		    return \$content;
+		} );
+	    }
+	    unless ($data->close) {
+		# Something did not work too well
+		if ($method ne 'HEAD') {
+		    $response->code(&HTTP::Status::RC_INTERNAL_SERVER_ERROR);
+		    $response->message("FTP close response: " . $ftp->code .
+				       " " . $ftp->message);
+		}
+	    }
+	} elsif (!length($remote_file) || $ftp->code == 550) {
+	    # 550 not a plain file, try to list instead
+	    if (length($remote_file) && !$ftp->cwd($remote_file)) {
+		LWP::Debug::debug("chdir before listing failed");
+		return HTTP::Response->new(&HTTP::Status::RC_NOT_FOUND,
+					   "File '$remote_file' not found");
+	    }
+
+	    # It should now be safe to try to list the directory
+	    LWP::Debug::debug("dir");
+	    my @lsl = $ftp->dir;
+
+	    # Try to figure out if the user want us to convert the
+	    # directory listing to HTML.
+	    my @variants =
+	      (
+	       ['html',  0.60, 'text/html'            ],
+	       ['dir',   1.00, 'text/ftp-dir-listing' ]
+	      );
+	    #$HTTP::Negotiate::DEBUG=1;
+	    my $prefer = HTTP::Negotiate::choose(\@variants, $request);
+
+	    my $content = '';
+
+	    if (!defined($prefer)) {
+		return HTTP::Response->new(&HTTP::Status::RC_NOT_ACCEPTABLE,
+			       "Neither HTML nor directory listing wanted");
+	    } elsif ($prefer eq 'html') {
+		$response->header('Content-Type' => 'text/html');
+		$content = "<HEAD><TITLE>File Listing</TITLE>\n";
+		my $base = $request->url->clone;
+		my $path = $base->epath;
+		$base->epath("$path/") unless $path =~ m|/$|;
+		$content .= qq(<BASE HREF="$base">\n</HEAD>\n);
+		$content .= "<BODY>\n<UL>\n";
+		for (File::Listing::parse_dir(\@lsl, 'GMT')) {
+		    my($name, $type, $size, $mtime, $mode) = @$_;
+		    $content .= qq(  <LI> <a href="$name">$name</a>);
+		    $content .= " $size bytes" if $type eq 'f';
+		    $content .= "\n";
+		}
+		$content .= "</UL></body>\n";
+	    } else {
+		$response->header('Content-Type', 'text/ftp-dir-listing');
+		$content = join("\n", @lsl, '');
+	    }
+
+	    $response->header('Content-Length', length($content));
+
+	    if ($method ne 'HEAD') {
+		$response = $self->collect_once($arg, $response, $content);
+	    }
+	} else {
+	    my $res = HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,
+			  "FTP return code " . $ftp->code);
+	    $res->content_type("text/plain");
+	    $res->content($ftp->message);
+	    return $res;
+	}
+    } elsif ($method eq 'PUT') {
+	# method must be PUT
+	unless (length($remote_file)) {
+	    return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,
+				       "Must have a file name to PUT to");
+	}
+	my $data;
+	if ($data = $ftp->stor($remote_file)) {
+	    LWP::Debug::debug($ftp->message);
+	    LWP::Debug::debug("$data");
+	    my $content = $request->content;
+	    my $bytes = 0;
+	    if (defined $content) {
+		if (ref($content) eq 'SCALAR') {
+		    $bytes = $data->write($$content, length($$content));
+		} elsif (ref($content) eq 'CODE') {
+		    my($buf, $n);
+		    while (length($buf = &$content)) {
+			$n = $data->write($buf, length($buf));
+			last unless $n;
+			$bytes += $n;
+		    }
+		} elsif (!ref($content)) {
+		    if (defined $content && length($content)) {
+			$bytes = $data->write($content, length($content));
+		    }
+		} else {
+		    die "Bad content";
+		}
+	    }
+	    $data->close;
+	    LWP::Debug::debug($ftp->message);
+
+	    $response->code(&HTTP::Status::RC_CREATED);
+	    $response->header('Content-Type', 'text/plain');
+	    $response->content("$bytes bytes stored as $remote_file on $host\n")
+
+	} else {
+	    my $res = HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,
+					  "FTP return code " . $ftp->code);
+	    $res->content_type("text/plain");
+	    $res->content($ftp->message);
+	    return $res;
+	}
+    } else {
+	return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,
+				   "Illegal method $method");
+    }
+
+    $response;
+}
+
+1;
+
+__END__
+
+# This is what RFC 1738 has to say about FTP access:
+# --------------------------------------------------
+#
+# 3.2. FTP
+#
+#    The FTP URL scheme is used to designate files and directories on
+#    Internet hosts accessible using the FTP protocol (RFC959).
+#
+#    A FTP URL follow the syntax described in Section 3.1.  If :<port> is
+#    omitted, the port defaults to 21.
+#
+# 3.2.1. FTP Name and Password
+#
+#    A user name and password may be supplied; they are used in the ftp
+#    "USER" and "PASS" commands after first making the connection to the
+#    FTP server.  If no user name or password is supplied and one is
+#    requested by the FTP server, the conventions for "anonymous" FTP are
+#    to be used, as follows:
+#
+#         The user name "anonymous" is supplied.
+#
+#         The password is supplied as the Internet e-mail address
+#         of the end user accessing the resource.
+#
+#    If the URL supplies a user name but no password, and the remote
+#    server requests a password, the program interpreting the FTP URL
+#    should request one from the user.
+#
+# 3.2.2. FTP url-path
+#
+#    The url-path of a FTP URL has the following syntax:
+#
+#         <cwd1>/<cwd2>/.../<cwdN>/<name>;type=<typecode>
+#
+#    Where <cwd1> through <cwdN> and <name> are (possibly encoded) strings
+#    and <typecode> is one of the characters "a", "i", or "d".  The part
+#    ";type=<typecode>" may be omitted. The <cwdx> and <name> parts may be
+#    empty. The whole url-path may be omitted, including the "/"
+#    delimiting it from the prefix containing user, password, host, and
+#    port.
+#
+#    The url-path is interpreted as a series of FTP commands as follows:
+#
+#       Each of the <cwd> elements is to be supplied, sequentially, as the
+#       argument to a CWD (change working directory) command.
+#
+#       If the typecode is "d", perform a NLST (name list) command with
+#       <name> as the argument, and interpret the results as a file
+#       directory listing.
+#
+#       Otherwise, perform a TYPE command with <typecode> as the argument,
+#       and then access the file whose name is <name> (for example, using
+#       the RETR command.)
+#
+#    Within a name or CWD component, the characters "/" and ";" are
+#    reserved and must be encoded. The components are decoded prior to
+#    their use in the FTP protocol.  In particular, if the appropriate FTP
+#    sequence to access a particular file requires supplying a string
+#    containing a "/" as an argument to a CWD or RETR command, it is
+#    necessary to encode each "/".
+#
+#    For example, the URL <URL:ftp://myname@host.dom/%2Fetc/motd> is
+#    interpreted by FTP-ing to "host.dom", logging in as "myname"
+#    (prompting for a password if it is asked for), and then executing
+#    "CWD /etc" and then "RETR motd". This has a different meaning from
+#    <URL:ftp://myname@host.dom/etc/motd> which would "CWD etc" and then
+#    "RETR motd"; the initial "CWD" might be executed relative to the
+#    default directory for "myname". On the other hand,
+#    <URL:ftp://myname@host.dom//etc/motd>, would "CWD " with a null
+#    argument, then "CWD etc", and then "RETR motd".
+#
+#    FTP URLs may also be used for other operations; for example, it is
+#    possible to update a file on a remote file server, or infer
+#    information about it from the directory listings. The mechanism for
+#    doing so is not spelled out here.
+#
+# 3.2.3. FTP Typecode is Optional
+#
+#    The entire ;type=<typecode> part of a FTP URL is optional. If it is
+#    omitted, the client program interpreting the URL must guess the
+#    appropriate mode to use. In general, the data content type of a file
+#    can only be guessed from the name, e.g., from the suffix of the name;
+#    the appropriate type code to be used for transfer of the file can
+#    then be deduced from the data content of the file.
+#
+# 3.2.4 Hierarchy
+#
+#    For some file systems, the "/" used to denote the hierarchical
+#    structure of the URL corresponds to the delimiter used to construct a
+#    file name hierarchy, and thus, the filename will look similar to the
+#    URL path. This does NOT mean that the URL is a Unix filename.
+#
+# 3.2.5. Optimization
+#
+#    Clients accessing resources via FTP may employ additional heuristics
+#    to optimize the interaction. For some FTP servers, for example, it
+#    may be reasonable to keep the control connection open while accessing
+#    multiple URLs from the same server. However, there is no common
+#    hierarchical model to the FTP protocol, so if a directory change
+#    command has been given, it is impossible in general to deduce what
+#    sequence should be given to navigate to another directory for a
+#    second retrieval, if the paths are different.  The only reliable
+#    algorithm is to disconnect and reestablish the control connection.
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/gopher.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/gopher.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/gopher.pm	(revision 20131)
@@ -0,0 +1,215 @@
+#
+# $Id$
+
+# Implementation of the gopher protocol (RFC 1436)
+#
+# This code is based on 'wwwgopher.pl,v 0.10 1994/10/17 18:12:34 shelden'
+# which in turn is a vastly modified version of Oscar's http'get()
+# dated 28/3/94 in <ftp://cui.unige.ch/PUBLIC/oscar/scripts/http.pl>
+# including contributions from Marc van Heyningen and Martijn Koster.
+#
+
+package LWP::Protocol::gopher;
+
+use strict;
+use vars qw(@ISA);
+
+require HTTP::Response;
+require HTTP::Status;
+require IO::Socket;
+require IO::Select;
+
+require LWP::Protocol;
+@ISA = qw(LWP::Protocol);
+
+
+my %gopher2mimetype = (
+    '0' => 'text/plain',                # 0 file
+    '1' => 'text/html',                 # 1 menu
+					# 2 CSO phone-book server
+					# 3 Error
+    '4' => 'application/mac-binhex40',  # 4 BinHexed Macintosh file
+    '5' => 'application/zip',           # 5 DOS binary archive of some sort
+    '6' => 'application/octet-stream',  # 6 UNIX uuencoded file.
+    '7' => 'text/html',                 # 7 Index-Search server
+					# 8 telnet session
+    '9' => 'application/octet-stream',  # 9 binary file
+    'h' => 'text/html',                 # html
+    'g' => 'image/gif',                 # gif
+    'I' => 'image/*',                   # some kind of image
+);
+
+my %gopher2encoding = (
+    '6' => 'x_uuencode',                # 6 UNIX uuencoded file.
+);
+
+sub request
+{
+    my($self, $request, $proxy, $arg, $size, $timeout) = @_;
+
+    LWP::Debug::trace('()');
+
+    $size = 4096 unless $size;
+
+    # check proxy
+    if (defined $proxy) {
+	return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,
+				   'You can not proxy through the gopher');
+    }
+
+    my $url = $request->url;
+    die "bad scheme" if $url->scheme ne 'gopher';
+
+
+    my $method = $request->method;
+    unless ($method eq 'GET' || $method eq 'HEAD') {
+	return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,
+				   'Library does not allow method ' .
+				   "$method for 'gopher:' URLs");
+    }
+
+    my $gophertype = $url->gtype;
+    unless (exists $gopher2mimetype{$gophertype}) {
+	return HTTP::Response->new(&HTTP::Status::RC_NOT_IMPLEMENTED,
+				   'Library does not support gophertype ' .
+				   $gophertype);
+    }
+
+    my $response = HTTP::Response->new(&HTTP::Status::RC_OK, "OK");
+    $response->header('Content-type' => $gopher2mimetype{$gophertype}
+					|| 'text/plain');
+    $response->header('Content-Encoding' => $gopher2encoding{$gophertype})
+	if exists $gopher2encoding{$gophertype};
+
+    if ($method eq 'HEAD') {
+	# XXX: don't even try it so we set this header
+	$response->header('Client-Warning' => 'Client answer only');
+	return $response;
+    }
+    
+    if ($gophertype eq '7' && ! $url->search) {
+      # the url is the prompt for a gopher search; supply boiler-plate
+      return $self->collect_once($arg, $response, <<"EOT");
+<HEAD>
+<TITLE>Gopher Index</TITLE>
+<ISINDEX>
+</HEAD>
+<BODY>
+<H1>$url<BR>Gopher Search</H1>
+This is a searchable Gopher index.
+Use the search function of your browser to enter search terms.
+</BODY>
+EOT
+    }
+
+    my $host = $url->host;
+    my $port = $url->port;
+
+    my $requestLine = "";
+
+    my $selector = $url->selector;
+    if (defined $selector) {
+	$requestLine .= $selector;
+	my $search = $url->search;
+	if (defined $search) {
+	    $requestLine .= "\t$search";
+	    my $string = $url->string;
+	    if (defined $string) {
+		$requestLine .= "\t$string";
+	    }
+	}
+    }
+    $requestLine .= "\015\012";
+
+    # potential request headers are just ignored
+
+    # Ok, lets make the request
+    my $socket = IO::Socket::INET->new(PeerAddr => $host,
+				       PeerPort => $port,
+				       Timeout  => $timeout);
+    die "Can't connect to $host:$port" unless $socket;
+    my $sel = IO::Select->new($socket);
+
+    {
+	die "write timeout" if $timeout && !$sel->can_write($timeout);
+	my $n = syswrite($socket, $requestLine, length($requestLine));
+	die $! unless defined($n);
+	die "short write" if $n != length($requestLine);
+    }
+
+    my $user_arg = $arg;
+
+    # must handle menus in a special way since they are to be
+    # converted to HTML.  Undefing $arg ensures that the user does
+    # not see the data before we get a change to convert it.
+    $arg = undef if $gophertype eq '1' || $gophertype eq '7';
+
+    # collect response
+    my $buf = '';
+    $response = $self->collect($arg, $response, sub {
+	die "read timeout" if $timeout && !$sel->can_read($timeout);
+        my $n = sysread($socket, $buf, $size);
+	die $! unless defined($n);
+	return \$buf;
+      } );
+
+    # Convert menu to HTML and return data to user.
+    if ($gophertype eq '1' || $gophertype eq '7') {
+	my $content = menu2html($response->content);
+	if (defined $user_arg) {
+	    $response = $self->collect_once($user_arg, $response, $content);
+	} else {
+	    $response->content($content);
+	}
+    }
+
+    $response;
+}
+
+
+sub gopher2url
+{
+    my($gophertype, $path, $host, $port) = @_;
+
+    my $url;
+
+    if ($gophertype eq '8' || $gophertype eq 'T') {
+	# telnet session
+	$url = URI::URL->new($gophertype eq '8' ? 'telnet:' : 'tn3270:');
+	$url->user($path) if defined $path;
+    } else {
+	$path = URI::Escape::uri_escape($path);
+	$url = URI::URL->new("gopher:/$gophertype$path");
+    }
+    $url->host($host);
+    $url->port($port);
+    $url;
+}
+
+sub menu2html {
+    my($menu) = @_;
+
+    $menu =~ s/\015//g;  # remove carriage return
+    my $tmp = <<"EOT";
+<HTML>
+<HEAD>
+   <TITLE>Gopher menu</TITLE>
+</HEAD>
+<BODY>
+<H1>Gopher menu</H1>
+EOT
+    for (split("\n", $menu)) {
+	last if /^\./;
+	my($pretty, $path, $host, $port) = split("\t");
+
+	$pretty =~ s/^(.)//;
+	my $type = $1;
+
+	my $url = gopher2url($type, $path, $host, $port)->as_string;
+	$tmp .= qq{<A HREF="$url">$pretty</A><BR>\n};
+    }
+    $tmp .= "</BODY>\n</HTML>\n";
+    $tmp;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/http.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/http.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/http.pm	(revision 20131)
@@ -0,0 +1,252 @@
+#
+# $Id$
+
+package LWP::Protocol::http;
+
+require LWP::Debug;
+require HTTP::Response;
+require HTTP::Status;
+require IO::Socket;
+require IO::Select;
+
+require LWP::Protocol;
+@ISA = qw(LWP::Protocol);
+
+use strict;
+my $CRLF         = "\015\012";     # how lines should be terminated;
+				   # "\r\n" is not correct on all systems, for
+				   # instance MacPerl defines it to "\012\015"
+
+sub _new_socket
+{
+    my($self, $host, $port, $timeout) = @_;
+
+    local($^W) = 0;  # IO::Socket::INET can be noisy
+    my $sock = IO::Socket::INET->new(PeerAddr => $host,
+				     PeerPort => $port,
+				     Proto    => 'tcp',
+				     Timeout  => $timeout,
+				    );
+    unless ($sock) {
+	# IO::Socket::INET leaves additional error messages in $@
+	$@ =~ s/^.*?: //;
+	die "Can't connect to $host:$port ($@)";
+    }
+    $sock;
+}
+
+
+sub _check_sock
+{
+    #my($self, $req, $sock) = @_;
+}
+
+sub _get_sock_info
+{
+    my($self, $res, $sock) = @_;
+    $res->header("Client-Peer" =>
+		 $sock->peerhost . ":" . $sock->peerport);
+}
+
+
+sub request
+{
+    my($self, $request, $proxy, $arg, $size, $timeout) = @_;
+    LWP::Debug::trace('()');
+
+    $size ||= 4096;
+
+    # check method
+    my $method = $request->method;
+    unless ($method =~ /^[A-Za-z0-9_!\#\$%&\'*+\-.^\`|~]+$/) {  # HTTP token
+	return new HTTP::Response &HTTP::Status::RC_BAD_REQUEST,
+				  'Library does not allow method ' .
+				  "$method for 'http:' URLs";
+    }
+
+    my $url = $request->url;
+    my($host, $port, $fullpath);
+
+    # Check if we're proxy'ing
+    if (defined $proxy) {
+	# $proxy is an URL to an HTTP server which will proxy this request
+	$host = $proxy->host;
+	$port = $proxy->port;
+	$fullpath = $url->as_string;
+    }
+    else {
+	$host = $url->host;
+	$port = $url->port;
+	$fullpath = $url->full_path;
+    }
+
+    # connect to remote site
+    my $socket = $self->_new_socket($host, $port, $timeout);
+    $self->_check_sock($request, $socket);
+	    
+    my $sel = IO::Select->new($socket) if $timeout;
+
+    my $request_line = "$method $fullpath HTTP/1.0$CRLF";
+
+    my $h = $request->headers->clone;
+    my $cont_ref = $request->content_ref;
+    $cont_ref = $$cont_ref if ref($$cont_ref);
+    my $ctype = ref($cont_ref);
+
+    # If we're sending content we *have* to specify a content length
+    # otherwise the server won't know a messagebody is coming.
+    if ($ctype eq 'CODE') {
+	die 'No Content-Length header for request with dynamic content'
+	    unless defined($h->header('Content-Length')) ||
+		   $h->content_type =~ /^multipart\//;
+	# For HTTP/1.1 we could have used chunked transfer encoding...
+    } else {
+	$h->header('Content-Length' => length $$cont_ref)
+	        if defined($$cont_ref) && length($$cont_ref);
+    }
+    
+    # HTTP/1.1 will require us to send the 'Host' header, so we might
+    # as well start now.
+    my $hhost = $url->netloc;
+    $hhost =~ s/^([^\@]*)\@//;  # get rid of potential "user:pass@"
+    $h->header('Host' => $hhost) unless defined $h->header('Host');
+
+    # add authorization header if we need them.  HTTP URLs do
+    # not really support specification of user and password, but
+    # we allow it.
+    if (defined($1) && not $h->header('Authorization')) {
+	$h->authorization_basic($url->user, $url->password);
+    }
+
+    my $buf = $request_line . $h->as_string($CRLF) . $CRLF;
+    my $n;  # used for return value from syswrite/sysread
+
+    die "write timeout" if $timeout && !$sel->can_write($timeout);
+    $n = $socket->syswrite($buf, length($buf));
+    die $! unless defined($n);
+    die "short write" unless $n == length($buf);
+    LWP::Debug::conns($buf);
+
+    if ($ctype eq 'CODE') {
+	while ( ($buf = &$cont_ref()), defined($buf) && length($buf)) {
+	    die "write timeout" if $timeout && !$sel->can_write($timeout);
+	    $n = $socket->syswrite($buf, length($buf));
+	    die $! unless defined($n);
+	    die "short write" unless $n == length($buf);
+	    LWP::Debug::conns($buf);
+	}
+    } elsif (defined($$cont_ref) && length($$cont_ref)) {
+	die "write timeout" if $timeout && !$sel->can_write($timeout);
+	$n = $socket->syswrite($$cont_ref, length($$cont_ref));
+	die $! unless defined($n);
+	die "short write" unless $n == length($$cont_ref);
+	LWP::Debug::conns($buf);
+    }
+    
+    # read response line from server
+    LWP::Debug::debug('reading response');
+
+    my $response;
+    $buf = '';
+
+    # Inside this loop we will read the response line and all headers
+    # found in the response.
+    while (1) {
+	{
+	    die "read timeout" if $timeout && !$sel->can_read($timeout);
+	    $n = $socket->sysread($buf, $size, length($buf));
+	    die $! unless defined($n);
+	    die "unexpected EOF before status line seen" unless $n;
+	    LWP::Debug::conns($buf);
+	}
+	if ($buf =~ s/^(HTTP\/\d+\.\d+)[ \t]+(\d+)[ \t]*([^\012]*)\012//) {
+	    # HTTP/1.0 response or better
+	    my($ver,$code,$msg) = ($1, $2, $3);
+	    $msg =~ s/\015$//;
+	    LWP::Debug::debug("$ver $code $msg");
+	    $response = HTTP::Response->new($code, $msg);
+	    $response->protocol($ver);
+
+	    # ensure that we have read all headers.  The headers will be
+	    # terminated by two blank lines
+	    until ($buf =~ /^\015?\012/ || $buf =~ /\015?\012\015?\012/) {
+		# must read more if we can...
+		LWP::Debug::debug("need more header data");
+		die "read timeout" if $timeout && !$sel->can_read($timeout);
+		$n = $socket->sysread($buf, $size, length($buf));
+		die $! unless defined($n);
+		die "unexpected EOF before all headers seen" unless $n;
+		#LWP::Debug::conns($buf);
+	    }
+
+	    # now we start parsing the headers.  The strategy is to
+	    # remove one line at a time from the beginning of the header
+	    # buffer ($res).
+	    my($key, $val);
+	    while ($buf =~ s/([^\012]*)\012//) {
+		my $line = $1;
+
+		# if we need to restore as content when illegal headers
+		# are found.
+		my $save = "$line\012"; 
+
+		$line =~ s/\015$//;
+		last unless length $line;
+
+		if ($line =~ /^([a-zA-Z0-9_\-]+)\s*:\s*(.*)/) {
+		    $response->push_header($key, $val) if $key;
+		    ($key, $val) = ($1, $2);
+		} elsif ($line =~ /^\s+(.*)/) {
+		    unless ($key) {
+			$response->header("Client-Warning" =>
+					 => "Illegal continuation header");
+			$buf = "$save$buf";
+			last;
+		    }
+		    $val .= " $1";
+		} else {
+		    $response->header("Client-Warning" =>
+				      "Illegal header '$line'");
+		    $buf = "$save$buf";
+		    last;
+		}
+	    }
+	    $response->push_header($key, $val) if $key;
+	    last;
+
+	} elsif ((length($buf) >= 5 and $buf !~ /^HTTP\//) or
+		 $buf =~ /\012/ ) {
+	    # HTTP/0.9 or worse
+	    LWP::Debug::debug("HTTP/0.9 assume OK");
+	    $response = HTTP::Response->new(&HTTP::Status::RC_OK, "OK");
+	    $response->protocol('HTTP/0.9');
+	    last;
+
+	} else {
+	    # need more data
+	    LWP::Debug::debug("need more status line data");
+	}
+    };
+    $response->request($request);
+    $self->_get_sock_info($response, $socket);
+
+
+    my $usebuf = length($buf) > 0;
+    $response = $self->collect($arg, $response, sub {
+        if ($usebuf) {
+	    $usebuf = 0;
+	    return \$buf;
+	}
+	die "read timeout" if $timeout && !$sel->can_read($timeout);
+	my $n = $socket->sysread($buf, $size);
+	die $! unless defined($n);
+	#LWP::Debug::conns($buf);
+	return \$buf;
+	} );
+
+    $socket->close;
+
+    $response;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/https.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/https.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/https.pm	(revision 20131)
@@ -0,0 +1,59 @@
+#
+# $Id$
+
+use strict;
+
+package LWP::Protocol::https;
+require Net::SSL;  # from Crypt-SSLeay
+
+use vars qw(@ISA);
+
+require LWP::Protocol::http;
+@ISA=qw(LWP::Protocol::http);
+
+sub _new_socket
+{
+    my($self, $host, $port, $timeout) = @_;
+    local($^W) = 0;  # IO::Socket::INET can be noisy
+    my $sock = Net::SSL->new(PeerAddr => $host,
+			     PeerPort => $port,
+			     Proto    => 'tcp',
+			     Timeout  => $timeout,
+			    );
+    unless ($sock) {
+	# IO::Socket::INET leaves additional error messages in $@
+	$@ =~ s/^.*?: //;
+	die "Can't connect to $host:$port ($@)";
+    }
+    $sock;
+}
+
+sub _check_sock
+{
+    my($self, $req, $sock) = @_;
+    my $check = $req->header("If-SSL-Cert-Subject");
+    if (defined $check) {
+	my $cert = $sock->get_peer_certificate ||
+	    die "Missing SSL certificate";
+	my $subject = $cert->subject_name;
+	die "Bad SSL certificate subject: '$subject' !~ /$check/"
+	    unless $subject =~ /$check/;
+	$req->remove_header("If-SSL-Cert-Subject");  # don't pass it on
+    }
+}
+
+sub _get_sock_info
+{
+    my $self = shift;
+    $self->SUPER::_get_sock_info(@_);
+    my($res, $sock) = @_;
+    $res->header("Client-SSL-Cipher" => $sock->get_cipher);
+    my $cert = $sock->get_peer_certificate;
+    if ($cert) {
+	$res->header("Client-SSL-Cert-Subject" => $cert->subject_name);
+	$res->header("Client-SSL-Cert-Issuer" => $cert->issuer_name);
+    }
+    $res->header("Client-SSL-Warning" => "Peer certificate not verified");
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/mailto.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/mailto.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/mailto.pm	(revision 20131)
@@ -0,0 +1,87 @@
+#
+# $Id$
+#
+# This module implements the mailto protocol.  It is just a simple
+# frontend to the Unix sendmail program.  In the long run this module
+# will built using the Mail::Send module.
+
+package LWP::Protocol::mailto;
+
+require LWP::Protocol;
+require HTTP::Request;
+require HTTP::Response;
+require HTTP::Status;
+
+use Carp;
+
+@ISA = qw(LWP::Protocol);
+
+$SENDMAIL = "/usr/lib/sendmail";
+
+
+sub request
+{
+    my($self, $request, $proxy, $arg, $size) = @_;
+
+    # check proxy
+    if (defined $proxy)
+    {
+	return new HTTP::Response &HTTP::Status::RC_BAD_REQUEST,
+				  'You can not proxy with mail';
+    }
+
+    # check method
+    $method = $request->method;
+
+    if ($method ne 'POST') {
+	return new HTTP::Response &HTTP::Status::RC_BAD_REQUEST,
+				  'Library does not allow method ' .
+				  "$method for 'mailto:' URLs";
+    }
+
+    # check url
+    my $url = $request->url;
+
+    my $scheme = $url->scheme;
+    if ($scheme ne 'mailto') {
+	return new HTTP::Response &HTTP::Status::RC_INTERNAL_SERVER_ERROR,
+				  "LWP::file::request called for '$scheme'";
+    }
+    unless (-x $SENDMAIL) {
+	return new HTTP::Response &HTTP::Status::RC_INTERNAL_SERVER_ERROR,
+				  "You don't have $SENDMAIL";
+    }
+
+    open(SENDMAIL, "| $SENDMAIL -oi -t") or
+	return new HTTP::Response &HTTP::Status::RC_INTERNAL_SERVER_ERROR,
+				  "Can't run $SENDMAIL: $!";
+
+    my $addr = $url->encoded822addr;
+
+    $request->header('To', $addr);
+    print SENDMAIL $request->headers_as_string;
+    print SENDMAIL "\n";
+    my $content = $request->content;
+    if (defined $content) {
+	my $contRef = ref($content) ? $content : \$content;
+	if (ref($contRef) eq 'SCALAR') {
+	    print SENDMAIL $$contRef;
+	} elsif (ref($contRef) eq 'CODE') {
+	    # Callback provides data
+	    my $d;
+	    while (length($d = &$contRef)) {
+		print SENDMAIL $d;
+	    }
+	}
+    }
+    close(SENDMAIL);
+
+    my $response = new HTTP::Response &HTTP::Status::RC_ACCEPTED,
+				     'Mail accepted by sendmail';
+    $response->header('Content-Type', 'text/plain');
+    $response->content("Mail sent to <$addr>\n");
+
+    return $response;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/nntp.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/nntp.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Protocol/nntp.pm	(revision 20131)
@@ -0,0 +1,142 @@
+#
+# $Id$
+
+# Implementation of the Network News Transfer Protocol (RFC 977)
+#
+
+package LWP::Protocol::nntp;
+
+require LWP::Protocol;
+@ISA = qw(LWP::Protocol);
+
+require LWP::Debug;
+require HTTP::Response;
+require HTTP::Status;
+require Net::NNTP;
+
+use strict;
+
+
+sub request
+{
+    my($self, $request, $proxy, $arg, $size, $timeout) = @_;
+
+    LWP::Debug::trace('()');
+
+    $size = 4096 unless $size;
+
+    # Check for proxy
+    if (defined $proxy) {
+	return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,
+				   'You can not proxy through NNTP');
+    }
+
+    # Check that the scheme is as expected
+    my $url = $request->url;
+    my $scheme = $url->scheme;
+    unless ($scheme eq 'news') {
+	return HTTP::Response->new(&HTTP::Status::RC_INTERNAL_SERVER_ERROR,
+				   "LWP::Protocol::nntp::request called for '$scheme'");
+    }
+
+    # check for a valid method
+    my $method = $request->method;
+    unless ($method eq 'GET' || $method eq 'HEAD' || $method eq 'POST') {
+	return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,
+				   'Library does not allow method ' .
+				   "$method for 'news:' URLs");
+    }
+
+    # extract the identifier and check against posting to an article
+    my $groupart = $url->groupart;
+    my $is_art = $groupart =~ /@/;
+
+    if ($is_art && $method eq 'POST') {
+	return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST,
+				   "Can't post to an article <$groupart>");
+    }
+
+    my $nntp = Net::NNTP->new(undef,
+			      #Port    => 18574,
+			      Timeout => $timeout,
+			      #Debug   => 1,
+			     );
+    die "Can't connect to nntp server" unless $nntp;
+
+    # Check the initial welcome message from the NNTP server
+    if ($nntp->status != 2) {
+	return HTTP::Response->new(&HTTP::Status::RC_SERVICE_UNAVAILABLE,
+				   $nntp->message);
+    }
+    my $response = HTTP::Response->new(&HTTP::Status::RC_OK, "OK");
+
+    my $mess = $nntp->message;
+    LWP::Debug::debug($mess);
+
+    # Try to extract server name from greating message.
+    # Don't know if this works well for a large class of servers, but
+    # this works for our server.
+    $mess =~ s/\s+ready\b.*//;
+    $mess =~ s/^\S+\s+//;
+    $response->header(Server => $mess);
+
+
+    # First we handle posting of articles
+    if ($method eq 'POST') {
+	return HTTP::Response->new(&HTTP::Status::RC_NOT_IMPLEMENTED,
+				   "POST not implemented yet");
+    }
+
+    # The method must be "GET" or "HEAD" by now
+    if (!$is_art) {
+	if (!$nntp->group($groupart)) {
+	    return HTTP::Response->new(&HTTP::Status::RC_NOT_FOUND,
+				       $nntp->message);
+	}
+	return HTTP::Response->new(&HTTP::Status::RC_NOT_IMPLEMENTED,
+				   "GET newsgroup not implemented yet");
+    }
+
+    # Send command to server to retrieve an article (or just the headers)
+    my $get = $method eq 'HEAD' ? "head" : "article";
+    my $art = $nntp->$get("<$groupart>");
+    unless ($art) {
+	return HTTP::Response->new(&HTTP::Status::RC_NOT_FOUND,
+				   $nntp->message);
+    }
+    LWP::Debug::debug($nntp->message);
+    
+    # Parse headers
+    my($key, $val);
+    while ($_ = shift @$art) {
+	if (/^\s+$/) {
+	    last;  # end of headers
+	} elsif (/^(\S+):\s*(.*)/) {
+	    $response->push_header($key, $val) if $key;
+	    ($key, $val) = ($1, $2);
+	} elsif (/^\s+(.*)/) {
+	    next unless $key;
+	    $val .= $1;
+	} else {
+	    unshift(@$art, $_);
+	    last;
+	}
+    }
+    $response->push_header($key, $val) if $key;
+
+    # Ensure that there is a Content-Type header
+    $response->header("Content-Type", "text/plain")
+	unless $response->header("Content-Type");
+
+    # Collect the body
+    $response = $self->collect_once($arg, $response, join("", @$art))
+      if @$art;
+
+    # Say godbye to the server
+    $nntp->quit;
+    $nntp = undef;
+
+    $response;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/RobotUA.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/RobotUA.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/RobotUA.pm	(revision 20131)
@@ -0,0 +1,285 @@
+# $Id$
+
+package LWP::RobotUA;
+
+require LWP::UserAgent;
+@ISA = qw(LWP::UserAgent);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+require WWW::RobotRules;
+require HTTP::Request;
+require HTTP::Response;
+
+use Carp ();
+use LWP::Debug ();
+use HTTP::Status ();
+use HTTP::Date qw(time2str);
+use strict;
+
+=head1 NAME
+
+LWP::RobotUA - A class for Web Robots
+
+=head1 SYNOPSIS
+
+  require LWP::RobotUA;
+  $ua = new LWP::RobotUA 'my-robot/0.1', 'me@foo.com';
+  $ua->delay(10);  # be very nice, go slowly
+  ...
+  # just use it just like a normal LWP::UserAgent
+  $res = $ua->request($req);
+
+=head1 DESCRIPTION
+
+This class implements a user agent that is suitable for robot
+applications.  Robots should be nice to the servers they visit.  They
+should consult the F<robots.txt> file to ensure that they are welcomed
+and they should not send too frequent requests.
+
+But, before you consider writing a robot take a look at
+<URL:http://info.webcrawler.com/mak/projects/robots/robots.html>.
+
+When you use a I<LWP::RobotUA> as your user agent, then you do not
+really have to think about these things yourself.  Just send requests
+as you do when you are using a normal I<LWP::UserAgent> and this
+special agent will make sure you are nice.
+
+=head1 METHODS
+
+The LWP::RobotUA is a sub-class of LWP::UserAgent and implements the
+same methods. In addition the following methods are provided:
+
+=over 4
+
+=cut
+
+
+#
+# Additional attributes in addition to those found in LWP::UserAgent:
+#
+# $self->{'delay'}    Required delay between request to the same
+#                     server in minutes.
+#
+# $self->{'rules'}     A WWW::RobotRules object
+#
+
+
+=item $ua = LWP::RobotUA->new($agent_name, $from, [$rules])
+
+Your robot's name and the mail address of the human responsible for
+the robot (i.e. you) is required by the constructor.
+
+Optionally it allows you to specify the I<WWW::RobotRules> object to
+use.
+
+=cut
+
+sub new
+{
+    my($class,$name,$from,$rules) = @_;
+
+    Carp::croak('LWP::RobotUA name required') unless $name;
+    Carp::croak('LWP::RobotUA from address required') unless $from;
+
+    my $self = new LWP::UserAgent;
+    $self = bless $self, $class;
+
+    $self->{'delay'} = 1;   # minutes
+    $self->{'agent'} = $name;
+    $self->{'from'}  = $from;
+    $self->{'use_sleep'} = 1;
+
+    if ($rules) {
+	$rules->agent($name);
+	$self->{'rules'} = $rules;
+    } else {
+	$self->{'rules'} = new WWW::RobotRules $name;
+    }
+
+    $self;
+}
+
+
+=item $ua->delay([$minutes])
+
+Set the minimum delay between requests to the same server.  The
+default is 1 minute.
+
+=item $ua->use_sleep([$boolean])
+
+Get/set a value indicating wether the UA should sleep() if request
+arrive to fast (before $ua->delay minutes has passed).  The default is
+TRUE.  If this value is FALSE then an internal SERVICE_UNAVAILABLE
+response will be generated.  It will have an Retry-After header that
+indicate when it is OK to send another request to this server.
+
+=cut
+
+sub delay     { shift->_elem('delay',     @_); }
+sub use_sleep { shift->_elem('use_sleep', @_); }
+
+sub agent
+{
+    my $self = shift;
+    my $old = $self->SUPER::agent(@_);
+    if (@_) {
+	# Changing our name means to start fresh
+	$self->{'rules'}->agent($self->{'agent'}); 
+    }
+    $old;
+}
+
+
+=item $ua->rules([$rules])
+
+Set/get which I<WWW::RobotRules> object to use. 
+
+=cut
+
+sub rules {
+    my $self = shift;
+    my $old = $self->_elem('rules', @_);
+    $self->{'rules'}->agent($self->{'agent'}) if @_;
+    $old;
+}
+
+
+=item $ua->no_visits($netloc)
+
+Returns the number of documents fetched from this server host. Yes I
+know, this method should probably have been named num_visits() or
+something like that :-(
+
+=cut
+
+sub no_visits
+{
+    my($self, $netloc) = @_;
+    $self->{'rules'}->no_visits($netloc);
+}
+
+*host_count = \&no_visits;  # backwards compatibility with LWP-5.02
+
+
+=item $ua->host_wait($netloc)
+
+Returns the number of seconds (from now) you must wait before you can
+make a new request to this host.
+
+=cut
+
+sub host_wait
+{
+    my($self, $netloc) = @_;
+    return undef unless defined $netloc;
+    my $last = $self->{'rules'}->last_visit($netloc);
+    if ($last) {
+	my $wait = int($self->{'delay'} * 60 - (time - $last));
+	$wait = 0 if $wait < 0;
+	return $wait;
+    }
+    return 0;
+}
+
+
+sub simple_request
+{
+    my($self, $request, $arg, $size) = @_;
+
+    LWP::Debug::trace('()');
+
+    # Do we try to access a new server?
+    my $allowed = $self->{'rules'}->allowed($request->url);
+
+    if ($allowed < 0) {
+	LWP::Debug::debug("Host is not visited before, or robots.txt expired.");
+	# fetch "robots.txt"
+	my $robot_url = $request->url->clone;
+	$robot_url->path("robots.txt");
+	$robot_url->params(undef);
+	$robot_url->query(undef);
+	LWP::Debug::debug("Requesting $robot_url");
+
+	# make access to robot.txt legal since this will be a recursive call
+	$self->{'rules'}->parse($robot_url, ""); 
+
+	my $robot_req = new HTTP::Request 'GET', $robot_url;
+	my $robot_res = $self->request($robot_req);
+	my $fresh_until = $robot_res->fresh_until;
+	if ($robot_res->is_success) {
+	    LWP::Debug::debug("Parsing robot rules");
+	    $self->{'rules'}->parse($robot_url, $robot_res->content, 
+				    $fresh_until);
+	} else {
+	    LWP::Debug::debug("No robots.txt file found");
+	    $self->{'rules'}->parse($robot_url, "", $fresh_until);
+	}
+
+	# recalculate allowed...
+	$allowed = $self->{'rules'}->allowed($request->url);
+    }
+
+    # Check rules
+    unless ($allowed) {
+	return new HTTP::Response
+	  &HTTP::Status::RC_FORBIDDEN, 'Forbidden by robots.txt';
+    }
+
+    my $netloc = $request->url->netloc;
+    my $wait = $self->host_wait($netloc);
+
+    if ($wait) {
+	LWP::Debug::debug("Must wait $wait seconds");
+	if ($self->{'use_sleep'}) {
+	    sleep($wait)
+	} else {
+	    my $res = new HTTP::Response
+	      &HTTP::Status::RC_SERVICE_UNAVAILABLE, 'Please, slow down';
+	    $res->header('Retry-After', time2str(time + $wait));
+	    return $res;
+	}
+    }
+
+    # Perform the request
+    my $res = $self->SUPER::simple_request($request, $arg, $size);
+
+    $self->{'rules'}->visit($netloc);
+
+    $res;
+}
+
+
+=item $ua->as_string
+
+Returns a text that describe the state of the UA.
+Mainly useful for debugging.
+
+=cut
+
+sub as_string
+{
+    my $self = shift;
+    my @s;
+    push(@s, "Robot: $self->{'agent'} operated by $self->{'from'}  [$self]");
+    push(@s, "    Minimum delay: " . int($self->{'delay'}*60) . "s");
+    push(@s, "    Will sleep if too early") if $self->{'use_sleep'};
+    push(@s, "    Rules = $self->{'rules'}");
+    join("\n", @s, '');
+}
+
+1;
+
+=back
+
+=head1 SEE ALSO
+
+L<LWP::UserAgent>, L<WWW::RobotRules>
+
+=head1 COPYRIGHT
+
+Copyright 1996-1997 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Simple.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Simple.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/Simple.pm	(revision 20131)
@@ -0,0 +1,329 @@
+#
+# $Id$
+
+=head1 NAME
+
+get, head, getprint, getstore, mirror - Procedural LWP interface
+
+=head1 SYNOPSIS
+
+ perl -MLWP::Simple -e 'getprint "http://www.sn.no"'
+
+ use LWP::Simple;
+ $content = get("http://www.sn.no/")
+ if (mirror("http://www.sn.no/", "foo") == RC_NOT_MODIFIED) {
+     ...
+ }
+
+ if (is_success(getprint("http://www.sn.no/"))) {
+     ...
+ }
+
+=head1 DESCRIPTION
+
+This interface is intended for those who want a simplified view of the
+libwww-perl library.  It should also be suitable for one-liners.  If
+you need more control or access to the header fields in the requests
+sent and responses received you should use the full object oriented
+interface provided by the C<LWP::UserAgent> module.
+
+The following functions are provided (and exported) by this module:
+
+=over 3
+
+=item get($url)
+
+The get() function will fetch the document identified by the given URL
+and return it.  It returns C<undef> if it fails.  The $url argument can
+be either a simple string or a reference to a URI::URL object.
+
+You will not be able to examine the response code or response headers
+(like 'Content-Type') when you are accessing the web using this
+function.  If you need this information you should use the full OO
+interface (see L<LWP::UserAgent>).
+
+=item head($url)
+
+Get document headers. Returns the following 5 values if successful:
+($content_type, $document_length, $modified_time, $expires, $server)
+
+Returns an empty list if it fails.  In scalar context returns TRUE if
+successful.
+
+=item getprint($url)
+
+Get and print a document identified by a URL. The document is printed
+on STDOUT as data is received from the network.  If the request fails,
+then the status code and message is printed on STDERR.  The return
+value is the HTTP response code.
+
+=item getstore($url, $file)
+
+Gets a document identified by a URL and stores it in the file. The
+return value is the HTTP response code.
+
+=item mirror($url, $file)
+
+Get and store a document identified by a URL, using
+I<If-modified-since>, and checking of the I<Content-Length>.  Returns
+the HTTP response code.
+
+=back
+
+This module also exports the HTTP::Status constants and procedures.
+These can be used when you check the response code from getprint(),
+getstore() and mirror().  The constants are:
+
+   RC_CONTINUE
+   RC_SWITCHING_PROTOCOLS
+   RC_OK
+   RC_CREATED
+   RC_ACCEPTED
+   RC_NON_AUTHORITATIVE_INFORMATION
+   RC_NO_CONTENT
+   RC_RESET_CONTENT
+   RC_PARTIAL_CONTENT
+   RC_MULTIPLE_CHOICES
+   RC_MOVED_PERMANENTLY
+   RC_MOVED_TEMPORARILY
+   RC_SEE_OTHER
+   RC_NOT_MODIFIED
+   RC_USE_PROXY
+   RC_BAD_REQUEST
+   RC_UNAUTHORIZED
+   RC_PAYMENT_REQUIRED
+   RC_FORBIDDEN
+   RC_NOT_FOUND
+   RC_METHOD_NOT_ALLOWED
+   RC_NOT_ACCEPTABLE
+   RC_PROXY_AUTHENTICATION_REQUIRED
+   RC_REQUEST_TIMEOUT
+   RC_CONFLICT
+   RC_GONE
+   RC_LENGTH_REQUIRED
+   RC_PRECONDITION_FAILED
+   RC_REQUEST_ENTITY_TOO_LARGE
+   RC_REQUEST_URI_TOO_LARGE
+   RC_UNSUPPORTED_MEDIA_TYPE
+   RC_INTERNAL_SERVER_ERROR
+   RC_NOT_IMPLEMENTED
+   RC_BAD_GATEWAY
+   RC_SERVICE_UNAVAILABLE
+   RC_GATEWAY_TIMEOUT
+   RC_HTTP_VERSION_NOT_SUPPORTED
+
+The HTTP::Status classification functions are:
+
+=over 3
+
+=item is_success($rc)
+
+Check if response code indicated successfull request.
+
+=item is_error($rc)
+
+Check if response code indicated that an error occured.
+
+=back
+
+The module will also export the LWP::UserAgent object as C<$ua> if you
+ask for it explicitly.
+
+The user agent created by this module will identify itself as
+"LWP::Simple/#.##" (where "#.##" is the libwww-perl version number)
+and will initialize its proxy defaults from the environment (by
+calling $ua->env_proxy).
+
+=head1 SEE ALSO
+
+L<LWP>, L<LWP::UserAgent>, L<HTTP::Status>, L<lwp-request>,
+L<lwp-mirror>
+
+=cut
+
+
+package LWP::Simple;
+
+use strict;
+use vars qw($ua %loop_check $FULL_LWP @EXPORT @EXPORT_OK $VERSION);
+
+require Exporter;
+
+@EXPORT = qw(get head getprint getstore mirror);
+@EXPORT_OK = qw($ua);
+
+# I really hate this.  I was a bad idea to do it in the first place.
+# Wonder how to get rid of it???  (It even makes LWP::Simple 7% slower
+# for trivial tests)
+use HTTP::Status;
+push(@EXPORT, @HTTP::Status::EXPORT);
+
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+$FULL_LWP++ if grep {lc($_) eq "http_proxy"} keys %ENV;
+
+
+sub import
+{
+    my $pkg = shift;
+    my $callpkg = caller;
+    if (grep $_ eq '$ua', @_) {
+	$FULL_LWP++;
+	_init_ua();
+    }
+    Exporter::export($pkg, $callpkg, @_);
+}
+
+
+sub _init_ua
+{
+    require LWP;
+    require LWP::UserAgent;
+    require HTTP::Status;
+    require HTTP::Date;
+    $ua = new LWP::UserAgent;  # we create a global UserAgent object
+    my $ver = $LWP::VERSION = $LWP::VERSION;  # avoid warning
+    $ua->agent("LWP::Simple/$LWP::VERSION");
+    $ua->env_proxy;
+}
+
+
+sub get ($)
+{
+    %loop_check = ();
+    goto \&_get;
+}
+
+
+sub get_old ($)
+{
+    my($url) = @_;
+    _init_ua() unless $ua;
+
+    my $request = HTTP::Request->new(GET => $url);
+    my $response = $ua->request($request);
+
+    return $response->content if $response->is_success;
+    return undef;
+}
+
+
+sub head ($)
+{
+    my($url) = @_;
+    _init_ua() unless $ua;
+
+    my $request = HTTP::Request->new(HEAD => $url);
+    my $response = $ua->request($request);
+
+    if ($response->is_success) {
+	return $response unless wantarray;
+	return ($response->header('Content-Type'),
+		$response->header('Content-Length'),
+		HTTP::Date::str2time($response->header('Last-Modified')),
+		HTTP::Date::str2time($response->header('Expires')),
+		$response->header('Server'),
+	       );
+    }
+    return;
+}
+
+
+sub getprint ($)
+{
+    my($url) = @_;
+    _init_ua() unless $ua;
+
+    my $request = HTTP::Request->new(GET => $url);
+    local($\) = ""; # ensure standard $OUTPUT_RECORD_SEPARATOR
+    my $response = $ua->request($request, sub { print $_[0] });
+    unless ($response->is_success) {
+	print STDERR $response->status_line, " <URL:$url>\n";
+    }
+    $response->code;
+}
+
+
+sub getstore ($$)
+{
+    my($url, $file) = @_;
+    _init_ua() unless $ua;
+
+    my $request = HTTP::Request->new(GET => $url);
+    my $response = $ua->request($request, $file);
+
+    $response->code;
+}
+
+
+sub mirror ($$)
+{
+    my($url, $file) = @_;
+    _init_ua() unless $ua;
+    my $response = $ua->mirror($url, $file);
+    $response->code;
+}
+
+
+sub _get
+{
+    my $url = shift;
+    my $ret;
+    if (!$FULL_LWP && $url =~ m,^http://([^/:]+)(?::(\d+))?(/\S*)?$,) {
+	my $host = $1;
+	my $port = $2 || 80;
+	my $path = $3;
+	$path = "/" unless defined($path);
+	return _trivial_http_get($host, $port, $path);
+    } else {
+        _init_ua() unless $ua;
+	my $request = HTTP::Request->new(GET => $url);
+	my $response = $ua->request($request);
+	return $response->is_success ? $response->content : undef;
+    }
+}
+
+
+sub _trivial_http_get
+{
+   my($host, $port, $path) = @_;
+   #print "HOST=$host, PORT=$port, PATH=$path\n";
+
+   require IO::Socket;
+   local($^W) = 0;
+   my $sock = IO::Socket::INET->new(PeerAddr => $host,
+                                    PeerPort => $port,
+                                    Proto    => 'tcp',
+                                    Timeout  => 60) || return;
+   $sock->autoflush;
+   my $netloc = $host;
+   $netloc .= ":$port" if $port != 80;
+   print $sock join("\015\012" =>
+                    "GET $path HTTP/1.0",
+                    "Host: $netloc",
+                    "User-Agent: lwp-trivial/$VERSION",
+                    "", "");
+
+   my $buf = "";
+   my $n;
+   1 while $n = sysread($sock, $buf, 8*1024, length($buf));
+   return undef unless defined($n);
+
+   if ($buf =~ m,^HTTP/\d+\.\d+\s+(\d+)[^\012]*\012,) {
+       my $code = $1;
+       #print "CODE=$code\n$buf\n";
+       if ($code =~ /^30[1237]/ && $buf =~ /\012Location:\s*(\S+)/) {
+           # redirect
+           my $url = $1;
+           return undef if $loop_check{$url}++;
+           return _get($url);
+       }
+       return undef unless $code =~ /^2/;
+       $buf =~ s/.+?\015?\012\015?\012//s;  # zap header
+   }
+
+   return $buf;
+}
+
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/UserAgent.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/UserAgent.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/UserAgent.pm	(revision 20131)
@@ -0,0 +1,732 @@
+# $Id$
+
+package LWP::UserAgent;
+use strict;
+
+=head1 NAME
+
+LWP::UserAgent - A WWW UserAgent class
+
+=head1 SYNOPSIS
+
+ require LWP::UserAgent;
+ $ua = new LWP::UserAgent;
+
+ $request = new HTTP::Request('GET', 'file://localhost/etc/motd');
+
+ $response = $ua->request($request); # or
+ $response = $ua->request($request, '/tmp/sss'); # or
+ $response = $ua->request($request, \&callback, 4096);
+
+ sub callback { my($data, $response, $protocol) = @_; .... }
+
+=head1 DESCRIPTION
+
+The C<LWP::UserAgent> is a class implementing a simple World-Wide Web
+user agent in Perl. It brings together the HTTP::Request,
+HTTP::Response and the LWP::Protocol classes that form the rest of the
+core of libwww-perl library. For simple uses this class can be used
+directly to dispatch WWW requests, alternatively it can be subclassed
+for application-specific behaviour.
+
+In normal usage the application creates a UserAgent object, and then
+configures it with values for timeouts proxies, name, etc. The next
+step is to create an instance of C<HTTP::Request> for the request that
+needs to be performed. This request is then passed to the UserAgent
+request() method, which dispatches it using the relevant protocol,
+and returns a C<HTTP::Response> object.
+
+The basic approach of the library is to use HTTP style communication
+for all protocol schemes, i.e. you will receive an C<HTTP::Response>
+object also for gopher or ftp requests.  In order to achieve even more
+similarities with HTTP style communications, gopher menus and file
+directories will be converted to HTML documents.
+
+The request() method can process the content of the response in one of
+three ways: in core, into a file, or into repeated calls of a
+subroutine.  You choose which one by the kind of value passed as the
+second argument to request().
+
+The in core variant simply returns the content in a scalar attribute
+called content() of the response object, and is suitable for small
+HTML replies that might need further parsing.  This variant is used if
+the second argument is missing (or is undef).
+
+The filename variant requires a scalar containing a filename as the
+second argument to request(), and is suitable for large WWW objects
+which need to be written directly to the file, without requiring large
+amounts of memory. In this case the response object returned from
+request() will have empty content().  If the request fails, then the
+content() might not be empty, and the file will be untouched.
+
+The subroutine variant requires a reference to callback routine as the
+second argument to request() and it can also take an optional chuck
+size as third argument.  This variant can be used to construct
+"pipe-lined" processing, where processing of received chuncks can
+begin before the complete data has arrived.  The callback function is
+called with 3 arguments: the data received this time, a reference to
+the response object and a reference to the protocol object.  The
+response object returned from request() will have empty content().  If
+the request fails, then the the callback routine will not have been
+called, and the response->content() might not be empty.
+
+The request can be aborted by calling die() within the callback
+routine.  The die message will be available as the "X-Died" special
+response header field.
+
+The library also accepts that you put a subroutine reference as
+content in the request object.  This subroutine should return the
+content (possibly in pieces) when called.  It should return an empty
+string when there is no more content.
+
+=head1 METHODS
+
+The following methods are available:
+
+=over 4
+
+=cut
+
+
+use vars qw(@ISA $VERSION);
+
+require LWP::MemberMixin;
+@ISA = qw(LWP::MemberMixin);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+
+require URI::URL;
+require HTTP::Request;
+require HTTP::Response;
+
+use HTTP::Date ();
+
+use LWP ();
+use LWP::Debug ();
+use LWP::Protocol ();
+
+use Carp ();
+
+use AutoLoader ();
+*AUTOLOAD = \&AutoLoader::AUTOLOAD;  # import the AUTOLOAD method
+
+
+=item $ua = new LWP::UserAgent;
+
+Constructor for the UserAgent.  Returns a reference to a
+LWP::UserAgent object.
+
+=cut
+
+sub new
+{
+    my($class, $init) = @_;
+    LWP::Debug::trace('()');
+
+    my $self;
+    if (ref $init) {
+	$self = $init->clone;
+    } else {
+	$self = bless {
+		'agent'       => "libwww-perl/$LWP::VERSION",
+		'from'        => undef,
+		'timeout'     => 3*60,
+		'proxy'       => undef,
+		'cookie_jar'  => undef,
+		'use_eval'    => 1,
+                'parse_head'  => 1,
+                'max_size'    => undef,
+		'no_proxy'    => [],
+	}, $class;
+    }
+}
+
+
+=item $ua->simple_request($request, [$arg [, $size]])
+
+This method dispatches a single WWW request on behalf of a user, and
+returns the response received.  The C<$request> should be a reference
+to a C<HTTP::Request> object with values defined for at least the
+method() and url() attributes.
+
+If C<$arg> is a scalar it is taken as a filename where the content of
+the response is stored.
+
+If C<$arg> is a reference to a subroutine, then this routine is called
+as chunks of the content is received.  An optional C<$size> argument
+is taken as a hint for an appropriate chunk size.
+
+If C<$arg> is omitted, then the content is stored in the response
+object itself.
+
+=cut
+
+sub simple_request
+{
+    my($self, $request, $arg, $size) = @_;
+    local($SIG{__DIE__});  # protect agains user defined die handlers
+
+    my($method, $url) = ($request->method, $request->url);
+
+    # Check that we have a METHOD and a URL first
+    return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST, "Method missing")
+	unless $method;
+    return HTTP::Response->new(&HTTP::Status::RC_BAD_REQUEST, "URL missing")
+	unless $url;
+
+    LWP::Debug::trace("$method $url");
+
+    # Locate protocol to use
+    my $scheme = '';
+    my $proxy = $self->_need_proxy($url);
+    if (defined $proxy) {
+	$scheme = $proxy->scheme;
+    } else {
+	$scheme = $url->scheme;
+    }
+    my $protocol;
+    eval {
+	$protocol = LWP::Protocol::create($scheme);
+    };
+    if ($@) {
+	$@ =~ s/\s+at\s+\S+\s+line\s+\d+\.?\s*//;  # remove file/line number
+	return HTTP::Response->new(&HTTP::Status::RC_NOT_IMPLEMENTED, $@)
+    }
+
+    # Extract fields that will be used below
+    my ($agent, $from, $timeout, $cookie_jar,
+        $use_eval, $parse_head, $max_size) =
+      @{$self}{qw(agent from timeout cookie_jar
+                  use_eval parse_head max_size)};
+
+    # Set User-Agent and From headers if they are defined
+    $request->header('User-Agent' => $agent) if $agent;
+    $request->header('From' => $from) if $from;
+    $cookie_jar->add_cookie_header($request) if $cookie_jar;
+
+    # Transfer some attributes to the protocol object
+    $protocol->parse_head($parse_head);
+    $protocol->max_size($max_size);
+    
+    my $response;
+    if ($use_eval) {
+	# we eval, and turn dies into responses below
+	eval {
+	    $response = $protocol->request($request, $proxy,
+					   $arg, $size, $timeout);
+	};
+	if ($@) {
+	    $@ =~ s/\s+at\s+\S+\s+line\s+\d+\.?\s*//;
+	    $response =
+	      HTTP::Response->new(&HTTP::Status::RC_INTERNAL_SERVER_ERROR,
+				  $@);
+	}
+    } else {
+	$response = $protocol->request($request, $proxy,
+				       $arg, $size, $timeout);
+	# XXX: Should we die unless $response->is_success ???
+    }
+
+    $response->request($request);  # record request for reference
+    $cookie_jar->extract_cookies($response) if $cookie_jar;
+    $response->header("Client-Date" => HTTP::Date::time2str(time));
+    return $response;
+}
+
+
+=item $ua->request($request, $arg [, $size])
+
+Process a request, including redirects and security.  This method may
+actually send several different simple reqeusts.
+
+The arguments are the same as for C<simple_request()>.
+
+=cut
+
+sub request
+{
+    my($self, $request, $arg, $size, $previous) = @_;
+
+    LWP::Debug::trace('()');
+
+    my $response = $self->simple_request($request, $arg, $size);
+
+    my $code = $response->code;
+    $response->previous($previous) if defined $previous;
+
+    LWP::Debug::debug('Simple result: ' . HTTP::Status::status_message($code));
+
+    if ($code == &HTTP::Status::RC_MOVED_PERMANENTLY or
+	$code == &HTTP::Status::RC_MOVED_TEMPORARILY) {
+
+	# Make a copy of the request and initialize it with the new URI
+	my $referral = $request->clone;
+
+	# And then we update the URL based on the Location:-header.
+	# Some servers erroneously return a relative URL for redirects,
+	# so make it absolute if it not already is.
+	my $referral_uri = (URI::URL->new($response->header('Location'),
+					  $response->base))->abs(undef,1);
+
+	$referral->url($referral_uri);
+
+	return $response unless $self->redirect_ok($referral);
+
+	# Check for loop in the redirects
+	my $count = 0;
+	my $r = $response;
+	while ($r) {
+	    if (++$count > 13 ||
+                $r->request->url->as_string eq $referral_uri->as_string) {
+		$response->header("Client-Warning" =>
+				  "Redirect loop detected");
+		return $response;
+	    }
+	    $r = $r->previous;
+	}
+
+	return $self->request($referral, $arg, $size, $response);
+
+    } elsif ($code == &HTTP::Status::RC_UNAUTHORIZED ||
+	     $code == &HTTP::Status::RC_PROXY_AUTHENTICATION_REQUIRED
+	    )
+    {
+	my $proxy = ($code == &HTTP::Status::RC_PROXY_AUTHENTICATION_REQUIRED);
+	my $ch_header = $proxy ?  "Proxy-Authenticate" : "WWW-Authenticate";
+	my $challenge = $response->header($ch_header);
+	unless (defined $challenge) {
+	    $response->header("Client-Warning" => 
+			      "Missing Authenticate header");
+	    return $response;
+	}
+
+	require HTTP::Headers::Util;
+	$challenge =~ tr/,/;/;  # "," is used to separate auth-params!!
+	($challenge) = HTTP::Headers::Util::split_header_words($challenge);
+	my $scheme = lc(shift(@$challenge));
+	shift(@$challenge); # no value
+	$challenge = { @$challenge };  # make rest into a hash
+	for (keys %$challenge) {       # make sure all keys are lower case
+	    $challenge->{lc $_} = delete $challenge->{$_};
+	}
+
+	unless ($scheme =~ /^([a-z]+(?:-[a-z]+)*)$/) {
+	    $response->header("Client-Warning" => 
+			      "Bad authentication scheme '$scheme'");
+	    return $response;
+	}
+	$scheme = $1;  # untainted now
+	my $class = "LWP::Authen::\u$scheme";
+	$class =~ s/-/_/g;
+	
+	no strict 'refs';
+	unless (defined %{"$class\::"}) {
+	    # try to load it
+	    eval "require $class";
+	    if ($@) {
+		if ($@ =~ /^Can\'t locate/) {
+		    $response->header("Client-Warning" =>
+				      "Unsupport authentication scheme '$scheme'");
+		} else {
+		    $response->header("Client-Warning" => $@);
+		}
+		return $response;
+	    }
+	}
+	return $class->authenticate($self, $proxy, $challenge, $response,
+				    $request, $arg, $size);
+    }
+    return $response;
+}
+
+
+=item $ua->redirect_ok
+
+This method is called by request() before it tries to do any
+redirects.  It should return a true value if the redirect is allowed
+to be performed. Subclasses might want to override this.
+
+The default implementation will return FALSE for POST request and TRUE
+for all others.
+
+=cut
+
+sub redirect_ok
+{
+    # draft-ietf-http-v10-spec-02.ps from www.ics.uci.edu, specify:
+    #
+    # If the 30[12] status code is received in response to a request using
+    # the POST method, the user agent must not automatically redirect the
+    # request unless it can be confirmed by the user, since this might change
+    # the conditions under which the request was issued.
+
+    my($self, $request) = @_;
+    return 0 if $request->method eq "POST";
+    1;
+}
+
+
+=item $ua->credentials($netloc, $realm, $uname, $pass)
+
+Set the user name and password to be used for a realm.  It is often more
+useful to specialize the get_basic_credentials() method instead.
+
+=cut
+
+sub credentials
+{
+    my($self, $netloc, $realm, $uid, $pass) = @_;
+    @{ $self->{'basic_authentication'}{$netloc}{$realm} } = ($uid, $pass);
+}
+
+
+=item $ua->get_basic_credentials($realm, $uri, [$proxy])
+
+This is called by request() to retrieve credentials for a Realm
+protected by Basic Authentication or Digest Authentication.
+
+Should return username and password in a list.  Return undef to abort
+the authentication resolution atempts.
+
+This implementation simply checks a set of pre-stored member
+variables. Subclasses can override this method to e.g. ask the user
+for a username/password.  An example of this can be found in
+C<lwp-request> program distributed with this library.
+
+=cut
+
+sub get_basic_credentials
+{
+    my($self, $realm, $uri, $proxy) = @_;
+    return if $proxy;
+
+    my $netloc = $uri->netloc;
+    if (exists $self->{'basic_authentication'}{$netloc}{$realm}) {
+	return @{ $self->{'basic_authentication'}{$netloc}{$realm} };
+    }
+
+    return (undef, undef);
+}
+
+
+=item $ua->agent([$product_id])
+
+Get/set the product token that is used to identify the user agent on
+the network.  The agent value is sent as the "User-Agent" header in
+the requests. The default agent name is "libwww-perl/#.##", where
+"#.##" is substitued with the version numer of this library.
+
+The user agent string should be one or more simple product identifiers
+with an optional version number separated by the "/" character.
+Examples are:
+
+  $ua->agent('Checkbot/0.4 ' . $ua->agent);
+  $ua->agent('Mozilla/5.0');
+
+=item $ua->from([$email_address])
+
+Get/set the Internet e-mail address for the human user who controls
+the requesting user agent.  The address should be machine-usable, as
+defined in RFC 822.  The from value is send as the "From" header in
+the requests.  There is no default.  Example:
+
+  $ua->from('aas@sn.no');
+
+=item $ua->timeout([$secs])
+
+Get/set the timeout value in seconds. The default timeout() value is
+180 seconds, i.e. 3 minutes.
+
+=item $ua->cookie_jar([$cookies])
+
+Get/set the I<HTTP::Cookies> object to use.  The default is to have no
+cookie_jar, i.e. never automatically add "Cookie" headers to the
+requests.
+
+=item $ua->parse_head([$boolean])
+
+Get/set a value indicating wether we should initialize response
+headers from the E<lt>head> section of HTML documents. The default is
+TRUE.  Do not turn this off, unless you know what you are doing.
+
+=item $ua->max_size([$bytes])
+
+Get/set the size limit for response content.  The default is undef,
+which means that there is not limit.  If the returned response content
+is only partial, because the size limit was exceeded, then a
+"X-Content-Range" header will be added to the response.
+
+=cut
+
+sub timeout    { shift->_elem('timeout',   @_); }
+sub agent      { shift->_elem('agent',     @_); }
+sub from       { shift->_elem('from',      @_); }
+sub cookie_jar { shift->_elem('cookie_jar',@_); }
+sub parse_head { shift->_elem('parse_head',@_); }
+sub max_size   { shift->_elem('max_size',  @_); }
+
+# depreciated
+sub use_eval   { shift->_elem('use_eval',  @_); }
+sub use_alarm
+{
+    Carp::carp("LWP::UserAgent->use_alarm(BOOL) is a no-op")
+	if @_ > 1 && $^W;
+    "";
+}
+
+
+# Declarations of AutoLoaded methods
+sub clone;
+sub is_protocol_supported;
+sub mirror;
+sub proxy;
+sub env_proxy;
+sub no_proxy;
+sub _need_proxy;
+
+
+1;
+__END__
+
+
+=item $ua->clone;
+
+Returns a copy of the LWP::UserAgent object
+
+=cut
+
+
+sub clone
+{
+    my $self = shift;
+    my $copy = bless { %$self }, ref $self;  # copy most fields
+
+    # elements that are references must be handled in a special way
+    $copy->{'no_proxy'} = [ @{$self->{'no_proxy'}} ];  # copy array
+
+    $copy;
+}
+
+
+=item $ua->is_protocol_supported($scheme)
+
+You can use this method to query if the library currently support the
+specified C<scheme>.  The C<scheme> might be a string (like 'http' or
+'ftp') or it might be an URI::URL object reference.
+
+=cut
+
+sub is_protocol_supported
+{
+    my($self, $scheme) = @_;
+    if (ref $scheme) {
+	# assume we got a reference to an URI::URL object
+	$scheme = $scheme->abs->scheme;
+    } else {
+	Carp::croak("Illeal scheme '$scheme' passed to is_protocol_supported")
+	    if $scheme =~ /\W/;
+	$scheme = lc $scheme;
+    }
+    return LWP::Protocol::implementor($scheme);
+}
+
+
+=item $ua->mirror($url, $file)
+
+Get and store a document identified by a URL, using If-Modified-Since,
+and checking of the Content-Length.  Returns a reference to the
+response object.
+
+=cut
+
+sub mirror
+{
+    my($self, $url, $file) = @_;
+
+    LWP::Debug::trace('()');
+    my $request = new HTTP::Request('GET', $url);
+
+    if (-e $file) {
+	my($mtime) = (stat($file))[9];
+	if($mtime) {
+	    $request->header('If-Modified-Since' =>
+			     HTTP::Date::time2str($mtime));
+	}
+    }
+    my $tmpfile = "$file-$$";
+
+    my $response = $self->request($request, $tmpfile);
+    if ($response->is_success) {
+
+	my $file_length = (stat($tmpfile))[7];
+	my($content_length) = $response->header('Content-length');
+
+	if (defined $content_length and $file_length < $content_length) {
+	    unlink($tmpfile);
+	    die "Transfer truncated: " .
+		"only $file_length out of $content_length bytes received\n";
+	} elsif (defined $content_length and $file_length > $content_length) {
+	    unlink($tmpfile);
+	    die "Content-length mismatch: " .
+		"expected $content_length bytes, got $file_length\n";
+	} else {
+	    # OK
+	    if (-e $file) {
+		# Some dosish systems fail to rename if the target exists
+		chmod 0777, $file;
+		unlink $file;
+	    }
+	    rename($tmpfile, $file) or
+		die "Cannot rename '$tmpfile' to '$file': $!\n";
+
+	    if (my $lm = $response->last_modified) {
+		# make sure the file has the same last modification time
+		utime $lm, $lm, $file;
+	    }
+	}
+    } else {
+	unlink($tmpfile);
+    }
+    return $response;
+}
+
+=item $ua->proxy(...)
+
+Set/retrieve proxy URL for a scheme:
+
+ $ua->proxy(['http', 'ftp'], 'http://proxy.sn.no:8001/');
+ $ua->proxy('gopher', 'http://proxy.sn.no:8001/');
+
+The first form specifies that the URL is to be used for proxying of
+access methods listed in the list in the first method argument,
+i.e. 'http' and 'ftp'.
+
+The second form shows a shorthand form for specifying
+proxy URL for a single access scheme.
+
+=cut
+
+sub proxy
+{
+    my($self, $key, $proxy) = @_;
+
+    LWP::Debug::trace("$key, $proxy");
+
+    if (!ref($key)) {   # single scalar passed
+	my $old = $self->{'proxy'}{$key};
+	$self->{'proxy'}{$key} = $proxy;
+	return $old;
+    } elsif (ref($key) eq 'ARRAY') {
+	for(@$key) {    # array passed
+	    $self->{'proxy'}{$_} = $proxy;
+	}
+    }
+    return undef;
+}
+
+=item $ua->env_proxy()
+
+Load proxy settings from *_proxy environment variables.  You might
+specify proxies like this (sh-syntax):
+
+  gopher_proxy=http://proxy.my.place/
+  wais_proxy=http://proxy.my.place/
+  no_proxy="my.place"
+  export gopher_proxy wais_proxy no_proxy
+
+Csh or tcsh users should use the C<setenv> command to define these
+envirionment variables.
+
+=cut
+
+sub env_proxy {
+    my ($self) = @_;
+    my($k,$v);
+    while(($k, $v) = each %ENV) {
+	$k = lc($k);
+	next unless $k =~ /^(.*)_proxy$/;
+	$k = $1;
+	if ($k eq 'no') {
+	    $self->no_proxy(split(/\s*,\s*/, $v));
+	}
+	else {
+	    $self->proxy($k, $v);
+	}
+    }
+}
+
+=item $ua->no_proxy($domain,...)
+
+Do not proxy requests to the given domains.  Calling no_proxy without
+any domains clears the list of domains. Eg:
+
+ $ua->no_proxy('localhost', 'no', ...);
+
+=cut
+
+sub no_proxy {
+    my($self, @no) = @_;
+    if (@no) {
+	push(@{ $self->{'no_proxy'} }, @no);
+    }
+    else {
+	$self->{'no_proxy'} = [];
+    }
+}
+
+
+# Private method which returns the URL of the Proxy configured for this
+# URL, or undefined if none is configured.
+sub _need_proxy
+{
+    my($self, $url) = @_;
+
+    $url = new URI::URL($url) unless ref $url;
+
+    LWP::Debug::trace("($url)");
+
+    # check the list of noproxies
+
+    if (@{ $self->{'no_proxy'} }) {
+	my $host = $url->host;
+	return undef unless defined $host;
+	my $domain;
+	for $domain (@{ $self->{'no_proxy'} }) {
+	    if ($host =~ /$domain$/) {
+		LWP::Debug::trace("no_proxy configured");
+		return undef;
+	    }
+	}
+    }
+
+    # Currently configured per scheme.
+    # Eventually want finer granularity
+
+    my $scheme = $url->scheme;
+    if (exists $self->{'proxy'}{$scheme}) {
+
+	LWP::Debug::debug('Proxied');
+	return new URI::URL($self->{'proxy'}{$scheme});
+    }
+
+    LWP::Debug::debug('Not proxied');
+    undef;
+}
+
+1;
+
+=back
+
+=head1 SEE ALSO
+
+See L<LWP> for a complete overview of libwww-perl5.  See F<lwp-request> and
+F<lwp-mirror> for examples of usage.
+
+=head1 COPYRIGHT
+
+Copyright 1995-1997 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/media.types
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/media.types	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/LWP/media.types	(revision 20131)
@@ -0,0 +1,120 @@
+# $Id$
+#
+# This file defines the mapping from file name extentions to media types.
+# Media types where the subtype does not have the "x-" prefix should be
+# registered by IANA:
+#
+#   ftp://www.isi.edu/in-notes/iana/assignments/media-types/
+#
+# See also: RFC-1590
+
+# Text formats
+text/html			html htm
+text/plain			txt text pm el c h cc hh cxx hxx f90
+text/richtext			rtx
+text/tab-separated-values	tsv
+
+text/x-setext			etx
+text/x-pod			pod			# Perl documentation
+
+# Image formats
+image/png			png
+image/gif			gif			# Compuserve
+image/ief			ief
+image/jpeg			jpeg jpg jpe jfif
+image/tiff			tiff tif
+
+image/x-cmu-raster		ras
+image/x-portable-anymap		pnm
+image/x-portable-bitmap		pbm
+image/x-portable-graymap	pgm
+image/x-portable-pixmap		ppm
+image/x-rgb			rgb			# SGI IRIS
+image/x-xbitmap			xbm			# X Windows
+image/x-xpixmap			xpm			# X Windows
+image/x-xwindowdump		xwd			# X Windows
+image/x-bmp			bmp			# MS Windows
+image/x-targa			tga
+image/x-fits			fts
+
+
+# Audio formats
+audio/basic			au snd
+audio/x-aiff			aif aiff aifc
+audio/x-wav			wav			# MS Windows
+audio/x-mpeg-2			mp2			# MPEG layer 2 audio
+
+# Video formats
+video/mpeg			mpeg mpg mpe
+video/quicktime			qt
+video/x-msvideo			avi
+video/x-sgi-movie		mov
+
+# Message
+message/rfc822			mail
+message/partial
+message/external-body
+message/news			art
+
+# Applications
+application/octet-stream	bin
+application/postscript		ai eps ps
+application/oda			oda
+application/atomicmail
+application/andrew-insert
+application/slate
+application/wita
+application/dec-dx
+application/dca-rtf
+application/activemessage
+application/rtf			rft			# MS Word
+application/applefile
+application/mac-binhex40	hqx
+application/news-message-id
+application/news-transmission
+application/wordperfect5.1
+application/pdf			pdf
+application/zip			zip
+application/macwriteii
+application/msword
+application/remote-printing
+application/mathematica
+application/cybercash
+application/commonground
+application/iges
+application/riscos
+application/eshop
+
+application/x-mif		mif			# FrameMaker
+application/x-maker		fm
+application/x-csh		csh
+application/x-dvi		dvi
+application/x-hdf		hdf
+application/x-latex		latex
+application/x-netcdf		nc cdf
+application/x-sh		sh
+application/x-tcl		tcl
+application/x-perl		pl
+application/x-tex		tex
+application/x-texinfo		texinfo texi
+application/x-troff		t tr roff
+application/x-troff-man		man 1 2 3 4 5 6 7 8
+application/x-troff-me		me
+application/x-troff-ms		ms
+application/x-wais-source	src
+application/x-bcpio		bcpio
+application/x-cpio		cpio
+application/x-gtar		gtar			# GNU tar
+application/x-shar		shar
+application/x-sv4cpio		sv4cpio
+application/x-sv4crc		sv4crc
+application/x-tar		tar
+application/x-ustar		ustar
+
+# Multipart
+multipart/mixed
+multipart/alternative
+multipart/digest
+multipart/parallel
+multipart/appledouble
+multipart/header-set
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/Escape.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/Escape.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/Escape.pm	(revision 20131)
@@ -0,0 +1,119 @@
+#
+# $Id$
+#
+
+package URI::Escape;
+use strict;
+
+=head1 NAME
+
+URI::Escape - Escape and unescape unsafe characters
+
+=head1 SYNOPSIS
+
+ use URI::Escape;
+ $safe = uri_escape("10% is enough\n");
+ $verysafe = uri_escape("foo", "\0-\377");
+ $str  = uri_unescape($safe);
+
+=head1 DESCRIPTION
+
+This module provide functions to escape and unescape URI strings.
+Some characters are regarded as "unsafe" and must be escaped in
+accordance with RFC 1738.  Escaped characters are represented by a
+triplet consisting of the character "%" followed by two hexadecimal
+digits.  The following functions are provided (and exported by
+default):
+
+=over 4
+
+=item uri_escape($string, [$unsafe])
+
+This function replaces all unsafe characters in the $string with their
+escape sequence and return the result.
+
+The uri_escape() function takes an optional second argument that
+overrides the set of characters that are to be escaped.  The set is
+specified as a string that can be used in a regular expression
+character class (between [ ]).  E.g.:
+
+  \x00-\x1f\x7f-\xff          # all control and hi-bit characters
+  a-z                         # all lower case characters
+  ^A-Za-z                     # everything not a letter
+
+The default set of characters to be escaped is:
+
+  \x00-\x20"#%;<>?{}|\\^~`\[\]\x7F-\xFF
+
+=item uri_unescape($string)
+
+Returns a string with all %XX sequences replaced with the actual
+character.
+
+=back
+
+The module can also export the %escapes hash which contains the
+mapping from all characters to the corresponding escape code.
+
+=head1 SEE ALSO
+
+L<URI::URL>
+
+
+=head1 COPYRIGHT
+
+Copyright 1995-1997 Gisle Aas.
+
+This program is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
+use vars qw(%escapes);
+
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(uri_escape uri_unescape);
+@EXPORT_OK = qw(%escapes);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+use Carp ();
+
+# Build a char->hex map
+for (0..255) {
+    $escapes{chr($_)} = sprintf("%%%02X", $_);
+}
+
+my %subst;  # compiled patternes
+
+sub uri_escape
+{
+    my($text, $patn) = @_;
+    return undef unless defined $text;
+    if (defined $patn){
+	unless (exists  $subst{$patn}) {
+	    # Because we can't compile regex we fake it with a cached sub
+	    $subst{$patn} =
+	      eval "sub {\$_[0] =~ s/([$patn])/\$escapes{\$1}/g; }";
+	    Carp::croak("uri_escape: $@") if $@;
+	}
+	&{$subst{$patn}}($text);
+    } else {
+	# Default unsafe characters. (RFC1738 section 2.2)
+	$text =~ s/([\x00-\x20\"#%;<>?{}|\\^~`\[\]\x7F-\xFF])/$escapes{$1}/g;
+    }
+    $text;
+}
+
+sub uri_unescape
+{
+    # Note from RFC1630:  "Sequences which start with a percent sign
+    # but are not followed by two hexadecimal characters are reserved
+    # for future extension"
+    my @copy = @_;
+    for (@copy) { s/%([\dA-Fa-f]{2})/chr(hex($1))/eg; }
+    wantarray ? @copy : $copy[0];
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/Heuristic.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/Heuristic.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/Heuristic.pm	(revision 20131)
@@ -0,0 +1,191 @@
+package URI::Heuristic;
+
+# $Id$
+
+=head1 NAME
+
+uf_urlstr - Expand URL using heuristics
+
+=head1 SYNOPSIS
+
+ use URI::Heuristic qw(uf_urlstr);
+ $url = uf_urlstr("perl");             # http://www.perl.com
+ $url = uf_urlstr("www.sol.no/sol");   # http://www.sol.no/sol
+ $url = uf_urlstr("aas");              # http://www.aas.no
+ $url = uf_urlstr("ftp.funet.fi");     # ftp://ftp.funet.fi
+ $url = uf_urlstr("/etc/passwd");      # file:/etc/passwd
+
+=head1 DESCRIPTION
+
+This module provide functions that expand strings into real absolute
+URLs using some builtin heuristics.  Strings that already represent
+absolute URLs (i.e. start with a C<scheme:> part) are never modified
+and are returned unchanged.  The main use of these functions are to
+allow abbreviated URLs similar to what many web browsers allow for URLs
+typed in by the user.
+
+The following functions are provided:
+
+=over 4
+
+=item uf_urlstr($str)
+
+The uf_urlstr() function will try to make the string passed as
+argument into a proper absolute URL string.  The "uf_" prefix stands
+for "User Friendly".
+
+=item uf_url($str)
+
+This functions work the same way as uf_urlstr() but it will
+return a C<URI::URL> object.
+
+=back
+
+=head1 ENVIRONMENT
+
+If the hostname portion of a URL does not contain any dots, then
+certain qualified guesses will be made.  These guesses are governed be
+the following two environment variables.
+
+=over 10
+
+=item COUNTRY
+
+This is the two letter country code (ISO 3166) for your location.  If
+the domain name of your host ends with two letters, then it is taken
+to be the default country. See also L<Locale::Country>.
+
+=item URL_GUESS_PATTERN
+
+Contain a space separated list of URL patterns to try.  The string
+"ACME" is for some reason used as a placeholder for the host name in
+the URL provided.  Example:
+
+ URL_GUESS_PATTERN="www.ACME.no www.ACME.se www.ACME.com"
+ export URL_GUESS_PATTERN
+
+Specifying URL_GUESS_PATTERN disables any guessing rules based on
+country.  An empty URL_GUESS_PATTERN disables any guessing that
+involves host name lookups.
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 1997-1998, Gisle Aas
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
+
+use strict;
+
+use vars qw(@EXPORT_OK $VERSION $MY_COUNTRY %LOCAL_GUESSING $DEBUG);
+
+require Exporter;
+*import = \&Exporter::import;
+@EXPORT_OK = qw(uf_url uf_urlstr);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+eval {
+    require Net::Domain;
+    my $fqdn = Net::Domain::hostfqdn();
+    $MY_COUNTRY = lc($1) if $fqdn =~ /\.([a-zA-Z]{2})$/;
+
+    # Some other heuristics to guess country?  Perhaps looking
+    # at some environment variable (LANG, LC_ALL, ???)
+    $MY_COUNTRY = $ENV{COUNTRY} if exists $ENV{COUNTRY};
+};
+
+%LOCAL_GUESSING =
+(
+ 'us' => [qw(www.ACME.gov www.ACME.mil)],
+ 'uk' => [qw(www.ACME.co.uk www.ACME.org.uk www.ACME.ac.uk)],
+ 'au' => [qw(www.ACME.com.au www.ACME.org.au www.ACME.edu.au)],
+ 'il' => [qw(www.ACME.co.il www.ACME.org.il www.ACME.net.il)],
+ # send corrections and new entries to <aas@sn.no>
+);
+
+
+sub uf_url ($)
+{
+    require URI::URL;
+    URI::URL->new(uf_urlstr($_[0]));
+}
+
+
+sub uf_urlstr ($)
+{
+    local($_) = @_;
+    print STDERR "uf_urlstr: resolving $_\n" if $DEBUG;
+    return unless defined;
+
+    s/^\s+//;
+    s/\s+$//;
+
+    if (/^(www|web|home)\./) {
+	$_ = "http://$_";
+
+    } elsif (/^(ftp|gopher|news|wais|http|https)\./) {
+	$_ = "$1://$_";
+
+    } elsif (m,^/,      ||          # absolute file name
+	     m,^\.\.?/, ||          # relative file name
+	     m,^[a-zA-Z]:[/\\],)    # dosish file name
+    {
+	$_ = "file:$_";
+
+    } elsif (/^\w+([\.\-]\w+)*\@(\w+\.)+\w{2,3}$/) {
+	$_ = "mailto:$_";
+
+    } elsif (!/^[.+\-\w]+:/) {      # no scheme specified
+	if (s/^(\w+(?:\.\w+)*)([\/:\?\#]|$)/$2/) {
+	    my $host = $1;
+
+	    if ($host !~ /\./ && $host ne "localhost") {
+		my @guess;
+		if (exists $ENV{URL_GUESS_PATTERN}) {
+		    @guess = map { s/\bACME\b/$host/; $_ }
+		             split(' ', $ENV{URL_GUESS_PATTERN});
+		} else {
+		    if ($MY_COUNTRY) {
+			my $special = $LOCAL_GUESSING{$MY_COUNTRY};
+			if ($special) {
+			    my @special = @$special;
+			    push(@guess, map { s/\bACME\b/$host/; $_ }
+                                               @special);
+			} else {
+			    push(@guess, "www.$host.$MY_COUNTRY");
+			}
+		    }
+		    push(@guess, map "www.$host.$_",
+			             "com", "org", "net", "edu", "int");
+		}
+
+
+		my $guess;
+		for $guess (@guess) {
+		    print STDERR "uf_urlstr: gethostbyname('$guess')..."
+		      if $DEBUG;
+		    if (gethostbyname($guess)) {
+			print STDERR "yes\n" if $DEBUG;
+			$host = $guess;
+			last;
+		    }
+		    print STDERR "no\n" if $DEBUG;
+		}
+	    }
+	    $_ = "http://$host$_";
+
+	} else {
+	    # pure junk, just return it unchanged...
+
+	}
+    }
+    print STDERR "uf_urlstr: ==> $_\n" if $DEBUG;
+
+    $_;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL.pm	(revision 20131)
@@ -0,0 +1,949 @@
+package URI::URL;
+
+$VERSION = "4.15";   # $Date$
+sub Version { $VERSION; }
+
+require 5.004;
+
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(url);
+
+require AutoLoader;
+*AUTOLOAD = \&AutoLoader::AUTOLOAD;
+
+use Carp ();
+
+# Basic lexical elements, taken from RFC 1738:
+#
+#  safe         = "$" | "-" | "_" | "." | "+"
+#  extra        = "!" | "*" | "'" | "(" | ")" | ","
+#  national     = "{" | "}" | "|" | "\" | "^" | "~" | "[" | "]" | "`"
+#  punctuation  = "<" | ">" | "#" | "%" | <">
+#  reserved     = ";" | "/" | "?" | ":" | "@" | "&" | "="
+#  escape       = "%" hex hex
+#  unreserved   = alpha | digit | safe | extra
+#  uchar        = unreserved | escape
+#  xchar        = unreserved | reserved | escape
+
+# draft-fielding-url-syntax-05.txt adds '+' to the reserved chars and
+# takes '~' out
+
+use strict;
+use vars qw($reserved $reserved_no_slash $reserved_no_form $unsafe
+	    $Debug $Strict_URL
+	   );
+
+$reserved          = ";\\/?:\\@&=+#%"; # RFC 1738 reserved pluss '#' and '%'
+$reserved_no_slash = ";?:\\@&=+#%";    # used when escaping path
+$reserved_no_form  = ";\\/?:\\@#%";    # used when escaping params and query
+
+# This is the unsafe characters (excluding those reserved)
+$unsafe   = "\x00-\x20{}|\\\\^\\[\\]`<>\"\x7F-\xFF";
+#$unsafe .= "~";  # according to RFC1738 but not to common practice
+
+$Debug         = 0;     # set to 1 to print URLs on creation
+$Strict_URL    = 0;     # see new()
+
+use overload ( '""' => 'as_string', 'fallback' => 1 );
+
+my %Implementor = (); # mapping from scheme to implementation class
+
+
+# Easy to use constructor
+sub url ($;$)
+{
+    URI::URL->new(@_);
+}
+
+
+# URI::URL objects are implemented as blessed hashes:
+#
+# Each of the URL components (scheme, netloc, user, password, host,
+# port, path, params, query, fragment) are stored under their
+# name. The netloc, path, params and query is stored in quoted
+# (escaped) form.  The others is stored unquoted (unescaped).
+#
+# Netloc is special since it is rendundant (same as
+# "user:password@host:port") and must be kept in sync with those.
+#
+# The '_str' key stores a cached stringified version of the URL
+# (by definition in quoted form).
+# The '_base' key stores the optional base of a relative URL.
+#
+# The '_orig_url' is used while debugging is on.
+#
+# Subclasses may add their own keys but must take great care to
+# avoid names which might be used in later verions of this module.
+
+sub new
+{
+    my($class, $init, $base) = @_;
+
+    my $self;
+    if (ref $init) {
+	$self = $init->clone;
+	$self->base($base) if $base;
+    } else {
+	$init = "" unless defined $init;
+	# RFC 1738 appendix suggest that we just ignore extra whitespace
+	$init =~ s/\s+//g;
+	# Also get rid of any <URL: > wrapper
+	$init =~ s/^<(?:URL:)?(.*)>$/$1/;
+
+	# We need a scheme to determine which class to use
+	my($scheme) = $init =~ m/^([.+\-\w]+):/;
+	if (!$scheme and $base){ # get scheme from base
+	    if (ref $base){ # may be object or just a string
+		$scheme = $base->scheme;
+	    } else {
+		$scheme = $1 if $base =~ m/^([.+\-\w]+):/;
+	    }
+	}
+	unless($scheme){
+	    Carp::croak("Unable to determine scheme for '$init'")
+		if $Strict_URL;
+	    $scheme = 'http';
+	}
+	my $impclass = URI::URL::implementor($scheme);
+	unless ($impclass) {
+	    Carp::croak("URI::URL scheme '$scheme' is not supported")
+		if $Strict_URL;
+	    # use generic as fallback
+	    require URI::URL::_generic;
+	    URI::URL::implementor($scheme, 'URI::URL::_generic');
+	    $impclass = 'URI::URL::_generic';
+	}
+
+	# hand-off to scheme specific implementation sub-class
+	$self->{'_orig_url'} = $init if $Debug;
+	$self = $impclass->new($init, $base);
+    }
+    $self->print_on('STDERR') if $Debug;
+    return $self;
+}
+
+
+sub clone
+{
+    my $self = shift;
+    # this work as long as none of the components are references themselves
+    bless { %$self }, ref $self;
+}
+
+
+sub implementor
+{
+    my($scheme, $impclass) = @_;
+    unless (defined $scheme) {
+	require URI::URL::_generic;
+	return 'URI::URL::_generic';
+    }
+
+    $scheme = lc($scheme);
+    if ($impclass) {
+	$impclass->_init_implementor($scheme);
+	my $old = $Implementor{$scheme};
+	$Implementor{$scheme} = $impclass;
+	return $old;
+    }
+
+    my $ic = $Implementor{$scheme};
+    return $ic if $ic;
+
+    # scheme not yet known, look for internal or
+    # preloaded (with 'use') implementation
+    $ic = "URI::URL::$scheme";  # default location
+    no strict 'refs';
+    # check we actually have one for the scheme:
+    unless (defined @{"${ic}::ISA"}) {
+	# Try to load it
+	eval { require "URI/URL/$scheme.pm"; };
+	die $@ if $@ && $@ !~ /Can\'t locate/;
+	$ic = '' unless defined @{"${ic}::ISA"};
+    }
+    if ($ic) {
+	$ic->_init_implementor($scheme);
+	$Implementor{$scheme} = $ic;
+    }
+    $ic;
+}
+
+
+sub _init_implementor
+{
+    my($class, $scheme) = @_;
+    # Remember that one implementor class may actually
+    # serve to implement several URL schemes.
+
+    if ($] < 5.003_17) {
+	no strict qw(refs);
+	# Setup overloading inheritace - experimental
+	%{"${class}::OVERLOAD"} = %URI::URL::OVERLOAD
+	    unless defined %{"${class}::OVERLOAD"};
+    }
+}
+
+
+# This private method help us implement access to the elements in the
+# URI::URL object hash (%$self).  You can set up access to an element
+# with a routine similar to this one:
+#
+#  sub component { shift->_elem('component', @_); }
+
+sub _elem
+{
+    my $self = shift;
+    my $elem = shift;
+    my $old = $self->{$elem};
+    if (@_) {
+	$self->{$elem} = shift;
+	$self->{'_str'} = '';        # void cached string
+    }
+    $old;
+}
+
+
+# Make all standard methods available to all kinds of URLs.  This allow
+# us to call these without to much worry when URI::URL::strict(0);
+
+sub bad_method;
+
+*netloc       = \&bad_method;
+*user         = \&bad_method;
+*password     = \&bad_method;
+*host         = \&bad_method;
+*port         = \&bad_method;
+*default_port = \&bad_method;
+
+*full_path    = \&bad_method;
+*epath        = \&bad_method;
+*eparams      = \&bad_method;
+*equery       = \&bad_method;
+
+*path         = \&bad_method;
+*path_components = \&bad_method;
+*params       = \&bad_method;
+*query        = \&bad_method;
+*frag         = \&bad_method;
+
+
+#
+# A U T O  L O A D I N G
+#
+# The rest of the methods are autoloaded because they should be less
+# frequently used.  We define stubs here so that inheritance works as
+# it should.
+sub newlocal;
+sub strict;
+sub base;
+sub scheme;
+sub crack;
+sub abs;
+sub rel;
+sub as_string;
+sub eq;
+sub print_on;
+
+# Don't need DESTROY but avoid trying to AUTOLOAD it.
+sub DESTROY { }
+
+1;
+__END__
+
+sub newlocal
+{
+    require URI::URL::file;
+    my $class = shift;
+    URI::URL::file->newlocal(@_);  # pass it on the the file class
+}
+
+sub strict
+{
+    return $Strict_URL unless @_;
+    my $old = $Strict_URL;
+    $Strict_URL = $_[0];
+    $old;
+}
+
+# Access some attributes of a URL object:
+sub base {
+    my $self = shift;
+    my $base  = $self->{'_base'};
+
+    if (@_) { # set
+	my $new_base = shift;
+	$new_base = $new_base->abs if ref($new_base);  # unsure absoluteness
+	$self->{_base} = $new_base;
+    }
+    return unless defined wantarray;
+
+    # The base attribute supports 'lazy' conversion from URL strings
+    # to URL objects. Strings may be stored but when a string is
+    # fetched it will automatically be converted to a URL object.
+    # The main benefit is to make it much cheaper to say:
+    #   new URI::URL $random_url_string, 'http:'
+    if (defined($base) && !ref($base)) {
+	$base = new URI::URL $base;
+	$self->_elem('_base', $base); # set new object
+    }
+    $base;
+}
+
+sub scheme {
+    my $self = shift;
+    my $old = $self->{'scheme'};
+    if (@_) {
+	my $new_scheme = shift;
+	if (defined($new_scheme) && length($new_scheme)) {
+	    # reparse URL with new scheme
+	    my $str = $self->as_string;
+	    $str =~ s/^[\w+\-.]+://;
+	    my $newself = new URI::URL "$new_scheme:$str";
+	    %$self = %$newself;
+	    bless $self, ref($newself);
+	} else {
+	    $self->{'scheme'} = undef;
+	}
+    }
+    $old;
+}
+
+sub crack
+{
+    # should be overridden by subclasses
+    my $self = shift;
+    ($self->scheme,  # 0: scheme
+     undef,          # 1: user
+     undef,          # 2: passwd
+     undef,          # 3: host
+     undef,          # 4: port
+     undef,          # 5: path
+     undef,          # 6: params
+     undef,          # 7: query
+     undef           # 8: fragment
+    )
+}
+
+# These are overridden by _generic (this is just a noop for those schemes that
+# do not wish to be a subclass of URI::URL::_generic)
+sub abs { shift->clone; }
+sub rel { shift->clone; }
+
+# This method should always be overridden in subclasses
+sub as_string {
+    "<URL>";
+}
+
+# Compare two URLs, subclasses will provide a more correct implementation
+sub eq {
+    my($self, $other) = @_;
+    $other = URI::URL->new($other, $self) unless ref $other;
+    ref($self) eq ref($other) &&
+      $self->scheme eq $other->scheme &&
+      $self->as_string eq $other->as_string;  # Case-sensitive
+}
+
+# This is set up as an alias for various methods
+sub bad_method {
+    my $self = shift;
+    my $scheme = $self->scheme;
+    Carp::croak("Illegal method called for $scheme: URL")
+	if $Strict_URL;
+    # Carp::carp("Illegal method called for $scheme: URL")
+    #     if $^W;
+    undef;
+}
+
+sub print_on
+{
+    no strict qw(refs);  # because we use strings as filehandles
+    my $self = shift;
+    my $fh = shift || 'STDERR';
+    my($k, $v);
+    print $fh "Dump of URI::URL $self...\n";
+    foreach $k (sort keys %$self){
+	$v = $self->{$k};
+	$v = 'UNDEF' unless defined $v;
+	print $fh "  $k\t'$v'\n";
+    }
+}
+
+1;
+
+
+#########################################################################
+#### D O C U M E N T A T I O N
+#########################################################################
+
+=head1 NAME
+
+URI::URL - Uniform Resource Locators (absolute and relative)
+
+=head1 SYNOPSIS
+
+ use URI::URL;
+
+ # Constructors
+ $url1 = new URI::URL 'http://www.perl.com/%7Euser/gisle.gif';
+ $url2 = new URI::URL 'gisle.gif', 'http://www.com/%7Euser';
+ $url3 = url 'http://www.sn.no/'; # handy constructor
+ $url4 = $url2->abs;       # get absolute url using base
+ $url5 = $url2->abs('http:/other/path');
+ $url6 = newlocal URI::URL 'test';
+
+ # Stringify URL
+ $str1 = $url->as_string;  # complete escaped URL string
+ $str2 = $url->full_path;  # escaped path+params+query
+ $str3 = "$url";           # use operator overloading
+
+ # Retrieving Generic-RL components:
+ $scheme   = $url->scheme;
+ $netloc   = $url->netloc; # see user,password,host,port below
+ $path     = $url->path;
+ $params   = $url->params;
+ $query    = $url->query;
+ $frag     = $url->frag;
+
+ # Accessing elements in their escaped form
+ $path     = $url->epath;
+ $params   = $url->eparams;
+ $query    = $url->equery;
+
+ # Retrieving Network location (netloc) components:
+ $user     = $url->user;
+ $password = $url->password;
+ $host     = $url->host;
+ $port     = $url->port;   # returns default if not defined
+
+ # Retrieve escaped path components as an array
+ @path     = $url->path_components;
+
+ # HTTP query-string access methods
+ @keywords = $url->keywords;
+ @form     = $url->query_form;
+
+ # All methods above can set the field values, e.g:
+ $url->scheme('http');
+ $url->host('www.w3.org');
+ $url->port($url->default_port);
+ $url->base($url5);                      # use string or object
+ $url->keywords(qw(dog bones));
+
+ # File methods
+ $url = new URI::URL "file:/foo/bar";
+ open(F, $url->local_path) or die;
+
+ # Compare URLs
+ if ($url->eq("http://www.sn.no")) or die;
+
+=head1 DESCRIPTION
+
+This module implements the URI::URL class representing Uniform
+Resource Locators (URL). URLs provide a compact string representation
+for resources available via the Internet. Both absolute (RFC 1738) and
+relative (RFC 1808) URLs are supported.
+
+URI::URL objects are created by calling new(), which takes as argument
+a string representation of the URL or an existing URL object reference
+to be cloned. Specific individual elements can then be accessed via
+the scheme(), user(), password(), host(), port(), path(), params(),
+query() and frag() methods.  In addition escaped versions of the path,
+params and query can be accessed with the epath(), eparams() and
+equery() methods.  Note that some URL schemes will support all these
+methods.
+
+The object constructor new() must be able to determine the scheme for
+the URL.  If a scheme is not specified in the URL itself, it will use
+the scheme specified by the base URL. If no base URL scheme is defined
+then new() will croak if URI::URL::strict(1) has been invoked,
+otherwise I<http> is silently assumed.  Once the scheme has been
+determined new() then uses the implementor() function to determine
+which class implements that scheme.  If no implementor class is
+defined for the scheme then new() will croak if URI::URL::strict(1)
+has been invoked, otherwise the internal generic URL class is assumed.
+
+Internally defined schemes are implemented by the
+URI::URL::I<scheme_name> module.  The URI::URL::implementor() function
+can be used to explicitly set the class used to implement a scheme if
+you want to override this.
+
+
+=head1 HOW AND WHEN TO ESCAPE
+
+
+=over 3
+
+=item This is an edited extract from a URI specification:
+
+The printability requirement has been met by specifying a safe set of
+characters, and a general escaping scheme for encoding "unsafe"
+characters. This "safe" set is suitable, for example, for use in
+electronic mail.  This is the canonical form of a URI.
+
+There is a conflict between the need to be able to represent many
+characters including spaces within a URI directly, and the need to be
+able to use a URI in environments which have limited character sets
+or in which certain characters are prone to corruption. This conflict
+has been resolved by use of an hexadecimal escaping method which may
+be applied to any characters forbidden in a given context. When URLs
+are moved between contexts, the set of characters escaped may be
+enlarged or reduced unambiguously.  The canonical form for URIs has
+all white spaces encoded.
+
+=item Notes:
+
+A URL string I<must>, by definition, consist of escaped
+components. Complete URLs are always escaped.
+
+The components of a URL string must be I<individually> escaped.  Each
+component of a URL may have a separate requirements regarding what
+must be escaped, and those requirements are also dependent on the URL
+scheme.
+
+Never escape an already escaped component string.
+
+=back
+
+This implementation expects an escaped URL string to be passed to
+new() and will return a fully escaped URL string from as_string()
+and full_path().
+
+Individual components can be manipulated in unescaped or escaped
+form. The following methods return/accept unescaped strings:
+
+    scheme                  path
+    user                    params
+    password                query
+    host                    frag
+    port
+
+The following methods return/accept partial I<escaped> strings:
+
+    netloc                  eparams
+    epath                   equery
+
+I<Partial escaped> means that only reserved characters
+(i.e. ':', '@', '/', ';', '?', '=', '&' in addition to '%', '.' and '#')
+needs to be escaped when they are to be treated as normal characters.
+I<Fully escaped> means that all unsafe characters are escaped. Unsafe
+characters are all all control characters (%00-%1F and %7F), all 8-bit
+characters (%80-%FF) as well
+as '{', '}', '|', '\', '^', '[', ']' '`', '"', '<' and '>'.
+Note that the character '~' is B<not> considered
+unsafe by this library as it is common practice to use it to reference
+personal home pages, but it is still unsafe according to RFC 1738.
+
+=head1 ADDING NEW URL SCHEMES
+
+New URL schemes or alternative implementations for existing schemes
+can be added to your own code. To create a new scheme class use code
+like:
+
+   package MYURL::foo;
+   @ISA = (URI::URL::implementor());   # inherit from generic scheme
+
+The 'URI::URL::implementor()' function call with no parameters returns
+the name of the class which implements the generic URL scheme
+behaviour (typically C<URI::URL::_generic>). All hierarchical schemes
+should be derived from this class.
+
+Your class can then define overriding methods (e.g., new(), _parse()
+as required).
+
+To register your new class as the implementor for a specific scheme
+use code like:
+
+   URI::URL::implementor('x-foo', 'MYURL::foo');
+
+Any new URL created for scheme 'x-foo' will be implemented by your
+C<MYURL::foo> class. Existing URLs will not be affected.
+
+
+=head1 FUNCTIONS
+
+=over 3
+
+=item $url = URI::URL->new( $url_string [, $base_url] )
+
+This is the object constructor.  It will create a new URI::URL object,
+initialized from the URL string.
+
+=item $url = URI::URL->newlocal($path);
+
+Returns an URL object that denotes a path within the local filesystem.
+Paths not starting with '/' are interpreted relative to the current
+working directory.  This constructor always return an absolute 'file'
+URL.
+
+=item $url = url($url_string, [, $base_url])
+
+Alternative constructor function.  The url() function is exported by
+the URI::URL module and is easier both to type and read than calling
+C<URI::URL->new> directly.  Useful for constructs like this:
+
+   $h = url($str)->host;
+
+This function is just a wrapper for URI::URL->new.
+
+=item URI::URL::strict($bool)
+
+If strict is true then we croak on errors.  The function returns the
+previous value.
+
+=item URI::URL::implementor([$scheme, [$class]])
+
+Use this function to get or set implementor class for a scheme.
+Returns '' if specified scheme is not supported.  Returns generic URL
+class if no scheme specified.
+
+=back
+
+=head1 METHODS
+
+This section describes the methods available for an URI::URL object.
+Note that some URL schemes will disallow some of these methods and
+will croak if they are used.  Some URL schemes add additional methods
+that are described in the sections to follow.
+
+Attribute access methods marked with (*) can take an optional argument
+to set the value of the attribute, and they always return the old
+value.
+
+=over 3
+
+=item $url->abs([$base])
+
+The abs() method attempts to return a new absolute URI::URL object
+for a given URL.  In order to convert a relative URL into an absolute
+one, a I<base> URL is required. You can associate a default base with a
+URL either by passing a I<base> to the new() constructor when a
+URI::URL is created or using the base() method on the object later.
+Alternatively you can specify a one-off base as a parameter to the
+abs() method.
+
+The rel() method will do the opposite transformation.
+
+Some older parsers used to allow the scheme name to be present in the
+relative URL if it was the same as the base URL scheme.  RFC1808 says
+that this should be avoided, but you can enable this old behaviour by
+setting the $URI::URL::ABS_ALLOW_RELATIVE_SCHEME variable to a TRUE
+value.  The difference is demonstrated by the following examples:
+
+  url("http:foo")->abs("http://host/a/b")     ==>  "http:foo"
+
+  local $URI::URL::ABS_ALLOW_RELATIVE_SCHEME = 1;
+  url("http:foo")->abs("http://host/a/b")     ==>  "http:/host/a/foo"
+
+You can also have the abs() method ignore if there is too many ".."
+segments in the relative URL by setting
+$URI::URL::ABS_REMOTE_LEADING_DOTS to a TRUE value.  The difference is
+demonstrated by the following examples:
+
+  url("../../../foo")->abs("http://host/a/b")   ==> "http://host/../../foo"
+
+  local $URI::URL::ABS_REMOTE_LEADING_DOTS = 1;
+  url("../../../foo")->abs("http://host/a/b")   ==> "http://host/foo"
+
+
+=item $url->as_string
+
+Returns a string representing the URL in its canonical form.  All
+unsafe characters will be escaped.  This method is overloaded as the
+perl "stringify" operator, which means that URLs can be used as
+strings in many contexts.
+
+=item $url->base (*)
+
+Get/set the base URL associated with the current URI::URL object.  The
+base URL matters when you call the abs() method.
+
+=item $url->clone
+
+Returns a copy of the current URI::URL object.
+
+=item $url->crack
+
+Return a 9 element array with the following content:
+
+   0: $url->scheme *)
+   1: $url->user
+   2: $url->password
+   3: $url->host
+   4: $url->port
+   5: $url->epath
+   6: $url->eparams
+   7: $url->equery
+   8: $url->frag
+
+All elements except I<scheme> will be undefined if the corresponding
+URL part is not available.
+
+B<Note:> The scheme (first element) returned by crack will aways be
+defined.  This is different from what the $url->scheme returns, since
+it will return I<undef> for relative URLs.
+
+=item $url->default_port
+
+Returns the default port number for the URL scheme that the URI::URL
+belongs too.
+
+=item $url->eparams (*)
+
+Get/set the URL parameters in escaped form.
+
+=item $url->epath (*)
+
+Get/set the URL path in escaped form.
+
+=item $url->eq($other_url)
+
+Compare two URLs to decide if they match or not.  The rules for how
+comparison is made varies for different parts of the URLs; scheme and
+netloc comparison is case-insensitive, and escaped chars match their
+%XX encoding unless they are "reserved" or "unsafe".
+
+=item $url->equery (*)
+
+Get/set the URL query string in escaped form.
+
+=item $url->full_path
+
+Returns the string "/path;params?query".  This is the string that is
+passed to a remote server in order to access the document.
+
+=item $url->frag (*)
+
+Get/set the fragment (unescaped)
+
+=item $url->host (*)
+
+Get/set the host (unescaped)
+
+=item $url->netloc (*)
+
+Get/set the network location in escaped form.  Setting the network
+location will affect 'user', 'password', 'host' and 'port'.
+
+=item $url->params (*)
+
+Get/set the URL parameters (unescaped)
+
+=item $url->password (*)
+
+Get/set the password (unescaped)
+
+=item $url->path (*)
+
+Get/set the path (unescaped).  This method will croak if any of the
+path components in the return value contain the "/" character.  You
+should use the epath() method to be safe.
+
+=item $url->path_components (*)
+
+Get/set the path using a list of unescaped path components.  The
+return value will loose the distinction beween '.' and '%2E'.  When
+setting a value, a '.' is converted to be a literal '.' and is
+therefore encoded as '%2E'.
+
+=item $url->port (*)
+
+Get/set the network port (unescaped)
+
+=item $url->rel([$base])
+
+Return a relative URL if possible.  This is the opposite of what the
+abs() method does.  For instance:
+
+   url("http://www.math.uio.no/doc/mail/top.html",
+       "http://www.math.uio.no/doc/linux/")->rel
+
+will return a relative URL with path set to "../mail/top.html" and
+with the same base as the original URL.
+
+If the original URL already is relative or the scheme or netloc does
+not match the base, then a copy of the original URL is returned.
+
+
+=item $url->print_on(*FILEHANDLE);
+
+Prints a verbose presentation of the contents of the URL object to
+the specified file handle (default STDERR).  Mainly useful for
+debugging.
+
+=item $url->scheme (*)
+
+Get/set the scheme for the URL.
+
+=item $url->query (*)
+
+Get/set the query string (unescaped).  This method will croak if the
+string returned contains both '+' and '%2B' or '=' together with '%3D'
+or '%26'.  You should use the equery() method to be safe.
+
+=item $url->user (*)
+
+Get/set the URL user name (unescaped)
+
+=back
+
+=head1 HTTP METHODS
+
+For I<http> URLs you may also access the query string using the
+keywords() and the query_form() methods.  Both will croak if the query
+is not of the correct format.  The encodings look like this:
+
+  word1+word2+word3..        # keywords
+  key1=val1&key2=val2...     # query_form
+
+Note: These functions does not return the old value when they are used
+to set a value of the query string.
+
+=over 3
+
+=item $url->keywords (*)
+
+The keywords() method returns a list of unescaped strings.  The method
+can also be used to set the query string by passing in the keywords as
+individual arguments to the method.
+
+=item $url->query_form (*)
+
+The query_form() method return a list of unescaped key/value pairs.
+If you assign the return value to a hash you might loose some values
+if the key is repeated (which it is allowed to do).
+
+This method can also be used to set the query sting of the URL like this:
+
+  $url->query_form(foo => 'bar', foo => 'baz', equal => '=');
+
+If the value part of a key/value pair is a reference to an array, then
+it will be converted to separate key/value pairs for each value.  This
+means that these two calls are equal:
+
+  $url->query_form(foo => 'bar', foo => 'baz');
+  $url->query_form(foo => ['bar', 'baz']);
+
+=back
+
+=head1 FILE METHODS
+
+The I<file> URLs implement the local_path() method that returns a path
+suitable for access to files within the current filesystem.  These
+methods can B<not> be used to set the path of the URL.
+
+=over 3
+
+=item $url->local_path
+
+This method is really just an alias for one of the methods below
+depending on what system you run on.
+
+=item $url->unix_path
+
+Returns a path suitable for use on a Unix system.  This method will
+croak if any of the path segments contains a "/" or a NULL character.
+
+=item $url->dos_path
+
+Returns a path suitable for use on a MS-DOS or MS-Windows system.
+
+=item $url->mac_path
+
+Returns a path suitable for use on a Macintosh system.
+
+=item $url->vms_path
+
+Returns a path suitable for use on a VMS system.  VMS is a trademark
+of Digital.
+
+=back
+
+=head1 GOPHER METHODS
+
+The methods access the parts that are specific for the gopher URLs.
+These methods access different parts of the $url->path.
+
+=over 3
+
+=item $url->gtype (*)
+
+=item $url->selector (*)
+
+=item $url->search (*)
+
+=item $url->string (*)
+
+=back
+
+=head1 NEWS METHODS
+
+=over 3
+
+=item $url->group (*)
+
+=item $url->article (*)
+
+=back
+
+=head1 WAIS METHODS
+
+The methods access the parts that are specific for the wais URLs.
+These methods access different parts of the $url->path.
+
+=over 3
+
+=item $url->database (*)
+
+=item $url->wtype (*)
+
+=item $url->wpath (*)
+
+=back
+
+=head1 MAILTO METHODS
+
+=over 3
+
+=item $url->address (*)
+
+The mail address can also be accessed with the netloc() method.
+
+=back
+
+
+=head1 WHAT A URL IS NOT
+
+URL objects do not, and should not, know how to 'get' or 'put' the
+resources they specify locations for, anymore than a postal address
+'knows' anything about the postal system. The actual access/transfer
+should be achieved by some form of transport agent class (see
+L<LWP::UserAgent>). The agent class can use the URL class, but should
+not be a subclass of it.
+
+=head1 AUTHORS / ACKNOWLEDGMENTS
+
+This module is (distantly) based on the C<wwwurl.pl> code in the
+libwww-perl distribution developed by Roy Fielding
+<fielding@ics.uci.edu>, as part of the Arcadia project at the
+University of California, Irvine, with contributions from Brooks
+Cutter.
+
+Gisle Aas <aas@sn.no>, Tim Bunce <Tim.Bunce@ig.co.uk>, Roy Fielding
+<fielding@ics.uci.edu> and Martijn Koster <m.koster@webcrawler.com>
+(in English alphabetical order) have collaborated on the complete
+rewrite for Perl 5, with input from other people on the libwww-perl
+mailing list.
+
+If you have any suggestions, bug reports, fixes, or enhancements, send
+them to the libwww-perl mailing list at <libwww-perl@ics.uci.edu>.
+
+=head1 COPYRIGHT
+
+Copyright 1995-1997 Gisle Aas.
+Copyright 1995 Martijn Koster.
+
+This program is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/_generic.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/_generic.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/_generic.pm	(revision 20131)
@@ -0,0 +1,514 @@
+#####################################################################
+#
+#       Internal pre-defined generic scheme support
+#
+# In this implementation all schemes are subclassed from
+# URI::URL::_generic. This turns out to have reasonable mileage.
+# See also draft-ietf-uri-relative-url-06.txt
+
+package URI::URL::_generic;           # base support for generic-RL's
+require URI::URL;
+@ISA = qw(URI::URL);
+
+use URI::Escape qw(uri_escape uri_unescape %escapes);
+
+
+sub new {                               # inherited by subclasses
+    my($class, $init, $base) = @_;
+    my $url = bless { }, $class;        # create empty object
+    $url->_parse($init);                # parse $init into components
+    $url->base($base) if $base;
+    $url;
+}
+
+
+# Generic-RL parser
+# See draft-ietf-uri-relative-url-06.txt Section 2
+
+sub _parse {
+    my($self, $u, @comps) = @_;
+    return unless defined $u;
+
+    # Deside which components to parse (scheme & path is manatory)
+    @comps = qw(netloc query params frag) unless (@comps);
+    my %parse = map {$_ => 1} @comps;
+
+    # This parsing code is based on
+    #   draft-ietf-uri-relative-url-06.txt Section 2.4
+
+    # 2.4.1
+    $self->{'frag'} = uri_unescape($1)
+      if $parse{'frag'} && $u =~ s/#(.*)$//;
+    # 2.4.2
+    $self->{'scheme'} = lc($1) if $u =~ s/^\s*([\w\+\.\-]+)://;
+    # 2.4.3
+    $self->netloc("$1")	# passing $1 directly fails if netloc is autoloaded
+      if $parse{'netloc'} && $u =~ s!^//([^/]*)!!;
+    # 2.4.4
+    $self->{'query'} = $1
+      if $parse{'query'} && $u =~ s/\?(.*)//;
+    # 2.4.5
+    $self->{'params'} = $1
+      if $parse{'params'} && $u =~ s/;(.*)//;
+
+    # 2.4.6
+    #
+    # RFC 1738 says:
+    #
+    #     Note that the "/" between the host (or port) and the
+    #     url-path is NOT part of the url-path.
+    #
+    # however, RFC 1808, 2.4.6. says:
+    #
+    #    Even though the initial slash is not part of the URL path,
+    #    the parser must remember whether or not it was present so
+    #    that later processes can differentiate between relative
+    #    and absolute paths.  Often this is done by simply storing
+    #    he preceding slash along with the path.
+    #
+    # In version < 4.01 of URI::URL we used to strip the leading
+    # "/" when asked for $self->path().  This created problems for
+    # the consitency of the interface, so now we just consider the
+    # slash to be part of the path and we also make an empty path
+    # default to "/".
+
+    # we don't test for $parse{path} becase it is mandatory
+    $self->{'path'} = $u;
+}
+
+
+# Generic-RL stringify
+#
+sub as_string
+{
+    my $self = shift;
+    return $self->{'_str'} if $self->{'_str'};
+
+    my($scheme, $netloc, $frag) = @{$self}{qw(scheme netloc frag)};
+
+    my $u = $self->full_path(1);  # path+params+query
+
+    # rfc 1808 says:
+    #    Note that the fragment identifier (and the "#" that precedes
+    #    it) is not considered part of the URL.  However, since it is
+    #    commonly used within the same string context as a URL, a parser
+    #    must be able to recognize the fragment when it is present and
+    #    set it aside as part of the parsing process.
+    $u .= "#" . uri_escape($frag, $URI::URL::unsafe) if defined $frag;
+
+    $u = "//$netloc$u" if defined $netloc;
+    $u = "$scheme:$u" if $scheme;
+    # Inline: uri_escape($u, $URI::URL::unsafe);
+    $u =~ s/([$URI::URL::unsafe])/$escapes{$1}/go;
+    $self->{'_str'} = $u;  # set cache and return
+}
+
+# Generic-RL stringify full path "path;params?query"
+#
+sub full_path
+{
+    my($self, $dont_escape)  = @_;
+    my($path, $params, $query) = @{$self}{'path', 'params', 'query'};
+    my $p = '';
+    $p .= $path if defined $path;
+    # see comment in _parse 2.4.6 about the next line
+    $p = "/$p" if defined($self->{netloc}) && $p !~ m:^/:;
+    $p .= ";$params" if defined $params;
+    $p .= "?$query"  if defined $query;
+    return $p if $dont_escape;
+    # Inline: URI::Escape::uri_escape($p, $URI::URL::unsafe);
+    $p =~ s/([$URI::URL::unsafe])/$escapes{$1}/go;
+    $p;
+}
+
+# default_port()
+#
+# subclasses will usually want to override this
+#
+sub default_port { undef; }
+
+
+#####################################################################
+#
+# Methods to handle URL's elements
+
+# These methods always return the current value,
+# so you can use $url->path to read the current value.
+# If a new value is passed, e.g. $url->path('foo'),
+# it also sets the new value, and returns the previous value.
+# Use $url->path(undef) to set the value to undefined.
+
+sub netloc {
+    my $self = shift;
+    my $old = $self->_elem('netloc', @_);
+    return $old unless @_;
+
+    # update fields derived from netloc
+    my $nl = $self->{'netloc'} || '';
+    if ($nl =~ s/^([^:@]*):?(.*?)@//){
+	$self->{'user'}     = uri_unescape($1);
+	$self->{'password'} = uri_unescape($2) if $2 ne '';
+    }
+    if ($nl =~ /^([^:]*):?(\d*)$/){
+	my $port = $2;
+	# Since this happes so frequently, we inline this call:
+	#    my $host = uri_unescape($1);
+	my $host = $1;
+	$host =~ s/%([\dA-Fa-f]{2})/chr(hex($1))/eg;
+	$self->{'host'} = $host;
+	if ($port ne '') {
+	    $self->{'port'} = $port;
+	    if ($self->default_port == $port) {
+		$self->{'netloc'} =~ s/:\d+//;
+	    }
+	} elsif (defined $self->{'netloc'}) {
+	    $self->{'netloc'} =~ s/:$//;  # handle empty port spec
+	}
+    }
+    $self->{'_str'} = '';
+    $old;
+}
+
+
+# A U T O  L O A D E R
+# Don't remove this comment, it keeps AutoSplit happy!!
+# @ISA = qw(AutoLoader)
+#
+# The rest of the methods are only loaded on demand.  Stubs are neccesary
+# for inheritance to work.
+
+#sub netloc;  # because netloc is used by the _parse()
+sub user;
+sub password;
+sub host;
+sub port;
+sub _netloc_elem;
+sub epath;
+sub path;
+sub path_components;
+sub eparams;
+sub params;
+sub equery;
+sub query;
+sub frag;
+sub crack;
+sub abs;
+sub rel;
+sub eq;
+
+1;
+__END__
+
+
+# Fields derived from generic netloc:
+sub user     { shift->_netloc_elem('user',    @_); }
+sub password { shift->_netloc_elem('password',@_); }
+sub host     { shift->_netloc_elem('host',    @_); }
+
+sub port {
+    my $self = shift;
+    my $old = $self->_netloc_elem('port', @_);
+    defined($old) ? $old : $self->default_port;
+}
+
+sub _netloc_elem {
+    my($self, $elem, @val) = @_;
+    my $old = $self->_elem($elem, @val);
+    return $old unless @val;
+
+    # update the 'netloc' element
+    my $nl = '';
+    my $host = $self->{'host'};
+    if (defined $host) {  # can't be any netloc without any host
+	my $user = $self->{'user'};
+	$nl .= uri_escape($user, $URI::URL::reserved) if defined $user;
+	$nl .= ":" . uri_escape($self->{'password'}, $URI::URL::reserved)
+	  if defined($user) and defined($self->{'password'});
+	$nl .= '@' if length $nl;
+	$nl .= uri_escape($host, $URI::URL::reserved);
+	my $port = $self->{'port'};
+	$nl .= ":$port" if defined($port) && $port != $self->default_port;
+    }
+    $self->{'netloc'} = $nl;
+    $self->{'_str'} = '';
+    $old;
+}
+
+sub epath {
+     my $self = shift;
+     my $old = $self->_elem('path', @_);
+     return '/' if !defined($old) || !length($old);
+     return "/$old" if $old !~ m|^/| && defined $self->{'netloc'};
+     $old;
+}
+
+sub path {
+    my $self = shift;
+    my $old = $self->_elem('path',
+		      map uri_escape($_, $URI::URL::reserved_no_slash), @_);
+    return unless defined wantarray;
+    return '/' if !defined($old) || !length($old);
+    Carp::croak("Path components contain '/' (you must call epath)")
+	if $old =~ /%2[fF]/ and !@_;
+    $old = "/$old" if $old !~ m|^/| && defined $self->{'netloc'};
+    return uri_unescape($old);
+}
+
+sub path_components {
+    my $self = shift;
+    my $old = $self->{'path'};
+    $old = '' unless defined $old;
+    $old = "/$old" if $old !~ m|^/| && defined $self->{'netloc'};
+    if (@_) {
+	$self->_elem('path',
+		     join("/", map {uri_escape($_, $URI::URL::reserved)} @_));
+    }
+    map { uri_unescape($_) } split("/", $old, -1);
+}
+
+sub eparams  { shift->_elem('params',  @_); }
+
+sub params {
+    my $self = shift;
+    my $old = $self->_elem('params', map {uri_escape($_,$URI::URL::reserved_no_form)} @_);
+    return uri_unescape($old) if defined $old;
+    undef;
+}
+
+sub equery   { shift->_elem('query',   @_); }
+
+sub query {
+    my $self = shift;
+    my $old = $self->_elem('query', map { uri_escape($_, $URI::URL::reserved_no_form) } @_);
+    if (defined(wantarray) && defined($old)) {
+	if ($old =~ /%(?:26|2[bB]|3[dD])/) {  # contains escaped '=' '&' or '+'
+	    my $mess;
+	    for ($old) {
+		$mess = "Query contains both '+' and '%2B'"
+		  if /\+/ && /%2[bB]/;
+		$mess = "Form query contains escaped '=' or '&'"
+		  if /=/  && /%(?:3[dD]|26)/;
+	    }
+	    if ($mess) {
+		Carp::croak("$mess (you must call equery)");
+	    }
+	}
+	# Now it should be safe to unescape the string without loosing
+	# information
+	return uri_unescape($old);
+    }
+    undef;
+
+}
+
+# No efrag method because the fragment is always stored unescaped
+sub frag     { shift->_elem('frag', @_); }
+
+sub crack
+{
+    my $self = shift;
+    return $self unless wantarray;
+    my @c = @{$self}{qw(scheme user password host port path params query frag)};
+    if (!$c[0]) {
+	# try to determine scheme
+	my $base = $self->base;
+	$c[0] = $base->scheme if $base;
+	$c[0] ||= 'http';  # last resort, default in URI::URL::new
+    }
+    $c[4] ||= $self->default_port;
+    @c;
+}
+
+# Generic-RL: Resolving Relative URL into an Absolute URL
+#
+# Based on RFC1808 section 4
+#
+sub abs
+{
+    my($self, $base, $allow_relative_scheme) = @_;
+    $allow_relative_scheme = $URI::URL::ABS_ALLOW_RELATIVE_SCHEME if @_ < 3;
+    my $embed = $self->clone;
+
+    $base = $self->base unless $base;      # default to default base
+    return $embed unless $base;            # we have no base (step1)
+
+    $base = new URI::URL $base unless ref $base; # make obj if needed
+
+    my($scheme, $host, $path, $params, $query, $frag) =
+	@{$embed}{qw(scheme host path params query frag)};
+
+    # just use base if we are empty             (2a)
+    return $base->clone
+      unless grep(defined($_) && $_ ne '',
+		  $scheme,$host,$port,$path,$params,$query,$frag);
+
+    # if we have a scheme we must already be absolute   (2b),
+    #
+    # but sec. 5.2 also says: Some older parsers allow the scheme name
+    # to be present in a relative URL if it is the same as the base
+    # URL scheme.  This is considered to be a loophole in prior
+    # specifications of the partial URLs and should be avoided by
+    # future parsers.
+    #
+    # The old behavoir can be enabled by passing a TRUE value to the
+    # $allow_relative_scheme parameter.
+    return $embed if $scheme &&
+      (!$allow_relative_scheme || $scheme ne $base->{'scheme'});
+
+    $embed->{'_str'} = '';                      # void cached string
+    $embed->{'scheme'} = $base->{'scheme'};     # (2c)
+
+    return $embed if $embed->{'netloc'};        # (3)
+    $embed->netloc($base->{'netloc'});          # (3)
+
+    return $embed if $path =~ m:^/:;            # (4)
+
+    if ($path eq '') {                          # (5)
+	$embed->{'path'} = $base->{'path'};     # (5)
+
+	return $embed if defined $embed->{'params'}; # (5a)
+	$embed->{'params'} = $base->{'params'};      # (5a)
+
+	return $embed if defined $embed->{'query'};  # (5b)
+	$embed->{'query'} = $base->{'query'};        # (5b)
+
+	return $embed;
+    }
+
+    # (Step 6)  # draft 6 suggests stack based approach
+
+    my $basepath = $base->{'path'};
+    my $relpath  = $embed->{'path'};
+
+    $basepath =~ s!^/!!;
+    $basepath =~ s!/$!/.!;                # prevent empty segment
+    my @path = split('/', $basepath);     # base path into segments
+    pop(@path);                           # remove last segment
+
+    $relpath =~ s!/$!/.!;                 # prevent empty segment
+
+    push(@path, split('/', $relpath));    # append relative segments
+
+    my @newpath = ();
+    my $isdir = 0;
+    my $segment;
+
+    foreach $segment (@path) {            # left to right
+	if ($segment eq '.') {            # ignore "same" directory
+	    $isdir = 1;
+	}
+	elsif ($segment eq '..') {
+	    $isdir = 1;
+	    my $last = pop(@newpath);
+	    if (!defined $last) {         # nothing to pop
+		push(@newpath, $segment); # so must append
+	    }
+	    elsif ($last eq '..') {       # '..' cannot match '..'
+		# so put back again, and append
+		push(@newpath, $last, $segment);
+	    }
+	    #else
+		# it was a component,
+		# keep popped
+	} else {
+	    $isdir = 0;
+	    push(@newpath, $segment);
+	}
+    }
+
+    if ($URI::URL::ABS_REMOTE_LEADING_DOTS) {
+	shift @newpath while @newpath && $newpath[0] =~ /^\.\.?$/;
+    }
+
+    $embed->{'path'} = '/' . join('/', @newpath) .
+	($isdir && @newpath ? '/' : '');
+
+    $embed;
+}
+
+# The oposite of $url->abs.  Return a URL as much relative as possible
+sub rel {
+    my($self, $base) = @_;
+    my $rel = $self->clone;
+    $base = $self->base unless $base;
+    return $rel unless $base;
+    $base = new URI::URL $base unless ref $base;
+    $rel->base($base);
+
+    my($scheme, $netloc, $path) = @{$rel}{qw(scheme netloc path)};
+    if (!defined($scheme) && !defined($netloc)) {
+	# it is already relative
+	return $rel;
+    }
+
+    my($bscheme, $bnetloc, $bpath) = @{$base}{qw(scheme netloc path)};
+    for ($bscheme, $bnetloc, $netloc) { $_ = '' unless defined }
+
+    unless ($scheme eq $bscheme && $netloc eq $bnetloc) {
+	# different location, can't make it relative
+	return $rel;
+    }
+
+    for ($path, $bpath) {  $_ = "/$_" unless m,^/,; }
+
+    # Make it relative by eliminating scheme and netloc
+    $rel->{'scheme'} = undef;
+    $rel->netloc(undef);
+
+    # This loop is based on code from Nicolai Langfeldt <janl@ifi.uio.no>.
+    # First we calculate common initial path components length ($li).
+    my $li = 1;
+    while (1) {
+	my $i = index($path, '/', $li);
+	last if $i < 0 ||
+                $i != index($bpath, '/', $li) ||
+	        substr($path,$li,$i-$li) ne substr($bpath,$li,$i-$li);
+	$li=$i+1;
+    }
+    # then we nuke it from both paths
+    substr($path, 0,$li) = '';
+    substr($bpath,0,$li) = '';
+
+    if ($path eq $bpath && defined($rel->frag) && !defined($rel->equery)) {
+        $rel->epath('');
+    } else {
+        # Add one "../" for each path component left in the base path
+        $path = ('../' x $bpath =~ tr|/|/|) . $path;
+	$path = "./" if $path eq "";
+        $rel->epath($path);
+    }
+
+    $rel;
+}
+
+
+# Compare two URLs
+sub eq {
+    my($self, $other) = @_;
+    local($^W) = 0; # avoid warnings if we compare undef values
+    $other = URI::URL->new($other, $self) unless ref $other;
+
+    # Compare scheme and netloc
+    return 0 if ref($self) ne ref($other);                # must be same class
+    return 0 if $self->scheme ne $other->scheme;          # Always lower case
+    return 0 if lc($self->netloc) ne lc($other->netloc);  # Case-insensitive
+
+    # Compare full_path:
+    # According to <draft-ietf-http-v11-spec-05>:
+    # Characters other than those in the "reserved" and "unsafe" sets
+    # are equivalent to their %XX encodings.
+    my $fp1 = $self->full_path;
+    my $fp2 = $other->full_path;
+    for ($fp1, $fp2) {
+	s,%([\dA-Fa-f]{2}),
+	  my $x = $1;
+	  my $c = chr(hex($x));
+	  $c =~ /^[;\/?:\@&=+\"\#%<>\0-\040\177]/ ? "%\L$x" : $c;
+	,eg;
+    }
+    return 0 if $fp1 ne $fp2;
+    return 0 if $self->frag ne $other->frag;
+    1;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/_login.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/_login.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/_login.pm	(revision 20131)
@@ -0,0 +1,25 @@
+package URI::URL::_login;
+require URI::URL::_generic;
+@ISA = qw(URI::URL::_generic);
+
+
+# Generic terminal logins.  This is used as a base class for 'telnet',
+# 'tn3270', and 'rlogin' URL schemes.
+
+
+sub _parse {
+    my($self, $init) = @_;
+    # All we want from _generic is the 'netloc' handling.
+    $self->URI::URL::_generic::_parse($init, 'netloc');
+}
+
+
+*path      = \&URI::URL::bad_method;
+*epath     = \&URI::URL::bad_method;
+*query     = \&URI::URL::bad_method;
+*equery    = \&URI::URL::bad_method;
+*params    = \&URI::URL::bad_method;
+*eparams   = \&URI::URL::bad_method;
+*frag      = \&URI::URL::bad_method;
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/data.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/data.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/data.pm	(revision 20131)
@@ -0,0 +1,160 @@
+package URI::URL::data;
+
+# Implements data:-URLs as specified in draft-masinter-url-data-02.txt
+#
+# Abstract
+#
+# A new URL scheme, "data", is defined. It allows inclusion of small
+# data items as "immediate" data, as if it had been included externally.
+#
+# Description
+#
+# Some applications that use URLs also have a need to embed (small)
+# media type data directly inline. This document defines a new URL
+# scheme that would work like 'immediate addressing'. The URLs are of
+# the form:
+#
+#        data:[<mediatype>][;base64],<data>
+#
+
+require URI::URL;
+@ISA = qw(URI::URL);
+
+use URI::Escape;
+use MIME::Base64 ();
+
+# as defined in rfc1522.txt
+my $tspecial  = qq(()<>@,;:/[]?.=);
+my $tokenchar = qq([^\\s\000-\037\177-\377\Q$tspecial\E]);
+
+
+sub new {
+    my($class, $init, $base) = @_;
+
+    my $self = bless { }, $class;
+
+    $self->{'scheme'} = lc($1) if $init =~ s/^\s*([\w\+\.\-]+)://;
+    $self->{'frag'} = $1 if $init =~ s/\#(.*)$//;
+
+    my $type = "";
+    if ($init =~ s/^($tokenchar+\/$tokenchar+)//o) {
+	$type = $1;
+    }
+    while ($init =~ s/^;($tokenchar+)=([^,;]*)//o) {
+	# XXX should we unescape the parst
+	$type .= ";$1=$2";
+    }
+
+    $self->{'media_type'} = $type;
+
+    my $base64;
+    if ($init =~ s/^;base64//i) {
+	$base64 = 1;
+    }
+    
+    $init =~ s/^,//;
+    if ($base64) {
+	$self->{'base64'} = uri_unescape($init);
+    } else {
+	$self->{'data'} = uri_unescape($init);
+    }
+    $self->base($base) if $base;
+    $self;
+}
+
+sub media_type
+{
+    my $self = shift;
+    my $old = $self->{'media_type'};
+    if (@_) {
+	$self->{'media_type'} = shift || "";
+	delete $self->{'_str'};
+    }
+    my($type, $param) = split(/;/, $old, 2);
+    if ($type) {
+	$type = lc $type;
+    } else {
+	$type = "text/plain";
+	$param = "charset=US-ASCII" unless $param;
+    }
+    if (wantarray) {
+	return ($type, $param);
+    } else {
+	return $type;
+    }
+}
+
+sub data
+{
+    my $self = shift;
+    my $old_data;
+    my $old_base64;
+    $old_data = $self->{'data'};
+    $old_base64 = $self->{'base64'};
+    if (@_) {
+	if ($_[1]) { # base64 flag
+	    $self->{'base64'} = $_[0];
+	    delete $self->{'data'};
+	} else {
+	    $self->{'data'} = $_[0];
+	    delete $self->{'base64'};
+	}
+	delete $self->{'_str'};
+    }
+    unless (defined $old_data) {
+	$old_data = MIME::Base64::decode($old_base64);
+	$self->{'data'} = $old_data unless @_;
+    }
+    $old_data;
+}
+
+
+sub crack
+{
+    my $self = shift;
+    ($self->{'scheme'}
+     || 'data',          # scheme
+     undef,              # user
+     undef,              # passwd
+     undef,              # host
+     undef,              # port
+     $self->data,        # path
+     $self->{'media_type'},  # params
+     undef,              # query
+     $self->{'frag'}     # fragment
+    )
+}
+
+sub as_string {
+    my $self = shift;
+    return $self->{'_str'} if $self->{'_str'};
+    my $str = ($self->{'scheme'} || 'data') . ":";
+    $str .= $self->{'media_type'};
+    if (defined $self->{'base64'}) {
+	$str .= ";base64,$self->{'base64'}";
+    } else {
+	my $urlenc = uri_escape($self->{'data'});
+	my $base64 = MIME::Base64::encode($self->{'data'});
+	if (length($base64) + 7 < length($urlenc)) {
+	    $str .= ";base64,$base64";
+	    $self->{'base64'} = $base64;
+	} else {
+	    $str .= ",$urlenc";
+	}
+    }
+    $self->{'_str'} = $str;
+}
+
+sub eq {
+    my($self, $other) = @_;
+    return 0 if ref($self) ne ref($other);
+    return 0 if $self->scheme ne $other->scheme;
+
+    my $mt1 = join(";", $self->media_type);
+    my $mt2 = join(";", $other->media_type);
+    return 0 if $mt1 ne $mt2;
+
+    $self->data eq $other->data;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/file.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/file.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/file.pm	(revision 20131)
@@ -0,0 +1,165 @@
+package URI::URL::file;
+require URI::URL::_generic;
+@ISA = qw(URI::URL::_generic);
+
+require Carp;
+require Config;
+
+# First we try to determine what kind of system we run on
+my $os = $Config::Config{'osname'};
+OS: {
+    $ostype = 'vms', last if $os eq 'VMS';
+    $ostype = 'dos', last if $os =~ /^(?:os2|mswin32|msdos)$/i;
+    $ostype = 'mac', last if $os eq "Mac";
+    $ostype = 'unix';  # The default
+}
+# NOTE: If you add more types to this list, remember to add a xxx_path
+# method as well.
+
+# This is the BNF found in RFC 1738:
+#
+# fileurl        = "file://" [ host | "localhost" ] "/" fpath
+# fpath          = fsegment *[ "/" fsegment ]
+# fsegment       = *[ uchar | "?" | ":" | "@" | "&" | "=" ]
+# Note that fsegment can contain '?' (query) but not ';' (param)
+
+sub _parse {
+    my($self, $init) = @_;
+    # The file URL can't have query
+    $self->URI::URL::_generic::_parse($init, qw(netloc path params frag));
+}
+
+# sub local_path { ... }
+#
+# Returns a path suitable for use on the local system (we just
+# set up an alias (derived from $ostype) to one of the path methods
+# defined below)
+*local_path = \&{$ostype . "_path"};
+
+*query  = \&URI::URL::bad_method;
+*equery = \&URI::URL::bad_method;
+
+# A U T O  L O A D E R
+# Don't remove this comment, it keeps AutoSplit happy!!
+# @ISA = qw(AutoLoader)
+#
+# These methods are autoloaded as needed
+sub newlocal;
+sub unix_path;
+sub dos_path ;
+sub mac_path ;
+sub vms_path ;
+1;
+__END__
+
+sub newlocal {
+    my($class, $path) = @_;
+
+    Carp::croak("Only implemented for Unix and OS/2 file systems")
+      unless $ostype eq "unix" or $^O =~ /os2|mswin32/i;
+    # XXX: Should implement the same thing for other systems
+
+    my $url = new URI::URL "file:";
+    unless (defined $path and
+    	    ($path =~ m:^/: or 
+	     ($^O eq 'os2' and Cwd::sys_is_absolute($path)) or
+	     ($^O eq 'MSWin32' and $path =~ m<^[A-Za-z]:[\\/]|^[\\/]{2}>))) {
+	require Cwd;
+	my $cwd = Cwd::fastcwd();
+	$cwd =~ s:/?$:/:; # force trailing slash on dir
+	$path = (defined $path) ? $cwd . $path : $cwd;
+    }
+    $url->path($path);
+    $url;
+}
+
+sub unix_path
+{
+    my $self = shift;
+    my @p;
+    for ($self->path_components) {
+	Carp::croak("Path component contains '/' or '\0'") if m|[\0/]|;
+	if (@p) {
+	    next unless length $_;   # skip empty path segments
+	    next if $_ eq '.';       # skip these too
+	    if ($_ eq '..' && $p[-1] ne '..') {  # go up one level
+		pop(@p) if $p[-1] ne '';
+		next;
+	    }
+	}
+	push(@p, $_);
+    }
+    shift(@p) if @p > 1 && $p[0] eq '.';   # './' rendundant if there is more
+    return '/' if !@p || (@p == 1 && $p[0] eq '');
+    join('/', @p);
+}
+
+sub dos_path
+{
+    my $self = shift;
+    my @p;
+    for ($self->path_components) {
+	Carp::croak("Path component contains '/' or '\\'") if m|[/\\]|;
+	push(@p, uc $_);
+    }
+    my $p = join("\\", @p);
+    $p =~ s/^\\([A-Z]:)/$1/;  # Fix drive letter specification
+    $p;
+}
+
+sub mac_path
+{
+    my $self = shift;
+    my @p;
+    for ($self->path_components) {
+	Carp::croak("Path component contains ':'") if /:/;
+	# XXX: Should probably want to do something about ".." and "."
+	# path segments.  I don't know how these are represented in
+	# the Machintosh file system.  If these are valid file names
+	# then we should split the path ourself, as $u->path_components
+	# loose the distinction between '.' and '%2E'.
+	push(@p, $_);
+    }
+    if (@p && $p[0] eq '') {
+	shift @p;
+    } else {
+	unshift(@p, '');
+    }
+    join(':', @p);
+}
+
+sub vms_path
+{
+    # ????? Can some VMS people please redo this function ??????
+
+    # This is implemented based on what RFC1738 (sec 3.10) says in the
+    # VMS file example:
+    #
+    #  DISK$USER:[MY.NOTES]NOTE123456.TXT
+    #
+    #      that might become
+    #
+    #  file:/disk$user/my/notes/note12345.txt
+    #
+    # BEWARE: I don't have a VMS machine myself so this is pure guesswork!!!
+
+    my $self = shift;
+    my @p = $self->path_components;
+    my $abs = 0;
+    if (@p && $p[0] eq '') {
+	shift @p;
+	$abs = 1;
+    }
+    # First I assume there must be a dollar in a disk spesification
+    my $p = '';
+    $p = uc(shift(@p)) . ":"  if @p && $p[0] =~ /\$/;
+    my $file = pop(@p);
+    $p .= "[" . join(".", map{uc($_)} @p) . "]" if @p;
+    $p .= uc $file;
+    # XXX: How is an absolute path different from a relative one??
+    $p =~ s/\[/[./ unless $abs;
+    # XXX: How is a directory denoted??
+    $p;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/finger.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/finger.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/finger.pm	(revision 20131)
@@ -0,0 +1,6 @@
+package URI::URL::finger;
+require URI::URL::_generic;
+@ISA = qw(URI::URL::_generic);
+
+sub default_port { 79 }
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/ftp.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/ftp.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/ftp.pm	(revision 20131)
@@ -0,0 +1,76 @@
+package URI::URL::ftp;
+require URI::URL::_generic;
+@ISA = qw(URI::URL::_generic);
+
+sub default_port { 21 }
+
+sub _parse {
+    my($self, $init) = @_;
+    # The ftp URLs can't have any query string
+    $self->URI::URL::_generic::_parse($init, qw(netloc path params frag));
+    1;
+}
+
+
+sub user
+{
+    my($self, @val) = @_;
+    my $old = $self->SUPER::user(@val);
+    defined $old ? $old : "anonymous";
+}
+
+BEGIN {
+    $whoami = undef;
+    $fqdn   = undef;
+}
+
+sub password
+{
+    my($self, @val) = @_;
+    my $old = $self->SUPER::password(@val);
+    unless (defined $old) {
+	my $user = $self->user;
+	if ($user eq 'anonymous' || $user eq 'ftp') {
+	    # anonymous ftp login password
+	    unless (defined $fqdn) {
+		eval {
+		    require Net::Domain;
+		    $fqdn = Net::Domain::hostfqdn();
+		};
+		if ($@) {
+		    $fqdn = '';
+		}
+	    }
+	    unless (defined $whoami) {
+		$whoami = $ENV{USER} || $ENV{LOGNAME} || $ENV{USERNAME};
+		unless ($whoami) {
+		    if ($^O eq 'MSWin32') { $whoami = Win32::LoginName() }
+		    else {
+		        $whoami = getlogin || getpwuid($<) || 'unknown';
+		    }
+		}
+	    }
+	    $old = "$whoami\@$fqdn";
+	} else {
+	    $old = "";
+	}
+    }
+    $old;
+}
+
+sub crack
+{
+    my $self = shift;
+    my @c = $self->SUPER::crack;
+    if ($c[3] && !$c[1]) {
+	# hostname defined, but user is undefined
+	$c[1] = $self->user;
+	$c[2] = $self->password;
+    }
+    @c;
+}
+
+*query  = \&URI::URL::bad_method;
+*equery = \&URI::URL::bad_method;
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/gopher.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/gopher.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/gopher.pm	(revision 20131)
@@ -0,0 +1,82 @@
+package URI::URL::gopher;
+require URI::URL::_generic;
+@ISA = qw(URI::URL::_generic);
+
+use URI::Escape qw(uri_unescape);
+
+sub default_port { 70 }
+
+sub _parse {
+    my($self, $init)   = @_;
+    $self->URI::URL::_generic::_parse($init, qw(netloc path));
+    $self->_parse_gopherpath;
+}
+
+sub path {
+    my $self = shift;
+    my $old = $self->URI::URL::_generic::path(@_);
+    return $old unless @_;
+    $self->_parse_gopherpath;
+    $old;
+}
+
+sub epath {
+    my $self = shift;
+    my $old = $self->URI::URL::_generic::epath(@_);
+    return $old unless @_;
+    $self->_parse_gopherpath;
+    $old;
+}
+
+sub _parse_gopherpath {
+    my $self = shift;
+    my $p = $self->{'path'};
+    # not according to RFC1738, but many popular browsers accept
+    # gopher URLs with a '?' before the search string.
+    $p =~ s/\?/\t/;
+    $p = uri_unescape($p);
+
+    if (defined($p) && $p ne '/' && $p =~ s!^/?(.)!!) {
+	$self->{'gtype'} = $1;
+    } else {
+	$self->{'gtype'} = "1";
+	$p = "";
+    }
+
+    delete $self->{'selector'};
+    delete $self->{'search'};
+    delete $self->{'string'};
+
+    my @parts = split(/\t/, $p, 3);
+    $self->{'selector'} = shift @parts if @parts;
+    $self->{'search'}   = shift @parts if @parts;
+    $self->{'string'}   = shift @parts if @parts;
+}
+
+
+sub gtype    { shift->_path_elem('gtype',    @_); }
+sub selector { shift->_path_elem('selector', @_); }
+sub search   { shift->_path_elem('search',   @_); }
+sub string   { shift->_path_elem('string',   @_); }
+
+sub _path_elem {
+    my($self, $elem, @val) = @_;
+    my $old = $self->_elem($elem, @val);
+    return $old unless @val;
+
+    # construct new path based on elements
+    my $path = "/$self->{'gtype'}";
+    $path .= "$self->{'selector'}" if defined $self->{'selector'};
+    $path .= "\t$self->{'search'}" if defined $self->{'search'};
+    $path .= "\t$self->{'string'}" if defined $self->{'string'};
+    $self->{'path'} = $path;
+
+    $old;
+}
+
+*params  = \&URI::URL::bad_method;
+*qparams = \&URI::URL::bad_method;
+*query   = \&URI::URL::bad_method;
+*equery  = \&URI::URL::bad_method;
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/http.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/http.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/http.pm	(revision 20131)
@@ -0,0 +1,57 @@
+package URI::URL::http;
+require URI::URL::_generic;
+@ISA = qw(URI::URL::_generic);
+
+sub default_port { 80 }
+
+require Carp;
+
+# @ISA = qw(AutoLoader)      # This comment is needed by AutoSplit.
+sub keywords;
+sub query_form;
+1;
+__END__
+
+# Handle ...?dog+bones type of query
+sub keywords {
+    my $self = shift;
+    $old = $self->{'query'};
+    if (@_) {
+	# Try to set query string
+	$self->equery(join('+', map { URI::Escape::uri_escape($_, $URI::URL::reserved) } @_));
+    }
+    return if !defined($old) || !defined(wantarray);
+
+    Carp::croak("Query is not keywords") if $old =~ /=/;
+    map { URI::Escape::uri_unescape($_) } split(/\+/, $old);
+}
+
+# Handle ...?foo=bar&bar=foo type of query
+sub query_form {
+    my $self = shift;
+    $old = $self->{'query'};
+    if (@_) {
+	# Try to set query string
+	my @query;
+	my($key,$vals);
+        my $esc = $URI::URL::reserved . $URI::URL::unsafe;
+	while (($key,$vals) = splice(@_, 0, 2)) {
+	    $key = '' unless defined $key;
+	    $key =  URI::Escape::uri_escape($key, $esc);
+	    $vals = [$vals] unless ref($vals) eq 'ARRAY';
+	    my $val;
+	    for $val (@$vals) {
+		$val = '' unless defined $val;
+		$val = URI::Escape::uri_escape($val, $esc);
+		push(@query, "$key=$val");
+	    }
+	}
+	$self->equery(join('&', @query));
+    }
+    return if !defined($old) || length($old) == 0 || !defined(wantarray);
+    Carp::croak("Query is not a form") unless $old =~ /=/;
+    map { s/\+/ /g; URI::Escape::uri_unescape($_) }
+	 map { /=/ ? split(/=/, $_, 2) : ($_ => '')} split(/&/, $old);
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/https.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/https.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/https.pm	(revision 20131)
@@ -0,0 +1,6 @@
+package URI::URL::https;
+require URI::URL::http;
+@ISA = qw(URI::URL::http);
+
+sub default_port { 443 }
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/mailto.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/mailto.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/mailto.pm	(revision 20131)
@@ -0,0 +1,78 @@
+package URI::URL::mailto;
+require URI::URL;
+@ISA = qw(URI::URL);
+
+use URI::Escape;
+
+sub new {
+    my($class, $init, $base) = @_;
+
+    my $self = bless { }, $class;
+    $self->{'scheme'} = lc($1) if $init =~ s/^\s*([\w\+\.\-]+)://;
+    $self->{'address'} = uri_unescape($init);
+    $self->base($base) if $base;
+    $self;
+}
+
+sub address { shift->_elem('address', @_); }
+
+# can use these as aliases
+*encoded822addr = \&address;   # URI::URL v3 compatibility
+*netloc         = \&address;
+
+sub user {
+    my $self = shift;
+    $old = $self->{'address'};
+    if (@_) {
+	my $new = $old;
+	$new =~ s/.*\@?/$_[0]\@/;
+	$self->{'address'} = $new;
+    }
+    $old =~ s/\@.*//;
+    $old;
+}
+
+sub host {
+    my $self = shift;
+    $old = $self->{'address'};
+    if (@_) {
+	my $new = $old;
+	$new =~ s/\@.*/\@$_[0]/;
+	$self->{'address'} = $new;
+    }
+    $old =~ s/.*\@//;
+    $old;
+}
+
+sub crack
+{
+    my $self = shift;
+    ('mailto',           # scheme
+     $self->user,        # user
+     undef,              # passwd
+     $self->host,        # host
+     undef,              # port
+     $self->{'address'}, # path
+     undef,              # params
+     undef,              # query
+     undef               # fragment
+    )
+}
+
+sub as_string {
+    my $self = shift;
+    my $str = ($self->{'scheme'} || "mailto") . ":";
+    $str .= uri_escape($self->{'address'}) if defined $self->{'address'};
+    $str;
+}
+
+sub eq {
+    my($self, $other) = @_;
+    $other = URI::URL->new($other) unless ref $other;
+
+    # Mail adresses are case-insensitive
+    $self->scheme eq $other->scheme &&
+      lc($self->{'address'}) eq lc($other->{'address'});
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/news.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/news.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/news.pm	(revision 20131)
@@ -0,0 +1,73 @@
+package URI::URL::news;
+require URI::URL;
+@ISA = qw(URI::URL);
+
+use URI::Escape;
+
+sub new {
+    my($class, $init, $base) = @_;
+    my $self = bless { }, $class;
+    $self->{'scheme'}  = lc($1) if $init =~ s/^\s*([\w\+\.\-]+)://;
+    $self->groupart(uri_unescape($init));
+    $self->base($base) if $base;
+    $self;
+}
+
+sub groupart {
+    my $self = shift;
+    my $old = $self->{'path'};
+    if (@_) {
+	my $p = shift;
+	if (defined $p && $p =~ /\@/) {
+	    # it is an message id
+	    $p =~ s/^<(.*)>$/$1/;  # "<" and ">" should not be part of it
+	}
+	$self->{'path'} = $p;
+    }
+    $old;
+}
+
+*path = \&groupart;
+
+sub article   {
+    my $self = shift;
+    Carp::croak("Illegal article id name (does not contain '\@')")
+      if @_ && $_[0] !~ /\@/;
+    my $old = $self->groupart(@_);
+    return undef if $old !~ /\@/;
+    $old;
+}
+
+
+sub group {
+    my $self = shift;
+    Carp::croak("Illegal group name (contains '\@')")
+      if @_ && $_[0] =~ /\@/;
+    my $old = $self->groupart(@_);
+    return undef if $old =~ /\@/;
+    $old;
+}
+
+sub crack
+{
+    my $self = shift;
+    ('news',             # scheme
+     undef,              # user
+     undef,              # passwd
+     undef,              # host
+     undef,              # port
+     $self->{'path'},    # path
+     undef,              # params
+     undef,              # query
+     undef               # fragment
+    )
+}
+
+
+sub as_string {
+    my $self = shift;
+    my $scheme = $self->{'scheme'} || "news";
+    "$scheme:" . uri_escape($self->{'path'});
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/nntp.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/nntp.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/nntp.pm	(revision 20131)
@@ -0,0 +1,44 @@
+package URI::URL::nntp;
+require URI::URL::_generic;
+@ISA = qw(URI::URL::_generic);
+
+use URI::Escape;
+
+sub default_port { 119 }
+
+sub _parse {
+    my($self, $init) = @_;
+    $self->URI::URL::_generic::_parse($init, qw(netloc path frag));
+
+    my @parts = $self->path_components;
+    shift @parts if @parts && $parts[0] eq '';
+
+    $self->{'group'} = uri_unescape($parts[0]);
+    $self->{'digits'}= uri_unescape($parts[1]);
+}
+
+sub group   { shift->_elem('group',  @_); }
+sub digits  { shift->_elem('digits', @_); }
+sub article { shift->_elem('digits', @_); }
+
+sub as_string {
+    my $self = shift;
+    my $str = "$self->{'scheme'}:";
+    $str .= "//$self->{'netloc'}" if defined $self->{'netloc'};
+    $str .= "/" . uri_escape($self->{'group'}) . "/" .
+		  uri_escape($self->{'digits'});
+    $str;
+}
+
+# Standard methods are not legal for nntp URLs
+*path      = \&URI::URL::bad_method;
+*epath     = \&URI::URL::bad_method;
+*query     = \&URI::URL::bad_method;
+*equery    = \&URI::URL::bad_method;
+*params    = \&URI::URL::bad_method;
+*eparams   = \&URI::URL::bad_method;
+*frag      = \&URI::URL::bad_method;
+*user      = \&URI::URL::bad_method;
+*password  = \&URI::URL::bad_method;
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/prospero.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/prospero.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/prospero.pm	(revision 20131)
@@ -0,0 +1,27 @@
+package URI::URL::prospero;
+require URI::URL::_generic;
+@ISA = qw(URI::URL::_generic);
+
+# RFC 1738 says:
+#
+#   A prospero URLs takes the form:
+#
+#      prospero://<host>:<port>/<hsoname>;<field>=<value>
+#
+#   where <host> and <port> are as described in Section 3.1. If :<port>
+#   is omitted, the port defaults to 1525. No username or password is
+#   allowed.
+#
+#   The <hsoname> is the host-specific object name in the Prospero
+#   protocol, suitably encoded.  This name is opaque and interpreted by
+#   the Prospero server.  The semicolon ";" is reserved and may not
+#   appear without quoting in the <hsoname>.
+
+sub default_port { 1525 }       # says rfc1738, section 3.11
+
+sub _parse {
+    my($self, $init) = @_;
+    $self->URI::URL::_generic::_parse($init, qw(netloc path params frag));
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/rlogin.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/rlogin.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/rlogin.pm	(revision 20131)
@@ -0,0 +1,7 @@
+package URI::URL::rlogin;
+require URI::URL::_login;
+@ISA = qw(URI::URL::_login);
+
+sub default_port { 513 }
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/telnet.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/telnet.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/telnet.pm	(revision 20131)
@@ -0,0 +1,7 @@
+package URI::URL::telnet;
+require URI::URL::_login;
+@ISA = qw(URI::URL::_login);
+
+sub default_port { 23 }
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/tn3270.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/tn3270.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/tn3270.pm	(revision 20131)
@@ -0,0 +1,7 @@
+package URI::URL::tn3270;
+require URI::URL::_login;
+@ISA = qw(URI::URL::_login);
+
+# sub default_port { 0 }
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/wais.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/wais.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/wais.pm	(revision 20131)
@@ -0,0 +1,50 @@
+package URI::URL::wais;
+require URI::URL::_generic;
+@ISA = qw(URI::URL::_generic);
+
+use URI::Escape;
+
+# RFC 1738 says:
+#
+#   A WAIS URL takes one of the following forms:
+#
+#     wais://<host>:<port>/<database>
+#     wais://<host>:<port>/<database>?<search>
+#     wais://<host>:<port>/<database>/<wtype>/<wpath>
+#
+#   where <host> and <port> are as described in Section 3.1. If :<port>
+#   is omitted, the port defaults to 210.  The first form designates a
+#   WAIS database that is available for searching. The second form
+#   designates a particular search.  <database> is the name of the WAIS
+#   database being queried.
+
+
+sub default_port { 210 }
+
+sub _parse {
+    my($self, $init) = @_;
+    $self->URI::URL::_generic::_parse($init, qw(netloc path query frag));
+}
+
+# Set the path component with the specified number
+sub _path_comp
+{
+    my $self = shift;
+    my $no   = shift;
+    my @p = $self->path_components;
+    shift(@p) if @p && $p[0] eq '';
+    my $old = $p[$no];
+    if (@_) {
+	$p[$no] = $_[0];
+	$self->path_components(@p);
+    }
+    $old;
+}
+
+sub database { shift->_path_comp(0, @_); }
+sub wtype    { shift->_path_comp(1, @_); }
+sub wpath    { shift->_path_comp(2, @_); }
+
+*params   = \&URI::URL::bad_method;
+*eparams  = \&URI::URL::bad_method;
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/webster.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/webster.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/webster.pm	(revision 20131)
@@ -0,0 +1,6 @@
+package URI::URL::webster;
+require URI::URL::_generic;
+@ISA = qw(URI::URL::_generic);
+
+sub default_port { 765 }
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/whois.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/whois.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/URI/URL/whois.pm	(revision 20131)
@@ -0,0 +1,6 @@
+package URI::URL::whois;
+require URI::URL::_generic;
+@ISA = qw(URI::URL::_generic);
+
+sub default_port { 43 }
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/WWW/RobotRules.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/WWW/RobotRules.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/WWW/RobotRules.pm	(revision 20131)
@@ -0,0 +1,364 @@
+# $Id$
+
+package WWW::RobotRules;
+
+=head1 NAME
+
+WWW::RobotsRules - Parse robots.txt files
+
+=head1 SYNOPSIS
+
+ require WWW::RobotRules;
+ my $robotsrules = new WWW::RobotRules 'MOMspider/1.0';
+
+ use LWP::Simple qw(get);
+
+ $url = "http://some.place/robots.txt";
+ my $robots_txt = get $url;
+ $robotsrules->parse($url, $robots_txt);
+
+ $url = "http://some.other.place/robots.txt";
+ my $robots_txt = get $url;
+ $robotsrules->parse($url, $robots_txt);
+
+ # Now we are able to check if a URL is valid for those servers that
+ # we have obtained and parsed "robots.txt" files for.
+ if($robotsrules->allowed($url)) {
+     $c = get $url;
+     ...
+ }
+
+=head1 DESCRIPTION
+
+This module parses a F<robots.txt> file as specified in
+"A Standard for Robot Exclusion", described in
+<URL:http://info.webcrawler.com/mak/projects/robots/norobots.html>
+Webmasters can use the F<robots.txt> file to disallow conforming
+robots access to parts of their WWW server.
+
+The parsed file is kept in the WWW::RobotRules object, and this object
+provide methods to check if access to a given URL is prohibited.  The
+same WWW::RobotRules object can parse multiple F<robots.txt> files.
+
+The following methods are provided:
+
+=over 4
+
+=cut
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+sub Version { $VERSION; }
+
+
+use URI::URL ();
+use strict;
+
+
+=item $rules = new WWW::RobotRules 'MOMspider/1.0'
+
+This is the constructor for WWW::RobotRules objects.  The first 
+argument given to new() is the name of the robot. 
+
+=cut
+
+sub new {
+    my($class, $ua) = @_;
+
+    # This ugly hack is needed to ensure backwards compatability.
+    # The "WWW::RobotRules" class is now really abstract.
+    $class = "WWW::RobotRules::InCore" if $class eq "WWW::RobotRules";
+
+    my $self = bless { }, $class;
+    $self->agent($ua);
+    $self;
+}
+
+
+=item $rules->parse($url, $content, $fresh_until)
+
+The parse() method takes as arguments the URL that was used to
+retrieve the F</robots.txt> file, and the contents of the file.
+
+=cut
+
+sub parse {
+    my($self, $url, $txt, $fresh_until) = @_;
+
+    $url = new URI::URL $url unless ref($url);	# make it URL
+    my $netloc = $url->netloc;
+
+    $self->clear_rules($netloc);
+    $self->fresh_until($netloc, $fresh_until || (time + 365*24*3600));
+
+    my $ua;
+    my $is_me = 0;		# 1 iff this record is for me
+    my $is_anon = 0;		# 1 iff this record is for *
+    my @me_disallowed = ();	# rules disallowed for me
+    my @anon_disallowed = ();	# rules disallowed for *
+
+    # blank lines are significant, so turn CRLF into LF to avoid generating
+    # false ones
+    $txt =~ s/\015\012/\012/g;
+
+    # split at \012 (LF) or \015 (CR) (Mac text files have just CR for EOL)
+    for(split(/[\012\015]/, $txt)) {
+
+	# Lines containing only a comment are discarded completely, and
+        # therefore do not indicate a record boundary.
+	next if /^\s*\#/;
+
+	s/\s*\#.*//;        # remove comments at end-of-line
+
+	if (/^\s*$/) {	    # blank line
+	    last if $is_me; # That was our record. No need to read the rest.
+	    $is_anon = 0;
+	}
+        elsif (/^User-Agent:\s*(.*)/i) {
+	    $ua = $1;
+	    $ua =~ s/\s+$//;
+	    if ($is_me) {
+		# This record already had a User-agent that
+		# we matched, so just continue.
+	    }
+	    elsif ($ua eq '*') {
+		$is_anon = 1;
+	    }
+	    elsif($self->is_me($ua)) {
+		$is_me = 1;
+	    }
+	}
+	elsif (/^Disallow:\s*(.*)/i) {
+	    unless (defined $ua) {
+		warn "RobotRules: Disallow without preceding User-agent\n";
+		$is_anon = 1;  # assume that User-agent: * was intended
+	    }
+	    my $disallow = $1;
+	    $disallow =~ s/\s+$//;
+	    if (length $disallow) {
+		$disallow = URI::URL->new($disallow, $url)->full_path;
+	    }
+
+	    if ($is_me) {
+		push(@me_disallowed, $disallow);
+	    }
+	    elsif ($is_anon) {
+		push(@anon_disallowed, $disallow);
+	    }
+	}
+	else {
+	    warn "RobotRules: Unexpected line: $_\n";
+	}
+    }
+
+    if ($is_me) {
+	$self->push_rules($netloc, @me_disallowed);
+    } else {
+	$self->push_rules($netloc, @anon_disallowed);
+    }
+}
+
+# is_me()
+#
+# Returns TRUE if the given name matches the
+# name of this robot
+#
+sub is_me {
+    my($self, $ua) = @_;
+    my $me = $self->agent;
+    return index(lc($ua), lc($me)) >= 0;
+}
+
+=item $rules->allowed($url)
+
+Returns TRUE if this robot is allowed to retrieve this URL.
+
+=cut
+
+sub allowed {
+    my($self, $url) = @_;
+    $url = URI::URL->new($url) unless ref $url;	# make it URL
+
+    my $netloc = $url->netloc;
+
+    my $fresh_until = $self->fresh_until($netloc);
+    return -1 if !defined($fresh_until) || $fresh_until < time;
+
+    my $str = $url->full_path;
+    my $rule;
+    for $rule ($self->rules($netloc)) {
+	return 1 unless length $rule;
+	return 0 if index($str, $rule) == 0;
+    }
+    return 1;
+}
+
+# The following methods must be provided by the subclass.
+sub agent;
+sub visit;
+sub no_visits;
+sub last_visits;
+sub fresh_until;
+sub push_rules;
+sub clear_rules;
+sub rules;
+sub dump;
+
+package WWW::RobotRules::InCore;
+
+use vars qw(@ISA);
+@ISA = qw(WWW::RobotRules);
+
+=item $rules->agent([$name])
+
+Get/set the agent name. NOTE: Changing the agent name will clear the robots.txt
+rules and expire times out of the cache.
+
+=cut
+
+sub agent {
+    my ($self, $name) = @_;
+    my $old = $self->{'ua'};
+    if ($name) {
+	delete $self->{'loc'};   # all old info is now stale
+	$name =~ s!/?\s*\d+.\d+\s*$!!;  # loose version
+	$self->{'ua'}=$name;
+    }
+    $old;
+}
+
+sub visit {
+    my($self, $netloc, $time) = @_;
+    $time ||= time;
+    $self->{'loc'}{$netloc}{'last'} = $time;
+    
+    my $count = \$self->{'loc'}{$netloc}{'count'};
+    if (!defined $$count) {
+	$$count = 1;
+    } else {
+	$$count++;
+    }
+}
+
+sub no_visits {
+    my ($self, $netloc) = @_;
+    $self->{'loc'}{$netloc}{'count'};
+}
+
+sub last_visit {
+    my ($self, $netloc) = @_;
+    $self->{'loc'}{$netloc}{'last'};
+}
+
+sub fresh_until {
+    my ($self, $netloc, $fresh_until) = @_;
+    my $old = $self->{'loc'}{$netloc}{'fresh'};
+    if (defined $fresh_until) {
+	$self->{'loc'}{$netloc}{'fresh'} = $fresh_until;
+    }
+    $old;
+}
+
+sub push_rules {
+    my($self, $netloc, @rules) = @_;
+    push (@{$self->{'loc'}{$netloc}{'rules'}}, @rules);
+}
+
+sub clear_rules {
+    my($self, $netloc) = @_;
+    delete $self->{'loc'}{$netloc}{'rules'};
+}
+
+sub rules {
+    my($self, $netloc) = @_;
+    if (defined $self->{'loc'}{$netloc}{'rules'}) {
+	return @{$self->{'loc'}{$netloc}{'rules'}};
+    } else {
+	return ();
+    }
+}
+
+sub dump
+{
+    my $self = shift;
+    for (keys %$self) {
+	next if $_ eq 'loc';
+	print "$_ = $self->{$_}\n";
+    }
+    for (keys %{$self->{'loc'}}) {
+	my @rules = $self->rules($_);
+	print "$_: ", join("; ", @rules), "\n";
+	
+    }
+}
+
+1;
+
+__END__
+
+=back
+
+=head1 ROBOTS.TXT
+
+The format and semantics of the "/robots.txt" file are as follows
+(this is an edited abstract of
+<URL:http://info.webcrawler.com/mak/projects/robots/norobots.html>):
+
+The file consists of one or more records separated by one or more
+blank lines. Each record contains lines of the form
+
+  <field-name>: <value>
+
+The field name is case insensitive.  Text after the '#' character on a
+line is ignored during parsing.  This is used for comments.  The
+following <field-names> can be used:
+
+=over 3
+
+=item User-Agent
+
+The value of this field is the name of the robot the record is
+describing access policy for.  If more than one I<User-Agent> field is
+present the record describes an identical access policy for more than
+one robot. At least one field needs to be present per record.  If the
+value is '*', the record describes the default access policy for any
+robot that has not not matched any of the other records.
+
+=item Disallow
+
+The value of this field specifies a partial URL that is not to be
+visited. This can be a full path, or a partial path; any URL that
+starts with this value will not be retrieved
+
+=back
+
+=head1 ROBOTS.TXT EXAMPLES
+
+The following example "/robots.txt" file specifies that no robots
+should visit any URL starting with "/cyberworld/map/" or "/tmp/":
+
+  User-agent: *
+  Disallow: /cyberworld/map/ # This is an infinite virtual URL space
+  Disallow: /tmp/ # these will soon disappear
+
+This example "/robots.txt" file specifies that no robots should visit
+any URL starting with "/cyberworld/map/", except the robot called
+"cybermapper":
+
+  User-agent: *
+  Disallow: /cyberworld/map/ # This is an infinite virtual URL space
+
+  # Cybermapper knows where to go.
+  User-agent: cybermapper
+  Disallow:
+
+This example indicates that no robots should visit this site further:
+
+  # go away
+  User-agent: *
+  Disallow: /
+
+=head1 SEE ALSO
+
+L<LWP::RobotUA>, L<WWW::RobotRules::AnyDBM_File>
+
+=cut
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/WWW/RobotRules/AnyDBM_File.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/WWW/RobotRules/AnyDBM_File.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lib/WWW/RobotRules/AnyDBM_File.pm	(revision 20131)
@@ -0,0 +1,170 @@
+# $Id$
+
+package WWW::RobotRules::AnyDBM_File;
+
+require  WWW::RobotRules;
+@ISA = qw(WWW::RobotRules);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+use Carp ();
+use AnyDBM_File;
+use Fcntl;
+use strict;
+
+=head1 NAME
+
+WWW::RobotRules::AnyDBM_File - Persistent RobotRules
+
+=head1 SYNOPSIS
+
+ require WWW::RobotRules::AnyDBM_File;
+ require LWP::RobotUA;
+
+ # Create a robot useragent that uses a diskcaching RobotRules
+ my $rules = new WWW::RobotRules::AnyDBM_File 'my-robot/1.0', 'cachefile';
+ my $ua = new WWW::RobotUA 'my-robot/1.0', 'me@foo.com', $rules;
+
+ # Then just use $ua as usual
+ $res = $ua->request($req);
+
+=head1 DESCRIPTION
+
+This is a subclass of I<WWW::RobotRules> that uses the AnyDBM_File
+package to implement persistent diskcaching of F<robots.txt> and host
+visit information.
+
+The constructor (the new() method) takes an extra argument specifying
+the name of the DBM file to use.  If the DBM file already exists, then
+you can specify undef as agent name as the name can be obtained from
+the DBM database.
+
+=cut
+
+sub new 
+{ 
+  my ($class, $ua, $file) = @_;
+  Carp::croak('WWW::RobotRules::AnyDBM_File filename required') unless $file;
+
+  my $self = bless { }, $class;
+  $self->{'filename'} = $file;
+  tie %{$self->{'dbm'}}, 'AnyDBM_File', $file, O_CREAT|O_RDWR, 0640
+    or Carp::croak("Can't open $file: $!");
+  
+  if ($ua) {
+      $self->agent($ua);
+  } else {
+      # Try to obtain name from DBM file
+      $ua = $self->{'dbm'}{"|ua-name|"};
+      Carp::croak("No agent name specified") unless $ua;
+  }
+
+  $self;
+}
+
+sub agent {
+    my($self, $newname) = @_;
+    my $old = $self->{'dbm'}{"|ua-name|"};
+    if (defined $newname) {
+	$newname =~ s!/?\s*\d+.\d+\s*$!!;  # loose version
+	unless ($old && $old eq $newname) {
+	# Old info is now stale.
+	    my $file = $self->{'filename'};
+	    untie %{$self->{'dbm'}};
+	    tie %{$self->{'dbm'}}, 'AnyDBM_File', $file, O_TRUNC|O_RDWR, 0640;
+	    $self->{'dbm'}{"|ua-name|"} = $newname;
+	}
+    }
+    $old;
+}
+
+sub no_visits {
+    my ($self, $netloc) = @_;
+    my $t = $self->{'dbm'}{"$netloc|vis"};
+    return 0 unless $t;
+    (split(/;\s*/, $t))[0];
+}
+
+sub last_visit {
+    my ($self, $netloc) = @_;
+    my $t = $self->{'dbm'}{"$netloc|vis"};
+    return undef unless $t;
+    (split(/;\s*/, $t))[1];
+}
+
+sub fresh_until {
+    my ($self, $netloc, $fresh) = @_;
+    my $old = $self->{'dbm'}{"$netloc|exp"};
+    if ($old) {
+	$old =~ s/;.*//;  # remove cleartext
+    }
+    if (defined $fresh) {
+	$fresh .= "; " . localtime($fresh);
+	$self->{'dbm'}{"$netloc|exp"} = $fresh;
+    }
+    $old;
+}
+
+sub visit {
+    my($self, $netloc, $time) = @_;
+    $time ||= time;
+
+    my $count = 0;
+    my $old = $self->{'dbm'}{"$netloc|vis"};
+    if ($old) {
+	my $last;
+	($count,$last) = split(/;\s*/, $old);
+	$time = $last if $last > $time;
+    }
+    $count++;
+    $self->{'dbm'}{"$netloc|vis"} = "$count; $time; " . localtime($time);
+}
+
+sub push_rules {
+    my($self, $netloc, @rules) = @_;
+    my $cnt = 1;
+    $cnt++ while $self->{'dbm'}{"$netloc|r$cnt"};
+
+    foreach (@rules) {
+	$self->{'dbm'}{"$netloc|r$cnt"} = $_;
+	$cnt++;
+    }
+}
+
+sub clear_rules {
+    my($self, $netloc) = @_;
+    my $cnt = 1;
+    while ($self->{'dbm'}{"$netloc|r$cnt"}) {
+	delete $self->{'dbm'}{"$netloc|r$cnt"};
+	$cnt++;
+    }
+}
+
+sub rules {
+    my($self, $netloc) = @_;
+    my @rules = ();
+    my $cnt = 1;
+    while (1) {
+	my $rule = $self->{'dbm'}{"$netloc|r$cnt"};
+	last unless $rule;
+	push(@rules, $rule);
+	$cnt++;
+    }
+    @rules;
+}
+
+sub dump
+{
+}
+
+1;
+
+=head1 SEE ALSO
+
+L<WWW::RobotRules>, L<LWP::RobotUA>
+
+=head1 AUTHORS
+
+Hakan Ardo E<lt>hakan@munin.ub2.lu.se>, Gisle Aas E<lt>aas@sn.no>
+
+=cut
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lwpcook.pod
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lwpcook.pod	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/lwpcook.pod	(revision 20131)
@@ -0,0 +1,343 @@
+=head1 NAME
+
+lwpcook - libwww-perl cookbook
+
+=head1 DESCRIPTION
+
+This document contain some examples that show typical usage of the
+libwww-perl library.  You should consult the documentation for the
+individual modules for more detail.
+
+All examples should be runnable programs. You can, in most cases, test
+the code sections by piping the program text directly to perl.
+
+
+
+=head1 GET
+
+It is very easy to use this library to just fetch documents from the
+net.  The LWP::Simple module provides the get() function that return
+the document specified by its URL argument:
+
+  use LWP::Simple;
+  $doc = get 'http://www.sn.no/libwww-perl/';
+
+or, as a perl one-liner using the getprint() function:
+
+  perl -MLWP::Simple -e 'getprint "http://www.sn.no/libwww-perl/"'
+
+or, how about fetching the latest perl by running this command:
+
+  perl -MLWP::Simple -e '
+    getstore "ftp://ftp.sunet.se/pub/lang/perl/CPAN/src/latest.tar.gz",
+             "perl.tar.gz"'
+
+You will probably first want to find a CPAN site closer to you by
+running something like the following command:
+
+  perl -MLWP::Simple -e 'getprint "http://www.perl.com/perl/CPAN/CPAN.html"'
+
+Enough of this simple stuff!  The LWP object oriented interface gives
+you more control over the request sent to the server.  Using this
+interface you have full control over headers sent and how you want to
+handle the response returned.
+
+  use LWP::UserAgent;
+  $ua = new LWP::UserAgent;
+  $ua->agent("$0/0.1 " . $ua->agent);
+  # $ua->agent("Mozilla/8.0") # pretend we are very capable browser
+
+  $req = new HTTP::Request 'GET' => 'http://www.sn.no/libwww-perl';
+  $req->header('Accept' => 'text/html');
+
+  # send request
+  $res = $ua->request($req);
+
+  # check the outcome
+  if ($res->is_success) {
+     print $res->content;
+  } else {
+     print "Error: " . $res->status_line . "\n";
+  }
+
+The lwp-request program (alias GET) that is distributed with the
+library can also be used to fetch documents from WWW servers.
+  
+
+
+=head1 HEAD
+
+If you just want to check if a document is present (i.e. the URL is
+valid) try to run code that looks like this:
+
+  use LWP::Simple;
+
+  if (head($url)) {
+     # ok document exists
+  }
+
+The head() function really returns a list of meta-information about
+the document.  The first three values of the list returned are the
+document type, the size of the document, and the age of the document.
+
+More control over the request or access to all header values returned
+require that you use the object oriented interface described for GET
+above.  Just s/GET/HEAD/g.
+
+
+=head1 POST
+
+There is no simple procedural interface for posting data to a WWW server.  You
+must use the object oriented interface for this. The most common POST
+operation is to access a WWW form application:
+
+  use LWP::UserAgent;
+  $ua = new LWP::UserAgent;
+
+  my $req = new HTTP::Request 'POST','http://www.perl.com/cgi-bin/BugGlimpse';
+  $req->content_type('application/x-www-form-urlencoded');
+  $req->content('match=www&errors=0');
+
+  my $res = $ua->request($req);
+  print $res->as_string;
+
+Lazy people use the HTTP::Request::Common module to set up a suitable
+POST request message (it handles all the escaping issues) and has a
+suitable default for the content_type:
+
+  use HTTP::Request::Common qw(POST);
+  use LWP::UserAgent;
+  $ua = new LWP::UserAgent;
+
+  my $req = POST 'http://www.perl.com/cgi-bin/BugGlimpse',
+                [ search => 'www', errors => 0 ];
+
+  print $ua->request($req)->as_string;
+
+The lwp-request program (alias POST) that is distributed with the
+library can also be used for posting data.
+
+
+
+=head1 PROXIES
+
+Some sites use proxies to go through fire wall machines, or just as
+cache in order to improve performance.  Proxies can also be used for
+accessing resources through protocols not supported directly (or
+supported badly :-) by the libwww-perl library.
+
+You should initialize your proxy setting before you start sending
+requests:
+
+  use LWP::UserAgent;
+  $ua = new LWP::UserAgent;
+  $ua->env_proxy; # initialize from environment variables
+  # or
+  $ua->proxy(ftp  => 'http://proxy.myorg.com');
+  $ua->proxy(wais => 'http://proxy.myorg.com');
+  $ua->no_proxy(qw(no se fi));
+
+  my $req = new HTTP::Request 'wais://xxx.com/';
+  print $ua->request($req)->as_string;
+
+The LWP::Simple interface will call env_proxy() for you automatically.
+Applications that use the $ua->env_proxy() method will normally not
+use the $ua->proxy() and $ua->no_proxy() methods.
+
+Some proxies also require that you send it a username/password in
+order to let requests through.  You should be able to add the
+required header, with something like this:
+
+ use LWP::UserAgent;
+
+ $ua = new LWP::UserAgent;
+ $ua->proxy(['http', 'ftp'] => 'http://proxy.myorg.com');
+
+ $req = new HTTP::Request 'GET',"http://www.perl.com";
+ $req->proxy_authorization_basic("proxy_user", "proxy_password");
+
+ $res = $ua->request($req);
+ print $res->content if $res->is_success;
+
+Replace C<proxy.myorg.com>, C<proxy_user> and
+C<proxy_password> with something suitable for your site.
+
+
+=head1 ACCESS TO PROTECTED DOCUMENTS
+
+Documents protected by basic authorization can easily be accessed
+like this:
+
+  use LWP::UserAgent;
+  $ua = new LWP::UserAgent;
+  $req = new HTTP::Request GET => 'http://www.sn.no/secret/';
+  $req->authorization_basic('aas', 'mypassword');
+  print $ua->request($req)->as_string;
+
+The other alternative is to provide a subclass of I<LWP::UserAgent> that
+overrides the get_basic_credentials() method. Study the I<lwp-request>
+program for an example of this.
+
+
+=head1 MIRRORING
+
+If you want to mirror documents from a WWW server, then try to run
+code similar to this at regular intervals:
+
+  use LWP::Simple;
+
+  %mirrors = (
+     'http://www.sn.no/'             => 'sn.html',
+     'http://www.perl.com/'          => 'perl.html',
+     'http://www.sn.no/libwww-perl/' => 'lwp.html',
+     'gopher://gopher.sn.no/'        => 'gopher.html',
+  );
+
+  while (($url, $localfile) = each(%mirrors)) {
+     mirror($url, $localfile);
+  }
+
+Or, as a perl one-liner:
+
+  perl -MLWP::Simple -e 'mirror("http://www.perl.com/", "perl.html")';
+
+The document will not be transfered unless it has been updated.
+
+
+
+=head1 LARGE DOCUMENTS
+
+If the document you want to fetch is too large to be kept in memory,
+then you have two alternatives.  You can instruct the library to write
+the document content to a file (second $ua->request() argument is a file
+name):
+
+  use LWP::UserAgent;
+  $ua = new LWP::UserAgent;
+
+  my $req = new HTTP::Request 'GET',
+                'http://www.sn.no/~aas/perl/www/libwww-perl-5.00.tar.gz';
+  $res = $ua->request($req, "libwww-perl.tar.gz");
+  if ($res->is_success) {
+     print "ok\n";
+  }
+
+Or you can process the document as it arrives (second $ua->request()
+argument is a code reference):
+
+  use LWP::UserAgent;
+  $ua = new LWP::UserAgent;
+  $URL = 'ftp://ftp.unit.no/pub/rfc/rfc-index.txt';
+
+  my $expected_length;
+  my $bytes_received = 0;
+  $ua->request(HTTP::Request->new('GET', $URL),
+               sub {
+                   my($chunk, $res) = @_;
+                   $bytes_received += length($chunk);
+	           unless (defined $expected_length) {
+	              $expected_length = $res->content_length || 0;
+                   }
+		   if ($expected_length) {
+		        printf STDERR "%d%% - ",
+	                          100 * $bytes_received / $expected_length;
+                   }
+	           print STDERR "$bytes_received bytes received\n";
+
+                   # XXX Should really do something with the chunk itself
+	           # print $chunk;
+               });
+
+
+
+=head1 HTML FORMATTING
+
+It is easy to convert HTML code to "readable" text.
+
+  use LWP::Simple;
+  use HTML::Parse;
+  print parse_html(get 'http://www.sn.no/libwww-perl/')->format;
+
+
+
+=head1 PARSE URLS
+
+To access individual elements of a URL, try this:
+
+  use URI::URL;
+  $host = url("http://www.sn.no/")->host;
+
+or
+
+  use URI::URL;
+  $u = url("ftp://ftp.sn.no/test/aas;type=i");
+  print "Protocol scheme is ", $u->scheme, "\n";
+  print "Host is ", $u->host, " at port ", $u->port, "\n";
+
+or even
+
+  use URI::URL;
+  my($host,$port) = (url("ftp://ftp.sn.no/test/aas;type=i")->crack)[3,4];
+
+
+=head1 EXPAND RELATIVE URLS
+
+This code reads URLs and print expanded version.
+
+  use URI::URL;
+  $BASE = "http://www.sn.no/some/place?query";
+  while (<>) {
+     print url($_, $BASE)->abs->as_string, "\n";
+  }
+
+We can expand URLs in an HTML document by using the parser to build a
+tree that we then traverse:
+
+  %link_elements =
+  (
+   'a'    => 'href',
+   'img'  => 'src',
+   'form' => 'action',
+   'link' => 'href',
+  );
+
+  use HTML::Parse;
+  use URI::URL;
+
+  $BASE = "http://somewhere/root/";
+  $h = parse_htmlfile("xxx.html");
+  $h->traverse(\&expand_urls, 1);
+
+  print $h->as_HTML;
+
+  sub expand_urls
+  {
+     my($e, $start) = @_;
+     return 1 unless $start;
+     my $attr = $link_elements{$e->tag};
+     return 1 unless defined $attr;
+     my $url = $e->attr($attr);
+     return 1 unless defined $url;
+     $e->attr($attr, url($url, $BASE)->abs->as_string);
+  }
+
+
+
+=head1 BASE URL
+
+If you want to resolve relative links in a page you will have to
+determine which base URL to use.  The HTTP::Response objects now has a
+base() method.
+
+  $BASE = $res->base;
+
+
+
+=head1 COPYRIGHT
+
+Copyright 1996-1997, Gisle Aas
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/README
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/README	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/README	(revision 20131)
@@ -0,0 +1,24 @@
+Self test suite for the libwww-perl library
+-------------------------------------------
+
+Tests are invoked by running the ./TEST script, but usually you run
+the tests with "make test" at the top libwww-perl directory.  Use -v
+option for verbose tests.  You might run an individual test like this:
+
+  ./TEST -v base/date
+
+or all tests in a directory like this
+
+  ./TEST base
+
+You enable network tests by creating the "net/config.pl" file.  A good
+start is to make a copy of the "net/config.pl.dist" file.  For network
+tests you should also make a link from the cgi-bin directory of your
+http server to the "net/cgi-bin" directory.  You might also have to
+check that the interpreter line (#!.../perl) in the scripts is ok for
+your system.  The following setup works for my site:
+
+  ln -s `pwd`/net/cgi-bin ~www/cgi-bin/lwp
+  cp net/config.pl.dist net/config.pl
+  emacs net/config.pl                        # fix if necessary
+  ./TEST net
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/TEST
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/TEST	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/TEST	(revision 20131)
@@ -0,0 +1,39 @@
+#!/usr/local/bin/perl
+
+# This script is run Test::Harness on the tests found under the
+# "t" directory.
+
+# First we check if we already are within the "t" directory
+unless (-d "base") {
+    # try to move into test directory
+    chdir "t" or die "Can't chdir: $!";
+
+    # fix all relative library locations
+    foreach (@INC) {
+	$_ = "../$_" unless m,^/,;
+    }
+}
+# Pick up the library files from the ../blib directory
+unshift(@INC, "../blib/lib", "../blib/arch");
+#print "@INC\n";
+
+
+use Test::Harness;
+$Test::Harness::verbose = shift
+  if $ARGV[0] =~ /^\d+$/ || $ARGV[0] eq "-v";
+
+if (@ARGV) {
+    for (@ARGV) {
+	if (-d $_) {
+	    push(@tests, <$_/*.t>);
+	} else {
+            $_ .= ".t" unless /\.t$/;
+	    push(@tests, $_);
+	}
+    }
+} else {
+    @tests = (<base/*.t>, <uri/*.t>, <robot/*.t>, <local/*.t>);
+    push(@tests, <net/*.t>) if -f "net/config.pl";
+}
+
+runtests @tests;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/common-req.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/common-req.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/common-req.t	(revision 20131)
@@ -0,0 +1,193 @@
+print "1..19\n";
+
+use HTTP::Request::Common;
+
+$r = GET 'http://www.sn.no/';
+print $r->as_string;
+
+print "not " unless $r->method eq "GET" and $r->url eq "http://www.sn.no/";
+print "ok 1\n";
+
+$r = HEAD "http://www.sn.no/",
+     If_Match => 'abc',
+     From => 'aas@sn.no';
+print $r->as_string;
+
+print "not " unless $r->method eq "HEAD" and $r->url->eq("http://www.sn.no");
+print "ok 2\n";
+
+print "not " unless $r->header('If-Match') eq "abc" and $r->header("from") eq "aas\@sn.no";
+print "ok 3\n";
+
+$r = PUT "http://www.sn.no",
+     Content => 'foo';
+print $r->as_string;
+
+print "not " unless $r->method eq "PUT" and $r->url->netloc eq "www.sn.no";
+print "ok 4\n";
+
+print "not " if defined($r->header("Content"));
+print "ok 5\n";
+
+print "not " unless ${$r->content_ref} eq "foo" and
+                    $r->content eq "foo";
+print "ok 6\n";
+
+#--- Test POST requests ---
+
+$r = POST "http://www.sn.no", [foo => 'bar',
+                               baz => [qw(a b c)],
+                               foo => 'zoo=&',
+                               "space " => " + ",
+                              ],
+                              bar => 'foo';
+print $r->as_string;
+
+print "not " unless $r->method eq "POST" and
+                    $r->content_type eq "application/x-www-form-urlencoded" and
+                    $r->content_length == 58 and
+                    $r->header("bar") eq "foo";
+print "ok 7\n";
+
+print "not " unless $r->content eq "foo=bar&baz=a&baz=b&baz=c&foo=zoo%3D%26&space%20=%20%2B%20";
+print "ok 8\n";
+
+$r = POST "mailto:gisle\@aas.no",
+     Subject => "Heisan",
+     Content_Type => "text/plain",
+     Content => "Howdy\n";
+print $r->as_string;
+
+print "not " unless $r->method eq "POST" and
+                    $r->header("Subject") eq "Heisan" and
+                    $r->content eq "Howdy\n" and
+	            $r->content_type eq "text/plain";
+print "ok 9\n";
+
+#
+# POST for File upload
+#
+$file = "test-$$";
+open(FILE, ">$file") or die "Can't create $file: $!";
+print FILE "foo\nbar\nbaz\n";
+close(FILE);
+
+$r = POST 'http://www.perl.org/survey.cgi',
+       Content_Type => 'form-data',
+       Content      => [ name  => 'Gisle Aas',
+                         email => 'gisle@aas.no',
+                         gender => 'm',
+                         born   => '1964',
+                         file   => [$file],
+                       ];
+print $r->as_string;
+
+unlink($file) or warn "Can't unlink $file: $!";
+
+print "not " unless $r->method eq "POST" and
+	            $r->url->path eq "/survey.cgi" and
+                    $r->content_type eq "multipart/form-data" and
+	            $r->header(Content_type) =~ /boundary="?([^"]+)"?/;
+print "ok 10\n";
+$boundary = $1;
+
+$c = $r->content;
+$c =~ s/\r//g;
+@c = split(/--\Q$boundary/, $c);
+print "$c[5]\n";
+
+print "not " unless @c == 7 and $c[6] =~ /^--\n/;  # 5 parts + header & trailer
+print "ok 11\n";
+
+print "not " unless $c[2] =~ /^Content-Disposition:\s*form-data;\s*name="email"/m and
+                    $c[2] =~ /^gisle\@aas.no$/m;
+print "ok 12\n";
+
+print "not " unless $c[5] =~ /^Content-Disposition:\s*form-data;\s*name="file";\s*filename="$file"/m and
+	            $c[5] =~ /^Content-Type:\s*text\/plain$/m and
+	            $c[5] =~ /^foo\nbar\nbaz/m;
+print "ok 13\n";
+
+$r = POST 'http://www.perl.org/survey.cgi',
+      [ file => [ undef, "xxx", Content_type => "text/html", Content => "<h1>Hello, world!</h1>" ]],
+      Content_type => 'multipart/form-data';
+print $r->as_string;
+
+print "not " unless $r->content =~ /^--\S+\015\012Content-Disposition:\s*form-data;\s*name="file";\s*filename="xxx"/m and
+	            $r->content =~ /^Content-Type: text\/html/m and
+	            $r->content =~ /^<h1>Hello, world/m;
+print "ok 14\n";
+
+
+$r = POST 'http://www.perl.org/survey.cgi',
+      Content_type => 'multipart/form-data',
+      Content => [ file => [ undef, undef, Content => "foo"]];
+print $r->as_string;
+
+print "not " if $r->content =~ /filename=/;
+print "ok 15\n";
+
+
+# The POST routine can now also take a hash reference.
+my %hash = (foo => 42, bar => 24);
+$r = POST 'http://www.perl.org/survey.cgi', \%hash;
+print $r->as_string;
+print "not " unless $r->content =~ /foo=42/ &&
+                    $r->content =~ /bar=24/ &&
+                    $r->content_type eq "application/x-www-form-urlencoded" &&
+                    $r->content_length == 13;
+print "ok 16\n";
+
+ 
+#
+# POST for File upload
+#
+use HTTP::Request::Common qw($DYNAMIC_FILE_UPLOAD);
+
+$file = "test-$$";
+open(FILE, ">$file") or die "Can't create $file: $!";
+for (1..1000) {
+   print FILE "a" .. "z";
+}
+close(FILE);
+
+$DYNAMIC_FILE_UPLOAD++;
+$r = POST 'http://www.perl.org/survey.cgi',
+       Content_Type => 'form-data',
+       Content      => [ name  => 'Gisle Aas',
+                         email => 'gisle@aas.no',
+                         gender => 'm',
+                         born   => '1964',
+                         file   => [$file],
+                       ];
+print $r->as_string;
+
+print "not " unless $r->method eq "POST" and
+	            $r->url->path eq "/survey.cgi" and
+                    $r->content_type eq "multipart/form-data" and
+	            $r->header(Content_type) =~ /boundary="?([^"]+)"?/ and
+		    ref($r->content) eq "CODE";
+print "ok 17\n";
+$boundary = $1;
+
+print "not " unless length($boundary) > 10;
+print "ok 18\n";
+
+$code = $r->content;
+my $chunk;
+my @chunks;
+while (defined($chunk = &$code) && length $chunk) {
+   push(@chunks, $chunk);
+}
+
+unlink($file) or warn "Can't unlink $file: $!";
+
+$_ = join("", @chunks);
+
+print int(@chunks), " chunks, total size is ", length($_), " bytes\n";
+
+# should be close to expected size and number of chunks
+print "not " unless abs(@chunks - 15 < 3) and
+                    abs(length($_) - 26589) < 20;
+print "ok 19\n";
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/cookies.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/cookies.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/cookies.t	(revision 20131)
@@ -0,0 +1,515 @@
+print "1..32\n";
+
+#use LWP::Debug '+';
+
+use HTTP::Cookies;
+use HTTP::Request;
+use HTTP::Response;
+
+#-------------------------------------------------------------------
+# First we check that it works for the original example at
+# http://www.netscape.com/newsref/std/cookie_spec.html
+
+# Client requests a document, and receives in the response:
+# 
+#       Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT
+# 
+# When client requests a URL in path "/" on this server, it sends:
+# 
+#       Cookie: CUSTOMER=WILE_E_COYOTE
+# 
+# Client requests a document, and receives in the response:
+# 
+#       Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
+# 
+# When client requests a URL in path "/" on this server, it sends:
+# 
+#       Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
+# 
+# Client receives:
+# 
+#       Set-Cookie: SHIPPING=FEDEX; path=/fo
+# 
+# When client requests a URL in path "/" on this server, it sends:
+# 
+#       Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001
+# 
+# When client requests a URL in path "/foo" on this server, it sends:
+# 
+#       Cookie: CUSTOMER=WILE_E_COYOTE; PART_NUMBER=ROCKET_LAUNCHER_0001; SHIPPING=FEDEX
+# 
+# The last Cookie is buggy, because both specifications says that the
+# most specific cookie must be sent first.  SHIPPING=FEDEX is the
+# most specific and should thus be first.
+
+$c = HTTP::Cookies->new;
+
+$req = HTTP::Request->new(GET => "http://www.acme.com/");
+
+$res = HTTP::Response->new(200, "OK");
+$res->request($req);
+$res->header("Set-Cookie" => "CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT");
+$c->extract_cookies($res);
+
+$req = HTTP::Request->new(GET => "http://www.acme.com/");
+$c->add_cookie_header($req);
+
+print "not " unless $req->header("Cookie") eq "CUSTOMER=WILE_E_COYOTE" &&
+                    $req->header("Cookie2") eq "\$Version=1";
+print "ok 1\n";
+
+$res->request($req);
+$res->header("Set-Cookie" => "PART_NUMBER=ROCKET_LAUNCHER_0001; path=/");
+$c->extract_cookies($res);
+
+$req = HTTP::Request->new(GET => "http://www.acme.com/foo/bar");
+$c->add_cookie_header($req);
+
+$h = $req->header("Cookie");
+print "not " unless $h =~ /PART_NUMBER=ROCKET_LAUNCHER_0001/ &&
+                    $h =~ /CUSTOMER=WILE_E_COYOTE/;
+print "ok 2\n";
+
+$res->request($req);
+$res->header("Set-Cookie", "SHIPPING=FEDEX; path=/foo");
+$c->extract_cookies($res);
+
+$req = HTTP::Request->new(GET => "http://www.acme.com/");
+$c->add_cookie_header($req);
+
+$h = $req->header("Cookie");
+print "not " unless $h =~ /PART_NUMBER=ROCKET_LAUNCHER_0001/ &&
+	            $h =~ /CUSTOMER=WILE_E_COYOTE/ &&
+	            $h !~ /SHIPPING=FEDEX/;
+print "ok 3\n";
+
+
+$req = HTTP::Request->new(GET => "http://www.acme.com/foo/");
+$c->add_cookie_header($req);
+
+$h = $req->header("Cookie");
+print "not " unless $h =~ /PART_NUMBER=ROCKET_LAUNCHER_0001/ &&
+	            $h =~ /CUSTOMER=WILE_E_COYOTE/ &&
+		    $h =~ /^SHIPPING=FEDEX;/;
+print "ok 4\n";
+
+print $c->as_string;
+
+
+# Second Example transaction sequence:
+# 
+# Assume all mappings from above have been cleared.
+# 
+# Client receives:
+# 
+#       Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/
+# 
+# When client requests a URL in path "/" on this server, it sends:
+# 
+#       Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001
+# 
+# Client receives:
+# 
+#       Set-Cookie: PART_NUMBER=RIDING_ROCKET_0023; path=/ammo
+# 
+# When client requests a URL in path "/ammo" on this server, it sends:
+# 
+#       Cookie: PART_NUMBER=RIDING_ROCKET_0023; PART_NUMBER=ROCKET_LAUNCHER_0001
+# 
+#       NOTE: There are two name/value pairs named "PART_NUMBER" due to
+#       the inheritance of the "/" mapping in addition to the "/ammo" mapping. 
+
+$c = HTTP::Cookies->new;  # clear it
+
+$req = HTTP::Request->new(GET => "http://www.acme.com/");
+$res = HTTP::Response->new(200, "OK");
+$res->request($req);
+$res->header("Set-Cookie", "PART_NUMBER=ROCKET_LAUNCHER_0001; path=/");
+
+$c->extract_cookies($res);
+
+$req = HTTP::Request->new(GET => "http://www.acme.com/");
+$c->add_cookie_header($req);
+
+print "not " unless $req->header("Cookie") eq "PART_NUMBER=ROCKET_LAUNCHER_0001";
+print "ok 5\n";
+
+$res->request($req);
+$res->header("Set-Cookie", "PART_NUMBER=RIDING_ROCKET_0023; path=/ammo");
+$c->extract_cookies($res);
+
+$req = HTTP::Request->new(GET => "http://www.acme.com/ammo");
+$c->add_cookie_header($req);
+
+print "not " unless $req->header("Cookie") =~
+       /^PART_NUMBER=RIDING_ROCKET_0023;\s*PART_NUMBER=ROCKET_LAUNCHER_0001/;
+print "ok 6\n";
+
+print $c->as_string;
+undef($c);
+
+
+#-------------------------------------------------------------------
+# When there are no "Set-Cookie" header, then even responses
+# without any request URLs connected should be allowed.
+
+$c = HTTP::Cookies->new;
+$c->extract_cookies(HTTP::Response->new("200", "OK"));
+print "not " if count_cookies($c) != 0;
+print "ok 7\n";
+
+
+#-------------------------------------------------------------------
+# Then we test with the examples from draft-ietf-http-state-man-mec-03.txt
+#
+# 5.  EXAMPLES
+
+$c = HTTP::Cookies->new;
+
+# 
+# 5.1  Example 1
+# 
+# Most detail of request and response headers has been omitted.  Assume
+# the user agent has no stored cookies.
+# 
+#   1.  User Agent -> Server
+# 
+#       POST /acme/login HTTP/1.1
+#       [form data]
+# 
+#       User identifies self via a form.
+# 
+#   2.  Server -> User Agent
+# 
+#       HTTP/1.1 200 OK
+#       Set-Cookie2: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
+# 
+#       Cookie reflects user's identity.
+
+$cookie = interact($c, 'http://www.acme.com/acme/login',
+                       'Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"');
+print "not " if $cookie;
+print "ok 8\n";
+
+# 
+#   3.  User Agent -> Server
+# 
+#       POST /acme/pickitem HTTP/1.1
+#       Cookie: $Version="1"; Customer="WILE_E_COYOTE"; $Path="/acme"
+#       [form data]
+# 
+#       User selects an item for ``shopping basket.''
+# 
+#   4.  Server -> User Agent
+# 
+#       HTTP/1.1 200 OK
+#       Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
+#               Path="/acme"
+# 
+#       Shopping basket contains an item.
+
+$cookie = interact($c, 'http://www.acme.com/acme/pickitem',
+		       'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"');
+print "not " unless $cookie =~ m(^\$Version="?1"?; Customer="?WILE_E_COYOTE"?; \$Path="/acme"$);
+print "ok 9\n";
+
+# 
+#   5.  User Agent -> Server
+# 
+#       POST /acme/shipping HTTP/1.1
+#       Cookie: $Version="1";
+#               Customer="WILE_E_COYOTE"; $Path="/acme";
+#               Part_Number="Rocket_Launcher_0001"; $Path="/acme"
+#       [form data]
+# 
+#       User selects shipping method from form.
+# 
+#   6.  Server -> User Agent
+# 
+#       HTTP/1.1 200 OK
+#       Set-Cookie2: Shipping="FedEx"; Version="1"; Path="/acme"
+# 
+#       New cookie reflects shipping method.
+
+$cookie = interact($c, "http://www.acme.com/acme/shipping",
+		   'Shipping="FedEx"; Version="1"; Path="/acme"');
+
+print "not " unless $cookie =~ /^\$Version="?1"?;/ &&
+     $cookie =~ /Part_Number="?Rocket_Launcher_0001"?;\s*\$Path="\/acme"/ &&
+     $cookie =~ /Customer="?WILE_E_COYOTE"?;\s*\$Path="\/acme"/;
+print "ok 10\n";
+
+# 
+#   7.  User Agent -> Server
+# 
+#       POST /acme/process HTTP/1.1
+#       Cookie: $Version="1";
+#               Customer="WILE_E_COYOTE"; $Path="/acme";
+#               Part_Number="Rocket_Launcher_0001"; $Path="/acme";
+#               Shipping="FedEx"; $Path="/acme"
+#       [form data]
+# 
+#       User chooses to process order.
+# 
+#   8.  Server -> User Agent
+# 
+#       HTTP/1.1 200 OK
+# 
+#       Transaction is complete.
+
+$cookie = interact($c, "http://www.acme.com/acme/process");
+print "FINAL COOKIE: $cookie\n";
+print "not " unless $cookie =~ /Shipping="?FedEx"?;\s*\$Path="\/acme"/ &&
+                    $cookie =~ /WILE_E_COYOTE/;
+print "ok 11\n";
+
+# 
+# The user agent makes a series of requests on the origin server, after
+# each of which it receives a new cookie.  All the cookies have the same
+# Path attribute and (default) domain.  Because the request URLs all have
+# /acme as a prefix, and that matches the Path attribute, each request
+# contains all the cookies received so far.
+
+print $c->as_string;
+
+
+# 5.2  Example 2
+# 
+# This example illustrates the effect of the Path attribute.  All detail
+# of request and response headers has been omitted.  Assume the user agent
+# has no stored cookies.
+
+$c = HTTP::Cookies->new;
+
+# Imagine the user agent has received, in response to earlier requests,
+# the response headers
+# 
+# Set-Cookie2: Part_Number="Rocket_Launcher_0001"; Version="1";
+#         Path="/acme"
+# 
+# and
+# 
+# Set-Cookie2: Part_Number="Riding_Rocket_0023"; Version="1";
+#         Path="/acme/ammo"
+
+interact($c, "http://www.acme.com/acme/ammo/specific",
+             'Part_Number="Rocket_Launcher_0001"; Version="1"; Path="/acme"',
+             'Part_Number="Riding_Rocket_0023"; Version="1"; Path="/acme/ammo"');
+
+# A subsequent request by the user agent to the (same) server for URLs of
+# the form /acme/ammo/...  would include the following request header:
+# 
+# Cookie: $Version="1";
+#         Part_Number="Riding_Rocket_0023"; $Path="/acme/ammo";
+#         Part_Number="Rocket_Launcher_0001"; $Path="/acme"
+# 
+# Note that the NAME=VALUE pair for the cookie with the more specific Path
+# attribute, /acme/ammo, comes before the one with the less specific Path
+# attribute, /acme.  Further note that the same cookie name appears more
+# than once.
+
+$cookie = interact($c, "http://www.acme.com/acme/ammo/...");
+print "not " unless $cookie =~ /Riding_Rocket_0023.*Rocket_Launcher_0001/;
+print "ok 12\n";
+
+# A subsequent request by the user agent to the (same) server for a URL of
+# the form /acme/parts/ would include the following request header:
+# 
+# Cookie: $Version="1"; Part_Number="Rocket_Launcher_0001"; $Path="/acme"
+# 
+# Here, the second cookie's Path attribute /acme/ammo is not a prefix of
+# the request URL, /acme/parts/, so the cookie does not get forwarded to
+# the server.
+
+$cookie = interact($c, "http://www.acme.com/acme/parts/");
+print "not " unless $cookie =~ /Rocket_Launcher_0001/ &&
+		    $cookie !~ /Riding_Rocket_0023/;
+print "ok 13\n";
+
+print $c->as_string;
+
+#-----------------------------------------------------------------------
+
+# Test rejection of Set-Cookie2 responses based on domain, path or port
+
+$c = HTTP::Cookies->new;
+
+# illegal domain (no embedded dots)
+$cookie = interact($c, "http://www.acme.com", 'foo=bar; domain=".com"');
+print "not " if count_cookies($c) > 0;
+print "ok 14\n";
+
+# legal domain
+$cookie = interact($c, "http://www.acme.com", 'foo=bar; domain="acme.com"');
+print "not " if count_cookies($c) != 1;
+print "ok 15\n";
+
+# illegal domain (host prefix "www.a" contains a dot)
+$cookie = interact($c, "http://www.a.acme.com", 'foo=bar; domain="acme.com"');
+print "not " if count_cookies($c) != 1;
+print "ok 16\n";
+
+# legal domain
+$cookie = interact($c, "http://www.a.acme.com", 'foo=bar; domain=".a.acme.com"');
+print "not " if count_cookies($c) != 2;
+print "ok 17\n";
+
+# can't use a IP-address as domain
+$cookie = interact($c, "http://125.125.125.125", 'foo=bar; domain="125.125.125"');
+print "not " if count_cookies($c) != 2;
+print "ok 18\n";
+
+# illegal path (must be prefix of request path)
+$cookie = interact($c, "http://www.sol.no", 'foo=bar; domain=".sol.no"; path="/foo"');
+print "not " if count_cookies($c) != 2;
+print "ok 19\n";
+
+# legal path
+$cookie = interact($c, "http://www.sol.no/foo/bar", 'foo=bar; domain=".sol.no"; path="/foo"');
+print "not " if count_cookies($c) != 3;
+print "ok 20\n";
+
+# illegal port (request-port not in list)
+$cookie = interact($c, "http://www.sol.no", 'foo=bar; domain=".sol.no"; port="90,100"');
+print "not " if count_cookies($c) != 3;
+print "ok 21\n";
+
+# legal port
+$cookie = interact($c, "http://www.sol.no", 'foo=bar; domain=".sol.no"; port="90,100, 80,8080"; max-age=100; Comment = "Just kidding! (\"|\\\\) "');
+print "not " if count_cookies($c) != 4;
+print "ok 22\n";
+
+# port attribute without any value (current port)
+$cookie = interact($c, "http://www.sol.no", 'foo9=bar; domain=".sol.no"; port; max-age=100;');
+print "not " if count_cookies($c) != 5;
+print "ok 23\n";
+
+# encoded path
+$cookie = interact($c, "http://www.sol.no/foo/", 'foo8=bar; path="/%66oo"');
+print "not " if count_cookies($c) != 6;
+print "ok 24\n";
+
+my $file = "lwp-cookies-$$.txt";
+$c->save($file);
+$old = $c->as_string;
+undef($c);
+
+$c = HTTP::Cookies->new;
+$c->load($file);
+unlink($file) || warn "Can't unlink $file: $!";
+
+print "not " unless $old eq $c->as_string;
+print "ok 25\n";
+
+undef($c);
+
+#
+# Try some URL encodings of the PATHs
+#
+$c = HTTP::Cookies->new;
+interact($c, "http://www.acme.com/foo%2f%25/%40%40%0Anew%E5/%E5", 'foo  =   bar; version    =   1');
+print $c->as_string;
+
+$cookie = interact($c, "http://www.acme.com/foo%2f%25/@@%0anewå/æøå", "bar=baz; path=\"/foo/\"; version=1");
+print "not " unless $cookie =~ /foo=bar/ && $cookie =~ /^\$version=\"?1\"?/i;
+print "ok 26\n";
+
+$cookie = interact($c, "http://www.acme.com/foo/%25/@@%0anewå/æøå");
+print "not " if $cookie;
+print "ok 27\n";
+
+undef($c);
+
+#
+# Try to use the Netscape cookie file format for saving
+#
+$file = "cookies-$$.txt";
+$c = HTTP::Cookies::Netscape->new(file => $file);
+interact($c, "http://www.acme.com/", "foo1=bar; max-age=100");
+interact($c, "http://www.acme.com/", "foo2=bar; port=\"80\"; max-age=100; Discard; Version=1");
+interact($c, "http://www.acme.com/", "foo3=bar; secure; Version=1");
+$c->save;
+undef($c);
+
+$c = HTTP::Cookies::Netscape->new(file => $file);
+print "not " unless count_cookies($c) == 1;     # 2 of them discarded on save
+print "ok 28\n";
+
+print "not " unless $c->as_string =~ /foo1=bar/;
+print "ok 29\n";
+undef($c);
+unlink($file);
+
+
+#
+# Some additional Netscape cookies test
+#
+$c = HTTP::Cookies->new;
+$req = HTTP::Request->new(POST => "http://foo.bar.acme.com/foo");
+
+# Netscape allows a host part that contains dots
+$res = HTTP::Response->new(200, "OK");
+$res->header(set_cookie => 'Customer=WILE_E_COYOTE; domain=.acme.com');
+$res->request($req);
+$c->extract_cookies($res);
+
+# and that the domain is the same as the host without adding a leading
+# dot to the domain.  Should not quote even if strange chars are used
+# in the cookie value.
+$res = HTTP::Response->new(200, "OK");
+$res->header(set_cookie => 'PART_NUMBER=3,4; domain=foo.bar.acme.com');
+$res->request($req);
+$c->extract_cookies($res);
+
+print $c->as_string;
+
+$req = HTTP::Request->new(POST => "http://foo.bar.acme.com/foo");
+$c->add_cookie_header($req);
+#print $req->as_string;
+print "not " unless $req->header("Cookie") =~ /PART_NUMBER=3,4/ &&
+	            $req->header("Cookie") =~ /Customer=WILE_E_COYOTE/;
+print "ok 30\n";
+
+
+
+# Test handling of local intranet hostnames without a dot
+$c->clear;
+print "---\n";
+#require LWP::Debug;
+#LWP::Debug::level('+');
+
+interact($c, "http://example/", "foo1=bar; PORT; Discard;");
+$_=interact($c, "http://example/", 'foo2=bar; domain=".local"');
+print "not " unless /foo1=bar/;
+print "ok 31\n";
+
+$_=interact($c, "http://example/", 'foo3=bar');
+$_=interact($c, "http://example/");
+print "Cookie: $_\n";
+print "not " unless /foo2=bar/ && count_cookies($c) == 3;
+print "ok 32\n";
+print $c->as_string;
+
+#-------------------------------------------------------------------
+
+sub interact
+{
+    my $c = shift;
+    my $url = shift;
+    my $req = HTTP::Request->new(POST => $url);
+    $c->add_cookie_header($req);
+    my $cookie = $req->header("Cookie");
+    my $res = HTTP::Response->new(200, "OK");
+    $res->request($req);
+    for (@_) { $res->push_header("Set-Cookie2" => $_) }
+    $c->extract_cookies($res);
+    return $cookie;
+}
+
+sub count_cookies
+{
+    my $c = shift;
+    my $no = 0;
+    $c->scan(sub { $no++ });
+    $no;
+}
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/date.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/date.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/date.t	(revision 20131)
@@ -0,0 +1,165 @@
+use HTTP::Date;
+
+print "1..59\n";
+
+$no = 1;
+$| = 1;
+sub ok {
+   print "not " if $_[0];
+   print "ok $no\n";
+   $no++;
+}
+
+# test str2time for supported dates
+my(@tests) =
+(
+ 'Thu Feb  3 00:00:00 GMT 1994',        # ctime format
+ 'Thu Feb  3 00:00:00 1994',            # same as ctime, except no TZ
+
+ 'Thu, 03 Feb 1994 00:00:00 GMT',       # proposed new HTTP format
+ 'Thursday, 03-Feb-94 00:00:00 GMT',    # old rfc850 HTTP format
+ 'Thursday, 03-Feb-1994 00:00:00 GMT',  # broken rfc850 HTTP format
+
+ '03/Feb/1994:00:00:00 0000',   # common logfile format
+ '03/Feb/1994:01:00:00 +0100',  # common logfile format
+ '02/Feb/1994:23:00:00 -0100',  # common logfile format
+
+ '03 Feb 1994 00:00:00 GMT',    # HTTP format (no weekday)
+ '03-Feb-94 00:00:00 GMT',      # old rfc850 (no weekday)
+ '03-Feb-1994 00:00:00 GMT',    # broken rfc850 (no weekday)
+ '03-Feb-1994 00:00 GMT',       # broken rfc850 (no weekday, no seconds)
+ '03-Feb-1994 00:00',           # VMS dir listing format
+
+ '03-Feb-94',    # old rfc850 HTTP format    (no weekday, no time)
+ '03-Feb-1994',  # broken rfc850 HTTP format (no weekday, no time)
+ '03 Feb 1994',  # proposed new HTTP format  (no weekday, no time)
+ '03/Feb/1994',  # common logfile format     (no time, no offset)
+
+ #'Feb  3 00:00',     # Unix 'ls -l' format (can't really test it here)
+ 'Feb  3 1994',       # Unix 'ls -l' format
+
+ "02-03-94  12:00AM", # Windows 'dir' format
+
+ # ISO 8601 formats
+ '1994-02-03 00:00:00 +0000',
+ '1994-02-03',
+ '19940203',
+ '1994-02-03T00:00:00+0000',
+ '1994-02-02T23:00:00-0100',
+ '1994-02-02T23:00:00-01:00',
+ '1994-02-03T00:00:00 Z',
+ '19940203T000000Z',
+ '199402030000',
+
+ # A few tests with extra space at various places
+ '  03/Feb/1994      ',
+ '  03   Feb   1994  0:00  ',
+);
+
+my $time = 760233600;  # assume broken POSIX counting of seconds
+for (@tests) {
+    if (/GMT/i) {
+	$t = str2time($_);
+    } else {
+	$t = str2time($_, "GMT");
+    }
+    $t = "UNDEF" unless defined $t;
+    print "'$_'  =>  $t\n";
+    print $@ if $@;
+    print "not " if $t eq 'UNDEF' || $t != $time;
+    ok;
+}
+
+# test time2str
+die "time2str failed"
+    unless time2str($time) eq 'Thu, 03 Feb 1994 00:00:00 GMT';
+
+# test the 'ls -l' format with missing year$
+# round to nearest minute 3 days ago.
+$time = int((time - 3 * 24*60*60) /60)*60;
+($min, $hr, $mday, $mon) = (localtime $time)[1,2,3,4];
+$mon = (qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec))[$mon];
+$str = sprintf("$mon %02d %02d:%02d", $mday, $hr, $min);
+$t = str2time($str);
+$t = "UNDEF" unless defined $t;
+print "'$str'  =>  $t ($time)\n";
+print "not " if $t != $time;
+ok;
+
+# try some out of bounds date and some garbage.
+for ('03-Feb-1969', '03-Feb-2039',
+     undef, '', 'Garbage',
+     'Mandag 16. September 1996',
+     'Thu Feb  3 00:00:00 CET 1994',
+     'Thu, 03 Feb 1994 00:00:00 CET',
+     'Wednesday, 31-Dec-69 23:59:59 GMT',
+
+     '1980-00-01',
+     '1980-13-01',
+     '1980-01-00',
+     '1980-01-32',
+     '1980-01-01 25:00:00',
+     '1980-01-01 00:61:00',
+     '1980-01-01 00:00:61',
+    )
+{
+    my $bad = 0;
+    eval {
+	if (defined str2time $_) {
+	    print "str2time($_) is not undefined\n";
+	    $bad++;
+	}
+    };
+    print defined($_) ? "'$_'\n" : "undef\n";
+    print $@ if $@;
+    print "not " if $bad;
+    ok;
+}
+
+print "Testing AM/PM gruff...\n";
+
+$t = time2iso(str2time("11-12-96  0:00AM"));print "$t\n";
+ok($t ne "1996-11-12 00:00:00");
+
+$t = time2iso(str2time("11-12-96 12:00AM"));print "$t\n";
+ok($t ne "1996-11-12 00:00:00");
+
+$t = time2iso(str2time("11-12-96  0:00PM"));print "$t\n";
+ok($t ne "1996-11-12 12:00:00");
+
+$t = time2iso(str2time("11-12-96 12:00PM"));print "$t\n";
+ok($t ne "1996-11-12 12:00:00");
+
+
+$t = time2iso(str2time("11-12-96  1:05AM"));print "$t\n";
+ok($t ne "1996-11-12 01:05:00");
+
+$t = time2iso(str2time("11-12-96 12:05AM"));print "$t\n";
+ok($t ne "1996-11-12 00:05:00");
+
+$t = time2iso(str2time("11-12-96  1:05PM"));print "$t\n";
+ok($t ne "1996-11-12 13:05:00");
+
+$t = time2iso(str2time("11-12-96 12:05PM"));print "$t\n";
+ok($t ne "1996-11-12 12:05:00");
+
+
+
+# Test the str2iso routines
+use HTTP::Date qw(time2iso time2isoz);
+
+print "Testing time2iso functions\n";
+
+$a = time2iso;
+$b = time2iso(500000);
+print "LOCAL $a  $b\n";
+$az = time2isoz;
+$bz = time2isoz(500000);
+print "GMT   $az $bz\n";
+
+for ($a,  $b)  { ok if /^\d{4}-\d\d-\d\d \d\d:\d\d:\d\d$/;  }
+for ($az, $bz) { ok if /^\d{4}-\d\d-\d\d \d\d:\d\d:\d\dZ$/; }
+
+
+
+print "HTTP::Date $HTTP::Date::VERSION tested ok\n";
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/headers-auth.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/headers-auth.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/headers-auth.t	(revision 20131)
@@ -0,0 +1,40 @@
+print "1..4\n";
+
+use HTTP::Response;
+use HTTP::Headers::Auth;
+
+$res = HTTP::Response->new(401);
+$res->push_header(WWW_Authenticate => qq(Foo realm="WallyWorld", foo=bar, Bar realm="WallyWorld2"));
+$res->push_header(WWW_Authenticate => qq(Basic Realm="WallyWorld", foo=bar, bar=baz));
+
+print $res->as_string;
+
+%auth = $res->www_authenticate;
+
+print "not " unless keys(%auth) == 3;
+print "ok 1\n";
+
+print "not " unless $auth{basic}{realm} eq "WallyWorld" &&
+                    $auth{bar}{realm} eq "WallyWorld2";
+print "ok 2\n";
+
+$a = $res->www_authenticate;
+print "not " unless $a eq 'Foo realm="WallyWorld", foo=bar, Bar realm="WallyWorld2", Basic Realm="WallyWorld", foo=bar, bar=baz';
+print "ok 3\n";
+
+$res->www_authenticate("Basic realm=foo1");
+print $res->as_string;
+
+$res->www_authenticate(Basic => {realm => foo2});
+print $res->as_string;
+
+$res->www_authenticate(Basic => [realm => foo3, foo=>33],
+Digest => {nonce=>"bar", foo=>'foo'});
+print $res->as_string;
+
+$_ = $res->as_string;
+
+print "not " unless /WWW-Authenticate: Basic realm="foo3", foo=33/ &&
+                    /WWW-Authenticate: Digest nonce=bar, foo=foo/;
+print "ok 4\n";
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/headers-etag.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/headers-etag.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/headers-etag.t	(revision 20131)
@@ -0,0 +1,28 @@
+print "1..4\n";
+
+require HTTP::Headers::ETag;
+
+$h = HTTP::Headers->new;
+$h->etag("tag1");
+print "not " unless $h->etag eq qq("tag1");
+print "ok 1\n";
+
+$h->etag("w/tag2");
+print "not " unless $h->etag eq qq(W/"tag2");
+print "ok 2\n";
+
+$h->if_match(qq(W/"foo", bar, baz), "bar");
+$h->if_none_match(333);
+
+$h->if_range("tag3");
+print "not " unless $h->if_range eq qq("tag3");
+print "ok 3\n";
+
+$t = time;
+$h->if_range($t);
+print "not " unless $h->if_range == $t;
+print "ok 4\n";
+
+
+print $h->as_string;
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/headers-util.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/headers-util.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/headers-util.t	(revision 20131)
@@ -0,0 +1,61 @@
+use strict;
+use HTTP::Headers::Util qw(split_header_words join_header_words);
+
+my $extra_tests = 2;
+
+my @s_tests = (
+
+   ["foo"                     => "foo"],
+   ["foo=bar"                 => "foo=bar"],
+   ["   foo   "               => "foo"],
+   ["foo="                    => 'foo=""'],
+   ["foo=bar bar=baz"         => "foo=bar; bar=baz"],
+   ["foo=bar;bar=baz"         => "foo=bar; bar=baz"],
+   ['foo bar baz'             => "foo; bar; baz"],
+   ['foo="\"" bar="\\\\"'     => 'foo="\""; bar="\\\\"'],
+   ['foo,,,bar'               => 'foo, bar'],
+   ['foo=bar,bar=baz'         => 'foo=bar, bar=baz'],
+
+   ['text/html; charset=iso-8859-1' =>
+    'text/html; charset="iso-8859-1"'],
+
+   ['foo="bar"; port="80,81"; discard, bar=baz' =>
+    'foo=bar; port="80,81"; discard, bar=baz'],
+
+   ['Basic realm="\"foo\\\\bar\""' =>
+    'Basic; realm="\"foo\\\\bar\""'],
+);
+
+print "1..", @s_tests + $extra_tests, "\n";
+
+my $testno = 1;
+
+print "split_header_words() tests\n";
+for (@s_tests) {
+   my($arg, $expect) = @$_;
+   my @arg = ref($arg) ? @$arg : $arg;
+
+   my $res = join_header_words(split_header_words(@arg));
+   if ($res ne $expect) {
+       print "\nUnexpected result: '$res'\n";
+       print "         Expected: '$expect'\n";
+       print "  when parsing '", join(", ", @arg), "'\n";
+       eval {
+	   require Data::Dumper;
+           my @p = split_header_words(@arg);
+           print Data::Dumper::Dumper(\@p);
+       };
+       print "not ";
+   }
+   print "ok ", $testno++, "\n";
+}
+
+
+print "Extra tests\n";
+# some extra tests
+print "not " unless join_header_words("foo" => undef, "bar" => "baz")
+                    eq "foo; bar=baz";
+print "ok ", $testno++, "\n";
+
+print "not " unless join_header_words() eq "";
+print "ok ", $testno++, "\n";
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/headers.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/headers.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/headers.t	(revision 20131)
@@ -0,0 +1,128 @@
+require HTTP::Headers;
+
+print "1..11\n";
+
+$h = new HTTP::Headers
+	mime_version  => "1.0",
+	content_type  => "text/html";
+
+$h->header(URI => "http://www.oslonett.no/");
+
+if ($h->header("MIME-Version") eq "1.0") {
+    print "ok 1\n";
+} else {
+    print "not ok 1\n";
+}
+
+if ($h->header('Uri') =~ /^http:/) {
+    print "ok 2\n";
+} else {
+    print "not ok 2\n";
+}
+
+
+$h->header("MY-header" => "foo",
+	   "Date" => "somedate",
+	   "Accept" => ["text/plain", "image/*"],
+	  );
+$h->push_header("accept" => "audio/basic");
+
+if ($h->header("date") eq "somedate") {
+     print "ok 3\n";
+}
+
+@accept = $h->header("accept");
+if (@accept == 3) {
+    print "ok 4\n";
+}
+
+$h->remove_header("uri", "date");
+
+
+$str = $h->as_string;
+print "\nHeader looks like this now:\n$str\n";
+
+$lines = ($str =~ tr/\n/\n/);
+
+if ($lines == 6) {
+    print "ok 5\n";
+} else {
+    print "Header has $lines lines\n";
+    print "not ok 5\n";
+}
+
+$h2 = $h->clone;
+
+$h->header("accept", "*/*");
+$h->remove_header("my-header");
+
+@accept = $h2->header("accept");
+if (@accept == 3) {
+    print "ok 6\n";
+}
+
+@accept = $h->header("accept");
+if (@accept == 1) {
+    print "ok 7\n";
+}
+
+# Check order of headers, but first remove this one
+$h2->remove_header('mime_version');
+
+# and add this general header
+$h2->header(Connection => 'close');
+
+@x = ();
+$h2->scan(sub {push(@x, shift);});
+
+$str = join(";", @x);
+$expected = "Connection;Accept;Accept;Accept;Content-Type;MY-Header";
+
+if ($str eq $expected) {
+    print "ok 8\n";
+} else {
+    print "Headers are '$str',\nexpected    '$expected'\n";
+    print "not ok 8\n";
+}
+
+# Check headers with embedded newlines:
+
+$h = new HTTP::Headers
+	a => "foo\n\n",
+	b => "foo\nbar",
+	c => "foo\n\nbar\n\n",
+	d => "foo\n\tbar";
+$str = $h->as_string("<<\n");
+print "-----\n$str------\n";
+
+print "not " unless $str =~ /^A:\s*foo<<\n
+                              B:\s*foo<<\n
+	                        \s+bar<<\n
+                              C:\s*foo<<\n
+                                \s+bar<<\n
+	                      D:\s*foo<<\n
+                                \t bar<<\n
+                             $/x;
+print "ok 9\n";
+
+
+# Check with FALSE $HTML::Headers::TRANSLATE_UNDERSCORE
+
+local($HTTP::Headers::TRANSLATE_UNDERSCORE);
+$HTTP::Headers::TRANSLATE_UNDERSCORE = undef;  # avoid -w warning
+
+$h = HTTP::Headers->new;
+
+$h->header(abc_abc   => "foo");
+$h->header("abc-abc" => "bar");
+
+#print $h->as_string;
+
+print "not " unless $h->header("ABC_ABC") eq "foo" &&
+                    $h->header("ABC-ABC") eq "bar";
+print "ok 10\n";
+
+$h->remove_header("Abc_Abc");
+print "not " unless !defined($h->header("abc_abc")) &&
+                    $h->header("ABC-ABC") eq "bar";
+print "ok 11\n";
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/listing.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/listing.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/listing.t	(revision 20131)
@@ -0,0 +1,86 @@
+print "1..6\n";
+
+
+use File::Listing;
+
+$dir = <<'EOL';
+total 68
+drwxr-xr-x   4 aas      users        1024 Mar 16 15:47 .
+drwxr-xr-x  11 aas      users        1024 Mar 15 19:22 ..
+drwxr-xr-x   2 aas      users        1024 Mar 16 15:47 CVS
+-rw-r--r--   1 aas      users        2384 Feb 26 21:14 Debug.pm
+-rw-r--r--   1 aas      users        2145 Feb 26 20:09 IO.pm
+-rw-r--r--   1 aas      users        3960 Mar 15 18:05 MediaTypes.pm
+-rw-r--r--   1 aas      users         792 Feb 26 20:12 MemberMixin.pm
+drwxr-xr-x   3 aas      users        1024 Mar 15 18:05 Protocol
+-rw-r--r--   1 aas      users        5613 Feb 26 20:16 Protocol.pm
+-rw-r--r--   1 aas      users        5963 Feb 26 21:27 RobotUA.pm
+-rw-r--r--   1 aas      users        5071 Mar 16 12:25 Simple.pm
+-rw-r--r--   1 aas      users        8817 Mar 15 18:05 Socket.pm
+-rw-r--r--   1 aas      users        2121 Feb  5 14:22 TkIO.pm
+-rw-r--r--   1 aas      users       19628 Mar 15 18:05 UserAgent.pm
+-rw-r--r--   1 aas      users        2841 Feb  5 19:06 media.types
+
+CVS:
+total 5
+drwxr-xr-x   2 aas      users        1024 Mar 16 15:47 .
+drwxr-xr-x   4 aas      users        1024 Mar 16 15:47 ..
+-rw-r--r--   1 aas      users         545 Mar 16 15:47 Entries
+-rw-r--r--   1 aas      users          39 Mar 10 09:05 Repository
+-rw-r--r--   1 aas      users          19 Mar 10 09:05 Root
+
+Protocol:
+total 37
+drwxr-xr-x   3 aas      users        1024 Mar 15 18:05 .
+drwxr-xr-x   4 aas      users        1024 Mar 16 15:47 ..
+drwxr-xr-x   2 aas      users        1024 Mar 15 18:05 CVS
+-rw-r--r--   1 aas      users        4646 Feb 26 20:13 file.pm
+-rw-r--r--   1 aas      users       13006 Mar 15 18:05 ftp.pm
+-rw-r--r--   1 aas      users        5935 Mar  6 10:29 gopher.pm
+-rw-r--r--   1 aas      users        5453 Mar  6 10:29 http.pm
+-rw-r--r--   1 aas      users        2365 Feb 26 20:13 mailto.pm
+
+Protocol/CVS:
+total 5
+drwxr-xr-x   2 aas      users        1024 Mar 15 18:05 .
+drwxr-xr-x   3 aas      users        1024 Mar 15 18:05 ..
+-rw-r--r--   1 aas      users         238 Mar 15 18:05 Entries
+-rw-r--r--   1 aas      users          48 Mar 10 09:05 Repository
+-rw-r--r--   1 aas      users          19 Mar 10 09:05 Root
+EOL
+
+@dir = parse_dir($dir, undef, 'unix');
+
+print int(@dir) ." lines found\n";
+@dir != 25 && print "not ";
+print "ok 1\n";
+
+for (@dir) {
+   ($name, $type, $size, $mtime, $mode) = @$_;
+   $size ||= 0;  # ensure that it is defined
+   printf "%-25s $type %6d  ", $name, $size;
+   print scalar(localtime($mtime));
+   printf "  %06o", $mode;
+   print "\n";
+}
+
+# Pick out the Socket.pm line as the sample we check carefully
+($name, $type, $size, $mtime, $mode) = @{$dir[9]};
+
+$name eq "Socket.pm" || print "not ";
+print "ok 2\n";
+
+$type eq "f" || print "not ";
+print "ok 3\n";
+
+$size == 8817 || print "not ";
+print "ok 4\n";
+
+# Must be careful when checking the time stamps because we don't know
+# which year if this script lives for a long time.
+$timestring = scalar(localtime($mtime));
+$timestring =~ /Mar\s+15\s+18:05/ or print "not ";
+print "ok 5\n";
+
+$mode == 0100644 || print "not ";
+print "ok 6\n";
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/mediatypes.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/mediatypes.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/mediatypes.t	(revision 20131)
@@ -0,0 +1,87 @@
+use LWP::MediaTypes;
+
+require URI::URL;
+
+$url1 = new URI::URL 'http://www/foo/test.gif?search+x#frag';
+$url2 = new URI::URL 'http:test';
+
+$file = "/etc/passwd";
+-r $file or $file = "./README";
+
+@tests =
+(
+ ["/this.dir/file.html" => "text/html",],
+ ["test.gif.htm"        => "text/html",],
+ ["test.txt.gz"         => "text/plain", "gzip"],
+ ["gif.foo"             => "application/octet-stream",],
+ ["lwp-0.03.tar.Z"      => "application/x-tar", "compress"],
+ [$file		        => "text/plain",],
+ ["/random/file"        => "application/octet-stream",],
+ ["/dev/null"	        => "text/plain",],
+ [$url1	        	=> "image/gif",],
+ [$url2	        	=> "application/octet-stream",],
+ ["x.ppm.Z.UU"		=> "image/x-portable-pixmap","compress","x-uuencode",],
+);
+
+$notests = @tests + 3;
+print "1..$notests\n";
+
+if (-f "$ENV{HOME}/.mime.types") {
+   warn "
+The MediaTypes test might fail because you have a private ~/.mime.types file
+If you get a failed test, try to move it away while testing.
+";
+}
+
+
+$testno = 1;
+for (@tests) {
+    ($file, $expectedtype, @expectedEnc) = @$_;
+    $type1 = guess_media_type($file);
+    ($type, @enc) = guess_media_type($file);
+    if ($type1 ne $type) {
+       print "guess_media_type does not return same content-type in scalar and array conext.\n";
+	next;
+    }
+    $type = "undef" unless defined $type;
+    if ($type eq $expectedtype and "@enc" eq "@expectedEnc") {
+	print "ok $testno\n";
+    } else {
+	print "expected '$expectedtype' for '$file', got '$type'\n";
+	print "encoding: expected: '@expectedEnc', got '@enc'\n"
+	  if @expectedEnc || @enc;
+	print "nok ok $testno\n";
+    }
+    $testno++;
+}
+
+@imgSuffix = media_suffix('image/*');
+print "Image suffixes: @imgSuffix\n";
+
+print "\n";
+require HTTP::Response;
+$r = new HTTP::Response 200, "Document follows";
+$r->title("file.tar.gz.uu");
+guess_media_type($r->title, $r);
+print $r->as_string;
+
+print "not " unless $r->content_type eq "application/x-tar";
+print "ok $testno\n"; $testno++;
+
+@enc = $r->header("Content-Encoding");
+print "not " unless "@enc" eq "gzip x-uuencode";
+print "ok $testno\n"; $testno++;
+
+#
+use LWP::MediaTypes qw(add_type add_encoding);
+add_type("x-world/x-vrml", qw(wrl vrml));
+add_encoding("x-gzip" => "gz");
+add_encoding(rot13 => "r13");
+
+@x = guess_media_type("foo.vrml.r13.gz");
+#print "@x\n";
+print "not " unless "@x" eq "x-world/x-vrml rot13 x-gzip";
+print "ok $testno\n"; $testno++;
+
+#print LWP::MediaTypes::_dump();
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/message.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/message.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/message.t	(revision 20131)
@@ -0,0 +1,104 @@
+print "1..15\n";
+
+require HTTP::Request;
+require HTTP::Response;
+
+$req = new HTTP::Request 'GET', "http://www.sn.no/";
+$req->header(
+	"if-modified-since" => "Thu, 03 Feb 1994 00:00:00 GMT",
+	"mime-version"      => "1.0");
+
+$str = $req->as_string;
+
+print $str;
+
+$str =~ /^GET/m || print "not ";
+print "ok 1\n";
+
+$req->header("MIME-Version") eq "1.0" || print "not ";
+print "ok 2\n";
+
+$req->content("gisle");
+$req->add_content(" aas");
+$req->add_content(\ " old interface is depreciated");
+
+${$req->content_ref} =~ s/\s+is\s+depreciated//;
+
+print "Content is: ", $req->content, "\n";
+
+$req->content eq "gisle aas old interface" || print "not ";
+print "ok 3\n";
+
+$req->if_modified_since == 760233600 || print "not ";
+print "ok 4\n";
+
+$time = time;
+
+$req->date($time);
+$timestr = gmtime($time);
+($month) = ($timestr =~ /^\S+\s+(\S+)/);  # extract month;
+
+print "These should represent the same time:\n\t", $req->header('Date'), "\n\t$timestr\n";
+
+$req->header('Date') =~ /\Q$month/ || print "not ";
+print "ok 5\n";
+
+$req->authorization_basic("gisle", "passwd");
+$auth = $req->header("Authorization");
+
+print "$auth\n";
+$auth =~ /Z2lzbGU6cGFzc3dk/ || print "not ";
+print "ok 6\n";
+
+($user, $pass) = $req->authorization_basic;
+($user eq "gisle" && $pass eq "passwd") || print "not ";
+print "ok 7\n";
+
+# Check the response
+$res = new HTTP::Response 200, "This message";
+
+$html = $res->error_as_HTML;
+print $html;
+
+($html =~ /<head>/i && $html =~ /This message/) || print "not ";
+print "ok 8\n";
+
+$res->is_success || print "not ";
+print "ok 9\n";
+
+$res->content_type("text/html;version=3.0");
+$res->content("<html>...</html>\n");
+
+$res2 = $res->clone;
+
+print $res2->as_string;
+
+$res2->header("cOntent-TYPE") eq "text/html;version=3.0" || print "not ";
+print "ok 10\n";
+
+$res2->code == 200 || print "not ";
+print "ok 11\n";
+
+$res2->content =~ />\.\.\.</ || print "not ";
+print "ok 12\n";
+
+# Check the base method:
+
+$res = new HTTP::Response 200, "This message";
+$res->request($req);
+$res->content_type("image/gif");
+
+$res->base eq "http://www.sn.no/" || print "not ";
+print "ok 13\n";
+
+$res->header('Base', 'http://www.sn.no/xxx/');
+
+$res->base eq "http://www.sn.no/xxx/" || print "not ";
+print "ok 14\n";
+
+# Check the AUTLOAD delegate method with regular expressions
+"This string contains text/html" =~ /(\w+\/\w+)/;
+$res->content_type($1);
+
+$res->content_type eq "text/html" || print "not ";
+print "ok 15\n";
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/negotiate.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/negotiate.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/negotiate.t	(revision 20131)
@@ -0,0 +1,105 @@
+print "1..3\n";
+
+use HTTP::Request;
+use HTTP::Negotiate;
+
+
+$no = 1;
+sub ok
+{
+    print "ok " . $no++ . "\n";
+}
+
+sub not_ok
+{
+    print "not ";
+    ok;
+}
+
+
+ #  ID       QS     Content-Type             Encoding     Char-Set      Lang    Size
+ $variants =
+  [
+   ['var1',  0.950, 'text/plain',           ['uuencode',
+					     'compress'], 'iso-8859-2', 'se',    400],
+   ['var2',  1.000, 'text/html;version=2.0', 'gzip',      'iso-8859-1', 'en',   3000],
+   ['var3',  0.333, 'image/gif',            undef,        undef,        undef, 43555],
+ ];
+
+
+# First we try a request with not accept headers
+$request = new HTTP::Request 'GET', 'http://localhost/';
+@a = choose($variants, $request);
+show_res(@a);
+expect(\@a, [['var2' => 1],
+	     ['var1' => 0.95],
+	     ['var3' => 0.333]
+	    ]
+);
+
+
+$a = choose($variants, $request);
+print "The chosen one is '$a'\n";
+if ($a eq 'var2') {
+    ok;
+} else {
+    not_ok;
+}
+
+#------------------
+
+$request = new HTTP::Request 'GET', 'http://localhost/';
+$request->header('Accept', 'text/plain; q=0.55, image/gif; mbx=10000');
+$request->push_header('Accept', 'text/*; q=0.25');
+$request->header('Accept-Language', 'no, en');
+$request->header('Accept-Charset', 'iso-8859-1');
+$request->header('Accept-Encoding', 'gzip');
+
+@a = choose($variants, $request);
+show_res(@a);
+expect(\@a, [['var2' => 0.25],
+	     ['var1' => 0],
+	     ['var3' => 0]
+	    ]
+);
+
+
+
+
+#------------------
+
+sub expect
+{
+    my($res, $exp) = @_;
+    do {
+	$a = shift @$res;
+	$b = shift @$exp;
+	last if defined($a) ne defined($b);
+	if (defined($a)) {
+	    ($va, $qa) = @$a;
+	    ($vb, $qb) = @$b;
+	    if ($va ne $vb) {
+		print "$va == $vb ?\n";
+		not_ok;
+		return;
+	    }
+	    if (abs($qa - $qb) > 0.002) {
+		print "$qa ~= $qb ?\n";
+		not_ok;
+		return;
+	    }
+	}
+
+    } until (!defined($a) || !defined($b));
+    return not_ok if defined($a) ne defined($b);
+    ok;
+}
+
+sub show_res
+{
+    print "-------------\n";
+    for (@_) {
+	printf "%-6s %.3f\n", @$_;
+    }
+    print "-------------\n";
+}
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/response.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/response.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/response.t	(revision 20131)
@@ -0,0 +1,86 @@
+
+# Test extra HTTP::Response methods.  Basic operation is tested in the
+# message.t test suite.
+
+
+print "1..7\n";
+
+
+use HTTP::Date;
+use HTTP::Request;
+use HTTP::Response;
+
+my $time = time;
+
+$req = HTTP::Request->new(GET => 'http://www.sn.no');
+$req->date($time - 30);
+
+$r = new HTTP::Response 200, "OK";
+$r->client_date($time - 20);
+$r->date($time - 25);
+$r->last_modified($time - 5000000);
+$r->request($req);
+
+print $r->as_string;
+
+$current_age = $r->current_age;
+
+if ($current_age < 35  || $current_age > 40) {
+    print "not ";
+}
+print "ok 1\n";
+
+$freshness_lifetime = $r->freshness_lifetime;
+if ($freshness_lifetime < 12 * 3600) {
+    print "not ";
+}
+print "ok 2\n";
+
+$is_fresh = $r->is_fresh;
+
+print "not " unless $is_fresh;
+print "ok 3\n";
+
+print "current_age        = $current_age\n";
+print "freshness_lifetime = $freshness_lifetime\n";
+print "response is ";
+print "not " unless $is_fresh;
+print "fresh\n";
+
+
+print "it will be fresh is ";
+print $freshness_lifetime - $current_age;
+print " more seconds\n";
+
+# OK, now we add an Expires header
+$r->expires($time);
+print $r->as_string;
+
+$freshness_lifetime = $r->freshness_lifetime;
+print "freshness_lifetime = $freshness_lifetime\n";
+print "not " unless $freshness_lifetime == 25;
+print "ok 4\n";
+$r->remove_header('expires');
+
+# Now we try the 'Age' header and the Cache-Contol:
+
+$r->header('Age', 300);
+$r->push_header('Cache-Control', 'junk');
+$r->push_header(Cache_Control => 'max-age = 10');
+
+print $r->as_string;
+
+$current_age = $r->current_age;
+$freshness_lifetime = $r->freshness_lifetime;
+
+print "current_age        = $current_age\n";
+print "freshness_lifetime = $freshness_lifetime\n";
+
+print "not " if $current_age < 300;
+print "ok 5\n";
+
+print "not " if $freshness_lifetime != 10;
+print "ok 6\n";
+
+print "not " unless $r->fresh_until;  # should return something
+print "ok 7\n";
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/status.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/status.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/base/status.t	(revision 20131)
@@ -0,0 +1,32 @@
+use HTTP::Status;
+
+print "1..8\n";
+
+200 == RC_OK || print "not ";
+print "ok 1\n";
+
+is_success(RC_ACCEPTED) || print "not ";
+print "ok 2\n";
+
+is_error(RC_BAD_REQUEST) || print "not ";
+print "ok 3\n";
+
+is_redirect(RC_MOVED_PERMANENTLY) || print "not ";
+print "ok 4\n";
+
+is_success(RC_NOT_FOUND) && print "not ";
+print "ok 5\n";
+
+$mess = status_message(0);
+
+defined $mess && print "not ";
+print "ok 6\n";
+
+$mess = status_message(200);
+
+if ($mess =~ /ok/i) {
+    print "ok 7\n";
+}
+
+is_info(RC_CONTINUE) || print "not ";
+print "ok 8\n";
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/local/autoload.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/local/autoload.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/local/autoload.t	(revision 20131)
@@ -0,0 +1,30 @@
+#
+# See if autoloading of protocol schemes work
+#
+
+print "1..1\n";
+
+require LWP::UserAgent;
+# note no LWP::Protocol::file;
+
+# localhost will not work on win32 (when networking is disabled)
+$url = $^O eq 'MSWin32' ? 'file:.' : 'file://localhost/';
+
+print "Trying to fetch " . (new URI::URL $url)->local_path . " ...\n";
+
+my $ua = new LWP::UserAgent;    # create a useragent to test
+
+$ua->timeout(30);               # timeout in seconds
+#$ua->use_alarm(0);               # don't use alarms
+#$ua->use_eval(0);                # don't eval, just die when thing go wrong
+				# (easier to read while debugging)
+
+my $request = new HTTP::Request('GET', $url);
+
+my $response = $ua->request($request, undef, undef);
+if ($response->is_success) {
+    print "ok 1\n";
+} else {
+    print $response->error_as_HTML;
+    print "not ok 1\n";
+}
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/local/get.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/local/get.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/local/get.t	(revision 20131)
@@ -0,0 +1,85 @@
+#
+# Test retrieving a file with a 'file://' URL,
+#
+
+# First locate some suitable tmp-dir.  We need an absolute path.
+$TMPDIR = undef;
+for ("/tmp/", "/var/tmp", "/usr/tmp", "/local/tmp") {
+    if (open(TEST, ">$_/test-$$")) {
+        close(TEST);
+	unlink("$_/test-$$");
+	$TMPDIR = $_;
+	last;
+    }
+}
+$TMPDIR ||= $ENV{TEMP} if $^O eq 'MSWin32';
+unless ($TMPDIR) {
+   # Can't run any tests
+   print "1..0\n";
+   print "ok 1\n";
+   exit;
+}
+$TMPDIR =~ tr|\\|/|;
+print "1..2\n";
+
+use LWP::Simple;
+require LWP::Protocol::file;
+
+my $orig = "$TMPDIR/lwp-orig-$$";          # local file
+my $copy = "$TMPDIR/lwp-copy-$$"; 	    # downloaded copy
+
+# First we create the original
+open(OUT, ">$orig") or die "Cannot open $orig: $!";
+for (1..100) {
+    print OUT "This is line $_ of $orig\n";
+}
+close(OUT);
+
+
+# Then we make a test using getprint(), so we need to capture stdout
+open (OUT, ">$copy") or die "Cannot open $copy: $!";
+select(OUT);
+
+# do the retrieval
+getprint("file://localhost" . ($orig =~ m|^/| ? $orig : "/$orig"));
+
+close(OUT);
+select(STDOUT);
+
+# read and compare the files
+open(IN, $orig) or die "Cannot open '$orig': $!";
+undef($/);
+$origtext = <IN>;
+close(IN);
+open(IN, $copy) or die "Cannot open '$copy': $!";
+undef($/);
+$copytext = <IN>;
+close(IN);
+
+unlink($copy);
+
+if ($origtext eq $copytext) {
+    print "ok 1\n";
+} else {
+    print "not ok 1\n";
+}
+
+
+# Test getstore() function
+
+getstore("file:$orig", $copy);
+
+# Take a look at the new copy
+open(IN, $copy) or die "Cannot open '$copy': $!";
+undef($/);
+$copytext = <IN>;
+close(IN);
+
+unlink($orig);
+unlink($copy);
+
+if ($origtext eq $copytext) {
+    print "ok 2\n";
+} else {
+    print "not ok 2\n";
+}
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/local/http.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/local/http.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/local/http.t	(revision 20131)
@@ -0,0 +1,319 @@
+$| = 1; # autoflush
+
+require IO::Socket;  # make sure this work before we try to make a HTTP::Daemon
+
+# First we make ourself a daemon in another process
+my $D = shift || '';
+if ($D eq 'daemon') {
+
+    require HTTP::Daemon;
+
+    my $d = new HTTP::Daemon Timeout => 10;
+
+    print "Please to meet you at: <URL:", $d->url, ">\n";
+    open(STDOUT, ">/dev/null");
+
+    while ($c = $d->accept) {
+	$r = $c->get_request;
+	if ($r) {
+	    my $p = ($r->url->path_components)[1];
+	    my $func = lc("httpd_" . $r->method . "_$p");
+	    if (defined &$func) {
+		&$func($c, $r);
+	    } else {
+		$c->send_error(404);
+	    }
+	}
+	$c = undef;  # close connection
+    }
+    print STDERR "HTTP Server terminated\n";
+    exit;
+}
+else {
+    use Config;
+    open(DAEMON, "$Config{'perlpath'} local/http.t daemon |") or die "Can't exec daemon: $!";
+}
+
+print "1..18\n";
+
+
+my $greeting = <DAEMON>;
+$greeting =~ /(<[^>]+>)/;
+
+require URI::URL;
+URI::URL->import;
+my $base = new URI::URL $1;
+
+print "Will access HTTP server at $base\n";
+
+require LWP::UserAgent;
+require HTTP::Request;
+$ua = new LWP::UserAgent;
+$ua->agent("Mozilla/0.01 " . $ua->agent);
+$ua->from('gisle@aas.no');
+
+#----------------------------------------------------------------
+print "Bad request...\n";
+$req = new HTTP::Request GET => url("/not_found", $base);
+$req->header(X_Foo => "Bar");
+$res = $ua->request($req);
+
+print "not " unless $res->is_error
+                and $res->code == 404
+                and $res->message =~ /not\s+found/i;
+print "ok 1\n";
+# we also expect a few headers
+print "not " if !$res->server and !$res->date;
+print "ok 2\n";
+
+#----------------------------------------------------------------
+print "Simple echo...\n";
+sub httpd_get_echo
+{
+    my($c, $req) = @_;
+    $c->send_basic_header(200);
+    print $c "Content-Type: text/plain\015\012";
+    $c->send_crlf;
+    print $c $req->as_string;
+}
+
+$req = new HTTP::Request GET => url("/echo/path_info?query", $base);
+$req->push_header(Accept => 'text/html');
+$req->push_header(Accept => 'text/plain; q=0.9');
+$req->push_header(Accept => 'image/*');
+$req->if_modified_since(time - 300);
+$req->header(Long_text => 'This is a very long header line
+which is broken between
+more than one line.');
+$req->header(X_Foo => "Bar");
+
+$res = $ua->request($req);
+#print $res->as_string;
+
+print "not " unless $res->is_success
+               and  $res->code == 200 && $res->message eq "OK";
+print "ok 3\n";
+
+$_ = $res->content;
+@accept = /^Accept:\s*(.*)/mg;
+
+print "not " unless /^From:\s*gisle\@aas\.no$/m
+                and /^Host:/m
+                and @accept == 3
+	        and /^Accept:\s*text\/html/m
+	        and /^Accept:\s*text\/plain/m
+	        and /^Accept:\s*image\/\*/m
+		and /^If-Modified-Since:\s*\w{3},\s+\d+/m
+                and /^Long-Text:\s*This.*broken between/m
+		and /^X-Foo:\s*Bar$/m
+		and /^User-Agent:\s*Mozilla\/0.01/m;
+print "ok 4\n";
+
+#----------------------------------------------------------------
+print "Send file...\n";
+
+my $file = "test-$$.html";
+open(FILE, ">$file") or die "Can't create $file: $!";
+binmode FILE or die "Can't binmode $file: $!";
+print FILE <<EOT;
+<html><title>En prøve</title>
+<h1>Dette er en testfil</h1>
+Jeg vet ikke hvor stor fila behøver å være heller, men dette
+er sikkert nok i massevis.
+EOT
+close(FILE);
+
+sub httpd_get_file
+{
+    my($c, $r) = @_;
+    my %form = $r->url->query_form;
+    my $file = $form{'name'};
+    $c->send_file_response($file);
+    unlink($file);
+}
+
+$req = new HTTP::Request GET => url("/file?name=$file", $base);
+$res = $ua->request($req);
+#print $res->as_string;
+
+print "not " unless $res->is_success
+                and $res->content_type eq 'text/html'
+		and $res->content_length == 147
+		and $res->title eq 'En prøve'
+		and $res->content =~ /å være/;
+print "ok 5\n";		
+
+
+# A second try on the same file, should fail because we unlink it
+$res = $ua->request($req);
+#print $res->as_string;
+print "not " unless $res->is_error
+                and $res->code == 404;   # not found
+print "ok 6\n";
+		
+# Then try to list current directory
+$req = new HTTP::Request GET => url("/file?name=.", $base);
+$res = $ua->request($req);
+#print $res->as_string;
+print "not " unless $res->code == 501;   # NYI
+print "ok 7\n";
+
+
+#----------------------------------------------------------------
+print "Check redirect...\n";
+sub httpd_get_redirect
+{
+   my($c) = @_;
+   $c->send_redirect("/echo/redirect");
+}
+
+$req = new HTTP::Request GET => url("/redirect/foo", $base);
+$res = $ua->request($req);
+#print $res->as_string;
+
+print "not " unless $res->is_success
+                and $res->content =~ m|/echo/redirect|;
+print "ok 8\n";
+print "not " unless $res->previous->is_redirect
+                and $res->previous->code == 301;
+print "ok 9\n";
+
+# Let's test a redirect loop too
+sub httpd_get_redirect2 { shift->send_redirect("/redirect3/") }
+sub httpd_get_redirect3 { shift->send_redirect("/redirect4/") }
+sub httpd_get_redirect4 { shift->send_redirect("/redirect5/") }
+sub httpd_get_redirect5 { shift->send_redirect("/redirect6/") }
+sub httpd_get_redirect6 { shift->send_redirect("/redirect2/") }
+
+$req->url(url("/redirect2", $base));
+$res = $ua->request($req);
+#print $res->as_string;
+print "not " unless $res->is_redirect
+                and $res->header("Client-Warning") =~ /loop detected/i;
+print "ok 10\n";
+$i = 1;
+while ($res->previous) {
+   $i++;
+   $res = $res->previous;
+}
+print "not " unless $i == 6;
+print "ok 11\n";
+
+#----------------------------------------------------------------
+print "Check basic authorization...\n";
+sub httpd_get_basic
+{
+    my($c, $r) = @_;
+    #print STDERR $r->as_string;
+    my($u,$p) = $r->authorization_basic;
+    if (defined($u) && $u eq 'ok 12' && $p eq 'xyzzy') {
+        $c->send_basic_header(200);
+	print $c "Content-Type: text/plain";
+	$c->send_crlf;
+	$c->send_crlf;
+	$c->print("$u\n");
+    } else {
+        $c->send_basic_header(401);
+	$c->print("WWW-Authenticate: Basic realm=\"libwww-perl\"\015\012");
+	$c->send_crlf;
+    }
+}
+
+{
+   package MyUA; @ISA=qw(LWP::UserAgent);
+   sub get_basic_credentials {
+      my($self, $realm, $uri, $proxy) = @_;
+      my $x =  $uri->rel($base);
+      if ($realm eq "libwww-perl" && $uri->rel($base) eq "basic") {
+	  return ("ok 12", "xyzzy");
+      } else {
+          return undef;
+      }
+   }
+}
+$req = new HTTP::Request GET => url("/basic", $base);
+$res = MyUA->new->request($req);
+#print $res->as_string;
+
+print "not " unless $res->is_success;
+print $res->content;
+
+# Let's try with a $ua that does not pass out credentials
+$res = $ua->request($req);
+print "not " unless $res->code == 401;
+print "ok 13\n";
+
+# Let's try to set credentials for this realm
+$ua->credentials($req->url->netloc, "libwww-perl", "ok 12", "xyzzy");
+$res = $ua->request($req);
+print "not " unless $res->is_success;
+print "ok 14\n";
+
+# Then illegal credentials
+$ua->credentials($req->url->netloc, "libwww-perl", "user", "passwd");
+$res = $ua->request($req);
+print "not " unless $res->code == 401;
+print "ok 15\n";
+
+
+#----------------------------------------------------------------
+print "Check proxy...\n";
+sub httpd_get_proxy
+{
+   my($c,$r) = @_;
+   if ($r->method eq "GET" and
+       $r->url->scheme eq "ftp") {
+       $c->send_basic_header(200);
+       $c->send_crlf;
+   } else {
+       $c->send_error;
+   }
+}
+
+$ua->proxy(ftp => $base);
+$req = new HTTP::Request GET => "ftp://ftp.perl.com/proxy";
+$res = $ua->request($req);
+#print $res->as_string;
+print "not " unless $res->is_success;
+print "ok 16\n";
+
+#----------------------------------------------------------------
+print "Check POSTing...\n";
+sub httpd_post_echo
+{
+   my($c,$r) = @_;
+   $c->send_basic_header;
+   $c->print("Content-Type: text/plain");
+   $c->send_crlf;
+   $c->send_crlf;
+   $c->print($r->as_string);
+}
+
+$req = new HTTP::Request POST => url("/echo/foo", $base);
+$req->content_type("application/x-www-form-urlencoded");
+$req->content("foo=bar&bar=test");
+$res = $ua->request($req);
+#print $res->as_string;
+
+$_ = $res->content;
+print "not " unless $res->is_success
+                and /^Content-Length:\s*16$/mi
+		and /^Content-Type:\s*application\/x-www-form-urlencoded$/mi
+		and /^foo=bar&bar=test/m;
+print "ok 17\n";		
+
+#----------------------------------------------------------------
+print "Terminating server...\n";
+sub httpd_get_quit
+{
+    my($c) = @_;
+    $c->send_error(503, "Bye, bye");
+    exit;  # terminate HTTP server
+}
+
+$req = new HTTP::Request GET => url("/quit", $base);
+$res = $ua->request($req);
+
+print "not " unless $res->code == 503 and $res->content =~ /Bye, bye/;
+print "ok 18\n";
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/local/protosub.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/local/protosub.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/local/protosub.t	(revision 20131)
@@ -0,0 +1,73 @@
+#!perl
+
+print "1..6\n";
+
+# This test tries to make a custom protocol implementation by
+# subclassing of LWP::Protocol.
+
+
+use LWP::UserAgent ();
+use LWP::Protocol ();
+
+LWP::Protocol::implementor(http => 'myhttp');
+
+$ua = LWP::UserAgent->new;
+$ua->proxy('ftp' => "http://www.sn.no/");
+
+$req = HTTP::Request->new(GET => 'ftp://foo/');
+$req->header(Cookie => "perl=cool");
+
+$res = $ua->request($req);
+
+print $res->as_string;
+
+print "not " unless $res->code == 200;
+print "ok 5\n";
+print "not " unless $res->content eq "Howdy\n";
+print "ok 6\n";
+exit;
+
+
+#----------------------------------
+package myhttp;
+
+BEGIN {
+   @ISA=qw(LWP::Protocol);
+}
+
+sub new
+{
+    my $class = shift;
+    print "CTOR: $class->new(@_)\n";
+    my($prot) = @_;
+    print "not " unless $prot eq "http";
+    print "ok 1\n";
+    my $self = $class->SUPER::new(@_);
+    for (keys %$self) {
+	print "$_: $self->{$_}\n";
+    }
+    $self;
+}
+
+sub request
+{
+    my $self = shift;
+    print "REQUEST: $self->request(",
+       join(",", (map defined($_)? $_ : "UNDEF", @_)), ")\n";
+
+    my($request, $proxy, $arg, $size, $timeout) = @_;
+    print $request->as_string;
+
+    print "not " unless $proxy eq "http://www.sn.no/";
+    print "ok 2\n";
+    print "not " unless $request->url eq "ftp://foo/";
+    print "ok 3\n";
+    print "not " unless $request->header("cookie") eq "perl=cool";
+    print "ok 4\n";
+
+    my $res = HTTP::Response->new(200 => "OK");
+    $res->content_type("text/plain");
+    $res->date(time);
+    $self->collect_once($arg, $res, "Howdy\n");
+    $res;
+}
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/moved
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/moved	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/moved	(revision 20131)
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+echo "Location: http://$SERVER_NAME:$SERVER_PORT/"
+echo
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/nph-slowdata
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/nph-slowdata	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/nph-slowdata	(revision 20131)
@@ -0,0 +1,26 @@
+#!/usr/local/bin/perl
+
+# This script outputs some data slowly. It can be used to check that
+# pipelined processing of response content really works.  We use syswrite
+# so that the script will notice when the connection is broken.
+
+out("HTTP/1.0 200 OK\r
+Content-Type: text/plain\r
+\r
+");
+
+for (1..5) {
+    out("The number is now $_\n");
+    sleep(1);
+}
+exit;
+
+
+sub out
+{
+    my $data = shift;
+    my $l = length $data;
+    if (syswrite(STDOUT, $data, $l) != $l) {
+	exit 1;
+    }
+}
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/slowread
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/slowread	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/slowread	(revision 20131)
@@ -0,0 +1,31 @@
+#!/usr/local/bin/perl
+
+# You might post large amount of data to this script.  It will read
+# it slowly.
+
+{ local($!) = 1; print "Content-Type: text/plain\n\n"; }
+
+$len = $ENV{CONTENT_LENGTH};
+
+unless ($len) {
+    system "env";
+    exit;
+}
+
+$size = 20;  # chunk size
+
+$content = '';
+$bytes = 0;
+
+sleep(1);
+while ($len > 0) {
+    $n = sysread(STDIN, $b, $size);
+    last if $n <= 0;
+    $len -= $n;
+    $bytes += $n;
+    $content .= $b;
+    sleep(1);
+}
+print "$bytes bytes read\n";
+
+	
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/test
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/test	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/test	(revision 20131)
@@ -0,0 +1,28 @@
+#!/usr/local/bin/perl
+
+$| = 1;
+print "Content-type: text/plain
+
+";
+
+if (@ARGV) {
+    print "ARGS: ";
+    print join(", ", map { $_ = qq{"$_"} } @ARGV);
+    print "\n\n";
+} else {
+    print "No command line arguments passed to script\n\n";
+}
+
+while (($key,$val) = each %ENV) {
+   print "$key=$val\n";
+}
+
+if ($ENV{CONTENT_LENGTH}) {
+    $len = $ENV{CONTENT_LENGTH};
+    while ($len) {
+	$n = sysread(STDIN, $content, $len, length $content);
+	last unless defined $n;
+	$len -= $n;
+    }
+    print "\nContent\n-------\n$content";
+}
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/timeout
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/timeout	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/cgi-bin/timeout	(revision 20131)
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+sleep 20;
+
+echo "Content-type: text/plain"
+echo
+echo "Test"
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/config.pl.dist
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/config.pl.dist	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/config.pl.dist	(revision 20131)
@@ -0,0 +1,10 @@
+package net;
+
+# Configure these for you local system
+$httpserver  = "localhost:80";
+$cgidir      = "/cgi-bin/lwp";
+
+# Used for proxy test
+$ftp_proxy = "http://localhost/";
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/http-get.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/http-get.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/http-get.t	(revision 20131)
@@ -0,0 +1,43 @@
+#!/usr/local/bin/perl -w
+#
+# Check GET via HTTP.
+#
+
+print "1..2\n";
+
+require "net/config.pl";
+require LWP::Protocol::http;
+require LWP::UserAgent;
+
+my $ua = new LWP::UserAgent;    # create a useragent to test
+
+$netloc = $net::httpserver;
+$script = $net::cgidir . "/test";
+
+$url = new URI::URL("http://$netloc$script?query");
+
+my $request = new HTTP::Request('GET', $url);
+
+print "GET $url\n\n";
+
+my $response = $ua->request($request, undef, undef);
+
+my $str = $response->as_string;
+
+print "$str\n";
+
+if ($response->is_success and $str =~ /^REQUEST_METHOD=GET$/m) {
+    print "ok 1\n";
+} else {
+    print "not ok 1\n";
+}
+
+if ($str =~ /^QUERY_STRING=query$/m) {
+    print "ok 2\n";
+} else {
+    print "not ok 2\n";
+}
+
+# avoid -w warning
+$dummy = $net::httpserver;
+$dummy = $net::cgidir;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/http-post.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/http-post.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/http-post.t	(revision 20131)
@@ -0,0 +1,44 @@
+#!/usr/local/bin/perl -w
+#
+# Check POST via HTTP.
+#
+
+print "1..2\n";
+
+require "net/config.pl";
+require LWP::Protocol::http;
+require LWP::UserAgent;
+
+$netloc = $net::httpserver;
+$script = $net::cgidir . "/test";
+
+my $ua = new LWP::UserAgent;    # create a useragent to test
+
+$url = new URI::URL("http://$netloc$script");
+
+my $form = 'searchtype=Substring';
+
+my $request = new HTTP::Request('POST', $url, undef, $form);
+$request->header('Content-Type', 'application/x-www-form-urlencoded');
+
+my $response = $ua->request($request, undef, undef);
+
+my $str = $response->as_string;
+
+print "$str\n";
+
+if ($response->is_success and $str =~ /^REQUEST_METHOD=POST$/m) {
+    print "ok 1\n";
+} else {
+    print "not ok 1\n";
+}
+
+if ($str =~ /^CONTENT_LENGTH=(\d+)$/m && $1 == length($form)) {
+    print "ok 2\n";
+} else {
+    print "not ok 2\n";
+}
+
+# avoid -w warning
+$dummy = $net::httpserver;
+$dummy = $net::cgidir;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/http-timeout.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/http-timeout.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/http-timeout.t	(revision 20131)
@@ -0,0 +1,41 @@
+#
+# Check timeouts via HTTP.
+#
+
+print "1..1\n";
+
+require "net/config.pl";
+require HTTP::Status;
+require LWP::Protocol::http;
+require LWP::UserAgent;
+
+my $ua = new LWP::UserAgent;    # create a useragent to test
+
+$ua->timeout(4);
+
+$netloc = $net::httpserver;
+$script = $net::cgidir . "/timeout";
+
+$url = new URI::URL("http://$netloc$script");
+
+my $request = new HTTP::Request('GET', $url);
+
+print $request->as_string;
+
+my $response = $ua->request($request, undef);
+
+my $str = $response->as_string;
+
+print "$str\n";
+
+if ($response->is_error and
+    $str =~ /timeout/) {
+    print "ok 1\n";
+}
+else {
+    print "nok ok 1\n";
+}
+
+# avoid -w warning
+$dummy = $net::httpserver;
+$dummy = $net::cgidir;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/mirror.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/mirror.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/mirror.t	(revision 20131)
@@ -0,0 +1,34 @@
+#
+# Test mirroring a file
+#
+
+require "net/config.pl";
+require LWP::Protocol::http;
+require LWP::UserAgent;
+require HTTP::Status;
+
+print "1..2\n";
+
+my $ua = new LWP::UserAgent;    # create a useragent to test
+
+my $url = "http://$net::httpserver/";
+my $copy = "lwp-test-$$"; # downloaded copy
+
+my $response = $ua->mirror($url, $copy);
+
+if ($response->code == &HTTP::Status::RC_OK) {
+    print "ok 1\n";
+} else {
+    print "not ok 1\n";
+}
+
+# OK, so now do it again, should get Not-Modified
+$response = $ua->mirror($url, $copy);
+if ($response->code == &HTTP::Status::RC_NOT_MODIFIED) {
+    print "ok 2\n";
+} else {
+    print "nok ok 2\n";
+}
+unlink($copy);
+
+$net::httpserver = $net::httpserver;  # avoid -w warning
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/moved.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/moved.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/moved.t	(revision 20131)
@@ -0,0 +1,34 @@
+#!/usr/local/bin/perl -w
+#
+
+print "1..1\n";
+
+require "net/config.pl";
+require LWP::Debug;
+require LWP::UserAgent;
+
+$url = "http://$net::httpserver$net::cgidir/moved";
+
+#LWP::Debug::level('+trace');
+
+my $ua = new LWP::UserAgent;    # create a useragent to test
+$ua->timeout(30);               # timeout in seconds
+
+my $request = new HTTP::Request('GET', $url);
+
+print $request->as_string;
+
+my $response = $ua->request($request, undef, undef);
+
+print $response->as_string, "\n";
+
+if ($response->is_success) {
+    print "ok 1\n";
+} else {
+    print "not ok 1\n";
+}
+
+
+# avoid -w warning
+$dummy = $net::httpserver;
+$dummy = $net::cgidir;
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/proxy.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/proxy.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/net/proxy.t	(revision 20131)
@@ -0,0 +1,36 @@
+#!/usr/local/bin/perl -w
+#
+# Test retrieving a file with a 'ftp://' URL,
+# via a HTTP proxy.
+#
+
+print "1..1\n";
+
+require "net/config.pl";
+unless (defined $net::ftp_proxy) {
+    print "not ok 1\n";
+    exit 0;
+}
+
+require LWP::Debug;
+require LWP::UserAgent;
+
+#LWP::Debug::level('+');
+
+my $ua = new LWP::UserAgent;    # create a useragent to test
+
+$ua->proxy('ftp', $net::ftp_proxy);
+
+my $url = new URI::URL('ftp://ftp.uninett.no/');
+
+my $request = new HTTP::Request('GET', $url);
+
+my $response = $ua->request($request, undef, undef);
+
+my $str = $response->as_string;
+
+if ($response->is_success) {
+    print "ok 1\n";
+} else {
+    print "not ok 1\n";
+}
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/robot/rules-dbm.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/robot/rules-dbm.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/robot/rules-dbm.t	(revision 20131)
@@ -0,0 +1,128 @@
+
+print "1..13\n";
+
+
+use WWW::RobotRules::AnyDBM_File;
+
+$file = "test-$$";
+
+$r = new WWW::RobotRules::AnyDBM_File "myrobot/2.0", $file;
+
+$r->parse("http://www.aas.no/robots.txt", "");
+
+$r->visit("www.aas.no");
+
+print "not " if $r->no_visits("www.aas.no") != 1;
+print "ok 1\n";
+
+
+$r->push_rules("www.sn.no", "/aas", "/per");
+$r->push_rules("www.sn.no", "/god", "/old");
+
+@r = $r->rules("www.sn.no");
+print "Rules: @r\n";
+
+print "not " if "@r" ne "/aas /per /god /old";
+print "ok 2\n";
+
+$r->clear_rules("per");
+$r->clear_rules("www.sn.no");
+
+@r = $r->rules("www.sn.no");
+print "Rules: @r\n";
+
+print "not " if "@r" ne "";
+print "ok 3\n";
+
+$r->visit("www.aas.no", time+10);
+$r->visit("www.sn.no");
+
+print "No visits: ", $r->no_visits("www.aas.no"), "\n";
+print "Last visit: ", $r->last_visit("www.aas.no"), "\n";
+print "Fresh until: ", $r->fresh_until("www.aas.no"), "\n";
+
+print "not " if $r->no_visits("www.aas.no") != 2;
+print "ok 4\n";
+
+print "not " if abs($r->last_visit("www.sn.no") - time) > 2;
+print "ok 5\n";
+
+$r = undef;
+
+# Try to reopen the database without a name specified
+$r = new WWW::RobotRules::AnyDBM_File undef, $file;
+$r->visit("www.aas.no");
+
+print "not " if $r->no_visits("www.aas.no") != 3;
+print "ok 6\n";
+
+print "Agent-Name: ", $r->agent, "\n";
+print "not " if $r->agent ne "myrobot";
+print "ok 7\n";
+
+$r = undef;
+
+print "*** Dump of database ***\n";
+tie(%cat, AnyDBM_File, $file, 0, 0644) or die "Can't tie: $!";
+while (($key,$val) = each(%cat)) {
+    print "$key\t$val\n";
+}
+print "******\n";
+
+untie %cat;
+
+# Try to open database with a different agent name
+$r = new WWW::RobotRules::AnyDBM_File "MOMSpider/2.0", $file;
+
+print "not " if $r->no_visits("www.sn.no");
+print "ok 8\n";
+
+# Try parsing
+$r->parse("http://www.sn.no:8080/robots.txt", <<EOT, (time + 3));
+
+User-Agent: *
+Disallow: /
+
+User-Agent: Momspider
+Disallow: /foo
+Disallow: /bar
+
+EOT
+
+@r = $r->rules("www.sn.no:8080");
+print "not " if "@r" ne "/foo /bar";
+print "ok 9\n";
+
+print "not " if $r->allowed("http://www.sn.no") >= 0;
+print "ok 10\n";
+
+print "not " if $r->allowed("http://www.sn.no:8080/foo/gisle");
+print "ok 11\n";
+
+sleep(5);  # wait until file has expired
+print "not " if $r->allowed("http://www.sn.no:8080/foo/gisle") >= 0;
+print "ok 12\n";
+
+
+$r = undef;
+
+print "*** Dump of database ***\n";
+tie(%cat, AnyDBM_File, $file, 0, 0644) or die "Can't tie: $!";
+while (($key,$val) = each(%cat)) {
+    print "$key\t$val\n";
+}
+print "******\n";
+
+untie %cat;			# Otherwise the next line fails on DOSish
+
+unlink "$file", "$file.pag", "$file.dir", "$file.db";
+
+# Try open a an emty database without specifying a name
+eval { 
+   $r = new WWW::RobotRules::AnyDBM_File undef, $file;
+};
+print $@;
+print "not " unless $@;  # should fail
+print "ok 13\n";
+
+unlink "$file", "$file.pag", "$file.dir", "$file.db";
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/robot/rules.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/robot/rules.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/robot/rules.t	(revision 20131)
@@ -0,0 +1,138 @@
+#!/local/bin/perl
+
+=head1 NAME
+
+robot-rules.t
+
+=head1 DESCRIPTION
+
+Test a number of different A</robots.txt> files against a number
+of different User-agents.
+
+=cut
+
+require WWW::RobotRules;
+use Carp;
+use strict;
+
+print "1..26\n"; # for Test::Harness
+
+# We test a number of different /robots.txt files,
+#
+
+my $content1 = <<EOM;
+# http://foo/robots.txt
+User-agent: *
+Disallow: /private
+Disallow: http://foo/also_private
+
+User-agent: MOMspider
+Disallow:
+EOM
+
+my $content2 = <<EOM;
+# http://foo/robots.txt
+User-agent: MOMspider
+ # comment which should be ignored
+Disallow: /private
+EOM
+
+my $content3 = <<EOM;
+# http://foo/robots.txt
+EOM
+
+my $content4 = <<EOM;
+# http://foo/robots.txt
+User-agent: *
+Disallow: /private
+
+User-agent: MOMspider
+Disallow: /this
+
+User-agent: Another
+Disallow: /that
+EOM
+
+# and a number of different robots:
+
+my @tests1 = (
+	   [$content1, 'MOMspider' =>
+	    1 => 'http://foo/private' => 1,
+	    2 => 'http://foo/also_private' => 1,
+	   ],
+
+	   [$content1, 'Wubble' =>
+	    3 => 'http://foo/private' => 0,
+	    4 => 'http://foo/also_private' => 0,
+	    5 => 'http://foo/other' => 1,
+	   ],
+
+	   [$content2, 'MOMspider' =>
+	    6 => 'http://foo/private' => 0,
+	    7 => 'http://foo/other' => 1,
+	   ],
+
+	   [$content2, 'Wubble' =>
+	    8  => 'http://foo/private' => 1,
+	    9  => 'http://foo/also_private' => 1,
+	    10 => 'http://foo/other' => 1,
+	   ],
+
+	   [$content3, 'MOMspider' =>
+	    11 => 'http://foo/private' => 1,
+	    12 => 'http://foo/other' => 1,
+	   ],
+
+	   [$content3, 'Wubble' =>
+	    13 => 'http://foo/private' => 1,
+	    14 => 'http://foo/other' => 1,
+	   ],
+
+	   [$content4, 'MOMspider' =>
+	    15 => 'http://foo/private' => 1,
+	    16 => 'http://foo/this' => 0,
+	    17 => 'http://foo/that' => 1,
+	   ],
+
+	   [$content4, 'Another' =>
+	    18 => 'http://foo/private' => 1,
+	    19 => 'http://foo/this' => 1,
+	    20 => 'http://foo/that' => 0,
+	   ],
+
+	   [$content4, 'Wubble' =>
+	    21 => 'http://foo/private' => 0,
+	    22 => 'http://foo/this' => 1,
+	    23 => 'http://foo/that' => 1,
+	   ],
+
+	   [$content4, 'Another/1.0' =>
+	    24 => 'http://foo/private' => 1,
+	    25 => 'http://foo/this' => 1,
+	    26 => 'http://foo/that' => 0,
+	   ],
+
+	   # when adding tests, remember to increase
+	   # the maximum at the top
+
+	  );
+
+my $t;
+
+for $t (@tests1) {
+    my ($content, $ua) = splice(@$t, 0, 2);
+
+    my $robotsrules = new WWW::RobotRules($ua);
+    $robotsrules->parse('http://foo/robots.txt', $content);
+
+    my ($num, $path, $expected);
+    while(($num, $path, $expected) = splice(@$t, 0, 3)) {
+	my $allowed = $robotsrules->allowed($path);
+	$allowed = 1 if $allowed;
+	if($allowed != $expected) {
+	    $robotsrules->dump;
+	    confess "Test Failed: $ua => $path ($allowed != $expected)";
+	}
+	print "ok $num\n";
+    }
+}
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/robot/ua.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/robot/ua.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/robot/ua.t	(revision 20131)
@@ -0,0 +1,135 @@
+$| = 1; # autoflush
+
+require IO::Socket;  # make sure this work before we try to make a HTTP::Daemon
+
+# First we make ourself a daemon in another process
+my $D = shift || '';
+if ($D eq 'daemon') {
+
+    require HTTP::Daemon;
+
+    my $d = new HTTP::Daemon Timeout => 10;
+
+    print "Please to meet you at: <URL:", $d->url, ">\n";
+    open(STDOUT, $^O eq 'MSWin32' ? ">nul" : ">/dev/null");
+
+    while ($c = $d->accept) {
+	$r = $c->get_request;
+	if ($r) {
+	    my $p = ($r->url->path_components)[1];
+	    $p =~ s/\W//g;
+	    my $func = lc("httpd_" . $r->method . "_$p");
+	    #print STDERR "Calling $func...\n";
+            if (defined &$func) {
+		&$func($c, $r);
+	    } else {
+		$c->send_error(404);
+	    }
+	}
+	$c = undef;  # close connection
+    }
+    print STDERR "HTTP Server terminated\n";
+    exit;
+}
+else {
+    use Config;
+    open(DAEMON , "$Config{'perlpath'} robot/ua.t daemon |") or die "Can't exec daemon: $!";
+}
+
+print "1..7\n";
+
+
+$greating = <DAEMON>;
+$greating =~ /(<[^>]+>)/;
+
+require URI::URL;
+URI::URL->import;
+my $base = new URI::URL $1;
+
+print "Will access HTTP server at $base\n";
+
+require LWP::RobotUA;
+require HTTP::Request;
+$ua = new LWP::RobotUA 'lwp-spider/0.1', 'gisle@aas.no';
+$ua->delay(0.05);  # rather quick robot
+
+#----------------------------------------------------------------
+sub httpd_get_robotstxt
+{
+   my($c,$r) = @_;
+   $c->send_basic_header;
+   $c->print("Content-Type: text/plain");
+   $c->send_crlf;
+   $c->send_crlf;
+   $c->print("User-Agent: *
+Disallow: /private
+
+");
+}
+
+sub httpd_get_someplace
+{
+   my($c,$r) = @_;
+   $c->send_basic_header;
+   $c->print("Content-Type: text/plain");
+   $c->send_crlf;
+   $c->send_crlf;
+   $c->print("Okidok\n");
+}
+
+$req = new HTTP::Request GET => url("/someplace", $base);
+$res = $ua->request($req);
+#print $res->as_string;
+print "not " unless $res->is_success;
+print "ok 1\n";
+
+$req = new HTTP::Request GET => url("/private/place", $base);
+$res = $ua->request($req);
+#print $res->as_string;
+print "not " unless $res->code == 403
+                and $res->message =~ /robots.txt/;
+print "ok 2\n";
+
+$req = new HTTP::Request GET => url("/foo", $base);
+$res = $ua->request($req);
+#print $res->as_string;
+print "not " unless $res->code == 404;  # not found
+print "ok 3\n";
+
+# Let the robotua generate "Service unavailable/Retry After response";
+$ua->delay(1);
+$ua->use_sleep(0);
+$req = new HTTP::Request GET => url("/foo", $base);
+$res = $ua->request($req);
+#print $res->as_string;
+print "not " unless $res->code == 503   # Unavailable
+                and $res->header("Retry-After");
+print "ok 4\n";
+
+#----------------------------------------------------------------
+print "Terminating server...\n";
+sub httpd_get_quit
+{
+    my($c) = @_;
+    $c->send_error(503, "Bye, bye");
+    exit;  # terminate HTTP server
+}
+
+$ua->delay(0);
+$req = new HTTP::Request GET => url("/quit", $base);
+$res = $ua->request($req);
+
+print "not " unless $res->code == 503 and $res->content =~ /Bye, bye/;
+print "ok 5\n";
+
+#---------------------------------------------------------------
+$ua->delay(1);
+
+# host_wait() should be around 60s now
+print "not " unless abs($ua->host_wait($base->netloc) - 60) < 5;
+print "ok 6\n";
+
+# Number of visits to this place should be 
+print "not " unless $ua->no_visits($base->netloc) == 4;
+print "ok 7\n";
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/uri/abs-config.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/uri/abs-config.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/uri/abs-config.t	(revision 20131)
@@ -0,0 +1,35 @@
+print "1..6\n";
+
+use URI::URL qw(url);
+
+# Test configuration via some global variables.
+
+$URI::URL::ABS_REMOTE_LEADING_DOTS = 1;
+$URI::URL::ABS_ALLOW_RELATIVE_SCHEME = 1;
+
+$u1 = url("../../../../abc", "http://web/a/b");
+
+print "not " unless $u1->abs->as_string eq "http://web/abc";
+print "ok 1\n";
+
+{
+    local $URI::URL::ABS_REMOTE_LEADING_DOTS;
+    print "not " unless $u1->abs->as_string eq "http://web/../../../abc";
+    print "ok 2\n";
+}
+
+
+$u1 = url("http:../../../../abc", "http://web/a/b");
+print "not " unless $u1->abs->as_string eq "http://web/abc";
+print "ok 3\n";
+
+{
+   local $URI::URL::ABS_ALLOW_RELATIVE_SCHEME;
+   print "not " unless $u1->abs->as_string eq "http:../../../../abc";
+   print "ok 4\n";
+   print "not " unless $u1->abs(undef,1)->as_string eq "http://web/abc";
+   print "ok 5\n";
+}
+
+print "not " unless $u1->abs(undef,0)->as_string eq "http:../../../../abc";
+print "ok 6\n";
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/uri/base.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/uri/base.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/uri/base.t	(revision 20131)
@@ -0,0 +1,955 @@
+#!/local/bin/perl -w
+
+use URI::URL qw(url);
+use URI::Escape qw(uri_escape uri_unescape);
+
+use Carp;
+
+# _expect()
+#
+# Handy low-level object method tester which we insert as a method
+# in the URI::URL class
+#
+sub URI::URL::_expect {
+    my($self, $method, $expect, @args) = @_;
+    my $result = $self->$method(@args);
+    $expect = 'UNDEF' unless defined $expect;
+    $result = 'UNDEF' unless defined $result;
+    return 1 if $expect eq $result;
+    warn "'$self'->$method(@args) = '$result' " .
+		"(expected '$expect')\n";
+    $self->print_on('STDERR');
+    confess "Test Failed";
+}
+
+package main;
+
+# Must ensure that there is no relative paths in @INC because we will
+# chdir in the newlocal tests.
+chomp($pwd = ($^O =~ /mswin32/i ? `cd` : `pwd`));
+for (@INC) {
+    next if m|^/| or $^O =~ /os2|mswin32/i and m|^\w:[\\/]|;
+    print "Turn lib path $_ into $pwd/$_\n";
+    $_ = "$pwd/$_";
+
+}
+
+$| = 1;
+
+print "1..8\n";  # for Test::Harness
+
+# Do basic tests first.
+# Dies if an error has been detected, prints "ok" otherwise.
+
+print "Self tests for URI::URL version $URI::URL::VERSION...\n";
+
+scheme_parse_test();
+print "ok 1\n";
+
+parts_test();
+print "ok 2\n";
+
+escape_test();
+print "ok 3\n";
+
+newlocal_test();
+print "ok 4\n";
+
+absolute_test();
+print "ok 5\n";
+
+eq_test();
+print "ok 6\n";
+
+# Let's test makeing our own things
+URI::URL::strict(0);
+# This should work after URI::URL::strict(0)
+$url = new URI::URL "x-myscheme:something";
+# Since no implementor is registered for 'x-myscheme' then it will
+# be handeled by the URI::URL::_generic class
+$url->_expect('as_string' => 'x-myscheme:something');
+$url->_expect('path' => 'something');
+URI::URL::strict(1);
+
+# Let's try to make our URL subclass
+{
+    package MyURL;
+    @ISA = URI::URL::implementor();
+
+    sub _parse {
+	my($self, $init) = @_;
+	$self->URI::URL::_generic::_parse($init, qw(netloc path));
+    }
+
+    sub foo {
+	my $self = shift;
+	print ref($self)."->foo called for $self\n";
+    }
+}
+# Let's say that it implements the 'x-a+b.c' scheme (alias 'x-foo')
+URI::URL::implementor('x-a+b.c', 'MyURL');
+URI::URL::implementor('x-foo', 'MyURL');
+
+# Now we are ready to try our new URL scheme
+$url = new URI::URL 'x-a+b.c://foo/bar;a?b';
+$url->_expect('as_string', 'x-a+b.c://foo/bar;a?b');
+$url->_expect('path', '/bar;a?b');
+$url->foo;
+$newurl = new URI::URL 'xxx', $url;
+$newurl->foo;
+$url = new URI::URL 'yyy', 'x-foo:';
+$url->foo;
+
+print "ok 7\n";
+
+# Test the new wash&go constructor
+print "not " if url("../foo.html", "http://www.sn.no/a/b")->abs->as_string
+		ne 'http://www.sn.no/foo.html';
+print "ok 8\n";
+
+print "URI::URL version $URI::URL::VERSION ok\n";
+
+exit 0;
+
+
+
+
+#####################################################################
+#
+# scheme_parse_test()
+#
+# test parsing and retrieval methods
+
+sub scheme_parse_test {
+
+    print "scheme_parse_test:\n";
+
+    $tests = {
+	'hTTp://web1.net/a/b/c/welcome#intro'
+	=> {    'scheme'=>'http', 'host'=>'web1.net', 'port'=>80,
+		'path'=>'/a/b/c/welcome', 'frag'=>'intro','query'=>undef,
+		'epath'=>'/a/b/c/welcome', 'equery'=>undef,
+		'params'=>undef, 'eparams'=>undef,
+		'as_string'=>'http://web1.net/a/b/c/welcome#intro',
+		'full_path' => '/a/b/c/welcome' },
+
+	'http://web:1/a?query+text'
+	=> {    'scheme'=>'http', 'host'=>'web', 'port'=>1,
+		'path'=>'/a', 'frag'=>undef, 'query'=>'query+text' },
+
+	'http://web.net/'
+	=> {    'scheme'=>'http', 'host'=>'web.net', 'port'=>80,
+		'path'=>'/', 'frag'=>undef, 'query'=>undef,
+		'full_path' => '/',
+		'as_string' => 'http://web.net/' },
+
+	'http://web.net'
+	=> {    'scheme'=>'http', 'host'=>'web.net', 'port'=>80,
+		'path'=>'/', 'frag'=>undef, 'query'=>undef,
+		'full_path' => '/',
+		'as_string' => 'http://web.net/' },
+
+	'http:0'
+	 => {   'scheme'=>'http', 'path'=>'0', 'query'=>undef,
+		'as_string'=>'http:0', 'full_path'=>'0', },
+
+	'http:/0?0'
+	 => {   'scheme'=>'http', 'path'=>'/0', 'query'=>'0',
+		'as_string'=>'http:/0?0', 'full_path'=>'/0?0', },
+
+	'http://0:0/0/0;0?0#0'
+	 => {   'scheme'=>'http', 'host'=>'0', 'port'=>'0',
+		'path' => '/0/0', 'query'=>'0', 'params'=>'0',
+		'netloc'=>'0:0',
+		'frag'=>0, 'as_string'=>'http://0:0/0/0;0?0#0' },
+
+	'ftp://0%3A:%40@h:0/0?0'
+	=>  {   'scheme'=>'ftp', 'user'=>'0:', 'password'=>'@',
+		'host'=>'h', 'port'=>'0', 'path'=>'/0?0',
+		'query'=>undef, params=>undef,
+		'netloc'=>'0%3A:%40@h:0',
+		'as_string'=>'ftp://0%3A:%40@h:0/0?0' },
+
+	'ftp://usr:pswd@web:1234/a/b;type=i'
+	=> {    'host'=>'web', 'port'=>1234, 'path'=>'/a/b',
+		'user'=>'usr', 'password'=>'pswd',
+		'params'=>'type=i',
+		'as_string'=>'ftp://usr:pswd@web:1234/a/b;type=i' },
+
+	'ftp://host/a/b'
+	=> {    'host'=>'host', 'port'=>21, 'path'=>'/a/b',
+		'user'=>'anonymous',
+		'as_string'=>'ftp://host/a/b' },
+
+	'file://host/fseg/fs?g/fseg'
+	# don't escape ? for file: scheme
+	=> {    'host'=>'host', 'path'=>'/fseg/fs?g/fseg',
+		'as_string'=>'file://host/fseg/fs?g/fseg' },
+
+	'gopher://host'
+	=> {     'gtype'=>'1', 'as_string' => 'gopher://host/', },
+
+	'gopher://host/'
+	=> {     'gtype'=>'1', 'as_string' => 'gopher://host/', },
+
+	'gopher://gopher/2a_selector'
+	=> {    'gtype'=>'2', 'selector'=>'a_selector',
+		'as_string' => 'gopher://gopher/2a_selector', },
+
+	'mailto:libwww-perl@ics.uci.edu'
+	=> {    'address'       => 'libwww-perl@ics.uci.edu',
+		'encoded822addr'=> 'libwww-perl@ics.uci.edu',
+		'user'          => 'libwww-perl',
+		'host'          => 'ics.uci.edu',
+		'as_string'     => 'mailto:libwww-perl@ics.uci.edu', },
+
+	'news:*'
+	=> {    'groupart'=>'*', 'group'=>'*', as_string=>'news:*' },
+	'news:comp.lang.perl'
+	=> {    'group'=>'comp.lang.perl' },
+	'news:perl-faq/module-list-1-794455075@ig.co.uk'
+	=> {    'article'=>
+		    'perl-faq/module-list-1-794455075@ig.co.uk' },
+
+	'nntp://news.com/comp.lang.perl/42'
+	=> {    'group'=>'comp.lang.perl', 'digits'=>42 },
+
+	'telnet://usr:pswd@web:12345/'
+	=> {    'user'=>'usr', 'password'=>'pswd', 'host'=>'web' },
+	'rlogin://aas@a.sn.no'
+	=> {    'user'=>'aas', 'host'=>'a.sn.no' },
+	'tn3270://aas@ibm'
+	=> {    'user'=>'aas', 'host'=>'ibm',
+		'as_string'=>'tn3270://aas@ibm/'},
+
+	'wais://web.net/db'
+	=> { 'database'=>'db' },
+	'wais://web.net/db?query'
+	=> { 'database'=>'db', 'query'=>'query' },
+	'wais://usr:pswd@web.net/db/wt/wp'
+	=> {    'database'=>'db', 'wtype'=>'wt', 'wpath'=>'wp',
+		'password'=>'pswd' },
+    };
+
+    foreach $url_str (sort keys %$tests ){
+	print "Testing '$url_str'\n";
+	my $url = new URI::URL $url_str;
+	my $tests = $tests->{$url_str};
+	while( ($method, $exp) = each %$tests ){
+	    $exp = 'UNDEF' unless defined $exp;
+	    $url->_expect($method, $exp);
+	}
+    }
+}
+
+
+#####################################################################
+#
+# parts_test()          (calls netloc_test test)
+#
+# Test individual component part access functions
+#
+sub parts_test {
+    print "parts_test:\n";
+
+    # test storage part access/edit methods (netloc, user, password,
+    # host and port are tested by &netloc_test)
+
+    $url = new URI::URL 'file://web/orig/path';
+    $url->scheme('http');
+    $url->path('1info');
+    $url->query('key words');
+    $url->frag('this');
+    $url->_expect('as_string' => 'http://web/1info?key%20words#this');
+
+    $url->epath('%2f/%2f');
+    $url->equery('a=%26');
+    $url->_expect('full_path' => '/%2f/%2f?a=%26');
+
+    # At this point it should be impossible to access the members path()
+    # and query() without complaints.
+    eval { my $p = $url->path; print "Path is $p\n"; };
+    die "Path exception failed" unless $@;
+    eval { my $p = $url->query; print "Query is $p\n"; };
+    die "Query exception failed" unless $@;
+
+    # but we should still be able to set it 
+    $url->path("howdy");
+    $url->_expect('as_string' => 'http://web/howdy?a=%26#this');
+
+    # Test the path_components function
+    $url = new URI::URL 'file:%2f/%2f';
+    my $p;
+    $p = join('-', $url->path_components);
+    die "\$url->path_components returns '$p', expected '/-/'"
+      unless $p eq "/-/";
+    $url->host("localhost");
+    $p = join('-', $url->path_components);
+    die "\$url->path_components returns '$p', expected '-/-/'"
+      unless $p eq "-/-/";
+    $url->epath("/foo/bar/");
+    $p = join('-', $url->path_components);
+    die "\$url->path_components returns '$p', expected '-foo-bar-'"
+      unless $p eq "-foo-bar-";
+    $url->path_components("", "/etc", "\0", "..", "øse", "");
+    $url->_expect('full_path' => '/%2Fetc/%00/../%F8se/');
+
+    # Setting undef
+    $url = new URI::URL 'http://web/p;p?q#f';
+    $url->epath(undef);
+    $url->equery(undef);
+    $url->eparams(undef);
+    $url->frag(undef);
+    $url->_expect('as_string' => 'http://web/');
+
+    # Test http query access methods
+    $url->keywords('dog');
+    $url->_expect('as_string' => 'http://web/?dog');
+    $url->keywords(qw(dog bones));
+    $url->_expect('as_string' => 'http://web/?dog+bones');
+    $url->keywords(0,0);
+    $url->_expect('as_string' => 'http://web/?0+0');
+    $url->keywords('dog', 'bones', '#+=');
+    $url->_expect('as_string' => 'http://web/?dog+bones+%23%2B%3D');
+    $a = join(":", $url->keywords);
+    die "\$url->keywords did not work (returned '$a')" unless $a eq 'dog:bones:#+=';
+    # calling query_form is an error
+    eval { my $foo = $url->query_form; };
+    die "\$url->query_form should croak since query contains keywords not a form."
+      unless $@;
+
+    $url->query_form(a => 'foo', b => 'bar');
+    $url->_expect('as_string' => 'http://web/?a=foo&b=bar');
+    my %a = $url->query_form;
+    die "\$url->query_form did not work"
+      unless $a{a} eq 'foo' && $a{b} eq 'bar';
+
+    $url->query_form(a => undef, a => 'foo', '&=' => '&=+');
+    $url->_expect('as_string' => 'http://web/?a=&a=foo&%26%3D=%26%3D%2B');
+
+    my @a = $url->query_form;
+    die "Wrong length" unless @a == 6;
+    die "Bad keys from query_form"
+      unless $a[0] eq 'a' && $a[2] eq 'a' && $a[4] eq '&=';
+    die "Bad values from query_form"
+      unless $a[1] eq '' && $a[3] eq 'foo' && $a[5] eq '&=+';
+
+    # calling keywords is an error
+    eval { my $foo = $url->keywords; };
+    die "\$url->keywords should croak when query is a form"
+      unless $@;
+    # Try this odd one
+    $url->equery('&=&=b&a=&a&a=b=c&&a=b');
+    @a = $url->query_form;
+    #print join(":", @a), "\n";
+    die "Wrong length" unless @a == 16;
+    die "Wrong sequence" unless $a[4]  eq ""  && $a[5]  eq "b" &&
+                                $a[10] eq "a" && $a[11] eq "b=c";
+
+    # Try array ref values in the key value pairs
+    $url->query_form(a => ['foo', 'bar'], b => 'foo', c => ['bar', 'foo']);
+    $url->_expect('as_string', 'http://web/?a=foo&a=bar&b=foo&c=bar&c=foo');
+
+
+    netloc_test();
+    port_test();
+
+    $url->query(undef);
+    $url->_expect('query', undef);
+
+    $url = new URI::URL 'gopher://gopher/';
+    $url->port(33);
+    $url->gtype("3");
+    $url->selector("S");
+    $url->search("query");
+    $url->_expect('as_string', 'gopher://gopher:33/3S%09query');
+
+    $url->epath("45%09a");
+    $url->_expect('gtype' => '4');
+    $url->_expect('selector' => '5');
+    $url->_expect('search' => 'a');
+    $url->_expect('string' => undef);
+    $url->_expect('path' => "/45\ta");
+    $url->path("00\t%09gisle");
+    $url->_expect('search', '%09gisle');
+
+    # Let's test som other URL schemes
+    $url = new URI::URL 'news:';
+    $url->group("comp.lang.perl.misc");
+    $url->_expect('as_string' => 'news:comp.lang.perl.misc');
+    $url->article('<1234@a.sn.no>');
+    $url->_expect('as_string' => 'news:1234@a.sn.no'); # "<" and ">" are gone
+    # This one should be illegal
+    eval { $url->article("no.perl"); };
+    die "This one should really complain" unless $@;
+
+    $url = new URI::URL 'mailto:';
+    $url->user("aas");
+    $url->host("a.sn.no");
+    $url->_expect("as_string" => 'mailto:aas@a.sn.no');
+    $url->address('foo@bar');
+    $url->_expect("host" => 'bar');
+    $url->_expect("user" => 'foo');
+
+    $url = new URI::URL 'wais://host/database/wt/wpath';
+    $url->database('foo');
+    $url->_expect('as_string' => 'wais://host/foo/wt/wpath');
+    $url->wtype('bar');
+    $url->_expect('as_string' => 'wais://host/foo/bar/wpath');
+
+    # Test crack method for various URLs
+    my(@crack, $crack);
+    @crack = URI::URL->new("http://host/path;param?query#frag")->crack;
+    die "Cracked result should be 9 elements" unless @crack == 9;
+    $crack = join("*", map { defined($_) ? $_ : "UNDEF" } @crack);
+    print "Cracked result: $crack\n";
+    die "Bad crack result" unless
+      $crack eq "http*UNDEF*UNDEF*host*80*/path*param*query*frag";
+
+    @crack = URI::URL->new("foo/bar", "ftp://aas\@ftp.sn.no/")->crack;
+    die "Cracked result should be 9 elements" unless @crack == 9;
+    $crack = join("*", map { defined($_) ? $_ : "UNDEF" } @crack);
+    print "Cracked result: $crack\n";
+    die "Bad crack result" unless
+      $crack eq "ftp*UNDEF*UNDEF*UNDEF*21*foo/bar*UNDEF*UNDEF*UNDEF";
+
+    @crack = URI::URL->new('ftp://u:p@host/q?path')->crack;
+    die "Cracked result should be 9 elements" unless @crack == 9;
+    $crack = join("*", map { defined($_) ? $_ : "UNDEF" } @crack);
+    print "Cracked result: $crack\n";
+    die "Bad crack result" unless
+      $crack eq "ftp*u*p*host*21*/q?path*UNDEF*UNDEF*UNDEF";
+
+    @crack = URI::URL->new("ftp://ftp.sn.no/pub")->crack;    # Test anon ftp
+    die "Cracked result should be 9 elements" unless @crack == 9;
+    die "No passwd in anonymous crack" unless $crack[2];
+    $crack[2] = 'passwd';  # easier to test when we know what it is
+    $crack = join("*", map { defined($_) ? $_ : "UNDEF" } @crack);
+    print "Cracked result: $crack\n";
+    die "Bad crack result" unless
+      $crack eq "ftp*anonymous*passwd*ftp.sn.no*21*/pub*UNDEF*UNDEF*UNDEF";
+
+    @crack = URI::URL->new('mailto:aas@sn.no')->crack;
+    die "Cracked result should be 9 elements" unless @crack == 9;
+    $crack = join("*", map { defined($_) ? $_ : "UNDEF" } @crack);
+    print "Cracked result: $crack\n";
+    die "Bad crack result" unless
+      $crack eq "mailto*aas*UNDEF*sn.no*UNDEF*aas\@sn.no*UNDEF*UNDEF*UNDEF";
+
+    @crack = URI::URL->new('news:comp.lang.perl.misc')->crack;
+    die "Cracked result should be 9 elements" unless @crack == 9;
+    $crack = join("*", map { defined($_) ? $_ : "UNDEF" } @crack);
+    print "Cracked result: $crack\n";
+    die "Bad crack result" unless
+      $crack eq "news*UNDEF*UNDEF*UNDEF*UNDEF*comp.lang.perl.misc*UNDEF*UNDEF*UNDEF";
+}
+
+#
+# netloc_test()
+#
+# Test automatic netloc synchronisation
+#
+sub netloc_test {
+    print "netloc_test:\n";
+
+    my $url = new URI::URL 'ftp://anonymous:p%61ss@håst:12345';
+    $url->_expect('user', 'anonymous');
+    $url->_expect('password', 'pass');
+    $url->_expect('host', 'håst');
+    $url->_expect('port', 12345);
+    # Can't really know how netloc is represented since it is partially escaped
+    #$url->_expect('netloc', 'anonymous:pass@hst:12345');
+    $url->_expect('as_string' => 'ftp://anonymous:p%61ss@h%E5st:12345/');
+
+    # The '0' is sometimes tricky to get right
+    $url->user(0);
+    $url->password(0);
+    $url->host(0);
+    $url->port(0);
+    $url->_expect('netloc' => '0:0@0:0');
+    $url->host(undef);
+    $url->_expect('netloc' => '');
+    $url->host('h');
+    $url->user(undef);
+    $url->_expect('netloc' => 'h:0');
+    $url->user('');
+    $url->_expect('netloc' => ':0@h:0');
+    $url->password('');
+    $url->_expect('netloc' => ':@h:0');
+    $url->user('foo');
+    $url->_expect('netloc' => 'foo:@h:0');
+
+    # Let's try a simple one
+    $url->user('nemo');
+    $url->password('p2');
+    $url->host('hst2');
+    $url->port(2);
+    $url->_expect('netloc' => 'nemo:p2@hst2:2');
+
+    $url->user(undef);
+    $url->password(undef);
+    $url->port(undef);
+    $url->_expect('netloc' => 'hst2');
+    $url->_expect('port' => '21');  # the default ftp port
+
+    $url->port(21);
+    $url->_expect('netloc' => 'hst2');
+
+    # Let's try some reserved chars
+    $url->user("@");
+    $url->password(":-#-;-/-?");
+    $url->_expect('as_string' => 'ftp://%40:%3A-%23-%3B-%2F-%3F@hst2/');
+
+}
+
+#
+# port_test()
+#
+# Test port behaviour
+#
+sub port_test {
+    print "port_test:\n";
+
+    $url = URI::URL->new('http://foo/root/dir/');
+    my $port = $url->port;
+    die "Port undefined" unless defined $port;
+    die "Wrong port $port" unless $port == 80;
+    die "Wrong string" unless $url->as_string eq
+	'http://foo/root/dir/';
+
+    $url->port(8001);
+    $port = $url->port;
+    die "Port undefined" unless defined $port;
+    die "Wrong port $port" unless $port == 8001;
+    die "Wrong string" unless $url->as_string eq
+	'http://foo:8001/root/dir/';
+
+    $url->port(80);
+    $port = $url->port;
+    die "Port undefined" unless defined $port;
+    die "Wrong port $port" unless $port == 80;
+    die "Wrong string" unless $url->as_string eq
+	'http://foo/root/dir/';
+
+    $url->port(8001);
+    $url->port(undef);
+    $port = $url->port;
+    die "Port undefined" unless defined $port;
+    die "Wrong port $port" unless $port == 80;
+    die "Wrong string" unless $url->as_string eq
+	'http://foo/root/dir/';
+}
+
+
+#####################################################################
+#
+# escape_test()
+#
+# escaping functions
+
+sub escape_test {
+    print "escape_test:\n";
+
+    # supply escaped URL
+    $url = new URI::URL 'http://web/this%20has%20spaces';
+    # check component is unescaped
+    $url->_expect('path', '/this has spaces');
+
+    # modify the unescaped form
+    $url->path('this ALSO has spaces');
+    # check whole url is escaped
+    $url->_expect('as_string',
+		  'http://web/this%20ALSO%20has%20spaces');
+
+    $url = new URI::URL uri_escape('http://web/try %?#" those');
+    $url->_expect('as_string',
+		  'http://web/try%20%25%3F%23%22%20those');
+
+    my $all = pack('c*',0..255);
+    my $esc = uri_escape($all);
+    my $new = uri_unescape($esc);
+    die "uri_escape->uri_unescape mismatch" unless $all eq $new;
+    $url->path($all);
+    $url->_expect('full_path' => '/%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20!%22%23$%25%26\'()*%2B,-./0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF');
+
+    # test escaping uses uppercase (preferred by rfc1837)
+    $url = new URI::URL 'file://h/';
+    $url->path(chr(0x7F));
+    $url->_expect('as_string', 'file://h/%7F');
+
+    # reserved characters differ per scheme
+
+    ## XXX is this '?' allowed to be unescaped
+    $url = new URI::URL 'file://h/test?ing';
+    $url->_expect('path', '/test?ing');
+
+    $url = new URI::URL 'file://h/';
+    $url->epath('question?mark');
+    $url->_expect('as_string', 'file://h/question?mark');
+    # XXX Why should this be any different???
+    #     Perhaps we should not expect too much :-)
+    $url->path('question?mark');
+    $url->_expect('as_string', 'file://h/question%3Fmark');
+
+    # See what happens when set different elements to this ugly sting
+    my $reserved = ';/?:@&=#%';
+    $url->path($reserved . "foo");
+    $url->_expect('as_string', 'file://h/%3B/%3F%3A%40%26%3D%23%25foo');
+
+    $url->scheme('http');
+    $url->path('');
+    $url->_expect('as_string', 'http://h/');
+    $url->query($reserved);
+    $url->params($reserved);
+    $url->frag($reserved);
+    $url->_expect('as_string', 'http://h/;%3B%2F%3F%3A%40&=%23%25?%3B%2F%3F%3A%40&=%23%25#;/?:@&=#%');
+
+    $str = $url->as_string;
+    $url = new URI::URL $str;
+    die "URL changed" if $str ne $url->as_string;
+
+    $url = new URI::URL 'ftp:foo';
+    $url->user($reserved);
+    $url->host($reserved);
+    $url->_expect('as_string', 'ftp://%3B%2F%3F%3A%40%26%3D%23%25@%3B%2F%3F%3A%40%26%3D%23%25/foo');
+
+}
+
+
+#####################################################################
+#
+# newlocal_test()
+#
+
+sub newlocal_test {
+    print "newlocal_test:\n";
+    my $pwd = ($^O eq 'MSWin32' ? 'cd' : (-e '/bin/pwd' ? '/bin/pwd' : 'pwd'));
+    my $tmpdir = ($^O eq 'MSWin32' ? $ENV{TEMP} : '/tmp');
+    $tmpdir =~ tr|\\|/|;
+
+    my $savedir = `$pwd`;     # we don't use Cwd.pm because we want to check
+			      # that it get require'd corretly by URL.pm
+    chomp $savedir;
+
+    # cwd
+    chdir($tmpdir) or die $!;
+    my $dir = `$pwd`; $dir =~ tr|\\|/|;
+    chomp $dir; $dir = uri_escape($dir, ':');
+    $url = newlocal URI::URL;
+    $url->_expect('as_string', URI::URL->new("file:$dir/")->as_string);
+
+    print "Local directory is ". $url->local_path . "\n";
+
+    # absolute dir
+    chdir('/') or die $!;
+    $url = newlocal URI::URL '/usr/';
+    $url->_expect('as_string', 'file:/usr/');
+
+    # absolute file
+    $url = newlocal URI::URL '/vmunix';
+    $url->_expect('as_string', 'file:/vmunix');
+
+    # relative file
+    chdir($tmpdir) or die $!;
+    $dir = `$pwd`; $dir =~ tr|\\|/|;
+    chomp $dir; $dir = uri_escape($dir, ':');
+    $url = newlocal URI::URL 'foo';
+    $url->_expect('as_string', "file:$dir/foo");
+
+    # relative dir
+    chdir($tmpdir) or die $!;
+    $dir = `$pwd`; $dir =~ tr|\\|/|;
+    chomp $dir; $dir = uri_escape($dir, ':');
+    $url = newlocal URI::URL 'bar/';
+    $url->_expect('as_string', "file:$dir/bar/");
+
+    # 0
+    chdir('/') or die $!;
+    $dir = `$pwd`; $dir =~ tr|\\|/|;
+    chomp $dir; $dir = uri_escape($dir, ':');
+    $url = newlocal URI::URL '0';
+    $url->_expect('as_string', "file:${dir}0");
+
+    # Test access methods for file URLs
+    $url = new URI::URL 'file:/c:/dos';
+    $url->_expect('dos_path', 'C:\\DOS');
+    $url->_expect('unix_path', '/c:/dos');
+    $url->_expect('vms_path', '[C:]DOS');
+    eval { $url->mac_path; };  # This is not allowed since we have ':' in path
+    die "Mac_path generated when it should fail." unless $@;
+    $url = new URI::URL 'file:/foo/bar';
+    $url->_expect('unix_path', '/foo/bar');
+    $url->_expect('mac_path', 'foo:bar');
+
+    # Some edge cases
+    $url = new URI::URL 'file:';
+    $url->_expect('unix_path', '/');
+    $url = new URI::URL 'file:/';
+    $url->_expect('unix_path', '/');
+    $url = new URI::URL 'file:.';
+    $url->_expect('unix_path', '.');
+    $url = new URI::URL 'file:./foo';
+    $url->_expect('unix_path', 'foo');
+    $url = new URI::URL 'file:0';
+    $url->_expect('unix_path', '0');
+    $url = new URI::URL 'file:../../foo';
+    $url->_expect('unix_path', '../../foo');
+    $url = new URI::URL 'file:foo/../bar';
+    $url->_expect('unix_path', 'bar');
+
+    # Relative files
+    $url = new URI::URL 'file:foo/b%61r/Note.txt';
+    $url->_expect('unix_path', 'foo/bar/Note.txt');
+    $url->_expect('mac_path', ':foo:bar:Note.txt');
+    $url->_expect('dos_path', 'FOO\\BAR\\NOTE.TXT');
+    $url->_expect('vms_path', '[.FOO.BAR]NOTE.TXT');
+
+    # The VMS path found in RFC 1738 (section 3.10)
+    $url = new URI::URL 'file://vms.host.edu/disk$user/my/notes/note12345.txt';
+    $url->_expect('vms_path', 'DISK$USER:[MY.NOTES]NOTE12345.TXT');
+    $url->_expect('mac_path', 'disk$user:my:notes:note12345.txt');
+
+    chdir($savedir) or die $!;
+}
+
+
+#####################################################################
+#
+# absolute_test()
+#
+sub absolute_test {
+
+    print "Test relative/absolute URI::URL parsing:\n";
+
+    # Tests from draft-ietf-uri-relative-url-06.txt
+    # Copied verbatim from the draft, parsed below
+
+    @URI::URL::g::ISA = qw(URI::URL::_generic); # for these tests
+
+    my $base = 'http://a/b/c/d;p?q#f';
+
+    $absolute_tests = <<EOM;
+5.1.  Normal Examples
+
+      g:h        = <URL:g:h>
+      g          = <URL:http://a/b/c/g>
+      ./g        = <URL:http://a/b/c/g>
+      g/         = <URL:http://a/b/c/g/>
+      /g         = <URL:http://a/g>
+      //g        = <URL:http://g>
+      ?y         = <URL:http://a/b/c/d;p?y>
+      g?y        = <URL:http://a/b/c/g?y>
+      g?y/./x    = <URL:http://a/b/c/g?y/./x>
+      #s         = <URL:http://a/b/c/d;p?q#s>
+      g#s        = <URL:http://a/b/c/g#s>
+      g#s/./x    = <URL:http://a/b/c/g#s/./x>
+      g?y#s      = <URL:http://a/b/c/g?y#s>
+      ;x         = <URL:http://a/b/c/d;x>
+      g;x        = <URL:http://a/b/c/g;x>
+      g;x?y#s    = <URL:http://a/b/c/g;x?y#s>
+      .          = <URL:http://a/b/c/>
+      ./         = <URL:http://a/b/c/>
+      ..         = <URL:http://a/b/>
+      ../        = <URL:http://a/b/>
+      ../g       = <URL:http://a/b/g>
+      ../..      = <URL:http://a/>
+      ../../     = <URL:http://a/>
+      ../../g    = <URL:http://a/g>
+
+5.2.  Abnormal Examples
+
+   Although the following abnormal examples are unlikely to occur
+   in normal practice, all URL parsers should be capable of resolving
+   them consistently.  Each example uses the same base as above.
+
+   An empty reference resolves to the complete base URL:
+
+      <>         = <URL:http://a/b/c/d;p?q#f>
+
+   Parsers must be careful in handling the case where there are more
+   relative path ".." segments than there are hierarchical levels in
+   the base URL's path.  Note that the ".." syntax cannot be used to
+   change the <net_loc> of a URL.
+
+     ../../../g = <URL:http://a/../g>
+     ../../../../g = <URL:http://a/../../g>
+
+   Similarly, parsers must avoid treating "." and ".." as special
+   when they are not complete components of a relative path.
+
+      /./g       = <URL:http://a/./g>
+      /../g      = <URL:http://a/../g>
+      g.         = <URL:http://a/b/c/g.>
+      .g         = <URL:http://a/b/c/.g>
+      g..        = <URL:http://a/b/c/g..>
+      ..g        = <URL:http://a/b/c/..g>
+
+   Less likely are cases where the relative URL uses unnecessary or
+   nonsensical forms of the "." and ".." complete path segments.
+
+      ./../g     = <URL:http://a/b/g>
+      ./g/.      = <URL:http://a/b/c/g/>
+      g/./h      = <URL:http://a/b/c/g/h>
+      g/../h     = <URL:http://a/b/c/h>
+
+   Finally, some older parsers allow the scheme name to be present in
+   a relative URL if it is the same as the base URL scheme.  This is
+   considered to be a loophole in prior specifications of partial
+   URLs [1] and should be avoided by future parsers.
+
+      http:g     = <URL:http:g>
+      http:      = <URL:http:>
+EOM
+    # convert text to list like
+    # @absolute_tests = ( ['g:h' => 'g:h'], ...)
+
+    for $line (split("\n", $absolute_tests)) {
+	next unless $line =~ /^\s{6}/;
+	if ($line =~ /^\s+(\S+)\s*=\s*<URL:([^>]*)>/) {
+	    my($rel, $abs) = ($1, $2);
+	    $rel = '' if $rel eq '<>';
+	    push(@absolute_tests, [$rel, $abs]);
+	}
+	else {
+	    warn "illegal line '$line'";
+	}
+    }
+
+    # add some extra ones for good measure
+
+    push(@absolute_tests, ['x/y//../z' => 'http://a/b/c/x/y/z'],
+			  ['1'         => 'http://a/b/c/1'    ],
+			  ['0'         => 'http://a/b/c/0'    ],
+			  ['/0'        => 'http://a/0'        ],
+			  ['%2e/a'     => 'http://a/b/c/%2e/a'],  # %2e is '.'
+			  ['%2e%2e/a'  => 'http://a/b/c/%2e%2e/a'],
+	);
+
+    print "  Relative    +  Base  =>  Expected Absolute URL\n";
+    print "================================================\n";
+    for $test (@absolute_tests) {
+	my($rel, $abs) = @$test;
+	my $abs_url = new URI::URL $abs;
+	my $abs_str = $abs_url->as_string;
+
+	printf("  %-10s  +  $base  =>  %s\n", $rel, $abs);
+	my $u   = new URI::URL $rel, $base;
+	my $got = $u->abs;
+	$got->_expect('as_string', $abs_str);
+    }
+
+    # bug found and fixed in 1.9 by "J.E. Fritz" <FRITZ@gems.vcu.edu>
+    $base = new URI::URL 'http://host/directory/file';
+    my $relative = new URI::URL 'file', $base;
+    my $result = $relative->abs;
+
+    my ($a, $b) = ($base->path, $result->path);
+	die "'$a' and '$b' should be the same" unless $a eq $b;
+
+    # Counter the expectation of least surprise,
+    # section 6 of the draft says the URL should
+    # be canonicalised, rather than making a simple
+    # substitution of the last component.
+    # Better doublecheck someone hasn't "fixed this bug" :-)
+    $base = new URI::URL 'http://host/dir1/../dir2/file';
+    $relative = new URI::URL 'file', $base;
+    $result = $relative->abs;
+    die 'URL not canonicalised' unless $result eq 'http://host/dir2/file';
+
+    print "--------\n";
+    # Test various other kinds of URLs and how they like to be absolutized
+    for (["http://abc/", "news:45664545", "http://abc/"],
+	 ["news:abc",    "http://abc/",   "news:abc"],
+	 ["abc",         "file:/test?aas", "file:/abc"],
+	 ["gopher:",     "",               "gopher:"],
+	 ["?foo",        "http://abc/a",   "http://abc/a?foo"],
+	 ["?foo",        "file:/abc",      "file:/?foo"],
+	 ["#foo",        "http://abc/a",   "http://abc/a#foo"],
+	 ["#foo",        "file:a",         "file:a#foo"],
+	 ["#foo",        "file:/a",         "file:/a#foo"],
+	 ["#foo",        "file:/a",         "file:/a#foo"],
+	 ["#foo",        "file://localhost/a", "file://localhost/a#foo"],
+	 ['123@sn.no',   "news:comp.lang.perl.misc", 'news:123@sn.no'],
+	 ['no.perl',     'news:123@sn.no',           'news:no.perl'],
+	 ['mailto:aas@a.sn.no', "http://www.sn.no/", 'mailto:aas@a.sn.no'],
+
+	 # Test absolutizing with old behaviour.
+	 ['http:foo',     'http://h/a/b',   'http://h/a/foo'],
+	 ['http:/foo',    'http://h/a/b',   'http://h/foo'],
+	 ['http:?foo',    'http://h/a/b',   'http://h/a/b?foo'],
+	 ['http:#foo',    'http://h/a/b',   'http://h/a/b#foo'],
+	 ['http:?foo#bar','http://h/a/b',   'http://h/a/b?foo#bar'],
+	 ['file:/foo',    'http://h/a/b',   'file:/foo'],
+
+	)
+    {
+	my($url, $base, $expected_abs) = @$_;
+	my $rel = new URI::URL $url, $base;
+	my $abs = $rel->abs($base, 1);
+	printf("  %-12s+  $base  =>  %s\n", $rel, $abs);
+	$abs->_expect('as_string', $expected_abs);
+    }
+    print "absolute test ok\n";
+
+    # Test relative function
+    for (
+	 ["http://abc/a",   "http://abc",        "a"],
+	 ["http://abc/a",   "http://abc/b",      "a"],
+	 ["http://abc/a?q", "http://abc/b",      "a?q"],
+	 ["http://abc/a;p", "http://abc/b",      "a;p"],
+	 ["http://abc/a",   "http://abc/a/b/c/", "../../../a"],
+         ["http://abc/a/",  "http://abc/a/",     "./"],
+         ["http://abc/a#f", "http://abc/a",      "#f"],
+
+	 ["file:/etc/motd", "file:/",            "etc/motd"],
+	 ["file:/etc/motd", "file:/etc/passwd",  "motd"],
+	 ["file:/etc/motd", "file:/etc/rc2.d/",  "../motd"],
+	 ["file:/etc/motd", "file:/usr/lib/doc", "../../etc/motd"],
+         ["file:",          "file:/etc/",        "../"],
+         ["file:foo",       "file:/etc/",        "../foo"],
+
+	 ["mailto:aas",     "http://abc",        "mailto:aas"],
+
+	 # Nicolai Langfeldt's original example
+	 ["http://www.math.uio.no/doc/mail/top.html",
+	  "http://www.math.uio.no/doc/linux/", "../mail/top.html"],
+        )
+    {
+	my($abs, $base, $expect) = @$_;
+	printf "url('$abs', '$base')->rel eq '$expect'\n";
+	my $rel = URI::URL->new($abs, $base)->rel;
+	$rel->_expect('as_string', $expect);
+    }
+    print "relative test ok\n";
+}
+
+
+sub eq_test
+{
+    my $u1 = new URI::URL 'http://abc.com:80/~smith/home.html';
+    my $u2 = new URI::URL 'http://ABC.com/%7Esmith/home.html';
+    my $u3 = new URI::URL 'http://ABC.com:/%7esmith/home.html';
+
+    # Test all permutations of these tree
+    $u1->eq($u2) or die "1: $u1 ne $u2";
+    $u1->eq($u3) or die "2: $u1 ne $u3";
+    $u2->eq($u1) or die "3: $u2 ne $u1";
+    $u2->eq($u3) or die "4: $u2 ne $u3";
+    $u3->eq($u1) or die "5: $u3 ne $u1";
+    $u3->eq($u2) or die "6: $u3 ne $u2";
+
+    # Test empty path
+    my $u4 = new URI::URL 'http://www.sn.no';
+    $u4->eq("HTTP://WWW.SN.NO:80/") or die "7: $u4";
+    $u4->eq("http://www.sn.no:81") and die "8: $u4";
+
+    # Test mailto
+    my $u5 = new URI::URL 'mailto:AAS@SN.no';
+    $u5->eq('mailto:aas@sn.no') or die "9: $u5";
+
+    # Test reserved char
+    my $u6 = new URI::URL 'ftp://ftp/%2Fetc';
+    $u6->eq("ftp://ftp/%2fetc") or die "10: $u6";
+    $u6->eq("ftp://ftp://etc") and die "11: $u6";
+}
+
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/uri/heuristic.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/uri/heuristic.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/uri/heuristic.t	(revision 20131)
@@ -0,0 +1,61 @@
+print "1..14\n";
+
+use URI::Heuristic qw(uf_urlstr uf_url);
+$URI::Heuristic::DEBUG++;
+open(STDERR, ">&STDOUT");  # redirect STDERR
+
+print "not " unless uf_urlstr("http://www.sn.no/") eq "http://www.sn.no/";
+print "ok 1\n";
+
+print "not " unless uf_urlstr("/etc/passwd") eq "file:/etc/passwd";
+print "ok 2\n";
+
+print "not " unless uf_urlstr("./foo.txt") eq "file:./foo.txt";
+print "ok 3\n";
+
+print "not " unless uf_urlstr("ftp.aas.no/lwp.tar.gz") eq "ftp://ftp.aas.no/lwp.tar.gz";
+print "ok 4\n";
+
+print "not " unless uf_urlstr("C:\\CONFIG.SYS") eq "file:C:\\CONFIG.SYS";
+print "ok 5\n";
+
+if (gethostbyname("www.netscape.com")) {
+    # DNS probably work, lets run test 6..8
+
+    $URI::Heuristic::MY_COUNTRY = "no";
+    print "not " unless uf_urlstr("perl/camel.gif") eq "http://www.perl.com/camel.gif";
+    print "ok 6\n";
+
+    $URI::Heuristic::MY_COUNTRY = "uk";
+    print "not " unless uf_urlstr("perl/camel.gif") eq "http://www.perl.co.uk/camel.gif";
+    print "ok 7\n";
+   
+    $ENV{URL_GUESS_PATTERN} = "www.ACME.org www.ACME.com";
+    print "not " unless uf_urlstr("perl") eq "http://www.perl.org";
+    print "ok 8\n";
+
+} else {
+    # don't make the inocent worry
+    print "Skipping test 6-8 because DNS does not work\n";
+    for (6..8) { print "ok $_\n"; }
+
+}
+
+$ENV{URL_GUESS_PATTERN} = "";
+print "not " unless uf_urlstr("perl") eq "http://perl";
+print "ok 9\n";
+
+print "not " unless uf_urlstr("http:80") eq "http:80";
+print "ok 10\n";
+
+print "not " unless uf_urlstr("mailto:gisle\@aas.no") eq "mailto:gisle\@aas.no";
+print "ok 11\n";
+
+print "not " unless uf_urlstr("gisle\@aas.no") eq "mailto:gisle\@aas.no";
+print "ok 12\n";
+
+print "not " unless uf_urlstr("Gisle.Aas\@aas.perl.org") eq "mailto:Gisle.Aas\@aas.perl.org";
+print "ok 13\n";
+
+print "not " unless uf_url("gopher.sn.no")->scheme eq "gopher";
+print "ok 14\n";
Index: /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/uri/rel-base.t
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/uri/rel-base.t	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/libwww-perl-5.36/t/uri/rel-base.t	(revision 20131)
@@ -0,0 +1,24 @@
+print "1..3\n";
+
+use URI::URL;
+
+# We used to have problems with URLs that used a base that was
+# not absolute itself.
+
+$u1 = url("/foo/bar", "http://www.acme.com/");
+$u2 = url("../foo/", $u1);
+$u3 = url("zoo/foo", $u2);
+
+$a1 = $u1->abs->as_string;
+$a2 = $u2->abs->as_string;
+$a3 = $u3->abs->as_string;
+
+print "$a1\n$a2\n$a3\n";
+
+print "not " unless $a1 eq "http://www.acme.com/foo/bar";
+print "ok 1\n";
+print "not " unless $a2 eq "http://www.acme.com/foo/";
+print "ok 2\n";
+print "not " unless $a3 eq "http://www.acme.com/foo/zoo/foo";
+print "ok 3\n";
+
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/Artistic
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/Artistic	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/Artistic	(revision 20131)
@@ -0,0 +1,131 @@
+
+
+
+
+			 The "Artistic License"
+
+				Preamble
+
+The intent of this document is to state the conditions under which a
+Package may be copied, such that the Copyright Holder maintains some
+semblance of artistic control over the development of the package,
+while giving the users of the package the right to use and distribute
+the Package in a more-or-less customary fashion, plus the right to make
+reasonable modifications.
+
+Definitions:
+
+	"Package" refers to the collection of files distributed by the
+	Copyright Holder, and derivatives of that collection of files
+	created through textual modification.
+
+	"Standard Version" refers to such a Package if it has not been
+	modified, or has been modified in accordance with the wishes
+	of the Copyright Holder as specified below.
+
+	"Copyright Holder" is whoever is named in the copyright or
+	copyrights for the package.
+
+	"You" is you, if you're thinking about copying or distributing
+	this Package.
+
+	"Reasonable copying fee" is whatever you can justify on the
+	basis of media cost, duplication charges, time of people involved,
+	and so on.  (You will not be required to justify it to the
+	Copyright Holder, but only to the computing community at large
+	as a market that must bear the fee.)
+
+	"Freely Available" means that no fee is charged for the item
+	itself, though there may be fees involved in handling the item.
+	It also means that recipients of the item may redistribute it
+	under the same conditions they received it.
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications
+derived from the Public Domain or from the Copyright Holder.  A Package
+modified in such a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided
+that you insert a prominent notice in each changed file stating how and
+when you changed that file, and provided that you do at least ONE of the
+following:
+
+    a) place your modifications in the Public Domain or otherwise make them
+    Freely Available, such as by posting said modifications to Usenet or
+    an equivalent medium, or placing the modifications on a major archive
+    site such as uunet.uu.net, or by allowing the Copyright Holder to include
+    your modifications in the Standard Version of the Package.
+
+    b) use the modified Package only within your corporation or organization.
+
+    c) rename any non-standard executables so the names do not conflict
+    with standard executables, which must also be provided, and provide
+    a separate manual page for each non-standard executable that clearly
+    documents how it differs from the Standard Version.
+
+    d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+
+    a) distribute a Standard Version of the executables and library files,
+    together with instructions (in the manual page or equivalent) on where
+    to get the Standard Version.
+
+    b) accompany the distribution with the machine-readable source of
+    the Package with your modifications.
+
+    c) give non-standard executables non-standard names, and clearly
+    document the differences in manual pages (or equivalent), together
+    with instructions on where to get the Standard Version.
+
+    d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package.  You may charge any fee you choose for support of this
+Package.  You may not charge a fee for this Package itself.  However,
+you may distribute this Package in aggregate with other (possibly
+commercial) programs as part of a larger (possibly commercial) software
+distribution provided that you do not advertise this Package as a
+product of your own.  You may embed this Package's interpreter within
+an executable of yours (by linking); this shall be construed as a mere
+form of aggregation, provided that the complete Standard Version of the
+interpreter is so embedded.
+
+6. The scripts and library files supplied as input to or produced as
+output from the programs of this Package do not automatically fall
+under the copyright of this Package, but belong to whomever generated
+them, and may be sold commercially, and may be aggregated with this
+Package.  If such scripts or library files are aggregated with this
+Package via the so-called "undump" or "unexec" methods of producing a
+binary executable image, then distribution of such an image shall
+neither be construed as a distribution of this Package nor shall it
+fall under the restrictions of Paragraphs 3 and 4, provided that you do
+not represent such an executable image as a Standard Version of this
+Package.
+
+7. C subroutines (or comparably compiled subroutines in other
+languages) supplied by you and linked into this Package in order to
+emulate subroutines and variables of the language defined by this
+Package shall not be considered part of this Package, but are the
+equivalent of input as in Paragraph 6, provided these subroutines do
+not change the language in any way that would cause it to fail the
+regression tests for the language.
+
+8. Aggregation of this Package with a commercial distribution is always
+permitted provided that the use of this Package is embedded; that is,
+when no overt attempt is made to make this Package's interfaces visible
+to the end user of the commercial distribution.  Such use shall not be
+construed as a distribution of this Package.
+
+9. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+				The End
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/Changes
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/Changes	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/Changes	(revision 20131)
@@ -0,0 +1,51 @@
+Fixes in 1.0.6:
+- -f works with binary files
+- w3mir will no longer use 'Referer: (commandline)' when a URL is derived
+  from the commandline/config file.
+- More errormessage fixes
+- Fixed install instructions to warn against LWP 5.40.
+
+Fixes in 1.0.5: 
+- Better error-messaged in -quiet mode 
+- Fixed quoting. Both " and ' quotes in documents are accepted. 
+- Fixed timeout handling. 
+- Fixed broken connection handling. Incomplete documents are 
+  deleted and retried.
+- Fixed URL mangling problem. In 1.0.3 URLs like ``foo.html#bar'' would
+  be rewritten to ``#bar''. This is quite bad and makes a lot of mirrors
+  un-useable. 
+- -v now prints LWPs version as well as w3mirs version
+
+Features/bugs in 1.0.5 
+- As earlier, w3mir does not support cookies. I have received a patch for
+  basic cookie support but have not yet incorporated it due to
+  time-restraints.
+- There actually exists web servers that break the HTTP standard rather
+  thoroughly by not sending a Content-type header (this is mandatory in
+  the standard). W3mir will not discover that a HTML file is HTML in this
+  case and will not extract URLs from it.
+- If you rewrite the ending filename URLs with Apply rules (as in 
+  index.htm -> index.html) and there are links to index.htm#foo the link
+  will be incorrect after mirroring. The solution is to avoid those
+  kinds of rules. This was meant to be fixed in 1.0.3 (which broke it as
+  described above), I will fix it when I get more time. The fix is to
+  remove the #fragment part of URLs when they pass thru the apply
+  machinery. Patches accepted. 
+
+Fixes in 1.0.3: 
+- The -R/remove option to remove files is no longer more destructive
+  than intended.
+- Files with 'unsafe' characters in their filename is now saved as
+  "foo bar" instead of "foo%20bar" 
+- The -B switch works once again. 
+
+Fixes in 1.0.2: 
+- W3mir now only newline converts HTML files, all other files are handled
+  as binary. This should ensure file-integrety even when working with
+   mis-configured servers. 
+
+Fixes in 1.0.1: 
+-fa option and corresponding configuration file directive works again. 
+- Added -nnc option and a corresponding configuration file directive. It
+  disables newline conversions, which could corrupt files the Webserver
+  mis-declares. The HOWTO explains the uses of -nnc 
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/INSTALL
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/INSTALL	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/INSTALL	(revision 20131)
@@ -0,0 +1,117 @@
+This is how you install w3mir on a Unix system. Please see the file
+INSTALL.w32 for install instructions for win32 systems.
+
+INSTALLING PREREQUISITES:
+
+The prerequisites are the perl packages libwww-perl, and MIME-Base64.
+The w3mir install procedure will check for their presence and complain
+if they are not there, so if you are unsure what you have you might
+skip this part for now.
+
+- Get libwww-perl from CPAN 
+  (http://www.perl.com/CPAN/modules/by-module/WWW/).  W3mir does not work
+  with LWP 5.40 and later versions.  Please get an earlier version.
+  It also does not work with the new URI package.  Use the URI package
+  enclosed in the older LWP.
+
+- Unpack it:
+
+    gzip -dc libwww-perl-*.tar.gz | tar xvBf -
+
+- Install it.  W3mir does not require the whole libwww-perl package and
+  all the packages that goes with it to work so you may follow these
+  install instructions instead of the libwww-perl install instructions
+  to get an easier install which will work with w3mir.
+
+    cd libwww-perl-*
+
+  Are you going to install it in the standard perl place (you need to
+  be the system administrator to do this)? If so:
+
+    perl Makefile.PL
+
+  If not (if you are a user):
+
+    perl Makefile.PL PREFIX=/some/dir
+
+  /some/dir could be ~ (as in your home directory).
+
+  IF you are installing an old LWP just for w3mir you can install both
+  the old LWP, the Base64 module and w3mir in a special PREFIX
+  separate from your usual install PREFIX.  This ensures that w3mir will
+  access the older version of LWP and that other software will access
+  the newer version.  If you do this make sure you install all of LWP,
+  Base64 and w3mir with the same PREFIX.
+
+  This step might produce some complaints;  A standard perl
+  installation will typically get messages about missing these
+  modules: IO::Socket, NET::FTP and MD5.  None of these need be
+  installed to run w3mir and so any error messages about these may
+  safely be ignored.
+
+    make
+    make test      (robot/ua and local/http might fail, that's OK)
+    make install
+
+  Now libwww-perl should be installed and working.
+
+- You also have to get the MIME-Base64 package
+  (http://www.perl.com/CPAN/modules/by-module/MIME/)
+
+- Unpack it:
+
+    gzip -dc MIME-Base64-*.tar.gz | tar xvBf -
+
+- Install it:
+
+    cd MIME-Base64-*
+
+  Then, as above, either
+
+    perl Makefile.PL
+
+  or
+
+    perl Makefile.PL PREFIX=/some/dir
+
+  Continue:
+
+    make
+    make test      (it should print 'All tests successful.')
+    make install
+
+  Now MIME-Base64 should be installed and working.
+
+INSTALLING W3MIR:
+
+- Get w3mir (http://www.math.uio.no/~janl/w3mir/ or from CPAN)
+
+- Unpack it:
+
+     gzip -dc w3mir-*.tar.gz | tar xvBf -
+
+- Install it:
+
+     cd w3mir-*
+
+  Are you going to install it in the standard perl place? (You
+  probably need to be the system administrator to do this.)  If so:
+
+    perl Makefile.PL
+
+  If not (if you're a user):
+
+    perl Makefile.PL PREFIX=/some/dir
+
+  /some/dir could be ~ (as in your home directory).
+
+  then
+
+     make
+     make install
+
+w3mir should now be installed correctly.  And if it's installed in
+your path you can even run it.  If you use csh or tcsh you want to run
+'rehash' before the shell will find it.
+
+1999/04/14 - Nicolai Langfeldt
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/INSTALL.w32
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/INSTALL.w32	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/INSTALL.w32	(revision 20131)
@@ -0,0 +1,92 @@
+This file contains installation instructions for two different ports
+of Perl to win32.  One port is known as the 'ActivePerl' port, the
+other is known as 'the GS port'.
+
+********************************* ActivePerl **********************************
+
+This was written and submitted by Roland Bauer.  Thanks.  I have
+edited them slightly.
+
+How to install w3mir on Win95/AS-port (April 1999):
+===================================================
+
++ get and install winzip from http://www.winzip.com/
++ get and install ActivePerl (now Build 509) from http://www.activestate.com/
++ get nmake.exe from 
+  ftp://ftp.microsoft.com/Softlib/MSLFILES/nmake15.exe
+  (or set switch make=nmake to make=dmake in Config.pm
+  and get dmake from GS port)
+
++ perl makefile.pl
++ nmake
++ nmake install
+
++ perl w3mir -h
++ perl w3mir http://xx.zz.zz/dir/
+
+
+Caveats:
+========
+
++ archive 1.0.6 from CPAN seems to be corrupted
+
++ &mkdir does not seem to work with dos-paths
+like 'D:/DIR1/DIR2'
+(so it is not possible to save to another harddisk)
+
+*********************************** GS Perl ***********************************
+
+These win32 installation instructions were written by Paul Hsiao and
+slightly edited by me. My thanks to Paul. It was current as of
+22-May-1998.
+
+
+WINZIP DOWNLOAD INSTRUCTIONS
+
+    The WinZip program can be accessed from the "Start" button, if the
+    program came with your system.  This software can be obtained from:
+ 
+                http://www.winzip.com/
+ 
+    Follow the installation instructions for the WinZip software as needed.
+
+ 
+PERL DOWNLOAD INSTRUCTIONS
+ 
+    The w3mir code will need access to version 5.003 or higher of the 
+    Perl interpreter and LWP library extensions in order for it to run. 
+    This software can be obtained from:
+ 
+                ftp://sunsite.uio.no/pub/languages/perl/CPAN/ports/win32/Standard
+ 
+    From this URL, select perl5.00402-bindist04-bc.tar.gz and download
+    to your PC into a folder of your choice.  In the folder, run WinZip
+    on this file.  For MS Windows 95, you need to update the registration: 
+    open C:\autoexec.bat  and add a line
+
+                path %path%;C:\Perl\bin;       
+    (C:\Perl\ is the path of the perl folder)  
+
+
+W3MIR DOWNLOAD AND INSTALLATION INSTRUCTIONS
+
+    You already have w3mir. Right? Unpack the .tar.gz file with
+    winzip.
+ 
+    Open a DOS prompt screen and go to the w3mir folder:
+ 
+        cd C:\w3mir-1.0.3
+ 
+    Type the install command for w3mir:
+ 
+        perl.exe Makefile.PL
+        make
+        make install
+ 
+    To test w3mir, type:
+ 
+    perl w3mir -h
+ 
+    If the screen displays all options (about 25 options), then 
+    w3mir is installed correctly.
+
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/MANIFEST
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/MANIFEST	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/MANIFEST	(revision 20131)
@@ -0,0 +1,15 @@
+Artistic
+Changes
+INSTALL
+INSTALL.w32
+MANIFEST
+Makefile.PL
+README
+example.cfg
+multiscope.cfg
+w3mir.PL
+w3mir-HOWTO.html
+w3mfix.PL
+htmlop.pm
+w3http.pm
+w3pdfuri.pm
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/Makefile.PL
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/Makefile.PL	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/Makefile.PL	(revision 20131)
@@ -0,0 +1,116 @@
+# -*-perl-*-
+# Makefile.PL for w3mir.
+# Note that the file 'MANIFEST' is quite significant in this context
+#
+# Notes:  Should unpack any tar.gz files in current directory and install
+#   them with identical arguments to Makefile.PL to this invocation.
+#   This is especially for making installation of w3mir easy 
+#   by installing libwww-perl and mime-base64 for the user before
+#   installing w3mir.  Cool eh?  That would require some changes.
+#
+# - janl 18/4/1997
+#
+# 19/04/99 janl: Added 'clean' target on tip from  Lupe Christoph
+#	and LWP max-version check to the LWP detection.
+# 
+
+# First just write the Makefile
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+    NAME	=> 'w3mir',
+    VERSION_FROM => 'w3mir.PL', # finds $VERSION
+    EXE_FILES => [ 'w3mir', 'w3mfix' ],
+    clean => { FILES => 'w3mir w3mfix' },
+    dist => { COMPRESS => 'gzip -f9', SUFFIX => 'gz' },
+);
+
+print "\n";
+
+# Find value of INSTALLSITELIB
+
+&read_makefile;
+$islib = resolve_make_var('INSTALLSITELIB');
+
+# Check for prerequisites
+
+$| = 1;
+my $missing_modules = 0;
+
+# libwww-perl
+print "Checking for libwww-perl:";
+
+eval "use lib '$islib'; require LWP;";
+
+if (!defined($LWP::VERSION)) {
+  print ' failed
+
+libwww seems to be missing.
+
+';
+  $missing_modules++;
+  sleep(2);
+} elsif ($LWP::VERSION<5.08 or $LWP::VERSION>=5.40) {
+  print ' failed
+
+libwww is version ',$LWP::VERSION,', I need version 5.08 to 5.39.
+Please see the INSTALL file.
+
+';
+  $missing_modules++;
+  sleep(2);
+} else {  
+  print " ok\n\n";
+}
+
+# MIME::Base64
+print "Checking for MIME::Base64:";
+
+eval "use lib '$islib'; require MIME::Base64;";
+
+if (!defined(&MIME::Base64::encode)) {
+  print ' failed
+
+MIME::Base64 seems to be missing.
+
+';
+  $missing_modules++;
+  sleep(2);
+} else {
+  print " ok\n\n";
+}
+
+
+print 'Please see the INSTALL file for instructions on how to get the
+missing/too old modules.
+
+' if $missing_modules;
+
+
+sub resolve_make_var ($) {
+
+  my($var) = shift @_;
+  my($val) = $make{$var};
+
+#  print "Resolving: ",$var,"=",$val,"\n";
+  
+  while ($val =~ s~\$\((\S+)\)~$make{$1}~g) {}
+#  print "Resolved: $var: $make{$var} -> $val\n";
+  $val;
+}
+
+
+sub read_makefile {
+
+  open(MAKEFILE, 'Makefile') || 
+    die "Could not open Makefile for reading: $!\n";
+
+  while (<MAKEFILE>) {
+    chomp;
+    next unless m/^([A-Z]+)\s*=\s*(\S+)$/;
+    $make{$1}=$2;
+#    print "Makevar: $1 = $2\n";
+  }
+
+  close(MAKEFILE)
+}
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/README
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/README	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/README	(revision 20131)
@@ -0,0 +1,133 @@
+PROPAGANDA:
+
+See http://www.math.uio.no/~janl/w3mir/ for propaganda.
+
+--------------------------------------------------------------------------
+Q: Where can I get a new version of w3mir?
+A: The w3mir homepage is at http://www.math.uio.no/~janl/w3mir/.
+   W3mir is also distributed on CPAN: http://www.perl.com/
+
+Q: Are there any mailing lists?
+A: Yes, see below.
+
+Q: Should I subscribe to any of the mailinglists?
+A: Yes, if you use w3mir at all you should subscribe to 
+   w3mir-info@usit.uio.no, send e-mail to janl@math.uio.no to be
+   subscribed.
+
+Q: I found a bug!
+A: See below.
+
+Q: How do it...
+A: There is a w3mir-HOWTO.html file in the distribution.  Read it.
+
+--------------------------------------------------------------------------
+BUGS:
+
+- -lc switch does not work too well.
+
+Please see below for how to report bugs.
+
+--------------------------------------------------------------------------
+FEATURES (NOT bugs):
+
+- URLs with two /es ('//') in the path component does not work
+  as some might expect.  According to my reading of the http/url spec.
+  it is an illegal construct, which is a Good Thing, because I don't
+  know how to handle it if it's legal.
+- If you start at http://foo/bar/ then index.html might be gotten twice.
+- Some documents point to a point above the server root, i.e.,
+  http://some.server/../stuff.html.  Netscape, and other browsers, in
+  defiance of the URL standard documents will change the URL to
+  http://some.server/stuff.html.  W3mir will not.
+
+--------------------------------------------------------------------------
+MAIL LISTS, REPORTING BUGS:
+
+Please send ideas (see todo lists further down please) and bug reports
+to w3mir-core@usit.uio.no, please include URL and command line/config
+file that triggered the bug. w3mir-info@usit.uio.no is mainly used for
+announcing new versions or bugs to w3mir users. You will get more
+information following that list than anywhere else. And it's very low
+volume. To subscribe to these lists email janl@math.uio.no. The
+w3mir-core list is intended for w3mir hackers only.
+
+--------------------------------------------------------------------------
+COPYRIGTHS:
+
+w3mir, w3http.pm, w3pdfuri.pm and htmlop.pm are free but it is
+Copyrighted by the various involved hackers.  If you want to copy,
+hack or distribte w3mir you can do that providing you comply with the
+'Artistic License' enclosed in the w3mir distribution in the file
+named Artistic.
+
+--------------------------------------------------------------------------
+CREDITS:
+
+- Oscar Nierstrasz: Wrote htget
+- Gorm Haug Eriksen: Started w3mir on the foundations of htget,
+	contributed code later.
+- Nicolai Langfeldt: Learning from Oscar and Gorms mistakes, rewrote
+  everything.
+- Chris Szurgot: Adapting to win32, good ideas and code contribs, 
+  Debugging.  And criticism.
+- Rik Faith: Uses w3mir extensively, not shy about complaining and
+  commenting and suggesting.  
+- The libwww-perl author(s) that made adding some new featres
+  ridicolously easy.
+
+--------------------------------------------------------------------------
+TODO LIST:
+
+* TODO, version 1.1:
+
+Some of these are speculative, some others are very useful.
+
+- CSS parsing/support at the same level as HTML
+- Full support for APPLETS/OBJECT tags.
+- Alias rules.  These would enable w3mir to map ukoln.bath.ac.uk and 
+  bubl.bath.ac.uk to www.ukoln.ac.uk and know that the objects contained
+  in these are all the same.  Another use would be to mirror from a mirror
+  instead of the _real_ site, since the original site to which you have
+  references are on a slow link while the mirror is on a fast link.
+- FTP support (easy if through a http style ftp proxy, but is that what
+  we want?)
+- SHTTP/SSL support
+- Add a 3rd argument to URL/Also that denotes the depth of documents to
+  be retrived under each, this would autimatically generate fetch/ignore
+  rules.  How well these work would be dependent on the order of the
+  URL/Also directives though.  Must be documented.
+- Retrive recursively until N-th order links are reached.  This
+  differs siginificantly from directory recursion which we do now.  When
+  this is done w3mir should also know the difference between inline and
+  external links, inline links should always be retrived.  Trivia question:
+  What order is needed to reach every findable document on the web from
+  Yahoo?
+- Integrate with cvs or rcs (or other version controll system) to make
+  retriver able to reproduce mirrored site for any given date.
+- Some text processing:  Adding and removing text/sgml comments when suitable
+  options and tags are found.
+- Put retrival date-stamps as comments in html files, to document the when
+  and how of how this document was retrived.
+- Example: If you're mirroring a site primarily to get to the papers, but
+  the site has n versions of each paper: foo.ps.gz, foo.ps.Z, foo.dvi.gz
+  foo.dvi.Z, foo.tar.gz, foo.zip and you only need one version.  Implement
+  a way to get only one version of documents provided in multipele versions,
+  something like multi axis preference list to get only the most attractive
+  version of the doc.
+- Logging of retrivals to file, need to change every print to a functioncall.
+- Your suggestion here.
+
+* TODO, http related
+- Use Keep-alive.  Then we should probably stop using 30 second pauses
+  between document retrivals.
+- HTTP/1.1?  HTTP/1.1 servers should do keep-alive even with 1.0 requests.
+- Separate quenes for each server, interleave requests.
+- Authentication is only done if challenged now.  If a document in a
+  directory needs authentication it is very likely that all other documents
+  in that directory and subdirectories require authentication.
+
+* If perl gets threads:
+- Make the retrival and analysis engines separate threads, and have each
+  one retrival thread pr. method/server/port and do paralell retrivals.
+- This makes http/1.1 easier too.
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/example.cfg
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/example.cfg	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/example.cfg	(revision 20131)
@@ -0,0 +1,120 @@
+# This is a example w3mir config file.  The file and options are fully
+# documented in the w3mir man page, and a lot is spelled out in the 
+# w3mir-HOWTO.  This file might not be completely updated, but the man
+# page should be.
+#
+# Comment lines start with '#'.  Comments are not allowed at end of
+# lines.  The keywords are not casesensitive, but some settings are,
+# notably fetch/ignore/apply settings, as well as the urls given.
+#
+# Available options: recurse, no-date-check, only-nonexistent, list-urls,
+# lowercase.  It is not default to recurse.  Options must be the
+# first directive to appear in the config file.
+# The options directive needs to be the first directive in the config file
+# and there can only be one.
+Options: recurse
+# Multipele options:
+# Options: recurse, only-nonexistent
+# This directive was previously named 'Fetch-options'
+#
+# Start here:
+URL: http://www.stud.ifi.uio.no/~janl/
+#
+#
+# How much noise to make, one of quiet, brief or chatty.  Default is brief
+#Verbosity: brief
+#
+# Initial referer.  Some servers are very picky....
+#Initial-Referer: http://foo.bar/
+#
+# Headers to disable for anonymitys sake: 
+#Disable-headers: referer, user
+#
+# Nicenes, robotrules can be true or false
+#Robot-Rules: true
+# Default pause between http connections is now 0 seconds 
+# Pause: 0
+# Pause between retries, in seconds.  If w3mir runs as a once-a-day thing
+# this can and should be high.  I suggest at least one hour (3600 seconds).
+#Retry-Pause: 600
+# How many times a failed retrival is retried.
+#Retries: 3
+#
+# URL selection.  Order is significant, first Fetch/Ignore rule overrides
+# later rules.  Supply as many as you want.  If not matched by ignore rules
+# a doc is gotten.  
+#Fetch: *.html
+#
+# Ignore urls we can't copy anyway.  Actually w3mir can copy
+# many cgi things with no problems.  But not always.
+Ignore: *.cgi
+Ignore: *-cgi
+Ignore: *.map
+#
+# RE variants are full perl REs.  Mix freely with the others.  These
+# must be legal perl REs, including the starting m and any
+# options you want, like 'i'.
+#
+#Fetch-RE: m/jpeg/
+#Ignore-RE: m/\.gif$/
+#
+# URL manipulation.  _All_ rules are applied in order.  If lowercasing
+# options is given that is done first.  This must be a legal perl
+# substitution RE.  Including the starting s and any options you want,
+# like 'g' and 'i'.
+#
+# This changes the name of all .gif files to .fif
+#Apply: s/\.gif$/.fif/
+#
+# HTTP Proxy server:
+#HTTP-Proxy: www-cache.uio.no:3128
+#
+# HTTP Proxy options: 
+# - 'revalidate': Force proxy to revalidate cached documents.
+# - 'refresh': Force proxy to get cached documents from server _again_.
+# - 'no-store': Use if the contents of the documents is sensitive.
+# - 'no-pragma': Force use of HTTP/1.1 'Cache-Control:' header.
+# If only 'refresh' is specified the default is to use the 'Pragma: no-cache'
+# HTTP/1.0 header, this can be overruled with the 'no-pragma' option.
+# You can be fairly sure any proxy will understand 'refresh', ONLY HTTP/1.1
+# proxies will understand 'revalidate' and 'no-store'.
+#proxy-options: refresh
+#
+# HTTP Proxy authentication.  The mechanism  is simpleminded, we either need
+# to authenticate ourselves with the proxy or not, and there can only be
+# one user/password tuple, domain/realm information is ignored...
+# HTTP-Proxy-user: foo
+# HTTP-Proxy-passwd: bar
+#
+# What to do with files, one of save, stdout or forget.
+#File-disposition: save
+#
+# Debug level
+#Debug: 0|1|2
+#
+# Umask, if not the default
+#Umask: 077
+#
+# HTML document editing options
+#Header: Mirrored from http://www.ifi.uio.no/~janl/ts/
+#Remove-nomirror: true
+#
+# Authentication:
+#Auth-domain: server:port/realm
+#Auth-user: me
+#Auth-passwd: my_password
+#
+# You can use '*' in place of server:port and/or realm:
+#Auth-domain: */*
+#Auth-user: otherme
+#Auth-passwd: otherpassword
+#
+
+# 'Fixup' is done by the external w3mfix program.  If you want a
+# mirror that's browseable in a filesystem (as opposed to via a http
+# server) just put this in:
+Fixup: run
+
+# Related is this, what is the name of the file the http server serves
+# when a directory URL is requested?  w3mir default is index.html.
+#Index-name: welcome.html
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/htmlop.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/htmlop.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/htmlop.pm	(revision 20131)
@@ -0,0 +1,656 @@
+# -*-perl-*-
+# htmlop.pl: Do operations on html documents.
+$VERSION=0.2.4;
+#
+# Original source from Bjørn Borud, without it I would not have atempted
+# this. In this incarnation it bears no resemblance to Bjørns code.
+# - Nicolai Langfeldt 18/11/95.
+# 
+# htmlop.pl does operations on html files, possebly many at a time.
+# Operations:
+# - Absolitify urls
+# - Relativify urls
+# - Gather list of urls
+# - Callback with url
+# - Canonify document w.r.t. SGML.
+#
+# Authors:
+# - Nicolai Langfeldt (janl@ifi.uio.no)
+# - Chris Szurgot (szurgot@itribe.net)
+#
+# Changes:
+# janl    18/11/95 - Initial version
+# szurgot 09/02/96 - Code in htmlop'process to remove <BASE> Tag if we are 
+#                    returning the form. An unchanged base destroys local 
+#                    fragments.
+# janl    22/02/96 - Added URLSUB functions.  <BASE> will only be removed from
+#		     the returned doc, never from the origninal doc.
+# janl    16/05/96 - Removed I* options and added single NODOC option/modifier
+#		     to replace them.
+# janl	  09/09/96 - Added URLPROC and NREL opcodes, for a better URL
+#		     processing model. -> 0.1.7
+# janl    24/09/96 - Various cosmetics, no longer inserting a !SGML tag,
+#		     only !DOCTYPE and HTML tags. -> 0.1.8
+# janl    11/10/96 - URLs in HTML 3.2 tags are now found.
+# janl     6/11/96 - Added netscape SCRIPT tag.
+# janl    20/11/96 - 'BORDER' is different from 'BORDER=0' -> 0.1.10
+# janl    06/11/96 - Added userdata argument to URLPROC.
+#   			Added SAVEURLS and USESAVED opcodes. -> 0.1.11
+# janl    11/04/97 - Changed to URI::URL and got into strict harness
+# janl	  13/04/97 - Fixed comment processing, extended it to processing
+#			directives. Bug reported by Chris Johnson. -> 0.1.12
+# janl    08/04/97 - Made ISMAP into ISMAP=, bad! -> 0.1.13
+# janl	  23/05/97 - Treating <script> and <style> as verbatim -> 0.1.14
+# janl	  06/06/97 - Canonify: <!SGML tag confused it and !DOCTYPE was mangled
+#			-> 0.1.15
+# janl	  30/07/97 - Now supporting <BASE> tag.
+#		   - Added TAGCALLBACK opcode -> 0.1.16
+# janl    16/10/97 - Empty string must be quoted, reported by Bart Barenburg
+#			-> 0.1.17
+# janl	  01/12/97 - More HTML URL tags/attributes recognized (Greg Lindhorst) 
+# janl	  13/12/97 - Can't delete the whole <BASE> tag.  Netscape has
+#		     extended it for frame use.  So only delete the HREF
+#		     attr -> 0.1.18
+# janl    01/01/98 - Realized applet/object support can't work and changed
+#		     so it's able to work, if conditions are right.
+# janl    04/01/98 - Added html 4.0 tags and attributes.
+# janl    08/02/98 - Hacked for speed.  Went from 43s to 9s on a 170K
+#		     document -> 0.2.  Thanks to Rune Frøysa who taunted me.
+# janl	  09/04/98 - More tolerant about what constitutes a newline -> 0.2.1
+# janl	  09/05/98 - Export %isdir -> 0.2.2
+# janl    13/04/99 - Remove leading /../ sequences in path component in
+#		     ABS code. -> 0.2.3
+# janl    28/05/99 - The code was buggy, now it's not. -> 0.2.4
+
+package htmlop;
+
+use URI::URL;
+
+use strict;
+# Global variables
+use vars qw($ABS $REL $LIST $CANON $URLSUB $NODOC $URLPROC $NREL);
+use vars qw($SAVEURL $USESAVED $TAGCALLBACK $debug %isdir);
+
+# These are for the smartrel routines
+my $url_origin;
+my $doc_top;
+my $doc_top_re;
+my $choped_url_or;
+
+# HTML operation codes for process_html.  The first argument is the
+# html document to do operations on.  It will not be changed.  If
+# NODOC is not passed a new document edited as specified will be
+# returned.  No more than one document will be returned by one
+# invocation of htmlop.
+
+$ABS = 1;			# Absolutify urls. Arg: Origin. The
+                                # ABS function absolutifies URLS,
+                                # assuming they are relative to the
+                                # argument.
+				# If a <BASE> tag is found the origin
+				# given by it will be used instead of
+				# the arguemnt given.
+
+$REL = 2;			# Relativize all urls. Arg: Origin.
+                                # The REL function simply removes the
+                                # argument string from any urls
+                                # matching it.  For this reason the
+                                # origin string is interprated as a
+                                # RE, which may have unexpected
+                                # results, unless RE specials are
+                                # escaped, which they should be.
+
+$LIST = 3;			# List all urls, Ret: urls
+
+$CANON = 4;			# See that missing opening (and
+                                # ending) SGML tags are injected.
+
+$URLSUB = 5;			# Do regular expression substitution
+                                # on urls.  Arg: RE, substitute.
+
+$NODOC = 6;			# Do not return a rebuilt document.
+                                # Saves memory, and time
+
+# NOTE: I SUSPECT URLPROC IS BROKEN IF A BASE TAG APPEARS IN THE TEXT.
+# THE URL PROCESSOR NEEDS TO BE PASSED htmlop::process' IDEA OF WHAT THE
+# BASE URL IS.
+
+$URLPROC = 7;			# Apply function on urls (process
+                                # urls).  Arg: Pointer to function to
+				# apply, userdata.  The function will
+				# be passed the url, modified by any
+				# previous operations and the
+				# userdata.  The function must return
+				# the new url.
+
+$NREL = 8;			# New relativisation function, works
+                                # much better than the old one. Arg:
+                                # Origin, Top.
+
+$SAVEURL = 9;			# Save urls in tag with modified name.
+				# Arg: attribute prefix.
+				# Example: <a href=foo> becomes
+				# <a href=foo w3mir-href=foo> if no other
+				# processing of the url is done.
+
+$USESAVED = 10;			# Use saved urls. Arg: attribute prefix
+
+$TAGCALLBACK = 11;		# Procedure to call for each Tag.
+				# Args: procedure, userdata (one item)
+
+				# Args to procedure: userdata, Base
+				# URL, tag name, reference to array of
+				# URL attributes, reference to hash of
+				# all attributes.  The base url is
+				# derived from the one used in ABS or
+				# the BASE tag.
+
+$debug=0;			# Debugging level in this package
+
+# process_html returns a array.  The first component of the array is
+# the new html document. The rest of the array is the urls.  If a
+# document is not to be returned a empty string is returned. If a url
+# list is not to be returned a empty array is returned.
+
+# HERE BE DRAGONS:
+
+# Where to find URLs in various tags.  The second compoent is a array
+# reference.
+
+my(%urls) = (
+	HEAD    => [ 'PROFILE' ],
+        BLOCKQUOTE => [ 'CITE' ],
+        Q 	=> [ 'CITE' ],
+        INS	=> [ 'CITE' ],
+	DEL	=> [ 'CITE' ],
+	A	=> [ 'HREF' ] ,
+	IMG	=> [ 'SRC' ,'LOWSRC' ,'USEMAP', 'LONGDESC' ] ,
+	EMBED	=> [ 'SRC' ],
+	FRAME	=> [ 'SRC', 'LONGDESC' ],
+        IFRAME  => [ 'SRC', 'LONGDESC' ],
+	BODY	=> [ 'BACKGROUND' ],
+	AREA	=> [ 'HREF' ],
+	LINK	=> [ 'HREF' ],
+
+	# The APPLET and OBJECT tags do not fit into my model for URL
+	# manipulation.  Just looking at CODEBASE might work, if the
+	# URL it names is a browseable directory...
+	APPLET	=> [ 'CODEBASE' ],  # If the codebase dir is browseable
+	OBJECT  => [ 'CODEBASE' ],  # Ditto.  Can't handle DATA attribute now
+
+	INPUT	=> [ 'SRC', 'USEMAP' ],
+	MAP	=> [ 'HREF' ],
+	SCRIPT	=> [ 'SRC', 'FOR' ],# 'FOR's semantics is not defined, the
+				    # attribute is just reserved for possible
+				    # future use...
+	BGSOUND => [ 'SRC' ],
+	FORM	=> [ 'ACTION' ],    # Is this asking for trouble?
+				    # Maybe it should just be absolutized...
+	     			    # On the other hand: It's CGI...
+	);
+
+my(%relative) = (
+	# Identify URL attributes containing urls that are relative to
+	# the named URL attribute.   When processing these they should
+        # be absolitized and then relativized relative to the BASE attribute.
+        # This is just window dressing for now; it is not used for anything.
+
+	# ARCHIVE is really a URI _list_.
+	CODEBASE => [ 'CLASSID', 'DATA', 'CODE', 'ARCHIVE' ],
+        );
+
+%isdir = (
+	# These tags refer to directories:
+	CODEBASE => 1
+	);
+
+# Tags that enclose bits we want to leave absolutely alone because they
+# are not very like HTML, or some such.
+
+# The material between the start and end tags is copied with no
+# processing at all.  The end tag is left to be processed.
+# The endtag match is case insensitive.
+my(%verbatim) = (
+        SCRIPT	=> quotemeta('</SCRIPT>'),	# Embeded scripts
+	STYLE	=> quotemeta('</STYLE>'),	# Embeded stylesheet
+	);
+
+# These are the functions that pick the HTML to pieces.  It will not
+# work esp. good on a random SGML document since the HTML application
+# of SGML has simpler quoting than it might.
+
+sub gettoken {
+  # Get one token from the argument, removing it from the argument.
+  # BUG: There should be whitespace at the end of the examined string.
+  my($c,$token,$i);
+  
+  # Skip whitespace and newlines
+  return '' unless defined(@_) && defined($_[0]);
+  $_[0] =~ s/^[\r\n\s]*//;
+  
+  return '' if ($_[0] eq '');
+  
+  $c = substr($_[0],0,1);
+  substr($_[0],0,1)='';
+  
+  if ($c eq '"' || $c eq "\'") { # Quoted material
+    $i=index($_[0],$c);
+    # End-quote missing, just gobble the rest of the doc
+    $i=length($_[0]) if $i == -1;
+    # Extract and remove token
+    $token=substr($_[0],0,$i);
+    substr($_[0],0,$i+1)='';
+  } elsif ($c eq '=') {
+    $token='=';
+  } else {			# Non-quoted material, ends in whitespace or =
+    $_[0] =~ m/[=\s\n\r]/;
+    $_[0] = $&.$';
+    $token=$c.$`;
+  }
+  # print "Token: '$token'\t\tRest: '",$_[0],"'\n";
+  return $token;
+}
+
+
+sub tagtoken {
+  # Pick the tag to pieces (also knonw as tokens). Return an
+  # associative array of attributes.  The attribute-names are changed
+  # to uppercase.  The attribute-values are left as is.
+  my($tok,$lasttok,%tokens);
+  # Append a space, gettoken needs it - silly? Yes! 
+  # Change it to test on boundrary things rather than ...?
+  $_[0].=' ';
+
+  $lasttok='';
+  while (1) {
+    last if (($tok=uc &gettoken($_[0])) eq '');
+
+    if ($tok eq '=') {
+#      print STDERR " -bad html-" if ($lasttok eq '');
+      $tokens{$lasttok}.=&gettoken($_[0]);
+      print STDERR "STORED: $lasttok = ",$tokens{$lasttok},"\n" if $debug;
+    } else {
+      $tokens{$tok}=undef;
+      $lasttok=$tok;
+    }
+  }
+  return %tokens;
+}
+
+
+sub gettag {
+  # Pick out the following things from the remaining html doc:
+  # Everything leading up to the first tag.  The first tag, and its
+  # contents.  Modify @_ directly to reduce number of copies of
+  # possebly huge documents kept in memory at once.  Return the body,
+  # the tag name, and the attributes (associative array)
+  my(%attr,$tagn,$tagc,$body,$tag,$doc);
+
+  $doc=\$_[0];
+
+  my($start,$end,$length);
+  
+  $start=index($$doc,'<');
+
+  if ($start<$[) {
+    # EOF
+    $body=$$doc;
+    $$doc='';
+    return ($body,'',());
+  }
+
+  $end=index($$doc,'>',$start+1);
+  
+  if ($end<$[) {
+    # This sucks, found no end of the tag...
+    $body=$$doc;
+    $$doc='';
+    return ($body,'',());
+  }
+
+  $length=$end-$start-1;
+
+  $body=substr($$doc,0,$start);
+  $tag=substr($$doc,$start+1,$length);
+
+  # This shortens the string in each itteration, some kind of mechanism
+  # to do it once in a while would speed things up further.  HOWEVER, when
+  # I tried to code this all I got was a _nasty_ memory leak.
+  substr($$doc,0,$end+1)='';
+
+#  print STDERR "------\n";
+  
+#  print STDERR "BODY: /$body/\n";
+  print STDERR "COMPLETE TAG: /$tag/\n" if $debug;
+#  print STDERR "REST: /",substr($$doc,0,20),"/\n";
+
+#  print STDERR "------\n";
+
+  # Examine tag contents
+  if ($tag =~ /^([!?]--)/ || $tag =~ /^(!\w+)/) {
+    # Comment or processing dicective, handle specially
+    $tagn=$&;
+    $tagc=$';
+    return ($body,$tagn,("$tagc",undef));
+  }
+
+  # Everything else
+  ($tagn,$tagc) = split(/[\s\n\r]+/,$tag,2);
+  $tagn="\U$tagn";
+
+  return ($body,$tagn,()) if !defined($tagc);
+  
+  return ($body,$tagn,&tagtoken($tagc));
+}
+
+
+# This is meant for general consumption:
+
+sub process {
+  # Process a html file.  Into one end you put a html file.  Out
+  # of the other end you get something dependent on the operations
+  # you specified.
+  # I cannot gobble my arguments. I need to examine them several times.
+  
+  my($arg,$doc,$i,$retdoc,$canon,$newdoc,@urllist,$Q,$cont);
+  my($origin,$baseurl);
+  
+  $origin=$baseurl='';
+
+  $retdoc=$canon=0;
+  
+  # Get the document from the argument list
+  $doc=shift(@_);
+  
+  $retdoc=1;
+  $i=0;
+  # Argument checking
+  while (defined($arg=$_[$i++])) {
+    if (! ($arg =~ /^\d+$/)) {
+      print STDERR "ERROR IN HTMLOP::process:\n";
+      print STDERR "Args: ",join(',',@_),"\n";
+      print STDERR "ARG: $arg is not a opcode.\n";
+      exit(1);
+    }
+    if ($arg == $ABS) {
+      $baseurl=$origin=$_[$i++];
+    } elsif ($arg == $REL || $arg == $SAVEURL || $arg == $USESAVED) {
+      $i++; # Skip one arg
+    } elsif ($arg == $URLSUB || $arg == $NREL || $arg == $URLPROC ||
+	     $arg == $TAGCALLBACK ) {
+      $i += 2; # Skip two args
+    } elsif ($arg == $LIST) { 
+      # do nothing
+    } elsif ($arg == $CANON) {
+      $canon=1;
+    } elsif ($arg == $NODOC) {
+      $retdoc=0;
+    } else {
+      die "htmlop: Incorrect invocation of html_process\n";
+    }
+  }
+  
+  my($endhtml)=0;	# Have we seen </html>?
+  my($SGML)=1;		# 1: !DOCTYPE not seen, 2: !DOCTYPE seen, -1: it's OK
+
+  # These are used to store the tag components
+  my($textpart);
+  my($tagname);
+  my(%attrval);
+
+  my($wholetag);	# The whole tag, put together again
+  my($moretag);		# TMP storage of tag attributes
+  my($attr);		# Looping thru attributes, misnomer.
+  my($RE);
+  my($subst);
+  my($prefix);
+  my($fun);		# Function to apply to url
+  my($verbatim)='';
+  my($url_o,$path);		# URL object Used in ABS to remove leading ..
+
+  # Welcome to the machine
+
+  $newdoc='';
+  while ($doc ne '') {
+    ($textpart,$tagname,%attrval)=&gettag($doc);
+    
+    # Process the tag
+    { # Need a way to get out of this, last is my friend
+      # 'Canonize'
+      if ($canon) {
+	$endhtml=1 if ($tagname eq '/HTML');
+	if ($SGML!=-1 && $canon && $tagname ne '!--' && $tagname ne '!SGML') {
+	  $wholetag=$tagname;
+	  $moretag=join('',keys %attrval);
+	  $wholetag.=' '.$moretag if ($moretag ne '');
+	  if ($SGML==1) {
+	    $SGML=2;
+	    if ($tagname eq '!DOCTYPE') {
+	      $tagname=$wholetag;
+	      %attrval=();
+	      last;
+	    }
+
+	    # We have no idea what DTD this doc follows so we put in
+	    # something kinda non-comitting
+	    $newdoc.='<!DOCTYPE HTML PUBLIC "html.dtd">'."\n";
+	  }
+	  if ($SGML==2) {
+	    $SGML=-1;
+	    if ($tagname eq 'HTML') {
+	      $tagname=$wholetag;
+	      %attrval=();
+	      last;
+	    }
+	    $newdoc.='<HTML>'."\n";
+	  }
+	}			# sgml!=-1
+      }				#canon
+
+      # Tack on text part before I bail out, if wanted
+      $newdoc.=$textpart if $retdoc;
+
+      if ($tagname eq 'BASE') {
+	if (exists($attrval{'HREF'})) {
+	  if ($origin) {
+	    $baseurl=(url($attrval{'HREF'})->abs($origin,1))->as_string;
+	  } else {
+	    $baseurl=$attrval{'HREF'};
+	  }
+	  # Get rid of the HREF attribute.  Netscape 4.0 puts (other) stuff
+	  # into BASE that is not found in the HTML 4.0 spec.
+	  delete $attrval{'HREF'};
+	  print STDERR "\nBase tag: $baseurl\n" if $debug;
+	}
+      }
+
+      # URL processing
+      $i=0;
+      while (defined($arg=$_[$i])) {
+	if (! ($arg =~ /^\d+$/)) {
+	  print STDERR "Args: ",join(',',@_),"\n";
+	  print STDERR "ARG: $arg ($i) is not a opcode.\n";
+	  exit(1);
+	}
+	$i++;
+	if ($arg == $ABS) {
+	  $origin=$baseurl || $_[$i++];
+	  $i++;
+	  # Want it to be a URL object
+	  $origin=url $origin unless ref $origin;
+	  print STDERR 'ABS: ',$origin->as_string,"\n" if $debug;
+	  next unless defined($urls{$tagname});
+	  foreach $attr (@{$urls{$tagname}}) {
+	    if (defined($attrval{$attr})) {
+	      # Ugly: Remove leading /../ sequences in path component
+	      $url_o=url($attrval{$attr})->abs($origin,1);
+	      if (defined($path=$url_o->path)) {
+		# mailto: URLs does not have path components
+		$path =~ s~/\.\.(?=/)~~g;
+		$url_o->path($path);
+	      }
+	      $attrval{$attr}=$url_o->as_string;
+	    }
+	  }
+	} elsif ($arg == $REL) {
+	  $origin=$_[$i++];
+	  # Want it to be a string
+	  $origin=$origin->as_string if ref $origin;
+	  print STDERR 'REL: ',$origin,"\n" if $debug;
+	  next unless defined($urls{$tagname});
+	  foreach $attr (@{$urls{$tagname}}) {
+	    $attrval{$attr} =~ s/^$origin//
+	      if defined($attrval{$attr});
+	  }
+	} elsif ($arg == $URLSUB) {
+	  $RE=$_[$i++];
+	  $subst=$_[$i++];
+	  warn "URLSUB: $RE -> $subst\n" if $debug;
+	  next unless defined($urls{$tagname});
+	  foreach $attr (@{$urls{$tagname}}) {
+	    $attrval{$attr} =~ s/$RE/$subst/
+	      if defined($attrval{$attr});
+	  }
+	} elsif ($arg == $LIST) {
+	  warn "LIST;\n" if $debug;
+	  next unless exists($urls{$tagname});
+	  foreach $attr (@{$urls{$tagname}}) {
+	    if (exists($attrval{$attr})) {
+	      $attrval{$attr}.='/'
+		if $isdir{$attr} && $attrval{$attr} =~ m~[^/]$~;
+	      push(@urllist,$attrval{$attr});
+	    }
+	  }
+	} elsif ($arg == $SAVEURL) {
+	  warn "SAVEURL;\n" if $debug;
+	  $prefix=$_[$i++];
+	  next unless exists($urls{$tagname});
+	  foreach $attr (@{$urls{$tagname}}) {
+	    $attrval{"$prefix$attr"}=$attrval{$attr}
+	      if defined($attrval{$attr});
+	  }
+	} elsif ($arg == $USESAVED) {
+	  warn "USESAVED;\n" if $debug;
+	  $prefix=$_[$i++];
+	  next unless exists($urls{$tagname});
+	  foreach $attr (@{$urls{$tagname}}) {
+	    $attrval{$attr}=$attrval{"$prefix$attr"}
+	      if (defined($attrval{"$prefix$attr"}));
+	    # bug compatability, drop sometime after w3mir 1.0
+	    $attrval{$attr}=$attrval{"$prefix-$attr"}
+	      if (defined($attrval{"$prefix-$attr"}));
+	  }
+	} elsif ($arg == $NODOC) {
+	  warn "NODOC;\n" if $debug;
+	} elsif ($arg == $CANON) {
+	  warn "CANON;\n" if $debug;
+	} elsif ($arg == $URLPROC || $arg == $NREL) {
+	  # Apply a function to all urls.
+	  # NREL = Special case of $URLPROC, apply internal function.
+	  if ($arg == $URLPROC) {
+	    warn "URLPROC;\n" if $debug;
+	    $fun=$_[$i++];
+	    $arg=$_[$i++];
+	  } else {
+	    $fun=\&smartrel;
+	    $arg=undef;
+	    $url_origin=$_[$i++];
+	    $doc_top=$_[$i++];
+	    $doc_top_re=quotemeta $doc_top;
+	    ($choped_url_or=$url_origin) =~ s/^$doc_top_re//;
+	    warn "NREL $url_origin $doc_top\n" if $debug;
+	  }
+
+	  next unless (defined($urls{$tagname}));
+
+	  foreach $attr (@{$urls{$tagname}}) {
+	    $attrval{$attr}=&$fun($attrval{$attr},$arg)
+	      if defined($attrval{$attr});
+	  }
+	} elsif ($arg == $TAGCALLBACK) {
+	  $fun=$_[$i++];
+	  $arg=$_[$i++];
+	  warn "TAGCALLBACK($tagname);\n" if $debug;
+	  &$fun($arg,$baseurl,$tagname, 
+		(defined($urls{$tagname})?($urls{$tagname}):undef),
+		\%attrval);
+	} else {
+	  print STDERR "Internal error. opcode: $arg, i: $i, args: ",
+	  join(',',@_),"\n";
+	}
+      }
+      last;
+    }
+
+    # That ends URL processing
+
+    # Was this a verbatim leadin tag?  If yes, atempt to fish out text
+    # between here and the end tag, (minimal match) and substitute it
+    # with nothing.  The end tag is kept.  And the fished out text is
+    # re-inserted in the result with no changes.
+
+    $verbatim=$1 
+      if defined($verbatim{$tagname}) &&
+	($doc =~ s/^(.*?)($verbatim{$tagname})/$2/is);
+    
+    # Tack on the tag, if wanted.
+    if ($retdoc) {
+      if ($tagname) {
+	$newdoc.='<'.$tagname;
+	foreach $attr (keys %attrval) {
+	  $newdoc.=' '.$attr;
+	  if (defined($cont=$attrval{$attr})) {
+	    $Q='"';
+	    $Q="'" if $cont =~ m/\"/;
+	    $newdoc.='='.$Q.$cont.$Q;
+	  }
+	}
+	$newdoc.='>'.$verbatim;
+	$verbatim='';
+      }
+    }
+    print STDERR "NEW: $newdoc\n" if $debug > 2;
+  }
+  $newdoc.="</HTML>\n" if ($canon && !$endhtml);
+  return ($newdoc,@urllist);
+}
+
+
+sub smartrel {
+  # 'smart' relativisation function, uses .. to refer to things up to
+  # $doc_top level.  Outside that scope it stays absolute.
+  #
+  # The rel function itself is now in libwww-perl
+  
+  my($url_o)=@_;
+
+  return if (!(defined($url_o) && $url_o));
+  
+  $url_o=url $url_o unless ref $url_o;
+
+#  print STDERR "\nsmartrel: $url_o->as_string\n",
+#                 "    from: $url_origin\n",
+#                 "  within: $doc_top\n";
+  
+  # Check if within scope of our doc
+  $url_o = $url_o->rel($url_origin)
+    if $url_o->as_string =~ m/^$doc_top_re/;
+
+  return $url_o->as_string;
+}
+
+
+sub smart_setup {
+  # Setup routine for smartrel.
+
+  ($url_origin,$doc_top) = @_;
+
+  $url_origin=$url_origin->as_string if ref $url_origin;
+  $doc_top=$doc_top->as_string if ref $doc_top;
+
+  $doc_top_re=quotemeta $doc_top;
+
+  ($choped_url_or=$url_origin) =~ s/^$doc_top_re//;
+}
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/install.sh
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/install.sh	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/install.sh	(revision 20131)
@@ -0,0 +1,9 @@
+#!/bin/sh -v
+
+export PERL5LIB=$GSDLHOME/perllib/cpan/lib:$PERL5LIB
+export PATH=$GSDLHOME/perllib/cpan/bin:$PATH
+
+perl Makefile.PL PREFIX=$GSDLHOME/perllib/cpan
+
+make
+make install
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/multiscope.cfg
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/multiscope.cfg	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/multiscope.cfg	(revision 20131)
@@ -0,0 +1,46 @@
+# This file is meant to illustrate multiscope retrival.
+#
+# Available options: recurse, no-date-check, only-nonexistent, list-urls,
+# lowercase.  It is not default to recurse.  options must be the 
+# first directive in the the config file.
+Options: recurse
+# This directive was previously known as 'Fetch-options'
+#
+# This is the two argument form of URL:.  It fetches the first into the second
+URL: http://www.math.uio.no/~janl/ math/janl
+#
+# These says that any documents refered to that lives under these places
+# should be gotten too.  Into the named directories.  Two arguments are
+# required for 'Also:'.
+Also: http://www.math.uio.no/drift/personer/ math/drift
+Also: http://www.stud.ifi.uio.no/~janl/ ifi/janl
+Also: http://www.mi.uib.no/~nicolai/ math-uib/nicolai
+#
+# A more typical use would perhaps be:
+#   URL: http://www.math.uio.no/~janl/ janl
+#   Also: http://www.math.uio.no/images/ images
+# which would retrive the images refered to under
+# http://www.math.uio.no/~janl/ into a directory called images
+#
+# CD here before doing any work
+#cd: janlhomes
+#
+# Default pause is now 0.
+#Pause: 0
+#
+# Ignore urls we can't copy anyway.  Actually w3mir can copy
+# many cgi things with no problems.  But not always.
+Ignore: *.cgi
+Ignore: *-cgi
+Ignore: *.map
+#
+# Run fixup to get a filesystem browseable mirror
+Fixup: run
+# The options above will result in this directory hierarchy under
+# where you started w3mir:
+#
+# w3mir/math/janl		files from http://www.math.uio.no/~janl
+# w3mir/math/drift		from http://www.math.uio.no/drift/personer/
+# w3mir/ifi/janl		from http://www.stud.ifi.uio.no/~janl/
+# w3mir/math-uib/nicolai	from http://www.mi.uib.no/~nicolai/
+#
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3http.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3http.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3http.pm	(revision 20131)
@@ -0,0 +1,765 @@
+# -*- perl -*-
+# w3http.pm	--- send http requests, janl's 12" mix for w3mir
+#
+$VERSION=1.0.22;
+#
+# This implements http/1.0 requests.  We'll have problems with http/0.9
+# This is in no way specific to w3mir.
+#
+# IMPORTANT: The caller should initialize the C locale for some of the
+#   things here to work correctly (specifically the strftime function).
+#
+# This is a rewrite of http.pl by Oscar Nierstrasz; I copied the code he he
+# copied from the camel book.  Some functions written by Gorm Haug Eriksen
+# (gorm@usit.uio.no) has been used as is.
+#
+# Contributors:
+#   Nicolai Langfeldt, janl@ifi.uio.no
+#   Gorm Haug Eriksen, gorm@usit.uio.no
+#   Chris Szurgot, szurgot@itribe.net
+#   Bernhard Weisshuh, bkw@weisshuhn.de
+# Copying and modification is governed by the "Artistic License" enclosed in
+# the w3mir distribution
+#
+# gorm :
+# &w3http::get_last_modified  return the last modified stamp on a file in
+#                         the right format for use with http
+#
+# janl:
+# &http::query: Send a http query.  A completely general function to send a
+#   http query.  Will extract header values, http response code and, optionaly,
+#   convert text files to local linefeed format.
+#
+# Variables to examine after a query
+# $w3http::document: The document returned by the query, if any.
+# $w3http::doclen: The length of the document
+# $w3http::result: The numerical http result code.  It may take these values:
+# - Normal HTTP reply codes
+# -  98: OS error, permanent, errormessage in $!
+# -  99: Other permanent error: see $restext.
+# - 100: Transient error: Timeout/connection broken
+# $w3http::restext: The english(?) HTTP result or w3http generated message
+# $w3http::header: The http header returned.
+# $w3http::plaintexthtml: 1 if this doc is non-content-encoded text/html
+#	(as opposed to content-encoding: compressed content-type: text/html
+#       which needs decompression before we can inspect the html) 
+#	The tests are somewhat longwinded so I do it just once here.
+# %w3http::headval: Associative array of header values
+# $w3http::headval{'CONTENT-TYPE'}: Derived content type, stripped of charset
+#		qualifiers and other distractions.
+# $w3http::xfbytes: Transfered bytes, cumulative.  Document part only.
+# $w3http::headbytes: Bytes of headers received, cumulative.
+#
+# Variables that change http's behaviour/requests:
+# $w3http::agent: User agent, default is basename of $0
+# $w3http::from: Request is from, default is user@host
+# $w3http::version: The http version to use, only 1.0 is known to me.
+# $w3http::timeout: How long to wait for new data to arrive, default is 600sec
+# $w3http::buflen: Network read buffer size, default is 4096.  It might give a
+#	speedup to tune this for specific servers' so it matches their send
+#	size.  This size can be detected if we want to, I think.
+# $w3http::debug: 1 debuging output, 2, more, 3 queries and replies
+# $w3http::verbose: 0: say nothing, 1: print progress info
+# $w3http::convert: Convert text/* documents to local newline convention?
+#	The default is to do it.
+# $w3http::proxyserver: The name of the proxyserver to use.
+# $w3http::proxyport: The port of the proxyserver to use. 0 if no proxyserver.
+# $w3http::proxyuser: If this is set proxy authentication will be used.
+# $w3http::proxypasswd: The password for proxy authentication
+#
+# Things gotten from main:
+# - $main::win32: 1 if win32 restrictions apply to this system
+# - $main::nulldevice: Bit sink file/device on this system.
+#
+# History (european date format dd/mm/yy):
+#     janl ??/??/95 -- Rewrite finished
+#  szurgot ??/??/95 -- Win32 compatability
+#     janl 16/05/96 -- Added SAVEBIN option, based on idea by szurgot
+#  szurgot 03/05/96 -- Corrected typo in check for content-length against
+#                      retreive document length. Added test for zero-length
+#		       documents (Not retreived because not-modified)
+#  szurgot 19/05/96 -- Win32 adaptions, fixes.
+#     janl 19/05/96 -- Chris won an argument, and janl simplified http 
+#		       retrival loop (-> version 1.0.4)
+#     janl 09/09/96 -- Incorporated a patch submited by Michael Kriby -> 1.0.5
+#     janl 16/09/96 -- Support for authorization. -> 1.0.6
+#     janl 27/09/96 -- Support for Accept header, lack pointed out by
+# 			charles@ermine.ox.ac.uk: ... HTTP/1.1 (§14.1) says 
+#			``If no Accept header field is present, then it is
+#			assumed that the client accepts all media types,
+#			earlier versions of the protocol suggest that only
+#			text/plain and text/html will be offered by default.''
+#			This contradicts my memory of a http/1.0 draft.
+#			Also added $ACCEPT option.
+#     janl 20/10/96 -- Now uses HTTP::Date to produce HTTP timestamps -> 1.0.7
+#     janl 27/10/96 -- Didn't use to check if gethostbyname worked -> 1.0.8
+#     janl 02/12/96 -- Forgot a unlink when renaming temporary files.
+#     janl 21/02/97 -- Multipele $ACCEPT options work. -> 1.0.9
+#     janl 19/03/97 -- Now issues Host: header -> 1.0.10
+#     janl 10/04/97 -- Changed from wwwurl to URI::URL, and various related
+#                      changes. -> 1.0.11
+#     janl 09/05/97 -- Microsoft ISS servers are _so_ broken -> 1.0.12
+#                      (don't close the write end of the HTTP socket after
+#			sending a query to them)
+#     janl 12/05/97 -- New version of perl caught some typos, fixed
+#			longstanding bug in the newline conversion bit.
+#			-> 1.0.13
+#     janl 06/06/97 -- Demand Loading of MIME::BASE64 -> 1.0.14
+#     janl 01/12/97 -- FAT filesystems drops LSB of modtime.  Patch from
+#			Greg Lindhorst (gregli@microsoft.com)
+#                   -- whoami does not exist on win32, hardwire a default
+#			value (unknown) (also Greg L.) -> 1.0.15
+#     janl 01/22/98 -- Proxy authentication as outlined by Christian Geuer
+#     janl 02/20/98 -- Complex 'content-type' headers handled. -> 1.0.17
+#     janl 04/20/98 -- Only newline convert text/html, everything else is
+#			handled as binary. -> 1.0.18
+#     janl 12/05/98 -- Store tmpfile in its final destination directory
+#			avoiding asking movefile move it across filesystems.
+#			-> 1.0.19
+#     janl 01/08/98 -- Timeout fix from Michael Gusev, also flag short doc
+#			as error.
+#     janl 24/09/98 -- Better error handling -> 1.0.20
+#     bkw  17/12/98 -- Fixed problem with tempfile-generation when
+#                      running in forget-mode (-f)
+#     janl 05/01/99 -- Referer: dropped if argument not true -> 1.0.21
+#     janl 13/04/99 -- Added workaround for broken win32 perl resolving.
+
+package w3http;
+
+require 5.002;
+use Socket;
+use HTTP::Date;
+use Sys::Hostname;
+use URI::URL;
+
+# Suplementary libwww-perl:
+sub URI::URL::_generic::basename {
+  my $self = shift;
+  my @p = $self->path_components;
+  my $old = $p[-1];
+  if (@_) {
+    splice(@p, -1, 1, shift);
+    $self->path_components(@p)
+  }
+  $old;
+}
+
+
+END { 
+  # Remove tmp file and such in here.  That means that main:: gotta catch
+  # interrupt signals and exit on them, so ENDs are executed.
+}
+
+use strict;
+# Global variables, we want to share them:
+use vars qw($GET $HEAD $GETURL $HEADURL $IFMOD $IFMODF $AUTHORIZ $REFERER);
+use vars qw($SAVEBIN $ACCEPT $NOUSER $FREEHEAD $agent $version $timeout);
+use vars qw($debug $convert $proxyserver $proxyport $xfbytes $headbytes);
+use vars qw($verbose $result $restext $header $document);
+use vars qw($plaintexthtml %headval $progress $doclen $proxyuser);
+use vars qw($proxypasswd);
+
+my $hasAlarm;   # Win32 does not have any alarm
+my $chime;	# Has the alarm gone off yet?
+my %address;	# My own DNS cache
+my $savALRM;	# Saved ALRM handler
+my $savPIPE;	# Saved PIPE handler
+
+# The main:: program should detect if we're running on win32 or not,
+# somehow
+if ($main::win32) {
+  warn "win32\n";
+  # Compensate for lacks of win32 perl. 
+  $hasAlarm=0;
+  # Seems to be unavailable in win32/perl5.001.  It has to be in 5.003!
+#  eval "sub sockaddr_in {
+#	($port, $thataddr) = @_;
+#	$sockaddr = 'S n a4 x8';
+#	return pack($sockaddr, &AF_INET, $port, $thataddr);
+#    }";
+} else {
+  $hasAlarm=1;
+}
+
+
+# Find out some things
+my $thishost = hostname();
+my $proto = getprotobyname("tcp");
+
+(my $name, undef) = gethostbyname($thishost);
+chomp(my $user = $ENV{'LOGNAME'} || $ENV{'USER'} || `whoami` || 'unknown');
+my $from   = "$user\@$name";
+
+my $nl = "\r\n";
+# Default values, change by assignment in using-program.
+$agent  = $0; $agent =~ s~.*/~~; # Basename 
+$version= "1.0";
+$timeout= 600;			# Timeout while waiting for data/connection
+my $buflen = 4096;		# recv buffer length
+$debug = 0;			# Debuging output?
+$convert = 1;			# Convert newlines of text docs to local format
+$proxyserver='';		# Proxy server.
+$proxyport=0;			# Proxy server port. 0 if no proxy.
+$proxyuser='';			# Username for proxy authentication
+$proxypasswd='';		# Password for proxy authentication
+$xfbytes=0;			# 0 bytes transfered, cumulative
+$headbytes=0;			# 0 bytes of headers, cumulative
+$doclen=0;			# 0 bytes in doc, pr. document
+my $tmpfile="w3mir$$.tmp";	# Temporary filename
+$verbose=0;			# Verbosenes, 0: silent, 1: progress info
+
+# Query opcodes
+$GET = 1;			# GET query. Arg: host,port,path
+$HEAD = 2;			# HEAD query. Arg: host,port,path
+$GETURL = 3;			# GET query. Arg: url
+$HEADURL = 4;			# HEAD query. Arg: url
+# Here we lack PUT, which is not implemented
+# Modify query thus:
+$IFMOD = 101;			# If-modified after: Arg: HTTP-date-str
+$IFMODF = 102;			# If-modified after file: Arg: local-file-name
+$AUTHORIZ= 103;			# Basic authorization. Arg: 'user:password'
+$REFERER = 104;			# Referer: Arg: Referer 
+$SAVEBIN = 105;			# Write binary files to disk. Arg: File name
+				# If this opcode is used then main must provide
+				# a &main::movefile(oldname,newname) procedure
+				# that handles moving the tmp file to the
+				# final name/location.
+$ACCEPT  = 106;			# Accept header value: Arg: value
+$NOUSER  = 107;			# Don't insert user header.  Arg: none
+$FREEHEAD= 999;			# Freeform header, one line.  Arg: header
+
+sub query {
+  # Build and send a HTTP query.  And also receive response - janl 95/09/18
+  #
+  # Return codes: 0 if it didn't work.  1 if it did work.
+  # HTTP style result code in w3http::$result and message in w3http::$restext
+  
+  # We do next to no argument type checking btw.
+  
+  my($host,$port,$request,$query,$method,$inp,$linp,$saveto,$save,$arg);
+  my($start,$wantbytes,$thataddr,$err,$headb,$tmpf,$ldoc,$nouser,$q,$accept);
+  my($origreq,$req_o,$plaintext);
+  
+  # Something ought to be said
+  $result=99;
+  $restext='w3http: internal error';
+  $nouser=0;
+  
+  if ($version ne '1.0') {
+    warn "Unknown HTTP version $version, no request sent\n";
+    return 0;
+  }
+  
+  $accept=$saveto=$query='';
+  
+  # Find out what to ask for
+  
+  while (defined($arg=shift)) {
+    if ($arg == $GET) {
+      $host=shift;
+      $port=shift;
+      $request=shift;
+      $req_o=url 'http://'.$host.':'.$port.$request;
+      if ($proxyport) {
+	$query.='GET http://'.$req_o->as_string;
+      } else {
+	$query.='GET '.$req_o->epath;
+      }
+      $query.=' HTTP/'.$version.$nl;
+    } elsif ($arg == $HEAD) {
+      $host=shift;
+      $port=shift;
+      $request=shift;
+      $req_o=url 'http://'.$host.':'.$port.$request;
+      if ($proxyport) {
+	$query.='HEAD '.$req_o->as_string;
+      } else {
+	$query.='HEAD '.$req_o->epath;
+      }
+      $query.=' HTTP/'.$version.$nl;
+    } elsif ($arg == $GETURL) {
+      $req_o=shift;
+      $req_o=url $req_o unless ref $req_o;
+      ($method,undef,undef,$host,$port,$request,undef,$q) = $req_o->crack;
+      if ($proxyport) {
+	$query.='GET '.$req_o->as_string;
+      } else {
+	$q=$req_o->equery;
+	$query.='GET '.$request.($q?"?$q":'');
+      }
+      $query.=' HTTP/'.$version.$nl;
+    } elsif ($arg == $HEADURL) {
+      $req_o=shift;
+      $req_o=url $req_o unless ref $req_o;
+      if ($proxyport) {
+	$query.='HEAD '.$req_o->as_string;
+      } else {
+	$q=$req_o->equery;
+	$query.='HEAD '.$req_o->epath.($q?"?$q":'');
+      }
+      $query.=' HTTP/'.$version.$nl;
+    } elsif ($arg == $IFMOD) {
+      $query.='If-Modified-Since: '.(shift).$nl;
+    } elsif ($arg == $IFMODF) {
+      $query.='If-Modified-Since: '.&last_modified(shift).$nl;
+    } elsif ($arg == $AUTHORIZ) {
+      # Demand-load MIME::Base64
+      if (!defined(&MIME::Base64::encode)) {
+	eval "use MIME::Base64;";
+	die "w3http: Could not load MIME::Base64 module necessary for authentication\n"
+	  unless defined(&MIME::Base64::encode);
+      }
+      $query.='Authorization: Basic '.MIME::Base64::encode(shift,'').$nl;
+    } elsif ($arg == $REFERER) {
+      my($referer)=shift;
+      $query.='Referer: '.$referer.$nl if $referer;
+    } elsif ($arg == $SAVEBIN) {
+      $saveto=shift;
+    } elsif ($arg == $ACCEPT) {
+      $accept.='Accept: '.(shift).$nl;
+    } elsif ($arg == $NOUSER) {
+      $nouser=1;
+    } elsif ($arg == $FREEHEAD) {
+      $query.=(shift).$nl;
+    } else {
+      warn "Unknown http query opcode: $arg\n";
+    } 
+    # Insert the last parts of the query:
+  }
+  
+  $query.='Host: '.$req_o->netloc.$nl;
+  $query.='From: '.$from.$nl unless $nouser;
+
+  $accept='Accept: */*'.$nl unless $accept;
+
+  if ($proxyport) {
+    # Use proxy instead of originserver
+    $host=$proxyserver;
+    $port=$proxyport;
+
+    # Add authentication stuff to query
+    if ($proxyuser) {
+      # Demand-load MIME::Base64
+      if (!defined(&MIME::Base64::encode)) {
+	eval "use MIME::Base64;";
+	die "w3http: Could not load MIME::Base64 module necessary for authentication\n"
+	  unless defined(&MIME::Base64::encode);
+      }
+      
+      $query.='Proxy-Authorization: Basic '.
+	MIME::Base64::encode($proxyuser.':'.$proxypasswd);
+
+      print STDERR "\nProxyuser: [$proxyuser]\nProxypasswd: [$proxypasswd]\n"
+	if $debug>=2;
+    }
+  }
+  
+  $query.='User-Agent: '.$agent.$nl.$accept.$nl;
+  
+  # If we're using proxy then set up things...
+  print STDERR "\nQUERY:\n",$query,"---\n" if $debug>=2;
+
+  # win32 fix: this should be added in case of troubles with
+  # gethostbyname. possible reason: nameserver down?
+  if ($host =~ /^\d+(\.\d+){3}$/) {
+    # in case gethostbyname will not work ... ;-)
+    $address{$host} = pack 'C4', (split /\./, $host);
+  }
+  
+  # Find out who to ask, check if we know already
+  if (exists($address{$host})) {
+    # We know
+    $thataddr=$address{$host};
+  } else {
+    # Cache miss, get and remember.
+    (my $fqdn, undef, undef, undef, $thataddr) = gethostbyname($host);
+    # Hostname lookup failure?  Cache even misses.
+    if (defined($fqdn)) {
+      print STDERR "Lookup of $host:\nFQDN: $fqdn\n"
+	if $debug;
+      $address{$host}=$thataddr;
+      $address{$fqdn}=$thataddr if $fqdn ne $host;
+    } else {
+      $thataddr=$address{$host}=undef;
+    }
+  }    
+
+  # Check if lookup failure, return
+  if (!defined($thataddr)) {
+    $restext='Host lookup failure';
+    return;
+  }
+
+  $port=80 unless defined($port) && $port;
+
+  # When connected we might receive SIGPIPE.  I'm not sure if the
+  # default behaviour of dying is beneficial in that case.  If we get
+  # alarm a timeout has expired.
+  $savPIPE = $SIG{'PIPE'};
+  $savALRM = $SIG{'ALRM'};
+
+  $chime=0;			# There has been no alarm yet
+  $SIG{'ALRM'} = \&timeout;
+  $SIG{'PIPE'} = \&ignore;
+
+  # Close the socket, just in case, and ignore error returns
+  close(FS);
+  
+  socket(FS, AF_INET, SOCK_STREAM, $proto) or return &oserror;
+  warn "Got my socks on\n" if $debug;
+  
+  my $paddr = sockaddr_in($port, $thataddr);
+  connect(FS, $paddr) or return &oserror;
+  warn "Connected\n" if $debug;
+  
+  # Arrange timeout
+  alarm($timeout) if $hasAlarm;
+  
+  # We have, in fact, received SIGPIPE on this line:
+  send(FS,$query,0) or return &oserror;
+
+  if ($chime) {
+    $result=100;
+    $restext='timeout sending query';
+    return &resetsign;
+  }
+  
+  $header='';
+  $document='';
+  $inp=' 'x$buflen;
+  $doclen=$chime=$plaintext=$plaintexthtml=$save=0;
+
+  # Breaks some M$ ISS servers:
+  # shutdown(FS,1);  # Half-close socket, sending now not allowed
+  
+  print STDERR ", receiving header" if $verbose>0;
+  
+  # Retrive HTTP response HEADER.  Why do I use recv and not <FS>?
+  # Because then the timeout can work correctly!
+  while (1) {
+    # Set up alarm to ensure recv returns within a reasonable timeframe
+    alarm($timeout) if $hasAlarm;
+    $err = recv(FS,$inp,$buflen,0);
+    # recv returned, cancel alarm.
+    alarm(0) if $hasAlarm;
+    
+    # If there has been a timeout, then we quit now.  The recv man page
+    # does not seem to allow recv to return the bytes received up to
+    # the timeout.
+    if ($chime) {
+      $result=100;  
+      $restext='timeout fetching document';
+      $!=0;
+      if ($save) {
+	unlink($tmpf) || 
+	  warn "Could not unlink $tmpf: $!\n";
+      }
+      return &resetsign;
+    }
+    
+    # recv returnes the undefined value on error
+    if (!defined($err)) {
+      warn "Error in recv: $!\n";
+      last;
+    }
+    
+    $linp=length($inp);
+    
+    # If the returned input was 0 in length then we've gotten to the 
+    # end of the response.
+    last unless $linp;
+    
+    # Accounting
+    $xfbytes += $linp;
+    $doclen += $linp;
+    
+    # Accumulate input
+    $header.=$inp;
+
+    # eof(SOCKET) has strange semantics it seems
+    # last if eof(FS);
+    
+    # Check if header is complete
+    last if ($header =~ m/(\r?\n\r?\n)/);
+  }
+  
+  if (length($header)==0) {
+    $restext='the HTTP reply header is empty!';
+    return &resetsign;
+  }
+  
+  if ($header =~ m/(\r?\n\r?\n)/) {
+    $header=$`;
+    $document=$';
+  } else {
+    $header=$document;
+  }
+  
+  # Adjust accounting
+  $headb = length($header)+length($1);
+  $headbytes += $headb;
+  $xfbytes -= $headb;
+  $doclen -= $headb;
+  
+  # Pick headers to pieces
+  ($result,$restext,%headval)=&analyze_header($header);
+
+  print STDERR "REPLY:\n",$header,"\n---\n" if $debug>=2;
+
+  # Check if the document is a non-encoded text document. The contents
+  # could be (x-)?compress or (x-)gzip coded (compressed in other
+  # words).
+  
+  $plaintext=defined($headval{'CONTENT-TYPE'}) &&
+    (substr($headval{'CONTENT-TYPE'},0,5) eq 'text/' || 0) &&
+      !defined($headval{'content-encoding'});
+  $plaintexthtml=$plaintext && 
+    ($headval{'CONTENT-TYPE'} eq 'text/html');
+  
+  if ($result==200) {
+    
+    # Save this to a file, or not?  Never save html files.
+    if ($saveto && !$plaintexthtml) {
+      # We're going to save this document directly into a file.  This
+      # stresses the VM less when getting the large binares so often
+      # found at cool sites.
+      $save=1;
+
+      # Find a temporary filename
+      $tmpf=url "file:$saveto";
+      $tmpf->basename($tmpfile);
+      $tmpf=$tmpf->unix_path;
+      
+      # Find suitable final filename, one with no URL escapes
+      $saveto=(url "file:$saveto")->unix_path;
+
+      # If output to stdout then send it directly there rather than
+      # using disk unnecesarily.
+      $tmpf='-' if ($saveto eq '-');
+
+      # If output is nulldevice (running -f), use it also for tmpfile,
+      # since it would otherwise try to create it in /dev under unix.
+      $tmpf=$main::nulldevice if ($saveto eq $main::nulldevice);
+      
+      warn "USING TMPFILE: $tmpf\n" if $debug;
+      
+      open(SAVE,">$tmpf") || 
+	die "Could not open tmp file: $tmpf: $!\n";
+      binmode SAVE;		# It's a binary file...
+    }
+    
+    if ($verbose>0) {
+      print STDERR ", document";
+      print STDERR "->disk" if $save;
+    }
+    
+    # Now retrive document itself.  Se comments in header loop
+    $start=time;
+    $wantbytes = defined($headval{'content-length'})?
+      $headval{'content-length'}:0;
+    
+    $ldoc=length($document);
+    
+    while (1) {
+      alarm($timeout) if $hasAlarm;
+      recv(FS,$inp,$buflen,0);
+      alarm(0) if $hasAlarm;
+      
+      if ($chime) {
+	$result=100;
+	$restext='timeout fetching document';
+	$!=0;
+	if ($save) {
+	  unlink($tmpf) || 
+	    warn "Could not unlink $tmpf: $!\n";
+	}
+	return &resetsign;
+      }
+      
+      $linp=length($inp);
+      
+      last unless $linp || $ldoc;
+      $ldoc = 0;
+      
+      $xfbytes += $linp;
+      $doclen += $linp;
+      
+      if ($verbose>0 && time-$start>5) {
+	# Write progress info ... 
+	if ($wantbytes) {
+	  $progress = sprintf " %3d%%", $doclen/$wantbytes*100;
+	} else {
+	  $progress = sprintf " %d", $doclen;
+	}
+	print STDERR $progress, "\ch"x(length($progress));
+	# ...every 5 seconds
+	$start=time;
+      }
+      
+      $document.=$inp;
+      
+      if ($save) {
+	$err = print SAVE $document;
+	die "Error writing $tmpf: $!\n" unless $err;
+	$document='';
+      }
+
+      # The eof test seems to work very oddly for sockets.
+      # last if eof(FS);
+    }
+
+    close(FS);  # Close socket completely
+    
+    print STDERR "DOCUMENT:\n----\n",$document,"\n----\n" if $debug>=255;
+  
+    if ($wantbytes &&
+	$wantbytes != $doclen) {
+      $result=100;
+      $restext='transfer error; too many bytes in document';
+      $restext='document was incomplete' if ($wantbytes > $doclen) ;
+      print STDERR "SHORT DOCUMENT" if $debug>=16;
+      if ($save) {
+	unlink($tmpf) || warn "Could not unlink $tmpf: $!\n";
+      }
+      return &resetsign;
+    }
+    
+    # warn "XFB: $xfbytes, DL: $doclen\n";
+    if ($save) {
+      close(SAVE);
+      &main::movefile($tmpf,$saveto);
+    }
+    
+    # If this is a non-encoded text file and we're supposed to convert
+    # foreign newlines then we do it. It would be faster to do this
+    # with each chunk of input in the input loop, but this gives us
+    # two problems:
+    # - A \r\n newline could be split into two chunks.  Thus escaping
+    #   newline conversion.
+    # - It messes up the received bytes accounting rather badly.
+    #
+    # This used to be a test for $plaintext, the problem is that too
+    # many documents were typed as text/plain and so we corrupted
+    # binary files. This is bad. So now we're more paranoid about it:
+    # Only HTML gets converted.
+    if ($convert && $plaintexthtml) {
+      # Change non unix newlines to unix newlines. bare \r is known
+      # from macintosh (they hadta be different didn't they?), \r\n is
+      # known as 'network format' and from numerous systems, among
+      # them ms-dos.
+      $document =~ s~\r~\n~g unless $document =~ s~\r\n~\n~g;
+      warn "Newlines converted(?)\n" if $debug;
+    }
+    
+  }				# if $result == 200
+  
+  &resetsign;
+  return 1;
+}
+
+
+sub analyze_header {
+  my($header)=@_;
+  my($result,$restext,%headval,$hdln,$key,$value);
+  
+  # Summary of the http spec on headers (with my comments):
+  # - Each header line ends in CRLF (or just LF, or maybe even just CR,
+  #   anyways, it's easier if all is LF).
+  $header =~ s/\r/\n/mg unless $header =~ s/\r\n/\n/mg;
+  # - If a line starts with space then it's a continuation of the previous
+  #   line (these I fold into one line).
+  $header =~ s/\n\s/ /mg;
+  # - The header field names are case insensitive (so I convert them to
+  #   lowercase)
+  # - A field may appear twice, that is equivalent to listing the values
+  #   in a comma separated list (so I fold them into a comma separated list)n
+  # - The field name and the field value are separated by ': '
+  ($result,$restext) = $header =~ m~^HTTP/\d\.\d (\d\d\d) (.*)~;
+  # Shave off http result code from the header
+  $header =~ s~^.*\n~~;
+  
+  warn "Header:\n$header\n---\n" if $debug>=3;
+  
+  warn "Result: $result, Text: $restext\n" if $debug>=2;
+  
+  %headval=();
+  
+  foreach $hdln (split(/\r?\n/m,$header)) {
+    ($key,$value)=split(': ',$hdln,2);
+    $key="\L$key";
+    # Strip leading&trailing space off the reply, some servers use
+    # copious space after.
+    $value =~ s/^\s+|\s+$//g;
+    print STDERR "K: '$key', V: '$value'\n" if $debug>=2;
+    if (defined($headval{$key})) {
+      $headval{$key}.=", ".$value;
+    } else {
+      $headval{$key}=$value;
+    }
+  }
+
+  # See if there are any type parameters in the content-type header
+  # and if so remove them.
+  if (defined($headval{'content-type'})) {
+    my $val=$headval{'content-type'};
+    ($val,undef)=split(';',$val,2) if ($val =~ /;/);
+    $headval{'CONTENT-TYPE'}=$val;
+  }
+  
+  return ($result,$restext,%headval);
+}
+
+
+sub last_modified {
+  # will return the last modified time for a local file as a HTTP
+  # timestamp.
+  
+  my(@tmp) = stat($_[0]);	# file doesn't exist ok to fetch
+
+  # FAT file systems strip the LSB of the file time.  Add it back in
+  # here before asking the server about a modified file.  The only way
+  # this can fail is if the newer server file was saved one second
+  # after the first version (very unlikely).  This isn't needed for
+  # NTFS file systems, but there is no good portable Perl way to
+  # determine the file system type.
+  $tmp[9] = $tmp[9] | 1 if ( $main::win32 );
+
+  # now we got the last modified in a 32 bit integer.  time to convert
+  # it and return
+  return time2str($tmp[9]);
+}
+
+
+sub timeout {
+  # Set timeout flag.  The using procedure has to set other result codes.
+  $chime=1;			# When this is 1 then the alarm has gone off
+  print STDERR "TIMEOUT!!!!\n" if $debug>=16;
+}
+
+
+sub ignore {
+  warn "I got SIGPIPE, ignoring it...\n";
+}
+
+
+sub resetsign {
+  return 0 if !defined($savALRM);
+  $SIG{'ALRM'}=$savALRM;
+  undef $savALRM;
+#  $SIG{'PIPE'}=$savPIPE;
+  return 0;
+}
+
+
+sub oserror {
+  
+  resetsign;
+
+  $result=98;
+  $restext='w3http: OS error';
+  return 0;
+
+}
+
+
+1;
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3mfix.PL
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3mfix.PL	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3mfix.PL	(revision 20131)
@@ -0,0 +1,1070 @@
+# -*-perl-*-
+
+use Config;
+
+&read_makefile;
+$fullperl = resolve_make_var('FULLPERL') || $Config{'perlpath'};
+$islib = resolve_make_var('INSTALLSITELIB');
+
+$name = $0;
+$name =~ s~^.*/~~;
+$name =~ s~.PL$~~;
+
+open(OUT,"> $name") || 
+  die "Could open $name for writing: $!\n";
+
+print "writing $name\n";
+
+while (<DATA>) {
+  if (m~^\#!/.*/perl.*$~o) {
+    # This substitutes the path perl was installed at on this system
+    # _and_ removed any (-w) options.
+    print OUT "#!",$fullperl,$1,"\n";
+    next;
+  }
+  if (/^use lib/o) {
+    # This substitutes the actuall library install path
+    print OUT "use lib '$islib';\n";
+    next;
+  }
+  print OUT;
+}
+
+close(OUT);
+
+# Make it executable too, and writeable
+chmod 0755, $name;
+
+#### The library
+
+sub resolve_make_var ($) {
+
+  my($var) = shift @_;
+  my($val) = $make{$var};
+
+#  print "Resolving: ",$var,"=",$val,"\n";
+  
+  while ($val =~ s~\$\((\S+)\)~$make{$1}~g) {}
+#  print "Resolved: $var: $make{$var} -> $val\n";
+  $val;
+}
+
+
+sub read_makefile {
+
+  open(MAKEFILE, 'Makefile') || 
+    die "Could not open Makefile for reading: $!\n";
+
+  while (<MAKEFILE>) {
+    chomp;
+    next unless m/^([A-Z]+)\s*=\s*(\S+)$/;
+    $make{$1}=$2;
+#    print "Makevar: $1 = $2\n";
+  }
+
+  close(MAKEFILE)
+}
+
+__END__
+#!/local/bin/perl5 -w
+# Perl 5.002 or later.  w3mir is mostly tested with perl 5.004
+#
+# You might want to change or comment out this:
+use lib '/hom/janl/lib/perl';
+#
+# Can perform the following fixes:
+# - Rewrite redirected to URLs
+# - change .../ into .../index.html (or .../Welcome.html)
+# - change external links to point to some helpfull .html file ---- NOT IMPLEMENTED
+# - change links to documents not retrived to point to some helpfull
+#   .html file --- NOT IMPLEMENTED
+# - After adding a 'Also' directive we can edit the urls pointing to within
+#   the new space of the retrival scope, making the pointers consistent.
+
+# Method: 
+# 1 Gather list of all URLs to be rewritten:
+#   - Redirects: Just read the .redirs file
+#   - .../ into .../index.html: All can be found in the .referers file
+#     Remember to rewrite missing / redirects too...
+#   - external links: in the .referers file too
+#   - non-retrived documents: What files should be here (according to
+#	.referers file) but are not?
+# 2 Gather list of all documents needing editing
+# 3 Edit them
+#
+# 09/05/98 janl		- Only rewrite .../ to .../$indexname if the attribute
+#			  does not refer to a directory. -> 0.6.2
+# 12/05/98 janl		- Use ->local_path to determine filename -> 0.6.3
+# 22/05/98 janl		- .../#foo was not being rewritten to 
+#			  .../$indexname#foo -> 0.6.4
+#
+require 5.002;
+
+use vars qw($win32);
+
+# To figure out what kind of system this is
+BEGIN {
+  use Config;
+  $win32 = ( $Config{'osname'} eq 'MSWin32' ); 
+}
+
+use Carp;
+use htmlop;
+use URI::URL;
+use URI::Escape;
+
+use strict;
+
+my $VERSION;
+$VERSION='0.6.5';
+
+my $debug=0;			# Not debugging
+my $verbose=0;
+
+my $indexname='index.html';
+my $chdirto='';			# Place to chdir to after reading
+                                # config file
+
+my $infoloss=0;			# 1 if any URL translations (which
+                                # cause information loss) are in
+                                # effect.  If this is true we use the
+                                # SAVEURL operation.  What to get, and
+                                # not.  Text of user supplied
+                                # fetch/ignore rules
+
+my $doindex=1;			# append $indexname to /$ ?
+
+my $editthis='';		# Edit references matching this expression.
+
+my $files=0;			# How many files have I edited?
+my $rc='';
+
+my $rule_text="# User defined fetch/ignore rules\n";
+# Code ref to the rule procedure
+my $rule_code;
+
+# Code to prefix and postfix the generated code.  Prefix should make
+# $_ contain the url to match.  Postfix should return 1, the default
+# is to get the url/file.
+my $rule_prefix='$rule_code = sub { local($_) = shift;'."\n";
+my $rule_postfix=' return 1; } ';
+
+# Scope tests generated by URL/Also directives in cfg. The scope code
+# is just like the rule code, but used for program generated
+# fetch/ignore rules related to multiscope retrival.
+my $scope_fetch="# Automatic fetch rules for multiscope retrival\n";
+my $scope_ignore="# Automatic ignore rules for multiscope retrival\n";
+my $scope_code;
+
+my $scope_prefix='$scope_code = sub { local($_) = shift;'."\n";
+my $scope_postfix=' return 0; } ';
+
+# Function to apply to urls, se rule comments.
+my $user_apply_code;	# User specified apply code
+my $apply_code;		# w3mirs apply code
+my $apply_prefix='$apply_code = sub { local($_) = @_;'."\n";
+my $apply_lc=' $_ = lc $_; ';
+my $apply_postfix=' return $_; } ';
+my @user_apply;		# List of users apply rules.
+my @internal_apply;	# List of w3mirs apply rules.
+
+
+my $iinline='';			# inline RE code to make RE caseinsensitive 
+my $ipost='';			# RE postfix to make it caseinsensitive
+my $lc=0;			# Convert urls/filenames to lowercase?
+my $abs=0;			# Absolutify URLs?
+my $fixrc='';			# Name of w3mfix config file
+my $fixup=0;			# Do things needed to run fixup
+my $r=0;			# Recurse? no recursion = absolutify links
+my %rum_referers=();		# Array of referers, key: rum_url
+my %rum_redirected=();		# Array of redirected url: key: original url
+my %lf_edited=();		# Edited this file yet?
+my $list;			# List url on STDOUT?
+
+my %stat=();			# stat($lf_url): 'd' for dir, 'f' for others
+
+# ######################### Libwww-perl addons:
+
+sub URI::URL::_generic::unix_path {
+  my $self = (shift)->clone;
+
+  $self->frag(undef);
+  $self->scheme("file");
+  $self->unix_path;
+}
+
+
+sub URI::URL::_generic::basename {
+  my $self = shift;
+  my @p = $self->path_components;
+  my $old = $p[-1];
+  if (@_) {
+    splice(@p, -1, 1, shift);
+    $self->path_components(@p)
+  }
+  $old;
+}
+
+
+sub URI::URL::_generic::path_components {
+    my $self = shift;
+    my $old = $self->{'path'};
+    $old = '' unless defined $old;
+    $old = "/$old" if $old !~ m|^/| && defined $self->{'netloc'};
+    if (@_) {
+	$self->_elem('path',
+		     join("/", map { uri_escape($_,$URI::URL::reserved)
+				   } @_));
+    }
+    map { uri_unescape($_) } split("/", $old, -1);
+}
+
+
+# ######################### Configuration/argument parsing
+
+sub parse_args {
+  my $f;
+  my $i;
+
+  $i=0;
+
+  while ($f=shift) {
+    $i++;
+    # This is a demonstration against Getopts::Long.
+    if ($f =~ s/^-+//) {
+      $verbose=-1,next if $f eq 'q'; 		# Quiet
+      $verbose=1,next if $f eq 'c';		# Chatty
+      die "w3mfix version $VERSION\n" if $f eq 'v';	# Version
+      die "rtfm\n" if ($f eq 'help' || $f eq 'h' || $f eq '?');
+
+      if ($f eq 'editref') {
+	die "Sorry, can only have one -editref pr. run\n"
+	  if $editthis;
+	$editthis=quotemeta(shift);
+	next;
+      }
+
+      if ($f eq 'd') {	# Debugging level
+	$f=shift;
+	unless (($debug = $f) > 0) {
+	  die "w3mfix: debug level must be a number greater than zero.\n";
+	}
+	next;
+      }
+
+      # Those were all the options...
+      warn "w3mfix: Unknown option: -$f.  Use -h for usage info.\n";
+      exit(1);
+    } else {
+      # If we get this far then ... it's a configuration file name:
+      $rc = $f;
+      die "w3mfix: Got a non-option argument that wasn't the name of a\n".
+	"(configuration) file either\n"
+	  unless -f $f;
+    }
+  }
+}
+
+
+sub parse_cfg_file {
+  # Read the configuration file.  Aborts on errors.
+  # Ignores w3mir options w3mfix does not need itself.
+
+  my ( $file ) = @_ ;
+  my ($key, $value, $authserver,$authrealm,$authuser,$authpasswd);
+  my $i;
+
+  die "w3mfix: config file $file is not a file.\n" unless -f $file;
+  open(CFGF, $file) || die "Could not open config file $file: $!\n";
+
+  # print STDERR "Reading $file\n";
+
+  $i=0;
+
+  while (<CFGF>) {
+    # Trim off various junk
+    chomp;
+    s/^#.*//;
+    s/^\s+|\s$//g;
+    # Anything left?
+    next if $_ eq '';
+    # Examine remains
+    $i++;
+    ($key, $value) = split(/\s*:\s*/,$_,2);
+    $key = lc $key;
+
+    # These are no-ops in w3mfix
+    next if ( $key eq 'initial-referer' );
+    next if ( $key eq 'header' );
+    next if ( $key eq 'pause' );
+    next if ( $key eq 'retry-pause' );
+    next if ( $key eq 'retries' );
+    next if ( $key eq 'robot-rules' );
+    next if ( $key eq 'remove-nomirror' );
+    next if ( $key eq 'file-disposition' );
+    next if ( $key eq 'http-proxy' );
+    next if ( $key eq 'proxy-options' );
+    next if ( $key eq 'auth-domain' );
+    next if ( $key eq 'auth-user' );
+    next if ( $key eq 'auth-passwd' );
+    next if ( $key eq 'disable-headers' );
+    next if ( $key eq 'agent' );
+
+    $debug=numeric($value),next if ( $key eq 'debug' );
+    umask(numeric($value)),next if ( $key eq 'umask' );
+    $indexname=$value,next if ($key eq 'index-name');
+    $verbose=nway($value,'quiet','brief','chatty')-1,next
+      if ( $key eq 'verbosity' );
+
+    if ( $key eq 'cd' ) {
+      $chdirto=$value;
+      next;
+    }
+
+    if ($key eq 'url') {
+      my ($rum_url_o,$lf_dir,$rum_reurl,$rum_rebase);
+
+      # A two argument URL: line?
+      if ($value =~ m/^(.+)\s+(.+)/i) {
+	# Two arguments.
+	$rum_url_o=url $1;
+	# The last is a directory, it must end in /
+	$lf_dir=$2;
+	$lf_dir.='/' unless $lf_dir =~ m~/$~;
+
+	# The first is a URL, make it more canonical, find the base.
+	# The namespace confusion in this section is correct.(??)
+	$rum_rebase = quotemeta( ($rum_url_o->as_string =~ m~^(.*/)~)[0] );
+
+	# print "URL: ",$rum_url_o->as_string,"\n";
+	# print "Base: $rum_rebase\n";
+
+	# Translate from rum space to lf space:
+	push(@internal_apply,"s/^".$rum_rebase."/".quotemeta($lf_dir)."/");
+
+	# That translation could lead to information loss.
+	$infoloss=1;
+
+	# Fetch rules tests the rum_url_o->as_string.  Fetch whatever
+	# matches the base.
+	$scope_fetch.="return 1 if m/^".$rum_rebase."/".$ipost.";\n";
+
+	# Ignore whatever did not match the base.
+	$scope_ignore.="return 0 if m/^".
+	  quotemeta("http://".$rum_url_o->netloc."/")."/".$ipost.";\n";
+
+      } else {
+	# $rum_url_o=root_quene($value);
+
+	$rum_url_o=url $value;
+
+	$rum_rebase = quotemeta( ($rum_url_o->as_string =~ m~^(.*/)~)[0] );
+
+	# Translate from rum space to lf space:
+	push(@internal_apply,"s/^".$rum_rebase."//");
+
+	$scope_fetch.="return 1 if m/^".$rum_rebase."/".$ipost.";\n";
+	$scope_ignore.="return 0 if m/^".
+	  quotemeta("http://".$rum_url_o->netloc."/")."/".$ipost.";\n";
+      }
+      next;
+    }
+
+    if ($key eq 'also' || $key eq 'also-quene') {
+      if ($value =~ m/^(.+)\s+(.+)/i) {
+	my ($rum_url_o,$lf_dir,$rum_reurl,$rum_rebase);
+	# Two arguments.
+	$rum_url_o=url $1;
+	$rum_url_o->host(lc $rum_url_o->host);
+	# The last is a directory, it must end in /
+	$lf_dir=$2;
+	$lf_dir.='/' unless $lf_dir =~ m~/$~;
+
+	# The first is a URL, find the base
+	$rum_rebase = quotemeta( ($rum_url_o->as_string =~ m~^(.*/)~)[0] );
+
+	# Ok, now we can transform and select stuff the right way
+	push(@internal_apply,"s/^".$rum_rebase."/".quotemeta($lf_dir)."/");
+	$infoloss=1;
+
+	# Fetch rules tests the rum_url_o->as_string.  Fetch whatever
+	# matches the base.
+	$scope_fetch.="return 1 if m/^".$rum_rebase."/".$ipost.";\n";
+
+	# Ignore whatever did not match the base.  This cures problem
+	# with '..' from base in in rum space pointing within the the
+	# scope in ra space.  We introduced a extra level (or more) of
+	# directories with the apply above.  Must do same with 'Also:'
+	# directives.
+	$scope_ignore.="return 0 if m/^".
+	  quotemeta("http://".$rum_url_o->netloc."/")."/".$ipost.";\n";
+      } else {
+	die "Also: requires 2 arguments\n";
+      }
+      next;
+    }
+
+    if ($key eq 'quene') {
+      # root_quene($value);
+      next;
+    }
+
+    if ($key eq 'ignore-re' || $key eq 'fetch-re') {
+      # Check that it's a re, better that I am strict than for perl to
+      # make compilation errors.
+      unless ($value =~ /^m(.).*\1[gimosx]*$/) {
+	print STDERR "w3mfix: $value is not a recognized regular expression\n";
+	exit 1;
+      }
+    }
+
+    if ($key eq 'fetch' || $key eq 'fetch-re') {
+      my $expr=$value;
+      $expr = wild_re($expr).$ipost if ($key eq 'fetch');
+      $rule_text.=' return 1 if '.$expr.";\n";
+      next;
+    }
+
+    if ($key eq 'ignore' || $key eq 'ignore-re') {
+      my $expr=$value;
+      $expr = wild_re($expr).$ipost if ($key eq 'ignore');
+      $rule_text.=' return 0 if '.$expr.";\n";
+      next;
+    }
+
+
+    if ($key eq 'apply') {
+      unless ($value =~ /^s(.).*\1.*\1[gimosxe]*$/) {
+	print STDERR
+	  "w3mfix: '$value' is not a recognized regular expression\n";
+	exit 1;
+      }
+      push(@user_apply,$value) ;
+      $infoloss=1;
+      next;
+    }
+
+    if ($key eq 'options') {
+      
+      my($val,$nval);
+      foreach $val (split(/\s*,\s*/,lc $value)) {
+	if ($i==1) {
+	  $nval=nway($val,'recurse','no-date-check','only-nonexistent',
+		     'list-urls','lowercase','remove','batch','read-urls',
+		     'abs');
+	  $r=1,next if $nval==0;
+	  next if $nval==1;
+	  next if $nval==2;
+	  $list=1,next if $nval==3;
+	  if ($nval==4) {
+	    $lc=1;
+	    $iinline=($lc?"(?i)":"");
+	    $ipost=($lc?"i":"");
+	    next ;
+	  }
+	  next if $nval==5;
+	  next if $nval==6;
+	  next if $nval==7;
+	  $abs=1,next if $nval==8;
+        } else {
+	  die "w3mfix: options must be the first directive in the config file.\n";
+	}
+      }
+    }
+
+    if ($key eq 'fixup') {
+
+#      chomp($fixrc=`pwd` || '.');
+#      $fixrc.="/$file";
+#      warn "Fixrc: $fixrc\n";
+#      $fixup=1;
+
+      my($val,$nval);
+      foreach $val (split(/\s*,\s*/,lc $value)) {
+	$nval=nway($val,'on','run','noindex');
+	next if $nval==0;
+	next if $nval==1;
+	$doindex=0 if $nval==2;
+	# Ignore everyting else
+      }
+    }
+
+  }
+  close(CFGF);
+}
+
+sub wild_re {
+  # Here we translate unix wildcard subset to to perlre
+  local($_) = shift;
+  s#\*#\.\*#;
+  s#\?#\.#;
+  s#([\/\(\)\\\|\{\}\+)\$\^])#\\$1#g;
+  return $_ = '/'.$_.'/';
+}
+
+
+sub numeric {
+  # Check if argument is numeric?
+  my ( $number ) = @_ ;
+  return oct($number) if ($number =~ /\d+/ || $number =~ /\d+.\d+/);
+  die "Expected a number, got \"$number\"\n";
+}
+
+
+sub boolean {
+  my ( $boolean ) = @_ ;
+
+  $boolean = lc $boolean;
+
+  return 0 if ($boolean eq 'false' || $boolean eq 'off' || $boolean eq '0');
+  return 1 if ($boolean eq 'true' || $boolean eq 'on' || $boolean eq '1');
+  die "Expected a boolean, got \"$boolean\"\n";
+}
+
+
+sub nway {
+  my ( $value ) = shift;
+  my ( @values ) = @_;
+  my ( $val ) = 0;
+
+  $value = lc $value;
+  while (@_) {
+    return $val if $value eq shift;
+    $val++;
+  }
+  die "Expected one of ".join(", ",@values).", got \"$value\"\n";
+}
+
+
+sub stat {
+
+  my $file = shift;
+
+  if (exists($stat{$file})) {
+    print STDERR "++Cache hit: $file\n" if $debug;
+  } else {
+    stat($file);
+    if (-e _) {
+      $stat{$file}=(-d _)?'d':'f';
+    } else {
+      $stat{$file}='n';
+    }
+    print STDERR "--Cache miss: $file\n" if $debug;
+  }
+  return $stat{$file};
+}
+
+# ######################## Read 'state' files ##############################
+
+sub read_state {
+
+  my $reffile='.referers';
+  my $refered;
+  my @referers;
+
+  $reffile="referers" if $win32;
+
+  print STDERR "reading $reffile\n" if $verbose>0;
+  open(REFERERS,"< $reffile") ||
+    die "Could not open $reffile for reading: $!\n";
+
+  while (<REFERERS>) {
+    chomp;
+    ($refered,undef,@referers) = split(/\s+/);
+    $rum_referers{$refered}= [ @referers ];
+    # print STDERR $refered," <- ",join(' and ',@referers),"\n";
+  }
+
+  close(REFERERS);
+
+
+  # Read redirection report
+
+  my $redirfile='.redirs';
+  my $wrong;
+  my $right;
+  my $tmp;
+
+  $redirfile="redirs" if $win32;
+
+  print STDERR "reading $redirfile\n" if $verbose>0;
+  open(REDIRS,"< $redirfile") ||
+    die "Could not open $redirfile for reading: $!\n";
+
+  while (<REDIRS>) {
+    chomp;
+    ($wrong,undef,$right) = split(/\s+/);
+
+    $rum_redirected{$wrong}=$right;
+  }
+
+  close(REDIRS);
+}
+
+# ######################### Process every single tag ########################
+
+sub process_tag {
+  # Process a tag in html file
+  my $lf_referer = shift;
+  my $base_url = shift;
+  my $tag_name = shift;
+  my $url_attrs = shift;
+
+  # Retrun quickly if no URL attributes
+  return unless defined($url_attrs);
+
+  my $attrs = shift;
+
+  # Information loss through apply or processing in this procedure?
+  my $il = $infoloss; 
+  my $redirs;
+  my $stat;
+
+  my $rum_url;	# The absolute URL
+  my $lf_url;	# The local filesystem url
+  my $lf_url_o; # ... and it's object
+  my $key;
+  my $orig_rum_url;
+#  my $debug = 1;
+
+#  print STDERR "\nProcess Tag: $tag_name, URL attributes: ", join(', ',@{$url_attrs}),"\nOrigin:",$base_url,"\n"; # if $debug>2;
+
+  substr($lf_referer,0,0)='./' unless substr($lf_referer,0,1) eq '/';
+
+  foreach $key (@{$url_attrs}) {
+    if (defined($$attrs{$key})) {
+      $orig_rum_url=$rum_url=$$attrs{$key};
+
+      print STDERR "\n$key = $rum_url\n" if $debug;
+
+      # Apply redirects:
+      $redirs=0;
+      if (exists($rum_redirected{$rum_url})) {
+	$il=1;
+	while (exists($rum_redirected{$rum_url})) {
+	  die "Too many redirects in a row\n" if $redirs++>32;
+	  print STDERR "$rum_url -> ".$rum_redirected{$rum_url}."\n"
+	    if $debug;
+	  $rum_url=$rum_redirected{$rum_url};
+	}
+      }
+
+      # Apply program/user apply rules
+      $lf_url=apply($rum_url);
+
+      if (defined($lf_url)) {
+	# Apply directory/file check here
+	$stat=&stat($lf_url);
+
+	if ($stat eq 'f' && $lf_url =~ m~/$~) {
+	  # It's a file, remove trailing /
+	  print STDERR "****** File / fixup of $lf_url\n" if $debug;
+	  $il=1;
+	  substr($lf_url,length($lf_url)) = '';
+	} elsif ($stat eq 'd' && !($lf_url =~ m~/$~) ) {
+	  # It's a directory, add a trailing /
+	  print STDERR "****** Directory / fixup of $lf_url\n" if $debug;
+	  $il=1;
+	  $lf_url .= '/';
+	}
+
+	substr($lf_url,0,0)='./' unless substr($lf_url,0,1) eq '/';
+
+	$lf_url_o=url $lf_url;
+	my $tmp=$lf_url_o->clone;
+	$tmp->basename($indexname);
+
+	if ( $doindex && $lf_url_o->basename eq "" && 
+	     &stat($tmp->unix_path) eq 'f' &&
+	     !$htmlop::isdir{$key}) {
+	  $lf_url_o=$tmp;
+	  $il=1;
+	  print STDERR "indexname adjusted to ",$lf_url_o->as_string,"\n"
+	    if $debug;
+	}
+		 
+	# Save new value in the hash, make it a file url to get 'rel' working
+	$lf_url_o->scheme('file');
+	$$attrs{$key} = ($lf_url_o->rel("file:".$lf_referer))->as_string;
+
+	printf STDERR "Saved ".$$attrs{$key}."\n" if $debug;
+
+	# If there is potential information loss save the old value too
+	$$attrs{"W3MIR".$key}=$orig_rum_url if $il;
+
+      } elsif ($redirs>0) {
+	$$attrs{$key}=$rum_url;
+	print STDERR "Saved ".$$attrs{$key}."\n" if $debug;
+	$$attrs{"W3MIR".$key}=$orig_rum_url;
+      }
+    }
+  }
+}
+
+
+# ###################### Edit the URLs in one file... ########################
+
+sub edit_html_file {
+  # Check if it's a html file.  I know this tag is in all html
+  # files, because w3mir put it there.
+
+  my($lf_url)=shift;
+  my($rum_url)=shift;
+
+  # Figure out the filename for our local filesystem.
+  $lf_url.=$indexname if $lf_url =~ m~/$~ || $lf_url eq '';
+
+  # Stuff in need of unquoting?
+  $lf_url = (url "file:$lf_url")->local_path if $lf_url =~ /\%\d\d/;
+
+  if (exists($lf_edited{$lf_url})) {
+    print STDERR "Already edited $lf_url\n" if $debug;
+    return ;
+  }
+
+  $lf_edited{$lf_url}=1;
+
+  my $page;
+  my $newpage;
+  my $read;
+  my $atime;
+  my $mtime;
+
+  # dev  uno   mode  nlink uid   gid   rdev  size  atime mtime
+  (undef,undef,undef,undef,undef,undef,undef,undef,$atime,$mtime)
+    = stat($lf_url);
+
+  if (!open(TMPF,"< $lf_url\n")) {
+    warn "Cannot read $lf_url: $!\n" if $verbose>=0;
+    return;
+  }
+
+  $read=sysread(TMPF,$page,10240,0);
+  close(TMPF);
+
+  if (! $page =~ /<HTML/i) {
+    print STDERR "$lf_url is not html\n" if $verbose>0;
+    return ;
+  }
+
+  $files++;
+
+  print STDERR "w3mfix: $lf_url" if $verbose>=0;
+  
+  print STDERR "$lf_url is a html file\n" if $debug;
+
+  print STDERR " reading" if $verbose>0;
+  
+  open(TMPF,$lf_url) || 
+    die "Could not open $lf_url for reading: $!\n";
+  # read the whole file.
+  {
+    local($/)=undef;
+    $page = <TMPF>;
+  }
+  close(TMPF);
+
+  print STDERR " ",length($page)," bytes" if $verbose>0;
+
+  # It's a html document
+
+  print STDERR ", editing" if $verbose>0;
+
+  ($newpage,undef) = 
+    &htmlop::process($page, # $htmlop::NODOC,
+		     $htmlop::ABS,$rum_url,
+		     $htmlop::USESAVED,'W3MIR',
+		     $htmlop::TAGCALLBACK,\&process_tag,$lf_url);
+
+  open(TMPF,">$lf_url") ||
+    die "\nCould not open $lf_url for writing: $!\n";
+  
+  print STDERR ", saving" if $verbose>0;
+
+  if (length($newpage)) {
+    # This is ODD: close does not seem to flush the buffers.  So we
+    # force the issue.
+    local($|)=1;
+    print TMPF $newpage || 
+      die "\nCould not write to $lf_url (disk full?): $!\n";
+  }
+
+  close(TMPF) || 
+    die "\nCould not close $lf_url after writing: $!\n";
+
+  # Set times back to what they were.
+  utime $atime,$mtime,$lf_url;
+
+  print STDERR ".\n" if $verbose>=0;
+}
+
+# ############################### Scope test
+
+sub want_this {
+  # Find out if we want the url passed.  Just pass it on to the
+  # generated functions.
+  my($rum_url)=shift;
+
+  # Does scope rule want this?
+  return &$scope_code($rum_url) &&
+    # Does user rule want this too?
+    &$rule_code($rum_url) 
+  
+}
+
+# ############################### Apply the apply rules
+
+sub user_apply {
+  # Apply the user apply rules
+  return &$user_apply_code(shift);
+}
+
+
+sub internal_apply {
+  # Apply the w3mir generated apply rules
+  return &$apply_code(shift);
+}
+
+
+sub apply {
+  # Apply the user apply rules.  Then if URL is wanted return result of
+  # w3mir apply rules.  Return the undefined value otherwise.
+
+  my $url = user_apply(shift);
+
+  return undef unless want_this($url);
+
+  internal_apply($url);
+}
+
+# ############################### Decide what URLs to edit
+
+sub edit_as_needed {
+  my $rum_redirected;
+  my $rum_url;
+  my $o_rum_url;
+  my $rum_referer;
+  my $lf_url;
+  my $foo;
+  my $redirs;
+
+  if ($editthis) {
+
+    # Find the URLs that match $edithis
+    foreach $o_rum_url (keys %rum_referers) {
+      # Work on them if they (now) fall within the scope of retrival
+      $redirs=0;
+      $rum_url=$o_rum_url;
+      if (exists($rum_redirected{$o_rum_url})) {
+	while (exists($rum_redirected{$rum_url})) {
+	  die "Too many redirects in a row\n" if $redirs++>32;
+	  print STDERR "$rum_url -> ".$rum_redirected{$rum_url}."\n"
+	    if $debug;
+	  $rum_url=$rum_redirected{$rum_url};
+	}
+      }
+      next unless $rum_url =~ /$editthis/io;
+      next unless want_this($rum_url);
+      # Find and edit the documents containing references to $o_rum_url
+      foreach $rum_referer (@{$rum_referers{$o_rum_url}}) {
+	next if $rum_referer eq '(commandline)';
+	$lf_url=apply($rum_referer);
+	next unless defined($lf_url);
+	edit_html_file($lf_url,$rum_referer);
+      }
+    }
+    
+    # Don't do anything else when invoked thus
+    return;
+  }
+
+  if ($doindex) {
+    # Edit everything that refers anything with trailing /
+    foreach $rum_url (grep(/\/$/,keys %rum_referers)) {
+      foreach $rum_referer (@{$rum_referers{$rum_url}}) {
+	next if $rum_referer eq '(commandline)';
+	$lf_url=apply($rum_referer);
+	next unless defined($lf_url);
+	edit_html_file($lf_url,$rum_referer);
+      }
+    }
+  }
+
+  # Edit only redirected stuff
+  foreach $rum_redirected (keys %rum_redirected) {
+    # print "Redirected $rum_redirected\n";
+    foreach $rum_url (@{$rum_referers{$rum_redirected}}) {
+      # print "- Found in $rum_url\n";
+      $lf_url=apply($rum_url);
+      next unless defined($lf_url);
+      edit_html_file($lf_url,$rum_url);
+    }
+  }
+}
+
+# ############################### 'main'
+
+&parse_args(@ARGV);
+
+if (!$rc) {
+  $rc='.w3mirc';
+  $rc='w3mir.ini' if $win32;
+}
+
+print STDERR "w3mfix: rc file: $rc\n" if $verbose>0;
+
+&parse_cfg_file($rc);
+
+# $chdirto is ignored, w3mir already did it
+
+# Compile second order code
+
+# - The rum scope tests
+my $full_rules=$scope_prefix.$scope_fetch.$scope_ignore.$scope_postfix;
+eval $full_rules;
+
+# warn "Scope rules:\n-------------\n$full_rules\n---------------\n";
+
+die "Program generated rules did not compile.  The code is:\n----\n".
+  $full_rules."\n----\n"
+  if !defined($scope_code);
+
+$full_rules=$rule_prefix.$rule_text.$rule_postfix;
+eval $full_rules;
+
+# warn "User rules:\n-------------\n$full_rules\n---------------\n";
+
+# - The user specified rum tests
+die "Ignore/Fetch rules did not compile.  The code is:\n----\n".
+  $full_rules."\n----\n"
+  if !defined($rule_code);
+
+# - The user specified apply rules
+
+my $full_apply=$apply_prefix.($lc?$apply_lc:'').
+  join($ipost.";\n",@user_apply).(($#user_apply>=0)?$ipost:"").";\n".
+  $apply_postfix;
+eval $full_apply;
+
+die "User apply rules did not compile. The code is:
+----
+".$full_apply."
+----\n" if !defined($apply_code);
+
+$user_apply_code=$apply_code;
+
+# - The w3mir generated apply rules
+
+$full_apply=$apply_prefix.($lc?$apply_lc:'').
+  join($ipost.";\n",@internal_apply).(($#internal_apply>=0)?$ipost:"").";\n".
+  $apply_postfix;
+eval $full_apply;
+
+die "Internal apply rules did not compile.  The code is:
+----
+".$full_apply."
+----\n" if !defined($apply_code);
+
+&read_state;
+
+&edit_as_needed;
+
+exit 0;
+__END__
+# -*- perl -*-  There must be a blank line here:
+
+=head1 NAME
+
+w3mfix - fixup program for w3mir
+
+=head1 SYNOPSIS
+
+B<w3mfix> [B<options>] [B<configuration-file>]
+
+=head1 DESCRIPTION
+
+B<w3mfix> is the companion program to L<w3mir>.  It can be used for
+several URL editing operations usefull in different situations.  
+
+When starting B<w3mfix> will read it's configuration file.  It's name is 
+either .w3mirc (w3mir.ini on win32) or specified on the commandline.
+
+B<w3mfix> is controlled by the 'Fixup' directive of the configuration
+file (described in the L<w3mir> documentation).  B<w3mfix> is also
+affected by 'Index-name' and the one special commandline option it
+knows, as well as the directives/options controlling verbosity and
+debugging information.
+
+=head1 DESCRIPTION
+
+B<w3mfix> can rewrite URLs in these ways:
+
+=over 4
+
+=item * Rewrite URLs that resutled in redirects to point to the place
+redirected to.  This is needed in all cases and will always be fixed
+by B<w3mfix>.
+
+=item * Change URLs ending in .../ into .../index.html (or
+.../Welcome.html).  This is, probably, not needed when the mirror is
+meant do be used with a web-server.  It is usefull for browsing
+directly from disk or CDROM, but in this case it's, most often,
+required.  To disable this specify the I<noindex> option with the
+'Fixup' directive.
+
+The default is to transform URLs ending in .../ into .../index.html.
+
+To controll the name of the index file use the I<Index-name> directive
+as documented in L<w3mir>
+
+=item * Change URL links to documents outside the mirror to point to
+some local document.  Could be usefull if the mirror is destined for a
+CDROM to be used on a unconnected machine.
+
+THIS IS NOT YET IMPLEMENTED
+
+=item * Change URL links to documents that L<w3mir> was
+unable/forbidden to retrive to point to some local document.  Pointing
+these to a nice informative document is probably better than random
+error messages from the browser.
+
+THIS IS NOT YET IMPLEMENTED
+
+=item * And, least, but far from last, B<w3mfix> can be used to
+prepare an established mirror for enlargement.
+
+This feature is used thus: Add the new site or subsite to be mirrored
+on the configuration file (by adding B<Also:> and B<Also-quene:>
+directives).  Then run B<w3mfix> with the B<-editref> option.  When
+the B<-editref> option is specified B<w3mfix> will not perform any
+other editing tasks.
+
+E.g.; To add I<http://www.yahoo.com/Science/Artificial_Life/> to your
+mirror add something like
+
+	  Also: http://www.yahoo.com/Science/Artificial_Life/ yahoo
+
+to the configuration file, then run w3mfix:
+
+	  w3mfix -editref www.yahoo.com/Science/Artificial_Life
+
+This will cause all references to
+I<www.yahoo.com/Science/Artificial_Life> (and under) to be edited so they
+point to within the mirror.  After B<w3mfix> has finished you can run
+L<w3mir> in the normal manner.
+
+=back
+
+=head1 BUGS
+
+Naah.
+
+=head1 SEE ALSO
+
+L<w3mir>
+
+=head1 AUTHORS
+
+B<w3mir>s authors can be reached at I<w3mir-core@usit.uio.no>.
+B<w3mir>s home page is at http://www.math.uio.no/~janl/w3mir/
+
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3mir-HOWTO.html
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3mir-HOWTO.html	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3mir-HOWTO.html	(revision 20131)
@@ -0,0 +1,943 @@
+<!doctype html public "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>W3MIR HOWTO</title>
+<style type="text/css">
+<!--
+  body { background-color: white }
+  h1, h2, h3, b { font-family: sans-serif }
+  .red { color: red }
+-->
+</style>
+<body>
+<h1>W3MIR HOWTO</h1>
+
+<p><b>Corresponding to w3mir version 1.0.2 and above</b>
+
+<p>W3mir is an all purpose WWW copying and mirroring program.  Its
+main focus is copying complete directory structures keeping your copy
+browseable through a web server, or directly off a disk or CDROM if
+you want.  W3mir will fix URLs that are redirected and everything else
+that needs to be fixed to make your copy browseable.  But it also does
+odd jobs, retrieving single documents, batch getting several documents
+and more.  You may tell w3mir not to change anything in the retrieved
+documents.  W3mir has been in development quite a long time so you
+find options to do a lot of things needed when copying things off the
+web.
+
+<p>With w3mir you may copy the entire contents a web server.  Or just
+a directory hierarchy, or several related hierarchies off as many
+servers as you like.  They don't even have to be related.
+
+<p>W3mir supports HTML4, and has partial support for CSS, Java,
+ActiveX and Adobe Acrobat (PDF) files.  And it works on Win32
+machines.
+
+<p><b>Warning:</b> W3mir enables you to copy a lot of things off the
+Web, but remember, the things you retrieve might be copyrighted and
+the copy you make with w3mir might in fact be illegal to make and
+posses.
+
+<hr>
+
+<h2><a name="contents">Contents</a></h2>
+
+<p><a href="#intro">README</a> (You want to read this!  <b
+class="red">Really!</b>)
+
+<p><b>How do I...</b>
+<ol>
+  <li><p><a href="#copy">copy a file?</a>
+  <li><p><a href="#recurse">copy a directory hierarchy?</a>
+  <li><p><a href="#resources">copy the needed resource files from another
+    directory hierarchy?</a>
+  <li><p><a href="#ignore">avoid copying files I don't want or copy only
+    files I want?</a>
+  <li><p><a href="#rm">remove the files that are no longer on the
+    original site from the mirror?</a>
+  <li><p><a href="#depth">limit how deep w3mir will recurse?</a>
+  <li><p><a href="#memory">limit w3mirs memory usage?</a>
+  <li><p><a href="#multi">copy files from multiple sites?</a>
+  <li><p><a href="#alias">copy files from one server with several names?</a>
+  <li><p><a href="#aborted">restart a mirror process after stopping it
+    prematurely?</a>
+  <li><p><a href="#enlarge">enlarge or prune an established mirror?</a>
+  <li><p><a href="#cat">'cat' a file?</a>
+  <li><p><a href="#list">list URLs in a document?</a>
+  <li><p><a href="#robots">disable robots.txt obedience?</a>
+  <li><p><a href="#corrupt">stop w3mir from corrupting binary files?</a>
+  <li><p><a href="#auth">copy a site that wants user-name and password?</a>
+  <li><p><a href="#mauth">access a site that wants several different
+    user-names and passwords?</a>
+  <li><p><a href="#proxy">use a proxy server?</a>
+  <li><p><a href="#pauth">authenticate myself to a proxy server?</a>
+  <li><p><a href="#proxytweak">ensure that the proxy server ...?</a>
+  <li><p><a href="#batchget">batch get files with w3mir?</a>
+  <li><p><a href="#cgi">handle CGI?</a>
+  <li><p><a href="#imap">handle server side image-maps?</a>
+  <li><p><a href="#java">handle Java and ActiveX?</a>
+  <li><p><a href="#script">handle java-script and other script languages?</a>
+  <li><p><a href="#css">handle the other things with 'partial support'?</a>
+  <li><p><a href="#anon">keep my identity secret?</a>
+  <li><p><a href="#ns">pretend that I'm using Netscape, Internet
+    Explorer or Lynx?</a>
+  <li><p><a href="#other">do other things?</a>
+</ol>
+
+<hr>
+
+<h2><a name="intro">README</a></h2>
+
+<p>W3mir may be used in two, main, ways:
+
+<ul>
+  <li><p>To copy something random once.
+  <li><p>To keep a local mirror of some remote site
+</ul>
+
+<p>To copy something random once there is a high likeliness you can
+just start w3mir with some simple options and it will do the job you
+want it to.  Providing that the remote site is not too complex and
+your expectations of the copy aren't high :-) This is what wget, the
+gnu w3 mirroring program, does and is good at.
+
+<h3>Configuration file</h3>
+
+<p>Once you want to keep a copy of a remote site up-to-date over time,
+mirror something with server side image-maps, redirects or
+authentication you have to write a configuration file for w3mir.  This
+is what w3mir is good at, compared to wget.  Writing the file is not
+hard, and there are two example files in the w3mir distribution.  It
+will also be explained here.  The configuration file is typically
+called <tt>.w3mirc</tt> (<tt>w3mir.ini</tt> on win32 machines), and
+can be written with a simple text editor.  It is kept in the top
+directory of the mirror, where w3mir will find it when it starts.
+Please refer to the <a href="#contents">contents</a> for how to handle
+a specific problem with a configuration file.
+
+<hr>
+
+<h2>The answers:</h2>
+
+<hr>
+
+<h3><a name="copy">How do I copy a file?</a></h3>
+
+<p>To copy the top page off www.starwars.com:
+
+<p><tt>w3mir http://www.starwars.com/</tt>
+
+<p><b>Note:</b> it is <em>important</em> that you give the trailing
+slash for server names and directories.
+
+<hr>
+
+<h3><a name="recurse">How to I copy a directory hierarchy?</a></h3>
+
+<p>To copy the entire stuff about episode I from www.starwars.com
+which is stored in <tt>http://www.starwars.com/episode-i/</tt> (I don't
+recommend this, it's quite a lot of data):
+
+<p><tt>w3mir -r http://www.starwars.com/episode-i/</tt>
+
+<p>The corresponding configuration file is simple:
+
+<pre>
+Options: recurse
+URL: http://www.starwars.com/episode-i/
+Fixup: run
+</pre>
+
+<p>The <tt>-r</tt> option makes w3mir recurse down from the starting
+point.  It will only copy all the documents under
+http://www.starwars.com/episode-i/ that it sees referenced from those
+same documents.  W3mir will <em>not</em> retrieve documents from
+http://www.starwars.com/ because it is considered to be 'over' the
+starting point.
+
+<p>The command-line will get you a copy that is definitely browseable
+via a WEB server, and possibly browseable directly from a CDROM or
+hard-disk.  To ensure that it is browseable from CDROM and disk you
+need to use a configuration file with the <tt>Fixup: run</tt> line in.
+It causes w3mir to edit anything that needs editing after the mirror
+has completed, including fixing URLs that caused redirects.  The dirty
+work is done by w3mirs helper program w3mfix.  The directive will
+cause w3mfix to be run each time w3mir completes the mirror.
+
+<p><b>Note:</b> it is <em>important</em> that you give the trailing
+slash after the directory name.  Specifying
+<tt>http://www.starwars.com/episode-i</tt> and
+<tt>http://www.starwars.com/episode-i/</tt> is quite different in
+w3mirs eyes.  In the former case episode-i is considered to be a
+document within the / (top) directory of www.starwars.com and w3mir
+will recurse from /, which is a lot more than you wanted.  In the
+latter case w3mir understands that episode-i is a directory and will
+consider that directory to be the staring point, which is what you
+wanted.
+
+<hr>
+
+<h3><a name="resources">How do I copy the needed resource files from
+another directory hierarchy?</a></h3>
+
+<p>Some sites store their documents in one place, and puts their
+banners, icons and such in a separate directory called
+<tt>/images</tt>, <tt>/banners</tt>, <tt>/icons</tt>,
+<tt>/resources</tt> or some such.  Unless you retrieve these as well as
+the documents things will probably not be too colorful.  So, imagine
+that the starwars site stored all the images in one holding directory
+called <tt>/imagery</tt> and you want to copy all the stuff in it that
+the episode-i pages need.  Then you do this:
+
+<pre>
+Options: recurse
+URL: http://www.starwars.com/episode-i/ episode-i
+Also: http://www.starwars.com/imagery/ imagery
+Fixup: run
+</pre>
+
+<p>There are two changes here compared to the simpler file we started
+with: There is an extra argument at the end of the URL directive.  It
+tells w3mir to store everything gotten from
+<tt>http://www.starwars.com/episode-i/</tt> in the subdirectory
+<tt>episode-i</tt>.  The directory can be omitted, but I think its
+neater this way.  Then the new directive 'Also:'.  It tells w3mir that
+you also want whatever the documents under
+<tt>http://www.starwars.com/episode-i/</tt> references under
+<tt>http://www.starwars.com/imagery/</tt>.
+
+<p><b>Note:</b> this will only get stuff that was used by the
+documents under <tt>http://www.starwars.com/episode-i/</tt>, anything
+stored under <tt>http://www.starwars.com/imagery/</tt> which is not
+used will not be retrieved. If you want everything under
+<tt>imagery</tt> to be retrived use the <tt>Also-quene:</tt>
+directive.
+
+<hr>
+
+<h3><a name="ignore">How do I avoid copying files I don't want or copy
+only files I want?</a></h3>
+
+<p>To control what files w3mir copies you can use the
+<tt>Ignore:</tt>, <tt>Fetch:</tt>, <tt>Ignore-RE:</tt> and
+<tt>Fetch-RE:</tt> directives in the configuration file.  The embeded
+references to any file you chose to ignore, i.e., not copy, will point
+at the original site, <em>not</em> to the mirror.  This means that the
+mirror user may still get ahold of the file from the original source
+by simply clicking if she so desires.
+
+<p>If a site contains huge .wav audio files that you are not
+interested in you put
+
+<pre>
+Ignore: *.wav
+</pre>
+
+<p>in the configuration file.  You may ignore as many different
+filename patterns as you want.  If you are mirroring a site you want
+very few, specific files from, say all HTML (named
+<em>something</em><tt>.html</tt>) and all Mpeg video files (named
+<em>something</em><tt>.mpg</tt>) you can write this:
+
+<pre>
+Fetch: *.html
+Fetch: *.mpg
+Ignore: *
+</pre>
+
+<p>W3mir will test each filename against each Fetch/Ignore rule in
+sequence.  A html file will match the first line and be fetched.  Any
+mpg file will match the second line and be fetched.  All other files
+will match the third line, and be ignored.  This last line is needed
+because the default is to get any files which are not ignored.  By
+arranging fetch and ignore rules carefully you may retrieve exactly
+the filename patterns you want and not retrieve anything else.
+
+<p>If you decide you also want all Mpeg Layer 3 audio files
+(<em>something.</em><tt>mp3</tt>) from the site, after the mirror has
+been established.  Then you add this:
+
+<pre>
+Fetch: *.mp3
+</pre>
+
+<p>as the third line, making the <tt>Ignore: *</tt> line the forth and
+last.  Then you must fix all references to .mp3 files within the
+mirror by running w3mfix thus:
+
+<pre>
+w3mfix -editref .mp3
+</pre>
+
+<p>which will edit all references to .mp3 files, pointing them the
+right place, on your disk. Ditto when you remove a fetch rule, or add
+or remove an ignore rule. See the answer about <a
+href="#enlarge">enlarging and pruning</a> mirrors for more examples of
+using <tt>w3mfix -editme ...</tt>
+
+<p><b>Note:</b> when retrieving only a very limited set of files, as
+in the example above, you <em>must</em> retrieve the html files,
+because how else will w3mir find URLs of files to retrieve? Only html
+files contain links to other files.
+
+<p>Similarly, you may chose to not mirror whole branches of the
+original site.  If you for example mirror my home-pages, and you decide
+not to mirror the comics pages you can put
+
+<pre>
+Ignore: /ts/
+</pre>
+
+<p>or more precisely
+
+<pre>
+Ignore: http://www.ifi.uio.no/~janl/ts/
+</pre>
+
+<p>in the configuration file.  If you do this after having established
+the mirror you use w3mfix to fix the references:
+
+<pre>
+w3mfix -editref /ts/
+</pre>
+
+<p><tt>Fetch:</tt> and <tt>Ignore:</tt> rules can only use a very
+limited subset of the Unix wild-cards.  w3mir understands only '?',
+'*', and '[a-z]' ranges.
+
+<p><tt>Ignore-RE:</tt> and <tt>Fetch-RE:</tt> are the same as
+<tt>Fetch:</tt> and <tt>Ignore:</tt> except that they give you access
+to the full power of Regular Expressions to make rules for that to get
+or not to get. They support perls superset of the normal Unix regular
+expression syntax.  They must be completely specified, including the
+prefixed m, a delimiter of your choice (except the paired delimiters:
+parenthesis, brackets and braces), and any of the RE modifiers. I.e.,
+
+<pre>
+Ignore-RE: m/.gif$/i
+</pre>
+
+<p>or
+
+<pre>
+Ignore-RE: m~/.*/.*/.*/~
+</pre>
+
+<p>and so on.  "#" cannot be used as delimiter as it is the comment
+character in the configuration file.
+
+<p>There are some traps when using <tt>Ignore-RE</tt> and
+<tt>Fetch-RE</tt>, please see their documentation in <tt>mandoc
+w3mir</tt> for a more complete explanation.
+
+<hr>
+
+<h3><a name="depth">How do I limit how deep w3mir will recurse?</a></h3>
+
+<p>W3mir has no explicit mechanism to limit the depth of recursion,
+but the same result can be achieved with a simple <tt>Ignore</tt> rule:
+
+<pre>
+Ignore: /*/*/*/*/*/*/
+</pre>
+
+<p>This will ignore any URLs that contain at least 7 slashes ("/").
+Note that a URL contains three slashes that does not have anything to
+do with depth:
+
+<pre>
+http://www.ifi.uio.no/
+</pre>
+
+<p>so only the surplus slashes are used for depth in this match.  In the
+example above the limit is 4 levels from the top.  The
+<tt>Ignore:</tt> rule that is used to limit recursion depth must be
+listed before any <tt>Fetch:</tt> rules to be effective.
+
+<hr>
+
+<h3><a name="memory">How do I limit w3mirs memory usage?</a></h3>
+
+<p>In a mirror consisting of <em>many</em> files, such as a archive of
+an active mailinglist w3mir will build a very large referer table, in
+part for w3mir to use in the <tt>Referer:</tt> header and in part for
+w3mfix to use in fixing references.
+
+<p>If you disable both the <tt>Referer:</tt> header and don't use
+w3mfix w3mir will not build a referer table.  You do this in the
+configuration file:
+
+<pre>
+Disable-headers: referer
+Fixup: off
+</pre>
+
+<p>Please note the potential problems of turning off fixup described
+earlier in this howto.  There are normaly no problems associated with
+simple sites, but if there are redirects fixup <em>is</em> needed for
+a consistent mirror.
+
+<hr>
+
+<h3><a name="rm">How do I remove the files are no longer on the
+original site from the mirror?</a></h3>
+
+<p>Over time the site you mirror will add files, and quite possibly
+remove files.  Or you might introduce new <tt>Ignore:</tt> rules after
+establishing the mirror that reduces the files wanted in the mirror.
+
+<p>By default w3mir will not delete such old files, some people might
+want to keep the files even if they are removed from the original
+site.  To remove the old/unwanted files you add 'remove' to the
+<tt>Options:</tt> line.
+
+<hr>
+
+<h3><a name="multi">How do I copy files from multiple sites?</a></h3>
+
+<p>In the answer to the previous question we see how to mirror several
+related sites.  For example, say you want to mirror all my home-pages
+into one mirror:
+
+<pre>
+Option: recurse
+URL: http://www.math.uio.no/~janl/ math/janl
+Also: http://www.math.uio.no/drift/personer/ math/drift
+Also: http://www.ifi.uio.no/~janl/ ifi/janl
+Also: http://www.mi.uib.no/~nicolai/ math-uib/nicolai
+</pre>
+
+<p>As in the previous example this will only get documents that are
+referenced.  Any documents that are stored at these location but to
+which w3mir finds no references will not be retrieved.  So this will
+fail if the sites are not in any way related, or if you wanted
+<em>everything</em> stored at each site.
+
+<p>To mirror unrelated sites, or get it all you may specify that the
+given URL should be considered a starting-point as well:
+
+<pre>
+Also-quene: http://www.math.uio.no/drift/personer/ math/drift
+</pre>
+
+<p>and, if you want to add an additional starting-point within a already
+named site:
+
+<pre>
+Quene: http://www.math.uio.no/drift/personer/foo.html
+</pre>
+
+<p>Armed with that you should be able to get pretty much anything you
+like.
+
+<hr>
+
+<h3><a name="alias">How do I copy files from one server with several
+names?</a></h3>
+
+<p>Simple, the same way you mirror several servers with different
+names. The math department at University of Oslo has a web server
+known under two names: math-www.uio.no and www.math.uio.no, and both
+names are used in documents stored on it. To copy the whole server,
+one time only, give these URL and Also lines:
+
+<pre>
+URL: http://www.math.uio.no/ .
+Also: http://math-www.uio.no/ .
+</pre>
+
+<p>Note the period/dot (.) at the end of each line.  It means that
+w3mir will store the files in the current directory, i.e. documents
+from both servers will be stored in the same place.  But since w3mir
+asks to only get documents that are newer than the ones it already has
+any document gotten from the server under the www.math.uio.no name
+will not be gotten from the math-www.uio.no name as well.  ... w3mir
+will ask for the document, but the server will tell w3mir that its
+copy is current and there will be no additional transfer of the
+document.
+
+<hr>
+
+<h3><a name="enlarge">How do I enlarge or prune an established
+mirror?</a></h3>
+
+<p>This only works if you use a configuration file.
+
+<p>If you want to add a site or directory to a mirror you simply add
+the needed <tt>Also:</tt> or <tt>Also-Quene:</tt> to the configuration
+file and then you run w3mfix manually, with the -editref option.  If,
+you for example have established a mirror of my home-pages, but want to
+add my wife's home-page you add this
+
+<pre>
+Also: http://www.ifi.uio.no/~annen/ ifi/annen
+</pre>
+
+<p>to the configuration shown earlier.  Then you run w3mfix, and you want
+it to fix all URLs referencing her home-page, the distinguishing
+characteristic is the name 'annen':
+
+<pre>
+w3mfix -editref annen
+</pre>
+
+<p>but 
+
+<pre>
+w3mirx -editref http://www.ifi.uio.no/~annen/
+</pre>
+
+<p>would work too, but it's a lot more to type.  This fixes all the
+references to her home-page so that they point to the mirror instead of
+the original pages.
+
+<p>To prune (cut out something) a mirror you do the same.  Make the
+change in the configuration file and run 'w3mfix -editme ...' to fix
+the references to that which you removed.
+
+<hr>
+
+<h3><a name="cat">How do I 'cat' a file?</a></h3>
+
+<p>W3mir will output the fetched document to its standard output
+(normally your screen/window) if you specify the '-s' command line
+option.  The corresponding configuration file directive is 
+
+<pre>
+File-Disposition: stdout
+</pre>
+
+<hr>
+
+<h3><a name="list">How do I list URLs in a document?</a></h3>
+
+<p>To list the URLs in http://www.math.uio.no/:
+
+<pre>
+w3mir -q -f -l http://www.math.uio.no/
+</pre>
+
+<p>The <tt>-q</tt> switch causes w3mir to produce no other output
+which would disturb the URL listing.  The <tt>-f</tt> switch tells
+w3mir to forget the document once it has been analyzed, i.e., not save
+it on disk.  And finally, the <tt>-l</tt> switch makes w3mir list the
+URLs in the document.  You may combine <tt>-l</tt> with <tt>-r</tt>
+and you need not use it with <tt>-f</tt>.
+
+<p>In the configuration file you put <tt>list</tt> on the
+<tt>Options:</tt> line.
+
+<hr>
+
+<h3><a name="aborted">How to I restart a mirror process after stopping
+it prematurely?</a></h3>
+
+<p>You may just rerun the same command once more.  But that makes
+w3mir request all the documents you have already once more to see if a
+more recent version is available on the server.  You can save time by
+using the <tt>-fs</tt> (Fetch Some) option.  This makes w3mir only
+request documents it does not find on your disk.  E.g.:
+
+<p><tt>w3mir -fs -r http://www.starwars.com/</tt>
+
+<p>This is not something you would normally put in the configuration
+file, but you can, by adding 'only-nonexistent' on the 'Options:' line.
+
+<hr>
+
+<h3><a name="robots">How do I disable robots.txt obedience?</a></h3>
+
+<p>Normally w3mir will read and obey each sites robots.txt file,
+because w3mir wants to be a nice tool. However robots.txt was designed
+with something slightly different than the normal use of w3mir in
+mind, so if you want w3mir to disregard the robot rules you can use
+<tt>-drr</tt> (Disable Robot Rules) on the command-line, or the line
+
+<pre>
+Robot-Rules: off
+</pre>
+
+<p>in the configuration file.  The robot exclusion standard is
+described in <a
+href="http://info.webcrawler.com/mak/projects/robots/norobots.html">http://info.webcrawler.com/mak/projects/robots/norobots.htm</a>.
+
+<hr>
+
+<h3><a name="corrupt">How do I stop w3mir from corrupting binary
+files?</a></h3>
+     
+<p>During the normal course of events w3mir converts the newline
+format of fetched HTML documents to your systems native newline
+format. On Unix a newline consists of a single ASCII LF character, on
+Macintoshes it's a single ASCII CR character and on Dos/Windows it's a
+ASCII CR/LF pair. W3mir understands all these and all HTML files are
+saved in the format your operating system prefers.
+
+<p>If, and this is very unlikely, a web server identifies a binary
+file as HTML w3mir will very likely corrupt the file. If you discover
+a file which is obviously ruined in the mirror, but is not ruined when
+you view it on the original site do this:
+
+<ol>
+
+<li>Notify the webmaster on the original site that the file has the
+wrong MIME type
+
+<li>Use the <tt>-nnc</tt> (No Newline Conversion) option on the
+command line, or
+
+<pre>
+Options: no-newline-conv
+</pre>
+
+in the configuration file.
+
+<li>Remove the corrupt file(s).
+
+<li>Run "<tt>w3mir -fs</tt>...", to fetch only the deleted file(s)
+again.
+
+</ol>
+
+<hr>
+
+<h3><a name="auth">How do I copy a site that wants user-name and
+password?</a></h3>
+
+<p>This can only be done with a configuration file.  Being able to
+give this on the command-line would give the user-name and password away
+to other users of the system, so the ability to give authentication
+information that way has not been put in w3mir.
+
+<p>In the configuration file you put:
+
+<pre>
+Auth-domain: */*
+Auth-user: me
+Auth-passwd: my-password
+</pre>
+
+<p>This will cause w3mir to give the user-name and password each time
+the server asks.  There is no way to make w3mir give the user-name and
+password each time no matter if the server asks or not.
+
+<hr>
+
+<h3><a name="mauth">How do I access a site that wants several
+different user-names and passwords?</a></h3>
+
+<p>If you have several user-names and passwords across
+the server(s) that are copied you need a slightly more advanced
+version of this that associates each user-name/password with a
+authentication "domain".  "Domain" is a HTTP concept.  It is simply a
+grouping of files and documents within a "realm".  One file or a whole
+directory hierarchy can belong to a realm.  One server may have many
+realms.  A user may have separate passwords for each realm, or the
+same password for all the realms the user has access to.  A
+combination of a server name, server port and a realm is called a
+domain.
+
+<pre>
+Auth-domain: theserver:theport/therealm
+Auth-user: me
+Auth-passwd: my-password
+
+Auth-domain: theserver:theport/otherrealm
+Auth-user: other-me
+Auth-password: other-password
+</pre>
+
+W3mir will tell you what the name of the realm is if it is unable to
+authenticate itself with the server. You may also use '*' as the realm
+name if you only copy documents from one realm on that server.
+
+<hr>
+
+<h3><a name="proxy">How do I use a proxy server?</a></h3>
+
+<p>On some secured sites you have to access the Internet through proxy
+servers to get out of the internal network.
+
+<p>A proxy server has a host name, and a port you must use. On the
+command line you simply specify <tt>-P proxy-host-name:proxy-port</tt>. In
+the configuration file you put this:
+
+<pre>
+HTTP-Proxy: proxy-host-name:proxyport
+</pre>
+
+<p>The main advantage of working through proxy servers other than
+security is that you take advantage of any caching the proxy server
+which can speed up retrievals enormously.
+
+<p>Another use of the proxy option is to "prime" the proxy servers
+cache.  I.e. you can use w3mir to fetch the documents through the proxy
+server to ensure that the documents are cached there later when you
+want to read them with your browser.  If you also specify 
+
+<pre>
+File-Disposition: forget
+</pre>
+
+<p>it won't even use any space on your disk, w3mir will just process
+the documents looking for URLs and then <em>not</em> save them.
+
+<hr>
+
+<h3><a name="pauth">How do I authenticate myself to a proxy
+server?</a></h3>
+
+<p>Some proxy servers demands a user-name and password to let you use
+them.  W3mir does not support the domain concept in connection with
+proxy authentication because the author cannot imagine that it will be
+needed.  You need to put this in your configuration file:
+
+<pre>
+HTTP-Proxy-user: proxy-username
+HTTP-Proxy-passwd: proxy-password
+</pre>
+
+<hr>
+
+<h3><a name="proxytweak">How do I ensure that the proxy server
+...?</a></h3>
+
+<p>HTTP/1.0 proxy servers may be told to not use its current copy of
+a document if you specify the <tt>-pflush</tt> command-line option.  Or 
+
+<pre>
+Proxy-Options: refresh
+</pre>
+
+<p>in the configuration file.  This is useful if the proxy has an old
+copy of some document and does not realize that a newer version exists
+on the origin site.  W3mir uses the HTTP/1.0 version of this command
+by default.  You can force w3mir to use the HTTP/1.1 version by adding
+<tt>no-pragma</tt> to the line.  If you do this it will not work at
+all as you want unless the server knows the HTTP/1.1 protocol.
+
+
+<p>HTTP/1.1 proxy servers can be manipulated in a few more ways.  The
+configuration file <tt>Proxy-Options:</tt> directive also takes
+<tt>revalidate</tt> and <tt>no-store</tt> options.  The former tells
+the proxy server to check if there is any newer version available.
+This is, in principle, more network friendly than the <tt>refresh</tt>
+option since it will only cause a copy if there is a newer file
+available.  The <tt>no-store</tt> option tells the proxy server to not
+store the documents you transfer.  This might be useful if the
+documents are 'sensitive' or something like that, but if the proxy
+server does not understand HTTP/1.1 it will not obey this option, and
+it might store the document anyway because the functionality is not
+implemented, so you should not count on this to work.
+
+<hr>
+
+<h3><a name="batchget">How do I batch get files with w3mir?</a></h3>
+
+<p>Normally when fetching files w3mir will process each html (and PDF)
+file to find URLs in them for further retrievals.  This is
+time-consuming, and not always wanted.  Sometimes you simply want to
+get a file, or more, and save it, untouched:
+
+<pre>
+w3mir -B http://www.starwars.com/ http://www.ifi.uio.no/~janl/
+</pre>
+
+<p>There is a companion switch for <tt>-B</tt>, namely <tt>-I</tt>, it
+makes w3mir read URLs from its standard input, one pr. line.  Thus you
+can use w3mir in a pipe to batch get several files whose URLs you find
+in some way.  This is a stupid example:
+
+<pre>
+w3mir -q -l -f http://www.ifi.uio.no/ | w3mir -I -B
+</pre>
+
+<p><tt>-B</tt> may also be used with <tt>-r</tt>, but the only effect
+it will have then is to save the html files unchanged on disk, because
+to recurse w3mir <em>has</em> to examine all the html the documents
+for URLs.
+
+<p><b>Please note</b> that using <tt>-B</tt> combined with <tt>-r</tt>
+for mirroring will probably lead to a unstable mirror, because w3mir
+does not get a chance to manipulate the URLs in the documents as it
+needs to be able to maintain a mirror later, and most important of
+all, w3mir needs all html files to contain a &lt;HTML&gt; tag to be
+able to recognize a HTML file as a HTML file. When running with the
+<tt>-B</tt> switch w3mir will not ensure the presence of this and thus
+we must rely on the original documents author to be nice. This is a
+bad bet. In other words, <b>don't use <tt>-B</tt> for recursive
+mirroring</b>, only for batch copying/mirroring of single documents.
+
+<hr>
+
+<h3><a name="cgi">How do I handle CGI?</a></h3>
+
+<p>There is no way w3mir can duplicate the process that happens on the
+Web server when it comes to CGI.  For some CGI programs w3mir can
+simply copy the output and store on disk.  For other CGI programs this
+is not possible, and the only way out is to make w3mir not get the
+involved files using Ignore rules in the configuration file.  These
+will avoid a lot of cgi programs:
+
+<pre>
+Ignore: *.cgi
+Ignore: *-cgi
+</pre>
+
+<p>You might have to add other/more rules for some sites if they have
+other naming conventions or if it's simply impossible to tell from the
+file-name if it's a CGI or not.
+
+<p>When you add ignore rules this causes two things:
+
+<ol>
+<li><p>W3mir will not retrieve documents matching the rules
+<li><p>W3mir will make all references to matching documents point to
+  the site you mirrored from instead of pointing to a non-existent
+  file in the mirror.
+</ol>
+
+<hr>
+
+<h3><a name="imap">How do I handle server side image-maps?</a></h3>
+
+<p>Server side image-maps is yet another thing it's impossible for
+w3mir to relate to.  w3mir simply cannot handle them.  Put ignore
+rules in the configuration file:
+
+<pre>
+Ignore: *.map
+</pre>
+
+<p>W3mir has full support for client side image-maps though.
+
+<hr>
+
+<h3><a name="java">How do I handle Java and ActiveX?</a></h3>
+
+<p>Java and Active X objects are are included in html pages with a
+<tt>&lt;OBJECT&gt;</tt> or <tt>&lt;APPLET&gt;</tt> tag.  W3mir can
+handle these on one condition: The CODEBASE attribute names the
+directory where the program stores its resources (such as
+subprograms, graphic files, sound, text, and so on) and w3mir must
+have read access to this directory.  Otherwise w3mir is without hope,
+it's impossible to extract the name of the resources the program needs
+in any reliable way.
+
+<p>HTML4 supports a attribute that enumerates the resources the
+program needs, w3mir is not able to use this yet.
+
+<hr>
+
+<h3><a name="script">How do I handle java-script and other script
+languages?</a></h3>
+
+<p>W3mir does its best to pass scripts (java-script, perl-script,
+etc...) embedded in the HTML undamaged.  It cannot, however, extract
+any URLs the script generates and the browser would cause the document
+to refer to or embed in a page. 
+
+<p>It will however work if the script generates relative references
+and there is some other way for w3mir to access the referenced file in
+some other manner.  Or if the script generates absolute references and
+the person browsing the mirror has access to the site named, then the
+user will be able to browse the referenced documents via that other
+server.
+
+<hr>
+
+<h3><a name="css">How to I handle the other things with 'partial
+support'</a></h3>
+
+<p>W3mir has partial support for CSS.  This means that
+<tt>&lt;style&gt</tt> tags and the enclosed style data are passed
+undamaged by w3mir.  W3mir will also retrieve the external CSSes named
+in HTML documents.  But w3mir will <em>not</em> (yet) analyze the
+CSSes data to find URLs of other resources (such as fonts) named in
+these.
+
+<p>W3mir also has partial support for Adobe Acrobat (PDF) files.  This
+means that w3mir can extract URLs from PDF files, and get the named
+documents if you want them.  But w3mir cannot edit those URLs so that
+the PDF files point to the mirror instead of wherever on the original
+site they were pointing.  If the PDF files contain absolute URLs they
+will continue pointing to where they were pointing before.  However,
+if the PDF files contain relative references things will work out.
+
+<p>The reason that URLs in PDF files cannot be edited is that they are
+binary and contain byte pointers.  If the URLs length is changed the
+byte pointers will point to the wrong place in the document.  Writing
+code to correct these pointers would be quite complex.  But if you
+write it I will use it.
+
+<hr>
+
+<h3><a name="anon">How do I keep my identity secret?</a></h3>
+
+<p>The HTTP protocol has a header, <tt>User:</tt> which is recommended
+to use by robots, such as w3mir.  Another way to track you is looking
+at the 'Referer:' header w3mir gives in HTTP requests.  Both can be
+disabled:
+
+<pre>
+Disable-headers: referer, user
+</pre>
+
+<p>If you in addition use a proxy server that many other users use
+there is little probability you can be tracked (easily) by the server
+you are copying things from.  You are however much easier to track
+from the logs in the proxy server.  And a court order is quite likely
+to get you tracked in spite of any precautions you take.  
+
+<p>W3mir does not support cookies and thus you cannot be tracked with
+the help of that mechanism.
+
+<hr>
+
+<h3><a name="ns">How do I pretend that I'm using Netscape, Internet
+Explorer or Lynx?</a></h3>
+
+<p>Some web sites give you different documents when you ask for a
+specific URL based on what browser you use, or even what OS you appear
+to be using.  w3mir identifies itself with a string that looks like
+this:
+
+<p><tt>w3mir/<em>version</em>-<em>release-date</em></tt>
+
+<p>Netscape identifies itself with strings that look something like
+this:
+
+<p><tt>Mozilla/3.01 (X11; I; Linux 2.0.30 i586)</tt>
+
+<p>and Internet Explorer says it's something like this:
+
+<p><tt>Mozilla/2.0 (compatible; MSIE 3.02; Windows NT)</tt>
+
+<p>and Lynx says something like this
+
+<p><tt>Lynx/2.6  libwww-FM/2.14</tt>
+
+<p>You can change w3mirs identification with <tt>-agent 'string'</tt>
+on the command line.  In the configuration file you put
+
+<pre>
+Agent: Mozilla/3.01 (X11; I; Linux 2.0.30 i586)
+</pre>
+
+<p>to pretend w3mir is netscape 3.01.
+
+<hr>
+
+<h3><a name="other">How do I do other things?</a></h3>
+
+<p>This document is by no means a complete list of the things you can
+do with w3mir.  The w3mir man page (<tt>man w3mir</tt> or <tt>perldoc
+w3mir</tt> lists more things, and goes into more detail of how things
+work so you can use the knowledge to do neat things.  There are
+several things mentioned only in the man-page that helps you with
+tricky multi-server mirroring, and gives you better control of what to
+get and not to get and under what name to save it on disk.  And a
+couple of other things...
+
+<hr>
+<address>Nicolai Langfeldt 9/7/1998</address>
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3mir.PL
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3mir.PL	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3mir.PL	(revision 20131)
@@ -0,0 +1,3291 @@
+# -*-perl-*-
+
+use Config;
+
+&read_makefile;
+$fullperl = resolve_make_var('FULLPERL') || $Config{'perlpath'};
+$islib = resolve_make_var('INSTALLSITELIB');
+
+$name = $0;
+$name =~ s~^.*/~~;
+$name =~ s~.PL$~~;
+
+open(OUT,"> $name") || 
+  die "Could open $name for writing: $!\n";
+
+print "writing $name\n";
+
+while (<DATA>) {
+  if (m~^\#!/.*/perl.*$~o) {
+    # This substitutes the path perl was installed at on this system
+    # _and_ removed any (-w) options.
+    print OUT "#!",$fullperl,$1,"\n";
+    next;
+  }
+  if (/^use lib/o) {
+    # This substitutes the actuall library install path
+    print OUT "use lib '$islib';\n";
+    next;
+  }
+  print OUT;
+}
+
+close(OUT);
+
+# Make it executable too, and writeable
+chmod 0755, $name;
+
+#### The library
+
+sub resolve_make_var ($) {
+
+  my($var) = shift @_;
+  my($val) = $make{$var};
+
+#  print "Resolving: ",$var,"=",$val,"\n";
+  
+  while ($val =~ s~\$\((\S+)\)~$make{$1}~g) {}
+#  print "Resolved: $var: $make{$var} -> $val\n";
+  $val;
+}
+
+
+sub read_makefile {
+
+  open(MAKEFILE, 'Makefile') || 
+    die "Could not open Makefile for reading: $!\n";
+
+  while (<MAKEFILE>) {
+    chomp;
+    next unless m/^([A-Z]+)\s*=\s*(\S+)$/;
+    $make{$1}=$2;
+#    print "Makevar: $1 = $2\n";
+  }
+
+  close(MAKEFILE)
+}
+
+__END__
+#!/local/bin/perl5 -w
+# Perl 5.002 or later.  w3mir is mostly tested with perl 5.004
+#
+# You might want to change or comment out this:
+use lib '/hom/janl/lib/perl';
+#
+# Once upon a long time ago this was Oscar Nierstrasz's
+# <oscar@cui.unige.ch> htget script.
+#
+# Retrieves HTML pages, creating local copies in the _current_ 
+# directory. The script will check for the last-modified stamp on the
+# document, and will not fetch it if the document isn't changed.
+#
+# Bug list is in w3mir-README.
+#
+# Test cases for janl to use:
+#   w3mir -r -fs http://www.eff.org/ - infinite recursion!
+#     --- but cursory examination seems to indicate confused server...
+#   http://java.sun.com/progGuide/index.html check out the img things.
+#
+# Copyright Holders:
+#   Nicolai Langfeldt, janl@ifi.uio.no
+#   Gorm Haug Eriksen, gorm@usit.uio.no
+#   Chris Szurgot, szurgot@itribe.net
+#   Ed Jordan, ed@olympus.itl.net
+#   Alex Knowles, aknowles@avs.com aka ark.
+# Copying and modification is governed by the "Artistic License" enclosed in
+# the w3mir distribution
+#
+# History (European format date: dd/mm/yy):
+#  oscar 25/03/94 -- added -s option to send output to stdout
+#  oscar 28/03/94 -- made HTTP 1.0 the default
+#  oscar 30/05/94 -- special handling of directory URLs missing a trailing "/"
+#   gorm 20/02/95 -- added mirror capacity + fixed a couple of bugs
+#   janl 28/03/95 -- added a working commandline parser.
+#   janl 18/09/95 -- Changed to use a net http library.  Removed dependency of
+#		     url.pl.
+#   janl 19/09/95 -- Extensive rewrite. Simplified a lot, works better. 
+#		     HTML files are now saved in a new and improved manner,
+#		     which means they can be recognized as such w/o fancy
+#		     filename extention type rules.
+# szurgot 27/01/96-- Added "Plaintextmode" wrapper to binmode PAGE. 
+#                    binmode page is required under Win32, but broke modified
+#                    checking
+#                 -- Minor change added ; to "# '" strings for Emacs cperl-mode
+# szurgot 07/02/96-- When reading in local file for checking of URLs changed
+#                    local ($/) =0; to equal undef;
+#   janl 08/02/96 -- Added szurgot's changes and changed them :-)
+# szurgot 09/02/96-- Added code to strip /#.*$/ from urls when reading from 
+#                    local file
+#                 -- Added hasAlarm variable to w3http.pl. Set to 1 if you have
+#                    alarm(). 0 otherwise.
+#                 -- Moved code setting up the valid extensions list into the
+#                    args processing where it belonged
+#   janl 20/02/96 -- Added szurgot changes again.
+#		  -- Make timeout code work.
+#   		  -- and made another win32 test.
+#   janl 19/03/96 -- Worked through the code for handling not-modified 
+#    		     documents, it was a bit shabby after htmlop was intro'ed.
+#   janl 20/03/96 -- -l fix
+#   janl 23/04/96 -- Added -fs by request (by Rik Faith)
+#   janl 16/05/96 -- Made -R mandatory, added use and support for
+#			w3http::SAVEBIN
+# szurgot 19/05/96-- Win95 adaptions.
+#   janl 19/05/96 -- -C did not exactly work as expected.  Thanks to Petr
+#		     Novak for bug descriptions.
+#   janl 19/05/96 -- Changed logic for @didntget, @got and so on to use
+#		     @queue and %urlstat.
+#   janl 09/09/96 -- Removed -R switch.
+#   janl 14/09/96 -- Added ir (initial referer) switch
+#   janl 21/09/96 -- Made retry code saner.  There probably needs to be a
+#                    sleep before retry comencing switch.  When no tty is
+#                    present it should be fairly long.
+#   gorm 15/09/96 -- Added cr (check robot) switch. Default to 1 (on)
+#   janl 22/09/96 -- Modified gorms patch to use WWW::RobotRules.  Changed
+#		     robot switch to be consistent with current w3mir
+#                    practice.
+#   janl 27/09/96 -- Spelling corrections from charles.curran@ox.ac.uk
+#                 -- Folded in manual diffs from ark.
+#    ark 24/09/96 -- Simple facilities to edit the incomming file(s)
+#   janl 27/09/96 -- Added switch to enable <!--NOMIRROR--> editing and
+#		     foolproofed ark's patch a bit.
+#   janl 02/10/96 -- Added -umask switch.
+#		  -- Redirected documents did not have a meaningful referer
+#		     value (it was undefined).
+#		  -- Got w3mir into strict discipline, found some typos...
+#   janl 20/10/96 -- Mtime is preserved
+#   janl 21/10/96 -- -lc switch added.  Mtime preservation works better.
+#   janl 06/11/96 -- Treat 301 like 302.
+#   janl 02/12/96 -- Added config file code, fetch/ignore rules, apply
+#   janl 04/12/96 -- Better checking of config input.
+#   janl 06/12/96 -- Putting together the URL selection/editing brains.
+#   janl 07/12/96 -- Checking out some bugs.  Adding multiscope options.
+#   janl 12/12/96 -- Adding to and defeaturing the multiscope options.
+#   janl 13/12/96 -- Continuing work in multiscope stuff
+#                 -- Unreferenced file and empty directory removal works.
+#   janl 19/02/97 -- Can extract urls from adobe acrobat pdf files :-)
+#		     Important: It does _not_ edit urls, so they still
+#		     point at the original site(s).
+#   janl 21/02/97 -- Fix -lc bug related to case and the apply things.
+#		  -- only use SAVEURL if needed
+#   janl 11/03/97 -- Finish work on SAVEURL conditional.
+#		  -- Fixed directory removal code.
+#                 -- parse_args did not abort when unknown option/argument
+#		     was specified.
+#   janl 12/03/97 -- Made test case for -lc.  Didn't work.  Fixed it.  I think.
+#		     Realized we have bug w.r.t. hostname caseing.
+#   janl 13/03/97 -- All redirected to URLs within scope are now queued.  
+#		     That should make the mirror more complete, but it won't
+#		     help browsability when it comes to the redirected doc.
+#		  -- Moved robot retrival to the inside of the mirror loop
+#		     since we now possebly mirror several sites.
+#		  -- Changed 'fetch-options' to 'options'.
+#                 -- Added 'proxy-options'/-pflush to controll proxy server(s).
+#   janl 09/04/97 -- Started using URI::URL.
+#   janl 11/04/97 -- Debugging and using URI::URL more correctly various places
+#   janl 09/05/97 -- Added --agent switch
+#   janl 12/05/97 -- Simplified scope checks for root URL, changed URL 'apply'
+#		     processing.
+#		  -- Small output formating fix in the robot rules code.
+#		  -- Version is now 0.99
+#   janl 14/05/97 -- htmpop no-longer puts '<!DOCTYPE...' into doc, so check 
+#		     for '<HTML' instead
+#   janl 11/06/97 -- Made :port optional in server part of auth-domain.
+#			Always removing :80 from server part to match netloc.
+#   janl 22/07/97 -- More debugging of rewrite for new features -B, -I.
+#   janl 01/08/97 -- Fixed bug in RE quoting for Ignore/Fetch
+#   janl 04/08/97 -- s/writepage/write_page/g
+#   janl 07/09/97 -- 0.99b1 is released
+#   janl 19/09/97 -- Kaj Hejer discovers omissions in non-html-url-mining code.
+#                 -- 0.99b2 is released
+#   janl 24/09/97 -- Matt Chapman found bug in realm-name extraction.
+#   janl 10/10/97 -- Referer: header supression supressed User: header instead
+#		  -- Added fixup handling, writes .redirs and .referers
+#		     (no dot in win32)
+#  		  -- Read .w3mirc (w3mir.ini on win32) if present
+#		  -- Stop file removal code from removing these files
+#   janl 16/10/97 -- process_tag was mangling url attributes in tags with more
+#		     than one of them.  Problem found by Robert L. Binkley
+#   janl 04/12/97 -- Fixed problem with authentication, misplaced +
+#		  -- default inter-docuent pause is 0.  I figure it's better
+#		     to keep one httpd occupied in a steady stream than to
+#		     wait for it to die before we talk to it again.
+#   janl 13/12/97 -- The arguments to index.html in the form of index.html/foo
+#		     handling code was incomplete.  To make it complete would
+#		     have been hard, so it was removed.
+#		  -- If a URL changes from file to directory or vice versa
+#		     this is now handled.
+#   janl 11/01/98 -- PDF files with no URLs does not cause warnings now.
+#		  -- Close REFERERS and REDIRECTS before calling w3mfix
+#   janl 22/01/98 -- Proxy authentication as outlined by Christian Geuer
+#   janl 04/02/98 -- Version 1pre1
+#   janl 18/02/98 -- Fixed wild_re after tip by Prentiss Riddle.
+#		  -- Version 1pre2
+#   janl 20/02/98 -- w3http updated to handle complex content-types.
+#		  -- Fix wild_re more, bug noted by James Dumser
+#		  -- 1.0pre3
+#   janl 18/03/98 -- Version 1.0 is released
+#   janl 09/04/98 -- Added feature so user can disable newline conversion.
+#   janl 20/04/98 -- Only convert newlines in HTML files. -> 1.0.2
+#   janl 09/05/98 -- More carefull clean_disk code.
+#		  -- Check if the redirected URL was a root url, if so
+#		     issue a warning and exit.
+#   janl 12/05/98 -- use ->unix_path instead of ->as_string to derive local
+#		     filename.
+#   janl 25/05/98 -- -B didn't work too well.
+#   janl 09/07/98 -- Redirect to fragment broke us, less broken now -> 1.0.4
+#   janl 24/09/98 -- Better errormessages on errors -> 1.0.5
+#   janl 21/11/98 -- Fix errormessages better.
+#   janl 05/01/99 -- Drop 'Referer: (commandline)'
+#   janl 13/04/99 -- Add initial referer to root urls in batch mode.
+#
+# Variable name discipline:
+# - remote, umodified URL.  Variables prefixed 'rum_'
+# - local, filesystem.  Variables prefixed 'lf_'.
+# Use these prefixes so we know what we're working with at all times.
+# Also, URL objects are postfixed _o
+#
+# The apply rules and scope rules work this way:
+# - First apply the user rules to the remote url.
+# - Check if document is within scope after this.
+# - Then apply w3mir's rules to the result.  This results is the local,
+#   filesystem, name.
+#
+# We use features introduced in 5.002.
+require 5.002;
+
+# win32 and $nulldevice need to be globals, other modules use them.
+use vars qw($win32 $nulldevice);
+
+# To figure out what kind of system this is
+BEGIN {
+  use Config;
+  $win32 = ( $Config{'osname'} eq 'MSWin32' ); 
+}
+# More ways to die:
+use Carp;
+# Http module:
+use w3http;
+# html url extraction and manupulation:
+use htmlop;
+# Extract urls from adobe acrobat pdf files:
+use w3pdfuri;
+# Date computer:
+use HTTP::Date;
+# URLs:
+use URI::URL;
+# For flush method
+use FileHandle;
+
+# Full discipline:
+use strict;
+
+# Set params in the http package, HTTP protocol version:
+$w3http::version="1.0";
+
+# The defaults should be for a robotic http agent on good behaviour.
+my $debug=0;			# Debug level
+my $verbose=0;			# Verbosity level, -1 = quiet, 0 = normal, 1...
+my $pause=0;			# Pause between http requests
+my $retryPause=600;		# Pause between retries. 10 minutes.
+my $retry=3;			# Max 3 stabs pr. url.
+my $r=0;			# Recurse? no recursion = absolutify links
+my $remove=0;			# Remove files that are not there?
+my $s=0;			# 0: save on disk 1: stdout 2: just forget 'em
+my $useauth=0;			# Use authorization
+my %authdata;			# Authorization data
+my $check_robottxt = 1;		# Check robots.txt
+my $do_referer = 1;		# Send referers header
+my $do_user = 1;		# Send user header
+my $cache_header = '';		# The cache-control/pragma: no-cache header
+my $using_proxy = 0;		# Using proxy server or not?
+my $batch=0;			# Batch get URLs?
+my $read_urls=0;		# Get urls from STDIN?
+my $abs=0;			# Absolutify URLs?
+my $immediate_redir=0;		# Immediately follow a redirect?
+my @root_urls;			# This is where we start, the root documents
+my @root_dirs;			# The corresponding directories.  for remove
+my $chdirto='';			# Place to chdir to after reading config file
+my %nodelete=();		# Files that should not be deleted
+my $numarg=0;			# Number of arguments accepted.
+
+# Fixup related things
+my $fixrc='';			# Name of w3mfix config file
+my $fixup=1;			# Do things needed to run fixup
+my $runfix=0;			# Run w3mfix for user?
+my $fixopen=0;			# Fixup files open?
+
+my $indexname='index.html';
+
+my $VERSION;
+$VERSION='1.0.8';
+$w3http::agent = my $w3mir_agent = "w3mir/$VERSION-1999-05-28";
+my $iref='';			# Initial referer.  Must evaluate to false
+
+# Derived settings	
+my $mine_urls=0;		# Mine URLs from documents?
+my $process_urls=0;		# Perform (URL) processing of documents?
+
+# Queue of urls to get.
+my @rum_queue = ();
+my @urls = ();
+# URL status map.
+my %rum_urlstat = ();
+# Status codes:
+my $QUEUED   = 0;		# Queued but not gotten yet.
+my $TERROR   = 100;		# Transient error, retry later
+my $HLERR    = 101;		# Permanent error, give up
+my $GOTIT    = 200;		# Gotten. Note similarity to http result code
+my $NOTMOD   = 304;		# Not modified.
+# Negative codes for nonexistent files, easier to check.
+my $NEVERMIND= -1;		# Don't want it
+my $REDIR    = -302;		# Does not exist, redirected
+my $ENOTFND  = -404;		# Does not exist.
+my $OTHERERR = -600;		# Some other error happened
+my $FROBOTS  = -601;		# Forbidden by robots.txt rule
+
+# Directory/files survey:
+my %lf_file;		# What files are present in FS?  Disposition?  One of:
+my $FILEDEL=0;		# Delete file
+my $FILEHERE=1;		# File present in filesystem only
+my $FILETHERE=2;	# File present on server too.
+my %lf_dir;		# Number of files/dirs in dir.  If 0 dir is 
+			# eligible for deletion.
+
+my %fiddled=();		# If a file becomes a directory or a directory
+                        # becomes a file it is considered fiddled and
+                        # w3mir will not fiddle with it again in this
+                        # run.
+
+# Bitbucket device, very OS dependent.
+$nulldevice='/dev/null';
+$nulldevice='nul:' if ($win32);
+
+# What to get, and not.
+# Text of user supplied fetch/ignore rules
+my $rule_text=" # User defined fetch/ignore rules\n";
+# Code ref to the rule procedure
+my $rule_code;
+
+# Code to prefix and postfix the generated code.  Prefix should make
+# $_ contain the url to match.  Postfix should return 1, the default
+# is to get the url/file.
+my $rule_prefix='$rule_code = sub { local($_) = shift;'."\n";
+my $rule_postfix=" return 1;\n}";
+
+# Scope tests generated by URL/Also directives in cfg. The scope code
+# is just like the rule code, but used for program generated
+# fetch/ignore rules related to multiscope retrival.
+my $scope_fetch=" # Automatic fetch rules for multiscope retrival\n";
+my $scope_ignore=" # Automatic ignore rules for multiscope retrival\n";
+my $scope_code;
+
+my $scope_prefix='$scope_code = sub { local($_) = shift;'."\n";
+my $scope_postfix=" return 0;\n}";
+
+# Function to apply to urls, se rule comments.
+my $user_apply_code;	# User specified apply code
+my $apply_code;		# w3mirs apply code
+my $apply_prefix='$apply_code = sub { local($_) = @_;'."\n";
+my $apply_lc=' $_ = lc $_; ';
+my $apply_postfix='  return $_;'."\n}";
+my @user_apply;		# List of users apply rules.
+my @internal_apply;	# List of w3mirs apply rules.
+
+my $infoloss=0;		# 1 if any URL translations (which cause
+                        # information loss) are in effect.  If this is
+                        # true we use the SAVEURL operation.
+my $list;		# List url on STDOUT?
+my $edit;		# Edit doc? Remove <!--NOMIRROR>...<!--/NOMIRROR-->
+my $header;		# Text to insert in header
+my $lc=0;		# Convert urls/filenames to lowercase?
+my $fetch=0;		# What to fetch: -1: Some, 0: not modified 1: all
+my $convertnl=1;	# Convert newlines?
+
+# Non text/html formats we can extract urls from.  Function must take one
+# argument: the filename.
+my %knownformats = ( 'application/pdf', \&w3pdfuri::list,
+		     'application/x-pdf', \&w3pdfuri::list,
+		   );
+
+# Known 'magic numbers' of the known formats.  The value is used as
+# key in %knownformats.  the key part is a exact match for the
+# following <string> beginning at the first byte of the file.
+# This should probably be made more flexible, but not until we need it.
+
+my %knownmagic = ( '%PDF-', 'application/pdf' );
+
+my $iinline='';	# inline RE code to make RE caseinsensitive 
+my $ipost='';	# RE postfix to make it caseinsensitive
+
+usage() unless parse_args(@ARGV);
+
+{
+  my $w3mirc='.w3mirc';
+  
+  $w3mirc='w3mir.ini' if $win32;
+  
+  if (-f $w3mirc) {
+    parse_cfg_file($w3mirc);
+    $nodelete{$w3mirc}=1;
+  }
+}
+
+# Check arguments and options
+if ($#root_urls>=0) {
+  # OK
+} else {
+  print "URLs: $#rum_queue\n";
+  usage("No URLs given");
+}
+
+# Are we converting newlines today?
+$w3http::convert=0 unless $convertnl;
+
+if ($chdirto) {
+  &mkdir($chdirto.'/this-is-not-created-odd-or-what');
+  chdir($chdirto) || 
+    die "w3mir: Can't change working directory to '$chdirto': $!\n";
+}
+
+$SIG{'INT'}=sub { print STDERR "\nCaught SIGINT!\n"; exit 1; };
+$SIG{'QUIT'}=sub { print STDERR "\nCaught SIGQUIT!\n"; exit 1; };
+$SIG{'HUP'}=sub { print STDERR "\nCaught SIGHUP!\n"; exit 1; };
+
+&open_fixup if $fixup;
+
+# Derive how much document processing we should do.
+$mine_urls=( $r || $list );
+$process_urls=(!$batch && !$edit && !$header);
+# $abs can be set explicitly with -abs, and implicitly if not recursing
+$abs = 1 unless $r;
+print "Absolute references\n" if $abs && $debug;
+
+# Cache_controll specified but proxy not in use?
+die "w3mir: If you want to control a cache, use a proxy server!\n"
+  if ($cache_header && !$using_proxy);
+
+# Compile the second order code
+
+# - The rum scope tests
+my $full_rules=$scope_prefix.$scope_fetch.$scope_ignore.$scope_postfix;
+# warn "Scope rules:\n-------------\n$full_rules\n---------------\n";
+eval $full_rules;
+
+die "w3mir: Program generated rules did not compile.\nPlease report to w3mir-core\@usit.uio.no.  The code is:\n----\n".
+  $full_rules."\n----\n"
+  if !defined($scope_code);
+
+$full_rules=$rule_prefix.$rule_text.$rule_postfix;
+# warn "Fetch rules:\n-------------\n$full_rules\n---------------\n";
+eval $full_rules;
+
+# - The user specified rum tests
+die "w3mir: Ignore/Fetch rules did not compile.\nPlease report to w3mir-core\@usit.uio.no.  The code is:\n----\n".
+  $full_rules."\n----\n"
+  if !defined($rule_code);
+
+# - The user specified apply rules
+
+my $full_apply=$apply_prefix.($lc?$apply_lc:'').
+  join($ipost.";\n",@user_apply).(($#user_apply>=0)?$ipost:"").";\n".
+  $apply_postfix;
+eval $full_apply;
+
+die "w3mir: User apply rules did not compile.\nPlease report to w3mir-core\@usit.uio.no. The code is:
+----
+".$full_apply."
+----\n" if !defined($apply_code);
+
+$user_apply_code=$apply_code;
+
+# - The w3mir generated apply rules
+
+$full_apply=$apply_prefix.($lc?$apply_lc:'').
+  join($ipost.";\n",@internal_apply).(($#internal_apply>=0)?$ipost:"").";\n".
+  $apply_postfix;
+eval $full_apply;
+
+die "Internal apply rules did not compile.  The code is:
+----
+".$full_apply."
+----\n" if !defined($apply_code);
+
+# - Information loss via -lc?  There are other sources as well.
+$infoloss=1 if $lc;
+
+warn "Infoloss is $infoloss\n" if $debug;
+
+# More setup:
+
+$w3http::debug=$debug;
+
+$w3http::verbose=$verbose;
+
+my %rum_referers=();	# Array of referers, key: rum_url
+my $Robot_Blob;		# WWW::RobotsRules object, decides if rum_url is 
+			# forbidden to access for us.
+my $rum_url_o;		# rum url, mostly the current, the one we're getting
+my %gotrobots;		# Did I get robots.txt from site? key: url->netloc
+my($authuser,$authpass);# Username and password for authentication with server
+my @rum_newurls;	# List of rum_urls in document
+
+if ($check_robottxt) {
+  # Eval is only way to defer loading of module until we know it's needed?
+  eval 'use WWW::RobotRules;';
+
+  die "Could not load WWW::RobotRules, try -drr switch\n"
+    unless defined(&WWW::RobotRules::parse);
+
+  $Robot_Blob = new WWW::RobotRules $w3mir_agent;
+}
+
+# We have several main-modes of operation.  Here we select one
+if ($r) {
+
+  die "w3mir: No URLs?  Try 'w3mir -h' for help.\n"
+    if $#root_urls==-1;
+
+  warn "Recursive retrival comencing\n" if $debug;
+
+  die "w3mir: Sorry, you cannot combine -r/recurse with -I/read_urls\n"
+    if $read_urls;
+
+  # Recursive
+  my $url;
+  foreach $url (@root_urls) {
+    warn "Root url dequeued: $url\n" if $debug;
+    if (want_this($url)) {
+      queue($url);
+      &add_referer($url,$iref);
+    } else {
+      die "w3mir: Inconsistent configuration: Specified $url is not inside retrival scope\n";
+    }
+  }
+  mirror();
+
+} else {
+  if ($batch) {
+    warn "Batch retrival commencing\n" if $debug;
+    # Batch get
+    if ($read_urls) { 
+      # Get URLs from <STDIN>
+      while (<STDIN>) {
+	chomp;
+	&add_referer($_,$iref);
+	batch_get($_);
+      }
+    } else {
+      # Get URLs from commandline
+      my $url;
+      foreach $url (@root_urls) {
+	&add_referer($url,$iref);
+      }
+      foreach $url (@root_urls) {
+	batch_get($url);
+      }
+    }
+  } else {
+    warn "Single url retrival commencing\n" if $debug;
+
+    # A single URL, with all processing on
+    die "w3mir: You specified several URLs and not -B/batch\n"
+      if $#root_urls>0;
+    queue($root_urls[0]);
+    &add_referer($root_urls[0],$iref);
+    mirror();
+  }
+}
+
+&close_fixup if $fixup;
+
+# This should clean up files:
+&clean_disk if $remove;
+
+warn "w3mir: That's all (".$w3http::xfbytes.'+',$w3http::headbytes.
+  " bytes of it).\n" unless $verbose<0;
+
+if ($runfix) {
+  eval 'use Config;';
+  warn "Running w3mfix\n";
+  if ($win32) {
+    system($Config{'perlpath'}." w3mfix $fixrc");
+  } else {
+    system("w3mfix $fixrc");
+  }
+}
+
+exit 0;
+
+sub get_document {
+  # Get one document by HTTP ($1/rum_url_o).  Save in given filename ($2).
+  # Possebly returning references found in the document.  Caller must
+  # set up referer array, check wantedness and everything else.  We
+  # handle authentication here though.
+
+  my($rum_url_o)=shift;
+  my($lf_url)=shift;
+  croak("\$rum_url_o is empty") if !defined($rum_url_o) || !$rum_url_o;
+  croak("$lf_url is empty") if !defined($lf_url) || !$lf_url;
+
+  # Make sure it's an object
+  $rum_url_o = url $rum_url_o 
+    unless ref $rum_url_o;
+  
+  # Derive a filename from the url, the filename contains no URL-quoting
+  my($lf_name) = (url "file:$lf_url")->unix_path;
+
+  # Make all intermediate directories
+  &mkdir($lf_name) if $s==0;
+
+  my($rum_as_string) = $rum_url_o->as_string;
+
+  print STDERR "GET_DOCUMENT: '",$rum_as_string,"' -> '",$lf_name,"'\n"
+    if $debug;
+
+  my $hostport;
+  my $www_auth='';	# Value of that http reply header
+  my $page_ref;
+  my @rum_newurls;	# List of URLs extracted
+  my $url_extractor;
+  my $do_query;		# Do query or not?
+
+  if (defined($rum_urlstat{$rum_as_string}) && 
+      $rum_urlstat{$rum_as_string}>0) {
+    warn "w3mir: Internal error, ".$rum_as_string.
+      " queued several times\n";
+    next;
+  }
+
+  # Goto here if we want to retry b/c of authentication
+  try_again:
+
+  # Start building the extra http::query arguments again
+  my @EXTRASTUFF=();
+
+  # We'll start by assuming that we're doing the query.
+  $do_query=1;
+    
+  # If we're not checking the timestamp, or the file does not exist
+  # then we get the file unconditionally.  Otherwise we only want it
+  # if it's updated.
+
+  if ($fetch==1) {
+    # Nothing do do?
+  } else {
+    if (-f $lf_name) {
+      if ($fetch==-1) {
+	print STDERR "w3mir: ".($infoloss?$rum_as_string:$lf_name).
+	  ", already have it" if $verbose>=0;
+	if (!$mine_urls) {
+	  # If -fs and the file exists and we don't need to mine URLs
+	  # we're finished!
+	  warn "Already have it, no mining, returning!\n" if $debug;
+	  print STDERR "\n" if $verbose>=0;
+	  return;
+	}
+	$w3http::result=1304;	# Pretend it was 'not modified'
+	$do_query=0;
+      } else {
+	push(@EXTRASTUFF,$w3http::IFMODF,$lf_name);
+      }
+    }
+  }
+
+  if ($do_query) {
+
+    # Does the server want authorization for this file?  $www_auth is
+    # only set if authentication was requested the first time around.
+
+    # For testing:
+    # $www_auth='Basic realm="foo"';
+
+    if ($www_auth) {
+      my($authdata,$method,$realm);
+
+      ($method,$realm)= $www_auth =~ m/^(\S+)\s+realm=\"([^\"]+)\"/i;
+      $method=lc $method;
+      $realm=lc $realm;
+      die "w3mir: '$method' authentication needed, don't know that.\n"
+	if ($method ne 'basic');
+      
+      $hostport = $rum_url_o->netloc;
+      $authdata=$authdata{$hostport}{$realm} || $authdata{$hostport}{'*'} ||
+	$authdata{'*'}{$realm} || $authdata{'*'}{'*'};
+
+      if ($authdata) {
+	push(@EXTRASTUFF,$w3http::AUTHORIZ,$authdata);
+      } else {
+	print STDERR "w3mir: No authorization data for $hostport/$realm\n";
+	$rum_urlstat{$rum_as_string}=$NEVERMIND;
+	next;
+      }
+    }
+    
+    push(@EXTRASTUFF,$w3http::FREEHEAD,$cache_header)
+      if ($cache_header);
+
+    # Insert referer header data if at all
+    push(@EXTRASTUFF,$w3http::REFERER,$rum_referers{$rum_as_string}[0])
+      if ($do_referer && exists($rum_referers{$rum_as_string}));
+
+    push(@EXTRASTUFF,$w3http::NOUSER)
+      unless ($do_user);
+
+    # YES, $lf_url is right, w3http::query handles this like an url so
+    # the quoting must all be in place.
+    my $binfile=$lf_url;
+    $binfile='-' if $s==1;
+    $binfile=$nulldevice if $s==2;
+
+    if ($pause) {
+      print STDERR "w3mir: sleeping\n" if $verbose>0;
+      sleep($pause);
+    }
+
+    print STDERR "w3mir: ".($infoloss?$rum_as_string:$lf_name) 
+      unless $verbose<0;
+    print STDERR "\nFile: $lf_name\n" if $debug;
+
+    &w3http::query($w3http::GETURL,$rum_as_string,
+		   $w3http::SAVEBIN,$binfile,
+		   @EXTRASTUFF);
+
+    print STDERR "w3http::result: '",$w3http::result,
+    "' doc size: ", length($w3http::document),
+    " doc type: -",$w3http::headval{'CONTENT-TYPE'},
+    "- plaintexthtml: ",$w3http::plaintexthtml,"\n"
+      if $debug;
+
+    print "Result: ",$w3http::result," Recurse: $r, html: ",
+    $w3http::plaintexthtml,"\n" 
+      if $debug;
+
+  } # if $do_query
+    
+  if ($w3http::result==200) { # 200 OK 
+    $rum_urlstat{$rum_as_string}=$GOTIT;
+
+    if ($mine_urls || $process_urls) {
+
+      if ($w3http::plaintexthtml) {
+	# Only do URL manipulations if this is a html document with no
+	# special content-encoding.  We do not handle encodings, yet.
+
+	my $page;
+
+	print STDERR ($process_urls)?", processing":", url mining"
+	  if $verbose>0;
+	  
+	print STDERR "\nurl:'$lf_url'\n" 
+	  if $debug;
+
+	print "\nMining URLs: $mine_urls, Process: $process_urls\n" 
+	  if $debug;
+	    
+	($page,@rum_newurls) = 
+	  &htmlop::process($w3http::document,
+			   # Only get a new document if wanted
+			   $process_urls?():($htmlop::NODOC),
+			   $htmlop::CANON,
+			   $htmlop::ABS,$rum_url_o,
+			   # Only list urls if wanted
+			   $mine_urls?($htmlop::LIST):(),
+
+			   # If user wants absolute URLs do not
+			   # relativize them
+
+			   $abs?
+			   ():
+			   (
+			    $htmlop::TAGCALLBACK,\&process_tag,$lf_url,
+			    )
+			  );
+
+#	print "URL: ",join("\nURL: ",@rum_newurls),"\n";
+
+	if ($process_urls) {
+	  $page_ref=\$page;
+	  $w3http::document='';
+	} else {
+	  $page_ref=\$w3http::document;
+	}
+
+      } elsif ($s == 0 &&
+	       ($url_extractor = 
+		$knownformats{$w3http::headval{'CONTENT-TYPE'}})) {
+
+	# The knownformats extractors only work on disk files so write
+	# doc to disk if not there already (non-html text will not be)
+	write_page($lf_name,$w3http::document,1);
+
+	# Now we try our hand at fetching URIs from non-html files.
+	print STDERR ", mining URLs" if $verbose>=1;
+	@rum_newurls = &$url_extractor($lf_name);
+	# warn "URLs from PDF: ",join(', ',@rum_newurls),"\n";
+      }
+      
+      
+    } # if ($mine_urls || $process_urls)
+
+#    print "page_ref defined: ",defined($page_ref),"\n";
+#    print "plaintext: ",$w3http::plaintext,"\n";
+
+    $page_ref=\$w3http::document 
+      if !defined($page_ref) && $w3http::plaintexthtml;
+
+    if ($w3http::plaintexthtml) {
+      # ark: this is where I want to do my changes to the page strip
+      # out the <!--NOMIRROR-->...<!--/NOMIRROR--> Stuff.
+      $$page_ref=~ s/<(!--)?\s*NO\s*MIRROR\s*(--)?>[^\000]*?<(!--)?\s*\/NO\s*MIRROR\s*(--)?>//g 
+	if $edit;
+	  
+      if ($header) {
+	# ark: insert a header string at the start of the page
+	my $mirrorstr=$header;
+	$mirrorstr =~ s/\$url/$rum_as_string/g;
+	insert_at_start( $mirrorstr, $page_ref );
+      }
+    }
+
+    write_page($lf_name,$page_ref,0);
+
+    # print "New urls: ",join("\n",@rum_newurls),"\n";
+
+    return @rum_newurls;
+  }
+
+  if ($w3http::result==304 || #  304 Not modified
+      $w3http::result==1304) { # 1304 Have it
+
+    { 
+      # last = out of nesting
+
+      my $rum_urlstat;
+      my $rum_newurls;
+      
+      @rum_newurls=();
+      
+      print STDERR ", not modified"
+	if $verbose>=0 && $w3http::result==304;
+      
+      $rum_urlstat{$rum_as_string}=$NOTMOD;
+
+      last unless $mine_urls;
+      
+      $rum_newurls=get_references($lf_name);
+
+      # print "New urls: ",ref($rum_newurls),"\n";
+      
+      if (!ref($rum_newurls)) {
+	last;
+      } elsif (ref($rum_newurls) eq 'SCALAR') {
+	$page_ref=$rum_newurls;
+      } elsif (ref($rum_newurls) eq 'ARRAY') {
+	@rum_newurls=@$rum_newurls;
+	last;
+      } else {
+	die "\nw3mir: internal error: Unknown return type from get_references\n";
+      }
+      
+      # Check if it's a html file.  I know this tag is in all html
+      # files, because I put it there as I pull them in.
+      last unless $$page_ref =~ /<HTML/i;
+      
+      warn "$lf_name is a html file\n" if $debug;
+      
+      # It's a html document
+      print STDERR ", mining URLs" if $verbose>=1;
+      
+      # This will give us a list of absolute urls
+      (undef,@rum_newurls) = 
+	&htmlop::process($$page_ref,$htmlop::NODOC,
+			 $htmlop::ABS,$rum_as_string,
+			 $htmlop::USESAVED,'W3MIR',
+			 $htmlop::LIST);
+    }
+
+    print STDERR "\n" if $verbose>=0;
+    return @rum_newurls;
+  }
+	
+  if ($w3http::result==302 || $w3http::result==301) { # Redirect
+    # Cern and NCSA httpd sends 302 'redirect' if a ending / is
+    # forgotten on a url.  More recent httpds send 301 'permanent
+    # redirect' in this case.  Here we check if the difference in URLs
+    # is just a / and if so push the url again with the / added.  This
+    # code only works if the http server has the right idea about its
+    # own name.
+    #
+    # 18/3/97: Added code to queue redirected-to-URLs that are within
+    # the scope of the retrival.
+    my $new_rum_url;
+
+    $rum_urlstat{$rum_as_string}=$REDIR;
+
+    # Absolutify the new url, it might be relative to the requested
+    # document.  That's a ugly wart on some servers/admins.
+    $new_rum_url=url $w3http::headval{'location'};
+    $new_rum_url=$new_rum_url->abs($rum_url_o);
+
+    print REDIRS $rum_as_string,' -> ',$new_rum_url->as_string,"\n"
+      if $fixup;
+
+    if ($immediate_redir) {
+      print STDERR " =>> ",$new_rum_url->as_string,", getting that instead\n";
+      return get_document($new_rum_url,$lf_url);
+    }
+
+    # Some redirect to a fragment of another doc...
+    $new_rum_url->frag(undef);
+    $new_rum_url=$new_rum_url->as_string;
+
+    if ($rum_as_string.'/' eq $new_rum_url) {
+      if (grep { $rum_as_string eq $_; } @root_urls) {
+	print STDERR "\nw3mir: missing / in a start URL detected.  Please fix commandline/config file.\n";
+	exit(1);
+      }
+      print STDERR ", missing /\n";
+      queue($new_rum_url);
+      # Initialize referer to something meaningful
+      $rum_referers{$new_rum_url}=$rum_referers{$rum_as_string};
+    } else {
+      print STDERR " =>> $new_rum_url";
+      if (want_this($new_rum_url)) {
+	print STDERR ", getting that\n";
+	queue($new_rum_url);
+	$rum_referers{$new_rum_url}=$rum_referers{$rum_as_string};
+      } else {
+	print STDERR ", don't want it\n";
+      }
+    }
+    return ();
+  }
+
+  if ($w3http::result==403 || # Forbidden
+      $w3http::result==404 || # Not found
+      $w3http::result==406 || # Not Acceptable, hmm, belongs here?
+      $w3http::result==410) { # Gone - no forwarding address known
+
+    $rum_urlstat{$rum_as_string}=$ENOTFND;
+    &handleerror;
+    print STDERR "Was refered from: ",
+      join(',',@{$rum_referers{$rum_as_string}}),
+      "\n" if defined(@{$rum_referers{$rum_as_string}});
+    return ();
+  }
+
+  if ($w3http::result==407) {
+    # Proxy authentication requested
+    die "Proxy server requests authentication but failed to return the\n".
+      "REQUIRED Proxy-Authenticate header for this condition\n"
+	unless exists($w3http::headval{'proxy-authenticate'});
+
+    die "Proxy authentication is required for ".$w3http::headval{'proxy-authenticate'}."\n";
+  }
+
+  if ($w3http::result==401) {
+    # A www-authenticate reply header should acompany a 401 message.
+    if (!exists($w3http::headval{'www-authenticate'})) {
+      warn "w3mir: Server indicated authentication failure but gave no www-authenticate reply\n";
+      $rum_urlstat{$rum_as_string}=$NEVERMIND;
+    } else {
+      # Unauthorized
+      if ($www_auth) {
+	# Failed when authorization data was supplied.
+	$rum_urlstat{$rum_as_string}=$NEVERMIND;
+	print STDERR ", authorization failed data needed for ",
+	$w3http::headval{'www-authenticate'},"\n"
+	  if ($verbose>=0);
+      } else {
+	if ($useauth) {
+	  # First time failure, send back and retry at once with some known
+	  # user/passwd.
+	  $www_auth=$w3http::headval{'www-authenticate'};
+	  print STDERR ", retrying with authorization\n" unless $verbose<0;
+	  goto try_again;
+	} else {
+	  print ", authorization needed: ",
+	    $w3http::headval{'www-authenticate'},"\n";
+	  $rum_urlstat{$rum_as_string}=$NEVERMIND;
+	}
+      }
+    }
+    return ();
+  }
+   
+  # Something else.  
+  &handleerror;
+}
+
+
+sub robot_check {
+  # Check if URL is allowed by robots.txt, if we respect it at all
+  # that is.  Return 1 it allowed, 0 otherwise.
+
+  my($rum_url_o)=shift;
+  my $hostport;
+
+  if ($check_robottxt) {
+    
+    $hostport = $rum_url_o->netloc;
+    if (!exists($gotrobots{$hostport})) {
+      # Get robots.txt from the server
+      $gotrobots{$hostport}=1;
+      my $robourl="http://$hostport/robots.txt";
+      print STDERR "w3mir: $robourl" if ($verbose>=0);
+      &w3http::query($w3http::GETURL,$robourl);
+      $w3http::document='' if ($w3http::result != 200);
+      print STDERR ", processing" if $verbose>=1;
+      print STDERR "\n" if ($verbose>=0);
+      $Robot_Blob->parse($robourl,$w3http::document);
+    }
+
+    if (!$Robot_Blob->allowed($rum_url_o->as_string)) {
+      # It is forbidden
+      $rum_urlstat{$rum_url_o->as_string}=$FROBOTS;
+      warn "w3mir: ",$rum_url_o->as_string,": forbidden by robots.txt\n";
+      return 0;
+    }
+  }
+  return 1;
+}
+
+
+
+sub batch_get {
+  # Batch get _one_ document.
+  my $rum_url=shift;
+  my $lf_url;
+
+  $rum_url_o = url $rum_url;
+
+  return unless robot_check($rum_url_o);
+
+  ($lf_url=$rum_url) =~ s~.*/~~;
+  if (!defined($lf_url) || $lf_url eq '') {
+    ($lf_url=$rum_url) =~ s~/$~~;
+    $lf_url =~ s~.*/~~;
+    $lf_url .= "-$indexname";
+  }
+
+  warn "Batch get: $rum_url -> $lf_url\n" if $debug;
+
+  $immediate_redir=1; # Do follow redirects immediately
+
+  get_document($rum_url,$lf_url);
+}
+
+
+
+sub mirror {
+  # Mirror (or get) the requested url(s). Possibly recursively.
+  # Working from whatever cwd is at invocation we'll retrieve all
+  # files under it in the file hierarchy.
+  
+  my $rum_url;	# URL of the document we're getting now, defined at main level
+  my $lf_url;	# rum_url after apply - and 
+  my $new_lf_url;
+  my @new_rum_urls;
+  my $rum_ref;
+  
+  while (defined($rum_url = pop(@rum_queue))) {
+
+    warn "mirror: Poped $rum_url from queue\n" if $debug;
+
+    # Unwanted URLs should not be queued
+    die "Found url $rum_url that I don't want in queue!\n" 
+      unless defined($lf_url=apply($rum_url));
+
+    $rum_url_o = url $rum_url;
+
+    next unless robot_check($rum_url_o);
+
+    # Figure out the filename for our local filesystem.
+    $lf_url.=$indexname if $lf_url =~ m~/$~ || $lf_url eq '';
+
+    @new_rum_urls = get_document($rum_url_o,$lf_url);
+
+    print join("\n",@new_rum_urls),"\n" if ($list);
+
+    if ($r) {
+      foreach $rum_ref (@new_rum_urls) {
+	# warn "Recursive url: $rum_ref\n";
+	$new_lf_url=apply($rum_ref);
+	next unless $new_lf_url;
+
+	# warn "Want it\n";
+	$rum_ref =~ s/\#.*$//s;		# Clip off section marks
+	
+	add_referer($rum_ref,$rum_url_o->as_string);
+	queue($rum_ref);
+      }
+    }
+
+    @new_rum_urls=();
+
+    # Is the URL queue empty? Are there outstanding retries?  Refill
+    # the queue from the retry list.
+    if ($#rum_queue<0 && $retry-->0) {
+      foreach $rum_url_o (keys %rum_urlstat) {
+	$rum_url_o = url $rum_url_o;
+	if ($rum_urlstat{$rum_url_o->as_string}==100) {
+	  push(@rum_queue,$rum_url_o->as_string);
+	  $rum_urlstat{$rum_url_o->as_string}=0;
+	}
+      }
+      if ($#rum_queue>=0) {
+	warn "w3mir: Sleeping before retrying.  $retry more times left\n"
+	  if $verbose>=0;
+	sleep($retryPause);
+      }
+    }
+
+  }
+}
+
+
+sub get_references {
+  # Get references from a non-html-on-disk file.  Return references if
+  # we know how to find them.  Return reference do the complete page
+  # if it's html.  Return single numerical 0 if unknown format.
+
+  my($lf_url)=shift;
+  my($urlextractor)=shift;
+
+  my $read; # Buffer of stuff read from file to check filetype
+  my $magic;
+  my $url_extractor;
+  my $rum_ref;
+  my $page;
+
+  warn "w3mir: Looking at local $lf_url\n" if $debug;
+	
+  # Open file and read the first 10kilobytes for file-type-test
+  # purposes.
+  if (!open(TMPF,$lf_url)) {
+    warn "Unable to open $lf_url for reading: $!\n";
+    last;
+  }
+	
+  $page=' 'x10240;
+  $read=sysread(TMPF,$page,length($page),0);
+  close(TMPF);
+	
+  die "Error reading $lf_url: $!\n" if (!defined($read));
+
+  if (!defined($url_extractor)) {
+    $url_extractor=0;
+
+    # Check file against list of magic numbers.
+    foreach $magic (keys %knownmagic) {
+      if (substr($page,0,length($magic)) eq $magic) {
+	$url_extractor = $knownformats{$knownmagic{$magic}};
+	last;
+      }
+    }
+  }
+
+  # Found a extraction method, apply.
+  if ($url_extractor) {
+    print STDERR ", mining URLs" if $verbose>=1;
+    return [&$url_extractor($lf_url)];
+  }
+
+  if ($page =~ /<HTML/i) {
+    open(TMPF,$lf_url) || 
+      die "Could not open $lf_url for reading: $!\n";
+    # read the whole file.
+    local($/)=undef;
+    $page = <TMPF>;
+    close(TMPF);
+    return \$page;
+  }
+
+  return 0;
+}
+
+
+sub open_fixup {
+  # Open the referers and redirects files
+
+  my $reffile='.referers';
+  my $redirfile='.redirs';
+
+  if ($win32) {
+    $reffile="referers";
+    $redirfile="redirs";
+  }
+
+  $nodelete{$reffile} = $nodelete{$redirfile} = 1;
+
+  open(REDIRS,"> $redirfile") || 
+    die "Could not open $redirfile for writing: $!\n";
+
+  autoflush REDIRS 1;
+
+  open(REFERERS,"> $reffile") ||
+    die "Could not open $reffile for writing: $!\n";
+
+  $fixopen=1;
+  eval 'END { close_fixup; 0; }';
+}
+
+
+sub close_fixup {
+  # Close the fixup data files.  In the case of the referer file also
+  # write the entire content
+
+  return unless $fixopen;
+
+  my $referer;
+
+  foreach $referer (keys %rum_referers) {
+    print REFERERS $referer," <- ",join(' ',@{$rum_referers{$referer}}),"\n";
+  }
+
+  close(REFERERS) || warn "Error closing referers file: $!\n";
+  close(REDIRS) || warn "Error closing redirects file: $!\n";
+  $fixopen=0;
+}
+
+
+sub clean_disk {
+  # This procedure removes files that are not present on the server(s)
+  # anymore.
+  
+  # - To avoid removing files that were not fetched due to network
+  #   problems we only do blanket removal IFF all documents were
+  #   fetched w/o problems, eventually.  
+  # - In any case we can remove files the server said were not found
+
+  # The strategy has three main parts:
+  # 1. Find all files we have
+  # 2. Find what files we ought to have
+  # 3. Remove the difference
+  
+  my $complete_retrival=1;	# Flag saying IFF all documents were fetched
+  my $urlstat;			# Tmp storage
+  my $rum_url;
+  my $lf_url;
+  my $lf_dir;
+  my $dirs_to_remove;
+
+  # For fileremoval code
+  eval "use File::Find;" unless defined(&find);
+
+  die "w3mir: Could not load File::Find module.  Don't use -R switch.\n"
+    unless defined(&find);
+  
+  # This to shut up -w
+  $lf_dir=$File::Find::dir;
+
+  # ***** 1. Find out what files we have *****
+  #
+  # This does two things:  For each file or directory found:
+  # - Increases entry count for the container directory
+  # - If it's a file: $lf_file{relative_path}=$FILEHERE;
+
+  chop(@root_dirs);
+  print STDERR "Looking in: ",join(", ",@root_dirs),"\n" if $debug;
+
+  find(\&find_files,@root_dirs);
+
+  # ***** 2. Find out what files we ought to have *****
+  #
+  # First we loop over %rum_urlstat to determine what files are not
+  # present on the server(s).
+  foreach $rum_url (keys %rum_urlstat) {
+    # Figure out name of local file from rum_url
+    next unless defined($lf_url=apply($rum_url));
+
+    $lf_url.=$indexname if $lf_url =~ m~/$~ || $lf_url eq '';
+
+    # find prefixes ./, we must too.
+    $lf_url="./".$lf_url unless substr($lf_url,0,1) eq '/';
+
+    # Ignore if file does not exist here.
+    next unless exists($lf_file{$lf_url});
+    
+    # The apply rules can map several remote files to same local
+    # file.  If we decided to keep file already we stay with that.
+    next if $lf_file{$lf_url}==$FILETHERE;
+    
+    $urlstat=$rum_urlstat{$rum_url};
+
+    # Figure out the status code.
+    if ($urlstat==$GOTIT || $urlstat==$NOTMOD) {
+      # Present on server.  Keep.
+      $lf_file{$lf_url}=$FILETHERE;
+      next;
+    } elsif ($urlstat==$ENOTFND || $urlstat==$NEVERMIND ) {
+      # One of: not on server, can't get, don't want, access forbiden:
+      # Schedule for removal.
+      $lf_file{$lf_url}=$FILEDEL if exists($lf_file{$lf_url});
+      next;
+    } elsif ($urlstat==$OTHERERR || $urlstat==$TERROR) {
+      # Some error occured transfering.
+      $complete_retrival=0;	# The retrival was not complete. Delete less
+    } elsif ($urlstat==$QUEUED) {
+      warn "w3mir: Internal inconsistency, $rum_url marked as queued after retrival terminated\n";
+      $complete_retrival=0;	# Fishy. Be conservative about removing
+    } else {
+      $complete_retrival=0;
+      warn "w3mir: Warning: $rum_url is marked as $urlstat.\n".
+	"w3mir: Please report to w3mir-core\@usit.uio.no.\n";
+    }
+  }				# foreach %rum_urlstat
+
+  # ***** 3. Remove the difference *****
+
+  # Loop over all found files:
+  # - Should we have this file?
+  # - If not: Remove file and decrease directory entry count
+  # Loop as long as there are directories with 0 entry count:
+  # - Loop over all directories with 0 entry count:
+  #   - Remove directory
+  #   - Decrease entry count of parent
+  
+  warn "w3mir: Some error occured, conservative file removal\n"
+    if !$complete_retrival && $verbose>=0;
+
+  # Remove all files we don't want removed from list of files present:
+  foreach $lf_url (keys %nodelete) {
+    print STDERR "Not deleting: $lf_url\n" if $verbose>=1;
+    delete $lf_file{$lf_url} || delete $lf_file{'./'.$lf_url};
+  }
+  
+  # Remove files
+  foreach $lf_url (keys %lf_file) {
+    if (($complete_retrival && $lf_file{$lf_url}==$FILEHERE) ||
+	($lf_file{$lf_url} == $FILEDEL)) {
+      if (unlink $lf_url) {
+	($lf_dir)= $lf_url =~ m~^(.+)/~;
+	$lf_dir{$lf_dir}--;
+	$dirs_to_remove=1 if ($lf_dir{$lf_dir}==0);
+	warn "w3mir: removed file $lf_url\n" if $verbose>=0;
+      } else {
+	warn "w3mir: removal of file $lf_url failed: $!\n";
+      }
+    }
+  }
+  
+  # Remove empty directories
+  while ($dirs_to_remove) {
+    $dirs_to_remove=0;
+    foreach $lf_url (keys %lf_dir) {
+      next if $lf_url eq '.';
+      if ($lf_dir{$lf_url}==0) {
+	if (rmdir($lf_url)) {
+	  warn "w3mir: removed directory $lf_dir\n" if $verbose>=0;
+	  delete $lf_dir{$lf_url};
+	  ($lf_dir)= $lf_url =~ m~^(.+)/~;
+	  $lf_dir{$lf_dir}--;
+	  $dirs_to_remove=1 if ($lf_dir{$lf_dir}==0);
+	} else {
+	  warn "w3mir: removal of directory $lf_dir failed: $!\n";
+	}
+      }
+    }
+  }
+}
+
+
+sub find_files {
+  # This is called by the find procedure for every file/dir found.
+  
+  # This builds two hashes:
+  # lf_file{<file>}: 1: file exists
+  # lf_dir{<dir>): Number of files in directory.
+  
+  lstat($_);
+
+  $lf_dir{$File::Find::dir}++;
+
+  if (-f _) {
+    $lf_file{$File::Find::name}=$FILEHERE;
+  } elsif (-d _) {
+    # null
+    # Bug: If an empty directory exists it will not be removed
+  } else {
+    warn "w3mir: File $File::Find::name has unknown type.  Ignoring.\n";
+  }
+  return 0;
+  
+}
+
+
+sub handleerror {
+  # Handle error status of last http connection, will set the rum_urlstat
+  # appropriately and print a error message.
+
+  my $msg;
+  
+  if ($verbose<0) {
+    $msg="w3mir: ".$rum_url_o->as_string.": ";
+  } else {
+    $msg=": ";
+  }
+
+  if ($w3http::result == 98) {
+    # OS/Network error
+    $msg .= "$!";
+    $rum_urlstat{$rum_url_o->as_string}=$OTHERERR;
+  } elsif ($w3http::result == 100) {
+    # Some kind of error connecting or sending request
+    $msg .= $w3http::restext || "Timeout";
+    $rum_urlstat{$rum_url_o->as_string}=$TERROR;
+  } else {
+    # Other HTTP error
+    $rum_urlstat{$rum_url_o->as_string}=$OTHERERR;
+    $msg .= " ".$w3http::result." ".$w3http::restext;
+    $msg .= " =>> ".$w3http::headval{'location'}
+    if (defined($w3http::headval{'location'}));
+  }
+  print STDERR "$msg\n";
+}
+
+
+sub queue {
+  # Queue given url if appropriate and create a status entry for it
+  my($rum_url_o)=url $_[0];
+
+  croak("BUG: undefined \$rum_url_o")
+    if !defined($rum_url_o);
+
+  croak("BUG: undefined \$rum_url_o->as_string")
+    if !defined($rum_url_o->as_string);
+
+  croak("BUG: ".$rum_url_o->as_string." (fragnent) queued")
+    if $rum_url_o->as_string =~ /\#/;
+  
+  return if exists($rum_urlstat{$rum_url_o->as_string});
+  return unless want_this($rum_url_o->as_string);
+
+  warn "QUEUED: ",$rum_url_o->as_string,"\n" if $debug;
+  
+  # Note lack of scope checks.
+  $rum_urlstat{$rum_url_o->as_string}=$QUEUED;
+  push(@rum_queue,$rum_url_o->as_string);
+}
+
+
+sub root_queue {
+  # Queue function for root urls and directories.  One or the other might
+  # be boolean false, in that case, don't queue it.
+
+  my $root_url_o;
+
+  my($root_url)=shift;
+  my($root_dir)=shift;
+
+  die "w3mir: No fragments in start URLs :".$root_url."\n"
+    if $root_url =~ /\#/;
+
+  if ($root_dir) {
+    print "Root dir: $root_dir\n" if $debug;
+    $root_dir="./$root_dir" unless substr($root_dir,0,1) eq '/' or
+      substr($root_dir,0,2) eq './';
+    push(@root_dirs,$root_dir);
+  }
+
+
+  if ($root_url) {
+    $root_url_o=url $root_url;
+
+    # URL canonification, or what we do of it at least.
+    $root_url_o->host($root_url_o->host);
+
+    warn "Root queue: ".$root_url_o->as_string."\n" if $debug;
+
+    push(@root_urls,$root_url_o->as_string); 
+
+    return $root_url_o;
+ }
+
+}
+
+
+sub write_page {
+  # write a retrieved page to wherever it's supposed to be written.
+  # Added difficulty: all files but plaintext files have already been
+  # written to disk in w3http.
+  
+  # $s == 0 save to disk
+  # $s == 1 dump to stdout
+  # $s == 2 forget
+
+  my($lf_name,$page_ref,$silent) = @_;
+  my($verb);
+
+  if ($silent) {
+    $verb=-1;
+  } else {
+    $verb=$verbose;
+  }
+
+#  confess("\n\$page_ref undefined") if !defined($page_ref);
+  
+  if ($w3http::plaintexthtml) {
+    # I have it in memory
+    if ($s==0) {
+      print STDERR ", saving" if $verb>0;
+
+      while (-d $lf_name) {
+	# This will run once, maybe twice, $fiddled will be canged the
+	# first time
+	if (exists($fiddled{$lf_name})) {
+	  warn "Cannot save $lf_name, there is a directory in the way\n";
+	  return;
+	}
+
+	$fiddled{$lf_name}=1;
+
+	rm_rf($lf_name);
+	print STDERR "w3mir: $lf_name" if $verbose>=0;
+      }
+
+      if (!open(PAGE,">$lf_name")) {
+	warn "\nw3mir: can't open $lf_name for writing: $!\n";
+	return;
+      }
+      if (!$convertnl) {
+	binmode PAGE;
+	warn "BINMODE\n" if $debug;
+      }
+      if ($$page_ref ne '') {
+	print PAGE $$page_ref || die "w3mir: Error writing $lf_name: $!\n";
+      }
+      close(PAGE) || die "w3mir: Error closing $lf_name: $!\n";
+      print STDERR ": ", length($$page_ref), " bytes\n"
+	if $verb>=0;
+      setmtime($lf_name,$w3http::headval{'last-modified'})
+	if exists($w3http::headval{'last-modified'});
+    } elsif ($s==1) {
+      print $$page_ref ;
+    } elsif ($s==2) {
+      print STDERR ", got and forgot it.\n" unless $verb<0;
+    }
+  } else {
+    # Already written by http module, just emit a message if wanted
+    if ($s==0) {
+      print STDERR ": ",$w3http::doclen," bytes\n"
+	if $verb>=0;
+      setmtime($lf_name,$w3http::headval{'last-modified'})
+	  if exists($w3http::headval{'last-modified'});
+    } elsif ($s==2) {
+      print STDERR ", got and forgot it.\n" if $verb>=0;
+    }
+  }
+}
+
+
+sub setmtime {
+  # Set mtime of the given file
+  my($file,$time)=@_;
+  my($tm_sec,$tm_min,$tm_hour,$tm_mday,$tm_mon,$tm_year,$tm_wday,$tm_yday,
+     $tm_isdst,$tics);
+
+  $tm_isdst=0;
+  $tm_yday=-1;
+
+  carp("\$time is undefined"),return if !defined($time);
+
+  $tics=str2time($time);
+  utime(time, $tics, $file) || 
+      warn "Could not change mtime of $file: $!\n";
+}
+
+
+sub movefile {
+  # Rename a file.  Note that copy is not a good alternative, since
+  # copying over NFS is something we want to Avoid.
+
+  # Returns 0 if failure and 1 in case of sucess.
+
+  (my $old,my $new) = @_;
+
+  # Remove anything that might have the name already.
+  if (-d $new) {
+    print STDERR "\n" if $verbose>=0;
+    rm_rf($new);
+    $fiddled{$new}=1;
+    print STDERR "w3mir: $new" if $verbose>=0;
+  } elsif (-e $new) {
+    $fiddled{$new}=1;
+    if (unlink($new)) {
+      print STDERR "\nw3mir: removed $new\nw3mir: $new"
+	if $verbose>=0;
+    } else {
+      return 0;
+    }
+
+  }
+
+  if ($new ne '-' && $new ne $nulldevice) {
+    warn "MOVING $old -> $new\n" if $debug;
+    rename($old,$new) || 
+      warn "Could not rename $old to $new: $!\n",return 0;
+  }
+  return 1;
+}
+
+
+sub mkdir {
+  # Make all intermediate directories needed for a file, the file name
+  # is expected to be included in the argument!
+
+  # Reasons for not using File::Path::mkpath:
+  # - I already wrote this.
+  # - I get to be able to produce as good and precise errormessages as
+  #   unix and perl will allow me.  mkpath will not.
+  # - It's easier to find out if it worked or not.
+  
+  my($file) = @_;
+  my(@dirs) = split("/",$file);
+  my $path;
+  my $dir;
+  my $moved=0;
+
+  if (!$dirs[0]) {
+    shift @dirs;
+    $path='';
+  } else {
+    $path = '.';
+  }
+
+  # This removes the last element of the array, it's meant to shave
+  # off the file name leaving only the directory name, as a
+  # convenience, for the caller.
+  pop @dirs;
+  foreach $dir (@dirs) {
+    $path .= "/$dir";
+    stat($path);
+    # only make if it isn't already there
+    next if -d _;
+
+    while (!-d _) {
+      if (exists($fiddled{$path})) {
+	warn "Cannot make directory $path, there is a file in the way.\n";
+	return;
+      }
+
+      $fiddled{$path}=1;
+
+      if (!-e _) {
+	mkdir($path,0777);
+	last;
+      }
+
+      if (unlink($path)) {
+	warn "w3mir: removed file $path\n" if $verbose>=0;
+      } else {
+	warn "Unable to remove $path: $!\n";
+	next;
+      }
+    
+      warn "mkdir $path\n" if $debug;
+      mkdir($path,0777) ||
+	warn "Unable to create directory $path: $!\n";
+
+      stat($path);
+    }
+  }
+}
+
+
+sub add_referer {
+  # Add a referer to the list of referers of a document.  Unless it's
+  # already there.
+  # Don't mail me if you (only) think this is a bit like a toungetwiser:
+
+  # Don't remember referers if BOTH fixup and referer header is disabled.
+  return if $fixup==0 && $do_referer==0;
+
+  my($rum_referee,$rum_referer) = @_ ;
+  my $re_rum_referer;
+
+  if (exists($rum_referers{$rum_referee})) {
+    $re_rum_referer=quotemeta $rum_referer;
+    if (!grep(m/^$re_rum_referer$/,@{$rum_referers{$rum_referee}})) {
+      push(@{$rum_referers{$rum_referee}},$rum_referer);
+      # warn "$rum_referee <- $rum_referer pushed\n";
+    } else {
+      # warn "$rum_referee <- $rum_referer NOT pushed\n";
+    }
+  } else {
+    $rum_referers{$rum_referee}=[$rum_referer];
+    # warn "$rum_referee <- $rum_referer pushed\n";
+  }
+}
+
+
+sub user_apply {
+  # Apply the user apply rules
+
+  return &$user_apply_code(shift);
+
+# Debug version:
+#  my ($foo,$bar);
+#  $foo=shift;
+#  $bar=&$apply_code($foo);
+#  print STDERR "Apply: $foo -> $bar\n";
+#  return $bar;
+}
+
+sub internal_apply {
+  # Apply the w3mir generated apply rules
+
+  return &$apply_code(shift);
+}
+
+
+sub apply {
+  # Apply the user apply rules.  Then if URL is wanted return result of
+  # w3mir apply rules.  Return the undefined value otherwise.
+
+  my $url = user_apply(shift);
+
+  return undef unless want_this($url);
+
+  internal_apply($url);
+}
+
+
+sub want_this {
+  # Find out if we want the url passed.  Just pass it on to the
+  # generated functions.
+  my($rum_url)=shift;
+
+  # What about robot rules?
+
+  # Does scope rule want this?
+  return &$scope_code($rum_url) &&
+    # Does user rule want this too?
+    &$rule_code($rum_url) 
+  
+}
+
+
+sub process_tag {
+  # Process a tag in html file
+  my $lf_referer = shift;	# User argument
+  my $base_url = shift;		# Not used... why not?
+  my $tag_name = shift;
+  my $url_attrs = shift;
+
+  # Retrun quickly if no URL attributes
+  return unless defined($url_attrs);
+
+  my $attrs = shift;
+
+  my $rum_url;	# The absolute URL
+  my $lf_url;	# The local filesystem url
+  my $lf_url_o; # ... and it's object
+  my $key;
+
+  print STDERR "\nProcess Tag: $tag_name, URL attributes: ", 
+  join(', ',@{$url_attrs}),"\nbase_url: ",$base_url,"\nlf_referer: ",
+  $lf_referer,"\n" 
+    if $debug>2;
+
+  $lf_referer =~ s~^/~~;
+  $lf_referer = "file:/$lf_referer";
+
+  foreach $key (@{$url_attrs}) {
+    if (defined($$attrs{$key})) {
+      $rum_url=$$attrs{$key};
+      printf STDERR "$key = $rum_url\n" if $debug;
+      $lf_url=apply($rum_url);
+      if (defined($lf_url)) {
+
+	printf STDERR "Transformed to $lf_url\n" if $debug>2;
+
+	$lf_url =~ s~^/~~;  # Remove leading / to avoid doubeling
+	$lf_url_o=url "file:/$lf_url";
+
+	# Save new value in the hash
+	$$attrs{$key}=($lf_url_o->rel($lf_referer))->as_string;
+	print STDERR "New value: ",$$attrs{$key},"\n" if $debug>2;
+
+	# If there is potential information loss save the old value too
+	$$attrs{"W3MIR".$key}=$rum_url if $infoloss;
+      }
+    }
+  }
+}
+
+
+sub version {
+  eval 'require LWP;';
+  print $w3mir_agent,"\n";
+  print "LWP version ",$LWP::VERSION,"\n" if defined $LWP::VERSION;
+  print "Perl version: ",$],"\n";
+  exit(0);
+}
+
+
+sub parse_args {
+  my $f;
+  my $i;
+
+  $i=0;
+
+  while ($f=shift) {
+    $i++;
+    $numarg++;
+    # This is a demonstration against Getopts::Long.
+    if ($f =~ s/^-+//) {
+      $s=1,next if $f eq 's';			# Stdout
+      $r=1,next if $f eq 'r';			# Recurse
+      $fetch=1,next if $f eq 'fa';		# Fetch all, no date test
+      $fetch=-1,next if $f eq 'fs';	# Fetch those we don't already have.
+      $verbose=-1,next if $f eq 'q'; 		# Quiet
+      $verbose=1,next if $f eq 'c';		# Chatty
+      &version,next if $f eq 'v';		# Version
+      $pause=shift,next if $f eq 'p';		# Pause between requests
+      $retryPause=shift,next if $f eq 'rp';	# Pause between retries.
+      $s=2,$convertnl=0,next if $f eq 'f';	# Forget
+      $retry=shift,next if $f eq 't';		# reTry
+      $list=1,next if $f eq 'l';		# List urls
+      $iref=shift,next if $f eq 'ir';		# Initial referer
+      $check_robottxt = 0,next if $f eq 'drr';	# Disable robots.txt rules.
+      umask(oct(shift)),next if $f eq 'umask';
+      parse_cfg_file(shift),next if $f eq 'cfgfile';
+      usage(),exit 0 if ($f eq 'help' || $f eq 'h' || $f eq '?');
+      $remove=1,next if $f eq 'R';
+      $cache_header = 'Pragma: no-cache',next if $f eq 'pflush';
+      $w3http::agent=$w3mir_agent=shift,next if $f eq 'agent';
+      $abs=1,next if $f eq 'abs';
+      $convertnl=0,$batch=1,next if $f eq 'B';
+      $read_urls = 1,next if $f eq 'I';
+      $convertnl=0,next if $f eq 'nnc';
+
+      if ($f eq 'lc') {
+	if ($i == 1) {
+	  $lc=1;
+	  $iinline=($lc?"(?i)":"");
+	  $ipost=($lc?"i":"");
+	  next;
+	} else {
+	  die "w3mir: -lc must be the first argument on the commandline.\n";
+	}
+      }
+
+      if ($f eq 'P') {				# Proxy
+	($w3http::proxyserver,$w3http::proxyport)= 
+	  shift =~ /([^:]+):?(\d+)?/;
+	$w3http::proxyport=80 unless $w3http::proxyport;
+	$using_proxy=1;
+	next;
+      }
+    
+      if ($f eq 'd') {		# Debugging level
+	$f=shift;
+	unless (($debug = $f) > 0) {
+	  die "w3mir: debug level must be a number greater than zero.\n";
+	}
+	next;
+      }
+
+      # Those were all the options...
+      warn "w3mir: Unknown option: -$f.  Use -h for usage info.\n";
+      exit(1);
+      
+    } elsif ($f =~ /^http:/) {
+      my ($rum_url_o,$rum_reurl,$rum_rebase,$server);
+
+      $rum_url_o=root_queue($f,'./');
+
+      $rum_rebase = quotemeta( ($rum_url_o->as_string =~ m~^(.*/)~)[0] );
+
+      push(@internal_apply,"s/^".$rum_rebase."//");
+      $scope_fetch.="return 1 if m/^".$rum_rebase."/".$ipost.";\n";
+      $scope_ignore.="return 0 if m/^".
+	quotemeta("http://".$rum_url_o->netloc."/")."/".$ipost.";\n";
+
+    } else {
+      # If we get this far then the commandline is broken
+      warn "Unknown commandline argument: $f.  Use -h for usage info.\n";
+      $numarg--;
+      exit(1);
+    }
+  }
+  return 1;
+}
+
+
+sub parse_cfg_file {
+  # Read the configuration file.  Aborts on errors.  Not good to
+  # mirror something using the wrong config.
+
+  my ( $file ) = @_ ;
+  my ($key, $value, $authserver,$authrealm,$authuser,$authpasswd);
+  my $i;
+
+  die "w3mir: config file $file is not a file.\n" unless -f $file;
+  open(CFGF, $file) || die "Could not open config file $file: $!\n";
+
+  $i=0;
+
+  while (<CFGF>) {
+    # Trim off various junk
+    chomp;
+    s/^#.*//;
+    s/^\s+|\s$//g;
+    # Anything left?
+    next if $_ eq '';
+    # Examine remains
+    $i++;
+    $numarg++;
+
+    ($key, $value) = split(/\s*:\s*/,$_,2);
+    $key = lc $key;
+
+    $iref=$value,next if ( $key eq 'initial-referer' );
+    $header=$value,next if ( $key eq 'header' );
+    $pause=numeric($value),next if ( $key eq 'pause' );
+    $retryPause=numeric($value),next if ( $key eq 'retry-pause' );
+    $debug=numeric($value),next if ( $key eq 'debug' );
+    $retry=numeric($value),next if ( $key eq 'retries' );
+    umask(numeric($value)),next if ( $key eq 'umask' );
+    $check_robottxt=boolean($value),next if ( $key eq 'robot-rules' );
+    $edit=boolean($value),next if ($key eq 'remove-nomirror');
+    $indexname=$value,next if ($key eq 'index-name');
+    $s=nway($value,'save','stdout','forget'),next 
+      if ( $key eq 'file-disposition' );
+    $verbose=nway($value,'quiet','brief','chatty')-1,next
+      if ( $key eq 'verbosity' );
+    $w3http::proxyuser=$value,next if $key eq 'http-proxy-user';
+    $w3http::proxypasswd=$value,next if $key eq 'http-proxy-passwd';
+
+    if ( $key eq 'cd' ) {
+      $chdirto=$value;
+      warn "Use of 'cd' is discouraged\n" unless $verbose==-1;
+      next;
+    }
+    
+    if ($key eq 'http-proxy') {
+      ($w3http::proxyserver,$w3http::proxyport)= 
+	$value =~ /([^:]+):?(\d+)?/;
+      $w3http::proxyport=80 unless $w3http::proxyport;
+      $using_proxy=1;
+      next;
+    }
+
+    if ($key eq 'proxy-options') {
+      my($val,$nval,@popts,$pragma);
+      $pragma=1;
+      foreach $val (split(/\s*,\*/,lc $value)) {
+	$nval=nway($val,'no-pragma','revalidate','refresh','no-store',);
+	# Force use of Cache-control: header
+	$pragma=0 if ($nval==0);
+	# use to force proxy to revalidate
+	$pragma=0,push(@popts,'max-age=0') if ($nval==1);
+	# use to force proxy to refresh
+	push(@popts,'no-cache') if ($nval==2);
+	# use if information transfered is sensitive
+	$pragma=0,push(@popts,'no-store') if ($nval==3);
+      }
+      $cache_header=($pragma?'Pragma: ':'Cache-control: ').join(', ',@popts);
+      next;
+    }
+
+
+    if ($key eq 'url') {
+      my ($rum_url_o,$lf_dir,$rum_reurl,$rum_rebase);
+
+      # A two argument URL: line?
+      if ($value =~ m/^(.+)\s+(.+)/i) {
+	# Two arguments.
+	# The last is a directory, it must end in /
+	$lf_dir=$2;
+	$lf_dir.='/' unless $lf_dir =~ m~/$~;
+
+	$rum_url_o=root_queue($1,$lf_dir);
+
+	# The first is a URL, make it more canonical, find the base.
+	# The namespace confusion in this section is correct.(??)
+	$rum_rebase = quotemeta( ($rum_url_o->as_string =~ m~^(.*/)~)[0] );
+
+	# print "URL: ",$rum_url_o->as_string,"\n";
+	# print "Base: $rum_rebase\n";
+
+	# Translate from rum space to lf space:
+	push(@internal_apply,"s/^".$rum_rebase."/".quotemeta($lf_dir)."/");
+
+	# That translation could lead to information loss.
+	$infoloss=1;
+
+	# Fetch rules tests the rum_url_o->as_string.  Fetch whatever
+	# matches the base.
+	$scope_fetch.="return 1 if m/^".$rum_rebase."/".$ipost.";\n";
+
+	# Ignore whatever did not match the base.
+	$scope_ignore.="return 0 if m/^".
+	  quotemeta("http://".$rum_url_o->netloc."/")."/".$ipost.";\n";
+
+      } else {
+	$rum_url_o=root_queue($value,'./');
+
+	$rum_rebase = quotemeta( ($rum_url_o->as_string =~ m~^(.*/)~)[0] );
+
+	# Translate from rum space to lf space:
+	push(@internal_apply,"s/^".$rum_rebase."//");
+
+	$scope_fetch.="return 1 if m/^".$rum_rebase."/".$ipost.";\n";
+	$scope_ignore.="return 0 if m/^".
+	  quotemeta("http://".$rum_url_o->netloc."/")."/".$ipost.";\n";
+      }
+      next;
+    }
+
+    if ($key eq 'also-quene') {
+      print STDERR 
+	"Found 'also-quene' keyword, please replace with 'also-queue'\n";
+      $key='also-queue';
+    }
+
+    if ($key eq 'also' || $key eq 'also-queue') {
+      if ($value =~ m/^(.+)\s+(.+)/i) {
+	my ($rum_url_o,$lf_dir,$rum_reurl,$rum_rebase);
+	# Two arguments.
+	# The last is a directory, it must end in /
+	# print STDERR "URL ",$1," DIR ",$2,"\n";
+	$lf_dir=$2;
+	$lf_dir.='/' unless $lf_dir =~ m~/$~;
+
+	if ($key eq 'also-queue') {
+	  $rum_url_o=root_queue($1,$lf_dir);
+	} else {
+	  root_queue("",$lf_dir);
+	  $rum_url_o=url $1;
+	  $rum_url_o->host(lc $rum_url_o->host);
+	}
+
+	# The first is a URL, find the base
+	$rum_rebase = quotemeta( ($rum_url_o->as_string =~ m~^(.*/)~)[0] );
+
+#	print "URL: $rum_url_o->as_string\n";
+#	print "Base: $rum_rebase\n";
+#	print "Server: $server\n";
+
+	# Ok, now we can transform and select stuff the right way
+	push(@internal_apply,"s/^".$rum_rebase."/".quotemeta($lf_dir)."/");
+	$infoloss=1;
+
+	# Fetch rules tests the rum_url_o->as_string.  Fetch whatever
+	# matches the base.
+	$scope_fetch.="return 1 if m/^".$rum_rebase."/".$ipost.";\n";
+
+	# Ignore whatever did not match the base.  This cures problem
+	# with '..' from base in in rum space pointing within the the
+	# scope in ra space.  We introduced a extra level (or more) of
+	# directories with the apply above.  Must do same with 'Also:'
+	# directives.
+	$scope_ignore.="return 0 if m/^".
+	  quotemeta("http://".$rum_url_o->netloc."/")."/".$ipost.";\n";
+      } else {
+	die "Also: requires 2 arguments\n";
+      }
+      next;
+    }
+
+    if ($key eq 'quene') {
+      print STDERR "Found 'quene' keyword, please replace with 'queue'\n";
+      $key='queue';
+    }
+
+    if ($key eq 'queue') {
+      root_queue($value,"");
+      next;
+    }
+
+    if ($key eq 'ignore-re' || $key eq 'fetch-re') {
+      # Check that it's a re, better that I am strict than for perl to
+      # make compilation errors.
+      unless ($value =~ /^m(.).*\1[gimosx]*$/) {
+	print STDERR "w3mir: $value is not a recognized regular expression\n";
+	exit 1;
+      }
+      # Fall-through to next cases!
+    }
+
+    if ($key eq 'fetch' || $key eq 'fetch-re') {
+      my $expr=$value;
+      $expr = wild_re($expr).$ipost if ($key eq 'fetch');
+      $rule_text.=' return 1 if '.$expr.";\n";
+      next;
+    }
+
+    if ($key eq 'ignore' || $key eq 'ignore-re') {
+      my $expr=$value;
+      $expr = wild_re($expr).$ipost if ($key eq 'ignore');
+      # print STDERR "Ignore expression: $expr\n";
+      $rule_text.=' return 0 if '.$expr.";\n";
+      next;
+    }
+
+
+    if ($key eq 'apply') {
+      unless ($value =~ /^s(.).*\1.*\1[gimosxe]*$/) {
+	print STDERR
+	  "w3mir: '$value' is not a recognized regular expression\n";
+	exit 1;
+      }
+      push(@user_apply,$value) ;
+      $infoloss=1;
+      next;
+    }
+
+    if ($key eq 'agent') {
+      $w3http::agent=$w3mir_agent=$value;
+      next;
+    }
+
+    # The authorization stuff:
+    if ($key eq 'auth-domain') {
+      $useauth=1;
+      ($authserver, $authrealm) = split('/',$value,2);
+      die "w3mir: server part of auth-domain has format server[:port]\n"
+	unless $authserver =~ /^(\S+(:\d+)?)$|^\*$/;
+      $authserver =~ s/:80$//;
+      die "w3mir: auth-domain '$value' is not valid\n"
+	if !defined($authserver) || !defined($authrealm);
+      $authrealm=lc $authrealm;
+    }
+
+    $authuser=$value if ($key eq 'auth-user');
+    $authpasswd=$value if ($key eq 'auth-passwd');
+
+    # Got a full authentication spec?
+    if ($authserver && $authrealm && $authuser && $authpasswd) {
+      $authdata{$authserver}{$authrealm}=$authuser.":".$authpasswd;
+      print "Authentication for $authserver/$authrealm is ".
+	"$authuser/$authpasswd\n" if $verbose>=0;
+      # exit;
+      # Invalidate tmp vars
+      $authserver=$authrealm=$authuser=$authpasswd=undef;
+      next;
+    }
+
+    next if $key eq 'auth-user' || $key eq 'auth-passwd' || 
+      $key eq 'auth-domain';
+
+    if ($key eq 'fetch-options') {
+      warn "w3mir: The 'fetch-options' directive has been renamed to 'options'\nw3mir: Please change your configuration file.\n";
+      $key='options';
+      # Fall through to 'options'!
+    }
+
+    if ($key eq 'options') {
+      
+      my($val,$nval);
+      foreach $val (split(/\s*,\s*/,lc $value)) {
+	if ($i==1) {
+	  $nval=nway($val,'recurse','no-date-check','only-nonexistent',
+		     'list-urls','lowercase','remove','batch','read-urls',
+		     'abs','no-newline-conv');
+	  $r=1,next if $nval==0;
+	  $fetch=1,next if $nval==1;
+	  $fetch=-1,next if $nval==2;
+	  $list=1,next if $nval==3;
+	  if ($nval==4) {
+	    $lc=1;
+	    $iinline=($lc?"(?i)":"");
+	    $ipost=($lc?"i":"");
+	    next ;
+	  }
+	  $remove=1,next if $nval==5;
+	  $convertnl=0,$batch=1,next if $nval==6;
+	  $read_urls=1,next if $nval==7;
+	  $abs=1,next if $nval==8;
+	  $convertnl=0,next if $nval==9;
+        } else {
+	    die "w3mir: options must be the first directive in the config file.\n";
+	}
+      }
+      next;
+    }
+
+    if ($key eq 'disable-headers') {
+      my($val,$nval);
+      foreach $val (split(/\s*,\s*/,lc $value)) {
+	$nval=nway($val,'referer','user');
+	$do_referer=0,next if $nval==0;
+	$do_user=0,next if $nval==1;
+      }
+      next;
+    }
+
+
+    if ($key eq 'fixup') {
+
+      $fixrc="$file";
+      # warn "Fixrc: $fixrc\n";
+
+      my($val,$nval);
+      foreach $val (split(/\s*,\s*/,lc $value)) {
+	$nval=nway($val,'on','run','noindex','off');
+	$runfix=1,next if $nval==1;
+	# Disable fixup
+	$fixup=0,next if $nval==3;
+	# Ignore everyting else
+      }
+      next;
+    }
+
+    die "w3mir: Unrecognized directive ('$key') in config file $file at line $.\n";
+
+  }
+  close(CFGF);
+
+  if (defined($w3http::proxypasswd) && $w3http::proxyuser) {
+    warn "Proxy authentication: ".$w3http::proxyuser.":".
+      $w3http::proxypasswd."\n" if $verbose>=0;
+  }
+
+}
+
+
+sub wild_re {
+  # Here we translate unix wildcard subset to to perlre
+  local($_) = shift;
+
+  # Quote anything that's RE and not wildcard: / ( ) \ | { } + $ ^
+  s~([\/\(\)\\\|\{\}\+)\$\^])~\\$1~g;
+  # . -> \.
+  s~\.~\\.~g;
+  # * -> .*
+  s~\*~\.\*~g;
+  # ? -> .
+  s~\?~\.~g;
+
+  # print STDERR "wild_re: $_\n";
+
+  return $_ = '/'.$_.'/';
+}
+
+
+sub numeric {
+  # Check if argument is numeric?
+  my ( $number ) = @_ ;
+  return oct($number) if ($number =~ /\d+/ || $number =~ /\d+.\d+/);
+  die "Expected a number, got \"$number\"\n";
+}
+
+
+sub boolean {
+  my ( $boolean ) = @_ ;
+
+  $boolean = lc $boolean;
+
+  return 0 if ($boolean eq 'false' || $boolean eq 'off' || $boolean eq '0');
+  return 1 if ($boolean eq 'true' || $boolean eq 'on' || $boolean eq '1');
+  die "Expected a boolean, got \"$boolean\"\n";
+}
+
+
+sub nway {
+  my ( $value ) = shift;
+  my ( @values ) = @_;
+  my ( $val ) = 0;
+
+  $value = lc $value;
+  while (@_) {
+    return $val if $value eq shift;
+    $val++;
+  }
+  die "Expected one of ".join(", ",@values).", got \"$value\"\n";
+}
+
+
+sub insert_at_start {
+  # ark: inserts the first arg at the top of the html in the second arg
+  # janl: The second arg must be a reference to a scalar.
+  my( $str, $text_ref ) = @_;
+  my( @possible ) =("<BODY.*?>", "</HEAD.*?>", "</TITLE.*?>", "<HTML.*?>" );
+  my( $f, $done );
+  
+  $done=0;
+  @_=@possible;
+  
+  while( $done!=1 && ($f=shift) ){
+    print "Searching for: $f\n";
+    if( $$text_ref =~ /$f/i ){
+      print "found it!\n";
+      $$text_ref =~ s/($f)/$1\n$str/i;
+      $done=1;
+    }
+  }
+}
+
+
+
+sub rm_rf {
+  # Recursively remove directories and other files
+  # File::Path::rmtree does a similar thing but the messages are wrong
+
+  my($remove)=shift;
+
+  eval "use File::Find;" unless defined(&finddepth);
+
+  die "w3mir: Could not load File::Find module when trying to remove $remove\n"
+    unless defined(&find);
+
+  finddepth(\&remove_everything,$remove);
+
+  if (rmdir($remove)) {
+    print STDERR "\nw3mir: removed directory $remove\n" if $verbose>=0;
+  } else {
+    print STDERR "w3mir: could not remove $remove: $!\n";
+  }
+}
+
+
+sub remove_everything {
+  # This does the removal
+  ((-d && rmdir($_)) || unlink($_)) && $verbose>=0 &&
+    print STDERR "w3mir: removed $File::Find::name\n";
+}
+
+
+
+sub usage {
+  my($message)=shift @_;
+
+  print STDERR "w3mir: $message\n" if $message;
+  
+  die 'w3mir: usage: w3mir [options] <single-http-url>
+          or: w3mir -B [-I] [options] [<http-urls>]
+
+    Options :
+	-agent <agent>	- Set the agent name.  Default is w3mir
+	-abs		- Force all URLs to be absolute.
+	-B		- Batch-get documents.
+	-I		- The URLs to get are read from standard input.
+	-c		- be more Chatty.
+	-cfgfile <file> - Read config from file
+	-d <debug-level>- set debug level to 1 or 2
+	-drr		- Disable robots.txt rules.
+	-f		- Forget all files, nothing is saved to disk.
+	-fa		- Fetch All, will not check timestamps.
+	-fs		- Fetch Some, do not fetch the files we already have.
+	-ir <referer>	- Initial referer.  For picky servers.
+	-l		- List URLs in the documents retrived.
+	-lc		- Convert all URLs (and filenames) to lowercase.
+				This does not work reliably.
+	-p <n>		- Pause n seconds before retriving each doc.
+	-q		- Quiet, error-messages only
+        -rp <n>		- Retry Pause in seconds.
+	-P <server:port>- Use host/port for proxy http requests
+        -pflush		- Flush proxy server.
+	-r		- Recursive mirroring.
+        -R		- Remove files not referenced or not present on server.
+	-s		- Send output to stdout instead of file
+	-t <n>		- How many times to (re)try getting a failed doc?
+        -umask <umask>  - Set umask for mirroring, must be usual octal format.
+	-nnc		- No Newline Conversion.  Disable newline conversions.
+	-v		- Show w3mir version.
+';
+}
+__END__
+# -*- perl -*- There must be a blank line here
+
+=head1 NAME
+
+w3mir - all purpose HTTP-copying and mirroring tool
+
+=head1 SYNOPSIS
+
+B<w3mir> [B<options>] [I<HTTP-URL>]
+
+B<w3mir> B<-B> [B<options>] <I<HTTP-URLS>>
+
+B<w3mir> is a all purpose HTTP copying and mirroring tool.  The
+main focus of B<w3mir> is to create and maintain a browsable copy of
+one, or several, remote WWW site(s).
+
+Used to the max w3mir can retrive the contents of several related
+sites and leave the mirror browseable via a local web server, or from
+a filesystem, such as directly from a CDROM.  
+
+B<w3mir> has options for all operations that are simple enough for
+options.  For authentication and passwords, multiple site retrievals
+and such you will have to resort to a L</CONFIGURATION-FILE>.  If
+browsing from a filesystem references ending in '/' needs to be
+rewritten to end in '/index.html', and in any case, if there are URLs
+that are redirected will need to be changed to make the mirror
+browseable, see the documentation of B<Fixup> in the
+L</CONFIGURATION-FILE> secton.
+
+B<w3mir>s default behavior is to do as little as possible and to be as
+nice as possible to the server(s) it is getting documents from.  You
+will need to read through the options list to make B<w3mir> do more
+complex, and, useful things.  Most of the things B<w3mir> can do is
+also documented in the w3mir-HOWTO which is available at the B<w3mir>
+home-page (F<http://www.math.uio.no/~janl/w3mir/>) as well as in the
+w3mir distribution bundle.
+
+=head1 DESCRIPTION
+
+You may specify many options and one HTTP-URL on the w3mir
+command line.
+
+A single HTTP URL I<must> be specified either on the command line or
+in a B<URL> directive in a configuration file.  If the URL refers to a
+directory it I<must> end with a "/", otherwise you might get surprised
+at what gets retrieved (e.g. rather more than you expect).
+
+Options must be prefixed with at least one - as shown below, you can
+use more if you want to. B<-cfgfile> is equivalent to B<--cfgfile> or
+even B<------cfgfile>.  Options cannot be I<clustered>, i.e., B<-r -R>
+is not equivalent to B<-rR>.
+
+=over 4
+
+=item B<-h> | B<-help> | B<-?>
+
+prints a brief summary of all command line options and exits.
+
+=item B<-cfgfile> F<file>
+
+Makes B<w3mir> read the given configuration file.  See the next section
+for how to write such a file.
+
+=item B<-r>
+
+Puts B<w3mir> into recursive mode.  The default is to fetch only one
+document and then quit.  'I<recursive>' mode means that all the
+documents linked to the given document that are fetched, and all they
+link to in turn and so on.  But only I<Iff> they are in the same
+directory or under the same directory as the start document.  Any
+document that is in or under the starting documents directory is said
+to be within the I<scope of retrieval>.
+
+=item B<-fa>
+
+Fetch All.  Normally B<w3mir> will only get the document if it has been
+updated since the last time it was fetched.  This switch turns that
+check off.
+
+=item B<-fs>
+
+Fetch Some.  Not the opposite of B<-fa>, but rather, fetch the ones we
+don't have already.  This is handy to restart copying of a site
+incompletely copied by earlier, interrupted, runs of B<w3mir>.
+
+=item B<-p> I<n>
+
+Pause for I<n> seconds between getting each document.  The default is
+30 seconds.
+
+=item B<-rp> I<n>
+
+Retry Pause, in seconds.  When B<w3mir> fails to get a document for some
+technical reason (timeout mainly) the document will be queued for a
+later retry.  The retry pause is how long B<w3mir> waits between
+finishing a mirror pass before starting a new one to get the still
+missing documents.  This should be a long time, so network conditions
+have a chance to get better.  The default is 600 seconds (10 minutes),
+which might be a bit too short, for batch running B<w3mir> I would
+suggest an hour (3600 seconds) or more.
+
+=item B<-t> I<n>
+
+Number of reTries.  If B<w3mir> cannot get all the documents by the
+I<n>th retry B<w3mir> gives up.  The default is 3.
+
+=item B<-drr>
+
+Disable Robot Rules.  The robot exclusion standard is described in
+http://info.webcrawler.com/mak/projects/robots/norobots.html.  By
+default B<w3mir> honors this standard.  This option causes B<w3mir> to
+ignore it.
+
+=item B<-nnc>
+
+No Newline Conversion.  Normally w3mir converts the newline format of
+all files that the web server says is a text file.  However, not all
+web servers are reliable, and so binary files may become corrupted due
+to the newline conversion w3mir performs.  Use this option to stop
+w3mir from converting newlines.  This also causes the file to be
+regarded as binary when written to disk, to disable the implicit
+newline conversion when saving text files on most non-Unix systems.
+
+This will probably be on by default in version 1.1 of w3mir, but not
+in version 1.0.
+
+=item B<-R>
+
+Remove files.  Normally B<w3mir> will not remove files that are no
+longer on the server/part of the retrieved web of files.  When this
+option is specified all files no longer needed or found on the servers
+will be removed.  If B<w3mir> fails to get a document for I<any> other
+reason the file will not be removed.
+
+=item B<-B>
+
+Batch fetch documents whose URLs are given on the commandline.
+
+In combination with the B<-r> and/or B<-l> switch all HTML and PDF
+documents will be mined for URLs, but the documents will be saved on
+disk unchanged.  When used with the B<-r> switch only one single URL
+is allowed.  When not used with the B<-r> switch no HTML/URL
+processing will be performed at all.  When the B<-B> switch is used
+with B<-r> w3mir will not do repeated mirrorings reliably since the
+changes w3mir needs to do, in the documents, to work reliably are not
+done.  In any case it's best not to use B<-R> in combination with
+B<-B> since that can result in deleting rather more documents than
+expected.  Hwowever, if the person writing the documents being copied
+is good about making references relative and placing the <HTML> tag at
+the beginning of documents there is a fair chance that things will
+work even so.  But I wouln't bet on it.  It will, however, work
+reliably for repeated mirroring if the B<-r> switch is not used.
+
+When the B<-B> switch is specified redirects for a given document will
+be followed no matter where they point.  The redirected-to document
+will be retrieved in the place of the original document.  This is a
+potential weakness, since w3mir can be directed to fetch any document
+anywhere on the web.
+
+Unless used with B<-r> all retrived files will be stored in one
+directory using the remote filename as the local filename.  I.e.,
+F<http://foo/bar/gazonk.html> will be saved as F<gazonk.html>.
+F<http://foo/bar/> will be saved as F<bar-index.html> so as to avoid
+name colitions for the common case of URLs ending in /.
+
+=item B<-I>
+
+This switch can only be used with the B<-B> switch, and only after it
+on the commandline or configuration file.  When given w3mir will get
+URLs from standard input (i.e., w3mir can be used as the end of a pipe
+that produces URLs.)  There should only be one URL pr. line of input.
+
+=item B<-q>
+
+Quiet.  Turns off all informational messages, only errors will be
+output.
+
+=item B<-c>
+
+Chatty.  B<w3mir> will output more progress information.  This can be
+used if you're watching B<w3mir> work.
+
+=item B<-v>
+
+Version.  Output B<w3mir>s version.
+
+=item B<-s>
+
+Copy the given document(s) to STDOUT.
+
+=item B<-f>
+
+Forget.  The retrieved documents are not saved on disk, they are just
+forgotten.  This can be used to prime the cache in proxy servers, or
+not save documents you just want to list the URLs in (see B<-l>).
+
+=item B<-l>
+
+List the URLs referred to in the retrieved document(s) on STDOUT.
+
+=item B<-umask> I<n>
+
+Sets the umask, i.e., the permission bits of all retrieved files.  The
+number is taken as octal unless it starts with a 0x, in which case
+it's taken as hexadecimal.  No matter what you set this to make sure
+you get write as well as read access to created files and directories.
+
+Typical values are: 
+
+=over 8
+
+=item 022
+
+let everyone read the files (and directories), only you can change
+them. 
+
+=item 027
+
+you and everyone in the same file-group as you can read, only you can
+change them.
+
+=item 077
+
+only you can read the files, only you can change them.
+
+=item 0
+
+everyone can read, write and change everything.
+
+=back
+
+The default is whatever was set when B<w3mir> was invoked.  022 is a
+reasonable value.
+
+This option has no meaning, or effect, on Win32 platforms.
+
+=item B<-P> I<server:port>
+
+Use the given server and port is a HTTP proxy server.  If no port is
+given port 80 is assumed (this is the normal HTTP port).  This is
+useful if you are inside a firewall, or use a proxy server to save
+bandwidth.
+
+=item B<-pflush>
+
+Proxy flush, force the proxy server to flush it's cache and re-get the
+document from the source.  The I<Pragma: no-cache> HTTP/1.0 header is
+used to implement this.
+
+=item B<-ir> I<referrer>
+
+Initial Referrer.  Set the referrer of the first retrieved document.
+Some servers are reluctant to serve certain documents unless this is
+set right.
+
+=item B<-agent> I<agent>
+
+Set the HTTP User-Agent fields value.  Some servers will serve
+different documents according to the WWW browsers capabilities.
+B<w3mir> normally has B<w3mir>/I<version> in this header field.
+Netscape uses things like B<Mozilla/3.01 (X11; I; Linux 2.0.30 i586)>
+and MSIE uses things like B<Mozilla/2.0 (compatible; MSIE 3.02;
+Windows NT)> (remember to enclose agent strings with spaces in with
+double quotes ("))
+
+=item B<-lc>
+
+Lower Case URLs. Some OSes, like W95 and NT, are not case sensitive
+when it comes to filenames.  Thus web masters using such OSes can case
+filenames differently in different places (apps.html, Apps.html,
+APPS.HTML).  If you mirror to a Unix machine this can result in one
+file on the server becoming many in the mirror.  This option
+lowercases all filenames so the mirror corresponds better with the
+server.
+
+If given it must be the first option on the command line.
+
+This option does not work perfectly.  Most especially for mixed case
+host-names.
+
+=item B<-d> I<n>
+
+Set the debug level.  A debug level higher than 0 will produce lots of
+extra output for debugging purposes.
+
+=item B<-abs>
+
+Force all URLs to be absolute.  If you retrive
+F<http://www.ifi.uio.no/~janl/index.html> and it references foo.html
+the referense is absolutified into
+F<http://www.ifi.uio.no/~janl/foo.html>.  In other words, you get
+absolute references to the origin site if you use this option.
+
+=back
+
+=head1 CONFIGURATION-FILE
+
+Most things can be mirrored with a (long) command line.  But multi
+server mirroring, authentication and some other things are only
+available through a configuration file.  A configuration file can
+either be specified with the B<-cfgfile> switch, but w3mir also looks
+for .w3mirc (w3mir.ini on Win32 platforms) in the directory where
+w3mir is started from.
+
+The configuration file consists of lines of comments and directives.
+A directive consists of a keyword followed by a colon (:) and then one
+or several arguments.
+
+ # This is a comment.  And the next line is a directive:
+ Options: recurse, remove
+
+A comment can only start at the beginning of a line.  The directive
+keywords are not case-sensitive, but the arguments I<might> be.
+
+=over 4
+
+=item Options: I<recurse> | I<no-date-check> | I<only-nonexistent> | I<list-urls> | I<lowercase> | I<remove> | I<batch> | I<input-urls> | I<no-newline-conv>
+
+This must be the first directive in a configuration file.  
+
+=over 8
+
+=item I<recurse>
+
+see B<-r> switch.
+
+=item I<no-date-check>
+
+see B<-fa> switch.
+
+=item I<only-nonexistent>
+
+see B<-fs> switch.
+
+=item I<list-urls>
+
+see B<-l> option.
+
+=item I<lowercase>
+
+see B<-lc> option. 
+
+=item I<remove>
+
+see B<-R> option.
+
+=item I<batch>
+
+see B<-B> option.
+
+=item I<input-urls>
+
+see B<-I> option.
+
+=item I<no-newline-conv>
+
+see B<-nnc> option.
+
+=back
+
+=item URL: I<HTTP-URL> [I<target-directory>]
+
+The URL directive may only appear once in any configuration file.
+
+Without the optional target directory argument it corresponds directly
+to the I<single-HTTP-URL> argument on the command line.  
+
+If the optional target directory is given all documents from under the
+given URL will be stored in that directory, and under.  The target
+directory is most likely only specified if the B<Also> directive is
+also specified.
+
+If the URL given refers to a directory it I<must> end in a "/",
+otherwise you might get quite surprised at what gets retrieved.
+
+Either one URL: directive or the single-HTTP-URL at the command-line
+I<must> be given.
+
+=item Also: I<HTTP-URL directory>
+
+This directive is only meaningful if the I<recurse> (or B<-r>)
+option is given.
+
+The directive enlarges the scope of a recursive retrieval to contain
+the given HTTP-URL and all documents in the same directory or under.
+Any documents retrieved because of this directive will be stored in the
+given directory of the mirror.
+
+In practice this means that if the documents to be retrieved are stored
+on several servers, or in several hierarchies on one server or any
+combination of those.  Then the B<Also> directive ensures that we get
+everything into one single mirror.
+
+This also means that if you're retrieving
+
+  URL: http://www.foo.org/gazonk/
+
+but it has inline icons or images stored in http://www.foo.org/icons/
+which you will also want to get, then that will be retrieved as well by
+entering
+
+  Also: http://www.foo.org/icons/ icons
+
+As with the URL directive, if the URL refers to a directory it I<must>
+end in a "/".
+
+Another use for it is when mirroring sites that have several names
+that all refer to the same (logical) server:
+
+  URL: http://www.midifest.com/
+  Also: http://midifest.com/ .
+
+At this point in time B<w3mir> has no mechanism to easily enlarge the
+scope of a mirror after it has been established.  That means that you
+should survey the documents you are going to retrieve to find out what
+icons, graphics and other things they refer to that you want.  And
+what other sites you might like to retrieve.  If you find out that
+something is missing you will have to delete the whole mirror, add the
+needed B<Also> directives and then reestablish the mirror.  This lack
+of flexibility in what to retrieve will be addressed at a later date.
+
+See also the B<Also-quene> directive.
+
+=item Also-quene: I<HTTP-URL directory>
+
+This is like Also, except that the URL itself is also quened.  The
+Also directive will not cause any documents to be retrived UNLESS they
+are referenced by some other document w3mir has already retrived.
+
+=item Quene: I<HTTP-URL>
+
+This is quenes the URL for retrival, but does not enlarge the scope of
+the retrival.  If the URL is outside the scope of retrival it will not
+be retrived anyway.
+
+The observant reader will see that B<Also-quene> is like B<Also>
+combined with B<Quene>.
+
+=item Initial-referer: I<referer>
+
+see B<-ir> option.
+
+=item Ignore: F<wildcard>
+
+=item Fetch: F<wildcard>
+
+=item Ignore-RE: F<regular-expression>
+
+=item Fetch-RE: F<regular-expression>
+
+These four are used to set up rules about which documents, within the
+scope of retrieval, should be gotten and which not.  The default is to
+get I<anything> that is within the scope of retrieval.  That may not
+be practical though.  This goes for CGI scripts, and especially server
+side image maps and other things that are executed/evaluated on the
+server.  There might be other things you want unfetched as well.
+
+B<w3mir> stores the I<Ignore>/I<Fetch> rules in a list.  When a
+document is considered for retrieval the URL is checked against the
+list in the same order that the rules appeared in the configuration
+file.  If the URL matches any rule the search stops at once.  If it
+matched a I<Ignore> rule the document is not fetched and any URLs in
+other documents pointing to it will point to the document at the
+original server (not inside the mirror).  If it matched a I<Fetch>
+rule the document is gotten.  If not matched by any ruøes the document
+is gotten.
+
+The F<wildcard>s are a very limited subset of Unix-wildcards.
+B<w3mir> understands only 'I<?>', 'I<*>', and 'I<[x-y]>' ranges.
+
+The F<perl-regular-expression> is perls superset of the normal Unix
+regular expression syntax.  They must be completely specified,
+including the prefixed m, a delimiter of your choice (except the
+paired delimiters: parenthesis, brackets and braces), and any of the
+RE modifiers. E.g.,
+
+  Ignore-RE: m/.gif$/i
+
+or
+
+  Ignore-RE: m~/.*/.*/.*/~
+
+and so on.  "#" cannot be used as delimiter as it is the comment
+character in the configuration file.  This also has the bad
+side-effect of making you unable to match fragment names (#foobar)
+directly.  Fortunately perl allows writing ``#'' as ``\043''.
+
+You must be very carefull of using the RE anchors (``^'' and ``$''
+with the RE versions of these and the I<Apply> directive. Given the
+rules:
+
+  Fetch-RE: m/foobar.cgi$/
+  Ignore: *.cgi
+
+the all files called ``foobar.cgi'' will be fetched. However, if the
+file is referenced as ``foobar.cgi?query=mp3'' it will I<not> be
+fetched since the ``$'' anchor will prevent it from matching the
+I<Fetch-RE> directive and then it will match the I<Ignore> directive
+instead. If you want to match ``foobar.cgi'' but not ``foobar.cgifu''
+you can use perls ``\b'' character class which matches a word
+boundrary:
+
+  Fetch-RE: m/foobar.cgi\b/
+  Ignore: *.cgi
+
+which will get ``foobar.cgi'' as well as ``foobar.cgi?query=mp3'' but
+not ``foobar.cgifu''. BUT, you must keep in mind that a lot of
+diffetent characters make a word boundrary, maybe something more
+subtle is needed.
+
+=item Apply: I<regular-expression>
+
+This is used to change a URL into another URL.  It is a potentially
+I<very> powerful feature, and it also provides ample chance for you to
+shoot your own foot. The whole aparatus is somewhat tenative, if you
+find there is a need for changes in how Apply rules work please
+E-mail. If you are going to use this feature please read the
+documentation for I<Fetch-RE> and I<Ignore-RE> first.
+
+The B<Apply> expressions are applied, in sequence, to the URLs in
+their absolute form. I.e., with the whole
+http://host:port/dir/ec/tory/file URL. It is only after this B<w3mir>
+checks if a document is within the scope of retrieval or not. That
+means that B<Apply> rules can be used to change certain URLs to fall
+inside the scope of retrieval, and vice versa.
+
+The I<regular-expression> is perls superset of the usual Unix regular
+expressions for substitution.  As with I<Fetch> and I<Ignore> rules it
+must be specified fully, with the I<s> and delimiting character.  It
+has the same restrictions with regards to delimiters. E.g.,
+
+  Apply: s~/foo/~/bar/~i
+
+to translate the path element I<foo> to I<bar> in all URLs.
+
+"#" cannot be used as delimiter as it is the comment character in the
+configuration file.
+
+Please note that w3mir expects that URLs identifying 'directories'
+keep idenfifying directories after application of Apply rules.  Ditto
+for files.
+
+=item Agent: I<agent>
+
+see B<-agent> option.
+
+=item Pause: I<n>
+
+see B<-p> option.
+
+=item Retry-Pause: I<n>
+
+see B<-rp> option.
+
+=item Retries: I<n>
+
+see B<-t> option.
+
+=item debug: I<n>
+
+see B<-d> option.
+
+=item umask I<n>
+
+see B<-umask> option.
+
+=item Robot-Rules: I<on> | I<off>
+
+Turn robot rules on of off.  See B<-drr> option.
+
+=item Remove-Nomirror: I<on> | I<off>
+
+If this is enabled sections between two consecutive
+
+  <!--NO MIRROR-->
+
+comments in a mirrored document will be removed.  This editing is
+performed even if batch getting is specified.
+
+=item Header: I<html/text>
+
+Insert this I<complete> html/text into the start of the document.
+This will be done even if batch is specified.
+
+=item File-Disposition: I<save> | I<stdout> | I<forget>
+
+What to do with a retrieved file.  The I<save> alternative is default.
+The two others correspond to the B<-s> and B<-f> options.  Only one
+may be specified.
+
+=item Verbosity: I<quiet> | I<brief> | I<chatty>
+
+How much B<w3mir> informs you of it's progress.  I<Brief> is the
+default.  The two others correspond to the B<-q> and B<-c> switches.
+
+=item Cd: I<directory>
+
+Change to given directory before starting work.  If it does not exist
+it will be quietly created.  Using this option breaks the 'fixup'
+code so consider not using it, ever.
+
+=item HTTP-Proxy: I<server:port>
+
+see the B<-P> switch.
+
+=item HTTP-Proxy-user: I<username>
+
+=item HTTP-Proxy-passwd: I<password>
+
+These two are is used to activate authentication with the proxy
+server.  L<w3mir> only supports I<basic> proxy autentication, and is
+quite simpleminded about it, if proxy authentication is on L<w3mir>
+will always give it to the proxy.  The domain concept is not supported
+with proxy-authentication.
+
+=item Proxy-Options: I<no-pragma> | I<revalidate> | I<refresh> | I<no-store>
+
+Set proxy options.  There are two ways to pass proxy options, HTTP/1.0
+compatible and HTTP/1.1 compatible.  Newer proxy-servers will
+understand the 1.1 way as well as 1.0.  With old proxy-servers only
+the 1.0 way will work.  L<w3mir> will prefer the 1.0 way.
+
+The only 1.0 compatible proxy-option is I<refresh>, it corresponds to
+the B<-pflush> option and forces the proxy server to pass the request
+to a upstream server to retrieve a I<fresh> copy of the document. 
+
+The I<no-pragma> option forces w3mir to use the HTTP/1.1 proxy
+control header, use this only with servers you know to be new,
+otherwise it won't work at all.  Use of any option but I<refresh> will
+also cause HTTP/1.1 to be used.  
+
+I<revalidate> forces the proxy server to contact the upstream server
+to validate that it has a fresh copy of the document.  This is nicer
+to the net than I<refresh> option which forces re-get of the document
+no matter if the server has a fresh copy already.
+
+I<no-store> forbids the proxy from storing the document in other than
+in transient storage.  This can be used when transferring sensitive
+documents, but is by no means any warranty that the document can't be
+found on any storage device on the proxy-server after the transfer.
+Cryptography, if legal in your contry, is the solution if you want the
+contents to be secret.
+
+I<refresh> corresponds to the HTTP/1.0 header I<Pragma: no-cache> or
+the identical HTTP/1.1 I<Cache-control> option.  I<revalidate> and
+I<no-store> corresponds to I<max-age=0> and I<no-store> respectively.
+
+=item Authorization
+
+B<w3mir> supports only the I<basic> authentication of HTTP/1.0.  This
+method can assign a password to a given user/server/I<realm>.  The
+"user" is your user-name on the server.  The "server" is the server.
+The I<realm> is a HTTP concept.  It is simply a grouping of files and
+documents.  One file or a whole directory hierarchy can belong to a
+realm.  One server may have many realms.  A user may have separate
+passwords for each realm, or the same password for all the realms the
+user has access to.  A combination of a server and a realm is called a
+I<domain>.
+
+=over 8
+
+=item Auth-Domain: I<server:port/realm>
+
+Give the server and port, and the belonging realm (making a domain)
+that the following authentication data holds for.  You may specify "*"
+wildcard for either of I<server:port> and I<realm>, this will work
+well if you only have one usernme and password on all the servers
+mirrored.
+
+=item Auth-User: I<user>
+
+Your user-name.
+
+=item Auth-Passwd: I<password>
+
+Your password.
+
+=back
+
+These three directives may be repeated, in clusters, as many times as
+needed to give the necessary authentication information
+
+=item Disable-Headers: I<referer> | I<user>
+
+Stop B<w3mir> from sending the given headers.  This can be used for
+anonymity, making your retrievals harder to track.  It will be even
+harder if you specify a generic B<Agent>, like Netscape.
+
+=item Fixup: I<...>
+
+This directive controls some aspects of the separate program w3mfix.
+w3mfix uses the same configuration file as w3mir since it needs a lot
+of the information in the B<w3mir> configuration file to do it's work
+correctly.  B<w3mfix> is used to make mirrors more browseable on
+filesystems (disk or CDROM), and to fix redirected URLs and some other
+URL editing.  If you want a mirror to be browseable of disk or CDROM
+you almost certainly need to run w3mfix.  In many cases it is not
+necessary when you run a mirror to be used through a WWW server.
+
+To make B<w3mir> write the data files B<w3mfix> needs, and do nothing
+else, simply put
+
+=over 8
+
+  Fixup: on
+
+=back
+
+in the configuration file.  To make B<w3mir> run B<w3mfix>
+automatically after each time B<w3mir> has completed a mirror run
+specify
+
+=over 8
+
+  Fixup: run
+
+=back
+
+L<w3mfix> is documented in a separate man page in a effort to not
+prolong I<this> manpage unnecessarily.
+
+=item Index-name: I<name-of-index-file>
+
+When retriving URLs ending in '/' w3mir needs to append a filename to
+store it localy.  The default value for this is 'index.html' (this is
+the most used, its use originated in the NCSA HTTPD as far as I know).
+Some WWW servers use the filename 'Welcome.html' or 'welcome.html'
+instead (this was the default in the old CERN HTTPD).  And servers
+running on limited OSes frequently use 'index.htm'.  To keep things
+consistent and sane w3mir and the server should use the same name.
+Put
+
+  Index-name: welcome.html
+
+when mirroring from a site that uses that convention.
+
+When doing a multiserver retrival where the servers use two or more
+different names for this you should use B<Apply> rules to make the
+names consistent within the mirror.
+
+When making a mirror for use with a WWW server, the mirror should use
+the same name as the new server for this, to acomplish that
+B<Index-name> should be combined with B<Apply>.
+
+Here is an example of use in the to latter cases when Welcome.html is
+the prefered I<index> name:
+
+  Index-name: Welcome.html
+  Apply: s~/index.html$~/Welcome.html~
+
+Similarly, if index.html is the prefered I<index> name.
+
+  Apply: s~/Welcome.html~/index.html~
+
+I<Index-name> is not needed since index.html is the default index name.
+
+=back
+
+=head1 EXAMPLES
+
+=over 4
+
+=item * Just get the latest Dr-Fun if it has been changed since the last
+time
+
+ w3mir http://sunsite.unc.edu/Dave/Dr-Fun/latest.jpg
+
+=item * Recursively fetch everything on the Star Wars site, remove
+what is no longer at the server from the mirror:
+
+ w3mir -R -r http://www.starwars.com/
+
+=item * Fetch the contents of the Sega site through a proxy, pausing
+for 30 seconds between each document
+
+ w3mir -r -p 30 -P www.foo.org:4321 http://www.sega.com/
+
+=item * Do everything according to F<w3mir.cfg>
+
+ w3mir -cfgfile w3mir.cfg
+
+=item * A simple configuration file
+
+ # Remember, options first, as many as you like, comma separated
+ Options: recurse, remove
+ #
+ # Start here:
+ URL: http://www.starwars.com/
+ #
+ # Speed things up
+ Pause: 0
+ #
+ # Don't get junk
+ Ignore: *.cgi
+ Ignore: *-cgi
+ Ignore: *.map
+ #
+ # Proxy:
+ HTTP-Proxy: www.foo.org:4321
+ #
+ # You _should_ cd away from the directory where the config file is.
+ cd: starwars
+ #
+ # Authentication:
+ Auth-domain: server:port/realm
+ Auth-user: me
+ Auth-passwd: my_password
+ #
+ # You can use '*' in place of server:port and/or realm:
+ Auth-domain: */*
+ Auth-user: otherme
+ Auth-user: otherpassword
+
+=item Also:
+
+ # Retrive all of janl's home pages:
+ Options: recurse
+ #
+ # This is the two argument form of URL:.  It fetches the first into the second
+ URL: http://www.math.uio.no/~janl/ math/janl
+ #
+ # These says that any documents refered to that lives under these places
+ # should be gotten too.  Into the named directories.  Two arguments are
+ # required for 'Also:'.
+ Also: http://www.math.uio.no/drift/personer/ math/drift
+ Also: http://www.ifi.uio.no/~janl/ ifi/janl
+ Also: http://www.mi.uib.no/~nicolai/ math-uib/nicolai
+ #
+ # The options above will result in this directory hierarchy under
+ # where you started w3mir:
+ # w3mir/math/janl		files from http://www.math.uio.no/~janl
+ # w3mir/math/drift		from http://www.math.uio.no/drift/personer/
+ # w3mir/ifi/janl		from http://www.ifi.uio.no/~janl/
+ # w3mir/math-uib/nicolai	from http://www.mi.uib.no/~nicolai/
+
+=item Ignore-RE and Fetch-RE
+
+ # Get only jpeg/jpg files, no gifs
+ Fetch-RE: m/\.jp(e)?g$/
+ Ignore-RE: m/\.gif$/
+
+=item Apply
+
+As I said earlier, B<Apply> has not been used for Real Work yet, that
+I know of.  But B<Apply> I<could>, be used to map all web servers at
+the university of Oslo inside the scope of retrieval very easily:
+
+  # Start at the main server
+  URL: http://www.uio.no/
+  # Change http://*.uio.no and http://129.240.* to be a subdirectory
+  # of http://www.uio.no/.
+  Apply: s~^http://(.*\.uio\.no(?:\d+)?)/~http://www.uio.no/$1/~i
+  Apply: s~^http://(129\.240\.[^:]*(?:\d+)?)/~http://www.uio.no/$1/~i
+
+
+=back
+
+There are two rather extensive example files in the B<w3mir> distribution.
+
+=head1 BUGS
+
+=over 4
+
+=item The -lc switch does not work too well.
+
+=back
+
+=head1 FEATURES
+
+These are not bugs.
+
+=over 4
+
+=item URLs with two /es ('//') in the path component does not work as
+some might expect.  According to my reading of the URL spec. it is an
+illegal construct, which is a Good Thing, because I don't know how to
+handle it if it's legal.
+
+=item If you start at http://foo/bar/ then index.html might be gotten
+twice.
+
+=item Some documents point to a point above the server root, i.e.,
+http://some.server/../stuff.html.  Netscape, and other browsers, in
+defiance of the URL standard documents will change the URL to
+http://some.server/stuff.html.  W3mir will not.
+
+=item Authentication is I<only> tried if the server requests it.  This
+might lead to a lot of extra connections going up and down, but that's
+the way it's gotta work for now.
+
+=back
+
+=head1 SEE ALSO
+
+L<w3mfix>
+
+=head1 AUTHORS
+
+B<w3mir>s authors can be reached at I<w3mir-core@usit.uio.no>.
+B<w3mir>s home page is at http://www.math.uio.no/~janl/w3mir/
Index: /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3pdfuri.pm
===================================================================
--- /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3pdfuri.pm	(revision 20131)
+++ /gsdl/stable/build-src/packages/w3mir/w3mir-1.0.8/w3pdfuri.pm	(revision 20131)
@@ -0,0 +1,64 @@
+# -*- perl -*-
+#
+# w3pdfuri.pm -- extract uris from a adobe acrobat pdf file.
+#     version 0.1
+$VERSION=0.1;
+#
+# Assumptions:
+# - File starts with %PDF
+# - All URLS match this RE: ^\/URI\s+\(([^)]*)\)\s*$  (found by inspection of
+#   one (1) pdf file (the reader.pdf in the acrobat distribution).
+# - pdf files are potentially very large, so we read it from disk
+#   record by record.
+# - Record separator is ^M
+#
+# History:
+# - 19/02/97 janl: Version 0.1, seems to work with PDF-1.2
+#
+
+package w3pdfuri;
+
+use strict;
+
+sub list ($) {
+  my ($file) = @_;
+
+  my @urls=();
+  local($/)="\r";
+
+  unless (open(PDF,"< $file")) {
+    warn "Could not open $file for input: $!\n";
+    return;
+  }
+
+  $_ = <PDF>;
+  unless (/^%PDF-/) {
+    warn "$file is not a PDF file.\n";
+    close(PDF);
+    return;
+  }
+  
+  while (<PDF>) {
+    chomp;
+    push(@urls,$1) if (m~^/URI\s+\(([^)]*)\)\s*$~);
+  }
+
+  close(PDF);
+
+  return @urls;
+}
+
+1;
+
+__END__
+
+# Test code
+print "reader.pdf: ",
+  join(",",list("/local/lib/acrobat/Reader/help/reader.pdf")),"\n";
+print "Acrobat.pdf: ",
+  join(",",list("/local/lib/acrobat/Reader/Acrobat.pdf")),"\n";
+print "License.pdf: ",
+  join(",",list("/local/lib/acrobat/Reader/License.pdf")),"\n";
+print "MapTypes.pdf: ",
+  join(",",list("/local/lib/acrobat/Reader/MapTypes.pdf")),"\n";
+list("/etc/services");
Index: /gsdl/stable/build-src/packages/wget/README
===================================================================
--- /gsdl/stable/build-src/packages/wget/README	(revision 20131)
+++ /gsdl/stable/build-src/packages/wget/README	(revision 20131)
@@ -0,0 +1,35 @@
+wget - web site mirroring software
+
+This directory contains a version of the GNU wget program that was written by
+Hrvoje Niksic and others and distributed under the GNU General Public Licence
+
+The GNU wget homepage is http://www.cg.tuwien.ac.at/~prikryl/wget.html
+
+A couple of very small changes were made to this package by Stefan Boddie
+(sjboddie@cs.waikato.ac.nz). The USE_STDARG preprocessor definition was
+added to the VC++ makefile as it appeared to need it to compile on either
+VC++ 4.2 or VC++ 6.0. A change was also made to prevent backslashes from
+mistakenly being converted to "@5c" on windows.
+
+2003/11/27 - sjboddie@cs.waikato.ac.nz made a few more small changes to fix
+h_errno bug preventing code from compiling on latest versions of GCC.
+
+2004/06/30 - kjdon@cs.waikato.ac.nz replaced version 1.5.3 with version 1.9.
+It compiled as is under Windows XP, using VC++ 6.0, under Linux using GCC 3.2.3
+and GCC 2.95.3. So I haven't made any changes. 
+Under Windows, I haven't compiled it with openssl, so it doesn't support
+https://. OpenSSL comes with a warning about it being illegal in some countries
+to distribute cryptographic technology, so I haven't used it. Look at
+wget-1.9/windows/README for Windows compiling instructions if you want to add
+it in.
+
+2008/07/03 - oranfry@cs.waikato.ac.nz replaced version 1.9 with version 1.11.4.
+Version 1.9 didn't compile statically with the new libraries which come with
+fedora, so upgrading. Had to apply the patch at
+http://marc.info/?l=wget&m=115131792408685&w=2 to get it to compile under
+windows(VC++ 6.0), and those changes are in the tar.gz file in the repository.
+Again, no ssl in windows wget. The packages/configure and packages/Makefile
+files perform the same operations on wget as before, just the directory name
+has changed from wget/wget-1.9 to wget/wget-1.11.4.
+
+
Index: /gsdl/stable/build-src/packages/wv/README
===================================================================
--- /gsdl/stable/build-src/packages/wv/README	(revision 20131)
+++ /gsdl/stable/build-src/packages/wv/README	(revision 20131)
@@ -0,0 +1,16 @@
+wv - Microsoft Word converter
+
+This directory contains a version of the wv program.  It was originally
+written by Caolan McNamara and distributed under the GNU General Public
+License.  wv is now maintained by Dom Lachowicz and Martin Vermeer.  wv
+incorporates code from a variety of GPL programs from other sources.
+Thank you all.
+
+The wv homepage is http://wvware.sourceforge.net/
+
+We have included the source code here.  It is a slimmed-down version
+of wv version 0.7.1. It should handle documents created with Word 2 up
+to Word 2000. We have tested it on Linux (slackware 7), darwin (OS X
+10.1.3), cygwin, and solaris 2.8 (via sourceforge's compile farm).
+
+John McPherson -- Apr 2002
Index: /gsdl/stable/build-src/packages/xlhtml/README.txt
===================================================================
--- /gsdl/stable/build-src/packages/xlhtml/README.txt	(revision 20131)
+++ /gsdl/stable/build-src/packages/xlhtml/README.txt	(revision 20131)
@@ -0,0 +1,19 @@
+This package contains two programs:
+* ppthtml, which converts Microsoft PowerPoint 95 and 97 files
+into html or xml, and
+* xlhtml, which converts Microsoft Excel 95 and 97 files.
+
+It has been slightly modified for greenstone use as we only want the
+ppt to html program and the xls to html program, and none of the other
+programs (summary/diagnostics, man pages, etc).
+
+This version (0.4.9.0) was the latest development snapshot at the
+time of writing.
+
+See http://www.xlhtml.org/ for newer versions or more info.
+
+xlhtml is released under the GNU GPL.
+
+20 Feb 2002
+John McPherson
+NZDL.
Index: /gsdl/stable/build-src/src/hashfile/Makefile.in
===================================================================
--- /gsdl/stable/build-src/src/hashfile/Makefile.in	(revision 20131)
+++ /gsdl/stable/build-src/src/hashfile/Makefile.in	(revision 20131)
@@ -0,0 +1,79 @@
+###########################################################################
+#
+# Makefile -- src/hashfile
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../..
+
+
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@
+GSDLOS = @gsdlos@
+INCLUDES = 
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@ @COMPAT32BITFLAGS@
+LIBS = @LIBS@
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+CXXLINK = $(CXX) $(LDFLAGS) -o $@
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+SOURCES = \
+	hashfile.cpp
+
+OBJECTS = \
+	hashfile.o
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS)
+
+EXECUTABLE = hashfile
+
+
+# Default target: make the hashfile executable
+all: $(EXECUTABLE)
+
+hashfile: $(EXECUTABLE_OBJECTS)
+	$(CXXLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	$(INSTALL) -d $(GSDL_DIR)/bin/$(GSDLOS)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/bin/$(GSDLOS)
+
+clean:
+	rm -f $(OBJECTS) $(EXECUTABLE)
+
+distclean:
+	rm -f $(OBJECTS) $(EXECUTABLE) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/build-src/src/hashfile/hashfile.cpp
===================================================================
--- /gsdl/stable/build-src/src/hashfile/hashfile.cpp	(revision 20131)
+++ /gsdl/stable/build-src/src/hashfile/hashfile.cpp	(revision 20131)
@@ -0,0 +1,263 @@
+/**********************************************************************
+ *
+ * hashfile.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include <stdio.h>
+
+#define MAXNUMLEN  100   // bytes
+
+
+// The number class is used to store very long unsigned integers.
+// The least significant of each number is stored first. Numbers can 
+// be no longer than MAXNUMLEN bytes long. A number with length=0
+// is considered to be equal to 0. There should be no extra zeros
+// at the front of the number.
+
+struct number {
+  unsigned int len;
+  unsigned char num[MAXNUMLEN];
+
+  number () {len = 0;}
+};
+
+
+// evaluates a = a + b
+// a and b can be the same number
+void my_inc (number &a, number &b) {
+  unsigned int carry = 0;
+  unsigned int num = 0;
+  unsigned int i = 0;
+
+  while ((carry || (i < a.len) || (i < b.len)) && (i < MAXNUMLEN)) {
+    num = carry;
+    if (i < a.len) num += a.num[i];
+    if (i < b.len) num += b.num[i];
+
+    if (num >= 256) {
+      num -= 256; // assumes that each number in the list < 256
+      carry = 1;
+    } else {
+      carry = 0;
+    }
+    a.num[i] = (unsigned char)num;
+
+    ++i;
+  }
+
+  a.len = i;
+}
+
+
+// evaluates a = a - b if a >= b
+// returns true if the subtraction was possible
+int my_ifpos_dec (number &a, number &b) {
+  int carry = 0;
+  int num = 0;
+  int i = 0;
+  unsigned int len = 0; // the last non-zero digit
+
+  // make sure a >= b
+  if (b.len > a.len) return 0;
+  if (b.len == a.len) {
+    i = a.len - 1;
+    while (i >= 0) {
+      if (a.num[i] > b.num[i]) break;
+      if (a.num[i] < b.num[i]) return 0;
+      --i;
+    }
+  }
+
+  unsigned int j = 0;
+  len = 0;
+  while ((j < a.len) || (j < b.len)) {
+    num = -carry;
+    if (j < a.len) num += a.num[j];
+    if (j < b.len) num -= b.num[j];
+
+    if (num < 0) {
+      num += 256; // assumes each number in the list < 256
+      carry = 1;
+    } else {
+      carry = 0;
+    }
+
+    a.num[j] = (unsigned char) num;
+    
+    ++j;
+    if (num != 0) len = j;
+  }
+
+  a.len = len;
+
+  if (carry) {
+    // panic, this should NOT happen
+    fprintf (stderr, "panic: error in my_ifpos_dec\n");
+  }
+
+  return 1;
+}
+
+
+char *my_convert_num (number &a) {
+  char *result = new char[(a.len*2)+1];
+  int i,len;
+  char convert[16] = {'0','1','2','3','4','5','6','7',
+		      '8','9','a','b','c','d','e','f'};
+
+  // zero might be a special case
+  if (a.len == 0) {
+    result[0] = '0';
+    result[1] = '\0';
+    return result;
+  }
+
+  for (i=a.len-1, len=0; i >= 0; --i) {
+    result[len++] = convert[a.num[i]/16];
+    result[len++] = convert[a.num[i]%16];
+  }
+  result[len] = '\0';
+
+  return result;
+}
+
+
+
+// create a hash string from the contents of a file.
+//
+// The file is treated as a large base 256 number (each char is a digit),
+// and the hash value is the remainder when this number is divided by a
+// very large prime.
+//
+// PROBLEM: This is a flawed hash function because the rightmost (highest)
+// value in remainder is more likely to be a "1" than it is to be any other
+// number.  
+//
+// EVIDENCE: About 50% of the files in any GSDL directory have a hash code
+// that starts with 01* which implies (based on the my_convert_num function)
+// that the rightmost "digit" of the remainder = z such that (z % 16 = 0)
+// and (z / 16 = 1) which means (z = 1).
+//
+// MAJOR REASON: suppose our prime number was 19.  Then, if we have a 
+// reasonably random distribution of numbers for which we are going to 
+// calculate (N % 19), we expect to get a roughly uniform distribution
+// of remainders where the possible values are 0, 1, 2, 3... 18.  The
+// problem is that 9 out of the 19 possible values (10,11... 18) start
+// with the digit 1.  Thus our hascode will start with "01".
+//
+// ANOTHER PROBLEM: Characters in the file are read one at a time; after each 
+// one is read it is prepended to the remainder, then the remainder is
+// recalculated on the string thus far seen.  I am sure the math here 
+// is wrong - if I try calculating (111 mod 7) by the same algorithm, it
+// simply does nor work.
+//
+// ANOTHER POSSIBLE PROLEM: Each character from the file is read into 
+// remainder at the most significant end, and when that character
+// is a zero you get a number like "01" which would be considered 
+// larger than a number like "8" because it is longer (two  digits
+// instead of 1).  
+//
+// These comments added by Gordon Paynter (gwp@cs.waikato.ac.nz) in
+// June 2000.  I didn't write any code, however.
+
+char *hashfile (char *filename) {
+  FILE *infile = (FILE *)NULL;
+  int i;
+
+  number primepow[8];
+  number pow;
+  number remainder;
+  unsigned char c;
+
+  // our prime number (618970019642690137449562111)
+  pow.num[0] = 255;  pow.num[1] = 255;
+  pow.num[2] = 255;  pow.num[3] = 255;
+  pow.num[4] = 255;  pow.num[5] = 255;
+  pow.num[6] = 255;  pow.num[7] = 255;
+  pow.num[8] = 255;  pow.num[9] = 255;
+  pow.num[10] = 255; pow.num[11] = 1;
+  pow.len = 12;
+
+  // calculate 8 multiples of the prime number.
+  // These are used to find the remainder using only subtraction operations
+  for (i=0; i<8; ++i) {
+    primepow[i] = pow;
+    my_inc (pow, pow);
+  }
+
+  // The "remainder" after division by the prime.  Our result.
+  remainder.len = 0;
+
+  // open the file
+  infile = fopen (filename, "rb");
+  if (infile == NULL) {
+    return (char *)NULL;
+  }
+  c = (unsigned char)fgetc(infile);
+  
+  while (!feof (infile)) {
+
+    // make sure the remainder has not grown too large
+    if (remainder.len == MAXNUMLEN-1) {
+      fprintf (stderr, "ERROR - number overflow\n");
+      return (char *)NULL;
+    }
+
+    // remainder = remainder * 256 + c
+    for (i=remainder.len; i>0; --i) {
+      remainder.num[i] = remainder.num[i-1];
+    }
+    remainder.num[0] = c;
+    if (remainder.len > 0 || c != 0) remainder.len = remainder.len+1;
+    
+    // remainder = (remainder % large-prime-number)
+    for (i=7; i>=0; --i) {
+      my_ifpos_dec (remainder, primepow[i]);
+    }
+
+    // read a new character from the file
+    c = (unsigned char)fgetc(infile);
+  }
+
+  fclose (infile);
+
+  return my_convert_num (remainder);
+}
+
+
+int main (int argc, char *argv[]) {
+  int i;
+  char *result;
+
+  for (i = 1; i < argc; ++i) {
+    result = hashfile (argv[i]);
+    if (result == NULL) {
+      printf ("ERROR - could not process %s\n", argv[i]);
+    } else {
+      printf ("%s: %s\n", argv[i], result);
+      delete [] result;
+    }
+  }
+
+  return 0;
+}
Index: /gsdl/stable/build-src/src/hashfile/win32.mak
===================================================================
--- /gsdl/stable/build-src/src/hashfile/win32.mak	(revision 20131)
+++ /gsdl/stable/build-src/src/hashfile/win32.mak	(revision 20131)
@@ -0,0 +1,83 @@
+###########################################################################
+#
+# win32 makefile -- hashfile
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+ 
+GSDLHOME = ..\..\..
+GSDL_VC4 = 0
+DEBUG = 0
+
+AR = lib
+CC = cl
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+DEFS = -DHAVE_CONFIG_H -D__WIN32__ -D_CRT_SECURE_NO_DEPRECATE
+INCLUDES = -I"$(GSDLHOME)\src\hashfile"
+LIBS =
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) -nologo $(LDFLAGS)
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $<
+
+ANSI2KNR = 
+o = .obj
+e = .exe
+ 
+HEADERS = 
+
+SOURCES = hashfile.cpp
+
+OBJECTS = hashfile$o
+
+EXEC = hashfile$e
+ 
+all : $(EXEC)
+
+install: $(EXEC)
+	if NOT EXIST "$(GSDLHOME)\bin\windows" mkdir "$(GSDLHOME)\bin\windows"
+	copy $(EXEC) "$(GSDLHOME)\bin\windows"
+
+clean:
+	del *$o
+	del $(EXEC)
+
+HASHFILE_OBJS = hashfile$o
+
+hashfile$e: $(HASHFILE_OBJS) $(LIBS)
+	    $(LINK) $(HASHFILE_OBJS) $(LIBS)
Index: /gsdl/stable/build-src/src/java/org/nzdl/gsdl/ApplyXSLT.java
===================================================================
--- /gsdl/stable/build-src/src/java/org/nzdl/gsdl/ApplyXSLT.java	(revision 20131)
+++ /gsdl/stable/build-src/src/java/org/nzdl/gsdl/ApplyXSLT.java	(revision 20131)
@@ -0,0 +1,373 @@
+package org.nzdl.gsdl;
+
+import java.io.*;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import javax.xml.parsers.*;
+import javax.xml.transform.dom.*;
+import org.w3c.dom.*;
+
+
+
+/**
+ *  Use the TraX interface to perform a transformation in the simplest manner possible
+ *  (3 statements).
+ */
+public class ApplyXSLT
+{
+
+    public static final String DOC_START = new String ("<?DocStart?>"); 
+    public static final String DOC_END = new String ("<?DocEnd?>"); 
+    public static final String INPUT_END = new String ("<?Done?>"); 
+
+    private static final String RECORD_ELEMENT = "record";
+    private static final String CONTROLFIELD_ELEMENT = "controlfield";
+    private static final String SUBFIELD_ELEMENT = "subfield";
+    private static final String LEADER_ELEMENT = "leader";
+
+    private final int BEFORE_READING = 0;
+    private final int IS_READING = 1;
+    private String xsl_file;
+    private String mapping_file;
+
+    public ApplyXSLT(){}
+   
+    public ApplyXSLT(String xsl_file)
+    {
+	this.xsl_file = xsl_file; 
+    }
+
+    public ApplyXSLT(String xsl_file,String mapping_file){
+	this.xsl_file = xsl_file; 
+	this.mapping_file = mapping_file;
+    }
+
+    private boolean process()
+    {
+	try{
+
+	// Use System InputStream to receive piped data from the perl program
+	InputStreamReader ir = new InputStreamReader(System.in, "UTF8");
+	BufferedReader br = new BufferedReader(ir);
+	
+	int system_status = BEFORE_READING;
+ 	String a_doc = new String();
+	String output_file = new String();
+
+
+	    while (br.ready()) {
+		                   
+		String this_line = br.readLine();
+		if(system_status == BEFORE_READING){
+		    if(this_line.compareTo(DOC_START) == 0){
+			output_file = br.readLine(); // read the next line as the output file name
+			system_status = IS_READING;
+			a_doc = "";
+		    }
+		    else if(this_line.compareTo(INPUT_END) == 0){
+			return true;
+		    }
+		    else{
+			System.err.println("Undefined process status:" + this_line);
+			system_status = BEFORE_READING;
+		    }
+		    
+		}
+		else if(system_status == IS_READING){
+		    if(this_line.compareTo(DOC_END) == 0){
+			boolean result = false;
+			if (mapping_file !=null && !mapping_file.equals("")){
+			    result = translateXMLWithMapping(a_doc,output_file);			    
+			}
+			else{
+			    result = translateXML(a_doc,output_file); 
+			}
+			
+			if (!result){
+			    System.err.println("Translation Failed!!");
+			    return false;
+			}
+			
+			system_status = BEFORE_READING;
+			
+		    }
+		    else{
+			a_doc = a_doc + this_line + "\n";
+			
+		    }
+		}
+		else{		  
+		    System.err.println ("Undefined system status in ApplyXSLT.java main().");
+		    System.exit(-1);
+		    }
+		
+	    }
+	}catch (Exception e)
+	    {
+		System.err.println("Receiving piped data error!" + e.toString());
+	    }
+				
+	return false;
+    }
+    
+    
+    private boolean translateXML(String full_doc, String output_file) 
+	throws IOException,TransformerException, TransformerConfigurationException, FileNotFoundException
+    {
+	
+ 	StringReader str = new StringReader(full_doc) ;
+	
+	TransformerFactory tFactory = TransformerFactory.newInstance();
+   	Transformer transformer = tFactory.newTransformer(new StreamSource(xsl_file));
+   	transformer.transform(new StreamSource(str), new StreamResult(new FileOutputStream(output_file)));
+	return true;
+    }
+
+    private boolean translateXMLWithMapping(String full_doc, String output_file) 
+	throws IOException,TransformerException, TransformerConfigurationException, FileNotFoundException
+    {	
+	StringReader str = new StringReader(full_doc) ;
+
+	try{
+	    TransformerFactory tFactory = TransformerFactory.newInstance();
+	    Transformer transformer = tFactory.newTransformer(new StreamSource(xsl_file));
+	    
+	    Document mapping_doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(mapping_file);
+	    Element mapping =mapping_doc.getDocumentElement(); 
+	    
+	    transformer.setParameter("mapping",mapping);
+	    
+	    Document output_doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+	    
+	    transformer.transform(new StreamSource(str), new DOMResult(output_doc));
+	    
+	    calculateRecordsLength(output_doc);
+	   
+	    transformer = tFactory.newTransformer();
+	   
+	    transformer.transform(new DOMSource(output_doc), new StreamResult(new FileOutputStream(output_file)));
+
+	}
+	catch(Exception e){
+	    e.printStackTrace();
+	    return false;
+	}
+
+	return true;
+    }
+
+    private void calculateRecordsLength(Document output_doc){
+	NodeList records = output_doc.getDocumentElement().getElementsByTagName(RECORD_ELEMENT);
+
+	for(int i=0;i<records.getLength();i++){
+	    Element record = (Element)records.item(i);
+	    calculateRecordLength(record);
+	}
+    }
+
+    private void calculateRecordLength(Element record){
+	int total_length =0;	
+	NodeList controlfileds = record.getElementsByTagName(CONTROLFIELD_ELEMENT);
+	for(int i=0;i<controlfileds.getLength();i++){
+	    Element controlfiled = (Element)controlfileds.item(i);
+	    total_length +=getElementTextValue(controlfiled).length();
+	}
+	
+	NodeList subfileds = record.getElementsByTagName(SUBFIELD_ELEMENT);
+	for(int i=0;i<subfileds.getLength();i++){
+	    Element subfiled = (Element)subfileds.item(i);
+	    total_length +=getElementTextValue(subfiled).length();
+	}
+
+	String record_length = total_length+"";
+	//fill in a extra digit as record length needs to be five characters long
+	if (total_length < 10000){
+	    record_length = "0"+record_length;
+	    if (total_length < 1000){
+		record_length = "0"+record_length;	
+	    }
+	    if (total_length < 100){
+		record_length = "0"+record_length;	
+	    }
+	    if (total_length < 10){
+		 record_length = "0"+record_length;	
+	    }
+	   
+	}
+
+	NodeList leaders = record.getElementsByTagName(LEADER_ELEMENT);	
+	
+	//only one leader element
+        if (leaders.getLength() >0){
+	    Element leader_element = (Element)leaders.item(0);
+	    removeFirstTextNode(leader_element);
+	    leader_element.insertBefore(leader_element.getOwnerDocument().createTextNode(record_length),leader_element.getFirstChild()); 
+	}
+
+    }
+
+    private void removeFirstTextNode(Element element){
+	//remove the first text node
+	NodeList children_nodelist = element.getChildNodes();
+	for (int i = 0; i < children_nodelist.getLength(); i++) {
+	    Node child_node = children_nodelist.item(i);
+	    if (child_node.getNodeType() == Node.TEXT_NODE) {
+		element.removeChild(child_node);
+		return;
+	    }
+	}
+
+    }
+
+    private String getElementTextValue(Element element)
+    {
+	String text ="";	
+
+	// Find the node child
+	NodeList children_nodelist = element.getChildNodes();
+	for (int i = 0; i < children_nodelist.getLength(); i++) {
+	    Node child_node = children_nodelist.item(i);
+	    if (child_node.getNodeType() == Node.TEXT_NODE) {
+		text +=child_node.getNodeValue();
+	    }
+	}
+
+       	return text;
+    }
+ 
+
+    private void setMappingVariable(Document style_doc){
+	Node child = style_doc.getDocumentElement().getFirstChild();
+	while(child != null) {
+	    String name = child.getNodeName();
+	    if (name.equals("xsl:variable")) {
+		Element variable_element = (Element)child;
+		if ( variable_element.getAttribute("name").trim().equals("mapping")){
+		    variable_element.setAttribute("select","document('"+mapping_file+"')/Mapping");
+		}
+	    }
+	    child = child.getNextSibling();
+	}
+	
+    } 
+
+
+    private void translate(String xml_file, String xsl_file, String output_file)throws IOException,TransformerException, TransformerConfigurationException, FileNotFoundException, IOException{             
+         
+      	TransformerFactory tFactory = TransformerFactory.newInstance();
+   	Transformer transformer = tFactory.newTransformer(new StreamSource(xsl_file));
+           
+	OutputStreamWriter output = null;  
+	if (output_file.equals("")) {
+             output = new OutputStreamWriter(System.out, "UTF-8");
+	}
+	else{
+            output = new OutputStreamWriter(new FileOutputStream(output_file), "UTF-8"); 
+	}
+       
+        transformer.transform(new StreamSource(new File(xml_file)),new StreamResult(output));
+        
+    }
+
+     static public String replaceAll(String source_string, String match_regexp, String replace_string)
+    {
+	return source_string.replaceAll(match_regexp, replace_string);
+    }
+
+
+    public static void main(String[] args) 
+    { 
+
+        String xml_file="";
+        String xsl_file="";
+        String mapping_file="";
+        String output_file="";
+      
+	// Checking Arguments
+	if(args.length < 1)
+	    {
+	       printUsage(); 
+	    }           
+
+	for (int i=0;i<args.length;i++){
+	    if (args[i].equals("-m") && i+1 < args.length && !args[i+1].startsWith("-")){
+		 mapping_file = args[++i];
+         	 checkFile(mapping_file.replaceAll("file:///",""));
+	    }
+	    else if (args[i].equals("-x") && i+1 < args.length && !args[i+1].startsWith("-")){
+               xml_file = args[++i]; 
+               checkFile(xml_file.replaceAll("file:///",""));
+	    }
+	    else if(args[i].equals("-t") && i+1 < args.length && !args[i+1].startsWith("-")){
+                xsl_file = args[++i];
+	         checkFile( xsl_file.replaceAll("file:///","")); 
+	    }
+            else if(args[i].equals("-o") && i+1 < args.length && !args[i+1].startsWith("-")){
+                output_file = args[++i];
+	    
+	    }
+	    else if(args[i].equals("-h")){
+                printUsage();
+	    }
+	    else{
+                printUsage();
+	    }
+		  
+	}
+
+         
+	ApplyXSLT core = null;
+	
+ 	if (xml_file.equals("") && !xsl_file.equals("")){//read from pipe line
+	    if (mapping_file.equals("")){ 
+           	 core = new ApplyXSLT(xsl_file);
+	    }
+	    else{
+                core = new ApplyXSLT(xsl_file,mapping_file);  
+	    }
+            
+	    if (core != null){
+		core.process();
+	    }
+	    else{
+		printUsage(); 
+	    }
+ 	}
+ 	else if(!xml_file.equals("") && !xsl_file.equals("")){
+	    core = new ApplyXSLT();
+            try {
+		core.translate(xml_file,xsl_file,output_file); 
+	    }  
+	    catch(Exception e){e.printStackTrace();}
+ 	} 
+	else{
+	    printUsage();    
+	}
+	
+    }
+
+    private static void checkFile(String filename){
+         File file = new File(filename);
+	 if (!file.exists()){
+	     System.out.println("Error: "+filename+" doesn't exist!");
+	     System.exit(-1);
+	 }
+    }
+  
+    private  static void printUsage(){
+	System.out.println("Usage:ApplyXSLT  -x File -t File [-m File] [-o File]");
+        System.out.println("\t-x spacifies the xml file (Note: optional for piped xml data)");
+        System.out.println("\t-t spacifies the xsl file");
+    	System.out.println("\t-m specifies the mapping file (for MARCXMLPlugout.pm only)");
+        System.out.println("\t-o specifies the output file name (output to screen if this option is absent)");
+        System.exit(-1);
+    }
+}
+
+
Index: /gsdl/stable/build-src/src/java/org/nzdl/gsdl/ApplyXSLTUtil.java
===================================================================
--- /gsdl/stable/build-src/src/java/org/nzdl/gsdl/ApplyXSLTUtil.java	(revision 20131)
+++ /gsdl/stable/build-src/src/java/org/nzdl/gsdl/ApplyXSLTUtil.java	(revision 20131)
@@ -0,0 +1,8 @@
+package org.nzdl.gsdl;
+
+public class ApplyXSLTUtil {
+    
+    public static String toLowerCase(String value){
+	return value.toLowerCase();
+    } 
+}
Index: /gsdl/stable/build-src/src/phind/generate/.cvsignore
===================================================================
--- /gsdl/stable/build-src/src/phind/generate/.cvsignore	(revision 20131)
+++ /gsdl/stable/build-src/src/phind/generate/.cvsignore	(revision 20131)
@@ -0,0 +1,4 @@
+Makefile
+suffix
+suffix2
+*.o
Index: /gsdl/stable/build-src/src/phind/generate/Makefile.in
===================================================================
--- /gsdl/stable/build-src/src/phind/generate/Makefile.in	(revision 20131)
+++ /gsdl/stable/build-src/src/phind/generate/Makefile.in	(revision 20131)
@@ -0,0 +1,82 @@
+###########################################################################
+#
+# Makefile -- src/phind/generate
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../../..
+
+
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@
+GSDLOS = @gsdlos@
+INCLUDES = 
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@ @COMPAT32BITFLAGS@
+LIBS = @LIBS@
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+CXXLINK = $(CXX) $(LDFLAGS) -o $@
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+SOURCES = \
+	phrase.cpp \
+	suffix.cpp
+
+OBJECTS = \
+	phrase.o \
+	suffix.o
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS)
+
+EXECUTABLE = suffix
+
+
+# Default target: make the suffix executable
+all: $(EXECUTABLE)
+
+suffix: $(EXECUTABLE_OBJECTS)
+	$(CXXLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	$(INSTALL) -d $(GSDL_DIR)/bin/$(GSDLOS)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/bin/$(GSDLOS)
+
+clean:
+	rm -f $(OBJECTS) $(EXECUTABLE)
+
+distclean:
+	rm -f $(OBJECTS) $(EXECUTABLE) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/build-src/src/phind/generate/check.h
===================================================================
--- /gsdl/stable/build-src/src/phind/generate/check.h	(revision 20131)
+++ /gsdl/stable/build-src/src/phind/generate/check.h	(revision 20131)
@@ -0,0 +1,130 @@
+// check.h -- manipulate the suffixCheck array
+//
+// The suffixCheck array is used to prevent a phrase being added to
+// the results of getExpansions.  It works by declaring an array that
+// has one bit for each entry in the suffix array, which is cleared at
+// the start of getExpansions.  As getExpansions adds each phrase to
+// the result set, we set the bits in the suffixCheck array that
+// correspond to the positions of of the phrase in the suffixArray.
+
+// (The point is that getExpansions can later check whether a phrase
+// or its prefix has been seen before by looking up the bit
+// corresponding to its first occurence in the suffixCheck array: if
+// the bit is set, a subphrase of this phrase is already in the
+// results already, and the current phrase can be ignored.)
+
+#include "suffix.h"
+
+// The suffixCheck array
+#if defined (__WIN32__)
+typedef unsigned char check;
+#else
+#include <inttypes.h>
+typedef uint8_t check;
+#endif
+
+check *suffixCheck;
+
+// The length of the suffixCheck array
+cellcount checkLength;
+
+// Some useful bitmask constants 
+const check ALLBITS        = 255;
+const check LEFTMOSTBIT    = static_cast<check>(ALLBITS << 7);
+const check LEFTMOSTBITS[] = {static_cast<check>(ALLBITS << 8), 
+			      static_cast<check>(ALLBITS << 7), 
+			      static_cast<check>(ALLBITS << 6), 
+			      static_cast<check>(ALLBITS << 5), 
+			      static_cast<check>(ALLBITS << 4),
+			      static_cast<check>(ALLBITS << 3), 
+			      static_cast<check>(ALLBITS << 2), 
+			      static_cast<check>(ALLBITS << 1),  
+			      static_cast<check>(ALLBITS << 0)};
+
+
+// Allocate the initial memory for suffixCheck
+inline void allocateSuffixCheck(cellcount number_of_symbols) 
+{
+  checkLength = number_of_symbols / (sizeof(check) * 8) + 1;
+  suffixCheck = new check[checkLength];
+  if (suffixCheck == NULL) {
+    cerr << "Suffix error: out of memory allocating suffixCheck array" << endl; 
+    exit(2);
+  }
+  memset(suffixCheck, 0, sizeof(check) * checkLength);
+}
+
+
+// Set all bits in suffixCheck to 0
+inline void clearSuffixCheck() 
+{
+  memset(suffixCheck, 0, sizeof(check) * checkLength);
+}
+
+
+// Get the value of a particular bit in suffixCheck
+inline int getSuffixCheck(cellindex position) 
+{
+  cellindex cell = position >> 3;
+  check remainder = position & 0x07; // the last 3 bits
+  if (suffixCheck[cell] & (LEFTMOSTBIT >> remainder)) {
+    return 1;
+  }
+  return 0;
+}                                                                               
+
+// Set the value of a bit in suffixCheck to 1
+inline void setSuffixCheck(cellindex suff) 
+{
+  cellindex cell = suff >> 3;
+  check remainder = suff & 0x07u; // the last 3 bits
+  suffixCheck[cell] |= (LEFTMOSTBIT >> remainder);
+}  
+
+
+// Set the bits in a cell in the suffixArray.
+// Bits are indexed 0-7.
+inline void setCellBits(cellindex cell_offset, unsigned first_bit, unsigned last_bit) 
+{
+  unsigned number_of_bits = last_bit - first_bit + 1;
+  check mask = (LEFTMOSTBITS[number_of_bits] >> first_bit);
+  suffixCheck[cell_offset] |= mask;
+}
+
+
+inline void setSuffixCheck(cellindex first, cellindex last) 
+{
+  // Find the first and last cells in which bits are set
+  cellindex first_cell = first >> 3;
+  cellindex last_cell = last >> 3;
+
+  // If all the values are in the same cell, set them
+  if (first_cell == last_cell) {
+    setCellBits(first_cell, (first & 0x07u), (last & 0x07u));
+    return;
+  }
+
+  // Set the bits in the first and last cells
+  setCellBits(first_cell, (first & 0x07u), 7);
+  setCellBits(last_cell, 0, (last & 0x07u));
+
+  // Set the bits in the intermediate cells
+  ++first_cell;
+  if(last_cell > first_cell)
+    memset(suffixCheck + first_cell, ALLBITS, 
+	   (last_cell - first_cell) * sizeof(check));
+}
+
+
+// Print the suffixCheck array (for debugging)
+void printSuffixCheck() 
+{
+  for (cellcount i = 0; i < checkLength; ++i) {
+    cout << "cell " << i << "  \t";
+    cout << "(" << (i * 8) << "-" << (i * 8 + 7) << ")    \t";
+    for (cellindex j = 0; j < 8; ++j)
+      cout << getSuffixCheck(i * 8 + j);
+    cout << " (" << (unsigned int) suffixCheck[i] << ")\n";
+  }
+}
+
Index: /gsdl/stable/build-src/src/phind/generate/phrase.cpp
===================================================================
--- /gsdl/stable/build-src/src/phind/generate/phrase.cpp	(revision 20131)
+++ /gsdl/stable/build-src/src/phind/generate/phrase.cpp	(revision 20131)
@@ -0,0 +1,853 @@
+/**********************************************************************
+ *
+ * phrase.cpp -- implementation of the phrase object used by suffix.cpp
+ *
+ * Copyright 2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include <assert.h>
+#include <stdio.h>
+
+#if defined(GSDL_USE_STL_H)
+#  include <vector.h>
+#else
+#  include <vector>
+#endif
+
+#if defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+#endif
+
+#include "suffix.h"
+#include "phrase.h"
+
+
+// Phrase constructor functions
+
+Phrase::Phrase(symbol *words, cellcount size, int direction) {
+  empty();
+  length = size;
+
+  if (direction == SUFFIX) {
+     forward = words;
+     back = forward + size - 1;
+  } else {
+    back = words;
+    forward = back - size + 1;
+  }
+}
+
+
+Phrase::Phrase() {
+  empty();
+}
+
+
+Phrase::Phrase(const Phrase &p) {
+  forward = p.forward;
+  back = p.back;
+  length = p.length;
+
+  suffixFound = p.suffixFound;
+  prefixFound = p.prefixFound;
+
+  firstSuffix = p.firstSuffix;
+  lastSuffix  = p.lastSuffix;
+  firstSuffixIndex = p.firstSuffixIndex;
+  lastSuffixIndex  = p.lastSuffixIndex;
+  suffixFrequency  = p.suffixFrequency;
+
+  firstPrefix = p.firstPrefix;
+  lastPrefix  = p.lastPrefix;
+  firstPrefixIndex = p.firstPrefixIndex;
+  lastPrefixIndex  = p.lastPrefixIndex;
+  prefixFrequency  = p.prefixFrequency;
+
+  uniqueSuffixExtension = p.uniqueSuffixExtension;
+  uniquePrefixExtension = p.uniquePrefixExtension;
+}
+
+
+// Empty the contents of a phrase
+
+int Phrase::empty() {
+
+  forward = back = NULL;
+  length = 0;
+
+  suffixFound = prefixFound = 0;
+  firstSuffix = firstPrefix = NULL;
+  lastSuffix = lastPrefix = NULL;
+
+  firstSuffixIndex = lastSuffixIndex = suffixFrequency = 0;
+  firstPrefixIndex = lastPrefixIndex = prefixFrequency = 0;
+
+  uniqueSuffixExtension = uniquePrefixExtension = -1;
+
+  return 0;
+}
+
+// Remove the details of the location where a suffix/prefix
+// is found in the array.
+
+int Phrase::clearSuffix() {
+  suffixFound = 0;
+  firstSuffix = lastSuffix = NULL;
+  firstSuffixIndex = lastSuffixIndex = suffixFrequency = 0;
+  uniqueSuffixExtension = -1;
+  return 0;
+}
+
+int Phrase::clearPrefix() {
+  prefixFound = 0;
+  firstPrefix = lastPrefix = NULL;
+  firstPrefixIndex = lastPrefixIndex = prefixFrequency = 0;
+  uniquePrefixExtension = -1;
+  return 0;
+}
+
+// Increase the length of s phrase
+//
+// We increase the length of a string "in place".  When we expand
+// the suffix, however, we invalidate the prefix data, and vice-versa.
+
+int Phrase::increaseSuffixLength(cellcount l) {
+  length = l;
+  clearPrefix();
+  back = forward + l - 1;
+  return 0;
+}
+
+int Phrase::increasePrefixLength(cellcount l) {
+  length = l;
+  clearSuffix();
+  forward = back - l + 1;
+  return 0;
+}
+
+// Shorten a phrase by one symbol
+int Phrase::shortenByOneAtSuffix() {
+  --length;
+  --back;
+  if (phraseMode==STOPWORDS) {
+    while (*back >=firstStopSymbol && *back <= lastStopSymbol) {
+      --length;
+      --back;
+    }
+  }  
+  clearSuffix();
+  clearPrefix();
+  return 0;
+}
+
+int Phrase::shortenByOneAtPrefix() {
+  --length;
+  ++forward;
+  if (phraseMode==STOPWORDS) {
+    while (*forward >=firstStopSymbol && *forward <= lastStopSymbol) {
+      --length;
+      ++forward;
+    }
+  }
+  clearSuffix();
+  clearPrefix();
+  return 0;
+}
+
+
+// Output a phrase to a stream
+ostream &operator<<(ostream &stream, const Phrase &phrase)
+{
+  assert(phrase.forward);
+  symbol *s = phrase.forward;
+
+  stream << "s" << *s++;
+  for (cellcount i = 1; i < phrase.length; ++i)
+    stream << " s" << *s++;
+
+  return stream;
+}
+
+
+// Convert the phrase to a string
+// Note thgat you have to delete the memory yourself.
+char *Phrase::toString() 
+{
+  assert(forward);
+
+  char *str;
+  str = new char[length*20];
+  symbol *s = forward;
+  sprintf(str, "s%d", *s++);
+
+  for (cellcount i = 1; i < length; ++i) {
+    sprintf(str, "%s s%d", str, *s++);
+  }
+
+  return str;
+}
+
+
+// Compare a phrase to an another array of symbols
+//
+// Given an array of words with a specified length, 
+// compare those words to this phrase.
+//
+// Return 0 if the two phrases are the same over length length
+// Return 1 if the phrase is "greater" than tyhe words, or
+// Return -1 if the phrase is less.
+
+int Phrase::compareSuffix(symbol *words, cellcount length) {
+  assert(forward);
+  symbol *p = forward;
+  
+  for (cellcount i = 0; i < length; ++i) {
+    if (*p > *words) {
+      return 1;
+    } else if (*p < *words) {
+      return -1;
+    } else {
+      *p++;
+      *words++;
+    }
+  }
+
+  return 0;
+
+}
+
+int Phrase::comparePrefix(symbol *words, cellcount length) {
+  
+  assert(back);
+  symbol *p = back;
+  
+  for (cellcount i = 0; i < length; ++i) {
+    if (*p > *words) {
+      return -1;
+    } else if (*p < *words) {
+      return 1;
+    } else {
+      *p--;
+      *words--;
+    }
+  }
+
+  return 0;
+
+}
+
+
+// Does the phrase have a unique suffix/prefix extension?
+//
+// For suffix:
+//   If uniqueSuffixExtensions is 1, then phrase has some unique expansion. 
+//   If it is 0 then it does not.  If it is -1 then we don't know, and have
+//   to calculate it from the suffix array.  Same goes for prefixes.
+
+int Phrase::hasUniqueSuffixExtension() {
+
+  // if we don't know, then work it out
+  if (uniqueSuffixExtension == -1) {
+
+    ensureSuffixFound();
+
+    // pointers to the phrase's first and last occurances in te suffixArray
+    symbol *fst = firstSuffix + length;
+    symbol *lst = lastSuffix + length;
+
+    // in ANYPHRASE mode, simply check the next symbol
+    if (phraseMode == ANYPHRASE) {
+      if ((*fst == *lst) && (*fst > LASTDELIMITER)) {
+	uniqueSuffixExtension = 1;
+      } else {
+	uniqueSuffixExtension = 0;
+      }
+    }
+    // in STOPWORDS mode, make sure there is a unique next content symbol
+    else {
+      uniqueSuffixExtension = 0;
+      while ((*fst == *lst) && (*fst > LASTDELIMITER)) {
+	if (*fst >= firstContentSymbol) {
+	  uniqueSuffixExtension = 1;
+	  break;
+	}
+	++fst;
+	++lst;
+      }
+    }
+  }
+
+  return uniqueSuffixExtension;
+}
+
+int Phrase::hasUniquePrefixExtension() {
+
+  // if we don't know, then work it out
+  if (uniquePrefixExtension == -1) {
+
+    ensurePrefixFound();
+
+    // pointers to the phrase's first and last occurances in the prefixArray
+    symbol *fst = firstPrefix - length;
+    symbol *lst = lastPrefix - length;
+
+    // in ANYPHRASE mode, simply check the next symbol
+    if (phraseMode == ANYPHRASE) {
+      if ((*fst == *lst) && (*fst > LASTDELIMITER)) {
+	uniquePrefixExtension = 1;
+      } else {
+	uniquePrefixExtension = 0;
+      }
+    }
+    // in STOPWORDS mode, make sure there is a unique next content symbol
+    else {
+      uniquePrefixExtension = 0;
+      while ((*fst == *lst) && (*fst > LASTDELIMITER)) {
+	if (*fst >= firstContentSymbol) {
+	  uniquePrefixExtension = 1;
+	  break;
+	}
+	--fst;
+	--lst;
+      }
+    }
+  }
+
+  return uniquePrefixExtension;
+}
+
+
+// Expand a phrase with a unique suffix/prefix by 1 symbol
+//
+// Note that in STOPWORDS mode a "unique extension" means a unique
+// extension that ends on a content symbol.  Although we may extend 
+// such a phrase by 2 or more symbols, we will only extend it by a
+// single content symbol.
+
+int Phrase::expandUniqueSuffixExtensionByOne() {
+  assert(suffixFound);
+  assert(uniqueSuffixExtension == 1);
+
+  // in ANYPHRASE mode, expand the phrase by one symbol
+  if (phraseMode == ANYPHRASE) {
+    increaseSuffixLength(length + 1);
+  }
+  // in STOPWORDS mode, expand the phrase up to the next content symbol
+  else {
+    symbol *next = firstSuffix + length;
+    cellcount newlength = length + 1;
+
+    while (*next < firstContentSymbol) {
+      ++next;
+      ++newlength;
+    }
+    increaseSuffixLength(newlength);
+  }
+
+  uniqueSuffixExtension = -1;
+  return 0;
+}
+
+int Phrase::expandUniquePrefixExtensionByOne() {
+  assert(prefixFound);
+  assert(uniquePrefixExtension == 1);
+
+  // in ANYPHRASE mode, expand the phrase by one symbol
+  if (phraseMode == ANYPHRASE) {
+    increasePrefixLength(length + 1);
+  }
+  // in STOPWORDS mode, expand the phrase to the next content symbol
+  else {
+    symbol *next = firstPrefix - length;
+    cellcount newlength = length + 1;
+    while (*next < firstContentSymbol) {
+      --next;
+      ++newlength;
+    }
+    increasePrefixLength(newlength);
+
+  }
+
+  uniquePrefixExtension = -1;
+  return 0;
+}
+
+
+// Find the phrase in a suffixArray
+//
+// Given a suffix array, find the first and last occurances of the phrase.
+// The begin and end parameters identify which cells to search (inclusive). 
+
+int Phrase::findFirstAndLastSuffix() {
+  
+  return findFirstAndLastSuffix(0, inputLength-1);
+}
+
+int Phrase::findFirstAndLastSuffix(cellindex begin, cellindex end) {
+
+  // First find *any* occurance of the phrase
+  assert(begin <= end);
+
+  // if we're only searching one cell, it is very easy
+  if (begin == end) {
+    assert(compareSuffix(suffixArray[begin], length) == 0);
+    firstSuffix = lastSuffix = suffixArray[begin];
+    firstSuffixIndex = lastSuffixIndex = begin;
+    suffixFrequency = 1;
+    suffixFound = 1;
+    return 0;
+  }
+
+  cellindex c;
+  int cmp;
+
+  do {
+    c = (end + begin) / 2;
+    cmp = compareSuffix(suffixArray[c], length);
+    if (cmp == 1) {
+      // target phrase is lower than phrase at suffixArray[c]
+      begin = c + 1;
+    } else if (cmp == -1) {
+      // target phrase is higher than phrase at suffixArray[c]
+      end = c - 1;
+    }
+  } while (cmp != 0);
+    
+  cellindex lastbegin = c;
+  cellindex lastend = end;
+
+  // Next find the first occurance of the phrase.
+  // We know that the first occurance must be between the 
+  // current value of begin and the current value of c.
+  end = c;
+
+  do {
+    if (begin == end) {
+      c = begin;
+      cmp = 0;
+    } else {
+      c = (begin + end) / 2;
+      cmp = compareSuffix(suffixArray[c], length);
+      if (cmp == 1) {
+	// target phrase is lower than phrase at suffixArray[c]
+	begin = c + 1;
+      } else {
+	assert(cmp == 0);
+	// target phrase is the same as the phrase at suffixArray[c].  However,
+	// to find the first occurance, suffixArray[c] must be the same as the 
+	// phrase, but suffixArray[c-1] must be different.
+	if (c>0) {
+	  cmp = compareSuffix(suffixArray[c-1], length);
+	  if (cmp == 0) {
+	    end = c - 1;
+	    assert(end >= begin);
+	    cmp = 1;
+	  } else {
+	    cmp = 0;
+	  }
+	}
+      }
+    }
+  } while (cmp != 0);
+
+  // we have found the first location
+  firstSuffixIndex = c;
+  firstSuffix = suffixArray[c];
+  
+  // Next find the last occurance of the phrase.
+  // We previously stored some bounds for its loccation.
+  begin = lastbegin;
+  end = lastend;
+  
+  do {
+    if (begin == end) {
+      c = begin;
+      cmp = 0;
+    } else {
+      c = (begin + end) / 2;
+      cmp = compareSuffix(suffixArray[c], length);
+      if (cmp == -1) {
+	// target phrase is greater than phrase at suffixArray[c]
+	end = c - 1;
+      } else {
+	assert(cmp == 0);
+	// target phrase is the same as the phrase at suffixArray[c].  However,
+	// to find the last occurance, one of two additional condiditons must be met:
+	// either c must be the very last cell in the array, or
+	// suffixArray[c+1] must be different from phrase
+	if (c < inputLength-1) {
+	  cmp = compareSuffix(suffixArray[c+1], length);
+	  if (cmp == 0) {
+	    begin = c + 1;
+	    cmp = -1;
+	  } else {
+	    cmp = 0;
+	  }
+	} 
+      }
+    }
+  } while (cmp != 0);
+  
+  lastSuffixIndex = c;
+  lastSuffix = suffixArray[c];
+  suffixFrequency = lastSuffixIndex - firstSuffixIndex + 1;
+  suffixFound = 1;
+
+  return 0;
+}
+
+
+// Find the phrase in a prefix array
+//
+// Given a prefix array, find the first and last occurances of the phrase.
+// The begin and end parameters identify which cells to search (inclusive). 
+
+int Phrase::findFirstAndLastPrefix() {
+  return findFirstAndLastPrefix(0, inputLength-1);
+}
+
+int Phrase::findFirstAndLastPrefix(cellindex begin, cellindex end) {
+
+  // First find *any* occurance of the phrase
+  assert(begin <= end);
+
+  // if we're only searching one cell, it is very easy
+  if (begin == end) {
+    assert(comparePrefix(prefixArray[begin], length) == 0);
+    firstPrefix = lastPrefix = prefixArray[begin];
+    firstPrefixIndex = lastPrefixIndex = begin;
+    prefixFrequency = 1;
+    prefixFound = 1;
+    return 0;
+  }
+
+  cellindex c;
+  int cmp;
+
+  do {
+    c = (end + begin) / 2;
+    cmp = comparePrefix(prefixArray[c], length);
+    if (cmp == 1) {
+      begin = c + 1;
+    } else if (cmp == -1) {
+      end = c - 1;
+    }
+  } while (cmp != 0);
+    
+  cellindex lastbegin = c;
+  cellindex lastend = end;
+
+  // Next find the first occurance of the phrase.
+  // We know that the first occurance must be between the 
+  // current value of begin and the cureent value of c.
+  end = c;
+
+  do {
+    if (begin == end) {
+      c = begin;
+      cmp = 0;
+    } else {
+      c = (begin + end) / 2;
+      cmp = comparePrefix(prefixArray[c], length);
+      if (cmp == 1) {
+	// target phrase is lower than phrase at prefixArray[c]
+	begin = c + 1;
+      } else {
+	assert(cmp == 0);
+	// target phrase is the same as the phrase at prefixArray[c].  However, to
+	// find the first occurance, one of two additional condiditons must be met:
+	// either  c == the first cell in prefix array
+	// or      prefixArray[c-1] != phrase.
+	if (c > 0) {
+	  cmp = comparePrefix(prefixArray[c-1], length);
+	  if (cmp == 0) {
+	    end = c - 1;
+	    assert(end >= begin);
+	    cmp = 1;
+	  } else {
+	    cmp = 0;
+	  }
+	}
+      }
+    }
+  } while (cmp != 0);
+
+  // we have found the first location
+  firstPrefixIndex = c;
+  firstPrefix = prefixArray[c];
+
+  // Next find the last occurance of the phrase.
+  // We previously stored some bounds for its loccation.
+  begin = lastbegin;
+  end = lastend;
+  
+  do {
+    if (begin == end) {
+      c = begin;
+      cmp = 0;
+    } else {
+      c = (begin + end) / 2;
+      cmp = comparePrefix(prefixArray[c], length);
+      if (cmp == -1) {
+	// target phrase is greater than phrase at prefixArray[c]
+	end = c - 1;
+      } else {
+	assert(cmp == 0);
+	// target phrase is the same as the phrase at prefixArray[c].  However,
+	// to find the last occurance, prefixArray[c] must be the same as the 
+	// phrase, but prefixArray[c+1] must be different.
+	cmp = comparePrefix(prefixArray[c+1], length);
+	if (cmp == 0) {
+	  begin = c + 1;
+	  cmp = -1;
+	} else {
+	  cmp = 0;
+	}
+      } 
+    }
+  } while (cmp != 0);
+  
+  lastPrefixIndex = c;
+  lastPrefix = prefixArray[c];
+  prefixFrequency = lastPrefixIndex - firstPrefixIndex + 1;
+  prefixFound = 1;
+
+  return 0;
+}
+
+
+// Calculate a set of initial suffix/prefix candidates
+//
+// Expand the phrase to find the initial 
+// set of candidates that may be extensions of that phrase,
+// and add them to the end of the results vector
+
+void Phrase::initialSuffixCandidates(vector<Phrase> &results) {
+
+  ensureSuffixFound();
+  Phrase next;
+  cellindex i = firstSuffixIndex;
+
+  // Find all the expansions of Phrase p
+  while (i <= lastSuffixIndex) {
+
+    // create new phrase exactly one longer than the current one
+    next = newPhraseShortestSuffixExpansion(i);
+
+    // If the expansion occurs more than once and is not delimited, expand it
+    if ((*(next.back) > LASTDELIMITER) && (next.suffixFrequency >= minOccurs)) {
+      next.expandWhileUniqueSuffixExtension();
+      results.push_back(next);
+    }
+    
+    // Move onto the next expansion
+    i = next.lastSuffixIndex + 1;
+  }
+}
+
+
+void Phrase::initialPrefixCandidates(vector<Phrase> &results) {
+
+  ensurePrefixFound();
+  Phrase next;
+  cellindex i = firstPrefixIndex;
+
+  // Find all the expansions of Phrase p
+  while (i <= lastPrefixIndex) {
+
+    // create new phrase exactly one longer than the current one
+    next = newPhraseShortestPrefixExpansion(i);
+
+    // If the expansion occurs more than once and is not delimited, expand it
+    if ((*(next.forward) > LASTDELIMITER) && (next.prefixFrequency >= minOccurs)) {
+      next.expandWhileUniquePrefixExtension();
+      results.push_back(next);
+    }
+    
+    // Move onto the next expansion
+    i = next.lastPrefixIndex + 1;
+  }
+}
+
+
+// Create a new phrase that is longer then the current one, but as short
+// as possible.  In ANYPHRASE mode this means the new phrase is exactly
+// one symbol longer than the current one, but in STOPWORD mode the expansion
+// must introduce a new content symbol
+//
+// Note that we never expand across delimiters; if we encounter a delimiter
+// then this becomes the "end" symbol of the phrase.  The calling function 
+// should check for this condition.
+
+Phrase Phrase::newPhraseShortestSuffixExpansion(cellindex i) {
+  
+  // create a new phrase exactly one symbol longer than the current one
+  Phrase p(suffixArray[i], length + 1, SUFFIX);
+
+  if (phraseMode == STOPWORDS) {
+    // in STOPWORDS mode we must introduce a new content symbol
+    while ((*(p.back) >= firstStopSymbol) &&
+	   (*(p.back) <= lastStopSymbol)) {
+      p.increaseSuffixLength(p.length + 1);
+    }
+  }
+
+  p.findFirstAndLastSuffix(i, lastSuffixIndex);
+  return p;
+}
+
+Phrase Phrase::newPhraseShortestPrefixExpansion(cellindex i) {
+  
+  // create a new phrase exactly one symbol longer than the current one
+  Phrase p(prefixArray[i], length + 1, PREFIX);
+
+  if (phraseMode == STOPWORDS) {
+    // in STOPWORDS mode we must introduce a new content symbol
+    while ((*(p.forward) >= firstStopSymbol) &&
+	   (*(p.forward) <= lastStopSymbol)) {
+      p.increasePrefixLength(p.length + 1);
+    }
+  }
+
+  p.findFirstAndLastPrefix(i, lastPrefixIndex);
+  return p;
+}
+
+
+// Expand a phrase until it no longer has a unique suffix extension
+// 
+// If the phrase only occurs once in the suffix array, do nothing.
+//
+// If we are in stopwords mode then we expand if there is a unique 
+// suffix expansion and this expansion is a content word.  We do this
+// with the content_len variable, which holds the length of the longest
+// phrase ending in a content word. 
+
+int Phrase::expandWhileUniqueSuffixExtension() {
+  ensureSuffixFound();
+
+  // if the phrase occurs only once, do nothing
+  if (suffixFrequency < minOccurs)
+    return 0;
+
+  // if we already know there's no unique suffix extension, do nothing
+  if (uniqueSuffixExtension == 0)
+    return 0;
+
+  // count the length over which the cells are the same
+  // and no delimiter is crossed.
+  symbol *fst = firstSuffix;
+  symbol *lst = lastSuffix;
+  cellindex len = 0;
+  cellindex content_len = 0;
+
+  // Calculate the length over which the phrases match
+  while((*fst == *lst) && (*fst > LASTDELIMITER)) {
+    ++len;
+    if (*fst > lastStopSymbol) content_len = len;
+    ++fst;
+    ++lst;
+  }
+
+  // in ANYPHRASE mode, expand the phrase for as long as possible
+  if (phraseMode == ANYPHRASE) {
+    if (len > length) {
+      increaseSuffixLength(len);
+    }
+  } 
+  // in STOPWORDS mode, expand only as far as the last contentword
+  else {
+    if (content_len > length) {
+      increaseSuffixLength(content_len);
+    }
+  }
+
+  uniqueSuffixExtension = 0;
+  return 0;
+}
+
+int Phrase::expandWhileUniquePrefixExtension() {
+  ensurePrefixFound();
+
+  // if the phrase occurs only once, do nothing
+  if (prefixFrequency < minOccurs)
+    return 0;
+
+  // if we already know there's no unique extension, do nothing
+  if (uniquePrefixExtension == 0)
+    return 0;
+
+  // count the length over which the cells are the same
+  // and no delimiter is crossed.
+  symbol *fst = firstPrefix;
+  symbol *lst = lastPrefix;
+  cellindex len = 0;
+  cellindex content_len = 0;
+
+  // Calculate the length over which the phrases match
+  while((*fst == *lst) && (*fst > LASTDELIMITER)) {
+    ++len;
+    if (*fst > lastStopSymbol) content_len = len;
+    --fst;
+    --lst;
+  }
+
+  // in ANYPHRASE mode, expand the phrase for as long as possible
+  if (phraseMode == ANYPHRASE) {
+    if (len > length) {
+      increasePrefixLength(len);
+    }
+  }
+  // in STOPWORDS mode, expand only as far as the last contentword
+  else {
+    if (content_len > length) {
+      increasePrefixLength(content_len);
+    }
+  }
+
+  uniquePrefixExtension = 0;
+  return 0;
+}
+
+// Compare the length of two phrases
+//
+// Given two phrases, return true if the first is shorter/longer,
+// otherwise return false.  For use in various sort functions.
+
+bool isShorter(Phrase p1, Phrase p2) {
+  if (p1.length < p2.length) {
+    return true;
+  }
+  return false;
+}
+
+bool isLonger(Phrase p1, Phrase p2) {
+  if (p1.length > p2.length) {
+    return true;
+  }
+  return false;
+}
+
+
Index: /gsdl/stable/build-src/src/phind/generate/phrase.h
===================================================================
--- /gsdl/stable/build-src/src/phind/generate/phrase.h	(revision 20131)
+++ /gsdl/stable/build-src/src/phind/generate/phrase.h	(revision 20131)
@@ -0,0 +1,162 @@
+/**********************************************************************
+ *
+ * phrase.h -- definition of the phrase object used by suffix.cpp
+ *
+ * Copyright 2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef PHRASE_H
+#define PHRASE_H
+
+// use the standard namespace
+#if !defined (GSDL_NAMESPACE_BROKEN)
+#if defined(GSDL_USE_OBJECTSPACE)
+using namespace ospace::std;
+#else
+using namespace std;
+#endif
+#endif
+
+#if defined(GSDL_USE_STL_H)
+#  include <vector.h>
+#else
+#  include <vector>
+#endif
+
+#include "suffix.h"
+
+class Phrase {
+
+public:
+
+  // The phrase itself is stored with two pointers: forward points to
+  // its first cell, back points to its last.  The length is always
+  // stored in length.  If one of these is set, all must be set, and
+  // it must be true that (forward + length - 1) = back.
+  symbol *forward;
+  symbol *back;
+  cellcount length;
+  
+  // Phrase location in the suffix array
+  int suffixFound;
+  symbol *firstSuffix;
+  symbol *lastSuffix;
+  cellindex firstSuffixIndex;
+  cellindex lastSuffixIndex;
+  cellcount suffixFrequency;
+
+  // Phrase location in the prefix array
+  int prefixFound;
+  symbol* firstPrefix;
+  symbol* lastPrefix;
+  cellindex firstPrefixIndex;
+  cellindex lastPrefixIndex;
+  cellcount prefixFrequency;
+
+  // Constructor functions
+  Phrase();
+  Phrase(const Phrase &p);
+
+  // A "partial" constructor: the first argument is an array of words,
+  // second is its length, third is the direction (SUFFIX or PREFIX)
+  // in which the words should be read (defaults to SUFFIX).
+  Phrase(symbol *words, cellcount size, int direction);
+
+  // Represent the phrase as an arracy of characters
+  // You will have to call "delete []" on the array returned. 
+  char *toString();
+
+  // Find an initial set of candidate phrases in the suffix/prefix array
+  void initialSuffixCandidates(vector<Phrase> &results);
+  void initialPrefixCandidates(vector<Phrase> &results);
+  
+  // Does the phrase have a unique extension?
+  int hasUniqueSuffixExtension();
+  int hasUniquePrefixExtension();
+  
+  // Extend a phrase by exactly one symbol
+  int expandUniquePrefixExtensionByOne();
+  int expandUniqueSuffixExtensionByOne();
+
+  // Extend a phrase until it no longer has a unique extanesion
+  int expandWhileUniqueSuffixExtension();
+  int expandWhileUniquePrefixExtension();
+
+  // Shorten a phrase by one symbol
+  int shortenByOneAtSuffix();
+  int shortenByOneAtPrefix();
+
+  // Find the phrase in the suffix/prefix array
+  int findFirstAndLastSuffix();
+  int findFirstAndLastPrefix();
+  int findFirstAndLastSuffix(cellindex begin, cellindex end);
+  int findFirstAndLastPrefix(cellindex begin, cellindex end);
+
+  // Make sure the phrase location in the suffix/prefix array is known
+  inline void ensureSuffixFound() {
+    if (!suffixFound)
+      findFirstAndLastSuffix();
+  }
+  inline void ensurePrefixFound() {
+    if (!prefixFound)
+      findFirstAndLastPrefix();
+  }
+
+  // Output a phrase to a stream
+  friend ostream &operator<<(ostream &stream, const Phrase &phrase);
+
+  int uniqueSuffixExtension;
+  int uniquePrefixExtension;
+
+private:
+
+  // Does the phrase have a unique suffix/prefix extension?
+  // if yes, then 1; if no then 0; if unknown then -1;
+
+  // reset a phrase
+  int empty();
+
+  // reset phrase information relating to location in suffix/prefix array
+  int clearSuffix();
+  int clearPrefix();
+
+  // increase the length of a phrase "in place"
+  int increaseSuffixLength(cellcount l);
+  int increasePrefixLength(cellcount l);
+    
+  // Compare the phrase to a given array of symbols
+  int compareSuffix(symbol *words, cellcount length);
+  int comparePrefix(symbol *words, cellcount length);
+
+  // Create a new phrase that is longer than this one, yet as short as possible.
+  Phrase newPhraseShortestSuffixExpansion(cellindex i);
+  Phrase newPhraseShortestPrefixExpansion(cellindex i);
+
+};
+
+
+bool isShorter(Phrase p1, Phrase p2);
+bool isLonger(Phrase p1, Phrase p2);
+
+#endif
+
Index: /gsdl/stable/build-src/src/phind/generate/suffix.cpp
===================================================================
--- /gsdl/stable/build-src/src/phind/generate/suffix.cpp	(revision 20131)
+++ /gsdl/stable/build-src/src/phind/generate/suffix.cpp	(revision 20131)
@@ -0,0 +1,1094 @@
+/**********************************************************************
+ *
+ * Suffix.cpp -- Extract the repeated phrases in the input with suffix
+ *               and prefix arrays (cgn & gwp's simpler algorithm,
+ *               and kjm's improvements).
+ *
+ * Copyright 2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software from the 
+ * New Zealand Digital Library Project at the University of Waikato, 
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(GSDL_USE_IOS_H)
+#  include <fstream.h>
+#  include <iostream.h>
+#else
+#  include <fstream>
+#  include <iostream>
+#endif
+
+#if defined(GSDL_USE_STL_H)
+#  if defined(GSDL_USE_ALGO_H)
+#    include <algo.h>
+#  else
+#    include <algorithm.h>
+#  endif
+#  include <vector.h>
+#else
+#  include <algorithm>
+#  include <vector>
+#endif
+
+#include "suffix.h"
+#include "phrase.h"
+#include "check.h"
+
+// Global variables declared in suffix.h
+cellcount inputLength;
+
+symbol   *symbols;
+symbol  **suffixArray;
+symbol  **prefixArray;
+
+// How many documents are in this collection?
+cellcount numberOfDocuments;
+symbol  **documentArray;
+
+
+// Do we accept any phrase, or do we eliminate those ending with stopwords ?
+int phraseMode = ANYPHRASE; //STOPWORDS;
+// What is the minimum phrase frequency for a phrase to be included in the hierarchy
+int minOccurs = 2;
+
+// The filestem of the collection's phindex directory
+char collection[FILENAME_MAX];
+
+
+// The ranges of the stopword and content-word symbols for the collection
+symbol firstStopSymbol = 0;
+symbol lastStopSymbol = 0;
+symbol firstContentSymbol = 0;
+symbol lastContentSymbol = 0;
+
+
+// Some useful comparison functions, defined below.
+int suffixCompare(const void *, const void *);
+int prefixCompare(const void *, const void *);
+int pointerCompare(const void *, const void *);
+
+                                           
+// Functions for implementing "phrase memory".  These let us "remember"
+// each phrase that we've expanded without using too much memory.
+void initialisePhraseMemory();
+void rememberThisPhrase(cellindex index, cellcount length);
+bool isPhraseStored(cellindex index, cellcount length);
+void deletePhraseMemory();
+
+
+// how much output do we want?
+int verbosity = 1;
+
+
+// Get a phrase's expansions
+//
+// Get the set of "minimal", "maximal", non-unique expansions of a
+// phrase p, using the simpler algorithm that Craig and Gordon came up
+// with at Google.
+//
+// Returns a vector of Expansions.
+
+void getExpansions(Phrase &p, vector<Phrase> &results) {
+
+  // 1. Get the initial candidates
+  vector<Phrase> candidates;
+  p.initialSuffixCandidates(candidates);
+  int suffcands = candidates.size();
+  p.initialPrefixCandidates(candidates);
+
+  if (candidates.size() == 0)
+    return;
+
+  vector<Phrase>::iterator i;
+  for (i = candidates.begin(); i != candidates.end(), suffcands>0; ++i, --suffcands) {
+    i->expandWhileUniquePrefixExtension();
+    i->ensureSuffixFound();
+  }
+  for (i; i != candidates.end(); ++i) {
+    i->expandWhileUniqueSuffixExtension();
+  }
+
+  // 3. Ensure minimality: ignore phrases whose subphrases are also found
+  results.clear();
+
+  // Initialise the candidates, check array, and various variables.
+  sort(candidates.begin(), candidates.end(), isShorter);
+  unsigned minimum_length = candidates.begin()->length;
+  clearSuffixCheck();
+  
+  // Try to add each candidate to the results set, ignoring the non-minimal
+  for (vector<Phrase>::iterator candidate = candidates.begin(); 
+       candidate != candidates.end(); ++candidate) {
+
+    // Make a copy of candidate to mutilate while performing sub-phrase checks
+    Phrase temp_phrase(*candidate);
+    bool shorter_found = false;
+    
+    // Check for shorter and shorter versions of the temporary phrase
+    while (temp_phrase.length >= minimum_length && !shorter_found) {
+      temp_phrase.ensureSuffixFound();
+      if (getSuffixCheck(temp_phrase.firstSuffixIndex)==0)
+	temp_phrase.shortenByOneAtPrefix();
+      else
+	shorter_found = true;
+
+      // Possible efficiency here: we can finish if the prefix of c
+      // and temp_phrase are the same for candidate->length symbols.
+    }
+      
+    // If no shorter phrase is found, use this one
+    if (!shorter_found) {
+      results.push_back(*candidate);
+      candidate->ensureSuffixFound();
+      setSuffixCheck(candidate->firstSuffixIndex, candidate->lastSuffixIndex);
+    }
+  }
+}
+
+
+// suffixCompare
+//
+// Compare two pointers into a suffix array.  We use this in the 
+// qsort function, so the input are pointers to pointers.  
+//
+// Return -1 if (a < b), otherwise (a > b) so return +1, 
+
+int suffixCompare(const void *cpa, const void *cpb) {
+
+  // Cast then dereference pointers to suffix array elements
+  symbol *pa = (symbol *) cpa;
+  symbol *pb = (symbol *) cpb;
+  pa = (symbol *) *pa;
+  pb = (symbol *) *pb;
+
+  // If the two elements are the same, examine the next one
+  while (*pa == *pb) {
+    *pa++;
+    *pb++;
+  }
+
+  // Make the copmparison and return
+  if ( *pa < *pb) {
+    return -1;
+  } else {
+    return +1;
+  }
+}
+
+
+// prefixCompare
+//
+// Compare two pointers into a prefix array.  We use this in the 
+// qsort function, so the input are pointers to pointers.  
+//
+// Return -1 if (a > b), otherwise (a < b) so return +1, 
+
+int prefixCompare(const void *cpa, const void *cpb) {
+
+  // Cast then dereference pointers to prefix array elements
+  symbol *pa = (symbol *) cpa;
+  symbol *pb = (symbol *) cpb;
+  pa = (symbol *) *pa;
+  pb = (symbol *) *pb;
+
+  // If the two elements are the same, examine the next one
+  while (*pa == *pb) {
+    *pa--;
+    *pb--;
+  }
+
+  // Make the copmparison and return
+  if ( *pa > *pb) {
+    return -1;
+  } else {
+    return +1;
+  }
+}
+
+// simpleCompare
+//
+// Compare two pointers based on the memory location they point to.
+
+int pointerCompare( const void *pa, const void *pb ) {
+
+  symbol **a = (symbol **) pa;
+  symbol **b = (symbol **) pb;
+
+  if (*a < *b) {
+    return  -1;
+  } else if (*a > *b) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+
+// Read the clauses.numbers file into the "symbols" array.
+//
+// Each number in the file is a symbol number; it is essential that 
+// the first symbol (and no others) be COLLECTIONSTART and the last
+// symbol (and no others) be COLLECTIONEND.
+//
+// Return the number of numbers in the array.
+
+int readNumbers() {
+
+  char filename[FILENAME_MAX];
+  sprintf(filename, "%s/clauses.numbers", collection);
+  if (verbosity) {
+    cout << "Reading numbers file: " << filename << endl;
+  }
+
+  // Open the numbers file
+  ifstream inFile1(filename, ios::in);
+  if (!inFile1) {
+    cerr << "File " << filename << " could not be opened\n";
+    exit(1);
+  }
+
+  // Count the number of symbols
+  inputLength = 0;
+  symbol word;
+  while (inFile1 >> word) {
+    ++inputLength;
+  }
+  inFile1.close();
+
+  // Allocate the symbbols array
+  if (verbosity > 1) {
+    cout << "Allocating symbol arrays for " << inputLength << " symbols" << endl;
+  }
+  symbols = new symbol[inputLength];
+  if (symbols == NULL) {
+    cerr << "Suffix error: not enough memory to hold " << inputLength
+	 << " symbols." << endl;
+    exit(2);
+  }
+
+  // Read the numbers file into the numbers array
+  if (verbosity > 2) {
+    cout << "Reading the numbers" << endl;
+  }
+
+  ifstream inFile2(filename, ios::in);
+  if (!inFile2) {
+    cerr << "File " << filename << " could not be opened\n";
+    exit(1);
+  }
+  cellcount next = 0;
+  numberOfDocuments = 0;
+  while (inFile2 >> word) {
+    symbols[next++] = word;
+    if (word == DOCUMENTSTART) {
+      ++numberOfDocuments;
+    }
+  }
+  inFile2.close();
+  
+  // Make sure the numbers file is intact
+  assert(symbols[0] == COLLECTIONSTART);
+  assert(symbols[next-1] == COLLECTIONEND);
+
+  return inputLength;
+}
+
+
+
+// Get Document Occurrance statistics
+//
+// Given a phrase, what documents does it occur in?
+
+cellcount getDocumentOccurrances(const Phrase &p, cellcount *frequency) {
+
+  // cout << "searching for \""<< p << "\" in documents " 
+  //      << 0 << "-" << numberOfDocuments - 1 << endl;
+
+  // The number of documents in which this phrase occurs
+  cellcount df = 0;
+
+  // Initialise the document frequency array
+  //  for (cellindex i = 0; i < numberOfDocuments; ++i) {
+  // frequency[i] = 0;
+  //}
+  memset(frequency, 0, sizeof(cellcount)*numberOfDocuments);
+
+  // variables used to facilitate the search
+  cellindex begin;
+  cellindex end;
+  cellindex d;
+  symbol *target;
+  bool found;
+
+  // search for the document in which each occurence of the phrase is found
+  for (cellcount j = p.firstSuffixIndex; j <= p.lastSuffixIndex; ++j) {
+    
+    // cout << "looking for phrase at suffixArray[" << j << "]\n";
+    
+    target = suffixArray[j];
+    begin = 0;
+    end = numberOfDocuments - 1;
+    found = false;
+
+    // Search for the occurence of a document delimiter that target
+    // occurs immediately after.  
+    // We do this by performing a binary chop search on documentArray.
+    while (!found) {
+
+      // cout << "searching for " << (cellindex) target << " in "
+      //      << begin << " - " << end << endl;
+
+      assert (begin <= end);
+
+      // If the beginning and end of the interval are the same,
+      // then we've found the correct document
+      if (begin == end) {
+	if (frequency[begin] == 0) {
+	  ++df;
+	}
+	++frequency[begin];
+	found = true;
+      }
+
+      // Otherwise, examine a new document midway through the begin-end
+      // interval and see if it is the one.
+      else {
+	d = (begin + end) / 2;
+	if (target > documentArray[d]) {
+	  // If target addrss is greater than this, but thisi sthe last document,
+	  // then this must be the one we want.  Or, if target is greater than
+	  // this one but less then the next, this must be the one we wnat.
+	  if ((d == numberOfDocuments - 1) || (target < documentArray[d+1])) {
+	    if (frequency[d] == 0) {
+	      ++df;
+	    }
+	    ++frequency[d];
+	    found = true;
+	  } else {	
+	    // otherwise we know to search later in the document set
+	    begin = d + 1;
+	  }
+	} else {
+	  // search earlier in the document set
+	  end = d - 1;
+	}
+      }
+    }
+  }
+  return df;
+}
+
+
+
+
+
+
+// phraseExpansionMemory : Which phrases have we expanded?
+//
+// A set of utilities for keeping track of which phrases we have expanded.
+// We don't want to expand a phrase more than once, after all.
+//
+// This REALLY ought to be in its own class, but it works so that's okay.
+//
+// Phrases are identified by their firstSuffixPosition and length.
+//
+// Functions provided are:
+//       void initialisePhraseMemory()
+//       void rememberThisPhrase(index, length)
+//       bool isPhraseStored(index, length)
+//       void deletePhraseMemory()
+//
+// Internally, we will have two separate cases:
+//
+// Phrases of length 1-8: 
+//       unsigned char phraseMemory[inputLength]
+// is an array where each cell "remembers" the corresponding index in the 
+// suffixArray, and each of the 8 bits of the cell correspond to the phrases 
+// of length 1, 2... 8.  
+// Eventually, we will make this disk-based (i.e. store the array in a file).
+//
+// Phrases of length 9+:
+//       file hashTableFile
+//       file listOfEntries
+// The first file is a hash table; each phrase maps to one of its cells, which
+// contains either 0 (empty, no occurence) or a number which is an entry number 
+// in the second file.  This file contains a "list" of entries.  Each consists of 
+// three numbers: the suffixArray index of the phrase, the length of the phrase,
+// and the entry number of the next phrase with the same hash.
+//
+
+
+unsigned char *phraseMemory;
+
+void initialiseLongPhraseMemory();
+void rememberThisLongPhrase(cellindex index, cellcount length);
+bool isLongPhraseStored(cellindex index, cellcount length);
+void deleteLongPhraseMemory();
+
+
+void initialisePhraseMemory() {
+
+  phraseMemory = new unsigned char[inputLength];
+
+  // to begin with, everything is empty
+  //  for (cellcount i = 0; i < inputLength; ++i) {
+  // phraseMemory[i] = 0;
+  //}
+  memset(phraseMemory, 0, sizeof(char)*inputLength);
+  
+  // intialise the hashTable of long phrases
+  initialiseLongPhraseMemory();
+
+}
+
+void rememberThisPhrase(cellindex index, cellcount length) {
+
+  // if the phrase is very long, use the file-based system
+  if (length > 8) {
+    rememberThisLongPhrase(index, length);
+    return;
+  }
+
+  // create a char with just the bit corresponding to length set
+  unsigned char newbit = 1;
+  for (cellcount i = 1; i < length; ++i) {
+    newbit <<= 1;
+  }
+
+  // set that bit in the memory array at position index
+  phraseMemory[index] |= newbit;
+}
+
+
+bool isPhraseStored(cellindex index, cellcount length) {
+
+  // if the phrase is very long, use the file-based system
+  if (length > 8) {
+    return isLongPhraseStored(index, length);
+  }
+
+  // create a char with just the bit corresponding to length set
+  unsigned char newbit = 1;
+  for (cellcount i = 1; i < length; ++i) {
+    newbit <<= 1;
+  }
+
+  // retrurn true if that bit is set in memory arrayat position index
+  return (phraseMemory[index] & newbit);
+}
+
+void deletePhraseMemory() {
+  delete []phraseMemory;
+  deleteLongPhraseMemory();
+}
+
+
+
+// Files etc used to store "long" equavlents of the above
+
+fstream hashTableFile;
+char    hashTableFileName[FILENAME_MAX];
+fstream listOfEntries;
+char    listOfEntriesName[FILENAME_MAX];
+cellindex nextEntryNumber;
+
+const cellcount bigPrime = 7919;
+
+
+void initialiseLongPhraseMemory() {
+
+  cellindex example = 0;
+
+  sprintf(hashTableFileName, "%s/hashTable", collection);
+  sprintf(listOfEntriesName, "%s/hashLists", collection);
+
+
+  // create the new hashtable
+  if (verbosity > 1) {
+    cout << "Initialising hashTable: " << hashTableFileName << endl;
+  }
+  hashTableFile.open(hashTableFileName, ios::in | ios::out);
+  for (cellcount i = 0; i < bigPrime; ++i) {
+    hashTableFile.write((char *) &example, sizeof(example));
+  }
+
+  // create the list of phrases
+  if (verbosity > 1) {
+    cout << "Initialising list of hashtable entries: " << listOfEntriesName << endl;
+  }
+  listOfEntries.open(listOfEntriesName, ios::in | ios::out);
+  listOfEntries.write((char *) &example, sizeof(example));
+  listOfEntries.write((char *) &example, sizeof(example));
+  listOfEntries.write((char *) &example, sizeof(example));
+  nextEntryNumber = 1;
+}
+
+
+void rememberThisLongPhrase(cellindex index, cellcount length) {
+
+  // cout << "rememberThisLongPhrase(" << index << ", " << length << ")\n";
+
+  cellindex hashOffset = ((index + length) % bigPrime) * sizeof(cellindex);
+  cellindex pointer;
+  cellindex zero = 0;
+  cellindex readp = 0;
+  cellindex readi = 0;
+  cellindex readl = 0;
+
+  hashTableFile.seekg(hashOffset);
+  hashTableFile.read((char *) &pointer, sizeof(cellindex));
+
+  if (pointer == 0) {
+    // There is no entry at all in the hash table for this entry
+    // so create one
+
+    pointer = nextEntryNumber++;
+    hashTableFile.seekg(hashOffset);
+    hashTableFile.write((char *) &pointer, sizeof(cellindex));
+        
+    listOfEntries.seekp(pointer * sizeof(cellindex) * 3);
+    listOfEntries.write((char *) &zero, sizeof(cellindex));
+    listOfEntries.write((char *) &index, sizeof(cellindex));
+    listOfEntries.write((char *) &length, sizeof(cellindex));
+
+  } else {
+    // There is a list starting at this hash value, so the phrase may
+    // be already remembered, or it might need to be appended
+    
+    while (pointer != 0) {
+      // Read the entry pointed to by pointer
+      listOfEntries.seekg(pointer * sizeof(cellindex) * 3);
+      listOfEntries.read((char *) &readp, sizeof(cellindex));
+      listOfEntries.read((char *) &readi, sizeof(cellindex));
+      listOfEntries.read((char *) &readl, sizeof(cellindex));
+
+      // cout << "read " << pointer << ", " << readp << ", " << readi << ", " << readl << endl;
+
+      if ((readi == index) && (readl = length)) {
+	// we've found that we've already stored it
+	return;
+      } else if (readp == 0) {
+	// we're reached the end of the list.  Add a new entry.
+	listOfEntries.seekp(pointer * sizeof(cellindex) * 3);
+	listOfEntries.write((char *) &nextEntryNumber, sizeof(cellindex));
+	pointer = nextEntryNumber++;
+
+	listOfEntries.seekp(pointer * sizeof(cellindex) * 3);
+	listOfEntries.write((char *) &zero, sizeof(cellindex));
+	listOfEntries.write((char *) &index, sizeof(cellindex));
+	listOfEntries.write((char *) &length, sizeof(cellindex));
+	return;
+      } else {
+	// go on to the next node
+	pointer = readp;
+      }
+    }
+  }
+
+
+}
+
+
+bool isLongPhraseStored(cellindex index, cellcount length) {
+
+  // cout << "isLongPhraseExpanded(" << index << ", " << length << ")\n";
+
+  cellindex hashOffset = ((index + length) % bigPrime) * sizeof(cellindex);
+  cellindex pointer;
+  cellindex readp = 0;
+  cellindex readi = 0;
+  cellindex readl = 0;
+
+  // Find the phrase in the hashFile
+  hashTableFile.seekg(hashOffset);
+  hashTableFile.read((char *) &pointer, sizeof(cellindex));
+
+  if (pointer == 0) {
+    // There is no entry at all in the hash table for this entry
+    // so nothing is stored
+    return false;
+
+  } else {
+    // There is a list starting at this hash value, so the phrase may
+    // be already remembered in that list
+    while (pointer != 0) {
+      // Read the entry pointed to by pointer
+      listOfEntries.seekg(pointer * sizeof(cellindex) * 3);
+      listOfEntries.read((char *) &readp, sizeof(cellindex));
+      listOfEntries.read((char *) &readi, sizeof(cellindex));
+      listOfEntries.read((char *) &readl, sizeof(cellindex));
+
+      if ((readi == index) && (readl = length)) {
+	// we've found the phrase stored here
+	return true;
+      } else {
+	// go on to the next node
+	pointer = readp;
+      }
+    }
+  }
+  return false;
+}
+
+
+void deleteLongPhraseMemory() {
+  // remove the hash & other files
+
+  hashTableFile.close();
+  listOfEntries.close();
+  remove(hashTableFileName);
+  remove(listOfEntriesName);
+
+}
+
+
+// Read the collection statistics file
+//
+void readStatistics() {
+
+  // open the statistics file
+  char filename[FILENAME_MAX];
+  sprintf(filename, "%s/clauses.stats", collection);
+
+  // Open the file
+  ifstream inFile(filename, ios::in);
+  if (!inFile) {
+    cerr << "File " << filename << " could not be opened\n";
+    exit(1);
+  }
+
+  // Read the numbers file into the numbers array
+  char key[1000];
+  symbol value;
+  while (inFile >> key >> value){
+    if (strcmp(key, "first_stopword") == 0) {
+      firstStopSymbol = value;
+    } else if (strcmp(key, "last_stopword") == 0) {
+      lastStopSymbol = value;
+    } else if (strcmp(key, "first_contentword") == 0) {
+      firstContentSymbol = value;
+    } else if (strcmp(key, "last_contentword") == 0) {
+      lastContentSymbol = value;
+    }
+  }
+  inFile.close();
+
+  // Make sure we have the information we need
+  if (!(firstStopSymbol && lastStopSymbol && firstContentSymbol && lastContentSymbol)) {
+    cerr << "Statistics file incomplete" << endl;
+    exit(1);
+  }
+}
+
+cellcount getContentCount(symbol firstContent) {
+
+  cellcount content=0;
+  for (cellcount i=0; i<inputLength; ++i) {
+    if (symbols[i]>=firstContent) ++content;
+  }
+
+  return content;
+}
+
+
+int main (int argc, char * argv[]) {
+
+  // Command-line arguments
+  // argv[1] is the phindex directory
+  // argv[2] is the mode, where 1 is stopword mode 
+  // argv[3] is the min_occurs, - minimum occurrence frequency for a phrase to be included in the hierarchy
+  // argv[4] is opitonal verbosity
+  if (argc < 4) {
+    cerr << "Usage: " << argv[0] << " phind-directory mode min-phrase-freq [verbosity]" << endl;
+    exit(1);
+  }
+
+  // collection directory
+  strcpy(collection, argv[1]);
+
+  // mode parameter
+  phraseMode = atoi(argv[2]);
+  assert((phraseMode == STOPWORDS) || (phraseMode == ANYPHRASE));
+
+  minOccurs = atoi(argv[3]);
+  assert((minOccurs > 0));
+
+  // optional verbosity parameter
+  if (argc == 5) {
+    verbosity = atoi(argv[4]);
+    assert (verbosity >= 0);
+  }
+
+  if (verbosity) {
+    cout << "suffix: the phrase extraction program" << endl;
+  }
+  if (verbosity > 1) {
+    if (phraseMode == STOPWORDS) {
+      cout << "Stopwords mode: no phrase may begin or end with a stopword" << endl;
+    } else {
+      cout << "AllPhrase mode: extract every phrase that occurs more than once" << endl;
+    }
+  }
+
+  // Read the statistics file 
+  readStatistics();
+  // Read the numbers file
+  readNumbers();
+  
+  if (numberOfDocuments == 0) {
+    cerr << "There are no documents in this collection!" << endl;
+    exit(0); // not necessarily an error...
+  }
+
+  symbol firstContent;
+  if (phraseMode==STOPWORDS) firstContent=firstContentSymbol;
+  else firstContent = firstStopSymbol;
+
+  // Allocate memory for the suffix & prefix arrays
+  cellcount contentLength = 0;
+  contentLength = getContentCount(firstContent);
+  suffixArray = new symbol *[contentLength];
+  prefixArray = new symbol *[contentLength];
+  if (prefixArray == NULL) {
+    cerr << "Suffix: not enough memory to hold " << inputLength << " symbols." << endl;
+    exit(2);
+  }
+  allocateSuffixCheck(contentLength);
+  // Initialise prefix and suffix arrays, only use the needed suffixes
+  for (cellcount j = 0, here = 0; j < inputLength; ++j) {
+    if (symbols[j]>=firstContent) {
+      suffixArray[here] = &symbols[j];
+      prefixArray[here] = &symbols[j];
+      ++here;
+    }    
+  }
+  qsort(suffixArray, contentLength, sizeof(symbol *), suffixCompare);
+  qsort(prefixArray, contentLength, sizeof(symbol *), prefixCompare);
+  // Create the document arrays
+  if (verbosity > 1) {
+    cout << "Allocating document arrays for " << numberOfDocuments << " documents" << endl;
+  }
+
+  // The document frequecy array is used to count the number of times
+  // each phrase occurs in each document.  The number of documents in
+  // which a phrase occurs is stored in df.
+  frequency *documentFrequency = new frequency[numberOfDocuments];
+  frequency df;
+
+  // documentArray will be searched in order to discover which document
+  // each phrase occurs in.
+  documentArray = new symbol *[numberOfDocuments];  
+  if (documentArray == NULL) {
+    cerr << "Suffix: out of memory allocating document arrays." << endl;
+    exit(2);
+  }  
+
+  // just scan through the input text to find the doc starts
+  cellindex d = 0;
+  for (cellindex i=0; i<inputLength; ++i) {
+    if (symbols[i] == DOCUMENTSTART) {
+      documentArray[d] = &symbols[i];
+      ++d;
+    }
+  }
+
+  // the phrases stuff is expecting inputLength to be the length of the
+  // suffix array, so change it.
+  inputLength = contentLength;
+
+  // Extract phrases
+  //
+  // We will make several passesover the data, in each case considering
+  // a set of input phrases and generating a set of output phrases, which
+  // we will expancd in later passes.
+  //
+  // The input phrases in the first pass will be the vocabulary.
+  // In later passes, the input phrases will be the output phrases of the
+  // previous pass.
+  //
+  // In each pass we will consider each input phrase in turn.  If we
+  // have seen it before, we will ignore it.  Otherwise, we will expand
+  // it and add its expansions to the set of output phrases.
+
+  cout <<"\ngenerating the phrase hierarchy\n\n";
+  
+  // Store the phrase data in the phrases file
+  char phraseDataName[FILENAME_MAX];
+  sprintf(phraseDataName, "%s/phrases", collection);
+  ofstream phraseData(phraseDataName, ios::out);
+  if (!phraseData) {
+    cout << "File " << phraseDataName << " could not be opened\n";
+    exit(1);
+  }
+
+  // Count the number of phrases output
+  unsigned long int phraseCounter = 0;
+
+  // Set up the phrase expansion memory.
+  // We need this so that we don't expand a phrase more than once
+  initialisePhraseMemory();
+
+  // The current pass numebr
+  int phrasePass = 1;
+
+
+  // PASS NUMBER 1
+  if (verbosity > 1) {
+    cout << "Starting pass " << phrasePass << endl;
+  }
+
+  ofstream outPhrase;
+  char     outPhraseName[FILENAME_MAX];
+  unsigned long int outPhraseCounter = 0;
+
+  // On the first pass, simply work through the vocabulary
+  sprintf(outPhraseName, "%s/outPhrase.1", collection);
+  outPhrase.open(outPhraseName, ios::out);
+  if (!outPhrase) {
+    cerr << "File " << outPhraseName << " could not be opened\n";
+    exit(1);
+  }
+
+  // Iterate over the different symbols by working through the suffix array
+  vector<Phrase> result;
+  cellindex ij = 0;
+  char *tmpString;
+
+  Phrase p;
+  while (ij < inputLength) {
+
+    // make a new phrase of length 1
+    p = Phrase(suffixArray[ij], 1, SUFFIX);
+    p.findFirstAndLastSuffix(ij, inputLength-1);
+
+    // We ignore this symbol if it occurs only once, if it is a delimiter,
+    // of if we are in stopwords mode and it is a stopword
+    // - in this new version, only need to check freq
+    // We could imagine a new mode/command-line option, which is like 
+    // STOPWORDS but without this restrictrion.  This would let you browse
+    // from "the" to "the AGRIS" for example, but not from "AGRIS" to
+    // "the AGRIS" (where the is a stopword and AGRIS a content word).
+    // The system used to work like this; it is easy to implement, but
+    // it explodes the size of the indexes.  So: would it be useful?  
+    if (p.suffixFrequency >= minOccurs) {
+      // Get minimal expansions of the phrase
+      getExpansions(p, result);
+      
+      if (!result.empty()) {
+	
+	// Remember that we have expanded this phrase
+	rememberThisPhrase(ij, 1);
+
+	// write the phrase text
+	phraseData << ij << "-1:" << p << ":" << p.suffixFrequency << ":"
+		   << result.size() << ":";
+
+	// write the results
+	for (cellcount k = 0; k < result.size(); ++k) {
+	  if (k) {
+	    phraseData << ",";
+	  }
+	  phraseData << result[k].firstSuffixIndex << "-" << result[k].length;
+	  outPhrase << result[k].firstSuffixIndex << " " << result[k].length << endl;
+	  ++outPhraseCounter;
+	}
+	result.clear();
+	
+	// Write the documents in which this phrase occurs
+	df = getDocumentOccurrances(p, documentFrequency);
+	phraseData << ":" << df << ":";
+
+	// write the documents
+	for (cellcount m = 0, first = 1; m < numberOfDocuments; ++m) {
+	  if (documentFrequency[m]) {
+	    if (first) {
+	      first = 0;
+	    } else {
+	      phraseData << ";";
+	    }
+	    // Output the document number.  Note that here we've numbered the 
+	    // N documents from 0 to N-1, but later they'll be 1-N.  Thus we
+	    // add 1 to the document id when we output it.
+	    phraseData << "d" << (m+1);
+	    // Next, output the frequency with which the document occurs, but
+	    // only if it is > 1.
+	    if (documentFrequency[m] > 1) {
+	      phraseData << "," << documentFrequency[m];
+	    }
+	  }
+	}
+
+	phraseData << endl;
+	++phraseCounter;
+
+	// feedback 
+	if (verbosity) {
+	  if (phraseCounter % 1000 == 0) {
+	    cout << "phrase " << phraseCounter << ": "
+		 << "cell " << p.firstSuffixIndex << " - " << p << endl;
+	  }
+	}
+      }
+    }
+   ij = p.lastSuffixIndex + 1;
+  }
+  outPhrase.close();
+
+  // REMAINING PASSES
+  // The previous outPhrase file forms the input to each new pass
+  cellcount start, length;
+  while (outPhraseCounter > 0) {
+
+    // Start a new pass
+    ++phrasePass;
+    if (verbosity) {
+      cout << "Starting pass " << phrasePass << endl;
+    }
+
+    // Open the input file
+    char inPhraseName[FILENAME_MAX];
+    sprintf(inPhraseName, "%s/outPhrase.%d", collection, phrasePass - 1);
+    ifstream inPhrase (inPhraseName, ios::in);
+    if (!inPhrase) {
+      cerr << "File " << inPhraseName << " could not be opened\n";
+      exit(1);
+    }
+
+    // Open the output file
+    sprintf(outPhraseName, "%s/outPhrase.%d", collection, phrasePass);
+    outPhrase.open(outPhraseName, ios::out);
+    if (!outPhrase) {
+      cerr << "File " << outPhraseName << " could not be opened\n";
+      exit(1);
+    }
+    outPhraseCounter = 0;
+
+    // Process each phrase
+    while(inPhrase >> start >> length) {
+
+      // Ignore the phrase if we have expanded it before
+      if (isPhraseStored(start, length))
+	continue;
+
+      // Remember that we have examined this phrase
+      rememberThisPhrase(start, length);
+
+      // Find the phrase in the suffixarray
+      p = Phrase(suffixArray[start], length, SUFFIX);
+      p.findFirstAndLastSuffix(start, inputLength-1);
+
+      // Ignore the phrase if it only occurs once
+      if (p.suffixFrequency < minOccurs)
+	continue;
+
+      // Write the phrase text;
+      phraseData << start << "-" << length << ":" << p << ":" << p.suffixFrequency << ":";
+	
+      // Expand the phrase, if it is fewer than 8 words long
+      if (length <= 8) {
+
+	// Get the minimal expansions for this phrase
+	getExpansions(p, result);
+      
+	// write the results
+	phraseData << result.size() << ":";
+
+	for (cellcount i = 0; i < result.size(); ++i) {
+	  if (i) {
+	    phraseData << ",";
+	  }
+	  phraseData << result[i].firstSuffixIndex << "-" << result[i].length;
+	  outPhrase << result[i].firstSuffixIndex << " " << result[i].length << endl;
+	  ++outPhraseCounter;
+	}
+	result.clear();
+	
+      } else {
+	// phrase is too long to expand further
+	phraseData << "0:";
+      }
+
+      // Write the documents in which this phrase occurs
+      df = getDocumentOccurrances(p, documentFrequency);
+      phraseData << ":" << df << ":";
+
+      // write the documents
+      for (cellcount i = 0, first = 1; i < numberOfDocuments; ++i) {
+	if (documentFrequency[i]) {
+	  if (first) {
+	    first = 0;
+	  } else {
+	    phraseData << ";";
+	  }
+	  // Output the document number.  Note that here we've numbered the 
+	  // N documents from 0 to N-1, but later they'll be 1-N.  Thus we
+	  // add 1 to the document id when we output it.
+	  phraseData << "d" << (i+1);
+	  // Next, output the frequency with which the document occurs, but
+	  // only if it is > 1.
+	  if (documentFrequency[i] > 1) {
+	    phraseData << "," << documentFrequency[i];
+	  }
+	}
+      }
+      
+      phraseData << endl;
+      ++phraseCounter;
+
+      // feedback 
+      if (verbosity) {
+	if (phraseCounter % 1000 == 0) {
+	  cout << "phrase " << phraseCounter << ": "<< "start " << start 
+	       << ", length " << length << " - " << p << endl;
+	}
+      }
+
+    }
+
+    inPhrase.close();
+    outPhrase.close();
+  }
+    
+  phraseData.close();
+  deletePhraseMemory();
+
+  delete [] documentFrequency;
+  delete [] symbols;
+  delete [] suffixArray;
+  delete [] prefixArray;
+  delete [] suffixCheck;
+  delete [] documentArray;
+
+
+  
+  cout << endl << "Done: " << phraseCounter << " phrases in " << phraseDataName << endl;
+  return 0;
+}
+
+
+
+
+
Index: /gsdl/stable/build-src/src/phind/generate/suffix.h
===================================================================
--- /gsdl/stable/build-src/src/phind/generate/suffix.h	(revision 20131)
+++ /gsdl/stable/build-src/src/phind/generate/suffix.h	(revision 20131)
@@ -0,0 +1,89 @@
+/**********************************************************************
+ *
+ * suffix.h -- definitions used in suffix.cpp
+ *
+ * Copyright 2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef SUFFIX_H
+#define SUFFIX_H
+
+// Types
+
+// The input words stored as an array of type symbol.
+// Required range: 0 - vocabulary size (typically hundreds of thousands)
+typedef unsigned int symbol;
+
+// The cellindex and cellcount types are used when we store indexes
+// to and ranges of cells in large arrays.
+// Required Range: 0 - length of input (typically millions)
+typedef unsigned int cellindex;
+typedef unsigned int cellcount;
+
+// The frequency type is used when we want to store the frequency with 
+// which a phrase (or some other thing) occurs
+// Required range: 0 - frequency of most common symbol (often "the")
+typedef unsigned int frequency;
+
+// Global variables 
+
+// The symbol array holds the input words
+extern cellcount symbol_array_length;
+extern symbol   *symbols;
+
+// The number of words read is storesd in inputLength.
+extern cellcount inputLength;
+
+// Suffix and prefix arrays are used to extract phrases
+extern symbol  **suffixArray;
+extern symbol  **prefixArray;
+
+// Collection-specific information about the first stopword/content symbols
+extern symbol firstStopSymbol;
+extern symbol lastStopSymbol;
+extern symbol firstContentSymbol;
+extern symbol lastContentSymbol;
+
+
+// Are we allowed to terminate a phrase on a stopword?
+extern int phraseMode;
+extern int minOccurs;
+
+#define ANYPHRASE 0
+#define STOPWORDS 1
+
+
+// Direction values
+#define SUFFIX 0
+#define PREFIX 1
+
+
+// Special symbol values
+#define COLLECTIONSTART 1
+#define COLLECTIONEND 2
+#define DOCUMENTSTART 3
+#define PHRASELIMIT 4
+
+#define LASTDELIMITER 4
+
+#endif
Index: /gsdl/stable/build-src/src/phind/generate/symbol-names.pl
===================================================================
--- /gsdl/stable/build-src/src/phind/generate/symbol-names.pl	(revision 20131)
+++ /gsdl/stable/build-src/src/phind/generate/symbol-names.pl	(revision 20131)
@@ -0,0 +1,57 @@
+#! /usr/bin/perl -w
+
+###########################################################################
+#
+# symbol-names.pl -- Diagnostic tool that substitutes symbols names for 
+#                    symbol numbers in the output of the suffix program. 
+#
+# Copyright (C) 2000 Gordon Paynter
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+$collection = shift(@ARGV);;
+die "Usage: symbol-names.pl collection [file]\n" unless ($collection);
+
+$vocab = $ENV{'GSDLHOME'} . "/collect/$collection/index/phind1/clauses.vocab";
+if (-e "$vocab") {
+    print "Using vocabulary from: $vocab\n";
+} else {
+    $vocab = $ENV{'GSDLHOME'} . "/collect/$collection/building/phind1/clauses.vocab";
+    if (-e "$vocab") {
+	print "Using vocabulary from: $vocab\n";
+    } else {
+	die "Usage: symbol-names.pl collection [file]\n" unless (-e "$vocab");
+    }
+}
+
+open(V, "<$vocab");
+my $n = 1;
+
+while(<V>) {
+    chomp;
+    $symbol[$n++] = $_;
+}
+
+while(<>) {
+    s/s(\d+)/$symbol[$1]/g;
+    print;
+}
+
Index: /gsdl/stable/build-src/src/phind/generate/win32.mak
===================================================================
--- /gsdl/stable/build-src/src/phind/generate/win32.mak	(revision 20131)
+++ /gsdl/stable/build-src/src/phind/generate/win32.mak	(revision 20131)
@@ -0,0 +1,83 @@
+###########################################################################
+#
+# win32 makefile -- src/phind/generate
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDLHOME = ..\..\..\..
+DEBUG = 0
+GSDL_VC4 = 0
+STLPATH = "$(GSDLHOME)\common-src\packages\windows\stlport\stlport"
+
+AR = lib
+CC = cl
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+LDFLAGS =
+DEFS = -D__WIN32__
+INCLUDES =
+!IF $(GSDL_VC4)
+DEFS = $(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS -D_CRT_SECURE_NO_DEPRECATE
+INCLUDES = $(INCLUDES) -I$(STLPATH)
+!ENDIF
+LIBS=
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) -nologo $(LDFLAGS)
+
+.SUFFIXES:
+.SUFFIXES: .c .obj
+.c.obj:
+	$(COMPILE) $<
+
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $< 
+
+HEADERS = suffix.h phrase.h
+SOURCES = suffix.cpp phrase.cpp
+OBJECTS = suffix.obj phrase.obj
+EXEC    = suffix.exe
+
+all: $(EXEC)
+
+install:
+	copy $(EXEC) "$(GSDLHOME)\bin\windows"
+
+clean:
+	del *.obj
+	del $(EXEC)
+
+suffix.exe: $(OBJECTS)
+	    $(LINK) $(OBJECTS) $(LIBS) 
Index: /gsdl/stable/build-src/win32.mak
===================================================================
--- /gsdl/stable/build-src/win32.mak	(revision 20131)
+++ /gsdl/stable/build-src/win32.mak	(revision 20131)
@@ -0,0 +1,78 @@
+###########################################################################
+#
+# win32 makefile -- gsdl
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDLHOME = $(GSDLHOME)
+BUILDHOME = $(MAKEDIR)
+
+GSDL_VC4 = 0
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+
+MDEFINES = /f win32.mak
+
+INSTALLDIRS = src\hashfile src\phind\generate
+
+
+MAKECMD = $(MAKE) $(MDEFINES) GSDLHOME="$(GSDLHOME)"
+
+!IF $(GSDL_VC4)
+MAKECMD = $(MAKECMD) GSDL_VC4=1
+!ENDIF
+!IF $(DEBUG)
+MAKECMD = $(MAKECMD) DEBUG=1
+!ENDIF
+!IF $(DLL)
+MAKECMD = $(MAKECMD) DLL=1
+!ENDIF
+!IF $(DLLDEBUG)
+MAKECMD = $(MAKECMD) DLLDEBUG=1
+!ENDIF
+
+MAKECLEANCMD = $(MAKE) $(MDEFINES) GSDLHOME="$(GSDLHOME)" clean
+
+all: win32.mak $(INSTALLDIRS) 
+
+install: win32.mak $(INSTALLDIRS)
+
+clean:
+	cd "$(BUILDHOME)"
+	cd src\phind\generate
+	$(MAKECLEANCMD)
+	cd "$(BUILDHOME)"
+	cd src\hashfile
+	$(MAKECLEANCMD)
+	cd "$(GSDLHOME)"
+
+$(INSTALLDIRS): FORCE
+	cd "$(BUILDHOME)"
+	cd "$@"
+	$(MAKECMD)
+	$(MAKECMD) install
+	cd "$(GSDLHOME)"
+
+FORCE:
+
Index: /gsdl/stable/cgi-bin/CGI.pm
===================================================================
--- /gsdl/stable/cgi-bin/CGI.pm	(revision 20131)
+++ /gsdl/stable/cgi-bin/CGI.pm	(revision 20131)
@@ -0,0 +1,6697 @@
+package CGI;
+require 5.004;
+use Carp 'croak';
+
+# See the bottom of this file for the POD documentation.  Search for the
+# string '=head'.
+
+# You can run this file through either pod2man or pod2html to produce pretty
+# documentation in manual or html file format (these utilities are part of the
+# Perl 5 distribution).
+
+# Copyright 1995-1998 Lincoln D. Stein.  All rights reserved.
+# It may be used and modified freely, but I do request that this copyright
+# notice remain attached to the file.  You may modify this module as you 
+# wish, but if you redistribute a modified version, please attach a note
+# listing the modifications you have made.
+
+# The most recent version and complete docs are available at:
+#   http://stein.cshl.org/WWW/software/CGI/
+
+$CGI::revision = '$Id$';
+$CGI::VERSION='2.81';
+
+# HARD-CODED LOCATION FOR FILE UPLOAD TEMPORARY FILES.
+# UNCOMMENT THIS ONLY IF YOU KNOW WHAT YOU'RE DOING.
+# $CGITempFile::TMPDIRECTORY = '/usr/tmp';
+use CGI::Util qw(rearrange make_attributes unescape escape expires);
+
+#use constant XHTML_DTD => ['-//W3C//DTD XHTML Basic 1.0//EN',
+#                           'http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd'];
+
+use constant XHTML_DTD => ['-//W3C//DTD XHTML 1.0 Transitional//EN',
+                           'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'];
+
+# >>>>> Here are some globals that you might want to adjust <<<<<<
+sub initialize_globals {
+    # Set this to 1 to enable copious autoloader debugging messages
+    $AUTOLOAD_DEBUG = 0;
+
+    # Set this to 1 to generate XTML-compatible output
+    $XHTML = 1;
+
+    # Change this to the preferred DTD to print in start_html()
+    # or use default_dtd('text of DTD to use');
+    $DEFAULT_DTD = [ '-//W3C//DTD HTML 4.01 Transitional//EN',
+		     'http://www.w3.org/TR/html4/loose.dtd' ] ;
+
+    # Set this to 1 to enable NOSTICKY scripts
+    # or: 
+    #    1) use CGI qw(-nosticky)
+    #    2) $CGI::nosticky(1)
+    $NOSTICKY = 0;
+
+    # Set this to 1 to enable NPH scripts
+    # or: 
+    #    1) use CGI qw(-nph)
+    #    2) CGI::nph(1)
+    #    3) print header(-nph=>1)
+    $NPH = 0;
+
+    # Set this to 1 to enable debugging from @ARGV
+    # Set to 2 to enable debugging from STDIN
+    $DEBUG = 1;
+
+    # Set this to 1 to make the temporary files created
+    # during file uploads safe from prying eyes
+    # or do...
+    #    1) use CGI qw(:private_tempfiles)
+    #    2) CGI::private_tempfiles(1);
+    $PRIVATE_TEMPFILES = 0;
+
+    # Set this to a positive value to limit the size of a POSTing
+    # to a certain number of bytes:
+    $POST_MAX = -1;
+
+    # Change this to 1 to disable uploads entirely:
+    $DISABLE_UPLOADS = 0;
+
+    # Automatically determined -- don't change
+    $EBCDIC = 0;
+
+    # Change this to 1 to suppress redundant HTTP headers
+    $HEADERS_ONCE = 0;
+
+    # separate the name=value pairs by semicolons rather than ampersands
+    $USE_PARAM_SEMICOLONS = 1;
+
+    # Do not include undefined params parsed from query string
+    # use CGI qw(-no_undef_params);
+    $NO_UNDEF_PARAMS = 0;
+
+    # Other globals that you shouldn't worry about.
+    undef $Q;
+    $BEEN_THERE = 0;
+    undef @QUERY_PARAM;
+    undef %EXPORT;
+    undef $QUERY_CHARSET;
+    undef %QUERY_FIELDNAMES;
+
+    # prevent complaints by mod_perl
+    1;
+}
+
+# ------------------ START OF THE LIBRARY ------------
+
+# make mod_perlhappy
+initialize_globals();
+
+# FIGURE OUT THE OS WE'RE RUNNING UNDER
+# Some systems support the $^O variable.  If not
+# available then require() the Config library
+unless ($OS) {
+    unless ($OS = $^O) {
+	require Config;
+	$OS = $Config::Config{'osname'};
+    }
+}
+if ($OS =~ /^MSWin/i) {
+  $OS = 'WINDOWS';
+} elsif ($OS =~ /^VMS/i) {
+  $OS = 'VMS';
+} elsif ($OS =~ /^dos/i) {
+  $OS = 'DOS';
+} elsif ($OS =~ /^MacOS/i) {
+    $OS = 'MACINTOSH';
+} elsif ($OS =~ /^os2/i) {
+    $OS = 'OS2';
+} elsif ($OS =~ /^epoc/i) {
+    $OS = 'EPOC';
+} else {
+    $OS = 'UNIX';
+}
+
+# Some OS logic.  Binary mode enabled on DOS, NT and VMS
+$needs_binmode = $OS=~/^(WINDOWS|DOS|OS2|MSWin)/;
+
+# This is the default class for the CGI object to use when all else fails.
+$DefaultClass = 'CGI' unless defined $CGI::DefaultClass;
+
+# This is where to look for autoloaded routines.
+$AutoloadClass = $DefaultClass unless defined $CGI::AutoloadClass;
+
+# The path separator is a slash, backslash or semicolon, depending
+# on the paltform.
+$SL = {
+       UNIX=>'/', OS2=>'\\', EPOC=>'/',
+       WINDOWS=>'\\', DOS=>'\\', MACINTOSH=>':', VMS=>'/'
+    }->{$OS};
+
+# This no longer seems to be necessary
+# Turn on NPH scripts by default when running under IIS server!
+# $NPH++ if defined($ENV{'SERVER_SOFTWARE'}) && $ENV{'SERVER_SOFTWARE'}=~/IIS/;
+$IIS++ if defined($ENV{'SERVER_SOFTWARE'}) && $ENV{'SERVER_SOFTWARE'}=~/IIS/;
+
+# Turn on special checking for Doug MacEachern's modperl
+if (exists $ENV{'GATEWAY_INTERFACE'} 
+    && 
+    ($MOD_PERL = $ENV{'GATEWAY_INTERFACE'} =~ /^CGI-Perl\//))
+{
+    $| = 1;
+    require Apache;
+}
+# Turn on special checking for ActiveState's PerlEx
+$PERLEX++ if defined($ENV{'GATEWAY_INTERFACE'}) && $ENV{'GATEWAY_INTERFACE'} =~ /^CGI-PerlEx/;
+
+# Define the CRLF sequence.  I can't use a simple "\r\n" because the meaning
+# of "\n" is different on different OS's (sometimes it generates CRLF, sometimes LF
+# and sometimes CR).  The most popular VMS web server
+# doesn't accept CRLF -- instead it wants a LR.  EBCDIC machines don't
+# use ASCII, so \015\012 means something different.  I find this all 
+# really annoying.
+$EBCDIC = "\t" ne "\011";
+if ($OS eq 'VMS') {
+  $CRLF = "\n";
+} elsif ($EBCDIC) {
+  $CRLF= "\r\n";
+} else {
+  $CRLF = "\015\012";
+}
+
+if ($needs_binmode) {
+    $CGI::DefaultClass->binmode(main::STDOUT);
+    $CGI::DefaultClass->binmode(main::STDIN);
+    $CGI::DefaultClass->binmode(main::STDERR);
+}
+
+%EXPORT_TAGS = (
+		':html2'=>['h1'..'h6',qw/p br hr ol ul li dl dt dd menu code var strong em
+			   tt u i b blockquote pre img a address cite samp dfn html head
+			   base body Link nextid title meta kbd start_html end_html
+			   input Select option comment charset escapeHTML/],
+		':html3'=>[qw/div table caption th td TR Tr sup Sub strike applet Param 
+			   embed basefont style span layer ilayer font frameset frame script small big/],
+                ':html4'=>[qw/abbr acronym bdo col colgroup del fieldset iframe
+                            ins label legend noframes noscript object optgroup Q 
+                            thead tbody tfoot/], 
+		':netscape'=>[qw/blink fontsize center/],
+		':form'=>[qw/textfield textarea filefield password_field hidden checkbox checkbox_group 
+			  submit reset defaults radio_group popup_menu button autoEscape
+			  scrolling_list image_button start_form end_form startform endform
+			  start_multipart_form end_multipart_form isindex tmpFileName uploadInfo URL_ENCODED MULTIPART/],
+		':cgi'=>[qw/param upload path_info path_translated url self_url script_name cookie Dump
+			 raw_cookie request_method query_string Accept user_agent remote_host content_type
+			 remote_addr referer server_name server_software server_port server_protocol
+			 virtual_host remote_ident auth_type http
+			 save_parameters restore_parameters param_fetch
+			 remote_user user_name header redirect import_names put 
+			 Delete Delete_all url_param cgi_error/],
+		':ssl' => [qw/https/],
+		':imagemap' => [qw/Area Map/],
+		':cgi-lib' => [qw/ReadParse PrintHeader HtmlTop HtmlBot SplitParam Vars/],
+		':html' => [qw/:html2 :html3 :html4 :netscape/],
+		':standard' => [qw/:html2 :html3 :html4 :form :cgi/],
+		':push' => [qw/multipart_init multipart_start multipart_end multipart_final/],
+		':all' => [qw/:html2 :html3 :netscape :form :cgi :internal :html4/]
+		);
+
+# to import symbols into caller
+sub import {
+    my $self = shift;
+
+# This causes modules to clash.  
+    undef %EXPORT_OK;
+    undef %EXPORT;
+
+    $self->_setup_symbols(@_);
+    my ($callpack, $callfile, $callline) = caller;
+
+    # To allow overriding, search through the packages
+    # Till we find one in which the correct subroutine is defined.
+    my @packages = ($self,@{"$self\:\:ISA"});
+    foreach $sym (keys %EXPORT) {
+	my $pck;
+	my $def = ${"$self\:\:AutoloadClass"} || $DefaultClass;
+	foreach $pck (@packages) {
+	    if (defined(&{"$pck\:\:$sym"})) {
+		$def = $pck;
+		last;
+	    }
+	}
+	*{"${callpack}::$sym"} = \&{"$def\:\:$sym"};
+    }
+}
+
+sub compile {
+    my $pack = shift;
+    $pack->_setup_symbols('-compile',@_);
+}
+
+sub expand_tags {
+    my($tag) = @_;
+    return ("start_$1","end_$1") if $tag=~/^(?:\*|start_|end_)(.+)/;
+    my(@r);
+    return ($tag) unless $EXPORT_TAGS{$tag};
+    foreach (@{$EXPORT_TAGS{$tag}}) {
+	push(@r,&expand_tags($_));
+    }
+    return @r;
+}
+
+#### Method: new
+# The new routine.  This will check the current environment
+# for an existing query string, and initialize itself, if so.
+####
+sub new {
+    my($class,$initializer) = @_;
+    my $self = {};
+
+    bless $self,ref $class || $class || $DefaultClass;
+    if ($MOD_PERL && defined Apache->request) {
+      Apache->request->register_cleanup(\&CGI::_reset_globals);
+      undef $NPH;
+    }
+    $self->_reset_globals if $PERLEX;
+    $self->init($initializer);
+    return $self;
+}
+
+# We provide a DESTROY method so that the autoloader
+# doesn't bother trying to find it.
+sub DESTROY { }
+
+#### Method: param
+# Returns the value(s)of a named parameter.
+# If invoked in a list context, returns the
+# entire list.  Otherwise returns the first
+# member of the list.
+# If name is not provided, return a list of all
+# the known parameters names available.
+# If more than one argument is provided, the
+# second and subsequent arguments are used to
+# set the value of the parameter.
+####
+sub param {
+    my($self,@p) = self_or_default(@_);
+    return $self->all_parameters unless @p;
+    my($name,$value,@other);
+
+    # For compatibility between old calling style and use_named_parameters() style, 
+    # we have to special case for a single parameter present.
+    if (@p > 1) {
+	($name,$value,@other) = rearrange([NAME,[DEFAULT,VALUE,VALUES]],@p);
+	my(@values);
+
+	if (substr($p[0],0,1) eq '-') {
+	    @values = defined($value) ? (ref($value) && ref($value) eq 'ARRAY' ? @{$value} : $value) : ();
+	} else {
+	    foreach ($value,@other) {
+		push(@values,$_) if defined($_);
+	    }
+	}
+	# If values is provided, then we set it.
+	if (@values) {
+	    $self->add_parameter($name);
+	    $self->{$name}=[@values];
+	}
+    } else {
+	$name = $p[0];
+    }
+
+    return unless defined($name) && $self->{$name};
+    return wantarray ? @{$self->{$name}} : $self->{$name}->[0];
+}
+
+sub self_or_default {
+    return @_ if defined($_[0]) && (!ref($_[0])) &&($_[0] eq 'CGI');
+    unless (defined($_[0]) && 
+	    (ref($_[0]) eq 'CGI' || UNIVERSAL::isa($_[0],'CGI')) # slightly optimized for common case
+	    ) {
+	$Q = $CGI::DefaultClass->new unless defined($Q);
+	unshift(@_,$Q);
+    }
+    return wantarray ? @_ : $Q;
+}
+
+sub self_or_CGI {
+    local $^W=0;                # prevent a warning
+    if (defined($_[0]) &&
+	(substr(ref($_[0]),0,3) eq 'CGI' 
+	 || UNIVERSAL::isa($_[0],'CGI'))) {
+	return @_;
+    } else {
+	return ($DefaultClass,@_);
+    }
+}
+
+########################################
+# THESE METHODS ARE MORE OR LESS PRIVATE
+# GO TO THE __DATA__ SECTION TO SEE MORE
+# PUBLIC METHODS
+########################################
+
+# Initialize the query object from the environment.
+# If a parameter list is found, this object will be set
+# to an associative array in which parameter names are keys
+# and the values are stored as lists
+# If a keyword list is found, this method creates a bogus
+# parameter list with the single parameter 'keywords'.
+
+sub init {
+    my($self,$initializer) = @_;
+    my($query_string,$meth,$content_length,$fh,@lines) = ('','','','');
+    local($/) = "\n";
+
+    # if we get called more than once, we want to initialize
+    # ourselves from the original query (which may be gone
+    # if it was read from STDIN originally.)
+    if (defined(@QUERY_PARAM) && !defined($initializer)) {
+	foreach (@QUERY_PARAM) {
+	    $self->param('-name'=>$_,'-value'=>$QUERY_PARAM{$_});
+	}
+	$self->charset($QUERY_CHARSET);
+	$self->{'.fieldnames'} = {%QUERY_FIELDNAMES};
+	return;
+    }
+
+    $meth=$ENV{'REQUEST_METHOD'} if defined($ENV{'REQUEST_METHOD'});
+    $content_length = defined($ENV{'CONTENT_LENGTH'}) ? $ENV{'CONTENT_LENGTH'} : 0;
+
+    $fh = to_filehandle($initializer) if $initializer;
+
+    # set charset to the safe ISO-8859-1
+    $self->charset('ISO-8859-1');
+
+  METHOD: {
+
+      # avoid unreasonably large postings
+      if (($POST_MAX > 0) && ($content_length > $POST_MAX)) {
+	  $self->cgi_error("413 Request entity too large");
+	  last METHOD;
+      }
+
+      # Process multipart postings, but only if the initializer is
+      # not defined.
+      if ($meth eq 'POST'
+	  && defined($ENV{'CONTENT_TYPE'})
+	  && $ENV{'CONTENT_TYPE'}=~m|^multipart/form-data|
+	  && !defined($initializer)
+	  ) {
+	  my($boundary) = $ENV{'CONTENT_TYPE'} =~ /boundary=\"?([^\";,]+)\"?/;
+	  $self->read_multipart($boundary,$content_length);
+	  last METHOD;
+      } 
+
+      # If initializer is defined, then read parameters
+      # from it.
+      if (defined($initializer)) {
+	  if (UNIVERSAL::isa($initializer,'CGI')) {
+	      $query_string = $initializer->query_string;
+	      last METHOD;
+	  }
+	  if (ref($initializer) && ref($initializer) eq 'HASH') {
+	      foreach (keys %$initializer) {
+		  $self->param('-name'=>$_,'-value'=>$initializer->{$_});
+	      }
+	      last METHOD;
+	  }
+	  
+	  if (defined($fh) && ($fh ne '')) {
+	      while (<$fh>) {
+		  chomp;
+		  last if /^=/;
+		  push(@lines,$_);
+	      }
+	      # massage back into standard format
+	      if ("@lines" =~ /=/) {
+		  $query_string=join("&",@lines);
+	      } else {
+		  $query_string=join("+",@lines);
+	      }
+	      last METHOD;
+	  }
+
+	  # last chance -- treat it as a string
+	  $initializer = $$initializer if ref($initializer) eq 'SCALAR';
+	  $query_string = $initializer;
+
+	  last METHOD;
+      }
+
+      # If method is GET or HEAD, fetch the query from
+      # the environment.
+      if ($meth=~/^(GET|HEAD)$/) {
+	  if ($MOD_PERL) {
+	      $query_string = Apache->request->args;
+	  } else {
+	      $query_string = $ENV{'QUERY_STRING'} if defined $ENV{'QUERY_STRING'};
+	      $query_string ||= $ENV{'REDIRECT_QUERY_STRING'} if defined $ENV{'REDIRECT_QUERY_STRING'};
+	  }
+	  last METHOD;
+      }
+
+      if ($meth eq 'POST') {
+	  $self->read_from_client(\*STDIN,\$query_string,$content_length,0)
+	      if $content_length > 0;
+	  # Some people want to have their cake and eat it too!
+	  # Uncomment this line to have the contents of the query string
+	  # APPENDED to the POST data.
+	  # $query_string .= (length($query_string) ? '&' : '') . $ENV{'QUERY_STRING'} if defined $ENV{'QUERY_STRING'};
+	  last METHOD;
+      }
+
+      # If $meth is not of GET, POST or HEAD, assume we're being debugged offline.
+      # Check the command line and then the standard input for data.
+      # We use the shellwords package in order to behave the way that
+      # UN*X programmers expect.
+      $query_string = read_from_cmdline() if $DEBUG;
+  }
+
+    # We now have the query string in hand.  We do slightly
+    # different things for keyword lists and parameter lists.
+    if (defined $query_string && length $query_string) {
+	if ($query_string =~ /[&=;]/) {
+	    $self->parse_params($query_string);
+	} else {
+	    $self->add_parameter('keywords');
+	    $self->{'keywords'} = [$self->parse_keywordlist($query_string)];
+	}
+    }
+
+    # Special case.  Erase everything if there is a field named
+    # .defaults.
+    if ($self->param('.defaults')) {
+	undef %{$self};
+    }
+
+    # Associative array containing our defined fieldnames
+    $self->{'.fieldnames'} = {};
+    foreach ($self->param('.cgifields')) {
+	$self->{'.fieldnames'}->{$_}++;
+    }
+    
+    # Clear out our default submission button flag if present
+    $self->delete('.submit');
+    $self->delete('.cgifields');
+
+    $self->save_request unless $initializer;
+}
+
+# FUNCTIONS TO OVERRIDE:
+# Turn a string into a filehandle
+sub to_filehandle {
+    my $thingy = shift;
+    return undef unless $thingy;
+    return $thingy if UNIVERSAL::isa($thingy,'GLOB');
+    return $thingy if UNIVERSAL::isa($thingy,'FileHandle');
+    if (!ref($thingy)) {
+	my $caller = 1;
+	while (my $package = caller($caller++)) {
+	    my($tmp) = $thingy=~/[\':]/ ? $thingy : "$package\:\:$thingy"; 
+	    return $tmp if defined(fileno($tmp));
+	}
+    }
+    return undef;
+}
+
+# send output to the browser
+sub put {
+    my($self,@p) = self_or_default(@_);
+    $self->print(@p);
+}
+
+# print to standard output (for overriding in mod_perl)
+sub print {
+    shift;
+    CORE::print(@_);
+}
+
+# get/set last cgi_error
+sub cgi_error {
+    my ($self,$err) = self_or_default(@_);
+    $self->{'.cgi_error'} = $err if defined $err;
+    return $self->{'.cgi_error'};
+}
+
+sub save_request {
+    my($self) = @_;
+    # We're going to play with the package globals now so that if we get called
+    # again, we initialize ourselves in exactly the same way.  This allows
+    # us to have several of these objects.
+    @QUERY_PARAM = $self->param; # save list of parameters
+    foreach (@QUERY_PARAM) {
+      next unless defined $_;
+      $QUERY_PARAM{$_}=$self->{$_};
+    }
+    $QUERY_CHARSET = $self->charset;
+    %QUERY_FIELDNAMES = %{$self->{'.fieldnames'}};
+}
+
+sub parse_params {
+    my($self,$tosplit) = @_;
+    my(@pairs) = split(/[&;]/,$tosplit);
+    my($param,$value);
+    foreach (@pairs) {
+	($param,$value) = split('=',$_,2);
+	next unless defined $param;
+	next if $NO_UNDEF_PARAMS and not defined $value;
+	$value = '' unless defined $value;
+	$param = unescape($param);
+	$value = unescape($value);
+	$self->add_parameter($param);
+	push (@{$self->{$param}},$value);
+    }
+}
+
+sub add_parameter {
+    my($self,$param)=@_;
+    return unless defined $param;
+    push (@{$self->{'.parameters'}},$param) 
+	unless defined($self->{$param});
+}
+
+sub all_parameters {
+    my $self = shift;
+    return () unless defined($self) && $self->{'.parameters'};
+    return () unless @{$self->{'.parameters'}};
+    return @{$self->{'.parameters'}};
+}
+
+# put a filehandle into binary mode (DOS)
+sub binmode {
+    CORE::binmode($_[1]);
+}
+
+sub _make_tag_func {
+    my ($self,$tagname) = @_;
+    my $func = qq(
+	sub $tagname {
+            shift if \$_[0] && 
+                    (ref(\$_[0]) &&
+                     (substr(ref(\$_[0]),0,3) eq 'CGI' ||
+                    UNIVERSAL::isa(\$_[0],'CGI')));
+	    my(\$attr) = '';
+	    if (ref(\$_[0]) && ref(\$_[0]) eq 'HASH') {
+		my(\@attr) = make_attributes(shift()||undef,1);
+		\$attr = " \@attr" if \@attr;
+	    }
+	);
+    if ($tagname=~/start_(\w+)/i) {
+	$func .= qq! return "<\L$1\E\$attr>";} !;
+    } elsif ($tagname=~/end_(\w+)/i) {
+	$func .= qq! return "<\L/$1\E>"; } !;
+    } else {
+	$func .= qq#
+	    return \$XHTML ? "\L<$tagname\E\$attr />" : "\L<$tagname\E\$attr>" unless \@_;
+	    my(\$tag,\$untag) = ("\L<$tagname\E\$attr>","\L</$tagname>\E");
+	    my \@result = map { "\$tag\$_\$untag" } 
+                              (ref(\$_[0]) eq 'ARRAY') ? \@{\$_[0]} : "\@_";
+	    return "\@result";
+            }#;
+    }
+return $func;
+}
+
+sub AUTOLOAD {
+    print STDERR "CGI::AUTOLOAD for $AUTOLOAD\n" if $CGI::AUTOLOAD_DEBUG;
+    my $func = &_compile;
+    goto &$func;
+}
+
+sub _compile {
+    my($func) = $AUTOLOAD;
+    my($pack,$func_name);
+    {
+	local($1,$2); # this fixes an obscure variable suicide problem.
+	$func=~/(.+)::([^:]+)$/;
+	($pack,$func_name) = ($1,$2);
+	$pack=~s/::SUPER$//;	# fix another obscure problem
+	$pack = ${"$pack\:\:AutoloadClass"} || $CGI::DefaultClass
+	    unless defined(${"$pack\:\:AUTOLOADED_ROUTINES"});
+
+        my($sub) = \%{"$pack\:\:SUBS"};
+        unless (%$sub) {
+	   my($auto) = \${"$pack\:\:AUTOLOADED_ROUTINES"};
+	   eval "package $pack; $$auto";
+	   croak("$AUTOLOAD: $@") if $@;
+           $$auto = '';  # Free the unneeded storage (but don't undef it!!!)
+       }
+       my($code) = $sub->{$func_name};
+
+       $code = "sub $AUTOLOAD { }" if (!$code and $func_name eq 'DESTROY');
+       if (!$code) {
+	   (my $base = $func_name) =~ s/^(start_|end_)//i;
+	   if ($EXPORT{':any'} || 
+	       $EXPORT{'-any'} ||
+	       $EXPORT{$base} || 
+	       (%EXPORT_OK || grep(++$EXPORT_OK{$_},&expand_tags(':html')))
+	           && $EXPORT_OK{$base}) {
+	       $code = $CGI::DefaultClass->_make_tag_func($func_name);
+	   }
+       }
+       croak("Undefined subroutine $AUTOLOAD\n") unless $code;
+       eval "package $pack; $code";
+       if ($@) {
+	   $@ =~ s/ at .*\n//;
+	   croak("$AUTOLOAD: $@");
+       }
+    }       
+    CORE::delete($sub->{$func_name});  #free storage
+    return "$pack\:\:$func_name";
+}
+
+sub _selected {
+  my $self = shift;
+  my $value = shift;
+  return '' unless $value;
+  return $XHTML ? qq( selected="selected") : qq( selected);
+}
+
+sub _checked {
+  my $self = shift;
+  my $value = shift;
+  return '' unless $value;
+  return $XHTML ? qq( checked="checked") : qq( checked);
+}
+
+sub _reset_globals { initialize_globals(); }
+
+sub _setup_symbols {
+    my $self = shift;
+    my $compile = 0;
+
+    # to avoid reexporting unwanted variables
+    undef %EXPORT;
+
+    foreach (@_) {
+	$HEADERS_ONCE++,         next if /^[:-]unique_headers$/;
+	$NPH++,                  next if /^[:-]nph$/;
+	$NOSTICKY++,             next if /^[:-]nosticky$/;
+	$DEBUG=0,                next if /^[:-]no_?[Dd]ebug$/;
+	$DEBUG=2,                next if /^[:-][Dd]ebug$/;
+	$USE_PARAM_SEMICOLONS++, next if /^[:-]newstyle_urls$/;
+	$XHTML++,                next if /^[:-]xhtml$/;
+	$XHTML=0,                next if /^[:-]no_?xhtml$/;
+	$USE_PARAM_SEMICOLONS=0, next if /^[:-]oldstyle_urls$/;
+	$PRIVATE_TEMPFILES++,    next if /^[:-]private_tempfiles$/;
+	$EXPORT{$_}++,           next if /^[:-]any$/;
+	$compile++,              next if /^[:-]compile$/;
+	$NO_UNDEF_PARAMS++,      next if /^[:-]no_undef_params$/;
+	
+	# This is probably extremely evil code -- to be deleted some day.
+	if (/^[-]autoload$/) {
+	    my($pkg) = caller(1);
+	    *{"${pkg}::AUTOLOAD"} = sub { 
+		my($routine) = $AUTOLOAD;
+		$routine =~ s/^.*::/CGI::/;
+		&$routine;
+	    };
+	    next;
+	}
+
+	foreach (&expand_tags($_)) {
+	    tr/a-zA-Z0-9_//cd;  # don't allow weird function names
+	    $EXPORT{$_}++;
+	}
+    }
+    _compile_all(keys %EXPORT) if $compile;
+}
+
+sub charset {
+  my ($self,$charset) = self_or_default(@_);
+  $self->{'.charset'} = $charset if defined $charset;
+  $self->{'.charset'};
+}
+
+###############################################################################
+################# THESE FUNCTIONS ARE AUTOLOADED ON DEMAND ####################
+###############################################################################
+$AUTOLOADED_ROUTINES = '';      # get rid of -w warning
+$AUTOLOADED_ROUTINES=<<'END_OF_AUTOLOAD';
+
+%SUBS = (
+
+'URL_ENCODED'=> <<'END_OF_FUNC',
+sub URL_ENCODED { 'application/x-www-form-urlencoded'; }
+END_OF_FUNC
+
+'MULTIPART' => <<'END_OF_FUNC',
+sub MULTIPART {  'multipart/form-data'; }
+END_OF_FUNC
+
+'SERVER_PUSH' => <<'END_OF_FUNC',
+sub SERVER_PUSH { 'multipart/x-mixed-replace;boundary="' . shift() . '"'; }
+END_OF_FUNC
+
+'new_MultipartBuffer' => <<'END_OF_FUNC',
+# Create a new multipart buffer
+sub new_MultipartBuffer {
+    my($self,$boundary,$length,$filehandle) = @_;
+    return MultipartBuffer->new($self,$boundary,$length,$filehandle);
+}
+END_OF_FUNC
+
+'read_from_client' => <<'END_OF_FUNC',
+# Read data from a file handle
+sub read_from_client {
+    my($self, $fh, $buff, $len, $offset) = @_;
+    local $^W=0;                # prevent a warning
+    return undef unless defined($fh);
+    return read($fh, $$buff, $len, $offset);
+}
+END_OF_FUNC
+
+'delete' => <<'END_OF_FUNC',
+#### Method: delete
+# Deletes the named parameter entirely.
+####
+sub delete {
+    my($self,@p) = self_or_default(@_);
+    my($name) = rearrange([NAME],@p);
+    CORE::delete $self->{$name};
+    CORE::delete $self->{'.fieldnames'}->{$name};
+    @{$self->{'.parameters'}}=grep($_ ne $name,$self->param());
+    return wantarray ? () : undef;
+}
+END_OF_FUNC
+
+#### Method: import_names
+# Import all parameters into the given namespace.
+# Assumes namespace 'Q' if not specified
+####
+'import_names' => <<'END_OF_FUNC',
+sub import_names {
+    my($self,$namespace,$delete) = self_or_default(@_);
+    $namespace = 'Q' unless defined($namespace);
+    die "Can't import names into \"main\"\n" if \%{"${namespace}::"} == \%::;
+    if ($delete || $MOD_PERL || exists $ENV{'FCGI_ROLE'}) {
+	# can anyone find an easier way to do this?
+	foreach (keys %{"${namespace}::"}) {
+	    local *symbol = "${namespace}::${_}";
+	    undef $symbol;
+	    undef @symbol;
+	    undef %symbol;
+	}
+    }
+    my($param,@value,$var);
+    foreach $param ($self->param) {
+	# protect against silly names
+	($var = $param)=~tr/a-zA-Z0-9_/_/c;
+	$var =~ s/^(?=\d)/_/;
+	local *symbol = "${namespace}::$var";
+	@value = $self->param($param);
+	@symbol = @value;
+	$symbol = $value[0];
+    }
+}
+END_OF_FUNC
+
+#### Method: keywords
+# Keywords acts a bit differently.  Calling it in a list context
+# returns the list of keywords.  
+# Calling it in a scalar context gives you the size of the list.
+####
+'keywords' => <<'END_OF_FUNC',
+sub keywords {
+    my($self,@values) = self_or_default(@_);
+    # If values is provided, then we set it.
+    $self->{'keywords'}=[@values] if @values;
+    my(@result) = defined($self->{'keywords'}) ? @{$self->{'keywords'}} : ();
+    @result;
+}
+END_OF_FUNC
+
+# These are some tie() interfaces for compatibility
+# with Steve Brenner's cgi-lib.pl routines
+'Vars' => <<'END_OF_FUNC',
+sub Vars {
+    my $q = shift;
+    my %in;
+    tie(%in,CGI,$q);
+    return %in if wantarray;
+    return \%in;
+}
+END_OF_FUNC
+
+# These are some tie() interfaces for compatibility
+# with Steve Brenner's cgi-lib.pl routines
+'ReadParse' => <<'END_OF_FUNC',
+sub ReadParse {
+    local(*in);
+    if (@_) {
+	*in = $_[0];
+    } else {
+	my $pkg = caller();
+	*in=*{"${pkg}::in"};
+    }
+    tie(%in,CGI);
+    return scalar(keys %in);
+}
+END_OF_FUNC
+
+'PrintHeader' => <<'END_OF_FUNC',
+sub PrintHeader {
+    my($self) = self_or_default(@_);
+    return $self->header();
+}
+END_OF_FUNC
+
+'HtmlTop' => <<'END_OF_FUNC',
+sub HtmlTop {
+    my($self,@p) = self_or_default(@_);
+    return $self->start_html(@p);
+}
+END_OF_FUNC
+
+'HtmlBot' => <<'END_OF_FUNC',
+sub HtmlBot {
+    my($self,@p) = self_or_default(@_);
+    return $self->end_html(@p);
+}
+END_OF_FUNC
+
+'SplitParam' => <<'END_OF_FUNC',
+sub SplitParam {
+    my ($param) = @_;
+    my (@params) = split ("\0", $param);
+    return (wantarray ? @params : $params[0]);
+}
+END_OF_FUNC
+
+'MethGet' => <<'END_OF_FUNC',
+sub MethGet {
+    return request_method() eq 'GET';
+}
+END_OF_FUNC
+
+'MethPost' => <<'END_OF_FUNC',
+sub MethPost {
+    return request_method() eq 'POST';
+}
+END_OF_FUNC
+
+'TIEHASH' => <<'END_OF_FUNC',
+sub TIEHASH { 
+    return $_[1] if defined $_[1];
+    return $Q ||= new shift;
+}
+END_OF_FUNC
+
+'STORE' => <<'END_OF_FUNC',
+sub STORE {
+    my $self = shift;
+    my $tag  = shift;
+    my $vals = shift;
+    my @vals = index($vals,"\0")!=-1 ? split("\0",$vals) : $vals;
+    $self->param(-name=>$tag,-value=>\@vals);
+}
+END_OF_FUNC
+
+'FETCH' => <<'END_OF_FUNC',
+sub FETCH {
+    return $_[0] if $_[1] eq 'CGI';
+    return undef unless defined $_[0]->param($_[1]);
+    return join("\0",$_[0]->param($_[1]));
+}
+END_OF_FUNC
+
+'FIRSTKEY' => <<'END_OF_FUNC',
+sub FIRSTKEY {
+    $_[0]->{'.iterator'}=0;
+    $_[0]->{'.parameters'}->[$_[0]->{'.iterator'}++];
+}
+END_OF_FUNC
+
+'NEXTKEY' => <<'END_OF_FUNC',
+sub NEXTKEY {
+    $_[0]->{'.parameters'}->[$_[0]->{'.iterator'}++];
+}
+END_OF_FUNC
+
+'EXISTS' => <<'END_OF_FUNC',
+sub EXISTS {
+    exists $_[0]->{$_[1]};
+}
+END_OF_FUNC
+
+'DELETE' => <<'END_OF_FUNC',
+sub DELETE {
+    $_[0]->delete($_[1]);
+}
+END_OF_FUNC
+
+'CLEAR' => <<'END_OF_FUNC',
+sub CLEAR {
+    %{$_[0]}=();
+}
+####
+END_OF_FUNC
+
+####
+# Append a new value to an existing query
+####
+'append' => <<'EOF',
+sub append {
+    my($self,@p) = @_;
+    my($name,$value) = rearrange([NAME,[VALUE,VALUES]],@p);
+    my(@values) = defined($value) ? (ref($value) ? @{$value} : $value) : ();
+    if (@values) {
+	$self->add_parameter($name);
+	push(@{$self->{$name}},@values);
+    }
+    return $self->param($name);
+}
+EOF
+
+#### Method: delete_all
+# Delete all parameters
+####
+'delete_all' => <<'EOF',
+sub delete_all {
+    my($self) = self_or_default(@_);
+    undef %{$self};
+}
+EOF
+
+'Delete' => <<'EOF',
+sub Delete {
+    my($self,@p) = self_or_default(@_);
+    $self->delete(@p);
+}
+EOF
+
+'Delete_all' => <<'EOF',
+sub Delete_all {
+    my($self,@p) = self_or_default(@_);
+    $self->delete_all(@p);
+}
+EOF
+
+#### Method: autoescape
+# If you want to turn off the autoescaping features,
+# call this method with undef as the argument
+'autoEscape' => <<'END_OF_FUNC',
+sub autoEscape {
+    my($self,$escape) = self_or_default(@_);
+    $self->{'dontescape'}=!$escape;
+}
+END_OF_FUNC
+
+
+#### Method: version
+# Return the current version
+####
+'version' => <<'END_OF_FUNC',
+sub version {
+    return $VERSION;
+}
+END_OF_FUNC
+
+#### Method: url_param
+# Return a parameter in the QUERY_STRING, regardless of
+# whether this was a POST or a GET
+####
+'url_param' => <<'END_OF_FUNC',
+sub url_param {
+    my ($self,@p) = self_or_default(@_);
+    my $name = shift(@p);
+    return undef unless exists($ENV{QUERY_STRING});
+    unless (exists($self->{'.url_param'})) {
+	$self->{'.url_param'}={}; # empty hash
+	if ($ENV{QUERY_STRING} =~ /=/) {
+	    my(@pairs) = split(/[&;]/,$ENV{QUERY_STRING});
+	    my($param,$value);
+	    foreach (@pairs) {
+		($param,$value) = split('=',$_,2);
+		$param = unescape($param);
+		$value = unescape($value);
+		push(@{$self->{'.url_param'}->{$param}},$value);
+	    }
+	} else {
+	    $self->{'.url_param'}->{'keywords'} = [$self->parse_keywordlist($ENV{QUERY_STRING})];
+	}
+    }
+    return keys %{$self->{'.url_param'}} unless defined($name);
+    return () unless $self->{'.url_param'}->{$name};
+    return wantarray ? @{$self->{'.url_param'}->{$name}}
+                     : $self->{'.url_param'}->{$name}->[0];
+}
+END_OF_FUNC
+
+#### Method: Dump
+# Returns a string in which all the known parameter/value 
+# pairs are represented as nested lists, mainly for the purposes 
+# of debugging.
+####
+'Dump' => <<'END_OF_FUNC',
+sub Dump {
+    my($self) = self_or_default(@_);
+    my($param,$value,@result);
+    return '<ul></ul>' unless $self->param;
+    push(@result,"<ul>");
+    foreach $param ($self->param) {
+	my($name)=$self->escapeHTML($param);
+	push(@result,"<li><strong>$param</strong>");
+	push(@result,"<ul>");
+	foreach $value ($self->param($param)) {
+	    $value = $self->escapeHTML($value);
+            $value =~ s/\n/<br>\n/g;
+	    push(@result,"<li>$value");
+	}
+	push(@result,"</ul>");
+    }
+    push(@result,"</ul>");
+    return join("\n",@result);
+}
+END_OF_FUNC
+
+#### Method as_string
+#
+# synonym for "dump"
+####
+'as_string' => <<'END_OF_FUNC',
+sub as_string {
+    &Dump(@_);
+}
+END_OF_FUNC
+
+#### Method: save
+# Write values out to a filehandle in such a way that they can
+# be reinitialized by the filehandle form of the new() method
+####
+'save' => <<'END_OF_FUNC',
+sub save {
+    my($self,$filehandle) = self_or_default(@_);
+    $filehandle = to_filehandle($filehandle);
+    my($param);
+    local($,) = '';  # set print field separator back to a sane value
+    local($\) = '';  # set output line separator to a sane value
+    foreach $param ($self->param) {
+	my($escaped_param) = escape($param);
+	my($value);
+	foreach $value ($self->param($param)) {
+	    print $filehandle "$escaped_param=",escape("$value"),"\n";
+	}
+    }
+    foreach (keys %{$self->{'.fieldnames'}}) {
+          print $filehandle ".cgifields=",escape("$_"),"\n";
+    }
+    print $filehandle "=\n";    # end of record
+}
+END_OF_FUNC
+
+
+#### Method: save_parameters
+# An alias for save() that is a better name for exportation.
+# Only intended to be used with the function (non-OO) interface.
+####
+'save_parameters' => <<'END_OF_FUNC',
+sub save_parameters {
+    my $fh = shift;
+    return save(to_filehandle($fh));
+}
+END_OF_FUNC
+
+#### Method: restore_parameters
+# A way to restore CGI parameters from an initializer.
+# Only intended to be used with the function (non-OO) interface.
+####
+'restore_parameters' => <<'END_OF_FUNC',
+sub restore_parameters {
+    $Q = $CGI::DefaultClass->new(@_);
+}
+END_OF_FUNC
+
+#### Method: multipart_init
+# Return a Content-Type: style header for server-push
+# This has to be NPH on most web servers, and it is advisable to set $| = 1
+#
+# Many thanks to Ed Jordan <ed@fidalgo.net> for this
+# contribution, updated by Andrew Benham (adsb@bigfoot.com)
+####
+'multipart_init' => <<'END_OF_FUNC',
+sub multipart_init {
+    my($self,@p) = self_or_default(@_);
+    my($boundary,@other) = rearrange([BOUNDARY],@p);
+    $boundary = $boundary || '------- =_aaaaaaaaaa0';
+    $self->{'separator'} = "$CRLF--$boundary$CRLF";
+    $self->{'final_separator'} = "$CRLF--$boundary--$CRLF";
+    $type = SERVER_PUSH($boundary);
+    return $self->header(
+	-nph => 1,
+	-type => $type,
+	(map { split "=", $_, 2 } @other),
+    ) . "WARNING: YOUR BROWSER DOESN'T SUPPORT THIS SERVER-PUSH TECHNOLOGY." . $self->multipart_end;
+}
+END_OF_FUNC
+
+
+#### Method: multipart_start
+# Return a Content-Type: style header for server-push, start of section
+#
+# Many thanks to Ed Jordan <ed@fidalgo.net> for this
+# contribution, updated by Andrew Benham (adsb@bigfoot.com)
+####
+'multipart_start' => <<'END_OF_FUNC',
+sub multipart_start {
+    my(@header);
+    my($self,@p) = self_or_default(@_);
+    my($type,@other) = rearrange([TYPE],@p);
+    $type = $type || 'text/html';
+    push(@header,"Content-Type: $type");
+
+    # rearrange() was designed for the HTML portion, so we
+    # need to fix it up a little.
+    foreach (@other) {
+        next unless my($header,$value) = /([^\s=]+)=\"?(.+?)\"?$/;
+	($_ = $header) =~ s/^(\w)(.*)/$1 . lc ($2) . ': '.$self->unescapeHTML($value)/e;
+    }
+    push(@header,@other);
+    my $header = join($CRLF,@header)."${CRLF}${CRLF}";
+    return $header;
+}
+END_OF_FUNC
+
+
+#### Method: multipart_end
+# Return a MIME boundary separator for server-push, end of section
+#
+# Many thanks to Ed Jordan <ed@fidalgo.net> for this
+# contribution
+####
+'multipart_end' => <<'END_OF_FUNC',
+sub multipart_end {
+    my($self,@p) = self_or_default(@_);
+    return $self->{'separator'};
+}
+END_OF_FUNC
+
+
+#### Method: multipart_final
+# Return a MIME boundary separator for server-push, end of all sections
+#
+# Contributed by Andrew Benham (adsb@bigfoot.com)
+####
+'multipart_final' => <<'END_OF_FUNC',
+sub multipart_final {
+    my($self,@p) = self_or_default(@_);
+    return $self->{'final_separator'} . "WARNING: YOUR BROWSER DOESN'T SUPPORT THIS SERVER-PUSH TECHNOLOGY." . $CRLF;
+}
+END_OF_FUNC
+
+
+#### Method: header
+# Return a Content-Type: style header
+#
+####
+'header' => <<'END_OF_FUNC',
+sub header {
+    my($self,@p) = self_or_default(@_);
+    my(@header);
+
+    return undef if $self->{'.header_printed'}++ and $HEADERS_ONCE;
+
+    my($type,$status,$cookie,$target,$expires,$nph,$charset,$attachment,@other) = 
+	rearrange([['TYPE','CONTENT_TYPE','CONTENT-TYPE'],
+			    'STATUS',['COOKIE','COOKIES'],'TARGET',
+                            'EXPIRES','NPH','CHARSET',
+                            'ATTACHMENT'],@p);
+
+    $nph     ||= $NPH;
+    if (defined $charset) {
+      $self->charset($charset);
+    } else {
+      $charset = $self->charset;
+    }
+
+    # rearrange() was designed for the HTML portion, so we
+    # need to fix it up a little.
+    foreach (@other) {
+        next unless my($header,$value) = /([^\s=]+)=\"?(.+?)\"?$/;
+	($_ = $header) =~ s/^(\w)(.*)/$1 . lc ($2) . ': '.$self->unescapeHTML($value)/e;
+        $header = ucfirst($header);
+    }
+
+    $type ||= 'text/html' unless defined($type);
+    $type .= "; charset=$charset" if $type ne '' and $type =~ m!^text/! and $type !~ /\bcharset\b/;
+
+    # Maybe future compatibility.  Maybe not.
+    my $protocol = $ENV{SERVER_PROTOCOL} || 'HTTP/1.0';
+    push(@header,$protocol . ' ' . ($status || '200 OK')) if $nph;
+    push(@header,"Server: " . &server_software()) if $nph;
+
+    push(@header,"Status: $status") if $status;
+    push(@header,"Window-Target: $target") if $target;
+    # push all the cookies -- there may be several
+    if ($cookie) {
+	my(@cookie) = ref($cookie) && ref($cookie) eq 'ARRAY' ? @{$cookie} : $cookie;
+	foreach (@cookie) {
+            my $cs = UNIVERSAL::isa($_,'CGI::Cookie') ? $_->as_string : $_;
+	    push(@header,"Set-Cookie: $cs") if $cs ne '';
+	}
+    }
+    # if the user indicates an expiration time, then we need
+    # both an Expires and a Date header (so that the browser is
+    # uses OUR clock)
+    push(@header,"Expires: " . expires($expires,'http'))
+	if $expires;
+    push(@header,"Date: " . expires(0,'http')) if $expires || $cookie || $nph;
+    push(@header,"Pragma: no-cache") if $self->cache();
+    push(@header,"Content-Disposition: attachment; filename=\"$attachment\"") if $attachment;
+    push(@header,map {ucfirst $_} @other);
+    push(@header,"Content-Type: $type") if $type ne '';
+
+    my $header = join($CRLF,@header)."${CRLF}${CRLF}";
+    if ($MOD_PERL and not $nph) {
+	my $r = Apache->request;
+	$r->send_cgi_header($header);
+	return '';
+    }
+    return $header;
+}
+END_OF_FUNC
+
+
+#### Method: cache
+# Control whether header() will produce the no-cache
+# Pragma directive.
+####
+'cache' => <<'END_OF_FUNC',
+sub cache {
+    my($self,$new_value) = self_or_default(@_);
+    $new_value = '' unless $new_value;
+    if ($new_value ne '') {
+	$self->{'cache'} = $new_value;
+    }
+    return $self->{'cache'};
+}
+END_OF_FUNC
+
+
+#### Method: redirect
+# Return a Location: style header
+#
+####
+'redirect' => <<'END_OF_FUNC',
+sub redirect {
+    my($self,@p) = self_or_default(@_);
+    my($url,$target,$cookie,$nph,@other) = rearrange([[LOCATION,URI,URL],TARGET,COOKIE,NPH],@p);
+    $url ||= $self->self_url;
+    my(@o);
+    foreach (@other) { tr/\"//d; push(@o,split("=",$_,2)); }
+    unshift(@o,
+	 '-Status'=>'302 Moved',
+	 '-Location'=>$url,
+	 '-nph'=>$nph);
+    unshift(@o,'-Target'=>$target) if $target;
+    unshift(@o,'-Cookie'=>$cookie) if $cookie;
+    unshift(@o,'-Type'=>'');
+    return $self->header(@o);
+}
+END_OF_FUNC
+
+
+#### Method: start_html
+# Canned HTML header
+#
+# Parameters:
+# $title -> (optional) The title for this HTML document (-title)
+# $author -> (optional) e-mail address of the author (-author)
+# $base -> (optional) if set to true, will enter the BASE address of this document
+#          for resolving relative references (-base) 
+# $xbase -> (optional) alternative base at some remote location (-xbase)
+# $target -> (optional) target window to load all links into (-target)
+# $script -> (option) Javascript code (-script)
+# $no_script -> (option) Javascript <noscript> tag (-noscript)
+# $meta -> (optional) Meta information tags
+# $head -> (optional) any other elements you'd like to incorporate into the <head> tag
+#           (a scalar or array ref)
+# $style -> (optional) reference to an external style sheet
+# @other -> (optional) any other named parameters you'd like to incorporate into
+#           the <body> tag.
+####
+'start_html' => <<'END_OF_FUNC',
+sub start_html {
+    my($self,@p) = &self_or_default(@_);
+    my($title,$author,$base,$xbase,$script,$noscript,
+        $target,$meta,$head,$style,$dtd,$lang,$encoding,@other) = 
+	rearrange([TITLE,AUTHOR,BASE,XBASE,SCRIPT,NOSCRIPT,TARGET,META,HEAD,STYLE,DTD,LANG,ENCODING],@p);
+
+    $encoding = 'iso-8859-1' unless defined $encoding;
+
+    # strangely enough, the title needs to be escaped as HTML
+    # while the author needs to be escaped as a URL
+    $title = $self->escapeHTML($title || 'Untitled Document');
+    $author = $self->escape($author);
+    $lang ||= 'en-US';
+    my(@result,$xml_dtd);
+    if ($dtd) {
+        if (defined(ref($dtd)) and (ref($dtd) eq 'ARRAY')) {
+            $dtd = $DEFAULT_DTD unless $dtd->[0] =~ m|^-//|;
+        } else {
+            $dtd = $DEFAULT_DTD unless $dtd =~ m|^-//|;
+        }
+    } else {
+        $dtd = $XHTML ? XHTML_DTD : $DEFAULT_DTD;
+    }
+
+    $xml_dtd++ if ref($dtd) eq 'ARRAY' && $dtd->[0] =~ /\bXHTML\b/i;
+    $xml_dtd++ if ref($dtd) eq '' && $dtd =~ /\bXHTML\b/i;
+    push @result,qq(<?xml version="1.0" encoding="$encoding"?>) if $xml_dtd; 
+
+    if (ref($dtd) && ref($dtd) eq 'ARRAY') {
+        push(@result,qq(<!DOCTYPE html\n\tPUBLIC "$dtd->[0]"\n\t "$dtd->[1]">));
+    } else {
+        push(@result,qq(<!DOCTYPE html\n\tPUBLIC "$dtd">));
+    }
+    push(@result,$XHTML ? qq(<html xmlns="http://www.w3.org/1999/xhtml" lang="$lang"><head><title>$title</title>)
+                        : qq(<html lang="$lang"><head><title>$title</title>));
+	if (defined $author) {
+    push(@result,$XHTML ? "<link rev=\"made\" href=\"mailto:$author\" />"
+								: "<link rev=\"made\" href=\"mailto:$author\">");
+	}
+
+    if ($base || $xbase || $target) {
+	my $href = $xbase || $self->url('-path'=>1);
+	my $t = $target ? qq/ target="$target"/ : '';
+	push(@result,$XHTML ? qq(<base href="$href"$t />) : qq(<base href="$href"$t>));
+    }
+
+    if ($meta && ref($meta) && (ref($meta) eq 'HASH')) {
+	foreach (keys %$meta) { push(@result,$XHTML ? qq(<meta name="$_" content="$meta->{$_}" />) 
+			: qq(<meta name="$_" content="$meta->{$_}">)); }
+    }
+
+    push(@result,ref($head) ? @$head : $head) if $head;
+
+    # handle the infrequently-used -style and -script parameters
+    push(@result,$self->_style($style)) if defined $style;
+    push(@result,$self->_script($script)) if defined $script;
+
+    # handle -noscript parameter
+    push(@result,<<END) if $noscript;
+<noscript>
+$noscript
+</noscript>
+END
+    ;
+    my($other) = @other ? " @other" : '';
+    push(@result,"</head><body$other>");
+    return join("\n",@result);
+}
+END_OF_FUNC
+
+### Method: _style
+# internal method for generating a CSS style section
+####
+'_style' => <<'END_OF_FUNC',
+sub _style {
+    my ($self,$style) = @_;
+    my (@result);
+    my $type = 'text/css';
+
+    my $cdata_start = $XHTML ? "\n<!--/* <![CDATA[ */" : "\n<!-- ";
+    my $cdata_end   = $XHTML ? "\n/* ]]> */-->\n" : " -->\n";
+
+    if (ref($style)) {
+     my($src,$code,$stype,@other) =
+         rearrange([SRC,CODE,TYPE],
+                    '-foo'=>'bar', # a trick to allow the '-' to be omitted
+                    ref($style) eq 'ARRAY' ? @$style : %$style);
+     $type = $stype if $stype;
+     if (ref($src) eq "ARRAY") # Check to see if the $src variable is an array reference
+     { # If it is, push a LINK tag for each one.
+       foreach $src (@$src)
+       {
+         push(@result,$XHTML ? qq(<link rel="stylesheet" type="$type" href="$src" />)
+                             : qq(<link rel="stylesheet" type="$type" href="$src">)) if $src;
+       }
+     }
+     else
+     { # Otherwise, push the single -src, if it exists.
+       push(@result,$XHTML ? qq(<link rel="stylesheet" type="$type" href="$src" />)
+                           : qq(<link rel="stylesheet" type="$type" href="$src">)
+            ) if $src;
+      }
+     push(@result,style({'type'=>$type},"$cdata_start\n$code\n$cdata_end")) if $code;
+    } else {
+     push(@result,style({'type'=>$type},"$cdata_start\n$style\n$cdata_end"));
+    }
+    @result;
+}
+END_OF_FUNC
+
+'_script' => <<'END_OF_FUNC',
+sub _script {
+    my ($self,$script) = @_;
+    my (@result);
+
+    my (@scripts) = ref($script) eq 'ARRAY' ? @$script : ($script);
+    foreach $script (@scripts) {
+	my($src,$code,$language);
+	if (ref($script)) { # script is a hash
+	    ($src,$code,$language, $type) =
+		rearrange([SRC,CODE,LANGUAGE,TYPE],
+				 '-foo'=>'bar',	# a trick to allow the '-' to be omitted
+				 ref($script) eq 'ARRAY' ? @$script : %$script);
+            # User may not have specified language
+            $language ||= 'JavaScript';
+            unless (defined $type) {
+                $type = lc $language;
+                # strip '1.2' from 'javascript1.2'
+                $type =~ s/^(\D+).*$/text\/$1/;
+            }
+	} else {
+	    ($src,$code,$language, $type) = ('',$script,'JavaScript', 'text/javascript');
+	}
+
+    my $comment = '//';  # javascript by default
+    $comment = '#' if $type=~/perl|tcl/i;
+    $comment = "'" if $type=~/vbscript/i;
+
+    my $cdata_start  =  "\n<!-- Hide script\n";
+    $cdata_start    .= "$comment<![CDATA[\n"  if $XHTML; 
+    my $cdata_end    = $XHTML ? "\n$comment]]>" : $comment;
+    $cdata_end      .= " End script hiding -->\n";
+
+	my(@satts);
+	push(@satts,'src'=>$src) if $src;
+	push(@satts,'language'=>$language);
+        push(@satts,'type'=>$type);
+	$code = "$cdata_start$code$cdata_end" if defined $code;
+	push(@result,script({@satts},$code || ''));
+    }
+    @result;
+}
+END_OF_FUNC
+
+#### Method: end_html
+# End an HTML document.
+# Trivial method for completeness.  Just returns "</body>"
+####
+'end_html' => <<'END_OF_FUNC',
+sub end_html {
+    return "</body></html>";
+}
+END_OF_FUNC
+
+
+################################
+# METHODS USED IN BUILDING FORMS
+################################
+
+#### Method: isindex
+# Just prints out the isindex tag.
+# Parameters:
+#  $action -> optional URL of script to run
+# Returns:
+#   A string containing a <ISINDEX> tag
+'isindex' => <<'END_OF_FUNC',
+sub isindex {
+    my($self,@p) = self_or_default(@_);
+    my($action,@other) = rearrange([ACTION],@p);
+    $action = qq/action="$action"/ if $action;
+    my($other) = @other ? " @other" : '';
+    return $XHTML ? "<isindex $action$other />" : "<isindex $action$other>";
+}
+END_OF_FUNC
+
+
+#### Method: startform
+# Start a form
+# Parameters:
+#   $method -> optional submission method to use (GET or POST)
+#   $action -> optional URL of script to run
+#   $enctype ->encoding to use (URL_ENCODED or MULTIPART)
+'startform' => <<'END_OF_FUNC',
+sub startform {
+    my($self,@p) = self_or_default(@_);
+
+    my($method,$action,$enctype,@other) = 
+	rearrange([METHOD,ACTION,ENCTYPE],@p);
+
+    $method = lc($method) || 'post';
+    $enctype = $enctype || &URL_ENCODED;
+    unless (defined $action) {
+       $action = $self->url(-absolute=>1,-path=>1);
+       $action .= "?$ENV{QUERY_STRING}" if $ENV{QUERY_STRING};
+    }
+    $action = qq(action="$action");
+    my($other) = @other ? " @other" : '';
+    $self->{'.parametersToAdd'}={};
+    return qq/<form method="$method" $action enctype="$enctype"$other>\n/;
+}
+END_OF_FUNC
+
+
+#### Method: start_form
+# synonym for startform
+'start_form' => <<'END_OF_FUNC',
+sub start_form {
+    &startform;
+}
+END_OF_FUNC
+
+'end_multipart_form' => <<'END_OF_FUNC',
+sub end_multipart_form {
+    &endform;
+}
+END_OF_FUNC
+
+#### Method: start_multipart_form
+# synonym for startform
+'start_multipart_form' => <<'END_OF_FUNC',
+sub start_multipart_form {
+    my($self,@p) = self_or_default(@_);
+    if (defined($param[0]) && substr($param[0],0,1) eq '-') {
+	my(%p) = @p;
+	$p{'-enctype'}=&MULTIPART;
+	return $self->startform(%p);
+    } else {
+	my($method,$action,@other) = 
+	    rearrange([METHOD,ACTION],@p);
+	return $self->startform($method,$action,&MULTIPART,@other);
+    }
+}
+END_OF_FUNC
+
+
+#### Method: endform
+# End a form
+'endform' => <<'END_OF_FUNC',
+sub endform {
+    my($self,@p) = self_or_default(@_);    
+    if ( $NOSTICKY ) {
+    return wantarray ? ("</form>") : "\n</form>";
+    } else {
+    return wantarray ? ($self->get_fields,"</form>") : 
+                        $self->get_fields ."\n</form>";
+    }
+}
+END_OF_FUNC
+
+
+#### Method: end_form
+# synonym for endform
+'end_form' => <<'END_OF_FUNC',
+sub end_form {
+    &endform;
+}
+END_OF_FUNC
+
+
+'_textfield' => <<'END_OF_FUNC',
+sub _textfield {
+    my($self,$tag,@p) = self_or_default(@_);
+    my($name,$default,$size,$maxlength,$override,@other) = 
+	rearrange([NAME,[DEFAULT,VALUE],SIZE,MAXLENGTH,[OVERRIDE,FORCE]],@p);
+
+    my $current = $override ? $default : 
+	(defined($self->param($name)) ? $self->param($name) : $default);
+
+    $current = defined($current) ? $self->escapeHTML($current,1) : '';
+    $name = defined($name) ? $self->escapeHTML($name) : '';
+    my($s) = defined($size) ? qq/ size="$size"/ : '';
+    my($m) = defined($maxlength) ? qq/ maxlength="$maxlength"/ : '';
+    my($other) = @other ? " @other" : '';
+    # this entered at cristy's request to fix problems with file upload fields
+    # and WebTV -- not sure it won't break stuff
+    my($value) = $current ne '' ? qq(value="$current") : '';
+    return $XHTML ? qq(<input type="$tag" name="$name" $value$s$m$other />) 
+                  : qq(<input type="$tag" name="$name" $value$s$m$other>);
+}
+END_OF_FUNC
+
+#### Method: textfield
+# Parameters:
+#   $name -> Name of the text field
+#   $default -> Optional default value of the field if not
+#                already defined.
+#   $size ->  Optional width of field in characaters.
+#   $maxlength -> Optional maximum number of characters.
+# Returns:
+#   A string containing a <INPUT TYPE="text"> field
+#
+'textfield' => <<'END_OF_FUNC',
+sub textfield {
+    my($self,@p) = self_or_default(@_);
+    $self->_textfield('text',@p);
+}
+END_OF_FUNC
+
+
+#### Method: filefield
+# Parameters:
+#   $name -> Name of the file upload field
+#   $size ->  Optional width of field in characaters.
+#   $maxlength -> Optional maximum number of characters.
+# Returns:
+#   A string containing a <INPUT TYPE="text"> field
+#
+'filefield' => <<'END_OF_FUNC',
+sub filefield {
+    my($self,@p) = self_or_default(@_);
+    $self->_textfield('file',@p);
+}
+END_OF_FUNC
+
+
+#### Method: password
+# Create a "secret password" entry field
+# Parameters:
+#   $name -> Name of the field
+#   $default -> Optional default value of the field if not
+#                already defined.
+#   $size ->  Optional width of field in characters.
+#   $maxlength -> Optional maximum characters that can be entered.
+# Returns:
+#   A string containing a <INPUT TYPE="password"> field
+#
+'password_field' => <<'END_OF_FUNC',
+sub password_field {
+    my ($self,@p) = self_or_default(@_);
+    $self->_textfield('password',@p);
+}
+END_OF_FUNC
+
+#### Method: textarea
+# Parameters:
+#   $name -> Name of the text field
+#   $default -> Optional default value of the field if not
+#                already defined.
+#   $rows ->  Optional number of rows in text area
+#   $columns -> Optional number of columns in text area
+# Returns:
+#   A string containing a <textarea></textarea> tag
+#
+'textarea' => <<'END_OF_FUNC',
+sub textarea {
+    my($self,@p) = self_or_default(@_);
+    
+    my($name,$default,$rows,$cols,$override,@other) =
+	rearrange([NAME,[DEFAULT,VALUE],ROWS,[COLS,COLUMNS],[OVERRIDE,FORCE]],@p);
+
+    my($current)= $override ? $default :
+	(defined($self->param($name)) ? $self->param($name) : $default);
+
+    $name = defined($name) ? $self->escapeHTML($name) : '';
+    $current = defined($current) ? $self->escapeHTML($current) : '';
+    my($r) = $rows ? qq/ rows="$rows"/ : '';
+    my($c) = $cols ? qq/ cols="$cols"/ : '';
+    my($other) = @other ? " @other" : '';
+    return qq{<textarea name="$name"$r$c$other>$current</textarea>};
+}
+END_OF_FUNC
+
+
+#### Method: button
+# Create a javascript button.
+# Parameters:
+#   $name ->  (optional) Name for the button. (-name)
+#   $value -> (optional) Value of the button when selected (and visible name) (-value)
+#   $onclick -> (optional) Text of the JavaScript to run when the button is
+#                clicked.
+# Returns:
+#   A string containing a <INPUT TYPE="button"> tag
+####
+'button' => <<'END_OF_FUNC',
+sub button {
+    my($self,@p) = self_or_default(@_);
+
+    my($label,$value,$script,@other) = rearrange([NAME,[VALUE,LABEL],
+							 [ONCLICK,SCRIPT]],@p);
+
+    $label=$self->escapeHTML($label);
+    $value=$self->escapeHTML($value,1);
+    $script=$self->escapeHTML($script);
+
+    my($name) = '';
+    $name = qq/ name="$label"/ if $label;
+    $value = $value || $label;
+    my($val) = '';
+    $val = qq/ value="$value"/ if $value;
+    $script = qq/ onclick="$script"/ if $script;
+    my($other) = @other ? " @other" : '';
+    return $XHTML ? qq(<input type="button"$name$val$script$other />)
+                  : qq(<input type="button"$name$val$script$other>);
+}
+END_OF_FUNC
+
+
+#### Method: submit
+# Create a "submit query" button.
+# Parameters:
+#   $name ->  (optional) Name for the button.
+#   $value -> (optional) Value of the button when selected (also doubles as label).
+#   $label -> (optional) Label printed on the button(also doubles as the value).
+# Returns:
+#   A string containing a <INPUT TYPE="submit"> tag
+####
+'submit' => <<'END_OF_FUNC',
+sub submit {
+    my($self,@p) = self_or_default(@_);
+
+    my($label,$value,@other) = rearrange([NAME,[VALUE,LABEL]],@p);
+
+    $label=$self->escapeHTML($label);
+    $value=$self->escapeHTML($value,1);
+
+    my($name) = ' name=".submit"' unless $NOSTICKY;
+    $name = qq/ name="$label"/ if defined($label);
+    $value = defined($value) ? $value : $label;
+    my($val) = '';
+    $val = qq/ value="$value"/ if defined($value);
+    my($other) = @other ? " @other" : '';
+    return $XHTML ? qq(<input type="submit"$name$val$other />)
+                  : qq(<input type="submit"$name$val$other>);
+}
+END_OF_FUNC
+
+
+#### Method: reset
+# Create a "reset" button.
+# Parameters:
+#   $name -> (optional) Name for the button.
+# Returns:
+#   A string containing a <INPUT TYPE="reset"> tag
+####
+'reset' => <<'END_OF_FUNC',
+sub reset {
+    my($self,@p) = self_or_default(@_);
+    my($label,@other) = rearrange([NAME],@p);
+    $label=$self->escapeHTML($label);
+    my($value) = defined($label) ? qq/ value="$label"/ : '';
+    my($other) = @other ? " @other" : '';
+    return $XHTML ? qq(<input type="reset"$value$other />)
+                  : qq(<input type="reset"$value$other>);
+}
+END_OF_FUNC
+
+
+#### Method: defaults
+# Create a "defaults" button.
+# Parameters:
+#   $name -> (optional) Name for the button.
+# Returns:
+#   A string containing a <INPUT TYPE="submit" NAME=".defaults"> tag
+#
+# Note: this button has a special meaning to the initialization script,
+# and tells it to ERASE the current query string so that your defaults
+# are used again!
+####
+'defaults' => <<'END_OF_FUNC',
+sub defaults {
+    my($self,@p) = self_or_default(@_);
+
+    my($label,@other) = rearrange([[NAME,VALUE]],@p);
+
+    $label=$self->escapeHTML($label,1);
+    $label = $label || "Defaults";
+    my($value) = qq/ value="$label"/;
+    my($other) = @other ? " @other" : '';
+    return $XHTML ? qq(<input type="submit" name=".defaults"$value$other />)
+                  : qq/<input type="submit" NAME=".defaults"$value$other>/;
+}
+END_OF_FUNC
+
+
+#### Method: comment
+# Create an HTML <!-- comment -->
+# Parameters: a string
+'comment' => <<'END_OF_FUNC',
+sub comment {
+    my($self,@p) = self_or_CGI(@_);
+    return "<!-- @p -->";
+}
+END_OF_FUNC
+
+#### Method: checkbox
+# Create a checkbox that is not logically linked to any others.
+# The field value is "on" when the button is checked.
+# Parameters:
+#   $name -> Name of the checkbox
+#   $checked -> (optional) turned on by default if true
+#   $value -> (optional) value of the checkbox, 'on' by default
+#   $label -> (optional) a user-readable label printed next to the box.
+#             Otherwise the checkbox name is used.
+# Returns:
+#   A string containing a <INPUT TYPE="checkbox"> field
+####
+'checkbox' => <<'END_OF_FUNC',
+sub checkbox {
+    my($self,@p) = self_or_default(@_);
+
+    my($name,$checked,$value,$label,$override,@other) = 
+	rearrange([NAME,[CHECKED,SELECTED,ON],VALUE,LABEL,[OVERRIDE,FORCE]],@p);
+    
+    $value = defined $value ? $value : 'on';
+
+    if (!$override && ($self->{'.fieldnames'}->{$name} || 
+		       defined $self->param($name))) {
+	$checked = grep($_ eq $value,$self->param($name)) ? $self->_checked(1) : '';
+    } else {
+	$checked = $self->_checked($checked);
+    }
+    my($the_label) = defined $label ? $label : $name;
+    $name = $self->escapeHTML($name);
+    $value = $self->escapeHTML($value,1);
+    $the_label = $self->escapeHTML($the_label);
+    my($other) = @other ? " @other" : '';
+    $self->register_parameter($name);
+    return $XHTML ? qq{<input type="checkbox" name="$name" value="$value"$checked$other />$the_label}
+                  : qq{<input type="checkbox" name="$name" value="$value"$checked$other>$the_label};
+}
+END_OF_FUNC
+
+
+#### Method: checkbox_group
+# Create a list of logically-linked checkboxes.
+# Parameters:
+#   $name -> Common name for all the check boxes
+#   $values -> A pointer to a regular array containing the
+#             values for each checkbox in the group.
+#   $defaults -> (optional)
+#             1. If a pointer to a regular array of checkbox values,
+#             then this will be used to decide which
+#             checkboxes to turn on by default.
+#             2. If a scalar, will be assumed to hold the
+#             value of a single checkbox in the group to turn on. 
+#   $linebreak -> (optional) Set to true to place linebreaks
+#             between the buttons.
+#   $labels -> (optional)
+#             A pointer to an associative array of labels to print next to each checkbox
+#             in the form $label{'value'}="Long explanatory label".
+#             Otherwise the provided values are used as the labels.
+# Returns:
+#   An ARRAY containing a series of <INPUT TYPE="checkbox"> fields
+####
+'checkbox_group' => <<'END_OF_FUNC',
+sub checkbox_group {
+    my($self,@p) = self_or_default(@_);
+
+    my($name,$values,$defaults,$linebreak,$labels,$rows,$columns,
+       $rowheaders,$colheaders,$override,$nolabels,@other) =
+	rearrange([NAME,[VALUES,VALUE],[DEFAULTS,DEFAULT],
+			  LINEBREAK,LABELS,ROWS,[COLUMNS,COLS],
+			  ROWHEADERS,COLHEADERS,
+			  [OVERRIDE,FORCE],NOLABELS],@p);
+
+    my($checked,$break,$result,$label);
+
+    my(%checked) = $self->previous_or_default($name,$defaults,$override);
+
+	if ($linebreak) {
+    $break = $XHTML ? "<br />" : "<br>";
+	}
+	else {
+	$break = '';
+	}
+    $name=$self->escapeHTML($name);
+
+    # Create the elements
+    my(@elements,@values);
+
+    @values = $self->_set_values_and_labels($values,\$labels,$name);
+
+    my($other) = @other ? " @other" : '';
+    foreach (@values) {
+	$checked = $self->_checked($checked{$_});
+	$label = '';
+	unless (defined($nolabels) && $nolabels) {
+	    $label = $_;
+	    $label = $labels->{$_} if defined($labels) && defined($labels->{$_});
+	    $label = $self->escapeHTML($label);
+	}
+	$_ = $self->escapeHTML($_,1);
+	push(@elements,$XHTML ? qq(<input type="checkbox" name="$name" value="$_"$checked$other />${label}${break})
+                              : qq/<input type="checkbox" name="$name" value="$_"$checked$other>${label}${break}/);
+    }
+    $self->register_parameter($name);
+    return wantarray ? @elements : join(' ',@elements)            
+        unless defined($columns) || defined($rows);
+    return _tableize($rows,$columns,$rowheaders,$colheaders,@elements);
+}
+END_OF_FUNC
+
+# Escape HTML -- used internally
+'escapeHTML' => <<'END_OF_FUNC',
+sub escapeHTML {
+         # hack to work around  earlier hacks
+         push @_,$_[0] if @_==1 && $_[0] eq 'CGI';
+         my ($self,$toencode,$newlinestoo) = CGI::self_or_default(@_);
+         return undef unless defined($toencode);
+         return $toencode if ref($self) && $self->{'dontescape'};
+         $toencode =~ s{&}{&amp;}gso;
+         $toencode =~ s{<}{&lt;}gso;
+         $toencode =~ s{>}{&gt;}gso;
+         $toencode =~ s{"}{&quot;}gso;
+         my $latin = uc $self->{'.charset'} eq 'ISO-8859-1' ||
+                     uc $self->{'.charset'} eq 'WINDOWS-1252';
+         if ($latin) {  # bug in some browsers
+                $toencode =~ s{'}{&#39;}gso;
+                $toencode =~ s{\x8b}{&#139;}gso;
+                $toencode =~ s{\x9b}{&#155;}gso;
+                if (defined $newlinestoo && $newlinestoo) {
+                     $toencode =~ s{\012}{&#10;}gso;
+                     $toencode =~ s{\015}{&#13;}gso;
+                }
+         }
+         return $toencode;
+}
+END_OF_FUNC
+
+# unescape HTML -- used internally
+'unescapeHTML' => <<'END_OF_FUNC',
+sub unescapeHTML {
+    my ($self,$string) = CGI::self_or_default(@_);
+    return undef unless defined($string);
+    my $latin = defined $self->{'.charset'} ? $self->{'.charset'} =~ /^(ISO-8859-1|WINDOWS-1252)$/i
+                                            : 1;
+    # thanks to Randal Schwartz for the correct solution to this one
+    $string=~ s[&(.*?);]{
+	local $_ = $1;
+	/^amp$/i	? "&" :
+	/^quot$/i	? '"' :
+        /^gt$/i		? ">" :
+	/^lt$/i		? "<" :
+	/^#(\d+)$/ && $latin	     ? chr($1) :
+	/^#x([0-9a-f]+)$/i && $latin ? chr(hex($1)) :
+	$_
+	}gex;
+    return $string;
+}
+END_OF_FUNC
+
+# Internal procedure - don't use
+'_tableize' => <<'END_OF_FUNC',
+sub _tableize {
+    my($rows,$columns,$rowheaders,$colheaders,@elements) = @_;
+    $rowheaders = [] unless defined $rowheaders;
+    $colheaders = [] unless defined $colheaders;
+    my($result);
+
+    if (defined($columns)) {
+	$rows = int(0.99 + @elements/$columns) unless defined($rows);
+    }
+    if (defined($rows)) {
+	$columns = int(0.99 + @elements/$rows) unless defined($columns);
+    }
+    
+    # rearrange into a pretty table
+    $result = "<table>";
+    my($row,$column);
+    unshift(@$colheaders,'') if @$colheaders && @$rowheaders;
+    $result .= "<tr>" if @{$colheaders};
+    foreach (@{$colheaders}) {
+	$result .= "<th>$_</th>";
+    }
+    for ($row=0;$row<$rows;$row++) {
+	$result .= "<tr>";
+	$result .= "<th>$rowheaders->[$row]</th>" if @$rowheaders;
+	for ($column=0;$column<$columns;$column++) {
+	    $result .= "<td>" . $elements[$column*$rows + $row] . "</td>"
+		if defined($elements[$column*$rows + $row]);
+	}
+	$result .= "</tr>";
+    }
+    $result .= "</table>";
+    return $result;
+}
+END_OF_FUNC
+
+
+#### Method: radio_group
+# Create a list of logically-linked radio buttons.
+# Parameters:
+#   $name -> Common name for all the buttons.
+#   $values -> A pointer to a regular array containing the
+#             values for each button in the group.
+#   $default -> (optional) Value of the button to turn on by default.  Pass '-'
+#               to turn _nothing_ on.
+#   $linebreak -> (optional) Set to true to place linebreaks
+#             between the buttons.
+#   $labels -> (optional)
+#             A pointer to an associative array of labels to print next to each checkbox
+#             in the form $label{'value'}="Long explanatory label".
+#             Otherwise the provided values are used as the labels.
+# Returns:
+#   An ARRAY containing a series of <INPUT TYPE="radio"> fields
+####
+'radio_group' => <<'END_OF_FUNC',
+sub radio_group {
+    my($self,@p) = self_or_default(@_);
+
+    my($name,$values,$default,$linebreak,$labels,
+       $rows,$columns,$rowheaders,$colheaders,$override,$nolabels,@other) =
+	rearrange([NAME,[VALUES,VALUE],DEFAULT,LINEBREAK,LABELS,
+			  ROWS,[COLUMNS,COLS],
+			  ROWHEADERS,COLHEADERS,
+			  [OVERRIDE,FORCE],NOLABELS],@p);
+    my($result,$checked);
+
+    if (!$override && defined($self->param($name))) {
+	$checked = $self->param($name);
+    } else {
+	$checked = $default;
+    }
+    my(@elements,@values);
+    @values = $self->_set_values_and_labels($values,\$labels,$name);
+
+    # If no check array is specified, check the first by default
+    $checked = $values[0] unless defined($checked) && $checked ne '';
+    $name=$self->escapeHTML($name);
+
+    my($other) = @other ? " @other" : '';
+    foreach (@values) {
+	my($checkit) = $checked eq $_ ? qq/ checked="checked"/ : '';
+	my($break);
+	if ($linebreak) {
+          $break = $XHTML ? "<br />" : "<br>";
+	}
+	else {
+	  $break = '';
+	}
+	my($label)='';
+	unless (defined($nolabels) && $nolabels) {
+	    $label = $_;
+	    $label = $labels->{$_} if defined($labels) && defined($labels->{$_});
+	    $label = $self->escapeHTML($label,1);
+	}
+	$_=$self->escapeHTML($_);
+	push(@elements,$XHTML ? qq(<input type="radio" name="$name" value="$_"$checkit$other />${label}${break})
+                              : qq/<input type="radio" name="$name" value="$_"$checkit$other>${label}${break}/);
+    }
+    $self->register_parameter($name);
+    return wantarray ? @elements : join(' ',@elements) 
+           unless defined($columns) || defined($rows);
+    return _tableize($rows,$columns,$rowheaders,$colheaders,@elements);
+}
+END_OF_FUNC
+
+
+#### Method: popup_menu
+# Create a popup menu.
+# Parameters:
+#   $name -> Name for all the menu
+#   $values -> A pointer to a regular array containing the
+#             text of each menu item.
+#   $default -> (optional) Default item to display
+#   $labels -> (optional)
+#             A pointer to an associative array of labels to print next to each checkbox
+#             in the form $label{'value'}="Long explanatory label".
+#             Otherwise the provided values are used as the labels.
+# Returns:
+#   A string containing the definition of a popup menu.
+####
+'popup_menu' => <<'END_OF_FUNC',
+sub popup_menu {
+    my($self,@p) = self_or_default(@_);
+
+    my($name,$values,$default,$labels,$override,@other) =
+	rearrange([NAME,[VALUES,VALUE],[DEFAULT,DEFAULTS],LABELS,[OVERRIDE,FORCE]],@p);
+    my($result,$selected);
+
+    if (!$override && defined($self->param($name))) {
+	$selected = $self->param($name);
+    } else {
+	$selected = $default;
+    }
+    $name=$self->escapeHTML($name);
+    my($other) = @other ? " @other" : '';
+
+    my(@values);
+    @values = $self->_set_values_and_labels($values,\$labels,$name);
+
+    $result = qq/<select name="$name"$other>\n/;
+    foreach (@values) {
+	my($selectit) = defined($selected) ? $self->_selected($selected eq $_) : '';
+	my($label) = $_;
+	$label = $labels->{$_} if defined($labels) && defined($labels->{$_});
+	my($value) = $self->escapeHTML($_);
+	$label=$self->escapeHTML($label,1);
+	$result .= "<option$selectit value=\"$value\">$label</option>\n";
+    }
+
+    $result .= "</select>";
+    return $result;
+}
+END_OF_FUNC
+
+
+#### Method: scrolling_list
+# Create a scrolling list.
+# Parameters:
+#   $name -> name for the list
+#   $values -> A pointer to a regular array containing the
+#             values for each option line in the list.
+#   $defaults -> (optional)
+#             1. If a pointer to a regular array of options,
+#             then this will be used to decide which
+#             lines to turn on by default.
+#             2. Otherwise holds the value of the single line to turn on.
+#   $size -> (optional) Size of the list.
+#   $multiple -> (optional) If set, allow multiple selections.
+#   $labels -> (optional)
+#             A pointer to an associative array of labels to print next to each checkbox
+#             in the form $label{'value'}="Long explanatory label".
+#             Otherwise the provided values are used as the labels.
+# Returns:
+#   A string containing the definition of a scrolling list.
+####
+'scrolling_list' => <<'END_OF_FUNC',
+sub scrolling_list {
+    my($self,@p) = self_or_default(@_);
+    my($name,$values,$defaults,$size,$multiple,$labels,$override,@other)
+	= rearrange([NAME,[VALUES,VALUE],[DEFAULTS,DEFAULT],
+			    SIZE,MULTIPLE,LABELS,[OVERRIDE,FORCE]],@p);
+
+    my($result,@values);
+    @values = $self->_set_values_and_labels($values,\$labels,$name);
+
+    $size = $size || scalar(@values);
+
+    my(%selected) = $self->previous_or_default($name,$defaults,$override);
+    my($is_multiple) = $multiple ? qq/ multiple="multiple"/ : '';
+    my($has_size) = $size ? qq/ size="$size"/: '';
+    my($other) = @other ? " @other" : '';
+
+    $name=$self->escapeHTML($name);
+    $result = qq/<select name="$name"$has_size$is_multiple$other>\n/;
+    foreach (@values) {
+	my($selectit) = $self->_selected($selected{$_});
+	my($label) = $_;
+	$label = $labels->{$_} if defined($labels) && defined($labels->{$_});
+	$label=$self->escapeHTML($label);
+	my($value)=$self->escapeHTML($_,1);
+	$result .= "<option$selectit value=\"$value\">$label</option>\n";
+    }
+    $result .= "</select>";
+    $self->register_parameter($name);
+    return $result;
+}
+END_OF_FUNC
+
+
+#### Method: hidden
+# Parameters:
+#   $name -> Name of the hidden field
+#   @default -> (optional) Initial values of field (may be an array)
+#      or
+#   $default->[initial values of field]
+# Returns:
+#   A string containing a <INPUT TYPE="hidden" NAME="name" VALUE="value">
+####
+'hidden' => <<'END_OF_FUNC',
+sub hidden {
+    my($self,@p) = self_or_default(@_);
+
+    # this is the one place where we departed from our standard
+    # calling scheme, so we have to special-case (darn)
+    my(@result,@value);
+    my($name,$default,$override,@other) = 
+	rearrange([NAME,[DEFAULT,VALUE,VALUES],[OVERRIDE,FORCE]],@p);
+
+    my $do_override = 0;
+    if ( ref($p[0]) || substr($p[0],0,1) eq '-') {
+	@value = ref($default) ? @{$default} : $default;
+	$do_override = $override;
+    } else {
+	foreach ($default,$override,@other) {
+	    push(@value,$_) if defined($_);
+	}
+    }
+
+    # use previous values if override is not set
+    my @prev = $self->param($name);
+    @value = @prev if !$do_override && @prev;
+
+    $name=$self->escapeHTML($name);
+    foreach (@value) {
+	$_ = defined($_) ? $self->escapeHTML($_,1) : '';
+	push @result,$XHTML ? qq(<input type="hidden" name="$name" value="$_" />)
+                            : qq(<input type="hidden" name="$name" value="$_">);
+    }
+    return wantarray ? @result : join('',@result);
+}
+END_OF_FUNC
+
+
+#### Method: image_button
+# Parameters:
+#   $name -> Name of the button
+#   $src ->  URL of the image source
+#   $align -> Alignment style (TOP, BOTTOM or MIDDLE)
+# Returns:
+#   A string containing a <INPUT TYPE="image" NAME="name" SRC="url" ALIGN="alignment">
+####
+'image_button' => <<'END_OF_FUNC',
+sub image_button {
+    my($self,@p) = self_or_default(@_);
+
+    my($name,$src,$alignment,@other) =
+	rearrange([NAME,SRC,ALIGN],@p);
+
+    my($align) = $alignment ? " align=\U\"$alignment\"" : '';
+    my($other) = @other ? " @other" : '';
+    $name=$self->escapeHTML($name);
+    return $XHTML ? qq(<input type="image" name="$name" src="$src"$align$other />)
+                  : qq/<input type="image" name="$name" src="$src"$align$other>/;
+}
+END_OF_FUNC
+
+
+#### Method: self_url
+# Returns a URL containing the current script and all its
+# param/value pairs arranged as a query.  You can use this
+# to create a link that, when selected, will reinvoke the
+# script with all its state information preserved.
+####
+'self_url' => <<'END_OF_FUNC',
+sub self_url {
+    my($self,@p) = self_or_default(@_);
+    return $self->url('-path_info'=>1,'-query'=>1,'-full'=>1,@p);
+}
+END_OF_FUNC
+
+
+# This is provided as a synonym to self_url() for people unfortunate
+# enough to have incorporated it into their programs already!
+'state' => <<'END_OF_FUNC',
+sub state {
+    &self_url;
+}
+END_OF_FUNC
+
+
+#### Method: url
+# Like self_url, but doesn't return the query string part of
+# the URL.
+####
+'url' => <<'END_OF_FUNC',
+sub url {
+    my($self,@p) = self_or_default(@_);
+    my ($relative,$absolute,$full,$path_info,$query,$base) = 
+	rearrange(['RELATIVE','ABSOLUTE','FULL',['PATH','PATH_INFO'],['QUERY','QUERY_STRING'],'BASE'],@p);
+    my $url;
+    $full++      if $base || !($relative || $absolute);
+
+    my $path = $self->path_info;
+    my $script_name = $self->script_name;
+
+    # for compatibility with Apache's MultiViews
+    if (exists($ENV{REQUEST_URI})) {
+        my $index;
+	$script_name = $ENV{REQUEST_URI};
+        $script_name =~ s/\?.+$//;   # strip query string
+        # and path
+        if (exists($ENV{PATH_INFO})) {
+           (my $encoded_path = $ENV{PATH_INFO}) =~ s/([^a-zA-Z0-9_.%;&?\/\\:+=~-])/sprintf("%%%02X",ord($1))/eg;
+           $script_name      =~ s/$encoded_path$//i;
+         }
+    }
+
+    if ($full) {
+	my $protocol = $self->protocol();
+	$url = "$protocol://";
+	my $vh = http('host');
+	if ($vh) {
+	    $url .= $vh;
+	} else {
+	    $url .= server_name();
+	    my $port = $self->server_port;
+	    $url .= ":" . $port
+		unless (lc($protocol) eq 'http' && $port == 80)
+		    || (lc($protocol) eq 'https' && $port == 443);
+	}
+        return $url if $base;
+	$url .= $script_name;
+    } elsif ($relative) {
+	($url) = $script_name =~ m!([^/]+)$!;
+    } elsif ($absolute) {
+	$url = $script_name;
+    }
+
+    $url .= $path if $path_info and defined $path;
+    $url .= "?" . $self->query_string if $query and $self->query_string;
+    $url = '' unless defined $url;
+    $url =~ s/([^a-zA-Z0-9_.%;&?\/\\:+=~-])/sprintf("%%%02X",ord($1))/eg;
+    return $url;
+}
+
+END_OF_FUNC
+
+#### Method: cookie
+# Set or read a cookie from the specified name.
+# Cookie can then be passed to header().
+# Usual rules apply to the stickiness of -value.
+#  Parameters:
+#   -name -> name for this cookie (optional)
+#   -value -> value of this cookie (scalar, array or hash) 
+#   -path -> paths for which this cookie is valid (optional)
+#   -domain -> internet domain in which this cookie is valid (optional)
+#   -secure -> if true, cookie only passed through secure channel (optional)
+#   -expires -> expiry date in format Wdy, DD-Mon-YYYY HH:MM:SS GMT (optional)
+####
+'cookie' => <<'END_OF_FUNC',
+sub cookie {
+    my($self,@p) = self_or_default(@_);
+    my($name,$value,$path,$domain,$secure,$expires) =
+	rearrange([NAME,[VALUE,VALUES],PATH,DOMAIN,SECURE,EXPIRES],@p);
+
+    require CGI::Cookie;
+
+    # if no value is supplied, then we retrieve the
+    # value of the cookie, if any.  For efficiency, we cache the parsed
+    # cookies in our state variables.
+    unless ( defined($value) ) {
+	$self->{'.cookies'} = CGI::Cookie->fetch
+	    unless $self->{'.cookies'};
+
+	# If no name is supplied, then retrieve the names of all our cookies.
+	return () unless $self->{'.cookies'};
+	return keys %{$self->{'.cookies'}} unless $name;
+	return () unless $self->{'.cookies'}->{$name};
+	return $self->{'.cookies'}->{$name}->value if defined($name) && $name ne '';
+    }
+
+    # If we get here, we're creating a new cookie
+    return undef unless defined($name) && $name ne '';	# this is an error
+
+    my @param;
+    push(@param,'-name'=>$name);
+    push(@param,'-value'=>$value);
+    push(@param,'-domain'=>$domain) if $domain;
+    push(@param,'-path'=>$path) if $path;
+    push(@param,'-expires'=>$expires) if $expires;
+    push(@param,'-secure'=>$secure) if $secure;
+
+    return new CGI::Cookie(@param);
+}
+END_OF_FUNC
+
+'parse_keywordlist' => <<'END_OF_FUNC',
+sub parse_keywordlist {
+    my($self,$tosplit) = @_;
+    $tosplit = unescape($tosplit); # unescape the keywords
+    $tosplit=~tr/+/ /;          # pluses to spaces
+    my(@keywords) = split(/\s+/,$tosplit);
+    return @keywords;
+}
+END_OF_FUNC
+
+'param_fetch' => <<'END_OF_FUNC',
+sub param_fetch {
+    my($self,@p) = self_or_default(@_);
+    my($name) = rearrange([NAME],@p);
+    unless (exists($self->{$name})) {
+	$self->add_parameter($name);
+	$self->{$name} = [];
+    }
+    
+    return $self->{$name};
+}
+END_OF_FUNC
+
+###############################################
+# OTHER INFORMATION PROVIDED BY THE ENVIRONMENT
+###############################################
+
+#### Method: path_info
+# Return the extra virtual path information provided
+# after the URL (if any)
+####
+'path_info' => <<'END_OF_FUNC',
+sub path_info {
+    my ($self,$info) = self_or_default(@_);
+    if (defined($info)) {
+	$info = "/$info" if $info ne '' &&  substr($info,0,1) ne '/';
+	$self->{'.path_info'} = $info;
+    } elsif (! defined($self->{'.path_info'}) ) {
+	$self->{'.path_info'} = defined($ENV{'PATH_INFO'}) ? 
+	    $ENV{'PATH_INFO'} : '';
+
+	# hack to fix broken path info in IIS
+	$self->{'.path_info'} =~ s/^\Q$ENV{'SCRIPT_NAME'}\E// if $IIS;
+
+    }
+    return $self->{'.path_info'};
+}
+END_OF_FUNC
+
+
+#### Method: request_method
+# Returns 'POST', 'GET', 'PUT' or 'HEAD'
+####
+'request_method' => <<'END_OF_FUNC',
+sub request_method {
+    return $ENV{'REQUEST_METHOD'};
+}
+END_OF_FUNC
+
+#### Method: content_type
+# Returns the content_type string
+####
+'content_type' => <<'END_OF_FUNC',
+sub content_type {
+    return $ENV{'CONTENT_TYPE'};
+}
+END_OF_FUNC
+
+#### Method: path_translated
+# Return the physical path information provided
+# by the URL (if any)
+####
+'path_translated' => <<'END_OF_FUNC',
+sub path_translated {
+    return $ENV{'PATH_TRANSLATED'};
+}
+END_OF_FUNC
+
+
+#### Method: query_string
+# Synthesize a query string from our current
+# parameters
+####
+'query_string' => <<'END_OF_FUNC',
+sub query_string {
+    my($self) = self_or_default(@_);
+    my($param,$value,@pairs);
+    foreach $param ($self->param) {
+	my($eparam) = escape($param);
+	foreach $value ($self->param($param)) {
+	    $value = escape($value);
+            next unless defined $value;
+	    push(@pairs,"$eparam=$value");
+	}
+    }
+    foreach (keys %{$self->{'.fieldnames'}}) {
+      push(@pairs,".cgifields=".escape("$_"));
+    }
+    return join($USE_PARAM_SEMICOLONS ? ';' : '&',@pairs);
+}
+END_OF_FUNC
+
+
+#### Method: accept
+# Without parameters, returns an array of the
+# MIME types the browser accepts.
+# With a single parameter equal to a MIME
+# type, will return undef if the browser won't
+# accept it, 1 if the browser accepts it but
+# doesn't give a preference, or a floating point
+# value between 0.0 and 1.0 if the browser
+# declares a quantitative score for it.
+# This handles MIME type globs correctly.
+####
+'Accept' => <<'END_OF_FUNC',
+sub Accept {
+    my($self,$search) = self_or_CGI(@_);
+    my(%prefs,$type,$pref,$pat);
+    
+    my(@accept) = split(',',$self->http('accept'));
+
+    foreach (@accept) {
+	($pref) = /q=(\d\.\d+|\d+)/;
+	($type) = m#(\S+/[^;]+)#;
+	next unless $type;
+	$prefs{$type}=$pref || 1;
+    }
+
+    return keys %prefs unless $search;
+    
+    # if a search type is provided, we may need to
+    # perform a pattern matching operation.
+    # The MIME types use a glob mechanism, which
+    # is easily translated into a perl pattern match
+
+    # First return the preference for directly supported
+    # types:
+    return $prefs{$search} if $prefs{$search};
+
+    # Didn't get it, so try pattern matching.
+    foreach (keys %prefs) {
+	next unless /\*/;       # not a pattern match
+	($pat = $_) =~ s/([^\w*])/\\$1/g; # escape meta characters
+	$pat =~ s/\*/.*/g; # turn it into a pattern
+	return $prefs{$_} if $search=~/$pat/;
+    }
+}
+END_OF_FUNC
+
+
+#### Method: user_agent
+# If called with no parameters, returns the user agent.
+# If called with one parameter, does a pattern match (case
+# insensitive) on the user agent.
+####
+'user_agent' => <<'END_OF_FUNC',
+sub user_agent {
+    my($self,$match)=self_or_CGI(@_);
+    return $self->http('user_agent') unless $match;
+    return $self->http('user_agent') =~ /$match/i;
+}
+END_OF_FUNC
+
+
+#### Method: raw_cookie
+# Returns the magic cookies for the session.
+# The cookies are not parsed or altered in any way, i.e.
+# cookies are returned exactly as given in the HTTP
+# headers.  If a cookie name is given, only that cookie's
+# value is returned, otherwise the entire raw cookie
+# is returned.
+####
+'raw_cookie' => <<'END_OF_FUNC',
+sub raw_cookie {
+    my($self,$key) = self_or_CGI(@_);
+
+    require CGI::Cookie;
+
+    if (defined($key)) {
+	$self->{'.raw_cookies'} = CGI::Cookie->raw_fetch
+	    unless $self->{'.raw_cookies'};
+
+	return () unless $self->{'.raw_cookies'};
+	return () unless $self->{'.raw_cookies'}->{$key};
+	return $self->{'.raw_cookies'}->{$key};
+    }
+    return $self->http('cookie') || $ENV{'COOKIE'} || '';
+}
+END_OF_FUNC
+
+#### Method: virtual_host
+# Return the name of the virtual_host, which
+# is not always the same as the server
+######
+'virtual_host' => <<'END_OF_FUNC',
+sub virtual_host {
+    my $vh = http('host') || server_name();
+    $vh =~ s/:\d+$//;		# get rid of port number
+    return $vh;
+}
+END_OF_FUNC
+
+#### Method: remote_host
+# Return the name of the remote host, or its IP
+# address if unavailable.  If this variable isn't
+# defined, it returns "localhost" for debugging
+# purposes.
+####
+'remote_host' => <<'END_OF_FUNC',
+sub remote_host {
+    return $ENV{'REMOTE_HOST'} || $ENV{'REMOTE_ADDR'} 
+    || 'localhost';
+}
+END_OF_FUNC
+
+
+#### Method: remote_addr
+# Return the IP addr of the remote host.
+####
+'remote_addr' => <<'END_OF_FUNC',
+sub remote_addr {
+    return $ENV{'REMOTE_ADDR'} || '127.0.0.1';
+}
+END_OF_FUNC
+
+
+#### Method: script_name
+# Return the partial URL to this script for
+# self-referencing scripts.  Also see
+# self_url(), which returns a URL with all state information
+# preserved.
+####
+'script_name' => <<'END_OF_FUNC',
+sub script_name {
+    return $ENV{'SCRIPT_NAME'} if defined($ENV{'SCRIPT_NAME'});
+    # These are for debugging
+    return "/$0" unless $0=~/^\//;
+    return $0;
+}
+END_OF_FUNC
+
+
+#### Method: referer
+# Return the HTTP_REFERER: useful for generating
+# a GO BACK button.
+####
+'referer' => <<'END_OF_FUNC',
+sub referer {
+    my($self) = self_or_CGI(@_);
+    return $self->http('referer');
+}
+END_OF_FUNC
+
+
+#### Method: server_name
+# Return the name of the server
+####
+'server_name' => <<'END_OF_FUNC',
+sub server_name {
+    return $ENV{'SERVER_NAME'} || 'localhost';
+}
+END_OF_FUNC
+
+#### Method: server_software
+# Return the name of the server software
+####
+'server_software' => <<'END_OF_FUNC',
+sub server_software {
+    return $ENV{'SERVER_SOFTWARE'} || 'cmdline';
+}
+END_OF_FUNC
+
+#### Method: server_port
+# Return the tcp/ip port the server is running on
+####
+'server_port' => <<'END_OF_FUNC',
+sub server_port {
+    return $ENV{'SERVER_PORT'} || 80; # for debugging
+}
+END_OF_FUNC
+
+#### Method: server_protocol
+# Return the protocol (usually HTTP/1.0)
+####
+'server_protocol' => <<'END_OF_FUNC',
+sub server_protocol {
+    return $ENV{'SERVER_PROTOCOL'} || 'HTTP/1.0'; # for debugging
+}
+END_OF_FUNC
+
+#### Method: http
+# Return the value of an HTTP variable, or
+# the list of variables if none provided
+####
+'http' => <<'END_OF_FUNC',
+sub http {
+    my ($self,$parameter) = self_or_CGI(@_);
+    return $ENV{$parameter} if $parameter=~/^HTTP/;
+    $parameter =~ tr/-/_/;
+    return $ENV{"HTTP_\U$parameter\E"} if $parameter;
+    my(@p);
+    foreach (keys %ENV) {
+	push(@p,$_) if /^HTTP/;
+    }
+    return @p;
+}
+END_OF_FUNC
+
+#### Method: https
+# Return the value of HTTPS
+####
+'https' => <<'END_OF_FUNC',
+sub https {
+    local($^W)=0;
+    my ($self,$parameter) = self_or_CGI(@_);
+    return $ENV{HTTPS} unless $parameter;
+    return $ENV{$parameter} if $parameter=~/^HTTPS/;
+    $parameter =~ tr/-/_/;
+    return $ENV{"HTTPS_\U$parameter\E"} if $parameter;
+    my(@p);
+    foreach (keys %ENV) {
+	push(@p,$_) if /^HTTPS/;
+    }
+    return @p;
+}
+END_OF_FUNC
+
+#### Method: protocol
+# Return the protocol (http or https currently)
+####
+'protocol' => <<'END_OF_FUNC',
+sub protocol {
+    local($^W)=0;
+    my $self = shift;
+    return 'https' if uc($self->https()) eq 'ON'; 
+    return 'https' if $self->server_port == 443;
+    my $prot = $self->server_protocol;
+    my($protocol,$version) = split('/',$prot);
+    return "\L$protocol\E";
+}
+END_OF_FUNC
+
+#### Method: remote_ident
+# Return the identity of the remote user
+# (but only if his host is running identd)
+####
+'remote_ident' => <<'END_OF_FUNC',
+sub remote_ident {
+    return $ENV{'REMOTE_IDENT'};
+}
+END_OF_FUNC
+
+
+#### Method: auth_type
+# Return the type of use verification/authorization in use, if any.
+####
+'auth_type' => <<'END_OF_FUNC',
+sub auth_type {
+    return $ENV{'AUTH_TYPE'};
+}
+END_OF_FUNC
+
+
+#### Method: remote_user
+# Return the authorization name used for user
+# verification.
+####
+'remote_user' => <<'END_OF_FUNC',
+sub remote_user {
+    return $ENV{'REMOTE_USER'};
+}
+END_OF_FUNC
+
+
+#### Method: user_name
+# Try to return the remote user's name by hook or by
+# crook
+####
+'user_name' => <<'END_OF_FUNC',
+sub user_name {
+    my ($self) = self_or_CGI(@_);
+    return $self->http('from') || $ENV{'REMOTE_IDENT'} || $ENV{'REMOTE_USER'};
+}
+END_OF_FUNC
+
+#### Method: nosticky
+# Set or return the NOSTICKY global flag
+####
+'nosticky' => <<'END_OF_FUNC',
+sub nosticky {
+    my ($self,$param) = self_or_CGI(@_);
+    $CGI::NOSTICKY = $param if defined($param);
+    return $CGI::NOSTICKY;
+}
+END_OF_FUNC
+
+#### Method: nph
+# Set or return the NPH global flag
+####
+'nph' => <<'END_OF_FUNC',
+sub nph {
+    my ($self,$param) = self_or_CGI(@_);
+    $CGI::NPH = $param if defined($param);
+    return $CGI::NPH;
+}
+END_OF_FUNC
+
+#### Method: private_tempfiles
+# Set or return the private_tempfiles global flag
+####
+'private_tempfiles' => <<'END_OF_FUNC',
+sub private_tempfiles {
+    my ($self,$param) = self_or_CGI(@_);
+    $CGI::PRIVATE_TEMPFILES = $param if defined($param);
+    return $CGI::PRIVATE_TEMPFILES;
+}
+END_OF_FUNC
+
+#### Method: default_dtd
+# Set or return the default_dtd global
+####
+'default_dtd' => <<'END_OF_FUNC',
+sub default_dtd {
+    my ($self,$param,$param2) = self_or_CGI(@_);
+    if (defined $param2 && defined $param) {
+        $CGI::DEFAULT_DTD = [ $param, $param2 ];
+    } elsif (defined $param) {
+        $CGI::DEFAULT_DTD = $param;
+    }
+    return $CGI::DEFAULT_DTD;
+}
+END_OF_FUNC
+
+# -------------- really private subroutines -----------------
+'previous_or_default' => <<'END_OF_FUNC',
+sub previous_or_default {
+    my($self,$name,$defaults,$override) = @_;
+    my(%selected);
+
+    if (!$override && ($self->{'.fieldnames'}->{$name} || 
+		       defined($self->param($name)) ) ) {
+	grep($selected{$_}++,$self->param($name));
+    } elsif (defined($defaults) && ref($defaults) && 
+	     (ref($defaults) eq 'ARRAY')) {
+	grep($selected{$_}++,@{$defaults});
+    } else {
+	$selected{$defaults}++ if defined($defaults);
+    }
+
+    return %selected;
+}
+END_OF_FUNC
+
+'register_parameter' => <<'END_OF_FUNC',
+sub register_parameter {
+    my($self,$param) = @_;
+    $self->{'.parametersToAdd'}->{$param}++;
+}
+END_OF_FUNC
+
+'get_fields' => <<'END_OF_FUNC',
+sub get_fields {
+    my($self) = @_;
+    return $self->CGI::hidden('-name'=>'.cgifields',
+			      '-values'=>[keys %{$self->{'.parametersToAdd'}}],
+			      '-override'=>1);
+}
+END_OF_FUNC
+
+'read_from_cmdline' => <<'END_OF_FUNC',
+sub read_from_cmdline {
+    my($input,@words);
+    my($query_string);
+    if ($DEBUG && @ARGV) {
+	@words = @ARGV;
+    } elsif ($DEBUG > 1) {
+	require "shellwords.pl";
+	print STDERR "(offline mode: enter name=value pairs on standard input)\n";
+	chomp(@lines = <STDIN>); # remove newlines
+	$input = join(" ",@lines);
+	@words = &shellwords($input);    
+    }
+    foreach (@words) {
+	s/\\=/%3D/g;
+	s/\\&/%26/g;	    
+    }
+
+    if ("@words"=~/=/) {
+	$query_string = join('&',@words);
+    } else {
+	$query_string = join('+',@words);
+    }
+    return $query_string;
+}
+END_OF_FUNC
+
+#####
+# subroutine: read_multipart
+#
+# Read multipart data and store it into our parameters.
+# An interesting feature is that if any of the parts is a file, we
+# create a temporary file and open up a filehandle on it so that the
+# caller can read from it if necessary.
+#####
+'read_multipart' => <<'END_OF_FUNC',
+sub read_multipart {
+    my($self,$boundary,$length,$filehandle) = @_;
+
+    my($buffer) = $self->new_MultipartBuffer($boundary,$length,$filehandle);
+    return unless $buffer;
+    my(%header,$body);
+    my $filenumber = 0;
+    while (!$buffer->eof) {
+	%header = $buffer->readHeader;
+
+	unless (%header) {
+	    $self->cgi_error("400 Bad request (malformed multipart POST)");
+	    return;
+	}
+
+	my($param)= $header{'Content-Disposition'}=~/ name="?([^\";]*)"?/;
+
+	# Bug:  Netscape doesn't escape quotation marks in file names!!!
+	my($filename) = $header{'Content-Disposition'}=~/ filename="?([^\"]*)"?/;
+
+	# add this parameter to our list
+	$self->add_parameter($param);
+
+	# If no filename specified, then just read the data and assign it
+	# to our parameter list.
+	if ( !defined($filename) || $filename eq '' ) {
+	    my($value) = $buffer->readBody;
+	    push(@{$self->{$param}},$value);
+	    next;
+	}
+
+	my ($tmpfile,$tmp,$filehandle);
+      UPLOADS: {
+	  # If we get here, then we are dealing with a potentially large
+	  # uploaded form.  Save the data to a temporary file, then open
+	  # the file for reading.
+
+	  # skip the file if uploads disabled
+	  if ($DISABLE_UPLOADS) {
+	      while (defined($data = $buffer->read)) { }
+	      last UPLOADS;
+	  }
+
+	  # choose a relatively unpredictable tmpfile sequence number
+          my $seqno = unpack("%16C*",join('',localtime,values %ENV));
+          for (my $cnt=10;$cnt>0;$cnt--) {
+	    next unless $tmpfile = new CGITempFile($seqno);
+	    $tmp = $tmpfile->as_string;
+	    last if defined($filehandle = Fh->new($filename,$tmp,$PRIVATE_TEMPFILES));
+            $seqno += int rand(100);
+          }
+          die "CGI open of tmpfile: $!\n" unless defined $filehandle;
+	  $CGI::DefaultClass->binmode($filehandle) if $CGI::needs_binmode;
+
+	  my ($data);
+	  local($\) = '';
+	  while (defined($data = $buffer->read)) {
+	      print $filehandle $data;
+	  }
+
+	  # back up to beginning of file
+	  seek($filehandle,0,0);
+	  $CGI::DefaultClass->binmode($filehandle) if $CGI::needs_binmode;
+
+	  # Save some information about the uploaded file where we can get
+	  # at it later.
+	  $self->{'.tmpfiles'}->{fileno($filehandle)}= {
+	      name => $tmpfile,
+	      info => {%header},
+	  };
+	  push(@{$self->{$param}},$filehandle);
+      }
+    }
+}
+END_OF_FUNC
+
+'upload' =><<'END_OF_FUNC',
+sub upload {
+    my($self,$param_name) = self_or_default(@_);
+    my @param = grep(ref && fileno($_), $self->param($param_name));
+    return unless @param;
+    return wantarray ? @param : $param[0];
+}
+END_OF_FUNC
+
+'tmpFileName' => <<'END_OF_FUNC',
+sub tmpFileName {
+    my($self,$filename) = self_or_default(@_);
+    return $self->{'.tmpfiles'}->{fileno($filename)}->{name} ?
+	$self->{'.tmpfiles'}->{fileno($filename)}->{name}->as_string
+	    : '';
+}
+END_OF_FUNC
+
+'uploadInfo' => <<'END_OF_FUNC',
+sub uploadInfo {
+    my($self,$filename) = self_or_default(@_);
+    return $self->{'.tmpfiles'}->{fileno($filename)}->{info};
+}
+END_OF_FUNC
+
+# internal routine, don't use
+'_set_values_and_labels' => <<'END_OF_FUNC',
+sub _set_values_and_labels {
+    my $self = shift;
+    my ($v,$l,$n) = @_;
+    $$l = $v if ref($v) eq 'HASH' && !ref($$l);
+    return $self->param($n) if !defined($v);
+    return $v if !ref($v);
+    return ref($v) eq 'HASH' ? keys %$v : @$v;
+}
+END_OF_FUNC
+
+'_compile_all' => <<'END_OF_FUNC',
+sub _compile_all {
+    foreach (@_) {
+	next if defined(&$_);
+	$AUTOLOAD = "CGI::$_";
+	_compile();
+    }
+}
+END_OF_FUNC
+
+);
+END_OF_AUTOLOAD
+;
+
+#########################################################
+# Globals and stubs for other packages that we use.
+#########################################################
+
+################### Fh -- lightweight filehandle ###############
+package Fh;
+use overload 
+    '""'  => \&asString,
+    'cmp' => \&compare,
+    'fallback'=>1;
+
+$FH='fh00000';
+
+*Fh::AUTOLOAD = \&CGI::AUTOLOAD;
+
+$AUTOLOADED_ROUTINES = '';      # prevent -w error
+$AUTOLOADED_ROUTINES=<<'END_OF_AUTOLOAD';
+%SUBS =  (
+'asString' => <<'END_OF_FUNC',
+sub asString {
+    my $self = shift;
+    # get rid of package name
+    (my $i = $$self) =~ s/^\*(\w+::fh\d{5})+//; 
+    $i =~ s/%(..)/ chr(hex($1)) /eg;
+    return $i;
+# BEGIN DEAD CODE
+# This was an extremely clever patch that allowed "use strict refs".
+# Unfortunately it relied on another bug that caused leaky file descriptors.
+# The underlying bug has been fixed, so this no longer works.  However
+# "strict refs" still works for some reason.
+#    my $self = shift;
+#    return ${*{$self}{SCALAR}};
+# END DEAD CODE
+}
+END_OF_FUNC
+
+'compare' => <<'END_OF_FUNC',
+sub compare {
+    my $self = shift;
+    my $value = shift;
+    return "$self" cmp $value;
+}
+END_OF_FUNC
+
+'new'  => <<'END_OF_FUNC',
+sub new {
+    my($pack,$name,$file,$delete) = @_;
+    require Fcntl unless defined &Fcntl::O_RDWR;
+    (my $safename = $name) =~ s/([':%])/ sprintf '%%%02X', ord $1 /eg;
+    my $fv = ++$FH . $safename;
+    my $ref = \*{"Fh::$fv"};
+    sysopen($ref,$file,Fcntl::O_RDWR()|Fcntl::O_CREAT()|Fcntl::O_EXCL(),0600) || return;
+    unlink($file) if $delete;
+    CORE::delete $Fh::{$fv};
+    return bless $ref,$pack;
+}
+END_OF_FUNC
+
+'DESTROY'  => <<'END_OF_FUNC',
+sub DESTROY {
+    my $self = shift;
+    close $self;
+}
+END_OF_FUNC
+
+);
+END_OF_AUTOLOAD
+
+######################## MultipartBuffer ####################
+package MultipartBuffer;
+
+# how many bytes to read at a time.  We use
+# a 4K buffer by default.
+$INITIAL_FILLUNIT = 1024 * 4;
+$TIMEOUT = 240*60;       # 4 hour timeout for big files
+$SPIN_LOOP_MAX = 2000;  # bug fix for some Netscape servers
+$CRLF=$CGI::CRLF;
+
+#reuse the autoload function
+*MultipartBuffer::AUTOLOAD = \&CGI::AUTOLOAD;
+
+# avoid autoloader warnings
+sub DESTROY {}
+
+###############################################################################
+################# THESE FUNCTIONS ARE AUTOLOADED ON DEMAND ####################
+###############################################################################
+$AUTOLOADED_ROUTINES = '';      # prevent -w error
+$AUTOLOADED_ROUTINES=<<'END_OF_AUTOLOAD';
+%SUBS =  (
+
+'new' => <<'END_OF_FUNC',
+sub new {
+    my($package,$interface,$boundary,$length,$filehandle) = @_;
+    $FILLUNIT = $INITIAL_FILLUNIT;
+    my $IN;
+    if ($filehandle) {
+	my($package) = caller;
+	# force into caller's package if necessary
+	$IN = $filehandle=~/[':]/ ? $filehandle : "$package\:\:$filehandle"; 
+    }
+    $IN = "main::STDIN" unless $IN;
+
+    $CGI::DefaultClass->binmode($IN) if $CGI::needs_binmode;
+    
+    # If the user types garbage into the file upload field,
+    # then Netscape passes NOTHING to the server (not good).
+    # We may hang on this read in that case. So we implement
+    # a read timeout.  If nothing is ready to read
+    # by then, we return.
+
+    # Netscape seems to be a little bit unreliable
+    # about providing boundary strings.
+    my $boundary_read = 0;
+    if ($boundary) {
+
+	# Under the MIME spec, the boundary consists of the 
+	# characters "--" PLUS the Boundary string
+
+	# BUG: IE 3.01 on the Macintosh uses just the boundary -- not
+	# the two extra hyphens.  We do a special case here on the user-agent!!!!
+	$boundary = "--$boundary" unless CGI::user_agent('MSIE\s+3\.0[12];\s*Mac|DreamPassport');
+
+    } else { # otherwise we find it ourselves
+	my($old);
+	($old,$/) = ($/,$CRLF); # read a CRLF-delimited line
+	$boundary = <$IN>;      # BUG: This won't work correctly under mod_perl
+	$length -= length($boundary);
+	chomp($boundary);               # remove the CRLF
+	$/ = $old;                      # restore old line separator
+        $boundary_read++;
+    }
+
+    my $self = {LENGTH=>$length,
+		BOUNDARY=>$boundary,
+		IN=>$IN,
+		INTERFACE=>$interface,
+		BUFFER=>'',
+	    };
+
+    $FILLUNIT = length($boundary)
+	if length($boundary) > $FILLUNIT;
+
+    my $retval = bless $self,ref $package || $package;
+
+    # Read the preamble and the topmost (boundary) line plus the CRLF.
+    unless ($boundary_read) {
+      while ($self->read(0)) { }
+    }
+    die "Malformed multipart POST\n" if $self->eof;
+
+    return $retval;
+}
+END_OF_FUNC
+
+'readHeader' => <<'END_OF_FUNC',
+sub readHeader {
+    my($self) = @_;
+    my($end);
+    my($ok) = 0;
+    my($bad) = 0;
+
+    local($CRLF) = "\015\012" if $CGI::OS eq 'VMS';
+
+    do {
+	$self->fillBuffer($FILLUNIT);
+	$ok++ if ($end = index($self->{BUFFER},"${CRLF}${CRLF}")) >= 0;
+	$ok++ if $self->{BUFFER} eq '';
+	$bad++ if !$ok && $self->{LENGTH} <= 0;
+	# this was a bad idea
+	# $FILLUNIT *= 2 if length($self->{BUFFER}) >= $FILLUNIT; 
+    } until $ok || $bad;
+    return () if $bad;
+
+    my($header) = substr($self->{BUFFER},0,$end+2);
+    substr($self->{BUFFER},0,$end+4) = '';
+    my %return;
+
+    
+    # See RFC 2045 Appendix A and RFC 822 sections 3.4.8
+    #   (Folding Long Header Fields), 3.4.3 (Comments)
+    #   and 3.4.5 (Quoted-Strings).
+
+    my $token = '[-\w!\#$%&\'*+.^_\`|{}~]';
+    $header=~s/$CRLF\s+/ /og;		# merge continuation lines
+    while ($header=~/($token+):\s+([^$CRLF]*)/mgox) {
+	my ($field_name,$field_value) = ($1,$2); # avoid taintedness
+	$field_name =~ s/\b(\w)/uc($1)/eg; #canonicalize
+	$return{$field_name}=$field_value;
+    }
+    return %return;
+}
+END_OF_FUNC
+
+# This reads and returns the body as a single scalar value.
+'readBody' => <<'END_OF_FUNC',
+sub readBody {
+    my($self) = @_;
+    my($data);
+    my($returnval)='';
+    while (defined($data = $self->read)) {
+	$returnval .= $data;
+    }
+    return $returnval;
+}
+END_OF_FUNC
+
+# This will read $bytes or until the boundary is hit, whichever happens
+# first.  After the boundary is hit, we return undef.  The next read will
+# skip over the boundary and begin reading again;
+'read' => <<'END_OF_FUNC',
+sub read {
+    my($self,$bytes) = @_;
+
+    # default number of bytes to read
+    $bytes = $bytes || $FILLUNIT;       
+
+    # Fill up our internal buffer in such a way that the boundary
+    # is never split between reads.
+    $self->fillBuffer($bytes);
+
+    # Find the boundary in the buffer (it may not be there).
+    my $start = index($self->{BUFFER},$self->{BOUNDARY});
+    # protect against malformed multipart POST operations
+    die "Malformed multipart POST\n" unless ($start >= 0) || ($self->{LENGTH} > 0);
+
+    # If the boundary begins the data, then skip past it
+    # and return undef.
+    if ($start == 0) {
+
+	# clear us out completely if we've hit the last boundary.
+	if (index($self->{BUFFER},"$self->{BOUNDARY}--")==0) {
+	    $self->{BUFFER}='';
+	    $self->{LENGTH}=0;
+	    return undef;
+	}
+
+	# just remove the boundary.
+	substr($self->{BUFFER},0,length($self->{BOUNDARY}))='';
+        $self->{BUFFER} =~ s/^\012\015?//;
+	return undef;
+    }
+
+    my $bytesToReturn;    
+    if ($start > 0) {           # read up to the boundary
+	$bytesToReturn = $start > $bytes ? $bytes : $start;
+    } else {    # read the requested number of bytes
+	# leave enough bytes in the buffer to allow us to read
+	# the boundary.  Thanks to Kevin Hendrick for finding
+	# this one.
+	$bytesToReturn = $bytes - (length($self->{BOUNDARY})+1);
+    }
+
+    my $returnval=substr($self->{BUFFER},0,$bytesToReturn);
+    substr($self->{BUFFER},0,$bytesToReturn)='';
+    
+    # If we hit the boundary, remove the CRLF from the end.
+    return (($start > 0) && ($start <= $bytes)) 
+           ? substr($returnval,0,-2) : $returnval;
+}
+END_OF_FUNC
+
+
+# This fills up our internal buffer in such a way that the
+# boundary is never split between reads
+'fillBuffer' => <<'END_OF_FUNC',
+sub fillBuffer {
+    my($self,$bytes) = @_;
+    return unless $self->{LENGTH};
+
+    my($boundaryLength) = length($self->{BOUNDARY});
+    my($bufferLength) = length($self->{BUFFER});
+    my($bytesToRead) = $bytes - $bufferLength + $boundaryLength + 2;
+    $bytesToRead = $self->{LENGTH} if $self->{LENGTH} < $bytesToRead;
+
+    # Try to read some data.  We may hang here if the browser is screwed up.  
+    my $bytesRead = $self->{INTERFACE}->read_from_client($self->{IN},
+							 \$self->{BUFFER},
+							 $bytesToRead,
+							 $bufferLength);
+    $self->{BUFFER} = '' unless defined $self->{BUFFER};
+
+    # An apparent bug in the Apache server causes the read()
+    # to return zero bytes repeatedly without blocking if the
+    # remote user aborts during a file transfer.  I don't know how
+    # they manage this, but the workaround is to abort if we get
+    # more than SPIN_LOOP_MAX consecutive zero reads.
+    if ($bytesRead == 0) {
+	die  "CGI.pm: Server closed socket during multipart read (client aborted?).\n"
+	    if ($self->{ZERO_LOOP_COUNTER}++ >= $SPIN_LOOP_MAX);
+    } else {
+	$self->{ZERO_LOOP_COUNTER}=0;
+    }
+
+    $self->{LENGTH} -= $bytesRead;
+}
+END_OF_FUNC
+
+
+# Return true when we've finished reading
+'eof' => <<'END_OF_FUNC'
+sub eof {
+    my($self) = @_;
+    return 1 if (length($self->{BUFFER}) == 0)
+		 && ($self->{LENGTH} <= 0);
+    undef;
+}
+END_OF_FUNC
+
+);
+END_OF_AUTOLOAD
+
+####################################################################################
+################################## TEMPORARY FILES #################################
+####################################################################################
+package CGITempFile;
+
+$SL = $CGI::SL;
+$MAC = $CGI::OS eq 'MACINTOSH';
+my ($vol) = $MAC ? MacPerl::Volumes() =~ /:(.*)/ : "";
+unless ($TMPDIRECTORY) {
+    @TEMP=("${SL}usr${SL}tmp","${SL}var${SL}tmp",
+	   "C:${SL}temp","${SL}tmp","${SL}temp",
+	   "${vol}${SL}Temporary Items",
+           "${SL}WWW_ROOT", "${SL}SYS\$SCRATCH",
+	   "C:${SL}system${SL}temp");
+    unshift(@TEMP,$ENV{'TMPDIR'}) if exists $ENV{'TMPDIR'};
+
+    # this feature was supposed to provide per-user tmpfiles, but
+    # it is problematic.
+    #    unshift(@TEMP,(getpwuid($<))[7].'/tmp') if $CGI::OS eq 'UNIX';
+    # Rob: getpwuid() is unfortunately UNIX specific. On brain dead OS'es this
+    #    : can generate a 'getpwuid() not implemented' exception, even though
+    #    : it's never called.  Found under DOS/Win with the DJGPP perl port.
+    #    : Refer to getpwuid() only at run-time if we're fortunate and have  UNIX.
+    # unshift(@TEMP,(eval {(getpwuid($>))[7]}).'/tmp') if $CGI::OS eq 'UNIX' and $> != 0;
+
+    foreach (@TEMP) {
+	do {$TMPDIRECTORY = $_; last} if -d $_ && -w _;
+    }
+}
+
+$TMPDIRECTORY  = $MAC ? "" : "." unless $TMPDIRECTORY;
+$MAXTRIES = 5000;
+
+# cute feature, but overload implementation broke it
+# %OVERLOAD = ('""'=>'as_string');
+*CGITempFile::AUTOLOAD = \&CGI::AUTOLOAD;
+
+sub DESTROY {
+    my($self) = @_;
+    unlink $$self;              # get rid of the file
+}
+
+###############################################################################
+################# THESE FUNCTIONS ARE AUTOLOADED ON DEMAND ####################
+###############################################################################
+$AUTOLOADED_ROUTINES = '';      # prevent -w error
+$AUTOLOADED_ROUTINES=<<'END_OF_AUTOLOAD';
+%SUBS = (
+
+'new' => <<'END_OF_FUNC',
+sub new {
+    my($package,$sequence) = @_;
+    my $filename;
+    for (my $i = 0; $i < $MAXTRIES; $i++) {
+	last if ! -f ($filename = sprintf("${TMPDIRECTORY}${SL}CGItemp%d",$sequence++));
+    }
+    # untaint the darn thing
+    return unless $filename =~ m!^([a-zA-Z0-9_ '":/.\$\\-]+)$!;
+    $filename = $1;
+    return bless \$filename;
+}
+END_OF_FUNC
+
+'as_string' => <<'END_OF_FUNC'
+sub as_string {
+    my($self) = @_;
+    return $$self;
+}
+END_OF_FUNC
+
+);
+END_OF_AUTOLOAD
+
+package CGI;
+
+# We get a whole bunch of warnings about "possibly uninitialized variables"
+# when running with the -w switch.  Touch them all once to get rid of the
+# warnings.  This is ugly and I hate it.
+if ($^W) {
+    $CGI::CGI = '';
+    $CGI::CGI=<<EOF;
+    $CGI::VERSION;
+    $MultipartBuffer::SPIN_LOOP_MAX;
+    $MultipartBuffer::CRLF;
+    $MultipartBuffer::TIMEOUT;
+    $MultipartBuffer::INITIAL_FILLUNIT;
+EOF
+    ;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+CGI - Simple Common Gateway Interface Class
+
+=head1 SYNOPSIS
+
+  # CGI script that creates a fill-out form
+  # and echoes back its values.
+
+  use CGI qw/:standard/;
+  print header,
+        start_html('A Simple Example'),
+        h1('A Simple Example'),
+        start_form,
+        "What's your name? ",textfield('name'),p,
+        "What's the combination?", p,
+        checkbox_group(-name=>'words',
+		       -values=>['eenie','meenie','minie','moe'],
+		       -defaults=>['eenie','minie']), p,
+        "What's your favorite color? ",
+        popup_menu(-name=>'color',
+	           -values=>['red','green','blue','chartreuse']),p,
+        submit,
+        end_form,
+        hr;
+
+   if (param()) {
+       print "Your name is",em(param('name')),p,
+	     "The keywords are: ",em(join(", ",param('words'))),p,
+	     "Your favorite color is ",em(param('color')),
+	     hr;
+   }
+
+=head1 ABSTRACT
+
+This perl library uses perl5 objects to make it easy to create Web
+fill-out forms and parse their contents.  This package defines CGI
+objects, entities that contain the values of the current query string
+and other state variables.  Using a CGI object's methods, you can
+examine keywords and parameters passed to your script, and create
+forms whose initial values are taken from the current query (thereby
+preserving state information).  The module provides shortcut functions
+that produce boilerplate HTML, reducing typing and coding errors. It
+also provides functionality for some of the more advanced features of
+CGI scripting, including support for file uploads, cookies, cascading
+style sheets, server push, and frames.
+
+CGI.pm also provides a simple function-oriented programming style for
+those who don't need its object-oriented features.
+
+The current version of CGI.pm is available at
+
+  http://www.genome.wi.mit.edu/ftp/pub/software/WWW/cgi_docs.html
+  ftp://ftp-genome.wi.mit.edu/pub/software/WWW/
+
+=head1 DESCRIPTION
+
+=head2 PROGRAMMING STYLE
+
+There are two styles of programming with CGI.pm, an object-oriented
+style and a function-oriented style.  In the object-oriented style you
+create one or more CGI objects and then use object methods to create
+the various elements of the page.  Each CGI object starts out with the
+list of named parameters that were passed to your CGI script by the
+server.  You can modify the objects, save them to a file or database
+and recreate them.  Because each object corresponds to the "state" of
+the CGI script, and because each object's parameter list is
+independent of the others, this allows you to save the state of the
+script and restore it later.
+
+For example, using the object oriented style, here is how you create
+a simple "Hello World" HTML page:
+
+   #!/usr/local/bin/perl -w
+   use CGI;                             # load CGI routines
+   $q = new CGI;                        # create new CGI object
+   print $q->header,                    # create the HTTP header
+         $q->start_html('hello world'), # start the HTML
+         $q->h1('hello world'),         # level 1 header
+         $q->end_html;                  # end the HTML
+
+In the function-oriented style, there is one default CGI object that
+you rarely deal with directly.  Instead you just call functions to
+retrieve CGI parameters, create HTML tags, manage cookies, and so
+on.  This provides you with a cleaner programming interface, but
+limits you to using one CGI object at a time.  The following example
+prints the same page, but uses the function-oriented interface.
+The main differences are that we now need to import a set of functions
+into our name space (usually the "standard" functions), and we don't
+need to create the CGI object.
+
+   #!/usr/local/bin/perl
+   use CGI qw/:standard/;           # load standard CGI routines
+   print header,                    # create the HTTP header
+         start_html('hello world'), # start the HTML
+         h1('hello world'),         # level 1 header
+         end_html;                  # end the HTML
+
+The examples in this document mainly use the object-oriented style.
+See HOW TO IMPORT FUNCTIONS for important information on
+function-oriented programming in CGI.pm
+
+=head2 CALLING CGI.PM ROUTINES
+
+Most CGI.pm routines accept several arguments, sometimes as many as 20
+optional ones!  To simplify this interface, all routines use a named
+argument calling style that looks like this:
+
+   print $q->header(-type=>'image/gif',-expires=>'+3d');
+
+Each argument name is preceded by a dash.  Neither case nor order
+matters in the argument list.  -type, -Type, and -TYPE are all
+acceptable.  In fact, only the first argument needs to begin with a
+dash.  If a dash is present in the first argument, CGI.pm assumes
+dashes for the subsequent ones.
+
+Several routines are commonly called with just one argument.  In the
+case of these routines you can provide the single argument without an
+argument name.  header() happens to be one of these routines.  In this
+case, the single argument is the document type.
+
+   print $q->header('text/html');
+
+Other such routines are documented below.
+
+Sometimes named arguments expect a scalar, sometimes a reference to an
+array, and sometimes a reference to a hash.  Often, you can pass any
+type of argument and the routine will do whatever is most appropriate.
+For example, the param() routine is used to set a CGI parameter to a
+single or a multi-valued value.  The two cases are shown below:
+
+   $q->param(-name=>'veggie',-value=>'tomato');
+   $q->param(-name=>'veggie',-value=>['tomato','tomahto','potato','potahto']);
+
+A large number of routines in CGI.pm actually aren't specifically
+defined in the module, but are generated automatically as needed.
+These are the "HTML shortcuts," routines that generate HTML tags for
+use in dynamically-generated pages.  HTML tags have both attributes
+(the attribute="value" pairs within the tag itself) and contents (the
+part between the opening and closing pairs.)  To distinguish between
+attributes and contents, CGI.pm uses the convention of passing HTML
+attributes as a hash reference as the first argument, and the
+contents, if any, as any subsequent arguments.  It works out like
+this:
+
+   Code                           Generated HTML
+   ----                           --------------
+   h1()                           <h1>
+   h1('some','contents');         <h1>some contents</h1>
+   h1({-align=>left});            <h1 ALIGN="LEFT">
+   h1({-align=>left},'contents'); <h1 ALIGN="LEFT">contents</h1>
+
+HTML tags are described in more detail later.  
+
+Many newcomers to CGI.pm are puzzled by the difference between the
+calling conventions for the HTML shortcuts, which require curly braces
+around the HTML tag attributes, and the calling conventions for other
+routines, which manage to generate attributes without the curly
+brackets.  Don't be confused.  As a convenience the curly braces are
+optional in all but the HTML shortcuts.  If you like, you can use
+curly braces when calling any routine that takes named arguments.  For
+example:
+
+   print $q->header( {-type=>'image/gif',-expires=>'+3d'} );
+
+If you use the B<-w> switch, you will be warned that some CGI.pm argument
+names conflict with built-in Perl functions.  The most frequent of
+these is the -values argument, used to create multi-valued menus,
+radio button clusters and the like.  To get around this warning, you
+have several choices:
+
+=over 4
+
+=item 1.
+
+Use another name for the argument, if one is available. 
+For example, -value is an alias for -values.
+
+=item 2.
+
+Change the capitalization, e.g. -Values
+
+=item 3.
+
+Put quotes around the argument name, e.g. '-values'
+
+=back
+
+Many routines will do something useful with a named argument that it
+doesn't recognize.  For example, you can produce non-standard HTTP
+header fields by providing them as named arguments:
+
+  print $q->header(-type  =>  'text/html',
+                   -cost  =>  'Three smackers',
+                   -annoyance_level => 'high',
+                   -complaints_to   => 'bit bucket');
+
+This will produce the following nonstandard HTTP header:
+
+   HTTP/1.0 200 OK
+   Cost: Three smackers
+   Annoyance-level: high
+   Complaints-to: bit bucket
+   Content-type: text/html
+
+Notice the way that underscores are translated automatically into
+hyphens.  HTML-generating routines perform a different type of
+translation. 
+
+This feature allows you to keep up with the rapidly changing HTTP and
+HTML "standards".
+
+=head2 CREATING A NEW QUERY OBJECT (OBJECT-ORIENTED STYLE):
+
+     $query = new CGI;
+
+This will parse the input (from both POST and GET methods) and store
+it into a perl5 object called $query.  
+
+=head2 CREATING A NEW QUERY OBJECT FROM AN INPUT FILE
+
+     $query = new CGI(INPUTFILE);
+
+If you provide a file handle to the new() method, it will read
+parameters from the file (or STDIN, or whatever).  The file can be in
+any of the forms describing below under debugging (i.e. a series of
+newline delimited TAG=VALUE pairs will work).  Conveniently, this type
+of file is created by the save() method (see below).  Multiple records
+can be saved and restored.
+
+Perl purists will be pleased to know that this syntax accepts
+references to file handles, or even references to filehandle globs,
+which is the "official" way to pass a filehandle:
+
+    $query = new CGI(\*STDIN);
+
+You can also initialize the CGI object with a FileHandle or IO::File
+object.
+
+If you are using the function-oriented interface and want to
+initialize CGI state from a file handle, the way to do this is with
+B<restore_parameters()>.  This will (re)initialize the
+default CGI object from the indicated file handle.
+
+    open (IN,"test.in") || die;
+    restore_parameters(IN);
+    close IN;
+
+You can also initialize the query object from an associative array
+reference:
+
+    $query = new CGI( {'dinosaur'=>'barney',
+		       'song'=>'I love you',
+		       'friends'=>[qw/Jessica George Nancy/]}
+		    );
+
+or from a properly formatted, URL-escaped query string:
+
+    $query = new CGI('dinosaur=barney&color=purple');
+
+or from a previously existing CGI object (currently this clones the
+parameter list, but none of the other object-specific fields, such as
+autoescaping):
+
+    $old_query = new CGI;
+    $new_query = new CGI($old_query);
+
+To create an empty query, initialize it from an empty string or hash:
+
+   $empty_query = new CGI("");
+
+       -or-
+
+   $empty_query = new CGI({});
+
+=head2 FETCHING A LIST OF KEYWORDS FROM THE QUERY:
+
+     @keywords = $query->keywords
+
+If the script was invoked as the result of an <ISINDEX> search, the
+parsed keywords can be obtained as an array using the keywords() method.
+
+=head2 FETCHING THE NAMES OF ALL THE PARAMETERS PASSED TO YOUR SCRIPT:
+
+     @names = $query->param
+
+If the script was invoked with a parameter list
+(e.g. "name1=value1&name2=value2&name3=value3"), the param() method
+will return the parameter names as a list.  If the script was invoked
+as an <ISINDEX> script and contains a string without ampersands
+(e.g. "value1+value2+value3") , there will be a single parameter named
+"keywords" containing the "+"-delimited keywords.
+
+NOTE: As of version 1.5, the array of parameter names returned will
+be in the same order as they were submitted by the browser.
+Usually this order is the same as the order in which the 
+parameters are defined in the form (however, this isn't part
+of the spec, and so isn't guaranteed).
+
+=head2 FETCHING THE VALUE OR VALUES OF A SINGLE NAMED PARAMETER:
+
+    @values = $query->param('foo');
+
+	      -or-
+
+    $value = $query->param('foo');
+
+Pass the param() method a single argument to fetch the value of the
+named parameter. If the parameter is multivalued (e.g. from multiple
+selections in a scrolling list), you can ask to receive an array.  Otherwise
+the method will return a single value.
+
+If a value is not given in the query string, as in the queries
+"name1=&name2=" or "name1&name2", it will be returned as an empty
+string.  This feature is new in 2.63.
+
+=head2 SETTING THE VALUE(S) OF A NAMED PARAMETER:
+
+    $query->param('foo','an','array','of','values');
+
+This sets the value for the named parameter 'foo' to an array of
+values.  This is one way to change the value of a field AFTER
+the script has been invoked once before.  (Another way is with
+the -override parameter accepted by all methods that generate
+form elements.)
+
+param() also recognizes a named parameter style of calling described
+in more detail later:
+
+    $query->param(-name=>'foo',-values=>['an','array','of','values']);
+
+			      -or-
+
+    $query->param(-name=>'foo',-value=>'the value');
+
+=head2 APPENDING ADDITIONAL VALUES TO A NAMED PARAMETER:
+
+   $query->append(-name=>'foo',-values=>['yet','more','values']);
+
+This adds a value or list of values to the named parameter.  The
+values are appended to the end of the parameter if it already exists.
+Otherwise the parameter is created.  Note that this method only
+recognizes the named argument calling syntax.
+
+=head2 IMPORTING ALL PARAMETERS INTO A NAMESPACE:
+
+   $query->import_names('R');
+
+This creates a series of variables in the 'R' namespace.  For example,
+$R::foo, @R:foo.  For keyword lists, a variable @R::keywords will appear.
+If no namespace is given, this method will assume 'Q'.
+WARNING:  don't import anything into 'main'; this is a major security
+risk!!!!
+
+In older versions, this method was called B<import()>.  As of version 2.20, 
+this name has been removed completely to avoid conflict with the built-in
+Perl module B<import> operator.
+
+=head2 DELETING A PARAMETER COMPLETELY:
+
+    $query->delete('foo');
+
+This completely clears a parameter.  It sometimes useful for
+resetting parameters that you don't want passed down between
+script invocations.
+
+If you are using the function call interface, use "Delete()" instead
+to avoid conflicts with Perl's built-in delete operator.
+
+=head2 DELETING ALL PARAMETERS:
+
+   $query->delete_all();
+
+This clears the CGI object completely.  It might be useful to ensure
+that all the defaults are taken when you create a fill-out form.
+
+Use Delete_all() instead if you are using the function call interface.
+
+=head2 DIRECT ACCESS TO THE PARAMETER LIST:
+
+   $q->param_fetch('address')->[1] = '1313 Mockingbird Lane';
+   unshift @{$q->param_fetch(-name=>'address')},'George Munster';
+
+If you need access to the parameter list in a way that isn't covered
+by the methods above, you can obtain a direct reference to it by
+calling the B<param_fetch()> method with the name of the .  This
+will return an array reference to the named parameters, which you then
+can manipulate in any way you like.
+
+You can also use a named argument style using the B<-name> argument.
+
+=head2 FETCHING THE PARAMETER LIST AS A HASH:
+
+    $params = $q->Vars;
+    print $params->{'address'};
+    @foo = split("\0",$params->{'foo'});
+    %params = $q->Vars;
+
+    use CGI ':cgi-lib';
+    $params = Vars;
+
+Many people want to fetch the entire parameter list as a hash in which
+the keys are the names of the CGI parameters, and the values are the
+parameters' values.  The Vars() method does this.  Called in a scalar
+context, it returns the parameter list as a tied hash reference.
+Changing a key changes the value of the parameter in the underlying
+CGI parameter list.  Called in a list context, it returns the
+parameter list as an ordinary hash.  This allows you to read the
+contents of the parameter list, but not to change it.
+
+When using this, the thing you must watch out for are multivalued CGI
+parameters.  Because a hash cannot distinguish between scalar and
+list context, multivalued parameters will be returned as a packed
+string, separated by the "\0" (null) character.  You must split this
+packed string in order to get at the individual values.  This is the
+convention introduced long ago by Steve Brenner in his cgi-lib.pl
+module for Perl version 4.
+
+If you wish to use Vars() as a function, import the I<:cgi-lib> set of
+function calls (also see the section on CGI-LIB compatibility).
+
+=head2 SAVING THE STATE OF THE SCRIPT TO A FILE:
+
+    $query->save(FILEHANDLE)
+
+This will write the current state of the form to the provided
+filehandle.  You can read it back in by providing a filehandle
+to the new() method.  Note that the filehandle can be a file, a pipe,
+or whatever!
+
+The format of the saved file is:
+
+	NAME1=VALUE1
+	NAME1=VALUE1'
+	NAME2=VALUE2
+	NAME3=VALUE3
+	=
+
+Both name and value are URL escaped.  Multi-valued CGI parameters are
+represented as repeated names.  A session record is delimited by a
+single = symbol.  You can write out multiple records and read them
+back in with several calls to B<new>.  You can do this across several
+sessions by opening the file in append mode, allowing you to create
+primitive guest books, or to keep a history of users' queries.  Here's
+a short example of creating multiple session records:
+
+   use CGI;
+
+   open (OUT,">>test.out") || die;
+   $records = 5;
+   foreach (0..$records) {
+       my $q = new CGI;
+       $q->param(-name=>'counter',-value=>$_);
+       $q->save(OUT);
+   }
+   close OUT;
+
+   # reopen for reading
+   open (IN,"test.out") || die;
+   while (!eof(IN)) {
+       my $q = new CGI(IN);
+       print $q->param('counter'),"\n";
+   }
+
+The file format used for save/restore is identical to that used by the
+Whitehead Genome Center's data exchange format "Boulderio", and can be
+manipulated and even databased using Boulderio utilities.  See
+
+  http://stein.cshl.org/boulder/
+
+for further details.
+
+If you wish to use this method from the function-oriented (non-OO)
+interface, the exported name for this method is B<save_parameters()>.
+
+=head2 RETRIEVING CGI ERRORS
+
+Errors can occur while processing user input, particularly when
+processing uploaded files.  When these errors occur, CGI will stop
+processing and return an empty parameter list.  You can test for
+the existence and nature of errors using the I<cgi_error()> function.
+The error messages are formatted as HTTP status codes. You can either
+incorporate the error text into an HTML page, or use it as the value
+of the HTTP status:
+
+    my $error = $q->cgi_error;
+    if ($error) {
+	print $q->header(-status=>$error),
+	      $q->start_html('Problems'),
+              $q->h2('Request not processed'),
+	      $q->strong($error);
+        exit 0;
+    }
+
+When using the function-oriented interface (see the next section),
+errors may only occur the first time you call I<param()>. Be ready
+for this!
+
+=head2 USING THE FUNCTION-ORIENTED INTERFACE
+
+To use the function-oriented interface, you must specify which CGI.pm
+routines or sets of routines to import into your script's namespace.
+There is a small overhead associated with this importation, but it
+isn't much.
+
+   use CGI <list of methods>;
+
+The listed methods will be imported into the current package; you can
+call them directly without creating a CGI object first.  This example
+shows how to import the B<param()> and B<header()>
+methods, and then use them directly:
+
+   use CGI 'param','header';
+   print header('text/plain');
+   $zipcode = param('zipcode');
+
+More frequently, you'll import common sets of functions by referring
+to the groups by name.  All function sets are preceded with a ":"
+character as in ":html3" (for tags defined in the HTML 3 standard).
+
+Here is a list of the function sets you can import:
+
+=over 4
+
+=item B<:cgi>
+
+Import all CGI-handling methods, such as B<param()>, B<path_info()>
+and the like.
+
+=item B<:form>
+
+Import all fill-out form generating methods, such as B<textfield()>.
+
+=item B<:html2>
+
+Import all methods that generate HTML 2.0 standard elements.
+
+=item B<:html3>
+
+Import all methods that generate HTML 3.0 elements (such as
+<table>, <super> and <sub>).
+
+=item B<:html4>
+
+Import all methods that generate HTML 4 elements (such as
+<abbrev>, <acronym> and <thead>).
+
+=item B<:netscape>
+
+Import all methods that generate Netscape-specific HTML extensions.
+
+=item B<:html>
+
+Import all HTML-generating shortcuts (i.e. 'html2' + 'html3' +
+'netscape')...
+
+=item B<:standard>
+
+Import "standard" features, 'html2', 'html3', 'html4', 'form' and 'cgi'.
+
+=item B<:all>
+
+Import all the available methods.  For the full list, see the CGI.pm
+code, where the variable %EXPORT_TAGS is defined.
+
+=back
+
+If you import a function name that is not part of CGI.pm, the module
+will treat it as a new HTML tag and generate the appropriate
+subroutine.  You can then use it like any other HTML tag.  This is to
+provide for the rapidly-evolving HTML "standard."  For example, say
+Microsoft comes out with a new tag called <gradient> (which causes the
+user's desktop to be flooded with a rotating gradient fill until his
+machine reboots).  You don't need to wait for a new version of CGI.pm
+to start using it immediately:
+
+   use CGI qw/:standard :html3 gradient/;
+   print gradient({-start=>'red',-end=>'blue'});
+
+Note that in the interests of execution speed CGI.pm does B<not> use
+the standard L<Exporter> syntax for specifying load symbols.  This may
+change in the future.
+
+If you import any of the state-maintaining CGI or form-generating
+methods, a default CGI object will be created and initialized
+automatically the first time you use any of the methods that require
+one to be present.  This includes B<param()>, B<textfield()>,
+B<submit()> and the like.  (If you need direct access to the CGI
+object, you can find it in the global variable B<$CGI::Q>).  By
+importing CGI.pm methods, you can create visually elegant scripts:
+
+   use CGI qw/:standard/;
+   print 
+       header,
+       start_html('Simple Script'),
+       h1('Simple Script'),
+       start_form,
+       "What's your name? ",textfield('name'),p,
+       "What's the combination?",
+       checkbox_group(-name=>'words',
+		      -values=>['eenie','meenie','minie','moe'],
+		      -defaults=>['eenie','moe']),p,
+       "What's your favorite color?",
+       popup_menu(-name=>'color',
+		  -values=>['red','green','blue','chartreuse']),p,
+       submit,
+       end_form,
+       hr,"\n";
+
+    if (param) {
+       print 
+	   "Your name is ",em(param('name')),p,
+	   "The keywords are: ",em(join(", ",param('words'))),p,
+	   "Your favorite color is ",em(param('color')),".\n";
+    }
+    print end_html;
+
+=head2 PRAGMAS
+
+In addition to the function sets, there are a number of pragmas that
+you can import.  Pragmas, which are always preceded by a hyphen,
+change the way that CGI.pm functions in various ways.  Pragmas,
+function sets, and individual functions can all be imported in the
+same use() line.  For example, the following use statement imports the
+standard set of functions and enables debugging mode (pragma
+-debug):
+
+   use CGI qw/:standard -debug/;
+
+The current list of pragmas is as follows:
+
+=over 4
+
+=item -any
+
+When you I<use CGI -any>, then any method that the query object
+doesn't recognize will be interpreted as a new HTML tag.  This allows
+you to support the next I<ad hoc> Netscape or Microsoft HTML
+extension.  This lets you go wild with new and unsupported tags:
+
+   use CGI qw(-any);
+   $q=new CGI;
+   print $q->gradient({speed=>'fast',start=>'red',end=>'blue'});
+
+Since using <cite>any</cite> causes any mistyped method name
+to be interpreted as an HTML tag, use it with care or not at
+all.
+
+=item -compile
+
+This causes the indicated autoloaded methods to be compiled up front,
+rather than deferred to later.  This is useful for scripts that run
+for an extended period of time under FastCGI or mod_perl, and for
+those destined to be crunched by Malcom Beattie's Perl compiler.  Use
+it in conjunction with the methods or method families you plan to use.
+
+   use CGI qw(-compile :standard :html3);
+
+or even
+
+   use CGI qw(-compile :all);
+
+Note that using the -compile pragma in this way will always have
+the effect of importing the compiled functions into the current
+namespace.  If you want to compile without importing use the
+compile() method instead (see below).
+
+=item -nosticky
+
+This makes CGI.pm not generating the hidden fields .submit
+and .cgifields. It is very useful if you don't want to
+have the hidden fields appear in the querystring in a GET method.
+For example, a search script generated this way will have
+a very nice url with search parameters for bookmarking.
+
+=item -no_undef_params
+
+This keeps CGI.pm from including undef params in the parameter list.
+
+=item -no_xhtml
+
+By default, CGI.pm versions 2.69 and higher emit XHTML
+(http://www.w3.org/TR/xhtml1/).  The -no_xhtml pragma disables this
+feature.  Thanks to Michalis Kabrianis <kabrianis@hellug.gr> for this
+feature.
+
+=item -nph
+
+This makes CGI.pm produce a header appropriate for an NPH (no
+parsed header) script.  You may need to do other things as well
+to tell the server that the script is NPH.  See the discussion
+of NPH scripts below.
+
+=item -newstyle_urls
+
+Separate the name=value pairs in CGI parameter query strings with
+semicolons rather than ampersands.  For example:
+
+   ?name=fred;age=24;favorite_color=3
+
+Semicolon-delimited query strings are always accepted, but will not be
+emitted by self_url() and query_string() unless the -newstyle_urls
+pragma is specified.
+
+This became the default in version 2.64.
+
+=item -oldstyle_urls
+
+Separate the name=value pairs in CGI parameter query strings with
+ampersands rather than semicolons.  This is no longer the default.
+
+=item -autoload
+
+This overrides the autoloader so that any function in your program
+that is not recognized is referred to CGI.pm for possible evaluation.
+This allows you to use all the CGI.pm functions without adding them to
+your symbol table, which is of concern for mod_perl users who are
+worried about memory consumption.  I<Warning:> when
+I<-autoload> is in effect, you cannot use "poetry mode"
+(functions without the parenthesis).  Use I<hr()> rather
+than I<hr>, or add something like I<use subs qw/hr p header/> 
+to the top of your script.
+
+=item -no_debug
+
+This turns off the command-line processing features.  If you want to
+run a CGI.pm script from the command line to produce HTML, and you
+don't want it to read CGI parameters from the command line or STDIN,
+then use this pragma:
+
+   use CGI qw(-no_debug :standard);
+
+=item -debug
+
+This turns on full debugging.  In addition to reading CGI arguments
+from the command-line processing, CGI.pm will pause and try to read
+arguments from STDIN, producing the message "(offline mode: enter
+name=value pairs on standard input)" features.
+
+See the section on debugging for more details.
+
+=item -private_tempfiles
+
+CGI.pm can process uploaded file. Ordinarily it spools the uploaded
+file to a temporary directory, then deletes the file when done.
+However, this opens the risk of eavesdropping as described in the file
+upload section.  Another CGI script author could peek at this data
+during the upload, even if it is confidential information. On Unix
+systems, the -private_tempfiles pragma will cause the temporary file
+to be unlinked as soon as it is opened and before any data is written
+into it, reducing, but not eliminating the risk of eavesdropping
+(there is still a potential race condition).  To make life harder for
+the attacker, the program chooses tempfile names by calculating a 32
+bit checksum of the incoming HTTP headers.
+
+To ensure that the temporary file cannot be read by other CGI scripts,
+use suEXEC or a CGI wrapper program to run your script.  The temporary
+file is created with mode 0600 (neither world nor group readable).
+
+The temporary directory is selected using the following algorithm:
+
+    1. if the current user (e.g. "nobody") has a directory named
+    "tmp" in its home directory, use that (Unix systems only).
+
+    2. if the environment variable TMPDIR exists, use the location
+    indicated.
+
+    3. Otherwise try the locations /usr/tmp, /var/tmp, C:\temp,
+    /tmp, /temp, ::Temporary Items, and \WWW_ROOT.
+
+Each of these locations is checked that it is a directory and is
+writable.  If not, the algorithm tries the next choice.
+
+=back
+
+=head2 SPECIAL FORMS FOR IMPORTING HTML-TAG FUNCTIONS
+
+Many of the methods generate HTML tags.  As described below, tag
+functions automatically generate both the opening and closing tags.
+For example:
+
+  print h1('Level 1 Header');
+
+produces
+
+  <h1>Level 1 Header</h1>
+
+There will be some times when you want to produce the start and end
+tags yourself.  In this case, you can use the form start_I<tag_name>
+and end_I<tag_name>, as in:
+
+  print start_h1,'Level 1 Header',end_h1;
+
+With a few exceptions (described below), start_I<tag_name> and
+end_I<tag_name> functions are not generated automatically when you
+I<use CGI>.  However, you can specify the tags you want to generate
+I<start/end> functions for by putting an asterisk in front of their
+name, or, alternatively, requesting either "start_I<tag_name>" or
+"end_I<tag_name>" in the import list.
+
+Example:
+
+  use CGI qw/:standard *table start_ul/;
+
+In this example, the following functions are generated in addition to
+the standard ones:
+
+=over 4
+
+=item 1. start_table() (generates a <table> tag)
+
+=item 2. end_table() (generates a </table> tag)
+
+=item 3. start_ul() (generates a <ul> tag)
+
+=item 4. end_ul() (generates a </ul> tag)
+
+=back
+
+=head1 GENERATING DYNAMIC DOCUMENTS
+
+Most of CGI.pm's functions deal with creating documents on the fly.
+Generally you will produce the HTTP header first, followed by the
+document itself.  CGI.pm provides functions for generating HTTP
+headers of various types as well as for generating HTML.  For creating
+GIF images, see the GD.pm module.
+
+Each of these functions produces a fragment of HTML or HTTP which you
+can print out directly so that it displays in the browser window,
+append to a string, or save to a file for later use.
+
+=head2 CREATING A STANDARD HTTP HEADER:
+
+Normally the first thing you will do in any CGI script is print out an
+HTTP header.  This tells the browser what type of document to expect,
+and gives other optional information, such as the language, expiration
+date, and whether to cache the document.  The header can also be
+manipulated for special purposes, such as server push and pay per view
+pages.
+
+	print $query->header;
+
+	     -or-
+
+	print $query->header('image/gif');
+
+	     -or-
+
+	print $query->header('text/html','204 No response');
+
+	     -or-
+
+	print $query->header(-type=>'image/gif',
+			     -nph=>1,
+			     -status=>'402 Payment required',
+			     -expires=>'+3d',
+			     -cookie=>$cookie,
+                             -charset=>'utf-7',
+                             -attachment=>'foo.gif',
+			     -Cost=>'$2.00');
+
+header() returns the Content-type: header.  You can provide your own
+MIME type if you choose, otherwise it defaults to text/html.  An
+optional second parameter specifies the status code and a human-readable
+message.  For example, you can specify 204, "No response" to create a
+script that tells the browser to do nothing at all.
+
+The last example shows the named argument style for passing arguments
+to the CGI methods using named parameters.  Recognized parameters are
+B<-type>, B<-status>, B<-expires>, and B<-cookie>.  Any other named
+parameters will be stripped of their initial hyphens and turned into
+header fields, allowing you to specify any HTTP header you desire.
+Internal underscores will be turned into hyphens:
+
+    print $query->header(-Content_length=>3002);
+
+Most browsers will not cache the output from CGI scripts.  Every time
+the browser reloads the page, the script is invoked anew.  You can
+change this behavior with the B<-expires> parameter.  When you specify
+an absolute or relative expiration interval with this parameter, some
+browsers and proxy servers will cache the script's output until the
+indicated expiration date.  The following forms are all valid for the
+-expires field:
+
+	+30s                              30 seconds from now
+	+10m                              ten minutes from now
+	+1h                               one hour from now
+	-1d                               yesterday (i.e. "ASAP!")
+	now                               immediately
+	+3M                               in three months
+	+10y                              in ten years time
+	Thursday, 25-Apr-1999 00:40:33 GMT  at the indicated time & date
+
+The B<-cookie> parameter generates a header that tells the browser to provide
+a "magic cookie" during all subsequent transactions with your script.
+Netscape cookies have a special format that includes interesting attributes
+such as expiration time.  Use the cookie() method to create and retrieve
+session cookies.
+
+The B<-nph> parameter, if set to a true value, will issue the correct
+headers to work with an NPH (no-parse-header) script.  This is important
+to use with certain servers that expect all their scripts to be NPH.
+
+The B<-charset> parameter can be used to control the character set
+sent to the browser.  If not provided, defaults to ISO-8859-1.  As a
+side effect, this sets the charset() method as well.
+
+The B<-attachment> parameter can be used to turn the page into an
+attachment.  Instead of displaying the page, some browsers will prompt
+the user to save it to disk.  The value of the argument is the
+suggested name for the saved file.  In order for this to work, you may
+have to set the B<-type> to "application/octet-stream".
+
+=head2 GENERATING A REDIRECTION HEADER
+
+   print $query->redirect('http://somewhere.else/in/movie/land');
+
+Sometimes you don't want to produce a document yourself, but simply
+redirect the browser elsewhere, perhaps choosing a URL based on the
+time of day or the identity of the user.  
+
+The redirect() function redirects the browser to a different URL.  If
+you use redirection like this, you should B<not> print out a header as
+well.
+
+One hint I can offer is that relative links may not work correctly
+when you generate a redirection to another document on your site.
+This is due to a well-intentioned optimization that some servers use.
+The solution to this is to use the full URL (including the http: part)
+of the document you are redirecting to.
+
+You can also use named arguments:
+
+    print $query->redirect(-uri=>'http://somewhere.else/in/movie/land',
+			   -nph=>1);
+
+The B<-nph> parameter, if set to a true value, will issue the correct
+headers to work with an NPH (no-parse-header) script.  This is important
+to use with certain servers, such as Microsoft Internet Explorer, which
+expect all their scripts to be NPH.
+
+=head2 CREATING THE HTML DOCUMENT HEADER
+
+   print $query->start_html(-title=>'Secrets of the Pyramids',
+			    -author=>'fred@capricorn.org',
+			    -base=>'true',
+			    -target=>'_blank',
+			    -meta=>{'keywords'=>'pharaoh secret mummy',
+				    'copyright'=>'copyright 1996 King Tut'},
+			    -style=>{'src'=>'/styles/style1.css'},
+			    -BGCOLOR=>'blue');
+
+After creating the HTTP header, most CGI scripts will start writing
+out an HTML document.  The start_html() routine creates the top of the
+page, along with a lot of optional information that controls the
+page's appearance and behavior.
+
+This method returns a canned HTML header and the opening <body> tag.
+All parameters are optional.  In the named parameter form, recognized
+parameters are -title, -author, -base, -xbase, -dtd, -lang and -target
+(see below for the explanation).  Any additional parameters you
+provide, such as the Netscape unofficial BGCOLOR attribute, are added
+to the <body> tag.  Additional parameters must be proceeded by a
+hyphen.
+
+The argument B<-xbase> allows you to provide an HREF for the <base> tag
+different from the current location, as in
+
+    -xbase=>"http://home.mcom.com/"
+
+All relative links will be interpreted relative to this tag.
+
+The argument B<-target> allows you to provide a default target frame
+for all the links and fill-out forms on the page.  B<This is a
+non-standard HTTP feature which only works with Netscape browsers!>
+See the Netscape documentation on frames for details of how to
+manipulate this.
+
+    -target=>"answer_window"
+
+All relative links will be interpreted relative to this tag.
+You add arbitrary meta information to the header with the B<-meta>
+argument.  This argument expects a reference to an associative array
+containing name/value pairs of meta information.  These will be turned
+into a series of header <meta> tags that look something like this:
+
+    <meta name="keywords" content="pharaoh secret mummy">
+    <meta name="description" content="copyright 1996 King Tut">
+
+To create an HTTP-EQUIV type of <meta> tag, use B<-head>, described
+below.
+
+The B<-style> argument is used to incorporate cascading stylesheets
+into your code.  See the section on CASCADING STYLESHEETS for more
+information.
+
+The B<-lang> argument is used to incorporate a language attribute into
+the <html> tag.  The default if not specified is "en-US" for US
+English.  For example:
+
+    print $q->start_html(-lang=>'fr-CA');
+
+The B<-encoding> argument can be used to specify the character set for
+XHTML.  It defaults to iso-8859-1 if not specified.
+
+You can place other arbitrary HTML elements to the <head> section with the
+B<-head> tag.  For example, to place the rarely-used <link> element in the
+head section, use this:
+
+    print start_html(-head=>Link({-rel=>'next',
+		                  -href=>'http://www.capricorn.com/s2.html'}));
+
+To incorporate multiple HTML elements into the <head> section, just pass an
+array reference:
+
+    print start_html(-head=>[ 
+                             Link({-rel=>'next',
+				   -href=>'http://www.capricorn.com/s2.html'}),
+		             Link({-rel=>'previous',
+				   -href=>'http://www.capricorn.com/s1.html'})
+			     ]
+		     );
+
+And here's how to create an HTTP-EQUIV <meta> tag:
+
+      print start_html(-head=>meta({-http_equiv => 'Content-Type',
+                                    -content    => 'text/html'}))
+
+
+JAVASCRIPTING: The B<-script>, B<-noScript>, B<-onLoad>,
+B<-onMouseOver>, B<-onMouseOut> and B<-onUnload> parameters are used
+to add Netscape JavaScript calls to your pages.  B<-script> should
+point to a block of text containing JavaScript function definitions.
+This block will be placed within a <script> block inside the HTML (not
+HTTP) header.  The block is placed in the header in order to give your
+page a fighting chance of having all its JavaScript functions in place
+even if the user presses the stop button before the page has loaded
+completely.  CGI.pm attempts to format the script in such a way that
+JavaScript-naive browsers will not choke on the code: unfortunately
+there are some browsers, such as Chimera for Unix, that get confused
+by it nevertheless.
+
+The B<-onLoad> and B<-onUnload> parameters point to fragments of JavaScript
+code to execute when the page is respectively opened and closed by the
+browser.  Usually these parameters are calls to functions defined in the
+B<-script> field:
+
+      $query = new CGI;
+      print $query->header;
+      $JSCRIPT=<<END;
+      // Ask a silly question
+      function riddle_me_this() {
+	 var r = prompt("What walks on four legs in the morning, " +
+		       "two legs in the afternoon, " +
+		       "and three legs in the evening?");
+	 response(r);
+      }
+      // Get a silly answer
+      function response(answer) {
+	 if (answer == "man")
+	    alert("Right you are!");
+	 else
+	    alert("Wrong!  Guess again.");
+      }
+      END
+      print $query->start_html(-title=>'The Riddle of the Sphinx',
+			       -script=>$JSCRIPT);
+
+Use the B<-noScript> parameter to pass some HTML text that will be displayed on 
+browsers that do not have JavaScript (or browsers where JavaScript is turned
+off).
+
+Netscape 3.0 recognizes several attributes of the <script> tag,
+including LANGUAGE and SRC.  The latter is particularly interesting,
+as it allows you to keep the JavaScript code in a file or CGI script
+rather than cluttering up each page with the source.  To use these
+attributes pass a HASH reference in the B<-script> parameter containing
+one or more of -language, -src, or -code:
+
+    print $q->start_html(-title=>'The Riddle of the Sphinx',
+			 -script=>{-language=>'JAVASCRIPT',
+                                   -src=>'/javascript/sphinx.js'}
+			 );
+
+    print $q->(-title=>'The Riddle of the Sphinx',
+	       -script=>{-language=>'PERLSCRIPT',
+			 -code=>'print "hello world!\n;"'}
+	       );
+
+
+A final feature allows you to incorporate multiple <script> sections into the
+header.  Just pass the list of script sections as an array reference.
+this allows you to specify different source files for different dialects
+of JavaScript.  Example:     
+
+     print $q->start_html(-title=>'The Riddle of the Sphinx',
+                          -script=>[
+                                    { -language => 'JavaScript1.0',
+                                      -src      => '/javascript/utilities10.js'
+                                    },
+                                    { -language => 'JavaScript1.1',
+                                      -src      => '/javascript/utilities11.js'
+                                    },
+                                    { -language => 'JavaScript1.2',
+                                      -src      => '/javascript/utilities12.js'
+                                    },
+                                    { -language => 'JavaScript28.2',
+                                      -src      => '/javascript/utilities219.js'
+                                    }
+                                 ]
+                             );
+
+If this looks a bit extreme, take my advice and stick with straight CGI scripting.  
+
+See
+
+   http://home.netscape.com/eng/mozilla/2.0/handbook/javascript/
+
+for more information about JavaScript.
+
+The old-style positional parameters are as follows:
+
+=over 4
+
+=item B<Parameters:>
+
+=item 1.
+
+The title
+
+=item 2.
+
+The author's e-mail address (will create a <link rev="MADE"> tag if present
+
+=item 3.
+
+A 'true' flag if you want to include a <base> tag in the header.  This
+helps resolve relative addresses to absolute ones when the document is moved, 
+but makes the document hierarchy non-portable.  Use with care!
+
+=item 4, 5, 6...
+
+Any other parameters you want to include in the <body> tag.  This is a good
+place to put Netscape extensions, such as colors and wallpaper patterns.
+
+=back
+
+=head2 ENDING THE HTML DOCUMENT:
+
+	print $query->end_html
+
+This ends an HTML document by printing the </body></html> tags.
+
+=head2 CREATING A SELF-REFERENCING URL THAT PRESERVES STATE INFORMATION:
+
+    $myself = $query->self_url;
+    print q(<a href="$myself">I'm talking to myself.</a>);
+
+self_url() will return a URL, that, when selected, will reinvoke
+this script with all its state information intact.  This is most
+useful when you want to jump around within the document using
+internal anchors but you don't want to disrupt the current contents
+of the form(s).  Something like this will do the trick.
+
+     $myself = $query->self_url;
+     print "<a href=$myself#table1>See table 1</a>";
+     print "<a href=$myself#table2>See table 2</a>";
+     print "<a href=$myself#yourself>See for yourself</a>";
+
+If you want more control over what's returned, using the B<url()>
+method instead.
+
+You can also retrieve the unprocessed query string with query_string():
+
+    $the_string = $query->query_string;
+
+=head2 OBTAINING THE SCRIPT'S URL
+
+    $full_url      = $query->url();
+    $full_url      = $query->url(-full=>1);  #alternative syntax
+    $relative_url  = $query->url(-relative=>1);
+    $absolute_url  = $query->url(-absolute=>1);
+    $url_with_path = $query->url(-path_info=>1);
+    $url_with_path_and_query = $query->url(-path_info=>1,-query=>1);
+    $netloc        = $query->url(-base => 1);
+
+B<url()> returns the script's URL in a variety of formats.  Called
+without any arguments, it returns the full form of the URL, including
+host name and port number
+
+    http://your.host.com/path/to/script.cgi
+
+You can modify this format with the following named arguments:
+
+=over 4
+
+=item B<-absolute>
+
+If true, produce an absolute URL, e.g.
+
+    /path/to/script.cgi
+
+=item B<-relative>
+
+Produce a relative URL.  This is useful if you want to reinvoke your
+script with different parameters. For example:
+
+    script.cgi
+
+=item B<-full>
+
+Produce the full URL, exactly as if called without any arguments.
+This overrides the -relative and -absolute arguments.
+
+=item B<-path> (B<-path_info>)
+
+Append the additional path information to the URL.  This can be
+combined with B<-full>, B<-absolute> or B<-relative>.  B<-path_info>
+is provided as a synonym.
+
+=item B<-query> (B<-query_string>)
+
+Append the query string to the URL.  This can be combined with
+B<-full>, B<-absolute> or B<-relative>.  B<-query_string> is provided
+as a synonym.
+
+=item B<-base>
+
+Generate just the protocol and net location, as in http://www.foo.com:8000
+
+=back
+
+=head2 MIXING POST AND URL PARAMETERS
+
+   $color = $query-&gt;url_param('color');
+
+It is possible for a script to receive CGI parameters in the URL as
+well as in the fill-out form by creating a form that POSTs to a URL
+containing a query string (a "?" mark followed by arguments).  The
+B<param()> method will always return the contents of the POSTed
+fill-out form, ignoring the URL's query string.  To retrieve URL
+parameters, call the B<url_param()> method.  Use it in the same way as
+B<param()>.  The main difference is that it allows you to read the
+parameters, but not set them.
+
+
+Under no circumstances will the contents of the URL query string
+interfere with similarly-named CGI parameters in POSTed forms.  If you
+try to mix a URL query string with a form submitted with the GET
+method, the results will not be what you expect.
+
+=head1 CREATING STANDARD HTML ELEMENTS:
+
+CGI.pm defines general HTML shortcut methods for most, if not all of
+the HTML 3 and HTML 4 tags.  HTML shortcuts are named after a single
+HTML element and return a fragment of HTML text that you can then
+print or manipulate as you like.  Each shortcut returns a fragment of
+HTML code that you can append to a string, save to a file, or, most
+commonly, print out so that it displays in the browser window.
+
+This example shows how to use the HTML methods:
+
+   $q = new CGI;
+   print $q->blockquote(
+		     "Many years ago on the island of",
+		     $q->a({href=>"http://crete.org/"},"Crete"),
+		     "there lived a Minotaur named",
+		     $q->strong("Fred."),
+		    ),
+       $q->hr;
+
+This results in the following HTML code (extra newlines have been
+added for readability):
+
+   <blockquote>
+   Many years ago on the island of
+   <a href="http://crete.org/">Crete</a> there lived
+   a minotaur named <strong>Fred.</strong> 
+   </blockquote>
+   <hr>
+
+If you find the syntax for calling the HTML shortcuts awkward, you can
+import them into your namespace and dispense with the object syntax
+completely (see the next section for more details):
+
+   use CGI ':standard';
+   print blockquote(
+      "Many years ago on the island of",
+      a({href=>"http://crete.org/"},"Crete"),
+      "there lived a minotaur named",
+      strong("Fred."),
+      ),
+      hr;
+
+=head2 PROVIDING ARGUMENTS TO HTML SHORTCUTS
+
+The HTML methods will accept zero, one or multiple arguments.  If you
+provide no arguments, you get a single tag:
+
+   print hr;  	#  <hr>
+
+If you provide one or more string arguments, they are concatenated
+together with spaces and placed between opening and closing tags:
+
+   print h1("Chapter","1"); # <h1>Chapter 1</h1>"
+
+If the first argument is an associative array reference, then the keys
+and values of the associative array become the HTML tag's attributes:
+
+   print a({-href=>'fred.html',-target=>'_new'},
+      "Open a new frame");
+
+	    <a href="fred.html",target="_new">Open a new frame</a>
+
+You may dispense with the dashes in front of the attribute names if
+you prefer:
+
+   print img {src=>'fred.gif',align=>'LEFT'};
+
+	   <img align="LEFT" src="fred.gif">
+
+Sometimes an HTML tag attribute has no argument.  For example, ordered
+lists can be marked as COMPACT.  The syntax for this is an argument
+that points to an undef string:
+
+   print ol({compact=>undef},li('one'),li('two'),li('three'));
+
+Prior to CGI.pm version 2.41, providing an empty ('') string as an
+attribute argument was the same as providing undef.  However, this has
+changed in order to accommodate those who want to create tags of the form
+<img alt="">.  The difference is shown in these two pieces of code:
+
+     CODE                   RESULT
+     img({alt=>undef})      <img alt>
+     img({alt=>''})         <img alt="">
+
+=head2 THE DISTRIBUTIVE PROPERTY OF HTML SHORTCUTS
+
+One of the cool features of the HTML shortcuts is that they are
+distributive.  If you give them an argument consisting of a
+B<reference> to a list, the tag will be distributed across each
+element of the list.  For example, here's one way to make an ordered
+list:
+
+   print ul(
+             li({-type=>'disc'},['Sneezy','Doc','Sleepy','Happy'])
+           );
+
+This example will result in HTML output that looks like this:
+
+   <ul>
+     <li type="disc">Sneezy</li>
+     <li type="disc">Doc</li>
+     <li type="disc">Sleepy</li>
+     <li type="disc">Happy</li>
+   </ul>
+
+This is extremely useful for creating tables.  For example:
+
+   print table({-border=>undef},
+           caption('When Should You Eat Your Vegetables?'),
+           Tr({-align=>CENTER,-valign=>TOP},
+           [
+              th(['Vegetable', 'Breakfast','Lunch','Dinner']),
+              td(['Tomatoes' , 'no', 'yes', 'yes']),
+              td(['Broccoli' , 'no', 'no',  'yes']),
+              td(['Onions'   , 'yes','yes', 'yes'])
+           ]
+           )
+        );
+
+=head2 HTML SHORTCUTS AND LIST INTERPOLATION
+
+Consider this bit of code:
+
+   print blockquote(em('Hi'),'mom!'));
+
+It will ordinarily return the string that you probably expect, namely:
+
+   <blockquote><em>Hi</em> mom!</blockquote>
+
+Note the space between the element "Hi" and the element "mom!".
+CGI.pm puts the extra space there using array interpolation, which is
+controlled by the magic $" variable.  Sometimes this extra space is
+not what you want, for example, when you are trying to align a series
+of images.  In this case, you can simply change the value of $" to an
+empty string.
+
+   {
+      local($") = '';
+      print blockquote(em('Hi'),'mom!'));
+    }
+
+I suggest you put the code in a block as shown here.  Otherwise the
+change to $" will affect all subsequent code until you explicitly
+reset it.
+
+=head2 NON-STANDARD HTML SHORTCUTS
+
+A few HTML tags don't follow the standard pattern for various
+reasons.  
+
+B<comment()> generates an HTML comment (<!-- comment -->).  Call it
+like
+
+    print comment('here is my comment');
+
+Because of conflicts with built-in Perl functions, the following functions
+begin with initial caps:
+
+    Select
+    Tr
+    Link
+    Delete
+    Accept
+    Sub
+
+In addition, start_html(), end_html(), start_form(), end_form(),
+start_multipart_form() and all the fill-out form tags are special.
+See their respective sections.
+
+=head2 AUTOESCAPING HTML
+
+By default, all HTML that is emitted by the form-generating functions
+is passed through a function called escapeHTML():
+
+=over 4
+
+=item $escaped_string = escapeHTML("unescaped string");
+
+Escape HTML formatting characters in a string.
+
+=back
+
+Provided that you have specified a character set of ISO-8859-1 (the
+default), the standard HTML escaping rules will be used.  The "<"
+character becomes "&lt;", ">" becomes "&gt;", "&" becomes "&amp;", and
+the quote character becomes "&quot;".  In addition, the hexadecimal
+0x8b and 0x9b characters, which many windows-based browsers interpret
+as the left and right angle-bracket characters, are replaced by their
+numeric HTML entities ("&#139" and "&#155;").  If you manually change
+the charset, either by calling the charset() method explicitly or by
+passing a -charset argument to header(), then B<all> characters will
+be replaced by their numeric entities, since CGI.pm has no lookup
+table for all the possible encodings.
+
+The automatic escaping does not apply to other shortcuts, such as
+h1().  You should call escapeHTML() yourself on untrusted data in
+order to protect your pages against nasty tricks that people may enter
+into guestbooks, etc..  To change the character set, use charset().
+To turn autoescaping off completely, use autoescape():
+
+=over 4
+
+=item $charset = charset([$charset]);
+
+Get or set the current character set.
+
+=item $flag = autoEscape([$flag]);
+
+Get or set the value of the autoescape flag.
+
+=back
+
+=head2 PRETTY-PRINTING HTML
+
+By default, all the HTML produced by these functions comes out as one
+long line without carriage returns or indentation. This is yuck, but
+it does reduce the size of the documents by 10-20%.  To get
+pretty-printed output, please use L<CGI::Pretty>, a subclass
+contributed by Brian Paulsen.
+
+=head1 CREATING FILL-OUT FORMS:
+
+I<General note>  The various form-creating methods all return strings
+to the caller, containing the tag or tags that will create the requested
+form element.  You are responsible for actually printing out these strings.
+It's set up this way so that you can place formatting tags
+around the form elements.
+
+I<Another note> The default values that you specify for the forms are only
+used the B<first> time the script is invoked (when there is no query
+string).  On subsequent invocations of the script (when there is a query
+string), the former values are used even if they are blank.  
+
+If you want to change the value of a field from its previous value, you have two
+choices:
+
+(1) call the param() method to set it.
+
+(2) use the -override (alias -force) parameter (a new feature in version 2.15).
+This forces the default value to be used, regardless of the previous value:
+
+   print $query->textfield(-name=>'field_name',
+			   -default=>'starting value',
+			   -override=>1,
+			   -size=>50,
+			   -maxlength=>80);
+
+I<Yet another note> By default, the text and labels of form elements are
+escaped according to HTML rules.  This means that you can safely use
+"<CLICK ME>" as the label for a button.  However, it also interferes with
+your ability to incorporate special HTML character sequences, such as &Aacute;,
+into your fields.  If you wish to turn off automatic escaping, call the
+autoEscape() method with a false value immediately after creating the CGI object:
+
+   $query = new CGI;
+   $query->autoEscape(undef);
+
+=head2 CREATING AN ISINDEX TAG
+
+   print $query->isindex(-action=>$action);
+
+	 -or-
+
+   print $query->isindex($action);
+
+Prints out an <isindex> tag.  Not very exciting.  The parameter
+-action specifies the URL of the script to process the query.  The
+default is to process the query with the current script.
+
+=head2 STARTING AND ENDING A FORM
+
+    print $query->start_form(-method=>$method,
+			    -action=>$action,
+			    -enctype=>$encoding);
+      <... various form stuff ...>
+    print $query->endform;
+
+	-or-
+
+    print $query->start_form($method,$action,$encoding);
+      <... various form stuff ...>
+    print $query->endform;
+
+start_form() will return a <form> tag with the optional method,
+action and form encoding that you specify.  The defaults are:
+
+    method: POST
+    action: this script
+    enctype: application/x-www-form-urlencoded
+
+endform() returns the closing </form> tag.  
+
+Start_form()'s enctype argument tells the browser how to package the various
+fields of the form before sending the form to the server.  Two
+values are possible:
+
+B<Note:> This method was previously named startform(), and startform()
+is still recognized as an alias.
+
+=over 4
+
+=item B<application/x-www-form-urlencoded>
+
+This is the older type of encoding used by all browsers prior to
+Netscape 2.0.  It is compatible with many CGI scripts and is
+suitable for short fields containing text data.  For your
+convenience, CGI.pm stores the name of this encoding
+type in B<&CGI::URL_ENCODED>.
+
+=item B<multipart/form-data>
+
+This is the newer type of encoding introduced by Netscape 2.0.
+It is suitable for forms that contain very large fields or that
+are intended for transferring binary data.  Most importantly,
+it enables the "file upload" feature of Netscape 2.0 forms.  For
+your convenience, CGI.pm stores the name of this encoding type
+in B<&CGI::MULTIPART>
+
+Forms that use this type of encoding are not easily interpreted
+by CGI scripts unless they use CGI.pm or another library designed
+to handle them.
+
+=back
+
+For compatibility, the start_form() method uses the older form of
+encoding by default.  If you want to use the newer form of encoding
+by default, you can call B<start_multipart_form()> instead of
+B<start_form()>.
+
+JAVASCRIPTING: The B<-name> and B<-onSubmit> parameters are provided
+for use with JavaScript.  The -name parameter gives the
+form a name so that it can be identified and manipulated by
+JavaScript functions.  -onSubmit should point to a JavaScript
+function that will be executed just before the form is submitted to your
+server.  You can use this opportunity to check the contents of the form 
+for consistency and completeness.  If you find something wrong, you
+can put up an alert box or maybe fix things up yourself.  You can 
+abort the submission by returning false from this function.  
+
+Usually the bulk of JavaScript functions are defined in a <script>
+block in the HTML header and -onSubmit points to one of these function
+call.  See start_html() for details.
+
+=head2 CREATING A TEXT FIELD
+
+    print $query->textfield(-name=>'field_name',
+			    -default=>'starting value',
+			    -size=>50,
+			    -maxlength=>80);
+	-or-
+
+    print $query->textfield('field_name','starting value',50,80);
+
+textfield() will return a text input field.  
+
+=over 4
+
+=item B<Parameters>
+
+=item 1.
+
+The first parameter is the required name for the field (-name).  
+
+=item 2.
+
+The optional second parameter is the default starting value for the field
+contents (-default).  
+
+=item 3.
+
+The optional third parameter is the size of the field in
+      characters (-size).
+
+=item 4.
+
+The optional fourth parameter is the maximum number of characters the
+      field will accept (-maxlength).
+
+=back
+
+As with all these methods, the field will be initialized with its 
+previous contents from earlier invocations of the script.
+When the form is processed, the value of the text field can be
+retrieved with:
+
+       $value = $query->param('foo');
+
+If you want to reset it from its initial value after the script has been
+called once, you can do so like this:
+
+       $query->param('foo',"I'm taking over this value!");
+
+NEW AS OF VERSION 2.15: If you don't want the field to take on its previous
+value, you can force its current value by using the -override (alias -force)
+parameter:
+
+    print $query->textfield(-name=>'field_name',
+			    -default=>'starting value',
+			    -override=>1,
+			    -size=>50,
+			    -maxlength=>80);
+
+JAVASCRIPTING: You can also provide B<-onChange>, B<-onFocus>,
+B<-onBlur>, B<-onMouseOver>, B<-onMouseOut> and B<-onSelect>
+parameters to register JavaScript event handlers.  The onChange
+handler will be called whenever the user changes the contents of the
+text field.  You can do text validation if you like.  onFocus and
+onBlur are called respectively when the insertion point moves into and
+out of the text field.  onSelect is called when the user changes the
+portion of the text that is selected.
+
+=head2 CREATING A BIG TEXT FIELD
+
+   print $query->textarea(-name=>'foo',
+			  -default=>'starting value',
+			  -rows=>10,
+			  -columns=>50);
+
+	-or
+
+   print $query->textarea('foo','starting value',10,50);
+
+textarea() is just like textfield, but it allows you to specify
+rows and columns for a multiline text entry box.  You can provide
+a starting value for the field, which can be long and contain
+multiple lines.
+
+JAVASCRIPTING: The B<-onChange>, B<-onFocus>, B<-onBlur> ,
+B<-onMouseOver>, B<-onMouseOut>, and B<-onSelect> parameters are
+recognized.  See textfield().
+
+=head2 CREATING A PASSWORD FIELD
+
+   print $query->password_field(-name=>'secret',
+				-value=>'starting value',
+				-size=>50,
+				-maxlength=>80);
+	-or-
+
+   print $query->password_field('secret','starting value',50,80);
+
+password_field() is identical to textfield(), except that its contents 
+will be starred out on the web page.
+
+JAVASCRIPTING: The B<-onChange>, B<-onFocus>, B<-onBlur>,
+B<-onMouseOver>, B<-onMouseOut> and B<-onSelect> parameters are
+recognized.  See textfield().
+
+=head2 CREATING A FILE UPLOAD FIELD
+
+    print $query->filefield(-name=>'uploaded_file',
+			    -default=>'starting value',
+			    -size=>50,
+			    -maxlength=>80);
+	-or-
+
+    print $query->filefield('uploaded_file','starting value',50,80);
+
+filefield() will return a file upload field for Netscape 2.0 browsers.
+In order to take full advantage of this I<you must use the new 
+multipart encoding scheme> for the form.  You can do this either
+by calling B<start_form()> with an encoding type of B<&CGI::MULTIPART>,
+or by calling the new method B<start_multipart_form()> instead of
+vanilla B<start_form()>.
+
+=over 4
+
+=item B<Parameters>
+
+=item 1.
+
+The first parameter is the required name for the field (-name).  
+
+=item 2.
+
+The optional second parameter is the starting value for the field contents
+to be used as the default file name (-default).
+
+For security reasons, browsers don't pay any attention to this field,
+and so the starting value will always be blank.  Worse, the field
+loses its "sticky" behavior and forgets its previous contents.  The
+starting value field is called for in the HTML specification, however,
+and possibly some browser will eventually provide support for it.
+
+=item 3.
+
+The optional third parameter is the size of the field in
+characters (-size).
+
+=item 4.
+
+The optional fourth parameter is the maximum number of characters the
+field will accept (-maxlength).
+
+=back
+
+When the form is processed, you can retrieve the entered filename
+by calling param():
+
+       $filename = $query->param('uploaded_file');
+
+Different browsers will return slightly different things for the
+name.  Some browsers return the filename only.  Others return the full
+path to the file, using the path conventions of the user's machine.
+Regardless, the name returned is always the name of the file on the
+I<user's> machine, and is unrelated to the name of the temporary file
+that CGI.pm creates during upload spooling (see below).
+
+The filename returned is also a file handle.  You can read the contents
+of the file using standard Perl file reading calls:
+
+	# Read a text file and print it out
+	while (<$filename>) {
+	   print;
+	}
+
+	# Copy a binary file to somewhere safe
+	open (OUTFILE,">>/usr/local/web/users/feedback");
+	while ($bytesread=read($filename,$buffer,1024)) {
+	   print OUTFILE $buffer;
+	}
+
+However, there are problems with the dual nature of the upload fields.
+If you C<use strict>, then Perl will complain when you try to use a
+string as a filehandle.  You can get around this by placing the file
+reading code in a block containing the C<no strict> pragma.  More
+seriously, it is possible for the remote user to type garbage into the
+upload field, in which case what you get from param() is not a
+filehandle at all, but a string.
+
+To be safe, use the I<upload()> function (new in version 2.47).  When
+called with the name of an upload field, I<upload()> returns a
+filehandle, or undef if the parameter is not a valid filehandle.
+
+     $fh = $query->upload('uploaded_file');
+     while (<$fh>) {
+	   print;
+     }
+
+In an array context, upload() will return an array of filehandles.
+This makes it possible to create forms that use the same name for
+multiple upload fields.
+
+This is the recommended idiom.
+
+When a file is uploaded the browser usually sends along some
+information along with it in the format of headers.  The information
+usually includes the MIME content type.  Future browsers may send
+other information as well (such as modification date and size). To
+retrieve this information, call uploadInfo().  It returns a reference to
+an associative array containing all the document headers.
+
+       $filename = $query->param('uploaded_file');
+       $type = $query->uploadInfo($filename)->{'Content-Type'};
+       unless ($type eq 'text/html') {
+	  die "HTML FILES ONLY!";
+       }
+
+If you are using a machine that recognizes "text" and "binary" data
+modes, be sure to understand when and how to use them (see the Camel book).  
+Otherwise you may find that binary files are corrupted during file
+uploads.
+
+There are occasionally problems involving parsing the uploaded file.
+This usually happens when the user presses "Stop" before the upload is
+finished.  In this case, CGI.pm will return undef for the name of the
+uploaded file and set I<cgi_error()> to the string "400 Bad request
+(malformed multipart POST)".  This error message is designed so that
+you can incorporate it into a status code to be sent to the browser.
+Example:
+
+   $file = $query->upload('uploaded_file');
+   if (!$file && $query->cgi_error) {
+      print $query->header(-status=>$query->cgi_error);
+      exit 0;
+   }
+
+You are free to create a custom HTML page to complain about the error,
+if you wish.
+
+If you are using CGI.pm on a Windows platform and find that binary
+files get slightly larger when uploaded but that text files remain the
+same, then you have forgotten to activate binary mode on the output
+filehandle.  Be sure to call binmode() on any handle that you create
+to write the uploaded file to disk.
+
+JAVASCRIPTING: The B<-onChange>, B<-onFocus>, B<-onBlur>,
+B<-onMouseOver>, B<-onMouseOut> and B<-onSelect> parameters are
+recognized.  See textfield() for details.
+
+=head2 CREATING A POPUP MENU
+
+   print $query->popup_menu('menu_name',
+			    ['eenie','meenie','minie'],
+			    'meenie');
+
+      -or-
+
+   %labels = ('eenie'=>'your first choice',
+	      'meenie'=>'your second choice',
+	      'minie'=>'your third choice');
+   print $query->popup_menu('menu_name',
+			    ['eenie','meenie','minie'],
+			    'meenie',\%labels);
+
+	-or (named parameter style)-
+
+   print $query->popup_menu(-name=>'menu_name',
+			    -values=>['eenie','meenie','minie'],
+			    -default=>'meenie',
+			    -labels=>\%labels);
+
+popup_menu() creates a menu.
+
+=over 4
+
+=item 1.
+
+The required first argument is the menu's name (-name).
+
+=item 2.
+
+The required second argument (-values) is an array B<reference>
+containing the list of menu items in the menu.  You can pass the
+method an anonymous array, as shown in the example, or a reference to
+a named array, such as "\@foo".
+
+=item 3.
+
+The optional third parameter (-default) is the name of the default
+menu choice.  If not specified, the first item will be the default.
+The values of the previous choice will be maintained across queries.
+
+=item 4.
+
+The optional fourth parameter (-labels) is provided for people who
+want to use different values for the user-visible label inside the
+popup menu nd the value returned to your script.  It's a pointer to an
+associative array relating menu values to user-visible labels.  If you
+leave this parameter blank, the menu values will be displayed by
+default.  (You can also leave a label undefined if you want to).
+
+=back
+
+When the form is processed, the selected value of the popup menu can
+be retrieved using:
+
+      $popup_menu_value = $query->param('menu_name');
+
+JAVASCRIPTING: popup_menu() recognizes the following event handlers:
+B<-onChange>, B<-onFocus>, B<-onMouseOver>, B<-onMouseOut>, and
+B<-onBlur>.  See the textfield() section for details on when these
+handlers are called.
+
+=head2 CREATING A SCROLLING LIST
+
+   print $query->scrolling_list('list_name',
+				['eenie','meenie','minie','moe'],
+				['eenie','moe'],5,'true');
+      -or-
+
+   print $query->scrolling_list('list_name',
+				['eenie','meenie','minie','moe'],
+				['eenie','moe'],5,'true',
+				\%labels);
+
+	-or-
+
+   print $query->scrolling_list(-name=>'list_name',
+				-values=>['eenie','meenie','minie','moe'],
+				-default=>['eenie','moe'],
+				-size=>5,
+				-multiple=>'true',
+				-labels=>\%labels);
+
+scrolling_list() creates a scrolling list.  
+
+=over 4
+
+=item B<Parameters:>
+
+=item 1.
+
+The first and second arguments are the list name (-name) and values
+(-values).  As in the popup menu, the second argument should be an
+array reference.
+
+=item 2.
+
+The optional third argument (-default) can be either a reference to a
+list containing the values to be selected by default, or can be a
+single value to select.  If this argument is missing or undefined,
+then nothing is selected when the list first appears.  In the named
+parameter version, you can use the synonym "-defaults" for this
+parameter.
+
+=item 3.
+
+The optional fourth argument is the size of the list (-size).
+
+=item 4.
+
+The optional fifth argument can be set to true to allow multiple
+simultaneous selections (-multiple).  Otherwise only one selection
+will be allowed at a time.
+
+=item 5.
+
+The optional sixth argument is a pointer to an associative array
+containing long user-visible labels for the list items (-labels).
+If not provided, the values will be displayed.
+
+When this form is processed, all selected list items will be returned as
+a list under the parameter name 'list_name'.  The values of the
+selected items can be retrieved with:
+
+      @selected = $query->param('list_name');
+
+=back
+
+JAVASCRIPTING: scrolling_list() recognizes the following event
+handlers: B<-onChange>, B<-onFocus>, B<-onMouseOver>, B<-onMouseOut>
+and B<-onBlur>.  See textfield() for the description of when these
+handlers are called.
+
+=head2 CREATING A GROUP OF RELATED CHECKBOXES
+
+   print $query->checkbox_group(-name=>'group_name',
+				-values=>['eenie','meenie','minie','moe'],
+				-default=>['eenie','moe'],
+				-linebreak=>'true',
+				-labels=>\%labels);
+
+   print $query->checkbox_group('group_name',
+				['eenie','meenie','minie','moe'],
+				['eenie','moe'],'true',\%labels);
+
+   HTML3-COMPATIBLE BROWSERS ONLY:
+
+   print $query->checkbox_group(-name=>'group_name',
+				-values=>['eenie','meenie','minie','moe'],
+				-rows=2,-columns=>2);
+
+
+checkbox_group() creates a list of checkboxes that are related
+by the same name.
+
+=over 4
+
+=item B<Parameters:>
+
+=item 1.
+
+The first and second arguments are the checkbox name and values,
+respectively (-name and -values).  As in the popup menu, the second
+argument should be an array reference.  These values are used for the
+user-readable labels printed next to the checkboxes as well as for the
+values passed to your script in the query string.
+
+=item 2.
+
+The optional third argument (-default) can be either a reference to a
+list containing the values to be checked by default, or can be a
+single value to checked.  If this argument is missing or undefined,
+then nothing is selected when the list first appears.
+
+=item 3.
+
+The optional fourth argument (-linebreak) can be set to true to place
+line breaks between the checkboxes so that they appear as a vertical
+list.  Otherwise, they will be strung together on a horizontal line.
+
+=item 4.
+
+The optional fifth argument is a pointer to an associative array
+relating the checkbox values to the user-visible labels that will
+be printed next to them (-labels).  If not provided, the values will
+be used as the default.
+
+=item 5.
+
+B<HTML3-compatible browsers> (such as Netscape) can take advantage of
+the optional parameters B<-rows>, and B<-columns>.  These parameters
+cause checkbox_group() to return an HTML3 compatible table containing
+the checkbox group formatted with the specified number of rows and
+columns.  You can provide just the -columns parameter if you wish;
+checkbox_group will calculate the correct number of rows for you.
+
+To include row and column headings in the returned table, you
+can use the B<-rowheaders> and B<-colheaders> parameters.  Both
+of these accept a pointer to an array of headings to use.
+The headings are just decorative.  They don't reorganize the
+interpretation of the checkboxes -- they're still a single named
+unit.
+
+=back
+
+When the form is processed, all checked boxes will be returned as
+a list under the parameter name 'group_name'.  The values of the
+"on" checkboxes can be retrieved with:
+
+      @turned_on = $query->param('group_name');
+
+The value returned by checkbox_group() is actually an array of button
+elements.  You can capture them and use them within tables, lists,
+or in other creative ways:
+
+    @h = $query->checkbox_group(-name=>'group_name',-values=>\@values);
+    &use_in_creative_way(@h);
+
+JAVASCRIPTING: checkbox_group() recognizes the B<-onClick>
+parameter.  This specifies a JavaScript code fragment or
+function call to be executed every time the user clicks on
+any of the buttons in the group.  You can retrieve the identity
+of the particular button clicked on using the "this" variable.
+
+=head2 CREATING A STANDALONE CHECKBOX
+
+    print $query->checkbox(-name=>'checkbox_name',
+			   -checked=>1,
+			   -value=>'ON',
+			   -label=>'CLICK ME');
+
+	-or-
+
+    print $query->checkbox('checkbox_name','checked','ON','CLICK ME');
+
+checkbox() is used to create an isolated checkbox that isn't logically
+related to any others.
+
+=over 4
+
+=item B<Parameters:>
+
+=item 1.
+
+The first parameter is the required name for the checkbox (-name).  It
+will also be used for the user-readable label printed next to the
+checkbox.
+
+=item 2.
+
+The optional second parameter (-checked) specifies that the checkbox
+is turned on by default.  Synonyms are -selected and -on.
+
+=item 3.
+
+The optional third parameter (-value) specifies the value of the
+checkbox when it is checked.  If not provided, the word "on" is
+assumed.
+
+=item 4.
+
+The optional fourth parameter (-label) is the user-readable label to
+be attached to the checkbox.  If not provided, the checkbox name is
+used.
+
+=back
+
+The value of the checkbox can be retrieved using:
+
+    $turned_on = $query->param('checkbox_name');
+
+JAVASCRIPTING: checkbox() recognizes the B<-onClick>
+parameter.  See checkbox_group() for further details.
+
+=head2 CREATING A RADIO BUTTON GROUP
+
+   print $query->radio_group(-name=>'group_name',
+			     -values=>['eenie','meenie','minie'],
+			     -default=>'meenie',
+			     -linebreak=>'true',
+			     -labels=>\%labels);
+
+	-or-
+
+   print $query->radio_group('group_name',['eenie','meenie','minie'],
+					  'meenie','true',\%labels);
+
+
+   HTML3-COMPATIBLE BROWSERS ONLY:
+
+   print $query->radio_group(-name=>'group_name',
+			     -values=>['eenie','meenie','minie','moe'],
+			     -rows=2,-columns=>2);
+
+radio_group() creates a set of logically-related radio buttons
+(turning one member of the group on turns the others off)
+
+=over 4
+
+=item B<Parameters:>
+
+=item 1.
+
+The first argument is the name of the group and is required (-name).
+
+=item 2.
+
+The second argument (-values) is the list of values for the radio
+buttons.  The values and the labels that appear on the page are
+identical.  Pass an array I<reference> in the second argument, either
+using an anonymous array, as shown, or by referencing a named array as
+in "\@foo".
+
+=item 3.
+
+The optional third parameter (-default) is the name of the default
+button to turn on. If not specified, the first item will be the
+default.  You can provide a nonexistent button name, such as "-" to
+start up with no buttons selected.
+
+=item 4.
+
+The optional fourth parameter (-linebreak) can be set to 'true' to put
+line breaks between the buttons, creating a vertical list.
+
+=item 5.
+
+The optional fifth parameter (-labels) is a pointer to an associative
+array relating the radio button values to user-visible labels to be
+used in the display.  If not provided, the values themselves are
+displayed.
+
+=item 6.
+
+B<HTML3-compatible browsers> (such as Netscape) can take advantage 
+of the optional 
+parameters B<-rows>, and B<-columns>.  These parameters cause
+radio_group() to return an HTML3 compatible table containing
+the radio group formatted with the specified number of rows
+and columns.  You can provide just the -columns parameter if you
+wish; radio_group will calculate the correct number of rows
+for you.
+
+To include row and column headings in the returned table, you
+can use the B<-rowheader> and B<-colheader> parameters.  Both
+of these accept a pointer to an array of headings to use.
+The headings are just decorative.  They don't reorganize the
+interpretation of the radio buttons -- they're still a single named
+unit.
+
+=back
+
+When the form is processed, the selected radio button can
+be retrieved using:
+
+      $which_radio_button = $query->param('group_name');
+
+The value returned by radio_group() is actually an array of button
+elements.  You can capture them and use them within tables, lists,
+or in other creative ways:
+
+    @h = $query->radio_group(-name=>'group_name',-values=>\@values);
+    &use_in_creative_way(@h);
+
+=head2 CREATING A SUBMIT BUTTON 
+
+   print $query->submit(-name=>'button_name',
+			-value=>'value');
+
+	-or-
+
+   print $query->submit('button_name','value');
+
+submit() will create the query submission button.  Every form
+should have one of these.
+
+=over 4
+
+=item B<Parameters:>
+
+=item 1.
+
+The first argument (-name) is optional.  You can give the button a
+name if you have several submission buttons in your form and you want
+to distinguish between them.  The name will also be used as the
+user-visible label.  Be aware that a few older browsers don't deal with this correctly and
+B<never> send back a value from a button.
+
+=item 2.
+
+The second argument (-value) is also optional.  This gives the button
+a value that will be passed to your script in the query string.
+
+=back
+
+You can figure out which button was pressed by using different
+values for each one:
+
+     $which_one = $query->param('button_name');
+
+JAVASCRIPTING: radio_group() recognizes the B<-onClick>
+parameter.  See checkbox_group() for further details.
+
+=head2 CREATING A RESET BUTTON
+
+   print $query->reset
+
+reset() creates the "reset" button.  Note that it restores the
+form to its value from the last time the script was called, 
+NOT necessarily to the defaults.
+
+Note that this conflicts with the Perl reset() built-in.  Use
+CORE::reset() to get the original reset function.
+
+=head2 CREATING A DEFAULT BUTTON
+
+   print $query->defaults('button_label')
+
+defaults() creates a button that, when invoked, will cause the
+form to be completely reset to its defaults, wiping out all the
+changes the user ever made.
+
+=head2 CREATING A HIDDEN FIELD
+
+	print $query->hidden(-name=>'hidden_name',
+			     -default=>['value1','value2'...]);
+
+		-or-
+
+	print $query->hidden('hidden_name','value1','value2'...);
+
+hidden() produces a text field that can't be seen by the user.  It
+is useful for passing state variable information from one invocation
+of the script to the next.
+
+=over 4
+
+=item B<Parameters:>
+
+=item 1.
+
+The first argument is required and specifies the name of this
+field (-name).
+
+=item 2.  
+
+The second argument is also required and specifies its value
+(-default).  In the named parameter style of calling, you can provide
+a single value here or a reference to a whole list
+
+=back
+
+Fetch the value of a hidden field this way:
+
+     $hidden_value = $query->param('hidden_name');
+
+Note, that just like all the other form elements, the value of a
+hidden field is "sticky".  If you want to replace a hidden field with
+some other values after the script has been called once you'll have to
+do it manually:
+
+     $query->param('hidden_name','new','values','here');
+
+=head2 CREATING A CLICKABLE IMAGE BUTTON
+
+     print $query->image_button(-name=>'button_name',
+				-src=>'/source/URL',
+				-align=>'MIDDLE');      
+
+	-or-
+
+     print $query->image_button('button_name','/source/URL','MIDDLE');
+
+image_button() produces a clickable image.  When it's clicked on the
+position of the click is returned to your script as "button_name.x"
+and "button_name.y", where "button_name" is the name you've assigned
+to it.
+
+JAVASCRIPTING: image_button() recognizes the B<-onClick>
+parameter.  See checkbox_group() for further details.
+
+=over 4
+
+=item B<Parameters:>
+
+=item 1.
+
+The first argument (-name) is required and specifies the name of this
+field.
+
+=item 2.
+
+The second argument (-src) is also required and specifies the URL
+
+=item 3.
+
+The third option (-align, optional) is an alignment type, and may be
+TOP, BOTTOM or MIDDLE
+
+=back
+
+Fetch the value of the button this way:
+     $x = $query->param('button_name.x');
+     $y = $query->param('button_name.y');
+
+=head2 CREATING A JAVASCRIPT ACTION BUTTON
+
+     print $query->button(-name=>'button_name',
+			  -value=>'user visible label',
+			  -onClick=>"do_something()");
+
+	-or-
+
+     print $query->button('button_name',"do_something()");
+
+button() produces a button that is compatible with Netscape 2.0's
+JavaScript.  When it's pressed the fragment of JavaScript code
+pointed to by the B<-onClick> parameter will be executed.  On
+non-Netscape browsers this form element will probably not even
+display.
+
+=head1 HTTP COOKIES
+
+Netscape browsers versions 1.1 and higher, and all versions of
+Internet Explorer, support a so-called "cookie" designed to help
+maintain state within a browser session.  CGI.pm has several methods
+that support cookies.
+
+A cookie is a name=value pair much like the named parameters in a CGI
+query string.  CGI scripts create one or more cookies and send
+them to the browser in the HTTP header.  The browser maintains a list
+of cookies that belong to a particular Web server, and returns them
+to the CGI script during subsequent interactions.
+
+In addition to the required name=value pair, each cookie has several
+optional attributes:
+
+=over 4
+
+=item 1. an expiration time
+
+This is a time/date string (in a special GMT format) that indicates
+when a cookie expires.  The cookie will be saved and returned to your
+script until this expiration date is reached if the user exits
+the browser and restarts it.  If an expiration date isn't specified, the cookie
+will remain active until the user quits the browser.
+
+=item 2. a domain
+
+This is a partial or complete domain name for which the cookie is 
+valid.  The browser will return the cookie to any host that matches
+the partial domain name.  For example, if you specify a domain name
+of ".capricorn.com", then the browser will return the cookie to
+Web servers running on any of the machines "www.capricorn.com", 
+"www2.capricorn.com", "feckless.capricorn.com", etc.  Domain names
+must contain at least two periods to prevent attempts to match
+on top level domains like ".edu".  If no domain is specified, then
+the browser will only return the cookie to servers on the host the
+cookie originated from.
+
+=item 3. a path
+
+If you provide a cookie path attribute, the browser will check it
+against your script's URL before returning the cookie.  For example,
+if you specify the path "/cgi-bin", then the cookie will be returned
+to each of the scripts "/cgi-bin/tally.pl", "/cgi-bin/order.pl",
+and "/cgi-bin/customer_service/complain.pl", but not to the script
+"/cgi-private/site_admin.pl".  By default, path is set to "/", which
+causes the cookie to be sent to any CGI script on your site.
+
+=item 4. a "secure" flag
+
+If the "secure" attribute is set, the cookie will only be sent to your
+script if the CGI request is occurring on a secure channel, such as SSL.
+
+=back
+
+The interface to HTTP cookies is the B<cookie()> method:
+
+    $cookie = $query->cookie(-name=>'sessionID',
+			     -value=>'xyzzy',
+			     -expires=>'+1h',
+			     -path=>'/cgi-bin/database',
+			     -domain=>'.capricorn.org',
+			     -secure=>1);
+    print $query->header(-cookie=>$cookie);
+
+B<cookie()> creates a new cookie.  Its parameters include:
+
+=over 4
+
+=item B<-name>
+
+The name of the cookie (required).  This can be any string at all.
+Although browsers limit their cookie names to non-whitespace
+alphanumeric characters, CGI.pm removes this restriction by escaping
+and unescaping cookies behind the scenes.
+
+=item B<-value>
+
+The value of the cookie.  This can be any scalar value,
+array reference, or even associative array reference.  For example,
+you can store an entire associative array into a cookie this way:
+
+	$cookie=$query->cookie(-name=>'family information',
+			       -value=>\%childrens_ages);
+
+=item B<-path>
+
+The optional partial path for which this cookie will be valid, as described
+above.
+
+=item B<-domain>
+
+The optional partial domain for which this cookie will be valid, as described
+above.
+
+=item B<-expires>
+
+The optional expiration date for this cookie.  The format is as described 
+in the section on the B<header()> method:
+
+	"+1h"  one hour from now
+
+=item B<-secure>
+
+If set to true, this cookie will only be used within a secure
+SSL session.
+
+=back
+
+The cookie created by cookie() must be incorporated into the HTTP
+header within the string returned by the header() method:
+
+	print $query->header(-cookie=>$my_cookie);
+
+To create multiple cookies, give header() an array reference:
+
+	$cookie1 = $query->cookie(-name=>'riddle_name',
+				  -value=>"The Sphynx's Question");
+	$cookie2 = $query->cookie(-name=>'answers',
+				  -value=>\%answers);
+	print $query->header(-cookie=>[$cookie1,$cookie2]);
+
+To retrieve a cookie, request it by name by calling cookie() method
+without the B<-value> parameter:
+
+	use CGI;
+	$query = new CGI;
+	$riddle = $query->cookie('riddle_name');
+        %answers = $query->cookie('answers');
+
+Cookies created with a single scalar value, such as the "riddle_name"
+cookie, will be returned in that form.  Cookies with array and hash
+values can also be retrieved.
+
+The cookie and CGI namespaces are separate.  If you have a parameter
+named 'answers' and a cookie named 'answers', the values retrieved by
+param() and cookie() are independent of each other.  However, it's
+simple to turn a CGI parameter into a cookie, and vice-versa:
+
+   # turn a CGI parameter into a cookie
+   $c=$q->cookie(-name=>'answers',-value=>[$q->param('answers')]);
+   # vice-versa
+   $q->param(-name=>'answers',-value=>[$q->cookie('answers')]);
+
+See the B<cookie.cgi> example script for some ideas on how to use
+cookies effectively.
+
+=head1 WORKING WITH FRAMES
+
+It's possible for CGI.pm scripts to write into several browser panels
+and windows using the HTML 4 frame mechanism.  There are three
+techniques for defining new frames programmatically:
+
+=over 4
+
+=item 1. Create a <Frameset> document
+
+After writing out the HTTP header, instead of creating a standard
+HTML document using the start_html() call, create a <frameset> 
+document that defines the frames on the page.  Specify your script(s)
+(with appropriate parameters) as the SRC for each of the frames.
+
+There is no specific support for creating <frameset> sections 
+in CGI.pm, but the HTML is very simple to write.  See the frame
+documentation in Netscape's home pages for details 
+
+  http://home.netscape.com/assist/net_sites/frames.html
+
+=item 2. Specify the destination for the document in the HTTP header
+
+You may provide a B<-target> parameter to the header() method:
+
+    print $q->header(-target=>'ResultsWindow');
+
+This will tell the browser to load the output of your script into the
+frame named "ResultsWindow".  If a frame of that name doesn't already
+exist, the browser will pop up a new window and load your script's
+document into that.  There are a number of magic names that you can
+use for targets.  See the frame documents on Netscape's home pages for
+details.
+
+=item 3. Specify the destination for the document in the <form> tag
+
+You can specify the frame to load in the FORM tag itself.  With
+CGI.pm it looks like this:
+
+    print $q->start_form(-target=>'ResultsWindow');
+
+When your script is reinvoked by the form, its output will be loaded
+into the frame named "ResultsWindow".  If one doesn't already exist
+a new window will be created.
+
+=back
+
+The script "frameset.cgi" in the examples directory shows one way to
+create pages in which the fill-out form and the response live in
+side-by-side frames.
+
+=head1 LIMITED SUPPORT FOR CASCADING STYLE SHEETS
+
+CGI.pm has limited support for HTML3's cascading style sheets (css).
+To incorporate a stylesheet into your document, pass the
+start_html() method a B<-style> parameter.  The value of this
+parameter may be a scalar, in which case it is incorporated directly
+into a <style> section, or it may be a hash reference.  In the latter
+case you should provide the hash with one or more of B<-src> or
+B<-code>.  B<-src> points to a URL where an externally-defined
+stylesheet can be found.  B<-code> points to a scalar value to be
+incorporated into a <style> section.  Style definitions in B<-code>
+override similarly-named ones in B<-src>, hence the name "cascading."
+
+You may also specify the type of the stylesheet by adding the optional
+B<-type> parameter to the hash pointed to by B<-style>.  If not
+specified, the style defaults to 'text/css'.
+
+To refer to a style within the body of your document, add the
+B<-class> parameter to any HTML element:
+
+    print h1({-class=>'Fancy'},'Welcome to the Party');
+
+Or define styles on the fly with the B<-style> parameter:
+
+    print h1({-style=>'Color: red;'},'Welcome to Hell');
+
+You may also use the new B<span()> element to apply a style to a
+section of text:
+
+    print span({-style=>'Color: red;'},
+	       h1('Welcome to Hell'),
+	       "Where did that handbasket get to?"
+	       );
+
+Note that you must import the ":html3" definitions to have the
+B<span()> method available.  Here's a quick and dirty example of using
+CSS's.  See the CSS specification at
+http://www.w3.org/pub/WWW/TR/Wd-css-1.html for more information.
+
+    use CGI qw/:standard :html3/;
+
+    #here's a stylesheet incorporated directly into the page
+    $newStyle=<<END;
+    <!-- 
+    P.Tip {
+	margin-right: 50pt;
+	margin-left: 50pt;
+        color: red;
+    }
+    P.Alert {
+	font-size: 30pt;
+        font-family: sans-serif;
+      color: red;
+    }
+    -->
+    END
+    print header();
+    print start_html( -title=>'CGI with Style',
+		      -style=>{-src=>'http://www.capricorn.com/style/st1.css',
+		               -code=>$newStyle}
+	             );
+    print h1('CGI with Style'),
+          p({-class=>'Tip'},
+	    "Better read the cascading style sheet spec before playing with this!"),
+          span({-style=>'color: magenta'},
+	       "Look Mom, no hands!",
+	       p(),
+	       "Whooo wee!"
+	       );
+    print end_html;
+
+Pass an array reference to B<-style> in order to incorporate multiple
+stylesheets into your document.
+
+=head1 DEBUGGING
+
+If you are running the script from the command line or in the perl
+debugger, you can pass the script a list of keywords or
+parameter=value pairs on the command line or from standard input (you
+don't have to worry about tricking your script into reading from
+environment variables).  You can pass keywords like this:
+
+    your_script.pl keyword1 keyword2 keyword3
+
+or this:
+
+   your_script.pl keyword1+keyword2+keyword3
+
+or this:
+
+    your_script.pl name1=value1 name2=value2
+
+or this:
+
+    your_script.pl name1=value1&name2=value2
+
+To turn off this feature, use the -no_debug pragma.
+
+To test the POST method, you may enable full debugging with the -debug
+pragma.  This will allow you to feed newline-delimited name=value
+pairs to the script on standard input.
+
+When debugging, you can use quotes and backslashes to escape 
+characters in the familiar shell manner, letting you place
+spaces and other funny characters in your parameter=value
+pairs:
+
+   your_script.pl "name1='I am a long value'" "name2=two\ words"
+
+=head2 DUMPING OUT ALL THE NAME/VALUE PAIRS
+
+The Dump() method produces a string consisting of all the query's
+name/value pairs formatted nicely as a nested list.  This is useful
+for debugging purposes:
+
+    print $query->Dump
+
+
+Produces something that looks like:
+
+    <ul>
+    <li>name1
+	<ul>
+	<li>value1
+	<li>value2
+	</ul>
+    <li>name2
+	<ul>
+	<li>value1
+	</ul>
+    </ul>
+
+As a shortcut, you can interpolate the entire CGI object into a string
+and it will be replaced with the a nice HTML dump shown above:
+
+    $query=new CGI;
+    print "<h2>Current Values</h2> $query\n";
+
+=head1 FETCHING ENVIRONMENT VARIABLES
+
+Some of the more useful environment variables can be fetched
+through this interface.  The methods are as follows:
+
+=over 4
+
+=item B<Accept()>
+
+Return a list of MIME types that the remote browser accepts. If you
+give this method a single argument corresponding to a MIME type, as in
+$query->Accept('text/html'), it will return a floating point value
+corresponding to the browser's preference for this type from 0.0
+(don't want) to 1.0.  Glob types (e.g. text/*) in the browser's accept
+list are handled correctly.
+
+Note that the capitalization changed between version 2.43 and 2.44 in
+order to avoid conflict with Perl's accept() function.
+
+=item B<raw_cookie()>
+
+Returns the HTTP_COOKIE variable, an HTTP extension implemented by
+Netscape browsers version 1.1 and higher, and all versions of Internet
+Explorer.  Cookies have a special format, and this method call just
+returns the raw form (?cookie dough).  See cookie() for ways of
+setting and retrieving cooked cookies.
+
+Called with no parameters, raw_cookie() returns the packed cookie
+structure.  You can separate it into individual cookies by splitting
+on the character sequence "; ".  Called with the name of a cookie,
+retrieves the B<unescaped> form of the cookie.  You can use the
+regular cookie() method to get the names, or use the raw_fetch()
+method from the CGI::Cookie module.
+
+=item B<user_agent()>
+
+Returns the HTTP_USER_AGENT variable.  If you give
+this method a single argument, it will attempt to
+pattern match on it, allowing you to do something
+like $query->user_agent(netscape);
+
+=item B<path_info()>
+
+Returns additional path information from the script URL.
+E.G. fetching /cgi-bin/your_script/additional/stuff will result in
+$query->path_info() returning "/additional/stuff".
+
+NOTE: The Microsoft Internet Information Server
+is broken with respect to additional path information.  If
+you use the Perl DLL library, the IIS server will attempt to
+execute the additional path information as a Perl script.
+If you use the ordinary file associations mapping, the
+path information will be present in the environment, 
+but incorrect.  The best thing to do is to avoid using additional
+path information in CGI scripts destined for use with IIS.
+
+=item B<path_translated()>
+
+As per path_info() but returns the additional
+path information translated into a physical path, e.g.
+"/usr/local/etc/httpd/htdocs/additional/stuff".
+
+The Microsoft IIS is broken with respect to the translated
+path as well.
+
+=item B<remote_host()>
+
+Returns either the remote host name or IP address.
+if the former is unavailable.
+
+=item B<script_name()>
+
+Return the script name as a partial URL, for self-refering
+scripts.
+
+=item B<referer()>
+
+Return the URL of the page the browser was viewing
+prior to fetching your script.  Not available for all
+browsers.
+
+=item B<auth_type ()>
+
+Return the authorization/verification method in use for this
+script, if any.
+
+=item B<server_name ()>
+
+Returns the name of the server, usually the machine's host
+name.
+
+=item B<virtual_host ()>
+
+When using virtual hosts, returns the name of the host that
+the browser attempted to contact
+
+=item B<server_port ()>
+
+Return the port that the server is listening on.
+
+=item B<server_software ()>
+
+Returns the server software and version number.
+
+=item B<remote_user ()>
+
+Return the authorization/verification name used for user
+verification, if this script is protected.
+
+=item B<user_name ()>
+
+Attempt to obtain the remote user's name, using a variety of different
+techniques.  This only works with older browsers such as Mosaic.
+Newer browsers do not report the user name for privacy reasons!
+
+=item B<request_method()>
+
+Returns the method used to access your script, usually
+one of 'POST', 'GET' or 'HEAD'.
+
+=item B<content_type()>
+
+Returns the content_type of data submitted in a POST, generally 
+multipart/form-data or application/x-www-form-urlencoded
+
+=item B<http()>
+
+Called with no arguments returns the list of HTTP environment
+variables, including such things as HTTP_USER_AGENT,
+HTTP_ACCEPT_LANGUAGE, and HTTP_ACCEPT_CHARSET, corresponding to the
+like-named HTTP header fields in the request.  Called with the name of
+an HTTP header field, returns its value.  Capitalization and the use
+of hyphens versus underscores are not significant.
+
+For example, all three of these examples are equivalent:
+
+   $requested_language = $q->http('Accept-language');
+   $requested_language = $q->http('Accept_language');
+   $requested_language = $q->http('HTTP_ACCEPT_LANGUAGE');
+
+=item B<https()>
+
+The same as I<http()>, but operates on the HTTPS environment variables
+present when the SSL protocol is in effect.  Can be used to determine
+whether SSL is turned on.
+
+=back
+
+=head1 USING NPH SCRIPTS
+
+NPH, or "no-parsed-header", scripts bypass the server completely by
+sending the complete HTTP header directly to the browser.  This has
+slight performance benefits, but is of most use for taking advantage
+of HTTP extensions that are not directly supported by your server,
+such as server push and PICS headers.
+
+Servers use a variety of conventions for designating CGI scripts as
+NPH.  Many Unix servers look at the beginning of the script's name for
+the prefix "nph-".  The Macintosh WebSTAR server and Microsoft's
+Internet Information Server, in contrast, try to decide whether a
+program is an NPH script by examining the first line of script output.
+
+
+CGI.pm supports NPH scripts with a special NPH mode.  When in this
+mode, CGI.pm will output the necessary extra header information when
+the header() and redirect() methods are
+called.
+
+The Microsoft Internet Information Server requires NPH mode.  As of
+version 2.30, CGI.pm will automatically detect when the script is
+running under IIS and put itself into this mode.  You do not need to
+do this manually, although it won't hurt anything if you do.  However,
+note that if you have applied Service Pack 6, much of the
+functionality of NPH scripts, including the ability to redirect while
+setting a cookie, b<do not work at all> on IIS without a special patch
+from Microsoft.  See
+http://support.microsoft.com/support/kb/articles/Q280/3/41.ASP:
+Non-Parsed Headers Stripped From CGI Applications That Have nph-
+Prefix in Name.
+
+=over 4
+
+=item In the B<use> statement 
+
+Simply add the "-nph" pragmato the list of symbols to be imported into
+your script:
+
+      use CGI qw(:standard -nph)
+
+=item By calling the B<nph()> method:
+
+Call B<nph()> with a non-zero parameter at any point after using CGI.pm in your program.
+
+      CGI->nph(1)
+
+=item By using B<-nph> parameters
+
+in the B<header()> and B<redirect()>  statements:
+
+      print $q->header(-nph=>1);
+
+=back
+
+=head1 Server Push
+
+CGI.pm provides four simple functions for producing multipart
+documents of the type needed to implement server push.  These
+functions were graciously provided by Ed Jordan <ed@fidalgo.net>.  To
+import these into your namespace, you must import the ":push" set.
+You are also advised to put the script into NPH mode and to set $| to
+1 to avoid buffering problems.
+
+Here is a simple script that demonstrates server push:
+
+  #!/usr/local/bin/perl
+  use CGI qw/:push -nph/;
+  $| = 1;
+  print multipart_init(-boundary=>'----here we go!');
+  foreach (0 .. 4) {
+      print multipart_start(-type=>'text/plain'),
+            "The current time is ",scalar(localtime),"\n";
+      if ($_ < 4) {
+              print multipart_end;
+      } else {
+              print multipart_final;
+      }
+      sleep 1;
+  }
+
+This script initializes server push by calling B<multipart_init()>.
+It then enters a loop in which it begins a new multipart section by
+calling B<multipart_start()>, prints the current local time,
+and ends a multipart section with B<multipart_end()>.  It then sleeps
+a second, and begins again. On the final iteration, it ends the
+multipart section with B<multipart_final()> rather than with
+B<multipart_end()>.
+
+=over 4
+
+=item multipart_init()
+
+  multipart_init(-boundary=>$boundary);
+
+Initialize the multipart system.  The -boundary argument specifies
+what MIME boundary string to use to separate parts of the document.
+If not provided, CGI.pm chooses a reasonable boundary for you.
+
+=item multipart_start()
+
+  multipart_start(-type=>$type)
+
+Start a new part of the multipart document using the specified MIME
+type.  If not specified, text/html is assumed.
+
+=item multipart_end()
+
+  multipart_end()
+
+End a part.  You must remember to call multipart_end() once for each
+multipart_start(), except at the end of the last part of the multipart
+document when multipart_final() should be called instead of multipart_end().
+
+=item multipart_final()
+
+  multipart_final()
+
+End all parts.  You should call multipart_final() rather than
+multipart_end() at the end of the last part of the multipart document.
+
+=back
+
+Users interested in server push applications should also have a look
+at the CGI::Push module.
+
+Only Netscape Navigator supports server push.  Internet Explorer
+browsers do not.
+
+=head1 Avoiding Denial of Service Attacks
+
+A potential problem with CGI.pm is that, by default, it attempts to
+process form POSTings no matter how large they are.  A wily hacker
+could attack your site by sending a CGI script a huge POST of many
+megabytes.  CGI.pm will attempt to read the entire POST into a
+variable, growing hugely in size until it runs out of memory.  While
+the script attempts to allocate the memory the system may slow down
+dramatically.  This is a form of denial of service attack.
+
+Another possible attack is for the remote user to force CGI.pm to
+accept a huge file upload.  CGI.pm will accept the upload and store it
+in a temporary directory even if your script doesn't expect to receive
+an uploaded file.  CGI.pm will delete the file automatically when it
+terminates, but in the meantime the remote user may have filled up the
+server's disk space, causing problems for other programs.
+
+The best way to avoid denial of service attacks is to limit the amount
+of memory, CPU time and disk space that CGI scripts can use.  Some Web
+servers come with built-in facilities to accomplish this. In other
+cases, you can use the shell I<limit> or I<ulimit>
+commands to put ceilings on CGI resource usage.
+
+
+CGI.pm also has some simple built-in protections against denial of
+service attacks, but you must activate them before you can use them.
+These take the form of two global variables in the CGI name space:
+
+=over 4
+
+=item B<$CGI::POST_MAX>
+
+If set to a non-negative integer, this variable puts a ceiling
+on the size of POSTings, in bytes.  If CGI.pm detects a POST
+that is greater than the ceiling, it will immediately exit with an error
+message.  This value will affect both ordinary POSTs and
+multipart POSTs, meaning that it limits the maximum size of file
+uploads as well.  You should set this to a reasonably high
+value, such as 1 megabyte.
+
+=item B<$CGI::DISABLE_UPLOADS>
+
+If set to a non-zero value, this will disable file uploads
+completely.  Other fill-out form values will work as usual.
+
+=back
+
+You can use these variables in either of two ways.
+
+=over 4
+
+=item B<1. On a script-by-script basis>
+
+Set the variable at the top of the script, right after the "use" statement:
+
+    use CGI qw/:standard/;
+    use CGI::Carp 'fatalsToBrowser';
+    $CGI::POST_MAX=1024 * 100;  # max 100K posts
+    $CGI::DISABLE_UPLOADS = 1;  # no uploads
+
+=item B<2. Globally for all scripts>
+
+Open up CGI.pm, find the definitions for $POST_MAX and 
+$DISABLE_UPLOADS, and set them to the desired values.  You'll 
+find them towards the top of the file in a subroutine named 
+initialize_globals().
+
+=back
+
+An attempt to send a POST larger than $POST_MAX bytes will cause
+I<param()> to return an empty CGI parameter list.  You can test for
+this event by checking I<cgi_error()>, either after you create the CGI
+object or, if you are using the function-oriented interface, call
+<param()> for the first time.  If the POST was intercepted, then
+cgi_error() will return the message "413 POST too large".
+
+This error message is actually defined by the HTTP protocol, and is
+designed to be returned to the browser as the CGI script's status
+ code.  For example:
+
+   $uploaded_file = param('upload');
+   if (!$uploaded_file && cgi_error()) {
+      print header(-status=>cgi_error());
+      exit 0;
+   }
+
+However it isn't clear that any browser currently knows what to do
+with this status code.  It might be better just to create an
+HTML page that warns the user of the problem.
+
+=head1 COMPATIBILITY WITH CGI-LIB.PL
+
+To make it easier to port existing programs that use cgi-lib.pl the
+compatibility routine "ReadParse" is provided.  Porting is simple:
+
+OLD VERSION
+    require "cgi-lib.pl";
+    &ReadParse;
+    print "The value of the antique is $in{antique}.\n";
+
+NEW VERSION
+    use CGI;
+    CGI::ReadParse
+    print "The value of the antique is $in{antique}.\n";
+
+CGI.pm's ReadParse() routine creates a tied variable named %in,
+which can be accessed to obtain the query variables.  Like
+ReadParse, you can also provide your own variable.  Infrequently
+used features of ReadParse, such as the creation of @in and $in 
+variables, are not supported.
+
+Once you use ReadParse, you can retrieve the query object itself
+this way:
+
+    $q = $in{CGI};
+    print $q->textfield(-name=>'wow',
+			-value=>'does this really work?');
+
+This allows you to start using the more interesting features
+of CGI.pm without rewriting your old scripts from scratch.
+
+=head1 AUTHOR INFORMATION
+
+Copyright 1995-1998, Lincoln D. Stein.  All rights reserved.  
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+Address bug reports and comments to: lstein@cshl.org.  When sending
+bug reports, please provide the version of CGI.pm, the version of
+Perl, the name and version of your Web server, and the name and
+version of the operating system you are using.  If the problem is even
+remotely browser dependent, please provide information about the
+affected browers as well.
+
+=head1 CREDITS
+
+Thanks very much to:
+
+=over 4
+
+=item Matt Heffron (heffron@falstaff.css.beckman.com)
+
+=item James Taylor (james.taylor@srs.gov)
+
+=item Scott Anguish <sanguish@digifix.com>
+
+=item Mike Jewell (mlj3u@virginia.edu)
+
+=item Timothy Shimmin (tes@kbs.citri.edu.au)
+
+=item Joergen Haegg (jh@axis.se)
+
+=item Laurent Delfosse (delfosse@delfosse.com)
+
+=item Richard Resnick (applepi1@aol.com)
+
+=item Craig Bishop (csb@barwonwater.vic.gov.au)
+
+=item Tony Curtis (tc@vcpc.univie.ac.at)
+
+=item Tim Bunce (Tim.Bunce@ig.co.uk)
+
+=item Tom Christiansen (tchrist@convex.com)
+
+=item Andreas Koenig (k@franz.ww.TU-Berlin.DE)
+
+=item Tim MacKenzie (Tim.MacKenzie@fulcrum.com.au)
+
+=item Kevin B. Hendricks (kbhend@dogwood.tyler.wm.edu)
+
+=item Stephen Dahmen (joyfire@inxpress.net)
+
+=item Ed Jordan (ed@fidalgo.net)
+
+=item David Alan Pisoni (david@cnation.com)
+
+=item Doug MacEachern (dougm@opengroup.org)
+
+=item Robin Houston (robin@oneworld.org)
+
+=item ...and many many more...
+
+for suggestions and bug fixes.
+
+=back
+
+=head1 A COMPLETE EXAMPLE OF A SIMPLE FORM-BASED SCRIPT
+
+
+	#!/usr/local/bin/perl
+
+	use CGI;
+
+	$query = new CGI;
+
+	print $query->header;
+	print $query->start_html("Example CGI.pm Form");
+	print "<h1> Example CGI.pm Form</h1>\n";
+	&print_prompt($query);
+	&do_work($query);
+	&print_tail;
+	print $query->end_html;
+
+	sub print_prompt {
+	   my($query) = @_;
+
+	   print $query->start_form;
+	   print "<em>What's your name?</em><br>";
+	   print $query->textfield('name');
+	   print $query->checkbox('Not my real name');
+
+	   print "<p><em>Where can you find English Sparrows?</em><br>";
+	   print $query->checkbox_group(
+				 -name=>'Sparrow locations',
+				 -values=>[England,France,Spain,Asia,Hoboken],
+				 -linebreak=>'yes',
+				 -defaults=>[England,Asia]);
+
+	   print "<p><em>How far can they fly?</em><br>",
+		$query->radio_group(
+			-name=>'how far',
+			-values=>['10 ft','1 mile','10 miles','real far'],
+			-default=>'1 mile');
+
+	   print "<p><em>What's your favorite color?</em>  ";
+	   print $query->popup_menu(-name=>'Color',
+				    -values=>['black','brown','red','yellow'],
+				    -default=>'red');
+
+	   print $query->hidden('Reference','Monty Python and the Holy Grail');
+
+	   print "<p><em>What have you got there?</em><br>";
+	   print $query->scrolling_list(
+			 -name=>'possessions',
+			 -values=>['A Coconut','A Grail','An Icon',
+				   'A Sword','A Ticket'],
+			 -size=>5,
+			 -multiple=>'true');
+
+	   print "<p><em>Any parting comments?</em><br>";
+	   print $query->textarea(-name=>'Comments',
+				  -rows=>10,
+				  -columns=>50);
+
+	   print "<p>",$query->reset;
+	   print $query->submit('Action','Shout');
+	   print $query->submit('Action','Scream');
+	   print $query->endform;
+	   print "<hr>\n";
+	}
+
+	sub do_work {
+	   my($query) = @_;
+	   my(@values,$key);
+
+	   print "<h2>Here are the current settings in this form</h2>";
+
+	   foreach $key ($query->param) {
+	      print "<strong>$key</strong> -> ";
+	      @values = $query->param($key);
+	      print join(", ",@values),"<br>\n";
+	  }
+	}
+
+	sub print_tail {
+	   print <<END;
+	<hr>
+	<address>Lincoln D. Stein</address><br>
+	<a href="/">Home Page</a>
+	END
+	}
+
+=head1 BUGS
+
+This module has grown large and monolithic.  Furthermore it's doing many
+things, such as handling URLs, parsing CGI input, writing HTML, etc., that
+are also done in the LWP modules. It should be discarded in favor of
+the CGI::* modules, but somehow I continue to work on it.
+
+Note that the code is truly contorted in order to avoid spurious
+warnings when programs are run with the B<-w> switch.
+
+=head1 SEE ALSO
+
+L<CGI::Carp>, L<CGI::Fast>, L<CGI::Pretty>
+
+=cut
+
Index: /gsdl/stable/cgi-bin/getior
===================================================================
--- /gsdl/stable/cgi-bin/getior	(revision 20131)
+++ /gsdl/stable/cgi-bin/getior	(revision 20131)
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+echo "Content-type: text/html";
+echo
+
+cat /tmp/localcorba.objid               
Index: /gsdl/stable/cgi-bin/gliserver.pl
===================================================================
--- /gsdl/stable/cgi-bin/gliserver.pl	(revision 20131)
+++ /gsdl/stable/cgi-bin/gliserver.pl	(revision 20131)
@@ -0,0 +1,1244 @@
+#!/usr/bin/perl -w
+# Need to specify the full path of Perl above
+
+# This file merges Michael Dewsnip's gliserver.pl for GS2 and Quan Qiu's gliserver4gs3.pl (GS3)
+
+use strict;
+no strict 'subs';
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+# Set this to 1 to work around IIS 6 craziness
+my $iis6_mode = 0;
+
+##
+# IIS 6: for some reason, IIS runs this script with the working directory set to the Greenstone
+#   directory rather than the cgi-bin directory, causing lots of stuff to fail
+if ($iis6_mode)
+{
+    # Change into cgi-bin directory - need to ensure it exists, since gliserver deals with both GS2 and GS3
+    if(-e "cgi-bin" && -d "cgi-bin") { # GS2
+	chdir("cgi-bin");
+    } else { # iis6_mode is not applicable for Greenstone 3
+	$iis6_mode = 0;
+    }
+}
+
+
+# We use require and an eval here (instead of "use package") to catch any errors loading the module (for IIS)
+eval("require \"gsdlCGI.pm\"");
+if ($@)
+{
+    print STDOUT "Content-type:text/plain\n\n";
+    print STDOUT "ERROR: $@\n";
+    exit 0;
+}
+
+
+#my $authentication_enabled = 0;
+my $debugging_enabled = 0; # if 1, debugging is enabled and unlinking intermediate files (deleting files) will not happen
+
+my $mail_enabled = 0;
+my $mail_to_address = "user\@server";  # Set this appropriately
+my $mail_from_address = "user\@server";  # Set this appropriately
+my $mail_smtp_server = "smtp.server";  # Set this appropriately
+
+sub main
+{	
+    my $gsdl_cgi = new gsdlCGI();
+
+    # Load the Greenstone modules that we need to use
+    $gsdl_cgi->setup_gsdl();
+    my $gsdlhome = $ENV{'GSDLHOME'};
+
+    $gsdl_cgi->checked_chdir($gsdlhome);
+
+    # Encrypt the password
+    $gsdl_cgi->encrypt_password();
+
+    $gsdl_cgi->parse_cgi_args();
+
+    # We don't want the gsdlCGI module to return errors and warnings in XML
+    $gsdl_cgi->{'xml'} = 0;
+
+    # Retrieve the (required) command CGI argument
+    my $cmd = $gsdl_cgi->clean_param("cmd");
+    if (!defined $cmd) {
+	$gsdl_cgi->generate_error("No command specified.");
+    }
+    $gsdl_cgi->delete("cmd");
+
+    # The check-installation, greenstone-server-version and get-library-url commands have no arguments
+    if ($cmd eq "check-installation") {
+	&check_installation($gsdl_cgi);
+	return;
+    }
+    elsif ($cmd eq "greenstone-server-version") {
+	&greenstone_server_version($gsdl_cgi);
+	return;
+    }
+    elsif ($cmd eq "get-library-url-suffix") {
+	&get_library_url_suffix($gsdl_cgi);
+	return;
+    }
+
+    # All other commands require a username, for locking and authentication
+    my $username = $gsdl_cgi->clean_param("un");
+    if ((!defined $username) || ($username =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No username specified.");
+    }
+    $gsdl_cgi->delete("un");
+
+    # Get then remove the ts (timestamp) argument (since this can mess up other scripts)
+    my $timestamp = $gsdl_cgi->clean_param("ts");
+    if ((!defined $timestamp) || ($timestamp =~ m/^\s*$/)) {
+	$timestamp = time();  # Fall back to using the Perl time() function to generate a timestamp
+    }
+    $gsdl_cgi->delete("ts");
+
+    my $site; # undefined on declaration, see http://perldoc.perl.org/perlsyn.html
+    if($gsdl_cgi->greenstone_version() != 2) { # all GS versions after 2 may define site
+	$site = $gsdl_cgi->clean_param("site");   
+	if (!defined $site) {
+	    $gsdl_cgi->generate_error("No site specified.");
+	}
+	$gsdl_cgi->delete("site");
+    }
+
+
+    if ($cmd eq "delete-collection") {
+	&delete_collection($gsdl_cgi, $username, $timestamp, $site);
+    }
+    elsif ($cmd eq "download-collection") {
+	&download_collection($gsdl_cgi, $username, $timestamp, $site);
+    }
+    elsif ($cmd eq "download-collection-archives") {
+	&download_collection_archives($gsdl_cgi, $username, $timestamp, $site);
+    }
+    elsif ($cmd eq "download-collection-configurations") {
+	&download_collection_configurations($gsdl_cgi, $username, $timestamp, $site);
+    }
+    elsif ($cmd eq "download-collection-file") {
+	&download_collection_file($gsdl_cgi, $username, $timestamp, $site);
+    }
+    elsif ($cmd eq "delete-collection-file") {
+	&delete_collection_file($gsdl_cgi, $username, $timestamp, $site);
+    }
+    elsif ($cmd eq "get-script-options") {
+	&get_script_options($gsdl_cgi, $username, $timestamp, $site);
+    }
+    elsif ($cmd eq "move-collection-file") {
+	&move_collection_file($gsdl_cgi, $username, $timestamp, $site);
+    }
+    elsif ($cmd eq "new-collection-directory") {
+	&new_collection_directory($gsdl_cgi, $username, $timestamp, $site);
+    }
+    elsif ($cmd eq "run-script") {
+	&run_script($gsdl_cgi, $username, $timestamp, $site);
+    }
+    elsif ($cmd eq "timeout-test") {
+	while (1) { }
+    }
+    elsif ($cmd eq "upload-collection-file") {
+	&upload_collection_file($gsdl_cgi, $username, $timestamp, $site);
+    }
+    elsif ($cmd eq "file-exists") { 
+	&file_exists($gsdl_cgi, $site);
+    }
+    # cmds not in Greenstone 2:
+    elsif ($gsdl_cgi->greenstone_version() != 2) { 	
+	if ($cmd eq "download-web-xml-file") {
+	    &download_web_xml_file($gsdl_cgi, $username, $timestamp, $site);
+	} 
+	elsif ($cmd eq "user-validation") {
+	    &user_validation($gsdl_cgi, $username, $timestamp, $site);
+	}
+	elsif ($cmd eq "get-site-names") {
+	    &get_site_names($gsdl_cgi, $username, $timestamp, $site);
+	}
+    }
+    else {
+	$gsdl_cgi->generate_error("Unrecognised command: '$cmd'");
+    }
+        
+}
+
+
+sub authenticate_user
+{
+    my $gsdl_cgi = shift(@_);
+    my $username = shift(@_);
+    my $collection = shift(@_);
+    my $site = shift(@_);
+
+    # Even if we're not authenticating remove the un and pw arguments, since these can mess up other scripts
+    my $user_password = $gsdl_cgi->clean_param("pw");
+    $gsdl_cgi->delete("pw");
+
+    # Only authenticate if it is enabled
+    # return "all-collections-editor" if (!$authentication_enabled);
+
+    if ((!defined $user_password) || ($user_password =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("Authentication failed: no password specified.");
+    }
+
+    my $users_db_content;
+    if($gsdl_cgi->greenstone_version() == 2) {
+	my $etc_directory = &util::filename_cat($ENV{'GSDLHOME'}, "etc");
+	my $users_db_file_path = &util::filename_cat($etc_directory, "users.gdb");
+	
+	# Use db2txt instead of GDBM_File to get the user accounts information
+	$users_db_content = "";
+	open(USERS_DB, "db2txt \"$users_db_file_path\" |");
+	while (<USERS_DB>) {
+	    $users_db_content .= $_;
+	}
+    }
+    elsif($gsdl_cgi->greenstone_version() == 3) {
+	my $gsdl3srchome = $ENV{'GSDL3SRCHOME'};
+
+	my $java = $gsdl_cgi->get_java_path();
+	my $java_gsdl3_classpath = &util::filename_cat($gsdl3srchome, "web", "WEB-INF", "lib", "gsdl3.jar");
+	my $java_derby_classpath = &util::filename_cat($gsdl3srchome, "web", "WEB-INF", "lib", "derby.jar");
+	my $java_classpath;
+	my $gsdlos = $ENV{'GSDLOS'};
+	if ($gsdlos !~ m/windows/){
+	    $java_classpath = $java_gsdl3_classpath . ":" . $java_derby_classpath;
+	}else{
+	    $java_classpath = $java_gsdl3_classpath . ";" . $java_derby_classpath;
+	}
+	my $java_args = &util::filename_cat($gsdl3srchome, "web", "sites", $site, "etc", "usersDB");
+	$gsdl_cgi->checked_chdir($java_args);
+	my $java_command="\"$java\" -classpath \"$java_classpath\" org.greenstone.gsdl3.util.usersDB2txt \"$java_args\" 2>&1";
+	$users_db_content = `$java_command`;
+    }
+    
+    # Get the user account information from the usersDB database
+    my %users_db_data = ();
+    foreach my $users_db_entry (split(/-{70}/, $users_db_content)) {
+	if ($users_db_entry =~ m/\n?\[(.+)\]\n/) {
+	    $users_db_data{$1} = $users_db_entry;
+	}
+    }
+
+    # Check username
+    my $user_data = $users_db_data{$username};
+    if (!defined $user_data) {
+	$gsdl_cgi->generate_error("Authentication failed: no account for user '$username'.");
+    }
+
+    # Check password
+    my ($valid_user_password) = ($user_data =~ m/\<password\>(.*)/);
+    if ($user_password ne $valid_user_password) {
+	$gsdl_cgi->generate_error("Authentication failed: incorrect password.");
+    }
+
+    # Check group
+    my ($user_groups) = ($user_data =~ m/\<groups\>(.*)/);
+
+    if ($collection eq "") {
+	# If we're not editing a collection then the user doesn't need to be in a particular group
+	return $user_groups;  # Authentication successful
+    }
+
+    foreach my $user_group (split(/\,/, $user_groups)) {
+	# Does this user have access to all collections?
+	if ($user_group eq "all-collections-editor") {
+	    return $user_groups;  # Authentication successful
+	}
+	# Does this user have access to personal collections, and is this one?
+	if ($user_group eq "personal-collections-editor" && $collection =~ m/^$username\-/) {
+	    return $user_groups;  # Authentication successful
+	}
+	# Does this user have access to this collection
+	if ($user_group eq "$collection-collection-editor") {
+	    return $user_groups;  # Authentication successful
+	}
+    }
+    $gsdl_cgi->generate_error("Authentication failed: user is not in the required group.");
+}
+
+
+sub lock_collection
+{
+    my $gsdl_cgi = shift(@_);
+    my $username = shift(@_);
+    my $collection = shift(@_);
+    my $site = shift(@_);
+
+    my $steal_lock = $gsdl_cgi->clean_param("steal_lock");
+    $gsdl_cgi->delete("steal_lock");
+
+    my $collection_directory = $gsdl_cgi->get_collection_dir($site, $collection);
+    $gsdl_cgi->checked_chdir($collection_directory);
+
+    # Check if a lock file already exists for this collection
+    my $lock_file_name = "gli.lck";
+    if (-e $lock_file_name) {
+	# A lock file already exists... check if it's ours
+	my $lock_file_content = "";
+	open(LOCK_FILE, "<$lock_file_name");
+	while (<LOCK_FILE>) {
+	    $lock_file_content .= $_;
+	}
+	close(LOCK_FILE);
+
+	# Pick out the owner of the lock file
+	$lock_file_content =~ m/\<User\>(.*?)\<\/User\>/;
+	my $lock_file_owner = $1;
+
+	# The lock file is ours, so there is no problem
+	if ($lock_file_owner eq $username) {
+	    return;
+	}
+
+	# The lock file is not ours, so throw an error unless "steal_lock" is set
+	unless (defined $steal_lock) {
+	    $gsdl_cgi->generate_error("Collection is locked by: $lock_file_owner");
+	}
+    }
+
+    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
+    my $current_time = sprintf("%02d/%02d/%d %02d:%02d:%02d", $mday, $mon + 1, $year + 1900, $hour, $min, $sec);
+
+    # Create a lock file for us (in the same format as the GLI) and we're done
+    open(LOCK_FILE, ">$lock_file_name");
+    print LOCK_FILE "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+    print LOCK_FILE "<LockFile>\n";
+    print LOCK_FILE "    <User>" . $username . "</User>\n";
+    print LOCK_FILE "    <Machine>(Remote)</Machine>\n";
+    print LOCK_FILE "    <Date>" . $current_time . "</Date>\n";
+    print LOCK_FILE "</LockFile>\n";
+    close(LOCK_FILE);
+}
+
+
+# ----------------------------------------------------------------------------------------------------
+#   ACTIONS
+# ----------------------------------------------------------------------------------------------------
+# This routine, which uses the variable site, won't get called by GS2, 
+sub user_validation{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+   
+    # Users can be in any group to perform this action
+    my $user_err = &authenticate_user($gsdl_cgi, $username, "", $site);
+     if (defined $user_err && $user_err!~ m/ERROR/){
+	 if ($user_err!~ m/ERROR/){
+	     #$gsdl_cgi->generate_error("Authentication failed: $username is not valid");
+	     $gsdl_cgi->generate_ok($user_err);
+	     #print $user_err;
+	 }else{
+	     $gsdl_cgi->generate_error($user_err);
+	     #print "not valid" . $user_err;
+	 }
+     }else{
+	 $gsdl_cgi->generate_error("Authentication failed: $username is not valid");	 
+     }
+}
+
+sub check_installation
+{
+    my ($gsdl_cgi) = @_;
+
+    my $installation_ok = 1;
+    my $installation_status = "";
+
+    # Check that Java is installed and accessible
+    my $java = $gsdl_cgi->get_java_path();
+    my $java_command = "\"$java\" -version 2>&1";
+    
+    # IIS 6: redirecting output from STDERR to STDOUT just doesn't work, so we have to let it go
+    #   directly out to the page
+    if($iis6_mode && $gsdl_cgi->greenstone_version() == 2) { ##
+	print STDOUT "Content-type:text/plain\n\n";
+	$java_command = "\"$java\" -version";
+    }
+
+    my $java_output = `$java_command`;
+        
+    my $java_status = $?;
+    if ($java_status < 0) {
+	# The Java command failed
+	$installation_status = "Java failed -- do you have the Java run-time installed?\n" . $gsdl_cgi->check_java_home() . "\n";
+	$installation_ok = 0;
+    }
+    else {
+	$installation_status = "Java found: $java_output";
+    }
+
+    # Show the values of some important environment variables
+    $installation_status .= "\n";
+    if($gsdl_cgi->greenstone_version() != 2) {
+	$installation_status .= "GSDL3SRCHOME: " . $ENV{'GSDL3SRCHOME'} . "\n";
+	$installation_status .= "GSDL3HOME: " . $ENV{'GSDL3HOME'} . "\n";
+    }
+    $installation_status .= "GSDLHOME: " . $ENV{'GSDLHOME'} . "\n";
+    $installation_status .= "GSDLOS: " . $ENV{'GSDLOS'} . "\n";
+    $installation_status .= "JAVA_HOME: " . $ENV{'JAVA_HOME'} . "\n" if defined($ENV{'JAVA_HOME'}); # on GS2, Java's only on the PATH
+    $installation_status .= "PATH: " . $ENV{'PATH'} . "\n";
+    if(defined $ENV{'FEDORA_VERSION'}) { # not using FLI unless version set
+	$installation_status .= "FEDORA_HOME: ".$ENV{'FEDORA_HOME'} . "\n";
+	$installation_status .= "FEDORA_VERSION: ".$ENV{'FEDORA_VERSION'};
+    }
+    
+    if ($installation_ok) { ## M. Dewsnip's svn log comment stated that for iis6_mode output needs to go to STDOUT
+	if($iis6_mode && $gsdl_cgi->greenstone_version() == 2) {
+	    print STDOUT $installation_status . "\nInstallation OK!";
+	} else {
+	    $gsdl_cgi->generate_ok_message($installation_status . "\nInstallation OK!");
+	}
+    }
+    else {
+	if($iis6_mode && $gsdl_cgi->greenstone_version() == 2) {
+	    print STDOUT $installation_status;
+	} else {
+	    $gsdl_cgi->generate_error($installation_status);
+	}
+    }
+}
+
+
+sub delete_collection
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+
+    my $collection = $gsdl_cgi->clean_param("c");
+    if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No collection specified.");
+    }
+
+    # Ensure the user is allowed to edit this collection
+    &authenticate_user($gsdl_cgi, $username, $collection, $site);
+
+
+    my $collect_directory = $gsdl_cgi->get_collection_dir($site);
+    $gsdl_cgi->checked_chdir($collect_directory);
+
+    # Check that the collection exists
+    if (!-d $collection) {
+	$gsdl_cgi->generate_error("Collection $collection does not exist.");
+    }
+
+    # Make sure the collection isn't locked by someone else
+    &lock_collection($gsdl_cgi, $username, $collection, $site);
+
+    $gsdl_cgi->checked_chdir($collect_directory);
+    $gsdl_cgi->local_rm_r("$collection");
+
+    # Check that the collection was deleted
+    if (-e $collection) {
+	$gsdl_cgi->generate_error("Could not delete collection $collection.");
+    }
+
+    $gsdl_cgi->generate_ok_message("Collection $collection deleted successfully.");
+}
+
+
+sub delete_collection_file
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+
+    my $collection = $gsdl_cgi->clean_param("c");
+    if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No collection specified.");
+    }
+    my $file = $gsdl_cgi->clean_param("file");
+    if ((!defined $file) || ($file =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No file specified.");
+    }
+    $file = $gsdl_cgi->decode($file);
+    $file =~ s/\|/&util::get_dirsep()/eg;  # Convert the '|' characters into whatever is right for this OS
+
+    # Make sure we don't try to delete anything outside the collection
+    if ($file =~ m/\.\./) {
+	$gsdl_cgi->generate_error("Illegal file specified.");
+    }
+
+    # Ensure the user is allowed to edit this collection
+    &authenticate_user($gsdl_cgi, $username, $collection, $site);
+
+    my $collection_directory = $gsdl_cgi->get_collection_dir($site, $collection);
+    if (!-d $collection_directory){ ## wasn't there in gs2, ok_msg or error_msg?
+	$gsdl_cgi->generate_ok_message("Directory $collection_directory does not exist."); 
+	die;
+    }
+
+    $gsdl_cgi->checked_chdir($collection_directory);
+
+    # Make sure the collection isn't locked by someone else
+    &lock_collection($gsdl_cgi, $username, $collection, $site);
+
+    # Check that the collection file exists
+    if (!-e $file) { ## original didn't have 'die', but it was an ok message
+	$gsdl_cgi->generate_ok_message("Collection file $file does not exist.");
+	die;
+    }
+    $gsdl_cgi->local_rm_r("$file");
+
+    # Check that the collection file was deleted
+    if (-e $file) {
+	$gsdl_cgi->generate_error("Could not delete collection file $file.");
+    }
+
+    $gsdl_cgi->generate_ok_message("Collection file $file deleted successfully.");
+}
+
+
+sub download_collection
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+
+    my $collection = $gsdl_cgi->clean_param("c");
+    if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No collection specified.");
+    }
+    
+    # language and region Environment Variable setting on the client side that was used to zip files.
+    my $lang_env = $gsdl_cgi->clean_param("lr") || "";
+    $gsdl_cgi->delete("lr");
+
+    # Ensure the user is allowed to edit this collection
+    &authenticate_user($gsdl_cgi, $username, $collection, $site);
+
+    my $collect_directory = $gsdl_cgi->get_collection_dir($site);
+    $gsdl_cgi->checked_chdir($collect_directory);
+
+    # Check that the collection exists
+    if (!-d $collection) {
+	$gsdl_cgi->generate_ok_message("Collection $collection does not exist."); ## original had an error msg (from where it would die)
+	die;
+    }
+
+    # Make sure the collection isn't locked by someone else
+    &lock_collection($gsdl_cgi, $username, $collection, $site);
+
+    # Zip up the collection
+    my $java = $gsdl_cgi->get_java_path();
+    my $java_classpath = &util::filename_cat($ENV{'GSDLHOME'}, "bin", "java", "GLIServer.jar");
+    my $zip_file_path = &util::filename_cat($collect_directory, $collection . "-" . $timestamp . ".zip");
+    my $java_args = "\"$zip_file_path\" \"$collect_directory\" \"$collection\"";
+    if($gsdl_cgi->greenstone_version() != 2) {
+	$java_args .= " gsdl3"; ## must this be done elsewhere as well?
+    }
+
+    $ENV{'LANG'} = $lang_env;
+    my $java_command = "\"$java\" -classpath \"$java_classpath\" org.greenstone.gatherer.remote.ZipCollectionShell $java_args"; 
+
+    my $java_output = `$java_command`;
+    my $java_status = $?;
+    if ($java_status > 0) {
+	$gsdl_cgi->generate_error("Java failed: $java_command\n--\n$java_output\nExit status: " . ($java_status / 256) . "\n" . $gsdl_cgi->check_java_home());
+    }
+
+    # Check that the zip file was created successfully
+    if (!-e $zip_file_path || -z $zip_file_path) {
+	$gsdl_cgi->generate_error("Collection zip file $zip_file_path could not be created.");
+    }
+
+    &put_file($gsdl_cgi, $zip_file_path, "application/zip"); # file is transferred to client
+    unlink("$zip_file_path") unless $debugging_enabled;      # deletes the local intermediate zip file
+}
+
+
+sub download_collection_archives
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+
+    my $collection = $gsdl_cgi->clean_param("c");
+    if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No collection specified.");
+    }
+
+    # language and region Environment Variable setting on the client side that was used to zip files.
+    my $lang_env = $gsdl_cgi->clean_param("lr") || "";
+    $gsdl_cgi->delete("lr");
+   
+    # Ensure the user is allowed to edit this collection
+    &authenticate_user($gsdl_cgi, $username, $collection, $site);
+
+    my $collect_directory = $gsdl_cgi->get_collection_dir($site);
+    $gsdl_cgi->checked_chdir($collect_directory);
+
+    # Check that the collection archives exist
+    if (!-d &util::filename_cat($collection, "archives")) {
+	$gsdl_cgi->generate_error("Collection archives do not exist.");
+    }
+
+    # Make sure the collection isn't locked by someone else
+    &lock_collection($gsdl_cgi, $username, $collection, $site);
+
+    # Zip up the collection archives
+    my $java = $gsdl_cgi->get_java_path();
+    my $java_classpath = &util::filename_cat($ENV{'GSDLHOME'}, "bin", "java", "GLIServer.jar");
+    my $zip_file_path = &util::filename_cat($collect_directory, $collection . "-archives-" . $timestamp . ".zip");
+    my $java_args = "\"$zip_file_path\" \"$collect_directory\" \"$collection\"";
+    $ENV{'LANG'} = $lang_env;
+    my $java_command = "\"$java\" -classpath \"$java_classpath\" org.greenstone.gatherer.remote.ZipCollectionArchives $java_args"; 
+
+    my $java_output = `$java_command`;
+    my $java_status = $?;
+    if ($java_status > 0) {
+	$gsdl_cgi->generate_error("Java failed: $java_command\n--\n$java_output\nExit status: " . ($java_status / 256) . "\n" . $gsdl_cgi->check_java_home());
+    }
+
+    # Check that the zip file was created successfully
+    if (!-e $zip_file_path || -z $zip_file_path) {
+	$gsdl_cgi->generate_error("Collection archives zip file $zip_file_path could not be created.");
+    }
+
+    &put_file($gsdl_cgi, $zip_file_path, "application/zip");
+    unlink("$zip_file_path") unless $debugging_enabled;
+}
+
+
+# Collection locking unnecessary because this action isn't related to a particular collection
+sub download_collection_configurations
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+
+    # language and region Environment Variable setting on the client side that was used to zip files.
+    my $lang_env = $gsdl_cgi->clean_param("lr") || "";
+    $gsdl_cgi->delete("lr");
+   
+    # Users can be in any group to perform this action
+    my $user_groups = &authenticate_user($gsdl_cgi, $username, "", $site);
+
+    my $collect_directory = $gsdl_cgi->get_collection_dir($site);
+    $gsdl_cgi->checked_chdir($collect_directory);
+
+    # Zip up the collection configurations
+    my $java = $gsdl_cgi->get_java_path();
+    my $java_classpath = &util::filename_cat($ENV{'GSDLHOME'}, "bin", "java", "GLIServer.jar");
+    my $zip_file_path = &util::filename_cat($collect_directory, "collection-configurations-" . $timestamp . ".zip");
+    my $java_args = "\"$zip_file_path\" \"$collect_directory\" \"$username\" \"$user_groups\"";
+    $ENV{'LANG'} = $lang_env;
+    my $java_command = "\"$java\" -classpath \"$java_classpath\" org.greenstone.gatherer.remote.ZipCollectionConfigurations $java_args"; 
+    my $java_output = `$java_command`;
+    my $java_status = $?;
+    if ($java_status > 0) {
+	$gsdl_cgi->generate_error("Java failed: $java_command\n--\n$java_output\nExit status: " . ($java_status / 256) . "\n" . $gsdl_cgi->check_java_home());
+    }
+
+    # Check that the zip file was created successfully
+    if (!-e $zip_file_path || -z $zip_file_path) {
+	$gsdl_cgi->generate_error("Collection configurations zip file $zip_file_path could not be created.");
+    }
+    
+    &put_file($gsdl_cgi, $zip_file_path, "application/zip");
+    unlink("$zip_file_path") unless $debugging_enabled;
+}
+
+# Method that will check if the given file exists
+# No error message: all messages generated are OK messages
+# This method will simply state whether the file exists or does not exist.
+sub file_exists
+{
+    my ($gsdl_cgi, $site) = @_;
+
+    my $collection = $gsdl_cgi->clean_param("c");
+    if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No collection specified.");
+    }
+    my $file = $gsdl_cgi->clean_param("file");
+    if ((!defined $file) || ($file =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No file specified.");
+    }
+    $file = "\"$file\"";   # Windows: bookend the relative filepath with quotes in case it contains spaces
+    $file = $gsdl_cgi->decode($file);
+    $file =~ s/\|/&util::get_dirsep()/eg;  # Convert the '|' characters into whatever is right for this OS
+
+    # Not necessary: checking whether the user is authenticated to query existence of the file
+    #&authenticate_user($gsdl_cgi, $username, $collection);
+
+    my $collection_directory = $gsdl_cgi->get_collection_dir($site, $collection);
+    $gsdl_cgi->checked_chdir($collection_directory); # cd into the directory of that collection
+
+    # Check that the collection file exists
+    if (-e $file) {
+	$gsdl_cgi->generate_ok_message("File $file exists.");
+    } else {
+	$gsdl_cgi->generate_ok_message("File $file does not exist.");
+    }
+}
+
+sub download_collection_file
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+
+    my $collection = $gsdl_cgi->clean_param("c");
+    if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No collection specified.");
+    }
+    # language and region Environment Variable setting on the client side that was used to zip files.
+    my $lang_env = $gsdl_cgi->clean_param("lr") || "";
+    $gsdl_cgi->delete("lr");
+    my $file = $gsdl_cgi->clean_param("file");
+    if ((!defined $file) || ($file =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No file specified.");
+    }
+    $file =~ s/\|/&util::get_dirsep()/eg;  # Convert the '|' characters into whatever is right for this OS
+
+    # Make sure we don't try to download anything outside the collection
+    if ($file =~ m/\.\./) {
+	$gsdl_cgi->generate_error("Illegal file specified.");
+    }
+
+    # Ensure the user is allowed to edit this collection
+    &authenticate_user($gsdl_cgi, $username, $collection, $site);
+
+    my $collection_directory = $gsdl_cgi->get_collection_dir($site, $collection);
+    $gsdl_cgi->checked_chdir($collection_directory);
+
+    # Check that the collection file exists
+    if (!-e $file) {
+	$gsdl_cgi->generate_ok_message("Collection file $file does not exist.");
+	die;
+    }
+
+    # Make sure the collection isn't locked by someone else
+    &lock_collection($gsdl_cgi, $username, $collection, $site);
+
+    # Zip up the collection file
+    my $java = $gsdl_cgi->get_java_path();
+    my $java_classpath = &util::filename_cat($ENV{'GSDLHOME'}, "bin", "java", "GLIServer.jar");
+    my $zip_file_path = &util::filename_cat($collection_directory, $collection . "-file-" . $timestamp . ".zip");
+    my $java_args = "\"$zip_file_path\" \"$collection_directory\" \"$file\"";
+    $ENV{'LANG'} = $lang_env;
+    my $java_command = "\"$java\" -classpath \"$java_classpath\" org.greenstone.gatherer.remote.ZipFiles $java_args"; 
+
+    my $java_output = `$java_command`;
+    my $java_status = $?;
+    if ($java_status > 0) {
+	$gsdl_cgi->generate_error("Java failed: $java_command\n--\n$java_output\nExit status: " . ($java_status / 256) . "\n" . $gsdl_cgi->check_java_home());
+    }
+
+    # Check that the zip file was created successfully
+    if (!-e $zip_file_path || -z $zip_file_path) {
+	$gsdl_cgi->generate_error("Collection archives zip file $zip_file_path could not be created.");
+    }
+
+    &put_file($gsdl_cgi, $zip_file_path, "application/zip");
+    unlink("$zip_file_path") unless $debugging_enabled;
+}
+
+# download web.xml from the server
+sub download_web_xml_file
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+
+    # Users can be in any group to perform this action
+    my $user_groups = &authenticate_user($gsdl_cgi, $username, "", $site);
+
+    # language and region Environment Variable setting on the client side that was used to zip files.
+    my $lang_env = $gsdl_cgi->clean_param("lr") || "";
+    $gsdl_cgi->delete("lr");
+    my $file = $gsdl_cgi->clean_param("file");
+    if ((!defined $file) || ($file =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No file specified.");
+    }
+    $file =~ s/\|/&util::get_dirsep()/eg;  # Convert the '|' characters into whatever is right for this OS
+
+    # Make sure we don't try to download anything else
+    if ($file =~ m/\.\./) {
+	$gsdl_cgi->generate_error("Illegal file specified.");
+    }
+
+    my $web_inf_directory = &util::filename_cat($ENV{'GSDL3SRCHOME'}, "web", "WEB-INF");
+    $gsdl_cgi->checked_chdir($web_inf_directory);
+
+    # Check that the collection file exists
+    if (!-e $file) {
+	$gsdl_cgi->generate_error("file $file does not exist.");
+    }
+
+    # Zip up the collection file
+    my $java = $gsdl_cgi->get_java_path();
+    my $java_classpath = &util::filename_cat($ENV{'GSDLHOME'}, "bin", "java", "GLIServer.jar");
+    my $zip_file_path = &util::filename_cat($web_inf_directory, "webxml" . $timestamp . ".zip");
+    my $java_args = "\"$zip_file_path\" \"$web_inf_directory\" \"$file\"";
+    $ENV{'LANG'} = $lang_env;
+    my $java_command = "\"$java\" -classpath \"$java_classpath\" org.greenstone.gatherer.remote.ZipFiles $java_args"; 
+    my $java_output = `$java_command`;
+
+    my $java_status = $?;
+    if ($java_status > 0) {
+	$gsdl_cgi->generate_error("Java failed: $java_command\n--\n$java_output\nExit status: " . ($java_status / 256) . "\n" . $gsdl_cgi->check_java_home());
+    }
+
+    # Check that the zip file was created successfully
+    if (!-e $zip_file_path || -z $zip_file_path) {
+	$gsdl_cgi->generate_error("web.xml zip file $zip_file_path could not be created.");
+    }
+
+    &put_file($gsdl_cgi, $zip_file_path, "application/zip");
+
+    unlink("$zip_file_path") unless $debugging_enabled;
+}
+
+# Collection locking unnecessary because this action isn't related to a particular collection
+sub get_script_options
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+
+    my $script = $gsdl_cgi->clean_param("script");
+    if ((!defined $script) || ($script =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No script specified.");
+    }
+    $gsdl_cgi->delete("script");
+
+    # Users can be in any group to perform this action
+    &authenticate_user($gsdl_cgi, $username, "", $site);
+    $gsdl_cgi->delete("ts"); ## two lines from GS3 version, doesn't seem to harm GS2
+    $gsdl_cgi->delete("pw"); 
+    
+
+    my $perl_args = "";
+    if ($script eq "classinfo.pl") {
+	$perl_args = $gsdl_cgi->clean_param("classifier") || "";
+	$gsdl_cgi->delete("classifier");
+    }
+    if ($script eq "pluginfo.pl") {
+	$perl_args = $gsdl_cgi->clean_param("plugin") || "";
+	$gsdl_cgi->delete("plugin");
+    }
+    if ($script eq "downloadinfo.pl") {
+	$perl_args = $gsdl_cgi->clean_param("downloader") || "";
+	$gsdl_cgi->delete("downloader");
+    }
+
+    foreach my $cgi_arg_name ($gsdl_cgi->param) {
+	my $cgi_arg_value = $gsdl_cgi->clean_param($cgi_arg_name) || "";
+	$cgi_arg_value = $gsdl_cgi->safe_val($cgi_arg_value);
+	if ($cgi_arg_value eq "") {
+	    $perl_args = "-$cgi_arg_name " . $perl_args;
+	}
+	else {
+	    $perl_args = "-$cgi_arg_name \"$cgi_arg_value\" " . $perl_args;
+	}
+    }
+
+
+    # IIS 6: redirecting output from STDERR to STDOUT just doesn't work, so we have to let it go
+    #   directly out to the page
+    print STDOUT "Content-type:text/plain\n\n";
+    my $perl_command;
+    if($iis6_mode && $gsdl_cgi->greenstone_version() == 2)
+    {
+	$perl_command = "perl -S $script $perl_args";
+    } else {
+	$perl_command = "perl -S $script $perl_args 2>&1";
+    }
+
+    my $perl_output = `$perl_command`;
+    my $perl_status = $?;
+    if ($perl_status > 0) {
+	$gsdl_cgi->generate_error("Perl failed: $perl_command\n--\n$perl_output\nExit status: " . ($perl_status / 256));
+    }
+
+    if (defined($perl_output))
+    {
+	print STDOUT $perl_output;
+    }
+}
+
+# get the names of all sites available on the server
+sub get_site_names
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+    my $sites_directory = &util::filename_cat($ENV{'GSDL3SRCHOME'}, "web", "sites");
+
+    my @sites_dir;
+    my @site_dir;
+    
+    $gsdl_cgi->checked_chdir($sites_directory);
+    opendir(DIR, $sites_directory);
+    @sites_dir= readdir(DIR);
+    my $sites_dir;
+    my $sub_dir_file;
+
+    print STDOUT "Content-type:text/plain\n\n";
+    foreach $sites_dir(@sites_dir)
+    {
+	if (!(($sites_dir eq ".") || ($sites_dir eq "..") || ($sites_dir eq "CVS")))
+	{
+	    my $site_dir_path= &util::filename_cat($sites_directory,$sites_dir);
+	    $gsdl_cgi->checked_chdir($site_dir_path);
+	    opendir(DIR,$site_dir_path);
+	    @site_dir=readdir(DIR);
+	    closedir(DIR);
+	    
+	    foreach $sub_dir_file(@site_dir)
+	    {
+		if ($sub_dir_file eq "siteConfig.xml"){
+		    print STDOUT "$sites_dir" . "-----";
+		}
+	    }
+	}
+    }
+
+}
+
+sub move_collection_file
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+
+    my $collection = $gsdl_cgi->clean_param("c");
+    if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No collection specified.");
+    }
+    my $source_file = $gsdl_cgi->clean_param("source");
+    if ((!defined $source_file) || ($source_file =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No source file specified.");
+    }
+    $source_file = $gsdl_cgi->decode($source_file);
+    $source_file =~ s/\|/&util::get_dirsep()/eg;  # Convert the '|' characters into whatever is right for this OS
+    my $target_file = $gsdl_cgi->clean_param("target");
+    if ((!defined $target_file) || ($target_file =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No target file specified.");
+    }
+    $target_file = $gsdl_cgi->decode($target_file);
+    $target_file =~ s/\|/&util::get_dirsep()/eg;  # Convert the '|' characters into whatever is right for this OS
+
+    # Make sure we don't try to move anything outside the collection
+    if ($source_file =~ m/\.\./ || $target_file =~ m/\.\./) {
+	$gsdl_cgi->generate_error("Illegal file specified.");
+    }
+
+    # Ensure the user is allowed to edit this collection
+    &authenticate_user($gsdl_cgi, $username, $collection, $site);
+
+    my $collection_directory = $gsdl_cgi->get_collection_dir($site, $collection);
+    $gsdl_cgi->checked_chdir($collection_directory);
+
+    # Check that the collection source file exists
+    if (!-e $source_file) {
+	$gsdl_cgi->generate_error("Collection file $source_file does not exist.");
+    }
+
+    # Make sure the collection isn't locked by someone else
+    &lock_collection($gsdl_cgi, $username, $collection, $site);
+
+    &util::mv($source_file, $target_file);
+
+    # Check that the collection source file was moved
+    if (-e $source_file || !-e $target_file) {
+	$gsdl_cgi->generate_error("Could not move collection file $source_file to $target_file."); # dies
+    }
+
+    $gsdl_cgi->generate_ok_message("Collection file $source_file moved to $target_file successfully.");
+}
+
+
+sub new_collection_directory
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+
+    my $collection = $gsdl_cgi->clean_param("c");
+    if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No collection specified.");
+    }
+    my $directory = $gsdl_cgi->clean_param("directory");
+    if ((!defined $directory) || ($directory =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No directory specified.");
+    }
+    $directory =~ s/\|/&util::get_dirsep()/eg;  # Convert the '|' characters into whatever is right for this OS
+
+    # Make sure we don't try to create anything outside the collection
+    if ($directory =~ m/\.\./) {
+	$gsdl_cgi->generate_error("Illegal directory specified.");
+    }
+
+    # Ensure the user is allowed to edit this collection
+    &authenticate_user($gsdl_cgi, $username, $collection, $site);
+
+    my $collection_directory = $gsdl_cgi->get_collection_dir($site, $collection);
+    $gsdl_cgi->checked_chdir($collection_directory);
+
+    # Check that the collection directory doesn't already exist
+    # ZipTools doesn't zip up empty directories, so this causes an error when downloading a new collection as we explicitly
+    # try to create the import directory
+## log -r13497 for GS2's gliserver.pl, Katherine Don explains:
+# "commented out checking for existence of a directory in new_collection_directory 
+# as it throws an error which we don't want"
+    #if($gsdl_cgi->greenstone_version() != 2 && -d $directory) {
+	#$gsdl_cgi->generate_error("Collection directory $directory already exists.");
+    #}
+
+    # Make sure the collection isn't locked by someone else
+    &lock_collection($gsdl_cgi, $username, $collection, $site);
+
+    &util::mk_dir($directory);
+
+    # Check that the collection directory was created
+    if (!-d $directory) {
+	$gsdl_cgi->generate_error("Could not create collection directory $directory.");
+    }
+
+    $gsdl_cgi->generate_ok_message("Collection directory $directory created successfully.");
+}
+
+
+sub run_script
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+
+    my $script = $gsdl_cgi->clean_param("script");
+    if ((!defined $script) || ($script =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No script specified.");
+    }
+    $gsdl_cgi->delete("script");
+ 
+    my $collection = $gsdl_cgi->clean_param("c");
+    if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No collection specified.");
+    }
+    $gsdl_cgi->delete("c");
+
+    # confuse other, so delete timestamp
+    $gsdl_cgi->delete("ts");
+
+    # Ensure the user is allowed to edit this collection
+    &authenticate_user($gsdl_cgi, $username, $collection, $site);
+
+    # Make sure the collection isn't locked by someone else (unless we're running mkcol.pl, of course)
+    &lock_collection($gsdl_cgi, $username, $collection, $site) unless ($script eq "mkcol.pl");
+
+    # Last argument is the collection name, except for explode_metadata_database.pl and
+    # replace_srcdoc_with_html (where there's a "file" option followed by the filename. These two preceed the collection name)
+    my $perl_args = $collection;
+    if ($script eq "explode_metadata_database.pl" || $script eq "replace_srcdoc_with_html.pl") {
+	# Last argument is the file to be exploded or it is the file to be replaced with its html version
+	my $file = $gsdl_cgi->clean_param("file");
+	if ((!defined $file) || ($file =~ m/^\s*$/)) {
+	    $gsdl_cgi->generate_error("No file specified.");
+	}
+	$gsdl_cgi->delete("file");	
+	$file = $gsdl_cgi->decode($file);
+	$file = "\"$file\""; # Windows: bookend the relative filepath with quotes in case it contains spaces 
+	$perl_args = $file;
+    }
+
+    foreach my $cgi_arg_name ($gsdl_cgi->param) {
+	my $cgi_arg_value = $gsdl_cgi->safe_val($gsdl_cgi->clean_param($cgi_arg_name));
+	if ($cgi_arg_value eq "") {
+	    $perl_args = "-$cgi_arg_name " . $perl_args;
+	}
+	else {
+	    $perl_args = "-$cgi_arg_name \"$cgi_arg_value\" " . $perl_args;
+	}
+    }
+
+    # mkcol.pl and import.pl, buildcol.pl, g2f-import.pl, g2f-buildcol.pl all need the -collectdir option passed
+    my $import_pl = "import.pl"; # import is a reserved word, need to put it in quotes
+    
+    if (($script =~ m/$import_pl|buildcol.pl/) || ($script eq "mkcol.pl")) { # || ($script eq "schedule.pl")
+	my $collect_directory = $gsdl_cgi->get_collection_dir($site); 
+	$perl_args = $perl_args . " -collectdir \"$collect_directory\"";
+    }
+
+    my $perl_command = "perl -S $script $perl_args 2>&1";
+    # IIS 6: redirecting output from STDERR to STDOUT just doesn't work, so we have to let it go
+    #   directly out to the page
+    if($gsdl_cgi->greenstone_version() == 2 && $iis6_mode)
+    {
+	$perl_command = "perl -S $script $perl_args";
+    }
+    if (!open(PIN, "$perl_command |")) {
+	$gsdl_cgi->generate_error("Unable to execute command: $perl_command");
+    }
+
+    print STDOUT "Content-type:text/plain\n\n";
+    print "$perl_command  \n";
+
+    while (defined (my $perl_output_line = <PIN>)) {
+	print STDOUT $perl_output_line;
+    }
+    close(PIN);
+
+    my $perl_status = $?;
+    if ($perl_status > 0) {
+	$gsdl_cgi->generate_error("Perl failed: $perl_command\n--\nExit status: " . ($perl_status / 256));
+    }
+    elsif ($mail_enabled) {
+	if ($script eq "buildcol.pl") {
+	    &send_mail($gsdl_cgi, "Remote Greenstone building event", "Build of collection '$collection' complete.");
+	}
+    }
+}
+
+sub upload_collection_file
+{
+    my ($gsdl_cgi, $username, $timestamp, $site) = @_;
+   
+    my $collection = $gsdl_cgi->clean_param("c");
+    if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No collection specified.");
+    }
+    my $file = $gsdl_cgi->clean_param("file");
+    if ((!defined $file) || ($file =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No file specified.");
+    }
+    my $directory = $gsdl_cgi->clean_param("directory") || "";
+    $directory =~ s/\|/&util::get_dirsep()/eg;  # Convert the '|' characters into whatever is right for this OS
+    my $zip = $gsdl_cgi->clean_param("zip");
+
+    # language and region Environment Variable setting on the client side that was used to
+    # zip files. This needs to be consistent on both client and server sides, otherwise zip 
+    # and unzip seem to produce different values.
+    my $lang_env = $gsdl_cgi->clean_param("lr") || "";
+    $gsdl_cgi->delete("lr");
+
+    # Make sure we don't try to upload anything outside the collection
+    if ($file =~ m/\.\./) {
+	$gsdl_cgi->generate_error("Illegal file specified.");
+    }
+    if ($directory =~ m/\.\./) {
+	$gsdl_cgi->generate_error("Illegal directory specified.");
+    }
+
+    # Ensure the user is allowed to edit this collection
+    if($gsdl_cgi->greenstone_version() == 2) { ## Quan commented this out for GS3 in r14325
+	&authenticate_user($gsdl_cgi, $username, $collection, $site); # site will be undefined for GS2, of course
+    }
+
+    my $collection_directory = $gsdl_cgi->get_collection_dir($site, $collection);
+    $gsdl_cgi->checked_chdir($collection_directory);
+
+    # Make sure the collection isn't locked by someone else
+    &lock_collection($gsdl_cgi, $username, $collection, $site);
+
+    my $directory_path = &util::filename_cat($collection_directory, $directory);
+    if (!-d $directory_path) {
+	&util::mk_dir($directory_path);
+	if (!-d $directory_path) {
+	    $gsdl_cgi->generate_error("Could not create directory $directory_path.");
+	}
+    }
+
+    #my $file_path = &util::filename_cat($directory_path, $file . "-" . $timestamp); 
+    my $file_path = "";
+    if($gsdl_cgi->greenstone_version() == 2) {
+	$file_path = &util::filename_cat($directory_path, $file . "-" . $timestamp); 
+    } else {
+	$file_path = &util::filename_cat($directory_path, $file); 
+    }
+   
+    if (!open(FOUT, ">$file_path")) {
+	print STDERR "Unable to write file $file_path\n";
+	$gsdl_cgi->generate_error("Unable to write file $file_path");
+    }
+
+    # Read the uploaded data and write it out to file
+    my $buf;
+    my $num_bytes = 0;
+    binmode(FOUT);
+    if($gsdl_cgi->greenstone_version() == 2) { ##
+	# We have to pass the size of the uploaded data in the "fs" argument because IIS 6 seems to be
+	#   completely incapable of working this out otherwise (causing the old code to crash)
+	my $num_bytes_remaining = $gsdl_cgi->clean_param("fs");
+	my $bytes_to_read = $num_bytes_remaining;
+	if ($bytes_to_read > 1024) { $bytes_to_read = 1024; }
+
+	while (read(STDIN, $buf, $bytes_to_read) > 0) {
+	    print FOUT $buf;
+	    $num_bytes += length($buf);
+	    $num_bytes_remaining -= length($buf);
+	    $bytes_to_read = $num_bytes_remaining;
+	    if ($bytes_to_read > 1024) { $bytes_to_read = 1024; }
+	}
+    } else { # GS3 and later
+    	my $bread;
+	my $fh = $gsdl_cgi->clean_param("uploaded_file");
+
+	if (!defined $fh) {
+	    print STDERR "ERROR. Filehandle undefined. No file uploaded onto GS3 server.\n";
+	    $gsdl_cgi->generate_error("ERROR. Filehandle undefined. No file uploaded (GS3 server).");
+	} else {
+	    while ($bread=read($fh, $buf, 1024)) {
+		print FOUT $buf;
+	    }
+	}
+    }
+    close(FOUT);
+       
+    # If we have downloaded a zip file, unzip it
+    if (defined $zip) {
+	my $java = $gsdl_cgi->get_java_path();
+	my $java_classpath = &util::filename_cat($ENV{'GSDLHOME'}, "bin", "java", "GLIServer.jar");
+	my $java_args = "\"$file_path\" \"$directory_path\"";
+	$ENV{'LANG'} = $lang_env;
+	my $java_command = "\"$java\" -classpath \"$java_classpath\" org.greenstone.gatherer.remote.Unzip $java_args"; 
+	my $java_output = `$java_command`;
+	my $java_status = $?;
+
+	# Remove the zip file once we have unzipped it, since it is an intermediate file only
+	unlink("$file_path") unless $debugging_enabled;
+	
+	if ($java_status > 0) {
+	    $gsdl_cgi->generate_error("Java failed: $java_command\n--\n$java_output\nExit status: " . ($java_status / 256) . "\n" . $gsdl_cgi->check_java_home()); # dies
+	}
+    }
+
+    $gsdl_cgi->generate_ok_message("Collection file $file uploaded successfully.");
+}
+
+sub put_file
+{
+    my $gsdl_cgi = shift(@_);
+    my $file_path = shift(@_);
+    my $content_type = shift(@_);
+
+    if(!defined $content_type) { ##
+	$content_type = "application/zip";
+    }
+	
+    if (open(PIN, "<$file_path")) {
+	print STDOUT "Content-type:$content_type\n\n"; ## For GS3: "Content-type:application/zip\n\n";
+ 	my $buf;
+ 	my $num_bytes = 0;
+ 	binmode(PIN);
+ 	while (read(PIN, $buf, 1024) > 0) {
+ 	    print STDOUT $buf;
+ 	    $num_bytes += length($buf);
+ 	}
+
+ 	close(PIN);
+    }
+    else {
+	$gsdl_cgi->generate_error("Unable to read file $file_path\n  $!");
+    }
+}
+
+sub send_mail
+{
+    my $gsdl_cgi = shift(@_);
+    my $mail_subject = shift(@_);
+    my $mail_content = shift(@_);
+
+    my $sendmail_command = "perl -S sendmail.pl";
+    $sendmail_command .= " -to \"" . $mail_to_address . "\"";
+    $sendmail_command .= " -from \"" . $mail_from_address . "\"";
+    $sendmail_command .= " -smtp \"" . $mail_smtp_server . "\"";
+    $sendmail_command .= " -subject \"" . $mail_subject . "\"";
+
+    if (!open(POUT, "| $sendmail_command")) {
+	$gsdl_cgi->generate_error("Unable to execute command: $sendmail_command");
+    }
+    print POUT $mail_content . "\n";
+    close(POUT);
+}
+
+sub greenstone_server_version
+{	
+    my $gsdl_cgi = shift(@_);
+    my $version = $gsdl_cgi->greenstone_version();
+    $gsdl_cgi->generate_ok_message("Greenstone server version is: $version\n");
+}
+
+sub get_library_url_suffix
+{
+    my $gsdl_cgi = shift(@_);
+    my $library_url = $gsdl_cgi->library_url_suffix();
+    $gsdl_cgi->generate_ok_message("Greenstone library URL suffix is: $library_url\n");
+}
+
+&main();
Index: /gsdl/stable/cgi-bin/gsdlCGI.pm
===================================================================
--- /gsdl/stable/cgi-bin/gsdlCGI.pm	(revision 20131)
+++ /gsdl/stable/cgi-bin/gsdlCGI.pm	(revision 20131)
@@ -0,0 +1,618 @@
+package gsdlCGI;
+
+# This file merges Michael Dewsnip's gsdlCGI.pm for GS2 and Quan Qiu's gsdlCGI4gs3.pm (GS3)
+
+use strict; 
+no strict 'subs';
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+use CGI;
+use Cwd;
+use MIME::Base64;
+
+@gsdlCGI::ISA = ( 'CGI' ); 
+
+sub new {
+    my $class = shift @_;
+    
+    my $self;
+   
+    # We'll determine the correct config file in this constructor itself 
+    # and use it to determine the Greenstone server's version. 
+    # Perhaps later, another test can be used for finding out what version 
+    # of the Greenstone server we are working with.
+    my $version;
+    if (-e "gsdl3site.cfg") {
+	$version = 3;
+    } else {
+	$version = 2;
+    }
+
+    if ((defined $ENV{'REQUEST_METHOD'}) && ($ENV{'REQUEST_METHOD'} eq "POST")) {
+
+	# Check if we're dealing with the upload-coll-file cmd. Because it will be a 
+	# multipart POST message and must be dealt with by the default CGI() constructor
+	if((defined $ENV{'QUERY_STRING'}) && ($ENV{'QUERY_STRING'} =~ m/upload-collection-file/)) {
+	    $self = new CGI(); 
+	} 
+
+	else { # all other POST commands processed using CGI($line)
+	    my $line = <STDIN>;
+	    if ((defined $line) && ($line ne "")) { 
+		$self = new CGI($line);
+	    }
+	}
+	
+    }    
+    
+    # If one of the conditions above did not hold, then self=new CGI() 
+    if (!defined $self) { 
+	$self = new CGI();
+    }
+
+    if ($version == 2) {
+	$self->{'site_filename'} = "gsdlsite.cfg";
+	$self->{'greenstone_version'} = 2;
+    } 
+    elsif ($version == 3) {
+	$self->{'site_filename'} = "gsdl3site.cfg";
+	$self->{'greenstone_version'} = 3;
+    }
+    
+    return bless $self, $class;
+}
+
+
+sub parse_cgi_args
+{
+    my $self = shift @_;
+    my $xml = (defined $self->param("xml")) ? 1 : 0;
+
+    $self->{'xml'} = $xml;
+
+    my @var_names = $self->param;
+    my @arg_list = ();
+    foreach my $n ( @var_names ) {
+	my $arg = "$n=";
+	my $val =  $self->param($n);
+	$arg .= $val if (defined $val);
+	push(@arg_list,$arg);
+    }
+	
+    $self->{'args'} = join("&",@arg_list);
+}
+
+
+sub clean_param
+{
+    my $self = shift @_;
+    my ($param) = @_;
+
+    my $val = $self->SUPER::param($param);
+    $val =~ s/[\r\n]+$// if (defined $val);
+
+    return $val;
+}
+
+sub safe_val
+{
+    my $self = shift @_;
+    my ($val) = @_;
+
+    # ensure only alpha-numeric plus a few other special chars remain
+
+    $val =~ s/[^[:alnum:]@\.\/\- :_]//g if (defined $val); 
+
+    return $val;
+}
+
+sub generate_message
+{
+    my $self = shift @_;
+    my ($message) = @_;
+    
+    #if($self->{'greenstone_version'} == 2) { # plain text, for IIS 6
+	print STDOUT "Content-type:text/plain\n\n$message";
+    #} else {
+	#print "Content-type:text/html\n\n";
+	#print "<pre>";
+	#print STDOUT $message;
+	#print "</pre>";
+    #}
+}
+
+sub generate_error
+{
+    my $self = shift @_;
+    my ($mess) = @_;
+    
+    my $xml = $self->{'xml'};
+
+    my $full_mess;
+    my $args = $self->{'args'};
+
+    if ($xml) {
+	# Make $args XML safe
+	my $args_xml_safe = $args;
+	$args_xml_safe =~ s/&/&amp;/g;
+
+	$full_mess =  "<Error>\n";
+	$full_mess .= "  $mess\n";
+	$full_mess .= "  CGI args were: $args_xml_safe\n";
+	$full_mess .= "</Error>\n";
+    }
+    else {
+	$full_mess = "ERROR: $mess\n  ($args)\n";
+    }
+
+    $self->generate_message($full_mess);
+
+    die $full_mess;
+}
+
+sub generate_warning
+{
+    my $self = shift @_;
+    my ($mess) = @_;
+    
+    my $xml = $self->{'xml'};
+
+    my $full_mess;
+    my $args = $self->{'args'};
+
+    if ($xml) {
+	# Make $args XML safe
+	my $args_xml_safe = $args;
+	$args_xml_safe =~ s/&/&amp;/g;
+
+	$full_mess =  "<Warning>\n";
+	$full_mess .= "  $mess\n";
+	$full_mess .= "  CGI args were: $args_xml_safe\n";
+	$full_mess .= "</Warning>\n";
+    }
+    else {
+	$full_mess = "Warning: $mess ($args)\n";
+    }
+
+    $self->generate_message($full_mess);
+
+    print STDERR $full_mess;
+}
+
+
+sub generate_ok_message
+{
+    my $self = shift @_;
+    my ($mess) = @_;
+    
+    my $xml = $self->{'xml'};
+
+    my $full_mess;
+
+    if ($xml) {
+	$full_mess =  "<Accepted>\n";
+	$full_mess .= "  $mess\n";
+	$full_mess .= "</Accepted>\n";
+    }
+    else {
+	$full_mess = "$mess\n";
+    }
+ 
+    $self->generate_message($full_mess);
+}
+
+
+
+sub get_config_info {
+    my $self = shift @_;
+    my ($infotype, $optional) = @_;
+
+    my $site_filename = $self->{'site_filename'};
+    open (FILEIN, "<$site_filename") 
+	|| $self->generate_error("Could not open $site_filename");
+
+    my $config_content = "";
+    while(defined (my $line = <FILEIN>)) {
+	$config_content .= $line;
+    }
+    close(FILEIN);
+
+    my ($loc) = ($config_content =~ m/^$infotype\s+((\".+\")|(\S+))\s*\n/m);
+    $loc =~ s/\"//g if defined $loc;
+
+    if ((!defined $loc) || ($loc =~ m/^\s*$/)) {
+	if((!defined $optional) || (!$optional)) {
+	    $self->generate_error("$infotype is not set in $site_filename");
+	}
+    }
+
+    return $loc;
+}
+
+sub get_gsdl3_src_home{
+    my $self = shift @_;
+    if (defined $self->{'gsdl3srchome'}) {
+	return $self->{'gsdl3srchome'};
+    }
+
+    my $gsdl3srchome = $self->get_config_info("gsdl3srchome");
+
+    if(defined $gsdl3srchome) {
+	$gsdl3srchome =~ s/(\/|\\)$//; # remove trailing slash
+    }
+    $self->{'gsdl3srchome'} = $gsdl3srchome;
+
+    return $gsdl3srchome;
+}
+
+
+sub get_gsdl_home {
+    my $self = shift @_;
+    
+    if (defined $self->{'gsdlhome'}) {
+	return $self->{'gsdlhome'};
+    }
+
+    my $gsdlhome = $self->get_config_info("gsdlhome");
+
+    $gsdlhome =~ s/(\/|\\)$//; # remove trailing slash
+
+    $self->{'gsdlhome'} = $gsdlhome;
+
+    return $gsdlhome;
+}
+
+sub get_gsdl3_home {
+    my $self = shift @_;
+    my ($optional) = @_;
+    
+    if (defined $self->{'gsdl3home'}) {
+	return $self->{'gsdl3home'};
+    }
+
+    my $gsdl3home = $self->get_config_info("gsdl3home", $optional);
+
+    if(defined $gsdl3home) {
+	$gsdl3home =~ s/(\/|\\)$//; # remove trailing slash
+	$self->{'gsdl3home'} = $gsdl3home;
+    }
+    return $gsdl3home;
+}
+
+sub get_java_home {
+    my $self = shift @_;
+    my ($optional) = @_;
+    
+    if (defined $self->{'javahome'}) {
+	return $self->{'javahome'};
+    }
+
+    my $javahome = $self->get_config_info("javahome", $optional);
+    if(defined $javahome) {
+	$javahome =~ s/(\/|\\)$//; # remove trailing slash
+	$self->{'javahome'} = $javahome;
+    }
+    return $javahome;
+}
+
+sub get_perl_path {
+    my $self = shift @_;
+    my ($optional) = @_;
+    
+    if (defined $self->{'perlpath'}) {
+	return $self->{'perlpath'};
+    }
+
+    my $perlpath = $self->get_config_info("perlpath", $optional);
+
+    if(defined $perlpath) {
+	$perlpath =~ s/(\/|\\)$//; # remove trailing slash
+	$self->{'perlpath'} = $perlpath;
+    }
+    return $perlpath;
+}
+
+sub get_gsdl_os {
+    my $self = shift @_;
+    
+    my $os = $^O;
+
+    if ($os =~ m/linux/i) {
+	return "linux";
+    }
+    elsif ($os =~ m/mswin/i) {
+	return "windows";
+    }
+    elsif ($os =~ m/macos/i) {
+	return "darwin";
+    }
+    else {
+	# return as is.
+	return $os;
+    }
+}
+
+sub get_library_url_suffix {
+    my $self = shift @_;
+    
+    if (defined $self->{'library_url_suffix'}) {
+	return $self->{'library_url_suffix'};
+    }
+
+    my $optional = 1; # ignore absence of gwcgi if not found
+    my $library_url = $self->get_config_info("gwcgi", $optional);
+    if(defined $library_url) {
+	$library_url =~ s/(\/|\\)$//; # remove trailing slash
+    }
+    else {
+
+	if($self->{'greenstone_version'} == 2) {
+	    $library_url = $self->get_config_info("httpprefix", $optional);
+	    $library_url = "/greenstone" unless defined $library_url;
+	    $library_url = "$library_url/cgi-bin/library.cgi"; # same extension for linux and windows
+	} 
+	else { # greenstone 3 or later and gwcgi not defined
+	    $library_url = "/greenstone3"; #"/greenstone3/library";
+	}
+    }
+
+    $self->{'library_url_suffix'} = $library_url;
+    return $library_url;
+}
+
+sub setup_fedora_homes {
+    my $self = shift @_;
+    my ($optional) = @_;
+
+    # The following will still allow the FEDORA_HOME and FEDORA_VERSION environment 
+    # variables to have been set outside the gsdlsite.cfg file. Existing env vars 
+    # are only overwritten if they've *also* been defined in gsdlsite.cfg.
+
+    if (!defined $self->{'fedora_home'}) # Don't need to go through it all again if we'd already done this before
+    {
+	# First look in the gsdlsite.cfg file for the fedora properties to be defined
+	# and set $ENV{FEDORA_HOME} and $ENV{FEDORA_VERSION} if values were provided
+	$self->{'fedora_home'} = $self->get_config_info("fedorahome", $optional);
+	
+	if (defined $self->{'fedora_home'}) {
+	    $ENV{'FEDORA_HOME'} = $self->{'fedora_home'}; 
+	} 
+	elsif (defined $ENV{'FEDORA_HOME'}) { # check environment variable
+	    $self->{'fedora_home'} = $ENV{'FEDORA_HOME'};
+	}
+	
+	# if FEDORA_HOME is now defined, we can look for the fedora version that is being used
+	if (defined $ENV{'FEDORA_HOME'}) 
+	{
+	    # first look in the file
+	    $self->{'fedora_version'} = $self->get_config_info("fedoraversion", $optional);
+
+	    if (defined $self->{'fedora_version'}) {
+		$ENV{'FEDORA_VERSION'} = $self->{'fedora_version'};
+	    } 
+	    elsif (defined $ENV{'FEDORA_VERSION'}) { # then check environment variable
+		$self->{'fedora_version'} = $ENV{'FEDORA_VERSION'};
+	    } 
+	    else { # finally, default to version 3 and warn the user
+		$ENV{'FEDORA_VERSION'} = "3";
+		$self->{'fedora_version'} = $ENV{'FEDORA_VERSION'};
+		#$self->generate_ok_message("FEDORA_HOME is set, but not FEDORA_VERSION, defaulted to: 3.");
+	    }
+	}
+    }
+}
+
+sub setup_gsdl {
+    my $self = shift @_;
+    my $optional = 1; # ignore absence of specified properties in gsdl(3)site.cfg if not found
+
+    my $gsdlhome = $self->get_gsdl_home();
+    my $gsdlos = $self->get_gsdl_os();
+    $ENV{'GSDLHOME'} = $gsdlhome;
+    $ENV{'GSDLOS'} = $gsdlos;
+
+
+    my $library_url = $self->get_library_url_suffix(); # best to have GSDLOS set beforehand
+    $self->{'library_url_suffix'} = $library_url;
+
+    unshift(@INC, "$ENV{'GSDLHOME'}/cgi-bin"); # This is OK on Windows
+    unshift(@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift(@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+
+    require util;
+
+    if($self->{'greenstone_version'} == 3) {
+	my $gsdl3srchome = $self->get_gsdl3_src_home();
+	$ENV{'GSDL3SRCHOME'} = $gsdl3srchome;
+
+	my $gsdl3home = $self->get_gsdl3_home($optional);
+	# if a specific location for GS3's web folder is not provided,
+	# assume the GS3 web folder is in the default location
+	if(!defined $gsdl3home) { 
+	    $gsdl3home = &util::filename_cat($ENV{'GSDL3SRCHOME'}, "web");
+	    $self->{'gsdl3home'} = $gsdl3home;
+	} 
+	$ENV{'GSDL3HOME'} = $gsdl3home;
+    } 
+   
+    
+    my $gsdl_bin_script = &util::filename_cat($gsdlhome,"bin","script");
+    &util::envvar_append("PATH",$gsdl_bin_script);
+    
+    my $gsdl_bin_os = &util::filename_cat($gsdlhome,"bin",$gsdlos);
+    &util::envvar_append("PATH",$gsdl_bin_os);
+    
+    # If the "perlpath" property is set in the gsdl(3)site.cfg config file, it is
+    # prepended to PATH only if the same perl bin dir path is not already on PATH env
+    my $perl_bin_dir = $self->get_perl_path($optional);
+    if(defined $perl_bin_dir) 
+    {
+	&util::envvar_prepend("PATH", $perl_bin_dir);	
+    }
+    elsif ($gsdlos eq "windows") 
+    {
+	# Perl comes installed with the GS Windows Release Kit. However, note that if GS 
+	# is from SVN, the user must have their own Perl and put it on the PATH or set
+	# perlpath in the gsdl site config file.
+	$perl_bin_dir = &util::filename_cat($gsdlhome, "bin", "windows", "perl", "bin");
+	if(-e $perl_bin_dir) {
+	    &util::envvar_append("PATH", $perl_bin_dir);
+	}
+    }
+    
+    # If javahome is explicitly set in the gsdl site config file then it will override
+    # any env variable JAVA_HOME. A GS2 server does not set JAVA_HOME, though java is on
+    # the path. Therefore, if Fedora is being used for FLI with GS2, then javahome must 
+    # be set in gsdlsite.cfg or the JAVA_HOME env var must be explicitly set by the user.
+    my $java_home = $self->get_java_home($optional);
+    if(defined $java_home) {
+	$ENV{'JAVA_HOME'} = $java_home;
+    }
+
+    # FEDORA_HOME and FEDORA_VERSION are needed (by scripts g2f-import and g2f-buildcol).
+    $self->setup_fedora_homes($optional);
+}
+
+sub greenstone_version {
+    my $self = shift @_;
+    return $self->{'greenstone_version'};
+}
+
+sub library_url_suffix {
+    my $self = shift @_;
+    return $self->{'library_url_suffix'};
+}
+
+# Only useful to call this after calling setup_gsdl, as it uses some environment variables
+# Returns the Greenstone collect directory, or a specific collection directory inside collect
+sub get_collection_dir {
+    my $self = shift @_;
+    my ($site, $collection) = @_; # both may be undefined
+    
+    my $collection_directory;
+    if($self->{'greenstone_version'} == 2 && defined $ENV{'GSDLHOME'}) {
+	if(defined $collection) {
+	    $collection_directory = &util::filename_cat($ENV{'GSDLHOME'}, "collect", $collection);
+	} else {
+	    $collection_directory = &util::filename_cat($ENV{'GSDLHOME'}, "collect");
+	}
+    }
+    elsif($self->{'greenstone_version'} == 3 && defined $ENV{'GSDL3SRCHOME'}) {
+	if(defined $collection) {
+	    $collection_directory = &util::filename_cat($ENV{'GSDL3SRCHOME'}, "web", "sites", $site, "collect", $collection);
+	} else {
+	    $collection_directory = &util::filename_cat($ENV{'GSDL3SRCHOME'}, "web", "sites", $site, "collect");
+	}
+    }
+}
+
+sub local_rm_r
+{
+    my $self = shift @_;
+    my ($local_dir) = @_;
+
+    my $prefix_dir = getcwd(); 
+    my $full_path = &util::filename_cat($prefix_dir,$local_dir);
+    
+    if ($prefix_dir !~ m/collect/) {
+	$self->generate_error("Trying to delete outside of Greenstone collect: $full_path");
+    }
+
+    # Delete recursively
+    if (!-e $full_path) {
+	$self->generate_error("File/Directory does not exist: $full_path");
+    }
+
+    &util::rm_r($full_path);
+}
+
+
+sub get_java_path()
+{
+    # Check the JAVA_HOME environment variable first
+    if (defined $ENV{'JAVA_HOME'}) {
+	my $java_home = $ENV{'JAVA_HOME'};
+	$java_home =~ s/\/$//;  # Remove trailing slash if present (Unix specific)
+	return &util::filename_cat($java_home, "bin", "java");
+    }
+
+    # Hope that Java is on the PATH
+    return "java";
+}
+
+
+sub check_java_home()
+{
+    # Return a warning unless the JAVA_HOME environment variable is set
+    if (!defined $ENV{'JAVA_HOME'}) {
+	return "JAVA_HOME environment variable not set. Might not be able to find Java unless in PATH (" . $ENV{'PATH'} . ")";
+    }
+
+    return "";
+}
+
+
+sub checked_chdir
+{
+    my $self = shift @_;
+    my ($dir) = @_;
+
+    if (!-e $dir) {
+	$self->generate_error("Directory '$dir' does not exist");
+    }
+
+    chdir $dir
+	|| $self->generate_error("Unable to change to directory: $dir");
+}
+
+sub rot13()
+{
+    my $self = shift @_;
+    my ($password)=@_;
+    my @password_arr=split(//,$password);
+    
+    my @encrypt_password;
+    foreach my $str (@password_arr){
+	my $char=unpack("c",$str);
+	if ($char>=97 && $char<=109){
+	    $char+=13;
+	}elsif ($char>=110 && $char<=122){
+	    $char-=13;
+	}elsif ($char>=65 && $char<=77){
+	    $char+=13;
+	}elsif ($char>=78 && $char<=90){
+	    $char-=13;
+	}
+	$char=pack("c",$char);
+	push(@encrypt_password,$char);
+    }
+    return join("",@encrypt_password);
+}
+
+sub encrypt_password
+{
+    my $self = shift @_;
+    
+    if (defined $self->param("pw")) { ##
+	if ($self->{'greenstone_version'} == 3) { # GS3 is in Java, so needs different encryption
+	    $self->param('-name' => "pw", '-value' => $self->rot13($self->clean_param("pw")));
+	}
+	else { # GS2 (and versions of GS other than 3?)
+	    #require "$self->{'gsdlhome'}/perllib/util.pm";  # This is OK on Windows
+	    require "$self->{'gsdlhome'}/perllib/cpan/Crypt/UnixCrypt.pm";  # This is OK on Windows
+	    $self->param('-name' => "pw", '-value' => &Crypt::UnixCrypt::crypt($self->clean_param("pw"), "Tp"));
+	}
+    } 
+}
+
+
+sub decode {
+    my ($self, $text) = @_;
+    $text =~ s/\+/ /g;
+    $text = &MIME::Base64::decode_base64($text);
+
+    return $text;
+}
+
+1;
+
Index: /gsdl/stable/cgi-bin/gsdlsite.cfg.in
===================================================================
--- /gsdl/stable/cgi-bin/gsdlsite.cfg.in	(revision 20131)
+++ /gsdl/stable/cgi-bin/gsdlsite.cfg.in	(revision 20131)
@@ -0,0 +1,59 @@
+# this file should be placed in the same directory as your library
+# executable file. it defines parameters that are particular to a
+# given site, and therefore should be edited to suit your site.
+
+# points to the GSDLHOME directory
+# This must be set, and must point to the top level Greenstone directory
+# (usually gsdl or Greenstone)
+gsdlhome    **GSDLHOME**
+
+# this is the http address of GSDLHOME
+# if your webserver's DocumentRoot is set to $GSDLHOME
+# then httpprefix can be commented out
+httpprefix  /greenstone
+
+# this is the http address of the Greenstone web directory (which contains
+# images, style etc)
+# if your web directory is a top level folder inside $GSDLHOME, then this
+# can remain commented out, and will default to httpprefix/web
+#httpweb     /greenstone/web
+
+# this should contain the http address of the library.cgi script. This 
+# is not needed if the http server sets the environment variable 
+# SCRIPT_NAME
+# Generally this is not needed with Apache
+#gwcgi       /greenstone/cgi-bin/library.cgi
+
+# maxrequests is the most requests a fastcgi process
+# will serve before it exits. This can be set to a
+# low figure (like 1) while debugging and then set
+# to a high figure (like 10000) when everything is
+# working well.
+# Only applies if you are using fastcgi
+maxrequests 10000
+
+# Remote Greenstone Options (for server side)
+
+# If Perl is not already on your PATH, set the following to the 
+# full path of the perl bin directory (Perl's parent folder) 
+# and it will be prepended to the PATH.
+#perlpath /usr/bin
+
+# Options for FLI
+
+# If using Greenstone's GLIServer to run the Fedora Librarian
+# Interface (FLI), then you need to set fedora version and fedora home
+# variables, either below, or as environment variables. 
+# FEDORA_VERSION is the major version number of Fedora and  
+# FEDORA_HOME is the full path to your Fedora installation.
+# Setting fedorahome and fedoraversion here will over-ride the
+# FEDORA_HOME and FEDORA_VERSION environment variables.
+#fedorahome /full/path/to/fedora
+#fedoraversion 3
+
+# If using Greenstone's GLIServer to run the Fedora Librarian
+# Interface (FLI), then you need to set the full path to Java either as below 
+# or as the JAVA_HOME environment variable.
+# Setting javahome here will over-ride the JAVA_HOME environment variable.
+#javahome /full/path/to/j2sdk1.4-or-higher
+
Index: /gsdl/stable/cgi-bin/image-server.pl
===================================================================
--- /gsdl/stable/cgi-bin/image-server.pl	(revision 20131)
+++ /gsdl/stable/cgi-bin/image-server.pl	(revision 20131)
@@ -0,0 +1,57 @@
+#!/usr/bin/perl -w 
+# Need to specify the full path of Perl above
+
+
+use strict;
+
+
+# Set this to 1 to work around IIS 6 craziness
+my $iis6_mode = 0;
+
+
+# IIS 6: for some reason, IIS runs this script with the working directory set to the Greenstone
+#   directory rather than the cgi-bin directory, causing lots of stuff to fail
+if ($iis6_mode)
+{
+    # Change into cgi-bin directory
+    chdir("cgi-bin");
+}
+
+
+# We use require and an eval here (instead of "use") to catch any errors loading the module (for IIS)
+eval("require \"gsdlCGI.pm\"");
+if ($@)
+{
+    print STDOUT "Content-type:text/plain\n\n";
+    print STDOUT "ERROR: $@\n";
+    exit 0;
+}
+
+
+
+sub main
+{
+    my $gsdl_cgi = new gsdlCGI();
+
+    # Load the Greenstone modules that we need to use
+    $gsdl_cgi->setup_gsdl();
+
+    my $gsdlhome = $ENV{'GSDLHOME'};
+    $gsdl_cgi->checked_chdir($gsdlhome);
+
+    require cgiactions::imageaction;
+
+    $gsdl_cgi->parse_cgi_args();
+
+    # We don't want the gsdlCGI module to return errors and warnings in XML
+    $gsdl_cgi->{'xml'} = 0;
+
+    my $action = new imageaction($gsdl_cgi,$iis6_mode);
+
+    $action->do_action();
+}
+
+
+
+
+&main();
Index: /gsdl/stable/cgi-bin/metadata-server.pl
===================================================================
--- /gsdl/stable/cgi-bin/metadata-server.pl	(revision 20131)
+++ /gsdl/stable/cgi-bin/metadata-server.pl	(revision 20131)
@@ -0,0 +1,63 @@
+#!/usr/bin/perl -w 
+# Need to specify the full path of Perl above
+
+
+use strict;
+
+
+# Set this to 1 to work around IIS 6 craziness
+my $iis6_mode = 0;
+
+
+# IIS 6: for some reason, IIS runs this script with the working directory set to the Greenstone
+#   directory rather than the cgi-bin directory, causing lots of stuff to fail
+if ($iis6_mode)
+{
+    # Change into cgi-bin directory
+    chdir("cgi-bin");
+}
+
+
+# We use require and an eval here (instead of "use") to catch any errors loading the module (for IIS)
+eval("require \"gsdlCGI.pm\"");
+if ($@)
+{
+    print STDOUT "Content-type:text/plain\n\n";
+    print STDOUT "ERROR: $@\n";
+    exit 0;
+}
+
+
+sub main
+{
+    my $gsdl_cgi = new gsdlCGI();
+
+
+    # Load the Greenstone modules that we need to use
+    $gsdl_cgi->setup_gsdl();
+
+    my $gsdlhome = $ENV{'GSDLHOME'};
+    $gsdl_cgi->checked_chdir($gsdlhome);
+
+    require cgiactions::metadataaction;
+    
+
+    # Useful debug statement for seeing what packages have been included
+####    printf("%-45s%-s\n",$_,$INC{$_}) foreach (sort keys %INC);
+    
+
+    $gsdl_cgi->parse_cgi_args();
+
+    # We don't want the gsdlCGI module to return errors and warnings in XML
+    $gsdl_cgi->{'xml'} = 0;
+
+    my $action = new metadataaction($gsdl_cgi,$iis6_mode);
+
+    $action->do_action();
+
+
+}
+
+
+
+&main();
Index: /gsdl/stable/cgi-bin/readresults.cgi
===================================================================
--- /gsdl/stable/cgi-bin/readresults.cgi	(revision 20131)
+++ /gsdl/stable/cgi-bin/readresults.cgi	(revision 20131)
@@ -0,0 +1,89 @@
+#!/usr/bin/perl
+
+use usabcgi;
+
+print "Content-type:text/html\n\n";
+
+
+print "<html><head><title>Greenstone Usability - Report Details</title>\n";
+usabcgi::printscript;
+usabcgi::printstyle($ENV{HTTP_USER_AGENT});
+
+print "</head><body bgcolor=\"#ffffff\">\n";
+
+usabcgi::printbanner("Report Details");
+usabcgi::printaplinks;
+ 
+usabcgi::checkidno;
+
+%reportvals=usabcgi::getusabreportdetails;
+
+print "<p>Your automatically generated report ID number is: <b>$reportvals{\"report-id\"}</b>";
+$reportid = $reportvals{"report-id"};
+delete $reportvals{"report-id"};
+
+print "<h2>The following technical information was automatically collected about your problem:</h2>\n";
+print "<table width=\"100%\">\n";
+
+make_table_entry("The URL of the page where you were having problems","URL");
+make_table_entry("the collection you were using when you had problems","collection");
+make_table_entry("Time you opened the usability report window","opentime");
+make_table_entry("Time you sent the usability report","sendtime");
+make_table_entry("Time the report was received by the server","time");
+make_table_entry("Your browser as it identifies itself","browser");
+make_table_entry("Your browser as the server identifies it","browser-read-by-server");
+make_table_entry("Your browser's IP number","browser-ip-no");
+make_table_entry("The server's IP number","server-ip-no");
+make_table_entry("Your language as recorded by your browser","language");
+make_table_entry("The resolution of your screen","resolution");
+make_table_entry("The colour of your screen","screencolour");
+make_table_entry("The number of bits per pixel your display uses to represent colour","pixeldepth");
+print "</table>";
+
+print "<h2>You provided us with the following extra information about the problem</h2>\n";
+
+print"<table width=\"100%\">\n";
+make_table_entry("How bad the problem was","severity");
+make_table_entry("What kind of problem it was","probtype");
+make_table_entry("Other details","moredetails");
+print "</table>\n";
+
+print "<h2>The following data was automatically collected from the form on the Greenstone interface</h2>\n";
+
+print"<table width=\"100%\">\n";
+print "<tr><td class=\"sans\"><b>Type of input</b></td><td class=\"sans\"><b>Name of input</b></td><td class=\"sans\"><b>Value of input</b></td></tr>\n";
+
+foreach $key (keys(%reportvals)){
+    if($key ne "update"){
+	$key=~/-/;
+	print "<tr><td width=\"33%\">$`</td><td width=\"33%\">$'</td><td width=\"34%\">$reportvals{$key}</td></tr>\n";
+    }
+}
+print "</table>\n";
+
+print "<br><br><p class=\"sans\"><a href=\"mailto:dmn&#064;cs.waikato.ac.nz\">Contact us</a> with any queries or if you would like this report to be removed from the database.  Please include your report ID number ($reportid) if your query concerns this report specifically.";
+	
+print "</body></html>";
+
+#This function takes a key into the report values interface, and a desription 
+# of what that entry means, and makes a properly formatted html table entry
+sub make_table_entry {
+    local ($desc, $entry) = @_;
+    print "<tr><td class=\"sans\" width=\"50%\"><strong>$desc:</strong></td>";
+    print "<td width=\"50%\">$reportvals{$entry}</td></tr>\n";
+    delete $reportvals{$entry};
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/cgi-bin/savereport.cgi
===================================================================
--- /gsdl/stable/cgi-bin/savereport.cgi	(revision 20131)
+++ /gsdl/stable/cgi-bin/savereport.cgi	(revision 20131)
@@ -0,0 +1,96 @@
+#!/usr/bin/perl
+
+use usabcgi;
+
+print "Content-type:text/html\n\n";
+
+
+
+
+$idno=$ENV{REMOTE_ADDR};
+$idno =~ s/\.//g;
+$idno =~ tr/0123456789/1357902468/;
+$idno .= time;
+
+print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"; 
+print "<html>\n<head>\n<title>Greenstone Usability Thank you!</title>\n";
+print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n";
+
+usabcgi::printstyle($ENV{HTTP_USER_AGENT});
+usabcgi::printscript;
+#print "timeleft=21;\n";
+#print "function timerdisplay(){\n";
+#print "\tif(eval(document.getElementById != undefined )){\n";
+#print "\t\tif(parseInt(timeleft)>0){\n";
+#print "\t\t\ttimeleft-=1;\n";
+#print "\t\t\ttimeforscreen = timeleft+\' second\';\n";
+#print "\t\t\tif(timeleft>1)\{ timeforscreen += \'s\';\}\n";
+#print "\t\t\t\tdocument.getElementById(\'timer\').firstChild.nodeValue=timeforscreen;\n";
+#print "\t\t\t\tsetTimeout(\'timerdisplay()\',1000);\n";
+#print "\t\t}\n";
+#print "\t}\n";
+#print "}\n";
+#print "\n";
+
+print "</head><body onLoad=\"if(parseInt(navigator.appVersion)>3)\{window.resizeTo(420,300);\}\" bgcolor=\"#FFFFFF\">\n";
+
+
+usabcgi::printbanner("Thank You");
+
+($fileoutloc) = usabcgi::get_config_info("gsdlhome");
+if(!($fileoutloc =~/\/$/)) {$fileoutloc.="/";}
+$fileoutloc .= "etc/usability.txt";
+
+if(-e $fileoutloc){
+    open FILEOUT, (">>$fileoutloc");
+}
+else {
+    open FILEOUT, (">$fileoutloc");
+}
+
+usabcgi::printaplinks;
+print "<p>Your comments have been noted. <p>Thank you for helping us make Greenstone more usable.</p>\n";
+print "<table width=\"100%\"><tr>\n";
+print "<td class=\"sans\"><a href=\"readresults.cgi?$idno\" target=\"_blank\">View report details</a></td>\n";
+print "<td class=\"sans\"><a href=\"trackreport.cgi?$idno\" target=\"_blank\">Track report</a></td>";
+print "<td align=\"right\"><form action=\"\"><button type=\"button\" onClick=\"window.close();\"><strong>Close Window</strong></button></form></td>\n";
+print"</tr></table>\n";
+
+
+#print "<h2>Your report ID number is: $idno</h2>";
+#print "<p>The information has now been sent, thank-you.  The information sent is displayed below.  This window will close automatically after <span id=\"timer\">20 seconds</span>.";
+read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
+@pairs=split(/&/,$buffer);
+
+foreach $pair (@pairs) {
+    ($name, $value) = split(/=/,$pair);
+    $value=~ tr/+/ /;
+    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
+    $FORM{$name} = $value;
+}
+
+
+
+if (-e $fileoutloc){ 
+    open FILEOUT, (">>$fileoutloc");
+}
+else { open FILEOUT, (">$fileoutloc") or print "cannot open file $fileoutloc\n"; }
+#print FILEOUT "-------------------------------------\n";
+print FILEOUT "report-id := $idno\&usabend;\n";
+foreach $key (keys(%FORM)) {
+    if($key eq "URL") {
+	$url = $FORM{$key};
+	$url =~s/\&/\&amp\;/g;
+    }
+    print FILEOUT "$key := $FORM{$key}\&usabend;\n"; 
+}
+print FILEOUT "browser-read-by-server :=  $ENV{HTTP_USER_AGENT}\&usabend;\n";
+print FILEOUT "browser-ip-no :=  $ENV{REMOTE_ADDR}\&usabend;\n";
+print FILEOUT "server-ip-no :=  $ENV{SERVER_ADDR}\&usabend;\n";
+print FILEOUT "time := ".scalar(localtime(time))."\&usabend;\n";
+print FILEOUT "----------------------------------------------\n";
+close (FILEOUT);
+
+
+print"</body></html>\n"; 
+
Index: /gsdl/stable/cgi-bin/trackreport.cgi
===================================================================
--- /gsdl/stable/cgi-bin/trackreport.cgi	(revision 20131)
+++ /gsdl/stable/cgi-bin/trackreport.cgi	(revision 20131)
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+
+use usabcgi;
+
+print "Content-type:text/html\n\n";
+
+
+print "<html><head><title>Greenstone Usability - Track Report</title>\n";
+usabcgi::printscript;
+usabcgi::printstyle($ENV{HTTP_USER_AGENT});
+
+print "</head><body bgcolor=\"#ffffff\">\n";
+
+usabcgi::printbanner("Track Report");
+usabcgi::printaplinks;
+
+usabcgi::checkidno;
+
+%reportvals=usabcgi::getusabreportdetails;
+
+print "<h2>Your automatically generated report ID number is: $reportvals{\"report-id\"}</h2>\n";
+
+print "<p>Thank you very much for helping us improve the usability of the Greenstone software\n<p>We received your report at $reportvals{\"time\"}, any updates are shown below.\n<p>To track this report continue to use the URL <a href=\"http://$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}?$ENV{QUERY_STRING}\">http://$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}?$ENV{QUERY_STRING}</a>.\n";
+
+print "<h2>Updates on this report</h2>\n";
+if(!(defined($reportvals{"update"}))){ print "<p>None at this time.</p>\n"; }
+else { print $reportvals{"update"}; }
+
+print "<br><br><p class=\"sans\"><a href=\"mailto:greenstone&#064;cs.waikato.ac.nz\">Contact us</a> with any queries or if you would like this report to be removed from the database.  Please include your report ID number ($ENV{QUERY_STRING}) if your query concerns this report specifically.\n";
+
+
+	
+print "</body></html>";
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/cgi-bin/usabcgi.pm
===================================================================
--- /gsdl/stable/cgi-bin/usabcgi.pm	(revision 20131)
+++ /gsdl/stable/cgi-bin/usabcgi.pm	(revision 20131)
@@ -0,0 +1,158 @@
+package usabcgi;
+
+
+sub get_config_info {
+    open FILEIN, ("gsdlsite.cfg") 	|| die "ERROR: Could not open site configuration file\n";
+
+    my $configfile;
+    while(<FILEIN>) {
+	$configfile .= $_;
+    }
+    close(FILEIN);
+
+    
+    ($infotype) = @_;
+    
+    $configfile =~ /^$infotype\s+(\S+)\s*\n/m;
+    $loc=$1;
+    $loc =~ s/\"//g;
+
+    return ($loc);
+}
+
+sub get_httpimg {
+    my ($imageloc) = usabcgi::get_config_info("httpimg");
+    if(!($imageloc =~ "http")) {$imageloc="http://".$ENV{HTTP_HOST}.$imageloc;}
+    return $imageloc;
+}
+
+sub get_httpusab {
+    my ($htmlloc) = usabcgi::get_config_info("httpimg");
+    if(!($htmlloc =~ "http")) {$htmlloc="http://".$ENV{HTTP_HOST}.$htmlloc;}
+    $htmlloc =~ s/images/usability/;
+    return  $htmlloc;
+
+}
+
+sub printscript {
+    
+    print "<script type=\"text/javascript\">\n";
+    print "\tfunction showaboutprivacy(url){\n";
+    print "\t\tinfowin=window.open(url,'infowin','toolbars=0, height=600, width=600')\n";
+    print "\t}\n";
+    print "</script>\n";
+}
+
+sub printbanner {
+    ($title)=@_;
+    ($imageloc) = usabcgi::get_httpimg();
+    print "<table width=\"100%\"><tr>\n<td><h1>Greenstone Usability - $title</h1></td>\n";
+    print "<td align=\"right\">";
+    if ($imageloc) { print "<img src=\"$imageloc\/usabbnr.gif\" alt=\"Greenstone koru design\" title=\"Greenstone koru design\">"; }
+    print "</td>\n</tr></table>";
+}
+
+sub printaplinks {
+    # this is a hack
+    ($htmlloc) = usabcgi::get_httpusab();
+    print "<p class=\"sans\">\n";
+    print "<a href=\"javascript:showaboutprivacy('$htmlloc/about.html')\">About</a>\n &#8226; <a href=\"javascript:showaboutprivacy('$htmlloc/privacy.html')\">Privacy</a>\n";
+
+}
+
+sub printstyle {
+    ($browser) = @_;
+    $browser=~/([^\/]*)\/([0-9]+\.[0-9]+)/;
+    if(($1 ne "Netscape")||($2 > 4.77)){
+	print "<style type=\"text/css\">\n";
+	print "\th1 {font-family: sans-serif; font-size: 20px}\n";
+	print "\th2 {font-family: sans-serif; font-size: 14px; font-weight: bold; color: #009966}\n";
+	print "\tp.sans {font-family: sans-serif}\n";
+	print "\ttd {vertical-align: top}\n";
+	print "\ttd.sans {font-family: sans-serif; width: 50%}\n";
+	print "</style>\n";
+    }
+
+}
+
+sub checkidno {
+    if((!($ENV{QUERY_STRING}=~/\d/)) || ($ENV{QUERY_STRING}=~/\D/) ) {
+	print "<h2>Each report sent has an ID number.  This page needs one of those numbers to work.</h2>\n";
+	print "<br><br><p class=\"sans\"><a href=\"mailto:greenstone&#064;cs.waikato.ac.nz\">Contact us</a> with any queries about this.\n";
+	print "</body></html>\n";
+	die;
+    }
+}
+
+sub getusabreportdetails {
+    ($etcfileloc) = usabcgi::get_config_info("gsdlhome");
+    if(!($etcfileloc =~/\/$/)) {$etcfileloc.="/";}
+    $etcfileloc .= "etc/usability.txt";
+    open (FILEIN, $etcfileloc) or die "could not open usability.txt\n";
+    while(<FILEIN>){
+	$etcfile.=$_;
+    }   
+    close(FILEIN);
+
+    if(!($etcfile=~ / $ENV{QUERY_STRING}\&usabend;/)) {
+	print "<h2>Each report has an ID number.  This program needs one of those ID numbers to work, and the ID number provided wasn't found.</h2>\n";
+	print "<br><br><p class=\"sans\"><a href=\"mailto:greenstone&#064;cs.waikato.ac.nz\">Contact us</a> with any queries about this.\n";
+	print "</body></html>";  
+        die;
+    }
+
+#get the report for whjich details are to be viewed.
+    $etcfile=~/report-id := $ENV{QUERY_STRING}\&usabend\;\n/;
+    $report = $&;
+    $tmp=$';
+    $tmp=~/----------------------?/;
+    $report.=$`;
+    @pairs=split(/\&usabend\;\n/,$report);
+    foreach $pair (@pairs) {
+	($name, $value)= split(/ := /,$pair);
+	
+	#this splits long values up for display purposes
+	@tmplist = split(/ /,$value);
+	foreach $item (@tmplist){
+	    if(length $item > 60){
+		$tmp="";
+		while(length $item > 60){
+		    $tmp.= substr $item, 0, 60;
+		    $tmp.=" ";
+		    $item = substr $item, 60;
+		}
+		$tmp.=$item;
+		$item=$tmp;
+	    }
+	}
+	$value = join(' ',@tmplist);
+	
+	#this adds html tags for breaks
+	$value =~ s/\n/\<br\>\n/g;
+	$reportvals{$name}=$value;
+    }
+    return %reportvals;
+
+}    
+
+1;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/collect/demo/demo.col
===================================================================
--- /gsdl/stable/collect/demo/demo.col	(revision 20131)
+++ /gsdl/stable/collect/demo/demo.col	(revision 20131)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE GathererCollection [
+  <!ELEMENT GathererCollection (Argument*, GathererConfig, BuildConfig)>
+  <!ELEMENT GathererConfig    (Arguments*)>
+  <!ELEMENT BuildConfig       (Build, Import)>
+  <!ELEMENT Build             (Arguments*)>
+  <!ELEMENT Import            (Arguments*)>
+  <!ELEMENT Schedule          (Arguments*)>
+  <!ELEMENT Argument          (#PCDATA)>
+  <!ATTLIST Argument
+            name              CDATA #REQUIRED
+				enabled           CDATA "true">
+]>
+<GathererCollection>
+    <Argument name="built">false</Argument>
+    <Argument name="imported">false</Argument>
+    <GathererConfig/>
+    <BuildConfig>
+        <Build/>
+        <Import/>
+        <Schedule/>
+    </BuildConfig>
+</GathererCollection>
Index: /gsdl/stable/collect/demo/etc/collect.cfg
===================================================================
--- /gsdl/stable/collect/demo/etc/collect.cfg	(revision 20131)
+++ /gsdl/stable/collect/demo/etc/collect.cfg	(revision 20131)
@@ -0,0 +1,111 @@
+creator		greenstone@cs.waikato.ac.nz
+maintainer	greenstone@cs.waikato.ac.nz
+public		true
+
+buildtype	mgpp
+
+indexes		text dls.Title,Title dls.Subject dls.Organization dls.Keyword
+
+levels	section document
+
+plugin	GreenstoneXMLPlugin
+plugin	HTMLPlugin -description_tags
+plugin	MetadataXMLPlugin
+plugin	ArchivesInfPlugin
+plugin	DirectoryPlugin
+
+classify	List -metadata dls.Title
+
+classify	Hierarchy -metadata "dls.Subject" -sort dls.Title
+
+classify	List -metadata dls.Organization -sort_leaf_nodes_using dls.Title -bookshelf_type always
+
+classify	List -metadata dls.Keyword -buttonname Howto
+
+format CL4VList "<td>[link][icon][/link]</td><td>[link][dls.Keyword][/link]"
+
+format SearchVList "<td valign=top>[link][icon][/link]</td><td>{If}{[parent(All\': \'):Title],[parent(All\': \'):Title]:}[link][Title][/link]</td>"
+
+format VList "<td valign=top>[link][icon][/link]</td><td valign=top>[highlight]{Or}{[Title],Untitled}[/highlight]{If}{[Date],<br><small><i>_textdate_[Date]</i></small>}{If}{[NumPages],<br><small><i>_textnumpages_[NumPages]</i></small>}{If}{[Source],<br><small><i>_textsource_[Source]</i></small>}</td>"
+
+format DocumentText "<h3>[Title]</h3>\\n\\n<p>[Text]"
+format DocumentImages true
+format DocumentButtons "Expand Text|Expand Contents|Highlight|Detach|Print"
+format DocumentSearchResultLinks true
+
+format HList "[link][highlight][Title][/highlight][/link]"
+
+format DocumentHeading "{Or}{[parent(Top):Title],[Title],untitled}<br>"
+
+format SearchTypes "plain,form"
+
+# strings that use macros
+# these don't need translating unless you want something different from the
+# default
+collectionmeta	.text [l=en] "_labeltext_"
+collectionmeta	.dls.Title,Title [l=en] "_labelTitle_"
+collectionmeta	.dls.Subject [l=en] "_labelSubject_"
+collectionmeta	.dls.Organization [l=en] "_labelOrganization_"
+collectionmeta	.dls.Keyword [l=en] "_labelHowto_"
+
+collectionmeta	.document [l=en] "_textbook_"
+collectionmeta	.section [l=en] "_textchapter_"
+
+# -- English strings ----------------
+collectionmeta	collectionname [l=en] "Greenstone demo"
+collectionmeta	collectionextra [l=en] "This is a demonstration collection for the Greenstone digital library software.\nIt contains a small subset (11 documents) of the Humanity Development Library."
+
+collectionmeta	depositormetadata [l=en] "{\"name\":\"dls.Title\",\"label\":\"Title\",\"tooltip\":\"dls.Title: The title of this resource.\",\"type\":\"text\"}, {\"name\":\"dls.Organization\",\"label\":\"Organization\",\"tooltip\":\"dls.Organization: The organization responsible for producing this resource.\",\"type\":\"text\"}, {\"name\":\"dls.Subject\",\"label\":\"Subject\",\"tooltip\":\"dls.Subject: The subject of this resource.\",\"type\":\"text\"}, {\"name\":\"dls.Keyword\",\"label\":\"Keyword\",\"tooltip\":\"dls.Keyword: A more specific indication of what the resource can be used for.\",\"type\":\"text\"}, {\"name\":\"dls.Language\",\"label\":\"Language\",\"tooltip\":\"dls.Language: The language of this resource.\",\"type\":\"text\"}"
+
+# -- French strings ----------------
+collectionmeta	collectionname [l=fr] "DÃ©mo Greenstone"
+collectionmeta	collectionextra [l=fr] "Il s\'agit d\'une collection de dÃ©monstration pour le logiciel de bibliothÃšque numÃ©rique Greenstone.\nElle contient un petit Ã©chantillon (11 documents) de la BibliothÃšque de DÃ©veloppement de l\'HumanitÃ©."
+
+# -- Spanish strings ----------------
+collectionmeta	collectionname [l=es] "ColecciÃ³n de muestra Greenstone"
+collectionmeta	collectionextra [l=es] "Esta es una colecciÃ³n de demostraciÃ³n del programa Greenstone.\nContiene un pequeÃ±o subconjunto (11 documentos) de la Biblioteca para el Desarrollo Humano."
+
+# -- Russian strings ----------------
+collectionmeta	collectionname [l=ru] "ÐŽÐµÐŒÐŸÐœÑÑÑÐ°ÑÐžÐŸÐœÐœÑÐ¹ Ð¿ÑÐžÐŒÐµÑ ÐÑÐžÐœÑÑÐŸÑÐœ"
+collectionmeta	collectionextra [l=ru] "Ð­ÑÐŸ - ÐŽÐµÐŒÐŸÐœÑÑÑÐ°ÑÐžÐŸÐœÐœÐ°Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐ³ÐŸ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÑ ÑÐžÑÑÐŸÐ²ÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž ÐÑÐžÐœÑÑÐŸÑÐœ. ÐÐœÐ° ÑÐŸÐŽÐµÑÐ¶ÐžÑ ÐœÐµÐ±ÐŸÐ»ÑÑÐŸÐ¹ Ð¿ÐŸÐŽÐœÐ°Ð±ÐŸÑ (11 ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ²) ÐÑÐŒÐ°ÐœÐžÑÐ°ÑÐœÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž ÑÐ°Ð·Ð²ÐžÑÐžÑ."
+
+# -- Arabic strings ----------------
+collectionmeta	collectionname [l=ar] "Ù
+Ø¬Ù
+ÙØ¹Ø© Ø¬Ø±ÙÙØ³ØªÙÙ Ø§ÙØªÙØ¶ÙØ­ÙØ©"
+collectionmeta	collectionextra [l=ar] "ÙØ°Ù Ù
+Ø¬Ù
+ÙØ¹Ø© ØªÙØ¶ÙØ­ÙØ© ÙØšØ±Ù
+Ø¬ÙØ§Øª Ø¬Ø±ÙÙØ³ØªÙÙ ÙÙÙ
+ÙØªØšØ© Ø§ÙØ±ÙÙ
+ÙØ©.\nØªØªØ¶Ù
+Ù Ù
+Ø¬Ù
+ÙØ¹Ø© ÙØ±Ø¹ÙØ© ØµØºÙØ±Ø© (11 ÙØ«ÙÙØ©) Ù
+Ù Ù
+ÙØªØšØ© Ø§ÙØªÙÙ
+ÙØ© Ø§ÙØšØŽØ±ÙØ©."
+
+# -- Armenian strings ----------------
+collectionmeta	collectionextra [l=hy] "ÕÕ¡ Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« ÖÕžÖÖÕ¡Õ€ÖÕ¡Õ¯Õ¡Õ¶ Õ¶ÕŽÕžÖÕ· Õ§Ö Ô±ÕµÕ¶ ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ§ Õ°Õ¡ÕœÕ¡ÖÕ¡Õ¯Õ¡Õ£Õ«Õ¿Õ¡Õ¯Õ¡Õ¶ Ö ÕŠÕ¡ÖÕ£Õ¡ÖÕŽÕ¡Õ¶ Õ¢Õ¶Õ¡Õ£Õ¡ÕŸÕ¡ÕŒÕ¶Õ¥ÖÕ« 11 ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕ« Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖ"
+
+# -- Finnish strings ----------------
+collectionmeta	collectionextra [l=fi] "TÃ€mÃ€ on esimerkkikokoelma, joka on tehty Greenstone digitaalisen kirjaston ohjelmistoa varten. Se sisÃ€ltÃ€Ã€ osan (11 dokumenttia) HumanitÃ€Ã€risestÃ€ kirjastosta ja KehitystyÃ¶kirjastosta."
+
+# -- Slovak strings ----------------
+collectionmeta	collectionname [l=sk] "Demo"
+collectionmeta	collectionextra [l=sk] "Toto je predvÃ¡dzacia zbierka softvÃ©ru digitÃ¡lnej kniÅŸnice Greenstone, ktorÃ¡ obsahuje 11 dokumentov."
+
+# -- Brazilian Portuguese strings ----------------
+collectionmeta	collectionname [l=pt-br] "Demo do Greenstone"
+collectionmeta	collectionextra [l=pt-br] "Esta Ã© uma coleÃ§Ã£o de demonstraÃ§Ã£o para o software de biblioteca digital Greenstone. \nEle contÃ©m um pequeno subconjunto (11 documentos) da Biblioteca de Desenvolvimento Humano."
+
+# -- Thai strings ----------------
+collectionmeta	collectionname [l=th] "àžàž²àž£àžªàž²àžàžŽàžàžàž²àž£à¹àžà¹àžàž²àžà¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàž"
+collectionmeta	collectionextra [l=th] "àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹à¹àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžªàž²àžàžŽàžàžàž­àžàžàž­àžàžà¹à¹àž§àž£à¹àž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥àžàž£àžµàžà¹àžàž\nIt àžàž¶à¹àžàžàž£àž°àžàž­àžàžà¹àž§àž¢àžàžžàžàžà¹àž­àž¡àž¹àž¥àž¢à¹àž­àž¢àžàžàž²àžà¹àž¥à¹àžàžàž³àžàž§àžàž«àžàž¶à¹àžàžàžžàž (à¹àž­àžàžªàž²àž£àžàž³àžàž§àž 11 àžàžàž±àž) àžàž­àžàž«à¹àž­àžàžªàž¡àžžàžà¹àžàž·à¹àž­àžàž²àž£àžàž±àžàžàž²àž¡àžàžžàž©àž¢àžàž²àžàžŽ (Humanity Development Library)"
+
+# -- Simplified Chinese strings ----------------
+collectionmeta	collectionname [l=zh] "ç»¿å®ç³ç³»ç»æŒç€ºæ¶è"
+collectionmeta	collectionextra [l=zh] "è¿æ¯äžäžªç»¿å®ç³æ°å­åŸä¹ŠéŠç³»ç»çæŒç€ºæ¶èã\nå®å
+å«äºäººç±»åå±åŸä¹ŠéŠïŒHumanity Development LibraryïŒçäžäžªå°å­éïŒ11äžªææ¡£ïŒã"
+
Index: /gsdl/stable/collect/demo/import/b17mie/b17mie.htm
===================================================================
--- /gsdl/stable/collect/demo/import/b17mie/b17mie.htm	(revision 20131)
+++ /gsdl/stable/collect/demo/import/b17mie/b17mie.htm	(revision 20131)
@@ -0,0 +1,7650 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META NAME="Generator" CONTENT="Microsoft Word 97">
+<TITLE>&lt;&lt;TOC1&gt;&gt; Microlivestock -  Little-Known Small Animals with a Promising Economic Future</TITLE>
+</HEAD>
+<BODY>
+
+<B><FONT FACE="Arial" SIZE=2><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Microlivestock -  Little-Known Small Animals with a Promising Economic Future</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Acknowledgments</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Board on Science and Tecnology for International Development </P>
+<P ALIGN="JUSTIFY">National Research Council</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NOTICE: The project that is the subject of this report was approved by the Governing Board of the National Research Council, whose members are drawn from the councils of the National Academy of Sciences, the National Academy of Engineering, and the Institute of Medicine. The members of the committee responsible for the report were chosen for their special competence and with regard for appropriate balance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report has been reviewed by a group other than the authors according to procedures approved by a Report Review Committee consisting of members of the National Academy of Sciences, the National Academy of Engineering, and the Institute of Medicine.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The National Academy of Sciences is a private, nonprofit, self-perpetuating society of distinguished scholars engaged in scientific and engineering research, dedicated to the furtherance of science and technology and to their use for the general welfare. Upon the authority of the charter granted to it by the Congress in 1863, the Academy has a mandate that requires it to advise the federal government on scientific and technical matters. Dr. Frank Press is president of the National Academy of Sciences.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The National Academy of Engineering was established in 1964, under the charter of the National Academy of Sciences, as a parallel organization of outstanding engineers. It is autonomous in its administration and in the selection of its members, sharing with the National Academy of Sciences the responsibility for advising the federal government. The National Academy of Engineering also sponsors engineering programs aimed at meeting national needs, encourages education and research, and recognizes the superior achievements of engineers. Dr. Robert M. White is president of the National Academy of Engineering.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Institute of Medicine was established in 1970 by the National Academy of Sciences to secure the services of eminent members of appropriate professions in the examination of policy matters pertaining to the health of the public. The Institute acts under the responsibility given to the National Academy of Sciences by its congressional charter to be an adviser to the federal government and, upon its own initiative, to identify issues of medical care, research, and education. Dr. Samuel O. Their is president of the Institute of Medicine.</P>
+<P ALIGN="JUSTIFY">The National Research Council was organized by the National Academy of Sciences in 1916 to associate the broad community of science and technology with the Academy's purposes of furthering knowledge and advising the federal government. Functioning in accordance with general policies determined by the Academy, the Council has become the principal operating agency of both the National Academy of Sciences and the National Academy of Engineering in providing services to the government, the public, and the scientific and engineering communities. The Council is administered jointly by both Academies and the Institute of Medicine. Dr. Frank Press and Dr. Robert M. White are chairman and vice chairman, respectively, of the National Research Council.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Board on Science and Technology for International Development (BOSTID) of the Office of International Affairs addresses a range of issues arising from the ways in which science and technology in developing countries can stimulate and complement the complex processes of social and economic development. It oversees a broad program of bilateral workshops with scientific organizations in developing countries and conducts special studies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report was prepared by an ad hoc advisory panel of the Advisory Committee on Technology Innovation, Board on Science and Technology for International Development, Office of International Affairs, National Research Council. Staff support was funded by the Office of the Science Advisor, Agency for International Development, under Grant No. DAN-5538-G-SS-1023-00. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PANEL ON MICROLIVESTOCK</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RALPH W. PHILLIPS, Deputy Director General (Retired), Food and Agriculture Organization of the United Nations, Chairman </P>
+<P ALIGN="JUSTIFY">EDWARD S. AYENSU, Senior Advisor to the President, African Development Bank, Abidjan, Ivory Coast.</P>
+<P ALIGN="JUSTIFY">BONNIE V. BEAVER, Professor of Veterinary Medicine, Department of Small Animal Medicine and Surgery, Texas A&amp;M University, College Station, Texas, USA</P>
+<P ALIGN="JUSTIFY">KURT BENIRSCHKE, Professor of Pathology and Reproductive Medicine, University of California-San Diego, San Diego, California, USA</P>
+<P ALIGN="JUSTIFY">ROY D. CRAWFORD, Professor of Animal and Poultry Genetics, Department of Animal and Poultry Science, University of Saskatchewan, Saskatoon, Saskatchewan, Canada</P>
+<P ALIGN="JUSTIFY">TONY J. CUNHA, Distinguished Service Professor Emeritus, University of Florida, Gainesville, and Dean Emeritus, School of Agriculture, California Polytechnic University, Pomona, California, USA</P>
+<P ALIGN="JUSTIFY">DAVID E. DEPPNER, Director, New Forest Project, International Center, Washington, D.C., USA</P>
+<P ALIGN="JUSTIFY">ELIZABETH L. HENSON, Executive Director, American Minor Breeds Conservancy, Pittsboro, North Carolina, USA</P>
+<P ALIGN="JUSTIFY">DONALD L. HUSS, Menard, Texas, USA (Formerly Regional Animal Production Officer, FAO, Santiago, Chile)</P>
+<P ALIGN="JUSTIFY">DAVID R. LINCICOME, Guest Scientist, U.S. Department of Agriculture, Beltsville, Maryland, USA</P>
+<P ALIGN="JUSTIFY">THOMAS E. LOVEJOY, Assistant Secretary for External Affairs, Smithsonian Institution, Washington, D.C., USA</P>
+<P ALIGN="JUSTIFY">ARNE W. NORDSKOG, Professor Emeritus, Department of Animal Science, Iowa State University, Ames, Iowa, USA</P>
+<P ALIGN="JUSTIFY">LINDA M. PANEPINTO, Director, Miniature Swine Laboratory, Colorado State University, Fort Collins, Colorado, USA</P>
+<P ALIGN="JUSTIFY">KURT J. PETERS, Professor of Animal Breeding and Husbandry in the Tropics and Subtropics, University of Gottingen, Gottingen, West Germany, and Director of Research, International Livestock Centre for Africa, Addis Ababa, Ethiopia</P>
+<P ALIGN="JUSTIFY">JOHN A. PINO, Senior Fellow, National Research Council, Washington, D.C., USA</P>
+<P ALIGN="JUSTIFY">HUGH POPENOE, Director, International Program in Agriculture, University of Florida, Gainesville, Florida, USA</P>
+<P ALIGN="JUSTIFY">MICHAEL H. ROBINSON, Director, National Zoological Park, Washington, D.C., USA</P>
+<P ALIGN="JUSTIFY">KNUT SCHMIDT-NIELSON, James B. Duke Professor of Physiology, Department of Zoology, Duke University, Durham, North Carolina, USA </P>
+<P ALIGN="JUSTIFY">ALBERT E. SOLLOD, Associate Professor and Head, Section of International Veterinary Medicine, Tufts University, North Grafton, Massachusetts, USA </P>
+<P ALIGN="JUSTIFY">LEE M. TALBOT, Visiting Fellow, World Resources Institute, Washington, D.C., USA </P>
+<P ALIGN="JUSTIFY">CLAIR E. TERRILL, Sheep and Goat Scientist, U.S. Department of Agriculture, Beltsville, Maryland, USA </P>
+<P ALIGN="JUSTIFY">CHRISTEN M. WEMMER, Assistant Director for Conservation, National Zoological Park, Front Royal, Virginia, USA </P>
+<P ALIGN="JUSTIFY">DANNY C. WHARTON, Associate Curator Animal Departments, New York Zoological Park, Bronx Zoo, The Bronx, New York, USA </P>
+<P ALIGN="JUSTIFY">CHARLES A. WOODS, Professor and Curator, Florida State Museum, University of Florida, Gainesville, Florida, USA </P>
+<P ALIGN="JUSTIFY">THOMAS M. YUILL, Associate Dean for Research and Graduate Training, School of Veterinary Medicine, University of Wisconsin-Madison, Madison, Wisconsin, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">* * *</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NOEL D. VIETMEYER, Board on Science and Technology for International Development (BOSTID), National Research Council, Washington, D.C., Microlivestock Study Director and Scientific Editor </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NATIONAL RESEARCH COUNCIL STAFF</P>
+<P ALIGN="JUSTIFY">F.R. RUSKIN, BOSTID Editor</P>
+<P ALIGN="JUSTIFY">MARK DAFFORN, Technical Writer</P>
+<P ALIGN="JUSTIFY">MARY JANE ENGQUIST, Staff Associate</P>
+<P ALIGN="JUSTIFY">ELIZABETH MOUZON, Senior Secretary</P>
+<P ALIGN="JUSTIFY">JOHN VREYENS, MUCIA Intern</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CONTRIBUTORS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The following individuals have made general contributions to the development of this book. All of the persons listed as research contacts in Appendix B also contributed - usually on one or two species that are their scientific specialty.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ASHIQ AHMAD, Wildlife Management Specialist, Pakistan Forest Institute, Peshawar, Pakistan</P>
+<P ALIGN="JUSTIFY">ANGEL C. ALCALA, Division Research, Extension and Development, Silliman University, Dumaguete City, Philippines</P>
+<P ALIGN="JUSTIFY">HARTI AMMANN, Basel, Switzerland</P>
+<P ALIGN="JUSTIFY">PATRICK ANDAU, Forest Department, Sandakan, Sabah, Malaysia</P>
+<P ALIGN="JUSTIFY">S.P. ARORA, National Dairy Research Institute, Karnal, India</P>
+<P ALIGN="JUSTIFY">S. AYYAPPAN, CIFRI, Kausabyaganga, Bhubaneswar Orissa, India</P>
+<P ALIGN="JUSTIFY">WALTER BAKHUIS, Caribbean Marine Biological Institute, Willemstad, Curacao, Netherlands Antilles</P>
+<P ALIGN="JUSTIFY">JAMES R. BARBORAK, CATIE, Turrialba, Costa Rica</P>
+<P ALIGN="JUSTIFY">PUSHKAR NATH BHAT, Indian Veterinary Research Institute, Izatnagar, Uttar Pradesh, India</P>
+<P ALIGN="JUSTIFY">STEVE BENNETT, Curepe, Trinidad, West Indies</P>
+<P ALIGN="JUSTIFY">K.P. BLAND, Department of Physiology, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Edinburgh, Scotland</P>
+<P ALIGN="JUSTIFY">MELVIN BOLTON, Yeppoon, Queensland, Australia</P>
+<P ALIGN="JUSTIFY">JOSEPH BONNEMAIRE, Ecole Nationale Superieure des Sciences Agronomiques Appliquees, Dijon, France</P>
+<P ALIGN="JUSTIFY">R.D.S. BRANCKRAERT, Faculte des Sciences Agronomiques, Universite du Burundi, Bujumbura, Burundi</P>
+<P ALIGN="JUSTIFY">PETER BRAZAITIS, Herpetology, New York Zoological Society, The Bronx, New York, USA</P>
+<P ALIGN="JUSTIFY">L. DE LA BRETONNE, JR., Louisiana Cooperative Extension Service, Louisiana State University, Baton Rouge, Louisiana, USA</P>
+<P ALIGN="JUSTIFY">P. BRINCK, Department of Animal Ecology, University of Lund, Lund, Sweden</P>
+<P ALIGN="JUSTIFY">LESLIE BROWNRIGG, CIAT, Cali, Colombia</P>
+<P ALIGN="JUSTIFY">D. HOMER BUCK, Illinois Natural History Survey, Kinmundy, Illinois, USA</P>
+<P ALIGN="JUSTIFY">GERARDO BUDOWSKI, Natural Renewable Resources Programme, CATIE, Turrialba, Costa Rica</P>
+<P ALIGN="JUSTIFY">DAVID BUTCHER, Taronga Zoo, Mosman, New South Wales, Australia</P>
+<P ALIGN="JUSTIFY">JULIAN O. CALDECOTT, World Wildlife Fund Malaysia, Kuching, Sarawak, Malaysia</P>
+<P ALIGN="JUSTIFY">GARY CALLIS, Texline, Texas, USA</P>
+<P ALIGN="JUSTIFY">J.K. CAMOENS, Asian Development Bank, Manila, Philippines</P>
+<P ALIGN="JUSTIFY">A. CHRISTOPHER CARMICHAEL, The Museum, Michigan State University, East Lansing, Michigan, USA</P>
+<P ALIGN="JUSTIFY">ROBERT H. CHABRECK, School of Forestry and Wildlife Management, Louisiana State University, Baton Rouge, Louisiana, USA</P>
+<P ALIGN="JUSTIFY">A.M. CHAGULA, Research, Ministry of Agriculture, Dar-es-Salaam, Tanzania</P>
+<P ALIGN="JUSTIFY">CHARAN CHANTALAKHANA, Department of Animal Science, Kasetsart  University, Bangkok, Thailand</P>
+<P ALIGN="JUSTIFY">PETER R. CHEEKE, Rabbit Research Center, Oregon State University, Corvallis,  Oregon, USA</P>
+<P ALIGN="JUSTIFY">G.S. CHILD, Forest Resources Division, FAO, Rome, Italy</P>
+<P ALIGN="JUSTIFY">A.S. CHOPRA, Ministry of Agriculture, Department of Agriculture and Cooperation,  New Delhi, India</P>
+<P ALIGN="JUSTIFY">W. Ross COCKRILL 29 Downs Park West, Bristol, England, BS6 7QH</P>
+<P ALIGN="JUSTIFY">CRISOSTOMO CORTES, Dairy Promotion and Extension Section, Dairy Development  Division, Manila, Philippines</P>
+<P ALIGN="JUSTIFY">WYLAND CRIPE, College of Veterinary Medicine, University of Florida, Gainesville,  Florida, USA</P>
+<P ALIGN="JUSTIFY">A. BEN DAVID, Holon, Israel</P>
+<P ALIGN="JUSTIFY">C. DEVENDRA, International Development Research Centre, Singapore</P>
+<P ALIGN="JUSTIFY">RODNEY DILLINGER, International Agency for Apiculture Development, Rockford,  Illinois, USA</P>
+<P ALIGN="JUSTIFY">DIRECTOR, Natal Parks Board, Pietermaritzburg, South Africa</P>
+<P ALIGN="JUSTIFY">ROLLANDE DUMONT, Ecole Nationale Superieure des Sciences Agronomiques  Appliquees, Dijon, France</P>
+<P ALIGN="JUSTIFY">N.G. EHIOBU, Department of Agricultural Sciences, College of Education, Agbor,  Nigeria</P>
+<P ALIGN="JUSTIFY">DONALD FARNER, Department of Zoology, University of Washington, Seattle,  Washington, USA</P>
+<P ALIGN="JUSTIFY">JOHN A. FERGUSON, Overseas Development Administration, Eland House, London,  England</P>
+<P ALIGN="JUSTIFY">ABELARDO FERRER D., Quinta Nueva Exparta, San Bernardino, Caracas,  Venezuela</P>
+<P ALIGN="JUSTIFY">LYNWOOD A. FIEDLER, Section of International Programs, U.S. Fish and Wildlife  Service, Denver Wildlife Research Center, Denver, Colorado, USA</P>
+<P ALIGN="JUSTIFY">H. FISCHER, Tropical Science Centre, Division of Tropical Veterinary Medicine,  Justus-Liebig University, Giessen, West Germany</P>
+<P ALIGN="JUSTIFY">J. FURTADO, Commonwealth Science Council, London, England</P>
+<P ALIGN="JUSTIFY">FRANK GOLLEY, Institute of Ecology, University of Georgia, Athens, Georgia, USA</P>
+<P ALIGN="JUSTIFY">E. GONZALES J., Instituto de Produccion Animal, Universidad Central de Venezuela,  El Limon-Maracay, Venezuela</P>
+<P ALIGN="JUSTIFY">GRAHAM GOUDIE, Mainland Holdings, Lae, Papua New Guinea</P>
+<P ALIGN="JUSTIFY">ALISTAIR GRAHAM, Tanglewood, Crowborough, East Sussex, England</P>
+<P ALIGN="JUSTIFY">GORDON GRIGG, Zoology, University of Sydney, Sydney, New South Wales, Australia</P>
+<P ALIGN="JUSTIFY">M.R. DE GUMAN, JR., Food and Fertilizer Technology Center, Taipei, Taiwan</P>
+<P ALIGN="JUSTIFY">COLIN P. GROVES, Department of Prehistory and Anthropology, The Australian  National University, Canberra, ACT, Australia </P>
+<P ALIGN="JUSTIFY">J. HARDOUIN, Institut de Medicine Tropicale "Prince Leopold," Antwerp, Belgium</P>
+<P ALIGN="JUSTIFY">GEOFFREY HAWTIN, International Development Research Centre, University of  British Columbia, Vancouver, B.C., Canada</P>
+<P ALIGN="JUSTIFY">GORDON HAVORD, Technical Advisory Division, UNDP, New York, New York, USA</P>
+<P ALIGN="JUSTIFY">TIN HLA, Veterinary Department, Director General's Office, Rangoon, Burma</P>
+<P ALIGN="JUSTIFY">JAMES HENTGES, Department of Animal Science, University of Florida, Gainesville, Florida, USA</P>
+<P ALIGN="JUSTIFY">W.F. HOLLANDER, Department of Genetics, Iowa State University, Ames, Iowa, USA</P>
+<P ALIGN="JUSTIFY">RENE E. HONEGGER, Herpetology, Zurich Zoo, Zurich, Switzerland</P>
+<P ALIGN="JUSTIFY">JACK HOWARTH, School of Veterinary Medicine, University of California, Davis, California, USA</P>
+<P ALIGN="JUSTIFY">HUANG CHU-CHIEN, Institute of Zoology, Academia Sinica, Beijing, China</P>
+<P ALIGN="JUSTIFY">ANGUS HUTTON, Gympie, Queensland, Australia</P>
+<P ALIGN="JUSTIFY">H.A. JASIOROWSKI, Animal Production and Health Division, FAO, Rome, Italy</P>
+<P ALIGN="JUSTIFY">MUHAMMAD YAQUB JAVAID, Directorate of Fisheries, Government of the Punjab, Punjab, India</P>
+<P ALIGN="JUSTIFY">J. MANGALARAJ JOHNSON, Nudumalai Sanctuary, Vannarpet, Udagamandalani, India</P>
+<P ALIGN="JUSTIFY">MATI KAAL, Tallinn Zoo, ESSR Tallinn, USSR</P>
+<P ALIGN="JUSTIFY">STELLAN KARLSSON, Simontorp Aquaculture AB, Blentarp, Sweden</P>
+<P ALIGN="JUSTIFY">JACKSON A. KATEGILE, International Development Research Centre, Nairobi, Kenya</P>
+<P ALIGN="JUSTIFY">ROBERT E. KENWARD, Institute of Terrestrial Ecology, Furzebrook Research Station, Wareham, Dorset, England</P>
+<P ALIGN="JUSTIFY">JAMES M. KEARNEY, Miami, Florida, USA</P>
+<P ALIGN="JUSTIFY">F. WAYNE KING, Florida State Museum, Gainesville, Florida, USA</P>
+<P ALIGN="JUSTIFY">H.-G. KLOS Zoologischer Garten Berlin, Berlin, West Germany</P>
+<P ALIGN="JUSTIFY">NELS M. KONNERUP, Boom International, Stanwood, Washington, USA</P>
+<P ALIGN="JUSTIFY">NAVU KWAPENA, Office of Environment and Conservation, Boroko, Papua New Guinea</P>
+<P ALIGN="JUSTIFY">THOMAS E. LACHER, Huxley College of Environmental Studies, Western Washington University, Bellingham, Washington, USA</P>
+<P ALIGN="JUSTIFY">JOHN K. LOOSLI, Gainesville, Florida, USA</P>
+<P ALIGN="JUSTIFY">PETER LUTZ, Rosenstiel School of Marine and Atmospheric Science, University of Miami, Miami, Florida, USA</P>
+<P ALIGN="JUSTIFY">CRAIG MACFARLAND, CATIE, Turrialba, Costa Rica</P>
+<P ALIGN="JUSTIFY">CONSTANCE M. MCCORKLE, Department of Rural Sociology, University of Missouri, Columbia, Missouri, USA</P>
+<P ALIGN="JUSTIFY">ROBERT E. MCDOWELL, Department of Animal Science, Cornell University, Ithaca, New York, USA</P>
+<P ALIGN="JUSTIFY">JEFFREY A. MCNEELY, International Union for Conservation of Nature and Natural Resources, Gland, Switzerland</P>
+<P ALIGN="JUSTIFY">ADRIAN G. MARSHALL, Institute of South-East Asian Biology, University of Aberdeen, Aberdeen, Scotland</P>
+<P ALIGN="JUSTIFY">RICHARD R. MARSHALL, Veterinary Medicine, Sutter Hospitals Medical Research Foundation, Sacramento, California, USA</P>
+<P ALIGN="JUSTIFY">G.H.G. MARTIN, Department of Zoology, Kenyatta University College, Nairobi, Kenya </P>
+<P ALIGN="JUSTIFY">IAN L. MASON, Edinburgh, Scotland</P>
+<P ALIGN="JUSTIFY">JOHN C. MASON, Pacific Biological Station, Nanaimo, B.C., Canada</P>
+<P ALIGN="JUSTIFY">J. MAYO MARTIN, Fish Farming Experimental Station, Stuttgart, Arkansas, USA</P>
+<P ALIGN="JUSTIFY">YOLANDA MATAMOROS, Escuela de Medicina Veterinaria, Universidad Nacional, Heredia, Costa Rica</P>
+<P ALIGN="JUSTIFY">ROBIN MCKERGON, Livestock Development Corporation, Lae, Papua New Guinea</P>
+<P ALIGN="JUSTIFY">M. MGHENI, Faculty of Agriculture, Sokoine University of Agriculture, Morogoro, Tanzania</P>
+<P ALIGN="JUSTIFY">P. MONGIN, Station de Recherches Avicoles, INRA-Centre de Tours, Nouzilly, Monnaie, France</P>
+<P ALIGN="JUSTIFY">JOSE ROBERTO DE ALENCAR MOREIRA, Agricultural Research Center of the Humid Tropics, Belem, Para, Brazil</P>
+<P ALIGN="JUSTIFY">W.L.R. OLIVER, Jersey Wildlife Preservation Trust, Jersey, Channel Islands, United Kingdom</P>
+<P ALIGN="JUSTIFY">WERNER PAUWELS, Basel, Switzerland</P>
+<P ALIGN="JUSTIFY">W.J.A. PAYNE, Worcester, England</P>
+<P ALIGN="JUSTIFY">IAN PLAYER, Wilderness Leadership School, Bellair, Natal, South Africa</P>
+<P ALIGN="JUSTIFY">JAMES H. POWELL, JR., Plainview, Texas, USA</P>
+<P ALIGN="JUSTIFY">WILLIAM R. PRITCHARD, School of Veterinary Medicine, University of California, Davis, California, USA</P>
+<P ALIGN="JUSTIFY">HECTOR HUGO LI PUN, International Development Research Centre, Bogota, Colombia</P>
+<P ALIGN="JUSTIFY">VICENTE T. QUIRANTE, Small Ruminant Collaborative Research Project, Bureau of Animal Industry, Manila, Philippines</P>
+<P ALIGN="JUSTIFY">DAN RATTNER, The Institute of Animal Research, Kibbutz Lahav, D.N. Negev, Israel</P>
+<P ALIGN="JUSTIFY">C.V. REDDY, Faculty of Veterinary Science, Andhra Pradesh Agricultural University, Rajendranagar, Hyderabad, India</P>
+<P ALIGN="JUSTIFY">RHOEHEIT, Institute of Applied Science and Technology, University Campus, Turkeyen, Guyana</P>
+<P ALIGN="JUSTIFY">CHARLES T. ROBBINS, Department of Zoology, Washington State University, Pullman, Washington, USA</P>
+<P ALIGN="JUSTIFY">CARMEN MA. ROJAS G., CATIE, Turrialba, Costa Rica</P>
+<P ALIGN="JUSTIFY">D.H.L. ROLLINSON, Sardinia, Italy</P>
+<P ALIGN="JUSTIFY">JULIO E. SANCHEZ P., Museo Nacional, San Jose, Costa Rica</P>
+<P ALIGN="JUSTIFY">JEFF SAYER, World Conservation Centre, Gland, Switzerland</P>
+<P ALIGN="JUSTIFY">G. SEIFERT, Tropical Cattle Research Centre, CSIRO, Rockhampton, Queensland, Australia </P>
+<P ALIGN="JUSTIFY">ANDRES ELOY SEIJAS, Servicio Nacional de Fauna Silvestre, Maracay, Venezuela</P>
+<P ALIGN="JUSTIFY">S.K. SHAH, Institute of Animal Sciences, National Institute of Health, Islamabad, Pakistan</P>
+<P ALIGN="JUSTIFY">SIEH CHENXIA, Department of Animal Science, Nanjing Agricultural College, Nanjing, People's Republic of China</P>
+<P ALIGN="JUSTIFY">B.P. SINGH, College of Veterinary and Animal Science, Chandra Sekhar Azad University of Agriculture and Technology, Mathura, Uttar Pradesh, India</P>
+<P ALIGN="JUSTIFY">C. CATIBOG SINHA, Forest Research Institute, College, Laguna, Philippines </P>
+<P ALIGN="JUSTIFY">A.J. SMITH, Tropical Animal Health, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Edinburgh, Scotland, Great Britain</P>
+<P ALIGN="JUSTIFY">A. MITHAT EFENDI, Ankara, Turkey</P>
+<P ALIGN="JUSTIFY">HENRY STODDARD, Shamrock Veterinary Clinic and Fisheries, Cross City, Florida, USA</P>
+<P ALIGN="JUSTIFY">SUKUT SULARSASA, Faculty of Animal Husbandry, Gadjalu Mada University, Yogyakarta, Indonesia </P>
+<P ALIGN="JUSTIFY">D.L. SUTTON, Agricultural Research and Education Center, Fort Lauderdale, Florida, USA</P>
+<P ALIGN="JUSTIFY">NICHOLAS SMYTHE, Smithsonian Tropical Research Institute, Panama</P>
+<P ALIGN="JUSTIFY">J. SZUMIEC, Polish Academy of Sciences, Experimental Fish Culture Station, Chybie, Poland</P>
+<P ALIGN="JUSTIFY">N. TABUNAKAWAI, Ministry of Primary Industries, Suva, Fiji</P>
+<P ALIGN="JUSTIFY">FRANK M. THOMPSON, Wild Animal Brokers, Bradenton, Florida, USA</P>
+<P ALIGN="JUSTIFY">ALLEN D. TILLMAN, Stillwater, Oklahoma, USA</P>
+<P ALIGN="JUSTIFY">DON TULLOCH, Winnellie, Northern Territory, Australia</P>
+<P ALIGN="JUSTIFY">CONRADO A. VALDEZ, Dairy Development Division, Bureau of Animal Industry, Manila, Philippines</P>
+<P ALIGN="JUSTIFY">LUIS VARONA, Havana, Cuba</P>
+<P ALIGN="JUSTIFY">PRAN VOHRA, Department of Avian Sciences, College of Agricultural and Environmental Sciences, University of California, Davis, California, USA</P>
+<P ALIGN="JUSTIFY">ANTOON DE VOS Whitford, Auckland, New Zealand</P>
+<P ALIGN="JUSTIFY">GRAHAME WEBB, Conservation Commission of the Northern Territory, Winnellie, Northern Territory, Australia</P>
+<P ALIGN="JUSTIFY">DAGMAR WERNER, Fundacion Pro Iguana Verde, Heredia, Costa Rica</P>
+<P ALIGN="JUSTIFY">GARY WETTERBERG, Department of the Interior, Washington, D.C., USA</P>
+<P ALIGN="JUSTIFY">CHARLES H. WHARTON, Clayton, Georgia, USA</P>
+<P ALIGN="JUSTIFY">F.W. BERT WHEELER, College Station, Texas, USA</P>
+<P ALIGN="JUSTIFY">ROMULUS WHITAKER, Madras Crocodile Bank, Perur, Tamil Nadu, India</P>
+<P ALIGN="JUSTIFY">WILDLIFE CONSERVATION INTERNATIONAL, New York Zoological Society, The Bronx, New York, USA</P>
+<P ALIGN="JUSTIFY">R.R. YEO, USDA-ARS, University of California, Davis, California, USA</P>
+<P ALIGN="JUSTIFY">BRUCE A. YOUNG, Department of Animal Science, University of Alberta, Edmonton, Alberta, Canada</P>
+<P ALIGN="JUSTIFY">CHAROON YOUNGPRAPAKORN, The Samutprakan Crocodile Farm and Zoo, Samutprakan, Thailand</P>
+<P ALIGN="JUSTIFY">THOMAS M. YUILL School of Veterinary Medicine, University of Wisconsin, Madison, Madison, Wisconsin, USA</P>
+<P ALIGN="JUSTIFY">W. ZEILLER, Miami Seaquarium, Miami, Florida, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Preface</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The purpose of this report is to raise awareness of the potential of small livestock species and to stimulate their introduction into animal research and economic development programs. It is geared particularly towards benefiting developing nations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">"Microlivestock" is a term we have coined for species that are inherently small, such as rabbits and poultry, as well as for breeds of cattle, sheep, goats, and pigs that are less than about half the size of the most common breeds. These miniature animals are seldom considered in the broad picture of livestock development, but they seem to have a promising future. Wherever land is scarce it seems reasonable to assume that, things being equal, small animals would be more attractive than large ones. And land for livestock is becoming increasingly scarce.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this report we have emphasized multipurpose species with promise for small  holders. In some species, the promise is immediate; in others, it is long term, and much research must be undertaken before that promise can be realized or even understood.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We have included wild species that seem to have potential as future livestock. Some are threatened with extinction but are described here because their economic merits may be the key to acquiring support for their protection. Also we have highlighted rare breeds of domesticated species because the current tendency has been to concentrate on a small number of large breeds, and many potentially valuable breeds are becoming extinct through neglect.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The book was prepared after an intensive survey of more than 300 animal scientists in 80 countries. They suggested more than 150 species for inclusion. The staff then drafted chapters on about 40 species and these drafts were reviewed by more than 400 researchers worldwide. The thousands of resulting comments, corrections, and additions were integrated into the drafts. The panel then met to review the product, to select the most promising species, and to rework the chapters based on their own experiences and joint conclusions. The result is the current 35 chapters. Most of the case studies and accounts of innovations highlighted in the various sidebars were developed by the staff study director. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Collectively, this study covers many species, but it by no means exhausts all the microlivestock possibilities. Lack of space and time precludes discussion of creatures such as edible insects, snails, worms, turtles, and bats, which in some regions are highly regarded foods. Similarly, we have not included aquatic life. These decisions were arbitrary; perhaps invertebrates and aquatic species can be included in future volumes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report is addressed to government administrators, technical assistance personnel, and researchers in agriculture, nutrition, and related disciplines who are concerned with helping developing countries achieve a more efficient and balanced exploitation of their biological resources. Hence, we deal with the animals in a general way and do not cover details of biology, husbandry, or economics. A selection of readings that contains such technical information is cited in Appendix A.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A further goal of this project has been to explore the common ground between the disparate arms of animal science: to show that specialists in wildlife, zoology, and livestock science have much to learn from one another's field of expertise; to show that "fanciers" of pigeons, pheasants, chinchillas, iguanas, and other species may have much to offer livestock breeders - including germplasm; and that those who raise "obsolete" breeds are not only playing a vital role in the protection of rare genes but can offer the benefit of their experience to commercial livestock producers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Throughout this report, the scientific names of mammals follow those in: Mammal Species of the World: A Taxonomic and Geographic Reference. 1982. J.H. Honacki, K.E. Kinman, and J.W. Koeppl, editors. Published by Allen Press, Inc.; and the Association of Systematics Collections, Lawrence, Kansas, USA. All dollar figures are in U.S. dollars; all ton figures are in metric tons.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report has been produced under the auspices of the Advisory Committee on Technology Innovation (ACTI) of the Board on Science and Technology for International Development, National Research Council. ACTI was mandated to assess innovative scientific and technological advances, with particular emphasis on those appropriate for developing countries. In this spirit, therefore, the current report includes some extremely unusual species. Whether these will eventually prove practical for widespread use is uncertain, but we present them here for researchers and others who look forward to challenges and enjoy the satisfaction of successful pioneering. The domestication of new poultry, as well as the management of rodents, iguanas, and small deer and antelope, should be viewed in this spirit.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Current titles in the ACTI series on managing tropical animal resources are: </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The Water Buffalo: New Prospects for an Underutilized Animal</P>
+<P ALIGN="JUSTIFY">· Little-Known Asian Animals with a Promising Economic Future</P>
+<P ALIGN="JUSTIFY">· Crocodiles as a Resource for the Tropics</P>
+<P ALIGN="JUSTIFY">· Butterfly Farming in Papua New Guinea.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The production of these books has been supported largely by the Office of the Science Advisor of the U.S. Agency for International Development (AID), which also made this report possible.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WARNING</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">If misunderstood, this book is potentially dangerous. Because of the severity of the food crisis, the panel has selected some animals - mainly in the rodent section - that are highly adaptable and grow quickly. These seem appropriate for raising only in areas where they already exist, which are clearly identified in those chapters. Such potentially invasive animals should not be introduced to other environments because they could become serious pests. In any trials, local species should always be given priority.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">How to cite this report:</P>
+<P ALIGN="JUSTIFY">National Research Council. 1991. Microlivestock: Little-Known Small Animals with a Promising Economic Future. National Academy Press, Washington, D.C. </P>
+<P ALIGN="JUSTIFY">Cover Design by David Bennett </P>
+<P ALIGN="JUSTIFY">In the developing countries, there are over 100 million farms of less than five hectares, supporting about 700 million people, who represent about 17 percent of the world population. Even more significant is the fact that about 50 million farms have less than one hectare of land. C. Devendra and Marcia Burns Goat Production in the Tropics We may now be in the wind down stage of bigger is better animal selection trend and it has certainly been a wild ride.... the lesson now being learned is that the bigger breeding animals . . . cost more to maintain, are often slower to reproduce, and may even have a shorter lifespan.</P>
+<P ALIGN="JUSTIFY">Kelly Klober</P>
+<P ALIGN="JUSTIFY">Small Farmer's Journal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Introduction</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g001a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like computers, livestock for use in developing countries should be getting smaller and becoming more "personal." Conventional "mainframes," such as cattle, are too large for the world's poorest people; they require too much space and expense. "Miniframes," such as the conventional breeds of sheep and goats, have an increasingly important role to play. But tiny, "user-friendly" species for home use are the ones highlighted in this report. We have called them "microlivestock."'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are two types of microlivestock. One consists of extremely small forms of conventional livestock - such as cattle, sheep, goats, and pigs. The other consists of species that are inherently small poultry, rabbits, and rodents, for instance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microlivestock are important because the developing world's animal production is only a fraction of what it should be. Throughout Latin America, Asia, and Africa, the poor eat almost no meat, milk, or eggs - the most nutritious foods. It is estimated, for example, that in Mexico 25 million campesinos cannot afford meat. In poor countries, even the middle class eats less meat in a year than the populations of North America and Europe eat in a month. Malnutrition is common and its effects, especially on children, can be debilitating. It is one of mankind's most serious imbalances - and most pressing problems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rural families in the Third World usually subsist mainly on the products from their homes or farms. Thus, if we are to help their livestock production, more attention must be given to animals that are sized for their situations. Examples discussed in the report are summarized here.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microbreeds Small breeds of cattle, sheep, goats, and pigs are common in the developing world. Because they are often raised for subsistence rather than for commerce, the national and global contribution that they make is often overlooked. These small, hardy animals deserve much greater recognition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Later chapters highlight dozens of promising microbreeds. All are less than half average size; some are far smaller than that. The "miniBrahman" cow of Mexico is only 60 cm tall and weighs 140 kg; the southern Sudan dwarf sheep of eastern Africa can weigh as little as 11 kg; the Terai goat of Nepal weighs less than 12 kg; and the cuing pig of Mexico weighs merely 10 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Poultry The widespread use of poultry in Third World villages demonstrates the importance of small, easily managed, household livestock. Small size, the ability to forage for themselves, and a natural desire to stay around the house put chickens, ducks, guinea fowl, and other birds among the most vital resources of rural Asia, Africa, and Latin America. Scratching a living out of the dirt, dust, ditches, and debris, these often-scrawny creatures are a resource to be taken seriously. For the most poverty stricken, a bony bird may be the only source of meat during much of a lifetime. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Among poultry, there are many underrated, but highly promising, species, including:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Pigeon. These birds forage widely but return home, thereby providing the farmers with squab, one of the tastiest of all meats. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Quail. Small and efficient, they, too, are suited to home rearing, and in Japan and a few other countries, large numbers are raised commercially in very small space. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Muscovy. A native of South American rainforests, this bird is a major poultry resource of France, Taiwan, and a few other countries. Tame, tolerant, and tough, it deserves greater recognition everywhere. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Guinea Fowl. One of the most self-reliant of all domestic birds, this native of Africa is raised in huge numbers in Europe - notably France. Its potential for increased production elsewhere is exceptional. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Turkey. The traditional turkey of Mexico still exists as a scavenger bird in villages and household backyards. Unlike the highly selected modern breeds, it is self-reliant, robust, and disease-resistant. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rabbits Like chickens, rabbits exemplify the vast possibilities that microlivestock offer for increasing meat production in the most poverty-stricken parts of the world. Captive rabbits have been popular as food at least since the time of the Romans. Rabbit rearing has been well established in Europe and China, and now national rabbit projects have begun in many developing nations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rodents Some 7,000 years ago, guinea pigs were domesticated as a source of food for the high Andes; even today in the uplands of Bolivia, Peru, and Ecuador, most Indians raise them inside their homes and regard them as an essential part of life. For many Indians, these indoor livestock are the main source of meat. Prolific, tractable, and easy to feed, house, and handle, guinea pigs are even kept in downtown apartment buildings - often in boxes under the bed. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other rodents might also be suited to domestication; for instance, the potentially tamable, clean-living species of South American fields and woodlands - agouti, capybara, hutia, mare, coypu, pace, and vizcacha. Two remarkable domestication programs have been started in Africa: the grasscutter in West Africa and the giant rat in Nigeria. Both animals provide popular "bushmeat" and researchers are now learning to raise them in captivity. (Because of its tangy taste, Ghanaians actually pay three times more for grasscutter meat than for beef!)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antelope Another wild African mammal with potential for "household animal husbandry," the blue duiker, is a rabbit-sized antelope. In some areas of Central and Southern Africa the demand is so great that its population is declining at an alarming rate. Duiker rearing, if it can be made successful, might provide both food and an economic alternative to slaughtering the wild populations. It is reported that duikers are easy to maintain and they reproduce well in captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The meat of several other tiny antelope species is also much sought in many African countries, and these animals are also suitably sized to feed the average family at one meal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Deer Several species of tiny deer - smaller than many dogs - might make useful microlivestock, although much research is needed before their true potential can be judged. Normal-sized deer were once considered too easily frightened to be reared as domestic livestock, but several species are now raised on thousands of deer farms in New Zealand as well as in at least a dozen other countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mouse deer and musk deer (which, strictly speaking, are not true deer at all) are of microlivestock size and are also possible future livestock. The musk deer produces one of the most valuable materials in the animal kingdom - more valuable, in fact, than gold. The musk from the male's glands is used in oriental medicines as well as in European perfumes. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Iguanas Over much of the Caribbean and Latin America, iguanas are a traditional source of food. Indeed, the meat of these large herbivorous lizards is so delicious they are being hunted to extinction throughout their wide range. Their eggs are much enjoyed also. Programs in Panama, Costa Rica, El Salvador, Curacao, and Argentina have developed simple methods to hatch and rear three iguana species. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bees Honey bees are present almost everywhere, and honey and wax are high-value products that demand little processing and can be stored and transported easily. Innovations in equipment and technique have made beekeeping successful in the tropics without requiring sophisticated hives or elaborate training. Raising bees can also benefit the many crops that require pollination.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE MICROLIVESTOCK ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although animal science has traditionally emphasized bigness, smallness has its advantages. Some of these are summarized below.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economic</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microlivestock lend themselves to economic niches that are not easily filled by large livestock. Much of their potential is for subsistence production. They are promising for the many peasants who, being outside the cash economy, are now unable to purchase meat, milk, cheese, or eggs. These people can afford only animals that can be raised within the home or backyard under ambient climatic conditions and on feeds that are cheap and easily available.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A subsistence farmer is likely to benefit more from small species than from large because of several factors:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">- The animals are less expensive to buy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- They are less of a financial risk to maintain. (A farmer with several small animals is less vulnerable to loss than a farmer with a single large animal, a feature that is particularly important in subsistence farming where success determines whether the family will survive.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- They give a faster return on investment. (Small size generally signifies high reproductive capacity and a fast turnover.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- They provide flexibility. (Farmers can more easily change the size of their herd or flock to match the amount of feed available at a given time. Also, they can sell animals according to the family's fluctuating needs for cash or food.) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- They provide a steadier source of income.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- They increase the chances of successful breeding because greater numbers are usually kept. (This also means that breeding stock is more likely to be retained in times of scarcity.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- They are more easily transported. (Who hasn't traveled in a Third World bus or train without chickens, ducks, or guinea pigs as fellow passengers?)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- In some cases they are more efficient converters of food energy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are also a number of other benefits to small species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Reduced Spoilage. A portion of meat that comes in a "package" of a size that can be readily consumed by a family is important in areas where refrigeration is unavailable or uneconomic. A family can eat the meat produced by most microlivestock in one meal or in one day to minimize the risk of spoilage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Efficient Use of Space. The space required for handling and feeding microlivestock is proportionately less than that required for large animals. Low space requirements make many microlivestock (such as guinea pigs, rabbits, pigeons, and quail) available to landless rural inhabitants who have no room for a cow. This is particularly important with respect to feed production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Cheaper Facilities. Facilities and equipment required for microlivestock are, by and large, smaller and simpler than those required for large animals. They often can be made from local products or scrap material or both.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Ease of Management. Farmers and villagers can manage small animals more easily than large, which is an advantage in the many places where women and children are the main keepers of livestock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Increased Productivity. Small animals tend to fit well into existing farming systems, thereby expanding the resource base and recycling nutrients. Some - for example bees, ducks, and geese - can feed themselves by scavenging.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- By-Products. Many species have fur, feathers, skins, and other by-products that are often more valuable than their meat, milk, or eggs. Examples include the feet and tails of rabbits, musk from musk deer, and pelts from rodents such as coypu. Processing such byproducts creates diversification for the farmer and perhaps jobs for the village.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RATIONALE FOR LIVESTOCK PRODUCTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many have argued that livestock raising should be discouraged, that it is a primary cause of desertification through overgrazing and that it is an inefficient converter of basic material and energy into human food. "Grow more pulses, grow more grains," these people cry. Their arguments can be valid where the land has high potential for permanent cultivation. Much of the world's surface, however, does not fit into that category, and it is in these areas and for those people who have no access to arable lands that a convincing case for livestock can most easily tee mace. As W.J.A. Payne has written:*</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Livestock, particularly ruminants, can process forage and waste crop materials inedible by man into nutritionally desirable food products, many of high protein, mineral and vitamin content and including some of high caloric value. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Approximately 40 percent of total land available in developing countries can be used only for some form of forage production and a further 30 percent is classified as forest with some potential for the production of forage. Some 12 percent of the world's total population live in areas where people depend almost entirely on the products obtained from ruminant livestock. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Livestock provide a range of extremely valuable by-products. Dung is not only a fertilizer and soil-stabilizer but also a fuel of often considerably greater value than the fodder consumed in its production. Other byproducts, especially hides and wool form the bases of rural enterprises that may provide significant incomes to the poorest members of society. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Animal plant and human life are ecologically interdependent. The establishment of agricultural systems in which livestock are integrated with crops, forestry and aquaculture is essential for the improvement of overall productivity. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Livestock produce food that adds to the nutritional quality and variety of human diets. Although it is possible for humans to exist without them, these foods are relished and sought after by the majority of humanity. These foods include meat, eggs and processed products such as biltong and cheese. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Feed</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In general, small species tend to expand the food base by using a wider array of resources than do major livestock such as cattle. Many can be raised on feeds that people discard: fibrous residues, industry by-products, or kitchen wastes. Some collect minute feeds that otherwise go unused. For example, chickens and pigeons gather scattered seeds, turkeys gobble up insects, geese graze water weeds, iguanas feed in the tops of trees, and bees collect nectar and pollen from flowers that may be miles away.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Even some grazing microlivestock prefer different forages from those preferred by cattle. Antelope and deer, for instance, browse tree leaves; capybara and grasscutters eat reeds. Combining microlivestock with conventional livestock results in a more complete utilization of forage resources and greater animal production per hectare.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under conditions of abundance, small size may be of no advantage in mammals, but if feed is limited, it is of great help. A small animal (or its keeper) needs to cover less area to fulfill its daily requirements, so that microlivestock may grow fat in areas where the forage is too sparse to support a larger animal. This is particularly vital when there are seasonal bottlenecks. For example, feed may be plentiful enough for most of the year to supply many large animals; however, the dry season may greatly restrict the numbers that can be kept.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although small animals generally require proportionately higher inputs of feed, they also grow proportionately faster (see sidebar opposite). In addition, species such as rabbits, guinea pigs, and grasscutters digest fibrous matter with surprising efficiency, even though they are not true ruminants like cattle, sheep, and goats.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Reproduction</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many small animals have high reproductive capacity with short gestation periods, large numbers of offspring, and rapid juvenile growth. They tend to reach sexual maturity at a younger age than large animals, and the interval between the generations can be very short. Thus, meat or other products can be produced more rapidly and more evenly throughout the year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cows, for example, produce a maximum of one calf per year. A pig, on the other hand, may produce 7 or more young; a rabbit, 30 or more; a chicken, more than 100.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Adaptability and Hardiness</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The survival rates and manageability of many small breeds and species can be outstanding. Smallness is often an adaptation to harsh environment. Indeed, a major promise for microlivestock is in special environmental niches. Where cold, heat, temperature fluctuations, aridity, or humidity are extreme, microlivestock are likely to show their greatest advantage. Chickens, guinea fowl, goats, and many other small species already live in villages, homes, and backyards in harsh and disease-prone climates, and are usually given no care and sometimes no food: they have to scavenge for their sustenance and survive as best they can. Such selection pressures result in animals of remarkable adaptability, tolerance, and robustness.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Some microlivestock can produce under conditions where conventional species die. The capybara, for instance, is at home in the Latin American lowlands, where the climate is hot and humid and floods cause seasonal inundations. Cattle, by contrast, die because of malnutrition, foot rot, or drowning. Other microlivestock species with a wide tolerance to ecological extremes include the turkey, pigeon, and bee. And some dwarf breeds of cattle, sheep, goats, and pigs show surprising tolerance to trypanosomes, the parasites that make conventional breeds impossible to maintain throughout much of Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some small species can be raised in cities, where poverty and malnutrition are often worse than in rural areas. It is estimated, for instance, that one million livestock exist in Cairo, not counting the pigeons that are raised on countless rooftops. Goats and cattle are common in urban India, and many Third World cities have far more chickens than people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p9a.png"></center><br>
+ Food utilization versus body size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MICROLIVESTOCK LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Raising microlivestock is not a panacea for the Third World's food problems. Efforts to develop them will not be without difficulties. Some likely problems are noted here.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">High Energy Requirements</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Smaller animals tend to have a higher feed requirement per unit of body weight than large animals. Anatomical and physiological constraints prevent them from meeting their relatively high energy requirements simply by increasing the rate of food ingestion. Therefore, for optimum production, some small animals, particularly nonruminants, require feed that is higher in protein and lower in fiber than large animals. This is particularly true when the small animals are compared with ruminants such as cattle, sheep, and goats.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Increased Labor Requirements</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The advantages of low investment, fast return on capital, flexibility, and efficient resource utilization are offset by higher demands for labor. Keeping small animals often requires considerable effort, and its economic viability may depend on the availability of cheap and willing labor. Many small animals are raised at home by family members, such as children, the elderly, and the handicapped, who have time available and whose labor costs are nominally zero.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Diseases</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some potential microlivestock are undomesticated, and resistance to diseases and parasites is one justification for their consideration. However, the general healthiness of a species when it is free-ranging can be a misleading guide for its husbandry. Confining any animal in high density invariably increases the potential for the spread of infectious diseases and parasites. Moreover, mismanagement can foster respiratory and gastrointestinal diseases (such as salmonella or coccidiosis) that are rare among scattered populations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some microlivestock are potential reservoirs for diseases that affect not only local animals but people as well. This may limit their successful development in some areas. Although the dangers are often exaggerated, controls may be needed, particularly of rinderpest, tickborne diseases, and those diseases communicable to humans.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Predation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Small size makes microlivestock easy prey.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lack of Research</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Techniques to manage some microlivestock species are not yet well established. The development of appropriate husbandry techniques, as well as a better understanding of the animals' particular biological and behavioral characteristics, will be needed before major progress can be made. These species (for instance rodents, deer, and iguanas) may require collection of different genotypes, as well as studies of diseases, nutrition, and management.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Complex Logistics</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is complicated and expensive to reach millions of widely scattered peasants, each having only a handful of small animals. Even though total production may far exceed that of commercial farms raising large animals, the smallholdings are often dispersed, their animals are often used for subsistence rather than commerce, and their managers are often ill-trained and illiterate.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Legislative Restrictions</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The use of some microlivestock species may be restricted by legislation. For instance, some countries have meat and veterinary laws that work against the development of species other than cattle. Others have laws to protect wildlife, which could be important in the case of species such as antelope, deer, pace, and iguana.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lack of Markets</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microlivestock need not be just for home or local consumption; they can also be raised for market. But some commercial programs, including some with rabbits and guinea pigs, have failed because no public demand was developed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Resistance to New Species</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">People have close associations with livestock, and in most cultures they do not easily accept animals or animal foods that are radically different from their traditional ones. In general, the ties between certain ethnic groups and a particular species or breed is very strong (one reason, for example, why European colonists introduced their own large breeds of cattle and sheep to Africa and Asia, paying little attention to small indigenous breeds). Moreover, people who are used to bringing the animal to the feed rather than the feed to the animal may resist a small animal that has to be penned up and fed by hand.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Opposition to Smallness</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, there seems to be an innate human trait that considers bigger to be better, especially among the common livestock. For example, because many tropical cattle are small, there is strong inclination on the part of those responsible for livestock improvement to dismiss them or to increase their size by crossing them with large breeds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FUTURE OF MICROLIVESTOCK</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Small animals are likely to become increasingly important. As human populations increase, the space available for growing forage decreases, and this phenomenon favors small animals. Many villagers already have little or no pastureland. Some live in areas (the rice-growing areas of Southeast Asia, for instance) where crops are grown on almost every square meter almost every month of the year. Microlivestock are potentially important for urban areas of developing countries as well. There, too, land is at a premium and is usually inadequate for raising conventional livestock. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So far, however, microlivestock have been largely ignored. Compared with cattle, they have been accorded little scientific effort. In the drive towards larger animals, stimulated by experience in the temperate zone, the virtually unstudied gene pool of small species and breeds has been mostly bypassed. There have been few attempts to assess or improve their farm productivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This is unfortunate, and it is perhaps due to the fact that small animals may be less efficient at digesting certain foods and therefore technically less attractive than large, "modern" breeds. But to Third World peasants, an animal's efficiency is far less important than its survivability and manageability. If an animal cannot be raised under village conditions, its feed-use efficiency or milk yield is irrelevant.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microlivestock production should be integrated into most ruraldevelopment projects. Small animals offer a way to improve the lives of people who are hard to reach by other methods. Only by expanding research on the husbandry, hygiene, nutrition, reproduction, physiology, and breeding can the promise of animals sized for small farms and villages be fulfilled. Moreover, the costs will be small compared with those of programs for large animals.2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Specifically, experiment stations should produce and promote methods and materials for use in rearing microlivestock. Donors and development institutions, planners, and policymakers should note the potentials of microlivestock and the benefits that can be derived from them. Teaching manuals and materials are needed, and classes in microlivestock husbandry should be included in rural school curricula.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Raising personal livestock on weeds and table scraps in cages beside the house or boxes under the bed will, in many instances, get quality protein to the most poverty stricken more effectively than raising large livestock on pastures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although small size confers many advantages, the question is not whether the large or small animal is "best," but rather how well each can meet a person's varying requirements. In a given situation, livestock can be too small or too large. But the fact remains that not everyone who wants meat or money has the resources to acquire, keep, manage, or utilize a large animal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The key is balance. Both microlivestock and traditional livestock deserve serious attention. Indeed, it seems likely that the two will seldom compete. Most microlivestock complement traditional livestock because of unique physical, physiological, behavioral, or economic characteristics. They increase the range of options for the millions of poor for whom the choice may not even be between large and small livestock, but between microlivestock and no livestock at all. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It's an unfortunate fact that small animals don't have the prestige among Third World farmers that large animals do (perhaps this arose because children can look after goats and sheep but it takes men to look after cattle). Even sheep and goats are not accorded the same stature as cattle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hugh Popenoe</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Breeds and varieties were created from mutant genes and thus haste become living reservoirs of these genes, holding them for use in future generations of mankind.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anonymous</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g002a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Part I : Microbreeds</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g003a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cattle, goats, sheep, and pigs supply millions of people around the world with the bulk of their cash and animal products. Yet scores of breeds - especially in the tropics - are left out of livestock development projects merely because they are considered too small. These "microbreeds"' have sometimes been considered genetic dead ends because they appear undersized and puny. Many of these traditional animals - some in local use for thousands of years - are disappearing, and even the small ancestors of large modern breeds are becoming extinct.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These small breeds deserve to be studied and developed in their own right. Throughout Africa, Asia, and Latin America, these usually hardy animals are especially adapted to traditional husbandry practices and harsh local conditions. Some have remarkable qualities and are well adapted to resist hostile weather, ravaging pestilence, and poor diets. In remote places and in areas of extreme climate, they are often vitally important for basic subsistence.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Indeed, because of stress or disease, or insufficient forage, land, or money, microbreeds may be the only practical livestock in many settings. Their individual output may be low, but it can be efficient considering the lack of care and poor feeds they are given. Their availability and the growing number of small-sized farms in the developing world make them increasingly worthy of consideration.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The following chapters in this section describe microcattle, microgoats, microsheep, and micropigs. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">1 Microcattle</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g004a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For the purposes of this report, "microcattle" are considered to be small breeds of cattle (Bos taurus and Bos indicus) with a mature weight of about 300 kg or less. In many areas of the developing world, these are actually the animals most widely held by farmers and pastoralists. They are often treasured because of their resilience and simple requirements. Many survive and produce under harsh conditions, grow rapidly, calve easily, show good maternal ability, yield lean meat, or have other advantages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microcattle have generally been ignored in the push towards larger animals, but they seem inherently suitable for traditional and small-farm husbandry. As rural people in developing countries improve their own productivity, as they become more aware of nutritional needs, and as they depend more upon cash economies, microcattle could become vital means for improving personal, dietary, and economic status.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Worldwide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cattle have been classified in many ways, but they are generally designated as humped or humpless types. However, clear distinctions among them are sometimes difficult or impossible to make because they have intermingled for thousands of years. Representative microcattle types are listed at the end of the chapter. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More than two-thirds of the world's 1.3 billion cattle are found in the developing world; one-third is in the tropics. As noted, a considerable number of these could be called "microcattle."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many strains of microcattle are threatened with extinction because of replacement or crossbreeding with larger types. This is in some respects shortsighted because promoting just a few breeds contributes to narrowing of the genetic base, and valuable traits may be lost when selection is done to conform to any preconceived standard, including large size.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microcattle are adapted to a wide variety of habitats. Many types thrive - even with little or no attention - in climates that are hot, humid, arid, or beset by diseases and parasites.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cattle are ruminants and digest fiber well, although they are selective foragers and prefer tender grasses and low-growing legumes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As with other tropical cattle, microbreeds generally reach physical and sexual maturity in 2 or 3 years. Many can breed year-round when conditions are favorable (gestation lasts about 9 months). Cows may remain fertile 10 years or more, and can live more than 20 years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cattle usually graze from as few as four hours to as many as eight hours a day. If feed is of poor quality, they must forage (and ruminate) longer to receive adequate nutrition. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microcattle are commonly docile and undemanding animals, and many small breeds are surprisingly responsive to humans.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like conventional breeds, microcattle produce the same well-known products: meat, milk, manure, hides, horn, blood, and bone. They are also used for traction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Small cattle often produce only modest amounts of milk and meat per animal. However, given higher stocking rates, a herd of microcattle is often able to outyield larger, genetically improved animals on a per hectare basis, especially under stressful conditions. When their ability to survive adversity and poor management is taken into account, they may often be far and away the most efficient cattle for traditional husbandry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Surprisingly, there is a place even for small draft animals. They tend to be active, thrifty (efficient), and more maneuverable in tight spaces, and so are adapted for use in the small fields, terraces, and paddies that are becoming increasingly common. The small hill cattle of Nepal, for instance, are valued because they can negotiate steep slopes and narrow terraces on Himalayan mountainsides. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microcattle are handled like their larger counterparts, but herding, tethering, fencing, and hobbling are generally easier.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cattle are familiar animals that are accepted in nearly all cultures; their meat, milk, manure, and leather are in demand almost everywhere. In many societies, beef is preferred over other meats, even by those who can rarely afford it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In most areas, organized breeding, production, and marketing associations are already in place. Microcattle can also integrate well into traditional forms of husbandry, whether in pastoral herds of hundreds or as solitary backyard milk cows.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under humid and hot conditions, microcattle probably suffer less than larger breeds because their greater ratio of skin area to body mass enhances their ability to shed heat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The number of cattle that can be kept on a given parcel of land may be increased, sometimes even doubled, with smaller animals. Microcattle can also be penned and fed cut-and-carry forage more easily than can larger cattle, and more of them can be maintained on the same amount of feed. This permits more continuous production and less financial hardship when an animal perishes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Small cattle may require less labor because they are generally easier to handle, herd, confine, and transport. They usually have few problems with calving, and as a rule require little or no assistance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some microcattle have unusual tolerances to disease. In Africa, for instance, there are breeds that tolerate or resist trypanosomiasis, a parasitic disease that makes large areas of that continent uninhabitable for most other cattle breeds. Others seem more tolerant of internal or external parasites, theileriosis (east coast fever), rinderpest, or other afflictions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microcattle often lack the prestige of larger breeds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When given quality forage and supplemental feeding, small unimproved cattle may not match the overall productivity of the large, highly developed breeds. Their greatest potential may prove to be for traditional husbandry and for grazing marginal areas where survival is more important than feed efficiency.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BONSAI BRAHMAN</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Mexico, researchers are deliberately creating microcattle. Since 1970, Juan Manuel Berruecos Villalobos, former director of the Veterinary Medicine school at the National Autonomous University, has directed this enterprise. He and his colleagues have miniaturized cows by selecting the smallest specimens out of a herd of normal-sized Brahman cattle and breeding them with one another. After five generations, adult females average 15-180 kg adult males 20-220 kg. A few of the smallest cows are now only 60 cm tall and 140 kg in weight. Merely one-fifth of normal weight, they are shorter than the turkeys that share the barnyard with them. Indeed, they even get lost in the grassy pastures so that the farmers cannot see them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This program seems to have yielded a productive animal that can be cheaply and easily maintained in a small space. Berruecos has demonstrated that the tiny cows can be stocked on one-third the area needed to support one normal-sized cow. He reports that they are giving remarkable amounts of milk: up to four lifers a day, compared with six lifers from their full-sized counterparts. On a feed-intake to weight-gain basis, the tiny cattle are no less efficient than their normal-sized counterparts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although 17 years have gone into the selection of what Berruecos calls his "bonsai cattle," the process is not yet finished. Future goals include testing embryo transplants to see if one normal-sized cow can support multiple "microfetuses" (possibly as many as eight). This would help to rapidly increase the numbers of the miniature form, which weigh merely 4-5 kg at birth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All in all, the Mexican researchers see miniaturization as a new option for governments and farmers increasingly squeezed by shrinking farm land and rising production costs. Small livestock they say, are a way to produce more food on less land faster. For example, a campesino with almost no land can have one or two bonsais, but could never maintain a standard-sized cow.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Their adaptability and robustness make microcattle worthy of preservation, study, and greater use, and they should be incorporated into many ongoing programs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Selective breeding, although infrequently attempted, can probably improve productivity significantly. Records of breed history should be established, and unusual or special characteristics noted and the information disseminated. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p24a.png"></center><br>
+ Original distribution of wild cattle and banteng (Based on Mason , 1984)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In areas where small, indigenous breeds are being replaced, representative populations should be maintained and studied to increase understanding of their adaptive diversity and to retain a genetic storehouse for the future.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">REPRESENTATIVE EXAMPLES OF MICROCATTLE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dwarf West African Shorthorn</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">West African coastal forests, and inland. Female 125 kg; male 150 kg. Adaptation to harsh, humid climates and good resistance to trypanosomiasis and other diseases allow these small animals to exist where other cattle die. They are perhaps the smallest cattle of all (often weighing less than 100 kg). In the areas of worst disease and highest rainfall, this hardy animal is often found thriving, but half wild. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muturu Nigeria. Female 160 kg; male 210 kg. This notable subtype is slightly larger. It is the most trypanotolerant of all cattle, showing no symptoms or loss of vitality. It is widely kept, mostly as a village scavenger and often as a pet, and yields a high percentage of meat. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">N'Dama</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">West Africa. 200-400 kg. These active, stocky animals utilize low-quality forage, produce good beef, and are used as light draft oxen. Milk production, though poor, improves with feeding level. N'Dama mature early and are exceptionally fertile, and they have already become important in breeding programs. They are resistant to trypanosomiasis, and can exist where temperatures average 30&Yacute; C with 1,500 mm annual rainfall. In the least hospitable areas, N'Damas ranging down to 200 kg are often the only cattle that can remain productive.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rodope</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Southeastern Europe. Female 200 kg; male 350 kg. A humpless multipurpose breed - draft, milk, and beef - that is exceptionally hardy. The milk is high in butterfat. Possibly adaptable to the subtropics. It is rapidly being lost to crossbreeding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zebu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zebus are among the most important tropical domestic animals. However, the dwarfs are not well known, although in many areas they are preferred, especially as draft animals. Zebus use less water, even though their sweat glands are larger and more numerous than those of most other cattle. All have a low basal metabolism and resist heat well. In general, they also have high resistance to ticks and other parasites.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Taiwan Black Taiwan. Female 250 kg; male 250 kg. Well adapted to poor tropical conditions, these work animals are also used for meat. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kedah-Kelantan Malaysia. Female 200 kg; male 250 kg. Hardy, well adapted cattle with exceptional fertility on a poor diet, both sexes are used as draft animals as well as sources of meat and cash. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sinhala (Dwarf Zebu) Sri Lanka. Female 200 kg; male 250 kg. An ancient type of zebu, preferred for its handiness in cultivating small paddies and terraced fields. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nuba Dwarf Sudan. 180-220 kg. These work animals are well proportioned but are not slaughtered for meat, and milk production is low. Although tolerant to trypanosomiasis, their numbers have dwindled because of crossbreeding. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Small Zebu Somalia. 160-230 kg. These small native cattle are used for beef, milk, and for work. They are well adapted to poor feed in a desolate environment. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Abyssinian Shorthorn Zebu (Showa) Central highlands of Ethiopia. Female 225 kg; male 305 kg. These widespread, small-humped cattle are very hardy. They produce beef and are generally milked, with surplus production about 2-4 kg daily. Resistant to many parasites, they also have a gentle disposition and make good work animals. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dwarf Zebu (Mongalla) Tanzania, Uganda, and Kenya. Female 150 kg; male 250 kg. A highly variable, long-entrenched, small, East-African zebu with some nonzebu blood. Pastoralists favor it because of its hardiness. Although slow-maturing, it is well-fleshed, can yield excellent beef, and some types are milked. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mashona Zimbabwe. Female 200 kg; male 250 kg. This hardy zebusanga type (see below) is widespread in drier areas and has a high resistance to disease and parasites. Since the 1940s, it has been bred for beef production and selected animals now weigh more than 500 kg. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mini-Brahman Mexico. 135 kg. Downsized from 450-kg Brazilian zebus through selective breeding by Mexican researchers, these gentle animals are reported to yield two-thirds as much milk (3-4 liters daily) as the parent stock. Because of much higher stocking rates on grass, production per hectare is reportedly greater than with full-sized animals (see sidebar, page 22). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Criollo</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Central and South America. Descendants of Spanish and Portuguese  cattle imported over 400 years ago, "criollo" cattle have adapted to a  wide range of harsh climates. Many varieties are small: mature females  often weigh 200-300 kg or less. They sometimes produce little beef or  milk under traditional conditions and management, but they are  extremely hardy and survive when other cattle perish. Through  importation and crossbreeding, many local types have been lost or are  threatened.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chinampo Baja California, Mexico. 200-350 kg. Extremely tolerant of  wild desert conditions, these docile criollo cattle exist largely on scrub  and cactus. They get most of their water from succulent plants, have a  low metabolic rate and body temperature, and are mostly active at night. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Florida Scrub Florida, USA. 225-300 kg. Genetically isolated for more  than 300 years, the Florida Scrub is very hardy in harsh, subtropical  conditions. It has good resistance to ticks and screwworm, and can  subsist on forage with a high roughage content. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sanga</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This type - an ancient cross between longhorns or shorthorns and  humped animals - is found throughout eastern and southern Africa. It  weighs from 150 to 500 kg or more. Some types have been selectively  bred or crossed with European cattle and are quite productive.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bavenda Transvaal, South Africa. 240-290 kg. This hardy and  disease tolerant tropical variety is small and prolific. It is generally used  for draft, barter, and beef. However, it has been crossbred with larger  animals so frequently that the smaller types are almost extinct; most  "Bavendas" now weigh more than 300 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ovambo' Northeastern Namibia. Female 160 kg; male 225 kg. A calm  and docile animal with a small hump, it is used by seasonal pastoralists  for beef and milk.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nilotic Sudan. 180-300 kg. These cattle of southern Sudan show great variation in size, partly due to environmental factors. They are generally resistant to local parasites and worms, have good potential for increased beef production, and their milk is very important locally.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chadian "Native" and Dwarf Black Cattle</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chad. Female 225 kg; male 275 kg. These two types are small, humped meat animals that graze the sparse savanna and are very drought resistant. Little scientific information exists about them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">"Arab Cattle"</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Middle East. Small types (female 225 kg; male 300 kg) are used for meat and some milk, especially in Lebanon. There are many local forms with variable appearance, but all have small humps. Well adapted to grazing sparse vegetation on rough land, they are becoming rare due to crossbreeding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hill Cattle</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nepal. Female 160 kg; male 200 kg. A widespread type often recrossed with Indian zebu animals, they are bred to be small. They are thrifty creatures that maintain themselves well on poor forage. Bulls make sure-footed draft animals on rough ground and slopes, and the cows are milked.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tibetan Dwarf</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tibet. Less than 250 kg. These humpless cattle are used as pack animals and can tolerate poor forage and high altitudes. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yellow Cattle</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Southwest and south China. Female 220 kg; male 380 kg. In the subtropics and tropics, small multipurpose types of Yellow Cattle withstand high temperature and humidity. They are used mainly for work and meat, and seem well adapted to poor feed, harsh conditions, and rugged terrain. The Chowpei (190-380 kg) is a hardy working breed of more temperate areas in Hubei Province.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cheju Hanwoo</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Korea. Female 230 kg; male 280 kg. A yellowish-brown Cheju Island native that has almost no calving difficulty, it is well adapted to poor grazing conditions in harsh environments and is docile and obedient.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Madura</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Indonesia. Female 220 kg; male 300 kg. An ancient cross between humped cattle and the banteng (see sidebar), these heat- and disease resistant hybrids also have good grazing and mothering ability, and are kept in the most extreme humid tropical environments. Breeding for fighting and racing has given them a poor disposition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dexter Cattle</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ireland and North America. 220-360 kg. This breed can be traced back to eighteenth-century Ireland and is believed to have been developed by peasant farmers living on rough land. It is exceptionally hardy and produces both milk and meat. In North America, it has become popular among city folk who acquire country property, as this microbreed is particularly well suited to their usually tiny farms. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BANTENG: THE CUTEST COW</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The banteng (Bos Javanicus) is a small Southeast Asian bovine with a promising future.* It is a different species from cattle. The two will interbreed, but the hybrid offspring are normally sterile.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although almost entirely neglected by the animal science community, the banteng is remarkable for an ability to thrive under hot, humid, and disease-ridden conditions where cattle often grow poorly. The sexes are easily distinguished: males are jet black, females are golden brown. Both have bright white socks and rumps as if they had been freshly whitewashed. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild banteng are found in remote areas of countries from Burma to Indonesia. But only Indonesia has used it as a farm animal so far. It has more than 1.5 million domesticated banteng - some 20 percent of the country's total "cattle" population. Indonesian farmers value the animal's agility, which allows them to cultivate Relds too narrow for cattle to turn the prow. In addition, gourmets consider banteng meat the tastiest of all. Indonesia appreciates the banteng so much that it has established a genetic sanctuary on the island of Bali - banning cattle in order to maintain the banteng's genetic purity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Outside Indonesia, only a few scientists have studied this animal, but it seems clear that it is particularly useful under tropical conditions. In heat and humidity, it thrives; even when cattle are starving, one rarely sees a skinny banteng. And demand for its meat is never ending.</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">2 Microgoats</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More than 90 percent of the world's nearly half billion goats (Capra hircus) are found in developing countries; many weigh less than 35 kg fully grown.` Such "microgoats" are noted for their high reproductive rates, rapid growth, early maturity, tasty meat, and rich milk' as well as for their robust constitution, ease of handling, and tolerance of climatic stress and poor feeds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To many people - especially where pigs and poultry are not common - meat and milk from microgoats are the primary animal proteins consumed during a lifetime. Perhaps the world's best foragers, goats eat practically anything made of cellulose, and are not dependent on grass. Because of their unselective feeding behavior, they are capable of living where the feeds - tree leaves, shrubs, and weeds - are too poor to support other types of livestock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Such microgoats deserve wider recognition, for they are often the poor person's only source of milk, meat, and cash income. They are cheap to acquire and easy to maintain, even by people with little property and scarce resources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Worldwide, especially in arid and semiarid climates.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goats generally have a long snout and an upright tail, by which they can be distinguished from most sheep. The mouth is unusual in having a mobile upper lip and a grasping tongue, which permits the animal to nibble even tiny leaves on spiny species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Common commercial goat breeds generally weigh between 60 and 100 kg, with some weighing more than 200 kg. Microgoats may weigh less than 15 kg. Representative examples are listed at the end of the chapter.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Worldwide, with half in Asia and one-third in Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The FAO projects that world numbers may nearly double by the turn of the century. Goats are thus not endangered, but in some areas select populations of feral goats are being deliberately eradicated, with the consequent loss of potentially valuable genes. Some small breeds are also threatened by excessive crossbreeding with larger types.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the most adaptable of all livestock, goats can persist in conditions from arid to humid, and from sea level to high altitude. They are especially well adapted to hot, semiarid climates and to rocky, barren terrain.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These ruminants can subsist on many feedstuffs that would otherwise be left to waste. Although selective browsers, they often prefer coarse leaves (including palm fronds) and shrubbery to palatable forage grass.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most microgoats mature quickly, and in the tropics they can generally breed year-round. Their reproductive potential has often been underestimated; kidding is rarely difficult, and many types produce twins and sometimes even triplets or quadruplets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In hot, dry areas, goats require less attention than other livestock, and smaller goats have the added advantage of better heat dissipation. Some microgoats may also show disease resistance. For example, tolerance to trypanosomiasis makes them an important livestock in many regions of Africa. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goats are generally gentle, but can be easily frightened. They may become stubborn and aggressive when threatened or thwarted, and can prove hard to confine.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If their feed smells of other animals - particularly of other goats -  they usually shun it unless nothing else is available. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microgoats mainly produce meat and form an important part of the diet in southern Asia, the Middle East, Africa, and Latin America, especially the Caribbean. Goat is sometimes a preferred meat, and there are few social or religious prohibitions against eating it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some microgoats are good milkers, and under stressful conditions they may keep producing when other livestock are dry. Goat milk is a valuable dietary supplement: it is nutritious, easily digestible, and usually commands premium prices. It makes excellent cheese and yogurt and can be used by people allergic to cow's milk.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microgoats produce some of the finest and most valuable fibers in the world. Angora and Cashmere goats often weigh less than 30 kg fully grown, for example.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goats produce a fine-textured, durable leather that finds extensive uses both locally and internationally. Horns, hooves, blood, and bone meal also have commercial value. Manure is another important product, and comes in fairly dry pellets that are easy to collect, store, and distribute.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goats perform important functions in land management. Seeds of many trees (Acacia and Prosopis, for example) are "scarified" by passing through the goats' digestive system, fostering germination and natural revegetation. With care, goats can also be used to clear land of weeds and brush.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goats are often allowed to roam and scavenge for their own food. They form strong territorial attachments and can be trained to stay within a designated area. However, they cannot be kept from investigating - and quite probably devouring - anything within that territory. They are persistent browsers, so it is essential to prevent overstocking as well as raids on crops.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Variety of diet is important, and goats show much individuality in feed preferences. They are often raised on crop residue and kitchen refuse.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goats can be run with other livestock without creating serious competition. The goats browse weedy shrubs, whereas the sheep and cattle graze more on grasses.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although perhaps the hardiest of all livestock, most breeds benefit when they are provided shelter from rain and high-noon sun. Abrupt chilling and poor ventilation can cause severe respiratory problems. They are also susceptible to various maladies, such as internal parasites, especially when confined. The highest mortality, however, is caused when very young kids are not supplied with adequate feed and clean, dry shelter.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In most developing countries goats are already prominent in rural life. Common almost everywhere in Africa, Asia, and Latin America, they are dependable multi-use animals. They are particularly important in providing ready cash, such as for school fees, taxes, marriages, or funerals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goats integrate well in mixed agriculture, for example, by consuming leafy wastes, clearing land, and contributing fertilizer. In many places they are raised almost exclusively by women and children. If confined, goats require only simple, inexpensive shelters or pens, which makes them especially important as subsistence animals. In many situations, they may be the most efficient and economic producers for smallholders.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These animals have a relatively fast rate of growth and early reproductive age, even under harsh conditions. They can graze rougher terrain than cattle and most sheep, can go for longer periods without water, and forage well in wooded areas where grass is lacking. They can derive most or all of their diet from roughage unusable by humans; high-energy feeds, such as protein supplements or carbohydrate supplements, are usually not needed even to fatten them for slaughter.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goats are generally healthy and are not affected by many of the parasites and diseases that ravage other livestock. Some resistance to mange, internal parasites, foot-and-mouth disease, and other livestock scourges has been reported.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In some places (notably, in industrialized nations) there is a strong prejudice against goats and goat meat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Smallness makes microgoats targets for predators and thieves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many small goats are poor milkers, especially under hardship conditions; however, even small amounts of milk can often fulfill a child's daily nutritional requirement or reinforce a nursing mother's diet.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goats are independent and may wander away if not watched, and they can be difficult to pen. They may also have an unpleasant odor when kept confined (males are particularly malodorous during rutting season). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goats are often disparaged for degrading land and destroying vegetation because they continue to survive on overutilized lands often laid waste by mismanagement of sheep or cattle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FRESH GENES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A rare wild animal with spectacular horns, the bezoar (Capra aegagrus) is the goat's wild ancestor. People domesticated it before 7000 B.C., probably in the mountains along the Iran/ Iraq border. Until recent times, it remained widely scattered across the vast region between Greece and Pakistan, but it now exists only in pockets and is threatened with extinction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This would be a tragedy because the bezoar is a resilient wild species that crosses readily with domestic goats, and it could pass on its genetic inheritance for heat, drought, and cold tolerance: disease resistance; and other survival qualities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p39a.png"></center><br>
+ Distribution of the bezoar. The arrow indicates the area where it was probably first domesticated, resulting in the goat as we know it (From Mason 1984)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fascinating science and valuable results probably await those willing to study this hardy, handsome creature and to explore the reharnessing of its genetic endowment. Today the bezoar is considered merely a trophy for hunters. The power of its genes to refresh - perhaps even revolutionize - the world's 500 million goats has been lost to sight. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The microgoat's potential has hardly been realized. More research on performance and husbandry is needed to preserve and restore small breeds. Selective breeding for prolificacy, viability, and rapid growth, as well as more selective on-site culling, could greatly improve both meat and milk yields and quality.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Management systems that exploit smallness, stabilize production, and preserve the environment should be introduced and publicized in appropriate goat-rearing areas. Careful assessments of indigenous management methods should be made, particularly emphasizing their desirable characteristics. Improving hygiene in the wet season and supplemental feeding in the dry season are also important, as are disease- and parasite-control measures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The undomesticated ibex and markhor could possibly be major contributors in the development of new, useful breeds for tropical and arid regions (see sidebar, page 42). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">REPRESENTATIVE BREEDS OF MICROGOATS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">West African Dwarf (Djallon)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">West and Central Africa. Female 20 kg; male 30 kg. Adapted to humid lowlands, this widespread goat is particularly valuable for meat and skin production. Generally, it is bred for meat, but milk is sometimes an important secondary product. Sexual maturity is very early (3-6 months), and quadruplets occasionally occur (most goat breeds normally produce only single births). Related types go by the names "Cameroon Dwarf," "Dirdi," and "Nigerian Dwarf."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nubian Dwarf</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">United States. 35-40 kg (often less). A stable miniature variety of the milking Nubian, this microgoat has been developed recently in the United States by crossing standard-sized Nubians with the West African Dwarf. It combines a good milk output with high levels of butterfat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">American Pygmy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">United States. 15-25 kg. Derived from the West African Dwarf, it is noted for its hardiness and good nature, good milk production, and adaptability to various climates. There are several varieties, some for milking, others for meat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sudanese Nubian</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Northern Sudan. 25-30 kg. Widespread milk goats of riverain and urban areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sudanese Dwarf</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Southern Sudan. 11-25 kg. A very hardy desert goat similar to the West African Dwarf, it averages 15 kg, but some mature individuals may weigh as little as 11 kg. Used for meat and hides, it produces little milk.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Small East African</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kenya, Uganda, Tanzania. 20-30 kg. A widely neglected meat and hide animal found over a wide range, it is fast growing (sexual maturity at four months) and extremely hardy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mauritian</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mauritius. 25-30 kg. A prolific, year-round breeder raised for meat production, it is often confined in simple shelters from birth to slaughter. Perhaps because of this isolation, mortality is less than 10 percent, even with little or no veterinary care.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Criollo</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Latin America. "Criollo" is a name given to several breeds of ancient Iberian blood with local adaptations to many unfavorable conditions. They are often small and hardy. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Creole Caribbean. Females 20 kg; males 25 kg. Robust meat goats of Spanish or West African origin that are kept throughout the Caribbean.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crioulo Brazil. 30-35 kg. A meat and skin goat derived from Portuguese ancestors, it is hardy, prolific, undemanding, and adapted to harsh environments. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chapper</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pakistan. Female 20 kg; male 24 kg. Originating in dry regions, this meat and milk goat is a nonseasonal breeder with outstanding potential.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Barbari</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pakistan, India. Females 20-25 kg; males 20-40 kg. A prolific, fastgrowing "urban" goat with high twinning and low mortality. Often kept inside houses, they adapt well to confinement and are important for both milk and meat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gaddi (White Himalaya)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hill districts of northern India. 25-30 kg. Kept for meat and their long, lustrous white hair, they are pure-breeding and healthy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Changthangi (Ladakh)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kashmir, India. Male 20 kg. A pashmina (cashmere) goat of India, it is adapted to a high altitude, high humidity climate with extremes of temperature.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Terai</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nepal. 8-12 kg. A very small, hardy animal of the southern lowlands, it kids year-round (sometimes twice), and often produces twins.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Southern Hill Goat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nepal. 12-16 kg. A small, mid-altitude goat resembling the Terai. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Black Bengal (Teddy, Bangladesh Dwarf)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Eastern India and Pakistan. Female 10 kg; male 14 kg. A widespread, humid-area, meat goat that is early maturing and very prolific. It kids twice a year, and produces 60 percent twins and 10 percent triplets. It produces a superior leather.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Katjang</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Southeast Asia, China, and Pacific Islands. In places, less than 20 kg. A widespread, highly variable, hardy goat adapted to humid conditions, it usually has twins or triplets. Used for meat and skins, with exceptional females being milked.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chinese Dwarf (Tibetan, Jining, Fuyang, or Chengdu Grey)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">China. 20-40 kg. Well adapted to the humid tropics, it normally twins and is a good meat producer.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Heuk Yumso</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Korea. Female 25 kg; male 35 kg. A prolific cold-climate goat with a year-round breeding season. The meat is highly prized, and often sells at a premium due to its supposed health-giving effects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hejazi</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Middle East. Female 20 kg; male 20 kg. A meat goat, usually black, for harsh desert conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sinai (Black Bedouin)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sinai, Egypt and Negev Desert, Israel. Female 20 kg; male 50 kg. Native to dry, hot deserts, this milk and meat goat matures at 5-8 months and has a twinning rate over 50 percent. A most important characteristic is its drought tolerance. The female, for instance, can drink only once a day - at a pinch, once every other day - without losing appetite or reducing milk flow. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILD RELATIVES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Several wild relatives will cross with the goat. Surprisingly, they have the same chromosome number (2n=60), and the offspring are frequently fertile. Although essentially unknown to agricultural science, these hybrids may offer a new gene pool for creating new farm animals and for improving the world's goats. They seem to combine the self-reliance of wild species with the usefulness of domestic ones. Artificial insemination and other modern techniques could make them easier to produce today than ever before.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ibex*</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A project in Israel has already produced a cross between the goat and the Nubian ibex (Capra ibex). The Sinai Desert goat, the breed that was used, ranks next to the camel in its ability to go without water - it often drinks only twice a week - but its meat has such a strong flavor that most people consider it dreadful. On the other hand, the ibex is compact and muscular and produces tender, mild meat that steak lovers find delicious. The product from crossbreeding the two is a creature seemingly able to endure extreme temperatures and drought, make use of poor pasture, and produce wonderful steaks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A herd of several hundred of these hybrids (dubbed 'ya-ez") has been created at Kibbutz Lahav in the northern Negev Desert area. Both sexes are fertile, and they can be bred with each other or with either parent. The meat is already in demand on the menus of elegant Tel Aviv hotels. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Markhor**</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In Pakistan's northern uplands, it is not uncommon to find hybrids between domestic goats and the mountain goat known as "markhor" (Capra falconeri). Each year in Chitral and Gilgit, they can be found in the goat markets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Markhors inhabit high elevations in rugged mountains and thrive on diets so meager as to be useless to goats. The hybrids are produced when markhor males - perhaps ousted by more dominant males - come in contact with feral domestic goats. However, some farmers raise young markhor and goats together (to overcome mutual resistance) and produce their own hybrids,</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For a single hybrid animal local goatherds pay up to 5,000 rupees, a princely sum in this impoverished region. Traditionally, villagers have kept them as stud animals. They appreciate the animal's genetic endowment. Markhors tolerate extremes of cold and snow, are nimble and skilled at escaping predators, and survive on scanty fodder, Moreover, they have a high reproduction potential because they generally produce twins. As a result, they also tend to give more milk and it is rich in nutritive value. Instead of long body hairs, markhors possess insulating underfur - a soft and valuable raw material for the famous Kashmiri shawls.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Apparently, the hybrids can possess many of these qualities together with a calm disposition. Thus they could be useful in themselves and as conduits for passing such traits on to goats. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">3 Microsheep</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Among the hundreds of breeds of sheep (Ovis aries) in the world, those weighing less than 35 kg when mature have been largely ignored. Although these are common, the impression lingers that they are too small to be useful. Yet this virtually untapped gene pool is esnecially well adapted to traditional Third World animal husbandry. Given attention, these "microsheep" could boost meat, milk, skin, wool, and pelt production in many villages and small farms of Africa, Asia, and Latin America.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many microsheep thrive in environments that tax the ability of larger breeds to survive. They are adapted to poor feeds and can be grazed in uncultivated wastelands unsuited to any other livestock except goats or camels. Because of their size, microsheep can fatten in areas where forage is so scattered and sparse that larger animals cannot cover enough ground to fill their bellies each day. In addition, their foraging complements that of other livestock. For example, sheep can graze rough grasses and weeds that cattle find unpalatable. Some survive even the stress of extreme aridity and for this reason are the predominant livestock in North Africa and the Middle East.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many small breeds can be disease resistant. Some, for example, are widespread in the zones of Africa where trypanosomiasis is prevalent. They are generally less adversely affected by foot-and-mouth disease than are cattle, and some small native sheep seem to have fewer problems with insects and parasites than do most other livestock, including temperate-area sheep.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Giving more attention to the management and improvement of microsheep could pay back abundantly in the form of food, income, and improved land utilization in many parts of the developing world. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Worldwide, but notably in drier regions of the tropics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">An average weight for temperate sheep breeds is about 70 kg,' but the smallest microsheep weigh less than 20 kg fully grown. Many tropical microsheep are "hairless," and have little or no wool. These are often difficult to distinguish from goats, but (like all sheep) they generally have blunter snouts, more fat, and hanging tails. Some have greatly enlarged rumps or tails that store fat. Unlike goats, sheep have no odor-producing glands.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some representative microsheep are described at the end of this chapter.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More than one billion sheep occur worldwide, and they occupy every climatic zone in which people live. At least half are in developing countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although more than 1,000 breeds are recognized, only a handful dominate the world's sheep industries. Lesser-known breeds are rapidly becoming extinct (especially in developed countries, although scattered efforts are being made to preserve them). Elsewhere, genetic resources have not been properly evaluated, and potentially valuable stock is being lost before it is even understood.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sheep are among the most adaptable animals. Various types are kept in areas of extreme heat, cold, altitude, aridity, humidity, and rainfall. They are especially widespread in hot, dry climates, but some breeds also thrive in humid areas. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sheep make efficient use of a wide variety of fodder: tree leaves, fortes, grasses, crop residues, and agricultural by-products, for instance. They often survive privation by calling on their reserves of body fat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the tropics, sheep reach sexual maturity in about a year. Many breeds lamb year-round, which allows for a continuous production of premium meat. Gestation takes about five months, and lambing is usually timed to occur when feed is most abundant and nutritious. Microsheep often bear two or more young and, under good management, may produce lambs annually for more than five years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These shy animals flock together and, in general, are managed with little effort. They are easily panicked, however, and rams can become aggressive during rutting or when threatened.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE LITTLE SHEEP THAT COULD</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dozens of the world's neglected breeds of tiny sheep should be preserved from extinction, for many will undoubtedely prove to have outstanding qualities. Current efforts to save the Navajo sheep in the United States exemplify what can be achieved</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Navajo is a microsheep, and is perhaps the oldest breed of sheep in the United States. It may have been introduced to North America in 1540 by the Spanish explorer Francisco Vazquez de Coronado, who was seeking the mythical Seven Golden Cities of Cibola in the region that is now Arizona and New Mexico. Smaller than many dogs, a full-grown Navajo sheep may weigh only 30 kg, but it became a big part of the culture of the Southwest. Although the Navajos and other local Indians had never seen sheep before the 1500s, they soon became shepherds and weavers, and their rugs made from the unique wool of this wiry little animal remain famous even today.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Navajo sheep have white or brown wool hanging in ringlets around their bodies. The fleece is a double coat: long, coarse guard hairs on the outside and short wool on the inside. It yields warm, waterproof, and long-lasting products. Many of the sheep have four horns because the Indians believed that this trait was sacred, and they favored four-horned rams for breeding purposes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The number of Navajo sheep was reduced sharply between 1950 and 1950 because of severe overgrazing and replacement by improved wool breeds. In recent times there has been so little commercial and scientific interest in this microsheep that by the 1970s only a handful of purebred specimens survived. Since the late 1970s, however, Lyle McNeal, a Utah State University professor, has been working to save it from extinction. By 1988 he had a burgeoning flock at the university and was learning that this supposedly obsolete dwarf is amazingly useful.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The breed originated in the arid south of Spain (where it is called the "churro"), and it thrives in the hot, dry climate. Unlike normal breeds, it can exist in the desert without supplementary food and with little water. As McNeal has pointed out, any sheep that can survive and raise a lamb in the aridity and searing heat of the American Southwest has to be superior. He has found that the ewes have a strong maternal instinct, which is vital for protecting lambs against the coyotes that are common in the region. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thanks to the efforts of McNeal and his colleagues, Indians are beginning to use Navajo sheep again; by 1988 there were more than 400 on the Navajo reservation, with their wool fetching premium prices. This tough little sheep could prove valuable not only for American Indians but for poor people in many other dry regions as well. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Microsheep are mainly kept for meat production, but - especially in arid regions - for milk as well. Their meat is usually lean with little "muttony" taste.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wool or hair is taken from many breeds, although the yield is often small. Skins from hair sheep' thinner than cowhide, are widely used and are in international demand. In some places, manure is considered an important product. In Nepal, thousands of small sheep are used as pack animals, especially to carry salt into mountain valleys.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Most sheep are maintained in free-ranging flocks. Many are grazed (often tethered) over a small area during the day and confined in a "fold" at night. Others are penned or kept as village scavengers. These are usually fed supplements of household scraps.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sheep form an integral part of a mixed farming economy; for example, they may graze pastures during the wet season, and survive on crop residues and field weeds during the dry season. They have excellent foraging capabilities and are often kept alongside goats. This broadens the variety of forages utilized and often increases total production from a single piece of land, for sheep and goats have complementary feeding habits and male goats help protect the sheep from some predators.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In spite of the heavy toll that predators (such as feral dogs) can take on lambs and ewes, the largest proportion of sheep in the tropics are lost through lack of basic care. Modest supplemental feeding of lambs and inexpensive preventive medicines can do much to lower mortality and boost production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sheep are multipurpose animals, and almost everywhere they produce several products. The rich milk is often preferred to that of cows or goats, especially for making cheese and yogurt.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lambs form an important part of the household economy for much of the rural world, and only rarely is social or religious stigma attached to keeping or eating them. Indeed, sheep are the traditional feast animals of several religions, and in some places sheep meat is preferred to beef and sells at a premium.</P>
+<P ALIGN="JUSTIFY">By and large, all sheep products can be processed, utilized, or marketed by the producer. In addition, sheep marketing and transportation systems exist in most countries, at least to some degree.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sheep are efficient producers and can provide a quick turnover for food and cash. On the brush and coarse grasses of marginal lands, they may be more productive than cattle, and on grass they may outproduce goats. As long as they are not overstocked, sheep do not degrade vegetation; unless starving they will not debark trees. Small breeds cause little erosion, even on steep slopes, heavily traveled paths, or near water holes.2 In South Asia, they have been continuously stocked on the same ground for thousands of years without causing apparent harm.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because sheep have a natural tendency to accumulate fat, they "finish" well on grazing and usually do not require a high-energy finishing diet.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite their general healthiness, sheep are affected by many internal parasites and diseases, a few of which are communicable to man. They are especially susceptible to infectious conjunctivitis (pinkeye).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Predators and thieves can be greater threats than sickness. Labor inputs can be high because of the almost continual protection sheep need.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some mutton has a strong taste that many find unappealing. However, the taste is carried mainly by the fat, and the generally lean microsheep are often commended for their fine-textured, sweet meat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The numerous breeds of small sheep should be investigated. Assessments should be made for the animals' ability to thrive under adverse conditions and for resistance to particular diseases and parasites.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As noted, even minimal extension services and veterinary support for sheep could greatly decrease mortality, especially among lambs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Improving microbreeds without increasing their size is one of the most interesting challenges facing sheep scientists today. While efforts should be made to conserve and select within types, research should also be conducted on hybrid vigor. Efforts to improve the pelt and fleece of microsheep should also be encouraged.</P>
+<P ALIGN="JUSTIFY">More studies on the interactions between sheep and cropping systems are needed. Sheep (and the manure they produce) could become important components of forestry (see sidebar), crop rotation, alley cropping, and other forms of sustainable agriculture. For instance, sheep are especially effective for weed control in plantation crops such as oil palm and rubber as well as in forests.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SMALL SHEEP IN THE FOREST</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Even in countries with long traditions of raising large sheep, there are opportunities for using small, agile, hardy breeds. The following is an example.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Seeking safer methods for stopping brush from smothering newly planted trees, U.S. government foresters have turned from chemical defoliants to flocks of sheep. Court decisions in 1983 and 1984 barred the use of herbicides along Oregon's Pacific Coast. Various alternatives were tried, and the animals proved the most successful. Sheep are now the favored method for controlling unwanted vegetation. Indeed, they have changed the foresters' whore approach to managing reforestation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Formerly, the U.S. Forest Service allowed the brush to grow on logged-over sites and then sprayed it down before planting tree seedlings. Now it plants grass to suppress brush and reduce erosion. The sites are later fertilized, tree seedlings are planted, and within a year sheep are brought in to graze. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Today, in the district around Alsea, Oregon sheep nimbly skirt old stumps to graze on the lush vegetation. Three times each summer since 1984, about 2,000 sheep have been guided across the replanted areas by a herder and a range conservationist. The sheep eat both the grass and the new buds on brush, but they leave most fir-tree seedlings untouched. The key, according to Rick Breckle, a forester, is to have enough sheep to graze an area evenly and to keep them moving so they don't resort to nibbling the young trees.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Previously, chemical brush treatments had annually cost $135-$353 per hectare. Now, sowing grass and grazing sheep costs about $300 per hectare. And there is a product to sell: the adult sheep don't fatten well, but the lambs bring a useful income at the end of the summer. What is more, Breckle reports that the trees seem to be growing faster - probably because of the manurings they receive.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This method seems likely to be effective elsewhere - at least with trees that are unpalatable or too tall for their growing points to be nibbled. Malaysia, for instance, doubled its sheep population between 1986 and 1989, in part because it has begun raising sheep between the trees in rubber plantations. With the use of agroforestry increasing worldwide, small sheep could find a whole new application.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">REPRESENTATIVE EXAMPLES OF MICROSHEEP</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">West African Dwarf</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Senegal to Nigeria, and south to Angola. Female 25 kg; male 35 kg. Well adapted to warm, humid conditions. Prolific, and good disease resistance. Major meat producer in West Africa. Fast growing: by six months of age they approach adult weight.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Landim (Small East African)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">East and Central Africa. 23-40 kg. Prolific, adaptable, long fat-tailed type. Large litter size for a sheep. In one recent test, ewes averaged more than 1.4 lambs.3 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Berber</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Atlas Mountains. 25-41 kg. Needing little feed and remaining constantly outdoors, these extremely hardy sheep are exploited for meat and their coarse, hairy wool. They fatten easily when well fed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Arab</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">North Africa. 40-50 kg. This thin-tailed sheep is exceptionally robust, and is resistant to extremes of temperature, drought, and poor nutrition. Primarily a meat producer, its wool is used for coarse cloths and carpets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Southern Sudan Dwarf</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the many small breeds of eastern and southern Africa, its weight ranges from 15 to 25 kg, but it may weigh as little as 11 kg. Yielding a fine, short fleece, this hardy, frugal sheep is often run with cattle to maximize grazing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hejazi</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Deserts of Arabia. 32 kg. A popular and ancient fat-tailed meat producer that is highly acclimatized to drought and privation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zel (Iranian Thin-Tailed)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Caspian region of northern Iran. Female 30-32 kg. Well adapted to subtropical regions, they produce coarse wool, milk, and excellent meat that lacks the "mutton taste" and odor of some sheep meats.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Greek Zackel</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mountain and island types. Female 30 kg; male 40 kg. These common sheep are active, hardy, and resistant to extremes of climate and disease. Primarily a milking sheep, their wool is used locally and lambs are slaughtered for special occasions. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sitia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crete. Female 25 kg; male 30 kg. Another of the hardy, screwhorned "zackel" sheep common to the Balkans, they are adapted to poor pasturage and extensive herding. Quick maturing and highly fertile, they can be exploited for milk as well as for meat and coarse wool.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Common Albanian</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Female 25 kg; male 35 kg. Similar to the Greek Zackel, they are used as triple-purpose animals: meat, milk, and wool. They survive in low, marshy areas where parasites are common.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zeta Yellow</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yugoslavia. Female 25 kg; male 35 kg. A small, hardy sheep used for milk and some meat, its primary product is wool. Often unshorn for several years, the long fibers are woven into expensive carpets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pag</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yugoslavia. Female 20-30 kg; male 25-35 kg. These wool, milk, and meat sheep are frugal and well adapted to scant vegetation and rocky terrain. Although they have a low birth rate and carcass yield, their milk and wool are commercially exploitable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Roccia (Steinschaf)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Northern Italy, Austria. Female 30 kg; Male 30-35 kg. These "stone sheep" resemble a goat in their ability to exploit the poor pastures of high, steep, rocky mountains. Although not highly productive, they are hardy and frugal and commonly produce twins.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Corsican</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Corsica (France). 25-30 kg. A hardy native breed that is well adapted to rather sparse feed conditions. Coarse wool, both white and black, is well suited for hand processing. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Entre Douro e Minho</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Portugal. Female 15-18 kg; Male 20-25 kg. These independent sheep yield a good wool in mountainous terrain that would otherwise be nonproductive.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Churra do Campo</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Portugal. Female 20 kg; male 30 kg. A coarse-woofed sheep extensively kept in Portugal's dry interior for milk and wool. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Galician</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Spain. Female 18 kg; male 25 kg. A milking breed that survives on  poor pasture, it also produces a marketable wool.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Soay</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Scotland. Female 25 kg; male 30 kg. Adapted to wide temperature  variations. Possibly the most primitive domesticated sheep of Europe,  probably unchanged from Viking times. Immune to foot rot. A wool  sheep with short brown fleece that is shed annually.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">North Ronaldsay (Orkney)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Northern Scotland. 27-32 kg. Surviving year-round on seaweed,  this rare breed is adapted to high salt intake and the associated digestive  problems. Yield 1-2 kg medium-coarse wool.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Criollo</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Latin America. Derived from ''native'' Spanish Churro and Merino  sheep. Many are small and very hardy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Navajo-Churro Southwestern United States. Female 45 kg; male 70  kg. Maternal, and very resistant to internal parasites and hoof rot.  Although the Navajo subsists and reproduces on little feed and scarce  water in desert regions, it was widely replaced by improved breeds  earlier in this century. Because of its hardiness, however, and the use of  its wool in traditional weaving, its numbers are rebounding (see sidebar,  page 50). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Florida Native Southeastern United States. Females 35-45 kg;  males 45-6O kg. This long-isolated and highly variable sheep is  adapted to harsh subtropical climates and is known for its ability to  forage. A medium-wool breed, it is very resistant to intestinal parasites.  Verging on extinction due to neglect and uncontrolled crossbreeding. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Virgin Islands White Hair (St. Croix)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Caribbean. Female 35-45 kg; male 45-55 kg. Hair sheep with  some wool in young animals. Well adapted to warm humid conditions, it has fairly good disease and parasite resistance and produces good meat. Prolific, it breeds most of the year and commonly has twins.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Magra (Chokhla)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Northwest India, Pakistan.4 20-25 kg. Adapted to hot, dry areas, the extremely white and shiny fleece is valued for carpet wool. Slowmaturing and low fertility (lambing at 45 percent) plus extensive crossbreeding have led to serious declines in population.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Marwari</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Northwest India. 25-30 kg. A widespread, white-fleeced sheep that has a high resistance to disease and worms, good fertility, and low mortality. They do well in large flocks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mandya (Bandur)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Southwest India. Female 25 kg; male 35 kg. An outstanding meat breed with good mutton quality, it adapts well to mixed farming and has unusually low lamb mortality.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hu (Huyang, Lake Sheep)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">China. Female 35 kg; male 45 kg. These fat-tailed sheep have a six month lambing interval and are very prolific. They are used under intensive management to produce meat, wool, and a valuable lambskin.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Javanese Thin-Tail</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Indonesia. 25-40 kg. Widely held as a "bank account," these meat, manure, and skin sheep are well known for being prolific. Although single lambs are not uncommon, litters of six have also been recorded. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILD AND WOOLLY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Considering that dozens of countries depend on the productivity of more than a billion domesticated sheep, it is remarkable that their wild ancestor is accorded no attention. This fast-declining animal is now little more than a trophy for hunters, a fact that should be of vital intemational concern.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sheep were domesticated in the Middle East and Central Asia in the Stone Age era between 8,000 and 11,000 years ago.* Their wild ancestor was almost certainly the mouflon (Outs orientalis). However, domestication may have occurred in more than one place, and two other wild creatures, the urial (Outs vignei) and the argali (Outs ammon), also possibly provided genes to some sheep breeds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mouflon, urial, and argali still exist in the mountains of Central Asia, and a European subspecies of mouflon is also found in the Mediterranean, but only on Corsica, Cyprus, and Sardinia.** Because they live in remote, rugged, upland areas, these wild sheep are usually undisturbed, but the numbers are decreasing everywhere.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This may be a serious loss because these animals could be extremely valuable. They are capable of crossing with domestic sheep, and the offspring are viable and fully fertile.*** For developing new meat-producing breeds, their potential seems almost limitless.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During the thousands of years that sheep have been protected by humans, their wild ancestors have continued to face predators, parasites, disease, extreme cold and seasonal starvation. Their genetic endowment, forged and tempered in unforgiving harshness, could be a benefit for all future sheep generations. These animals appear to resist various diseases. Their meat is reported to be of excellent quality, notably lacking the strong mutton flavor that many people find objectionable. They have relatively short, thin tails - a feature that might eliminate the need for docking (tail removal) in the domestic flock. Some (for instance, the Asian mouflon and the urial) have rates of effective reproduction up to 1.6 lambs per ewe, more than twice the average of most domestic types, especially under the conditions where these wild creatures live.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">That mouflon and other wild sheep could have practical utility is suggested by research at Utah State University. Scientists there have mated mouflon with farm sheep to create sheep better able to defend themselves against coyotes and other natural dangers. Half-wild, half-tame sheep hybrids have existed on a ranch in southern Utah for the past decade. Also, in Cyprus similar mouflon x sheep hybrids have shown considerable promise.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the very least, this wiry little mountain sheep could be a model for educating students and the public. It is a living reminder of the fantastic changes that can be induced in animals by selection for various traits. Also, it is a "map" to the history of sheep domestication. Studies of mouflon genes, blood immunology, morphology, physiology, horn structure, skeleton, fleece, temperament, and a host of other features would help unravel the ancestry. These studies and various biochemical analyses would be a fascinating contribution to agriculture, science, history, and the public perception of the origins of our natural resources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Genes from wild sheep are not likely to quickly benefit wool production. Lack of fleece is one reason why these creatures have been neglected but throughout most of Asia and in North Africa, sheep are bred primarily for meat and milk, and there is a growing worldwide interest in the use of hair sheep. All of this brings new possibilities for the use of this old resource.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">4 Micropigs</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g005a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most breeds of swine (Sus scrofa) are too large to be considered microlivestock, but there are some whose mature weight is less than 70 kg. These micropigs are particularly common in West Africa, South Asia, the East Indies, Latin America, and oceanic islands around the world. At least one, the Mexican Cuino, may weigh a mere 12 kg full-grown.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many miniature swine have been developed for use in medical research, but their agricultural potential has been largely ignored. This is unfortunate, for micropigs of all types - native, feral, and laboratory - deserve investigation. Swine provide more meat worldwide than any other animal, and micropigs are potentially important sources of food and income for poor people in many parts of the developing world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Smallness makes for nimble and self-sufficient pigs, in contrast to large, lethargic breeds. Small breeds are easier to manage and cheaper to maintain; the threat of injury from angry or frightened animals is lessened; and the sows are less likely to crush newborn piglets, often a major cause of mortality in large breeds. Some micropigs - particularly those from hot regions or wild populations - also have a higher resistance to heat, thirst, starvation, and some diseases.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigs adapt to a wide variety of management conditions, from scavenging to total confinement; some are even kept indoors.2 They gain weight quickly, mature rapidly, and help complement grazing livestock because they relish many otherwise unused wastes from kitchens, farms, and food industries, as well as other foods such as small roots, leafy trash, or bitter fruits that are not consumed by humans or ruminants. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For these reasons, micropigs could become useful household and village livestock in the developing world, and they deserve greater attention than they now receive. Although their growth may not be as rapid as that of improved breeds raised under intensive commercial production, with modest care and minimum investment, backyard micropigs can produce sizable yields of meat and other products, as well as improved income for rural and even urban populations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Worldwide, especially in warm, humid areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like full-sized breeds, micropigs are stout-bodied, short-legged animals with small tails and flexible snouts ending in flat discs. Examples of some micropigs are listed at the end of the chapter.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Domestic pigs are found all over the world, but their concentrations vary greatly. Africa has the fewest per capita, but in recent years they have gained increasing favor in the sub-Saharan regions. In Latin America, pigs have long been a major component of backyard agriculture. In the Middle East, an early center of domestication, pigs are not widely kept today because of religious dietary restrictions. In the Ear East, they are the major meat source, and China has more pigs than any other country. And in the Pacific region, pigs and chickens are often the only meat available.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigs are becoming more popular: their worldwide numbers increased by about 20 percent in the 1970s. However, in most countries commercial pig production has focused on a mere handful of breeds, and much genetic diversity is unstudied or even threatened with extinction. Some microbreeds have already been lost, and others are dwindling in numbers.3 Many European breeds have been completely lost. The Cuino and some other Latin American criollo types are threatened, as are most of Africa's traditional breeds. China, however, has made notable efforts to preserve its native types. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although, as previously noted, pigs are found all over the world, they are in general adapted to warm, humid climates where many other livestock species are more susceptible to diseases and environmental stresses. They are also raised at high altitudes, such as in the Andes and Tibet. Although there are few climatic limitations to pig production, only about 20 percent of the world's pigs are currently kept in the tropics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigs are omnivores, willing and able to eat almost anything.4 Unlike most other livestock, they eat their fill and sleep as the food digests, allowing humans to establish a convenient eating and sleeping schedule.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigs are prolific; a few Chinese breeds routinely have litters of 20 or more. Micropigs are no exception; litters of 6-10 are common. Piglets gain weight rapidly and can be weaned after a few weeks. Sexual maturity is sometimes attained as early as 4-6 months, depending on breed and environment. Pigs are usually slaughtered at 67 months of age, allowing them to be produced on an annual cycle. They can live 10-20 years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of their smaller size, micropigs have a relatively greater skin-to-weight ratio than today's commercial breeds, and therefore they probably shed heat more effectively. Certainly they seem to perform better in tropical heat and humidity, which normally keep the heavier types from reaching their maximum productivity. Studies have suggested that an optimal size for some tropical environments - because of metabolic and feed efficiency - may be less than 65 kg.5</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigs are social animals; they enjoy companionship and ferociously defend their young and sometimes even the humans who care for them. They are employed as guard animals in some areas and have been used extensively in behavioral research.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Contrary to common belief, pigs are clean and tidy if provided adequate space. Larger breeds, however, wallow in mud to stay cool in hot weather and require a wallow or shade (except for some Latin American types, which seem less susceptible to heat). Some lightcolored pigs sunburn easily.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigs will dig up earth with their mobile snouts; some breeds do it constantly. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fresh pork is the major pig product in tropical areas. It usually fetches premium prices, and in many places (such as the Pacific Islands and China) it is the most important red meat available to rural people. Nutritious and tasty, it is one of the easiest meats to preserve, needing only salt or melted fat. Processed products such as bacon and sausages can be important for both home consumption and cash sales.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pig fat (lard) is a good source of food energy, and can substitute for cooking fats and oils. It is easily melted and clarified, is widely used to make soap, and is a valuable commercial product.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pig skin, once degreased, is easily tanned into leathers that are popular for garments, shoes, and other products demanding soft, light, and flexible leathers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pig manure is a good fertilizer. Because the animals are often kept in confinement, it can be easily collected.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In many places, pigs are kept as free-roaming scavengers. They can be trained (by coaxing with feed, salt, or affection) to keep close to home, thereby helping to minimize destructive scavenging.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Herding is a higher level of management that requires more effort, but it allows pigs to be integrated into other types of agriculture while utilizing feeds that otherwise go to waste.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because their exercise needs are minimal and dominance is quickly established within litters, pigs are the easiest hoofed livestock to raise in small enclosures (sties). However, fencing must be secure, and if sties are small, the animals must be moved frequently to prevent diseases and parasites from building up.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigs are well-known, often traditional, animals in many areas, and people usually do not have to be taught how to manage and use them. Efficient scavengers, they can live, grow, and reproduce with a minimum of investment or specialized care. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigs are highly efficient converters of feed to meat. They can provide the greatest return for the least investment of any hoofed livestock because of their fecundity, low management costs, broad food preferences, and rapid growth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigs normally accumulate fat during adolescent growth (making ''finishing" feeds less necessary). Some micropigs (especially those from feral ancestors) have the ability to quickly mobilize and store these body-fat reserves; in times of extreme scarcity, it aids their survival.6</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigs work well in multiple-cropping schemes. They are often used to help clear small plots by uprooting weeds, shrubs, and even small trees. In Southeast Asia, they are frequently raised in conjunction with aquaculture, their manure providing food for the fish.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If improperly managed or maintained in filthy conditions, pigs may quickly succumb to disease and parasite epidemics. Most diseases are communicated only among pigs, but some can be transmitted to humans. For this reason, pork should always be fully cooked.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some cultures never eat pork. Others do, but nonetheless accord pigs and their keepers low status.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Young pigs are vulnerable to many predators.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A major survey of small pig breeds is needed. They have the potential to be valuable producers in their own right, as well as to improve other pig breeds. For instance, they represent a little-known reservoir of disease resistance and climatic adaptation. Governments, research stations, universities, and individuals should make special efforts to preserve types that have outstanding or unusual qualities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When it is necessary to eradicate feral pig populations (as is common on Pacific islands), representative stocks should be preserved. These rugged animals have been genetically isolated for decades or even centuries and are likely to carry valuable traits for survival under adversity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Large breeds may be promising candidates for genetic "downsizing," which has already produced the many types of miniature pigs that are used in medical research. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE LITTLEST PIG</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although this chapter highlights the world's smallest breeds, there exists a pig that is even smaller. It is, however, an entirely different species and it is on the brink of extinction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The pigmy hog (Sus salvanius) is a shy and retiring wild creature of northeastern India. It is merely 60 cm long with a shoulder height of 25 cm, and weighs less than 10 kg. It was once found widely along the southern foothills of the Himalayas. Today, however, it apparently occurs in only one area, the Manas National Park in Assam. Despite this protection and the fact that it is listed among the 12 most endangered species on earth, it still falls victim to hunters and to habitat destruction - especially illegal grass fires.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If saved from extinction, this minute species - barely reaching a person's calf - might become useful throughout the world. Its chromosome number is the same as that of the common pig and its physiological processes are probably also similar. Therefore, were its numbers to be built up, it might become a valued and well-known resource for laboratories and small farms. Its daily food intake and its space requirements are only a fraction of a normal pig's. It probably has exceptional tolerance to heat, humidity, and disease.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This is not a domesticated species, and there is therefore much to learn before its usefulness can be clearly seen. Indeed, whether it can be reared in captivity is uncertain. Some attempts have ended in disaster, but this seems to have been the result of mismanagement.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Before there is any possibility of developing it, however, the pigmy hog must be preserved from ultimate loss. The last specimen could go into a villager's pot at any time now. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g006a.png"></center><br>
+ Adult male of the common pig (wild boar) and pigmy hog draw to same scale. (W.L.R. OLIVER)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">REPRESENTATIVE EXAMPLES OF MICROPIGS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">West African Dwarf (Nigerian Black, Ashanti)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">West Africa. Mature weights of 25-45 kg are reported. In the humid lowland forests of West Africa this breed has long been kept by villagers, often as a scavenger. Indigenous to the hot, humid tsetse zones of West Africa, it seems resistant to trypanosomiasis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chinese Dwarfs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">China (and Southeast Asian countries such as Vietnam) has long had small pigs - often characterized by numerous teats and large litters - associated with traditional intensive agriculture as well as scavenging conditions. Some Chinese pigs weighing less than 70 kg are adapted to tropical and subtropical conditions, but the smallest (20-35 kg) live in the cold climates and high altitudes of Gansu, Sichuan, and Tibet. Small black Chinese pigs were crossed with European types in the early 1800s and produced the foundation stock of many modern Western breeds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Criollo</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are a number of "native" breeds throughout Latin America commonly known as "criollo." Many are quite small. Although, apparently, they are slow to mature and bear small litters, they adapt well to environmental extremes and are widely kept by rural inhabitants for food and income. Criollos are little studied and are being replaced by imported breeds before their possibly outstanding qualities can be quantified.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cuino This micropig from the highlands of central Mexico may be descended from small Chinese types and is the smallest domestic pig, weighing as little as 10-12 kg fully grown. Hardy and an efficient scavenger, it can grow quickly when feed - especially corn - is abundant. A century ago the cuing was a widespread household animal and was used for a time for experimental work in central Mexico. It is now little known and could be threatened with extinction. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Black Hairless (felon, Tubasqueno, Birish) These small pigs of central and northern South America survive in hot, humid, adverse climates. They are adapted to bulkier feeds than most pigs and can thrive on fruit wastes. Many local types exist. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nilo (Macao, Tatu, Canastrinha) This small, widespread, black, hairless pig of Brazil is often kept inside the house. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yucatan Miniature Swine A subtype of the black hairless from Mexico's hot, arid Yucatan Peninsula, it was imported into the United States in 1960. It has been downsized for laboratory use in the United States and is known as the Yucatan Micropig (registered). Weight at sexual maturity has been lowered through selective breeding from 75 kg to, currently, between 30 and 50 kg, with an ultimate goal of 20-25 kg. There is no evidence of "dwarfism," stunting, or loss of reproductive performance, and it appears to hold notable promise as microlivestock for developing countries. The parent stock, used for meat and lard production in Yucatan, is renowned for gentleness, intelligence, resistance to disease, and relative lack of odor. Exceptional docility, even in older boars and sows with litters, makes them easy to handle without the need for specialized housing or equipment.7 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other Laboratory Breeds</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other miniature laboratory pigs have potential for tropical use. These include the Goettingen, Hanford, Kangaroo Island, Ohmini, Pitman-Moore, and Sinclair (Hormel). In general they weigh 30-50 kg when ready for slaughter and mature at less than 70 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ossabaw</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">United States. 20-30 kg. Feral on Ossabaw Island, South Carolina, for more than 300 years, this pig is well adapted to environmental extremes. Unlike most domestic animals, it can maintain itself in coastal salt marshes. It has perhaps the highest percentage of fat of any pig. The piglets are very precocious, self-reliant, and robust.8</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kunekune (Pua'a, Poaka)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">New Zealand. Female 40 kg; male 50 kg. Perhaps of Chinese origin, these black-and-white spotted pigs are docile, slow, and easy to contain. Although late maturing, they can fatten on grass alone. Like other native breeds throughout the Pacific region (for example, the Pauta of Hawaii), stock is being lost through crossbreeding, displacement by other breeds, and eradication efforts. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To find certain disease-resistant genes in poultry it may be necessary to go looking in the backyard chicken flocks in Latin America, Africa, or Asia.</P>
+<P ALIGN="JUSTIFY">Kelly Klober</P>
+<P ALIGN="JUSTIFY">Small Farmer's Journal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">. . . Policies are needed to encourage development of a labor-intensive small-scale livestock sector, which would increase employment and provide a major market for surplus cereals. This sector, however, is particularly restrained by poor technology, poor public support services, and poor marketing channels. Third World livestock production of this type could provide a natural focus for foreign assistance that earlier seemed inappropriate because of concerns about global food scarcity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John W. Mellor International Food Policy Research Institute</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Successful development of agriculture often requires an intimate understanding of the society within which it is to take place - of its systems of values, of its customary restraints.... It has been necessary to understand what incentives the farmer needs to change, what practical difficulties he encounters introducing change, what his traditional pattern of land use is and how this pattern or system can be upset by thoughtless innovation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John de Wilde</P>
+<P ALIGN="JUSTIFY">Experience with Agricultural Development in Tropical Africa </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Part II : Poultry</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g007a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chickens, ducks, muscovies, geese, guinea fowl, quail, pigeons, and turkeys epitomize the concept of microlivestock. Throughout Africa, Asia, and Latin America they are (collectively) the most common of all farm stock. In many - perhaps most - tropical countries, practically every family, settled or nomadic, owns some kind of poultry. In the countryside, in villages, even in cities, one or another species is seen almost everywhere; in some places, several may be seen together. Although raised in all levels of husbandry, these birds occur most often in scattered household flocks that scavenge for their food and survive with little care or management.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Their size bestows microlivestock advantages, including low capital cost, low food requirements, and little or no labor requirements. They are also "family sized": easily killed and dressed, with little waste or spoilage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These poultry species help meet the protein needs of the poorest people in the world. Some are raised even in areas where domestic cattle cannot survive because of afflictions such as trypanosomiasis and foot-and-mouth disease. Some are maintained under conditions of intensive confinement - provided a source of feed is available - and can be produced in areas with insufficient land for other meat-producing animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition, these birds grow quickly and mature rapidly. (For instance, a chicken can, under proper conditions, reach maturity in 26 months.) They adapt readily to being fenced or penned much, or all, of the time. And, compared with the major farm livestock, their life cycles are short and their production of offspring is high. Thus, farmers can synchronize production to match seasonal changes in the availability of feed. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although poultry contribute substantially to human nutrition in the tropics, it is a small fraction of what it could be. The meat is widely consumed and is in constant demand. An excellent source of protein, it also provides minerals such as calcium, phosphorus, and iron, as well as the B-complex vitamins riboflavin, thiamine, and niacin. Nutritionally as complete as red meat, it is much lower in cholesterol and saturated fats. Poultry eggs are also important sources of nutrients. They are a renewable resource, easy to prepare, and are among the best sources of quality protein and vitamins (except vitamin C).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In spite of their numbers and potential, poultry are rarely accorded primary consideration in economic development activities. All in all, these small birds lack the appeal of large, four-legged livestock. Indeed, most countries have little knowledge of the contribution household birds actually make to the well-being and diets of their peoples. In some countries - even those where birds are widely kept - there is little or no poultry research or extension. And where such programs do exist they usually focus almost exclusively on the production of chickens under "industrial" conditions near cities (see sidebar, page 75).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most developing countries now have these intensive chicken industries, in which birds are kept in complete confinement. However, these commercial operations provide food for people in the cash economy, not for subsistence farmers. Moreover, grain is sometimes diverted or imported to maintain these operations, perhaps causing food shortages, higher prices, or depleted foreign exchange. Thus, in this section we focus on other, neglected, aspects of poultry production.,</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The neglect of poultry that scavenge around the rural farmhouses and in village yards is understandable. The birds are scattered across the countryside where extension programs are difficult to implement. Their presence is often so ingrained in traditional village life that they are taken for granted and ignored by the authorities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yet village poultry deserve greater attention. As converters of vegetation into animal protein, poultry can be outstanding. In fact, it is estimated that, in terms of feed conversion, eggs rank with cow's milk as the most economically produced animal protein, and that poultry meat ranks above that of other domestic animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most Third World poultry flocks live a wary, half-wild existence, scrounging for insects, earthworms, snails, seeds, leaves, and leftovers from the human diet. From dung and refuse piles they salvage undigested grains, as well as insects and other invertebrates. Often the persons who care for them are women or children. Some keep the birds around the house, penning them at night for protection from predators and thieves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This almost zero-cost production has, in spite of high losses, a remarkable rate of return. Any improvements that require the purchase of supplies cut severely into the profitability. The first step in improving the production of free-ranging poultry is vaccination against diseases (especially Newcastle disease, fowl pox, and Marek's disease) and a modest, supplemental feeding during times of seasonal scarcity. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE INDUSTRIAL CHICKEN</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Throughout modem livestock farming the trend is toward more intensive methods, and poultry specialists have set the pace. In many countries, since the 1920s, barnyard fowl have given way to egg and broiler factories. The old-fashioned chicken reared outside on corn stubbles for 5 or 6 months has been replaced by the broiler, mass-produced in controlled environment houses in 7 - 10 weeks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As a result of this revolution in poultry raising, small farmers who once made a comfortable living from a few laying hens have been forced out of business. These economic changes have also forced poultry men to have larger and larger flocks to survive. The largest broiler-chicken companies even control their own breed development, feed production, house construction, slaughtering, and freezing, many even have wholesale outlets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The rapid changes in poultry farming methods can be attributed to the application of advanced technology. The development of the incubator to replace the mother hen sitting her seasonal clutch of eggs was the first mayor step toward intensive poultry farming.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition, chickens were the first livestock to receive serious attention from geneticists. Before World War II, it was discovered that crossbreeding selected pure and inbred lines could result in dramatic increases in production. Hybrids tailor-made for egg or meat production quickly ousted the old pure breeds such as the Rhode Island Red White and Brown Leghorns, Light Sussex, and the various crosses among them. Chicken broilers made by crosses involving parents derived from Cornish and Plymouth Rock have supplanted all others.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This situation now prevails in most industrialized countries. The breeding of commercial stocks is in the hands of a few corporations for each commodity (white eggs, brown eggs, chicken broilers, turkeys) and each has national or even global distribution of its hybrid stocks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A BREAKTHROUGH IN POULTRY HEALTH</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Newcastle disease is endemic in developing countries and is a constant threat to poultry. Farmers dread this virus, first identified half a century ago in northern England that brings diarrhea, paralysis, and death to most poultry. It is severe, highly contagious, and can cause 100 percent mortality. When it strikes an area, farmers must kill all chickens - even healthy ones - to stop it from spreading.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Only Australia, New Zealand, Northern Ireland and some Pacific islands are unaffected. But, although the disease is not found in Australia, certain strains of the virus are present in Australian chickens. These strains are completely harmless, but Australian researchers have found that they induce antibodies that are effective against Newcastle disease.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In a joint project (funded by the Australian Centre for International Agricultural Research), scientists from Malaysia's University of Agriculture and Australia's University of Queensland* have put this to good use. They have produced a live culture of the harmless virus that farmers can spray onto feed pellets to vaccinate their birds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Field tests of the new vaccine, carried out in Southeast Asia, have been extremely promising. Simply coating feeds with the virus seems to be enough to immunize some chickens, which then pass the immunity on to the others in the flock as well as to new hatchlings. In Malaysia, which has 49 million chickens and a population willing to pay a premium for tasty village poultry meat, one economist estimates that the vaccine might increase rural incomes by 25 percent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Conventional vaccines must be stored under refrigerated conditions, which most villages lack. But the Malaysian workers made the Newcastle disease vaccine tolerant of heat. By selective breeding, they now have strains that resist 56&Yacute;C for at least 2 hours. Thus, even in the tropics, the vaccine remains effective for several weeks without refrigeration. The researchers have also devised methods for coating the vaccine onto pelleted feeds. Because the virus can withstand heat, they use a machine designed for coating pharmaceutical tablets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At this stage, the project is showing every promise of producing a cheap means of reducing Newcastle disease losses among chickens throughout much of the world. Already inquiries have come from other Asian countries and from Africa, and it is hoped that the vaccine may eventually benefit many countries. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">5 Chicken</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g008a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chickens (Gallus gallus or Gallus domesticus)1 are the world's  major source of eggs and are a meat source that supports a food  industry in virtually every country. There may be as many as 6.5 billion  chickens, the equivalent of 1.4 birds for every person on earth.2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">No other domesticated animal has enjoyed such universal acceptance,  and these birds are the prime example of the importance of  microlivestock. Kept throughout the Third World, they are one of the  least expensive and most efficient producers of animal protein.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To the world's poor, chickens are probably the most nutritionally  important livestock species. For instance, in Mauritius and Nigeria more  than 70 percent of rural households keep scavenger chickens. In  Swaziland, more than 95 percent of rural households own chickens,  most of them scavengers. In Thailand, where commercial poultry  production is highly developed, 80-90 percent of rural households still  keep chickens in backyards and under houses. And in other developing  countries from Pakistan to Peru, a similar situation prevails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Clearly, these chickens should be given far more attention. They  represent an animal and a production system with remarkable qualities;  they compete little with humans for food; they produce meat at low  cost; and they provide a critical nutritional resource.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Scavenger chickens are usually self-reliant, hardy birds capable of  withstanding the abuses of harsh climate, minimal management, and inadequate nutrition. They live largely on weed seeds, insects, and feeds that would otherwise go to waste.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unfortunately, however, quantitative information about the backyard chicken is hard to obtain. Few countries have any knowledge of its actual contribution to the well-being and diet of their people. Notably lacking is an understanding of the factors limiting egg production, which is markedly low and perhaps could be raised dramatically with modest effort.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Worldwide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chickens are so well known and ubiquitous that they need no further description. Varying in color from white through many shades of brown to black, they range in size from small bantams of less than 1 kg to giant breeds weighing 5 kg or more. Scavenger chickens tend to weigh about I kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The indigenous chickens of Asia are probably descended directly from the wild junglefowl. Those of West Africa are believed descended from European birds brought by the Portuguese in the sixteenth century; those of Latin America probably descend from Spanish birds introduced soon after the time of Columbus.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p81a.png"></center><br>
+ figure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All countries have chickens in large numbers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They are not endangered, but industrial stocks are replacing traditional breeds to such an extent that much potentially valuable genetic heritage is disappearing. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although chickens derive from tropical species, they adapt to a wide  variety of environments. The modern Leghorn, for example, is found  from the hot plains of India to the frozen tundra of Siberia, and from  sea level to altitudes above 4,000 m in the Andes. (There are, however,  hatching problems at such high altitudes because of oxygen deficiency.)  They also occur in desert countries such as Saudi Arabia, which has a  vast poultry industry and even exports broilers. (However, the birds  need shade and a lot of water where it is hot and dry.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chickens are omnivorous, living on seeds, insects, worms, leaves,  green grass, and kitchen scraps.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A commercial bird may produce 280 eggs annually, but a scavenger  may produce close to none. Commonly, a farmyard hen lays a dozen  eggs, takes three weeks to hatch out a brood of chicks, stays with the  chicks six weeks or more, and only then starts laying again.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Egg production depends on daylength. For the highest production  rate, at least 12 hours of daylight are needed. The incubation period is  21 days. A hen can begin laying at 5 months of age or even earlier, but  in scavengers it may be much later. The average weight of the eggs is  approximately 55 g from industrial layers and approximately 40 g from  scavengers. Hatching success from breeder flocks often exceeds 90  percent. Industrial broilers can be marketed as early as 6 weeks, when  they are called "Cornish hens."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These passive, gregarious birds have a pronounced social (pecking)  order. If acclimated, they remain on the premises and are unlikely to go  feral. If given a little evening meal of "scratch," they learn to come  home to roost at night.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chickens have multiple uses. They were probably first used for cock  fighting; later they were used in religious rituals, and only much later  were raised for eggs and meat. Today, chickens can provide a family  with eggs, meat, feathers, and sometimes cash.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In different parts of the world, people keep scavenging chickens in  different ways. The managers are often women and children because  they have more time to spend at home to feed the birds and repel  predators. Some people leave the birds entirely to their own devices.  Many house them at night. Others take the birds each day to the fields,  where they may find much more food.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are many ingenious local practices. In Ghana, for example,  farmers "culture" termites for poultry by placing a moist piece of cow  dung (under a tin) over a known termite nest. The termites burrow into  the dung, and some can then be fed to the chickens each day. Because  termites digest cellulose, this system converts waste vegetation into  meat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A ratio of 1 male to 10-15 females is adequate for barnyard flocks.  Hens will lay eggs in the absence of a rooster - but of course the rooster  is needed if fertile eggs are wanted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Removing chicks stimulates the hen to lay more eggs. This results in  more chicks being hatched, but it requires that the chicks be nurtured  and fed until they are old enough to fend for themselves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Chickens are everywhere; every culture knows them and how to  husband them. They have been utilized for so many centuries that in  most societies their use is ingrained. Unlike the case with pork and beef,  there are few strictures against eating chicken meat or eggs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The meat is high in quality protein, low in fat, and easily prepared. In  many countries, the village chicken's meat is preferred to that of  commercial broilers because it has better texture and stronger flavor.  Even in countries with vast poultry industries there is a growing demand  for the tasty, "organically grown," free-ranging chicken.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chickens are more suited to "urban farming" than most types of  livestock and can be raised in many city situations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The birds are conveniently sized, easily transported alive, and, by and  large, do not transmit diseases to humans.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Throughout Asia, Africa, and Latin America, the problems of village  chickens are mainly those discussed below.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">High Hatching Mortality</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Commonly, a hatch of eight or nine village chicks results in only two  or three live birds after a few days. A survey in Nigeria, for instance,  showed that 80 percent died before the age of eight weeks. Losses  elsewhere are known to be similar. This is mostly because of starvation,  cold, dehydration, predators (hawks, kites, snakes, dogs, and cats, for  example), diseases, parasites, accidents, and simply getting lost - all of  which can be prevented without great effort.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chronic and Acute Disease</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Poultry diseases can become epidemic in the villages because there  are few if any veterinarians. Newcastle disease, fowlpox, pullorum  disease, and coccidiosis, for example - all of which are endemic in the  Third World - can destroy the entire chicken population over large  areas. Lice and other parasites are also prevalent. Scavengers and  industrial birds seem to show no differences in their tolerance for such  diseases and parasites.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Low Egg Production</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">A survey in Nigeria showed that the annual production per hen was  merely 20 eggs. Such low production is common throughout the Third  World and is caused by a combination of low genetic potential,  inadequate nutrition, and poor management. Villagers rarely provide nest  boxes or laying areas, so that some eggs are just not found. Some birds  have high levels of broodiness, and eggs accumulating in a nest  stimulates this. There are indications, however, that some village  chickens (for example, some in China) have quite substantial egg-laying  potential when provided with adequate feed.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Low Egg Consumption</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In the tropics, many people choose not to eat eggs. Often this is  because eggs are the source of the next generation of chickens;  sometimes it is because of superstition. Further, eggs do not keep well  because most are fertile and, exposed to constant tropical heat, undergo  rapid embryo development.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crop Damage</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">It is often necessary to confine the birds to protect young crops or  vegetable gardens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Unlike the situation with small cattle, goats, sheep, and pigs, there are  few named and recognized breeds of Third World chickens. Yet, nearly  every country has at least one kind of village chicken. These have  survived there for centuries and are highly adapted to local conditions.  In village projects, these unnamed chickens deserve priority attention  before other types are sought from elsewhere.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Generally speaking, improving the production of scavenging poultry  does not require sophisticated research. Instead, simple precautions are  sufficient. These are discussed below.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Disease Control</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">At a national or regional level, the initial approach to increasing  chicken production in tropical areas should be disease control. There are  several outstanding instances of success in this endeavor. For example,  the spectacular rise of poultry production in Singapore (from 250,000  birds in 1949 to 20 million in 1957) followed the control of Ranikhet  disease. Village flock-health programs, carried out regularly by visiting  veterinarians ("barefoot veterinarians"), might be the answer to some of  the routine health problems. Today, a prime target should be Newcastle  disease, for which there are good chances for success (see page 76).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Management</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The first step in chicken production at the farm level is improved  management. With more care and attention, mortality can be greatly  reduced. Because incubating and brooding hens must spend the night on  the ground, they are extremely vulnerable. Even modest predator  controls can be highly beneficial. Building crude and inexpensive nest  boxes and constructing a simple holding area around them can  substantially raise production by ensuring that more chicks survive.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE CHICKEN'S WILD ANCESTOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Although little known to most people, the red junglefowl has  contributed more to every nation than any other wild bird. It is  the ancestor of the chicken.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Given its descendants importance worldwide, the neglect of  this bird is baffling. If the cow's wild ancestor, the aurochs, had  not become extinct in the 1600s, it would now be worth millions  of dollars as the ultimate source of cattle genetic diversity. Yet  the world's chicken industry remains virtually unaware of the  origin of its source of livelihood.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like the aurochs, the red junglefowl has a wealth of wild  genes, and it deserves more recognition and protection. For one  thing the modern chicken - selectively bred in the temperate  zone - is highly susceptible to heat and humidity; the junglefowl,  on the other hand, is not. It inhabits the warmest and most humid  parts of Asia: Sri Lanka, India, Burma, Thailand, and most of  Southeast Asia. It may also be resistant to various chicken  diseases and pests.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This is not a rare species. Throughout the wide crescent  stretching from Pakistan to Indonesia, junglefowls are still seen  in the wild, especially in forest clearings and lowland scrub.  Although they are a prized bag for hunters, they survive by fast  running and agile flying. They are sometimes sold in village  markets, but can easily be mistaken for domesticated chickens,  which in this region are often very similar. The wild junglefowl,  however, has feathered legs, a down-curving tail, and an overall  scragginess.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Junglefowls should be under intensive study. They are easy to  rear in captivity and do well in pens, even small ones, as long as  they are sheltered from rain and wind. One drawback is their  craze for scratching unless provided plenty of space they  promptly tear up all grass and dirt. Another is that junglecocks  are violent fighters and must be kept apart. (Cockfighting is  probably a major reason why they were initially selected, and  thus their aggressiveness is perhaps the reason we have the  chicken today.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These highly adaptable creatures live in a variety of habitats,  from sea level to 2,000 m. Most, however, are found in and  around damp forests, secondary growth, dry scrub, bamboo  groves, and small woods near farms and villages. They are  amazingly clever at evading capture and thrive wherever there is  some cover.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other junglefowl species might also provide useful poultry.  They, too, can be raised in captivity with comparative ease, as  long as the cocks are kept apart. Perhaps they might be tamed with imprinting and could prove useful as domestic fowl,  especially in marginal habitats. They are everywhere considered  culinary luxuries and their meat commands premium prices.  Moreover, several have colorful feathers, giving them additional  commercial value. These other species are:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">- La Fayette's Junglefowl (Gallus lafayettei). Avery attractive  bird of Sri Lanka, it is little known in captivity, and only in the  United States are there any number in captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">- Gray or Sonnerat's Junglefowl (Gallus sonnerati). A native  of India, this colorful bird produces feathers that are used in  tying the most prized trout and salmon flies. Demand is so great  that certain populations have declined, and since 1968 India has  banned all export of birds or feathers. Nonetheless, there are  several hundred in captivity in various countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">- Green Junglefowl (Gallus varius). This is yet another striking  bird. The cock has metallic, greenish-black feathering set off by  a comb that merges from brilliant green at the base to bright  purple and red at the top. Native to Java, Bali, and the  neighboring Indonesian islands as far out as Timor, it is found  particularly near rice paddies and rocky coasts. This species, too,  can be raised without great difficulty, and there are at least 90 in  captivity in various parts of the world.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nutrition</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Improving poultry nutrition is also of prime importance. There are no quantitative data on the quality of a scavenging chicken's diet. Surveys are badly needed so that appropriate, low-cost supplements can be devised.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chances are that the diet for chicks of scavenging poultry is almost always deficient in available energy. Minimal supplementation in the form of cereals or energy-rich by-products can greatly improve both egg and meat production. However, caution must always be exercised and the supplements given only to chicks. Overfed adults will give up scavenging and stay around the owner's house, without really producing much more meat or eggs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Genetic Improvement</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Although it seems attractive to replace the scrawny village chicken with bigger, faster-growing imported breeds, it is a process fraught with difficulty. Exotic breeds lack the ability to tolerate the rigors of mismanagement and environmental stress. Many cannot avoid predators, as a result either of being overweight or of having a poor conformation for flight. The local birds, however, probably have a genetic potential that is much higher than can be expressed in the constraining environment. Thus, the environmental constraints should be tackled first.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, the village birds may have a feed-conversion efficiency that is far less than ideal because they are adapted to a scavenging existence. Modern breeds imported into Ghana, for instance, showed a feed-conversion efficiency of less that 3.5:1 (weight of food eaten: growth and eggs), but the local birds had efficiencies of 11:1.4 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Conservation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The need for preserving genetic variability is greater in poultry, especially in chickens, than in any other form of domestic animal. North America, for instance, which years ago had 50 or more common breeds, now relies on only 2 for meat production, and the others have been largely lost. Conservation of germplasm has become a matter of serious concern, and the saving of rare breeds in domestic fowl should not be delayed. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE SOUTH AMERICAN CHICKEN</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Early European explorers of South America were surprised to discover an abundance of unusual chickens that laid colored eggs and had feathers resembling earrings on the side of the head. While the origin of this bird - commonly called the araucanian chicken and classified as Gallus inauris - is debatable, scientists generally agree that it is pre-Columbian. There is archeological evidence that this bird is native to the Americas. It is reported to have occurred in Chile, Ecuador, Bolivia, Costa Rica, Peru, and Easter Island. It still occurs in the wild in southern Chile and on Easter Island.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The araucanian has been called the "Easter-egg chicken" because it lays light green, light blue, and olive colored eggs. It lays well and has a delicious meat. In areas such as southern Chile the eggs are preferred over those of normal chickens because of their flavor and dark yellow yolk. This unusual bird has a high degree of variability; however, specimens of similar genetic background have been grouped to create "breeds" such as the White Araucanian, Black Araucanian, and Barred Araucanian. These are homozygotes and breed true.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The araucanian has been the subject of much public interest,. clubs dedicated to its preservation have been formed in the United States, Great Britain, and Chile. Its possible exploitation as a backyard microlivestock deserves serious consideration. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">6 Ducks</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g009a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Domestic ducks (Anas platyrhynchos)1 are well known, but still have much unrealized promise for subsistence-level production. Although a major resource of Asia, where there is approximately one duck per 20 inhabitants, they are not so intensively used elsewhere. On a worldwide basis, for instance, they are of minor importance compared with chickens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This is unfortunate because ducks are easy to keep, adapt readily to a wide range of conditions (including small-farm culture), and require little investment. They are also easily managed under village conditions, particularly if a waterway is nearby, and appear to be more resistant to diseases and more adept at foraging than chickens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moreover, the products from ducks are in constant demand. Some breeds yield more eggs than the domestic chicken. And duck meat always sells at premium. A few recently created breeds (notably some in Taiwan) have much lower levels of fat than the traditional farm duck. This development could open up vast new markets for duck meat, especially in wealthy countries, where consumers are both concerned over fat in their diet and eager for alternatives to chicken.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ducks are also efficient at converting waste resources - insects, weeds, aquatic plants, and fallen seeds, for instance - into meat and eggs. Indeed, they are among the most efficient of all food producers. Raised in confinement, ducks can convert 2.4-2.6 kg of concentrated feed into I kg of weight gain. The only domestic animal that has better feed conversion is the broiler chicken.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Raised as village birds and allowed to forage for themselves, ducks become less productive but become even more cost effective because much of the food they scavenge has no monetary value. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Worldwide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Several distinctive types have been developed in various regions. Most have lost the ability to fly any distance, but they retain a characteristic boatlike posture and a labored, waddling walk. The Indian Runner, however, has an almost erect stance that permits it to walk and run with apparent ease.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Domestic ducks range in body size from the diminutive Call, weighing less than I kg, to the largest meat strains (Pekin, Rouen, and Aylesbury, for example) weighing as much as 4.5 kg. For intensive conditions, the Pekin is the most popular meat breed around the world. In confinement it grows rapidly - weighing 2.5-3 kg at a market age of 78 weeks. In addition, it is hardy, does not fly, lays well, and produces good quality (but somewhat fatty) meat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Khaki Campbell breed is an outstanding egg producer, some individuals laying more than 300 eggs per bird per year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Taiwan Tsaiya (layer duck) is also a particularly efficient breed. It weighs 1.2 kg at maturity, starts laying at 120-140 days, and can produce 260-290 eggs a year. Its small body size, large egg weight, and phenomenal egg production make Brown Tsaiya the main breed for egg consumption in Taiwan. More than 2.5 million Brown Tsaiya ducks are raised annually for egg production.2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The domestic duck is distributed throughout the world; however, its greatest economic importance is in Southeast Asia, particularly in the wetland-rice areas. For example, about 28 percent of Taiwan's poultry are- ducks. In parts of Asia, some domestic flocks have as many as 20,000 birds. One farm near Kuala Lumpur, Malaysia, rears 40,000 ducks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Although ducks are abundant, some Western breeds are becoming rare. Indigenous types are little known outside their home countries and have received little study, so their status is uncertain.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These adaptable creatures thrive in hot, humid climates. However, during torrid weather they must have access to shade, drinking water, and bathing water.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ducks are well adapted to rivers, canals, lakes, ponds, marshes, and other aquatic locations. Moreover, they can be raised successfully in estuarine areas. Most ocean bays and inlets teem with plant and animal life that ducks relish, but (unlike wild sea ducks) domestic breeds have a low physiological tolerance for salt and must be supplied with fresh drinking water. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Ducks search for food underwater, sieve organic matter from mud, root out morsels underground, and sometimes catch insects in the air. Their natural diet is normally about 90 percent vegetable matter (seeds, berries, fruits, nuts, bulbs, roots, succulent leaves, and grasses) and 10 percent animal matter (insects, snails, slugs, leeches, worms, eels, crustacea, and an occasional small fish or tadpole). They have little ability to utilize dietary fiber. Although they eat considerable quantities of tender grass, they are not true grazers (like geese), and don't eat coarse grasses and weeds at all. Sand and gravel is swallowed to serve as "grindstones" in the gizzard.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When protected from accidents and predation, ducks live a surprisingly long time. It is not unusual for one to continue reproducing for up to 8 years, and there are reports of exceptional birds living more than 20 years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite large differences in size, color, and appearance, all domestic breeds interbreed freely. Eggs normally take 28 days to incubate, brooding and rearing is performed solely by the female.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Depending on breed, a female may reach sexual maturity at about 20 weeks of age. Most begin laying at 20-26 weeks, but the best egg- laying varieties come into production at 16-18 weeks and lay profitably for 2 years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">It is generally well known that ducks are shy, nervous, and seldom aggressive towards each other or humans. Skilled and enthusiastic swimmers from the day they hatch, they spend many hours each day bathing and frolicking in any available water. However, most breeds can be raised successfully without swimming water.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although wild ducks normally pair off, domestic drakes will mate indiscriminately with any females in a flock. In intensively raised flocks, I male to 6 females, and in village flocks, 1 male for up to 25 females, results in good fertility.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most domestic ducks, particularly the egg-laying strains, have little instinct to brood. If not confined, they will lay eggs wherever they happen to be - occasionally even while swimming. To facilitate egg collection, some keepers confine ducks until noon. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY"><center><img src="p96a.png"></center><br>
+ Figure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As a meat source, ducks have major advantages. Their growth rate is phenomenal during the first few weeks. (Acceptable market weights can be attained under intensive management with birds as young as 6-7 weeks of age.) Yet, even in older birds, the meat remains tender and palatable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Eggs from many breeds are typically 20-35 percent larger than chicken eggs, weighing on average about 73 g. They are nutritious, have more fat and protein, and contain less water than hen's eggs. They are often used in cooking and make excellent custards and ice cream. Eggs incubated until just before the embryos form feathers produce a delicacy known as balut in the Philippines. Salted eggs are popular in China and Southeast Asia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Feathers and down (an insulating undercoat of fine, fluffy feathers) are valuable by-products. Down is particularly sought as a filler for pillows, comforters, and winter clothing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ducks have a special fondness for mosquito and beetle larvae, grasshoppers, snails, slugs, and crustaceans, and therefore are effective pest control agents. China, in particular, uses ducks to reduce pests in rice fields.3 Its farmers also keep ducks to clear fields of scattered grain, to clear rice paddy banks of burrowing crabs, and to clear aquatic weeds and algae out of small lakes, ponds, and canals. This not only improves the conditions for aquaculture and agriculture, it also fattens the ducks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In Southeast Asia, droving is a traditional form of duck husbandry, much as it was in medieval Europe. The birds are herded along slowly, foraging in fields or riverbanks as they march to market. The journey might cover hundreds of kilometers and take as long as six months.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This process, however, is generally declining, and most ducks are raised under farm conditions where they scavenge for much of their feed. Throughout Southeast Asia, ducks have been integrated with aquaculture.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ducks can be raised on almost any kitchen wastes: vegetable trimmings, table scraps, garden leftovers, canning refuse, stale produce, and stale (but not moldy) baked goods. However, for top yields and quickest growth, protein-rich feeds are the key. Commercial duck farms rely on such things as fish scraps, grains, soybean meal, or coconut cake. Agricultural wastes such as sago chips, palm-kernel cake, and palm-oil sludge are being used in Malaysia.4</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ducks have a very high requirement for niacin (a B vitamin). If chicken rations are used, a plentiful supply of fresh greens must be provided to avoid "cowboy legs," a symptom of niacin deficiency.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Of all domestic animals, ducks are among the most versatile and useful and have multiple advantages, including:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">- Withstanding poor conditions;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Producing food efficiently;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Utilizing foodstuffs that normally go unharvested;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Helping to control pests; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Helping to fertilize the soil.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Also, they are readily herded (for instance, by children).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Excellent foragers, they usually can find all their own food, getting by on only a minimum of supplements, if any. Raising them requires little work, and they provide farmers with food or an income from the sale of eggs, meat, and down.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ducks can grow faster than broiler chickens if they have adequate nutrients. Like guinea fowl and geese, they are relatively resistant to disease. They also have a good tolerance to cold and, in most climates, don't need artificial heat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">DOMESTICATING NEW DUCKS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Many species of ducks adapt readily to captivity; it is surprising, therefore, that only the mallard and the muscovy have been domesticated so far. Several wild tropical species seem especially worth exploring for possible future use in Third World farms, Because of the year-round tropical warmth, their instinct to migrate is either absent or unpronounced, and the heavy layer of fat (a feature of temperate-climate ducks that consumers in many countries consider a drawback) is lacking. Moreover, because of uniform daylength, they are ready to breed at any time of the year. Candidates for domestication as tropical ducks include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Whistling ducks (Dendrocygna species). These large, colorful, gooselike birds are noted for their beautiful, cheerful whistle.* They are long-necked perching ducks that are found throughout the tropics. By and large, they are gregarious, sedentary, vegetarian, and less arboreal than the muscovy - all positive traits for a poultry species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The black-bellied whistling duck (D. auturunalis) seems especially promising. It is common throughout tropical America (southwestern United States to northwestern Argentina) and is sometimes kept in semicaptivity. Occasionally, in the highlands of Guatemala, for instance, Indians sell young ones they have reared as pets. When hand reared, the birds can become very tame. * * They eat grain and other vegetation, require no swimming water, and will voluntarily use nest boxes. In the wild, they "dump" large numbers of eggs so that even if substantial numbers were removed for artificial hatching, the wild populations should not be affected.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Greater wood ducks (Cairina species). The muscovy (C. moschata) was domesticated by South American Indians long before Europeans arrived (see page 124). Its counterparts in the forests of Southeast Asia and tropical Africa are, however, untried as domesticates. The white-winged wood duck (C. scutulata) is found from eastern India to Java. Hartlaub's duck (C. hartlaubi) occurs in forests and wooded savannas from Sierra Leone to Zaire. Both are rare in captivity, but might well prove to be future tropical resources. Both are strikingly similar to muscovies in size and habits, being large, phlegmatic, sedentary, and omnivorous. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Predators are the most important cause of losses in farm flocks. Ducks are almost incapable of defending themselves, and losses from dogs and poachers can be high. Locking them in at night both protects the birds and prevents eggs from being wastefully laid outside.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ducks do suffer from some diseases, mainly those traceable to mismanagement such as poor diet, stagnant drinking water, moldy feed or bedding, or overcrowded and filthy conditions. Of all poultry, they are the most sensitive to aflatoxin, which usually comes from eating moldy feed. They are also susceptible to cholera (pasteurellosis) and botulism, either of which may wipe out entire flocks. Duck virus enteritis (duck plague) and duck virus hepatitis also can cause severe losses.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If not carefully managed, ducks can become pests to some crops, especially cereals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As noted, ducks tend to be extremely poor mothers and can be helped by using broody chicken hens or female muscovies as surrogate mothers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Major limitations to large-scale, intensive production are mud, smell, and noise.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Defeathering ducks is much more difficult than defeathering chickens because of an abundance of small pinfeathers and down feathers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These birds already function so well that no fundamental research needs to be done. Nonetheless, there are a number of topics that could improve their production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For example, different types of low-cost systems need to be explored and developed. These must be low-input systems since cash is a limiting factor for most subsistence farmers. One possibility is the integration of duck and fish farming.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A survey of all breeds is needed to determine their status and likelihood of extinction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One need in countries that already have ducks is to encourage the consumption of duck meat. Indonesia, for instance, has 25 million egg-producing ducks, but little duck meat is consumed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research on economically significant diseases is needed. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">7 Geese</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g010a.png"></center><br>
+ Brown Chinese Geese</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although geese (Anser spp.) were one of the first domesticated animals, they have yet to receive the level of commercial or industrial exploitation of chickens or even ducks. Thus, their global potential is far greater than is generally recognized today.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Domestic geese are easily managed and well suited to small-farm production; they are among the fastest growing avian species commonly raised for meat, and they have immediate application in many developing countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These birds are especially appropriate for providing farmers a supplemental income. With little extra work they supply nutritious meat, huge eggs, and rich fat for cooking, as well as soft down and feathers for bedding and clothing. Moreover, their strident voices sound the alarm when strangers or predators approach. They are especially well suited to aquatic areas and marshy lands and are completely at home in warm shallow waterways. Nevertheless, they can thrive away from water. In fact, wherever pasture is available geese readily adapt to captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Geese are grazers, and can be raised almost exclusively on pasture. They are excellent foragers, and on succulent grass can find most or all of their own food. With their powerful bills they pull up grasses and underwater plants and probe soil and water for roots, bulbs, and aquatic animals. Their long necks make them adept at gleaning weeds from hard-to-reach places - such as fence rows, ditches, and swampy areas that baffle larger livestock. They will also feast on vegetable trimmings, garden and table leftovers, canning refuse, and stale baked goods. Like other poultry, they pick up shattered grains of rice, wheat, barley, and other crops, which can reduce the bothersome problem of weeds volunteering in subsequent years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Geese are available worldwide. In most climates, they require little or no housing. Given reasonable care and protection from predators, mortality can be extremely low. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Worldwide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Domestic geese come in an assortment of colors, sizes, and shapes. There are two main types, however. Descendants of the wild greylag goose (Anser anser) make up the domestic breeds common in North America and Europe, including the Embden, Toulouse, Pilgrim, American Buff, Pomeranian, Sebastopol, and Tufted Roman breeds. These are generally best suited to temperate climates. On the other hand, descendants of the wild "swan goose" (Anser cygnoides) make up the geese of Asia, including the Chinese and "African" types. These breeds seem better suited to hot climates.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition to these, many European and Asian countries have their own local breeds and types, and there are even several wild species that show some potential for captive production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With their long legs and webbed toes, geese are equally at home walking or swimming. Avid walkers, they march long distances to find forage, but return home at dusk. Accomplished and graceful swimmers, geese are able to take to water soon after they hatch. Despite their large size, some domestic breeds - especially the leaner ones - have retained the ability to fly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Geese are found worldwide, but goose farming is nationally important only in Asia and Central Europe.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Domestic geese are not threatened, although much local variation among the breeds is being lost.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Most geese adapt well to hot climates - as long as some shade is available. Their waterproof feathers help them adapt well to high rainfall regions. They also tolerate extreme cold. (For instance, in Canada, geese are wintered outdoors in subfreezing temperatures, with merely 'e simple shelter from wind.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For tropical developing countries, the Chinese type, which is widely kept in Southeast Asia, is especially promising. Smaller than most geese (although ganders can weigh over 5 kg), they are the best layers, the most active foragers (making them economical and useful as weeders), the most alert and "talkative," and they produce the leanest meat. Some European breeds, such as Embden and Toulouse, have also been used in the tropics with notable success. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DOMESTICATING GEESE</P>
+<P ALIGN="JUSTIFY">(Temperate Zones)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Today's domestic geese are descended from two species: the greylag (Anser anser) and the swan goose (Anser cygnoides). These were domesticated in Europe and China, respectively. Their domestication occurred in ancient times, long before people knew about genetics, microorganisms, veterinary science, or behavior modifications such as imprinting. Today, armed with such knowledge, more geese may be amenable to domestication. Most of the 15 other wild species adapt to captivity. Compared to most birds, geese spend much time walking and swimming and are less inconvenienced by pinioning (removing the tip of the wing). Thus, they can be kept outdoors rather than in cages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Both of the ancestors of today's domestic geese are native to the northern temperate zone. Two more wild species that might make useful domesticates are:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Canada goose (Branta canadensis). North America. People feeding these birds in city parks and wildlife refuges are causing many local flocks to develop. These birds no longer migrate. They are increasing in numbers each year and are well on the way to de facto domestication.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- American swan goose (Coscoroba coscoroba). Southern South America. Although most closely allied to swans in shape and physiology, this bird resembles a muscovy (see page 124) in size and behavior. Its calm disposition, as well as its attractive red feet and bill that accent its white plumage, have made it much sought as an ornament for parks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In its diet, the goose utilizes large quantities of tender forage. It can break down plant-cell walls and digest the contents. Although it has no crop for storing food, there is an enlargement at the end of the gullet that serves as a temporary storage organ. Sand and small gravel are swallowed to aid the gizzard in grinding hard seeds and fibrous grasses. Research has shown that geese can digest 15-20 percent of the fiber in their diet, which is 3-4 times the amount that other poultry species can digest.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The natural diet consists of grasses, seeds, roots, bulbs, berries, and fruits, normally supplemented with a little animal matter (mainly insects and snails) picked up incidentally. Most feeding takes place on land. They characteristically feed for prolonged periods, even at night.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Females may lay for 10 years or more. It is generally believed that reproduction is best in the second year and that it remains good until the fifth year. Geese outlive other types of poultry; life spans of 1520 years are common.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The eggs incubate in 27-31 days. The incubation time is more variable than in most poultry species, perhaps because geese have not been subjected to the selection pressure that is imposed by artificial incubators.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">One of the most intelligent birds, the goose has a good memory and does not quickly forget people, animals, or situations that have frightened it. While personalities and habits vary among individual specimens, there are common behavioral patterns, such as the pecking order, that allow individuals to live peaceably together.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unless conditions are crowded or there are too many males, geese normally live harmoniously both with themselves and with other creatures. The bond between male and female is strong. Changing mates is difficult, although most geese will eventually accept a new mate after a period of "mourning."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Geese nest on the ground and prefer the water's edge, but they adapt readily to man-made nesting boxes. The gander usually stands guard while the goose incubates the eggs. He then assists in rearing the goslings. Most geese become irritated if intruders approach their nest or goslings, and will even attack people and large dogs. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As previously noted, these birds provide meat, eggs, fat, and down. The meat is lean, flavorful, and of outstanding quality. The fat accumulates between the skin and the flesh and can be rendered into a long-lasting oil. The eggs are large and taste much like chicken eggs. The "down" (the small, fluffy feathers that lie next to the body of adult birds) is the finest natural insulating material for clothing and bedding, and can fetch a premium price. Worldwide markets exist for both down and other goose feathers. In France, in particular, some geese are raised for their livers (foie gras).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Geese can control many types of aquatic weeds in shallow water as well as grass and some types of palatable broad-leaf weeds on the banks of lakes, ponds, and canals. They can also be used as ''lawn mowers" and "weeders" among cotton, fruit trees, and other crops (see sidebar).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Elongated necks not only allow geese to reach many different foods, they also help them keep a watchful eye on the surroundings. With their exceptional eyesight they can see great distances, and the position of the eyes gives them a wide field of vision. Geese are among the most alert of all animals, and strangers cannot calm them into silence. In the high Andes, in Southeast Asia, and in many other locations, they replace guard dogs. In Europe, they are used to guard whiskey warehouses and sensitive military installations (see page 111).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Methods of caring for adult geese vary according to climate, breed, and people's experiences and needs. Overall, however, the birds cause little trouble and require little expense. They range freely without restriction, feeding themselves and returning home of their own accord. They have strong flocking instincts and can readily be herded from one area to another.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like all young poultry, goslings are fragile. The highest mortality is caused by predators. Until the goslings are 6-10 weeks old, it is prudent to confine the parents and their young at night in a secure pen or building.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Geese are the only domestic fowl that can live and reproduce on a diet of grass. They cannot remain healthy on coarse dry fodder, but when grass is succulent they need little else other than drinking water. Many legumes also make excellent goose forage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the tropics, eggs can be laid year-round. The production seldom exceeds 40 eggs per year, although with feed supplement and simple management, the Chinese breed may yield more than 100 eggs. Geese go broody quickly. To break up broodiness, the goose can be confined for 4 6 days away from, but in sight of, the ganders.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goslings grow rapidly and can reach market size as early as 10-12 weeks; most geese, however, are marketed at 20-30 weeks of age, when they may weigh from 5 to 7 kg, depending on type and breed. Some young birds (also called green or junior geese), force-fed for rapid growth, are marketed at 4-6 kg when they are 8-10 weeks old.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If fed a good diet to maximize growth and if slaughtered at, say, 10 weeks, the Embden, Chinese, or African will have a carcass low in fat. However, the carcass normally has much more fat than other poultry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Geese must have a constant supply of reasonably clean drinking water during daylight hours. Although swimming water is not necessary, it promotes cleaner and healthier birds because they find it easier to care for their plumage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DOMESTICATING GEESE</P>
+<P ALIGN="JUSTIFY">(Tropics)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Geese of the tropics have seldom if ever been considered for domestication, but they might provide poultry of considerable value. Presumably they are more heat tolerant and lack the layers of subcutaneous fat (which the ancestors of today's geese needed for warmth in the Arctic). They might thus produce lean birds that would fetch premium prices because excessive fat is the major drawback of today's commercial geese. Examples of tropical species that might be domesticable are:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Egyptian goose (AIopochen aegyptiacus). Found throughout the African tropics, this bird is already partly domesticated. However, it is bad tempered and quarrelsome and, so far, this has limited its utility. It has therefore been kept only under semidomestication, without intensive breeding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Nene (Branta sandvicensis). A native of the Hawaiian Islands, this is one of the most endangered species on earth. So few specimens are in existence that farming enterprises cannot now be envisaged. Yet, should this bird prove amenable and suitable, the possibility of an economic future could boost efforts to build up its now meager populations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Bar-headed goose (Anser indicus). India and Central Asia. These smallish geese are handsome, dainty, and have a musical horn-like call. They have distinct black bars across the nape, which gives them their popular name. Hand-reared specimens breed well in captivity. Despite heavy hunting they are still abundant.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Northern spur-winged goose (Plectropterus gambensis gambensis). Tropical Africa (Senegal to Zimbabwe). This large bird is a ground nester, but it has long bony spurs on the wings that enable it to easily protect its eggs and young from predators.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Semipalmated (magpie) goose (Anseranas semipalmata). Australia and New Guinea. One of the most aberrant and primitive of all waterfowl, this long-legged sturdy-billed bird has only partially webbed feet. It perches high in trees and has a loud ungooselike whistling call. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE WADDLING WORK FORCE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Because geese relish grasses and shun most broad-leafed plants, some enterprising U.S. farmers in the 1950s began using them to rid cotton fields of grassy weeds, which are difficult to kill with herbicides. The geese were put into the fields as soon as the crop came up. A brace of birds kept an acre of cotton weeded; a gaggle of 12 would gobble as many weeds as a hard-working man could clear with a hoe.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This method of clearing fields was so effective that by 1960 more than 175,000 geese honked their way across the carefully tended farmland, mainly in the Southwest. Seven days a week, rain or shine, the feathered field hands slaved uncomplainingly from daybreak to dusk, even putting in overtime on moonlit nights. Many toiled so diligently that they worked themselves out of a job.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The geese cleared the fields more cheaply than hoe hands. They left the crop untouched and ate only the succulent young weeds. They did not damage crop roots (as hoes or tractors can), and they were safe and selective, unlike many herbicides. On top of all that they spread fertilizer for the farmer, and ultimately provided him meat for the market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Eventually, farmers found that geese could be used to weed nearly all broad-leafed crops: asparagus, potatoes, berry fruits, tobacco, mint, grapes, beets, beans, hops, onions, and strawberries, for example. Geese were used in vineyards and fruit orchards to eat both weeds and the fallen fruits that could otherwise harbor damaging insects. They were employed in fields producing trees for the forest industry and flowers for florists shops. Some growers turned goslings loose in cornfields to consume the "suckers" (cone, after all, is a grass) as well as the grain left on the ground. This eliminated the problem of corn as a weed when different crops were later planted in those fields.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the 1970s when cotton acreage dropped and herbicides selective for the troublesome grasses were developed, the use of geese declined. But today, some organic farmers are returning to the practice. From February to June in the Pacific Northwest, fields are resounding once more to the old-fashioned racket of White Chinese geese. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Mature geese are independent creatures. When kept in small flocks and allowed to roam the farmyard or field, they require less attention than any other domestic bird with the possible exception of guinea fowl. In areas where grass is green for much of the year, they can be raised on less grain or concentrated feed than any other domestic fowl.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Durability is one of their most attractive features. Along with ducks, geese seem to be the most resistant of all poultry to disease, parasites, and cold or wet weather. They also do well in hot climates as long as drinking water and deep shade are available.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Growth is not only rapid, it is also efficient. If managed properly, goslings can produce I kg of body weight for every 2.25-3.5 kg of concentrated feed consumed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Geese are not usually thought of as prolific layers. However, as noted, some strains of the Chinese breed will yield well over 100 eggs per goose per year. At 140-170 g per egg, that compares favorably with the output of laying chickens. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p112a.png"></center><br>
+ figure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These birds are messy and their loud trumpeting is often irritating. However, unless they have been teased or mistreated or if they are nesting or brooding young, they are not aggressive. But kilo for kilo, they are stronger than most animals, and a harassed or angry adult can express its displeasure effectively with powerful bill and pounding wings.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Excessive concentrations of geese on ponds or along creeks encourages unsanitary conditions, muddies water, hastens bank erosion, and destroys plant life. Where sanitation is poor, salmonellosis can devastate geese and be transmitted, via meat and eggs, to humans. Coccidiosis and gizzard worm are other infections.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Defeathering geese is more difficult than plucking chickens because there are two coats (feathers and down) to remove.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In some situations, geese may need a diet supplement (such as grain) if they are grazing vegetation exclusively. A balance must be struck: too much supplement and they will quit foraging and become too fat; too little and they grow slowly and may suffer malnutrition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Geese are not fully mature until two years of age. Their overall reproductive rate, therefore, is lower than that of other poultry. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Poultry researchers worldwide should begin studies to clarify the role that geese could play in helping to feed Third World nations. Studies might include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">- Management practices for tropical areas;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Breeding and management for increased egg production;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Incubation techniques;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Nutrition supplementation (for example, vitamins, minerals, energy, specific amino acids) needed by grazing geese;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Physiology of digestion and reproduction;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Clarifying the inheritance of various traits;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Genetic selection for specific meat, eggs, growth factors, or disease resistance;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Comparative studies of the relative efficiency (especially of feed utilization) of the various types and breeds for specific climates in underdeveloped countries;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Weeding tropical crops with geese; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Studying diseases and cross-infection with other birds. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">8 Guinea Fowl</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g011a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For Third World villages, the guinea fowl (Numida meleagris) could become much more valuable than it is today. The bird thrives under semi-intensive conditions, forages well, and requires little attention. It retains many of its wild ancestor's survival characteristics: it grows, reproduces, and yields well in both cool and hot conditions; it is relatively disease free; it requires little water or attention; it is almost as easily raised as chickens and turkeys; and it is a most useful all-round farm bird.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The guinea fowl's potential to increase meat production among hungry countries should be given greater recognition. The birds are widely known in Africa and occur in a few areas of Asia, but they show promise for use throughout all of Asia and Latin America and for increased use in Africa itself. Strains newly created for egg and meat production in Europe - notably in France - show excellent characteristics for industrial-scale production. Also, many semidomestic types in Africa deserve increased scientific assessment as scavenger birds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Meat from domestic guinea fowl is dark and delicate, the flavor resembling that of game birds. It is a special delicacy, served in some of the world's finest restaurants. Several European countries eat vast amounts. Annual consumption in France, for example, is about 0.8 kg per capita.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea fowl also produce substantial numbers of eggs. In Africa, these are often sold hard-boiled in local markets. In the Soviet Union, they are produced in large commercial operations. In France, guinea fowl strains have been developed that not only grow quickly but lay as many as 190 eggs a year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Outside Europe, virtually all guinea fowl are raised as free-ranging birds. These find most of their feed by scratching around villages and farmyards. Their cost of production is small, and they yield food for subsistence farmers. In Europe, on the other hand, most are raised in confinement, with artificial insemination, artificial lighting, and special feeding. In the main, this is to produce meat for luxury markets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea fowl production is beginning to increase all over the world. During the last 20 years, for example, many of Europe's chicken farmers and breeders, wishing to diversify, have switched to this bird. The United States is now studying ways to establish industrial production, and both Japan and Australia are increasing their flocks. Nonetheless, there is still a vast untapped future for this bird.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Worldwide. This species is robust and resilient and adapts to many climates.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Guinea fowl are somewhat larger than average scavenger-type chickens: adults weigh up to 2.5 kilograms. They have dark-grey feathers with small white spots. Their heads are bare with a bony ridge (helmet) on top, which makes them look something like vultures. The short tail feathers usually slope downwards.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The chicks, known as "keels," resemble young quail. They are brown striped with red beaks and legs. The sexes are indistinguishable until eight weeks of age. After that, the males' larger helmets and wattles and the cries of the different sexes can be identified. Both sexes give a one-syllable shriek, but females also have a two-syllable call.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like the chicken, the guinea fowl is a gallinaceous species and possesses the characteristic sternum with posterior notches and a raised "thumb."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Among domestic types are pearl, white, royal purple, and lavender. Pearl is the most common, and is probably the type first developed from the wild West African birds. Its handsome feathers are often used for ornamental purposes. The white is entirely white from the time of hatching and has a lighter skin. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p117a.png"></center><br>
+ figure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Europe dominates industrial production. France, Italy, the Soviet Union, and Hungary all raise millions of guinea fowl under intensive conditions, just as they raise chickens. Elsewhere, guinea fowl have become established as a semidomesticated species on small family farms. Native flocks are found about villages and homes in parts of East and West Africa, and free-ranging flocks can be seen in many parts of India, notably Punjab, Uttar Pradesh, Assam, and Madhya Pradesh. During the slavery era, they were introduced from Africa to the Americas to be used for food. In Jamaica, Central America, and Malaysia, the birds have reverted to the wild state and are treated as game.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Guinea fowl are abundant; in most places even wild populations are not threatened.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Guinea fowl are native to the grasslands and woodlands of most of Africa south of the Sahara where they occupy all habitats except dense forests and treeless deserts. Being native also to temperate South Africa, they appear to have an inherent adaptability to both heat and cold. However, in cool climates, regardless of daylength, they will not begin egg production until temperatures exceed 15&Yacute;C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Guinea fowl accept many foods: grains, leaves, ant eggs (for which they will tear anthills open), and even carrion.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Normally, they lay their first egg at about 18 weeks of age. Unlike many wild birds, which produce a single clutch a year, guinea hens lay continuously until adverse weather sets in.2 Free-range "domestic" guinea hens lay up to 60 eggs a season. And well-managed birds under intensive management lay close to 200. The eggs weigh approximately 40 g. Shells are stronger than those of chickens and are usually brown, but can be white or tinted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The guinea hen goes broody after laying, which can be overcome by removing most of the eggs. A clutch of 15-20 is common. The incubation period is 27 days.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These birds never become "tame," but neither do they leave the premises. Although they stray farther than chickens do, they always return. They like to hide their eggs in a bushy corner, often in hollows scratched in the ground. They can fly, although even in the wild they do not fly far. They prefer to roost on high branches and (unless pinioned) can be hard to catch during the day.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although wild guinea fowl live in groups, they are monogamous by nature and tend to bond in pairs. However, in domestication a single male may serve four or more females.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As noted, guinea fowl are valuable sources of both meat and eggs. They can also be used to control insect pests on vegetable crops.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea fowl are good "watch animals"; they have fantastic eyesight, a harsh cry, and will shriek at the slightest provocation. Their agitation on sighting dogs, foxes, hawks, or other predators have saved the lives of many a chicken, duck, and turkey. They are brave and will attack even large animals that threaten them.4 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Guinea fowl can be kept in confinement using the methods for raising battery chickens. In this system, breeding stock are housed in cages and artificially inseminated. It gives the best egg production and fertility but requires housing, equipment, and skilled labor.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These birds can also be kept in a semidomestic state in and around the farmyard. In such cases they are penned until they are 12 weeks old. Unaccustomed to foraging for natural food, they constantly return to their artificial food supply. Eventually, however, they learn to subsist by scavenging.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The birds have been called "the worst parents in the world," and are almost incapable of looking after their keets.5 Because the females are such indifferent mothers, the eggs are best hatched in incubators or under other birds, to avoid the keets' being lost by their natural mothers. In many African countries, eggs are hatched under chickens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Keets are often kept indoors until they are 3-4 weeks old to protect them from predators and wet weather. Sexual maturity can be delayed to as late as 32 weeks of age by holding the birds in windowless housing and controlling the lighting. This improves egg size and hatchability and reduces early mortality. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">GUINEA FOWL AND THE ANCIENTS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The earliest reference to guinea fowl can be found in murals in the Pyramid of Wenis at Saqqara in Egypt, painted about 2400 B.C. Aviaries were quite fashionable at the time, and wealthy landowners maintained guinea fowl within their walled gardens. A thousand years later, by the time of Queen Hatshepsut (about 1475 B.C.), the junglefowl (the ancestor of the chicken) had arrived, and from then on it was raised on a substantial scale. Records of this period refer to "walk-in" incubators, constructed of mud bricks and heated by cameldung fires. The largest could hold up to 90,000 eggs (mainly from junglefowl but some from guinea fowl) and hatching rates of up to 70 percent were claimed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By 400 B.C., guinea fowl were well established on farms in Greece. Later, they rose to importance in ancient Rome. Pliny the elder (in his Natural History, published 77 A.D.) stated that they were the last bird to be added to the Roman menu and that they were in great demand, both eggs and flesh being considered great delicacies. The emperor Caligula offered them as sacrifices to himself when he assumed the title of deity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The guinea fowl then died out in Europe but was reintroduced by the Portuguese navigators returning from their African explorations in the late 1400s. They gave it the name pintada or "painted chicken" and this changed to pintade in French, while the name "Guinea fowl" (fowl from Africa) stayed in English, and gallina de Guinea in Spanish. Coincidentally, guinea fowl and turkeys were both introduced to England between 1530 and 1550, and the English, smitten with the original French misnomers, were left sorting out "Ginny birds" and "Turkey birds" for the remainder of the century. Both birds were adopted with great enthusiasm, and within 150 years they had utterly displaced the peafowl and swan as the major table birds for festive occasions.</P>
+<P ALIGN="JUSTIFY">Adapted from R.H.H. Belshaw, 1985 Guinea Fowl of the World</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Compared with the farmyard chicken the guinea fowl's advantages are:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">- Low production costs;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Premium quality meat;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Greater capacity to utilize green feeds;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Better ability to scavenge for insects and grains;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Better ability to protect itself against predators; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Better resistance to common poultry parasites and diseases (for example, Newcastle disease and fowlpox).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Surprisingly, this semidomestic bird, which has been farmed for centuries, retains the characteristics (feather morphology, hardiness, social behavior) of its wild ancestor - even when subjected to the most modern intensive-rearing methods employing battery cages and artificial insemination. Thus, it thrives under semicaptive conditions and needs little special care. The birds forage well for themselves and do not require much attention; their meat is tasty and they produce substantial numbers of eggs. Unlike chickens, they don't scratch to get insects out of the soil, so they are less destructive to the garden.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In backyard production the guinea fowl is supreme, but when produced intensively it costs more to raise than chickens. In Europe, for instance, day-old keets cost about twice as much as day-old broiler chicks. (The major reason is that guinea fowl produce fewer hatching eggs and require a longer feeding period.) Guinea fowl are also more expensive to feed. Their feed conversion (for meat production at the marketing age) is about 3.3-3.6 as compared with a broiler's feed conversion of 1.8-1.9. Moreover, guinea fowl take about twice as long to reach marketable size: they are marketed for meat at age 12-14 weeks, compared with 7-8 weeks for the broilers. Therefore, the selling price of guinea fowl in the Western world is up to twice that of broilers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea fowl are nervous and stupid. They can be difficult to catch' and when panicking they can easily suffocate their keets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They are susceptible to some of the common diseases of chickens and turkeys. Salmonella is the most prevalent, but others are pullorum disease, staphylococcus, and Marek's disease. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE GUINEA FOWL'S WILD COUSINS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The domesticated guinea fowl is descended from just one subspecies of the family's seven known species and numerous subspecies. Some of the others may also have promise as poultry. They, too, generally occur in flocks in bushy grasslands and open forests in Africa. All feed on vegetable matter such as seeds, berries, and tender shoots, and on invertebrates such as slugs. They rarely fly except to roost. They acclimatize well are easy to maintain in captivity, and can survive long periods away from water.** Their disposition is tame and nonaggressive, and they mix well with other birds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild subspecies closely related to the domestic guinea fowl that might make future poultry in their own right include the following:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">- Gray-breasted guinea fowl (Numida meleagris galeata). This subspecies is the principal ancestor of domestic guinea fowls. It is found throughout West Africa and probably has many valuable genetic traits. There is much variation in the size and other characteristics among the various individuals. People along the Gambia, Volta, and Niger rivers have long traditions of breeding these birds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Tufted guinea fowl (Numida meleagris meleagris). This subspecies is quite large and has black plumage thickly spotted with white dots. It is the probable ancestor of the birds reared in ancient Egypt and in the Roman empire (see page 120). Hill farmers in the southern Sudan sometimes breed them in captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Mitred guinea fowl (Numida meleagris mitrata). Probably the most popular game bird in East Africa, this type has a bright blue-green head and red wattles. It was once a common sight in the wild but it has now been decimated by overhunting. It is now most numerous in the Masai lands of Kenya and Tanzania. It has been kept in a semidomesticated form in Zanzibar for several centuries. Zoos and aviaries around the world have imported it, and it has bred well for them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild guinea fowl that are different species from the domestic one but that are still worth considering as potential poultry include the following:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Black guinea fowl (Phasidus niger or Agelastes niger). This bird of the tropical rainforests of West and Central Africa is the size of a small chicken. It has sooty black plumage, a naked head, and a pink or yellow neck. It is seldom hunted because the meat tastes dreadful but this is probably because of a particularly pungent fungus they eat in the forest. Raised on fungus-free forages, these birds are probably very palatable. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Crested guinea hen (Guttera spp.). Three species. These strange-looking birds have a thick mop of inky black feathers above their black, naked faces. Widely distributed in the thickly forested areas of sub-Saharan Africa. Unlike the other species, they prefer the rainforest. They have a musical trumpeting call. At least one species has bred well in Europe. For example, a flourishing colony has been established in the Walsrode Bird Park in Germany.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Vulturine guinea fowl (Acryllium vulturinum). The largest of all guinea fowl, this species is found in parts of Ethiopia, Somalia, and East Africa. One of the most striking looking of all birds, its head is bare and blue, its body black with white spots, and its breast bears long bright cobalt-blue patches on either side. This has been reared as an aviary bird in both Europe and America and might make a useful domesticate.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Agencies involved in international economic development should undertake guinea fowl assessment trials, evaluations, and coordinated introductions to stimulate programs for small farmers and for industries in dozens of countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Breeders have been working to improve guinea fowl only since the 1950s. There is a need for more information on growth rate, health, egg production, feed conversion, body weight, carcass yield, laying intensity, fertility, hatchability, and egg weight - especially under free-ranging conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Husbandry research should also be directed towards feeds and feeding systems for growing and breeding stock. Other efforts are needed to increase the hatchability of eggs under natural conditions (under guinea hens or surrogate mothers), and to identify the best lighting regimes (both sexual maturity and rate of lay are influenced by changes in daylength).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The guinea fowl that has become an important domesticated bird throughout the civilized world is descended from just one of seven known species in the family. These birds generally occur in flocks in bushy grasslands and open forest in Africa and Madagascar, and some of the others may also have promise as poultry (see sidebar opposite). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">9 Muscovy</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g012a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The muscovy (Cairina moschata), a unique ducklike species of the South American rainforest, belongs to a small group of waterfowl that perch in trees. In poultry science, however, it is normally grouped with domestic ducks for lack of a better classification.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Except in France, Italy and Taiwan muscovies have received little modern research. But their promise can be judged from the fact that they account for 50 percent of the duck meat consumed in France - about 60,000 tons per year - and they are often consumed in Italy and Taiwan as well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For Third World subsistence farming, muscovies have excellent possibilities. There is probably no better choice for a meat bird that requires minimal care and feed. Tame, quiet, and able to forage for much of their keep, they are inherently hardy, vigorous, and robust. They have heavily fleshed breasts and are highly prized for their meat, which is dark, more flavorful, and less fatty than that of common ducks. An average muscovy gives more meat than a chicken of the same age, and it also survives hot, wet environments better. In addition, muscovies are better parents than the domestic duck. Females are probably the best natural mothers of any poultry species, as measured by their success at incubating their eggs and caring for their young.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All in all, this bird deserves more attention than it has received so far in Third World livestock projects. Dispersed around the warm and hot regions of the world, muscovies already exist in small numbers in backyards and villages, much like the domestic chicken in previous centuries. Despite a lack of research, the present unimproved stocks are already impressive meat yielders. Used more widely and more intensively, they could contribute much to poor people's meat supplies. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crossing the muscovy with the common duck produces a hybrid that combines many of the advantages of both. This cross, known as "mulard," or "mule duck" in English, is raised in France for its liver and meat and is produced in quantity in Taiwan (see sidebar, page 132). It, too, has a major future role.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Muscovies are suitable for use almost anywhere that chickens can be kept. Moreover, their tropical ancestry and inherent robustness give them an advantage in hot and humid climates.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Although a muscovy somewhat resembles a goose, it is one of the greater wood ducks of tropical South America. It was domesticated in pre-Columbian times, most likely in the rainforests of Colombia. Related wild types, looking very much like the muscovy, still occur in South American wetlands, particularly mangrove swamps.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Males have mature live weights of 5 kg and females about 2.5 kg. Both have broad and rounded wings. The adults have patches of bare skin around the eyes, rather than feathers. Much of this is covered in "caruncles," which superficially resemble warty outgrowths. The feet have sharp claws. Both sexes raise a crest of feathers when alarmed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is much color variation among the various muscovy populations including types that are called white, colored, black, blue, chocolate, silver, buff, and pied.2 The most common types (they are not considered breeds) are the white and the colored. The white produces a cleaner looking carcass, but the colored is the most popular meat type in France. Its plumage is an iridescent greenish black, except for white forewings.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The native range of the muscovy's probable wild ancestor covers much of Central America and northern South America. The domestic form also occurs over most of Latin America - from southern Chile to the northern limits of traditional culture in lowland Mexico - including the Caribbean, where it was present shortly after Columbus landed.3 The birds can be observed among the domestic fowl in the high Andes, for example, and are feral in southern coastal areas of the United States.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Carried across the Atlantic, probably in the early 1500s, the domesticated muscovy spread quickly in Europe, and thence to North America, Asia, Africa, and Oceania. Today, it finds favor with the food-loving French as "canard de Barbarie," and France has the greatest concentration of muscovies in Europe.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Down the centuries the muscovy became popular in tropical Asia (especially the Philippines and Indonesia) and in China and Taiwan. Throughout Indonesia (where it is known as "entok") it is popular with villagers for incubating eggs from ducks, geese, and chickens. It is now spreading into Oceania, and has recently gained particular favor in the Solomon Islands.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muscovies are also known in Africa and can be found in many villages, especially in West Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Not endangered.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Wild muscovies occur mainly along tropical jungle streams, but domestic muscovies are found in many environments from the heat of Central America to the cold of Central Europe. They also tolerate dry conditions, but they thrive best where climates are both hot and wet.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Muscovies utilize high-fiber feeds better than chickens and common ducks, and eat larger quantities of grass. They also consume other green vegetation and readily snap up any insects they can find. If quality forage is available, only a small daily ration of grain or pellets is required for them to reach peak production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muscovy females normally hatch and raise large broods efficiently. It is not unusual to see them with a dozen or more fragile ducklings in tow - many of them adopted from other species. They bravely protect their young and have been known to beat off cats, dogs, foxes, and other marauders.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Normally, muscovies are healthy and live and breed for many years. They suffer few diseases, especially when free ranging. However, they seem to be more susceptible to duck virus enteritis (duck plague) than common ducks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p129a.png"></center><br>
+ figure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">While appearing to be slow and lethargic, muscovies can be quick and agile when one tries to catch them. Females are strong fliers and readily clear a standard fence. Males frequently become so ponderous that they cannot get airborne without an elevated perch or the aid of a strong wind. Although they forage over a larger area than chickens, they generally neither decamp nor wander as far as common ducks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Domesticated muscovies are either solitary or live together in small family groups, but sometimes in winter they flock together on bodies of water. They swim and dive well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These birds seldom make loud noises. A drake's voice resembles a muffled "puff"; females are almost mute. However, both can hiss or make a soft sound not unlike that of sleigh bells.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The muscovy is polygamous (a young male will try to mate with almost any fowl, including chickens). Mating can occur on land or in water. Males are pugnacious and tolerate no opposition. Because of this, they do not do well in close confinement.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A BETTER FLY TRAP</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The muscovy is a voracious omnivore that is particularly fond of insects. For years, some Canadian farmers have sworn that a few muscovies took care of all fly problems on their farms. In 1989, Ontario biologists Gordon Surgeoner and Barry Glofcheskie (see Research Contacts) decided to put this to the test.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Starting with laboratory trials, the entomologists first put a hungry five-week-old muscovy into a screened cage with 400 living houseflies. Within an hour it had eaten 326. Later, they placed four muscovies in separate cages containing 100 flies each. Within 30 minutes over 90 percent of the insects were gone. It took flypaper, fly traps, and bait cards anywhere from 15 to 86 hours to suppress the populations that much.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moving to fleld tests, the researchers placed pairs of twoyear-old muscovies on several Ontario farms. Videotapes showed the birds snapping at houseflies and biting flies about every 30 seconds and being successful on 70 percent of their attempts. With that efficiency, they achieved 80-90 percent fly control in enclosures such as calf rooms or piggeries. The birds were given only water and had to scavenge for all their food. Females seemed to eat about 10 percent more flies than males, and individuals of any age between eight days and two years were equally effective.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The birds fit the practical needs for farmyard fly control. They stayed close to piglets and calves, to which flies are particularly attracted. They even snatched flies off the hides of resting animals without waking them up. On one farm, the birds huddled between sleeping piglets and were accepted by the sow lying beside them. This was noteworthy because most fly-catching devices (chemical, electrical, or mechanical) must be kept far from animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To the Canadians, the economic advantages are clear. A 35-cow dairy needs $150-$590 worth of chemicals for controlling flies during the fly season; muscovy chicks, on the other hand, cost less than $2 each, eat for free, and can be sold for a profit of 200-400 percent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The researchers point out that employing muscovies does not eliminate all need for insecticides, but it reduces the amounts required. And muscovies are biodegradable, will not cause a buildup of genetic resistance, and taste better than flypaper. Indeed, their meat is excellent, and the naturally mute birds seldom make any noise.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Reportedly, muscovies are kept in some houses in South America to control not only flies, but also roaches and other insects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The muscovy is generally raised only for its meat, which is of excellent quality and taste. In stews it is hard to distinguish from pork; cured and smoked it is similar to lean ham.4 The fat content is low.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muscovy eggs are as tasty as other duck eggs, and a muscovy female can supply a large number if she is kept from sitting.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These birds are useful for clearing both terrestrial and aquatic weeds.5</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Down feathers are used, like those of other ducks, in clothing and comforters.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Muscovies may be raised like common ducks. An ideal grouping is one male to five or six females. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Except in Taiwan, France, Hungary, and a few other European countries, they exist predominantly in small flocks in farmyards and village ponds. However, they can be reared under intensive conditions in a shed or pen that is well lighted and equipped with low roosts and bedding. Under such conditions, they may be fed diets recommended for rearing common ducks or given coarse feeds, including whole grain. If chicken rations are used, fresh greens must be provided to avoid "cowboy" legs, a symptom of niacin deficiency.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although they thrive in areas where there is abundant water, they do not require access to swimming water. They prefer to nest under cover and will use nesting boxes. A normal clutch size is 9-14 eggs; however, clutches of up to 28 can occur. There may be 4 clutches annually, and (when the hen does not have to brood the ducklings) some muscovies have laid 100 eggs in a year.6</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The egg weight, which increases with the female's age, ranges from 65 to 85 g. The eggs require 33-35 days to hatch, a week longer than the common duck's. Hatching success of 75 percent or more is common.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Compared with domestic ducks early growth is slow, which is perhaps why muscovies have not enjoyed wider industrial use. However, after the slow period they grow rapidly and, because they forage on a broader range of vegetation than common ducks, they can scavenge a large proportion of their diet at little or no cost.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When raised intensively, females average 2 kg and males 4 kg at 11-12 weeks of age. Females may reach sexual maturity by 28 weeks of age; males require a month more.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE MULE DUCK OF TAIWAN</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In parts of Europe, hybrids between muscovies and common ducks are reared for fattening. However, Taiwan has made the most outstanding use of this "mule duck." Thanks in part to this muscovy hybrid, Taiwan's duck industry has grown rapidly in the last decade. The total value of duck products now exceeds $346 million per year. Much of the boom in duck production is due to improved feeding disease control and management systems, but much is also due to the performance of the mule duck. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This hybrid is now Taiwan's major meat-duck breed, and about 30 million are consumed each year. Indeed, the duck industry has been so successful that Taiwan is increasingly exporting frozen duck breast and drumstick meat to Japan. It now provides 24 percent of the duck meat eaten in Japan most of it coming from mule ducks. Also, Taiwan is exporting partially incubated mule-duck eggs throughout Southeast Asia. And mule ducks supply most of the raw material for Taiwan's large feather industry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Taiwan farmers have been producing mule ducks for 250 years, but the recent jump in production is due to the use of artificial insemination to overcome the natural reticence of the different species to mate. Fortunately, artificial insemination is well developed and is a standard part of farming practice in Taiwan.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mule ducks are successful because they have less fat than a broiler chicken and they grow faster. Indeed, they can reach a market weight of 2.8 kg at 65 - 75 days of age, depending upon the weather, season, and management. In part, this fast growth is because they are sterile and waste no energy in preparing for a sexual existence or in laying eggs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The usual cross employs a muscovy male and a domesticduck female. The domestic breeds most employed for muleduck production are White Kaiya (Pekin male x White Tsaiya female), Large White Kaiya (Pekin male x White Kaiya female) and colored Kaiya. Both sexes of the hybrid offspring weigh about the same.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crosses between a muscovy hen and a domestic drake are much rarer (traditionally, this was because of the different mating behavior of the two species, but even with artificial insemination available they are not much used) and the males of these hybrids are much heavier than the females. Females of this cross do lay eggs, but the eggs are small (about 40 g) and their embryos do not develop.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are almost 300 duck-breeding farms in Taiwan, annually producing more than 600,000 female domestic ducks for use in producing mule ducks. Some farmers combine duck raising with fish farming. The excrete of 4,000 ducks on one hectare of pond can provide 30,000 tilapia with 20 percent of their feed. It helps the farmer get rid of waste as well as giving him fresh fish to sell. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As noted, the muscovy is an extremely good forager and thrives under free-ranging conditions. Unlike other ducks, it grazes on grass and leaves and will maintain itself on pasture. Apparently, it can digest bran and other fibrous feeds better than common ducks can.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The males are larger than all but the largest strains of table duck. They have exceptionally broad, well-muscled breasts and provide one of the leanest meats of any waterfowl.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The muscovy is apparently more resistant to diseases that regularly decimate other poultry. This is one reason why villagers favored them: when chickens die, muscovies often survive.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The female's strong parental qualities help assure the survival of ducklings with a minimum of human intervention. Her ability to incubate and hatch most other poultry eggs is an added advantage to small farmers who have neither the capital to buy, nor the knowledge to operate, artificial incubators.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unlike other ducks, muscovies are not easily alarmed, and fright does not affect their egg production and laying. Indeed, they are so phlegmatic that automobiles can be major causes of death.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Because they are a tropical species, these birds are much less tolerant of cold than common ducks and require more protection from freezing weather.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The muscovy's feed conversion is not as good as the chicken's. Also, compared with some other meat-duck breeds, muscovies have a slower rate of growth and require about 4 6 weeks longer to attain maximum development of breast muscles.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muscovies can be difficult to handle. If their legs are free, the handler may be badly lacerated by the claws.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although adults have a fair homing ability, muscovies may wander away when local forage is sparse, and young birds may be carried long distances downstream, never to return.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because they feed on greenery, they can devastate gardens if the plants are very young.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muscovies can be unsuspected carriers of poultry diseases, so that healthy-looking muscovies may infect the other species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Poultry scientists should unite in efforts to advance technical knowledge and public appreciation of this bird. Governments and researchers should begin evaluations of local varieties and their uses and performances. The experiences of France, Italy, Eastern Europe, and Taiwan should be gathered and made available for a worldwide readership.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is important that the many muscovy varieties within the countries of Latin America - where the bird has a centuries-long history of domestication - be maintained and studied. Many superior varieties and specimens may be awaiting discovery.7</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The muscovy's nutritional requirements, range and confined systems of management, and disease vulnerability are poorly understood and need study. Especially needed are ways to increase growth rate. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">10 Pigeon</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g013a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigeons (Columba livia)1 are durable birds that can be raised with little effort. Able to survive in inhospitable climates, they fend for themselves - often ranging over many square kilometers to locate seeds and edible scraps. They have been raised for centuries, especially in North Africa and the Middle East. In parts of North America and Europe, they are produced as a delicacy for the gourmet market. But raising pigeons for food is not nearly as widespread as it could be; indeed, in modern times its potential has hardly been touched. Farmed pigeons are particularly promising as urban microlivestock because they require little space and thrive in cities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Young pigeons (squab) grow at a rapid rate. Their meat is finely textured, has an attractive flavor, and is often used in place of game fowl. Tender and easily digested, it commands premium market prices. In many areas, the continuing demand is unfilled.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigeons are traditionally raised in dovecotes - "houses" that protect the birds from the elements and from predators. This system allows free-ranging flight and requires almost no human intervention. Dovecotes are a good source of both squab and garden manure, and they continue to be used, especially in Egypt. On the other hand, pigeons can also be raised in confinement - usually in enclosed yards - with all their needs supplied by the farmer. There are, for example, pigeon farms in the United States with up to 35,000 pairs of breeding birds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigeon production may never rise enough to compete with commercial poultry as a major source of food, but for Third World villages these birds could become a significant addition to the diet as well as a source for substantial supplemental income. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Worldwide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Pigeons have small heads, plump, full-breasted bodies, and soft, dense plumage. They weigh from about 0.5 to nearly I kg. A few large breeds (Runts, for instance, which commonly weigh 1.4 kg) are the size of small domestic chickens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many breeds have been developed for meat production. They produce squab that grow quicker and have larger breasts than unselected birds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The wild ancestor of the common pigeon - domestic, wild, or feral -  is thought to be the rock pigeon or rock dove of Europe and Asia. Today its domestic descendants are bred in virtually every country, and those that have gone feral (reverted to the wild) occur in most of the world's cities and towns.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">They are abundant. However, as with most other domestic species there is concern over the decline and loss of certain breeds. Societies have been organized (notably in the United Kingdom) to preserve rare types.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p138a.png"></center><br>
+ Natural habitat of the rock dove ancestor of the domestic pigeon</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The domestic pigeon can be raised equally well in temperate and tropical zones. Indeed, this adaptable species can be kept anywhere that wild pigeons exist, including arid and humid regions. It should be noted, however, that cold climates do not favor squab production and hot climates promote vermin and disease.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The pigeon's natural diet consists mostly of seeds, but includes fruits, leaves, and some invertebrates. Feral pigeons consume a wide array of materials, including insects, bread, meat scraps, weed seeds, and many kinds of spilled grains at mills, wharves, railway yards, grain elevators, and farm fields.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For the first four or five days of life, the young are fed "crop milk." This substance, common to pigeons and doves,2 is composed of cells from the lining of the crop and is very high in fats and nutritional energy. The phenomenal growth rate of young squab has been attributed to crop milk and to its early replacement (within 8-10 days) with concentrated foods, regurgitated by both parents. The parents feed the squab for about four weeks before pushing it out of the nest to prepare for the next clutch.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In domestic birds, sexual maturity (as measured by age at first egg) is reached at 120-150 days. Life span can be 15 years, although growth and egg production decline rapidly after the third year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Wild pigeons often nest on cliff sides. Domestic pigeons prefer to nest around buildings, in nooks and shelves and under the eaves - that is, in "pigeonholes."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In domestic varieties, the pair-bond often lasts until severe illness or death. Sometimes, however, a vigorous male will "invade" a nest and mate with the females there. Both sexes take nearly equal part in nest building, incubation, and caring for the young. Typically, there are two eggs to a clutch. Eight clutches a year is not uncommon for a breeding pair. The incubation period is 17-19 days.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unlike most birds, pigeons drink by inserting their beaks into water and sucking up a continuous draft. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Courtship is characterized by cooing, prancing, and displays of spread, lowered tail feathers. "Bow and coo" exhibitions are unique to pigeons and doves and differ among species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Pigeons are usually raised exclusively for meat. The squab are harvested just before full feather development and before the youngster has started to fly, usually at 21-30 days of age. At this time the ratio of flesh to inedible parts is highest; once flying begins, the meat becomes tougher. Weight depends upon breed, nutrition, and other factors, but usually ranges from 340 to 680 g.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigeons are extensively used for scientific research, notably in physiology and psychology. They are also widely kept as pets for plumage and for racing. The pigeon's unique homing ability was recognized in Roman times, and the birds have been trained to return to the dovecote from as far away as 700 km. Even today, homing pigeons are used to carry messages, especially during war.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Pigeons are easily trained to recognize "home." The wing feathers are clipped and the birds are fed close to the dovecote; by the time they refledge, their homing instinct has been developed. Alternatively, newly captured pigeons may be trained by confining them to the dovecote for at least one week. At first, a little grain is provided in the morning (this is to ensure the birds will return to the coop). The birds can obtain the rest themselves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Any waterproof house that is easy to clean is suitable for keeping pigeons. Many traditional dovecotes are built of earthenware pots. In Asia and Europe, wooden pigeon towers are generally used.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unlike chickens, pigeons do not prefer communal roosts. Instead, they prefer nesting shelves, of which there should be two for each breeding pair. The shelves are usually placed in dark corners and are fitted with low walls to keep eggs from rolling out.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Grit is important in the diet, both to provide minerals and to allow the birds to grind feed in their gizzards.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Commercial squab breeds are often kept permanently in pens, a process that requires care and experience. Growers expect an average of 12-14 squab per pair per year, although much depends on environment and management. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The birds need fresh water daily and water for bathing at least weekly. Since they feed their young by regurgitation, the adults must have a continuous supply of clean drinking water. Orphan squab can be fed egg yolk until old enough to consume adult feeds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like all poultry, confined pigeons must be provided enough supplemental feed to ensure a balanced diet. A mixture of whole grains can be fed for maximum production. It is important that grains be dry and free of mold (pigeons will not thrive on mash). Peas, beans, or similar pulses make good supplements.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CARRIER PIGEONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Most people consider message-carrying pigeons to be a quaint anachronism. But in a few countries (both developed and developing) carrier pigeons are making a comeback, and in the future they may be used routinely once again.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">New techniques are making this process far more practical than before. For example, in the past the pigeons would be flown in one direction only. They were transported away from home and at the appropriate time released to find their way back. That was very limiting. But it has since been found that pigeons can be trained to carry messages in two directions: flying from one point to another and then back again. They will do it twice a day, and with almost perfect reliability. The key is to place the feeding station at one end and the nest at the other. This limits the pigeon's range, but they still can handle round-trip distances up to 160 km.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With a little ingenuity, there is no need for a person to monitor the stations to receive the messages as the bird arrives. One simple technique is to arrange the station with one-way doors - one opening inwards, the other outwards. Placing a bar across the outward door means that the bird cannot get out until someone releases it. Thus the message can always be retrieved.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This system has been employed in Puerto Rico and Guatemala, but it could be used almost anywhere. In many parts of the Third World, in particular, there are remote areas with no phones and with hilly, rough terrain where delivering messages can take hours of strenuous travel. Some locations are subject to unexpected isolation by natural calamities or military or terrorist actions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Puerto Rico, for instance, we kept pigeons in a village 32 km from the capital. The pigeons could get downtown in 20-30 minutes. It took us 1.5-2 hours each way by road. What was easy for the birds was a major trip for us. Pigeons carried the villagers' requests for certain foods and medicines. Our contact in the city then sent up the supplies by bus. The birds never let us down.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Carrier pigeons are useful for more than just flying far and fast. They have been bred for racing and their large pectoral muscles make them excellent meat producers - much better than the common pigeons normally raised for food. A pair of carriers typically will raise 12 - 16 young each year, and those not needed for message carrying can be butchered at 28 days of age - yielding meat that is nutritious and considered a delicacy in many countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">David Holderread</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Every day on the northwest coast of France, Petit Gendamme, a black and white carrier pigeon, flies on average 23 km between hospitals on his blood delivery route. Trussed in tiny hand-sewn harnesses, he and a flock of carrier pigeons set out (except during the hunting season) with little red tubes of blood secured to their breasts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">"It's a simple, effective, and cost-saving transport system," said Yves Le Henaff, head of the Avranches Hospital laboratory, Cotentin, France, a central blood-testing center that serves a number of isolated medical centers along the coast.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The service becomes particularly valuable during the summer tourist rush, when travellers flock to the seashore to visit nearby Mont Saint Michel, crowding the small country roads and increasing the risk of traffic accidents.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The birds' average flight time between the hospitals of Avranches and Granville, for example, a distance of about 27 km, is 20 minutes, including the time for harnessing up. And with a favorable western wind their best time can reach 11 minutes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While gasoline costs the equivalent of $0. 75 a lifer in France, hospital officials say that a few grains of corn is all it takes to run this operation. According to Le Henaff, who supervises the carrier pigeon operation, the hospital is saving up to $46 a day on gas and auto maintenance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 40-year-old Le Henaff got the idea five years ago from an article in a scientific journal describing a similar experiment in Britain. A year later, he and an associate called on the local seamstress to design a light harness that could hold a tube, which, when filled, weighs approximately 39 g.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The flock now consists of 40 veteran fliers and 20 carrier pigeons in training.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">And what if the winged creatures stray en route? Le Henaff has devised a fall-back option: two pigeons carry two different test tubes containing the same blood sample.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The birds fly every day of the year with the exception of the three-month autumn hunting season. Since the beginning of the experiment four years ago, there have been two casualties. Le Henaff believes the birds probably met their fate in some Normand's oven.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sometimes weather is a factor, and heavy fog can keep the delivery team grounded.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So far, the new job seems to benefit the pigeons, too. Unlike sickly city pigeons, whose average life span is about four years, well-cared-for carrier pigeons can live up to 15 years, Le Henaff said. "And how many people do you know who are willing to stay with the same outfit for that long?"</P>
+<P ALIGN="JUSTIFY">Sabine Maubouche</P>
+<P ALIGN="JUSTIFY">The Washington Post</P>
+<P ALIGN="JUSTIFY">December 2, 1986</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Under extensive conditions - where the birds are released each day to feed themselves - almost no land is needed. Under intensive conditions, where the birds spend their lives in confinement, a mere half hectare can be enough space to raise 2,000 pairs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Free-ranging pigeons forage over a wider area than most domestic fowl because they fly out to find their feed. Nutrient requirements3 are similar to those of chickens and other fowl (making allowance for the energy needed for flying), so commercial feed and other supplements - if needed at all - are generally available.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In dovecote culture, pigeons require little or no handling. They brood the young with little intervention. Although not continuous, the production of meat from these fast-growing, rapidly reproducing birds is more sustained than with most livestock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Almost nowhere are there taboos against consuming pigeon meat. Prices received for squab are normally high, and in most places the demand is constant. The only limitation in some areas is the absence of an effective market, which is usually easy to create.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Squab contains a larger proportion of soluble protein and a smaller proportion of connective tissue than most meats and is therefore good for invalids and people with digestive disorders.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As many hobbyists can testify, raising pigeons can be gratifying.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Pigeons are subject to few diseases. However, worms, lice, diarrhea (coccidiosis), canker (trichomoniasis), and salmonella (paratyphoid) occur at some time in most domestic breeds. Salmonella exists in low levels in most flocks and will flare up if birds are stressed. Treatments recommended for domestic chickens are usually suitable for pigeons. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By flying over a wide area and eating grains and other foods, pigeons can cause conflicts with farmers. Indeed, in the 13th century the aristocracy's pigeons became a major grievance of the peasants who saw their seed devoured. On the other hand, "croppers" (breeds with large crops) were developed to steal grain from the lord's fields. The pigeon returned home and his crop was emptied of the grain, which was used by the peasant to make bread.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The birds can become nuisances. They leave droppings in annoying places, some people find them too noisy, and a few people are severely allergic to "pigeon dust."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Every conceivable type of predator can be expected; therefore, precautions must be taken. The dovecote must be well protected against rats, which are the principal enemy of the eggs and the squabs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nesting birds need a high-protein diet to raise squab at the high rates of gain that are possible.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Poultry researchers should study the increased role pigeons might play in Third World economic development. Nothing comparable to the sophisticated selection employed with the domestic chicken has so far been attempted. Given such attention the gains could be great.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Among pressing research needs are:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">- Breeding. This needs to be better understood. For example, the effects of hybridization and inbreeding need clarification.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Environmental limits. Little work has been done outside the temperate regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Diseases. These deserve increased attention.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">There is also the potential of "dovecotes" for wild pigeons. Numerous local species are well adapted to local conditions, and these deserve to be tested for "domestication."4 Many wild species quickly lose their fear of man, and in time they can even become too fat to fly. Wild pigeons are already found throughout the humid tropics and are trapped for meat and rearing in New Guinea and other places. They are already an important food source for many subsistence farmers and shifting cultivators, and with some dovecote management could provide a greater, more dependable source of food and income. The potential for domesticating local pigeon species, especially those suited to the tropics, deserves exploration. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">11 Quail</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g014a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Native to Asia and Europe, quail' (Coturnix coturnix2) have been farmed since ancient times, especially in the Far East. They reproduce rapidly and their rate of egg production is remarkable. They are also robust, disease resistant, and easy to keep, requiring only simple cages and equipment and little space. Yet they are not well known around the world and deserve wider testing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Quail are so precocious that they can lay eggs when hardly more than 5 weeks old. It is said that about 20 of them are sufficient to keep an average family in eggs year-round. Quail eggs are very popular in Japan, where they are packed in thin plastic cases and sold fresh in many food stores. They are also boiled, shelled, and either canned or boxed like chicken eggs. Quail eggs are excellent as hors d'oeuvres and they also are used to make mayonnaise, cakes, and other prepared foods.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In France, Italy, the United States, and some countries in Latin America (Brazil and Chile, for example) as well as throughout Asia, it is the meat that is consumed. It is particularly delicious when charcoal broiled. One company in Spain annually processes 20 million quail for meat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many of the domesticated strains seem to have originated in China, and migrating Chinese carried them throughout Asia. Today, millions of domestic quail are reared in Japan, Indonesia, Thailand, Taiwan, Hong Kong, Indochina, Philippines, and Malaysia, as well as in Brazil and Chile. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Commercial production is carried out, as in the chicken industry, in specialized units involving hatcheries, farms, and factories that process eggs and meat. However, quail have outstanding potential for village and "backyard" production as well. It is this aspect that deserves greater attention.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Worldwide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Quail come in various sizes. The smaller types are used for egg production, whereas the larger ones are better for meat. Adult females of improved meat strains may weigh up to 500 g. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are several color varieties. However, mature females are characterized by a tan-colored throat and breast, with black spots on the breast. Mature males, which are slightly smaller than females, have rusty-brown throats and breasts. All mature males have a bulbous structure, known as the foam gland, located at the upper edge of the vent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the United States, the Pharaoh strain is the bird of choice for commercial production. Other available strains tend to be bred more for fancy than for food.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Quail eggs are mottled brown, but some strains have been selected for white shells. These eggs are often preferred by consumers and are easier to candle (the process of holding eggs up to a light to check for interior quality and stage of incubation). An average egg weighs 10 g - about 8 percent of the female's body weight. (By comparison, a chicken egg weighs about 3 percent of the hen's body weight.) Quail chicks weigh merely 5-6 g when hatched and are normally covered in yellowish down with brown stripes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The ancestral wild species is widely distributed over much of Europe and Asia as well as parts of North Africa. Although domestic quail are now available almost everywhere, Japan is probably the world leader in commercial production; quail farms are common throughout its central and southern regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Not endangered. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p149a.png"></center><br>
+ figure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Quail are hardy birds that, within reasonable limits, can adapt to many different environments. However, they prefer temperate climates; the northern limit of their winter habitat is around 38&Yacute;N.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">A quail's diet in the wild consists of insects, grain, and various other seeds. To thrive and reproduce efficiently in captivity, it needs feeds that are relatively high in protein.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The females mature at about 5-6 weeks of age and usually come into full egg production by the age of 50 days. With proper care, they will lay 200-300 eggs per year, but at that rate they age quickly. The life span under domestic conditions can be up to 5 years. However, second-year egg production is normally less than half the first year's, and fertility and hatchability fall sharply after birds reach 6 months of age, even though egg and sperm production continue. Thus, the commercial life is only about a year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crosses between the wild and domestic stocks produce fertile hybrids. Repeated backcrossing to either wild quail or domestic quail is successful.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Only females hatch the eggs and raise the chicks. Males go off and court other females when their partners begin the nesting process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Quail eggs taste like chicken eggs. They are often served hard boiled, pickled, fried, or scrambled. Because of their size they make attractive snacks or salad ingredients. They provide an alternative for some people who are allergic to chicken eggs. On frying, the yolk hardens before the albumen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Quail meat is dark and can be prepared in all of the many ways used for chicken. The two meats are similar in taste, although quail is slightly gamier.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of its hardiness, small size, and short life cycle, quail are now commonly used as an experimental animal for biological research and for producing vaccines - especially the vaccine for Newcastle disease, to which quail are resistant. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many fanciers and hobbyists have also become interested in raising this adaptable species as a pet. Science teachers find it an excellent subject for classroom projects. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">QUAIL IN JAPAN</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In some areas of Japan, quail are widely raised for their eggs and meat. However, Japanese originally valued the quail as a songbird. Tradition has it that about 600 years ago people began to enjoy its rhythmic call. In the feudal age, raising song quail became particularly popular among Samurai warriors. Contests were held to identify the most beautiful quail song and birds with the best voices were interbred in closed colonies. Even photostimulation was practiced to induce singing in winter.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Around 1910, enthusiastic breeders produced the present domestic Japanese quail from the song quail. It was created as a food source and became a part of Japanese cuisine. During World War II it was almost exterminated, but Japanese quail breeders restored it from the few survivors and from birds imported from China. The original song quail, however, were lost. In the 1960s, commercial quail flocks rapidly recovered and Japan's quail population again reached its prewar level of about 2 million birds. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A QUAIL IN EVERY POT: AN OLD DELICACY FINDS A NEW PUBLIC</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">For centuries, quail were considered a great delicacy: a dish that only eminent chefs would cook and diners with an appreciative palate could enjoy. These small migratory birds, which are found in one variety or another throughout the world, were available until recently almost exclusively to hunters in the wild.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But now quail are in danger: in danger of becoming commonplace.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the last few years, quail have gone from being rarefied to a supermarket specialty item. They are on menus in the most elegant restaurants and the most casual cafes and bistros.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Why so much interest?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Quail are now available semi-boneless, which makes them faster and easier to cook, and easier to eat as well. The breastbones are removed by hand before the birds are packaged and shipped to stores. The bones in the wings and legs remain.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A stainless-steel V-shaped pin - invented and patented by a restaurant chef who wanted a way to keep quail flat for grilling is inserted into the breast. The pin can be left there throughout cooking and removed just before serving.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While whole quail might require 45 minutes to cook, the semi-boneless variety can be grilled in less than 10 minutes, or pan-roasted, braised or sauteed in less than 20 minutes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The flavor of farm-raised quail has also helped bring them into the mainstream. Most farm-raised quail have tender meat like the dark meat of chicken, whose flavor is enjoyed by many people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">And at a time when people are searching for foods, specifically animal protein, with low fat and cholesterol, quail fills the bill. The Agriculture Department says that quail skin has about 7 percent fat, about the same as dark meat of roasted chicken without the skin.</P>
+<P ALIGN="JUSTIFY">Judith Banrett Adapted from The New York Times </P>
+<P ALIGN="JUSTIFY">June 21, 1989</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">It is necessary to keep quail in battery cages on wire floors because males secrete a sticky foam (from the foam gland) with their feces; on a solid floor, this adheres to the feet and collects dung, leading to crippling and breakage of eggs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Adult quail can live and produce successfully if they are allowed 80 cm2 of floor space per bird. However, for reproduction about twice that is needed to allow for mating rituals.3 If properly mated, high fertility rates and good egg hatchability can be expected. To obtain fertile eggs, one male is needed for roughly six females.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Eggs hatch in about 17 days. Chicks require careful attention. Brooding temperatures of between 31 C and 35 C  are needed for the first week and above 21 C for the second week. From the second week on, chicks can survive at room temperature. (These temperatures are similar to those required for common chickens.) In cold climates, supplemental heat may be needed as well as protection from cool drafts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Clean water must be provided at all times, with care taken to prevent the chicks from drowning in their water troughs. Shallow trays, jar lids, or pans filled with marbles or stones may be used.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Quail production can be started with little money. These easy-care birds can be housed in small, simple, inexpensive cages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As noted, they are resistant to Newcastle disease.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SIX OF ONE, HALF A DOZEN OF THE OTHER</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The fact that chickens can be crossed with quail has been known for some time, but there has been little attempt to develop the fertile hybrids. Now Malaysia has begun a project aimed at producing a new poultry bird - a cross between a cockerel and a hen quail. Zainal Abidin bin Mohd Noor, of the Department of Veterinary Services in Kuala Lumpur, is creating a strain that produces eggs of good quality and meat with the flavor of both parents. The new bird is intermediate in size between chicken and quail which is convenient because it is about right for an individual helping.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The crossbreeding is done through artificial insemination. The progeny exhibit a range of appearances, sizes, and plumage colors, depending on the strains of cockerel and quail hens used. In the Malaysian research, cockerels have been local Ayam Kampung Bantam, Hybro, and Golden Comet hybrids. The quails have been local inbred Japanese quail (IJQ) and imported meat strain quail (IMSQ).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The trials show that the hybrids derived from the IMSQ flocks grew faster and bigger than those from the IJQ cross. The best have been the Hybro x IMSQ crosses, which weigh 475 g at 10 weeks of age. The best of the IJQ group weighed 290 g during the same period.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This type of "tropical game hen" might be a way to introduce hybrid vigor into poultry production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The researchers who developed the hybrid have named it the "yamyuh." </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Although generally disease resistant, quail are affected by several common poultry diseases, including salmonella, cholera, blackhead, and lice. They also suffer epidemic mortality from "quail disease" (ulcerative enteritis), which can, however, be controlled with antibiotics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Quail seem to require more protein than chickens, and produce best when given feed that is fairly high in protein.4 However, they also perform satisfactorily when fed rations designed for turkeys. They have high requirements for vitamin A, which they do not store.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Quail are not suitable as free-ranging "scavengers." They must be kept confined, which is a major constraint. Unlike chickens or pigeons, they have no homing instinct and will not remain on a given site; if released, they will be lost. In addition, since they nest on the ground, they are highly susceptible to predation; they must be protected, especially where certain animals, the mongoose for example, are common.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Artificial incubation is essential. Natural incubation using the female is futile; the females do not go broody and rarely incubate their eggs. The shells are extremely thin, but the eggs can be incubated under a small chicken hen, such as a bantam.5 The eggs are also subject to minute fractures. However, the shell membrane is extremely tough and unfertilized eggs are generally unaffected, but the cracks cause fertilized embryos to dehydrate and die. This is a serious limitation. Whenever quail husbandry is introduced, artificial incubation should be included.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Quail deserve to be included in all poultry research aimed at helping the Third World. Through its international scientific program, Japan, in particular, could apply to developing nations its vast experience with quail farming.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Experiences with quail in the tropics (for example, Japanese farmers in the Amazon Basin) and in tropical highlands (for instance, in India, Nepal, or Central Africa) should be collected and assessed to improve understanding of the environmental limits to Third World quail farming.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cooperation between commercial and laboratory quail breeders should be encouraged. Mutants found at the commercial level would be useful for laboratory work. Conversely, introducing new stocks could help the farmer. In both cases, more genetic diversity might also lead to the production of hybrid vigor, and genetic variability would be conserved.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sex-linked genes, if they can be found, would be useful to the commercial quail breeder for the rapid sexing of newly hatched chicks. This could lead to more efficient production techniques, like those in the chicken industry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although virtually all work to date has been on the Japanese quail, other species and subspecies warrant research and testing. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">12 Turkey</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g015a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The turkey (Meleagris gallopavo) is well-known in North America and Europe, but in the rest of the world, especially in developing countries, its potential has been largely overlooked. Partly, this is because chickens are so familiar and grow so well that there seems no reason to consider any other poultry. Partly, it is because modern turkeys have been so highly bred for intensive production that the resulting birds are inappropriate for home production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nevertheless, there is a much wider potential role for turkeys in the future. There are types that thrive as village birds or as scavengers, but these are little known even to turkey specialists. These primitive types are probably the least studied of all domestic fowl; little effort has been directed at increasing their productivity under free-ranging conditions. However, they retain their ancestral self-reliance and are widely used by farmers in Mexico. That they are unrecognized elsewhere is a serious oversight.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Native to North America, the turkey was domesticated by Indians about 400 BC, and today's Mexican birds seem to be direct descendants.' Unlike the large-breasted, modern commercial varieties, they mate naturally and they retain colored feathers and a narrow breast configuration. Their persistence in Mexico after 500 years of competition with other poultry highlights their adaptability, ruggedness, and usefulness to people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These birds complement chicken production. They are able to thrive under more arid conditions, they tolerate heat better, they range farther, and they have higher quality meat. Also, the percentage of edible meat is much greater than that from a chicken. Turkey meat is so low in fat that in the United States, at least, it is making strong inroads into markets that previously used chicken exclusively. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Turkeys are natural foragers and can be kept as scavengers. Indeed, they thrive best where they can rove about, feeding on seeds, fresh grass, other herbage, and insects. As long as drinking water is available, they will return to their roost in the evening.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appreciation for the turkey could rise rapidly. Interest already has been shown by several African nations. A French company has created a strain of self-reliant farm turkeys and is exporting them to developing countries.2 Researchers in Mexico are displaying increased interest in their national resource. And as knowledge and breeding stock continue to be developed, it is likely that village turkeys will become increasingly popular around the world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Worldwide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Modern turkey breeding has been so dominated by selection for increased size and muscling that commercial turkeys have leg problems and cannot mate naturally (they are inseminated artificially). These highly bred birds are adapted for large-volume intensive production, and must be raised with care. As noted, this chapter emphasizes the more self-reliant, less highly selected turkeys found in Mexico and a few other Latin American countries. They do not require artificial insemination, and with little attention can care for themselves and their young.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fully grown "criollo" turkeys of Mexico are less than half the size of some improved strains. Males weigh between 5 and 8 kg; females, between 3 and 4 kg.3 They vary in color from white, through splashed or mottled, to black. The skin of the neck and head is bare, rough, warty, and blue and red in color. A soft fleshy protuberance at the forehead (the snood) resembles a finger. In males it swells during courtship. The front of the neck is a pendant wattle. A bundle of long, coarse bristles (the beard) stands out prominently from the center of the breast.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The unimproved domestic turkey is essentially limited to central Mexico and scattered locations throughout nearby Latin American countries. Some village birds are also kept in India, Egypt, and other areas, but these are descended from semi-improved strains exported from North America and Europe in earlier times. Generally speaking, few turkeys are found in tropical countries outside Latin America.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Domesticated turkeys are not endangered; there are estimated to be about 124 million in the world. However, the wild Mexican varieties, ancestors to the first domesticated turkeys sent to Europe, may now be endangered since their distribution in southwestern Mexico has been greatly reduced. Certainly, some primitive domestic strains in the uplands of central Mexico are also being depleted. A separate type, independently domesticated by the Pueblo Indians of the southwestern United States, seems to have disappeared entirely.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Turkeys can be reared virtually anywhere. Their natural habitat is open forest and wooded areas of the North American continent, but in Mexico they are raised from sea level to over 2,000 m altitude, from  rainforest to desert, and from near-temperate climates to the tropics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p159a.png"></center><br>
+ The original distribution of the turkey and the occellated</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The range of diet is broad. Turkeys eat greens, fruits, seeds, nuts,  grasses, berries, roots, insects (locusts, cicadas, crickets, and  grasshoppers, for example), worms, slugs, and snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Reproduction is generally seasonal and is stimulated by increasing  daylength. (A minimum daylength of 12 hours is required.) The birds  can reach sexual maturity at six months of age and may start breeding at  this time. Ten days after first mating, the hen searches out a nest and  commences laying. Industrial birds in temperate climates lay, on  average, 90 eggs a year. The nondescript type of turkey in the tropics  seldom lays more than 20 small eggs (weighing about 60 am) before  going broody.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Domestic turkeys walk rather than fly, and find almost all their food  on the ground. They can, however, fly short distances to avoid  predators.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The commercial birds have lost many abilities for survival in the wild;  they can no longer exist without human care. However, village types  can do well with little management.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Turkeys prefer to make their own nests but can be induced to lay in a  convenient spot if provided with nest boxes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These birds are raised almost exclusively for meat. In many countries,  they are a treat for holidays, birthdays, and weddings. In their native  range of Mexico and Central America, the "unimproved" birds are  usually produced as a cash crop for market. They receive little care or  feed, and thus they are almost all profit - providing a significant income  supplement to many rural homes.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The principles of turkey management (nutrition, housing, rearing' and prevention of disease, for example) are basically the same as those for other poultry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Mexico, turkeys are usually kept under free-ranging conditions around houses and villages. Some shelter and kitchen scraps are occasionally provided. A number of them, however, are confined in backyards as protection from marauders and for shelter against rain and wind.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One male can service up to 12 females. Roomy nests are needed. (As a rule, turkeys require three times the space occupied by chickens.) Most range turkeys are corralled when they begin to lay, so as to protect them from predators. Eggs may be gathered to prevent broodiness and thereby increase production. The eggs may be kept for several days (cool, but not refrigerated) if turned daily, and then may be placed under a chicken hen. (A setting chicken can be used this way to hatch up to nine eggs at a time.) Hatching takes 28 days.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As in other birds, newly hatched turkeys (poults) must be kept warm during the first weeks of life. Until they begin foraging and have full access to pasture they are usually fed broken grain or fine mash, as well as finely chopped, tender green feed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although free-ranging turkeys are simple to raise, confined turkeys require more complex management. The birds need uncrowded, well ventilated conditions and should be on a wire or slatted floor to reduce parasitic infections. Any feeds recommended for chicks are suitable, but the protein content should be somewhat higher; that is, about 27 percent. They can be fed mixed grains, corn, and chopped legume hay. It may be necessary to provide vitamin supplements and antibiotics and take steps to prevent coccidiosis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">"AN INCOMPARABLY FINER BIRD"</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The turkey was domesticated in Mexico some time before the Conquest. It is the one and only important domestic animal of North American origin. When the Spanish arrived, they found barnyard turkeys in the possession of Indians in all parts of Mexico and even in Central America. However, the Aztecs and the Tarascans, originating in west-central Mexico, seemed to have achieved the highest development of turkey culture, and it is probable that turkeys were domesticated in the western highlands, perhaps in Michoacan. Wild turkeys of that region are morphologically very similar to the primitive domestic bronze type. Both the Aztecs and Tarascans kept great numbers of the birds, including even white ones. They paid royal tribute to their respective kings in turkeys, according to the Relacion de Michoacan. The Tarascan king fed turkeys to the hawks and eagles in his zoo. The economy of some highland tribes was based on the cultivation of corn and the raising of turkeys.</P>
+<P ALIGN="JUSTIFY">A. Starker Leopold</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE INDUSTRIAL TURKEY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The modern domesticated turkey is thought to be descended from two differing wild subspecies, one found in Mexico and Central America and the other in the United States. The southern type is small, whereas the U.S. native is larger and has a characteristic bronze plumage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mexican turkeys were exported to Europe soon after the Conquest, and spread rapidly. In the 17th century, some were returned to North America, where they interbred with the eastern subspecies of wild turkey, producing a heavier bird, which was then re-exported to Europe.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These types underwent little change until this century, when the Englishman Jesse Throssel bred them for meat quality. In the 1920s, he brought his improved birds to Canada, where their large size and broad breasts quickly made them foundation breeding stock. Crossed with the narrow-breasted North American types, these heavily muscled meat birds quickly supplanted other varieties.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">About the same time, the U.S. Department of Agriculture began the scientific development of a smaller meat turkey derived from a more diverse genetic base. By the 1950s, the Beltsville Small Whites predominated in the home consumption market in the United States.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The birds are efficient and generally take care of themselves. They tolerate dry, hot, or cold climates and forage farther than chickens. They are large, fast growing, highly marketable, low in fat, and tasty. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE TURKEY'S TROPICAL COUSIN</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The ocellated turkey (Agriocharis ocellata) occurs in Yucatan, Guatemala, and Belize. It is much like the common turkey in size, form, and behavior: however, unlike the common turkey, which in Mexico lives in the high mountain pine and oak forests, the ocellated turkey inhabits bushy, semiforested lowlands. This splendid bird lacks the kind of beard sported by the common turkey gobbler, is generally more metallic in appearance, and has brighter coppery colors. The chief character is a neck and head that are bare, blue, and profusely covered with coral-colored pimples. It also has a yellow-tipped protuberance growing on the crown between the eyes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This species is worthy of investigation by poultry researchers because it might prove to be domesticable. It was possibly domesticated by the Mayas, whose ruins often include appropriately sized stone enclosures whose soil has elevated levels of phosphorus and potassium. Even today, in the rural Peten area of Guatemala, ocellated turkeys are sometimes kept around houses as scavengers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Young birds are readily affected by temperature changes and must be protected from the sun as well as from sudden chills, such as may occur at night. They are particularly susceptible to dampness, especially if associated with cold. One peculiarity is the turkey's aversion to any change in feeding routine or the nature of the food.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Young turkeys are susceptible to parasitic infestation as well as to the same type of bacterial and virus diseases as chickens (for example, fowlpox and coccidiosis). Blackhead, a devastating disease of young turkeys, is carried by a common parasitic nematode, and can be contracted from chickens. Medicines are available to prevent or treat most disease and pest problems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Turkey development is almost nonexistent in the Third World (and much of the rest of the world, too). Although commercial turkeys are highly developed in some countries, little or no research has been conducted on the criollo turkey. Research on physiology, disease, and husbandry of the criollo turkey should be given high priority.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The need for conservation of genetic variability is perhaps more critical in this species than in almost any other domesticated animal. The unimproved types in Mexico should be collected and assessed, and a program to conserve the stocks should be initiated. An analysis should also be made of the traditional management and performance of these birds. In addition, the four or five recognized turkey subspecies should be evaluated for their potential as seed stock for Third World countries. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">13 Potential New Poultry</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g016a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Several preceding chapters have discussed the possibilities of domesticating certain wild birds.l Here, briefly, are highlighted other wild species with qualities that might make them suitable for sustained production. It should be understood that their practical use in the long run is pure speculation; they are included here merely to guide those interested in exploring the farthest frontiers of livestock science.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Collectively, poultry have become the most useful of all livestock and the most widespread. Yet only a handful of species are employed. Of the 9,000 bird species, only a few (for instance, chickens, ducks, geese, muscovies, pigeons, and turkeys) have been domesticated for farm use. Strictly speaking, all birds are edible - at least none have poisonous flesh - so it seems illogical to conclude that these are the only likely candidates. Perhaps they are not even the best.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At first sight there may seem to be little need for new species, but poultry meat is in ever increasing demand and there are many niches where the main species are stricken by disease, or are afflicted by heat, humidity, altitude problems, or other hazards. For these areas, a new species might become a vital future resource. Perhaps some could even become globally important. The modern guinea fowl, for example, is a relative newcomer as a worldwide resource (see page 120).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The birds now used as poultry were domesticated centuries ago by people unaware of behavior modification, nutrition, genetics, microbiology, disease control, and the other basics of domestication. Today we can tame species that they couldn't. In particular, the new understanding of "imprinting" may make the domestication of birds easier today than ever before. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this highly speculative concept, the birds described on the following pages are worth considering. They all eat vegetation and tend to live in flocks, which makes them likely to be easy to feed and to keep in crowded conditions. Most are sedentary, nonmigratory, and poor fliers. All but three (tinamous, sand grouse, and trumpeters) are gallinaceous.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gallinaceous birds are already the most important to people. The best known are chickens, turkeys, quail, and guinea fowl. But there are about 240 other species. Most are chickenlike: heavy bodied with short, rounded wings, and adapted for life on the ground. Although some are solitary, many are sociable. Basically vegetarian, they also eat insects, worms, and other invertebrates. The young birds are extremely precocious, walking and feeding within hours of hatching. All of these are advantageous traits for domestication.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Game birds are also emphasized here. Many today are considered gourmet delights, and this should give them a head start in the marketplace. Indeed, some are already being raised in a small way on game farms and are at least partly on the way to domestication.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CHACHALACAS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These brownish birds (Ortalis vetula and nine other species) are found throughout Central and South America, and, given research, could possibly be raised on a large scale. A sort of "tropical chicken," they tame easily, live together in dense populations, and protect their chicks extremely well. They commonly scavenge around houses and people often put out scraps to feed them.2 The chicks are easily hatched, grow fast, and can be fed standard chicken rations.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is already considerable demand for these birds. Everywhere they are found, they are prized as food. In some areas they constitute the single most important game species, and are heavily hunted to supply local communities. Although they have less meat than a chicken, it is tastier and darker.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chachalacas are very adaptable. They occur mainly around forest edges and thrive in the thickets that appear after tropical forests have been felled. They do well close to humans, and their populations are not threatened, despite much hunting. Indeed, they seem well adapted to existence around villages and towns. Although not strong fliers, they are one of the few tree-roosting gallinaceous species. Primarily fruit eaters, they also consume tender leaves, twigs, and buds, and they scratch up the ground, presumably for insects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although excitable and noisy, chachalacas become remarkably tame when fed by people. In a few cases, full domestication has almost been reached. Farmers like to have chachalacas around and have even used them to guard domestic chickens. These very raucous and fearless birds will take on all potential threats, even weasels.4</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GUANS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Close relatives of the chachalacas, guans5 are glossy black birds about the size of small geese. They are highly gregarious and perhaps could be raised in larger numbers. They commonly live around houses, farms, and settlements in their native region of tropical America.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unlike most game birds, guans are chiefly tree dwellers, but they also feed on the ground. Some 12 species are known. All are relentlessly hunted for food and sport - their tameness and inability to fly far or fast making them easy targets. The rapid destruction of tropical forests threatens their populations in some parts of their range. Conservation projects and specific plans of action are being proposed for the most threatened species. Perhaps for the other species, game-ranching projects or even outright domestication might provide just the right incentive for their protection and multiplication.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CURASSOWS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Curassows are also relatives of guans and chachalacas, but they are even larger - up to 1 m tall and 5 kg in weight. At least seven species are found over the vast area from northern Mexico to southern South America.6 Among them are Latin America's finest game birds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It might be possible to produce curassows in organized farming or ranching. They are commonly called "tropical turkeys" because they look like and run like turkeys. Indeed, Latin Americans normally refer to them as "pavos" or "pavones," as if they were the real thing. Their plumage ranges from deep blue to black, invariably with a purple gloss, and all have rather curly crests on their heads. They are not good fliers and spend most of their time on the ground.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Curassows are increasingly hunted; their tropical forest habitat is shrinking, and the subsequent loss of populations is a calamity. They are special targets, not only because they are large but also because their light-colored flesh makes exceptional eating.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is hope that these large wild fowls can be raised and managed in organized programs. Even now, people commonly keep them around their farms and villages. For example, on a number of Venezuelan ranches, yellow-raped curassows can be seen wandering around the cattle yards as if they were chickens.7</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FOREST BIRD RANCHING</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">This report has intentionally focused on intensive farming - the type where people bring feed to animals in captivity. However, where this normal type of farming is of marginal value, `'ranching'' free-ranging birds may often be a more effective option. In this, the farmer simply monitors and improves the condition of the range and devises methods to harvest the birds on a sustainable basis. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">"Bird ranching" may today have outstanding merit, particularly in tropical rainforests. Hence, in this chapter we emphasize birds of the jungle. These might help make standing rainforests profitable producers of income, and thereby provide economic incentives to stop felling trees for cow pastures. Indeed, forest birds might become part of a whole new "salvation farming'' that makes forests more valuable than fields. It is a technique that may contribute to preserving both bird life and its vitally valuable habitat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MEGAPODES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Megapodes (family Megapodiidae) include some of the world's most interesting birds. They have temperature-sensitive beaks and employ nature's own heat sources as incubators. The best-known species build piles of leaves and use the heat of decomposition to incubate their eggs. The species of Papua New Guinea and Indonesia, however, take advantage of sun-warmed sand or even geothermal activity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">People have long revered these birds. Aborigines in Australia, Melanesians in New Guinea, and many Micronesians all protect the bizarre nesting sites, and "farm" them for eggs. Local people consider the large eggs special delicacies, and sometimes the egg-laying sites are owned and exploited for generations without a single bird being killed for food.8</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Programs that provide sustainable supplies of eggs have been established in Papua New Guinea. One is near Mt. Tovarvar, a simmering volcano on the island of New Britain. Here, megapodes gather in large numbers to lay eggs in the hot sands. They dig until they locate sand that is exactly 32.7&Yacute;C, before laying their huge (more than 10 cm long and 6 cm wide) pink eggs. Each year the villagers dig up some 2O,OOO eggs, which are an important source of protein and cash income. The government now regulates the harvest in a way that protects the bird population while supplying a nourishing food.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Megapodes are found in only a few parts of the world, but projects such as those in Papua New Guinea provide hope and guidance not only for the sustainable "ranching" of megapodes, but also for other species elsewhere. Many wild birds yield locally important products down, colored feathers, eggs, meat, and skins, and they make excellent songbirds and pets, for example. Their management on a sustainable basis may in certain cases be the key to turning local people into the most dedicated conservationists of all.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PARTRIDGES AND FRANCOLINS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Partridges include many small game birds native to the Old World. They are robust, precocious, and larger than quails. Some lay many eggs - the European partridge, for example, lays up to 26 in a clutch. Newly hatched chicks are soon able to feed themselves and can fly within a few weeks, sometimes even within the first few days.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Species that may make useful poultry include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- The European (or gray) partridge (Perdix perdix); </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- The rock partridge (Alectoris), bantamlike birds of Africa; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- The chukar (A. graeca). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A native of the vast area from southeastern Europe to India and Manchuria, the chukar is stocked as a game bird in many countries. It is now produced routinely under poultrylike husbandry in many parts of the United States, not only for hunting clubs, but also for expensive food markets. The birds are generally raised on turkey rations and dress out at about 500 g after 18 weeks. They sell for more than broiler chickens and are a profitable sideline for increasing numbers of poultry farmers.9</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A group of closely related birds are the francolins (genus Francolinus), of which there are 34 species in Africa and 5 in West and South Asia. These adaptable birds are sturdy, live in a variety of habitats, and tend to be rather noisy. Basically, they are partridges with leg spurs. They are highly regarded as a food source and are hunted and trapped wherever they are found.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Francolins are much like quail, but are several times larger. Arabs introduced one of the most beautiful species (Francolinus francolinus) into southern Spain, Sicily, and Greece during the Middle Ages. However, it was hunted so heavily that it soon became extinct in Europe. More recently, francolins have been introduced to the Soviet Union.'&Yacute;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Francolins inhabit steppes, savannas, primeval forests, and mountains. They thrive in cultivated land with much cover. The clutch consists of 6-8 hard, thick-shelled eggs. In recent times at least one program to domesticate them for food has been started in Africa.11</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MALAYSIA'S MOBILE MOUSETRAP</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Although the report emphasizes microlivestock as food suppliers, it should be realized that small animals - even wild ones - can have other important uses as welt The following interesting example, with possible worldwide implications, comes from recent experiences in Malaysia. *</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Certain rodents are major pests on farms and plantations. Now, however, Malaysian zoologists are finding that owls, particularly barn owls (Tyto alba), can help control them. An owl pair and its chicks annually consume 1,500 or more rodents. This is not new knowledge; indeed, on farms throughout the world the barn owl has always been a welcome guest. What is new is that Malaysians are showing how outstandingly effective this process is, and they have initiated major projects to attract and maintain these feathered friends. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Barn owls are found in many parts of the world, but were formerly almost unknown in Peninsular Malaysia. In 1969, however, a pair began nesting in an oil-palm plantation in Johore State. Since then, these birds have steadily increased in numbers and have spread throughout most of the peninsula. Today, the population is increasing remarkably quickly as more and more managers erect nest boxes for the owls to live in.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The owls are proving to be a good way to remove rats and are notably effective in plantations of oil palm. They perch on fronds and fly under and between the rows of trees. A cost of $1 - $2 per hectare per year is all that is required to install nest boxes, a negligible outlay for the control of such a serious and expensive problem.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is believed that the barn owls hunt mainly in plantations and other agricultural areas and not in the rainforest. Barn owls are, after all primarily adapted to open spaces and not dense forest.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Perhaps this experience can be replicated and adopted in other locations and with other crops. Grain crops - notably rice - are particularly prone to the ravages of rodents, and one trial has commenced in Selangor State in a rice area. The concept of using owls for rodent control is also catching on in the United States. Indeed owl nest boxes are being erected in Central Park in the heart of New York City.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PHEASANTS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">One pheasant, the red junglefowl, gave the world the chicken (see page 86). The other 48 species may have some potential, too. These are rarely seen forest birds; all but one are confined to Asia.13 Because they are prolific they can sustain heavy predation, and many species, notably the ring-necked pheasant (Phasianus colchicus), are constantly hunted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">People in several countries have learned to exploit pheasants on farms and estates. As a result, there is a vast amount of information on how to rear and manage these birds. So far, however, it has been applied only to sport hunting in wealthy societies; the potential of raising pheasants for the mass market should now be seriously addressed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The most dramatic-looking pheasant, the peacock (Pavo cristatus), is raised as a poultry species in Vietnam. The meat of the young birds is considered outstanding. In fine restaurants in New York, a peacock dinner is reputed to cost $150. Common peafowls are considered sacred in many parts of India, where they have become so tame that they are essentially domesticated. They also control snakes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">QUAIL</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Domestic quail have been previously described (page 146)J but dozens of wild quail species and subspecies occupy many different habitats and ecological niches in almost all parts of the world. Out of all this genetic wealth only one species - the Japanese quail - is widely used. Yet many other species seem easy to raise, becoming exceedingly tame after about the sixth generation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The management and even perhaps intensive production of these various local quails might provide long-term benefits for many developing nations. Quail meat ranks among the finest.14 Some of these lesser-studied birds are more meaty than the Japanese quail or have other possibly useful traits. Much is known about rearing a few of them because they are used in sport hunting or laboratory research. The possibility of domestication, therefore, is not farfetched.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Particular quail that might be considered for domestication are the lesser-known subspecies of Coturnix coturnix. These subspecies are found in various places, including the following:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Europe (C. c. coturnix breeds in the area ranging from northern Russia to North Africa and from the British Isles to Siberia. In winter it migrates to tropical Africa, Asia, and southern India.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- The Azores (C. c. conturbans) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- The Azores, Madeira, and the Canary Islands (C. c. confisa) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Cape Verde Islands (C. c. inopinata) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- East Africa (C. c. erlangeri) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Tropical Africa, southern Africa, Madagascar, and Mauritius (C. c. africana) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Japan (C. c. japonica, the most probable ancestor of the domesticated quail)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- China (C. c. ussuriensis, a possible ancestor of the domesticated Japanese quail)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">TINAMOUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Tinamous are quail-like birds of Central and South America's forests and grasslands. They are, however, much larger than quail and resemble small chickens, with plump bodies and no visible tail. There are more than 40 species, and all are much sought for food because their meat is tender and flavorful. The breast is surprisingly large, and its flesh is pale and translucent. One species, the great tinamou (Tinamus major), has been called "the most perfect of birds for culinary purposes." Frozen tinamous from Argentina were formerly sold in the United States under the name "South American quail."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tinamous are found mainly in tropical areas, but are also widely distributed in Argentina and Chile. They dwell in varied habitats: rainforests, thickets, bushlands, savannas, and grasslands up to 5,000 m altitude in the Andes. Some species sleep in trees, others on the ground. They spend their days creeping about in heavy cover, flying only when forced.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At least some species tame readily. Indeed, during the nesting period males become so tractable that they can be picked up off the nest. At the turn of the century, many tinamous were raised as game birds in France, England, Germany, and Hungary. However, for reasons unknown, subsequent attempts to settle them in Europe have failed. Tinamous have been raised in Canada without undue difficulty; they showed little or no stress under captivity and there were few losses.15</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tinamous may also prove suitable for egg production. They lay clutches of 16-20 spectacular-looking shiny eggs that seem to be made of sky-blue and bright-green ceramic.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SAND GROUSE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Sand grouse (mainly Pterocles species) are highly adapted to life in arid regions - desert, dry grasslands, arid savanna, and bushveld. Their entire body (including most of the bill and feet) is covered with dense down, which in the desert insulates them from the burning heat of midday and the freezing cold of night. It also protects the nostrils against blowing sand and dust.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These pigeonlike birds are found throughout the drier regions of Africa and Asia - for instance, the Sahara, Kalahari, Namib, Arabian, and Thar deserts. They live mainly on small seeds, and sometimes flocks of thousands may be seen at waterholes, flying in for a drink from up to 80 km away. For peoples of the driest spots on earth, these birds may make a useful food species: for one thing, they are not endangered. Indeed, they are proliferating as drought and overgrazing is increasing the amount of dry, desolate rangeland that they prefer. The bore holes provided for livestock have both boosted their populations and afforded a place where these wide-ranging birds can be easily captured. When nesting, sand grouse are highly vulnerable to foxes, jackals, mongooses, and other predators. Protection of the nesting sites may be the key to maintaining their populations if harvesting schemes are introduced.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">TRUMPETERS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Trumpeters (Psophia species) might prove to be a useful species for sustainable production within tropical forests. As "tree poultry," these relatives of cranes could help provide meat without destroying the trees, as is now done to raise cattle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These chicken-sized birds inhabit South America's jungles.16 They are nonmigrating, ground-dwelling, and are often kept as pets, notably by Amerindians. Under human protection, trumpeters become very tame. They recognize strangers and challenge them with a loud cackle. 17 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fully adapted to the forest environment, they can run fast, but fly poorly. In the wild, this makes them easy targets for hunters. Because of this and the fact that they make excellent eating, they are approaching extinction in some areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">No attempts have been made to rear these birds in numbers, but this should be tried. They feed mainly on plant materials, particularly berries of all kinds. They also relish grasshoppers, spiders, and centipedes, and are particularly fond of termites.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Trumpeters require trees; they completely avoid cultivated land. Thus, as the destruction of forests in South America continues, their habitat is shrinking. Although their existence is not as yet threatened, the long-term prognosis is bleak. If managed in "forest-ranching" programs, however, they might be saved from extinction and thriving populations built up. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Interest in rabbits continues to increase. It is now widely recognized that the raising of small animals in developing countries has great potential as a means of improving human nutrition and economic security. The famines in Africa, Latin America, and Southeast Asia starkly illuminate the need for maximum efficiency in food production to maintain the quality of human life. Rabbit raising contributes to meeting these needs.</P>
+<P ALIGN="JUSTIFY">P.R. Cheeke, N.M. Patton, S.D. Lukefahr, and J.I. McNitt Rabbit Production </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rabbits are especially well adapted to backyard rearing systems in which capital and fodder resources are usually limiting factors in animal production. When rabbits are reared according to the techniques appropriate to the environment they can do much to improve the family diet of many of the most needy rural families, while at the same time supplying them with a source of income. With more advanced technology rabbit production can also help to supply big city meat markets.</P>
+<P ALIGN="JUSTIFY">Food and Agriculture Organization The Rabbit: Husbandry, Health, and Production </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g017a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Part III : Rabbits</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Contrary to popular opinion, the domestic rabbit is a substantial part of the world's meat supply. Annual production of rabbit meat is estimated to be one million metric tons, and the total number of rabbits is approximately 708 million.' However, rabbits are now intensively raised for food only in temperate, mostly industrialized, nations. France, Italy, and Spain, for example, have long consumed rabbit meat; West German production was 20,000 tons each year; Hungary raises rabbits in large numbers (two of its commercial rabbitries have more than 10,000 does each); and the United States raises almost 8.5 million rabbits each year for consumption in homes and restaurants.2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In most developing countries, on the other hand, rabbits are not well known - at least compared with other livestock. But they have great promise there, and in recent years there has been a dramatic increase in interest. For those developing countries where information is available, rabbit meat production almost doubled between 1966 and 1980. For instance, several African countries - among them Ghana, Kenya, Malawi, Mauritius, Mozambique, Nigeria, Sudan, Tanzania, Togo, and Zambia - now have national rabbit-raising programs. A number of Asian countries - such as the Philippines, Indonesia, India, and Vietnam - are also encouraging rabbit farming. And some Latin American countries - Mexico, Costa Rica, and El Salvador, for instance - are actively promoting rabbits for subsistence farmers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ghana is also extensively promoting rabbit farming. Although able to produce all the cereals its population needs, it cannot produce enough meat to satisfy demand. In response, the government organized "Operation Feed Yourself." The National Rabbit Project was created </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hares</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The common hare (Lepus europus) has not been domesticated, but it is nevertheless a major cash crop of several countries. In Argentina, for example, there is a booming, million-dollar enterprise that exports hundreds of thousands of carcasses, mainly to Germany where they are sold as game meat. For Argentine campesinos, many of whom have few sources of livelihood, trapping hares provides a vital income. In New Zealand, too, hare has become an export item.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A closely related species (Lepus capensis) is native to Africa, and perhaps could be "ranched in the same fashion.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rainforest Rabbit</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The forest rabbit, or tapeti (Sylvilagus brasiliensis), is commonly eaten in its native habitat, which extends from southern Mexico to southern Brazil. It occurs in various hot and humid areas of Central and South America and probably within the Amazon Basin itself. Thus, this creature seems a possible candidate for a "tropical rabbit" that can be raised under sweltering conditions, perhaps even in rainforest regions. Although it seems to be heat resistant, it has an especially fine fur.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Little is now known about the tapeti. It is rather secretive and its natural history and even its range are still uncertain. However, its populations appear stable and it is not threatened with extinction. It produces litters of 1 - 5 young after a 44-day gestation, and may bear 4 litters a year. This may seem a lot, but compared with other wild rabbits, the litter size is small and the gestation period long. under this program to provide farmers with breeding stock and practical information on rearing rabbits. (To qualify for the purchase of new breeding stock, would-be rabbit raisers are required to take an intensive three-day course in rabbit husbandry, which is provided at no charge.) With both official and popular support, the rabbit's potential for Ghana has been enhanced through media campaigns complete with radio jingles (examples: "Get the bunny money!" "Grow rabbits - grow children." "Get into the rabbit habit!"), television spots, and large posters. Already, rabbit breeding is included in school curricula and rabbit meat is available in school lunches.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other countries have mounted similar campaigns. In Mexico, for instance, teachers raise rabbits in rural schools as a way of training students; scores of government officials have taken to breeding rabbits in their homes; and several army units are raising rabbits as mess-hall substitutes for costly beef, pork, and chicken. In Nigeria, farmers can now acquire rabbits from 18 government rabbit-breeding centers, which distribute thousands of animals each year. In Costa Rica, the government has similarly established a series of breeding, distribution, and rabbit-farming training centers. And in El Salvador, the technology of rabbit production is being transferred to farmers via the army.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although rabbits are ideal microlivestock in a general sense, rabbit rearing has many problems and limitations. Poor management is a common difficulty. Unlike the traditional method of keeping scavenger animals, rabbits have to be contained and cannot be left to find their own food. Raising rabbits requires more skills, more time, and much more effort than raising barnyard chickens or other familiar scavengers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For all that, rabbits produce more food than scavenging animals; they are less likely to damage crops because they are kept confined; they live exclusively on forage, which tends to grow vigorously in tropical zones; and they generally produce a more valuable product. The rabbit's potential is far from exploited, and rabbit farming will have to increase enormously before its promise for the small farms of the world is realized.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is, however, an increasing concern over a recent outbreak of an exceptionally virulent viral rabbit disease - hemorrhagic tracheopneumonis, which attacks the lungs and lung tissue, killing 48 hours after the onset of symptoms. The virus, which has ravaged the animals in parts of Asia and Europe, was identified in China five years ago in Angora rabbits imported from Germany. It spread to Korea in 1986, and in early 1988 moved through southern and eastern Europe and spread as far as Egypt. It has also been identified in Mexico. Vaccination may become a future prerequisite of rabbit rearing in many countries. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FAST FOOD</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The order Lagomorpha includes more than 60 small quickmaturing, and rapidly reproducing species. It seems illogical to think that only one is useful as microlivestock. In principle, any rabbit, hare, or pike could be raised in captivity. All are clean, fast growing and rapid breeding. They are opportunistic feeders and can digest fibrous vegetation. Their meat tastes better than chicken and does not carry the stigma of rodent. The animals are small inoffensive, efficient at foraging, and generally tolerant of difficult environments. In theory, at least, they could be raised on vegetation not used by people or by many domesticated livestock.</P>
+<P ALIGN="JUSTIFY">Species worthy of exploratory research include the following.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">14 Domestic Rabbit</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g018a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The domestic rabbit (Oryctolagus cuniculus)1 is suited to small-scale production and backyard farming. It is easily maintained, requires scant space, makes minimal demands on the family budget, and thrives on plant materials that are usually disdained by humans. It utilizes forage efficiently. even coarse vegetation that is high in fiber, and under ideal conditions it can grow so rapidly that its rate is only slightly lower than that of broiler chickens.2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The rabbit's capacity for reproduction is legendary. In theory, a single male and four females can produce as many as 3,000 offspring a year, representing some 1,450 kg of meat - as much as an average sized cow.3 The meat is pink, delicately flavored, and is usually considered a premium product that provides variety in the diet. It has more protein and less fat and calories per gram than beef, pork, lamb, or chicken.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some breeds are raised for their wool. The long-haired Angora, for instance, yields a luxury fiber that makes a soft, lustrous fabric. It sells at high prices and makes these animals very valuable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rabbit pelts also bring cash. They are used in fur coats and other luxury garments. In addition, rabbit feet and tails are used in good luck charms and many curios.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Worldwide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Rabbits are well known for their long ears, fluffy tails, and long hind legs. Many commercial breeds are white, although colored types are sometimes chosen because of special qualities in their meat or pelts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are many breeds and much genetic diversity within and between breeds. (Almost 160 varieties are recognized by the American Rabbit Breeders Association.) However, in both North America and Europe, the New Zealand White has traditionally displaced most other breeds for commercial meat production. This medium-weight breed bears large litters, is a good milk producer, and has good mothering ability. It reproduces best under intensive farming and, among purebreds, yields the most meat. A full-grown New Zealand White weighs 4-5 kg, giving about 2 kg of meat at 8-10 weeks of age. Large breeds include the Flemish Giant or the Checkered Giant, which weigh more than 6 kg at maturity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hybrids are rapidly replacing purebreds in Europe for commercial production. Specific crosses of breeds have been shown experimentally to be more productive overall compared with purebred New Zealand Whites.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Different meat breeds are preferred in various countries. For example, in Ghana the most popular are Flemish Giants, New Zealand Whites, Yellow Silvers, and Checkered Giants; in Tanzania and Nigeria, New Zealand Whites and Dutch are preferred; in China, Chinchillas and Japanese Large Whites are the most widely consumed. Some smaller breeds - for instance, the Polish - are also valuable for husbandry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some Third World strains have already evolved. They show high tolerance to local conditions (for example, the Baladi - the main strain of the Sudan and the Near East - and the Criollo of Mexico). The Baladi has a small body and relatively low production, but it is hardy and tolerates harsh conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Specialized breeds have been developed for wool, fur, and laboratory research. The Angora wool breed has already been mentioned. The Rex breed produces a high-quality pelt used in furs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The wild ancestor of the domestic rabbit was originally restricted to Spain and Portugal. Today, its descendants are found worldwide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Plentiful.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Domestic rabbits are best suited to temperate climates, but they do well in tropical and subtropical conditions if hutches are constructed and sited to take advantage of shade and cooling breezes. Ventilation is important (but care must be taken to avoid direct exposure to cold drafts). Prolonged exposure to temperatures higher than 30&Yacute;C reduces both fertility and growth. Apparently, all breeds tolerate heat equally well. However, heat is shed through the ears, and the longer the ear, the more heat a rabbit will tolerate. Lop-eared varieties withstand heat poorly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Rabbits eat fibrous vegetation. In addition to normal feces, they produce special droppings called cecotropes. Softer and smaller than the regular fecal pellets, they are excreted in clusters and are swallowed as soon as they are eliminated. Cecotropes are rich in bacterial protein, and this double digestion (coprophagy) enables the animals to utilize the fermentation products formed in the cecum. This process is rather like that of ruminants, and rabbits are sometimes called pseudoruminants.4</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Breeding begins at 4-6 months of age and may continue up to age 4, occasionally to age 6. Gestation takes 28-32 days. Females can conceive within 24 hours after giving birth and can produce a second litter merely 4 weeks later. With good feed and early rebreeding, 9 or more litters a year are possible. (Such a rate is only achievable under exceptional management, however.) Litter size depends on breed and body weight. Small breeds average 4 young per litter; large breeds 810. Births occur at any time of the year, but production slackens when the weather is exceptionally cold or hot, when feed is scarce, or when days are short. Extremes of heat or cold can also affect the survival of the young.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rabbits raised under subsistence conditions are likely to produce 4 or 5 litters a year, with an average of 5-8 young per litter' depending on management and feed quality.5 Annual production of about 20 weaned offspring per female per year under tropical and subtropical conditions is common. The young remain in the nest until they are 2-3 weeks old. Their eyes open at approximately 10 days of age. About 4 months are required to produce a 2-kg market rabbit under subsistence conditions. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Rabbits that receive human handling are very gentle and can be trained to live inside people's houses and even use a "litter box."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Rabbits are multipurpose animals yielding the following products:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Meat. Delicious hot or cold, fancy or plain, it can be breaded and fried, broiled, baked, or barbecued.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Wool. The fineness of rabbit hair is an asset in the production of wool, which is the plucked or shaved hair of the long-haired Angora breed. It is usually mixed with fine Merino sheep wool to give more substance and to improve its wearing quality. An average Angora rabbit produces about 850 g of wool each year. (Some specimens produce as much as 1,000 g.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Fur. The fur is dense.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Leather or vellum. Rabbit hide has the tension and strength required for tiny drive-belts in tape recorders and other delicate machines.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Fertilizer. Rabbit manure often contains high proportions of nitrogen, phosphorus, and potash, and it comes in convenient drypellet form.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Tourist charms. In many societies, rabbits are connected with good luck. Feet and tails are used for car decorations, key chains, charms, and mementos that appeal to tourists.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rabbits are also used in biochemical and physiological research.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Rabbits can be housed in hutches ranging from sophisticated commercial cages to simple packing crates with a few ventilation holes and rough troughs for food and water. In all cases, watertight roofing is essential. A floor space of only 0.25 m&Yacute; is sufficient for one rabbit, but about 1 m&Yacute; is recommended for a female and her young.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Starting small-scale rabbit production is generally inexpensive. An almost infinite variety of backyard feeding and drinking equipment can be made from various scrap items, such as old bottles. The main criteria are that cleaning should be easy and spillage minimized.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In practice, diets can be based largely on herbage: grass, leaves, legumes, crop residues, and kitchen scraps. However, the diet must be wholesome, and caged rabbits fed on forage usually need some grain or agricultural by-products (rice bran, for instance) as a dietary supplement. Supplementation is particularly important for newborns and lactating females, whose diet must contain about 16 percent protein and at least 18 percent fiber. When "noncommercial" feeds are used, salt must be added to prevent salt deficiency.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of higher protein content, legumes (for instance, alfalfa, cowpea, vetch, or pea) are better than grass. Alfalfa is particularly valuable, and in the Sudan and Mozambique it is already grown extensively for feeding rabbits. On diets consisting of alfalfa and rye grass, weaned New Zealand Whites have demonstrated growth rates of 38-39 g per day in animals weighing up to 2 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Rabbits, as mentioned, can utilize almost any type of edible vegetation. Also, despite their diminutive size, they can collectively produce as much meat per unit of forage as large livestock, or even more (see page 183).6</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is much genetic diversity. Differences in growth rate, fertility, maternal ability, milk production, disease resistance, heat resistance, and other features have been noted. This is useful, since a wide genetic base enhances the likelihood of success of selection programs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rabbits are easy to handle and can be raised under primitive conditions. They require little financial investment and their husbandry is easily accomplished in the home by women and children.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animal's rapid reproduction is a big advantage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Tropical conditions produce special problems. There, rabbits must be protected from heat and rain. Stress brought on by high temperatures, high humidity, and wet conditions can lead to respiratory disorders and even sudden death.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most diseases are caused by poor management. Dirty or wet cages lead to diarrhea, sores, mites, and ringworm, all of which can cause serious losses. Enteritis (diarrhea) often kills 20 percent or more of all rabbits before they attain market age and weight. A major disease problem in most countries is coccidiosis, which is particularly harmful to young rabbits. Again, damp and unsanitary conditions increase the susceptibility; better management can control it. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In some countries - notably Australia and New Zealand - escaping rabbits have become a serious menace and have destroyed crops and grazing lands. Because of this threat, it is illegal to import rabbits into some countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At present, many people are unaccustomed to eating rabbit. Indeed, where commercial ventures have been established in areas with an otherwise plentiful meat supply, there have been financial failures. However, where rabbit meat is familiar, there is usually great demand for it. Also, in poorer areas where animal protein is in short supply, the tasty pink meat is widely appreciated.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HOW RABBITS WERE DOMESTICATED</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">For 30 or 40 million years the wild species Oryctolagus Cuniculus lived only in the area that today is Spain. Caves there contain Stone Age drawings of it. Phoenician traders landing on the Iberian Peninsula in about 1100 B.C. found huge numbers of these wild rabbits. The little animals were unknown to them and they mistook them for the hyraxes they had seen in Africa. (Although small and rabbitlike, the hyrax is actually related to elephants.) Since the Semitic name for hyrax was shaphan ("one who hides"), the Phoenicians named the peninsula l-shepan-im, from which the Latin name Hispania developed. Thus, "Spain" actually means "island of hyraxes," even though these African animals have never occurred there.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Given the rabbit's reproductive powers and adaptability it is surprising that it hadn't spread beyond Spain, but dense forests covered most of Europe after the last Ice Age. The rabbit, which is suited to open country, only spread rapidly after man had cleared most of the trees. Even then, the natural spread was slowed by the Pyrenees mountains blocking the way into the rest of Europe.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ancient Romans became acquainted with rabbits after they invaded Spain, and they eagerly added wild rabbit meat to their banquets. The meat was so popular that around 1 A.D. Roman voyagers released a pair of rabbits onto the Balearic Islands. In time, these produced so many offspring that the islanders had to appeal to the Roman emperor for help. They even asked to be moved to another country if the emperor could not get rid of the plague of rabbits!</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Eventually, Romans in Italy, France, and other parts of the European mainland began raising rabbits for meat. They kept them in special cages called leporaria. Their rabbits were probably not truly domesticated; instead they were netted in the wild and caged for fattening before being prepared for the table. The Romans had little incentive to domesticate an animal that could be so easily captured.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tne rabbit was the last farm animal to be domesticated. It seems likely that this did not begin until the Christian era when monks in French monasteries began taming rabbits. In those days, rabbit embryos and newborn young were considered delicacies, called "laurices." In 600 A.D. the Pope declared that laurices were "not meatp," and permitted them to be eaten during fasts and in monasteries of strict discipline where meat was forbidden. Within a few years, the animal was domesticated, </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Government-sponsored rabbit-research stations and programs are found in France, Germany, Italy, Spain, the United States, and the United Kingdom.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rabbit husbandry is well known, but much basic research is needed; for example, specific nutrient requirements, breed comparisons, disease control, reproductive management, and efficient housing and equipment. There is a particular need to reduce the labor required for feeding, breeding, caging, and cleaning.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With the increasing number of rabbit programs in Africa, Asia, and Latin America, there is a need to share information and ideas among the various countries. The exchange of experiences with rabbit breeding, health and nutrition, and the practical experiences and field studies could be of great value.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Further research in rabbit nutrition is necessary to identify nutrient requirements more precisely. Moreover, links between nutrition and disease should be clarified.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Further research into the cause and prevention of enteritis is needed. (At present, this condition is prevented by maintaining a fiber level in the diet of at least 18 percent and keeping the energy level relatively low.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Legume shrubs could be an answer to the feed problems in the dry season. Deep-rooted shrubby legumes, such as gliricidia or leucaena, remain green well into the dry season and have high protein contents. Rabbits find the leaves of leucaena palatable (see companion report Leucaena: Promising Forage and Tree Crop for the Tropics. National Academy Press. Washington, D.C. 1984), and they are fairly resistant to mimosine (a sometimes toxic amino acid found in leucaena foliage). More research on this promising approach is needed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As noted earlier (page 181), a killer virus has recently appeared. Studies into its epidemiology and control are most important. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Outsiders who hope to improve conditions in underdeveloped areas, sometimes . . . introduce new food avoidances to the communities they came to help [if outsiders] show repugnance toward consuming goats, . . . rats, . . . crows, insects, intestines and blood, then the people they are educating may likewise give up those . . . foods and lose valuable proteins.</P>
+<P ALIGN="JUSTIFY">Calvin W. Schwabe</P>
+<P ALIGN="JUSTIFY">Unmentionable Cuisine</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">You can count on the fingers of one hand the domestic animals that produce virtually all of mankind's meat and milk - a selection made more than 10,000 years ago by our Neolithic ancestors. Yet the earth teems with thousands of species of animals; why limit ourselves to cattle, pigs, goats, and sheep? Given the world's shortages of energy and water and arable land, why not try to domesticate wild animals? The effort would save many species from extinction, provide the world with more food, and introduce gentle farming to fragile environments.</P>
+<P ALIGN="JUSTIFY">N.D. Vietmeyer</P>
+<P ALIGN="JUSTIFY"> </P>
+<P ALIGN="JUSTIFY"><center><img src="g019a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Part IV : Rodents</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Rodents are the world's most widespread, adaptable, and prolific group of mammals. They reproduce well, grow fast, learn quickly, and adapt to a wide variety of local conditions. Many convert vegetation into meat efficiently, digesting some fiber, even though their stomach, like man's, is a simple one.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It seems probable, therefore, that some species would make suitable microlivestock - a notion supported by the previous domestication of the guinea pig, laboratory rat and mouse, gerbil, and hamster. Indeed, "ranching" rodents might be an effective way to increase food supplies in remote areas. It could also be a mechanism to ensure the survival of rare rodents whose natural habitats are being rapidly destroyed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RODENTS AS FOOD</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Rodents are already common foods in many countries and are valued items of commerce. It has been estimated that 42 of 383 cultures eat rodents.! But the fact that they are a major meat source is almost unrecognized. This is due in part to cultural misunderstanding. Rodents suitable for human food or other products do not live in filth, like common rats. They are clean and vegetarian. Like rabbits, they eat grass and grains.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In some regions of the world, cooked rodent meat is regarded as the epitome of dining. In many countries, local rodent species are the most eagerly sought meats. City markets in different parts of Latin America carry guinea pig, pace, capybara, and vizcacha. Markets in Asia may carry rice rats, cloud rats, and bandicoot rats. Those of rural Africa are filled with "bushmeats" - usually including grasscutters, giant rats, and several other rodent species. These are often preferred to the meat of domestic stock and fetch higher prices than beef. And the amounts of rodent bushmeat available are not minor. In one year, for example, hunters in Botswana have brought to market 3.3 million kg of meat of the rodent called springhare (see page 278).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fondness for rodent meat is not restricted to the tropics. In the United States, squirrel was once a much sought treat. Fat, nut-fed grey squirrels went into Brunswick stew, which has been called the most famous dish to emerge from the campfires and cabins of Colonial America. Thomas Jefferson liked it. Today, squirrel is the country's number two game animal (after deer), and many are still eaten.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ancient Romans kept fat dormice in captivity, serving them as a delicacy. "The fat dormice are fattened up in barrel-like pots like those in country houses," wrote Varro (116-27 BC). "One feeds these animals large amounts of acorns, chestnuts, or other nuts."2 This small rodent remains a prized food in Europe and still appears on tables in certain areas. The meat is regarded as a delicacy because it tastes of almonds and other nuts. Often it is roasted, broiled, and cooked with its cracklings.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rodents have seldom been included in livestock programs or economic development plans. Yet human appetite has actually caused the extinction of a number of species. Caribbean Indians ate several endemic rodents (one of which was as big as a bear), and may have caused several species to become extinct just before the time of Columbus. Others may soon follow the same dismal route, including the beautiful cloud rat of the Philippines, the hare-like mare of Argentina, the vizcacha of southern South America, and the gentle hutias of the Caribbean.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The guinea pig is described in a later chapter, but as it is the epitome of a rodent microlivestock species, some historical background is given here. It was domesticated for food use at least 7,000 years ago, probably in what is now the central highlands of Peru and Bolivia. With only llama and deer available, the prehistoric Andean peoples had few readily available sources of meat. They adopted wild cavies, and found that these rangeland rodents (which are more closely related to porcupines than to rats or mice) were gentle, manageable, and easy to rear. By the time the Spaniards arrived in the 1500s, the "cuy"  (pronounced "coo-ee," like the faint cry it makes) was a major food from  Argentina to the Caribbean.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This impressed the conquistadores, who introduced cuys into Europe,  where they also became a delicacy.3 Within a century, these easily  transported animals began to appear on tables in many parts of the  Spanish empire. Guinea pigs are now reared in campesino huts in the  mountains of central Mexico, in the Philippines, and in several African  nations, along with other areas of the world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Elsewhere, guinea pigs came to be used only as house pets and  laboratory animals. Although during World War II Mussolini's  government urged Italians to keep them to supplement their meager  meat rations, their use as food was largely ignored in most parts of the  world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DOMESTICATION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The idea of domesticating rodents may seem radical, but  domestication projects are already under way with capybara in  Venezuela (see page 206), pace in Panama (see next page and page  262), giant rat in Nigeria (see page 224), and the grasscutter in Ghana  (see page 232). Rodent husbandry is not complicated and the animals'  environmental requirements seem relatively simple and easy to satisfy.  Moreover, rodents are not usually fastidious feeders, and being  essentially vegetarian will readily accept a wide variety of commonly  available foodstuffs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As with most animals with which man is in close contact, rodents can  transmit human diseases.4 With care, however, managed rodents need  not be any more dangerous to care for or to eat than pigs or  horses - both of which are worldwide food resources.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DOMESTICATING RODENTS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">To domesticate the pace (see page 262) would seem to be impossible. These large rodents of Central and South America are nocturnal and fiercely territorial; they have low fecundity and take 10 months to reach weaning, and they have tender skin that is easily damaged Most researchers have written them off as candidates for domestication. But at least two have undertaken to beat the odds. We present the findings of one of them here to show that, using modem techniques, even species that normally fight each other to the death on sight are potential farm animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Through years of studying paces in Panama, Smithsonian biologist Nicholas Smythe has found that with care and planning the aggressive behavior can be so radically altered that the animals become calm. Indeed, some become almost loving. Newborns, Smythe found, undergo "imprinting" and when he places them with docile adults or with humans, the fierce territoriality never develops. He nurses newborns on "surrogate" mothers that have been imprinted on people. The youngsters then welcome human company and, if fumed out of the cage, return there voluntarily. "It's difficult to imagine a more manageable animal," Smythe said. "Technically speaking they are behaviorally indistinguishable from traditional domestic animals."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As of this writing, Smythe has three generations totalling about 50 individuals, and has several "families" of gentle paces living together in harmony. He has observed that they lose their nocturnal habit and, although they live mainly on fruits in the wild, they readily eat leafy vegetables and other foods in captivity. His captive specimens have recently begun to breed. The offspring remain docile, but they have so far averaged only a little more than two young per female per year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">"If we can just double the reproduction rate, then raising paces can compete economically with raising cattle," Smythe explained. "The potential for a bigger brood is all in the animal's anatomy, and if successful, paces in the wet tropics could produce as much protein as cattle."*</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pacas need the shade and protection of the forest. Thus, pace raising might provide an alternative to cutting down rainforests for cattle raising. Instead of toppling trees and planting pastures, people could farm paces in the forest, and perhaps make as much or more money at the same time. In tropical America, the ready acceptance of pace meat is a near guarantee that all they produce will be snapped up at premium prices. In the past, many territorial and aggressive species have been dismissed as being impossible to domesticate or manage. But Smythe has demonstrated that with imprinting and other methods of behavior modification, these need be dismissed no longer.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Indeed, the pace may already be becoming a new domesticated species. In the first stage of his experiments, Smythe had to train his captive-born paces to be social and nonaggressive. Subsequent generations, however, need no training adopt the new behavior patterns of the parents, and do not revert to aggressive asocial behavior. By the third generation, they have become as accepting of, and indifferent to, people as cattle or sheep. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">15 Agouti</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g020a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Among the best known of all animals of the American tropics, agoutis (Dasyprocta species)' are prolific rabbit- or hare-sized rodents that are probably easily farmed. They are valued for food and are hunted throughout most of their range. Indeed, agouti meat, once common in Latin markets. is now difficult to find because of indiscriminate killing. Agouti hunting is already prohibited in Brazil; restaurants in Belem, for example, once offered a variety of "cotta" (agouti) dishes at prices equivalent to those of choice filet mignon, but since the early 1970s they have been banned from serving it. Other countries will probably have to institute similar bans.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agoutis are active, long-legged, and high-strung. They flee in panic at the slightest alarm. They do not climb but they do burrow occasionally, being essentially specialized ground-dwellers that live in tropical forest regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There have been no organized scientific attempts to raise these swift, shy animals in captivity, but Latin Americans sometimes keep them as "domestics," especially in parks and large gardens. (Agoutis are well known, for instance at the Goeldi Museum in Belem, Brazil.) These animals seem to tame easily, and could perhaps be mass produced on a large scale like rabbits or guinea pigs. They make affectionate pets, sometimes refusing to return to the wild. A research project on captive breeding of two local agouti species (Dasyprocta mexicana and D. punctata) for food is already under way in Tuxtla Gutierrez, Mexico.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Most of lowland, tropical Latin America and the Caribbean. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Agoutis are delicately built, graceful, nimble, and beautifully proportioned. They have slender bodies, short ears, and look somewhat like a rabbit that has been "jacked up" in back. Generally, adults are 40-60 cm long and weigh 2-5 kg. Some are even bigger.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They run well and are good jumpers. From a standing start an agouti reportedly can leap as high as 2 m or as far as 6 m; however, as long as they are well fed, there is little problem keeping them behind a wall only 1 m high.2 Reportedly, they sometimes climb easy-sloping trees to collect green fruits, but researchers studying Central American agoutis report that they are strictly terrestrial.3 They swim well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The body hair is thick, coarse, and glossy: pale orange to black on the back, and white to yellow on the belly. Some species have faint stripes, and some have a rump that contrasts with the rest of the back. The short tail is partially concealed under the long body hair.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Agoutis occur over a vast area from southern Mexico to Paraguay, including many islands in the Caribbean.4</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Because they occasionally damage sugarcane plantings and because the meat is particularly tasty, people hunt agoutis relentlessly, especially near cities and towns. Now, in the l990s, they are becoming rare because of excessive hunting and habitat destruction. Many Latin Americans have never heard of them. In Mexico, for instance, there are few places where agoutis survive, and Dasyprocta mexicana may become extinct if habitat destruction and overhunting continue in its restricted range. In Costa Rica and Panama, agoutis occur only where there is little or no hunting or human interference.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">From sea level to elevations of at least 2,500 m, the adaptable agouti lives in many habitats: moist lowland forests, dry upland forests, thick brush, and savannas. However, although they thrive in secondary growth areas, they are mainly forest dwellers. Nonetheless, they often enter fields to forage, and young animals occasionally are seen in open areas such as grassy stream banks and cultivated fields.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Agoutis shelter in hollows among boulders, in riverbanks, or under tree roots. They also hide in heavy brush and sometimes in holes dug out by other species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These herbivores eat seeds, fruit, stalks, leaves, roots, and other succulent plant parts, as well as occasional insects and fungi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They seem to mate twice each year. The estrous cycle is variable, but is only about 34 days long. The young are born after a gestation period of 3.5-4 months. Usually, there are twins; however, single births and triplets have been recorded. Newborns are fully developed and are able to run around within hours. They start feeding on solids within a few days. Puberty occurs at about 9 months of age. Life expectancy is 10 years or more.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In the wild, agoutis are shy and retiring. Every sense seems constantly triggered for instantaneous action and sometimes they become hysterical. If danger threatens, they usually "freeze," but when discovered they stamp their feet as an alarm signal and dash away, nimbly dodging obstacles.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite excessive timidity, they can be violent among themselves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In undisturbed forests, agoutis are diurnal and are often seen. But around villages they become nocturnal, as a means of self-preservation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For the most part, these rodents live in loosely formed pairs, with previous litters living around their territory as "satellites." There is some "bigamy," some "philandering," and some "divorce."5.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite their long claws, they display much finger dexterity. To eat, they usually sit erect, crouching on their haunches and holding the food in their forepaws. If it has a skin' they carefully peel it before starting their meal. They save some nonperishable foods (nuts, for instance) by digging holes in scattered locations, dropping each one in a separate location, stamping it down, and covering it over. This behavior helps disperse the seeds of many species of trees so that agoutis benefit tropical forests and reforestation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p203a.png"></center><br>
+ figure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As noted, agoutis are popular game animals. They are often hunted with dogs that even follow them into the burrows. Agouti meat is tasty, although it is usually said to fall short of the meat of the pace (see page 262) because it is leaner and gamier.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Agoutis adapt well to captivity. With appropriate care they can be bred without difficulty.6 The nervousness that is pronounced in nature is quickly lost in captivity. The young become tame pets. They can be fed on foods such as leafy vegetables, fruit, potatoes, and bread scraps. Although many wild specimens have become nocturnal, captives readily readapt to daylight.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Being entirely terrestrial, agoutis require no trees, but they do need space. Given enough area, they get on well (with each other and with different species), and they breed freely. To avoid fighting, it seems necessary to separate females from males at puberty. Probably removing progeny from breeding pens at weaning could also help avoid most of the interpersonal aggression. In large areas with plenty of cover (banana plants, for instance), groups can be kept, but breeding may be disappointing. Husbandry may be most appropriate in large enclosures (50-100 agoutis) with some animals then removed to small cages 0.5-1 m&Yacute; for selective feeding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ACOUCHIES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Close relatives, the green and red acouchies (Myoprocta acouchy and Myoprocta exilis) also deserve study. These are smaller animals with longer tails, bearing a little plume of white hairs. Although even more delicate and hypersensitive than agoutis, they can be kept in captivity and breed well. They then become less nervous and are easily handled. Acouchies. show remarkable intelligence and even some affection for those they trust. They frequent rainforests, but are rare or even absent in disturbed areas. Adults weigh up to 1.5 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The general biology (diet, reproduction, activity rhythm), is almost the same as that of the agouti, but they live in smaller home ranges (0.6-1.2 hectares versus 2.5 hectares for the agouti) and travel singly, although belonging to a well-established family unit. Adult males tolerate the juvenile males. They occur only in Colombia, the Guianas, Ecuador, Peru, and Brazil.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Farming methods would probably be the same as for the agoutis, but acouchies always need plant cover.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Agoutis are appropriately sized: a dressed carcass can weigh 1-3 kg. The meat is good, and large commercial undertakings in urban centers could profit from the ready market that already exists.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals are prolific: females can produce up to two litters a year, each litter averaging two offspring. In protected areas, populations may grow fast.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These forest dwellers might provide a source of meat and income without destroying the forests in favor of cattle pastures. Also, they thrive in disturbed areas as long as there is some cover. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Experiments in Brazil show that agoutis are highly susceptible to foot-and-mouth disease.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals might become pests: they eat the roots, leaves, and fruit of agricultural crops and occasionally damage sugarcane and banana plants. However, current experience suggests that if they escape captivity they are quickly caught by hunters and do not reach pest levels.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Live agoutis have strong-smelling anal glands that may be offensive to breeders or could contaminate the meat if the animals are carelessly handled.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Where the rainforest is destroyed, the agouti population is destroyed. The animals were once well known throughout Latin America, but not anymore. In some areas, therefore, wild breeding stock may not be locally available. Moreover, people may have become sufficiently unfamiliar with them that their value may no longer be appreciated.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In captivity, they can be the prey of large birds such as eagles.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The taxonomy of agouti species needs clarification.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Husbandry experiments are required, including studies on topics such as:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Nutrition;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Growth rate;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Shelters and enclosures;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Reproduction; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Techniques for catching, moving, marketing, and managing the animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One area where agoutis might profitably be raised is in enclosures in palm plantations. Palms such as the babassu provide food, shade, and shelter, while fallen and rotten logs offer secure retreats from predators. This deserves investigation.8</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Instead of clearing vast areas of rainforest for cattle pasture, as is being done in much of Latin America, people might well "farm" agouties in the forests. Few of the settlers flooding into such regions can afford, let alone raise, beef. Small-scale agouti farming offers a promising and inexpensive alternative that would be gentle on the fragile land. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">16 Capybara</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g021a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The capybara (Hydrochoerus hydrochaeris), the world's largest rodent, can be as big as a sheep and weigh as much as a small person. Its natural habitat is the environs of South America's rivers, marshlands, and swamps, where it feeds on the grasses and reeds that grow near water.1</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of its size, tasty meat, valuable leather, and rapid reproduction, the capybara is a candidate for both ranching and intensive husbandry throughout the hot and humid lowland tropical regions of Latin America. It seems easy to handle. It is commonly raised in zoos or occasionally as a pet, and has, in at least one instance, been proven successful in large commercial herds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In floodplain ecosystems, capybaras complement cattle because they prefer to graze swamp grasses rather than the dryland grasses on which cattle feed. They have simple stomachs, but are one of the more efficient herbivores. Although they are "selective feeders" that eat lush waterside grasses "preserved in quality" by the water, they also graze pasture, usually selecting new growth that is often too short and scattered for cattle, with their large muzzles, to eat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The floodplains of the South American subtropics and tropics where the animal is indigenous.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Although they have blunt, horselike heads, capybaras look like gigantic guinea pigs. They are ponderous, barrel shaped, and have a tail too small to be seen from a distance. Their skin is tough and covered by sparse, bristlelike hairs: the color above is reddish brown to gray; beneath, it is yellowish brown.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The front legs are shorter than the back. Slightly webbed toes - four on the front feet and three on the back - make them good swimmers. They dive with ease and can stay underwater for up to five minutes. They also move nimbly on land.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The capybara is extremely large for a rodent. In size and color, it looks much like a pig. Often more than 100 cm long and 50 cm high at the shoulder, it can exceed 50 kg liveweight. Indeed, specimens weighing up to 90 kg have been reported.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Before livestock were introduced, the capybara grazed widely over riverine regions throughout South and Central America. Today, it is found in the flooded grasslands from Panama to Paraguay. Mainly, it occurs in the watersheds of the Orinoco, Amazon, Paraguay, and Parana rivers. High population densities exist in the Pantanal of western Brazil and on the Llanos floodplains of Venezuela and Colombia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">There are few precise population counts, but capybaras can occur in large numbers.2 However, in many areas they appear to be on the verge of extinction, being deliberately eradicated by farmers who think they compete with cattle and transmit diseases. Also, in some areas illegal hunting goes on year-round and great numbers are killed. The animals are particularly vulnerable during the dry season, when they concentrate around the diminished river channels and water holes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As noted, most capybaras live in swampy or grassy areas bordering rivers. However, some are found in other habitats, ranging from open plains to tropical rainforests. But even here they stay near ponds, lakes, streams, and swamps, and never venture much more than 500 m from water.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p210a.png"></center><br>
+ The capybaras native range</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The capybara, like all rodents, is a simple-stomached animal, but it is a true herbivore. Its digestive system is especially adapted for fibrous materials. The large cecum - the site of enzymatic digestion serves a function like that of the rumen of sheep, cattle, and goats. It has a digestive capacity similar to that of a sheep's rumen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like rabbits and all the rodents, capybaras are coprophagous. That is, during the morning hours when they are resting, soft feces from the cecum are passed a second time through the digestive system.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Contributing to the animal's digestive ability is its efficient mastication. It chews its forage seemingly incessantly, reducing it to extremely small particles before it is swallowed. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under natural conditions, the females annually bear 1 or 2 litters, each averaging from 4 to 6 offspring. Birth weight is between 1 and 2 kg, depending on litter size and sex. Both males and females reach sexual maturity when they reach a liveweight of 30 kg or more usually between the first and second year of life.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Capybaras are intelligent, shy, inoffensive, and harmless. In undisturbed ecosystems, they are gregarious and live in family groups of up to 30. The young follow the mother about for many months after birth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unlike most rodents, they do not construct dens, but the groups have specific resting areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals are both diurnal and nocturnal and, like many herbivores, they graze at daybreak and dusk, and perhaps also at midnight. They spend the morning resting in weeds on riverbanks, and at noon they cool off by bathing for an hour or so before grazing. They may feed belly deep in water.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Capybaras wallow in mud, allowing it to dry on their skin before bathing again. Mange can develop in captivity when they cannot take a mud bath.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When startled, a capybara barks loudly and dashes away, but after running 200 m or so it tires, slows down, and may lapse into hyperthermia. At that point a hunter can easily catch it. However, if the animal reaches water, it usually eludes the pursuer because it swims so well - especially underwater.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Capybara meat is white and has qualities and properties (such as high emulsification) that might allow it to compete with pork and other meats in the food industry. Spanish-style sausages, Italian-style mortadellas, frankfurters, and German-style smoked chops have been produced experimentally.4 However, at present, the meat is mainly consumed only in the dried and salted form. It is particularly popular in Venezuela, where more than 400 tons are sold every year, especially during Easter festivities.5 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The capybara's hide is one of the best for glove making. This luxury product, known in international commerce as carpincho leather, fetches high prices on European markets because it is more heat resistant than most leathers and because it stretches in only one direction. This one way grain allows gloves to stretch sideways without lengthening and looking sloppy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The capybara appears suitable for raising as a livestock animal. Amerindians traditionally collected capybara orphans during the hunting season and raised them until needed for food. Capybara breeding was reported in Brazil as early as 1565.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Modern attempts have been made towards domestication. Researchers at the Institute of Animal Production in Venezuela, for instance, started a breeding program in the 1970s using 20 females and 5 males. Since that time they have continuously kept capybaras in confinement. Through selection and management, they have improved the reproduction of captive animals. The current aim is to get 16 offspring per mother per year. Newborns are weaned after 5 weeks and the mother is returned to the breeding pen.6 In Colombia, similar work is in progress, and guidelines for raising capybaras on breeding farms have been published.7 In Brazil, research has been carried out to study capybara nutrition, genetics, management, reproduction, and social behavior in total confinement.8</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Throughout South America, the price of beef has increased greatly within the last few years, thereby providing a new incentive for capybara husbandry. It has also forced many campesinos to eat more wildlife, which adds another incentive for producing capybara meat on farms and thereby perhaps helping to relieve pressure on the wild stocks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When tame, the animals are amenable to handling without physical restraint. They are so tractable that in Surinam a blind man once used one as a guide animal. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Capybaras can be raised on a variety of readily available vegetation: leaves, roots, fruits, and vegetables. They thrive in coarse grasses, if given opportunity to select nutritious parts. Their large incisors allow them to bite off short grasses that many herbivores cannot use. For instance, they eat "capybara grass" (Paspalum fasciculatum) that is abundant on river edges in Venezuela and is normally too short for cattle to graze. This makes for low-cost feeding and utilization of a resource that is otherwise unused.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Capybaras are at home in hot, humid environments and are fully adapted to life on the tropical floodplains and seasonally flooded savannas. They thrive in extreme climates where cattle struggle, such as in the parts of the lower Paraguayan Chaco where summer temperatures reach 45&Yacute;C.9 An ecological benefit to raising capybaras is that there is no need to alter habitats by introducing exotic forage plants.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They reproduce quickly. Age at first conception for females is about 1.5 years, and the time between parturitions is generally shorter than that of goats or sheep in the tropics. Young capybaras grow so fast that in 18 months they can reach a liveweight of more than 40 kg. In their natural conditions, they are more disease resistant than cattle. The annual productivity is said to exceed that of cattle in many parts of its range.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This species is already so widely eaten in South America that the meat from farmed animals should be readily acceptable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Capybaras occasionally raid fields and can harm sugarcane, rice, bananas, sweet potatoes, cassava, corn, and other crops. In many parts of Brazil, they are considered agricultural pests and are shot.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Confining these animals in high density may create serious problems. Infectious diseases and parasite outbreaks seem to be worse than those that occur with conventional livestock. Aggression might prove a limitation to capybara husbandry: it is almost impossible to cage two adult males together or to introduce new animals to an existing group.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals may transmit disease to people and livestock. They can harbor foot-and-mouth disease and are known to be susceptible to brucellosis. They also carry a form of trypanosome, Trypanosoma evansi. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Compared with cattle, capybara use only a small proportion of the total plant biomass. They are largely selective feeders, and for satisfactory performance must have sufficient area to select the plants they need. If placed in a paddock of only coarse grass, most will eventually die. Like goats and gazelles, capybara probably select a diet that is at least 15 percent richer in crude protein than a typical cattle diet.'&Yacute;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">High mortality has never been observed in Venezuela, but keeping the animals alive on a farm in some areas may not be easy. In one trial, more than half (55 percent) of the capybara died of disease, and a few of septicemia (the result of wounds incurred during fights), but most apparently of trypanosomiasis. Other losses were caused by speeding vehicles (29 percent), poaching (6 percent), and predation, mainly by jaguars (12 percent)."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">It is important for researchers to undertake the following:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Gather specimens from different regions for comparative evaluation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Assess experiences of zoos and farms.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Undertake nutritional trials.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Initiate captive breeding trials - measurements of growth rates, space requirements, feed needs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Characterize the animal's productivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Study the capybara's basic physiology and production potentials.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Investigate biological factors, such as reproductive physiology, and social behavior (both in the wild and under controlled conditions).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Determine the factors influencing capybara reproduction, growth, and development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Determine the animal's adaptability and economic merit in various farming systems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Study the influence of environment on reproduction rate.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Determine their complementarily with water buffalo or other ruminants that normally use swampy habitats.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Determine relative causes of mortality (such as diseases specific to capybaras) and predation (especially of the young) by spectacled caiman, crested caracayes, black vultures, and others. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">17 Coypu</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g022a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The coypu' (Myocastor coypus) is an aquatic rodent native to South America. It has been called the "South American beaver," but its size is actually closer to that of a small dog or an agouti. It seems suited to be a microlivestock species because, compared with most rodents' it has a large body size and a relatively high reproduction rate. Moreover, it is easy to manage, and there is much literature on how to raise it in captivity.2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fur is the main item of commercial value. In the late 19th century, it was in such high demand that the animal was nearly exterminated. However, in 1922 Argentineans began raising coypu in captivity and this practice spread through South America and to other regions. In many European countries and in various locations in the United States some specimens escaped or were released, and coypu have become established in the waterways.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coypu meat is tasty and is consumed in many regions of South America as well as in parts of Europe. Because of the absence of musk glands, the meat is free of the "gamy" flavor found in squirrels and rabbits. It is moist, fine "rained, medium light in color, and firm. It is one of the mildest and tenderest of wild meats.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">This animal has been widely distributed, but its area of safest use is within its natural range in South America. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The coypu is adapted to a semiaquatic existence and has webbed feet, valvular nostrils that can be closed to keep water out, and underfur that remains dry even under water. Its long, powerful claws on the forefeet are used for grooming, excavating burrows, and digging up and holding food. The tail is slender; the extremely large incisor teeth are orange-red.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An adult is 40-65 cm long and weighs 7-10 kg. Some occasionally weigh up to 17 kg. Males are larger than females. The pelage is thick, with coarse guard hairs overlying the underfur. The soft dense underfur (the commercially valuable pelt called "nutria") is about 2 cm long on the belly, and 2-5 cm long and less dense on the back. The color is yellowish to reddish brown on the back and pale yellow on the belly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The coypu is distributed through southern Brazil, Paraguay, Uruguay, Bolivia, Argentina, and Chile. It has been widely introduced in North America, Europe, northern Asia, and eastern Africa. As a result of escapes and releases from fur farms, the animals are now feral in Europe, North America, northern Asia, Japan, and East Africa. In the United States, they are abundant in Louisiana, Oregon, Florida, and the Chesapeake Bay region.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In various countries, the animal's status ranges from that of a rarity to that of a pest. Wild coypu are protected by law in Argentina because of overhunting, but there are about 100 producers of farmed coypu.3 Elsewhere the animals are destroyed en masse to reduce the threat of damage to irrigation ditches, dams, and agricultural crops. In England a decade-long program has eradicated them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Coypu mainly inhabit the banks of fresh or brackish waterways.4 They live in temperate zones and are highly sensitive to freezing conditions. Also, their heat tolerance is poor; lowland tropical regions may be too hot for them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p219a.png"></center><br>
+ figure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The coypu feeds mainly at night. The diet consists chiefly of plants, particularly water plants and reeds. Large amounts of fibrous vegetation is decomposed in the cecum, where bacteria break down cellulose particles. Mussels, snails, and other small organisms are also often eaten.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals burrow into soft soil or construct nests out of vegetation above ground.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coypu are relatively fast breeding. Females first give birth at ages ranging from 6 to 15 months. From then on, they produce 2 or 3 litters a year. They are able to mate and give birth at any time of the year, although more young are born during certain seasons. The gestation period is between 128 and 140 days. There are 5 or 6 (sometimes up to 12) young in each litter. Newborns are well developed, able to see, and fully covered with hair at birth. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The female's four or five pairs of mammae are located on the side of the body, an adaptation that permits the young to nurse while floating with their mothers in the water. In captivity, young are nursed for two months, but can survive if weaned at five days. The mean body weight at birth is about 225 g, but growth is rapid during the first five months.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coypu have a potential life span of more than six years. However, they seldom survive more than three years, and in the wild probably no animals are older than five years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These are passive creatures, usually entirely lacking in aggression. They are shy and fearful; the slightest disturbance will send them scurrying to the shelter of water, a burrow, or other hiding place. With their large incisors they can bite viciously, but in captivity they tame down, even to where they can be carried around by hand. Compared with domestic animals, they are very sanitary in their feeding and living habits.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In hot climates they are nocturnal, in cooler climates crepuscular, and in cold weather they become diurnal. Captive animals become conditioned to diurnal activity if fed during daylight hours. Most of the active period is spent feeding, grooming, and swimming. Grooming is done by scratching and "nibbling" the fur, and an oily secretion from glands located near the mouth and anus lubricates the pelage. Secretions from the anal glands are also employed for marking out territory.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Excellent swimmers, coypu spend most of their time in the water. They can remain submerged for five minutes or more. On land, they lumber about with awkward, clumsy movements; however, when the need arises they can run fast and jump short distances.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although they usually live together in pairs, coypu will form large colonies. They tend to remain in one area throughout their lives: their daily "cruising range" has been measured at less than 45 m.5 However, drought or freezing weather can induce mass migrations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The burrows, which are dug in sloping banks, are usually short with no branching tunnels and generally end in a simple chamber. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In South America, the coypu has a long history of use. Nutria fur was in such high demand and the animal was hunted so avidly at the beginning of the last century that it became rare and had to be protected by government decree. As a result, populations increased dramatically. Nowadays, coypu are protected in many areas, but widespread poaching has reduced their numbers and range.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many thousands are killed each year just for the guard hairs, which are used in making felt.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coypu are used in marsh management to reduce infestations of aquatic weeds and to keep waterways open.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In most areas where it is found, the coypu is trapped by commercial hunters. However, as noted, several countries have coypu farms. In Germany, the animals have been raised on diets consisting chiefly of potatoes supplemented with oats, clover, corn, hay, green forage, legumes, turnips, or cabbage. Elsewhere, feeds generally include such materials as hay, corn, crushed oats, greens, root vegetables, apples, bread, and rabbit feed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To confine coypu, a wall of stone or concrete or a fence of stout wire netting is necessary. It must be set 1 m deep into the ground and rise 1-1.5 m above ground. Water must be available.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Where selected strains of animals are kept, it is usual to house each female in separate small compartments, complete with pools and shelter boxes. Each is then paired with a male, which is removed after mating to leave the female to rear her brood in seclusion.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The fur is particularly valuable because the female's nipples are so high that the soft belly fur is unbroken.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This herbivore is much cheaper to feed than the furbearing carnivores such as mink. Furs of coypu raised in captivity fetch a price about three times greater than furs from wild animals.6 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Wherever the coypu has escaped it has damaged embankments and stream banks. The burrows sometimes weaken dikes that protect low lying areas from flooding. In northern Europe and eastern England, for example, it is considered a serious pest. In rice paddies, coypu could become particularly devastating. They can also damage crops and natural plant communities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coypu can carry viruses that result in toxoplasmosis, papillomatosis, rabies, and equine encephalomyelitis; bacteria that cause salmonellosis, paratyphoid, and leptospirosis; protozoans that produce sarcosporidiosis and coccidiosis; and rickettsia. Common diseases of captive specimens are bacterial pneumonia, hepatitis-nephritis, Strongyloides infection, and neoplasms.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">European winters often cause the coypu's tail (which is hairless) to freeze, but the animal hardly seems to notice. A more dangerous situation arises when lakes, streams, or rivers freeze over; beneath the ice, coypu cannot find their way as easily as beavers, and often drown.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Little research needs to be done. There is massive literature on farming coypu. Nonetheless, the animal's behavior is little studied, and there are few reliable published observations on its social organization. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">18 Giant Rat</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The giant rat, also known as the pouched rat, is one of Africa's largest rodents.! Two species have been distinguished: Cricetomys gambianus, which lives chiefly in savannas and around the edges of forests and human settlements; and Cricetomys emini, which occurs mainly in rainforests. Both are highly prized as food </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These animals are solitary, but they are easy to handle, have a gentle nature, and make good pets. Researchers at the University of Ibadan in Nigeria have been developing techniques for managing them in captivity. Breeding stocks were established in 1973, and since then so many generations have been bred that this small population is considered domesticated. Commercial-scale giant rat farming is now being established in southern Nigeria.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">This is a promising development because giant rats are a common "bushmeat" throughout much of Africa. Since these herbivores are well known there, and are acceptable as food, they may have as much or more potential as meat animals than the introduced rabbits that are getting considerable attention (see page 178).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The intertropical zone of Africa from the southern Sahara to the northern Transvaal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This species is among the most striking of all African rodents. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of its large size, it often causes amazement - even alarm -  when seen for the first time. The body measures as much as 40 cm, and, on average, weighs about 1-1.5 kg. The record for a hand-reared specimen is 1.6 kg 2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Apart from its size, the best known species (Cricetomys gambianus) is noted for the dark hair around its eyes, a nose that is sharply divided into dark upper and pale lower regions, and a tail that has a dark (proximal) section and pale (distal) section. The overall body color is a dusky gray.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The lesser known species (Cricetomys emini) has short, thin, and relatively sleek fur. Its upper parts are pale brown; the belly is white.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Giant rats are commonly found from Senegal to Sudan, and as far south as the northern region of South Africa. The main species is mostly found in moist savannas, patches of forests, and rainforests. However, it can also be found in all West African vegetation zones from the semiarid Sahel to the coast. It also exists at high altitudes up to about 2,OOO m in West Africa and 3,000 m in eastern Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The rainforest species occurs in the great equatorial forest belts of Zaire and neighboring Central African countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These animals are probably not threatened with extinction. However, they have been exterminated in some areas (such as in parts of eastern Zaire) where the human population is dense, the land fully cultivated, and the wildlife overhunted. Although common, they are not as well known as one might suppose from their bulk and from the fact that they are sometimes found around, and even inside, houses.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Giant rats occur largely in lightly wooded dryland regions or in forested humid regions. They cannot tolerate high temperatures or truly arid conditions. They often live in farm areas and in gardens. Their burrows are commonly found inside deserted termite mounds and at the base of trees. Some have also been found in the middle of cassava fields. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p227a.png"></center><br>
+ The giant rats distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These are herbivores with a tendency to omnivory. They prefer fruits, but also subsist on tubers, grains, vegetables, leaves, legume pods, and wastes (such as banana peels). However, they are not grasseaters. Giant rats also kill and eat mice, insects (caterpillars, cockroaches, and locusts, for example), and probably many other small animals.3 They are particularly fond of mollusks (such as snails).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Reproduction is prolific and year-round. The female attains puberty at 20-23 weeks and the gestation period is about 20-42 days. The young are weaned at 21-26 days of age but stay with their mother until 2-3 months of age. So far, the record for the most litters has been 5 in 9 months. It thus seems possible that a female can reproduce 6 times a year. Litter size ranges between I and 5, but 4 is most common. Thus, in 1 year a single female could produce 24 or more young.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These strictly nocturnal animals usually lead solitary lives and forage alone. Mostly, they occupy a burrow by themselves, except when the </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">young are being raised. The burrows can be complex. Below the entrances are vertical shafts leading to a system of galleries and chambers for storing food, depositing droppings, sleeping, or breeding. The home range is individual and limited (1-6 hectares). In the wild, one male "supervises" the home ranges of several females.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In captivity, the animals are often seen sitting up and ramming large amounts of food into their spacious cheek pouches. With full cheeks, they return to their burrows and disgorge the food into a "larder." Food (chiefly hard nuts) is stored there.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They swim and climb well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">A study carried out in Nigeria showed that the giant rat produces about the same amount of meat as the domestic rabbit.4 The meat's nutritional value compares favorably with that of domestic livestock, and African villagers know how to preserve it by smoking or by salting.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The giant rat has recently attracted attention as a potential laboratory animal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Farmers in Nigeria have traditionally trapped the juveniles and fattened them for slaughter. They usually keep the animals in wire cages and feed them daily with food gathered in the wild as well as with scraps from the household.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As noted, the program at the University of Ibadan indicates that the giant rat can be domesticated. Already, specimens are being bred and reared in an intensive program. They adapt to captivity after about a month. They are subsequently transferred into breeding cages, which are wooden boxes with a rectangular wire-mesh "playroom." Each cage holds a breeding pair or a nursing female with its young. Experimental feeding cages have also been designed.5</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Food-preference trials show that palm fruits and root crops (especially sweet potato) are preferred to grains and vegetables. Nutritional studies show that the animals can tolerate up to 7 percent crude fiber in their rations. Although largely vegetarian, they eagerly consume dry and canned dog food. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These animals have several advantages:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· They are well known and much sought after for food.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· They have adapted to life in lowland tropics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">· They are able to live on locally available plant materials, including vegetable waste.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· They reproduce rapidly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">· They are more tolerant of captivity than the grasscutter (see next chapter). This is largely because omnivorous feeding makes them easier to feed than the grasscutter and other strict herbivores.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">This species could easily become a pest. It is recommended for rearing only in areas where it already exists. The crops it damages include cacao, root crops, peanuts, maize, sorghum, vegetables, and stored grains and foods. There is also the possibility that this rodent may transmit diseases to humans.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">A project at the University of Kinshasa in Zaire reports problems in getting giant rats to reproduce in captivity. When two specimens were paired they sometimes fought so viciously that copulation was impossible.6 Special management may be required, such as housing animals in adjacent cages before actually introducing them to each other. Moreover, selection for docility may also be necessary.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The ratlike appearance is not attractive, and a few African tribes have taboos against consuming the meat of these animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Throughout Africa south of the Sahara, giant rat domestication deserves experimentation and trials. Success would open up the potential for supplemental meat supplies in rural and urban areas where meat is now scarce. Tests are needed to determine the factors that favor breeding: temperature, aeration, light, privacy, and size and form of cages. Moreover, diets that are cheap and easy to make from local feedstuffs must be identified. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Further research on the domestication of the giant rat might include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">· Identifying husbandry techniques that are applicable at low cost in rural areas;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Studying food digestibility and setting up various diets;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">· Illuminating social behavior: pairing of animals, the best moment for pairing, duration of pairing, age of partners;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">· Outlining the basics of husbandry (for instance, capital costs, food conversion ratios, growth rates) and making simple and cheap cages;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">· Studying biology (anatomy, physiology, birth records, growth rate); and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">· Testing the practical likelihood that this rodent may transmit diseases to people and other animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The giant rat has an interesting commensal relationship with Hemimerus, an insect that feeds on secretions in the skin. It seems to cause no irritation or damage, and may even benefit the host by helping to keep the skin clean. Caging these animals results in the general loss of the insect, but attempts should be made to maintain them and to determine their role and life cycle.7</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The potential of this species as a laboratory animal in nutritional, clinical, and pharmacological research also deserves exploration. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">19 Grasscutter</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g023a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The grasscutter (Thryonomys swinderianus and Thryonomys gregorianus) is found in many forests and savannas of Africa. Its meat, said to resemble suckling pig, often sells for more per kilogram than chicken, beef, pork, or lamb. It is the preferred, and perhaps most expensive meat in West Africa. Indeed. in Ivory</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coast it sells for about $9 per kg. With prices like that, grasscutter is a culinary luxury that only the wealthy can afford.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">If domestication of this wild species were successful in providing meat at a price similar to that of poultry (the second most popular meat), markets would be unlimited.2 However, as production costs are high, long-term research will be required before grasscutter production can be profitable to the small farmer. This research should now be undertaken.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In an effort to capitalize on the markets for this delicacy, agricultural extension services of Cameroon, Ghana, Ivory Coast, Nigeria, Togo, and particularly Benin are already encouraging farmers to rear grasscutters as backyard livestock. They furnish breeding stock and information, and maintain central offices for records. In addition, a bilateral cooperation project in Benin has started experimental work on improved breeding methods combined with the study of animal responses under domestication.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In future, this vegetarian animal might become the African equivalent of South America's guinea pig, playing an important role in reducing Africa's chronic protein shortage. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Humid and subhumid Africa south of the Sahara.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Grasscutters are robust animals with short tails, small ears, and stocky bodies. Taxonomically, they are more closely related to porcupines than to common rats or mice.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Although many varieties have been described, there are probably only two species. The larger (Thryonomys swinderianus) weighs 9 kg or more and has a head-and-body length of up to 60 cm. The smaller species (Thryonomys gregorianus) may occasionally reach 8 kg and a body length of 50 cm.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Both species have yellow-brown to gray-brown bodies, with whitish bellies. The fur is extremely coarse, firm, and bristly - reflecting the animal's kinship to the porcupine. The tail is scaly and has short, sparse hairs. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Both species have thick, heavy claws and enormous orange incisors that can chew through even the toughest vegetation. (Grasscutters have been known to tear holes in corrugated iron fences.) Nevertheless, they do not bite when handled, although their claws sometimes cause injuries.4</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Grasscutters occur in grassland or in wooded savanna throughout the humid and subhumid areas of Africa south of the Sahara. They often live in forest-savanna habitats where grass is present. They do not inhabit rainforest, dry scrub, or desert, but they have colonized the road borders in forest regions. Distribution is determined by availability of adequate or preferred grass species for food. Specifically, Thryonomys swinderianus occurs in virtually all countries of west, east, and southern Africa. Thryonomys gregorianus occurs in savannas in Cameroon, Central African Republic, Zaire, Sudan, Ethiopia, Kenya, Uganda, Tanzania, Malawi, Zambia, Zimbabwe, and Mozambique.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Despite heavy hunting, these animals are not threatened with extinction. Nonetheless, many individual populations are well below carrying capacity, or are extinct because of local overexploitation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The larger grasscutter (T. swinderianus) generally lives in swampy, low-lying areas, especially along river banks and the borders of lakes and streams. Occasionally, it is found on higher ground among bushes and rocks, living where savanna grasses are dense and tangled enough to afford good cover. In Ivory Coast and southern Guinea, for instance, grasscutters are found (and hunted) throughout the savanna zones. And they can occur in close proximity to farmlands and people (for example, in southwest Nigeria).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Although the precise diet in the wild has not been determined, grasscutters are vegetarian. They consume nuts, bark, and the soft parts of grasses and shrubs. They particularly favor elephant grass and sweet potatoes. They commonly "raid" cassava and yam plantations, and are considered local pests.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Grasscutters reproduce year-round, although the births seem to peak at certain times of the year, correlated with weather conditions.5 Probably one male takes several females, and the family group possibly has more than one generation of young. The gestation is about 152 days. Apparently, litters normally contain between 2 and 4 young, but in Benin and Togo some litters of up to 11 or 12 are reported.6 Newborns are fully developed, their eyes are open, they weigh approximately 80 g, have thick fur, and quickly become accomplished runners.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p236a.png"></center><br>
+ figure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Although they commonly forage in groups, grasscutters are generally solitary. They are nocturnal, and they travel at night through trails in reeds and grass, often to water. Most specimens seen in markets are males, possibly because males lead the groups and are thus most prone to being trapped.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When alarmed, these animals stamp their hind feet and give a strange booming grunt. When fleeing, they can run very fast and, given a chance, will take to water. They swim with ease.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For shelter, grasscutters usually weave nests of matted vegetation or scoop out shallow burrows.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In a broad geographic band across sub-Saharan Africa, cattle raising is severely limited by trypanosomiasis. There, other sources of animal protein, including rodents, are traditionally used. Thus, grasscutter meat constitutes an important food for many Africans. The animals are mostly caught and eaten by families for their own use, but some are sold in markets and especially in roadside stalls. Many families depend exclusively on selling bushmeat, particularly that of grasscutters. In Accra, Ghana, during one year, 73 tons of grasscutter meat were sold in the local market. This represented more than 15,000 animals. In southern Africa, too, people find that these rodents make tasty food, although they may cut off the tail to make the carcass look less ratlike.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The meat is usually eaten smoked, and is so much in demand that grasscutters are hunted in organized drives with spears, dogs, and sometimes fire. It is considered excellent, especially when cooked in soups and stews or barbecued.7 It has been described as resembling venison in flavor, but it is dark like the meat of wild duck.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In the savanna area of West Africa, people have traditionally captured wild grasscutters and raised them at home. As an extension of this, organized grasscutter husbandry has been initiated in West Africa. The animals are provided with marshy, tightly fenced areas with plenty of plant cover. The young are harvested from these areas and raised separately.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ghanaian researcher Emanuel Asibey, a pioneer of this research, reports success at getting such captive stocks to reproduce. To this end, farmers are provided with breeding boxes and foundation grass cutter colonies. They are taught how to rear and feed the animals for home consumption or for cash income. Basically, the farmers make available large sheds where the animals can move freely. To prevent escape, the walls may be reinforced with cement plaster. The farmers also provide piles of grass, sugarcane, and other foods. A grasscutter reportedly takes about a month to adjust to such confinement. High mortality can occur in this period. The average weight of a mature, home-raised grasscutter is 4-7 kg. The average killing-out (dressed carcass) is 64 percent.8</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Wildlife Domestication Unit of Ibadan University in Nigeria, another pioneer of rodent domestication, has also reported the potential of domesticated grasscutter colonies.9</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research on grasscutter breeding, husbandry, and feeding is similarly being implemented by the Ministry for Rural Development in Benin and at the Lacena in Ivory Coast (see Research Contacts).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The demand for grasscutter meat is so large that it is not being met. Markets for it already exist over much of Africa,</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Grasscutters can devastate such crops as rice, sugarcane, soybeans, peanuts, yams, cassava, sweet potatoes, oil-palm seedlings, maize, young rubber, sorghum, and wheat. Therefore, as with most rodents, they should be reared only in areas where they already exist.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In past years, captive animals in Benin have suffered fatal Clostridium infections during September and October. In 1986, a broad-spectrum antibiotic was given with outstanding results. During this season, the animals also suffered from ascarid worms, which were also successfully treated with standard drugs.10</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Research is needed in the following areas:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Digestive physiology, feeding habits, feed preferences, feed conversion and growth rate; </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Diseases (pathogens and parasites);</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Captive breeding and management (growth rates, space requirements, feed needs, etc);</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Performance under different environments;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Productivity; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Basic biology (for example, chromosome type, reproductive physiology, and social behavior both in its wild state and under controlled conditions).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moreover, specimens should be gathered from different regions for comparative evaluation. A particular need is to select and breed docile specimens because today, even after several generations in captivity, the animal must still be handled with caution.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although domestication of the grasscutter is encouraged, wild populations might also be managed to maximize and sustain production through habitat manipulation. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">20 Guinea Pig</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g024a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea pigs (Cavia porcellus) are promising microlivestock because they require little capital or labor; provide an inexpensive, readily available, palatable meat; have no odor, and are suitable for keeping indoors. In the highlands of the Andes, many Indians raise them to supplement diets based on grains  and vegetables. Families eat them mostly on special occasions such as weddings and first communions, or they sell them to restaurants or peddle them in village markets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The low cost of these small animals makes them available even to many landless peasants. For both the small farmer and apartment dweller, the guinea pig is a possible food reserve. It converts kitchen scraps and marginal wastelands into meat. According to estimates, 20 females and 2 males may produce enough meat year-round to provide an adequate meat diet for a family of 6.2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Since husbandry practices are simple and cheap, the guinea pig is an excellent source of supplementary income. An FAO study at Ibarra, Ecuador, showed that on small mountain farms the guinea pig provided more profit than either pigs or dairy cows, partly because its meat fetched high prices.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although domesticated guinea pigs are mainly a food resource of Latin America, their use has also spread to parts of Africa and Asia. They are raised, for instance, in Nigeria, Cameroon, Ghana, Sierra Leone, Togo, and Zaire. In southern Nigeria, at least 10 percent of all households raise guinea pigs for food, with colonies of up to 30 animals per household. Guinea pigs are also raised in small cages or cardboard boxes by small farmers in the Philippines.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The feeding efficiency is high: studies have shown that it takes between 3.2 and 5.7 kg of forage to produce 1 kg of growth. This makes guinea pigs more efficient than most farm mammals. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea pigs seem especially adapted to the climate and forages of high-altitude zones, but the fact that they are being raised in Central and West Africa indicates that they are also adapted to the lowland tropics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p243a.png"></center><br>
+ The native distribution of the guinea pigs wild ancestor</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Worldwide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Guinea pigs have stocky bodies, fairly short hind legs, and short, unfurred ears. Adults can weigh up to 2 kg, but an average-sized specimen is about 0.5 kg. They are 20-40 cm long (average 28 cm) and have no tail. In domesticated forms, the pelage may be smooth or coarse, short or long, and in some types the hairs form rosettes.4 Domesticated types come in colors ranging from white to dark brown, as well as piebald.5 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The original home of the wild guinea pig is believed to have been the central highlands of Peru and Bolivia. Its domesticated descendants are important as meat animals mainly in that same area, but, as noted, they are also important in certain African and Asian countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A few strains are distributed worldwide as laboratory animals and pets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Domesticated guinea pigs, as a whole, are in no danger of extinction, although some rare strains are threatened.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These extremely adaptable animals are found in temperate zones and in the highland tropics, but they are usually kept indoors and protected from the extremes of weather. In Lambayeque and other departments of Peru, they are reared at elevations from sea level to more than 4,000 m. In areas where they are raised, daily temperatures fluctuate as much as 30&Yacute;C. In the Bolivian or Peruvian puna region, for instance, day temperatures can be 22&Yacute;C, while night temperatures are -7&Yacute;C. However, they cannot survive freezing temperatures and they may not perform well when exposed to the full tropical heat and sunlight. Many people of the Peruvian highlands keep the animals in darkness (for example, in wood boxes with little or no light).6</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animal's original wild habitat is believed to have been an area of grasslands, forest edges, swamps, and rocks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These herbivores can be raised on kitchen scraps, garden wastes, and weedy vegetation plucked from backyards or roadsides. Andean peasants mainly feed them potato peels, scraps of cabbage, lettuce, carrot, wild grasses, corn stalks, and the foliage of miscellaneous wild plants. Some barley and alfalfa is grown specifically for guinea pigs; it is cut green and sold in small bundles in the markets. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea pigs mate throughout the year except when climate is excessively adverse. Domestic breeds average 2-3 young per litter, although larger litters sometimes occur. The gestation period is 65-70 days with an average of 67. Females come into estrus every 13-24 days, and there is a fertile postpartum estrus.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Females can become pregnant when merely 3 months old, and many produce 4 litters every year from then on. In principle, a farmer starting with 1 male and 10 females could see his herd grow to 3,000 animals in one year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Newborns are so large that the female's pubic bones must separate for the birth. They emerge fully developed, with fur and open eyes. They look like miniature adults, and they start eating grass and other feedstuffs within hours. (For this reason, babies orphaned at birth have been known to survive.) Weaning may be reached as early as 21 days of age.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The life span in captivity is as long as 8 years, but animals used for breeding usually live only 3.5 years. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SUPER GUINEA PIGS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Even in their native region, guinea pigs have traditionally received little research attention. However, that began changing in the 1970s with the onset of meat shortages in Peru. (For a time the government restricted beef sales to only 15 days a month.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For instance, in 1972 Peru began a guinea pig improvement project. Researchers from i a Molina National Agrarian University traveled throughout Peru gathering many kinds of guinea pigs short haired long haired black, white, yellow, brown, and even purple. Practically all the guinea pigs eaten in Peru are home grown, and researchers observed that the bigger ones were generally winding up in the stew, leaving the smaller ones for breeding. The people inadvertently were making the animals smaller. (This is a common phenomenon for many animals.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To overcome it, the university research workers compared the mature size and growth rates of all the different guinea pigs. They selected and cross-bred the biggest, meatiest, and fastest-growing ones. This program, later taken over by Instituto Nacional de Investigacion y Promocion Agropecuaria (INIPA), produced remarkable results. The starting animals averaged little more than 0.5 kg, the resulting ones averaged almost 2 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Peru's "super guinea pigs" are now getting international recognition. They have been introduced into the highlands of Honduras, where the animal is also part of the Indian cuisine. The FAO has shipped some to the Dominican Republic. In addition, Bolivia, Ecuador, and Colombia have all begun their own guinea pig improvement programs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Within Peru the government has established 11 breeding stations to encourage the farming of guinea pigs for food. The goal is to provide better stud males to the people so that future animals will grow more quickly and reach a greater weight.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Guinea pigs generally congregate in small groups, normally made up of 5-10 adults. In favorable areas, however, such groups may coalesce into large colonies. The animals communicate incessantly among themselves, emitting a variety of squeaks and other noises.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Males, although good-natured with other species, often fight fiercely among themselves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Guinea pigs are raised mainly for meat. Peru has about 20 million, which annually provide 16-17,000 tons of meat (only 4,000 tons less than Peru's sheep meat production).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea pigs are used worldwide for studies on disease, nutrition, heredity, and toxicology, as well as for the development of serums and other biomedical research. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Guinea pigs require so little space that a small cage or pit can house up to 10 females and 1 male. They can be raised in cages with wire floors of small mesh as well. The labor required is low. A colony of 1,000 females reportedly can be properly cared for by one person. A layer of wood shavings, shredded paper, straw, and dried corncobs is usually recommended for bedding. The droppings are odorless, so the bedding does not need changing as often as with other animals. When the diet mainly consists of greens, much urine is produced, and then the beds have to be changed frequently.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When grown for meat, the young are weaned at 3-4 weeks and are ready for market in a matter of 10-13 weeks. Weight gain is rapid for the first 4-6 weeks, and then decreases. The carcasses normally dress out at about 65 percent, including the skin and legs. The meat's protein content is approximately 21 percent.7</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In a few regions of Peru, guinea pigs are "herded" on the open range and retired at night into small adobe coops.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">This small, inoffensive animal rarely bites, is easy to manage, and has no smell. It is an excellent supplemental meat supply. The improved breeds cannot climb or jump so that they are easy to contain. (Primitive "criollo" types, however, can jump.) If kept dry and given green vegetation, grain, and water, it survives in many environments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">A major constraint is consumer reluctance. Even in Latin America, attempts to promote guinea pig consumption outside the Indian communities have failed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When raised in a clean environment and under normal feeding conditions, guinea pigs thrive and reproduce and do not need routine vaccinations or antibiotics that cattle, sheep, and pigs often require. However, guinea pigs can be carriers of Chagas' disease and salmonella. Further, they are susceptible to pneumonia if temperatures change abruptly when conditions are wet. Coccidiosis and internal and external parasites are also common.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Green forages and surplus fruits or by-products are critical to provide vitamin C, which the animal is unable to synthesize for itself. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Since the greatest concentration of guinea pigs is found in the Andes, particular efforts should be directed towards this region. Already, research on guinea pigs has begun in some universities and government research stations in Colombia, Ecuador, Venezuela, Peru, and Bolivia, but more work is needed on matters such as:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Breeding "elite" stock for distribution;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Feeding and nutritional-requirement trials, especially for creating alternate feeds that peasants and commercial producers can use during seasons when conventional feeds are hard to get;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Diseases and parasites that may limit production in small farming systems;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Management practices concerning reproduction, housing, herd size, and feeding; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- The genetic basis for weight gain and productivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some research should be directed towards developing rations or introducing drought-resistant forages for the dry season because green forage is needed year-round. A range of practical and economical diets needs to be created.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Animal geneticists in Latin American countries should establish "elite" populations that can provide superior stock throughout the world. It can be anticipated that applying modern breeding methods to existing improved strains will result in great advances in a relatively short period and at little cost (see sidebar).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Three species of wild cavies (Cavia aperea, C. fulgida, and C. tschudii), close relatives of the guinea pig, are native to South America and are declining drastically. Research to preserve them is urgently needed. C. aperea is a widely used item of food in rural Brazil and other parts of South America. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">21 Hutia</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g025a.png"></center><br>
+ Hispaniolan Hutia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first meat Christopher Columbus tasted in the New World was probably hutia, a rodent avidly hunted by the Carib Indians. Hutia bones have been unearthed from kitchen middens of pre-Columbian inhabitants of all the Greater Antilles. Indians carried live hutias on voyages possibly in a semidomestic state as a source of food. On some islands, hutias were so eagerly sought that their populations were destroyed long before Europeans arrived. Slaves in the cane fields also hunted hutias for food. The surviving species later suffered when forests were cleared and cats, dogs, mongooses, and other predators were introduced. Consequently, the majority of hutia species died out, and today most surviving members of the family (Capromyidae) are facing extinction. Human predation continues in some areas (for instance, in Jamaica) where the tradition of "coneyhunting" still endures in a few regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hutias should be tested as possible microlivestock: success could create the incentive for their complete protection. The animals seem to take well to captivity. The Jamaican hutia is already overproducing in zoos, causing a local glut of animals. And hutias are, or were until recently, kept in barns by some people in Cuba, who fed them on banana and other vegetable waste and ate them regularly.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">POTENTIAL AREA OF USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The Caribbean.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Hutias are broad-headed, short-legged, robust animals with small eyes and ears. The various species are from 20 to 60 cm long and weigh from 1 to 9 kg - a size range from that of a guinea pig to that of a small dog. They walk with a slow, waddling motion, but can hop quickly if frightened or pursued. They also climb well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 10 1iving species are all big enough to be candidates for microlivestock. The best known and easiest species to keep in captivity are the Cuban hutia (Capromys pilorides) and Jamaican hutia (Geocapromys brownii). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Cuban hutia (also called hutia conga) is about 60 cm long, with coarse fur, a raccoon-shaped body, and a thick tail covered with sparse bristles. A forest dweller, it weighs up to 7 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The short-tailed Jamaican hutia is smaller: it is 33-45 cm long and weighs up to 2.5 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p252a.png"></center><br>
+ The hutias native range .</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Hutias are found only in the Caribbean (Greater Antilles and Bahamas). Most species are confined to a single island, where they represent the only remaining indigenous land mammals. The Cuban hutia is found only in Cuba. The Jamaican hutia is found only in Jamaica, although a close relative occurs on East Plana Cay, Bahamas. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">This once widely distributed and plentiful family is now failing. Of the 30 or so known recent taxa, more than half are already extinct, and the remainder all suffer from habitat alteration, predation by introduced animals, and hunting by man. With the exception of the Cuban hutia, all species are included on the list of the world's threatened mammals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Hutia ranges have been so reduced that these animals survive only in the most inaccessible forests and rocky drylands. Both the Cuban and the Jamaican hutias occur in a variety of habitats from montane cloud forests to arid coastal semideserts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Most species are terrestrial, but some live in trees. The Cuban and Jamaican species are terrestrial, but they can climb trees if circumstances demand. They maneuver well on trunks and larger branches, descending head first like squirrels.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hutias are primarily vegetarian, their diets consisting of leaves, bark, fruits, and twigs, as well as incidental catches of small animals such as lizards and invertebrates.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hutias seem to breed year-round, generally giving birth to litters of 1-4 offspring after a gestation period of 16-20 weeks. The young are well developed at birth, fully haired, open eyed, and capable of most adult movements. After 10 days they begin taking solid food, although they are not fully weaned for at least a month and a half (5 months for the Cuban hutia). Sexual maturity is at 10 months; life expectancy is 8-11 years in captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Jamaican hutia has one of the highest diploid chromosome numbers (2n = 88) of any mammal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Most hutias are wary and secretive and are easily displaced by human encroachment. They live like rabbits, hiding among tangled vegetation, in holes, and among rocks - communicating by voice and scent markings. They build shelters mainly in rock crevices, but also in the base of thick bushes or in natural cavities in trees. The Cuban hutia is often diurnal, whereas the Jamaican hutia is largely nocturnal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HISPANIOLAN HUTIA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The Hispaniolan hutia, or zagouti (Plagiodontia aedium) as it is known in Haiti is smaller than the two Capromyids discussed here, weighing just 1.2 kg. It is difficult to breed in captivity and has a lower reproductive rate than either the Jamaican or Cuban hutia. It is therefore less suitable as an economic or food source.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, there is a significant need for supplemental protein sources in both Haiti and the Dominican Republic. It might be possible to develop a special captive-breeding program for this animal, but it should be done with great care. It is important that a hunting tradition for this animal not be reestablished in rural areas of Haiti or the Dominican Republic, and that local organizations not be misled into believing that there will be a rapid increase in the numbers of this species in captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Hutia meat is relished, especially in Jamaica. The animals are still hunted, often by using dogs that smell them out and retrieve them from a hole or hold them at bay in treetops.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Experiences of zoos suggest that the Cuban and Jamaican hutias will thrive in captivity. The animals are generally long-lived and have survived up to 17 years. They are often friendly with their keepers and, when tame, can be held and carried about without any particular danger. However, if angered they can inflict deep bites and should normally be handled with considerable caution.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These animals are already much in demand. Their meat has an excellent flavor and they are big enough to provide a worthwhile quantity. If husbandry could be developed on a sustainable basis, it could be used as a mechanism for both economic development and for saving the remnant populations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Wild populations are threatened. Any captive population must be built up without endangering them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All hutias are susceptible to predation by domestic cats, mongooses, dogs, and human poachers, so care must be taken to design predator-proof breeding facilities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These animals are carriers of eastern equine encephalomyelitis, a serious disease of horses.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Hutias deserve urgent conservation attention. In particular, the following steps should be taken:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Establish reserves in natural habitats containing breeding populations to ensure the survival of the genetic diversity of these animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Build up breeding populations in suitable zoos and livestock research centers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Gather specimens from different regions for comparative evaluation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Investigate hutia biology, including chromosome type, reproductive physiology, nutrition, and diseases.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Assess experiences of zoos.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Perform captive breeding trials, measuring growth rates, space requirements, food needs, and social behavior (both in its wild state and under controlled conditions).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Study the social organization and tameability.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Colonies of some species could be established on uninhabited islands, as has been done with the Bahamian hutia Geocapromys ingrahami. Even this rare species might eventually be raised to yield meat for local inhabitants, as it is well adapted to dry and barren environments and was a regular food of the pre-Columbian Indians. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">22 Mara</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g026a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many wild relatives of the guinea pig are native to South America. Some, such as the guinea pig itself, are small; others, such as the mare, are much bigger. Maras1 (Dolichotis patagonum) are as tall as terriers and, at first glance, look like dwarf antelopes or huge hares They have large ears and eyes, long legs, and short tails. They generally behave like hares or wild rabbits, but, like deer, they run with a stiff-legged gait when pursued by predators.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These strange-looking creatures are found in temperate regions in the southern half of South America. They are dry-country animals, living on the thorn-scrub, desert plains of Argentina and the stony wastes of Patagonia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although exceedingly shy, restless, and watchful, mares tame easily, make good pets, and are much favored by the local populace. They were introduced to France last century, and in Victorian times Europeans sometimes bred them. These big, handsome rodents, grazing in little herds, were considered an attractive addition to the lawns of country estates.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">POTENTIAL AREA OF USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Maras are best kept in their native region of southern South America. With care, however, they could be used in other areas because they are slow breeders and their population growth is easy to control.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">At first sight, these large rodents look like some weird hybrid. They have the long ears of a hare and the tidy body and spindly legs of a small antelope. Although related to guinea pigs, they are long legged. The tail is short; the ears are long and erect.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Average-size mares weigh about 8 kg, but large ones can be 1 m long and weigh up to 16 kg.2 Females are larger than males. The coat is light in color, with grey upper parts and whitish underparts. The limbs and feet are tinged a yellowish brown. The pelage is dense, with individual hairs standing at nearly right angles to the skin. This gives a harsh texture, even though the hairs are soft and fine.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These animals can hop, walk, gallop, or run. They are extremely swift and can reach 45 km per hour over long distances. They are also accomplished jumpers, often leaping 2 m high from a standing start. The feet are compact and rather hooflike, but with sharp claws. The hind foot has three digits; the front foot has four.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The mare's range in the thorn-scrub desert and Patagonian steppe of Argentina extends from about 28&Yacute;S to 50&Yacute;S.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Endangered. These animals, once plentiful, are now threatened because of the introduction of the European hare, which is more successful at competing for food. In many of the eastern parts of its distribution (see map) it is now extinct.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Maras inhabit open, dry plains and other treeless semidesert areas of coarse grass or scattered shrubs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Maras are pure vegetarians. They feed on short grasses and herbs that are sparsely distributed between patches of dry desert scrub. Usually, they are satisfied with a few coarse weeds and the shoots of bushes. However, their overall diet consists of any available vegetation: leaves, roots, fruits, and stems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Female mares become sexually receptive within a few hours after giving birth. The estrous cycle is 35 days, plus or minus 5 days.3 The gestation period is 77 days. Each female gives birth to 1-3 young at the mouth of the den; the pups crawl inside to safety. Newborns are well developed, and within a few hours they begin grazing vegetation. They remain in the vicinity of the den for up to 4 months.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Initially, at least, the young are nervous and easily frightened.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Maras shelter in a burrow that they either construct for themselves or "borrow" from another animal that has abandoned it. They are active during the day and spend considerable time basking in the sun. They are always alert for danger. When alarmed, they flee at high speed. The white rump patch flashes a warning to the others, who then follow this "flag."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A fundamental element of their social system is the monogamous pair bond. Certainly in captivity, and probably in the wild as well, the bond between a pair lasts for life. When breeding, 20 or more pairs may band together temporarily to share a single den for the pups.4 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals stand on straight legs, sit on bent haunches with the forepart of the body resting on the fully extended front legs, or recline in a catlike position with the front legs folded under the chest, an unusual position for a rodent. They travel in single file, with the female usually leading. Members of a pair maintain contact by means of a low grumble. Although the long legs can quickly carry it to safety, a mare usually stops every 20-30 m and turns to peer at its pursuer.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals clean themselves by licking their sides and apparently by "combing" their fur with their teeth. They wipe their faces as cats do, with the inside of a foreleg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p260a.png"></center><br>
+ The maras native range</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Although the light-colored meat is said to be dry and flavorless, it is widely consumed in South America.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Maras have been successfully raised and bred in many zoos, and, as noted, have been kept as pets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Adults make little use of any shelter; they seem fond of being out and about in all weather. As long as they have a protected burrow for the use of the pups, mare populations can thrive in severe climates.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In zoos, diets include straw, vegetables, and crushed oats. Drinking water is supplied, although the animals rarely take it if they are feeding on fresh plant materials. They like to have salt blocks, however.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In South America, one mare lived in captivity for almost 14 years; most specimens do not live beyond 10 years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Maras are a good size for microlivestock. They have a short gestation period, and they are social and easy to maintain in groups. They can be successfully kept in pens and can be fed relatively low-quality forage. Colonies can grow to be quite large.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These animals can easily dig under the edges of cages and escape. Extra-deep foundations are needed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Following heavy rains, care must be taken to keep them from drowning in their subterranean burrows.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If suddenly disturbed, mares can become hysterical, leaping away regardless of anything in the way, and often seriously injuring or even killing themselves as a result. They fear bodily contact.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mare's monogamous nature in the wild is a likely limitation. But perhaps, like chinchillas, the animal will become polygamous in captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals are sensitive to tuberculosis when kept in humid conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Research needs to increase understanding of the mare include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Nutritional trials;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Husbandry experiments - measurements of growth rates, space requirements, feed needs;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Productivity tests;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Grazing-efficiency measurements;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Exploration of commercial details; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Determination of diseases and parasites. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">23 Paca</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Pacas (Agouti paca)1,2 are large, white-spotted, almost tailless rodents with the potential to become a source of protein for the American tropics. They are found in lowlands from Mexico to northern Argentina. The meat is white and is considered the best of all Latin American game meat. It is common in local markets and restaurants. Tasting like a combination of pork and chicken, it sells at higher prices than beef and is a regular item of diet in some areas. In Costa Rica, pace is served on special occasions such as weddings or baptisms. It has a higher fat content than the lean meat of agoutis, rabbits, and chickens, and has no gamy taste.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Paca has promise as a microlivestock. In several countries, Belize and Mexico for example, people already keep them in cages beside their homes and fatten them on kitchen scraps. In Costa Rica, some are bred on farms, under houses, and even in apartments. Research on raising paces in captivity is under way at the Universidad Nacional in Heredia, Costa Rica; at the Smithsonian Tropical Research Institute in Balboa, Panama (see page 196); and at the Instituto de Historia Natural in Tuxtla Gutierrez, Mexico. In Turrialba, Costa Rica, an entrepreneur is already breeding and raising pace commercially.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While the pace has potential as a food source, many problems still must be resolved before it can be recommended for mass rearing. If solved, however, this species would become an attractive microlivestock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The pace has potential for use throughout its vast geographical range in Latin America.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In general appearance, paces are somewhat like giant guinea pigs. The legs are short, the forefeet have four "fingers," and the hindfeet have five small, hooflike "toes." The feet are partially webbed and are adapted both for digging and for swimming. Pacas burrow with all four feet as well as their teeth; even large roots are no obstacle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Adults weigh 6-14 kg, males being somewhat larger than females. Although they may become bulbously fat, paces remain "one of the fastest things on four feet. " From a standing start, even a fat specimen can jump at least 1 m off the ground. Pacas are also agile. However, their skin's epidermal layer is thin and fragile, and large strips may be ripped off as they rush headlong through spiky undergrowth. However, such wounds heal astonishingly fast - frequently within days.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pacas are chocolate brown in colon The head is somewhat lighter in shade than the body, and the underparts are whitish or buff colored. There are usually four longitudinal rows of white spots that may merge into stripes along each side of the body. The fur is coarse, spiny, and slippery, and has no underwool. Each hair is stiff, relatively sharp, and very smooth, which makes paces extremely difficult for predators to hang on to.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Parts of the cheekbones are enlarged, and the cheeks can open to form special pouches. This is more developed in adult males than in females - indeed, adults can be readily sexed by head shape. The pouches are outside of the mouth and are fully haired. The animals use them mainly to create a resonating chamber for their booming bark and noisy tooth grinding. These enlarged cheeks push the large bulging eyes toward the top of the skull. The eyes are suited for nocturnal conditions, the senses of smell and hearing are uncannily acute, and there is an array of long whiskers that is used when maneuvering at night.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Lowland paces are found throughout most of Latin America from east central Mexico to northern Paraguay, Argentina, and Minas Gerais, Brazil. This includes all of Central America and most of Colombia, Ecuador, Peru, Venezuela, and the Guianas. The animal has also been introduced into Cuba.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p265a.png"></center><br>
+ The pacas native range</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Burgeoning human populations are severely reducing many of Latin America's native animal resources, and the pace is one of the most persecuted. It has been exterminated within hunting range of virtually all cities, towns, and villages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Several governments, recognizing the pace's plight, have passed laws prohibiting the hunting and marketing of its meat. Nevertheless, people continue to take it, usually at night, using trail dogs and headlights.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Pacas thrive in a variety of tropical habitats but are most common in forests, swamps, and partly cleared grazing lands. They inhabit most types of forests from deciduous woodland to rainforest. Usually, they stay near streams or rivers, but they often live where there is no permanent water. They are abundant only in little-disturbed forest areas. Although preferring low, dense tree cover, paces sometimes inhabit open rocky areas and farmland.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These herbivores feed mainly on fruits, young seedlings, and some seeds. However, when fruits are scarce they may switch to browsing leaves and roots. They probably sometimes eat large insects, and, on rare occasion, may perhaps eat small vertebrates. Captive paces, like many other "frugivores," seem to develop a protein deficiency and will eagerly eat meat scraps on occasion.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The young are usually born singly after a gestation period of 146 days. There are probably 2 births a year. Females have an estrous period that begins shortly after giving birth. If mating does not take place at this time, the female becomes unreceptive until after the 3-month (sometimes 4- to 6-month) lactation is over. The length of the estrous cycle is 30 days.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During daylight hours, paces seclude themselves in brushy cover, in or under fallen logs, or in extensive underground burrows. The burrows, which may be several meters long, are dug in moist soil or taken over from other animals; they are often in river banks, on slopes, among tree roots, or under rocks. Usually, several exits are provided, often being plugged with leaves as a disguise.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In the wild, paces dig large holes and rummage about the forest floor at night, gnawing on fruits. Pairs inhabit a defended area, sometimes living together in the same burrow, sometimes not. Also, they usually travel alone, following paths that lead to feeding grounds and water. Individual home ranges are small (1-3 hectares).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although paces are terrestrial, they enter water freely, they swim well, they copulate in water, and, when alarmed, they generally attempt to escape by swimming. They are also lively and playful; however, they can be exceedingly obstinate. Sometimes fighting among themselves becomes very savage. When angered they growl, sometimes noisily, and they can suddenly jump on aggressors, real or imagined, delivering frightful wounds with their chisel-like front teeth thrust forward like a spear. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As noted, pace meat is tasty and brings high prices in the markets. It is considered a delicacy in fine restaurants and was served to Queen Elizabeth during her October 1985 visit to Belize. In Mexico, paces, like pigs, are usually boiled unskinned. Even the skin is then edible.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">If treated appropriately when young, paces become manageable. They undergo "imprinting," a characteristic of most species that have been domesticated. An imprinted pace becomes so tame that it seeks out human company, follows people around like an amiable dog and, if turned out of its cage, returns voluntarily. (To achieve this degree of tameness it is necessary to remove the animal from its mother at an early age.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although wild paces are almost entirely nocturnal, tame paces are more active during daylight hours.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Young or partly grown paces are commonly exhibited in zoos. They eat prodigious quantities of almost any vegetation and have been called, "a good substitute for a large garbage pail." Diets can include rolled oats, raw vegetables, bananas, apples, and bread. They probably need additional protein occasionally, and seem to appreciate some fat in their diet.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">If husbandry can be developed, the clamor for pace meat throughout tropical America would be a big economic incentive for farming these animals. The excellence and wide acceptance of the meat is an indication that pace farming would be taken up both in rural and urban areas and by many levels of society.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Pacas can harbor human diseases, including leishmaniasis and Chagas' disease.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Apart from the project in Panama (see page 194), paces have bred only sporadically in captivity, with few offspring surviving. However, successes have been recorded in zoos in London, San Diego, and Washington, D.C., and in a research project in Tuxtla Gutierrez, Mexico. In Costa Rica, they are also reportedly breeding well, with a survival rate of 90 percent since 1982, and 80 percent of the females are reproducing.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All adult paces can be aggressive and dangerous. Their powerful incisors can inflict serious wounds. (They can even rip through planks.) Intraspecific aggression is one of the most serious impediments to captive breeding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unlike the capybara, the pace not only has a long gestation but usually bears a single young. Thus, the output of a single breeding female may be, at best, two offspring per year (at least this is the expected production in the wild). This "slow" breeding is a limitation. In captivity, however, there is a possibility that it can be speeded up.4 The fact that paces bond together in pairs is a limitation. If every female has to be accompanied by a male, then many (otherwise unnecessary) males have to be fed and maintained.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Male paces are considered difficult to keep as household pets because they spray females (or human substitutes) with a mixture of urine and glandular secretions. This can occur several times a day. In addition, they have anal glands that produce a musky odor that some people find objectionable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Although paces are common in some areas over the vast region from Mexico to Argentina, they are little understood, even by zoologists. In fact, most data concerning this animal have come from interviews with local hunters. Intensive field work is needed to develop an understanding of the pace's biology, status, and habitat requirements.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The popularity of pace meat makes it urgent to start this work as well as to begin breeding paces on an organized basis. Such projects would lay the groundwork for preserving the species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Particular research needs concern the following:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Age structure and reproductive performance;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Growth rates and feeding habits;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Behavioral patterns in captivity;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Nutritional requirements;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Meat quality;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Helminth and arthropod parasites;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Role in transmitting or perpetuating diseases;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Reproduction (such as external manifestations of estrus in females); and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Genetic variations that would allow the selection of animals adapted to captivity and females that produce multiple offspring - twins, triplets, or more.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Ways must be found to introduce more than one female to each male without inciting aggression. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">24 Vizcacha</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g027a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vizcachas (Lagostomus maximus) are soft-furred South American rodents that look like long-tailed guinea pigs. They can weigh as much as 8 kg and are resilient animals, inhabiting dry pampas and shrub lands in northern Argentina and neighboring countries. They seem to have promise for producing meat and hides in marginal zones whithin their native habitat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like chinchillas (page 277), these rodents provide a prized furry pelt. They also provide meat that reportedly tastes "as good as hare," which in Europe is considered the epitome of dining. They are easily trapped alive in cheap, homemade, multiple-catch, funnel traps. And they are thought to be suitable for farming on a large scale.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the other hand, vizcachas are currently considered pests because they take grazing from cattle and sheep and because they build large burrows that undermine the land. Government campaigns have eradicated them in the richer agricultural areas of Argentina, but the animals are still common in marginal zones. There is evidence that they become more abundant when domestic livestock overgraze the land. In improverished marginal sites, where other livestock enterprises are unsuitable, the potential exists for game-ranching vizcachas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Because of the potential hazard to new areas, vizcachas can be used only in the pampas regions of southern South America where they are already widespread.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Vizcachas have short front legs, long, muscular hind legs, and round eyes and ears. Their heads seem oversized in proportion to their bodies. Males weigh 5-8 kg, females 2-4.5 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Members of the same rodent subfamily as the chinchilla, they have a thick, soft, valuable fur that is grey or brown above, whitish or greyish below. They are, however, much larger than chinchillas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although basically running animals, vizcachas often jump bipedally (like kangaroos), and they sit erect while eating or grooming. The forefeet have four long flexible digits used to grasp food. Their soles and palms are naked and have fleshy pads (pallipes).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Vizcachas once swarmed widely over the savannas of southern Paraguay, Bolivia, and Argentina, but they are being systematically exterminated. Today they inhabit isolated areas of north, central, and western Argentina and southern Paraguay.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Since 1907, these animals have been mercilessly hunted. The governments of the Argentine provinces where they are mostly found, reward hunters for killing this "pest." However, the numbers are so reduced that now there is no need for a bounty system.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Vizcachas live in flat, dry, steppelike plains; in dry woodland (Chaco), and in low mountains.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The fact that these rodents eat their own droppings (coprophagy) augments their ability to utilize natural forages, and allows them to abound in degraded zones. They feed on any plant materials they can find near their colonies, particularly grasses. In feeding trials, their daily dry matter intake was 2-5 percent of the body weight. The metabolic efficiency (dry matter per kg) was 33-56 percent; the digestive efficiency was 50-60 percent.2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Male vizcachas become sexually mature at about seven months of age and remain fertile throughout the year. The gestation period is long: 154 days. Litters contain one or two young. Newborns are well developed, fully furred, and open eyed, although they cannot fend for themselves for at least three weeks. In the wild, one or two litters are reared each year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Vizcachas are nocturnal and are active year-round. They inhabit underground burrows, living in colonies often containing many individuals. They collect a variety of materials (for example, bones, sticks, and stones), and heap them in piles above the entrances to their burrows.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Their hearing and sense of smell are acute. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p274a.png"></center><br>
+ Vizcachas native range</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Vizcachas have long been hunted for food as well as for their fur. Their meat is often consumed in pickled form in southern South America.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The skins are fabricated into table runners, rugs, bedspreads, slippers, and belts. The skins are also popular for overcoats.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vizcachas can be kept in captivity without major difficulty.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In zoos, vizcachas are fed the typical diets furnished for vegetarian rodents: rolled oats, green vegetables, bananas, apples, and bread. They are usually kept indoors in wire-fronted cages, about 1 x 2 m in size, and provided with sleeping boxes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Little is known about vizcacha husbandry, but in one trial, weight rose most rapidly in males until age 18 months (the average size was then 5.3 kg) and subsequently slowed. The heaviest male was 7.3 kg at 30-32 months. The female's weight gain was greatest until 16-18 months (average size 3.3 kg).3 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The animals seem well adapted to harsh sites where the climate and forage make raising conventional livestock difficult.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The meat is white and has a good nutritive value because of its high digestibility, low levels of saturated fats, and high levels of proteins.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In marginal zones of the pampas, these rodents appear far more productive than traditional livestock.4</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Vizcachas may do considerable damage by foraging in cultivated crops. As noted, ranchers claim that they take grazing away from domestic animals, 10 vizcachas eating as much as a sheep. In addition, they claim, vizcachas destroy pasture with their acidic urine. And the large burrow systems sometimes create a hazard.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because their reproductive rate is low and their growth rate is only moderate, their commercial breeding might not be profitable except in well-designed projects with clear markets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vizcachas require sturdy pens, which implies a high initial cost for materials such as concrete and brick.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vizcachas can be aggressive to one another, especially in captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">There are several possible research projects, including:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">- Gathering specimens from different regions for comparative evaluation of characters such as biology, chromosome type, reproductive physiology, social behavior (both in its wild state and under controlled conditions);</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Attempting captive rearing and small-scale husbandry;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Assessing performance under various environments; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Quantifying productivity and population dynamics in relation to rangeland use and improvement practices.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">A rational cropping program based on wild stocks is perhaps more viable than captive breeding. This could be organized so as to keep vizcacha numbers in check while sustaining a small chain of processing plants by providing a constant supply of meat and skins. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">25 Other Rodents</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The 10 previous chapters have described some rodent species that show promise as microlivestock. Rodentia, however, is one of the largest families of mammals, and the species highlighted by no means exhaust the possibilities. In this chapter we briefly mention others that deserve consideration and exploratory research. These might prove to be potential resources, at least in localized situations. Several are fast nearing extinction and they deserve protection and immediate attention from animal scientists.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CHINCHILLAS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In the high Andes of South America are found the short-tailed chinchilla (Chinchilla brevicaudata) and the long-tailed chinchilla (Chinchilla lanigera). These plump little rodents have fur that is possibly the thickest, softest, and warmest of any animal's.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the surface they would seem to be ideal candidates for microlivestock in Third World regions. Indeed, in recent years chinchilla-rearing has been successfully carried out in northern India. However, raising these animals for commercial markets is a highly specialized and costly business because only rare and expensive breeding stock produces top-quality pelts, and all other pelts are worthless in today's marketplace.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These guinea-pig-sized animals have round ears, a bushy tail, and range from 25 to 50 cm long. Adult males rarely weigh more than 500 g, but females may weigh up to 800 g.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PACARANA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The pacarana (Dinomys branickii) is the third-largest living rodent only capybaras and some beavers are larger. But little is known about this seldom-encountered, forest-dwelling species. Nevertheless, pacaranas appear to be likely candidates for domestication. They are amazingly even-tempered and peaceful, and become surprisingly tame.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because these animals are endangered they are unlikely candidates for microlivestock in the short run, but their large size and good meat could be the stimulus for an international effort to study, protect, and rear them in large numbers before it is too late.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pacaranas are found along the eastern foothills of the Andes, including parts of Bolivia, Brazil, Colombia, Ecuador, and Peru. Their area of potential use is in Latin America and the Caribbean.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It would be advantageous for livestock scientists to investigate this species in captivity. Studies are needed of the animal's general biology, including its nutritional requirements, reproductive capacity, behavior, and physiology. For wildlife specialists, there is a compelling need to protect this species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SPRINGHARE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Scattered through the dry lands of eastern and southern Africa - on numerous grasslands, plains, fossil lake beds, hill slopes, and floodplains - is the springhare (or springhaas). With its powerful hind legs, tiny forelegs, upright stance, and hopping gait, it looks something like a tiny kangaroo. It is commonly seen at night, eyes glowing a characteristic red in the headlights.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This animal is an important source of food and skins for rural peoples throughout southern Africa. In Botswana, it is the principal bushmeat in the human diet.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Springhares are 35-40 cm long and weigh 3-4 kg. There is one species (Pedetes capensis) and two subspecies: the East African springhare and the Cape springhare (formerly Pedetes cafer). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROCK CAVY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The rock cavy (Kerodon rupestris) is closely related to the guinea pig and occurs in the impoverished semiarid region of northeastern Brazil. It is large and lean and has a face somewhat resembling a dog's. It is hunted extensively and is an important source of meat for country people, who consider it a delicacy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This creature might be suitable as a microlivestock. It consumes leaves and bark, and breeds well in captivity. Famine is a serious periodic problem in the often-drought-stricken area, and protein deficiency is common. The rock cavy, like the guinea pig, may be amenable to domestication and may be able to provide the people with better nutrition. However, it is difficult to keep in a cage because it moves fast, climbs well, and easily slips out.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because these rodents occur in rare and patchily distributed habitats, they are in desperate need of protection, whether or not they prove to have any long-term utility.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SALT-DESERT CAVY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">A smaller relative of the mare (page 256), the salt-desert cavy (Dolichotis salinicola) is rabbitlike in appearance and behavior. It has large ears and eyes, long legs, and a short tail. It lacks the mare's white rump patch.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This animal inhabits dry, salty areas of the Chaco desert, particularly areas of dry, woody brush. Specifically, it is found in the saline western Chaco of Paraguay and northwestern Argentina, as well as in the extreme south of Bolivia. It is about 45 cm long and weighs up to 4 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although it might make a useful microlivestock in its native habitat, the salt-desert cavy breeds rapidly and can cause much devastation; it should never be introduced to new regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The salt-desert cavy's life in the wild is largely unknown; however, some have been successfully raised and bred in zoos. Exploratory research on keeping and managing these little creatures is warranted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">OTHERS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As noted earlier (page 193), it has been estimated that 42 peoples of various cultures eat rodents. Most of these eat locally available species, some of which are listed below. Whether any have long-term usefulness is uncertain, but study of them in the wild and in captivity could result in some interesting and valuable scientific discoveries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Solomon Islands Rodents</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The Solomon Islands in the southwest Pacific are home to a collection of six rare giant rodents that live in the rainforest canopy. At one time they were important food items. Archeologists have dug up tens of thousands of rodent bones on sites where people lived as long as 30,000 years ago. These mysterious animals were classified last century, but most have not been seen by biologists for decades. However, one, the thinking rat (Solomys sapientis), was rediscovered in 1987 - the first time it had been reported seen since 1901. The others may also be inhabiting the dense and undisturbed forests.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The thinking rat was located on the island of Santa Isabel. It proved to be gentle, unafraid, and friendly. It lives in the forest canopy, weighs up to 1 kg, and feeds on nuts and fruits. Efforts to build up the population are urgently needed. The other species should also be sought.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Such animals could be a resource for rainforest production (perhaps in the manner of butterfly farming in Papua New Guinea2). They may never be plentiful enough to be food sources again, but they could nonetheless become valuable. Zoos the world over are likely first customers for these scientific curiosities if production can be boosted and the populations secured.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Giant New Guinea Rat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The giant New Guinea rat (Mallomys rothschildi) is often eaten in New Guinea. It is little known to science but is odorless and easily tamed. It grows so fast that it becomes as big as a guinea pig even before it is weaned. It feeds on a wide variety of tubers and vegetable products. An attractive species native to mountain forests, it has a long heavy tail and black fur with white ticking.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Porcupines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Porcupines, brush-tailed porcupines, and their relatives are distantly related to guinea pigs and are widely consumed as food in tropical regions. Examples are:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">- Indian porcupine (Hystrix indica) and other species of South Asia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Cape porcupine (H. africaeaustralis) of southern Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Prehensile-tailed porcupine (Coendou prehensilis), which inhabits Central and South America. These nocturnal creatures live in the thick, leafy crowns of trees or in hollow trees or holes in the ground. Although often belligerent among themselves, they can be very friendly and tame toward humans.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kiore</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The kiore (Rattus exulans) was formerly an important component of  the diet of most Polynesians, including the Maoris of New Zealand. It  has been successfully reared in captivity in recent times. Unlike many  other rodents, this animal is normally not a scavenger; it is a clean,  even fastidious feeder that is basically a vegetarian (flowers, berries,  nuts, and seeds) and is reckoned remarkably good eating.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Soft-Furred Rat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The soft-furred rat (Praomys) is relatively large and slender and is  found in the tropical forests of Africa from sea level to more than  3,000 m. Among the most common rodents of the African jungle, it is  trapped almost everywhere. It feeds largely on plants, but eats large  quantities of ants and other insects. It has been raised successfully in  captivity and is eaten by villagers in Malawi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Giant Squirrels</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The giant squirrel (Ratufa bicolor) occurs throughout Indonesia,  Malaysia, and Sri Lanka. It is the largest squirrel on earth, almost the  size of a cat. A related species, the palm squirrel (Funambulus), also  gets very large. It can crop nuts in the very high treetops that are  inaccessible to people. It is widely used as food.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Squirrels</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Squirrels of the genus Callosciurus (notably C. notatus and C.  prevostii) are significant pests on cocoa, oil palm, and mixed fruit  plantations in Southeast Asia. They can be reared and bred on a diet of  most types of fruit as long as a little protein, in the form of insects or  cooked wheat, is available. The systematic use of this animal may  offer a chance to turn a pest to advantage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cloud Rat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Two species of slender-tailed cloud rats (Phlocomys spp.) are found  only in southeastern Asia. They live in tree cavities, climb well, and  are well adapted to tree life.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of these (P. cumingi) lives in the northeastern part of Luzon in the Philippines, where it appears to be thriving. It has a large body and long tail and is the largest member of the mouse subfamily.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The other (Crateromys schadenbergi) has long, thick hair and a thick, bushy tail. It lives in the mountainous areas of northern Luzon. A nocturnal animal, it feeds on buds, bark, and fruits.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Both are attractive, even fascinating, creatures that are relentlessly hunted for food. They might make useful livestock in forest situations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Spiny Rat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The Cayenne spiny rat (Proechimys guyannensis) is found throughout most of South America. It is tasty, easily kept in captivity, and is popularly used in Colombia for food. A nocturnal animal, it is one of the most common mammals in many areas. It has been raised in captivity on bananas, sweet corn, coconut, grain, and various seeds.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bamboo Rat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The bamboo rat (Rhyzomys spp.) is the largest rodent on the island of Sumatra in Indonesia; it weighs 2-4 kg and the body can be as long as 45 cm. It prefers to live in bamboo thickets and is hunted and eaten by many local peoples.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is a need - in considering any sort of game farming - to relate the animal's "preferred" conditions (range, feed, temperature, etc.) to the varying land and climate types not being effectively utilized. In other words, rather than looking at animals that might be farmed, it might be necessary to consider the terrain and climate and then seek animals that would "do" well under those conditions. One major fault with traditional farming has been the tendency to force traditional livestock onto unsuitable land. This has given rise to numerous serious problems. In many cases the most suitable use of an area is provided by several species grazing together to mutual benefit (e.g., goats and sheep on New Zealand hill country improve grazing for each other if ratios are right).</P>
+<P ALIGN="JUSTIFY">David Yerex</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g028a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Part V : Deer and Antelope</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Several types of tropical deer' and antelope are no bigger than an average-size dog. These "microdeer" and "microantelope"2 are the smallest of all ruminants. Although there is considerable experience with rearing and utilizing the larger species, little is known about these miniature ones.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Given research, mouse deer, muntjac, musk deer, pudu, brocket, huemul, and water deer, as well as half a dozen small antelope, might prove to have considerable potential. Collectively, they come from diverse habitats, ranging from equatorial to subarctic and from moist rainforest to arid savanna. They are adapted to some environmental conditions that are only marginal for production of conventional livestock because of drought, heat, diseases, altitude, or other constraints.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DEER FARMING</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Deer appear to be unlikely candidates for livestock, but reindeer were probably among the first domesticated animals and have been draft animals for perhaps 2O,OOO years. Even today, tens of thousands of reindeer pull sleighs in the European arctic. On military expeditions, the ancient Romans took along herds of fallow deer as a source of meat, and more than 1,000 years ago deer were annually herded off the Scottish Highlands for winter meat supplies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In recent years, there have been breakthroughs in the "domestication" of deer. Species already being [armed are: red deer (New Zealand, Australia, Taiwan, Korea, Russia, China, Scotland, the United States), elk (New Zealand, Canada, the United States), fallow deer (New Zealand, Australia, England, Denmark, Sweden, Switzerland, Germany, the United States), ruse deer (Australia, Mauritius, New Zealand, Papua New Guinea), sika deer (Taiwan, New Zealand), musk deer (China, India), and PFre David's deer (New Zealand). Although not truly domesticated, even the moose has been tamed in Scandinavia and the Soviet Union, the calves being bottle-raised from three days of age.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">New Zealand has made particular progress in domesticating large deer (see sidebar). It seems probable, therefore, that similar success with small deer could be achieved. For those seeking interesting, pioneering research, microdeer are good candidates.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ANTELOPE RANCHING AND FARMING</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The worldwide experiences in domesticating various deer species suggest that the organized production of small antelope should also be considered. Several large species have already been studied and are used in game farming in eastern and southern Africa. Similar research on the smaller species, which so far have received little or no attention, is one of the more speculative ideas in this report. We put it forward only for consideration by researchers, but if exploratory studies prove successful, this is a topic deserving international support.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In some parts of Africa there are large expanses of uninhabited lands, and producing any sort of livestock there is limited by aridity and by the presence of tsetse flies. But in this habitat live tiny antelope such as dikdik, suni, and klipspringer. In the rainforests and secondary forests are found duikers and the royal antelope. All these creatures have advantages that justify their consideration as microlivestock: they have a more rapid turnover than the big species, and they produce a high yield of quality meat. In addition, compared with cattle, these native ungulates make better use of the habitat. Cattle select a limited number of grass species; antelopes choose a wider range, and also include fortes, bushes, and trees.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More important perhaps is their resistance to many diseases. Most, if not all, are resistant to trypanosomiasis, the disease carried by the tsetse fly. They are not immune to this and other tropical diseases, but they are less susceptible than cattle. However, part of this may be owing to their ability to roam widely; if confined and treated like domestic animals, they may also require some protection against parasites and diseases.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antelopes are also more productive than cattle; that is, they produce a given quantity of meat more quickly because they breed better in the African hinterlands and grow more rapidly on its existing forages. On the other hand, they generally require a richer diet than cattle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, in their favor, antelopes affect the habitat less than the same density of cattle does; they spread out more while feeding and thereby cause less erosion.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are two ways of exploiting this potential. One is by "cropping"taking a controlled offtake from free-ranging populations without depressing the overall population. Several methods for producing meat this way from large antelope have been attempted in countries such as Kenya, Tanzania, and Mozambique. Few have persisted. Often this has been due to opposition from the vested interests of the cattle industry and from stringent veterinary requirements. Nonetheless, game ranching offers a means by which marginal lands could produce food of a high nutritional quality on a sustained basis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The other method is by farming - that is, domesticating or partially domesticating the animals, keeping them in pens or herding them like cattle. Experiments in farming antelopes have been less common than game ranching, but one of the most interesting is that conducted on the Galana Ranch in Kenya. Three wild species - buffalo, eland, and oryx - were selected for comparison with cattle. Half-grown animals were preferred for capture, and it was found that if they were kept in the dark for the first week after capture, and then gradually provided with more and more space while they became familiar with people, after about six weeks they could be released into the open and herded from place to place. Grazing during the day under the eye of a herdsman, they allowed themselves to be herded back to a pen at night in the traditional African manner, where they would sleep around the campfire. This was a promising advance in behavior modification leading toward domestication. The oryx, for example, gained weight on grazing that would not even sustain cattle, and it required only a quarter of the amount of water.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At bottom, the question is not what contribution antelopes can make to the African larder, for they already make a significant contribution through (largely illegal) hunting. The question is whether farming could make them a sustainable asset rather than their being senselessly squandered, as is the case at present. Although its potential has yet to be realized, antelope farming is not a panacea for Africa's food problems, and certainly not the world's, but it might pave the way to a new and more gentle way to make savannas useful. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">TAME GAME</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Since the 1970s, deer have taken the place of sheep on many New Zealand pastures, and today the country has more than 5, 000 deer farms carrying over one million head, mainly red deer. It is now common along country roads to see tall fences surrounding graceful deer quietly grazing ryegrass and clover. And there are all the appurtenances for deer that exist for cattle and sheep. Auctions and shows are held regularly. Deer farmers have a professional association and produce their own glossy magazine. Government scientists publish pamphlets on the care and management of deer. There are recognized stud stags, computerized recording schemes for breed improvement, and even veterinary services specifically for deer. Hybridization between wapiti and red deer, and PFre David's deer and red deer, is accepted practice. The animals are moved by use of dogs (which command by mere presence rather than by bark or bite), and herds of up to 80 are shifted by truck. Slaughter facilities specifically for deer are in operation throughout the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This transformation of a nervous, jumpy, and retiring wild species into a farm animal is a remarkable achievement. Once accustomed to people, many specimens become gentle, even affectionate, and will come at a farmer's call. Males are generally as easy to handle as females, except during the rutting season when they become aggressive and cannot be handled at all.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, even at the best of times the farmed deer must be handled gingerly. If the causes of stress are not quickly suppressed, hysteria can erupt throughout a herd; in an instant, quiet animals can be leaping suicidally in all directions, disoriented, diving head-on into fences, charging gates. Chronic stress, the causes of which are not always obvious, can result in illness or death, although this trait diminishes in subsequent generations of farm-born stock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A deer farm has to be laid out to certain special specifications. To prevent escapes, the boundary fences must be 2 m high with netting of 15- or 30-cm mesh. Inner fences need only be 1.5 m high. Water troughs are placed in the middle of the fields, and nothing is allowed to jut inwards from the fences because the animals tend to walk fencelines and take comfort from the illusion of openness. Because deer like to wallow in hot weather, some farmers also provide shallow waterholes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Deer yards can be of any design, but the sides of the passageways and holding pens should be solid, as deer do not see fences very well, particularly when under pressure, and may injure themselves in a leap towards what appear to be wide open space. (New Zealanders usually make the sides of plywood.) Also, the holding pens should be roofed, as semidarkness has a calming effect. Animals that in the sunlight become hysterical on seeing a person in the distance, can, in the relative darkness of a roofed shed, be touched and even given injections.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite the special facilities, however, handling deer takes time and care and experience. The most successful farmers spend much time among the deer so that the animals become accustomed to human presence. This helps to make yard work easier. Also, new arrivals are allowed to wander through the yards on their own to become familiar with them. In addition, special tame deer are used as leads or decoys to encourage the rest of the herd to follow. Using such simple techniques, a formerly intractable species has become almost fully domesticated.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">26 Mouse Deer</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g029a.png"></center><br>
+ Lesser Malayan Deer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mouse deer1 (Tragulus spp. and Hyemoschus aquaticus) are among the smallest ruminants known. The lesser mouse deer of Southeast Asia is probably the smallest; an adult stands only 20 cm high and weighs a merc 1-2.5 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although they look vaguely like tiny deer, mouse deer differ in several particulars. The stomach is simpler and (like the camel's) has three instead of four effective compartments. Rumination occurs, but mouse deer are the most primitive of all ruminants. Indeed, they share a number of characteristics with nonruminants, including lack of horns or antlers; continually growing, tusklike upper canines in males; sharp-crowned premolars; and four fully developed toes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Virtually unchanged in 25 million years of evolution, these are solitary, nocturnal, retiring animals that have seldom received detailed research. Whether they might make suitable microlivestock is unknown. However, they seem to be tractable, and people in Southeast Asia (Sarawak, for instance) have traditionally kept at least one of the species as backyard pets. Moreover, mouse deer are indigenous to tropical lowland regions and withstand the heat and humidity that are stressful to most conventional livestock species. They probably also are resistant to many diseases of those torrid regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the United States, mouse deer are being raised as laboratory animals for basic research on ungulates. This is because the animals are easier to handle than large deer or goats.2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Mouse deer are graceful, lithe, and look somewhat like large rodents. The Asian species are the shape and size of an agouti (see page 198); the African species is more like the pace (see page 262). All have short legs, a small head, and a pointed snout. Adults weigh from 1 to 5 kg, depending on species. The head and body are only 04-1 m long, and the shoulder height is merely 20-36 cm. Males are generally smaller than females.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In most species the body is a rich brown with white spots and stripes. The belly is usually white. The animals stand on the middle toes, so that the lateral ones do not touch the ground. Neither sex bears antlers. In males the upper canines form long tusks that may extend outside the lips and even to below the line of the jaw.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Twenty-five million years ago, early forms of mouse deer existed throughout Asia, Africa, and Europe. Today's species are restricted to tropical forests and mangrove thickets of Southeast Asia and Central Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Of the three Asian species, the Indian mouse deer occurs in southern India and Sri Lanka; the larger Malayan mouse deer occurs on the mainland of Southeast Asia and the lesser Malayan mouse deer occurs on Java as well. The water chevrotain, a related African animal, is found from eastern Zaire to the Atlantic coast. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p292a.png"></center><br>
+ figure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p293a.png"></center><br>
+ Range of water chevrotain .</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In recent years, human encroachment into the forest has caused the destruction of the mouse deer habitats and has put various mouse deer species under a pressure that is causing their populations to decline.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These animals inhabit equatorial forests and mixed secondary tropical forest. They generally live among undergrowth on the edges of dense lowland rainforests. They especially haunt rivers and swampy bush areas, seeking escape by water when in danger.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Little about these animals is recorded. Essentially vegetarians, they feed chiefly on fruits, supplemented by leaves. They also eat insects (for instance, ants), if available. They do not seem to eat grass.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The premolars of the mouse deer are designed for piercing and chopping food rather than for chewing. As noted, the stomach consists of three functional compartments: the rumen, the reticulum, and the abomasum. (The omasum of ruminants is represented only by a rudimentary area.) The stomach occupies almost the whole of the abdominal cavity, extending from the diaphragm to the pelvic inlet, which provides this small animal with large food-storage capacity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The blood has a very high erythrocyte (red blood corpuscle) count as well as the smallest erythrocyte size of any mammal. The flesh is "white" and the muscles contain little myoglobin.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mature females reproduce almost continuously, and usually regardless of season. In the female larger Malayan mouse deer, mating occurs within 2 days of giving birth. In the African species, many births are synchronized with the rainy seasons, when fruits are plentiful. The gestation period is about 5-6 months, depending on the species. There is only one young per birth. Weaning normally occurs at 2-3 months, but can occur as early as 3 weeks, with sexual maturity achieved at 4-5 months (Asian species) and 10 months (African species). The young stay alone, hidden in vegetation during the first month or two.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Mouse deer are shy, keeping to dense jungle and depending on concealment for protection. Although often present in large numbers, they are seldom seen. Preferring to be near lakes, rivers, or streams, they can nevertheless wander I km or more from water. They feed mostly at dusk or at night, sheltering in undisturbed areas or under shady bushes during the day. They utter weak, bleating sounds, and when frightened, jump a meter or more in the air.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Communication is by scent and calls. The African species possess anal and preputial glands, with which, along with urine and feces, they mark their home ranges. Males of both Asian and African species possess a chin gland to mark either the vegetation or their mates.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mouse deer are among the most excitable, nervous, and jumpy animals. One must tread softly in their presence for fear of causing absolute pandemonium and mishap.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Mouse deer are widely sought by native people for food, and their meat is highly regarded. Dressed carcasses have a high proportion of muscle (84 percent in Asian species), low proportion of bone (15 percent), and an insignificant amount of fat. The ratio of muscle to bone is large - 5.6:1. The mean dressing percentage of 62.1 percent is greater than that reported for cattle, water buffalo, or goat.5</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Adults are wild, generally intractable, and "flighty," but young animals (at least of the Asian species) tame readily and make good pets. Nevertheless, these are delicate creatures and must always be handled gently. Individuals caught in the wild tend to bash against the sides of cages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite an unpromising temperament, Asian mouse deer are regularly bred in zoos, including those in Amsterdam, New York, and Zurich. They also have been reared successfully in small enclosures at several research institutes, such as the I.R.E.T. Institute, Makokou, Gabon; the Institute of Medical Research in Kuala Lumpur, Malaysia; and at Fort Detrick in the United States.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Perhaps the best way to breed this animal is by using the battery system of small units comprising one male and two females per cage. The costs are mostly for obtaining suitable enclosures and for feeding and watering troughs.6 The cages must be covered with mesh because the mouse deer can jump. However, the covering must be sufficiently high to allow the male to stand with its body vertical during copulation.7 They can be fed a variety of foods and grow well on stems of bean plants.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As noted, these are small, seemingly tractable creatures that are at home in the heat, humidity, and diseases of tropical lowlands. They might play a particularly important role as livestock for tropical rainforests; the forests could be left standing while the animal still produces meat. Today, in a widely condemned process, tropical rainforests are being felled in order to raise cattle for meat. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Small size makes mouse deer easy prey for various predators. In the wild, snakes, crocodiles, eagles, and forest cats feed on them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mouse deer are among the most excitable, nervous, and jumpy animals. One must tread softly in their presence for fear of causing absolute pandemonium and mishap.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The different species are solitary, and it is difficult to keep many individuals (especially males) in a restricted space. They must be kept in a quiet enclosure, with cover or good shelters.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The survival of these four "living fossils" depends on conserving their rainforest habitat and restricting hunting, especially night hunting. But studies of their propagation and management are also imperative.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In particular, research is warranted on various aspects of their husbandry, such as enclosure design, space requirements, and health. A special research need is to understand the animal's nutritional requirements and to develop diets for use in captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">27 Muntjac</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g030a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muntjac, or barking deer (Muntiacus species), are among the most widespread but least known of all Asian animals.1 They are almost the size of an average dog and they bark, but they are true deer. These little animals adapt well to captivity and have been introduced to zoos and wildlife collections throughout the world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In recent years one species, the Reeves' muntjac, has become established in England, and a few specimens have settled into semicaptivity - staying behind fences, accepting human presence, and even eating out of people's hands. In Sarawak, villagers have also been known to keep muntjac, feeding them a diet of rice with some leafy matter occasionally added.2 Such experiences show that these small, shy deer can be calm and adaptable. It also shows that they can be raised on practical, artificial diets and that they are not strictly browsers. This creates the possibility (admittedly highly speculative) that they might make future microlivestock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muntjac produce lean, palatable venison and perhaps could be farmed on an organized basis. They are native to severe environments where heat, humidity, and endemic diseases make raising conventional livestock difficult. In future, given research, muntjac might become widespread contributors to Asian economic development. The lessons learned in captive breeding could also be important for conserving endangered muntjac species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One species, the Indian muntjac, has an incredibly low chromosome number (2n=7 in males; 2n=6 in females), which makes them particularly promising candidates for mammalian genetic studies. This species has regularly bred well in both zoos and research institutions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Muntjac are small and slender. Reeves' muntjac, the smallest, has a shoulder height of 45-60 cm. Fully grown, it weighs less than 20 kg; commonly it is merely 10-12 kg. The Java subspecies of the Indian muntjac is the biggest, with a shoulder height of 58 cm and a mature weight of 43 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antlers on the males usually include a main prong as well as a much shorter brow tine. Even the main prong is no larger than a finger, but its pointed tip is hooked and must be treated with caution. There are also two tusklike canine teeth that protrude from the mouth. These have sharp points and a knifelike posterior edge, capable of cutting to the bone a person's finger or another muntjac's rump.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coloration varies from deep brown to yellowish or greyish brown with cream or whitish markings, depending on the species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Muntjac are native to a vast region from eastern China to Nepal, India, Sri Lanka, and Indonesia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Almost a century ago, Indian and Reeves' muntjac were introduced to a deer park in southeast England. Some escaped, and (as noted) the Reeves' muntjac has adapted, spread, and settled down to life in the countryside.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Of the five muntjac species, the Reeves' and the Indian are well known and in no danger. For instance, recent estimates of annual game production have shown that there are about 650,000 Reeves' muntjac in China. The other three are threatened with extinction. Black, Roosevelt's, and Fea's muntjacs are virtually untried in captivity, but the success of raising Reeves' muntjac in English country gardens suggests that perhaps their populations could be saved through captive breeding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In their native habitats, these small deer are usually found in dense vegetation on hilly ranges at elevations up to at least 3,000 m.3 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p301a.png"></center><br>
+ The native ranges of the various muntjacs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Muntjac seem to be primarily browsers. However, in captivity they eat fresh grass, alfalfa hay, and feed pellets. They also readily eat root crops such as potatoes, carrots, and parsnips. They are "concentrate selectors," preferring foods low in fiber and rich in protein and nutrients. Captive specimens reportedly need; a supply of cut browse.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Breeding may occur year-round, but in practice it is synchronized with certain seasons. The first conception can occur as early as 6 months of age. One, occasionally two, young are born after a gestation of about 200 days. They weigh around I kg at birth, and the fawns usually remain hidden until they can move about with the mother. The females mate within a few days of giving birth. Life spans up to 16 years have been recorded.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As noted, the Indian muntjac is a species of great cytogenetic interest. It has the lowest diploid chromosome numbers yet found in a mammal.4 The large, easily distinguishable chromosomes are a great advantage in tissue culture, and many laboratories now have muntjac cell lines. The karyotypes of the different species' chromosomes are very different; the Indian and Reeves' muntjac can hybridize, but the offspring are infertile.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Muntjac are dainty and have a captivating charm. Always on the alert, they are active both day and night. Often they will bark for an hour or more, but typically they bark for only a minute or two. When panicked, captive muntjac may rush into fences or walls. They can easily leap barriers 1.5 m high.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Males are highly territorial and defend their territories vigorously. Adult females also inhabit a specific territory, which they defend against strange individuals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Males mark the ground at intervals by lowering the head and rubbing the frontal glands on the ground and by scraping their hooves against the ground. They mark trees by scraping the bark with the lower incisors and rubbing the base of their antlers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In Asia, muntjac are hunted for meat, skins, and antlers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Muntjac thrive and, at least under ideal conditions, breed freely in captivity. However, they may stop breeding if they are crowded.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In England, zoos and private collections keep as many as six muntjac in an area of 40 x 20 m. Plenty of cover is provided for the animals to hide in. Fences almost 2 m high are used. (Lower fences are reportedly adequate where there is no risk of the deer being panicked by dogs or people.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Like other deer, muntjac produce extremely lean meat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They seem to be healthy animals. In Britain, wild and captive muntjac have few gastrointestinal worms, and ectoparasites such as ticks and lice are not a problem. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MUNTJAC</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In England, far from Asia's forests and mountains, the Reeves' muntjac is the subject of a peculiar chapter in the otherwise unhappy history of introduced species. Charmed by the deer's odd characteristics, the British have welcomed its invasion into gardens around the country. Now, there are tens of thousands of muntjacs on the loose, and some people have even adopted them as pets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although other alien species have wreaked havoc on native plants and animals, muntjacs appear to be a merciful exception. At least over the short term, muntjacs "have proven to be an almost innocuous asset to the countryside. They give pleasure to thousands and pain to few. Eating mostly ivy, grass, leaves, and prickly bushes, they rarely feed in one place long enough to do much damage except to an occasional suburban garden." </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Life for many muntjacs is made soft by homeowners who find the deer's large, dewy eyes and tiny antlers irresistible. The kind-hearted suburbanites put out salt licks, water, and kitchen scraps, and they built snug little shelters against the cold north wind. "All our adult deer will take food from the hand," says Walter Buckingham, who has kept muntjacs for five years in his garden in the county of </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hertfordshire, just north of London.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The adaptable immigrant is colonizing new areas so rapidly, say biologists, that soon there may be more in England than in Asia. "In time," predicts muntjac-researcher Oliver Dansie (pictured opposite), "it may eventually establish itself as our most widely distributed deer species."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In the wild these animals are not gregarious and are generally found alone or in pairs. Because of their strong territorial instincts, large males may not be able to be kept together without fighting. The upper canine teeth can inflict serious wounds. Some females are intolerant of each other as well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muntjac are fragile; they cannot be held by the legs, for example.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some infectious diseases may prove to be of epizootic importance: foot-and-mouth disease, mucosal disease, epizootic hemorrhagic disease, rinderpest, and tuberculosis (all three types). This may be a problem, especially when people are raising the animals by hand.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">To ensure a better understanding of their potential as microlivestock, muntjac deserve research and recognition from animal scientists and conservationists from Nepal to China. The English experience shows how populations of the endangered species might be built up. At present, however, none are receiving any husbandry research; only the two most common species can generally be found in zoos.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These animals deserve investigation into physiology, reproductive requirements, fertility, nutrition (for example, food preferences, feeding strategies, and food utilization), growth, adaptability and environmental tolerance, diseases, management, social structure, and selection for calm temperament. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">28 Musk Deer</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The musk deer (Moschus species)1 is so small that (like other ungulates in this section) it is only as large as an average-size dog. A gland in males produces musk, a thick, oily secretion that is one of the most valuable substances in the animal kingdom. Musk is used in Oriental Medicine as well as in Europeans perfumes, and in recent year it has sometimes sold for as much as three times the price of gold.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Musk is traditionally obtained by killing these deer and removing their glands. The dried glands, called pods, contain a reddish brown musk powder that has been a commodity in international commerce for more than 1,000 years. Despite bans in India (1972) and Nepal (1973), musk continues to be illegally exported, mainly via Hong Kong, for use in Japan and Europe. In Japan, for example, it is an ingredient in more than 200 different medicines.2 In Europe, musk goes into some of the most famous perfumes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The international trade in Himalayan musk, originating from both northern and southern sides of the Himalayan divide, amounts to 200 kg per year, representing an annual slaughter of 20,000-32,000 male deer.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The commercial value of the animal makes it highly attractive for development as a livestock species. The economic force causing its slide toward extinction could be employed to protect and restore both the species and its habitat. Ranching these deer might put musk production on a sustainable footing. It might also encourage habitat protection, because in the harsh climate of the high Himalayas, rearing musk deer could be much more profitable to villagers than raising crops or cattle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Musk deer are already being farmed under primitive conditions in China, where techniques for extracting musk without killing the animal have been developed. In India, small collections of musk deer have been established by the forest departments of Himachal Pradesh and Uttar Pradesh. For several years authorities in Nepal have successfully extracted musk from an adult male at the Kathmandu Zoo' without apparent harm to the animal.3 These experiences suggest that musk might become a farmed product. So far, however, success has been limited. The Chinese animals, for example, have a high mortality rate and the musk is said to be of poor quality. Nonetheless, these examples are valuable pioneering case studies that deserve recognition, support, and further development.4</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">With their long ears, arched back, and bounding gait, these diminutive deer remind one of large hares. The pointed face and large ears make their heads strikingly reminiscent of kangaroos. The coarse hair gives them a stocky appearance. The color varies according to species (and subspecies) from rich reddish brown to dark grey or black. The peculiarly brittle and wavy hair probably has good insulating properties, as it consists of air-filled cells arranged like a honeycomb.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Musk deer have an average mature weight of about 6-11 kg and a body length of 50-90 cm. They stand 50 60 cm high at the shoulder and 5 cm higher at the rump because the hind legs are longer than the forelegs. Some dwarf types are only 40-46 cm high. The tail is short, and in males it is naked, except for a terminal tuft of hair, because they mark their territories by constantly rubbing the caudal gland, which is located near the tail, onto objects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All four toes are flexible, which, compared to the rigid hoof of other ungulates, gives a firmer grip on precipitous slopes. The dew claws are enlarged and, together with the central digits, splay out, to minimize sinking in soft snow.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Neither sex possesses antlers, but males have long upper canine teeth that project well below the lips. The lower front teeth have a spatulate form that probably helps the animals scrape lichens from the surfaces of rocks and trees in winter, when most vegetation is snow covered. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p309a.png"></center><br>
+ The musk deers native range.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The genus is distributed patchily throughout the forested mountainous parts of most of Asia. One population extends from just north of the Arctic Circle southward to the northern edge of Mongolia and Korea. Others occur in China, northern Vietnam, and the Himalayan region including Bhutan, Assam, Tibet, the Indian Himalayas, Nepal, and northern Pakistan.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">During this century, the musk deer has rapidly declined throughout its former regions. In many parts of Afghanistan, Pakistan, India, Nepal, and probably Tibet, it is already regarded as rare, with a distribution that is becoming increasingly localized. Possible exceptions are Bhutan and most of China, where its population is thought to be stable. In southern China, a recent estimate puts the musk deer population at 100,000 head. In western and northwestern China, the population is estimated at 200,000-300,000 head.5</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is the uncontrolled hunt for musk that in most places is driving this animal toward extinction, but its habitat is also being increasingly destroyed by livestock and woodcutters. Part of the loss to hunters is owing to the mindless way in which the animals are caught. Most are snared in traps or nets or killed by poisoned stakes set on trails. This kills all the animals indiscriminately, even females and fawns, which produce no musk. This waste of reproductive animals is extremely destructive to the populations and is senselessly hastening the musk deer's extinction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Musk deer mainly occur in upland woodland and scrub areas. They prefer remote, dense vegetation, especially birch-rhododendron forests in mountainous terrain. They are seldom found in treeless regions or areas thickly populated by people. In the Himalayas, the upper limit coincides approximately with the tree line, which is as high as 4,600 m at the eastern end.6</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Despite its economic importance and wide distribution, little is known of the musk deer's biology. Nonetheless, it is known that musk deer have a gall bladder, a bovid feature that distinguishes it from the true deer.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals are browsers, relying on young leaves, buds, fruits, and flowers. During the winter, as snow deepens, they depend more on lichens growing above the snow on rocks or tree bark, although in shallow snow they scrape for vegetation with their hooves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The male's musk sac is unique among deer. Situated between the umbilicus and penis, it contains the gelatinous, odoriferous oil. The amount varies with the season and the age of the animal, but pods of adult males usually weigh about 30 g; occasionally up to 45 g.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Males also have a caudal gland under the tail, which secretes a viscous yellow substance with a goaty smell. They mark vegetation with this secretion by rubbing their hindquarters against stems and branches.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Males become sexually mature at about 18 months, but females seem capable of reproducing in their first year. The estrous cycle is 18-25 days; the receptive period lasts 36 60 hours. Gestation varies from 178 to 192 days. Each female usually bears one or two fawns, rarely three. The fawn is precocious - able to stand and move within 15 minutes. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Musk deer are shy, furtive animals with keen senses of hearing, smell, and sight. They are normally solitary and are most active at dawn and dusk. Only under cover of darkness do they frequent the more open spaces. Except in the rutting season, more than two animals are seldom seen together; groups usually consist only of a female and her young. The alarm call, a loud hiss, is often accompanied by a highstepping, springy gait.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the wild, musk deer lead "orderly" lives. They use well established trails connecting well-established feeding places, resting places, and "latrines" where they deposit their droppings. Migration is uncommon.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Remarkably sure footed, musk deer climb cliffs and even the trunks of leaning trees. Being small and solitary, they rely on camouflage to avoid predators but flee through established escape routes when disturbed. If cornered, males defend themselves by slashing with their tusks, often inflicting deep cuts and severe injuries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The strong-smelling, reddish-brown musk is obtainable only from this animal.7 It is used as a fixative in expensive perfumes to increase the retention of the fragrance on the skin. In Oriental medicines it is used in stimulants, sedatives, and other products. Some medicinal properties appear to be genuine.8 Recently, highly purified musk has been selling for as much as $27 a gram.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Trade in the Himalayan musk deer or its products is banned by all countries that are parties to the Convention on International Trade in Endangered Species of Wild Fauna and Flora (CITES). However, products from musk deer in the Soviet Union and China can be traded legally under license. It seems likely that if formal, self-sufficient, musk-deer farming projects can be established elsewhere, with safeguards to minimize poaching, a wider trade would be officially sanctioned.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Since at least 1919, Chinese scientists have been experimenting with the extraction of musk without killing the males. When the sexual activity is at its peak, the males are caught and musk removed from the pod with a runcible spoon (curved fork) inserted into the sac's aperture. The procedure takes only minutes. There are records of up to 9 g being recovered at a time.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As noted, China established formal musk deer farms in 1958. They are clustered in the Maerkang, Miyalo, and Manchuan areas of Sichuan Province; the Zhenping county of Shanxi Province; and the Fuziling area of Anhui Province. Despite heavy initial losses of animals, mainly during transportation and acclimatization, the Chinese now breed musk deer in considerable numbers. However, juvenile mortality is still high and longevity relatively short. Zoos in other parts of the world have also had difficulties maintaining the animals.9</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In captivity, musk deer readily accept many foods: lettuce, carrots, potatoes, apples, rolled oats, hay, alfalfa, bananas, some grass, bamboo leaves, and pumpkins, for example.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The musk deer's social system may represent an impediment to its successful reproduction in captivity. It is irascible and scares easily. In close confinement, males fight and may have to be isolated from each other.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is an inherent danger in any captive-breeding scheme in the Himalayas: resumption of legal trade in natural musk could damage the remaining populations by stimulating the market and providing an outlet for illicit musk from poached animals. Some biologists (notably in India) consider that a total ban on the trade in natural musk from all sources is essential.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So far, removing the musk without damaging the animals has not proved commercially successful because of market resistance. Most purchasers require the entire pod in order to be certain that they are receiving the genuine product. Given a regularized farming program, however, it seems likely that mutual trust would circumvent this lack of confidence.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">To protect this species will not be easy. It occurs in vast, remote areas that are difficult to patrol. The local people are poor and traditionally have used it as a source of income and food. The value of musk is so high that smuggling is already well organized and will be difficult to eradicate.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is imperative that the status of existing musk deer populations be established. This is especially important in Nepal. The total population may be not more than 500 in the wild.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">No matter what is achieved in farming, pressure on populations will only be reduced by protecting the wild specimens. Thus, the dietary requirements and behavior of musk deer should also be evaluated with a view to building up the wild populations directly. If the techniques of breeding and handling can be improved, farming the animal may also indirectly help wild populations by reducing the pressure to harvest them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An alternative to captive breeding might be ranching the wild animals. In this process, males would be caught periodically and the musk extracted before releasing them. The organized, sustainable harvesting is particularly attractive if developed at the rural level with revenue going directly to local people; it would provide them incentive to conserve not only "their" musk deer but also its habitat. For this purpose, today's musk deer hunters could be trained to extract musk from live animals, releasing and recapturing them on a controlled basis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another alternative could be controlled culling at a sustainable level, as is now done in the Soviet Union, where about 5 percent of the population is harvested each year. However, elsewhere annual culls at any level would not be feasible for at least 10 years because the populations are now so low. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g031a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">29 South America's Microdeer</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g032a.png"></center><br>
+ Pudu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">South America contains three types of tiny, indigenous deer. None are well known to science, yet they are of microlivestock size, and if given research attention at least two might respond to rearing in captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PUDU</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The pudu (pronounced "poo-doo") is native to temperate forests of the Andean region. It is among the smallest of all true deer, adult males being merely the size of small terriers and the females being smaller still. It is very shy and retiring and is endangered.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All things considered, this animal would appear to be an unlikely candidate for microlivestock. But wherever it is found, the pudu is mercilessly hunted, and captive rearing might be the only way to save its populations from extinction. Indeed, it is already being raised in experimental herds in Chile and Argentina.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pudus (also called the Andean dwarf deer) once ranged widely through the foothills, valleys, and lowlands of the Andes. They prefer the dark, dank underbrush of the cool rainforest, particularly thick bamboo stands. There are two species: Pudu pudu is distributed in parts of southern Bolivia and throughout much of southern Chile nearly to the Straits of Magellan. It is also found on islands off the Chilean coast. Pudu mephistophiles is distributed throughout the highlands of Ecuador, where it occurs only in cool areas at great height.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With their short legs, stocky bodies, and compact heads, pudus do not look much like deer - more like small antelopes with foxlike faces and spiky antlers. Full grown, they are only 40 cm tall and weigh less than 12 kg. They have thick fur ranging from reddish brown to pale gray.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of the pudu's small size, shy and secretive nature, and forbidding habitat, few people have ever even seen one. Nonetheless, these animals tame easily and reportedly were once kept by South American Indians. Several generations were also once bred in a Paris apartment and were treated exactly like domestic dogs, which most people who saw them for the first time thought they were.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In recent years, habitat destruction has greatly reduced the range and numbers of these attractive and fascinating little creatures. The International Union for the Conservation of Nature already lists them as vulnerable to extinction. Pudu studies are highly recommended, and raising pudus promises to be an interesting and valuable activity that may one day lead to one of the most intriguing microlivestock of all.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BROCKET</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Brockets (Mazama spp.) are small deer that occupy the place in South America's environment that duikers occupy in Africa (see page 326). They typically reside in thick brush. They occur widely throughout South America and are found in every country except Chile and Uruguay. They also occur in Central America, the West Indies, and Mexico.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are four species:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">- Red brocket (Mazama americana), the most common and widespread, is found from Mexico to Argentina. It is also the largest species, with a mature weight of about 20 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Gray (brown) brocket (Mazama gouazoubira) is also found throughout Latin America. It is slightly smaller, weighing about 17 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Lesser brocket (Mazama rufina)2 resides in small and scattered locations in Venezuela, Ecuador, Peru, Bolivia, Brazil, Argentina, and Paraguay. It weighs 10-20 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Dwarf brocket (Mazama chunyi) is found only in pockets of forest and brush on certain mountainsides in Venezuela, Colombia, Ecuador, and northern Peru. The smallest brocket, it weighs only 8-12 kg. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Except for their size and color, all brockets look alike. The head,  neck, and tail are short; the ears are wide. The lumbar region is higher  than the shoulders, and this, together with an arched back, gives them a  hunched appearance not unlike a duiker's. The antlers are simple  spikes, never longer than a person's hand.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The different species are similar in behavior, too.3 They generally  wander around singly or in pairs. Although frequenting dense cover  during the day, they emerge at night to feed in open areas. Little is  known of their food preferences. But farmers know only too well how  fond they are of melons, beans, peppers, and corn. Doubtless, wild  forest fruits dominate their native diet.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although extensively hunted, brockets are so adept at dodging into  dense brush that relatively few get caught. However, small size makes  them vulnerable to many other predators: puma, jaguar, ocelot, and  eagles and other large birds of prey. Near villages the domestic dog is  probably their worst enemy. (Infuriated vegetable growers commonly  set their dogs on them.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although at first sight these retiring, nervous, and agile creatures  seem unlikely to be even potential microlivestock, young brockets are  sometimes caught and raised by people. It is not uncommon to find  them as pets on farms and in gardens. They seem to become very  tame and might therefore make useful livestock at some future time.  At least one species, the grey brocket, adjusts particularly well to life in  and around human settlements.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUEMUL</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The third type of South American microdeer, the huemul,4 is a much  less likely candidate. It is very rare, very shy, and has so far shown  little likelihood of settling into captivity. However, huemul conservation  is critical: without urgent attention, the animal will become extinct.  Although totally protected by law, it is declining owing to poaching,  farm dogs, habitat loss and diseases transmitted by cattle and other  livestock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are two species:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- The Chilean huemul (Hippocamelus bisulcus)5 occurs in high altitude forests, thickets, and grasslands in the Andes of southern Chile and Argentina.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- The Peruvian huemul, or taruca (H. antisepsis), occurs in parts of the Andes of southern Peru and Bolivia as well as of northern Chile and Argentina.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Both species live in small herds above the tree line. They are very shy, and even though the Chilean national seal bears the depiction of a huemul, almost no Chilean (or anyone else, for that matter) has ever seen a live one.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At less than 85 cm tall and probably weighing under 15 kg, huemuls are sized to be microlivestock. However, previous attempts at rearing them in Chile have met with little success. Nevertheless, huemuls have been kept in zoos in Germany, and such experiences - together with the increasing knowledge of how to raise red deer and other species - may eventually provide the keys to their continued existence. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g033a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">30 Water Deer</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g034a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Little is known about the water deer' (Hydropotes inermis), but it should be considered along with mouse deer, muntjacs, musk deer, and others as a possible species for microlivestock development. It is comparable in size, and it is unusual among deer for producing large litters: births of triplets or more are common.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As with the other species in this section, this is a highly speculative notion; however, there is some justification for it. The Zoological Society of London has successfully established breeding colonies, and other zoos have also bred the animal in captivity. The water deer has the advantage of rapid growth, early maturity, and high fecundity. Indeed, given protection, its populations have been known to increase rapidly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The animal has a graceful and delicate appearance, its best known characteristic being the male's long tusks. Both sexes are about the same size, standing 45-55 cm at the shoulder and weighing up to 19 kg. Body length is up to about I m, and the tail is so tiny that it is barely noticeable. The round-tipped ears are characteristically held erect above the head.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water deer are somewhat like muntjacs, but they are longer in the leg and lighter in build. Their forelegs are shorter than their hindlegs so that they stand slightly higher at the haunches than at the shoulders. This gives them a hunched appearance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The hair is generally thick and coarse, longest on the flanks and rump. The backs and sides are usually yellowish brown, finely stippled with black. In winter, the coat is thick and variable in color; pale fawn and peppery gray-brown are common shades. In summer, the coat is sleek and reddish. Fawns are white spotted at birth, but this dappling soon fades.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Neither sex has antlers. The upper canine teeth, especially in the males, are enlarged, forming curved tusks 7 cm long. These are much bigger than those in muntjacs and can protrude well below the jawline.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In both sexes there is a small inguinal gland present between the hind legs, the only instance among deer.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In China the water deer has a wide distribution range. It is mainly found in the provinces of Jiangsu, Zhejiang, Anhui, Jiangxi, Hunan, Hubei, and Fujian, the mid and lower Yangtze River Basin, and coastal areas and islands in central and eastern China. It is also found in Guilin, southern Sichuan Province, Guangxi Province, and Guangdong Province in the south.2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Korea, the animal lives along the lower reaches of most rivers, except those in the extreme northeast. Its northern limit of distribution is probably about latitude 43&Yacute;N.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At Woburn Park in England, a few escaped from a herd early this century and have increased and become established in a number of counties, particularly Bedfordshire, Hertfordshire, Cambridgeshire, and Norfolk.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In China, owing to increasing reclamation and cultivation of wetlands, the habitat of the water deer is gradually shrinking. At present the animal is protected by the government, which designates appropriate hunting seasons. It is estimated that about 10,000 are killed each year by hunters. In Korea the water deer is still plentiful. As noted, in England it is maintaining itself and is thriving in some protected parks. It is also reported to be present in France.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In its home range, the water deer is usually found among reeds and rushes in swampy areas. It also frequents the tall grasses and sparse shrubs of mountainsides and cultivated fields. In England it has adapted to a variety of habitats, including woodlands. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p323a.png"></center><br>
+ Native range of the water deer.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The water deer is chiefly a grazer. It feeds mainly on reeds, coarse grasses, and some tree leaves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As previously mentioned, this is the most prolific species of deer. Up to seven fetuses have been observed in a single pregnant female, although the normal litters are two or three. The gestation period is about 176 days. Fawns are born in late spring or early summer, and weigh only about 0.5 kg at birth. Within 4 days the newborns can live almost exclusively on grasses. Usually, however, they are fully weaned after 4 8 weeks, but remain socially attached to the mother. They appear to become independent after about 4 months. Males become sexually mature at about 5-6 months; females at about 7-8 months.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Water deer are generally seen alone. Even where abundant, they seldom congregate in herds. Females are sometimes intolerant of each other, as are adult males or young males. However, in captivity, several females can graze and rest in loose aggregations. The peak period of grazing activity occurs around dusk. Feeding sessions are interspersed with periods of passive cud-chewing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water deer "bark" at intruders. During the rut, males are especially noisy and aggressive, and defend their territories with vigor. Fighting involves striking their tusks into the shoulder or back of their opponents. 3 Information from Lu Houji. These are extremely excitable little animals. When upset, they often "hump" their backs and bound away like rabbits. They are also good swimmers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In China the water deer are hunted for their meat and skins, and newly born fawns are killed to obtain the mother's colostrum for medicinal purposes. In a few localities in England, the species has become a game animal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The water deer is not yet known on "farms." However, it seems to be easily kept, has bred well in zoos, and has thrived in many British wildlife parks. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The assets of early maturity and high fecundity mean that the potential exists for rapid population expansion. Such an event occurred at Britain's Whipsnade Zoo. In 1929 and 1930, 32 deer were released into undeveloped pasture; by 1937, 120 fawns had been raised.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because they are relatively small, and because in the wild state they aggregate only under exceptional conditions, water deer are unlikely to have any appreciable impact on vegetation in forests, farms, or gardens. Nonetheless, they can damage crops, and Chinese farmers, who consider them pests, often illegally kill them out of season.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These animals are swift and adept at escaping captivity. It is possible that because of territoriality only a single pair will live in a given area. Moreover, males are aggressive and must be kept apart.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They seem able to withstand chilly weather well, but a combination of wet and cold is harmful. Their heavy winter coat, essential to survival in the Far East, renders the animal susceptible to dehydration and heat exhaustion in comparatively mild climates, such as England's.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At birth, the tiny fawns are extremely vulnerable to a variety of predators, both birds and mammals. The species may need areas of dense cover or some shelter from wind.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The water deer has been successfully kept in semicaptivity for many years; however, for it to reach a level of domestication suitable for use as microlivestock, research is needed in the following areas:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Reproduction;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Performance under a range of environments;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Grazing efficiency;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Basic physiology;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Captive breeding and domestication - measurements of growth rates, space requirements, and feed needs; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Modifying behavior to overcome territoriality - for instance, imprinting on humans, selection of docile specimens, hand rearing, and castration.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The water deer is not an endangered species; however, efforts should be made to preserve the populations in their native ranges and habitats. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">31 Duikers</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g035a.png"></center><br>
+ Red Duiker</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Duikers (Cephalophus and Sylvicapra species) are small African antelopes. Although they are ruminants like cattle, sheep, and goats, some are hardly bigger than hares or rabbits. One, the blue duiker, is less than 40 cm high and usually weighs a mere 4-6 kg. It and some of the slightly larger duikers might be suitable for household husbandry because their meat is an extremely popular food throughout much of Africa. In West Africa, for example, it is one of the most common meats sold in both rural and urban markets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This idea, however, is highly speculative because, despite their popularity, little is known about these tiny animals. Their husbandry has been attempted only a few times, but the results were encouraging, and rearing duikers deserves further investigation. They are already being raised in captivity in the United States,' Zimbabwe,2 Togo,3 and Gabon. Researchers in Nigeria have bred blue duikers to the fourth generation and found that, if the animals were first handled by people while young, they remained docile.4 Even blue duikers caught in the wild tame quickly if they are very young, but by the time they reach 3.5 months, they become barely tolerant of man's presence.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If duiker husbandry can be developed, it might provide not only a more regular source of meat, but also a lessening of the hunting pressures, thereby giving the wild populations a better chance of survival.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These antelopes are suitable for testing as microlivestock only in their native region, sub-Saharan Africa. Eventually, they might prove to have wider applicability. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Duiker species vary from about the size of a small dog to that of a small donkey. Most are similar in shape and are characterized by short front legs, arched back, and pointed hoofs. The tail is stubby, often with a terminal tuft. The coat varies from reddish brown to nearly black, although a few species are blue-grey and one is zebra striped.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Females are slightly larger than males, but the sexes look alike. In most species, both sexes bear small straight horns that project backward from the skull, frequently hidden in a long tuft of hair.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Duikers inhabit virtually all regions of Africa below the Sahara from Gambia in the west to Ethiopia in the east, and all countries as far south as South Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Duikers are so shy that they are rarely encountered by people. But almost anywhere in Africa (other than North Africa), the observant traveler may glimpse them ducking into forests or thickets. Although there are still countless numbers, people are eating so many that in some localized areas the populations are fast heading toward extinction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">All but one species are found in rainforests or dense woodlands. The grey duiker, however, is found in savannas. If the vegetation is juicy, only a few of the species need a separate water source, so they can thrive in very dry sites.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The main foods are fruits and seeds supplemented by leaves and shoots. Fruits, which they eat to a much greater degree than other antelopes, are an important part of their diet. Some rare species (for example, the red-flanked duiker, C. rufilatus) can graze. Occasionally (especially in captivity), duikers are also omnivorous, eating fish, crabs, insects, snails, frogs, small animals, or carrion; they also readily accept chopped meat. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Duikers reach sexual maturity at 9-15 months; gestation lasts about 7-8 months. In some species, females conceive a few days after calving on a 3- to 5-day postpartum estrus. Apparently one calf per birth is normal. A newborn blue duiker weighs between 0.4 and 0.7 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Before one year of age, young duikers leave their parents to find their own mates and territories. Life expectancy is more than 10 years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In spite of habitat differences, most duikers behave alike. In the wild they are nervous, shy, and retiring. When alarmed, they plunge into the protection of dense vegetation - hence the origin of the name duiker, which means "diver." Nonetheless, their behavior allows them to be easily netted. An experienced hunter can imitate duiker sounds and call the male out of the bush. Also, a startled animal freezes, thereby facilitating its capture.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moving easily through dense vegetation, the head carried low, these tiny animals use regular runs. Forest duiker species are largely diurnal, although a few, such as the bay duiker, are nocturnal. Bush duikers are mainly nocturnal, feeding from early evening until morning. Such nocturnal species shelter during the day in holes (presumably dug by other animals) or inside fallen trees; the diurnal ones lie directly on the ground.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Blue duikers are the best-known species and are probably the most likely candidates for microlivestock (see page 332). They seem to be monogamous and apparently mate for life. Unlike most antelopes, their population densities can be high. The pairs reside in territories of 2-4 hectares, which both male and female stoutly defend against rivals. Other species appear to be polygamous and live in large territories (up to 80 hectares).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In captivity, the animals are generally calm. However, both males and females can be aggressive toward unfamiliar individuals of their own species. In an enclosure, one male can serve several females.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Large glands, located beneath each eye, exude a scent that is rubbed onto fences, trees, and other objects as territorial marking. In another form of marking the horns are rubbed against tree trunks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As noted, duiker meat is much sought in many African countries, and the animals are regularly hunted. The meat is lean with little or no intramuscular fat (marbling). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Duikers also have promise as experimental animals. They are true ruminants, with four-part stomachs, and they produce cud. Some are only rabbit size, they need far less room or feed than sheep, and thus are potentially an efficient test animal for determining the nutritional value of forages. Blue duikers, for instance, have a digestion efficiency comparable to that of sheep, but, because of their small size, a test needs only four rabbit cages and 5-10 kg of feed. Sheep, by comparison, require much more spacious facilities and 150 kg of feed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Nigeria, blue duiker pelts are used in making karosses, a traditional dress. A single garment may contain up to 60 pelts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Almost nothing is known about rearing duikers, but they seem to tame easily and perhaps may be kept in backyards like goats. Indeed, they reportedly make good house pets when hand raised. They are attractive, and from the day of capture young ones can be handled and petted.5</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Nigerian researchers who bred blue duikers to the fourth generation bottle-fed young specimens five times a day. Older animals were given feeds that included banana, plantain, and papaya; leaves of hibiscus, cassava, and banana; and dried corn. Variety seemed to be important, and the researchers could not predict the quantity of particular foods the animals would choose on any given day. In addition to varied vegetables, a small dish of salt or a salt lick was sometimes required.6</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Duikers are unlikely to run away, except when startled. However, providing an enclosure is worthwhile. It enables them to establish a territory by marking poles, bushes, and fences. Although needing space in which to run, as little as 10 m&Yacute; is reportedly sufficient for 24 animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Satisfactory shelters include an open-ended oil drum laid on its side, a lean-to made of palm frond, or a small hut made of local matting. Apart from providing shade and protection, shelters should be built so that excited animals can run through them. When cornered, duikers tend to either flee for shelter or jump upwards; a run-through shelter can prevent a frightened one from accidentally leaping over the fence.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Based on their own experiences, researchers at Pennsylvania State University in the United States report that blue duikers raised in captivity are easy to maintain, reproduce well, and are not fussy about environmental conditions. In fact, they say, blue duikers seem to enjoy living in cages.7</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In order to raise duikers successfully, post-pubertal males must be separated. A female should be bred with the same male throughout her productive life span.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE BLUE DUIKER</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In one sense, the blue duiker is the most important animal in Africa. It is the only one found throughout the continent south of the Sahara. It occurs at a greater range of altitudes than most - as low as sea level in many places to almost 5,000 m elevation in Kenya. It occurs in habitats from dense rainforests to dryland savannas. And, in sub-Saharan Africa as a whole, the blue duiker is eaten more than any other animal (although in West Africa it is generally called Maxwell's duiker).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This very small antelope, caught by snare or net, can be found in the meat markets of villages, towns, and cities in all countries from Senegal to Madagascar. It is a source of food for tens of millions. Bushmen, Pygmies, Dinkas, and Mandingos, thousands of miles apart; all share the same fondness for duiker meat and for duiker-skin clothes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nevertheless, scientifically speaking, this is one of the world's least-known animals. And its numbers are diminishing rapidly. Areas that used to have plenty now have few or none. Overhunting and destruction of the rainforests are jointly contributing to their decline.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite the losses, people are snaring as many as they can, and there is no sense of concern - not even among most conservationists. However, in many locations there is already evidence that the animals won't be around much longer. Unless something is done - and soon - people will lose their major source of animal protein. If that happens, it is likely that they will move on to larger animals, such as gorillas, which would be an even worse disaster.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The best long-term solution is to organize duiker husbandry. Learning to rear duikers would benefit people throughout Africa. The blue duiker is the most suitable species; it is the most common and the most important. Also, it inhabits the edges of the forest and could therefore become a suitable species for ranching without denuding the forest.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Blue duikers are easy to maintain in captivity. They tame readily and like to shelter and sleep In boxes or cages. They are good converters of vegetation and produce top-quality lean meat. In addition, they are neither affected by tsetse flies nor are very susceptible to diseases.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The key now is to learn how to keep these very timid creatures under different conditions. We need to know their foods (especially foods that might be harvested from forests) and reproductive biology. We need to know the right numbers to house together. Most of all, we need projects aimed at rearing and breeding them in captivity under village conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vivian J. Wilson</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Many African countries already have a ready market for duiker meat. It is somewhat similar to goat meat, but most people agree that it is superior.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animal can live on fibrous vegetation. Unlike conventional ruminant livestock, it is suitable for feeding an average family at one meal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The ability to forage in undergrowth where other domestic livestock do not thrive makes duikers potential livestock for tropical forest and bushland regions. They can be raised for meat without cutting the trees or bushes to create pastures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Duikers are easy prey for predators: eagles, pythons, wildcats, and people, among others. Thus, they probably require more sophisticated management than common livestock such as goats. However, the quality of their meat could more than compensate for the extra effort.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some species are territorial, which means that they may do poorly in captivity, unless their social organization can be altered.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under good conditions, the ideal slaughtering age reportedly occurs at 8-10 months, when the blue duiker can weigh 4 kg. Compared to rabbits and guinea pigs, production is relatively slow because of long gestation and lack of multiple births.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Duikers are resistant to trypanosomiasis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One general problem is that duikers have short, sharp horns designed specifically for jabbing. This could be a potential danger, especially since the males of some species become aggressive when their females are receptive. However, the horns can easily be clipped and taped to limit the danger. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Because of the duikers' secluded lifestyle, much has still to be learned about their habits. Specific information on behavior and breeding is needed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Animal scientists in Africa should gather small herds for comparative studies. This will provide insights into whether duiker temperaments facilitate or hinder their utilization. In addition, assessments of diet, growth rates, behavior in captivity, reproductive rate, adaptability, and future potential can be made. Management considerations include clipping horns, trimming hooves, and controlling lice and fleas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research of particular value would be chemical analysis of duiker milk and of other characteristic glandular secretions. The latter lend themselves especially to a study of animal communication.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Parming duikers might help rescue the wild populations by relieving hunting pressures. Programs in this area are recommended for locations where overhunting is occurring. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g036a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">32 Other Small Antelope</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g037a.png"></center><br>
+ Klipspringer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The least known and most obscure of all antelope are the delicate African creatures called dikdik, suni, royal antelope, pygmy antelope, and klipspringer. The smallest is a West African form of the royal antelope that stands a mere 25 cm high and weighs less than 2 kg. The four-horned antelope of South Asia is a similarly tough, tractable animal that is also the size of a small dog.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">None of these has previously been seriously considered for use as livestock, but they are possibly amenable to rearing in captivity and they provide some of the finest game meat in the world. Given New Zealand's experience with various deer species (see page 288) and Africa's experience with large antelopes, basic research to test out the possibility of organized dwarf-antelope production could prove to be rewarding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AREA OF POTENTIAL USE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The areas where these antelopes might be used are sub-Saharan Africa for the African species and South Asia for the four-horned antelope.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Of these animals, some, such as the pygmy antelopes, have a crouched appearance with an arched back and short neck; others have a more upright posture with a long neck and a raised head. In all species, the males are smaller than the females and bear tiny spikelike horns. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Collectively, these antelopes have native ranges covering huge areas of Africa and part of Asia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dikdik: Six species occur in two discontinuous distributions - one from Somalia and Ethiopia southward through Kenya and Tanzania, the other in Namibia and Angola. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sunis: Eastern Africa, from Kenya to South Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Royal antelope: West African forests. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pygmy antelope: Central Africa from southeastern Nigeria to Zaire. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Klipspringer: Ethiopia to the Cape of Good Hope. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Four-horned antelope: India. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Many forms are protected by local laws, but none of the species is on the international endangered-species list.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The animals occupy habitats from dense, moist forests to dry, rocky outcrops and even to deserts. Their ranges have almost certainly been affected by humans - sometimes for the better, since many prefer the secondary growth that invades disturbed areas, notably after overgrazing or slash-and-burn agriculture.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although dikdik and klipspringer usually frequent dry areas with scattered brush, the other dwarf antelopes normally stay in dense vegetation. All seem to live in definite areas and do not migrate. For instance:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Dikdik live near streambanks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Sunis inhabit dry country with thick bush, but they can also be found in reed scrub along rivers and in forests up to 3,000 m elevation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Klipspringers live on stony mountain slopes, rocky outcrops' or the sides of steep gorges at altitudes from sea level to 4,000 m.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Four-horned antelopes live in undulating or hill country and shelter in tall grass and open jungle, a terrain more common to deer than to antelope. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Most of these antelope browse on shrubs. They are "concentrate selectors," taking easily digested vegetation such as buds, fruit, and succulent young leaves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Also, most obtain much of their water requirement from dew and the vegetation they consume. Klipspringers, for example, are able to live for months without drinking. Sunis and four-horned antelope, on the other hand, drink regularly and seldom live far from water sources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Little is known of the reproduction and general performance of these animals. Females become sexually mature at about 6 months in the smaller species and 10 months in the larger. Males become sexually mature at about 14 months. The young are born throughout the year, but births peak with the vegetation flush following the first rains. Where there are two rainy seasons a year, two birth peaks occur. Usually a single calf is born. Dikdik is the only one whose reproduction has been studied in detail. Its pregnancy lasts 172 days, one young is born at a time, and the birth weight is 600-800 g.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Their longevity is unknown but is probably in the range of 10-12 years.l</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These tiny creatures have some of the habits of deer. They are shy and elusive and generally rely on concealment to escape detection. Their first response to a predator is to freeze, and then to flee like hares - dashing off in a series of erratic, zigzag leaps.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They live alone, in pairs, or in small family groups, but sometimes congregate in larger groups in thorn thickets. The species that have been studied most (dikdik and klipspringer) are strongly pair bonded. (A male, a female, and one or two young is typical, and a klipspringer rarely moves more than 5 m from its mate.) However, the royal and pygmy antelopes and the suni are more solitary in their behavior. Four-horned antelope are usually seen alone or in pairs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These animals feed mostly in the early morning and late afternoon Some species deposit dung and urine on particular sites. And they repeatedly daub secretions from glands in front of the eyes onto plant stems, where a sticky mass accumulates. Glands near the hooves mark the ground along frequently traveled pathways. Males also mark females with the scent, thus reinforcing the bond. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The four-horned antelope has a whistling call, which helps keep the family group together. Males repeat it frequently in hot weather. Gestation is 8-8.5 months. If taken young, they reportedly tame easily.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Much more research needs to be done before attempts are made to convince anyone to domesticate these antelope. There are likely to be considerable difficulties. Guinea pigs, rabbits, and giant rats can successfully be kept in cages or small enclosures, but most antelope probably cannot. Larger enclosures will be needed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The food habits and general behavior of these small animals must be studied closely. They are strictly monogamous, and it may be necessary to keep them in pairs. Reproduction, growth, and general performance must become understood under different environmental and nutritional conditions. Mixing species is another aspect to be examined - whether these antelope can be kept with other species in the same enclosure (typical of livestock farming in most poor nations) is not known.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To settle such questions, representative species of microantelope should be gathered for comparative assessment. Researchers should focus on the animals' social structure, on husbandry methods for maintaining them over generations, and on how best to breed them. If the findings are promising, then a campaign to domesticate these antelope could be mounted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Throughout most of their ranges these animals are highly sought "bushmeats." The meat is lean and of extremely high quality. In Zaire's Ituri Forest, for example, pygmies net and kill large numbers of pygmy antelope, hanging the carcasses on sticks by the roadside for sale.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of their small size, these species might make good laboratory animals for ruminant studies. The dikdik, for instance, becomes a fully functioning ruminant at a body weight of about only 1.5 kg.2 However, their digestive physiology is quite different from that of cattle, sheep, and goats, which makes them atypical ruminants.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Given organized production, it is likely that dwarf-antelope pelts could become commercially important. North Africa exports the hides of medium-size antelopes to Europe for use in fine sueded leathers. Hides of the small species would almost certainly be in demand as well if a steady supply could be obtained as a by-product of meat production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Microantelope provide some of the finest game meat. They are small and perhaps tractable. Most are already widely eaten and are being eliminated over broad areas of their range. Turning them into a sustainable, economic food source could provide motivation for their conservation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These antelope can digest, and are adapted to, the indigenous forage over vast areas of Africa and South Asia. They are native to tropical habitats, where cattle and other livestock often grow poorly. They also appear to be resistant to trypanosomiasis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Some African peoples (for example, the Kalahari Bushmen) have superstitions or social injunctions that prohibit the eating of some of these species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Small antelope are probably not as efficient as larger ruminants in digesting fiber: the retention time in the rumen may be too short. On the other hand, quickly digestible cell walls of lush green plants can be used efficiently.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The territorial behavior of most of these species may limit their rearing in large numbers under captive conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As noted, preliminary research on dwarf antelope husbandry is required. Specifically, studies should be conducted to assess:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Growth rates, feed efficiency, and reproductive rate;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Carcass quality;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Economics and the likely cost of production per animal unit; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Studies of digestion.4 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The few statistics available today on the use of wildlife as food are probably much below actual consumption. Most food consumption surveys record food obtained by hunting or trapping under the indiscriminate heading of "Bushmeat" and neglect to include the many small animals that are normally collected by children. In Africa, an amazing variety of wildlife is eaten, including all wild ungulates, primates, all cats, and many species of birds and reptiles.</P>
+<P ALIGN="JUSTIFY">Food and Agriculture Organization Ceres magazine</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All the world's people must begin to overcome in themselves - and even more so in their children - senseless taboos about what is edible and what is not. Only then can we stop today's universal animal-protein wastage. How ironic it would be, in this scientific age, for mankind to starve largely because of a bunch of old wives' tales, irational beliefs, silly associations, and the lack of a sufficient spirit of culinary and gustatory adventure.</P>
+<P ALIGN="JUSTIFY">Calvin W. Schwabe Unmentionable Cuisine </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Iguana is really good, a thousand times better than chicken.</P>
+<P ALIGN="JUSTIFY">Omero Asinto, waiter Pochote Bar and Restaurant</P>
+<P ALIGN="JUSTIFY">Barranca, Costa Rica</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Part VI : Lizards</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Large lizards have been important foods since prehistoric times and are still commonly hunted in parts of Asia, Africa, and Latin America.1 Some (such as the monitor lizards seen in markets in Indochina) are carnivorous species that may be difficult to feed and raise economically. However, the iguanas of the Americas offer promise as microlivestock. They are herbivorous and feed primarily on leaves, flowers, and fruits, including many that are too high in the trees to be gathered by man or by other livestock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Iguana meat is popular throughout much of Latin America, where consumers willingly pay more for it than for fish, poultry, pork, or beef. To fill the demand, several iguana species are hunted by rifle, slingshot, trap, and noose; they are even run down by trained dogs. Villagers (often small children) catch them for food for the family; professional hunters snare and sell them to vendors. Iguanas are hauled around in gunny sacks and wicker baskets by car, boat, horseback, and people on foot. In parts of El Salvador they have been known to arrive at the market by the truckload.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As a result of this indiscriminate hunting, iguanas are now steadily becoming more scarce, and the destruction of their habitat makes the situation even worse. At present, many parts of Latin America's tropical forests are being cleared. The green iguana in particular depends on trees, and as forests disappear its populations are destroyed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, iguanas are forest-edge species: they will grow well on ranches and farms as long as patches of trees are left standing. This offers the hope that they can be raised as microlivestock. They reproduce so prolifically that, in principle, populations can build up exponentially. Mature females, for example, may produce 30 or more eggs a year for up to 10 years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the past few years, a notable research program in Panama and Costa Rica (see page 351) has laid the practical foundation for iguana farming. It has artificially incubated and raised thousands of green iguana hatchlings. With less than half a square meter of living space per animal, the hatchlings have grown as fast or faster than their wild counterparts. Unlike their kin in the wild - which in their first year of life suffer 95 percent mortality from birds, snakes, and other predators the captive-raised iguanas show almost 100 percent survival. This research project demonstrates that ranching iguanas both for food or for repopulating depleted habitats is feasible. In addition, experimental projects for farming green iguanas have begun in Curacao and El Salvador.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As livestock, lizards have advantages. Being cold-blooded they do not carry human diseases (except for those such as salmonella that result from gross mismanagement). They can be kept in captivity in fairly high densities without diseases breaking out. Although often aggressive in the wild, they coexist in dense populations with few problems as long as they are well fed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is an important conservation component as well. Farming these lizards may help check and may even reverse the downward trends of their populations by allowing large numbers to be released back to the wild at a size that inhibits predators.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are three alternatives for utilizing iguanas:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- To manage wild stocks as game animals;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- To raise iguanas on farms, like chickens and pigs; or</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- To raise young iguanas in captivity and then release them into the wild where they can grow to full size and later be harvested on a sustainable basis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although the green iguana has so far received the most attention, two other Latin American species are in farming trials. Black iguanas (garrobos) are being raised experimentally in El Salvador and Costa Rica. And the omnivorous tegu lizard, which produces a valuable leather, is beginning to be farmed in Argentina and is briefly described opposite. Both iguana species are described in the following chapters. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">TEGU</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The tegus (Tupinambis rufescens and T. teguixin) are large lizards of South America. They are highly prized for their skins, which are made into leather for handbags and similar items. Tegus are heavily exploited; on average, Argentina exports over one million skins a year - about $15 million worth. The 50-year-old tegu industry is estimated to support as many as 30,000 people, including tannery employees and people in rural areas who hunt the lizards full- or part-time. Poor agricultural conditions make farming difficult in the Chaco, and sale of a single tegu skin is worth more than a day's wages for a farmband. Some families also eat the tegu meat and use the fat for medicinal purposes. In many areas, the populations have already been driven to the verge of extinction. Husbandry, therefore, could be beneficial. Traders are hoping that captive operations run by families can eventually replace hunting.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although usually associated with the arid regions of northern Argentina and Paraguay, the tegu's range actually covers much of South America - as far north as Colombia, including Trinidad and the Amazon basin. One species (T. rufescens) normally occurs in a dryland habitat, such as Argentina's Chaco region. It can occur in great numbers in pastures, probably because of the insects associated with cattle. But it also occurs in areas that are unsuitable for cattle. Some places where tegus are common are so dry that they can carry only a single cow in 10 hectares. There, farmers might find it profitable to raise tegus. This would maintain the native biological diversity while perhaps reducing the soil degradation that cattle cause.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The other species (T. tegubixin) occurs in wet forests, such as those found in Argentina's Formosa Province.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tegus are scientifically interesting. Little is known about their biology, and basic studies are needed. They are not much eaten, but in some areas the tail is considered a delicacy. Indeed, deteriorating economic conditions are already making them more important as a food resource. Convincing campesinos that they can increase their cash income and their meat production by rationally exploiting these large lizards should not be difficult.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sustainable exploitation could also benefit tegu conservation. Large populations still exist in some areas in Argentina and Paraguay, but, overall, the species are declining. A welldesigned management project could ensure the maintenance and reestablishment of large populations where numbers have drastically decreased. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">33 Green Iguana</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g038a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As noted, the green iguana (Iguana iguana) is consumed throughout Central America. It is already subject to heavy commercialization and its populations are plummeting. This is not likely to change: as human population increases, so does demand for iguana meat and eggs as well as for live iguanas, thousands of which are kept as house pets. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of its herbivorous diet, inoffensive nature, and high reproductive potential, this reptile is a prime species for intensive management. Alert, curious, and social, it is easily tamed from birth. Given minimal protection during the reproductive season, large populations can build up, and animals can be maintained in simple facilities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, although iguanas can be maintained as microlivestock, they may require three years to reach market size. Raising them to maturity entirely under captive conditions is thus probably uneconomic at present, when specimens can still be inexpensively (albeit often illegally) harvested from the wild. However, it has been found that if released into the wild, most will remain in nearby trees, especially if people erect simple feeding stations and keep them stocked with table scraps or weedy vegetation. This makes for very low-cost production during the years of waiting.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Given such findings, iguana farming has a promising future. With research, growth rates can undoubtedly be increased and maintenance costs reduced. Also, iguanas are becoming more valuable each year. Even now, farming them could be economic in some areas where wild iguanas are scarce, especially if the young are released into forested sites when they have grown to a size where mortality is low.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although green iguanas will happily graze pastures, they need trees. Iguana farming, therefore, provides a way to keep tropical forests standing while still providing people with meat and income. By growing lizards, farmers don't have to fell the forests to create space for growing food crops or cattle. Iguana farming thus gives an economic incentive to preserve the beleaguered tracts of remaining trees. It may even render reforestation economically attractive. And it may promote the use of shelterbelts and contour strips of trees in cattle-ranching areas. Today's researchers estimate that 200-300 kg of meat can be produced per year per hectare from iguanas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The green iguana can grow to more than 2 m long, but more than half of that length is in its whiplike tail. Adults of breeding size generally weigh 2-4 kg. The scaly skin is green, yellowish, or golden brown with dark markings; color is a function of age and reproductive stage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">This large lizard is indigenous to a vast region stretching from Mexico to northern Brazil and Peru, including a number of Caribbean islands. In Mexico, it occurs in tropical forests along both coasts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Green iguanas were formerly abundant throughout Central America, but no longer. In the mangrove forests along Mexico's Pacific coast, for instance, only 5 percent of the former population remains. In Guatemala's Pacific lowlands, mere remnants are left. In El Salvador's jungles, the animals have declined to 1 percent of their former density. And in both Panama and Costa Rica, the species is now officially classified as endangered.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The green iguana usually lives near water in tropical lowland forests. It thrives only as long as some trees remain. The forests may be either humid or seasonally dry. The animal normally inhabits the treetops, feeding on tender shoots and fruits in the canopy; few other herbivores can convert such forest foliage into food for humans.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Like cattle and other herbivorous mammals, iguanas have a specialized digestive system with an enlarged fermentation chamber in which bacteria break down plant cells. Vegetation is converted into meat about as effectively as in cattle, but not as quickly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">After reaching sexual maturity, at 2 or 3 years of age, females lay one clutch of 10 85 eggs each year. (For most specimens the average is probably about 35.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p349a.png"></center><br>
+ Native habitat of the green iguana</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The animals are generally slow moving and lethargic when cold, but during the heat of the day they become extremely alert and can run, swim, and climb with speed and agility.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They have a complex social structure and a defined annual reproductive cycle. Hatchlings adapt easily to captivity both when artificially incubated and when captured in the wild. However, captured adults, used to living free, are hard to keep in small enclosures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Green iguanas are used mainly for food. The meat tastes somewhat like chicken and in Latin America is typically cooked in a spicy stew. The eggs are also consumed. Small and leathery shelled, they are considered special delicacies and are said to cure various ailments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is a sizable demand for live iguanas in the international pet trade.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Exploitation has been mainly for the flesh; the skins are wasted in most cases. However, given organized production, green iguana skin could perhaps become a farm by-product. It sells in the international reptile-leather market under the trade name "chameleon lizard." The hide is typically up to 20 cm wide. Thin and relatively fragile, it is glued to a fabric or cowhide backing to prevent it from tearing. The prime uses are for ladies' accessories, belts, wallets, and shoes. It is inappropriate for uses that involve flexure because the scales overlap and repeated flexing causes them to separate. The skin then becomes rough to the touch and loses its glossy finish.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">IGUANA MAMA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The program that now offers hope for raising green iguanas as microlivestock is the brainchild of zoologist Dagmar Werner. She began in 1983 by collecting 700 iguana eggs and then learning what to do with them "on the job."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Through a combination of luck and intuition, coupled with determination, she discovered appropriate conditions for incubating the eggs on the first try - no less surprising because her incubators (dirt-filled wooden boxes warmed with light bulbs) were in an apartment in a high-rise building in Panama City. Nonetheless, most of the eggs hatched and the several hundred squirming young lizards were quickly trucked to a forest park near the Panama Canal. Here, for five years, assisted by a steady stream of enthusiastic Panamanian biology students, Wemer experimented with cages, feeds, facilities, breeding genetic selection, and the myriad aspects of management.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These dedicated researchers eventually devised what might be considered a production line, and they hatched and raised tens of thousands of green iguanas, reduced the animals' infant mortality rate, and created the basic underpinnings for economic production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1988, administration for the project was shifted to neighboring Costa Rica, where Werner established another research farm as well as a fund-raising foundation. From there, she hopes to catalyze all Central America to take up iguana production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Her immediate goal is, paradoxically, to preserve the lizards by putting an iguana in every pot. That will help reduce the indiscriminate hunting that is taking these animals toward extinction in the wild.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Her system is based on setting up feeding stations in the woods and releasing iguanas at seven months, an age at which they are virtually immune to predators. Iguanas need trees, and her ultimate goal is to help save the vanishing rainforests. With profitable iguana farming, she hopes to persuade farmers to save the trees as homes for iguanas, rather than clearing them for crops and cattle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">"Iguana management and an international marketing system will protect, rather than exterminate, the iguana," Werner says. "I don't think iguana farming will stop deforestation. But I do think it will contribute a great deal." </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The iguana farming project in Panama and Costa Rica (see sidebar) provides a model for what might be done elsewhere. In its first five years of operation, the project raised more than 10,000 green iguanas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To create the farms, enclosures are constructed with sheet-metal wails sunk 30 cm in the ground.' Inside, the animals sleep in shelters made of bamboo and vegetation. Each shelter has an adjustable entrance slit through which young lizards can slither, but predators, which usually are larger, cannot. Most are set on stilts and food is served in the shade underneath. With this system, from 20 to 60 young iguanas are kept in an area of 10 m&Yacute; (0.5-0.17 m&Yacute; of land area per individual). In another "high-intensity" design, 30 hatchlings are kept in cages I m&Yacute; in size (only 0.05 m&Yacute; per individual).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The iguana farms also include an artificial nest consisting of a "tunnel" leading to a sand-filled egg-laying chamber. (Both tunnel and chamber are made of concrete blocks or other predator-safe material.) Female iguanas (at least in captivity) prefer this to digging their own tunnels, and it is an important advance in iguana breeding because it produces a hatching success of close to 100 percent. Recent versions require no human intervention: the eggs incubate and hatch by themselves and the hatchlings climb out of the nest through a hollow bamboo "pipe" and fall into plastic bags, which can be easily emptied twice a day.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The iguanas are fed mixtures of broken rice meal, meat meal, bone meal, fish meal, papayas, bananas, mangos, avocados, and a variety of leaves and flowers. Each day they receive fresh-cut leaves from plants such as beans, mustard, or hibiscus. Hatchlings are raised to an age of 6-10 months, when they are big enough to be released into forests, farmland with scattered trees, or into village backyards with almost no vulnerability to predators.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">With each female producing an average of 35 eggs annually, these animals have inherently high reproductive potential. And if the young are protected from predators during their first few months, populations can build up rapidly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Iguanas adapt well to second-growth forest and to backyard conditions and can feed on the leaves of fruit trees or timber trees while the farmer can harvest the fruits or wood. Unless grossly overstocked, they are unlikely to affect the productivity of the trees.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These lizards may take three years to reach marketable size,2 and the cost of raising them to usable size entirely in captivity is currently greater than their market value as food. Less-expensive methods of raising the animals must be found if large-scale commercial iguana farming is to become economically feasible. The main problem is the high cost of the enclosures, not the cost of food. The food costs no more than that for raising a chicken to marketable size, but iguanas do not grow as fast as chickens. For smallholders the only cost of raising them is labor, and that is often unimportant. Free-ranging herbivorous lizards can damage home gardens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">For conservation purposes, the main need is to educate people throughout Latin America to the iguana's plight. For example, in Central America people catch pregnant females and cut out the eggs for food. (There is a widespread misconception that the females survive this brutality.) This is devastating to the iguana populations, yet by installing artificial nests, farmers could let the females live and still harvest the eggs. Moreover, people could eat half the eggs and incubate the other half to repopulate the trees around their farms.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is also important to develop an understanding of iguana reproduction in the wild. At present, the longevity, growth rate, and age of sexual maturity are not well known. Such information would provide baseline data for creating conservation measures to reverse the depletion of this natural resource.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Further husbandry research is needed. Costs must be reduced. The effectiveness of artificial nests must be tested in village practice. Survival rates of captive-raised young after release must be studied. And harvesting and recruitment schemes should be developed to secure optimum exploitation of the repopulated forests. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">34 Black Iguana</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g039a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The work on green iguana husbandry may apply also to the black iguanas' (Ctenosaura similis, C. acanthura, C. hemilopha, and C. pectinata). These are similar lizards that live in dry habitats throughout Central America </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Exploitation of wild black iguanas for food began in ancient times and has continued in most places over hundreds of years without much harm to the natural populations. Until the 1970s, Latin Americans could obtain the meat and eggs with little effort, and the animals sold cheaply in city markets. In recent years, however, the lizards have become scarce and prices have risen sharply. For instance, in 1976 the central market of San Salvador was selling large specimens for the equivalent of 80 cents, but by 1979 prices were generally from three to six times as much. Today, black iguana meat costs more than fish, poultry, pork, or beef.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Eating small game animals is deeply rooted in the traditions of Central America and cannot readily be changed by legislation or education. Despite official edicts, campesinos on a subsistence diet will not willingly forego the little meat they get by capturing and eating lizards. Moreover, legislation is seldom effective because there are too few enforcement officials.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As with the green iguana, it seems likely that when the factors causing hatchling mortality are reduced, a large harvestable annual surplus can be produced. Black iguanas efficiently convert vegetation into high-grade protein suitable for human consumption. Young ones, however, are insectivorous and carnivorous rather than purely herbivorous, and during their first weeks of life may require a more expensive diet (perhaps meat scraps) than green iguanas require. Moreover, most insectivorous lizards require moving prey. They may or may not accept meat scraps as food.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Black iguanas are smaller and more stocky than green iguanas, but weigh up to 3 kg. Their tails are spiny and short. The scales on the tail are enlarged, grow in spirals, and are sharp-pointed. Other than that (apart from being generally greyish black in color), the two animals are similar in appearance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The different black iguana species range from northern Mexico along both coasts of Central America to Panama and Colombia's Caribbean islands. Most tolerate moderate human presence well, often thriving around town garbage dumps and cemeteries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As recently as 1981, black iguanas were shipped to markets by the truckload. Today, they are generally limited or even absent over much of their original range. Nevertheless, they are still the major game animals across extensive areas of Central America. Many of those taken are gravid females, which is disastrous for the populations. Excessive insecticide spraying is also thought to be reducing their populations in some areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Black iguanas thrive in dry, open woodland. They particularly like rocky hillsides, for they depend for shelter on crevices, rock piles, or soft soil in which they dig burrows.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These omnivores feed on foliage, flowers, and fruits, but also on insects and small vertebrates. Adults spend some of their time climbing trees, but they are much less arboreal than green iguanas. Hatchlings are initially terrestrial but have a mostly arboreal stage in their early weeks of life.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Females lay one clutch of 20-90 eggs each year. The eggs are much smaller than those of the green iguana and therefore are not as popular a food. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p357a.png"></center><br>
+ Distribution of the black iguana.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These lizards live in burrows or in holes in trees. A typical burrow has several entrances and is 1-2 m long. Several females may combine efforts to form a complex communal burrow with several individual nest chambers. They are such diligent diggers that many are caught while absorbed in the task of adding a new room.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In some places, even where they are not common, black iguanas are still intensively hunted. Because their meat is valuable, the reward justifies the considerable effort involved in finding and killing them. Hence, where populations are so depleted that organized hunting is unprofitable, the animals are still subjected to relentless destruction by individuals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Farming black iguanas is a novel idea. However, it is not a foolish one. In 1981 the Centro de Recursos Naturales (CENREN) in El </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Salvador started a black iguana farming project. Since then, its researchers have collected data on growth rates, feeding patterns, and the maintenance and reproduction of captive adults. The program offers some promise of maintaining breeding stock in large outdoor enclosures, of producing large numbers of hatchlings, and of restocking depleted areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">OTHER IGUANAS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Other iguanas that deserve consideration for husbandry include the rock (rhinoceros) iguana (Cyclura cornuta), a herbivorous lizard of the Antillean region. This has been raised in considerable numbers at the National Zoo of Santo Domingo, Dominican Republic. Captive-bred specimens have reproduced at the age of 32 months, average clutch size has been about 15, and the average incubation time has been 82 days (at 31&Yacute;C). The innate tameness of these island iguanas renders them better adapted for captive rearing than either the green or the black iguana, and their greater size is an advantage as well. On the other hand, the length of time required to reach maturity, and the relatively small egg clutch (about half that of the green iguana and one-third that of the black iguana) are definite disadvantages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A related species, Iguana delicatissima, also deserves research and conservation attention. It occurs in the Leeward Islands and Martinique, and (as its specific name implies) is even better eating than the green iguana.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Latins believe that various ailments are cured or benefited by the flesh of these lizards, so they willingly pay much more for their meat than they would for equivalent amounts of other meats. In most places where the two occur together, the black iguana is preferred over the green iguana.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Compared with green iguana, the black iguana reproduces readily in captivity and has an even higher reproductive potential (averaging 43 eggs per clutch). It has the additional advantage that it thrives in deforested and altered habitats. It can survive near human settlements despite the attacks of dogs and cats, and it attains dense populations in suburban lots or open spaces. (It survives even downtown in cities such as Managua, but not in dense populations because dogs, cats, and humans take so many.) Hence, even in towns and cities, there are habitats capable of supporting it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Black iguanas will feed on weedy vegetation or garbage, and adults seem easier to maintain in captivity than their green iguana counterparts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The long delay (probably at least two years) before the animals reach marketable size might make it difficult for the grower to compete with common meats such as poultry or fish. Certain parasitic worms can make the flesh inedible.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although smaller than green iguanas, black iguanas are much more aggressive and will defend what they perceive to be their territory. They can inflict a painful bite. They also tend to escape from captivity more readily.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As noted, these omnivores depend on animal matter during part of their life cycle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The biology of the black iguana deserves much more study.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Management techniques developed for the green iguana should be tested for their applicability for black iguana species. Harvesting and recruitment schemes must be developed to create sustainable populations in the wild. The specific needs for feeding the young also need to be addressed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I am convinced that in the Third World, it is only when poor people are assured of their livelihood that they will help us to safeguard their natural environments. So long as people remain hungry, it is very difficult to talk to them about conservation. As a result, I believe that development and conservation are inseparable. Only when conservation takes on a dimension of helping the poor, the downtrodden, the destitute, will it have an enduring impact.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M.S. Swaminathan International Union for Conservation of Nature and Natural Resources</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I suspect that wildness is an inherited characteristic as was found for the turkey by Starker Leopold. So in attempting domestication one should expect to have difficulty until there are enough animals that you can select breeding stock for quietness and tractability.</P>
+<P ALIGN="JUSTIFY">Ian McTaggart Cowan Emeritus Professor of Zoology</P>
+<P ALIGN="JUSTIFY">University of British Columbia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cattle will never be extinct for the simple reason that man eats cattle. The best way to preserve wild species is by demonstrating that they, too, can be a valuable resource.</P>
+<P ALIGN="JUSTIFY">Ernie Matteram</P>
+<P ALIGN="JUSTIFY">New York Times Magazine</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wildlife utilization should be considered a legitimate form of land use, just as much as livestock husbandry. In fact, what has happened in the past is that Man has domesticated a limited number of animals, mainly in the temperate zones, while overlooking a considerable potential of other animals, which could be domesticated or used with equal validity.</P>
+<P ALIGN="JUSTIFY">Antoon De Vos </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Part VII Others</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As noted in the preface, this report by no means exhausts all the microlivestock possibilities. Lack of space and time precludes discussion of creatures such as edible insects, snails, worms, frogs, turtles, and bats, which in some regions are highly regarded foods. Similarly, we have not included fish, shrimp, and other aquatic life.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This is not to say that these are less worthy of consideration. The decision to leave them out was arbitrary, but with several recent breakthroughs in tropical beekeeping it seems prudent to include bees. Accordingly, the final chapter of this book describes the smallest livestock of all.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bees are one of the most promising microlivestock. They forage on flowers that are otherwise little utilized and produce honey, wax, and other products of high value. They are important as plant pollinators and can greatly increase the production of some crops. Bees can be kept virtually anywhere with little disruption of other activities, and they are easily available. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">35 Bees</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="g040a.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Of all the livestock reviewed in this publication, bees are the smallest, the least demanding of space, probably the most familiar, and perhaps the most easily adapted to worldwide rural development efforts. For all that, however, they are an often forgotten component in agricultural programs. This is unfortunate because bees can be particularly valuable to tropical countries, providing pollination of crops, useful products, and a premium source of income.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Almost every village in every tropical country traditionally has had a beekeeper or two. Most use "seat-of-the-pants" methods and "rustic" hives, and this generally leads to low yields and inefficiencies. Today, numerous innovative methods and appropriate equipment are coming available. Many are still not widely known; however, their importance is slowly being recognized. Indeed, some developing countries are already turning bees into a valued natural resource.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For example, in less than 10 years Kenya has become self-sufficient in honey production and - despite increased local consumption - is now exporting. In seven years, Papua New Guinea has met its local honey requirements and now also exports its surplus. In only four years, Thailand increased yearly production from practically nothing to more than 1,000 tons. In Brazil, beekeeping is more widespread and production greater than before the outbreak of the African honey bee. These achievements can be largely attributed to the promotion of innovative equipment, modern beekeeping techniques, and extension support for small-scale beekeepers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">APPEARANCE AND SIZE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Honey bees are generally easily recognized and need no description here. The major species and subspecies are all roughly similar in appearance and size. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DISTRIBUTION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Among several hundred species of bees that store honey and pollen in harvestable amounts, only two "social" species, Apis mellifera and Apis cerana, produce multiple combs and can be kept in hives.' Given adequate forage and proper management, they can build up a honey surplus that can be harvested without harming their colonies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Apis mellifera, the most widely distributed and exploited honey bee, comes from Europe and Africa. The subspecies from Europe (especially the Italian type, A. mellifera ligustica) is normally preferred because of its docility and high honey yields. It is now the predominant honey bee throughout the temperate zones of Europe, North America, Australasia, and China. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Of the many subspecies in Africa, A. mellifera adansonii and A. mellifera scutellata have the widest native ranges. The latter was accidently released in Brazil in 1957. It has become naturalized and has dominated the European bees formerly kept by beekeepers. By l990, it had spread northwards to the southernmost areas of the United States and southwards deep into Argentina.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The docile Asian hive bee, A. cerana, is found in Asia from the Middle East to Japan and as far south as Indonesia. Although it produces much less honey per hive than A. mellifera, its overall production in many Southeast Asian countries may be greater.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STATUS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Honey bees do not face extinction. However, genetic diversity is disappearing due to loss of habitat, insecticides, displacement by massproduced, genetically uniform queens and exotic breeds, destructive harvesting, and the spread of diseases and pests such as protozoans, bacteria, insects, and mites.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HABITAT AND ENVIRONMENT</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Honey bees can exist in locations from deserts to rainforests and from near the Arctic to the tropics. They occur wherever there is nectar, pollen, tree resin (for nest building), shelter, and a little water. Heat, drought, and especially rain and humidity may curtail their activities, but a well-managed colony can survive periods of extreme adversity. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BIOLOGY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Honey bees live in rigidly hierarchical colonies. Normally there is a  single queen. After mating, she begins laying hundreds of eggs a day.  Those that are fertilized become sterile females, called workers; those  that remain unfertilized develop into males (drones), whose only role is  to fertilize future queens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">After two or three years the queen, worn-out, starts laying fewer  and fewer eggs, and the colony may replace her. At that time a few  female larvae are raised on royal jelly, a nutritious, little-understood  secretion that causes them to develop into queens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Workers perform different tasks as they mature. Young ones tend  the queen, guard the hive, and raise the larvae. Older ones, comprising  the vast majority of a colony's population, gather pollen and nectar and  water. Pollen provides the protein and fats, and the nectar, converted  into honey in the bee's body, provides carbohydrates to feed the colony.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEHAVIOR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Honey bee activities are dictated by weather, availability of food,  genetics, and the overall strength of the colony. They are mediated by  chemical interactions between the queen and the workers that control  almost all behavior.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While the Asian and European hive bees are relatively docile, most  of the African subspecies are unpredictable and may defend their  colonies in great numbers and with great persistence. The threat of  "killer bees" has been greatly exaggerated, however. Africans have  provided them nests and hives - and harvested their honey - for  thousands of years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Occasionally, large numbers of the bees in a colony split off from  their nest or hive. They usually cluster on a nearby tree or building,  calmly waiting for "scouts" to find a suitable new home. These  homeless swarms can be captured and will readily move into a hive  the simplest and cheapest way for beekeepers to acquire a colony.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">USES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Honey and beeswax are two of nature's best known and most  valuable products. Honey can be employed in hundreds of foods. It is  widely used in baking because, in addition to its flavor, it retains  moisture better than sugar or syrup, and the product keeps longer. Honey-based alcoholic beverages are popular in many parts of the world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Beeswax also is used in many products, including candles, lubricants, polish, waterproofings, soaps, cosmetics, and electronics. Beeswax can be locally important for `'lost-wax" metal-casting and sculptures as well as batik-dyed clothing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Both bee pollen and royal jelly are used in cosmetics and can be eaten. Bee venom is used medicinally, particularly in Europe and the developing world. Bee larvae are eaten raw or fried in many parts of Asia and Africa and are considered a delicacy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUSBANDRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Keeping bees means managing a colony so that it produces surplus honey or wax. Specifically this requires:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Providing a suitable hive;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Obtaining bees by collecting a swarm, transferring a wild colony, or purchasing a colony complete with an active queen;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Maintaining the colony free from natural enemies in an area that allows it to produce excess honey; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Harvesting the excess honey without weakening the colony or causing it to flee (abscond).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADVANTAGES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Few other livestock enterprises require less capital, less space, or less attention. Moreover, scarcely any other provides higher quality, more marketable products.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Beekeeping is a respected and traditional activity in most areas of the world. It promotes self-reliance and requires little, if any, land or money. It is an easy-entry cottage industry that can be started with minimal equipment or training. It can be done by any member of a family as it requires no special strength or size. It is especially appropriate for increasing women's income in the many areas where men are away working.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Beekeeping is suited to remote areas where many agricultural enterprises are at a competitive disadvantage because their products are bulky and far from the markets. Honey, wax, pollen, and other bee products can all be sold far from their point of origin, have high monetary value for their weight, and generally find a ready market. Local honeys often command premium prices (in part because many of them are considered medicinal). In addition, beekeeping encourages people to remain in rural areas rather than move to the city in search of an income.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pollination increases the productivity of many crops, and therefore a few hives can boost local food production. By rotating hives among farmers' fields and orchards, a beekeeper performs a valuable service.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Beekeeping is also an important adjunct to reforestation and desert reclamation projects. It can provide income during the long wait for the trees to reach marketable size. Many forests are potential reservoirs of honey and other products. In some cases, the bees also enhance the fruitfulness and standing value of forests. They also increase pollination in tree-seed orchards and tree nurseries. And in newly established forests, bees improve reseeding potential. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">BETTER BEEHIVES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">So many hives have been developed in recent years that a design now exists for almost any level of expertise. One of the most important for Third World beekeeping is the top-bar hive. This crate-like box, derived from an ancient Greek design, incorporates modern beekeeping principles but adds the innovation of sloping sides. Beneath its lid are removable boards (top bars) from which the bees hang the combs (because the sides are sloping the bees do not attach the edges of the comb to them). By lifting a top bar, the comb can be inspected and handled - and the honey harvested - with little disturbance to the colony.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This simple hive can make beekeeping accessible to even the poorest people. It is easy to build and use, and can be locally constructed from scrap lumber. It is well suited for raising most types of honey bees.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More elaborate and productive is the African long hive. In addition to having top bars, this square-sided box has removable frames within which the bees build their comb.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The most elaborate is the Langstroth hive - the type most common in temperate zones.* These yield the most honey. They can be made only where there are facilities for precise carpentry, where durable, nonwarping parts are available, and where there are good extension services to aid and assist beekeepers. Although traditional Langstroth hives are demanding to build and maintain, simplified designs have been created for use in developing countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STINGLESS BEES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">By far the most common bees in the tropics, perhaps in the  world, are bees that cannot sting. Their stingers are so akophied  as to be essentially nonexistent (but some can deliver a pretty  fierce bite). They live in colonies and store their honey in wax  pots, some as large as egg cups.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Stingless bees can be abundant. In a two-block area in  downtown Panama City, 150 nests have been counted. However,  many species depend on trees and their populations are  plummeting as more and more tropical forests are felled.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like honey bees, stingless bees have been "domesticated." For  thousands of years in the tropical Americas, Indians have raised  them in special hives made out of logs, gourds, clay pots, and  other simple containers. Cortes reported in 1519 that Indians on  the island of Cozumel, the now popular tourist spot off the east  coast of Yucatan, practiced beekeeping. That was almost 300 years  before the European honeybee was introduced. A popular Mayan  drink was honey wine, and Mayan beekeepers carved stone  earplugs to keep these bees out of their ears.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Honey from stingless bees has less sugar than normal honey.  However, it is usually more tasty. It is used throughout the  tropics: the Americas, Central Africa, and Southeast Asia, for  instance. Normally, the nests are just robbed, which devastates  the bees because the queen cannot fly, and when she is disturbed  the colony dies. In some areas people open a little hole in the nest.  By putting in a plug, they can then harvest honey a couple of  times a year without destroying the colony.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Today, a few scientists are reconsidering stingless beekeeping.  In the state of Maranhao in Brazil, an area of crushing poverty,  biologist Warwick Kerr is harnessing stingless bees. He began  after learning that peasants were spending a third of their meager  incomes buying sugar. As part of his experiments, he keeps 60  hives stacked in his garage on the outskirts of the city of San Luis.  (A notable feature of these bees is that there is no prohibition  against keeping them in populated areas.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kerr has found that stingless bees can be made to produce well.  After years of experimenting with different-sized boxes, he can  now obtain more than 4.5 lifers of honey per hive per year. He  reports that the stingless bees are easy to maintain, and can be  raised by poor peoole without land or equipment.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIMITATIONS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Compared to raising four-footed livestock, beekeeping is inexpensive and fairly trouble free, but it is not without problems. Many things can go wrong, and include, for example:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Losses. Bees are susceptible to various predators, pests, and diseases. Although ways to avoid or control most afflictions are available, once a colony becomes infested it may have to be destroyed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Theft. Hives or combs - usually kept in secluded areas - that are full of honey are tempting targets and may be stolen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Swarming and absconding. Some or all of the bees may leave a hive and start a new nest, taking even the honey with them.2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Bad management. Beekeeping requires certain skills and knowledge, and sometimes frequent attention (such as when the colony is stressed, diseased, or swarming).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Lack of equipment. Beekeepers need hives, smokers (to quiet and repel the bees), hive tools, and - advisable but not absolutely necessary - gloves and a veil.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Inadequate storage. Some areas lack the knowledge or the bottles in which to store liquid honey.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Pesticides and herbicides. Nectar- and pollen-collecting bees are vulnerable to insecticides, which farmers may apply (often inappropriately) at the time their crops are flowering. Herbicides can destroy important sources of bee forage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Neighborhood concerns. Bees can sting people and livestock. Although wild bees (and other insects) are the principal culprits, the beekeeper is often blamed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Stressful conditions. When rainfall, aridity, heat, or cold are excessive, bees often cannot produce surplus honey.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RESEARCH AND CONSERVATION NEEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Surprisingly, much remains to be learned about the natural science of bees. Although some of the research requires sophisticated equipment and facilities, much can (or must) be performed locally by beekeepers because many factors - such as colony behavior, foraging habits, and microclimatic adaptation - depend on the local conditions. This research may include the following:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Adaptation. The provision of locally adapted bee varieties is an important basis for developing advanced beekeeping. This can be done by selecting an appropriate local queen. Further, local breeding of queens and workers lessens the probability of importing exotic diseases and pests. Recent developments promise to move the mass production of queens and workers from the realm of high technology to common practice.4</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Integration. Continued developments in beekeeping cannot succeed without research, promotion, education, training, and extension services. These are essential for integrating beekeeping with agriculture and reforestation efforts. Thus, descriptions of agronomic plants should always include pollination requirements as well as nectar and pollen potentials. Planting nectar- and pollen-producing firewood species would increase the number of bees, which would in turn help ensure forest survival.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Bee plants. There is still much to be understood about the relative qualities that different plants bring to beekeeping. Recently, many valuable bee-forage plants have been identified.5 These deserve special consideration in any reforestation or beautification projects. Broad introduction of these plants may also encourage beekeeping that could produce high-value "specialty" honeys or ensure more continuous production of honey. There may also be a place for "bee farms," where every plant is bee forage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- New bee species. Nontraditional species of Apis as well as other members of the bee family (such as Anthophora, Bombus, Megachilae, Nomia, Osmia, Xylocopa, and especially Trigona and Melipona, which are stingless) should be studied to determine their role in pollination and - for some species - their further exploitation for honey. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendixes</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">A Selected Readings</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">A small selection follows of books and articles that are not too  difficult to locate and that will help readers explore each topic further. Obscure documents are accompanied by an address from which readers can obtain a reprint or photocopy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GENERAL</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Grzimek, B. 1975. Animal Life Encyclopedia. Vol. 1-13. Van Nostrand Reinhold  Company, New York.</P>
+<P ALIGN="JUSTIFY">Robbins, C.T. 1983. Wildlife Feeding and Nutrition. Academic Press, Inc., New York.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MICROBREEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mason, I.L. 1988. A World Dictionary of Livestock Breeds, Types and Varieties.  Commonwealth Agricultural Bureaux, Farnham Royal, Buckinghamshire, UK. Microcattle</P>
+<P ALIGN="JUSTIFY">Barnard, J.P. and J.P. Venter. 1983. Indigenous and Exotic Beef Cattle in South West  Africa - A Progress Report. Available from Department of Agriculture and Nature  Conservation, PB 13184, Windhoek 9000, Namibia. (Sanga)</P>
+<P ALIGN="JUSTIFY">Cheng Peilieu. 1984. Livestock Breeds of China. FAO Animal Production and Health  Paper 46. Food and Agriculture Organization of the United Nations, Rome. 217 pp.</P>
+<P ALIGN="JUSTIFY">Cole, H.H. and W.N. Garrett, eds. 1974. Animal Agriculture. 2nd edition. W.H. Freeman  and Company, San Francisco, California, USA.</P>
+<P ALIGN="JUSTIFY">Epstein, H. and l.L. Mason. 1984. Cattle. Pages 6-27 in Evolution of Domesticated  Animals, I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY">Felius, M. 1985. Genus Bos: Cattle Breeds of the World. MSD-AGVET, Merck and Co.,  Rahway, New Jersey. 234 pp.</P>
+<P ALIGN="JUSTIFY">Gryseels, G. 1980. Improving Livestock and Farm Production in the Ethiopian Highlands:  Initial Results. ILCA study. International Livestock Centre for Africa, Addis Ababa,  Ethiopia.</P>
+<P ALIGN="JUSTIFY">ILCA. 1979. Trypanotolerant Livestock in West and Central Africa. Vol. 1, General Study.  International Livestock Centre for Africa, Addis Ababa, Ethiopia.</P>
+<P ALIGN="JUSTIFY">Joshi, N.R. and R.W. Phillips. 1953. Zebu Cattle of India and Pakistan. FAO Agricultural  Study No. 19. Food and Agriculture Organization of the United Nations, Rome. 297 pp.</P>
+<P ALIGN="JUSTIFY">Joshi, N.R., E.A. McLaughlin, and R.W. Phillips. 1957. Types and Breeds of African  Cattle. FAO Agricultural Study No. 37. Food and Agriculture Organization of the  United Nations, Rome. 297 pp. </P>
+<P ALIGN="JUSTIFY">Koger, M., T.J. Cunha, and A.C. Warnick, eds. 1973. Crossbreeding Beef Cattle. Series 2. University of Florida Press, Gainesville, Florida, USA.</P>
+<P ALIGN="JUSTIFY">Martinez Balboa, A. 1980. La Ganaderia en Baja California Sur. Vol. 1. Editorial J.B. La Paz, BCS: Mexico. 229 pp. (Criollo)</P>
+<P ALIGN="JUSTIFY">Mason, I.L. and J.P. Maule. The Indigenous Livestock of Eastern and Southern Africa. Commonwealth Agricultural Bureaux, Farnham Royal, Buckinghamshire, UK.</P>
+<P ALIGN="JUSTIFY">Maule, J.P. 1989. The Cattle of the Tropics. Centre for Tropical Veterinary Medicine, Edinburgh University, Edinburgh, UK.</P>
+<P ALIGN="JUSTIFY">McDowell, L.R., ed. 1985. Nutrition of Grazing Ruminants in Warm Climates. Academic Press, Inc., New York.</P>
+<P ALIGN="JUSTIFY">McDowell, R.E. 1972. Improvement of Livestock Production in Warm Climates. W.H. Freeman and Company, San Francisco, California, USA.</P>
+<P ALIGN="JUSTIFY">McDowell, R.E. 1983. Strategy for Improving Beef and Dairy Cattle in the Tropics. Cornell International Agricultural mimeo. Cornell University, Ithaca, New York.</P>
+<P ALIGN="JUSTIFY">Miller, W.J. 1979. Dairy Cattle Feeding and Nutrition. Academic Press, Inc., New York.</P>
+<P ALIGN="JUSTIFY">National Research Council. 1980. Animal Science in China. CSCPRC Report No. 12. National Academy Press, Washington, D.C.</P>
+<P ALIGN="JUSTIFY">National Research Council. 1981. Effect of Environment on Nutrient Requirements of Domestic Animals. National Academy Press, Washington, D.C.</P>
+<P ALIGN="JUSTIFY">Perry, T.W. 1980. Beef Cattle Feeding and Nutrition. Academic Press, Inc., New York.</P>
+<P ALIGN="JUSTIFY">Rollinson, D.H.L. 1984. Bali cattle. Pages 28-34 in Evolution of Domesticated Animals, I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY">Rouse, J.E. 1970. World Cattle. Vol. 1, Cattle of Europe, South America, Australia, and New Zealand. University of Oklahoma Press, Norman, Oklahoma, USA.</P>
+<P ALIGN="JUSTIFY">Rouse, J.E. 1970. World Cattle. Vol. 2, Cattle of Africa and Asia. University of Oklahoma Press, Norman, Oklahoma, USA.</P>
+<P ALIGN="JUSTIFY">Rouse, J.E. 1973. World Cattle. Vol.3, Cattle of North America. University of Oklahoma Press, Norman, Oklahoma, USA.</P>
+<P ALIGN="JUSTIFY">Rouse, J.E. 1977. The Criollo-Spanish Cattle in the Americas. University of Oklahoma Press, Norman, Oklahoma, USA. 303 pp.</P>
+<P ALIGN="JUSTIFY">Shirley, R.L. 1986. Nitrogen and Energy Nutrition of Ruminants. Academic Press, Inc., New York.</P>
+<P ALIGN="JUSTIFY">Thrower, W.R. 1954. The Dexter Cow. Revised third impression, 1980. The Spaulding Press, Bethel, Vermont, USA</P>
+<P ALIGN="JUSTIFY">Williamson, G. and W.J.A. Payne. 1965. An Introduction to Animal Husbandry in the Tropics. 2nd edition. Longman, London.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microgoat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Acharya, R.M. 1982. Sheep and Goat Breeds of India. FAO Animal Production and Health Paper No. 30. Food and Agriculture Organization of the United Nations, Rome.</P>
+<P ALIGN="JUSTIFY">Ademosun, A.A. 1985. Capra spp.: The Emblem of Anarchy - The King-Pin of Man's Pastoral Life. Ife Lectures No. 3. University of Ife, Ile-Ife, Nigeria.</P>
+<P ALIGN="JUSTIFY">Cheng Peilieu. 1984. Livestock Breeds of China. FAO Animal Production and Health Paper 46. Food and Agriculture Organization of the United Nations, Rome. 217 pp.</P>
+<P ALIGN="JUSTIFY">Cole, H.H. and W.N. Garrett. 1980. Animal Agriculture. W.H. Freeman and Company, San Francisco, California, USA.</P>
+<P ALIGN="JUSTIFY">Copland, J.W. 1985. Goat Production and Research in the Tropics. Proceedings of a workshop held at the University of Queensland, Brisbane, Australia, February 6-8, 1984. Australian Centre for International Agricultural Research (ACIAR) Proceedings Series No. 7, 118 pp.</P>
+<P ALIGN="JUSTIFY">Devendra, C. and M. Burns. 1983. Goat Production in the Tropics. Commonwealth Agricultural Bureaux, Farnham Royal, Buckinghamshire, UK. 83 pp.</P>
+<P ALIGN="JUSTIFY">Devendra, C. and G.L. McLeroy. 1983. Goat and Sheep Production in the Tropics. 2nd edition. Longman, London. 271 pp.</P>
+<P ALIGN="JUSTIFY">Devendra, C. and J.E. Owen. 1983. Quantitative and qualitative aspects of meat production from goats. World Animal Review (FAO) 47:19-29.</P>
+<P ALIGN="JUSTIFY">Fielding, D. Goat-keeping in Mauritius. Sonderdruck aus Zeitschrift fur Tierzuchtung und Zuchtungsbiologie. Vol 97(1)(1980):21-27.</P>
+<P ALIGN="JUSTIFY">Gall, C., ed. 1981. Goat Production. Academic Press, London. 619 pp.</P>
+<P ALIGN="JUSTIFY">Haenlein, G.F.W. and D.L. Ace. 1983. Goat Extension Handbook. University of Delaware Cooperative Extension Service, Newark, Delaware, USA.</P>
+<P ALIGN="JUSTIFY">Husnain, H.V. 1985. Sheep and Goats in Pakistan. FAO Animal Production and Health Paper No. 56. Food and Agriculture Organization of the United Nations, Rome.</P>
+<P ALIGN="JUSTIFY">International Development Research Centre (IDRC). Small Ruminant Production Systems in South and Southeast Asia, C. Devendra, ed. Proceedings of a workshop held in Bogor, Indonesia, October 6-10, 1986, cosponsored by the Small Ruminant Collaborative Research Support Program. Ottawa, Ontario, Canada.</P>
+<P ALIGN="JUSTIFY">ILCA. 1983. Peste des Petits Ruminants (PPR) in Sheep and Goats, D.H. Hill, ed. Proceedings of the International Workshop held at the International Institute of Tropical Agriculture (IITA), Ibadan, Nigeria, September 24-26, 1980. International Livestock Centre for Africa, Addis Ababa, Ethiopia.</P>
+<P ALIGN="JUSTIFY">ILCA. 1985. Sheep and Goats in Humid West Africa. Proceedings of the International Workshop held in Ibadan, Nigeria, January 23-26, 1984. International Livestock Centre for Africa, Addis Ababa, Ethiopia.</P>
+<P ALIGN="JUSTIFY">ILCA. 1979. Trypanotolerant Livestock in West and Central Africa. Vol. 1, General Study. International Livestock Centre for Africa, Addis Ababa, Ethiopia.</P>
+<P ALIGN="JUSTIFY">King, J.W.B., ed. 1988. Directory of Research on Sheep and Goats. Commonwealth Agricultural Bureaux International, Wallingford, Oxford, UK. 271 pp.</P>
+<P ALIGN="JUSTIFY">Mason, I.L. 1981. Breeds. Pages 57-110 in Goat Production, C. Gall, ed. Academic Press, London.</P>
+<P ALIGN="JUSTIFY">Mason, I.L. 1984. Goat. Pages 85-99 in Evolution of the Domesticated Animals, I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY">Mason, I.L. and J.P. Maule. 1960. The Indigenous Livestock of Eastern and Southern Africa. Commonwealth Agricultural Bureaux, Farnham Royal, Buckinghamshire, UK.</P>
+<P ALIGN="JUSTIFY">National Research Council, 1980. Animal Science in China. CSCPRC Report No. 12. National Academy Press, Washington, D.C.</P>
+<P ALIGN="JUSTIFY">Phillips, R.W., R.G. Johnson, and R.T. Moyer. 1945. The Livestock of China. U.S. Department of State Publication No. 2249, Far Eastern Series 9. U.S. Department of State, Washington, D.C. 174 pp.</P>
+<P ALIGN="JUSTIFY">Proceedings of the 3rd International Conference on Goat Production and Disease. January 10-15, 1982, University of Arizona, Tucson, Arizona. Copies can be obtained from Kent Leach, Dairy Goat Journal, P.O. Box 1808, Scottsdale, Arizona 85252, USA. </P>
+<P ALIGN="JUSTIFY">Williamson, G. and W.J.A. Payne. 1965. An Introduction to Animal Husbandry in the Tropics. 2nd edition. Longman, London.</P>
+<P ALIGN="JUSTIFY">Wilson, R.T., T. Murayi, and A. Rocha. 1989. Indigenous African small ruminant strains with potentially high reproductive performance. Small Ruminant Research 2: 107-117.</P>
+<P ALIGN="JUSTIFY">Winrock International, 1984. Sheep and Goats in Developing Countries. Winrock International Technical Paper. The World Bank, Washington, D.C. </P>
+<P ALIGN="JUSTIFY">Acharya, R.M. 1982. Sheep and Goat Breeds of lndia. FAO Animal Production and Health Paper No. 30. Food and Agriculture Organization of the United Nations, Rome.</P>
+<P ALIGN="JUSTIFY">Carles, A.B. 1983. Sheep Production in the Tropics. Oxford University Press, London. 213 pp.</P>
+<P ALIGN="JUSTIFY">Cheng Peilieu. 1984. Livestock Breeds of China. FAO Animal Production and Health Paper 46. Food and Agriculture Organization of the United Nations, Rome. 217 pp. Cole, H.H. and W.N. Garrett. 1980. Animal Agriculture. W.H. Freeman and Company,</P>
+<P ALIGN="JUSTIFY">San Francisco, Calffornia, USA.</P>
+<P ALIGN="JUSTIFY">Devendra, C. and G.L. McLeroy. 1983. Goat and Sheep Production in the Tropics. </P>
+<P ALIGN="JUSTIFY">Longman, London. 271 pp.</P>
+<P ALIGN="JUSTIFY">Fitzhugh, H.A. and G.E. Bradford, eds. 1983. Hair Sheep of Western Africa and the Americas. Westview Press, Boulder, Colorado, USA. </P>
+<P ALIGN="JUSTIFY">Husnain, H.V. 1985. Sheep and Goats in Pakistan. FAO Animal Production and Health Paper No. 56. Food and Agriculture Organization of the United Nations, Rome. International Development Research Centre (IDRC). 1987. Small Ruminant Production Systems in South and Southeast Asia, C. Devendra, ed. Proceedings of a workshop held in Bogor, Indonesia, October 6-10, 1986, cosponsored by the Small Ruminant Collaborative Research Support Program. IDRC, Ottawa, Canada. </P>
+<P ALIGN="JUSTIFY">ILCA. 1983. Peste des Petits Ruminants (PPR) in Sheep and Goats, D.H. Hill, ed. Proceedings of the International Workshop held at the International Institute of Tropical Agriculture (IITA), Ibadan, Nigeria, September 24-26, 1980. International Livestock Centre for Africa, Addis Ababa, Ethiopia.</P>
+<P ALIGN="JUSTIFY">ILCA. 1985. Sheep and Goats in Humid West Africa. Proceedings of the International Workshop held in Ibadan, Nigeria, January 23-26, 1984. International Livestock Centre for Africa, Addis Ababa, Ethiopia.</P>
+<P ALIGN="JUSTIFY">ILCA. 1979. Trypanotolerant Livestock in West and Central Africa. Vol. 1, Ceneral </P>
+<P ALIGN="JUSTIFY">Study. International Livestock Centre for Africa, Addis Ababa, Ethiopia. </P>
+<P ALIGN="JUSTIFY">King, J.W.B., ed. 1988. Directory of Research on Sheep and Goats. Commonwealth</P>
+<P ALIGN="JUSTIFY">Agricultural Bureaux International, Wallingford, Oxford, UK. 271 pp.</P>
+<P ALIGN="JUSTIFY">Mason, I.L. 1980. Prolific Tropical Sheep. FAO Animal Production and Health Paper No. 17. Food and Agriculture Organization of the United Nations, Rome.</P>
+<P ALIGN="JUSTIFY">Mason, l.L.1967. Sheep Breeds of the Mediterranean. Food andAgriculture Organization of the United Nations. Commonwealth Agricultural Bureaux, Farnham Royal, UK.</P>
+<P ALIGN="JUSTIFY">Mason, I.L. and J.P. Maule. 1960. The Indigenous Livestock of Eastern and Southern Africa. Commonwealth Agricultural Bureaux, Farnham Royal, Buckinghamshire, UK. Phillips, R.W., R.C. Johnson, and R.T. Moyer. 1945. The Livestock of China. U.S. Department of State Publication No. 2249, Far Eastern Series 9. U.S. Department of State, Washington, D.C. 174 pp.</P>
+<P ALIGN="JUSTIFY">Ponting, K. 1980. Sheep of the World. Blandford Press, Ltd., Poole, Dorset, UK.</P>
+<P ALIGN="JUSTIFY">Ryder, M.L. 1984. Sheep. Pages 63-85 in Evolution of Domesticated Animals, I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY">Ryder, M.L. 1983. Sheep and hIan. Monograph. Duckworth, London.</P>
+<P ALIGN="JUSTIFY">Terrill, C.E. 1970. Sheep breeds of the world. (505 breeds). USDA mimeo. U.S. Department of Agriculture, Washington, D.C. 163 pp.</P>
+<P ALIGN="JUSTIFY">Whitehurst, V.E., R.M. Crown, R.W. Phillips, and D.A. Spencer. 1947. Productivity of Columbia sheep in Florida and their use for crossing with native sheep. Florida Agricultural Experimental Station Bulletin 429. 34 pp.</P>
+<P ALIGN="JUSTIFY">Williamson, G. and W.J.A. Payne. 1965. An Introduotion to Animal Husbandry in the Tropics. 2nd edition. Longman, London. </P>
+<P ALIGN="JUSTIFY">Wilson, R.T., T. Murayi, and A. Rocha. 1989. Indigenous African small ruminant strains with potentially high reproductive performance. Small Ruminant Research 2: 107-117. Winrock International. 1984. Sheep and Goats in Developing Countries. Winrock International Technical Paper. The World Bank, Washington, D.C.</P>
+<P ALIGN="JUSTIFY">Yaltin, B.C. 1979. The Sheep Breeds of Afghanistan, lran, and Turkey. Food and Agriculture Organization of the United Nations, Rome.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Micropig</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cheng Peilieu. 1984. Livestock Breeds of China. FAO Animal Production and Health Paper 46. Food and Agriculture Organization of the United Nations, Rome.</P>
+<P ALIGN="JUSTIFY">Clutton-Brock, J. 1981. Domesticated Animals from Early Times. British Museum (Natural History), London.</P>
+<P ALIGN="JUSTIFY">Cole, H.H. and W.N. Garrett. 1980. Animal Agriculture. W.H. Freeman and Company, San Francisco, Calffornia, USA.</P>
+<P ALIGN="JUSTIFY">Cunha, T.J. 1977. Swine Feeding and Nutrition. Academic Press, Inc., New York.</P>
+<P ALIGN="JUSTIFY">Epstein, H. and M. Bichard. 1984. Pigs. Pages 145-162 in Evolution of Domesticated </P>
+<P ALIGN="JUSTIFY">Animals, I.L. Mason, ed. Longman, London. </P>
+<P ALIGN="JUSTIFY">Krider, J.L., J.H. Conrad, and W.E. Carroll. 1982. Swine Production. McGraw-Hill Company, New York.</P>
+<P ALIGN="JUSTIFY">Mason, I.L. and J.P. Maule. 1960. The Indigenous Livestock of Eastern and Southern Africa. Commonwealth Agricultural Bureaux, Farnham Royal, Buckinghamshire, UK. National Research Council. 1983. Little-Known Asian Animals with a Promising Economic Future. National Academy Press, Washington, D.C. National Research Council. 1980. Animal Science in China. CSCPRC Report No. 12. National Academy Press, Washington, D.C.</P>
+<P ALIGN="JUSTIFY">Panepinto, L.M. 1986. Miniature swine in biomedical research. LabAnimal 15(8)(November/December 1986):21-27.</P>
+<P ALIGN="JUSTIFY">Panepinto, L.M., R.W. Phillips, L.R. Wheeler, and D.H. Will. 1978. The Yucatan miniature pig as a laboratory animal. Laboratory Animal Science 28(3):308-313.</P>
+<P ALIGN="JUSTIFY">Phillips, R.W. and T.Y. Hou. 1944. Chinese swine and their performance compared with modern and crosses between Chinese and modern breeds. Journal of Heredity 35:365-79.</P>
+<P ALIGN="JUSTIFY">Pond, W.G. and J.H. Maner. 1984. Swine Production and Nutrition. AVI Publishing Company, Westport, Connecticut, USA.</P>
+<P ALIGN="JUSTIFY">Williamson, G. and W.J.A. Payne. 1965. An Introduction to Animal Husbandry in the Tropics. 2nd edition. Longman, London. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">POULTRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The World's Poultry Science Journal is published 3 times a year by the World's Poultry Science Association, (c/o Institut f-r Kleintierzucht, Dornbergstrasse 25/27, Postfach 280, C-3100 Celle, Germany). It has also published a multilingual poultry dictionary.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Poultry, an international journal on poultry, is published by Misset International, a department of Uitgeversmaatschappij, C. Misset b.v., Doetinchem-The Netherlands. (Address: Misset International, P.O. Box 4, 7000 BA Doetinchem, Netherlands.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Poultry Science is published monthly by the Poultry Science Association, Inc., 309 West Clark Street, Champaign, Illinois 61820, USA. British Poultry Science, a quarterly, is available c/o Longman Group Ltd., Subscriptions (Journals) Department, Fourth Avenue, Harlow, Essex CM195AA, UK. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chicken</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Attfield, H.H.D. 1990. Raising Chickens and Ducks. Volunteers in Technical Assistance, Arlington, Virginia, USA.</P>
+<P ALIGN="JUSTIFY">Crawford, R.D. 1984. Domestic fowl. Pages 298-311 in Evolution of Domesticated Animals, I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY">Ensminger, M.E.1971. Poultry Science. Interstate Printers and Publishers, Inc., Danville, Illinois, USA.</P>
+<P ALIGN="JUSTIFY">Fielding, D. 1984. The silent scavengers. African Farming September/October 1984: 11-13.</P>
+<P ALIGN="JUSTIFY">Howman, K.C. 1980. Pheasants: Their Breeding and Management. K&amp;R Books, UK.</P>
+<P ALIGN="JUSTIFY">Huchzermeyer, F.W. 1973. Free ranging hybrid chickens under African tribal conditions. Rhodesian Agricultural Journal 70:73-75.</P>
+<P ALIGN="JUSTIFY">Latif, M.A. 1985. In-Depth Analysis on the Successful Experience of Poultry Production in Bangladesh. Report submitted to FAO-APHC Regional Animal Production and Health Office. FAD/UN, Bangkok, Thailand.</P>
+<P ALIGN="JUSTIFY">Matthewman, R.W. 1977. A Survey of Small Livestock Production at the Village Level in the Derived Savannah and Lowland Forest Zones of South West Nigeria. M.Sc. thesis, University of Reading, UK.</P>
+<P ALIGN="JUSTIFY">MTrat, P. 1986. Potential usefulness of the Na (Naked Neck) gene in poultry production. [Vorld's Poultry Science Journal 42:124-142.</P>
+<P ALIGN="JUSTIFY">Nesheim, M.C., R.E. Austic, and L.E. Card. 1979. Poultry Production. 12th edition. Lea and Febiger, Philadelphia.</P>
+<P ALIGN="JUSTIFY">Phillips, R.W., R.C. Johnson, and R.J. Moyer. 1945. The Livestock of China. U.S. Department of State Publication No. 2249, Far Eastern Series 9. U.S. Department of State, Washington, D.C. 174 pp.</P>
+<P ALIGN="JUSTIFY">Sainsbury, D. 1980. Poultry Health and Management. Granada, London.</P>
+<P ALIGN="JUSTIFY">Scott, M.L., M.C. Nesheim, and R.J. Young. 1982. Nutrition of the Chicken. M.L. Scott and Associates, Ithaca, New York.</P>
+<P ALIGN="JUSTIFY">Smith, A.J. nd. Supplementation for scavenging animals. Unpublished paper. Copies available from A.J. Smith, Centre for Tropical Veterinary Medicine, Easter Bush, Roslin, Midlothian EH25 9RG, Scotland, UK.</P>
+<P ALIGN="JUSTIFY">Somes, R. 1984. International Registry of Poultry Genetic Stocks. BuDetin 469, University of Connecticut Agricultural Experiment Station, Storrs, Connecticut, USA.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Araucanian</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wilhelm, G.O.E. 1965-1966. La Gallina Araucana (Gallus inauris castelloi 1914). Universidad de Concepcion, Concepcion, Chile, Boletia de Concepcion 40:5-26.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Duck</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A film, Duck Farmingan Indonesian Tradition, is available from the CSIRO Film and Video Unit, 314 Albert Street, East Melbourne 3002, Victoria, Australia. Soundtrack is in English or Indonesian and it is available in 16 mm or VHS/Beta Video.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Attfield, H.H.D. 1990. Raising Chickens and Ducks. Volunteers in Technical Assistance, Arlington, Virginia, USA. </P>
+<P ALIGN="JUSTIFY">Clayton, G.A. 1984. Common duck. Pages 334-339 in Evolution of Domesticated Animals, I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY">Farrell, D. and P. Stapleton, eds. 1986. Duck Production, Science and World Practice. Proceedingsofaduckproductionworkshop, November 18-22, 1985, Bogor, Indonesia. Central Research Institute for Animal Science. Available from Department of Biochemistry, Microbiology and Nutrition, University of New England, Armidale, NSW 2351, Australia. 430 pp.</P>
+<P ALIGN="JUSTIFY">Holderread, D. 1978. The Home Duck Flock. The Hen House, P.O. Box 492, Corvallis, Oregon 97330, USA.</P>
+<P ALIGN="JUSTIFY">Kingston, D.K., D. Kosasih, and I. Ardi. 1979. The Rearing of Alabio Dt~cklings -nd Management of the Laying Duck Flocks in the Swamps of South Kalimantan. Report No. 9. Centre for Animal Research and Development, Ciawi, Bogor, Indonesia.</P>
+<P ALIGN="JUSTIFY">Petheram, R.J. and A. Thahar. 1983. Duck egg production systems in West Java. Agricultural Systems 2:75-86.</P>
+<P ALIGN="JUSTIFY">Phillips, R.W., R.G. Johnson, and R.J. Moyer. 1945. The Livestock of China. U.S. Department of State Publication No. 2249, Far Eastern Series 9. U.S. Department of State, Washington, D.C. 174 pp.</P>
+<P ALIGN="JUSTIFY">Sainsbury, D. 1980. Poultry Health and Management. Granada, London.</P>
+<P ALIGN="JUSTIFY">Scott, M.L. and W.F. Dean. 1991. Nutrition and Management of Ducks. M.L. Scott of Ithaca, Publisher (P.O. Box 4464, Ithaca, New York 14852, USA)</P>
+<P ALIGN="JUSTIFY">Warren, A.G. 1972. Ducks and geese in the tropics. World Animal Review 3:35-36.</P>
+<P ALIGN="JUSTIFY">Yi Yung and Yu-Ping Zhon. 1980. The Pekin duck in China. World Animal Review 34:11-14.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Geese</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crawford, R.D. 1984. Goose. Pages 345-349 in Evolution of Domesticated Animals, I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY">FAO. 1983. The Goose and its Possible Use for Controlling Weeds. Small Animals for Small Farms. GAN-I. FAO Regional Office for Latin America and the Caribbean, Casilla 10095, Santiago, Chile.</P>
+<P ALIGN="JUSTIFY">Holderread, D. 1981. The Book of Geesea Complete Guide to Raising the Home Flock. Hen House Publications, P.O. Box 492, Corvallis, Oregon 97339, USA.</P>
+<P ALIGN="JUSTIFY">Phillips, R.W., R.G. Johnson, and R.J. Moyer. 1945. The Livestock of China. U.S. Department of State Publication No. 2249, Far Eastern Series 9. U.S. Department of State, Washington, D.C. 174 pp.</P>
+<P ALIGN="JUSTIFY">Soames, B. 1980. Keeping Domestic Geese. Blandford, London. 159 pp.</P>
+<P ALIGN="JUSTIFY">USDA Extension Service. 1983. Raising Geese. Farmer's Bulletin No. 2251. U.S. Department of Agriculture, Washington, D.C.</P>
+<P ALIGN="JUSTIFY">Warren, A.G. 1972. Ducks and geese in the tropics. World Animal Review 3:35-36.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea Fowl</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many research papers have been published in French, Italian, Spanish, and Russian, but few in English.</P>
+<P ALIGN="JUSTIFY">Ayeni, J.S.O. 1983. Studies of Grey Breasted Helmet Guineafowl (Numida meleagris galeata Pallas) in Nigeria. World's Poultry Science Journal 39(2):143-151.</P>
+<P ALIGN="JUSTIFY">Belshaw, R.H.H. 1985. Guinea Fowl of the World. Nimrod Book Services, P.O. Box No. 1, Liss, Hampshire, UK. </P>
+<P ALIGN="JUSTIFY">Blum, J.C., J. Guillaume, and B. Leclercq. 1975. Studies of the energy and protein requirements of the growing guinea-fowl. Br-ish Poultry Science 16:157-168.</P>
+<P ALIGN="JUSTIFY">Cauchard, J.C. 1971. La Pintade. Henri Peladan, UzFs, France.</P>
+<P ALIGN="JUSTIFY">Chemillier, J. 1984. L'Alimentation de la Pintade. F. Hoffmann-La Roche and Cie, 52, Boulevard du Parc, 92521 Neuilly-sur-Seine, Cedex, France.</P>
+<P ALIGN="JUSTIFY">Commonwealth Agricultural Bureaux. 1968. Guinea Fowl Breeding and Managernent. Annotated Bibliography No. 85. The Commonwealth Bureau of Animal Breeding and Genetics, King's Buildings, Edinburgh 9, Scotland, UK.</P>
+<P ALIGN="JUSTIFY">Leclercq, B. 1982. Alimentation des Futurs Reproducteurs Pintades. Pages 101-111 in FertilitT et Alimentation des Volailles. I.N.R.A. Edit.7 Versailles, France.</P>
+<P ALIGN="JUSTIFY">Leclercq, R. and B. Sauveur. 1982. L'alimentation des reproducteurs pintades. Pages 113-135 in FertilitT et Alimentation des Volailles, I.N.R.A. edit., Versailles, France.</P>
+<P ALIGN="JUSTIFY">Lukefahr, S. Raising guinea fowl. Paper available from author, c/o International Small Livestock Research Center, Alabama Agricultural and Mechanical University. P.O. Box 264, Normal, Alabama 35762, USA.</P>
+<P ALIGN="JUSTIFY">Ministry of Agriculture, Fisheries and Food. 1985. Small-scale guinea-few! production. Pamphlet 934. Ministry of Agriculture, Fisheries and Food (Publications), Lion House, Alnwick, Northumberland NE66 2PF, UK.</P>
+<P ALIGN="JUSTIFY">Mongin, P. and M. Plouzeau. 1984. Guinea-fowl. Pages 322-324 in Evolution of Domesticated Animals, I . L. Mason, ed. Longman, London .</P>
+<P ALIGN="JUSTIFY">USDA. 1970. Raising Cuinea Fowl. Leaflet No. 519. U.S. Department of Agriculture, Washington, D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muscovy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Clayton, G.A. 1984. Muscovy duck. Pages 340-344 in Evolution of Domesticated Animals, I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY">De Corville, H. 1972. La Production du Canard de Barbarie. Copies available from Institut nacional de la recherce agronomique (INRA), Nouzilly, France.</P>
+<P ALIGN="JUSTIFY">Farrell, D. and P. Stapleton, eds. 1986. Duck Production, Science and World Practice. Proceedings of a duck production workshop, November 18-22, 1985, Bogor, Indonesia. Central Research Institute for Animal Science. Copies available from D. Farrell, University of New England, Armidale, NSW 2351, Australia.</P>
+<P ALIGN="JUSTIFY">Jeffreys, M.D.W. 1956. The Muscovy duck. The Nigerian Field21(3):108-11.</P>
+<P ALIGN="JUSTIFY">Kingston, D.J., D. Kosasih, and I. Ardi. 1978. The Use of the Muscovy Drrck for Hatching of Alabio Duck &Yacute;ggs in the Swamplands of Kalimantan. Centre Report No. 7. Centre for Animal Research and Development, Bogor, Indonesia.</P>
+<P ALIGN="JUSTIFY">Richet, M. 1985. La production du canard de Barbarie. Techniques Agricoles 3770.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigeon</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Abs, M., ed. 1983. Pltysiology and Behavior of the Pigeon. Academic Press, Inc., New York.</P>
+<P ALIGN="JUSTIFY">Hawes, R.O. 1984. Pigeons. Pages 351-356 in Evolution of Domesticated Anirnals, I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY">Hollander, W.F. and W.J. Miller. 1981. Hereditary variants of behavior and vision in the pigeon. Iowa State Journal of Research 55(4):323-331.</P>
+<P ALIGN="JUSTIFY">Levi, W.M. 1965. Encyclopedia of Pigeon Breeds. T.F.H. Publications, Jersey City, New Jersey, USA. </P>
+<P ALIGN="JUSTIFY">Levi, W.M. 1981. The Pigeon. 2nd edition revised. Levi Publishing, Sumter, South Carolina, USA.</P>
+<P ALIGN="JUSTIFY">Murton, R.K., R.P.J. Thearle, and J. Thompson. 1972. Ecological studies of the feral pigeon (Columba livia). 1. Population, breeding biology and methods of control. II. Flock behaviour and social organisation. Ecology 9:835-889.</P>
+<P ALIGN="JUSTIFY">University of Wisconsin. 1977. Pigeons. Bulletin 4-H 135. University of Wisconsin, Madison, Wisconsin, USA.</P>
+<P ALIGN="JUSTIFY">USDA. 1963. Squab Raising. Farmers Bulletin No. 684. U.S. Department of Agriculture, Washington, D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Quail</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bourquin, O. 1980. Biology of rhe Quail (Coturnix coturnix Linnaeus 1758). Ph.D. thesis, University of Natal, Pietermaritzburg, Republic of South Africa.</P>
+<P ALIGN="JUSTIFY">Katoh, H. and N. Wakasugi. 1980. Studies on the blood groups in the Japanese quail: detection of three antigens and their inheritance. Developmental and Comparative Immunology 4:99-110.</P>
+<P ALIGN="JUSTIFY">Kawahara, T. 1973. Comparative study of quantitative traits between wild and domestic Japanese quail (Coturnix coturnix japonica). Experimental Animals 22(supplement): 138-50.</P>
+<P ALIGN="JUSTIFY">Marsh, A. Quail Manual. Marsh Farms, 7171 Patterson Drive, Garden Grove, Calffornia 92641, USA.</P>
+<P ALIGN="JUSTIFY">National Academy of Sciences. 1969. Coturnix (Coturnix coturnix japonica): Standards and Guidelines for the Breeding, Care, and Management of Laboratory' Animals. National Academy of Sciences, Washington, D.C.</P>
+<P ALIGN="JUSTIFY">Quail Production Technology. Leaflet No. 13/1982. Central Avian Research Institute, Izatnagar, India. </P>
+<P ALIGN="JUSTIFY">Somes, R.G., Jr. 1981. International Registry of Poultry Genetic Stocks. Storrs Agricultural Experiment Station, University of Connecticut, Storrs, Connecticut, USA.</P>
+<P ALIGN="JUSTIFY">Varghese, S.K. 1981. Coturnix Internationalat home and in the Caribbean. Poultry Science 60:1747.</P>
+<P ALIGN="JUSTIFY">Varghese, S.K. 1982. Coturnix production proves to be a profitable business. Poultry Science 61:1560.</P>
+<P ALIGN="JUSTIFY">Varghese, S.K. 1983. Processing and yield of coturnix (Japanese quail). Poultry Science 62:1517</P>
+<P ALIGN="JUSTIFY">Wakasugi, N. and K. Kondo. 1973. Breeding methods for maintenance of mutant genes and establishment of strains in the Japanese quail. Experimental Animals 22(Supplement): I 51 -9.</P>
+<P ALIGN="JUSTIFY">Woodard, A.E., A. Abplanalp, W.O. Wilson, and P. Vohra. 1973. Japanese Quail Husbandry in the Laboratory. Department of Avian Sciences, University of Calffornia, Davis, Calffornia 95616, USA.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Turkey</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Berg, R. and D. Halvorson. 1985. Turkey Management Guide. Minnesota Turkey Growers Association, 678 Transfer Road, St. Paul, Minnesota 55114, USA.</P>
+<P ALIGN="JUSTIFY">Crawford, R.D. 1984. Turkey. Pages 325-334 in Evolution of Domesticated Animals, I.L. Mason, ed. Longman, London. </P>
+<P ALIGN="JUSTIFY">Ensminger, M.E. 1971. PoultryScience. InterstatePrintersandPublishers, Inc., Danville,</P>
+<P ALIGN="JUSTIFY">Illinois, USA. Sainsbury, D. 1980. Poultry Health and Management. Granada, London.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RABBITS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The Rabbit Research Center has been established at Oregon State University, Corvallis, Oregon 97331, USA. It publishes the Journal of Applied Rabbit Research, whose purpose is to convey current research information to those with an interest in commercial rabbit production. The journal describes research conducted at the center and reviews rabbit research results reported in the world's scientific literature.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Founded in 1976 in Paris, the World Rabbit Science Association (Typing House, Shurdington, Cheltenhem, Gloucestershire, GL51 SXF, UK) publishes a newsletter of coming events and chronicles the progress of rabbit farming in most countries of the world. Its aims are to facilitate the advancement of the various branches of the rabbit industry, disseminate knowledge, and study problems of production and marketing. Its members represent individuals and associations in 20 countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The American Rabbit Breeder's Association (1925 South Main Street, Bloomington, Illinois 61701, USA) has published a book, Guide to Producing Better Rabbits, which contains an abundance of information concerning management and diseases of the domestic rabbit. The organization also publishes a bimonthly magazine, Domestic Rabbit, that includes a great deal of updated information on rabbit raising.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Asociacion Espanola de Cunicultura (Spanish Rabbit Science Association), Now, 23 08785 Ballbona d'Anoia, Barcelona, Spain, has a set of slides for training, covering breeds, handling, pathology, and commercialization.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Report of the Workshop on Rabbit Husbandry. Copies of this report are available free of charge from the International Foundation for Science, Sibyllegatan 47, S-114 42 Stockholm, Sweden. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A Working Rabbit Literature Resources File. This materia, is directed at scientists working on some aspect of domestic rabbit research. It lists methods of computer searching for scientific reports in the world's scientific literature, various types of computer literature searches, including commerciaHy available ones, and government services. It a,so includes a list of prepared abstracts. The address is D.D. Caveny and H. L. Enos, Colorado State University, Fort Collins, Colorado 80523, USA. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Domestic Rabbit</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ministry of Livestock Development. 1981. Rabbit Production. Kenya Ministry of Livestock Development. Copies can be obtained from the Agricultural Information Centre, P.O. Box 14733, Nairobi, Kenya.</P>
+<P ALIGN="JUSTIFY">Attfield, H.H.D. 1977. Rabbit Raising. Volunteers in Technical Assistance, 1815 Lynn</P>
+<P ALIGN="JUSTIFY">Street, Arlington, Virginia 22209, USA. 90 pp.</P>
+<P ALIGN="JUSTIFY">Bennett, R. 1975. Raising Rabbits the Modern Way. Garden Way Publishing, Charlotte, Vermont 05445, USA.</P>
+<P ALIGN="JUSTIFY">Cheeke, P.R. 1987. Rabbit Feeding and Nutrition. Academic Press, Inc., New York.</P>
+<P ALIGN="JUSTIFY">Cheeke, P.R., N.M. Patton, S.D. Lukefahr, and J.I. McNitt. 1986. Rabbit Production. Sixth edition. The Interstate, Danville, Illinois, USA. </P>
+<P ALIGN="JUSTIFY">FAO. 1986. Cooking Rabbits. Food and Agriculture Organization of the United Nations,  Regional Office for Latin America and the Caribbean, Santiago, Chile.</P>
+<P ALIGN="JUSTIFY">FAO. 1986. Self-Teaching Manual on Backyard Rabb- Rearing. Food and Agriculture  Organization of the United Nations, Regional Office for Latin America and the  Caribbean, Santiago, Chile.</P>
+<P ALIGN="JUSTIFY">FAO. 1986. Backyard Rabbit Rearing: Some Basic Husbandry Practices. Small Animals  for Small Farms. GAN-16. Food and Agriculture Organization of the United Nations,  Regional Office for Latin America and the Caribbean, Santiago, Chile.</P>
+<P ALIGN="JUSTIFY">Schlolaut, W., ed. 1985. A Compendium of Rabbit Production. Gesellschaft f-r  Technische Zusammenarbeit (GTZ) Publication No. 169. TZ-Verlagsgesellschaft mbH,  Postfach 36, D6101 Rossdorf, Germany.</P>
+<P ALIGN="JUSTIFY">Sicivaten, J. and D. Stahl. 1982. A Complete Handbook on Backyard and Commercial  Rabbit Production. CARE/Philippines.</P>
+<P ALIGN="JUSTIFY">Vogt, D.W. 1982. Raising Rabbits in Hawaii. Circular 499, Cooperative Extension  Service, College of Tropical Agriculture and Human Resources, University of Hawaii at  Manoa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RODENTS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agouti</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A report summarizing preliminary results in a captive-breeding project in Mexico is available from A. D. Cuaron (see Research Contacts for address).</P>
+<P ALIGN="JUSTIFY">Deutsch, L.A., and G. Santos. 1984. Contribuitao pare o conhecimento do gOnero  Dasyproctareprodutao de cutiasentre cruzamente das espTcies Dasyprocta aguti,  Dasyprocta azarae e Dasyprocta fuliginosa. Congresso Brasileiro de Zoologia, II,  BelTm, 1984. Resumos. . .BelTm, SBZ/UFPalMPEC, p. 383-4/(Resumos 390). Copies  available from the authors, see Research Contacts.</P>
+<P ALIGN="JUSTIFY">Clark, M.M. and B.G. Galef, Jr. 1977. Patterns of agonistic interaction and space  utilization by agoutis, Dasyprocta punctata. Behavioral Biology 20:135-140.</P>
+<P ALIGN="JUSTIFY">Leopold, A.S. 1959. Pages 388-393 in Wildlife of Mexico. University of California Press,  Berkeley and Los Angeles.</P>
+<P ALIGN="JUSTIFY">Meritt, D.A., Jr. 1982. Bibliography of Dasyprocta (Rodentia). Brenesia 19/20:595-612.</P>
+<P ALIGN="JUSTIFY">Meritt, D.A., Jr. 1983. Preliminary observations on reproduction in the Central  American agouti, Dasyprocta punctata. Zoo Biology 2:127-131.</P>
+<P ALIGN="JUSTIFY">Morris, D. 1962. The behaviour of the green acouchi (Myoprocta pratti) with special  reference to scatter hoarding. Proceedings Zoological Society of London 139:701732.</P>
+<P ALIGN="JUSTIFY">Smith N. 1974. Agouti and babassu. Oryx 12(5):581-582.</P>
+<P ALIGN="JUSTIFY">Smythe, N. 1978. The Natural History of the Central American Agouti (Dasyprocta  punctata). Smithsonian Contributions to Zoology No. 257. Smithsonian Institution,  Washington, D.C., USA. 52 pp.</P>
+<P ALIGN="JUSTIFY">Tribe, C.J., R. Leher, M.C.O. Doglio, M.I.L. Rebello, D.S. Mello, and E.M.M. Guimar es.  1985. Uma tentative de esclarecimento do uso de espato e estrutura social na cutia  Dasyprocta a. aguti (Rodentia). Pages 296-7 in Congresso Brasileiro de Zoologia, 12,  Campinas, 1985. Resumos. . .Campinas, SBZ/UNICAMP, 1985. (Resumo 614.)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Capybara</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A capybara bibliography, Bibliograf a sobre Chiguires (Hydrochoerus hydrochaeris), is available from E. Gonzalez-Jimenez and JosT Roberto de Alencar Moreira (see Research Contacts for addresses).</P>
+<P ALIGN="JUSTIFY">Aliaga Rodriguez, L. 1979. Produccion de Cuyes. Universidad Nacional del Centro del Peru, Puno.</P>
+<P ALIGN="JUSTIFY">Baldizan, A., R.M. Dixon, and R. Parra. 1983. Digestion in the capybara (Hydrochoerus hydrochaeris). South African Journal of Animal Science 13(1):27-28.</P>
+<P ALIGN="JUSTIFY">Gonzalez-Jimenez, E. 1977a. The capybara, an indigenous source of meat in tropical America. World Animal Review', 21:24-30.</P>
+<P ALIGN="JUSTIFY">Gonzalez-Jimenez, E. 1977b. Digestive physiology and feeding of capybaras. Pages 167177 in Handbook Series in Nutrition and Food. Section G, Diets, Culture Media and Food Supplements, M. Rechcigl, ed. CRC Press, Cleveland, Ohio, USA.</P>
+<P ALIGN="JUSTIFY">Gonzalez-Jimenez, E. and R. Parra. 1975. The capybara, a meat-producing animal for the flooded areas of the tropics. Pages 81-86 in Proceedings of the Third World Conference on Animal Production, R.L. Reid, ed. Sydney University Press.</P>
+<P ALIGN="JUSTIFY">Gonzalez-Jimenez, E. 1984. Capybara. Pages 258-259 in Evolution of Domesticated Animals, I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY">Macdonald, D.W., K. Krantz, and R.T. Aplin. 1984. Behavioural, anatomical and chemical aspects of scent marking amongst Capybaras (Hydrochoerus hydrochaeris) (Rodentia:Caviomorpha). Journal of Zoology (London) 202:341-360.</P>
+<P ALIGN="JUSTIFY">Mones, A. and J. Ojasti. 1986. Hydrochoerus hydrochaeris. Mammalian Species 264: 1-7.</P>
+<P ALIGN="JUSTIFY">Ojasti, J. 1968. Notes on the mating behavior of the capybara. Journal of Mammalogy 49:345-374.</P>
+<P ALIGN="JUSTIFY">Ojasti, J. 1973. Estudio Biologico del Chiguire o Capybara. Fondo Nacional de Investigaciones Agropecuaria, Caracas, Republica de Venezuela. 27 pp.</P>
+<P ALIGN="JUSTIFY">Zara, J.L. 1973. Breeding and husbandry of the capybara at Evansville Zoo. International Zoo Yearbook 13:137-139.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coypu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Christen, M.F. 1978. Evaluacion nutritive de cuatro dietas mono especificas en la alimentacion del coipo (Myocastor coypus Molina 1782). Tesis. Faculty of Veterinary Science, Universidad Austral de Chile, Valdivia, Chile.</P>
+<P ALIGN="JUSTIFY">Deems, E.F., Jr., and D. Pursley. 1978. North American Fur bearers. Maryland Wildlife Administration, Department of Natural Resources, Cheltenham, Maryland, USA. pp. 155.</P>
+<P ALIGN="JUSTIFY">CORFO. n.d. Pieles fieas. Especie coipos. Tomo 1, I! and III. Santiago, Chile.</P>
+<P ALIGN="JUSTIFY">Murua, R., O. Newman, and J. Propelmann. 1981. Food habits of Myocastor coypus (Molina) in Chile. Pages 544-558 in Proceedings of rhe Worldwide Furbearer Conference, J.A. Chapman and D. Pursley, eds. Vol. 1. Worldwide Furbearer Conference, Inc., Frostburg, Maryland, USA.</P>
+<P ALIGN="JUSTIFY">Willner, G.R. 1982. Nutria; Myocastor coypu. Pages 1059-1076 in Wild Mammals of NorthAmerica, J.A. Chapman and G.A. Feldhamer, eds. The John Hopkins University Press, Baltimore, Maryland, USA. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Giant Rat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ajayi, S.S. 1975. Domestication of the African Giant Rat. Department of Forest Resources, University of Ibadan, Ibadan, Nigeria.</P>
+<P ALIGN="JUSTIFY">Faturoti, E.O., O.O. Tewe, and S.S. Ajayi. 1982. Crude fibre tolerance by the African giant rat (Cricetomys gambianus Waterhouse) (Potential sources of protein, Nigeria.) African Journal of Ecology 20(4):289-292.</P>
+<P ALIGN="JUSTIFY">Faturoti, E.O., O.O. Tewe, and S.S. Ajayi. 1983. Effect of varying dietary oil levels on the performance of the African giant rat (Cricetomys gambianus Waterhouse). Nutrition Reports International 27(3):525-530.</P>
+<P ALIGN="JUSTIFY">Den Hartog, A.P. and A. de Vos. 1973. The use of rodents as food in tropical Africa. Nutrition Newsletter (FAO) 11 (2):1-14.</P>
+<P ALIGN="JUSTIFY">Halcrow, J.G. 1958. The giant rat of East Africa. Nature (London) 181:649-650.</P>
+<P ALIGN="JUSTIFY">Matthewman, R.W. 1977. A Survey of Small Livestock Production at the Village Level in the Derived Savanna and Lowland Forest Zones of South West Nigeria. Development Studies 24. Department of Agriculture and Horticulture, University of Reading, UK.</P>
+<P ALIGN="JUSTIFY">Tewe, O.O., S.S. Ajayi, and E.O. Faturoti. 1984. Giant rat and cane rat. Pages 291-293 in Evolution of Domesticated Animals, I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Grasscutter</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Asibey, E.O.A. 1979. Some problems encountered in the field study of the grasscutter (Thryonomys swinderianus) population in Ghana. Pages 214-7 in Wildlife Management in Savannah Woodland, S.S. Ajayi and L. B. Halstead, eds. Cambridge University Press, Cambridge, UK.</P>
+<P ALIGN="JUSTIFY">Baptist, R. and G.A. Mensah. 1986. The Cane-RatFarm animal of the future? [Vorld Animal Review 60:2-6.</P>
+<P ALIGN="JUSTIFY">Matthewman, R.W. 1977. A Survey of Small Livestock Production at the Village Level in the Derived Savanna and Lowland Forest Zones of South West Nigeria. Development Study 24. Department of Agriculture and Horticulture, University of Reading, UK.</P>
+<P ALIGN="JUSTIFY">Pich, S. and K.J. Peters. 1985. Possibilities of using the cane cutter for meat production in Africa. Unpublished manuscript. Copies available from K.J. Peters, Institute of Animal Breeding, Gottingen, Germany.</P>
+<P ALIGN="JUSTIFY">Tewe, O.O., S.S. Ajayi, and E.O. Faturoti. 1984. Giant rat and cane rat. Pages 291-293 in Evolution of Domesticated Animals, I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea Pig</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">"Let's Raise Guinea Pigs," a filmstrip on guinea pig farming, is available from World Neighbors International Headquarters, 5116 North Portland Avenue, Oklahoma City, Oklahoma73112, USA.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Aliaga Rodriguez, L. 1979. Produccion de Cuyes. Universidad Nacional del Centro del Peru, Huancayo, Peru. </P>
+<P ALIGN="JUSTIFY">Aliaga Rodriguez, L. 1983. improvement of Guinea Pig Breeding as a Means of Increasing the Productivity and Production of Meat for Consumption oy the Rural Population in Peru. National University of Central Peru, Huancayo, Peru.</P>
+<P ALIGN="JUSTIFY">Bolton, R. 1979. Guinea pigs, protein, and ritual. Ethnology 18(3):229-252.</P>
+<P ALIGN="JUSTIFY">Huss, D.L. 1982. Small animals for small farms in Latin America. World Animal Ret~iew (FAO) 43:24-29.</P>
+<P ALIGN="JUSTIFY">FAO. 1982. The Guinea Pig and a Hypothetical Development Centre. Small Animals for Small Farms. FAO, Regional Office for Latin America and the Caribbean, Santiago, Chile.</P>
+<P ALIGN="JUSTIFY">Loetz, E. and C. Novoa. 1983. Meat from the guinea pig. Span 26(2):84-86.</P>
+<P ALIGN="JUSTIFY">Muller-Haye, B. 1984. Guinea-pig or cuy. Pages 252-257 in Evolution of Domesticated Animals I.L. Mason, ed. Longman, London.</P>
+<P ALIGN="JUSTIFY">Stansfield, S.K., C.L. Scribner, R.M. Kaminski, T. Cairns, J.B. McCormick, and K.M. Johnson. 1982. Antibody to ebola virus in guinea pigs: Tandala, Zaire. The Journal of Infectious Diseases 146(4):483-486.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hutia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anderson, S., C.A. Woods, G.S. Morgan, and W.L.R. Oliver. 1983. Geocaprornys brownii. Mammalian Species 201:1-5.</P>
+<P ALIGN="JUSTIFY">Canet, R.S. and V. Berovides Alvares. 1984. Ecomorfologia y rendimiento de la jutia conga (Capromys pilorides Say). Poeyana 279:1-19.</P>
+<P ALIGN="JUSTIFY">Canet, R.S. and V. Berovides Alvares. 1984. Reproduccion y ecolog~a de la jutia conga (Capromys pilorides Say). Poeyana 220:1-20.</P>
+<P ALIGN="JUSTIFY">Howe, R., and G.C. Clough. 1971. The Bahamian hutia Geocapromys ingrahami in captivity. international Zoo Yearbook 11:89-93.</P>
+<P ALIGN="JUSTIFY">Johnson, M.L., R.H. Taylor, and N.W. Winnick. 1975. The breeding and exhibition of capromyd rodents at Tacoma Zoo. International Zoo Yearbook 15:53-56.</P>
+<P ALIGN="JUSTIFY">Oliver, W.L.R. 1977. The hutias (Capromyidae) of the West Indies. International Zoo Yearbook 17:14-20.</P>
+<P ALIGN="JUSTIFY">Oliver, W.L.R. 1985. The Jamaican hutia or Indian Coney (Geocapromys brownii). A model programme for captive breeding and reintroduction? Symposium of the Association of British Wild Animal Keepers, 10:35-52. (Copies available from author, see Research Contacts.)</P>
+<P ALIGN="JUSTIFY">Rowlands, I.W., and B.J. Weir, eds. 1974. The Biology of Hystricomorph Rodents. Symposium of the Zoological Society of London, 34:1-482.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mara</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dubost, G. and H. Genest. 1974. Le comportement social d'une colonide mares, Dolichotis patagonum Z. dans le Parc de BranfTrT. Zeitschrift fin Tierpsychologie 35:225-302.</P>
+<P ALIGN="JUSTIFY">Taber, A.B. and D.W. Macdonald. 1984. Scent dispensing papillae and associated behaviour of the mare, Dolichotis patagonum (Rodentia: Caviomorpha). Journal of Zoology (London) 203:298-302. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Paca</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A report summarizing progress in the captive-breeding project in Panama is available from Nicholas Smythe, Smithsonian Tropical Research Institute, Box 2071, Balboa, Panama. A report summarizing preliminary results in the captive-breeding project in Mexico is available from Alfredo D. Cuaron, (see Research Contacts).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Collett, S.F. 1981. Population characteristics of Agouti paca (Rodentia) in Colombia. Michigan State University, Publications of the Museum, Biological Series 5(7): 485-602.</P>
+<P ALIGN="JUSTIFY">Matamoros, Y. 1982. Investigaciones preliminares sobre la reproduccion, comportamiento, alimentacion y manego del tepezcuinte (Cuniculus paca, Brisson) en cautiverio. Pages 961-992 in Zoologia Neotropical, Actas del VIII Congreso Latinoamericano de Zoologia, P.J. Salinas, ed. (Copies available from Y. Matamores, see Research Contacts.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vizcacha</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jackson, J.E. nd. Growth rates in vizcacha (Lagostomus maximus) in San Luis, Argentina. Instituto Nacional de Tecnologia Agropecuaria, San Luis, Argentina. (Copies available from author, see Research Contacts.)</P>
+<P ALIGN="JUSTIFY">Llanos, A.C., and J.A. Crespo. 1952. Ecologia de la vizcacha (Lagostomus maximus maximus Blainv.) en el nordeste de la provincia de Entre Rios. Revista de Investigaciones Agricolas (Buenos Aires) 6:289-378.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other Rodents</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Butynski, T.M. 1973. Lffe history and economic value of the springhare (Pedetes capensis Forster) in Botswana. Botswana Notes Record 5:209-213.</P>
+<P ALIGN="JUSTIFY">Butynski, T.M. 1979. Reproductive ecology of the springhaas Pedetes capensis in Botswana. Journal of Zoology 189:221-232.</P>
+<P ALIGN="JUSTIFY">Butynski, T.M. 1984. Nocturnal ecology of the springhare, Pedetes capensis, in Botswana. African Journal of Ecology 22:7-22.</P>
+<P ALIGN="JUSTIFY">Butynski, T.M. and R. Mattingly. 1979. Burrow structure and fossorial ecology of the springhare Pedetes capensis in Botswana. African Journal of Ecology 17:205-215.</P>
+<P ALIGN="JUSTIFY">Kofron, C.P. 1987. Seasonal reproduction of the springhare, Pedetes capensis, in southeastern Zimbabwe. African Journal of Ecology 25.</P>
+<P ALIGN="JUSTIFY">Rosenthal, M.A., and D.A. Meritt. 1973. Hand-rearing springhaas at Lincoln Park Zoo. International Zoo Yearbook 18:206-208.</P>
+<P ALIGN="JUSTIFY">Smithers, R.H.N. 1983. The Mammals of the Southern African Subregion. University of Pretoria, Pretoria.</P>
+<P ALIGN="JUSTIFY">Velte, F.F. 1978. Hand-rearing springhaas Pedetes capensis at Rochester Zoo. International Zoo Yearbook 18:206-208. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DEER AND ANTELOPE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Deer Farmer, a quarterly magazine, is published by the New Zealand Deer Farmers' Association, P.O. Box 2678, Wellington, New Zealand.</P>
+<P ALIGN="JUSTIFY">Deer Farming is the quarterly magazine of the British Deer Farmers Association (22 Levat Road, Inverness IV2 3NS, Scotland, UK).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chaplin, R.E. 1977. Deer. Blandford Press, Poole, Dorset, UK.</P>
+<P ALIGN="JUSTIFY">Hoffman, R.R. 1985. Digestion and feeding in deer: their morphophysiological adaptation. In Proceedings International Conference on Deer Biology and Production, eds. P.F. Fennessy and K.R. Drew. Royal Society of New Zealand Bulletin 22, Wellington, New Zealand.</P>
+<P ALIGN="JUSTIFY">Fennessy, P.F. and K.R. Drew, eds. 1985. Biology of Deer Production. Proceedings of an international conference held February 13-18, 1983, Dunedin, New Zealand. Royal Society of New Zealand Bulletin 22, Wellington, New Zealand. Available from Royal Society of New Zealand, Private Bag, Wellington, New Zealand.</P>
+<P ALIGN="JUSTIFY">Wemmer C., ed. 1987. The Biology and Management of the Cervidae. Smithsonian Institution Press, Washington, D.C., USA.</P>
+<P ALIGN="JUSTIFY">Yerex, D. 1982. The Farming of Deer. Agricultural Publishing, Box 176, Carterton, New Zealand.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mouse Deer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kay, R.N.B. 1987. The comparative anatomy and physiology of digestion in tragulids and cervids and its relation to food intake. In The Biology and Management of the Cenvidae, C. Wemmer, ed. Smithsonian Institution Press, Washington, D.C.</P>
+<P ALIGN="JUSTIFY">Dubost, G. 1975. Le comportement du chevrotain africain, Hyemoschus aquaticus Ogilby (Artiodactyla, Ruminantia). Zeitschrift fdr Tierpsychologie 37:403-501.</P>
+<P ALIGN="JUSTIFY">Dubost, G. 1978. Un apertu sur l'Tcologie du chevrotain africain, Hyemoschus aquaticus Ogilby, Artiodactyle Tragulide. Mammalia 42:1-62.</P>
+<P ALIGN="JUSTIFY">Ralls, K., C. Barasch, and K. Minkowski. 1975. Behaviour of captive mouse deer, Tragulus napu. Zeitschrift Tierpsychology 37:356-378.</P>
+<P ALIGN="JUSTIFY">Robin, K.P. 1979. Zum Verhalten des Kleinkantschils (Tragulus javanicus). Ph.D. dissertation, University of Zurich. (Copies available from K.P. Robin, see Research Contacts.)</P>
+<P ALIGN="JUSTIFY">Vidyadaran, M.K., M. Hilmi, and R.A. Sirimane. 1982. The gross morphology of the stomach of the Malaysian lesser mousedeer (Tragrrlus javanicus). Pertanika 5(1): 34-38.</P>
+<P ALIGN="JUSTIFY">Vidyadran, M.K., S. Vellayan, and R. Karuppiah. 1983. Muscle weight distribution of the Malaysian lesser mousedeer (Tragulus javanicus). Pertanika 6(2):63-69. </P>
+<P ALIGN="JUSTIFY">Wharton, D.C. 1987. Captive Management of Tragulids at New York Zoological Park. In Biology and Management of the Cervidae, C. Wemmer, ed. Smithsonian Institution Press, Washington, D.C., USA.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muntjac</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anderson, J. 1981. Studies on digestion in Muntiacus reeves). M.Phil. thesis. Cambridge University. </P>
+<P ALIGN="JUSTIFY">Barrette, C. 1977. The social behavior of captive muntjac Muntiacus reeves) (Ogilby  1839). Zeitschrift f-r Tierpsychologie 43: 188-213.</P>
+<P ALIGN="JUSTIFY">Chaplin, R.E. 1977. Deer. Blandford Press, Poole, Dorset, England</P>
+<P ALIGN="JUSTIFY">Chapman, D.I., N.G. Chapman, J.G. Mathews, and D.H. Wurster-Hill. 1983. Chromosome  studies of feral muntjac (Muntiacus sp.) in England. Journal of Zoology, London  201:557-559.</P>
+<P ALIGN="JUSTIFY">Dansie, O. 1970. Muntjac. British Deer Society, Welwyn Garden City, England. 22 pp.</P>
+<P ALIGN="JUSTIFY">Dubost, G. 1970. L'organisation spatiale et sociale de Muntiacus reeves) Ogilby 1839 en  semi-liberte. Mammalia 34:331-355.</P>
+<P ALIGN="JUSTIFY">Dubost, G. 1971. Observations Tthologiques sur le muntjac (Muntiacus muntjak  Zimmermann 1780 et Muntiacus reeves) Ogilby 1839) en captivitT et semi-libertT.  Zeitschrift fdr Tierpsychologie 28:387-427.</P>
+<P ALIGN="JUSTIFY">Jackson, J.E., D.I. Chapman, and O. Dansie. 1977. A note on the food of muntjac deer  (Muntiacus reeves)). Journal of Zoology (London) 183:546-548.</P>
+<P ALIGN="JUSTIFY">Lu Ho-gee and Sheng He-lin. 1984. Status of the black muntjac Muntiacus crinifrons, in  eastern China. Mammal Review 14(1):29-36.</P>
+<P ALIGN="JUSTIFY">Oli, Madan K. 1986. Studies on stereotyped behavior of barking deer (Muntiacus  muntjak). M.S. dissertation, Institute of Science and Technology, Tribhauvan  University, Kathmandu, Nepal. 84 pp.</P>
+<P ALIGN="JUSTIFY">Shi Liming, Ye Yingying, and Duan Xinsheng. 1980. Comparative cytogenetic studies on  the red muntjac, Chinese muntjac, and their Fl hybrids. Cytogenetics and Cell Genetics  26:22-7.</P>
+<P ALIGN="JUSTIFY">Yonzon, Pralad B. 1978. Ecological studies on Muntaicus muntjack. Journal of Natural  History Museum (Nepal) 2(2):91-100.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Musk Deer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anonymous. 1974. Feeding musk deer in captivity and collecting musk from the live  animal. Dongwuxue Zhazi, China 2:11-14.</P>
+<P ALIGN="JUSTIFY">Anonymous. 1975. Preliminary experience in raising the survival rate of musk deer.  Dongwuxue Zhazi, China 1 :17-19.</P>
+<P ALIGN="JUSTIFY">Bannikov, A.G., S.K. Ustinov, and P.N. Lobanov. 1980. The musk deer Moschus  moschiferus in the USSR. International Union for Conservation of Nature and Natural  Resources (IUCN), Gland, Switzerland.</P>
+<P ALIGN="JUSTIFY">Bi, S.Z., Y.H. Yan, Z.X. Qing, P.T. Sheng, Y.M. Wu, C.F. Chen, G.K. Yang, T.B. Yin,  and Y.J. Lu. 1980. Dissection and analysis of the musk gland of M. moschiferus and a  preliminary investigation into its histology. The Protection and Use of Wild Animals  (China) 1: 14-19.</P>
+<P ALIGN="JUSTIFY">Green, M.J.B. 1978. Himalayan musk deer (Moschus moschiferus moschiferus). Pages  56-64 in Threatened Deer. International Union for Conservation of Nature and Natural  Resources (IUCN), Morges, Switzerland.</P>
+<P ALIGN="JUSTIFY">Green, M.J.B. 1985. The musk trade, with particular reference to its impact on the  Himalayan population of Moschus chrysogaster. In Conservation in Developir~g  Countries. Bombay Natural History Society, Bombay.</P>
+<P ALIGN="JUSTIFY">Green, M.J.B. 1985. Aspects of the Ecology of the Himalayan Musk Deer. Ph.D.  dissertation, University of Cambridge, U.K. 280 pp.</P>
+<P ALIGN="JUSTIFY">Groves, C.P. 1978. The taxonomy of Moschus, with particular reference to the Indian  Region. Journal of the Bombay Natural History Society 72:662-676.</P>
+<P ALIGN="JUSTIFY">Holloway, C.W. 1973. Threatened deer of the world: conservation status. Biological  Conservation 5(4).  </P>
+<P ALIGN="JUSTIFY">IUCN. 1974. Red Data Book: Mammalia. International Union for Conservation of Nature and Natural Resources (IUCN), Morges.</P>
+<P ALIGN="JUSTIFY">Jamwal, P.S. 1972. Collection of deer musk in Nepal. Journal of Bombay Natural History Society 69(3):647-649.</P>
+<P ALIGN="JUSTIFY">Seth, S.D., A. Muktiopadtiyay, K. Raghunatham, and R.B. Arora. 1975. Pharmodymamics of Musk. Central Council for Research on Indian Medicine and Homoeopathy, New Delhi, India.</P>
+<P ALIGN="JUSTIFY">Zhang B. 1983. Musk-deer. Their capture, domestication and care according to Chinese experience and methods. Unasylva 35(139):16-24.</P>
+<P ALIGN="JUSTIFY">Zhang, B.L., F.M. Dang, and B.S. Li. 1979. The Farming of Musk Deer. Agricultural Publishing Company, Peking.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water Deer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chaplin, R.E. 1977. Deer. Blandford Press, Poole, Dorset, England.</P>
+<P ALIGN="JUSTIFY">Cooke, A. and L. Farrell. 1983. Chinese water deer (Hydropotes inermis). British Deer Society Publication No. 2. Elvy and Gibbs, Canterbury, UK.</P>
+<P ALIGN="JUSTIFY">Feer, F. 1982. Quelques observations Tthologiques sur l'Hydropote de chine, Hydropotes inennis (Swinhoe, 1870) en captivitT. Zeitschrift fitr Saeugetierkunde 47: 175-185.</P>
+<P ALIGN="JUSTIFY">Sheng Helin and L. Housl. 1984. A preliminary study on the river deer (Hydropotes inermis) population of Shoushau Island (China) and adjacent islets. Acta Theriologica Sinica 4:161-166.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Duikers</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dittrich, L. 1972. Beobachtungen bei der Haltung von Cephalophus-Arten sowie zur Fortpflanzung und Jugendentwicklung von C. dorsalis und C. rufilatus in gefangenschaft. Zoologische Garten Lpz (N.F.) 42:1-16.</P>
+<P ALIGN="JUSTIFY">Dubost, G. 1980. L'Tcologie et la vie sociale du cTphalophe bleu (Cephalophus monticola Thunberg), petit ruminant forestier africain. Zeitschrift fur Tierpsychologie 54: 205-266.</P>
+<P ALIGN="JUSTIFY">Dunbar, R.l.M. and E.P. Dunbar. 1979. Observations on the social organisation of common duiker in Ethiopia. African Journal of Ecology 17:249-252.</P>
+<P ALIGN="JUSTIFY">Dunbar, R.I.M. and E.P. Dunbar. 1980. Animal Behaviour 28:219.</P>
+<P ALIGN="JUSTIFY">Ketelhodt, H.F. Von. 1977. The lambing interval of the blue duiker, Cephalophus monticola Gray in captivity, with observations on its breeding and care. South African Journal of Wildlife Research 7:41-43.</P>
+<P ALIGN="JUSTIFY">Ralls, K. 1975. Agonistic behavior in Maxwell's duiker, Cephalophus max~elli. Marnrnalia 39:241-249.</P>
+<P ALIGN="JUSTIFY">Schweers, S. 1984. The reproductive biology of the banded duiker Cephalophus zebra in comparison with other species of Cephalophus. Zeitschrift fur Saeugetierkunde 49(1):21-36.</P>
+<P ALIGN="JUSTIFY">Whittle, C. and P. Whittle. 1977. Domestication and breeding of Maxwell's duiker. The Nigerian Field 42(4):13-21.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antelope</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Spinage, C.A. 1986. The Natural History of Antelopes. Christopher Helm, UK. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Klipspringer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dunbar, R. and P. Dunbar. 1974. Zeitschrift fur Tierpsychologie 35:481-493.</P>
+<P ALIGN="JUSTIFY">Dunbar, R.I.M. 1979. Energetics, thermoregulation and the behavioural ecology of klipspringer. African Journal of Ecology 17:217-230.</P>
+<P ALIGN="JUSTIFY">Dunbar, R. I . M . and E. P. Dunbar. 1 980 . The pairbond in klipspringer. A nimal Beha vior 28:219-229.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dikdik</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hendricks, H. 1975. Zeitschrift fdr Tierpsychologie 38:55-69.</P>
+<P ALIGN="JUSTIFY">Feer, F. 1979. Observations Tcologiques sur le neotrague de Bates (Neltragus bates) de Winton, 1903, Artiodactyle, ruminant, Bovide) du nord-est du gabon. Terre et vie 33: 159-239.</P>
+<P ALIGN="JUSTIFY">Hoppe, P.P. 1975. Acta Physiol. Scand. 95, 9A.</P>
+<P ALIGN="JUSTIFY">Hoppe, P. P. 1 976 . Tritiated water turnover in Kirk' s dikdik, Madoqua (Rhynchotragus) kirk), Gunther, 1880. Zeischrift far Sadgetierkunde, Mitt. 24:318-319.</P>
+<P ALIGN="JUSTIFY">Hoppe, P.P. 1977. How to survive heat and aridity: ecophysiology of the dikdik antelope. Veterinary Medical Review 1:77-86.</P>
+<P ALIGN="JUSTIFY">Hoppe, P.P. 1977. Comparison of voluntary food and water intake and digestion in Kirk's dik-dik and suni. East African Wildlife Journal 15:41-48.</P>
+<P ALIGN="JUSTIFY">Hoppe, P.P. 1977. Rumen fermentation and body weight in African ruminants. Pages 141-150 in Proceedings 13th International Congress of Game Biologists, T.J. Peterle, ed. Wildlife Society, Washington, D.C., USA.</P>
+<P ALIGN="JUSTIFY">Hoppe, P. 1984. Strategies of digestion in African herbivores. Pages 222-243 in Herbivore Nutrition in the Tropics and Subtropics. F.M.C. Gilchrist and R.I. Machie, eds. The Science Press, South Africa.</P>
+<P ALIGN="JUSTIFY">Hungate, R.E., G.D. Phillips, A. McGregor, D.P. Hungate, and H.K. Buechner. 1959. Microbial fermentation in certain mammals. Science 130:1192-1194.</P>
+<P ALIGN="JUSTIFY">Morat, P. and M. Nording. 1978. Maximum food intake and passage of markers in the alimentary tract of the lesser mouse-deer. Malaysian Applied Biology 7:11-17.</P>
+<P ALIGN="JUSTIFY">Yalden, D.W., M.J. Largen, and D. Kock. 1984. Catalogue of the mammals of Ethiopia. 5. Artiodactyla. Monitore Zoologico Italiano Supplemento 19:67-221.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIZARDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Green Iguana</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Burghardt, G.M. and A.S. Rand, eds. 1982. Iguanas of the World: Behavior, Ecology, and Conservation. Noyes, Park Ridge, New Jersey, USA.</P>
+<P ALIGN="JUSTIFY">Fitch, H.S. and R.W. Henderson. 1977. Age and Sex Differences, Reproduction and Conservation of Iguana iguana. Milwaukee Public Museum Press. Milwaukee, Wisconsin, USA.</P>
+<P ALIGN="JUSTIFY">Hirth, H.F. 1963. Some aspects of the natural history of Iguana iguana on a tropical strand. Ecology 44:613-615.</P>
+<P ALIGN="JUSTIFY">Klein, E.H. 1982. Reproduction of the green iguana (Iguana iguna L.) in the tropical dry forest of southern Honduras. Brenesia 19/20:301-310. </P>
+<P ALIGN="JUSTIFY">Lazell, J.D., Jr. 1973. The lizard genus Iguana in the Lesser Antilles. Bulletin of the Museum of Comparative Zoology, Harvard University 145(1):1-28.</P>
+<P ALIGN="JUSTIFY">Tamsitt, J.R. and D. Valdivieso. 1963. The herpetofauna of the Caribbean Islands San Andres and Providencia. Revista de Biologfa Tropical 11(2): 131- 139. (Copies available from C. LardT, see Research Contacts.)</P>
+<P ALIGN="JUSTIFY">Van Devender, R.W. 1982. Growth and ecology of spiny-tailed and green iguanas in Costa Rica. with comments on the evolution of herbivory and large body size. Pages 162-183 in Iguanas of the World. Behavior, Ecology, and Conservation. Noyes, Park Ridge, New Jersey, USA.</P>
+<P ALIGN="JUSTIFY">Werner, D. and T. Miller. 1984. Artificial nests for female green iguanas. Herpetological Review 15(2):57-58.</P>
+<P ALIGN="JUSTIFY">Werner, D. 1986. Iguana management in Central America. BOSTID Developments 6(1). 4 pp. (Available from BOSTID Publications, HA 476, National Research Council, 2101 Constitution Avenue, N.W., Washington, D.C. 20418.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Black Iguana</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Burghardt, G.M. and A.S. Rand, eds. 1982. Iguanas of the World: Behavior, Ecology, and Conservation. Noyes, Park Ridge, New Jersey, USA.</P>
+<P ALIGN="JUSTIFY">Fitch, H.S. and R.W. Henderson. 1978. Ecology and exploitation of Ctenosaura similis. University of Kansas Science Bulletin 51 :483-500. (Copies available from the authors, see Research Contacts.)</P>
+<P ALIGN="JUSTIFY">Fitch, H.S., R.W. Henderson, and D.M. Hillis. 1982. Exploitation of Iguanas in Central America. In Iguanas of the World: Behavior, Ecology, and Consen~ation. Noyes, Park Ridge, New Jersey, USA.</P>
+<P ALIGN="JUSTIFY">Iverson, J.B. 1979. Behavior and ecology of the rock iguana, Cyclura carinata. Bulletin of the Florida State Museum Biological Science 24(3):175-358.</P>
+<P ALIGN="JUSTIFY">Martinez, M.G. 1986. Habitos alimenticios de iguanas y garrobos. La Prensa Grafica, San Salvador, May 5:55. (Copies available from G. LardT, see Research Contacts.)</P>
+<P ALIGN="JUSTIFY">Sanchez, S.A. 1985. El garrobo. El Diario de Hoy, San Salvador June 18:36. (Copies available from G. LardT, see Research Contacts.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tegu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Donadio, O.K. and J.M. Gallardo. 1984. Biologia y Conservacion de las Especies del GTnero Tupinambis (Squamata, Sauria Teiidae) en la Republica Argentina. Revista del Museo Argentino de Ciencias Naturales 'Bernardino Rivadavia" Zoologia, 13(11):117-127. Agosto.</P>
+<P ALIGN="JUSTIFY">Revision Bibliografica de algunos aspectos de la Biologfa conservacion y explotacion de los lagartos del gTnero topinambis (Daudin, 1803) by Laura Venturino, Dr. Thesis, Universidad de la Republic (Uruguay) 1983).</P>
+<P ALIGN="JUSTIFY">Report to World Wildlife Fund, USA, Biologia y aprovechamiento de una poblacion de Tupinambis references, by Claudio Blanco and Leohor Pessina (1985).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition to the publications listed, many countries run beekeeping programs, and have literature and extension services available based on local experiences. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The International Bee Research Association (IBRA) publishes a Newsletter for Beekeepers in Tropical and Subtropical Countries twice each year. Its purpose is to provide a forum for exchange of information about beekeeping. The Newsletter is funded by the United Kingdom Overseas Development Agency (ODA) and is distributed free of charge to those in developing countries involved with beekeeping. Write to the International Bee Research Association, 18 North Road, Cardiff CFI 3DY, United Kingdom, for subscription information. The IBRA can also provide information on forthcoming conferences, grant programs, and the names of other beekeepers in your country. The International Agency for Apiculture Development (IAAD) publishes a quarterly newsletter called Cornucopia that contains articles from beekeepers around the world, especially from the developing world. It provides information on producing, selling, and manufacturing hive products on a local level and discusses agroforestry and the pest and pesticide problems of honeybees. Write to Cornucopia, c/o M. Coleman, 6N 909 Roosevelt Avenue, St. Charles, Illinois 60174, USA, for a free sample. Subscriptions are $12 a year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Adjare, S. 1984. The Golden Insect: a Handbook on Beekeeping for Beginners. Technology Consultancy Centre, University of Science and Technology, Kumasi, Ghana, in association with Intermediate Technology Publications, Ltd., 9 King Street, Covent Garden, London, WC2 E8HN, UK. 103 pp.</P>
+<P ALIGN="JUSTIFY">Anderson, R.H., B. Buys, and M.F. Johannsmeier. 1983. Beekeeping in South Africa. Department of Agriculture BuHetin No. 394. Pretoria, South Africa. 207 pp.</P>
+<P ALIGN="JUSTIFY">Bradbear, N. and D. De Jong. 1985. The management of africanized honeybees. IBRA Leaflet No. 2. International Bee Research Association (IBRA). Available in English or Spanish from Hill House, Gerrards Cross, Buckinghamshire SL9 ONR, UK. 4 pp.</P>
+<P ALIGN="JUSTIFY">Clauss, B. 1982. A Beekeeping Handbook. Agricultural Information Service, Gaborne, Botswana. 65 pp.</P>
+<P ALIGN="JUSTIFY">Crane, E., P. Walker, and R. Day. 1984. Honey plants of the world. International Bee Research Association, London.</P>
+<P ALIGN="JUSTIFY">FAO. 1984. Proceedings of the expert consultation on beekeeping with Apis mellifera in tropical and sub-tropical Asia. 9-14 April, 1984. FAO Regional Office for Asia and the Tropical Region, Paliwan Mansion, Phra Atit Road, Bangkok, Thailand.</P>
+<P ALIGN="JUSTIFY">Gentry, C. 1984. Small Scale Beekeeping. Manual M-17. Peace Corps, Washington, D.C.</P>
+<P ALIGN="JUSTIFY">IBRC. 1976. Apiculture in Tropical Climates. E. Crane, ed. Full report of the First Conference. International Bee Research Association, London.</P>
+<P ALIGN="JUSTIFY">IBRC. 1982. Proceedings of the Second International Conference on Apiculture in Tropical Climates. New Delhi, 1980. International Bee Research Association, London.</P>
+<P ALIGN="JUSTIFY">IBRC. 1985. Proceedings of the Third international Conference on Apiculture in Tropical Climates. Nairobi, Kenya, November 5-9, 1984. International Bee Research Association, London.</P>
+<P ALIGN="JUSTIFY">IBRC. 1988. Proceedings of the Fourth International Conference on Apiculture in Tropical Climates. Cairo, Egypt, November 1988. International Bee Research Association, London.</P>
+<P ALIGN="JUSTIFY">Kigatiira, K.I. 1974. Hive Designs for Beekeeping in Kenya. Proceedings Entomological Society of Ontario 105:118-128.</P>
+<P ALIGN="JUSTIFY">McGregor, S.E. 1976. Insect Pollination of Cultivated Crop Plants. U.S. Department of Agriculture Handbook No. 496. Government Printing Office, Washington, D.C. 411 pp.</P>
+<P ALIGN="JUSTIFY">Razafindrakoto, C. 1972. Beekeeping in Madagascar. UniversitT Paul-Sabaier de Toulouse, France. 123 pp. </P>
+<P ALIGN="JUSTIFY">Sammataro, D. 1985. Beekeeping in the Philippines. 2nd edition. International Bee Research Association, London.</P>
+<P ALIGN="JUSTIFY">Sammataro, D. and A. Avitabile. 1986. Beekeepers Handbook. 2nd edition. Collier Books' MacMillan Co., New York.</P>
+<P ALIGN="JUSTIFY">Saubolle, B.R, and A. Bachmann. 1979. Beekeeping: an Introduction to Modern Beekeeping in Nepal. Sahayogi Prahashan, Tripureshwar, Kathmandu, Nepal.</P>
+<P ALIGN="JUSTIFY">Silberrad, Roger E.M. n.d. Beekeeping in Zambia. Apimondia. Available through the International Bee Research Association, London.</P>
+<P ALIGN="JUSTIFY">Singh, S. 1964. Beekeeping in India. Silver Jubilee Publication of the Entomological Society of India. Entomological Society of India, New Delhi.</P>
+<P ALIGN="JUSTIFY">Smith, Francis G. 1960. Beekeeping in the Tropics. Western Printing Service, Bristol UK.</P>
+<P ALIGN="JUSTIFY">Townsend, G.F. 1978. Preparation of Honey for Market. Ministry of Agriculture and Food Publication 544. Ministry of Agriculture and Food, Ontario, Canada.</P>
+<P ALIGN="JUSTIFY">Townsend, G.F. 1976. Transitional hives for use with the tropical African bee Apis mellifera adansonii. Pages 181-189 in Apiculture in Tropical Climates. E. Crane, ed. Full report of the First Conference. International Bee Research Association, London. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">B Research Contacts</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">This section includes the names and addresses of individuals and institutions who are familiar with the animal listed. Each person has agreed to answer requests for information and advice. This personal follow-through is the main way this book can stimulate the development of microlivestock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MICROBREEDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microcattle</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">B.K. Ahunu, Animal Science Department, University of Ghana, P.O. Box 25, Legon, Ghana</P>
+<P ALIGN="JUSTIFY">D.O. Alonge, Meat Hygiene and Preservation Laboratory, Faculty of Veterinary Medicine, University of Ibadan, Ibadan, Nigeria</P>
+<P ALIGN="JUSTIFY">M. Andres Poli, EEA San Luis INTA, CC 17, 5730 Mercedes (SL), Argentina</P>
+<P ALIGN="JUSTIFY">F.B. Bareeba, Department of Animal Science, Makerere University, P.O. Box 7062, Kampala, Uganda</P>
+<P ALIGN="JUSTIFY">J.A. Bennett, Department of Animal, Dairy, and Veterinary Sciences, Utah State University, Logan, Utah 84322-4815, USA</P>
+<P ALIGN="JUSTIFY">J.M. Berruecos V., School of Veterinary Medicine and Zoology, Universidad Nacional Aut6noma de MTxico, Ciudad Universitaria, Alvaro Obreg6n, 04510, Mexico D.F., Mexico</P>
+<P ALIGN="JUSTIFY">Cai Li, Animal Science and Veterinary Research Institute, Southwest College of Minority Nationalities, Chengdu, People's Republic of China</P>
+<P ALIGN="JUSTIFY">Centro de Investigaciones Pecuarias (CENIP), A.P. 227-9, Santo Domingo, Dominican Republic</P>
+<P ALIGN="JUSTIFY">G.L. Chan, B4-5 Nanyang Mansion, Shenzhen, Guangdong, People's Republic of China</P>
+<P ALIGN="JUSTIFY">Y. Cheneau, Institut d'Elevage et de MTdecine VTtTrinaire des Pays Tropicaux, Laboratoire de Farcha, BP 433, N'Djamena, Chad</P>
+<P ALIGN="JUSTIFY">Cheng Peilieu, Institute of Animal Science, Chinese Academy of Sciences, Beijing, People's Republic of China</P>
+<P ALIGN="JUSTIFY">W.R. Cockrill, 29 Downs Park West, Bristol BS6 7QH, UK</P>
+<P ALIGN="JUSTIFY">J.H. Conrad, Department of Animal Science, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">T.J. Cunha, P.O. Box R, La Verne, California 91750, USA</P>
+<P ALIGN="JUSTIFY">D.E. Deppner, Trees for the Future, 11306 Estona Drive, Silver Spring, Maryland 20902, USA (breeds of the Himalayas, East Indies)</P>
+<P ALIGN="JUSTIFY">C. Devendra, Agriculture Food and Nutrition Sciences Division, International Development Research Centre (IDRC), Tanglin P.O. Box 101, 9124 Singapore</P>
+<P ALIGN="JUSTIFY">N.l. Dim, Department of Animal Science, Faculty of Agriculture, Institute for Agricultural Research, Ahmadu Bello University, P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">Director, Agriculture and Forestry, PB 13184, Windhoek 9000, Namibia</P>
+<P ALIGN="JUSTIFY">V.M.S. Duarte, Instituto de Investigatao Veterinaria, C.P. 7, Huambo, Angola</P>
+<P ALIGN="JUSTIFY">M. Felius, Kerkhoflaan 47C, 3034 TA Rotterdam, The Netherlands</P>
+<P ALIGN="JUSTIFY">D. Fleharty, American Dexter Cattle Association, R.R. #1, Box 378, Concordia, Missouri 64020. USA </P>
+<P ALIGN="JUSTIFY">G. Garcia Lagombra, Animal Husbandry Department, Universidad Nacional "Pedro Henriquez Urena," Decanato Ciencias Agropecuarias, Km 5~/z Aut. Duarte, Santo Domingo, Dominican Republic</P>
+<P ALIGN="JUSTIFY">F. Gebreab, College of Veterinary Science, Addis Ababa University, Addis Ababa, Ethiopia</P>
+<P ALIGN="JUSTIFY">G.F.W. Haenlein, Department of Animal Science and Agricultural Biochemistry University of Delaware, Newark, Delaware 19717-1303, USA</P>
+<P ALIGN="JUSTIFY">Z.B. Jensen, Animal and Dairy Science Research Institute, PB X02, Irene, Transvaal 1675, South Africa</P>
+<P ALIGN="JUSTIFY">Jin Xizhen, Animal Science and Veterinary Research Institute, Southwest College of Minority Nationalities, Chengdu, People's Republic of China</P>
+<P ALIGN="JUSTIFY">G. Kitsopanidis, Faculty of Agriculture, Aristotelian University of Thessaloniki, University Campus, Thessaloniki, Greece</P>
+<P ALIGN="JUSTIFY">G.E. Kodituwakku, Department of Veterinary Clinical Studies, University of Peradeniya, Peradeniya, Sri Lanka</P>
+<P ALIGN="JUSTIFY">N.M. Konnerup, 74 North Sunrise Boulevard, Camano Island, Washington 98292, USA</P>
+<P ALIGN="JUSTIFY">L.Y.L. Li, Department of Animal Husbandry and Veterinary Science, South China Agricultural College, Ghangzhou, People's Republic of China</P>
+<P ALIGN="JUSTIFY">J.K. Loosli, 406 S.W. 40th Street, Gainesville, Florida 32607, USA</P>
+<P ALIGN="JUSTIFY">A.B. Lwoga, Sokoine University of Agriculture, P.O. Box 3000, Morogoro, Tanzania</P>
+<P ALIGN="JUSTIFY">A. Martinez Balboa, Legaspy 1025, Apartado Postal 43, 23000, La Paz, Baja California Sur, Mexico</P>
+<P ALIGN="JUSTIFY">A. Masam, Livestock Training Institute, Tengeru, P.O. Box 3101, Arusha, Tanzania</P>
+<P ALIGN="JUSTIFY">J.P. Maule, Hannahfield Quarry House, 578 Lanark Road West, Balerno, Midlothian EH 14 7BN, UK</P>
+<P ALIGN="JUSTIFY">M. Mazid, Faculty of Agriculture, University of Aleppo, Aleppo, Syria</P>
+<P ALIGN="JUSTIFY">L.R. McDowell, Department of Animal Sciences, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">J.A. Morgan, College of Natural Resources and Environmental Studies, University of Juba, P.O. Box 82, Juba, Sudan</P>
+<P ALIGN="JUSTIFY">D.B. Mpiri, Livestock Production Research Institute, Private Bag, Mpwapwa, Tanzania</P>
+<P ALIGN="JUSTIFY">Ni Shicheng, Animal Husbandry and Veterinary Science, Zhejiang Agricultural University, Hangzhou, People's Republic of China</P>
+<P ALIGN="JUSTIFY">B. Nikolov, Institute of Cattle and Sheep Breeding, 6000 Stara Zagora, Bulgaria</P>
+<P ALIGN="JUSTIFY">T. Olson, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">T.W. Perry, Department of Animal Sciences, Purdue University, West Lafayette, Indiana 47907, USA</P>
+<P ALIGN="JUSTIFY">R.W. Phillips, The Representative, Apartment 810, 1101 South Arlington Ridge Road, Arlington, Virginia 22202, USA</P>
+<P ALIGN="JUSTIFY">F. Pirchner, Technical University of Munich, D-8050 Munich-Weihenstephan, Germany</P>
+<P ALIGN="JUSTIFY">A. Ramamohana Rao, Postgraduate Studies, Andhra Pradesh Agricultural University, Rajendranagar, Hyderabad, Andhra Pradesh 500 030, India</P>
+<P ALIGN="JUSTIFY">Soedomo Reksohadiprodjo, Department of Animai Nutrition, Faculty of Animal Husbandry, Universitas Gadjah Mada, Sekip Blok N-42, Yogyakarta, Indonesia</P>
+<P ALIGN="JUSTIFY">A.Y. Robles, Dairy Training and Research Institute, University of the Philippines at Los Banos, College, Laguna 3732, Philippines</P>
+<P ALIGN="JUSTIFY">Sie Cheuxia, Department of Animal Science, Nanjing Agricultural University, Nanjing, People's Republic of China</P>
+<P ALIGN="JUSTIFY">A.D. Tillman, 523 West Harned Place, Stillwater, Oklahoma 74074, USA</P>
+<P ALIGN="JUSTIFY">J.C.M. Trail, Livestock Productivity and Trypanotolerance Group, International Livestock Centre for Africa (ILCA), P.O. Box 30709, Nairobi, Kenya</P>
+<P ALIGN="JUSTIFY">A.C. Warnick, Department of Animal Science, University of Florida, Gainesville, Florida 32611, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microgoat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">E.A. Adebowale, Institute of Agricultural Research and Training, University of Ife, Moor Plantation, P.M.B. 5029, Ibadan, Nigeria</P>
+<P ALIGN="JUSTIFY">A.A. Adeloye, Faculty of Agriculture, Adeyemi College of Education, Onjo, Nigeria</P>
+<P ALIGN="JUSTIFY">A.A. Ademosun, Department of Animal Science, University of Ife, lle-Ife, Nigeria</P>
+<P ALIGN="JUSTIFY">I.F. Adu, N.A.P.R.I., Ahmadu Bello University, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">I.A. Akinbode, Faculty of Agriculture, University of Ife, Ile-Ife, Nigeria</P>
+<P ALIGN="JUSTIFY">A.O. Akinsoyinu, Department of Animal Science, University of Ibadan, Ibadan, Nigeria</P>
+<P ALIGN="JUSTIFY">J.A. Akonji, Institut de Recherches Zootechniques, Office National de la Recherche Scientifique et Technique (ONAREST), B.P. 65, Yaounde, Cameroon</P>
+<P ALIGN="JUSTIFY">D.O. Alonge, Faculty of Veterinary Medicine, University of Ibadan, Ibadan, Nigeria</P>
+<P ALIGN="JUSTIFY">Baik Dong Hoon, Department of Animal Science, College of Agriculture, Jeonbug National University, JEONJU, 520, Republic of Korea</P>
+<P ALIGN="JUSTIFY">J.S.F. Barker, Department of Animal Science, University of New England, Armidale, New South Wales 2351, Australia</P>
+<P ALIGN="JUSTIFY">K. Boateng, Cooperative Extension Service, University of the Virgin Islands, Box L, Kingshill, St. Croix, Virgin Islands 00850, USA</P>
+<P ALIGN="JUSTIFY">G.E. Bradford, University of California, Davis, California 95616, USA</P>
+<P ALIGN="JUSTIFY">M.S. Browne, Nutrition Consulting Services, P.O. Box 788, St. Thomas, Virgin Islands 00801, USA</P>
+<P ALIGN="JUSTIFY">T.D. Bunch, Department of Animal, Dairy, and Veterinary Sciences, Utah State University, Logan, Utah 84322-4815, USA</P>
+<P ALIGN="JUSTIFY">T.C. Cartwright, Department of Animal Science, Texas A&amp;M University, College Station, Texas 77843, USA</P>
+<P ALIGN="JUSTIFY">Centro de Investigaciones Pecuarias (CENIP), A.P. 227-9, Santo Domingo, Dominican Republic</P>
+<P ALIGN="JUSTIFY">C. Devendra, Agriculture Food and Nutrition Sciences Division, International Development Research Centre (IDRC), Tanglin P.O. Box 101, 9124 Singapore, Singapore</P>
+<P ALIGN="JUSTIFY">N.I. Dim, Department of Animal Science, Faculty of Agriculture, Institute for Agricultural Research, Ahmadu Bello University, P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">D. Fielding, Centre for Tropical Veterinary Medicine, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Easter Bush, Roslin, Midlothian EH25 9RG, Scotland, UK</P>
+<P ALIGN="JUSTIFY">H.A. Fitzhugh, Winrock International, Route 3, Petit Jean Mountain, Morrilton, Arkansas 72110, USA</P>
+<P ALIGN="JUSTIFY">W.C. Foote, Utah State University International Sheep and Goat Institute, UNC 48, Utah State University, Logan, Utah 84322, USA</P>
+<P ALIGN="JUSTIFY">G.R. Gerona, Department of Animal Science and Veterinary Medicine, Visayas State College of Agriculture, Baybay, Leyte, Philippines</P>
+<P ALIGN="JUSTIFY">G.F.W. Haenlein, Department of Animal Science and Agricultural Biochemistry, University of Delaware, Newark, Delaware 19717-1303, USA</P>
+<P ALIGN="JUSTIFY">A. Essa Haid, Essa International, Inc., 2550 M Street, Suite 405, Washington, D.C. 20037, USA (small East African)</P>
+<P ALIGN="JUSTIFY">W. Harding, Agrarian Society, Palazzo de la Salle, Valletta, Malta</P>
+<P ALIGN="JUSTIFY">M.A. Hasnath, Department of Animal Husbandry, Bangladesh Agricultural University, P.O. Agricultural University, Mymensingh, Bangladesh</P>
+<P ALIGN="JUSTIFY">A.S. Hoversland, Division of Research Grants, National Institutes of Health, 5333 Westbard Avenue, Bethesda, Maryland 20205, USA</P>
+<P ALIGN="JUSTIFY">L. Hulse, National Pygmy Goat Association, RFD #1, Fern Avenue, Amesbury, Massachusetts 01913, USA</P>
+<P ALIGN="JUSTIFY">T.P. Husband, Department of Natural Resource Science, University of Rhode Island, Kingston, Rhode Island 02881, USA (bezoar, agrimi) </P>
+<P ALIGN="JUSTIFY">D.L. Huss, P.O. Box 426, Menard, Texas 76859, USA</P>
+<P ALIGN="JUSTIFY">B. Hutchins, 2535 Halsted Road, Apartment 1, Rockford, Illinois 61103, USA</P>
+<P ALIGN="JUSTIFY">N. Iba+ez Herrera, Paraguay 160-Urbanizacion, Apartado 315, El Recreo, Trujillo, Peru</P>
+<P ALIGN="JUSTIFY">S. Karam Shah, Livestock Experimental Station Rakh Khairewala, District Muzaffergarh, Pakistan</P>
+<P ALIGN="JUSTIFY">C. Katongole, Faculty of Veterinary Medicine, Makerere University, PO Box 7062, Kampala, Uganda</P>
+<P ALIGN="JUSTIFY">G. Kiwuwa, Department of Animal Science, Makerere University, PO Box 7062, Kampala, Uganda</P>
+<P ALIGN="JUSTIFY">L.Y.L. Li, Department of Animal Husbandry and Veterinary Science, South China Agricultural College, Ghangzhou, People's Republic of China</P>
+<P ALIGN="JUSTIFY">D.R. Lincicome, Animal Parasitology Institute, U.S. Department of Agric£lture, Building 1180, BARC-East, Beltsville, Maryland 20705, USA</P>
+<P ALIGN="JUSTIFY">Liu Chengxiang, Animal Husbandry and Veterinary Science Research Institute, Guang^ dong Agricultural Academy, Guangdong, People's Republic of China</P>
+<P ALIGN="JUSTIFY">J.K. Loosli, 406 S.W. 40th Street, Gainesville, Florida 32607, USA</P>
+<P ALIGN="JUSTIFY">M. Mahyuddin Dahan, Department of Animal Sciences, Universiti Pertanian Malaysia, Serdang, Selangor, Malaysia</P>
+<P ALIGN="JUSTIFY">G.C.H. Mandari, Livestock Research Centre, West Kilimanjaro, P.O. Box 103, Hai, Tanzania</P>
+<P ALIGN="JUSTIFY">J. Mann, Institute of Tropical Veterinary Medicine, University of Giessen, Germany</P>
+<P ALIGN="JUSTIFY">A. Martinez Balboa, Legaspy 1025, Apartado Postal 43, 23000, La Paz, Baja California Sur, Mexico</P>
+<P ALIGN="JUSTIFY">I. Mecha, Department of Animal Science, University of Nigeria, Nsukka, Anambra State, Nigeria</P>
+<P ALIGN="JUSTIFY">J. Metcalf, School of Medicine, University of Oregon, Eugene, Oregon 97403, USA</P>
+<P ALIGN="JUSTIFY">K. Mitchell, Baptist Bible Institute, P.O. Box 301, Basseterre, St. Kitts, West Indies</P>
+<P ALIGN="JUSTIFY">M. Khusahry Mohd Yusuff, Malaysian Agricultural and Research Institute (MARDI), G.P.O. Box 12301, Kuala Lumpur 01-02, Malaysia</P>
+<P ALIGN="JUSTIFY">A. Monsi, Departments of Animal Science/Food Science and Technology, Rivers State University of Science and Technology, P.M.B. 5080, Port Harcourt, Nigeria</P>
+<P ALIGN="JUSTIFY">G. Montsma, Klomperweg 79, 6741 PD, Lunteren, Netherlands</P>
+<P ALIGN="JUSTIFY">J. Moore, Department of Animal Science, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">C.M. Munyabuntu, Department of Animal Science, P.O. Box 7062, Makerere University' Kampala, Uganda</P>
+<P ALIGN="JUSTIFY">Th. Murayi, Institut des Sciences Agronomiques du Rwanda, P.O. Box 138, Butare, Rwanda</P>
+<P ALIGN="JUSTIFY">W.N.M. Mwenya, School of Agricultural Sciences, University of Zambia, Box 32379, Lusaka, Zambia</P>
+<P ALIGN="JUSTIFY">A. Nivyobizi, FacultT des Sciences Agronomiques, UniversitT du Burundi, BP 2940, Bujumbura, Burundi</P>
+<P ALIGN="JUSTIFY">G.A. Norman, Tropical Development Research Institute, 56/62 Gray's Inn Road, London WCIX 8LU, UK</P>
+<P ALIGN="JUSTIFY">K. Okello-Lapenga, Department of Veterinary Pathobiology, Makerere University, PO Box 7062, Kampala, Uganda</P>
+<P ALIGN="JUSTIFY">S. Ramahefarison, DTpartement de Recherches Zootechniques et VTtTrinaires tCENRADERU), BP 904, Amatobe, Antananarivo, Madagascar</P>
+<P ALIGN="JUSTIFY">A. Ramamohana Rao, Postgraduate Studies, Andhra Pradesh Agricultural University, Rajendranagar, Hyderabad, Andhra Pradesh 500 030, India</P>
+<P ALIGN="JUSTIFY">R.K. Rastogi, Department of Livestock Science, University of the West Indies, St. Augustine, Trinidad, West Indies </P>
+<P ALIGN="JUSTIFY">G. Rasul, District Forest Officer &amp; Wildlffe Warden, P.O. Box 501, Gilgit (northern area), Pakistan</P>
+<P ALIGN="JUSTIFY">D. Rattner, Institute of Animal Research, Kibbutz Lahav, Israel (Sinai goat, ya-ez hybrids)</P>
+<P ALIGN="JUSTIFY">Soedomo Reksohadiprodjo, Department of Animal Nutrition, Faculty of Animal Husbandry, Universitas Gadjah Mada, Sekip Blok N-42, Yogyakarta, Indonesia</P>
+<P ALIGN="JUSTIFY">A. Repollo, Jr., Palawan National Agricultural College, Aborlan, Palawan, Philippines</P>
+<P ALIGN="JUSTIFY">A.Y. Robles, Dairy Training and Research Institute, University of the Pbilippines, Los Banos, Laguna 3732, Philippines</P>
+<P ALIGN="JUSTIFY">A. Rocha, Instituto de Reprodutao e Melhoramento Animal, C.P. 25, Matola, Mozambique</P>
+<P ALIGN="JUSTIFY">C. Rodriguez, Centro de Investigaciones Pecuarias (CENIP), Autopista Duarte Km 24, Apartado 227-9, Santo Domingo, Dominican Republic</P>
+<P ALIGN="JUSTIFY">M. Nasim Siddiqi, Zoology Department, University of Peshawar, N.W.F.P., Pakistan</P>
+<P ALIGN="JUSTIFY">M. Shelton, Texas A &amp; M University, College Station, Texas 77843, USA (criollo)</P>
+<P ALIGN="JUSTIFY">A. Shkolnik, Department of Zoology, Tel Aviv University, Tel Aviv, Israel</P>
+<P ALIGN="JUSTIFY">O.C. Simpson, Cameroon Road, Prairie View A&amp;M University, Prairie View, Texas 77445, USA</P>
+<P ALIGN="JUSTIFY">Sie Chenxia, Department of Animal Science, Nanjing Agricultural University, Nanjing, People's Republic of Cbina</P>
+<P ALIGN="JUSTIFY">R.G. Wahome, Department of Animal Production, University of Nairobi, P.O. Box 29053, Nairobi, Kenya</P>
+<P ALIGN="JUSTIFY">R. Watts, Animal Science Department, Natural Resources Development College, Lusaka, Zambia</P>
+<P ALIGN="JUSTIFY">R.T. Wilson, Bartridge House, Umberleigh, North Devon EX37 9AS, UK</P>
+<P ALIGN="JUSTIFY">H. Wood, Highland Game Farm, Route 4, Box 450, Alexandria, Indiana 46001, USA</P>
+<P ALIGN="JUSTIFY">T.P. Husband, Department of Natural Resources Science, University of Rhode Island, Kingston, Rhode Island 02881, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Microsheep</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">E.A. Adebowale, Institute of Agricultural Research and Training, University of Ife, Moor Plantation, P.M.B. 5029, Ibadan, Nigeria</P>
+<P ALIGN="JUSTIFY">I.F. Adu, N.A.P.R.I., Ahmadu Bello University, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">I.A. Akinbode, Faculty of Agriculture, University of Ife, Ile-Ife, Nigeria</P>
+<P ALIGN="JUSTIFY">A.O. Akinsoyinu, Department of Animal Science, University of Ibadan, Ibadan, Nigeria</P>
+<P ALIGN="JUSTIFY">M. Amin, Jammu and Kashmis State Sheep and Shearing Products Development Board, Nowshera, Srinigar, Kashmir 190 011, India</P>
+<P ALIGN="JUSTIFY">Ahmad Mustaffa B. HJ. Babjee, Veterinary Services Department, Ibu Pejabat Perkhidmatan Haiwan, Kementerian Pertanian, Malaysia, Jalan Mahameru, Kuala Lumpur 10-02, Malaysia (grazing in rubber plantations)</P>
+<P ALIGN="JUSTIFY">J.S.F. Barker, Department of Animal Science, University of New England, Armidale, New South Wales, 2351, Australia (Indonesian breeds)</P>
+<P ALIGN="JUSTIFY">K. Boateng, Cooperative Extension Service, College of the Virgin Islands, Box L, Kingshill, St. Croix, Virgin Islands 00850, USA</P>
+<P ALIGN="JUSTIFY">G.E. Bradford, University of Calffornia, Davis, Calffornia 95616, USA</P>
+<P ALIGN="JUSTIFY">R. Breckle, U.S. Forest Service, Alsea, Oregon 97324, USA (grazing sheep in forests)</P>
+<P ALIGN="JUSTIFY">T. Bunch, Department of Animal, Dairy, and Veterinary Sciences, Utah State University, Logan, Utah 84322-4815, USA (Iranian thin-tailed, Navajo, wild-sheep hybrids)</P>
+<P ALIGN="JUSTIFY">M. Carpio P., Departamento de Produccion Animal, Universidad Nacional Agraria, Apartado 456, La Molina, Lima, Peru </P>
+<P ALIGN="JUSTIFY">Centro de Investigaciones Pecuarias (CENIP), A.P. 227-9, Santo Domingo, Dominican Republic</P>
+<P ALIGN="JUSTIFY">S. Cottrell, Pippin Farm, 3081 Goshen Road, Bellingham, Washington 98226, USA</P>
+<P ALIGN="JUSTIFY">C. Courtney, Veterinary Faculty, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">D. Deller, Virgin Islands Department of Agriculture, St. Thomas, Virgin Islands 00820, USA</P>
+<P ALIGN="JUSTIFY">A. Dettmers, 5620 Longwood Avenue, Port Charlotte, Florida 33953, USA (West African dwarf)</P>
+<P ALIGN="JUSTIFY">C. Devendra, Agricultural Food and Nutrition Sciences Division International Development Research Centre (IDRC), Tanglin P.O. Box 101, 9124 Singapore, Singapore</P>
+<P ALIGN="JUSTIFY">N.l. Dim, Department of Animal Science, Faculty of Agriculture, Institute for Agricultural Research, Ahmadu Bello University, P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">K. Drew, Invermay Agricultural Research Centre, Private Bag, Mosgiel, New Zealand</P>
+<P ALIGN="JUSTIFY">F. El Amin, Department of Animal Husandry, Faculty of Veterinary Science, University of Khartoum, P.O. Box 32, Khartoum North, Sudan</P>
+<P ALIGN="JUSTIFY">Gholam-Hossein Erabi, Faculty of Agriculture, University of Tabriz, Tabriz 51664, Iran</P>
+<P ALIGN="JUSTIFY">H.A. Fitzhugh, Winrock International Institute for Agricultural Development, Route 3, Petit Jean Mountain, Morrilton, Arkansas 72110, USA</P>
+<P ALIGN="JUSTIFY">W. Foote, Animal' Dairy, and Veterinary Science Department, UNC 48, Utah State University, Logan, Utah 84322-4815, USA (Virgin Islands white hair, wild-sheep hybrids)</P>
+<P ALIGN="JUSTIFY">E.-H. Gueye, Centre de Recherches Zootechniques de Kolda, Institut SenTgalais de Recherches Agricoles, (ISRA), B.P. 53, Kolda, Senegal</P>
+<P ALIGN="JUSTIFY">G. Garcia Lagombra, Animal Husbandry Department, Universidad Nacional "Pedro Henriquez Urena," Decanato Ciencias Agropecuarias, Km 5 1/2 Aut. Duarte, Santo Domingo, Dominican Republic</P>
+<P ALIGN="JUSTIFY">G.F.W. Haenlein, Department of Animal Science and Agricultural Biochemistry, University of Delaware, Newark, Delaware 19717-1303, USA</P>
+<P ALIGN="JUSTIFY">E. Henson, Bemborough, Guiting Power, Cheltenham, Gloucester, UK (rare breeds)</P>
+<P ALIGN="JUSTIFY">D.L. Huss, P.O. Box 426, Menard, Texas 76859, USA</P>
+<P ALIGN="JUSTIFY">N. Ibanez Herrera, Paraguay 160 - Urbanizacion, Apartado 315, El Recreo, Trujillo, Peru</P>
+<P ALIGN="JUSTIFY">P. Jewell, Department of Physiology, University of Cambridge, Cambridge CB2 ITN, UK</P>
+<P ALIGN="JUSTIFY">Jones Sheep Farm, RR 2 Box 185-55, Peabody, Kansas 66866, USA</P>
+<P ALIGN="JUSTIFY">P.E. Loggins, Animal Science Department, 108-D Suite, University of Florida, Gainesville, Florida32611, USA</P>
+<P ALIGN="JUSTIFY">J.K. Loosli, 406 S.W. 40th Street, Gainesville, Florida 32607, USA</P>
+<P ALIGN="JUSTIFY">G.C.H. Mandari, Livestock Research Centre, West Kilimanjaro, P.O. Box 103, Hai, Tanzania</P>
+<P ALIGN="JUSTIFY">J.P. Maule, Hannahfield Quarry House, 578 Lanark Road West, Balerno, Midlothian EH14 7BN, UK</P>
+<P ALIGN="JUSTIFY">L.K. McNeal, Animal, Dairy, and Veterinary Science Department, UNC 48, Utah State University, Logan, Utah 84322-4815, USA</P>
+<P ALIGN="JUSTIFY">I. Mecha, Department of Animal Science, University of Nigeria, Nsukka, Anambra State, Nigeria</P>
+<P ALIGN="JUSTIFY">K. Mitchell, Baptist Bible Institute, P.O. Box 301, Basseterre, St. Kitts, West Indies</P>
+<P ALIGN="JUSTIFY">A. Monsi, Department of Animal Science, Food Science and Technology, Rivers State University of Science and Technology, P.M.B. 5080, Port Harcourt, Nigeria</P>
+<P ALIGN="JUSTIFY">C.M. Munyabuntu, Department of Animal Science, Makerere University, P.O. Box 7062, Kampala, Uganda </P>
+<P ALIGN="JUSTIFY">Th. Murayi, Institut des Sciences Agronomiques du Rwanda, P.O. Box 138, Butare, Rwanda</P>
+<P ALIGN="JUSTIFY">W.N.M. Mwenya, School of Agriculture Sciences, University of Zambia, Box 32379, Lusaka,  Zambia</P>
+<P ALIGN="JUSTIFY">M. Ngendahayo, Institut des Sciences Agronomiques du Rwanda, B.P. 138, Butare, Rwanda</P>
+<P ALIGN="JUSTIFY">R. Njwe, DTpartement des Sciences Animales, Ecole Nationale SupTrieure Agronomique, Centre  Universitaire de Dschang, B.P. 138, YaoundT, United Republic of Cameroon</P>
+<P ALIGN="JUSTIFY">W.J.A. Payne, 91 Bedwardine Road, London SE19 3AY, UK</P>
+<P ALIGN="JUSTIFY">R.W. Phillips, The Representative, Apartment 810, 1101 South Arlington Ridge Road, Arlington,  Virginia 22202, USA</P>
+<P ALIGN="JUSTIFY">G.V. Raghavan, Animal Science Department, College of Veterinary Science, Andhra Pradesh  Agricultural University, Rajendranagar, Hyderabad 500 030, Andhra Pradesh, India</P>
+<P ALIGN="JUSTIFY">A. Ramamohana Rao, Postgraduate Studies, Andhra Pradesh Agricultural University,  Rajendranagar, Hyderabad, Andhra Pradesh 500 030, India</P>
+<P ALIGN="JUSTIFY">R.K. Rastogi, Department of Livestock Science, University of the West Indies, St. Augustine,  Trinidad, West Indies</P>
+<P ALIGN="JUSTIFY">Soedomo Reksohadiprodjo, Department of Animal Nutrition, Faculty of Animal Husbandry,  Universitas Gadjah Mada, Sekip Blok N-42, Yogyakarta, Indonesia</P>
+<P ALIGN="JUSTIFY">A.Y. Robles, Dairy Training and Research Institute, University of the Philippines at Los Banos,  College, Laguna 3732, Philippines</P>
+<P ALIGN="JUSTIFY">A. Rocha, Instituto de Reprodutao e Melhoramento Animal, C.P. 25, Matola, Mozambique</P>
+<P ALIGN="JUSTIFY">M.L. Ryder, c/o H.F.R.O., Bush Estate, Penicuik, Edinburgh, UK (Barbados blackbelly, wool)</P>
+<P ALIGN="JUSTIFY">Sie Chenxia, Department of Animal Science, Nanjing Agricultural University, Nanjing, People's  Republic of China</P>
+<P ALIGN="JUSTIFY">C. David Simpson, Range and Wildlife Department, Texas Tech University, P.O. Box 4349,  Lubbock, Texas 79409, USA</P>
+<P ALIGN="JUSTIFY">C.E. Terrill, U.S. Department of Agriculture, Building 005, BARC-West, Beltsville, Maryland 20705,  USA</P>
+<P ALIGN="JUSTIFY">H.N. Turner, Genetics Research Laboratories, CSIRO, P.O. Box 184, North Ryde, New South  Wales 2113, Australia (Indonesian breeds)</P>
+<P ALIGN="JUSTIFY">R. Vaccaro, Universidad Nacional Agraria, La Molina, P.O. Box 456, Lima, Peru</P>
+<P ALIGN="JUSTIFY">R.G. Wahome, Department of Animal Production, P.O. Box 29053, Nairobi, Kenya</P>
+<P ALIGN="JUSTIFY">S. Wildeus, College of the Virgin Islands, Agricultural Experiment Station, R.R. 2, Box 10051  Kingshill, St. Croix, Virgin Islands 00850, USA</P>
+<P ALIGN="JUSTIFY">R.T. Wilson, Bartridge House, Umberleigh, North Devon EX37 9AS, UK</P>
+<P ALIGN="JUSTIFY">Wu Jitang, Animal and Veterinary Science, Jiangsu Province Academy of Agricultural Sciences,  Nanjing, People's Republic of China</P>
+<P ALIGN="JUSTIFY">A. Yenikoye, FacultT d'Agronomie, UniversitT de Niamey, B.P. 10662, Niamey, Niger</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Micropig</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I.A. Akinbode, Faculty of Agriculture, University of Ife, Ile-Ife, Nigeria</P>
+<P ALIGN="JUSTIFY">D.O. Alonge, Meat Hygiene and Preservation Laboratory, Faculty of Veterinary Medicine,  University of Ibadan, Ibadan, Nigeria  </P>
+<P ALIGN="JUSTIFY">J.M. Andrews, Mesoamerican Ecology Institute, Tulane University, New Orleans, Louisiana 70118, USA (Yucatan pig)</P>
+<P ALIGN="JUSTIFY">G. Ashton-Peach, Box 17, Ohaeawai, Bay of Islands, New Zealand (kunekune)</P>
+<P ALIGN="JUSTIFY">M. Berruecos V. Muz, Facultad de Medicina Veterinaria y Zootecnia, Ciudad Universitaria, Mexico D.F., Mexico</P>
+<P ALIGN="JUSTIFY">R. Blakely, Sedgwick County Zoo, Wichita, Kansas 67203, USA (Ossabaw)</P>
+<P ALIGN="JUSTIFY">K. Boateng, Cooperative Extension Service, University of the Virgin Islands, Box L., Kingshill, St. Croix, Virgin Islands 00850, USA</P>
+<P ALIGN="JUSTIFY">I.L. Brisbin, Savannah River Ecology Laboratory, P.O. Drawer E, Aiken, South Carolina 29801, USA (Ossabaw)</P>
+<P ALIGN="JUSTIFY">L. Bustad, Veterinary School, Washington State University, Pullman, Washington, 99163, USA</P>
+<P ALIGN="JUSTIFY">C. Catibog-Sinha, Forest Products Research and Development Institute, College, Laguna 4031, Philippines</P>
+<P ALIGN="JUSTIFY">Centro de Investigaciones Pecuarias (CENIP), A.P. 227-9, Santo Domingo, Dominican Republic</P>
+<P ALIGN="JUSTIFY">Charles River Laboratories, Inc., 251 Ballardvale Street, Wilmington, Massachusetts 01887-0630, USA</P>
+<P ALIGN="JUSTIFY">J.H. Conrad, Department of Animal Science, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">T.J. Cunha, PO Box R, LaVerne, California 91750, USA</P>
+<P ALIGN="JUSTIFY">F. Dederer, 712 Brown Street, Philadelphia, Pennsylvania 19123, USA</P>
+<P ALIGN="JUSTIFY">A. Dettmers, 5620 Longwood Avenue, Port Charlotte, Florida 33953, USA (miniature pigs)</P>
+<P ALIGN="JUSTIFY">C. Devendra, Agriculture Food and Nutrition Sciences Division, International Development Research Centre (IDRC), Tanglin P.O. Box 101, 9124 Singapore</P>
+<P ALIGN="JUSTIFY">N.I. Dim, Department of Animal Science, Faculty of Agriculture, Ahmadu Bello University, P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">G. Edgar, Greenhill, I R.D., Balfour, Southland, New Zealand (kunekune)</P>
+<P ALIGN="JUSTIFY">H. Hendricks, Department of Animal, Dairy, and Veterinary Sciences, Utah State University, Logan, Utah 84322-4815, USA</P>
+<P ALIGN="JUSTIFY">B.J. Hepburn, Swine Program, Charles River Laboratories, 251 Ballardvale Street, Wilmington, Massachusetts 01887-0630, USA (laboratory pigs)</P>
+<P ALIGN="JUSTIFY">P. Holbrook, Aria Road' via Te Kuiti, New Zealand (kunekune)</P>
+<P ALIGN="JUSTIFY">R.R. Hook, Jr., Sinclair Medical Research Farm, University of Missouri, Route 3, Columbia, Missouri 65203, USA (laboratory pigs)</P>
+<P ALIGN="JUSTIFY">J.O. Ilori, Faculty of Agriculture, University of If e, Ile-Ife, Nigeria</P>
+<P ALIGN="JUSTIFY">G. E. Kodituwakku, Department of Veterinary Clinical Studies, University of Peradeniya, Peradeniya, Sri Lanka</P>
+<P ALIGN="JUSTIFY">J.K. Loosli, 406 S.W. 40th Street' Gainesville, Florida 32607, USA</P>
+<P ALIGN="JUSTIFY">J.H. Maner, Winrock International, Route 3, Petit Jean Mountain, Morrilton, Arkansas 72110, USA</P>
+<P ALIGN="JUSTIFY">J.J. Mayer, Savannah River Ecology Laboratory, P.O. Drawer E, Aiken, South Carolina 29801, USA (Ossabaw)</P>
+<P ALIGN="JUSTIFY">K. Mitchell, Baptist Bible Institute, P.O. Box 301, Basseterre, St. Kitts, West Indies</P>
+<P ALIGN="JUSTIFY">A. Monsi, Departments of Animal Science/Food Science and Technology, Rivers State University of Science and Technology, P.M.B. 508O, Port Harcourt, Nigeria</P>
+<P ALIGN="JUSTIFY">J. Mtimuni, Livestock Production Department, Bunda College of Agriculture, University of Malawi, P.O. Box 219, Lilongwe, Malawi</P>
+<P ALIGN="JUSTIFY">D.G. Mugisa, c/o Insure Consult, P.O. Box 30002, Nakivubo, Kampala, Uganda</P>
+<P ALIGN="JUSTIFY">K. Mull, 2834 Hamner Avenue #208, Norco, California 91760, USA</P>
+<P ALIGN="JUSTIFY">W.L.R. Oliver, Pigs and Peccaries Specialist Group, Jersey Wildlife Prescrvation Trust, Les AugrFs Manor, Jersey, Channel Islands, UK (pigmy hog) </P>
+<P ALIGN="JUSTIFY">L. Panepinto, Redstone Canyon, P.O. Box 105, Masonville, Colorado 80541, USA (miniature pigs)</P>
+<P ALIGN="JUSTIFY">W.J.A. Payne, 91 Bedwardine Road, London SE19 3AY, UK</P>
+<P ALIGN="JUSTIFY">C.C. Perdomo, Centro Nacional de Pesquisa de Suinos e Aves, BR 153, km 110, CP D-3, 89700 Concordia, SC, Brazil</P>
+<P ALIGN="JUSTIFY">R.W. Phillips, The Representative, Apartment 810, 1101 South Arlington Ridge Road, Arlington, Virginia 22202, USA (Chinese breeds)</P>
+<P ALIGN="JUSTIFY">W.G. Pond, Meat Animal Research Center, U.S. Department of Agriculture, Box 166, Clay Center, Nebraska 68933, USA</P>
+<P ALIGN="JUSTIFY">H. Popenoe, International Programs in Agriculture, 3028 McCarty Hall, University of Florida, Gainesville, Florida 32611, USA (New Guinea pigs)</P>
+<P ALIGN="JUSTIFY">B.S. Reddi, CoHege of Veterinary Science, Andhra Pradesh Agricultural University, Tirupati 517 502, India</P>
+<P ALIGN="JUSTIFY">S. Avendano Reyes, Instituto Nacional de las Investigaciones sobre los Recursos BiotTcnicos, (INIREB), Apartado Postal 97, MTrida, Yucatan, Mexico (Yucatan)</P>
+<P ALIGN="JUSTIFY">C. Robinson, Robinson's Racing Pigs, 5809 20th Avenue South, Tampa, Florida 336195457, USA (miniature pigs)</P>
+<P ALIGN="JUSTIFY">C. Arellano Sota, Regional Office for Latin America and the Caribbean, Food and Agriculture Organization of the United Nations, Casillo 10095, Santiago, Chile (Cuing)</P>
+<P ALIGN="JUSTIFY">A. Sriramamurty, College of Veterinary Science, Andhra Pradesh Agricultural University, Tirupati 517 502, India</P>
+<P ALIGN="JUSTIFY">M.M. Swindle, Comparative Medicine/Lab Animal Resources, Medical University of South Carolina, 171 Ashley Avenue, Charleston, South Carolina 29425, USA (laboratory pigs)</P>
+<P ALIGN="JUSTIFY">N. Tilakaratne, Veterinary Research Institute, Gannoruwa, Peradeniya, Sri Lanka</P>
+<P ALIGN="JUSTIFY">R.G. Wahome, Department of Animal Production, P.O. Box 29053, Nairobi, Kenya</P>
+<P ALIGN="JUSTIFY">Wu Jitang, Animal and Veterinary Science, Jiangsu Provincial Academy of Agricultural Sciences, Nanjing, People's Republic of China</P>
+<P ALIGN="JUSTIFY">Yong Shen Lee, Department of Animal Husbandry and Veterinary Medicine, South China Agricultural University, Guangzhou, People's Republic of China</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">POULTRY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Information on poultry can generally be obtained from local ministries of agriculture or veterinary and livestock services. However, another source is the World's Poultry Science Association (c/o Institut fur Kleintierzucht, Dornbergstrasse 25/27, Postfach 280, C-3100 Celle, Germany). It has over 5,000 members from 40 national groups. Its objectives are (1) to advance poultry science and the poultry industry, (2) to disseminate and facilitate the exchange of knowledge pertaining to all branches of the poultry industry, (3) to encourage the promotion of world poultry congresses and regional conferences, and (4) to cooperate with other international organizations. It maintains working groups to explore and assess research work on tropical poultry problems. The World's Poultry Science Journal is published 3 times a year. It has also published a multilingual poultry dictionary.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chicken</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A.O. Aduku, Department of Animal Science, Faculty of Agriculture, Ahmadu Bello University, P.M.B. 1044, Zaria, Nigeria </P>
+<P ALIGN="JUSTIFY">D.O. Alonge, Meat Hygiene and Preservation Laboratory, Faculty of Veterinary Medicine, University of Ibadan, Ibadan, Nigeria</P>
+<P ALIGN="JUSTIFY">A. Ben-David, Poultry Production Specialist, 5, Azar Street, Holon 58291, Israel</P>
+<P ALIGN="JUSTIFY">I.L. Brisbin, Jr., Savannah River Ecology Laboratory, P.O. Drawer E, Aiken, South Carolina 29801, USA</P>
+<P ALIGN="JUSTIFY">J.K. Camoens, Senior Livestock Specialist, Asian Development Bank, P.O. Box 789, Manila 2800, Philippines</P>
+<P ALIGN="JUSTIFY">J.R. Couch, Poultry Science Department, Texas A&amp;M University, College Station, Texas 77843, USA</P>
+<P ALIGN="JUSTIFY">R.D. Crawford, Department of Animal and Poultry Science, University of Saskatchewan, Saskatoon, Saskatchewan S7N 0W0, Canada</P>
+<P ALIGN="JUSTIFY">M. Cuca G., Institucion de Ensenanza e Investigacion en Ciencias Agricolas, Colegio de Postgraduados, Chapingo, Mexico</P>
+<P ALIGN="JUSTIFY">N.I. Dim, Animal Science Department, Faculty of Agriculture, Ahmadu Bello University, P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">D. Fielding, Centre for Tropical Veterinary Medicine, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Easter Bush, Roslin, Midlothian EH25 9RG, Scotland, UK</P>
+<P ALIGN="JUSTIFY">R.O. Hawes, Department of Animal and Veterinary Sciences, University of Maine, Orono, Maine 04469, USA</P>
+<P ALIGN="JUSTIFY">D. Holderread, P.O. Box 492, Corvallis, Oregon 97339, USA</P>
+<P ALIGN="JUSTIFY">C.H. Huang, Food and Fertilizer Technology Center for the Asian and Pacific Region, Fifih Floor, 14 Wenchow Street, Taipei, Taiwan</P>
+<P ALIGN="JUSTIFY">E.H. Ketelaars, Department of Tropical Husbandry, P.O. Box 338, 6700 A.H. Wageningen, The Netherlands</P>
+<P ALIGN="JUSTIFY">M.A. Latif, Department of Poultry Science, Bangladesh Agricultural University, Mymensingh, Bangladesh</P>
+<P ALIGN="JUSTIFY">H. Martoyo, Faculty of Animal Science, Institut Pertanian Bogor, Jalan Raya Pajajaran, Bogor, West Java, Indonesia</P>
+<P ALIGN="JUSTIFY">K. Mitchell, Baptist Bible Institute, P.O. Box 301, Basseterre, St. Kitts, West Indies</P>
+<P ALIGN="JUSTIFY">E.T. Moran, Jr., Poultry Science Department, Auburn University, Auburn, Alabama 36849-4291, USA</P>
+<P ALIGN="JUSTIFY">S. Ochetim, School of Agriculture, University of the South Pacific, Alafua Campus, Apia, Western Samo</P>
+<P ALIGN="JUSTIFY">S. Parks, Route 1, Box 47-C, Brookshire, Texas 77423, USA (Araucanian chicken)</P>
+<P ALIGN="JUSTIFY">R.W. Phillips, The Representative, Apt.810, 1101 South Arlington Ridge Road, Arlington, Virginia 22202, USA</P>
+<P ALIGN="JUSTIFY">H.L. Polley, Programme DTveloppement Plateau Bateke, CBZO, B.P. 4728, Kinshasa 2, Zaire</P>
+<P ALIGN="JUSTIFY">A. Ramakrishman, Center for Advanced Studies in Poultry Science, Kerala Agricultural University, Mannuthy 680 651, Kerala, India</P>
+<P ALIGN="JUSTIFY">C.V. Reddy, Faculty of Veterinary Science, Andhra Pradesh Agricultural University, Rajendranagar, Hyderabad 500 030, India</P>
+<P ALIGN="JUSTIFY">E. Ross, Department of Animal Science, University of Hawaii, Honolulu, Hawaii 96822, USA</P>
+<P ALIGN="JUSTIFY">M.L. Scott, 16 Spruce Lane, Ithaca, New York 14850, USA</P>
+<P ALIGN="JUSTIFY">T.J. Sexton, Agricultural Research Service, U.S. Department of Agriculture, Beltsville Agricultural Research Center, Building 262, Beltsville, Maryland 20705, USA</P>
+<P ALIGN="JUSTIFY">R.G. Somes, Nutritional Sciences, Box U-17, University of Connecticut, Storrs, Connecticut 06268, USA</P>
+<P ALIGN="JUSTIFY">M. Sunde, Poultry Science Department, University of Wisconsin, Madison, Wisconsin 53706, USA</P>
+<P ALIGN="JUSTIFY">R.T. Wilson, Bartridge House, Umberleigh, North Devon EX37 9AS, UK </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Duck</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">R.E. Abdelsamie, Department of Biochemistry, Microbiology, and Nutrition, University of New England, Armidale, New South Wales 2351, Australia</P>
+<P ALIGN="JUSTIFY">S. Ahmed, Department of Poultry Science, Bangladesh Agricultural University, Mymensingh, Bangladesh</P>
+<P ALIGN="JUSTIFY">A. Bande, PATI, Popondetta Agricultural College, Box 131, Popondetta, Oro Province, Papua New Guinea</P>
+<P ALIGN="JUSTIFY">R.S. Bird, Cherry Valley Farms Ltd., Rothwell, Lincoln LN7 6BR, UK</P>
+<P ALIGN="JUSTIFY">V.D. Bulbule, Central Duck Breeding Farm, Government of India, Hessaraghatta, Bangalore 560 088, India</P>
+<P ALIGN="JUSTIFY">J.K. Camoens, Asian Development Bank, P.O. Box 789, Manila 2800, Philippines</P>
+<P ALIGN="JUSTIFY">K.M. Cheng, Avian Genetics Laboratory, Department of Animal Science, University of British Columbia, Vancouver, British Columbia V6T 2A2, Canada</P>
+<P ALIGN="JUSTIFY">W.F. Dean, Cornell University Duck Research Laboratory, P.O. Box 217, Eastport, New York 11941, USA</P>
+<P ALIGN="JUSTIFY">N.I. Dim, Animal Science Department, Faculty of Agriculture, Ahmadu Bello University, P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">P. Edwards, Agricultural and Food Engineering Division, Asian Institute of Technology, P.O. Box 2754, Bangkok 10501, Thailand</P>
+<P ALIGN="JUSTIFY">L. Fishelson, Department of Zoology, Tel Aviv University, Ramat-ave, Tel Aviv 69978, Israel</P>
+<P ALIGN="JUSTIFY">W.F. Floresca, Department of Animal Science and Veterinary Medicine, Visayas State College of Agriculture, Baybay, Leyte 7127, Philippines</P>
+<P ALIGN="JUSTIFY">H. Godoy, Ingeniero Agronomio, Simon Bolivar 2397, Santiago, Chile</P>
+<P ALIGN="JUSTIFY">P. Hardjosworo, Fakultas Peternakan, Institut Pertanian Bogor, Bogor, Indonesia</P>
+<P ALIGN="JUSTIFY">R. Henry, Cherry Valley Farms Limited, Divisional Offices, North Kelsey Moor, Lincoln LN7 6HH, UK</P>
+<P ALIGN="JUSTIFY">D. Holderread, P.O. Box 492, Corvallis, Oregon 97339, USA</P>
+<P ALIGN="JUSTIFY">W.F. Hollander, Route 4, Box 168, Ames, lowa 5001O, USA</P>
+<P ALIGN="JUSTIFY">E. Hoffmann, Canning, Nova Scotia BOP IHO, Canada</P>
+<P ALIGN="JUSTIFY">C.H. Huang, Food and Fertilizer Technology Center for the Asian and Pacific Region, Fifth Floor, 14 Wenchow Street, Taipei, Taiwan</P>
+<P ALIGN="JUSTIFY">G. Ibanez H., Bolivar 451, Trujillo, Peru</P>
+<P ALIGN="JUSTIFY">Z. Jungkaro, Research Institute for Inland Fisheries, Jalan Sempur No. 1, Indonesia</P>
+<P ALIGN="JUSTIFY">G.A.R. Kamar, Animal Production Department, Faculty of Agriculture, Cairo University, Giza, Egypt</P>
+<P ALIGN="JUSTIFY">E.H. Ketelaars, Department of Tropical Husbandry, P.O. Box 338, 6700 A.H. Wageningen, The Netherlands</P>
+<P ALIGN="JUSTIFY">I.P. Kompiang, BaliPenelitianTernak, P.O. Box 123, Bogor 16001, WestJava, Indonesia</P>
+<P ALIGN="JUSTIFY">M.A. Latif, Department of Poultry Science, Bangladesh Agricultural University, Mymensingh, Bangladesh</P>
+<P ALIGN="JUSTIFY">H. Martoyo, Faculty of Animal Science, Institut Pertanian Bogor, Jalan Raya Pajajaran, Bogor, Indonesia</P>
+<P ALIGN="JUSTIFY">P. Mongin, Station de Recherches Avicoles, I.N.R.A., Nouzilly 37380 Monnaie, France</P>
+<P ALIGN="JUSTIFY">E.T. Moran, Jr., Poultry Science Department, Auburn University, Auburn, Alabama 36849-4291, USA</P>
+<P ALIGN="JUSTIFY">S. Ochetim, School of Agriculture, University of the South Pacific, Alafua Campus, Apia, Western Samoa</P>
+<P ALIGN="JUSTIFY">R.W. Phillips, The Representative, Apartment 810, 1101 South Arlington Ridge Road, Arlington, Virginia 22202, USA</P>
+<P ALIGN="JUSTIFY">H. Pingel, Karl-Marx-Universitat, Sektion TV, Lehrstuhl Geflugel- und Pelztierzucht, 7010 Leipzig, Stephanstrasse 12, Germany </P>
+<P ALIGN="JUSTIFY">S. Poernomo, Research Institute for Veterinary Science, Jalan R.E. Martadinata 32, P.O. Box 52, Bogor, West Java, Indonesia</P>
+<P ALIGN="JUSTIFY">A. Ramakrishman, Center for Advanced Studies in Poultry Science' Kerala Agricultural University, Mannuthy 680 651, Kerala, India</P>
+<P ALIGN="JUSTIFY">B. Retailleau, Grimaud FrFres S.A., La CorbiFre, 49450 Roussay, France</P>
+<P ALIGN="JUSTIFY">T.S. Sandhu, Cornell University Duck Research Laboratory, P.O. Box 217, Eastport, New York 11941, USA</P>
+<P ALIGN="JUSTIFY">M.L. Scott, 16 Spruce Lane, Ithaca, New York 14850, USA</P>
+<P ALIGN="JUSTIFY">B.K. Shingari, Department of Animal Science, Punjab Agricultural University, Ludhiana 141 004, India</P>
+<P ALIGN="JUSTIFY">C. Tai, Taiwan Livestock Research Institute, 112 Farm Road Shin-hua, Tainan, Taiwan 71210</P>
+<P ALIGN="JUSTIFY">B. Tangendjaja, Bali Penelitian Ternak, P.O. Box 123, Bogor 16001, Indonesia</P>
+<P ALIGN="JUSTIFY">Tian Fuh Shen, Department of Animal Husbandry, National Taiwan University, Taipei 10764, Taiwan</P>
+<P ALIGN="JUSTIFY">S.S. Tsai, Laboratory of Veterinary Pathology, National Pintung Institute of Agriculture, Pintung, Taiwan</P>
+<P ALIGN="JUSTIFY">A. Romero Villanueva, Centro Tropical de Capacitaci6n Agropecuaria y Forestal, Apartado Postal #4S, Macuspana 86700 Tabasco, Mexico</P>
+<P ALIGN="JUSTIFY">R.T. Wilson, Bartridge House, Umberleigh, North Devon EX37 9AS, UK</P>
+<P ALIGN="JUSTIFY">Wildfowl Trust, Slimbridge, UK</P>
+<P ALIGN="JUSTIFY">Yeong Shue Woh, Malaysian Agricultural Research and Development Institute (MARDI), G.P.O. No. 12301, 50774 Kuala Lumpur, Malaysia</P>
+<P ALIGN="JUSTIFY">Cha Tak Yimp, Poultry and Swine Unit, Department of Veterinary Services, Jalan Mahameru, 50630 Kuala Lumpur, Malaysia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Geese</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many universities have a department of animal or poultry science that should know about the culture and management of these birds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. Bande, PATI, Popondetta Agricultural College, Box 131, Popondetta, Oro Province, Papua New Guinea</P>
+<P ALIGN="JUSTIFY">J.K. Camoens, Asian Development Bank, P.O. Box 789, Manila 2800, Philippines</P>
+<P ALIGN="JUSTIFY">F.D. Chesterley, 4502 Loomis Trail, Blaine, Washington 98230, USA</P>
+<P ALIGN="JUSTIFY">R.D. Crawford, Department of Animal and Poultry Science, University of Saskatchewan, Saskatoon, Saskatchewan S7N 0W0, Canada</P>
+<P ALIGN="JUSTIFY">N.l. Dim, Animal Science Department, Faculty of Agriculture, Ahmadu Bello University, P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">D. Holderread, P.O. Box 492, Corvallis, Oregon 97339, USA</P>
+<P ALIGN="JUSTIFY">S. Jackson, P.O. Box 3, Creenbank, Washington 98253, USA (weeder geese)</P>
+<P ALIGN="JUSTIFY">Liu Fuan, Department of Animal Husbandry and Veterinary Medicine, South China Agricultural University, Guangzhou, People's Republic of China</P>
+<P ALIGN="JUSTIFY">P. Mongin, Station de Recherches Avicoles, l.N.R.A., Nouzilly 37380, Monnaie, France</P>
+<P ALIGN="JUSTIFY">E. Ross, Department of Animal Science, University of Hawaii, Honolulu, Hawaii 96822, USA</P>
+<P ALIGN="JUSTIFY">B.K. Shingari, Department of Animal Science, Punjab Agricultural University, Ludhiana 141 004, India</P>
+<P ALIGN="JUSTIFY">H.R. Wilson, Poultry Science Department, University of Florida, Gainesville, Florida 32611, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea Fowl</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A.O. Aduku, Department of Animal Science, Faculty of Agriculture, Ahmadu Bello University, P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">American Guinea Club, c/o Angie Papp, 620 Payne Road, New Albany, Indiana 47150, USA</P>
+<P ALIGN="JUSTIFY">J.S.O. Ayeni, Kainji Lake Research Institute, P.M.B. 666, New Bussa, Kwara State, Nigeria</P>
+<P ALIGN="JUSTIFY">A. Ben-David, 5, Azar Street, Holon 58291, Israel</P>
+<P ALIGN="JUSTIFY">G.S. Brah, Department of Animal Science, Punjab Agricultural University, Ludhiana 141 004, India</P>
+<P ALIGN="JUSTIFY">X. Colonna C., 14 Cotham Road, Bristol BS6 6DR, UK</P>
+<P ALIGN="JUSTIFY">N.I. Dim, Department of Animal Science, Faculty of Agriculture, Ahmadu Bello University, P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">R. Dumont, Ecole Nationale SupTrieure des Sciences Agronomiques AppliquTes, 26, boulevard Docteur Petitjean 21100 Dijon, France</P>
+<P ALIGN="JUSTIFY">R. Etches, Department of Animal and Poultry Science, University of Guelph, Guelph, Ontario NIG 2WI, Canada</P>
+<P ALIGN="JUSTIFY">D. Holderread, P.O. Box 492, Corvallis, Oregon 97339, USA</P>
+<P ALIGN="JUSTIFY">A.F. Hutton, Garaina Farms, Scrubby Creek Road, Gympie MS: 115, Queensland 4570, Australia</P>
+<P ALIGN="JUSTIFY">D.N. Johnson, Natal Parks, Game and Fish Preservation Board, P.O. Box 661, Pietermaritzburg 3200, South Africa</P>
+<P ALIGN="JUSTIFY">S.D. Lukefahr, International Small Livestock Research Center, Department of Food Science and Animal Industries, Alabama A&amp;:M University, P.O. Box 264, Normal, Alabama 35762, USA</P>
+<P ALIGN="JUSTIFY">W. Michie, Poultry Husbandry Division, North of Scotland College of Agriculture, Parkhead, Craibstone, Bucksburn, Aberdeen AB2 9SX, Scotland, UK</P>
+<P ALIGN="JUSTIFY">P. Mongin, Station de Recherches Avicoles, I.N.R.A., Nouzilly, 37380 Monnaie, France</P>
+<P ALIGN="JUSTIFY">S. Ochetim, School of Agriculture, University of the South Pacific, Alafua Campus, Apia, Western Samoa</P>
+<P ALIGN="JUSTIFY">A.N. Okaeme, Wildlife/Range Division, Kainji Lake Research Institute, P.M.B. 666, New Bussa, Kwara State, Nigeria</P>
+<P ALIGN="JUSTIFY">J.S. Sandhu, Poultry Breeder, Department of Animal Science, Punjab Agricultural University, Ludhiana 141 004, India</P>
+<P ALIGN="JUSTIFY">B.K. Shingari, Department of Animal Science, Punjab Agricultural University, Ludhiana 141 004, India</P>
+<P ALIGN="JUSTIFY">R.G. Somes, Nutritional Sciences, Box U-17, University of Connecticut, Storrs, Connecticut 06268, USA</P>
+<P ALIGN="JUSTIFY">R.T. Wilson, Bartridge House, Umberleigh, North Devon EX37 9AS, UK</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muscovy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">R.E. Abdelsamie, Department of Biochemistry, Microbiology, and Nutrition, University of New England, Armidale, New South Wales 2351, Australia</P>
+<P ALIGN="JUSTIFY">G.P. Bilong, Department of Primary Industry, Monogastric Research Centre, P.O. Box 73, Lae, Papua New Guinea</P>
+<P ALIGN="JUSTIFY">J.K. Camoens, Asian Development Bank, P.O. Box 789, Manila 2800, Philippines</P>
+<P ALIGN="JUSTIFY">H. de Carville, Station de Recherches Avicoles, I.N.R.A., Centre de Tours, Nouzilly 37380, Monnaie, France</P>
+<P ALIGN="JUSTIFY">F.D. Chesterley, 4502 Loomis Trail, Blaine, Washington 98230, USA</P>
+<P ALIGN="JUSTIFY">X. Colonna C., 14 Cotham Road, Bristol BS6 6DR, UK</P>
+<P ALIGN="JUSTIFY">N.I. Dim, Animal Science Department, Faculty of Agriculture, Ahmadu Bello University, P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">R. Dumont, Ecole Nationale SupTrieure des Sciences Agronomiques AppliquTes, 26, boulevard Docteur Petitjean 21100 Dijon, France</P>
+<P ALIGN="JUSTIFY">G.R. Gerona, Department of Animal Science and Veterinary Medicine, Visayas State College of Agriculture, Baybay, Leyte, Philippines</P>
+<P ALIGN="JUSTIFY">Barry Glofcheskie, Department of Environmental Biology, University of Guelph, Guelph, Ontario NIG 2WI, Canada (fly control)</P>
+<P ALIGN="JUSTIFY">D. Holderread' P.O. Box 492, Corvallis, Oregon 97339, USA</P>
+<P ALIGN="JUSTIFY">W.F. Hollander, Route 4, Box 168, Ames, Iowa 50010, USA</P>
+<P ALIGN="JUSTIFY">E. Hoffmann, Canning, Nova Scotia BOP IH0, Canada</P>
+<P ALIGN="JUSTIFY">C.H. Huang, Food and Fertilizer Technology Center for the Asian and Pacific Region, Fifth Floor, 14 Wenchow Street, Taipei, Taiwan (mule duck)</P>
+<P ALIGN="JUSTIFY">G.A.R. Kamar, Animal Production Department, Faculty of Agriculture, Cairo University, Giza, Egypt</P>
+<P ALIGN="JUSTIFY">W. Michie, Poultry Husbandry Division, North of Scotland College of Agriculture, Parkhead, Craibstone, Bucksburn, Aberdeen AB2 9SX, Scotland, UK</P>
+<P ALIGN="JUSTIFY">Donald E. Mock, Department of Extension Entomology, 239 Waters Hall, Kansas State University, Manhattan, Kansas 66506-4004, USA (fly control)</P>
+<P ALIGN="JUSTIFY">P. Mongin, Station de Recherches Avicoles, I.N.R.A., Nouzilly 37380 Monnaie, France</P>
+<P ALIGN="JUSTIFY">S. Ochetim, School of Agriculture, University of the South Pacific, Alafua Campus, Apia, Western Samoa</P>
+<P ALIGN="JUSTIFY">H. Pingel, Karl Marx Universitat, Sektion TV, Lehrstuhl Geflugel- und Pelztierzucht, 7010 Leipzig, Stephanstrasse 12, Germany</P>
+<P ALIGN="JUSTIFY">B. Retailleau, Grimaud FrFres S.A., La CorbiFre, 494S0 Roussay, France</P>
+<P ALIGN="JUSTIFY">I. Romboli, Le Quericole, Universita Delgi Studi di Pisa 56010 S. Piero A Grado, Italy</P>
+<P ALIGN="JUSTIFY">T.S. Sandhu, Cornell University Duck Research Laboratory, P.O. Box 217, Eastport, New York 11941, USA</P>
+<P ALIGN="JUSTIFY">G.A. Surgeoner, Department of Environmental Biology, University of Guelph, Guelph, Ontario NIG 2WI, Canada (fly control)</P>
+<P ALIGN="JUSTIFY">C. Tai, Taiwan Livestock Research Institute, 112 Farm Road Shin-hua. Tainan, Taiwan 71210</P>
+<P ALIGN="JUSTIFY">R.T. Wilson, Bartridge House, Umberleigh, North Devon EX37 9AS, UK</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigeon</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A.O. Aduku, Department of Animal Science, Faculty of Agriculture, Ahmadu Bello University, P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">D.O. Alonge, Meat Hygiene and Preservation Laboratory, Faculty of Veterinary Medicine, University of Ibadan, Ibadan, Nigeria</P>
+<P ALIGN="JUSTIFY">J.K. Camoens, Asian Development Bank, P.O. Box 789, Manila 2800, Philippines</P>
+<P ALIGN="JUSTIFY">K.M. Cheng, Avian Genetics Laboratory, Department of Animal Science, University of British Columbia, Vancouver, British Columbia V6T 2A2, Canada</P>
+<P ALIGN="JUSTIFY">R. Dillinger, 3201 Huffman Boulevard, Rockford, Illinois 61103, USA</P>
+<P ALIGN="JUSTIFY">N.I. Dim, Animal Science Department, FacultyofAgriculture, AhmaduBello University, P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">R.O. Hawes, Department of Animal and Veterinary Sciences, University of Maine, Orono, Maine 04469, U.S.A.</P>
+<P ALIGN="JUSTIFY">D. Holderread, P.O. Box 492, Corvallis, Oregon 97339, USA (carrier pigeons) </P>
+<P ALIGN="JUSTIFY">W.F. Hollander, Route 4, Box 168, Ames, lowa 5001O, USA</P>
+<P ALIGN="JUSTIFY">M.A. Latif, Department of Poultry Science, Bangladesh Agricultural University, Mymensingh, Bangladesh</P>
+<P ALIGN="JUSTIFY">Y. Le HTnaff, Laboratoire de l'H(pital Avranches, Avranches, Cotentin, France (carrier pigeons)</P>
+<P ALIGN="JUSTIFY">S.D. Lukefahr, International Small Livestock Research Center, Department of Food Science and Animal Industries, Alabama A&amp;M University, P.O. Box 264, Normal, Alabama 35762, USA</P>
+<P ALIGN="JUSTIFY">G.A.R. Kamar, Animal Production Department, Faculty of Agriculture, Cairo University, Giza, Egypt</P>
+<P ALIGN="JUSTIFY">W.J. Miller, Department of Genetics, Iowa State University, Ames, Iowa 50011, USA</P>
+<P ALIGN="JUSTIFY">G. Owen, 6520 Wiscasset Road, Bethesda, Maryland 20816, USA</P>
+<P ALIGN="JUSTIFY">G. Pena PTrez, Apartado Postal 23, La Nucia, Alicante, Spain</P>
+<P ALIGN="JUSTIFY">E. Ross, Department of Animal Science, University of Hawaii, Honolulu, Hawaii 96822, USA</P>
+<P ALIGN="JUSTIFY">M.D. Roush, Green Valley Squab Farm, 1348 Green Valley Road, Folsom, California 9563O, USA</P>
+<P ALIGN="JUSTIFY">T.S. Sandbu, Cornell University Duck Research Laboratory, P.O. Box 217, Eastport, New York 11941, USA</P>
+<P ALIGN="JUSTIFY">J.S. Sim, Department of Animal Science, University of Alberta, Edmonton, Alberta TOG 2P5, Canada</P>
+<P ALIGN="JUSTIFY">R.T. Wilson, Bartridge House, Umberleigh, North Devon EX37 9AS, UK</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Quail</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Many people raise Japanese quail. Probably the best way to locate a local source is to consult local pet stores, the county farm advisor's office, university faculty of agriculture, game-bird fanciers, and the like. Finding people with local research experience is usually most useful to beginners. Coturnix International, Inc., is a nonprofit organization with primary interests in promoting small domesticated food animal production for both youth training and improved nutrition. The use of coturnix (Japanese quail) for these purposes is already well established in a number of Michigan schools and in the Dominican Republic, with special emphasis on science projects, especially where nutritional inadequacies exist. The address is Coturnix International Inc., International Headquarters, 1111 Michigan Avenue, Box 250O, East Lansing, Michigan 48823, USA. Avian Sciences Department, University of California, Davis, California 95616, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J.K. Camoens, Asian Development Bank, P.O. Box 789, Manila 2800, Philippines </P>
+<P ALIGN="JUSTIFY">K.M. Cheng, Avian Genetics Laboratory, Department of Animal Science, University of British Columbia, Vancouver, British Columbia V6T 2A2, Canada</P>
+<P ALIGN="JUSTIFY">D.E. Deppner, Trees for the Future, 11306 Estona Drive, Silver Spring, Maryland 20902, USA</P>
+<P ALIGN="JUSTIFY">D. Holderread, P.O. Box 492, Corvallis, Oregon 97339, USA</P>
+<P ALIGN="JUSTIFY">S.D. Lukefahr, International Small Livestock Research Center, Department of Food</P>
+<P ALIGN="JUSTIFY">Science and Animal Industries, Alabama AOcM University, P.O. Box 264, Normal, Alabama 35762, USA</P>
+<P ALIGN="JUSTIFY">H.L. Marks, Genetics Unit, Room 107 Livestock-Poultry Building, University of Georgia, Athens, Georgia 30602, USA</P>
+<P ALIGN="JUSTIFY">A. Marsh, Marsh Farms, 7171 Patterson Drive, Garden Grove, California 92641, USA</P>
+<P ALIGN="JUSTIFY">H. Martoyo, Faculty of Animal Science, Institut Pertanian Bogor, Jalan Raya Pajajaran, Bogor, West Java, Indonesia</P>
+<P ALIGN="JUSTIFY">Z. Abidin bin Mohd Noor, Department of Veterinary Services, Jalan Sultan Salahuddin, 50630 Kuala Lumpur, Malaysia (chicken-quail hybrids)</P>
+<P ALIGN="JUSTIFY">P.K. Pani, Indian Veterinary Research Institute, Izatnagar 243 122, Bareilly, Uttar Pradesh, India</P>
+<P ALIGN="JUSTIFY">H. Pingel, Karl Marx Universitat, Sektion TV, Lehrstuhl Geflugel- und Pelztierzucht, 7010 Leipzig, Stephanstrasse 12, Germany</P>
+<P ALIGN="JUSTIFY">D. Polin, Department of Animal Science, Michigan State University, East Lansing, Michigan 48824, USA</P>
+<P ALIGN="JUSTIFY">C.V. Reddy, Faculty of Veterinary Science, Andhra Pradesh Agricultural University, Rajendranagar, Hyderabad 500 030, India</P>
+<P ALIGN="JUSTIFY">Rodale Research Center, RD #1, Box 323, Kutztown, Pennsylvania 19530, USA</P>
+<P ALIGN="JUSTIFY">E. Ross, Department of Animal Science, University of Hawaii, Honolulu, Hawaii 96822, USA</P>
+<P ALIGN="JUSTIFY">B.K. Shingari, Department of Animal Science, Punjab Agricultural University, Ludhiana 141 006, India</P>
+<P ALIGN="JUSTIFY">R.G. Somes, Nutritional Sciences, Box U-17, University of Connecticut, Storrs, Connecticut 06268, USA</P>
+<P ALIGN="JUSTIFY">R. Tempest, Heifer Project International, P.O. Box 808, Little Rock, Arkansas 72203, USA</P>
+<P ALIGN="JUSTIFY">S. K. Varghese, Department of Animal Science, Michigan State University, East Lansing, Michigan 48824-1225, USA</P>
+<P ALIGN="JUSTIFY">N. Wakasugi, Laboratory of Animal Genetics, Nagoya University, Furo-cho, Chikusaku, Nagoya, Japan</P>
+<P ALIGN="JUSTIFY">H.R. Wilson, Poultry Science Department, Archer Road, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Turkey</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M. Berruecos V. Muz, Facultad de Medicina Veterinaria y Zootecnia, Ciudad Universitaria, Mexico D.F., Mexico</P>
+<P ALIGN="JUSTIFY">R.D. Crawford, Department of Animaland Poultry Science, UniversityofSaskatchewan, Saskatoon, Canada</P>
+<P ALIGN="JUSTIFY">M. Cuca G., Institucion de Ensenanza e Investigacion en Ciencias Agricolas, Colegio de Postgraduados, Chapingo, Mexico</P>
+<P ALIGN="JUSTIFY">K.E. Nestor, Ohio Agricultural Research and Development Center, Ohio State University, Wooster, Ohio</P>
+<P ALIGN="JUSTIFY">H. Pingel, Karl-Marx-Universitat, Sektion TV, Lehrstuhl Geflugel- und Pelztierzucht, 7010 Leipzig, Stephanstrasse 12, Germany</P>
+<P ALIGN="JUSTIFY">M.L. Scott, 16 Spruce Lane, Ithaca, New York 14850, USA</P>
+<P ALIGN="JUSTIFY">H.J. Sexton, Agricultural Research Service, U.S. Department of Agriculture, Beltsville Agricultural Research Center, Building 262, Beltsville, Maryland 20705, USA</P>
+<P ALIGN="JUSTIFY">R.G. Somes, Nutritional Sciences. Box U-17, University of Connecticut, Storrs, Connecticut 06268, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Potential New Poultry</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J.E. Duckett, P.O. Box 12378, 50776 Kuala Lumpur, Malaysia (barn owls)</P>
+<P ALIGN="JUSTIFY">W.R. Marion, Department of Wildlife and Range Science, University of Florida, Gainesville, Florida 32611, USA (chachalaca)</P>
+<P ALIGN="JUSTIFY">C. Smal, Wildlife Service, Sidmonton Place, Bray County, Wicklow, Ireland (barn owls) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RABBITS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Domestic Rabbit</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A.O. Aduku, Department of Animal Science, Faculty of Agriculture, Ahmadu Bello University,  P.M.B. 1044, Zaria, Nigeria</P>
+<P ALIGN="JUSTIFY">J. Baranga, Department of Zoology, Makerere University, P.O. Box 7062, Kampala, Uganda</P>
+<P ALIGN="JUSTIFY">M. Baselga, Departamento de Ciencia Animal, Escuela TTcnica Superior de Ingenieros  Agronomos, Camino de Vera 14, 46022 Valencia, Spain</P>
+<P ALIGN="JUSTIFY">C. de Blas, Departamento Alimentacion Animal, Escuela TTcnica Superior de Ingenieros  Agronomos, Ciudad Universitaria, 28040 Madrid, Spain</P>
+<P ALIGN="JUSTIFY">J.A. Castell6, Real Escuela Oficial y Superior de Avicultura (REOSA), Calle Plana Parafso, s/n  Arenys de Mar, Barcelona, Spain</P>
+<P ALIGN="JUSTIFY">C.B. Chawan, International Small Livestock Research Center, Department of Food Science and  Animal Industries, Alabama A&amp;M University, P.O. Box 264, Normal, Alabama 35762, USA</P>
+<P ALIGN="JUSTIFY">P.R. Cheeke, Rabbit Research Center, Department of Animal Science, Oregon State University,  Corvallis, Oregon 97331, USA</P>
+<P ALIGN="JUSTIFY">S. Fekete, University of Veterinary Science, Department of Animal Nutrition, Budapest, Pf.2,  H-1400 Hungary</P>
+<P ALIGN="JUSTIFY">J. Fernandez C., Departamento de Ciencia Animal, Escuela TTcnica Superior de Ingenieros  Agronomos, Universidad PolitTcnica de Valencia, Camino de Vera, 14, 46022 Valencia, Spain</P>
+<P ALIGN="JUSTIFY">C. Cervera Fras, Departamento de Ciencia Animal, Universidad PolitTcnica de Valencia, Apartado  22012, Valencia, Spain</P>
+<P ALIGN="JUSTIFY">D.J. Harris, Pel-Freez Rabbit Meat, Inc., P.O. Box 68, Rogers, Arkansas 72756, USA</P>
+<P ALIGN="JUSTIFY">J.A.B. Hundleby, Ciskei Agricultural Corporation Ltd., P.O. Box 59, Bisho, Ciskei, South Africa</P>
+<P ALIGN="JUSTIFY">D.L. Huss, P.O. Box 426, Menard, Texas 76859, USA</P>
+<P ALIGN="JUSTIFY">R. de Jong, Department of Tropical Animal Production, Marykeweg 40, 6709 P.G. Wageningen,  The Netherlands</P>
+<P ALIGN="JUSTIFY">L.A. Kamwanja, Bunda College of Agriculture, University of Malawi, P.O. Box 219, Lilongwe,  Malawi</P>
+<P ALIGN="JUSTIFY">M. Leyun, Instituto TTcnico Gesti6n Porcino (ITGP), Seccion Conejos, Ctra. del Sadar, s/n 31006  Pamplona (Navarra), Spain</P>
+<P ALIGN="JUSTIFY">H. Loliger, Lisztstrasse 20, 3100 Celle, Germany</P>
+<P ALIGN="JUSTIFY">S.D. Lukefahr, International Small Livestock Research Center, Department of Food Science and  Animal Industries, Alabama A&amp;M University, P.O. Box 264, Normal, Alabama 35762, USA</P>
+<P ALIGN="JUSTIFY">T.P.E. Makhambera, Bunda College of Agriculture, University of Malawi, P.O. Box 219, Lilongwe,  Malawi</P>
+<P ALIGN="JUSTIFY">J.I. McNitt, Center for Small Farm Research, Southern University, P.O. Box 11170, Baton Rouge,  Louisana 70813-1170, USA</P>
+<P ALIGN="JUSTIFY">M. Mgheni, Sokoine University of Agriculture, Animal Science and Production Department, P.O.  Box 3004, Morogoro, Tanzania</P>
+<P ALIGN="JUSTIFY">K. Mitchell, Baptist Bible Institute, P.O. Box 301, Basseterre, St. Kitts, West Indies</P>
+<P ALIGN="JUSTIFY">G.A. Norman, Tropical Products Institute, Culham, Abingdon, Oxfordshire OX14 3DA, UK</P>
+<P ALIGN="JUSTIFY">L.N. Odonker, P.O. Box 11, Tsito-Awudome, Volta Region, Ghana</P>
+<P ALIGN="JUSTIFY">O.C. Onwudike, Department of Animal Science, University of Ife, Ile-Ife, Nigeria  </P>
+<P ALIGN="JUSTIFY">G.G. Partridge, Rowett Research Institute, Bucksburn, Aberdeen AB2 9SB, Scotland, UK</P>
+<P ALIGN="JUSTIFY">N.M. Patton, Rabbit Research Center, Oregon State University, Corvallis, Oregon 97331, USA</P>
+<P ALIGN="JUSTIFY">M.J. Paya, Departamento de Microbiologia, Facultad de Veterinaria, Avenida Puerta de Hierro, Ciudad Universitaria, 28040 Madrid, Spain</P>
+<P ALIGN="JUSTIFY">T. PTrez, Departamento de Reproduccion Animal, Instituto Nacional de Investigaciones Agrarias (INIA), Avenida Puerta de Hierro, s/n, 28040 Madrid, Spain</P>
+<P ALIGN="JUSTIFY">H.L. Polley, Programme DTveloppement Plateau Bateke, CBZO, B.P. 4728, Kinshasa 2, Zaire</P>
+<P ALIGN="JUSTIFY">R. Ramchurn, School of Agriculture, University of Mauritius, RTduit, Mauritius</P>
+<P ALIGN="JUSTIFY">T.E. Reed, Box 98, Markle, Indiana 46770, USA</P>
+<P ALIGN="JUSTIFY">E. Respaldiza, Instituto Nacional de Investigaciones Agrarias (INIA), Departamento de Higiene y Sanidad Animal, Calle Embajadores, 68, 28012 Madrid, Spain</P>
+<P ALIGN="JUSTIFY">B. Retailleau, Grimaud FrFres S.A., La CorbiFre, 49450 Roussay, France</P>
+<P ALIGN="JUSTIFY">A. Rodriguez, Departamento Microbiologia e Inmunologia, Facultad de Veterinaria, Calle Miguel Servet, numero 117, 50013 Zaragoza, Spain</P>
+<P ALIGN="JUSTIFY">R. Rodriguez de L., "Conejos" Centro de Investigacion Cientifica del Estado de MTxico A.C., Camino a Huexotla No. 5, San Miguel Coatlinchan, 56170 Texcoco, Estado de MTxico, Mexico</P>
+<P ALIGN="JUSTIFY">W. Schlolaut, Hessen Institute for Animal Production, Neu-Ulrichstein, 6313 Homberg, West Germany</P>
+<P ALIGN="JUSTIFY">W.D. Semuguruka, Department of Veterinary Pathology, Faculty of Veterinary Medicine, Sokoine University of Agriculture, P.O. Box 3018, Chuo Kikuu Morogoro, Tanzania</P>
+<P ALIGN="JUSTIFY">I. Sierra, Departamento Produccion Animal, Facultad de Veterinaria, Calle Miguel Servet, numero 117, 50013 Zaragoza, Spain</P>
+<P ALIGN="JUSTIFY">R. Valls, Institut de Recerce i Tecnologia Agroalimentaria (IRTA), Torre Marimon, 08140 Caldes de Montbui, Barcelona, Spain</P>
+<P ALIGN="JUSTIFY">P. Zaragoza, Departamento de Genetica y Mejora, Facultad de Veterinaria, Calle Miguel Servet, numero 117, 50013 Zaragoza, Spain</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RODENTS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agouti</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C.J.R. Alho, Departamento de Biologia Animal, Universidade de Brasilia, 70910 Brazilia, DF, Brazil</P>
+<P ALIGN="JUSTIFY">R.H. Baker, 302 North Strickland Street, Eagle Lake, Texas 77434-1841, USA</P>
+<P ALIGN="JUSTIFY">H. Bonilla Encizo, ICA Tibaitata, Apartado Aereo 151123, BogotG, Colombia</P>
+<P ALIGN="JUSTIFY">A.D. Cuaron O., Instituto de Historia Natural, Apartado Postal No. 6, Tuxtla Gutierrez, Chiapas 29000, Mexico</P>
+<P ALIGN="JUSTIFY">L.A. Deutsch, Parque Zoologico de Sao Paulo, SGo Paulo, Brazil</P>
+<P ALIGN="JUSTIFY">G. Dubost, Laboratorie d'Ecologie, 4 avenue Petit ChGteau, 91800 Brunoy, France</P>
+<P ALIGN="JUSTIFY">J.K. Frenkel, Department of Pathology, University of Kansas Medical Center, Kansas City, Kansas 66013, USA</P>
+<P ALIGN="JUSTIFY">A. Escajadillo, Gorgas Memorial Laboratory, P.O. Box 935, APO Miami, Florida 340020012, USA OR Avenida Justo Arosemena 34-30, Apartado 6991, Panama 5, Panama</P>
+<P ALIGN="JUSTIFY">W. Hallwachs, Department of Biology, University of Pennsylvania, Philadelphia, Pennsylvania 19104-6018, USA </P>
+<P ALIGN="JUSTIFY">G. Hislop, Wildlife Section, Forest Division, Ministry of Food Production, Port-ofSpain, Trinidad and Tobago</P>
+<P ALIGN="JUSTIFY">S. Ingrand, I.N.R.A., Campus agronomique, B.P. 709, 97387 Kourou Cedex, French Guiana</P>
+<P ALIGN="JUSTIFY">D.H. Janzen, Department of Biology, University of Pennsylvania, Philadelphia, Pennsylvania 19104, USA</P>
+<P ALIGN="JUSTIFY">D. Kleiman, National Zoological Park, Washington, D.C. 20008, USA</P>
+<P ALIGN="JUSTIFY">A. Lavorenti, Animal Sciences Department, ESALQ Universidade de Sao Paulo, C.P. 9, Piracicaba, Sao Paulo 13.400, Brazil</P>
+<P ALIGN="JUSTIFY">D.A. Meritt, Jr., 2200 North Cannon Drive, Chicago, IHinois 60614, USA</P>
+<P ALIGN="JUSTIFY">J.R. de Alencar Moreira, EMBRAPA-CPATU, Agricultural Research Center of the Humid Tropics, Caixa Postal 48, BelTm, Para 66000, Brazil</P>
+<P ALIGN="JUSTIFY">C.Ma. Rojas G., CATIE, 7170 Turrialba, Costa Rica</P>
+<P ALIGN="JUSTIFY">G. Santos, Fundatao Parque Zoologico de Sao Paulo, Sao Paulo, Brazil</P>
+<P ALIGN="JUSTIFY">N. Smith, Department of Geography, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">N. Smythe, Smithsonian Tropical Research Institute, Box 2072, Balboa, Panama</P>
+<P ALIGN="JUSTIFY">O. Sousa, Department of Microbiology, Cinuad Universitaria "Dr Octavio MTndez Pereira," El Cangregio, Apartado Estafeta Universitaria, Panama City, Panama</P>
+<P ALIGN="JUSTIFY">A.B. Taber, Animal Behaviour Research Group, Department of Zoology, South Parks Road, Oxford OXI 3PS, UK</P>
+<P ALIGN="JUSTIFY">E. Wing, Florida State Museum, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">C.A. Woods, Florida State Museum, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Capybara</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C.J.R. Alho, Departamento de Biologia Animal, Universidade de Brasilia, 70910 Brasilia, DF, Brazil</P>
+<P ALIGN="JUSTIFY">K.P. Bland, Department of Veterinary Physiology, Royal (Dick) School of Veterinary Studies, Summerhall, Edinburgh EH9 IQH, Scotland, UK</P>
+<P ALIGN="JUSTIFY">H. Bonilla Encizo, ICA Tibaitata, Apartado Aereo 151123, Bogota, Colombia</P>
+<P ALIGN="JUSTIFY">P.R. Cheeke, Rabbit Research Center, Department of Animal Science, Oregon State University, Corvallis, Oregon 97331, USA</P>
+<P ALIGN="JUSTIFY">T.J. Cunha, P.O. Box R, LaVerne, California 91750, USA</P>
+<P ALIGN="JUSTIFY">J.F. Eisenberg, Florida State Museum, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">F. Golley, Institute of Ecology, University of Georgia, Athens, Georgia 30601, USA</P>
+<P ALIGN="JUSTIFY">E. Gonzalez-Jimenez, Facultad de Agronomia, Universidad Central de Venezuela, Maracay, Venezuela</P>
+<P ALIGN="JUSTIFY">H. Hemmer, Institute of Zoology, Johannes Gutenberg University, Anemonenweg 18, D-6500 Mainz-Ebersheim, Germany</P>
+<P ALIGN="JUSTIFY">J.A. Howarth, School of Veterinary Medicine, University of California, Davis, California 95616, USA</P>
+<P ALIGN="JUSTIFY">S. Ingrand, I.N.R.A., Campus agronomique, B.P. 709, 97387 Kourou Cedex, French Guiana</P>
+<P ALIGN="JUSTIFY">N. Konnerup, 74 North Sunrise Boulevard, Camano Island, Washington 98292, USA</P>
+<P ALIGN="JUSTIFY">J.E. Jackson, Terraza Turrado 80, 5730 Villa Mercedes, San Luis, Argentina</P>
+<P ALIGN="JUSTIFY">D. Kleiman, National Zoological Park, Washington, D.C. 20008, USA</P>
+<P ALIGN="JUSTIFY">A. Lavorenti, Animal Sciences Department, ESALQ Universidade de Sao Paulo, C.P. 9, Piracicaba, Sao Paulo 13.400, Brazil </P>
+<P ALIGN="JUSTIFY">R.D. Lord, Biology Department, Indiana University of Pennsylvania, Indiana, Pennsylvania 15705, USA</P>
+<P ALIGN="JUSTIFY">D.W. MacDonald, Animal Behaviour Research Group, Department of Zoology, South Parks Road, Oxford OXI 3PS, UK</P>
+<P ALIGN="JUSTIFY">J.R. de Alencare Moreira, Agricultural Research Center of the Humid Tropics, EMBRAPA-CPATU, Caixa Postal 48" BelTm, Para 66000, Brazil</P>
+<P ALIGN="JUSTIFY">B. Muller-Haye, Food and Agricultural Organization of the United Nations, Room F524, Via delle Terme di Caracalla, 00100 Rome, Italy</P>
+<P ALIGN="JUSTIFY">J. Ojasti, Institute of Tropical Zoology, Apartado 47058, Universidad Central de Venezuela, Caracas 1041A, Venezuela</P>
+<P ALIGN="JUSTIFY">N.L. Rondon, Departamento de Engenharia Florestal, Centro de Ciencias Agrarias, Universidada Federal de Mato Grosso, Cuiaba-MT, 78000, Brazil</P>
+<P ALIGN="JUSTIFY">N. Smith, Department of Geography, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">A.E. Sollod, Section of International Veterinary Medicine, Tufts University, 200 Westboro Road, North Grafton, Massachusetts 01536, USA</P>
+<P ALIGN="JUSTIFY">F. Sunquist, Route 1, Box 1434, Melrose, Florida 32666, USA</P>
+<P ALIGN="JUSTIFY">A.B. Taber, Animal Behaviour Research Group, Department of Zoology, South Parks Road, Oxford OXI 3PS, UK</P>
+<P ALIGN="JUSTIFY">K.D. Thelen, FAO Regional Of fice for Latin America and the Caribbean, CasiHa 10095, Santiago, Chile</P>
+<P ALIGN="JUSTIFY">D. Wharton, New York Zoological Society, Bronx, New York 10460, USA</P>
+<P ALIGN="JUSTIFY">E. Wing, Florida State Museum, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coypu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A.C. Carmichael, The Museum, Michigan State University, East Lansing, Michigan 48824-1045, USA</P>
+<P ALIGN="JUSTIFY">G. Chapman, Utah State University, Logan, Utah 84322, USA</P>
+<P ALIGN="JUSTIFY">L. Contreras, Universidad Cat61ica de Valpariso, Avenida Brasi. 295O, Casilla 4059, Valparaiso, Chile</P>
+<P ALIGN="JUSTIFY">D. Huss, P.O. Box 426, Menard, Texas 76859, USA</P>
+<P ALIGN="JUSTIFY">H.-G. Klos, Zoologischer Garten Berlin, Aktiengesellschaft, Hardenbergplatz, 1000 Berlin 30, Germany</P>
+<P ALIGN="JUSTIFY">P. Lutz, Rosenstiel School of Marine and Atmospheric Science, Biology and Living Resources, University of Miami, 4600 Rickenbacker Causeway, Miami, Florida 33149, USA</P>
+<P ALIGN="JUSTIFY">J.R. de Alencar Moreira, Agricultural Research Center of the Humid Tropics, Caixa Postal 48, BelTm, ParG, 66000, Brazil</P>
+<P ALIGN="JUSTIFY">J. Szumiec, Experimental Fish Culture Station, Polish Academy of Sciences, Golysz 43-422 Chybie, Poland</P>
+<P ALIGN="JUSTIFY">C.A. Woods, Florida State Museum, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Giant Rat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Animal Research Institute, Council for Scientific and Industrial Research (CSIR), P.O. Box 20, Achimota, Chana</P>
+<P ALIGN="JUSTIFY">J. Baranga, Department of Zoology, Makerere University, P.O. Box 7062, Kampala, Uganda </P>
+<P ALIGN="JUSTIFY">K.P. Bland, Department of Veterinary Physiology, Royal (Dick) School of Veterinary Studies, Summerhall, Edinburgh EH9 IQH, Scotland, UK</P>
+<P ALIGN="JUSTIFY">P. Brinck, Ecology Building, Department of Animal Ecology, University of Lund, S223 62 Lund, Sweden</P>
+<P ALIGN="JUSTIFY">G. Dubost, Laboratorie d'Ecologie, 4 avenue Petit ChGteau, 91800 Brunoy, France</P>
+<P ALIGN="JUSTIFY">D. Fielding, Centre for Tropical Veterinary Medicine, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Easter Bush, Roslin, Midlothian EH25 9RG, Scotland, UK</P>
+<P ALIGN="JUSTIFY">D.C.D. Happold, Department of Zoology, Australian National University, Canberra, Australian Capital Territory 2601, Australia</P>
+<P ALIGN="JUSTIFY">J.C. Heymans, BP 1910, Cotonou, Benin</P>
+<P ALIGN="JUSTIFY">J.A. Kamara, c/o Njala University College, Private Mail Bag, Freetown, Sierra Leone</P>
+<P ALIGN="JUSTIFY">M.H. Knight, Kalahari Gemsbok Park, Private Bag X5890, Upington 8800, South Africa</P>
+<P ALIGN="JUSTIFY">M. Malekani, DTpartement de Biologie, FacultT des Sciences, UniversitT de Kinshasa, B.P. 190, Kinshasa XI, Zaire</P>
+<P ALIGN="JUSTIFY">R.W. Matthewman, Centre for Tropical Veterinary Medicine, Royal (Dick) School for Veterinary Studies, University of Edinburgh, Easter Bush, Roslin, Midlothian EH25 9RG, Scotland, UK</P>
+<P ALIGN="JUSTIFY">A.J. Smith, Centre for Tropical Veterinary Medicine, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Easter Bush, Roslin, Midlothian EH25 9RG, Scotland, UK</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Grasscutter</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. Alexander, Department of Biology, Natal University, King George V Avenue, Durban 4001, South Africa</P>
+<P ALIGN="JUSTIFY">E.O.A. Asibey, Department of Game and Wildlife, Ministry Post Office, Accra, Ghana</P>
+<P ALIGN="JUSTIFY">E.S. Ayensu, African Development Bank, 01 B.P. No. 1837, Abidjan 01, Ivory Coast</P>
+<P ALIGN="JUSTIFY">R. Baptist, Institute for Animal Production in the Tropics and Subtropics, University of Hohenheim (480), P.O. Box 700562, D-7000 Stuttgart 70, Germany</P>
+<P ALIGN="JUSTIFY">S.Y. Bimpong-Buta, Council for Law Reporting, P.O. Box M165, Accra, Ghana</P>
+<P ALIGN="JUSTIFY">P. Brinck, Department of Animal Ecology, University of Lund, Ecology Building, S223 62, Lund, Sweden</P>
+<P ALIGN="JUSTIFY">H. Dosso, Institut d'Ecologie Tropicale, Abidjan, Ivory Coast</P>
+<P ALIGN="JUSTIFY">D. Fielding, Centre for Tropical Veterinary Medicine, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Easter Bush, Roslin, Midlothian EH25 9RG, Scotland, UK</P>
+<P ALIGN="JUSTIFY">D.C.D. Happold, Department of Zoology, Australian National University, Canberra, Australian Capital Territory 2601, Australia</P>
+<P ALIGN="JUSTIFY">J. Hardouin, Institut de Medicine Tropicale "Prince Leopold," Nationalestraat 155, B2000 Antwerp, Belgium</P>
+<P ALIGN="JUSTIFY">J.C. Heymans, BP 1910, Cotonou, Benin</P>
+<P ALIGN="JUSTIFY">A. Hutton, Garaina Farms, Scrubby Creek Road, Gympie MS:115, Queensland 4570, Australia</P>
+<P ALIGN="JUSTIFY">J.A. Kamara, c/o Njala University College, Private Mail Bag, Freetown, Sierra Leone</P>
+<P ALIGN="JUSTIFY">Laboratoire Centrale de Nutrition Animale (LACENA), B.P. 353, Abidjan 06, Ivory Coast</P>
+<P ALIGN="JUSTIFY">S.D. Lukefahr, International Small Livestock Research Center, Department of Food Science and Animal Industries, Alabama A&amp;M University, P.O. Box 264, Normal, Alabama 35762, USA</P>
+<P ALIGN="JUSTIFY">R.-P. Mack, Projet BTnino-Allemand Conseiller Technique auprTs du MDRAC, BP 504, Cotonou, Benin </P>
+<P ALIGN="JUSTIFY">G.H.G. Martin, Department of Zoology, Kenyatta University College, P.O. Box 43844, Nairobi, Kenya</P>
+<P ALIGN="JUSTIFY">R.W. Matthewman, Centre for Tropical Veterinary Medicine, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Easter Bush, Roslin, Midlothian EH25 9RG, Scotland, UK</P>
+<P ALIGN="JUSTIFY">G.A. Mensah, Responsable PBAA (Projet BTnino-Allemand d'Aulacodiculture), P.B. 2359, Cotonou, Benin</P>
+<P ALIGN="JUSTIFY">T.A. Omole, Department of Animal Science, University of Ife, Ile-lfe, Nigeria</P>
+<P ALIGN="JUSTIFY">K.J. Peters, International Livestock Centre for Africa (ILCA), P.O. Box 5689, Addis Ababa, Ethiopia</P>
+<P ALIGN="JUSTIFY">F. Petter, MammifFres et Oiseaux, Museum National d'Histoire Naturelle Zoologie, 55 rue de Buffon 75005, Paris, France</P>
+<P ALIGN="JUSTIFY">W. Schr(der, Institute of Animal Breeding, Albrecht-Thaer-Weg 1, 3400 Gottingen, Germany</P>
+<P ALIGN="JUSTIFY">A.J. Smith, Centre for Tropical Veterinary Medicine, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Easter Bush, Roslin, Midlothian EH25 9RG, Scotland, UK</P>
+<P ALIGN="JUSTIFY">D.W. Thomas, Department of Biology, University of Sherbrooke, Sherbrooke, Quebec JIK 2RI, Canada</P>
+<P ALIGN="JUSTIFY">St. von Korn, Institute of Animal Breeding, Albrecht-Thaer-Weg 1, 3400 G(ttingen, Germany</P>
+<P ALIGN="JUSTIFY">J. Walder, Presbyterian Rural Training Centre, P.O. Box 72, Bamenda, NW Province, Cameroon</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea Pig</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">G.P. Bilong, Department of Pimary Industry, Monogastric Research Centre, P.O. Box 73, Lae, Papua New Guinea</P>
+<P ALIGN="JUSTIFY">K.P. Bland, Department of Physiology, Royal (Dick) School of Veterinary Studies, Summerhall, Edinburgh EH9 IQH, Scotland, UK</P>
+<P ALIGN="JUSTIFY">R. Bolton, Department of Anthropology, Pomona College, Claremont, California 91711, USA</P>
+<P ALIGN="JUSTIFY">H. Bonilla Encizo, ICA Tibaitata, Apartado Aereo 151123, Bogota, Colombia</P>
+<P ALIGN="JUSTIFY">J.K. Camoens, Asian Development Bank, P.O. Box 789, Manila 2800, Philippines</P>
+<P ALIGN="JUSTIFY">A. Del Carpio R., Facultad de Zootecnia, Universidad Nacional "Pedro Ruiz Gallo," Calle Atahualpa No. 179, Apartado 48, Lambayeque, Peru</P>
+<P ALIGN="JUSTIFY">P.R. Cheeke, Rabbit Research Center, Department of Animal Science, Oregon State University, Corvallis, Oregon 97331, USA</P>
+<P ALIGN="JUSTIFY">T.J. Cunha, P.O. Box R, LaVerne, California 91750, USA</P>
+<P ALIGN="JUSTIFY">J. Descailleux, Laboratorio GenTtica Humana, C.P. 11010, Lima 14, Peru</P>
+<P ALIGN="JUSTIFY">J.A. Ferguson, Overseas Development Administration, Eland House, Stug Place, London, UK</P>
+<P ALIGN="JUSTIFY">D. Fielding, Centre for Tropical Veterinary Medicine, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Easter Bush, Roslin, Midlothian EH25 9RC, Scotland, UK</P>
+<P ALIGN="JUSTIFY">J.K. Frenkel, Department of Pathology, University of Kansas Medical Center, Kansas City, Kansas 66013, USA</P>
+<P ALIGN="JUSTIFY">J. Hardouin, Institut de MTdecine Tropicale "Prince Leopold," Nationalestraat IS5, B2000 Antwerpen, Belgium</P>
+<P ALIGN="JUSTIFY">R.E. Honegger, Zurich Zoo, Zurichbergstrasse 221, CH-8044 Zurich, Switzerland </P>
+<P ALIGN="JUSTIFY">J. Howarth, School of Veterinary Medicine, University of Calffornia, Davis, Calffornia 95616, USA</P>
+<P ALIGN="JUSTIFY">D.L. Huss, P.O. Box 426, Menard, Texas 76859, USA</P>
+<P ALIGN="JUSTIFY">J.E. Jackson, Terraza Turrado 80, 5730 Villa Mercedes, San Luis, Argentina</P>
+<P ALIGN="JUSTIFY">C. Jenkins, PNG Institute Medical Research, P.O. Box 60, Goroka, Eastern Highlands Province, Papua New Guinea</P>
+<P ALIGN="JUSTIFY">R. de Jong, Department of Tropical Animal Production, Marykeweg 40, 6709 PG Wageningen, The Netherlands</P>
+<P ALIGN="JUSTIFY">J.A. Kamara, c/o Njala University College, Private Mail Bag Freetown, Sierra Leone</P>
+<P ALIGN="JUSTIFY">P.J. Kohun, Department of Agriculture, PNG University of Technology, Lae, Papua New Guinea</P>
+<P ALIGN="JUSTIFY">N.M. Konnerup, 74 North Sunrise Boulevard, Camano Island, Washington 98292, USA</P>
+<P ALIGN="JUSTIFY">T.E. Lacher, Jr., Huxley College of Environmental Studies, Western Washington University, Bellingham, Washington 98225, USA</P>
+<P ALIGN="JUSTIFY">S.D. Lukefahr, International Small Livestock Research Center, Department of Feed Science and Animal Industries, Alabama A&amp;M University, P.O. Box 264, Normal, Alabama 35762, USA</P>
+<P ALIGN="JUSTIFY">R.C. Malik, Department of Agriculture, PNG University of Technology, Lae, Papua New Guinea</P>
+<P ALIGN="JUSTIFY">R.W. Matthewman, Centre for Tropical Veterinary Medicine, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Easter Bush, Roslin, Midlothian EH25 9RG, Scotland, UK</P>
+<P ALIGN="JUSTIFY">A.R. Moreno, Departamento de Produccion Animal, Universidad Nacional Agraria, Apartado 456, La Molina, Lima, Peru</P>
+<P ALIGN="JUSTIFY">B. Muller-Haye, Food and Agriculture Organization of the United Nations, Room F524, Via delle Terme di Caracalla, 00100 Rome, Italy</P>
+<P ALIGN="JUSTIFY">H.L. Polley, Programme DTveloppement Plateau Bateke, CBZO, B.P. 4728, Kinshasa 2, Zaire</P>
+<P ALIGN="JUSTIFY">V. Purizaga A., Alcalde del Concejo Provincial de Pacasmayo, Dos de Mayo 360, Peru</P>
+<P ALIGN="JUSTIFY">V.T. Quirante, Bureau of Animal Industry, Research Center, Alabang 3124, Metro Manila, Philippines</P>
+<P ALIGN="JUSTIFY">C.V. Reddy, Faculty of Veterinary Science, Andhra Pradesh Agricultural University, Rajendranagar, Hyderabad 500 030, India</P>
+<P ALIGN="JUSTIFY">O.W. Robinson, Department of Animal Science, North Carolina State University, Box 7621 Raleigh, North Carolina 27695-7621, USA</P>
+<P ALIGN="JUSTIFY">A.J. Smith, Centre for Tropical Veterinary Medicine, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Easter Bush, Roslin, Midlothian EH25 9RG, Scotland, UK</P>
+<P ALIGN="JUSTIFY">D. Wharton, New York Zoological Society, Bronx, New York 10460, USA</P>
+<P ALIGN="JUSTIFY">E. Wing, Florida State Museum, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hutia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A.C. Allen, Hope Zoo, Kingston, Jamacia</P>
+<P ALIGN="JUSTIFY">R.S. Canet, Instituto de Zoologla, Academia Ciencias de Cuba, Calle 214, esq. a Avenida 19, No. 17A 09, Reparto Atabey, Havana 16, Cuba</P>
+<P ALIGN="JUSTIFY">D. Kleiman, National Zoological Park, Washington, D.C. 20008, USA</P>
+<P ALIGN="JUSTIFY">K. Jordan, Department of Zoology, University of Florida, Gainesville, Florida 32611, USA </P>
+<P ALIGN="JUSTIFY">W.L.R. Oliver, Jersey Wildlife Preservation Trust, Les AugrFs Manor, Jersey, Channel Islands, UK</P>
+<P ALIGN="JUSTIFY">J.A. Ottenwalder, Parque Zool6gico Nacional (ZOODOM), Apartado 2449, Santo Domingo, Dominican Republic</P>
+<P ALIGN="JUSTIFY">E. Wing, Florida State Museum, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">C. Woods, Florida State Museum, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mara</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">L.T. Blankenship, Animal Resources Center, School of Medicine, East Carolina University, Greenville, North Carolina 27858-4354, USA</P>
+<P ALIGN="JUSTIFY">G. Dubost, Laboratoire d'Ecologie, 4 avenue Petit ChGteau, 91800 Brunoy, France</P>
+<P ALIGN="JUSTIFY">J.E. Jackson, Terraza Turrado 80, 5730 Villa Mercedes, San Luis, Agentina</P>
+<P ALIGN="JUSTIFY">D. Kleiman, National Zoological Park, Washington, D.C. 20008, USA</P>
+<P ALIGN="JUSTIFY">D.W. MacDonald, Animal Behaviour Research Group, Department of Zoology, South Parks Road, Oxford OXI 3PS, UK</P>
+<P ALIGN="JUSTIFY">W.H. Pryor, Jr., School of Medicine, East Carolina University, Greenville, North Carolina 27858-4354, USA</P>
+<P ALIGN="JUSTIFY">A.B. Taber, Animal Behaviour Research Group, Department of Zoology, South Parks Road, Oxford OXI 3PS, UK</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Paca</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J.R. de Alencar Moreira, Agricultural Research Center of the Humid Tropics, EMBRAPA-CPATU, Caixa Postal 48, BelTm, Para 66000, Brazil</P>
+<P ALIGN="JUSTIFY">C.J.R. Alho, Departamento de Biologia Animal, Universidade de Brasilia, 70910 Brasilia, DF, Brazil</P>
+<P ALIGN="JUSTIFY">R.H. Baker, 302 North Strickland Street, Eagle Lake, Texas 77434-1841, USA</P>
+<P ALIGN="JUSTIFY">A.D. Cuardn O., Instituto de Historia Natural, Apartado Postal No. 6, Tuxtla Gutierrez, Chiapas 29000, Mexico</P>
+<P ALIGN="JUSTIFY">G. Dubost, Laboratoire d'Ecologie, 4 avenue Petit ChGteau, 91800 Brunoy, France</P>
+<P ALIGN="JUSTIFY">L. de Escalante, Zool6gico Nacional, Direccion del Patrimonio Natural y Cultural, San Salvador, El Salvador</P>
+<P ALIGN="JUSTIFY">J.K. Frenkel, Department of Pathology, University of Kansas Medical Center, Kansas City, Kansas 66013, USA</P>
+<P ALIGN="JUSTIFY">W. Hallwachs, Ecology and Systematics, Corson Hall, Cornell University, Ithaca, New York 14853, USA</P>
+<P ALIGN="JUSTIFY">C. Hislop, Wildlife Section, Forest Division, Ministry of Food Production, Port-ofSpain, Trinidad and Tobago</P>
+<P ALIGN="JUSTIFY">D.H. Janzen, Department of Biology, University of Pennsylvania, Philadelphia, Pennsylvania 19104, USA</P>
+<P ALIGN="JUSTIFY">D. Kleiman, National Zoological Park, Washington, D.C. 20008, USA</P>
+<P ALIGN="JUSTIFY">A. Lavorenti, Animal Sciences Department, ESALQ Universidade de Sao Paulo, C.P. 9, Piracicaba, Sao Paulo 13.400, Brazil</P>
+<P ALIGN="JUSTIFY">Y. Matamoros, Escuela de Medicina Veterinaria, Universidad Nacional, Apartado 86, Heredia, Costa Rica</P>
+<P ALIGN="JUSTIFY">D. Meritt, Jr., 2200 North Cannon Drive, Chicago, Illinois 60614, USA</P>
+<P ALIGN="JUSTIFY">C.Ma. Rojas G., CATIE, 7170 Turrialba, Costa Rica </P>
+<P ALIGN="JUSTIFY">O. Rosado, Ministry of Industry and Natural Resources, Belmopan, Belize</P>
+<P ALIGN="JUSTIFY">N. Smith, Department of Geography, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">N. Smythe, Smithsonian Tropical Research Institute, Box 2072, Balboa, Panama</P>
+<P ALIGN="JUSTIFY">V. Solis, Union Internacional pare la Conservacion de la Naturaleza y de los Recursos Naturales, Oficina Regional pare Centro AmTrica, Apartado Postal 91-1009-FECOSA, San JosT, Costa Rica</P>
+<P ALIGN="JUSTIFY">S. VaidTs, Centro Universitario del Norte Carrera ZootTcnica, Coban, A.V., Ciudad Guatemala 16001, Guatemala</P>
+<P ALIGN="JUSTIFY">E. Wing, Florida State Museum, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vizcacha</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. Bonilla Encizo, ICA Tibaitata, Apartado Aereo 151123, Bogota, Colombia</P>
+<P ALIGN="JUSTIFY">J.E. Jackson, Terraza Turrado 80, 5730 Villa Mercedes, San Luis, Argentina</P>
+<P ALIGN="JUSTIFY">E.L. Marmillon, Estancias del Conlara S.A., Casilla de Correo 451, 5800 Rio Cuarto, Argentina</P>
+<P ALIGN="JUSTIFY">K.D. Thelen, FAO Regional Office for Latin America and the Caribbean, Casilla 10095, Santiago, Chile</P>
+<P ALIGN="JUSTIFY">E. Wing, Florida State Museum, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other Rodents</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">T.M. Butynski, Impenetrable Forest Conservation Project, Zoology Department, Makerere University, P.O. Box 7062, Kampala, Uganda (springhare)</P>
+<P ALIGN="JUSTIFY">T. Flannery, Australian Museum, 6-8 College Street, Sydney, New South Wales 2000, Australia (Solomon Island rodents)</P>
+<P ALIGN="JUSTIFY">Inter-African Bureau for Animal Resources, Maendeleo House, Monrovia Street, POB 30786, Nairobi, Kenya (springhare)</P>
+<P ALIGN="JUSTIFY">N. Jacobsen, Nature Conservation Division, Private Bag X209, Pretoria 0001, South Africa (springhare)</P>
+<P ALIGN="JUSTIFY">C.P. Kofron, Museum of Zoology, Louisiana State University, Baton Rouge, Louisiana 70893, USA (springhare)</P>
+<P ALIGN="JUSTIFY">T. Leary, Ministry of Natural Resources, Honiara, Solomon Islands (Solomon Island rodents)</P>
+<P ALIGN="JUSTIFY">C.A. McLaughlin, San Diego Zoo, San Diego 92112, California, USA (springhare)</P>
+<P ALIGN="JUSTIFY">R.P. Millar, Department of Chemical Pathology, Medical School, Observatory 7925, South Africa (springhare)</P>
+<P ALIGN="JUSTIFY">J.D. Skinner, Mammal Research Institute, University of Pretoria, Pretoria 0002, South Africa (springhare)</P>
+<P ALIGN="JUSTIFY">Southern African Wildlife Management Association, POB 413, Pretoria, South Africa ( s p ring hare )</P>
+<P ALIGN="JUSTIFY">L. Talbot, 6656 Chitton Court, McLean, Virginia 22101, USA (springhare)</P>
+<P ALIGN="JUSTIFY">M. Van der Merwe, University of Pretoria, Mammal Research Institute, Pretoria 0002, South Africa (springhare)</P>
+<P ALIGN="JUSTIFY">Wildlife Society of Zimbabwe, POB 3497, Harare, Zimbabwe (springhare) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DEER AND ANTELOPE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mouse Deer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J.O. Caldecott, World Wildlife Fund Malaysia, 7 Jalan Ridgeway, 93200 Kuching, Sarawak, Malaysia</P>
+<P ALIGN="JUSTIFY">R. Chaplin, Burnhouse, Fountainhall, Galashiels, Selkirk TDI 2RX, UK</P>
+<P ALIGN="JUSTIFY">G.W.H. Davison, Zoology Department, Universiti Kebangsaan Malaysia, 43600 Bangi, Selangor, Malaysia</P>
+<P ALIGN="JUSTIFY">G. Dubost, Laboratoire d'Ecologie GTnTrale, 4 avenue Petit ChGteau, 91800 Brunoy, France</P>
+<P ALIGN="JUSTIFY">P. Grubb, 35 Downhills Park Road, London N17 6PE, UK</P>
+<P ALIGN="JUSTIFY">Liu Ruiqing, Kunming Institute of Zoology, Academia Sinica, Kunming, Yunnan Province, People's Republic of China</P>
+<P ALIGN="JUSTIFY">M. MacNamara, Fauna Research, Inc., 11 Park Avenue, Ardsley, New York 10502, USA</P>
+<P ALIGN="JUSTIFY">I. Muul, Integrated Conservation Research, P.O. Box 920, Harpers Ferry, West Virginia 25425, USA</P>
+<P ALIGN="JUSTIFY">M. Nordin, Bureau of Research and Consultancy, University Kebangsaan Malaysia, Bangi, Selangor, Malaysia</P>
+<P ALIGN="JUSTIFY">S. Pathak, Department of Genetics, M.D. Anderson Hospital and Tumor Institute, Houston, Texas 77030, USA</P>
+<P ALIGN="JUSTIFY">C.T. Robbins, Wildlife Biology Program, Washington State University, Pullman, Washington 99164-4220, USA</P>
+<P ALIGN="JUSTIFY">K. Robin, Tierpark Dahlholzli Bern, Dalmaziquai 149, CH-3005 Bern, Switzerland</P>
+<P ALIGN="JUSTIFY">C.R. Schmidt, Zoological Garden, CH-8044 Zurich, Switzerland</P>
+<P ALIGN="JUSTIFY">R.A. Sirimanne, Singapore Zooological Gardens, 80 Mandai Lake Road, Singapore 2572</P>
+<P ALIGN="JUSTIFY">L. Talbot, 6656 Chilton Court, McLean, Virginia 22101, USA</P>
+<P ALIGN="JUSTIFY">M.K. Vidyadaran, Faculty of Veterinary Science, Department of Animal Science, Universiti Pertanian Malaysia, Serdang 43400, Selangor, Malaysia</P>
+<P ALIGN="JUSTIFY">Wang Yingxiang, Kunming Institute of Zoology, Academia Sinica, Kunming, Yunan Province, People's Republic of China</P>
+<P ALIGN="JUSTIFY">D. Wharton, New York Zoological Society, Bronx, New York 10460, USA</P>
+<P ALIGN="JUSTIFY">G.C. Whittow, Department of Physiology, John A. Burns School of Medicine, University of Hawaii, 1960 East West Road, Honolulu, Hawaii 96822, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Muntjac</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. Barrette, DTpartement de Biologie, FacultT des Sciences et de GTnie, UniversitT Laval, QuTbec, GIK 7P4, Canada</P>
+<P ALIGN="JUSTIFY">K. Benirschke, 8457 Prestwick Drive, La Jolla, California 92037, USA</P>
+<P ALIGN="JUSTIFY">The British Deer Society, Church Farm, Lower Basildon, Reading, Berkshire RG8 9NH, UK</P>
+<P ALIGN="JUSTIFY">J.O. Caldecott, World Wildlife Fund Malaysia, 7 Jalan Ridgeway, 933200 Kuching, Sarawak, Malaysia</P>
+<P ALIGN="JUSTIFY">N. Chapman, Larkmead, Barton Mills, Bury St. Edmunds, Suffolk IP28 6AA, UK</P>
+<P ALIGN="JUSTIFY">M. Coe, Department of Zoology, University of Oxford, South Parks Road, Oxford OXI 3PS, UK </P>
+<P ALIGN="JUSTIFY">O. Dansie, The Chapel, 2 Hobbs Hall, Welwyn, Hertsfordshire, UK</P>
+<P ALIGN="JUSTIFY">S.K. Dhungal, Department of Parks and Wildlffe, P.O. Box 860, Kathmandu, Nepal</P>
+<P ALIGN="JUSTIFY">C. Dubost, Laboratoire d'Ecologie GTnTrale, 4 avenue Petit ChGteau, 91800 Brunoy, France</P>
+<P ALIGN="JUSTIFY">R.J. Goss, Division of Biology and Medicine, Brown University, Providence, Rhode Island 02912, USA</P>
+<P ALIGN="JUSTIFY">C.P. Groves, Department of Prehistory and Anthropology, Australian National University, P.O. Box 4, Canberra, Australian Capital Territory 2600, Australia</P>
+<P ALIGN="JUSTIFY">P. Grubb, 35 Downhills Park Road, London N17 6PE, UK</P>
+<P ALIGN="JUSTIFY">S.P. Harding, Animal Ecology Research Group, Zoology Department, South Parks Road, Oxford OX1 3PS, UK</P>
+<P ALIGN="JUSTIFY">S. Harris, Department of Zoology, University of Bristol, Woodland Road, Bristol BS8 JUG, UK</P>
+<P ALIGN="JUSTIFY">H. Heck, CatskiH Game Farm, Inc., RD #1, Box 133, Catskill, New York 12414, USA</P>
+<P ALIGN="JUSTIFY">H.A. Jacobson, Fish and Wildlffe Department, Mississippi State University, Mississippi State, Mississippi 39762, USA</P>
+<P ALIGN="JUSTIFY">Liu Ruiqing, Kunming Institute of Zoology, Academia Sinica, Kunming, Yunnan Province, People's Republic of China</P>
+<P ALIGN="JUSTIFY">Lu Houji, Department of Biology, East China Normal University, Shanghai 200062, People's Republic of China</P>
+<P ALIGN="JUSTIFY">M. MacNamara, Fauna Research, Inc., 11 Park Avenue, Ardsley, New York 10502, USA</P>
+<P ALIGN="JUSTIFY">V.J.A. Manton, Zoological Society of London, Whipsnade Park, Dunstable, Bedfordshire LU6 2LF, UK</P>
+<P ALIGN="JUSTIFY">S. Miura, Department of Biology, Hyogo College of Medicine, Mukogawa-cho 1-1, Nishinomiya, Hyogo-ken 663, Japan</P>
+<P ALIGN="JUSTIFY">I. Muul, Integrated Conservation Research, P.O. Box 920, Harpers Ferry, West Virginia 25425, USA</P>
+<P ALIGN="JUSTIFY">S. Pathak, Department of Genetics, M.D. Anderson Hospital and Tumor Institute, Houston, Texas 77030, USA</P>
+<P ALIGN="JUSTIFY">C.T. Robbins, Wildlife Biology Program, Washington State University, Pullman, Washington 99164, USA</P>
+<P ALIGN="JUSTIFY">B. Seidel, Tierpark Berlin, Tierklinik, DDR-1136 Berlin, Friedrichsfelde, Germany</P>
+<P ALIGN="JUSTIFY">Shi Liming, Kunming Institute of Zoology, Academia Sinica, Kunming, Yunnan Province, People's Republic of China</P>
+<P ALIGN="JUSTIFY">H. Soma, Department of Obstetrics and Gynecology, Tokyo Medical College Hospital, 1-7, Nishishinjuku 6, Shinjuku-ku, Tokyo 160, Japan</P>
+<P ALIGN="JUSTIFY">S. Stadler, Fakultat fur Biologie, Universitat Bielefeld, 4800 Bielefeld, Universitatsstrasse 25, Germany</P>
+<P ALIGN="JUSTIFY">L. Talbot, 6656 Chilton Court, McLean, Virginia 22101, USA</P>
+<P ALIGN="JUSTIFY">P.F. Taylor, Taylor Energy Company, The 2-3-4 Loyola Building, New Orleans, Louisiana 70112, USA</P>
+<P ALIGN="JUSTIFY">Wang Yingziang, Kunming Institute of Zoology, Academia Sinica, Kunming, Yunnan Province, People's Republic of China</P>
+<P ALIGN="JUSTIFY">C. Wemmer, Conservation and Research Center, National Zoological Park, Front Royal, Virginia 22630, USA</P>
+<P ALIGN="JUSTIFY">D. Wharton, New York Zoological Society, Bronx, New York 10460, USA</P>
+<P ALIGN="JUSTIFY">D.M. Wurster-HiH, Department of Pathology, Dartmouth Medical School, Hanover, New Hampshire 03755, USA</P>
+<P ALIGN="JUSTIFY">R.H. Yahner, 320 Forest Resources Laboratory, Pennsylvania State University, University Park, Pennsylvania 16802, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Musk Deer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">R. Chaplin, Burnhouse, Fountainhall, Galashiels, Selkirk TDI 2RX, UK</P>
+<P ALIGN="JUSTIFY">S.K. Dhungel, Department of Parks and Wildlife, P.O. Box 860, Kathmandu, Nepal</P>
+<P ALIGN="JUSTIFY">A.J. Gaston, Canadian Wildlife Service, Ottawa KIA OE7, Canada</P>
+<P ALIGN="JUSTIFY">C.P. Groves, Department of Prehistory and Anthropology, Australian National University, P.O. Box 4, Canberra, Australian Capital Territory 2600, Australia</P>
+<P ALIGN="JUSTIFY">M.J.B. Green, IUCN Conservation Monitoring Centre, 219C Huntingdon Road, Carnbridge CB3 ODL, UK</P>
+<P ALIGN="JUSTIFY">P. Grubb, 35 Downhills Park Road, London N17 6PE, UK</P>
+<P ALIGN="JUSTIFY">M.L. Hunter, Jr., Wildlife Department, University of Maine, Orono, Maine 04469, USA</P>
+<P ALIGN="JUSTIFY">H.A. Jacobson, Fish and Wildlife Department, Mississippi State University, Mississippi State, Mississippi 39762, USA</P>
+<P ALIGN="JUSTIFY">B. Kattel, P.O. Box 3070, Kathmandu, Nepal</P>
+<P ALIGN="JUSTIFY">Liu Riqing, Kunming Institute of Zoology, Academia Sinica, Kunming Yunnan Province, People's Republic of China</P>
+<P ALIGN="JUSTIFY">Lu Houji, Department of Biology, East China Normal University, Shanghai 200062, People's Republic of China</P>
+<P ALIGN="JUSTIFY">J. McNeely, Program and Policy Division, International Union for Conservation of Nature and Natural Resources, Avenue du Mont-Blanc, CH1196 Gland, Switzerland</P>
+<P ALIGN="JUSTIFY">B.W. O'Gara, Montana Cooperative Wildlife Research Unit, University of Montana, Missoula, Montana 59812, USA</P>
+<P ALIGN="JUSTIFY">C.T. Robbins, Wildlife Biology Program, Washington State University, Pullman, Washington 99164-4220, USA</P>
+<P ALIGN="JUSTIFY">B. Seidel, Tierpark Berlin, Tierklinik, DDR-1136 Berlin, Friedrichsfelde, Germany</P>
+<P ALIGN="JUSTIFY">Shi Liming, Kunming Institute of Zoology, Academia Sinica, Kunming, Yunnan Province, People's Republic of China</P>
+<P ALIGN="JUSTIFY">P.F. Taylor, Taylor Energy Co., The 2-3-4 Loyola Building, New Orleans, Louisiana 70112, USA</P>
+<P ALIGN="JUSTIFY">Wang Yingxiang, Kunming Institute of Zoology, Academia Sinica, Kunming, Yunnan Province, People's Republic of China</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water Deer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. Cooke, Nature Conservancy Council, Northminster House, Peterborough PEI I UA, UK</P>
+<P ALIGN="JUSTIFY">L. Farrell, Nature Conservancy Council, Northminster House, Peterborough PEI IUA, UK</P>
+<P ALIGN="JUSTIFY">F. Feer, Laboratoire d'Ecologie GTnTrale, 4 avenue Petit ChGteau, 91800 Brunoy, France</P>
+<P ALIGN="JUSTIFY">P. Crubb, 35 Downhills Park Road, London N17 6PE, UK</P>
+<P ALIGN="JUSTIFY">Liu Riuqing, Kunming Institute of Zoology, Academia Sinica. Kunming Yunnan Province, People's Republic of China</P>
+<P ALIGN="JUSTIFY">Lu Houji, Department of Biology, East China Normal University, Shanghai 200062, People's Republic of China</P>
+<P ALIGN="JUSTIFY">V.J.A. Manton, Zoological Society of London, Whipsnade Park, Dunstable, Bedfordshire LU6 2LF, UK</P>
+<P ALIGN="JUSTIFY">B. Seidel, Tierpark Berlin, Tierklinik DDR-1136, Berlin, Friedrichsfelde, Germany</P>
+<P ALIGN="JUSTIFY">R Smith, Department of Zoology, Whiteknights Park, University of Reading, Reading, Berkshire RG6 2AH, UK</P>
+<P ALIGN="JUSTIFY">S. Stadler, Fakultat fur Biologie, Universitat Bielefeld, 4800 Bielefeld, Universitats strasse 25, Germany</P>
+<P ALIGN="JUSTIFY">P.F. Taylor, Taylor Energy Company, The 2-3-4 Loyola Building, New Orleans, Louisiana 70112, USA</P>
+<P ALIGN="JUSTIFY">C. Wemmer, Conservation and Research Center, National Zoological Park, Front Royal, VA 2263O, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">South American Microdeer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M. Sampath, Trinidad and Tobago Wildlffe Breeders and Farmers Association, c/o 5 3/4 Mile Mark, Penal Rock Road, Penal, Trinidad, West Indies (red brocket)</P>
+<P ALIGN="JUSTIFY">M. MacNamara, Fauna Research, Inc., 11 Park Avenue, Ardsley, New York 10502, USA (pudu)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Duikers</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. Baranga, Department of Zoology, Makerere University, P.O. Box 7062, Kampala, Uganda</P>
+<P ALIGN="JUSTIFY">B. Chardonnet, Projet Petits Ruminants, B.P. 65, Atakpame, Togo</P>
+<P ALIGN="JUSTIFY">R.L. Cowan, 324 Henning Building, Pennsylvania State University, University Park, Pennsylvania 16802, USA</P>
+<P ALIGN="JUSTIFY">G. Dubost, Laboratoire d'Ecologie GTnTrale, 4 avenue Petit ChGteau, 91800 Brunoy, France</P>
+<P ALIGN="JUSTIFY">RI.M. Dunbar, Department of Zoology, University of Liverpool, P.O. Box 147, Liverpool L69 3BX, UK</P>
+<P ALIGN="JUSTIFY">F. Feer, Laboratoire d'Ecologie GTnTrale, 4 avenue Petit ChGteau, 91800 Brunoy, France</P>
+<P ALIGN="JUSTIFY">K.R. Kranz, Zoological Society of Philadelphia, 34th Street and Girard Avenue, Philadelphia, Pennsylvania 19104, USA</P>
+<P ALIGN="JUSTIFY">S. Lumpkin, Department of Zoological Research, National Zoological Park, Washington, D.C. 20008, USA</P>
+<P ALIGN="JUSTIFY">I. Player, Wilderness Leadership School, P.O. Box 15036, BeHair 4006, Natal, South Africa</P>
+<P ALIGN="JUSTIFY">K. Pond, Department of Animal Science, North Carolina State University, Box 7621, Raleigh, North Carolina 27695, USA</P>
+<P ALIGN="JUSTIFY">S. Schweers, Bahnhofstrasse 29, D-6744 Kandee, Germany</P>
+<P ALIGN="JUSTIFY">J.D. Skinner, Mammal Research Institute, University of Pretoria, Pretoria 0002, South Africa</P>
+<P ALIGN="JUSTIFY">A.E. SoHod, International Veterinary Medicine, Tufis University, 200 Westboro Road, North Grafion, Massachusetts 01536, USA</P>
+<P ALIGN="JUSTIFY">L. Talbot, 6656 Chilton Court, McLean, Virginia 22101, USA</P>
+<P ALIGN="JUSTIFY">C.C. Udell, 14934 VaHey Vista Blouvard, Sherman Oaks, Calffornia 91403, USA</P>
+<P ALIGN="JUSTIFY">G.A. Varga, Department of Dairy and Animal Science, 225B Borland Laboratory, Pennsylvania State University, University Park, Pennsylvania 16802, USA</P>
+<P ALIGN="JUSTIFY">V.J. Wilson, Duiker Research and Breeding Centre, Chipangali Wildlife Trust, P.O. Box 1057, Bulawayo, Zimbabwe </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other Small Antelope</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">L. Asibey, Department of Game and Wildlife, Ministry Post Office, Accra, Ghana</P>
+<P ALIGN="JUSTIFY">J. Baranga, Department of Zoology, Makerere University, P.O. Box 7062, Kampala, Uganda</P>
+<P ALIGN="JUSTIFY">J.I. Boshe, College of African Wildlife Management, Mweka, P.O. Box 3031, Moshi, Tanzania (dikdik)</P>
+<P ALIGN="JUSTIFY">B. Chardonnet, Project Petits Ruminants, BP 65, Atakpame, Togo (oribi)</P>
+<P ALIGN="JUSTIFY">S.K. Dhungel, Department of National Parks and Wildife, Conservation, Babar Mahal, Kathmandu, Nepal (four-horned antelope)</P>
+<P ALIGN="JUSTIFY">R.I.M. Dunbar, Department of Zoology, University of Liverpool, P.O. Box 147, Liverpool L69 3BX, UK (dikdik, klipspringer)</P>
+<P ALIGN="JUSTIFY">F. Feer, Laboratoire d'Ecologie GTnTrale, 4 avenue Petit ChGteau, 91800 Brunoy, France</P>
+<P ALIGN="JUSTIFY">A.M. Goebel, Department of Biology, University of Texas at Arlington, Arlington, Texas 76019, USA</P>
+<P ALIGN="JUSTIFY">P.P. Hoppe, Am Hauenstein 13, 6706 Wachenheim, Germany (dikdik, suni)</P>
+<P ALIGN="JUSTIFY">K.R. Kranz, Zoological Society of Philadelphia, 34th Street and Girard Avenue, Philadelphia, Pennsylvania 19104, USA (royal antelope, beira, dikdik, klipspringer, suni, four-horned antelope)</P>
+<P ALIGN="JUSTIFY">I. Player, Wilderness Leadership School, P.O. Box 15036, Bellair 4006, Natal, South Africa</P>
+<P ALIGN="JUSTIFY">E.N.W. Oppong, UNDP/FGN/FAO Livestock Project, P.O. Box 6603, Jos, Plateau State, Nigeria</P>
+<P ALIGN="JUSTIFY">W.R. Pritchard, School of Veterinary Medicine, University of California, Davis, California 95616, USA</P>
+<P ALIGN="JUSTIFY">J. Skinner, Mammal Research Institute, University of Pretoria, Pretoria 0002, South Africa (otibi, steinbok)</P>
+<P ALIGN="JUSTIFY">A.E. Sollod, International Veterinary Medicine, Tufts University, 200 Westboro Road, North Grafton, Massachusetts 01536, USA (dikdik, klipspringer)</P>
+<P ALIGN="JUSTIFY">L. Talbot, 6656 Chilton Court, McLean, Virginia 22101, USA (dikdik, klipspringer, four-horned antelope)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LIZARDS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Green Iguana</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">K. Benirschke, 8457 Prestwick Drive, La Jolla, California 92037, USA</P>
+<P ALIGN="JUSTIFY">G.M. Burghardt, Department of Psychology, University of Tennessee, Knoxville, Tennessee 37996, USA</P>
+<P ALIGN="JUSTIFY">A. Ferreira, Parque Zoologico Nacional, Apartado 2449, Santo Domingo, Dominican Republic</P>
+<P ALIGN="JUSTIFY">H.S. Fitch, Route #3, Box 142, Lawrence, Kansas 66044, USA</P>
+<P ALIGN="JUSTIFY">G. Hemley, World Wildlife Fund, 1255 23rd Street, N.W., Washington, D.C. 20037, USA (for trade information)</P>
+<P ALIGN="JUSTIFY">R.W. Henderson, Milwaukee Public Museum, 800 West Wells Street, Milwaukee, Wisconsin 53233 USA</P>
+<P ALIGN="JUSTIFY">J. Higginson, Voluntaria del Cuerpo de Paz, #156 6a Avenida 1-46, Zona 2 Guatemala, Guatemala</P>
+<P ALIGN="JUSTIFY">J.B. Iverson, Department of Biology, Earlham College, Richmond, Indiana 47374, USA S.R. Kellert, School of Forestry and Environmental Studies, Yale University, 205 Prospect Street, New Haven, Connecticut 06511, USA</P>
+<P ALIGN="JUSTIFY">F.W. King, Florida State Museum, University of Florida, Gainesville, Florida 32601, USA</P>
+<P ALIGN="JUSTIFY">G. Larde, Ministerio de Agricultura y Ganaderia Planes de Renderos, Km. 10 Col. Los Angeles 13, CP 01196 San Salvador, El Salvador</P>
+<P ALIGN="JUSTIFY">D. Marcellini, National Zoological Park, Washington, D.C. 20008, USA</P>
+<P ALIGN="JUSTIFY">J.M. Mora, 200 m sur Pulperia la Uni6n, Cinco Esquinas, Carrieal, Alajuela, Costa Rica</P>
+<P ALIGN="JUSTIFY">J.A. Ottenwalder, Parque Zool6gico Nacional, Apartado 2449, Santo Domingo, Dominican Republic</P>
+<P ALIGN="JUSTIFY">G.C. Packard, Department of Zoology, Colorado State University, Fort Collins, Colorado 80523, USA</P>
+<P ALIGN="JUSTIFY">J.J. Perez, Condominio Su. Antonio 7, C. San Antonio Abad, San Salvador, El Salvador</P>
+<P ALIGN="JUSTIFY">J. Phillips, Research Department, San Diego Zoo, Box 551, San Diego, Calffornia 92112, USA</P>
+<P ALIGN="JUSTIFY">D. Werner, Fundacion Pro Iguana Verde, Apa,-tado 1501-3000, Heredia, Costa Rica</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Black Iguana</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H.S. Fitch, Route #3, Box 142, Lawrence, Kansas 66044, USA</P>
+<P ALIGN="JUSTIFY">R.W. Henderson, Milwaukee Public Museum, 800 West Wells Street, Milwaukee, Wisconsin 53233, USA</P>
+<P ALIGN="JUSTIFY">J. Higginson, Voluntaria del Cuerpo de Paz, #156 6a Avenida 1-46, Zona 2 Guatemala, Guatemala</P>
+<P ALIGN="JUSTIFY">D.M. Hillis, Department of Biology, University of Miami, Coral Gables, Florida 33124, USA</P>
+<P ALIGN="JUSTIFY">G. Larde, Ministerio de Agricultura y Ganaderia, Planes de Renderos Km. 10 Col. Los Angeles 13, CP 01196, San Salvador, El Salvador</P>
+<P ALIGN="JUSTIFY">D. Marcellini, National Zoologica, Park, Washington, D.C. 20008, USA</P>
+<P ALIGN="JUSTIFY">J.M. Mora, 200 m sur Pulperita La Union, Cinco Esquinas, Carrieal, Alajuela, Costa Rica</P>
+<P ALIGN="JUSTIFY">G.C. Packard, Department of Zoology, Colorado State University, Fort Collins, Colorado 80523, USA</P>
+<P ALIGN="JUSTIFY">J.J. Perez, Condominio Su. Antonio 7, C. San Antonio Abad, San Salvador, El Salvador</P>
+<P ALIGN="JUSTIFY">J. Phillips, Research Department, San Diego Zoo, Box 551, San Diego, Calffornia 92112, USA</P>
+<P ALIGN="JUSTIFY">D. Werner, Fundacion Pro Iguana Verde, Apartado 1501-3000, Heredia, Costa Rica</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rock Iguana</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. Auffenberg, Florida State Museum, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">D. Auth, Florida State Museum, University of Florida, Gainesville, Florida 32611, USA</P>
+<P ALIGN="JUSTIFY">T.J. Cullen, Cullen Vivarium, 3401 South 16th Street, Milwaukee, Wisconsin 53215 USA</P>
+<P ALIGN="JUSTIFY">A. Ferreira, Parque Zool6gico Nacional, Apartado 2449, Santo Domingo, Dominican Republic </P>
+<P ALIGN="JUSTIFY">R.W. Henderson, Mi]waukee Public Museum, 800 West Wells Street, Milwaukee, Wisconsin 53233, USA</P>
+<P ALIGN="JUSTIFY">J.B. Iverson, Department of Biology, Earlham College, Richmond, Indiana 47374, USA</P>
+<P ALIGN="JUSTIFY">J.A. Ottenwalder, Parque Zool6gico Nacional, Apartado 2449, Santo Domingo, Dominican Republic</P>
+<P ALIGN="JUSTIFY">T.A. Wiewandt, Wild Horizons, Inc., P.O. Box 5118, Tucson, Arizona 85703, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tegu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C.A. Blanco, Direccion Nacional de Fauna Silvestre, Avenida Paseo Colon 922 2&Yacute;piso, (1063) Buenos Aires, Argentina</P>
+<P ALIGN="JUSTIFY">O.K. Donadio, Museo Argentino de Ciencias Naturales, CC 220, Avenida Angel Gallardo 470, Suc. 5, 1405 Buenos Aires, Argentina</P>
+<P ALIGN="JUSTIFY">J.M. Gallardo, Museo Argentino de Ciencias Naturales, CC 220, Avenida Angel Gallardo 470, Suc. 5, 1405 Buenos Aires, Argentina</P>
+<P ALIGN="JUSTIFY">G. Hemley, World Wildlife Fund, 1255 23rd Street, N.W., Washington, D.C. 20037, USA</P>
+<P ALIGN="JUSTIFY">D. Marcellini, National Zoological Park, Washington, D.C. 20008, USA</P>
+<P ALIGN="JUSTIFY">E.L. Marmillon, Casilla de Correo 451, 5800 Rio Cuarto, Argentina</P>
+<P ALIGN="JUSTIFY">G.C. Packard, Department of Zoology, Colorado State University, Fort Collins, Colorado 80523, USA</P>
+<P ALIGN="JUSTIFY">D. Werner, Fundacion Pro Iguana Verde, Apartado 1501-3000, Heredia, Costa Rica</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEES</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Local Agriculture Extension Services and beekeepers are often the best source of information for beginning beekeeping. In addition, the following organizations can provide information: International Bee Research Association, 16/18 North Road, Cardiff CF1 3DY, UK; International Agency for Apiculture Development, 6N 909 Roosevelt, St. Charles, Illinois 60174, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I. Abt, Centre for International Agricultural Development Cooperation, Tel Aviv, Israel M. Adey. International Bee Research Association, 16/18 North Road, Cardiff CFI 3DY, UK</P>
+<P ALIGN="JUSTIFY">S.O. Adjare, Technology Consultancy Centre, University of Science and Technology, Kumasi, Ghana</P>
+<P ALIGN="JUSTIFY">All India Beekeepers' Association, 817 Sadashiv Peth, Poono 411 030, India</P>
+<P ALIGN="JUSTIFY">S.K.N. Atuahene, Forest Product Research Institute (Ghana Forestry Commission), University P.O. Box 63, Kumasi, Ghana</P>
+<P ALIGN="JUSTIFY">H.S. Brar, Department of Entomology, Punjab Agricultural University, Ludhiana 141 004, India</P>
+<P ALIGN="JUSTIFY">N. Bradbear, International Bee Research Association, North Road, Cardiff CFI 3DY, UK</P>
+<P ALIGN="JUSTIFY">D.M. Caron, Department of Entomology and Applied Ecology, University of Delaware, Newark, Delaware 19717, USA</P>
+<P ALIGN="JUSTIFY">B.S. Chahal, Department of Entomology, Punjab Agricultural University, Ludhiana 141 004, India</P>
+<P ALIGN="JUSTIFY">B. Clauss, Beekeeping Survey, Kabompo, Zambia </P>
+<P ALIGN="JUSTIFY">M.P. Coleman, International Agency for Apiculture Development, 6N 909 Roosevelt, St. Charles, Illinois 60174, USA</P>
+<P ALIGN="JUSTIFY">Director, or Resident Bee Specialist, Apiary Studies, Zoological Institute, Leningrad, USSR</P>
+<P ALIGN="JUSTIFY">D. DeJong, Departamento de Genetica, Faculdade de Medicina de Ribeirao Preto, Universidade Sao Paulo, 14.049Ribeirao Preto, Sao Paulo, Brazil</P>
+<P ALIGN="JUSTIFY">R.W. Dutton, Centre for Overseas Research and Development (CORD), University of Durham, South Road, Durham DHI 3LE, UK (Apisflorea) </P>
+<P ALIGN="JUSTIFY">E.H. Erickson, Carl Hayden Bee Research Center, Agricultural Research Service, U.S. Department of Agriculture, 2000 East Allen Road, Tucson, Arizona 85719, USA</P>
+<P ALIGN="JUSTIFY">Faculdade de Medicina de Ribeirao Preto, Departamento de GenTtica, 14100Ribeirao Preto, Sao Paulo, Brazil</P>
+<P ALIGN="JUSTIFY">R.D. Fell, Virginia Polytechnic Institute, Blacksburg, Virginia 24061, USA</P>
+<P ALIGN="JUSTIFY">K. Flottum, Gleanings in Bee Culture, 623 West Liberty Street, P.O. Box 706, Medina, Ohio 44258-0706, USA (editor)</P>
+<P ALIGN="JUSTIFY">J. Free, Rothamstead Experimental Station, Harpenden, Hertfordshire L5 2JQ, UK</P>
+<P ALIGN="JUSTIFY">D. Wolde-Semait Gebre-Wold, P.O. Box 7505, Addis Ababa, Ethiopia</P>
+<P ALIGN="JUSTIFY">C.B. Habarugira, AHO (Apiary), Mbara Stockfarm, Beekeeping Section, P.O. Box 4, Mbarara, Uganda</P>
+<P ALIGN="JUSTIFY">L.A.M. Hassan, Njiro Wildlife (Beekeeping) Research Centre, P.O. Box 661, Arusha, Tanzania</P>
+<P ALIGN="JUSTIFY">R. Hoopingarner, Department of Entomology, University of Michigan, East Lansing, Michigan 48824-1115, USA</P>
+<P ALIGN="JUSTIFY">W.E. Kerr, Departamento de Biolgia, Universidade Federal de UberlGndia, 38400 UberlGndia, Brazil</P>
+<P ALIGN="JUSTIFY">P.G. Kevan, or Resident Bee Specialist, Department of Environmental Biology, University of Guelph, Guelph, Ontario NIG 2WI, Canada</P>
+<P ALIGN="JUSTIFY">K.K. Kigatiia, Beekeeping Branch, Ministry of Agriculture c~ Livestock Development, P.O. Box 30028, Nairobi, Kenya</P>
+<P ALIGN="JUSTIFY">H.C. Killins, 163 Trowbridge Avenue, London, Ontario N6J 3M2, Canada</P>
+<P ALIGN="JUSTIFY">H.M. Kiwuwa, AHL (Apiary), Department of Veterinary Services, Headquarters, Beekeeping Section, P.O. Box 7141, Kampala, Uganda</P>
+<P ALIGN="JUSTIFY">G. Lanarolle, Apiculture Project, Bindunuwewa, Bandarawela, Sri Lanka</P>
+<P ALIGN="JUSTIFY">Y. Lensky, Triwaks Bee Research Center, Hebrew University Faculty of Agriculture, Rehovot 76-100, Israel</P>
+<P ALIGN="JUSTIFY">M.D. Levin, Carl Hayden Bee Research Center, Agricultural Research Service, U.S. Department of Agriculture, 2000 East Allen Road, Tucson, Arizona 85719, USA</P>
+<P ALIGN="JUSTIFY">M. Singh Limbu, Godavari Ashram, GPO Box 50, Kathmandu, Nepal</P>
+<P ALIGN="JUSTIFY">I. Mann, 14 Millimani Road, Box 20360, Nairobi, Kenya</P>
+<P ALIGN="JUSTIFY">R.J. McGinley, Department of Entomology, NHB-105, Smithsonian Institution, Washington, D.C. 20560, USA (Apoidea, except Apis) </P>
+<P ALIGN="JUSTIFY">J. McKay, Peace Corps, American Embassy, Asunci6n, Paraguay</P>
+<P ALIGN="JUSTIFY">C.D. Michener, Snow Entomological Museum, University of Kansas, Lawrence, Kansas 66045, USA</P>
+<P ALIGN="JUSTIFY">R.A. Morse, Department of Entomology, Cornell University, Ithaca, New York 14853, USA</P>
+<P ALIGN="JUSTIFY">J. Morton, Morton Collectanea, University of Miami, Box 248204, Coral Gables, Florida 37724, USA (bee plants)</P>
+<P ALIGN="JUSTIFY">D.G. Mugisa, c/o Insure Consult, P.O. Box 30002, Nakiuubo, Uganda</P>
+<P ALIGN="JUSTIFY">M. Bin Muid, Department of Plant Protection, Faculty of Agriculture, Universiti Pertanian Malaysia, Serdang 43400, Selangor, Malaysia</P>
+<P ALIGN="JUSTIFY">H.C. Mulzac, International Agency for Apiculture Development, 393 Decatur Street, Brooklyn, New York 11233, USA </P>
+<P ALIGN="JUSTIFY">K.S. Najar, Faculty of Agriculture, University of Aleppo, Aleppo, Syria</P>
+<P ALIGN="JUSTIFY">B.E. Nightingale, Box 23, Njoro, Kenya</P>
+<P ALIGN="JUSTIFY">G. Patty, Foreign Agriculture Service, U.S. Department of Agriculture, 6095 South Building, Washington, D.C. 20250, USA</P>
+<P ALIGN="JUSTIFY">L.M. Phiri, Office of Chief Beekeeping Officer, P/BAC Mwekera, Kitwe, Zambia</P>
+<P ALIGN="JUSTIFY">R. Pickard, Zoology Department, University College, P.O. Box 78, Cardiff CFI IXL, South Wales, UK</P>
+<P ALIGN="JUSTIFY">G.W. Robins, GPO Box 50, Kathmandu, Nepal</P>
+<P ALIGN="JUSTIFY">D. Roubik, Stop 105, Museum of Natural History, Smithsonian Institution, Washington, D.C. 20560, USA (stingless bees)</P>
+<P ALIGN="JUSTIFY">D. Sammataro, 7011 Spieth Road, Medina, Ohio 44256, USA (editor, Cornucopia) </P>
+<P ALIGN="JUSTIFY">G. Schechtel, Cnel. Bogado/Itapua, Paraguay</P>
+<P ALIGN="JUSTIFY">H. Shimanuki, Beneficial Insects Laboratory, Agricultural Research Service, U.S. Department of Agriculture, B-476 BARC-East, Beltsville, Maryland 20705, USA</P>
+<P ALIGN="JUSTIFY">O.R. Taylor, Department of Entomology, University of Kansas, Lawrence, Kansas 66045, USA</P>
+<P ALIGN="JUSTIFY">J.E. Tew, Agricultural Technical Institute, Ohio State University, Wooster, Ohio 44691, USA</P>
+<P ALIGN="JUSTIFY">M. Tomasko, Pennsylvania State University, 106 Patterson Building, University Park7 Pennsylvania 16802, USA</P>
+<P ALIGN="JUSTIFY">P. Torchio, Agricultural Research Service, U.S. Department of Agriculture, Bee Laboratory, Utah State University, Logan, Utah 84322-5310, USA</P>
+<P ALIGN="JUSTIFY">R. Wadlow, 8381 San Mateo, Ft. Myers, Florida 33907, USA</P>
+<P ALIGN="JUSTIFY">D.W. Whitehead, International Agency for Apiculture Development, c/o 1000 Connecticut Avenue NW, #707, Washington, D.C. 20036, USA</P>
+<P ALIGN="JUSTIFY">Siriwat Wongsiri, Department of Biology, Chulalongkorn University, Bangkok7 Thailand (Apis cerana) </P>
+<P ALIGN="JUSTIFY">Wu Yan-ru, Department of Insect Taxonomy and Faunistics, Institute of Zoology, Academia Sinica, 7 Zhongguancun Lu, Haitien, Beijing, People's Republic of China </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">C BIOGRAPHICAL SKETCHES OF PANEL MEMBERS</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RALPH W. PHILLIPS retired in 1982 from the post of deputy director general of the Food and Agriculture Organization of the United Nations (FAO), Rome, Italy, a post he held for four years. Among his earlier posts were that of professor and head, Animal Husbandry Department, Utah State University; senior animal husbandman in charge, Genetic Investigations, United States Department of Agriculture (USDA); chief, Animal Production Branch and deputy director, Agriculture Division, FAO; and executive director, International Organization Affairs, USDA. Among his special assignments were: serving as consultant on animal breeding to the governments of China and India for the U.S. Department of State in 1943-44; and as scientific secretary for agriculture of the United Nations Conference on Science and Technology for the Benefit of Developing Countries, in Ceneva, Switzerland, 1962-63. Dr. Phillips holds a B.S. degree in agriculture from Berea College (1930), M.A. (1931) and Ph.D. (1934) degrees from the University of Missouri, and Honorary D.Sc. degrees from Berea College and West Virginia University. He has been awarded the Berea College Distinguished Alumnus Award and the USDA's Distinguished Service Award. He is author or coauthor of some 240 scientific papers, review papers, chapters in books, and books on various aspects of physiology of reproduction, genetics, livestock production, and international agriculture. In his research, writings, and international activities, Dr. Phillips has given particular attention to breeding in relation to the environment and to the identification and conservation of valuable animal genetic resources. He is also the author of a definitive history of FAO entitled FAO: Its Origins, Formation and Evolution, 19451981 and an autobiography, The World Was My Barnyard. </P>
+<P ALIGN="JUSTIFY">EDWARD S. AYENSU is currently senior advisor to the president of the African Development Bank. He is also president of ESA Associates, Washington, D.C., and former director of the Office of Biological Conservation, Smithsonian Institution, Washington, D.C. A citizen of Ghana, he received his B.A. in 1961 from Miami University in Ohio, M.Sc. from The George Washington University in 1963, and his Ph.D. in 1966 from the University of London. His research interests cover many areas of tropical biology. An internationally recognized expert on topics relating to science, technology, and development, especially in developing countries, he has also published extensively on tropical plants. Dr. Ayensu chairs and serves as a member of many international bodies. </P>
+<P ALIGN="JUSTIFY">BONNIE V. BEAVER, professor of small animal medicine and surgery, Texas A&amp;M University, College Station, is a specialist in animal behavior and problem behaviors, especially in domestic and laboratory animals. She received her B.S. and D.V.M. from the University of Minnesota and her M.S. from Texas A&amp;M. In addition to being a popular speaker at scientific meetings, she is the author of five books and numerous book chapters and articles. </P>
+<P ALIGN="JUSTIFY">KURT BENIRSCHKE, professor of pathology and reproductive medicine, University of California at San Diego, received his M.D. from the University of Hamburg, Germany, in 1948. He served on the faculties of Harvard and Dartmouth medical schools before coming to San Diego in 1970. At the San Diego Zoo he initiated a research department to advance knowledge in endangered species and now serves as a trustee of that organization. He has written on comparative mammalian cytogenetics, vanishing species, and human reproductive pathology. </P>
+<P ALIGN="JUSTIFY">ROY D. CRAWFORD is professor of animal and poultry genetics at the University of Saskatchewan, Saskatoon, Saskatchewan, Canada. He received his B.S.A. from the University of Saskatchewan in 1955, his M.S. in animal genetics from Cornell University in 1957, and his Ph.D. in poultry genetics from the University of Massachusetts in 1963. He was employed as a scientist with the Research Branch of Agriculture Canada from 1957 to 1964 in Prince Edward Island and Nova Scotia. He joined the faculty of the University of Saskatchewan in 1964. He was made a fellow of the Agricultural Institute of Canada in 1986 in recognition of his teaching and research work. His research interests include single gene genetics of poultry, and conservation of genetic resources in poultry and livestock. He has discovered and studied many mutants in chickens; some of them have biomedical importance, including one shown to be an animal genetic model of human grand mal epilepsy; some of them are potentially useful in food production, including an albinism mutant that is being developed for autosexing of commercial chicken broilers. He maintains a very large conservation collection of poultry genetic resources at the University of Saskatchewan and has prepared an inventory and assessment of Canada's poultry and livestock genetic resources. Dr. Crawford is a member of the Expert Panel on Animal Genetic Resources Conservation and Management, FAO/UNEP, Rome, and is a member of the Animal Resources Committee, Canadian Council on Animal Care, Ottawa. He serves on the International Scientific Committee for the French journal GTnTtique, STlection, +volution. He is a member of the Rare Breeds Survival Trust (UK) and is a board member of the American Minor Breeds Conservancy (USA). </P>
+<P ALIGN="JUSTIFY">TONY J. CUNHA, distinguished service professor emeritus, University of Florida, Gainesville, and dean emeritus, California State Polytechnic University, Pomona, received his Ph.D. at the University of Wisconsin in 1944. He has given more than 100 lectures in livestock feeding and nutrition in 40 foreign countries. He served as chairman of the Animal Nutrition Committee of the National Academy of Sciences and as a member of the NAS-NRC Board of Agriculture and Renewable Resources, Latin American Science Board, and as chairman of the livestock committee of two world food studies by NAS-NRC. He served as a member of the organizing committee for the first two World Conferences on Animal Production in Rome (1963) and Washington, D.C. (1968). He served as a member of the Title XII Board of International Food and Agricultural Joint Committee on Research and as chairman of its research priorities committee 1977-1981. He is author, editor, coeditor, or contributor to 30 books and author of more than 1,423 scientific and professional articles. He is a winner of 42 campus, state, national, and international honors and awards. </P>
+<P ALIGN="JUSTIFY">DAVID E. DEPPNER, director of Trees for the Future in Silver Spring, Maryland, has been a consultant for international development projects involving livestock and poultry management and marketing for the past 14 years. He has served in 17 countries of Asia, Africa, and Central America. He has written on processing livestock rations under tropical conditions and about the Madurese breed of cattle found in East Java, Indonesia, where he spent two years studying this ancient breed. He is currently providing technical assistance to projects in several countries for the development of improved forage production as an answer to destruction of natural resources of tropical uplands caused by overgrazing. He received his B.Sc. in animal science from Ohio State University in 1954 and M.Sc. in livestock economics from Araneta University, the Philippines, in 1977. </P>
+<P ALIGN="JUSTIFY">ELIZABETH L. HENSON is the director of the American Minor Breeds Conservancy, based in Pittsboro, North Carolina. She received an M.A. in zoology from Oxford University in 1980 and an M.Sc. in domestic animal breeding from Edinburgh University in 1981. Her primary interests are in the conservation of rare and endangered breeds and varieties of domestic livestock as a genetic resource for changing agricultural needs. She represented Britain at the first international conference on domestic animal conservation in Hungary in 1982, and was a member of the Office of Technology Assessment Committee on grassroots strategies to maintain genetic diversity in 1985. She is executive secretary for four British breed associations and is a member of the British Rare Breeds Survival Trust Technical Panel. </P>
+<P ALIGN="JUSTIFY">DONALD L. HUSS was regional animal production officer of the FAO Regional Office for Latin America and the Caribbean, Santiago, Chile, before his retirement. He received a B.S. in 1949, an M.A. in 1954, and a Ph.D. in 1959, all at Texas A&amp;M University. He was assistant professor of range management at Texas A&amp;M before joining the Food and Agricultural Organization of the United Nations (FAO) in 1967. He founded the FAO Regional Office's Small Animals for Small Farms programme in 1980. Professional assignments and travels in Latin America, the Caribbean' Near and Middle East, and Africa have contributed to his knowledge and experience in microlivestock development. Dr. Huss was recognized by Texas A&amp;M University by being chosen as the recipient of the Memorial Student Center Appreciation and Distinguished Service Awards in 1958 and 196O, respectively, and Honour Professor in the College of Agriculture in 1966 67. He also received the Society for Range Management's Outstanding Service and Achievement Award in 1975 and its Fellow Award in 1978. </P>
+<P ALIGN="JUSTIFY">DAVID RICHARD LINCICOME has been a guest scientist with the Animal Parasitology Institute, United States Department of Agriculture Experiment Station, Beltsville, Maryland, since 1978, having retired as professor of parasitology, Howard University, Washington, D.C., in 1970. He received the B.S. and M.S. degrees cum laude simultaneously in 1937 from the University of Illinois and a Ph.D. in tropical medicine from the Tulane Medical School, New Orleans, Louisiana, in 1941. His principal research interests have centered around morphologic studies on Acanthocephala, molecular exchanges of dependent cells and their environments, and diagnosis of parasitic diseases. He has been a breeder of Nubian and American pygmy goats for the past 20 years. Dr. Lincicome is currently a member of the Board of Directors of the American Dairy Goat Association and is past president of the National Pygmy Goat Association. He was founder and long time trustee of the American Dairy Goat Association Research Foundation. He is also past president of the Helminthological Society and currently serves the society as archivist. He received the Helminthological Society's Anniversary Award in 1975. He was founder and, for 27 years, editor of the journal Experimental Parasitology, and is the author and editor of more than 180 scientific contributions. </P>
+<P ALIGN="JUSTIFY">THOMAS E. LOVEJOY is a tropical biologist and ornithologist. He is assistant secretary for external affairs, Smithsonian Institution' Washington, D.C. He was formerly executive vice president for the World Wildlife Fund-U.S., chairman of the Wildlife Preservation Trust International, and a member of two commissions of the International Union for the Conservation of Nature and Natural </P>
+<P ALIGN="JUSTIFY">Resources. At present, Dr. Lovejoy is a principal investigator of the world's largest controlled ecological experiment, which is attempting to determine the optimum size for parks and reserves. This project, conceived and designed by Dr. Lovejoy, is called "the Minimum Critical Size of Ecosystems" and is a joint program of World Wildlife Fund-U. S. and Brazil's National Institute for Amazon Research. Dr. Lovejoy is also the principal advisor for NATURE (WNET/THIRTEEN, New York), a series that he started in 1980. As principal advisor, he recommends program content and oversees the factual accuracy of the program scripts. A member of 11 scientific societies, Dr. Lovejoy has received grants from 16 foundations and institutions and written more than 100 articles for various national and International publications. He has published three books, Key Environments, Pergamon Press, Oxford; Nearctic Avian Migrants in the Neotropics, a Department of the Interior publication; and Conservation of Tropical Forest Birds, an ICPB publication. He is currently working on The Magnificent Exception, a book on people and the biosphere.</P>
+<P ALIGN="JUSTIFY">ARNE W. NORDSKOG is professor emeritus, Department of Animal Science, Iowa State University. He received his B.S., M.S., and Ph.D. degrees from the University of Minnesota between 1937 and 1943. His training and principal area of research has been in quantitative genetics, but by about 1960 his interests shifted to immunogenetics and more recently to molecular genetics. He has traveled widely, spending two years as an instructor in agriculture at the University of Alaska (1937-39), and has been an NSF Research Fellow at Cal Tech (1960), a visiting professor at the University of Minnesota (1966), an FAO lecturer at the Indian Veterinary Institute (1973), and an FAO-sponsored lecturer on poultry breeding in China (1979). He has acted as a consultant to a commercial breeder in Japan for 20 years. He has been the major professor at Iowa State for more than 60 M.S. and Ph.D. candidates and has published more than 150 scientific papers. Dr. Nordskog is an honorary member of the Norwegian Poultry Breeding Association, a fellow of the Poultry Science Association, and a fellow of the AAAS. In 1972, he was the recipient of the Poultry Science Distinguished Service Research Award. </P>
+<P ALIGN="JUSTIFY">LINDA M. PANEPINTO, swine research consultant, was director of the Colorado State University Swine Laboratory through 1988. She earned her B.S. in animal sciences at Colorado State University in 1972. In 1973 she joined the research team developing Yucatan miniature swine at Colorado State University, where she was given primary responsibility for colony management, protocol development, and genetic selection programs. In 1977, she designed an experimental research program for the development of a line of Yucatan pigs with a genetic propensity for exceptionally small size. She has continued her work in that area and has developed the Yucatan Micropig, described elsewhere in this publication. Her other major professional area of interest has been the design of facilities and equipment for swine with emphasis on animal comfort and minimizing stress. Her invention, known as the Panepinto Sling, has been widely adopted as the primary restraint method for numerous medical schools and research facilities using swine in the laboratory. She has published extensively in the field.</P>
+<P ALIGN="JUSTIFY">KURT J. PETERS is professor of animal breeding and husbandry in the tropics and subtropics, University of Gottingen, and is currently director of research at the International Livestock Centre for Africa. He received his Dr. Agr. degree from the Technical University of Berlin in 1975. He has undertaken research in livestock production development in Southeast Asia and Africa. The major focus of his research has been small animals, with special attention given to the potential of unconventional animals. Early in 1985 he assumed his present position directing research at the International Livestock Centre for Africa. </P>
+<P ALIGN="JUSTIFY">JOHN A. PINO is a senior fellow of the National Research Council, Board on Agriculture, and is currently the project director of the study "Managing Global Genetic Resources: Agricultural Imperatives." He received his B.S. in agriculture in 1944-47 and Ph.D. in zoology in 1951 from Rutgers University. As an associate professor he taught and did research in the Department of Poultry Science at Rutgers until 1955 when he accepted a position with the Rockefeller Foundation as animal scientist with the Mexican Agricultural Program, becoming the associate director of that program in 1960. In 1965 he was transferred to the Rockefeller headquarters in New York and became director of the Agricultural Science Program in 1970. Most of his career has been in international agricultural development. He retired from the Foundation in 1983 and went to Washington to become agricultural science advisor at the InterAmerican Development Bank until July 1986 when he accepted his present position. Dr. Pino has been a member of the Board on Agriculture since 1983 and previously from 1973 to 1977. </P>
+<P ALIGN="JUSTIFY">HUGH POPENOE is professor of soils, agronomy, botany, and geography, and director of the Center for Tropical Agriculture and International Programs (Agriculture) at the University of Florida. He received his B.S. from the University of California at Davis in 1951 and his Ph.D. in soils from the University of Florida in 1960. His principal research interest has been in the area of tropical agriculture and land use. His early work on shifting cultivation is one of the major contributions to this system. He has traveled and worked in most of the countries in the tropical areas of Latin America, Asia, and Africa. His current interests include improving indigenous agricultural systems of small landholders, particularly with the integration of livestock and crops. He was chairman of the Advisory Committee on Technology Innovation and a member of the Board on Science and Technology for International Development (under whose aegis this report is presented). He chaired the BOSTID report panels on water buffalo and little-known Asian animals. Currently, he is on the International Advisory Committee of the National Science Foundation and serves as U.S. Board Member for the International Foundation of Science.</P>
+<P ALIGN="JUSTIFY">MICHAEL HILL ROBINSON, director of the Smithsonian Institution's National Zoological Park, is an animal behaviorist and a tropical biologist. Before his appointment to the National Zoo, Dr. Robinson served as deputy director of the Smithsonian Tropical Research Institute in Panama, which he joined in 1966 as a tropical biologist. He received his Ph.D. from Oxford University after being awarded his B.S., summa cum laude, from the University of Wales. His scientific interests include predator-prey interactions, evolution of adaptations, tropical biology, courtship and mating behavior, phenology of arthropods, and freshwater biology. In the course of his studies, Dr. Robinson has done research in the United States and throughout the developing world. Recent publications include articles on predator-prey interactions, tropical forest conservation, reproductive behavior in spiders, and the function and purpose of zoos in relation to education and conservation. Dr. Robinson's favorite animals are cats, of all kinds. </P>
+<P ALIGN="JUSTIFY">KNUT SCHMIDT-NIELSON, J.B. Duke Professor of Physiology in the Department of Zoology at Duke University, has studied animal responses to extreme environmental conditions. His major emphasis has been on life in hot deserts, and he is widely recognized for his studies of camels and other desert animals. His research has involved field studies in North and South America, Africa, Asia, and Australia. Dr. Schmidt-Nielson has written several books, which have been translated into more than a dozen languages, and he has published several hundred research papers. He has been elected to the National Academy of Sciences, the Royal Society, the French Academie des Sciences, and several other academies. </P>
+<P ALIGN="JUSTIFY">ALBERT E. SOLLOD, is associate professor and head of the international veterinary medicine section at Tufts University School of Veterinary Medicine. He is currently stationed in Niger as chief of party of the integrated livestock project and policy advisor in the Ministry of Animal Resources. He has consulted in 15 countries in Africa and Asia, and his research interests include interdisciplinary systems analysis, indigenous pastoral technologies, monitoring change in agricultural production systems, and monitoring and assessing drought impact.</P>
+<P ALIGN="JUSTIFY">LEE M. TALBOT received his Ph.D. in geography and ecology from the University of California at Berkeley in 1963 and has worked on environmental and natural resource ecology and management in over 110 countries. At present he is visiting fellow at the World Resources Institute, Washington, D.C., and senior environmental consultant to the World Bank. He carried out pioneering research in Africa and elsewhere on the use of wild animals for food production. He has written more than 180 scientific and technical publications, including ten books and monographs. </P>
+<P ALIGN="JUSTIFY">CLAIR E. TERRILL, animal scientist, collaborator, Agricultural Research Service, United States Department of Agriculture (USDA), Beltsville, Maryland, received his Ph.D. from the University of Missouri in 1936, served briefly at the Georgia Agricultural Experiment Station, and joined the USDA at the U.S. Sheep Experiment Station, Dubois, Idaho, in the same year. His research concerned genetics and reproduction of sheep, leading to national and international responsibility regarding research and production of sheep, goats, and other animals, with primary emphasis on increasing efficiency of production of meat, wool, and other products. </P>
+<P ALIGN="JUSTIFY">CHRISTIAN M. WEMMER is assistant director for conservation and captive breeding programs at the National Zoological Park and is also in charge of the zoo's 3,100 acre Conservation and Research Center in Front Royal, Virginia. He is vice chairman of the IUCN Deer Specialist Group and a member of the Mustelid and Viverrid Specialist Group of the same organization. His interest in evolutionary and conservation biology has been motivated by frequent travel to South Asia and his role as scientific coordinator of the Smithsonian Nepal Terai Ecology Project. For the past 12 years he has coordinated the development of facilities and programs at the Conservation and Research Center and with Dr. R. Rudran has promoted conservation training and wildlife research in developing nations. He has published over 50 papers on various aspects of mammalian biology and conservation and has co-edited with Benjamin Beck one book on PFre David's deer. His edited volume "The Biology and Management of the Cervidae" was published by the Smithsonian Institution Press. </P>
+<P ALIGN="JUSTIFY">DANNY C. WHARTON is associate curator, Animal Departments, at New York Zoological Park, Bronx, New York. He received a B.S. from the College of Idaho and an M.Sc. in 1975 from the School for International Training in Brattleboro, Vermont. His Ph.D. in biology was earned at Fordham University. Dr. Wharton was a Peace Corps volunteer to Ecuador 1969-71 and a Fulbright scholar to Germany 1976-77. His research interests have been in the genetic and demographic management of small populations. He works on several committees including the IUCN/SSC Captive Breeding Specialist Group, Species Survival Plan Committee of the American Association of Zoological Parks and Aquariums, and is species chairman for the North American Propagation Group for the Snow Leopard.</P>
+<P ALIGN="JUSTIFY">CHARLES A. WOODS IS curator of mammals at the Florida State Museum and a professor of zoology at the University of Florida. He received his B.S. in zoology from the University of Denver and his Ph.D. in zoology from the University of Massachusetts. He worked at the University of Vermont from 1970 to 1979 when he assumed his present position at the University of Florida. His principle research interests have been in the areas of mammalian ecology (Rodentia) and systematics and evolution and he is especially concerned with island biology. He has spent many years working in the West Indies on a variety of projects and has worked closely with the government of Haiti in establishing a plan for the National Parks of Haiti and in completing a biogeophysical inventory of the natural resources of Hispaniola. He is the ecological consultant for the Institut de Sauvegarde du Patrimoine National in Haiti. He is the author of a number of scientific articles on the fauna of the Antilles including a multivolume series on the fauna of the mountains of Haiti. </P>
+<P ALIGN="JUSTIFY">THOMAS M. YUILL is associate dean for research and graduate training of the School of Veterinary Medicine, assistant director of the Agricultural Experiment Station, and professor of pathobiology and of veterinary science at the University of Wisconsin-Madison. He received his B.S. in wildlife management from Utah State University in 1959 and his Ph.D. jointly in veterinary science and wildlife ecology in 1964 from the University of Wisconsin. His principal research interests are animal health and diseases of wildlife, including those transmissible to domestic animals and to man. He worked in Thailand for two years and has had active research programs in Colombia for 17 years, and Costa Rica for 5 years. He has recently become involved in animal health and production development in the Gambia, West Africa. Dr. Yuill is an executive committee member and immediate past president of the Organization for Tropical Studies and currently serves as president of the Wildlife Disease Association. He completed a five-year term as Chairman of the U.S. Virus Diseases Panel of the U.S.-Japan Cooperative Biomedical Sciences Program. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Board on Science and Technology for International Development (BOSTID)</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ALEXANDER SHAKOW, Director, Strategic Planning and Review,</P>
+<P ALIGN="JUSTIFY">The World Bank, Washington, D.C., Chairman</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Members</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PATRICIA BARNES-MCCONNELL, Director, Bean/Cowpea CRSP, East Lansing, Michigan</P>
+<P ALIGN="JUSTIFY">JORDAN J. BARUCH, President, Jordan Baruch Associates, Washington, D.C.</P>
+<P ALIGN="JUSTIFY">PETER D. BELL, President, The Edna McConnell Clark Foundation, New York, New York</P>
+<P ALIGN="JUSTIFY">BARRY BLOOM, Professor, Department of Microbiology, Albert Einstein College of Medicine, The Bronx, New York</P>
+<P ALIGN="JUSTIFY">JANE BORTNTCK, Assistant Chief, Congressional Research Service, Library of Congress, Washington, D.C.</P>
+<P ALIGN="JUSTIFY">GEORGE T. CURLIN, The National Institute of Allergy and Infectious Diseases, The National Institutes of Health, Bethesda, Maryland</P>
+<P ALIGN="JUSTIFY">DTRK FRANKENBERG, Director, Marine Sciences Program, University of North Carolina, Chapel Hill, North Carolina</P>
+<P ALIGN="JUSTIFY">RALPH HARDY, Boyce-Thompson Institute for Plant Research, Cornell University, Ithaca, New York</P>
+<P ALIGN="JUSTIFY">FREDERICK HORNE, Dean, College of Sciences, Oregon State University, Corvallis, Oregon</P>
+<P ALIGN="JUSTIFY">ELLEN MESSER, Allan Shaw Feinstein World Hunger Program, Brown University, Providence, Rhode Island</P>
+<P ALIGN="JUSTIFY">CHARLEs C. MUSCOPLAT, Executive Vice President, Molecular Genetics, Inc., Minneapolis, Minnesota</P>
+<P ALIGN="JUSTIFY">JAMES QUINN, Amos Tuck School of Business, Dartmouth College, Hanover, New Hampshire </P>
+<P ALIGN="JUSTIFY">VERNON RUTTAN, Regents Professor, Department of Agriculture and Applied Economics, Saint Paul, Minnesota</P>
+<P ALIGN="JUSTIFY">ANTHONY SAN PIETRO, Professor of Plant Biochemistry, Department of Biology, Bloomington, Indiana</P>
+<P ALIGN="JUSTIFY">ERNEST SMERDON, College of Engineering and Mines, University of Arizona, Tucson, Arizona</P>
+<P ALIGN="JUSTIFY">GERARD P. DINEEN, Foreign Secretary, National Academy of Engineering, National Research Council, Washington, D.C., ex officio </P>
+<P ALIGN="JUSTIFY">JAMES B. WYNGAARDEN, Foreign Secretary, National Academy of Sciences, National Research Council, Washington, D.C., ex officio </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Board on Science and Technology for International Development Publications and Information Services (H A-476E)</P>
+<P ALIGN="JUSTIFY">Office of International Affairs</P>
+<P ALIGN="JUSTIFY">National Research Council</P>
+<P ALIGN="JUSTIFY">2101 Constitution Avenue, N.W.</P>
+<P ALIGN="JUSTIFY">Washington, D.C. 20418 U SA</P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<!--
+</Section>
+</Section>
+-->
+</BODY>
+</HTML>
Index: /gsdl/stable/collect/demo/import/b17mie/metadata.xml
===================================================================
--- /gsdl/stable/collect/demo/import/b17mie/metadata.xml	(revision 20131)
+++ /gsdl/stable/collect/demo/import/b17mie/metadata.xml	(revision 20131)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE DirectoryMetadata SYSTEM "http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd">
+<DirectoryMetadata>
+    <FileSet>
+        <FileName>.*</FileName>
+        <Description>
+            <Metadata name="dls.Title">Microlivestock - Little-Known Small Animals with a Promising Economic Future (b17mie)</Metadata>
+            <Metadata mode="accumulate" name="dls.Language">English</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Animal Husbandry and Animal Product Processing|Other animals (micro-livestock, little known animals, silkworms, reptiles, frogs, snails, game, etc.)</Metadata>
+            <Metadata mode="accumulate" name="dls.Organization">BOSTID</Metadata>
+            <Metadata mode="accumulate" name="dls.Keyword">introduce small animals and micro-livestock in your farm</Metadata>
+        </Description>
+    </FileSet>
+</DirectoryMetadata>
Index: /gsdl/stable/collect/demo/import/b18ase/b18ase.htm
===================================================================
--- /gsdl/stable/collect/demo/import/b18ase/b18ase.htm	(revision 20131)
+++ /gsdl/stable/collect/demo/import/b18ase/b18ase.htm	(revision 20131)
@@ -0,0 +1,2966 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META NAME="Generator" CONTENT="Microsoft Word 97">
+<TITLE>&lt;&lt;TOC1&gt;&gt; Little Known Asian Animals With a Promising Economic Future</TITLE>
+</HEAD>
+<BODY>
+
+<B><FONT FACE="Arial" SIZE=2><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Little Known Asian Animals With a Promising Economic Future</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Report of an Ad Hoc Panel of the Advisory Committee on Technology Innovation Board on Science and Technology for International Development Office of International Affairs National Research Council </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Acknowledgments</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NATIONAL ACADEMY PRESS</P>
+<P ALIGN="JUSTIFY">Washington, D.C. 1983</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NOTICE: The project that is the subject of this report was approved by the Governing Board of the National Research Council, whose members are drawn from the Councils of the National Academy of Sciences, the National Academy of Engineering, and the Institute of Medicine. The members of the Committee responsible for the report were chosen for their special competences and with regard for appropiate balance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report has been reviewed by a group other than the authors according to procedures approved by a Report Review Committee consisting of members of the National Academy of Sciences, the National Academy of Engineering, and the Institute of Medicine.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The National Research Council was established by the National Academy of Sciences in 1916 to associate the broad community of science and technology with the Academy's purposes of furthering knowledge and of advising the federal government. The Council operates in accordance with general policies determined by the Academy under the authority of its congressional charter of 1863, which establishes the Academy as a private, nonprofit, self-governing membership corporation. The Council has become the principal operating agency of both the National Academy of Sciences and the National Academy of Engineering in the conduct of their services to the government, the public, and the scientific and engineering communities. It is administered jointly by both Academies and the Institute of Medicine. The National Academy of Engineering and the Institute of Medicine were established in 1964 and 1970, respectively, under the charter of the National Academy of Sciences.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Board on Science and Technology for International Development (BOSTID) of the Office of International Affairs addresses a range of issues arising from the ways in which science and technology in developing countries can stimulate and complement the complex processes of social and economic development. It oversees a broad program of bilateral workshops with scientific organizations in developing countries and conducts special studies. BOSTID's Advisory Committee on Technology Innovation publishes topical reviews of technical processes and biological resources of potential importance to developing countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report has been prepared by an ad hoc advisory panel of the Advisory Committee on Technology Innovation, Board on Science and Technology for International Development, Office of International Affairs, National Research Council. Program costs for the study were provided by the Office of Technical Resources, Bureau for Asia, Agency for International Development, under Grant No. ASB-0249-SS-00-1026-00 and the Office of the Science Advisor, Agency for International Development, under Grant No. DAN/ 5538-G-SS-1023-00.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Funding for this printing was provided by the Office of Agriculture, Bureau for Science and Technology, Agency for International Development, Washington, D.C., under Grant No. DAN 1406-G-SS-4001-00.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">First Printing, June 1983</P>
+<P ALIGN="JUSTIFY">Second Printing, July 1984</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Library of Congress Catalog Card Number 83-061909</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Participants in the Study</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUGH POPENOE, Director, International Programs in Agriculture, University of Florida, Gainesville, Florida, USA, Chairman </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Contributors </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AMBAR ROESYAT, Research Institute for Animal Husbandry, Bogor, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">1. B. ARKA, Faculty of Veterinary Science and Animal Husbandry, Udayana University, Bali, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. S. F. BARKER, Professor of Animal Sciences and Head of Department, The University of New England, Armidale, New South Wales, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">KURT BENIRSCHKE, Research Department, San Diego Zoological Garden, San Diego, California, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BEN BERESKIN, Research Geneticist, Nonruminant Animal Nutrition Laboratory, Animal Science Institute, United States Department of Agriculture, Beltsville, Maryland, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RALEIGH A. BLOUCH, World Wildlife Fund, Bogor, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. BONGERS, Nature Conservation Department, Wageningen Agricultural University, Wageningen, The Netherlands </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I. BONNEMAIRE, Ecole Nationale Superieure des Sciences Agronomiques Appliquees, Dijon, France </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. A. BOSMA, Vakgroep Funktionele Morfologie, Rijksuniversiteit, Utrecht, The Netherlands </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D. BUTCHER, Assistant Director, Western Plains Zoo, Dubbo, New South Wales, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">G. S. CHILD, Wildlife and Parks Management Officer, Food and Agriculture Organization, Rome, Italy </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. ROSS COCKRILL, International Animal Consultant, Almansil, Algarve, Portugal </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PAUL CONRY, Division of Aquatic and Wildlife Resources, Department of Agriculture, Guam </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HAROLD J. COOLIDGE, Former President, International Union for the Conservation of Nature, Beverly, Massachusetts, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. P. CROWCROFT, General Director, Metropolitan Zoo, Toronto, Canada </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">TONY J. CUNHA, Dean Emeritus, California State Polytechnic University, Pomona, California, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D. DEPPNER, Tropical Livestock Consultant, Washington, D.C., USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. DEVENDRA, Head, Feed Resources and Animal Nutrition Branch, Malaysian Agricultural Research and Development Institute, Selangor, Malaysia </P>
+<P ALIGN="JUSTIFY">J. M. DOLAN, San Diego Zoological Garden, San Diego, California, USA DUKUT SULARSASA, Department of Tropical Veterinary Science, James Cook University, Townsville, Queensland, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. EPSTEIN, Faculty of Agriculture, The Hebrew University of Jerusalem, Tel Aviv, Israel (retired) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">T. FINNIE, Taronga Zoo, Mosman, New South Wales, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. FISCHER, Director, Institute of Tropical Veterinary Medicine, JustusLiebig-Universitat, Giessen, Federal Republic of Germany </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">IAN FLETCHER, Project for Animal Research and Development, Bogor, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ANNIE P. GRAY, Commonwealth Bureau of Animal Breeding and Genetics, Edinburgh, Scotland (retired) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">R. B. GRIFFITHS, Director, Animal Production and Health Division, Food and Agriculture Organization, Rome, Italy </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">1. R. GRiMWOOD, Nairobi, Kenya </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">COLIN P. GROVES, Australian National University, Canberra, A.C.T., Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ULRICH HALDER, Swiss League for Nature Conservation, Basel, Switzerland </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CHARLES G. HICKMAN, Livestock Consultant, A. Mithat Efendi Sokak No. 36/11, Cankaya, Ankara, Turkey </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D. HOFFMAN, Veterinarian, Project for Animal Research and Development, Bogor, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. H. G. HOLMES, Department of Agriculture and Forestry, University of Melbourne, Victoria, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. HUITEMA, Veterinarian, Osterbeek, The Netherlands </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. H. HUTASOIT, Director-General, Livestock Services, Jakarta, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BENT JORGENSEN, Director, Copenhagen Zoo, Copenhagen, Denmark </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NAT KlEFFER, Department of Animal Science, Texas A&amp;M University, College Station, Texas, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">F. WAYNE KING, Director and Professor, Florida State Museum, University of Florida, Gainesville, Florida, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GRAHAM W. M. KIRBY, Principal Animal Production Officer, Department of Primary Production, Darwin, Northern Territory, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HEINZ-GEORG KLOS, Director, Zoologischer Garten, Berlin, West Germany </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">KUSMAT TANUDIMADJA, Professor of Veterinary Anatomy, Faculty of Veterinary Medicine, Institut Pertanian, Bogor, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN K. LOOSLI, Department of Animal Science, University of Florida, Gainesville, Florida, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN A. LUKAS, White Oak Plantation, Yulee, Florida, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. A. MACDONALD, Vakgroep Funktionele Morfologie, Rijksuniversiteit, Utrecht, The Netherlands </P>
+<P ALIGN="JUSTIFY">JOHN MACKINNON, Representative, World Wildlife Fund, Bogor, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROBERT E. McDOWELL, Professor, Department of Animal Science, Cornell University, Ithaca, New York, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JEFFREY A. McNEELY, Executive Officer, Commission on National Parks and Protected Areas, International Union for Conservation of Nature and Natural Resources, Gland, Switzerland </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ADRIAN G. MARSHALL, Honorary Secretary, Institute of South-east Asian Biology, Department of Zoology, University of Aberdeen, Scotland </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">[AN L. MASON, Animal Breeding Consultant, Edinburgh, Scotland </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GEERT MONTSMA, Vakgroepen Veefokkerij, Veehouderij, Tropische Veehouderij, Wageningen, The Netherlands </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. B. MORAN, Senior Research Officer, Animal and Irrigated Pastures Research Institute, Kyabram, Victoria, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROBERT H. MILLER, Chief, Milk Secretion and Mastitis Laboratory, Beltsville, Maryland, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JAN NARI, Director, Central Research Institute for Animal Science, Bogor, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HARVEY NEESE, President, Agri-Food Systems International, Inc., Troy, Idaho, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I. M. NITIS, Department of Animal Nutrition and Tropical Pasture Production, Udayana University, Denpasar, Bali, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM L. R. OLIVER, Chairman, lUCN/SSC Pigs and Peccaries Specialist Group, Jersey, Channel Islands, United Kingdom </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN PAYNE, Wildlife Section, Forest Department, Sandakan, Sabah, Malaysia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W.J.A. PAYNE, Tropical Animal Breeding Consultant, London, England </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RALPH W. PHILLIPS, Arlington, Virginia, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DONALD L. PLUCKNETT, Scientific Advisor, Consultative Group on International Agricultural Research, Washington, D.C., USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DAVID W. ROBINSON, Associate Dean, International Programs, University of California, Davis, California, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PATRICK J. ROBINSON, Department of Agricultural and Forest Sciences, University of Oxford, Oxford, England </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D. H. L. ROLLINSON, Animal Production Officer, Animal Production and Health Division, Food and Agriculture Organization of the United Nations, Rome, Italy </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CLIVE ROOTS, Director, Assiniboine Park Zoo, Winnipeg, Manitoba, Canada </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. A. SAYER, Nature Conservation and National Parks Project, FAO, Rangoon, Burma </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">R. E. SATTER, Nature Conservation and National Parks Project, FAO, Rangoon, Burma </P>
+<P ALIGN="JUSTIFY">GEORCE B. SCHALLER, New York Zoological Society, New York, New York, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN SCHOTTLER, Principal Animal Production Officer, Department of Primary Industry, Lae, Papua New Guinea </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GEORGE SEIFERT, CSIRO, Rockhampton, Queensland, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROGER V. SHORT, Professor of Reproductive Biology, Monash University, Melbourne, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. C. SINHA, Outdoor Recreation and Wildlife Research Division, Forest Research Institute, College, Laguna, Philippines </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FREDERICK J. SIMOONS, Professor, Department of Geography, University of California, Davis, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. D. SIMPSON, Senior Extension Specialist, Department of Agricultural, Technical and Extension Services, Bulawayo, Zimbabwe </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">P. SITORUS, Research Institute for Animal Production, Bogor, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. J. SMITH, Royal School of Veterinary Studies, University of Edinburgh, Edinburgh, Scotland </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D. J. STOLP-DIEPEVEEN, Department of Tropical Animal Production, Agricultural University, Wageningen, The Netherlands </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SUBANDRlYO, Research Institute for Animal Production, Bogor, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. SUMADI, Faculty of Animal Husbandry, Gadjah Mada University, Yogyakarta, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">L. M. TALBOT, World Wildlife Fund International, Gland, Switzerland </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WARREN D. THOMAS, Director, Los Angeles Zoo, Los Angeles, California, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. L. THROP, Director, Taronga Zoo, Mosman, New South Wales, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ALLEN D. TILLMAN, Private Consultant in Animal Production, Stillwater, Oklahoma, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DONALD G. TULLOCH, Division of Wildlife Research, CSIRO, Winnellie, Northern Territory, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HELEN NEWTON TURNER, Genetics Research Laboratories, CSIRO, North Ryde, New South Wales, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">B. VAN PUIJENBROECK, Curator of Mammals, Royal Zoological Society of Antwerp, Antwerp, Belgium </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">E. J. WARWICK, Visiting Professor, Faculty of Animal Husbandry, Gadjah Mada University, Yogyakarta, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WARTOMO HARDJOSUBROTO, Lecturer in Animal Husbandry, Faculty of Animal Husbandry, Gadjah Mada University, Yogyakarta, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">R. H. WHARTON, Chief Research Scientist, CSIRO, Long Pocket Laboratories, Brisbane, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. L. WHEELER, Project Manager, Project for Animal Research and Development, Bogor, Indonesia </P>
+<P ALIGN="JUSTIFY">M.H. WOODFORD, Wildlife Veterinarian, Food and Agriculture Organization, Rome, Italy </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">B.A.YOUNG, Department of Animal Science, the University of Alberta, Edmonton, Canada </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M.ZULBARDI, Research Institute for Animal Production, Bogor, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NOEL D. VIETMEYER, Professional Associate, Board on Science and Technology for International Development, Asian Animals Study Director </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">National Research Council Staff</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">F. R. RUSKIN, BOSTID Editor </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MARY JANE ENGQUIST, Staff Associate </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CONSTANCE RECKS, Administrative Secretary </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">It is high time that the world was made aware of the valuable, large ruminant genetic resources of Southeast Asia.</P>
+<P ALIGN="JUSTIFY">J. B. MORAN Livestock Specialist Animal and Irrigated Pastures Research Institute Kyabram, Victoria, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Without utilization preservation is doomed to failure. Local breeds able to perform well in difficult habitats, such as in sparse vegetation, mountainous terrain, or the tropics, should be used for their agricultural potential. Breeds that demonstrate hybrid vigor on crossing with improved or exotic breeds also merit utilization. Genetically unique breeds should be retained for scientific studies of genetics, evolution, and biochemistry. And aesthetically attractive and historically important breeds should be maintained in parks and preserves for their educational and cultural values.</P>
+<P ALIGN="JUSTIFY">I. L. MASON Animal Breeding Consultant Edinburgh. Scotland </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p00.png"></center><br>
+ YAK</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Preface</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report began as a brief examination of the domesticated banteng, a little studied bovine that is an important livestock resource in eastern Indonesia. But the study expanded to include other possibly useful but obscure bovines of Asia: the madura (a hybrid between banteng and cattle), gaur, mithan, kouprey, anoa, tamaraw, yak, and yakowshybrids formed by crossing yaks with cattle. Four pig species were also included (the bearded pig, the Sulawesi warty pig, the Javan warty pig, and the pygmy hog) that are important traditional resources in parts of Asia, as well as the babirusaa piglike, wild animal of Sulawesi that may have a rudimentary rumen. (Asia also has some interesting, little-known breeds of cattle, water buffalo, sheep, goats, and the common pig, but in this report we have chosen to highlight unconventional species only.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">These animals are unfamiliar to international animal science. This report aims to kindle awareness of their possible promise and to stimulate their introduction into projects in the world's animal research facilities. Only through active investigation will the potential of these species - most of which are now familiar only to a small number of wildlife specialists - become clear. Many are threatened with extinction; their genetic merits should be assessed before it is too late.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Development agencies and governments in the tropics should regard local species, such as those described in this report, as important genetic material for bolstering the long-term success of domestic livestock breeding programs. These indigenous resources can probably be improved genetically to compare favorably with imported livestock, particularly in difficult tropical environments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report was prepared after Hugh Popenoe, Chairman of the Advisory Committee on Technology Innovation (ACTI), and Noel Vietmeyer of the ACT! staff visited banteng researchers in Indonesia, northern Australia, and Papua New Guinea in May 1981. More than 90 researchers (see contributor's list) provided information to the report through correspondence.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ACTI is a committee of the Board on Science and Technology for International Development, National Research Council. It assesses unconventional resources and technologies that might prove especially applicable to problems of developing countries. Current titles in the ACTI series Managing Tropical Animal Resources are: </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Water Buffalo: New Prospects for an Underutilized Animal (1981)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Little-Known Asian Animals with a Promising Economic Future (1983) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Crocodiles as a Resource for the Tropics (1983) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Butterfly Farming in Papua New Guinea (1983). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The production of these books has been supported largely by the U.S. Agency for International Development (AID). Program costs for this study were sponsored by AID'S Bureau for Asia, and staff costs by AID'S Office of the Science Advisor, which also made possible the free distribution of this report.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This is an exploratory volume. It will, perhaps, lead in a few years' time to a more complete book on indigenous Asian animals - and perhaps also to similar books on little-known animals of Africa and Latin America. If you have material to contribute to the future edition, please send it to Noel Vietmeyer, JH213, National Academy of Sciences, 2101 Constitution Avenue, Washington, D.C. 20418, USA, who will contact you when any new publication on this subject is planned.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Introduction</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Asia has several domesticated animals about which little is known. Among them are the banteng ("Bali cattle") of Indonesia, the yak of Central Asia's high country, and the mithan of the border region of India, Burma, and Bangladesh.( *The promise of another Asian animal, the water buffalo, is described in companion report no 32. ) Some Asian farmers use domesticated bovine hybrids: the madura (banteng-cattle hybrid) in Indonesia and the yakow (yak-cattle hybrid) in Central Asia. In addition, domesticated forms of at least two Asian pig species (the Indonesian wild boar and the Sulawesi warty pig) are important husbandry animals in parts of Indonesia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Among Asia's undomesticated animals are five interesting and potentially valuable species of wild bovines: the kouprey in Thailand, Laos, and Kampuchea; the gaur in India and much of Southeast Asia; two species of anoas in Indonesia; and the tamaraw in the Philippines. There are also three species of undomesticated Asian pigs: the bearded pig, the Javan warty pig and pigmy hog. Perhaps the strangest Asian animal of all is the babirusa, a piglike species of eastern Indonesia that may be a rudimentary ruminant.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many of these animals are either threatened or endangered species, and some will soon be extinct unless scientists, governments, and resource managers take forceful action to preserve them. Scientific management and a better understanding of the animals themselves is required.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An important need is to investigate their potential as livestock resources. All seem to be disease resistant and well adapted to difficult natural conditions. Some will interbreed with conventional livestock and might thereby pass on important characters to hybrid progeny. A few of the wild species are ancestors of domestic livestock and could be important genetic reservoirs for maintaining or improving the quality of their domestic descendants. Others may make useful new domesticates.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appreciation of their potential in the long-term for the world's agricultural development could create a momentum for the protection, preservation, and greater use of these little-known animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Imported Livestock</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the past, many thought that the best way to raise animal productivity in tropical developing countries was to introduce high-performing breeds from temperate industrialized areas. The fact that the exotic animals were much more productive than local stock made this seem very appealing. But many such importations ended in failure when the animals either quickly died or their growth or reproduction rates declined so drastically that the herds dwindled away or became uneconomic. These introductions had been made without adequate consideration of the local environment that was expected to support the imported animal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More recently, some animal scientists have decried the idea of wholesale importing of temperate-zone livestock into tropical countries without also evaluating the indigenous livestock. In many cases the local animals' apparent poor performance results not from their lack of genetic potential, but from inadequate feeding, breeding, selection, management, and health care.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Indigenous Animals</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Until an objective evaluation of particular indigenous breeds is undertaken, governments should regard local animals as vitally important for the long-term development of their domestic livestock industries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To achieve an agriculture that is compatible with nature, we should try to raise an animal as much as possible within its own natural environment. Indigenous species are necessarily well adapted to their surroundings and have survival qualities that imported livestock often lack. They generally select food, either graze or browse, better than foreign species and can therefore exploit the habitat more efficiently and live within it more harmoniously.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But most of the livestock species the world depends on today are best adapted to temperate conditions. This is because Stone Age peoples in what today are Europe, the Middle East, and eastern China domesticated the prototypes of agricultural animals that were available in those places. The world's best-known breeds of cattle, wool sheep, and horses, for example, usually perform well in temperate regions and poorly in the tropics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The species described in this report offer promise as new and important alternative livestock resources for tropical regions. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Embryo Transplants</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It seems likely that modern technology will substantially improve our ability to use new species and breeds of livestock. One of the most encouraging of the new biotechnology techniques is embryo transplantation. In this process multiple eggs (produced by hormonally stimulating female animals) are fertilized and transplanted to other female animals. The hormonal cycles of the donor and receiving animals are synchronized so that a pregnancy results.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This technique is widely used to transfer embryos between cattle, but researchers are now exploring transfers between different species and even between different genera. In 1981, for example, animal scientists at the New York Zoological Garden transplanted a fertilized gaur ovum into a Holstein cow, which carried the gaur calf to term. Now veterinarians at the University of Florida are attempting to transplant water buffalo embryos into both zebu and Holstein-Friesian cattle, and vice versa. If such pioneering work can become everyday practice, it will open possibilities of using common livestock to raise rare animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moreover, because embryos are thought to be free of many diseases, their shipment between nations may soon be permitted without elaborate quarantine precautions. Methods for freezing embryos have been worked out so that the tiny bundles of cells can be air freighted inexpensively in small, insulated containers. This may make animals such as those discussed in this report available to Africans, Latin Americans, North Americans, and Europeans. It may vastly simplify the worldwide exchange of animal genetic material and become the animal counterpart of exchanging seeds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An additional benefit of embryo transplants is that the surrogate mother's placental blood supply provides the fetus with natural immunity to some local diseases, thus perhaps reducing one of the most serious causes of failure when exotic animals are introduced to new environments. And at Utah State University it has been noted that raising wildsheep embryos in domestic ewes produces lambs that are more docile than if they were raised by their biological mothers. Embryo transplants may be a small step toward domesticating new animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With these possibilities on the horizon, it becomes even more important that all countries preserve their indigenous animals. The rest of this report suggests and discusses Asian species for protection and study. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Part I : Domesticated Bovine Species</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It seems probable that two of our widely used livestock species were domesticated in the Asian tropics: the zebu or humped cattle in India and the water buffalo in the humid marshlands of northeastern India or Southeast Asia. (Both the chicken and some races of pig may also have a tropical Asian origin, but the exact sites of their earliest domestication is unclear.) There are, however, other, much more localized, domesticated bovines in Asia. These are not well studied and deserve greatly increased recognition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This section highlights:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Domesticated banteng</P>
+<P ALIGN="JUSTIFY">· Banteng-cattle hybrids</P>
+<P ALIGN="JUSTIFY">· Mithan</P>
+<P ALIGN="JUSTIFY">· Yak</P>
+<P ALIGN="JUSTIFY">· Yakows. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is time for the world's scientific community to study the genetics, evolution, and biochemical parameters of the unique animal resources, that are found in Southeast Asia. ALLEN D. TILLMAN Animal Consultant Stillwater, Oklahoma, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Though well adapted for survival in their own harsh tropical environments, many domestic livestock breeds are being neglected in the race to achieve temperate zone levels of productivity. CHARLES HICKMAN Department of Dairy Cattle Breeding Ottawa, Canada </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Studies should be made of the present and potential role, productivity and efficiency of all domestic animals and birds, large and small, before they are replaced by imported types. Many wild species also could make important contributions to human welfare with proper management. J. K. LOOSLI Department of Animal Science University of Florida .</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The conservation of endangered genetic resources represents a genuine and welcome synthesis of the concerns of the agriculturalist and the wildlife enthusiast.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN TINKER British Journalist</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY"><center><img src="p06.png"></center><br>
+ MITHAN</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">1 Domesticated Banteng</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The banteng (*Bos javanicus is now the accepted name, but Bos sondaicus, Bibos banteng, and other synonyms have been used in the past. (See Hooijer, 1956.) The name "banteng" has traditionally referred to the wild form of Bos javanicus; the name "Bali cattle" to the domesticated form. This chapter describes the domesticated form, but we retain the name banteng to reinforce the fact that the animal is not a breed of cattle, but a distinct species. Despite a cattle-like appearance, the animals are at least as genetically remote from cattle as is the bison. Both produce sterile males when hybridized with European cattle. Australia. (N.D. Vietmeyer)) is a bovine that resembles a small cow. It is, however, an entirely different species from either European cattle (Bos taurus) or zebus (Bos indicus). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These docile animals thrive under hot, humid conditions and, like the water buffalo, have high resistance to ticks and tick-borne diseases. In parts of Southeast Asia they have proved acceptable for draft power and meat production, and they may have potential for many other regions of the world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng are remarkably uniform in type and have changed little from their wild ancestors (see chapter 6). Bulls stand from 1.3 to 1.5 m high at the shoulders, while cows are about 1.2 m high. They have the general conformation of beef cattle. The skin is tight, the neck short, and the dewlap inconspicuous. The face is narrow and is carried horizontally with the large ears pointing forward. There is no hump, but the male possesses a distinctive crest over the thorax because the spines of the thoracic vertebrae are unusually elongated.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On both sexes a striking white oval patch covers the rump and all four legs have white stockings. Calves and females are usually light brown with a thin black line along the middle of the back. Bulls are brown when young but usually turn near-black at maturity, unless castrated. Thus, in a herd the sexes - black males and brown females - are strikingly apparent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Male horns grow sideways, upward, and outward from a horny mass on the forehead. Females lack this horny shield and their horns usually grow upward and back, eventually curving down again toward the head. Polled animals have not been reported.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mature banteng bulls can weigh from 450 to 500 kg. Under exceptional conditions they may reach 550 kg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nearly all the world's domesticated banteng are found in Indonesia. They are particularly important on the islands of Bali, Kalimantan, Lombok, Sulawesi, Sumbawa, and Timor. On Bali and Sumbawa, they are virtually uncontaminated by crossbreeding with other cattle and are thought to have been domesticated there in prehistoric times. Since 1913 government officials have enforced a law that prohibits crossbreeding so as to maintain the purity of the breed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Small numbers of banteng have been introduced to Sumatra, Malaysia, and northern Australia, and there are experimental herds in Texas, USA, and New South Wales, Australia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY"><center><img src="p09.png"></center><br>
+ DISTRIBUTION OF DOMESTICATED BANTEG</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Domesticated banteng account for about 20 percent of Indonesia's total population of "cattle." The banteng population increased from 1.1 million in 1967 to 1.4 million in 1975 and is now estimated to be more than 1.5 million.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng are found mainly in lowland areas on Indonesian islands straddling the equator. The environment is monsoonal with mean annual temperatures ranging from 23° to 31°C. Most of the region receives heavy rainfall throughout the year, but dry spells as long as five months occur at some locations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng normally have high conception rates. In northern Australia they regularly achieve 80-90 percent conception, as compared with the 50-60 percent of Brahman-Shorthorn crossbred cattle. Similar conception rates have been recorded in Sulawesi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Little basic information on the banteng's reproductive physiology has been reported. However, it appears that this differs little from that of cattle. Sexual maturity has been observed as early as 13 months and mating at 16 months.* The gestation period is about one week longer than that of cattle and twinning is not common. At birth, males weigh about 16-17 kg and females about 14-15 kg (about half the size of Brahman-Shorthorn calves). Calves are not weaned at any specific time, and dams may continue suckling a calf until the next birth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng will crossbreed with domestic cattle, producing hybrids with notable vigor and heat tolerance (see chapter 2).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It has been reported that banteng have the ability to drink water with high salinity," and in northern Australia they have even been seen grazing seaweed on coral reefs at low tide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On high-quality diets, feed-conversion ratios approach those of other bovine species. For example, banteng bulls on high-concentrate diets have shown daily growth rates of 0.7 kg, compared with 0.7 kg in water buffalo, 0.8 kg in zebu cattle, and 0.9 kg in British cattle bulls.:"</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As the banteng matures, its weight remains lower than that of cattle of similar age. However, relative to mature liveweight, this disadvantage is only about 8 percent.§</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Behaviour</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng cannot be handled as roughly as domestic cattle. Cows and calves are timid and easily upset. When stressed they may run into fences and walls, incurring head and spinal injuries. They also easily get into a state of shock. Special squeeze chutes and other special facilities, along with much care in handling the animals, are essential. However, despite their lively temperament banteng are docile if reared, as in Indonesia, with frequent human contact.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These animals are promising beef producers. Gourmets consider banteng cuts among the finest of meats, and Indonesia cannot export enough to satisfy the demand in Hong Kong and Japan alone. The meat's outstanding characteristics are its tenderness and leanness. When the animals are maintained and finished under traditional village management, total fat content of the meat (both on a liveweight and carcass basis) is usually less than 4 percent. Little of the fat is deposited among the meat fibers (marbling); about two-thirds of it is mesenteric and the remainder is subcutaneous, laid down in small globules. The carcasses have a high dressing-out percentage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng have proved to be useful as draft animals for the farm but are reportedly less suitable than zebus for hauling carts on roads. Traditionally, both male and female animals are worked, but Balinese farmers normally use females for cultivating light soils only. Banteng are trained when they are about 2 years old and are reportedly easier to train than zebus.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like water buffaloes banteng can utilize low-quality feeds; they are similar in that they can live off forage unpalatable to cattle. It is rare to see banteng in poor condition. Animals of all ages appear to have an ability to maintain weight and body condition even when pasture quality is poor. In this respect, they have been noted to outperform cattle in Australia's Northern Territory. Moreover, due to their lower milk production banteng cows lose less weight and condition during lactation than, for example, Brahman-Shorthorn cows.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In comparison with cattle (European breeds) kept under similar circumstances in Australia, banteng are less infested with external parasites. Their hair is short and their hide tough, which helps them resist ticks. Under field conditions few adult cattle ticks (Boophilus microplus) are observed on the animals, except on malnourished individuals, and the incidence of tick-borne disease is said to be very low. Sarcoptic mange is known to affect the animals, but it has a low incidence as well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng also appear to tolerate several internal parasites. Liver fluke is probably the most prevalent. Although the animals themselves appear healthy at slaughter, some 80 percent or more of carcasses are found to have partially infected livers. In addition, intestinal worms are often present.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals are only slightly affected by Asian trypanosomiasis (Trypanosoma evansi). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals are poor milkers; their udders are almost invisible. The lactation varies from 6 to 10 months and milk production is only 0.9-2.8 kg per day.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To keep from reverting to the wild state, banteng may need close contact with humans or regular handling.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An unidentified banteng disease first appeared on Bali in 1964. Known locally as "jembrana," it spread rapidly, causing mortalities from 10 to 60 percent in certain localities. It was originally thought to be rinderpest; it is now believed to be caused by a rickettsia transmitted by cattle ticks. Outbreaks have occurred with decreasing intensity and virulence since the original outbreak. The disease is under intensive investigation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">"Bali ziekte," a disease affecting only banteng, has also been noted. It is characterized by dry eczema, followed by severe necrosis of the skin and exposed mucous membrances.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of their high susceptibility to bovine malignant catarrhal fever, banteng must not be brought in contact with sheep and some other animals. This virus is widely disseminated in sheep and several domestic and wild hoofed mammals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There have been few scientific studies of banteng and no coordinated attempt to improve their performance. They deserve more recognition and they merit testing in tropical locations outside their traditional home in Indonesia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The herds in northern Australia (descendants of animals remaining from an abortive colonization attempt in the 1820s) are in a relatively disease-free zone, and although they are feral, they can potentially provide animals for breeding and use in other nations. Although these few hundred banteng are a valuable resource, they are vulnerable to destruction if adverse environmental conditions arise or exotic diseases break out in Australia. Representatives of the herd should therefore be distributed and viable breeding stock established at several new locations. (Their genes and gene combinations may even prove valuable for the indigenous herds in Indonesia, and banteng research and development would make a valuable topic for cooperative research between Australia and Indonesia.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research is particularly needed to identify the reasons for the banteng's apparent ability to maintain weight and body condition on poor-quality grazing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The problems of bovine malignant catarrhal fever, Bali ziekte, and jembrana need increased attention, particularly directed toward prevention and control. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p13.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">2 Banteng Cattle Hybrids</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng and cattle have the same number of chromosomes, and they will interbreed. Few scientific details on the hybrid progeny are available, but on the Indonesian island of Madura they are a "stabilized crossbreed" because they seem to be genetically uniform. This hybridization took place some 1,500 years ago, when Indian invaders brought zebus of the Sinhala, or Ceylonese, type to Madura and crossed them with the banteng.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These maduras reportedly show better growth rate than the pure banteng species itself. They are thrifty, hardy, and able to perform well under extremes of heat and poor nutrition. Though a hybrid in origin, both sexes of the madura are fully fertile. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For more than 15 centuries the winners of the bull races ("kerapan sap)") have been the herd sires of Madurese villages. This long breeding history has led to an animal with the following characteristics:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Long legs and small feet</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Elongated muscles of the rear legs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Heavy muscling over the back, loin, and shoulder</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Quick reactions and nervous temperament</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Great heat tolerance</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The ability to perform well as a work animal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng-cattle hybrids vary in appearance, depending on whether European or zebu cattle are used in the cross as well as on the amount of backcrossing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Maduras (banteng x zebu) are graceful animals. Their bodies are neat, compact, and deep, with well developed forequarters. The cows attain an average weight of about 210 kg and bulls range from 350 to 375 kg at maturity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Superficially, maduras are like Jersey cattle, except for having a much smaller udder. In most of them the banteng dominates the body structure and coat color. Bulls have a well-developed hump; females have almost none. There is no distinct dewlap. Horns are medium sized and curve upwards and slightly backwards. Ears are medium length and horizontal. Breeders on Madura accept only red-brown animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Today, crossbreeds of banteng and zebu are distributed throughout Indonesia. On the other hand, hybrids between banteng and European cattle have been made only in small programs in the United States and Australia. For example, researchers in central Texas are producing a cross that is one-eighth banteng/seven-eighths Charolais. They believe this will result in a beef animal able to grow well in warm, humid conditions. In the Northern Territory of Australia, no problems have been encountered in mating banteng bulls to Brahman-Shorthorn cows. Calves that are one-fourth banteng/three-fourths Brahman-Shorthorn have since been produced.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Virtually all of the 575,000 "cattle" on the Indonesian island of Madura are hybrid animals resulting from crossing indigenous domesticated banteng with zebus. More than 200 head of banteng/Charolais hybrids are found near Easterly, Texas, and a score or so banteng/ Brahman-Shorthorn hybrids are on a research station near Darwin, Australia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The environment in Madura, where most of these hybrids occur, is monsoonal, with mean average temperatures as high as 31°C in the hot season, and dry spells as long as 5 months. It seems likely that judicious selection of the cattle breed could result in hybrids suitable for many other environments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As noted, the animals on Madura are bred to be raced. They are probably the fastest running bovines. From a standing start, a yoked pair pulling a sled can reach 50 kph by the end of the 130-meter course. An unencumbered individual can approach the speed of a horse (about 68 kph).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When compared with other bovine genotypes in Indonesia, the performance of these hybrids is more closely related to the banteng than the zebu ancestry."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the cross between banteng and European cattle all F1 bulls are sterile; their sperm development ceases at the secondary spermatocyte stage. Infertility also exists in most one-fourth banteng (although some sperm are present) and in all three-fourths banteng bulls. The fertility of the F1 cows, on the other hand, is high - 90 percent as compared with 70 percent for Brahman-Shorthorn cows.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The hybrids have a lively temperament. However, when they are reared with other domestic cattle or handled on a regular basis, they are almost as docile as cattle. For instance, they remain calm even in Madura's extremely crowded towns. Nevertheless, personal contact probably must be maintained to keep them accustomed to human management.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The cows are very protective of their calves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Several reports from the livestock service of the former Dutch colonial government, as well as several books on the East Indies, state that meat from the madura is the tenderest of any known breed. In addition, the hides are pliable and superior to those of cattle and are used in the highest quality leather goods. They command a price about 20 percent higher than zebu hides.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The breed is reportedly one of the best draft animals for its size in the world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Maduras have several desirable traits, including those outlined below:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Feed efficiency. With grain rations, yearling bulls can gain 1 kg on less than 7 kg of ration.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Thriftiness. The breed can maintain its body condition on low quality forages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Heat tolerance. The madura has a high rate of cutaneous evaporation and is therefore well adapted to the tropical monsoonal climate. Teams of madura can plow or cultivate land for more than 6 hours, even at high temperatures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">· Carcass quality. The madura fattens readily on a high-quality diet and  produces carcasses with high dressing percentages, a large rib-eye area, and  high yields of lean meat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· External fat thickness. A well-finished madura normally has only a slight  covering of fat over ribs and lower round. Maximum thickness (over the top  round) is less than 1.5 cm.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Intelligence. These animals are responsive and easily trained. The famous  dancing cattle of Madura, for instance, are actually these banteng-cattle  hybrids.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Parasite resistance. Despite often high levels of fluke infections, the  animals continue to work, reproduce, and maintain body condition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Maduras have been bred for one thing - speed. Some of their genetic  limitations are:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Low birth weight. The calves begin small, weighing 12-14 kg at birth, and  they continue to be slow weight gainers. [Feeding trials with yearling bulls  have shown daily gains of over 600 g for 180 days.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Poor lactation. Milk production is normally less than 1.5 lifers per day and lactation ends after about 4 months. The cows often fail to produce milk. Much of this is probably caused by poor nutrition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the important features of the madura is that its genetic variation has been largely removed during 1,500 years of continuous breeding; with study much valuable information could be obtained that is beneficial to all bovine breeds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The following topics need further study:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Fertility levels</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Crossbreeding to test the effect of using a wider range of cattle breeds*</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Assessment of the hybrid's advantages over the pure banteng</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Performance under a wide range of environments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">3 Mithan</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mithan (Bos frontalis) is believed to be a domesticated form of gaur (see chapter 6).t (However, it resembles the banteng and some authors have proposed that it is a gaur-cattle cross, others a gaur-banteng cross.) The mithan is a domestic animal indigenous to parts of India, Burma, and Bangladesh. Because of large size and the high butterfat content of its milk it is widely used to crossbreed with cattle in Bhutan. It deserves greater recognition both in Asia and elsewhere.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mithan is a handsome animal. Bulls may occasionally exceed 1.7 m at the shoulder and weigh 1,000 kg, but the average bull is about 1.5 m tall and weighs 540 kg. Cows are shorter and weigh less.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animal has a dorsal ridge on the crest of the shoulders, a small but pronounced dewlap, and a generally flat forehead. Mithan horns are often of unusual girth; they are straight or gently curving, and many have an enormous base that practically covers the top of the skull.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most calves and females are brown, but adult males are generally black with white stockings on all four legs. Some, however, are light brown, white, or piebald.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the hill ranges of Assam, where gaur are still plentiful and interbreeding between mithan and gaur frequently occurs, the mithans are massive and gaurlike. But in the Chin Hills, where gaur are scarce, the mithans have lost their bulky proportions, probably by interbreeding with cattle. With them, the high dorsal ridge on the shoulder (which lends so much to the imposing stature of the gaur) has disappeared, the horns are cowlike, and the varied coloring of the domestic cow begins to appear.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mithan are kept in a domesticated condition by the hill tribes of northeastern India (Mishmis, Mizo, Nagas), the Chittagong Hill tracts, and some Burmese hill ranges (Arakan and Chin Hills). It is the main domestic animal of the Nagas of Nagaland.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In India feral herds totalling some 50,000 head roam the jungles of Arunachal Pradesh. Recently the Royal Government of Bhutan has established two herds by purchasing animals from Arunachal Pradesh. Bhutanese farmers have some 60,000 head of animals that are hybrids of mithan and the local breed of cattle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The government of Bhutan is breeding mithans on government farms and distributing males to private breeders to improve the genetic base.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mithan is a grazing animal, but in some areas herds are allowed to browse freely in the woods; some return to the villages for protection at night, while others remain largely in the forests. The villagers keep the forest mithans nearby by providing salt, for which the animals have an insatiable craving.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Feral mithan live in the same habitat as gaurs and are said to move equally skillfully in mountainous terrain. Usually they are found at elevations from 600 to 3,000 m. However, in the Chittagong Hill tracts and the Mishmi country they descend to 300 m and lower, while in Bhutan they have been reported grazing in summer at altitudes as high as 3,300 m, for example around Thimphu.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p23.png"></center><br>
+ Mithan distribution. (after Simoons and Simoons, 1968)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mithans are fully fertile amongst themselves. Also, they interbreed freely with the gaur, banteng, yak, and cattle of both the taurus and zebu types. Naga owners encourage the interbreeding with gaur, regarding it as an improvement of the race. (They arrange this by placing salt licks in the forest. After gaur bulls have formed a habit of coming to the licks, mithan cows are left there and in due course mating takes place.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The crosses between mithan and zebu are also encouraged in certain districts. Unlike most crosses between bovine species, those between mithan and cattle result in fertile male and female offspring (although some owners indicate that the F1 male is not a reliable breeder).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This is an unusually gentle animal with a quiet disposition, as revealed in the Chin tribe's expression "gentle as a mithan." Normally even a stranger is safe to approach one; if he gives it a bit of salt, it will usually follow him about. Thus, mithans are easily managed in a regular cattlerearing operation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many mithans are not domesticated in the strict sense. Their herds live in a semi-tame state near jungle villages and come to settlements only in the evening to lick salt.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In some regions of northern India, mithans are used for field work and as draft animals. They are also important as a meat supply. The Bhutanese government is establishing a national dairy-mithan breeding program, which could result in a valuable dairy animal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To many tribes of northeast India and Burma, mithans serve mainly as sacrificial animals. The Nagas use them as a kind of "currency" to pay for goods, to buy brides, and to pay penalties.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hybrids resulting from backcrossing mithan with common cattle are also used as work animals. For at least a century, Bhutanese livestock breeders, particularly those in the eastern section, have mated mithan bulls to siri cows (Bos taurus) from India. This produces very profitable hybrid offspring that have high milk production. The milk is rich in total solids and produces exceptional yields of cheese and butter.* The male of the cross (called "jatsha") is a powerful draft animal, and the female ("jatshum") is a prized milk cow. To this day, extensive crossing continues.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mithan is potentially an animal that can be used in difficult terrain where most domestic cattle breeds do not perform well. Mithans are superior when it comes to feeding on steep slopes and cliffs and for grazing native grass and the leaves of local fodder trees. They are also adapted to tropical and subtropical environments. And they are able to maintain themselves in small herds (6-10 head) in dense jungle.*</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mithan could prove valuable in other parts of the world, and it could be important particularly for the genetic improvement of cattle in the tropics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If they are disturbed, mature mithans can be temperamental. They can be difficult to hold with normal fences or chutes, because of their size. When given injections or otherwise subjected to pain, they are liable to bolt to the jungle and not return.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The productivity of these animals needs to be better characterized and defined. Attention should be given to their grazing efficiency as compared with that of cattle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The two farms the Bhutan government has established for breeding mithans provide an opportunity to gather genetic information on the species and to have experimental matings take place to establish the most suitable animal for various conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The genetic relationship of mithan to gayal, gaur, and cattle needs to be clarified. Although it is believed that the mithan and gayal are the same animal, one of this report's reviewers points out that the mithan of Bhutan are strikingly different in color, body shape, and horn structure from gayals seen in zoos in Europe and India. Although the mithan is now considered a domesticated gaur, many in the past have claimed it as a gaur-cattle hybrid. Physiological research could remove lingering doubts. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p26.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">4 Yak</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The yak (Bos grunniens), is a grazing animal that is accustomed to traveling great distances in a harsh environment. Nothing is known about when it was first domesticated, but there has probably been a close association between man and yaks ever since the first humans migrated into the high mountains of Asia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Domesticated yaks are about the size of ordinary cattle and rarely exceed heights of 1.3 m at the shoulder. Their liveweight is generally 250-550 kg for the males and 180-350 kg for the females. They differ little from wild yaks except that they are smaller, have shorter and thinner horns, and may be rusty brown, black, silver grey, or piebald instead of black. Often they have whitish spots on their faces.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The yak's hair is long, especially on the flanks, where it forms a shaggy fringe that often reaches the ground. This, together with an underlying layer of thick, fine wool, protects the animal from the bitter cold of its native region. The yak has an enormous tail with a brush of long hair coming from its root, which is rare in bovines.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Long extensions of the thoracic vertebrae give the yak shoulders that look like a hump, but this is different from the boneless hump in zebus. The body is long, short-legged, and compact, with particularly large forequarters because, like the bison, the yak has 14 or 15 pairs of ribs instead of the 13 of domestic cattle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The horns spread outward and upward, and the head is held low, like that of the bison. While no hornless domestic yaks have been reported in Nepal, more than 90 percent of those found in Mongolia lack horns.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most yaks are found especially in the mountains and plateaus of Tibet and western China, however they occur from northern Afghanistan, Pakistan, India, and Bhutan to Mongolia, and the Soviet Union.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are more than one million domestic yaks in the world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the Himalayas the domestic yak is almost always found above 2,000 m elevation. Males are sometimes brought as low as 1,700 m for mating with cattle (see chapter 6), but they do not fare well at such altitudes. In Mongolia and Buryatiya (U.S.S.R.), however, they are found as low as 1,500 m elevation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY"><center><img src="p29.png"></center><br>
+ Yak distribution. (after J. Bonnemaire, 1976)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The wild yak lives in desolate mountain areas at altitudes of 4,000-6,000 m. Its habitat is the alpine tundra and the cold desert regions of the northern part of the Tibetan plateau. These barren mountain regions are remote and at higher elevations than the zones of human habitation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yaks look ungainly, partly because they are covered with long hair, but they are agile climbers and can maneuver narrow mountain paths. Their long hair is one adaptation to the cold climate. Other adaptations are the small, compact scrotum of the male and udder of the female, the small teats (only 2-3 cm long) and covering of hair over the udder, and the covering of short hair over the muzzle, except just around the nostrils.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In early summer yaks graze the lush grass in valley bottoms, but for much of the year they live on dry, coarse mountain grass and for long periods obtain water by eating snow.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The gestation length is 258 days - slightly shorter than that of cattle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Domestic yaks are docile and easily managed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yaks are especially useful as riding and pack animals; they can manage loads of more than 150 kg. At altitudes up to 6,000 m they may carry a pack or a person at a steady pace for days and still remain in good condition. In some regions they are the only feasible pack animal. Yak bulls (generally castrated) are also used for plowing and for threshing grain.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Occasionally the yak is slaughtered for meat. The meat is particularly important in parts of the USSR and in Mongolia, where in the cold, high-altitude environments it reportedly costs only half as much to produce as beef.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In most areas milk production is an essential aspect of yak husbandry. Yields vary considerably according to management and nutrition, but they average about 600 kg and can be more than 1,000 kg per lactation. Yak milk is golden colored. It is much richer than cow's milk; a typical analysis is: total dry matter, 17.35 percent; fat, 6.5 percent; protein, 5.3 percent; and sugars, 4.6 percent. The fat globules are much larger than those in cow's milk. People of Tibetan stock use yak butter as a food staple and as a lighting fuel.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yak hide, though apparently not as good as that of cattle, is used for many purposes. It makes outstanding saddles. Yak hair is used for making ropes, saddle blankets (purportedly the best in the world), grainstorage bags, and tents. The fine wool that occurs beneath the long hair is used for making felt. The annual yield of adult females and males is about 750 g and 1,600 g of hair and about 350 g and 600 g of wool, respectively.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because yaks are often found above the timberline their dung is an important fuel in many areas. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yaks can live and work hard in a cold climate. They are the only bovines to thrive at high altitudes. In cold, high areas they can work and produce meat and milk more efficiently and cheaply than cattle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yaks are not well able to eliminate surplus heat because their heavy coat reduces their ability to sweat. In warm climates their respiration rate and body temperature increase and they become exhausted and susceptible to infections. At low altitudes in Nepal yaks die of a variety of diseases. Apparently not even yak-cattle hybrid animals (see next chapter) can successfully live below 700 m in that part of the world. This is probably due to overheating, since during the first half of this century yaks grew successfully in trials at low altitudes in Alaska and northern Canada.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Yak improvement programs are much needed. It seems probable that the genetic potential of the species is far from realized because Buddhist beliefs oppose the deliberate killing of stock. Techniques for deep freezing yak semen have been successfully developed at Regents Park Zoo, London and should prove invaluable for improving the breed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· As a result of uncontrolled hunting the wild yak is endangered and is now restricted to remote barrens on upland plateaus and highlands in northern Tibet and Chinghai, inhospitable even to domestic yaks. The numbers of wild yak are unknown. They require total protection throughout their range and the establishment of adequately protected reserves with good pasture. To preserve their genetic purity, it is important to isolate wild yaks from domestic yaks and thus keep them pure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· A primary need is to catalog the numbers and locations of purebred yaks. Today we have little idea of the total breeding population. Gathering such information is difficult, owing to the geographical isolation of the communities involved.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· It is also important to catalog the movement of yaks between different areas to see if enough genetic exchange occurs to prevent inbreeding of the population. Exchanges between local pastoralists were much more frequent in the past (for example, between Tibet and Nepal), but this is now more difficult because of border restrictions and because many yak </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">herders that used to move herds long distances have become sedentary farmers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Breeding strategies, herd management, product processing, and herd hygiene in Nepal, Bhutan, Sikkim, northern India, and northern Pakistan, Tibet, Mongolia, and the Soviet Union all differ greatly. It is important to get an overall perspective so that the strengths of the different systems can be judged and the weaknesses reduced.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· There are clearly different domestic yak "breeds" in terms of their appearance, and these need to be identified and compared systematically. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p33.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">5 Yakows</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yaks and cattle have the same diploid number of chromosomes (60). And in the regions where yaks are found, they are often interbred with cattle, either the humpless cattle (Bos taurus) of Tibet and Mongolia or the zebu (Bos indicus) of South Asia. As with mules, the hybrid offspring of cattle and yak surpass their parents in strength and vigor. Yakows* grow faster than their parents, and they suffer less from high temperatures than yaks. The hybrid cow reaches sexual maturity earlier and yields larger quantities of milk than the yak cow. The males, however, are sterile.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The yakow's appearance varies with the type of cattle used in the cross. But because of the phenomenon of hybrid vigor (heterosis), the hybrids are considerably bigger than the mean size of their parents. (For instance, in one test the liveweight was approximately 18 percent higher than the average weight of the parents.) The hybrids also excel in hardiness, working ability, growth rate, and milk production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nevertheless, their appearance and performance is closer to that of the mother than of the father. Because of this, the yakows can be "custom designed" for various altitude zones. For example, the farmer at lower altitudes may produce cattle-like yakows by breeding yak bulls to domestic cows, while farmers at higher altitudes would use the reverse cross.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Yakows have shorter hair and a much less downy undercoat than purebred yaks. They are similar in color to yaks. (In Nepal, black is most frequent, but brown shades and even white may occur.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yakows are found in parts of northeastern Afghanistan, northern Pakistan, northeast and northwest India, Nepal, Sikkim, Bhutan, Tibet, western China, Mongolia, and southeastern Russia. They are found notably in the Himalayan region of Nepal, where they are bred by people of Tibetan culture and language. Sherpas, for instance, supply hybrid cows and heifers to dairy farmers throughout northeastern Nepal. Hybrids are also much bred in Ladakh (northern Pakistan) and Mongolia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Whereas farmers in Nepal tend to use zebus to cross with yak, the inhabitants of the Tibetan plateau generally use Bos taurus cattle. People in some areas favor mating yak bulls to cows, while those in other areas prefer the reverse. But even within one village there can be a degree of specialization by different families, depending on wealth and the location of traditional grazing grounds. Generally, however, the crosses between domestic cattle bulls and yak cows are the predominant ones.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The number of yak-cattle hybrids in the world is unknown.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like the yak, the hybrid can live in cold, barren, upland terrain, but it has the advantage of being able to adapt to lower altitudes. In winter, caravans of hybrids may come down as low as 1,600 m in some parts of Nepal, and hybrid herds (especially those resulting from crossing yak bulls with zebu cows) can spend several weeks grazing at altitudes as low as about 1,700 m in winter.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Female hybrids are fertile when mated with either parent stock. Male hybrids, however, are sterile. Although they have fully developed secondary sexual characters and show libido, their testes do not produce spermatozoa because the seminiferous tubules are poorly developed and the spermatogonia and their nuclei are degenerate.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A few normal or motile spermatozoa may be found in the semen of backcrosses of the F1 hybrids to either parent, but as a rule the spermatozoa are normal and dead.* Backcrossing is reportedly not common, however, as the progeny do not retain hybrid vigor.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tibetan farmers prefer the hybrids for plowing because of their docile temperament. The yak is said to be more stubborn.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The hybrids are valued as beasts of burden and draft, and are often preferred over yaks. Male hybrids are generally castrated at about 3 years of age so as to increase their strength and size.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Where pastures occur over areas of greatly varying altitude, the use of hybrid livestock is likely to be more efficient, in biological terms, than the use of yaks or cattle. By judiciously selecting cattle, yaks, or hybrids all altitudes from sea level to above 5,000 m can be utilized with best efficiency.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The hybrid's milk is intermediate in composition between that of its parents. However, hybrids yield up to 7 kg of milk per day against the yak's 3 kg. (It seems that the hybrid derived from cattle bull and female yak produces considerably more milk, with a higher fat content than that derived from yak bull x cattle female.) Also the female hybrids produce larger quantities of milk than Nepalese zebu cows on the same hill pastures. They also produce a calf each year, while under normal herd management yaks tend to produce a calf every 2 years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hybrids do not tolerate extremes of altitude or cold as well as purebred yaks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The normal gestation period for yaks is about 1 month shorter than that of cattle, and the gestation period for a hybrid is intermediate between that of the parents - hence there may be problems at calving when a female yak is sired by a bull from a large cattle breed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research is needed to identify differences in altitude tolerance between various hybrids. This should include measurements of hemoglobin count, respiration rate, and pulse rates at different altitudes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Studies are also needed on all production characteristics, particularly on the meat and milk production potentials.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cataloging the breeding strategies of different areas where hybrids occur would be useful, along with a historical perspective.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research to determine the most productive hybrids by crossing different yak and cattle "breeds" in areas with different environmental conditions could be extremely useful. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Part II : Wild Bovine Species</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In various parts of Southeast Asia there exist little-known relatives of cattle and water buffaloes. Many of these wild animals are close to extinction, and attention is drawn to them in hope their populations will be preserved. All of them survive in tropical regions subject to environmental extremes - flooding annual rains, searing droughts, and swarming pests and parasites. These are conditions to which conventional livestock are poorly adapted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">None of Africa's bovines is threatened with extinction, and both the European and American forms of bison are being preserved by governments and individuals. In Asia, however, there has been an alarming drop in the numbers of wild water buffalo, wild yak, wild banteng, kouprey, gaur, and tamaraw in recent years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This section describes:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Wild banteng</P>
+<P ALIGN="JUSTIFY">· Gaur</P>
+<P ALIGN="JUSTIFY">· Kouprey</P>
+<P ALIGN="JUSTIFY">· Tamaraw</P>
+<P ALIGN="JUSTIFY">· Anoas</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If not molested, many of these animals can thrive side by side with human settlements. They may therefore have an important future role in the development of the tropics. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is little point in conservation for conservation's sake, but loss of irreplaceable resources through ignorance, greed, or thoughtlessness should be avoided. It may be that these Asian animals have little merit other than their uniqueness, but at the very least, sufficient numbers should be conserved until we have time to find out. A. J. SMITH Royal School of Veterinary Studies, Edinburgh, Scotland </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rapid human increase and relative poverty deny hope that any land can lie idle when so many would be robbed of an opportunity simply to exist. For wildlife to survive, let alone at its breathtaking best, we must think of new and better ways to justify its future, preferably by having it contribute to the welfare of those hard-pressed humans who inevitably are further disadvantaged by the creation of national parks. DAVID WESTERN New York Zoological Society, Bronx, New York, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is an urgency to conserve and study nontraditional animal species, especially for use in the environmentally challenging tropical areas of the world. The philosophy plant scientists apply to exploring the potential of the plant kingdom needs to be more enthusiastically adopted for the world's animal species. G. W. M. KIRBY, Principal Animal Production Officer Department of Primary Production Darwin, Australia</P>
+<P ALIGN="JUSTIFY"> </P>
+<P ALIGN="JUSTIFY"><center><img src="p40.png"></center><br>
+ GAUR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">6  Wild Banteng</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The wild banteng (Bos javanicus)* are the most cowlike of all the wild bovines and are the parent stock of the 1.5 million domesticated banteng in Indonesia (see chapter 1). They have a scattered distribution throughout Southeast Asia, and three subspecies are recognized:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The Java banteng Bos javanicus javanicus (Java and Bali)</P>
+<P ALIGN="JUSTIFY">· The Borneo banteng Bos javanicus lowi (Borneo)</P>
+<P ALIGN="JUSTIFY">· The Burma banteng Bos javanicus birmanicus (Burma, Thailand, Indochina).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng have been called the most beautiful of all wild relatives of cattle. The cows are usually a vibrant reddish brown, while adult bulls are mostly blackish-brown and sometimes even blue-black (although in Burma and Indochina bulls remain golden brown like the cows, and in Thailand a few banteng have been recorded with white, deerlike spots on their brown coats). Both sexes have white "stockings" and a large white patch on their rumps.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild banteng are larger than their domesticated counterparts. Average-sized bulls of the Java and Burma subspecies stand 1.6 m high and weigh 635 kg, but bulls as large as 1.9 m and 825 kg have been recorded. Cows average 1.4 m in height and weigh 400 kg. The Borneo subspecies is smaller.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The horns of banteng bulls are angular, turning out and then up, with inward-pointing tips and reaching a spread of 60-75 cm. The horns of cows are short and crescent shaped. There is a patch of thick, naked skin between the horns.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals are found in restricted localities scattered over an area ranging from the northeastern edge of India, through Burma, Thailand, the northern Malay Peninsula, central and southern Indochina, and the islands of Borneo, Java, and Bali.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Only a few thousand wild banteng survive, and their numbers are decreasing. Most populations are endangered because their habitats are being encroached upon by the growing human population. In Sabah, Malaysia, for example, the areas where an estimated 300-550 banteng (the last remaining herds) occur are scheduled for conversion to permanent agriculture. The animals are being forced to use smaller and smaller habitats, thus increasing losses caused by malnutrition, diseases, and parasites. In addition, throughout much of the animal's range, hunting, military operations, and perhaps interbreeding with domestic cattle are further reducing the original stocks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY"><center><img src="p43.png"></center><br>
+ Distribution of wild banteng. (courtesy of C.H. Wharton)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The banteng's general distribution lies in the zone of deciduous monsoon forest in Southeast Asia. Habitats vary between the extremes of dry wooded parkland with large grassy plains to tropical rain forest with small clearings. The animals prefer flat or undulating terrain. In northern Kampuchea and eastern Java, they inhabit grassland savannas. In western Thailand, they live in a belt of grass and bamboo thickets along upper slopes of dry mountains.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild banteng inhabit sites from sea level to around 2,000 m elevation. They avoid large human settlements and plantations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In most areas there are no pronounced hot or cold seasons, but dry seasons can be long.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng prefer feeding on grass, but are fond of herbs, leaves, fruits and blossoms, as well as the sprouts of trees, brush, and young bamboo. Under favorable conditions they drink daily, preferring standing water. During droughts, they seem able to survive several days without water. In coastal areas where there are no mineral licks they can meet their need for salt by occasionally drinking seawater. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The sex ratio at birth is 140 males to 100 females, but mortality of bulls is heavy and the adult ratio is about three cows for every bull.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Calves are suckled until they are 14-16 months old.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In undisturbed conditions, the banteng's daily activity has a more or less fixed rhythm. During daytime, the animals alternate active and resting periods of 2-3 hours each. The active periods predominantly involve feeding, drinking, and social interactions. While resting, the animals commonly ruminate.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As a reaction to heavy rains or human disturbances, the animals retreat into dense vegetation. In regions with frequent human disturbance they generally appear in the open only at night. However, where they find particularly suitable localities they become somewhat accustomed to human presence and will venture out in daylight.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng live alone or in small groups of up to eight members. Males separate from their mothers at an age of 2-3 years. Sometimes female calves continue living with their mother even beyond maturity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cows and dominant bulls command the best pastures, and young and weaker bulls roam widely, rarely leaving the protection of the thick forest.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The banteng bull has a reputation for extraordinary savagery, but stories of its lightning attack have been exaggerated. Wildlife biologists in Indonesia have not been able to document any such attacks and have no qualms about walking in banteng habitats.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild banteng show important promise for improving domesticated banteng (see chapter 1) or for interbreeding with cattle (chapter 2). Almost 170 years ago Sir Stamford Raffles, founder of Singapore, noted that in Java "The degenerate domestic cows are sometimes driven into the forest to couple with the wild benteng, for the sake of improving that breed."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tourism could be developed in areas where these magnificent animals occur.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild banteng are large, robust animals fully at home both in the heat and humidity of the wet season and in the hot dry season. Their genetic </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">endowment for such tolerance could be of significant value fin improving domestic stock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Possible Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild banteng may prove to have a special susceptibility to diseases of domestic animals. Blackleg (Clostridium chauvoli) and mucosal disease have caused heavy losses in banteng in European zoos.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Capture of wild banteng may prove difficult.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research on the physiology, production potential, and possible uses of wild banteng is needed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hunting and destruction of its habitats menace the wild banteng over all of its range. The only promising means for conservation is creation of nature reserves where hunting and forest destruction are forbidden. Conservation efforts should particularly include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Supporting government of Thailand efforts to conserve banteng in western Thailand and the Petchabun Range;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Cooperating with the Burmese government in surveys to locate the best banteng habitats;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Cooperating with the governments of Kampuchea and Laos to identify banteng habitats and establish appropriate protective measures; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Carrying out research in Java's nature reserves (Ujung Kulon National Park and Baluran Reserve) to ascertain the genetic distinctiveness of the banteng, its status, and its characteristics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Sabah and other areas of Southeast Asia there are cattle breeding projects that use imported stock exclusively. Experimental crossbreeding of local banteng with this stock should be encouraged. There are some feral and domestic banteng, as well as hybrids between wild banteng and feral cattle, that should also be tested.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p45.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">7 Gaur</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The gaur (Bos gaurus) would seem to be an ideal meat-producing animal. It is a large bovine with massive muscular development, and it has already been domesticated (see mithan, chapter 3). Gaurs, which are threatened with extinction, deserve much greater attention.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Two subspecies of gaurs are recognized.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Bos gaurus gaurus (India, Nepal) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Bos gaurus laosiensis (Burma, Thailand, Laos, Vietnam, Kampuchea, West Malaysia). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With its huge head, massive body, and sturdy limbs, the gaur is the embodiment of vigor and strength. It is among the biggest of bovines. Bulls weigh 600-940 kg and stand 1.6-1.9 m tall at the shoulder, but a record bull of 2.2 m and 1,225 kg has been recorded. Cows are only about 10 cm shorter in height, but they are more lightly built and weigh 150 kg less.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On their shoulders gaur bulls have a striking muscular ridge that slopes down to the middle of the back, where it ends in an abrupt dip. The horns are crescent shaped, creamy yellow, and taper to a sharp point, which is usually tipped in black.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Newborns are a light golden yellow, but soon darken to coffee or reddish brown, the color of young bulls and cows. Old bulls are jet black, their bodies almost hairless. Gaurs have light colored forehead and yellowish or white stockings. Their eyes are brown but in certain lights, because of reflection, they appear blue.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gaurs excrete an oily, aromatic sweat, unique to this species and to the mithan. It gives the animals a strong bovine smell and may be an adaptation for keeping away insects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Once common throughout South and Southeast Asia, gaurs now survive only in scattered remnant herds of up to 30 animals in the hill forests of India, Nepal, Burma, Thailand, Laos, Kampuchea, Vietnam, and the Malay Peninsula.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY"><center><img src="p48.png"></center><br>
+ Gaur distribution. (courtesy of C.H. Wharton)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Historically, the largest concentrations have coexisted with farmers in areas of shifting cultivation. The animals adjust to disturbed land, and they also adapt to man's presence if not unduly harassed. For example, gaurs will feed in agricultural fields, along roadsides, and near occupied houses. Herds in national parks feed peacefully while tourists stand by. Gaurs in zoos also become quite tame and manageable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Populations not protected in parks and reserves are in immediate danger of extinction. Even in the remotest hill forests gaurs are harassed by hunting, exposed to the diseases of domestic cattle, and driven from their natural habitat by human invasion. Most herds outside of parks or wildlife reserves are threatened by agricultural development, hydroelectric dam projects, human settlement, or extensive logging.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In India, large populations still exist in the larger sanctuaries such as </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mudumalai and Kanha Park. In Thailand diseases carried by domestic animals, poaching, and habitat destruction have reduced total gaur numbers to fewer than 500. In Malaysia, the population is estimated to be only 400 animals. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gaurs typically live on gentle, undulating terrain with natural mineral licks. They inhabit gaps in the forest, such as abandoned clearings, where they can find grasses and shrubs. In the northern portions of their range, they inhabit deciduous and semideciduous hill and mountain forests with light brush and many grassy clearings. In the lowlands they live in open bamboo jungles, grassy plains near forests, or dense forests broken by glades or open meadows. (In the forest they probably depend to some extent on the slash and burn agriculture of hill people.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals appear to be adapting to increased human presence. They make use of such man-modified habitats as logged forests and fringe areas of agricultural estates that abound with grasses and early secondgrowth vegetation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gaurs are combination grazers and browsers. They feed on the grasses of forest openings as well as on the young leaves, fruits, twigs, and bark of shrubs and juvenile trees. In one study in Malaysia, grasses comprised 41 percent of their diet, fortes 23 percent, and woody browse 36 percent."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gaurs develop large muscular bodies and maintain excellent condition on relatively low-quality feed. In the Malaysian study, crude protein content of grass species varied from 7.0 to 7.6 percent and phosphorus content varied from 0.11 to 0.17 percent; yet calves reached weights of 300 kg or more during their first year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Birth and survival rates of up to 100 percent have been reported for wild gaur populations. Calves are born at any time of the year. The gestation period is 270 days, a little shorter than for banteng or domestic cattle and longer than for yak or kouprey.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Captive gaurs calve first at 2.5 years of age.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The gaur interbreeds with the mithan, and both have a diploid chromosome number of 2n = 58.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By nature gaurs are shy and timid. As with most wild bovines, their hearing and eyesight seem comparatively poor. Their defense lies in their massive size and acute sense of smell. When a herd with juveniles is threatened by a predator, the adults form a protective circle around the young. Although individuals retreat from danger if they can, they have a unique form of threat: they approach their opponents broadside instead of head on, displaying the huge muscular body and dorsal ridge.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In common with other wild bovids, gaurs habitually visit mineral licks, which appear to be necessary to their habitat and influence the herd's movements.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unlike water buffaloes, gaurs do not wallow. They take cover in the forest during the heat of the day and may feed at night and in the early morning during hot weather. In populated areas such as near agricultural estates, they may feed only at night to avoid people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the past, gaurs associated in loose herds of up to 400 animals, but today groups of only 5 to 12 animals are normally found. The herds, which are of more stable composition than those of banteng, are separated by sex for most of the year; however, during the rut stronger bulls form a series of "tending bonds" with estrous cows.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gaurs are thought to be interfertile with domestic cattle. If so, their attributes of size, massive muscular development, tolerance of heat and humidity, and resistance to diseases and parasites can contribute to beef production in the tropics. A gaur-cattle hybrid might also have immunity to some cattle diseases; if it retained the mild temperament of the domesticated parent, an extremely powerful beast of burden could be produced.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The gaur is a truly majestic animal. Its habit of using grassy forest clearings and salt licks makes it a likely tourist attraction in parks and reserves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In a climate and environment where domestic cattle are susceptible to heat stress and parasite infestation, gaur thrive and maintain body condition. Further, they are able to develop large muscular bodies and maintain excellent body conditions on relatively low-quality forage by feeding on a variety of woody browse, grasses, and fortes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Retaining its wild instincts for survival, the gaur is better able to withstand predator attacks them domestic cattle. This could be an advantage when animals graze in remote areas. Adult gaurs are strong enough to defend themselves against a predator as powerful as a tiger. In addition, they are also very protective of their young.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gaurs have little immunity to some cattle diseases. In many regions of India, cattle driven into the forests to graze infect gaur herds with rinderpest, foot and mouth disease, cattle plague, and other contagious diseases. Severe losses occur. Gaurs also appear very susceptible to malignant catarrhal fever.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gaur numbers are declining throughout their range. If this trend is not reversed, it could effectively prohibit the use of gaur for domestication or crossbreeding purposes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gaurs are shy and excitable, making them difficult to catch, but once in captivity the animals calm down. Second generation zoo populations are easily worked and handled.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gaurs on occasion damage cultivated crops such as young rubber trees and cassava. They require sturdy and well-kept fences.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Southeast Asia there is special need to support the efforts of the governments of Malaysia and Thailand to conserve this species and to identify important gaur populations. Similar protective measures are needed in Burma, Laos, Kampuchea, and Vietnam.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research is needed to establish and manage new gaur herds in forest reserves and build up the gaur population in the world's zoos. Techniques have been developed to capture and release wild gaur safely.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fertilized gaur ova have been successfully transferred into a foster Holstein cow. The cow carried the gaur fetus to a successful delivery. This could be the forerunner of an important means of rapidly expanding captive herds by transferring gaur embryos into cattle in different parts of the world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research is also needed on the basic physiology and production potential of gaur.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crossbreeding experiments should be started immediately to establish the degree of interfertility between the gaur and other bovine species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p52.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">8 Kouprey</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The kouprey (Bos sauveli) is the most primitive of living cattle. Its features are typical of some forms that existed in the Pleistocene era, 600,000 years ago. Discovered by Western scientists only in 1937, the kouprey was the last large mammal to enter the biology books. It is perhaps the most primitive of living cattle and is closely allied to Bos namadicus, the wild ancestor of zebu cattle. In 1964 it was declared Cambodia's national animal. It is now perilously close to extinction, and for a decade no koupreys have been observed close enough for a positive identification by a specialist. In 1982, however, five of the animals were believed sighted in Thailand, near the border with Kampuchea. Thus there are hopes that the kouprey still exists.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The kouprey is large. Males stand 1.5-2 m high at the shoulder and may weigh 900 kg. Females are approximately three-quarters the height and weight of the males. The body is slender and long-legged. The hump from the withers to the center of the back is smaller than that of the gaur, but larger than that of the banteng. There is a well-developed dewlap from the throat to the mid-chest, which in old animals is sometimes so pendulous that it drags through the grass in front of the forelegs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Young bulls are gray, with black on the head and dewlap. Old bulls are entirely black and cows are mouse gray or dullish light brown. As in the gaur and the banteng, the lower parts of the legs have white stockings, but kouprey stockings have a streak of dark hair down the front.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Kouprey. (P. Pfeffer)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kouprey horns are among the longest and widest of any bovine. The tips of the adult male horns are surrounded by rough, frayed tissue caused by the animals' habit of digging in the soil with their horns. The females have slender, lyre-shaped horns that corkscrew upwards, unlike those of any other wild or domesticated cattle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kouprey are said to have a grace more reminiscent of deer than cattle. They move at a light trot, as fast as 32 kph.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The kouprey's prevalence in ancient times is evidenced by prehistoric cave-paintings in Kampuchea. The animal was also a favorite of the ancient Khmers, who carved kouprey statues and featured the animal in bas-reliefs on temples, including the monuments of Angkor Wat. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Today, whatever kouprey exist are restricted to an area along both sides of the Mekong River in northern Kampuchea, the Dangrek Range, and other parts of eastern Thailand to the far south of Laos, and to the westernmost part of Vietnam. Although one or two small herds may still exist in remote pockets of Laos and Vietnam, the bulk of the population has always been centered in Kampuchea.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are no koupreys in captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of their large size, gregarious behavior, comparatively low reproductive rate, and preference for open areas, kouprey are vulnerable to hunting. The impressive horns and other tissues are valued as trophies and as medicinals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1964 it was estimated there were about 500 kouprey in Kampuchea, but by 1970 fewer than 70 were left. The subsequent fate of the species is unknown because of the years of warfare in the area. (Early in 1970, the three nominal kouprey reserves of Kampuchea were overrun by military forces.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p55.png"></center><br>
+ KOUPREY DISTRIBUTION. (AFTER C.H. WHARTON )</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1975 the kouprey stocks in Laos and Thailand were estimated at only 50 and 20 animals, respectively. By now, hunting and habitat destruction probably have all but eliminated the kouprey from Thailand. However, a reported sighting of five animals that had strayed across the border from Kampuchea was made in July 1982. (By the time Thai zoologists arrived to investigate, the herd apparently had crossed back into Kampuchea.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like the banteng, the kouprey inhabits open sites such as light savannas, woodland meadows, and scattered glades in the monsoon forests. It is adapted to dry country. This type of habitat is not widespread in Indochina, and the range of the kouprey is consequently limited.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kouprey spend most of the year among low rolling hills in open areas where grazing and visibility are good. These open areas are a fire climax mosaic of dry dipterocarp savannas and patches of dense forest. Fires occur each dry season, most of them deliberately set by man. Kouprey capitalize on the young growth in burned-over areas. They feed primarily on grasses, sedges, and tree leaves. They also require salt licks and a supply of water in the dry season.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The gestation period is thought to be about 8.5 months. Cows leave the herd before parturition and return with their calves after about a month. They nurse their calves for about 6 months.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kouprey are said to be even more shy than banteng and gaur. They feed in erratic patterns and are always alert and nervous.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Loose herds of 20 or more have been reported. These were of mixed composition, often with more than one adult male, and were usually led by an old female. Adult bulls sometimes form bachelor herds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kouprey utilize some of the same feeds as wild banteng, and the two animals often live in a loose association. They graze together, and, especially after the mating season, solitary kouprey bulls often associate with banteng herds. The two species do not, however, interbreed in the wild. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The kouprey is a candidate for domestication and has important potential as breeding stock. It is a wild animal, but it may have been domesticated temporarily during the Khmer culture, 400-800 years ago.* Both Vietnam and Laos have cattle breeds that resemble kouprey, and a kouprey bull, reputed to be a domestic animal of the Stieng tribe, was exhibited in the Paris Menagerie in the mid-nineteenth century. It may be that kouprey are domestic even today in parts of Indochina.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kouprey survival has worldwide significance. The animals could be important for studies of bovine evolution and as a genetic resource for crossbreeding to improve disease resistance and other characteristics of domesticated bovines. For instance, the kouprey is thought to be resistant to rinderpest, a killer disease of domestic cattle. Also, kouprey bulls are distinctive for their long dewlap, and they probably have more skin area for their weight than other bovines and are therefore better able to eliminate body heat. This genetic trait may help large cattle breeds survive in the tropics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The kouprey's potential may be moot - there may be none left in the world. It is feared that the warfare of recent years may have caused its extinction. However, if enough animals survive and can be protected, the kouprey could probably recover its numbers, as a higher calf-to-cow ratio (1:3) was reported for this species than for either banteng (1:4) or gaur (1:10).*</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If wild kouprey are found, their capture is likely to be difficult.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is a long-term sequence of research needs for the kouprey, which includes the following:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">.  Working with the governments of Thailand, Laos, and Kampuchea to identify any remaining pockets of this species and to establish conservation programs;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Establishing one or more captive breeding herds (because there is little chance of the animal surviving in the wild owing to the fighting and turmoil in the area);</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Studying the animal's basic physiology and production potential;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Exploring its possible commercial utilization; and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Investigating the kouprey's genetic relationship to zebu cattle and the transferability of genetic characters through interbreeding. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p58.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">9 Tamaraw</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The tamaraw (Bubalus mindorensis) is related to the water buffalo, one of Asia's most important animal resources, but it has never been domesticated or studied and is threatened with extinction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The tamaraw looks rather like a miniature water buffalo of the swamp type that is found in Southeast Asia. It reaches about I m in height and 300 kg in weight. It is much more stockily built and is blacker than the swamp buffalo. The tamaraw has white marks on the fetlocks, instead of completely white lower legs like the banteng, gaur, and kouprey. It has short (35-50 cm), very stout horns that curve out and back slightly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Endemic to the Philippine island of Mindoro the tamaraw is now virtually restricted to three small areas (Mount Iglet/Mount Baco, Mount Calavita, and Sablayon) in Mindoro Occidental.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of its limited distribution, the tamaraw's future is of concern to conservationists. Until World War II, hunting was carefully regulated in its native region and no serious concern was felt for the animal's safety. Since then, however, increases in human population, lumbering, and ranching have restricted the tamaraw's habitat, and the availability of rifles and automatic weapons has seriously threatened its numbers. In 1971, research teams counted 148 head, consisting of 116 adults and 32 calves. The latest estimate is 150-200 head.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Of these last remaining animals, about 80 are located at Mount Iglit, a game refuge established in 1961 primarily to protect the tamaraw. Recently an active tamaraw conservation program has been started in a 400-hectare enclosed area on the refuge. Stockade traps have been built and tamaraw are beginning to move into them. The goal is to establish a small, semicaptive population that can be properly guarded, studied, and managed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY"><center><img src="p61.png"></center><br>
+ Tamaraw distribution. (courtesy Wildlife magazine)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The habitat requirements of the tamaraw appear to be fairly flexible, and present habitat use reflects human pressures rather than the animal's preferences. In the past, tamaraw were found in virtually all parts of Mindoro, from sea level to mountain tops. They occupied open grasslands or glades, but hunting pressure and habitat change have forced it to retreat into forest environments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At present the tamaraw is found primarily in remote areas that have been partly cleared, largely by fire, so that only small pockets of trees remain among coarse grasses such as Imperata cylindrica (a widespread, unpalatable tropical weed commonly called cogon, kunai, alang alang, lalang, or blady grass), and "tahalib" (Saccharum spontaneum). The tamaraw uses the forest pockets for rest and retreat and the open land for grazing. It must have a supply of water for wallowing and drinking.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">According to cattlemen, tamaraw eat both Imperata grass and tehalib but only when these are short and green. During the wet season when most forages are tall and unpalatable, the animals are known to feed on bamboo shoots.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Life expectancy is about 20 years. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tamaraw are reputed to be nocturnal, ferocious, and retiring. However, in earlier times they were reportedly relatively tame, diurnal animals of open areas. It was the continual hunting that made them increasingly nocturnal and secretive, and like other wild bovids they can become aggressive and dangerous when harassed or wounded. Given effective protection they doubtless would revert to placid, diurnal behavior.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The tamaraw appears to be a possible livestock animal. Its meat and hides were highly regarded by local peoples, cattlemen, and visiting hunters. Because of its close relationship to the water buffalo, it may be able to provide genetic material for improving the health and hardiness of that valuable animal resource.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animal is renowned for hardiness and resilience to heat, humidity, and poor forage, as well as its capability to thrive in a variety of environmental conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tamaraws have only once produced offspring in a zoo and may prove difficult to raise in captivity. However, they have been kept in captivity so seldom that the prospects are unclear. Experiences with other wild bovids suggests that captivity and captive breeding should be no problem.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The tamaraw must be protected and preserved. There is urgent need, for example, to establish more secure parks in the Philippines to rebuild the wild population to safe levels. Other conservation measures should include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Establishing and maintaining more reserves in natural habitats containing breeding populations, and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Building up breeding populations in suitable zoos and livestock research centers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research is needed on the tamaraw's physiology, production characteristics, behavior, and genetic relationship to the water buffalo. None of these is well understood. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p63.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">10 Anoas</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The lowland anoa (Bubalus depressicornis) and the mountain anoa (Bubalus quarlesi)* are small bovines that are related to the water buffalo but that are scarcely bigger than goats.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Compared with other bovines, the anoa is tiny. It stands only 0.75-1 m tall at the shoulder. The mountain anoa is smaller than its lowland counterpart. The limbs are short, the body plump, and the neck thick.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anoa horns are short and straight, reaching a maximum length of about 380 mm; they are ringed and triangular in cross section at the base in lowland species and simple and conical in cross section in mountain species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although the young are thickly covered with yellowish-brown woolly hair, the mountain anoa adults tend to have curly hair, while lowland anoa have straight hair or are hairless. Adults vary from dark brown to black, with frequent blotches of white on the face, nape, throat, and lower limbs. In mountain anoas the entire lower limbs are creamy white. The underbody parts are usually light brown. Males are generally darker than females.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The hide is exceptionally thick.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anoas are native to dense, mature forests of Sulawesi in eastern Indonesia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Both species are abundant and well distributed on Sulawesi. Most of the northern, eastern, and southeastern peninsulas and the central area of Sulawesi are still forested and have anoa populations, and there are several large nature reserves to protect them. *</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Several of the world's zoos have anoa collections (see Research Contacts).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The climate of Sulawesi is hot, but tempered by sea winds; annual rainfall varies from 500 mm to 4,000 mm. The eastern and southeastern peninsulas have a sparse population and a scattering of subsistence agriculture.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The lowland species is found in forests and was once common along the coasts. The mountain anoa is found in primary forests at high altitudes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY"><center><img src="p66.png"></center><br>
+ DISTRIBUTION OF ANOA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anoas have a wide-ranging diet that includes grasses, ferns, saplings, palm, ginger, and fallen fruit, especially figs. It is of particular interest that the animals can live on a diet that contains no grass.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anoas have a high requirement for minerals. They visit mineral-rich hot springs and salt licks, and they even drink from the sea.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The San Diego Zoo in the United States and Surabaya Zoo in Indonesia have successfully bred and reared the animals in captivity. The gestation period is 276-315 days, and there is generally only a single birth. The life expectancy is about 20-25 years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anoas are shy animals, but they can be aggressive. The sideways and upwards stab of their straight, sharp horns can be dangerous.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Except when the cows are about to give birth, anoas apparently associate in pairs rather than in herds. They enjoy water and frequently wallow in mud. Their gait is a trot, but a times they make clumsy leaps. During the morning they feed alone. In the heat of the afternoon they seek refuge under shade trees.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On Sulawesi anoas are prized for their hide, horns, and meat. The flesh, especially that of calves, is tender and well flavored.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although somewhat aggressive and pugnacious, anoas might make a suitable livestock animal. They grow and reproduce well in captivity and are adaptable and intelligent. Their small size makes them easier to handle than many other wild bovines.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Little is known about the habits of these animals because of their wary nature, secluded environment, and restricted range. They can be tamed enough to obey commands ("lie down," for example) but they remain nervous and likely to butt strangers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Surveys are needed throughout Sulawesi to determine the distribution and taxonomy of possible races of the two species, with a view to establishing a protected-area system that will ensure the survival of the genetic diversity of this group.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research is also needed on social organization and tameability, as well as on the anoa's biological relationship to the tamaraw and water buffalo.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One target should be to build up the zoo populations of both species. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p68.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Part IlI : Pig and Piglike Species</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In parts of Asia wild and feral pigs are often the most abundant source of meat. These animals are predominantly variants of the domestic pig, Sus scrofa, or of its ancestor, the Eurasian wild boar. Also contributing to the pig population are five Asian species:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Bearded pig</P>
+<P ALIGN="JUSTIFY">· Sulawesi warty pig</P>
+<P ALIGN="JUSTIFY">· Javan warty pig</P>
+<P ALIGN="JUSTIFY">· Pigmy hog</P>
+<P ALIGN="JUSTIFY">· Babirusa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Southeast Asia hybridization between these species and common pigs has resulted in a confusing diversity of forms and interrelationships. Because of their value, these pigs have been spread since prehistoric times by traders and migrating peoples, creating odd and unpredictable distribution patterns.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The species listed represent a gene pool of potential importance for the further development of one of man's most important sources of food. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In many areas of the world, one must start with the native animals adapted to that environment. In many cases, they are the only animals the native human population can afford to begin with. And it is amazing the increased animal production that can result from the use of better production practices with them. TONY J. CUNHA, Dean Emeritus California State Polytechnic University Pomona, California, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fitting the animal to the vegetation might be a better approach than trying to fit the vegetation to the animal, especially on ranges that have been changed or degraded by man. JAMES TEER, Director Texas Parks and Wildlife Department, Austin, Texas, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is now widespread realization that breed importation is not necessarily the quickest route to increased animal production. Indigenous, adapted breeds should be examined more closely and, where necessary, steps should be taken to ensure conservation of at least some of them. HELEN NEWTON TURNER Genetics Research Laboratories, CSIRO, North Ryde, New South Wales, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Maximizing the animal harvest, essentially of animal protein, assumes in concept that all animals will be fully exploited in efficient and economic production systems. C.DEVENDRA Malaysian Agricultural Research and Development Institute, Selangor, Malaysia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p70.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">11 The Bearded Pig</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although it apparently has never been domesticated, the bearded pig (Sus barbatus) has a long history as an important resource in Southeast Asia. Human remains from the Niah Caves in Sarawak are accompanied by large numbers of its bones and teeth, indicating that 40,000 years ago it was the most commonly eaten large animal. Today in Sarawak and some other areas the bearded pig is still probably the most sought after source of wild meat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bearded pigs are large. Boars measure 1-1.6 m in length (crown to rump), up to 1 m in height, and may weigh as much as 150 kg. Sows are smaller. Adult males have small facial warts (infraocular and preocular) and a bushy tuft of hair on the cheek. Both sexes vary in color from pale red-brown to yellow-brown or black. They have elongated skulls with longer, more flexible snouts than the common pig.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Five subspecies are recognized. They range through the Philippines (Balabac, Palawan and offshore islands, Calamianes, Luzon, Mainit, Mindanao, Jolo, Mindoro, and Cebu) to Borneo, Bangka, Sumatra, the Riau Archipelago, and the Malay Peninsula.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Borneo subspecies (Sus barbatus barbatus) is still abundant in some parts of Sabah, Sarawak (including several wildlife reserves), and </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kalimantan. It remains an important food resource for some hill tribes, although with the spread of Islam, attitudes toward pork are changing in some areas. The Malayan subspecies (Sus barbatus of) is now rare in the Malay Peninsula. It is also becoming rare in Sumatra as the lowland forests are logged and broken up by commercial interests and as the human population expands. The status of the three Philippine subspecies is currently unknown.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The bearded pig is most commonly found in both primary and secondary evergreen forests. However, it seems to have wide adaptability, and in Sarawak bearded pigs are found in virtually all habitats from the beaches to the upland rain forests.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">No biological research has yet been conducted on bearded pigs, but naturalists have made several observations. The pigs eat the seeds of trees (for example, those of species of Dipterocarpaceae and Fageceae), fallen fruits (of Moraceae, Bombacaceae, and other plant families), roots, stems of wild bananas, herbs, and probably earthworms, and along the coast they dig up and eat turtle eggs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Births occur throughout the year in Sabah, but the peak coincides with the fruiting season of forest trees, usually August-September. The litter size is from 3 to 11 piglets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p73.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">No behavioral studies have been conducted, but observations suggest that bearded pigs are generally sedentary animals, although in some areas they congregate into large groups that may travel long distances together.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The species might be used (alone or together with other pig species) as a local source of meat, or even as the foundation of a meat industry. The bearded pig is accustomed to living in groups, which may make it suitable for husbandry or game management.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is evidence that the bearded pig will interbreed with the common pig, producing young in which both sexes are fertile.* The progeny might have considerable hybrid vigor.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The bearded pig may have tolerance (if not actual resistance) to tropical diseases and conditions that affect the common pig. The species survives in areas of Southeast Asia where feral herds of common pigs are not common, apparently owing to their inability to cope with disease or other environmental challenges.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">No negative qualities have been reported, but the animal's biology, behavior, management, and potential uses are so far virtually unstudied.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Aspects of the animal's general biology that should be investigated include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Chromosome type and variability, and chromosomal differences between the bearded pig and other wild and domesticated pig species</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Reproductive physiology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Nutritional physiology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Social behavior (both in its wild state and under controlled conditions).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To assist in the selective capture of young bearded pigs in the wild, external features that characterize the species at an early age need to be identified.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To assess the bearded pig's potential for contributing hybrid vigor, crossbreeding with other pig species should be attempted under controlled conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">12 The Sulawesi Warty Pig</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Sulawesi warty pig (Sus celebensis) is one of the world's few domesticated animals. It is maintained as a village or household animal in a few areas of Southeast Asia, such as on the Indonesian island of Roti. The common pigs of New Guinea and parts of the Moluccas group are hybrids between this species and the common pig.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sulawesi warty pigs are medium sized, averaging about 60 cm high and 40-70 kg. Boars are larger than females and have longer (10 cm) tusks on both jaws. Boars have three pairs of prominent facial warts: on the snout, the cheek, and on the angle of the jaw. In sows these warts are small or absent entirely.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals are usually red-brown with sharply marked white and yellow undersides; older animals have a round white spot (about 3 cm in diameter) on each side of the upper cheek. Piglets have horizontal stripes on the body, which disappear as they mature.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The body is covered with scanty coarse hair, but stiff bristles, which become erect when the animal is alarmed, occur along the mid-dorsal line of the body. The longest and stiffest occur on the head and nape.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Native to mainland Sulawesi and certain surrounding islands, the Sulawesi warty pig has been introduced to the Lesser Sunda Islands (Flores, Sumba, Roti, Semau, and Timor), the Moluccas (Malmahera and Buru), and Simaleue, a small island west of Sumatra. In some parts of the Philippines (for instance, Naujan and Mindoro Oriental) the animal either occur naturally or has been introduced. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hybrids between the Sulawesi warty pig and the common domestic pig occur on New Guinea, Ternate, Morotai, Bacan, Amron, Seram, Kei island, Aru island, and Sulawatti.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In many islands of eastern Indonesia, this species is widespread and common. In a few places it is extremely abundant, particularly at higher altitudes; in others, it has been greatly reduced by overhunting, deforestation, and expanding human settlement.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Overall, however, Sulawesi warty pig populations are declining, probably due to increased hunting and to human alterations of the animal's habitats.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This pig inhabits varied environments, including rain forest, mountain forest, grasslands, and agricultural areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p77.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like the common pig, the Sulawesi warty pig has broad dietary preferences. It feeds on roots, fallen fruit, leaves, and young shoots. The bulk of its food consists of vegetable materials, but it also feeds on earthworms, insects, aquatic invertebrates, rats, birds, and even carrion.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The uterus and placenta are anatomically indistinguishable from those of the common pig. The litter size is from 2 to 8 piglets, with an average of 5.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sows can give birth throughout the year, but usually have their young in April or May. The gestation period is about 4 months.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Breeding and farrowing occur in the forest and in open Imperata cylindrica grasslands. The pregnant female makes a nest of grasses, leaves, twigs, and branches, which she collects and places over a hole (approximately 2 m long) that she has previously dug. Here she gives birth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Foraging is the main activity of the day and usually takes up several hours, mainly in the early morning and evening. In the wild the pigs travel in small groups, the young always traveling with an adult female. On the move, warty pigs feed and rest intermittently.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As a source of meat the Sulawesi warty pig has been recognized and exploited by local populations since prehistoric times. The presence of feral specimens far outside the pigs' natural range indicates that traders or migrants have long carried it with them on voyages, either as domestic stock or as wild specimens to be released for later capture.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The tusks, which can be carved like ivory, are a resource for local artisans. Wild specimens are suitable for sport hunting.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is a body of unrecorded indigenous experience with this animal as a domesticate, but the information needs to be collected and appraised.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The Sulawesi warty pig may be expected to possess resistance or tolerance to the many diseases prevalent in its native habitat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is promising potential for hybridization between this species and domestic pigs, which might lead to the improvement of common pigs in tropical regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Apart from the unwritten knowledge of the indigenous people who raise the species, very little information is available on the characteristics and management of this animal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The genetic variability within the species, as well as the karyotypic differences with common pigs and other Sus species, should be defined. Further, the hybrid vigor resulting from crossbreeding with other Sus species should be- quantified under controlled conditions. Apart from producing potentially important heat-tolerant livestock, crossbreeding may shed important light on the origins of the common pig in Asia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animal's nutritional requirements and reproductive biology also need study. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p79.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">13 Javan Warty Pig</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Javan warty pig (Sus verrucosus) apparently has never been domesticated, but it has been a resource for hunting peoples for centuries. Now, however, the human population in its native region is predominantly Moslem, and all pigs are widely regarded as agricultural pests. Increasing numbers of them are poisoned each year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Javan warty pig can be up to 1.35 m long and 0.9 m tall. Mature males usually weigh between 80 and 120 kg; females are only half that weight - an unusually dramatic example of sexual dimorphism. The animal has a markedly elongated face with large warts, particularly the infraorbital wart and the smaller preorbital and mandibular warts. Body hairs can be black, red, or yellow, with black tips.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This species is found only on the Indonesian islands of Java and Bawean. It was formerly found on Madura as well, but because of deforestation it is now thought to be extinct there. Two extant subspecies are recognized. The nominate one, Sus verrucosus verrucosus, occurs on mainland Java. The second, Sus verrucosus blouchi, a smaller animal, has recently been described on Bawean.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For years it was thought that the Javan warty pig was extinct in the wild, but in October 1981 a herd was found in a small area on Mount Penanggungan in East Java. This population may prove to be substantial, and there is reason to hope that other populations can be found. Overall, however, it is clear that the Javan warty pig is endangered and declining in numbers. In many areas the animals are subjected to uncontrolled poisoning and hunting.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Five new reserves have recently been proposed to protect the animal in a variety of habitats because it is not found in appreciable numbers in any of Java's nature reserves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Bawean subspecies is believed to be relatively secure since the establishment of a large reserve.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A breeding colony of 12 Javan warty pigs at the Surabaya Zoo includes 5 young ones born in captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitats of the Javan warty pig appear to be confined to elevations below about 800 m. The animals prefer relatively large expanses of grassland or secondary vegetation, where human population is sparse. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p82.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The piglets can be born throughout the year; in one study of 8 sows the litter size ranged from 2 to 8, with a mean of 5.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The (diploid) chromosome number has been found to be 38, the same as that of the common pig. Hybridization between these species is thought to occur in the wild, but apparently not with enough frequency to contaminate the Javan warty pig gene pool.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unreported.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These are omnivorous, adaptable animals that might make useful domesticates.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The small size of the sows could make this species particularly appropriate for households or smallholder farms. The animal's genetic "distance" from the domestic pig may make it a useful generator of hybrid vigor in crossbreeds. It could have particular value because its meat is much leaner than pork from the common pig.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The numbers in the wild are now too few to permit any cropping.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Efforts should be directed towards locating and breeding up the Javan warty pig populations that still exist. An immediate need is to isolate pure populations in reserves because it is essential to protect the animal from crossbreeding with other species. In addition, current specimens in zoos should be cataloged and a breeding program established. Other captive breeding colonies should also be started.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is important to determine the genetic differences between the Javan warty pig and the common pig, as well as the levels of existing hybridization between them. It is also necessary to determine what variation in karyotype may exist within the populations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Basic ecological and behavioral studies are needed, as well as studies of the dietary requirements, growth rates, and nutritional physiology of captive specimens. The reproductive biology of the animal should be studied, and the possibility of crossbreeding it with other Sus species should be examined under controlled conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Javan warty pig's potential for local meat production should be evaluated. The benefit to rural people of converting an agricultural pest into a profitable source of income should be explored within the local religious context. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p84.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">14 Pigmy Hog</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The pigmy hog (Sus salvanius), a shy and very small pig of northeastern India, is close to extinction because of hunters and the destruction of its habitat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The pigmy hog is only about 60 cm long, with a shoulder height of about 25 cm and a body weight of less than 10 kg. The hair is medium brown on the sides, darkening to blackish brown along the mid-dorsal line. A facial band of short, dark hair extends from the bridge of the nose to below the eye. The tiny tail is only 3 cm long.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This animal was once widely found along the southern foothills of the Himalayas; today, it is definitely known to occur in only one area, the Manas National Park in Assam.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigmy hogs are seriously endangered; in the wild they are close to extinction. Captive animals are now reduced to a single male in the Assam State Zoo and four male siblings in the Zurich Zoo.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The few remaining pigmy hogs mainly inhabit tall-grass savannas, but it seems likely that they could adapt to other environments. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigmy hog. (W.L.R. Oliver)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animal is omnivorous and consumes roots, tubers, grass, leaves, insects, earthworms, eggs, and carrion. While foraging, it undoubtedly consumes large quantities of earth as well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The chromosome number, 38, is the same as that of the common pig. The karyotype is similar to that the common pig, but small, significant differences have been demonstrated using chromosome banding techniques.*</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The age at puberty, time of weaning, length of gestation and estrous cycle, and season of breeding are not yet known with certainty. However, the animal is known to have a single well-defined birth peak (April/May) that coincides with the onset of the rainy season when the food supply increases. The uterus and placenta are anatomically similar to those of the common pig. The litter size varies from 2 to 6. It is not known if the animal can be crossbred with the common pig.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY"><center><img src="p87.png"></center><br>
+ Distribution of pigmy hog. (W.L.R. Oliver)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals are shy, but can be tamed. They tend to forage and run in groups. Nest building is carried out by both males and females and is not restricted to pre-farrowing periods.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is no evidence that the pigmy hog has ever been domesticated; it has, however, been extensively hunted and trapped, and recently it was still being sold for human consumption. There would probably be no inherent difficulty in maintaining this species in husbandry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The pigmy hog's small size may make it useful in studies of the physiology of pigs and like mammals. In particular, a study of the uterine capacity may contribute to our understanding of the maternal factors that influence the number and size of mammalian young at birth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is unknown if the animal carries genetic resistance to diseases of the domestic pig, but given its habitat, such resistance seems likely.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The small numbers of surviving pigmy hogs obviate any consideration of its use in husbandry at the present time. Moreover, its nervous temperament might restrict its potential as a domesticate. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is essential to ensure the survival of this animal. Efforts should be directed towards locating and breeding up the populations that still exist. If its habitat could be protected by preventing the annual dry-season burning of grasses, it is possible that substantial populations could be established. Attempts should also be made to acquire two or more females as mates for the male pigmy hogs at the Assam and Zurich zoos.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is also an urgent need to ensure that the animals breed successfully in captivity, and the wealth of international expertise in pig reproduction should be applied to that end. For example, the reproductive biology of the animal could be studied by swine experts; the age at puberty, the length of the estrous cycle, the season of breeding (and whether it is influenced by light or temperature), the length of gestation, and time of weaning all need to be determined.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animal is an omnivore, but the physiology of its digestion has not been studied. Thus, its nutritive requirements are not well enough known to ensure its survival in captivity or reserves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Experiments should be made to determine if pigmy hog embryos can be brought to term in the uterus of the common pig. If so, such embryo transfers could be used to distribute embryos and set up new herds, lessening the risk of this species" extinction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p88.png"></center><br>
+ Adult male of the common pig (wild boar Sus scrofa) and pigmy hog drawn to the same scale. (W.L.R. Oliver) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">15 The Babirusa</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The babirusa (Babyrousa babyrussa) is a piglike animal whose closest relative appears to be an ancestral animal that lived in Europe 35 million years ago. It is easily tamed, and in its native area there is an ancient tradition of raising young babirusa for meat and for the males' unique tusks. The animal appears to reproduce well in captivity, and with good management techniques it might gain wide use in the tropics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appearance and Size</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Male babirusa can be up to 110 cm long and 80 cm tall and weigh up to 100 kg; females are smaller. The male has large upper canines that grow upwards, piercing right through the flesh of the snout and curving back and downwards towards the forehead without ever entering the mouth. The female may sometimes have small upper canines projecting through the skin of the upper lip.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animal is more slender than a pig of similar size. It has a gray or brown-grey skin color, although one subspecies, Babyrousa babyrussa babyrussa, has light body hair that is fawn colored or black.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The babirusa is unique to a few islands of eastern Indonesia: north, central, and southeast Sulawesi, the Togian Islands, and the Sula (Taliabu and Sulabesi) and Buru Islands. On Sula and Buru it is probably not native but was introduced in prehistoric times.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On Sulawesi the babirusa remains abundant, despite hunting and the widespread clearing of the forest. Nevertheless, disturbances created by wood and rattan collectors, hunters, loggers, and farmers threaten the babirusa's survival. Throughout the rest of its range, it is also vulnerable to extinction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biologists are particularly concerned about some of the babirusa subspecies. The one from the north of mainland Sulawesi, Babyrousa babyrussa celebensis, is still relatively abundant in places and is probably in no immediate danger. The Togian Islands' subspecies, Babyrousa babyrussa togeanensis, is abundant in small islands but is threatened by Indonesia's settlement programs and deforestation. The Buru and Sula Islands subspecies, Babyrousa babyrussa babyrussa, may already be extinct; there have been no confirmed sightings in recent years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1981, there were 26 male and 27 female babirusa held in six zoo collections; 22 of these animals are in the Surabaya Zoo in Indonesia, where they breed well. Most, if not all, are believed to belong to the mainland Sulawesi race.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat and Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The animals mainly inhabit moist forests at low altitudes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p91.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Biology</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Precise details of babirusa biology are unknown, but the stomach has an extra sac, suggesting that the animals may have some ability to break down cellulose. Indeed, they browse leaves, a behavior more often found in a deer than in a pig, and have been referred to as "ruminant pigs." Babirusa also live on roots, berries, and grubs, making them true omnivores. Compared to other pigs, they do little rooting, and in captivity their enclosures remain quite grassy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Babirusa are said to be sexually mature at 5-10 months, but this depends on nutrition. Gestation length is about 158 days. One or two young are produced although there are some reports of litters of three.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One specimen was kept for 24 years in captivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Behavior</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The babirusa is a social animal that moves in groups. A retiring native of the dense jungle, it is a fast runner and swims readily. Mating behavior in captivity generally resembles that of domestic pig. Evidence from zoo animals suggests that the male must be removed from the young at birth but that by the time they are a month old the young are safe from paternal attack.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uses</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When captured young or reared in captivity, the babirusa is easily tamed. It has potential as a domesticated species, and with appropriate management may provide a useful source of meat. The meat is tasty and of good quality.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of its unique tusks, the skull of the male finds ready markets. This could provide additional income to farmers raising babirusa for meat. The ivory of the tusks could also be a resource for local artisans.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Potential Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As noted, the anatomy of the stomach suggests that the babirusa may be able to make more efficient use of fibrous foodstuffs than other pigs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Limitations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The babirusa produces only one or two young after a gestation period of just over five months; it may therefore take considerable time to build up herds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although the babirusa is easily tamed, it is not known whether it can be husbanded in large groups. Also, present lack of knowledge of the animal's nutrition may restrict its husbandry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Conservation Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The number of animals in the wild is decreasing, and attempts should be made to determine their exact status. Particular attention should be paid to the subspecies Babyrousa babyrussa togeanensis and Babyrousa babyrussa babyrussa. Captive breeding programs for these subspecies should be started.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p93.png"></center><br>
+ When seen in longitudinal section, the stomach of babirusa presents striking similarities  to that of a relatively simple ruminant such as the domestic sheep. Every part except the  omasum, even including a rudimentary reticulum, is represented and occupies the same  relative position. The babirusa stomach differs from that of the domestic pig chiefly in  the enormous size of the diverticulum ventriculi, the prominence of the constrictions  that delimit its three main divisions, and in the size and complexity of the cardia. Regions  corresponding to parts of the ruminant stomach are labeled in brackets. (Information  from Davis, 1940; diagram courtesy Field Museum of Natural History, Chicago.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild populations should be maintained in several regions to ensure that  the species" genetic base is retained. Advantage could be taken of the large  number of islands in eastern Indonesia to establish reserves for the different  babirusa subspecies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Currently, little is known about the biology of the animal in the wild its  diet, social behavior, or reproductive performance are almost unstudied. In  view of the relatively small number of babirusa in zoos and the scarcity of  information about the animal's growth rate and general biology, coordinated  studies between zoos could provide much basic information. It has been  suggested that a studbook be initiated for this species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is clear from chromosome analysis that this pig differs markedly in  its karyotype from that of other pigs. However, more anatomical and  biochemical knowledge is needed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Basic parameters of the animal's reproductive physiology are not known.  Questions to be answered include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Can the babirusa be induced to reproduce twice per year?</P>
+<P ALIGN="JUSTIFY">· Can babirusa embryos be developed to term in the uterus of the domestic  pig? If so, can the number of babirusas be rapidly multiplied in this way?</P>
+<P ALIGN="JUSTIFY">· Does the babirusa genotypic and gestation-length difference with the  common pig prevent the two from successfully crossbreeding? And if  crossbreeding can be achieved, will the progeny be fertile?  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p94.png"></center><br>
+ FIGURE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Part IV : Recommendations and  General Research  Needs</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Asian animals described in this report are a natural resource whose  potential is barely glimpsed. They are virtually unknown to established  livestock interests and there has been little thought to developing them as  livestock. As a result, the research and trials that could lead to further use of  these animals is scattered, small scale, and conducted outside the mainstream  of livestock science, mainly by wildlife conservationists.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yet these animals seem worth considering for use in husbandry in many  tropical regions, especially where poor grazing and harsh environments limit  the performance of conventional livestock. There is a pressing need for  research to develop these species and to explore their potential. Only through  rapid action can many of them be kept available for study and possible  inclusion in agriculture.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One suggestion is that funds be provided to establish an Asian  native-livestock research-support team. Its primary purpose would be to  assist in the funding of research projects and to coordinate research being  done in various Asian countries. The team's goal would be to establish a  network of animal scientists based at institutions in Asia and elsewhere to  work cooperatively on the region's little-known bovines and pigs. In this  manner, relatively small sums of money could be used to stimulate and  coordinate Asia-wide research on indigenous animals.*</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Basic Research</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The time has come for basic studies on each of the 15 animals discussed in  this book. For each species, the following areas should be investigated:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">· Physiology</P>
+<P ALIGN="JUSTIFY">· Reproductive requirements and fertility</P>
+<P ALIGN="JUSTIFY">· Nutritional requirements (such as food preferences, feeding strategies, and food utilization)</P>
+<P ALIGN="JUSTIFY">· Growth</P>
+<P ALIGN="JUSTIFY">· Adaptability and environmental tolerance (for instance, water balance, sweat rate, and shade-seeking habits, as well as temperature, pulse, and respiration rates, both under normal conditions and heat stress)</P>
+<P ALIGN="JUSTIFY">· Diseases</P>
+<P ALIGN="JUSTIFY">. Management (including stocking rates and other production characteristics</P>
+<P ALIGN="JUSTIFY">· Genetic selection for calm temperament, quick growth, and other desirable qualities</P>
+<P ALIGN="JUSTIFY">· Crossbreeding to take advantage of hybrid vigor</P>
+<P ALIGN="JUSTIFY">· Social structure (for example population density and distribution, social organization, leadership, herding potential, aggressiveness of bulls)</P>
+<P ALIGN="JUSTIFY">· Habitat characteristics (behavior-habitat interactions and herd dynamics, for instance).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Studies are also needed on better utilization of products, such as milk, meat, hides, horn, and hair, from these animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Experimental transfer of fertilized eggs of all of these animals into domestic species should be explored with a view to establishing herds in secure and disease-free areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Efforts specific to domesticated and wild species, and to hybrids of these species, are discussed below. The report concludes with brief discussions of a few promising species not taken up in the body of the text.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Domesticated Species Improving Performance</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Little data is available on the performance of the domesticated animals discussed in this report. Yet the main value of these species lies in the new and superior genes and gene combinations that can be adapted to animal production in the tropics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Studies need to be conducted with the indigenous species and strains in their native countries to determine if they will respond to improved conditions with improved performance. These projects could provide opportunities for geneticists and animal breeders to improve livestock production while conducting challenging basic research. It would be helpful to establish studbooks of captive specimens and to select and breed for desirable genetic qualities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Genetic improvement must be directed towards remedying production deficiencies. Methods include selection of superior breeding animals, crossbreeding, and combinations of selection and crossbreeding. Different genetic improvement techniques will be required for each species. Progress should be regularly monitored against the unselected animals and the domestic livestock breeds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">New Introductions</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tropical countries should import breeding stock to evaluate the performance of some of these Asian animals in the local environment. Strict quarantine procedures must, of course, be observed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Special emphasis should be placed on the domesticated banteng of eastern Indonesia. These animals are already an important source of human food and they may have considerable potential for increasing production elsewhere.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild Animals</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild animals contribute extensively to the welfare of people and economies of developing countries. In many areas they supply much of the animal protein consumed. But the contributions they make are largely unrecorded, and local officials and aid agencies seldom regard wildlife as an economic resource. As a result, few developing countries have analyzed how their people use indigenous animals for subsistence, and few nutritional studies recognize "bushmeat," although large numbers of people eat it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wildlife's contribution justifies more detailed and precise evaluations. In many tropical regions few people even know what species are present, let alone in what numbers. Ecologists and animal scientists should be employed to identify and collect data on the fauna of the tropical forests and how it is used by local people. Their work will provide baseline information on the species present and on the potential utility of the undisturbed natural ecosystems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Initial Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All wildlife utilization must be based on a thorough knowledge of the resource, its numbers, the animals' condition, annual recruitment in the </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">various populations, and the seasonal movements of the herds. In addition, it is important to understand the interactions of the species with its habitat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thus, the immediate need is for action to assure the preservation of populations of these animals until research studies can be conducted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this regard, priority actions include the following:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Establishing adequate preserves</P>
+<P ALIGN="JUSTIFY">· Providing total protection for remaining animals</P>
+<P ALIGN="JUSTIFY">· Preventing poaching.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With few exceptions, the wild species described in this report are under the pressures of agricultural and human expansion. Without efforts to preserve their habitats it will be difficult for these species to survive.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Developing Wildlife Resources</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Governments cannot stop hungry people from hunting game, but they can use this impetus to help protect some indigenous animals as well as forest and woodland habitats. Fostering the production and supply of wild animals such as those described in this book could open up a new: source of meat and other products, particularly for subsistence farmers in remote areas. In the last analysis, this may be the only way of protecting and maintaining these animals and developing local awareness of their value.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">International economic development organizations have traditionally shown little interest in wildlife or wildlife habitats. Yet maintaining these animals and their habitats is crucial to the continuing supply of many indigenous food animals, the most important of which are often the smaller ones that flourish in secondary growth. And the forests that support wildlife also protect some of the huge investments that AID, the World Bank, and other other agencies have made to help developing countries. The forest is the sponge that absorbs the water from tropical rains. Without trees covering the watersheds, heavy rains cause rushing water that erodes the land, despoils highways, silts up dams and reservoirs, knocks out bridges, and inundates towns, villages, and farm fields.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In principle, the farming of tropical wildlife could become a force in preventing clear-felling of the tropical forests. Rational utilization of tropical animals offers productive alternative use of the land. In some cases, the farming of indigenous animals can fit smoothly into tropical habitats and into traditional village life, because the livestock and its needs are usually familiar to local people and are often ingrained in their traditions.( For successful examples see companion reports nos. 44 and 45, Butterfly Farming in Papua New Guinea and Crocodiles as a Resource for the Tropics. </P>
+<P ALIGN="JUSTIFY">Hybrid Animals)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Hybridization may offer new prospects for using underexploited tropical animal resources. This is a speculative notion, but it deserves serious attention.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crossbreeding between the animals mentioned in this report holds exciting possibilities for expanding livestock options in the tropics. Some of the crosses, known or envisaged, are:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· gaur x cattle</P>
+<P ALIGN="JUSTIFY">· banteng x cattle</P>
+<P ALIGN="JUSTIFY">· kouprey x cattle</P>
+<P ALIGN="JUSTIFY">· yak x cattle</P>
+<P ALIGN="JUSTIFY">· yak x banteng</P>
+<P ALIGN="JUSTIFY">· anoa x water buffalo</P>
+<P ALIGN="JUSTIFY">· tamaraw x water buffalo</P>
+<P ALIGN="JUSTIFY">· domestic pig x warty pigs</P>
+<P ALIGN="JUSTIFY">· warty pigs x bearded pig</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Care must be taken, however, to guard against the dilution of wild genes by the escape of hybrid or interbreeding domestic species, or the establishment of feral hybrid populations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">International Exchange of Pig Germ Plasm</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Present veterinary restrictions effectively prevent the movement of pigs between most countries. Relatively few species of wild pigs are therefore maintained in zoos outside their countries of origin. This stifles the promising potential for the species described in Part III, as well as for captive-breeding safeguards and research on the endangered species. It is important that attempts be made to identify channels for the future establishment of viable captive stocks both within Asia and elsewhere. Transfer of embryos should be verified as a means of permitting disease-free movement across frontiers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Species Not Covered in this Report</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This project, which began as a short report on banteng, quickly developed momentum as it brought in suggestion after suggestion of further species. Through pressures of time and budget, it was not possible to take up all of these interesting animals. Some of the omitted ones are listed below. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Takin (Budorcas taxicolor).* A heavily built, Southeast Asian hoofed mammal of the family Bovidae, the takin lives in small herds in the mountains, often above timberline. Though robust and short-legged, it can move about quickly and easily over difficult slopes. It stands up to about 1 m at the shoulder and has a shaggy yellowish- to blackish-brown coat. Both sexes have heavy horns that turn outward from the center of the forehead and then curve up and backward.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goral (Naemorhedus goral).* This small Asian goatlike bovine has slightly backward curving cylindrical horns and a coarse brownish-grey coat. It is related to the chamois and serow (see below) but is distinguished from them by peculiarities in skull form, as well as by smaller size, shorter horns, and the absence of face glands. Gorals are native to a vast area, ranging from the Himalayas to eastern Siberia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Serow (Capricorhis sumatrensis). The serow has been called a "goatantelope." Found in Sumatra, the Malay Peninsula, Vietnam, Thailand, Burma, the eastern Himalayas, and China, it lives on forest-clad slopes, such as the mountains of southern China that are the home of the giant panda. Serows have coarse black hair, long pointed ears, a distinct mane, and short, backward pointing horns.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Native species of goats are also valuable genetic resources of Asia and examples include ibex (Capra ibex), markhor (Capra falconeri), and bharal (Pseudois nayaur). There are also various species of sheep, including the various races of argalis (Ovis ammon), which form small herds in the mountains, often above timberline. Although robust and short-legged, these animals can move about quickly and easily over difficult slopes. Soviet animal breeders apparently are exploring some of the possibilities of using argalis in animal husbandry. They are crossing domestic sheep with arkhar (Ovis ammon karelini) to produce a commercially viable hybrid.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The marketable size of lamb might be increased appreciably to provide larger, leaner cuts of meat by crossing domestic sheep with the Marco Polo sheep (Ovis ammon polii), which is as big as deer and has a mature body weight of 400-500 pounds. Marco Polo sheep meat is reported to have none of the "mutton" favor of domestic sheep. Thus, crosses might enhance consumer acceptance of sheep meat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Asia also has several species of deer that could have been included.§ The musk deer (Moschus moschiferus) is now domesticated in China for musk production and is a resource with a promising future. Also, sambar deer (Cervus unicolor), Asia's largest deer, may prove useful in husbandry. Several deer species are being farmed in New Zealand and ruse deer (Cervus rusa), which are native to South and Southeast Asia, are being farmed in Mauritius, Australia, and Papua New Guinea for meat and medicinal by-products. Two small, goat-sized Asian deer, the hog deer (Cervus porcinus) and the barking deer (Muntiacus muntjak), may also be worth considering. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p101.png"></center><br>
+ KOUPREY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendixes</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Selected Readings</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">General</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bohlken, H. 1961. Haustiere und Zoologische Systematik. Zeitschrift fur Tierzuchtung und Zuchtungsbiologie76:107-113.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Boonsong Lekagul, and J. A. McNeely. 1977. Mammals of Thailand. Association for the Conservation of Wildlife, Bangkok, Thailand. 758 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Corbet, G. B., and J. E. Hill. 1980. A World List of Mammalian Species. British Museum of Natural History, London, England.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Groves, C. P. 1981. Ancestors for the Pigs, Taxonomy and Phylogeny of the Genus Sus. Department of Prehistory Technical Bulletin No. 3. Australian National University Press, Canberra, Australia. 96 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gray, A. P. 1972. Mammalian Hybrids: A Check-List with Bibliography. Commonwealth Technical Communication No. 10 (Rev.). Bureau of Animal Breeding and Genetics, Edinburgh, Scotland.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Honacki, J. H., K. E. Kinman, and J. W. Koeppl. 1982. Mammal Species of the World. Allen Press, Lawrence, Kansas, USA. 694 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mochi, U. and T. D. Carter. 1953. Hoofed Mammals of the World. Charles Scribner's Sons, New York.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Payne, W. J. A. 1970. Cattle Production in the Tropics. Longman, London, England.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robbins, C. T. In Press. Wildlife Feeding and Nutrition. Academic Press, New York, USA.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Walker, E. P. 1975. Mammals of the World. The Johns Hopkins University Press, Baltimore, Maryland, USA, and London, England.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wharton, C. H. 1969. Man, fire and wild cattle in Southeast Asia. Tall Timbers Fire Ecology Conference 8: 107-167.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Domesticated and Wild Banteng</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appleton, D. C., G. Dryden, and A. C. Kondos. 1976. A comparison of the digestive efficiency of the water buffalo and Brahman and Banteng cattle. In Proceedings of the Australian Society of Animal Production 11.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Budiarso, I. T., and S. Hardjosworo. 1976. Jembrana disease in Bali cattle. Australian Veterinary Journal 52(2):97.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Copland, R. S. 1974. Observations on banteng cattle in Sabah. Tropical Animal Health and Production 6(2):89-94.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Darmadja, D., and P. Sutedja. 1975. Gestation period and calving interval in Bali cattle. Majalah Ilmiah Universitas Udayana 9:61 -65.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Darmadja, D., and P. Sutedja. 1976. Masa kebuntingan den interval beranak padas sapi Bali. In Proceedings, Seminar Reproduksi den Performance Sapi Bali, April 5-6, 1976. Dinas Peternakan Daerah Ternak Institute, Bali, Indonesia. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Devendra, C., T. Lee Kok Choc, and M. Pathmasingam. 1973. The productivity of Bali cattle in Malaysia. Malaysian Agricultural Journal 49(2):183-197.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Holmes, J. H. C., J. H. Schottler, and T. F. Leche. 1977. Southeast Asian cattle, buffalo, and beef in Papua New Guinea. In Agriculture in the Tropics, B. A. C. Enyi and T. H. Varghese, eds. University of Papua New Guinea, Port Moresby, Papua New Guinea.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hoogerwerf, A. 1970. Udjung Kulan, The Land of the Last Javan Rhinoceros. E. J. Brill, Leiden, The Netherlands.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hooijer, D. A. 1956. The valid name of the banteng Bibos javanicus d'Alton. Zoologische Mededelingenuitgegeven door het Rijksmuseum van Natuurlijke Historie te Leiden 34:223-226.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jellinek, P. J., J. Avenell, A. Thahar, and P. Sitorus. 1980. Infertility associated with crossbreeding of Bali cattle. In Proceedings, 2nd Ruminant Seminar, Ciawi, Indonesia. 79 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jenkinson, D. M., and T. Nay. 1975. The sweat glands and hair follicles of different species of Bovidae. Australian Journal of Biological Science 28:55-68.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kirby, G. W. M. 1979. Bali cattle in Australia. World Animal Review 31 :24-29.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mason, 1. L. In Press. Evolution of Domesticated Animals. Longman, London, England.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Meijer, W. C. P. 1962. Das Balirind (Balinese Cattle). Die Neue Brehm-Bucherei, No. 303, A. Ziemsen Verlag, Wittenberg Lutherstadt, Federal Republic of Germany. (Translated from the Dutch by E. Mohr.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moran, J. B. 1973a. Liveweight changes of Brahman cross, Shorthorn, Banteng and buffalo steers grazing improved pastures at Darwin, Northern Territory. Journal of the Australian Institute of Agricultural Science 39:68-9.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moran, J. B. 1973b. Heat tolerance of Brahman cross, buffalo Banteng and Shorthorn steers during exposure to sun and as a result of exercise. Australian Journal of Agricultural Research 24:775-782.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moran, J. B. 1978. Digestibility and water metabolism in Brahman cross, buffalo, Banteng and Shorthorn steers fed roughage diets. Journal of the Australian Institute of Agricultural Science 44: 57-59.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moran, J. B. 1980. The prediction of chemical content of the whole carcass from the physically-dissected rib in cattle and buffaloes. Proceedings of the Australian Society of Animal Production 13:503.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moran, J. B. 1981. Beef and buffalo production by smallholders in Indonesia. World Review of Animal Production 17:55-64.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moran, J. B. 1982. The performance of Indonesian beef breeds under traditional and improved management systems. Pp. 347-351 in Animal Production and Health in the Tropics, M. R. Jainudeen and A. R. Omar, eds. Universiti Pertanian Malaysia, Serdang, Selangor, Malaysia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moran, J. B., B. W. Norton, and J. V. Nolan. 1979. The intake, digestibility and utilization of a low quality roughage by Brahman cross, buffalo, Banteng and Shorthorn steers. Australian Journal of Agricultural Research 30:333-340.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Namikawa, T., and W. Widodo. 1978. Electrophoretic variations of hemoglobin and serum albumin in the Indonesian cattle including Bali cattle (Bos banteng). Japanese Journal of Zootechnical Science 49(11):817-827.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nitis, 1. M., K. Rika, M. Supardjata, K. D. Nurbudhi, and L. R. Humphreys. 1976. Productivity of improved pastures grazed by Bali cattle under coconuts: a preliminary report. Universitas Udayana, Denpasar, Bali, Indonesia. 18 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nitis, 1. M., and K. Rika. 1978. Bali cattle grazing improved pasture under coconuts. 1. Effects of stocking rate on steer performance and coconut yield. In Seminar on Integration of Animals with Plantation Crops, April 13-15. Preprint No. 10. Penang, Indonesia. 8 pp</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nitis, 1. M. 1979a. Effects of replacing 30 percent of the green roughage with concentrate on the performance of Bali steer. Progress report to the International Development Research Centre, Ottawa, Canada. Centre file:3-P77-0087. 25 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nitis, 1. M. 1979b. Performance of Bali cattle fed grass supplemented with stylosanthes. Progress report to the International Foundation for Science, Sweden. Project No. RR 76. 15 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nitis, 1. M., K. Lana, 1. B. Sudana, N. Sutji, and 1. C. N. Sarka. I980. Persediaan den kebutuhan hijauan ternak di Bali (Roughage supply and requirement of livestock in </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bali). Fakultas Kedokteran Hewan den Peternakan, Universitas Udayana, Denpasar, Bali, Indonesia. 218 pp. (Report series mimeograph.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Norton, B. W., J. B. Moran, and J. V. Nolan. 1979. Nitrogen metabolism in Brahman cross, buffalo, Banteng and Shorthorn steers fed on low quality roughage. Australian Journal of Agricultural Research 30:341.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nursamad, M. 1972. Berat lahir den petumbuhan anak sapi Bali selama 4 bulan di kecamatan Watang Pulu, kabupaten Sidenreng, Sulawesi Selatan. Laporan, Fakultas Peternakan Universitas Hasanuddin yang berafinasi dengan Fakultas Peternakan Institut Pertanian Bogor, Bogor, Indonesia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pastika, M., and D. Darmadja. 1976. Performance reproduksi sapi Bali. In Proceedings, Seminar Reproduksi den Performance Sapi Bali, April 5-6, 1976. Dinas Peternakan Daerah Ternak Institut, Bali, lndonesia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Payne, W. J. A., and D. H. L. Rollinson. 1973. Bali cattle. World Animal Review 7: 13-21.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pulungan, H., and K. Ma'sum. 1977. Performance sapi Bali den hasil persilangannya dengan sapi Hereford den Shorthorn. Laporan Khusus Lembaga Penelitian Peternakan, Cabang Grati 1977 (Abstract).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robinson, D. W. 1977. Livestock in Indonesia. Research Report No. 1. Centre for Animal Research and Development, Bogor, Indonesia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Siebert, B. D., and W. V. MacFarlane. 1969. Body water content and water turnover of tropical Bos taurus, Bos indicus, Bibos banteng, and Bos bubalus bubalis. Australian Journal of Agricultural Research 20:613-622.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Siregar, M. G., and 1. M. Suparjata. 1975. A half century existence of Bali cattle in South Sulawesi. Majalah llmiah Universitas Udayana 9: 13-21.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Subandriyo, P. Sitorus, M. Zulbardi, and A. Roesyat. 1979. Performance of Bali cattle, as work animals and milk and beef producers. Indonesian Agricultural Research and Development Journal 1(1/2):9-10, 24.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sutedja, P., M. Kota, 1. B. Mantra, and D. Darmadja. 1976. Progress report beberapa performance pada sapi Bali. In Proceedings, Seminar Reproduksi den Performance Sapi Bali, April 5-6, 1976. Dinas Peternakan Daerah Ternak Institut, Bali, Indonesia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thahar, A., J. B. Moran, and J. T. Wood. In press. Studies on the haemotology of Indonesian large ruminants. Tropical Animal Health and Production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thahar, A., J. B. Moran, and R. E. Soerifpo. In press. Observations on the hair and skin of Indonesian large ruminants and their relationships to heat tolerance. SABRAO Journal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vercoe, J. E., and J. E. Frisch. 1977. The importance of voluntary feed intake and metabolic rate to production in different genotypes of cattle in different environments. Pp. I(c)-42 in Proceedings of the 3rd International Congress of the Society for the Advancement of Breeding Researchers in Asia and Oceania, Canberra, Australia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yeates, N. T. M., and P. J. Schmidt. 1974. Beef Cattle Production. Butterworths Pty Ltd., Chatswood, Sydney, Australia. 323 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng Cattle Hybrids</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Payne, W. J. A., and D. H. L. Rollinson. 1976. Madura cattle. Zeitschrift fur Tiezuchtung und Zuchtungsbiologie 93:89-100.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mithan</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Simoons, F. J., and E. S. Simoons. 1968. A Ceremonial Ox of India: The Mithan in Nature, Culture, and History. The University of Wisconsin Press, Madison, Wisconsin, USA.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mason, 1. L. In Press. Evolution of Domesticated Animals. Longman, London, England.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Scheurmann, E. 1975. Observations on the behaviour of the mithan (Bibos frontalis Lambert 1837) in captivity. Applied Animal Ethology I :321 -355. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yak and Yakow</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Accolas, J. P., and J. P. Deffontaines. 1970. Quelques donnees sur l'elevage du Yak en Republique Populaire de Mongolie. Pp. 133-141 in The Yak: Its Role in the Economic and Cultural Life of Breeders in Central Asia. Societe d'Ethnozootechnie, 25 Boulevard Arago, 75013 Paris, France.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bonadonna, T. 1970. Nuove possibilita per la Zootechnia dei tropic). Zootecnica e Veterinaria 25:202-221.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bonnemaire, J. 1976. Le Yak domestique et son hybridation. Pp. 46-77 in The Yak: Its Role in the Economic and Cultural Life of Breeders in Central Asia. Societe d'Ethnozootechnie, Paris, France.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dor, R. 1976. Note sur le Yak au Pamir. Pp. 126-131 in The Yak: Its Role in the Economic and Cultural Life of Breeders in Central Asia. Societe d'Ethnozootechnie, Paris, France.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ekvall, R. B. 1968. Fields on the Hoof: Nexus of Tibetan Nomadic Pastoralism. Holt, Rinehart and Winston, New York, USA.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Epstein, H. 1974. Yak and chauri. World Animal Review 9:8-12.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Epstein, H. 1977. Yak and Yak-cattle hybrids. Chapter 3 in Domestic Animals of Nepal. Holmes and Meier Publishers, Inc., New York, USA, and London, England.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ivanova, V. V. 1938. K voprosu izucenija plodovitosti samvoc gibridov jaka s rogatym skotom (On the fertility of male yak x cattle hybrids). Izvestiya Akademii Nauk SSSR, Seriya Biologicheskaya 883-884.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Phillips, R. W., R. G. Johnson, and R. T. Moyer. 1945. The livestock of China. Pp. 67-76 in United States Department of State Publication No. 2249; Far Eastern Series 9.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Phillips, R. W., I. A. Tolstoy, and R. G. Johnson. 1946. Yaks and Yak-cattle hybrids in Asia. The Journal of Heredity 37(6): 162-170; 37(7):206-215.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Schley, P. 1967. Der Yak und seine Kreuzung mit dem Rind in der Sowjetunion. Giessener Abhandlungen zur Agrar- und Wirtschaftsforschung des Europaischen Ostens, Vol. 44. Otto Harassowitz, Weisbaden, Federal Republic of Germany. 131 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Shahrani, M. Nazif Mohib. 1979. The Kirghiz and Wakki of Afghanistan. University of Washington Press, Seattle, Washington, USA. 264 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vlasov, P., S. Gersenzon, and A. Poljakov. 1932. Gibridizacija mezdu jakom i krupnym rogatym skotom (Hybrids between yak and cattle). Problemy Zhivotnovodstva (1):48-57.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">White, W. T., R. W. Phillips, and E. C. Elting. 1946. Yaks and Yak-cattle hybrids in Alaska. Journal of Heredity 37:355-358.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zawadowsky, M. M. 1931. Zebu-Yak hybrids. Journal of Heredity 22:297.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zuitin, A. I. 1938. New data on the chromosome number in yak (Poephagus grunniens L.). Doklady Akademii Nauk Uzbekskoi SSR 19:201-202.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild Banteng</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A unique, interesting film showing wild banteng, gaur and kouprey in Cambodia in 1951</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">is available for hire from The Coolidge Foundation, 38 Standley Street, Beverly, Massachusetts 01915, USA.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Boonsong Lekagul and J. A. McNeely. 1977. Mammals of Thailand. Association for the Conservation of Wildlife, Bangkok, Thailand. 758 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fischer, H., and E. Scheurmann. 1977. Cytogenetic investigations on domestic and wild animal populations in South and Southeast Asia. Animal Research and Development 6:63-71.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Halder, U. 1975. Okologie und Verhalten des banteng (Bos javanicus) in Java. Eine Feldstudie. Verlag Paul Parey, Hamburg and Berlin, Federal Republic of Germany. 124 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hoogerwerf, A. 1974. Report on a Visit to Wildlife Reserves in East Java. Mededelingen No. 21. Nederlandsche Commissie voor Internationale Natuurbescherming.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">McNeely, J. A. 1975. Wildlife and national parks in the Lower Mekong Basin. Unpub</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">lished report to the Committee for the Coordination of Investigations of the Lower  Mekong Basin, Economic Commission for Asia and the Far East, Bangkok, Thailand.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sumardja, E. A. 1976. The relationships between banteng Bos javanicus (d'Alton) and  vegetation at the Pananjung-Pangandaran Nature Reserve. Research Grant No. 1237/  TF/VI/74. Preliminary Study Internal Report Biotrop. Bogor, Indonesia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wind, J., and H. Amir. 1977. Distribution of banteng (Bos javanicus) in Java and Bali,  Indonesia. Unpublished ms.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wind, J., and H. Amir. 1977. Management Plan Baluran Reserve FAO INS/73/013.  Nature Conservation and Wildlife Management Project.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gaur</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Boonsong Lekagul. 1965. The gaur. (Bos gaurus). Conservation News of South East  Asia 5:7-10.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Boonsong Lekagul and J. A. McNeely. 1977. Mammals of Thailand. Association for the  Conservation of Wildlife, Bangkok, Thailand. 758 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Conry, P. J. 1980. The impact of development and the behavioural response of the  Malaysian seladang. Pp. 279-286 in Tropical Ecology and Development, Proceedings  Fifth International Symposium of Tropical Ecology. International Society of Tropical  Ecology, Kuala Lumpur, Malaysia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Conry, P. J. 1981. Habitat selection and use, movements, and home range of Malayan  gaur (Bos gaurus hubbacki) in Central Pahang, Malaysia. M.S. thesis. University of  Montana, Missoula, Montana, USA. 120 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Conry, P. J. (In press) Immobilizing Malayan gaur with etorphine. Journal of Wildlife  Management.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fischer, H. 1975. The water buffalo and related species as important genetic resources:  their conservation, evaluation and utilization. In The Asiatic Water Buffalo.  Proceedings of an International Symposium, Khon Kaen, Thailand. Food and Fertilizer  Technology Center, Taipei, Taiwan.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fischer, H. 1980. Hybrids between Gaur and Gayal and between Gayal and Banteng as  zoological rarities in Thailand. Animal Research and Development 12:116-119.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fradrich, H., and H. G. Klos. 1976. Zur Haltung und Zucht des Gaurs, Bos gaurus.  Zoologische Garten 46(6):417-425.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hussain, M. Khader. 1969. The southern Asiatic gaur or Indian bison (Bos gaurus  gaurus H. Smith). Cheetal 12(1):29-47.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Krishnan, M. 1972. An ecological survey of the larger mammals of peninsular India.  Journal of the Bombay Natural History Society 69:322-349.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Medway, Lord. 1978. The Wild Mammals of Malaya and Singapore. 2nd Edition. Oxford  University Press, Kuala Lumpur, Malaysia. 128 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Momin Khan, M. K. bin 1973. Studies on the seladang (Bos gaurus) in the State of  Perak. Malaysian Nature Journal 26:163-169.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sahai, R. C. 1972. Distribution, composition and herd size of Gaur (Bos gaurus) in  Palamau, Bihar. Cheetal 15:60-66.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Schaller, G. B. 1967. The Deer and the Tiger. Chicago University Press, Chicago, USA.  370 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Weigun, L. E. 1971. The last refuge. Malaysian Nature Journal 24:132-137.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Weigun, L. E. 1972. The problems in the preservation of the seladang in the Malaysian  National Park. M.S. thesis. Michigan State University, East Lansing, Michigan, USA.  55 pp</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kouprey</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Boonsong Lekagul and J. A. McNeely. 1977. Mammals of Thailand. Association for the  Conservation of Wildlife, Bangkok, Thailand. 758 pp.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coolidge, H. J. 1940. The Indo-Chinese Forest Ox or Kouprey. Memoirs, Museum of Comparative Zoology at Harvard College 54(6):421-431.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coolidge, H. J. 1955. The Forest Ox or Kouprey of South East Asia. P. 109 in Breeding Beef Cattle for Unfavorable Environments, A. O. Rhoad, ed. University of Texas Press, Austin, Texas, USA.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Neese, H.C. 1976. Kouprey along the Laos/Cambodia border area. Unpublished report to the New York Zoological Society, 185 and Southern Blvd., New York, New York 10460, USA.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pfeffer, P., and O. Kim-San. 1967. Le kouprey, Bos(Bibos) sauvelli, Urbain, 1937: discussion systematique et status actuel. Hypothese sur l'origine du zebu (Bos indicus). Mammalia 31(4):521-536.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pfeffer, P. 1969. Considerations sur l'ecologie des forets claires du Cambodge oriental. Terre et Vie 23(1):3-24.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wharton, C. H. 1957. An Ecological Study of the Kouprey. Novibos sauveli (Urbain). Monograph No. 5. Institute of Science and Technology, Manila, Philippines. 111 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anoas</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dolan, J. M. 1965. Breeding of the lowland anoa in the San Diego Zoological Garden. Zeitschrift Saugetierekunde 30(4):241-248.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Duplaix-Hall, N., ed. 1975. International Zoo Yearbook 15. Zoological Society of London</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fradrich, H. 1973. Einige Bemerkungen uber den Anoa. Zeitschrift des Kolner Zoo 16(3):101-105.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fischer, H., and H. Hohn. 1976. Der Karyotyp eines weiblichen Tamarau (Anea mindorensis) [The Karyotype of a Female Tamaraw (Anoa mindorensis)]. Giessener Beitrage zur Erbpathologie und Zuchthygiene 6:173.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Groves, C. P. 1969. Systematics of the anoa (Mammalia, Bovidae) Beaufortia 17(223): 1-12.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Koulischer, L., J. Tyskens, and J. Mortelsmanns. 1972. The chromosomes of a male specimen of Anoa depressicornis quarlesi. Acta Pathologica, Antwerp 56:21.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Scheurmann, E., H. Hohn, and H. Fischer. 1977. The karyotype of a male Bubalus (Anoa) depressicornis quarlesi Ouwens 1911. In Symposium, Domesticated Animal Cytogenetics, Jouy en Josas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tamaraw</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Alvarez, J. B., Jr. 1970. Philippines tamaraw, here to stay. IUCN Publication, New Series 18:46-51.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Grimwood, l. R. 1975. National Parks and Wildlife Conservation in the Philippines. FAO: PHI/72/006. UNDP/FAO, Rome, Italy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Harrisson, T. 1969. The tamaraw and its survival. Conservation News of South East Asia 8:60-61, 70.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kuchn, D. 1975. Tamaraw at Mt. Iglit Came Refuge, Philippines. Tigerpaper 2(3):26.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sitwell, N. 1975. On the track of the tamaraw. Wildlife 17:428-430.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Talbot, L. M., and M. H. Talbot. 1966. The tamaraw, Bubalus mindorensis (Heude). Observations and recommendations. Mammalia 30(1): 1 - 12.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bearded </P>
+<P ALIGN="JUSTIFY">Pig</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Allen, E. F. 1948. The bearded pig. Malaysian Nature Journal 3(2):98-99.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cranbrook, Earl of. 1979. A review of domestic pig remains from archaeological sites in </P>
+<P ALIGN="JUSTIFY">Diong, C. H. 1973. Studies of the Malayan wild pig in Perak and Johore. Malaysian Nature Journal26(2):120-151.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Croves, C. P. 1981. Ancestors for the Pigs, Taxonomy and Phylogeny of the Cenus Sus. Department of Prehistory Technical Bulletin No. 3. Australian National University Press, Canberra, Australia. 96 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hertwig, P. 1936. Artbastarde bei Tieren. Handbuch Vererb Wissenschaften 2B:21.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hislop, J. A. 1949. Field notes on the bearded pig. Malaysian Nature Journal 4(2):62-64.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hislop, J. A. 1952. More about the bearded pig. Malaysian Nature Journal 7:22-23.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">International Union for the Conservation of Nature. 1972. Red Data Book 1: Mammalia. IUCN, Cland, Switzerland. (This is a loose-leaf binder that is updated from time to time.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kempe, J. E. 1948. The riddle of the bearded pig. Malaysian Nature Journal 3(1):36-42.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lotsy, J. P. 1922. Die Aufarbeitung des kuhn'schen kreuzungsmaterials im Institut fur Tierzucht der Universitat Halle. Cenetica 4:32-61.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MacKinnon, J. 1981. The distribution and status of wild pigs in Indonesia. IUCN/SSC Pigs and Peccaries Specialist Group. Unpublished report. 9 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Medway, Lord. 1978. The Wild Mammals of Malaya and Singapore, 2nd Edition. Oxford University Press, Kuala Lumpur, Malaysia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mohr, E. 1960. Wilde Schweine. Die Neue Brehm-Biicherei, A. Ziemsen Verlag, Wittenberg Lutherstadt, Federal Republic of Cermany.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Oliver, W. L. R. 1981. First written report. IUCN/SSC Pigs and Peccaries Specialist group. Unpublished report. 14 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pfeffer, P. 1959. Bologie et migrations du sanglier de Borneo (Sus barbatus Muller 1869). Mammalia 23:277-303.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sulawesi Warty Pig</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appelman, F. J. 1955. Uber Sus celebensis Muller und Schlegel. Der Zoologische Garten 21:152-156.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Catibog-Sinha, C. S. 1981. The quantity and quality of wild food plants and the depredation of wild pigs in the Philippines. Ph.D. thesis. Oklahoma State University, Stillwater Oklahoma, USA.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Croves, C. P. 1981. Ancestors for the Pigs, Taxonomy and Phylogeny of the Cenus Sus. Department of Prehistory Technical Bulletin No. 3. Australian National University Press, Canberra, Australia. 96 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hooijer, D. A. 1968. Pleistocene Vertebrates from Celebes. 8. Sus celebensis Muller and Schlegel, 1845. Beaufortia 16:215-218.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MacKinnon, J. 1981. The distribution and status of wild pigs in Indonesia. IUCN/SSC Pigs and Peccaries Specialist Croup. Unpublished report. 9 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mohr, E. 1960. Wilde Schweine. Die Neue Brehm-Bucherei, A. Ziemsen Verlag, Wittenberg Lutherstadt, Federal Republic of Germany.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Oliver, W. L. R. 1981. Interim report. IUCN/SSC Pigs and Peccaries Specialist Group. Unpublished report. 14, pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Javan Warty Pig</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Blouch, R. A. 1979. Proposed Bawean Island Wildlife Reserve Management Plan. World Wildlife Fund, Report to Directorate of Nature Conservation, Indonesia. Unpublished report. 63 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Blouch, R. A. 1981. Results of a preliminary search for Sus verrucosus in the Mt. Arjuna area. World Wildlife Fund, Meru Betiri Project 1024. Unpublished report. 4 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Groves, C. P. 1981. Ancestors for the Pigs, Taxonomy and Phylogeny of the Genus Sus. Department of Prehistory Technical Bulletin No. 3. Australian National University Press, Canberra, Australia. 96 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hoogerwerf, A. 1970. Udjung Kulonthe Land of the Last Javan Rhinoceros. E. J. Brill, I.eiden. The Netherlands. Pp. 330-349. </P>
+<P ALIGN="JUSTIFY">MacKinnon, J. 1981. The distribution and status of wild pigs in Indonesia. IUCN/SSC Pigs and Peccaries Specialist Group. Unpublished report. 9 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Oliver, W. L. R. 1981. First written report. IUCN/SSC Pigs and Peccaries Specialist Group. Unpublished report. 14 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigmy Hog</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bosma, A. A., W. L. R. Oliver, and A. A. MacDonald. In press. The karyotype, including g- and c- banding patterns, of the pigmy hog Sus (Porcula) salvanius (Suidae, Mammalia).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Groves, C. T. 1981. Ancestors for the Pigs, Taxonomy and Phylogeny of the Genus Sus. Department of Prehistory Technical Bulletin No. 3. Australian National University Press, Canberra, Australia. 96 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Oliver, W. L. R. 1980. The Pigmy Hog: The Biology and Conservation of the Pigmy Hog Sus (Porcula) salvanius, and the Hispid Hare, Caprolagus hispidus. Special Scientific Report No. I. Jersey Wildlife Preservation Trust. 93 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Oliver, W. L. R. 1981. Pigmy hog and hispid hare: further observations of the continuing decline (or, a lament for Barnadi and a good cause for skepticism). The Dodo, Journal of the Jersey Wildlife Preservation Trust 18:10-20.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Babirus a</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bosma, A. A., 1980. The karyotype of the babirusa (Babyrousa babyrussa); karyotype evolution in the Suidae. Fourth European Colloquium Cytogenetics Domestic Animals 1980:238-241.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bosma, A. A., and De Haan, N. A. 1981. The karyotype of Babrousa babyrussa (Suidae, Mammalia) Acta Zoologica et Pathologica Antverpiensia 76: 17-27.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Davis, D. D. 1940. Notes on the anatomy of the babirusa. Field Museum of Natural History-Zoology 22(5):363-411.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fradich, H. 1974. A comparison of behaviour in the suidae. Pp. 133-144 in The Behaviour of Ungulates and Its Relation to Management. V. Ceist and F. Walther, eds. IUCN Publication No. 24.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Groves, C. P. 1981. Ancestors for the Pigs, Taxonomy and Phylogeny of the Genus Sus. Department of Prehistory Technical Bulletin, No. 3. Australian National University Press, Canberra, Australia. 96 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Croves, C. P. 1980. Notes on the systematics of Babyrousa (Artiodactyla, Suidae). Zoologische Mededelingen, Deel 55(3):29-46.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MacKinnon, J. 1981. The structure and function of the tusks of babirusa. Mammal Review 1 1(1):37-40.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MacKinnon, J. 1981. The distribution and status of wild pigs in Indonesia. IUCN/SSC Pigs and Peccaries Specialist Group. Unpublished report. 9 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Oliver, W. L. R. 1981. First written report. IUCN/SSC Pigs and Peccaries Specialist Group. Unpublished report. 14 pp.</P>
+<P ALIGN="JUSTIFY">1</P>
+<P ALIGN="JUSTIFY">Selmier, V. J. 1978. Only in Indonesia: the babirusa. Unpublished report to Directorate of Nature Conservation (P.P.A.), Bogor, Indonesia. 40 pp. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Research Contacts</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because Asia contains many livestock breeds about which little is known, an expert committee on Animal Genetic Resources has been recently formed by the Society for the Advancement of Breeding Researchers in Asia and Oceania (SABRAO). Its chairman is Professor J. S. F. Barker of the University of New England, Armidale, New South Wales 2351, Australia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Species Survival Commission of the International Union for the Conservation of Nature has a Wild Cattle Specialist Group that concerns itself with wild banteng, gaur, and kouprey. Its chairman is Mr. Mohd. Khan bin Momin Khan, Director-General, Wildlife and National Parks, West Malaysia, Kompleks Pejabat-Pejabat Kerajaan, Block K-20, Jalan Duta, Kuala Lumpur, Malaysia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The following have particular knowledge of the animals described in this book, have contributed to the various chapters, and (in most cases) have agreed to provide advice to bona fide researchers wishing to study further the animals in this report.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Domesticated Banteng</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ida Bagus Arka, Faculty for Veterinary Science and Animal Husbandry, Udayana University, Jalan Sudirman Sanglah, Denpasar, Bali, Indonesia J. S. F. Barker, Department of Animal Science, University of New</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">England, Armidale, New South Wales 2351, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. Bongers, Department of Nature Conservation, Wageningen Agricultural University, Ritzema Bosweg 32a, 6703AZ Wageningen, The Netherlands David Butcher, Western Plains Zoo, Box 813, Dubbo, New South Wales</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">2830, Australia (Banteng are available for research projects and zoos.</P>
+<P ALIGN="JUSTIFY">Quarantine for shipments between Australia and most countries are</P>
+<P ALIGN="JUSTIFY">straightforward)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. K. Camoens, Livestock Specialist, Asian Development Bank, P.O. Box 789, Manila, Philippines 2800</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">David Deppner, 1603 Dayton Road, Hyattsville, Maryland 20783, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. Devendra, Malaysian Agricultural Research and Development Institute (MARDI), Serdang, Selangor, Malaysia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J.-M. Duplan, Institut Technique de l'Elevage Bovin, Section Amelioration Genetique, Maison Nationale des Eleveurs, 149, rue de Bercy F, 75595 Paris Cedex 12, France</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. Fischer, Institute of Tropical Veterinary Medicine, 63 Giessen, Wilhelmstrasse 15, Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">S. I. Furtado, Universiti Malaya, Lembah Pantai, Kuala Lumpur 22-11, Malaysia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John Hodges, FAO, Via delle Terme di Caracalla, 00100 Rome, Italy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. Huitema, Overzicht 60, 6862 CT, Oosterbeek, The Netherlands</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Graham W. M. Kirby, Principal Animal Production Officer, Department of Primary Production, P.O. Box 4160, Darwin, Northern Territory 5790, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moh. Zain Katoe, P.T. United Livestock, Jalan Bau Massepe 472, ParePare, South Sulawesi, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. -G. Klos, Director, Zoologischer Garten Berlin, Hardenbergplatz 8 , 1000 Berlin 30, Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Prof. Kusmat, Dean, Faculty of Veterinary Medicine, Institut Pertanian Bogor, Jalan Oto Iskandardinata, Bogor, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ian L. Mason, 8 Ramsay Garden, Edinburgh, EH1 1NA, Scotland</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robert E. McDowell, Department of Animal Science, Frank B. Morrison Hall, Cornell University, Ithaca, New York 14853, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">G. Montsma, Department of Animal Production, Wageningen Agricultural University, Ritzema Bosweg 32a, 6703 AZ Wageningen, The Netherlands</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. B. Moran, Senior Research Officer, Animal and Irrigated Pastures Research Institute, Kyabram, Victoria 3620, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jan Nari, Director of Central Research Institute for Animal Science, Jalan Raya Pajajaran, Bogor, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I. M. Nitis, Department of Animal Nutrition and Tropical Pasture Production, Udayana University, Jalan Sudirman Sanglah, Denpasar, Bali, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. J. A. Payne, 91 Bedwardine Road, London SE19 3AY, England</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Donald L. Plucknett, Consultative Group on International Agricultural Research, 1818 H Street, Washington, D.C. 20433, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research Institute for Animal Production, P.O. Box 123, Bogor, Indonesia (Amber Roesyat, Ian Fletcher, Dennis Hoffmann, P. Sitorus, Subandriyo, M. Zulbardi)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">David W. Robinson, International Programs, University of California, Davis, California 95616, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D. H. L. Rollinson, Animal Production and Health Division, FAO, Via delle Terme di Caracalla, 00100 Rome, Italy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">G. Seifert, CSIRO, Tropical Cattle Research Centre, P.O. Box 5545, Rockhampton Mail Centre, N. Rockhampton, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. David Simpson, Senior Extension Specialist, Veld, Pastures and Wildlife, Agritex Box 363, Bulawayo, Zimbabwe</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. J. Smith, Tropical Animal Health, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Summerhall, Edinburgh, EH9 1QH Scotland</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dukut Sularsasa, Department of Tropical Veterinary Science, James Cook University, Townsville, Queensland 4811, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M. Syamsul Arifin, Jalan Amin Jakfar 41, Pamekasan Madura, Jatim, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Taronga Zoo, P.O. Box 20, Mosman, New South Wales 2088, Australia (T. Finnie and J. L. Throp)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Frank M. Thompson, Wild Animal Brokers, 15605 S. R. #64, Bradenton, Florida 33508, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Allen D. Tillman, 523 West Harned Place, Stillwater, Oklahoma 74074, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Don Tulloch, P.O. Box 38841, Winnellie, Northern Territory 5789, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Helen Newton Turner, P.O. Box 184, North Ryde, New South Wales 2113, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antoon de Vos, P.O. Box 34, Whitford, Auckland, New Zealand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robert Warren, Department or Range and Wildlife Management, Texas Tech University, Lubbock, Texas 79409, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Everett J. Warwick, The Rockefeller Foundation, P.O. Box 63, Yogyakarta, D.I.Y., Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John Woodward, 35AI, Sultan Hasanudin, Ujung Pandang, South Sulawesi, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zoos with Domesticated Banteng</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antwerp, Belgium (Royal Zoological Society of Antwerp)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Askaniya-Nova, USSR (Zoologicheskii Park Askaniya-Nova)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bangkok, Thailand (Dusit Zoological Park; banteng-mithan hybrid)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Berlin, Federal Republic of Germany (Zoologischer Garten)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Berlin, German Democratic Republic (Tierpark Berlin)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Copenhagen, Denmark (Zoologisk Have)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dubbo, New South Wales, Australia (Western Plains Zoo)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jakarta, Indonesia (Kebun Binatang Ragunan)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kiev, USSR (Kievskii Zoologicheskii Park)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Madrid, Spain (Zoo de la Casa de Campo; mithan-banteng hybrid)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pretoria, South Africa (National Zoological Gardens of South Africa) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rome, Italy (Giardino Zoologico e Museo de Zoologia del Comune de Rome and Zoorama)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rotterdam, The Netherlands (Stichting Koninklijke Rotterdamse Diergaarde; 2 male, 2 female, may be wild form)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Surabaya, Indonesia (Kebun Binatang Surabaya)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yogyakarta, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Banteng-Cattle Hybrids</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Abubakar Aldjufri, Secretary, Asian Livestock Business Club, Kebun Pala I/79B Tanah Abang, Jakarta, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Saleh Aldjufri, Jalan Jakarta 42, Surabaya, Jawa Timur, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">David Deppner, 1603 Dayton Rd., Hyattsville, Maryland 20783, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. Huitema, Overzicht 60, 6862 CT, Oosterbeek, The Netherlands</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Graham W. M. Kirby, Principal Animal Production Officer, Department of Primary Production, P.O. Box 4160, Darwin, Northern Territory 5790, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. B. Moran, Senior Research Officer, Animal and Irrigated Pastures Research Institute, Kyabram, Victoria 3620, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. J. A. Payne, 91 Bedwardine Road, London SE19 3AY, England</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">David W. Robinson, International Programs, University of California, Davis, California 95616, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D. H. L. Rollinson, Animal Production and Health Division, FAO, Via delle Terme di Caracalla, 00100 Rome, Italy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">B. Wheeler, 1000 Shady Lane, College Station, Texas 77840, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mithan</P>
+<P ALIGN="JUSTIFY">Chaichana Satrulee, Dusit Zoological Park, Bangkok, Thailand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">H. Fischer, Institute of Tropical Veterinary Medicine, 63 Giessen, Wilhelmstrasse 15, Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. von Furer Haimendorf, School of Oriental and African Studies, University of London, London WC1, England</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Charles G. Hickman, Livestock Consultant, A. Mithat Efendi Sokak No. 36/11, Cankaya, Ankara, Turkey</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Frederick J. Simoons, 140 Bartlett Ave., Woodland, California 95695, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zoos with Mithan (Gayal)</P>
+<P ALIGN="JUSTIFY">Aalborg, Denmark (Aalborg Zoologiske Have)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Amsterdam, The Netherlands (Stichting Koninklijk Zoologisch) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Arnhem, The Netherlands (Burgers' Zoo and Safari)</P>
+<P ALIGN="JUSTIFY">Bangkok, Thailand (Dusit Zoological Park)</P>
+<P ALIGN="JUSTIFY">Berlin, German Democratic Republic (Tierpark Berlin)</P>
+<P ALIGN="JUSTIFY">Calcutta, India</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cologne, Federal Republic of Germany (Aktiengesellschaft Zoologischer Garten)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Heidelberg, Federal Republic of Germany (Tiergarten Heidelberg)</P>
+<P ALIGN="JUSTIFY">Kolmarden, Sweden (Koemardens Djurpark)</P>
+<P ALIGN="JUSTIFY">Madrid, Spain (Zoo de la Casa de Campo; mithan-banteng hybrid)</P>
+<P ALIGN="JUSTIFY">Rabat, Morocco (Pare Zoologique National)</P>
+<P ALIGN="JUSTIFY">Vienna, Austria (Schonbrunn Zoo)</P>
+<P ALIGN="JUSTIFY">Tallin, USSR (Tallinna Loomaaed)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yak</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Joseph Bonnemaire, Ecole Nationale Superieure des Sciences Agronomiques Appliquees, 26, Bd. Docteur Petitjean, 21100 Dijon, France</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Corneille Jest, Centre National de la Recherche Scientifique, 1, Place Artistide-Briand, 92190 Meudon, France</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">R. A. Kazarova, Director, Riga Zoological Garden, Meza prospekt 1, Riga 14 226014, Latvian SSR, USSR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">K. K. Panday, Swiss Association for Technical Assistance (SATA), Box 113, Kathmandu, Nepal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ralph W. Phillips, The Representative, Apartment 810, 1101 South Arlington Ridge Road, Arlington, Virginia 22202, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Patrick J. Robinson, Department of Agricultural and Forest Sciences, University of Oxford, Commonwealth Forestry Institute, South Parks Road, Oxford OX1 3RB, England</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">George B. Schaller, New York Zoological Society, 185 and Southern Blvd., New York, New York 10460, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">T. B. Singh, Director General, Department of Livestock, HMG, Harihar Bhawan, Pulchowk, Laitpur, Nepal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Societe d'Ethnozootechnie, 25, Boulevard Arago, 75013 Paris, France (R. Laurans)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zoos with Yak</P>
+<P ALIGN="JUSTIFY">Antwerp, Belgium (Royal Zoological Society of Antwerp)</P>
+<P ALIGN="JUSTIFY">Arnhem, The Netherlands (Burgers' Zoo and Safari)</P>
+<P ALIGN="JUSTIFY">Baltimore, Maryland, USA</P>
+<P ALIGN="JUSTIFY">Bronx, New York, USA (New York Zoological Park)</P>
+<P ALIGN="JUSTIFY">Chicago, Illinois, USA (Brookfield Zoo)</P>
+<P ALIGN="JUSTIFY">Denver, Colorado, USA (Denver Zoological Gardens)</P>
+<P ALIGN="JUSTIFY">Detroit, Michigan, USA (Detroit Zoological Park)</P>
+<P ALIGN="JUSTIFY">Evansville, Indiana, USA (Meeker Park Zoo)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Granby, Quebec, Canada (Societe Zoologique de Granby, Inc.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Grand Rapids, Michigan, USA (John Ball Zoological Gardens)</P>
+<P ALIGN="JUSTIFY">Kansas City, Missouri, USA (Kansas City Zoological Gardens)</P>
+<P ALIGN="JUSTIFY">Knoxville, Tennessee, USA (Knoxville Municipal Zoo)</P>
+<P ALIGN="JUSTIFY">London, England</P>
+<P ALIGN="JUSTIFY">Rochester, New York, USA (Seneca Park Zoo)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rotterdam, The Netherlands (Stichting Koninklijke Rotterdamse Diergaarde)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">San Diego, California, USA (San Diego Wild Animal Park)</P>
+<P ALIGN="JUSTIFY">Sioux Falls, South Dakota, USA (Great Plains Zoo)</P>
+<P ALIGN="JUSTIFY">South Bend, Indiana, USA (Potawatomi Park Zoo)</P>
+<P ALIGN="JUSTIFY">Syracuse, New York, USA (Burnet Zoo)</P>
+<P ALIGN="JUSTIFY">Toronto, Ontario, Canada (Metro Toronto Zoo)</P>
+<P ALIGN="JUSTIFY">Utica, New York, USA (Utica Zoo)</P>
+<P ALIGN="JUSTIFY">Wichita, Kansas, USA (Sedgwick County Zoo)</P>
+<P ALIGN="JUSTIFY">West Orange, New Jersey, USA (Turtleback Zoo)</P>
+<P ALIGN="JUSTIFY">Winnipeg, Manitoba, Canada (Assiniboine Park Zoo)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yakows</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Joseph Bonnemaire, Ecole Nationale Superieure des Sciences Agronomiques Appliquees, 26, Bd. Docteur Petitjean, 21100 Dijon, France</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Department of Agriculture, Hari Har Bhawan, Pulchok, Lalitpur, Kathmandu, Nepal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Department of Animal Husbandry and Veterinary Science, Kathmandu, Nepal (Tewari and Burathoky)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Director of Livestock Development, Peking, China</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Professor Karl Fredge, Department of Genetics, University of Uppsala, Uppsala, Sweden</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Indian Veterinary Research Institute, P.O. Izatnagar 243 122, Uttar Pradesh, India</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Livestock Division, National Agricultural Research Center, Islamabad, Pakistan</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">National Sheep and Yak Development Project, Dechhen Pelrithang, P.O. Bumthang, Bhutan</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ralph W. Phillips, The Representative, Apartment 810, 1101 South Arlington Ridge Road, Arlington, Virginia 22202, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Patrick J. Robinson, Department of Agricultural and Forest Sciences, University of Oxford, Commonwealth Forestry Institute, South Parks Road, Oxford OX1 3RB, England</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Whipsnade Zoo, Whipsnade, England</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bruce A. Young, Department of Animal Science, University of Alberta, Edmonton, Alberta TOG 2P5, Canada </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wild Banteng</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. Amir, c/o Ministry of Development Supervision and the Environment, JalanMirdekaBarat 15, Jakarta, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. H. Blower, National Parks Project, c/o UNDP, Box 650, Rangoon, Burma</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bonsong Lekagul, Association for the Conservation of Wildlife, No. 4 Customhouse Road, Bangkok, Thailand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chaichana Satrulee, Dusit Zoological Park, Bangkok, Thailand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Z. Coto, Tropical Forest Biology, SEAMEO-BIOTROP, P.O. Box 17, Bogor, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Forest Department, P.O. Box 311, Sandakan, Sabah, Malaysia (Patrick Andau, Assistant Chief Game Warden)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I. R. Grimwood, P.O. Box 45079, Nairobi, Kenya</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. P. Groves, Department of Prehistory and Anthropology, The Australian National University, P.O. Box 4, Canberra, ACT 2600, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">U. Halder, Swiss League for Nature Conservation, P.O. Box 73, CH4020 Basel, Switzerland</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. Huitema, Overzicht 60, 6862 CT, Oosterbeek, The Netherlands</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">F. Wayne King, Director and Professor, Florida State Museum, University of Florida, Gainesville, Florida 32601, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lembaga Biologi Nasional (LBN-LIPI), Bogor, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John A. Lukas, White Oak Plantation, Rt. 3 Box 224, Yulee, Florida 32097, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jeffrey A. McNeely, Executive Officer, Commission on National Parks and Protected Areas, International Union for Conservation of Nature and Natural Resources, Avenue du Mont-Blanc, 1196 Gland, Switzerland</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John Payne, Wildlife Section, Forest Department, P.O. Box 311, Sandakan, Sabah, Malaysia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Somtob Norapuckprutikorn, Captive Propagation Section, Wildlife Conservation Division, Royal Forest Department, Bangkhen, Bangkok 9, Thailand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">B. Wheeler, 1000 Shady Lane, College Station, Texas 77840, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M. H. Woodford, c/o FORW, FAO, Via delle Terme di Caracalla, 00100 Rome, Italy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zoos with Wild Banteng</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Albuquerque, USA (Rio Grande Zoological Park)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Amsterdam, The Netherlands (Stichting Koninklijk Zoologisch)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bangkok, Thailand (Dusit Zoological Park)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Berlin, Federal Republic of Germany (Zoologischer Garten)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chicago, Illinois, USA (Brookfield Zoo)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cologne, Federal Republic of Germany (Aktiengesellschaft Zoologischer Garten)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Copenhagen, Denmark (Zoologisk Have)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Darmstadt, Federal Republic of Germany (Vivarium Darmstadt)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dortmund, Federal Republic of Germany (Tierpark Dortmund)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dresden, German Democratic Republic (Zoologischer Garten Dresden)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Frankfurt, Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jakarta, Indonesia (Kebun Binatang Ragunan)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">San Diego, California, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">St. Louis, Missouri, USA (St. Louis Zoological Park)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Surabaya, Indonesia (Kebun Binatang Surabaya)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yogyakarta, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yulee, Florida, USA (White Oak Plantation)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gaur</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John Aspinal, Howlett's Wildlife Park, near Canterbury, Kent, England</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Boonsong Lekagul, Association for the Conservation of Wildlife, No. 4 Customhouse Road, Bangkok, Thailand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Paul Conry, Division of Aquatic and Wildlife Resources, Department of Agriculture, P.O. Box 23367, GMF Guam 96921, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. Fischer, Institute of Tropical Veterinary Medicine, 63 Giessen, Wilhelmstrasse 15, Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I. R. Grimwood, P.O. Box45079, Nairobi, Kenya</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mohd Khan bin Momin Khan, Director-General, Department of Wildlife and National Parks, P.O. Box 611, Kuala Lumpur, Malaysia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">R. A. Kazarova, Director, Riga Zoological Garden, Meza prospekt 1, Riga 14 226014, Latvian SSR, USSR</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H.-G. Klos, Director, Zoologischer Garten Berlin, Hardenbergplatz 8, 1000 Berlin 30, Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Adrian G. Marshall, Department of Zoology, University of Aberdeen, Aberdeen, Scotland</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">George B. Schaller, New York Zoological Society, 185 and Southern Blvd., New York, New York 10460, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lee Simmons, Omaha Zoo, Omaha, Nebraska 68108, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Janet Stover, Bronx Zoo, 185 and Southern Blvd., New York, New York 10460, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Frank M. Thompson, Wild Animal Brokers, 15605 S. R. #64, Bradenton, Florida 33508, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M. H. Woodford, c/o FORW, FAO, Via delle Terme di Caracalla, 00100 Rome, Italy </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zoos with Guar </P>
+<P ALIGN="JUSTIFY">The Berlin Zoo was assigned by the IUCN in cooperation with the</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">lUDZG to keep the guar studbook records. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bangkok, Thailand (Dusit Zoological Park)</P>
+<P ALIGN="JUSTIFY">Berlin, Federal Republic of Germany (Zoologischer Garten)</P>
+<P ALIGN="JUSTIFY">Bronx, New York, USA (New York Zoological Park; 7 male, 3 female)</P>
+<P ALIGN="JUSTIFY">Brownsville, Texas, USA (Gladys Porter Zoo; 5 male, 10 female)</P>
+<P ALIGN="JUSTIFY">Copenhagen, Denmark (Zoologisk Have; 1 male, 2 female)</P>
+<P ALIGN="JUSTIFY">Holiday Island, Eureka Springs, Arkansas, USA</P>
+<P ALIGN="JUSTIFY">Hyderabad, Andhra Pradesh, India (Nehru Zoological Park)</P>
+<P ALIGN="JUSTIFY">Ivey, Wilburton, Oklahoma, USA</P>
+<P ALIGN="JUSTIFY">Kansas City, Missouri, USA (Kansas City Zoological Gardens; I male)</P>
+<P ALIGN="JUSTIFY">Kings Mill, Ohio, USA (Wild Animal Safari,; 1 male)</P>
+<P ALIGN="JUSTIFY">Kuala Lumpur, Malaysia</P>
+<P ALIGN="JUSTIFY">London, England</P>
+<P ALIGN="JUSTIFY">Los Angeles, California, USA (The Los Angeles Zoo; I male, 3 female)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Memphis, Tennessee, USA (Memphis Zoo and Aquarium; I male, 2 female)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Munich, Federal Republic of Germany (Munchener Tierpark Hellabrunn Ag)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mysore, Karnataka, India</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Oklahoma City, Oklahoma, USA (Oklahoma City Zoo; 7 male, 7 female)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Omaha, Nebraska, USA (Henry Doorly Zoological Gardens; 7 male, 15 female)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Riga, Latvian SSR, USSR (Riga Zoological Garden)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">San Diego, California, USA (San Diego Wild Animal Park; 6 male, 6 female)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">South Bend, Indiana, USA (Potawatomi Park Zoo; 1 male)</P>
+<P ALIGN="JUSTIFY">St. Louis, Missouri, USA (St. Louis Zoological Park; 1 male, 2 female)</P>
+<P ALIGN="JUSTIFY">Toronto, Ontario, Canada (Metro Toronto Zoo; 3 male, 1 female)</P>
+<P ALIGN="JUSTIFY">Vienna, Austria (Schonbrunn Zoo)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kouprey</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Boonsong Lekagul, Association for the Conservation of Wildlife, No. 4 Customhouse Road, Bangkok, Thailand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Harold Coolidge, 38 Standley Street, Beverly, Massachusetts 01915, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jeffrey A. McNeely, Executive Officer, Commission on National Parks and Protected Areas, International Union for Conservation of Nature and Natural Resources, Avenue du Mont-Blanc, 1196 Gland, Switzerland</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Harvey C. Neese, P.O. Box 332, Troy, Idaho 83871, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">David Anthony Parkinson, White House, San Roque 1, San Jose, Occidental Mindoro, Philippines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pierre Pfeffer, Zoologie, Mammiferes et Oiseaux Museum National d'Histoire Naturelle 55, rue de Buffon 75005 Paris, France</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. Kelly Shelton, 211-A North Cordova, Burbank, California 91505, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Henry Stoddard, Branford Veterinary Clinics, Inc., P.O. Box 548, Branford, Florida 32008, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Charles H. Wharton, Institute of Ecology, University of Georgia, Athens, Georgia 30602, USA (Rt. 2, Clayton, Georgia 30525)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">World Conservation Centre, Avenue du Mont-Blanc, CH 1196 Gland, Switzerland (David Mitchell, Elizabeth Kemf)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M. H. Woodford, c/o FORW, FAO, Via delle Terme di Caracalla, 00100 Rome, Italy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zoos with Kouprey</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">None</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anoas</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. M. Dolan, San Diego Zoological Garden, San Diego, California 92112, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. Fischer, Institute of Tropical Veterinary Medicine, 63 Giessen, Wilhelmstrasse 15, Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. P. Groves, Department of Prehistory and Anthropology, The Australian National University, P.O. Box 4, Canberra, ACT 2600, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zoos with Anoas</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antwerp, Belgium (Royal Zoological Society of Antwerp; mountain anoa)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Berlin, Federal Republic of Germany (Zoologischer Garten; mountain anoa)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">London, England (lowland anoa)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Leipzig, German Democratic Republic (Zoologischer Garten Leipzig; mountain anoa)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jakarta, Indonesia (Kebun Binatang Ragunan) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rotterdam, The Netherlands (Stichting Koninklijke Rotterdamse Diergaarde; 1 male, 3 female)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">San Diego, California, USA (San Diego Zoological Garden; 1 male)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">San Diego, California, USA (San Diego Wild Animal Park; 1 male)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Surabaya, Indonesia (Kebun Binatang Surabaya)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sydney, New South Wales, Australia (Taronga Park Zoo)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tamaraw</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Department of Natural Resources, Quezon City, Manila, Philippines (J. B. Alvarez, Jr., Assistant Director)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. Fischer, Institute of Tropical Veterinary Medicine, 63 Giessen, Wilhelmstrasse 15, Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I. R. Grimwood, P.O. Box 45079, Nairobi, Kenya</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Natural Resources Conservation Office, Ministry of Natural Resources, Visayas Avenue, Diliman, Quezon City, Philippines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">David Anthony Parkinson, White House, San Roque 1, San Jose, Occidental Mindoro, Philippines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ian Player, P.O. Box 192, Howick 3290, Natal, South Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">N. Sitwell, c/o WWF(UK), 11-13 Ockford Rd., Godalming, Surrey GU7 lQU, England</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">L. M. Talbot, 6656 Chilton Court, McLean, Virginia 22101, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Forest Research Institute, College, Laguna 3720, Philippines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bearded Pig</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Julian Oliver Caldecott, Sub-Department of Veterinary Anatomy, University of Cambridge, Downing Street, Cambridge CB2 3DY, England</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. P. Groves, Department of Prehistory and Anthropology, The AustralianNationalUniversity, P.O. Box4, Canberra, ACT 2600, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Alastair A. Macdonald, Department of Anatomy, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Edinburgh EH9 10H, Scotland, United Kingdom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. MacKinnon, WWF/IUCN Representative, P.O. Box 133, Bogor, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">National Parks and Wildlife Office, Sarawak Forest Department, Jalan Gartak, Kuching, Sarawak, Malaysia (Kron Aken, David Labang, Mike Kavanagh)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. L. R. Oliver, Jersey Wildlife Preservation Trust, Les Augres Manor, Jersey, Channel Islands, United Kingdom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John Payne, Wildlife Section, Forest Department, P.O. Box 311, Sandakan, Sabah, Malaysia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M. H. Woodford, c/o FORW, FAO, Via delle Terme di Caracalla, 00100 Rome, Italy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zoos with Bearded Pig</P>
+<P ALIGN="JUSTIFY">Singapore, Singapore</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Manila, Philippines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sulawesi Warty Pig</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. Catibog-Sinha, Outdoor Recreation and Wildlife Research Division, Forest Research Institute, College, Laguna 3720, Philippines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. P. Groves, Department of Prehistory and Anthropology, The AustralianNationalUniversity, P.O. Box4, Canberra, ACT 2600, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Alastair A. Macdonald, Department of Anatomy, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Edinburgh EH9 10H, Scotland, United Kingdom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. Mackinnon, WWF/TUCN Representative, P.O. Box 133, Bogor, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. L. R. Oliver, Jersey Wildlife Preservation Trust, Les Augres Manor, Jersey, ChanneL Islands, United Kingdom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M. H. Woodford, c/o FORW, FAO, Via delle Terme di Caracalla, 00100 Rome, Italy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zoos with Sulawesi Warty Pig</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">None.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Javan Warty Pig</P>
+<P ALIGN="JUSTIFY">Raleigh A. Blouch, 2125 Forest Glen, Lansing, Michigan 48906, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">A. A. Bosma, Department of Functional Morphology, Faculty of Veterinary Sciences, State University Utrecht, P.O. Box 80157, 3508 TD Utrecht, The Netherlands</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Directorate of Nature Conservation (PPA), Jalan Ir. H. Juanda 9, Bogor, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. P. Groves, Department of Prehistory and Anthropology, The Australian National University, P.O. Box 4, Canberra, ACT 2600, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lembaga Biologi Nasional (LBN-LIPl), Bogor, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Alastair A. Macdonald, Department of Anatomy, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Edinburgh EH9 10EI, Scotland, United Kingdom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. MacKinnon, WWF/IUCN Representative, P.O. Box 133, Bogor, Indonesia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. L. R. Oliver, Jersey Wildlife Preservation Trust, Les Augres Manor, Jersey, Channel Islands, United Kingdom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Werner Pauwels, Pfeffingerstrasse 48, CM-053, Basel, Switzerland</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Perum Perhutani, Forest State Corporation, Jalan Jendral Gatot Subroto 17-18, Post Box 111, Jakarta, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M. H. Woodford, c/o FORW, FAO, Via delle Terme di Caracalla, 00100 Rome, Italy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zoos with Javan Warty Pig</P>
+<P ALIGN="JUSTIFY">Jakarta, Indonesia (Kebun Binatang Ragunan)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Surabaya, Indonesia (Kebun Binatang Surabaya)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pigmy Hog</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. A. Bosma, Department of Functional Morphology, Faculty of Veterinary Sciences, State University Utrecht, P.O. Box 80157, 3508 TD Utrecht, The Netherlands</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">P. C. Gogoi, Adviser Forests, (Wildlife and Environmental Planning), Meghalaya, P.O. Shillong 793 001, India</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. P. Groves, Department of Prehistory and Anthropology, The AustralianNationalUniversity, P.O. Box4, Canberra, ACT 2600, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Alastair A. Macdonald, Department of Anatomy, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Edinburgh EH9 lOH, Scotland, United Kingdom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. MacKinnon, WWF/IUCN Representative, P.O. Box 133, Bogor, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. L. R. Oliver, Jersey Wildlife Preservation Trust, Les Augres Manor, Jersey, Channel Islands, United Kingdom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">S. Deb Roy, Manas National Park, P.O. Barpeta Road, Kamrup 781 315, India</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zoos with Pigmy Hog</P>
+<P ALIGN="JUSTIFY">Gauhati, India (Assam State Zoo)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zurich, Switzerland</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Babirusa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. A. Bosma, Department of Functional Morphology, Faculty of Veterinary Sciences, State University Utrecht, P.O. Box 80157, 3508 TD Utrecht, The Netherlands</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C. P. Groves, Department of Prehistory and Anthropology, The Australian National University, P.O. Box 4, Canberra, ACT 2600, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Alastair A. Macdonald, Department of Anatomy, Royal (Dick) School of Veterinary Studies, University of Edinburgh, Edinburgh EH9 lOH, Scotland, United Kingdom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. MacKinnon, WWF/IUCN Representative, P.O. Box 133, Bogor, Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. L. R. Oliver, Jersey Wildlife Preservation Trust, Les Augres Manor, Jersey, Channel Islands, United Kingdom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Victoria Selmier, 353 10th Street, San Francisco, California 94103, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zoos with Babirusa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antwerp, Belgium (Royal Zoological Society of Antwerp, W. de Meurichy)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bandung, Indonesia</P>
+<P ALIGN="JUSTIFY">Berlin, Federal Republic of Germany, (Zoologischer Garten)</P>
+<P ALIGN="JUSTIFY">Copenhagen, Denmark, (Zoologisk Have)</P>
+<P ALIGN="JUSTIFY">Frankfurt, Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY">Jakarta, Indonesia, (Kebun Binatang Ragunan)</P>
+<P ALIGN="JUSTIFY">Nuremberg, Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY">Poznan, Poland</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rotterdam, The Netherlands (Stichting Koninklijke Rotterdamse Diergaarde)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Stuttgart, Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY">Surabaya, Indonesia, (Kebun Binatang Surabaya)</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Advisory Committee on Technology Innovation</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUGH POPENOE, Director, International Programs in Agriculture, University of Florida, Gainesville, Florida, Chairman </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Members</P>
+<P ALIGN="JUSTIFY">WILLIAM BRADLEY, Consultant, New Hope, Pennsylvania</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">HAROLD DREGNE, Director, International Center for Arid and Semi-Arid Land Studies, Texas Tech University, Lubbock, Texas (member through 1981) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ELMER L. GADEN, JR., Department of Chemical Engineering, University of Virginia, Charlottesville, Virginia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CARL N. HODGES, Director, Environmental Research Laboratory, Tucson, Arizona </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CYRUS MCKELL, Native Plants, Inc., Salt Lake City, Utah </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FRANCOlS MERGEN, Pinchot Professor of Forestry, School of Forestry and Environmental Studies, Yale University, New Haven, Connecticut (member through 1982) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DONALD L. PLUCKNETT, Consultative Group on International Agricultural Research, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THEODORE SUDIA, Deputy Science Advisor to the Secretary of Interior, Department of Interior, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Board on Science and Technology for International Development</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GEORGE BUGElARELLO, President, Polytechnic Institute of New York, Brooklyn, New York, Chairman </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Members</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SAMUEL P. ASPER, Educational Commission for Foreign Medical Graduates, Philadelphia, Pennsylvania </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DAVID BELL, Department of Population Sciences, Harvard School of Public Health, Boston, Massachusetts </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LEONARD BERRY, Professor, Graduate School of Geography, Clark University, Worcester, Massachusetts </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ERNEST.J. BRISKEY, Dean, School of Agriculture, Oregon State University, Corvallis, Oregon </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HARRISON S. BROWN, Director, Resources Systems Institute, East-West Center, Honolulu, Hawaii </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROBERT H. BURRIS, Department of Biochemistry, University of Wisconsin, Madison, Wisconsin </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CLAUDIA JEAN CARR, Associate Professor, Conservation and Resource Studies, University of California at Berkeley, Berkeley, California </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NATE FIELDS, Director, Developing Markets, Control Data Corporation, Minneapolis, Minnesota </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROLAND J. FUCHS, Chairman, Department of Geography, University of Hawaii at Manoa, Honolulu, Hawaii </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ELMER L. GADEN, JR., Department of Chemical Engineering, University of Virginia, Charlottesville, Virginia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN HOWARD GIBBONS, Director, U.S. Congress, Office of Technology Assessment, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">N. BRUCE HANNAY, Foreign Secretary, National Academy of Engineering, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM HUGHES, Director, Engineering Energy Laboratory, Oklahoma State University, Stillwater, Oklahoma </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM A. W. KREBS, Vice President, Arthur D. Little, Inc., Acorn Park, Cambridge, Massachusetts </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GEORGE I. LYTHCOTT, University of Wisconsin, School of Medicine, Madison, Wisconsin </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JANICE E. PERLMAN, Executive Director, Committee for a New New York, New York City Partnership, New York, New York </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUGH POPENOE, Director, International Programs in Agriculture, University of Florida, Gainesville, Florida </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FREDERICK C. ROBBINS, President, Institute of Medicine, National Academy of Sciences, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WALTER A. ROSENBLITH, Foreign Secretary, National Academy of Sciences, Washington, D.C. </P>
+<P ALIGN="JUSTIFY">FREDERICK SEITZ, President Emeritus, The Rockefeller University, New York, New York </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RALPH HERBERT SMUCKLER, Dean of International Studies and Programs, Michigan State University, East Lansing, Michigan </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GILBERT F. WHITE, Institute of Behavioral Science, University of Colorado, Boulder, Colorado </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BILL C. WRIGHT, Assistant Dean for International Programs, Oklahoma State University, Stillwater, Oklahoma </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN G. HURLEY, Director</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">MICHAEL G. C. McDONALD DOW, Associate Director/Studies </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MICHAEL P. GREENE. Associate Director/Research Grants </P></FONT>
+<!--
+</Section>
+</Section>
+-->
+</BODY>
+</HTML>
Index: /gsdl/stable/collect/demo/import/b18ase/metadata.xml
===================================================================
--- /gsdl/stable/collect/demo/import/b18ase/metadata.xml	(revision 20131)
+++ /gsdl/stable/collect/demo/import/b18ase/metadata.xml	(revision 20131)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE DirectoryMetadata SYSTEM "http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd">
+<DirectoryMetadata>
+    <FileSet>
+        <FileName>.*</FileName>
+        <Description>
+            <Metadata name="dls.Title">Little Known Asian Animals With a Promising Economic Future (b18ase)</Metadata>
+            <Metadata mode="accumulate" name="dls.Language">English</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Animal Husbandry and Animal Product Processing|Other animals (micro-livestock, little known animals, silkworms, reptiles, frogs, snails, game, etc.)</Metadata>
+            <Metadata mode="accumulate" name="dls.Organization">BOSTID</Metadata>
+            <Metadata mode="accumulate" name="dls.Keyword">introduce little-known Asian farm animals with a promising future</Metadata>
+        </Description>
+    </FileSet>
+</DirectoryMetadata>
Index: /gsdl/stable/collect/demo/import/b20cre/b20cre.htm
===================================================================
--- /gsdl/stable/collect/demo/import/b20cre/b20cre.htm	(revision 20131)
+++ /gsdl/stable/collect/demo/import/b20cre/b20cre.htm	(revision 20131)
@@ -0,0 +1,1134 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META NAME="Generator" CONTENT="Microsoft Word 97">
+<TITLE>&lt;&lt;TOC1&gt;&gt; Managing Tropical Animal Resources - Crocodiles as a Resource for the Tropics</TITLE>
+</HEAD>
+<BODY>
+
+<B><FONT FACE="Arial" SIZE=2><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Managing Tropical Animal Resources - Crocodiles as a Resource for the Tropics</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Report of an Ad Hoc Panel of the</P>
+<P ALIGN="JUSTIFY">Advisory Committee on Technology Innovation</P>
+<P ALIGN="JUSTIFY">Board on Science and Technology for International Development</P>
+<P ALIGN="JUSTIFY">Office of International Affairs</P>
+<P ALIGN="JUSTIFY">National Research Council</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Cooperation with the Division of Wildlife, Department of Lands and Environment, Papua New Guinea</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NATIONAL ACADEMY PRESS</P>
+<P ALIGN="JUSTIFY">Washington, D.C. 1983</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Board on Science and Technology for International Development(BOSTID) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Panel on Crocodile Farming</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">EDWARD S. AYENSU, Director, Office of Biological Conservation, Smithsonian Institution, Washington, D.C., USA, Chairman </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HOWARD W. CAMPBELL (deceased) U.S. Fish and Wildlife Service, Gainesville, Florida, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ARCHIE F. CARR, Jr., Department of Zoology, University of Florida, Gainesville, Florida, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">F. WAYNE KING, Director, Florida Museum, Gainesville, Florida, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FRANCOIS MERGEN, Pinchot Professor of Forestry, Yale University, New Haven, Connecticut, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MICHAEL G. MORRIS, Furzebrook Research Station, Institute of Terrestrial Ecology, Wareham, Dorset, England </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUGH POPENOE, Director, International Programs in Agriculture, University of Florida, Gainesville, Florida, USA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROBERT M. PYLE, Species Conservation Monitoring Unit, Cambridge, England </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SHELDON R. SEVERINGHAUS, Representative, The Asia Foundation, Taipei, Taiwan </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Contributors</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Papua New Guinea</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CAROL GABARA, Wildlife Division, Department of Oro Province, Popondetta </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WASSAM GABARA, Wildlife Division, Department of Oro Province, Popondetta </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">KAROL KISOKAU, Director, Office of Environment and Conservation, Waigani </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NAVU KWAPENA, Division of Wildlife, Department of Lands and Environment, Konedobu </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MIRO LAUFA, Division of Wildlife, Department of Lands and Environment, Konedobu </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GREG MITCHELL, Crocodile Farm, Lae </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LEO NING, Division of Wildlife, Department of Lands and Environment, Wewak </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other Countries</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MIGUEE AEVAREZE DEE TORO, Instituto de Historia Natural, Departamento de Zoologia, Chiapas, Mexico</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ANGUS D'A.BELLAIRS, Department of Anatomy, St. Mary's Hospital Medical School, University of London, England</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PETER BRAZAITIS, Department of Herpetology, New York Zoological Society, Bronx, New York, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROBERT H.CHABRECK, Louisiana Cooperative Wildlife Research Unit, Louisiana State University, Baton Rouge, Louisiana, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MAX C.DOWNES, The Game Conservation Centre, Melbourne, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">KARLHEINZ FUCHS, hoechst Aktiengesellschaft, Frankfurt, Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CLAIRE HACEN, Reptile Products Association, New York, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RENEE.HONEGGER, Zurich Zoo, Zurich, Switzerland</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">TED JOANEN, Rockefeller Wildlife Refuge, Chenier, Louisiana, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN LEVER, Koorana Crocodile Farm, Rockhampton, Queensland, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM MAGNUSSON, Instituto Nacional de Pesquisas da Amazonia, Manaus, Amazonia, Brazil</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HARRY MESSEE, School of Physics, University of Sydney, Sydney, New South Wales, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FRED PARKER, Kirwan Queensland, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ANTHONY POOLEY, St. Lucia Estuary, Zululand, South Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CHARLES A.ROSS, National Museum of Natural History, Smithsonian Institution, Washington, D.C., USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">K.B.SALE, UNDP/FAO Crocodile Breeding and Management Project, Hyderabad, India</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LUISVARONA, La Habana, Cuba</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CHAROON YOUNGPRAPAKORN, The Samutprakan Crocodile Farm, Samutprakan, Thailand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UTAl YOUNGPRAPAKORN, The Samutprakan Crocodile Farm, Samutprakan, Thailand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MYRNA WATANABE, Co-editor of ICUN Newsleter, Brooklyn, New York, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROMULUS WHITAKER, Guindy Deer Park, Madras, India</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NOEL D. VIETMEYER, Professional Associate, Board on Science and Technology for International Development, Crocodile Study Director</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">National Research Council Staff</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">F. R. RUSKIN, BOSTID Editor</P>
+<P ALIGN="JUSTIFY">MARY lANE ENGQUIST, Staff Associate</P>
+<P ALIGN="JUSTIFY">CONSTANCE REGES, Administrative Secretary</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This publication is dedicated to the memory of panel member Howard W. "Duke" Campbell who devoted most of his professional life to the conservation of crocodilians. Dr. Campbell was Chairman of the Crocodilian Specialist Group of the Survival Commission of the International Union for Conservation of Nature and Natural Resources at the time of his death in 1981.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Preface</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The panel that produced this report met in Papua New Guinea in May 1981. Its purpose was to consider the principles of the Papua New Guinea crocodile farming program and their implications for economic development and for the management and survival of crocodilians elsewhere.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodiles are an integral part of the tropical fauna; they are ecologically important, biologically interesting, and, potentially, a renewable natural resource of considerable economic value. The panel hopes that through this report the possibility of saving and managing this animal throughout the tropics can be better assessed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Members of the panel consulted officials of the Ministry of Wildlife and Conservation in Port Moresby and visited crocodile farms in Moitaka, Popondetta, and Lae. The panel is grateful to Karol Kisokau, Navu Kwapena, and Miro Laufa of the Division of Wildlife for arranging its itinerary and visits in Papua New Guinea. It also wishes to thank Yano Belo, Minister of Environment, for hosting an evening social at the Moitaka crocodile farm; Greg Mitchell and his wife Judy, who entertained the panel at their home in Lae and conducted a tour of their company's crocodile farm; and Wassam and Carol Gabara who acted as guides and hosts in Popondetta.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Advisory Committee on Technology Innovation (ACTI) of the Board on Science and Technology for International Development, National Research Council, is assessing scientific and technological advances that might prove especially applicable to problems of developing countries. This report is one of a series that explores promising areas of science previously unknown, neglected, or overlooked. Current titles in the ACT! series on Managing Tropical Animal Resources include:</P>
+<P ALIGN="JUSTIFY">· Water Buffalo: New Prospects for an Underutilized Animal (1981) </P>
+<P ALIGN="JUSTIFY">· Little-Known Asian Animals with a Promising Economic Future (1983) </P>
+<P ALIGN="JUSTIFY">· Crocodiles as a Resource for the Tropics (1983) </P>
+<P ALIGN="JUSTIFY">· Butterfly Farming in Papua New Guinea (1983) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These activities are supported largely by the U.S. Agency for International Development (AID). Program costs for this study were sponsored by AID'S Bureau for Asia, and staff costs by AID'S Office of the Science Advisor, which also made possible the free distribution of this report. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">1 Introduction</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodiles, alligators, caimans, and gavials ( Present-day crocodilians are grouped into three families: crocodiles, alligators and caimans, and gavials (gharials). The animals differ from one another only in minor characters such as shape of snout, arrangement of scutes, and dental features. This report focuses mainly on crocodile species, but its conclusions are generally applicable to alligators, caimans, and gavials.) have existed for some 200 million years - much longer than mammals - but they are now disappearing at alarming rates. Of the 21 or so species of crocodilians distributed in the warm waters of the world, at least 18 are threatened with extinction in most of the countries where they are found.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although some species, such as the American alligator, appear to be out of danger because of strict conservation measures, many of the others survive mostly in national parks, protected preserves, or a few breeding stations. This is true for the slender-spouted crocodiles of Africa and Asia, the saltwater crocodile of Australia and Southeast Asia, the black caiman and Orinoco crocodile of South America, the Chinese alligator, the Siamese crocodile, and other species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat destruction is a major contributor to crocodilian decline; each year more breeding areas are disturbed as swamps and marshlands are drained, rivers dammed, estuaries reclaimed, and riverine forests denuded. However, illegal poaching by tribal people with their simple but effective traps, snares, and set hooks, as well as professional hunters operating with power boats, spotlights, and modern firearms are also decimating the animals over most of their ranges.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To a large extent these animals are being destroyed because of their market value. Crocodile is regarded as the costliest and most fashionable leather in western markets. Since World War II, demand for crocodile leather shoes, handbags, luggage, wallets, watchbands, and other expensive luxury articles has far exceeded supply. Even small items such as purses and handbags sell for many hundreds of dollars each. For instance, a ladies' purse or handbag made from crocodile skin can command prices as high as $4,000. A pair of men's shoes may cost from $500 to $900, and a wallet from $150 to $250.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The crocodile trade peaked in the mid-1960s, when world markets absorbed more than 2 million crocodile skins each year. Today it is still large. In 1979, for instance, 1,000,000 caiman hides and 300,000 true crocodile hides entered international commerce. In 1981 the United States itself imported 100,000 hides.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">International markets for reptile hides and leathers are centered in France, Italy, the Federal Republic of Germany, and Japan. France, the single largest buyer of raw crocodilian hides, uses an estimated 300,000 to 400,000 skins a year. The major buyers of finished crocodile leather products are Hong Kong, Japan, Thailand, Singapore, and the United States.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unrestricted hunting and poaching for hides are wiping out the large breeding animals. Excessive hunting has a devastating effect on crocodile populations because their age distribution is like a pyramid: a small number of breeding animals dominates a large number of juveniles and hatchlings, most of which never survive to maturity. Such societies, in which the size of future populations depends on only a few animals, are highly vulnerable to extinction; once some of the mature members are killed the population can crash. And it takes a long time for a crocodilian population to rebuild because for most large species the females do not begin breeding until they are at least 8 years old.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rearing Crocodiles</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although there may seem to be no future for many crocodile populations, the situation is not hopeless. With intelligent intervention and under good conditions they can recover rapidly. Mature crocodiles have no enemies other than man, and, given some care and protection, a small number of breeders can produce a huge number of progeny each year. Mature females of the various crocodilian species usually lay between 30 and 70 eggs each year, and under normal conditions most of these eggs hatch successfully. The key to conserving the population is to protect the few mature animals and their habitats. Then, because of their fecundity, crocodilians can rapidly build up large numbers of young.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This has been exemplified by the American alligator (Alligator mississippiensis). Ten years ago its future seemed doubtful, but the legal protection of the populations has brought a remarkable recovery. Numbers are now so high that two states have lifted the ban on harvesting alligators, and between lo,ooo and 20,000 American alligator hides now enter commerce each year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The past few decades have seen several other examples of successful crocodile-rearing projects. Later chapters of this book highlight the national program in Papua New Guinea. In addition, three successful government-operated farms exist in India (where all the progeny is returned to the wild because current Indian law prohibits commercial crocodile farms). A remarkable farm with more than 3,000 breeding animals operates on the outskirts of Bangkok, Thailand. Australia has four crocodile farms, and a few African countries now have crocodile farms that are already beginning to supply hides internationally. For example, in 1982 Zambia had two such farms, Zimbabwe, five, South Africa, four (with five more planned or under construction), and Kenya, one. Appendix A lists these and other countries that are initiating farms for various crocodilian species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The early technical success of these projects offers the expectation that with an appropriate framework of safeguards and research, crocodiles might become a thriving resource for tropical nations. If such experiences can be replicated, crocodilians and their habitats may come to be considered as resources to be managed and treasured. This will require considerable investment, strict legislation and law enforcement, and international cooperation and research, as well as careful monitoring of the traffic in farmed hides. But national crocodile industries are a possibility, and they could result in thriving natural populations that are free from the danger of extinction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Such prospects may also provide economic incentives for preserving the often-fragile ecosystem in which wild crocodilians live. Crocodile farming could play a part by slowing the uncontrolled draining of swamps and other wetlands that cover large areas of the lowland humid tropics of Asia, Africa, and Latin America.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodiles as a managed resource could economically benefit remote areas of the lowland tropics. Villagers there often have few alternative sources of income and possibilities for economic development are limited. Because the human population is relatively sparse, few opportunities exist for local trading; even where fish are abundant the problems of marketing are formidable. Indeed, in some areas crocodiles may constitute the only readily salvable resource.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodiles as Farm Animals</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Well-fed crocodiles grow quickly. Under ideal conditions they may reach lengths of 1 m or more in a year and 1.5 m in 2 years. They are normally harvested in the third year when they reach about 2 m in length. In this time their value may have risen from about $5 to as much as $200.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodiles have acquired a reputation as voracious feeders; investigations reveal this to be false. The animals actually have modest food requirements. Many hatchling animals have a food conversion rate of about 50 percent; that is, the crocodile adds 1 kg of weight for every 2 kg of food it consumes. Cattle, sheep, and pigs would have to eat 3-5 times as much food to achieve the same weight increase. After 2 years the crocodile's growth rate begins to slow down. During the third year the conversion falls to about 25 or 30 percent, which is still a high figure, and makes crocodiles probably the most nutritionally efficient land animal for commercial husbandry. Only the growth of some fish is comparable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The high food conversion efficiency is due to the fact that crocodiles have low metabolic rates and are normally extremely lethargic. They are active only in short bursts, spend hours immobile, and move only about one-third as much as mammals. Moreover, being reptiles, they spend almost no food energy maintaining body temperature. They bask in the sun to keep warm and seek shade or water to cool off. For these reasons crocodilians can thrive in marginal habitats unsuitable for mammals or birds (Investigations on the Nile crocodile showed that a pelican takes 3 days to consume food equal to its own weight, whereas a crocodile takes 125-160 days - Cott, 1961.) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodile farming is also space efficient. As long as they are sorted by size, hundreds of juveniles or dozens of larger animals can be penned together in a small area. Indeed crocodiles often choose to pile up on top of one another in stacks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Little is known about disease in reptiles. However, as farm animals, crocodiles have a major advantage: they produce antibodies readily and have few problems with external infections. In the wild it is common to find crocodiles missing limbs or tips of tails, with eyes gouged out, or enormous scars on the body. But the wounds heal readily, with little sign of infection (The American alligator is being used at the University of Florida College of Veterinary Medicine as a model for studies on antibody formation.). This minimizes the need for veterinary services, a distinct benefit in remote village farms. Nevertheless, internal bacterial diseases, such as salmonella, can get out of hand and destroy a program by reducing growth rates, lowering hide quality, or killing the animals outright.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodile Hides</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is the belly skin that is the valuable part of a crocodile, and the worth of a hide is determined by the size of the belly skin, the smallness of its scales, and the hide's general condition. (Holes, cuts, scars, and rot drastically reduce its value.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although international markets utilize any crocodile skin from 0.3 m to 6 m long, the most sought-after hides are not the biggest but the moderate-sized ones from animals about 1.5-2 m long. These hides are approximately 25-50 cm in belly width.( A crocodile's total length is approximately 4-4.5 times the width of its belly). Large hides, for example those more than 3 or 4 m in length, are suitable only for luggage and briefcases because their scales are large. Smaller hides, on the other hand, are suitable both for items such as shoes, handbags, and wallets and for larger items.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Internationally, the most desirable hides come from the saltwater crocodile (Crocodylus porosus). It has proportionally the smallest belly scales of any crocodile, it lacks osteoderms,(Osteoderms are deposits of calcium carbonate under the skin. They are undesirable because they dissolve away during the tanning process, leaving a pitted surface),and on the side of its body the scales are uniformly small. The next most valuable hides probably come from Morelet's crocodile (Crocodylus moreletii), the American alligator, the Siamese crocodile (Crocodylus siamensis), and the Nile crocodile (Crocodylus niloticus). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Papua New Guinea</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The rest of this report highlights the program in Papua New Guinea, where during the last 10 years the government has made crocodile rearing an organized industry, much as poultry farming is elsewhere. This program, which is beginning to establish crocodiles as a significant natural asset, is designed both to protect the wild populations and to integrate traditional uses of these reptiles into a scientifically managed hide industry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Papua New Guinea crocodile farming (In the official terminology of the Convention on International Trade in Endangered Species of Wild Fauna and Flora (CITES), the Papua New Guinea program is "ranching" rather than "farming" because the young livestock are mostly culled from wild populations and are not bred on the farm) has become the cornerstone for the economic improvement of some of the world's poorest people. It offers a means for bringing the rural poor into the process of economic development, and it can be blended into a traditional village structure where land and resources may be communally owned.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The projects are small and many have had operational difficulties, but they suggest that conservation and economic development can be not only compatible, but also mutually reinforcing. The innovative idea is not that crocodiles can bring in money, but that sound conservation can be blended with marketing crocodile skins, meat, and by-products.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An important aspect of this approach to crocodile conservation is that it is based on protecting the existing landscape and resources. It provides a tool for conserving the species in their own wild habitats so that survival will not depend on a few captive specimens living under artificial conditions. It requires none of the bush clearing, fencing, forage planting or pesticide spraying that domestic animals often demand ,important advantages in an economic development project in a fragile tropical swamp or rain forest ecosystem.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Papua New Guinea approach, then, provides an economic incentive for wildlife protection. Everyone ,from the villager to the minister of trade ,has a stake in keeping the wild populations healthy. Out of self-interest, in addition to natural respect, large numbers of people become the guardians of the resource and the habitat needed to keep it surviving and productive.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The world's major conservation organizations have given Papua New Guinea's crocodile program their stamp of approval. In 1976 a team of scientists representing the International Union for the Conservation of Nature and Natural Resources, one of the most prestigious conservation organizations in the world, inspected the program. As a result, Papua New Guinea was given special dispensation, and its crocodile skins can be legally traded internationally. For example, because of its endangered status the saltwater crocodile is banned from trade by the Convention on international Trade in Endangered Species of Wild Fauna and Flora (CITES). An exemption, however, is granted to Papua New Guinea in recognition of the fact that its crocodiles now are sufficiently well managed to sustain a skin industry without seriously damaging the wild stock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This program serves as a model for nations of the Americas, Asia, and Africa where crocodilian resources are still unmanaged or managed poorly. Crocodiles are being destroyed so fast that within about five years Papua New Guinea and other countries that have organized crocodile farming operations may be the only ones supplying significant numbers of skins to the international market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although the principles developed in Papua New Guinea deserve international attention, the recipe will not be a cure-all for problems of rural development or crocodile conservation. Instead, the Papua New Guinea experience suggests that local social, political, economic, and conservation goals can become the impetus for a successful blend of village improvement and wildlife protection.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">2 Crocodile Farming in Papua New Guinea</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As recently as the l950s, crocodiles were abundant in Papua New Guinea. Hunting was a major occupation and was unrestricted. Some Australians and Europeans made fortunes by shooting thousands of crocodiles a year to make shoes and handbags in Europe and North America.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although it was obvious that wild populations could not sustain such wholesale slaughter, the destruction continued. By 1967 both the saltwater crocodile (Crocodylus porosus) and the freshwater crocodile (Crocodylus novaeguineae) were threatened with extinction. By 1968, despite increased hunting, the yield of skins had dropped in half; along the easily accessible river systems, crocodile populations had been wiped out. By 1969 the saltwater crocodile had disappeared from much of its range throughout the country, and wildlife officers estimated that without protection most specimens of breeding size would be eliminated within five years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But how could crocodiles be protected? Papua New Guinea is divided by mountain ranges, ravines, torrential rivers, forests, seas, malarial swamps, and more than 700 languages. It would take hundreds of trained wildlife officers to enforce a ban on crocodile hunting, particularly in the face of opposition from tribesmen who have traditionally harvested crocodiles for food, decorative items, and implements.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The challenge was given to the officers of the Wildlife Division. Under the leadership of Max C. Downes, these officials concluded that the best way to protect crocodile populations was to halt the slaughter of the large breeding adults and build up a new hide industry based on the increased numbers of young that would result.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Few young crocodiles ever reach breeding age in the wild. The tiny, virtually defenseless hatchlings are easy prey for large fish, birds, or other crocodiles. Almost all of them are killed by predators or by other natural causes, such as floods..</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Main areas of crocodile distribution in Papua New Guinea.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What was needed, the wildlife officers concluded, were incentives to make these smaller animals economically attractive, incentives to encourage local people to raise small crocodiles to commercial size. If that could be accomplished, hundreds of hatchlings that would normally perish could be utilized without endangering the wild populations' future. Villagers could benefit by selling skins while the vital breeding-sized animals were being left alone to provide more hatchlings. The system could benefit both the villagers and the vulnerable crocodile populations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="b20a.png"></center><br>
+ Main areas of crocodile distribution in Papua New Guinea</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The idea was viable partly because many Papua New Guineans - particularly those of the Sepik and Fly Rivers - have ancient spiritual and cultural attachments to crocodiles. To them, the idea of handling and managing the animals is not unusual. Crocodile motifs are common in their art and they live in harmony with the big beasts and do not consider them dangerous pests to be eliminated.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Legislation passed by the Papua New Guinea government in 1969 capitalized on this tradition by making the villagers themselves the real force in crocodile protection. The law did not ban crocodile hunting, but instead banned the possession, sale, and export of skins larger than 20 inches (51 cm) wide. In this way, it protected breeding-sized animals while allowing for the harvest of juveniles. It also allowed a person to kill a crocodile if attacked (but barred the selling of the skin, if it were oversized).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1980, the legislation was supplemented by a law banning the export of small skins. Together, the bans on possessing large skins and exporting small skins have created a stimulus for gathering small crocodiles from the wild and rearing them to moderate size on farms. The legislation has been the impetus for crocodile farming.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodile farming officially started in Papua New Guinea in 1972. In the late 1970s, it was extensively supported by a UNDP/FAO assistance program that provided personnel and funds for technical support and program management. Today there are about 300 small village farms (The numbers vary, since some villagers go in and out of production depending on their need for income, seasonal variation in river levels, the cost of fuel, and the availability of government extension agents) supplying a number of larger business groups that rear crocodiles.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wildlife officers now teach crocodile farming, not crocodile conservation per se. They have introduced crocodile-rearing techniques to villagers all over Papua New Guinea. They help build pens and teach tribesmen how to care for the young reptiles, which are so vulnerable and timid that they can literally die of fright.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Government loans of up to US$10,000, along with matching development bank loans, are available to help a farmer enter the crocodile farming business. The funds pay for pumps for changing the water in the pens and sometimes for an outboard motor used in gathering young crocodiles. Everything else a villager needs can be obtained from the forest, including materials for pen construction; a small farm can therefore be established inexpensively.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Three Types of Farms</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The government's crocodile management program recognizes three levels of operation: village farms (up to 300 crocodiles), small-business farms (up to 1,000 crocodiles), and large-business farms (more than 1,000 crocodiles).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A village crocodile farm consists of a small pen fenced with posts lashed together with vines. This stockade fence is about 1.5 m high and is sunk about 60 cm in the ground so the crocodiles cannot burrow out. Much of the enclosure is planted with grass, cassava, and banana trees to provide secluded areas where the animals, which regulate their body temperature by the warmth of the sun, can find shade. A shallow pool is excavated in the center.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These village farms are usually run by only one or two people. Many are little more than pens scattered in the remote bush for holding young crocodiles until a buyer from a larger farm comes around. Small crocodiles bring less money than medium-sized animals, but the villager avoids having to feed and care for them for a long period.(Because of operational difficulties, many village farms were abandoned in 1982. Lack of proper husbandy - despite government efforts - were the main reason for these difficulties. Most villagers now collect and hold young only until buyers from commercial farms arrive. However, they are still earning money from crocodiles, and the concept of fully functioning village farms remains valid for the future in Papua New Guinea, as well as for appropriate sites elsewhere). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The small-business farm usually consists of a group of enclosures (each about 6 m x 6 m) constructed of bush materials. It is typically located near an airstrip. It buys crocodiles from the village farmer and, in turn, supplies them to the larger farms, which sometimes dispatch aircraft to pick the animals up (Special cardboard shipping containers have been devised. They can be folded to make cylinders of various diameters to fit crocodiles of different sizes). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Large-scale crocodile farms accommodate as many as 20,000 crocodiles and require a large investment. They serve to regulate the export of skins and are the major purchasers of live crocodiles from the smaller farms. During periods of drought, flooding, or diminished food supplies, the large-scale farms also act as emergency buyers. On the outskirts of Lae on Papua New Guinea's northern coast, there is a 100-hectare farm with nearly 8,000 crocodiles. It is associated with a poultry company, and the crocodiles are raised on the offal from the slaughterhouse.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Government Research and Extension</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Wildlife Division has constructed four demonstration farms across the country and one large research farm at Moitaka near Port Moresby, the capital city. After training at one of these, a tribesman can start his own farm alone or can call on the government for further assistance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moitaka is also the site of short courses in crocodile farming. Prospective farmers are brought in for several weeks' training. They learn how to build pens, to feed and care for crocodiles, to kill and skin them, and to prepare the hides for market. They also learn about the crocodile laws and the reason they were enacted. A farm at Lake Murray, in a remote and swampy area of the Western Province, serves the same purpose. It is built entirely from bush materials (see picture, pp. 6-7).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Wildlife Division provides instruction books, profusely illustrated for the illiterate. The books include vivid descriptions of all phases of farming the animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economic Gains</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 10 years, crocodile rearing has expanded remarkably in Papua New Guinea. It has already become the main source of income for the people of some swamp and river areas. The Ambunti area, for example, produces coffee and rice, but crocodile skins now bring in much of the area's income. By 1981 the farms nationwide contained a total of 30,000 crocodiles, ensuring a sustained production of at least 10,000 skins a year worth approximately US$ 1-2 million on the international market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because crocodiles are a familiar resource, villagers take to the program quickly. By contrast, introducing cattle or western-style crop raising requires massive education and training, in addition to some social and environmental disruption.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On government farms in Papua New Guinea, fish-fed crocodiles have increased their belly width by 25 cm per year and are ready for slaughter in 2-3 years when the width approaches 50 cm. The selling price of the skin is then between $100 and $200, depending on species, flaws, and size.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But skins are not the only product. A crocodile with a skin big enough to market can provide 20 kg of meat. The meat is white and is low in fat. Papua New Guinea is a net importer of meat, and crocodile farming is now augmenting local supplies. The large farm at Lae already sells frozen crocodile meat (including front and hind legs, tail steaks, ribs, and chops) both locally and on foreign markets. Some orders have come in from dealers in Paris who supply expensive French restaurants.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">3 Conclusions</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Benefits of Crocodile Farming</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodile farming seems to be singularly appropriate for rural, isolated, lowland communities in the tropics. The land there is often unsuitable for conventional agriculture, and the people lead a tenuous existence or drift to the cities looking for work. In such areas, there are few opportunities for people to earn cash without drastic and expensive modifications to the environment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodile farming has many advantages over hunting the animal in the wild. For instance, crocodiles farms can:</P>
+<P ALIGN="JUSTIFY">· Permit government monitoring of the crocodile industry. (Hunters are more difficult to regulate since they work in remote areas, often undetected and crossing borders at will.)</P>
+<P ALIGN="JUSTIFY">· Yield a regular harvest of a specific number of animals of a selected size.</P>
+<P ALIGN="JUSTIFY">· Produce a standardized, premium product that better serves the needs of the international hide industry, making skins poached from the wild less desirable. (They may provide, for instance, a standard first grade 1-1.5 m long hide rather than hides of mixed size and quality.)</P>
+<P ALIGN="JUSTIFY">· Reduce the wasteful losses of hides from improper handling, the fate of a high proportion of skins now brought in from the wild.(*In remote areas, salt may become scarce late in the season as it is used for hides. This often results in insufficient salt being used when the supply runs out and hides subsequently rot or "slip". In some isolated areas, as much as 25 percent of the hides are lost or downgraded because of improper curing for lack of salt. However, skins produced on farms, especially near urban areas or large villages, are usually properly salted; if salt becomes scarce, killing of the animals can be delayed) </P>
+<P ALIGN="JUSTIFY">· Educate the public about crocodile ecology and the animal's importance to the habitat and the local economy.</P>
+<P ALIGN="JUSTIFY">· Provide sites for scientific studies on crocodilians. Studies conducted on alligators at the Rockefeller Refuge in Louisiana, USA, for example, have provided reproductive, nutritional, and growth data directed specifically towards developing efficient farming techniques.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For some farms the earnings from hides, meat, and by-products may be supplemented by tourism (through gate admissions and the sale of curios), as well as by selling eggs and young to other farms for breeding stock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A long-term program of wise utilization of crocodiles can benefit governments by providing revenue from hides, curios, craftwork, and manufactured articles, as well as from export duties. Furthermore, in their natural state in parks and preserves, crocodiles are an important tourist attraction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In an effort to preserve crocodile habitats, the Papua New Guinea program has encouraged the collection of eggs or young from the wild and has discouraged the breeding of crocodiles in captivity. This is because a reliance on the wild creates economic incentives to conserve crocodile habitats; if the habitats are drained for human settlement or conventional agriculture the farmers lose the source of their stock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Contrary to popular impression, preliminary observations indicate that crocodiles benefit commercial fisheries. The animals are important links in the ecosystems of rivers and lakes and are often the largest inhabitants of the freshwater wetlands. Their movements inhibit the growth of aquatic plants in the waterways, and, in areas with prolonged dry seasons, some species maintain residual waterholes that benefit small aquatic organisms that would otherwise perish. In estuaries and lakes, crocodiles enrich the nutrient content of the water by converting terrestrial prey into feces that in turn feed invertebrates and fish.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Where crocodiles have been eliminated, reductions in the tonnage of fish caught for human consumption can usually be demonstrated. For example, in Brazil, Kenya, and India, a decline in the fishermen's catch has paralleled the decline in crocodiles.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Limitations of Crocodile Farming</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Governments and individuals seeking rapid returns on investments should realize that a crocodile farming industry is not a get-rich-quick scheme. To build a stable national industry may require 10 years and an investment of at least $500,000 before it is biologically and economically successful.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nevertheless, an organized industry is vital. A village crocodile-rearing pond is only profitable if there is someone to buy, grade, package, and ship the product with all its documentation. Services will be needed at all levels to advise on disease control, nutrition, skinning, and preserving the hides. In many parts of the world crocodile farms have been financial and conservation failures not just because of poor husbandry management, but also because of fiscal shortsightedness.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Selection of a suitable farm site is basic to the economics of the entire operation. Farms demand a steady supply of meat or fish to feed the crocodiles, and are most successful when located near a reliable source of inexpensive food. Some farms take advantage of offal from nearby chicken or cattle abattoirs; others use the fish by-catch from shrimping operations. In the absence of an inexpensive animal protein feed, the farm will have to raise its own food (tilapia is frequently used) or harvest it from the wild, both of which can be expensive.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodile farms also require a steady year-round supply of clean water for the holding ponds and tanks. If this cannot be supplied by gravity flow from nearby sources, it must be pumped from wells or from nearby lakes or ponds. This, too, is likely to be expensive.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite the general hardiness of crocodiles, the farms must have access to veterinary care. Most disease problems stem from poor sanitation, low water temperatures, and poor diet, all of which can be easily corrected. But with large numbers of animals crowded together, disease problems, if not quickly diagnosed and treated, can wipe out the young captive animals in epidemic proportions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Capturing and transporting large crocodilians is dangerous and difficult. Dealing with a large captive population of crocodiles of different age groups and sizes requires a great deal of experience.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although crocodilians are common in zoos, successful breeding of these reptiles in captivity is so far a rare and remarkable event. However, researchers are now coming to understand the behavioral requirements for success. For instance, gravid females must have access to appropriate nesting sites, males must have ample space when they are penned in with other males, and juveniles and hatchlings must be separated from their parents and housed by size and feeding preferences. That prolific breeding can be achieved, however, is illustrated by the Samutprakan crocodile farm near Bangkok, Thailand, which reportedly has reared tens of thousands of its own animals and now aims for a population of 100,000 crocodiles by 1987.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Conservation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The worldwide shortage of crocodile leather is becoming more acute each year, and it will be many years before any output from farms can significantly reduce pressure on wild populations. Thus, farming should be only one aspect of an overall conservation program that includes total protection of some populations in national parks and sanctuaries. In addition, the conservation of natural wetlands is an important part of overall economic planning. If wetlands are lost, many wild species in addition to crocodiles will be affected.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Australia, Asia, Africa, and the Americas, many crocodilian populations are poorly protected because governments lack the manpower or the will to enforce conservation laws rigorously, especially in the remote areas where the last remaining crocodiles reside. Because most wildlife departments in the tropics are short staffed and have vast areas to police, their efforts at wildlife protection are frequently ineffective. Moreover, some countries have been slow to introduce protective legislation for an animal that does not engender public sympathy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Papua New Guinea's program offers one of the best hopes for saving all endangered crocodiles, alligators, caimans, and gavials. The methods developed there serve as a model for other nations. By providing an alternative, Papua New Guinea gives villagers the incentive to protect wild crocodiles that are breeding nearby so as to assure themselves of future supplies. The people themselves become the conservators of the local animals and habitats. In turn, watersheds, soils, and conventional agricultural development (including natural and forest products) can all benefit. The habitat is also preserved for many other wildlife species that share it, and genetic diversity can be maintained. Conversely, without a special incentive to conserve them, all these resources are normally degraded as a region develops.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">4 Regulations, Safeguards, and Research Needs</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Papua New Guinea experience provides a model for other nations, but to implement such a program requires a foundation of legislation, government support, and legal safeguards. Prerequisites of any crocodile farming program are an overhaul of legislation, strict law enforcement, and reciprocal laws with neighboring countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The enforcement of wildlife regulations is so inadequate in most countries that crocodile farming is open to abuse. Farms can front for illegal poaching operations, and hides taken from the wild can be intermingled with hides produced on the ranch or farm unless government enforcement is stringent and inspection frequent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moreover, the stimulation of world trade in crocodile hides through the sale of farmed hides might lead to increased poaching of wild crocodiles or eggs. Poachers have fewer operating expenses than farmers, and unscrupulous hunters and dealers can harvest hides, steal crocodile eggs or young, and subsequently sell them through countries that lack enforcement capabilities. This practice could be disastrous for countries where crocodile populations have almost disappeared.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Government Regulations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Before any farming scheme is attempted, protective legislation should be in operation throughout the country. This should make it unlawful to kill, capture by any means whatsoever, disturb willfully, or pursue any crocodiles, or to collect or gather any crocodile eggs without a permit.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">No crocodile eggs should be allowed to be imported or exported with out a permit. No persons should possess, sell, buy, donate, receive consequent upon a donation, convey, keep in captivity, or display any live crocodiles without being the holder of a permit. And no person should be allowed to import or export any crocodile, dead or alive, or any portion of a crocodile, processed or not, from any country without a permit.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Before granting a license for a commercial farm, the government should investigate the applicant's land tenure and financial resources, particularly since the farm will have to operate for three to four years before producing crocodiles suitable for culling. The applicant's ability and experience in rearing crocodiles should be determined. A plan of the proposed farm, including details of water and food supply and the proposed methods of harvesting food, should be examined.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is suggested that:</P>
+<P ALIGN="JUSTIFY">· No permit for egg harvesting should be issued until adequate rearing facilities have been prepared. The permit should state the name of the holder or his authorized representative, the annual total number of eggs allocated for harvesting, and the area where collection is permitted.(In some cases it is also important to specify a harvest time. Often it is best to take eggs laid early in the season because the female will then lay another clutch.) </P>
+<P ALIGN="JUSTIFY">· Permits should be issued on a year-by-year basis. The applicant should understand that the department may refuse to renew or issue further permits if the farm is not managed satisfactorily or if permit conditions have not been observed.</P>
+<P ALIGN="JUSTIFY">· The applicant should understand that the farm and all production records should be available for inspection by an official of the conservation department.</P>
+<P ALIGN="JUSTIFY">· The farmer should be required to submit periodic reports detailing the total number of nests raided and eggs harvested, the egg mortality, and the number of eggs hatched. Thereafter, the number of animals held in captivity, the rate of mortality and its causes, if known, and the number of animals sold or culled should be included in each report.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Furthermore, it is recommended that the permit holder release 5 percent of his annual crop of hatchlings in order to restock the natural habitat. In addition, a further 5 percent of the hatchling crop should be reared to a length of 1 m before being released, bringing the total release of young crocodilians to 10 percent of the annual crop of hatchlings.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The distribution of hatchlings and young reared animals should be supervised by the conservation department.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unless government agencies monitor the wild populations of crocodilians being harvested for hides, eggs, or young, the farms themselves could become a major drain on those populations, leading to their extinction. Therefore, before any farming program is started, a survey of the breeding grounds should be undertaken to determine the number of nests available and those from which eggs can be taken with least danger to the wild population (for example, from nests on grounds likely to be flooded).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These breeding grounds should be fully protected; tourists on foot, in vehicles, or in launches should not be allowed to visit or disturb crocodiles during the breeding season.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">International Safeguards and Cooperation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The international traffic in millions of unmarked crocodilian hides and products poses one of the greatest obstacles to enforcement of national and international endangered species regulations. Hides and skins frequently cannot be traced to their source or country of origin. Legally harvested or farmed animals cannot readily be distinguished from those exported in secret from illegal sources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The need for internationally acceptable methods of marking individual hides and products is critical. Traffic in illegal crocodilian hides and products will continue as long as law enforcement agencies lack the means to detect them easily.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the United States a system has been developed in some states that enables conservation, police, and customs officials to monitor traffic in alligator hides. A conservation authority issues an official tag for each animal allowed by the license. All hides exported are tagged with a serially numbered plastic tag that cannot be removed without breaking it. The serial number is recorded on the export permit and with details of the buyer's and seller's name and address. This tag remains on the hide, right through the tanning process, until the hide reaches the manufacturer. Each tannery maintains a register of purchases that is available for inspection. This system also is being implemented in Zimbabwe and is worthy of trial in other countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The tagging of all hides and products for individual identification is an important safeguard. Other safeguards include:</P>
+<P ALIGN="JUSTIFY">· The use of engraved stamps or seals to authenticate legal licenses and export permits and make it more difficult for documents to be forged.</P>
+<P ALIGN="JUSTIFY">· Internationally accessible data and a retrieval system that allows law enforcement personnel to corroborate the authenticity of documentation and the origin of hides and products;</P>
+<P ALIGN="JUSTIFY">· Monitoring agencies to record and publish market statistics, traffic, and trends;</P>
+<P ALIGN="JUSTIFY">· Laws limiting the sale of hides only to nations that cooperate in an internationally sanctioned program of safeguards; and</P>
+<P ALIGN="JUSTIFY">· Research funding to monitor populations and develop new marking and identification techniques. (For instance, the use of dyes, roll marking, and infusion of detectable chemical tracers has yet to be fully explored.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research Needs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is urgent need for tannery owners, manufacturers, and conservation authorities to jointly work out the rational exploitation of crocodile populations. Commercial interests have reaped a rich reward over many years, and if the crocodile industry is to continue, its entrepreneurs must invest in management and conservation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Clearly, research to improve farming techniques will be a wise investment for both commercial operators and the countries concerned. Surveys to determine population numbers and size as well as the structure of breeding stocks and recruitment rates are essential. Such surveys may indicate the need to establish sanctuaries to protect breeding stock and nesting grounds, or perhaps to ban hunting to allow populations to recover. A rearing program and restocking of suitable habitats might be necessary.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendixes</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Appendix A: Crocodile Farming Around the World</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Experiences with crocodile farming in Papua New Guinea, the main subject of this report, are described in chapter 2. Here we summarize the status of similar efforts in other countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Four crocodile farms have been established in Australia, one in the Northern Territory and three in Queensland. To date, only the Edward River farm, operated by the government as an aboriginal development project, has developed a successful breeding program. There, seven-yearold saltwater crocodiles (Crocodylus porosus) hatched on the farm from wild eggs are now breeding and laying fertile eggs. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Asia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">People's Republic of China</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A farm for Chinese alligators (Alligator sinensis) has been established at Xuancheng, Anhui Province. Its purpose is to breed alligators for conservation, although the hide of this species is not in great demand because it has many osteoderms in the belly scales. Recently the government has expressed interest in establishing a farm for saltwater crocodiles in southern China. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Taiwan</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Taiwan has one crocodile farm or rearing station, but it is too far north to breed its own stock, except in heated indoor enclosures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Philippines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are several buyers in the Philippines who maintain pens of crocodiles for short periods. None of these is a farm. A new experimental farm for the Philippine freshwater crocodile (Crocodylus novaeguineae mindorensis) was established by Silliman University in an attempt to preserve that endangered species and to promote an economic interest in crocodile conservation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Micronesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A farm for saltwater crocodiles has been established on Palau, where a small population of these crocodiles occurs in a brackish interior swamp. In the past, the government hired a hunter to reduce the population whenever the local people felt it had become sufficiently large to present a danger, about once a decade. Presumably the nuisance crocodiles will now end up in the farm. The farm, which has been in existence only for a year or two, earns money from tourist admissions as well as hide production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A few crocodile-rearing stations have operated for several decades in Java, Sumatra, and Kalimantan. These have been stocked with eggs and young animals collected from the wild in Sumatra and Kalimantan. In the early 1970s, three such operations in Samarinda, East Kalimantan, closed down for lack of wild stock. At least one operation in Jakarta, Java, continues to survive, but with virtually no output of stock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A survey of Irian Jaya (Indonesian New Guinea) in 1980 indicated a number of ranches in that region as well, but revealed that some were having difficulty obtaining stock because of overharvest.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Singapore</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Singapore has a famous crocodile farm that figures prominently in tourism. It breeds some of its stock, but also obtains wild stock from all over Southeast Asia. Singapore has a thriving crocodile hide trade. Many buyers and several tanneries are located there.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Singapore is not a member of CITES and openly trades in any and all species of crocodilians.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Malaysia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are several crocodile farms in West Malaysia (at Penang, for example) and at least one in East Malaysia (near Sandakan, Sabah). These started out as rearing stations relying on wild young, but have moved slowly toward breeding their own stock. The Penang farm depends on tourism to pay many of its expenses. The Sandakan farm is operated in conjunction with a duck and pig farm that supplies it with offal. Its stock consists of saltwater crocodiles. Until at least 1980, it had very little production from captive animals, but the owner is hoping to broaden his stock from them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sarawak (East Malaysia) also used to have several rearing farms. The present status of these operations is unknown.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thailand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Samutprakan Crocodile Farm was started in 1950 with 20 wild crocodiles and an investment of US$500. Today it is reported to be the world's largest crocodile farm, with about 30,000 individuals. About 3,700 of these animals, placed in eight separate breeding ponds, are used for breeding stock, and there are plans for a population of 100,000 by 1987. The Samutprakan farm opened to the public 12 years ago and now receives about one million visitors annually.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most of the farm's crocodiles are from the two species native to Thailand, the saltwater crocodile and the Siamese freshwater crocodile (Crocodylus siamensis). It also has hybrids of the two, as well as the indigenous false gavial (Tomistoma schlegelii) and five exotic species: South American caiman (Caiman crocodilus), New Guinea freshwater crocodile (Crocodylus novaeguineae), Chinese alligator (Alligator sinensis), broad-spouted caiman (Caiman latirostris), and dwarf caiman (Paleosuchus palpebrosus). The farm has succeeded in breeding South American caiman (Caiman crocodilus); the other species are approaching maturity and it is hoped they will breed in the near future.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The farm sells crocodile meat locally, mostly to restaurants as a delicacy (for US$5 per kg).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The commercial and biological success of the farm is largely due to favorable conditions at Samutprakan. The temperature and humidity are high year-round, and low costs of labor and building materials permit the physical plant to be profitably established and maintained. The main cost is for food; approximately 4,000-5,000 kg of by-catch fish are needed daily at a cost of US 20 cents per kg. If the supply of fish is inadequate, the diet is supplemented with chicken wings, legs, and necks from a slaughterhouse.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Burma</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Rangoon there are some crocodile-holding pens operated by hide buyers. It is not clear whether breeding or farming of crocodiles occurs in them or whether the operation simply acts as a clearing center for wild hides. The government has expressed interest in establishing farms in the mangrove areas near the mouth of the Irrawaddy River. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">India</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1974 an FAO report on India's crocodiles noted that the Indian gavial (Gavialis gangeticus) was on the verge of extinction, the saltwater crocodile was extremely rare, and the Indian mugger (Crocodylus palustris was a depleted, although not threatened, species).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The government, with United Nations assistance, then initiated a project for the conservation and management of all three species. This program aimed to protect and restock habitats. Animals for restocking were obtained by collecting eggs laid in the wild, incubating them under controlled conditions, raising the resulting hatchlings, and returning juveniles to specially selected sanctuaries when they reached about 1.2 m in length,at which time they are free from predation other than by man.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The project has resulted in the comeback of the gavial. By March 1979, 200 gavials had been restored to the wild. The wild population now exceeds 1,000 animals of more than 2 m length, and the number is expected to increase rapidly through natural reproduction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The project has also carried out extensive research on crocodiles, and since its founding in 1978 the Central Crocodile Breeding and Management Training Institute, located in Hyderabad, has trained many wildlife officers in crocodile protection. Crocodile-rearing facilities are also located near Madras, Lucknow, and Cuttack. All have had success in raising the animals and restocking their habitats.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Indian crocodile project has been a notable success and it coincided with (and perhaps helped create) a wave of local interest in India's wildlife and its conservation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Israel</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A farm stocked with American alligators (Alligator mississippiensis) was established at a popular hotwater spring resort area, using animals supplied by a Florida farm. The Israeli program will earn money from tourist admissions and from future production of hides. The first successful hatching of captive-bred alligators was reported in 1982.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kenya</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Near Mombasa a farm for the Nile crocodile (Crocodylus niloticus) has been set up to produce hides from captive-bred stock. The farm is a demonstration project of a large cement factory that is attempting to return its limestone-mined areas to productive agriculture. Some sophisticated experiments are under way on crocodile nutrition, with food for the animals produced in an intensive aquaculture project using tilapia. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zambia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zambia is planning a series of farms patterned after those in Zimbabwe (described below).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zimbabwe</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zimbabwe has made great strides in captive breeding. In 1979, 87 captive females at two farms produced 1,906 eggs, and a third farm has set aside 30 captive females for breeding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Four of the country's five crocodile farms are on the shores of Lake Kariba and the other is at Victoria Falls. The government allows each farm an annual allotment of wild eggs (averaging 2,000 to 2,500 eggs) for stocking its rearing programs. Each farm is also striving to become self sufficient in egg production by developing successful breeding programs. The government is considering reducing each farm's allotment by the number of eggs produced annually in the farm so that each will eventually become independent of the wild populations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zimbabwe farmers operate on a system that obliges them to return a small percentage of live animals to the wild if the government requires it. At present, this requirement is being waived because the wild population is increasing on its own.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zimbabwe has built its crocodile conservation program on a broad base. Crocodiles are protected throughout the country, as game animals in the country at large and as totally protected species in parks and sanctuaries. Populations have increased dramatically, from endangered status in the l950s to over 50,000 individuals today. In the 1950s a survey of the Zambesi River and Lake Kariba revealed no crocodiles; today thousands are seen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zimbabwe's Department of National Parks and Wildlife is striving to ensure that its legitimate international trade in farm-raised hides does not provide illegal operators in other countries with the opportunity to sell poached hides (for example, forging papers that claim their hides originated on legitimate Zimbabwe farms). To make poaching difficult, Zimbabwe, taking a clue from the state of Louisiana, plans to use serially numbered nonremovable plastic tags to mark legitimate hides. Numbers of the tags will be noted on export permits. In addition, every export permit will be validated by the government with an engraved security stamp that is difficult to forge and that shows ink damage if any erasures or modifications are attempted. The use of such stamps is recommended by CITES, and Zimbabwe is the first nation to put them into use.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">South Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">South Africa has four crocodile farms, and another five are planned or under construction. Apart from the Natal Parks Board Crocodile Research Station at St. Lucia Estuary, which breeds Nile crocodiles for restocking and conservation purposes, all farms are for tourism and hide production. So far only one farm, outside Pretoria, is reported to produce many offspring. Only the provinces of Transvaal and Natal have wild crocodiles, and neither allows eggs, young, or adults to be collected for stocking farms. Both provinces, however, permit the killing of nuisance crocodiles on private land. Transvaal will allow one or two nuisance crocodiles to be taken captive by farmers, but it refuses permission for removing larger numbers of nuisance animals,presumably for fear that this would generate a flood of spurious nuisance complaints. Natal will not permit the removal of any wild crocodiles to farms, nor will it supply offspring from the St. Lucia station to farmers. This makes the Pretoria farm the only source of crocodiles in South Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Following the example of Zimbabwe, the South African farmers (present and potential) formed a crocodile farming association in 1982.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Botswana</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Several farms patterned after those in Zimbabwe are planned for the Okavango area. Petitions for approval are currently before the Botswana government.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chad</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the late 1960s French businessmen established a farm for Nile crocodiles near Lake Chad. It collapsed after only a few years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ivory Coast</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The government of Ivory Coast has obtained assistance from Zimbabwe to establish a conservation program for its three native crocodiles: the Nile crocodile, African slender-spouted crocodile (Crocodylus cataphractus), and Congo dwarf crocodile (Osteolaemus tetraspis). Recommendations were made for conserving the wild populations as well as for establishing farms. Field studies are under way.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Europe</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Italy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A commercial farm for the South American caiman (Caiman crocodilus) was established in southern Italy in the late 1970s. Stock was obtained from Colombia. The animals, numbering in the thousands, arrived in Rome in winter and were transported south to the farm in an open truck. Most died from cold. Later shipments fared no better, and the few animals that survived died from poor husbandry. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Americas</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">United States</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are between 15 and 20 successful alligator farms in the United States. Most are located in Florida and Louisiana, and there is at least one in California. All earn a portion of their money from tourist admissions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cuba</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the 1960s the Cuban government established at least two farms for crocodiles. One is located in the Zapata Peninsula National Park; the other is near Cienfuegos. The purpose of these farms is to breed crocodiles whose wetland habitat has been converted to sugar cane fields. Eventually, the farms will also produce a cash crop of hides.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unfortunately, what started out as an admirable effort created several conservation problems because the farm managers did not realize there were two crocodiles in Cuba ,the American crocodile (Crocodylus acutus) in brackish waters, and the Cuban crocodile (Crocodylus rhombifer) in freshwater areas. The two were mixed in the farms and hybridization resulted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mexico</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Mexican government has established several farms for Morelet's crocodile (Crocodylus moreletii) in Chiapas and Veracruz. The purpose is to breed the species in captivity to relieve hunting pressure on the wild population and prevent its extinction. Original funding was provided by the World Wildlife Fund. At least one of these farms still exists. Breeding has been achieved, but there have been problems of survival in hatchlings. The cause of the deaths has not been discovered.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In recent years several businessmen in Mexico have expressed interest in starting one or more crocodile farms, but none has yet materialized.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">El Salvador</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the late 1960s, the Louisiana Game and Fisheries Commission supplied specimens of the American alligator to a cattle rancher in El Salvador for the purpose of establishing an experimental farm.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Louisiana was interested in studying growth rates of American alligators in a tropical nation where the animals did not have to undergo winter hibernation. The husbandry on the farm followed methods worked out in Louisiana. The animals grew fast and presumably have started breeding. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Venezuela</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A captive breeding program for the Orinoco crocodile (Crocodylus intermedius) was established in Venezuela in the late 1970s on the ranch of Tomas Blohm. The operation is not commercial; its purpose is to prevent extinction of the species. The offspring may be used for restocking wild habitats in the future.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under Venezuelan law there can be no commercial export of any crocodilians. In addition, the Orinoco crocodile and the various caimans are protected. However, the reptiles are everywhere killed as vermin.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Peru</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Peru has proposed harvesting certain wild populations of caimans (Caiman crocodilus) to supply animals to a ranching operation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BraziI</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The government of Brazil is interested in establishing farms for several species of caiman, including the yacare (Caiman crocodilusyacare). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other Latin American Nations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During the past two years, other Central and South American nations that have indicated their intention to set up farms for crocodiles or caimans are Bolivia, Colombia, Costa Rica, Ecuador, French Guiana, Guatemala, Guyana, Haiti, Honduras, Nicaragua, Panama, Paraguay, Suriname, and Uruguay. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendix B: Practical Crocodile Farming</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This appendix is adapted from a paper by A. Pooley that detailed the lessons learned from farming crocodiles to restock depleted habitats in Natal, South Africa. The information is presented here not as a blueprint for setting up a farm, but to show prospective farmers some of the points that they must first consider before attempting to rear crocodiles.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Farm Location</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Reliable supplies of good water and suitable food are the most important considerations for establishment of a crocodile farm; the area selected must have both. Village farms also need to be close enough to wild crocodile populations for the animals to be obtained easily. Larger farms can be located farther from the source.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For small farms, a natural supply of food should also be readily available in the wild. Areas that have a fishing industry are ideal locations. For large farms, sites near slaughterhouses or fish-processing facilities are ideal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other considerations also include the volume of water available throughout the year, the distance over which water must be piped to the ponds, and pumping costs. The quality of the water should be established, with samples tested for salinity and acidity and, where the supply comes from mineral springs, analyzed for harmful chemicals. Chlorinated water must be tested regularly to ensure that the chlorine content is not too high, and the nature of any factory effluents present should be determined. It is important to establish whether fish, frogs, crabs, mollusks, or aquatic insects survive in the water intended for use.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bacterial analysis is advisable where the water is drawn from a river that drains an area densely populated by humans and livestock. If the water is found to be contaminated, the stagnant pond rearing pen system should not be used, particularly when Salmonella spp. are present in high concentrations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A filter system has advantages if water is pumped straight from a river carrying a heavy silt load. Apart from enabling farmers to see the animals in the pools, filtered water makes the pools and pipes easier to clean. Filtration can be achieved by drawing water from a deep pit close to the river so that the water collected seeps through sand or mud.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A reservoir or a series of supply tanks is useful as an additional method of filtering water. In the event that pumping equipment fails, such a reserve supply may prove vital to the health and survival of the crocodiles.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The ponds should receive as much sun as possible, particularly during the winter months. A series of winter air temperature recordings would be useful in choosing the site of rearing pens, since valley temperatures are often several degrees lower than the temperatures some 50 to 100 m uphill. Preference should be given to the warmer locations, taking into account the direction of local winds and heavy rains.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Soil types are the next consideration. If soils are sandy and porous, earth ponds are impractical and a concrete lining is required to retain water.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Drainage of the ponds must be carefully considered. Drainage is far easier if the ponds are built on a slight rise. Water from the ponds must not be allowed to stagnate nearby; the drainage system must be efficient. It is recommended that pens be spaced at least 8 m apart and that their drainpipes lead underground at least 10 m before emptying.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pen Construction</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pens with rounded corners are the most successful. Crocodiles frequently choose to lie together in a pile. Square corners allow them to pile up against the angle, smothering those on the bottom and sometimes allowing animals to climb over the fence. With rounded corners, the pile cannot grow very high before the crocodiles slide sideways and the heap collapses.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Experiments in South Africa indicate that natural pools containing rooted vegetation are less prone to become sources of disease than are concrete pools. The surface of the concrete seems to become impregnated with liquid and debris from food and to become a breeding ground for bacteria. For hatchlings and very small juvenile crocodiles, concrete has an added disadvantage; its rough surface can abrade the belly skin when the animals slide in and out of the water, which can foster infection. In 5 or 10 years, even smooth concrete will erode sufficiently to become a problem.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Researchers elsewhere, however, report better results with concrete lined ponds, which they find easier to clean. Concrete pools are useful for summer because they can be scrubbed clean and because the volume of water used is small. Normally they need only be emptied, cleaned, and refilled every third day, and there is no wastage through seepage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The pools are best built as channels. This provides more bank for basking and enables the pools to accommodate more crocodiles. Because the larger males become belligerent only when they can see each other, floating logs, patches of grass, or channel corners are visual barriers that reduce interactions. The channel system also gives more water edge, and this appears to satisfy the territorial instinct.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodiles are famous for basking in the sun, but they die surprisingly easily of heat prostration. At least one-third of the land area of a farm pen should be shaded with vegetation. The amount of space around each pool is calculated to allow ample basking room for each animal, and an area of shade must likewise be provided.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On land, crocodiles often seek contact with each other (thigmotaxis) and frequently lie piled on top of each other, but this should be a matter of choice rather than of overcrowding. There should be few enough animals in the enclosure to allow every crocodile to get out of the water if it chooses.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ideally, only half the available number of pools should be occupied at a time, so that they can be used in rotation. In this system, the animals can be moved to fresh pools every two months (or as necessary), leaving the "used" pools to be drained and dried out to bake in the sun. After two months, the pools will then be clean and ready for use again.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An important requirement is that the pools be at least 60 cm in depth; otherwise, the water becomes too hot in summer. The pool floor should be sloped towards the drain outlet to facilitate cleaning and flushing away uneaten food. Also, the outlet pipe should be 10 cm in diameter, with a stopcock outside the enclosure, so that the pool can be cleaned and emptied efficiently. It is essential to place a screen in the drainpipe to prevent small crocodiles from escaping or being sucked out of the pool during cleaning. After some time, stagnant ponds may become difficult to clean because of the heavy growth of algae on their sides. Hard-bristle scrubbing brushes are needed to dislodge this growth. Small amounts of copper sulfate in the water will help control algae if used regularly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The entire pond and surrounding apron must be smoothly plastered to facilitate cleaning. It helps to have a water source close to each pool from which a hose pipe can be led to pressure spray and clean the pool and its apron.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An important part of the design is a partly submerged, gently sloping ledge, some 45 cm in width, around the perimeter of the pool. This provides a shallow resting zone for the crocodiles and gives them easy access to the water. The crocodiles rest there when feeding, and the ledge prevents them from scraping their bellies and damaging their claws when they enter or leave the pool.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For small crocodiles it is advisable to roof over the entire pen with wire netting or cries-crossed strands of wire. This protects against predators. Further, young crocodiles can climb vertical wire netting with ease and will escape unless the enclosure is either roofed or has side walls that slope inwards. A skirting board (planking, sheet iron, tin, or plastic sheeting) placed against the wire netting can also prevent this. If wire netting is used for the sides of the pens it should have mesh no larger than 1 cm so that hatchlings will not injure themselves by trying to climb through. While these pools are being cleaned, care must be exercised to prevent crocodiles from falling into the empty pool.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water can be passed continuously through the pools. The advantage of this is that during hot summer weather, when crocodiles are feeding at their maximum rate, small uneaten food particles, feces, and urine are carried away. Constant dilution of the pond's water also ensures a low bacteria level. However, the pool must be drained and scrubbed clean at least weekly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Earthen pools are easy and cheap to build and are a "natural" habitat where vegetation can be planted and small live fish introduced; insects, frogs, and other creatures attracted to the dams will be an important addition to the diet and health of the crocodiles. Earthen pools are ideal in climates where low winter temperatures are likely to cause respiratory illness in the young animals. During cold weather the crocodiles burrow into the mudbanks and survive nights of heavy frost.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of the animal's burrowing capabilities, it is important to provide a strip of land 4 m wide between the pool's edge and the boundary fence. Otherwise, crocodiles may tunnel beyond the fence line. Fences must be buried at least 1 m deep to intercept the burrows and to prevent predators from burrowing in. Burrowing, however, can be hazardous, because the burrows can collapse and suffocate the animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In areas where the soil is porous or sandy, the floor of an earth dam can be sealed with concrete or plastic irrigation sheets. A layer of earth can be used to conceal this artificial floor. The disadvantages of earth pools are that, because of seepage, they require more water than concrete ones and that they require more maintenance because they cannot be efficiently cleaned. Even if the pools are provided with constantly circulating water, they eventually become fouled, particularly during hot weather.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Removing crocodiles from an earth pond can prove difficult, since most will take refuge in their burrows.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Capturing Crocodiles</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodiles are located at night, usually from a boat, by shining a light along the edges of rivers and lagoons. Because of a reflective tapetum, the eyes of crocodiles glow reddish or orange and are visible for a hundred meters or more. If the population has not become exposed to hunting and become wary of people, the animals will not submerge when the light strikes them. Dazzled by the beam, they tolerate a stealthy approach, and small animals can simply be grabbed by hand or scooped up in a net. They can then be transported in sacks to the rearing pens. Larger animals may be noosed or baited into cylindrical screen traps at places they frequent along the water's edge.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Managing a Crocodile Farm</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is a problem to sort the young crocodiles. From one clutch of eggs, some individuals will be aggressive and others may be shy or extremely timid; growth may vary from rapid to very slow, with a few individuals classed as runts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Larger animals can be so dominant that smaller individuals will not even attempt to feed. If sorting is not done, the smaller, less-aggressive individuals do not get a fair share of the food; they grow slowly and get bitten and harassed by the larger animals. At feeding time, some will flee to the opposite side of the pen and stop feeding altogether. Keeping the young animals sorted into classes of the same size avoids many of these problems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nutrition and Feeding</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite the crocodilian's reputation as a man-eater, small wild crocodiles live mainly on invertebrates and larger ones live mainly on fish. Papua New Guinea's farmers feed a varied diet of locally caught fish, crab, shrimp, frogs, snails, grasshoppers, beetles, and slaughterhouse waste. Whole animals minced up should be used, if necessary, because crocodiles require a diet of bone, intestine, scales, and other tissues to provide calcium and minerals. Bones in chopped fish must be minced thoroughly for hatchlings or very young crocodiles, or they should be fed very small fish supplemented by tadpoles or insects. One village in Papua New Guinea has shown remarkable success in rearing hatchlings on a diet of chopped fish and live freshwater shrimp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fish is an excellent food for the bulk feeding of a large captive population. Whole fish chopped into pieces, including the livers and hearts, forms a balanced diet that may be supplemented by meat, if available, to make up bulk. Small whole fish are particularly suitable; the crocodiles derive calcium from the bones and scales, plus roughage to facilitate digestion, while the flesh, liver, and heart are rich in nutrients and protein The main difficulty usually lies in harvesting enough fish to meet the crocodiles' demands.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Any method of supplementing the diet with live creatures is recommended. For instance, a light can be left burning in each pen about 15 cm above the water for attracting insects. Various types of insect traps may also be used.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodiles also can be fed on a variety of wastes such as offal or noncommercial fish. Ideally, a large-scale farm should be located near a poultry slaughterhouse. (Cattle offal is also satisfactory, but it is not nutritionally adequate as a sole ration for crocodiles.) Even crocodile offal itself can be fed back to crocodiles. However, the use of offal will necessitate dietary supplements to assure sufficient phosphorus and calcium. These minerals are generally provided by feeding bones to the crocodiles.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crocodiles usually consume their food in the water, but they can also be fed on land. They will eat daily, but are able to remain active for weeks without food. If they are fed in the water of a farm pen, the water will become polluted unless there is considerable flow to carry away the debris. In extreme cases, the pools become septic. To ensure the health of the growing animals, constantly flowing water is far superior to standing water. (The Samutprakan Crocodile Farm in Thailand feeds some of its animals in water, but the small feeding pools are separate from the large regular breeding pools and at a lower level to prevent their overflowing into the breeding pools.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is important to feed pieces of food small enough to be swallowed without difficulty. Large fish should be cut into elongated rather than square pieces, since the bones can cause damage during swallowing. Similarly, whole live fish should not be so large that the dorsal fin may cause damage to the reptile's throat and gullet.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is important to know the amount of food that each group of animals will consume at each meal. By feeding at the same time each day, it is easy to calculate how much is required. Moreover, the crocodiles become accustomed to a routine and the food is consumed while it is still fresh. In the hot summer months the animals will devour a full meal every 24 hours, but the feeding rate slackens with the onset of colder weather. It is then wise to start reducing frequency and quantities until food is required only every second or third day, depending on the climate. Generally, young crocodiles will refuse food when the air or water temperature falls below 60°F (15.6°C). Even in midsummer sudden cold spells may occur; at such times, it is usually futile to feed the animals or try to coax them to eat until the weather warms up again. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During hot weather conditions it is preferable to feed late in the afternoon or evenings, mainly to avoid placing the food on a hot cement surface. The food should be spread out around the edge of the pool under the shaded area so that the animals do not have to climb over one another to reach it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In cemented pens the area where the food is laid out should be cleaned and scrubbed two hours after feeding time and any uneaten food removed from the water with a hand net. In earthen pools, the food should be placed at a different spot along the bank at each feeding. A useful aid to hygiene is keeping a few predacious fish, such as barbel (Clarias spp.), in each pool to clean up scraps of uneaten food.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Population Density</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Twenty-five crocodiles are considered the maximum manageable number per unit; staying within this limit reduces competition for food, bullying and fighting, and the number of injuries. A low stocking rate also results in a more even average growth rate. Most important is the fact that the overall health of the crocodiles is better than in a more crowded pen; disease problems are fewer and the symptoms easier to detect in a small group. If the units are spaced 8 m apart, there is also less danger of infectious disease spreading to other pens. The cleaning of pens is facilitated, and the disturbance caused by capturing crocodiles to be moved to other units is minimized. Housing 500 crocodiles in groups of 25 will require 20 separate pens, and an additional two pens should be provided to allow for intensive care of sick, injured, and weaker animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During the first year, when animals are graded frequently, they will often be moved from one pen to another. Recording the number of animals housed in each pen will make it possible to keep track of numbers and movements.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Breeding</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Reproduction is impossible when crocodiles are kept in large groups composed of different species and sizes and in more or less unnatural enclosures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Healthy, sexually mature pairs of crocodiles are usually not enough to start a breeding program. Genetic diversity to maintain a long-term breeding group must be considered, and certain environmental factors are vital for success. The distinct size and age classes of a free-living population must also be taken into consideration. Optimal sex ratios for breeding in enclosed compounds must be determined and adhered to. If a breeding unit is not based on regard for the animals' basic needs for space, nesting sites, and retreats, the larger specimens will disturb, injure, and often kill smaller specimens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Diseases and Parasites</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Disease symptoms may be easily overlooked if the observer is not familiar with the behavior of crocodiles under a variety of conditions. It is essential to know how they normally walk, swim, sleep, feed, and bask in relation to the time of day, the air and water temperatures, and the amount of sunlight or rain, by day, by night, and at different seasons of the year. Caretakers should notice the appearance of feces from healthy animals to be able to detect evidence of diarrhea, and to identify misaligned teeth and weakened limbs to detect nutritional deficiencies. Eggs are critically dependent on specific temperature and moisture requirements if the embryos are to develop normally.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is often difficult to determine the cause of illness or death, and even if the ailment has been correctly diagnosed, it is not easy to capture and administer drugs to large numbers of sick animals. Some animals may be injured during the handling process. Emphasis on preventing disease, rather than curing it, is the best way of ensuring a healthy crop.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Almost inevitably, the water in the pools will harbor concentrations of bacteria such as salmonella. If strict hygiene is observed, however, the bacterial level will not be harmful.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is recommended that whenever possible animals found newly dead should be dissected and vital organs such as the brain, heart, lung, liver, spleen, kidney, and stomach removed for veterinary research. Blood slides should also be taken and feces samples collected. The various specimens must be carefully labeled, frozen as quickly as possible, and packed on ice in a vacuum flask for immediate dispatch to the nearest veterinary research institute or pathologist. Alternatively, dying animals may be sent live for research purposes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is helpful for the handler to become thoroughly acquainted with the animal's internal anatomy, in order to distinguish between healthy and diseased organs. This knowledge, coupled with the symptoms noted before the animal dies, and the veterinary report, will be useful in future diagnosis and treatment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One problem for the crocodile farmer is a roundworm (nematode) parasite that burrows into the belly skin. When the burrow collapses it produces an undulating track across the belly and throat scales that ruins the hide. These parasites have been found in crocodiles from Latin America, Africa, Australia, Papua New Guinea, and Asia. They seem more prevalent in some areas and some farms than in others. The organism has been identified, but no treatment or control has been discovered. It is, however, believed that damp, muddy conditions foster the nematode, and that to reduce it pens should have areas of dry land where the animals can bask.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Killing, Skinning, and Tanning</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some farmers kill the crocodiles themselves, but many rear the animals and then sell them to a larger concern that is better equipped to deal with the skins. Killing is done most quickly and humanely by catching the crocodile with a noose and severing the spinal cord just behind the skull.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many hides are ruined or severely damaged during skinning. Even a single hole resulting from a slip of the skinning knife may reduce a hide's value by 25 percent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">After skinning, the hides are normally coated with about 0.5 cm of coarse salt and rolled up. Within 48 hours they are unrolled and resalted. If the hide is not sufficiently salted, it may become infected with bacteria or fungi that cause the epidermis of the scales to decay or slip. Although this layer is removed during tannage, scale slip is a symptom of rot and usually causes damage to the finished hide product. If the decay is intense, the salted hides may become reddish or brown in color. This is called "red heat."</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although salt remains the universally used preservative for raw hides, the reptile leather industry has developed chemical fixatives that are used in addition to salt for preserving hides for tanning. Most of these pretannage fixatives are liquid and require soaking the hide in a vat, which may not be feasible in remote areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A pretanned hide is called a crust. It is green-gray (chrome tanned) or tan (vegetable tanned) and is stiff. The hide is dyed and glazed to its final finish. To increase the workability and to remove as many of the osteoderms as possible (if they are present), the underside of the hide is shaved to an even thickness. The shaving is done by craftsmen. If they shaved too much, the hide will be thin and weak, especially over the suture between the scales.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendix C: Selected Readings</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">General information on the management and status of crocodiles can be found in the following:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">IUCN/Crocodile Specialist Group Newsletter. Available from the editors, Peter Brazaitis and Myrna Watanabe, c/o New York Zoological Park, Bronx Zoo, The Bronx, New York 10460, USA.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A Field Guide of Captive Rearing and Management of Crocodiles in India is available from Mr. R. K. Rao, Director, Central Crocodile Breeding and Management Training Institute (Government of India), Hyderabad, Andhra Pradesh, India.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Blake, D. K. 1974. The rearing of crocodiles for commercial and conservation purposes in Rhodesia. The Rhodesia Science News 8(10):315-324.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Blake, D. K., and J. P. Loveridge. 1975. The role of commercial crocodile farming in crocodile conservation. Biological Conservation 8(4): 261-272.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bolton, M. 1981. Crocodile Husbandry in Papua New Guinea. Field Document 4. FO: DP/ PNG/74/029. Food and Agriculture Organization of the United Nations, Rome, Italy. 103 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bolton, M., and M. Laufa. 1982. The crocodile project in Papua New Guinea. Biological Conservation 22:169-179.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Brazaitis, P. (In press) Problems in the Identification of Commercial Crocodilian Hides and the Effect on Law Enforcement. Proceedings of the IUCN Crocodile Specialist Group meeting in Zimbabwe September-October, 1982. International Union for the Conservation of Nature and Natural Resources, Gland, Switzerland.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Brazaitis, P. 1973. The identification of living crocodiles. Zoologica 58(3-4):59-101.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cott, H. B. 1954. Ecology and economic status of the crocodile in Uganda. Record of the Symposium on African Hydrobiology and Inland Fisheries, Committee on Technical Cooperation for Africa South of the Sahara 6:119-122.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cott, H. B. 1961. Scientific results of an inquiry into the ecology and economic status of the Nile crocodile (Crocodylus niloticus) in Uganda and Northern Rhodesia. Transactions of the Zoological Society of London 29(4):211-337.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Downes, M. C. 1978. An explanation of the National Policy for the Crocodile Programme. Wildlife Division, Department of Lands, Surveys and Environment, Konedobu, Papua New Guinea.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fuchs, K., nd. Die Krokodilhaut Eduard Roether Verlag Darmstadt, Frankfurt, West Germany.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Graham, A., 1981. Mapping the pattern of crocodile nesting activity in Papua New Guinea. Field Document No. 3, FO: DP/PNG/74/029. Food and Agriculture Organization of the United Nations, Rome, Italy. 50 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Joanen, T., and L. McNease. 1975. Notes on the Reproductive Biology and Captive Propagation of the American Alligator. Proceedings of the 29th Annual Conference of the Southeastern Association of Game and Fish Commissioners 29:407-415. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Joanen, T., and L. McNease. 1979. Culture of the American alligator. International Zoo Yearbook 19:61-66.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">King, F. W., and P. Brazaitis. 1971. Species identification of commercial crocodile skins. Zoologica 56(2): 15-72.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Loveridge, J. P. ed. 1982. The Zimbabwe Science News 16(9):196-219. Causeway, Zimbabwe. (Contains five articles on crocodilian research and conservation; from Zimbabwe, Australia the United States, and lndia.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Millichamp, N. J. ;980. Medical aspects of disease in reptile collections. In The Care and Breeding of Captive Reptiles, The British Herpetological Society, London, England.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Parker, F. 1981. New Crocodile Laws for Papua New Guinea. Division of Wildlife, Department of Lands and Environment, Konedobu, Papua New Guinea. 50 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pooley, A. C. 1969. Some observations on the rearing of crocodiles. Lammergeyer 10:45-59.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pooley, A. C. 1971. Crocodile rearing and restocking. Pp. 104-130 in Crocodiles, IUCN Publications New Series Supplementary Paper 32. International Union for Conservation of Nature and Natural Resources, 1110 Gland, Switzerland.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pooley, A. C. 1973. Conservation and Management of Crocodiles in Africa. Journal of the South African Wildlife Management Association 3(2):101-103.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pooley, A. C. 1977. A report on Crocodile Farming. Papua New Guinea. Wildlife leaflet No. 77/27. pp. 1-14.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pooley, A. C. 1981. Disappearing African Crocodiles. Oryx 16(1):38-40.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pooley, A. C. (In press). The status of crocodiles in Africa. Paper Presented at 5th Meeting IUCN Survival Service Commission's Crocodile Specialist Group. Gainesville Florida, USA. September 1980.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pooley, A. C., and C. Gans. 1976. The Nile crocodile. Scientific American 234(4): 114-124.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wallis, B. E. 1980. Market prospects for reptile leathers. Report number ITC/DIP/12, International Trade Commission, Geneva, Switzerland. 50 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wermuth, Von H., and K. Fuchs. 1978. Bestimmen von Krokodilen und ihrer Haute. Gustav Fischer Verlag, Stuttgart, New York.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Whitaker, R. 1982. Export prospects from commercial crocodile farms in Bangladesh. ITC/UNCTAD, Geneva, Switzerland. 47 pp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Whitaker, R., and M. Kemp. 1981. The crocodile industry in Papua New Guinea: Commercial Aspects. Field Document No. 2. FO:DP/PNC/74/029. Food and Agricultural Organization of the United Nations, Rome, Italy. 35 pp. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendix D: Research Contacts</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The following individuals are involved in crocodilian research. Most are biologists concerned with the conservation or natural history of the animals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Applied Ecology Crocodile Farm, Edward River, Queensland 4870</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Shelley Burgin, Total Environment Center, 18 Argyle Street, Sydney, New South Wales 2000</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Melvin Bolton, Woodbury Farm, Woodbury Road, M.S. 142, Via Yeppoon, Queensland 4703</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Max C. Downes, The Game Conservation Center, 24 Queens Parade, North Fitzroy, Victoria 3068</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Alistair Graham, P.O. Box41266, Darwin, Northern Territory 5792</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gordon Grigg, Zoology A08, University of Sydney, Sydney, New South Wales 2006</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John Lever, Koorana Crocodile Farm, M.S.F. 76, Rockhampton, Queensland 4702</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Harry Messel, Head, School of Physics, University of Sydney, Sydney, New South Wales 2006</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fred Parker, 717 Ross River Road, Kirwan, Queensland 4814</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Grahame Webb, School of Zoology, University of New South Wales, Kensington 2033</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bangladesh</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mohd. Reza Khan, Assistant Professor, Department of Zoology, University of Dacca, Dacca 2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Brazil</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">William Magnusson, Depto de Ecologia, Instituto Nacional de Pesquisas da Amazonia, Caixa Postal 478, 69000, Manaus, Amazonia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Burma</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ko Ko Gyi, Professor of Zoology, Rangoon Arts and Sciences University, Rangoon</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nyan Taw, Research Officer, People's Pearl and Fishery Corporation, Myakhwanyo Street, Thaketa, Rangoon </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">People's Republic of China</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Huang Chu-Chien, Institute of Zoology, Chinese Academy of Science, Beijing</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Swatow Prefecture Crocodile Farm, Shantou, Guang Dong Province</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Colombia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Federico Medem, Instituto Roberto Franco, Apartado Aereo 2261, Villavicencio (Meta)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Costa Rica</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gerado Budowski, Head, Natural Renewable Resources Programme, CATIE, Turrialba</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cuba</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Luis Varona, Norte 29, Nuevo Vedado, La Habana 6</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dominican Republic</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jose Alberto Ottenwalder, Museo Nacional de Historia Natural, Plaza de la Cultura, Santo Domingo</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Karlheinz Fuchs, Schillerstrasse 2, 6257 Hunfelder 2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guatemala</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jaime Tres 1., Centro de Estudias Conservacionistas, Universidad de San Carlos de Guatemala, Avenida de la Reforma 0-63, Zona IO, Guatemala</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">India</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">B. C. Choudhury and Lala A. K. Singh, Central Crocodile Breeding and Management Training Institute, 19-4-319, Lake Dale, Rajendranagar Road, Hyderabad 500 264, Andhra Pradesh</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Indian Board for Wildlife, c/o Department of Environment, Bikaner House, Shahjahan Road, New Delhi 110 011</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John Sale, UNDP/FAO Crocodile Breeding and Management Project, 19-4-319, Lake Dale, Rajendranagar Road Hyderabad 500 264, Andhra Pradesh</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">S. Shanmugunathan, Chief Wildlife Warden, Vivekananda Road, Coimbatore, Tamil Nadu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sudhakar Kar, Saltwater Crocodile Research and Conservation Unit, Danginal 754 220 Via Rejkanika, District Cuttack, Orissa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Romulus Whitaker, Madras Snake Park Trust, Guindy Deer Park, Madras, Tamil Nadu, 600 002</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Italy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">G. S. Child, Wildlife and Parks Management Of ficer FAO, Rome</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Japan</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wataru Kimura, Proprietor, Atagawa Tropical and Alligator Garden, Atagawa Higashi Zlu Town, Shizuoka Prefecture</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kenya</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">R.D. Haller , Bamburi Portland Cement Co. ,Ltd., P.O. Box 90202 ,Mombasa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Malaysia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Paul R. Wycherley, President, Malayan Nature Society, P.O. Box 150, Kuala Lumpur</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mexico</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Miguel Alvarez del Toro, Director, Instituto de Historia Natural, Departamento de Zoologia, Apartado Postal No. 6, Tuxtle Gutierrez, Chiapas, 29000</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Marco Antonio Lascano B., INIREB, Apdo. No 281, Merida</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nepal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tirtha Maskey, National Parks and Wildlife Conservation Office, Thapathali, P.O. Box 107, Kathmandu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">New Zealand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antoon de Vos, Box 34, Whitford, Auckland</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nicaragua</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Milton G. Camacho B., Instituto Nicaraguense de Recursos Naturales y del Ambiente (IRENA), Depto. de Fauna Silvestre, Kim 12 1/2 Carreterra Norte, Managua.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pakistan</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ashiq Ahmad, Wildlife Management Specialist, Pakistan Forest Institute, Peshawar</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Abdul Latif Rao, Conservator of Wildlife, National Council for Conservation of Wildlife, Ministry of Food and Agriculture, U.G. St. 51, Sector F 6/4, Islamabad</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Papua New Guinea</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Miro Laufa, Division of Wildlife, Department of Lands and Environment, P.O. Box 2585, Konedobu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Karol Kisokau, Director, Office of Environment and Conservation, Central Government Offices, Waigani</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Navu Kwapena, Division of Wildlife, Department of Lands and Environment, Konedobu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Graham Goudie, Crocodile Farm, Lae</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Martin Hollands, Monitoring Ecologist, National Crocodile Project, P.O. Box 2585 Konedobu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Peru</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pedro Vasques Ruesta, Departamento de Manejo Forestal, Universidad Nacional Agraria, Apdo. 456, La Molina</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Philippines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Angel C. Alcala, Division Research, Extension and Development, Silliman University, Dumaguete City, 6501, Negros</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">School of Agriculture, Silliman University, Dumaguete City, 6501, Negros.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">South Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. B. Anthony, The Natal Parks, Game and Fish Preservation Board, Box 662, Pietermaritzburg, Natal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antony Pooley, P.O. Box 42, St. Lucia Estuary, 3936 Zululand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Switzerland</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rene E. Honegger, Curator, Zurich Zoo, Zurichbergstrasse 221, 8044 Zurich</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thailand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">U. Srisomboon, Ministry of Agriculture, Department of Livestock Development, Bangkok Utai Youngprapakorn and Charoon Youngprapakorn, The Samutprakan Crocodile Farm and Zoo Co., Ltd., Talban Road, Samutprakan</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">United Kingdom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Angus d'A. Bellairs, Department of Anatomy, St. Mary's Hospital Medical School University of London, Paddington, London W2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. Robert Bustard, Isle of Man</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">United States</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John Behler, New York Zoological Society, 185th Street &amp; Southern Blvd., The Bronx, New York 10460</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Peter Brazaitis, New York Zoological Society, 185th Street &amp; Southern Blvd., The Bronx New York 10460</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gary Callis, Rt. I, Box 360, Clayton, New Mexico</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robert H. Chabreck, Louisiana State University, School of Forestry and Wildlife Management, Baton Rouge, Louisiana 70803</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Michael Davenport, Department of Herpetology, National Zoological Park, Smithsonian Institution, Washington, D.C. 20008</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Claire Hagen, Representative, Reptile Products Association, 120 Cabrini Blvd., New York, New York 10033</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fred Hauptfuhrer, Director of Planning and Development, World Wildlife Fund, Inc., 910 17th Street NW, Washington, D.C. 20006</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Howard Hunt, Atlanta Zoological Park, 518 Atlanta Ave. S.E., Atlanta, Georgia 30315</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ted Joanen, Rockefeller Wildlife Refuge, Route 1, Box 20-B, Grand Chenier, Louisiana 70643</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">F. Wayne King, Director, Florida State Museum, Gainesville, Florida 32611</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jeffrey W. Lang, Biology Department, University of North Dakota, University Station, Grand Forks, North Dakota 58202</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Charles J. Lankester, UNDP, I United Nations Plaza, New York, New York 10017</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">James H. Powell, 1110 Kokomo Street, Plainview, Texas 79072</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Charles A. Ross, Division of Reptiles and Amphibians, National Museum of Natural History, Smithsonian Institution, Washington, D.C. 20560</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Myrna Watanabe, 141 Columbia Heights, Brooklyn, New York 11201</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uruguay</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Federico Achaval, Departamento de Zoologia (Vertebrados), Universidad de la Republic Cerrito73, Montevideo</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Venezuela</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tomas Blohm, Apartado 69, Caracas 1010-A</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Andres Seijas Y., Servicio Nacional de Fauna Silvestre, MARNR, Apartado 184, Maracay</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zimbabwe</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D. K. Blake, Department of National Parks and Wildlife Management, P.O. Box 8365, Causeway, Harare</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John Loveridge, Zoology Department, University of Zimbabwe, P.O. Box MP 167, Mount Pleasant, Harare</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kevin van Jaarsveldt, Crocodile Farmers Association of Zimbabwe, P.O. Box 2569, Harare </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendix E: Biographical Sketches of Panel Members</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">EDWARD S. AYENSU, Director of the Office of Biological Secretary General Smithsonian Institution, Washington, D.C., is currently the Secretary General of the International Union of Biological Sciences. He received his B.A. in 1961 from Miami University in Ohio, M.Sc. from The George Washington University in 1963, and his Ph.D. in 1966 from the University of London. His research interests are in comparative anatomy and phylogeny of flowering plants, commercial timbers, histology of monocotyledons, economic botany, and tropical biology. An internationally recognized expert on tropical plants, he has published extensively in these areas and on topics relating to science, technology, and development, especially in developing countries. Dr. Ayensu was co-chairman of the Panel on Underexploited Tropical Plants of the Advisory Committee on Technology Innovation and chairs and serves as a member of many international bodies. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ARCHIE F. CARR, JR., is Graduate Research Professor in the Department of Zoology, University of Florida, Gainesville. As Technical Director of the Caribbean Conservation Corporation, he has directed a seasonal research program at the breeding ground of the green turtle at Tortuguero, Costa Rica, since 1952, with continuous grants from the National Science Foundation from 1955 to 1980, and has carried out investigations of marine turtle ecology and navigation in various parts of the world. The author of numerous papers, articles, and books, he received the Daniel Giraud Elliot Medal of the National Academy of Sciences for Handbook of Turtles and the John Burroughs Medal for The Windward Road. He is Research Associate of the American Museum of Natural History; Affiliate Curator of Natural Sciences, Florida State Museum; Chairman of the Marine Turtle Specialist Group of the Survival Service Commission, International Union for the Conservation of Nature; Honorary Consultant of the World Wildlife Fund; Fellow of the Linnean Society of London; Fellow of the American Fisheries Society; and a member of Phi Beta Kappa and Sigma Xi.In 1973 he was awarded a gold medal from the World Wildlife Fund for the application of scientific findings to the conservation of marine turtles. In 1975 he received the Edward W. Browning Award for achievement in biological conservation. In 1978 Dr. Carr was awarded the Gold Medal of the New York Zoological Society for contributions to natural science and conservation; in 1978 he became Officer of the Order of the Golden Ark (The Netherlands).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">F. WAYNE KING is the Director of the Florida State Museum, Gainesville. He received a B.S. in 1957 and an M.S. in 1961 from the University of Florida and a Ph.D. from 1966 from the University of Miami. His research interests are in wildlife conservation and habitat preservation, impact of international trade on wildlife populations, and ecology and behavior of reptile populations. He worked at the New York Zoological Society from 1967 to 1975. As an international wildlife consultant, Dr. King has received honors from the Dominican Republic, the American Association of Zoological Parks and Aquariums, and from H.R.H. Prince Bernhard of The Netherlands. He has served on committees advising the State Department and the International Union for Conservation of Nature and Natural Resources on policies regarding the trade of crocodile skins, turtle products, and other wildlife materials. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FRANCOIS MERGEN, Pinchot Professor of Forestry and Professor of Forest Genetics, Yale University, was Dean of the School of Forestry and Environmental Studies at Yale from 1965 to 1975. He received a B.A. from Luxembourg College and a B.Sc.F. from the University of New Brunswick in 1950, an M.F. in ecology in 1951, and a Ph.D. in forest genetics from Yale in 1954. He is especially knowledgeable about francophone Africa and was chairman of the Sahel program of the Board on Science and Technology for International Development and a member of the Advisory Committee on Technology Innovation. From 1960 to 1965 he was research collaborator at the Brookhaven National Laboratory. In 1966 he was the recipient of the Award for Outstanding Achievement in Biological Research from the Society of American Foresters and in 1975 was Distinguished Professor (Fulbright-Hays Program) in Yugoslavia. Before joining the Yale faculty, he served as project leader in forest genetics for the U.S. Forest Service in Florida. He has served as a consultant to FAO, various foreign governments, and private forestry companies, and he has traveled extensively in the tropical countries of Asia, Africa, and Latin America. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MICHAEL G. MORRIS is head of the Furzebrook Research Station of the Institute of Terrestrial Ecology (National Environment Research Council, U.K.). He received a B.A. in natural sciences (zoology) at the University of Cambridge of 1958, M.A. in 1962, and received his Ph.D. from London University in research on the integrated control of orchard pests. Dr. Morris worked at Monks Wood Experimental Station on the effects of grassland management on populations of invertebrates and developed a strong interest in community and applied ecology, particularly the conservation of insect populations. Recently he has become involved with problems of butterfly conservation and resource utilization. He is Secretary of the Joint Committee for the Conservation of British Insects, a Vice-Chairman of the Lepidoptera Specialist Group of lUCN'S Survival Commission, and Chairman of the Habitat and Species Protection Committee of SEL (Societal Europaea Lepidoptero-Logica). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUGH L. POPENOE is Professor of Soils, Agronomy, Botany, and Geography and Director of the Center for Tropical Agriculture and International Programs (Agriculture) at the University of Florida. He received his B.S. from the University of California at Davis in 1951 and his Ph.D. in soils from the University of Florida in 1960. His principal research interest has been in the area of tropical agriculture and land use. His early work on shifting cultivation is one of the major contributions to this system. He has traveled and worked in most of the countries in the tropical areas of Latin America, Asia, and Africa. He is past Chairman of the Board of Trustees of the Escuela Agricola Panamericana in Honduras, Visiting Lecturer on Tropical Public Health at the Harvard School of Public Health, and a Fellow of the American Association for the Advancement of Science, the American Society of Agronomy, the America Geographical Society, and the International Soils Science Society. He is Chairman of the Advisory Committee for Technology Innovation and a member of the Board on Science and Technology for International Development. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROBERT MICHAEL PYLE, a writer and consulting lepidopterist based in Gray's River, Washington, has served since 1979 as Co-Compiler of the lUCN Invertebrate Red Data Book. In this capacity he is consultant to the Conservation Monitoring Center in Cambridge, England. After receiving his B.S. and M.S. at the University of Washington, he took his Ph.D. through the School of Forestry and Environmental Studies at Yale University in 1976. He worked for the Government of Papua New Guinea on the conservation and utilization of insect resources and then with the Nature Conservancy as Northwest Land Steward. A former Fulbright Scholar to the United Kingdom, Dr. Pyle subsequently founded the Xerces Society for conservation of beneficial insects and their habitats. He has been chairman of IUCN'S Lepidoptera Specialist Group (Species Survival Commission) since 1976. His publications include the Audubon Society Field Guide to North American Butterflies. A comprehensive book on insect conservation in his next project.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SHELDON R. SEVERINGHAUS received his Ph.D. from Cornell University in 1977 in natural resources management. He has worked on various wildlife research projects in Asia since 1964 and is representative for the Asia Foundation in Taiwan. He has published articles on butterfly conservation and wildlife industries in Taiwan, where he has been studying the butterfly and wildlife farming projects. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NOEL D. VIETMEYER, staff officer for this study, is Professional Associate of the Board on Science and Technology for International Development. A New Zealander with a Ph.D. in organic chemistry from the University of California, Berkeley, he now works on innovations in science that are important for developing countries. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Advisory Committee on Technology Innovation</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUGH POPENOE, Director, International Programs in Agriculture, University of Florida, Gainesville, Florida, Chairman </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Members</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM BRADLEY, Consultant, New Hope, Pennsylvania</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HAROLD DREGNE, Director, International Center for Arid and Semi-Arid Land Studies, Texas Tech University, Lubbock, Texas (member through 1981) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ELMER L. GADEN, JR., Department of Chemical Engineering, University of Virginia, Charlottesville, Virginia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CARL N. HODGES, Director, Environmental Research Laboratory, Tucson, Arizona </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CYRUS MCKELL, Native Plants, Inc., Salt Lake City, Utah </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FRANCOIS MERGEN, Pinchot Professor of Forestry, School of Forestry and Environmental Studies, Yale University, New Haven, Connecticut (member through 1982) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DONALD L. PLUCKNETT, Consultative Group on International Agricultural Research, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THEODORE SUDIA, Deputy Science Advisor to the Secretary of Interior, Department of Interior, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Board on Science and Technology for International Development</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GEORGE BUGLIARELLO, President, Polytechnic Institute of New York, Brooklyn, New York, Chairman </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Members</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SAMUEL P. ASPER, Educational Commission for Foreign Medical Graduates, Philadelphia, Pennsylvania </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DAVID BELL, Department of Population Sciences, Harvard School of Public Health, Boston, Massachusetts </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LEONARD BERRY, Professor, Graduate School of Geography, Clark University, Worcester, Massachusetts </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ERNEST I. BRISKEY, Dean, School of Agriculture, Oregon State University, Corvallis, Oregon </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HARRISON S. BROWN, Director, Resources Systems Institute, East-West Center, Honolulu, Hawaii </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROBERT H. BURRIS, Department of Biochemistry, University of Wisconsin, Madison, Wisconsin </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CLAUDIA JEAN CARR, Associate Professor, Conservation and Resource Studies, University of California at Berkeley, Berkeley, California </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NATE FIELDS, Director, Developing Markets, Control Data Corporation, Minneapolis, Minnesota </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROLAND J. FUCHS, Chairman, Department of Geography, University of Hawaii at Manoa, Honolulu, Hawaii </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ELMER L. GADEN, JR., Department of Chemical Engineering, University of Virginia, Charlottesville, Virginia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN HOWARD GIBBONS, Director, U.S. Congress, Office of Technology Assessment, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">N. BRUCE HANNAY, Foreign Secretary, National Academy of Engineering, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM HUGHES, Director, Engineering Energy Laboratory, Oklahoma State University, Stillwater, Oklahoma </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM A. W. KREBS, Vice President, Arthur D. Little, Inc., Acorn Park, Cambridge, Massachusetts </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GEORGE I. LYTHCOTT, University of Wisconsin, School of Medicine, Madison, Wisconsin </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JANICE E. PERLMAN, Executive Director, Committee for a New New York, New York City Partnership, New York, New York </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUGH POPENOE, Director, International Programs in Agriculture, University of Florida, Gainesville, Florida </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FREDERICK C. ROBBINS, President, Institute of Medicine, National Academy of Sciences, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WALTER A. ROSENBLITH, Foreign Secretary, National Academy of Sciences, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FREDERICK SEITZ, President Emeritus, The Rockefeller University, New York, New York </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RALPH HERBERT SMUCKLER, Dean of International Studies and Programs, Michigan State University, East Lansing, Michigan </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GILBERT F. WHITE, Institute of Behavioral Science, University of Colorado, Boulder, Colorado </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BILL C. WRIGHT, Assistant Dean for International Programs, Oklahoma State University, Stillwater, Oklahoma </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN G. HURLEY, Director</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MICHAEL G. C. McDONALD DOW, Associate Director/Studies </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MICHAEL P. GREENE, Associate Director/Research Grants </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P></FONT>
+<!--
+</Section>
+</Section>
+-->
+</BODY>
+</HTML>
Index: /gsdl/stable/collect/demo/import/b20cre/metadata.xml
===================================================================
--- /gsdl/stable/collect/demo/import/b20cre/metadata.xml	(revision 20131)
+++ /gsdl/stable/collect/demo/import/b20cre/metadata.xml	(revision 20131)
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE DirectoryMetadata SYSTEM "http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd">
+<DirectoryMetadata>
+    <FileSet>
+        <FileName>.*</FileName>
+        <Description>
+            <Metadata name="dls.Title">Managing Tropical Animal Resources - Crocodiles as a Resource for the Tropics (b20cre)</Metadata>
+            <Metadata mode="accumulate" name="dls.Language">English</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Animal Husbandry and Animal Product Processing|Other animals (micro-livestock, little known animals, silkworms, reptiles, frogs, snails, game, etc.)</Metadata>
+            <Metadata mode="accumulate" name="dls.Organization">BOSTID</Metadata>
+        </Description>
+    </FileSet>
+</DirectoryMetadata>
Index: /gsdl/stable/collect/demo/import/b21wae/b21wae.htm
===================================================================
--- /gsdl/stable/collect/demo/import/b21wae/b21wae.htm	(revision 20131)
+++ /gsdl/stable/collect/demo/import/b21wae/b21wae.htm	(revision 20131)
@@ -0,0 +1,1888 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META NAME="Generator" CONTENT="Microsoft Word 97">
+<TITLE>&lt;&lt;TOC1&gt;&gt; The Water Buffalo: New Prospects For An Underutilized Animal (1984)</TITLE>
+</HEAD>
+<BODY>
+
+<B><FONT FACE="Arial" SIZE=2><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">The Water Buffalo: New Prospects For An Underutilized Animal (1984)</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Original editon 1981</P>
+<P ALIGN="JUSTIFY">Second printing 1984</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Report of an Ad Hoc Panel of the</P>
+<P ALIGN="JUSTIFY">Advisory Committee on Technology Innovation</P>
+<P ALIGN="JUSTIFY">Board on Science and Technology for International Development</P>
+<P ALIGN="JUSTIFY">Commission on International Relations</P>
+<P ALIGN="JUSTIFY">National Research Council</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Panel on Water Buffalo</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUGH POPENOE, Director, International Programs in Agriculture, University of  Florida, Gainesville, Florida, USA, Chairman </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">STEVE P. BENNETT, Bennett's Animal Clinic, Port of Spain, Trinidad, West Indies</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CHARAN CHANTALAKHANA, Dean, Department of Animal Science, Kasetsart  University, Bangkok, Thailand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DONALD D. CHARLES, Senior Lecturer, Meat Production, Department of Animal  Husbandry, University of Queensland, St. Lucia, Queensland, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. ROSS COCKRILL, Livestock Expert, Food and Agriculture Organization (retired),  Rome, Italy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WYLAND CRIPE, Department of Veterinary Science, University of Florida,  Gainesville, Florida, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">TONY J. CUNHA, Dean, School of Agriculture, California Polytechnic University,  Pomona, California, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. JOHN DE BOER, Winrock International Livestock Research and Training Center,  Morrilton, Arkansas, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MAARTEN DROST, Department of Veterinary Science, University of Florida,  Gainesville, Florida, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MOHAMED ALI EL-ASHRY, Department of Animal Production, Faculty of  Agriculture, Shoubra el Khiema, Cairo, Egypt </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ABELARDO FERRERD ., Former Director, Breeding Administration Centers,  Animal Sciences Division, Ministry of Agriculture, Caracas, Venezuela</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JEAN K. GARDNER, Former Chief, Logistics Division USAID/Philippines, Jackson,  Mississippi, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JAMES F. HENTGES, Department of Animal Science,University of Florida,  Gainesville, Florida, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JACK HOWARTH, School of Veterinary Medicine, University of California, Davis,  California, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NELS M. KONNERUP, Livestock Expert, Agency for International Development  (retired), Washington, D.C., USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. P LEONARDS, Water buffalo breeder, Lake Charles, Louisiana, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN K. LOOSLI, Department of Animal Science, University of Florida, Gainesville,  Florida, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOSEPH MADAMBA, Director, Asian Institute of Aquaculture, Iloilo, Philippines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CRISTO NASCIMENTO,Director, Brazilian Agriculture Research Corporation  (EMBRAPA), Agriculture Research Center for Humid Tropics (CPATU), Belem,  Para, Brazil</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DONALD L. PLUCKNETT, Consultative Group on International Agricultural  Research, The World Bank, Washington, D.C., USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM R. PRITCHARD, Dean, School of Veterinary Medicine, University of California, Davis, California, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. THOMAS REID, (deceased), Department of Animal Science, Cornell University, Ithaca, New York, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN H. SCHOTTLER, Animal Production Officer, Department of Primary Industries, Lae, Papua New Guinea </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DALBIR SINGH DEV, Dean, Animal Science Department, College of Agriculture, Agricultural University, Ludhiana, Punjab, India </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROBERT W. TOUCHBERRY, Dean, Department of Animal Science, University of Minnesota, St. Paul, Minnesota, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DONALD G. TULLOCH, Division of Wildlife Research, Commonwealth Scientific and Industrial Research Organization, Winnellie, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NOEL D. VIETMEYER, Board on Science and Technology for International Development, National Research Council, Washington, D.C., Staff Study Director </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MARY JANE ENGQUIST, Board on Science and Technology for International Development, National Research Council, Washington, D.C., Staff Associate </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Preface</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The water buffalo is an animal resource whose potential seems to have been barely recognized or examined outside of Asia. Throughout the world there are proponents and enthusiasts for the various breeds of cattle; the water buffalo, however, is not a cow and it has been neglected. Nevertheless, this symbol of Asian life and endurance has performed notably well in recent trials in such diverse places as the United States, Australia, Papua New Guinea, Trinidad, Costa Rica, Venezuela, and Brazil. In Italy and Egypt as well as Bulgaria and other Balkan states the water buffalo has been an important part of animal husbandry for centuries. In each of these places certain herds of water buffalo appear to have equaled or surpassed the local cattle in growth, environmental tolerance, health, and the production of meat and calves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although these are empirical observations lacking painstaking, detailed experimentation, they do seem to indicate that the water buffalo could become an important resource in tropical, subtropical, and warm temperate zones in developing and developed countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If this is the case, then it is clear that many countries should begin water buffalo research. Serious attention by scientists could help dispel the misperceptions and uncertainties surrounding the animal and encourage its true qualities to emerge.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report describes the water buffalo's attributes as perceived by several animal scientists. It is designed to present the apparent strengths of buffaloes compared with those of cattle, to introduce researchers and administrators to the animal's potential, and to identify priorities for buffalo research and testing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The panel that produced this report met at Gainesville, Florida, in July 1979. It was composed of leading water buffalo experts (particularly those from outside Asia who have directed the beginnings of water buffalo industries in their countries) and leading American animal scientists, many of whom are also familiar with the animal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report complements The Husbandry and Health of the Domestic Buffalo, edited by W. Ross Cockrill and published in 1974 by the Food and Agriculture Organization of the United Nations. Cockrill's 933-page book is a "bible" of water buffalo knowledge and provides details of breeds, world distribution, physiology, and an extensive bibliography.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The present report is an introduction to the water buffalo and its potential. It is written particularly for decision makers, as well as scholars or students, in the hope that it will stimulate their interest in the animal and thereby increase the appreciation of, and funding for, buffalo research. The report includes much empirical observation, largely from the panel members. Some of these observations may, in the long run, prove not to be universally applicable. Much benchmark information needs to be obtained.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Since its creation in 1971, the Advisory Committee on Technology Innovation (ACTI) has investigated innovative ways to use current technology and resources to help developing countries. Often this has meant taking a fresh look at some neglected and unappreciated plant or animal species. The committee assembles ad hoc panels of experts (usually incorporating both skeptics and proponents) to scrutinize the topics selected. The panel reports serve to draw attention to neglected, but promising, technologies and resources. (For a list of ACTI reports, see page 115.) ACTI reports are provided free to developing countries under funding by the Agency for International Development (AID).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Program costs for this study were provided by AID'S Office of Agriculture, Development Support Bureau, and staff support was provided by the Office of Science and Technology, Development Support Bureau.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The final draft of this report was edited and prepared for publication by F. R. Ruskin. Bibliographic editing was by Wendy D. White. Cover art was by Deborah Hanson.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">1 Introduction</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The domesticated water buffalo Bubalus bubalis numbers at least 130 million-one-ninth the number of cattle in the world. It is estimated that between 1961 and 1981 the world's buffalo population increased by 11 percent, keeping pace with the percentage increase in the cattle population.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although there are some pedigreed water buffaloes, most are nondescript animals that have not been selected or bred for productivity. There are two general types-the Swamp buffalo and the River buffalo.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Swamp buffaloes are slate gray, droopy necked, and ox-like, with massive backswept horns that make them favorite subjects for postcards and wooden statuettes in the Far East. They are found from the Philippines to as far west as India. They wallow in any water or mud puddle they can find or make. Primarily employed as a work animal, the Swamp buffalo is also used for meat but almost never for milk production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">River buffaloes are found farther west, from India to Egypt and Europe. Usually black or dark gray, with tightly coiled or drooping straight horns, they prefer to wallow in clean water. River buffaloes produce much more milk than Swamp buffaloes. They are the dairy type of water buffalo. In India, River buffaloes play an important role in the rural economy as suppliers of milk and draft power. River buffaloes make up about 35 percent of India's milk animals (other than goats) but produce almost 70 percent of its milk. Buffalo butterfat is the major source of cooking oil (ghee) in some Asian countries, including India and Pakistan.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although water buffaloes are bovine creatures that somewhat resemble cattle, they are genetically further removed from cattle than are the North American bison (improperly called buffalo) whose massive forequarters, shaggy mane, and small hindquarters are unlike those of cattle. While bison can be bred with cattle to produce hybrids,( This is not, however, very successful, the male progeny (at least of the F 1 generation) are sterile).there is no well-documented case of a mating between water buffalo and cattle that has produced progeny.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Parts of Asia and even Europe have depended on water buffaloes for centuries. Their crescent horns, coarse skin, wide muzzles, and low-carried heads are represented on seals struck 5,000 years ago in the Indus Valley, suggesting that the animal had already been domesticated in the area that is now India and Pakistan. Although buffaloes were in use in China 4,000 years ago, they are not mentioned in the literature or seen in the art of the ancient Egyptians, Romans, or Greeks, to whom they were apparently unknown. It was not until about 600 A.D. that Arabs brought the animal from Mesopotamia and began moving it westward into the Near East (modern Syria, Israel, and Turkey). Water buffaloes were later introduced to Europe by pilgrims and crusaders returning from the Holy Land in the Middle Ages. In Italy buffaloes adapted to the area of the Pontine Marshes southeast of Rome and the area south of Naples. They also became established in Hungary, Romania, Yugoslavia, Greece, and Bulgaria and have remained there ever since.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Villagers in medieval Egypt adopted the water buffalo, which has since become the most important domestic animal in modern Egypt. Indeed, during the last 50 years, their buffalo population has doubled to over 2 million head. The animals now supply Egypt with more meat-much of it in the form of tender "veal"-than any other domestic animal. They also provide milk, cooking oil, and cheese.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other areas have capitalized on the water buffalo's promise only in very recent times. For instance, small lots of the animals brought to Brazil (from Italy, India, and elsewhere) during the last 84 years have reproduced so well that they now total about 400,000 head and are still increasing, especially in the lower Amazon region. Buffalo meat and milk are now sold widely in Amazon towns and villages; the meat sells for the same price as beef. Nearby countries have also become familiar with the water buffalo. Trinidad imported several breeds from India between 1905 and 1908, while Venezuela, Colombia, and Guyana have been importing them in recent decades. During the 1970s Costa Rica, Ecuador, Cayenne, Panama, Suriname, and Guyana introduced small herds. By 1979 the buffalo in Venezuela numbered more than 7,000 head.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Across the Pacific, the new nation of Papua New Guinea has found the water buffalo well suited to its difficult environment. For 9 years the government has attempted to run cattle on the Sepik and Ramu Plains on Papua New Guinea's north coast, where the temperatures are high and the forage of poor quality. But the cattle remain thin and underweight. In the 1960s animal scientists began evaluating water buffaloes already living in Papua New Guinea and, encouraged by the results, introduced additional buffaloes from Australia. These have performed remarkably well, producing greater numbers of calves and much more meat than the cattle in the region. The buffaloes appear to maintain appetite despite the heat and humidity, whereas cattle do not. The government of Papua New Guinea has since imported more water buffaloes and today has thriving herds totaling almost 3,500 head. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The United States has been slow to recognize the water buffalo's potential, but the first herd (50 head) ever imported for commercial farming arrived in February 1978.(Air-freighted from the wilds of Guam, the U.S. island possession on the western Pacific, by panel member Tony Leonards. Prior to that time (in 1974), four head of water buffalo were imported to the Department of Animal science' university of Florida, for study. The only other water buffaloes in North America were a few animals in zoos.) The humble water buffalo, normally considered fit only for the steamy rice fields of Asia, is now proving itself on farm fields in Florida and Louisiana. As a result, interest in the animal is on the rise in U.S. university and farm circles.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From experience accumulated in Asia, Egypt, South America, Papua New Guinea, Australia, the United States, and elsewhere, animal scientists now perceive that many general impressions about the water buffalo are incorrect.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For example, it is widely believed that the water buffalo is mean and vicious. Encyclopedias reinforce this perception, and in the Western world it is the prevalent impression of the animal. The truth is, however, that unless wounded or severely stressed, the domesticated water buffalo is one of the gentlest of all farm animals. Despite an intimidating appearance, it is more like a household pet-sociable, gentle, and serene. In rural Asia the care of water buffaloes is often fumed over to small boys and girls aged about four to nine. The children spend their days with their family's gentle buffalo, riding it to water, washing it down, waiting while it rolls and wallows, and then riding it to some source of forage, perhaps a grassy field or thicket. It is not uncommon to see a buffalo patiently feeding, with a young friend stretched prone on its broad gray back, asleep.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Perhaps the notion about the viciousness of water buffaloes stems from confusing them with the mean-tempered African buffalo Syncerus caffer, actually a distant relative with which they will not interbreed and which is classified in a different genus.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ferocity is the most blatant misconception concerning the water buffalo, although other fallacies are widely reported as well.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One generally held belief is that water buffaloes can be raised only near water. Actually, buffaloes love to wallow, but they grow and reproduce normally without it, although in hot climates they must have shade available.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another belief is that the water buffalo is exclusively a tropical animal. River-type buffaloes, however, have been used to pull snow plows during Bulgarian winters. They are found in Italy (over 100,000 head), Albania, Yugoslavia, Greece, Turkey, the Georgia and Azerbaijan areas of the Soviet Union (almost 500,000 head) and other temperate-zone regions as well. They are also found in cold, mountainous areas of Pakistan, Afghanistan, and Nepal.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p04to05.png"></center><br>
+ World Distribution of Water Buffaloes</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yet another misconception is that the water buffalo is just a poor man's beast of burden. In addition to providing fine lean meat, buffaloes in fact provide rich milk. Mozzarella cheese, one of the most popular in Europe, comes from the buffaloes in Italy. Buffalo milk has a higher content of both butterfat and nonfat solids than cow's milk does. It therefore often brings higher prices than cow's milk. Throughout much of India it is in such demand that cow's milk is sometimes hard to sell.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many of the misconceptions generally held about buffaloes are based on little data and much prejudice. For instance, it is widely believed that water buffalo meat is tough and less desirable than beef. However, when the animals are raised for meat, buffalo steaks are lean, as tender as beef, and in appearance it is difficult to distinguish the two. In taste-preference tests at the University of Queensland, buffalo steaks were preferred over those from Angus and Hereford cattle. Tests conducted in Trinidad, Venezuela, the United States, and Malaysia produced similar results.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Australia has shipped water buffalo meat to Hong Kong, the United States, Germany, and Scandinavia. Buffalo meat is now available in stores in Australia's Northern Territory, where demand exceeds supply. It sells at competitive prices and is particularly sought for barbecues and the famous Australian meat pie. In the Philippines, two-thirds of the meat consumed in homes and restaurants is actually water buffalo, a fact that many Filipinos do not realize.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Compared with cattle,waterbuffaloes apparently have an efficient digestive system, one which extracts nourishment from forage so coarse and poor that cattle do not thrive on it. Thin cattle are commonly seen in Asia and northern Australia, for example, but it's rare to see a protruding rib on a buffalo, even though it uses the same source of feed.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Asia, the Middle East, and Europe, water buffaloes live on coarse vegetation on the marginal land traditionally left to the peasants. They help make human survival possible. An old Chinese woman in Taiwan once told panelist W. Ross Cockrill: "To my family the buffalo is more important than I am. When I die, they'll weep for me; but if our buffalo dies, they may starve."  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A better understanding of the water buffalo could be invaluable to many developing nations. In particular, improved production of water buffalo meat offers hope for helping feed India, the second most populous nation on earth. Although India for religious reasons forbids the slaughter of cows, it has no prohibitions regarding slaughter of water buffaloes or the consumption of buffalo meat.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most developing countries are in the tropics, and the water buffalo is inherently a tropical animal. It is comfortable in hot, humid environments. In the Amazon, for example, buffaloes are now common on the landscape and may even replace cattle completely.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tropical countries have more serious disease problems than temperate countries do. Although susceptible to most cattle diseases, the water buffalo seems to resist ticks and often appears to be more resistant to some of the most devastating plagues that make cattle raising risky, difficult, and sometimes impossible in the tropics. Several researchers report that when water buffaloes are allowed to wallow, their mud-coated skin seems to deter insect and tick ectoparasites and they consequently require greatly reduced treatment with insecticides. Although the buffalo fly (Siphona exigua) affects the animals, other pests such as the warble fly and the screwworm, for example, seldom affect healthy buffaloes. AIso, despite their inclination for living in swamps, Avers, and ponds, diseases of the feet such as foot rot and foot abscesses are rare.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another benefit to developing countries is the water buffalo's legendary strength. A large part of the total farm power available in South China, Thailand, Indonesia, the Philippines, the Indochina states, India, and Pakistan comes from this "living tractor." Dependable and docile, the animals pull plows, harrows, and carts with loads that weigh several tons. In the Amazon buffalo teams pull boats laden with cargo and tourists through shallows and swamps.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The petroleum crisis has forced many farmers to reconsider animal power even in some of the technically advanced countries. Buffaloes are not only extraordinarily strong, they can also work in deep mud that may bog down a tractor. Even up to their bellies they forge on, dragging both plow and driver through the mud. Although its average walking speed is only about 3 kilometers per hour, the buffalo, unlike its mechanical competition, doesn't need gasoline or spare parts and its working life is often 20 years or more.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Breeds</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As already noted, the major genetic divisions of the water buffalo are the Swamp buffalo of the eastern half of Asia, which has swept-back horns, and the River buffalo of the western half of Asia, which usually has curled horns. There is also the Mediterranean buffalo, which is of the River type but has been isolated for so long that it has developed some unique characteristics. (Records of the buffalo in Italy date back 1,000 years, during which there have been no reported imports.) Mediterranean buffaloes are stocky, high yielding animals that combine both beef and dairy characteristics.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although there is only one breed of Swamp buffalo, certain subgroups seem to have specific inherited characteristics. For example, the buffaloes of Thailand are noted for their large size, averaging 450-550 kg, and weights of up to 1,000 kg have been observed. Elsewhere, Swamp buffaloes range from 250 kg for some small animals in China to 300 kg in Burma and 500-600 kg in Laos.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Only in India and Pakistan are there well-defined breeds with standard qualities. There are eighteen River buffalo breeds in South Asia, which are further classified into five major groups designated as the Murrah, Gujarat, Uttar  Pradesh, Central Indian, and South Indian breeds. These are the five groups and  main breeds:  </P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=2 CELLPADDING=7 WIDTH=484>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<B><FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">Group</B></FONT></TD>
+<TD WIDTH="79%" VALIGN="TOP">
+<B><FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">Breeds</B></FONT></TD>
+</TR>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">Murrah</FONT></TD>
+<TD WIDTH="79%" VALIGN="TOP">
+<FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">Murrah, Nili/Ravi, Kundi</FONT></TD>
+</TR>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">Gujarat</FONT></TD>
+<TD WIDTH="79%" VALIGN="TOP">
+<FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">Surti, Mehsana, Jafarabadi</FONT></TD>
+</TR>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">Uttar Pradesh</FONT></TD>
+<TD WIDTH="79%" VALIGN="TOP">
+<FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">Bhadawari, Tarai</FONT></TD>
+</TR>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">Central Indian</FONT></TD>
+<TD WIDTH="79%" VALIGN="TOP">
+<FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">Nagpuri, Pandharpun, Manda, Jerangi, Kalahandi, Sambalpur</FONT></TD>
+</TR>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">South Indian</FONT></TD>
+<TD WIDTH="79%" VALIGN="TOP">
+<FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY">Toda,  South Kanara</FONT></TD>
+</TR>
+</TABLE>
+
+<FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The best-known breeds are Murrah, Nili/Ravl, Jafarabadi, Surti, Mehsana, and  Nagpuri. Most of the buffaloes of the Indian subcontinent belong to a nondescript  group known as the Desi buffalo. There is no controlled breeding among these  animals and most are quite small, yield little milk, and are variable in color.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Genetics</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Swamp buffalo has 48 chromosomes, the River buffalo, 50. The chromosomal  material is, however, similar in the two types and they crossbreed to produce fertile  hybrid progeny. Cattle, however, have 60 chromosomes and although mating  between cattle and buffaloes is common, hybrids from the union are unlikely to  occur.( In 1965 a reputed hybrid was born at Askaniya Nova Zoopark in the Soviet Union  (see Gray, A., 1971. Mammalian Hybrids, Commonwealth Agricultural Bureaux,  Slough, England, p. 126). Hybrids have also been reported from China (Van  Fu-Czao 1959, Gibridy buivolc i krupnogo  i rogatogo skota(buffalo and  cattlehybrids)Zhivotnovodstro, Mosk., 21:92). Both of these reports seem doubtful  because despite many attempts, no other hybrids have ever been claimed to have  been produced). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Individual buffaloes show large variation in milk yield, conformation, horn shape,  color, meat production, temperament, growth rate, and other characteristics.  Selection for survival under adverse conditions has occurred naturally (those that  could not stand adversity died early) and farmers have probably tended to select  animals of gentle temperament. But systematic genetic improvement has almost  never been attempted. It seems likely that further selection could quickly improve  their productivity.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unfortunately, the large bulls that would be best for breeding purposes are often  being selected as draft animals and castrated, or sent to slaughter, or (as with  some feral animals in northern Australia and on the Amazon island of Marajo) shot  by hunters. The result is that the buffalo's overall size in countries such as Thailand  and Indonesia has been decreasing as the genes for large size and fast growth are  lost.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Limitations  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The buffalo is still largely an animal of the village, and many of its reported  limitations are caused more by its environment than by the animal itself. Moreover,  much of the animal's genetic potential is obscured by environmental influences. For  example, for many breeds and types the genetic variations in milk yield and growth  cannot be accurately determined because they are overwhelmed by the effects of  inadequate nutrition and management.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nevertheless, some inherent limitations of buffaloes can be identified. For instance,  buffaloes suffer if forced to remain, even for a few hours, in direct sunlight. They  have only one-tenth the density of sweat glands of cattle and their coating of hair is  correspondingly sparse, providing little protection from the sun. Accordingly,  buffaloes must not be driven over long distances in the heat of the day. They must  be allowed time for watering and, if possible, for wallowing. Driving under a hot sun  for long hours will cause heat exhaustion and possibly death; losses can be very  high and can occur suddenly. Young calves are particularly affected by heat.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffaloes are also sensitive to extreme cold and seem less able than cattle to  adapt to truly cold climates(A rule of thumb is that buffaloes don't do well where the sun is inadequate to ripen,  say, cotton, grapes, or Ace. Kaleff, B., 1942. Der Hausbuffel und seine  Zuchtungsbiologie im Vergleich zum Rind. Zeitschsift Tierzucht Biologze,  51:131-178). Sudden drops in temperature and chill winds may lead  to pneumonia and death.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The water buffalo is usually found m areas where there is ready access to a wallow  or shower. This is not a necessity, but when temperatures are high the availability of  water is important for maintaining buffalo health and productivity. It seems clear,  then, that the buffalo is not suitable for arid lands.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Increasing buffalo productivity through breed improvement is just now beginning.  Throughout Asia buffalo mating is almost completely haphazard, and so the animal  lacks the quality improvement through breeding that most cattle have had.  Therefore, most buffaloes are of nondescript heritage and genetic potential.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On poor quality feed water buffalo grow at least as well as cattle, but under intensive  conditions they probably won't grow as fast as the best breeds of cattle. In feedlots,  therefore, the buffalo is likely to be less productive than improved cattle. Weight  gains of about 1 kg per day have been recorded, some exceptional cattle may gain  at almost twice that rate.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The buffalo has long been considered a poor breeder-slow to mature sexually,  and slow to rebreed after calving. Accumulated experience now shows, however,  that this is mainly a result of poor management and nutrition. Buffaloes are not  sluggish breeders. Nevertheless, their gestation period is about a month longer  than that of cows, buffalo estrus is difficult to detect, and many matings occur~at  night so that~ farmers are likely to encounter more problems breeding buffaloes  than cattle.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffaloes are gentle creatures, but if roughly or inexpertly handled they can, through fear or pain, become completely unmanageable. Buffalo behavior sometimes differs from that of cattle. For example, most buffaloes are not trained to be driven. Instead, the herdsman must walk alongside or ahead of them; they then instinctively follow. Also, because of their innate attachment to an individual site or herd it is more difficult to move buffaloes to new locations or herds. In addition, buffaloes respect fences less than cattle do and when they have the desire to move they are harder to contain. (Electric fences, however, will stop them.)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite their general good health, buffaloes are probably as susceptible as cattle to most infections. However, the buffalo seems to be peculiarly sensitive to a few cattle diseases and resistant to a few others (see chapter 7). Reactions to some diseases seem to vary with region, environment, and breed, and the differences are not well understood.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Destruction of the environment is sometimes attributed to buffalo wallowing. This danger seems to have been overstated, except in cases where stocking rates were unreasonably high.(An ongoing study in Northern Australia of environmental degradation widely attributed to buffalo has now shown that the effects are caused by man and climatic changes and only very slightly by buffaloes. (information supplied by D. G. Tulloch.) ) However, buffaloes rub against trees more often than cattle do, and they sometimes de-bark the trees, causing them to die.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unfortunately, some of the best genetic stocks of water buffaloes exist in areas where certain infections and viral and other diseases sometimes occur. Thus, many countries are reluctant to permit importation of water buffaloes, despite the fact that modern quarantine procedures under conditions of maximum security can essentially eliminate the risk.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, it must be emphasized that because buffalo research has been largely neglected, most results reported in this and other buffalo writings cover small numbers of animals and short periods of time. Many are merely empirical observations that have not been subjected to independent confirmation.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Selected Readings</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anonymous. 1972.Buffalo at the crossroads. World Farming 14(n:l0-l3.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Asian and Pacific Council. 1979. Priorities in buffalo research identified.ASPAC News letter No. 43.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bowman, J. c. 1977. Animals for Man. Edward Arnold Publishers, Ltd., London, United Kingdom.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo Bulletin. Newsletter published by the Buffalo Research Committee of Kasetsart University, Bangkok' Thailand. (In English and Thai.)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo World. Newsletter published by the National Dairy Research Institute, Karnal, 132001, Haryana, India.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chantalakhana, C. 1975. The buffaloes of Thailand-their potential, utilization and conservation. In: The Asiatic Water Buffalo. Proceedings of an International Symposium held at Khon Kaen, Thailand, March 31-April 6, 1975. Food and Fertilizer Technology Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chantalakhana, C., and Na Phuket, S. R. 1979. The role of swamp buffalo in small farm development and the need for breeding improvement in Southeast Asia. Extension Bulletin No. 125. Food and Fertilizer Technology Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill, W. R. 1967. The water buffalo. Scientific American 217:118.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill, W. R., ed. 1974. The Husbandry and Health of the Domestic Buffalo. Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill W. R. 1975. The domestic buffalo. Blue Book for the Veterinary Profession No. 25. Animal Production and Health Division, Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill, W. R. 1976. The Buffaloes of China. Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill, W. R., ed. 1977. The Water Buffalo. Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill, W. R. 1977. The water buffalo: domestic animal of the future. Bovine Practitioner 12:92-98.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill, W. R. 1978. Domestic water buffaloes. In: The Care and Management of Farm Animals, edited by W. N. Scott. Bailliere TindaU, London, United Kingdom.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill, W. R. 1980. The ascendant water buffalo-key domestic animal. World Animal Review 33:2-13.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DeBoer, A. J. 1972. Technical and economic constraints on bovine production in three villages in Thailand. Dissertation Abstracts International 33(5):1935.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DeBoer, A. J. 1975. Livestock and Poultry Industry in Selected Asian Countries. Report of Survey on Diversification of Agriculture: Livestock and Poultry Production. Asian Productivity Organization, Tokyo, Japan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">de Guzman, M. R., Jr. 1979. An overview of recent developments in buffalo research and management in Asia. Extension Bulletin No. 124. Food and Fertilizer Technology Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Documentation Center on Water Buffalo. 1978. Abstract Bibliography on Water Buffalo, 1971-1975. Documentation Center on Water Buffalo, University of the Philippines at Los Banos Library, College, Laguna 3720, Philippines.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fahimuddin, M. 1975. Domestic Water Buffalo. Oxford and IBH Publishing Company, New Delhi, India  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fischer, H. 1975. The water buffalo and related species as important genetic resources: their conservation, evaluation and utilization. In: The Asiatic Water Buffalo. Proceedings of an International Symposium held at Khon Kaen, Thailand, March 31-April 6  1975. Food and Fertilizer Technology Center, Taipei, Taiwan.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ford, B. D., and Tulloch, D. G. 1977. The Australian buffalo-a collection of papers. Technical Bulletin No.18. Department of the Northern Territory, Animal Industry and Agriculture Branch, Australian Government Publishing Service, Canberra, Australia.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gupta, H. C. 1977. Possibilities and realities of developing buffalo's performance, breeding and feeding. Indian Dairyman 29(6):337-346.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kartha, K. P. R.1965. Buffalo. In: An Introduction to Animal Husbandry in the Tropics edited by G. Williamson and W. J. A. Payne. Longman, London, United Kingdom.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">McKnight, T. L. 1971. Australia's buffalo dilemma. Annals of the Association of American Geographers 61(4):759-773.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Madamba, J. C., and Eusebio, A. N. 1979. Developments in the strengthening of buffalo research in Asia. Buffalo Bulletin 2(3):7-16.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mahadevan, P. 1978. Water buffalo research-possible future trends. World Animal Review 25: 2-7.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Oloufa, M. M. 1979. Buffaloes as producers of meat and milk. Egyptian Journal of AnimalProduction 19:1-10. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pant, H. C., and Roy, A. 1972. The water buffalo and its future. In: Improvement of Livestock Production in Warm Climates, edited by R. E McDowell. W. H. Freeman and Company, San Francisco, California, USA.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Philippine Council for Agriculture and Resources Research. 1978. The Philippines Recommends for Caraboo Production, PCARR, Los Banos, Laguna 3732, Philippines.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ranjhan, S. K., and Pathak, N. N. 1981. Management and Feeding of Buffaloes. Vikas Publishing House, New Delhi, India  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robinson, D. W. 1977a. Livestock in Indonesia. Research Report No. 1. Centre for Animal Research and Development, Bogor, Indonesia. (In English and Indonesian.)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robinson, D. W. 1977b. Preliminary Observations on the Productivity of Porking Buffalo in Indonesia. Research Report No. 2. Centre for Animal Research and Development, Bogor, Indonesia. (In English and Indonesian.)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sundaresan, D. 1979. The role of improved buffaloes in rural development. Indian Dairyman 31(2):73-78.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tulloch, D. G. 1978. The water buffalo, Bubalus bubalis, in Australia: grouping and home range.Australian Wildlife Research 5:327-34.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wahid, A. 1973. Pakistani buffaloes. World Animal Review 7:22~28. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">2 Meat</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The water buffalo offers promise as a major source of meat, and the production of buffaloes solely for meat is now expanding.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because buffaloes have been used as draft animals for centuries, they have evolved with exceptional muscular development, some weigh 1,000 kg or more. Until recently, however, little thought was given to using them exclusively for meat production. Most buffalo meat was, and still is, derived from old animals slaughtered at the end of their productive life as work or milk animals. As a result, much of the buffalo meat sold is of poor quality. But when buffaloes are properly reared and fed, their meat is tender and palatable.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water buffaloes are exported for slaughter from India and Pakistan to the Middle East and from Thailand and Australia to Hong Kong. Demand for meat is so great that Thailand's buffalo population has dropped from 7 million to 5.7 million head in the last 20 years, a period in which the human population has more than doubled.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Carcass Characteristics</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All buffalo breeds-even the milking ones-produce heavy animals whose carcass characteristics are similar to those of cattle.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite heavier hide and head, the amount of useful meat (dressing percentage) from buffaloes is almost the same as in cattle. Mediterranean type buffalo and Zebu cattle steers in Brazil yielded dressing percentages of 55.5 and 56.6 percent respectively. Swamp buffalo dressing percentages have been measured in Australia at 53 percent. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffaloes are lean animals. Although a layer of subcutaneous fat covers the carcass, it is usually thinner than that on comparably fed cattle. Even animals that appear to be fat prove to be largely muscle. Australian research on Swamp buffaloes reveals that buffaloes with more than 25 percent fat are difficult to produce, whereas average choice-grade beef carcasses may contain  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In general, the buffalo carcass has rounder ribs, a higher proportion of muscle, and a lower proportion of bone and fat than beef has.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo hide is so thick that it can be sliced into two or three layers before tanning into leather.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Meat Quality</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo meat and beef are basically similar. The muscle pH (5.4), shrinkage on chilling (2 percent), moisture (76.6 percent), protein (19 percent), and ash (1 percent) are all about the same in buffalo meat and beef. Buffalo fat, however, is always white and buffalo meat is darker in color than beef because of more pigmentation or less intramuscular fat (2-3 percent "marbling," compared with the 3-4 percent in beef).  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Eating Quality</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Taste-panel tests and tenderness measurements conducted by research teams in a number of countries have shown that the meat of the water buffalo is as acceptable as that of cattle. Buffalo steaks have rated higher than beefsteaks in some taste tests in Australia, Malaysia, Venezuela, and Trinidad.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In taste-panel studies in Trinidad, cooked joints from three carcasses Trinidad buffalo, a crossbred steer (Jamaica-Red/Sahiwal), and an imported carcass of a top-grade European beef steer-were served. The 28 diners all had experience in beef production, butchery, or catering and were not told the sources of the various joints. All the carcasses were held in cold storage for one week before cooking. The buffalo meat was rated highest by 14 judges; 7 chose the European beef; 5 thought the crossbred beef the best; and 2 said that the buffalo and crossbred were equal to or better than the European beef. The buffalo meat received most points for color (both meat and fat), taste, and general acceptability. There was little difference noted in texture.( Information supplied by P. N. Wilson.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo veal is considered a delicacy. Calves are usually slaughtered for veal between 3 and 4 weeks of age; dressed weight is 59-66 percent of live weight.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is some evidence that buffaloes may retain meat tenderness to a more advanced age than cattle because the connective tissue hardens at a later age or because the diameter of muscle fibers in the buffalo increases more slowly than in cattle(Joksimonc, 1979) In one test the tenderness (measured by shearing force) of muscle samples from carcasses of buffalo steers 16-30 months old was the same as that from feedlot Angus, Hereford, and Friesian steers 12-18 months old. This gives farmers more flexibility in meeting fluctuating markets while still providing tender meat.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Selected Readings  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anonymous. 1976. Livestock Production in Asian Context of Agricultural Diversification. Asian Productivity Organization, Tokyo, Japan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Arganosa, F. C., Sanchez, P. C., Ibarra, P. I., Gerpacio, A. L., Castillo, L. S., and Arganosa, V. G. 1973. Evaluation of carabeef as a potential substitute for beef. Philippine Journal of Nutrition 26(2).  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Arganosa, F. C., Arganosa, V. G., and Ibarra, P. I. 1975. Carcass evaluation and utilization of carabeef. In: The Asiatic Water Buffalo. Proceedings of an International Symposium held at Khon Kaen, Thailand, March 31-April 6, 1975. Food and Fertilizer Technology Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bennett, S. P. 1973. The "buffalypso"-an evaluation of a beef type of water buffalo in Trinidad, West Indies. Paper presented at the Third World Conference on Animal Production, Melbourne, Australia.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Borghese, A., Gigli, S., Romita, A., Di Giacomo, A., and Mormile, M. 1978. Fatty acid composition of fat in water buffalo calves and bovine calves slaughtered at 20, 28, and 36 weeks of age. In: Patterns of Growth and Development in Cattle: A Seminar in the EEC Programme of Coordination of Research on Beef Production, held at Ghent, October 11-13,1977. Martinus Nijhoff, The Hague, Netherlands.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Charles, D. D., and Johnson, E. R. 1972. Carcass composition of the water buffalo (Bubalus bubalis). Australian Journal of Agriculture Research 23:905-911.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Charles, D. D., and Johnson, E. R. 1975. Live weight gains and carcass composition of buffalo (Bubalus bubalis) steers on four feeding regimes. Australian Journal of Agriculture Research 26:407-413.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill, W. R. 1975. Alternative livestock: with particular reference to the wafer buffalo (Bubalus bubalis). In: Meat. Proceedings of the 21st Easter School in Agricultural Science, University of Nottingham, edited by D. J. A. Cole and R. A. Lawrie. Butterworth, London, England.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">El-Ashry, M. A., Mogawer, H. H., and Kishin, S. S. 1972. Comparative study of meat production from cattle and buffalo male calves. Egyptian Journal of Animal Production 12:99-107.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">El-Koussy, H. A., Afifi, Y. A., Dessouki, T. A., and El-Ashry, M. A. 1977. Some chemical and physical changes of buffalo meat after slaughter. Agriculture Research Review 55:1-7.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Johnson, E. R., and Charles, D. D. 1975. Comparison of live weight gain and changes in carcass composition between buffalo (Bubalus bubalis) and Bos taurus steers. Australian Journal of Agriculture Research 26:415- 422.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Joksimovic, J. 1979. Physical, chemical and structural characteristics of buffalo meat. Arhiv za Polloprivredne Nauke 22:110.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Joksimovic, J., and Ognjanovic, A. 1977. A comparison of carcass yield, carcass composition, and quality characteristics of buffalo meat and beef Meat Science 1:105 -110.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mai, S. C., and Wu, T. H. 1974. TSC's intensive feed-lot system for cow-calf and beef production program. Taiwan Sugar 21(6):198-211.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Matassino, D., Romita, A., Cosentino, E., Girolami, A., and Cloatruglio, P. 1978. Myorheological, ohemical, and colour characteristics of meat in water buffalo and bovine calves slaughtered at 20, 28 and 36 weeks. In: Patterns of Growth and Development in Cattle: A Seminar in the EEC Programme of Coordination of Research on Beef Production, held at Chent, October 11-13, 1977. Martinus Nijhoff, The Hague, Netherlands.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mogawer, H. H., El-Ashry, M. A., and Mahmoud, S. A. 1976. Comparative study of meat production from cattle and buffalo male calves. II. Effect of different roughage concentrate ratios in ration on carcass traits. Journal of Agriculture Research {Tanta University) 2:6-12.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ognjanovic, A. 1974. Meat and meat production. In: The Husbandry and Health of the Domestic Buffalo, edited by W. R. CockrilL Food and Agriculture Organization of the United Nations, Rome, Italy. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rastogi, R., Youssef, F. G., and Gonzalez, F. D. 1978. Beef type water buffalo of Trinidad-Beefalypso. World Review of Animal Production 14(2) :49 -56.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Romita, A., Borghese, A., Gigli, S., and Di Giacomo, A. 1978. Growth rate and carcass composition of water buffalo calves and bovine calves slaughtered at 20, 28 and 36 weeks. In: Patterns of Growth and Development in Cattle: A Seminar in the EEC Programme of Coordination of Research on Beef Production, Held at Chent, October 11-13, 1977. Martinus Nijhoff, The Hague, Netherlands.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wilson, P. N. 1961. Palatability of water buffalo meat. Journal of the Agricultural Society of Trinidad 61:457, 459-460. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">3 Milk</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More than 5 percent of the world's milk comes from water buffaloes. Buffalo milk is  used in much the same way as cow's milk. It is high in fat and total solids, which  gives it a rich flavor. Many people prefer it to cow's milk and are willing to pay more  for it. In Egypt, for example, the severe mortality rate among buffalo calves is due in  part to the sale of buffalo milk, which is in high demand, thus depriving calves of  proper nourishment. This also occurs in India, where in the Bombay area alone an  estimated 10,000 newborn calves starve to death each year through lack of milk.  The demand for buffalo milk in India (about 60 percent of the milk consumed; over  80 percent in some states) is reflected in the prices paid for a liter of milk: about  130 paisa for cow's milk compared with about 200 paisa for buffalo milk.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Twelve of the 18 major breeds of water buffalo are kept primarily for milk production  (although males may be used for traction and all animals are eventually used for  meat). The main milk breeds of India and Pakistan are the Murrah, Nili/Ravi, Surti,  Mehsana, Nagpuri, and Jafarabadi. The buffaloes of Egypt, Eastern Europe  (Bulgaria, Romania, Yugoslavia, and the USSR), and Italy are used for milk  production and there are also herds used principally for this purpose in Iran, Iraq,  and Turkey.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Composition</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo milk contains less water, more total solids, more fat, slightly more lactose,  and more protein than cow's milk. It seems thicker than cow's milk because it  generally contains more than 16 percent total solids compared with 12-14 percent  for cow's milk. In addition, its fat content is usually 50-60 percent higher (or more)  than that of cow's milk. Although the butterfat content is usually 6-8 percent,( An analysis of 7,770 records of Nili/Ravi buffaloes in herds at the Pakistan  Research Institute showed that average butterfat content was 6.40 (a mean based  on 10 tests over 10 months). of all the samples tested, 77 percent ranged between  5 and 8 percent butterfat and 12 percent were below 5 percent butterfat.  -information supplied by R. E. McDowell.)  it can  go much higher in the milk of some well fed dairy buffaloes and in the milk of  Swamp buffaloes (which are not normally used for milking). Cow's milk butterfat content is usually between 3 and 5 percent.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of its high butterfat content, buffalo milk has considerably higher energy value than cow's milk. Phospholipids are lower but cholesterol and saturated fatty acids are higher in buffalo milk. Studies have shown that digestibility is not adversely affected by this. Because of the high fat content, the buffalo's total fat yield per lactation compares favorably with that of improved breeds of dairy cattle; it is much higher than that of indigenous cows.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Normally the protein in buffalo milk contains more casein and slightly more albumin and globulin than cow's milk. Several researchers have claimed that the biological value of buffalo milk protein is higher than that of cow's milk, but this has not yet been proved conclusively.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p27.png"></center><br>
+ Tables 1 and 2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mineral content of buffalo milk is nearly the same as that of cow's milk except for phosphorus, which occurs in roughly twice the amount in buffalo milk. Buffalo milk tends to be lower in salt.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo milk lacks the yellow pigment carotene, precursor for vitamin A, and its whiteness is frequently used to differentiate it from cow's milk in the market. Despite the absence of carotene, the vitamin A content in buffalo milk is almost as high as that of cow's milk. (Apparently the buffalo converts the carotene in its diet to vitamin A. The two milks are similar in B complex vitamins and vitamin C, but buffalo milk tends to be lower in riboflavin.)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Milk Products</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo milk, like cow's milk, can provide a wide variety of products: butter, butter oil (clarified butter or ghee), soft and hard cheeses, condensed or evaporated milks, ice cream,yogurt, and buttermilk. It is of great economic importance in India in preparing "toned" milk-a mixture of buffalo milk and milk made by reconstituting skim milk powder.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The richness of buffalo milk makes it highly suitable for processing. To produce 1 kg of cheese, a cheese maker requires 8 kg of cow's milk but only 5 kg of buffalo milk. To produce 1 kg of butter requires 14 kg of cow's milk but only 10 kg of buffalo milk. Because of these high yields, processors appreciate the value of buffalo milk.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo cheese is pure white. It many countries it is among the most desirable cheeses (mozzarella and ricotta in Italy, gemir in Iraq, the salty cheeses of Egypt, and pecorino in Bulgaria, for example). In Venezuela all the cheese produced from the small La Guanota milking herd in the Apure River basin (about 100 kg a day) is bought by the Hilton Hotel and sells for 15 bolivars per kg compared with 8 bolivars per kg for cheese made from cow's milk.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although much in demand for making soft cheese, buffalo milk is less desirable for making hard cheeses such as cheddar or gouda. During cheesemaking it produces acid more slowly than cow's milk, retains more water in the curd, and loses more fat in the whey.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cheeses are becoming increasingly popular throughout the world. Demand is rising at a rate that is among the highest for any food product. Cheese offers particular benefit to areas where refrigeration is not widely available, where transporting high-protein foods to remote areas is difficult, and where seasonal fluctuations affect milk supplies. Buffalo milk may make cheesemaking profitable on an even smaller scale than conventional dairying; it is more concentrated than cow's milk and requires relatively less energy to transport and process (an increasingly important factor where fuels are limited).  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p31.png"></center><br>
+ Table 3 Highest Milk Yield (kg per Day) Recorded in the All India Milk Yield</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Yield</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In countries like India and Egypt, the milk yield of buffaloes is generally higher  (680-800 kg) than for local cattle (360-500 kg). However, since selection for  exceptional milk production is not conducted systematically, large variations in yield  occur between individual animals, and milk production of dairy buffaloes falls short  of its potential.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nonetheless, some outstanding yields have been recorded. On Indian government  farms, average yields for milking buffaloes range from 4 to 7 kg per day in  lactations averaging 285 days. Daily yields of 12 kg have been reported for some  Bulgarian buffalo cows and a daily production of over 20 kg has been reported for  some remarkable animals in India. A peak milk yield of 31.5 kg in a day has been  recorded from a champion Murrah buffalo in the All India Milk Yield Competition  conducted by the Government of India (see Table 3).  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At Caserta, Italy, a herd of 1,600 machine-milked, pedigreed dairy buffaloes has  produced average yields of 1,500 kg during lactations of 270 days. In Pakistan an  analysis of over 6,000 lactations of Nili/Ravi buffalo cows showed an average yield  of 1,925 kg during lactations averaging 282 days(Average adjusted for year and  season and calving. Cady et al., in press.) . In India the average milks yield of  Murrah buffaloes in established herds is also reported to be about  1,800kg(*"Williamson and Payne, 1965.)Table 4 lists some outstanding lactation  yields reported from different parts of the world. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As with cattle, the percentages of fat, protein, and total solids decrease as the milks yield increases.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Swamp buffaloes of Southeast Asia are usually considered poor milk producers. They are used mainly as draft animals, but it may be that their milk potential has been underestimated. In the Philippines Swamp buffalo cows with nursing calves have produced 300-800 kg of milk during lactation periods of 180-300 days(*Philippines Council for Agriculture and Resources Research (PCARR). 1978. The Philippines Recommends for Caraboo Production, PCARR, Los Banos, Philippines)In Thailand Swamp buffaloes selected and reared for milk production have yielded 3-5 kg per day during 305-day lactations.(Information supplied by Charan Chantalakhana.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p32.png"></center><br>
+ Table 4 Milk Production of Some Outstading Buffalo Cows and Dairy Herds</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Nanning Livestock Research Institute and Farm in Kwangsi Province,which is representative of many others in South China, is upgrading the native  Swamp buffaloes (or Shui Niu) by selective breeding for size and weight and by  crossbreeding with dairy breeds such as the Murrah and Nili/Ravi. The crossbreeds  that are milked yield 4-5 kg daily.(*CockriH, W. R. 1976. The Buffaloes of China.  FAO, Rome.) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">  </P>
+<P ALIGN="JUSTIFY">Dairy Management</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The characteristics of the dairy buffalo so closely approximate those of the dairy cow that successful methods of breeding, husbandry, and feeding for  milks production for the cow can be applied equally to the dairy buffalo. Buffaloes,  however, have not been bred for uniform udders and it is more difficult to milk them  by machine.(Some thousands of buffaloes are machine milked in Bulgaria and Italy, however. At  Ain Shams University in Egypt, buffaloes have adapted to machine milking. The  calves are separated from their dams immediately after birth and no problems of  milk letdown have been observed. -information supplied by M. El Ashry.)Also, some buffaloes have more of a problem with milks letdown than  dairy cows (although not as much of a problem as some native cattle breeds in the  tropics). Frequently, a calf is kept with the cow and is tied to her foreleg at milking  time. In India, Burma, and other countries a dummy calf may be provided; playing  music seems to work, too.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Selected Readings</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Addeo, F., Mercier, J. C., and Ribadeau-Dumas, B. 1977. The caseins of buffalo  milk. Journal of Dairy Research 44(3):455-468.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agarwala, O. P. 1962. Certain factors of reproduction and production in a water  buffalo herd. Indian Joumal of Dairy Science 15(2):45-51.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Albourco, F., Mincione, B., Addeo, F., and Ameno, M. 1969. Buffaloes' milk. II.  Variations in composition during lactation of milk produced without change in  feeding. Industrie Agraria 7(5):210-219.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Associazione Italiana Tecnici del Latter. 1970. Buffaloes' milk and cheese. Scienza  e Tecnica 21(3):175-196.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bhatnagar, V. K., Lohia, K. L., and Monga, O. P. 1961. Effect of the month of  calving on milk yield, lactation length and calving interval in Murrah buffaloes. Indian  Journal of Dairy Science 14(3): 102-108.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bhasin N. R., and Desai, R. N. 1967. Effect of age at first calving and first lactation  yield on life time production in Hariana cattle. Indian Veterinary Journal 44:684694.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cady, R. A., Shah, S. K., Schermerhorn, E. C., and McDowell, R. E. In Press.  Factors affecting performance of Nili-Ravi buffaloes in Pakistan. Journal of Dairy  Science.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Castillo, L. S. 1975. Production, characteristics and processing of buffalo milk. In:  The Asiatic Water Buffalo. Proceedings of an International Symposium held at  Khon Kahn, Thailand, March 31-April 6, 1975. Food and Fertilizer Technology  Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dassat, P. M., de Paolis, P., and Sartore, G. 1966. Environmental effects on milks  yield in Italian buffalo.Acta Medica Veterinaria 12(6):587-593.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dave, B. K., and Taylor, C. M. 1975. A study on relationship of persistency with other first production traits in Indian water buffaloes. Indian Journal of Animal Health 14(1) :77-80.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Deshmukh, S. N., and Choudhury, P. N. R. 1971. Repeatability estimates of some economic characteristics in Italian buffaloes. Zentralblatt fuer Veterinaer-medizen 18:104-107.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ganguli, N. C. 1979. Buffalo milk technology. World Animal Review 30:2-10.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gomez, I. V. 1977. The manufacture of semihard cheese (Danish type) from carabao milk. Philippine Agriculturalist 61(3/4) :78-86.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gurnani, M., and Nagarcenkar, R. 1971. Evaluation of breeding performance of buffaloes and estimation of genetic and phenotypic parameters. Annual Report of the National Dairy Research Institute, Karnal, India.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Katpatal, B. G. 1977. Dairy cattle crossbreeding in India. I. Growth and development of crossbreeding. World Animal Review 22: 15-21.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kay, H. D. 1974. Milk and milk production. In: The Husbandry and Health of the Domestic Buffalo, edited by W. R. Cockrill. Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kohli, M. L., and Malik, D. D. 1960. Effect of service period on total milk production and lactation length in Murrah buffaloes. Indian Journal of Dairy Science 13(3): 105-111.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nascimento, C. N. B., Moura Carvalho, L. O. D., and Lourenco, J. B. 1979. Irnportancia do Bufalo para a Pecuarfa Brasileira. Agricultural Research Center for Humid Tropics (CPATU), Belem, Para, Brazil.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Raafat, M. A., El-Sayed, Abou-Hussein, Abou-Raya, A. K., and El-Shirbiny A. 1974. Some nutritional studies of colostrum and milk of cows and buffaloes E:gyptian Journal of Animal Production 14(1) :137-148.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ragab, M. T., Asker, A. A., and Kamal, T. H. 1958. The effect of age and seasonal calving on the composition of Egyptian buffalo milk. Indian Journal of Dairy Science 11(1):18-28.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Saudi Arabia Standards Institution. 1978. Raw milk. Saudi Arabia Standard 98.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sebastian, J., Panthulu, P. C, and Bhimasena, M. 1971. Composition of Surti buffalo milk. Annual Report of the National Dairy Research Institute, Karnal, India.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sekhon, G. S., and Gehlon, M. S. 1966. Repeatability estimates of some economic traits in the Murrah buffalo. Ceylon Veterinary Journal 14:18-22.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Singh, B. B., and Singh, B. P. 1971. Comparative study of lifetime economics of Hariana versus Murrah buffaloes. Indian Veterinary Journal 48:485-489.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Singh, R. P. 1966. A study of production up to ten years of age in buffaloes maintained at military farms. Indian Veterinary Journal 43:986-992.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Singh, S. B., and Desai, R. N. 1962. Production character of Bhadawari buffalo cow. Indian Veterinary journal 39:332-343.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Venkayya, D., and Anantakrishnan, C. P. 1957. Influence of age at first calving on the performance of Murrah buffaloes. Indian Journal of Dairy Science 10(1):20-24.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Williamson, G., and Payne, W. J. A. 1965. An Introduction to Animal Husbandry in the Tropics. Longman, London, United Kingdom. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">4 Work</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The water buffalo is the classic work animal of Asia, an integral part of that  continent's traditional village farming structure. Probably the most adaptable and  versatile of all work animals, it is widely used to plow; level land; plant crops; puddle  rice fields; cultivate field crops; pump water; haul carts, sleds, and shallow-draft  boats; carry people; thresh grain; press sugar cane; haul logs; and much more.  Even today, water buffaloes provide 20-30 percent of the farm power in South  China, Thailand, Indonesia, Malaysia, Philippines, and Indochina(Figures provided by A. J. de veer. In India water buffaloes contribute much less to  farm power (6-12 percent); bullocks are more commonly used. In Pakistan  buffaloes are little used for farm power (1-2 percent) but provide much of the road  haulage. Papua New Guinea has no tradition of using any work animal, but villagers  are increasingly using buffaloes for farm work and the government is employing  Fillipinos to train them) . Millions of  peasants in the Far East, Middle East, and Near East have a draft buffalo. For them  it is often the only method of farming food crops.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As fuel becomes scarce and expensive in these countries, the buffalo is being used  more frequently as a draft animal. ln 1979 water buffalo prices soared in rural  Thailand because of the increased demand.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although Asian farms have increasingly mechanized in the last 20 years, it has  often proved difficult to persuade the farmer to replace his buffalo with a tractor  since the buffalo produces free fertilizer and does not require diesel fuel. Now there  is renewed official interest in draft power. Sri Lanka has recently opened up large  new tracts of farmland in the Mahawali Valley, creating such a demand for work  animals that buffalo shortages have become a national development problem.  Indonesia's transmigration schemes are also handicapped by shortages of animal  power.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For many small farmers the buffalo represents capital. It is often the major  investment they have. Buffalo energy increases their productivity and allows them to  diversify. Even small farms have work animals that, like the farmer himself, subsist  off the farm. Tractors usually require at least four hectares for economical operation,  which precludes their use on most peasant farms. Further, the infrastructure to  maintain machinery is often not readily available.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffaloes are also used for hauling. Buffalo-drawn carts carry goods between  villages where road surfaces are unfit for trucks. The animals easily traverse  ravines, streams, paddies, and narrow and rocky trails. In the cities carts can  compete economically with trucks where the road surface is unprepared, where  loading or unloading takes longer than the journey itself, or where the loads are too  small and distances too short to make trucking economical. For road haulage  buffaloes are generally shod: the shoes are flat plates fitted to each hoof.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Capacity for Work</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The water buffalo is a sturdy draft animal Its body structure, especially the  distribution of body weight over the feet and legs, is an important advantage. Its  large boxy hooves allow it to move in the soft mud of rice fields. Moreover, the  buffalo has very flexible pastern and fetlock joints in the lower leg so that it can bend  back its hooves and step over obstacles more easily than cattle. This water-loving  animal is particularly well adapted to paddy farming because its legs withstand  continual wet conditions better than mules or oxen(Australian animal scientists working in Bogor, Indonesia, found that the puddling  effect of buffalo hooves on the soil was critical for rice cultivation in the local soils.  Tractors produced fields so porous that they drained dry. (Information supplied by  A. F. GurnettSmith.) On one research station near Darwin, Australia, buffaloes were  used to prevent water draining from a dam. (Information supplied by D. G. Tulloch.). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although buffaloes are preferred by farmers in the wet, often muddy lowlands of  Asia, mules, horses, and cattle move more rapidly and are preferred in the dryer  areas.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water buffaloes do not work quickly. They plod along at about 3 km per hour. In  most parts of Southeast Asia they are worked about 5 hours a day and they may  take 6-10 days to plow, harrow, and grade one hectare of rice field. Their stamina  and drawing power increase with body weight.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because they have difficulty keeping cool in hot, humid weather (see next chapter),  it is necessary to let working buffaloes cool off, preferably in a wallow, every 2 hours  or so. Without this their body temperatures may rise to dangerous levels.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A pair of 3-year-old buffaloes costs about the same as a small tractor in Thailand.  But many farmers raise their own calves and there is no investment beyond labor.  The "fuel" for the animals comes mainly from village pastures and farm wastes such  as crop stubble and sugarcane tops. Buffaloes have an average working life of  about 11 years, but some work to age 20.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">  </P>
+<P ALIGN="JUSTIFY">Harness</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The yoke used on working buffalo in Asia has changed very little in the last 1,500 years. It is doubtful that a working buffalo can exert its full power with it. The hard wooden yoke presses on a very small area on top of the animal's neck, producing severe calluses, galls, and obvious discomfort. The harness tends to choke the animal as the straps under the neck tighten into the windpipe. Since the traditional hitch is usually higher than the buffalo's low center of gravity, the animal cannot pull efficiently. Considerably more pulling power and endurance can be obtained by improving the harness. The situation is not unlike that in Western agriculture in the twelfth century when the horse collar-one of the most important inventions of the Middle Ages first appeared. Before that, horses were yoked like buffalo and the harness passed across their windpipes and choked them as they pulled. Use of the horse collar improved pulling efficiency and speeded the development of transportation and trade.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The curved yoke now universally used on water buffalo contacts an area of the neck that is only about 200 cm2 (little more than half the size of this page). The entire load is pulled on this small area and causes the wood to dig into the flesh.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A horse collar is a padded leather device that encircles the animal's neck. One modified in Thailand for use on water buffalo (see page 43) had a contact area of 650 cm2, more than three times that of the yoke it replaced. The collar's padding pressed against the animal's shoulders, not its neck, and  therefore did not choke it. Attached to the collar were wooden hames with the traces for hitching the animal to a wagon or plow. In trials a buffalo pulled loads 24 percent heavier with the collar than with the yoke, and the horsepower it developed increased by 48 percent(These trials were conducted by J. K. Garner in Thailand in 1958. In the maximum-load test the yoked buffalo failed to move a load of 570 kg, but it moved a load of 640 kg when fitted with the horse collar. In an endurance test the yoked animal took 35 minutes to pull a load 550 m, but harnessed with the collar it took only 21 minutes). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another potentially valuable harness is the breast strap, a set of broad leather straps that pass over the animal's neck and back. One breast strap modified for water buffalo use had a contact area of 620 cm2, almost as much as that of the horse collar, and in trials the buffalo pulled a load 12 percent heavier than with a yoke and the horsepower it developed increased by almost 70 percent( The same animal used in the horse collar trials pulled 700 kg with the breast strap, in the endurance test it took 18.5 minutes to travel the 550-m distance). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These seem very good innovations. In the humid tropics, however, leather collars and breast straps may decay rapidly. To make them widely practical may require experimentation with, or development of, special leather treatments or more durable materials.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Selected Readings</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill, W. R. 1974. The working buffalo. In: The Husbandry and Health of the Domes tic Buffalo, edited by W. R. Cockrill. Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill, W. R. 1976. The Buffaloes of China. Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">de Guzman, M. R., Jr. 1975. The water buffalo-Asia's beast of burden and key to progress. In: The Asiatic Water Buffalo. Proceedings of an International Symposium held at Khon Kaen, Thailand, March 31-April 6, 1975. Food and Fertilizer Technology Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Garner, J. K. 1958 (Reprint 1980) Increasing the Work Efficiency of the Water Buffalo Through Use of Improved Harness. (Copies available from Office of Agriculture, Development Support Bureau, Agency for International Development, Washington, D.C. 20523)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kamal, T. H., Shehata, O., and Elbanna, I. M. 1972. Isotope Studies on the Physiology of Domestic Animals. International Atomic Energy Agency, Vienna, Austria.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robinson, D. W. 1977. Preliminary Observations on the Productivity of Working Buffalo in Indonesia. Research Report No. 2, Center for Animal Research and Development, Bogor, Indonesia.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vaugh, M. 1945. Report on a detailed study of methods of yoking bullocks for agricultural work. Indian Journal of Veterinary Science 15:186-198.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ward, G. M., Sutherland, T. M., and Sutherland, J. M. 1980. Animals as an energy source in Third World agriculture. Science 208:570. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">5 Adaptability and Environmental Tolerance</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Heat Tolerance</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While the buffalo is remarkably versatile, it has less physiological adaptation to extremes of heat and cold than the various breeds of cattle. Body temperatures of buffaloes are actually lower than those of cattle, but buffalo skin is usually black and heat absorbent and only sparsely protected by hair. Also, buffalo skin has one-sixth the density of sweat glands that cattle skin has, so buffaloes dissipate heat poorly by sweating. If worked or  driven excessively in the hot sun, a buffalo's body temperature, pulse rate, respiration rate, and general discomfort increase more quickly than those of cattle(Failure to appreciate this has caused many buffalo deaths in northern Australia when the animals were herded long distances through the heat of the day as if they were cattle).. This is particularly true of young calves and pregnant females. During one trial in Egypt 2 hours' exposure to sun caused temperatures of buffalo to rise 1.3°C, whereas temperatures of cattle rose only 0.2-0.3°C.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffaloes prefer to cool off in a wallow rather than seek shade. They may wallow for up to 5 hours a day when temperatures and humidity are high. Immersed in water or mud, chewing with half-closed eyes, buffaloes are a picture of bliss.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In shade or in a wallow buffaloes cool off quickly, perhaps because a black skin rich in blood vessels conducts and radiates heat efficiently (Tests at the University of Florida have shown that buffaloes in the shade cool off more quickly than cattle. -Robey, 1976).  Nonetheless, wallowing is not essential. Experience in Australia, Trinidad, Florida, Malaysia, and elsewhere has shown that buffaloes grow normally without wallowing as long as adequate shade is available.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Cold Tolerance</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although generally associated with the humid tropics, buffaloes, as already noted, have been reared for centuries in temperate countries such as Italy, Greece, Yugoslavia, Bulgaria, Hungary, Romania, and in the Azerbaijan and Georgian republics of the USSR. In 1807 Napoleon brought Italian buffaloes to the Landes region of southwest France and released them near Mont-deMarsan. They became feral and multiplied prodigiously in the woods and dunes of the littoral, but unfortunately the local peasants found them easy targets, and with the fall of Napoleon the whole herd was killed for meat(In the twelfth century Benedictine monks introduced buffaloes from their possessions in the Orient to work the lands of their abbey at Auge in northeastern France. In the thirteenth century a herd was introduced to England by the Earl of Cornwall, the brother of Henry III. Nothing is known about how well either herd survived). Buffaloes are also maintained on the high, snowy plateaus of Turkey as well as in Afghanistan and the northern mountains of Pakistan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The buffalo has greater tolerance of cold weather than is commonly supposed. The current range of the buffalo extends as far north as 45° latitude in Romania and the sizable herds in Italy and the Soviet Union range over 40° N latitude(Philadelphia and Peking are at comparable latitudes. In the Southern Hemisphere the 40° line of latitude easily encompasses Cape Town, Buenos Aires, Melbourne, and most of New Zealand's North Island).  Cold winds and rapid drops in temperatures, however, appear to have caused illness, pneumonia, and sometimes death. Most of the animals in Europe are of the Mediterranean breed, but other River-type buffaloes (mainly Murrahs from India) have been introduced to Bulgaria and the Soviet Union, which indicates that River breeds, at least, have some cold tolerance.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Altitude</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although water buffaloes are generally reared at low elevations, a herd of Swamp buffaloes is thriving at Kandep in Papua New Guinea, 2,500 m above sea level. And in Nepal, River buffaloes are routinely found at or above 2,800 m altitude.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Wetlands</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water buffaloes are well adapted to swamps and to areas subject to flooding. They are at home in the marshes of southern Iraq and of the Amazon, the tidal plains near Darwin, Australia, the Pontine Marshes in south-central Italy, the Orinoco Basin of Venezuela, and other areas.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the Amazon, buffaloes (Mediterranean and Swamp breeds) are demonstrating their exceptional adaptability to flood areas. Buffalo productivity outstrips that of cattle, with males reaching 400 kg in 30 months on a diet of native grasses( Information supplied by C. Nascimento). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The advantage of water buffaloes over Holstein, Brown Swiss, and Criollo cattle was demonstrated in a test at Delta Amacuro, Venezuela, when the cattle developed serious foot rot In the wet conditions of the Orinoco Delta and had to be withdrawn from the test. The area of Venezuela is flooded 6 months of the year and creates constant problems for cattle, yet the buffalo seems to adapt well(*Information supplied by A. Ferrer). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">High humidities seem to affect buffaloes less than cattle. In fact, if shade or wallows are available, buffaloes may be superior to cattle in humid areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In southern Brazil, trials comparing buffalo and cattle on subtropical riverine plains have favored the buffalo also. This work is being carried out on native pastures, mostly in  the State of Sao Paulo.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Selected Readings</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hafez, E. S. E., Badreldin, A. L., and Shafei,M. M. 1955. Skin structure of Egyptian buffaloes and cattle with particular reference to sweat glands. Journal of Agricultural Science, Cambridge 46:19-30.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Katyega, P. M. J., Masoud, A. J., and Kobo, E. 1980. Information on body and carcass characteristics of Egyptian water buffalo and Mpwapwa x Friesian steers raised in central Tanzania. Tanzania Veterinary Bulletin 2:86-90.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mason, I. L. 1974. Environmental physiology. In: The Husbandry and Health of the Domestic Buffalo, edited by W. R. Cockrill. Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moran, J. B. 1973. Heat tolerance of Brahman cross, buffalo, Banteng and Shorthorn steers during exposure to sun and as a result of exercise. Australian Journal of Agricultural Research 24(5) :775 -782.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nair, P. G., and Benjamin, B. R. 1963. Studies on sweat glands in the Indian water buffalo. 1. Standardization of techniques and preliminary observations. Indian Journal of Veterinary Science 33:102.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pandey, M. D., and Roy, A. 1969a. Studies on the adaptability of buffaloes to tropical climate. I. Seasonal changes in the water and electrolyte status of buffalo cows. Indian Journal of Animal Science 39:367.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pandey, M. D., and Roy, A. 1969b. Studies on the adaptability of buffaloes to tropical climate. II. Seasonal changes in the body temperature, cardio-respiratory and hematological attributes in buffalo cows. Indian Journal of Animal Science 39:378.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Prusty, J. N. 1973. Role of the sweat glands in heat regulation in the Indian water buffalo. Indian Journal of Animal Health 12(1):33-37.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robey, C. A., Jr. 1976. Physiological Responses of Water Buffalo to the Florida Environment. M.S. Thesis, University of Florida, Gainesville, Florida, USA.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">6 Nutrition</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most buffaloes are located in countries where land, cultivated forage crops, and pastures  are limited. Livestock must feed on poor-quality forages, sometimes supplemented with  a little green fodder or byproducts from food, grain, and oil seed processing. Usually  feedstuffs are in such short supply that few animals have a balanced diet, but the buffalo  seems to perform fairly well under such adverse conditions.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Growth Rate</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Insufficient measurements have been taken to allow unequivocal state. meets about the  relative growth rates of cattle and buffaloes. However, many observations made in  various parts of the world indicate that the buffalo's growth is seldom inferior to that of  cattle breeds found in the same environments. Some observations are given below.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Trials in Trinidad in the early 1960s involved buffaloes grazing pangola grass (Digitaria  decumbens) together with Brahman and Jamaican Red cattle. Over a period of 20  months the buffaloes gained an average of 0.72 kg per day, whereas the cattle on a  comparable nearby pasture gained 0.63 per day(Experiments performed by P. N. Wilson. -Information supplied by S. P. Bennett.).  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· In the Orinoco Delta of Venezuela unselected Criollo/Zebu crossbred cattle gained  0-0.2 kg per day on Paspalum fasciculatum, whereas the water buffaloes with them  gained 0.25-0.4 kg per day(Cunha  et al., 1975).  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· In the Apure Valley of Venezuela, 100 buffalo steers studied in 1979 reached an  average weight of 508 kg in 30 months, whereas the 30-month old Zebu steers tested  with them weighed 320 kg. The feed consumed was a blend of native grasses (25  percent of the diet) and improved grasses (such as pangola, pare, and guinea grass)( Information supplied by A. Ferrer). In  the same valley 200 buffalo heifers (air freighted from Australia) produced weight gains  averaging 0.5 kg per day over a 2-year period (and 72 percent of them calved). Government statistics for the area record average weight gains in crossbreeds between Zebu and Criollo cattle as 0.28 kg per day (with 40 percent calving).  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· In the Philippines, buffaloes showed weight gains of 0.75-1.25 kg per day, the same as those of cattle. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Daily weight gains of over 1 kg have been recorded for buffaloes in Bulgaria and Yugoslavia.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Liveweight gains of 0.80 kg per day have been recorded for buffaloes in Papua New Guinea. In a very humid, swampy area of the Sepik River coastal plains liveweight gains by males averaged 0.47 kg per day and females 0.43 kg per day for more than a year. The average weight of 30 4-year-old female buffaloes was 375 kg, while the average weight of 4-year-old female Brahman/ Shorthorn crossbred cattle was 320 kg.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· At the research station near Belem in the Brazilian Amazon weaned Murrah buffaloes, pastured continuously on Echinochloa pyramidalis (a nutritious grass), gained 0.8 kg daily and reached 450 kg in about 18 months. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Liveweight gains of 0.74-l.i kg per day have been obtained in Australia. Buffalo steers grew as fast or faster than crossbred Brahman cattle on several improved pastures near Darwin, but on one very poor pasture, 40-year-old buffaloes each weighed only 400 kg, whereas the Brahman crossbred steers reared with them weighed 500 kg. The reason for this is not clear.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Efficiency of Digestion</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Indian animal nutritionists have investigated water buffaloes intensively over the past two decades. Many have reported that buffaloes digest feeds more efficiently than do cattle, particularly when feeds are of poor quality and are high in cellulose.One trial revealed that the digestibility of wheat straw cellulose was 24.3 percent for cattle and 30.7 percent for buffalo. The figures for berseem (Trifolium alexandrinum) cellulose were 34.6 percent for cattle and 52.2 percent for buffalo. In another trial the digestion of straw fiber was 64.7 percent in cattle, 79.8 percent in buffalo.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other nutrients reported to be more highly digested in buffaloes than in cattle (Zebu) are crude fat, calcium and phosphorus, and nonprotein nitrogen.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Recent experiments in India suggest that buffaloes also are able to utilize nitrogen more efficiently than cattle. Buffaloes digested less crude protein than cattle in one trial but increased their body nitrogen more (and they were being fed only 40 percent of the recommended daily intake of crude protein).  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The ability of buffaloes to digest fiber efficiently may be partly due to the microorganisms in their rumen. Several Indian research teams have published data indicating that the microbes in the buffalo rumen convert feed into energy more efficiently than do those in cattle (as measured by the rate of production of volatile fatty acids in the rumen).  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Also, in laboratory studies samples of buffalo rumen contents produced volatile fatty acids more quickly from a variety of animal feedstuffs than did samples from the rumen of cattle  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">No single reason alone explains the buffalo's success in using poor quality forages. Rather, it is a combination of reasons that differ with the breed and conditions used. Studies by other researchers suggest that additional causes might include:  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Higher dry matter intake; </P>
+<P ALIGN="JUSTIFY">· Longer retention of feed in digestive tract;  </P>
+<P ALIGN="JUSTIFY">· Ruminal characteristics more favorable to ammonia-nitrogen utilization;  </P>
+<P ALIGN="JUSTIFY">· Less depression of cellulose digestion by soluble carbohydrates (e.g., starch or molasses);  </P>
+<P ALIGN="JUSTIFY">· Superior ability to handle stressful environment; and  </P>
+<P ALIGN="JUSTIFY">· A wider range of grazing preferences.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Calf Growth Rates</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although the buffalo's gestation period is more than a month longer than that of cattle, the calves are born weighing 35-40 kg, or about the same as that of a newborn Holstein calf. But because buffalo milk has about twice the butterfat of cow's milk, the calves grow very quickly. They also suffer more shock at weaning and have to be slowly changed to their new feeding program. Buffaloes can be marketed as full-grown animals for beef at the age of 2-3 years, sometimes even earlier.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p59.png"></center><br>
+ Table 5 Some Coarse Grasses and Forages Palatable to Buffaloes but Less Readily</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For example, in Indonesia it has been found that buffalo steers can be marketed 6 months before Zebu steers because they may be 100 kg heavier. In Egypt some buffalo calves given feed supplemented with concentrates weighed 360 kg at 1 year of age. At Ain Shams University near Cairo, buffalo calves weaned at 7-14 days of age gained 0.7 kg per day from weaning to slaughter at 18 months of age and weighed 400 kg. Rice straw comprised 50 percent of the finishing diet.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffaloes on Italian farms have reached 350 kg in 15-18 months and some year-old calves weighed 320 kg. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Grazing trials on native pasture (with mineral supplementation) in the Brazilian Amazon indicate that buffalo calves grew faster than cattle. At 2 years of age Mediterranean-type buffaloes averaged 369 kg, Swamp type, 322 kg, and Jafarabadi type, 308 kg. The Zebu cattle tested with them averaged 265 kg and the crossbred Zebu/Charolais, 282 kg. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Feed Preferences</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffaloes graze a wider range of plants than cattle. During floods near Manaus in the  Brazilian Amazon when cattle become marooned on small patches of high ground,  many suffer from foot rot and many starve to death. Their buffalo companions on the  other hand-bodies sleek and full-swim out to islands of floating aquatic plants and eat  them, treading water. Also, they dive almost 2 m to graze beneath the floodwaters. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">University of Florida buffaloes in a lakefront voluntarily consumed vines, sedges, rushes, floating aquatic weeds, and the leaves and shoots of willows and other  trees along the water's edge. Few of these plants are voluntarily grazed by cattle. In  northern Australia water buffaloes graze the very pickily leaves of pandanus; they also  graze sedges, reeds, floating grass, and aquatic weeds. Hungry buffaloes will eat bark,  twigs, and other unpalatable vegetation.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of the variety of their tastes they have been used in northern Queensland,  Australia, to clear pastures of woody weeds left untouched by cattle. In some countries  cattle are used to graze the palatable tops of pasture plants and are followed by  buffaloes to graze the less desirable lower parts.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Selected Readings </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Afifi, Y. A., El-Koussy, H. A., El-Khishen, S. S., and El-Ashry, M. A. 1977. Production of  meat from Egyptian buffaloes. I. The effect of using different sources of roughages on  rate of gain, gross and net efficiency during the growth and finishing periods. Egyptian  Journal of Animal Production 17(2).  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appleton, D. c., Dryden, G., and Kondos, A. C. 1976. A comparison of the digestive  efficiency of the water buffalo and the Brahman and Banteng cattle. Proceedings of the  Australian Society of Animal Production 11.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bhatia, L S. 1967. The Study of Factors Affecting the Utilization of Low Grade  Roughages and Production of Volatile Fatty Acids in the Rumen of Indian Cattle. Punjab  Agricultural University, Ludhiana, India.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chalmers, M. 1.1974. Nutrition. In: The Husbandry and Health of the Domestic Buffalo  edited by W. R. Cockrill. Food and Agriculture Organization of the United Nations Rome,  Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Charles, D. D., and Johnson, E. R. 1975. Live weight gains and carcass composition of  buffalo (Bubalus bubalis) steers on four feeding regimes. Australian Journal of  Agricultural Research 26:407-413.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chaturvedi, M. L, Singh, u. B., and Ranjhan, 5. K 1973. Comparative studies on the  efficiency of feed unitization in cattle and buffaloes. Indian Journal of Animal Science  43(12):1034.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chutikul, K. 1975. Ruminant (Buffalo) nutrition. In: The Asiatic Water Buffalo. Proceedings of an International Symposium held at Khon Kacn, Thailand, March 31April 6, 1975. Food and Fertilizer Technology Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cunha, E., Alvarez, F., Larez, O., and Bryan, W. B. 1975. Pasture and Livestock Investigations in the Humid Tropics: Orinoco Delta, Venezuela. 4. Beef Cattle and Water Buffalo Grazing Trials with Native and Introduced Grasses. IRI Research Institute, New York, New York, USA.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Davendra, C. 1979. The potential value of grasses and crop by-products for feeding buffaloes in Asia. Extension Bulletin No. 126. Food and Fertilizer Technology Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">de Guzman, M. R., Jr. 1975. A summary of research into buffalo feeding in the Philippines. In: The Asiatic Water Buffalo. Proceedings of an International Symposium held at Khon Kaen, Thailand, March 31-April 6, 1975. Food and Fertilizer Technology Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dunkel, R. 1981. Animal production using nutrient-deficient fodders in the tropics and subtropics. Animal Research and Development 13:32-39.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">El-Ashry, M. A., Mogawer, H. H., and Kishin, S. S. 1972. Comparative study of meat production from cattle and buffalo male calves. I. Effect of roughage: concentrate ratio in ration for rate of gain and feed efficiency of native cattle, Friesian and buffalo calves. Egyptian Journal of Animal Production 12(2) :99 -107.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Grant, R. J., Van Soest, P. J., McDowell, R. E., and Perez, C. B. 1974. Intake, digestibility and metabolic loss of Napier grass by cattle and buffaloes when fed wilted, chopped and whole. Journal of Animal Science 39(2):423.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ibrovic, M., Cvetkovic, A., Smrcek, A., and Janevski, K. 1972. A contribution to the knowledge of metabolism of carotene and seasonal dynamics of vitamin A in the buffalo. Veterinaria 21(4) :511.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ichhponani, J. S., Makkar, G. S., Sidhu, G. S., and Moxin, A. L. 1962. Cellulose digestion in water buffaloes and Zebu cattle. Journal of Animal Science 21:1001.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ichhponani, J. S., and Sidhu, G. S. 1966. Effect of urea on the voluntary intake of wheat skew in Zebu cattle and the buffalo. Indian Veterinary Journal 43:880-886.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ichhponani, J. S., Makkar, G. S., and Sidhu, G. S. 1969. Biochemical processes in the rumen. 111. Effect of different carbobydrates on in vitro digestion of cellulose and utilization of urea nikogen by rumen micro-organisms from zebu and buffalo. Indian Journal of Animal Science 39 :27-32.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ichhponani J. S., Makkar, G. S., and Sidhu, G. S. 1971a. Studies on the biochemical process in the rumen. Vl. In vivo digestion of cellulose in buffalo and cattle. Indian Veterinary Journal 48:267-271.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ichhponani, J. S., Makkar, G. S., and Sidhu, G. S. 1971b. Studies on the biochemical process in the rumen. VII. In vitro digestion of cellulose in cattle and buffalo. Indian Veterinary Journal 48:583-586.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ichhponani, J. S., Makkar, G. S., and Sidhu, G. S. 1972. Studies on the biochemical processes in the rumen. VIIL The significance of molar proportions of acetic and propionic acids in the rumen on the growth rate of buffalo and Zebu. Indian Veterinary Journal 49:995-1000.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ichhponani, J. S., Gill, R. S., Makkar, G. S., and Ranjan, S. K. 1977. Work done on buffalo nutrition in India-a review. Indian Journal of Dairy Science 30(3): 173-191.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Langar, P. N., Sidhu, G. S., and Bhatia, I. S. 1969. Utilization of nitrogen and production of volatile fatty acids in the rumina of buffalo (Bos bubalis) and zebu (Bos indicus) at different time intervals, under a feeding regimen deficient in carbohydrates. Indian Veterinary Journal 46:593-598.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ludri, R. S., and Razdan, M. N. 1975. Effect of level and source of dietary nitrogen on water metabolism in cows and buffaloes. Indian Journal of Dairy Science 28:107109.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ludri, R. S., and Razdan, M. N. 1980. Efficiency of nitrogen utilization by Zebu cows and buffaloes. I. Nutrient utilization and nitrogen balances on preformed protein diets. TropicalAgriculture (Trinidad) 57:83-90. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Makkar, G. S., and Sidhu, G. S. 1964. The fractionation of carbohydrates in Indian feedstuffs and the digestion of different fractions in the rumina of cattle and buffalo. Journal of Research, Ludhiana 1:56-66.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Misra, R. K., and Ranhoka, G. S. 1969. Influence of energy levels on the utilization of peanut protein-urea nikogen by cattle and buffalo. Journal of Animal Science 28: 107-109.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mullick, D. N. 1964. Review of the investigations on the physiology of Indian buffaloes. Indian Journal of Dairy Saience 17:45-50.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Naga, M. A., El-Shazly, K., Deif, H. I., Abaza, M. A., and El-Faham, R. H. 1975. Relationship between nitrogen balance, digested nitrogen and dry matter digestibility in ruminants. Journal of Animal Science 40(2):366-373.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nangia, O. P., Aggarwal, V. K., and Singh, A. 1972. Studies on the utilization of dietary protein in cattle and buffaloes. Indian Joumal of Dairy &amp;ience 25: 1-5.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nascimento C. N. B., Moura Carvalho, L. O. D., and Lourenco, J. B. 1979. Importdneia do Bufaio para a Pecubria Brasileira. Agricultural Research Center for Humid Tropics (CPATU), Belem, Para, Brazil.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nascimento, C. N. B., and Velga, J. B. 1973. Weight gains in stabled buffaloes of the Mediterranean breed. Boletim Tecnico do Instituto de Pesqutsas e Experimentacao Agropecuarias do Norte 58:24-72.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ponnappa, G. G., Nooruddin, M. D., and Raghavan, G. V. 1971. Rate of the passage of food and its relation to digestibility of nutrients in Murrah buffaloes and Hariana cattle. Indian Journal of Animal Science 41:1026-1030.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Punj, M. L., Kochar, A. S., Bhatia, I. S., and Sidhu, G. S. 1968. In vitro studies on the cellulolytic activity and production of volatile fatty acids by the inocula obtained from the rumen of Zebu cattle and Murrah buffalo on different feeding regimens. Indian Journal of Veterinary Science 38 :325-332.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Raghavan, G. V., Kakkar, B., Rao, M. V. N., and Mullick, D. N. 1963. Effects of air temperature and humidity on the metabolism of food nutrients in cattle and buffalo bulls. Annals of Biochemistry and Experimental Medicine 23 :23-28.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ray, S. N., and Mudgal, V. D. 1962. Rumen metabolism studies in cattle and buffalo. Proceedings of the 16th International Dairy Congress, Copenhagen. A:105-l11.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sahai, L., Johri, P. N., and Kehar, N. D. 1955. Effect of feeding alkali and water-treated cereal straws on milk yield. Indfan Journal of Veterinary Science 25:201-212.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Saini, B. S., and Ray, S. N. 1964. Comparative utilization of coarse fodders in cattle and buffalo. Annual Report of the National Dairy Research Institute, Karnal, India.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Schottler, J. H., Boromana, A., and Williams, W. T. 1977. Comparative performance of cattle and buffalo on the Sepik Plains, Papua New Guinea.AustralianJournal of Experimental Agriculture and Animal Husbandry 17(87) :550 -554. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sebastian, L., Mudgal, V. D., and Nair, P. G. 1970. Comparative efficiency of milk production by Sahiwal cattle and Murrah buffalo. Joumal of Animal Science 30:253256.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sharma, C. B., and Mugdal, V. D. 1966. Studies on the lignin and cellulose contents of fedder crops and effect of lignification of cellulose digestion. Indian Journal of Dairy Science 19:100.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sidbu, G. S., Kochar, A. S., and Makkar, G. S. 1967. Effect of supplementing Bajra stalks with lucerne and concentrates and their part replacement by urea on the production of volatile fatty acids in the rumen of cows and buffaloes. Journal of Research, Ludhiana 4:104-110.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Singh, B. K., and Mudgal, V. D. 1967. The comparative utilization of feed nutrients from lucerne hay in buffalo and crossbred zebu heifers. Indian Journal of Dairy Science 20: 142-145.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tandon, R. N.' Sharma, D. D., and Mugdal, V. D. 1972. Effect of feeding urea with different levels of energy on the biochemical changes in the rumen of cows and buffaloes. Indian Journal of Animal Science 42: 174-179  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Upadhyaya, R. S., Singh, U. B., and Ranjhan, S. K. 19i3. Digestibilit of nutrients and VFA concentation in zebu cattle and buffalo calves fed on green cowpea and maize. Indian Journal of Animal Science 43 :5 83-s 88.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Verma, M. L., Sidhu, G. S., and Kochar, A. S. 1968. Effect of frequency on the production of VFA in the rumen by zebu cattle and buffalo. Journal of Research, Ludhiana 5(3) :1 -6.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Verma, M. L., Singh, N., Sidhu, G. S., Kochar, A. S., and Bhatia, I. S. 1970. The in vitro cellulose digestion and VFA production from some of the common Indian feeds using rumen inocula from Zebu cattle and buffalo. Indian Journal of Dairy Science 23:155 -160. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">7 Health</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When compared with other domestic livestock, the water buffalo generally is a healthy animal. This is particularly impressive because most of them live in hot, humid regions that are conducive to disease, and the buffalo is a bovine susceptible to most diseases and parasites that afflict cattle. Although the reasons are not specifically known, the effect of disease on the buffalo and its productivity is often less deleterious than on cattle.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antibiotics and vaccines developed for cattle work equally well on buffaloes. As a result, treatments are available for most of the serious diseases of buffaloes, although some are not very effective for either animal.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The greatest buffalo losses are often among calves. Newborn buffalo calves, like bovine calves, can succumb in large numbers to viruses, bacteria, and poor nutrition. This is largely due to poor management during the calf's frst 2 months of life. For example, as noted previously, villagers in some countries often sell the valuable buffalo milk, thus depriving the calves.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo calf losses are often similar to those of the cattle around them, but the animal's proclivity for wallowing exposes calves to waterborne diseases. Further, a young one occasionally drowns when an adult rolls on top of it.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Reactions to some specific diseases and parasites are discussed below.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pasteurellosis- Probably the water buffalo's most serious disease, pasteurellosis, or hemorrhagic septicemia, is caused by the bacterium Pasteurella multocida (P. septica). Buffaloes are more susceptible to it than cattle and die in large numbers where pasteurellosis occurs. A vaccine against pasteurellosis is effective in protecting both buffaloes and cattle; it is cheap and easily made.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tuberculosis- Despite some claims to the contrary, the water buffalo is susceptible to the bovine strain of tuberculosis (Alycobacterium bovis). Scattered reports from different parts of India indicate no difference in the incidence of infection between cattle and buffaloes(Information supplied by S. K. Misra, Department of Veterinary Medicine, Punjab Agricultural University, Ludhiana, Punjab, India).  Other strains of mycobacteria have been isolated from feral buffaloes and cattle in northern Australia but seem to have little effect on the animals. Tuberculosis occurs among the buffalo herds of the world only because most are kept under unsanitary conditions(In 1905 buffaloes were introduced to Trinidad because the cattle herds (Zebu and srahman breeds) were infected with tuberculosis and, in those days, it was thought that buffaloes were resistant to the disease. Most were housed in muddy, ill-kept pens and forced to eat sugarcane tops off the ground; consequently, in 1949 over 30 percent of the buffaloes reacted to the tuberculin test. (The cattle herds had 80 percent reactors.) Tuberculosis was eliminated in Trinidad's buffaloes by improving the sanitary conditions: installing concrete floors and mangers and cleaning the pens regularly. This, together with regular tuberculin testing and removal of reactors, led to such a dramatic improvement that buffalo tuberculosis is now virtually unknown. -Information supplied by S. K. Bennett.) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Brucellosis-Buffaloes and cattle are equally susceptible to brucellosis. Although seldom reported as a problem elsewhere, brucellosis in Venezuela is increasing more rapidly among buffaloes than among cattle. In India the disease is no more prevalent among buffaloes than among cattle.  As many as 57 percent of some Venezuelan herds are infected with the disease. It is a frequent cause of abortion in buffaloes. Serologic procedures and measures developed for the control of the disease in cattle are also effective means of curbing this infection in buffaloes. (Consumption of raw milk or contact with aborted fetuses may cause undulant fever in humans.)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mastitis- Among milking buffaloes mastitis is a problem as it is in dairy cows, but to a lesser extent. It is likely to increase, however, as the milk production per individual buffalo is increased. The bacteria that cause mastitis in the buffalo are similar to those in cattle. Treatment and control programs used for cattle are equally effective for buffaloes.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other Diseases -Among the epizootic diseases, rinderpest and piroplasmosis seem to affect buffaloes as much as cattle. Foot-and-mouth disease also affects buffaloes, but to a lesser degree than cattle, producing smaller lesions and having a lower incidence. In northern Australia buffaloes deliberately infected with bovine pleuropneumonia bacteria exhibited slight fever, but the disease never appeared. No naturally occurring eases have been reported in buffaloes. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ticks -Buffaloes are notably resistant, although not immune, to ticks. In a tick-infested area of northern Australia only 2 engorged female ticks were found on 13 adult buffaloes during a 2-year test. Accordingly, healthy buffaloes are not commonly affected by diseases borne by ticks nor are the hides damaged by their bites. Since ticks are rarely found on buffaloes, anaplasmosis, theileriasis, and babesiosis, which are tick-borne, have little effect on buffaloes in the field. (Buffaloes and cattle are equally susceptible, however, if inoculated with East Coast fever, a form of theileriasis.) This is important because tick infestations in cattle are particularly troublesome in the tropics and the pesticides used to control them are becoming ineffective as the ticks develop resistance. The pesticides are also becoming expensive.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The basis of the buffalo's tick resistance is not known, but wallowing and rubbing may play a role in it; animals kept in experimental concrete pens in Australia have developed heavy tick infestation. (rials carried out on Magnetic Island by R. H. V/harton, Commonwealth Scientiflc and Industrial Research Organisation, Townsville, Queensland, Australia). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p68to69.png"></center><br>
+ Table 6 Some Infections and Parasites of Buffalo</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Screwworm- Larvae of the screwworm fly (Callitroge species), a major pest of livestock in Central and South America and some other tropical areas, do not affect adult water buffalo. In Venezuelan areas where cattle (Zebu type) are severely infested, adult water buffaloes are virtually free of screwworm larvae and the umbilicus of newborn calves seldom if ever becomes infected. ( Information supplied by A. Ferrer). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The same is true in Papua New Guinea. It is thought that the mud plaster produced by wallowing suffocates the larvae, but in India screwworms do not affect water buffaloes either, and there they wallow in fairly clear water and the farmer usually washes them off. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Roundworm- The heavy losses of young buffalo calves throughout the world are caused, in large measure, by the roundworm Toxocara vitulorum. The calves seem more susceptible than mature animals and they become infected before birth or within 24 hours after birth through the mother's colostrum. The roundworm is the most serious buffalo parasite and in untreated calves the small intestine can get packed with worms to the point of complete occlusion. Although huge numbers of calves die each year, anthelmintic drugs that control roundworms are highly effective and widely available.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The adult water buffalo appears to have a high degree of resistance to strongyloid nematodes. Being such excellent converters of rough fodders they do not suffer the nutritional deficiency and the resulting liability to these roundworms experienced seasonally by cattle.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Liver Fluke- During wallowing, water buffaloes can easily become infected with the waterborne infective stages of liver fluke (Fasciola gigantica). Although the number of flukes in a buffalo may be phenomenally high, no clinical signs of the disease are usually evident. It seems likely that the resulting liver damage reduces the growth and the work and milk production of buffaloes more than is generally appreciated.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Trypanosomiasis- The water buffalo is susceptible to trypanosomiasis and is reportedly more susceptible than cattle to Trypanosoma evansi.Experience with the animal in Africa is limited, but trypanosomiasis may be the reason why Egypt is the only African country that has traditionally employed water buffalo.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other Parasites- The wallow and its resulting mud cake seem to protect water buffalo from many biting flies, but the main ectoparasite in Australia and Southeast Asia is the buffalo fly (Siphona spp.). Pediculosis, caused by the sucking louse (Hematopinus tuberculatus), occurs widely among buffalo, and sarcoptic mange (Sarcoptes scabiei var. bubalus) is a serious disease, especially among calves and during dry seasons when wallowing opportunities are restricted. The lung worm Dictyocaulus ririparus thrives in warm, humid areas and sometimes infects buffaloes heavily, although its outward manifestations are rare.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Selected Readings</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Barlow, J. N. 1977. Toxicology and safety evaluation of Phosvel to Egyptian water buffalo. Pages 517-522 in: Pesticide Management and Insecticide Resistance, edited by D. L. Watson and A. W. A. Brown. Academic Press, New York, New York, USA.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bhowmik, M. K., and Iyer, P. K. R. 1977. Studies on the pathology of chronic lesions in the mammary glands of buffaloes (Bubalus bubalis). 1. Actinomycosis, nocardiosis and lesions simulating tuberculosis. Indian Veterinary Journal 54(5):342-346.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bhowmik, M. K., Singh, S. P., and Iyer, P. K. R. 1977. Studies on chronic mastisis in buffaloes (Bubalus bubalis). lndian Journal of Animal Health 16(2) :157-160.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill, W. R. 1974. Aspects of disease. In: The Husbandry and Health of the Domestic Buffalo, edited by W. R. Cockrill, Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dhar, S., Bhattacharyulu, Y., and Gautam, O. P. 1973. Susceptibility of Indian water buffalo (Bubalus bubalis) to Theileria annulata infection. Haryana Agricultural University Journal of Research 3(1):27-30.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dwivedi, S. K., Mallick, K. P., and Malhotra, M. N. 1979. Babesiosis: clinical cases in Indian water buffaloes. Indian Veterinary Journal 56(4):333-335.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Griffiths, R. B. 1974. Parasites and parasitic diseases. In: The Husbandry and Health of the Domestic Buffalo, edited by W. R. Cockrill. Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hafez, S. M., and Krauss, H. 1979. Detection of antibodies against some respiratory pathogens in the sera of domestic animals in Egypt. Bulletin of Animal Health and Production in Africa 27(3):209-214.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ho, T. M. 1976. Animal disease control program in Republic of China for better animal production. Korean Journal of Animal Science 18(4):317-321.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Iannelli, D. 1978. Water buffalo (Bubalus bubalis Arnee) allotypes: identification of a multiple allelic system. Animal Blood Groups and Biochemical Genetics 9(2):105113.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kapur, M. P., and Singh, R. P. 1977. Diagnosis of mastitis: a comparative study of four indirect tests.Haryana Veterinarian 16(2):69-73.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Leue, A. 1971. Buffaloes in Nepal. Tierartliche Umschau 26(4):173-178.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mohan, R. N. 1968. Diseases and parasites of buffaloes. I. Viral, mycoplasmal, and rickettsial diseases. II. Bacterial and fungal diseases. III. Parasitic and miscellaneous diseases. Veterinary Bulletin 38:567-576, 647-659, 735-756.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Murthy, D. K., and Sharma, S. K. 1974. Studies on reactivity and immunogenecity of cell-culture rinderpest vaccine in different species of ruminants. Indian Journal of Animal Science 44(6):359-365.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">San Agustin, F. 1973. Important diseases and parasites of Carabaos. Philippine Journal of Nutrition 26(2):68-79.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Schneider, C. R., Kitikoon, V., Sornmani, S., and Thiachantra, S. 1975. Mekong schistosomiasis. III. A parasitological survey of domestic water buffalo (Bubalus bubalis) on Khong Island, Laos. Annals of Tropical Medicine and Parasitology 69(2):227-232.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sharma, K. N. S., Jain, D. K,, and Noble, D. 1975. Calf mortality in pure and crossbred Zebu cattle and Murrah buffaloes reared artificially from birth. Animal Production 20(2):207-211.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sharma, S. K., Banegee, D. P., and Gautam, O. P. 1978. Anaplasma marginale infection in Indian water buffalo (Bubalus bubalis). Indian Journal of Animal Health 17(2): 105-110.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Shaw, J. J., and Lainson, R. 1972. Trypanosoma vivax in Brazil. Annals of Tropical Medicine and Parasitology 66(1):25-32.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Shukla, R. R., and Singh, G. 1972. Studies on tuberculosis amongst Indian buffaloes. Indian Veterinary Journal 49(2):119-123.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Soni, J. L. 1978. Suitability of different serological tests for diagnosis of brucellosis in buffaloes (Bubalus bubalis). Indian Journal of Animal Science 48(12) :873-881. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tantawi, H. H., Fayed, A. A., Shalaby, M. A., and Skalinsky, E. I. 1979. Isolation, cultivation and characterization of poxviruses from Egyptian water buffaloes .Journal of the Egyptian Veterinary Medical Association 37(4):15-23.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thomson, D. 1977. Diseases of water buffalo in the Northern Territory of Australia. Australian Veterinary Practioner 7(1):50-52.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Young, P. L. 1979. Infection of water buffalo (Bubalus bubalis) with bovine ephemeral fever virus. Australian Veterinary Journal 55(7):349-350. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">8 Reproduction</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The water buffalo has a reputation for being a sluggish breeder, but the average animal is so poorly fed that its reproductive performance is unrepresentative of its capabilities. Without reasonable nutrition the animals cannot reach puberty as early in life or reproduce as regularly as their physiology or genetic capability would normally allow.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Actually, adequately nourished buffaloes reach puberty at about the same age as cattle, as early as 18 months of age in buffalo bulls. In northern Australia Swamp females have conceived even as early as 14 months of age and feral buffaloes routinely conceive at 16 months of age. In the herd at Punjab Agricultural University in Ludhiana, India, 11 River buffalo heifers showed estrus at ages less than 18.5 months and a few came into heat when less than 15 months old. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The water buffalo also can calve at an age comparable to that of cattle. At the Ain Shams University in Egypt a well-fed Egyptian buffalo herd of several hundred animals has an average age at first calving of 27 months, 22 days(Information supplied by M. El Ashry. Because of nutritional uncertainties, El Ashry and his colleagues believe that body weight is a better indicator of sexual preparedness than age is. These researchers at Ain Shams University recommend mating heifers when they weigh 365 kg no matter what their age. Research at Punjab Agricultural University shows that buffalo heifers can be bred when they weigh over 270 kg and manifest estrus).Most animals in the Punjab Agricultural University River buffalo herd calved before 35 months, one at 28.3 months.! In one Venezuelan herd almost all heifers 20-24 months old were pregnant; virtually all calved before age 38 months, most by 30 months, and one at age 23 months. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In trials in Queensland, Australia, and in Papua New Guinea buffaloes produced more calves over a 3-year period than the cattle tested with them. In the hot, humid Sepik Plains in northern Papua New Guinea it was noticed that female buffaloes (Swamp breed) came into estrus even while they were losing weight because of inadequate nutrition, whereas cattle did not. Under these stressful conditions the buffalo calves also reached sexual maturity earlier and the buffaloes had a higher calving percentage and a shorter calving interval because they came back into estrus more quickly than cattle(Information supplied by J. Schottler. The age at first calving of more than 60 nutritionally poor buffaloes was 38 months in one herd and 45 months for Brahman cross cattle) . Similar observations have been made in Florida, Trinidad, the Brazilian Amazon, Venezuela, and elsewhere. Although these are exceptions to the normal observations in Asia, where buffaloes seem to breed more slowly than cattle, they do demonstrate the buffalo's potential for improved breeding.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Estrus in buffalo cows usually lasts about 24 hours, but duration varies and may range from 11 to 72 hours. It occurs on an average 21-day cycle. Determination of when a cow is in estrus is difficult because often the animal shows few outward signs of "heat." This increases the chances of missing a cycle, especially for artificial insemination. Unclean surroundings, poor nutrition, and poor management, cause a high death rate among calves; this also contributes to the buffalo's often low reproductive rate.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In many areas, calving is seasonal. This seems to be largely due to changes in nutrition. It may also be caused by heat stress, in either males or females, which results in a low breeding rate during the hot season. However, when buffalo cows are well fed, they come into estrus and will breed in any season.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many matings take place at night and are therefore unobserved. In one set of pregnancy diagnoses in northern Australia, the buffalo's conception rate (81 percent) was higher than that of the Brahman crossbreeds (70 percent) they were with. In India, artificial insemination of water buffaloes began in the late 1950s. Deep-frozen semen is now available and its use is spreading. Overall conception rates of 70-80 percent are obtained. It is estimated that some 100,000 buffaloes are now being artificially inseminated.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The water buffalo's gestation period is about one month longer and is more variable than that of cattle. Whereas cattle give birth after about 280 days (Angus, 279, Holstein, 279-280, Brown Swiss, 286), buffaloes take 300334 days (average 310) or roughly 10 months and 10 days (differences between breeds are unknown). In Punjab, India, River buffaloes have been observed to come into estrus as early as 40 days after calving. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nonetheless, only under uncommon circumstances can a buffalo cow produce a calf each year. In one herd of 800 cows in Venezuela the average female buffalo over age 4 produces 2 calves every 3 years. In response to a recent questionnaire, the majority of Indonesian farmers estimated that the calving rate was between 3 and 4 calves in 5 years. A few claimed a calf a year, some only 1 or 2 calves In 5 years. In Florida it has been noted that some buffalo cows having just calved became pregnant more quickly than cattle, so that a calf may indeed be produced each year. Regular yearly breeding has been noted also in northern Australia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The incidence of abortion, dystocia, retained placenta, and other parturition problems in buffaloes is similar to that in cattle. Twinning is very rare; probably no more than 0.01 percent of buffalo pregnancies produce twins.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Preliminary results in northern Australia indicate that weaning can be carried out as late as 12 months of age without any effect on conception time of the buffalo dam.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Selected Readings</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bhattacharya, P. 1974. Reproduction. In: The Husbandry and Health of the Domestic Buffalo, edited by W. R. Cockrill. Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chauhan, F. S., Singh, N., and Singh, M. 1977. Involution of uterus and cervix in buffaloes. Indian Journal of Dairy Science 30(4):286-291.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Eusibio, A. N. 1975. Breeding, management and feeding practices of buffaloes in the Philippines. In: The Asiatic Water Buffalo. Proceedings of an International Symposium held at Khon Kaen, Thailand, March 31-April 6, 1975. Food and Fertilizer Technology Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FAO Animal Production and Health Paper. 1979. Buffalo Reproduction and Artificial Insemination. Proceedings of the Seminar Sponsored by FAO/SIDA/Government of India, held at National Dairy Research Institute, Karnal, 132001-India, December 4-15, 1978. Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ghanem, Y. S. 1955a. Environmental causes of variation in the length of gestation of buffaloes. Indian Journal of Veterinary Science 25 :301-311.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ghanem, Y. S. 1955b. Genetic causes of variation in the length of gestation of buffaloes. Indian Journal of Veterinary Science 25:307-311.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Health, E., and Gupta, R. 1976. Ultrastructure of water buffalo (Bos bubalis) spermatozoa. Zentralblatt fuer Veterinaerrnedizin 23(2):106-120.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Liu, C. H. 1978. The preliminary results of crossbreeding of buffaloes in China. Research Institute for Animal Science of Kwangsi, People's Republic of China.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Matharoo, J. S., and Singh, M. 1980. Revivability of buffalo spermatozoa after deepfreezing the semen using various extenders. Zentralblatt fuer Veterinaermedizin 27(5): 385-391.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rao, A. V. N., Murthy, T. S., and Dutt, K. L. 1979. Effect of lunar cyclicity on oestrus rhythmicity in the Indian water buffalo. Livestock Advisor 4(7):29-30.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rawal, C. V. S. 1978. A study on correlations of weight of pituitary gland and reproductive organs in males of Indian water buffalo. Indian Journal of Heredity 10(3):11-12.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robinson, D. W. 1977. Livestock in Indonesia. Research Report No. 1. Centre for Animal Research and Development, Bogor, Indonesia. (In English and Indonesian.)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Roy, A. 1974. Observations on the physiology of reproduction. In: The Husbandry and Health of the Domestic Buffalo, edited by W. R. CockrilL Food and Agriculture Organization of the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sahai, R., and Singhal, R. A. 1977. The sex chromatin profile of water buffaloes of Murrah breed. Indian Journal of Animal &amp;Science 11(2):63-67.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sharma, A. 1978. Studies on the process of spermatogenesis and epididymal sperm reserve in water buffalo (Bubalus bubalis). Thesis Abstracts, Haryana Agricultural University 4(4):331.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Singh, M., Matharoo, J. S., and Chauhan, F. S. 1980. Preliminary fertility results with frozen buffalo semen in Tris extender. Theriogenology 13(3):191-194.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Singh, N., Chauhan, F. S., and Singh, M. 1979. Postpartum ovarian activity and fertility in buffaloes. Indian Journal of Dairy Sefence 32(2): 134-139.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sunkaporn Ratanadilok Na Puket. 1975. The improvement of buffalo production through breeding and management under Thailand conditions. In: Asiatic Water Buffalo. Proceedings of an International Symposium held at Khon Kaen, Thailand, March 31-April 6, 1975. Food and Fertilizer Technology Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Takkar, P. O., Chauhan, F. S., Tiwana, M. S., and Singh, M. 1979. Breeding behaviour of buffalo cows. Indian Veterinary Journal 56: 168-172.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Toelihere, M. R. 1975. Physiology of reproduction and artificial insemination of water buffaloes. In: The Asiatic Water Buffalo. Proceedings of an International Symposium held at Khon Kaen, Thailand, March 31-April 6, 1975. Food and Fertilizer Technology Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tulloch, D. G. 1968. Incidence of calving and birth weights of domesticated buffalo in the Northern Territory. Proceedings of the Australian Society for Animal Productlon 7: 144-147.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tulloch, D. G. 1979. The water buffalo in Australia: reproductive and parent-offspring behaviour of buffalo. Australian Wildlife Research 6:265-287. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">9 Management</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water buffaloes are adaptable and are managed in many ways. In general, they are raised like cattle. But in some operations they must be handled differently. This chapter highlights these differences.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Millions of water buffaloes are managed in "backyards" in Asia. They exist on the resources of small holdings. Management and expenditures are minimal. Care of the family buffalo is usually entrusted to children, old people, or women not engaged in other farm duties; the buffalo allows them to be useful and productive.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The buffalo fits the resources available on the farm, but it is also an urban animal. Thousands of herds of 2-20 buffaloes may be found in the cities and towns of India, Pakistan, and Egypt-all fed, managed, and milked in the streets.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition, the buffalo has important qualities as a feedlot animal; it can be herded and handled with relative ease because of its placid nature. The Anand Cooperative in India's Gujarat State, which daily contributes thousands of gallons of milk to Operation Flood (the world's largest nutrition project), involves more than 150,000 Surti buffaloes that are fed, managed, and milked by their owners under feedlot-like conditions in their villages. Many of Italy's 100,000 buffaloes are maintained under similar conditions.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water buffaloes can also be managed on rangelands. In Brazil, Venezuela, Trinidad, the United States, Australia, Papua New Guinea, Malaysia, Indonesia, the Philippines, and elsewhere there is rising interest in raising buffalo beef on the range. The production practices for raising them are similar to those used for range cattle.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water buffaloes in the humid tropics must be able to cool off. Shade trees are desirable, and although a wallow is not essential, it is probably the most effective way the animal has of coping with heat. Alternatively, water showers may be provided to wet down the animals 3-5 times during the hottest part of the day.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water buffaloes are intelligent animals. Young ones learn patterns quickly and often are reluctant to change their habits. Feral animals-even those born in the wild-tame down after a week or two in a fenced enclosure to the point where many can be handled, haltered, and hand fed(In one example, loo feral buffalo were captured in Northern Territory, Australia. With in 14 days all the animals-males and females, young and old-had become docile and amenable to handling. -Information supplied by D. G. Tulloch) . Among feral herds of northern Australia it has been observed that buffaloes have clans and families. A female calf seems to remain with its family and mother for many years (possibly for life). A male calf stays until it is about 2 years old, when it is driven from the group by an adult bull. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It has also been noted in northern Australia that free-ranging buffaloes instinctively select clean water areas to drink from, other areas to wallow in, and still others as "toilet areas." In addition, China's buffaloes reportedly are being "toilet trained" to defecate only at specific sites to avoid contaminating waterways with schistosome eggs.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another interesting observation from northern Australia is that most buffalo dams readily adopt a calf that has been orphaned by the death of its mother. In fact, females will allow several calves to nurse (including calves of other mothers and sometimes even adults).  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffaloes are also self-reliant. For several months each year in Vietnam and Malaysia, for instance, they are turned loose in the forests to fend for themselves.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Provision of adequate fencing is one of the great problems of buffalo management. The  animals have strong survival instincts and if feed runs short, such as in the dry season,  they will break through fences that would deter cattle who would remain and starve. They  will also break through fences if their family unit is split up. Barriers must be stronger  than those used for cattle and the wires closer together and lower to the ground because  buffaloes lift fences up with their horns rather than trample them down. In northern  Australia, Papua New Guinea, and Costa Rica it has been found that buffaloes are  particularly sensitive to electric fences (a single wire is all that is needed), and in Brazil a  special suspension fence has been devised(Moura Carvalho et al., 1979). Both of these  seem to be cheap and efficient answers to the fencing problem.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water buffaloes are easily handled from horseback and easily worked through a corral.  Actually, because of their docility they can be mustered on foot, even on ranges where  cattle require horses. Unless they come from different areas they tend to herd together  and can be mustered like sheep.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the major management adjustments to be made by cattlemen is understanding  and capitalizing on the buffalo's placid nature. Buffaloes are naturally timid and startle  easily; they must be handled quietly and calmly. Rough handling, wild riding, and loud  shouting make handling them more difficult and training them much harder.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Village buffaloes are led and managed by a ring threaded through the septum between  the nostrils. The technique is frequently applied crudely and cruelly, often resulting in a  ripped septum.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The identification of individual buffaloes is difficult. Fire brands do not remain legible on  the skin for long. Cryobranding (freeze branding) is more durable. Most types of ear tags  are not very successful; the numbers wear off and mud covers up the tag's color. In  northern Australia ear tattooing has been the most successful identification technique,  with tattoos remaining legible for at least 8 years(Between 1958 and 1962 hundreds of  Australian buffalo were shipped on the hoof to the meat markets in Hong Kong without  trouble, despite crowded shipboard conditions and the long sea voyage. But in 1962 one  roughly treated bull went berserk in Hong Kong and killed a handler, and the Hong Kong  authorities stopped the trade as a result, although the problem was really one of  mismanagement. Buffalo have since been sent by air from Australia to Venezuela,  Nigeria, and Papua New Guinea and by barge to Papua New Guinea. No handling  problems have been experienced en route).  When they pasture together, cattle and  buffaloes coexist satisfactorily. They segregate themselves into their own groups and do  not interfere with one another. The buffaloes, however, usually dominate the cattle and  tend to monopolize the areas with the best feed supply.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Feed troughs and mineral boxes used for cattle are suitable for buffaloes, but chutes and  crushes must be widened to accommodate the buffalo's broader body and, when  necessary, the Swamp buffalo's greater horn spread. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water buffaloes are powerful  swimmers. In Brazil they have been known to escape by swimming down the Amazon River. An unusual management difficulty is caused by piranha in the rivers and swamps of Venezuela. In one herd of 100 heifer buffaloes, 40 have lost all or part of a teat to these voracious fish.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The horns of water buffaloes are seldom removed or prevented from growing, a  testament to the animal's docility. (When questioned, one Thai villager said that he wouldn't  allow it because it would be a disgrace to the buffalo.) However, the animals can be  dehorned as calves in the same manner as cattle. They are then easier to handle In  chutes and cause less accidental injury to neighboring animals, handlers, walls, and  trees.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Selected Readings</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Benya, E. G. 1972. Cattle and buffalo production in Vietnam. Dairy Science Mimeo  Report, Florida Agricultural Experiment Station, Gainesville, Florida, USA.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cockrill, W. R. 1974. Management, conservation and use. In: The Husbandry and Health  of the Domestic Buffalo, edited by W. R. Cockrill. Food and Agriculture Organization of  the United Nations, Rome, Italy.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">De Boer, A. J. 1976. A further report on the Taiwan livestock industry: general policy  conclusions and further research needs. Journal of Agricultural Economics 19:116129.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lin, C. H. 1975. The breeding, management and feeding of water buffaloes in Taiwan. In:  The Asiatic Water Buffalo. Proceedings of an International Symposium held at Khon  Kaen, Thailand, March 31-April 6, 1975. Food and Fertilizer Technology Center, Taipei,  Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">McDowell, R. E. 1972. Improvement of Livestock Production in Warm Climates. W. H.  Freeman and Company, San Francisco, California, USA.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moura Carvalho, L. O. D., LouIenco, J. B., Nascimento, C. N. B., and Costa, N. A. 1979.  Cerca de Contencao pare Bubalinos e Bovinos. Comunicado Tecnico No. 28,  Agricultural Research Center for the Humid Tropics (CPATU), Belem, Para, Brazil.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rufener, W. H. 1975. Management and productive performance of water buffalo in  northeast Thailand. In: The Asiatic TVater Buffalo. Proceedings of an International  Symposium held at Khon Kaen, Thailand, March 31-April 6, 1975. Food and Fertilizer  Technology Center, Taipei, Taiwan.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tulloch, D. G. 1978. The water buffalo in Australia: grouping and home range. Australian  Wildlife Research 5:327-354.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tulloch, D. G. 1979. Redomestication of water buffaloes in the Northern Territory of  Australia. Animal Regulation Studies 2(1):5-20.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">10 Environmental Effects</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The grazing and wallowing habits of water buffaloes may have unexpected consequences when the animals are introduced to new, perhaps fragile environments. The presence of several thousand feral buffaloes on the coastal plains of northern Australia, for example, has become a very emotional issue among Australian environmentalists, some of whom foretell the complete destruction of the environment if the uncontrolled feral herds are not destroyed( It is not at all clear, however, that the buffaloes (which have existed in the area for 150 years) are causing the observed environmental degradation. Other possibilities include: fire, climatic stress, overgrazing, and a variety of farming, hunting, and other human activities, especially the use of four-wheel-drive vehicles. Thousands of wild pigs also share the area, along with crayfish that burrow into and weaken the levees that keep out the sea, something for which the buffaloes have been blamed). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Soil Compaction</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water buffaloes have larger hooves than cattle of comparable size and thus they compact the soil less. But buffaloes often live in damp, boggy areas where their feet may compact soft soils. Also, buffaloes are creatures of habit and, when able, they set up fixed points for drinking, feeding, defecating, wallowing, and sleeping. Between the points they wear sharply defined trails in the vegetation and soil.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Wallowing</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Possibly the water buffalo's greatest environmental limitation is its propensity to build wallows. In hot climates every buffalo will wallow at some time during the heat of the day if water is available. When they can, buffaloes will make their own wallows, enlarging a mud puddle by rolling in it or even using their heads to flip water out of a drinking trough and muddying the ground nearby.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The pasture in the immediate area of the wallow is usually damaged by trampling and waterholes may become fouled, but buffaloes return to the same wallow day after day and do not build new ones indiscriminately. Thus, the muddied area is not a large proportion of the location in which they graze unless a large number of animals are confined in a small space(At Gainesville, Florida (possibly because of its subtropical but not hot climate), a herd of 52 buffaloes concentrated in a one-hectare field did not attempt to build a wallow at ale -Information supplied by H. Popenoe.) . In addition, man-made wallows can be dug at safe sites and the animals will use them. The problem of wallowing is therefore not generally a serious one.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Damage to Waterways</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because buffaloes often live near and enter water freely, they may cause erosion in ditches, river banks, canals, and levees. Also, their wallowing muddies the water, which may adversely affect some fish species and reduce the growth of algae. Buffaloes commonly urinate and defecate in the water, possibly creating a pollution hazard, although in most situations this contamination is likely to be minor.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The presence of this herbivore in natural waterways may reduce the number of water plants. Some plants are trampled, some eaten, and some underwater species are suppressed because the muddied water transmits less light. This (and several other of the buffalo's environmental effects) can be turned to advantage (see picture page 85) when, as often occurs, aquatic plants grow out of control and become obnoxious weeds.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Damage to Pastures</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water buffaloes have very strong jaws, and when forage is sparse they graze it close to the ground; this overgrazing can destroy a pasture. In addition, they eat virtually all available plant material (including many species that cattle shun), so that a densely stocked pasture can become completely defoliated. In northern Australia it has been found that, with time, buffaloes become accustomed to a given pasture, and unless fences are strong they will instinctively return to it until the forage has been depleted.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The buffalo's inclination to eat many plants can be used to improve the environment and suppress growth of coarse weedy species of plants. On the Sepik Plains in Papua New Guinea buffaloes are being used to graze and suppress sedges (Cyperus species), as a result, the more desirable Paspalum species are beginning to appear. At Mount Bundy in northern Australia native pastures are being improved on a commercial scale by overstocking them with buffaloes. The animals reduce or completely eliminate spear grass and other weeds-even those with thorns-and thus foster the survival and growth of introduced forage legumes such as stylo (Stylosanthes guianensis). In Sri Lanka buffaloes have been used to graze out the vigorous tropical grass Imperata cylindrica.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Damage to Trees</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffaloes instinctively rub against trees (and walls and fences), eagerly browse leaves, and sometimes nibble bark, so they damage trees more so than cattle. In northern Australia it has been noted that each "family herd" of feral buffaloes selects one or two trees for rubbing against so that the rubbing damage is confined to them. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Selected Readings</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rajapske, G., 1950. Death of illuk. Ceylon Coconut Quarterly, 1:7-9.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tulloch, D. G. 1969. Home range in feral water buffalo. Australian Journal of Zoology 17:143-152.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tulloch, D. G. 1970. Seasonal movement and distribution of the sexes in the water buffaloes in the Northern Territory. Australian Journal of Zoology 18:399-414.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tulloch, D. G. 1975. Buffalo in the northern swamplands. Proceedings III of the World Conference on Animal Production. Theme 1, Paper 7.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tulloch, D. G. 1977. Some aspects of the ecology of the water buffalo in the Northern Territory. In: The Australian buffalo-a collection of papers, edited by B. D. Ford and D. G. Tulloch. Technical Bulletin No. 18, Department of the Northern Territory, Animal Industry and Agriculture Branch, Australian Government Printing Service, Canberra, Australia. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">11 Recommendations and Research Needs</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report has outlined the water buffalo's apparent merits, but most of the statements made about the animal are based on empirical observations. Many of its most exciting and potentially valuable features have not been subjected to the careful scrutiny needed to confirm their validity.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite the fact that there are 130 million or more water buffalo in the world, research on the animal is scanty and limited to only a few situations and sites. Quantitative information (especially for the various breeds), tests, trials, and comparison studies are needed.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The research to be done on the water buffalo offers scientific challenges that can be undertaken in laboratories and experiment stations in most parts of the world and in many disciplines: breeding, physiology, microbiology, veterinary science, nutrition, food science, dairy science, and other fields. Water buffalo research is an area worthy of financial support by philanthropic institutions and international development agencies concerned with problems of food and resource shortages. The dominant role of the buffalo in the rural economies of Egypt and Asian countries offers the opportunity for buffalo research that can bring improvements quickly and easily to the rural poor. For other countries the water buffalo is an untapped resource, and they should test its productivity on native pasturelands, marshy lowlands, hot and humid areas where cattle do not thrive, and on areas prone to cattle diseases and parasites that are difficult to control.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Specific recommendations follow.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Comparison with Cattle</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Animal scientists worldwide should undertake trials to compare growth rate, feeding, nutrition, breeding, and other aspects of buffalo and cattle performance.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cattle and water buffaloes are obviously different animals. Each has its own limitations and advantages, and each deserves to be studied in its own right. Perhaps the quickest way for animal scientists to experience for themselves the merits of the water buffalo is to conduct their own comparative trials with buffaloes and cattle in their areas. The results will provide local guidance and will help extend recognition of the buffalo's value, especially under difficult conditions where it may exceed cattle in productivity and profitability.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Germ Plasm Preservation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Urgent action is needed, especially in Southeast Asia, to preserve and protect outstanding buffalo specimens.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In some countries (Thailand, Malaysia, and Indonesia, for example) buffalo populations are decreasing dramatically. High demands for meat are causing slaughter at younger and younger ages. Much of the meat is exported to restaurants and markets in Singapore and Hong Kong. Unfortunately, the largest and quickest growing animals are often selected for slaughter. This results in the loss of a major genetic resource, which is compounded by the practice of castrating the largest males to make them more tractable as work animals. Ten years ago in Thailand it was common to find buffalo weighing 1,000 kg; now it is hard to find 750-kg specimens. A similar situation exists in the Philippines where there is no dearth of good breeding stock, but butchers are paying such high prices that farmers are selling even quality animals for slaughter. In northern Australia, where some of the bulls weigh almost 1,200 kg, the largest animals are being shot for meat, hides, pet food, or sportsmen's trophies,  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A large number of high-yielding buffaloes are taken each year to big cities in India (for example, Bombay, Calcutta, Madras) for milking. At the end of lactation many are returned to the villages, but many others are slaughtered, rather than being fed and retired. This creates a huge loss of valuable germ plasm. In many locations most of the largest animals have already been lost. Only urgent action will protect those remaining.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">International Shipment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo quarantine stations should be organized in "disease-free" areas to develop buffalo germ plasm pools for international exchange.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The importation of buffaloes presents difficulties for any government, researcher, or farmer wishing to obtain the animals for the first time or for breeding purposes. Quarantine laws make it extremely difficult and expensive to exchange genetic resources.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Australia is one of the few nations where there are large numbers of water buffalo in an area free of the major animal diseases. Papua New Guinea, </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nigeria, Colombia, Venezuela, and other nations have taken advantage of this and have  imported Australian buffaloes. But Australian herds are all Swamp buffaloes(The island  of Guam is also a safe source of Swamp animals, although the feral herds there are  depleted, only 300 or 400 animals were left on Guam in 1978) and so breeding centers  should be set up also (in Sri Lanka and Italy perhaps) where importers can obtain  River-type (including Mediterranean) buffaloes.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Genetic Improvement</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Worldwide efforts should be made to select superior buffalo bulls and cows for breeding.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Performance testing, leading to the mass selection of superior animals, deserves high  priority. Virtually all buffalo breeding is haphazard and unplanned. Village animals graze  together and matings are usually not con" trolled, observed, or recorded. Thus, the full  genetic potential of the water buffalo is not being realized.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A massive selection program is needed to bring about genetic progress. For each breed,  bulls and cows with the potential for improving production of meat and milk and  increasing draft power should be identified and used for breed improvement. However,  the wide variations between the characteristics of individual animals may make  exceptional genetic advances difficult to achieve quickly.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Important traits for culling and selection include behavior, temperament, reproduction  rate, easy milk letdown, average daily gain in weight or weight at a given age, carcass  quality (for example, large hindquarters), and milk production, as well as strength and  endurance for work.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Crossbreeding of Swamp and River buffaloes is a potentially important route to genetic  improvement. The progeny reportedly show hybrid vigor (heterosis) in milking ability,  fertility, meat production, and working ability. Infusing genes for high milk production into  the Swamp buffalo, now used mainly for meat and work, creates the potential for a  triple-purpose animal.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The use of artificial insemination and deep-frozen semen should be a major help in  upgrading the buffalo. Moreover, the transport of live embryos (rather than neonatal  animals) for implantation in the uterus of surrogate mothers could be important for water  buffalo. It seems unlikely, however, that buffalo embryos can be implanted in cattle.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most genetic selections should be made in Asia where 97 percent of the world's water  buffaloes are located. The improvements will depend on how accurately bulls can be  identified, selected, and mated. Performance and  progeny testing is sorely needed at research stations as well as "on the farm." Governments should also institute bull-loan or artificial-insemination programs as a means for upgrading the village herds.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Comparison of Breeds</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The relative merits of the various buffalo breeds should be determined,  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Little or no information is available on the comparative performance of the different buffalo breeds in various environments, especially the 17 or so River breeds in the Subcontinent and the Egyptian and Mediterranean breeds. Comparison trials of the breeds and breed-crosses are needed in a wide range of climates from the humid tropical to the temperate. In addition, the cytogenetic, immunogenetic, and inheritance relationships of breeds should be clarified.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The panel encourages countries such as India and Pakistan that have a number of buffalo breeds (for example, Murrah, Surti, Jafarabadi, Mehsana, and Nili/Ravi) to set up experimental farms for scientific reproduction of superior specimens. Substantial research benefits as well as profitable economic returns from using and exporting some of them would be realized.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Meat and Milk Research</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and demonstration is needed to foster the widespread consumption of buffalo meat and milk.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo milk, cheese, and other dairy products are considered outstanding foods in all locations where they are produced. Taste tests so far have indicated that buffalo meat is similar or slightly superior to beef produced under the same conditions.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A specific need is to feed the male calves and use them for meat. Many are now slaughtered at a young age and light weight. Research that provides either a partial or complete milk substitute for feeding calves would have a major impact on meat supplies and farmer income. Diets being developed for calves in Egypt incorporate such ingredients as whey, soybean meal, corn flour (corn starch), and yeast.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other research topics include:  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The effect of climate, thermoregulation, and wallowing on meat and milk production;  </P>
+<P ALIGN="JUSTIFY">· The meat characteristics of each of the breeds and the differences between them,  </P>
+<P ALIGN="JUSTIFY">· Milk production and quality for each of the breeds;  </P>
+<P ALIGN="JUSTIFY">· Adapting buffaloes to machine milking by genetic selection or by designing new milking  machinery;  </P>
+<P ALIGN="JUSTIFY">· Developing new or improved milk products (such as yogurt, cottage cheese, and hard  cheese); and  </P>
+<P ALIGN="JUSTIFY">· Banking genetically superior germ plasm for later use.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Work Research</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The panel recommends research on new harnesses to replace the omnipresent yoke.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As already noted, the wooden yoke, which has not changed in 1,500 years or more, is an  inefficient harness. Research is needed to adapt horse collars, hames, breast straps,  and other devices for the buffalo. Because much of the farm power in Asia comes from  buffaloes, the impact of improved harness could be dramatic, widespread, and of  enormous value to millions of small farmers there. If the experiments in Thailand  described earlier are an indication, the farm power in Asia could be increased by 25  percent overnight with the adoption of an improved harness. The buffalo will continue to  be the small farmer's "tractor," so the benefits from improved harnesses are likely to  continue for a long time.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are 13 million buffalo and bullock carts in India and 20 million Indians are engaged  in the business of road haulage. Application of appropriate technology would eliminate  the archaic wooden wheels, axles, and heavy carts and substitute lightweight carts,  perhaps with such features as metal wheels, pneumatic tires, ball bearings, and fixed  axles. With such improvements, loads might be increased and hauled over longer  distances at greater speed and with less work.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Trials in New Areas</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Testing of water buffalo production is needed in many areas where the animal is not  known.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A seemingly adaptable animal, the water buffalo should be productive throughout the  earth's warm temperate, subtropical, and tropical zones. Different breeds may adapt  differently to extremes of heat, humidity, and cold, and this needs further study.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The United States, the Mediterranean Basin of Europe, and some of the more temperate  European areas like southern England are worth considering for water buffalo trials. In the Southern Hemisphere River buffaloes are already found as far south as 25° latitude in Brazil's Sao Paulo State (where large herds are raised); an experimental herd of Swamp buffaloes has performed outstandingly in Brisbane, Australia (27°S); and there are a few Swamp buffalo in South Australia and Victoria (35°S or more). There is good reason to believe that water buffaloes may be productive in all of the states in Australia, New Zealand's North Island, South Africa, Argentina, and other warm temperate areas of the Southern Hemisphere.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The biggest void in the water buffalo map is virtually the entire continent of Africa. It seems a paradox that the buffalo-Egypt's most important domestic animal-is not farmed commercially in any other African country. Experimental herds have been introduced to Nigeria, Uganda, Mozambique, Tanzania, and other countries in the past, and the initial success of three of them is described in Appendix A.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The water buffalo, with its tolerance for heat, disease, poor-quality feed, and mismanagement, appears to have outstanding promise for African nations such as Sudan, Tunisia, Morocco, Senegal, and The Gambia as well as all nations south of the Sahara (Nambia perhaps being an exception).  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More specific aspects of environmental tolerance deserving research attention are:  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">· The physiology of the buffalo's response to heat, cold, humidity, and other environmental factors;  </P>
+<P ALIGN="JUSTIFY">· The effect of climate on growth, reproduction, milk production, health, respiration rate, behavior, and carcass quality; and  </P>
+<P ALIGN="JUSTIFY">· Measurement of the calorific efficiency and chemical composition of all breeds of buffaloes and cattle to determine the environments best suited to each breed.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Nutrition Research</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite observations of the buffalo's ability to utilize poor quality forage, research is needed to learn how the animal does it.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This research should:  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Establish the buffalo's nutrient requirements by breed, sex, age, and weight for maintenance, growth, reproduction, lactation, and work;  </P>
+<P ALIGN="JUSTIFY">· Determine voluntary forage consumption and the nutrient utilization of different forages in various stages of maturity;  </P>
+<P ALIGN="JUSTIFY">· Examine rumen microbiology and fermentation, the rate of digestion, production, and absorption of volatile fatty acids produced in the rumen, and utilization of energy, nitrogen, vitamins, and minerals; </P>
+<P ALIGN="JUSTIFY">· Develop milk replacements for early~weaned calves;  </P>
+<P ALIGN="JUSTIFY">· Observe the current village-level feeding of low~uality forages to learn their nutrient requirements, nutrient deficiency diseases, and nutrient supplementation needed;  </P>
+<P ALIGN="JUSTIFY">· Study the utilization of concentrated, high-energy feeds (especially byproduct feeds) to determine the upper limits of buffalo growth and productivity (milk, meat, and work) and carcass quality;  </P>
+<P ALIGN="JUSTIFY">· Compare various breeds of water buffaloes and other ruminants to determine possible differences in nutritional requirements and performance; and  </P>
+<P ALIGN="JUSTIFY">· Apply economic research to production practices, including night feeding of cut forage and the use of improved pastures.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Management</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research to improve management practices could benefit small farmers, ranchers, and feedlot feeders alike.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Little is known about the farm management factors that influence water buffalo productivity. Studies and extension literature for farmers are needed on subjects such as:  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Proper fencing;  </P>
+<P ALIGN="JUSTIFY">· Procedures for dehorning and for preventing horn growth in calves;  </P>
+<P ALIGN="JUSTIFY">· Grazing management methods;  </P>
+<P ALIGN="JUSTIFY">· Preservation of forages;  </P>
+<P ALIGN="JUSTIFY">· Methods and effect of castration;  </P>
+<P ALIGN="JUSTIFY">· Methods and effect of spaying;  </P>
+<P ALIGN="JUSTIFY">· Breeding methods;  </P>
+<P ALIGN="JUSTIFY">· Milking methods;  </P>
+<P ALIGN="JUSTIFY">· Artificial insemination, methodology and use;  </P>
+<P ALIGN="JUSTIFY">· Methods of handling animals under grazing conditions or in feedlots;  </P>
+<P ALIGN="JUSTIFY">· Age for weaning under different conditions;  </P>
+<P ALIGN="JUSTIFY">· Mineral and protein supplementation methods;  </P>
+<P ALIGN="JUSTIFY">· Semen freezing;  </P>
+<P ALIGN="JUSTIFY">· Ova transplantation methods;  </P>
+<P ALIGN="JUSTIFY">· Cryobranding and other methods of animal identification;  </P>
+<P ALIGN="JUSTIFY">· Control of internal parasites; and  </P>
+<P ALIGN="JUSTIFY">· Disease prevention and treatments. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Health</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research is needed in areas where uncertainties about buffalo diseases are hindering  the animals' use.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The research should:  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Develop control and management practices to prevent specific infections and parasites  for buffalo groups such as calves, yearlings, heifers, pregnant cows, newly calved cows,  and bulls;  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Elucidate the factors (genetic, nutritional,management, disease) causing losses of  newly born calves;  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Prevent and control the major diseases and parasites of the buffalo: hemorrhagic  septicemia, brucellosis, tuberculosis, foot-and-mouth disease, sarcoptic mange,  fascioliasis, nematode parasites, rinderpest and "rinderpestlike" diseases, nephritis, and  conjunctivitis;  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Develop herd-health programs and specific disease-control programs for the various  production systems;  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Determine the level of susceptibility to trypanosomiasis, a disease that might mitigate  against introducing the animal widely to Africa; and  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Define the buffalo's role in malarial ecology.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Reproduction</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research is needed to improve water buffalo reproduction.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research topics should include:  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Physiology and deep-freezing of buffalo semen. (Although it is possible to freeze the  buffalo semen now, further improvements are needed to achieve higher conception  rates.)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Incidence of sub-estrus and anestrus. This is fairly high in buffaloes. Work is needed to  determine the factors contributing to this problem and find solutions applicable in the  field. A simple, inexpensive test for the routine diagnosis of estrus is needed. It could  ensure that buffaloes are inseminated at the optimal time and could lead to the possible  synchronizing of estrus in groups of animals as well as the elimination of seasonal  breeding.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Seasonality of breeding. Investigations are needed into seasonal effects on the intensity  and deviation of estrus in buffaloes. Most of the buffaloes in northern India and Pakistan,  for example, calve between July and December, causing scarcity of milk in the summer  season and a flush of production in the winter months (this phenomenon causes serious  marketing problems).  </P>
+<P ALIGN="JUSTIFY">· Low libido and low semen yield in buffalo bulls. Semen yield in buffalo bulls is less than half of the yield from cattle bulls.  </P>
+<P ALIGN="JUSTIFY">· Effect of season and other factors on semen quality.  </P>
+<P ALIGN="JUSTIFY">· Variation in the freezability of semen from different bulls.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Dissemination of Information</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The panel recommends that two water buffalo publications be produced.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These should be:  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· An international water buffalo newsletter. It is important to maintain communication among researchers working with the water buffalo in far flung research stations, universities, missions, and villages. Research findings may not be widely shared if technical animal science journals and the one or two national newsletters now available remain the only source of water buffalo information. A newsletter would bring together results from different parts of the world. It would provide rapid exchange of information as well as a forum for informal opinions, observations, and preliminary experimental data that are usually not accepted by journals.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· A formal journal of water buffalo research.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition, other methods for disseminating water buffalo information are to be encouraged. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendixes</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Appendix A</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Water Buffalo in Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For the water buffalo, Africa is the unknown continent. Apart from Egypt, where the  "gamoosa" is a major livestock resource, there have been few recorded experiences  with the animal in Africa. While this may be attributed to disease, chances are it is  because of historical oversight.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Small herds of buffaloes were recently introduced to Uganda, Tanzania, and Nigeria, but  because there were so few animals no firm conclusions can be drawn. Initial  observations, however, suggest that the water buffalo could have an important future role  in Africa, south of the Sahara. There seems little reason to believe that they won't thrive  there as they have done elsewhere in the tropics.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The following statements were provided by researchers involved in the enterprises.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Uganda</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">"Uganda imported a herd of 12 buffalo cows and one bull in 1969. Grazed on poor-quality  unimproved pasture they received neither supplementary feeding nor any preferential  treatment over the East African zebus kept with them. The herd stayed 7 years at  Entebbe before being moved to another part of the country. They proved to be very  efficient converters of the low protein, high-fber fodder. During this time the herd grew to  40 adult cows and 2 bulls (all other steers were slaughtered). The cows calved every  year. The calves matured at 2 to 21/2 years; the zebu calves took at least 3 years to  mature. Buffalo calves were much heavier than the zebus of comparable age.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">"The buffalo cows averaged 7 liters of milk per milking. In taste it was preferred to zebu  milk. Also, the quality of the meat after slaughter was much better than that of the zebus.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">"A major advantage the buffaloes had over the cattle was that they were remarkably  unaffected by diseases endemic to the area. Apart from a few calves that died of  diseases that also killed cattle on the farm at Entebbe, the buffaloes resisted tick-borne  diseases, the biggest killers of cattle in Uganda, and were unaffected by the virulent  strains of East Coast Fever (Theileriosis), Uganda's most serious endemic animal  disease."(Information supplied by G. L. Corry, Director, Veterinary Research Services, Entebbe  Uganda)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Nigeria</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Early in 1976, 194 buffaloes aged 6-9 months were imported from the environs of Darwin in Australia's Northern Territory. The animals settled down quite well, and by the end of 1978 the stock population had risen to about 320, the adults weighing about 400 kg with about 80 percent fertility. The animals were in excellent health when an outbreak of streptothricosis occurred early in 1979. Because of the intractable nature of this rare disease of cattle, sheep, and pigs, the apparent spread of the disease in the confined area of the ranch, and the persistence of the organism, the animals were slaughtered(nformation supplied by Dr. J. E. Erhiaganoma, Chief Veterinary Officer, Ministry of Agriculture and Natural Resources, Benin City, Bendel State of Nigeria)..  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Tanzania</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tanzania introduced 21 buffalo heifers and 2 buffalo bulls from Egypt in 1968 and 1970. By 1977 the herd had grown to 150 animals. They were kept at the Livestock Production Research Institute at Mpwapwa, a site representative of central Tanzania(Mpwapwa is located at an elevation of 1,000 m. It receives an annual rainfall of 700 mm during a single season between late November and early May. Mean minimum temperatures of 13°C occur in June, and mean maximum temperatures of 26°C occur in November). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over a period of 10 years the buffalo were studied and compared with crossbreeds of local Mpwapwa cows and Friesian steers. On average, the buffaloes conceived and calved 4 months earlier than the cattle, their mean calving intervals were about a month shorter, their birth and weaning weights were 1.5 times higher, and their daily weight gain was about double that of the crossbred cattle. The milk yield from the buffaloes was only about two thirds that of the crossbred cattle, but their rnilk's high butterfat content meant that the overall butterfat production was higher in buffaloes.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Figures reported are shown below:  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p98.png"></center><br>
+ Table</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In a second study (Shoo, R A. 1980. A study of the performance of Egyptian water buffaloes. Student project, Animal Production Department, Faculty of Agriculture, Forestry and Veterinary Medicine, University of Dar-Es-Salaam, Morogoro, Tanzania.), 30 buffaloes and 34 Mpwapwa cattle (not the crossbreeds) were compared(Mpwapwa cattle are a Tanzanian breed with 55 percent Asian, 35 percent African, and 10 percent European blood). The calving intervals were 396 + 126 days for buffaloes and 437 + 109 days for cattle. The buffaloes first conceived at mean ages of 23-25 months (matings occurred in both wet and dry seasons), the cattle at 27-36 months. The buffaloes calved at 35 months, the cattle at 46 months.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On farms at Ruvu and Mabuki the calving rate was 63 percent, and the mortality rate 1.2-6.9 percent(Rakha, A. 1980. water buffalo Production, Tanzania. Report of the technical Cooperation Program TCP/URT/9002, Food and Agriculture Organization of United Nations, Rome, Italy). The buffalo's overall milk yields averaged 1,237 kg in 225 days, or 5.5 kg per day.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The results of the introduction of buffalo to Tanzania are considered "quite encouraging and the future of buffaloes in Tanzania will be bright." (Oloufa, M. M. 1981. The future of water buffaloes in Tanzania Paper presented at the Tanzania Society of Animal Production Eighth Scientific Conference, Arusha, Tanzania May 26-29, 1981.) Future plans call for increasing the herd to about 200 animals with a view toward establishing another buffalo herd. In addition, 5 buffalo sires have been selected in Egypt for shipment to Tanzania.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendix B</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research Contacts</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A directory of names in buffalo studies and research is available from the International Buffalo Information Center, Kasetsart University Library, Bangkhen, Bangkok 10900, Thailand.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Animal Industry Branch, Department of Primary Production, P.O. Box 5160, Darwin, Northern Territory 5790 (D.R. Thomson, B. Ford)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Berrimah Agricultural Research Station, Darwin, Northern Territory</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coastal Plains Research Station, near Darwin, Northern Territory</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D. G. Tulloch, P.O. Box 38841, Winnellie 5789, Northern Territory</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">University of Queensland, Department of Animal Husbandry, St. Lucia, Queensland (D.D. Charles)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Brazil</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Associacao de Criadores de Bufalos do Brasil, Cx Postal 832, Sao Paulo (President, Dr. Paulo Joaquim Monteiro da Silva)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Centro de Pesquisa Agropecuaria do Tropico Umido (Agricultural Reseach Center of the Humid Tropics), Caixa Postal, 48, Belem, Para, 66000  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Faculdade de Medicina Veterinaria e Zootecnia (Faculty of Veterinary Medicine and Zootechnology), Universidade Estadual "Julio de Mesquita Filho," Campus de Botucatu, Estado de Sao Paulo  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Instituto de Zootecnia (Institute of Zootechnology), Nova Odessa, Sao Paulo (Prof. Alberto Alves Santiago)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dr. Geraldo Mosse, Rua Apinages 716-CEP, 05017, Sao Paulo, S.P.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dr. Walmore Muller Lacort, Ministerio de agriculture Explanada des Ministerios, Bloco 8-50 Andar Sala 518, 70.000 Brasilia, D.F.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Bulgaria</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Academy of Agricultural Sciences, Sofia (P. Ivanov, Z. Zahariev)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Buffalo Basis, Livestock Breeding Research Institute, Shumen (Dr. D. St. Polikhronov, Director; Dr. A. Alexis)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">China</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Department of Animal Husbandry and Veterinary Medicine, Nanking Agricultural College, Nanking (Professor Sieh Chen-Hsia)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kwangsi Agriculture College, Nanning, Kwangsi (Professor Wang Pei Chien</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Livestock Farm, Lu Hsu, Pinyang County, Kwasngsi Chang Autonomous Region</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research Institute for Animal Science, Nanning, Kwangsi (Dr. Chou Chi-Sheng)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Singchow Dairy Farm, Kwangtung Province</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Costa Rica</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jose Luis Pacheco, Director, Dept Formento, 8502 JAPDEVA, Puerto Limon</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Egypt</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ain Shams University, Kasr-EI-Zaafran, Abbasiyah, Cairo (M.A. El-Ashry, A.M. El-Serafy)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Department of Animal Production, College of Agriculture, Cairo University, Cairo (Dr. M.T. Ragab)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">University of Alexandria, 22 Al-Gueish Avenue, Shatby, Alexandria (K. El-Shazly)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Federal Republic of Germany</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dr. R. Dunkel, Herzeleidstrasse 39, 5330 Konigswinter 41, Bonn</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Prof. Dr. H. Fischer, Insitut fur Tropische Veterinarmedizin, Wilhelmstr. 15, 6300 Giessen</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gesellschaft fur Agrarentwicklung (GAE), Meckenheimer Allee 113, 5300 Bonn 1</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Hungary</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. Kovacs, Department of Animal Husbandry, Agricultural University, Deak F. -u16, 8361Keszthely  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">India</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Andhra Pradesh Agricultural University, Hyderabad, A.P. (Director of Research)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Animal Husbandry Commissioner, Government of India, Ministry of Agriculture and Irrigation, Krishi Bhavan, New Delhi  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Animal Sciences, Director General, Indian Council of Agricultural Research, Krishi Bhavan, New Delhi  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Central Buffalo Breeding Farm, Sambalpua, PO: Sunbeda, Distt. Kerapur, Orissa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Central Frozen Semen Bank, Hessarghatta, Bangalore, Kamataka</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Central Murrah Breeding Farm, Almadi, Tamil Nadu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Central Surti Buffalo Farm, Dhamrod, Gujarat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chief Superintendent, Govenment Livestock Farm, Hissar, Haryana</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">College of Veterinary and Animal Science, Chandra Sekhar Azad University of Agriculture and Technology, Mathura Campus, Mathura, U.P.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Co-ordinator, All India Buffalo Improvement Project, Natioal Dairy Research Institute, Karnal, Haryana, (Dr. V. N. Tripathi)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Director, Military Dairy Farm, Army Headquarters, Quatermaster, General Branch, DHQ PO New Delhi 11  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">G.B. Pant, University of Agriculture and Technology, Pantnagar, U.P.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Government Livestock Farm, Anjora Distt: Durg, Madhya Pradesh</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gujarat Agricultural University, Reproductive Biology Research Unit, PO Anand Agricultural Institute, Anand, Gujarat  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Haryana Agricultural University , Hissar, Haryana</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Indian Veterinary Research Institute, Izatnagar, Barcilly, V.P. (Dr. S.K. Ranjan)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jawaharlal Nehru Krishi Vishwa Vidyalaya, Jabalpur, 482004, M.P.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kaira District Cooperative Milk Producers Union Ltd., Anand, Gujarat (Dr. V. Kurien, Chairman)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">National Dairy Development Board, Anand, Gujarat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">National Dairy Research Institute (ICAR), Karnal 132002, Haryana (S.P. Arora, Dr. D. Sundaresan, Director)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Punjab Agricultural University, Ludhiana, Punjab (Dr. J.S. Ichhponani, Dr. S.K. Misra)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">University of Agricultural Sciences, Dharwar Campus, Dharwar, Karnataka</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">University of Udaipur, Udaipur, Rajasthan</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Indonesia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Balai Inseminasi Buatan Lembang, Jawa Barat (Dr. R.D. Simangunsong)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Directorate of Animal Husbandry, Department of Agriculture, Jl Salemba Raya 16, Jakarta (Dr. Jaman Zailani)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pusat Penelitian den Pengambangan Ternak (Centre for Animal Research and Development), Bogor</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Iraq</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Animal Rearing Station, Abu Ghraib, Baghdad</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Italy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Animal Production and Health Division, FAO,00100 Rome</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Associazione Provinciale Allevatori, via Redentare, Caserta (Professore de Franciscis,Presidente)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Instituto de Ricerche soll'Adattamento Bovini e dei Bufali, Ponticelli, Napoli (Director: Pro£ Lino Ferrara)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Instituto Sperimentale per la Zootecnica, via Onofrio Panvino, Rome (Prof. A. Pilla)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Instituto Sperimentale per la Zootecnice di Roma, via Salaria 31, 00016, Monterotondo Scalo (Dr. Augusto Romita)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ugo Jemma, Torre Lupara, 81050 Pastorano, near Caserta</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Japan</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. Shimuzu, The University of Tsukuba, Sakura-mura niihar gun ibaraki-ken 300-311</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Malaysia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Central Animal Husbandry Station, Kluang</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Faculty of Veterinary Medicine and Animal Science, University Pertanian, Serdang, Selangor</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Malaysian Agricultural Research and Development Institute, Serdang, Selangor</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Nepal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Artificial Insemination Project, Tfipureshwar, Kathmandu (Dr. A.C. Gupta)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Livestock Division, Khumaltar, Lalitpur, Kathmandu (Dr. N.D. Joshi)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Pakistan</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">College of Animal Husbandry, Lahore (Dr. Mohammad Shafi Chaudhry)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Department of Animal Reproduction, University of Agriculture, Faisalabad (Dr. Rashid Ahmad Chaudhary)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Livestock Production Research Institute, Bahadurnagar District, Sahiwat, Punjab (Dr. S.K. Shah, Director)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Punjab Veterinary Research Institute, Lahore 13</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Panama</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hugo Giraoud, Apartado 60-2745, El Dorado</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Papua New Guinea</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Department of Primary Industry, ERAP, P.O. Box. 348, Lae (John H. Schottler)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sepik Plains Livestock Station, Ufimo via Wewak, E.S.P.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Philippines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Animal Science Department, Central Luzon State University, Muiloz, Nueva Ecija</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">College of Veterinary Medicine, University of the Philippines Systems, Diliman, Quezon City Dairy Development Division, Bureau of Animal Industry, Sta. Mesa, Metro Manila (Dr. Conrado A. Valdez)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dairy Training and Research Institute, University of the Philippines at Los Banos, College, Laguna 3720  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Department of Animal Science, University of the Philippines at Los Banos, College, Laguna 3720 (Dr. V. C. Momongon)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Documentation Center on Water Buffalo, University of the Philippines at Los Banos Library, College, Laguna 3720  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Philippine Council for Agriculture and Resources Research, Livestock Research Division, Los Banos, Laguna 3732 (Dr. Alfonso N. Eusebio)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Portugal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">W. Ross CockriII, 591 Vale do Lobo, Almansil, Algrave 8100</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Sri Lanka</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Department of Animal Production and Health, Peradeniya (Dr. K. Balachandran)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">School of Veterinary Science, University of Sri Lanka, Peradenlya Dr. B.M.A.O. Perrera)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Taiwan</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Food and Fertilizer Technology Center, P.O. Box 22-149, Taipei City</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Tanzania</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Animal Production Department, Faculty of Agriculture, Forestry and Veterinary Medicine, University of Dar es Salaam, Morogoro (M.L. Kyomo)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DAFCO Farm, Ruvu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Director, Livestock Development Division, Ministry of Agriculture, Dar es Salaam</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">P.M.J. Katyega, Director, Livestock Production Research Institute, Private Bag, Mpwapwa M.M. Oloufa, FAO, Morogoro  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Thailand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kasetsart University, Department of Animal Science, Bangkok (Dr. Charan Chantalakhana) Faculty of Veterinary Science, Chulalongkorn University, Henri Dunant Street, Bangkok 5 (Dr. Maneewan Kamonpatana)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Department of Obstetrics, Gynecology and Reproduction, Faculty of Veterinary Science, Chulalongkorn University, Henri Dunant Road, Bangkok 10500  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FAO Regional Office, Maliwan Mansion, Phra Atit Road, Bangkok 2 (Dr. B. K. Soni)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Office of Livestock Development Project, Tha Phra, Khon Kaen</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">National Buffalo Research and Training Center, Surin</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Trinidad</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Steve Bennett, 61 Mucurapo Road, Port-of-Spain</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Uganda</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">G. L. Corry, Director, Veterinary Research Services, P.O. Box 24, Entebbe</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">S. Mugerwa, Faculty of Agriculture, MaKerere University, P.O. Box 7062, Kampala</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">United Kingdom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">T. B. Begg, Resident Veterinary Surgeon, Howletts and Port Lympne Estates, Ltd., Port Lympne, Lympne, Kent CT21 4PD  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">P. N. Wilson, BOCM Silcock Ltd., Basing View, Basingstoke, Hampshire RG21 2EQ</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">United States</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wyland Cripe, Asst. Dean for Public Services, College of Veterinary Medicine, Box J-125, JHMHC, University of Florida, Gainesville, Florida 32610  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J. Harrington, IRI Research Institute, Inc. One Rockefeller Plaza, New York, New York 10020 James Hentges, Department of Animal Science, Room 2104 McCarty Hall, University of Florida, Gainesville, Florida 32611  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jack Howarth, School of Veterinary Medicine, University of California, Davis, California 95616</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nels M. Konnerup, 609 East Iverson Road, Camano Island, Washington 98292</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A. P. Leonards, P.O. Box 1094, Lake Charles, Louisiana 70602</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">John K. Loosli, Department of Animal Science, Room 2103 McCarty Hall, University of Florida, Gainesville, Florida 32611  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robert E. McDowell, Department of Animal Science, Frank B. Morrison Hall, Cornell University, Ithaca, New York 14853  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hugh Popenoe, International Programs in Agriculture, 3028 McCarty Hall, University of Florida, Gainesville, Florida 32611  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">William R. Pritchard, School of Veterinary Medicine, University of California, Davis, California 95616  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Venezuela</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Abelardo Ferrer D., Quinta Nueva Exparta, Avenida Jose Felix Rivas, San Bernardino, Caracas</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendix C</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Advisory Committee on Technology Innovation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUGH POPENOE, Director, International Programs in Agriculture, University of Florida, Gainesville, Florida, Chairman  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Members</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM BRADLEY, Consultant, New Hope, Pennsylvania</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HAROLD DREGNE, Director, International Center for Arid and Semi-Arid Land Studies, Texas Tech University, Lubbock, Texas  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ELMER L. GADEN, JR., Department of Chemical Engineering, University of Virginia, Charlottesville, Virginia  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ANDREW HAY, President, Calvert-Peat, Inc., New York, New York (member through 1980)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CARL N. HODGES, Director, Environmental Research Laboratory, Tucson, Arizona  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CYRUS MCKELL, Institute of Land Rehabilitation, Utah State University, Logan, Utah  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FRANCOIS MERGEN, Pinchot Professor of Forestry, School of Forestry and Environmental Studies, Yale University, New Haven, Connecticut  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DONALD L. PLUCKNETT, Consultative Group on International Agricultural Research, Washington, D.C.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THEODORE SUDIA, Deputy Science Advisor to the Secretary of Interior, Department of Interior, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Board on Science and Technology for International Development  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GEORGE BUGLIARELLO, President, Polytechnic Institute of New York, Brooklyn, New York, Chairman  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Members  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">EDWARD S. AYENSU, Director, Office of Biological Conservation, Smithsonian Institution, Washington, D.C. (member through 1980)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PEDRO BARBOSA, Department of Entomology, University of Maryland, College Park, Maryland (member through 1979)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FLETCHER L. BYROM, Chairman, Koppers Company, Inc., Pittsburgh, Pennsylvania  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HARRISON BROWN, Director, Resource Systems Institute, The East-West Center, Honolulu, Hawaii  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DORIS GALLOWAY, Department of Nutrition Sciences, University of California, Berkeley, California  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MARY E. CARTER, Associate Administrator, U.S. Department of Agriculture, Washington, D.C.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ELIZABETH COLSON, Department of Anthropology, University of California, Berkeley, California  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BREWSTER C. DENNY, Dean, Graduate School of Public Affairs, University of Washington, Seattle, Washington (member through 1980)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROLAND I. FUCHS, Chairman, Department of Geography, University of Hawaii at Manoa, Honolulu, Hawaii, ex-officio  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HERBERT I. FUSFELD, Director, Center for Science and Technology Policy, Graduate School of Public Administration, New York University, New York, New York (member through 1979)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MARTIN GOLAND, President, Southwest Research Institute, San Antonio, Texas (member through 1979)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LINCOLN GORDON, Senior Fellow, Resources for the Future, Washington, D.C. (member through September 1980)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JAMES P. GRANT, President, Overseas Development Council, Washington, D.C. (member through 1979)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">N. BRUCE HANNAY, Foreign Secretary, National Academy of Engineering, ax-officio  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GEORGE R. HERBERT, President, Research Triangle Institute, Research Triangle Park, North Carolina  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM N. HUBBARD, JR., President, The Upjohn Company, Kalamazoo, Michigan (member through 1980)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROBERT N. KREIDLER, Private Foundation Consultant, New York, New York  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RICHARD LASTER, Executive Vice President, General Foods Corporation, White Plains, New York </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN LISTON, Director, Institute for Food Science &amp; Technology, College of Fisheries, University of Washington, Seattle, Washington  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THOMAS F. MALONE, Foreign Secretary, National Academy of Sciences, ex-officio  FRANCOIS MERGEN, Pinchot Professor of Forestry, School of Forestry and Environmental Studies, Yale University, New Haven, Connecticut  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RODNEY W. NICHOLS, Executive Vice President, Rockefeller University, New York, New York (member through 1980)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DANIEL A. OKUN, Department of Environmental Sciences and Engineering, School of Public Health, University of North Carolina, Chapel Hill, North Carolina  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">E. RAY PARISER, Senior Research Scientist, Department of Nutrition and Food Science, Massachusetts Institute of Technology, Cambridge, Massachusetts  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NAMES BRIAN QUINN, Amos Tuck School of Business Administration, Dartmouth College, Hanover, New Hampshire (member through 1979)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PRISCILLA C. REINING, Director, Project on Desertification, International Division, American Association for the Advancement of Science, Washington, D.C. (member through 1980)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RALPH W. RICHARDSON, JR., Department of Horticulture, Pennsylvania State University, University Park, Pennsylvania (member through 1979)  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FREDERICK SEITZ, President Emeritus, Rockefeller University, New York, New York  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H. GUYFORD STEVER, Consultant, Washington, D.C.  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BILL C. WRIGHT, Program Officer, Africa and the Middle East, International Agricultural Development Service, New York, New York  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">VICTOR RABINOWITCH, Director</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MICHAEL G. C. McDONALD DOW, Deputy Director  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN G. HURLEY, Deputy Director</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P></FONT>
+<!--
+</Section>
+</Section>
+</Section>
+-->
+</BODY>
+</HTML>
Index: /gsdl/stable/collect/demo/import/b21wae/metadata.xml
===================================================================
--- /gsdl/stable/collect/demo/import/b21wae/metadata.xml	(revision 20131)
+++ /gsdl/stable/collect/demo/import/b21wae/metadata.xml	(revision 20131)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE DirectoryMetadata SYSTEM "http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd">
+<DirectoryMetadata>
+    <FileSet>
+        <FileName>.*</FileName>
+        <Description>
+            <Metadata name="dls.Title">The Water Buffalo: New Prospects For An Underutilized Animal (1984) (b21wae)</Metadata>
+            <Metadata mode="accumulate" name="dls.Language">English</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Animal Husbandry and Animal Product Processing|Cattle</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Animal Husbandry and Animal Product Processing|Other animals (micro-livestock, little known animals, silkworms, reptiles, frogs, snails, game, etc.)</Metadata>
+            <Metadata mode="accumulate" name="dls.Organization">BOSTID</Metadata>
+            <Metadata mode="accumulate" name="dls.Keyword">utilize the Water Buffalo more effectively</Metadata>
+        </Description>
+    </FileSet>
+</DirectoryMetadata>
Index: /gsdl/stable/collect/demo/import/b22bue/b22bue.htm
===================================================================
--- /gsdl/stable/collect/demo/import/b22bue/b22bue.htm	(revision 20131)
+++ /gsdl/stable/collect/demo/import/b22bue/b22bue.htm	(revision 20131)
@@ -0,0 +1,656 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META NAME="Generator" CONTENT="Microsoft Word 97">
+<TITLE>&lt;&lt;TOC1&gt;&gt; Butterfly Farming in Papua New Guinea </TITLE>
+</HEAD>
+<BODY>
+
+<B><FONT FACE="Arial" SIZE=2><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Butterfly Farming in Papua New Guinea</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Managing Tropical Animal Resources</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">First Printing, June 1983 </P>
+<P ALIGN="JUSTIFY">Second Printing, May, 1985 </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY">&nbsp;</P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P ALIGN="CENTER"><A NAME="Acknowledgements"></A></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Acknowledgments</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Report of an Ad Hoc Panel of the Advisory Committee on Technology Innovation </P>
+<P ALIGN="JUSTIFY">Board on Science and Technology for International Development </P>
+<P ALIGN="JUSTIFY">Office of International Affairs </P>
+<P ALIGN="JUSTIFY">National Research Council </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Cooperation with the Insect Farming and Trading Agency, Bulolo, Papua New Guinea </P>
+<P ALIGN="JUSTIFY"> </P>
+<P ALIGN="JUSTIFY">NOTICE: The project that is the subject of this report was approved by the Governing  Board of the National Research Council, whose members are drawn from the Councils of  the National Academy of Sciences, the National Academy of Engineering, and the  Institute of Medicine. The members of the committee responsible for the report were  chosen for their special competencies and with regard for appropriate balance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report has been reviewed by a group other than the authors according to the  procedures approved by a Report Review Committee consisting of members of the  National Academy of Sciences, the National Academy of Engineering, and the Institute  of Medicine.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The National Research Council was established by the National Academy of Sciences in  1916 to associate the broad community of science and technology with the Academy's  purposes of furthering knowledge and of advising the federal government. The Council  operates in accordance with general policies determined by the Academy under the  authority of its congressional charter of 1863, which establishes the Academy as a  private, nonprofit, self-governing membership corporation. The Council has become the  principal operating agency of both the National Academy of Sciences and the National  Academy of Engineering in the conduct of their services to the government, the public,  and the scientific and engineering communities. It is administered jointly by both  Academies and the Institute of Medicine. The National Academy of Engineering and the  Institute of Medicine were established in 1964 and 1970, respectively, under the charter  of the National Academy of Sciences.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Board on Science and Technology for International Development (BOSTID) of the  Office of International Affairs addresses a range of issues arising from the ways in which  science and technology in developing countries can stimulate and complement the  complex processes of social and economic development. It oversees a broad program of  bilateral workshops with scientific organizations in developing countries and conducts  special studies. BOSTID's Advisory Committee on Technology Innovation publishes  topical reviews of technical processes and biological resources of potential importance to  developing countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report has been prepared by an ad hoc advisory panel of the Advisory Committee  on Technology I innovation, Board on Science and Technology for International  Development, Office of international Affairs, National Research Council. Program costs  for the study were provided by the Office of Technical Resources, Bureau for Asia,  Agency for International Development under Grant No. ASB-0249-SS-00-1026-00 and  the Office of the Science Advisor, Agency for International Development, under Grant  No DAN/5538-GSS- 1023-00.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">First Printing, June 1983 </P>
+<P ALIGN="JUSTIFY">Second Printing, May, 1985 </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY"><A NAME="Panel_on_Butterfly_Farming_in_P"></A></P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Panel on Butterfly Farming in Papua New Guinea</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROBERT M. PYLE, Chairman, Lepidoptera Specialist Group, International  Union for Conservation of Nature and Natural Resources, Gland,  Switzerland, Chairman </P>
+<P ALIGN="JUSTIFY">EDWARD S. AYENSU, Director, Office of Biological Conservation, Smithsonian  Institution, Washington, D.C. </P>
+<P ALIGN="JUSTIFY">ARCHIE F. CARR, JR., Professor, Department of Zoology, University of Florida,  Gainesville, Florida </P>
+<P ALIGN="JUSTIFY">F. WAYNE KING, Director, Florida State Museum, C;ainesville, Florida </P>
+<P ALIGN="JUSTIFY">FRANCOlS MERGEN, Pinchot Professor of Forestry, Yale University, New  Haven, Connecticut </P>
+<P ALIGN="JUSTIFY">MICHAEL G. MORRIS, Head of Subdivision of Invertebrate Ecology,  Furzebrook Research Station, Institute of Terrestrial Ecology, Wareham,  Dorset, England </P>
+<P ALIGN="JUSTIFY">HUGH POPENOE, Director, International Programs in Agriculture, University  of Florida, Gainesville, Florida </P>
+<P ALIGN="JUSTIFY">SHELDON R. SEVERINGHAUS, Representative, The Asia Foundation, Taipei,  Taiwan </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY"><A NAME="Contributors_"></A></P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Contributors</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Papua New Guinea </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PETER CLARK, Manager, Insect Farming and Trading Agency, Bulolo </P>
+<P ALIGN="JUSTIFY">CAROLE GABARA, Wildlife Division, Department of Oro Province, Popondetta </P>
+<P ALIGN="JUSTIFY">WASAM GARARA, Wildlife Division, Department of Oro Province, Popondetta </P>
+<P ALIGN="JUSTIFY">KAROL KISOKAU, Director, Office of Environment and Conservation, Waigani </P>
+<P ALIGN="JUSTIFY">NAVU KWAPENA, Division of Wildlife, Department of Lands and  Environment, Konedobu </P>
+<P ALIGN="JUSTIFY">MIRO LAUFA, Crocodile Section, Department of Lands and Environment,  Konedobu </P>
+<P ALIGN="JUSTIFY">LEO NING, Division of Wildlife, East Sepik Province, Wewak </P>
+<P ALIGN="JUSTIFY">RODERICK ORARI, Butterfly farmer, Popondetta </P>
+<P ALIGN="JUSTIFY">MICHAEL PARSONS, Ecologist, Insect Farming and Trading Agency, Bulolo </P>
+<P ALIGN="JUSTIFY">BLU RAIRI, Butterfly farmer, Maprik  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other Countries </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">K. S. BROWN, JR., Department of Zoology, State University of Campinas, Sao  Paulo, Brazil </P>
+<P ALIGN="JUSTIFY">N. M. COLLINS, Co-compiler, Invertebrate Red Data Book, International Union  for Conservation of Nature and Natural Resources, Cambridge, England </P>
+<P ALIGN="JUSTIFY">WAYNE GAGNE, Bishop Museum, Honolulu, Hawaii </P>
+<P ALIGN="JUSTIFY">ANGUS HUTTON, Garaina Farms, Gympie, Queensland, Australia </P>
+<P ALIGN="JUSTIFY">ASHLEY C. MORTON, Department of Biology, The University, Southampton,  England </P>
+<P ALIGN="JUSTIFY">FRED PARKER, Kirwan, Queensland, Australia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">* * *</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NOEL D. VIETMEYER, Professional Associate, Board on Science and Technology for International Development, Butterfly Study Director </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">National Research Council Staff </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">F. R. RUSKIN, BOSTID Editor </P>
+<P ALIGN="JUSTIFY">MARY JANE ENGQUIST, Staff Associate </P>
+<P ALIGN="JUSTIFY">CONSTANCE REGES, Administrative Secretary </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY"><A NAME="Preface_"></A></P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Preface</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Butterfly farming is a growing new industry in Papua New Guinea, and by  turning irdwings, mauve swallowtails, and other insects into a cash crop  villagers are both earning money and practicing sound wildlife conservation.  In this unique program butterfly farming is being used to complement the  preservation of species and of habitats. In balancing the utilization of  common butterflies with the protection of the most threatened species, Papua  New Guinea is providing a model for other countries, particularly those in the  tropics. The program demonstrates how village development can become an  integral part of conservation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The panel that produced this report convened in Papua New Guinea in  May 1981. Its purpose was to investigate the concepts underlying this  project and to assess their potential for application elsewhere. Panel members  met with staff of the government's Division of Wildlife in Port Moresby and  later visited butterfly farms in Popondetta and the insect trading agency in  Bulolo. The panel is grateful to Karol Kisokau, Navu Kwapena, and Miro  Laufa of the Division of Wildlife for arranging the itinerary in Papua New  Guinea and to Peter Clark and Michael Parsons for hosting the Bulolo and  Popondetta visits.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report is one of the National Research Council series, Managing  Tropical Animal Resources. Current titles in the series are:*</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Water Buffalo: New Prospects for an Underutilized Animal (  1981 ) </P>
+<P ALIGN="JUSTIFY">· Little-Known Asian Animals with a Promising Economic Future  (1983) </P>
+<P ALIGN="JUSTIFY">· Crocodiles as a Resource for the Tropics (1983)</P>
+<P ALIGN="JUSTIFY">· Butterfly Farming in Papua New Guinea ( 1983)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These activities have been conducted under the auspices of the Advisory  Committee on Technology Innovation (ACTI) of the Board on Science and Technology for International Development, National Research  Council (see page 29). The purpose of ACT}iS the assessment of  unconventional scientific advances that might prove especially applicable to  problems of developing countries. Since its founding in 1971, it has produced  about 30 reports covering subjects as diverse as ferrocement construction  materials, the winged bean (a high-protein tropical food crop), and techniques  to provide more water for arid lands. This study adds the dimension of  conservation and ecosystem protection to ACTI'S principal concerns of  promising but neglected resources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ACTI activities are supported largely by the U.S. Agency for International  Development (AID). Program costs for this study were supported by AID'S  Bureau for Asia, and staff costs by AID'S Office of the Science Advisor, which  also made possible the free distribution of this report.  </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY">&nbsp;</P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P ALIGN="CENTER"><A NAME="BM1_Introduction_and_Summary_"></A></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">1 Introduction and Summary</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The international demand for tropical butterflies is much greater than is  generally recognized. Each year millions of them are caught and sold  throughout the world. Many buyers are scientists engaged in research on  aspects of systematics, ecology, ethology, evolution, and conservation.  Others are individuals who like expensive curios that incorporate butterflies,  such as display cases, coffee tables, wall hangings, or other objects. But  increasingly, the fragile, iridescent creatures, mounted in plastic or glass, are  used to decorate less-expensive items such as purses, trays, platters, screens,  and other common objects in Europe, North America, and Japan. In addition,  amateur butterfly collecting, which reached a peak in Victorian times, is again becoming popular.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All this has produced a strong and active market. The current trade is  estimated to be between US $10 and $20 million annually, and the demand is  rising.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Butterfly Farming in Papua New Guinea </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Remote regions of Papua New Guinea are benefiting from this burgeoning  interest in tropical insects, and several hundred villagers are rearing or  collecting butterflies, beetles, and other insects for export. The Papua New  Guinea government now considers insects a national resource, and it has  made butterfly farming part of the nation's village economic development. At Bulolo it has established an Insect Farming and Trading Agency (IFTA) to  handle the business details of a growing international trade. And Papua New  Guinea is the only country so far to specify insect conservation as a national  objective in its constitution.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Botanical research is the key to Papua New Guinea's butterfly farming  program. Local botanists and ecologists have identified the plants that the  various butterfly species use during their life cycle. The butterfly farmers  then build up their "livestock" by clearing small areas of ground  and planting leafy food plants for larvae, together with the nectar-producing  flowering plants that adult butterflies feed on. The combination of flowering  and leafy plants provides a complete habitat where butterflies find everything  they need to grow and reproduce. Therefore, most remain, and the farmer  retains his livestock without fences or walls.*</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They are among the most unusual farms in the world. Around their edges  are hibiscus and bougainvillea that attract the adult butterflies, whose  mouthparts are adapted for drinking nectar from flowers. And inside are leafy  plants, such as the strange Dutchman's pipe vine (Aristolochia tagala), on  which the caterpillars of several birdwing butterflies feed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The enriched butterfly habitat in the villager's garden attracts and holds a  breeding population that becomes a self-renewing resource. By varying the  plant species the farmer can even maintain colonies of different butterfly  species. And because insects are so prolific, some butterfly farmers are  beginning to have problems with overstocking and have had to shift larvae  from plant to plantrather like moving cattle from one field to the next as the  grazing runs out.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economic Development </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The IFTA program started in 1974 with fewer than 30 Papua New Guineans  from villages in two provinces. By 1978, more than 500 villagers in 10  provinces had been introduced to farming or collecting butterflies for export.  Since then, business has been increasing about 40 percent a year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gram for gram, exotic butterflies are far more valuable than cattle. Prices  paid by dealers in Europe, North America, and Japan range from 30 cents for  individuals of common species to around $10 for the two birdwing species  whose export is allowed. A specimen of a rarer species (for example, a female  of the mauve swallowtail Graphium weiskei) may bring as much as $50.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The project is still an embryonic activity; it is not large, as development  programs go. IFTA has only one professional staff person and two local  technicians to handle the distribution of specimens. The agency's goal is to  export between 5,000 and 10,000 specimens a month, from which the villages  can expect a return of $10,000 or more.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The agency purchases butterflies from villagers and uses them to fill orders from overseas buyers. Colorful beetles, strange-looking stick and leaf insects, and some moths and cicadas are also caught in the wild and sent to Bulolo. The profits, less 25 percent, are returned to the villagers. At the time of the panel's visit, IFTA had received about 4,000 shipments of butterflies and other insects from the rural people and had paid out about US $180,000 to purchase them. In 1979, the average farmer or collector received about $37 per box of specimens. By 1980, this had risen to about $50 per box. In 1981 it was estimated that a diligent butterfly farmer could earn an annual income of about $1,200.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Even so small an annual income is substantial in rural areas where the mean annual per capita income may be only $50. In many remote areas it is difficult to create income-producing opportunities because of illiteracy, dispersed population, and, in some cases, resistance to foreign ways.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Through butterfly farming many rural Papua New Guineans are for the first time participating in a cash economy. The product is a highvalue, low-volume crop. It brings needed or supplementary income to the people of the predominantly rural areas. Compared with farming coffee, another possible industry in Papua New Guinea's rural regions, it requires far less effort or land, and it involves minimal costs to the producer. And where a few expatriate opportunists once made small fortunes exploiting Papua New Guinea's butterflies, the profits now go to the villagers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Conservation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat loss is by far the most critical issue in butterfly conservation. If habitat changes, the animals must change, leave, or die. Usually they die, since alternative habitats are already occupied or too distant.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nearly all the world's butterfly species have suffered diminished ranges, and an estimated half of the world's butterfly populations face threats from human development. From Britain to Bhutan, the insects' habitats have come under siege. In Europe, perhaps one-third of all butterfly species are threatened, owing chiefly to the reductions in their various habitats. In California, half-a-dozen coastal butterflies have been lost since the 1860s, and an equal number are now endangered. In Madagascar and Rwanda, swallowtails and some species that occur nowhere else are being sacrificed to the clearing of forests.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The losses are much more than aesthetic, for many butterflies benefit people. They pollinate crops, are a major link in the food chain, and serve as sensitive indicators of ecological health.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A striking feature of the Papua New Guinea butterfly farming program is that it is designed to conserve and increase the species being traded. It is a pioneering conservation effort that has been endorsed by the Lepidoptera Specialist Group of the International Union for Conservation of Nature and Natural Resources. The program helps relieve pressure on endangered populations, because for successful butterfly farms the villagers must retain - and even foster - a healthy wild population on or near their land.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Insect farming also helps preserve habitats because it leaves the bulk of the land intact and it helps landowners earn money without requiring them to cut down the rain forest as they would for timber or for cocoa, coffee, or oil palm plantations. Similarly, villagers can retain their traditional hunting grounds while cropping the insects that rely on these grounds for survival.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The existence of the butterfly farming project has served to focus attention on the status of all butterfly species. In 1968 this led to a law banning the taking of even a single specimen of the seven birdwing species threatened with extinction in Papua New Guinea. These large, brilliantly colored creatures can bring as much as $1,000 each in international trade, but there is a stiff fine in Papua New Guinea for even possessing one.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Enriching habitats with butterfly food plants (notably the Dutchman's pipe vine, Aristolochia tagala) has greatly increased the numbers of Papua New Guinea's two common birdwing species, Ornithoptera priamus and Troides oblongomaculatus. Now the country is taking on the challenge of increasing the seven endangered birdwing species that are protected and banned from trade. Already the IFTA staff has found that at least one of these rare species (Ornithoptera victoriae) is easily reared on the Dutchman's pipe vine. Farms are now being designed and sited with a view to building up the populations of this giant endangered species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Conclusions</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At this stage, the importance of this pioneering activity lies not in its size, but in the new vistas it opens up for the use of tropical resources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Village Development</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In farming butterflies, Papua New Guinea is showing that indigenous wildlife resources (especially those being depleted because of their commercial value) can contribute to economic development and that the farming of indigenous animals can be fitted smoothly into traditional village life.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Providing employment in rural areas is a major problem of developing countries. And in a sense, butterflies are an "appropriate" livestock, particularly for remote areas of the tropics where other income-producing activities are difficult to establish or are harmful to traditional lifestyles and fragile environments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Butterflies may seem unusual farm animals, but to villagers in the Papua New Guinea jungle it is cattle that are exotic. The villagers live in close contact with their local insects; invariably they know much about butterfly locations, behavior, habits, life cycle, and the food eaten by the caterpillars.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Farming butterflies is proving a business to which villagers quickly adapt. Butterflies do not require the equipment or financing of a conventional farm; no capital is required, except for postage on the first shipment of specimens. Insect farming allows people to participate in the cash economy without causing disruptive changes in traditional village life. The villagers can work long and hard if they wish or they can put in only enough time to produce a little cash for necessities, leaving plenty of time for raising crops and other village activities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat Conservation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is often claimed that economic development is necessarily destructive to the environment and detrimental to conservation - that as rural societies develop, their natural surroundings must suffer. The Papua New Guinea butterfly farming project is an innovative program that demonstrates this need not be true.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The program also shows that where human needs are given attention, conservation can be successful. Elsewhere in the tropics, attempts to conserve habitat without considering the needs of the people who live nearby have often failed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In sum, the butterfly farming program demonstrates that certain natural resources can be used profitably in a way that protects the environment. The program offers a culturally appropriate use of the land; on a broad scale, it could become a force in preventing clear-felling of the forest for timber exports or the wholesale conversion of rain forest to cash-crop monocultures such as coconut, coffee, or oil palm. Most of Papua New Guinea is still covered by primary rain forest; exploiting the economic value of the insects that live there is helping safeguard this increasingly rare habitat, which is fast disappearing in most parts of the tropics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Species Conservation </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The knowledge gained from farming Papua New Guinea's butterflies has already contributed to relieving the threat of extinction from seven endangered species of birdwings. This experience could be replicated in other places where there are endangered butterfly species. Indeed, the program provides a model for nations that could profitably farm butterflies while protecting their threatened butterfly species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Extension to Other Organisms</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This project has a strategy and organizational structure that could well be applied to plants, such as rare orchids, and animals, such as crocodiles, that are endangered because of their commercial value. Indeed, using similar concepts of combining village income and conservation, the Papua New Guinea Division of Wildlife is farming crocodiles,* ruse deer, wallabies, and two native birds, the megapode and cassowary.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Through such husbandry practices, many species elsewhere might be saved from extinction, while providing income to the local people who traditionally have used the resource. Other countries should look with interest at the way Papua New Guinea is handling its wildlife enterprises. </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY"><A NAME="BM2_Butterfly_Status_and_Conserva"></A></P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">2 Butterfly Status and Conservation</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">About 100,000-150,000 species of butterflies have been described; perhaps half that number remain to be discovered. Although there are important concentrations in the Arctic and temperate regions, most species are found in the tropics. There, the diversity of colors and forms is dazzling; every imaginable combination of hue and color is displayed. And many tropical butterflies are enriched with "structural" colors, which cause the wings to flash iridescently in the sun as they bend the light they reflect.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although butterflies have long been admired and often depicted in art, they have been seriously studied only since the end of the seventeenth century. Linnaeus, in his Systema Naturae, placed the small number of butterflies then known in the single genus Papilio. Today that genus is restricted to the true swallowtails, and more than 700 genera of butterflies are recognized.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Butterfly Trade</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Last century, as knowledge of butterflies grew and methods of preserving them improved, they become popular collectors' items. Wealthy naturalists such as Rothschild and LeMoult dispatched collectors to all parts of the world for specimens. Today the trade in butterflies is even more extensive.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are three major kinds of butterfly and insect trade. In one, large numbers of common species are collected in the wild and processed for use in ornamental objects such as coasters, mats, and lampshades. This is a low-value, high-volume industry that is both labor- and capital-intensive. It frequently uses "chipped" or slightly damaged butterflies. It often sells butterflies with paper bodies and only the wings of actual insects, which seem to be acceptable to a large part of the buying public.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Taiwanese butterfly trade is an example. It operates on a large scale. At least a dozen Taiwanese factories employ scores of workers to capture and process butterflies. Estimates of annual sales vary from 15 million to 500 million butterflies. Taiwanese butterfly wings pasted onto paper bodies with pig-bristle antennae are used in ornaments and household objects from wall hangings to clear-plastic toilet seats. The bodies are recycled as pig feed. Despite this massive trade, Taiwan's wild butterfly populations seem to be remaining steady.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Similar, though smaller, industries trafficking in common butterflies are found in Korea, Malaysia, Hong Kong, Brazil, Honduras, and several African nations. The famous blue morpho butterflies of the American tropics enter the trade at the rate of some 50 million per year. Nearly all of these are the brilliant iridescent males, and biologists believe the number sold could be doubled without harming the overall population.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The second type of trade involves higher value and lower volume. This produces a vastly different product from the paper-bodied butterflies bound for novelty stores. It is exemplified by the operation in Papua New Guinea where sales are to collectors, museums, and students, and the specimens are high-quality insects in good to perfect condition, usually bearing scientific data. Because of the relatively high value per specimen, this trade can be carried on by fewer individuals in a nonfactory setting, and it is well suited to village industry, provided there is supervision and a quality-control checkpoint.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The third type of butterfly trade is for high-quality, expensive ornamental items, such as glass cases, domes, wall mounts, or jewelry containing beautiful insects. Brazil, for example, has a thriving jewelry trade based on the iridescent blue morpho butterfly. This type of trade can also furnish high-paying outlets for village-farmed insects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p08.png"></center><br>
+ Papua New Guinea.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In all three divisions of the butterfly trade, dealers fulfill an essential role. Few collectors and scientists can travel the world collecting their own specimens. Some dealers have established reputations for honesty, some have not. Exploitation of suppliers and customers alike has been rife. Few dealers are careful to attach accurate locality data to their specimens; some make serious mistakes in identifying them. (To combat this problem, British insect dealers have formed an association to monitor conservation-related activities and improve professional practice.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Generally, dealers supply specimens bred from the caterpillar or chrysalis and described as "ex pupa." Unless butterflies are caught immediately after emerging from the pupa the fragile wings tear and the scales detach to produce "worn" specimens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Butterfly Taxonomy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Classifying butterflies is difficult. Their most obvious features, the color and pattern of the wings, vary greatly; individuals and populations of the same species often look quite different. This has led to the dubious naming of many species and subspecies. And the uncertainties it causes have led some biologists, especially those working in ecology and genetics, to name populations rather than species or subspecies. However, populations frequently evolve, and this introduces a further uncertainty. Much additional work on basic butterfly systematics is needed. The knowledge gained should contribute particularly to the conservation of endangered species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Butterfly Conservation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Butterfly conservation is still in an early state of development, bedeviled by scarce or incomplete information. The conservation status of even the most thoroughly studied butterfly species is known in only a few areas. The distribution and status of most species is essentially unknown, and proposals for conservation measures are largely based on guesswork. Nevertheless, some conservation programs have been enacted. Most have concentrated on designating endangered species and banning their collection.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The greatest threat to butterflies and other insects, however, is habitat alteration. On several continents some species have already become extinct or endangered when humans altered the special environment they require. The importance of protecting butterfly habitats should not be underrated. Many species are restricted to very small areas, particularly to individual islands (Corsica, Sardinia, Jamaica, Madagascar, Sumba, the Comoros, Fiji, the Solomon Islands, Manus, and the Duke of York Islands, for instance). Such species are vulnerable to extinction because nearly all island habitats are fragile and are changing rapidly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although it is uncommon for insect species to be dangerously reduced merely by the capture of specimens, renewed commercial interest in butterflies gives rise to concern for their conservation. Most insects reproduce rapidly, and their high fecundity enables them to replace such losses in a generation or two - provided the basic environment has not been altered.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But there are certain species of butterfly that reproduce slowly and are therefore more threatened by collection. The unusual birdwing butterflies of New Guinea, for example, produce only small broods. Moreover, these rare species command higher prices. Because this makes them particularly vulnerable, legislation to protect birdwing butterflies has been instituted in both parts of New Guinea - Papua New Guinea and Irian Jaya.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Accordingly, to save Queen Alexandra's birdwing (the largest and most threatened of the birdwings) from extinction, several wildlife management areas have been set up in Popondetta on Papua New Guinea's north coast. The government is also setting up refuges, administered by village councils, to preserve and protect other birdwing butterflies and wildlife resources. This habitat conservation is an important adjunct to the butterfly farming program. </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY"><A NAME="BM3_History_and_Government_Policy"></A></P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">3 History and Government Policy</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Soon after Europeans discovered New Guinea's remarkable insect fauna around the turn of the century, collectors began arriving, and they have been coming ever since. Many were reputable professional or amateur scientists, gathering modest numbers of specimens for study and for museums, including Papua New Guinea's own national collection. Others, however, were plunderers who carried away large numbers of rare butterflies, giving little or no compensation to the local people and showing no concern for survival of the species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1966 the Papua New Guinea government responded to excessive collecting by designating seven rare birdwing butterflies as protected species. It became illegal to collect these huge, colorful birdwings, and strong measures were instituted - fines for nationals, deportation of expatriates - to halt black market trade.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the late 1960s and early 1970s commercial collecting of the other butterfly species continued piecemeal and unsupervised. Income was erratic, and expatriate dealers often paid their Papua New Guinean suppliers only a few cents for specimens that retailed for several hundred dollars in Europe and Japan.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Insect Farming and Trading Agency</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When Papua New Guinea achieved independence in 1975, the new government decreed that only nationals should profit from the country's butterfly resource. Since that time only Papua New Guineans have been able to export butterfly specimens (nonprotected species) for profit. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1978, to guarantee Papua New Guineans fair prices and stable sales, a marketing agency was established. Its purpose was to protect the resource, to foster butterfly farming, and to ensure a high-quality export product.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Modest in its beginnings, the Insect Farming and Trading Agency (IFTA) was organized by Angus Hutton, a former tea planter and amateur lepidopterist. The business side of the agency was later developed by Peter Clark, who had worked with Hutton. Identification and production of food plants was advanced by Michael Parsons, Robert Pyle, and others.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">IFTA provides a market for those Papua New Guinea nationals who farm and collect butterflies and other insects. The agency allows them to obtain fair and fixed prices, maintains quality control, and ensures that current data accompanies all specimens. It also pools the insects from many sources and fills large orders from overseas dealers. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Of the butterflies IFTA exports, about 30 percent are from village farms and 70 percent are collected in the field. However, more than 50 percent of the revenue is made up of the farmed butterflies because of their better quality.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Quality Control</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The agency strives to sell only highest-quality insects; it rejects many butterflies as substandard. Most specimens are sold as named subspecies and to identify and name them requires much skill. Staff members have been specially trained to do this. (To a large extent, the area of origin, particularly in the case of the offshore islands, defines the subspecies concerned.) Locality data, usually consisting of village, province, and month and year of collecting or emergence, is affixed to all butterfly envelopes before they are pooled at the agency.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">IFTA stores its collection by species, in simple wooden boxes kept in cupboards lit from below (to lure potential pests away from the insects and to warm the cupboards and prevent mold). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Marketing</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The agency makes up orders and dispatches them (with the required export permits) to customers "on trust." Although this is open to abuse, most buyers pay promptly and the system is easy and convenient. Careful records are kept of all suppliers, customers, and species in stock.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the time of the panel's visit, about 80 percent of the agency's business consisted of responding to requests from dealers. However, less than 10 percent of the orders received from all sources could be filled.Some requests were too small and others too specialized; in some cases the agency simply didn't have the specimens on hand (for example, a request for all the subspecies of a given butterfly). Furthermore, the agency has neither the office staff nor space to cope with every order in a business whose volume is almost doubling every two years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Field Extension</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wildlife extension officers periodically visit clients and new villages to sustain or develop enthusiasm for insect farming. They explain and demonstrate the procedures of butterfly farming and collecting and teach potential farmers how to recognize a valuable species in each of its life stages. Above all, they demonstrate how to prepare specimens for sale. This is because it is often difficult to convince farmers of the need for extreme care and delicacy in handling, and many inexperienced farmers send in bruised or hopelessly damaged specimens. Although about 500 villagers were farming butterflies at the time of the panel's visit, fewer than 50 were supplying good material regularly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These contacts are also important because the butterfly farmers easily become discouraged if no interest is shown in their work. In the Papua New Guinea countryside there is often little need for cash; people can obtain all their food, clothes, shelter, and resources from their gardens or from the bush. Money received from one shipment of butterflies may last a subsistence farmer for months, making it difficult for the agency to sustain his interest in providing regular shipments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The agency's extension officers have initiated a number of butterfly farming projects at primary, secondary, and vocational schools. These projects have proved most successful. Apart from the practical education they give students, they provide early insight into one of Papua New Guinea's most useful resources. Several vocational schools also provide training in mounting butterflies and beetles as souvenirs for tourists, as well as in the construction of hatching cages and solar driers. Beautiful wooden cabinets to hold butterflies have also been made by some teenage students.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research and Monitoring</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition to teaching Papua New Guineans to collect and farm insects, IFTA promotes research both to conserve species and to make them available in quantity. Success has already been achieved in farming the common birdwing butterflies by planting large numbers of the Dutchman's pipe (Aristolochia tagala) vines that they feed on.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The agency's staff includes an ecologist, indicating the importance of the scientific basis for conservation in this project. The ecologist is at hand to conduct research on life histories, farming methods, and management measures for rare species.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">IFTA staff are now identifying new food plants that will permit more species to be farmed. Research into the life histories of many butterflies with economic potential is well under way, so that an increasing number of species will become "farmable" and will be available in future in perfect ex pupa condition. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The sources of all specimens received by IFTA are recorded on a map so that a butterfly's range and rarity or abundance can be assessed and conservation measures implemented where necessary. In this way, even insects too damaged for sale at least have value to conservation efforts. All specimens of unusual scientific interest are lodged in the national insect collection for future study. </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY"><A NAME="BM4_Operating_a_Butterfly_Farm"></A></P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">4 Operating a Butterfly Farm</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Planting the Farm</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The key to farming butterflies is to establish a garden of the plants the various species need for their life cycles. The ideal farm area is about 0.2 hectares. This is spacious enough for growing food plants for adults and larvae and small enough to keep the plants watered, weeded, pruned, and generally well tended. Such a farm can contain about 500 vines, grown like bean plants on poles or shade trees.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is important to surround the site with a thick hedge of hibiscus, bougainvillea, ixora, poinsettia, or other nectar-bearing plants whose flowers attract adult butterflies and encourage them to remain in the area. The hedges also keep out pigs and other livestock that may damage the leafy plants inside the farm.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A good way to start a farm is to establish it in a vegetable garden. (Papua New Guinea butterfly farmers often plant butterfly vines between their rows of sweet potato or tarot) By the time the vegetables are ready to harvest, the area already has some thriving butterfly food plants and probably some winged livestock as well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the most successful butterfly food plants in Papua New Guinea is Aristolochia tagala, a vine on which the larvae of more common birdwing butterflies feed. Another is Evodea - a food plant of the large blue ulysses swallowtail and many colorful weevils.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Shade trees also can be food plants for butterflies other than birdwings and for beetles or weevils. Examples are species of Annona (such as soursop), Citrus (such as lemon), Cerbera, and Graptophyllum. Wallace's Longhorn Beetle feeds on breadfruit (Artocarpus communis). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Normally, one area of the farm is kept aside for growing seeds or cuttings. (IFTA sells seed of some suitable species.) In this nursery the butterfly food plants are watered and cared for, and unhealthy ones are easily spotted and weeded out. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p16.png"></center><br>
+ Stylized diagram of a butterfly farm:</P>
+<P ALIGN="JUSTIFY">A Hedge of hibiscus, ixora, and poinsettia to keep pigs out and provide nectar.</P>
+<P ALIGN="JUSTIFY">B Fruits trees (such as lemon).</P>
+<P ALIGN="JUSTIFY">C The aristolochia vine grown on the branches of others trees (such as leucaena), to feed    caterpillar larvae.</P>
+<P ALIGN="JUSTIFY">D Nursery area.</P>
+<P ALIGN="JUSTIFY">E A hut for tools.</P>
+<P ALIGN="JUSTIFY">(Diagram courtesy IFTA, Bulolo)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Life Cycle</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Normally, each butterfly species has a preferred food plant for its larvae. After the female has mated she searches for the correct plant and lays her eggs on or near it. In a few days the eggs hatch, and the young caterpillars usually eat their own eggshells and begin feeding on the softer leaves and shoots of the food plant.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As they grow, the caterpillars shed their skins. Each molt is called an instar, and five instars occur before a larva is big enough to pupate. Pupation is a resting stage during which the adult butterfly develops inside the hard, protective chrysalis. For pupation the larva selects the underside of a stem or leaf to protect it from rain and predators.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">After 10 days to 3 weeks, depending on the type of butterfly, the pupal case splits open and the adult insect emerges. This usually occurs before 9 o'clock in the morning. The freshly emerged adult then takes from 3 to 4 hours to expand and dry its wings before flying off to feed on nectar and to search for a mate to begin the life cycle once again. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Harvesting</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Once the farm is well established, pupae can be collected daily. Ideally, about 50 percent should be left or released. At least as many females as males should be released. Pupae that are too high to reach are usually left to emerge naturally and repopulate the farm. Others are left because they are not quite perfect.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The farmer can usually see that emergence will occur on the next day, since the pupa becomes darker in color as the adult wing and body colors develop. He then plucks off the stem or leaf to which the pupa is attached. (The soft, new pupae are not touched because this damages the adult.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He pins the leaf to a board or puts it in a net or in a small cage. Often these are kept inside to protect the pupae against pests and large predators. However, some farmers construct small houses out of bush materials to hold pupae ready for hatching. Others keep their pupae in the open and count on being able to collect the adults before they have flown away.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Care is taken to protect the specimens from ants and rats. For example, the legs of the cage are placed in bowls of water to deter ants from climbing up. The pupae are sprayed with water 2-3 times a week to speed up the hatching process and to prevent them from drying out. (Only a light spray is used; otherwise the pupa develop mold.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The pupae are best kept in a shady place so the butterflies will remain calm after hatching and will not flap and damage their wings.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Processing</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When the newly emerged butterfly has completely dried its wings, it is carefully caught by the thorax and injected with a small amount of a killing agent such as ethyl acetate or boiling water.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Small butterflies are particularly easily damaged if handled, so they are placed for about 10 minutes in a killing jar containing cotton (cotton wool) soaked with a little ethyl acetate. A layer of cardboard is placed above the cotton so that the butterflies are not stained by the solvent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The farmer places the dead butterflies in paper envelopes, being careful at all times not to touch or damage the wings. The envelopes are easily made from grease-proof paper, which the agency supplies on request.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To ensure that the butterflies will not mold, they are placed on a black plastic tray and dried in the sun, in their papers, for about 4 days. During this time they are protected from pests such as ants, and the drying trays have a screen on top to prevent the envelopes from blowing away or from being rained on.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Once properly dried, the insects, still in their envelopes, are stored in boxes, preferably airtight to prevent condensation and molding. When enough specimens have been collected, the villager packs them carefully in strong cardboard boxes (which the agency also supplies) with cotton or kapok. A few naphthalene crystals are added to keep away pests, and the box is wrapped and sent to Bulolo. </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY"><A NAME="BM5_Application_to_Other_Nations"></A></P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">5 Application to Other Nations</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As noted, the essence of the Papua New Guinea approach is the cultivation of food plants that the butterflies need to complete their life cycles. This is a process that could be replicated elsewhere, and the potential for butterfly farming exists in many countries. In fact, although Papua New Guinea is rich in butterfly species - some 700 of them - it is not unusually so. Other countries also have large numbers of species. There are, for instance 2,500 species known in Costa Rica.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are some 14,000 species of true butterflies in the world. Although there is possible competition, many countries have no overlap in species at all. As collectors and specialists usually want butterflies from many different parts of the world, the likely competition among countries exporting farmed or wild-caught butterflies is minimal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Butterflies are supplied to the trade from nearly every part of the world. But because they are most diverse in the tropics, it is likely that the best chance for success in farming them lies there. However, some temperate countries also have an abundance of particular species, and in Europe, the United States, and Japan, butterfly farming is already established on a small scale. This is mainly because many collectors like to rear their own material and they purchase eggs, caterpillars, or chrysalids instead of killed adults. Many dealers in these countries supply a few tropical species that are easy to rear, such as the orchard swallowtail (Papilio aegeus). However, this trade is generally low in volume and value, and temperate-zone butterfly farms are little more than a sideline to normal dealerships.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some general comments follow on the potential of butterfly farming in various parts of the world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Temperate regions of the Old World (Palaearctic Realm). East palaearctic species are in great demand internationally and obtainable with great difficulty. China, in particular, has species of both Parnassius and Papilio that might be farmed. However, all Parnassius species are montane to some degree and none has been farmed yet. Eurasian arctic satyrids, lesser fritillaries, and sulphurs are also in great commercial demand and could perhaps be farmed. Swallowtails are few and are frequently protected.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Tropical Africa and associated islands (Afrotropical Region). The potential for butterfly farming has not yet been considered in Africa, although the diversity of desirable species is great and the potential market extensive. This area has important swallowtails and Charaxes species (Nymphalidae), but so far as is known, no farming enterprises exist. Experimental or trial farms for butterflies are needed in different parts of Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Indian subcontinent and Southeast Asian tropics (Oriental Realm). Silk moths, such as Bombyx mori, are commercially farmed in Asia, and butterfly farming would seem to be a natural extension of this. Many Asian butterflies are supplied to dealers, especially from Taiwan and the Philippines, but there is little farming. A very large trade originates in Malaysia, especially for Rajah Brooke's birdwing (Trogonoptera brookiana). Farming is reputed to take place, but most specimens are actually collected. Desirable species of swallowtails, including the black and gold birdwings (Troides species), occur throughout the region. Species belonging to the families Nymphalidae and Pieridae are good candidates for farming, as they are in much demand from dealers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Australia, New Guinea, and associated islands to the west (Australasian Realm). Australia is not rich in butterflies, but it has some important endemic species. At least one "farm" exists in Australia, but this appears to be an offshoot of a normal dealership, which rears a few local species to supply at early stages to collectors. Farming is to be encouraged here.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">New Guinea's most coveted butterflies, which it shares with Irian Jaya, are the Ornithoptera birdwings. But almost equally desired by collectors and specialists are the Troides birdwings, concentrated to the west of New Guinea.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Temperate regions of the Americas (Nearctic Realm). There is a considerable trade in New World butterflies from nearly every family (few Lycaenidae and Hesperiidae), but almost all are caught in the wild. There is a strong market for far-northern species (Boloria, Colias, Erebia, Oenesis). Farming these might be possible among Canadian and Alaskan Indian or Eskimo groups.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Tropical regions of the Americas (Neotropical Realm). This is a likely area for the development of butterfly farming, particularly as its species are completely different from those of the tropics elsewhere. The Morpho and Agrias species of South America are much desired by collectors. It is possible that some of the highly prized morpho butterflies are already farmed (as the law, in fact, requires), but evidence is conflicting, and most biologists believe that the major supply of specimens is from wild populations. Other groups that lend themselves to farming include the swallowtails, nymphalids (including Agrias), and certain members of the family Satyridae. There are large fauna of Riodinidae and Lycaenidae that are potentially suitable for farming.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A dealer in preserved butterflies has recently set up business in the Dominican Republic, and butterfly farms have been established in Costa Rica.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· General. Butterflies in the family Riodinidae and, especially, Lycaenidae seem to be a neglected resource. Many species are relatively small but brightly colored. A major difficulty is that many Lycaenidae have to live with ants for part of their lives and this complicates their rearing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Butterfly Parks</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some regions with tourist industries are showing interest in establishing "butterfly zoos" or "butterfly jungles." These displays have live butterflies (usually farmed or reared) in artificial habitats resembling the natural ones. Some species, such as the orchard swallowtail (Papilio aegeus), respond well to such conditions. One British dealer has a "tropical jungle" in an enclosed environment in which both temperature and atmospheric pressure are regulated. A large British butterfly zoo has been established and a smaller one has been proposed. The New York Zoological Society is developing a butterfly component in its Wild Asia Hall at the Bronx Zoo, and San Francisco, Portland, Cincinnati, and Tokyo all have thriving insect zoos. Also, the Colombo Zoo in Sri Lanka has a live display and a successful program of butterfly rearing. Similar enterprise could be shown in other places with tourist industries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Starting a Butterfly Farm</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Butterfly farming is initially an ecological and botanical challenge. One must first observe, identify, and propagate the plants that the various species use for food.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Success for butterfly farmers rests on their choosing commercially attractive species. Unfortunately, ecological details of the life histories of suitable species are known in only a few cases. The prospective farmer will be largely on his own and must first develop this information.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many of the most desirable species are native to primary tropical forests, and they may need protection because of the rate at which their habitat is being destroyed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Any program to commercially exploit butterflies and other insects must either bypass the rarest, most restricted, and slowest reproducing species; farm them cautiously with a high percentage of adults released; or take them with the greatest of care. Further, there must be adequate habitat protection both in the natural state and in mixed land uses (rather than just agricultural croplands) to support the insects and furnish a continuing supply.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some competition could occur if live butterflies were exported between countries and used to establish farming enterprises. In general, however, butterflies are easier to farm in their native habitats. </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY"><A NAME="Appendix_A"></A></P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendixes</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">A Selected Readings</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Carvalho, J. C. M., and O. H. H. Mielke. 1972. The trade of butterfly wings in Brazil and its effect upon survival of the species. Proceedings 19th International Congress of Entomology (Moscow) 1 :486-488.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fenner, T. L. 1976. Aspects of butterfly conservation in Papua New Guinea, Pp. 121-127 in Ecology and Conservation in Papua New Guinea, K. P. Lamb and J. L. Gressitt eds. Pamphlet 2. Wau Ecology Institute, Papua New Guinea.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Parsons, M. n.d. Insect Farming and Trading Agency Farming Manual. Insect Farming and Trading Agency, Division of Wildlife, P.O. Box 129, Bulolo, Morobe Province, Papua New Guinea.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pyle, R. 1981. Butterflies: now you see them.... International Wildlife I I (1):4- 11.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pyle, R., M. Bentzien, and P. Opler. 1981. Insect conservation. Annual Review of Entomology 26:233-258.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pyle, R. M. and S. A. Hughes. 1978. Conservation and utilization of the insect resources of Papua New Guinea. Unpublished report, copies available from the author, see Research Contacts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Severinghaus, S. R. 1977. The butterfly industry and butterfly conservation in Taiwan. Atala 5(2):20-23.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unno, K. 1974. Taiwan's butterfly industry. Wildlife 16: 356-359.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vietmeyer, N. D. 1979. Butterfly ranching is taking wing in Papua New Guinea. Smithsonian 10(2):119-135. </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY"><A NAME="Appendix_B"></A></P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendix B</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Research Contacts</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wayne Gagne, Bishop Museum, P.O. Box 6037, Honolulu, Hawaii, 96818 USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Angus Hutton, Garaina Farms, Scrubby Creek Road, Gympie 4570, Queensland, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Insect Farming and Trading Agency, P.O. Box 129, Bulolo, Morobe Province, Papua New Guinea (Peter Clark, Manager; Michael Parsons, Ecologist)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Karol Kisokau, Director, Office of Environment and Conservation, Central Government Offices, Waigani, Papua New Guinea</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Navu Kwapena, Division of Wildlife, Department of Lands and Environment, Konedobu, Papua New Guinea</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rudi Mattoni, 9620 Heather Road, Beverly Hills, California 90210, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Michael G. Morris, Chairman, Butterfly Specialist Group, International Union for Conservation of Nature and Natural Resources, Furzebrook Research Station, Institute of Terrestrial Ecology, Wareham, Dorset BH20 5AS, England</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ashley C. Morton, Department of Biology, Building 44, The University, Southampton S09 5NH, England</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fred Parker, 717 Ross River Road, Kirwan, Queensland 4814, Australia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robert M. Pyle, Chairman, Monarch Project, Xerces Society, 369 Loop Road, Gray's River, Washington 98621, USA</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sheldon R. Severinghaus, Representative, The Asia Foundation, 42, Chien Kuo North Road, Taipei 104, Taiwan, Republic of China </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY"><A NAME="Appendix_C"></A></P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Appendix C</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Biographical Sketches of Panel Members</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">EDWARD S. AYENSU, Director of the Office of Biological Conservation, Smithsonian Institution, Washington, D.C., is currently the Secretary-General of the International Union of Biological Sciences. He received his B.A. in 1961 from Miami University in Ohio, M.Sc. from The George Washington University in 1963, and his Ph.D. in 1966 from the University of London. His research interests are in comparative anatomy and phylogeny of flowering plants, commercial timbers, histology of monocotyledons, economic botany, and tropical biology. An internationally recognized expert on tropical plants, he has published extensively in these areas and on topics relating to science, technology, and development, especially in developing countries. Dr. Ayensu was co-chairman of the Panel on Under exploited Tropical Plants of the Advisory Committee on Technology Innovation and chairs and serves as a member of many international bodies. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ARCHIE F. CARR, JR., is Graduate Research Professor in the Department of Zoology, University of Florida, Gainesville. As Technical Director of the Caribbean Conservation Corporation, he has directed a seasonal research program at the breeding ground of the green turtle at Tortuguero, Costa Rica, since 1952, with continuous grants from the National Science Foundation from 1955 to 1980, and has carried out investigations of marine turtle ecology and navigation in various parts of the world. The author of numerous papers, articles, and books, he received the Daniel Giraud Elliot Medal of the National Academy of Sciences for Handbook of Turtles and the John Burroughs Medal for The Windward Road. He is Research Associate of the American Museum of Natural History; Affiliate Curator of Natural Sciences, Florida State Museum; Chairman of the Marine Turtle Specialist Group of the Survival Service Commission, International Union for the Conservation of Nature; Honorary Consultant of the World Wildlife Fund; Fellow of the Linnean Society of London; Fellow of the American Fisheries Society; and a member of Phi Beta Kappa and Sigma Xi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1973 he was awarded a gold medal from the World Wildlife Fund for the application of scientific findings to the conservation of marine turtles. In 1975 he received the Edward W. Browning Award for achievement in biological conservation. In 1978 Dr. Carr was awarded the Gold Medal of the New York Zoological Society for contributions to natural science and conservation; in 1978 he became Officer of the Order of the Golden Ark (The Netherlands).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">F. WAYNE KING is the Director of the Florida State Museum, Gainesville. He received a B.S. in 1957 and an M.S. in 1961 from the University of Florida and a Ph.D. from 1966 from the University of Miami. His research interests are in wildlife conservation and habitat preservation, impact of international trade on wildlife populations, and ecology and behavior of reptile populations. He worked at the New York Zoological Society from 1967 to 1975. As an international wildlife consultant, Dr. King has received honors from the Dominican Republic, the American Association of Zoological Parks and Aquariums, and from H.R.H. Prince Bernhard of The Netherlands. He has served on committees advising the State Department and the International Union for Conservation of Nature and Natural Resources on policies regarding the trade of crocodile skins, turtle products, and other wildlife materials. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FRANCOlS MERGEN, Pinchot Professor of Forestry and Professor of Forest Genetics, Yale University, was Dean of the School of Forestry and Environmental Studies at Yale from 1965 to 1975. He received a B.A. from Luxembourg College and a B.Sc.F. from the University of New Brunswick in 1950, an M.F. in ecology in 1951, and a Ph.D. in forest genetics from Yale in 1954. He is especially knowledgeable about francophone Africa and was chairman of the Sahel program of the Board on Science and Technology for International Development and a member of the Advisory Committee on Technology Innovation. From 1960 to 1965 he was research collaborator at the Brookhaven National Laboratory. In 1966 he was the recipient of the Award for Outstanding Achievement in Biological Research from the Society of American Foresters and in 1975 was Distinguished Professor (Fulbright-Hays Program) in Yugoslavia. Before joining the Yale faculty, he served as project leader in forest genetics for the U.S. Forest Service in Florida. He has served as a consultant to FAO, various foreign governments, and private forestry companies, and he has traveled extensively in the tropical countries of Asia, Africa, and Latin America. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MICHAEL G. MORRIS is head of the Furzebrook Research Station of the Institute of Terrestrial Ecology (National Environment Research Council, U.K.). He received a B.A. in natural sciences (zoology) at the University of Cambridge of 1958, M.A. in 1962, and received his Ph.D. from London University in research on the integrated control of orchard pests. Dr. Morris worked at Monks Wood Experimental Station on the effects of grassland management on populations of invertebrates and developed a strong interest in community and applied ecology, particularly the conservation of insect populations. Recently he has become involved with problems of butterfly conservation and resource utilization. He is Secretary of the Joint Committee for the Conservation of British Insects, a Vice-Chairman of the Lepidoptera Specialist Group of lUCN'S Survival Commission, and Chairman of the Habitat and Species Protection Committee of SEL (Societal Europaea Lepidoptero-Logica). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUGH L. POPENOE is Professor of Soils, Agronomy, Botany, and Geography and Director of the Center for Tropical Agriculture and International Programs (Agriculture) at the University of Florida. He received his B.S. from the University of California at Davis in 1951 and his Ph.D. in soils from the University of Florida in 1960. His principal research interest has been in the area of tropical agriculture and land use. His early work on shifting cultivation is one of the major contributions to this sytem. He has traveled and worked in most of the countries in the tropical areas of Latin America, Asia, and Africa. He is past Chairman of the Board of Trustees of the Escuela Agricola Panamericana in Honduras, Visiting Lecturer on Tropical Public Health at the Harvard School of Public Health, and a Fellow of the American Association for the Advancement of Science, the American Society of Agronomy, the America Geographical Society, and the International Soils Science Society. He is Chairman of the Advisory Committee for Technology Innovation and a member of the Board on Science and Technology for International Development. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROBERT MICHAEL PYLE, a writer and consulting lepidopterist based in Gray's River, Washington, has served since 1979 as Co-Compiler of the lUCN Invertebrate Red Data Book. In this capacity he is consultant to the Conservation Monitoring Centre in Cambridge, England. After receiving his B.S. and M.S. at the University of Washington, he took his Ph.D. through the School of Forestry and Environmental Studies at Yale University in 1976. He worked for the Government of Papua New Guinea on the conservation and utilization of insect resources and then with the Nature Conservancy as Northwest Land Steward. A </P>
+<P ALIGN="JUSTIFY">former Fulbright Scholar to the United Kingdom, Dr. Pyle subsequently founded the Xerces Society for conservation of beneficial insects and their habitats. He has been chairman of IUCN'S Lepidoptera Specialist Group (Species Survival Commission) since 1976. His publications include the Audubon Society Field Guide to North American Butterflies. A comprehensive book on insect conservation in his next project.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SHELDON R. SEVERINGHAUS received his Ph.D. from Cornell University in 1977 in natural resources management. He has worked on various wildlife research projects in Asia since 1964 and is representative for the Asia Foundation in Taiwan. He has published articles on butterfly conservation and wildlife industries in Taiwan, where he has been studying the butterfly and wildlife farming projects. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NOEL D. VIETMEYER, staff officer for this study, is Professional Associate of the Board on Science and Technology for International Development. A New Zealander with the Ph.D. in organic chemistry from the University of California, Berkeley, he now works on innovations in science that are important for developing countries. </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY"><A NAME="Advisory_Committee_on_Technolog"></A></P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Advisory Committee on Technology Innovation</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUGH POPENOE, Director, International Programs in Agriculture, University of Florida, Gainesville, Florida, Chairman </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Members</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM BRADLEY, Consultant, New Hope, Pennsylvania </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HAROLD DREGNE, Director, International Center for Arid and Semi-Arid Land Studies, Texas Tech University, Lubbock, Texas (member through 1981) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ELMER L.GADEN,JR., Department of Chemical Engineering, University of Virginia, Charlottesville, Virginia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CARL N. HODGES, Director, Environmental Research Laboratory, Tucson, Arizona </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CYRUS MCKELL, Native Plants, Inc., Salt Lake City, Utah </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FRANCOIS MERGEN, Pinchot Professor of Forestry, School of Forestry and Environmental Studies, Yale University, New Haven, Connecticut (member through 1982) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DONALD L. PLUCKNETT, Consultative Group on International Agricultural Research, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THEODORE SUDIA, Deputy Science Advisor to the Secretary of Interior, Department of Interior, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+</FONT><FONT FACE="Arial" SIZE=2 COLOR="#0000ff"><P ALIGN="JUSTIFY"><A NAME="Board_on_Science_and_Technology"></A></P>
+</FONT><B><FONT FACE="Arial" SIZE=2><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Board on Science and Technology for International Development</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GEORGE BUGLIARELLO, President, Polytechnic Institute of New York, Brooklyn, New York, Chairman </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Members</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SAMUEL P. ASPER, Educational Commission for Foreign Medical Graduates, Philadelphia, Pennsylvania </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DAVID BELL, Department of Population Sciences, Harvard School of Public Health, Boston, Massachusetts </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LEONARD BERRY, Professor, Graduate School of Geography, Clark University, Worcester, Massachusetts </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ERNEST J. BRISKEY, Dean, School of Agriculture, Oregon State University, Corvallis, Oregon </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HARRISON S. BROWN, Director, Resources Systems Institute, East-West Center, Honolulu, Hawaii </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROBERT H. BURRIS, Department of Biochemistry, University of Wisconsin, Madison, Wisconsin </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CLAUDIA JEAN CARR, Associate Professor, Conservation and Resource Studies, University of California at Berkeley, Berkeley, California </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NATE FIELDS, Director, Developing Markets, Control Data Corporation, Minneapolis, Minnesota </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ROLAND J. FUCHS, Chairman, Department of Geography, University of Hawaii at Manoa, Honolulu, Hawaii </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ELMER L. GADEN, JR., Department of Chemical Engineering, University of Virginia, Charlottesville, Virginia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JOHN HOWARD GIBBONS, Director, U.S. Congress, Office of Technology Assessment, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">N. BRUCE HANNAY, Foreign Secretary, National Academy of Engineering, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM HUGHES, Director, Engineering Energy Laboratory, Oklahoma State University, Stillwater, Oklahoma </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WILLIAM A. W. KREBS, Vice President, Arthur D. Little, Inc., Acorn Park, Cambridge, Massachusetts </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GEORGE 1. LYTHCOTT, University of Wisconsin, School of Medicine, Madison, Wisconsin </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">JANICE E. PERLMAN, Executive Director, Committee for a New New York, New York City Partnership, New York, New York </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUGH POPENOE, Director, International Programs in Agriculture, University of Florida, Gainesville, Florida </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FREDERICK C. ROBBINS, President, Institute of Medicine, National Academy of Sciences, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WALTER A. ROSENBLITH, Foreign Secretary, National Academy of Sciences, Washington, D.C. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FREDERICK SEITZ, President Emeritus, The Rockefeller University, New York, New York </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RALPH HERBERT SMUCKLER, Dean of International Studies and Programs, Michigan State University, East Lansing, Michigan </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GILBERT F. WHITE, Institute of Behavioral Science, University of Colorado, Boulder, Colorado </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BILL C. WRIGHT, Assistant Dean for International Programs, Oklahoma State University, Stillwater, Oklahoma </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">JOHN C. HURLEY, Director</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MICHAEL G. C. McDONALD DOW, Associate Director/Studies </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MICHAEL P. GREENE, Associate Director/Research Grants </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P></FONT>
+<!--
+</Section>
+</Section>
+-->
+</BODY>
+</HTML>
Index: /gsdl/stable/collect/demo/import/b22bue/metadata.xml
===================================================================
--- /gsdl/stable/collect/demo/import/b22bue/metadata.xml	(revision 20131)
+++ /gsdl/stable/collect/demo/import/b22bue/metadata.xml	(revision 20131)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE DirectoryMetadata SYSTEM "http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd">
+<DirectoryMetadata>
+    <FileSet>
+        <FileName>.*</FileName>
+        <Description>
+            <Metadata name="dls.Title">Butterfly Farming in Papua New Guinea (b22bue)</Metadata>
+            <Metadata mode="accumulate" name="dls.Language">English</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Animal Husbandry and Animal Product Processing|Other animals (micro-livestock, little known animals, silkworms, reptiles, frogs, snails, game, etc.)</Metadata>
+            <Metadata mode="accumulate" name="dls.Organization">BOSTID</Metadata>
+            <Metadata mode="accumulate" name="dls.Keyword">start a butterfly farm</Metadata>
+        </Description>
+    </FileSet>
+</DirectoryMetadata>
Index: /gsdl/stable/collect/demo/import/ec158e/ec158e.htm
===================================================================
--- /gsdl/stable/collect/demo/import/ec158e/ec158e.htm	(revision 20131)
+++ /gsdl/stable/collect/demo/import/ec158e/ec158e.htm	(revision 20131)
@@ -0,0 +1,2772 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META NAME="Generator" CONTENT="Microsoft Word 97">
+<TITLE>&lt;&lt;TOC1&gt;&gt; The Courier - N°158 - July - August 1996 Dossier Communication and the media - Country report Cape Verde</TITLE>
+</HEAD>
+<BODY>
+
+<B><FONT FACE="Arial" SIZE=2><P ALIGN="JUSTIFY"></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">The Courier - N°158 - July - August 1996 Dossier Communication and the media - Country report Cape Verde</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">AFRICA-CARIBBEAN-PACIFIC - EUROPEAN UNION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dossier</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Communication and the media</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Press freedom, regarded as a fundamental human right, is also a key component in the democratization process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With the help of experts in the field, we look at what various organizations are doing to combat censorship and promote a free press in ACP countries and elsewhere.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We also highlight the new trend of donor support for projects aimed at promoting press freedom. These include, notably, provisions for the training of journalists. And as new means of communication, such as the World Wide Web, develop, we consider what is being done to prevent the opening up of a new divide - this time between the 'information rich' end the 'information poor'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Country report</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cape Verde</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Among the least-developed countries, Cape Verde is seen as a model of good governance and stable democracy. It is also admired for its perseverance in the struggle against the exigencies of history and climate. The country suffers from almost permanent drought and has virtually no regular supplies of fresh water.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Its history has been punctuated by serious famines and while the people are no longer hungry, they still face formidable economic difficulties.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cape Verde produces just 10% of what it consumes and its exports are one fifteenth of its imports. The one bright spot is in services, where it enjoys a positive trade balance. This sector (in particular, international transport and tourism), together with the country's cultural industries, offer the best hope for future development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Meeting point</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Robert M&eacute;nard, Director of 'Reporters sans fronti&egrave;res'</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'Combating attacks on press freedom</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'Reporters sans fronti&egrave;res' was founded in June 1985 in Montpellier where Robert M&eacute;nard was working as a journalist with Radio France. Now based in Paris, RSF has two main policy areas. In the first place it alerts international public opinion and the media to situations involving violations of press freedom (via publications such as 'RSF News letter' the Annual Report and specific books and reports). Secondly, RSF actively intervenes by sending letters of protest to official bodies and assisting victims. Last year RSF dealt with more than 350 cases involving the press throughout the world. The organisation's ambition, according to Mr M&eacute;nard, is to be a kind of Amnesty International in the press field. The interview began with Mr M&eacute;nard giving a detailed description of RSF's work.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - We do two things - we report violations of press freedom and help journalists who are the victims of such violations. Take the former Yugoslavia, for example. It would have been unthinkable to monitor what was going on in that war-torn country without, at the same time, helping the media who were victims of the repression. So we sent over lawyers to help in trials involving the press, helped the families of imprisoned journalists and gave general assistance to the media. In the case of Oslabodenje, the Sarajevo daily, this went on for four years. We did similar work in Rwanda where RSF helped the media to get back on its feet after the genocide. In Algeria at the moment we are involved in aiding  journalists who are obstructed when doing their work. We also give help in Europe - currently to refugee journalists in Belgium, France, Spain, Switzarland and Germany. That's basically what we do; reporting violations of press freedom and helping those who are the victims of it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Do you work with other organisations, for example the United Nations ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - We work with various types of organisations. We have daily contact with other NGOs specialising in press freedom, such as Article 19 in London and the Committee for the Protection of Journalists in New York, to give just two examples. We also have contacts with NGOs involved in human rights issues in general and, above all, with Amnesty International.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Then there are our links with international organisations and, first and foremost, with the UN system. RSF has submitted reports in response to requests from various organisations, ranging from the UN Committee for Human Rights to UNESCO. We also work with the Council of Europe and the Organisation of African Unity. But our closest  relationship is with the European Union, or two reasons; firstly because it is RSF's main financial backer and secondly Because the EU enables us to do three things. It has helped us set up and has Financed a vast network of correspondents in 130 different countries and, to my mind, this is the most important thing in terms of defending human rights and press freedom. We also publish reports, which we write in response to EU requests, on press freedom in one country or another and which are made available to the EU and European Parliament. Our third \ink comes in the form of assistance. We manage an aid fund to help where the press is in difficulties, and the money is provided by the Union.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-You have mentioned a network of correspondents which has been set up. How does it operate ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - It is a network of people who are in daily contact with RSF and who tip us off when a situation requiring our attention arises. Whenever there is a violation of press freedom in a country where the network operates, our correspondent lets us know - that's the first priority. Then, they make enquiries at our request. The third stage is to set up events. For example May 3 was World Press Freedom Day and, on that day, in about 20 countries in Africa, our correspondents organised events on the theme of press freedom. A fourth aspect of our correspondents' work is that they are often responsible on the ground for helping journalists in difficulty. They also help the media in general because we give them documents and supply them with information which they distribute in their particular country. Their task, therefore, is to alert us to a situation, meet our requirements for information and, on our behalf, physically to assist people on the ground, set up events and disseminate information.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Are the correspondents all nationals of the countries in which they work ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Yes. Also, about 90% of them are joumalists and they are all paid for what they do. Their relationship with us is clear-cut. It is very important for them to be paid because this means that   we can ask certain things of them. If you   work as a volunteer no-one can give you  a deadline to produce such and such a   document. In our case, we pay them to   do this work for RSF.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Do you choose countries where the situation is already problematic ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Unfortunately, problems exist in many countries. Less than half the countries in the world show any degree of respect for press freedom and that means we have a great deal of work. In addition, information arriving at RSF from the correspondents is distributed to other organisations. We have set up a system called Infex which is an electronic mailbox.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All RSF's information is put on a computerised system and immediately disseminated to all the organisations involved in the defence of human rights, and press freedom in particular.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· So the technological revolution is a positive thing as far as you are concerned ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Absolutely. Both the Imais and Internet systems are unbelievably useful tools which have completely revolutionised our work. For example, RSF might protest about the situation in some country or other. Take China, for example - we regularly lodge protests against the lack of press freedom there. There are 17 journalists in jail, no freedom for the press and a great many problems. However, people in China are not aware of what we do and in order to get information they have to listen to international radio stations. On the Internet, RSF's services are available in French, English and Spanish and it is consulted by people the world over. It is thus one of their sources of information. Another example would be a case where we set up an operation and inundate a number of people in a particular country with faxes, in order to pass on the information. Modern technology enables us to break down the fortresses which totalitarian or dictatorial regimes attempt to construct around themselves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- RSF has just published its 1996 Report. What do you have to say regarding the current position of press freedom ? Has progress been made ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> </P>
+<P ALIGN="JUSTIFY"> - I would say two things. In the long term, the situation is improving. If you remember, 25 years ago, the regimes in half the countries in Latin America were dictatorships, communism dominated half of Europe and nearly all of Africa had single-party systems. Even in Europe, there were dictatorships - in Spain, Portugal and Greece. So we cannot deny that there has been progress. The problem is that, for three or four years now, there has been a noticeable rise in new threats to press freedom, and this is a great source of concern to us. Here I am thinking of the rise in power of fundamentalist movements, particularly religious fundamentalism. In a number of countries nowadays - the best example, or perhaps I should say the worst example, is Algeria - journalists are not only threatened by the state but are being killed by armed Islamic groups. The rise in religious fundamentalism is indeed a real danger.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The second type of threat confronting the press is the increased influence of mafia-type criminals. You will, of course, have heard about drug trafficking in places like Colombia or Peru. Nowadays, in some countries where communism has been overthrown, the big threat comes from these criminal gangs. Not so long ago in Russia, the star presenter on the main TV channel was killed because he got in the way of 'Mafia' interests.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The third threat comes from uncontrolled actions by groups fighting for autonomy or independence, like the Kurdish movement in Turkey (the PKK), and a number of separatist groups in India. The EU is no stranger to this either</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - ETA poses a continual threat to the press, as do members of the FLNC in Corsica. It is only a few months since members of the latter group machine gunned a journalist's house. A fourth and new kind of threat, particularly in countries with a democratic system, comes from the rise of the extreme right.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lastly, a point I draw particular attention to in our recent report is, in fact, a dual phenomenon. On the one hand there are states which pass laws under which any criticism is a crime and may lead to prosecution. An example of this is Egypt where the government has enacted a law which has led to charges being brought against some 60 journalists since summer 1995. On the other hand, there are states where justice simply does not operate and there is no will to make it function.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Last year, 51 journalists were killed and a number of others were attacked, but there has not been a single trial or conviction. It is a real culture of impunity. In some countries, the justice system either does not operate, or it is not independent. In such places, the authorities are reluctant to identify and prosecute those responsible for attacks on journalists.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· RSFcurrently has project running in Rwanda, in collaboration with the EU. Could you tell us something about this ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The EU is helping us to meet a wide range of needs in Rwanda, as well as in Burundi, where sadly, the situation is rather similar. In Rwanda, there are those who governed the country before the genocide and those in power at the moment. There was a specific problem there in that nearly half of Rwanda's journalists were killed during the genocide - 49 out of about 100. We had virtually to reconstruct the press system and the EU gave us the means to do this.The press currently has difficulties vis-&agrave;-vis the authorities but it is attempting to do its job.  in Burundi, where our work is of a more conventional type, we see continuing attacks on press freedom. There, RSF is trying to resist the pressure, again supported by the EU. In fact, thanks to the EU, we are helping a   number of countries' media to survive despite difficult conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another quite new problem is that before and during the genocide in Rwanda, the media were used as vehicles for disseminating hatred. They issued calls for people to kill their compatriots, in this instance the Tutsis, and the language they used was unbelievably violent. On Radio Mille Collines, presenters would say - and I quote; 'The graves are not full yet'. They would give out the addresses of people who had to be killed and when the murders had been carried out they would actually say, 'You killed them too quickly - you should have killed them more slowly to make them suffer more', or, 'You didn't kill the children, go back and kill the childreni. We actually have recordings of statements like this.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In such a situation, journalists must be made to answer for what they have done and be brought to justice.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU has helped us conduct a number of surveys which will enable the international criminal court in The Hague to charge Rwandan journalists with complicity or incitement to genocide. We expect this to take place in the very near future.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Of course in Rwanda, all that is in the past but the same thing is happening today in Burundi where there is a radio station called 'Radio Democracy' - what a joke! A number of journalists there are issuing calls for people to be killed and we have a copy of one of their newspapers whose front page offers a cash reward to anyone who kills such and such a person. This is not journalism. RSF has lodged complaints against these people and one of these 'journalists' has just been charged.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We are doing three things in Rwanda and Burundi: denouncing violations of press freedom by the authorities, helping media victims and - something new - reporting what has come to be known as 'the media of hatred'. Unfortunately, this type of media is not restricted to Rwanda and Burundi. it is a phenomenon that we see in a number of African countries, in the former Yugoslavia, the Caucasus and the</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Middle East. Perhaps you are aware that the 50th anniversary of the Nuremberg trials has just passed ? But did you know that there were two journalists among the accused? The press has forgotten that journalists played a part in the rise of Nazism. RSF is pointing out that the same thing is happening today in many countries and we have to fight it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> 'The EU is a  perfect partner</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Given what you have just said, should restrictions be placed on press freedom ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - This is a very complex subject. You have to remember that international texts, particularly the convention on civil and political rights, place restrictions on press freedom. Article 19, which defines press freedom, stipulates that there are certain limits to this and Article 20 forbids any dissemination of racist or antisemitic ideas and any incitements to violence.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">RSF has two things to say. First, governments which have signed the agreements must ensure they are observed. These set limits. Journalists are not above the law and they must be punished when they say certain things. So states must face up to their responsibilities and apply the treaties they have signed. Second, I feel that the international community, and Europe in particular - when it signs agreements or gives aid to third countries - should demand that they respect press freedom but clamp down on the media of hatred.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· RSF has just published a draft model legislation governing the press. In preparing this, were you influenced by your experience of the extremist media ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Perhaps we were influenced too much. I am my own worst critic. We sent a mission to Rwanda before the genocide but did not appreciate the full effects of the evil disseminated by the media of hatred, particularly Radio Mille </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Collines. We underestimated the situation and are concerned at what is happening. We believe there must be express limits on press freedom and this draft framework law is one way of formulating such restrictions. It is not necessarily the best way of going about things, but our profession has to ask itself questions regarding the definition of press freedom and the limits we must not exceed. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Are you satisfied with what the EU is doing in this area ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The EU is a perfect partner and has never exerted any pressure. With the Union, we are able to do things that would not be possible with individual Member-State government because the latter conduct foreign policy in defence of certain interests. Each country has its own cultural history linguistic links or links arising out of former colonial times which prevent it financing RSF's studies unconditionally. As far as our missions are concerned, RSF decides what it wants to do and we send our reports to the EU. They have also granted us a budget enabling us to give immediate aid to people in difficulty. This is the most positive action possible If the EU were not there, there would unfortunately be no-one else to finance an organisation like ours. 60% of our budget comes from the Union, 20%from various companies. We generate the remaining 20% ourselves through sales of books and contributions. Because the EU is a grouping of governments, the Commission has some room for manoeuvre. This is the only possible kind of support for organisations like RSF and, if it were not there, it would be the end for the people whom RSF supports.  interview by Dorothy Morrissey</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">ACP</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">The economy of Cameroon: Better prospects but still a long way to go</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is an astonishing sight to behold during the rainy season. As you drive along the road from Yaound&eacute; to Bamenda, you come to a point where human habitation starts - and it then continues unbroken for more than 100 kiLom&eacute;tres. Just before Bafoussam, and as far as the eye can see, every patch of land is cultivated. Bananas, oranges, mangoes, sugarcane, cassava, palm trees, groundnuts and maize grow luxuriantly in open fields and in the front and back gardens of many houses. This route, of course, takes you mainly through the western part of Cameroon, home to the Bamilelr&eacute;s, recognised as one of the country's most enterprising and industrious ethnic groups. The population density here is 200 per km2 as opposed to 1 per km2 in the East.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The impact of this widespread farming, carried out by a large number of smallholders, is visible in the local markets, whether in Bafoussam, Mbouda or Bamenda. There, the stalls overflow with fruits and vegetables and prices are very low - a virtual paradise for the middlemen whose unmistakable presence is signalled by the significant number of trucks loading the produce for distribution throughout the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These scenes come as no surprise to the long-time observer of Cameroon's economy. The country achieved virtual self-sufficiency in food over 15 years ago. It is one of the few African countries to have been able to do this, thanks both to its physical  endowments and an early recognition of its agricultural vocation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cameroon is often described as a microcosm of Africa, not just in terms of its make-up of English- and French speaking communities, but because it enjoys almost all the continent's climatic conditions. The south is equatorial, with two rainy seasons and two dry seasons of equal duration, the centre is Savannah country with one rainy season and one dry season, while the extreme north (part of the Sahel) is hot and dry. The country has a very good supply of rainfall - from 5000 mm annually in the southwest to around 600 mm near Lake Chad.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Such varied climates favour the cultivation of a variety of crops. Timber is  produced mainly in the southern provinces while palm oil, tea, cocoa, coffee, rubber, timber and foodcrops are produced in the southwestern and western areas. The central and north provinces specialise in cattle and cotton production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Concentration on agriculture</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cameroon has, not surprisingly, concentrated on agriculture. Indeed the government has given top priority to the sector in all its development plans   since independence in 1960. It has been involved in the marketing of the main export crops and has provided subsidies to farmers in the form of low-priced fertilisers and pesticides for their cocoa, coffee, rubber, palm oil, etc. Almost three-quarters of the working population (the majority of whom are smallholders) are engaged in farming. And despite a low level of mechanisation, they are very efficient. The rate of growth in food outstrips the rate of population growth. Only a few largescale farmers or firms are involved in the production of cash crops.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Until the early 1980s, when oil came into the picture, these large scalefarmers and firms amounted for more than 70% of export earnings, 40% of state revenue and 32% of the Gross Domestic Product. The plan initially was to use oil revenues to further boost and transform agriculture. However, the dramatic increase in the country's oil production, combined with much higher world petroleum prices during the first half of the 1980s, made the sector not only Cameroon's biggest export earner, but also, in a certain sense, a 'spoiler' for agriculture. Increased revenues enabled the government to maintain the level of prices paid to farmers, even though world prices had slumped to disastrous levels. This created distortions in the market. (Later, when the oil price slumped, and revenues dropped sharply, producer prices were also reduced, bringing them closer into line with international prices.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agriculture's contribution to GDP declined steadily to around 21 % in 1985, rose to 27% in 1989 and has hovered around 30% ever since. The sector's share of export earnings has also fallen to about 40% of total exports by value.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite this, Cameroon's agriculture remains, comparatively, in a much better shape than that of most African countries. Indeed, it contributed in large measure to the country's reputation as one of Africa's economic successes in the 1980s. During that decade, growth averaged 8% per annum. However, the period was also marked by dramatic increases in oil revenues which induced  significant policy changes as well as leading to maladministration. The government paid less attention to taxation and customs duties as sources of income and turned a virtual blind eye to smuggling which harmed the manufacturing sector. The civil service, on the other hand, expanded beyond reason, a phenomenon that some have attributed to patronage by the ruling single party.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Boom in public expenditure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Protected somewhat against fluctuations in earnings from export crops, by a strong but overvalued CFA franc, the government embarked on a wide range of capital expenditure and imports. Then, in 1987, international oil prices fell as dramatically as they had risen earlier in the decade. At the time, public spending was running at CFAF 8 billion - well above the CFAF 5.6bn the country actually earned. Revenues from oil continued their downward slide to CFAF4.5 bn in 1988, CFAF 2.8 bn in 1991 and CFAF 2.5 bn in 1994. 1995 saw a modest rise to CFAF 3 bn.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">1987 thus marked the beginning of a rapid deterioration in Cameroon's financial situation. In the period which followed, civil servants' salaries were unpaid for months, several of the country's foreign missions were left without resources and both domestic and foreign debts worsened. In 1993, the government owed commercial banks around CFAF 3.3bn. Its external debt stood at around $7.5bn with a service ratio of more than 25% of foreign exchange earnings. The devaluation of the CFA franc in January 1994 improved the internal debt situation significantly. In February, the government signed a letter of intent with the IMF after agreeing to a series of reforms which included, among other things, rationalising the banking and insurance sectors, raising revenue from non-oil sources, bringing inflation down and reducing the budget deficit. In return the IMF provided a stand-by loan equivalent to CFAF 1.4bn. However, the agreement was suspended just a few months later when the Fund reached the conclusion that the government lacked the will to carry the reforms through. The 1994/95 budget foresaw a deficit of 4.5% of GDP - well above the IMF's guideline of 1.5%.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Meanwhile the country's financial situation had become so critical that it could no longer service its debts, most notably, those it owed to the World Bank. France, which had traditionally been ready to come to the rescue, refused to bail Cameroon out and it finally dawned on the authorities that structural adjustment was unavoidable. When, in September 1995, talks resumed with the IMF, the commitment to adjustment was no longer in doubt. The government agreed, in addition to fiscal reforms, to liberalise trade in cocoa, coffee and timber, to prune the civil service and to privatise state enterprises which dominate the industrial sector.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Commitment to reforms</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Since then the reform process has been in full swing. The first and most important task has been to improve the government's financial position. The civil service, which employs more than 175000 people, is gradually being reduced and salaries have been cut. Trade is also being liberalised and subsidies are being removed. The 1995/96 budget, unveiled in June last year, was welcomed by the IMF. It included, for the first time in a long while, increases in income tax and a widening of tax bands. A series of measures have also been introduced to combat tax evasion and fraud. External signs of wealth, water and electricity consumption, and telephone bills are now being used as means of assessing income tax.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Responsibility for the collection of customs duties has been removed from the Customs Department which was often accused in the past of corruption and inefficiency. The task has been given instead to a Swiss-based preshipment inspection company. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The donor community has responded positively. With French assistance, the government has been able to clear its outstanding debt to the World Bank. The IMF has provided a stand-by credit facility of $101 million in support of the adjustment programme for 1995/ 96 and debts to the Paris Club covering the same period have been rescheduled. In addition, now that Cameroon has been reclassified as a poor country, it is entitled to benefit from the terms of the Naples Agreement, which allow for up to 67% of debts to western govemments to be written off. A number of creditor nations have either forgiven the country its debts or have reduced them substantially. More loans have come from France and a number of other donors, including the World Bank and the European Community.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EC is financing a series of projects within the framework of the adjustment programme, including the restructuring of the civil service and preparation of the ground for privatisation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lately though, the donor community has been showing signs of disenchantment, following allegations of misuse of funds and perhaps even outright embezzlement. Last March, an IMF mission to Yaound&eacute; failed to obtain an adequate explanation concerning the allocation of certain sums. The result, at the time The Courier went to press, was that an IMF loan for settlement of Cameroon's debt to the African Development Bank was being held up.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dealing with the negative social impact</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p07a.png"></center><br>
+ Figure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The sudden devaluation of the CFA franc in January 1994 halved Cameroon's purchasing power overnight. The government has since cut wages twice. The average salary of a top civil servant, which stood at around CFAF 300 000 before devaluation, is now less than CFAF 180 000 while the lowest paid government employees receive just CFAF 30 000. At the same time, prices, particularly of imported manufactured goods and inputs, have risen sharply. Increases of up to 150% have been  recorded. By way of example, the price of a baguette (french bread), which was only CFAF 80 in January 1994 had risen to CFAF 130 by March 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although there is considerable hardship, Cameroonians are a great deal more fortunate than fellow Africans in many other countries undergoing a similar adjustment process. Staple food remains cheap and affordable to the vast majority, thanks to the continuing strength of agriculture. As a result, there are few, if any, cases of malnutrition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A number of donors, including China, Belgium and the EC, are concentrating on health and education with the specific aim of reducing the negative social impact of adjustment. The EC, for example, has a project designed to strengthen health provision at the grassroots. This entails rehabilitating  infrastructures (health centres and district hospitals in particular) and establishing medical supply centres in areas that are not covered by other donors. The project is governed by the principle of cost-recovery to ensure viability and sustainability. But one area where the donors cannot do much is in the field of job creation. There is growing unemployment and job prospects in the formal sector, at least in the short term, are not good.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In macro-economic terms, things are locking up slightly for Cameroon. After recording economic growth of 3% in 1994/95, the hope is for a 5% increase in 1995/96. However, Cameroon's main economic operators, grouped under the umbrella of GICAM (Groupement inter-patronal du Cameroun), expressed fears late last year   that the country would not achieve this level of growth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cameroon exports a variety of primary commodities, most of whose prices have recovered in recent years, and devaluation has had a positive impact on the country's balance of trade. Specifically, it has helped make exports more competitive and in 1994/ 95 the trade surplus was a healthy CFAF 349bn, almost double the CFAF 128bn recorded in the previous year. There was a noticeable slowdown in the export of timber in the latter half of last year and the qualities of coffee and cocoa being sold were not up to the usual standard, a situation that led to both crops being shunned in the world market. Bananas exported to France were also meeting stiffer competition from French Caribbean bananas. However, the fact that rubber production has risen by more than 10%, while aluminium output and sales have increased, should help Cameroon to record another positive trade balance when the figures are next published.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The forestry sector, which has huge foreign-exchange earning and employment potential, is being rationalised as part of the current structural adjustment programme. The Canadian Agency for International Development</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(CAID) has a five-year project to conserve and regenerate some 30 000 hectares. In fact, half of Cameroon is covered by forest and less than 500 000 ha is currently being exploited. The objective is to ensure that forest resources are exploited in the future at a sustainable level.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The private sector</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Industry, which is still in its infancy, has been developed by the government since independence largely with a view to import-substitution, although with some gearing towards the regional market. It accounts for about 14% of GDP and is currently dominated by aluminium smelting. Although devaluation has lately improved the competitiveness of those enterprises that add value to locally available raw materials, the manufacturing sector as a whole faces two major challenges now that the government has accepted the idea that the economy is best driven by the private sector.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first relates to private investments, which have been sluggish  over the past ten years; a clear illustration of a lack of confidence in the economy. This was amply demonstrated when Cameroonians with funds abroad failed to repatriate them to take advantage of the CFAF devaluation as was widely expected. This phenomenon puts the whole privatisation exercise in jeopardy as it means that the government is more likely to have to rely on foreign entrepreneurs. The best the authorities can therefore expect in the short term, some observers say, is to convert those state enterprises that are not already joint-ventures into ones where private investors become the majority shareholders. Complete divestment will then take place gradually over a longer timescale. Overall, 150 state enterprises have been earmarked for sale.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">According to Andr&eacute; Siaka, director of Cameroon's Brewery, who is also Chairman of GICAM, another reason for the lack of investment was high interest rates. These hovered around 20% for many years. Even now, after the reform of the banking sector, interest rates remain very high and there are no borrowers, he told The Courier. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Donors again have been conscious of this and some of their interventions have reflected this concern. For example, Canada is providing funds for the establishment in Douala (the commercial capital) of a centre for the development of private enterprises. Meanwhile, the Chinese have promised to provide CFAF 7bn to enable a line of credit to be opened for small and medium sized enterprises.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The government itself is puting in place a number of incentives, according to Minister of Trade and Industry Eloundou Mani Pierre. The liberalisation of the economy and the reform of the customs regime in collaboration with UDEAC, to which Cameroon belongs, are part of these. Mr Mani told The Courier that with a population of under 12 million, Cameroun's most important market was Central Africa. He also, perhaps surprisingly, has high hopes for the new World Trade Aareement. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cameroon meanwhile is reviewing its plan for the establishment of export processing zones with the help of its main donors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is also looking at other ways of attracting foreign investment, particularly in 'value-added' enterprises involved in the processing of locally available raw materials such as cotton, cocoa, coffee and timber.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Social and political peace</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The second, and by far the more serious challenge facing manufacturing, is the problem of large-scale smuggling by petty traders.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Evidence of this abounds in the booming central market of Douala, where goods of all kinds can be found at very reasonable prices. Ironically the measures which were being taken and judged to be relatively effective against smuggling in recent years have had to be abandoned under structural adjustment rules imposed on the government.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As Mr Siaka pointed out, petty traders dealing in smuggled goods put pressure on enterprises, 'because they do not pay tax', and threaten to render domestic manufacturing uncompetitive. It is also widely acknowledged, however, that the small-scale traders, who dominate the informal sector, provide job opportunities to Cameroonians, which is important at a time of economic austerity. Indeed petty trading has arguably been the safety-valve, helping to ease the social pressures brought about by structural adjustment, and thus preventing civil unrest.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But the extent to which that safety-valve can withstand the emerging political pressures is a different matter. Democratisation, understandably, was one of the conditions imposed by donors for assistance to Cameroon. After a series of elections - presidential, legislative and municipal - which were marred by violence and deaths, there are still doubts about the health of democracy in the country. Indeed, there are signs that tension is  mounting. And few would dispute that if Cameroon is to succeed economically, it needs both social peace and political stability. </P>
+<P ALIGN="JUSTIFY">Augustin Oyowe </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Jacques Santer commends regional  initiative</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Alex Kremer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Commission President's visit to West Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union's commitment to regional development in sub-Saharan Africa is as strong as ever, but sustainable development can only come from Africa's own initiative. This was the message delivered by Jacques Santer, President of the European Commission, in his address to African heads of state at the UEMOA (Economic and Monetary Union of West Africa) summit in Ouagadougou, Burkina Faso, on May 10.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'I wish to emphasise from the start,' Mr Santer declared to the Presidents of Benin, Burkina Faso, C&ocirc;te d'lvoire, Mali, Niger, Senegal and Togo, 'that the European Commission and the European Parliament are both determined to make our partnership even more dynamic and in tune with today's rapidly changing world.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The presence of the Commission President at the UEMOA summit marks a milestone in the European Community's support for regional integration in the developing world. With its own Commission, Council of Ministers and Court of Justice, the UEMOA appears to be consciously  following the supranational model of regional integration pioneered by the European Union.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The sequencing of UEMOA integration, however, is almost the reverse of the European model. Already linked by a single currency in the CFA franc, the West African Union's member states are now pressing ahead with plans for integration of their 'real' economies. The implementation timetable agreed in Ouagadougou covers freedom of establishment, free movement of capital, mutual macroeconomic monitoring and the first steps to customs union with the harmonisation of external tariffs and the lowering or removal of intra-regional barriers to trade.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">President Santer indicated that the European Commission is keen to discuss how the European Development Fund (EDF) can support these initiatives. Such aid could take the form of technical assistance and training as well as direct budgetary support to mitigate the short-term costs of customs union.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UEMOA is not, however, an aid project. Its member states have designed it to stand on its own feet financially from the start. A 'community solidarity levy' was due to come into effect on 1 July 1996. The money will be used for a structural fund programme beginning in late 1997, as well as to finance the Union's operating costs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Meeting with the President of Burkina Faso, Blaise Compaor&eacute;, Mr Santer said that it was particularly significant that his first official visit to Africa as President of the European</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Commission was to Ouagadougou. Not only was it a reaffirmation of the partnership between Africa and the EU, and a statement of the EU's willingness to support regional integration in the developing world. It was also a tribute to the determination of the people of Burkina Faso and other African countries to promote their own development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Community is Burkina Faso's second largest donor, contributing 10% of total aid payments in 1994. Since 1991, the EC has committed an average of ECU 45 million each year to development cooperation with this country, rising to a peak of ECU 100m in 1995.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mr Santer visited the EDF-financed road improvement site at Tougan, close to the frontier with Mali, and noted that intra-regional transport links were an essential complement to the legislative programme of the UEMOA. He concluded his tour of regional cooperation projects with a visit to a photovoltaic pumping system financed by the EC under its West African solar energy programme.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, on a more personal note, the Commission President was able to drop in on a project managed by the charity Chr&eacute;tiens pour le Sahel. Mr Santer worked for this Luxembourg-based organisation before starting his career in politics and he was visibly pleased to see that it was still going strong - supporting home-grown African initiatives with a little financial help from the European Community.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A.K. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">CTA - moving with the times</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When the Technical Centre for Agricultural and Rural Cooperation (CTA) was inaugurated 11 years ago in Ede, Prince Claus of the Netherlands - whose interest in development issues is well-known - attestded as guest of honour. On 19 April, he returned to take part in the official opening of the CTA's new building in neigh bouring Wageningen in the Dutch province of Gelderland. The siting of the purpose built premises is significant. The town of Wageningen has long been an important European centre for agricultural research and the Dutch, of course, are renowned for their commitment to cooperation with developing countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The CTA may only have moved a short distance from its previous headquarters, but the Centre's 38-strong staff are also aware of the need to move with the times when it comes to fulfilling  their role in the field of agricultural information. This point was particularly emphasised by CTA Director, Dr. R.D. Cooke in his presentation at the opening ceremony. Recalling the Centre's main tasks (see box) Dr Cooke spoke of the 'changing horizons and challenges' which they faced, and he focused on four specific aspects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first of these is the big change taking place in national agricultural systems, with the state withdrawing more and more in favour of the private sector and NGOs. This is being accompanied by a trend towards decentralisation with the result that the CTA has many more potential partners to cater for and work with.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Global liberalisation has also had an effect on the kind of information being sought by the CTA's 'customers'. In the past, demand was almost exclusively for scientific or technical information, notably aimed at increasing productivity. Dr Cooke reported that while this remained important, there was now  an increasing interest in marketing and socio-economic aspects to facilitate decision-taking.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It came as no surprise to hear the Director highlight the challenge posed by new technologies such as electronic networking and digital storage. The key point here, he stressed, was to find ways of adapting these to ACP needs and realities. 'In the next century,' he argued, 'the haves and the heve-nots will be defined by their access to information.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, Dr Cooke referred to the growing significance of regional linkages. He indicated that the CTA was locking at ways in which it could help its partners to devise regional development programmes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The declaration signalling the official opening of the building was made in the preceding presentation by E.F.C. Niehe who is Deputy DirectorGeneral for European Cooperation at the Dutch Ministry of Foreign Affairs. In his speech, Mr Niehe emphasised the relevance of the CTA, pointing out that while the world food situation had improved, 'we are now on the threshold of structural food insecurity'. He also spoke in more general terms about the future of ACP-EU cooperation and acknowledged that 'partnership, sovereignty and equality had been somewhat neglected' by donors. However, he suggested that these concepts were now 'coming back'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From the ACP side, the Swaziland ambassador, CS. Mamba,who is co-President of the Committee of Ambassadors, took up the theme of food shortages in sub-Saharan Africa and identified some of the difficulties encountered by African producers, particularly in respect of new technologies and marketing. He also referred to the environmental challenges facing ACP countries, especially in the Caribbean and Pacific. He was keen, however, to stress that the picture was 'not entirely negative'. Thus, for example, new technologies and methods had had a positive impact on grain production in Zimbabwe, horticulture in Kenya, and cocoa and coffee in West Africa. Mr Mamba echoed Dr Cooke in stressing the advantages of regional markets, and concluded with a firm statement of support for continuing ACP-EU cooperation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'History,' he said, 'will show that the Lom&eacute; Convention played a central role in the momentum of development.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The final speaker was Steffen Smidt, Director-General for Development at the European Commission, who suggested that the CTA had played a pioneering role in developing a sectoral  approach at a time when the focus of development cooperation tended to be on individual projects. 'The Centre', he said, 'has become a well-respected international institution in the field of agricultural information.' The Director General focused on the need for ACP countries to develop their own capacities and on the gap that exists 'between potential and reality', because of capacity limitations. The Centre, he believed, could 'help bridge this gap.' Mr Smidt also reiterated a point made earlier that the information flow should not just be in one direction. 'Information from South to North is vital,' he argued, to ensure better targeting of programmes in future.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">After the speeches, guests had an opportunity to learn more about the CTA's work by speaking to the Centre's personnel and visiting a special exhibition illustrating the nature and purpose of the Centre's activities. _</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Simon Homer About the CTA </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The CIA's tasks are: </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - to develop and provide services which improve access to information for agricultural and rural development ; </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - to strengthen the Opacity of ACP countries to produce, acquire, exchange and utilise information in these areas. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Programmes are organised around three principal themes: </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Strengthening information centres - designing strategies for improving agricultural information services; - promoting use of new information technologies; - providing training; - donating books. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Promoting contact and exchange of: experience among CTA's partners in rural development - seminars; - study visits. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Providing information on demand - publication s; - radio and audiovisual materials; - literature services for researchers; - Question and answer service. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(The address of the Technical Centre for Agriculture and Rural cooperation can be found in the CTA section towards the end of the white pages in   this issue.) </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Bananas, Hamlet and the Windward IsIands</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By Martin Dihm</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What do the Windward Islands' banana industry and Hamlet have in common ? Both are intrigued by the same question: 'To be or not to be.' But unlike Hamlet, whose fete was decided rather quickly and tragically, the future of Windward Canibbean banana production is still open. And what is more, Windward producers have a distinct advantage over Hamlet. They can hire consultants to analyse their problem and come up with fresh solutions. That is what has happened. But before turning to the solutions, what have the problems been ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The four Windward Islands; Dominica, St Lucia, St Vincent and Grenada, have long enjoyed preferential market access to the UK. This first permitted the creation of the industry and then secured its survival, even with production costs that are much higher than those of other producers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A traumatic moment came when the European Community had to decide on a common market regime for bananas. Coming into effect in mid 1993 the regime maintained the principle of preferential access for traditional ACP producers. Nevertheless, it introduced a move towards greater market liberalisation. Fierce attacks on the regime by certain of the EU's trading partners have raised doubts about its viability. The system is due, in any case, to expire in 2002 when even further liberalisation seems likely.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All this could cause great difficulties for the Windward Islands which still depend substantially on banana exports to the EU. A decline in prices since mid-1993 and the appearance of new competitors in the previously protected UK market have further underlined the need for the Windwards to compete in a more liberal arena. The Islands commissioned a study, funded by the UK and the EC, into the competitiveness of their industry and on ways of improving its position. It was not the first study of this type, but earlier ones had had no real impact on the industry which had always been sufficiently protected to avoid swallowing the bitter pill of adjustment. This time, it was clear from the outset that action would have to be taken if the industry were to master the new situation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The study provided a wealth of interesting insights and recommendations. The first big surprise - at least for outsiders - was the discovery that the industry was wasting considerable amounts each year through certain deficiencies in governance, management and production methods. The second theme of the study was the poor banana quality resulting from an inappropriate pricing system. In effect, price differences paid to farmers were not sufficient to reward extra attention to quality aspects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The study's recommendations pertaining to management, production and quality were all agreed in a meeting on 29 September 1995, which brought together the Prime Ministers, the EC and other donors. Prime Minister Mitchell of St Vincent labelled this chance for the industry to get its business right as 'the last train to San Fernando'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What has happened since then ? After some hesitation, the industry has indeed begun to 'take up arms against its sea of troubles' (to return to the Hamlet analogy). The EC, for its part, has taken the part of Horatio, the faithful friend. Its role is a delicate one though - for the EC has a lot of money available. Take, for example, the ECU 25m allocated to St Vincent in the 1994 STABEX exercise (roughly five times that  country's national indicative programme). How are such funds to be injected reasonably into the islands without undermining their own strength and sense of purpose in pursuing the right strategy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To answer this, one has to look at the actual requirements. Streamlining the banana industry is less a question of big infrastructure projects than of providing expertise to guide the necessary structural changes. It also means fewer people will be employed in the sector. Aid should, therefore, focus on technical assistance, promoting diversification, and social 'cushioning'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The challenge, of course, remains considerable and the outcome will not be known for some time. But it is clear that the Windwards have taken bold steps in the right direction and that further steps are on the agenda. There is also little doubt that the islands small, sweet bananas can only be competitive in their market segment if they are produced and marketed professionally, and with dedication.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So what could Hamlet have learnt from this experience ? In short - get sound analysis and fresh advice from outside - and then boldly implement. And stick close to your good old friend, Horatio! </P>
+<P ALIGN="JUSTIFY">M.D.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">British beef overshadows Development Council</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The most recent meeting of the EC`s Development Council was one of the first to be hit by the non-cooperation policy adopted by the UK in protest at the export ban on British beef. The Overseas Development Minister, Linda Chalker, announced at the outset to her fellow ministers: 'I will not be able to agree today to the adoption of those texts... on which unanimity is required'. Britain is seeking agreement 'for a step-by-step lifting of the export ban', which was imposed after scientific evidence suggested a link between Bovine Spongiform Encephalopathy (BSE) - and its human 'equivalent', Creuzfeld Jakob Disease. Cases of BSE have been recorded across Europe, but the vast majority have been in the UK.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Texts which were approved included a regulation on refugees in non-Lom&eacute; developing countries. This makes available ECU 240 million over a four-year period (19961999) for longer term assistance to refugees and displaced persons - mainly in Asia and Latin America. Also agreed were two three-year programmes covering Aids control and environmental projects respectively. They will cover the period 1997-1999, and each has been allocated the sum of ECU 45m. In addition, ministers confirmed a regulation on the criteria for disbursing humanitarian aid.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But the British stance meant that a number of important resolutions were blocked, including a text on mounting projects which link emergency, rehabilitation and longer-term aid. Rino Serri, Italy's Under Secretary of State for Foreign Affairs who presided the Council meeting, said that once adopted, this approach would represent a 'qualitative leap for the EU's development policy.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other resolutions awaiting approval relate to the strengthening of coordination between Member States, evaluation of the environmental impact of development policies, decentralised cooperation, and migration and development. Since good headway was made on these subjects despite the British attitude, the texts are expected  to be speedily agreed once the UK lifts its veto. Ministers also had an initial discussion on a paper presented by Commissioner Pinheiro on preventing conflicts in Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As is customary at these biannual meetings, several delegations raised points of particular national concern. Belgium, for example, is worried about the Commission's proposal which would finally establish the single market in chocolate products while leaving Member States the choice of adapting their legislation to allow a vegetable oil content of up to 5% in chocolate. Belgium feels that this approach could ultimately prove harmful to cacoa-producing countries and claims that it will be difficult to control the exact percentage of oil used. Sweden, meanwhile, wants action to reform the UN institutions while Italy is keen to increase public awareness of development policies. Finland emphasised the need for better coordination between the European Community and its Member States on environmentally sustainable projects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Great Lakes region</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There was backing for the June Round Table meeting on Rwanda organised by the UNDP, as well for the various diplomatic initiatives aimed at bringing stability to the Great Lakes region. On 27 May, the ministers dined  with Emma Bonino, the European Commissioner responsible for humanitarian issues, and with former US President, Jimmy Carter, who has played a major role in the search to find a solution to the region's problems. Others active in this effort include South Africa's Archbishop Tutu, and former Presidents Nyerere and Tour&eacute; of Tanzania and Mali respectively. Ministers also commended the efforts of the UN and the OAU.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mr Serri said there was a 'desperate need for a ceasefire' in Burundi and called for a 'speeding up of the peace process and full deployment of available humanitarian and development aid.' He told journalists it was vital for the EU to make special efforts to strengthen the judicial systems in Rwanda and Burundi - 'so that the justice system can work properly and identify those responsible for the genocide.' He pledged that 'substantial resources' would be made available once peace is secured. Ministers also called for a control of arms sales to the region, although they have no power to legislate in this area, which remains the preserve of the Member States.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Outside the meeting place, Senegalese fishermen and NGOs joined forces to mount a protests against the effects of traditional EU fisheries agreements. These provide financial compensation to governments in exchange for access to their waters for EU vessels, but the protesters claim that they harm local fishing industries and disrupt food supplies. A significant number of agreements are due to come up for renewal later this year. NGOs are lobbying for a new and 'fairer' type of accord which provides for catch reductions, more selective fishing methods and the employment of locally-hired fishermen on EU boats. These proposals are all set out in a paper entitled 'The Fight for Fish: Towards Fair Fisheries Agreements,' published by Eurostep, a Brussels-based NGO. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D.P.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Country report</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Cape Verde</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Making the best of history</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cape Verde has been shaped by the harmattan, the hot dry wind which blows from Africa, strong ocean currents and five hundred years of Portuguese colonialisation. Portugal has been a constant presence in the archipelago's history since the fifteenth century, when it granted the colonists who were to settle on the islands of Cape Verde a monopoly over the slave trade. The country became an interface between Africa, Europe and the Americas, at the centre of the triangle of trade in slaves, hardware and gold. The intermingling of black populations of every origin who  passed through the islands meant that the country was unable to present a united face against the colonialist culture. The colonists were therefore able to impose their own culture, with their fervent and proselytzing Catholicism becoming the principal ingredientin the mixture that is Cape Verde. Strong, scorching winds from the desert have shaped the islands' landscape and inhospitable ocean currents mean that approaches to the islands are difficult, their rocky cliff faces plunging into the sea.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mythical Portuguese colonial oasis</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Up to the eighteenth century, Cape Verde was no more than a commercial centre for Portugal, its population at the end of that century barely exceeding 50,000, to be halved by the great drought between 1773-75. Other periods of drought regularly decimated the population and the arrival of new colonists and slaves did not offset such losses or compensate for the massive exodus which began in the early nineteenth century with the arrival of American whalers in search of crew members for their ships. Seven hundred thousand Cape Verdians currently live abroad, half of these in the United States.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Only four hundred thousand  have stayed in their own country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the beginning of the twentieth century, a period which signalled a turning point in the country's history, the population still numbered no more than 150 000. At the time, major sea voyages were being undertaken and Cape Verde's geographical location was highly valued. Mindelo, on the island of S&atilde;o Vicente in the north of the archipelago, developed as a coal-and-watersupply port for English vessels plying the route between India and the Americas, and England helped construct this port. However, Portugal's policy towards Cape Verde was double-edged. On the one hand, the islands were regarded as a natural extension of the home country, but as a competitor in terms of port activities. This led to Mindelo's slow development, although the trade in  skins, fishery produce, coffee and salt  could have made it a thriving centre. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mixing of races in Cape Verde has often been held up as, so-to-speak, 'humane colonisation', but this opinion is not corroborated by the under-developed state of the country at the time of independence and the fact that Portugal implemented food security measures to combat the ravages of catastrophic famines only when under pressure from public opinion, at the end of the first half of the twentieth century. The island's colonists had always used slave labour to produce food or fabrics which enabled them to purchase more slaves and it was only when the slave based economy began to decline, which   resulted in the impoverishment of the colonists, that a major grouping of free Blacks and rebel or emancipated slaves came into being. That is when the intermixing of races began. Therefore, before the abolition of slavery (18641869-1878), the vast majority of the black population of the island was free; both unmarried and married colonists would generally emancipate their children born of a secret relationship with female slaves. The aristocracy and white upper-middle classes continued to live a cloistered, aloof life and did not mix with other races. A second factor which would suggest that Portuguese colonisation of Cape Verde was sympathetic in outlook is the reputation of this small country's intellectuals; although colonisation created only a small intellectual elite which was the product of a single institution, the Mindelo College, opened in 1917. In a quote by Michel Lesourd, Deirdre Meintel refers to this phenomenon as the mythical 'cultural oasis'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A nation born of a middle class in tatters</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Through its contradictions, it was this black, mulatto and 'petty white' middle class which was to forge the mixed-race culture and national identity, caught between its own privileges and its aspirations of aristocracy, between its rejection of African culture (they sought a 'lusotropical' culture) and the need to find allies amongst the lower classes who retained African cultural values. In order to acquire the wealth and attributes of power, this middle class was to take over the lands vacated by the decline of the slavebased economy and which were often much improved by the former slaves (renamed 'tenant farmers' without a major change in their living conditions) preventing a major economic upheaval which could have put an end to this iniquitous system. Their wholesale appropriation of land explains why, today, there is a very high proportion of landless farmers in Cape Verde, seasonal agricultural workers who survive only thanks to the State's welfare system.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This petty bourgeoisie was to give birth to growing awareness which would lead to calls for independence. Officially, Cape Verde was not a colony but a province, and its inhabitants in theory had the same rights or lack of rights as Portuguese citizens in Salazar's 'New State', where the right to vote depended on social and cultural status. In other Portuguese territories, members of the petty bourgeoisie held the rank of colonial administrators and, from their ranks, the pro-independence movements emerged. Such was the case of the PAIGC (Guinea-Bissau and Cape Verde pro-lndependence Party), created by Amilcar Cabral, a symbolic figure in Africa's striuggles for independence and Cape Verde's national hero. He was assassinated in mysterious circumstances in Guinea-Conakry in 1973. His brother, Luiz Cabral, was to become president of Guinea-Bissau, and Aristides Pereira his successor as Party leader and Cape Verde's first president.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cape Verde's uneventful transition to independence in July 1975 mirrored Portugalts Carnation Revolution and was quite unlike the fierce war entered into by Portugal in Mozambique and Angola. There was a clandestine struggle during which a number of combatants were imprisoned, but there was never any real guerilla warfare. The Portuguese governor remained at his post until he was replaced by an ambassador. The PAIGC was to govern both Guinea-Bissau and Cape Verde until the coup d'&eacute;tat against Luiz Cabral in Guinea-Bissau in 1980, when it adopted the name of PAICV in Cape Verde, thereby signalling the end to any dream of a union between the two countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Diplomatic ventures</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The new state pursued an even-handed diplomatic approach and accomplished the considerable diplomatic feat of remaining equidistant between the Cold wer's principal adversaries, adapting over time to all the changes which occurred on the world  scene. Post-independence, embassies were opened by the United States, China and the Soviet Union. Cape Verde, with its marxist leanings, maintained the former links created with apartheid South Africa by Portugal. The arrival in power of a liberal party had no effect on this diplomatic tightrope-walking act. It was South Africa which was to provide aid to build the international airport at Sal. Ironically, after the establishment of democracy in South Africa, it was at this very airport that President Mandela was to stress his desire for strengthened links with the archipelago. Latterly, Cape Verde has demonstrated this flexible in its recent decision to Join the group of, French-speaking countries whilst still regarding itself as a mouthpiece for the Portuguese-speaking world, enjoying a privileged relationship with Portugal, the Azores, Brazil and African countries where the official language is Portuguese. It is also a very active member of the CEDAO (Community of West-African States) and its President is currently chairman of the CILSS (Inter  national Commitee to Combat Drought). Cape Verde receives as much aid from China as from the US, from Russia and Sweden as from Cuba and Japan.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This diplomacy is in keeping with the atypical 'Marxist' Party which first initiated it. With its interventionist approach to economics, its highly developed social policy which gives priority to education, health and combating unemployment through public welfare, this party could be regarded as a socialist party, yet it opted decisively for a market economy. Its single-party structure mirrored the example of would-be popular democracies, but it never set up a system of repression and terror: only one opposition member's death is said to have taken place in suspicious circumstances on the island of Santo Antao. The population was able to discuss politics at popular assemblies and held no fear of openly criticising the government and, in the case of the well-off, of displaying its wealth. A mudan&ccedil;a (change) was implemented calmly and collectedly by the PAICV when it was in power, sowing the seeds of its own downfall. With no pressure from street demonstrations and no insistent demands from political classes, the government of President Aristides Pereira and Prime Minister Pedro Pires adapted to the new situation created by the fall of the Berlin Wall. In early 1990, the PAICV gave up its privileged position as the single party and, one year later, at the legislative elections in January 1991 and presidential elections in February 1991, Africa witnessed the first democratic overthrow of a single-party government which had achieved independence. After the legislative elections, the PAICV, which had placed too great a reliance on being credited for its good governance, was silenced. The desire for change was too great and the position adopted by the Catholic church, anxious to punish a party which had dared to opt for a referendum on abortion, did the rest. President Aristides Pereira's personal prestige stood for little in the full face of this onslaught.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What change?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Prime Minister Carlos Veiga, who had founded the MPD only eight months before his overwhelming success in the 1991 elections, became the new figurehead in Cape Verde politics. His power sharing with Antonio Mascarenhas Monteiro was again successful at the most recent elections (December 1995 and January 1996). Shortly before the poll, the MPD experienced a near-fatal split, but the new party which emerged, the PCD, had only one representative as against 50 (an absolute majority) for the MPD and 21 for the PAICV, which continued to exist. Three other parties taking part in the elections fell by the wayside and the polarisation of Cape Verde's politics into two camps locks set to continue. This is the second time that the MPD has surprised its opponents - this time, the political adversaries had attacked the MPD's attempt to curry favour, but the majority of the electorate, concentrated on the island of Santiago, continued to show their appreciation of the visible signs of modernisation in their lives and also the government's seductive politics, particularly in the ran-up to the elections. The country had also had a good harvest and, although this was unconnected with the MPD, that party could only benefit from it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite what MPD leaders might say, there has been no real ideological split, any political reorientation having been instigated in 1990 by the previous regime when it threw off its socialist trappings. Diplomacy remains  pragmatic and the new government's liberal rhetoric and social policy, particularly in the areas of education and health, has essentially been maintained. Suspension of the State's collective works programme, the symbol of the State's interventionist social policy, is only temporary, according to statements issued by the Prime Minister, counter to several rumours.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More visible changes have taken place in the economy: partial liberalisation of the banking system; legislation relating to foreign investment; suspension of the requirement for preliminary import authorisation; despite the government's backtracking as regards certain basic products; privatisation of State assets, particularly in the hotel business, etc. Here, too, the PAICV government engineered the changes, but it can surely not be criticised for maintaining a delicate balance between the new demands of the global village and the social practices of a country which is very poor, but which is succeeding in putting an end to its poverty and creating a modest quality of life, but a secure one. Given its bleak geographical location, Cape Verde is simply  continuing to make the best of history. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H&eacute;gel Goutier</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The economy: too weak to worsen</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The arrival in Praia on 30 April of a throng of IMF officials cannot have failed to cause the government some concern, despite its air of calm. Ministers repeated publicly that Cape Verde had already carried out its own programme of structural adjustments, that they were on the same wavelength as the Bretton Woods institutions, and that they could not, therefore, see any reason why any further adjustments  should be imposed upon them. Nevertheless, the fact that the Cape Verde escudo has had rather a bumpy ride since last year's elections, trading sometimes by as much as 15% under its official rate on the parallel market, caused a certain degree of anxiety within financial circles, with the banks taking action by freezing certain credit facilities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The government insists that this situation has by no means arisen because of a sudden anxiety raised by opposition parties as to the effects of possible devaluation The truth is that there is a genuine structural imbalance caused by the trade deficit, a disequilibrium which is only being partially offset by official development assistance and the transfer of currency by Cape Verde emigres. As a percentage of the GDP, the overall budgetary deficit has tripled between 1993 and 1994 (increasing from 3.3% to 13.6%). For a country which could always be relied upon to pay its debts promptly, Cape Verde is now, for the first time, in arrears with its payments (see the 1995 report of the Bank of Portugal). The servicing of external debts represents 25.7% of goods and services exported - although these are relatvely small compared with neighbouring countries - the country's total outstanding debt is now nearing $200 million.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although Cape Verde is one of the LDCs (least developed countries) with a total GNP of approximately $850 per capita, out of a total of 174 States, it actually ranks 123 in the Human Development Indicator Tables, which take into account various factors such as life expectancy, education, etc. Its position near the middle of these tables clearly shows that, although the country is poor, its affairs are nevertheless being managed fairly efficiently. Boasting an adult literacy rate of 66% and a life expectancy of 64.7 years, Cape Verde is well ahead of those countries at the bottom of the list, which include a number of its Sahelian neighbours. Efficient administration of the State and the absence of rampant corruption are further feathers in the nation's cap. These achievements have earned Cape Verde much esteem from its sponsors, which goes to explain the prudence of the Bretton Woods institutions and their relative sympathies towards the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unkind Mother Nature</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cape Verde's history has been punctuated by great famines. Between the sixteenth and nineteenth centuries the country suffered no less than 30 famines, with this century seeing some of the cruellest: 16 000 people died in 1903-1904, the death toll in 1921 was 17000, in 1941-43 it was 25000 and between 1946-48 famine claimed 20 000 lives - a figure which at the time represented 20% of the total population of the archipelago. After the last famine, the colonial authorities, under pressure from international opinion, adopted food programmes which made the country more able to cope with the consequences of subsequent droughts. The last great famine ended 50 years ago. The nation may no longer be hungry, but the factors which make its inhabitants' lives so difficult remain. The  main reason lies in the country's geography. Cape Verde has virtually no permanent springs and the topography of most of the islands, which are very mountainous, means that heavy rain simply runs down to the sea, the parched soil being unable to absorb it sufficiently. What is more, these downpours simultaneously wash away the little arable land that do" exist, thereby aggravating erosion. The whole situation is further worsened by the fact that the winter in this Sahelian region is very short. Despite huge efforts by successive governments, barely half the population has access to drinking water, with this figure barely reaching 25% in rural areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With a population of less than 400 000, there are just not enough people to pull off the miracle of making such an unforgiving soil bear fruit. Hence, although providing 50% of all jobs, agriculture represents only 17% of the nation's gross domestic product and produces only 10% of food consumed locally. The mountainous islands that make up Cape Verde are like teeth jutting out of the sea, and with virtually no continental shelf to speak of, small scale fishing is extremely difficult. Even with industrial equipment such as that installed on board large trawlers, catches are small - so small in fact that the country's fisheries agreement with the European Commission brings it only one million ECU over three years, one tenth of the proportional amount earned by neighbouring Senegal. Fishing thus represents less than 4% of the GDP.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mere survival - a</P>
+<P ALIGN="JUSTIFY">Herculean task</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Transport difficulties are another handicap for the economy. The sheer force of the harmattan, the strong ocean currents and the fog which often covers the region, make journeying by boat between the islands frequently hazardous. In addition, the volcanic relief of the islands makes them difficult to reach and means that there are very few locations that make suitable har  bours. construction is both complex and costly due to the steep rocky barriers that seal off deep valleys. Those roads which have been built under the FAIMO scheme (Highly Labour-lntensive Projects) have sometimes turned into real labours of Hercules, and many areas, especially those on sparsely-populated islands, remain completely cut-off. The use of aeroplanes only partly solves the problem. Although competitive, the prices charged by the national airline, TAICV, are still too high for the average inhabitant.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Not only does the soil on Cape Verde contain very little water, it has virtually no natural resources: a few stones, lime, pozzolana and a little salt. Within the manufacturing sector (which makes up less than 20% of the GDP), only the construction and civil engineering industries, representing more than 10% of the GDP, contribute in any significant way to the economy, thanks partly to the transfer of currency from emigres who invest in the construction  sector and works with wide public interest. These works, known as FAIMO schemes, have to some extent given this impoverished country a gloss that masks its poverty. Launched after Cape Verde gained its independence, they employ more than 25 000 people for up to ten months of the year in the construction of paved roads or in reafforestation projects, and ensure the survival of one hundred thousand people - over one quarter of the population. The workers are on the whole recruited from among farm labourers, with another large section of the workforce being made up of 'Solteiras' or 'single women', numerous in a country where the male population is constantly emigrating. Unfortunately, the liberal option adopted by the present government has cast some doubt as to whether these projects will continue and this year, for the first time, work ceased in April - three months ahead of the usual termination date. Yet the poor wages which these seasonal jobs pay (ECU 2 per day) are sometimes the only source of income for some families.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Only the tertiary sector shows a healthy balance of trade, accounting for  more than 60% of the country's gross domestic production, with the biggest slice of the sector going to the hotel industry, followed by the transport industry. Although, overall, Cape Verde's balance of trade records a large deficit, the balance of trade for the services sector generally shows a profit, with the transport services provided by the international airport, Amilcar Cabral de Sal, alone accounting for 13% of exports.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> Barely 10% of commercial goods are domestically produced and this has at times fallen below 5%. Cape Verde is therefore genuinely dependent upon foreign aid. Official development assistance represents 27.8% of the GNP (1989 figures), having risen from 17.7% to 27.2% of the GNP between 1980 and 1986. Cape Verde also relies on a second source of income - its emigrant population. In 1990 the currency transfers of its emigres represented nearly 20% of the GNP. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The colonial heritage</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Contributing too to the country's poverty are relatively low educational standards. In this area too, successive governments have continued their predecessors' efforts to improve standards of education. However, at the time the country achieved independence, it was in a deplorable state. The reputation of a small intellectual elite of Cape Verdians had, over several decades, led the world to believe that Portuguese colonial rule had been 'enlightened'. This was a mere illusion. It was not until 1917, when the Mindelo grammar school was founded, that the country was able to claim an educational establishment of any cultural sophistication. The Mindelo school was the first state school in the country and it was to provide the nation with its first batch of 'home-grown' intellectuals. Until the middle of the nineteenth century, the Church, which was in charge of all matters educational, had provided basic primary education; then, at the end of the last century, it opened two secondary schools with the purpose of training students for positions in government and the civil service.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Even so, the Mindelo school remained an exception until the middle of this century. In 1950, no more than 5000 children received primary education and no more than 400 went to secondary school. Thirty years earlier, the figure was slightly higher, but Salazar, with his retrograde ideologies, saw education as dangerous and threatening and trimmed the number of schools on the islands from 150 to 60. True, Cape Verde was undoubtedly in a better state than other Portuguese colonies, but, with an illiteracy rate of 80% at the beginning of the 1960s, its position was nevertheless far from enviable. It was not until independence that any real progress was made, with 60% of children attending primary school in 1989 (the average for LDCs is 54%). However, this figure is still well below the average for developing countries, which stands at 90%, and even now, only 13 % of children have access to secondary education. As for higher education, this is virtually only available abroad; in Europe, Brazil, USA and Cuba, in particular.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Serious health problems still exist, exacerbated in particular by the scarcity of water. The cholera epidemic which has struck several African countries over the last two years has killed over 150 people in Cape Verde. The prevalence of AIDS exceeds the average for sub-Saharan Africa, with more than 2000 people being HIV positive and with some one hundred having developed the full-blown disease. According to official figures, 70 have died of the disease. The cholera epidemic which, unlike previous epidemics has affected towns much more than rural areas, is a sign of the deterioration of sanitary conditions in towns - particularly in Praia - affected by a lack of water, a dilapidated sewerage system and overcrowding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anchoring the country's economy in its culture</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yet, through all the doom and gloom, a small miracle is taking place in Cape Verde. Despite such a heavy burden of poverty, the country has, since gaining independence 20 years ago, managed to clamber up the league tables notably in the essential areas of health and education. Life expectancy at birth, which was only 52 years in 1950,  had increased in 1992 to 64.7 years, better than the average for developing countries and 13 years more than the average for sub-Saharan Africa. The infant mortality rate which stood at 110 per thousand in 1960, had dropped drastically to 50 per thousand by 1992, while virtually all children now receive essential vaccinations. Malaria is also now rare. In 1988 the GDP of Cape Verde amounted to only C.V.Esc 20 billion ($289 million), in other words, 6.9% of the GDP of Trinidad and Tobago, and 16.6% of that of Mauritius. But it is growing steadily. From 1980 to 1988, it grew by 6% per annum, compared with 3% per annum for the Sahel, and since 1980 the GDP per capita has doubled.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The solution the nation's leaders should be seeking is greater integration in the global economy context by encouraging foreign investment. They do not need to create free zones but free enterprise, such as the shoe manufacturing concerns which, over the last two years, have contributed to achieving a considerable increase in exports. Various steps have been taken to attract investors, such as the adoption of the principle of tacit acceptance of applications for investment within 30 days. The Prime Minister, Carlos Veiga, and the 'Super-Minister' for Economic Coordination, Antonio Guelberto do Rosario, have highlighted the service, tourism and fishing industries as top government priorities. In order to develop these areas they intend to invest in infrastructures, with the aid, of course, of foreign backers. The modernisation of the port of S&atilde;o Vicente and of the international airport of Sal are currently underway, and the telecommunications project to link the islands by cable has also already been launched. The government's short-term plans also include the development of industries connected with the islands' culture. In the words of Mr Veiga: 'We in Cape Verde should develop our culture and use it as our anchor, to prevent our country drifting into oblivion. That way, our tiny country, which is fortunate enough to have a strong cultural identity, will be a Nation rather than a just a State'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H.G. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Interview with President Antonio Mascarenhas Monteiro</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A wealth of culture and a realistic approach to diplomacy: Cape Verde's two major assets</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- How the current government differ from the former administration which had Marxist leanings ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The two eras are distinct from each other in that, since 1990, the Cape Verde people have been able to choose a life of freedom and democracy. Before that, for the   first fifteen years after independence, there was a single-party system. So it is also valid to speak of a break - a break with the way in which institutions used to function at a political level.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-The single-party era does not seem to have been as strict as in other countries and the current regime appears to be continuing along the same lines in some areas. Was the former administration not, to some extent, responsible for initiating the change which has taken place ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - No, that's something else entirely. I often say that we had a civilised single party, and I assume that is what you are referring to. However, it is not possible to speak of continuity when formerly we had a single party and now we have moved on to a system where there is freedom of expression and new parties can be set up. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Admittedly, the single party did initiate a change when it created the conditions necessary for the advent of democracy. It removed the infamous Article 4 from the constitution, which seates that the PAICV was the guiding force of society and the state. In fact, it was the PAICV which drew up the country's first electoral laws whereby we were elected. When I say 'we', I mean the party which is in power and also myself, President of the Republic. The single party thus opened the way to  democracy here: that much is undeniable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Am I also right in thinking that many of those who are in power today received their training in that single party ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - You are quite correct. When a change such as this comes about, one has to appreciate, and I do not wish to be elitist here, that it is the higher echelons of a party which lead the move towards change. Such people were there, working in the administration.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Since politics gives direction to economic affairs, has there been a total turnaround in this sector, with a clear decision to opt for liberalisation and privatisation ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Before 1990, we had a staterun economy. After that, the country's economy was opened up with a number of privatisations, fewer import restrictions, and so on. The word 'break' is also applicable in this area in that we now have a market economy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Do you feel that the economy has really shaken off state control given that the govemment still manages important sectors, such as the price of raw materials ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">That is necessary a market economy does not mean that the state is entirely absent. I am in favour of a market economy, but with state monitoring. As far as possible, the state has to correct the injustices which are necessarily generated by competition. This is not, as some would have it, ultraliberalism. The government is still entitled to monitor the economy, but the change has been greatest in terms of attitude, in terms of the way things are done.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Do you, like many leaders of developing countries, believe that the requirements set by international institutions as regards structure/ adjustment are too great ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - We are not subject to compulsory adjustment - it is on a voluntary basis here. However, I do feel that adjustment, as implemented in Africa, sometimes has regrettable aspects. On occasion, it is asking a little too much to impose the same requirements on countries whose actual situations are very different. What is applicable to Nigeria is not necessarily suitable for S&atilde;o Tome.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-The 1992 constitution switched Cape Verde over from a presidential system to a parliamentary system. As President of the Republic, do you fee/ trapped by this constitution ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Cape Verde's constitution was never a presidential one. The system under which I was elected is effectively 'semi-presidential'. Admittedly, the constitution which was approved by Parliament in 1992 reduced the powers of the </P>
+<P ALIGN="JUSTIFY">President, particularly as regards the right to dissolve Parliament - which was unrestricted in the 1980 text. The revision was made to permit democratisation and ensure the proper functioning of the institutions, and it was therefore fairly wide-ranging. Now, in order to dissolve Parliament, the President has to have the support of the Council of the Republic, which means that his hands are tied to some extent. Previously, the President could also dismiss the government, without too many restrictions. I would say that the President's prerogatives have undergone a substantial reduction in comparison with those exceptional powers. As for the rest, things are as they were. In a semi-presidential regime as that envisaged by the 1980 constitution, the President has no executive role.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You seem to have chosen to play the role of 'wise man' Some observers think you give the Prime Minister too much leeway.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - They are wrong. The Prime Minister's post is conferred on him by the constitution. He is Head of Government and it is he who governs. I cannot govern in his place. What is true is that there is a great deal of ignorance - people do not restrict themselves to their own fields and attempt to teach lessons in subjects they are unfamiliar with. Germany has a parliamentary  regime like we do - what is the position of the President of the Republic in Germany? If you were to ask a Cape Verde intellectual for the name of the President of Germany, he would be unable to answer you. The parliamentary regime does not give the President of the Republic any powers to run the country. I do not know what the Prime Minister can have taken away from me because I have no power for him to take over. However, I would say that, here, the President of the Republic does have a fairly high profile, in spite of his reduced powers, because all the country's citizens know him. In terms of foreign policy, he plays a significant role in that he represents the country abroad. I attend international conferences like the Rio Summit, go to meetings of the OAU and sign international undertakings on behalf of my country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The President is also the guarantor of the new democracy, which observers seem to regard as well-established. But there still seem to be some bad habits. For instance, I have heard criticism of MPD power and of the fact that state  resources are made available to one party at election time.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Look, this is criticism from the government's opponents - it is a normal state of affairs and happens everywhere. Any party, in any country, which has a parliamentary majority, can govern easily. This is possible, even when the majority is very small - and even in Europe. Look at Portugal when Cavaquo Silva was Prime Minister. There were people who said it was a PSD State. You will be familiar with France when Pompidou and even de Gaulle were in power, and Francis Mitterrand used to speak of a Gaullist state. As far as the election campaign is concerned, I am not aware of the government here having monopolised state resources and I don't believe this has happened.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Another important factor involved in democracy is the press. Several journalists from the private media sector are awaiting a decision from you on a number of points - for example the lack of pubic support for the private press - in contrast to thestate-run press which has access to all that it needs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - What decision are they waiting for ? Do they want me to decide in favour of resourcess being given to the private media ? I have already done that on a number of occasions. Recently, I had a meeting with the Prime Minister and I brought this matter up. He told me that it was something that was currently being considered. Sometimes, however, I get the impression that some of my critics want me to do the work of an opposition leader and to oppose the Government. That is not my job. I think that the President of the Republic, in a regime such as ours, ought to be a unifying force and not someone who foments political tension and instability. That is something I have always tried to avoid, but I do have sufficient courage to tell the government and the Prime Minister exactly what I think and I have actually dared to criticise them publicly several times. I am sole judge of the criticism I make, and I decide if it is appropriate and also when the time is right. Sometimes, people would have   me criticise the government according to a timetable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· A number of journalists in the private sector are currently being prosecuted and these actions nearly all originate from sources close to the government Surely if they were actually acting unprofessionally, we would see legal actions from parts of society, such as business, and not just from the political class.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The reason for this is very simple. It is the political class that they vilify. I myself have been insulted on a number of occasions and, despite having put up with it for five years, I have not instigated any lawsuits. There was one case which was taken seriously by the Attorney General's office and there  were other cases when the Prime Minister was called a thief. I would ask you, is this a normal state of affairs ? Does freedom of the press mean that it can call a Minister or the Mayor of Praia a thief? Is that what is meant by democracy ? You have to be aware of the background to these court cases - and there are a good many of them, some dating from 1991. They are not designed to 'get at' any particular newspaper. The reason many of these cases have been brought is because serious insults of the kind we are talking about are a crime. That is true of even the most advanced democracies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· In economic terms, Cape Verde does not appear too badly off. But some economic indicators do give rise to concern, notably the big gap between the export and import figures. How do you see your country's future when it no longer relies so much on international aid ? Do you believe in the dream of many of your fellow countrymen, that Cape Verde will be Africa's 'little dragon'?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Unlike some people, I have never spoken of becoming a dragon. I don't like this expression. I do believe that, despite our enormous problems - Cape Verde has few resources and we have been in the grip of drought for many years - it does have a number of assets. We are capable of making progress and I believe that there are a number of promising areas which have already been identified: for example, fisheries, tourism and even 'foreign' investment. We have to be optimistic about Cape Verde's future. We are in a difficult situation, everyone knows that, but we are a hard-working and courageous people and our prospects are good. The country will be able to forge ahead.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-On the diplomatic front, Cape Verde appears something of an expert at maintaining good relations with different regimes: for instance, with both Israel and the Arab countries, with China, and with South Africa before and after apartheid. How do you manage this ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - There is no magic formula. Since independence, Cape Verde has tried to adopt a realistic and pragmatic foreign policy. We are a small country with no great influence on the international scene and we have to be on good terms with everyone. That is the principle on which we base our foreign policy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Cape Verde and Guinea Bissau used to be fairly close - do you foresee any future rapprochement, perhaps in some form of federation ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - It is difficult to say. I feel that there is already a degree of rapprochement in progress, particularly in economic terms. Recently, we signed a civil aviation cooperation agreement, and there are opportunities for similar achievements in the fisheries and shipping sectors as well. Relations between the Cape Verde and Guinea Bissau governments are excellent but, to my mind, the idea of our forming a federation is out of date. It would not be in our interests nor in those of Guinea Bissau. We do, however, intend to develop a closer economic relationship and our political relations are very good indeed. I would wager that our partners in Guinea Bissau would give you a similar analysis of the situation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-In cultural terms, can it be said that your country has succeeded in becoming a multi-ethnic state ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The important thing is that the Cape Verde people should have their own identity; that there should be a specific Cape Verde culture. What I would say is that all the citizens of Cape Verde are proud of their culture and citizenship. This constitutes a great source of strength for a country such as ours which has major challenges to overcome. Our culture is also an asset in our country's development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Interview by Hegel Goutier</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Interview with Aristides Lima, leader of the Opposition</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'The government owes its victory to abuse of the electoral system'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· As main leader of the Opposition, what are your views on the fact that the governing party has recently been reelected ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I believe the country's economy is in crisis. Growth rates are not very high, just like in the 1980s, for example, and there is a high level of structural imbalance. Unemployment has increased: in 1990, unemployment stood at approximately 25% and now it is 30%. There used to be 25 000 people who worked in what we call the high intensity labour sector and who had a job for about 10 months of the year. They were recently laid off early. Such jobs were part of a social programme which, amongst other things, enabled us to build roads. The prices of staple products, such as sugar, maize and rice, which were stable, have just gone up, and the price of cement, which was also controlled to promote economic growth, is no longer subject to the same control and I can foresee this giving rise to many problems in areas outside the towns and cities. In Praia, a 50-kg bag of cement used to cost 440 escudos and, although that price will stay more or less the same, on islands like Fogo, it will go up to about 660 escudos. This will generate problems for economic growth and a number of major projects in the tourism sector, for example, will suffer. The balance between exports and imports has also been adversely affected in that the level of coverage of imports by exports has fallen, despite announcements to the contrary made by the government.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· From 1993 to 1995, exports tripled in volume, if the government is to be believed. What are your thoughts on that ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The problem is that, in this country, some exports rely on the import of considerable amounts of raw materials. For example, in S&atilde;o Vicente, there is a shoe-manufacturing plant which gets its supplies of raw materials from abroad. The same applies to fishing and a number of fisheries products, such as anchovies, which are still canned in S&atilde;o Vicente but which have to be imported from Chile or elsewhere. This causes great problems when it comes to managing the country's foreign currency reserves, which have fallen markedly. In 1990, reserves provided over 6 months' coverage for imports, but now we have to operate in terms of weeks or even days.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Nevertheless, the government could say that it is not responsible for the economic picture you have just painted because the world economic situation is hitting all small countries harder.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - No, the government is responsible, because it has been unable to implement the appropriate liberalization policy. For example, this should have been applied gradually to the trade sector, but the government rushed in and has now had to backtrack on goods which needed import authorization. What happened was that it lifted this authorization requirement but has now  had to bring it in once again. And another thing, the policy of liberalization has not been accompanied by very high levels of foreign investment and, in addition, the country's skilled workers feel marginalised, all of which goes to make the situation worse. As for structural adjustment, the government has always supported the idea of 'less State equals a better State', but, in practice, we have seen spending on the State's everyday activities go up and up. Civil service staff levels have now risen to about 12 000, compared with the former 10 000. However, increased spending is also a result of a not always equitable wages policy - the difference between the highest and lowest salaries is huge and, in some public bodies, one worker might be earning 15 times as much as another.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· According to the Minister for Economic Coordination, the currency is under pressure as a result of the Opposition's irresponsible scare tactics of announcing a future devaluation, leading to the stock-piling of currency and goods, a kind of artificial speculation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - That's a very good way of offloading one's responsibilities - the Opposition did no more than criticise the government's policy and point to the   facts of the situation. It was members of the government themselves who acknowledged the low levels of currency reserves and the State bank which suspended transfers abroad. The Minister would have people believe that the Opposition lacks any credibility so how could this same Opposition have any influence on peoples' behaviour? The problem is actually extremely basic: economic operators, society and foreigners are not really au fait with the country's real economic situation because the government does not issue information, which is one of our basic criticisms. Parliamentary representatives and political parties no longer receive the figures they need and the latter are sometimes forced to consult foreign sources or to rely on their personal links with people who are close to sources of information. I myself criticised the Prime Minister for adopting this attitude of regarding information as subversive. I asked the Prime Minister for a copy of the study on Cape Verde's economy by a Portuguese professor, which had been paid for with tax payers' money. I never received it. For our part, we hope that Cape Verde's partners will be able to recognise the true situation and persuade the government to act in a more equitable manner.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Nonetheless the people cannot be too disappointed, because they reelected the government for another term.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - That could be explained in many ways - the government controls information and therefore holds the reins of power. It controls television, radio, part of the print media, and the private-press sector is fairly weak, so it has been able to manipulate information and give people the idea that the country is on the right track. The government did do things to change peoples' lives, but it exaggerated its achievements using the State social communication means available to it. In fact, it did not achieve the major objectives it set itself: firstly its fight against unemployment - a failure. Balancing foreign economic relations - another failure. Balancing the domestic  economic situation: differences between our various islands have become more acute. In matters of health, Cape Verde made major advances when our party was in power and, although, to all intents and purposes, the health sector is just as good when compared with other African countries, it has, in fact, deteriorated. Diseases which had been eradicated from the country are returning, like malaria, for example, cholera, etc. Health services are concentrated in the capital city, Praia, and there is no decentralisation, which has negative effects on even links between carers and patients. Humanism shows the effects of a situation such as this, and it applies not only to health: there is an unfair distribution of State financial resources between the central government and local government. The State has been unable to reform local finances and has politicised transfers of funds to those districts which are closest to it. The government has also profited from the structural problems encountered in the working of our democracy. One of these structural problems is Parliament's weakness: it sits only three times a year and the representatives do not work full-time - they are sometimes employed by the administration which they are supposed to monitor. Democracy has a price and although savings can be made in other spheres, when one is  seeking good governance, one of the conditions for which is a strong, functional and effective Parliament, this is not possible. The weakness of the private-press sector is yet another problem.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-And are you continuing to work in the administration ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I am a 'full-time' parliamentary representative. There are now about 10 out of 79 representatives who work on a full-time basis. They are members of Parliament's office, chairmen of committees and parliamentary leaders.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-The government says that it inherited a serious state of affairs when it took over power from the PAICV.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - It is simply not true that the good life began with this government's accession to power. Here's a little history lesson: think back to colonial times. Admittedly, there were negative aspects to our time in power but you must remember that the PAICV did, in fact, leave in place the subjective.  physical basis for the new policy direction. When we achieved independence, Cape Verde had no ports or airports, apart from small-scale port facilities at S&atilde;o Vicente. We built the port at Praia, the port at Sal, the port at S&atilde;o Nicolau and a number of airports. The telecommunications system was also set up by the PAICV government and we implemented the initial educational reforms. In the 1980s, the GDP growth rate was 7%and the per capita income was one of the highest in Africa, more than $820.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The party in power describes the PAICV as marxist and non-democratic claiming that it was they, not the PAICV, who introduced democracy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - That is nothing more than rhetoric, because all of the current governing party's members were in the PAICV - they were radicals, more marxist than anyone. Everyone knows that here, in Cape Verde, we had a pragmatic party, not a marxist party, although marxism was a source of ideas for many people. The idea was not to build socialism here. In those days, we had an open, not a centralised economy and all trade was private. We always had a market economy and to describe us as non-democratic is idle rhetoric. The PAICV's ideology has always been one of national liberation based on political and economic independence, with power vested in the people. This was a normal state of affairs during a national liberation struggle and, although it would be true to say that we were influenced by a certain single-party model which had gained widespread acceptance in Africa, the single party here could not be compared with any other. Both the PAIGC and later the PAICV attempted to force people into taking part in citizens' assemblies in order to put forward suggestions to the candidates. The current Prime Minister, Mr Veiga, for example, was put forward by a militants' assembly - he was on the PAICV's lists and they used to sit one beside the other on the benches in Parliament. The regime was, I suppose, slightly paternalistic but it was the people themselves who were really responsible for national liberation, it was they who had an idea of justice, patriotism, of being African, which explains the total commitment of Cape Verde's people to our party in the struggle for independence and also the good results we achieved when in power.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Why, then, were you not re-elected ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The party had been in power for a long time, with the same president, the same prime minister, the same president of the national assembly and virtually all the same ministers. People were hungry for change because the ruling elite had been in place for so long. The international scene, also, did not favour the old single-party system. Another element, too, was the Church, which fought us over the question of abortion. Perhaps I should point out that, from the very beginning, a section of the Catholic church was not in favour of independence, but younger members of the clergy, with more sympathetic feelings towards the population, supported us and, thus, we changed peoples' attitudes. The Church in Africa is a phenomenon worthy of greater analysis, particularly in Cape Verde, where, I feel, the current government was able to take advantage of the Cape Verde peoples) essentially religious nature to criticise us and present us as an anticlerical party. In fact, the situation is quite different: most PAICV leaders and militants are Roman Catholics and some church" were damaged by opponents in an attempt to discredit the party. Another example of abuse of the electoral system, apart from taking advantage of the peoples' religious nature, is the country's poverty. During election campaigns, the government make it easier for people to obtain food, and it also creates more jobs, en masse, but these disappear again after the elections - precisely as is happening at the moment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· As it is governed at the moment, Cape Verde is regarded by other countries as a 'star pupil'. Surely this is another success for the government ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Cape Verde has always been regarded as a star pupil because, here, our society is fairly homogeneous and there are no major social or ethnic imbalances. However, in my opinion, the future depends on changes at a structural level and such changes cannot take place unless we have a functioning parliament and a strong private press. I cannot deny that the government has had some successes, but I also believe that the people will have an opportunity to judge how it keeps its promises.  interview by Hegei Gouger</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">A portrait of towns and cities with atmosphere</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It suffices for an unruly little bird to escape</P>
+<P ALIGN="JUSTIFY">For, suddenly, Fire to spark, Night to dissolve</P>
+<P ALIGN="JUSTIFY">The walls of every prison to cave in</P>
+<P ALIGN="JUSTIFY">From the tidal-wave battering</P>
+<P ALIGN="JUSTIFY">Amassed, in its untamed heart,</P>
+<P ALIGN="JUSTIFY">By a tiny breathless bird.</P>
+<P ALIGN="JUSTIFY">(Mario Fonseca in 'La Mer a tous les coupe')</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most cities in the Third World devote all their energy to mere survival and there are few imbued with the same atmosphere as Mindelo - the very air  appears to brim over with art and good taste, beauty and sensuality. Our guide to the city speaks slowly, measuring his words, his delivery not an indication that he is searching for a translation, although it could be interpreted as an affectation, but matching the modulation of the language which is closest to his heart: 'I believe the air in this city is imbued with hedonism. Here, we mix work and pleasure - today is a holiday, but I am working. However, my day is not so rigidly timetabled that I cannot do some work and, since you have invited me out for a drink, take some time off to accept'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antonio Firmino, director of the Craft Centre, continues to tell us about his favourite city in the same steady language, a dreamy look in his eyes and wearing a Che Guevara-style beret. The tale he tells is the story of a tiny country which has fallen in love with culture: the actual building housing the Craft Centre used to be a school, the 'Mindelo Technical College', founded in 1917, the first secular educational institution. It was to transform the city into a cultural haven. The story goes that a certain senator named Vera Cruz, who represented the island of S&atilde;o Vicente in the Portuguese Senate, wanted to establish Cape Verde's first college. His peers objected, arguing that Mindelo had no building worthy of housing an institution of such a high standing but</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vera Cruz straight away replied: 'So, why not use mine?'. Thus, he casually handed over his private residence.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Art even in the fish market</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">How many inhabitants are there in Mindelo? According to Antonio Firmino, 'Just me and my friends'. How right he is. It would be impossible not to become part of such a captivating place. And so a long journey began, which included the creation of Claridade, a review (and cultural movement) established in 1938 by Balthasar Lopes, a writer and essayist of world renown who was born in S&atilde;o Nicolau but taught in Mindelo, and other great artists who were to make up the country's literary and artistic roll of honour. Claridade was to be followed by Certeza which was also to influence the cultural elite. Although historians and other commentators feel that Claridade did no more than praise Cape Verde's 'latinity', rejecting its African side, artists are unanimous in regarding it as the cradle of Cape Verdian intellectual culture and the soil which was to nurture Mindelo and make it such an extraordinary little town. The impression is that everyone here is interested in art - the local authorities encourage and help sculptors in their creative activities all over the town, making it a living museum: here, there is a painting by Antonio Concei&ccedil;&auml;o and, over there, a huge flat sculpture of couples in languorous embraces, by Ro and Anildo, an illustration of the marvellous hedonism evoked by our host.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The same assured but delicate touch of these two artists can be seen in the lobby of Fishpackers, an anchovy- and tunapacking company, this time in the form of a celebration of fishermen. One of the finest examples of this type of art, which can be seen everywhere in the streets and public places, is the sequence of four huge decorative-tile frescoes in the fish market. When Bela Duarte showed them to us, it was such a delight to see how much at ease this famous artist was in the company of the staliholders, to whom both she and her work seemed so familiar.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over and above this hedonistic atmosphere, there is, in Mindelo, an eclecticism which can be detected just as widely in other towns and cities, which means that you can talk about painting with the President of the Republic, dancing with a factory manager and decorative tiles with the man in the street. And the latter is literally 'in the street' - the inhabitants of S&atilde;o Vicente, the capital, derive immense pleasure from strolling in its squares and narrow streets, and around the port. A little stall, looking like a sugar loaf in the middle of one of the city's many squares, opposite a grand hotel, opens up in the early evening just like a flower, attracting hundreds of people to it who come to quench their thirst, to converse or woo, and to dance to the music escaping from the terrace of the Porto Grande Hotel, which has just reopened after being privatised and modernised.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is as if a dress ball were taking place on two different levels, one in front of the other, dancing to the same music and with equal pleasure: above, in an enormous gallery open to the sky, elegant guests (who include a small gathering of government officials and pretty Brazilian actresses who are here to film television soaps) and, down in the square, the dancing promenaders, full of admiration, almost stimulating those above.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cape Verdian nights</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like all the island's intellectuals, Antonio Firmino has a number of different jobs. In addition to running the </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Craft Centre, he teaches 'nautical' English to would-be sailors, is an amateur painter and musician (he plays and composes for his wife, who is a singer). His spare time is devoted to writing a column. The Craft Centre exhibits, amongst other things, a large number of tapestries, an art form much prized in Cape Verde. These admirable examples are by Ju&auml;n Fortes, Juamo Pento, and a good many others, in particular Bela Duarte, Tchal&ecirc; Figueira, Lucia Queiros and Miguel Figueira, Mindelo's top artistic foursome who appear to be  involved in everything, including the frescoes at the fish market. Bela, who showed us her studio, her house and the fish market, does not conceal the joy she derives from colour and allusion in her pictures, tapestries or decorative tiles, ranging from the most distant abstraction to an anecdotal figuration, using her native land with its doleful nuances, soft cries and romantic strength as raw  material. Above all, there is convivial artistic writing: 'Resistencia', which is at first sight a tapestry and then a patchwork of colour and sinuous lines. Scarcely has the artist begun to explain her work than everything becomes clear: this is a story, in threads and colours, about drought, representing roots, energy, space and struggle, all part of the Cape Verdian soul. She is also paying homage to those weavers of traditional African loincloth (badiu) from Cape Verde from whom today's artists inherited their technique.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So, where to meet Antonio's friends? To find them, look no further than the Cape Verdian nights (noite caboverdiana), those gatherings which take place everywhere and resemble both a nightclub and an artistic association, all those present sharing a fondness for Cape Verde mingled with nostalgia and yearning. One such place is the Piano Bar, which was closed on account of the departure of its owner Chico Serra, another notable in local society, who was accompanying a friend, C&eacute;saria Evora, in her attempt to conquer new lands. Mission accomplished, Chico Serra is back and will soon be open for business again, his club's atmosphere just as intimate and warm as before - just enough room for his piano, his musician friends and others who come to sample grog and music.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Africa nonetheless</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mario Fonseca also adores Mindelo but he would not agree that that wind-blown city has a monopoly on art and culture. He is from an island in the lee of the wind, from Praia, capital of the island of Santiago and of the country. In his opinion, it is the whole of Cape Verde which is bubbling with creativity and he will enchant you with his tales of Praia and its old colonial district, the 'Plateau', which still retains much of the nostalgic character to be seen in the now yellowing photographs taken 50 years ago when the city was not so sprawling and the ambience of Sucupira market was almost tangible. He will also tell you everything about the island of Santiago, with Cidade Velha, the ancient capital  which was too difficult to defend against repeated pirate attacks. It bowed to Praia's supremacy and, today, has an old-fashioned feeling, nestling within a cove around the ruins of its castle, and dominated by the fort which perches above a cliff face. The architecture owes much of its charm to the predominant Creole style which is vaguely reminiscent of Portugal, in every pastel shade. Cidade Velha's central square is caressed by a gentle breeze and groups of young people can always be seen lazing around the monument to the slaves. Time seems to stand still. The pretty little white church whose walls are decorated with sheaves of bougainvillaea, Santa Maria do Rosario, is the oldest on the island and, indeed, along the entire West African coast. It was built in 1460 and the white marble paving in the central nave conceals the final resting place of grandees from colonial times, their epitaphs erased over five hundred years by the soles and knees of penitents.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The director of the INAC (National Cultural Institute), responsible for Praia National Museum (which is soon to open its doors), is Mario Alberto de Almeida Fonseca, who once taught French in Portugal; he is a former administrator who has worked in Mauritania and Turkey, a translator and also a former regional manager of the national airline. In addition he is a poet whose works have been translated into several languages, including Serbo-Croat and Russian. Above all, he is an amateur connoisseur of the art and artists of his country. As the INAC's director, he is responsible for cultural events, exhibitions, shows, publishing and also the compilation of an oral record of the country's history and the preparation of  a Creole dictionary. The INAC's work also involves a major history of Cape Verde, the first volume of which has already been published. He will show you the future National Museum's collection, moving from one painting to another, from an old photograph to an antique cimboa, a type of locally-manufactured violin from the 1 9th century, or to an old Massachusetts galleon, testament to the past explorations of his people. You will first of all discover the works of artists from Praia such as Mito and Kiki Lima, not on account of Fonseca's chauvinism but because he feels he has to 'convert' the visitor who may have left Mindelo with the impression that that city is Cape Verde's premier cultural centre. There is also the music from the island of Santiago - the funana, the batuque, the fina&ccedil;o - all more African than the languid style so influenced by the Portuguese fado of this island's musical groups (Fina&ccedil;on, Bulimundo, Tuvaroes, Kod&eacute; di Dona or the great traditional style singer Nha Inacia Gomes). Gomes is a 'women of the people' whose musical heritage consists of no more than local tradition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It was she who 'reinvented' jazz and whom Alberto Fonseca admires a great deal. Cesaria Evora, moreover, is not the first musician to publicise Cape Verdian music abroad: Fina&ccedil;on or Kod&eacute; di Dona, for example, have captivated many music-lovers, particularly musicians, in Europe and America.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Chamber and the stage</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Daniel Brito is not from Mindelo either. He is from Sal but confesses to having to pay regular visits to Mindelo, to immerse himself in that city's hedonistic atmosphere. For three years he has been director of the National Cinematographic Institute which was established in 1967 and is currently exhibiting newfound dynamism on account of the 'production tax' (4% of the filming budget, paid to the Institute and generally converted into a holding, which the State supplements to make the sum up to slightly more than 10% in co-productions). There is also an agreement with Portugal which encourages co-productions between the two countries, thereby enabling Cape Verdian technicians to receive their training. Brito is working on a local video-film-production project (TV viewers are very fond of such things) and wants to set up a major production centre to be made available to lusophone African countries and, perhaps, others. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Daniel Spencer Brito is also Sal's parliamentary representative (10 000 inhabitants), musician, writer/composer and guitarist in his own group, Madrugada. His talents include the composition of morna and coladeira pieces, as well as jazz-rock. At the end of May, the MP was due to appear in his own production at the Cirque d'Hiver in Paris, as part of the lusophone music festival. You could say that he divides his time between the Institute, the Chamber and the stage; however, he is also involved in research into copyright protection in Cape Verde. Daniel (it would never occur to you to call him anything else, even five minutes after making his acquaintance) always gives the same advice to anyone wishing to discover Cape Verde, namely to get to know the atmosphere of a tocatinha, spontaneous jam sessions which take place at one location or another, usually even more intimate than the 'Cape Verdian nights'. By the way, I almost forgot - by training, Brito is a vet, having studied in Romania. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H&eacute;gel Goutier</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Cape Verd-EU Cooperation</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sponsors are delighted at the full use of aid</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cape Verde's physical characteristics - its small size, the fact that its territory is scattered over a number of islands and islets, its Sahelian climate (continually rendering it vulnerable to drought), the arid nature of the soil and its low population (under five hundred  thousand inhabitants) - might explain its high levels of poverty and mean that, in order to survive and develop, it requires considerable amounts of foreign aid. However, it is the effort made by this small country to stabilise its economy and to gain maximum profit from foreign aid which has attracted special attention from sponsors. Last year the European Commission decided to increase its contribution to Cape Verde's National Indicative Programme, within the framework of the Lom&eacute; Convention (tome IV, first protocol 199-95, seventh EDF) by 7%, i.e. an extra ECU 1.7 million. Cape Verde had already put virtually all the ECU 23 million allocated to it to good use, an indication of the government's desire to use the aid granted to the full.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When realism is a luxury</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is difficult to imagine an island inhabited by 160 000 people - the island of S&atilde;o Vicente, where the country's second largest city, Mindelo, with its population of 70 000, is located - having no source of drinking water. In former times, water was shipped in from the neighbouring island of Santo Antao, but Mindelo now has a number of seawater desalination plants, most of these provided by Israel, which meet 100% of its supply needs. The supply of both water and electricity is managed by</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Electra, a publicly-owned company, which, within the framework of the EDF (European Development Fund), has received European Commission aid to increase its electricity-generating capacity. It has set up three wind pumps, of Danish manufacture, which alone supply 13% of the island's non-industrial requirements. Elsewhere, such solutions as sea-water desalination and wind pumps might appear to be unrealistic but, for 160 000 people with no indigenous supply, realism is sometimes a luxury.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although the island of Santiago, which is home to Praia, the capital city, does have some natural water sources, these are far from sufficient for its needs. One of the projects recently financed by the European Union concerned improvements to water-distribution systems, water purity and rainwater drainage. Amongst other things, this work involves the recycling of waste water which the island cannot afford to let drain away. Cape Verde's Achilles' heel is definitely its lack of water, its strong point unquestionably the dynamic outlook of its population.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Commission has an office on Cape Verde where the work done at Praia (water distribution and purity, support for poorer districts of the capital threatened with overpopulation) is regarded as symbolic of the EU's desire to take account of both weaknesses and strengths and represents the overall intention behind Community aid to this country. Generally speaking, such aid is geared towards infrastructures (water and electricity production and distribution, urban development) on the one hand and education and health on the other.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Praia's historic old town, the 'Plateau', with its wealth of fine colonial and neo-classical architecture, risks losing many of its buildings which have been abandoned by their owners who lack the means to maintain them. Community aid has also been provided to help save this part of the country's heritage. Funds are insufficient to finance a complete restoration of the 'Plateau', but, following the example of the Cape Verde government, which has maintained administrative buildings in good condition, the Commission will probably assume responsibility for renovation of a superb nineteenth-century building, the 'Case Cor-de-Rosa'. The purpose of this project is two-fold; not only will the building be restored, but also it will become the core of a more general project to train professionals in building techniques and restoration and it will serve as an example to motivate future purchasers, institutions, businesses and individuals to preserve the historic old town.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Community has also funded a study into the preservation of the capital's historic old town, which has been used as a basis by Praia Town Council. A project is currently underway, costing 1 million ECU, to restore an islet. The principal aim of this project is to train Cape Verdian technicians. Other work in the field of training has induded the building of the Praia Technical College. The next phase of this project, worth almost ECU 1 million, will fund the supply of equipment and teacher training.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Still within the context of the overall project to develop Praia city, an EDF programme worth ECU 1.3 million has been created for the development of a designated area as an industrial site. A rural electrification project in the area around Praia was, at the end of 1995, granted a budget of ECU 1.5 million and will benefit a population of 7500 people living in the three most densely populated rural centres on the island of Santiago. The technical side of the works will be entrusted to Electra, with the private sector being responsible for supplying equipment and monitoring the works. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cape Verde's 'essence' as a resource</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cape Verde's leaders regularly point to the richness, which they term the 'essence', of Cape Verde, contrasting this with the fact that their country is so poor. Indeed, despite limited resources, this country devotes a great deal of energy and ingenuity to 'cultivating' its culture. Two projects, financed within the framework of the National Indicative Programme and amounting to ECU 500 000, concern two feature-length films and will play a part in lessening the island's isolation by publicising its culture and people abroad. The first film, made during 1995 and entitled 'llh&eacute;u de Contenda', is the first fiction-based feature film to be made in Cape Verde and is the work of Leao Lopes, a director who has drawn his inspiration from the work of another Cape Verdian citizen, Teixeira de Sousa, and which centres on the history of Cape Verde and the birth of its national identity. The EDF contribution (approximately ECU 250 thousand) amounts to 14% of the total production cost. The film is currently being shown in a number of European countries. Virtually the same amount of  money has been set aside to fund another production, this time by a Portuguese director, Francisco Manso, based on a novel by a Cape Verdian author, Germano de Almeida, and entitled 'O Testamento do Sr. Napuceno', which was being filmed on the island of S&atilde;o Vicente at the time of our visit. 50% of the finance for this film comes from Portuguese producers, the other co-producers being French and Belgian.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Others EDF projects recently completed or being completed include one for improving roads on the islands of Santiago, S&atilde;o Nicolau and Maio (ECU 3 million) and a micro-project programme (ECU 1 million). In addition to funds from the EDF, Cape Verde has received further finance under the Lom&eacute; Convention, including ECU 700 000 within the context of the Stabex transfer schemes to offset loses in the banana-production sector during 1994.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Design a micro climate</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Extemal food aid is essential in a country which cannot meet its own requirements and the Commission's most recent food-aid-budget contribution amounted to nearly ECU 2 million. Other special budget lines include funds provided under 'Human Rights and Democratisation in Developing Countries'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To an attentive foreign visitor, one of Cape Verde's most interesting achievements is the progress it has made in reforesting such an infertile soil. One of these reforested areas, covering 5000 hectares (1990-94) forms the basis of a regional project to disseminate knowhow accumulated in this sphere in Cape Verde. Training course. have enabled technicians and others involved in the reformtation of the Sahel countries to gain experience in methods which have proved succesful here. The production and distribution of teaching tools (books, posters, films, etc.) supplement the project. Since independence, Cape Verde has achieved a tenfold increase in the amount of land which is forested - admittedly there was little to start with, but since climatic conditions are so hostile this result can be regarded as a major accomplishment. There is even a hope that a micro-climate might form. On the island of Santiago, in some of these new green areas, wild duck which had long since disappeared have returned. It is nice to dream but the country cannot afford to rest on its laurels.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">H&eacute;gel Goutier </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Profile</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">General information</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Area: 4 033 km2 Population: 390 000 (1990) Population density: 97 per km2 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Population growth rate: 2.8 % (forecast for the period 19922000) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Capital: Praia (pop. 75 000)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other main town: Mindelo (pop. 65 000) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Languages: Portuguese, Creole</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Currency: Cape Verde Escudo (CVE). In May 1996,1 ECU was worth CVE 104 ($1 = CVE 83 approx.) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Politics</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Government: Mixed presidential/parliamentary system. The President is not the head of the executive but he represents the country and is guarantor of national unity and the Constitution. Unicameral Parliament. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">President: Antonio Mascarenhas Monteiro (elected in 1991 and reselected at the beginning of this year) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Prime Minister: Carlos Veiga (since 1991) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Political parties represented in Parliament:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Movimento pare a Democracia (MPD)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Partido Africano pare a Independencia de Cabo Verde (PAICV)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Partido da Convergencia Democratica (PCD) - formed as a result of a break away from the MPD</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Party representation in Parliament: MPD 50, PAICV 21, PCD 1 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(1992 figures)</P>
+<P ALIGN="JUSTIFY">GDP: CVE 23.9 billion</P>
+<P ALIGN="JUSTIFY">GDP per capita: US $840</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Origin of GDP by sector: agriculture 13%, industry 17%, services 70% </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Real GDP growth (estimate 1995): 4% Balance of payments: deficit of CVE 11.9 billion </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Main trade partners: Portugal, Spain, Netherlands, Brazil. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Annual inflation rate: 9.1%</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Social indicators</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Life expectancy at birth: 64.7</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Infant mortality per 1000 live births: 56 Adult literacy: 66.4% </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Enrolment in education (primary, secondary and tertiary): 59% </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Human Development Index rating: 0.536 (123rd out of 174) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sources: UNDP Human Development Report, 1995; Economic Intelligence Unit 1995; 'Etat et soci&eacute;t&eacute; aux iles du Cap Vert, by Michel Lesourd. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p32a.png"></center><br>
+ Figure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Europe</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">The Lom&eacute; Convention in focus</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Poll results and new brochure launched in Brussels</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A new poll of Europeans high lights a deficit of information about the European Community's development policies. A brochure just published on the Lom&eacute; Convention, available in all EU languages, seeks to fill some of the gaps.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At a press conference on May 21, Development Commissioner, Joso de Deus Pinheiro, unveiled the findings of a survey commissioned from the Brussels consultancy, International Research Associates (INRA). The aim of the exercise was to sound out how Europeans perceive developing countries. The sample was 16 346 people, of 15 years and upwards, who were polled in the 15 Member States during December 1995.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The survey shows that since 1991, helping the poor in the developing countries has slipped in the 'league' of issues of most concern to Europeans. The subject now ranks eighth in a table topped by the fight against unemployment. But the better news is that Europeans believe development of these regions should be the fourth most important priority for joint actions between Member States. This comes just below combating terrorism, environmental questions and defending Europe's economic interests.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While 82% of Europeans are favourable to development cooperation, 12% are against. The degree of support varies, as one would expect, from one EU country to another. Interestingly, the survey shows that Member States facing an economic squeeze are the most reticent, irrespective of their past track record in development aid. In Belgium, only 65% are in favour while in</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Austria and France, the figures are 69% and 72% respectively. At the other end of the scale, Greece comes out top with 97% just ahead of Spain on 96% and Ireland on 91%. INRA's explanation for this variation is that it reflects the economic problems which are increasingly being felt in northern states of the Community. It is also worth pointing out that nations on EU's southern flank may be more convinced of the effectiveness of aid since they themselves are recipients of EC structural funds allocated to modernise the Union's disadvantaged regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But INRA's report also reveals some misconceptions about European development aid. These, says Commissioner Pinheiro, may be attributed to the lack of visibility of the relevant development policies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">57% of those questioned believe that the bulk of the Community's assistance consists of emergency aid, rather than longer-term project support. The reverse is actually true. More people answer 'no' then 'yes' to the question: 'Does aid contribute to reducing poverty in developing countries'? And most consider that United Nations agencies (UNICEF, UNESCO etc.) do more in the  field of helping developing countries than the EC. Non-governmental organisations also have a high profile, with the EU Member States and Bretton Woods institutions (IMF and World Bank) trailing behind.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other key findings from the poll - which Professor Pinheiro says will provide much food for thought in the coming months as thoughts turn to cooperation after Lom&eacute; IV - are highlighted in the box.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mid-term review and beyond</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Professor Pinheiro feels that some of results, which signal the need to tighten up on the management of development aid, have already been addressed in the mid-term review of the Lom&eacute; Convention which will come on stream from the beginning of 1997. The programming of the eighth European Development Fund (EDF) is already well under way and, with a view to increasing the effectiveness of aid, just 70% of resources earmarked for each ACP state will be allocated at the outset (for a three year period). An analysis of how the remainder should be spent will take place at the end of the three years. In addition, Professor Pinheiro indicated that a 'strategic' document was being drawn up on each of the 70 ACP states prior to allocation of funds. This was being done in 'permanent consultation with Member States and Commission delegations, in the interests of achieving a real synergy between the two.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More sweeping changes to the relationship are likely after the current</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some key findings from the INRA report</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Aid must reach its intended destination and arrive where it is needed 93.2%</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Aid must meet the needs of the local people</P>
+<P ALIGN="JUSTIFY">90.7%</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The beneficiary state must raspect human rights</P>
+<P ALIGN="JUSTIFY">85.1%</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Transparency, effective public management and the fight against  corruption are essential</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The beneficiary state must respect an overall development plan put forward by an  international aid organisation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">78.3%  plan  put  forward</P>
+<P ALIGN="JUSTIFY"> by an  internati onal  aid  organisa tion</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Aid must be used to fund action by local NGOs</P>
+<P ALIGN="JUSTIFY"> - The beneficiary state must have a democratic system of government</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">59.3%</P>
+<P ALIGN="JUSTIFY">56.0%</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Convention expires at the turn of the century. Professor Pinheiro indicated that a first draft (green paper) on the possible shape of the ACP-KU relationship after 2000 will be published by the Commission by the end of the year. This, however, is likely to offer more questions than answers about future cooperation. 'I am not sure if we should keep the Lom&eacute; structure for every country, in the third millennium,' the Commissioner told the assembled journalists, highlighting the different levels of development now apparent between Lom&eacute; nations. Mauritius, now well on the way to becoming the 'Singapore' of Africa, was a case in point. He also pointed out the small island states of the Caribbean are at a very different stage of development from countries such as the Central African Republic or Burundi. He added that, in deciding what to do in future it would also be necessary to take stock of regional developments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Questions about Lom&eacute; answered</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the meantime, efforts are under way to boost the image of Community aid. With this in mind, the Information Unit of the Development Directorate-General has just published a brochure entitled 20 Questions and Answers about the Lom&eacute; Convention.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Besides explaining in a nutshell what the Convention is, it answers some of the questions most frequently asked by sceptics about the benefits of development aid and trade preferences, highlighting the positive aspects for developing and developed economies alike. It points out, for example, that for every ECU 100 spent on aid, the Community recovers ECU 48 in the form of projects, supplies and technical assistance purchased from European companies!</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The brochure provides a succinct explanation of how the Commission monitors aid to stop embezzlement and corruption. It highlights the right of the European Court of Auditors to check accounts of projects and fund transfers - and to investigate documents in the Lom&eacute; states, without the permission of the country concerned. Another precaution is that once a project is under way, financing is by banker's transfer. This involves a paper specifying that the holder of contract X, whose bank account number is Y. should be credited with Z amount of money.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An explanation is given as to why the European Commission is involved in development aid when the Member States have their own bilateral development policies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The brochure explains the advantages of EC assistance over bilateral arrangements and details how the Lom&eacute; system has been evolving in line with the increasing globalisation of the economy, in particular since the fall of the Berlin Wall.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It also contains some pocket statistics on official development assistance (ODA) flows which help to underline the message that the European Union (Community plus Member States) digs deeper into its pocket than its industrialised competitors in providing development aid. In 1994, the Community and its then 12 member states (excluding Austria, Sweden and Finland), contributed an average of 0.40% of their gross national product in ODA. The individual percentages varied from 1.03% in the case of Denmark to 0.20% in Italy. This compared with figures of 0.29% and 0.15% for Japan and the United States respectively.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1994, total ODA from the Twelve reached $26.59 billion. Of this, $4.83 billion came from the European Community in its own right. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D.P. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The content of chocolate</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Months of heated debate in the EU over the maximum allowable content of vegetable fats in chocolate have culminated in a Commission proposal for a revised Directive which, claim officials, should be to the taste of most interested parties.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Commission has proposed that the 'subsidiatity' principle should apply to the content of chocolate. This means leaving it to individual Member States to decide whether they will allow the use of vegetable oil - up to a maximum of 5% by weight - in their chocolate-making. The eight EU countries where this practice is currently prohibited  are free to modify their laws to take account of this 5% rule. The other cocoa butter and dry cocoa contents specified in the Directive - 18% and 35% respectively - may not be reduced.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The addition of up to 5% vegetable fats was authorised under Directive 73/241 for the UK, Ireland and Denmark when they first joined the EC. Other Member States who acceded later - Austria, Finland, Portugal and Sweden - also use these oils in chocolate production. The remaining EU countries have continued to prohibit the use of vegetable fats - and the sale of chocolate containing such fats. The result has been a partitioning of the EU market, in direct conflict with the Single Market principle.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If the proposal is approved by the Council and the Parliament, all 15 Member States will be free to decide whether vegetable oil can be used in making chocolate. Whatever their individual decisions, however, the barriers will come down, thus opening up the 'pure' chocolate markets to competition from less expensive varieties containing vegetable oil. Stricter labelling rules will also be introduced, with the precise nature of any substitute oils being clearly indicated. The simple mention 'vegetable oil' will no longer suffice. Martin Bangemann, the Commissioner responsible for industry, stressed the significance of revising the Directive in allowing  chocolate products to circulate freely throughout the KU. This, he argued, would be in the interests of consumers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Winners and losers</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Traditional cocoa producers such as Cote d'lvoire, Ghana, Nigeria and Cameroon are fearful that the proposal may prompt some of Europe's 'pure' chocolate countries to change their laws - and that they will lose trade as a result. On the other hand, sheanut exporters in Burkina Faso, Mali, Ghana, Togo and Benin are hoping for higher sales if the 5% rule is adopted by more EU countries. Sheanuts account for 20% of Burkinabe exports and 98% of these are used to make vegetable oil substitute for chocolate products. The sheanut price is just 10% of the cocoa bean price. The Commission calculates that the maximum saving a manufacturer could expect by substituting vegetable fat for cocoa butter is around 1.5% of the ax-factory price.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In weighing up what to do, the Commission also considered the objectives of the International Cocoa Organisation (ICCO). These include taking 'all practical measures to increase the cocoa consumption in their countries by eliminating or reducing all obstacles to the growth of consumption in cocoa.' The ICCO estimates that if the 5% rule is applied in the remaining eight states - Belgium, Luxembourg, France, Germany, Greece, Italy, the Netherlands and Spain - it will lead to a reduction in cocoa butter usage of 36 000-50 000 tonnes, which amounts to a drop in demand for cocoa beans of between 88000 and 125000 tonnes. This represents between 9-12% of current consumption.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some producers suggest that these estimates are too high since they assume that manufacturers will go for  almost full substitution, which is not necessarily seen as inevitable. In addition, there is a belief that overall demand for chocolate products may grow as a result of the legal change.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This was not the view taken by NGOs who reacted promptly - and critically - to the Commission text. The Brussels NGO Liaison Committee issued a statement claiming that it would lead to a drop of between 6.25% and 12.5% in the main exporting countries' cocoa receipts - and an additional burden on the European Community's Stabex fund. But chocolate producers and others argue that this is speculative. The impact, they say, will depend on the legal response of the eight Member States, as well as on the reaction of manufacturers. There are signs that the latter may well stick to their traditional and distinctive methods. A spokesperson for the Belgian-based Cote d'Or/ Suchard, pointed out that the proposal had a long way to go before it was approved, and stressed that his company had no intention of changing their 'winning recipes which had served them well since 1883. At the same time, he admitted, vegetable oil could be useful in a more diversified range of chocolate products.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The vegetable oil 'lobby' argues that the addition of vegetable fat makes chocolate easier to mould and less likely to melt in warm climates. And for those who fear the elimination of 'pure' chocolate from the market, they point to manufacturers in Britain, where vegetable oil has traditionally been used, who still exclude such fats from some of their brands.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The proposal must now be debated by the Council and it is clear that the arguing is not over yet. But it is beginning to look as if the consumers may be the final arbiters. Through their purchasing habits, they are likely to be the ones who finally determine the winners and losers in the great chocolate debate. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D.P.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Minority businesses in the UK</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In no country in Europe are ethnic minorities more organised than in the United Kingdom - though they are still not adequately organised, in the opinion of many, to pool their considerable resources together and overcome stereotypes, racism and unenployment. But this may  change if the morale engendered by a recent exhibition of minority businesses in the UK is anything to go by.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The statistics speak for themselves. There are 3.3 million Asians, Africans and Afro-Caribbeans in Britain, about 5% of the population (and the figure is projected to double in the next 25 years). They have six elected Members of Parliament - five Labour and one Conservative - as well as numerous personalities in the world of sports and the media. According to the 1994 Labour Force Survey, 48% of ethnic minorities are graduates or are in full time studies and 55% earn salaries well over &amp;15 000 (ECU 18 000) annually. They have a combined gross annual income estimated at f42 billion and an annual spending power of at least f26 ten.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over the past 15 years, ethnic minority-owned businesses have grown considerably. In the last two years alone, they were responsible for more than 30 000 new business concerns throughout the country, according to the Commission for Racial Equality (CRE). Although many are in the retail trade, the 10% or so involved in production or manufacturing are extremely dynamic,  particularly those connected with the clothing industry or operating franchises.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are considerable differences between Asians on the one hand and Africans and Afro-Caribbeans on the other. The former are more business oriented and account for well over 80% of all ethnic enterprises. This success in business is often attributed to Asians' industriousness, but there is another crucial and often neglected factor: Asians have a stronger sense of group solidarity and patronage than Africans and Afro-Caribbeans. Whereas the former spend virtually all their earnings within their community, the latter (who are mainly Christians and are known to make greater efforts at integration into the British society) spend theirs in the society at large.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unemployment among the black population in general is 19% compared to 8% for whites (in London it is three times higher). They are much more likely to be turned down by employers even when they have better qualifications than their white counterparts. Often self-employment is the only way out. This explains why there has been a boom in business start-ups by ethnic minorities over the past two years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although several black profffsional associations have come into being in recent years, it has been clear for some time to black leaders that the community's energies are dispersed and that these needed to be harnessed for the benefit of ethnic minorities as a whole. Blacks clearly have political and business clout to be exploited.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The idea for an exhibition of black businesses in the United Kingdom was mooted by a black business couple who, were influenced by a similar event  held annually in the United States called 'Black Expo USA'. But the impetus came from the 'Race for Opportunity Campaign' launched in October last year by the Conservative Government through the Department of Trade and Industry. The campaign has so far seen more than 20 big British companies pledge to do business with ethnic minority enterprises. These include British Airways, British Gas, British Telecom, British Aerospace and several high-street banks and finance houses.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Held at the Barbican Centre in London on 4 and 5 May, the exhibition was aimed at creating awareness among ethnic minorities of their potentialities, showing the opportunities available to them not only in the UK but also in Europe, and at promoting networking amongst their businessmen and women. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cross-party support</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The exhibition, which had a cross-party support, could not have come at a more favourable time. Both the Tory government and opposition Labour Party have expressed support for policies favourable to small and medium-sized enterprises, which means that there should be continuity in this area if Labour comes to power in the next general election.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This was borne out by the enthusiasm with which the shadow minister for small business, Mrs Barbara Roche greeted the exhibition. To her, the event should be seen in the context of Labour's overall policy on small businesses. Speaking at one of the seminars which was run alongside the exhibition to discuss various aspects of minority business problems, Mrs Roche explained that there were three important reasons why her party was promoting small enterprises, especially those involved in exports.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first was that large companies were downsizing, and job-creation towards the end of this century and into the next would be largely by small and medium-sized enterprises. The second was that small businesses were efficient distributors of wealth and the third was that they were good at innovation and using new technologies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because a large number of small businesses are folding, or are struggling to survive in the UK today (often as a result of late payment of bills by large companies), Mrs Roche said a Labour government would introduce a statutory limit of 30 days for the settlement of bills by large companies. The latter would then have to pay interest to small businesses for any late payments. Ethnic minority businesses, she also said, were part and parcel of Labour's strategy for economic growth and jobs in Britain.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Barbican exhibition attracted more than 80 exhibitors mainly in retailing, finance, telecommunications, consultancy, arts and crafts, publishing, electronics and education. There were  very few exhibitors from the manufacturing sector (a disappointment considering the number of Asians in the clothing industry) and virtually none in engineering. Some of the big companies connected with the 'Race for Opportunity Campaign' like British Airways and British Gas, as well as the newly created government-backed Business Link, the Customs and Excise department, the Inland Revenue, the Army and the Metropolitan Police were there. Also present was Louis Farrakan's 'Nations of Islam', (not necessarily on a recruitment drive, though that must have been part of the game), but as a reminder of its campaign for greater self-reliance by the black community which culminated late last year in the 'Million-Man' march on Washington DC. Video tapes of the march and speeches by Farrakan and other black leaders in the United States were on sale.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Difficulties</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The seminar run concurrently with the exhibition attracted many notable speakers, among them Members of Parliament, Keith Vaz, Bernie Grant and Barbara Roche and Commissioner Dr Zaka Khan of the Commission for Racial Equality. Jessie Boseman, vice-president of 'Black Expo USA, who was also scheduled to speak, did not turn up.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There was general agreement on the main factors inhibiting the growth of ethnic minority businesses, the most obvious being racism and  discimination. Ethnic businesspeople not only have difficulties obtaining public contracts, but they are often denied access to finance, market and even premises. Furthermore, they suffer from lack of management skills, networks and feedback. Dr Khan of the Commission for Racial Equality highlighted mounting racist attacks, mostly against Asianowned shops, which have claimed a number of lives in recent years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Integration into mainstream economy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is no longer a hidden fact that banks discriminate against black businesses. Surveys carried out by the NatWest and Midland banks have confirmed that fact. The latter though, it must be acknowledged, has a laudable Fellowship Programme, designed to encourage ethnic minority university students to take up careers in the Midland Bank on graduation. Lack of access to the market has effectively meant that black businesses have been left out of the mainstream of the British economy. Everyone agreed that it makes good economic sense to see them integrated into it. This was particularly   the position of both Barbara Roche and Zaka Khan. The question was: would it be possible ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some of the issues raised on the floor by businesspeople revealed that many were sceptical that racism and discrimination could be overcome in multiracial Britain. The Commission for Racial Equality symbolises the fight against these two evils and Dr Khan had a hard time defending its role. The CRE was criticised for constantly quoting statistics on improvements in the living conditions of ethnic minorities which, it was argued, were totally removed from reality. Despite this, Dr Khan remained upbeat. To him the future promises great things for ethnic minorities. He promised to look into the grievances aired by some businespeopie during the seminar. Barbara Roche, for her part, promised that a Labour government would encourage the banks to offer packages of assistance to small enterprises, in particular, black-owned ones. They would also ensure that local councils offered minority enterprises a share of local government contracts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Greater self-reliance and global trade</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In view of the problems black businesspeople have had to contend with over the years, Bernie Grant, the Member of Parliament for Tottenham in North London, did not devote much time to the idea of integrating them into mainstream British economy. He felt that racism and discrimination were so prevalent that there was little chance of that happening. For him, the future for black businesspeople in Britain lay in greater self-reliance and entry into international trade.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In a speech entitled 'political responsibility, and black import and export business', the M.P. set the Barbican exhibition in the context of the global economic situation - one where he said, 'the countries of the North are exploiting those of the South, in particular African countries.' Africa's heavy debts to the West should in fact be the other way round. He argued that the new world trade agreement, which  opens up the developing countries to competition, was unfair. 'This means that countries where minorities in the UK came from are going to have problems, and it is the duty of thee minorities to ensure that their countries have a fair deal,' he said. Mr Grant cited, by way of example, the EU's banana protocol under the Lom&eacute; Convention which gives preferential treatment to small Caribbean island producers and which is currently being 'unfairly' challenged by South American producers under the WTO rules. The role of multinationals, which are effectively acting es 'middleman', was, he believed, pernicious for developing countries. There was a need for black businessmen to step in.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Minority enterprises in the UK do not exist in isolation from the rest of the world, he elaborated. They should seek to engage in international trade and take advantage of their connection with their countries of origin. To facilitate this, Mr Grant said that a group under his chairmanship had set up a Global Trade Centre in his constituency in North London with the aim of helping black and minority enterprises establish direct trade links with Africa, the Caribbean and black America. The Centre was already in contact with a number of African countries which have expressed interest in the idea. Such a link would not only ensure a better deal for African producers but also favour the growth of minority businesses across the world. This was, he confessed, 'a political agenda' designed to reduce the excessive profits of multinationals, if not put an end to their 'outright exploitation' of Africa and the Caribbean. Mrs Roche expressed support for the Centre for the role it could play in boosting British exports.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UK minorities and the</P>
+<P ALIGN="JUSTIFY">European Union</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A self-confessed Eurosceptic, who would have preferred the UK to strengthen economic ties with the Commonwealth rather than with Europe, Mr Grant displayed an extraordinary understanding of the European</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Union's affairs. What worried him most about greater European integration, he said, was racism and the fact the UK job market, where black and ethnic minorities are already heavily disadvantaged, will be exposed to further competition from other Europeans most of whom speak several languages. However, he had no alternative but to support the Labour Party's line on Europe and work to secure the best advantage of British membership for ethnic minorities. He contrasted Tory 'divisions' on Europe with Labour's 'united' policy and condemned the British Government's attitude generally towards the Union.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The development of the Union, Mr Grant said, was of great significance to black people. He was sure the Government's Immigration and Asylum bill, which had come up against strong opposition in the House of Lords, was aimed at harmonising immigration laws with other countries in the Union. The bill, if passed, will change the UK's visa regime and have serious implications for ethnic minorities and their businesses in Britain. He revealed that, with the support of ethnic minority members of the British Parliament, Bill Morris, the black General Secretary of the Transport and General Workers Union (the second biggest trade union in the UK) and other European trade union leaders, the Intergovernmental Conference was being lobbied for the inclusion of a stronger clause against racism in the Treaty of Rome. The aim, ultimately, is to see measures in line with the UK's laws against racism and discrimination enacted at the Union level. This would include the establishment of a European equivalent of the Commission for Racial Equality - with similar powers - so as to establish a level-playing field for ethnic minorities in competition for jobs and in business throughout Europe. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Augustin Oyowe</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Dossier</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Communication and the media</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(Dossier coordinated by Debra Percival)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Press freedom is widely acknowledged as the cornerstone of democracy with a clamp-down anywhere in the world frequently interpreted as a sign of government repression. The rash of multi-party elections in African nations at the beginning of the</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">1990s brought new publications to news-stands. Many of these have since folded - often because of a lack of funds and sometimes because of government censorship.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many organisations are campaigning vigorously in the public eye for a free press in developing nations. These include Reporters Sans Frontieres, Article 19 and the International Federation of Joumalists - all of which are featured in this Dossier. The US-based Freedom House has also been monitoring the state of press freedom worldwide since 1979. In its recently published 1996 survey, it says that even today, only 22% of the world's population live in countries with a free press. 38% have a press sector that is 'partly free' while the description 'not free' is applied to the remaining 40%.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are also regional organisations such as The Media Institute of Southern Africa (MISA), which are playing a part in keeping media issues to the fore. David Nthengwe, a researcher with MISA, highlights the fact that democratisation does not necessarily guarantee a free media or free expression more generally. He also draws attention to the difficulties faced by private and community organisations in obtaining adequate finance. These are  typical of the problems facing the media in many countries, both in the ACP group and elsewhere in the developing world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In seeking to tackle these issues, donors are showing increasing interest in backing media programmes with development finance (linked to democratisation and human rights). The European Union, UNESCO and a number of bilateral donors have expanded their activities in this area with a variety of projects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One big change has been the rapid growth of the 'Information Superhighway'. This has prompted fears that the developing countries may fall further behind, although donors have indicated a willingness to help ensure this does not happen. One NGO closely monitoring the development of the Internet for the South is the PANOS Institute. Meanwhile, multilateral donors (notably the World Bank, through its INFODEV programme) are also becoming involved. A number of EU personalities lent their support to the development of the information society in the developing world, at a major conference staged in South Africa in May on the initiative of the country's Vice President, Thabo Mbeki. A work programme of projects was drawn up with the aim of making sure, in the words of European Commissioner, Martin Bangemann, that there is no divide between the 'information-poor' end the 'information-rich'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Finally, although the world is undergoing an information revolution, the more traditional media (the press and above all, radio) will, for the foreseeable future, continue to have a central part in informing, educating and entertaining people in many developing  countries. It is important that those of us who increasingly communicate via our computer screens do not lose sight of this essential fact.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this Dossier, we examine a number of the key issues affecting the media and highlight some innovative projects in this area - with the help of a series of experts. The subject has clearly moved higher up the development agenda, but there is still a long way to go, as the figures cited above show. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D.P. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Aidan White of the IFJ</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Confronting the age-old problem</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Given the chance, 'governments would like to run and manipulate the media'. This is the view of Aidan White, General Secretary of the Brusselsbased International Federation of Journalists (IFJ), who says it is an 'ageold problem'. And the Federation, which has member organizations in 93 countries, works to prevent it from happening. It also provides a range of services to journalists throughout the world. We recently spoke to Mr White, who used to write for the British daily, The Guardian. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He began by outlining to us the Federation's key areas  of activity which include, in particular, the professional conditions in which journalists work and the defence of human rights. On the first of these, Mr White focused on the problem of economic pressures and difficult social conditions. 'We take a strong view that you can't have press freedom if journalists work in conditions of poverty or technical deprivation. It is a nonsense,' he stressed, 'to talk about a free press in a situation where journalists aren't paid, or if they are unable to function properly.' In seeking to tackle this, he spoke, in particular, of the 'need for independent organisations of journalists defending professional and social interests.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As regards human rights, the IFJ is active in the international community, working with bodies such as UNESCO and the UN Human Rights Commission. 'We are very interested in issues such as the legal environment in which journalists and the media operate, and are extremely active in the defence of physical safety.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mr White went on to give more detailed information about the IFJ's work in Algeria, where many journalists have been killed in recent years. This country clearly has a bad international reputation and the General Secretary was anxious to offer a more balanced picture of the situation. 'In my view, there is a real malformation of Alaeria's  image in Europe and elsewhere. The view we get is of a paralysed society where nothing can function properly - a kind of international basket case. It is not like that. In Algeria, life continues. There is a form of democracy. There are a dozen newspapers which appear every day. The streets are full of traffic and people walking about. The reality is that there is a particularly horrifying and barbaric form of terrorism which is targeted against intellectuals including journalists. This means that the media has a terrible problem.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Aidan White explained the strategy of the IFJ in seeking to confront this. 'We began by going to Algeria to investigate what was going on. Then we established an international office on the spot. This is a direct contact point of solidarity for local journalists and the local media. So we don't report Algeria through Paris. We don't see the need to go through some sort of middleman in order to find out what's going on in the country or have contact with Algerian journalists.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'And then we have two specific programmes which are very important', he continued. One involves providing humanitarian assistance to journalists and their families. The other is a series of practical activities in Algeria. Thus, for example, we are organising a round table on terrorism and information.' He pointed out that the Algerian government had resorted to the traditional method of press censorship in the face of ,the terrorist threat and stressed the 'need to counter this. 'We are also organising a practical seminar on personal safety, as well as one on professional social rights, the need for ethical standards and better social conditions.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The point, he emphasised was that events were being organised on the spot. Algeria may pose terrible difficulties 'but it doesn't mean we walk away from it.' The IFJ's emphasis was firmly on being a 'functional organisation working directly with the people who need help.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Funding and the EU link</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tuming to the issue of the IFJ's funding, Mr White explained how the core activities - his own salary and administrative costs - are paid for by the subscriptions of member organisations, which amount to roughly $1 million. On top of that, the Federation carries out projects with the EU and other donors. They also distribute funds, offering their expertise as a representative body to help other organisations that want to undertake work.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Asked in what way the EU could do more, the General Secretary stressed the political dimension. 'It should intervene,' he argued, 'to establish certain standards in international relations. We say, for instance, that political, economic and military cooperation with any state outside the Union should be based on a commitment to and respect for freedom of expression and opinion.' He underlined the 'responsibility' of the EU to take a stand against countries that locked up journalists, implicitly criticising those who argued that freedom of expression was very important but who then shelved the issue when economic relations were involved.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He also urged a more proactive approach 'moving away from the strategy of counting bodies, complaining, and making reports about how bad the situation is' towards one based on comprehensive programmes of assistance. He described the IFJ's Media for Democracy programme in Africa as a 'first attempt' in that direction. Mr </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">White highlighted what he saw as a difficulty with existing projects. 'The problem is that the EU is confronted by all sorts of different NGOs who come and say: 'we have got this good project - give us support for it'. This is fine but it inevitably means that resources are spread very diffusely and often to no effect.' A lot of activities, he suggested, such as one-off seminars and conferences, were 'like fireworks in the night sky: they glow bright for a brief period and then they disappear.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He went on to plead for an integrated, comprehensive strategy. 'Until that exists, you will not be able to solve the fundamental problems facing journalists.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Training and status</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The discussion moved on to the subject of training. Perhaps surprisingly, Aidan White did not see this as an important priority in itself. As he explained: 'It's no use training journalists to be very high quality if they go off to work in a country where the legal environment does not allow them to function properly. And it's no use training them to be ethical if they go somewhere that is steeped in political or financial corruption, and where there is no culture which appreciates the media's role in democratic society.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With this in mind, he believes that training should be directly related to the strategic approach he referred to earlier. 'Yes, we need professional, well trained journalists, but it should be part of a range of programmes. And professional training is not just important for journalists. It should also be provided for managers, editors, advertisers... and perhaps even for politicians!'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The General Secretary noted that the status of journalists in most countries was quite high. They are seen as a filter for information 'coming from the government to the governed'. This was important, he thought, but 'tine real question is how the filter functions. On the one hand journalists have a relatively high status, and what they do is extremely important, but they work close to the political elites, which means they  are subject to pressure. They must retain their independent role, scrutinising and investigating what governments are doing.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the subject of access to information in developing countries, Aidan White observed that the situation is now better than it was ten years ago but pointed to the 'age-old problem of people in power wanting to control the media.' He gave the example of journalists in Indonesia, 'who really want to speak independently of the government, but who are being killed because they represent independent strands of opinion.' Overall, however, he believes the situation has been improving. 'This is partly due to changes in information technology. A government can no longer simply take a journalist out and beat him up. There are half a dozen press freedom organisations around the world watching for and reporting on such events.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is a tendency in Europe to assume that 'everything in the garden is rosy' in terms of press freedom, and we were interested to hear what the Secretary General thought of this proposition. He was quick to offer a less complacent view. 'We have just issued a very strong statement against the EU about their secrecy policy,' he pointed out. 'You cannot claim the moral high ground for democracy in Africa or elsewhere if you have a system of secrecy in Europe which operates at the highest political level and which denies citizens access to information.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He was also concerned about the concentration of the media in enormous congLom&eacute;rates. This trend, he argued, 'is actually profoundly damaging to the culture of information.' He cited, in this context, the action of the Murdoch organisation 'in banning all news from his cable channels going into China.' Mr White continued: 'They banned the BBC and they banned news coverage in the Chinese language in order to make a business arrangement with the Beijing government. That sort of activity, in our view, is direct censorship from the heart of western democracy.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In conclusion, Aidan White gave some more detailed information about the Media for Democracy programme in Africa which he described as 'ground-breaking.' The Federation has used it to develop key themes, including the coverage of elections. 'The real test of press freedom,' he continued, 'is at an election, because that is when the political pressure is toughest and the professional quality of journalism is exposed. For Africa, we developed a manual on election reporting and, interestingly, it has become the source document worldwide for election reporting.' He explained how it formed the basis for developing a text which is universal. This has been translated into various European languages, and Arabic, and has been employed in Poland, Romania, Albania and Latin America.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the first phase of the Media for Democracy programme, the Federation held a serf. of seminars and conferences on how the media covered elections. As Mr White stressed, this was a crucial time in Africa. Political change was taking place, multi-party democracy was being introduced and there was a need to clarify how elections operated and how they should be reported. 'People didn't have the experience. They wanted the information, and to discuss how things should be done.' The seminars covered aspects such as financial corruption, the organisation of journalists and the role of ethics. And what the IFJ found was that the same kind of things happen in Kenya, Tanzania, Mozambique and South Africa - and indeed across the world. In the words of the Secretary General, 'they have an echo everywhere because, at its root, the problem is the same - those in power want to manipulate the media and use whatever pressures they can.' The lesson learnt from the IFJ's experience in Africa is that common solutions are also valid. Or as Aidan White put it, 'there is no part of the world that can't teach the rest of the world something.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D.M. &amp; S.H.</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Freedom of expression: the first freedom</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Frances d'Souza</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Frances d'Souza who is Executive Director of AROSE 19, a nom governmental organization which campaigns against censorship globally, explains why Freedom of Expression is for her the most important human right</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the absence of freedom of expression, it is almost impossible to protect other rights, including the right to life. Once governments can draw a cloak of secrecy round their actions and remain unaccountable, massive human rights violations can, and do, take place. For this reason alone, the right to free expression, specifically protected in international human rights treaties, must be considered a primary right. It is significant that one of the first indications of a government's intention to depart from democratic principles is when it increases its control over information, usually by gagging the media. At the one end of the spectrum, supposedly minor infringements of this fundamental right occur daily in western democracies; for example the abuse of national security laws to prevent publication of information which might embarrass the authorities. At the other end of the scale are regimes of terror which brutally suppress opposition, information and even the freedom to exercise religious beliefs. Without free speech and an independent media, it is easier for governments to employ propaganda to promote ethnic conflict, war and genocide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The right to freedom of expression is formally protected in major international treaties including the Universal Declaration of Human Rights, the International Covenant on Civil and</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">* This text is an abridged version of a submission made by the author to a public hearing hosted by the European Parliament's Committee on Foreign Affairs, Security and Defence and the Sub-Committee on Human Rights and the Committee on Culture, Youth, Education and the Media, April 25, 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Political Rights (Article 19), and the European Convention on Human Rights (Article 10). It is also enshrined in many national constitutions, although this does not always guarantee its protection. Freedom of expression is something which applies even in countries which have not ratified the relevant international treaties. This is because the Universal Declaration is so widely accepted that its provisions now form part of customary international law.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While it is generally agreed that freedom of expression is the cornerstone of democracy, international treaties permit certain restrictions. Unlike the American First Amendment rights which allow few, if any, checks on free speech, the international treaties aim for a balance between competing rights. Thus, for example, free speech may be limited where it impinges on the individual's right to privacy, or where it involves incitement to violence or hatred. Given that the permitted restrictions are necessarily broad, the limits of free speech are constantly being tested in national courts and in regional tribunals such as the European Commission and Court of Human Rights. In recent years, several landmark cases have helped define what restrictions may be imposed by governments and under what circumstances. In particular, it has been emphasised by the European Court that any restriction should 'pass' a threepart test; it should be prescribed by law (and thus not be arbitrarily imposed), it should be proportionate to the legitimate aims pursued, and it should be demonstrably necessary in a democratic society in order to protect the individual and/or the state.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Who censors what?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite the rules governing restrictions on free speech, many justifications are still invoked by governments in suppressing information which may be inimical to their policies or interests. These include arguments in defence of national security or the 'public interest'. The mechanisms used to restrict the free flow of information range from subtle economic pressures, and devious methods of undermining political opponents and the independent media, to the enactment of restrictive press laws and rules for licensing journalists. In extreme cases, they may involve the illegal detention, torture and disappearance of journalists and others associated with the expression of independent views.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The right of free speech may appear less important than, for example, freedom from torture or extrajudicial killing. It is also sometimes difficult to persuade the public that censorship, generally associated with banning obscene materials, is a bad thing! It requires a recognition of some of the fundamental principles of democracy to understand why censorship is so dangerous. Democracy implies that people can make choices about the issues that affect their lives, including what they wish to see, read, hear or discuss. While this may seem a luxurious freedom, mainly preoccupying the wealthy West, it is a comparatively short distance between state censorship of an offensive book to the silencing of political dissidents. And the distance between this and the use of violence to suppress opposition is even shorter. Censorship tends to grow rapidly from small beginnings. Allowing a government the power to deny people information, however trivial, not only leads to laws and procedures which can and will be used by those in authority against those with less authority. It also denies people the information they need to render their governments accountable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There have been some terrible examples of the role of censorship in recent years. We have seen it in the republics of the former Yugoslavia   where the media were manipulated for propaganda purposes. We have seen it in Rwanda where the government associated radio incited citizens to kill each other in the name of ethnic supremacy. And we have seen it in Iran which maintains the threat of murder against a citizen of another country because he wrote a book which displeased the authorities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are clear links between access to information (or rather the lack of it), and war. Democracy empowers people by increasing participation in decision-making at all levels. The poor, who are denied access to information on decisions which deeply affect their lives, are powerless and have no voice. They cannot influence the ruling elites whose interest in consolidating their own power and position may be served by initiating conflict.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is significant that of the 126 developing countries listed in the 1993 Human Development Report, wars were being waged in 30 and a further 33 were suffering severe civil conflicts. 55 of these 63 countries were to be found at the lower end of the Human Development Index which is an indicator of poverty. It is reasonably safe to assume that most people never welcome war. They may be coerced into supporting 'their' side in a conflict by their governments, using propaganda designed to whip up fear and extreme nationalist sentiment. If the majority had a democratic voice, they would undoubtedly object to war. But voices are silenced. Thus, the freedom to express one's views, to challenge government decisions and to insist upon political rather than violent solutions, are necessary aspects of democracy which can, and do, avert war.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">State-sponsored propaganda in Rwanda, as in the former Yugoslavia, succeeded because there were no ways of challenging it. One can conclude that it is impossible for a country to wage war in the absence of a compliant media willing to indulge in government propaganda. Governments needs civilians to fight wars for them and the media is needed to reinforce government policies and intentions at every turn. In a  totalitarian state where the expression of political views, let alone the possibility of political organisation is suppressed, one has to ask what other possibilities are open to a genuine political movement intent on introducing justice. All too often, terrorism and violence are the only perceived options available to communicate the need for change.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What NGOs can do</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The work of human rights organizations has to become much more proactive and should be concerned with providing early warning and preventive action. Monitoring freedom of exprmsion, especially freedom of the press, offers an excellent context because it is widely recognised that would-be dictators always seek to silence people's voices through banning newspapers or other methods of censorship. One has to assume that when censorship begins in earnest, worse human rights abuses will follow and this should be the point for action. Had there been a greater international lobby for an independent media, for access to information and for participation in decision-making in the former Yugoslavia, Rwanda, Nigeria, Burma and many other countries, some of the gross violations which continue to occur, could have been prevented.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Censorship is the first instrument of a government intent on departing from democratic procedures. In this sense it is an early warning signal and at ARTICLE 19, we believe we have a special responsibility to understand better how democracy is destroyed through censorship and how we can alert the international community to act to prevent it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By way of conclusion, anything which can build strong and sound media infrastructures, at the earliest to pportunity, in transitional democracies, is both a gift and a great investment. A crusading press, prepared to separate fact from opinion and to verify its sources, can create a level playing field in which all sectors of society have a voice. This would preclude political control and manipulation for nationalistic power purposes. There is also a need to strengthen local monitoring groups which have the capacity to verify information. International organisations should amplify the voices of local organisations and bring them to the attention of the international community. It is only where there is a strong human rights culture in a given country, whether it has achieved democracy or not, that political changes can be seized upon and shaped into the democratic process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To achieve these objectives, NGOS need to work with governments which are obliged by international law to uphold fundamental rights. We need organisations such as the KU, the UN, ASEAN, and others, to insist on respect for human rights in their dealings with third countries. We also need the general public to be aware of what fundamental rights are, what are the consequences of infringement, and how they can, as individuals, successfully challenge restrictionss imposed on them by their governments. Above all, NGOS need to work with multilateral organisations to determine where slender resources can most fruitfully be targeted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">F.d'S.</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Commission support for democratisation through the media</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Mark Leysen</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Amongst the many cooperation activities in which it is involved, the Lom&eacute; Convention covers cultural cooperation, which includes information and communication, yet European Development Fund support for the media in ACP countries is negligible. Although considerable and increasing amounts of aid are granted for the cinema in such countries, EU support for TV, radio and the printed media is small.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the other hand, for some years now, the Commission has provided considerable aid to the printed media and radio in ACP countries under its 'Support for democratisation and respect for human rights' budget, which heralds a new approach to media questions. The EDF does not participate in the vast majority of big communications projects in Africa, namely PANA (Panafrican News Agency), URTNA (African National Television and Radio Union, the African equivalent of the European Broadcasting Union), the Programme Exchange Centre, Afrovision, Cierro, etc. The reluctance of EU and ACP partners to embark on such media projects can be explained both by EDF procedures and by the worldwide political context including the situation in most African countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Until recently, the media was a matter for the State in Africa. The 'New World Information and Communications Order', announced in the 1 970s, foresaw the participation of not only African citizens, but also of their governments in the world information highway. However, the democratic credentials of such governments were open to question - they controlled the printed media, radio, television and press agencies and any support for such media amounted to a strengthening of the State monopoly and this is why the EDF did not take part.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moreover, aid to the independent media was impossible because such entities did not exist in most African countries and the authorities were not prepared to back a request for aid to the press which they regarded as contrary to their country's interests. If support for the media did exist, it was indirect and restricted to backing of means of communication servicing development projects: literacy campaigns, the fight against AIDS, increasing awareness of ecological problems, etc.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It was not until the advent of the democratisation movement and the support that Europe decided to grant to it that a media-aid strategy was to take root. As a kind of 'Fourth Estate', the media monitor executive power and report any abuse of it. In parallel, they play a key role in strengthening civil society by providing information (if not objective information, then at least information from many sources) on current political, social, economic and cultural issues and by providing a medium which offers an opportunity to speak out on matters of importance to society.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Commission focuses its media support in five areas in agreement with representatives of African press and specialist European . organisations in this area. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Freedom of expression It provides direct aid to national, regional and international organizations to defend freedom of expression, specifically financing monitoring, surveys and the reporting of any violation of press freedom (censorship, intimidation, arrests and arbitrary trials, etc.), and direct assistance to the media and any journalists who are victims of such attacks on press freedom. This direct aid is channelled to, inter alia, the activities of Reporters sans frontieres (see 'Interview with Mr Robert Menard', in this issue), 'Article XIX' and Index on Censorship, all organisations which operate like an Amnesty International for the press.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Training</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The new independent press is often run by journalists who have had no journalistic training and the former State media often require being updated after many years of professional 'distortion' responding to 'his master's voice'. The Commission hence finances programmes offering training in basic journalistic techniques, election coverage; professional codes of ethics, etc. In this area, it is working with a number of European and African organizations, giving priority to long-term actions which are likely to spawn others and to programmes aimed at achieving a higher level of professionalism.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Aid for vocational organizations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vocational organizations for journalists have a role to play in improving the profession's social standing, in strengthening its cohesion in the face of political division, in defending its interests and in coming to the aid of journalists who have been victims of repression. The Commission finances a vast 'Media for Democracy' programme conducted by the International Federation of Journalists and its affiliated regional and national organisations (see interview with Aidan White, in this issue). The programme aims to strengthen or create national and regional associations of journalists, but is also involved in more general actions to   increase the professional standing of the media.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Access to sources of information</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A credible and responsible press requires sources of information which the new and financially precarious press cannot allow itself. The Commission supports the creation or updating of documentation centres, North/South  and South/South exchanges between publications and radio stations, access to international press agencies or photographic libraries, etc., being shared between several media bodies. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Legislative framework and code of ethics</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is not enough merely to guarantee freedom of expression in the   constitution. This principle must be embodied in all legislative and regulatory texts to prevent a journalist being prosecuted arbitrarily for 'defamation' or 'a breach of State security'. Moreover, to appear credible, the profession must observe a code of ethics. The Commission backs the drafting of press codes, codes of ethics and regulations to govern the air waves. It also backs the creation of press and air wave regulatory bodies as well as the provision of training in journalistic ethics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is obvious that the 'Democracy and Human Rights' budget cannot alone meet the needs of Africa's multi-faceted media scene. Moreover, although the media are a key element in any democratisation process, they are also much more than that - as a means of information and recreation, they have a role to play in the human development of society; as an instrument to create greater awareness, they can contribute to the strengthening of a civil society which is gradually taking charge; and as an economic sector in the full throes of development, they can make a contribution to the GDP and create jobs. All the more reason for national sponsors and the EDF to take more of an interest. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">National television, victim of  democracy </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More than the other media, television in Africa is controlled by the State and serves, first and   fore most, to disse minat e news about the leade r and his govern ment. The state of equip ment depen ds on when it was suppl ied by a friend ly count ry from the North, and as it was almos t certai nly offere d to the count ry's leade rs 'as a perso nal gift', it usual ly consi sts of oversi zed equip ment which the nation al televis ion statio n canno t maint ain correc tly owing to a lack of resou rces. Whils t Europ e is movin g over to digita l Betac am and 1619 forma t, many Africa n TV statio ns are still opera ting with Umat ic and with mach ines that are impos sible to maint ain. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With such deriso ry mean s, nation al TV statio ns have to conte nd with unfair comp etition from the intern ationa l statio ns which, from their satell ites, are inund ating the contin ent with their broad casts . The worldbroad castin g chann els of Europ ean statio ns are receiv ed clearl y (CFI, TV5 Afriqu e, BBC World Telev ision, Deut sche Welle, etc.). The numb er of religio us statio ns (gene rally Islam ic) contin ues to increa se and comm ercial televi sion is develo ping apace - CN N, MTV, Cana l Horizo ns, M-Ne t and others can be picke d up just about every where and can thus cream off the best of a comm ercial mark et which is still virtual ly non-e xisten t and awaiti ng better days . </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The URTN A is unabl e to defen d the intere sts of its memb ers, prope rly and its initiat ives (which are, nevert heles s, lauda ble) are stagn ating: the -progr amme rexch ange centre in Nairob i does not excha nge very much at all and Afrovi sion, . the syste m for excha nging news betw een   nation al TV statio ns via satell ite, is strugg ling to Get off the aroun d. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Never theles s, Africa n TV statio ns do not lack talent or motiva tion and many of them are capab le of produ dng more qualit y progra mmes . What can be done to help them ? Firstly, a decis ion has to be made regar ding who is to be helpe d. Certa inly not intern ationa l TV statio ns' be they private or public, which have their own strate gy (comm ercial or politic al and produ ce televis ion progra mmes for impor t which make only a very margi nal contri bution to the expre ssion of Africa n talent . It would also be wrong to rely or, privati sation and comm ercial statio ns in order to obtain quali ty televis ion - t his much has been demo nstrat ed by the Europ ean exper ience . As for direct aid to nation al televis ion, this would mere ly reinfo rce the State mono poly over inform ation. Wha t is requir ed is greate r suppo rt for the transi tion of State televi sion into a genui ne public servic e. with the benef it of an indep enden t statut e and also true editor ial indep enden ce. Conse quent ly, as things curre ntly stand, aid for trainin g teievis ion' profes siona ls, suppo rt for qualit y progra mme produ ction and any aid aimed at draftin g a public -servic e televis ion Statu te, are usefu l forms of suppo rt which are neutra l with regard to State -medi a contro l. Any direct aid to nation al </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> televis ion statio ns in the form of   hardw are and equip ment shoul d be </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> subje ct to their conve rsion into an auton omou s public servic e. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M.L. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Images of Africa in the Western media</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> by Geoff Mungham</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It seems difficult to find an African leader or African journalist who has not, at some time, been either fiercely critical or quietly despairing of the way in which the continent is depicted by the western media. Their grievances have come to form part of a now familiar litany. Claims are made that the reporting of Africa is now almost entirely in terms of what has been called a'coup, crisis and famine syndrome', and that the western media focus only on 'bad news' out of Africa and ignore the 'positive' achievements of many African countries. These criticisms go hand-in-hand with accusations that Africa cannot ' tell its own story, in its own way', because the global news market is dominated by powerful, westerr-owned corporations, who have their own agenda for reporting Africa. For many Africans, their continent is becoming increasingly invisible in the trade in global news. For them, Rupert Murdoch's cynical remark that 'the Third World sells no newspapers' would appear to have been uttered with Africa specifically in mind. Finally there are those Africans who are concerned about 'western cultural imperialism' undermining traditional African values and culture.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">How true are these claims? Is Africa becoming once again a dark continent; one largely excluded from the glare of western media coverage? Are some of the correctives suggested by different African leaders worse than the problems they are complaining about? And if Africa is in danger of becoming a 'disappearing world' for news, to what extent are many African countries themselves to blame?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To begin with, there is no doubt that African critics have a case. First and most obvious, is the undeniable brute fact that global news and information flows are dominated by a small number of multinational operators, nearly all of whom - especially since the end of the Cold War - are western owned and controlled. This is true of the great international news agencies, whether the traditional wire services like Reuters or Agence France-Press, or the newer global television news services represented by WTN and CNN, among others. The major clients for their output are western news organizations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the same time, most African countries are in no position to mount a challenge to this world news order. The continent has recently been described as one of the 'least dynamic regions in the global economy, where buying power of consumers is low' and in which many countries are burdened with crippling debt payments. In the same vein, a 1991 World Bank report not only pointed to the increasing 'communications gap' between Africa and the developed world, but went on to suggest that most of the continent offered poor prospects for those wanting to invest in telecommunications projects. These are among the reasons why Africa scores so poorly in terms of putting in place viable national communications infrastructures, let alone being able to take on the global market leaders in securing a higher profile for Africa in the world's news rooms. The same factors also help explain why most African countries remain so dependent on western-controlled news sources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This dependency is not simply a question of the easy availability of copy or other material from the western news agencies. Puri (a Tanzanian journalist and Managing Editor of Newslink Africa)  presents other reasons why African editors are interested in what's happening in the West. These include the links between many African countries and their former colonial rulers, the realities of global and economic relations and his claim that African editors often have little interest in other parts of the continent. As he puts it, '...a newspaper reader in Botswana, for example, is not much interested in reading detailed reports from Morocco.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the same time, there is plenty of evidence to support the criticisms of the 'coup, crisis, famine' coverage. Examples are too numerous to cite here, but the following small selection is fairly representative of the broader picture.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Introducing the findings of a 'Global News Agenda Survey', Malik and Anderson noted: 'For the rest of the world, Africa means coupe, and largescale killings (covered usually only in the first few days), almost ritualistic famine relief... and the occasional travelogues in the guise of saving something or other'. Similar claims were made by Okigho when he wrote that while CNN and other satellite organisations have 'revolutionised international news coverage', the most common images of Africa still depict internecine warfare (in Angola, Liberia, Somalia), pogroms in Rwanda, political violence in Sierra Leone and ethnic conflicts in Kenya and elsewhere in Africa. In contrast, says Okigho, the 'many positive developments' are routinely ignored.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A limited review that I made of wire service copy from the main international news agencies during the week of 13-20 May 1996, produced findings that seemed to echo some of these complaints. In this period, hard news stories were concentrated on a handful of the 50 plus countries of Africa; Burundi, the Central African Republic (C.A.R.), Egypt, Liberia, Somalia, Sudan and South Africa - together with stories of alleged financial irregularities in the World Health Organisation in Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Copy about Burundi dealt with ethnic violence and attacks inside Zaire   on Burundi by Hutu 'rebels'. Reports from the C.A.R. focused on an army mutiny, street battles and looting, but were angled on the mediating role of French troops (the C.A.R is a former French colony) and the fate of 100 Americans trapped in the capital, Bangui. Egypt was featured after its government accused Sudan of harbouring a 'vipers' nest of terrorists'. Out of Liberia came a torrent of wire copy about fighting in Monrovia along with assorted atrocity stories, but pinning the emphasis on the plight of foreign nationals (especially Britons and Americans) and the role being played by the USS Guam in air-lifting them to safety. Somalia rated a mention because of the release of two foreign aid workers (British and German) held by an unidentified 'rebel faction'. On South Africa, the wire services were fixed on further violence and killings in KwaZuluNatal, the result of ongoing struggles between rival supporters of the A.N.C and the Inkatha Freedom Party.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 'agenda for Africa' sent out by the wire agencies, was replicated by  the menu offered by Reuters TV and APTV. For instance, on one day during the study period, the former was offering ten picture feeds; only one was from Africa (on the C.A.R.) while the rest included such compelling visuals as the British Queen's visit to the Chelsea Flower Show. For the fifteen picture feeds being touted by the APTV on a single day, one featured Africa ('news pictures to offer on the airlift by US marines'), which competed for the attention of western news rooms alongside visuals of a US woman who collected hubcaps (140 000 of them, no less!), Hugh Grant arriving by boat at the Cannes Film Festival, footage of the Monaco Grand Prix and a 'fun run' in Sarajevo (whether or not pictures are available, the idea of a 'fun-run' in Bosnia still seems a difficult concept to grasp) But what these studies show is not the whole picture about Africa which circulates in the West. Nor should they necessarily be used to support the usual criticisms about the performance of the western media in relation to the continent. In the first place, not all news  out of Africa fits into the syndrome the critics complain about. For example, a great deal of the coverage of South Africa has been 'positive' (if we trace the reporting of that country's transition to majority rule). So, too, have the moves towards multi-party politics in African states like Zimbabwe. Similarly, there is plenty of reporting of Africa's sporting successes (such as South Africa's Rugby World Cup triumph). Nor is the West unaware of the work of certain African musicians and film makers - indeed, it has been influenced by them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">And even if 'positive' coverage is sometimes hard to find, the critics may still be missing some key points. The first is to do with western 'news values' or rather a failure to appreciate how they work - whether in relation to Africa or anywhere else. The staple diet of much of the global news flow is about 'bad news' and, in this respect, Africa prob  ably fares no worse or better than other parts of the developing world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Second, a more 'systematic' reporting of much of Africa is still difficult. My point here is about a lack of efficient and developed communication infrastructures, but also a reluctance by many African leaders to tolerate - let alone actively encourage - free and honest open reporting. Too many African journalists have been, and are being, harassed, imprisoned or killed by their own governments. Much of the media in Africa - especially the broadcast media - remains under state control. Newspapers that show a 'lack respect' for the ruling party are frequently shut down. These realities help explain why some of the maligned western media are turned to by those Africans who want something more than state propaganda from their newspapers or broadcasters. This is why the BBC World Service has come to enjoy such a high reputation in many parts of Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Third, the attempts made by the African states to try and take on western dominance of global news and information flows, have been misjudged. Two failed initiatives in particular are worth mentioning in this context; the launch in 1983 of the Pan African News Agency (PANA) and the long-time obsession with setting up a 'New World Information Order' (NWIO).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From the start, PANA has been dogged by financial and management problems. African governments owe $18 million, journalists have gone unpaid, lines have been disconnected and in 1992 a UNESCO-funded audit found evidence of financial mismanagement. The main source of information PANA traded in was material from the domestic news agencies of OAU member states. Since most of these are state-controlled, the 'news' they were offering was never likely to attract many western users. To try and give PANA a new lease of life, UNESCO are backing a rescue package, which would allow for private investors to be shareholders along with state-owned African national news agencies. But the pro  posed partnership funding is unlikely to work, especially in one-party states where the ruling groups have always been suspicious of any media not under their direct ownership.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The NWIO project has chased even more impossible dreams. Any attempt fundamentally to change the global news order was always going to be beyond countries with severe national communication 'deficits'. Most African countries, with weak and undercapitalised information infrastructures were never in a position to take on the market leaders in the global news business. In pursuit of the NWIO idea, endless international conferences were held, declarations passed and ritual attacks made on ' western media dominance'. Nothing came of it all. If the sense of frustration which kept the concept alive was understandable, less easy to grasp was why African leaders focused on the NWIO idea, while their own grassroots communication systems remained impoverished and under-resourced.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The most recent attempt to develop 'top-down' communications facilities in parts of Africa comes with the attempts to push satellite-delivered payTV on the continent. Among the 'players' here are Multi-Choice (which will be offered to subscribers in over 30 countries in sub-Saharan Africa), Canal Horizons (targeted on North Africa and Francophone West Africa) and Panafnet (also aimed at buyers in Francophone West Africa). Because these enterprises are subscription-based there will be a clear bias in take-up towards upperincome groups; and - certainly in the case of Multi-Choice - the output will have a 'strong UK/USA programming flavour'. It is hard to see how these initiatives will ever meet the real news and information needs of the vast majority of African consumers, who have limited spending power and are often deprived of the most basic communication tools.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As Hans Dieter Klee (former Head of the Africa Service of Deutsche Welle) has rightly argued, what Africa urgently needs is large-scale international media aid to help strengthen its own media. This aid should not be targeted at projects designed somehow to allow Africa to 'compete' with Western media congLom&eacute;rates. It should, instead, be aimed at building up diverse, viable and professional local and national media enterprises in African countries themselves. In this, the EU can play a leading role, working through the links established under the Lom&eacute; Convention.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robust national communication structures in Africa will not, of course, alter the balance of global media power. They will be able to do little to stop the international news agencies reporting Africa in the way they have done in the past. And it will be a long time before most Africans becomes travellers on the 'information superhighway', since this, in essence, is an extension of existing computer and telephonic communications, which the continent lacks. But a vigorous local and national media, Africa-wide, would be good for Africa and the best barrier for resisting outside media influences. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">6.M.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">References</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Okigho: 'National Images in the Age of the Information Super Highway </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">African Perspectives', African Media Review, vol. 9,1995.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">R. Malik and K. Anderson: 'TV: The Global New Agenda Survey', intermedia, January-February 1992. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">B. Hicks 'North of the Limpopo', Cable and Satellite Europe, April 1996. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">A message of hope on the Burundi airwaves</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Parliament may seem an unlikely launch pad for a radio station, but two members of this elected body, who are committed to a free and fair press as one of the cornerstones of democracy, have set up Radio Espoir (Radio Hope) in Burundi with backing of the European Community Humanitarian Office (ECHO).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Parliamentarians, Pierre Pradier (ERA-F) and Bernard Kouchner (PSE-F) are co-founders of Radio Espoir (Radio Umwizero, in Kirundi) which brings together a French association and a local Burundi radio station. Three expatriates are working on the Bujumbura-based project; an editor, a radio technician and an administrator. They have teamed up with local journalists who, for the moment, are providing their services free of charge.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The station, which broadcasts in Kirundi, is targeted at an audience in the 15-25 age group. In a country with an 80% illiteracy rate, radio is the only way of reaching the population. 'The idea came to us in 1994, with Rwanda and Radio Libre des Mille Collines' says Pierre Pradier. 'If so much harm could be done with radio, then why equally could good not be achieved.' RLMC was the radio set up in July 1993 on the eve of the genocide in Rwanda. It became a mouthpiece  for the Akazu, a clan of Hutu extremists grouped around the then President's wife, Agathe Habyarimana, and it undermined the Arusha agreements by whipping up ethnic conflict in Rwanda.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mr Pradier explains that Radio Hope journalists intentionally avoid speaking about Hutus and Tutsis. He also highlights the problems encountered in providing news coverage when local conditions are so difficult. As he points out; 'When you speak about the situation of a woman who has lost her husband in Burundi, you are talking politics.' Security considerations are important too while the MEP stresses that a proper analysis of events can only come with time: 'At the moment we are limited to reporting the facts. And it is only when the facts are verified that one can begin to interpret them.' The news items broadcast by the station rely on agency dispatches confirmed by a network of local people who call in.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of such sensitivities and in an effort to find as much common ground as possible, the radio station gives music top billing. This has the added advantage of helping to attract listeners. It also offers general programmes on African roots, sport, culture and educational themes, in addition to its news items. It is currently broadcasting for six hours a day.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pierre Pradier says he would like to see an end to the 'navel gazing' of Burundi's population. 'We want to show that peace is possible, by showing how it is progressing elsewhere: in Haiti, for example, where there is a legitimate President now, and amongst the Chiapas in Mexico.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But, like many fledgling stations, finding enough funds from donors to guarantee its future is a worry. The station's current ECHO grant runs out in September 1996. Indeed, the project, classified under emergency aid, was atypical for the humanitarian aid office. But Mr Pradier is hoping that continued support will come from one of the EU's budget lines. He believes that the Union is a particularly suitable donor because it tends to be less 'colonialistic' than some others. He also raises the possibility of seeking funds from private donors such as the Fondation de France. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Looking to the future of the station, Pierre Pradier argues that they cannot let the project 'drop' and hopes eventually to see it being handed over to local broadcasters, assuming 'they are people we can depend on'. The signs so far are encouraging. He would also like to see Radio Hope's programme content broadened to include game shows, with radios offered as prizes for the winners. As far as he is concerned, the more people who tune in, the better! _</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D.P.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Joint Assembly resolution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The ACP/Ku Joint Assembly is pushing for EC institutions and Lom&eacute; signatories to be more supportive of media issues. A resolution on the role of communications media in the development and consolidation of democracy in ACP states. passed by the Assembly in March, contained the following points:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - freedom of expression and free communications and media are vital to the development of a democratic society;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - more ACP countries should give opposition parties access to the media' notably where this is controlled by the state;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - all candidates and political parties should be given access to the media in a 'balanced and fair manner'; </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - laws which restrict press freedom and the electoral process should be repealed;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - any threat of physical attack against media organisations or their employees should be investigated by the authorities, with those responsible being brought to justice;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - the media should be impartial, providing accurate information during elections, helping to educate the electorate, explaining the importance of elections, giving information on where, when and how to vote, and explaining the secret ballot;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - EU assistance for free and a fair elections - and a free media sector in ACP countries - should be increased. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Catholic radio in Southern Africa</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Antonio Pacheco</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this abridged article, the author, who is a Portuguese journalist, gives details of two church-supported local radio projects in Southern Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the end of the 1980s, the Social Communication Department of IMBISA, the conference of Catholic bishops in Southern Africa (a kind of SADC for Roman Catholics) embarked on a local radio project. It had a two-pronged approach. First, it involved setting up a network of small community radio stations. The local population were involved, sharing responsibility for making programmes and broadcasting information and news about everyday life in the remotest places. In some cases, the programme content was retransmitted at a provincial or even national level. The second aspect was that it was supplemented by the creation of flexible and independent associations of journalists/presenters. They formed information agencies operating as a network to link up local radio stations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At that time, the main concern in Southern Africa was to rid South Africa of apartheid. There was also a desire to promote freedom of expression in Angola and Mozambique. Given that radio was (and still is) the most important means of communication in the region, the idea was to set up a regional network capable of overcoming all the constraints ranging from legal bans and restrictions on broadcasting to widespread illiteracy. The ultimate objective was to set up a Catholic radio station based in Swaziland. This project did not go ahead, however, because it was too expensive to finance and, above all, because it was dependent on the regional Catholic hierarchy. It proved difficult to reconcile the various ideological views and sensitivities of bishops in the various countries of the region. There was also a growing feeling amongst the Christian communities that the underlying need was not for a radio station which would be a vehicle for bishops' views, but rather a media system that served the people, offering recreation, training and information.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Radio Pax</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another local radio project of interest, which is now up and running, involved reviving Radio Pax, the private Catholic radio station which made a significant contribution during the 1 960s to the struggle for a free Mozambique. The operation closed down in 1977 but the experience was not forgotten and 16 years later, the decision was made to bring the station back on air. Those behind the new project took advantage of the trend towards greater political openness in the country. Their aim was to offer a credible and informative alternative, which, they hoped, would be up and running in time for the elections scheduled for October 1994. A course was run between July and September 1994 which brought together young presenters chosen by small communities on the outskirts of Beira, Chimoio, Nampula, Quelimane and Maputo. The course involved honing the participants' presentation skills and providing practical training in technical subjects, and programme and information preparation. This was how the first association of young independent Christian journalists came into being.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For various reasons, including red-tape and customs regulations, the  new Radio Pax was unable to broadcast in the run-up to the general election. However, the young journalists, who received their training at various locations, were able to act as important independent sources of information. This was channelled to Maputo and used as backup for a number of international press officials and observers. The information relayed by the young presenters in the provinces made it possible to publish a newsletter which was circulated throughout the country, using fax, religious channels and a variety of other means.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Radio Pax is now in operation, although it faces major technical problems. It is based in a community centre in Inhamizua, 20 km from Beira. The station has already done important work in gathering information about local traditions, and has broadcast programmes aimed particularly at women and young people in suburban areas. The network also incorporates Mozambique's Radio Encontro, which broadcasts from Nampula in conjunction with the Anchilo training centre. There are plans for further local radio stations in Maputo in the south, Quelimane and Chimolo in the centre and Pemba in the north.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Radio Pax is managed entirely by the Association of Independent Young Christian Journalists in Beira. In terms of training, the current preoccupation is to teach the young people involved how to manage the small radio stations which have been made available to them, and to set up local self financing systems. Although equipment is important, what really counts in this project is the training of the presenters. Working in close collaboration with the community, it is they who are in the front linepromoting the inalienable right of free expression.</P>
+<P ALIGN="JUSTIFY">A.P.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The Voice of the Disabled in Chad!</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> by Mand Rya&iuml;ra Ngarara</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Support Group for the Disabled in Chad (AEHPT) was set up in 1987 with the assistance of the International Christian Service for Peace (EIRENE), which has its headquarters in Germany. By coming together to form a group, disabled people hoped to take charge of their lives and break down the wall of silence that surrounds them. However, despite setting up various workshops (welding workshops, small printing works, musical groups) and publishing an information newsletter, entitled 'Perspectives'. the AEHPT has been unable to improve the image of disabled people within Chad society and has failed to  raise awareness that the work done by the disabled is not only of value, but deserves due recognition. From this status quo sprang the idea of broadcasting a national weekly radio programme called 'The Voice of the Disabled'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are two reasons why radio was chosen as the communication medium: firstly, the very strong oral tradition of the country, together with the population's weak purchasing power, which make access to newspapers difficult, means that radio remains the most appropriate medium for reaching a wide audience; and secondly, radio programmes are not difficult to produce, since they do not require vast technical, financial or human resources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Letting the disabled have their say</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Initially launched by the AEHPT, The Voice of the Disabled is now jointly produced and broadcast by four associations actively involved in defending the interests of those with disabilities. It is broadcast nationwide every Monday at peak listening times.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The programme is not, however, aimed solely at those with disabilities but, on the contrary, seeks to increase awareness in Chad society as a whole. It also acts as a platform from which to urge the authorities to take concrete measures to help this section of the population.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Today, more than a year after its launch, The Voice of the Disabled is enjoying tremendous success, with ever larger numbers of people, from all walks of life, tuning in. For the disabled themselves it provides a vast source of information, explaining the facts behind the causes of their disabilities and giving advice on how to prevent such disabilities and what can be done to treat them, and it keeps people informed about  what is happening within the various associations for the disabled, giving information about the activities, projects and special events that are taking place. As far as the rest of the population is concerned, The Voice of the Disabled has helped to raise the profile of disabled people in Chad. Slowly but surely, people's preconceptions are beginning to change and one of the programme's greatest achievements has been to eradicate gradually the negative image which people used to have of disabilities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nevertheless, the lamentable fact remains that this programme is broadcast solely in French, and this is why plans are now in the pipeline to broadcast The Voice of the Disabled in both Arabic and Sara - Chad's two national languages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M.R.N. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">TV documentaries and development</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Africa Express experiment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By Richard Synge</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 'Africa Express' documentory series mounted by Channel4, an independent British TV station, has done more than just put a new slant on news provided by state-run African channels. it has also created jobs for African producers and reporters.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Television viewers in Africa will soon get the chance to see documentaries on African current affairs and development topics which have hitherto only been seen on British TV sets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Channel Four's Africa Express programme has recently concluded its third series to much critical acclaim in Britain. it included items on a surprisingly diverse range of topics. One film showed how a cash-strapped Congolese prison saves money by sending its prisoners home one day in every month, and included lively interviews with the governor and the prisoners themselves as well as footage of the grim prison conditions. Others focused on the flourishing free currency market in Zaire, the spread of South Africa's 'shebeen' culture into the country's upmarket suburbs, political battles in Namibia over the rights to manage historic tourist sites and the Nigerian military government's blatant attempts to censor television reporting.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The latest series supplemented the work of British film crews by incorporating several documentaries that were made entirely by African production teams. Special funding for this element of the Africa Express project came from the environmental television distribution agency TVE. As a result, Africa Express hired four African directors and used African-based crews to film half of the 24 films in the series.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The other innovative part of the project was that the programmes are now becoming available to viewers in Africa at the lowest possible cost. To promote this concept of 'media feedback', TVE has been actively marketing the series to non-governmental organisations and facilitating arrangements for the distribution of the cassettes to African broadcasting stations, both state-owned and private.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'It is a way forward for us, because nothing like this has been done before,' says Raphael Tuju, a Kenyan film producer who runs a video resource centre in Nairobi, marketing documentaries to local broadcasting stations and the educational sector. 'There are too few opportunities for producers in African countries to break into the international networks. The subjects we cover are rarely of interest to the distribution companies, the differences in technology are too wide and getting wider, and there are not enough African producers who have reached the professional level to compete with their counterparts abroad.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Peter Gill, who edited Africa Express for Channel Four, welcomed the opportunity to help promote the independent film industry in Africa. 'It was thoroughly stimulating,' he says, adding that one of the constant challenges was 'finding ways to bridge the gap between what is technically possible in Africa and the standards required for a European television production.' The four African directors hired for the series were two South Africans, Eddie Mbalo and Teddy Mattera, a Zimbabwean, </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Albert Chimedza, and a Namibian, Bridget Pickering. They all worked directly under Peter Gill's management and in contact with a producer in the field. Gill was impressed with the level of journalistic and technical expertise available in Africa and the dedication of the teams working in difficult situations. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Even where the production teams were British, all the 24 films in the latest Africa Express series used African journalists and presenters. They researched and organised most of the films in advance of the actual shoot by the visiting film crews. Cameroonian journalist, Emmanual Wotany, played a prominent role in the films on Congo and Zaire. Kenyan reporter Joseph Warungu proposed and presented a film on the hazards of skin-bleaching in The Gambia. The presenter of the programme on Nigeria, Toyin Fane-Kayode, bravely challenged the censorship of the country's military regime.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An all-African camera and sound team led by Lawrence Mbada and Mandla Mlambo was responsible for the four films in the series that were shot by the South African Broadcasting Corporation (SABC). In the extremely difficult conditions of Angola and Namibia, an experienced SABC cameraman was used. Here there was a need to ensure that the less experienced directors were not further challenged by having to work with an inexperienced crew.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For TVE's Robert Lamb, one of the main breakthroughs made by Africa Express was in the agreement of Channel Four to collaborate both with the SABC and with TVE itself, which insisted on the involvement and participation of African journalists, film-makers and technicians. He was impressed by the results and hopes that thee could be 'an even greater African involvement in another series, if one is commissioned.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The latest series was a success, being regularly watched by up to two million viewers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Channel Four granted broadcasting rights for the series in lowincome countries to TVE and Worldview International Foundation as well as the non-broadcast rights to TVE and its partners in the third world. These   agreements allow TVE to provide the tapes at nominal cost to a network of video resource centres, similar to that run by Raphael Tuju in Nairobi. Such centres seek to get development-oriented documentary films shown by the local broadcasting stations but survive by supplying the needs of schools, colleges, non-governmental organisations and other categories of 'multipliers'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the most successful documentary centres is the Film Resource Unit (FRU) in Johannesburg. From its origins as a way of sharing bootlegged foreign films and TV programmes during the political repression of the 1980s, FRU is now a major distributor of educational and documentary films.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To overcome the inexperience of state-owned African broadcasting networks in showing programmes of developmental relevance to their societies, video resource centres have to provide their own sponsorship. 'It is difficult for us to compete with the likes of Coca Cola, which will sponsor programmes like soap operas,' says Raphael Tuju, 'but one way round this obstacle is to sponsor a programme and at the same time advertise our services. The business we generate this way usually means that we can at least break even.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Film-making capacity in Africa has been severely limited by most governments' domination of the broadcasting media and a deep and institutional reluctance to encourage independent local productions. The mainly government-owned television stations rarely have a policy to buy in locallymade programmes and tend to look to Britain, France or the US for outside material, which is often dumped on the market at low prices, making it an even harder challenge for local producers to generate the funds to make their own programmes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The decline of the once-active film industry in Nigeria, in particular, means that in English-speaking Africa, the field is now dominated by South Africa and Zimbabwe. In French-speaking Africa, the continuation of subsidies  has kept an 'art house' tradition alive, especially in Senegal and Burkina Faso. In most of the continent, however, the only development-oriented programmes shown to the public tend to be made by the governments' own propaganda departments rather than by independent film-makers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Where there is a lack of access  to local broadcasting media, African film-makers continue to experiment with making their own dramas and documentaries, showing their work on video in village halls and schools. 'At the grassroots, African film-making can be stimulated simply by consumer demand,' says Russel Honeyman, who publishes the African Film and TV Yearbook in Harare. 'But local products do not usually translate into international products. Film and television is a global industry and film-makers should not insist on being too parochial. There is room for greater international collaboration.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Based on the experience of the latest Africa Express series, TVE now plans to build on its achievements. In May 1996, it exhibited the series to the directors of African television stations at a conference in Windhoek, Namibia, and discussed arrangements for distribution of the cassettes. It is also planning to  participate in a workshop for French speaking West African nations in Senegal under a grant from the European Union's human rights division. The consultative process will continue with a meeting of the African video resource centre network at the end of 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">TVE's Robert Lamb hopes that the success of Africa Express might encourage international funding agencies in Europe to take up the challenge of funding films made in Africa for African consumption. He doubts that Channel Four on its own would take such a risk. Constraints are, perhaps inevitably, imposed on TVE's concept by the fact that programmes produced for European audiences use a production and editorial structure that requires 'post production' in European capitals. 'Although we came out owning the rights to the programmes in Africa, Channel Four still had 80% of the control over the production and editorial decisions,' he acknowledges.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Robert Lamb is fully aware of the challenges that lie ahead. 'National broadcasters are in a parlous financial position and are still, for the most part, stifled by government controls,' he notes. 'Africans who have received formal training rarely find the funds to apply their newly-acquired skills.' But Mr Lamb and his TVE organisation are convinced that there will be increasing demand for more programmes like Africa Express, as much from Africa itself as from European audiences. </P>
+<P ALIGN="JUSTIFY">R.S. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The Internet and the South</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> by Renaud de la Brosse</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The author, who works at the Panos Institute in Paris, reflects on the pros and cons of new information technology for countries in the South and on their chances of success.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Internet has become such a craze amongst users in Third-World countries (researchers, teachers, businesses,, liberal professions, etc.) that it amply demonstrates that a real and genuine need is being met, despite adverse comments from its detractors. The rapid increase in the number of connections to the network in the North is mirrored by an exponential growth in the South. Africa is a good example of the possibilities offered by access to the global network whilst at the same time revealing the technical and financial restrictions facing countries in the South.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Almost all of Africa's 55 countries are today connected to the network, from South Africa, which has over 800.000 computers, to Uganda, which has just a few thousand. The importance of the Internet in Africa must be viewed less in terms of the number of computers (means of access to the Internet) and more in terms of the constant increase it represents in numbers of subscribers to the network. In the last six months alone, the number of subscribers increased by over 50%, whilst the increase in France, for example, was only 20%. Another telling figure is the number of host computers per 1.000 inhabitants, which rose by 147% in South Africa between 1994 and 1995 whereas the increase for Taiwan and Australia was 83% and 50%, respectively!</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because it is under-supplied in communications equipment, Africa is starting out with a disadvantage compared with other continents. However, the recent G7 Conference on Information and Development, which took place in mid-May in Midrand in South Africa, brought together 40 countries and 18 intergovernmental organizations and made it possible 'to build a bridge between developed countries and developing countries' so that the latter are not excluded from the world of new information technologies. The benefit to be gained from the Net for the Black Continent lies in the fact that African surfers are anxious to break free  from their scientific, cultural or economic isolation which comes not only from relationships between Africa and the rest of the world, but often from relationships between regions and countries on the African continent itself.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Precursors</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As in Europe and the United States, scientists and researchers in Africa are the first to have understood the importance of the Net and there are now - in French speaking Africa - networks such as the Intertropical Computer Network, which groups together approximately 3000 surfers in 11 countries. The importance of the Internet for these researchers is manifold; in most countries, the education system is in grave crisis, essentially because of diminishing budget resources which for years, on account of structural adjustment measures, have been melting away. This explains the absence of libraries or documentation centres. The Internet is therefore becoming a stopgap measure, offering access to all current scientific production and giving African researchers the chance to publicise and gain recognition for their work outside their own continent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Interesting experiments in North/South cooperation are also being set up, with the French-speaking Agency for Higher Education and Research currently establishing what it calls a 'virtual French-speaking campus', a kind of vast library to which affiliated universities will be connected. The project is also justified in economic terms since, through the medium of electronic mail (e-mail), which goes hand in hand with the Internet, exchanges of information will be cheaper than by fax, for example, which costs at least five times as much for the same amount of information transmitted. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Outside the academic community, heads of African businesses are also launching themselves into cyberspace, particularly in the case of several hundred of them who have grouped together within a West-African Business Network. Internet's financial viability in the South is dependent on membership of African businesses and multinational companies established in Africa. The cost of subscription is still beyond the means of private individuals and only 'institutional' subscribers are currently able to guarantee payment in the short term.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A useful tool</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many of the possibilities on offer remain to be explored, so the Internet can therefore be an important medium for promoting African culture - Niger has set up a Web via which it is possible to visit its archaeological sites and Benin has just set up a server dedicated to voodoo. In general terms, there is the challenge of mastering content, in other words the African suffers should not restrict themselves to a  passive use (sleeking information from the North) but should, on the contrary, move progressively as players providing content and information. For the countries of the South, it is a matter of mastering information and preserving their culture.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The range of possibilities offered by the Net is limitless. Its development in Africa or in the South in general does, however, run up against a number of obstacles, including those of both a technical and financial nature. The importance of the Internet lies in being able to transmit greater quantities of information more cheaply than by using other communications techniques. However, the required technology is expensive and therein lies the principal difference between the North and the South.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The infrastructure which would permit rapid, longterm expansion of the Internet is nowhere near being installed in Africa, just as in the other developing countries. The continent is still under-equipped in terms of telephone lines; according to a survey by the BDT (Telecommunications Development Office), the number of main telephone lines per 100 inhabitants is less than 0.5 in sub-Saharan Africa, and in terms of equipment providing access to the Net (computer, modem, etc.). In real terms, this makes access to the network much more expensive for a user in the South than for one in the North. All these imported electronic goods are much more expensive than in the West, and this is without taking account of the additional cost, in most African countries, imposed by tariff barriers on IT goods, which are regarded with great suspicion by the authorities who perceive them as a potential danger more than as essential development tools.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The fear is that the remote transmission of data might pose a threat to less than democratic regimes. Under the pretext of 'the control of information-based wealth', a State may decide to interfere with the 'consent' or even 'suppress' a site for producing and exchanging information deemed contrary to its interests. Once more, the question of freedom of expression arises in different terms in the South and North. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Panos Institute</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Panos Institute is a non-profit-making association set up in 1988. Together with its counterparts in London and Washington, the Paris Panos Institute founded Panos International The Institute's aim is to strengthen, particularly in Africa, local expression and information capabilities. Within the context of sustainable and  better-shared development, it aims to promote the emergence of a more democratic culture and of more democratic debate. To this end, the Panos Institute runs two main programmes in west Africa from Paris and its branch offices (Senegal, Mali, Chad and Ghana).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The programme to support pluralism in matters of information, which has four major objectives: - to expand and consolidate the legal, institutional and statutory framework of pluralist-type information - to increase professionalism in the media - to give institutional support to authors in west Africa who promote pluralism in information - to contribute to the production and circulation of more diversified and more qualified information on certain priority topics such as the environment, human rights, management and prevention of conflict, etc.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The migration and cooperation programme seeks to enhance the value of the contribution made by citizens from Third World countries residing in the rich nations to development in their countries of origin. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union, UNESCO and the ACCT, American foundations (Ford, Rockefeller) or German foundations, and bilateral cooperation agreements (Denmark, Netherlands, Norway, Germany, France) support the actions of the Panos Institute. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The press in Africa as a tool in the democratic  process</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Florence Win&eacute;ry</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although radio is 'king of the media' in Africa, the press is increasingly becoming an active player in the democratic process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This has been seen particularly over the last six years in the French-speaking African states where a burgeoning of political parties has been matched by the appearance of an unusually large number of  newspapers. In these countries, the press still requires rudimentary political stability - in contrast to English-speaking countries, where it has a much longer tradition and can nowadays be generally regarded as the 'Fourth Estate'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nigeria is a good illustration of this. One need only cite the press campaigns mounted there to protest against the Federation's membership of the Islamic Conference Organisation in 1986, and more recently, the support given to Moshood Abiola. The vitality of the Nigerian press is something that deserves to be emphasised. Despite a series of measures over the years aimed at suppressing it (not exclusively by the military authorities) it is still much in evidence. There are demonstrations to support it, and it has 'gone underground' at times, continuing to publish clandestinely. The journalists' struggle intensified in June 1993, when it was recommended that they should exercise 'discretion and self-regulation'. In spite of the problems, the Nigerian press endeavours to remain a source of pressure in Nigeria's political and social arena.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Returning to the French-speaking media, we see that the pace of expansion varies considerably from one country to another. In Benin, for example, current discussions are centred  strongly on opening up the country's airwaves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Is a private press a partisan press?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is debatable whether the private press is truly independent. In the political sphere, it is often highly partisan while 'economic' independence - in the sense of access to the materials needed to produce a newspaper - is not always possible. Printing and distribution are often subject to monopolies which may constitute a form of disguised censorship for the publishers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Initiatives aimed at setting up press associations in one form or another have been launched in an attempt to overcome these problems. This helps explain why the SEP (publishers' Society) was established. This group, which hopes to extend its activities throughout the region, is based in Benin where the democratisation process (and the proliferation of press titles) first begun. In many countries, media associations have already been formed covering specific areas such as radio, the press and publishing. There are plans for similar organisations in the field of television. Sometimes, they have printing facilities which are available to other private publications.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The principal challenge facing a general information-based newspaper is that it should appear regularly and on time. The next stage, ideally, is for it to be able to increase its distribution. Initially, a number of newspapers only came out monthly or even every two months. After appearing regularly for several months - and thereby achieving  relative financial stability - they then moved to weekly publication.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In most countries, a new legal framework was also adopted, although the application of the legislation has often proved laborious. This is particularly true of the setting up of regulatory authorities. In Senegal, where the media was previously governed by a law passed in 1979 (and amended in 1986), new legislation was enacted at the beginning of 1996. The measure was prompted by concerns over ethical standards, a demand for a more 'responsible' approach, a desire to prevent monopolies developing, and fears of excessive foreign involvement. This year has also seen the implementation of media law amendments in Cote d'lvoire.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The focus of the work of many newly-formed organisations has been the drawing up of a professional code of ethics, with a view to defining the basis of the journalist's profession. In Cote d'lvoire, the OLPED (Press Freedom and Professional Ethics Monitor) was created in September 1995 in Yamoussoukro at a seminar on journalists' responsibilities during elections. The OLPED is made up of 13 members representing publishers, civil society and the nation's journalists. Although the 'Monitor' has only moral authority, it has had considerable influence on journalists' professional consciences.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The OLPED held weekly working sessions up to March 1996 and now meets every two months. One of its main achievements has been to define the criteria whereby a responsible attitude can be guaranteed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vigilance</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The press can expect to be subject to rigorous supervision during an election campaign - as happened recently in Benin. Indeed, Benin's press has attracted special attention from various national institutions including, most notably, the NGO community. This interest resulted In the organisation of seminars on journalism during an election period, designed to avoid incitements to violence. The HAAC (Audi  ovisual and Communications High Authority), responsible for statutory control of the media in the run-up to and during the campaign, took part in these meetings which were aimed at increasing awareness and highlighting the heavy responsibility carried by the media.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite a number of incidents during the campaign (which were immediately reported) and although the situation threatened to get out of hand while the country was obliged to wait for the publication of the results of the second round, the press conducted itself in a fairly moderate manner. It should be recalled that there was a great deal of apprehension in Benin before the results were announced with a widespread fear that violence might break out. These fears were given extensive coverage by the media.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The HAAC proved to be central to the electoral process and, ultimately, the press was congratulated by most political leaders in Benin, and by those from abroad who were involved in organising and observing the poll, for the role that it played in the process. By and large, it concentrated on portraying popular expectations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During an election period, the print media is an essential vehicle of opinion and power, justifying the creation of special titles.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At present, the private press is playing an increasingly important role in the democratic process and the question of its survival appears to have attracted more serious attention from the authorities. In Senegal, a subsidy has been granted to a number of newspapers, subject to certain conditions, and Mali set an example this year by establishing a private press aid fund, with Cote d'lvoire about to follow suit.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The political context which has favoured this flourishing of the private press has had a marked influence on the way it has developed and on the editorial content of most journals - which is strongly focused on politics and 'national' issues. The press has barely had a chance to find its feet on the media scene and in the political process, and it has had to contend with huge  economic constraints. Low circulation figures are one key reason for its precarious position - newspapers are read only by an educated, urban minority. However, the press is now embarking on a new course, attempting to establish a loyal readership with a view to guaranteeing its long-term survival.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Independence and integrity ought, of course, to be the hallmark of journalism, although currently it is not  possible to say that the profession is dissociated entirely from political militancy. In the past, the press has played  a part in undermining the national consensus by promoting division and, on occasion, fomenting exclusion and confrontation. The issue today is whether the sector can now take its place in states governed by the rule of law, representing public opinion and helping to bring about a rapprochement of ideas. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">F.M. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Benin's press on parole?</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Richard Lawson T&egrave;vi</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When President Mathieu K&eacute;rekou of Benin granted permission to set up private newspapers in his country, the result was an upsurge of new titles. The following article is written by a journalist who works on  one of these publications ('Tam-Tam Express'). He offers an assessment of the way the private press has developed in Benin, and in particular of the ethical and economic challenges it needs to overcome in the new democratic order.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1988, President K&eacute;r&eacute;kou's revolutionary regime authorised the setting-up of private newspapers in Benin. At the beginning, only a limited degree of freedom was granted to new publications but things have evolved quickly. 'La Gazette du Golfe' and 'Tam-Tam Express', the first independent weeklies to be set up (two years prior to the 1990 national conference), went beyond what the Marxist regime had in mind and effectively achieved press freedom in the face of opposition from the Ministry of Information and Propaganda.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Journalists took advantage of their initial limited freedom to publish reports about political and financial scandals and this, not surprisingly, gave a new lease of life to the media more generally in Benin. In particular, journalists from the national radio and television  channels were quick to switch their style of reporting, dispensing with the stereotyped formal language which had previously characterised the public-service media.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Meanwhile, several politically oriented publications came into being ('L'Opinion', 'La Recade', 'Le Canard du Golfe'). This development gave newfound dynamism to the emergence of a free and independent press in the crucial period prior to Benin's national conference, which was held in February 1990.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To date, 170 titles have been registered with the Ministry of the Interior, although barely half of these have been published more than five times. Some appeared only once and many have existed in name only. Publications which have had only a sporadic existence are legion and, in the years between 1991 and 1996, when political power alternated between Presidents Soglo and Kerekou, independent privatepress titles flourished. Unfortunately, they faced a number of problems - such as prohibitive paper and printing costs and poor distribution networks. The result was that many operators were financially ruined as a result of their decision to venture into this area of publication.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Currently, the Benin market has only 20 or so titles which appear on a   reasonably regular basis. For the most part, these are two-weekly and monthly publications which concentrate their activities in Cotonou. The audiovisual media are conspicuous by their absence, despite the provisions of the Constitution adopted in December 1990, which gave special powers to the HAAC (Audiovisual and Communications High Authority), particularly as regards guaranteeing 'press freedom' and 'opening up the audiovisual sector'. No one knows when this law will actually be implemented, but it does appear that the Benin Parliament, which sits in Porto Novo, has been giving more attention to this issue since General K&eacute;r&eacute;kou's accession to power.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The relationship between the press and the state</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Governmen/press relationships are not particularly healthy at the moment. The usual reflex of authorities in any country is to control or manipulate the press wherever possible. At the ORTB (Benin Broadcasting and Television Office), a branch of the public sector, journalists often complain of the pressures they face in processing information. The same is said at the national daily, 'La Nation'. Fortunately, such pressures have not always shaken the resolve of the professional journalists.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The private press has a different problem. In this case, it is the newspaper proprietors who look to collaborate with the political parties. As one publishing editor has said, 'Our problem is more one of allegiance than of harassment'. Virtually all publications are political vehicles for one or other group - which makes nonsense of the code of ethics that is supposed to govern the profession. This phenomenon was most marked during the election period. All the titles that had been in 'hibernation' came to life again and new titles were born, only to disappear once the poll was over. This is also a reflection of the very meagre resources available to most private publishers. Those who do have sufficient means are usually quick to offer allegiance - for example to particular businesses - in order to position themselves more favourably from an economic  standpoint. Thus, some of the press rather overtly promotes particular economic interests. Others assiduously woo politicians and, in some cases, use blatant blackmailing techniques. In the latter situation, the 'market' operates on the basis that a file (sometimes assembled from a number of documents) will not be published if an endorsement is given or - what is worse - in return for hard cash. The justification for this shameful practice is that the market is highly restricted, sales of newspapers bring in very little income and advertising is non-existent but the newspaper has to keep going nonetheless. This situation also explains why defamation actions are frequently settled 'out of court' by the parties to the dispute.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A profession fraught with difficulties</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another explanation for the existence of blackmail is the lack of training. The majority of journalists working for private publications come into the profession for want of something better to do, after they have finished their university courses. One experienced journalist refers to these people as mere 'hirelings'. It is only once they have entered the profession that they learn the basics through joining journalists' associations and by receiving support from some of the bilateral-cooperation missions and foundations that are operating in Benin. The country does not, itself, have any colleges of journalism to speak of. Only recently, the national daily newspaper inaugurated a course for young journalists receiving their training on the country's various publications. This course will be spread over one year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Young journalists working at the national agency, the Benin Press Agency, are trained by WANAD (the West-African National Agencies Development) centre, under the auspices of UNESCO, which is subregional in vocation. The 20 or so trainees have no clear idea of what awaits them when they finish their course - whether all, or just some of them, will be taken on full-time by the agency. Those who are not kept on at the end of their training period are likely to  swell the ranks of the 'hirelings' - who seem fated to remain at that level.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The new administration will have to tackle the more general question of aid to the press in order to give a fresh boost to the private sector. This has been facing a real struggle since the devaluation of the CFA franc. The effect of the devaluation was to increase the cost of all the inputs needed for publishing newspapers. A new initiative of the part of the authorities would make it possible to offer more work to journalists and to improve considerably the quality of work they produce. To quote the publisher of a private newspaper: 'The influence of money must be curbed. To do this, the state must grant genuine aid to the press so that the profession can be genuinely free and objective and thereby fulfil the important role it has to play in the consolidation of democracy'. R.L.T. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Current media in the English-speaking Caribbean</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Dr Marjan de Bruin</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The author of this abridged article, who leaches et the Caribbean institute of Media and Communication (CARIMAC) at the Mona (Jamaica) Campus of the University of the West Indies, focuses on some of the peculiarities of press and media development in small island Caribbean states.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The English-speaking</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Caribbean comprises thirteen independent nations that are members of Caricom (the Caribbean Community) and a few  remaining small dependent territories. The total population is about six million. In most of these countries, the majority of the population is of African descent although in Trinidad and Guyana, about half the people are of Asian (Indian) origin.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The sea, whose name unites the islands, is a serious barrier to communication and social interchange between them. it takes as long to go by plane from Barbados to Jamaica (1200 miles direct, but 2000 miles via Miami) as it takes to cross the Atlantic from Paris to New York (3600 miles) - and the latter journey is usually cheaper! And until fairly recently, telephone calls from neighbouring Caribbean countries without a common language were routed through London, Paris or Miami.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The distances make communications difficult. Mail can take weeks, telephone circuits are often overloaded and, in some countries, unscheduled power cuts often disrupt computer systems at the most inopportune moments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Communication and the media</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Caribbean has a strong oral tradition. This, together with poverty and an estimated general literacy rate of about 80%, makes radio the most popular medium. Recent studies show,  for instance, that 99% of Jamaican households reported having at least one radio at home. In Jamaica alone, three large national radio stations between them broadcast nine hours of prime time call-in radio.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In all Caribbean countries, alongside the mass media, 'alternative' medias play an important role in communication for social change. In some countries, the term simply connotes non mainstream operations. In others it refers to alternative formats which are found in the mainstream media. The term also represents the use of other communication behaviour - popular theatre, dance, music, oral history, story telling. It has been suggested that the increased use of alternative media and alternative uses of mainstream media are an indication of the audience's dissatisfaction with the mainstream mass media.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In most English-speaking Caribbean countries, the government owns some of the major mass media, especially electronic. Only recently has the private sector developed its own strongholds in radio and television. Print has always been an area of mainly private ownership. Only the larger countries have daily newspapers; morning or evening papers - although usually not more than two or three. In the smaller countries the press consists of weeklies, or bi-weeklies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Government ownership</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ownership or control of media houses by governments is recognised as  a serious obstacle to true investigative journalism.The economies of all Caribbean countries are heavily dependent on tourism. Stories on environmental hazards and crises which might affect this essential source of income are subject to explicit or implicit (selfl censorship.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Government ownership in some instances means policy discontinuity over time; each new regime imports its own set of administrators and sometimes even entire newsroom staffs. In other instances, where the same party has ruled for a long time, positions within the media are very stable because they are tied to political loyalty.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Private ownership, however, does not mean an absence of potential pressure or political influences. In Trinidad &amp; Tobago, the country's oldest daily - The Trinidad Guardian - recently lost its Managing Director, its editor and six of its top editorial executives, after the owners - a supermarket chain - pressurised the editor to moderate criticisms of the country's new administration. The owners also tried to convince the managing director and editor to dismiss a columnist who was a disaffected and now hostile former member of the new ruling party. In apparent justification, the owners produced a document which suggested that it was the policy of the Guardian not to endanger the commercial prospects of its owners by injudicious criticism of the powers that be. Caribbean journalists attacked the Guardian ownership for what some saw as an attempt to turn a respected newspaper into the public relations arm of a commercial congLom&eacute;rate. Despite the protests, the Guardian's new editor, a veteran of forty years in journalism, argued that the proprietors had good reason to interfere with his predecessors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The region's oldest daily, The Jamaica Gleaner (established in 1834) went even further. In an editorial it said: 'In our view the owners have a right to oppose the way in which the judgment of the Editor and others is exercised. The right of the Guardian Board to query content cannot be questioned. It is impossible for a newspaper to be run   without the input of the Board of Governors.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Small markets</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most English-speaking Caribbean countries are relatively small in population as well as area. The number of media organizations is limited. The limited size of the market has important implications for the financial basis of the media, especially the part that is privately-owned. It limits the horizontal mobility of media workers - there are simply not that many options - and it makes the relationship between media and sources extremely vulnerable. There are not that many sources either. It also means that most Caribbean media houses have very limited resources. Many reporters have to cover a wide range of topics. Specialised reporting for instance on the environment, or health, is usually not feasible.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the major problems in the Caribbean media is the high proportion of imported television programming. The region is geographically close to the United States and satellite broad  casting makes access to the Northern networks even easier. In the ten years from 1976 to 1986, the imported content of four large television stations in the region moved from an average of 78.5% to 87%. When the amount of imported content carried by the smaller stations was included, the average increased to 90% of all material televised.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Privatisation and new technologies</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Several of the larger Caribbean countries have seen an explosive growth in the electronic media. Jamaica, which has a population of about 2.5 million living in some 620 000 households, and per capita GDP of $1563, has seen the number of radio stations grow from three to nine and TV stations from one two, in a period of just five years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Trinidad &amp; Tobago, with 1.2 million inhabitants in 300 000 households, and per capita GDP of $4049, went through a similar process, with seven new radio stations and two new, privately-owned TV stations being set up over the last five years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Barbados, with a population of 260000 living in about 50000 households has long supported two daily newspapers. There are also two TV stations on the island, while viewers can receive television signals from neighbouring islands. This country has the highest per capita GDP in the region ($5562) after The Bahamas ($10,308).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One positive effect of this intensive growth is certainly to be found in the increased employment opportunities for broadcasters. In the past, journalists risked their careers if they disagreed with their employers. Now people have more options. However, increased competition in a relatively small market also enlarges the risk of commercialisation and a lowering of standards. One does not need to undertake in-depth research to discover that locally-produced television is scarce and not always of the highest standard. It is cheaper to buy foreign programming than to produce original content. Some   of the graduates of the Caribbean Institute of Media and Communication, who performed above average during their training and education in print journalism, can be seen sliding down the standards scale once they enter the mass media as working journalists. Similarly, the standards of newsrooms are not always high. In fairness to the professionals, it must be said that the decline in standards is partly due to the lack of resources in editorial departments. The major newsrooms in radio and television in Jamaica, still depend on typewriters.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Development of new technologies has contributed to two almost opposite movements. On the one hand, greater access to worldwide networks has widened horizons. On the other, the introduction of cable TV offers, at least in principle, the possibility for small-scale communication initiatives, such as community radio stations either for geographical communities or communities of interest (for example, people or groups interested in the environment).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Satellite dishes, VCRs and computers are breaking down traditional communication borders. In the Jamaican capital, Kingston, 28% of households have a dish and 21% a computer. The picture is very different just 20 miles away, in the neighbouring but rural parish of St Thomas, where the figures are just 1% and 2% respectively. New technologies are affordable for the happy few and are increasing the gap between the 'haves' and 'have-nots' of information.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In all of these societies, computers sit uneasily in otherwise nondigital environments. The information that one works with is usually not computerised. Many records are still handwritten, with data kept on index cards. Computerisation is a costly process for which there is rarely a budget.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Once the hardware is available, it is easy to retrieve data from non Caribbean sources. At the same time, it is barely possible - at least at the moment - to tap into Caribbean data sources. There is no commercial Caribbean software. Page make-up and layout programmes, for instance, rely on  non-Caribbean electronic clip-art-images and symbols. It may simply be a matter of time before local products develop, but currently, the main constraints are to do with lack of funds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Journalism</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">How is journalism faring in this environment ? The Caribbean context gives journalism a special professional profile. The small size of Caribbean societies has implications for the use of sources. Access is easier, but it also creates sharper dilemmas where loyalty is concerned: most sources are people you know personally and who know you. Anonymity is almost impossible.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because the societies are so small, you will meet many of the same people in different roles on different occasions. The small scale of the market makes all enterprises in media and journalism very vulnerable to market forces: the withdrawal of one or two major advertisers would endanger the chances of survival of some media houses.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The situation of the press is most marginal in the smaller countries. In Antigua (population 66000), radio and television are controlled either by the Government or by people with close links to those in power. One opposition paper, a trade union publication, has survived several legal assaults by the authorities over the years. The other, little more than a newsletter, has managed to survive into its second year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Grenada (population 91000), journalists complain about police harassment of reporters on duty, and in most of the smaller countries, journalists are uneasily aware of the continuing hostility of long-ruling political parties.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The working environment of journalists in Caribbean media organisations is usually more modest compared to that of journalists in rich countries. There is less technology, smaller staffs and lower salaries. In the smaller Caribbean countries, it is not unusual for journalists to have to combine two jobs. Journalism alone cannot pay the bills.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is a sharp difference between rich and poor in most developing countries. For large sections of the population, the big decisions will have nothing to do with buying a second or a third television set.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is more likely to be a simple matter of whether there is food on the table tonight. These different priorities obviously influence a journalist's agenda.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In developing economies, this can create serious dilemmas for the journalists: if you know your story is likely to hurt the tourist industry - which happens to be the main national income earner of your country - will pursuing it be a waste of valuable time ? And how do you decide on the relevance of a scoop when people - some of whom are your friends - could lose their jobs ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">M.d.B.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> Sources</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hilary Brown (1995): American Media Impact on Jamaican Youth: The Cultural Dependency Thesis in 'Globalization, Communications and Caribbean identity', Edited by Hopeton S. Dunn, Kingston, Jamaica, lan Randle Publishers. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Aggrey Brown and Roderick Sanatan !1987). Talking With Whom ? A Report a the State of the Media in the Caribbean. Caribbean Institute of Media and Communication (Carimac), Kingston, Jamaica. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Aggrey Brown (1995). Caribbean Cultures and Mass Communication Technology: Re-examining the Cultural/ Dependency Thesis, in 'Globalization, Communications and Caribbean Identity'. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">'Doctoring' the image</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With modern computer technology, it is now very easy for publishers (and film-makers) to dabble with reality. Whereas in the past, you could be reasonably sure that what you saw was a fair representation of what actually happened, today there is no such guarantee.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Recently in the United Kingdom, one of the country's regional newspapers came in for criticism when it published a 'doctored' photograph of a well-known opposition politician. He was captured on  film at a social function sitting at a table with a glass of beer in front of him. By the time the paper's computer experts had finished with the photo, it looked as if he was drinking champagne ! When the story broke, the journal thought it expedient to issue an immediate apology. For while  this kind of misrepresentation may appear trivial, in the modern age, image is crucial for those who are involved in public life. Put simply, voters' are more likely to look kindly on beer-drinking politicians than on those whose favourite tipple is champagne.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There was a similar case involving an advertisement issued by a well-known car manufacturer. For their publicity in Britain, the company used a landscape photo portraying a selection of their employees. In Poland, the same picture was used but black and Asian workers were no longer to be seen. Their places in the line-up were miraculously taken by people of Caucasian appearance. The advertisers' rather surprising explanation was that this had been a 'mistake'!</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other recent victims of 'doctored' pictures or socalled 'photo collages' have included members of the European Parliament and a senior EC official, although these particular misrepresentations received very little publicity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Should consumers of printed or broadcast material be entitled to assume that images are never tampered with ? And if some doctoring is acceptable, where do you draw the line ? The answer to the first question is clearly no. There are certain situations where photo or film enhancement techniques are unobjectionable. We sometimes use them on The Courier cover pages to remove blemishes or fill in gaps which may detract from the main image. In fashion  advertising, it is common for the 'look' of the model to be altered. The aim here is to draw the reader's eye to the page so that their attention can then be focused on the product. More dramatic alterations may even be acceptable if it is evident to the reader that a change has been made. Satirical articles, for example, can sometimes be amusingly illustrated with obviously altered images.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Where the practice is reprehensible is where the picture has been changed in a way that leads the reader to draw false conclusions about what he or she is observing. The  classic example of this is where the image of a person captured in one setting is placed against a different backdrop, without the reader being informed. This may be done to give either a more positive or a more negative impression (the latter approach is more usual) but in either case, it is dishonest. If a politician allows himself to be photographed on a Caribbean beach while on mission at the taxpayers' expense, even if he was only there during the lunch break for a quick dip, then he can't really complain. But if the picture was actually taken when he was on holiday in Majorca, and superimposed against a more exotic back  ground, then both the 'victim' and the reader are being cheated.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There will always be borderline cases, but in principle, it ought to be possible to draw a reasonably clear distinction between 'right' and 'wrong' in this area.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nonetheless, it is likely that distorted images will continue to be presented to us in the future. In pluralist societies, newspapers and broadcasters operate in a fiercely competitive environment and in theory, this should provide a deterrent. If one media organisation is found to have doctored images in a dishonest way, there will always be plenty of others willing to expose the misbehaviour.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In practice, however, the only real deterrent is the likelihood of a drop in circulation, or lower viewing figures. And while consumers may say they disapprove of journalistic dishonesty (whether in photographs or the written word), there is little evidence to suggest that they react by taking their custom elsewhere. Indeed, in some developed countries, the closer a journal sails to the wind, the more likely it is to enjoy a high circulation!</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It used to be said that 'the camera never lies'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nowadays, we can't be so certain.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">S.H.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Analysis</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Broadening the debate</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In issue 156 of The Courier, we announced the launch of a programme by the European Centre for Development Policy Management on the future of KU-ACP relations beyond Lom&eacute; IV. Here, we publish an abridged text supplied by the ECDPM reporting on progress.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">After 20 years, the Lom&eacute; Convention is thought by some not to have lived up to expectations and now that East West rivalry is no longer an issue, many doubt its continued relevance. Questioning, as such, is no bad thing, provided it takes place in a fair and unbiased manner and is not used as a pretext to abandon the acquis  of more than 20 years of cooperation. This is the rationale behind a number of private and official initiatives to redefine KU-ACP cooperation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Consultations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The ECDPM's post-tome IV exercise has now been up and running for more than a year. Consultations have been held in more than 20 ACP countries, involving representatives from the private and non-governmental sectors, officials in the National Authorising Offices, EC delegations, regional organisations and research centres. A number of strong impressions have emerged from these interviews. In the first place, the initial comment of many NGOs and private sector representativ  was essentially 'what is in it for us ?'. This points to a lack of knowledge of the Convention in non-governmental circles and suggests that this complicated instrument is not entirely 'user-friendly'. Its government to government character was also criticised. There were calls for ACP-KU relations to be opened up to the private sector and civil society. In this context, experience with decentralised cooperation was seen as encouraging.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Second, the benefits of the Lom&eacute; trade provisions were highlighted with fears being expressed about what would happen after the year 2000. It was felt that at a time when many ACPs  are undergoing structural adjustment, and the private sector is getting its act together, a clearer European commitment in this area would benefit both sides.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Various actors from the private, NGO and research communities indicated a willingness to engage in debate on redefining mutual ACP-KU interests and on the design of a new cooperation contract. Some of them had an opportunity to present their views at an ECDPM conference on the future of KU-ACP relations held on 12-14 June.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is clear that the process of reflection is now firmly under way. At the institutional level, the Joint Assembly began as far back as February 1995, when it launched an action plan to revitalise KU-ACP cooperation. This year, it asked Senator Jean-Louis Firmin of Haiti to draw up a report on the future of the Lom&eacute; Convention. It also requested the Social Partners to tackle the issue at their next annual meeting in November 1996. On the European side, the Commission will present a Green Paper later this year while the ACPs are also studying the question. Last November, the ACP Council resolved that Heads of State should meet before the end of 1997 to agree on a joint position.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Obstacles</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All this activity suggests a real awareness of what is at stake. Many obstacles have to be overcome, however, if a new type of partnership is to emerge. The main pillars of Europe's commitment to the ACP countries - aid and trade - both appear under threat. It will be necessary to redefine mutual interests - beyond the negative interdependencies - so that they can serve as a basis for a more modern and effective partnership. Greater creativity  will also be required to find new forms of EU support on ACP trade issues that are compatible with World Trade Organisation obligations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An in-depth rethink of ACP-KU cooperation will significantly benefit from inputs by actors traditionally excluded from the discussions - who are anxious to participate in redefining cooperation ties. For instance, in Namibia, NGOs called for formal consultation mechanisms for non-governmental actors. Similarly, economic operators meeting in Trinidad in November called for a new Europe-Caribbean partnership. There should also be a role for applied research conducted in ACP centres. There is already a joint research project on the future of West Africa Europe relations and similar initiatives are being formulated elsewhere.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The plea for a debate that is open to the key ACP actors should be taken on board by decision-makers and negotiators - and thus far, they have proved receptive. However, two conditions are needed to maintain this fruitful exchange. First, ACP stakeholders need to be able to base their views on full knowledge of the facts and issues. It is essential that the Convention's authors make a major effort to provide more and better information. The ECDPM is willing to play a part in this. Initiatives already under way include the development of EUFORIC - a Forum on the Internet for specialised information on European development cooperation - and the preparation of practical guides to the Lom&eacute; Convention. Enhanced access to information can help all partners move towards a real dialogue. Second, forms and channels for dialogue. need to be devised to ensure that an open debate is sustained beyond the initial reflections taking place within the EU and ACP groups.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ECDPM</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">'Re-compromising' development aid for the future</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Jos Jonckers</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The author of this article offers an academy critique of *e challenges facing the global system of development cooperation in the post-cold War era. He argues that the old compromises that have shaped development assistance since the Second World War have broken down and pleads for a radical re-think of the strategy in order to 'enable' fess affluent societies to gain from the advent of global 'free market democracy'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Let us face it. International development early 50 years, the developed world has taken aid for granted. It no longer does. In real terms, it has started to give less. The expected 'peace dividend' has not materialised and scepticism is rising. Aid and solidarity are considered old-fashioned concepts. Progress and development, it is increasingly argued, must come from cooperation based on mutual interest and a businesslike approach.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Aid scepticism is at its highest in the USA. A conservative majority in Congress promotes radical 'winner' recipes and aid has been slashed. Slowly but surely, America is getting out of the development business. Lacking domestic support, the Clinton administration seeks to 'rescue' the country's aid programme by seeking more cooperation with other donors - particularly the KU, whose solidarity horizons do not yet stop at its own borders. But even here, horizons are shrinking. European aid to its immediate neighbours in the East and the southern Mediterranean basin has risen. Happy and prosperous neighbours suddenly seem more important than distant friends in need.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Has the end of the cold war marked the beginning of a cold world - where international solidarity is being dismantled together with the nuclear warheads ? Or could we be experiencing the beginning of a fundamental reshaping of international solidarity and aid between nations?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Beyond altruism - self interest</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">International aid has always involved a compromise within affluent society. People and nations are not normally disposed to give something away unless they receive something in return. Any attempt at understanding and reshaping the future of development aid must therefore start from the premise that those providing development aid do so as a result of a complex and evolving compromise between altruism and self-interest.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Affluent countries are usually only interested in assisting poorer ones when the effect is to strengthen their international leadership, and in some way to enhance their security and material wellbeing. Looked at in this context, we must recognise that development aid, whatever its altruistic aims, will only exist if it also serves the legitimate, albeit more selfish agenda of the donor. It also means that the compromise which gives aid its rationale in affluent society changes over time: aid is regularly 'recompromised'. In secure and prosperous times, donors are  more inclined to forego self-interest and to cooperate in the interest of less affluent countries. In times of insecurity, the altruistic dimension is likely to diminish in importance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In colonial times, systematic aid flows first emerged as a result of a compromise between expansionist Northern governments and Christian society with its own 'colonizing' clergy. Decolonisation had the effect of increasing insecurity in most former colonial powers. In an attempt to safeguard the capital they had 'invested' in their overseas territories, following the latter's independence, they increasingly shaped aid with a view to 'buying' goodwill from the new rulers. This process, which 'recompromised' aid from a colonial into a neocolonial form, resulted in the secular, institutionalised arrangement now known as 'bilateral aid'. In addition, during the Cold War, Western aid was used increasingly as a device to stop the Third World joining the Second World (the communist bloc). The result was an aid system which was both more internationalised and more politicised.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The next stage came with the end of the Cold War. Communism had joined colonialism and fascism in the dustbin of history. Affluent Western society had emerged as the winner. With it came the Western vision for stability, peace and progress: a world of sovereign nations, organised on the basis of democratic and capitalist market principles and committed to respect for each other's territory and for basic human rights. Today, capitalism has become the norm in most nation states. Long-time sceptics such as India, and even convinced opponents such as China and Vietnam, have embraced it. Democracy has not yet achieved the same coverage, but it is sailing forward under favourable conditions. Political pluralism is steadily being consolidated in much of East and Central Europe, while dictatorial regimes in Africa, Asia and Latin America are now the exception.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The effect of all of this has been a speedy erosion of the terms of the compromise on which development aid thrived for so long. In a rapidly globalis  ing,multi-polar world, the old approaches appear increasingly redundant. From this perspective, the current aid crisis is not surprising and is not necesarily a bad thing. Western affluent society is essentially trying to come to terms with the demystification of its development aid, as part of a process of reshaping it for the future.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Three 'recompromising' strategies</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As in the past, the recompromising process is influenced by both self-interest and altruism in affluent society. Three trends can be identified.. The first, which is the most idealistic, involves restoring altruism. This approach seeks to 'purge' aid of the perverse political and economic compromises and contradictions caused by decades of neocolonial and Cold-War self-interest. It has impacted on aid in several ways. First, it has given a significant boost to humanitarian aid - the most altruistic form - at the expense of development assistance. Second, it has led to a 'decentralisation' of aid - with more assistance being channelled through organisations such as NGOs, that have an 'uncompromised' altruistic profile. Third, it has led to a 'deconstruction' of development aid along idealistic-altruistic lines. 'Women in development', 'child health', 'environment'and 'poverty alleviation' are all examples of deconstructed labels around which aid is increasingly being structured and justified. Finally, it has prompted an 'intellectualisation' of development aid with the particular purpose of tightening its altruistic aims. For example, the Logical Framework Approach, the concept of 'sustainable development', the UNDP's Human Development Index and various experiments with more 'accountable' project management systems, have all essentially been devised as ways of encapsulating and supporting the altruistic intentions that lie behind aid.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The second recompromising strategy, which may be summed up in the expression be businesslike, approaches development cooperation  much more skeptically. Aid, it is argued, only makes sense if it leads to real progress and development - and the prevailing view is that this is not happening. The approach is fueled by the obsession of trying to measure progress with the help of business tools such as 'output', 'impact', 'efficiency', 'rates of return' and so on. This has led to burgeoning aid 'evaluation'. It has also probably contributed to the discovery of aid failures which, in turn, has prompted growing criticism of aid agencies and operators. The businesslike strategy has gained further ground because of the failure of many countries to achieve any real progress in recent decades. Its advocates argue that the compromises which undermined aid's development impact in the past are inherently linked with its altruistic nature. The conclusion is that altruistic aid will seldom or never work. The strategy has impacted on aid in a number of ways being, for example, the major cause of so-called 'aid fatigue'. It has also prompted a search for ways to enhance cooperation for mutual benefit, indeed transforming the narrow, pre Cold War trade cooperation link with developing countries into a much broader and rapidly growing economic cooperation approach. Finally, it has sought to enhance aid's impact on the economic conditions and growth prospects of developing countries through more ambitious, structural-oriented forms of aid.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Regionalism, the third major strategy, is linked to globalisation. Rooted in human survival psychology, this approach prompts nations in close proximity to form 'strategic' coalitions. In the post-Cold War era, development aid is one of the instruments used by affluent regions to strengthen their position in a 'globalising' environment. The strategy entails promoting 'open' regionalism elsewhere in the world and capitalising on this to create linkages and interactions which enhance their own influence or hegemony. From the point of view of the international political economy, this makes perfect sense. Having succeeded in making the 'world of nations' accept capitalism and democracy, it is through the consolidation   process of free market democracy in other countries and regions that powerful affluent nations will seek to gain maximum advantage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Need for a vision</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With this improved insight into the dynamics that have been reshaping development aid, is it now possible to go further and develop a more political vision of relations between affluent and less affluent nations in future ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Free market democracy, having endured the 'crises' of decolonisation, fascism and communism, has succeeded in promoting stability and peace within and between nations. Its main strength has probably been its crucial enabling function, with an increasing number of people and nations now in a position to 'earn' a better future. It appears that the model has the capacity to generate fairly equitable growth and progress, which is presumably why more and more countries are turning to it. As is so often the case, however, the strength of the system also contains the seeds of its weakness. Conceived as an 'enabling' mechanism, it results in the categorisation of those who fail to 'be enabled' as 'unable'. Marginalised because they cannot participate and perform in the   system, the excluded (whether individuals or states) are dubbed 'losers'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They are seen as a burden and a threat by the 'winners'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The result is disparity in society.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Experience in most affluent nations suggests that despite the enabling environment created by free market democracy, up to a quarter of the population finds itself unable to perform effectively, and is marginalised as a result. Moreover, there seems to be an upward trend in the numbers affected by unemployment, underemployment and poverty. Disparity never occurs without some cost to society, which is a good reason why it ought to be minimised. The costs come mainly in the form of internal transfers earned (but foregone) by the active, 'winning' section of society. In more sociallyinspired, free market democracies, it is accepted that marginalisation resulting from the model's shortcomings must be minimised and/or adequately compensated for. In more conservative free market democracies, exclusion is seen more as a weakness of individuals than of the system. Compensatory transfers are generally kept to a minimum to induce people to 'break out' of their situation. But while such societies may save on 'empathetic' transfers, they will generally need to spend much more of their wealth defending against threats posed by growing disparity, such as crime, drug-trafficking and political extremism.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The costs of disparity are political as well as financial. Genuine democracy is based on the participation of a representative majority of citizens. In affluent societies, however, a growing minority no longer participates. The real danger stems from the fact that this is highly skewed. It is the same, growing, marginalised minority that is 'unable' to participate which is also withdrawing from democratic involvement. The result is alienation from the political system and an erosion of democracy to the extent that its very survival may be threatened.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What is really at stake </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Having conquered most of the world's nations, free market capitalism is now set to conquer the world of nations, helped by technological advances in communications, transport and computer technology. Economists have amply shown that the interdependence resulting from free international competition need not be detrimental. Indeed, because global capitalism ensures that ideas, initiatives and resources can be 'put to work' anywhere in the world - wherever they generate most profit - interdependence is usually seen as mutually beneficial. In essence, it confirms what might be called the global enabling effect of free-market capitalism. The basic thesis is that the adoption by less affluent nations of free market democracy should 'enable' many more of them to improve the lives of their people in the coming decades. The boost engendered by this 'enabling effect' will, in turn, help to sustain progress in the more affluent countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If this is the aim, then a new vision should progressively inspire future cooperation between the affluent and less affluent countries. The first concern should be to define 'purpose' and 'interest' much more in terms of system and process, than of output. What really matters is the 'enabling potential' of free market democracy in the specific context of the less affluent countries. How something is achieved and by whom should take precedence over what is achieved. The ultimate aim must be to ensure that free-market democracy 'takes root' in less affluent nations and is able to determine who does what and how.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A second major concern should be to maximise the 'enabling potential' of free market democracy for the most vulnerable sections of individual populations. As mentioned earlier, up to a quarter of the people in affluent societies are excluded. In poorer countries, the figure is much higher. If free market democracy fails to enable a significant proportion of this marginalised group, then it will not take root. And if the poor cannot be mobilised, the  growth that does occur will be highly skewed, leading to growing disparity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A third point is to ensure that the 'global enabling' effect of free market capitalism does not become the exclusive preserve of deregulated capital and the 'winners' who control it, leading to new forms of exploitation and disparity. The concern must be to find a way of directing the combined forces of 'capitalism without borders' and 'democracy within borders' in such a way that it leads to a genuinely better world in which the number of 'losers' is dropping and disparities are diminishing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A historic perspective</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is useful at this stage to take a look at the history of capitalism. Freemarket democracy delivered affluence to about a third of the global population over the last century mainly because of the 'accommodation' between labour and capital in an enabling environment created by 'Fordist' mass-production and consumption. A similar accommodation is now needed to enable global free market democracy to extend material wellbeing to the remaining two thirds of the (continually growing) world population, while at the same time sustaining it among the existing affluent third. It is no longer an accommodation between capitalists and workers that is required, however, but one between the affluent and the less affluent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fordism basically transformed the 'interdependent' stake of capital and labour in the economic pie, into a 'joint stake' - leading to the production of a larger pie. By analogy, what is needed today is to ensure that affluent and less affluent societies develop a joint stake in the production of a larger 'global pie' as a result of new technologies and more efficient, globalised modes of production. Attracting and sustaining capitalist investment in such modes will increasingly depend on demand and consumption structures which guarantee that poorer societies share with affluent ones the benefits of such global production systems. In the same way that a larger 'mess-produced pie' was dependent on higher and more   equitable mass consumption, so will a larger 'globally-produced pie' depend increasingly on higher and more equitable global consumption. In this context, the principal policy aim of development cooperation should be to ensure that growth resulting from globalisationis both enabling and disparity-reducing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The disabling effect of</P>
+<P ALIGN="JUSTIFY">'poor' competition</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Driven by the powerful motive of capital accumulation, globalisation has the tendency to promote competition. In principle, this should be a good thing, but left unchanneled, it can have negative effects. One might draw an analogy between the conquering of the global market and the spread of water during a flood. The water always takes the easiest route, entering the most vulnerable areas first where it causes the most damage. Likewise, globalization, fueled by 'deregulated' capital, often tends to promote competition where it is easiest, but where it is not necessarily beneficial. This is the case, for example, in less affluent countries, where poverty is exploited to achieve what might be dubbed a 'poor' competitive advantage - in the sense that it is based on disparity, but also in that, far from 'enabling', it may actually have the opposite effect. Child labour, sex tourism, environmentally destructive tourism, tropical forms logging, the export of industrial pollution and misuse of intellectual property are all examples of 'disabling' competition resulting from global disparity. In a rapidly globalising world this is ultimately damaging to all concerned, which is why both affluent and less affluent nations have an interest in reducing the gap.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All of this points to the need for a major redefinition of society's role in general and of aid in particular. During the colonial and Cold War periods, development cooperation was progressively uprooted and alienated from society. Serving an increasingly complex and non-transparent agenda, it became more and more a 'cockpit' affair, piloted by a small specialised crew - and it  found itself flying higher and higher above society. In short, affluent society lost touch with development cooperation and aid. Occasionally, the media intervened to 're-establish contact' but the result was that development aid usually only attracted mainstream public attention when things had gone terribly wrong.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Turning vision into action</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If the aim is to have affluent and less affluent society working together to ensure that the latter adopts 'free market democracy'- and can adapt it in a way which benefits both - it is vital that the former be reconnected to the business of development cooperation. The affluent must be challenged to help transform their less affluent partners, in the interested and creative manner of a minority stakeholder. They must be ready to share the wealth of knowledge and experience generated in their own process of development. Representatives of all walks of affluent life should therefore be provided with greater opportunity for dialogue and cooperation with their less affluent counterparts. Increasingly easy and cheap communications and transport should facilitate this. This new form of stakeholdership will not happen, however, unless affluent society can be imbued with the new vision.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Donors should actively support the process. Instead of spending most of their time and resources determining the scope and content of development cooperation, they should step down from their cockpit. Their new role should be as brokers and facilitators of cooperation. An initial priority must be to extol the vision itself. As this gathers momentum, they should then turn to 'brokering' it in practice - acting as a catalyst between the affluent and less affluent in order to facilitate 'enabling' cooperation between them. The development of an effective brokerage profile and methodology will probably entail important changes in the way that donors work. They need to move much closer to their  constituency, and to be made democratically accountable again.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As mentioned earlier, the concept of enabling cooperation concentrates on who does what, and how. Essentially, therefore, it should be seeking to mobilise democratic and free market forces in less affluent societies. The advantage of working this way is that change and progress will be determined primarily from within the society in question - with cooperation as a source of encouragement. Such an approach also entails acceptance of the fact that the pace of progrms must be left much more to the enabling forces of the maturing democracies and free markets, however weak and imperfect these may still appear. Indeed, the central purpose of cooperation should be to help these fore" become stronger. To achieve this, cooperation will need to move away from an emphasis on engineering outputs to one which involves 'messaging' the system and process. And it is not just methodologies that need to be altered; there must also be a radical change in cooperation mentality. Thus, for example, donors should attempt to broker cooperation which is 'small but smart'. Advancing 'best practice' might be another creative way to pursue cooperation which is enabling. And while some output-related decision techniques can still be used, these must be creatively reshaped to support a more 'enabling' approach.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In conclusion, this enabling vision entails an awareness of the imperfections of free-market democracy, combined with a conviction that it offers enormous potential for the less affluent countries of the world. 'Recompromising' development aid for the future will mean reshaping it to support a process of adoption and adaptation of free market democracy in less affluent countries which is highly 'enabling'. The result should be a system of international solidarity which is working for free-market democracy, rather than as a substitute for it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J.J.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The effects of corruption on development</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> by Dieter Frisch</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Corruption - defined as 'the abuse of public power for personal ends' - has always existed. During recent decades, however, it has grown both in terms of geographic extent and intensity. Since the mid 1970s, it has infiltrated virtually every country in the world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It was hoped that the easing of political and economic restrictions that characterised the 1990s after the end of the Cold War would have gone some way to reducing this phenomenon. Through increased openness resulting from political pluralism and the freedom of the press, the process of democratisation should, under normal circumstances, mobilise efforts to overcome corruption. However, emergent democracies are still fragile and seem to find the task of tackling established self interests a formidable one.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By reducing state intervention and therefore the opportunities for corruption, economic liberalisation should improve matters. In the short term, however, the opposite would appear to be true. Weakened state structures, a lack of appropriate legislation, powerlessness on the part of the judicial system to combat corruption, the pursuit of easy money - mistakenly perceived by some as being equivalent to a market economy - all these factors together contribute to aggravating the phenomenon, at least in the transitional stages. Such a state of affairs cannot fail to have some effect on those who are involved in and concerned by development issues.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Needless to say, corruption and its effects can be seen from a multitude of viewpoints. There is always the ethical angle - but how can we possibly presume to preach to countries of the South and East when bribery is just as rife in the North and when, as far as corruption within international economic relations is concerned, it is in fact, virtually by definition, the North who is the corrupter and the South and East who are the corrupted ? The only possible reply to such an argument - and one which is morally disputable even though economically valid - would be that the rich North can afford the luxury of wasting some of its wealth whereas in the case of developing countries, their sparse financial resources need to be used in the best way possible! Other lines of reasoning emphasise the distortions that corruption causes in the fair application of conditions of competition by penalising successful, yet honest, undertakings.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A major obstacle in the path of development</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In my opinion, corruption should be approached from the point of view of the effects it has on development. I say this because long professional experience has taught me that corruption is one of the major obstacles to progress, and that its effects on development are disastrous.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some people would no doubt counter this assertion with the 'cultural' argument whereby they would have us believe that, in certain cultures, corruption is quite normal and morally acceptable. Well I do not know of a single place on earth where growing rich through taking bribes is considered lawful or morally acceptable! I should like to quote Olusegun Obansanjo,  former President of Nigeria, on the subject: 'In the African concept of appreciation and hospitality, a gift is a token. It is not demanded. The value is in the spirit of the giving, not the material worth. The gift is made in the open for all to see, never in secret. Where the gift is excessive, it becomes an embarrassment, and is returned. If anything, corruption has perverted the positive aspects of this age-old tradition'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Then there are the cynics - including renowned professors - who claim that corruption oils the wheels of progress and enables development to take place. In this respect again, and putting all ethical aspects aside, it would be worthwhile distinguishing between the small baksheesh which 'helps' certain administrative procedures along ('acceleration fees') and large-scale corruption which perverts the course of de  velopment. This does not of course mean that we should underestimate the destructive effects that even small-scale corruption can have on society!</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yet others have simply resigned themselves to the situation. For them, corruption is intrinsically linked to underdevelopment. As long as a person's normal income does not provide him with a decent living, the door will always be open to bribes. It is, therefore, through development that we should be attempting to eradicate corruption. Yet this argument is reminiscent of the debate on the population explosion. It is only through development, some say, that the problems of population growth will be resolved. But by then, the planet will be inexorably overpopulated! In my opinion, the same argument is just as valid as far as corruption is concerned. We simply cannot wait for it to be stamped out through development. (In any case, development is hardly a miracle cure: true, we have the examples of Singapore and Hong Kong where corruption is extremely uncommon, but we could also mention Italy, where it was precisely at the height of the country's development that corruption became the norm). We must act therefore, and without delay, focusing our efforts on eradicating large-scale corruption.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If we analyse some of the effects that corruption has on development, the first thing we notice is that it increases the cost of goods and services, and not insignificantly either. Although a 5% reduction in the profit margin might, at a pinch, be absorbed by the supplier, corruption levels of 10% to 20%, which have become commonplace, will inevitably be reflected in the price and will, consequently, be paid for through the national or foreign (in the case of foreign aid) resources of a country. It is therefore the national economy that ultimately suffers the consequences of an unjustified surcharge on the goods or services, with the difference being pocketed by some government official or politician who has abused his power for his own personal gain. Given that such operations are generally financed by bank  loans or, in the case of foreign aid, by concessional loans, these surcharges inevitably bring about a proportionate increase in that country's debts. In fact it is now assumed that the exchange value of sums paid out in backhanders makes up a considerable proportion of the foreign debts of developing countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, the damaging effects of such practices do not stop there. The corrupt decision-maker may well be tempted to accept a substandard quality of service which will make his personal profit all the greater. Thus, with a road building project for example, complicity between government departments and contractors may result in corner-cutting with regard to agreed standards of quality so that the savings made may be shared out between the two parties.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At their very worst, the disastrous effects of corruption mean that the conception of a project, and ultimately its very choice, are determined by corruption. As far as conception is concerned, a good example would be the purchase of a technology which is wholly unsuited to the particular needs of a country or the choice of a capital intensive project - more lucrative in terms of corruption - rather than a labour-intensive one which would nevertheless be far more beneficial to that nation's development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The absolute peak of perversion, however, is when the very choice of priorities - and therefore of projects - is determined by corruption. What we are referring to here are those situations in which the real development priorities of a country are neglected in favour of operations which generate the greatest personal gain for the decision-makers. At this point I would like to quote R&eacute;mi Godeau, writing in Jeune Afrique: 'These currency-guzzling abortive projects have become a graveyard of white elephants. Africa is littered with vast deserted motorways which are being eroded by the Savannah, with fully functional but empty factories which have been left to fall into ruin only a few years after they were opened, with railway lines which are now impassable  through a lack of maintenance, and with hydroelectric dams abandoned because they cost too much to run'. Let us pick up on the point about empty factories. These 'follies of development' are to be found in many developing countries and in Africa in particular. Some have never produced, others have failed to reach full production capacity while others still face such prohibitive costs that big state subsidies are needed to keep them going. If we follow the thread right back to the beginning we find, more often than not, that factories have been sold without ensuring real competition between suppliers. Admittedly, such projects usually have only private-sector backing (they are rarely financed through official aid), but the funding is nonetheless backed by state-controlled bodies. The existence of corruption in such cases must be more than mere presumption - what other reason could there be for making decisions which run so counter to the interests of development ? In his work 'Grand Corruption in Third World Development', George Moody-Stuart identified those areas which are especially vulnerable to corruption. These are most notably, the procurement of military and other   technically sophisticated equipment, and large-scale works (in other words, any major, capital-intensive project and any scheme where objective valuation and comparison is hampered because of the technical sophistication involved).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is worthwhile mentioning at this point that a country which borrows money to finance projects that do not satisfy its real needs, and which may indeed be considered economically futile or absurd, will see its debt burden increase - and not simply by the 10% to 20% that is used to fund 'backhanders'. The loss will ultimately be 100% if one views it in terms of the cost of the unproductive investment to the national economy. Discussions about the debts of developing countries rarely focus on the mechanisms which have produced these debts. Yet in most cases, they have become unserviceable on account of the ineffective use of overseas aid - the sort of bad management to which corruption contributes considerably.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What is more, by deflecting the sparse resources which do exist towards non-priority or low-priority areas, corruption contributes to a large extent to ensuring that fundamental needs such as food, health and education, are not met. It is therefore one of the causes of under development and of poverty in general. Needless to say, official aid is often called upon to make good the deficit left by the irresponsible management of otherwise available resources. Is it any surprise if, in the long run, public opinion in the countries of the North begins to grow weary of bridging gaps which efficient management of resources should never have allowed to appear in the first place ? How are we to convince European taxpayers that it is they who need to provide the money to fund bush clinics in countries which put their funds in prestige projects, if not directly into Swiss bank accounts?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A vicious circle that must be broken</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Effectively, we find ourselves in a 'catch-22'situation. Corruption is one of the causes of under development and poverty, yet poverty is in part responsible for its continuation. If a person cannot earn an honest living for himself and his family, then he is more or less forced into earning it by less honest means. Hence corruption is both the cause and the consequence of under development. In order to break the pattern we must therefore combat large-scale corruption inasmuch as it is a significant cause of underdevelopment and we must work gradually to eradicate the reasons for its propagation in society, and in particular to remedy the notorious lack of adequate income to ensure a decent standard of living.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In general terms, we can say that corruption also kills off the spirit of development. Nothing is more destructive to a society than the pursuit of 'a fast and easy buck' which makes honest people who work hard appear naive or foolish. That is why, in the context of economic reforms under the heading of 'structural adjustment', it is vital that the model advocated be one of a market economy based on a sound framework of legislation and on an efficient state. It should not allow free rein to the sort of ruthless capitalism which is aimed at immediate profit at all costs. The example of certain transition countries in the East, where a market economy has become synonymous with the law of the jungle, the Mafia and corruption, really should make us stop and think.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the final analysis, an economy undermined by corruption has the effect of discouraging potential foreign investors and public donors. Yet if development is to succeed, countries have to be able to attract a flow of capital. As Serge Michailof put it: 'Success attracts money. Waste, failure and chaos drive it away'. And although investors are very keen to do business, with the exception of a few opportunists, they all look for host countries that have a stable and predictable climate. Entrepreneurs have been known to withdraw from certain African countries - which are nevertheless rich in resources - because of the constraints imposed on them by corruption on a scale which they considered to be unacceptable. As for public donors, they are increasingly reluctant to offer financial aid to those countries that manage their own resources poorly. It is precisely this failing which is one of the causes of what we now refer to as 'aid fatigue'. Financial aid institutions should go as far as suspending their cooperation in blatant cases of corruption and bad management, just as they do in cases of serious violation of human rights. Conversely, 'good governance' should be the determining factor when allocating aid, and it would appear that Article 5 of the revised Lom&eacute; IV Convention does in fact foresee such an approach.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In conclusion, far from reserving the foregoing criticisms for countries of the South, I believe that the partners of the North have their part to play in the ravages wrought by corruption, be it only as a result of the inconsistencies between their development cooperation policies and their export promotion policies. Basing our assumptions on the principle that cooperation efforts are genuinely motivated by concerns for development - and I can attest that this is precisely the motivation behind the policies of the European Union, which I have served for a great many years - we should not forget that Western countries have a tendency to promote exports, by other means, without any consideration for the effects this has in terms of development. They thus contribute to the dishonest practices which we have been discussing. The fact that they tolerate, or even go as far as to encourage corruption as a means of promoting exports - restricting the application of the criminal law to acts committed on their own territory and allowing corruption to be taxdeductible under the heading of 'necessary expenses' - seems to me to be absolutely scandalous. In the AlortR too, the battle against the canker of international corruption is a formidable one. But it is a fight to which we are committed in the context of 'Transparency International' This NGO, which was created in 1993, makes its services available to any country which genuinely wishes to eradicate the scourge of corruption. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> D.F. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Close-up</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">National park  restoration in Chad: luxury or necessity ?</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Phllippe Dejace</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Terms like 'democracy' and 'sustainable development' are increasingly used to keep donors happy, and to present new development projects in the most favourable possible light. With this in mind, it is interesting to look at an example from 'the field' to see how genuine the commitment actually is. Adherence to these concepts has undoubtedly made a positive contribution to environmental protection, but there is also a negative side</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Since 1989, the Zakouma National Park in south-east Chad has been undergoing restoration in a   programme supported by the KU. Devastated by a decade of conflict, this wildlife sanctuary of nearly 3000 square kiLom&eacute;tres was little more than a huge graveyard in 1986 when Pierre Pfeffer of the Paris Natural History Museum visited it and decided to campaign for its restoration. Today, this is recognised to have been a sensible decision. It is acknowledged that wildlife are better off when they have a reasonably large area in which to live, away from human activity. Aerial counts made in 1986, 1991 and 1995 confirm that animal numbers are on the increase in the park and that irreversible destruction has been averted. Currently, Zakouma is the only area effectively being protected in Chad. The other designated sites (one park and seven reservations) remain impoverished and in a state of near devastation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Recognising the challenge</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One should not be lulled into complacency. Even when a process involving local village communities is initiated, the low standard of living of the inhabitants, their educational level, and the progressive deterioration of vegetation around protected areas in  variably make the latter a tempting 'target'. In these circumstances, it is very hard to preserve their integrity. At Zakouma, a busy time lies ahead. The local people must be educated and informed as quickly as possible. This presents us with the first hurdle given the inadequacy of the education sector. The Ministry of Education is underfunded and with growing numbers of pupils in the system, it is virtually impossible to plan special programmes aimed at increasing awareness of this particular problem.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are other reasons why there should be short-term investment in this sector. There are good arguments for preserving a few control sites while the awareness programme is under way, since these will one day serve to illustrate what can be achieved. It is also much less difficult to preserve an area than to try to reconstitute it, once desertification has set in. The site is part of the national heritage whose value can only increase. Moreover, in most cases, the protected areas ensure the survival of fish stocks in lakes and rivers downstream and act as a reservoir for game: many of the animals which breed there provide food for the people living at the zone's edges. Even frequent wholesale slaughter of wildlife, as happens during a war, is reversible if the vegetation remains intact.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although the park is cut off from human activity (the area is flooded and therefore closed, to all intents and purpose, for four months of the year), it has an uncertain future. It faces pressure  from itinerant herdsmen and poachers, the latter tracking giraffe right up to the outskirts of Zakouma village, which is in the middle of the park. Although located in a wildlife reserve of 20 000 km2 - which is supposed to be a buffer zone - the park is not truly protected because human activity inside the reserve is not controlled. In the dry season, the park teems with wildlife. A clear density gradient has been identified with the animal population dropping as you move from the centre to the periphery. Indeed, only about a third of the 3000 km2 is intensively exploited by the wildlife which lives there - and even this area is relatively insecure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Enclosure would give those who are keen to defend the park a grace period in which to set up long-term awareness strategies. Ironically, one danger results from the striking democratisation that has taken place in Chad. To win votes, some politicians have called for the bans applying to the park to be lifted. This approach has the potential to succeed because, owing to shortfalls in the education system, the electorate is insufficiently mature in political terms. Another factor is that traditional leaders, seeing their power progressively diminish, are inclined to 'revolt'. Thus, they may fail to intervene when stockmen deliberately invade the park, encouraged by demagogues in search of votes. When the grasslands are invaded by cattle, few wild animals can compete and they are forced to retreat to the central area of the park. Against this background of a need for urgent action, the Zakouma Park team is concentrating its awareness-raising efforts on traditional leaders and the administrative authorities - rather than on teaching schoolchildren about environmental protection (although such a campaign is also envisaged).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Participation ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some argue that setting up a 'sustainable and participation-based development' strategy would make it possible to avoid the situation that now exists in Zakouma. The idea behind such a strategy - which clearly has its   attractions - is that man is perfectly capable of managing his native territory. All that is needed is for him to be granted land and to receive support for his initiatives. Many who espouse this approach continue to despatch teams to demonstrate that this is the ideal response. Unfortunately, in the particularly complicated case of managing the environment on the fringes of a national park, the local people are usually reluctant to make the investment. The more normal inclination is to reap a short-term profit from resources that are within reach. The inhabitants are also tired of the lectures they get from specialists who visit for just a few hours. The scope of the problem is such that expertise needs to be available on an ongoing basis. Considerable resources are also needed to ensure.that the effort is sustained.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is not easy to halt environmental destruction in a market economy which has overturned traditional values and gives priority to increasing personal wealth and consumption. A natural environment's potential for exploitation is always limited. Yet stock-rearing involves the use of animals 'selected' over thousands of years to take maximum advantage of the least scrap of vegetation. By contrast, a wild animal is much more selective and never ruins the environment it exploits. It may even be able to adapt its reproductive cycle to the available food resources! We are nowhere near this situation in domestic stockbreeding!</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This is where 'sustainable development', which sounds highly reassuring, appears at odds with reality. Beyond a certain threshold, one cannot avoid depleting the resource. If one is to adopt an approach that involves the population actively, one must acknowledge that their response may fall short of what is needed. Indeed, they may do things which provoke migration, and are thus damaging. Thus, for example, the opening-up of a water source may attract more nomadic herdsman, thereby undermining rather than enhancing the surrounding area.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Awareness programme</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The single most significant step towards protecting the park would be to ease population pressure, but progress in this area is very limited. We can only wait for the birthrate to decrease; something which invariably happens as a country develops. But what will become of the national parks in the meantime ? In Zakouma, an eco-development team is currently listening to the villagers' claims. As elsewhere, an attempt is being made to gain time. Unfortunately, the current climate of transparency in Chad, which is one of the positive aspects of democratisation and should be a major asset, has not had much impact in this area. The awareness programme suffers from a serious lack of trained workers and when meetings are held, they usually turn into interminable discussions, simply increasing the level of frustration. On the other hand, a convincing discussion-leader can advance matters considerably and discussion is surely the right approach to adopt. Furthermore, the process must lead to concrete results. Otherwise, decisions taken may end up being postponed indefinitely because they conflict with the interests of political decision-makers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite the difficulties, the Zakouma team is placing heavy reliance on this desire for transparency. Although the project's initial aims have essentially been to restore infrastructures and thereby promote an increase in wildlife, the addition of an ecodevelopment aspect and ecological monitoring has made it possible to create an important 'reservoir' of knowledge. A computerized map of the vegetation has been produced with the help of a microlight equipped with a GPS (satellite positioning) system. There have also been aerial inventories tracking the seasonal density and distribution of wildlife, as well as in-depth sociological surveys in the villages most hostile to the park's existence. This major database makes it possible to organise meetings, conferences and discussions to demonstrate that the park's contribution is greater than it seems. One big frustration for local people living on the  park's fringes concerns the redistribution of the income it generates. Looking first at tourism, Chad hardly qualifies as a major holiday destination and those who do visit the park are too few to make a significant contribution (the income raised barely covers the cost of replacing their bedlinen !)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One interesting conclusion has been drawn from studies of the animal distribution in the different seasons. It appears that when pressure from nomadic herdsman is at its strongest, during the dry season, the wildlife take refuge in the park and numbers multiply in safety. When the stockmen return northward, the wild animals then go beyond the park boundaries where they are hunted and eaten by villagers. This is surely a form of income redistribution! Moreover, many young fish in the park's only river (the bahr Salamat), take advantage of the flooding of the area during the rains. This releases huge volumes of nutrients back into the ecosystem. In the park, the fish are safe from the fishermen who work downstream and they can swim back to their spawning grounds. This guarantees the renewal of stocks depleted during the dry season. The level of fish stocks in Lake Iro - and probably in the River Chari as well - is thus linked to the existence of the Zakouma Park! When this version of income redistribution is explained, it often helps to convince traditional leaders who then use their influence to limit incursions by stockmen or poachers. However, a lot remains to be done because demographic pressure and standards of living both make it more difficult to get the message across.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We know that excessive human activity always results in environmental deterioration. Zakouma, although under pressure, has been 'spared' to some extent, and as such, it represents an important resource. But some see it as a luxury and it faces a suspended death sentence. If people stop regarding its conservation as something that is necessary, the sentence will end up being carried out. In my opinion, the most reliable way of guaranteeing its preservation would be to enclose it completely.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">P.H.D. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Developing World</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">European NGOs look ahead at annual meeting in Brussels</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> by Agostino Ambrogetti</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 22nd annual General Assembly of European Development Non-Governmental Organisations (NGOs), and a thematic conference entitled 'A Europe open to the world', were held in Brussels from 18 - 20 April. Representatives of more than 800 NGOs attended, with the Assembly adopting 14 resolutions as well as issuing specific appeals on the European Union's Intergovernmental Conference (IGC) and on Lebanon. The Assembly renewed its approval of the development NGOs' 'Strategic Priorities', adopted the Work Plan for the 1996-98 period, and looked at the overall impact of the Lom&eacute; Convention with an eye to likely future developments. The subsequent Conference focused, among other things, on the issue of coherence between the EU's development cooperation and its other policies (notably trade and agriculture). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A general impression that emerged from the two events was that the NGO movement was attaching increasing importance to its role as advocate for the developing countries. A fundamental aspect of this is the ongoing dialogue that NGOs have with the European institutions, and the lobbying they carry out on policy issues. Commission representatives who spoke at the Assembly indicated their understanding and appreciation of this. For example, Development Commissioner, Jao de Deus Pinheiro, referred warmly to 'the very active role played by the NGO community in the debate on the mid-term revision of the Lom&eacute; Convention,' and acknowledged that the NGOs had mounted an 'important political lobby' in favour of increased funding for the next five-year period.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Commissioner was keen to emphasise the complementarily that existed between the European Commission and the NGO movement in support of emerging societies in the South. He also urged his audience to continue in their task of challenging the general apathy towards development cooperation. This, he said, entailed appealing directly to public opinion in order to influence political leaders.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A similar tone was adopted by Bernard Ryelandt, who heads the unit responsible for cofinancing NGO projects in the Commission's development directorate-general (DG VIII) He spoke of the 'decisive' action of European NGOs in balancing other lobbies such as the agricultural one. This, he believed, had the effect of improving the coherence of EU policies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Delegates from a number of countries set out their views on the advocacy issue, and what they saw as the growing NGO role in this area. Andy Rutherford from the United Kingdom said that he saw increased lobbying as necessary, complementing the work carried out in the field through development projects. He pointed out that Southern NGOs had themselves requested their Northern partners to pressurise European governments in the hope that the latter would adopt external policies more favourable to the developing world. Mr Rutherford also raised the thorny question of structural adjustment. The view that adjustment policies were not succeeding in eradicating poverty, had, he said, been acknowledged by the EU's Development Council in its resolution adopted in June 1995. With this in mind, the NGOs would be raising the issue with the World Bank and the IMF - where the EU Member States are among the most substantial contributors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guido Barbera, who headed the Italian delegation to the Assembly, took up this point, calling for more pressure to be exerted on the Bretton Woods institutions by European NGOs and indeed, by the European Commission itself. This was necessary, he believed, to promote coherent macroeconomic policies favouring the development of economic relationships with the less-developed countries. In more general terms, Mr Barbera applauded the growing NGO participation in the political arena, stating that this was both 'positive' and fundamental'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Evaluation of the Liaison</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Committee's work</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A document was presented to the Conference by the NGDO-EU Liaison Committee containing an evaluation of its activities. The aim, in drawing up the document, was to 'review and critically assess the work and organization of the Committee, and evaluate whether it meets the expectations of its stake holders.' In order to do this, NGO members were consulted through questionnaires.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The evaluation revealed that support for the Liaison Committee as the representative umbrella organization of European NGOs remains strong, although there is widespread uncertainty about the future. This is reflected in the perception that the Committee has   gradually been losing momentum. There were also some doubts expressed about its representativeness. Large NGOs, it was noted, were able to spread their efforts across different networks. The fact that small NGOs tended not to be involved in the Committee emerged as one of the critical issues for discussion.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Attention was also focused on the alleged weakness of many national platforms (the documents containing proposals drawn up by the various national NGO assemblies) in representing the aspirations of their member organizations. This issue, and the question of voting on resolutions without debating the documents in question gave rise to controversy. Some delegates boycotted the vote while others submitted a written protest and there is clearly some demand for reforms designed to make the Assembly's procedures more democratic.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">General conditions of cm  financing</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another highly topical subject on the Assembly's agenda was the proposed revision of the General Conditions for the Co-financing of NGO </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Projects in Developing Countries. Commission speakers who touched on this subject included Professor Pinheiro and Jacob Houtman who is a Director in DG VIII Both referred to the revision process that was currently under way, and emphasised the higher priority that would be attached to capacity building for Southern NGOs. This involves providing support to strengthen the organisational structure of the bodies in question, and to improve the skills of their staff in managing and implementing projects. Such an approach is now recognised as essential for the long-term sustainability of NGO activities. As Mr Houtman was keen to stress, the principles underpinning the KU-NGO relationship (recognition of NGO independence and specificity, freedom of initiative for European NGOs in cooperation with their Southern partners) would be safeguarded in the revised conditions. Other priorities to be set out in the conditions would include the promotion </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Notice at the site of a non governmental organisation in</P>
+<P ALIGN="JUSTIFY">Zimbabwe devoted to improving agricultural productivity</P>
+<P ALIGN="JUSTIFY">'Crucial to provide more institutional support for Southem</P>
+<P ALIGN="JUSTIFY">NGOs' of democracy and human rights through reinforced structures of civil society, and a greater emphasis on the fight against poverty, income-generating activities and social development programmes. With these objectives in mind, it was all the more crucial to provide more institutional support for Southern NGOs. They, unlike their Northern partners, had a permanent presence in society in the developing countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The revised general conditions would also reflect the new orientation which favours a long-term programme approach over the traditional project by-project method. This should lead to a reduced administrative burden, and benefit long-standing NGO partners who have demonstrated viable approaches in working with their Southern counterparts, as well as good management and accountability.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'A Europe open to the world'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Conference which took place following the NGO General Assembly focused on assessing the coherence of different EU policies and on ways of achieving coherence where it might be lacking. As the title of the Conference suggests, the question which was never far from participants' minds was 'what sort of Europe is being created.' Is it a Europe which stands in solidarity with the South (and East), or is it one which retreats into its fortress, concerned only with its own prosperity ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the outset, EU policy - or rather its mode of implementation - came in for criticism. It was claimed, on the bask of the experience of both European and Southern NGOs, that the principles of development cooperation set out in the Maastricht Treaty (Title XVII) were not being applied universally and consistently. These principles include the sustainable economic and social development of developing countries, their integration into the world economy, the fight against poverty, and the development and consolidation of democracy, human rights and the rule of law.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this connection, three specific discussion topics were selected: the EU's common foreign and security policy (CFSP), its common commercial and agriculture policies (CCP and CAP) and its immigration and asylum policy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Regarding the first of these, it was suggested that the EU's definition of 'security' tended to be viewed solely in terms of common defence, and that the concept of 'human security' drawn up by the UNDP had been neglected. The latter seeks to define the concept on a broader basis including aspects such as equitable and sustainable development, as well as human rights and democracy. The view was also expressed that a more firm and coordinated CFSP was needed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the second topic - trade and agriculture - there was a strong feeling that the policies of the EU (and the USA) were heavily weighted in favour of 'home' producers and that this had the effect of undermining local production and food security in the</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Developing countries. The Union was urged to remove the policy 'contradictions' that allowed this situation to arise bearing in mind the specificity and sensitivity of the food trade.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, several speakers were highly critical of what they viewed as negative trends in the approach to immigration and asylum adopted by the EU and its Member States, with increasingly strict rules being implemented. There were also calls for measures designed to integrate resident migrants into society.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Indeed, integration may well be seen as the key message to have emerged from the NGOs' gathering. The call was for the people and governments of the European Union, acting in the Intergovernmental Conference (IGC), to integrate the needs of the rest of the world's people into their actions and programmes. The talk was of common values of human rights and solidarity, in both internal and external polices. And it was clear from the commitment of those who attended that the NGOs are determined to maintain and strengthen their role - as active partners in the development of the South, as advocates for the developing countries and perhaps indeed as keepers of the European conscience.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A.A.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Workshops</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As part of the proceedings of the NGO General Assembly, three workshops were organised dealing with specific themes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Workshop 1 was entitled Beyond Lom&eacute; IV. There was a general consensus among those taking part that the Convention's underlying philosophy helped to protect developing countries in today's global commercial environment. Without the Lom&eacute; system, it was felt that the ACP countries would have suffered even more from the deterioration in their terms of trade. With this in mind, the World Trade Organisation came in for criticism for its stance against regional preferential agreements (even if this does not apply to the least developed countries).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The major finding of Workshop 2, which dealt with Poverty in the North and the South, was that  poverty is the result of interactions at a global level - and is not 'nation specific'. It was therefore important to adopt a global approach in  seeking to tackle the causes of poverty, and to develop further North-South exchanges of experience for the benefit of both sides.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The third workshop was devoted to making the most of EU Presidencies. Here, the aim was to evaluate past experience of lobbying undertaken by the NGO community in those countries holding the EC Council Presidency, during the six-month period in question. The main recommendation to emerge was that more needed to be done in establishing contacts and exchanging information between the relevant national NGO communities. Such exchanges, it was felt, were needed before, during and after the six month Presidency period, in order to facilitate continuity of lobbying on key themes. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Resolutions </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the Resolutions adopted by the NGO General Assembly, considerable emphasis was placed on human rights</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> issues, with texts being agreed on Nigeria, the peoples of the Western</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sahara and the child sex 'industry'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Trade (in the widest sense of the word) also featured prominently. In addition to a general resolution on world trade, representatives passed motions on the arms trade, traffic in landmines and the production of the drug coca.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Also adopted were resolutions on preventive diplomacy, cooperation with Cuba, the Euro-Mediterranean partnership and the 'deterioration' of the situation in the Great Lakes region of Africa. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Africans seek bigger share of tourist dollar</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Godfrey Karoro</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zimbabwe's government is under pressure to encourage greater African involvement in the predominantly white-run tourism industry, which is facing intense competition from neighbouring South Africa. 'Black participation in all sectors of tourism is a priority,' says Environment and Tourism Minister Chen Chimutengwende. 'Blacks have waited in the wings long enough,' he adds, 'and their entry on to centre stage is inevitable. The solution lies in nurturing black entrepreneurship and giving it the material and technical backup to ensure its growth.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Only 38 of the country's 436 tour operators are indigenous, and most focus on provision of goods and services, particularly transport. African interest in the business was kindled last year when the government identified tourism as one of the sectors which could benefit from an international $74 million credit facility. This prompted enquiries from  about 500 potential entrepreneurs. Interest was heightened during the election campaign earlier this year, when President Mugabe's government made an issue of the continuing economic domination of the white community which constitutes  less than 1% of the country's 11 million population.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mr Chimutengwende pledged support for greater black participation, but the government itself is under fire for not doing enough. 'We have a time-bomb and the government should do something about it quickly before it explodes,' says Colin Blythe-Wood, managing director of a tour company and chairman of the Zimbabwe Association of Tour and Safari Operators (ZATSO), referring to the black-white imbalance in the whole economy. 'We are indeed fortunate that this industry, which has perhaps the greatest potential in our economy, is still in its infancy,' he says. He argues that the government holds the trump card, through its ownership of vast tracts of land in national parks, forests and communal areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A 1994 Zatso report identified more than 100 sites on state-owned land suitable for development by African tourism ventures. At least half, says Mr Blythe-Wood, were in areas of abundant wildlife, including the 'big five' - elephant, lion, rhinoceros, hippopotamus and buffalo. Other opportunities could be provided he suggests, if the National Park service got out of the accommodation business and concentrated on flora and fauna conservation. 'The government cannot be a referee and a player at the same time. It should sell off its shares in the Rainbow Tourism Group' - a wholly-owned government company which is the third largest operator in the tourism sector.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the industry's problems is that South Africa, too, has found tourism to be an unexpectedly good economic performer. Arrivals there rose by 50% in 1995, and a new government discussion document suggests that tourism could double its foreign exchange earnings by the year 2000 and triple its contribution to national income. South Africa's parks and beaches are well developed, but entrepreneurs are also fostering attractions such as Boer War battle sites and 'Road to Freedom' tours in which visitors have breakfast with former freedom fighters.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The fear is that South Africa will be the regional hub for visitors, siphonino off  most of the earnings, with</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zimbabwe merely getting the overspill from short side-trips.</P>
+<P ALIGN="JUSTIFY">Zatso chief executive, Elias Nyakuni, points out that South</P>
+<P ALIGN="JUSTIFY">Africa is already using Zimbabwe's top attraction to lure visitors, urging them 'to come to South Africa to see the</P>
+<P ALIGN="JUSTIFY">Victoria Falls'! Efficient train, luxury bus and air services connect several South African cities to the Falls, which are on the Zimbabwe-Zambia border. Mr Nyakuni says that Zimbabwe  could also lose out if things go wrong in their southern neighbour. 'Violence in South Africa could deter people from coming to Zimbabwe.' He accuses the government of not taking marketing in Europe and North America sufficiently seriously. 'The 4-5% annual growth is, in essence, through word of mouth. We need to investt more in marketing.' He says that the Zimbabwe Council for Tourism is underfunded and that it operates 'without brochures or pamphlets.' Neverthelms,  with 1.25 million visitors last year spending $252m (up from 1.04m spending $203m in 1994) - tourism is a growth area in which black people could take a bigger share - and not just, as at present, as guides, drivers, mechanics and cooks.</P>
+<P ALIGN="JUSTIFY">Lovemore Chihota, who runs a booming Victoria Falls safari business, has shown the way. He admits that there is a lot of money to be made from tourism, but warns that careful preparation is needed, as well as determination, commitment and, a realisation that there are no quick returns. He also points to the need to have some equity. 'The promoter,' he stresses, 'must put his money where his mouth is.'</P>
+<P ALIGN="JUSTIFY"> G.K.</P>
+<P ALIGN="JUSTIFY"> </P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Culture and society</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Dak'Art 96</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the most important exhibitions of African art, the Biennial Festival of Conternporary African Art, opened its doors to the public in Dakar, Senegal, on 8 May 1996. The 'Pan-African Art Exhibition', as it is still called, was being staged for the third time although it almost failed to take place at all, having been postponed several times over the last four years. All those who participated - from the artists who exhibited to the directors of art galleries and cultural  institions - were pleasantly surprised. The next edition of me Courier will include a more comprehensive account of the exhibition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">President Abdou Diouf of Senegal inaugurated the event at the Daniel Sorano National Theatre in the company of a number of VlPs, including BartoLom&eacute; Amat Armengol who represented the European Commission. The Commission was Dak'Art 96's main financial partner providing support to the tune of CFAF 200 million (ECU 300 000 approx). The Biennial Festival aims to be a showcase for African artists allowing them to break into the international plastic arts market. Hitherto, this has remained relatively closed to them despite the general recognition that Africa has a contribution to make to the art world in this area. Mr Ousmane Sow Huchard, chairman of the Festival's scientific board, stressed that success lay first in stimulating the art market in Africa itself. He gave the example of his own country which had voted the so-called '1 % law', which stipulated the proportion of works of art that should be used to decorate all new public buildings.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Festival's main exhibition, at the Ifan Museum of African Arts, was devoted to major trends in African sculpture. 42 artists selected by an international panel took part and, despite some criticism, their choice was a  judicious one. The same cannot be said, unfortunately, of the second major exhibition, at the National Art Gallery. This was devoted to contemporary Senegalese art and the skill involved in producing the exhibits was not of a consistently high standard.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There were also five individual exhibitions featuring artists chosen by internationally famous judges. These might be expected to have a dynamic effect in setting standards on the market. Zeribun Yempeta of Ethiopia offered a quite original style, working on a support of leather straps fastened to a trellis of fine strips of wood. He draws his inspiration from a combination of African design, Coptic and Greek influences, and ancient Egyptian art. Ethiopian painting was one of the major revelations of the 'Africa 95' exhibition in London last year and the Festival gave a further opportunity for such art to be displayed. Another display presented work by the Moroccan painter, Mohamed Kacimi, whose pictures have been hung in various exhibitions - although the term 'pictures' is not always appropriate to this artist's work. It is perhaps more fitting to say that he 'occupies space'. In Dakar, he covered three walls of a large room with 'rolling art'. His skill, particularly in monumental works, is to offer excitement and calm simultaneously, through the use of animated forms and soft, rhythmic harmonies. Ezrom Legae of South Africa, Moustapha Dime of Senegal and Pascale Martine Tayou of Cameroon were the three other artists granted individual exhibitions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the trends which came to the fore at Dak'Art was the use of alternative media and recycled material. The latter, in a sense, is the man in the street's legacy to art. Initially, recycling was used predominantly in the informal sector to produce utilitarian objects. The 'Biennial Festival Village' was set aside for informal sculptors, and in an open area beside the Village, both inside a marquee and outdoors, one of the most individually striking exhibitions was presented. This combined a variety of artistic forms ranging from painting to video, not to mention Adeagbo's unusual montages, including 'African artists and AIDS'. This had already been exhibited in a number of countries and was staged by the Revue Noire team in parallel with its 'AIDS' issue.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Festival included dozens of on-site exhibitions as well as all the 'fringe' presentations. The AIDS exhibition was one of the boldest but the display entitled 'Love' offered the greatest degree of unity and uniformity of design. Dak'Art 96 also made an attempt to integrate other forms of creativity such as dance, design and fashion. The latter two, for example, were presented at the Espace Vema, a fine metal structure where the creations of the Senegalese designer Claire Kane were in perfect harmony with the highly original furnishings. The European Union's prize for creativity, one of the Festival's four major prizes, was awarded to Vincent Namien, a designer from Cote d'lvoire.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hege'Goueier</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">On creativity... in Africa and elsewhere</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> by Alain Nicolas</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The author of this article is head curator and director of the Museum of African, Oceanic and Amerindian Arts in Marseilles. Here he offers his thoughts on the (partially unconscious) reluctance of the 'official' art world in the West - museums, critics and art historians - to accept contemporary African artists. Even now, they tend to be relegated to the sphere of 'alternative' art. However, he believes that the abundance of creative Africans, and the pressure they are exerting on the art world and market will, sooner or later, generate a 'new revolution' in the museums. This iswhat happened in the early20th century when traditional African art first arrived in the West. This article is linked to the dossier on African creativity published in our previous issue.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When I was asked to make this small contribution on African creativity, I was happy to oblige since, as a non-specialist, I am able to content myself with a few generalisations. I believe that there are still barriers, sometime not very visible, but nonetheless real, which have to be broken down.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unfortunately, writing just a few lines on creativity is a difficult exercise given the amount of literature on the subject and so many divergent opinions. So, what line should I adopt? About 15 years ago - in the wake of hordes of specialists in the humanities from sociology, psychology, ethnology, anthropology and so on - a rational approach, known as 'the anthropology of art', was at last proposed. The term 'rational' should be seen here in the context of the distinction between exact or 'hard' sciences such as mathematics, physics and astronomy, and the humanities, which are essentially inexact or 'soft' disciplines. And in brief, the West tends to take a scientific approach, relying on empirical evidence, even when it seeks to study such subjects as human creativity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Creativity obviously is to be found in many different spheres. It is needed in technology, it is fundamental to story-telling, it underpins all forms of social organisation and has a part to play in religion. Similarly, what we term 'art'  is one of the spheres of creative endeavour. The anthropology of art seeks to document artistic creativity and to analyse the conditions surrounding its expression in various cultures. This is a laudable enterprise insofar as art is regarded as another means of expression, used in one form or another by all human groups.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The creative function is universal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The basic postulate is that any society - and any individual - possesses creative potential which may be expressed in any way. The first thing to examine, therefore, is the context of choice. There are various modes of artistic expression ranging from music, poetry, prose and dance to architecture, painting and fashion. Some individuals or societies may have no choice, perhaps because of socio-economic constraints. Others may favour a particular mode of expression while nonetheless dabbling in more than one area. The expression of creativity is, therefore, like an identifying mark, claimed by the group or by the individual. The concept of 'style' now comes into play. The expression of one group is different from that of another and no two can ever be the same. Fundamental elements are at work in this materialisation of creativity. Some  are due to the natural environment. Thus, for example, a society located in a place where wood is abundant may favour sculpture. Others come from the group or individual themselves. And in the final analysis, it is the groups or individuals that decide what to portray (or not) on the basis of their own social norms and what they want to express.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These few limited thoughts should be supplemented by the observation that sculpture or the plastic arts more generally can also be examined from at least two angles: as a means of conveying information, and as a form of linguistic expression.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As regards the former, some have proposed analysing any work of art, from whatever culture, as a message. Analysis of the work therefore includes an examination of the conditions surrounding the production and transmission of the message. What message is broadcast ? How does it function ? What does the addressee gain from it? This approach is fine in hypothetical terms but does not allow one to go beyond theoretical and formal data, teaching us nothing about the content of the message under study. It refers back to the originator who holds the keys to the way in which it was sent and thus to its form and meaning.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Linguistically speaking, we assume that all expression through sculpture is a language and that the techniques for studying language can therefore be applied to the work of art. This approach is more rewarding because it brings us closer both to the sources and to the function of communication.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Be that as it may, all methods involve knowledge of the group or of the individual (but also of the relationships between them) and thus of any organised knowledge. Art cannot be separated from perception. This is the position of the majority of scientists. Yet we are not completely certain of this. Briefly, we are led to imagine that art could be irreducible at a certain level. When we look at a sculpture or listen to a piece of music, aside from the emotional content which is at least   partly quantifiable, what are we able to understand about the culture which produced them ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Having travelled widely throughout the world and kept my eyes open, without having become the 'observer-participant' which the ethnologist should be, I am certain that the same creative function can be seen everywhere, and it is not difficult to identify.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Frequent visits to the world's museums and, perhaps above all, to their vaults, further reinforces the impression that constants do exist and are worthy of more and better investigation. Art, and more particularly the art of others, from other continents, is still the domain of a happy few.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They are usually highly literate people, and are seldom activists expounding a cause.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Contemporary African art must find its niche</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The above statements relate as much to contemporary art as to what we term 'traditional' art. How many of the world's museums really show contemporary art from Africa ? It is as if this sector were cut off from current cultural reality. This is despite the fact that each week, new artists, musicians, designers, painters, sculptors, dancers, film-makers, stylists and photographers emerge from Africa, to be 'recognised' in the West (if anyone knows what 'recognition' really means!). The museums are, in fact, confused by this burgeoning of talent because they have no idea how to manage it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It has been said that contemporary African art is an urban phenomenon aimed at those living in towns and cities - and that it rebels against essentially rural, traditional art.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The argument is that the usual methods for analysing traditional art cannot be fully mobilised because 'urban civilisation' conforms to a set of universal norms (more or less), which are distinct from those studied by ethnologists. It would, therefore, be more appropriate to consider contemporary art in the context of sociology and aesthetics. This may be true, but it still comes down to a matter of observation. Confusion reigns.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When we staged an exhibition in Marseilles by the Senegalese sculptor, Ousmane Sow, the first individual showing of his works came as a major shock to many people, including the specialists. I can remember the reactions of at least   two colleagues from museums of contemporary art. What they said was almost identical, and was along the following lines:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What's the name of this sculptor ? I am not familiar with him...</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A N. Do you like his work ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Yes, I do, but what's his name ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A.N. Ousmane Sow </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· I don't know him. Astonishing! Where's he from ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A N. Senegal - he lives in Dakar. Are you interested in his sculptures ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Yes, but..</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A N. You can buy one of his works - he's not very expensive yet and it would be good for your museum. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The problem is he's African.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AN. I see... </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· His works are more your sphere.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A.N. But they don't have anything to do with traditional art which is what I have in my museum. Ousmane Sow is a contemporary artist, isn't he ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Yes, but he's African, and your museum is a museum of African art.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A N. You're correct, I would love to buy one of his works. But it would be the only example of contemporary art in my museum and would represent a change of policy for me. You wouldn't have anything by Ousmane Sow. And we would then be rivals! </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Critics, artists and art historians have begun discussing contemporary African art, more and more good reviews of it are being published, talks are being given and some major exhibitions have been mounted. There are pioneers and supporters in France, Germany and elsewhere, and there is even a great museum - Washington's Smithsonian - which took it on board several years  ago - but we still seem to be a long way from a commitment from most institutions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I hope this statement will soon be proved wrong. Institutions do not like taking risks. Either they create 'ghettos' ('let's set up a museum of contemporary African art'), or they set up committees to consider the subject. It is up to us to set our houses in order, but we must not be too naive. This is the art market, after</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although we tend to cling to this somewhat short-sighted administrative view that there should be different institutions depending on whether we are dealing with heritage or contemporary creativity, museums of contemporary art must integrate all the world's sculptural expression. If not, they will be in conflict with the above; postulate which claims that creative  potential is the same everywhere.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As for so-called museums of anthropology and also a few rare museums such as the Museum of African, Oceanic and Amerindian Art in Marseilles, the systematic exhibition of contemporary art does generate a number of problems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When I have wanted to do this in the past, I have been reminded of the 'museographic landscape' and advised to consult the authorities, to organise a major debate on the topic: who, what, where ? That is the rational approach, we are told. There is no great hurry!</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In fact, the recent arrival of African artists comes at a moment in our history when we are questioning the existence of our museums. When I say 'we', I mean the West in general.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So, what might happen ? Traditional African art caused an explosion in Western art and traditional art history at the very beginning of the 20th century, with the cubists and their research which led them to develop a passion for African sculpture. We are all aware of what we owe to Africa and its traditional artists.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Contemporary art from Africa is knocking on the closed door of Western museums, but the arrival of contemporary African artists and the pressure they exert on the art world and  market might trigger a new revolution in the museums, which are also the archives. Certainly, all the usual followers are ready to take up the cause, and that is how it should be. Let's be optimistic.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A.N. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The works of Ainsley Yearwood: Bombarded with colour</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Claude Smets</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ainsley Yearwood is a Trinity dadian artist based in London. me Courier had the opportunity to meet him recently when an exhibition of his works was staged at his country's embassy in Brussels. Brought up in Trinidad, he moved to London to study fine arts at the Chelsea Art School. Feeling unable to express himself fully in this discipline, he ended up taking a degree in graphic design. Mr Yearwood is still based in the UK capital where, in addition to his work as a painter, he also designs costumes for the Notting Hill Carnival, a cousin of the famous Trinidad Carnival.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The artist is fortunate to be able to live from his work. Besides the present exhibition which is touring Europe (Manchester, Brussels, Geneva and London), he has other works currently on show at three galleries in the US. He finds that the reaction of the American public is different from the European one. Americans, he believes, are more spontaneous and openminded. 'Europeans tend to stick more to things they already know; to which they are more accustomed.' The titles he gives to his art pieces are for him 'a basis for artistic conversation' with his audience. They express his emotions, feelings, and thoughts, but do not try to impose a specific interpretation of the painting on the viewer. Ainslie Yearwood dislikes the idea of being labelled or categorised - or as he describes it, 'to  be put into a box'. As such, he rebels against people who try to make him conform.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A world citizen</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although Ainsley Yearwood recognises his African roots within Trinidadian society, he sees himself as 'a world citizen'. The influences in his paintings are many and varied - deriving from the multicultural background of Trinidad and Tobago, European art and graphic design, the memories of his own childhood and his recent experiences. 'I am like a sponge', he says. 'Everything influences me in my work... people, places and all that I see around me. They help me to view things from a different perspective.' These all then flow together to be visualised through his 'inner eye' (expressed, for example, by two blue dots in his work In the Company of Nature which represents the Grand Canyon). By paying particular attention to what he sees, his 'visual view' is transformed into an 'emotional view'. Thus, for example, his painting Evolution appears to be a landscape. A :loser look reveals that the rocks are in the shape of hands.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The artist also uses symbols in dome of his work, as a personal means 'or him to express life. The butterfly :rapped in a jar, for example, in Love lost, is a symbol of the fragility of life. The glass of water in Soul of a Mother symbolises the way a child looks at the world as something exciting and new. he also draws strongly on the imagery of candles, inner eyes and doorways.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Strong colours, strong emotions</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What unifies Mr. Yearwood's work, is his use of colours. As he says, they are 'strong colours to express strong emotions'. In this, he has been inspired by his childhood in Trinidad which, in his own words, 'was an environment that constantly bombarded you with colour - from crystal to aquamarine, sapphire and emerald - a perpetual rainbow of red, yellow, green and blue'. One painting where colour is used to striking effect is Carnival Bacchanal. This depicts Trinidad's Carnival and reflects both the island's multicultural society and its vividness.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ainsley Yearwood has also produced more surrealist and psycho-biographical works, under the influence of artists such as Salvador Dali and Francis Bacon. Emotions are revealed through the use of darker though still vivid colours. These works (such as Evolution, </P>
+<P ALIGN="JUSTIFY">Translucent State and Suspended in Limbo) show a fragmented self, stuck between past, present and future, looking for a way forward. They come in stark contrast to the brighter mood of paintings of island scenes - which are in a more African style - or of jazz musicians (such as Soul of a City or The Musician). According to the artist, this is being realistic. If he wants to paint life, he must show the different and contrasting emotions a human being experiences. 'You get up in the morning and you are feeling a little bit happy. You come home in the evening and you are feeling a little bit down. So emotions are continuously changing. If I said that I was always happy, that wouldn't be true.' </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As mentioned above, a number of Ainsley Yearwood's pieces portray jazz players. He enjoys going to New Orleans to listen to jazz bands and in Soul of a City he portrays one of the musicians. The title underlaines the importance of performers in a place like New Orleans - where indeed, they form an integral part of city life. In A Musical Love affair, the painter uses techniques learned as a graphic designer to help him express his feelings. By drawing graphic lines, the cello player and the instrument flow into one another. He explains: 'The cello player was not just playing the instrument. She was actually part of it. It is as if she were making love to the cello.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is clear from the foregoing that Mr. Yearwood's art is primarily visual. The onlooker is bombarded with strong colours - which are used, together with abstraction and symbolism, to express both optimistic and pessimistic feelings. The artist uses his multicultural background to great effect, drawing on influences from Trinidad, Africa and Europe, to create different modes of expression. These are the essential factors which make his paintings interesting and refreshing to look at.  c.s. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">CTA-Bulletin</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Fairness on the livestock field of play</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Sarah Reynolds</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the town of Thies one of Senegal's regional capitals, there is an abattoir where nothing goes to waste. Even the horns of cattle are sold for making carvings for sale to tourists while the tips of the horns are exported to Japan. In a rural area of Chad, small-scale livestock farmers are preserving meat by the age-old process of cutting it into strips and drying it in the sun. Careful attention to hygiene and quality control has resulted in a product so consistently good that it has found an export market as far away as Gabon. Livestock producers in sub-Saharan Africa are responding to market opportunities, not because they recognise the need to improve national food requirements, but in pursuit of profit. Therein lies the best chance for stimulating the livestock sector's production capacity. The challenge is to design policies that protect consumers without crushing entrepreneurial potential for producers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More than half the population of sub-Saharan Africa is likely to be living in a town or city within the next 30 years. These city dwellers will have neither the skill, the time nor the space to raise livestock. There are indications on present trends that their demand for food of animal origin will increase. Where will they get it from ? Imported meat is more expensive than it used to be, largely as a result of the change in policies of the European Union. These have also affected the supply of low-cost milk powder and butter oil. Imports from countries outside the continent will  undoubtedly continue but intra-African   trade and local production will become   far more significant.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It has been estimated that the production of animal products in sub-Saharan Africa would have to increase by 4% per year to ensure an adequate supply of animal protein for the region's growing population, and to end the need for imports. This presents a major challenge to policy-makers. Already, the current pressure on land resources is causing conflict in some areas and the prospect of more people, more animals, and more strain on already inadequate resources, is perturbing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Information vacuum  in developing countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The concept of value</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Decisions on how to achieve sustainable and yet more productive land-use, while at the same time ensuring fair access to resources for other interested users, cannot be soundly based if made in an information vacuum. It was in recognition of the lack of information about the livestock sector that the CTA organised and sponsored a seminar on Livestock development policies in the humid and sub-humid zones of sub-Saharan Africa. This was held in Abidjan, Cote d'lvoire on 5-9 February 1996. It was attended by participants from 17 countries within the region and by representatives from international institutions and from Europe. The objective was to contribute to the ongoing debate on policies aimed at bringing about sustainable livestock development while respecting natural resources in developing countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The concept of value</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Effective planning of government action on issues such as import policy, provision of inputs and services, marketing and research priorities requires quantitative information on livestock production systems. Why is this information lacking when it is estimated that livestock products contribute about 25% of total agricultural GDP in subSaharan Africa? The livestock sector is too important to ignore and yet it is consistently undervalued. The reason is that economists and statisticians like to deal with a tangible unit that can be counted. Ideally, this should be a monetary unit but, failing that, it should at least be a unit that can be easily converted to money, such as the number of animals potentially available to the market. But if animals are used to sustain a traditional way of life, for people who do not have to pay before they can eat, it is difficult to put a monetary value on the food they consume. Similarly, if a herd of animals is sustained by forage that has no other use, on land that can be used for no other purpose, the cost of feeding cannot easily be measured in financial terms. Indeed producers have little to gain from allowing government   departments to acquire information about their assets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Livestock owners have their own objectives when deciding whether and how to increase production. Livestock provide energy in the form of draught power, and dung for fuel or biogas. Their manure restores structure and fertility to the soil. Social prestige may be measured in the quantity and quality of the animals one possesses. For some livestock owners, their animals are their 'barking' system. They represent a deposit account for accumulated wealth and a current account when an animal is sold to raise cash. Indeed it may be impossible to obtain credit from an orthodox bank. There is an added advantage in that there are no interest charges to pay when you raise cash by selling your own animals as opposed to taking out a loan from a bank. It may be difficult to measure real production when animals are treated as a capital reserve. For example, an increase in meat prices, perhaps as a response to a change in economic policy, may result in a short-term reduction rather than increase, in the number of animals being marketed. This is because producers are able to maintain their income by selling fewer animals and can simultaneously  increase their breeding herds. Alternatively, there may be little incentive to producers to sell more animals if they have no use for the extra money they earn. It is of course true that more people are joining the cash economy as they become aware of the desirability of consumer goods, or of services such as schooling. Governments may aspire to design policies which will develop the livestock sector for the economic welfare of society as a whole, but if these policies ignore the objectives of livestock owners, they will fail.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fair play</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In a football match, the referee is there to see fair play. In the livestock sector, governments have to ensure fair play between the 'demand team' and the 'supply team', in other words the -consumers and the producers. Governments often make two mistakes. Either they help one team at the expense of the other, or else they join in the game themselves. The role of the authorities should be to make the rules that protect both teams from unfair or unsafe practices. For example, health and hygiene regulations must be in place, and  enforced, but not be so onerous that illegal and totally unregulated marketing channels are established.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Private traders have considerable power to manipulate markets if they collude to form cartels and prevent outsiders from entering their ring. Governments should ensure that this is not allowed to happen, that markets are open and that traders are free to operate provided that they observe health and hygiene regulations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Veterinary services</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most countries are no longer able to supply even minimum standards of veterinary support to their livestock producers. The efforts that have been made in recent years have been largely in the form of donor-funded projects where continuity is rarely guaranteed. The only viable alternative seems to be to transfer activities of this kind to service providers in the private sector. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The work that they do under contract to the government, for example relating to the control of epidemic diseases, must be funded by government or other central agencies since cost-recovery from individual livestock owners is not feasible when participation has to be compulsory. The work that they do on behalf of individuals, or associations of livestock owners, should, however, be paid for by those who benefit directly from the increased productivity that should result - the farmers. The greatest difficulty lies in managing what will be a long and difficult transition period. The success of ventures to privatise veterinary services depends on whether the profession can deliver a decent living in the private sector, particularly in rural areas where the need is undoubtedly greatest.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rural development</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is in the rural areas that livestock production needs to be intensified. On the outskirts of Africa's major cities, intensive pig and poultry production is already being supported by commercial, joint venture capital. Dairy units, in which exotic, high performance cattle breeds are managed in a controlled environment, are producing fresh milk for cash-paying consumers in nearby towns and cities. Urban areas create the demand but it is the rural areas that need the development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Animal products are seasonal and prices fluctuate accordingly. However, consumers are more likely to develop the habit of using products that are consistently available at stable prices. Government intervention to stabilise  prices risks favouring the consumer at the expense of the producer. For example, if imports are used to counter temporarily high prices during periods of drought, then producers will receive less for their reduced output at the very time when they need support. The most effective policy of price stabilization is to encourage the adoption of production systems that are less vulnerable to seasonal changes. Processing achieves this to some degree and brings benefits to both producers and consumers. Furthermore, because animal products are perishable, and dangerous to human health when they deteriorate, processing extends storage life, and may even have an effect in improving food security.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In most countries, the time of greatest food shortage is at the beginning of the rainy season. This is also the time when milk production soars because cattle have good feed; and yet much of that milk is wasted because there is more than required for home consumption. If that surplus milk can be fumed into cheese, potential customers in more distant markets may be reached. Provided that the product is acceptable to the consumer, cheese-making reduces wastage, diversifies the producer's source of income and may also provide employment, and therefore income, to those brought in to help with the production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A technology that has been exhaustively tested by FAO for its suitability for use in Africa is lactoperoxydase. This is an enzyme which extends by three hours the length of time before milk begins to curdle and clot. This effectively doubles the time available for milk to reach the cooling centre, and thereby extends the catchment areas for producers wishing to supply fresh milk to urban markets. The trials that have been conducted show that it is entirely safe. When milk is brought to rural collecting points, it is the responsibility of the cooling centre employee, not the farmer, to add the enzyme at the prescribed rate as the milk is transferred into cans.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On current trends, it seems probable that there will be more than 20 capital cities in Africa that have a population of 10 million people by the year 2010. How many other cities and towns will have developed by that time ? There are so many people migrating to the urban areas, and they are doing so because the type of activities that ought to be taking place in the countryside do not exist. If the livestock industry, both primary production and processing, can be encouraged in rural areas, and if the infrastructure is in place to ensure that animal products, in whatever form, can reach urban markets, rural dwellers will find it more comfortable to stay where they are rather than going to the cities to look for jobs that do not exist.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The challenge for policy-makers is to deal even-handedly, not only in the interests of the livestock sector, but in the interests of other farmers, consumers, the national economy and the long-term sustainability of the nation's natural resources. For this task, reliable information, which is accessible to all countries within the region, is essential. The database structure of this information should be standardised so that it can form the basis of regional cooperation on trade and the sustainable use of land resources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">S.R. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The Couriers Mailbag</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WCL seeks a wider  expression views</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We refer to the article published by The Courier in issue no 156 (March-April 1996) entitled The changing face of trade unionism in Africa, which reflects the views of the ICFTU (AFRO) and OATUU.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We are surprised that you have not taken pains to solicit the views of the World Confederation of Labour (WCL) and its regional organisation, the Democratic Organisation of African Workers Trade Unions (DOAWTU) - which participated on the same footing as the two other trade union organisations at the ACP-KU Social Partners meeting in December last year. We strongly believe this omission on your part should be corrected in future in order to allow a wider expression of the views and stands of all representative trade unions in Africa on such important issues as structural adjustment programmes, the social clause, labour standards and working conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Carlos L. Custer, Secretary-General, World Confederation of Labour, Brussels, Belgium</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Linked destinies</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The continuing dialogue between the ACP and EC Groups has exposed many mutual concerns about world affairs and has promoted a more complete understanding of the problems of both advanced and developing  nations. I am confident that in the future, we shall see further progress in our efforts to create a favourable financial climate for the resolution of our economic problems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Global political and economic events have brought home to all of us how inextricably our social and economic destinies are linked. This is true of a whole range of subjects from human rights and political reform to economic development, conservation, health education and industrial promotion. None of these subjects can be put into independent boxes. We must seek more effective integration of our social and economic policies - both internally and internationally - if we are to serve the welfare of the people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I rejoice in your initiative in publishing The Courier. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Teddyiniovo, International institute for Global Cooperation, Benin City, Nigeria</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Scope for energy selfsufficiency</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">May I congratulate you on the new layout of The Courier, which is a great deal clearer and which you have instituted as a result of comments made by a number of your readers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I am surprised to discover that you have not said anything about the question of energy dependence in the Lom&eacute; Convention countries. Energy self sufficiency is an extremely important issue. ACP countries face a famine in this area which is rarely mentioned. Most are majors exporters of petroleum, which is  costly and absorbs a significant proportion of their foreign exchange earnings.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Practically all the Lom&eacute; countries are in a position to produce alcohol from crops such as sugar cane and manioc without any negative impact on their food resources. These crops could be distilled to produce big-ethanol which is an excellent fuel. All that is needed - and it is a major challenge admittedly - is for production to be organised in each country, and for the required national and international financing to be set up.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Also required is the political will in these countries to overcome the various obstacles, including those lobbies who oppose this kind of production because they want petrol imports to be maintained.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pierre Mariotte Consultant, Paris, France </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Bibliography</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jean Monnet - 1888-1979  </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Eric Roussel. Published by Fayard, Paris. 1996. 1004 pages. FFR 198.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jean Monnet was almost 91 years old when he died and, despite the fact that he had no higher education qualifications and at times did not hold any official post, his public role was legendary. From the very first page of his book, Eric Roussel stresses the fact that, from the moment Jean Monnet met the Prime Minister, Rene Viviani, in September 1914 until 9 May 1975, the day the Action Committee for a United States of Europe was dissolved, he worked constantly for the European cause.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He applied the same tireless enthusiasm to all his duties, in whatever sphere of activity he was involved - and these were many and varied. Despite his provincial origins, Jean Monnet was, among other things, a cognac merchant, an advocate of the Allied coordination effort during the First World War, Deputy Secretary General of the League of Nations (for a short time), a banker in America and China during the 1930s and in charge of the Victory Program in the USA in 1941. From 1947 to 1952, he was the first Commissioner-General of the Economic Plan in France. He and Robert Schuman were the architects of the famous Declaration of 9 May 1950 which was to form the basis of European construction. He went on to become the first President of the ECSC's High Authority and, until 1975, he was the driving force behind the Action Committee for a United States of Europe. And that is just to highlight his renowned roles.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition, Jean Monnet was both a visionary and a pragmatist, who was to become adviser to some of the greatest names of his day. General de Gaulle, another great visionary, albeit with a very different ideology, called him 'the inspiration' behind European integration, although such an accolade was not completely devoid of irony given that the two men could hardly be said to see eye to eye.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jean Monnet was a purveyor of new ideas, but also an eternal realist who never failed to recognise the importance of the status quo. Indeed, he could have stepped right out of the pages of a Paul Morand novel. And yet, despite the fact that he was held in the highest esteem by world political heavyweights (Clemenceau, Roosevelt, Churchill, Adenauer, de Gasperi, Brandt, Pompidou, John Kennedy, Henry Kissinger, Heath and Giscard d'Estaing, to name but a few), in his private life he was a simple man, of modest disposition - in fact a bourgeois in the best sense of the word.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A 'workaholic', like many great men, Jean Monnet defied categorization. He has recently been described as 'a man of fringe ideologies who was nevertheless always at the centre of things'. During the latter part of his life, he settled comfortably into his role as 'rather' of Europe. His fundamental thoughts on that topic could be summed up in one line from the Declaration of 9 May 1950, (now a public holiday in the European institutions). 'Europe will not be built in a day, nor as a single structure, but will come about through concrete actions which, first and foremost, create a de facto solidarity'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For Monnet, nationalism meant only war and, from 1942 onwards, he set his sights on preparing for the future, surrounding himself with a team of extraordinary talent - people such as Etienne Hirsch, Herve Alphand, Rene Mayer and Robert Marjolin. These men strove to find ways to avoid war between the countries of Western Europe, to define the objectives of European unification and to establish European institutions which would be equal to such a task.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Eric Roussel is a journalist with an arts degree and a doctorate in law, and this is an outstanding work on the 'pragmatic visionary' that was Jean</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Monnet. The book is comprehensive, extremely well-written and impressively documented. Most notably, the author had access, for the first time, to the famous journal kept by Jean Monnet in which he recorded his countlles conversations with the key players and set out his own thoughts. Today, his dream of 'a united Europe complemented by a partnership with the United States' is still one of the big issues. And as the arguments rage, we should perhaps recall some other famous words from Jean Monnet's Memoires: 'We do not seek to form a coalition of States, we seek to unite men . </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Alain Lacroix </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Le Choix de l'Europe</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(Opting for Europe)  by Laurent Cohen-Tanugi. Pub/ished by Fayard, Paris. 225 pages. FFR 110 - BFR 748.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'Laurent Cohen-Tanugi successfully reminds us of the modernity of the European project; that there are aspects of it that are essential to our independence and our prosperity, to preserving our model of society and maintaining our influence on the international stage. By urging Europeans and European leaders to look to the future so as to be better able to manage the risks and seize the opportunities that it offers and, ultimately, to be in a better position to change things, he brings us all hope'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This was how Jacques Delors described this book, and, basically, there you have it in a nutshell. It would, however, be worthwhile adding that 'opting for Europe' is not quite as simple as it sounds - a fact which has not escaped the attention of the author, who is a graduate of France's elite Ecole normale superieure and of the Harvard Law School. He is also a barrister and member of a renowned firm of international lawyers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Since the Treaty of Rome, European progress has very often come about because Member States have set themselves deadlines for achieving particular objectives. 1996 sees the opening of the Intergovernmental Conference, an event of major importance, which is expected to continue at least until the spring of 1997 (with parliamentary elections planned in several Member States in 1997 and 1998). Among the items on the agenda for the IGC is the need to adapt the European institutions - which in essence have hardly changed since 1958 - and to open up the way for the third phase of Economic and Monetary Union in 1999 for those States which have fulfilled the economic convergence criteria set out in the Maastricht Treaty.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, besides the technical and financial problems involved, there are also differences between certain Member States about the political future of Europe. The author rightly stresses, in this respect, that the situation has become even more complex since the demise of the Soviet Union. In particular, some politicians support an expansion of the EU towards Central and Eastern Europe, so as to avoid strengthening European integration. The author believes that, broadly speaking, there are two distinct positions. On the one hand, there is the United Kingdom, which would be happy with a large free trade area guided by a 'Secretariat-Commission'and with flexible and relatively loose inter-State cooperation structures at a political level. On the other hand, there is Germany, which wants expansion of the Union towards the East as well, but also wants a swift and concrete consolidation of a common monetary and political 'hard core'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In his book, the author expresses his view that France will play a vital role in maintaining and advancing the essential elements that form the basis of the European enterprise. And he nails his own colours firmly to the mast as someone who hopes to see the continent moving towards some form of federal structure. As one observer commenting   on the work has noted, 'This little Bible, brimming with faith in the concept of a unified Europe, will be invaluable - even to the doubting Thomases among us'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Publications received</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Et.... qu'en pensent les villageois? Projets de developpement durable et be veins de base b&eacute;n&eacute;ficiaires</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(But... what do the villagers think about it ? Sustainable development projects and basic needs of aid recipients)  by Myriam Bacquelaine. Published by Ured (Research, Education and Development Unit) of the K.U. Brussels (17, avenue de la Liberte, B- 1080 Brussels). 1995. 3Z2 pages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Les problemes du monde rural vus par les habitants - Portraits de villages de Haute-Guinee</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(me problems of rural life as seen by the inhabitants - Profiles of villages in Upper Guinea)  by Myriam Bacquelaine. Published by Ured (Research, Education and Development Unit) of the KU. Brussels (17, avenue de la Liberte, B- 1080 Brussels). 1995. 222 pages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The author, who has a PhD in educational sciences and is a researcher at Ured, has written these two works on the basis of a study she carried out on behalf of the European Commission in Guinea (Conakr,v). This aimed at identifying the most urgent priorities of village communities within the context of an environment restoration project.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The conclusion of the first book underlines research results which point to the adoption of a different approach to development at local level: one which respects the wishes of the recipients and which finally breaks free from western ethnocentrism.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the second volume, the author presents the results of the survey conducted in the villages of Upper Guinea. Six villages with varying characteristics in terms of size, geographical location and administrative status are featured in more detail. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Informations pour le Developpement: Agriculture</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(Information on development: Agriculture)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Published by Ibiscus (ibis, rue du Havre, F-75008 Paris) and by the Agency for Cultural and Technical Cooperation. 1995. 271 pages. FFR 150.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More than just an index, this publication is a useful working tool for anyone seeking reliable information about development in the agricultural sector. It includes a list of the main organisations specialising in agriculture in 40 French-speaking countries and a list of the principal places and means from which to obtain information (documentation centres, data banks, optical discs, CDs and on-line data services). There is also a selection of periodicals, a bibliographic section (with more than 300 references, including abstracts) and contributions by specialists relating to major topics connected with rural development: landownership systems, links between cash crops and food crops, agricultural funding, etc.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rwanda - Trois jour qui ont fait basculer l'histoire</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(Rwanda - Three days that shook history)  by Filip Reyntjens. Published by L'Harmattan (5-7, rue de l'Ecole-Polytechnique, F75005 Paris). Cahiers africains no. /6! 1995. 148 pages FFR 9O. ISBN 2-738437044.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although much has been written about the tragic events in Rwanda, this work examines an aspect of the story which is still largely a mystery: the brief period which began on 6 April with the missile attack on the presidential jet and ended on 9 April, when the 'caretaker government' was swam into office. According to the author, these 72 hours were of critical importance since it was during  this time that the country's killing machine was set in motion.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Essentially based on eye-witnffs accounts, it is a tale which is far from complete. The book, however, does provide some hitherto undocumented information which allow us to delve deeper in search of the truth behind one of the darkest pages of recent human history.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Les refugies rwandais a Bukavu au Zaire - De nouveaux Palestiniens?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(The Rwandan refugees in Bukavu, Zaire - the new Palestinians ?)  by Philippe de Dorlodot Published by L'Harmattan (5-7, rue de l'Ecole-Polytechnique, F-75005 Paris) and by the Jeremie Group. 1995. 253 pages. FM 150. ISBN 2-7384-3698-6.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The author has brought together various stories, appeals, communiques, analyses and thoughts to write this book about the crisis facing the Rwandan refugees. The accounts cover the period from April 1994 to October 1995 and relate to the situation in South Kivu, Zaire, where an already volatile position has been greatly exacerbated by the arrival of the refugees. The people living in the regional centres of Goma and Bukavu are having to live with the tragedy of gross overcrowding and all its consequences - environmental deterioration, price increases, general insecurity and the threat of war on the border between Rwanda and Burundi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zaire now wants the refugees to leave as quickly as possible, but their return to Rwanda is still problematic. Rejected at every turn, are these Rwandan refugees set to become the new Palestinians? In the postscript to the work, Filip Reyntjens (the author of the book reviewed previously) states that 'These new refugees will not accept eternal exile. H voluntary repatriation is not possible, and if forced repatriation is unacceptable, the only way left open to them may be armed repatriation... The civil society of South Kivu... is well aware of this, and the international community would do well to listen to their cries of alarm... If  it does not, the tragic events of the past year will have been merely a prelude, with the worst still to come'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">La tragedie rwandaise - Historique et Perspectives</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(The Rwandan tragedy - historical background and future prospects)  by Emmanuel Nkunzumwami. Published by L'Harmaffan (5-7, rue de l'Ecole Polytechnique, F-75005 Paris). 1995. 480 pages. FFR 250. ISBN 2-7384-3697-8.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The author, a teiecommunications engineer and economist, was born and raised in Rwanda. He now lives in France and has had several articles about the situation in his country published. In this work, he seeks to Reconstruct the machine of central Rwandan power which first appeared in the eleventh century, seeking answers to questions such as: Who ruled the country and how? What alliances were forged and according to what criteria? What kinds of social structure existed and what forms did conflict take? He then goes on to describe the trauma of colonial rule which 'deliberately' fanned the flames of socio-ethnic conflict so that the people could be more easily controlled. From there, he takes us through the era of an 'independent' Rwanda under a dictatorial regime. Its power was progressively stripped away, initially under the pressure of internal calls for democracy, and then by the demands of Western aid donors. Finally, he recounts the events since April 1994.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Having given the historical background, the author examines the country's future prospects. He believes that the 'siege mentality' of the new government does nothing to induce the return of the 2 million refugees who shuffle back and forth across the border and who find themselves stuck between a 'rock and a hard place'. Finally, the author poses a straightforward question - but one which has yet to be answered: How can we rebuild a country that has witnessed genocide on such a scale ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">News round-up</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In brief</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UNCTAD Report on the least-developed countries (LDCs)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">According to the annual report of UNCTAD (The UN Conference on Trade and Development), the 48 least developed countries of the planet, after several years of stagnation - and indeed, decline in some cases - enjoyed an average growth rate of 3% in Gross Domestic Product (GDP) in 1994-95. The figure was 4.6% for LDCs in Asia and 2.2% for those in Africa (33 out 48).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UNCTAD says that the renewed grovvth rate for Africa's least developed nations is due to an increase in commodity prices, to improved political and social stability in certain countries and to economic reforms which have been implemented. If these favourable conditions are maintained, further modest progress can be anticipated for 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite the positive impact of these factors on the development of countries, notably in Asia, UNCTAD believes that there is still a short-term danger that the world's weakest economies will suffer further marginalisation. It is pointed out, in this context, that the LDCs' share of total world trade - which stood at 1.7% in 1970 - had fallen to 0.4% for exports and 0.7% for imports, by 1994.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the longer term it is thought that the LDCs, with their reliance on basic commodities for export receipts, may benefit from the globalization of their economies. This should happen notably through the regional trade agreements to which they are parties, alongside other developing countries. These regional markets, which are more attractive for investors, offer an opportunity for LDCs to try out their products and can, in time, help improve their competitiveness. In the  meantime, however, UNCTAD has noted that the immediate effects of the Uruguay Round have tended to be more negative, with reductions in the preferences enjoyed by LDCs in export markets and increases in the price of foodstuffs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition, because they are dependent on official development aid (ODA) to finance investment, and even for their national budgets, LDCs are faced with possible further marginalisation as such aid flows are reduced. The figures show that, in terms of total resource flows, the amount of ODA provided by the Development Assistance Committee (DAC) of the OECD fell to 23% in 1994 from a figure of 27% a decade previously.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Likewise, the amount of aid, expressed as a proportion of the GDP of the donor countries, has been falling.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UNCTAD suggests a bolder policy as regards external debt - which, in 1994, amounted to 73% of the entire Gross Domestic Product of the LDCs. The organisation believes that the establishment of a new mechanism with sufficient resources to reduce multilateral indebtedness, combined with the expansion of existing mechanisms, could have the effect of reducing the overall debt burden to a more reasonable level.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the subject of globalisation, UNCTAD argues that the international community should work to ensure that the LDCs' export markets do not become blocked by protectionist measures. It also believes that extensions to regional trade agreements, taking in the main industrialised countries, should not be allowed to have a damaging effect on the commercial interests of the LDCs. It points out that these countries have only limited scope for pursuing independent, national economic policies and that</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">No agreement over banning landmines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Humanitarian organisations have expressed disappointment over the outcome of a recent United Nations conference, convened in Geneva to draw up a convention on 'Inhumane weapons). Both NGOs, and public agencies such as UNICEF, are particularly unhappy that state representatives at the meeting were unable to agree to an immediate and comprehensive ban on anti-personnel mines. These devices, which often lie hidden in the soil for many years, kill and maim thousands of civilians in current (and former) conflict areas across the globe</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Diplomats attending the Geneva conference were keen to emphasise what had been achieved. So-called 'dumb' mines, which do not self-destruct after a certain time will eventually be phased out.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Seif-destructing devices, which are still permitted under international law, will be subject to strict new standards, designed notably to ensure that they can be detected. And there will be new rules to ensure that minefieids are properly marked.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Critics point out that signatories to the Convention will not be obliged to phase out 'dumb' mines immediately and that their use will remain legal for a further nine years after the agreement enters into force.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is also an exception to the rule about marking the location of mines, 'where direct military action makes its impossible to comply' - a not uncommon circumstance in conflict situations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Since the Geneva Conference, a number of countries, including the United States, have announced their intention to reduce their stockpiles of mines. Few nations, however, seem willing to renounce their use altogether. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">S.H.  their governments have little choice but to adopt the prevailing market oriented approach.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Long-term food security</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A seminar on 'Long-Term Food Security Policies' was held in Brussels on 1-3 April at the initiative of the European Commission. The meeting, which was opened by Professor Pinheiro, Commissioner with responsibility for relations with the ACP countries, brought together about a hundred participants representing Member States, third countries, international organisations and major cooperation agencies. It was also attended by experts and researchers in the field of food security.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fulfilling a promise made by the Commission, the aim of the seminar was to clarify the long term strategic issues and take a closer look at food security policies with a view to preparing a European position for the World Food Summit scheduled for Rome in November under the auspices of the UN Food and Agriculture Organisation (FAO).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Community and its Member States are the world's main donors of food aid having spent ECU 1.089 billion on this in 1994. This amounted to 53% of the global total with the United States providing 44% and Japan 3%. Despite the large amounts being given, the FAO, the International Food Policy Research Institute (IFPRI) and the World Bank are all predicting that unless global food donations are boosted significantly, certain Asian and African countries will face an alarming food deficit by the beginning of the next century.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Between 600 million and 800 million people are likely to be facing hunger by the year 2010 and the cereal needs  of the developing countries could well double between now and then.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This projected scenario coincides with a period of market difficulty. World stocks are low and grain prices have risen by 40% in just one year. Whether or not this is a portent of future food shortage, it has given rise to renewed debate on the ability of certain countries and regions of the world to supply themselves and the extent to which they will have to have recourse to the international markets. Closer attention is also being paid to the wider strategies that need to be implemented to ensure food security in the future.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If one looks at the issue solely in terms of increasing supply, the projections are gloomy. Experience shows that the 'right' of access to a sufficient food supply for each of the planet's inhabitants cannot be guaranteed whether through world economic growth, food self-sufficiency at the national level, or the international markets and trade liberalisation. There is, therefore, a need for food security policies, in the developing countries in particular, which act on the conditions of demand as well as supply.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In his presentation opening the seminar, Commissioner Pinheiro stressed the fact that of the ECU 7 billion allocated by the EU for development cooperation last year, ECU 1 billion was in the form of food aid. He also noted that this aid 'category' had evolved over the last decade in the context of the search for food security and explained how the Commission, in revising the policy towards the end of 1994, had set out three essential aspects:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - the use of food aid as a policy instrument designed to achieve longterm food security with the emphasis on local purchases and 'triangular' operations - thereby encouraging the growth of the agricultural sector in the developing countries: this entailed developing a new aid instrument in which funds are available to import basic food products (as a way of encouraging the private sector to  take a more active part in the economic life of those countries facing a structural food deficit);</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - the integration of aid instruments into the actual development efforts of the beneficiary countries;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - improved access for the people who suffer most from food shortages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Professor Pinheiro indicated that the Commission would shortly be presenting a communication on the strengthening of the link between development aid on the one hand and emergency, rehabilitation and food aid on the other.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He stressed the important role that food aid operations could play in preventing conflicts and easing social tensions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">According to the Commissioner, the challenge in this area have been clearly identified but he believes that additional thinking is needed, notably on the impact of events in China and the countries of the former Soviet Union, and on the effect of US and EC agricultural policies on the world markets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In conclusion, Professor Pinheiro expressed the view that food security was, above all, a national responsibility with all civil society actors having a role to play.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Citing the rise in the price of cereals during the second half of 1995 - which had prompted concerns about the availability of food aid and its impact on the balance of payments (notably in sub-Saharan Africa and the Indian sub-continent) - he gave an assurance that the Commission would remain vigilant about this. At the same time, he was concerned not to see a return to situations where aid in the form of straightforward transfers of food increased. These, he observed,</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· had at least partly contributed to food costs, the destabilisation of local production and constraints on intra-regional trade. As such, they had set   back or undermined the reforms in this sector in the countries concerned.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Caribbean rice exporters fear changes in OCT . rules</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guyana and Suriname, together with a number of Overseas Countries and Territories (OCTs), have expressed concern over the European Commission's recently announced intention to change the shape of its relations with the OCTs. In particular, they are worried that proposed new rules could harm their rice sales to the 15 European Union nations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guyana currently exports 180 000 tonnes of rice (80% of its exports) to the KU. This is shipped initially to the Netherlands Antilles (Cura&ccedil;ao, Aruba and Bonaire) to be partially milled. It then enters the EU market duty-free by virtue of the Union's existing trade rules with the OCTs. But Caribbean exporters fear that this 'OCT route' could soon be blocked by changes currently being considered in Brussels.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As already announced in issue no 157 of The Courier (May-June 1996), in the context of the mid-term review of the association with the OCTs, the Commission published a text on February 14 proposing some fine tuning to the trade preferences it grants to these territories. This has now gone forward to the Council of Ministers for decision. The Commission proposal is that while agricultural produce may continue being processed in the OCTs - and hence still benefit from the more relaxed rules - this should happen in future on a case-by-case basis, and only if priority is given to the least developed OCTs and the operations are economically justified.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In fact, preferential arrangements do apply to direct rice exports from Guyana and Suriname to the KU, but it is argued that the levies are still too high to make the trade viable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">According to Yesu Persaud, who is Chairman of Guyana's Institute of Private Enterprise; 'it is only via the OCTs that we can export to the European Union.' Mr Persaud was speaking to journalists during a lobby visit to Brussels on April 16. He was accompanied by Charles P Kennard, Chairman of the Guyana Rice Development Board and David Jessop, director of the London-based Caribbean Council for Europe.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Justifying the need for derange, some EU officials point to evidence that non-tome developing countries are 'abusing' the OCT rice route. Rice is a sensitive product for some EU nations such as Spain and Italy, who grow their own.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mr Persaud said that Guyana and Suriname were lobbying either for their own duty-free quota under the Lom&eacute; trade rules, or for 'a more reasonable levy'. At the same time, however, he indicated that the Caribbean rice growers were keen on keeping the route open via the Dutch and other OCTs (such as Montserrat and the Turks and Caicos) where major investments have been made on the  strength of the existing arrangements. A representative of the Turks and Caicos told reporters that his country earned half a million dollars a year from the trade, and that a new jetty had been built with British government support.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guyana's rice exports have climbed from less than 39 000 tonnes in 1986 to more than 200 000 tonnes in 1995. And as Mr Persaud also stressed, the trade has done so well that Guyana is now investing in high-yielding varieties. </P>
+<P ALIGN="JUSTIFY">D.P.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fight against locusts</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fipronil, a recently developed pesticide, is said to be 10 times more effective than other products on the market in the control of locusts, according to representatives of the pharmaceutical giant, Rhone-Poulenc who organised a seminar on locust control </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Links between emergency, rehabilitation and development aid </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European commission has recently approved a communication </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> (COM(96) 153) which was due to be presented to the Development Council on 28 May. The document seeks to respond tO the challenge of I maintaining and improving the effectiveness of emergency aid  rehabilitation assistance and development cooperation with third countries - in the face of a wide variety of political, economic and social circumstances.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Communication suggests ways of strengthening the links between the three types of aid within a strategic planning framework which includes intensified dialogue and political cooperation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This initiative follows extensive consultations, both within the Commission (i_ service groups) and with representatives of numerous outside bodies (Member State experts, USAID, UN agencies, NGOs, academic institutions etc.). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While the key phrase in the Communication may be 'strategy and global planning', emphasis is also placed on 'coordination' end 'opportunity'. This underlines a commitment to adapting procedures, where necessary, so that measures can be taken at the right time and the transition from emergency aid, to rehabilitation and subsequently to development cooperation can take place in the best possible conditions.  with the 70-member African, Caribbean and Pacific group. The event took place in Brussels in April.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The new product, claims the company, fills a big gap that was left in the war against locust infestation when DDT was banned in 1986 (toxic residues from the chemical having been found to enter the food chain and damage the ecosystem).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is stated that Fipronil causes 99% mortality among locusts and gives complete protection for up to three weeks when applied in doses of six grammes per hectare.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Its developers claim that it is three times cheaper than any other form of anti-locust pesticide used between 1987-1995, a calculation which includes the logistical costs involved in distributing the pesticide. It is said to be very effective in preventing locust infestations in countries in the Sahel that are particularly at risk.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Sahel has some 250 acridian species. Of these, about 15, are known regularly to attack crops in large numbers, according to Michel Launois, who heads the French agricultural research body, CIRAD-GERDAT-PRIFAS.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the Brussels seminar, emphasis was placed on the need for donors to set aside more funds for the prevention of locust infestations. It was also stressed that locust control must be at a regional level because of the migratory nature of the species, and the link between locust control and food security was underlined.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CIRAD-GERDAT-PRIFAS has just published an educational cartoon strip entitled 'Les Dents du Ciel 11' (available from Cirad-Gerdat-Prifas, B.P. 5035, F34032 Montpellier Cedex 1). This is intended to explain to a wide audience the need for an integrated approach to locust control.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I New fishing agreement between Angola and the EU</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A new fisheries agreement between Angola and the EU was initialled on 2 May. It is due to run for three years (as opposed to two years for the previous one) and should ensure greater stability and better programming of the Community fleet's fishing activities in Angolan waters. The EU will pay Angola the sum of ECU 13.35 million per annum in exchange for improved fishing rights for European fishermen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is worth noting that the agreement contains certain innovations. These concern, for example, the legal status of catches (which are given Community origin). This should help to avoid the kind of dispute that has arisen in the recent past. There is also the possibility of imposing an annual biological 'rest-period' for shrimp fishing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I African conference on consumer protection</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first African conference on consumer protection was held in Harare, Zimbabwe from 28 April to 2 May. This resulted from a joint initiative by the organization Consumers international and the United Nations, and it was supported financially by the European Commission. The latter was represented at the event by Mrs Emma Bonino, the Commissioner responsible for Consumer Policy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The aim of the conference was to lay down the basis for a genuine consumer policy in Africa. Representatives of 45 African governments attended, together with officials from various regional and sub-regional organizations and delegates from a large number of</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">African consumer bodies. Coinciding with the tenth anniversary of the adoption by the UN of the guiding principles for the protection of consumers, the Conference offered an opportunity to track progress on the application of these principles in African countries. It also saw the adoption of 'model' legislation setting out the essential rights which should be guaranteed to consumers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In her speech, Mrs Bonino stressed the Commission's commitment to supporting the efforts of African governments and consumer organisations in seeking to establish, in a clear and pragmatic way, the link between consumption and development. Evidence of this commitment, she pointed out, was to be seen in her very presence at the conference. She also lent her support to the broad application of the UN's guiding principles in Africa. This would ensure that the health, security and economic rights of African consumers could be protected.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But the European Commissioner stressed that legislation, while important, was not enough in itself to tackle the fundamental problem - which was the satisfaction of basic needs. She appealed for global action in Africa deigned to break the vicious circle of poverty - based on voluntary action at all levels.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mrs Bonino added that the Commission would seek ways of supporting projects, in particular in the fields of food and health. This should assist citizens to meet their essential needs - with the opportunity to consume products which were different, 'local' and of better quality, and with risks to health and security minimised. The approach should avoid the exhaustion of scarce resources and respect nature. She indicated that an action plan would be drawn up by the Commission in collaboration with Consumers International. This, it was hoped, would allow financing of pilot programmes under a separate budget line which would be sought from the European Parliament for 1997. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE INSTITUTIONS</P>
+<P ALIGN="JUSTIFY">AT WORK</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">COMMON FOREIGN</P>
+<P ALIGN="JUSTIFY"> AND SECURITY POLICY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Within the framework of its Common Foreign and Security Policy (CFSP), the European Union has recently issued a number of statements, details of which are set out below:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Towards national reconciliation in Angola</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 4 April 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Troika of the European Union Ambassadors in Luanda made a formal demarche with both the Government of Angola and UNITA in order to welcome the positive outcome of the Libreville Summit between the President of Angola, Jose Eduardo dos Santos, and the President of UNITA, Jonas Savimbi, and in particular their commitment to establish an integrated national army by June and the creation of an appropriate institutional structure, including the formation of a government of unity and national reconciliation by June/July. The Government and UNITA were encouraged to continue to refrain from military activity and hostile propaganda and to provide for free circulation of persons and goods as soon as possible. The EU Ambassadors underlined also the importance of securing human rights as well as transparency in financial management, economic stabilisation and reforms. Having recalled the terms of reference of the EU Joint Position adopted on 2 October, 1995, the Ambassadors underlined that the Union will continue to monitor, with the greatest attention, the development of the situation particularly as regards respect for the implementation of the calendar agreed in Libreville. Welcoming the recent steps taken by UNITA, the EU expressed concern at the slow pace of the quartering and disarming of UNITA troops and urged UNITA to proceed with its commitments, in full cooperation with UNAVEM ill. The EU encouraged the Government to continue the quartering of the rapid intervention police and the disengagement and pulling back of the FAA to the nearest barracks. The importance of disarming the civilian population was also emphasised. The EU also reiterated their call to the Government and UNITA to refrain from acquiring lethal material and to cooperate fully with the de-mining process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU has reiterated its full support to the Special Representative of the UN Secretary-General, Maitre Blondin Beye, to the Joint Commission and to the United Nations Angola Verification Mission (UNAVEM).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cyprus, Estonia, Latvia and Malta align themselves with this declaration.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Free elections in Sierra Leone</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 4 April 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union welcomes the fact that presidential and parliamentary elections took place in Sierra Leone in a free and fair atmosphere and in fulfilment of the established timetable for the return to democracy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The results reflect the will of the people of Sierra Leone to achieve a democratically elected civilian government despite attempts at intimidation by armed elements and the ongoing fighting in various parts of the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU welcomes the peace talks between the Revolutionary United Front (RUF) and the Freetown authorities as well as the intention expressed by President Kabbah to meet Mr Sankoh at the earliest possible opportunity. The EU calls on all the parties to work for peace and national reconciliation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Serious threat to peace process in Liberia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 11 April 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union expresses its deep concern at the outbreak of fighting in Monrovia, which represents a serious threat to the peace process in Liberia. The EU is firmly convinced that the AbuJa agreement provides the right framework for resolving the crisis and calls upon the Council of State, the Liberian national transitional government and the Liberian factions to implement it, and to put the peace process back on track, in order to avoid further deterioration of the situation, and the violation of human rights. The EU condemns the loss of human life and the harassment of the civilian population and humanitarian workers. All parties concerned should prove their willingness to re-establish and maintain the ceasefire which represents the necessary prerequisite to disarmament and demobilization. The relevant measures and the necessary preparations can no longer be delayed. The EU asks the factions to return all weapons seized during the fighting to ECOMOG. The EU will base its attitude to Liberia on the concrete steps taken by all parties concerned to implement the Abuja agreement and bring the conflict to an end.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Treaty of Pelindaba on a nuclear weapon-free zone in Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 12 April 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union welcomes the signature in Cairo on 11 April 1996 of the Pelindaba Treaty establishing the African Nuclear Weapon Free Zone. The Treaty is in line with the Decision on Principles and Objectives for Nuclear Non-Proliferation and Disarmament issued by the 1995 NPT Review and Extension Conference which   recognised that the creation of Nuclear Weapon Free Zones enhances global and regional peace and security.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU considers that Nuclear Weapon Free Zones are welcome complementary instruments to the Treaty on the Non-Proliferation of Nuclear Weapons, the universality of which the EU continues to promote.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Central and Eastern European countries associated with the EU and the associated countries Cyprus and Malta align themselves with this declaration.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appeal for the 'boat people' of Liberia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 14 May 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union expresses its deep concern at the grave humanitarian situation caused by the ongoing fighting in Monrovia and condemns the violence against the civilian population and the harassment of aid operations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While recognising the enormous efforts already made by neighbouring countries to assist the hundreds of thousands of existing Liberian refugees, the Council deplores the fact that the thousands of people crammed in precarious conditions on ships in the area are still in search of a friendly port.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It appeals on humanitarian grounds to the neighbouring countries to give at least temporary shelter to these victims of the fighting and affirms its own willingness to give humanitarian aid to cover their most urgent needs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Council calls on all the Liberian factions to stop the fighting immediately and put the peace process back on track in order to avoid further suffering.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">VISITS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Prime Minister of Rwanda</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Prime Minister of Rwanda, Pierre Celestin Rwigema, visited Brussels from 26 to 29 March in the course of a tour aimed at informing the main donors about the work undertaken by his government in recent months and about the policies which would be implemented in the future. He was accompanied by the Minister of Planning and the Minister for Rehabilitation. The Prime Minister was received by Commissioner Pinheiro, who is responsible for relations with the ACP countries and by Mrs Bonino, the Commission member in charge of humanitarian actions. He also spoke at meetings of the External Relations and Development Committees of the European Parliament. Professor Pinheiro took the opportunity to highlight to the Prime Minister his concerns about the current situation in Rwanda, reiterating the Commission's commitment to the country and its people. He also spoke of the need for the authorities to pursue policies and implement measures leading to the restoration of normality. He said it was essential to have a dialogue with the Rwandan refugees in neighbouring countries (there are now about 1.7 million) and to pursue the pacification process under the auspices of the United Nations and the Organisation of African Unity, with the involvement of all the heads of government in the Great Lakes region. Mr Rwigema's visit came at a crucial time for Rwanda. Even if the immediate crisis had passed, there was still a dire need for rehabilitation and development assistance, on top of the existing emergency aid programmes. The political situation remained delicate and the future was by no means secure, notwithstanding some encouraging signs of a progressive improvement as exemplified by the Tunis summit. The recent nomination of</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Aldo Ajello as the EU's special envoy to the Great Lakes region underlined the political and moral dimension of the EU's commitment to the peace process in this troubled part of Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SUPPORT FOR HUMAN</P>
+<P ALIGN="JUSTIFY">RIGHTS</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Commission has recently decided to provide the following financing for projects under the budget line 'Support for. democratisation and human rights'. Non-ACP countries </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Central America: ECU 180.000 to support seven national and one regional fore aimed at providing training in the field of human rights for instructors. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Central America: ECU 100.000 for a democracy consolidation training programme for 30 teams from various organisations in Nicaragua, Guatemala and El Salvador. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Central America/Colombia: ECU 263.000 for a series of actions, notably in Colombia, involving the provision of information on human and citizens' rights. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Brazil: ECU 190.000 for a project designed to boost the civil rights of black people in the country, through the training of judicial personnel and the strengthening of legislation against race discrimination. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Brazil: ECU 145.000 for a training programme for magistrates, prosecutors and the police aimed at facilitating the uniform application of the law in the State of S&atilde;o Paulo. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Brazil: ECU 290.000 for a training programme in the sphere of democratic municipal management, in the cities of Recife, Porto Alegre, Santos and Fortaleza. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guatemala: ECU 308.000 for a project to collect and make available the case law of the Constitutional Court, and  to train officials and members of civil society.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Honduras: ECU 326.000 to support the National Human Rights Commission with a view to promoting such rights in the Departments of Comayagua and Olancho. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Honduras: ECU 131.000 for an education programme dealing with civic and electoral issues and the rights of children. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mexico: ECU 20.000 to support an initial Latin-American colloquium on the subject of the Ombudsman (in the face of the objectives and challenges of the region). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nicaragua: ECU 285.000 to support the social rehabilitation of minors in custody. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Panama: ECU 125.000 for a training action in the field of the defence of human rights. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Panama: ECU 250.000 to support a communication campaign designed to strengthen the image of the 'people's ombudsman'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Venezuela: ECU 160.000 to strengthen the institution of Justices of the Peace in the country's municipalities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Venezuela: ECU 100.000 ECU for a training and promotion action in the field of human rights and the strengthening of civil society. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">EUROPEAN</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DEVELOPMENT FUND</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Following, where required, favourable opinions from the EDF Committee, the Commission has decided to provide grants and special loans from the 5th, 6th and 7th EDFs to finance the following operations (grants unless otherwise stated). Major projects and programmes are highlighted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economic and social infrastructure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cameroon: ECU 7.3 million for a programme aimed at protecting the urban boundary of the city of Kousseri from the encroachments of the Logone river, to improve sanitation and for the upgrading of an urban access route towards Chad. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ghana: ECU 54 million for a transport infrastructure programme aimed at facilitating the social and economic development of the people living in the recisions in question (Western region, Brong Afaho, the Ashanti region). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ghana: ECU 3.8 million for a human resource development programme designed to achieve better planning, management and implementation of development projects. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kenya: ECU 1.9 million for a project to support the development of tourism. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mozambique: ECU 385 000 to extend the water supply system in the town of Mantola </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chad: ECU 13.5 million to upgrade the Ere-Kelo road </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Trade promotion/ structural adjustment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Benin-Cameroon C&ocirc;te-d'lvoire-GhanaGuinea-Togo: ECU 1.99 million for a regional programme of trade activities and training with a view to relaunching the pineapple business in West and Central Africa. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Burkina Faso: ECU 180 000 for the construction of an 'export and creativity' pavilion at the Salon international de l'artisanat in Ouagadougou. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Papua-New Guinea: ECU 5.3 million for the fourth structural adjustment support programme. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agriculture</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Madagascar: ECU 1.9 million for a rice irrigation project. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Enterpris</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Botswana: ECU 33.7 million from the Sysmin fund, to support the work of the BCL, Tati and FEB mining companies in the SelebiPhikwe region. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Health</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dominican Republic: ECU 1.3 million to support the STD-HIV-AIDS prevention programme. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Education</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Madagascar: ECU 1.9 million for a decentralised training project in favour of regional tourism operators. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tuvalu: ECU 300 000 for the rehabilitation of primary schools on the islands of Nukutetau and Nanumea. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Central Africa (Cameroon-Central African Republic-Congo-GabonEquatorial Guinea): ECU 16 million for phase 2 of the ECOFAC project (Conservation and rational utilisation of forest ecosystems in Central Africa). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Institutional support</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Malawi: ECU 1 million towards a study aimed at allowing the government to implement its land reform policy. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Eritrea: ECU 4.5 million for a study aimed at allowing the government to undertake proper planning in the area of water resources and irrigation. </P>
+<P ALIGN="JUSTIFY">Miscellaneous</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pacific region: ECU 4.9 million for a project designed to improve the efficiency and security at certain airports. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HUMANITARIAN AID</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ACP countries</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mali: ECU 1 million towards the reintegration of some 200 000 Malians who fled to Algeria and Mauritania during the rebellions of the 1980s. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mozambique: ECU 317 000 for victims of the severe floods that struck the centre and south of the country recently. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nigeria: ECU 850 000 to help fight the meningitis epidemic affecting seven provinces of the country. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sierra Leone: ECU 700 000 in urgent food and medical assistance for some 250 000 refugees who fled to the areas around the towns of Bo and Kemena following the fighting. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chad: ECU 200 000 to help fight the meningitis epidemic. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zaire: ECU 145 000 to help victims of the cholera epidemic and to assist in preventing its further spread (following the course of the Zaire river). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Non-ACP countries</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Colombia: ECU 60 000 to help fight cholera in the municipality of Silvia, where some 40 000 are under threat due to a lack of drinking water and deficiencies in basic hygiene. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guatemala: ECU 1.52 million to provide food aid and basic essentials to returnees from other parts of the country, and from Mexico, following years of civil war. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Armenia/Azerbaijan: ECU 11.57 million (ECU 4.07m for Armenia and ECU 7.5m for Azerbaijan), for food and medical assistance, targeted at the most vulnerable sections of the population, and for the provision of agricultural materials with a view to reducing progressively the dependence of the refugees, who are victims of the conflict in Nagomo-Karabakh.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Caucasus-Georgia-Tadilkistan: ECU 3.2 million for food aid to be targeted at the most vulnerable sections of the population. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Georgia: ECU 7.43 million for victims of the internal conflict in this country where the loss of the Russian market has seriously undermined the rural economy. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lebanon: ECU 600 000 for displaced people, to allow for the purchase of basic essentials including food, medicines, shelter and blankets. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Afghanistan: ECU 600 000 for health infrastructures in the refugee camps   around Jalalabad, and for medical aid to refugees in the town of Herat. Indonesia: ECU 120 000 for toots and materials to construct shelters for the victims of the earthquake that struck in February. China (Tibetan nomads): ECU 550 000 for food aid, medicines and blankets for some 72 000 people living in the mountainous regions who have been badly hit by severe weather and a food shortage.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FOOD AID </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p95a.png"></center><br>
+ The Commission has recently taken decisions to finance food aid as set out in the chart which follows: </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Aknowlegments</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Courier</P>
+<P ALIGN="JUSTIFY">Africa - Caribbean - Pacific - European Union</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Address: Postal address (mail only) 'The ACP-KU Courier' Commission of the European Communities 200, rue de la Loi 1049 Brussels Belgium</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Courier office address (visitors) First floor Astrid Building 1, rue de Geneve Evere - Brussels Belgium</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Publisher Steffen Smide commission of the European Communities 200, rue de la Loi 1049 - BRUSSELS (Belgium) Tel. 00-32-2-299 11 11 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Director of Publications</P>
+<P ALIGN="JUSTIFY">Dominique David</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Editor</P>
+<P ALIGN="JUSTIFY">Simon Homer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Assistant editors</P>
+<P ALIGN="JUSTIFY">Augustin Oyowe</P>
+<P ALIGN="JUSTIFY">Jeanne Remade</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Associate assistant  editor</P>
+<P ALIGN="JUSTIFY">Hegel Goutier</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Joumalist:</P>
+<P ALIGN="JUSTIFY">Debra Percival</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Production Manager:</P>
+<P ALIGN="JUSTIFY">Dorothy Morrissey</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Secretariat:</P>
+<P ALIGN="JUSTIFY">Carmela Peters</P>
+<P ALIGN="JUSTIFY">Fax: 299-30~02</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Circulation:</P>
+<P ALIGN="JUSTIFY">Margriet Mahy-van der Werf</P></FONT>
+<!--
+</Section>
+</Section>
+-->
+</BODY>
+</HTML>
Index: /gsdl/stable/collect/demo/import/ec158e/metadata.xml
===================================================================
--- /gsdl/stable/collect/demo/import/ec158e/metadata.xml	(revision 20131)
+++ /gsdl/stable/collect/demo/import/ec158e/metadata.xml	(revision 20131)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE DirectoryMetadata SYSTEM "http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd">
+<DirectoryMetadata>
+    <FileSet>
+        <FileName>.*</FileName>
+        <Description>
+            <Metadata name="dls.Title">The Courier - NÂ°158 - July - August 1996 Dossier Communication and the media - Country report Cape Verde (ec158e)</Metadata>
+            <Metadata mode="accumulate" name="dls.Language">English</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Communication, Information and Documentation|Communication, telecommunication, mass communication, mass media, film-making</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Development Periodicals and Magazines|The Courier ACP 1990 - 1996 Africa-Caribbean-Pacific - European Union</Metadata>
+            <Metadata mode="accumulate" name="dls.Organization">EC Courier</Metadata>
+        </Description>
+    </FileSet>
+</DirectoryMetadata>
Index: /gsdl/stable/collect/demo/import/ec159e/ec159e.htm
===================================================================
--- /gsdl/stable/collect/demo/import/ec159e/ec159e.htm	(revision 20131)
+++ /gsdl/stable/collect/demo/import/ec159e/ec159e.htm	(revision 20131)
@@ -0,0 +1,2869 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META NAME="Generator" CONTENT="Microsoft Word 97">
+<TITLE>&lt;&lt;TOC1&gt;&gt; The Courier - N°159 - Sept- Oct 1996 Dossier Investing in People Country Reports: Mali ; Western Samoa</TITLE>
+</HEAD>
+<BODY>
+
+<B><FONT FACE="Arial" SIZE=2><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">The Courier - N°159 - Sept- Oct 1996 Dossier Investing in People Country Reports: Mali ; Western Samoa</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">AFRICA-CARIBBEAN-PACIFIC - EUROPEAN-UNION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Country report</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mali</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mali, which used to be the centre of great appears hemmed in by its frontiers, colonisation having culminated in the break-up of the old 'French Sudan'. Following the marxist regime of Modibo Keita (the 'founder' of the nation) and the dictatorship of Mousse Traor&eacute;, Mali has discovered democracy. It is still one of the world's poorest countries but recent macro-economic trends are highly encouraging and there is a new dynamism. It seems that the ending of the Tuareg conflict has provoked a surge of optimism- even among ordinary citizens whose wallets have yet to feel the effects of an improving national economy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Country report</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Western Samoa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pacific island nations have a reputation for idyllic scenery and rich cultural traditions. Western Samoa has both of these assets in abundance, but it also faces many development challenges. With a population of just 165 000, the country has a limited local market, and it is a very long way from potential overseas customers. It is also susceptible to destructive tropical storms. Despite these constraints, there have been some promising signs of economic progress in recent years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dossier</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Investing in people</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To say that investing in people makes economic sense is to state the obvious. But to what extent are the implications of this statement fully understood in the developing countries, especially in sub-Saharan Africa, in these days of constantly shifting development theories? We look at this subject in our Dossier. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Acnowledgements</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Courier</P>
+<P ALIGN="JUSTIFY">Africa - Caribbean - Pacific - European Union</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Address: Postal address (mail only) </P>
+<P ALIGN="JUSTIFY">'The ACP-EU Courier' Commission of the European Communities 200, rue de la Loi </P>
+<P ALIGN="JUSTIFY">1049 Brussels </P>
+<P ALIGN="JUSTIFY">Belgium </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Courier office address (visitors) </P>
+<P ALIGN="JUSTIFY">First floor Astrid Building 1, rue de Gen&egrave;ve </P>
+<P ALIGN="JUSTIFY">Evere - Brussels </P>
+<P ALIGN="JUSTIFY">Belgium</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Publisher Steffen Smidt </P>
+<P ALIGN="JUSTIFY">Commission of the European communities </P>
+<P ALIGN="JUSTIFY">200, rue de la Loi </P>
+<P ALIGN="JUSTIFY">1049 - BRUSSELS </P>
+<P ALIGN="JUSTIFY">(Belgium) </P>
+<P ALIGN="JUSTIFY">Tel. 00-32-2-299 11 11 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Director of Publications</P>
+<P ALIGN="JUSTIFY">Dominique David</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Editor</P>
+<P ALIGN="JUSTIFY">Simon Homer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Assistant editors</P>
+<P ALIGN="JUSTIFY">Augustin Oyowe</P>
+<P ALIGN="JUSTIFY">Jeanne Remacle</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Associate assistant editor</P>
+<P ALIGN="JUSTIFY">H&eacute;gel Goutier</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Journalist:</P>
+<P ALIGN="JUSTIFY">Debra Percival</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Production Manager:</P>
+<P ALIGN="JUSTIFY">Dorothy Morrissey</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Secretariat:</P>
+<P ALIGN="JUSTIFY">Carmela Peters</P>
+<P ALIGN="JUSTIFY">Fax: 299-30-02</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Circulation:</P>
+<P ALIGN="JUSTIFY">Margriet Mahy-van der Werf</P>
+<P ALIGN="JUSTIFY">(299-30-12)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cower page:</P>
+<P ALIGN="JUSTIFY">Cover photo by</P>
+<P ALIGN="JUSTIFY">John and Penny Hubley</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Meeting points</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Ieremiah Tabai, Secretary General of the Forum Secretariat</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">South Pacific Forum: 'responding to the needs of the Member States'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although an accountant by training, leremiah Tabai has never had the opportunity to practise his profession, having pursued a successful political career instead since 1974. In 1978, he was annointed head of government in Kiribati and a year later he became his country's first President, when it achieved independence. He held this position for 12 years. In 1991, he took up the top post in one of the South Pacific's key regional bodies, the Forum Secretariat, which is based in Suva, Fiji. During a recent Courier visit to the region, we had the opportunity to interview the Secretary General. Our discussion was wide-ranging, covering issues such as the Forum Secretariat's role, the economic challenges facing the South Pacific, and the development of regional links with Australia, New Zealand and Asia. We began by asking Mr Tabai to outline the objectives of the organisation that he heads.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Like many other organisations in the region, the Forum was established essentially to try and assist the development process of the Member States. At the time it was set up, there was already an organisation in existence - the South Pacific Commission - which dates back to 1947. But there was a feeling that we needed an organisation that was not just restricted to economic issues; that could talk about other matters with a bearing on the development of the region.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the early years, when the organisation was called the South Pacific Bureau for Economic Cooperation (SPEC), the focus was heavily on trying to assist the trade and economic development of the member countries. Later, the name was changed to the Forum Secretariat and its role evolved.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· In what way ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-It has evolved in seeking to respond to the needs of the Member States. It started as a very small bureau essentially dealing, as I said, with trade and economic issues. Subsequently, it moved into areas like energy, civil aviation, maritime questions and telecommunications. It also became more involved in political issues. We have a division which deals specifically with these.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">1995 was a very important year in the history of the Forum. We had a review of the organisation, looking at ways we could perform better and taking account of the changes in the region and the world at large. The fundamental recommendation in the report which came out of that review was that the Secretariat should focus mainly in future on poliy-related issues, in the areas of trade and investment, economics and international relations. This report was discussed and endorsed at the last Forum in Madang, Papua New Guinea. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Does this mean, in practice, a withdrawal from project activity ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-It may. The essential focus of the work will be providing policy advice to countries. Having said this, there should still be some project work. For instance, we will be engaged in a programme to provide assistance for importers, particularly in the small island countries. The idea is to help people- who may not be familiar with all the legal requirements-to learn how to get into the business. This will involve running a workshop and inviting people with expertise to pass on their knowledge. So even though the focus will be on policy issues, there will still be room for project-type activities where needed -so long as these fit in with the policy priorities. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You mentioned the fact that the Forum now deals with political questions. Although the issue may now be seen as 'water under the bridge' to what extent was the Forum Secretariat involved in the diplomatic disagreement over French nuclear testing ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- We were very much involved from the beginning. In 1991, when the French testing was not underground but atmospheric, the region, at a Forum meeting, came out strongly in opposition to the tests. Right up to our last meeting in Madang, the subject was always a major item on the agenda, and we left France in no doubt as to the resolve of our region.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When the new President took the decision to resume testing after a gap of several years, I was in the group from the South Pacific that went to France to express our views to French ministers, face-to-face. Our team was led by the then Australian Foreign Minister, Gareth Evans, who was President of the Forum. And when the tests began again, the Chairman took a decision suspending the dialogue and partner status of France with the Forum. So, as you see, we have been heavily involved in the issue.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What resources does the Forum have at its disposal and where does the money come from ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- An important source of funds is our members' contributions. These tend to be used to cover the operational costs of the organisation. Then of course, there are the funds made available by our donors. The main ones are obviously Australia and New Zealand but there are many other countries and international organisations who provide assistance. The EU, of course, is an important partner. There was also a private donor who funded our conference centre.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· How many people are employed in the Secretariat ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Around 80, all based here in Suva. Most of these are support staff.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What is the current state of relations between the Forum Secretariat and the main donors ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-I would say our relations are good. We have an extensive mechanism for consultation with the donors. Every two years, we invite them here for a dialogue. We talk about the key issues and discuss ways in which they can assist us. There is also usually a dialogue associated with the Forum (ministerial) meetings. In September this year, after the Forum meeting, we will have more discussions with our main partners such as the EU, Canada, France, Japan and the UK. I should mention too the close links we have with international organisations like the Asian Development Bank, the World Bank and the IMF.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I think it is fair to say that the Forum Secretariat is seen as a particularly important organisation in the region. That is why donors are quite keen to be seen assisting us in what we do.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What are the key development issues facing the South Pacific nations ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Development is quite a difficult process for our region. There are various international reports (particularly from the World Bank) - that describe how we have fared over the last few years. If you compare our performance with the Caribbean countries, for example, you find that we have not done nearly so well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We face a number of problems. First, there is the fact that we are so small. Small communities find it much more difficult than large ones to achieve development. You need to have the market and the critical mass to do all the things that are needed and we lack these. A second, related point is that our countries are very isolated from the rest of the world. It is true that here in Fiji, there are quite good connections, but if you go to Tuvalu, Kiribati or Niue, you will soon discover how difficult it is to get out. And if you are so isolated in terms of communication, how can you hope to increase your exports ? How can you airfreight your fish to Japan when there is no aircraft available-or the one that is available is not fast enough to ensure that the product is still fresh when it arrives?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On this question, one of the things we are increasingly realising is the need to do more in terms of human resource development. We all recognise that, without an educated population and workforce, it is very hard to achieve the development that we are aiming for. To be fair, if you compare the literacy rates here with those of many other countries, say in Africa, they are not at all bad. Our literacy levels are quite high. But I think we have a long way to go in acquiring problem-solving skills of the type needed to compete internationally. We are now talking with the EU about how we can utilise funding from the second protocol of Lom&eacute; IV. And I suspect that human resource development will remain high on the agenda.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Is that view shared by the European side ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-I think so. l have a feeling that they will support it because it is so obvious. If you develop human skills, you are better placed when it comes to problem-solving.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Going back to the key development issues, another point is the lack of natural resources. This is less of a difficulty for countries like Fiji or Papua New Guinea, but it certainly affects the small island states. It hardly needs saying that if you don't have the resources in the first place, it is much harder to develop.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, I think there is a question of how the Pacific region can get a better return on the resources it does have. This theme of 'managing our resources' was discussed by the Forum in Brisbane two years ago. Fisheries is probably the most important area here. The question is how we can earn more from this than we are currently doing- and there is no easy answer. Likewise in the forestry sector. We have to ensure that logging is done on a sustainable basis. But we must also recognise that leaders of the Pacific nations are under pressure. On the one hand, they are trying to take a lona-term view. but they are also striving to tackle the immediate problems. In an ideal world, our region would obtain a far better return on our resources, and that is something that we have to work on.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Having said all this, I don't think one should be too pessimistic. This region is still a very good place to live in. That is clearly reflected in the number of visitors we get. The 'South Seas' still have a special connotation that draws people here.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You effectively have two 'genera/' regional organisations, with overlapping memberships, covering the South Pacific -the Forum, and the South Pacifc Commission (SPC). Do you think there is room for bath ? Do you complement each other or is there a rivalry ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-We have more than two regional organisations. We also have SPREP (South Pacifc Regional Environment Programme), the FFA (Forum Fisheries Agency)....</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Yes, but these are specialist bodies with distinct sectoral responsibilities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Yes, that's true. In answer to your question, my view is that we have no problem with things as they stand. I was very involved in the debate some years back on the question of what we called an SRO - a single regional organisation. There was a strong push to try and achieve an SRO. The subject was debated for a few years and, in the end, it was possible to resolve the question.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You mean it was resolved by the idea being abandoned ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-I suppose it depends on the way you look at it. The outcome was a decision to leave the regional organisations as they are but with the establishment of a mechanism to ensure they work together more effectively. This mechanism is called SPOCC-the South Pacific Organisations Coordinating Committee. It is a meeting of heads of regional organisations which happens at least once a year. We talk about the issues that are common to our mandate and work out ways of doing things better. SPOCC has been operating for six or seven years now and I think it works fairly well. There is, after all, no conflict in our underlying objectives. So my answer here is no, I don't see any problem. I don't see any rivalry between us. It is a question of seeing how we can work together to achieve the goals that we share.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· In the European Union, the fundamental goal, set out in the Treaty, is to move towards 'ever-closer union' We have been doing this in fits and starts over the past 35 years. Do you see the Forum perhaps taking on a similar role here-as the focus for economic, and perhaps ultimately, political integration in the South Pacifc ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- I think it is too early to speculate. We already have a number of sub-groups in the region like the MSG, the Melanesian Spearhead Group, whose members are the Solomon Islands, Papua New Guinea, Vanuatu and Fiji (admitted last year). Further north, we have the Micronesian grouping which brings together Nauru, Tuvalu, the Marshall Islands and Kiribati. These groups meet outside the Forum framework and they essentially have a common aim which is to work more closely together. I think they feel it is easier to do it at this level because they are closer to each other and have more in common.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As for the Forum Secretariat, you can never tell what may come in the future. On balance, however, I think at the moment that integration is a long way off. Having said this, you do sometimes hear people putting the idea forward. There is, for example, something called the CER system, which stands for 'closer economic relations' between Australia and New Zealand. There have been suggestions that it might be possible to enlarge this grouping.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Looking at closer economic cooperation, and the general dismantling of trade barriers, we also need to recognise the growing importance of APEC (Asia-Pacific Economic Cooperation) for the region. We are trying strengthen our links with the APEC countries and in October, we will be establishing a trade office in Japan.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You mean a Forum Secretariat office ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Yes, in Tokyo. We are also talking with the Chinese and will probably end up with an office in Beijing. This is all part of our attempt to integrate ourselves with the Asean region. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Interview by Simon Homer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mission statement of the Forum Secretariat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mission of the Forum Secretariat is to enhance the economic and social well being of the people of the South Pacific, in support of the efforts of the national governments. The Secretariat has particular responsibility to facilitate, develop and maintain cooperation and consultation between member governments. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Secretariat must pursue its mission in accordance with the directives of the Forum and within its mandated areas of operation. it undertakes political and economic activities, regional in nature and complementary to the activities of the member governments. Its role requires it to act as the secretariat to the Forum and to disseminate the Forum's views, to coordinate activities with other regional institutions in particular through the SPOCC process, and to represent the Forum's interests intemationally, as required. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">ACP</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Investment symposium</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">A success story for African mining</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The MIGA (Multilateral Investment Guarantee Agency) symposium was held in Montreal from 22-24 May. It brought together some 40 African mining ministers, most of the important donor agencies and representatives of around 25 mining companies. MIGA, which is a specialised agency of the World Bank, promotes the flow of private investment to developing countries. It provides insurance against political risks and assists member countries in attracting foreign investment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The purpose of the symposium was to attract investors from all over the world in order to exploit the rich mining possibilities offered by many African states. Several of the countries that attended went to considerable effort to present themselves well, and it was evident that some are quickly learning what it takes to attract foreign investors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The climate for mining investment in most African states has improved tremendously over the last two to three years. Most countries have introduced new mining codes, clearly defining the rights and obligations of foreign investors. State-owned companies are also being privatised, taxation has been made more reasonable and institutions in the mining sector, such as geological surveys, are becoming more efficient.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All this has led to a big increase in exploration for new deposits and a substantial increase in investment. At present, the activity is particularly heavy in West Africa, where many countries have very good gold potential. The European Community is contributing to this development in several ways. The biggest success so far has been the exploration campaign in Mali, funded under that country's Lom&eacute; National Indicative Programme (NIP), which led to the discovery of the Sadiola gold deposit. A world-class gold mine will be built here, bringing substantial benefits to the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The World Bank has also supported many African countries in their efforts to reform the legal and administrative framework for the mining industry. An important element, however, in attracting mining companies is the availability of good geological data. This is a very expensive activity, which does not bring immediate returns, if at all. So it is not appropriate to finance this through bank loans. The NlPs and SYSMIN Fund, on the other hand, are instruments that are well-suited to this kind of work. The Community has already financed a series of airborne geophysical surveys in Botswana and Namibia -to mention just two examples-and a new Sysmin project is currently being prepared for Burkina Faso.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Commission Unit responsible for Mining Cooperation and Sysmin (VIIIl.B.5) was represented at the symposium. Its main purpose for being there was to present the functioning of Sysmin and the Community's cooperation in the field of mining to ACP ministers, mining companies and other donor agencies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Current state of the mining sector</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mining sector is currently very active. Exploration in West Africa doubled between 1993 and 1995 and new mines are being opened all the time. A lot of this new activity is to be found in the gold sector. This is mainly due to the development of cheaper production methods combined with a much more positive investment climate in many African countries. A gold mine takes less time to reach the production stage than, for example, a copper mine, with the former being far less dependent on good infrastructure. Outside the gold sector, activity is much more subdued. While base-metal prices are at a reasonable level, the pay-back period is much longer and the lack of suitable infrastructure kills many projects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For many countries, mining is a key area in the growth of the private sector. State-ownad mines are being privatised and the new mines that are being opened have little or no state participation. Foreign investors are bringing in the most up-to-date mining technologies and business methods, and they are faced with the need to train local people in technical and business skills. Supporting the mining sector is clearly an efficient way of supporting private sector development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SYSMIN's future role</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Given that most metals are currently fetching quite high prices, it is probable that relatively few ACP countries will be eligible for SYSMIN assistance over the next two to three years. The viability of most existing mines is not thought to be under threat and they should continue to be profitable. Thus, countries that are heavily dependent on mining should not experience severe losses in export income, which in turn means that relatively few SYSMIN requests are expected during the period of Lom&eacute; IV's second financial protocol. At the same time, the financial allocation for SYSMIN has been increased from ECU 48Om to ECU 575m.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When trying to attract new mining investors, it is essential for a country to have good geological information. Private companies are normally unwilling to undertake much general prospect ion, such as airborne geophysical surveys, because it is very expensive and, if they do, it is usually limited to very small areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At present, companies are tending to restrict their activities to areas for which general information is already available. These points were raised by several of the mining companies that attended the symposium.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But the present mining boom is not going to last for ever. Metal prices are volatile and, with the next downturn in the business cycle, a decline in metal prices will surely follow. So it is essential to prepare the basis for future mining activities by collecting general data. Given that a significant part of the SYSMIN allocation may remain unused because of a lack of requests, it would be worthwhile to consider whether a part could be reallocated to prepare general geological data for mining activities in the next century. </P>
+<P ALIGN="JUSTIFY">F. B.-H.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Joint Assembly to consider climate problem</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY">by Hans van de Veen</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Can the EU-ACP relationship be used to strengthen the dialogue between Europe and the main victims of climate change ? And can the Lom&eacute; Convention be one of the tools to promote climate protection measures, as well as the implementation of the Climate</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Treaty? These questions will be considered in depth at a hearing on climate derange scheduled for the next ACP-EU Joint Assembly, to be held in the last week of September 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Periods of heavy rain have always been part of normal life in Fiji. But the latest rains were different, says counsellor Taina Tudau of the Fiji Embassy in Brussels. 'They were much more extreme than what we were used to, and caused heavy damage. Normally it took several days of heavy rain before the floods came up. This time, the water flooded the islands almost immediately the rain began to fall.' Mrs Tudau sees two main causes for the recent flooding. First, there is heavy deforestation on the islands, causing widespread erosion. But she is sure there was another reason for the recent damage: 'In the Pacific we know the local climate is changing. We see that the sea is rising. We are experiencing more extreme weather events. There can be no doubt that global warming is already going on.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fiji is a prominent member of the Alliance of Small Island States (Aosis), the group of 36 nations which feel particularly threatened by global warming. At the first Conference of Parties to the UN Framework Convention on Climate Change, held in Berlin in March 1995, Aosis called for industrialised nations to reduce their C02 emissions by 20% by 2005 (based on 1990 levels). At the end of the conference, the 150 national delegations agreed to begin negotiations on targets for industrialised nations to cut emissions in the early years of the next century.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So intentions may be good, but in practice not much has been done yet. The EU, for its part, risks losing credibility if firm action is not taken soon. According to a recent Commission White Paper on energy policy, the use of energy within the Union will increase by 1% a year up to 2020. Failing 'any strong policy interventions', the paper says, emissions of carbon dioxide are likely to show a 'substantial increase' during this period. Says Fiji-counsellor Tudau: 'As small island states we know what's at stake, but there seems to be no feeling of urgency in the rest of the world. We really wonder how long it will take before there is a definite move towards reduction of greenhouse gases.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">EU-ACP cooperation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the Berlin conference, the ACP countries-led by Aosis but with support from most of the African states -took a constructive and moderate position in the G77. The position adopted by the EU could also be described as moderate, certainly compared to that of other OECD countries. Several observers have pointed to the fact that these two moderate approaches by important blocks within the Climate Convention negotiations offer possibilities for some form of cooperation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'No doubt the EU represents the most progressive group of countries</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">within the OECD, although its position is far from sufficient', says Sible Schone, a representative of the World Wide Fund for Nature. 'Besides that, the EU has a special relationship with a large group of developing countries. Quite obviously it will be significant to get a dialogue started between the EU and the ACPs on the subject of climate change.' Currently, there is no such dialogue. 'At the moment we are not in a dialogue with ACP countries on climate change', says Bertil Heerink of the European Commission's Environment Directorate-General who is a member of the EU delegation to the climate negotiations. 'I'm convinced this will happen some day, but first we have to agree on our own goals and measures. I am sure developing countries want us to give priority to this too.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The special ACP subcommittee to deal with tropical timber, the environment and fisheries, formed after the signing of the revised Lom&eacute; IV, only recently started its work. With respect to the global warming issue, it is waiting for the Joint Assembly hearing, according to ambassador Michael King of Barbados, who is a committee member. 'The specific interests of the different regions have to be articulated there, and then some kind of sustained effort has to be initiated.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The unit for Sustainable Development and Natural Resources in the Development Directorate-General of the Commission (DG VIII) not at present dealing with the subject of climate change. Says Head of Unit, Amos Tincani: 'We have worked on biodiversity and desertification, and we want to do more on the specific environmental problems of small island states. But we have done nothing similar on climate change. This is partly because it is so much a global problem, but the main reason is we simply lack the people and the time to go into it.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Assembly hearing</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At its meeting in Windhoek in March this year, the Joint Assembly adopted a resolution which had been proposed by representatives of 13 small island states. This urged the EU to take the lead in combating climate change and the adverse effects thereof. More specifically, the Commission is being asked to update its climate change strategy for the period post-2000 and to achieve significant reductions in emissions of greenhouse gases over the coming decade and thereafter. The resolution riches on to call for extra assistance to ACP countries in the Caribbean, Pacific and Indian Ocean to help them improve their disaster preparedness. The Commission is also urged to accelerate the transfer of appropriate technologies and practices, to enable ACP states to develop coastal zone management strategies and to rehabilitate and protect areas stricken by drought and desertification as well as by hurricanes and floods.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Two representatives of the European Parliament, Maartje van Putter (PES) and Peter Liege (EPP), have been active on the situation of the small island states and climate change for several years. According to Mrs Van Putten, the main effect of the coming Assembly hearing should be to put extra pressure on the Commission to take its responsibility seriously. 'Talking about climate change,' she says, 'one should never forget who is to blame and who, therefore, must take decisive action. A European tax on energy or carbon dioxide would be an important first step, but no more than that.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Besides influencing the Commission's energy policy, Mrs Van Putten hopes the Assembly hearing will raise public awareness on the climate problem in those ACP countries which are not in the 'small island' category. 'If you are talking about rising sea levels, the African states with low-lying coastal zones face the same problems as the small island countries,' she points out. 'And they also face the problem of desertification and declining food production.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Integrating the climate dimension</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In a recent briefing paperto the Commission, the International Institute for Environment and Development (IIED) concluded that, hitherto, the aid community (including the EU) had not incorporated measures on global warming into their strategic thinking on sustainable development. 'Indeed, the possibility of climate change has been considered of minor importance in comparison to other environmental concerns.' This is hardly surprising, says the London-based institute, as the climate issue has only recently been placed on the international agenda. Moreover, the long-term threat of global warming raises some difficult questions regarding priorities in circumstances where resources are limited. In other words: who wants to spend scarce funds on problems the full effects of which will probably not be felt for another 25 to 50 years? The best way forward, suggests the IIED, is to tackle the apparent conflict between shortterm development priorities and longterm climate protection, by 'integrating the climate dimension' rather than considering climate change as an issue in isolation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Technology transfer could be a central point, according to WWF's Sible Schone. 'Developing countries see technology transfer as a central theme in the Climate Convention, but the industrialised countries don't give enough weight to these There are a lot of paragraphs about technology transfer in the Convention as well as in Lom&eacute;. Now it's time to fill in these commitments.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Strangely, there are hardly any Lom&eacute; projects currently under way in the field of energy efficiency. It is strange because experts have pointed to the large potential in developing countries for cost-effective energy improvement and energy conservation. Improved management could save at least 25% of the energy now being consumed. Quick realisation of this potential would significantly contribute to alleviating environmental &agrave;nd development problems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Henri Martin, energy specialist in DG VIII, agrees a lot more could be done in this field, but he points out: 'We are dependent on requests. If you look at the wording of the Convention, everything has already been said. There are chapters on energy and technology transfer. The problem is that we don't get enough signals back from the ACP countries that these items are a priority for them. I'm afraid sustainable energy or energy efficiency is not high on the agenda of most countries.' Taina Tudau disagrees strongly: 'Our experience is that the projects that could make a difference and contribute to sustainable development, protection of the environment and local sustainable energy production, are found to be too small. It is the donor that sets the conditions for the projects, not us, the small island states.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">New funding?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Can the EU build a credible policy linking climate and development cooperation, without reserving extra money? Not surprisingly, there is disagreement on this question. In Brussels, officials are inclined to point to possibilities that are already there but not being used. Amos Tincani, for instance, observes that 'there are budgets for this kind of problem under Lom&eacute;. We have provisions specially targeted for the islands'. He mentions regional budgets in particular: 'A lot can be started at the regional level which then trickles down to the national level. But after producing fine resolutions, everybody seems to forget the work still needs to be done. The idea is: 'oh yes, we can do it, provided it is with fresh money'. We say: a lot more can be done with existing budgets and instruments.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Maartje van Putten, from the Parliament, says the discussion should not be 'dominated by southern demands for additional money'. She agrees that ACP countries could make better use of existing funds and possibilities, such as, for instance, the funds for intra ACP cooperation. But counsellor Tudau points to the fact that the Climate Convention urges industrialised countries to support the response of developing countries to climate problems through 'new and additional' money, besides the transfer of environmentally sound technologies and expertise.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is a financial mechanism built into the Climate Convention, which is administered by the Global Environmental Facility, to cover additional costs of appropriate measures. But much more could be done by the aid community, including the EU, according to Mrs Tudau. 'Most European countries will not succeed in stabilising, let alone reducing, their emissions. In reaction to this, as ACP countries we should say: European Union, you are not fulfilling your obligations. You have to try harder and you have to set extra money aside to compensate for the damage this is doing to us. </P>
+<P ALIGN="JUSTIFY">H.v.d.V.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">ACP-EU Council in Apia</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There were no real surprises or unexpected developments at the ACP-EU Council meeting which took place in Apia, Western Samoa, on 27 and 28 June, 1996. The session was preceded by an ACP Council, which saw the adoption of three important decisions. The first of these was the appointment of a new ACP Secretary-6eneral, Mr Ng'andu P. Magande of Zambia. The post had been vacant for some time, following deadlock within the ACP Group over a successor to Berhane Ghebray (see issue 155 of The Courier, p.6). The ministers also agreed to hold a summit of ACP heads of government in Libreville, Gabon, during the second half of 1997. This meeting is expected to focus heavily on the future of ACPEU relations once the present Lom&eacute; Convention has expired.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the substantive area, the ACP Council adopted a resolution deploring the suspension of cooperation with Equatorial Guinea. Ministers urged the European Union to make use of the procedure in Article 366a of the revised Lom&eacute; Convention, and to set in train the consultation procedure envisaged in this provision.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This issue was raised again by the ACP side at the subsequent ACP-EU Council. This meeting, which was presided over by Mrs Toya (Italian Under Secretary for Foreign Affairs) and Mr Syamujaye (Zambia's Trade Minister) had a relatively light agenda. There was a discussion about the Commission proposal for a directive on the use of vegetable fats, other than cocoa fat, in chocolate (see issue 158 of The Courier, p.35). Somalia also featured in the debate, with representatives agreeing on the need to find ways of allowing this country to benefit from Lom&eacute; Convention provisions. The civil conflict in Somalia, and the absence of an effective central administration have prevented the deployment of regular development aid for many years, although significant amounts of emergency assistance have been and are still being provided.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition, the ACP-EU Council approved two reports drawn up by the development finance cooperation subcommittee and commodities sub-committee respectively. Representatives were able to reach a compromise on two outstanding points of contention in the resolution on development finance relating to tenders and the dissemination of the user's guide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Note was taken of the number of countries that have so far lodged instruments of ratification for the revisad Lom&eacute; Convention (Mauritius agreement). At the time of the Apia meeting, only nine countries had ratified: seven on the ACP side (Barbados, Dominica, Equatorial Guinea, Jamaica, Malawi, Mauritius and Solomon Islands) and two EU Member States (Denmark and Sweden). Appeals were made for the contracting parties to speed up their ratification procedures so that the Eighth European Development Fund can come on stream as speedily as possible.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The next ACP-EU Council meeting will take place in Luxembourg on 24 and 25 April 1997.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The government of Western Samoa deserves a special mention for the warmth of their hospitality and the efficient way in which they organised the Council meeting. Delegates from all sides were keen to express their appreciation of the host country's efforts, which ensured the smooth running of the various meetings and gave the visitors a real taste of this Pacific country's unique culture. ed. S.H.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">New ACP Secretary-General</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ng`andu Peter Magande, is no stranger to the challenge of development at the grassroots. The new Secretary-General of the ACP Group, who was born in 1947, began his working career as a provincial development officer, planning and supervising projects in the Southern Province of his native Zambia. He is an economics graduate of the University of Zambia and also holds a master's degree in agricultural economics from Makerere university, Uganda.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From working in the field, he moved into government administration, rising to the position of Permanent Secretary-a post which he held in a number of ministries. Since the mid-1980s, he has had key jobs in a number of Zambian enterprises (including Managing Director of the Zambia National Commercial Bank) His most recent work has been on a project to develop private sector participation in agricultural input and produce marketing.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Kenya's economy in the 1990s</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Elisabeth Pape</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kenya has enjoyed rare political stability since independence in 1963. It is one of the most famous holiday destinations in Africa, with abundant wildlife, fine beaches and stunning scenery. But despite having the most advanced economy in East Africa, it is still one of the world's poorest countries. Over 11 million Kenyans live below the poverty line. But better times may be ahead. The Government has embarked on an ambitious reform programme which promises to lay the foundations for strong growth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The early 1990s marked the worst time in Kenyan history, in economic development terms. Real GDP growth dropped from 4.3% in 1990 to 2.1% in 1991 and was almost zero in 1992 and 1993. This poor performance was due to drought, structural rigidities, lack of monetary discipline, non-enforcement of banking regulations, and reduced donor assistance. While Kenya was used to receiving substantial foreign aid inflows, the present decade began with growing tensions between Government and donors. In the new post-Cold War atmosphere, the latter wanted to see political and economic reforms, and in November 1991 they decided to halt guick-disbursing aid.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Multi-party elections in December 1992 did not immediately restore relations with the donors, in particular as they were accompanied by a lack of fiscal and monetary discipline whose effects threatened economic ruin. Monetary expansion was fuelled, among other things, by discretionary exemptions to Banking Act provisions, which enabled over-borrowing by certain 'political' banks from the Central Bank. In early 1993, things came to a head. Foreign currency reserves were down to just a few weeks of imports, the banking system was on the verge of collapse, and consumer prices had shot up. Against this background, the Government went for a comprehensive, IMF-supported structural adjustment programme.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A number of far-reaching reforms were implemented with unprecedented speed. Exchange restrictions were removed, import licensing was ended, import procedures were made easier and tariffs were reduced. The export license requirement was also lifted and price controls were abolished. In March 1993, the Central Bank (CBK) began to tighten monetary policy. By issuing large amounts of treasury bills, it soaked up most of the excess liquidity which had been injected the previous year. There was also stricter bank supervision and a number of weak financial institutions were closed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Structural reforms</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Government began structural reforms aimed at reducing its own role in the economy in favour of the private sector. The privatisation programme, begun in 1991, was accelerated. By the end of 1995, the authorities had divested more than half of the 211 non-strategic parastatals-though critics complained the process often lacked transparency. The Government also substantially reduced its fiscal deficit through, above all, an improved revenue policy. The deficit fell from 11.4% of GDP in 1992/93 to 2.5% in 1994/95. The number of civil servants was reduced, mainly through voluntary early retirement, so that, by the end of 1995, the service had been trimmed by more than 30 000 (10% of the payroll).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1995, the reform programme lost momentum as proponents of the old and the new systems locked horns. Vested interests stood in the way of more radical reforms. Temporary import bans on maize and sugar were reimposed, key parastatal reforms were delayed and expensive but economically dubious projects were approved outside normal budgetary procedures. These included an international airport in Eldoret, a presidential jet and an identity card project. These further delayed the resumption of balance of payments support by the Bretton Woods Institutions and contributed to the frustration of efforts to improve relations with donors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The economic crisis peaked in early 1993 and the shilling was sharply devalued. The official rate went from about KSh 36 to the dollar at the end of 1992 to KSh 60 in April 1993. On the market, the currency was being traded at a premium of more than 30% and that continued until July-i.e. about two months after the removal of exchange restrictions. The market premium then started to decline and the two rates converged in mid-October when the shilling stood at 69 to the dollar.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The high interest rate on treasury bills under the liberalised foreign exchange regime was the main reason behind strong currency inflows which began in October 1993. Other factors, whose exact impact is difficult to gauge, included capital flight from neighbouring crisis-torn countries, the international money laundering one normally finds in places with newly liberalised foreign exchange regimes, and a surplus in the current account position. The shilling then started to rise, despite the CBK's massive currency purchases which led to a build up of reserves to the equivalent of six months of imports. The appreciation continued up to October 1994: indeed, at one point, the shilling reached a high of 35 to the dollar.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">That was the turning point. Strong import demand, fuelled in particular by a surge in oil imports in the wake of petroleum market liberalisation, and an outflow of portfolio investments due to lower interest rates, weakened the currency. By mid-1995, after two sharp falls, it reached a rate of 56 to the dollar. Since then, it has been relatively stable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economic recovery</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Real GDP grew by 3% in 1994 and an estimated 5% in 1995. Good weather certainly helped, but the economy also benefited from the Government's reforms. Agriculture, the mainstay, grew by 2.8% in 1994 and by more than 5% in 1995. This compares with negative growth rates in 1992-93, when the sector was hard hit by bad weather. Elsewhere, the trends were more mixed. Many producers for the local market were affected by trade liberalisation and, in 1994, by the strong shilling. The former created a highly competitive environment almost overnight-after years of cosy protectionism. For cloth manufacturers, the liberalisation of imports of second-hand clothing further aggravated the problem. In 1994, the clothing sector's output dropped 35%. Tourism, the main foreign exchange earner, fared quite well in volume terms in 1994 despite the strong shilling. But while turnover may have gone up, it is likely that many operators did not earn enough extra to cover their increased local currency costs. In 1995, visitor arrivals fell by 20% to the lowest figure since 1988. In consequence, tourism earnings fell by a quarter.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As intended, liberalisation led to higher trade volumes. In 1994, exports ( + 16%) rose by more than imports ( + 13%) in value terms, but the position was reversed in 1995 when the latter jumped by 35% while the former were 14% lower. One good sign was that the highest import growth was in industrial supplies and machinery (60% up) but the fact that the deficit almost doubled to reach record levels was obviously a cause for concern.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A major revolution has also taken place in trade flows. In 1994, for the first time, Uganda overtook the UK as the biggest importer of Kenyan goods. In the same year, the value of Kenya's exports to African countries moved ahead of its combined exports to Europe and North America.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During 1994, the Nairobi Stock Exchange proved to be one of the worid's best-performing stock markets, the value of shares rising by 80%.1995 was disappointing, however. Although foreigners were allowed to invest for the first time, the index nonetheless fell by 25%.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fighting inflation has been the CBK's main objective since 1993 and a tight monetary policy has brought the problem under control. Inflation dropped from 46% in 1993 to 29% in 1994 and to below 2% in 1995. Recently, however, an upward trend has bean observed. This follows a money supply increase far in excess of the expansion of economic activity, and is mainly due to a substitution of treasury bills for borrowing from the Central Bank since the end of 1994. If inflation is to remain within the 5% target for 1996-which already seemed highly unlikely by the middle of the year - the trend needs to be speedily reversed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Initially, the main way of mopping up excess liquidity was through the sale of treasury bills. When the sales began in March 1993, there was a huge liquidity overhang and high interest rates had to be offered to take money out of the market quickly. The rate earned on 90-day bills-which became the lead interest rate in the economy- rose from 17% to 80% between March and July 1993. It then declined steadily, reaching 18% at the end of 1994. This prompted an outflow of short-term capital, leading to currency depreciation and lower foreign reserves. Since mid 1995, treasury bill rates have been back above 20% and this seems to have stabilised the foreign exchange situation. It is generally believed that the high prevailing real interest rates are a major obstacle to investment and economic growth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Interest on domestic debt is still a big item in the state budget, although, the situation is much improved, thanks to the reduction in the stock of treasury bills and lower interest rates. In fiscal year 1993/94, interest payments on domestic debt alone swallowed one third of total gavernnnent expenditure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The agriculture sector employs 70% of the total labour force and generates more than a quarter of Kenya's GDP. Much of industry is linked to agricultural processing, and tea, coffee and horticultural products are Kenya's major foreign exchange earners after tourism. The marketing of key farm products is dominated by large parastatals and cooperatives which are often run like parastatals. Most marketing organisations have been hard hit by the liberalisation, which brought both inefficiency and corruption to light. Tea growers have complained about improprieties at the Kenya Tea Development Authority. Imported sugar flooded the local market, often without paying import duties, leaving the mills with huge stocks. This, in turn, created severe cash flow problems. Most sugar farmers have not been paid for months. Kenya Cooperative Creameries was not able to pay farmers for milk deliveries for up to half a year, and could only start servicing the arrears when the Government came to its rescue with KSh 800 million in January 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Formidable challenges</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kenya's labour force, around 12.5 million in 1996, is growing at more than 4% a year. This means that at least half a million people enter the job market annually. The challenge of absorbing the new workers is formidable. Studies show that any strategy to deal with this must be based on three pillars: smallholder agriculture (to absorb most of the growth in the rural labour force), continuing substantial job creation in the informal sector, and high real GDP growth (+8% per year is needed to ensure that the modem sector absorbs a significant number of workers).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Informal sector employment has risen rapidly (up by 15-20% a year since 1991). By 1994, for the first time, there were more people working here than in the modern economy. The informal sector covers semi-organised and unregulated activities largely under taken by self-employed people or employers with just a few workers. Typically, they do not comply fully with tax, registration, and licensing rules, and this sometimes leads to conflict with the authorities. Workers are often paid below the minimum wage and have no social security. For many, the informal sector is, therefore, an 'employer' of last resort.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is estimated that almost 50% of rural people and 30% of urban residents live in absolute poverty- unable to meet their minimum requirements for food and essential non-food items. While the percentage has remained fairly stable in recent decades, the increase in the number of 'absolute' poor is alarming. So too is the extent of the poverty: the gap between these people's minimum needs and their actual disposable income has reportedly increased over the last ten years. The bulk of the poor live in the central and western parts of the country, which have the best agricultural potential, the rich soils having always attracted settlers. For decades there was enough land to go around, but demographic trends have finally started to take their toll. The size of landholding has declined continuously, in many cases reaching levels which are no longer capable of sustaining a family.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There has been some progress in restructuring parastatals, but much remains to be done. The performance of key parastatals has been unsatisfactory by international standards and this has constrained growth. At Mombasa port, which is managed by the Kenya Ports Authority, handling charges are 50% higher than the global average, while container turnover is three times slower. Rail transport is unreliable, slow and more expensive than road haulage. The Kenya Power and Lighting Company has a shortage of generating capacity which means periodic power cuts. And intervention in the maize market by the National Cereals and Produce Board- at above-market prices-has prevented private sector involvement as well as placing a heavy burden on government finances. The Board has posted annual operating losses of between KSh 1.8bn and KSh 2.5bn each fiscal year since 1992/93.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Corruption, misuse of funds, and the politics of patronage remain endemic and these clearly distort development. Elimination of corruption has been an aim of most reform programmes but it seems that the effect so far has only been to change its form. Trade liberalisation has killed cash cows such as import and foreign exchange licences, and the commercialisation of parastatals has stopped them from doing deals with cronies which were profitable only for the latter. But other forms of non-acceptable wealth accumulation have emerged. In the early 1990s, alleged exports of gold and diamonds are thought to have resulted in a loss of KSh 7 billion of public funds. Land grabbing has also become widespread. This either involves land being sold to individuals or companies with well-established political connections at well below market prices, or the purchase of land by public institutions from the same individuals or companies at inflated prices.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">After delays because of political differences, cooperation between the three states of the former East African Community (Uganda, Tanzania and Kenya) was revived in early 1996. The EAC Secretariat, based in Arusha, is headed by a Kenyan, Francis Muthaura, a former ambassador in Brussels. For the three countries, the new cooperation aims at facilitating movements of people, capital and trade within the region, and harmonisation of external tariffs and investment regulations. Currencies will be fully convertible. This revived cooperation is expected to have a major growth impact. The Nairobi Stock Exchange is currently assisting Kampala and Dar es Salaam to set up their own exchanges. And the NSE Chairman, Jimnah Mbaru, sees the future not only in a cross-listing of companies in the three places, but in a regional stock exchange.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Policy framework</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Policy Framework Paper (PFP) for 1996-1998, which was published in February ahead of the donors' Consultative Group (CG) Meeting, was highly applauded for both its content and form. The programme, which the media has dubbed 'the big push', promises finally to crack most of the 'hard nuts' of previous reform agendas, in particular in the parastatal and public sector. It also lays down measures aimed at supporting fiscal and monetary discipline through the next elections. These include cutting the budget deficit to 1.5 % of GDP by 1997/98, a tight monetary policy, and more autonomy for the Central Bank. In addition, it tackles some areas'that have emerged as avenues of corruption in recent years, such as the National Social Security Fund. While previous PFPs were highly confidential, this one was published, and the President appointed a Commission chaired by himself to oversee its implementation. These are seen as important steps in bridging the credibility gap which threatened to open up again in 1995. Donors are prepared to support the reform agenda and are eager to see it implemented speedily. Shortly after the positive outcome of the CG meeting, the IMF approved a three-year Enhanced Structural Adjustment Facility programme for a total of $220m. The World Bank is expected to follow suit with a credit of $85m.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An increasing number of donors, however, have pointed to the link between democratic governance/ human rights issues on the one hand, and aid and investment flows on the other. If Kenya is to meet its ambitious targets and turn into a newly-industrialising country by 2010, foreign inflows will be vital. The point was succinctly put by a delegate to the CG meeting. 'If its (the Government's) economic successes are matched by a commitment to democracy and human rights, Kenya may yet prove that surging economic growth is not just for Asian tigers, but for African lions, too.' The period leading up to the next general election will be the acid test. </P>
+<P ALIGN="JUSTIFY">E.P. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Country report</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Mali : An omnipresent sense of history</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some countries have a strong folk memory. Despite its size, Mali appears hemmed in by its frontiers. For more than a thousand years, this state was a splendid empire, constantly spreading outward and reflecting the history of the African continent with its conquests and alliances, reversals of fortune and moments of glory. At its height, it extended from the Atlantic to the Sudanese border, from the south of Morocco to the north of Nigeria. Mali's history rests in the minds of its people rather than in any structures inherited from the past. This acts as an antidote to the 'amnesia' often brought on by colonisation, which has the effect of paralysing the future. Although poor, the country has a well-established sense of its place in the world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A racial melting pot</P>
+<P ALIGN="JUSTIFY">`</P>
+<P ALIGN="JUSTIFY">On the eve of colonisation, Mali was known es 'west Sudan'. In 1924, the territory then known as 'French Sudan' was split up and small portions of the Malian nation were incorporated into the seven states bordering it-a move certainly not calculated to have a cohesive effect on the remnants of the old empire. Mali has long been a melting pot of races, ethnic groups and cultures. They have learned to live together- intermingling, sometimes forming unexpected alliances, and occasionally fighting one another. The result today is a potpourri where true racial or ethnic confrontation is difficult to imagine. The interplay of history and the mixing of ethnic groups, families and individuals, has created what one intellectual de scribed to us as 'the anti Rwanda vaccine'. Historical mythology offers, perhaps, further evidence of the fusion of cultures in this country. As in ancient Greece or Rome, to take European examples, each ethnic group and each Malian empire, was 'backed' by a host of gods, spirits and totems. In this nebulous world, where dreams beget history and where vastly differing ethnic groups can trace themselves back to a common ancestor, the result was a multiplicity of interrelationships. Under various names, the python totem belongs to many different peoples, including the Peal, Ma/inke and Sarakolle. A study of the migrations of the peoples who make up Mali also reveals a great many relationships - for example, between the Dogon, who are black, and the Shongoi; who are more half-caste. They regard one another as cousins, originating from Aswan in Egypt.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Malians appear to share a genuine sense of belonging in keeping with their shared culture. The 'people' of Mali came into being long before the state of the same name. The guerilla war fought in recent years by the Tuaregs (this is the English plural, Tuareg already being the plural form of Targul) against the Malian army, is often viewed abroad as a struggle between whites (or Arabs) and blacks. But this is an illusion. Although the Tuaregs are probably the only 'white' minority in the country, they are an integral ingredient in the melting pot. They are also known as 'Kel-Tamasheq' - those who speak Tamashek, which was originally the language of their Bella slaves. Like all the country's ethnic groups, they have dominated and have in turn been dominated. They have forged alliances with one another, and, more commonly, have united against Arab or Berber invasions. The relative absence of bitterness overall is probably due to the fact that each of Mali's peoples has had its era of glory and imperial dominance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mali is lucky to have such knowledge of its history. For centuries, the most precise details have been collected by the griots. The same role has also been played by the many secret societies which have initiation periods lasting, in some cases, up to 50 years. They were, and sometimes still are, repositories for the secrets of history, magic, astrology and science, and also for the symbols of power-the religious objects and artefacts of the former emperors. There are written sources as well, something which is quite rare in Africa. These have been transcribed since the beginning of the millennium and, in recent decades, close collaboration between historians, griots and members of traditional societies has enabled a deeper knowledge to be gained of Mali's history.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A rich empire</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Asselar Man, discovered near Timbuktu in the centre of Mali, was a contemporary of Cro Magnon Man. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cave paintings from five thousand B.C. reveal similarities with those in Egypt and are probably the work of migrant populations from the east, who moved into Mali as the Sahara Desert expanded. Less reliable sources state that interbred populations of Jews and Egyptians under the command of an officer of the Pharaoh Dinga created the Soninke dynasty (originating from Aswan). These people probably laid the found ations of the first great Malian empire, that of Ouagadou. Other sources, equally unreliable, report that they were probably Judaeo-Syrians who arrived at the end of the third century A.D. and found a population already in place. What is more or less certain is that, during the first millennium, a Soninke dynasty was installed around the current frontier between Mauritania and Mali and that 40 princes ruled it in succession in the period prior to 750 A.D. Initially, these rulers were white but, with increasing intermarriage, their skins became darker and darker. To Arab chroniclers, Mali came to be known as Bafour or Bilad es-Soudan (the country of the blacks). At the beginning of the second millennium, the Ouagadou empire held sway over several kingdoms in the south, including the Nigerian delta and a number of Berber principalities. Documents dating from this period have replaced the name Ouagadou with that of Ghana, by analogy, perhaps, with the emperor's title. The empire was already very rich, the richest in the world according to an Arab chronicler who visited it in 970. A work by the writer A/ Bakri, which appeared a century later (1087) went into great detail about the empire's organisation-the system of matrilinear succession, the role of councils of dignitaries, and the capital, Koumbi (whose foundations were discovered in 1914 in southern Mauritania). This city was divided into two districts, one of these being the sacred, imperial city, home to the empire's python totem to which a young girl was sacrificed every year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A story of courage</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The killing of the snake totem is the most significant myths in the country's history. The hero of the story is Amadou Sefedokete whose love for his beautiful fiancee Sia (who was about to be offered in sacrifice), prompted him to descend into the monster's lair and confront it. By killing the totem, he broke the thread of countless generations before him, who had carried out the ritual sacrifice. He is still remembered for this magnificent action, based on love and a sense of nobility, and he remains a subject for artists of all types. His brave action still causes young lovers in Africa to shudder in admiration. However, this act of deicide brought about a reversal of fortunes. The monster's seven heads, which the young hero is said to have cut off one after the other, are reputed to have been scattered to the four comers of the earth, thereby dispersing the empire's riches and leaving it penniless. The true story is more prosaic. Ghana's wealth was eyed greedily by the Arabs and Berbers who had long traded with it. The empire's resistance in the face of Islam gave Moroccan religious fanatics a pretext for organising a jihad. It was invaded by an army of 30000 devotees supported by forces from some of the empire's black vassal states. The 'holy war' began in 1042 ending 34 years later with the occupation of Koumbi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The occupation did not last long but was followed by internal clan wars which brought about the end of an era. Restoration came about at the end of the 72th century , in the small Sosso kingdom, south of Ouagadou (also set up by a small group of Sonink&eacute;). One of the minor kings called Soumangourou Diarasso dreamed of recreating Ghana's empire, and, in 1203, he succeeded in sacking the ancient capital of Koumbi in a move designed to establish his own dynasty. This was an important symbolic act and in the fierce war which followed, Soumangourou subjugated Mand&eacute;, a region which was overflowing with wealth. One of Africa's greatest heroes, Soundjata, rose up against him. He was supposedly the legitimate heir to the Mandingo throne, but was unable to walk, having been born an invalid of a deformed mother who had been married at the recommendation of the king's sorcerer. His young half-brother took his place on the throne and sent the paralysed prince into exile. At the age of 18, Soundjata decided to seize his own place in history and a 'giant' was thus bom. In 1235, his army fought that of the bloodthirsty Sosso monarch whom he himself is said to have cut down in an extraordinary battle. It was a fight which, according to the legends, saw the use of all types of weapon, including magic. Soundjata had forged a grand alliance in order to gain victory. Rather than reducing to vassalage the small kingdoms which had allied themselves with him, the new emperor decided to form them into a federation-although he wisely declared that from Niani (his capital), 'I shall see all'. His empire took the name of 'Mali' (the hippopotamus) on account of that animal's strength and mastery of bath water and land. For 20 years, the empire was to stretch as far as the Atlantic Ocean. Its structure, based on a number of warrior clans, craftsmen, freemen and marabous, is still characteristic of Mali and neighbouring countries today. The empire was rich in gold once again but also in terms of agricultural organisation with the development of cotton and groundout farming. Soundjata disappeared mysteriously in 1255, leaving a prosperous empire.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'Conquest' of America?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1285, there was a struggle for succession between two princes and a third, Prince Sakoura (a freed slave), took advantage of the quarrel to take power for himself. Sakoura expanded the empire by subjugating the Timbuktu Tuaregs and the Gao Shongoi: After his short reign, a genuine heir of Soundjata, Aboubakar II, ascended the throne. He had his eye on conquests over the seas and, according to the story, he set sail westwards leading a fleet of 2000 vessels. He was never seen again. However, recent studies favour the hypothesis that he was not lost at sea as had always been supposed' but did, in fact, reach the Americas. A series of ineffective monarchs succeeded this 'conqueror of the impossible', who preceded Christopher Columbus by 200 years, leaving little real impression on history other than the records of their exuberant behaviour. One of them, for example, went on a pilgrimage to Mecca in 1324 with a reported retinue of 60 000 and distributed considerable amounts of gold to all the dignitaries he encountered in that holy place. These kings, however, are acknowledged as having preserved the empire's unity, guaranteeing order without repression and allowing wide religious, moral and sexual tolerance, even for married women. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The kingdom centred on Gao dates back to at least the first millennium but it was usually a vassal of the Ouagadou empire and of Mali. One of its kings, Sonny Ali Ber (known as Sonny the Great), came to the throne in 1464, profiting from the decay of the Mali empire. His reign was marked by a bitter struggle against the Ul&eacute;mas of Timbuktu who, over a period of four centuries following the Almoravid conquest, had converted a large portion of the empire to Islam. The circumstances of Sonny's disappearance are uncertain, but he is thought to have drowned in 1492, the year when a certain Genoese navigator was to achieve the ancient goal of 'discovering' the Malian empire.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sonny Ber's successor did not last long in the face of Islamic expansion. The new Askia dynasty was installed to lead the Shongoi empire, and this expanded with the annexation of Dahomey and part of Nigeria. However, a small part of the former Mali empire never passed under their rule. The Askia dynasty blew hot and cold in terms of religious fervour. Tyrannical at first, it later took a softer line. Under the reign of one monarch, the Gao court based in the university city of Timbuktu became a place of exceptional refinement-only to slide once again into a state of intolerance. One of the Askias, having destroyed the last symbols of the former Mali empire, the city of Niani, set upon his former Moroccan allies. Another emperor, Askia Daoud (1549-1582), turned out to be a fine administrator. He developed agriculture and set up a genuine bank in Gaol War with Morocco continued throughout his reign and beyond. In 1584, imperial force defeated 20 000 Moroccan soldiers, winning a victory which might have been decisive had it not been for internal dissent. This weakened the Askia side and enabled Morocco, with a band of Spanish mercenaries, to take over the empire, following a battle in April 1591. Success was due, above all on this occasion, to the firearms deployed by the winning side. Such weapons were unknown to the 45 000 Malian cavalry and infantry who were engaged. It also turned out to be a Pyrrhic victory. The occupying troops sent the great scholars from Timbuktu University to Morocco, where their peers took up their cause. Moreover, the foreign soldiers were won over by the easy life in Mali-and one of the first results of their presence was a big increase in the half-caste population. In 1612, the troops rejected the Moroccan command: the occupation was at an end and the last few Moroccans were later expelled from Timbuktu by the Tuaregs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Black religious proselytism and colonisation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To each dog his day. In the 17th century, the Bambaras set up an empire around Segou, but the debauched lifestyle of several of the sovereigns and disapproval of the part they played in the slave trade proved to be their downfall. Once again, the history of the country was to be shaped by a slave- Ngolo Diarra-who founded his dynasty in 1766. He was able to restore a degree of prestige to the kingdom, but his efforts were undermined after his death. As a reaction, a proselytising Black Islam then began to evolve.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Massina became a theocratic state around the beginning of the 19th century, in common with other kingdoms which appeared at the same time. One of their most famous rulers, the conqueror El Hadj Oumar, was defeated by the troops of the French General Faidherbe who forced him to give up West Senegal. The days of Malian independence were now numbered. The courage of his successor only delayed the progress of French colonisation, which finally prevailed at the end of the century.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Resistance fighters carried on the war from other points in the old empire, particularly from what is now Guinea. The country was dismantled by the colonial system and pacified, but the end of the Second World War and the return of African soldiers brought a renewed desire for independence. French Sudan became the rallying point for freedom fighters in the French colonies-the old dream of reunification was not dead and buried. In 1946, the Rassemblement Democratique Africain was set up, later to become the USRDA (Union soudanaise-Rassemblement democratique africain). In 1956, the future architect of Mali's independence, Modibo Keita, was appointed leader of the movement and elected to represent the 'Sudan' in the French Assembly. A 'Malian Federation' project was drawn up to include Dahomey (Benin), Upper Volta (Burkina Faso), Senegal and 'Sudan' (Mali). A constituent assembly of independence movement representatives was set up in 1959. However, the constitution adopted by the local Malian and Senegalese assemblies was rejected by the other two. The Federation now had only two members but was nonetheless proclaimed independent on 20 June 1960. In the event, the spirit of unity was lacking and, on the pretext of a rivalry between the two leaders (the 'Sudanese' Modibo Keita and the Senegalese Mamadou Dia), Senegal withdrew from the union in August. On 22 September 1960, the 'Sudan', now without an outlet to the sea, adopted one of the most prestigious names in its history: Mali.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The new state was landlocked not only geographically but also, very soon, politically. Modibo Keita's socialist agenda prompted foreign investors to pull out, and the country was organised increasingly as a 'people's democracy'. Fortunately, the repression was not excessive but a sizeable proportion of the population disapproved of the system that had been chosen. Mali and Guinea still had modest aspirations to their old dream of unification. The founder of the Republic, Modibo Keita, was overthrown by a military coup on 19 November 1968. More than the break-up by colonisation, which left dreams of Sudan being reconstituted, this military putsch sounded the knell of the old empire. Mali became just another state whose colonial and post-colonial eras have been marked by a lack of success. Nevertheless, a sense of history is still omnipresent. </P>
+<P ALIGN="JUSTIFY">Hegel Goueier</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Three republics to create one democracy</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is just something you have to get used to-in French-speaking Africa, virtually all countries have imitated France in assigning a number to each republic formed under a new constitution. At the time of its independence on 20 June 1960, Mali was a federation of two states; Senegal and the former 'French Sudan'. It was an alliance which failed after only a few weeks'existence end 'French Sudan' then adopted one of its most prestigious former names- Mali. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first regime, under Modibo Keita, became increasingly unpopular as its form of 'tropical' marxism caused it to become more and more isolated. One of its main shortcomings was its unrealistic five-year plans, none of which were ever implemented. Discontent became rife among various social groups. including the farmers who, opposed collectivisation and were adept at passive resistance which they employed to disrupt the supply of produce. The regime also modelled itself on the so-called 'people's democracies' in certain respects. For instance, it made a determined effort to improve education, health and social justice, while refraining from the more dictatorial excesses that often characterised such systems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Initially welcomed by some sections of the population, the November 1968 putsch, by Lieutenant Moussa Traore quickly fumed into dictatorship although it was to be more than 10 years before there were any significant anti-government protests. At the end of 1990, opponents of the regime openly set up organisations which claimed opposition-party status. One of these was ADEMA (the Alliance for Democracy in Mali), formed by the current President of the Republic, Alpha Oumar Konare. Marches calling for a multi-party state attracted the support of tens of thousands of people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The dictator then sought to neutralise the opposition, beginning with the Tuaregs in the north who had been waging a guerilla war. This conflict was viewed by many as the 'front line' in the people's struggle against dictatorship, and the Tuareg cause was supported by opposition movements. The government, which had for some time opted for 'soft' repression, now revealed its claws and in January 1991 it began to imprison student leaders. The streets were filled with armoured vehicles and the first death amongst the students brought condemnation. Repression reached its height on 22 March 1991, when several dozen students were killed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Prior to this, in February 1991, Moussa Traore's UDPM (Democratic Union of the Malian People) came out in support of a multi-party system - a move which marked the beginning of the end of the regime. The day after the students were killed, a democracy coordination committee launched an appeal for a general strike, to last until the dictator was overthrown. This began on 26 March, and amounted, in effect, to a 'democratic' coup d'etat. Its instigator was Lieutenant Colonel Amadou Toumani Toure, who took charge of the transition to-tether with the democratic movements.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The former dictator was arrested and put on trial for his crimes. He was later condemned to death but his sentence was recently commuted by President Konare.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Tuareg guerilla war continued despite the government's conciliatory attitude. The new administration also had to deal with a number of social claims which had long been stifled by the dictatorship. However, popular support for the regime remained firm. The new constitution was adopted virtually unanimously in a January 1992 referendum and, a week later, ADEMA won the municipal elections, the first in a series of electoral victories for Alpha Oumar Konare. He went on to win the Presidential election (for the Third Republic) in April, with almost 70% of the vote. Meanwhile, negotiations with the Tuareg rebels resulted only in signatures on agreements which were not observed. The situation grew worse with the Ghanda Koy counter-offensive, but this in turn led to a seemingly viable accord between the Azawad Arab Islamic front, the most important guerilla movement, and the Malian government. Last March, President Konare presided over an enormous bonfire of weapons seized from the former guerilla fighters. The flames lit up the skies above Timbuktoo, the symbol par excellence of rapprochement between the peoples of Mali.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the beginning of January 1994, the regime suffered the effects of the devaluation of the CFA franc. Economic liberalisation had enabled Mali to improve its macroeconomic position, but social discontent, particularly in the towns and cities, demonstrated that the average citizen was continuing to suffer economic hardship. The President still enjoys considerable support, and political democracy is greatly appreciated. Obviously, the government cannot be blamed for all the difficulties facing the country. There is, for example, a lack of professionalism in the press. However, it could have given a lead in the case of the State media, which still studiously avoids criticising the government's actions. The administration has also been taken to task for its apparently lax attitude towards 'economic' misdemeanours.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Next year will see a series of elections. The government views these with apprehension, although it has stolen a march over its rivals by signing a political accord with several small parties. Opposition is centred around the MPR (Patriotic Movement for Renewal), the revamped former party of the dictator Moussa Traore. This has undergone a 'facelift, and now seems to be regaining support. lts trump card is decentralisation. Its former leaders, who held total power for a quarter of a century, can take advantage of the network of contacts they built up. The US-ADA, the party of the Republic's founder, Modibo Keita, which until recently appeared to be the herald of change, seems lately to have restricted its role to that of arbiter. Surprises are in the offing, but one thing is certain: the Third Republic's constitution will remain the guarantee of democracy in Mali. </P>
+<P ALIGN="JUSTIFY">H.G.</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Interview with Ali N. Diallo, President of the National Assembly</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Mali, the army has learnt if from the past</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mali's institutions were radically remodelled in the wake of the recent vote on decentralisation. This is aimed at allowing, among other things, a degree of autonomy for the north of the country-which is essential to guarantee national reconciliation. The sudden growth in the number of small towns and villages may result in some political surprises during the long e/ection campaign period which is due to begin early next year. The President of the National Assembly, Ali N. Diallo, finds himself in a pivotal position: his Adema (A/fiance for Democracy in Mali) party current/y holds a comfortable majority in Parliament. With democracy being consolidated in Mali, he must find this an exhilarating time. Our frst question touched on this</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-This is certainly an excellent time to be in Mali, but freedom is the most difficult of man's needs to satisfy. Our National Assembly has 12 parties and most people in our country are inspired by ideas based on tolerance and respect for the right to be different. The main concern of those of us who lead the party currently in the majority, is to question constantly whether we are necessarily always right. We have a comfortable majority-72 members out of 115-but this certainly doesn't mean that the National Assembly is just a rubber stamp.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· There is, of course, another stumbling block when one has such a large majority, which is the possibility of internal divisions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Yes, I would agree with you there. Mali's MPs have to realise that they came into this business after a three-stage process. First there was a popular uprising, then the army intervened to put an end to the bloodbath.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, we had the high level national conference to draft the constitution, the electoral code and the charter for the country's parties. MPs, therefore, must always bear in mind that, though they can claim legitimacy on the basis of the revolution, there is also a republican legitimacy they ought to respect.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The second phase in the process was the intervention of the army-are you not a*aid that the 'Niger syndrome'will raise its ugly head in Mali, too ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Naturally, MPs have seen what happened in Niger and elsewhere, but fear is tempered here because officers in Mali's forces have also given a great deal of thought to the effects of military dictatorship. Democrats and republicans within the armed forces are very aware that only a minority of men in uniform profited to any degree from the previous regime.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Do you think that because Mali had what might be called a 'moderate' dictatorship, it is now in a better position than it would have been had the previous administration been more repressive ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Let me put it this way. The military dictatorship went through three different stages. During the first stage, just after the coup on 19 November 1968, the junta chose Mao Tse Tung as a model, hammering home the idea that power could be won by force of arms-and it was carried away by the popular acclaim it initially received. Subsequent popular resistance then took them by surprise. People wanted more freedom, but they also wanted to keep what they had gained in social matters. Army officers asked the protestors to abandon their action so that normal constitutional life could be resumed, but the trade unions had their own ideas. They advocated things which the people in power opposed. The ensuing repression was therefore fierce.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There was a second phase during which the military were at odds with one another over the leadership question. The popular view was that the country had fourteen different heads of state at that time. This went on until 28 February 1978 when there was a brief Iuli and they were tempted to return power to the civil authorities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Then came the third phase when, despite appearances, poverty was on the increase. At first, Malians said that there were two 'IMFs' on the loose in Mali-the International Monetary Fund and the intimate circle surrounding the Moussa family. When the social foundation of the regime contracted, and all the country's business became concentrated in the hands of Moussa, his wife and her relations, the popular forces went on the offensive. This was a period of vociferous protest. Moussa Traore reacted with brutality: hence the 200 dead amongst the schoolchildren and students who were protesting- we will never know the exact number.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Yet, the former regime could be said to have made the crucial economic choices which your government has continued with. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-I wouldn't agree with that. There was a half-hearted discussion at the time about liberalising the economy but, in reality, bureaucracy got in the way. It is the economic laws voted in by ourselves which form the true basis of a liberal economy. However, if you really want to look to the past, I would say that it was the February 1967 accords signed between Mali and France, when we came back into the franc zone, which set the whole process rolling.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The Tuaregs and the government have just signed an agreement but the question of the north of the country is still a sensitive one. What are your views on this subject ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-The problem in the north of Mali is extremely complex. First, the Malian nation is made up of a patchwork of minorities, the largest being the Ban Mana (Ed. 'Bambara' in the colonial vocabulary), but no ethnic group is larger than all the others put together. Second, all groups have, at one time or another, held supremacy. But the fact is that the peoples involved have all lived in the same area throughout history- they have shared joys and sorrows, and their blood has mingled on Malian soil. l would accept that the Malian nation is not as well consolidated as it should be, but it is arguably one of the most advanced in the sub-region in terms of its constitution-though I don't mean to sound chauvinistic here.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anyway, the problem in the north of the country seems to me to be one of development. The various regions have not all developed at the same rate on account of climate differences. In addition, the dictatorship did not show any great respect for minorities - although it did not direct its actions solely against the Tuaregs, who resorted to arms. The Tuaregs exaggerated the mistreatment they had suffered because they were unfamiliar with what was happening in the rest of the country. In fact, Moussa Traore oppressed everyone: the French-style Jacobin state we inherited did not allow for regional differences. After independence, the regime redoubled its efforts to centralise the state. both because it was Jacobin in outlook and because of Modibo Keita's communist leanings. In 1959, the French forced the Tamashek (ea. 'Tuaregs') to secede-Max Lejeune and Houphouet Boigny were mixed up in all that. This was when oil was first discovered in Algeria and the war with Algeria had been in full swing since 1954. Modibo Keita set up the Malian Federation and declared in 1959 that, upon independence, he would withdraw all soldiers from the Algerian front. Since the Malian Federation was dismantled, Gao virtually became an Algerian willaya, a base camp for its fighters. Mali did not accept this. Moreover, Algeria, around the time it achieved independence, took retaliatory measures and sealed off its borders, mercilessly sending back huge numbers of refugees. It mobilised them through humiliation, telling them that they were the last members of the white race-the only ones to allow themselves to be under black rule.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· But when Ganda Koy's militia halted the Tuareg movement, they appeared to have been supported by the black population. Doesn't that also suggest a racist attitude ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-I addressed the Tuaregs in October 1992, and pointed out that their wish to regard themselves as overlords and the other peoples in Mali as vassals who ought to pay tribute would provoke a general uprising, with the risk of a slide into civil war. I told several of the Tuareg chiefs seated around me the legend of Ouagadou- about the serpent of the well who each year demanded that the Soninke people should sacrifice an 18-year-old girl in its honour. Then the day came when a young man refused to accept the sacrifice of his fiancee. He went down into the monster's lair, watched by a horrified crowd who saw his recklessness as folly, and cut off the serpent's head. In the beginning, the Malian people's sympathies in fact lay with the rebellion. On 26 March, when the rebellion against the dictatorship took place, the president at the time, Konare, asked for all the Tuareg chiefs to be brought to him so that they could set up a transition body. He got a nasty surprise when the Tuaregs resorted to arms.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Was the government, as rumoured, behind the Ganda Koy ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Not the government as such. To my mind, it would be wrong to applaud when one faction of the people one governs wants to exterminate another faction.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· It appears that some of the people are unhappy with the concessions that have been made to the Tuaregs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-This is a myth. The idea that we are frustrated because the Tuaregs were once our masters, is a story put about by Europe. The situation is quite the reverse. At the time of colonisation, they were unwilling to ream, like other nomads, such as the Peul people, for example. There were splits with them, of course, but no actual, all-out war. Forging a nation always requires tears, sweat and mourning. Those who return will find what they left broken or stolen and will want land which is less barren than that impoverished by the encroaching desert. However, those who stayed put in the face of rebel attacks had their houses smashed and their animals taken away. There will be problems when some Peals, for example, identify their cows which were stolen. We will have to negotiate, but I have confidence in the people. Just as they ended the war, they will be able to heal the wounds-of this I am sure. And the process has already started.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· I gather that you continue to practice as a doctor, on top of your political duties. Is this to teach a moral lesson to your political colleagues ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-I would say that it is more of a weakness, an inability to abandon a passion, even for supposedly good reasons. l am an 'internalist' and I have a passion for mechanisms. If you cure an infection and it returns, you have to look elsewhere to solve the problem. There are those in authority who spend money on trying to tackle problems without troubling to locate the cause. I would like to think that the analytical rigour of clinical science might also be put to good use in promoting understanding in politics. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Profile</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">General information</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Area: 1 240 190 km²</P>
+<P ALIGN="JUSTIFY">Population: 10 million</P>
+<P ALIGN="JUSTIFY">Population density: 8.15 per km²</P>
+<P ALIGN="JUSTIFY">Population growth rate: 3.1 % </P>
+<P ALIGN="JUSTIFY">Capital: Bamako (pop.700 000) </P>
+<P ALIGN="JUSTIFY">Other main towns: S&eacute;gou (65 000), Mopti (52 000), Sikasso (50 000), Koutiala (37 000) </P>
+<P ALIGN="JUSTIFY">Languages: French (official language), Bambara, Peul, Shongoi, Tamashek </P>
+<P ALIGN="JUSTIFY">Curreny: CFA franc. In July 1996,1 ECU was worth CFAF 647.5 ($1 = CFAF 515) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Politics</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Government: Mixed presidential and parliamentary system. Greater powers are due to be transferred to the regions after the next elections. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Head of State: Alpha Oumar Konar&eacute;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Prime Minister: Ibrahim Boubacar Keita Political parties represented in Parliament: ADEMA (absolute majority). 'Opposition' - CNID, USRDA and numerous other smaller groupings. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p021.png"></center><br>
+ Map</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economy</P>
+<P ALIGN="JUSTIFY">(1993 figures unless otherwise stated) GDP: CFAF 753.8 billion</P>
+<P ALIGN="JUSTIFY">GDP per capita: $530</P>
+<P ALIGN="JUSTIFY">Origin of GDP by sector: agriculture 42%, industry 11 %, services 47% </P>
+<P ALIGN="JUSTIFY">Real GDP growth: 2.4%</P>
+<P ALIGN="JUSTIFY">Balance of payments: deficit of CFAF 84.1 billion (estimated) </P>
+<P ALIGN="JUSTIFY">Main trade partners (% of total trade) </P>
+<P ALIGN="JUSTIFY">Exports: Thailand (24.2%), Brazil (19.1%), Ireland (9.7%), Belgium/Luxembourg (9.7%) </P>
+<P ALIGN="JUSTIFY">Imports: C&ocirc;te d'lvoire (22.2%), France (14.5%), Senegal (9.7%), Hong Kong (4.6%)</P>
+<P ALIGN="JUSTIFY">Main exports: cotton 40%, livestock 28%, gold 17.5%</P>
+<P ALIGN="JUSTIFY">Annual inflation rate: 3%</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Social indicators</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Life expectancy at birth: 46.2 </P>
+<P ALIGN="JUSTIFY">Infant mortalityper 1000 live births: 158 </P>
+<P ALIGN="JUSTIFY">Adult literacy: 28.4% </P>
+<P ALIGN="JUSTIFY">Enrolment in education (primary, secondary and tertiary): 16% </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Human Development Index rating: 0.223 (171st out of 174)</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Interview with Amadou Seydou Traor&eacute;, opposition leader and USRDA spokesman</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'Macro-economic indicators tell you nothing about the distribution of the country's resources'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· It cannot be easy to be in opposition when Parliament is dominated by a majority which is given a good press and is regarded abroad as a good pupil.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-We do not really find it a problem. If one is familiar with Mali's current situation, the people's views, reactions and judgments count for more than outside opinion, despite the fact the latter may seem important. However, we do take account of others' opinions. We are pleased to be able to speak to you-to express our ideas and points of view- so that outsiders can see that the USRDA offers a credible alternative for Mali. We feel quite secure in our current position because the principles and values we stand for are those closest to the Malian people. So we have no problem in being the opposition party. We are not the kind of hysterical opposition which resorts to foul means as well as fair ones.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Given that most Malian political trends stem from the revolutionary democratic movement, what are your party's special features ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Our party's origins are in the movement which dates from 26 March 1960-which itself grew out of an underground movement. The main component of this was the USRDA whose government was overthrown by a reactionary military putsch. Adema won the last elections, and we do not contest this fact despite a number of irregularities. Indeed, we supported the Adema government's initial actions. We were one of seven parties who regarded the Third Republic as our own offspring. Between 1992 and 1994, even when we faced grave difficulties and they were asking for suggestions, the government ignored our proposals. This happened, for example, at the time the World Bank threatened to pull out. As it functions at the moment, the government is not meeting the Malian people's basic aspirations. They want to see a change from the previous regime.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What are your essential criticisms of the way Adema works ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-We are critical on a number of fronts. Looking at it first from an institutional standpoint, when the Malian people rejected the old regime, they wanted the existing set-up to be changed into a democratic one. The few institutions that have been established since then do not reflect this desire. They are virtually no different from what we had under the single-party system. True, we have an opposition party, but its views are ignored. Second, in terms of the management of democracy, a number of bodies, such as the State Commission on the public media, simply do not function. You have been in Mali for a week now, so you must have heard Adema spokesmen on the TV or radio. But you will never hear a member of the opposition. The space reserved for that -formerly an open forum for free political discussion-has been removed and the state-controlled TV and radio stations do not allow political parties to have a say. In the economic sphere, our approach is also completely different. We believe that support for the development of the private sector means that the state has to act as regulator. Economic development cannot simply be left to run its course as a kind of 'rat race'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Could you give us a few practical examples of what you describe as Use selling-off of the family jewels ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-With pleasure. Before the 26 March revolution, there was a general consensus that, in the process of privatisation, the state sector should be managed in a way that benefited the Malian economy. But the reality is that privatisation methods have not changed. They are no different from what they were in Moussa Traor&eacute;'s time. The electricity sector, for example, which has not yet really been privatised, is now managed by the Bouyges group of France. And it costs more, which will hardly help the country's economic development. The state airline has simply been absorbed by Air Afrique. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· If you were in power, how much economic scope do you think you would have, given the prevailing trend towards international liberalisation ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-I recognise that there is a dominant international lobby which has drawn up its own conditions, laws and principles. Even if one does not agree with this approach, one has to take it into account. However, it should be feasible to achieve privatisation in a different way. We know what we are talking about because we used to run this country. Indeed, we set up the national economy. Before 1960, there was no economic system to speak of. l am currently completing the text of a work which looks at our economic position at the time of independence. The plain fact is that we had nothing at the time of independence. There were only three pharmacists, fewer than ten doctors, and about ten people qualified to teach in our grammar schools-not much to write home about after 70 years of colonialism! After 1960, we had to set everything up from scratch. If you trace the history of every country in the world, whether under a monarchy or a republic, you see that the state has always made the first move in bringing about industrialisation, developing the maritime sector, and stimulating imports and exports. If you think about it, at the outset, the main manufactured activities were the domain of royalty.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You claim that your party left a legacy, but some might say that the highly interventionist regime of your hero, Modibo Keita, who brought about independence, contained the seeds of Moussa Traore's dictatorship.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-These are just fairy stories. When a regime is overthrown by a coup d'etat, it always becomes the victim of systematic defamation campaigns in the press. We were maligned for 23 years with no right of reply and no right to issue a statement to set the record straight. In a way, we are talking today about a past which did not exist. You know the saying 'you are not only what you are but also what people say you are'. This reference to dictatorship is one of the most serious calumnies. But no matter what lies are told, something of the truth will always remain. If our regime had been dictatorial or inquisitorial, a coup d'etat would not have been possible. Before the 1968 coup, Modibo Keita was given a file by the security services warning him of the plot by Moussa Traore, and giving a list of his accomplices. He was advised to arrest the conspirators and put them on trial. His response was that he would not agree to a Malian citizen being deprived of his liberty without a scrap of evidence. I knew Keita very well. It will be a long time before we have another head of state with such democratic convictions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The ordinary people, the farmers, say that they did better under Traore, than under Keita.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Yes, but it depends who you talk to. With Traore, there was an atmosphere of moral decline. We were free to plunder, steal and murder, but it was not real freedom. The farmers see it from a different perspective. However, l can still show you a copy of the 'Summary Report on the Seminar on Cooperation in the Rural Environment' which we drew up in 1968, just a few months before the coup d'etat. This highlighted the fact that socialism had not penetrated into the countryside during the seven or eight years we were in power. So you see our own self criticism appeared in a document published in May 1968. This demonstrates the fact that we were not complacent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What is your view of the compliments the current government is receiving from many foreign observers, and the good marks it has been given in the macro-economic field by international institutions ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Good macro-economic results which are due to good management of public finances are beneficial for the country. However, such management must be accompanied by greater welfare and an improved standard of living for the people. There is no point hailing a GDP increase of 3-4% if more than 10% of the population does not have enough to eat. You have been through Bamako and other towns and cities and you have seen the construction sites and big buildings. But in their daily life, people are now more ill at ease. They have been disappointed by the Adema regime. The welfare of the ordinary citizen cannot be defined by reference to the personal wealth of someone who is having a seven-storey building put up. All of this new construction is reflected in the higher GDP. But the macro-economic indicators tell you nothing about the distribution of the country's resources-and the scales are currently tipped towards injustice. Those who are working are earning less but those who do not work are earning more. Embezzlement and corruption are currently worse than under Moussa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What is the likelihood of a changeover of political power given that the opposition groups are at odds? The union between yourselves and Parena appears to have been suspended.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-We are capable of winning the forthcoming elections without entering into an agreement with any other party. Having said this, we are the party to which most groupings in Mali are now turning and we are currently in the process of forming an alliance which will carry a great deal of weight. l am not one to speculate but I am sure that Parena's supporters will, in time, reach the same conclusions as ourselves regarding the timeliness and suitability of an alliance between us. We have contacts with a number of other parties but we do not want to form an electoral pact in the way one would make preparations for a coup-forming a group, ousting the regime and then shooting at each other! Moreover, it is important not to confuse change with restoration. There are those who advocate the restoration of Moussa's regime. Opposition of that kind would suit the current government very well because it would allow them to raise the spectre of our former dictator in the hope of attracting support from those who are frightened by such a pro spect. </P>
+<P ALIGN="JUSTIFY">Interview by H.G.</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The magnetism of the unfamiliar... but unexotic</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In West Africa, there is a dry, desert-like region which a river tried to bring under its sway. Instead of flowing seawards, the river's path went in the opposite direction to find this region, impulsively tracing a majestic loop of 2000 kiLom&eacute;tres before heading seawards. The Niger may not have provided an ideal site for Mali's major towns and villages, but it was considerate enough to form a major waterway between them which is navigable over almost its entire course. Its network of tributaries has resulted in the formation of large landlocked lakes whose waters are full of fish-a reminder of the times when the Sahara was one huge expanse of water. It has also resulted in the extraordinary Niger basin, a central delta area the size of Belgium, criss-crossed by lesser tributaries which reach into the smallest valleys. The river has created a diverse landscape which entices the visitor back. The land is steeped in history and if one wishes to learn its secrets, one has no choice but to study the empires of the past, forged it is said, by mythological deities and heros.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During the dry season, visitors marvel at the beauty of the plains, which stretch as far as the eye can see. They will be tempted to return to view the waters that will cover them for just a few months during the rains. This is when the towns and villages appear as islands in the flooded landscape. Later in the seasonal cycle, Nature divests itself of its watery raiment and prepares to welcome the egrets, pink flamingos and all the other richly coloured birds which have flown in from afar. The cultural life of this region is also imbued with a rare richness, combining mystery and individuality. Mali has a distinctive character: it is accessible but not adulterated by frippery, welcoming but not taken over, affable but able to treat everyone as its equal. There is no need to make constant reference to the past which existed before colonial times-the past simply exists, eloquent in its tranquil humility.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A survey of Mali should logically begin in Bamako, the likely port of arrival. But if one immediately journeys to the towns and villages that were the cradles of empire, one is better able to appreciate this young capital, barely 250 years old, whose history owes much to its smaller forebears. We arrived in the evening and departed at dawn the next day. So Bamako was no more than a blur. The River Niger, still known as the Djoliba in the capital, is crossed by two long bridges which offer a view over the wild river banks. Most of the constructions are brand-new and some have a style borrowed from their thousandyear-old 'Sudanese' architectural heritage. It would have been more romantic to travel by river to the central part of the delta but, despite the welcoming nature of the Niger as it flows through Mali, it is difficult to navigate over the Sotuba rapids, between Bamako and Koulikoro approximately 50 km away. When the waters are in spate from July to December, it takes no more than two days to reach Segou, three to reach Mopti, five to reach Gao and an extra day to arrive in Timbuktu.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Segou, the rebel</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Our first stop after Bamako is Koulikoro, the departure point for Niger cruises. After the unusual houses of the bazo fisherman on the banks of the river, as one leaves Bamako, it is the river itself which is a source of curiosity, transforming the voyage into a wonderful promenade through a forest abounding in game. Then there are the thatched, circular mud huts. Those without a roof are built on piles and are often ovens for preparing karite-nut oil whose bitter-sweet fragrance mingles with the fruity scent of the mango trees which line our route. In Koulikoro, every day is market day. The market spills out into the road and then shrinks back to allow vehicles to pass. It is also a centre for hunters and poachers who come here to seek customers. Above all, it is the centre for the guilds of masons who jealously guard the secrets of traditional Sudanese building skills. For the visitor who cares to linger, the griots will sing the praises of the old magician-king Soumangourou whose spirit has haunted this small town for eight-and-a-half centuries. When he was overthrown by the hero Soundjata, he just vanished into thin air-in the land of mystery that is Mali, great kings do not die, they simply disappear.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first 250 kiLom&eacute;tres of the river's course from Bamako are enchanting. One's first real encounter with Mali's past come at Segou-when the balanzans come into view. The charming, independent city is close by. Segou, the Bambara capital, did not form part of most of Mali's empires. Indeed, the word Bambara comes from 'Ban-Mane', which means 'those who reject a master'. There are 4444 + 1 balanzans to announce the city, all of which are numbered except the last one, which still guards its secret. The balanzans conceal another secret: during the dry season they are covered with leaves, which they lose during the winter. A curious traveller might arrive at Segou with memories of Maryse Conde's fine prose (Segou, Robert Laffont, France, 1984). Her work is an epic fresco of life at the court of the Bambara kingdom in the nineteenth century. The city itself stretches for eight kiLom&eacute;tres along the river bank, with a promenade high above the river on an embankment from where there is an uninterrupted view over the water to the horizon. The richly coloured fabrics of the washer women create a dreamlike atmosphere, giving an impression of the shimmering tunics worn by princes, and the women who swim in the river are not given to excessive prudishness, another reminder of the city's enduring rebellious nature. The charm and cleanliness of the town are striking, its administrative buildings stretching along a grand boulevard lined with modern structures. We see in their profiles, the traditional architectural styles as well as a variety of colours. The whole scene is shaded by gardens full of flowers. It is easy to forget that Segou has retained none of its former architectural wealth. This was all destroyed by the organisers of a jihad who sacked this city of infidels who had never been won over to Islam or, later, to Catholicism. The city walls and the regal courtyards are all gone, so what remains is jealously protected: the sceptre and regal symbols of King Diarra, the kingdom's treasures and its secrets. On Mondays, market day, it is possible to see people kneeling at the feet of an old man. He is the custodian of the town's remaining riches, but will never reveal where they are held. Oumar Santara, one of Segou's intellectuals, is attempting to gain an insight into these mysteries in order to protect them better because, he says, the pillage is still going on. Mali's cultural heritage is being ransacked by outsiders. In some villages on the opposite bank of the river, it is still possible to find 13th-century coins in the village squares.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Trial marriage</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nearly 500 kiLom&eacute;tres separate Segou from Mopti. Midway between the two is San, barely more than a large village. San is bathed by the waters of the Bani, a major tributary of the Niger which it flows into it at Mopti. In the market, fine cotton fabrics can be bought, as can the skills of the blacksmiths. Here, however, there is above all an air of secrecy. The town's inhabitants are members of the Bobo people. The name translates es 'stammering', 'mute' being implied. This is the town which holds the secrets of fatal poisons- cocktails of poisonous plants and snake venom. There are also unguents of all kinds to relieve pain, alleviate scarring, and so on. San has another reputation, that of handing out severe punishment to adulteresses. This seems paradoxical when one discovers that women here enjoy exceptional sexual freedom during adolescence and up to the time of their marriage, and even afterwards. They enter into a trial marriage for three or four years, during which time they are free to 'play the field'. At the end of this period, on the occasion of a feast, they reveal whether or not they will accept their 'provisional' husband. If not, the woman regains her freedom and can start all over again as many times as she wishes. If she decides to become the man's wife, she chooses some of her husband's friends with whom she may 'have a fling' for two weeks, the aim being that she thereby lays to rest her unmarried freedom. She will then swear an oath of fidelity to her husband which she breaks on pain of being cast out of society and even, it would appear, at the risk of losing her life.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A 1 2-kiLom&eacute;tre dyke, which seems to float on the water during the winter season, links Sevare, the crossroads of the major routes across Mali, to Mopti. Situated below water level, Mopti owes its existence to the embankments which protect it. The dyke offers a fine promenade which opens out onto the quayside of this bustling town. The streets are crowded and the settlement has a vitality and beauty, with coloured lights mirrored in the water. On land, the crowds drift in much the same way as the multitude of boats anchored in staggered rows along the riverbank. These stretch for hundreds of metres- as far as the eye can see. All this wealth of detail forms a tableau punctuated by the outlines of the slender fishing smacks (pirogues or dugout canoes). Despite their size, these vessels retain their uncluttered lines, always giving the impression that they are slicing through the water. The biggest of them are perhaps 50 metres long, carrying cargoes of up to 150 tonnes. This strange, animated scene, which resembles no other in the world, seems to have been staged as a way of reviving the buried images of the Mali of legend-provoking a memory of things unseen and prompting new sensations. Despite the fact that it is replete with Malian influences, Mopti did not develop until colonial times. Like Segou, it never really belonged to any of Mali's great empires, although it became their meeting point. It is a place where all the country's languages are spoken. Indeed, the word 'mopte' in Peal means 'place of assembly'. At Zigui's restaurant or in a cafe down by the port, one find groups of beribboned Tuareg artisans still with their belle servants (former slaves) in tow. One can watch the Peals, also followed by their servants, negotiating their deals. Some trade in gold jewellery, dogon or other ethnic sculptures. Others buy and sell the magnificent Segou carpets or cotton fabrics. Others still dabble in ancient archaeological artifacts (which it is forbidden to sell) and in sacred objects from all over the country. The town itself is an artifact: the apparent hotchpotch is regulated by an internal, almost natural organisation. The hundreds of boats, fishing smacks and other small craft are arranged along the river banks according to the goods they are importing. There is one place for fishing boats, another for furniture imports, and so on.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mopti merits an overnight stay. In the curve of the great arc which forms the port, a soft light lingers on the congested river banks. It is not just the people who seem to tire of the day's hustle and bustle. The biggest boats with their gentle backwash, anchored in the mud until the next incoming tide, grow too lazy for their images to be reflected in the water and they seem to hold on to the last of the sun's glow, awaiting the first glimmers of moonlight</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Dogon region, poetry in stone</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As one approaches Bandiagara, on the threshold of the cliff faces which bear the name of this town, the landscape changes. Most of Mali is flat, but here, we find ourselves in the high land. In fact, the altitude is only a few hundred metres, but the landscape is dominated by sheer and rugged rock faces. This is Dogon country where everything seems to be made of stone: the roads, houses and hills appear in matching tones of salmon pink. The inhabitants, too, seem to have been hewn from the very rock. At first glance, the landscape is unremarkable apart from the sight of all this rock, but as one's perception grows keener, shapes can be made out. At the foot of the slopes are caves that are still lived in. And in the most vertical part of the cliff faces, we can pick out regular, sculpted barrel shapes, combining to form an impressive design. These stone cylinders are the ancient dwellings of the Telems, a mysterious people who preceded the Dogons and were conquered by them. Nothing is known about their disappearance. Today, the cylinders are used as Dogon graves. Access is gained to them during funeral services, by means of a system of ropes. At the top of the cliff is Shanga, the beauty of the Dogon region. It stands atop a 400metre sheer drop which extends over a length of 200 kiLom&eacute;tres. Reaching Shanga from Bandiagara involves picking one's way through the rocky landscape and sliding over sandstone scree.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Before the Europeans arrived to colonise the country, no one had succeeded in subjugating the Dogon region. Was it really ever under the sway of the colonists ? This region, whose beauty lies in its harshness, has no embellishments. And its language is as hard on the ears as the rock is underfoot. As everywhere, to feed themselves, the Dogons till the soil. But this must be carried on the backs of men and women over distances of several kiLom&eacute;tres and then deposited on the rock. Every onion bulb and every root pulled from this thin layer is a testament to the tenacity of humankind.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Dogon region is like a magnet-it attracts pilgrims from afar who come to venerate El Hadj Oumar, the founder of the Islamic brotherhood of the African Tidjani-a military and religious leader whose life and disappearance are shrouded in mystery. It also attracts people because of the beauty of its works of art. Some of these, apparently of recent manufacture, are actually centuries old. For the custodians of the sacred objects, the interest of outsiders is viewed as a catastrophe. The artefacts are constantly pilfered and sometimes, their keepers commit suicide in their horror at such desecration.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fine regalia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Djenne translates as 'the beloved of the waters' and is surrounded by two strekhes of the Bani river. Thus, apart from a short time in the dry season, when the river can be forded, it is an island accessible only by boat. The town has always been a rival of Timbuktu, the 'daughter' of the desert. Before Mopti was created, Djenne was the country's meeting point. The town is dominated by its mosque which is a masterpiece of Sudanese architecture. This imposing clay structure has been a magnet for the faithful since the thirteenth century. It has always been rebuilt in the same style, each version scrupulously identical to the previous one. The most recent reconstruction dates from the early 1900s.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Centre of the Malian empire, Djenne has retained all its finery, magnificence and prestige. It was annexed by the Shongoi empire at the end of the Middle Ages and its conquerors have always been seduced by the town's beauty. The mosque has been designated a World Heritage Site, and the entire town has protected status. For centuries, its architecture influenced other towns and cities in the Sahel and it continues to do so. The secrets of the knowledge and skills of its master masons are still jealously guarded, passed on only reluctantly to the initiated. The whole town is built around the mosque, revealing an interplay of balance and power. There are magnificent inner courtyards to which entry is gained through massive, ornate studded gates. The elaborate and finely carved windows, the intertwined leaves and scrolls of the arabesques and the moucharabies, all bear witness to the Moroccan influence. This has, however, been toned down and it now blends in with Djenne's indigenous forms of decoration and architecture. Whilst all Mali's former great towns and cities were known for their power and military glory, Djenne takes pride in having dispensed with brute force, its spirit protecting it from subjugation. All those who pass through take something of Djenne's spirit away with them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coca Cola kept at bay</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Returning to the capital from where we started, we discover that it was colonisation that turned Bamako from a village into the large city that it is today. It inhabitants now number approximately one million. Although a city of recent origin, the site on which it is built dates back to the dawn of time. The hills overlooking the city are home to cave paintings and the underground tombs provide more evidence of a human presence dating from ancient times. There is then a gap of several thousand years in Bamako's history. In early colonial times, just two centuries ago, the village had no more than 700 inhabitants. Bamako began to be developed at the beginning of the 1900s and it is the only city in Mali to have a colonial atmosphere. It has not, however, lost out to change. The ministerial buildings at Koulouba hill, one of five dominating the city, or the Point G houses in the National Museum area, may not equal the beauty of Sudanese architecture, but they are elegant nonetheless. Their plain style is softened by their leafy gardens. The administrative buildings in the lower part of the city are often a fusion of colonial or modern styles and traditional architecture. These edifices are also made more attractive by fine gardens, which lend originality to the city. One of the most successful combinations is the great market, unfortunately in the process of restoration at the time of our visit and whose beautiful interior we were unable to appreciate. It is interior beauty which characterises this city in comparison with other African capitals. Despite its congestion and the density of its population, Bamako still has the atmosphere of a lively village. There is little of what one might term a 'social scene', but it is enough to be invited into the 'squares' or respectfully to visit the block-shaped houses which are still home to entire families and where discussion sessions (grins) last into the small hours. These sessions are enhanced with food and the omnipresent cup of tea. Bamako still prefers tea to imported beverages and to receive guests in the family home rather than joining in the social round in the hotel foyers so characteristic of major capital cities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For those hesitant to venture into the traditional life of Bamako (although they would be assured of a welcome), there are many restaurants which make a good attempt at recreating a homely atmosphere. One is not, however, required to take part in the conversations. Two restaurants (the Djenne and the Santoro), which have opened recently, allow one to enjoy the pleasures of art and history. They are part of a wider project to promote Malian art and set up an organisation for artists and craftsmen. They contain areas modelled on the refinement of former imperial furnishing, interior design and architecture, as well as exhibits by Mali's greatest artists. Their creator, Aminata Traore, is an intellectual, art connoisseur and international expert. In Dakar or Abidjan, patrons of such establishments would probably be expatriates with perhaps a few local dignitaries. But at the Santoro and Djenne, prices have been kept reasonably low (no account having been taken of the 50% devaluation in the CFA franc) and the art remains accessible to middle-class Malians. Thus, the spirit of the 'grins' is preserved. The preferred beverage is still a cup of fragrant tea or perhaps a glass of refreshing juice. Whisky will never replace tea, nor will Coca Cola replace fruit juices. Mali is not a country which rejects other people, but it resists cultural encroachment, preferring the </P>
+<P ALIGN="JUSTIFY">familiar to the exotic. </P>
+<P ALIGN="JUSTIFY">Hegel Goutier</P>
+<P ALIGN="JUSTIFY"> </P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Mali-EU cooperation</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY">Roads and adjustment</P>
+<P ALIGN="JUSTIFY">by Theo Hoorntje</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For 1990-95, ECU 151.7m was allocated (mainly in project aid) under the seventh EDF National Indicative Programme (NIP). This is equivalent to about 1.5% of Mali's GDP and 13% of its public-sector investment programme for the period in question. European funds from sources other than the NIP-emergency aid, Stabex, European Investment Bank (EIB) venture capital and resources from the structural adjustment facility- reached ECU 87.2m over the same five-year period.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1995, support for the structural adjustment programme represented 5.4% of the balance of payments deficit and 7.8% of the budget deficit. Looking at all instruments together, the amount involved in financing decisions taken by the Commission last year was ECU 42m, with the disbursement figure rising to ECU 40m.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The NlP's primary commitment level under the 7th EDF rose from 76% at the beginning of the financial year to 92% at the end, which means that virtually all available programmable resources are now allocated to projects and programmes. The secondary commitment level, which involves the conversion of proposals into concrete agreements and contracts, rose from 33% to 45% by the end of the financial year. Disbursement rates remain relatively low (32% of available resources).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Allocations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Aid is distributed to the various sectors, as follows:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Roads (29% of the total);</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Support for structural adjustment (20%);</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Rural development / Environment (1 4%);</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Support for the private sector (12%);</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Decentralisation (9%); </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Public health (9%); </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Water supplies (4%); </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Education/Culture (3%).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is clear that Community aid concentrates mainly on road infrastructures-covering both maintenance and the opening-up of remote regions. Support for structural adjustment, which comes second, is used to finance the State budget's current expenses, particular emphasis being placed on improvement of fiscal and customs income and greater efficiency in health-policy matters.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In other areas, such as rural development, Community aid also makes an attempt to consolidate gains from previous actions, particularly through the development of rice growing and stock rearing, which should improve supplies to the domestic market and offer further export potential. As far as the environment is concerned, the aim is to contribute to the sustainable management of natural resources on the part of basic users, such as farmers, breeders, etc.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The private sector is supported by actions in key areas and by a programme that was recently set up which involves directing resources through a financial institution (Credit Initiative SA). The objective is to promote lending to SMEs, which is in keeping with the general aim of achieving economic growth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the context of administrative reform, priority is given to the decentralisation process which aims to promote the emergence of new local decision making centres (which should, in the long term, become key players in project development and implementation), and to give such decentralised bodies the means they require to fulfil these new public-sector missions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As for health, Community aid has contributed to the PSPHR project financed by other donors. Its main focus is initially on infrastructures and on the policy relating to the supply of essential medicines.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the water-supply sector, actions are aimed at strengthening village infrastructures, particularly in the Bankass and Koro areas. A solar-pump programme has also been set up in the Mopti and Koulikoro regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition to a school reconstruction programme in the north of the country, the Commission has been able to support education and culture through a dozen or so film projects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under the general 'heading' of non-programmable resources, there have been a number of interventions. These include extra support for structural adjustment, Stabex transfers, deployment of the balance from the 5th EDF and EIB projects. Emergency aid has been deployed in the north of the country where, despite difficult conditions, programmes have been able to continue without interruption.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, Community regional aid is helping to combat rinderpest, as well as being directed towards road maintenance, and the provision of training and information on environmental protection. </P>
+<P ALIGN="JUSTIFY">T.H. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">NGOs finally achieve tangible results</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Catherine Beauraind and her five colleagues in the small team of foreigners and Malians, woke early. It had been a short night: our fault, since we had arrived at Bandiagara on the edge of the Niger valley much later than expected having taken the Sevare route. This is the gateway to the rocky Dogon region and travellers on the road occacionaliy fall victim to bandits-which probably made our hosts somewhat apprehensive about our late arrival. The people we had come to see are road builders, working without sophisticated equipment in a region of rocks and cliffs. They seem very youth froml, particularly those who have come from afar.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These are 'Progress Volunteers', the name given to the many young people who come to this very poor African country to offer their commitment and dynamism, if not perhaps their experience. On this particular morning, still feeling fatigued, Catherine was having to coordinate the departure of escorts for seasonal workers who were being dispatched to various locations. Their job is to ensure the upkeep of the rocky roads, and the equipment they use is rudimentary to say the least. The Bandiagara-Dourou stretch is maintained by the AFVP (French Association of Progress Volunteers) and is one in a long list of NGO projects. In 1995 alone, the European Commission supported over 50 NGO schemes, to the tune of ECU 1.5 million. Most EU countries and a number of others also have their own projects. On top of this, there is the emergency help provided by the European Commission Humanitarian Office (ECHO), which has just approved a grant of ECU 1 million for the north of Mali. Now that a peace accord has been signed between the government and the Tuareg rebels, this region is likely to see a huge influx of refugees returning to villages that are ill prepared to receive them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mali is a least-developed nation and one of the most highly subsidised countries in terms of per capita aid, though recently, its political fortunes have been boosted by the democratisation process. And the efforts of the NGOs now seem to be paying off. The recent times of famine have faded in people's memories even in the Dogon region, where many families ate calabashes in desperation before succumbing to starvation. Mother nature is playing a part in the country's renewal: there has been ample rain over the last Many NGO projects are aimed at helping the population use its meagre resources to exploit the natural wealth of the River Niger and its tributaries. At Konna, for example, a striking village at the confluence of two rivers, the Regional Literacy and Self-Management Project is up and running. Financed, among others, by the European Development Fund, this is being implemented at a number of localities, and it has played a part in the renewal which can now be seen. Fresh coats of paint, repairs to houses, fewer starving children and the return of many migrants all underline this new vitality. Each of the 17 small cultivated areas in the village that are covered by the project (worked by about 60 people), receives no more aid than a motorised pump, a few cereals and a small amount of cash in the first year. A basic course in management is also provided. It is up to the villagers to use these resources to yield a profit. Results tend to be good, proof of success being the growing number of such schemes which are being set up without aid from the organisation. The project is now in its seventh year. It did experience one bad year-1992-when, despite bumper harvests, rice imports into Mali were excessive and prices dropped. The village has therefore made an attempt to diversify its crops. Its objective is to sell onions in Cote d'lvoire, where the inhabitants are very fond of this vegetable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most villages have been able to save money which was initially placed in banks and then invested elsewhere in the wake of devaluation's harsh lessons. Konna opted for purchasing livestock. In nearby Kotaka, surpluses partially funded the construction of an impressive mosque. Kotaka was one of the places most affected by the recent meningitis epidemic, but a hospital would probably have been too expensive. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hegel Goutier </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Western Samoa</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">A new spirit of enterprise</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Small countries with a limited resource base are frequently buffeted by economic forces over which they have no control. If you live in Western Samoa, however, you are likely to be preoccupied by forces of a different kind. For while most of the time, Mother Nature presents a benign face in this attractive and fertile Pacific state, every once in a while, she loses her temper.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tropical storms are an unavoidable reality in much of the Pacific and they breed a special form of resilience which should impress the inhabitants of more temperate climes. The people of Samoa, and other cyclone prone countries in the region, are adept at picking themselves up and, if necessary, starting all over again, once the winds have passed. But between 1989 and 1993, the Samoans' capacity for renewal was to be tested more than ever before. Like a plucky boxer facing a much stronger opponent, the country would just be struggling back to its feet when another hammer blow would send it reeling.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The closest to a knock-out punch came in December 1991 in the shape of Cyclone Val-the worst storm to hit the islands in more than a century. This brought death and injury, as well as widespread economic devastation. The coconut and coffee trees on which the country depends for much of its export income were either swept away or stripped bare. Many homes were also destroyed and infrastructures were severely damaged. (The 1993 cyclone, although less powerful, caused further crop destruction.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over the last five years, virtually all the damage has been repaired. Indeed, a great many facilities have been upgraded with plans for further improvements in the pipeline. To some extent, the credit for this remarkable recovery must be shared. Overseas donors played an important part in restoring key infrastructures while expatriate Samoans, whose remittances are an important 'invisible' earning for the country in normal times, also rallied round. But the key players, of course, were the people themselves, who rose to the challenge of reconstructing their country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Today, Western Samoa - which has a population of 165 000-is experiencing an economic mini-boom. Growth during 1996 is expected to be between 5% and 6% for the second consecutive year and there are encouraging signs of a new, home-grown entrepreneurial spirit. This is not to say that everything in the garden is rosy. The latest growth figures need to be set against the unavoidable recession caused by Cyclones Val and Ofa (which struck in 1990) and a mediocre economic performance throughout the 1980s. And while there is some evidence of diversification, the economy is still very narrowly based. There is also considerable room for improvements in health care and education provision. Doubts have been expressed, for example, as to the accuracy of the official literacy figures. Finally, there is a high level of dependence on foreign aid (the country's main donors are the Asian Development Bank, Japan, Australia and the European Community).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economists will tell you how notoriously difficult it is to express the wealth of a developing nation in statistical form. GDP figures can offer a pointer, but they do not present the whole picture as they take no account of the informal economy. Western Samoa provides a particularly good illustration. At US $950, the estimated per capita GDP is very low by Pacific standards. Yet there is clearly no starvation. A great deal of the food consumed by the Samoans simply does not 'show up' in the cash economy. The term subsistence agriculture seems peculiarly inappropriate here since locally available food sources are many and varied.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Similarly, many of the materials used to build the 'fares' (traditional houses) in the villages are obtained without recourse to builders' merchants. And when a Samoan wants a new house, he builds it himself-with the help of his family and neighbours. This involves skilled carpentry work-for which people would pay highly in industrialised societies - and which does not register either in the country's economic statistics. So it is clear that the basic GDP figures do not paint a complete picture. Nonetheless, they illustrate the relatively underdeveloped state of the formal economy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agriculture</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Looking at exports, Western Samoa's traditional agricultural sector has gone through some rough times, for a variety of reasons. In the past, the mainstays were copra and coconut products (oil and cream), cocoa and tarot</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The storms destroyed or damaged many of the coconut and cocoa trees, wiping out exports for a number of years until new plantings could reach maturity. The market in food products derived from the coconut had been depressed in any case. One reason for this was negative publicity over the high cholesterol content of coconuts, although more recent research, suggesting that not all types of cholesterol are bad for you, has at least partly restored the reputation of this highly flexible crop.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Taro, which is Western Samoa's staple food crop, was exported in ever increasing quantities during the 1980s but the trade has suffered badly in recent years because of an outbreak of taro leaf blight.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Today, Western Samoa's most important primary exports are, once again, coconut-based (oil and cream). With the new trees reaching maturity, production recommenced on a small scale towards the end of 1994. The following year saw a big jump in exports and the figures for 1996 are expected to - come close to pre-cyclone levels,The marketing situation has also improved as a result of privatisation. The old Copra Board, a parastatal with a reputation for inefficiency, was abolished in 1990, its assets being bought for a nominal sum by a Samoan businessman who has invested heavily in refurbishment. This has all been achieved despite continuing low prices for coconut products in the world markets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cocoa takes longer to recover but harvesting of the first new crop is due to take place this year with the emphasis on a high value, fine tasting variety. A new chocolate factory (Wilex C.C.P. Ltd), also masterminded by a local entrepreneur, Eddie Wilson, has been built with assistance from the EU's Centre for the Development of Industry (CDI) and a credit from the European Investment Bank (EIB) channelled through the Development Bank of Western Samoa (DBWS). This is a particularly significant venture since it aims to maximise added value before export. The factory is currently operating well below full capacity, awaiting the arrival of the first local crop, but there are high hopes for its long term success.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The other main crops exported are bananas and kava. The latter is a mild narcotic based on the root of the pepper plant, which is used in pharmaceutical preparations. It also has an important place in Samoan (and wider Pacific) culture, being drunk in diluted form on ceremonial occasions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With a view to achieving further export diversification, a number of other agricultural/horticultural export possibilities have also been identified. These include asparagus, mangos and cut flowers. The most likely potential market for new tropical production is New Zealand-already the destination for more than half of Western Samoa's exports. However, this country has stringent health rules with rigorous controls on the import of plant and animal material. The understandable aim is to protect the local farming sector from diseases introduced from outside, but it creates an additional hurdle for potential exporters in the developing countries of the Pacific. In particular, Western Samoa needs to come to grips with the fruit fly problem, if it wishes to make inroads into the New Zealand market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Timber also once featured prominently in the trade statistics before declining at the end of the 1980s. There are hopes for a revival here with the authorities keen to encourage value added processing of wood products within the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite its obvious association with the sea, Western Samoa has never really gone in for commercial fishing. While the Exclusive Economic Zone is small by Pacific standards, the country being 'hemmed in' by other island nations and territories, it is still more than 40 times the land area. The government would particularly like to attract foreign investment in fish processing and canning.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Industry</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is probably unrealistic to expect a small and geographically isolated nation such as Western Samoa to develop a highly diversified industrial base but there have been one or two notable ventures which show signs of potential. The above-mentioned chocolate factory is one such. The country also has a highly successful brewery. It is not uncommon for developing nations to produce their own local beer but Western Samoa's Vailima brand has managed to break out successfully into the regional market, bringing in useful foreign exchange in the process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The biggest industrial success story-dwarfing all other manufacturing ventures-has been the establishment of a factory by the Japanese company Yazaki to produce wire harnesses for cars. The business employs some 2500 people (mainly women) in a highly labour-intensive operation-and it makes a significant contribution to the trade balance. The value-added electrical components are re-exported for incorporation into cars sold mainly in Australia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The company was attracted by a number of factors including low labour costs in this non-unionised society, and the political stability of Western Samoa. Perhaps most important, however, were the incentives offered by the government. These went well beyond the usual tax holidays provided by developing countries to attract foreign investors. Indeed, it was the government that built the factory and the company was allowed to occupy it rent-free. Some observers have expressed concern at such largesse but the authorities are insistent that it was still a good deal. They point to the jobs that were created (a huge number by Samoan standards) at a time when many people's livelihoods were threatened by taro blight. They also argue that the profits of the operation are retained in Western Samoa, thereby helping to boost the wider economy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Services</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The service sector offers perhaps the best potential for expansion of Western Samoa's formal economy. Top of the list here comes tourism (featured in a separate article), which has been expanding much faster than the underlying rate of economic growth. Despite the increase in both visitors and income, tourism is still underdeveloped. The government (supported by the opposition) believes that this is one field where Western Samoa definitely has a 'comparative advantage'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Linked to tourism, of course, is the air transport business. Although it might still be possible to obtain passage on a merchant ship bound for the South Sea islands, the vast majority of visitors arrive by plane, and good air connections are obviously essential. The history of the country's national carrier, Polynesian Airlines, offers two object lessons. The first is how not to run an airline and the second, more recent and encouraging one, is how to grasp the nettle when the crisis finally breaks. In 1992, with tourism in mind, the government owned airline decided to expand its operations substantially. It leased three long-haul aircraft which it hoped to fill with visitors in search of a new tropical haven. The market research was clearly inadequate and the planes flew with many empty seats. Other aspects of the company's management proved deficient and there was a chronic lack of financial. Debts mounted at such a frightening rate that the budgetary position of the entire country was threatened.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1994, the government took decisive action, bringing in Richard Gates, the experienced airline entrepreneur, who is credited with having turned Air New Zealand around. Relatively small airline businesses in the Pacific are not likely to make a.fortune for anyone, but with proper management, they should at least be able to break even and perhaps even turn in a small profit. This was not something that even the prodigious talents of Mr Gates could achieve, however, with the crushing burden of debt accumulated by Polynesian Airlines. So the government assumed responsibility for the debts and then gave the new manager a free hand, on the firm understanding that the taxpayer would not come to the rescue again.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the airline side, the operation was drastically slimmed down. The leases on the large aircraft were terminated, staff 'down-sizing' took place and bath ticketing and financial management were tightened up. The positive impact of these measures was soon evident, with a small operating profit registered in 1995.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Left with huge debts, the action of the authorities was equally impressive, although it entailed discomfort for most Western Samoans. In order to restore its own financial position, the government instituted 15% public expenditure cuts across the board. In macro-economic terms, it is generally acknowledged that this strong medicine was needed, but the social consequences were all too clear as well: reduced funds for health and education, and pressure on important capital investment budgets. Perhaps fortuitously for the country, the financial crisis caused by the Polynesian Airlines debacle coincided with the payment of a substantial Stabex payment from the European Community. The country's was eligible for Stabex funds because of the collapse in agricultural export receipts following the cyclones, and the money-which was directed mainly into infrastructure projects-could hardly have come at a better time. Meanwhile, the government has paid off a large portion of the airline's debt with the residue rescheduled for payment over a five-year period.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The government has taken a number of steps aimed at attracting offshore finance business to the country. Western Samoa now has a comprehensive legal framework governing such activities, including crucial provisions guaranteeing secrecy. Another vital factor in attracting offshore funds, which has already been mentioned, is political stability. There is even the suggestion that the country's time zone, which puts it almost a day behind Australia and New Zealand, might somehow be turned to its advantage in global financial dealings (although it is not clear how the benefit would be derived in otherwise legitimate transactions).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The last three years have seen a big increase in company incorporations and there are now more than 2500 offshore companies (including 15 banks and eight insurance companies) registered. It is difficult to imagine Western Samoa ever challenging the likes of Liechtenstein, the Bahamas or Jersey in this market, given its geographical distance from the main industrialised nations, but even a successful 'niche' operation could bring some useful income to the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Politics</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Five years ago, when the Courier last covered Western Samoa, the emphasis was heavily on recent constitutional changes and most notably, the introduction of universal franchise. At the time, there was a lot of interest in how the traditional Samoan way of life (faa-Samoa) would be affected. This is based on the village structure and the matai system which vests considerable authority in family heads. There is also a strong attachment to the Christian faith, as exemplified by strict Sunday observance rules (also found in Tonga and other Pacific countries).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In fact, the Samoans appear to have embraced their more 'westernised' system of government without any difficulty. Although everyone over 21 has a vote, one still has to be a matai to be eligible to stand for Parliament. In contrast to hierarchical structures elsewhere in the Pacific, however, the system here seems to be based largely on merit and it is not particularly exclusive (there are an estimated 19 000 matai). The matai, nonetheless, exercise considerable authority in village affairs, most notably over the use of customary land.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In short, the change seems to have caused few problems because Western Samoa already had its own decentralised form of democracy. It was not a question of educating people about hitherto alien concepts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The fact that change in Western Samoa is slow and progressive rather than sudden and violent, is recognised by most observers to be a good thing. An illustration of this evolutionary approach is the arrangement governing the position of Head of State. The post, which is held by His Highness Malietoa Tunamefili 11, currently appears to be a cross between a presidency and a monarchy. Under the 1962 independence constitution, two of the country's four paramount chiefs were given the position, to be held jointly, for life. With the death of Tupua Tamasese Meaole in 1963, the surviving incumbent became sole Head of State. There will be no automatic succession, however, and Parliament will decide who should have the post in future, with the term of office limited to five years. There is obviously a great deal of respect for the Head of State and his office among Western Samoans, although it should be stressed that his role is largely ceremonial, with political authority being vested in the elected government. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As for party politics, there are two groupings represented in Parliament, the ruling Human Rights Protection Party and the opposition Samoa National Development Party. The party system is not particularly strong, however, being based more on personalities than ideology. Corruption is not seen to be a major problem although a major row did blow up recently over a critical report issued by the Auditor-General for 1994. This led to him being suspended and this issue had not yet been resolved at the time The Courier went to press.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Western Samoa is not unique in having to adapt to a rapidly changing world. The phenomenon affects all societies, with modern communications technology increasingly breaking down the 'protection' that geographical isolation used to afford. In Westem Samoa, as elsewhere, there must be concern about the impact of this on the country's traditional way of life. Yet the indications are that this Pacific nation is managing the transition rather better than many other developing countries. The people seem to combine an unselfconscious pride in their traditions and cultural assets with a pragmatic welcoming of ideas from outside which help to improve their material wellbeing. The hope must be that this process can continue as we approach the third millennium. S'imon Homer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Historical summary</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">According to archaeological evidence, the islands of Samoa were first settled about 3000 years ago, after gradual migration within the Pacific from people originally from South East Asia. Samoa, it seems, was the cradle of the Polynesian culture, and settlers from there spread to other islands of Polynesia in the east, north and south.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first European to sight the group in 1722 was Jacob Roggeveen, and although there was intermittent contact between European sailing vessels and the islanders during the 18th century, more permanent contact was established with the arrival of the European missionaries in the early 1980s. They were soon followed by traders looking for copra, beche de mer, sandalwood and other products. Later, some of the trading firms, notably German, fumed to large-scale production of copra and other products such as cotton, cacao and rubber, which also led a corresponding increase in interest on the part of colonial powers. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the late 1800s, the Samoan group became the focus of colonial rivalry between Great Britain, the USA and Germany, leading, in 1900, to the partitioning of the islands between Germany and the United States. The eastern part of the group came under American control and has remained so to this day, while Germany controlled the western islands. Britain received territorial concessions elsewhere in the Pacific. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the outbreak of World War I, New Zealand took over what had come to be known as German Samoa, and became the administrative power there under the League of Nations and later the United Nations until Western Samoa became the first Patific island nation to become an independent state in 1962.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(Source: Government of Western Samoa. this text is taken from the information brochure prepared by the authorities for distribution to delegates at the recent ACP-EU Council of Ministers meeting). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dream ticket ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Depart Nuku'alofa-12.00, January l 2000 Arrive Apia - 14.00, December 37 1999</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">People with cash to burn are often ready to spend surprising amounts of money in their pursuit of the unusual. Tonga has already recognised this as it begins preparing for the third millennium Lying just to the west of the International Dateline, it believes it will the first country to see the sun rise on the new millennium, although other Pacific territories have also made the claim. (For this purpose, we ignore the purists who point out that the third millennium will not actually begin until January 1, 2001.) Celebrations are planned and bookings are already being taken.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Westem Samoa is obviously not in the running for this distinction since it is east of the dateline, but what this means is it will be the last nation in the world to say goodbye to the old millennium. This surely presents an opportunity for the local tourist industry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">And what about those intrepid voyagers who fancy greeting the year 2000 in Tonga and then 'seeing out' the old millennium 24 hours later in Samoa. If i were an airline manager, I would be examining the possibility of extra flights from Nuku'alofa on the big day. (Let's hope it's not a Sunday I)</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">An interview with Tuilaepa Sailele Malielegaoi, Deputy Prime Minister and Minister of Finance</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY">'Economic future in tourism end manufacturing'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Courier visited Western Samoa at the end of June while the country was hosting the ACP-EU Council of Ministers meeting. At the time, veteran Prime Minister, Tofilau Eti Alesana, was recovering from an operation, and his duties were being carried out by his deputy, Tuilaepa Sailele Malielegaoi, who is also the Minister of Finance. Despite a hectic schedule, the Deputy Prime Minister kindly managed to find a slot for a keynote interview with The Courier.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· There is growing evidence of a new economic dynamism in this island nation, which has managed to find its feet remarkably speedily after the destruction wrought by cyclones in 1989 and 1990. With this in mind, we began by asking the Minister about the economic prospects for the country ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-I think they are excellent. Our country suffered a major catastrophe as a result of the cyclones, coming, as they did, in two successive years. There was major damage to our infrastructure and forestry resources- coconuts and cocoa. At the time, we estimated the bill at more than $600m. But the rehabilitation of the infrastructure went ahead quickly, thanks to the major support provided by bodies like the World Bank, the Asian Development Bank, and of course, the European Union, not to mention the bilateral donor countries who answered our call for help. So in some ways, it was a blessing in disguise. We suffered badly, but with the assistance that came, we have been able to improve our roads and electricity supply, and the protection of our foreshore. It also encouraged us to embark on replanting to replace the trees-mainly cocoa and coconut -that had been destroyed. Last year, for the first time since the cyclones, our copra exports came back in strength. We have, at last, started to approach the pre-cyclone export levels.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What are likely to be the key sectors for future economic activity ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-We believe that the economic future of our country now lies more in tourism and in manufacturing industries. Dealing with the latter first, we have already succeeded in attracting some industries. The major investment so-far has come from Yazaki, a Japanese company that produces wire harnessing systems (electrical components) for vehicles. This employs almost 3000 people in Western Samoa. In fact, the company set up here before the cyclones and it did not take long for us to see the benefits. The value added equivalent provided by just that one plant is roughly equivalent to our total agricultural exports for last year. So you can see the importance of manufacturing industry for us. We have provided very generous incentives and have also allocated sufficient government land to provide space for factories.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The other industry which is now in the forefront, in terms of foreign exchange earnings, is tourism. We now earn four times more from this sector than we do from agriculture-and agriculture is supposed to be the mainstay of our economy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Of course, we mustn't reduce the priority that we give to agriculture. It is one area where we have the resources. More specifically, I think that we have great potential for beef production. If we should have another cyclone, the trees will be damaged but cattle should not be affected. So I think we should look more towards beef production and other forms of agricultural diversification. We do have some good commercial farming in place at the moment, but it is not enough. We need to do more.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What about the chocolate industry ? You have traditionally grown cocoa but you now also have a factory to process the raw material right up to the end product.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-This is a direct result of our drive to promote more manufacturing - whether it is export-oriented or geared towards import substitution. The chocolate venture is a new one and I think there are good, prospects here as well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An important point is that we are moving back into growing the fine flavour variety of cocoa here. We used to be one of the 14 producers of fine flavoured cocoa in the world, and we got premium prices for it. But somehow, over the years, we switched to producing inferior quality bulk cocoa. We regretted doing that and are now switching back to the higher quality variety-which is just coming back into production following the cyclones. So here we have another potential area for exports. On the other hand, taro which used to be our major export prior to 1993 is facing difficulties. It is affected by a disease, the taro blight, which seems to be uncontrollable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Thinking in particular of the impact of tourism, are you concerned that an influx of foreign visitors might damage Western Samoa's unique and very special culture ? I see, for example, that you now have a 'McDonalds' restaurant in the centre of Apia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- No. I am not really concerned. In 1992, we set up our own tourism festival. This takes place in the first week of September and is quite clearly intended to be a feature event with an emphasis on promoting tourism. All the activities at the festival focus on the various aspects of our culture-the arts, the dances, the preparation of food, the singing and so on. It seems to me that our drive for tourism is actually helping to revive some of the cultural aspects that would otherwise have been dvina out. So I believe there is a complementarily between culture and tourism, so long as we ensure that the relationship between the two is maintained. I think this point is backed up, if you look at the growing popularity of ecotourism nowadays. This is very much concerned with preservation-of both the environment and of local cultures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· In international circles, Western Samoa is deemed to be a least-developed country on account of its low GDP per head figures. Yet nobody is starving here and you appear to have a very 'rich' lifestyle, even if people don't have a great deal of cash in their pockets. Do you think the international classification is a fair one ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- I think the first point to emphasise is that a lot of the signs of development you see here are of recent origin. They date back only to 1992-93. Infrastructures have improved considerably over a very short time and this could well create a certain impression about the people's standard of living. On the other hand, it is true that our economy is not completely based on cash. And, of course, our earnings are in Tala which go a lot further here than their dollar equivalent in the United States.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Presumably, it is to your benefit to be classified as an LDC because it gives you access to more sources of foreign funding ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-I am happy to leave the classification to the experts. They are the ones who come and estimate our average per capita income, which is then used as the yardstick for placing a country in one or other category. I think it is ironic though, that if you go to a country like the USA, which is supposed to be very rich, you find beggars on the street. It certainly makes you wonder. Perhaps it is not really the statistical wealth of a country that is important, but its social system. And our social system here ensures that no-one goes hungry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· That leads on rather neatly to my next question. What do you think are the main social challenges that need to be tackled here ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-We still have quite a lot of 'service care' needs in the villages that we need to attend to. That is why we have placed the highest priority on social services over the next five years. I am talking here in particular about health, education and water supplies. There are still a lot of villages that need to have piped water brought into the home. Education-wise, we have reasonable access, but we need to improve the teaching material that is available in the classes and upgrade the general level of village schooling. We need to dissuade families from moving to the capital in the belief that they can get better education for their children here. So we still have a lot of work to do to ensure that the primary schools in the villages are upgraded. It is not simply a question of ensuring that competent teachers are available, but also as I say, providing good teaching materials and laboratory equipment for science subjects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· All of this obviously needs to be paid for, which entails healthy government finances. You recently had a serious problem over the debts run up by Air Polynesia, and you took very stringent measures to tackle this which resulted in expenditure cuts. What do the figures look like today ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-They are OK. We are running a budget deficit which means we have to borrow both overseas and locally, but we try to keep the deficit at a reasonable level.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What has been the effect of introducing the Value Added Goods and Services Sales Tax (VAGST) ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-It has helped enormously. Of course, in order to sell the idea, we had to reduce other taxes and duties. As you know, there is an international trend towards removing customs duties and shifting revenue-raising in the direction of consumption taxes. Customs levies, which are the traditional source of revenue are diminishing. So what we have done is to lay the foundation for the eventual shift in our revenue base. Also, we promised to cut income taxes even more-from 38% to 25% within two years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Has this measure been implemented yet ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-No, it is due to be introduced in 1998.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Finally, I would like to turn to a constitutional question. Western Samoa introduced universal franchise some five or six years ago, but you still have a system in which only matai (family heads) are entitled to stand as candidates in elections. Do you envisage any further changes to the system ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-I cannot really see that we will ever change again. The Constitution stipulates that our government is based on Samoan traditions and Christian principles. When we introduced universal suffrage, we were applying something that had always been there in any case. Samoans have always taken part in the process of choosing their leaders and voting is simply another way of doing this. The only difference is that we would arrive at a decision by getting together through our village structures and talking, whereas your system involves marking a ballot. So the change was quite in accordance with our customs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Let me say something about the way villages choose their matai. When there is a question of succession, everyone has a right to take part in the process. There is no age limit. So in that sense, you could argue that we are more advanced. And we always had female matai, even before the arrival of the Europeans.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this respect, I believe we are quite different from Fiji and Tonga. In Tonga, the dividing line is quite clear. If you are born a noble, you remain a noble and if you are born a commoner, you will always be a commoner. It is the same in Fiji. There, you are automatically a ratu K your father was one. By contrast, here in Samoa, my son cannot automatically succeed to my title. So to become a matai, a person has to earn it, and to put his case at the family meeting which is convened to choose a successor. Usually, the person chosen is the one who displays the best leadership qualities. I think I should also point out that becoming a matai is not that difficult. If you want to be one, you inform the family and if they think you have matured sufficiently, you will generally get the position and then become eligible to be a parliamentary candidate. It is typical that when a family sees a fellow has matured, he becomes a matai.</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Profile</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">General information</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Area: 2934 km² (Exclusive Economic Zone of 130 000 km²)</P>
+<P ALIGN="JUSTIFY">Population: 165000</P>
+<P ALIGN="JUSTIFY">Population density: 57 per kiLom&eacute;tres</P>
+<P ALIGN="JUSTIFY">Capital: Apia (situated on the island of Upolu)</P>
+<P ALIGN="JUSTIFY">National language: Samoan (English is the business language)</P>
+<P ALIGN="JUSTIFY">Currency: Tala (WS$) made up of 100 sene. In June 1996, 1 ECU was worth approximately WS$ 3. (US$1 = WS$ 2.3)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Politics</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">System of government: A unicameral constitutional democracy with strong traditional elements. The current Head of State is one of the country's four paramount chiefs, and he holds the office for life. Thereafter, the Fono (Legislative Assembly) will elect the Head of State for five-year terms.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is universal franchise (introduced in 1991) but in order to be a Parliamentary candidate, one has to be a matai (family head). Western Samoa is said to have about 19000 matai. The minimum voting age is 21.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Head of State: HH Malietoa Tanumafili II</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Prime Minister: Tofilau Eti Alesana</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Main political parties: Human Rights Protection Party (HRPP), Samoa National Development Party (SNDP)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Party representation in Parliament: HRPP 35, SNDP 11, Independent 3. (The HRPP total includes 11 members elected as independents in the April 1996 election who subsequently joined the governing party).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p038.png"></center><br>
+ Map</P>
+<P ALIGN="JUSTIFY"> </P>
+<P ALIGN="JUSTIFY">Economy (1995 figures unless otherwise stated)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Annual GDP per capita: approx US$ 950</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GDP growth rate: 7%. The target for 1996 is 34%</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Principal exports: coconut oil (WS $8m), coconut cream (WS $4.8m), copra (WS $2.2m).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Balance of payments: exports - WS $21.7m, imports - WS $228.1m. 'Invisible' earnings, officially described as 'net foreign earnings' amounted to WS $171m, leaving a current amount deficit of WS $36.8m in 1995 (20%lower than the previous year). The main 'invisibles' are private transfers (remittances from Western Samoans living abroad), tourism, income from services and the value added trade of the Yazaki electrical components firm.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Inflation rate (end 1995): 1 %. Inflation tends to fluctuate a great deal. The figure for 1994 was 18.4%.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Government budget (projected for 1996/97): revenue WS $288.4m, expenditure WS $312.7m, deficit WS $24.3m.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Accumulated government debt: WS$ 389 m</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Social indicators</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Life expectancy at birth (1993): 67.8 years</P>
+<P ALIGN="JUSTIFY">Adult literacy (1993): 98% (A UNESCO report in 1994 suggested that real literacy levels were significantly below those indicated in official figures) </P>
+<P ALIGN="JUSTIFY">Enrolment in education: all levels from age 6-23: 74%</P>
+<P ALIGN="JUSTIFY">Human Development Index rating: 0.700 (88th out of 174) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Marketing a tropical idyIl</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Folasaito Joe Annandale and his wife Tui are the brains behind Western Samoa's latest tourist facility- the Sinalei Reef Resort, which has just opened on the beautiful south coast of Upolu island. They are among a growing number of Samoan entrepreneurs who are injecting new dynamism into the country's economy although they are somewhat unusual in the tourist trade. With the notable exception of the famous 'Aggie Grey's Hotel' in Apia, tourist accommodation in Western Samoa has tended to be the preserve of foreign investors, including some of the major international hotel chains.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At first sight, it is surprising to discover how underdeveloped the tourism sector is in Western Samoa. Tour operators may be inclined to use the phrase 'tropical paradise' a little too freely but this island nation certainly seems to meet most of the essential criteria. It has the obligatory golden beaches fringed with palm trees, extensive coral reefs and striking mountain scenery overlaid with lush vegetation. The vivid colours leave a particularly strong impression. Greens predominate but there are also many copper-leafed trees and bushes, and an abundance of red, orange and yellow flowers. Western Samoa can also offer a number of special features which are important in marketing terms. There is, of course, the legendary hospitality of the Samoans and their distinctive and vibrant traditions. This must be one of the most musically 'literate' populations in the world, a talent which is reflected in the numerous choirs/dance groups. The harmonies are impressive and the traditional dances are both expressive and entertaining. There is also the unique 'fare' architecture which is a particular source of fascination to outsiders, not to mention the Robert Louis Stevenson connection. The famous author spent the last four years of his life in Western Samoa and the house where he lived- which used to be the Head of State's residence - has recently been converted into a museum.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Good prospects</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The potential for expanding tourism is something that has not escaped the government. In today's highly competitive free-market world, countries are being urged to exploit their 'comparative advantage' and the Western Samoan authorities recognise that this sector offers some of the best prospects for future growth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like most other economic activities, the tourist trade was badly hit as a result of cyclone devastation in 1989 and 1990. However, visitor numbers have increased substantially since then. Indeed, looking at year on year earnings, the tourist sector is performing better than any other area of the economy. In 1994, income was WS$.58 million (50 000 + visitors). The following year, it reached WS$.78m and there are hopes that it could top WS$.100m in 1996. Of course, no-one in Samoa is talking about 'mass' tourism. The country is too far from the main industrialised nations to be able to offer traditional package holidays (perhaps fortunately !), and too small to absorb the cultural and environmental impact without lasting damage. Having said this, the market can be divided into two very distinct portions. At one end of the scale are the low spending 'back-packers'-often taking advantage of relatively cheap 'round the world' airline tickets to stop off and sample the pleasures of Western Samoa. These tourists may not spend very much on a daily basis but they are reasonably significant from a financial standpoint because they tend to stay for quite lengthy periods.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the other end, you find the high-spending, 'exclusive' customer willing to pay for high quality accommodation and catering. Perhaps not surprisingly, the Government is more interested in attracting the latter, which is why they are keen to encourage investors such as the Annandales.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Courier spoke to Joe Annandale about his business strategy when we recently visited the country. The Sinalei Reef Resort, which has received EIB loan financing channelled through the Development Bank of Western Samoa, has just 20 rooms (including four suites) giving it a capacity of less than 50. Customers will be offered a tropical idyll and a chance to escape completely from the pressures of modern living. The long term aim, according to Mr Annandale, is to entice Europeans in general and Germans in particular. The latter, it is said, have a preference for environmentally-friendly, 'escapist' vacations and, of course, there is a historical link between Germany and Western Samoa. Until a European clientele can be built up, the focus will be on attracting guests from Australia and New Zealand. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Culture clash?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although there is no question of Western Samoa being swamped by visitors from overseas, even a modest increase in tourist numbers is bound to have an impact in this country of just 165000 inhabitants. On the negative side, the Samoan system of customary (village) land ownership sometimes appears at odds with entrepreneurship founded on individual ownership of property and resources. In the early stages, Joe and Tui Annandale encountered local difficulties-including squatters-when they bought the land to develop the resort. The usual arrangement is for overseas tourism operators to lease customary land, a process which may involve protracted and ultimately fruitless negotiations with the matai (village heads) who have traditionally used the land for other purposes. Of course, the clash between traditional land tenure systems and 'modern' capitalism is not restricted to tourist ventures-as mining operators in Papua New Guinea have discovered. But while one understands the frustrations for developers, who may find themselves embroiled in complex and interminable land disputes, we should also recognise the concerns of local people who see a possible threat to their way of life.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the positive side, new tourism developments mean jobs and trading opportunities. In the building of the Sinalei Resort, the Annandales drew heavily on local labour, employing 35 people from the neighbourhood. As Mr Annandale pointed out, this was essential for a complex designed to fit in with the local environment. The Samoans have always built their own houses and only they had the required carpentry skills. The resort also employs 35 regular staff for catering, housekeeping etc. and again, the majority are local people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, there is one criticism often levelled against tourist ventures which certainly does not apply at the Sinalei Reef (or other Samoan hotels). This is that most of the food and drink consumed by visitors is imported. The Annandales make a point of purchasing their fish, meat and fruit locally, thereby ensuring that some of the financial benefits of their venture flow back to their own community: in short, a happy combination of astute public relations and good economics. </P>
+<P ALIGN="JUSTIFY">S.H.</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Interview with opposition leader Tupua Tamasese Efi</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY">'Revive the agricultural base'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tupua Tamasese Efi a former Prime Minister of Western Samoa, is leader of the opposition Samoa National Development Party which won 11 of the 49 seats in the parliamentary elections held in April 1996. In this interview, he outlines his own and his party's views on some of the key political and economic issues in his country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· In what ways does your party offer a different agenda from that of the governing HRPP ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-I think the differences are mainly of emphasis. The present government tends to focus on law-making and exploiting the country's least developed status. Our focus would be more on developing our indigenous agricultural industries. If you scrutinise the economic picture in Samoa, you will find that there has been a very substantial decline in agricultural exports in the last fifteen years. Our economy, if you can call it that, is increasingly sustained by largesse-the donations that we get from overseas. This has complicated our situation. Our relative economic independence has been sabotaged to a point where, suddenly, we are getting a proletariat. That might be unavoidable in a lot of places, but it doesn't have to happen in a small country like ours which has self-sustaining village units, and a potentially secure agricultural base supported by products like cocoa, copra and bananas. If you look at what is happening today, you see that, all of a sudden, we have a new class of under-privileged people with absolutely no income at all. And the tragedy is that it has happened without anyone really noticing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So our emphasis is to try and revive our agricultural base, and to seek out exports. In the past, our economy was sustained by cocoa and copra exports, and a lot of our food was sold to New Zealand. Now, you find that there are hardly any exports.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· So your focus would be more on boosting the traditional aspects of the Samoan economy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Not necessarily traditional. Our party is not bound to cocoa, or copra or whatever. But we are committed to improving our agriculture. It matters little whether it is traditional or other crops. But we need to break back into the New Zealand market. This is the best place to aim for. Australia has its own tropical sector and nothing that we can produce is needed by them. New Zealand is different. One of the biggest challenges we have to overcome in getting back into that market is our fruit fly problem. It would seem sensible for us to channel substantial resources into overcoming this hurdle so that we can sell to New Zealand again. There is a tremendous potential market-and not just for copra. There are also products such as flowers, and a whole number of other possibilities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Given what you have just said,what emphasis would you place on sectors like manufacturing and tourism ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-I think that tourism is an obvious way to go and this is where we are in agreement with the government. Of course, you will have heard of the debacle of the Air Polynesia finances. When you compare the losses that were run up with our foreign exchange reserves you get some idea of how enormous the problem was. It was a situation that went badly awry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This issue aside, we agree that we need to get into tourism-but it must be within reason. Part of the explanation for people gravitating towards tourism is that they see it as the only available avenue-or at least the most visible way of making money.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another economic point I want to raise concerns debt. Loans can be a quick fix, but when your whole economy is tied to indebtedness, you are creating something that is built on sand. You end 'A potentially secure agricultural base' up acquiring more and more capital items that are totally unrelated to your present or likely future resources. This is one of the most destructive things that can happen to a society, and it is very clearly happening here.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You have a rich and vibrant living culture here in Western Samoa. Are you concerned that globalisation could ultimately pose a threat to this ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-No, I am not worried. You have to accept it as a natural development. The things that are distinctive in our culture have to find their place in adapting to the new realities. There is no point putting your head in the sand.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Turning to political aspects, you now have universal franchise, but you still have to be a matai to be eligible to stand for Parliament Does your party have any plans to change this ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Some years ago, we had a constitutional convention which led to changes in the system. Attached to that was a provision requiring a further constitutional convention to be convened in 20 or 25 years (I can't remember the exact period). So we are committed to that. We have to sit down and look at the overall picture. We have gone a long way in terms of universal franchise and it is possible that we need to go even further.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But if one takes the United Kingdom as a model, I think the important lesson is that you should 'make haste slowly'. The genius of the Westminster model is that it involves careful evolution. I hope that this tradition will be followed by our country. The constitution, as it was put together some 30 or 40 years ago, has served its purpose very well but there are quite a few anomalies appearing now.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What is your view about regional cooperation in the South Pacific What future do you see in working together with the other countries of the region- perhaps presenting a more united front to the outside world ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-There is a lot of sense in the SAS approach-I am referring here to the Scandinavian countries getting together to form an airline. It is sensible to take a common stand where we have a common interest. But there are obviously intricacies resulting from historical, economic and social factors. At the moment I am reading a book on lain Macleod, the British Conservative statesman. His experience in the failed attempt to form a federation in the Caribbean is very revealing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When you enter a common endeavour, there is always the pull of your own particular interests. And there can be a suspicion that the 'bigger boys' will use the others to promote their own interests. A lot of this may be perception rather than reality. Also, traditional rivalries can intrude. Sometimes you need to fall flat on your face before you Let me give you an example from the world of rugby. It took Rupert Murdoch to get Fiji, Tonga and Western Samoa to realise that our fates are intertwined. He has come in with a commercial package that has taken over the entire rugby scene in the region- with a heavy emphasis on Australia and New Zealand-and this has hit us in a big way. For example, we find ourselves being cut out of traditional rugby tours. There is no point in us trying to claim that we are self-sufficient in this area. The big lesson is that we need to cooperate a lot more with the Tongans and Fijians in order to make an impact on the wider rugby scene._ </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Western Samoa-EU cooperation</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY">Focus on utilities</P>
+<P ALIGN="JUSTIFY">by Mylanwy van de Velde</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Western Samoa's cooperation with the European Community began in 1975 with its accession to the Lom&eacute; Convention. From the start, the sector to benefit most from programmable funds (ECU 4.6 m under Lom&eacute; I and ECU 6m under Lom&eacute; II) was the energy sector, with the financing of the Samasoni Hydroelectric Scheme in the late 1970s and the Sauniatu Hydropower Scheme in the early 1980s.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In parallel, a programme of 260 microprojects was funded involving the development of poultry and pig farming, and fisheries, covering 96 villages on the main islands of Upolu and Savai'i. A further ECU 890 000 was allocated to the Western Samoa Development Bank, in the form of a credit line, to increase the Bank's lending capacity. In addition, at a time when copra exports were still considerable, the Community financed storage and handling facilities for coconut oil and copra pellets (ECU 900 000).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On top of programmable aid, Western Samoa received 12 Stabex transfers totalling ECU 9.3m for export losses on copra, wood, bananas and cocoa in the period 1975-84.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under Lom&eacute; III, the development of the country's substantial hydroelectric power potential continued, and Western Samoa began to make considerable steps towards self-sufficiency in energy needs. While in 1980 some 78% of the electricity generated came from diesel plants, by 1986 this percentage had dropped to 26%. The volume of petroleum imports for electricity generation dropped to 36% in the period 1982-86. With the building of the Afulilo Hydropower Plant (Lom&eacute; III and IV), these volumes have decreased further, with positive benefits in terms of foreign exchange savings. The scheme (which was co-funded by the Asian Development Bank, the EIB, the World Bank and the Western Samoa Electric Power Corporation) involved the construction of a 10 million cubic metre reservoir, a penstock, a powerhouse, and the installation of mechanical equipment and transmission lines, and has contributed substantially to the quality of electricity supply on the island of Upolu.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p043.png"></center><br>
+ Community aid to Western Samoa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Additional work has been done with Lom&eacute; IV funds to address the question of rural water supply: a water master plan and design study for a number of rural areas have been completed, and a public awareness programme on the rational use of water resources has been designed for implemention at such time as planned infrastructural work goes ahead.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, an ECU 1 m microprojects programme has been initiated with the aim of financing the renovation of infrastructure for rural communities in the fields of water supply, health, education, tourism, agriculture and fisheries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Stabex payments under Lom&eacute; 111 (1985-1989) and Lom&eacute; IV (1990-1994) amounted to ECU 11.1 m and ECU 5.7m respectively. These were paid to compensate for losses in coconut oil and copra products, especially, but also for losses on exports of cocoa beans and of wood in the rough.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition to the above grant aid, the EIB has provided a total of some ECU 9m in risk capital in the years since 1981, the bulk of which was used in connection with the Sauniatu and Afulilo Hydropower Schemes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A further total of ECU 660 896 has been allocated in emergency aid to Western Samoa, in 1983 after a serious fire on Savai'i, and in 1990 and 1991 after the disastrous cyclones Ofa and Val.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Programming of the next tranche of EC funding under the eighth EDF has still to be completed, but the indications are that prominence will be given to extending and upgrading the water supply network. </P>
+<P ALIGN="JUSTIFY">M.v.d.V.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A new health-centre for Tafua</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The sight that greeted the people of Tafua when they emerged from shelter in 1990, following the passage of Ccyclone Ofa,was one of complete devastation. The tropical storm had been one of the worst in living memory and this village community on the island of Savai'i, together with many others in the Samoas, found themselves having to start almost from scratch. Homes had been swept away' crops destroyed and much of the essential infrastructure Iay in ruins.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is a testament to the resilience and determination of the people in these communities that there are few signs today of the havoc wrought by the winds just six years ago. In some places, rows of dead trees still stand in silent witness to the power of Mother Nature, although the scene is softened : by the new crops and lush vegetation growing beneath. But the villagers have rebuilt their houses and, with some help from outside, they have been able to re-establish i the essential community facilities as well. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Through its micro-projects programme, the EC was able to offer a helping hand in the task of reconstruction. For the modest sum of just ECU 10 000, Tafua now has a new community health clinic adjacent to the site of the old one which was swept away by Ofa. In keeping with the rules of the scheme, the villagers were obliged to contribute 25% of the cost-which they provided in kind, in the shape of the labour for rebuilding the clinic. The Courier visited Tafua in June and was shownaround the facility by Nurse Agata Leuelu who provides primary health care for the 600 villagers. We also met local Methodist minister, the Rev. Siaosi Selesele, who explained how the people had taken shelter in the neighbouring school when the storm reached Samoa. It turned out to be the right choice as it was one of very few structures left standing in the neighbourhood. Villagers are obviously hoping that there won't be another 'Ofa' for a very long time' but if and when the next big wind does strike, the new ctinic-which has been built to withstand a lot more strain-should hopefully be able to weather the storm. In the meantime, it provides an important service in the delivery of health care to the people of the area. The European Community has also provided micro-project funding to help rebuild the health clinic at Taga on Savai'i. </P>
+<P ALIGN="JUSTIFY">S.H.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Dossier</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Investing in people</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(Dossier coordinated by Augustine Oyowe)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Previous editions of The Courier have dealt, separately and at length, with various aspects of human resource development, especially in the context of recent dossiers on population and social development, education and training, public health, women, and poverty. Our current dossier looks at the issue from the investment perspective.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To say that investing in people makes economic sense is to state the obvious. But to what extent are the implications of this statement fully understood in the developing countries, especially in sub-Saharan Africa in these days of constantly shifting development theories?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Labour or 'human capital' has long been recognised as a key factor of economic growth. As opposed to sustainable human development, which places human beings at the centre of economic activities (the recipient of the fruits of economic progess), 'human capital' places them at the beginning of the process. The difference of approach is thus evident even though the objective is the same. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Investing in people is a concept which simultaneously combines 'human welfare' with the 'human capital' approach at the beginning of the economic development process. It encompasses nutrition, health and education, and should, under the right investment climate or conditions, enable any investor, whether State or individual, to reap an adequate return .</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">After three decades of considerable efforts at investment in health and education by sub-Saharan African countries, the returns in terms of standards of living, economic grovvth and rate of development have been extremely disappointing. The conclusion which can be drawn is that the conditions necessary for adequate returns on these investments have been absent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Colonial legacy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sub-Saharan Africa inherited from the colonial regimes, infrastructures in health delivery and education that were not only alien to its culture and traditions, but also totally inadequate for nation building. It is a well known fact that in 1960, there were no more than 1200 university graduates in Capital redefined</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is important when thinking of investnent in human resources to understand the real concept of capital. Below is an extract of a definition given by Stefan de Vylder (taken from his UNDP discussion paper: 'Sustainable Human Development and Macroeconomics strategic links and implications' . </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A child in the North is born wealthy. His or her share of the capital accumulated by earlier generations is worth a fortune. The higher wages and salaries in the North, compared with those in the South, largely reflect differences in endowment of the country, rather than of the individual. The fact that, for example, a nurse in Germany earns 30 times more than one in Bangladesh or Zambia has little to do with individual differences in training or skills; the higher salaries in the North simply reflect the higher dividend on the capital bestowed from the past. Part of this wealth or heritage is easily visible: factories, roads, schools hospitals, universities, telecommunications, and other infrastructure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, there are other, less tangible, forms of capital that constitute a crucial complement to physical and infrastructural capital; parliamentary democracy, a free press, respect for human rights' norms for social interaction, systems of rapid dissemination of new ideas, trade unions and a myriad of other large or small social organisations, a judiciary system which, by and large, defends law and justice, and other institutions. This latter form of capital may be called institutional or social capital. It is also highly unevenly distributed in the world, with large differences both between the North and the South and within individual countries of the North as well as in the South the region as a whole. Indeed, some countries had no graduates at all and in others, they could be counted on the fingers of one hand. In what was effectively a race against time, African leaders understandably responded by investing massively in human resource development. This was made possible partly by small, but steady rates of economic growth and partly by sustained foreign assistance. Between 1960 and 1980, sub-Saharan African governments consistently allocated high proportions of their annual budgets to health and education. Households and individuals made similar efforts (accounting for nearly 75% of all spending on health). They made sacrifices and gave a high premium to the education of their children.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The results were tangible and very significant. By the late 1980s, sub-Saharan Africa was producing over 70 000 graduates a year. Major cities had hospitals and health centres and the rural areas, clinics and dispensaries. Amid a general improvement in nutrition and health-care delivery, the incidence of infectious disease, and maternal and infant mortality were considerably reduced.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite these achievements, the approach to manpower building by the post-independent African leaders was, to say the least, haphazard. As a result, a number of problems, such as the appropriateness of school curricula, under staffing and the long-term budget implications of recurrent expenditures, were overlooked (although reform efforts have since been attempted in some countries with varying degrees of success).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The consequences were felt in the 1980s when Africa's economic crisis was only just beginning. Health and school infrastructures deteriorated for lack of maintenance. There were shortages of qualified teachers and teaching materials leading to falls in educational standards as well as in primary school enrolments. And health systems failed for lack of personnel and drugs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The situation has worsened as the continent's economic crisis has deepened-a crisis characterised by huge budget deficits, high inflation rates, sluggish growth rates and a heavy debt burden. Structural adjustment programmes (SAPs), introduced in response to this, have only served to undermine further the gains made in human resource development. SAPs have been aimed mainly at macroeconomic stabilisation, deregulation and privatisation of state enterprises, and the social sectors have lost out in the process. Subsidies on basic commodities, especially food, have been removed, civil servants and employees of state enterprises have been made redundant and cost-recovery has become the standard practice in medical services. These measures have all combined to produce a level of poverty never before seen in the region, a situation which has adversely affected nutritional standards, provoked malnutrition in many countries and reduced resistance generally to infectious diseases. Because of the rise in unemployment, large sections of the educated population have been rendered unproductive, a waste of several years investment by both the state and the individuals in question.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Appropriateness of skills</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although sub-Saharan Africa produced a large number of graduates before the economic crisis began, few had the kinds of skills needed for industry and agriculture. The evidence of this lies in the unsuccessful attempts by some governments in the late 1970s to indigenise executive positions, most of which required high levels of technological knowledge or experience. The 1980s saw a dramatic increase in the number of foreign technical assistants working on the continent and, paradoxically, in the number of qualified African professionals leaving, mainly for Western Europe, the United States and Canada.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">International technical assistance to, or cooperation with, subSaharan Africa has intensified. Organisations such as the World Bank, IMF, UNDP, UNCTAD, UNESCO, European Union and Commonwealth are all involved in one form or another. The effectiveness of this assistance varies, however. This dossier features articles on the work of three of these bodies (the Commonwealth, UNDP and VNESCO). The Commonwealth Fund for Technical Cooperation was set up more than 25 years ago to mobilise Commonwealth skills to meet the needs of member states as required. The UNDP's TOKTEN programme is designed to reduce the negative impact of the brain drain by getting highly qualified developing country expatriates to contribute their skills to the development of their home countries without necessarily having to return permanently. Finally, UNESCO's university twinning programme is designed as a mechanism for the rapid transfer of technology and sharing of knowledge. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While international assistance or cooperation is indispensable, it is surely no substitute for Africa's own efforts at human resource development. Three years ago, Edward Jaycox, then World Bank Vice-President for the Africa Region, announced what appeared to be a change of policy at the annual conference of the African-American Institute in Washington DC. He said that the Bank would no longer pay for foreign technical assistants to help resolve African economic problems but would instead help African governments build their own capacity. Although the Bank has traditionally had enormous influence on development thinking and policy worldwide, the apparent policy change does not appear to have influenced other donors. Nor, indeed, is there any evidence that the Bank itself is implementing it vigorously. The number of foreign experts being sent to Africa continues to grow. There were over 100 000 in 1988.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rationality of investing in people</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition to the negative social impact, ten years of structural adjustment have not produced the sought-after stabilisation or the economic growth that was initally anticipated. Even the World Bank and IMF, who spearheaded the structural adjustment idea, have admitted that it has flaws and the need for a new approach to sub-Saharan Africa's economic problems could hardly be more urgent. In the Dossier, Giovanni Andreas Cornia argues for a new focus for structural adjustment, based on restoring adequate levels of public spending on health, education, social welfare and water supplies, so as to enable sub-Saharan Africa to restore and develop its human resources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Evidence of the impact of a healthy and educated population on economic growth and development abound. Studies on the economies of the East Asian 'tigers' have all concluded that big investments in education in the late 1950s and 1960s were largely responsible for the rapid growth they have experienced in recent years. Malaysia, although a latecomer, appears to be following in the footsteps of its neighbours. After nearly two decades of investment in human resource development, and the introduction of a foreign investment policy which requires some technology transfer, the Government now predicts Malaysia will achieve 'fully developed' status by 2016-twenty years from now.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A relatively well-educated workforce and a certain amount of physical capital or natural resources are all a country needs to succeed economically. Sub-Saharan Africa has sufficient natural resources as is often pointed out. The other side of the equation-a relatively well-educated workforce-is missing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sub-Saharan Africa lags behind other regions in human resource development for a complex variety of reasons. The natural and political environment are not conducive to the delivery of social services: low population density and weak transport infrastructures make such delivery expensive and the achievement of economies of scale impossible. The region's climate favours a variety of diseases (such as malaria and sleeping sickness) and many areas have little or no access to natural water sources. Political instability and weak institutions also continue to cast a long shadow. Although these constraints are long-term, appropriate policy measures could reduce their negative impact significantly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Giovanni Cornia analyses the distributive effects of appropriate health care, nutrition and education on economic growth. He suggests ways of making rational use of available resources for maximum returns and of mobilising funds through taxation, foreign aid and other sources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In an age of increasing globalisation, where technology is more easily transferable across borders, a healthy and educated population is essential, not only for the absorption and use of new technology but also for meaningful participation in international trade.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is insufficient, however, to have an educated workforce. Sub Saharan Africa must acquire the institutional and managerial capacity to make the right decisions, both in the public and private sectors. This is essential in the quest to eliminate poverty, achieve sustained and sustainable economic growth and ensure a realistic integration of the region into the global economy. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">A much needed new focus for SAPs</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY">by Giovanni Andrea Cornia </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over the past two decades, a clear consensus, supported by a growing amount of empirical evidence, has emerged on the growth and distributive effects of appropriate health care, nutrition and education, and on the rationality of investing in human resources to promote development in low-income economies, and in sub-Saharan Africa in particular. It is now clear that public and private rates of return on investment in primary and secondary education are substantially greater than those in most industrial sectors. Similarly, it is now well demonstrated that nutritional interventions in favour of workers at low levels of food intake has a very large impact on labour productivity. Also, provision of simple but adequate nutrition and health care at an early age has been shown to spare substantially greater health outlays over the longer term. While the number of these examples can be multiplied, the lesson is overwhelmingly clear: investing in people is a sound development policy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During the same two decades, a broad political consensus has also emerged on the need to establish realistic targets in these areas and mobilise adequate resources to achieve them. The latter decade, however, has also been characterised by a widespread and acute recession which has reached its lowest point in the African continent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While there has been a general recognition of the link between the deterioration of the social sector and Africa's economic decline, the interpretations of the causes of this decline and how best to address them vary considerably.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 1980s also witnessed the advent of structural adjustment, an approach aiming at revitalising economies affected by severe crises and which calls, amongst other things, for a reduction in public spending, including on social services. With sharp falls in revenues, it was argued, African governments could no longer afford to provide health and education free of charge.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Governments were to encourage instead the role of the private sector (since competition between state, private and non-governmental agencies fosters efficiency and enhances quality) and make households bear a greater share of the cost of publicly provided social services (as-it was alleged-households had a strong 'willingness to pay' for better quality health care and education).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In a debate characterised by an overwhelming concern for expenditure reduction, little thought was given to protecting the provision and effectiveness of basic health care and education for all. Nor was sufficient attention paid to the mobilisation of additional revenue through taxation, foreign aid or other measures Even the introduction of rationalisation measures, which would have allowed for use and preservation of limited resources, received scant attention. During this period, public policies often ignored a number of well-known public finance arguments concerning market failures, externalities, natural monopolies, etc. typical of basic health and education. It was all too often forgotten, for instance, that the market systematically undersupplies 'quasi-public goods' like education, safe water, immunisation and collective infrastructure (i.e. goods which produce benefits not only for consumers but also for society as a whole); that incomplete or non-existent markets alone are unable to provide complete insurance coverage against the risks of sickness and disability; that the free play of market forces can generate levels of poverty that are socially unacceptable, and that competition among many small providers does not allow for the realisation of the economies of scale which only the public sector can realise because of its size, administrative infrastructure and revenue raising ability.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Greater and better government involvement</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this paper, I will attempt to point out the main distortions in the social sector in sub-Saharan Africa and the major reforms, part of an alternative policy paradigm to the standard approach focusing on large expenditure reductions. My main line of argument is for more efficient and renewed but, in most cases, greater rather than less government involvement. I do not deny the important role of communities, nongovernmental bodies and private providers of social services, but the retreat of the state, which has been underway for several years in most of Africa, is palpably wrong: it may be a good survival strategy, it is definitely not a good development strategy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Any approach to revitalisation of the social sector in Africa must aim at increasing both the quality and the relevance of services to the life, health and productivity of the population; enhancing efficiency; reducing distributive biases in the use of public expenditure, and improving the flow of both public and private resources to the social sector. These sets of measures are briefly discussed here.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Raising relevance, reducing unit costs and enhancing quality</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Two basic initiatives are essential to the achievement of this goal. Firstly, it is necessary to adapt the content of services to the demands placed on the child, the adolescent and the family by the external environment. Secondly, in doing so, it is necessary to provide minimum resources, particularly recurrent inputs, for every unit of service offered.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Much can be done to improve the relevance of education in Africa. A key element in this is the wider use of African languages in the educational system. Admittedly such a step would probably encounter obstacles, but the results of pilot projects in the continent and experiences in several English speaking countries have been encouraging. The use of African languages should be expanded throughout primary and at least part of secondary schooling. And the curriculum of basic education should include basic health science, agriculture, food and nutrition, basic technological science, ecology and environmental studies as well as reading, writing, arithmetic, history, geography and elementary civics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While responding more appropriately to the life and developmental needs of children and adolescents, these measures offer the potential to improve substantially the cost effectiveness of the educational system by reducing the number of drop-outs and repeaters, particularly if the measures are accompanied by school-based nutritional support programmes and by steps to ensure a steady, if basic, supply of teaching materials such as books, chalk, slates, pens, exercise books and so on. Minimum expenditures for the latter, estimated at $5-10 per child per year, have been shown to have a profound impact on the quality and attractiveness of education.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Improving the relevance and quality of African secondary and higher education will require an increase in the number of courses in science, engineering, agronomy, management and other fields. Given the limited success of vocational training and yet the profound need for this type of education, a more flexible approach may be appropriate. Business associations and ministries of labour, rather than ministries of education, for example, could organise the type of vocational training that responds more closely to labour market conditions. Much needs to be done to gear university research to local and national needs. Rather than maintaining the model of independent residential universities, faculties could interact more with and rely upon local institutions and non-governmental organisations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the health sector, a more vigorous approach is necessary to implement the 'Health for All' strategy. In particular, more attention must be paid to the quality of the training imparted to village health workers, the provision of minimum supplies of essential drugs, adequate supervision, the mobilisation of communities and the strengthening of family planning services in the first tier of the primary health care pyramid.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Greater efforts are needed to contain unit costs through the mobilisation of community resources (such as materials and time) and the introduction of 'product standards' and 'production techniques' more in line with local factor endowments. With respect to capital expenditure, one major source of potential savings is the substitution of imported materials with local ones in the construction of schools, clinics and other public health facilities. Through this approach, capital costs per student could be more than halved.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In health care, savings are also possible, in some cases, in wages and other recurrent expenditures. The potential for savings through increased efficiency in the procurement, management, storage, distribution and prescription of pharmaceuticals is substantial. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">And there is a need for more carefully articulated manpower policies, with recognition of the cost implications of alternative skill mixes. Many tasks carried out by senior professionals can be performed by auxiliary personnel. In this regard, there is substantial scope for the application of nominal fees as a tool to guide demand for health care and thus increase efficiency.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Similar considerations are valid in the education sector. Despite considerable declines during the 1980s in both French-speaking and Eastern and Southern Africa, teacher salaries in the late 1980s were still considerably higher than per capita GNP in several countries. While a cutback may be possible in some countries, reductions below the 'efficiency wage' should be avoided as they affect the quality of teaching.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are, of course, other approaches to reducing unit costs such as using teachers trained on crash courses and- paid salaries lower than that of fully trained ones, multi shift education to increase teaching hours, multigrade classes to increase class sizes and the creation of regional training centres with donor support. In addition, in most of sub-Saharan Africa, all university students receive fellowships to cover living expenses while at school. In many cases these fellowships represent a substantial proportion of total unit costs at the tertiary level. They add, in effect, to the regressive nature of educational subsidies and should be suppressed for all except for those who are least able to pay.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Improving distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Substantial improvements in the distribution of benefits of public expenditure could be obtained through its restructuring towards basic services which benefit the poor more than they do the rich. This would mean, typically, the reallocation of part of the expenditure on hospitals to primary health care activities and part of the expenditure on universities to primary education. It would also mean that a greater share of investments in water supply and sanitation should be assigned to rural areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Correcting existing misallocation, however, is not simple, as capital and labour resources are only partially mobile. This is particularly true of capital expenditure which has already been invested in physical infrastructure. Inter sect oral reallocation is easier for recurrent expenditure, particularly when budgets are expanding, and it can lead to the achievement of more efficient and distributive gains.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Government subsidies need to be improved through effective targeting on 'merit goods' (such as food and shelter). Targeting is distributionally and administratively more effective when it is accomplished according to some objective criteria such as geography (the poorest areas), type of commodity ( low quality foods not consumed by the rich), easily identifiable population group (like pregnant women, young children, children in elementary school in poor areas, etc.) or season. It is less effective when carried out by means-testing or by targeting individuals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The decentralisation of health care and education in the African context is likely to improve the geographical distribution of services. Poor communications and transport systems, population dispersion and the fact that the supervision of personnel, resource distribution and operations is easier at lower levels of administration, are all arguments in favour of such decentralisation. Nonetheless, where it means loss of control over the implementation of national policies (in curriculum development, manpower training, drug procurement and so forth) and excessive additional financial burdens on households and communities, decentralisation is potentially damaging. This was the experience of Kenya when the purchase of drugs was decentralised at the district level. It subsequently had to reverse this policy because of the problems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Increasing the flow of resources to basic social services.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite the considerable scope for protecting and, in some cases, expanding the delivery of cost-effective and high-impact social services, even during periods of declining resources, there are limits to what can be achieved through the measures discussed above, particularly in countries where the share in GDP of public health and education expenditure is already low. Indeed in most African countries, the flow of resources to these sectors must be vastly increased. The options available include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Increasing the share of government expenditure on key social services.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Top priority should be given to a radical restructuring of government expenditure involving the shifting of resources towards those sectors with high social rates of return. Expenditure on defence can be cut substantially, while subsidies to chronically lossmaking public and private enterprises and interest payments on debt (the relief effect on foreign-debt interest payments of current provisions is utterly inadequate) should be reduced. If realistic expenditure restructuring like that proposed here were implemented, 1015% of overall public spending in many countries could be redirected to social activities with high rates of return. One half to two-thirds of these savings could be allocated to health care, nutrition, training, education and welfare, thus raising the share of these activities to about 30-35% of total expenditure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Increasing taxation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Between the late 1970s and the mid-1980s, the average tax to GDP ratio for sub-Saharan Africa fell from 18% to 16-17%. (Only recently are there signs of recovery, but these are confined to only a few countries). This resulted mainly from the recession affecting the region and from the limited priority attached to revenue collection in most adjustment programmes implemented during the first part of the 1980s. In these 'first generation' programmes, the stabilisation of deficits was achieved mainly by cutting expenditure and raising excise duties. Increases in income taxes and progressive indirect taxes were far less frequent and land and property taxes were almost never introduced.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While taking effect rapidly, the measures implemented led to excessive drops in public expenditure on 'quasi public goods' and have had a regressive distributive impact. It is now widely recognised that a more active tax policy is needed. Such a policy should aim at improving revenue generation and enhancing the efficiency and equity of the overall tax system. This would permit a controlled rise in specific 'socially efficient' public expenditures, particularly basic health, primary and secondary education and public infrastructure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the 1980s, a number of countries, including Burkina Faso, Kenya, Malawi and Zimbabwe, initiated efforts to reform their tax systems. While the choice of optimal tax instruments has depended on specific country conditions, a few general principles of tax reform apply to all countries. First, colonial type tax systems emphasising the taxation of exports (and to some extent, of imports) should evolve towards systems which focus on income taxes, progressive and efficient indirect taxes and increases in the prices of such public utilities as telephone and electricity which benefit mainly the wealthier sections of society. Second, purchases of goods and services consumed by the poorest should be exempted from indirect taxes. Third, efforts should not concentrate on raising marginal tax rates but rather on broadening the tax base by reducing tax evasion and tax elusion, and fourth a low, uniform and broad-based tax on wealth (such as on land or other assets) should be introduced.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A non-distortionary and equitably-spread increase in the tax ratio equivalent to 2-3% of GPD is technically feasible in a good number of African countries and would by itself add to the real flow of resources to health care and education by about 15%, even assuming no growth and no shift in priorities towards the social sector.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Introducing 'earmarked' taxes or raising local ones.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The flow of tax resources to the social sector could be augmented more readily if the new tax revenue thus generated, or at least part of it, were directly earmarked for specific health and education activities (for which there are guarantees that tax money is spent efficiently), or if these taxes were raised directly by district and provincial authorities, who are usually entrusted with responsibility for social services at the local level.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Mobilising additional resources from households and communities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In sub-Saharan Africa, as in most other developing regions, households have long borne a substantial share of the national expenditure on health, education, water supply and so on by contributing resources (in kind, cash and time) for the construction of health and education facilities, covering direct and indirect costs (transport uniforms, fees, drugs etc.) associated with the provision of public services and making payments to private providers. Despite these already considerable contributions, user charges have been introduced or raised on a large scale in recent years in many countries to alleviate the burden on public expenditure imposed by the economic crisis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, while the small but significant contribution of user charges to health and education budgets should be acknowledged, the negative effects of the indiscriminate application of these charges should also be emphasised. Indeed, in many African countries the need for health care, education and other social services rarely coincides with the ability to pay. The implementation of user charges can have adverse effects in three ways. First, it may lead to a contraction in the demand for services. Second, in the health sector, it tends to discourage the use of preventive services for which potential patients may not see an immediate relevance (such as ante natal care and immunisation). Third, it may adversely affect a household's ability to meet other basic needs, such as the purchase of food, particularly if fees are charged simultaneously for health, education and other services and if the household's income declines. In addition to these problems, there is little evidence that the revenue from user charges is actually reinvested to improve the quality or expand the coverage of local services, as those who promote user charges argue. Despite recent attempts at keeping a share of the user fees at the local level (e.g. at the collecting facilities), in most cases revenue merely flows to the public treasury. Moreover, user charges usually generate a relatively small proportion of the total operating cost of the health care sector, with gross yields at around 5%. If the costs of fee collection are included, the yields are lower and, in some cases, negative.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, health care, education and the provision of water include different types of services, some clearly geared to the needs of the poor and others catering more for middle and upper-income groups. While user charges are not well suited to primary education, disease control programmes, basic curative services and communal water supply, the same cannot be said of university education and other 'income elastic' services. For the latter, cost recovery measures would be advisable, although subsidised access for the deserving poor must be assured. For the intermediate category, which includes most curative health services and secondary education, selective cost-recovery measures might be desirable, with low income individuals exempted or charged only a nominal fee.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While direct user fees (levied on patients at the moment of their treatment) are problematic from several perspectives, there are other indirect ways to mobilise resources from communities (generally before episodes of illness), such as various kinds of prepayment schemes, health insurance, lotteries, mutual funds and the sale of produce from community fields, in addition to their contributions in kind. These schemes have two main features which are attractive for health-care: they shift the moment of payment, so that individuals are not burdened with relatively more significant expenditure at the time of illness, and they spread the burden of costs (e.g. for drugs) over a larger group.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Increasing the volume of international aid.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There has been a considerable shift in official development assistance (ODA) in favour of Africa over the past two decades. Africa's share in total ODA rose from 19.4% in 1975/6 to 25.1% in 1980/1, and to 34.2% in 1988/9. However, the share assigned to human resource development has dropped, while- debt-service obligations have often absorbed a growing share of ODA. Greater flows are therefore needed. In the late 1980s, the World Bank estimated that additional annual aid of about $1 billion was required during the 1990s to halt social retrogression and ensure reasonable progress. But this flow of aid has not materialised on any appreciable scale. Indeed the trend in the 1990s has been towards an absolute decline in aid flows. The simplest and the most cost-effective way to effect such aid transfer would be through debt relief, although some increases in ODA are needed. Improvement in the quality of aid, including substantial shifts to programme aid, greater participation in the financing of recurrent costs and more focus on primary health care and education and on rural water supply are also required.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What role for NGOs and private providers?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While private providers, including church missions, have always been important in Africa, much of the market oriented literature tends to be very optimistic about the scope for expanding private services in order to replace government ones. Although a multiplicity of providers is desirable (and frequently unavoidable), there are several reasons why such optimism should be tempered. First, private sector services in Africa are typically concentrated in urban areas, and because of their cost, cater for upper-income groups. Although non-governmental providers (especially missions) are often located in rural areas, and they generally provide valuable services, they are seldom able to guarantee extensive coverage and in some cases may duplicate government services. Second, private providers are not without costs to governments; they often receive subsidies or preferential treatment in the allocation of foreign exchange and typically offer higher salaries and better working conditions which draw manpower away from the public sector. In Zambia, for instance, a teacher in a primary school run by the Consolidated Copper Mines can earn more than a lecturer at the University of Zambia. In countries with extremely limited numbers of doctors, certified nurses, qualified teachers and so on, greater privatisation would exacerbate the 'brain drain' from the public to the private sector and the undersupply of 'quasi public goods' for the majority, leading to harmful social differentiation. Third, quality is not necessarily an important incentive in the private sector in developing countries. The view that private institutions in health care and education are more efficient tends to be based largely on analyses in developed countries. Fourth, the growing pressure for pluralism in social service provision often gives scant attention to the problems of central coordination and planning and the development of an adequate 'regulatory framework' for private sector activities. While playing an important complementary role, the private sector and, to a lesser extent, the NGO sector, are thus affected by important objective limitations. Indeed, ironically, their proper functioning and social utility depends crucially on the existence of a stronger, not weaker, state able to regulate, coordinate and ensure that basic social services are provided - possibly through a multitude of public, NGO and private providers-to all citizens of a nation. G.A.C</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Capacity building for management and development</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Franklyn Lisk</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The development experience of much of sub-Saharan Africa in past decades provides ample illustration of the importance of capacity building in the development process. The importance is related to the ability to manage economic and social processes, including the analysis and formulation of policy options, for attaining development objectives such as employment generation and poverty reduction. The consequences of failures in domestic economic management, compounded by the effects of a prolonged economic crisis in the region have, inter alla, contributed to high and rising levels of open unemployment and underemployment, declining per Capita incomes and real wages, and an increase in the incidence and intensity of poverty in a number of African countries. The persistence of these adverse consequences, which represent a serious threat to economic growth and sustainable development, are somehow linked-either as a cause or an effect -to weaknesses and instability in the institutional framework for management and public administration.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The problem of weak institutional and general capacity for management in Africa today can be traced to the colonial legacy. This left many countries in the region, at the time of independence, with insufficient institutional and human capacity to cope with the transition from colony to independent sovereign state, particularly with respect to the responsibility for economic management. More specifically, this related to the unequal and disadvantageous manner of Africa's incorporation into the international economic system in the late 1950s and the early 1960s. Lack of technological know-how, inadequate infrastructure and limited investment resources compounded the immediate post-independence problem of weak institutional capacity, and left many African countries highly vulnerable to external shocks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It was extremely difficult for the majority of African countries to break out of the old 'protected' colonial production and trade systems and rapidly to diversify their economies in line with the requirements of participating effectively in a competitive world economy. Since independence, institutional and human capacity for management in many African countries has not grown fast enough to keep up with the requirements of changing socioeconomic circumstances at the national level and to face the challenge of increasing globalisation. Critical skill shortages in public administration and private sector management in Africa can hardly be addressed in the context of the current economic crisis. The consequences of this crisis can be seen, for example, in underfunded and poorly equipped training and management development institutions, and in low-paid and demoralised civil services. At the same time, the 'brain drain' from the continent, partly as a consequence of poor pay and career prospects, has further undermined capacity in Africa. The interaction of foreign donors and African governments has not always served the interest of capacity building. It has been admitted, even by the World Bank that 'aid has done much less than one might have hoped to reduce poverty (in Africa)'. There is now more or less a consensus in the international donor community that expatriate technical assistance does not and cannot solve all kinds of development problems in the region. Far from solving problems, the imposition of foreign technical assistance has, in some cases, become a destructive force which undermines the development of domestic capacity that is critical to solving local development problems. Where donor assistance is inappropriate in terms of project concept and design, or there is a mismatch between design and domestic implementation and management capacity, technical assistance could end up becoming part of the problem rather than the solution.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Conceptual issues</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Before examining the requirements for institutional capacity building in developing countries, and particularly African countries, it is necessary to clarify salient issues pertaining to the concept. Broadly speaking, capacity building in a development context refers to a comprehensive process which includes the ability to identify constraints and to plan and manage development. The process usually involves the development of human resources and institutions, and a supportive policy environment. Ideally, it aims at improving on existing capabilities and resources and using them efficiently to achieve sustainable economic and social development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Narrowing the concept to focus on institution-building, the emphasis will be on the development of particular institutions, their human and material resources, their organisational management and their administrative capacities. More specifically, the aim of institutional capacity building is to improve significantly the outputs and impacts of institutions concerned with economic management, public administration (including project management), enterprise development and so on-in both the public and private sectors. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is obvious that relevant development-oriented institutions within an economy can exert a decisive influence on economic growth and employment prospects, and indeed on the attainment of sustainable economic and social development. From a macro standpoint,planning and similar development institutions are required for better management of the economy including, more crucially, the ability to mobilise, allocate and utilise human and material resources in an efficient and productive manner. At the micro level, human and institutional capacity is critical to sound project management and public administration.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The framework</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The general situation in Africa today suggests that capacity building is required in relation to the following priority areas:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- good governance, to ensure stability;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-economic management, to maximise resource mobilisation and promote sustainable development;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- human resource development, to support employment creation and income generation, and reduce poverty;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- science and technology, to increase the efficiency of the population and facilitate infrastructural development;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-enterprise development, to enhance the critical role of the private sector in overall development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The degree of emphasis given to each of the above in a given context would vary according to the level and complexity of existing human and institutional capacities, the economic and financial means to support capacity, the relative roles of the public and private sectors, and the degree of involvement of civil society in the decision-making process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The policy context for institutional capacity building should be multi-sectoral and flexible, but coherent in relation to the desired objectives of development. This is to ensure that the process of capacity building is adaptable to changing circumstances-an issue that is particularly relevant in the context of countries undertaking structural adjustment and economic reform programmes when there is a need effectively to nurture and utilise local skills and to mobilise investment resources efficiently.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the light of the development challenge facing African countries, the process of capacity building in the region requires, above all, appropriate and adequate human and institutional capabilities to plan and manage economic and social development processes. These capabilities should include the means of assessing the achievements and impact of capacity building on poverty reduction, employment creation, etc. Existing public sector institutions for development planning and management could provide the operational framework for national capacity building, but the process should also include the participation of diverse social forces, the private sector and non-governmental institutions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Regarding the role of external donors and technical assistance agencies, the approach should be based on the concept of 'partners in development', which implies consultation and dialogue between donor and recipient on all aspects of project planning, design and implementation- with project 'ownership' resting with national authorities. Technical assistance from foreign donors should therefore go mainly towards developing the necessary domestic capacity, rather than contributing to the undermining of existing or potential capacity. Furthermore, assistance provided by external donors should be directed towards the building of capacity for promoting regional economic cooperation and integration through support for the development of viable African regional and sub-regional development organisations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Support initiatives</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The issue of domestic capacity building in Africa has more recently been the focus of attention by the international community as a whole. Indeed, the former World Bank vice-president for Africa, Edward Jaycox, has described 'capacity building' es the 'missing link in African development' which is 'critical to the development effort (of the region) and the chances of success'. UN agencies, spearheaded by the UNDP, have been active in promoting capacity building as a major requirement for attaining sustainable development. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1991, the UNDP Governing Council took a decision which resulted in the development of guidelines covering assistance to governments in the formulation and implementation of national capacity building strategies relating to all stages of the project cycle in the developing countries. The decision coincided with the introduction of the 'programme approach' by the UNDP which emphasised the centrality of national development programmes as the hub for the integration of UN technical assistance activities with national efforts. Emphasis on the use of national skills in the development process was consolidated within the general operational framework for 'national execution', which implied that overall responsibility for management of UN operational activities and accountability remained with the government and other national institutions and beneficiaries who 'owned' these activities. Under these new arrangements, a high priority was thus placed on the strengthening and sustaining of development management and administrative capacities on a long-term basis as an integral part of UNDP technical assistance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The World Bank's interest in capacity building in Africa has been more closely linked to the need for administrative and technical capacity at the national level to carry out policy analysis and economic management in the context of on-going structural adjustment and economic reform programmes. In a trailblazing address to the African American Institute Conference in 1993, Mr Jaycox came out strongly in favour of a new approach to lending to African countries which gave top priority to the development of critical human and institutional capacity. He admitted that the Bank's $4 billion a year lending programme in sub-Saharan Africa had not had the desired impact on development in the region because not enough attention had been paid to national capacity in the past. He went on to criticise the international donor community and financial institutions, including the World Bank itself, for designing and carrying out technical assistance activities which not only fail to solve problems but end up undermining the development of capacity in Africa. Mr Jaycox accordingly pledged to give direct support to capacity building in the Bank's lending programmes, mainly through human resource development and the creation of a 'demand for professionalism in Africa.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The UNDP, the African Development Bank and the World Bank, collaborated in the early 1990s to set up the 'African Capacity Building Foundation' (ACBF), based in Harare, Zimbabwe, with initial seed money of about $30 million and another $70 million attracted from bilateral donors and African governments themselves. The fund is to be used by the Foundation to support capacity building in Africa through training and institution building. Particular attention will be paid to the rehabilitation and strengthening of selected research and training institutions to meet the challenge of indigenous capacity building. Another initiative set up with foreign donors and African support, the Africa Research Consortium in Nairobi, is a good example of collaboration at regional level that is contributing to capacity building in the critical area of economic policy analysis and management. Similarly, the African Development Bank helped establish the African Business Round table which promotes entrepreneurship and enterprise development based on African ownership and control.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Role of the ILO</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For well over three decades the ILO, as part of its technical cooperation programme in Africa, has been involved in a wide range of management development, productivity and institution building initiatives at both national and regional levels. This is consistent with the need to strengthen African training institutions to play a crucial role in providing development managers with the necessary skills to analyse and formulate policy options and manage public and private enterprises efficiently.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the most successful initiatives undertaken by the ILO, in collaboration with the UNDP and the Economic Development Institute (EDI) of the World Bank, is the UNEDIL programme for strengthening management training in Africa. Since its inception in 1987, the UNEDIL programme has proven to be a worthwhile initiative in institutional capacity building in the management field. Support for the programme has also come from national and regional management development institutes (MDIs) in Africa, regional and sub-regional organisations such as SADC and the Commonwealth Secretariat, and major bilateral donors such as USAID, CIDA, NORAD, the Netherlands and France.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Apart from aiming at strengthening institutional capacity, the UNEDIL programme has been instrumental in fostering networking among African development institutes and promoting professional contacts and the exchange of experience. One outcome of the programme has been the revival of three subregional MDI associations which enjoy the direct support of UNEDIL and serve as focal points for UNEDIL's subregional networking arrangements.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Networking on a subregional basis has made it possible to optimise the use of scarce resources and talents, and this has helped to increase managerial capacity in the region as a whole. Collaboration has also permitted an exchange of experience among African institutions, and has brought together expertise both from within Africa and from outside to assist in the development of managerial capacity across the continent. This fits in with the goals of technical cooperation in general, and of South-South cooperation in particular. </P>
+<P ALIGN="JUSTIFY">F.L. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The role of international academic cooperation</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Increasing demands and diminishing resources in higher education</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Professor Dumitru Chitoran</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As we approach the end of the millennium, higher education world-wide finds itself in a paradoxical situation. On the one hand, it is witnessing unprecedented growth. Enrolments are on the increase and so are the expectations placed on it by society. The correlation between investment in higher education and research, and the level of social, economic and cultural development of nations is well-established and is gaining increasing ground at a time when all development has become knowledge-intensive. On the other hand, higher education is in a state of crisis in practically all countries of the world, under the pressure of serious financial constraints. It has to compete for public funds with many other sectors and very often it is among the first to undergo severe cuts. These cuts have reached a dramatic threshold in the developing countries. As a result, the gap between the developing and the developed countries with regard to higher learning and research is wider than ever and it continues to grow.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Inter-university cooperation has emerged as a major tool for the support of higher education in the developing countries and as a flexible mechanism for the rapid transfer and sharing of knowledge, channelled via university links and exchanges. As emphasised in the Policy Paper for Change and Development in Higher Education issued by UNESCO in 1995, 'the most pressing need for international cooperation in higher education is to reverse the process of decline of institutions in the developing countries, particularly in the least developed.' The internationalisation of higher education has advanced steadily, reinforced by current processes of economic and political integration and facilitated by the steady advances in information and communication technologies. But, as indicated in the UNESCO World Education Report (1993), it is increasingly subject to the competitive laws of the market. Universities have been urged to develop an entrepreneurial, commercial attitude and to regard international cooperation mainly as a source of additional income. Fees for foreign students have risen considerably in many countries. As a result, academic mobility is becoming more North-North and less South-North or South-South. The benefits of study abroad, of exchanges, networking and access to data are recognised, but the costs involved render them increasingly a privilege, restricted to those who can afford it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An innovative programme</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UNESCO's response to these trends was the UNITWIN/UNESCO Chairs Programme, launched in 1991. While serving as an instrument to foster overall inter-university cooperation, it was aimed at giving a clear direction and goal, namely to support higher education in the developing countries. It was meant to mark a return to the spirit of international academic solidarity, through twinning, networking and other linking arrangements among universities. The programme was also designed as an innovative form for the rapid transfer of knowledge, and for institutional development in higher education, including the establishment of transnational centres for advanced studies and research, as a means of redressing the widening knowledge gap between industrially developed and developing countries. One other aim of the Programme was to alleviate the negative effects of the brain drain.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The UNITWIN/UNESCO Chairs Programme has seen steady and dynamic development from the very beginning, and has emerged as the major thrust of UNESCO's action in the field of higher education. The favoured institutional framework for carrying out activities is a UNESCO Chair. The programme's activities are extremely diverse. They include the appointment of visiting professors, provision of scholarships and fellowships, facilitating of staff and student exchanges and undertaking of joint research. The 'chairs' are typical of basic units of research and training, with a strong international dimension, since either the chairholder, or some of the professors or researchers associated with its programme come from abroad. Other projects involve complex inter university networks, varying in size from three to more than 50 institutions. Within networks, certain institutions serve as focal points, responsible for initiating activities and securing broad participation in their execution. Also included are cooperation programmes established by UNESCO with major university associations and networks in order to carry out UNITWIN-related activities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At present, there are 163 established UNESCO Chairs (a further 84 are under consideration) and 34 largescale networks (18 more are being developed). A total of over 750 teachers, researchers and other support staff are involved in their activities. It is estimated that 350 courses (mainly at the graduate level), attended by more than 7500 students, were organised by the established UNESCO Chairs during the 1992-1996 period. Also, 120 seminars, training workshops, symposia and colloquia were staged over the same period, attended by more than 6000 participants. Some 580 academics from developing countries spent short periods of time at partner universities in the developed countries to upgrade their training. In addition, 355 scholarships have been granted to students and young academics from developing nations within the framework of the Programme. Research has been encouraged through 240 projects (mainly joint ones) resulting, according to progress reports received so far, in the publication of 55 volumes, some 100 published articles and over 150 monographs and progress reports.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The ACPs in the programme</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A large number of these projects (UNESCO Chairs and networks) concern ACP countries. Africa has been given top priority. Over 30 of the established Chairs are located there and 18 more are under consideration for subSaharan Africa, in order to reinforce the contribution of the programme to the development of higher education in this region. In addition, certain projects located at institutions in Europe and North America carry on activities which are designed to support African universities. A few examples illustrate this. Starting from its bilateral links with several African universities, the University of Utrecht proposed developing these into a broader, multilateral project under the umbrella of UNITWIN. For this purpose, it joined forces with three other European institutions: the University of Lund in Sweden, the Ruhr University in Bochum, Germany and the University of Porto in Portugal. The result was the establishment of the Utrecht/Southern Africa/UNITWIN (USU) network. It includes, at its southern pole, the universities of Harare, Maputo, Namibia, and Western Cape, where UNESCO Chairs have been established in different fields. The aim is to develop each of them into (sub)regional centres of advanced study and research. This is well under way in the case of the UNESCO Chair in Mathematics and Science Education at Western Cape University in South Africa. A first step was to link its activities to those of the MESA (Mathematics Education in South Africa) project, a cooperation project between the Utrecht-Freundenthal Institute for Mathematics Education and the University of the Western Cape. A school for Science and Maths Education is to be established at the University of Western Cape.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another large scale project is the Network of African Teacher Training Institutions, built around a UNESCO Chair at the Ecole Normale Superieure in Dakar. This is designed to serve as a regional centre for postgraduate training and research in the field of education. After several years preparation, activities were launched in 1995. The strength of networking is illustrated by a number of other linking arrangements in support of African higher education institutions. These include the network initiated by the NATURA Group of European universities in the field of agriculture, the ORBICOM Network in the field of Communication, which is a global network but pays particular attention to the needs of African universities, and the UNESCO/John Hopkins University Networking and Partnership in Adolescent Youth Health and Development. The last-mentioned focuses on HlV/AIDS-related research, and includes institutions such as Addis Ababa and Makerere Universities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The agreement signed by UNESCO with the Association of African Universities (AAU) within the framework of UNITWIN provides for support of the latter's staff development and management programme. A UNESCO Chair in Educational Management and Administration is to be established. It will function on a rotating basis at several universities in South Africa, Botswana and Malawi. There are also a number of 'tailor-made' chairs which respond to more specific needs of institutions, notably to develop training and research capabilities in areas such as human rights, democray and peace (at the Universities of Namibia, Addis Ababa and Fianarantsoa in Madagascar), or in the field of Water Resources and Water Culture (at the Universities of Malawi and Omdurman in Sudan). In the latter field, an interesting example is the UNESCO Chair established at the University of Nice, which, although located in France, carries out its activities in Mauritania and has produced the most comprehensive study so far on water resource management in that country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The programme has also made a good start in the Pacific and the Caribbean, even if achievements there are on a more modest scale. There are already 22 established chairs with 14 more under consideration. They cover a wide spectrum of priority fields, including the sustainable use of rain forest resources at the University of Guyana, higher education management and information technology at the University of Havana in Cuba, educational sciences in Fiji, and the use of drugs in Chulalongkorn University in Thailand.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UNESCO works closely with the University of the South Pacific and the University of the West Indies, with which it has established four UNESCO Chairs. Moreover, it has signed a cooperation agreement, in the framework of UNITWIN, with the Commonwealth Secretariat and the Association of Commonwealth Universities for activities in both regions. There is great potential for the further development of the Chairs programme in the Pacific and Caribbean, given the existence of the two regional universities mentioned above and the strong interest of universities in a number of developed countries (such as Australia, Canada, Japan and Spain) in supporting the programme. It appears to be particularly well suited for the systems of higher education in the two regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Funding</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The cost of international cooperation in higher education has risen steadily and this is currently one of the major obstacles preventing the full use of the potential of academic links. New information and communication technologies help reduce costs, but universities in the least-developed countries would first need considerable investment in order to procure and maintain the necessary equipment. That is why UNESCO has based the Chairs programme on funding principles aimed at lowering costs and sharing them in a genuine spirit of academic solidarity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the outset, UNESCO made it very clear that, since it was not a funding agency, it could not, by itself, assume the financial burden of such an ambitious programme, involving several hundred institutions and thousands of university teachers, researchers and students. However, it decided to make a commitment by providing some initial funds. Rough estimates indicate that, over the 1992-1995 period, UNESCO has contributed some $2.5 million (from its Regular and Participation Programmes, Fellowship Bank and Funds-in-Trust) to the UNITWIN/UNESCO Chairs Programme. At the same time, it has pressed for increased international development aid for higher education, particularly from the developed countries, and from international organisations, including the UN specialised agencies. A strong case is made for the benefit of pooling resources and for involving directly the higher education institutions themselves </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UNITWIN-based projects, including UNESCO Chairs, are usually initiated through the direct contributions of UNESCO (the range is generally between $15 000 and $25 000 per individual project). This is meant to help prepare and launch projects and to secure further funding from other sources. The institutions themselves must include allocations for the respective projects in their own budgets and request their appropriate national authorities to make contributions. This applies equally to universities in the developing countries, however poor their resources may be. It serves to indicate that the project in question is indeed seen as a priority by them and by their national authorities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Experience of the UNITWIN funding formula so far gives cause for cautious optimism. Many projects have been able to secure funds by having recourse to the various sources mentioned above. Thus, the Utrecht/ Southern Africa/UNITWIN Project received a first UNESCO allocation of $50 000 in 1993, in order to launch its activities. The fact that it concerned a large-scale project (a network of eight universities, with four chairs established at four African universities and one at the University of Utrecht) explains the larger UNESCO allocation. This was followed by a second allocation of $70 000 in 1994 for the actual implementation of activities in Africa. The UNESCO seed money led to additional funding-$600 000 annually, for the 1992-1995 period, from various Dutch donors (mainly the Ministry of Development Cooperation, through NUFFIC) and from the European Union, and $450 000 from the University of Utrecht budget, including the total cost for the functioning of the UNESCO Chair on African Studies established at that university. The other three European universities participating in the network (Bochum, Lund and Porto) have also made contributions and are now looking for donor funding in their countries. It is important to mention that the four African universities belonging to the network have also allocated funds from their own budgets to the UNITWIN projects and are actively seeking additional resources from aid and development programmes established for their countries by various donor agencies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It can be fairly argued that in terms of cost-effectiveness, efficiency and the ability to generate funding from various sources, UNITWIN compares favourably with existing cooperation schemes in higher education and research. But it is still too early to conclude that the Chairs Programme can continue and develop further on the basis of the present funding arrangements. The needs are arguably too big for the institutions and individuals involved, who may find themselves in a perpetual search for funds. An evaluation of the programme is under way and this will be submitted to the Member States for their decision. UNESCO is hoping that its efforts to revive academic solidarity, and its campaign in favour of higher education in the developing countries will receive the support of the international community. More than ever before, these countries need to develop their capacity for advanced training and research in order to achieve self sustainable development. The academic community has already indicated its willingness to join forces with UNESCO in this undertaking. </P>
+<P ALIGN="JUSTIFY">D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Brain drain : Colossal loss of investments for developing countries</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When a highly qualified professional chooses to leave his own country for another, he does so for one or several legitimate political or economic reasons: peace and security for himself and his family, job satisfaction, better pay and conditions. a higher standard of living, etc. Throughout history, countries and centres of academic excellence which offer these attractions have received the largest numbers of professional migrants and these have, in turn, made substantial contributions, not only to the economic growth of their host countries, but also to the scientific and technological advancement of humanity. The wave of German scientists who moved to the United States after the Second World war, and their discoveries and inventions, come readily to mind. On a global level, therefore, the free movement and interaction of highly skilled people is a positive thing. But the costs to the home countries of losing their professionals is incalculable-in terms of both development opportunities and loss of investment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Whereas Western Europe was the main loser, especially to the United States, up until the 1960s, the developing countries have emerged in recent years as the biggest suppliers of qualified professionals to the industrialised world as a whole. Today there are more than a million and a half skilled expatriates from the developing countries settled in Western Europe, the USA, Japan and Canada. The USA's educational system and its research institutions are heavily dependent on them. These migrant professionals contribute in no small way to increasing the disparities between the world's rich and poor nations. And it is the developing countries that need them most.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Africa, which has serious shortages of manpower, has been worst hit. It is said to have lost 60 000 professionals (doctors, university lecturers, engineers, surveyors, etc) between 1985 and 1990 and to have been losing an average of 20 000 annually ever since.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are more than 21 000 Nigerian doctors practising in the United States alone. Meanwhile, Nigeria's own health system suffers a cruel lack of medical practitioners. 60% of all Ghanaian doctors trained locally in the 1980s have left the country, according to the UNDP's 1992 Human Development Report, while, in Sudan, 17% of doctors and dentists, 20% of university lecturers, 30% of engineers and 45% of surveyors have gone to work abroad.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although it is difficult to calculate the cost of an expatriate professional in terms of the nutrition, health care and education provided by households and the State, it is clear developing countries are losing colossal amounts of investment annually to the developed countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The US Congressional Research Service, for example, computed in 197172 that the USA gained $20 000 annually on each skilled migrant from the developing countries. If this rather conservative amount is extrapolated for Africa, then the continent lost more than $1.2 billion of investment between 1985 and 1990 on the 60 000 or so African professionals who emigrated during that period. Much closer perhaps to the truth today would be the estimate made by the United Nations Conference on Trade and Development (UNCTAD), using 1979 prices, which put a cash value of $184 000 on each African professional migrant (and this only for those between the ages of 25 and 35).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the other hand, expatriate remittances, particularly from skilled workers who earn higher salaries than the average migrant, constitute an important source of funds for development in their home countries. Throughout Africa, households are being maintained by remittances from relatives working abroad. Also, fine buildings are being put up and small-scale projects are financed in villages and cities across the continent with funds sent from overseas. But taken together, these will never be large enough to compensate Africa for the loss of investment suffered as a result of the 'brain drain'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Serious flaw in international cooperation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The migration of highly qualified professionals from the developing countries is an extremely complex problem which presents the international community with a major dilemma. First, the 'brain drain' cannot be stopped by force nor can it be legislated against. It is linked to fundamental human rights- the right of individuals to move from one country to another, although the exercise of that right is governed by the immigration policies of individual countries. Second, it is fundamentally a national problem which can only be resolved at the national level by providing enough incentives for qualified nationals to remain at home. Third, some industrialised countries like the USA and Canada, have historically operated liberal immigration policies. Even European states, whose immigration policies tend to be more restrictive, have a good number of third world professionals, but there are over a million in the USA and Canada. It is arguable whether, under the circumstances, the liberalisation of the international labour market under the World Trade Organisation, as is being suggested (even by some developing countries), will actually be in Africa's interests.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The reasons for Africa's brain drain problem are legion and easily identifiable, being both structural and economic. The most often cited cause is the continent's school curricula which many see as still largely modelled on the systems of the former colonial masters. This, it is argued, has led to the production of graduates in disciplines that have little or no relevance to the socio-cultural and economic milieux of the continent. This is a highly debatable assertion, given the large numbers of the technical assistants currently working in Africa who are products of the educational systems of the former colonial powers-at least some of whom are having a positive impact on the continent's development. This, however, must not distract from the fact that African higher schools systems are illequipped to produce the right skills for Africa's development needs. Because of shortages of both science equipment and teachers, the system instructs the vast majority of pupils in arts rather than in science and technology-and it is the latter which hold the key to economic growth and development. Thus, there is overproduction of graduates in areas where there are few employment opportunities. This results in high levels of migration, even, paradoxically among the few trained scientists because of the absence of an environment conducive to full professional expression and satisfaction. It is not uncommon for things as simple as electricity and water supply to provide reasons for emigration. Examples abound of frustrated African scientists who have had their experimental work of several years destroyed overnight through power failures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Powerful factors in the brain drain include Africa's poor rates of economic growth over the past 30 years (worsened by structural adjustment measures which have resulted in dramatic falls in living standards) and political instability (disturbances in Nigeria and Zaire, civil war in Liberia, Sierra Leone and Somalia etc). Thousands of qualified professionals have been forced unwillingly into exile, and the majority of those left behind, in these times of serious economic crisis, are engaged in unskilled pursuits-in petty trading and taxi driving-far removed from their professional training. The loss of investment associated with this situation cannot be underestimated.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sub-Saharan Africa is in the paradoxical situation today of having large numbers of graduates in various disciplines -from medicine and engineering to architecture and accountancy-who have either emigrated or are simply unemployed, while it hosts a large army of foreign technical assistants. Indeed, Africa receives more advice per capita than any other continent. In 1988, there were more than 80 000 technical assistants, and today the figure is well over 100 000. These experts are believed to cost donors a total of $4bn annually to maintain, a figure which represents nearly 35% of Africa's total official development aid. This situation reveals a serious flaw in the operation of international development cooperation. Would it not be more efficient and cost effective to employ qualified African expatriates in the place of many of these foreign technical experts. The former, after all, have both linguistic and cultural links with the continent. The United Nations Development Programme (UNDP) has a programme in this area which points to a possible way forward. The article on that programme, TOKTEN, follows. </P>
+<P ALIGN="JUSTIFY">A.O.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">'Brain gain' : A cost - effective UNDP programme</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the scale of the brain drain problem facing the developing countries, the UNDP's Transfer of Knowledge Through Expatriate Nationals (TOKTEN) project may not amount to much, but it has proved, in its 19 years of existence, to be a cost-effective way of getting highly qualified expatriates from the developing countries to contribute to the development of their countries of origin.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It all started in Turkey in 1977 by pure accident. A Turkish mineral expert in Alberta, Canada, was asked by a compatriot if he would be kind enough to come over to Turkey and explain his innovative coal cleaning process to the staff and students of his old university in Ankara-the Middle East Technical University. He expressed his interest in the project. Soon afterwards he was contacted by the UNDP which offered to fund part of his trip to Ankara. The expert spent one month in Turkey giving a series of seminars, not only at the Middle East Technical University, but also at the Istanbul and Dokuz Eylul Universities. During these lectures, he made recommendations on resolving Turkey's specific coal utilisation problems. His impact was immense and such that the UNDP was inspired to set up the TOKTEN project along similar lines to help developing countries gain from the knowledge of their expatriate professionals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The system is simple. Member States of the United Nations can apply to join the project. The latter is administered in each country by a National Working Commitee (NWC) which is made up of representatives from the government, local organisations, the private sector and the UNDP. Institutions of that country (government ministries and agencies, private and public sector enterprises, universities, research and development institutions, hospitals, etc) can apply for assistance in a variety of areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Applications are processed by the NWC and recruitment of experts is usually in one or more of the following ways:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> through consultants with lists of experts recognised by the Government as having extensive contacts within their expatriate communities;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> through embassies and missions, alumni associations and research institutions;</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> through prominent members of the country's expatriate community who identify and alert other high level expatriates of the opportunities to return home and serve their countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When the Working Committee chooses a consultant, an offer of assignment is made. The beneficiary organisation and the consultant will then determine the timing of the mission and inform the UNDP.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">TOKTEN assignments last between one and three months depending on the ability of the consultant and the needs of the beneficiary'. They are not meant to be highly remunerative. Consultants are only entitled to round trip economy fare tickets (by the most direct route) and a daily subsistence allowance at the prevailing UN rate. The costs are paid out of the beneficiary country's 'Indicative Planning Figure'(IPF) which is the amount of assistance the UNDP makes available to a developing country over a five-year programming cycle. Health insurance cover and accommodation is not provided. Usually these are the responsibilities of the beneficiary government or organisation. The salaries of the consultants during their absence are paid by their affiliated employers whose agreement is often necessary for the projects to go ahead.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">TOKTEN consultants are thus not motivated by money but by a genuine desire (with a modicum of patriotism) to contribute to the development of their countries of origin to which they retain strong cultural and linguistic ties. And their impact on the ground is usually immediate and measurable. Pressures are not put on volunteers to return permanently to their countries, although many have chosen to do so since the programme began in 1977.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The system is not only low-cost and cost-effective. It covers a great variety of specialised fields and enables programmes to be implemented with speed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Conditions for success</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A UNDP assessment of the programme in 1987, ten years after it began, concluded that regular monitoring of its operation had enabled information garnered to be applied to increase its effectiveness. It had been found, for example, that short-term expatriate consultancies were especially beneficial when the problem tackled was specific and the consultant selected was of international standing, when both the requesting organisation and the expatriate were well prepared in advance, and when the initial mission was followed up by a series of measures, often including a return visit.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By 1992, 35 countries were participating in the programme and over 3800 consultancies had been run. Since then, the number of countries has increased dramatically to 51 and con</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">sultancies to 5000. In 1994 and 1995 alone, 28 countries reported over 700 consultancies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It has also become clear that, whereas the main recipient institutions have been government agencies, science and technology research institutions, universities and organisations, the private sector is increasingly showing interest in the programme. The number of female specialists is also increasing: in 1991, 40 consultants were women and last year this figure rose to over 100.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So far, the ACP countries participating in the programme are; Benin, Cape Verde, Central African Republic, Chad, Dominica, Ethiopia, Fiji, Guinea, Guyana, Haiti, Liberia, Nigeria, Sao Tome &amp; Principe, Sierra Leone, St Lucia, Trinidad &amp; Tobago and Uganda.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Success stories include a highly skilled Guyanese medical practitioner in the United States who returned home after 17 years to assume the post of minister of health. He had been sent to oversee the introduction of certain aspects of health care such as preventive medicine (immunisation, general child care and nutrition), treatment of trauma (victims of accidents and violence etc) and the establishment and management of the physical facilities for emergency patients. During his stint, his recommendation on the upgrading of the emergency room facilities was rapidly implemented and this contributed significantly to improving patient care. Another story involved a Guinean banker who, after a consultancy stint in Guinea, abandoned a lucrative job in France to return home permanently to work at the Central Bank of Guinea, helping to set up a new loan system for commercial imprt and export businesses. Guinea, in fact, has been one of the greatest beneficiaries of the TOKTEN programme with numerous consultancies involving the University of Conakry, covering more than 20 disciplines.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For very small sums the programme is ensuring that developing countries which have invested enormously in the education of their expatriate nationals have a return, at least, in the form of the knowledge they oquired.</P>
+<P ALIGN="JUSTIFY">A.O </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Mobilising Commonwealth skills for Commonwealth development</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The role of the Commonwealth in the economic and social progress of its member states is neither widely known nor widely publicised. Yet for over 25 years, the Commonwealth Fund for Technical Cooperation (CFTC) has made significant contributions to the efforts of its developing member countries to accelerate the pace of their economic development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The recognition by the Commonwealth that people are its greatest resource forms the basis of its approach to development assistance-providing, in the short term, specialist technical skills which are either not available or are in short supply to governments to enable them to fill key positions in areas as diverse as export and industrial promotion, high-level economic and legal services etc, and in the longer term, a wide range of training programmes in areas that are crucial for economic development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Commonwealth Fund for Technical Cooperation is funded by voluntary financial contributions from member governments which, as has just been mentioned, can also draw on it according to their needs and priorities. As a pioneer of technical cooperation between developing countries, the Fund recruits its experts from these countries and encourages South/South cooperation. It is thus not uncommon to see West Africans serving, on short-term contracts, as legal officers in remote Pacifc island states or Sri Lankans or Indians advising on new agricultural techniques in Africa. The Fund is administered by four separate divisions within the Commonwealth Secretariat: the management and training division; the general technical assistance division; the export and industrial development division, and the economic and legal advisory services division. In 1994-95 the CFTC's financial resources stood at around f23.6 million (ECU 30m).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Human resource development</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nearly one-third of the CFTC's budget is spent on human resource development, helping enhance people's skills through a mix of training workshops, study visits and individual attachments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some 4000 training fellowships were awarded in 1993-95 to enhance technical skills. These were given to middle and senior professional, technical and administrative managers to study at some of the Commonwealth's best institutions or to take up work attachments (63% of training takes place in less-developed countries).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Fund also enables universities and other institutions to become centres of excellence and upgrade the tuition they offer by appointing academic and technical specialists. In 1993-95, for example, it helped five universities in Africa and the Caribbean to run applied Masters courses through collaboration with other Commonwealth universities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As the CFTC is usually able to meet only 60% of the requests it receives for specialised training, its programmes are held on a regional and pan-Commonwealth basis to maximise impact, especially in topics such as administrative reform, financial management and strategic planning.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Fund's training priorities include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- first and foremost, identifying needs (consultants are sent to countries to examine their development plans and help them to prioritise training needs).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- providing education and training in key areas that reflect CFTC concerns such as well-managed economic and financial reform by government, sustainable development, participation of women and application of technology.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- ensuring an integrated package of consultancy, advice and training to help managers in government, and public and private sector enterprises to coordinate and manage reforms and restructuring.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- organising policy workshops and seminars that bring together senior government officials, executives and academics from Commonwealth countries to pool experiences, learn examples of best practice, discuss problems and reflect on emerging issues.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- giving support to institutions to offer new and specialised education and training programmes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- providing technical and vocational training under the Commonwealth Industrial Training and Experience Programme (between 1993 and 1995, workshops were held in hospital equipment repairs, railway repairs and maintenance and computer-assisted manufacturing).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- providing training in information systems, new technologies and environmental issues (governments are helped to develop management information systems and apply information technology). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-setting up programmes for women with a particular focus on entrepreneurs and community managers (among other initiatives, the CFTC is helping three African universities develop specialised programmes in entrepreneurship for women in non-traditional sectors).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-coordinating wider linkages among professional networks to facilitate exchanges of information and examples of best practice (the CFTC recently helped to set up the Commonwealth Association for Public Administration and Management to assist in improving public service performance and in raising ethical standards).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Expertise on tap</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Shortage of skills is one of the biggest stumbling-blocks facing countries trying to raise the living standards of their people. Providing experts accounts for about one-third of the CFTC's budget.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because its assistance is relatively small and carefully targeted, it avoids the potential waste associated with larger scale projects and poor technical planning. In 1993-95, the cost both of a typical long-term expert and an average project was around £50 000 (ECU 62 000) a year. Experts can be in place within three or four weeks of project approval.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During the same period, over 200 long- and short-term experts were provided to 43 developing Commonwealth countries, six dependent territories and 18 regional organisations. The expertise requested is extremely diverse, from hydrography and agroforestry to tourism, statistics, legal affairs, health, social planning and computer science.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Assignments for short-term experts can range from a few days to six months. Their role is advisory, helping governments to introduce new systems or technologies. Long-term experts stay usually from six months to two years; others may stay up to four years. Experts assist in the development and implementation of policies or in the provision of managerial skills and the training of counterpart staff to take over in due course. Some long-term experts are trainers in specialist fields.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The CFTC makes every effort to appoint women experts. In 1993-95, they made up 13% of experts that were sent to the field. These included a consultant anaesthetist in Ghana, an agricultural economist in Mozambique, an information specialist in Barbados, a fisheries development officer in Papua New Guinea and an environmental lawyer in Seychelles.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A scheme to allow suitably qualified and experienced people to volunteer as short-term experts for a maximum of three months was launched in mid-1995. The scheme draws on experts from the Commonwealth who are willing to give their services on a voluntary basis to developing countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Entrepreneurs come first</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In its help to small businesses, the CFTC focuses on those who manage the businesses and identify new entrepreneurial talent. Most assistance is given to small states, especially in the Pacific. The programme has three phases: the first relates to 'surveys of opportunity' which is aimed at identifying suitable entrepreneurs, investment opportunities and potential for expansion as well as specific problems. Next comes 'workshops on entrepreneurship development' during which business owners and operators are helped to think creatively, to become more aware of opportunities that are available and to act strategically when planning expansion. And the last are what we call 'business clinics' in which one-to-one counselling is provided to an entrepreneur at his or her business. This personal support has proved very successful in helping individual entrepreneurs to become more efficient and competitive and, by implication, adapt to changing world economic conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Developing exports</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The CFTC has pioneered the use of Contact-Promotion programmes and 'Buyer-Seller Meets' forums to help small exporters. These forums allow company representatives, often from small Commonwealth countries, to display their wares and meet prospective buyers from other countries. CFTC consultants plan these activities well ahead, short listing producers that are likely to succeed, identifying suitable foreign markets and advising on redesigning of products. Sometimes exporters and factory staff also receive training.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The CFTC funds a special 'export development programme' for women entrepreneurs. This includes detailed country studies of women engaged in exporting as well as sales promotions abroad. Studies of this type have recently been conducted in Cyprus, Sri Lanka and Zambia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Women are helped, under the programme, to adapt their handicrafts for export, improve their manufacturing techniques and undertake sales missions abroad. Training is also given in export marketing, product development, costing and pricing. If necessary, changes to government policy are recommended. In 1994, the assistance given to Ghanaian women to develop markets for their basket ware and handicrafts is estimated to have helped generate sales worth US$3.1 million (ECU 2.4m). </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">EU's investments in education and training in the ACP states</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY">by Digby Swift</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Community's investments in human resource development-health, nutrition and education-in ACP states have regularly been covered in the pages of this magazine whether in the context of dosiers or of country resorts. Here we present a brief description of how the EU's policy in education and training evolved under the Yaounde and Lom&eacute; Convemntions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Educating all the people. This is not just a slogan. In a poor, underdeveloped country, there may be some short-term gains from supplying high quality education and training to an elite few. But, as the 'Asian Miracle' has proved, major long-term gains in development and wealth are possible only if the entire population possesses a reasonable level of education.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Now for the problem. For many countries, notably those of sub-Saharan Africa, a large proportion of school age children receive no education at all. Of those who do attend school, many receive little benefit from their education because of the very low quality of provision. Only a small minority reach secondary education. And yet a higher proportion than ever of national budgets is now going to the education sector.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The problem is urgent because of the time it will take to resolve. Even if we could wave a magic wand to provide all children with a good primary education, it would take a decade to see the benefits.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">How is European aid helping to tackle this problem? What have been the guiding principles of European aid to education in the past? And why is the problem still acute in, for example, subSaharan Africa, despite decades of investment in aid to education ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Aid mirrors developments</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Aid to education has mirrored developments in the education sectors of the countries concerned. For example, the low-income countries of Africa, which account for 73% of Africa's population, have seen a rapid expansion in their education systems followed by a collapse of funding. This has resulted in a serious decline in standards of provision. European aid, which began by providing piecemeal assistance to infrastructure and manpower, shifted to a 'project approach' to tackle these emerging problems and is now moving towards a coordinated sectoral approach to help tackle the reform of whole education systems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From 1970 to 1980, the number of pupils enrolling in the primary schools of developing countries more than doubled, and the numbers in secondary and tertiary education quadrupled. Even relative to the increasing population, there was a 90% increase in the proportion of primary-aged children in school, and a large increase in the proportion of girls. This growth was accompanied by a doubling of government budgetary resources made available to education.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the massive general economic decline between 1980 and 1985, the money made available for education from the public purse fell by 40%, yet the education systems continued to grow. The result was that teachers' salaries plummeted, and funds for non-salary recurrent costs such as teaching materials and maintenance virtually dried up.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Since 1985, the financial situation has somewhat improved and funding is now at an all-time high. Nevertheless, for many African states, the education sector is in a state of crisis. Buildings are crumbling and inadequate; teachers are untrained or undertrained and often absent because of low incentives and weak supervision. There are few books and other teaching materials. Consequently, many pupils leave school virtually illiterate and innumerate. Moreover, because of the low quality of instruction and increasing costs to parents, many parents are no longer bothering to send children to school even when places are available. Primary enrolment fell by around 10% between 1990 and 1992. Thus in many countries, a fundamental reform of the sector is seen as the only way forward.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Evolution of aid</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the early days of European aid, education and training were seen as suppliers of manpower for countries to modernise their economies. The priority themes of the 1970 Yaounde Convention for European Community aid were industrialisation, regional cooperation and international trade. Community support to education and training focused on the construction of colleges and university faculties to serve industrialisation and regional cooperation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 1975 Lom&eacute; I Convention referred specifically to 'the establishment of regional institutions of advanced technology, in the context of training programmes to enable nationals to participate fully in economic development'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 1980 Lom&eacute; II Convention introduced multiannual training programmes, and support in the form of training awards and courses/seminars; experts and instructors; teaching equipment; collaboration between training or research establishments and universities. The emphasis was still on vocational training for other sectors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A significant proportion of European bilateral aid to education and training took the form of European teachers for secondary schools, colleges and universities. These helped to cover the shortage of locally trained teachers, whilst educating an elite able to fill senior and middle positions in the public and private sectors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By 1985, problems were becoming all too apparent within the education systems being supported. As in other sectors, there was increased emphasis on the 'project approach' towards tackling these problems. Thus the Lom&eacute; Ill Convention includes support to education and training 'in the form of integrated programmes aimed at a well defined objective'. This could include, for example, 'assisting the ACP States' own efforts to restructure their educational establishments and systems and to update curricula, methods and technology employed, in order to step up the effectiveness and cut back the cost of all types of training'. A concern for under-represented groups, particularly women, was also becoming explicit.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By 1990, the concept of investing in people through education and training had moved high on the donor agenda, and alongside it, a growing concern for sectoral reform. According to the 1989 Lom&eacute; IV Convention, 'Cooperation shall be aimed at supporting development in the ACP States, a process centred on man himself and rooted in each people's culture. It shall back up the policies and measures adopted by those States to enhance their human resources, increase their own creative capacities and promote their cultural identities. Cooperation shall also encourage participation by the population in the design and execution of development operations.' In a chapter entitled Operations to enhance the value of human resources, a section on Education and Training refers to supporting the ACP State's efforts to 'reform their basic education institutions and systems, in particular by providing overall primary education coverage and adjusting imported systems as well as building them into development strategies'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the late 1980s and early 1990s, European states and the Community joined the World Bank in support of structural adjustment. In a 1991 communication to the European Development Council, the Commission stated that it 'will give absolute priority to the social dimension of adjustment, in particular ensuring that the health and education sectors are adequately covered, in conjunction with sectoral reforms introduced or planned in these two areas.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Balancing this concern for system reform has been a growing appreciation of the importance of decentralised cooperation. An example is the cost-sharing microprojects for grassroots development first introduced in Lom&eacute; I with explicit mention of support to primary schools. Another example is the need to support the activities of nongovernmental organisations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A new policy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Two events in the early 1990s have had a profound impact on European support for education and training. The first was the World Conference on Education for All: Meeting the Basic Learning Needs held in Jomtien in 1990. This emphasised the need for universal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">primary education and adult literacy to be firmly placed on the political agenda, and has resulted in a profound swing of donor support away from higher education and towards primary education. The second important event was the 1992 Treaty of European Union which requires the coordination of Member States' policy and operations, particularly in the social sectors. Guidelines are contained in the 1994 Council Resolution on support to education and training in developing countries in which 'the Council emphasises that education, in particular basic education, is a fundamental right'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">According to the Resolution, 'the priority for the Community and the Member States must be both to maximise access to education within the limits of the resources available and to ensure that the quality of education provided is suited to the needs of the majority of students. 'This is to be achieved through 'a balanced, programme-based strategy, tailored to the specific circumstances of the individual developing country', with pride of place accorded to basic education. It should provide 'support to the developing countries' own policies and efforts', not acting as a substitute for local initiative, and should involve better integration of action under structural adjustment with education sector priorities and aid activities. The Council also recommends a special emphasis on coordination in a number of pilot countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From the outset, Community aid to education and training in African, Caribbean and Pacific countries has been in response to requests from the ACP states with an emphasis on ownership of the resulting programme by those states. What the new policy introduces into this process is a dialogue between government and all donors on needs, priorities and approaches set in the context of the education sector as a whole. Only through such a comprehensive approach can developing countries and European states reach a true partnership in realising the education and training needs of all citizens on which the future of their countries so crucially depends. </P>
+<P ALIGN="JUSTIFY">D.S.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Analysis</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">EU-ACP relations : Building for tomorrow</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY">by Kenneth Karl</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">1989 saw the end of the Yalta inspired twin-superpower dominance. Nations had to examine their priorities in their desire for integration in an international environment in which geostrategic and economic realignment would be unavoidable. The philosophy which had served as a basis and reference point for North/South relations throughout the Cold War period is now being called into question and necessary adjustments in ideas have been triggered.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Lom&eacute; Convention, which governs the development-cooperation relationship between the EU and the 70 ACP countries, is a unique North/South cooperation agreement on account of its contractual nature, its durability, the funds it allocates and the fact that it provides for a permanent dialogue. But it is also now at a decisive point in its history.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Those who regard the Convention as out-of-date and in need of renovation, and those more radical critics who believe that it no longer serves any useful purpose and must be phased out, both argue that a new direction is needed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Beyond all the criticism formulated against this system, the fundamental question remains as to whether the Lom&eacute; Convention will be able, given the necessary changes, to carry on after its fourth version expires.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The years between now and the end of the century will, naturally, see the application of the revised Lom&eacute; IV, including the substantial improvements made to it. However, this same period must also be used to prepare the ground for ACP/KU development cooperation in the future, whatever form it might take.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Shortly after his nomination as European Commissioner for relations with the ACP countries and South Africa, Professor Pinheiro commented, realistically, that the ACP countries are no longer 'in fashion'. The change of emphasis can be seen clearly if one looks at the EU's burgeoning relations with its eastern neighbours from the former Communist bloc (illustrated by the wide range of European programmes now benefiting these countries). One might also cite the strengthening of ties with countries in the Mediterranean basin. Economic and security concerns underpin this development, but it undoubtedly reduces the significance which was once accorded to the ACP states.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moreover, the economic objectives of virtually all EU countries, as they seek to reduce budget deficits and deal with increasing internal social problems inevitably put pressure on the amount of development aid being granted to the Third World.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This situation is, of course, not restricted to the European Union - which in fact remains the world's main contributor of official development aid. At the instigation of a Republican dominated Congress, the United States is planning much more swingeing cuts in its contribution, both to certain international agencies and to certain regions (including Africa).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This undeniable cutback in public development aid has been offset in recent years by net increases in private capital flows, but the geographical distribution is highly skewed. Only a few of the poorest developing countries have benefited from the trend, the main 'winners' being the emerging states of Asia. These include countries such as China, India and Indonesia which, it is worth noting in passing, do not have particularly good human rights records, in the sense that the term is understood in Europe. Despite the fact that ACP countries have identified potential for attracting foreign investment, they have not actually benefited from this change in resource flows.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this climate, with official development aid in inaeasingly short supply, innovative methods for making optimum use of the available resources must be devised within the context of the Lom&eacute; Convention.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On current indications, it is quite possible that in the year 2000, the Lom&eacute; Convention will be filed away in the archives. ACP/KU relations will certainly have to be more in step with recent developments on the international scene. The initial reasons for the establishment of a cooperative relationship between Europe and the ACPs, following the signature of the Rome Treaty, are now outmoded. As Paul Valery has commented: 'One of the worst mental aberrations is to think that things can survive when the reasons for their existence have gone'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So, what type of development cooperation should the countries of the European Union and their ACP partners aim for in the future ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Alternative trends</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU has stated that it is in favour of a globalisation of aid within an innovative framework. One of the first questions to be asked is whether uniform cooperation with regions whose monolithic character is being increasingly called into question is still desirable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Variable geometry in development cooperation relations is increasingly being seen as the trend to be followed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If this option is chosen, there is a risk of the following scenario being created: The EU's relationship with the Caribbean could become diluted within its relationship with Latin-American countries and links with the Pacific countries could become confused with economic relations with Asia. What would then become of Africa, the continent needing most attention on account of the wide range of its difficulties and its increasing marginalisation ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1990, the United Nations General Assembly, aware of the African question, adopted a new agenda on development in Africa, thus making that continent its number-one priority. Europe, on the other hand, must not simply focus on Africa but must invent new modes of action which are more concrete and more effective.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Secondly, recent trends imply greater conditionality. This has been taken on board not just by EU Member States. A number of multilateral aid agencies have also included it in their strategy. The OECD's Development Aid Committee believes that future relationships between North and South will be greatly influenced by conditionality and, indeed, the Organisation goes so far as to advocate this approach.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, conditionality in terms of development is a strategic element which must be handled with extreme caution. If cooperation, whether today or in the future, is to be based on conditionality, then it can only be rendered effective if aid recipients (both governments and the governed) are genuinely committed to the idea. They must be convinced, in a climate of resource-scarcity, than the approach is motivated above all by a desire for greater success.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union thus has a vital role to play, making full use of its advantages in terms of dialogue and consultation in order to prevent conditionality being perceived as a condescending mechanism. Thereby, it can help to prevent conditionality from generating the well-known perverse effects of 'tied' aid.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Of course, conditionality raises the thorny question of national sovereignty, but it is important to observe that modern international relations have moved on, both de jure and de facto, from a concept of absolute sovereignty to one of relative sovereignty. This is illustrated by the trend towards humanitarian intervention as a right, the requirements of the Bretton Woods institutions, supranationality in certain regional international organisations, and the very fact of world economic interdependence.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This does not mean that the developing states should sell off their sovereignty to the highest bidder but that conditionality should be the subject of negotiation. Donors must be more flexible in their demands and thereby give the country in question such room to manoeuvre as is necessary for programmes to succeed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thirdly, development of the private sector appears now to be approved by all parties. Since independence, the State has been omnipresent and omnipotent in most productive areas of ACP economies. Given the failures of the public sector, private enterprise is now being called in to help. Its development is one of the sector specific policies which will and must receive most support.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The development of the private sector must permit better distribution of the fruits of the growth that it generates and promote integration of the ACP countries into the market economy. There can be no question of pitting private enterprise against the public sector, because any Manichean approach in this sphere might prove to be risky. It is important also to stress that free market development cannot take place overnight and that it is subject to inescapable macro and microeconomic preconditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Indeed, the birth and expansion of a dynamic private sector depends on the politico-economic fabric. This includes reliable financial bodies, functioning financial intermediation, adequate infrastructures, technical qualifications and training, a suitable legal/ regulatory framework, institutions to support private businesses, the channelling of the informal sector and a public sector which is prepared to play fair, aware of its regulatory role. These, in short, are the necessary ingredients for the adjustment of the private sector to permit the development of a true enterprise culture.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The development of a harmonious private sector will make it possible more easily to achieve the transformation and export objectives required by international competitiveness. It should, therefore, help to counteract the erosion of commercial preferences generated by the Uruguay Round. The latter's time limits should, in any case, be extended, because it seems clear that the ACP countries will be unable to fulfil their obligations by the end of the moratorium obtained by the EU during the negotiations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The notion of compensating for inequality that is found in international development law, implies the adoption of a normative system to counteract the weak trading position of developing countries vis-a-vis their competitors in the North. But in recent times, this idea has been losing ground and it is unlikely to cut much ice with the WTO authorities. Legal equality in a situation where there is structural inequality is not, in fact, equitable, and it is therefore necessary to find some other way of mitigating the adverse effects, looking at it in a global context.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Promotion of domestic and foreign investment should be better supported. People talk of the 'risk/ country' threshold that deters foreign investors. It may be that this can be measured objectively by looking at economic and other indicators, but even if this is not possible, it clearly exists as a psychological barrier. This is a problem for many ACP countries and it needs to be crossed, using measures which tackle the many obstacles to investment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Changing the culture of development cooperation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Besides all the technical aspects, one could argue that the shortcomings of the Lom&eacute; Convention stem also from the perceptions of those involved in development cooperation. In short, it is the actual concept and culture of development aid which must be changed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the European side, the colonial legacy has conditioned attitudes, imprinting on them a dominant patemalism which is prejudicial to the aim of development. This European concept of cooperation must be overturned. Moreover, development cooperation must not be seen as the art of the possible but as the art of making possible what is strictly necessary, by virtue of genuine negotiation with the countries which have resolved to move forward.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moreover, it is desirable to have a better developed policy of informing European public opinion about development cooperation. An effort is needed to counter false impressions, such as the one left by the French journalist who wrote: 'Official development aid is like taking money from the poor in rich countries to give it to the rich in poor countries'. Better information is needed to ensure that the public can decide such matters for itself.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Coordinating the Union's policies with those of the Member States now presents an enormous challenge. The political obstacles are huge and development cooperation may well suffer as a result of them if the objectives of coordination, coherence and complementarity contained in the Maastricht Treaty are not achieved.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As for the ACP countries, success in their economic development depends on many factors, cooperation being only one of them. Many political leaders in these nations have too often described cooperation with the North as the only way in which they can develop. In fact, this should be seen as nothing more than an additional factor - supporting the national effort and a genuine desire for development. It is pure fantasy to believe that development can be set in motion solely on the basis of an external impetus. To succeed, it must come from within a country. This is why future cooperation between the EU and the ACP countries must progress towards reinforcing the aptitude of the latter to devise, master and control their own development process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the future, the ACP countries must propose concrete and responsible solutions to their partners, doing so by means of the dialogue system. They must also promote development based on participation, particularly with the involvement of young people and women.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The fact that the ACPs can offer a credible prospectus for development must be acknowledged. It is undoubtedly a challenge, but it can successfully be overcome if a climate of stability, security and confidence is created, matched by an unambiguous political will.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In KU/ACP relations, programmes must include the long-term vision necessary for sustainable development. Too often in the past, the strategy has been aimed at an immediate and ostentatious result. Successful development in the future will depend crucially on a change in such attitudes. </P>
+<P ALIGN="JUSTIFY">K.K. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Let us know what you think</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The debate about the future of cooperation between the European Union and the ACP states is now beginning to gash' pace. Last year, we established the 'Analysis' section in The Courier to report on this debate-and give readers an opportunity to express their own views on the subject.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The response so far has been encouraging, but it has come mainly from the European side. We are keen to receive contributions from ACP readers as well. If you have you own ideas or opinions about what should happen after Lom&eacute; IV expires, why not put them on paper and send them to us. Our address is on the inside front cover of the magazine. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The view of civil society on the future after Lom&eacute; IV</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This was the subject of a conference which took place in Maastricht from 12-14 June, under the auspices of the European Centre for Development Policy Management (ECDPM). It brought together participants from ACP countries and Europe, including representatives of civil society (NGOs, the private sector, etc.). Four major topics were addressed:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· How can a new KU/ACP commercial relationship be constructed ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There was agreement that some form of preferential trade regime should continue after 2000. Some participants stressed the need to Promote 'fair trade', which would contribute not only to growth but also to development. The impact of individual trade preferences is not always clear-cut, but obviously there cannot be a single solution covering all problems in all ACP countries. An analysis of negative constraints demonstrated the difficulties involved in reconciling the rules of the Lom&eacute; Convention and those of the World Trade Organisation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· How can the private sector become involved in development ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The most important aspect of this topic is knowing how to create a favourable and business-friendly environment which will enable the private sector to play its part-and the role the European Union could play in this process. The private sector was defined as both formal and informal, encompassing large, medium and small enterprises, whether local or foreign. The importance of a strong local private sector in guaranteeing long-term stability was particularly emphasised. In this respect, the view was expressed that the role of the state and its relationship with the European Commission should be redefined. There was also a call for time to be set aside time for effective dialogue, and to create the space for a partnership between the public and private sectors. It was felt that the role of Economic and Social Councils should be expanded and specified more clearly. As for the specific issue of privatisation, the point was made that this should not be seen as a panacea and that it should be approached on a country-by-country basis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As regards current instruments, it was noted that their objective is essentially to meet public-sector requirements. The role of the Centre for the Development of Industry (CDI) attracted some criticism. Speakers felt that the private sector should be more involved in the preparation and implementation of cooperation programmes with the European Community. Direct financial support to the private sector was seen as desirable, including backing from the European Investment Bank.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What partnership ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The partnership concept was seen to have been eroded over the past two decades, with the pretext of efficiency resulting in a more paternalistic approach. Mechanisms needed to be found to enable EU priorities and the prerogatives of ACP countries to be reconciled. Reference was made to the political nature of the origin of the partnership and the need to find a new political raison d'etre for this type of relationship. The problems of cohesion within the ACP group and its relations with the EU were also raised, and there was a discussion about the possibility of giving the Convention a regional character-although a number of speakers expressed reservations about this.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the European side, two lacunae emerged, namely coordination between donors, and consistency between Lom&eacute; and other Community policies (including relationships with the Bretton Woods institutions).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition to the principle of partnership, some participants were keen to stress the motives of solidarity and common interest that lay behind cooperation. It was not simply a matter of 'negative' interdependence. The appropriateness of the term 'partnership' was questioned, if this was only to mean financial and technical cooperation. The politicisation of Lom&eacute; appears to be on the agenda, involving a move from the current partnership to a genuine 'contractual approach' through political dialogue.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As for the role of partnership in cooperation policy management, it was felt essential that civil society and the private sector be involved. There was also a discussion of the debt problem.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· How can financial and technical cooperation be improved ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As usual, reference was made to the need to simplify and differentiate management of Lom&eacute; Convention instruments, particularly in the context of the programming process. As regards the role of non-state actors, a cautious approach was recommended. Finally, new instruments were called for to prevent conflict.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Conclusions</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This conference, coming after several others of the same type, was characterised essentially by private sector and NGO calls for greater participation in Community cooperation policy. Moreover, the need for 'politicisation' of the Lom&eacute; policy, shifting from purely financial and technical aid to a genuine cooperation contract, seems to have attracted the support of all participants. These questions are sure to figure in the 'Green Paper' on 'tome after 2000', which the European Commission plans to publish before the end of 1996. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dominique David</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">'Democratising democracy'</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On 6 and 7 June, the Belgian Par/iament hosted a UN seminar on 'me future of international development cooperation: new communication challenges' 'Democratising Democracy' was the succinct, journalistic way in which one of the speakers at the meeting summed up his solution to the problem of underdevelop meet. He was Jean-Bertrand Aristide, former President of Haiti, who observed that democracy, as advocated by the developed world, and increasingly accepted by developing countries, does not prevent the latter's slide into even greater poverty. The Courier had the opportunity to interview Mr Aristide. We began by asking him whether his statement implied that democracy is failing in a world striving to 'globalise' it J-B.A.-The word democracy comes from the Greek words 'demos', meaning people and 'kratein', meaning to govern. In other words, it signifies government of the people, for the people by the people-but if we take a look at the world today, the impression we get is that not all so-called democratic governments are in fact what they purport to be. Hence the need to 'democratise democracy', so as to create a situation in which all citizens can help set governments on a course towards such a model.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Concepts usually generate conflict and, therefore, when speaking of revolution, democracy or globalisation, it is necessary to be au fait with the subject matter so as not to become involved in a dialogue of the deaf. In the specific case of globalisation, my opinion is that this has a tendency to make what is an already precarious situation even more unbalanced. Concepts cannot be applied everywhere without thought being given to their harmful consequences. This does not mean to say that we should give up completely. It's one thing to speak of the globalisation of peace, as if an ineluctable need existed to promote peace on a world scale, but I'm not sure that everyone would define the globalisation of peace in the same way as I do.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Could we turn now to your own country, Haiti. How do you view the future of democracy there, bearing in mind the economic circumstances ? At the seminar, you mentioned several factors which demonstrate democracy's *agility.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Democracy is indeed fragile. 1% of Haiti's population owns 48% of the country's wealth and it is estimated that about 65% of the working population is employed in agriculture as against 5.1% in the 'industrial' sector. But is this really the true picture ? Reality for most people is poverty-unacceptable and sub-human poverty. A man needs work to earn his daily crust by the sweat of his brow, but unemployment has reached catastrophic proportions. When people are unable to earn their living, there is little point in discussing the positive influence of democracy. What is needed is for those with a great deal of wealth and those with less wealth to talk to each other; a dialogue between the private and public sectors, so that we can head off futile conflicts and devote all our efforts to economic growth coupled with human development. I do believe that this is possible.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Yet, the rich are so rich and the poor so poor. Is it not fantasy to think that the gulf which separates them, and their mutual mistrust, can simply be set aside so that genuine dialogue can take place ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-This is one of the challenges we have faced ever since 1960 and, although we have not yet reaped the harvest of this process, we have to carry on. It's not too late. We just have to approach the subject logically and with all the facts to hand, and we must have the intelligence to be patient. If we continue with dialogue, we will achieve real results. Only the citizens of Haiti can play a part in Haiti's development-this is not a task for outsiders. We, on the other hand, have to be more receptive to international cooperation, while maintaining mutual respect and dignity. But what we also need is for our own people to act together in order to enhance our own growth. This is not to say that geopolitical reality can be disregarded. Other countries have to be taken into account, but, as a starting point, we have to consider Haiti's human and material resources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Thereisdialogueata world level, but there are rules to be applied. I am thinking, here, of free competition. Haiti has to play by the rules, just like any other country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-Since we gained independence, our history has seen a succession of coups d'etat and people have been over-eager in brandishing weapons to solve economic, political or social problems. Now that democracy has been restored in Haiti, weapons are not the solution to our problems-I cannot stress this enough. What we need is for those with money to sit down and negotiate with those who have none: for the government to get people round the table and devise a common plan to accommodate all interested parties- looking at both the nation's interests and the interests of investors. I do believe that it is possible to achieve this. We have, in fact, already begun to prepare the ground. I am not basing my words, here, on pure theory, but am speaking from experience. In concrete terms, we have to transcend class and racial differences to recognise that Haitian men and women, regardless of their colour and the country they might live in outside Haiti, regardless of their nationality, even, are still part of Haiti's indigenous population. The way must be kept open for dignified and balanced cooperation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The other point you mentioned today was that there can be no development without the effective involvement of the population. Are you not leaving yourself open to accusations of having socialist or even communist tendencies ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-As I have just said, we have to be scientific in our approach and check our facts over and over again. I fail to see how anyone can claim to be working towards peace without looking at poverty which is the greatest threat to social cohesion. Of course, there are those who would deny this assertion, and that is their right. However, rational analysis of the situation can help us alleviate poverty and promote security. It needs to be underlined that security is also one of the essential factors in economics. The UN Security Council is called in to prevent or resolve conflicts. To my mind, we should also be talking about an economic security council to deal with the economic realities. The deeper one plunges into poverty, the greater one's feelings of insecurity-the two always go hand in hand. And insecurity can crop up anywhere in the world. Nor is it a question of charity. It is a real, rational question which must sharpen our awareness, stimulate our common sense and set us on a course to protect the world by alleviating poverty. That, at least, is one approach.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the same time, you have to recognise that politics is essentially a question of power while economics is influenced by interests. Everyone uses the means at their disposal to defend their personal interests and we know perfectly well that there are no free gifts. The so-called developed countries allocate just 0.3% of their GDP to development aid, yet we are losing our tropical forests at the rate of the area of a football pitch every second. In Haiti, forests now cover only a small area of the country. But in the final analysis, environmental catastrophe threatens us all, rich and poor alike, even if certain countries do not face specific ecological risks. We either deal with it as reasonable people, or we close our eyes to the 'cause and effect' realities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Yes, but are we reasonable people ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-The crisis of ethics is indeed a reality and a great many values are now being called into question. These days, we have to love in order to prove we are not contradicting ourselves. If we believe in God, we might call this love 'God', just as we might call it 'justice'. It all depends on your philosophy, religion or beliefs. If I feel love, I cannot be indifferent to the situation of victims of injustice, both in Haiti and elsewhere. If a man is humiliated, crushed, exploited or marginalised, then 1, too, am humiliated, crushed and marginalised. It is love which makes us fight for justice everywhere. Either one is a demagogue revelling in big words or one is sincere and ready to die so that another might live-this brings immortality.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· One final question. You were speaking just now of insecurity and economics. Is there a link, here, with one of your most recent decisions, the abolition of Haiti's army ? Could you tell us how you were able to pull off this 'coup'? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- I am perfectly happy to answer such an important question and would like to be able to give a clear and direct reply. But given that the struggle is still going on, I don't think I should go into too much detail. A decision was made. The Haitian people opted to rid themselves of the army. Supporting their democratic wish, it was our job to help bring about this dissolution. The army, it is worth recalling, had about 7000 men, absorbed 40% of the national budget-and had killed many of our compatriots. We have had to be logical and patient in achieving this goal, bearing in mind that the guarantors of the agreement which led to my return had their own views, which were different from ours. We also needed courage and wisdom and, above all, the determination of the people. My motto has always been that it is better to fail with the people than to succeed without them, and in this we did not fail. Our task now is not to bask in our own glory but to continue the work of structuring the police force, to prevent it becoming another army. To achieve this, we have to make steady progress and use sound judgment. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Interview by Hegel Goutier</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Close-up</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Growing rice at high altitude in Burundi</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY">by Jean-Pierre Tilquin and Miguel Amado</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This tiny country tucked away at the heart of Africa has, as is well known, been convulsed over the last three years by an acute socio-political crisis. The tragic consequences have included loss of human life, damage to the economic and social infrastructure, and a movement of refugees to neighbouring countries. Burundi, already one of the most densely populated nations in Africa, also has high population growth. It could be argued that it is only thanks to the hard work and perseverance of the farmers (admittedly, 90% of the population) that the country manages to keep going at all.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agriculture in Burundi follows traditional lines and is based on a farming system divided between food crops for consumption by the farmer and his family, and cash crops (mainly coffee, tea and cotton). Although at the beginning of the decade the crops grown for food were sufficient to meet the population's needs, today demographic pressures are forcing farmers to increase food-crop production. It is these pressures that have prompted them to descend into the marshlands which cover approximately 110 000 hectares (8% of cultivable land in Burundi). These marshes are flooded during the rainy season and so allow rice to be cultivated.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Population growth has also meant that fields cannot be left fallow for long periods. This has resulted in more intensive use of marginal land and an increase in forest clearing. Such practices exacerbate erosion of cultivated areas. The loss of organic matter and nutrients leads to reduced soil fertility and lower yields. Although rainfall in Burundi is high, the soil is only moderately fertile, because of factors such as acidity, aluminium toxicity, and phosphorus immobilisation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While 20% of land suitable for cultivation is currently given over to growing dry beans-a staple in the Burundi diet - various factors now point towards farming the low-lying marshlands, with a particular emphasis on rice. This is one way of increasing the useful agricultural surface area of the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The events of 1993 (democratic elections, followed by the assassination of President Ndadaye), have created a period of instability which has been highly damaging for the country's agriculture. Some people lost their property and livelihood, and are only now slowly re-establishing themselves. The environment has also suffered as a result of the sheer numbers of displaced people. They occupy areas, both urban and rural, which were completely unprepared for the flood of people. it is estimated that 50 000 hectares of forest have been destroyed as a result-with devastating consequences for the country's ecosystem. What is more, the rate of demographic growth has led to overfarming and to a reduction in the average surface area of farms (to 0.7 ha per household).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rice-a crop for the future</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Against this background, the prospect of farming low-lying marshland offers some hope for the people of Burundi. In fact, the marshy valleys have long been used to grow beans, maize and sweet potatoes during the long dry season for later consumption during the short dry season. This practice, which was environmentally sound, provided a regular harvest, but also ensured the preservation of the marshlands.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The practice of growing rice during the rainy season, followed by a crop of maize and beans during the dry season, is a form of integrated agriculture. It should be economically viable and environmentally sustainable while ensuring product quality, delivering a good yield, limiting any risks involved and allowing a high degree of social integration. These are the criteria which need to be examined in determining whether high-altitude rice cultivation in Burundi succeeds or fails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rice crops have been grown in this region, on the shores of Lake Tanganyika and in the Ruzizi valley (altitude 800 m), for more than 200 years, having been introduced by successive migrations of people travelling along the old slave route from Zanzibar. Certain varieties, known as 'pandabilima' (which in Swahili means 'he who climbs the mountain') can be grown on land up to a height of 1300 metres. They cannot, however, be planted on the higher central plateau because low temperatures at night render them completely infertile.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is not surprising that the new scheme to grow rice at high altitudes was greeted with interest. Indeed, it became almost a craze among farmers -to the extent that in 1990, rice crops covered more than 20 000 ha of Burundi. The area planted with rice fell subsequently, and in some regions the crop disappeared altogether. This was due largely to the appearance of the fungal 'rice blast disease', which can wipe out an entire crop, and to inadequate planning and misguided husbandry. The extensive planting of only one variety left the crop particularly vulnerable and once the disease did take hold, it was virtually impossible to eradicate. Needless to say, in a country where access to pesticides is non-existent, the introduction of a new crop cannot be based on a single variety; if it is to establish itself successfully, varietal diversification is vital. We should point out here that attempts were made in 1984 to improve varietal diversification </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">in the framework of the EU's Scientific and Technical Programme run by DG XII of the Commission. At that time, it was necessary to familiarise farmers with the techniques for growing the new crop and this aspect of the programme was funded by the EDF, in particular through three integrated projects. These related to agriculture and pastoral forestry and were initiated during 198889 in three provinces of Burundi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Without going into the technical details of the programme, it suffices to say that growing rice at high altitude in the tropics differs from rice-growing in temperate regions. The low night-time temperatures characteristic of high altitudes mean that the crop is subject to constant stress. In temperate regions, the stress caused by cold weather is a problem only at the beginning and end of the growing cycle. As for selection methods, rice varieties have been produced that are resistant to rice blast disease - which remains the main problem. Also, by mixing the varieties grown, the farmers have created a wide diversity which offers a stable basis for a sustainable crop.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Transformation of an ecosystem</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From the viewpoint of development aid specialists, turning marshland into cultivable land means draining it (digging a ditch and fitting pipes). But this leaves the land open to erosion, causes silting in rivers and ultimately leading to desertification. By changing water levels in a region and disturbing the thermal equilibrium, marshlands cease to be marshlands. The method may have been justifiable before rice growing became possible. Indeed, it was employed in the natural marshlands of Buyenzi by some experts who specialised in upland rice. But it also resulted in large-scale destruction of one ricevariety-Yunnan 3-by rice blast disease in 1990.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Development projects which set themselves spectacular objectives can involve major alterations to the landscape. More often than not, these need to be rectified later. Thus, when it was decided to cultivate vast expanses of papyrus, the plants were moderately successful only thanks to constant artificial assistance. Put simply, the land could not sustain the crop on its own. In the process, the marshes were turned into floating peat bogs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The option chosen here was to adapt the small valleys for rice cultivation and teach the farmers the relevant techniques. Together with their families, they have eagerly embarked on the work needed to prepare the terrain for cultivation, although there are still some land tenure issues that need resolving. (Some people have refused to commit themselves to marshland reclamation projects as long as the land does not belong to them). It should be stressed that growing rice along a strip of water is an option which is in harmony with environmental needs. It promotes percolation of the water, thereby restoring underground water levels and preventing pollutants from being washed down towards the Nile or Zaire basins. It is therefore in keeping with global strategies for conserving resources and ensuring sustainable development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the marshlands, farmers traditionally plant beans and maize in banked-up beds during the dry season (from June to November). By skilfully selecting and growing different bean varieties, the farmer can stagger his crops and thereby ensure a continuous harvest from September until the time the maize is harvested. The marshes are then left fallow during the heavy rains which reach their peak in April. A rice variety which can be harvested in six months could thus be fitted in during this perriod with out disturbing the traditional hill-farming work schedule.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Since farmers on the high plateaux had not traditionally grown rice, it was necessary to teach them the techniques needed to produce a successful crop. They were also informed of the benefits that improvements such as dykes, water supply pipes and drainage pipes could have on crop productivity. They have since applied this knowledge in their cultivation. During the dry season, without disrupting the infrastructures on which their rice cultivation is based, they have rebuilt banked-up beds and grown the traditional bean and maize crop. The system has been in place for about ten years and no drop in yield has been recorded. The yield averages 4.5 t/ha for rice, 1 t/ha for beans and 0.4 t/ha for maize-figures which are quite remarkable when compared with the yields of crops grown on the hills in acid soil with increasing levels of aluminium toxicity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By alternating two different farming systems, the problem of weeds -and therefore hoeing-and of pests is greatly limited. The extensive mixing of the soil that takes place accelerates the recycling of biogenic material-and the marshlands stay as marshlands!</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Manageable land development</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are three main types of marshy valley, each requiring specific programmes. The first consists of valleys lying above 1400 m with a rainfall in excess of 1500 mm. These areas are characterised by a clay soil, are constantly fed with water (with a high iron content) from the mountains, and are often very rich in organic matter. They require drainage using ditches and filtration channels, with changes of gradient so that the mountain water tables can be tapped and the water levels controlled. This is important to prevent a build-up of ferrous toxicity in the soil, which is extremely harmful to rice. A farming system involving paddy fields and banked-up beds can be accommodated perfectly in these types of valleys. Then there are the valleys lying between 800 and 1400 m with a rainfall of between 1100 and 1500 mm. These are known as 'dambos' in Swahili, and they extend from Northern Kenya right down to Southern Zimbabwe. Strewn with giant termite nests, the land here is well-suited to rice cultivation as long as water levels are carefully controlled. All the available water needs to be harnessed via filtration canals dug into the hillside. These allow the paddies to be irrigated speedily and, during the dry season, they can also be used to irrigate between the rows of ridgeplanted crops. It would, however, be very difficult to irrigate the entire valley during the dry season and so it is pointless digging a drainage ditch. The third and final type consists of small alluvial plains tucked away between the hills and stretching along the escarpments. Here, the level of soil fertility is determined by the heavy erosion resulting from farming on burnt land, and the practice of setting fire to the hills in order to 'regenerate' pastures. To grow rice in such locations, a filtration canal needs to be dug into the hillside, into which water then collects from the water table. The paddy fields also need to be terraced. These alluvial plains lend themselves perfectly to a farming system in which paddy fields are alternated with banked-up beds. All these land-adaptation schemes can be easily implemented and maintained by the farmers themselves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A sociological revolution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although rice grows quickly, it is highly labour-intensive. Thus, when</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">the young rice plants need to be planted out-which happens to coincide with the end-of-year school holidays-the whole family takes part. What is more, rice has become extremely important in sociological terms: reserved in days gone by for special occasions, it now forms part of the nation's staple diet, being mixed together with beans and dressed with palm oil and tomato sauce. The rice harvest is also a time for merrymaking and festivities which go on for the best part of a week.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rice cultivation has also engendered a vital sense of solidarity among farmers as far as sharing water is concerned, and rice-growing cooperatives have been a runaway success. These enable farming operations to be synchronised and running costs to be reduced, in particular by reducing the number of bird scarers needed. The crop, furthermore, can be harvested when fully ripe. On individual plots, farmers usually only allow the rice to mature to 75% before harvest for fear of theft. Finally, the cooperative helps to ensure that infrastructures such as drains and canals are properly maintained and that water supply installations are treated with respect. Each cooperative is run by a representative appointed by the group of farmers. These supervisors are then responsible for organising all operations: choosing and storing seed for the following season's crops, getting information about new varieties, consulting each other and pointing out any problems they may have to those in charge of research and advisory services. The area allotted to each cooperative depends on the number of households in the group and also takes into account the area available, with 10 ares per family being the usual maximum for planted-up paddy fields. Cooperatives may range in size from 5 to 25 families.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cooperatives like this are just the beginning. Networks of rural organisations, in which the farmers club together to buy equipment and fertilisers, need to be developed on a larger scale and they could provide a springboard for the development of the secondary sector, which is vital to the development of the country as a whole.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We would do well to recall that the cassava mills which have been so successful in Burundi and which still run today without any 'technical assistance' had equally humble beginnings.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The future</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It must be acknowledged that the people who migrated to this 'wild frontier' of rice cultivation in Burundi also introduced into these regions diseases such as bilharzia and malaria (the mosquitoes carrying the parasite were transported in the luggage of people travelling from the capital to the provinces). Despite this, rice cultivation at high altitude has proved a veritable lifesaver for Burundi. In the year that the FAO plans to stage a summit on famine, it is appropriate to highlight the important role of rice-growing in the food production strategy of this country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Until recently, Burundi ensured that it had enough to feed its people through a delicate balancing act between growing food crops, leaving land fallow and rearing livestock which produced manure. At present, however, increased agricultural production is only possible by increasing the surface area of the country under cultivation-at the expense of fallow land and livestock farming. Such a move risks reducing soil fertility and could lead to the substitution of crops of high nutritional value, such as beans, with higher yield crops such as cassava or sweet potatoes which suck the subsoil dry of minerals and nutrients.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In short, traditional farming methods in Burundi are arguably now out of balance and the situation is getting worse. This may, indeed, be a root cause of the ethnic crisis. A systematic policy of re-establishing marshlands and organising rural communities around high-altitude rice cultivation would allow the country to look ahead with optimism to the next 20 years. Suitable varieties are currently available and the altitudes at which rice can be grown have been pushed back in Burundi as far as 1700 m. What is now needed is the funds! </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">J-P.T. &amp; M.A.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Developing world</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Freedom of expression: the heartbeat of democracy</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A view from UNESCO.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The article which follows is an abridged version of a text compiled by Carlos Amaldo, who heads UNESCO's research into communication and the free flow of information. Mr Arnaldo highlights some of the main aspects of the UN agency's support for the development of a free press in the African, Caribbean and Pacific regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The resolution passed by the ACP/KU Joint Assembly in March 1996 in Windhoek, Namibia, reflected the spirit of many of UNESCO's communication programmes in these regions. Echoing the principal tenets of the Universal Declaration of Human Rights, the resolution declares: 'freedom of expression is a precondition for holding free and fair elections'; 'the monopoly of information media is a barrier to the development of democracy,'; 'there is a need to create a climate in which all part)" can participate fully in political life.' It further holds: 'communication media must not only inform the electorate in an impartial and objective manner' but also; 'freedom of expression and the existence of free communications media are vital preconditions for the development of a democratic society.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The resolution was timely, responding to a need to remind political leaders, as well as civic society, of the relation between free communication media and truly democratic practices. Just five years ago, on 3 May 1991,</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">African journalists and media adopted the Windhoek Declaration at the UN/ UNESCO seminar on promoting an independent and pluralistic African press. Likewise, journalists and media practitioners of each major region adopted the Declarations of Alma Ata (October 1992), Santiago (May 1994) and Sana'a (January 1996), all of which affirmed the unwavering belief of professional communicators in freedom of expression, press freedom, independence and pluralism of the media, and the contribution of such freedoms to democratic processes. At their 28th General Conference, UNESCO Member States further declared that, 'press freedom is an essential component of any democracy.' All these declarations contain action programmes to strengthen press freedom in these regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Turning to look at some practical initiatives, a media project entitled 'Independent Press in Africa', which was put in place after the signing of the Windhoek declaration, soon attracted the interest of a number of donors (Italy, USA, France). Under this project, the International Programme for the Development of Communication (IPDC) organised four sets of courses for journalists in 1994. In April 1995, IPDC arranged a multi-theme workshop for 33 English-speaking journalists and editors from Central and West Africa on marketing, distribution techniques, managing mass media enterprises in Africa, new communication technologies, journalism and ethical issues.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are now plans afoot to study the situation of the press in Mauritius, Madagascar and Comoros, and to publish several handbooks about press enterprises. Efforts will also be made to attract increased donor contributions so that the successes achieved by these initial training activities can be strengthened and shared with other regions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A further example of positive action in support of the media is the work of MISA (the Media Institute of Southern Africa-featured in more detail in the following article). This organisation has been receiving UNESCO support since 1994 under a funding arrangement with the Danish International Development Agency. The project seeks to strengthen links among the region's independent media so as to enhance the free flow of information. It also aims to boost cooperation and information-sharing with similar groups in developing and developed countries worldwide, to strengthen the ability of the region's independent media to stand on its own feet and to improve professional standards.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MlSA, which was set up in 1992, has been monitoring and safeguarding press freedom in the region, facilitated by an electronic network for distribution of information on press freedom issues. It has mounted seminars and training workshops for professional journalists on computer-aided design, strategic financial management, journalism ethics and advertising management. MISA's campaigning material includes a bi-monthly magazine, Free Press: the Media Magazine of Southern Africa and a booklet, So this is Democray, which is a compilation of its 'action alerts' curing 1994 and 1995.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another UNESCO initiative is the 'Communication and Good Governance in West and Central African Countries' project, supported by Germany. This aims to strengthen the human and technical capacity of the media in these regions so that they can make a contribution to good governance. The three year project is to be implemented in 10 countries - Benin, Chad, Equatorial Guinea, Gambia, Ghana, Guinea Bissau, Liberia, Mali, Sao Tome &amp; Principe and Togo.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Together with other institutions such as legislatures, the judiciary and civic organisations, media bodies like MISA have a useful role to play. They can enhance transparency and accountability by systematic analysis and reporting of government programmes, policies and pledges, and by encouraging public discussions which help people to make informed decisions about public issues and about how their leaders discharge the power vested in them. Fulfilment of these functions requires access to the media, and qualified, well-trained practitioners who can effectively use the media for information, education and communication on good governance issues.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Caribbean</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Turning our attention now to the Caribbean, the question of media freedom recently came to the fore in Trinidad and Tobago when 13 editors and journalists on The Guardian lost their jobs following publication of a number of controversial articles (some reports said they 'constructively resigned'). The events cast a shadow over the famous Carnival. Indeed, as one journalist put it, the Carnival quickly ceded to the 'sacrificial rites' of Holy Week. Six of the paper's youngest reporters were among those who lost their jobs-but out of the furore, a new newspaper was born.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A 'Comparative Study of Media Laws in the CARICOM countries' by Ainsley Sahai, commissioned earlier by UNESCO, became a reference in the debates that followed. The study highlighted that all Caribbean countries guaranteed freedom of expression in their national constitutions. Indeed, Trinidad and Tobago's constitution explicitly guarantees press freedom as well. The Media Association of Trinidad and Tobago (MATT) organised two meetings. The first of these, on 10 April 1996, was a public forum on issues of press freedom. Although a full cross-section of society was not present, and not all the issues at stake were fully debated, it was nevertheless a start. Those who took the floor came from many sectors of society -women, the unemployed, workers, community organisations and at least three different religious groups. About a quarter of those who contributed spoke as individuals. While many criticised the press for errors in reporting, all confirmed the need to uphold a free press vis-a-vis both political pressures and economic and financial interests.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The public gave strong support to MATT and demanded that the forum be replicated in other parts of the country. It was the first time that the public had been given the opportunity to speak out on these issues. It was not so much the content of the discussion which counted, but the very fact that the event took place, bringing the media closer to its 'customers'. The meeting gave the public an opportunity to put over their own perceptions of press freedom, impartial reporting and the strengthening of democratic processes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Two days later, with support from UNESCO, the Media Association staged a journalists' symposium, moderated by George John, consulting editor at The Guardian. David de Caires, publisher of Guyana's Stabroek News was invited by MATT as an external consultant. Drawing on past and more recent examples of uneasy relations between a free press and governments, Mr de Caires concluded with a headlinehitting statement; the relations of the press with government should not be too cosy, the press must maintain its adversarial position.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many journalists took the floor to stress Trinidad and Tobago's constitutional guarantees for both freedom of expression and press freedom. They also stressed the need to safeguard editorial independence, not only in the printed press, but also in broadcasting, and urged the repeal of 'antiquated' libel laws-a point also made in the Sahai study. The preparation of a Freedom of Information Act was strongly urged to ensure access to public information.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These events appear to have strengthened the resolve of the jobless journalists. They grouped together to set up a new weekly newspaper, called The Independent. The new publication focuses on investigative articles, comment and reviews. In addition, a monthly called The Formatt was launched by MATT to disseminate specialised news on press freedom issues and to provide print support for future public fore. Both newspapers brought out their first editions in early May amidst the celebrations of World Press Freedom Day.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pacific</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the Pacific, issues of freedom of expression and press freedom are no less salient, although a key issue for practitioners there is the modernisation of infrastructures. This is needed to ensure that this vast island region does not find itself in the slow lane of the information highway.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The computerisation of radio newsrooms, in places such as the Cook Islands, Vanuatu, Fiji, Solomon Islands and Tonga, is a priority. The Cook Islands already has a fully computerised newspaper operation. Indeed, this is the first newspaper in the Pacific with the capacity to transmit photographs from various parts of the country to the newsroom electronically by phone.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Considerable concern has been expressed about the inadequacy of national television programming. There is a need for the people of the Pacific to see themselves and their culture, and not just the imported fare distributed by most international TV services. With UNESCO support, women media producers from seven island countries were able to meet to work out ways of cooperating on a series of television documentaries that they themselves produced and exchanged within the region. Preparations are now under way for the annual evaluation and awarding of prizes at the end of 1996. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">C.A.A. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Campaigning for free expression in the SADC region</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY">by David Nthengwe</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Media Institute of Southern Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Officially launched in September 1992, the role of the Media Institute of Southern Africa is primarily that of coordinator, facilitator and communicator in the promotion of media freedom and diversity, (as envisaged in the 1991 Windhoek Declaration). MISA operates in 11 of the 1 2 SADC countries and is currently investigating setting up a chapter in the twelfth-Mauritius- which joined the Community 1995.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The chapters are serviced by a regional secretariat based in the Namibian capital, Windhoek. The secretariat is accountable to a policy-making governing council of elected representatives from each national chapter, while funding for MISA and its projects is channeled through the MISA Education and Production Trust, overseen by a board of independent trustees. The organisation is currently almost entirely donor-funded, with UNESCO, NORAD, SIDA, the KU, the Friedrich Ebert Stiftung, IBIS, and the Australian and German governments being the main contributors. Other income is generated through the sale of subscriptions to MISA publications and services.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Institute's main work is in the field of advocacy; highlighting violations of media freedom and free expression, and exploring ways of ensuring that these fundamental freedoms become entrenched throughout Southern Africa. In 1994, MISA became a member of the International Freedom of Expression Exchange (IFEX) network in a bid to increase international awareness of media freedom violations in Southern Africa. Membership of IFEX has enabled MISA to distribute as well as receive information on media freedom issues in a quick and relatively cheap way via the Internet.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'Action alerts'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1994 and 1995, MISA issued via IFEX and its own electronic mail network, the MISANET (see below), more than 190 'action alerts' relating to media freedom infringements in Southern Africa, and effective campaigns against some of these violations have resulted. In August 1994, Lesotho journalist, Rabuka Chalatse, was shot by soldiers while covering a demonstration. An alert issued by MISA triggered a swift response, and within 24 hours, funds had been raised to pay for emergency treatment which saved the young journalist's leg. In November 1995, Angolan freelance journalist, Mario Paiva, had his life threatened by people who, it was alleged, were state security agents. MlSA's alert prompted protest from throughout the world, and resulted in several governments offering Paiva sanctuary in their embassies in Angola. The threat against the journalist was subsequently lifted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MlSA's advocacy work has also shown that democratisation does not necessarily result in guaranteed media freedom and free expression. In Zambia, for example, which had a multi-party election in 1991, arcane laws inherited from previous regimes have been used against the private media in particular, and free expression, in general. As this article was being written, Fred M'membe, the Editor-in-Chief of Zambia's privately-owned daily 'The Post', and two of his colleagues, were starting an indefinite prison term for contempt of Parliament. The sentence was passed not by a court of law, but by the Speaker, under legislation inherited from British colonial rule. Their 'crime' was to comment on criticism made in Parliament of a Supreme Court decision which declared unconstitutional, laws requiring anyone wishing to stage a demonstration to obtain police permission first.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Five months prior to his arrest, M'membe received the MISA Press Freedom Award, which is presented annually to individuals or institutions considered to have made an outstanding contribution to the advancement of media freedom in Southern Africa. M'membe was the third recipient of the award.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Free flow of information essential</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As the Windhoek Declaration points out, 'the establishment, maintenance and fostering of an independent, pluralistic and free press' is essential to economic development, as well as for the growth of democracy. Accordingly, MISA argues that the free flow of information is vital to the development process. Effective communication within SADC-a 'development community'- has been hampered by the region's poor postal and telecommunications services. MISA considers that these logistical barriers to the free flow of information are a form of censorship. In a bid to break through the information voids which have kept Southern African media workers and their audiences isolated from each other for so long, it has made particular use of advances in information technology, including, most notably, the Internet.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over the past two years, MISA has been linking member organisations up to electronic mail (e-mail). This allows members throughout the region to exchange news, photographs and other information. To date, 25 MISA member organisations are linked to this network, called the MISANET, although further growth has been hampered by members' unfamiliarity with e-mail, and the lack of local technicians to train people and provide user support. Nonetheless, computerised communications have proved to be an appropriate technology, and development of the MISANET remains a top priority. By making some services available to non-MISA subscribers, MISA also intends to generate income and thus reduce its current dependency on donor funding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Focus on training</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The coordination of training and material support to independent media is another area where MISA looks to develop media freedom and diversity. The region's independent media sometimes operates in politically and economically hostile environments. Its survival-and thus the sustenance and growth of media diversity-hinges on these organisations becoming highly professional, well-managed concerns.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Working through training institutions based primarily in the region, MISA coordinates workshops and other training programmes aimed at improving the skills of media workers, particularly in the fields of management and finance. Workshops in strategic and financial management, project management, advertising, marketing, sales and subscription management, ethics, subediting, and computerised design were staged during 1994 and 1995. For 1996, training is scheduled in economic reporting, project management, photography, advertising sales, circulation and sales management, computer-aided design, developing world and financial and strategic management. Instruction will also be provided to media workers without formal training. Meanwhile, research is to be carried out into setting up a media ombudsman for Southern Africa, printing press initiatives, media training needs, and the difficulties faced by women media workers in the region. The last-mentioned is in line with MlSA's policy of encouraging gender awareness and equality within the Southern African media.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Private and community-based media organisations face constant problems securing adequate finance. As businesses, they often do not qualify for donor support, while banks are reluctant to lend them money. Therefore, MISA is looking to set up of a Media Development Fund to which independent media can apply for loans, credit guarantees and grants. A study is currently being conducted into the feasibility of such a fund, which MISA hopes to have up-andrunning by early 1997.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Broadcasting in Southern Africa is still largely state-controlled. Moves by some of the region's governments to 'deregulate' broadcasting have been erratic, and many private broadcasting licenses granted in the process have gone to organisations or individuals closely linked to the authorities. MISA is now drawing up a policy aimed at seeking the effective liberalisation of broadcasting legislation covering public, private and community broadcasting throughout the region.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As part of this process, MISA will, this year, stage a conference on broadcasting and community media, to coincide with its Annual General Meeting-which has become one of the largest gatherings of media workers on the African continent. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D.N.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Volunteers show their worth</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY">by Thomas M. Neufing</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Volunteers have become a major component in international development efforts. They make up a significant proportion of the total human resources available for development cooperation (up to a fifth of the skilled international personnel serving in developing countries). In the early days, volunteer service was strongly influenced by the idea of oneway technical assistance. Specialists, mainly from the North, served in developing nations where their expertise was desperately needed but not yet found among local citizens. Much has changed since.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">After the US Peace Corps, the UN Volunteers Programme (UNV) ranks as the second largest volunteer-sendina agency with some 4000 professionals in the field every year. Its universality and internationality is reflected in the high number of UNV specialists (74%) who come from developing countries. The scope and size of the international volunteer contribution to development cooperation (notably areas such as HIV/AIDS and the environment), has increased significantly over the years as a result of the changing development challenge. The re-thinking of the role of technical cooperation is equally central to the volunteer debate and this has led to much greater flexibility in the ways in which volunteer services are provided. The important role volunteers can play in peace building efforts with a long-term development dimension, complementary to humanitarian relief, is increasingly being recognised.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Working with rather than for people</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With the UNV's 25th anniversary, and the relocation of its headquarters to Bonn this summer, it is an appropriate time both to assess and to acknowledge the contribution made by these volunteers. Since the programme began in 1971, some 14 000 professionals have dedicated a period of their lives to serve as a UNV. The programme is administered by UNDP, and is therefore intimately linked to its structures, particularly in the field. Regarding community-based initiatives, the comparative advantage of UNVs is that of working with rather than for people over an extended period, thus facilitating their initiatives. The experience of many development agencies shows that in promoting socio-economic change at the village level, the type of person needed is one who-through long-term commitment and sensitivity -can learn as much from local partners as offer advice to them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">International volunteers are engaged mainly in rural development tasks. Those working through specialised NGOs such as the Red Cross, and Medecins Sans Frontieres have proved to be highly effective agents, supporting governments faced with disaster situations. In the case of UNV, the value of using volunteer specialists from other developing nations, as a way of encouraging technical cooperation amongst developing countries, is particularly recognised. Most volunteers- perhaps two-thirds - serve in least developed and small island countries. And about three-quarters serve in rural areas, working mostly in programmes of agricultural and community development, health, education and the supply of basic services. Since the end of the Cold War, a growing number have been deployed in emergency relief, refugee and rehabilitation programmes. UNVs make up 10% of the UN's civilian component in Cambodia; 4096 of the field staff of the World Food Programme and almost 100% of outreach workers attached to the UN Mission in Guatemala. UNVs are increasingly involved in human rights promotion, the organisation of elections and conflict resolution.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is a consensus among the main international humanitarian and development actors that their programmes should be mutually supportive. For example, development efforts must respond to humanitarian crises by remaining on the scene and supporting immediate needs, as well as aiding in the prevention of crises which are known to be looming. Emergency humanitarian assistance should also pave the way for longer term development by viewing the immediacy of the moment through the lens of future sustainable rehabilitation. Both sets of activities should, ideally, be launched and implemented in tandem with local bodies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">External assistance efforts must include strengthening local capacity to cope with problems. Empowerment strategies which inform, educate and facilitate the people's own vision of peaceful and sustainable living environments (including respect for human rights) are fundamental to the future of communities coping in the aftermath of crisis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Relief, rehabilitation and development?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The UNV programme has been active in exploring the efficacy of volunteer support to communities in crisis in order to bridge the gap between immediate needs and longer term developmental goals. In 1994, the UNV held its 4th Special Consultation, entitled, Between Crisis and Development - Volunteer Roles and UNV's Contribution. At this event, donor governments, UN agencies and cooperating partners from civil society had an indepth discussion of the issues surrounding volunteer efforts, and the complementary nature of emergency interventions and follow-up measures. The participants reconfirmed the need for local capacity building. They also affirmed the usefulness of the UN Volunteer contribution in crisis prevention, emergency rehabilitation and 'building bridges' to sustainable development. The work of UNVs in preventive action and promoting post-conflict development was highlighted. There has been a significant increase in demand for specialist volunteer services in all types of crisis. These may be economic, natural or man-made, but they all have in common the need to provide essential relief and rehabilitation services for basic survival (to refugees and resident populations). In many countries, disasters and internal strife have put so much pressure on essential public services that the longterm capacity of the people to recover may be threatened. Governments in developing countries and donors both believe it is fully justified to use volunteer specialists to help provide such services during the adjustment period.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'Mixed' teams</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The contribution of both international and national volunteers is often essential to link immediate relief efforts to future long-term development. National volunteers-people working in their own countries within the UN framework-complement the international approach by providing the key grassroots perspective. UN Volunteers who speak local languages, live and work in remote communities, are familiar with community structures and are known to local leaders, play a key part in facilitating preventive action and providing follow-up in the aftermath of a crisis. UNV specialists are well-placed to build effective partnerships with national and local actors. In the last two years, some 2000 UN Volunteers have worked in various parts of the world in prevention and preparedness, peacekeeping, electoral support, human rights, rehabilitation and reconstruction, and humanitarian relief.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Burundi offers an example of an initiative designed to stem a crisis through local capacity-building. The UNV is financing a project there which supports the mediation and dialogue efforts of the UN Secretary General's Special Representative (SRSG) through the recruitment of UNV peace advisers and conflict resolution facilitators. This project is being run successfully out of the SRSG's office, extending public awareness of the reconciliation process. It includes use of the mass media to promote understanding, and brings local actors together to work for peaceful solutions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The tasks undertaken by UN volunteers all fit into the spectrum which has 'crisis' et one end end 'development' at the other. The work, moreover, is undertaken in partnership-with civil society (NGOs and community-based organisations), government departments, UN agencies and regional international organisations (such as the KU).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Through efforts that aim to link relief, rehabilitation and development, new productive partnerships are emerging to enhance coherence, coordination and complementarily.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The growth of professionalism</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">30 years ago, the typical profile of an international volunteer was that of a generalist graduate from an industrialised country seeking first-time experience abroad before settling down to a career. Over time, the governments of developing countries made clear their need for practical and often specialised skills aimed at giving them the ability to manage their own programmes. They increasingly expressed impatience at hosting untrained volunteers. Professionalism became the key word. Unfortunately, the word 'volunteer' is still a source of confusion: it is often equated with 'amateur'. This is a perception that now needs to be corrected. The personnel sent out by most agencies that supply volunteers are likely to be in their thirties, with post-graduate qualifications and several years' practical experience in their fields. The typical UNV specialist is an example par excel/ence of this trend: 39 years of age, holding a Master's degree and with more than ten years of experience in a particular discipline.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It was not just the dedication, but also the professionalism of the hundreds of UN Volunteers serving in Mozambique that impressed Aldo Ajello, the former UN Special Representative in Mozambique (now EU Special Envoy for the Great Lakes Region). 'If I were to run another mission,' he said, 'I would ask immediately for volunteers.' In terms of monitoring-which was vital in building up the trust and confidence needed to ensure the election results were accepted-'UNV electoral officers were our only real presence and they proved to be extremely professional.' ~ T.N. </P>
+<P ALIGN="JUSTIFY">Study by the World Wide Fund for Nature</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Structural adiustment, the environment, and sustainable development</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY">by David Reed</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On 29 May, David Reed of the World Wide Fund for Nature (WWF) was in Brussels to present the results of a study undertaken by the WWF, with the support of the European Commission, the longterm consequences of structural adjustment programmes (SAPs) on the environment and the use of nature/ resources. Conclusions were drawn from nine country case studies from Cameroon, Mall Tanzania, Zambia, El Salvador, Jamaica, Venezuela, Vietnam and Pakistan. We publish here an abridged version of Mr Reed's general presentation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SAPs, often implemented at the instigation of the international financial institutions, have responded to the pervasive economic problems of the 1980s and to profound changes in the economy in recent decades. The programmes have generally been successful in improving macroeconomic indicators in developing countries. The marketorientation of economies has been increased through liberalised trade and capital flows, privatisation, reductions in regulation and price setting, and cuts in government budgets and programmes. For most developing countries, these changes were essential to economic recovery and adjustment to the new global marketplace.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sustainable development in the social, economic, and environmental sense, has, however, been ignored in SAPs. Many reform programmes have been accompanied by increases in poverty and unemployment, worsening income distribution, and the collapse of social services, environmental protection and state institutional capacities. These immediate costs of adjustment inhibit countries' long-term ability to expand productivity and employment opportunities, as natural resources are exploited indiscriminately to meet short-term needs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Environmental impacts</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The environmental effects of structural adjustment vary from country to country depending on the specific components of the reform package, the structure of the economy, and the implementation process. The WWF's country case studies reveal particular mechanisms through which structural adjustment has altered resource-use patterns. Some more general patterns also emerge from the studies. Everywhere, cuts in government institutions and funding have reduced the state's capacity to facilitate the transition process, to compensate for market failures, and to provide for long-term and social sustainability.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many reforms associated with structural adjustment have the potential to improve both environmental and economic outcomes. However, the failure to implement complementary environmental policies or strengthen institutions and regulations, has created a very mixed environmental record. Increases in poverty, greater production incentives, and the loss of government regulatory capacity, have all aggravated patterns of poor resource use.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Extractive and agricultural economies generally increased production in response to greater exposure to global markets. Without proper policies in place, this increase has put a strain on fragile ecosystems. Environmental pressures include increased land degradation and deforestation for agriculture, livestock and timber production; increased production of non-renewables without long-term investment of the proceeds or environmental safeguards; and increased pollution and damage to the ecosystem from unregulated tourism.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The burden of fiscal retrenchment and price changes under structural adjustment have fallen most heavily on the poor, particularly women. The strong association between poverty and environmental degradation has been revealed, as efforts to maintain livelihoods have led to deforestation, land degradation, overhunting and other pressures on endangered species, as well as the unmanaged extraction of nonrenewable resources. Increasing poverty and unemployment associated with adjustment has also added to population pressures in urban areas with insufficient infrastructure exacerbating problems of pollution, disease and congestion.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The implications of disregarding the environmental and social impact of adjustment are examined in the various case studies. Structural adjustment has been sustained by the promise that market-orientation and export-led - growth will raise living standards. Evidence from the studies, however, strongly suggests that long-term productive capacity is being destroyed by short-term exploitation of natural resources. Not only environmental but also economic and social sustainability are threatened by the loss of environmental goods and services. Drawing down natural capital has been encouraged by government policies that promote exports and open resources up to international markets. And the process is accelerated by the growing population of poor and unemployed who rely on natural resources for survival.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Recommendations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Following its study, the WWF offers a series of recommendations to reduce the environmental costs of structural adjustment and economic integration, and to reorient structural adjustment aims towards sustainable development. Most urgently, environmental issues must be integrated into structural economic reforms - environmental assessments must become part of the programmes. A strategic vision of the role that natural resources and environmental goods and services could play in the transformation of developing economies is essential to designing appropriate strategies. Efforts to industrialise economies must include consideration of the environmental implications. Social services and environmental institutions must be maintained during the adjustment process to prevent increases in poverty and environmental degradation that have both short-term and long-term consequences for development. Essential services include credit and marketing support to small farmers, income-generating opportunities for women, food-assistance programmes, and promotion of distributional equity. The state's role in providing services which neither the private sector nor civil society can provide, must be maintained.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Given the great variety in economic structures and in the capacity of markets and civil society among developing countries, adjustment strategies and government roles must be tailored to each case. Everywhere, countries must implement national institutional reforms for environmental management. Civil society must be strengthened to allow participation in the adjustment process. International financial institutions promoting and designing SAPs must reform their policies and approaches to implementation in the light of the clear evidence that macroeconomic reforms are having a profound effect on the environment and on the possibilities for sustainable development. Continuing failure to correct these problems on a national level accentuates the concern for addressing issues of sustainability on a global level. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D.R. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Culture and society</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Why a Biennial Festival of Contemporary African Art?</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dak'Art 96</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first World Festival of Negro Art, held in 1966, was essentially a political exercise. In the post-independence period, it was felt necessary to show the world that the people of Africa (both the continent and the diaspora), had a rich culture which had long been suppressed. The festival - which has never been repeated-is viewed with a great deal of nostalgia by supporters of modern African art and black intellectuals. The better, brighter future, which seemed at the time to be just over the horizon, never quite lived up to expectation. Even before financing problems had surfaced, the festival's fate had already been sealed by petty political rivalries and a greedy pursuit of the limelight. Years later, attempts to relaunch the event met with a lukewarm reception. It was already the beginning of the end as far as ideologies were concerned. In complete contrast, Dak'Art 96 (Dakar, 915 May 1996) set its sights firmly on the market place, nowadays the yardstick by which all success is measured. Its goals were simple: to break into the art market and overcome the generally held prejudice that contemporary African art lacks modernity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An international market for African art does exist, but it concerns itself solely with ancient art- and Africa itself profits little from such trade. Indeed, it would be more accurate to speak of plundering than of trade. The seminar, organised last year by the Terveuren Museum in Brussels on the looting of African works of art, revealed the true extent of the phenomenon. Despite the fact that pirated works fetch considerable sums on the black market, contemporary African artists are faced with a 'Catch-22' situation. Major galleries in Europe, America and Japan do not exhibit their work because African art is ignored by the leading art periodicals; and their work never appears in these publications because it is never exhibited. One reason for the fact that African art is not put on show is that virtually no funds are allocated by international institutions to sponsor exhibitions by the artists in question.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many third-world governments do not dare, are unwilling or are unable to include culture on their list of priorities within international cooperation agreements. One exception is Burkina Faso which now boasts a cinema industry as a result. Senegal is trying to follow in its footsteps. But there are not many places in Africa where artists are promoted for the quality of their creative output. The majority of initiatives have, in fact, been on a voluntary basis. The magazine Revue Noire is one of the most significant examples of this approach. A group of aficionados of contemporary African art - indeed with a passion for art pure and simple, whether African or European-decided to try and break the vicious circle. They looked at two options: the establishment of an art gallery of worldwide renown or of an equally prestigious arts publication, and came down in favour of the latter. Thus Revue Noire was born. However, its success was generally given very slim odds: it was seen as too glossy, too expensive and too intellectual. The sub-text here of course, is that a publication about African art had no right to be glossy, expensive or intellectual, especially since the money could have been used for something far more 'useful' to the development of these countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Others, such as Marie-Claire Mwanza from l'Espace Alizes in Brussels, have attacked the problem from a different angle-by exhibiting contemporary African art. Prior to her initiative, there was not a single gallery in Brussels that specialised in this sector of the market, and there are still none that figure on the shopping lists of the world's great collectors. Whatever the price set for a contemporary African work, it is generally perceived as being too high. The contrast with the prices demanded for works by even the youngest European or American artists, even for their very first exhibitions, speaks volumes. African art is too expensive in relation to what exactly ? The answer is in relation to the status accorded to it, which is of course determined by the art world. In other words, a big fat zero if one considers the fact that African art is never exhibited.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thanks to Revue Noire, African art has been brought to the major galleries of the Western world. Similar projects have been launched or are in the process of being launched in various countries of the West, such as the magazine NKA in Brooklyn, for example. Exhibition organisers, museums, galleries and those looking to stage art festivals now know on whose door to knock, and the last few months have proved extremely promising. The Guggenheim Museum in New York is currently hosting a major exhibition of African art, and Africa 95, held in London, was swiftly followed by Copenhagen 96. The Guggenheim Museum, moreover, is in a completely different league to the Museum of African and Oceanic Art in Paris or the Museum of Central Africa in Tervueren, Belgium (formerly the Colonial Museum)-it is one of the world's most prestigious temples of modern art. What is more, London's Africa 95, which was so disparaged by African art specialists, who considered it nothing more than a meeting place for traders, did, whether we like it or not, act as a significant catalyst. And what about pirated works of art, such as those plundered from the Niger Valley ? These have found a 'home' in public as well as private collections, pointing to a real need to 'clean out the Augean stables'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A few African artists are beginning to get themselves known within 'the market', but there are still not enough of them. It was with great foresight that the organisers of Dak'Art placed these artists at the top of their invitation list. Another shrewd move was to invite the art market's arbiters of taste to select those African artists who should present solo exhibitions, and to ask celebrated art critics and collectors to form part of the international panel of judges.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is probably true to say that Africa has rarely known such a dynamic period of creativity which places it at the forefront of global aesthetic trends. The aim of the Biennial Festival was to underline this fact beyond any doubt. Among those artists who are currently in a position to break into the market, the Senegalese sculptor, Ousmane Sow, probably heads the list. Paradoxically, however, Ousmane Sow's work was not presented at Dakar although he himself was there, his tall, striking figure standing out from the crowd. Despite the fact that he lent his support to Dak'Art 96 and that the opening gala was partly dedicated to him with the magnificent film of Beatrice Soule, Ousmane Sow resolutely refused to display his own work. He has no wish to take part in gatherings of 'African artists'. He is an artist and he is African, but he is not an 'African artist'. 'A Japanese artist is a contemporary artist in this universal world', he argues, 'so why should I allow myself to be pigeon-holed in a ghetto ?' No matter how satisfied and pleased champions of contemporary African art may be with the organisation behind the Biennial Festival, they cannot deny that Ousmane Sow has a point. Having said this, there is no contradiction here, but rather a complementary vision. Sow's stance and the idea behind Dak'Art are part of a two-pronged attack, to borrow a military term. The organisers of the Biennial and Sow himself doubtless saw it in this way, and decided to join forces.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Each time Beatrice Soule tackles the work of an artist, she explores it in a very unusual way, reinventing the arts documentary. Her films are reminiscent of the music of Nino Rota in Fe//ini's films, Rota subjugating himself to the service of the director's work, sublimating his own originality through this extreme humility. It is impossible to picture the images of Federico Fellini without Rota's haunting music. Beatrice Soule saw in Sow's work a love affair between an artist and his sculpture, coming up with the idea of placing Sow's sculptures in the savannah and imagining the intimate interaction between Africa's natural world, which is at the heart of the artist's inspiration, and his works, which the natural world is able to absorb back into itself. The result of this juxtaposition is that the physical work of art is eclipsed by sheer creative force and spirit. The genius behind the work becomes the work, merges with it and is reincarnated in it. The one thing that Soule did not film was Ousmane Sow himself, her images concentrating solely on the creative act. It would be illusory to attempt to explain a Beatrice Soule film, especially this film. When she unveils how the artist tames physical matter, reinventing materials in order to create a work of art, technique simply recedes into the background, becoming blurred and intangible. Whereas others would have adopted a scientific or factual approach, her camera perceives the abstract aspects of the piece-and its gestation. The film was due to be broadcast on the international FrancoGerman arts channel Arte. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If Ousmane Sow's sculptures are characterised by their gigantic proportions, then those of Georges Adeagbo, a Beninois artist whose name is also beginning to be heard in the commercial art establishment, are characterised by their 'fugacity'. Adeagbo's artistic constructions are as fleeting as puffs of smoke, like voodoo symbols scratched out in the sand. His art is symbolic and ephemeral. Once one of his works has been exhibited, all that remains of it is a hollow shell which he has to reinvent over and over again. Adeagbo constructs ideas, using a host of assorted materials which he painstakingly selects over months, even years. Yet despite the meticulous care with which they are put together, as far as the artist is concerned, the materials per se are of no importance. He could convey exactly the same idea using other elements. An Adeagbo piece is not merely a pile of objects. It is neither conceptual art, nor scrap art. It consists rather of 'installations' which rise and spread outwards. Sometimes, he uses specially constructed sculptures. At other times he employs everyday objects- shoes, saucepans, stones, spectacles or footballs. He also works with written material; manuscripts, parchment, pieces of newspaper and books, portraying the written word as both a creative force and a deceptive screen. Adeagbo himself is a man of few words. Perpetually crouched on the ground, he constructs, modifies, touches and observes his creations. Why should these constructions remind us so much of paintings? They are as much a pile of objects as a painting is an accumulation of layers of paint. It is by forgetting the paint that we are able to admire the picture and it is by looking beyond the materials used by Adeagbo that his work truly reveals itself. Indeed, it is a sign of his genius as an artist that the materials never intrude upon our contemplation of his work. In Dakar, Adeagbo's work was shown in the AIDS exhibition organised by Revue Noire. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another artist who took part in the AIDS exhibition, and whose art could well be the impetus behind the new universal aesthetic, the avant-garde (if such a concept has a meaning), is Pascale Marthine Tayou from Cameroon. He was given the honour of presenting one of the five solo exhibitions. Tayou was sponsored by Yakuyi Kawagushi, the curator of the Setagaya Museum in Tokyo, who exhibited his work at the forum organised within the overall framework of the exhibition. While the term 'installation' may best describe the works of Georges Adeagbo's, Tayou's work falls unquestionably under the heading of sculpture. This is despite the fact that the two artists use virtually identical materials. Tayou sculpts from wood, covering his pieces with all manner of manufactured and salvaged objects such as shoes, nails, plastic bags and enormous condoms, or with natural objects such as bits of roots and stones. He then paints the arrangement. The work is dense, unyielding and mesmerising, often etching itself into the onlooker's mind. His sculpture lacks heavy ornamentation, yet its starkness has a rich quality, the theme encompassed by a jumble of material standing out clearly, like the outline of a silhouette. Take his work 'Fight against AIDS'. The piece consists of a wooden frame in the shape of figure-of-eight, with each horizontal line doubled, defining a key element in a tragic body with bulging eyes and a Pere Ubu belly. In contrast to this suffocatingly tragic figure, the brightly-coloured shoes of a Harlequin with a faded costume offer a comical note.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There were other creators who could well ruffle a few feathers in the art market that ultimately makes or breaks an artist: Tamsir Dia of Cote d'lvoire (whose screaming figures are reminiscent of Munch), Cheikh Niass of Senegal, Mathilde Moro of Cote d'lvoire and Abdoulaye Konate of Mali. The last mentioned was honoured with the highest award of the festival.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A decision was taken that Dak'Art 96 should encompass other areas of creativity, such as music, design and fashion, in addition to the visual arts. At the gala evening held to inaugurate the Festival, there was a fashion show choreographed in the manner of a ballet. The staging of this can only be described as mawkish. The audience were treated neither to a real performance, nor to a good fashion show. The second fashion spot, which was supposed to present an overview of African design, was also quite pitiful. If the event's organisers decide to keep these parallel areas of creativity in the Festival, then their decision will be solely thanks to the success of the International Design Exhibition. Apart from two or three 'exotic' pieces, this was generally of a very high standard.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Community's choice in awarding the prize for creativity to a designer, Vincent Amian Namien from the Cote d'lvoire, was particularly revealing. This artist strips everything down to its bare essentials, creating a line that is so purified as to leave only the quintessence of form. Thus, he creates a chair that is nothing more than a perfect metal triangle, with four boards and four metal wires-and yet offers perfect comfort.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Claire Kane, a fashion designer of Franco-Senegalese descent, had the verve to go it alone and show her collection at the prestigious Salon of Design. Her clothes are characterised by the rejection of all superfluous detail, achieving a fluid line that stylises movement. Following an aesthetic code that has been decanted from the melting pot of the collective costume heritage of the entire continent, Claire Kane is directly involved in the creation of her designs, from the weaving of the cloth to the last finishing touches. In fact, she admits that her true passion is fabric rather than fashion, her favourite material being woven pagne. She often uses silk-screen printing to introduce pattern. She then adds words to the patterns in her designs and, abracadabra, one would think that this is the way it has always been done in Africa. A subtle modernity, combining both past and future, seems to be a recurring motif in African creativity. International artists, still few in number, travel from Dakar to be dressed by her.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If, in the future, the Festival's organisers decide to concentrate solety on the visual arts, this would come as no surprise. On the other hand, it would also make sense to continue to include design and fashion. A country's cultural heritage should be considered one of its raw materials and a source of economic wealth, and unimaginative accountants may have to resign themselves to this fact. Herein lies a possible answer to the question: 'why hold a Biennial Festival of Contemporary African Art?'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hegei Goutier</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Acting against AIDS</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY">by Robert Rowe</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many ways of raising money to fight AlDS have been tried, but one of the most unusual must surely be the approach taken by an official of the European Commission. Robert Rowe, who until last year was an assistant editor on The Courier, put on a oneman show in Brussels and then rook it to the other side of the world to raise money for a voluntary organisation working on AIDS prevention and care in Malaysia. Here is his story of fighting the virus with the power of the theatre.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'By the year 2000, South-East Asia will be host to the majority of the world's AIDS cases.' So runs a stark prediction from the World Health Organisation, quoted in a recent paper from a grouping of NGOs affiliated to the Malaysian AIDS Foundation. It goes on to predict that 'the region faces a potential HIV spread of titanic proportions.' In Thailand, a country with a large population and a sad reputation for prostitution, the HIV threat was recognised relatively early and effective public awareness campaigns have successfully reversed the rise in the incidence of infection. But in neighbouring Malaysia, where stricter religious and social attitudes have inhibited wide public discussion of the disease and its methods of transmission, over 13000 people were HIV-positive at the last count-and that is just the figure derived from the small percentage of the population who have been tested. Activists say the true number is certainly higher and it is growing every day.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first cases of HIV in Malaysia were found among intravenous drug users and sex workers, and one of the earliest organisations to begin working with people engaged in these high-risk activities was Pink Triangle. This is a voluntary, non-profit-making body which started up in 1987 by setting up AIDS prevention and support programmes for and with the general public and the gay community. Its name, in fact, refers to the pink triangle badge which men sent to concentration camps in Nazi Germany for homosexuality were made to wear. The group has always depended heavily on volunteers to plan and carry out its programmes, which now also involve running a support group for people with HIV or AIDS and a street outreach programme and drop-in centre providing AIDS information, basic medical care, temporary shelter and food for sex workers, injecting drug users and transsexuals. The centre can also provide legal referrals for members of these groups summonsed to appear in court. For the general public, talks, workshops and poster and photo exhibitions are held in schools, hospitals, factories, youth and corporate organisations and other NGOs. Pink Triangle trains its volunteers, too, to provide counselling and information about AIDS and sexuality to anyone who calls up on a confidential telephone line.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The work is serious and vital, but the atmosphere is far from gloomy in Pink Triangle's premises in a lively part of the Malaysian capital, Kuala Lumpur. Though funding comes from several sources at home and abroad, including the European Union, the organisation still has to generate a lot of its own money, and one successful method they have used is to put on imaginative events where fund-raising can be combined with an opportunity to raise public awareness. Last December, for example, they marked the week surrounding World AIDS Day with a string of shows, dance parties, talk-ins and street activities called Pinkfest '95. In venues all over the town, and on television and radio, well-known personalities joined a hundred of Pink Triangle's own speakers and performers to provide education without moralising. The aim was to personalise the issue of AIDS by showing how anyone could be at risk, but at the same time dealing in facts, not fear. Thousands of attractively designed and very frank leaflets and posters put across the virus-busting message in catchy graphics and pithy phrases in several languages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I happened to be in Kuala Lumpur around New Year and saw a video of some of the Pinkfest highlights which set me thinking how admirable an impression of solidarity and self-help the anti-AIDS struggle in Malaysia conveys, and to wondering whether, back in Brussels, it might not be possible for us in Europe to do something to help. It particularly impressed and touched me that while Pink Triangle delivers its message to every single member of Malaysian society, it makes quite clear, even by its name, that it has a special care for some of that society's most downtrodden members, people for whom no one else had ever ventured to speak. Public silence, opprobrium and ridicule make it especially hard to get the safe-sex message through to gay men, especially the young, to transsexuals and sex workers, and as long as there is no cure the only way of containing the spread of infection is by education- and by changing social attitudes. The many women whose husbands or partners are careless about infection also stand to benefit from greater openness and more factual information. But organising all this takes money.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It happens that among the multinational English-speaking expatriate community in Brussels there is a thriving amateur theatre scene-in fact they say that if two British people found themselves on an otherwise deserted island, one would immediately put on a play for the other, and the same seems to hold true of the Irish and the North Americans. However, it was less certain that anyone apart from me would want to exert themselves, for the many weeks required to stage a production, on behalf of an AIDS charity in a remote Asian country, so l decided to go ahead by myself and perform a one-man comedy. The play was Brief Lives; it has nothing whatever to do with AIDS, but in its day it was a huge success in London and New York. Adapted in the 1960s by the British actor Patrick Garland from the dusty old memoirs of a real historical figure, John Aubrey, it depicts a day in the life of this 1 7th-century English scientist, historian and wit. As he potters about, an extremely old man, in a garret full of manuscripts and curios, he reminisces about his contemporaries in hilarious and touching vignettes, the potted biographies which give the play its name. Aubrey died in penury, but the picture he gives of a vanished age is now reckoned to be the equal of the record we find in the diary of the better-known Samuel Pepys.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is also a great deal funnier, and when I showed the script to various friends I was astounded and moved to discover how many of them wanted to be involved in the project. Eventually we put together a team headed by the director, Anne Wilkinson, a music impresario married to a coal expert from the European Commission, with production, design, stage management, lighting, sound effects, costume, music and offstage voices-not to mention publicity and box office-provided by other friends from the European institutions or the private sector. The five performances were given in June in a small theatre just adapted from a pottery workshop, and altogether the Brussels showing made a profit of some 110 000 Belgian francs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We had expected just to send this donation to Pink Triangle through the post, but to our immense pleasure they said they would like to see not just the money but, if possible, the play too. By ingenious compression the designer, Burt Baum, managed to cut the essentials of the set down to three sheets painted to give a three-dimensional effect, we put the voices and music on cassette, rolled up the costume tightly and worked out that the whole play, thus reduced, could be got into one suitcase. There is a little theatre company in the Pacific ACP state of Vanuatu called Wan Smol (One Small) Bag which actually gave me this idea. So off I went to Kuala Lumpur with this bag, and did the play another five times there.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The staging in Malaysia was done by an adventurous outfit called Instant Cafe Theatre. This young company has a reputation for pushing forward the boundaries of public discussion with topical plays and supports Pink Triangle's aims and work. Brief Lives was well outside their usual repertoire, as well as being spoken in the English of 300 years ago. My worry was that bringing such a Western and Eurocentric entertainment might be resented as cultural imperialism in a country with three great and fascinating cultures of its own, Malay, Chinese and Indian, each with its own style of drama. But it turned out there was a local tradition of amateur dramatics in English, particularly Shakespeare, and that English is the usual lingua franca for speakers of different Asian languages. What went down unexpectedly well was the depiction of an old man nearing death and reviewing the best moments of his life; as the character puts it in the play, 'When a boy, I did always love to converse with old men, as living histories,' and Maiaysians have a particular regard and affection for the elderly. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I came away from Kuala Lumpur with many charming memories: the unfailing, sweet-natured enthusiasm of the audience; the relief on the first night as I stood on stage in a floor-length costume of three layers, designed to suggest London in midwinter rather than to cope with the equatorial heat of the Malay peninsula, and realised that the stage was air conditioned. The night when this air conditioning blew out a vital candle on the stage, and a man in the front row lent me his highly un-17th-century lighter to get my clay pipe going. The Chinese friend who gave me a genuine antique opium pipe to add to John Aubrey's collection of exotic curios. The delicious succession of Asian chicken dishes which the stage manager produced for me to eat on stage, cooked in very un-English coconut milk or glazed with rice wine. The work permit which specified I could perform as an artiste but must not 'sit out' or dance with the audience! The theatre's resident singer asking if she could add the play's Elizabethan theme song, with lute accompaniment, to her repertoire.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Taking this play to another continent was a fascinating cultural experience for me as a European, and I hope for the audiences too it was something more than just a painless way of being relieved of money in a deserving cause. At any rate the theatre asked if they could have another play soon, one in which Malaysian actors could be incorporated as well. As for Pink Triangle, some of its leading lights were packing their bags to go to Vancouver for this year's International AIDS Conference, but before they left it was a pleasure to hand over the proceeds of the whole venture and to hear that the organisation will use the money to develop a drop-in centre for people approaching them in person for the first time. Some first-timers are understandably timid about coming to the unfamiliar (and clearly signposted) premises for help or information, and a private space where they can talk in confidence is something Pink Triangle has always wanted to provide but could never find the funds for, as the project or programme money they get from their regular donors is invariably tied to what outsiders might think were more urgent priorities. It is not only the headline grabbing schemes which have useful effects: a quietly welcoming space where someone can be himself or herself may do more to dispel an individual's fear and ignorance than publicly visible campaigning, especially where religious and social pressures against certain types of nonconformity are strong. In fighting HIV/AIDS, we must try whatever works. And empowerment must begin with the self. It was a great privilege to be welcomed in like any other volunteer wanting to help bring about a necessary change. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">R.R. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">CTA-Bulletin</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Earthen architecture</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Materials, techniques and knowledge at the service of new architectural applications</P>
+<P ALIGN="JUSTIFY">by Hugo Houben and Hubert Guilland.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A major building material</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The importance - both in quantity and quality- of unbaked earth constructions in the world is very little known. Believed to be of ancient origin, (it is associated with the early civilisations of the Nile, Tigris and Euphrates, Indus and Huang He), nowadays, earth is not usually regarded as a major building material. This is despite the fact that it continues to leave an undeniable and distinctive imprint on the architectural landscapes, both rural and urban, of many countries. Unbaked earth is still, in fact, a major building material, being used extensively by people to erect homes and other buildings. Although sites of human occupation have seen constant regeneration with the passage of time, unbaked earth construction has persisted. Excavated from the soil itself, and moulded by the hand of man (or trampled by beasts of burden), the result is a building material which is used in all forms of construction-from simple huts and modest homes, to farm buildings, large houses, urban blocks, religious edifices, castles and palaces. The skills employed are based on knowledge acquired and refined over a long period of time.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A contemporary building material</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While the use of earth in so called 'advanced' countries has declined in the 40 years since the end of the Second World War, in the developing countries it has continued unabated. In the former, the industrialisation of construction and other sweeping changes have rendered obsolete ancient techniques based on the use of local skills and materials, and on mutual help within communities. In the latter, various factors have dictated the continuing use of locally available solutions, materials and knowledge. These include shortages of processed materials (which are costly in both foreign currency and imported energy terms), the widening of the development 'gap', the accumulation of debt contracted within the international monetary system and the survival of local life-styles in which people are accustomed to coming to get her for mutual help for survival. In these countries, which have no industrial means, and which are to be found in various latitudes across the world, earth remains the main-if not the only- building material. Do these circumstances mean that it is a poor material, fashioned using outmoded techniques and unsuitable for promoting the development which is so necessary? The answer to this question is a clear 'no'. On the contrary, the materials and techniques involved are generally of a high standard. They can ensure true architectural quality, allowing communities to continue creating their private or public living environments, and to integrate their buildings into a coherent framework of self-generated development which makes the most of the resources available, both human and material. In fact, scientific and architectural research into earth as a building material, and on related building techniques, has made considerable progress in recent decades. Combined with investments made by industrialists and construction companies, the result is that we now have a wide range of properly mastered production procedures and technical solutions available. These offer great flexibility in meeting a wide range of possible applications.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Making a mark on world architecture</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Recent global surveys, although partial (covering about 30% of the world's housing), have given us an indication of how extensively earth is used in construction. In developing countries alone, 50% of the rural population and 20% of those living in urban areas are believed to be concerned. The figures, which are drawn from the combined data of statistical surveys in various areas, and from bibliographical information, almost certainly underestimate the true position. They show, for example, that 60% of the housing in Peru is in moulded bricks or rammed earth. 83% of the houses in Kigali, the capital of Rwanda, are made of earth. More than 70%of India's housing stock is constructed out of moulded earth bricks or using successive layers of earth, and these buildings provide shelter for nearly six hundred million people. In France, many rural dwellings are built from unbaked earth and one finds, for instance, that in the Dauphine region, up to 90% of the buildings in certain villages are made out of rammed 'pise' earth. Finally, in California, there were estimated to be almost 200 000 'adobe' (sun-dried earth brick) dwellings by 1980 and the use of this material was growing at the rate of 30% a year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Closer examination reveals that the whole world bears the indelible stamp of earthen architecture. Earth is used in Africa-in humble shelters built on leased land and in the great granaries of the continent. It is found in the palaces of the Hausa emirs of Nigeria, the ksours and kasbahs of Morocco and the mosques of Mali. In the Middle East, you come auoss it in the tightly-packed neighbourhoods of Ispahan and Iran, the fortified dwellings of Najran in Saudi Arabia, the multi-storey earth blocks of Shibam and the valley of the Hadramaut in Yemen. In Europe, there are the mouded brick farms of Aquitaine and the baroque and neo-classical castles of the Saone valley. And bringing in other parts of the world, we might mention the pueblos of the New Mexico Indians, and the houses built by the Hakkas in the Chinese province of Fujian, laid out in their characteristic concentric circles. The use of unbaked earth in building may be seen as a vestige of past history, but it is actually a living framework for history in the making.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Realistic uses for the future</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Confronted with the energy crisis of the 1970s, oil-dependent industrialised countries were forced to look again at tried and tested technical solutions which were now proving to be too 'energy-greedy'. The building sector did not escape this reappraisal and the search began for ways of reducing energy consumption both at source (covering the production and use of building materials) and further down the production chain (maintenance). Research on biomass and solar energy ran in parallel with experiments to update traditional materials and to attempt to rationalise the production process. Earth again became a focus of interest, with government institutions supporting a considerable amount of new research and experimentation. This covered applications in both the industrialised world and in developing countries, research for the latter being undertaken in the context of bilateral or multilateral cooperation. With the threat to the ecological balance posed by pollution, degradation and the plundering of natural areas, this interest in developing materials and techniques that are inherently friendly to the environment has not lessened. In many places, people are becoming increasingly involved in controlling and managing their living environment. The field has been opened up by qualitative research, a new awareness of the available options and an increase in leisure time. With techniques now at hand that are easy to use and economical, a greater measure of (partial or complete) selfhelp building is now possible. The USA, Australia and Germany all encourage new forms of intervention in building which give greater responsibility to the occupier in the creation of his living environment. Viewed from this perspective, earth as a building material has definite advantages and plays an important role.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In developing countries, burdened by debt and confronted by an urgent need to build on a scale unprecedented in history, imported materials, techniques and energy are largely inaccessible to the majority of people, and their use may contribute to promoting 'bad' development. Building with earth emerges as an efficient shortterm way of producing houses or public buildings such as schools, which are both economical and of high quality (being culturally and climatically suitable). Decision-makers in these countries are well aware of this and have mobilised 'upstream' feasibility studies in their education and public housing programmes. The research covers local resources and knowledge, and the use of labour intensive techniques that generate employment and enable the population gradually to become 'monetarised'. The days of costly experimentation, often with no practical result, are now over. A new confidence in the resources that are available must be encouraged. There needs to be an increase in building completions and those who built them need more training. Today, this is happening in Mexico (850 earthen houses recently built in the state of Zacatecas) and in Burkina Faso (6000 school classrooms constructed by 1995.) No fewer than forty million homes will have to be built between now and the year 2000 for the urban population of Africa alone.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Studies show that for most of the people involved, there is no choice but to employ local materials, most often earth. One can thus predict that at least 20% of urban and pert-urban housing in African countries (about eight million units), will be built in earth over the next ten years, at a rate of eight hundred thousand units per year. If demand from rural areas is added to this, one gets some idea of the scale of the task facing decision-makers and builders. The use of earth and other locally available materials is unavoidable, and should be encouraged.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Environmental advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is particularly important to enumerate the many advantages of building in unbaked earth from the point of view of the environment. This issue, one of the contemporary problems facing society, is increasingly moving centre-stage, and in the future, it is sure to play a greater part in political, economic, social and cultural strategies linked to the planning and improvement of the quality of life. Here we refer to the concept of the environment in the widest sense of the word, ecological, economic, technical, health-wise and psychological, cultural and human.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From the point of view of the ecological environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In terms of pollution and degradation, unbaked earth offers a highly positive picture:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It does not contribute to the deforestation which results, for example, from the use of organic resources for firing baked earth materials.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It does not consume any nonrenewable energy (oil, gas, etc.) at source for the processing and production of materials, or further down the production line in their application. This is in sharp contrast to the production of cement, lime and other conventional binding materials, and steel.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- By exploiting strata on construction sites, it allows a considerable saving in energy for the transport of materials.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It does not contribute to a degradation of the landscape as does the extraction of minerals and ores which hollows out hillsides and creates open cast sites. A great deal of the earth excavated in the course of large public works (notably roads and motorways) can be recycled and used in building (allowing very easy decentralised distribution).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It does not contribute to the diminution of resources of aggregates such as gravel and sand, excavated either from quarries or from water courses, in insular sites or lagoons. The latter can endanger the ecological balance of these natural environments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It uses very little water which is essential for the life of the people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It produces no industrial or chemical waste and has the additional advantage of being almost entirely recyclable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From the point of view of the economic environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It is often comparable in cost with, or indeed more economic than competing technologies and requires no major financial mobilisation for its generally light production infrastructure. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It guarantees rapid amortisement thresholds for bankable investments thanks to its low infrastructure requirements for usable production.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It contribution to local flexibility, being readily susceptible to a decentralised approach.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Throughout the production process, it creates employment and monetary added-value which can be injected for development purposes into other sectors of the economy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- By allowing savings in energy and foreign currency, it contributes at the macro and micro economic levels of the building sector, to a considerable reduction in developing countries' debt and to the balance of payments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From the point of view of the technical environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It has thermophysical and hydric properties (good conductivity, energy retention capacity, thermal differential, delayed temperature differences etc.) which help ensure comfortable temperatures:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It normally only requires simple production and application tools (moulds, presses, light shuttering, normal masonry tools, etc.) which are widely accessible to masons and self-help builders.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From the point of view of health and the psychological environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Not only non-polluting in its use, it also guarantees the absence of harmful effects in the context of daily life (no gaseous emissions or other toxic chemical components, radioactive emissions etc.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It contributes to psychological wellbeing by the architectural exploitation of its inherent characteristics; these include the surface texture, colour, form and luminosity of the material. It thus makes an active contribution to the beauty of the living environment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From the point of view of the cultural and human environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-It maintains the traditional architecture heritage of the area in question through the use of local materials and thus plays a part in the respect for, as well as the survival and updating of, cultural, architectural and urban environments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- It allows local populations to take charge of the production of their built environment and thus contributes to the expression of the democratic rights of all to control their living environment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The future of earth on the move</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In her work entitled 'A Fate Worse than Debt' (Penguin Books, 1988), the famous political commentator, Susan George, analysed the debt situation of developing countries and attempted to determine the basis for a positive resolution of the problem. Her approach focused in particular on solutions involving repayment in creative values or 'in kind' rather than in strictly monetary means. At the end of her analysis, she put forward eleven potential solutions to allow this repayment in kind and to launch a coherent approach for the development of less advanced societies. One of these recommendations was that it would be necessary to develop 'the study and survey (and if necessary the improvement) of local building techniques, in particular earth architecture ('pise' or 'banco').' Ms George argued that new buildings, particularly public ones, should be constructed using these techniques.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is clear that various solutions are being considered for the future: one in which building with earth, using a wide range of local techniques, will have a new technological, social, cultural, ecological, economic and political role of paramount importance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Various methods of utilisation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The technical, constructional and architectural possibilities of earth are very extensive. The study of popular traditions and of traditional knowledge throughout the world has enabled some 18 different methods of utilisation of the material to be identified, each in itself capable of being applied in a wide variety of ways. This wide construction potential has enabled the building of modest shelters, village houses, urban blocks, religious edifices and palaces. This is not to say that other traditional materials do not have an important role, but the sheer diversity and flexibility of earthen architecture probably cannot be equalled.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As was indicated earlier, the use of earth as a building material has given rise to numerous applications using a wide variety of production and construction techniques. Some of these techniques are still used in traditional construction many countries, some have been abandoned, while others have only recently been the subject of developmental experimentation. It is worth noting that there is a register of the principal techniques, mainly associated with processes using moulds, shuttering and direct shaping. The six most widely used techniques are: 'adobe', 'rammed earth', 'straw clay', 'wattle and daub', 'cob' and 'compressed blocks'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Of these six, three (wattle and daub, straw clay, and cob), are highly traditional, while the others (adobe, rammed earth and compressed earth blocks) have recently been the subject of spectacular evolution linked to the modernisation of production machinery and methods of application. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p094.png"></center><br>
+ The use of earth</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The couriers mailbag</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Plea for African solidarity</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thank you sincerely for your report on the second plenary of the Global Coalition for Africa which appeared in the March-April 1996 edition. As a 'displaced' Liberian, I would like to comment on some of the issues reported in the article.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">First, I hope that Africans recognise and appreciate all that former President Jimmy Carter has done and continues to do for our beloved continent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Second, I support the view of Ms Johnson-Sirleaf and President Afwerki of Eritrea that we, as Africans, must invest in ourselves and in productive endeavours in our own countries. However, given the number of civil wars, that have resulted in displacement of our peoples and migration of the labour force, it is imperative that we also begin to think of and recognise each other as Africans first - and only then as members of whatever ethnic group we belong to. As a Liberian with professional qualifications who relocated to Ghana in 1992, I met with opposition and resentment because of my nationality and sex. I subsequently went to the Caribbean where my acceptance as an African was easier.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When there is a population movement, the psychological impact associated with feelings of rejection and intimidation is severe. Sub-Saharan Africa will never develop or reach its fullest potential until we begin to think and act as a united, yet diverse group of people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I agree that it is important to develop our homelands first, but in the case of Liberia, Burundi or Rwanda, where no one seems to understand the concept of peace or the idea of having a future, it is crucial that the displaced be respected and accepted as fellow Africans. It would be even better if we were afforded the opportunity to integrate and assimilate into society.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ciata A. Bishop, Grand Cayman.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What about Guinea-Bissau ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I am a student from Guinea-Bissau reading international law and political science at the Social Science University in Toulouse. I have also been a faithful Courier reader for more than seven years. In the March-April issue of 1996, you published an article on fisheries by Anthony Acheampong entitled 'A vital food source in West Africa'. You gave the figures for fish production in 16 West African countries-but did not mention my native country! I should point out that Guinea-Bissau consumes and exports a great deal of fish, and the product is an important source of foreign exchange to the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">F.J. Alves d'Almada, Toulouse, France.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Media and democracy in Southern Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I refer to the article with the above title by Francis Caas which appeared in issue no. 154 of The Courier (November-December). I enjoyed reading the text which examined the emergence of a free press due to the advent of political liberalisation in the Southern African region. However, I wish to make a correction as to what I think is a misrepresentation of fact. The author said, and I quote: 'The installation of a democratic regime in 1994 (in Malawi) enabled the MBC to begin broadcasting in all languages spoken in the country'. This is not actually correct although the Malawi Broadcasting Corporation, apart from broadcasting in English and Chechewa, has since introduced Tumbuka on the radio. I felt it was important to put the record straight on this.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Disher G.DJ. Pindani Lecturer in Public Administration, Chancellor College, Zomba, Malawi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Corrigenda </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In issue no 157, a number of 'author' footnotes were inadvertently omitted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pascal Dotchevi, author of 'Togo: the victory of the taxi. bikes' (p.11) is a journalist on Kpakpa Desenchante, a satirical weekly published in Lom&eacute; </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Piritta Sorsa, author of 'Banking and securities' (p.13) works at the IMF office in Geneva.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yves Delafon, author of 'Developing consultancy work in the ACP countries' (p.15) is the director of a consultancy and President of the Federation of External Trade Associations in Provence/ Cote d'Azur.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">N'Gone Fall, author of 'Fashion; Out of Africa.. the breath of inspiration' (p.53) is a journalist.</P>
+<P ALIGN="JUSTIFY">Also in issue 157, some errors appeared in the article entitled 'Sparks fly in Namibia'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the introductory section it was stated that secret harlots were held on resolutions relating to Nigeria, Niger and Sudan. This should have read Nigeria, Niger and Equatorial Guinea; a resolution on Sudan was passed by normal, open vote procedure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under the heading 'The future of Lom&eacute;' the ACP Generai Rapporteur vvas refered to as Mr Firmin, which is the forename. The General Rapporteur's surname is Mr Jean-Louis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the fifth paragraph under the same heading, there was a reference to Helena Torres Couto. This should have read Mr Jose Manuel Torres Couto. </P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Bibliography</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">L'Afrique est-elle protectionniste- Les chemins buissonniers de la liberation exterieure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(Is Africa protectionist ? Greater economic freedom via the maze)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Beatrice Hibou. Karthala Publications (22-24, boulevard Arago, F-75013 Paris). 1996. 334 pp. ISBN 286537-633-8.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This volume offers a clearsighted analysis of the foreign trade policies of African states, fraud, smuggling and the way in which the franc zone operates, giving a definitive, reformulated account of structural adjustment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In her approach, the author is critical of both the liberal political economy and the new trends (the 'new political economy' end the neoinstitutionalist trends) which perpetuate the division between the economy and society. She refers to K Polanyi for whom Man's social relationships include economics and in whose opinion the economic system is managed as a function of non-economic motives.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">From this starting point, Beatrice Hibou demonstrates the part played by the unexpected and the unintentional in economic policies as they currently exist, revealing that coherence in foreign-trade policies on the part of African countries is not an economic priority but a socio-political one. In this connection, she shows that structural adjustment programmes have been unsuccessful in making any real impact on protectionist practices, at least in terms of their political and historical bases.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">After an overview of (legal or illegal) foreign-trade practices in contemporary Africa, protectionism is clearly alive and well, although much less widely applied and effective than about a decade ago. The reduction in the State's legal powers has meant increased freedom for 'informal networks', various types of dispensation, and an increase in fraud and smuggling.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the basis of Jean-Francois Bayart's opinion, dating from 1989, the author suggests that the explanation is to be found in the specific nature of Africa's economic history, which is one of independent means, a lack of production and management of dependency without the way in which it operates being affected. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dominique David</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Reality of Aid</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Independent review of international aid. Pub.: J. Randel and T. German. Earthscan Publications Ltd. (120, Pentonville Road, UK London N1 9JN). 1996. 244 pp. ISBN 1 85383 292 8.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Reality of Aid (now an annual publication) compiled by two NGOs; Eurostep and ICVA, aims to highlight the extent to which donor aid helps developing nations, looking beyond the official publications of governments, banks and inter-governmental bodies. It contains a useful critique of the European Union's various aid policies and the respective bilateral policies of each of its 15 member states, as well as those of other Western nations like Australia, New Zealand, Switzerland and the United States. This year's review highlights, in particular, the need to mount more projects to alleviate poverty, despite aid commitments becoming more scarce.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It says, for example, 'Too much aid is being squandered by governments on projects which have more to do with commercial and political advantage than poverty eradication. Rigorous evaluation needs to identify those programmes which can make an impact -and aid must increasingly be directed only to these areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">International aid to developing nations has fallen off over the years. In 1994, members of the OECD's Development Assistance Committee-21 of the world's richest countries-allowed their aid to fall to just 0.3 % of GNP, the lowest level for more than 20 years. The review stresses the need for donors to address in particular; policy coherence (environment, agriculture and consumption policies are all linked to poverty), the effectiveness of aid, the failure thus far to invest in people and the fact that the amount of assistance going to health and education is stagnating.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The review also features analytical case studies of various donor activities in selected developing nations (India, Fiji, Cambodia, Peru, Zimbabwe) and looks at Western assistance to post communist countries in transition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A chapter on the European Union's current development policies, edited by Mirjam van Reisen, a Brussels-based Eurostep researcher, criticises the lack of coherence of EU aid with its Member States bilateral programmes-an issue which is likely to come more to the fore as other European nations join the Union in the next millennium. Ms van Reisen also claims that there are too few staff running the EU's development policies and suggests, in particular, that there is a lack of expertise in the social and poverty areas. She stresses the importance for the EU's political leaders of giving more political clout to the EU's development policies at the Intergovernmental Conference (IGC), which is currently engaged in revising the EU's treaties. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Debra Percival</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">News round-up</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">In brief</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Trafficking of women</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">European Commissioner for immigration policy and legal affairs, Anita Gradin, will set to work with fellow Commissioners over the coming months to draw up a European Union action programme to clamp down on the trafficking of women which she describes as, 'the modern slave trade'. This comes hot on the heels of the Vienna European conference on trafficking of women, held on June 10 and 11, which was co-hosted by the European Commission, the Austrian government and the International Organisation for Migration.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ms Gradin told journalists on June 12: 'I will put forward to the Council and the European Parliament a communication on the trafficking in women for sexual exploitation. This will cover migration policy, police and judicial cooperation, and social aspects to support and protect the victims. It will also consider European relations with the source countries, where the women are recruited.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Vienna conference highlighted the need for cooperation between Member States and third countrie from which women are lured into prostitution in Western Europe. Recommendations, which are expected to be part of the EU policy, include setting up central national units in each Member State to exchange information.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Commissioner told the participants in Vienna: 'The slave trade in women is growing, a slave-trade that aims at sexual exploitation. No part of the world seems to be free from this degrading treatment of women. Women are bought and sold like cattle or commodities. They are deprived of their rights and their dignity. And the direction of the trade is the same all over-it is women from poor conditions that are forced into a deplorable life by men in richer countries.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">She cited a typical case of one woman from the Dominican Republic from the book 'Stolen Lives' by Sietske Altinks: 'One day I went to visit a friend who was going to discuss job opportunities in Europe. I went with her and met a schoolteacher who knew somebody called Juan who could get me a job in the Netherlands. When I went to see him, his associates told me that I would easily find employment in a beauty parlour.' She ended up in prostitution.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ms Gradin continued: 'The consequences for the women are dreadful. Often, they find themselves deprived of their freedom to move and decide for themselves; they are often locked up and subjected to violence and sexual exploitation. And should they be able to free themselves, they are regarded as illegal residents and expelled.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Debra Percival</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> Aid for development in the field of communication</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A seminar was held under the auspices of the United Nations in the Belgian Parliament on 6 and 7 June, on 'the future of international development cooperation: new challenges for communication'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union was represented at the event, among others, by Colette Flesch and Steffen Smidt, the directors general respectively of DG X and DG VlII of the Commission. Mrs Flesch gave a presentation at the opening session in which she highlighted the various communication approaches adopted by the European Community in its efforts to counter what appears to be a growing lack of interest in development aid on the continent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mr Smidt, who spoke in the second session of the seminar, began his presentation with an anecdote, citing a text displayed at the entrance to a Federal building in Washington. This states: 'Taxes are what we pay to have a civilised society'. Paraphrasing this sentiment, the Director-General argued that, 'development assistance is what we pay to have a civilised European Union.' The question, he went on to pose, was whether we were paying enough ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A number of the participants painted a discouraging picture of the situation facing the world's poorest countries in a world of advanced communications and increasing globalisation. Almost all were pessimistic about the impact of the socalled 'information super highways' on the least-developed nations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the most striking interventions came from Mabbub Ul Haq, the former Finance Minister of Pakistan, who spoke just after Mr Smidt in the plenary meeting, as well as at one of the discussion workshops. Mr Ul Haq urged the creation of a UN Economic Security Council, arguing that the main risk of global conflagration lies in the disparity that exists between rich and poor, now that the dangers associated with the Cold War have receded. One of the most acute issues under discussion was the growing challenge to the received wisdom that technical assistance is essential for consolidating national capacities. The evidence of 40 years of technical assistance would suggest otherwise (with 95% of funds set aside for this purpose going to foreign experts). Indeed, it was argued that those countries receiving most technical assistance per capita, had 'benefited' least from the system.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In his second contribution, Mr Ul Haq painted a somewhat more encouraging picture, pointing out that the shaky 0.3% share of GNP allocated to development aid by the industrialised countries had achieved miracles in terms of increased life expectancy (up by 17 years) and the doubling of school enrolments in the countries of the South.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hegel Goutier</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Round one of the South Africa-EU talks</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">South Africa gave no immediate response to the European Union's proposals for a bilateral trade agreement at the first round of high level negotiations in Brussels on June 20. The talks were headed by Dr L. T Links who is South Africa's new Ambassador in Brussels and for the KU, by the Director General for Development, Steffen Smidt. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The most difficult subject to negotiate will be future terms of access for South Africa's farm produce. The European mandate, which was agreed by EU Member States on March 25, foresees the exclusion of 39% of South Africa's farm produce currently sold to the EU from the planned free trade area. Applying World Trade Organisation (WTO) rules, the EU wants a scaled dismantling of barriers to trade in both farm and manufactured goods over a 10-year period, with a maximum of 12 years for a few highly sensitive items. But the EU has agreed to 'asymmetry' whereby, in some areas, it will open up its market to South Africa at a faster pace than vice versa. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Abdul Minty, deputy Director General at the Foreign Affairs Department in Pretoria, who is one of ,the chief negotiators, explained that South Africa had not yet responded to the terms because it is still consulting internally with the National Economic Development and Labour Council and with its partners of the Southern African Customs Union (Botswana, Swaziland, Namibia and Lesotho). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During a recent visit to Brussels, South Africa's former agriculture minister, Dr Kraai van Niekerk and his deputy, Mrs Thoko Didiza, told reporters that as it stood, the EU's mandate was 'anti-developmental'. Dr van Niekerk said he would like to see citrus fruit, in particular, removed from the list of exclusions. He also sought to dispel the fears of some EU Member States who wish to omit a larger proportion of South Africa's farm produce from the FTA, for fear of competition with equivalent EU produce.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dr van Niekerk stressed the 'complementary' nature of South Africa's farm production. He pointed out that his country's growing season was at the opposite time of year to that of the EU and noted that South Africa's output of farm produce could only increase by about 2%.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">EU spokesman, Joao Vale de Almeida, said that progress had been made during the Brussels talks on aspects of South Africa's 'tome protocol'. This is aimed at giving South Africa certain benefits from the Lom&eacute; Convention- some eligibility for South African companies to tender for Lom&eacute; contracts and the partial extension of the Lom&eacute; rules of origin to South African exports. It was originally planned that the Lom&eacute; protocol should be implemented at the same time as a bilateral trade accord, (on January 1 1997). Mr Vale de Almeida spelt out that although it would not be technically and legally impossible for the Lom&eacute; protocol to come on stream without the bilateral pact, it would be more practical if the two could be implemented at the same time. A second round of talks is expected to take place in the autumn.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D.P</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Echo Media Awards</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On 29 June, the European Community Humanitarian Office (ECHO) launched a Television and Radio awards scheme to reward high-quality coverage of humanitarian affairs. Prizes will go to programmes produced or co-produced by independent production companies and/or broadcasting stations in the 15 EU countries which have been transmitted in a Member State on terrestrial or satellite television or radio between January 1 1995 and September 1 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Judging by a panel made up of NGOs, environmentalists, politicians and the media will be in six categories:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">People on the move-a television documentary on the humanitarian consequences of sudden or forced population movements; </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the minds of the people-a TV documentary on the psychological trauma in crisis situations; </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Forgotten conflicts-TV coverage of a long-running crisis forgotten by the mainstream; </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vulnerable groups-TV coverage of the hazards encountered by women, children and the elderly in rebuilding their lives; </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Broadcast commitment-to a radio or TV station for consistent, high-quality coverage of humanitarian issues; </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Radio award-for the most incisive and analytical coverage of an emergency or humanitarian crisis. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Announcing the scheme, EC Commissioner, Emma Bonino, said: 'These awards give us an opportunity to acknowledge the vital role that broadcasters play in raising awareness of the issues at stake in imaginative, accurate and moving ways. They also serve to remind us of some of the basic European values such as solidarity and humanitarianism that have sometimes been eclipsed by barrages of headlines about mad cows and fish wars.' </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Entries for this inaugural year must be submitted by September 19, 1996. Details can be obtained from: Mandy Duncan-Smith, Media Natura (UK), tel: (44 171) 240 4936 fax: (44171) 240 2291 E-mail: medianatura@gn.apc.org</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Posters featuring contemporary Bantu art</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the framework of its cooperation programme with the Commission, CICIBA (Centre international des civilisations bantu-B.P. 770-Libreville- Gabon) has recently launched a series of large format reproductions featuring contemporary Bantu art. Thirteen works have been chosen, displaying a representative selection of art forms-painting, sculpture, engraving and moulded leather. The posters, more than 5000 of which have been printed in quadrichromic colour, have a 40 x 60 format. They are also available as postcards.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The artists featured are Marcela Costa (Angola), Assouambo (Cameroon), Daikou (Central African Republic), Mouanga Nkodia (Congo), Abdou Moeou (Comoros), Pambou Boulaz (Gabon), Jose Menan (Equatorial Guinea), Protais Hakizimfura (Rwanda), Protasio Pina (Sao Tome &amp; Principe), Silu Kinanga and Munyenz Tshibangu (Zaire) and Mulenga Chafilwa (Zambia).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CICIBA has also put together a similar series on ancient Bantu art. The fourth bi-annual exhibition of contemporary Bantu art, which has received some support from the European Commission, was due to be staged in Luanda (Angola) during July and August.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Links between technology and society</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For more than 50 years, technological innovation has been regarded by many writers in the field as the motor of economic development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Today, with rapid developments in the media sector and the emergence of 'information super-highways', the whole world is talking about the emergence of a new society dominated by 'smart' technology linked with research and creativity. This trend gives rise to many questions. Will the information be made available to all, and if so, when ? Will it lead to a change in North-South relations? Can we imagine what a world of 'tale-working', 'tale-education' and video on demand will be like ? What will the cost of all this be? Will biotechnology rescue the world or be the cause of its downfall ? What will the consequences be for the environment ? And in a globalised world, what standards and norms will be used ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In short, what is the real nature of the relationship between technology and society; between science and humankind ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fifteen universities of the EEA (European Economic Area) from Oslo to the Basque country and from London to Athens (taking in Roskilde, Maastricht, Louvainla-Neuve, Namur, Strasbourg, Lausanne, Sienna, Bari, Madrid, Valencia and Lisbon), have come together to offer a multidisciplinary course focusing on these key questions. During the first term, classes in theory and seminars are offered (in the local language of the institution) by experts from the academic world and the public and private sectors. Visits are also planned to multinational companies and laboratories. For the second half of the course, the students gain a wider European dimension by 'changing' university (with grants from the Socrates programme). The bulk of their time at this stage will be spent preparing a research dissertation in English on a topic which fits in with the specialisation of the host institution.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For further information on the ESST</P>
+<P ALIGN="JUSTIFY">programme, contact:</P>
+<P ALIGN="JUSTIFY">Prof. E Lints (UCL-Belgium)</P>
+<P ALIGN="JUSTIFY">Tel. (32) 01047.82.60</P>
+<P ALIGN="JUSTIFY">Prof. T. Nguyen (FUNDP-Belgium)</P>
+<P ALIGN="JUSTIFY">Tel. (32) 081-72.49.09</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The institutions at work</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Common foreign and security policy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Within the framework of its Common Foreign and Security Policy (CFSP), the European Union has recently issued a number of statements, details of which are set out below:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Antipersonnel mines</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 13 May 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the closure of the Review Conference of the States Parties to the Convention on Certain Conventional Weapons, the European Union recalls that it has, in recent years, redoubled its efforts to combat the severe consequences caused to civilians by the indiscriminate use of land mines, in particular anti-personnel mines.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The KU, which adopted joint action in May 1995 in order to reconfirm its commitment to the objective of an overall strengthening of Protocol 11 of the CCW, considers that the achievements of the Review Conference (such as the extension of the scope of Protocol II; the strengthening of restrictions on the use of mines; the new and immediate prohibitions regarding transfers; the provisions on technological cooperation and assistance; the regular review mechanism, etc), taken together, are significant steps forward, both in terms of the land mines protocol itself and of the development of international humanitarian law.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The KU, however, underlines that the resuits of the Review Conference fall short of its expectations and of some of the goals set out in its joint action. In particular, the EU should have liked an effective and binding verification mechanism and no periods of deferral of compliance, or at least much shorter ones.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU is convinced that the conclusion of this Review Conference is only the beginning of a challenging process which requires constant and widespread efforts and persistence in order to fully achieve its basic humanitarian objectives. The EU will continue to seek solutions to the problems caused by antipersonnel land mines and will strive towards the goal of their eventual elimination as stated in UN Resolution 50/70 (O). In the meantime, the Member States of the EU will seek early ratification of the amended Protocol II, as well as of the new Protocol IV on blinding laser weapons, and will take urgent steps to ensure their compliance with all the provisions of these two protocols pending their entry into force.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU will also continue to make active efforts with a view to achieving universal adherence to the CCW, since its objectives can only be effectively attained through implementation of its provisions by the widest number of states and parties to conflicts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Furthermore, the EU recalls its determination to pursue its contribution to the international mine clearance efforts. The EU has already contributed to the UN Voluntary Trust Fund, financing, in particular, projects in Angola and Mozambique as well as in Bosnia-Herzegovina and Croatia. In addition, the EU will consider the possibility of conducting specific demining actions and will continue to seek to that effect the contribution of the WEU to the elaboration and implementation of such actions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Central and Eastern European countries associated with the EU (Bulgaria, the Czech Republic, Estonia, Hungary, Latvia, Lithuania, Poland, Romania and Slovakia) and the associated countries Cyprus and Malta, as well as the EFTA country members of the EEA, Iceland, Liechtenstein, and Norway, align themselves with this statement.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Great Lakes region and the situation in Burundi</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 24 June 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU's objectives and priorities with regard to the Great Lakes region are to secure peace, to consolidate the process of national reconciliation in the countries concerned, to facilitate a return to normal democratic life, in particular by restoring the rule of law, and to encourage economic and social recovery.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Aware as it is of the close links between the various political, economic and humanitarian problems in the region and of the serious risk of destabilisation which remains, the EU would emphasise the need for a comprehensive approach and a regional dimension in the search for lasting solutions to the crisis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It considers that the presence of over a million and a half refugees in the region constitutes a major factor of destabilisation and that their return to their countries of origin in safety and with dignity is essential if peace is to be restored.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It appeals to the Heads of State who signed the Cairo and Tunis Declarations to comply with the undertakings they gave, so as in particular to stop trafficking in arms and the training of the various militia and armed groups which serve only to increase insecurity in the region. It would point to United Nations Resolution 1053 in this regard and also the measures in the plan of action adopted by the Bujumbura Conference (12 to 17 February 1995) for the prevention of subversive activities in countries of asylum. The EU also emphasises the importance of deploying United Nations observers in airports and at frontiers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU is increasingly concerned at the deteriorating political and human rights situation in Burundi and at the increase in violence. The persistent clashes, spreading over different parts of the country, and the killings and atrocities committed against the civilian population could well involve Burundi in a spiral of permanent conflict.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU strongly condemns all recourse to violence, which will never bring about a solution to the country's problems, and appeals to all the factions in the country to begin negotiating a resolution of their differences and to agree on an immediate, general cessation of violence. It supports the initiatives taken by the United Nations and the Organisation of African Unity to restore peace, as well as former President Nyerere's current efforts in this area.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It fervently hopes that the talks taking place will result in a national dialogue open to all factions within the country. It also expresses its support for the ongoing efforts made by various bodies and eminent figures such as former Presidents Carter and Toure, and Archbishop Tutu.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU would point out that it too has taken initiatives aimed at resolving the crisis and recently appointed a special envoy for the Great Lakes region, Mr Aldo Ajello, to assist the current efforts of the United Nations, the Organisation of African Unity and other bodies and individuals, and specifically to lend support to the organisation of a regional conference under the joint aegis of the UN and the OAU to examine and resolve the deep-rooted causes of the crisis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU remains convinced that such a conference must be convened as soon as possible.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU reiterates that it is prepared to assist with specific measures to promote peace and reconciliation in Burundi, in particular the organisation of a national dialogue, support for action to promote human rights and the restoring of the rule of law. It is furthermore willing to continue funding the presence of OAU observers and United Nations human rights observers in the country. It is also prepared to help with the economic and social recovery of Burundi as soon as political and security conditions allow rehabilitation programmes to be set up in the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Niger: progressive restoration of aid</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 28 June 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union takes note of the fact that the regime in Niger has announced the results of the country's constitutional referendum and has lifted the state of emergency and the ban on political parties.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU takes the view that Niger has thus met the conditions set out by the Council on 13 May 1996 for the progressive restoration of cooperation. In the first instance, this will take the form of: -support for the electoral process; -aid for structural adjustment which, at present, needs to be focused exclusively on the most pressing needs in the social sectors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Council will continue to follow closely the situation in Niger, in particular as regards the preparation and conduct of the presidential and legislative elections.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Arusha summit on Burundi</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 5 July 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Recalling its declaration of 25 June 1996, the European Union congratulates President Mkapa on the organisation of the Arusha regional summit, which has produced constructive proposals on the conflict in Burundi. It expresses appreciation for the untiring efforts of former President Nyerere and reiterates its support for his peace initiative.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU encourages the region's Heads of State and the Organisation of African Unity to commit themselves resolutely to supporting and giving substance to the Arusha recommendations and to contribute to the restoration of security in Burundi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU expects the President and the Prime Minister of Burundi to fulfil the undertakings they gave at the Summit to overcome the crisis in Burundi and, with the help of the countries of the region, to put an end to the violence which is destroying the people of Burundi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU calls on all the political forces of Burundi to seek a political solution and to give a favourable reception to regional initiatives to restore peace to their country. It calls the attention of all the parties to the conflict in Burundi to the fact that it condemns all forms of violence and that it will not recognise a government that has taken power by force of arms. Only peace, a peace consolidated at regional level, can guarantee the security of all and lay the foundations for economic and social development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU is prepared to support the realisation of the Arusha objectives with a view to restoring peace and security in Burundi. It reiterates its readiness to help Burundi in its economic and social recovery when political and security conditions make it possible to begin its rehabilitation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU reiterates the need to convene the Conference on Peace, Security and Stability in the Great Lakes Region under the joint aegis of the United Nations and the OAU.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Burundi: support for the OAU Resolution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 15 July 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Recalling its previous Declarations and Common Position on Burundi and, in particular, the Declarations of 25 June 1996 and 5 July 1996, the European Union warmly welcomes the Resolution on Burundi adopted by the Organisation of African Unity's Assembly of Heads of State and Government in Yaounde on 8 -10 July 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Union particularly welcomes the reaffirmation by the OAU of its support for the Mwanza Peace Talks under the facilitation of former President Nyerere and its encouragement to him to continue with his efforts based on and incorporating the principles of sustainable democracy and security for all the people of Burundi and an all-inclusive negotiation process. The Union reiterates its appreciation of the untiring efforts of former President Nyerere and its support for his peace initiative in this context.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The declaration in the Resolution of the OAU's full support for the outcome of the Arusha Summit of 25 June 1996, especially the acceptance of the request by the Government of Burundi for security assistance in order to complement and reinforce the Mwanza peace talks, as well as creating conducive security conditions for all parties to freely participate in the Mwanza process is also welcomed by the Union.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU reaffirms its willingness to support the realisation of the Arusha objectives with a view to restoring peace and security in Burundi. It remains ready to help Burundi in its economic and social recovery when political and security conditions make it possible to begin its rehabilitation.</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Visits</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The President of Haiti</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The President of the Republic of Haiti, Rene Preval, visited the Commission on 11 June. He met with President Jacques Santer, Commissioner Joao de Deus Pinheiro (responsible for relations with the ACP States) and Commissioner Emma Bonino (responsible for humanitarian aid).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">President Preval thanked the European Union for all the support it had provided both for the restoration of democracy in Haiti and for the country's economic development. He spoke in particular of the discussions that are currently under way with the Bretton Woods institutions aimed at restoring Haiti's economy. The President indicated that an economic recovery programme would need balance of payments support to the tune of $119m during 1996, as well as assistance for a range of economic sectors amounting to a billion dollars over a three-year period.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For his part, Professor Pinheiro expressed satisfaction at being able to welcome the President at a time when the democratic process in Haiti was functioning normally and institutional consolidation was taking place. In a statement to the press, he said it was an appropriate moment 'to evaluate our cooperation and to strengthen it in a way that will contribute to economic and social development' in Haiti. He added that it was essential for the Haitian people to recognise that democracy was worthwhile. Professor Pinheiro also welcomed the normalisation of relations between Haiti and its neighbour, the Dominican Republic.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The President of the Dominican Republic</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The newly-elected President of the Dominican Republic, Leonel Fernandez Reyna, had a working session at the Commission on 15 and 16 July.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This trip to Brussels was the President's first overseas visit in his new capacity, following his election on 30 June. Indeed, he had not yet formally assumed office at the time of his visit. His inauguration was due to take place on 16 August and the President-elect extended an invitation to the Commission to attend the ceremony. Mr Fernandez Reyna's subsequent itinerary included visits to Spain, France and the United States.</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Support for human rights</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Commission has recently approved the financing of the following projects under the budget line 'Human Rights and Democracy in the Developing Countries):</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ACP countries</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea: ECU 120 000 for a project aimed at actively involving members of the National Assembly in the institution's functioning, and in the democratisation process taking place in the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Niger: ECU 72 000 for a human rights training programme in schools in both urban and rural areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nigeria: ECU 118 000 for a human -rights training programme to be run in educational establishments and through itinerant projects in regions lacking education infrastructures. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fiji: ECU 119 000 for a project to support a non-partisan, multi-ethnic civic forum, aimed at contributing to the achievement of a consensus among various social groups.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Non-ACP countries</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nepal: ECU 59 112 to safeguard texts which are essential to the preservation of Tibetan culture. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nepal: ECU 30196 for the archiving of slides and photographs depicting art objects in order to preserve the culture and traditional techniques of Tibet. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Philippines: ECU 61 750 for a mission to identify the areas in which strategies for human rights and democracy could lead to positive and lasting changes. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sri Lanka: ECU 84 314 for a programme of information in the field of promoting equal opportunities and non-discrimination </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Aid for rehabilitation</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Commission has recently decided to finance the following projects in developing countries affected by serious civil disturbances or natural disasters:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Angola: ECU 847 000 for an integrated programme covering the rehabilitation of agriculture and basic infrastructures, training in demining, hygiene and self sustaining development in Kipungo. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Angola: ECU 185 000 for the rehabilitation of basic infrastructures (water, health, education and housing) In the province of Luanda. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Eritrea: ECU 353 947 to support the rehabilitation and development of basic </P>
+<P ALIGN="JUSTIFY">health care services in the south-west of the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Eritrea: ECU 575 197 for the rehabilitation of water supplies and community development in the town of Hagaz. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ethiopia: ECU 515.685 for the rehabilitation of primary care and water supplies in the Warder area. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ethiopia: ECU 455 630 to help the rehabilitation of repatriated people and displaced persons in the Borena area. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ethiopia: ECU 308 475 for the rehabilitation of health care and water supplies in the Hararghe area. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mozambique: ECU 848 000 for a programme of support to upgrade medical infrastructures. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mozambique: ECU 590 000 to consolidate the water sector and rehabilitate livestock infrastructures in Maputo and Gaza provinces. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mozambique: ECU 500 000 for the second phase of a programme to help reestablish and reintegrate displaced people in Milange. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rwanda: ECU 241 259 for a project designed to revitalise livestock producer groups, make available essential veterinary products and support cattle production in the landward prefecture of Kigali. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rwanda: ECU 411 751 to provide professional training in primary health care. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rwanda: ECU 805 475 for an environment rehabilitation project in the prefecture of Kibungo. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rwanda: ECU 437 622 for the rehabilitation of primary schools in the southwest of the country. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rwanda: ECU 94 650 to train laboratory technicians. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Somalia: ECU 626 439 for the rehabilitation of wells and water points in the Nugal region. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zaire: ECU 423 687 for the creation of enterprises involved in making bricks and earth blocks in order to assist in the rehabilitation of rural habitats. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zaire: ECU 1 491 117 for a tree-planting project around the Virungas National Park as part of a rehabilitation programme directed at Rwanda's immediate neighbours.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Haiti: ECU 213 536 for operational and methodological support for rural development projects. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Haiti: ECU 645 120 for technical assistance in the follow-up and evaluation of rehabilitation projects. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Haiti: ECU 551980 for a programme to rehabilitate schools and provide support for the education sector. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">European development fund</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Following, where required, favourable opinions from the EDF Committee, the Commission has decided to provide grants and special loans from the 5th, 6th and 7th EDFs to finance the following operations (grants unless otherwise stated). Major projects and programmes are highlighted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economic and social infrastructure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Malawi: ECU 1.9 million for the rehabilitation and construction of customs facilities. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zambia: ECU 11 million for resurfacing and improvements to the runway at Lusaka international Airport. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fiji ECU 1.8 million for the rebuilding of three bridges.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Trade promotion/ structural adjustment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Member states of SADC (Southern Africa), ECOWAS (West Africa) and ECOCAS (Central Africa): ECU 500 000 for a follow-up pilot project relating to industrial fore in different sectors. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Botswana: ECU 1.9 million for a tourism development programme. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Djibouti: ECU 4.1 million to support the 1996-97 structural adjustment programme. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Netherlands Antilles/Aruba: ECU 5 million for a tourism promotion programme. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agriculture/ rural development</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Madagascar: ECU 1.9 million to support professional organisations in the field of rural credit. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Swaziland: ECU 1.4 million to build a bridge at Maphobeni, to facilitate rural development in this area. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Swaziland: ECU 1.5 million to improve the storage and commercialisation of maize. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Health</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Benin: ECU 700 000 to enhance the security of blood supplies in the Oueme, Mono and Atlantique departments. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Education/training</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Botswana: ECU 15 million for a training programme directed at SMEs, independent operators and the unemployed. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ethiopia: ECU 1.05 million for a programme designed to strengthen training and research capacity in the economic field. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Member states of IGAD (Djibouti, Eritrea, Ethiopia, Kenya, Somalia, Sudan, Uganda): ECU 1.9 million for a training programme for the commercialisation of cereals. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lesotho: ECU 1.3 million for a community reforestation programme in the Lesotho Highlands. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Institutional support</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Djibouti: ECU 250 000 to provide technical support for the computerisation of the National Bank's accounting system. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Niger: ECU 1.8 million to support the electoral process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kenya: ECU 1.7 million for an assistance programme for the National Authorising </P>
+<P ALIGN="JUSTIFY">Officer covering the management of funds allocated by the European Community.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zambia: ECU 1.5 million for the first phase of a tourism development programme. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cariforum countries-Antigua &amp; Barbuda, Barbados, Belize, Bahamas, Dominica, Dominican Republic, Grenada, Guyana, Haiti, Jamaica, St Kitts &amp; Nevis, St Lucia, St Vincent &amp; the Grenadines, Suriname, Trinidad &amp; Tobago): ECU 725 000 in technical assistance for the programming unit of the Cariforum General Secretariat. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Miscellaneous</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All ACPs: ECU 5 million to strengthen fisheries management and biodiversity. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ghana: ECU 1.5 million for a pilot project in the field of decentralised cooperation. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kenya: ECU 12.5 million for a community development programme in the battle against poverty. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Somalia: ECU 47 million for the second rehabilitation programme. The focus will be on productive activities (livestock, agriculture and fisheries), the social sectors (health, water, sanitation systems and education), the private sector (revenue generation, job creation, SMEs), the public sector (training, establishment of institutions), demobilisation, and the integration of former combatants </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zambia: ECU 1.6 million for a programme to combat poverty including, in particular, the provision of credit to micro-enterprises. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zaire: ECU 2 million to support the integration of displaced people in Kasai. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">European investment bank</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">South Africa: A loan of ECU 56 million for Eskom, the public electricity company, for the modemisation of part of its electricity distribution network.</P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Humanitarian aid</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ACP countries</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Angola: ECU 14 million for a global assistance programme covering food and medical aid, the distribution of equipment and demining operations. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chad: ECU 500 000 for the distribution of essential food products and to meet the special nutritional needs of children in the north of the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cote d'lvoire: ECU 340 000 to help combat cholera and yellow fever among refugees from Liberia. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ghana: ECU 140 000 towards the setting up of a camp for 'boat people' arriving from Liberia. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guinea: ECU 160000 for the distribution of food to refugees from Liberia and Sierra Leone. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Senegal: ECU 250 000 towards the fight against cholera, notably in the town of Touba.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sierra Leone: ECU 4.2 million for food and emergency medical aid (to combat cholera) for people displaced by the civil war. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Somalia: ECU 1.5 million for a measles vaccination programme and for medical and food aid for victims of the internal conflict. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Southern Sudan: ECU 13 million to finance ECHO flights, and for food, medical aid and the provision of water supplies, for civilian victims of the conflict, notably in Khartoum and its environs and in the refugee camps in the north of Uganda.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Non - ACP countries</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nicaragua: ECU 1.5 million for medicines, essential provisions, drinking water supply equipment and training actions in the area of epidemic prevention. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Peru: ECU 800 000 for shelters and medical assistance to people in the process of reestablishing their homes having fled from the violence that has occurred over the past ten years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ex-Yugoslavia: ECU 102 million for various emergency operations. The breakdown of this aid, by country, is as follows: Bosnia-Herzegovina-ECU 77.45 million; Croatia-ECU 11.95 million; Serbia-Montenegro-ECU 12,6 million.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Russian Federation: ECU 900 000 for street children in St Petersburg and homeless people in Moscow. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Afghanistan: ECU 7 million for a coordinated aid programme covering public health measures, the provision of drinking water, hygiene and refuse collection. The aid will be directed both at the people of Kabul and at other provinces of the country. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kirghizistan: ECU 3.6 million for the purchase and distribution of food. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tadilkistan: ECU 8.9 million for a food and medical programme. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bangladesh: ECU 300 000 to help victims of the tropical storm that struck in the middle of May. </P>
+<P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Food aid</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Angola: 15 000 tonnes of cereals, 2000 tonnes of oils and 3000 tonnes of beans amounting to a total value of ECU 20.075 million. </P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<!--
+</Section>
+</Section>
+</Section>
+</Section>
+-->
+</BODY>
+</HTML>
Index: /gsdl/stable/collect/demo/import/ec159e/metadata.xml
===================================================================
--- /gsdl/stable/collect/demo/import/ec159e/metadata.xml	(revision 20131)
+++ /gsdl/stable/collect/demo/import/ec159e/metadata.xml	(revision 20131)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE DirectoryMetadata SYSTEM "http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd">
+<DirectoryMetadata>
+    <FileSet>
+        <FileName>.*</FileName>
+        <Description>
+            <Metadata name="dls.Title">The Courier - NÂ°159 - Sept- Oct 1996 Dossier Investing in People Country Reports: Mali ; Western Samoa (ec159e)</Metadata>
+            <Metadata mode="accumulate" name="dls.Language">English</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Society, Culture, Community, Woman, Youth, Population|Social sciences, sociology (works comprising several subgroups) incl. participatory research and training</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Development Periodicals and Magazines|The Courier ACP 1990 - 1996 Africa-Caribbean-Pacific - European Union</Metadata>
+            <Metadata mode="accumulate" name="dls.Organization">EC Courier</Metadata>
+        </Description>
+    </FileSet>
+</DirectoryMetadata>
Index: /gsdl/stable/collect/demo/import/ec160e/ec160e.htm
===================================================================
--- /gsdl/stable/collect/demo/import/ec160e/ec160e.htm	(revision 20131)
+++ /gsdl/stable/collect/demo/import/ec160e/ec160e.htm	(revision 20131)
@@ -0,0 +1,2779 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META NAME="Generator" CONTENT="Microsoft Word 97">
+<TITLE>&lt;&lt;TOC1&gt;&gt; The Courier - N°160 - Nov - Dec 1996 - Dossier Habitat - Country reports: Fiji , Tonga</TITLE>
+</HEAD>
+<BODY>
+
+<B><FONT FACE="Arial" SIZE=2><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">The Courier - N°160 - Nov - Dec 1996 - Dossier Habitat - Country reports: Fiji , Tonga</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Africa - Caribbean - Pacific - European Union </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Country reports</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fiji</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fiji is home to people of a variety of cultures but it would not be accurate to describe this Pacific island country as a 'melting pot'. Politics here are dominated by the difficult relationship between indigenous Fijians and the descendants of indentured Indian labourers brought in to work the sugar cane fields. We look at how this situation affects the economy -  which everyone acknowledges has considerable potential, and examine the prospects for ethnic rapprochement as the nation begins a 'great debase' on the future shape of its Constitution. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Tonga</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tonga appears like a haven of tranquility in a turbulent world. A society which respects hierarchies and is strongly attached to 'traditional values', it is also one of the few remaining places with a hereditary ruler who wields substantial power. But outside influences cannot be ignored altogether and nations everywhere are having to adapt to living in the 'global village'. Our report focuses on the possible consequences of this for the 'Friendly Islands' as the new millenium approaches. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Dossier</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Habitat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The concept of 'habitat' conjures up different things to different people - from the right to a roof over one's head to the way in which we manage the flora and fauna of the planet. In our dossier, we consider the legacy of the United Nations 'Habitat' Conference held in Istanbul earlier this year. We also highlight some of the initiatives being taken to improve the quality of people's living environment. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Acknowledgements</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The Courier: Africa  - Caribbean - Pacific - European union</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Address: Postal address (mail only) 'The ACP-EU Courier' Commission of the European Communities 200, rue de la Loi 1049 Brussels Belgium </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Courier office address (visitors) First floor Astrid Building 1, rue de Geneve Evere- Brussels Belgium</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Publisher Steffen Smidt commission of the European communities 200, rue de la Loi 1049 - Brussels (Belgium) Tel. 00-32-2-299 1111 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Director of Publications</P>
+<P ALIGN="JUSTIFY">Dominique David</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Editor</P>
+<P ALIGN="JUSTIFY">Simon Homer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Assistant editors</P>
+<P ALIGN="JUSTIFY">Augustin Oyowe</P>
+<P ALIGN="JUSTIFY">Jeanne Remacle</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Associate assistant editor</P>
+<P ALIGN="JUSTIFY">Hegel Goutier</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Journalist:</P>
+<P ALIGN="JUSTIFY">Debra Percival</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Production Manager:</P>
+<P ALIGN="JUSTIFY">Dorothy Morrissey</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Secretariat:</P>
+<P ALIGN="JUSTIFY">Carmela Peters</P>
+<P ALIGN="JUSTIFY">Fax: 299-30-02</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Circulation:</P>
+<P ALIGN="JUSTIFY">Margriet Mahy-van der Werf (299-30-1 2)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Meeting point</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Jacques Bugnicourt, Executive Secretary of Enda Tiers Monde</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The main development battle must be fought in the towns and cities</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Founded in 1972, Enda Tiers Monde ('Enda' stands for 'environment and development') is one of the few large international NGOs to be based in a developing country. It has a presence in a number of states in Africa, Latin America and Asia and has been concentrating its efforts on towns and cities, in the belief that this is where deprived populations can be best assisted. Jacques Bugnicourt, who is Enda's Executive Secretary, has some strong views about what needs to be done to tackle the problem of urban deprivation. When we interviewed him at the Enda headquarters in Dakar, Senegal, we began by asking him about the history of the organisation that he heads.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - When we launched Enda, I am not sure that we had any particular goal in mind. You would have to go back to the end of the 1950s, with the war in Indochina, the approaching conflict in Algeria, the independence of countries in Africa and the last-ditch struggles of the colonial powers, notably France. It was in Paris that links were forged between activists from many Third-World countries - in particular, we all took part in the street demonstrations mounted by people from the French colonies. There were some very strong groupings like the Federation of Students from Black Africa, and its equivalents set up by students from the Maghreb, Latin America and Asia. Ten years later, in the 1970s, we could see that the independence experiment was turning sour and the hopes we vested in the actions of determined and brilliant people had come to nothing. The United Nations was becoming increasingly bureaucratic. Some of our friends and colleagues who had government posts had their hands tied, while others were in prison and were equally powerless. In addition, the communists were disappointed at not being able to apply their doctrine to local conditions. Some did, in fact, manage to achieve small-scale results locally when working at the grass-roots, but by and large, their efforts were not successful. I came to Dakar, where I taught in a United Nations institute.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A lot of people had theories. But you cannot take up the battle for the poor without the poor themselves, or for those under the yoke of colonial rule without the participation of the subjugated population. To begin with, you have to appreciate the diversity of the various peoples in developing countries, and be aware of their daily life and struggle. Cesaire wrote that you had to ask questions about the soil, about cities, about men and about the sun. Later, once you have done this, you can act.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We need to dismantle the barriers. There can be no agronomy without economics, and no economics without sociology. If you are talking about jobs in Senegal, you also must talk about jobs in Mali and Guinea - treat Africa as a whole. Another thing is that you have to stand up for yourself and not allow yourself to be manipulated by people from the developed countries. One of the major problems we have noticed is that part of Africa's elite is out of touch with the general population.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These are the underlying reasons for the foundation of Enda. Nowadays, it is a non-profit-making international organisation working with various communities - an 'INGO', if you like, with the 'I' standing for 'international'. We have bases almost everywhere in the Third World, from Ho Chi Minh City to La Paz.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Is each section of Enda independent, then ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Yes. We took the view that there was a danger of becoming too centralised and acting like a small-scale UNICEF or UNESCO, so we decided to guard our independence very carefully. We opted for the widest-ranging autonomy possible. This has its drawbacks of course, but these are far outweighed by the advantages.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You mention drawbacks. Would it be true to say that the original enthusiasm which greeted the creation of Enda has fallen off somewhat ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - That's something we are always concerned about. It is not structures which maintain cohesion, but the sharing of goals and the channelling of our actions towards the common good.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When the various sections get together, we find that we have a great many things in common. But there is no good reason why those of us in Dakar should try to influence the way people work in working-class districts in Santo Domingo, for example, where they are trying to tackle problems like AIDS and unemployment. We simply tell them what we are doing here and vice versa. If you want to serve the people, you have to have a decentralised set-up. It would be wrong to deal with a problem centrally, and to do so would be against our instincts. Most of us have no particular liking for institutions. An institution must be of service in the battle, not the other way round.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· How do you guarantee cohesion in practice ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - It costs a great deal to travel of course, but we do have a lot of joint programmes. For example, the cities programme includes people from Bogota, Santo Domingo, Rabat, Dakar, Ho Chi Minh City and Bombay, all working together. They meet from time to time and, when they do, it is to get down to practical work. Together, their work is, say, three-quarters practical and one quarter reflective. Nevertheless, there is ongoing tension, particularly in the relationship between overall policy and local demands. Another conflict arises between grass-roots action and reflection.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The impression one gets is that you yourself are the 'cement' between the various groups which make up Enda. Could this not be seen as a weakness which may make things difficult in the future ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - That's what other people say, not what I think. I try to make my presence useful and those who come after me will do the same. What really holds us together is our belief in what we are doing. It is not a question of adhering to some kind of 'monolithic' faith. We simply believe that we can be of use, recognising that there are many limitations. Let me give you a practical example. If someone involved in recycling in Bogota were to meet up with someone from a poor district in Dakar who works at the rubbish tip, they would have a great deal in common and would find it useful to compare their problems and consider practical ways of solving them together.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What are your most important activities in Senegal ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - By far the most important is the one covering the city of Dakar. As well as being a focus for the country itself, Dakar is a metropolitan centre for the entire sub-region, with influence over Bamako, Conakry, Bissau and perhaps even Praia in Cape Verde and Nouakchott in Mauritania. What happens here has repercussions in all those cities. I do not want to sound too dramatic, but the decisive factor in our destiny will be the fate of young people and the poor in the major cities. Two-thirds of these people are facing chronic problems. Those under twenty make up more than half the population and their lives are continuing to spiral down into poverty.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Enda should obviously be operating in those areas where it can be of most use. And in the context of towns and cities, we have completely reviewed our strategy. For some years we gave priority to the countryside. For a long time, in fact, we believed that rural development would permit a much improved urbanisation process. There was even the view that people in developed countries would not object to paying a little more for agricultural produce, because they could be certain that the money was going to those who actually grew the cotton, groundnuts, cocoa or whatever.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over the last fifteen years or so, though, we have come round to the view that our actions must be directed principally at towns and cities. We found initially that there were some interesting projects involving small groups - working to improve the position of children or banding together in cooperative savings ventures. It was good, long-term work which gave results. But that is all out of date now. We have to speak in terms of much larger numbers  -  tens of thousands and not tens or hundreds. Otherwise, there is no chance of making a real difference. That is why we have considerably altered our strategy. Three years ago, approximately two thousand children were able to go to holiday camps. Most of these holidays were paid for by companies, but fewer than 10% of the beneficiaries were genuinely poor. Last year, no fewer than 10 000 children were sent away on five days' holiday -  to the coast near Dakar. Enda was involved in this programme working with 200 local cultural and sports associations. The idea was to give the children the chance to splash about in the sea, but also to use African resources to help them become full citizens and learn that our diversity is the source of our wealth. There are at least 100 000 children living in misery and many of them could end up joining the ranks of the street children. If you can give these youngsters five days holiday plus a bit of follow-up, you allow friendships to be built. It offers a brief escape from everyday reality. It may not be paradise, but it is something tangible.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another example is the tontines that have been formed into a federation. We currently have nineteen thousand women participating in these and if you bear the large family sizes in mind - there are perhaps ten people in every family - that represents a lot of people. The women pay into the tontines and the money is used, not just for the security of their immediate family, but also to help young people set themselves up.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Then there is rubbish collection. Enda runs its own scheme but there are also a number of groups that have turned rubbish collection into a profession. The young people collect the rubbish and recycle it. There are about 50 000 people in the biggest district where we are involved in rubbish collection. There are also some young people in that district who are engaged in water recycling and although it only involves supplying about a hundred people at the moment, I believe this scheme will grow. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We also organise schools and are currently involved in making films for schools on the subjects of the environment, hygiene and solidarity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Enda has just opened an 'eco-centre'. If I understand it correctly, this is a showcase to promote a horizontal link between Enda's various activities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - That is right. We want it to be a place of passage, meeting, exhibition, permeation and redistribution. We hope people will feel comfortable there, and that it will be a tool symbolising a new way of working. So the centre offers an experience, but we also want it to be used to promote activity. A variety of events have been organised there simultaneously - recently for example, a meeting of shoe-shiners, a gathering of teachers from a long-standing educational centre, an exhibition for the Biennial Festival of Contemporary African Art, and a local-community meeting about setting up a small production facility. Two days earlier, there was a preliminary holiday-camp meeting where the instructors got together to look at the best available teaching methods designed to make children more aware of the importance of solidarity. We believe that solidarity is essential in tackling problems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So the centre has a multitude of uses, all of which contribute to the vitality of the local economy. You have to understand the crucial importance of the local economy. It responds to all the basic needs of the poorest people, who want to live their lives just like the rest of us.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You talk of depending on the local (what some would call the informal) economy to live - or at least survive. But this sector is not viewed with enthusiasm by the international authorities ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> -  Their policy is based on domination and fear: fear of those who accumulate assets. To see these hordes of people in the developing countries frightens them. It's a bit like the horror of the wealthy classes at the end of the nineteenth century when faced with a working class which dared to aspire to wealth. They will give to charity but are not prepared to make a long-term investment. The lack of support for the local economy stems from the fact that foreign aid is geared, first and foremost, towards major projects or emergency aid. Four or five years ago, the UN conducted a survey in 10 towns and cities in West Africa, but the results were not published because they showed that the average rate of growth of the local economy was 7.5%. So, you see, we are far from just muddling along. Great things could be achieved if only there were a change in attitude. It also requires a change of terminology. How can one justify the use of the word 'informal' and, worse still, treat the work of the poorest people and fraudulent activities under the same heading. Fraud may be formal or informal. Knowing African society as I do, I am aware that fraud is statistically more widespread amongst the prosperous and highly respected. So we must not cast stones at the little man selling socks who has no trading licence because he cannot afford one, or at the woman who sets up a stall at a school entrance without complying with the law which requires a recent certificate stating that she does not have tuberculosis. What is the bottom line here ? Must we respect the law or the people who want to live without being thieves, beggars or prostitutes ? It is unacceptable for force to lie with the law and for the majority to be cast into wretchedness.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Senegal, there used to be fixed prices for milk. The World Bank protested, declaring that this was a restriction on free competition. Now we have to pay much more and many people can no longer afford to give their children-milk every day.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To put it in perspective, Senegal's economy is about the same size as that of the city of Bordeaux. So we must use all the available potential. Highly qualified managers should do their job looking after the high-tech sectors. But, at the same time, we should not be driving out the poor people who are just trying to eke out a living. The informal sector creates services for a very small investment, and people also require services. Economic policy must allow society to walk on two legs, not just one. What that means is that we need a great deal of flexibility, and perhaps a complete review of the law. Contraceptive implants have to be licensed so that there are no more back-street abortions. And it must be possible for girls to attend school even if they do not have a proper birth certificate - why should they be excluded from education for want of a piece of paper. It should be possible to trade with a simple one-day ticket which people should be able to buy in post offices or cinemas. What would be wrong with that? And we should have a moratorium on a number of regulations. We need to wage war on the destitution that we are suffering and that means taking decisive measure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">ACP</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Joint Assembly begins discussions on future ACP-EU relations</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although the agenda was, as usual, heavily laden with a variety of long-standing issues ranging from regional cooperation, fisheries, the cocoa content of chocolate and bananas to the situation in several ACP states (in particular Rwanda and Burundi), the future of ACP-EU relations was at the forefront of discussions at the ACP-EU Joint Assembly, which was held in Luxembourg from 23-26 September 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Opened in the presence of the Grand Duke and Grand Duchess of Luxembourg, the Assembly's general attitude was not one of speculation as to whether or not the European Union would abandon the ACP states when the Lom&eacute; IV Convention expires in the year 2000 - a feeling that was rife shortly after the signing of the revised version in Mauritius in November 1995. Instead, it was one of positive thinking and of exploring the kind of agreement that would succeed it. 'There is no question of the European Union getting out of a relationship which took decades to build', Luxembourg's Prime Minister Jean-Claude Junker, told participants in his welcoming address.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As pessimism gives way to guarded optimism, ACP-EU parliamentarians have taken an important initiative, even before the Commission's Green Paper is published, in what is bound to be a long and passionate debate. A special summit of ACP Heads of State is planned for Gabon later in 1997 to discuss the issue.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Options for the future</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A general report, introduced by Mr Firmin Jean-Louis (Haiti), provided the main platform for the Joint Assembly's deliberation. Although presented too late for representatives to have the opportunity to examine it in detail, the exchange of views on the floor was wide-ranging and reflected the report's content to a considerable degree.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The report encapsulates all the ideas that have emerged so far in various fore. It analyses framework options for future ACP-EU relations  -  bilateral, regional and multilateral - and raises pertinent questions and concerns. Noting that international cooperation is increasingly dictated by economic and security considerations, and that North-South solidarity is, as a result, being pushed to the background, it regrets the fact that certain EU member states appear to indicate a preference for bilateral over multilateral cooperation. The author of the report warns that this trend would not only diminish the credibility of the Union but also its international influence.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Any instrument of cooperation, the report says, should take into account the different levels of development among ACP states as well as the regional vocation of many others. Its objective must be poverty eradication, sustainable economic and social development, and the harmonious integration of the ACP states into the global economy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It recognises the need to secure the support of European public opinion which is largely unconvinced that EU aid to ACP states has been effective over the past 20 years. Not enough publicity; it says, has been given to its positive aspects. The report goes on to warn that solidarity and development are at stake and that the debate on the future of ACP-EU relations should not be left to politicians and technocrats. It should also involve wider civil society.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the Joint Assembly debate, the commitment of EU political leaders to the development of the ACP states was often called into question. Francis Wurtz (EUL-F) summed it up when he said there were worrying signs that the EU intends to downgrade its relationship with the ACP states - signs which go back to the negotiations on the Lom&eacute; IV second financial protocol, when several countries refused to increase their contributions to the 8th EDF. The EU draft budget for 1997, which he said revealed a substantial reduction in the funds allocated to the developing countries outside the Mediterranean region, provided further evidence of this. 'We must be vigilant,' he told his colleagues, 'and must not allow the Lom&eacute; Convention to be revised downwards.' Mr Wurtz agreed that greater efforts were needed to create awareness and mobilise European opinion in favour of development. The European public should know that EU development policy was not based on charity but on self-interest. 'Without Africa developing, Europe has little chance of maintaining growth in the long run.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lord Plumb (EPP-UK), the European Co-President of the Joint Assembly, admitted that it would not be easy to influence European public opinion. 'One of the roles of the Joint Assemby,' he said, however, 'must be to ensure that the peoples of Europe have confidence in the progress being made by the countries of the South. We must all help in this task of confidence-building.' </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Glenys Kinnock (PES-UK) urged that there should be as much participation as possible in the ongoing dialogue over future ACP-EU relations in order to bridge what she saw as 'the gap between rhetoric and reality.' Equity, she argued, should be the main objective.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ACP Co-President, Sir John Kaputin (Papua New Guinea), said there was no doubt that the EU was forging closer ties with the former Eastern bloc countries at the expense of the ACPs. He pointed out, however, that the Lom&eacute; Convention had always encouraged a 'forward-looking' approach and argued that whatever succeeded the current ACP-EU relationship should be 'the most important' agreement ever.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The representative from Barbados, Dr Richard Cheltenham, was of the opinion that whatever the outcome of the discussions, efforts were needed to avoid 'chaos'. There should, for example, be no immediate abandonment of the trade preferences that ACP states had acquired. Transformation must be gradual to enable them to adjust and restructure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">European Commissioner, Professor Pinheiro, chose, first of all, to underline the importance of the role of 'the state and civil society' in development. He indicated that he saw this as growing more and more in importance. This was reflected in the agreement signed in Mauritius -  an agreement which seeks to encourage the consolidation of democracy, the rule of law, good governance and transparency, and which emphasises decentralised cooperation and the role of the private sector. the Commissioner spoke about the current programming exercise, reminding the Assembly that resources were being allocated in two tranches in accordance with the provisions of the revised Convention, to take account of each ACP state's development strategy and the objectives and priorities of the Community's development policy. He revealed that only 16 ACP countries and two EU Member States had ratified the revised Convention and urged those that have not done so to accelerate the process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He welcomed the Joint Assembly's initiative in debating future ACP-EU relations. The Commission's Green Paper, he told representatives, will be published in November. He was, therefore, not in a position to enter into detailed discussions with members on the subject at this stage. He stressed, nonetheless, that the document 'will not be a blueprint for future EU strategy towards the ACP countries. It will be a discussion paper.' there were a number of key questions that needed to be addressed regarding strategy, the scope of future relations and the use of the traditional instruments of aid and trade. 'This is not to say that we should start afresh', he argued. 'We should build on what has been achieved so far, and adapt where necessary.' Professor Pinheiro was certain that whatever the outcome of the discussions, there were a number of 'unchallengeable principles' on which ACP-EU relations should continue to be based. These were: partnership, ownership by ACP countries of their development policies, security in terms of EU support and predictability of relations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">New areas of concern</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This session of the Joint Assembly saw the emergence of two new areas of concern: urban development, and the effects of climate change on small island states. An initial report on the former was presented by the rapporteur, Daby Diagne (Senegal). It did not give rise to much debate. The report emphasises the pivotal role towns play in economic development and urges the Community to adopt an integrated policy on urban development (See our interview with Mr Daigne in the Dossier). The latter was the subject of a full morning hearing, involving a panel of ACP-EU experts who are closely involved with the problem. They warned of the threat posed by global warming to the survival, and even existence, of many islands in the Caribbean and the Pacific. The emission of greenhouse gases, the Assembly was told, has reached levels never before experienced (see the article which follows). Representatives agreed on the need to integrate climate change considerations into sustainable development strategies. A Working Group on the issue was set up with Karin Junker (PES-G) as general rapporteur.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cocoa and babanas</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There was no avoiding the intractable problems of cocoa and bananas. On cocoa, opinions were divided as usual. There were those who felt that the Commission's proposed new directive allowing chocolate to contain vegetable oils (up to 5% of total volume) in place of cocoa butter, was reasonable. The proposal also involves a labelling system to ensure that the exact contents of the product are clearly indicated Advocates of this strategy argued that it would not only widen consumer choice but would also promote the export of shea-butter and other vegetable oils which a number of ACP countries produce. Opponents were worried that if implemented, the directive could lead to a big fall in cocoa exports and a commensurate loss of earnings for ACP cocoa producers. Magda Aelvoet (Greens-B) argued in favour of maintaining the status quo, saying that this was preferable to what was being put forward in the draft directive. She warned that the Commission propose' would almost certainly result in everyone (cocoa producers, shea-butter producers and consumers) losing out. There was no guarantee that menu facturers would choose shea-butter given that they would be free to use whatever vegetable oils they liked She was certain they would go for the cheapest substitute or even for synthetic products. Accordingly, Mrs Aelvoet proposed a 'freeze' on all proposals. This view was reflected in the resolution passed by the Assembly, which called on the Council to reject the proposed directive. It also requested the sever member countries which currently authorise the use of vegetable oil to comply gradually with the existing directive  -  which bans their use altogether.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The banana issue proved even thornier. There is a dispute at the World Trade Organisation, where the Lom&eacute; Protocol is being challenged by the United States and Latin American banana producers. Mrs Kinnock expressed anger at the fact that the arbitration panel set up by the WTO is made UP of three countries known to advocate free trade. The panel, she said, is chaired by Hong Kong - which the Organisation told her was representing the 'developing countries!' The general feeling among representatives was that the odds were stacked against the European Union and the ACPs. The Assembly passed a resolution asking the Union to stand firm in defence of the banana regime.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Democracy, human rights, peace and security</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Twenty-seven questions were addressed to the Council of Ministers and a further 28 to the Commission. More than a third of these dealt with issues relating to emergency relief operations, democracy, human rights, peace and security  -  recurring themes throughout the four-day meeting. The emphasis, in this context, was on Burundi, Rwanda, Liberia and Nigeria, all of which were considered individually under the agenda item 'the situation in ACP states'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition to the detailed answers given by Commissioner Pinheiro to questions on Burundi and Rwanda, the Assembly had a long session with Aldo Ajello, the EU's Special Representative to the Great Lakes. The discussion focused on efforts to restore democracy and legitimate government in Burundi, national reconciliation, and the repatriation of refugees from neighbouring countries to both Burundi and Rwanda. Mr Ajello gave members a comprehensive picture of the complex political and humanitarian situation in the region. He spoke of the sanctions imposed on Burundi by neighbouring countries and the efforts of the former Tanzania President, Julius Nyerere, to bring about dialogue and a just political settlement in Burundi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nigeria was again in the dock. Its representative, Dada Olisa, acting Charge d'affaires at the Embassy in Brussels, gave an account of what he considered was the progress made by the Abacha regime on human rights and democracy since the Joint Assembly met in Windhoek last March. He mentioned the repeal of the decree under which Ken Saro-Wiwa and other minority activists were executed, the release of detainees and the transitional programme for a return to democracy by 1998. He pleaded for the Assembly's understanding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">His explanation cut no ice with any of the seven political groupings in the European Parliament, who came together to present a compromise draft resolution on Nigeria. They wish to see all political prisoners released immediately, and the restoration of civil and political rights, as well as a democratically elected civilian government, by the end of 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The resolution on Nigeria was again passed by secret ballot - the very last act of the session. It calls, among other things, for a total arms embargo (preventing the trade in future but also covering existing supply agreements) and for the financial assets of the Nigerian government and of members of the country's ruling councils (and of their families), to be frozen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The resolution does not differ very much from the previous one. Mrs Junker, Johanna Maij-Weggen (EPP-NL) and Mrs Kinnock all expressed disappointment that the EU Council had failed to implement this fully. However, by repeating the demand for sanctions, they said, the Assembly was sending a very strong message to the Council that it was determined to see Nigeria return to democracy as quickly as possible. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Alarm bells sound on small island states</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Climate change</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A morning session of the ACP-EU Joint Assembly was devoted to a public hearing on the effects of climate change on small island states. It was appropriate that the issue should be brought to the attention of the Assembly by Maartje van Putten (PESNL). Representing a country much of which lies below sea-level. she is familiar with the devastating effects of sea flooding. At the hearing, which was very well attended, a panel of invited ACP-EU experts was on hand to enlighten the audience on the extent of the problem.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although global warning has been on the international agenda for more than 10 years, the seriousness of the threat it poses to the survival of small island states is only now beginning to be taken seriously - and it might already be too late, if some of the most apocalyptic scientific predictions are to be believed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is now growing evidence that global warming is taking place. In recent years, we have experienced more extreme weather conditions - heatwaves, floods and increasingly destructive tropical storms - while there are signs that icecaps are melting and sea levels rising. The increasing incidence of malaria in Africa has been linked to these changes. And it is all happening because of the influence our style of living is having on the planet - in particular the huge emissions of greenhouse gases such as carbon dioxide and methane, from our factories, vehicles and so on.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">That the public hearing attracted a large audience was not only a reflection of the interest the problem is now commanding. It also symbolised the mounting international pressure for reductions in CO2 levels in the atmosphere, and for the adoption of more realistic strategies of sustainable development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The panel of experts comprised Dr Leonard Nurse, Manager of the Coastal Conservation Project in Barbados, Donald Stewart, Acting Director of the South Pacific Regional Environmental Programme (SPREP), Dr Robert Watson, Senior Scientific Adviser at the Environment Department of the World Bank and Chairman of the second Working Group of the Intergovernmental Panel on Climate Change (IPCC), and Neroni Slade, Vice-Chairman of the Association of Small Island States (AOSIS) and AOSIS Coordinator on Climate Change. A separate workshop on climate change was also organised on the same afternoon outside the formal Joint Assembly setting.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">According to Dr Nurse, current estimates based on most reliable models, suggest sea level is rising at the rate of 5mm a year (the 'range of uncertainty' is between 2mm and 9mm). This is two to five times the rate experienced in the last 100 years. This rise is expected to continue beyond the year 2100 even if greenhouse gases are stabilised. The implications for small island states, particularly the low-lying ones, would be severe. 'Atolls such as Tokelau, Marshall Islands, Tuvalu and the Maldives could possibly disappear', he said. 'Major population displacement would be experienced in Micronesia, Palau, Nauru, French Polynesia, the Cook Islands and Tonga.' Meanwhile, small islands with extensive coastal plains and limited upland areas such as Barbados, the Bahamas and Antigua, 'would be highly vulnerable to social and economic disruptions', as major cities, ports and tourist facilities, industries, freshwater sources, fertile agricultural lands and even coral reefs are destroyed by typhoons and cyclones, or washed away in floods. 'Given the limitations of climate models,' Dr Nurse said, 'it is not possible to state with certainty at this stage whether there will be a change in the behaviour of tropical storms and hurricanes. However, it is highly probable that an increase in the frequency and intensity of these phenomena could occur in a 'warmer world'. One study, he claims, predicts tropical storms would have a potential destructive force at least twice what they have today.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dr Watson, similarly, struck a pessimistic note when he said that the potential for irreversible damage was great. He agreed with Dr Nurse that even if we took measures now to reduce CO2 emissions, stabilisation of the situation will take centuries. He pleaded for climate change to be taken into consideration 'in our everyday decisions.' Governments must not wait for cause and effect to be established before taking action. 'It is,' he said, 'economically feasible to reduce CO2' by introducing appropriate policy measures: looking at supply of and demand for energy, resorting to new and renewable energy sources, nuclear power, etc. and ensuring more efficient land management.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The question of 'burden-sharing' in the reduction of emissions between the industrialised world and the developing countries was debated at length. It was noted, for example, that small islands states are responsible for a very small proportion of the emissions, yet they bear the brunt of the consequences. There was a general consensus that burden-sharing should be based on equity and justice.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It should be noted that the Alliance of Small Island States (which was formed during the Second World Climate Conference in 1990) has called on the industrialised world to achieve a 20% reduction in their greenhouse gas emissions by the year 2005 (The 'Toronto objective'). This, it hopes, would bring CO2 in the atmosphere down to 1990 levels. Whether this is realistic is debatable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, a number of strategy options are being closely examined by the European Commision and the Council with a view to adopting Community-wide measures to reduce emissions significantly by 2005-2010. Member States have made phasing-out proposals with targets of 5-10% by 2005, 15-20% by 2020 and 50% by 2030. This works out at an average reduction of 196 2% annually from the year 2000.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Several parliamentarians wanted to know what the Commission, in particular, had done and will do to help small ACP island states overcome the effects of climate change. It was soon discovered during the discussion that a number of African countries were equally concerned. A Commission representative referred the Assembly to the provisions in the Convention which covered global warming and the special problems of island states. Although there is no specific reference to climate change, the Commission had dealt and would continue to deal with the issue in the broader context of its environmental action. Studies, projects and programmes are being implemented in the Caribbean and Indian Ocean in particular. Furthermore, DG VIII has drawn up internal briefing papers aimed at making departments aware of the issues of climate change and the environment. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Country reports</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Fiji</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Political stability is the key to economic success</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In most of the ACP states featured in our Country Reports, the vital issues are usually economic and social ones. How is a nation with a poor natural resource base to achieve lasting development ? What can be done to improve the skills of the people? How can a vibrant private sector be created ? Can better health care be delivered and how should it be paid for? Some of these questions might well be valid for Fiji but the visiting journalist soon discovers that they are all secondary issues. For this is a country whose political system itself dominates the agenda. The fundamental issue here is the relationship between the indigenous people of Fiji and the descendants of indentured Indian labourers brought in by the British between 1879 and 1916 to work in the sugar cane fields.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fiji, in fact, is home to people of a variety of cultures. On the indigenous side, the majority are Melanesians but there are also some Polynesians (living on the island of Rotuma). The country even plays host to Banabans, from Kiribati, who were displaced from their homes on Ocean Island to make way for the phosphate diggers. They hold a freehold to the island of Rabi and enjoy a special self-governing status. And while the Indians form the bulk of the non-indigenous population, there are also small Chinese and European communities as well as a number of inhabitants of mixed race.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite this diversity, it would be inappropriate to describe Fiji as a melting pot. Ever since the rapid expansion of the Indian population, official policy has tended to accentuate the divisions. In the early days, it was the British who were responsible for this, although one has to be careful to avoid value judgments. The colonial administrators, it seems, were aware of the tensions that would arise by bringing in large numbers of people of a different culture, language and religion. Their eventual response was to provide guarantees for the local population, notably as regards land rights. The effect was to preserve the traditional land tenure system which was based on villages and families. At the time, it seemed a logical thing to do, but several generations on, the country now has a settled population of Indian origin (43% of the total) who have limited opportunities to own land - even though many of them work on it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As the economy has developed, each of the two main communities has found itself 'specialising' in different fields. For example, cane farmers and retailers tend to be of Indian origin while the public service has traditionally attracted more native Fijians. Significantly, the army is almost exclusively filled by indigenous people - a crucial factor in the 1987 military coup.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the political front, as Fiji moved towards independence, the idea of providing separate representation for each ethnic group also took hold. The independence constitution of 1970 reflected this with the two main communities being given parity (22 seats each) in the House of Representatives.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Shattered illusion</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although there was no real assimilation between 1970 and 1987, Fiji was seen by many as a model of a successful multiracial society. It was only when the country got its first Indian-dominated administration (sustained in power by a smaller native Fijian party) that this illusion was shattered. There was a military coup led by Lieutenant-Colonel Sitiveni Rabuka, who is now the elected Prime Minister,. Shortly thereafter, Fiji became a republic (Queen Elizabeth was formerly Head of State) and in 1990, a new Constitution was adopted giving political primacy to the indigenous Fijians. Needless to say, it was a time of greatly heightened communal tension.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 1987 coup and the events that followed have been well covered elsewhere (including our previous Country Report which was published in 1991). It suffices to say here that while the last few years have been a lot less turbulent, tensions remain. In 1997, the country must adopt a new set of constitutional proposals and a big debate is currently under way about the shape of the system of government for the 21st century. This subject is covered in a later article and also features prominently in our interviews with the Prime Minister and Opposition Leader.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The main focus of this article is therefore on economic and social aspects although, as one soon discovers, this frequently leads us back to the ethnic question. This is particularly the case when one considers the overall economic performance of the country. Fiji is not poor by developing nation standards and it has enjoyed modest growth during 1995 and 1996, but there is a widespread view that it could be doing a great deal better were it not for the political uncertainties. The problem is summed up by the Economic Intelligence Unit in its Fiji Country Report for the first quarter of 1996: 'Political instability will continue to deter investment, other than that on highly favourable tax terms.' In other words, Fiji is paying a high economic price for its internal difficulties.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">General unease about the future and, in particular, the outcome of the constitutional review process is compounded by specific concerns over land tenure. The long-term leases granted to (mainly Indian) farmers are approaching their end and the government must soon decide what it should do next. Will any of the sugar cane farmers be evicted and if so, how many ? What alternative arrangements will be made for them? These questions remained to be answered when The Courier visited Fiji in July although, as our keynote interviews show, the subject was clearly exercising the minds of the politicians.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A long-term strategy for agriculture?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The way in which the land question is dealt with will have a crucial impact on the sugar industry - still the country's most important product in terms of its contribution to GDP and the jobs that it generates (see the article entitled 'Sugar definitely has a future'). With other uncertainties facing this sector - in particular, the process of global liberalisation - there is a growing recognition of the need for a long-term strategy. The government has a two-pronged approach  -  improving efficiency within the sector and diversifying into other agricultural products. To learn more about this, we spoke to Luke Ratuvuki, who is the Permanent Secretary for Agriculture, Fisheries and Forests.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mr Ratuvuki began by stressing the scope for increasing the sugar yield per hectare by as much as 75% (and by even more with irrigation). If productivity could be boosted on this scale, Fiji sugar would be in a much better position to compete in open world markets. He admitted, however, that the country would still face a struggle in maintaining market share and, looking ahead ten years, foresaw a slimmed down industry providing high quality sugar with more of a focus on niche markets. This inevitably meant looking at other agricultural products as possible long-term substitutes. The coconut (or as the Permanent Secretary dubbed it, 'the tree of life') is traditionally grown here and seems poised to enjoy a new lease of life following a period of decline. Fiji has also picked up the taro trade at the expense of Western Samoa, which is affected by taro blight, while there are significant exports of ginger to Australia, New Zealand, Canada and Europe. Mr Ratuvuki spoke enthusiastically about branching out into other areas such as pawpaws, mangoes, bananas and aubergines.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fiji has potential for growth in a range of non-agricultural sectors, but farming is sure to play a vital part in the economy for many years to come. Currently, sugar represents almost three quarters of all crops by value (excluding subsistence growing) and the Fijians are only too aware that this makes the country particularly vulnerable to external shocks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The other primary sectors are all present in Fiji, albeit on a more modest scale. There is some deep-sea fishing backed by Asian investors. This provides useful employment although perhaps not the best possible financial return to the country. As one would expect in a nation of three hundred islands, there is also extensive artisanal and subsistence fishing in the inshore areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The forestry sector divides into two parts: artificial softwood plantations which are said to be managed sustainably and the naturally growing hardwoods. As regards the latter, the EU is helping with a mapping project. Although Asian loggers do not operate in Fiji, there is considerable land clearance taking place, leading to problems of erosion and silting.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Prospects for mining</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gold is the main mineral being exploited with important deposits around Vatukoula. The sector has had its ups and downs but the Emperor Gold Mining Company has now embarked on an expansion project aimed at raising production from the current level of about 4000 kilos per annum to 6000 kilos by the year 2000. A huge copper and gold mine is also planned for Namosi, some 35 km from Suva. Other minerals discovered but not exploited include bauxite, iron, lead, zinc, phosphates and marble. Mining currently makes a modest contribution to overall GDP but represents an important component in the export earnings figures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With one key exception, manufacturing is on a fairly small scale with an emphasis on staple items (butter, beer, soft drinks, paint, soap etc.) for the local market. The exception is the garment industry which provides some 20% of the country's export income and a considerable amount of employment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The investments in garment manufacturing and mining have been important in jobs terms and in improving the trade figures, but there are those who criticise the fact that the government appears to derive little revenue from the operations. The exact fiscal benefits are not easy to determine, prompting some observers to suggest that official secrecy should be eased (see the article on the Constitutional Review later in this Country Report).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the service sector, long-term growth is foreseen in the key area of tourism. The number of holidaymakers choosing Fiji dipped sharply at the time of the coup, illustrating the importance of political stability in attracting visitors. Tourist arrivals bounced back once Fiji's internal difficulties had receded from the international headlines. The politicians must be hoping that nothing will occur during the current period of constitutional discussion and negotiation to put Fiji back on the front pages. It is worth mentioning here that Fiji's national carrier, Air Pacific, is an example of a relatively rare bird - an airline that makes money ! According to journalist Avin Rahish, writing in the July 1996 issue of The Review (the news and business magazine of Fiji): 'It is one of the few government investments that is profitable on its own.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If tourism is a success story, there is something of a shadow over the financial services sector, which is more extensive here than in most developing countries. The reason is the collapse last year of the National Bank of Fiji with losses of US$ 142m (equivalent to 10% of the annual GDP). The authorities were accused of a failure in supervision and the taxpayers have had to pick up some of the bill. More serious, however, is the undermining of confidence in the system and it will take time for this to be restored.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Social challenges</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">As a middle-income country, Fiji has relatively favourable social indicators in the areas of health and education. Medical facilities are provided by the government but it is said that the public health system is not as good as it once was. This is attributed, among other things, to the emigration of highly qualified staff in the aftermath of the events of 1987. Nonetheless, the country does have 27 hospitals and one doctor for approximately every 1900 people. At 72 years, life expectancy is high compared to the ACP average.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The education sector is well-developed with more than 800 primary and secondary schools (for a population of less than 800 000) and 41 technical or vocational institutions. As a result, primary school enrolment is close to 100% while the 1986 census revealed that 60% of 15-year olds were still in education. On the other hand, there are concerns over the proportion of teachers lacking qualifications, notably in the primary school system. In practice, there is considerable racial segregation at both primary and secondary levels, although there is no official policy to this effect.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Educationally, the jewel in the crown is almost certainly the University of the South Pacific whose main campus is in Suva. This regional institution, which has departments in a number of other countries of the South Pacific, draws students from various island nations. Dr Vijay Naidu, who is the USP's Pro-Vice Chancellor, outlined some of the special features of this unique university which has to cater for a highly dispersed population. Like traditional tertiary institutions, it provides a wide range of degree programmes on campus, catering for 3500 students. It has a further 9000 who are being educated using the 'distance mode'. Distance learning is organised through centres in each of the participating countries. Students can attend these centres from time to time but much of their work is done through radio and telephone linkages and, increasingly nowadays, by e-mail and satellite communications. The University, Dr Naidu stressed, also provides continuing education at non-degree level 'in everything from computing to basket-weaving'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Like the health sector, the USP suffered a loss of highly qualified staff after 1987  -  and not just among employees of Indian origin. As the Pro-Vice Chancellor pointed out, the coup created 'a new sense of insecurity' all round and teachers who decided to emigrate were quickly accepted in Australia and New Zealand. The loss has been particularly serious in the scientific disciplines.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">90% of the USP's recurrent expenditure is covered by member government contributions with the remainder coming from Australia and New Zealand. For capital investments, there is heavy reliance on external donors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In both of Fiji's main ethnic communities, a strong commitment to the family ensures that there is relatively little absolute poverty although things may be changing as the country become more urbanised. It is rare to see beggars in the streets in the South Pacific but Suva, sadly, has a number of these.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The overall picture is of a country with very considerable potential in both human and natural resource terms which needs to overcome a number of challenges to secure a more prosperous future. Some of these challenges - adapting to the world of free markets, tackling bureaucratic impediments, bringing development to rural villages, improving the infrastructure, and so on - are familiar to all developing countries. The single most important constraint, however, is the big ethnic divide, and the political uncertainty which flows from this. And this is something which can only be solved by the people of Fiji themselves. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Interview with Prime Minister Sitiveni Rabuka</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'The last ten years have been very educational for me'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is almost ten years since Sitiveni Rabuka led the military coup which toppled the newly-electerl coalition government The stormy events of 1987 are long gast end Fiji has returned to more peaceful ways, but the country is arguably not yet at peace with itself. Major-General Rabuka is now the erected Prime Minister, having led the SVT to victory at the polls in 1992 and 1994. But the gulf between the native Fijians end citizens of Indian descent remains -  indeed, it is institutionalised in a political system which ensures a parliamentary majority for the former. A constitutional review is currently under way end a new text must tee adopted by July 1997. For both sides, the stakes are high. In this interview, Prime Minister Rabuka speaks frankly about the crucial issues facing Fiji as the nation gears up for the great constitutional debate.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fiji also faces some formidable economic challenges and we began by asking the Prime Minister about these.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The main challenge is the one that everybody faces: achieving an acceptable rate of growth to ensure job creation and address the unemployment problem. We also want to improve the standard of living of the people, to upgrade our infrastructure, and to develop both the urban and rural areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What sectors do you see as offering the best hope for future growth ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> -  We are looking particularly at tourism and the agro-based industries. In the international sphere, we are aiming to boost trade, particularly with our traditional trading partners, Australia and New Zealand, and with new partners that we are trying to cultivate in Asia.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We are very grateful for the Lom&eacute; Convention and the various arrangements associated with it - particularly as regards access to the EU market for our sugar products. Although it would be desirable for us not to have to rely on preferential pricing for sugar, for the moment, there is no alternative. And while we are looking for alternatives and seeking to diversify our economy, we will need that system to remain in place. We would like to continue the dialogue to ensure that this happens. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the area of trade, as I say, our focus is on Australia and New Zealand, and the regional trade agreement that the Pacific island territories have with them. This agreement is currently under review. One important aspect is the clause governing the rules of origin. If we can convince Australia and New Zealand to reduce the local input requirement from 50% to 35%, then we won't need any aid from them. The effect will be to secure existing jobs and, indeed, to increase employment, particularly in the garment industry. At the moment, most of the textiles we import for further processing come from Australia. Because of the market we have to sell to, it is very good quality material. This means the costs are high, in comparison with the local input needed to turn it into finished products, and this makes it difficult for us to get up to the required 50%.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If we don't get that reduction, things could go in the opposite direction. Manufacturers might relocate and we could be facing jobs losses. You have to remember that we are competing with Asian producers who have very low wage costs. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Is this proposal for a reduction in the local input requirement on the agenda with the Australians and New Zealanders ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The review actually excludes the clause on the rules of origin. Having said this, we have effectively raised the calculation of our local input in negotiations on a series of other points. On paper, the 50% figure is unchanged but in fact, there has been a reduction of about 5%, thus giving us a little margin.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· On the sugar issue you said you were hopeful that some form of preferential access to the EU market would be maintained. Isn't there a concern that this may not last beyond the year 2000, particularly given the increasingly liberal world trading system ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Yes, and we are looking at that. We should be gearing ourselves up for what happens at the end of the current Lom&eacute; agreement. It remains to be seen whether, with the WTO and the new trends, the curtain will suddenly be brought down on 1 January 2000, or whether there will be a grace period in which we are given time to consolidate our diversification.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The other big issue in the sugar sector concerns the impending expiry of the land leases.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - That is a local issue and a very important one. It has high priority on our government agenda. We are currently talking to the landowners and lessees, explaining what will happen. The legislation (the Agricultural Landlord and Tenant Act) makes no provision for further extensions to the leases, which are now nearing their end. Do we need a new act or should we amend the present law to allow extensions beyond the 50 years originally allowed for ? And if we are to do that, what happens to the compensation provisions? At the moment, these are viewed in a rather one-sided way. The emphasis is on the situation where the landlord compensates the tenant for improvements made to the land. But the rules also provide for compensation in the other direction where the value has been reduced. This may be due to constant cultivation over 50 years. What if the owner wants to return the land to its original use, planting taro, yams or cassava, as his father may have done fifty years ago, and finds he can no longer do so ? There has to be a balancing act here.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hopefully, most of the land will be leased again under a new agreement or under an amendment to the existing law - because we will need to continue sugar production. It is also worth noting that some sugar farmers are beginning to diversify into other crops, both subsistence and commercial.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What arrangements do you envisage for those farmers who do not have their leases renewed ? Will they be relocated ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Right now, we are looking at the use of state land. There are two basic categories here - what used to be known as 'Crown Land under Schedule A' and 'Crown Land under Schedule B'. Schedule A covers the land not claimed by anybody during the Commission that was set up to determine the ownership of land in the very early colonial years. Schedule B is land that belonged to a community or landholding unit that has since died out: in other words, where there is no surviving member of the land-owning unit. So we have those parcels of land available. My party's policy is to restore land to the traditional owners where possible, but in those cases where you cannot identify the original owners, there will be land available for resettlement - although resettlement is perhaps not a very good term to use. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· It is somewhat emotive.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - It implies taking a person, family or community from somewhere and planting them somewhere else -  and I hope we can avoid that. On the other hand, if you look at what people are doing nowadays, everybody's relocating. People are always resettling, moving away from home and setting up elsewhere. In this case it is perhaps a necessity, in the sense that the legislation has caught up with us. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Can I turn now to the sensitive issue of the constitution. This is another area where decision day is looming. You currently have a constitutional review under way with the Commission's report due out soon. What do you think will emerge from this process over the next 12-18 months ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I don't feel that the constitutional issue is a sensitive one and do not think anyone should feel restrained in asking questions about it. It reflects the reality of the situation in Fiji. There is a requirement that the 1990 Constitution be reviewed and we have a Review Commission chaired by Sir Paul Reeves. He is a very capable man who is a former Governor-General of New Zealand and a very eminent constitutional lawyer. Assisting him, we have two party nominees - one from the main Fijian party and one nominated jointly by the Indian parties in Parliament. I have total confidence in that Commission. I believe they will come up with very objective observations and recommendations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Let me explain the timetable to you. The report is expected by the end of August. It will be presented first to the President and then to me for submission to Cabinet. I envisage it being tabled in Parliament towards the end of September. We cannot debate it until three months have elapsed from the date it was tabled - which takes us to the end of the year. A lot of work will be needed during the first half of 1997. The Joint Parliamentary Select Committee, made up of members of both the upper and lower houses, will have to work on the report and try and build consensus on the various issues.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Given that the house is racially divided, and the possibility that a premature discussion on the floor of the house may raise the temperature, I would prefer not to have a full parliamentary sitting in the early part of next year. Instead, we should go into committee and deal with it there. And then when we are satisfied that the issues can be brought out into the open, we will debate them fully in Parliament. As soon as we start talking next year, the legislative craftsmen should begin their work. On the basis of this programme, I believe we can meet the deadline to the day, promulgating a new Constitution which has been accepted by both houses on 25 July 1997. So I am very hopeful.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Without prejudging the final outcome, do you envisage a move away from strict communal separation ? I am thinking here, in particular, of the separate voting lists ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I think there may be provision for some cross-communal voting. There was something like this in the 1970 Constitution which had both communal and national rolls.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What about the longer term. Do you foresee a political system developing in Fiji where ethnic origin is irrelevant -  perhaps a 'right-left' divide, if that is still a meaningful concept ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I am not bold enough to say that that will happen. I have seen the darkest side of Fijian nationalism. I have seen the fear that was in the Indian population in 1987. But if we move too quickly to remove the racial safeguards that are in the Constitution, we may run the risk of prolonging the bad relationship between the races that we now have. So I would say we should proceed very cautiously and let the natural healing process take its course. We also need to look beyond the Constitution at aspects such as our education system and enhancing the ability of the Fijians to compete.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· I believe the education system is also very divided.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Some schools are reserved for Fijians although, slowly, there are Indians from families close to the schools who are beginning to enter them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Do you think that this is a promising sign for the future ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I think so. I went to a purely Fijian school and when I came out of that, everything was Fijian for me. I went straight into the army which is another Fijian-dominated institution. It was not planned that way. It is just the way it happened. My tolerance level of other races was very low. But you cannot expect somebody who gets to this level of leadership to have a low racial tolerance level. I must admit that the last ten years have been very, very educational for me - very good for my own being. I consider what I used to think before and the way I used to feel before. I have never been threatened by an Indian, but I had always been in Fijian 'safe' areas - a Fijian school and then in the army. But since coming out of that sort of cocoon, I have managed very well to accept that I have to compete with them, I have to look after them, and I have to devise policies and programmes that will be good for them as well as being good for us.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· One final question. Do you envisage Fiji seeking to rejoin the Commonwealth in the near future ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I think seeking is the wrong word. We will do what we feel is good for Fiji and its people. The people of Fiji are those who are here now but it will include some of those who have moved on looking for greener pastures and who are willing to come back. We were not expelled from the Commonwealth; our membership lapsed. It is up to the Commonwealth to say whether they are prepared to reconsider our member ship. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Profile</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">General information</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Area: 18 272 km². Fiji has two main islands (Viti Levu and Vanua Levu) and about 300 smaller ones. It has an Exclusive Economic Zone of approximately 1.3 million km²). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Population: 790 000</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Population density: 43 per kilometre² </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Capital: Suva (situated on the island of Viti Levu) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Main languaqes: English, Bauan </P>
+<P ALIGN="JUSTIFY">(main Fijian language)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Currency: Fiji dollar (F$). In June 1996, 1 ECU was worth approximately F$ 1.80. (US$1 = F$ 1.40) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p15.png"></center><br>
+ Fiji</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Politics</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">System of government: A bicameral parliamentary system consisting of an appointed Senate and an elected House of Representatives. The President is a non-executive head of state chosen by the Great Council of Chiefs. The President appoints the Prime Minister. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under the Constitution, adopted in 1990, the Parliament is divided along racial lines. The Senate has 34 members, 24 of whom are indigenous Fijians. In the 70-member House of Representatives, 37 seats are reserved for native Fijians, 27 for Indo-Fijians, 5 for 'general voters' (other ethnic groups) and 1 for Rotuma Island (whose inhabitants are Polynesian). The 1990 Constitution provides for a review within seven years and discussions are currently under way with a view to amending the Constitution by the 1997 deadline.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">President: Ratu Sir Kamisese Mara</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Prime Minister: Major General Sitiveni Rabuka </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Main political parties: Soqosoqo ni Vakavulewa ni Taukei (SVT - Fijian), National Federation Party (NFP  -  Indian), Fiji Labour Party (FLP - Indian),  Fijian Association (FA - Fijian), General Voters Party (GVP).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Party representation in Parliament (1994 election result): SVT 31, NFP 20, FLP 7, FA 5, GVP 4, Others 3. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economy</P>
+<P ALIGN="JUSTIFY">GDP: (1995) F$ 2.85 billion</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Annual GDP per capita: approx US$ 2600 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GDP growth rate (1995): 2.2% (2.9% predicted for 1996) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Principal exports (1994): Sugar (US$ 182m), Garments (US$ 96m), Gold (US$ 43m), Fish (US$ 38m), Timber (US$ 21 m) Main trading partners (in order of importance):</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Exports - Australia, UK, USA, Japan, New Zealand.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Imports - Australia, New Zealand, USA, Japan, Singapore.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Trade balance (1994): exports - US$ 547m, imports - US$ 826, deficit - US$ 279m. The current account figures also usually reveal a deficit but this is much smaller due to tourism earnings and official transfers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Inflation rate (1995): 2.2%</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Government budget (1996): revenue -  F$ 759m, expenditure  -  F$ 851 m, deficit - F$92 (about 3.5% of GDP) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Forma/sector employment: 98 112 (out of a total economically active population of about 265 000) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Social indicators</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Life expectancy at birth (1993): 71.6 years </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Adult literacy (1993): 90.6%</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Enrolment in education: all levels from age 6-23: 79% </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Human Development Index rating: 0.853 (47th out of 174) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sources: Economic Intelligence Unit, UNDP Human Development Report, 1996, EC Commission. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">An interview with opposition leader Jai Ram Reddy</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'We need to move to a more racially neutral system'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fiji is not unique in having a political system that is heavily influenced by racial or communel issues In places as diverse as Northern Ireland, Belgium, Guyana and Trinidad - not to mention many parts of Africa - people vote for parties which claim to represent the particular ethnic, religious or linguistic group to which they belong. Where Fiji is different, however, is in having a Constitution that gives primacy to one particular community. Since the 1987 coup, native Fijians have held the upper hand with a guaranteed majority in Parliament and a firm grip on the levers or power.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 1990 Constitution, adopted when communal feelings were still running high, contained a requirement for a constitutional review within seven years. When The Courier visited Fiji (July 19961 the work of a three-member Commission appointed to carry out the review and make recormmendations was nearing completion. All sides seem to accept the need for reforms designed to help bridge the sharp racial divide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The big question is how radical these reforms are likely to be. We sought the views of Jai Ram Reddy, the leader of the opposition National Federation Party (NFP) which has the support of most of the country's Indian (Indo-Fijian) community.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You are the first opposition leader I have met who cannot, constitutionally, become Prime Minister. How do you feel about that ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - It is something that rankles with me - the mere thought that I am not equal with my fellow citizens of other races. I think that's generally the way the Indians feel here. All the constraints and limitations, the denial of basic human rights, are the source of a great deal of unhappiness.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You talk about basic human rights. Obviously, the political aspects are very important but I get the impression that, in other respects, this is a fairly free and easy society: there is free expression, for example.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Yes, but free expression is only one aspect of human rights. The fact is that discrimination based on race is widespread and institutionalised. About 45% of the population is Indo-Fijian but you will find they are not fairly represented in the higher levels of the public service. At the Permanent Secretary level, there is definitely a government policy to have a limited number of Indians - and there are hardly any in the more crucial ministries. The same is true of managerial positions throughout the public sector. In the statutory bodies and major public undertakings, there is a deliberate policy of excluding Indians. So we are very much a marginalised community in the public sector.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Wouldn't it be true to say that Indians have quite a lot of economic power ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - No, I don't agree. There is a tendency for people who come here, end for some people in Fiji, to project this image of Indians controlling the economy. It is a fallacy. It all boils down to how you define economic power.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Let's take natural resources. The land, and therefore the forests, are almost exclusively owned and controlled by native Fijians. Even in the corporate sector, the largest business undertaking is the manufacture of sugar, and 80% of the shares are owned by the government. The Indians don't own this industry. They are the small sugar cane producers working on ten-acre plots. And who controls banking and insurance ? Certainly not the Indians. Most of the financial services companies are foreign-owned.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The area where the Indians are most visible is in the retail sector. But those little shops you see in the towns are small family businesses. The shopkeepers work up to 15 hours a day, and you will discover that many of them do not even own their premises; they are tenants. So the idea that Indians control the economy is a bit of a myth. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The Constitution, and in particular the system of racial differentiation for voting and holding certain offices, is obviously a key issue for you. With the Constitution currently under review, what is your party's policy in this area ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The first elections under the current Constitution took place in 1992 and we took part in them under protest. We made clear that our participation should not be construed as acceptance of the system. Indeed, the sole issue on which we campaigned was our rejection of the Constitution. But we accepted the fact that we needed to get into the system as it was, and to try and create an environment where there would be widespread appreciation that it had to change. The 1990 text, in fact, laid down that it had to be reviewed by the seventh anniversary of its promulgation. I think the architects of the Constitution realised themselves that it was deficient. And we laid great emphasis on the need for dialogue; a general recognition that the country would be much better off with everybody working together and that there was nothing to be gained by oppressing or marginalising a community. And that is the kind of environment we have tried to create.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The Constitutional review will shortly be published. What do you hope will come out of that exercise ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I am reasonably optimistic. I think the environment is more favourable now and there is a general recognition that the system has to change. I am sure you will get confirmation of this when you talk to the government side. We need to move away from this very polarised, compartmentalised political system to a more racially neutral one. I think views may diverge as to how far we should go. That will be the contentious issue. But I believe we will make progress.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I certainly think we will get a good report from the Constitutional Review Commission. One of our fears, when we started on this journey, was whether it would be independent and be given fair terms of reference. Largely because of the cooperative and accommodating attitude that we ourselves adopted, and to which the government responded, we were able to get a Commission that was well-balanced. We are very fortunate to have Sir Paul Reeves, a former Governor-General of New Zealand. His independence is taken for granted. The Commission also has one nominee from the indigenous side and one from the Indo-Fijian side. So we certainly expect a good report. There is already a kind of acceptance I think on all sides that political parties need to prepare themselves for a more multiracial approach to governance in the future.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· On this point, I see that the SVT (the governing party) is looking at the idea of opening up its membership to other groups.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - That's right.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Do you think there will be many nonnative Fijians interested in joining ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Not straight away but at least it is a beginning. It is an acceptance that they can't remain racially exclusive. If, for example, the Commission recommends a move toward a racially neutral system - at least for a certain number of seats - then it would be important for the SVT to have non-Fijians in their party.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Can I turn to economic issues, which I presume cannot be divorced altogether from political ones ? There is a lot of discussion about the future of the sugar industry which is tied in with the question of renewing the land leases This is an issue which is due to be resolved soon. How concerned are you about the impending decision on the leases ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - This is something that concerns us very deeply. As you correctly observe, you can't separate the political and economic aspects. The two are very closely interlinked here - perhaps more so than in other countries - because of the land situation. The bulk of Indian peasant farmers, both within and outside the sugar industry, are on leases that will begin to expire next year. If these are not renewed, the problem will not just be an economic one but an enormous human one. What do we do with these people who all belong to a particular racial group. It really boils down to our very survival. Despite the growth in the towns, the bulk of the people are still rurally based. They are small subsistence farmers, living in the country areas with no more than 10 or 12 acres to cultivate. So the social implications of non-renewal in terms of poverty, dispossession and hardship are enormous.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· But how real is the concern ? Surely, the overwhelming economic logic is for the leases to be renewed. After all the land is being put to productive use at the moment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> -  Yes, but unfortunately, when you have a communal dimension to the problem, logic does not always prevail. If you think about it, there was no logic in the events of 1987. The trouble is that every issue here has a racial twist. After the coup, communal sentiments were aroused and sharpened. There was a prolonged period of anti-lndian propaganda and in that environment of anger, a highly racial constitution was adopted. There were people in positions of influence openly advocating non-renewal, threatening to take all the land back. Now they need to undo all this and it will not be easy, given the enormous strength of feeling that has been aroused. Having said this, I believe that we are now in the process of restoring sanity to our public life. It is also beginning to dawn on everybody that the sugar industry is vital for Fiji and it will continue to be so for some years to come.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· I have heard that view expressed on all sides, but I wonder if people are sufficiently aware of the implications of global liberalisation. It has been suggested that this will make sugar increasingly unviable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I think a lot of people are unaware of the implications, because there has been very little public education in this field. But amongst those 'in the know', there is certainly an appreciation. I am a member of the Parliamentary Select Committee on Sugar and we were recently addressed by the head of the marketing company and the head of the Sugar Commission. At that level, there is an awareness, but if you speak to the average farmer who has been growing and selling sugar for many years, he will probably assume that life will just go on as before.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Isn't it true to say that sugar depends heavily on the Lom&eacute; Convention arrangement with the European Community ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Very much so. In my view, the sugar industry is run so inefficiently that but for the huge subsidy we get from the European Community, it would not be viable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Presumably, this means that measures must be taken to improve efficiency ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Yes, absolutely. But the first issue to resolve is the land question.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is no point talking to the farmers about efficiency  -  asking them to improve their husbandry and focus on sugar content rather than the quantity of cane produced - when they don't know if they will have land to cultivate after next year. So you see all other issues have become completely subsidiary to the tenure question. At the moment, we are in a limbo. The government and the people urgently need to resolve this problem. Then we can put it behind us and address the other concerns.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Are there any other economic sectors which you feel offer promise for the future of the country ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> -  Any growth outside of tourism will, I think, have to be centred on the agricultural sector. We need more agro-based industries and more diversification. We could grow a lot of other crops here - mangoes for example. We also need to improve extension services to farmers, and make an aggressive effort to identify markets. The farmers will grow the crops but they must be sure that somebody will buy them. Every year, for example, we have a glut of tomatoes - so many that they can't even give them away in the markets. This kind of problem kills the incentive to produce.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is obviously heavy state involvement in the running of agriculture. Do you see scope for more privatisation or 'corporatisation' in line with global trends ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I think that growth, even in the agricultural sector has to be private-sector driven. At the same time, you have got to create the right environment and infrastructure for this to happen. Unfortunately, it keeps coming back to this question of land. If big investors, for instance, want to come here and invest in agriculture, they need to know what sort of tenure they are going to get and whether they can buy the freehold. I am sure there are people, particularly now from the Asian region, who would be interested in investing in agriculture, but the land problem is a big constraint.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Do you think Fiji will rejoin the Commonwealth at any point ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Well, we hope so. You know we are all very strongly in favour of rejoining. One of the things that I personally feel very strongly about is the unfortunate severance of our link with the Queen. I don't know, constitutionally, whether it can be restored. Obviously, there are difficulties in that area, but I think a large majority of ordinary people in this country would like at least to see Fiji back in the Commonwealth. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Seeking a lasting constitutional settlement</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When The Courier visited Fiji in July, the report of the Constitutional Review Commission headed by Sir Paul Reeves (former Governor-General of New Zealand) had not yet been completed  -  and what it would contain was a major topic of speculation. As readers will see from the interview we publish with the Prime Minister and Opposition Leader, the impartiality of the three-member Commission was not in question  -  at least within the political mainstream on both the native Fijian and Indian sides. Nonetheless, there were doubts about whether a consensus could be found. For the Indo-Fijians, a scaling down of the 'racial' features in the Constitution was seen as a prerequisite. Yet the ruling SVT, in its own submissions to the Commission, had effectively supported the status quo. In view of this apparently unbridgeable gulf, could the compilers of the Report come up with recommendations capable of forming the basis for a lasting constitutional settlement ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The long-awaited Report was formally transmitted to President Ratu Mara on 6 September and a few days later, it was tabled to a joint session of the Senate and the House of Representatives. It now falls to a joint select committee of the two Houses to thrash out a new set of constitutional proposals. These will be presented to Parliament for debate and decision in the first half of next year with a view to meeting the July 1997 deadline foreseen in the 1990 Constitution.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Report of the Review Commission is lengthy (almost 800 pages) and contains no fewer than 697 separate recommendations. The key ones, however, relate to the system for electing members of the House of Representatives. Currently, separate electoral lists based on race are used to fill all 70 seats (37 native Fijians, 27 Indo-Fijians, 1 Rotuman and 5 'General Electors', covering all other races). It was widely expected that the Commission would propose a mixture of 'reserve' seats and 'open' ones, with the latter, as their name implies, being chosen by the whole electorate.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">45 'open' seats proposed</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This is precisely what they have done - but the suggested breakdown may have come as a surprise to some. The proposal is for 45 open seats (15 three-member constituencies) and 25 single-member 'reserve seats (12 native Fijian, 10 Indo-Fijian, 1 Rotuman and 2 'General Electors'). If adopted, the new system would no longer legally guarantee a majority for people of Fijian origin in the country's legislature. What would happen in practice would depend on a number of factors including the nature of the voting system in the three member open constituencies, the willingness of people to cast their ballots across the ethnic divide and the actual turnout of voters from the different communities. It should be pointed out, however, that native Fijians now constitute half the population, large numbers of Indians having emigrated over the past nine years. So long as communal voting patterns persist, this will presumably be reflected in the Parliamentary arithmetic.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is also proposed that the bulk of the 35-member Senate (Bose e Cake) should be made up of elected representatives of Fiji's provinces. In the field of local government, it is suggested that the present system based on villages and provinces, which applies only to native Fijians, might be replaced by an arrangement applicable to all races. In this context, the rote of the Council of Chiefs (Bose Levu Vakaturaga) would be reduced.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although the sections of the Report relating to representation are bound to attract most attention, the Commission also put forward a series of other proposals aimed at improving the governance of Fiji. One idea, which appears designed to alter the political culture, is for the 'Official Secrets Act' to be replaced by a 'Freedom of Information Act'. The presumption of secrecy would be replaced by a rule that official information should be accessible to the public except where there is good reason to withhold it. In a similar vein, the Report recommends an 'integrity code' to govern the behaviour of holders of public office.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Initial reactions to the outcome of the Commission's work were mixed. Key players, including the President, Prime Minister and opposition spokespersons broadly welcomed the Report but more nationalistic elements were quick to reject it and one group even mounted a ceremonial burning of the document.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is obvious that a great many more words will be exchanged - and some of them will no doubt be heated  - in the coming months. It is difficult to see how everyone can be 'brought on board' but the hope must be that a compromise can be crafted that is acceptable to the majority on both sides of the communal divide. The people of this Pacific island nation are well aware that prosperity and stability go hand in hand. The single most important achievement in ensuring stability for the longer term would be to secure a satisfactory settlement of the constitutional issue. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">'Sugar definitely has a future'</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This was the key sentiment expressed by Isimeli Bose, Fiji's Trade Minister, when he spoke to The Courier earlier this year. Mr Bose insisted that 'no matter what anybody says, sugar will be the backbone of this country's economy for years to come.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When we discussed Fiji's current economic situation and future prospects with the Minister, it was not surprising that sugar should have featured so prominently. The sector faces a difficult future for both internal and external reasons. At home, the long-term leases granted to the farmers (mainly Fiji Indians) under the Agricultural Landlord and Tenant Act are due to expire over the next few years. No provision was made for their renewal and the resulting uncertainty has provoked widespread concern, not least among the leaseholders themselves. The external 'threat' comes from new international trade rules administered by the World Trade Organisation. At present, Fiji's sugar industry is heavily dependent on the preferential access to the EU market which was granted under the Lom&eacute; Sugar Protocol. No one is quite sure what will happen when Lom&eacute; IV expires at the turn of the century but it is clear that the stakes are high.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mr Bose was quick to acknowledge the importance of ending the uncertainty facing the sugar farmers. 'But the real challenge', he said, 'is to ensure the maintenance of our markets for sugar.' He was aware of the encroachment of global trade liberalisation but stressed that the industry's leaders and the government were 'doing the work now and planning for the future.' At the same time, the authorities are clearly hoping that the European Union will be able to continue with some form of preferential arrangement after the year 2000, if only to buy time so that the industry can adapt and farmers can diversify.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the subject of trade diversification, Mr Bose pointed out that 'the field is very limited'. He continued; 'However, since 1988, we have seen garment production picking up from very humble beginnings. By 1995, we had about F$185 million-worth of exports in this area.' He also spoke enthusiastically about the government policy of encouraging manufacturing in tax-free factories and zones. 'This developed well between 1989 and 1992 and then there was something of a slowdown.' Tax-free factories have been established in a number of locations and the first real tax-free zone is now being set up in Kalabo. Mr Bose indicated that EU assistance was being provided in this area.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Privatisation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Our conversation then turned to the changing economic role of governments - throughout the world, they are withdrawing from active involvement in industrial and commercial operations. We asked how far this process had occurred in Fiji and, in particular, whether there was a privatisation policy. The Minister replied in the affirmative, pointing out that government departments 'do not usually make very good businesspeople.' The policy, therefore, was to 'corporatise' and 'privatise', although the process is still in its early stages. The Trade and Commerce Ministry has a public enterprise unit which is responsible for drawing up a policy framework for the government. In 1995, Mr Bose explained, a public enterprise bill was presented to Parliament, 'but there were so many concerns expressed to the previous Minister that it was referred to a select committee -  which, in fact was chaired by me before I took up my present poet.' The committee had now completed its work and the Minister indicated that the issue would go back to Parliament in September.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite the legislative delay, Mr Bose was keen to stress that his department was already working on individual programmes. The post and telecoms business, for example, had just gone through another stage towards privatisation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is, of course, an important distinction between 'corporatisation' and 'privatisation' - the former implies staying within the state sector but at arms-length from the administration. This point was acknowledged by our interviewee who explained that the approach was a step-by-step one. The first stage was to reorganise a department along commercial lines. Corporatisation came next 'and then finally you have privatisation by disposing of shares.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He stressed that the most important aim was to ensure an element of competition wherever possible. 'There is no point simply moving from a government monopoly to a private monopoly', he insisted, 'although obviously, there are utilities like water, electricity and even telephones where this may not be easy.' The minister concluded; 'Where they are natural monopolies, we will regulate them.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Our final topic of discussion was the possibility of regional integration in the Pacific.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">How far had the South Pacific countries gone in this direction and did the Minister think there was a need for closer economic cooperation? Mr Bose replied that he thought economic integration was a good thing. He pointed to a document on his desk containing a draft proposal for a bilateral trade agreement with Papua New Guinea. 'We will soon be holding negotiations with them, and have also just signed an agreement with Tonga.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The focus on bilateral trade arrangements at this stage suggests that the region still has some way to go on the regional integration path.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But the Minister nonetheless insisted that it was something 'that can and will happen'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Our daily bread - courtesy of a remarkable Fijian businesswoman</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">How can a businesswomen succeed in Fiji's patriarchal society? Mere Samisoni, the entrepreneur behind the 'Hotbread Kitchen' gave us an appropriate answer when she said 'I roll with it', although the pun was probably unintentional In fact, it is difficult to imagine this dynamic lady being pushed around. Anybody who manages to build up a chain of bakeries from scratch, capturing 35% of the country's urban consumer market in the process, must have a lot of determination. At the same time, Mrs Samisoni displays a strong sense of social commitment. She believes in community values, advocates group decision-making and consensus, and even describes the tax system as 'reasonably fair'. In short, she contradicts the widely-held view propagated by lurid American TV series, that a dogeat-dog attitude is needed for business success.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In fact, Mrs Samisoni started out with the idea of working with one of the caring professions. Trained in nursing administration in Australia and New Zealand, she returned to Fiji only to find that there were no openings available. That was when she decided to go into the private sector, establishing 'Samisoni Enterprises'. And over the years, she has succeeded in building up one of the largest bread-making operations in the country. The Hotbread Kitchen operation is highly decentralised with the bread being baked in different locations for sale through the company's local outlets. Her business is also the first Fijian one to franchise out its operations. And having already won a big chunk of the urban market, she is now looking to expand operations in the rural areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Samisoni Enterprises, of course, is not simply a bread-making operation. The company now offers a line of 62 separate bakery products, with some local adaptations to suit varying tastes. It employs some 275 staff with perhaps another 50 working in the related franchise operations. And the business had an important breakthrough when it won the contract for 'MacDonalds' in Nadi. With branches of the famous hamburger chain likely to open in other parts of Fiji, this could be the start of something big. In fact, there is even a suggestion that Fiji could be used to source Macdonalds' operations in New Zealand, the rolls (or buns, as the Americans like to call them) being exported frozen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Constant quality</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For Mrs Samisoni, the key to a successful and profitable operation is 'constant quality' and unfailing attention to customer service. As she puts its, 'if you let quality slip just once, you can end up losing customers for a very long time.' Baking is a labour-intensive business and she is keen to stress the importance of developing people's abilities - in particular, the human relaitons skills of those who deal direct with the customer.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As if running a business wasn't enough, Mere Samisoni is also busy completing a Masters in Business Administration (MBA) at the University of the South Pacific, with a thesis on indigenous business. From what we discovered, speaking to this remarkable Fijian entrepreneur, she should have been helping to teach the course! </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Viti Levu - island of contrasts</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Anyone from overseas who is travelling to the Fijian capital, Suva, will soon discover that the country's largest island is a very diverse place. Roughly circular in shape, Viti Levu provides more than half of Fiji's total land area and is home to about three-quarters of the population.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The journey to Suva on the south-east coast will almost certainly involve transiting through Nadi International Airport (pronounced Nandi) which is situated in the west. This is the country's only major international gateway and while it is ideal for tourists heading for the resort hotels, it is less convenient for business travellers whose destination is Suva. Their journey has to be completed either by road (which takes several hours) or on one of the small commuter planes which ply regularly between Nadi and Nausori (itself a half-hour drive from the capital).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The biggest surprise to those who are unfamiliar with the country is that the west and the south-east have very different weather patterns. When your aircraft lands at Nadi, the chances are high that the sun will be shining. On reaching Suva, you are more likely to encounter rain. This part of the country enjoys - if that is the correct term - a micro-climate which is good for tropical vegetation but less appealing to human beings. The 'blame' for locating the Fijian capital in such a spot is said (not too seriously) to lie with the country's former colonial rulers. According to the story, a British envoy visited Suva on one of its rare sunny days and, on the strength of this, designated it as the seat of administration. The British can hardly deny their involvement since it was in 1882, during the early years of colonial rule, that the capital moved from Levuka (situated on the much smaller island of Ovalau). But the key reason was almost certainly the fact that Suva, with its large bay, could be developed as a port. Whatever the explanation, one must have some sympathy with the foreign diplomats who keep a raincoat or umbrella to hand at all times, and yet are viewed with envy back home because they have a 'paradise' posting.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To be fair, Suva has attributes other than its weather which make it an interesting place. It has, for example, some very attractive architecture, both local and colonial. The views across the bay can be dramatic - and, in this respect, the rolling cloud formations may actually enhance the picture. And the centre of the city buzzes with activity (except on Sunday because of the Sabbatarian influence).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The population of the greater Suva area is about 160 000. This may not be enormous, but it is the largest concentration of humanity to be found between Hawaii and Australia. In some ways, it is the 'capital' of the South Pacific - a point which is underlined by the fact that the Forum Secretariat is based here. It is also the site of the University of the South Pacific's main campus. The local population is mainly ethnic Fijian but there are Indo-Fijians as well as citizens of Chinese and European extraction. Add to this the diplomatic corps, foreign businesspeople and students from other parts of the region, and you get a very cosmopolitan mix. This is reflected in the variety of cuisines available in the local restaurants.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The western part of Viti Levu is also cosmopolitan but in a very different way, with a stronger Indian influence and, of course, a constantly changing tourist population.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most of the island's inhabitants live a relatively short distance from the sea. Thus, in demographic terms, Viti Levu is like a doughnut with a thick layer of humanity around the edge and a hole in the middle. The analogy may not be entirely apt since the 'hole' is, in fact, a spectacular mountainous area. This makes the road that runs round the island a key arterial route. Meanwhile, those who choose to fly from Nadi to Suva, assuming they are not of a nervous disosition, can enjoy the experience of travelling below the height of the surrounding peaks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The few people who do occupy the central region live in traditional Fijian villages and have a lifestyle far removed from either the town dwellers or the sugar cane farmers. Its size may be little more than ten thousand square kiLom&eacute;tres but Viti Levu is truly an island of contrasts. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Fiji-EU cooperation: comprehensive package</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Ernst Kroner</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fiji was a signatory of the first Lom&eacute; Convention in 1975 and, to date, the country has been allocated some ECU 190m in EU development cooperation funds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Starting with a relatively modest ECU 9.9m under Lom&eacute; I, the national indicative programme rose to ECU 13m under the following Convention. Without neglecting rural development (feeder roads in Vanua Levu), under Lom&eacute; I most of the resources were devoted to transport infrastructure (a main road on Vanua Levu). Under Lom&eacute; 11, cooperation concentrated clearly on agriculture and rural development, in particular by means of the funding of microprojects, with infrastructural programmes (the extension of the Vanua Levu road, social infrastructure) taking second place. Under this Convention, a new field of action was also addressed: trade development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tax free zone</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Trade development was addressed further under Lom&eacute; III (6th EDF, ECU 20m, of which ECU 5m in special loans), with support given to an Investment and Trade Development Programme. The longer-term objective of the project was to widen the economic base of Fiji and to create employment. The more immediate objective was the i establishment of a Tax Free Zone near Suva. In order to promote this scheme and to secure markets for exporting the goods which would eventually be produced, the project included a programme of trade and investment promotion to be implemented by the Fiji Trade and Investment Board. Due to problems linked with identifying an appropriate site, the project, which had been given the go-ahead in 1990, only came on stream in 1995.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rural and agricultural development continued to be one of the main sectors of cooperation, with the funding of three major projects. The first was a coconut rehabilitation and development project, situated on the island of Taveuni, which aimed at improving the productivity of coconut plantations through the introduction and multiplication of high yield hybrids. The project also provided for the establishment of a 30 hectare coconut nursery centre, which was expected to finance itself through the sales of seedlings. EC support for this project ended in 1992, since when the scheme has been taken over by the Government. A second project (a large-scale microprogramme divided into two sub-programmes) aimed on the one hand at the construction of access roads to facilitate the development of cocoa plantations, and on the other at the introduction and development of pineapple plantations in Vanua Levu. The first component was closed after disappointing results. The second component, however, produced very interesting and promising results, which will, however, need private and governmental support in order to become sustainable. A rural electrification project involving 28 rural electrification schemes and the supply and installation of a small power plant is still ongoing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Developing human resources</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under Lom&eacute; III, the formerly prominent transport infrastructure sector lost some importance. The Kubulau Peninsula road project on Vanua Levu brought to an end the work started under previous Conventions. This road, which filled the last gap in the circuminsular road, was opened on in July 1994. Lom&eacute; III also saw the beginning of human resources development as a new theme of cooperation, with Technical Assistance funded for the logging school. This area, embodying strong links with forestry and environmental issues, has been further developed under Lom&eacute; IV with the reconstruction of the school burnt down in 1993, and the enlargement of the training and education provided to what now constitutes a Forest Training Centre.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The national indicative programme relating to the first protocol of Lom&eacute; IV (7th EDF, ECU 22m in grant aid) identifies rural development and social infrastructure as the sectors of concentration to which 65% of resources are to be devoted. The remaining 35% will be used for non-focal activities, including trade and services, tourism, cultural cooperation, training and technical cooperation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Building bridges</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unfortunately, it was only following the very destructive cyclone Kina in January 1993 that cooperation activities could start in the form of the rebuilding of four bridges either severely damaged or completely destroyed by the post-cyclone floods.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Work on two smaller bridges of major importance to Viti Levu (Korovou and Vunidawa, ECU 1.135m) was started in 1994 by the Public Works Department and completed in January 1995.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Financing Agreement for the two major bridges (ECU 10.24m) was signed in June 1994 and provides for the rebuilding of the bridges of Ba and Sigatoka. These form part of the main road around the island of Viti Levu and are therefore vital for the movement of people and goods on Fiji's main island. The new bridges, 190 and 182 metres long respectively, will be two-lane, and will provide for footpaths and utilities. To enable the traffic to by-pass the often congested towns of Ba and Sigatoka, new sites for both bridges have been chosen, which also call for the building of new approach roads. Building works were under way in early 1996 and completion is expected by April 1997.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Non programmable aid for Fiji has been considerable over the years. While Stabex transfers for losses on coconut oil (totalling ECU 5.4m under Lom&eacute; I - Lom&eacute; III) came to a halt under Lom&eacute; IV (because levels of exports fell below the required dependency threshold), emergency aid (total ECU 9.5m) has continued, unfortunately, to be needed. Time and again the islands have been hit by cyclones (the most recent occasion being in January 1993, when the EU made available ECU 1 m for food rations following cyclone Kina).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the past, a significant feature of EU-Fiji cooperation was the credits provided by the European Investment Bank. It was very active under Lom&eacute; I to Lom&eacute; III, providing loans from its own resources to a total value of ECU 87.5m with a further ECU 6.1 m allocated in risk capital. Loans went to the energy sector (hydropower scheme), industry (wood processing) and services (telecommunications, sea and air transport). Considerable interest rate subsidies (totalling ECU 14.1m) have also been made available under the various EDFs in support of these loans. More recently, the EIB has financed an aircraft maintenance centre (1991) and a telecommunications project (1995).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Trade cooperation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over and above financial cooperation, Fiji benefits from the second largest quota (165348 tonnes per annum) under the Sugar Protocol annexed to the Lom&eacute; Conventions. This covers some 45% of its total sugar exports. The yearly benefit from this provision is estimated at between ECU 45m and ECU 55m - in other words, only slightly less than the total of all programme aid granted since Lom&eacute; I (ECU 64.9m). About two-thirds of these benefits reach the farmers, so that the EU subsidises every sugar smallholder, on average, to the extent of some ECU 1500 a year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Recently, Fiji's quota under the Sugar Protocol was increased by 881 tonnes, as a result of the reallocation of the shortfall of deliveries by Barbados. Furthermore, Fiji benefits from an annual special tariff quota to the tune of some 30 000 tonnes up to the year 2001.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Industrial development and external trade have been supported by the relaxation of the rules of origin for exports to the EU of canned tuna to the extent of 500 tonnes a year from 1993 to 1996. A similar arrangement, applicable for certain quantities of garments up the end of 1993 was recently extended to the end of 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fiji's main exports to the EU (sugar, fish and garments) - and the resulting surplus in its trade relations with the EU - are consequently highly dependent upon the continuity of these preferences.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Support for tourism</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the field of services, and specifically in tourism, the EU - through its support of the Tourism Council of the South Pacific - has contributed to the fact that every sixth tourist or so arriving in Fiji comes from a member country of the Union. Tourism being by far Fiji's most important source of foreign exchange earnings, receipts from European tourists amount at present to some ECU 30m, and are greater than those from the export of fish and fish products</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Taking the Sugar Protocol into consideration, the EU is by far the most important of Fiji's development partners, followed by Australia. The country also benefits from bilateral cooperation arrangements with EU Member States (UK, France, Germany). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Tonga</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Hoping to maintain harmony</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'None of the most civilised nations have ever exceeded these islanders in the great order and regularity maintained on every occasion, in ready and submissive compliance with the commands of their chiefs, and the perfect harmony that subsists among all ranks.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These were the words of Captain Cook who visited the Tonga archipelago several times on his voyages around the world in the eighteenth century. The famous explorer was obviously impressed by the social organisation of this island nation and, although it is more than two centuries since he undertook his Pacific voyages, many of his observations hold true today. Talk of submissive compliance may no longer be appropriate, but in contrast to the turbulence of much of the outside world, Tonga certainly ranks as a peaceful society, which is respectful of hierarchies and strongly attached to 'traditional values'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The reference to harmony is particularly apposite, as The Courier discovered when we visited Tonga earlier this year. It was fortunate that our trip coincided with the King's birthday celebrations and we had the opportunity to enjoy the superb choral music which plays a central part in many important ceremonies here. Like their Polynesian cousins in Western Samoa (featured in our last issue), the Tongans seem to have a natural flair for music and a talent for spontaneous harmony. The question is whether these 'Friendly Islands' - a name they certainly deserve  -  can maintain their reputation for social harmony into the third millenium.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In order to answer this, one has to identify where discordant notes could creep in. The biggest challenge appears to come from the process of globalisation. New technologies, particularly in the field of communications, are rapidly breaking down barriers. The tide of the international economic system, with its emphasis on mass production, con sumerism and free trade, is lapping at the islands' shores And political systems everywhere are under pressure to con form to a 'democratic' model which some would argue places the individual above the community. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Of course, external influences can be both positive and negative Cultural exchanges can be enriching, and new ideas and techniques may offer opportunities for improving the quality of life. The key is to adapt without undermining the social fabric. And in Tonga, as in other countries, a harmonious future will ultimately depend on the way the country evolves both politically and economically.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Looking first at the current political set-up in Tonga, one cannot fault the use of the term constitutional monarchy which is the preferred description locally. It is important, however, to recognise that the constitution - which dates back to 1875 - gives considerable power to the monarchy. There is a measure of democracy in that all adults over 21 have a vote, but they only elect nine of the 30 Members of Parliament A further nine are chosen by the country's 30+ nobles while the twelve Cabinet Ministers, who sit in the House ex officio are nominated by the King. Tonga may' be small (it has fewer than 100 000 inhabitants) but it nonetheless attract: the interest of political scientists as one of the few remaining states with a hereditary ruler who wields substantial power.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Critics of the system view it as an anachronism, although their emphasis is on reform rather than revolutionary change. Defenders argue that the arrangement works well in a small, homogenous nation which values its unique culture and traditions (even if the constitution contains many 'British' elements). The latter also point, with some justification, to the attitude of the population. There are dissenting voices but the majority appears to be happy with the existing set-up, thereby lending it democratic legitimacy  -  at least indirectly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There may not, at present, be any overwhelming demand for constitutional reform but things can change. In particular, a people's view of their political system and how it might evolve is likely to be influenced by the prevailing economic conditions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economic outlook</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tonga's economy is not exactly booming with the most recent estimates suggesting a 2% GDP drop in 1995-96. Several of the traditional problems faced by developing countries are to be found writ large here. The local market is not just small but tiny by global standards, and this makes it exceptionally difficult to achieve economies of scale. There is heavy demand for imported manufactured items and few viable export opportunities to balance the equation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The education system compares favourably with those of other developing nations but the pool is so small that Tonga inevitably suffers from human resource shortages. This is exacerbated by a steady 'brain drain'. Qualified Tongans, who may already have experienced life abroad at college or university, are tempted by a range of attractions including higher salaries, better housing and more extensive career prospects. The skills shortage is particularly severe in the medical profession. In a recent issue of Matangi Tonga (the 'national news magazine'), it was reported that the country would only have one anaesthetist by 1997 - with a local doctor observing wryly that there was no need for one since the main hospital's only specialist surgeon had recently left to take up a post abroad.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although it would be better for Tonga to retain its qualified people, the fact that the country 'exports' labour does have its positive side. Tongans have a strong sense of family and community, and overseas workers send significant amounts of money back home. This injection of 'foreign' funds boosts the local economy and reduces the overall balance of payments deficit.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agriculture</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agriculture is by far the most important economic sector, with most crops being grown for local consumption. The islands benefit from a fertile soil and a tropical climate, allowing the cultivation of a wide variety of fruit and vegetables. All land is vested in the Crown, with estates allocated to the nobles. By law, each adult male is also supposed to be allotted three hectares although there is not enough land to go round. Despite this difficulty, which means that some people do not receive their allocation, the result is that most Tongans are involved in farming. The advantage of the arrangement is that it guarantees a living for the bulk of the population even if their cash income is low. On the other hand, it is obviously a feudal system which favours the upper echelons of Tongan society. In addition, it tends to hinder the development of larger units which could benefit from economies of scale. While anxious to make farming more efficient (and export-oriented), the government currently has no plans to introduce land reform.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In export terms, the main crop is squash (pumpkins). Production increased dramatically in the early 1990s when a market niche was identified in Japan and it soon became the country's biggest foreign exchange-earner. More recently, income has been depressed, with overproduction in 1994 leading to a drop in prices, and poor rainfall the following year reducing yields. The November export figures for the last three years (November is the month when squash deliveries peak) illustrate the extent of Tonga's reliance on this single product. In November 1993, the country's overall export income was T$15m - more than half of the annual total. Twelve months later, the figure had dropped to T$9m and last year, it fell below T$6m. When The Courier visited Tonga, the authorities were talking about limiting the amount of squash exported to Japan this year to 15 000 tonnes, in the hope of maintaining premium prices.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The government is also acutely aware of the risks of mono-dependence and is looking for other outlets for its agricultural produce. Demand for copra, Tonga's traditional export, has apparently been reviving, but the price has not been high enough to attract local farmers back into the market. Other crops sold abroad include vanilla, cocoa, coffee, black pepper and ginger.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One farmer who is doing his bit in the quest for export diversification is Masao Soakai, a former general manager of the Copra Board. He is now the managing director of a company that specialises in the import and export of produce. This energetic 73 year-old gave us a guided tour of the plots he had rented. He cultivates an astonishing range of different crops which include potatoes (for Fiji), cassava, taro, yams, carrots, broccoli, cauliflowers, strawberries, bananas and capsicums. He also rears cattle and pigs (a Tongan tradition). Masao Soakai stresses the importance of rotation in maintaining yields and believes strongly in planting for the future.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other sectors</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wherever you happen to be in Tonga, the Pacific Ocean is never far away. Evidence of the country's maritime tradition can be found in accounts of the appropriately named William Mariner (see box article on this page). But while, in the past, Tongan vessels sailed far and wide, and the country has a huge exclusive economic zone (EEZ), the fishing industry is relatively undeveloped. The sector generates about 5% of GDP. A project sponsored jointly by the FAO and the UNDP revealed that there was considerable scope for expansion, both in the inshore and reef zones and in the deep sea area. The main species which could be exploited commercially are albacore, skipjack and yellowfin tuna. Tonga has received assistance to develop its fisheries from the USA and Japan, and the government has offered tax advantages in the hope of promoting investment, but there is still a long way to go before the country realises its full potential in this area. Hitherto, the country has not licensed foreign vessels to fish in its waters but there is talk of this policy changing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tourism could also generate a lot more income although it currently faces a number of infrastructural and practical constraints. The government is committed to expanding the sector but Mrs Papiloa Bloomlield Foliaki, the owner and manager of Nuku'alofa's third largest hotel (the 'Friendly Islander') feels that a lot more could be done. She pointed out to The Courier that a healthy tourist sector would provide employment as well as stimulating new business for food producers, builders and craft industries. She focused, in particular, on deficiencies in training and marketing, and suggested that some of the resources allocated to agriculture might be better spent in tackling these.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tonga's natural assets make it a 'dream' location for visitors looking for a complete change of scene - particularly if they happen to be keen on sailing, snorkelling or scuba diving. The problem is that the country is so far off the beaten track that it is expensive to get to (some would see this as an advantage in deterring mass tourism). Nothing much can be done to change this but it does mean that they have to aim at the upper end of the market. This requires top quality accommodation  -  of which there is a distinct shortage at the moment. As regards marketing, Mrs Foliaki was hopeful that the recent formation of a hotel association would enable the Tongan tourist industry to raise its profile abroad. Despite her optimism - echoed by all those we spoke to in official circles - the latest figures for visitor arrivals show a downturn.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the manufacturing sector, the story is, sadly, one of long term decline. Clothing production ceased in 1994 and the output of leather items has been falling. There are very few industrial activities in which Tonga has a comparative advantage (whether actual, or potential) and this is something which is recognised locally. There may be some scope for adding value to agricultural products through processing but it is unlikely that industry will take off in a big way in the foreseeable future.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The sale of passports (see the interview with Prime Minister Baron Vaea) is an issue which attracted publicity - not all of it favourable - some years ago, when the government launched the TPPP (Tonga Protected Person's Passport). This was designed to be a travel document which did not confer the right of residence in the country. The authorities adopted the scheme with an eye firmly on Hong Kong, a British colony which is due to be transferred to China in 1997. Some passports were sold but the project never really took off as the immigration authorities of other countries refused to accept the document. Now there are suggestions that the idea may be revived, although this time involving normal passports.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The foregoing survey of Tonga's economy does not paint a particularly happy picture but it should be stressed that there is very little real poverty in the islands. In many ways, the informal economy is more important, and subsistence agriculture and fishing ensure that people do not go hungry. With their traditional family structures and strong attachment to the Christian faith, the Tongans have not yet encountered many of the social problems associated with more consumption-oriented societies. But to paraphrase a famous saying, 'no nation is an island' nowadays - even if it happens to be surrounded by water! In an era of increasing globalisation, the key question is how to manage change. Let us hope that the people of Tonga can find the right answer. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Interview, Prime Minister Baron Vaea</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'Constrained by our geography'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">No-one can accuse Tonga's Prime Minister of being a starry-yed optimist. As the following interview reveals, Baron Vaea, who heads a twelve-member ministerial team, is refreshingly honest about the economic difficulties facing his small island country. The Courier interviewed him in July, at his office in Nuku'alofa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You have suffered a GDP drop and a general slowdown of activity in recent years. What is the government doing to restore the situation ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - It is true that the economy has been declining. The main cause is the excessive demand from the private sector for imports from New Zealand and Australia, combined with diminishing exports. Our exports fell when the price of copra dropped. Another problem is New Zealand's quarantine rules. New Zealand is very particular on quarantine against insects, notably fruit flies, which may damage their own export trade. We have endeavoured to balance this out by selling squash to Japan and indeed, it has been a saviour as far as our economy is concerned. Squash is something our farmers know how to grow. Of course, the market goes up and down. Recently, we made the mistake of over-producing and quite a lot of the crop could not be sold abroad. I think our farmers are now realising this, and that they have to plant according to the quota that we ourselves have imposed. Tourism is another important area although levels of room occupancy are very dependent</P>
+<P ALIGN="JUSTIFY">on the economic situation in other countries. Then there are passport sales.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Is this something you are still doing ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Yes, but it has been hit by technical difficulties. A number of Hong Kong Chinese bought our Tongan Protected Persons Passport (TPPP) in the hope that they could travel. The immigration authorities in other countries decided they would not accept the document so this source of income dried up. We have changed to national passports which people can use to travel. We are hoping to revive this in order to suit the conditions of the Hong Kong people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Is this being done on the assumption that the people who purchase such a passport would not ultimately settle here ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Yes. The main reason people in Hong Kong want a passport is to keep open the option of leaving after the changeover.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Has this policy prompted any criticism from other countries ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - No. The main problem is the Chinese themselves who are due to take over Hong Kong next year. It is possible that they will not recognise these passports. We are planning to have discussions with the Chinese on this.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Going back to the agricultural sector, are you not putting too many eggs in one basket in focusing so heavily on squash. What efforts are you making to diversify ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - We have just signed a trade agreement with Fiji. They are such a close neighbour yet we have had virtually no trade with them. This should change with the agreement, to the benefit of our economy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What products are we talking about here ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Mainly vegetables, particularly those that are favoured by the Indian community, such as chills and spices. A trade mission has just returned from Fiji where they picked up a number of orders. The representative of a group of growers also recently returned from Japan. He took a sample of dried pawpaw, a crop which is popular with the Japanese, and apparently received an excellent response. This is an area which is promising.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The key issue, however, is the amount of space available in the aeroplane. You can't ask everyone to grow pawpaw when the airline tells us that they can only take eight tonnes at a time. Only a limited number of farmers can be involved, so that we can continue to supply the tonnage that the airline can handle. We will encourage the rest of the farmers to concentrate on other products.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What is your policy regarding foreign investment ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - We encourage overseas investors to engage in activities that local people are not involved in. Land leases are available for anything they want to do which fits in with this policy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tonga has an extremely limited manufacturing sector and there appears to have been a long-term decline. What prospects are there for reversing this trend ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - For many years, the policy of the government has been to encourage exports. We have had entrepreneurs here who have exported things like woollen garments, small boats, horse saddles and so on - but it didn't last. The sad fact is that hardy anything is exported from Tonga. The main reason is that we are constrained by our geography. We are so far away from the main markets. The raw materials have to be brought in and by the time the article is finished, there is no way that it can compete in price terms. This has always been our problem. We are always looking for new markets but it is not easy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A second limitation is the private sector in Tonga. This is weak in terms of technology, marketing and product quality.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What about further processing of local products - perhaps value-added agricultural activity ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Yes, this is something that we would hope to do, though the same kinds of problem arise. People don't set up the processing plant because they say there isn't enough local cultivation to make it worthwhile. And the farmers don't grow the crop because they say there is no market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· So it is 'chicken and egg' situation ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Yes. The result is that people only grow for home consumption.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I should mention here that there are other resources we have yet to exploit, notably in our waters. We have reserved these for ourselves and do not allow foreign fishing vessels. So we are trying to recover resources from the sea.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is also the possibility of drilling for oil. Research ships operating in the Pacific have found a limited number of locations where it would be worth looking for oil reserves and two of them are in our waters. We have been publicising this with a view to encouraging further exploration.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· This would presumably involve drilling licences for oil multinationals.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Yes. Some companies have done this in the past although only on a small scale. The answer we got from the oil companies is that they are interested in exploitation - but not now because of the low oil price. When the price goes up, I think we may attract interest again but that is clearly only a long term possibility.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· A lot of young Tongans leave the islands to work overseas. What is the explanation for this ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - It is true that a high percentage of our population migrates. These are people in search of a better life, who seek to reap the benefits of their abilities by working overseas. They can have a nice house and get a good education for their children.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I should stress that we have a good education system here but there is a heavy emphasis on gaining qualifications in order to get into the civil service. Where we are lacking is in the field of technical education. We have some facilities of course - an Institute of Science and Technology and a Marine Institute to train people to go to sea. This is very much in its infancy and we hope it will help for the future. But even some who have gone through this system end up looking for jobs overseas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Turning to political issues, you have a monarchy here which is still very powerful. Do you anticipate any changes in the system ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - There has been some public pressure for change. I don't think people want a radical upheaval but there is a feeling in certain quarters that the present system could be improved upon. As you probably know, Parliament has nine members elected by the people and a further nine selected by the 28 nobles from among their own number. The third component is the government -  12 ministers who are appointed by the King. It has been suggested that qualified people who don't presently sit in Parliament should be there to help deal with the economy. One idea is to change the Constitution so that whole population elects 30 members. The King would then choose his ministers from these 30.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Has this idea made any headway ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> -  No, not so far. We are maintaining the old system. The proposal has been aired but it hasn't been passed in the House. There are a lot of people, I think, who prefer the present system because they feel the monarchy works for the benefit of all the people. Would a new team necessarily stick to this principle? There must be a danger that they would tend to favour just one section of the population.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Can you comment, finally, on Tonga' relations with its partners in development cooperation ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - As you know, we have good relations with the EU through the Lom&eacute; Convention. We also have strong bilateral links with Australia and New Zealand which have been giving us assistance. But I think we have to face up to the fact that the aid cannot continue. The UK, for example, used to provide us with our judges. That has been taken over by Australia and New Zealand -  but for how long ? I think it is bound to be phased out.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So we will continue to have relations with our partners, but we need to recognise that they are concentrating their efforts now and adapt accordingly. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Profile</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">General information</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Area: 669 km². Tonga has about 170 small islands and four main island groups (Tongatapu, Ha'apai, Vava'u and the Niuas). It has an Exclusive Economic Zone of approximately 700 000 km,). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Capital: Nuku'alofa (situated on Tongatapu) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Population: 99 000 (1994 census) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Population density: 149 per kilometre² </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Life expectancy at birth (1992): 68 years Official languages: Tongan and English Currency: Pa'anga (T$) made up of 100 seniti. The currency is pegged to the Australian dollar. In September 1996, 1 ECU was worth T$ 1.57 (US$1 T$ 1.22)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p32.png"></center><br>
+ Tonga</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Polities</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">System of government: Constitutional monarchy based on the Constitution promulgated in 1875. Considerable powers remain vested in the King. The Parliament has 31 members  -  the Speaker, 12 ministers (including the Governors of Vava'u and Ha'apai) who are appointed by the King, 9 nobles chosen by the 33 members of the nobility and 9 People's Representatives elected by universal suffrage. There are no political parties although there has been talk of setting up a 'people's Party'. The twelve cabinet ministers hold office until they reach retirement age.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Head of State: King Taufa'ahau Tupou IV</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Prime Minister: Baron Vaea of Houma</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economy (estimated 1995 figures unless otherwise stated) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Annual GDP per capita: approx US $1900</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">GDP growth rate: -2% (1995/96)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Principal exports: squash, vanilla, manufactured goods and fish. In the early 1990s, squash accounted for more than half the country's total export income. In 1995, however, the harvest was affected by drought and exports dropped significantly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Balance of payments: A trade deficit of US $38.8m (exports  -  US $18.3m, imports  -  US $57.1 m). The current account deficit is much smaller thanks to 'invisible' earnings, notably from tourism and remittances from Tongans living overseas. Inflation rate (April 1995): 4.5%. Total external debt: T$ 44m (1993)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sources: Tonga in Profile (on the Internet -  http: 11l www. netstorage. com/kami/ tonga) Economic Intelligence Unit Country Report 1996. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Interview with peoples representative, Teisina Fuko</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'There is much more political awareness'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">People's representative, Teisina Fuko offers an alternative view</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While Tonga has no political parties, and the main levers of power remain in the hands of the monarch, it would be a mistake to conclude that there is no questioning of the status quo in this small Pacific kingdom. As The Courier discovered on its recent visit, Tongans are happy to speak openly about their political system and to criticise (or praise) aspects of it me local media may not be particularly extensive but it nonetheless allowe for different viewpoints to be expressed, including criticism of the authorities. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Those who advocate political reforms in Tonga face something of an uphill struggle. There is no overwhelming demand for change and although the lever of popular support for the current system is not easy to judge, there appears to be widespread acquiescence  -  which effectively amounts to the same thing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In recent years, the focus of 'opposition' has tended to be within the ranks of the people's representatives who sit in Parliament We spoke to one of these elected members, Teisina Fuko, who comes from the Ha'apai island group and began by asking how democratic the thought the system was.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I would say about 50%. Up until the 1970s, the system was very traditional but we now seem to be westernising quite quickly. People are returning from overseas with different ideas and this is having an impact on the way we are governed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Do you think you will ultimately have a Parliament whose members are all elected by universal franchise ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I would say it is more certain now than ever before. There is much more political awareness. We see it in the schools, where children are being taught to think independently. There are also the new economic trends -  commercialisation and the focus on foreign earnings which imply the need for modernisation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You sound quite enthusiastic about the 'westernisation' process. Are you not concerned about the possible negative aspects in terms of the survival of your traditional culture ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I think we have to strike a balance. We mustn't go to extremes. Our culture and traditions are important but there are new things we need to take on board and some old habits we should drop. Take business opportunities: we have to be more democratic in this area. If one group has all the power then they will tend to favour their friends which isn't necessarily efficient. What it boils down to is a lack of checks and balances.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Given the present economic difficulties, I also think we need to move quite quickly. I recently wrote an article arguing that the King should transfer his power to appoint ministers to the people. Ministers should be elected so that they can be accountable to the taxpayer. We are a close-knit family here and there is no question of getting rid of the monarchy. But we need to sit down and hammer out a compromise which will allow us to improve our economy and make it more competitive.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Let me give you a practical example. Defence is now third on our list of priorities. That doesn't make sense to me. We would be better spending the money on economic development. We also need to boost the private sector so it can create jobs, instead of tying its hands. At present, 50% of our revenue goes on paying civil servants. What for 7 It may create employment, but it is not productive. So the government has to be minimised. Having said this, there are some positive signs. I am glad, for example, to see new blood being brought into the ministerial team.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Parliament is currently composed of three groups - twelve ministers, nine nobles and nine people's representatives. On paper, that suggests that no group can dominate ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">- Yes, but the ministers and nobles often work together and we are  outvoted. It is difficult to imagine the nobles saying 'no' to the King although, to be fair, they do sometimes abstain and some of them recognise the need for certain reforms to the system.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Turning to the economy, which areas do you think offer the best development prospects ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">-  Tonga's potential lies in fishing. We are an island nation that has always depended on the resources of the sea and we have the necessary labour force. What the people need is the know-how  -  advanced technologies to develop this sector. We also have to set up credit programmes so that people can invest in boats and equipment. I believe we should spend a lot more on fishing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unfortunately the government does not take the same view. It has put a lot of resources into small industries, airlines and so on. Yet the reality is that these sectors are in decline. Manufacturing has fallen and so have agricultural exports. Fishing is the only sector that is expanding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· What about the prospects for agriculture ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I think we have reached the limit in this sector. There is very little scope for expansion. I also believe we should be concentrating on what we can produce to use locally. There is very little more we can do in terms of commercial exploitation. Tonga is somewhat overcrowded and we cannot use too many chemicals because the water table is so low.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· One local issue, which presumably has economic implications, concerns the possible expulsion of foreigners who have been here for a certain amount of time. Apparently, the decision has been taken not to renew certain residence permits. What is your view on this ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I think Tonga should encourage skilled people who are here to stay. We should use make use of their skills, particularly where they have expertise that is lacking locally. At the same time, there are some people here who just came for a visit and ended up staying without doing anything very productive. There are also a number who came after the coup in Fiji and I think we should give them some leeway.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the whole, I don't think it is a big problem. Tonga has traditionally been very liberal in the application of its immigration law. We have never been colonised so we tend not to have a suspicion of foreigners. And whatever we do must be in accordance with the law.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Could you sum up your vision for the future ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> -  You only need to look around you to see that we have a youthful population here: a lot of young people who need to be catered for. We are investing heavily in education which I think is good but we need to do more to adapt to the changing world. We were peaceful in the past because most Tongans were on roughly the same level in terms of wealth. Now the poor are getting poorer while the rich get richer. This could lead to an increase in social tensions. With a more democratic system, we should be able to close the gap and work for a peaceful and more prosperous future. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Seeking business overseas</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">New Minister outlines economic strategy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If the policy of appointing Ministers for life - or at least until retirement age - is maintained, then Dr Giulio Masasso Tu'ikolongahau Paunga can look forward to a long career in the Tonga Cabinet. At just 32, he has recently been been given the job of Minister for Labour, Commerce and Industries (with responsibility also for tourism). He may be relatively young, but the new minister has impressive academic credentials. He took a master's degree in Japan (in Japanese) and as we soon discovered, he has some new ideas about how to achieve economic development in his country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dr Masasso's portfolio covers a wide range of economic activities and we began by asking what he thought the main focus of his work would be. He identified three areas  -  agriculture, which is the single most important sector; fisheries which has potential for growth; and tourism. He would also like to see more manufacturing, particularly for export, but acknowledged that the current prospects in this area were very limited.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Looking first at agricultural production for export, we noted that a significant change had taken place over the last decade. Coconut-related products had been largely replaced by squash, a 'gap' in the Japanese market having been identified when other sources of supply were not available. Tonga may have been the first to spot the opportunity but was there not a danger that other countries might 'muscle in'? The government was 'very aware of this danger', said the Minister and was trying very hard to diversify its export products. He mentioned vanilla, papaya, beans and, in particular, carrots. The last-mentioned crop grows well in the islands and there is apparently a growing taste for carrot juice in Japan. A list of products with export potential, which could be grown successfully in Tonga, had been drawn up in cooperation with the Ministry of Agriculture, and Dr Masasso's department would be actively seeking new business overseas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The government is obviously interested in developing trade with Japan and other countries in Asia, but the Minister felt that New Zealand and Australia were likely to remain the principal markets for Tongan farm products in the future. He was looking forward to easier access to New Zealand once new quarantine facilities had been set up at the international airport on Tongatapu. This, he said, should allow for a larger throughput of export crops.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Efficiency, of course, is the key to winning and keeping overseas customers. With this in mind, our discussion turned to the land tenure system. The allocation (at least in theory) of parcels of land to all male Tongans discourages the development of larger farms or plantations. Was this the most effective way of exploiting the country's fertile lands? Dr Masasso acknowledged that the system hampered efficiency but stressed that the question was a very sensitive one. The right to cultivate a plot of land is deeply rooted in Tongan culture, and radical changes to the property laws are not on the agenda. As the Minister put it; 'We are trying to maximise our efficiency under the present system of land tenure.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Turning to tourism, Dr Masasso observed that 'this has been the most stable industry over the past ten years,' bringing an average of T$ 12 million into the country every year. In looking at possible growth, however, he stressed the need to take account of the environmental and cultural impact. 'Tonga is a very small country, and it would not be right to build too many hotels and related facilities. It might be possible, but the long-term effects would be a little too much for the country.' Dr Masasso said he favoured tourism which has 'e closer relationship with people -  a cultural exchange, targeting people who really wish to understand our country.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fishing is a sector which appears to have huge potential given the size of Tonga's exclusive economic zone. Dr Masasso explained how Japanese assistance was being used in a boat building scheme designed to produce vessels that local people could afford. He also spoke enthusiastically of the research that had been carried out to determine the nature and size of the fish stocks. He recognised, however, that while most of Tonga's fishing was inshore, there was scope for a great deal more revenue from deep-sea fishing. In this connection, negotiations were underway with the United States, Taiwan and Japan, to allow vessels from these nations to fish in Tongan waters. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The conversation then moved on to the more general issue of entrepreneurship and the role of the state in the economy. The Minister indicated that the government believed in privatisation but stressed that this was not simply 'because other countries are doing ft.' The main issue at this stage, he said, was to create a sufficiently large pool of well-trained people to take over activities currently run by the authorities. 'The government wishes it didn't need to get involved but we are a small developing nation, and to get things started, you need capital and know-how  - which locals sometimes don't have access to.' In these circumstances, the state had to activate projects which could later be privatised once the necessary skills had been built up. Another 'major strategy' was to develop a much closer relationship between the Ministry and the private sector.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This led us into a discussion about Tonga's attitude to foreign investors who might also be in a position to supply capital and know-how. The authorities had recently threatened that a number of residence permits would not be renewed. Was this not a disincentive to potential overseas investors ? Dr Masasso was keen to offer clarification. 'The media makes it look as if Tonga doesn't like investors but they have misinterpeted the situation. He insisted; 'we want the foreign investment here and are encouraging it in those areas where locals cannot get involved.' Defending the actions of the immigration authorities, the Minister stressed that what they were doing was normal practice. 'Those who stay here illegally and do not extend their visa have to be deported.' The action, he argued, was not directed against foreign investors and indeed, the latter should be encouraged by the government's commitment to upholding the law.' </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Tonga-EU cooperation</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Developing the Vava'u islands</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Myfanwy van de Velde</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">EC-Tonga cooperation began in 1975 with the first Lom&eacute; Convention, soon after Tonga gained full independence in 1970. Grant aid totalling ECU 19.8m (Lom&eacute; I - Lom&eacute; IV) has been allocated to the country during its 20-year membership of the Convention.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under Lom&eacute; I, funds were directed principally towards two main projects: the construction of the wharf at Neiafu, Vava'u, and funding for the Ministry of Works to procure road maintenance equipment and build schools, rural health centres and small wharves at Ha'apai and Vava'u. Remaining funds were used to finance studies involving dredging, trade promotion and designs for Vava'u and Faua fisheries harbours. The EIB also financed a line of credit of ECU 130 000, under Lom&eacute; I, to the Tonga Development Bank.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lom&eacute; II funds focused on the fisheries sector, and on initiating works relating to the upgrading of the Vava'u airport. There were also projects in the fisheries sector, aimed at encouraging fishermen to undertake commercial fishing to meet local demand. To this end, the Faua Fisheries Harbour for small boats was built, and marketing and cold storage facilities were provided.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By the time Lom&eacute; III funds came on stream, Tonga had adopted a regional development approach with regard to its various island groups. The aim was to have a coherent development programme taking account of the specific constraints and potential of each. The Vava'u group of islands became identified as the focal area for the use of EC assistance, and Lom&eacute; III resources (ECU 6.5m in grants and ECU 0.5m in the form of risk capital to be managed by the EIB) as well as Lom&eacute; IV funds (ECU 6m and ECU 1 m respectively) have duly focused on its development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Located in the north of the Kingdom, Vava'u is the second group of islands both in terms of population (16 000) and land area. With an abundance of natural resources, the group is thought to have greater potential for agriculture and tourism than other parts of the Kingdom. However, this potential was largely untapped at the time Lom&eacute; III was initiated. This was due to a variety of constraining factors including relatively low productivity, undeveloped marketing infrastructures, substantial import levels and poor distribution of utilities and other public services. One particular constraint preventing the development of tourism was limited access caused by a lack of transport infrastructures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Two main projects aimed at addressing these problems have been implemented. The first, costing ECU 1.24m, involved completing the upgrading of the local airport at Lupepau'u (begun under Lom&eacute; II). In addition to runway improvements, a new terminal building was provided, complete with safety and navigational equipment. Passengers began using the new facilities in early 1995. The second project, entitled the 'Vava'u Development Programme', was allocated the sum of ECU 5m. This money is being used to pay for a series of activities including road upgrading, the provision of photovoltaic equipment for household energy needs and the supply of equipment for vocational training colleges. New buildings being funded include health clinics, a market and an agricultural quarantine building. The funds also cover the cost of establishing the Vava'u Development Unit as the monitoring and implementing agency for the programme.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Programme continues under Lom&eacute; IV, with about 85% of programmable resources for Tonga (approximately ECU 5m) set aside for activities in the focal area. Funds will be directed towards developing the Neiafu urban area, in recognition of the need to upgrade access and services in the commercial centre of Vava'u. The projects envisaged include upgrading the town centre and urban roads, port improvements, and measures to increase the capacity and improve the distribution of piped and rain water to households. In addition, a multi-annual micro-projects programme will lead to the construction of jetties on the inhabited outer islands of Vava'u, thereby improving access to Neiafu which is the main centre of the archipelago.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition to the above grant aid, Tonga has received funds in the form of Stabex transfers for losses in export earnings in respect of coconut products, bananas and vanilla. It also received emergency aid in 1977, following an earthquake, and in 1982 following Hurricane Isaac.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">EIB interventions have contributed to the share capital of the Tonga Development Bank and have increased the Bank's lending capacity to small and medium-sized enterprises. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Switching on the Iights</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Uelingatoni Tevita Vaea (known as 'T' to his friends), proved to be a mine of information for The Courier, when we visited the Vava'u island group in northern Tonga recently. 'T' is a Tongan engineer who returned to his native land from Australia to work as assistant project manager in the Vava'u Development Unit. His help was particularly useful during the highlight of our visit - a traditional celebratory feast laid on by the villagers of Nuapapu. This is one of Vava'u's inhabited outer islands and the celebration was staged to mark the installation of solar powered lighting, courtesy of Lom&eacute; Convention funds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nuapapu is one of a number of outlying villages to receive solar installations under the Vava'u Development Programme. In all, some 350 homes have been wired up. Units attached to individual buildings collect the power and convert it into electricity which is stored in a battery. When night falls, the lights can then be switched on. Although the bulk of the installation costs are covered by the project, each participating household is required to pay a lump sum to have a unit fitted. They are also contracted to pay a modest amount each month towards maintenance of the system.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It may all seem rather prosaic to those of us accustomed to electrical power at the flick of a switch, but for the people of the villages in the Vava'u group, the project is little short of revolutionary. For centuries, their daily rhythm has been governed largely by the rising and setting of the sun. The only 'artificial' light available after darkness came from fuel-burning (and more recently, battery) torches or lamps  - enough perhaps to reveal a path or highlight the position of an object, but certainly not to read or do intricate work with one's hands.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The formal 'switching on' ceremony was performed by the Dutch Ambassador, Mr van Thessen and Jonathan Rodwell, who is the European Commission's resident advisor in Tonga. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This was preceded by a courtesy visit to the village chief and the above-mentioned feast, which gave the European visitors an authentic and memorable taste of traditional Tongan hospitality.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The food was brought from all quarters of the village on long rectangular trays covered with leaves. Each was laden with food.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The fare was predominantly local: the famous roast pigs featured prominently along with fish, chicken, bananas, coconuts and a variety of root and tuber vegetables.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There were also some 'imported' items: the corned beef which is so popular here, some packets of crisps to add colour to the guest 'table' and boiled sweets woven into garlands.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The trays were laid end to end, stretching perhaps 20 metres and woven mats were placed all around. Having received our garlands of flowers, we were invited to sit down.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The feast was interspersed by various speeches and 'T' helped out with a translation and explanation of the proceedings. We began with a prayer in Tongan, delivered by the local minister. This was followed by a speech of welcome and thanks by the matapule (spokesman) of the village chief.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">High ranking people in Tonga always have a matapule to speak on their behalf on such occasions. Ambassador van Thessen and Mr Rodwell then replied on behalf of the guests, (in English, with consecutive translation provided).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They expressed thanks to the people of Nuapapu for their hospitality and wished them success with their new electric lighting. There was then a short discourse by the District Officer followed by a closing prayer.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">References to all this speechmaking could leave a false impression that this was a formal and stilted affair.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In fact the reverse was very much the case: the mood was relaxed throughout and there is no doubt that the villagers know how to enjoy themselves. Music was supplied by a group of men playing a variety of instruments and the women joined in the festivities with what appeared to be spontaneous bursts of dancing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There were also special solo dances performed by two young ladies whose bodies had been smeared with coconut oil.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As tradition dictates, once their performances (involving highly expressive hand and finger movements) were complete, the audience expressed their appreciation by slapping banknotes on the oily exposed surfaces of the dancers' bodies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The light was fading as the feast ended and we moved to the brief 'lighting up' ceremony, carried out to the accompaniment of applause.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The guests (including the staff of the Vava'u Development Unit who have guided the project through its various stages) then took their leave of this hospitable community and set off by boat on the return journey to Neiafu. As the vessel drew away from the shore, we were able to look up and see, for the first time, the twinkling lights of Nuapapu. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Dossier</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Habitat</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Livable cities and rural rights</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(Dossier coordinated by Debra Percival and  Claude Smets)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The United Nations Conference, Habitat 11, on human settlements (Istanbul, June 3-14 1996) exposed the Herculean task of addressing the problems of ever-growing cities and called for 'shelter for all.' The special contribution of civil society in making cities more liveable was acknowledged at the conference - but the big question is, who will foot the bill ? The meeting also spoke of improving dwellings in rural areas to keep people on the land and halt the mass exodus to the cities. But the right to remain and prosper from one's habitat can be at odds with outside pressures for environmental conservation. The dossier looks at some of the issues raised by the conference, and the wider significance of 'Habitat II' </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The second UN gathering on the theme of 'habitat', staged two decades after the first conference in Vancouver, took place against a backdrop of rapid and alarming urban growth. In 1900, one person in ten lived in a city. By 1948, the ratio was three in ten and by the year 2000 half the world's population are expected to be urban dwellers. 25 years after that, the figure is expected to have climbed to 60%. Africa is the region that currently has the highest rate of urban growth. In 1950, it had only one city with a population of one million. By the end of this decade there could be 60 cities of this size, according to UN figures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The focus on human settlements and liveable cities inevitably meant that Habitat II covered some of the same ground as other UN conferences convened during the 1990s to explore the big issues facing mankind: the 1992 'Earth Summit' on environmental matters in Rio de Janeiro, the 1994 Population Conference in Cairo, the 1995 Social Summit in Copenhagen and the 1995 Women's Conference in Beijing. Issues common to all the agendas included rapid population growth, environmental degradation, access to clean water, poor sanitation, lack of infrastructures, and women's issues.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The rallying calls of Habitat II, set out in the Conference's conclusions, were 'shelter for all' and 'sustainable human settlements in an urbanising world.' The Nairobi-based Centre for Human Settlements is to be the focus for the follow-up. But as delegates dispersed, one of the pressing questions was where the money will come from to meet the host of agreed objectives -  which include clean water with improved technology, conservation and protection of the environment, and better health and education. In this dossier, European Commission officials from the Development Directorate General, who attended the conference, reflect on Istanbul and its likely followup.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Whereas in the past, cities were associated with economic development, innovation and the diffusion of new ideas, nowadays they conjure up the vision of urban poverty, environmental degradation, poor sanitation and a host of health hazards. Urbanisation is the direct consequence of rapid population growth, according to the 1993 Human Development Report. In 1965, agriculture provided 77% of employment in developing countries and represented more than 41 % of Gross Domestic Product. By 1985, this sector was contributing a lot less to GDP but was still providing 72% of all employment. So a large number of people continue to depend on agriculture although its share of the global economy is declining. In these circumstances, it not surprising that many of the world's poorest people are migrating to cities - the annual estimate is 20-30 million.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The dossier looks, in particular, at the environmental cost of rampant urbanisation and at the problems of city living for more vulnerable groups such as women. They are often among the poorest urban dwellers and can fall victim to exploitation and crime.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Paradoxically, poor people in cities are becoming even poorer as economies improve. Additional pressures on these marginalised groups living in cities are neatly summed up by Jeremy Seabrook, author of 'In the Cities of the South.' In a recent article for Gemini news agency: 'Tougher Struggle for Survival in the Concrete Jungle,' he writes; 'As the pace of development quickens, with high economic growth and increased migration to urban areas, land price in most big cities have soared. Poor people are being increasingly removed from their hoary" - by mysterious fires, explosions and 'accidents'. Meanwhile, the urban poor's ability to mobilise and achieve has been used against them. The capacity of people to create homes and secure local communities has been used as a justification for the withdrawal of government services.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He continues: 'As inequalities become more glaring, enclaves of prosperity are sealed off from the slums by checkpoints, guards and fences - like frontiers to another country. Despite this, people are still flocking to the city  -  often refugees from intensifying, industrialised agriculture and.. megaprojects in the countryside...' Mr Seabrook points out that without decent jobs, they fall prey to sub-contractors, who exploit them, offering them low pay and demanding that they work long hours.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Civil society</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the cities of many developing nations, 'civil society' is taking a lead, with projects to bridge the gap between the 'haves' end the 'have note'. Numerous participants at the Istanbul conference applauded the urban programmes undertaken by various elements of civil society, which include NGOs, community groups and individuals. Their significance was recognised in Istanbul, where their voice came through loud and clear. Nigerian journalist, Paul Okunlola, writing in this dossier notes a move towards 'bottom up' projects in Lagos as a result of the tough times.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agostinho Jardim Gon&ccedil;alves, the President of the NGO-EU Liaison Committee, was particularly pleased at the input of civil society to the conference's committees and conclusions. The debate, he said, had not just been about the macroeconomic aspects. Instead, it had come 'within the reach of the populations themselves.' The people, he argued, were both victims of the anomalies of inhumane settlement and the key players in efforts to construct a humane, dignified habitat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jeremy Seabrook describes some of the inspiring international initiatives undertaken by civil society. Examples include the Society for the Promotion of Area Resource Centres (SPARC) in Bombay, which works with pavement dwellers; the Association of Basic Needs (ARBAN), and 'Health for All' in Dhaka; the Eddie Guazon Foundation in Manila, which seeks to protect the poor against private interests; and the Foundation for Women, which is trying to tackle the trafficking of girls for Bangkok's brothels. But Mr Seabrook also warns against overestimating the strengths of popular organisation. As he points out: 'They require an enabling and positive framework, which the free market can never provide. Government intervention, of a more benign and positive kind than hitherto, is vital if people are to help themselves. As it is, too often they are forced to struggle against the people elected to govern them.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The chair of the Habitat Conference, Wally N'Dow, emphasised local solutions. The conference, he said, 'recognised the changing global patterns of life' and that solutions must be found at the local level. 'National governments and international agencies', he argued, were not in a position to solve massive urban problems or to pay to put them right.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There were a number of donor pledges at the conference. The European Union countries, for example, reiterated their long-standing commitment to provide 0.7% of GNP for development by the year 2000  -  though many of the 15 member states are still well short of this target.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One scheme which has attracted the particular interest of donors is South Africa's Reconstruction and Development Programme (RDP). To a considerable extent, the success of President Mandela's government is likely to be judged on the success of this programme. It aims, among other things, to improve health, education, housing and sanitation and as such, it mirrors many of the 'Habitat II' goals. Launched in 1994, it is the centrepiece of the South African government's efforts to create a more democratic, prosperous, non-racial and non-sexist society. In the dossier, we look at the RDP's objectives, how it is faring and what sort of support the EU is giving.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rural rights</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Beyond the city, the dossier looks at what is happening to some rural dwellers who have not taken flight to the city. Although, largely focused on the city, Habitat II acknowledged the importance of urban and rural linkages in its conclusions: 'Rural and urban settlements are interdependent... governments must work to extend adequate infrastructure and opportunities to rural areas to increase their attractiveness and thereby minimise... migration.' There was mention too of the need for more jobs and housing for rural areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But in some rural areas, the inhabitants have found themselves in dispute with conservationists. The latter seek to protect wildlife and the rural habitat by setting up national parks - a solution which is not necessarily in the interests of local people struggling to maintain their livelihood. We take a look at such dilemmas and the possible solutions being developed so that rural dwellers can continue to make the most of their habitat. This rural struggle, where solutions are also being called for at a local level, is not unlike the battle being waged for a better quality of life in the cities. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Towards a global concept of urban development - an interview with Daby Diagne</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Deputy mayor of the city of Louga, Daby Diagne is also President of the Finance Committee of Senegal's National Assembly, General Secretary of the Association of Mayors of Senegal and President of the World Federation of United Cities. He is the ACP-EU Joint Assembly's General Rapporteur on urban development and The Courier had the opportunity to interview him in September at the Assembly's meeting in Luxembourg.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You have just submitted an initial report on urban development to the Joint Assembly. In it, you recommend that the Community adopt a specific and consistent global policy in this field, notwithstanding the fact that successive Lom&eacute; Conventions have contained a number of significant provisions relating to the subject. What is the reasoning behind your recommendation ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - There are several reasons. First, there is the fact that, in the past, cities were often viewed solely in terms of infrastructures and sectors. Experience shows that this approach is not effective. Specialists are increasingly opting for a more global 'city' concept. The Commission must therefore adapt itself to the new situation. It is true that it has financed infrastructures and launched health and clean-up programmes, but the problem is that this has been done in a somewhat unsystematic way without being linked to long-term regional development or a zonal policy. There is now an increasing need for an integrated regional development approach. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Do you think ACP countries are aware of the importance of cities ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">That's another question altogether. Obviously, the ACP countries are in the process of changing their views on this subject and a number have appointed ministers to look after urban affairs. The reality of city life has to be taken into account. The rate of urban growth in the ACPs far exceeds that in other parts of the world and it is in the towns and cities that one sees the most glaring instances of poverty and under-development. People have therefore been forced to take the 'city' phenomenon into account in the ACP countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The political will must exist for a policy to be successful. Do the ACP countries have a genuine will to implement an urban policy ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I don't think it is possible to speak of a uniform trend in all ACP states. However, in certain regions - for example in West Africa, which I know well - a municipal culture is beginning to take shape. There is a growing political will, which is illustrated by the discussions on decentralisation, and people are increasingly recognising that central government cannot do everything by itself. One can find regional development and planning policies designed to create the fabric of mediumsized cities. Not everyone has them but it is something we are seeing more and more of.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· ACP countries face complex challenges and there are people who say that the actions of the European Community are too dispersed owing to the number of sectors it is involved in. Doesn't your recommendation simply add to this problem ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - On the contrary. I regard my recommendation as being pro-integration and therefore pro-globalisation  - which is not the complete opposite of a sectoral, diversified approach. I believe it would allow the Union's activities in certain fields to be better interlinked. I am thinking here of water, health, clean-up operations and infrastructures  - all of which are major problems for society. Naturally, a more global concept will require greater dedication, and if there are additional resources, so much the better, but, in my view, the situation could be improved even with what we currently have available.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The rate of urbanisation in Africa is higher than elsewhere and the living conditions of city dwellers - particularly those in the shanty towns  -  are becoming increasingly difficult in terms of health, education, environment and so on. What, in your opinion, would be the optimum strategy for reversing the decline, at least in the short-term ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - First of all, I think we have to make a distinction here. Let's take the actual rate of urbanisation. Contrary to what is generally thought, this is lower than in the rest of the world. In other words, Africa has fewer towns and cities than the rest of the world. It is the rate of growth in the urban population that is higher. Populations are becoming increasingly concentrated in the cities, with the drift of people from the countryside. In addition, the phenomenon is being fed by demographic trends. You ask me if there is anything we can do to halt this. There are actions that can be taken to restore some balance. For example, we could make investments in the rural environment to keep people in the countryside, and we could implement suitable agricultural policies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But we must not labour under too many illusions, because life in towns and cities will be an inevitable characteristic of the next century. Economists and urban planners have been considering the phenomenon for a long time now - perhaps 30 or 40 years. It is  something that cannot be halted, because it is a fact of civilisation. So, what should we do? Above all, we should devote our efforts to regional development, achieving a balanced distribution of human resources, and a more equitable exploitation of natural resources. Power has to be decentralised so that people do not abandon their roots but face up to local challenges. And we have to implement urban policies which are satisfactory in terms of investment, management and popular participation. In simple terms, urbanisation has to be managed. We cannot hope to reverse the trend overnight, particularly in the case of a continent like Africa where everything happens quickly. Africa is enormous and its population has not yet reached its maximum levels. We have to take all this into account.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We must acknowledge that scientific progress and improvements in the field of health have contributed to population growth, and a reduction in mortality rates. This means that urban civilisation is a reality that we have to manage. There is a risk of uncontrolled growth in urban centres. When infrastructures are lacking, when there is no water, when hygiene cannot be guaranteed and when there is no work, a country's security is threatened.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You have mentioned democracy end the decentralisation of government This also requires adequate financial resources. Where do you think the ACP countries will find the money to implement decentralisation strategies ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Democracy involves a search for freedom - freedom of opinion and expression, independent of material or financial problems. The problem with decentralisation lies in administrative method. It is not purely a matter of money. In the first instance, it is a question of choosing the right approach. It has been demonstrated that without any extra resources, one can still act differently by delegating and decentralising. And success is much more likely because the people are involved in the process. Admittedly, it requires an internal reallocation of resources. A proportion of everything that was formerly centralised has to be allocated to development and to basic needs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To answer your question more directly, there is a great deal of talk of this alternative method of governing. It is inspiring new hope and a thirst for something better. It is even being viewed as an 'ideal' solution - which it cannot be entirely. However, by decentralising human and economic resources, and by allowing people to participate, hope can be inspired at local level. This should make for better administration and support, which is an improvement in itself. Of course, this may make people more demanding. Will it satisfy their requirements? As I have already said, internal resources will have to be reallocated, but resources must also come from outside. One cannot make an allout effort for decentralisation without doing something to improve international cooperation. This cooperation, however, must be adaptable, and the state must retain its pre-eminent position and its role as guarantor and arbiter. But in addition, local communities should have access to international cooperation either directly or indirectly through their organisations, municipal structures and so on.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· In this context, what role do you see for international organisations - not just in terms of financial resources, but also of human resources ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I think what we now need to do is build up a pool of skills in each municipal area. The developed countries have experience in this field. We have to take their processes as a model without necessarily copying their experience. This is something which will be discussed. Secondly, in the context of relationships between towns and cities, I believe it is possible to make access to experts more flexible and that this can take place very quickly, with the provision of training and fairly basic technology transfers. General training is also extremely important. In order to build up a pool of skills in towns and cities, local government must form a dynamic, management-oriented team. The approach has to be one of business-like management and objectives have to be targeted using private-sector methods, although public-service requirements always have to be borne in mind. A great deal, therefore, can be done at international level, in terms of support for networks of associations and committees of locally elected representatives, enabling them to discuss matters.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We could, for example, carry out a comparative study of legislation in a particular area, thereby gaining access to other types of experience. Internationally, aid can be given to associations to help them buy equipment and attain a degree of freedom of manoeuvre vis-&agrave;-vis the authorities. In the field of decentralised cooperation, the international community can help elected representatives to implement their projects through partnerships, conducting studies, and providing personnel. Cooperation is possible in all spheres -  implementation, management, financing and so on. I believe that a new type of cooperation will gradually come into being. It is not a question of creating 'white elephants', but rather small and medium-scale projects which are of genuine use to the population. And I am not talking here about acts of charity, such as the donation of medicines, but sustainable projects. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Habitat II: taking stock</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Christian Cure'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The future of towns and cities is not what it was. In the 20 years between the first United Nations conference on human settlements (1976) and Habitat II which took place in Istanbul in June 1996, the situation has changed a good deal. The significance of urbanisation  - and its irreversible nature -  are now acknowledged, as is the powerlessness of the authorities to deal single handedly with the complex phenomena which result The author of this article points out that civil society has suddenly broken into a field hitherto the preserve of official agencies and qualified experts, claiming a 'right to the city' based on research into more equitable development models.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vancouver to Istanbul: two symbols for two eras</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Vancouver was the 1976 host of the first conference on human settlements organised by the United Nations. At that time, the UN was celebrating 30 years of existence and Vancouver, a model of urban development and modernity, provided inspiration for the developers and experts needed to plan the cities of the future. 'Appropriate technologies' heralded the possibility of mass-produced, cheap housing for everyone.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Twenty years later, the UN chose Istanbul as the host city for the Habitat II conference on human settlements, forcing us to face up to a quite different situation: uncontrollable urban growth (400 000 migrants arrive there every year), social and environmental problems, and intercultural and political tensions (amply illustrated by the Turkish politicians' inability to form a government at the very time the Conference was taking place). In brief, Istanbul presents us with the usual list of problems facing most of the world's major cities - and those of developing countries in particular.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Against this backdrop, the international community  -  180 countries, 500 local dignitaries, a few thousand professionals and even some ordinary citizens - came together from 3 to 14 June to discuss a 'settlement action plan'. This document, which had been in preparation for two years, contains 183 articles. It sets out a series of goals, principles and undertakings as well as providing an action plan for cities, the initial results of which should begin to be seen by the year 2001.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The preparatory committee selected two basic topics for discussion: securing adequate shelter for all, a basic but nonetheless controversial theme; and sustainable urban development The latter encompasses housing, demographic factors, infrastructure, services, the environment, transport, energy, social and economic development, the future of underprivileged groups and combating exclusion.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The cycle initiated at the Rio Earth Summit in 1992 (followed by the Copenhagen, Beijing and Cairo meetings) was continued by Habitat II. Two major handicaps had to be overcome - 'conference fatigue' (with the resulting fact that there were fewer delegates than anticipated) and ensuring that what had been accomplished at earlier conferences was not undermined. Given that the subject of the meeting was human settlements, it was inevitable that sensitive issues already debated at previous summits, relating to the environment and social aspects, would keep recurring.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Civil society as an active force</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A number of conclusions arose from the official sessions (hearings, dialogues and various forums) which took place over the two weeks of the conference.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">First, Habitat II represented a recognition of the fact of urbanisation. In the past, there was a tendency on the part of the international community to play down, or even ignore, the phenomenon of urban growth and this was reflected in the meagre resources allocated to this area by donors. Today, the issue is better understood than it was 10 or 20 years ago, and it is acknowledged that the growth trend is unstoppable. Statistical studies and a set of 'urban indicators' drawn up for Habitat II confirm the scale of the problem. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Second, the Istanbul summit was a lesson in modesty. The obvious powerlessness of public authorities to deal single-handedly with the challenge of burgeoning towns and cities is recognised. The result was an understanding that a more pragmatic view is needed -  one which pays more attention to the complexities of urbanisation, to the wide variety of possible responses and, above all, to the multi-faceted nature of the players involved.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Conference therefore became a genuine forum for debate. One of its most significant aspects was the emergence of 'civil society' as an active force. Hitherto, the field has largely been the preserve of official agencies and qualified experts. For the first time in a UN forum, local authorities, community leaders, private sector representatives and other dynamic forces in civil society were invited to give their views and take part in discussion groups. Whereas in the past, the debate was dominated by macroeconomic and technical questions, in Istanbul, the political and social aspects were given prominence as well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The effect of this was to improve the quality of the debate. The outlines of a new relationship between governments and civil society (NGOs, ordinary citizens and popular urban groups) were defined - with the local authorities slotting in somewhere in the middle. And there was a particular focus on the question of dimension or scale: what should be the basis for urban democracy and citizenship. Both of these are seen as essential if one is to have successful and sustainable urban development policies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A right to the city?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first stage of the analysis is to look at urban life from a macroeconomic standpoint. Urban growth is determined by the evolution of the world economic system and, in particular, by the globalisation of markets. This has generated increased competition, including competition between cities themselves. Since the end of the 1980s, cities have been responsible for between 50% and 80% of the GDP of most countries. In other words, they represent more than mere links in the global economy; they are, in fact, pivotal points.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hence the principles which broadly underpin the Habitat 11 programme. In fundamental terms, public policies must promote the capital, housing, property and employment markets, with a view to improving the efficiency of urban management (living conditions, infrastructures, services, environment, etc.). This is not just desirable in human terms but also essential if urban productivity is to be improved. Many decision-makers at the meeting agreed that privatisation of services, partnerships involving the authorities, the community and the private sector, and decentralisation were all part and parcel of a new standard for good local governance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Representatives of 'social' interests, on the other hand, were successful in focusing the debate on fundamental rights and principles, including individual and social rights. Indeed, these issues dominated the Conference and gave rise to the most difficult negotiations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There were prolonged talks, for example, on the central issue of the right to a roof over one's head. The outcome was a commitment by governments to promote 'the full and progressive acceptance of the right to adequate shelter'. The NGOs had been hoping for a more clear-cut undertaking. Questions relating to the status of vulnerable groups, women's rights and their equal access to land, and protection against eviction, were also the subject of heated exchanges.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Perhaps the most important step forward, however, was the success of civil society representatives in sowing the seeds of a new idea - the 'right to the city'. This concept has been devised on the basis of research into more equitable and soundly-based development models to which local authorities are increasingly giving practical support. Thousands of individual experiences and issues were highlighted in Istanbul by NGOs and community groups. Thus, there is a mass of evidence that populations are capable of responding through local initiatives and of taking responsibility for improving their living and housing conditions. If this 'resource' is to be exploited to the full, urban politicians must develop a deeper understanding of the scale of micro-territories and local societies within cities. They also need to promote and coordinate their decision-making in a way which involves consulting and involving the local populations. In the modern era, this is the key to ensuring social cohesion.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Beyond Istanbul</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There may have been a lot of new thinking on the basic principles, but there was no reference to financial undertakings in the Habitat 11 programme. On the latter issue, the international community was highly circumspect.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The World Bank took the initiative, announcing the launch of an 'urban compact', involving an additional $15 billion in loans for urban projects over the next five years. It also revealed that it would triple its aid to NGOs involved in the urban environment. Recent World Bank estimates suggest that just 0.2% to 0.5% of a country's GDP would need to be set aside for the poor to gain access to basic urban services.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As regards monitoring, the NGOs and local authorities won the right to sit on the Human Settlements Committee which will be responsible for implementing the habitat programme.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The most important points to emerge from Istanbul, however, were that local authorities were given both formal recognition, and a major practical role - in keeping with their current responsibilities. The habitat programme is, in fact, a powerful call for decentralisation and increased local autonomy, its action plan being built on the implicit principles of 'subsidiarily' and 'proximity'. To a large extent, the successful implementation of the programme will depend on the mobilisation of municipal politicians and officials - and on the policies they adopt at local level. The agenda for cities in the 21 st century that was adopted at the Rio Summit must now be fleshed out and become the future reference for action by local authorities, NGOs and citizens' associations. Finally, the importance of decentralised cooperation and the role of local councils in international cooperation have been reconfirmed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Local authorities and their international organisations decided to form a worldwide coordinating group to continue structured dialogue with the international community and to guarantee that the Istanbul resolutions are followed up.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some people predicted that Habitat 11 would be 'the revenge of the cities'. To quote P. Maragall, chairman of the Committee of the Regions, the conference at least provided the opportunity to build, and to give a wider audience to 'the voice of the United Cities within the United Nations'. That itself is a major step forward. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">'A house to call my own'</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tackling violence against women</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Rosemary Okello</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The author of this article is a journalist with the Nairobi-based Women's Feature Service (WFS) She contends that the Habitat 11 conference skirted around some of the issues affecting women city dwellers in Africa, such es violence and sexual abuse. Improving their lives, she argues, starts with a roof over their heads</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The lofty ideals set during this year's UN Conference on Human Settlements in Istanbul meant little to African women like Catherine Kaberu. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As she recalls the misery of living on the streets of Nairobi, she is just happy now to have a safe, secure room for her family. 'I thought by running away from home and coming to Nairobi, I would find a better life" says Ms Kaberu. Instead, the streets became her home and her life was defined by the fear of violence against her. Her two children were born during that difficult period, following rapes. She cannot identify their father. There are an estimated 30 000 street people in Nairobi and Catherine Kaberu says that all street women and girls are regularly abused.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'Every day we had to look for a place to sleep and we bribed the watchmen to guard us.' Often it was the same watchmen, employed to guard office blocks in the city's central district, who took advantage of the women's desperate situation. Not even age could protect them says 63-year old Felista Nyambura, herself a veteran of the streets. 'I suffered all manner of humiliation,' she states, referring to ten years spent on the streets with her seven children. 'The watchmen would rape me if I refused to give in to them - after they had offered me a place to sleep for the night with my children. I am just so happy to be off the streets. I will never go back,' she states firmly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The confidence of the two women comes from their new security as owners of simple one-roomed houses.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'Having a house to call my own is the most important thing that ever happened to me,' says Ms Nyambura as she explains how she ended up on the street after the piece of land her husband left in their rural home was taken over by her in-laws.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The two women are part of a group of 114 who have benefited from the Urban Destitute Programme, a project of the African Housing Fund which is involved in participatory community development with the homeless women of Nairobi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Catalina Trujillo, the 'Women in Development' coordinator for the Habitat conference stresses: 'If a woman's place is in the house, we had better make sure she owns it.' These sentiments were supported in Istanbul by the conference Secretary General, Wally N'Dow: He stated: 'By conviction, by analysis and even by instinct, women's rights to ownership and inheritance of property is right. If Habitat II... does not also contribute to social progress by addressing some of the issues like property rights for women, then it will have failed.' </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For the women of-Africa in particular, the most important thing that should have come out of Istanbul was an affirmation of their right to own and inherit property, and to security.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These issues affect most African women regardless of their status and they were presented to ministers concerned with shelter and settlements when they met in Johannesburg last year to prepare an African agenda for the Istanbul meeting.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Most African countries accept the theoretical premise that women must have access to land, credit and inheritance, and recognise that certain types of violence are targeted primarily at women. South Africa's President Mandela affirmed: 'When we talk about people-centred development, we should understand that the involvement of women is often the difference between success and failure.' Yet in reality, customary law and insensitivity to gender concerns continue to predominate. Unfortunately, when the African ministers adopted their declaration, the point on the "unencumbered access of women to credit and land ownership' appeared in only 20th place. And while forced evictions were highlighted in Istanbul, violence against women did not feature at all among the 'key priorities'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yet in parts of Africa these are major concerns affecting women every day. 'In South Africa, a women is raped every 83 seconds and in some areas, a girl can expect to be raped four times in her life,' says Emelda Boikanyo of the Johannesburg-based Women's Health Project. Idah Matou remembers how one Sunday morning in 1992, five men stormed into her shop in Alexandria township. They seized the day's earnings and anything else they could carry away before raping her 1 5-year old daughter. A few weeks earlier, they had called to demand protection money.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Violence in the home is also a growing problem. Mmatshilo Motsei, Director of Agisanang Domestic Abuse Prevention and Training, an NGO based in Alexandria, South Africa, says the problem is so pervasive, 'it must be raised as a national concern.' Habitat II turned a deaf ear on these women's concerns. This was not their forum. Shawna Tropp of the NGO Women's Caucus criticised those attending the conference who claimed that it was not about women but cities. 'Women live in cities,' she says and adds: 'By and large, human settlements are still very much seen in terms of bricks and mortar'. She calls for greater understanding of the role played by women, usually in an unpaid capacity, in the management of communities. 'Everything begins with having a house in a secure neighbourhood where the dignity of women is protected.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Megacities</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The megacity personifies human misery for many in developing nations. As agglomerations proliferate in the twenty-first century, the United Nations Population Fund's 1996 report - The State of the World Population  -  considers how one might go about remedying the ills of city dwelling.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The UNFPA's figures for urban growth make worrying reading. Over half the world's people will live in cities within ten years (3.3 billion out of a total of 6.59 billion). Between 1970 and 2020, the urban population will have risen by more than two billion - and 93% of these will be in developing nations. These increases will add to the strain of an estimated 600 million people already living in urban areas of developing nations without the resources to meet their basic housing and health needs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Back in 1950, New York was the only city with more than 10 million inhabitants. Today, there are 14 in this category. Tokyo, which is home to 26.5 million people, is the largest. And by 2015, many others are expected to join the megacity 'club'  -  Djakarta (Indonesia), Karachi (Pakistan), Dhaka (Bangladesh), Delhi (India), Tianjin (China), Manila (Philippines), Cairo (Egypt), Istanbul (Turkey), Rio de Janeiro (Brazil), Lahore (Pakistan), Hyderabad (India), Bangkok (Thailand), Lima (Peru), Teheran (Iran) and Kinshasa (Zaire).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While the majority of the world's people will be living in cities by 2005, it will take a little longer for the 50% threshold to be crossed in the less developed regions. However, this is expected to happen before 2015. Looking specifically at Africa, the current estimates reveal significant regional variations. In Southern Africa the rate of urbanisation is 48%. The figures for North, West, Central and East Africa are 45%, 36%, 33% and 21 % respectively.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Expanding populations are likely to add to the widely reported list of horrors emanating from cities that are bursting at their seams. Problems include the collapse of basic services such as water and waste management, escalating social conflict, millions of urban children open to labour exploitation, sexual exploitation, environmental degradation, traffic congestion and environmental hazards such as increased air pollution.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the other hand, the UNFPA report acknowledges that cities are also 'concentrations of human creativity and the highest form of social organisation'. It continues: 'Cities provide capital, labour and markets for entrepreneurs and innovators at all levels of economic activity'. Indeed, between 60% and 80% of developing countries' GNP is generated by their major conurbations. Social transformation occurs at a faster pace in urban areas. Thus, health indicators tend to be better, literacy is higher and there is more social mobility. And there are more opportunities for women. The city presents fewer obstacles for women's education and female city dwellers are less likely to be constrained by traditions which may stifle their creativity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But harnessing this potential is no easy task. The final chapter of the UNFPA report, entitled 'Policies, strategies and issues for improving cities', argues that urban dwellers in developing nations have been badly affected by structural adjustment policies. These have resulted in the elimination of subsidies on food and other commodities, increases in school fees and job losses in the public sector. Cities will also be required to adapt to the 'mass global experience in decentralisation' involving the shifting of local decisions from central government to municipal authorities, parastatal bodies and the private sector.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p48.png"></center><br>
+ Regional distribution of urban population</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Women - a priority</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The report stresses the importance of improving education and health, with a particular focus on women. As Dr Nafis Sadik, who is Executive Director of the UNFPA, observes; 'If urban centres are to be made liveable, and the quality of life of the poorer members of society is to be improved, women should be given the chance to play their role in the process.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The report reiterates the specific targets for improving the lives of women that were drawn up by the 1994 International Conference on Population and Development held in Cairo.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the field of education, these include 100% primary school enrolment (for both girls and boys) by 2015, improving access for girls and women to secondary, tertiary and vocational education, and closing the gender gap in the primary and secondary sectors by 2005.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other goals include a progressive reduction in infant and maternal mortality, making reproductive health services accessible to all through the primary health care system by 2015, greatly improved provision for family planning (allowing couples to make free and informed decisions on the number, spacing and timing of births) and providing better protection against sexually transmitted diseases.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The State of the World Population Report concludes: 'A successful urban future depends, as much as anything else, on engaging all members of the community - especially women and the poor  -  in a constructive political process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There will have to be partnerships struck between governments, nongovernmental organisations, the private sector, and local and community organisations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">And global urbanisation will require that the international community  -  governments, NGOs and international institutions - act to exploit the potential of cities to improve the lives of the world's people and to establish the foundations of sustainable development in the 21st century.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Lagos under stress</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Paul Okunlola</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With a present population of some 7.5 million, the new millenium will propel Lagos to megacity status. The United Nations Population Fund predicts that 24 million people will live in the city by 2015, making it the third most populous conurbation on the globe. Whilst the donor community has supported urban projects in the past, tough times mean more reliance on 'bottom up' schemes backed by N60s and community-based groups.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When it began to rain in the small hours of Thursday 18 July 1996, residents of Lagos -  Nigeria's largest city and economic nerve centre -  merely stirred in their slumber. The gentle, but persistent showers, didn't rank among the heaviest downpours experienced by this coastal city, which gets rain on average for eight months in every year. Nor are Lagosians unfamiliar with spells of rain lasting up to seven days without break.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But by the time of the early morning 'rush hour', the traffic-laden streets of metropolitan Lagos were being swept with rampaging floods. Until well after noon, the city's social and economic life was at a standstill. Already difficult road conditions were rendered impossible for motorists, marooned at the wheel for hours. Exhausted school children eventually made it back home after spending the better part of the day in traffic. Crowds of commuters waited interminably at bus-stops for vehicles that never came.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The economic toll was expected to be heavy, with offices in both government and the private sector remaining empty all day. Commercial activities were put on hold as shops remained shuttered until well after noon. The communications network and electricity supply to key areas of the city were shut down for hours, to protect equipment. One state government official commented: 'It has never been so bad.' By the time the water receded and life had returned to normal, both government engineers and private sector consultants were in agreement: the main reasons for the flooding were illegal development along the natural courses of inner-city waterways, and the reduced drainage capacity of the overdeveloped metropolitan area.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Exploding metropolis</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Both the flood itself, and the acknowledgement of the human limitations of the city officials, illustrate the frustrations that have attended the management of this exploding metropolis over the last three decades. In the months leading up to the July flooding, a major controversy erupted over plans to landfill the inland Kuramo lake in the highbrow Victoria Island district and develop it as a housing estate. This pitted state government officials and a firm of developers on the one hand, against a motley band of citizens groups, non-governmental organisations and concerned environmentalists on the other.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The unusual strength of local feeling against the project reflects growing fears that the island itself could be submerged. Five years ago, this was thought to be a remote prospect but today it is seen as a real threat, given the increasing frequency of flooding incidents and ocean surges along the coastal area.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More and more people are arguing that there is a correlation between the growing frequency of flooding incidents and the massive sandfilling activity that has taken place over the years. The Kuramo issue remains contentious but it is just one example of the wider dilemma facing the city's development planners. They have the daunting task of providing for legions of migrants to Lagos - whose swelling numbers are placing great stress on the failing infrastructure. The problem may be particularly acute in the Nigeria's largest city, but it reflects a wider trend of urbanisation in the country over the past half century, as the overall population has increased.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1921, Nigeria had just 18.7 million inhabitants. Current estimates put the population in the region of 103.5 million. And the growth in the proportion of urban dwellers has been equally dramatic. In 1931, fewer than 7% of the people lived in urban centres. The figure had risen to 10% by 1952,19% by 1963, 33% by 1984, and 42% at the last count, in 1991. Current figures suggest that there are now seven Nigerian cities with more than a million inhabitants and no fewer than 78 whose population exceeds 100 000.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The changing structure of the country's human settlement profile has been linked to broader economic and social changes. The situation has been exacerbated by the economic depression of the last two decades. Analysts have noted a trend of declining primary production in such areas as agriculture, mining, quarrying and exploitation of natural resources. This has resulted in greater attention being paid to secondary and tertiary economic activities -  which are generally city-based. The figures illustrate the dramatic nature of the change that has taken place. In 1952, the ratio of primary to secondary/ tertiary economic activity, as measured in Nigeria's GDP, was 68:32. Four decades later, the ratio was 38:62.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">According to World Bank consultant, Prof. Akin Mabogunje, the trend is exemplified by the expansion of a whole range of activities located in urban centres -  large, medium and small-scale enterprises in manufacturing and construction, utilities, transport and communications systems, wholesale and retail outlets, hotels, restaurants, finance and insurance companies, and estate agencies. Then there is the whole range of government activity. Until 1991, Nigeria's huge federal bureaucracy was located in Lagos, operating alongside a state administration and some 15 local authorities. Add to this the major docks and airports of Lagos, and you get an urbanisation phenomenon which has, to say the least, been intimidating.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lagos, which only occupies 0.4% of the country's land area, gains an extra 300 000 inhabitants every year on top of its natural growth rate. That the city is a 'pole of attraction' is hardly surprising. It is clearly the economic nucleus of the country, reputed to account for about 57% of total value added in manufacturing and about 40% of the nation's most highly skilled manpower.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Urban toll</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The costs have also been high. Professor Poju Onibokun, a human settlements expert, enumerates these: grossly inadequate housing and infrastructure with millions dwelling in slums; social amenities under enormous pressure with a shortage of schools and poor health facilities; endemic crime and juvenile delinquency; the breakdown of traditional values, family cohesiveness and community spirit. The capacity of law enforcement institutions is also increasingly hampered by technological and resource limitations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Of these ills, the shortage of housing and lack of infrastructure are seen as the most acute. This is borne out by a recent World Bank study which notes that:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - the quality of life and living conditions have deteriorated;</P>
+<P ALIGN="JUSTIFY"> - economic production has plunged;</P>
+<P ALIGN="JUSTIFY"> - the inadequate provision of infrastructural services has negatively affected the operations of most private sector investors, who now need to spend between 22% and 25% of their capital outlay on providing their own infrastructure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over 90% of the city's housing is provided by the private sector. But this has been handicapped in recent times by spiralling development costs and a general shortage of funds. New private housing has consisted largely of thousands of individual units, built mainly in areas of existing large scale developments. The authorities have made their own efforts to plug the gap and over the last 15 years, no fewer than 6000 hectares of marshland have been sandfilled and reclaimed in six separate development schemes (some of which have proved controversial). The Land Use Act of 1978 vested all urban land in the state authorities, although the administration of the legislation has not always proved satisfactory.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Public transport is another problem for Lagos residents. There is no integrated system of mass transport and the sector is essentially made up of hundreds of privately operated buses and a dwindling taxi fleet. Massive currency devaluations have meant that the purchase price of new vehicles has rocketed. Maintenance costs for the increasingly dilapidated fleet have also spiralled. As a result, the system is stretched to beyond its capacity and it is the commuters who bear the brunt.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Public sector spending obviously has an important part to play in maintaining urban structures. The downturn in international aid flows has, therefore, had a visible impact with decline in infrastructure provision and maintenance, leading to a less favourable operating environment for private investors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the past, Lagos has been a notable beneficiary of urban support programmes with multi-million dollar schemes for water supply, storm water drainage, and infrastructure. Most of these have been World Bank-led but the support of the European Union and its Member States in this area is also considered crucial.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the positive side, adversity has proved a catalyst for greater community-based and NGO activity in environmental and human settlement issues over the last decade. This is a fresh approach, based on 'bottom-up' strategies, which should open up muchneeded new avenues to urban management in Nigeria more generally and in Lagos in particular. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">A Eurocrat in Istanbul</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Gilles Fontaine</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The author, a specialist in urban development, offers us his thoughts on the Istanbul conference. This event, he believes, was a landmark in the collective process of raising awareness which was begun at the Rio Conference on the environment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">14 June 1996 - last day of Habitat II</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Night fell a long time ago. A feeling of hope permeates the hall. Most of the work is completed but there are still disputes over a few paragraphs of the text of the Habitat 11 Agenda. Some delegates have not slept for two days and they can be seen standing around, afraid they might fall asleep. The sense of fatigue increases further when, at midnight, the symbolic 'stopping of the clocks' (to permit a successful outcome of the final negotiations) is announced over the PA system.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At two in the morning, the wait has become almost unreal. It is virtually unimaginable that the Conference should come to nothing, after two years of intense work. Since Wednesday evening, the general atmosphere has been almost euphoric. Agreement has been reached on all the essential points within the allotted time and the Conference is already being heralded as another success story. All that remains to be done is to finalise the 'Istanbul Declaration', a four-page policy text broadly summarising the work of the Conference. The Conference would finally close about two hours later, amid general relief - but why the impasse?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Breaking new ground... and remaining steadfast</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some problems arose where they were least expected! To everyone's surprise, 'informal' working sub-groups had to be set up to discuss nuclear testing and anti-personnel mines! These themes were a far cry from the Habitat Agenda, but this sort of thing inevitably happens at major international conferences.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other stumbling blocks appeared without any real warning, when some delegates attempted to renegotiate the conclusions of the Beijing and Cairo conferences. The negotiators had to stand firm on two counts. The hard-won recognition of women's rights needed to be defended all over again. And, more importantly, the attempt in Istanbul to reopen the debate on everything that had been gained at previous conferences had to be avoided. The European Union's negotiators took an aggressive stance on both these issues.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The fact that so much negotiating effort is expended is a good illustration of the political significance governments attach to the topics debated on such occasions. A conference may be seen as resembling the proverbial half-bottle of water  - some regard it as half empty and others as half full. One's viewpoint depends on one's expectations  -  and much disappointment is caused by a misunderstanding of how such conferences operate.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Meeting the delegates</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although I am no anthropologist, I think I was able to identify three major groups of participants. First, there were the 'negotiators', who have built up a common language from conference to conference. I was surprised at the extent to which reference was constantly made, in the negotiating groups, to the 'Languages' of Rio, Copenhagen or Beijing. This is not just a question of vocabulary or syntax, but represents a genuine revolution in thought at international level.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The second group, to which I myself belonged, was made up of national and international officials. These are the people who, to a greater or lesser extent, prepare the conference. They then attend it and, ideally, write a mission report on returning to their offices (bemoaning the fact that few people will read their words of wisdom !)'These delegates tend to offer the harshest judgments. A common refrain is: 'We have long argument about words in parenthesis in a huge document that no one will ever read!'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The third group, which nowadays is the largest, consists of representatives of so-called civil society. Since Rio, every United Nations conference has seen the parallel organisation of an NGO Forum, and the latter's influence has constantly increased. At Beijing, the authorities banished the NGO Forum to a site 60 km from the capital, but Istanbul welcomed it with open arms on the same footing as the 'Cities Summit' and the meetings of researchers and industrialists. A more fundamental development was the invitation to NGOs and local authorities to take an active part in the working groups and at meetings. This was a 'first' in international conference history and I was struck by the motivation and competence of many of the participants, as well as by the ease with which they have adapted to the information society. Gone are the days when addresses are exchanged on scraps of paper, accompanied by the ritual 'We must keep in touch!'. These days, your business card must include your Internet Email address. Contacts are organised through networks connected to databases, and people swap CD ROMs with each other.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What did Habitat II achieve?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 'official' end most visible result of the Conference was obviously the adoption of the Habitat Agenda - the final fruit of long hours of work within the national committees set up for the occasion. This document, over a hundred pages in length, contains a 'World Action Plan', accompanied by the 'Istanbul Declaration'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What is not so well-publicised is the fact that many countries  -  including a number of ACPs  -  took the opportunity to publish their own national reports containing individual action plans. The amount of preparation that went into these reports revealed a high degree of motivation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Having looked at them more closely since, I have gained a somewhat better understanding of the months of work put in tens of thousands of people across the world. This reassures me that the majority of state participants will monitor the Habitat 11 follow-up very closely.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One has to recognise that the mere adoption of a text, however significant it may be, cannot be regarded as a magic formula which will change the face of the world overnight. To the impatient among us who want everything straight away, and to unrepentant sceptics, I would say this. In environmental matters there are two major periods in our recent history - the period before Rio and the period after Rio. The Rio meeting, and each subsequent conference, have been milestones in a long, coherent process of collective reflection and growing awareness. Istanbul did, in fact, keep its promises: the right to adequate shelter is now recognised internationally as the fundamental right of every human being.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The exploding city</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Stephane Yerasimos</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Istanbul. Ten million inhabitants - with double that number expected in 20 years time. Financial irregularities, a chaotic house-building sector, a lack of infrastructure and rampant speculation. One needed to look no further than the host city to find the key issues facing the Habitat Conference.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Istanbul is a city steeped in history. It is also one of the Third World's biggest conurbations. Over the last 16 centuries, it has been the capital of two great empires - the Byzantine and the Ottoman - resulting in a rich legacy of monuments and a historic centre on a par with that of Rome. From the Middle Ages to the beginning of the modern era, it was regarded as Europe's largest city. On the eve of the Second World War, it had a population of one million, but that figure has now multiplied tenfold. Almost half of its ten million inhabitants are living on a knife edge, and many are in 'illegal' housing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first big transformation of the city came in the middle of the 19th century when the Ottoman authorities opted for westernisation and embarked on an extensive management programme. By the time the Empire collapsed in 1922, much of the ancient fabric - and traditional housing -  of the city had already been lost. Under the new republic, the capital was transferred to Ankara, and the authorities stepped up their efforts at modernisation. In 1937, Ataturk gave Frenchman Henri Prost, a city planner who had helped preserve the old centres of a number of Moroccan towns, the job of devising major public works in the heart of the old city. The infrastructure was also updated and taken together, these works (which were completed during the 1950s) transformed the old walled city and its ancient suburbs (Galata and Uskudar) into a modern aggLom&eacute;ration, interspersed with ancient monuments.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mass immigration</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unlike the colonial powers who attempted to preserve the traditional character of old city centres around the Mediterranean rim and in the rest of the Islamic world, the desire of successive Turkish governments to modernise the country resulted in the disappearance of most of Istanbul's ancient fabric, and the city no longer has a compact area of old districts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The transformation of the city centre was matched, after the Second World War, by an explosion of building on the outskirts - a phenomenon characteristic of Third World countries. Improved sanitation and hygiene standards led to a natural population increase of between 2.5% and 3% per year. Meanwhile, the modernisation of agricultural practices caused a mass rural exodus. Marginalised in both economic and social terms. the people who flooded into Istanbul soon over whelmed the resident population. Today, the bulk of the people living in the city have rural origins.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The new residents began by occupying the edges of the old quarters and taking over the open spaces which remained after the ravages of an earlier fire. They then began to settle in ever-increasing circles around Istanbul, establishing the first gecekondu districts (groups of huts constructed overnight). These have been incorrectly described as shanty towns. In fact, most buildings are permanent structures and they rapidly develop into multi-storey dwellings. Most of the land on which these illegal buildings have sprung up was originally privately owned. But the elected multi-party government in power at the time was quick to spot the electoral possibilities in these areas. Each district was a reservoir of potential voters and, on the eve of each election, the parties in power would distribute property titles to the illegal occupants. They, in turn hastened to consolidate and increase their assets. This explains the emergence of increasingly densely populated districts without infrastructure during the 1950s and early 1960s</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Industrialisation, and the arrival in the city of people who used to be rural landowners (driven out by the new market economy) later created a demand for housing which the normal market was unable to meet. This has given rise to a new phenomenon of urban marginalisation, involving the illegal division of land into plots. The system involves the purchase of agricultural properties by developers and speculative builders. These are divided into small plots and resold, quite legally, to purchasers  -  who then build unauthorised structures in contravention of the normal planning rules. Often, benefiting from political alliances, the developers take control of these districts and 'convert' the votes of the people living there into cash, in return for urban investments. This enables them to consolidate their power and increase the value of their remaining stock of plots.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An uncontrolled population increase</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, a third phenomenon, linked to the growth of a middle class, began to occur in the mid-1980s, when building cooperatives came into being. Their predecessors were the corporate associations which grouped together public officials (beginning with the army and the police). These developed into ad-hoc associations enabling a group of developers to tap people's savings, thereby dispensing with the need for loans in a country where chronic inflation makes credit prohibitive. Several thousands of dwellings are often constructed at the same time, in the form of tightly packed, multiple-occupancy blocks. The requirements of multi-storey construction mean that these buildings are of acceptable quality, but the related infrastructures are sorely lacking. Entire districts are built 'in the wilds' without any infrastructural investment by the developers or local authorities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The city is continuing to expand, without reference to any development plan. The fifteen or so major urban schemes drawn up since the 1950s have all remained in desk drawers and the only significant construction work has been on roads (notably bridges and ring roads). These generate further uncontrolled population increases on the outskirts of the city.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although the natural rate of demographic growth is slowly declining - it has just dropped to under 2% per year -  the most recent census (in 1990) reveals that Turkey now has more people living in its cities than in its rural areas. Yet the statistics also show that half of the country's people are still involved in agriculture. Given the continuing natural growth, and the fact that in semi-industrialised countries, the rural population tends to settle at around a third or even just a quarter of the total, we can assume that the drift to towns and cities will continue for the next 30 or 40 years. This trend will affect all Turkish towns and cities, be they large, small or medium-sized. But Greater Istanbul, where the majority of the country's economic and social activity is concentrated, is set to experience a doubling of its population within the next twenty-five years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dilemma for urban planners</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The problem caused by demographic changes is exacerbated by economic constraints. For a number of years now, Turkey has suffered a high (albeit stable) inflation rate of about 70% per year. This situation discourages investment in industry, and makes people take refuge in ownership of land that they can build on. Land has thus become the target of speculation by people in all social classes. Against this background, it is virtually impossible to regulate the use of land  - something which must be at the heart of any urban-development programme. An alternative is to discuss the possibility of developing a social consensus involving a more liberal approach to property speculation, recgnising that land is a source of revenue at all levels. This might entail releasing central and local authorities from any responsibility to provide services or other infrastructural investment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the present circumstances, however, any scheme to redevelop Istanbul effectively would seem doomed to failure. The only intervention which might succeed would be at the 'cleaning-up' stage - coming in after the construction of the dwellings under the conditions described above. It is only once the new inhabitants' dream of having a roof over their heads is realised that they come face to face with the harsh daily realities of living in a self-built city of nearly ten million people. They may then be prepared to make some sacrifices in order to improve their living conditions. The moment when harsh reality replaces emotion, is the only time the urban planner has the slightest chance of being listened to. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Adequate housing in the EU: rights and realities</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Misia Coghlan</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are 2.7 million homeless people in the European Union and many millions more are badly housed. But the EU is said to be lagging in taking measures to provide adequate housing - one of the internationally recognised human rights. An expert from a leading campaign group for the homeless explains.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rights</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the weeks and months leading up to the Second United Nations Conference on Human Settlements (Habitat II), much argument and debate centred around the existence of the right to adequate housing. The legal basis of this right was challenged by a handful of delegates and the arguments continued right through the Conference itself. The outcome is that the final Declaration includes a reaffirmation of states to a 'commitment to the full and progressive realisation of the right to adequate housing as provided for in the international instruments.' (see first box)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The political impact of Habitat II as the culmination of the recent series of UN Conferences has been disappointing. The Istanbul Conference was originally heralded with the catch-phrase 'housing for all'. In the course of the preparatory process, this was watered-down to become 'shelter for all' and, as has been seen, the wording of the final Declaration simply refers to existing international commitments and allows for the 'full and progressive realisation of the right.' This of course begs the question of how such a right was ever supposed to have been achieved other than 'progressively' and how meaningful such a commitment can be in the absence of parallel undertakings as to implementation and enforcement. In short, very little has been achieved in progressing international commitment to the realisation of the right.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The right to adequate housing has in fact been recognised for some time now by the Member States of the European Union, all of whom have ratified the 1966 International Covenant on Economic, Social and Cultural Rights (the most important legal basis of housing rights found in international law). Under article 11(1), the parties to the Covenant recognise, 'the right of everyone to an adequate standard of living for himself and his family, including adequate food, clothing and housing...'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The concept of 'adequacy', it is generally acknowledged, is determined at least in part by social, economic, cultural and climatic factors. Adequate housing can be understood as including the following components: legal security of tenure, affordability, habitability, accessibility, location and availability of services, materials, facilities and infrastructure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It hardly needs pointing out that commitments in international law, whether legally binding or not, remain statements of intent and are of limited practical use unless accompanied by a comprehensive legislative framework in domestic law which will secure both the access to the right as well as providing enforcement mechanisms. What, then, is the reality ? Has the right to adequate housing been enacted into national legislation and, most importantly, is the right actually being respected across the European Union?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Realities</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FEANTSA, the European Federation of National Associations Working with the Homeless, has been conducting the European Observatory on Homelessness with the support of the European Commission since 1991. FEANTSA's research findings have increasingly demonstrated both the extent and the gravity of the housing crisis in Europe: in what is one of the wealthiest subregions of the world, a large and growing group of the population is being excluded from adequate housing. (see box on next page)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moreover, FEANTSA's 1995 transnational research report (Home/essness in the European Union) has found that the right to housing does not exist in any Member State as a legally enforceable claim. Although the right is recognised in the constitution of several Member States, this remains a statement of intent and does not create any entitlement. Other Member States have adopted a different approach - housing legislation in the United Kingdom, for example, does create an obligation on the local authorities to provide housing for those homeless people assessed to be in priority need and found to be unintentionally homeless. There is no sign of convergence in the ways EU Member States address the right to housing and housing exclusion in their national legislation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The right to housing is not addressed in EU legislation as a legal principle and Member States have exclusive competence to deal with housing issues themselves. There is thus no overall European housing policy, nor is there yet any European policy on homelessness. FEANTSA has, however, identified common trends throughout Europe which have contributed to the escalation of homelessness and the lack of adequate housing provision.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The overall European trend has been an increased reliance on the competitive market to meet all housing needs, with an unwillingness on the part of government to commit public resources to assist lower income groups, who are therefore confronted with the limited choice available to them on the open housing market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The supply of housing has been undergoing change throughout Europe. In all countries, owner-occupation is on the increase, with tax relief generally being offered as an incentive. The private rented sector, on the other hand, has continued to decline. Social housing has generally suffered from cuts in funding. The result is that there is a shortfall in the supply of affordable housing for rent and rents have become correspondingly higher. It is clear that the competitive housing market cannot and will not meet the needs of the increasing numbers of people without the resources to afford market rents.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The type of housing required has also changed: demographic trends have meant that households are getting smaller but more numerous - thus, there is a need for more but smaller dwellings.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The problem has been exacerbated by the lack of an overall strategy either at European level or, indeed, often at national level, to meet the realities of structural changes on the labour market. Indeed, in some countries, the increase in long-term unemployment has been accompanied by an erosion of social protection systems. Faced with escalating demand for longterm welfare assistance, the authorities have often responded by tightening up on eligibility criteria in an attempt to cut or limit benefit payments, with shortterm palliative measures to deal with emergency cases. Thus, increasing numbers of people living on or under the poverty threshold, coupled with the deregulation of the housing market, have led to severe housing stress and increased vulnerability to homelessness.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finland sets an example</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finland is one EU country tackling the housing problem. In 1987, the International Year of the Homeless, the Finnish government announced its intention to eliminate homelessness. At that time, the number of homeless people was put at close to 20 000. The programme for the development of housing set the objective of making 18 000 homes available for the homeless over a period of five years. Special funds were set aside in the national budget to permit the local authorities and other organisations to purchase housing for the homeless. State loans for the construction of housing for rent were made available to municipalities with a large homeless population. In under ten years, the number of homeless people in Finland has been reduced to half what it was in the mid-1980s. Finland now enjoys a comprehensive system of carefully targeted housing supply, housing subsidies, benefits and allowances and housing is seen as an integral part of a multi-dimensional strategy to combat poverty.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For one in twenty citizens of the European Union, the criteria which, as a whole, constitute adequate housing remain inaccessible. Yet at Istanbul, the EU voiced its determination to make an important and constructive contribution to the implementation of the Habitat objectives. This included an acknowledgement that increased attention should be paid to people living in poverty and that appropriate action should be taken by governments at all levels.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European housing ministers were due to meet informally in Dublin, on 24 and 25 October of this year, specifically to tackle the question of 'housing for socially excluded people'. The time has come to devise and implement coherent strategies to prevent housing exclusion for low income groups. The market has neither the ethics nor the long-term planning capacity to do this; it remains the responsibility of the state. It can only be hoped that the housing ministers will recognise this and agree on the necessity of protecting housing as a product and as a service from the competitive market, at least for vulnerable groups. The housing ministers have been holding informal meetings since 1989. This year's meeting provides the opportunity, particularly in the light of the Habitat II debate, to exchange information on effective measures to help low income groups access and maintain a home. The result should be the drafting of a number of concrete goals to be achieved within a realistic time-scale.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Homelessness in Europe is not on the scale seen in other regions of the world - with the development and reinforcement of effective preventive policies, based on proven and cost-effective welfare models existing in some Member States, the housing crisis can still be contained. In short, where there is a political will, there is a way. Europe has the potential to serve as a model of good practice to the rest of the world and should do so, more especially in the light of all that was - and wasn't  - achieved at Istanbul. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">References</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Is the European Union Housing its Poor ? Dragana Avramov, Catherine Parmentier and Brian Harvey, FEANTSA, Brussels 1995 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Homelessness in the European Union, Dragana Avramov, FEANTSA, Brussels 1995</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Invisible Hand of the Housing Market, Dragana Avramov, FEANTSA, Brussels 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Cities of the Third World</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Francis Cass</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In ten or so years' time, more than half the world's population will be living in built-up areas and, according to UN figures, by 2025 nearly two thirds of us will live in towns and cities. This is not a complete surprise -  over the last few decades, the ratio of city dwellers to rural people has consistently moved in 'favour' of the former. In 1950, 29% of people were city dwellers. Since 1985, the urban population has exceeded 40% of the global total.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Today, we are witnessing an acceleration in demographic growth, especially in developing countries. Of the 2.6 billion people who currently live in towns, 1.6 billion live in the world's least developed regions. By 2025, the urban population of the Third World will have risen to 3.2 billion, out of a global urban population of just over 4 billion. On the basis of these figures, it is estimated that the number of urban dwellers in developing countries is increasing by approximately 150 000 people each day! In Cape Town in South Africa, for example, as in many towns and cities of the Third World, this demographic explosion can actually be seen happening. All you need to do is drive regularly along the N2 motor way  - which passes through the shanty towns of Khayelitsha and Guguletu -  to see how, week by week, the makeshift dwellings are spreading - gradually expanding to every available plot of land. The same scene is repeated in all of Africa's large towns. In Cot&eacute; d'lvoire, the population of Abidjan rises by 400 inhabitants a day on average. In Gabarone, the capital of Botswana, whose population was barely 3000 at the time of independence in the 1960s, the population is increasing by 18% each year and today 160 000 people live there. Such growth is often accompanied by widespread indifference on the part of local authorities. Such indifference is due, in particular, to a shortage of financial resources, but it also reflects an absence of political will to do anything to tackle the problem.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Demography and poverty</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The demographic explosion which has taken place in the urban areas of developing countries is due to three main factors: natural population growth, rural emigration to towns and cities, and (less importantly) the redefinition of the administrative boundaries of built-up areas. The first two factors are equally to 'blame' but in future, it is predicted that rural depopulation in Africa will become the single most important element in urban population growth. This will be especially true of countries where there is rampant rural poverty. In this context, we need to recognise other circumstances, such as famine, desertification, a shortage of cultivable land and conflicts, which serve to exacerbate the phenomenon. If people living in the countryside decide to migrate to towns, it is because they are looking for a better life and hope to improve their standard of living. Few succeed. According to a World Bank study, 50% of people in abject poverty will be living in urban areas by the year 2000.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The effects that urban poverty has on the environment are often dramatic. The reverse is also true. A damaged environment constitutes a daily hazard for town and city dwellers, in particular the most destitute. The precarious nature of their living conditions means that only in extremely rare cases are these people able to guard against the degeneration of their immediate surroundings. Driven to the outer limits of the towns - where even basic infrastructures such as sewers and the collection of household waste are often lacking, the poorest sections of society are left to fend for themselves. Local authorities have neither the means nor (often) the inclination to do anything to help them. Even those who are comfortably off and who can afford to give part of their income to safeguard their immediate environment (thereby protecting themselves to some extent) cannot escape the consequences of more general ecological problems such as air pollution and the contamination of water supplies. Living in a modern house in a well-to-do district is simply not enough. It is not possible to shield oneself completely from the problems created by environmental destruction. For example, even an unofficial rubbish tip, located several kilometres away from a residential area, can have disastrous effects on groundwater - meaning that sooner or later, the quality of the drinking water will suffer.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Towns gasping for water...</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At present, the vast majority of Third World towns are facing a series of ecological problems which directly or indirectly, affect the lives of their inhabitants. According to the World Health Organisation (WHO), 220 million city dwellers have no access to drinking water and 420 million have no latrines. It does not take much to imagine the potentially catastrophic health consequences of such a situation - in which people are forced to drink and irrigate their land with water from contaminated sources. The WHO has estimated that three million children died during 1993 as a direct result of diarrhoea, and that nearly two million of these victims had consumed drinking water contaminated with faecal matter. In developing countries, 90% of waste water is poured, completely untreated, into rivers, lakes and coastal waters. Again, one can easily imagine the impact on marine flora and fauna, and on the health of those who eat the products fished from these waters.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">...and gasp for breath</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As far as air quality is concerned, the WHO intimates that more than a billion city dwellers throughout the world breathe highly polluted air. For the most part, this pollution is generated by industry and motor vehicles. A small improvement has been recorded in the urban areas of developed countries, but air quality in the towns and cities of the South has deteriorated considerably during recent years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are many reasons for this. First, there has been an increase in industrial activity, mainly concentrated around towns and cities. This is a result of economic development, but also of the fact that many factories - including some with the worst pollution records  - have relocated from the North to the South, where legislation governing emissions is less stringent. Second, in contrast to the trends seen in developed countries - where cars are usually well-maintained, (running on unleaded petrol and rarely more than five years old) motor vehicles in the Third World -  whose numbers are increasing significantly  -  are frequently old, badly maintained and run on leaded fuel. According to the World Bank, 95% of the lead polluting the air in the towns and cities of developing countries comes from vehicles which run on leaded petrol and studies carried out on the subject have revealed concentrations of up to 1.5 microgrammes of lead per cubic metre of air. In North America and Europe the concentration varies between 0.2 and 0.8 microgrammes per cubic metre.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another problem facing towns and cities in the southern hemisphere arises from the enormous amounts of waste they produce and from the fact that they have few treatment facilities. In many cases, the rubbish is not even collected and is left to accumulate into the piles which can often be seen on the edges of shanty towns. This accumulation of refuse encourages the proliferation of certain diseases and poses a real threat to the health of residents both nearby and further away. In addition to this ordinary, everyday waste, the countries of the Third World have to deal with problems generated by toxic waste  - not just their own, but also that which is 'exported' there by industrialised countries. Needless to say, the towns which actually have the means and facilities needed to treat this highly polluting waste are few and far between.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Linking development with environmental protection</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While environmental problems have a direct impact on human health and on the natural world, they also entail huge economic costs. The effect of pollution on human health translates into ever-increasing health costs and a decline in productivity. And it is not only city dwellers who suffer the consequences of a deteriorating urban environment. Depending on their size, the degree of industrial activity and population concentration, towns and cities pollute and destroy areas well beyond their own administrative boundaries. They swallow up enormous amounts of natural resources, suck their hinterlands dry and spit out 'what is left'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nowadays, there is an increasing global consensus over the need to tackle these growing problems rapidly. This was seen clearly at the Habitat II Conference in Istanbul. Most cities of the southern hemisphere urgently need to get to grips with their numerous ecological problems - the alternative is to sink further into chaos. In a similar vein, it has become obvious that some sort of balance must be found between economic development and safeguarding the environment - and that considerable investments are needed to achieve this.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Solutions do exist. Recycling projects, for example, could provide jobs for large numbers of town and city dwellers, as well as cleaning up the environment. Governments of industrialised nations should take the necessary steps to ensure that their toxic waste does not end up in the rubbish dumps of the countries of the South. Authorities in urban areas in the Third World should set aside more of their budgets to help the most underprivileged sections of their populations, so that they can manage their own environment. Local authorities should also respond more efficiently to the basic needs of impoverished districts, not least by building roads and sewer systems, by ensuring that rubbish is collected and by guaranteeing all people access to drinking water.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Last but not least, a concerted effort - especially a concerted financial effort - should be made by decision-makers at the local, national and international levels. We need to recognise that environmental damage is a phenomenon which rarely confines itself to the local level. Sooner or later, it becomes a problem for all of us. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">When conservation is at odds with the local population</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Hendrik Smets</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The clash between the interests of people living on the edges of the Zakouma National Park in Chad and the authorities' attempts at conservation illustrates the situation facing many other nature reserves in Africa. This article argues in favour of a form of eco-development to suit everyone.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When the Zakouma National Park (PNZ) WAS officially set up in 1963 (it had been at the planning stage since 1956), the area it covered meant that local people had to be moved -  but the promised compensation was never paid. During the second phase of the PNZ's relaunch, financed by the European Development Fund (EDF), a perimeter path following the 1963 boundaries was marked out, but local villagers opposed this, regarding it as an extension of the Park's area. Subsequently, they rejected a move to build a dispensary in a village located at the edge of the park on the pretext that such a structure would again constitute an extension to the reserve's land.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Conflict between the itinerant stockbreeders of the region and the authorities has simmered for many years. The latter have shrunk from enforcing the 1963 law on transhumance corridors which applies to the fringes of the national park. Under this law, it is prohibited (in principle) to gather wood, hunt for game, fish, or gather honey and other natural produce. The result is a tendency among locals to view the PNZ as an adversary rather than a potential partner in development. Safari tourism is developing too slowly and is not leading to sufficient benefits for example, from a craft industry, or more general redevelopment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When the second phase of the project was at the planning stage, its organisers recognised that, in order to guarantee the park's future, support had to be given to the people living on its edges. A high-level 'cooperation committee' was therefore proposed. The membership of this committee, which would sit in N'Djamena, was to include ministers, directors-general, park authorities and Commission representatives. Unfortunately it has not yet been brought into operation. By contrast, the local authorities and park management have been able to set up their own committee which met for the first time in January 1996. This body has helped to tackle some of the most sensitive problems.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The second phase also saw the implementation of a series of microprojects. - school renovations, a dispensary, a bridge, the sinking of wells, a dam, a mill and a nursery. But these were set up without preliminary study, and no arrangements were made to sound out the views of the local people, or the form of development they would like promoted. Understandably, local hostility was encountered and the projects cannot, in any real sense, be viewed as offshoots of the wider PNZ scheme.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The future</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The project has not been extended to a third phase. Because of this, there is a risk that the capital invested -  and the positive results that have been achieved - could be lost altogether. Should any donor choose to 'pick up the baton' in future, they will need to recognise the key imperative of creating a symbiotic relationship between the park and the local population. To do this, there must be an awareness-raising effort, undertaken in parallel with any eco-development programme.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the first instance, a higher profile should be given to institutional issues. In particular, the cooperation committee in N'Djamena must be able to act, where necessary, as an appeal or arbitration chamber to deal with any disputes which cannot be resolved by the local authorities' committee. The latter, of course, would continue to meet on a regular basis to discuss any problems encountered.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the same time, there should be campaigns to disseminate information and train local people who are in daily contact with the park's environment. The aim here would be to make them progressively more accountable for conservation and the exploitation of natural resources (cutting wood, gathering produce, hunting, fishing, and so on). They must also gain a better understanding of the effects of poaching and desertification. Above all, such campaigns should seek to convince the people of the benefits they stand to gain from the park, if they continue to respect its integrity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this context, some lessons might be drawn from a regional project dating from April 1987 (which was never fully implemented). This was aimed at halting the advance of the desert in the northern Central African Republic and southern Chad. The component of the project which is of interest to the present discussion was its programme to increase public awareness  -  which involved training organisers, preparing and disseminating information (posters, videos, films), organising information tours and giving support to the Training and Environmental Information Programme of the CILSS (Inter-State Committee to Combat Drought in the Sahel), of which Chad is a member.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One could also learn something from the approach adopted by the Manda National Park which is situated 270 km from Zakouma. This has 'volunteer villagers' appointed by the chiefs of the four cantons making up the park zone, who know the territory well. The volunteers take part in information, awareness and monitoring operations alongside national park and animal reserve employees. Dressed in pale olivegreen uniforms, they cycle between the villages and encampments, providing a link between the villagers and officials in N'Djamena. They have an invaluable role in convincing village people of the advantages of cooperating in the development of the park and its surrounding areas. And the cost of a volunteer is just CFAF 5 000 (ECU 7.5) per month.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Eco-development</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Returning to the PNZ, it is true that a small proportion of the population already benefits from the park's existence. Wages are paid to the patrols, and the permanent and seasonal workforce, while micro-projects have been set up. The park pays traders, artisans, farmers and stockbreeders for certain services and there are some tourists. But the bulk of the population does not see these advantages having been largely excluded up to now.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Any future eco-development programme should therefore aim at reducing pressure on the park in order to guarantee its long-term integrity. This would obviously need to be preceded by a clear definition of the action to be undertaken, but in the meantime, it might be useful to offer a few guidelines. The programme should include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - a series of flanking or support activities providing infrastructure and equipment, such as a dispensary, a school, paths, wells and carts;</P>
+<P ALIGN="JUSTIFY"> - a food-security programme providing for the conservation of agricultural areas, as well as measures to prevent erosion and safeguard harvests (cereal banks, stores, gardens, agro-forestry systems and pest control);</P>
+<P ALIGN="JUSTIFY">- a project to promote natural resources such as fisheries, gum arable, honey, and straw fodder;</P>
+<P ALIGN="JUSTIFY">- a wood/energy management programme providing improved hearths and brick ovens, and the organised gathering and use of supplies;</P>
+<P ALIGN="JUSTIFY">- development of the craft industry and training of tourist guides.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If, in a third phase, an awareness and eco-development programme could be successfully implemented, the Zakouma National Park should be able to look forward to a brighter future. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">A new 'eco-centre' in West Africa: Two Presidents amid the dust</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In April, on the eve of the International Conference on Human Settlements, the first West-African eco-centre ('Ecopole`) was opened in Dakar. It was set up by Enda, one of the few international non-governmental organisations of significant size based in a developing country. The 'eco' refers to two things - the economic life of the ordinary people and the ecological aspect of the centre. One of the most memorable images of the opening ceremonies was the sight of two Presidents  -  Abdou Diouf of Senegal and his Malian counterpart, Alpha Oumar Konare  -  striding through the dust in a working-class district of the Senegalese capital. For supporters of the 'Ecopole', the event epitomised the fight back of the popular urban economy. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The dust which settled on the Presidents' fine clothes was that of the Rail district, so called on account of the railway which cut through it in former times. Built in an old, disused factory, the airy, clean 'eco-complex' adds a touch of style to this semi-industrial, semi-shanty town district. The old buildings were redeveloped with the help of members of some two hundred cultural and sports associations, working in partnership with the NGO. They used recycling techniques of which they are past masters.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The complex had, in fact, been in operation for some time prior to its formal inauguration, but the ceremony  -  which attracted the interest of international press agencies - provided an opportunity to publicise the venture. Since its formation in 1972, Enda has been working to give a higher profile to the 'popular' economy (they eschew the term 'informal') in Senegal and elsewhere. The NGO has focused, in particular, on trying to encourage those involved in the popular economy to collaborate more closely and integrate their activities, as well as on boosting awareness of what is happening in similar communities elsewhere. The opening of the 'Ecopole' provided a showcase for the achievements of the popular economy in West Africa, as well as a forum for dialogue. And it now has the seal of approval of two Heads of State, not to mention other VlPs who made supportive statements at the opening.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The popular economy fights back</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For the inaugural ceremony, the former sheds - now converted into airy vaults clustered around a central structure - hosted a major presentation of the popular economy in a series of exhibitions. It is a kind of 'eco-museum' with pride of place going to recycling. Exhibits ranged from 'fabrics' made of old plastic bags crocheted together, to toy sports cars fashioned from wire and tin cans. And the reaction to the exhibition went beyond the usual, somewhat condescending appreciation of 'the skill of these people'. There were, of course, some curios of interest to tourists such as the aforementioned children's toys, small metal suitcases and papier-mache boxes. But there were also works of art, masks and sculptures, which captured something of the nature of this 'recycling culture'. Indeed, international art critics at the Biennal Festival of Contemporary African Art, taking place in Dakar, were talking of a new artistic trend, also seen in the work of artists from other regions, based on reclamation. This, of course, begs the question: 'Has art not always been based on reclamation?'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Interesting though the subject may be, the artistic and aesthetic qualities of the fruits of recycling are of only secondary importance when one is dealing with everyday objects. The important thing is for deprived populations to use what means they have to survive and to improve the quality of their lives. Tourists may choose to buy decorative and unusual objects on the reclamation market, but more significantly, families can obtain essential items such as kitchen utensils, ploughing implements, carpentry tools and stoves  - all cast from vehicle wheels and bits of scrap metal. They are made using small forges and furnaces the size of a large saucepan, or cut from otherwise unusable pieces of metal sheet. The craftsmen can also supply somewhat more sophisticated equipment: ploughs, brick-moulding machines or soldering irons. One of the exhibitions staged at the 'eco-centre' was a co-production with the Quebec Museum of Civilisation and the Canadian Embassy in Senegal, which had previously toured Canada and four African countries. Entitled 'Africa's ingenuity', it covered a wide variety of styles, ranging from the utilitarian to the artistic. It will, in due course, form the eco-museum's centrepiece. Another temporary exhibition was called 'Antuka: Kinshasa, the art of living in the city', and this paid homage to the Zairean capital - a place which, of necessity, has become one of the 'capitals' of resourcefulness. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jet engines and donkeys</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One hopes that the two Heads of State found time to admire the jet engine constructed by a young Zairean from nothing but reclaimed materials: parts taken from cars, mopeds and unwanted metal sheet. And it works -  not on an aircraft, naturally, but on the bench. This engine is now a legend. Its constructor has apparently already been spotted by a European head-hunting company and offered a job in France. This is part of the 'fight-back' referred to by Enda officials, in which some recognition is finally being given to the economies of the world's poorest populations. During his visit, the President of Senegal issued a plea for greater integration of the informal sector into the overall economic fabric. His remarks were revealing: the West-African 'Ecopole', as its name implies, covers an entire region, and assumption of responsibility by the local people for the shanty towns and poorer districts has lifted a significant burden from central government.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another example of this trend is found in the Malian capital, Bamako, where a hundred or so local community associations have banded together to take over full responsibility for the collection of domestic waste. This organisation, whose initial efforts were ridiculed, is now fully operational. One wonders whether the authorities in other cities have heard about Bamako's scheme. What about Port-au-Prince in Haiti, for example, where they are struggling with mountains of rubbish which they cannot deal with owing to a lack of resources ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Since their inception, economic interest groupings (ElGs) such as the one in Bamako have helped bridge the gap between the 'formal' and 'informal' economies. They rely on collaboration and their enterprise is exemplary. At the outset, the inhabitants of poor districts, acting on the initiative of the ElGs, expressed the desire to improve their neighbourhoods by organising refuse collection. They used whatever means were available - which in most cases meant donkeys and carts. In more central districts, delivery tricycles were employed for collection. Specially constructed, tipper-style carts, each costing CFAF 200 000 (ECU 300) have since been brought into service. The price of a donkey, by contrast, is about CFAF 50 000 (ECU 75). The animals and equipment belong to the ElGs and are looked after and maintained by them, with carters receiving a monthly income and social security benefits. A number of groups were set up eight years ago, promoted by young technicians, academics, architects and economists. Those who benefit are known as 'subscribers', with each family paying a contribution towards the service. Managing equipment and collecting contributions both require a well-structured administrative department, but the administrators are not confined to their offices. As employees of the business, they see nothing wrong in lending a hand and assisting the carters. In short, it is an enterprise based on a whole new approach. The contribution made by families varies according to the EIG and the district in question, but it is generally set at around CFAF 750 (ECU 1.2) per family per month. The price of the service may be up to twice this sum in the so called 'quartier des Blancs' (the 'white' district). In theory, the state ought to be subsidising the ElGs, but in practice, this does not happen. The authorities do not even fulfil the task allocated to them under agreements signed with the ElGs, which is to transport the refuse from temporary dumps to a final site. According to local people, the problem is not that the local authorities do not have the trucks available for the task. The vehicles, they allege, are used instead for the officials' own private purposes. The ElGs are forced to plug the gap as far as possible. At present, they appear to be the only ones taking any interest in waste recycling, aware as they are of the risk to the environment posed by permanent dumping grounds, and of the specific danger that the water table will be polluted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A modern concept of the 'informal' economy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 'informal' economy is increasingly becoming the norm. According to an Enda survey, 90% of businesspeople in Senegal started out in the informal sector. The conclusion would seem to be that the necessary training for dealing with current conditions is not to be found in the formal education system. The popular economy is not out of step with the modern economy as some would claim. Indeed, one could argue that it is the modern economy, as adapted to today's conditions. The increasing involvement of ordinary people in the economic circuit, which they enter via parallel routes, should also guarantee the continuation of Africa's experiment with democracy. We have seen attempts by former dictators to backtrack in this respect. They cite as evidence, the failure of technicians trained abroad - the 'darlings' of the West who, they claim, are at the beck and call of international institutions. But a return to the past, as exemplified by the regime of Nicephore Soglo, strikes fear into many people. Their response is to generate productivity, social cohesion and political stability through the popular economy, by way of compensation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is suggested that small-scale traders, who distribute hardware from south-east Asia, constitute an obstacle to the development of local production. But there is a confusion here between cause and effect. In fact, the popular economy appears more as a response to the lack of consumer goods. The problem lies with the so-called 'major' local entrepreneurs who favour the import/ export business over production, and with the banks that prefer to focus on larger businesses (influenced by anonymous officials or major economic interests) and have no time for small-scale operators.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Rail district in Dakar has a long history. It is overpopulated, having been settled by workers and artisans, and their influx made it the most expensive poor district. It is a place where the rents, for even the humblest hut without water or electricity, accounted for most of the inhabitants' meagre income. This situation led to the appearance of squatters who built their own shacks on waste ground. For these people, the threat of eviction loomed constantly like a sword of Damocles. The district is also home to a large number of maids and other household employees. Two thousand of these people (from Rail and other parts of the city) set up their own friendly society to which they pay regular contributions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is a world which has always teemed with good ideas: artisans recycling materials, blacksmiths working at the forge and so on. In this sense, nothing much has changed, but the big difference now is that the people have organised themselves. In so doing, they have been able to provide training for adults and children in makeshift schools, and to purchase and renovate old huts  - having extracted a guarantee from officials that such moves would not be opposed. Nowadays, those who live in the district no longer pay rent. However, it will only be possible to measure the true success of the Rail district when there is no longer a need for an organisation like Enda to ensure that it operates effectively.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some years ago, a former sailor, who always dreamed of being a teacher, set up his own school in the main street which runs through the district. He worked on the pavement and in the car park in front of a furniture store, teaching children in the morning before the offices opened and adults in the evening after they had closed. Enda recently offered him a few pieces of furniture, but for many years, he received no help other than a few pieces of chalk, worn-down pencils and the remains of exercise books from his 'colleagues' in regular education. This is a man who has to supply his pupils not just with teaching materials but also sometimes with food. This year, with his voice catching in his throat, he told us that one of his former 'street pupils' is going to college. How can the learned economists calculate the value of this devoted 'academic'? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The RDP challenge</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Professor Willie Esterhuyse</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The cornerstone of South Africa's Reconstruction and Development Programme (RDP) announced by President Nelson Mandela on May 24 1994, shortly after taking office, is people-centred development with an accent on modern infrastructure, health, education, housing and sanitation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lessons have already been learnt from teething troubles.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The RDP is the government's response to the massive socio-economic needs of the bulk of the South African population. It is foremost a strategic framework aimed at human development and restructuring the country's economy. It involves housing projects and programmes to improve the socioeconomic infrastructure covering clean water, electricity, public works, schools, urban renewal and primary health care. Empowerment programmes have been developed, for example; micro and small businesses, support for emergent farmers and skills training.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of the main achievements of the RDP has been to sensitise South Africans to the plight of the poor. Apartheid, amongst other things, succeeded in keeping this out of sight, effectively locking the poor out of the system. A veil of ignorance prevailed among the privileged class. The RDP tore away the veil and has led to a willingness to participate in development and reconstruction programmes, especially in private sector circles. It is succeeding in prioritising South Africa's socio-economic challenges, as well as mobilising funding and organising a common and sustainable approach. Its most important achievement to date is probably the idea of partnerships in development between the state, private sector institutions and non-governmental organisations. Through the RDP, South Africans have accepted that they will have to 'run with the development ball'. They are also aware that the state cannot go it alone, nor should it act as a 'super' development agency. Thus, a very high premium is put on involving the private sector and other actors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Problems</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But many problems have already been encountered. Unfortunately, the RDP was seen by some as a quick-fix solution to South Africa's socio-economic difficulties. Expectations over delivery were too high. Red tape and a growing bureaucracy stifled the initiative early on. Frustrations among the poor quickly surfaced. Many of those who wanted to participate, and applied for RDP funding, were unable to develop viable business plans - a strict requirement to get funds. The launch of projects was further complicated by the absence, at one stage, of legitimate local and governmental structures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But important lessons were learnt from the initial phases, in particular the need to involve people on the ground from day one - starting with the identification of needs, the design of a specific project and its execution. It was accepted that process is more decisive than the product. A second lesson was that a separate RDP office, with its own Ministry, complicated matters as far as delivery was concerned, tending to centralise development. This led to the announcement by President Mandela on March 28 1996 that the RDP office would be closed down. RDP programmes were thereafter integrated into the main budget administered by functional government agencies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another very important lesson was that socio-economic development and reconstruction had to go hand in hand with a dynamic macro-economic strategy - made public earlier this year. It was realised that one cannot have good projects in a bad policy environment - to quote a World Bank report.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In fact, it is generally accepted that the RDP, on its own, cannot launch South Africa on a road to sustainable and vigorous economic growth. We needed a twin-track approach.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Progress</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The RDP has notched up a number of successes. The provision of clean water to rural and urban communities has gone a long way under the leadership of Minister Kadar Asmal -  highlighting the fact that leadership strengthened by solid management, does make a difference. The electrification programme for low-income households, involving the parastatal, Eskom (Electricity Supply Commission), is another success story. The same goes for the Presidential projects, such as free health care for expectant mothers and infants, and some of the nutrition programmes. But the provision of housing for low-income groups has been less successful than anticipated. Rent and services boycotts, as well as unemployment, are some of the reasons for slow progress. Job creation is another problem area. It is envisaged that visible progress in these areas will emerge in the course of next year. Establishing a culture of learning is another great challenge. A restructuring of the educational system is underway, but progress is restricted by severe financial constraints.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Implementation of the RDP, the best strategic framework for socioeconomic development South Africa has ever had, will be a long process. Courage and sustainability are key issues. How to lead and manage expectations, without undermining hope, is a great challenge. The meaningful involvement of donors is another issue. Joint ventures between donors, the private sector, government agencies and communities are happening. Most of these, having been carefully negotiated and executed, are already making a significant difference.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But spectacular progress should not be expected. Development, reconstruction, and growth of the kind that South Africa needs, will take time. However, the lessons and achievements of the past two years have put South Africa in an excellent position to change the country's socio-economic environment. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Targeting South Africa's poor</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Christine Thompson</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The provision of basic amenities for the urban and rural poor rank high on the agenda of the EU's aid policy towards South Africa. In this respect, European cooperation has been tailored to fit with the government's own Reconstruction and Development Programme.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Programme for Reconstruction and Development (EPRD) is the name of the current EU development assistance package to South Africa and it seeks to help improve living conditions for all South Africans. The programme earmarks ECU 125 million a year until 1999. It has evolved from the so-called 'positive measures' programme launched in 1985 to help counter the negative effects of sanctions and to help the victims of apartheid.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under a Declaration of Intent drawn up with Minister Jay Naidoo, then at the helm of South Africa's Reconstruction and Development Programme, it was decided that EU aid should be channelled to the key sectors of education and training, health, rural development, water supply, urban development, economic cooperation, trade and investment promotion, and the promotion of good governance and democracy. In each of these areas, the EU actively encourages a partnership effort between governmental structures and NGOs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">2.5 million homes wanted</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over 60% of South Africa's population is urbanised. The apartheid government's restrictions on home ownership in urban areas for the past four decades resulted in a housing backlog estimated at 2.5 million units, with demand growing by 200 000 units per year. Estimates vary, but approximately seven million people are believed to be living in informal settlements throughout South Africa on land occupied both legally and illegally.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Improved housing and sanitation are seen as priority areas in urban and rural development. Between 1991 and 1996, the EU has funded 18 projects in the urban development sector valued at approximately R303.1 m (ECU 52m). The Urban Sector Network (USN) and the Cato Manor Development Programme are typical.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU is providing the USN with a total of R26.2m (ECU 4.5m) between 1995 and 1998. The USN is a national network of nine affiliate NGOs, and its aim is to improve living conditions for the urban poor. The beneficiaries of the programme are city dwellers earning less than R2000 (ECU 344) a month and there is a particular emphasis on households with monthly incomes of under R800 (ECU 137) a month.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Through integrated, community-based development, the USN and its affiliates provide technical support and service provision to urban development projects, focusing on housing, local government transformation, skills transfer, project planning, facilitation, information dissemination, education and training.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Cato Manor Development Programme received funding in 1995, also for a three year period. The EU has contributed R117.6m (ECU 20.2m) to the project. Cato Manor, an area in Natal near Durban, was the location of the largest forced resettlement scheme implemented under apartheid. Today, it is the first area targeted for integrated housing in a former white township.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The overall objective of the programme is to improve living conditions through a policy that strengthens the delivery system for infrastructure and housing. The programme anticipates providing the community with primary and secondary schools, sports fields, community halls, libraries and a community health centre. Access to housing finance will be improved and opportunities for income generation provided through a vocational training centre and small-scale industry workshops. In addition, provision is being made to improve management and general policy-making capabilities. By continuing to fund such projects, the EU is working with the South African government to improve the living conditions of the urban and rural poor. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">'Guardians of Eden'</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Theatre for Africa, a performing group from Southern Africa, went on tour this autumn to put across the message that the exploitation of Africa's fauna should remain in the hands of rural communities. They did this with a powerful mix of words, dance, mime and song, in a play entitled Guardians of Eden '. The Courier met the author and cast on the Brussels leg of their tour. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The setting for the Brussels' performance was the 'Grand Place' (Grote Markt). With its ornate mediaeval architecture, this famous square in the centre of the Belgian capital could hardly have been more removed from the theme of the play - which is about conservation and development problems in Africa and empowering rural people to manage, use and benefit from the wildlife around them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The play was commissioned by the Southern Africa Sustainable Use Specialist Group (SASUSG) and the idea was that it should reach as many people as possible in the run-up to the World Conservation Congress planned for Montreal in October 1996. South African writer and former economist, Nicolas Ellenbogen, travelled throughout Southern Africa to recruit the all-African cast. Many examples of cultural imperialism leading to the destruction of habitat, highlighted in the production, were actually encountered by Mr Ellenbogen as he travelled through the region.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The play opens with a spirit medium summoning representatives from villages in several African countries to discuss the threat to their survival. The actors display their athletic skills performing mimes of the abundant wildlife with simple props, as the history of Africa is recalled from the dinosaurs to the present day.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A parable is then told. An old chief informs his three sons that to prosper in the 21st century, the village must change. He instructs them to return a year later with ideas for prosperity, which will be discussed in an indaba (debate). Each chooses a different path. The wheeling and dealing first son seeks out quick fix schemes with NGOs and various city authorities. The second son learns from the difficulties of city life and comes up with a blend of simple wisdom and new ideas. The third spends his time in beer halls -  and his revelry provokes roars of laughter throughout the performance.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Arriving back in his village after almost a year has elapsed, the second son finds that his older brother returned several months earlier to implement his money raising projects. Enjoying the cash benefits of the scheme, the men of the village do not want to hold an indaba. They are forced to do so by the women and Midzimu - the old chief. The audience is then asked to vote and there is a unanimous show of hands for the second son who symbolises the sustainable use of natural resources. The dissolute third son, meanwhile, is eaten by a crocodile.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ivory ban fury</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While the message goes out to developers and donors to respect rural autonomy, the play also raises serious questions for Europe's politicians. The frequent appearance of the destructive elephant, in the course of the play, allows Mr Ellenbogen to vent his anger at the ivory import ban imposed by many European states. 'I am furious about the ban', be told The Courier, 'as it is having a profound effect on the daily needs of the people.' He rejects the argument that it helps conservation, insisting that; 'with a stroke of a pen, you reduced the value of the elephant.' The playwrite argues that local people need to see wildlife as economically and socially valuable. Otherwise, they will adopt new forms of land use which will result in the extinction of the species. He also draws attention to the growing black market in ivory in Southern Africa since the ban was introduced.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 'token' South African - symbolically played by the only woman in the cast - is given a 'rough time as the baby of Africa', says Ellenbogen. The play also contains numerous swipes at the donor community which frequently gives grants, without, it is said, any respect for local traditions. The Swiss doctoral student researching the potential for producing goat's cheese in Africa exits the stage squealing after asking a goat herder what he does with his animals. 'We slit their throats', is his reply.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guardians of Eden was first launched at the Grahamstown Arts Festival in South Africa in July. It was performed in Zimbabwe and Kenya, and won a prize at the Edinburgh Festival 'Fringe' in August. From there, it moved to Frankfurt and Geneva before reaching Brussels. It was due to be performed in Antwerp, London and several American cities before a final staging at the Montreal Congress in October.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The play is in English and the languages of Southern Africa, but Nicolas Ellenbogen believes it can be readily understood by his multinational audiences. For him, the message - that local people must have the power to manage their own wildlife on their own land - needs no translating. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Analysis</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Europeans and development cooperation: there are opportunities too!</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Stelios Christopoulos</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If politicians in Europe see jobs as their primary concern, it is probably because the citizens regard unemployment as their most serious problem. In the Europe of the Fifteen, the average unemployment rate was about 10% in 1985 dropping to 7.5% in 1990. By 1994, it had risen to a record high of more than 11%. By contrast, unemployment in the United States fell below 6.5% in 1994 and the figures for 1995 reveal a continuing downward trend. In Japan, the proportion of people without work remained below 3% in 1994. Assuming there is no change in current trends, the most recent demographic projections suggest that there will be 70 million people over the age of 65 in the EU by the year 2020, out of a total population of 348 million. This is 18 million more than there are today. The proportion of over-65s is, thus, projected to rise from 15% at present to 20% in less than 25 years. These two elements  -  an ageing population and ongoing structural unemployment - clearly reveal that European society lacks a degree of dynamism compared with its competitors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In an attempt to address this problem, albeit partially, the President of the European Commission, Jacques Santer, launched a European employment pact in April 1996. There are three underlying reasons for this initiative -  Europe's endemic unemployment, the need to reestablish a climate of confidence as a prerequisite for renewed investment and consumption, and the need to fit the creation of the single currency into an overall economic strategy aimed at increasing growth, competitiveness and employment in Europe.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'I'm young, help me find a job', is the heartfelt plea of many of young Europeans. But what chance is there that their cry for help will be answered in a difficult global environment?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We have seen the globalisation of strategic relationships in a range of key areas including the environment, the management of energy resources, health, demography and security. The trend has been accelerated by rapid technical progress in the fields of transport and telecommunications. This process has not taken the big multinational companies by surprise - they were already free of the constraints of sovereignty or space, and were quick to globalise their structures. These enterprises have become more competitive by taking advantage, wherever possible, of the most favourable production conditions, particularly regarding raw materials and employment conditions. More spectacular still has been the growth of international trade: in 1990, the volume of world trade was 11.5 times as great as it had been 40 years earlier. During the same period, global production only increased fivefold.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What this means nowadays is that employment in the EU Member States is directly affected (and some would say threatened) by the world situation. Productivity and growth conditions in Europe are no longer sufficient to ensure full employment. Competition from developing countries, with their low wage bills and undervalued currencies, is too great for countries in the EU. Their position is not the same as that of the multinational companies. They do not have the structures to deal with swiftly evolving events, nor are they capable of controlling the process of globalisation. This is demonstrated, inter alia, by their inability to respond to the financial speculation which turns capital away from productive investment. Today, for example, for every US dollar in circulation, there are at least 30 dollars which are the product of financial speculation. This is not money from productive work by any particular person, but money which is the product of a financial 'virtual reality' and which is usually reinvested in financial speculation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Countries are beginning to realise the need to pool their national skills and cooperate at a regional level, in order to enhance their business competitiveness and take on the challenges of the globalised trading system. But the level of integration implied by this strategic choice must be sufficiently comprehensive if it is to make up for the reduced capability of countries to respond on an individual basis. This process of regionalisation may well be a prerequisite for regulating the world economy in such areas as exchange parities and financial speculation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">And what of Europe in particular? Despite having a head-start on other regional groupings (such Asean, Nafta and Mercosur), the situation is not too rosy. Owing to the lack of a full internal market, Europe is unable to compete on equal terms with the United States or Japan. The internal market still comes up against blocks in important areas, as evidenced by problems over the European employment pact. And there are a number of other defects which make the internal market insufficiently competitive in the context of globalisation. It is true that a more coherent environment has been created for European companies, with common regulations and rules of competition enabling them to distribute their goods and services among the EU's consumers. But despite the appearance of a domestic, or single, market, it is one which is devoid of a genuine internal policy in keeping with its size. This is what distinguishes it from the internal markets of the United States or Japan.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The explanation for the disparity may lie in the fact that the most recent moves towards the single market, through 'Single Act', date from 1987. This was before the upheavals which so decisively signalled the globalisation trend. Despite the criticisms sometimes levelled at it, it is a genuine single market which is largely open to the outside world (with only a few exceptions, notably as regards the Common Agricultural Policy, where it is recognised that there is a need for progressive adaptation). But there is still no single currency, nor is there a genuine common commercial and economic policy. The EU is unable to react to change at world level in the same way as its competitors. The common customs tariff, together with protective measures such as the anti-dumping regulations, are still not sufficient to solve all the Union's problems. What is needed on top of this is an active common policy component.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yet, as the European employment pact makes clear, the EU holds a trump card in an increasingly interdependent world. The proviso is that it must speak with one voice, enforce multilateral rules and open up new markets for itself, because, as the document points out 'exports create jobs...'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1994, the developing world received 37% of global direct foreign investment ($84 billion) as against less than 20% at the beginning of the 1980s (the flow of foreign exchange is regarded nowadays as the principal factor influencing development). This is a spectacular increase but the resources are not 'fairly' distributed from the point of view of either the investing countries or the recipients. For example, southeast Asia is currently the world's most dynamic region. Yet, not to put too fine a point on it, it is virtually ignored by European investors. Only 3% of European overseas investment is directed towards this zone. Likewise, Europe's market share in the region is no more than 5%. The US has invested between two and three times more in south-east Asia while Japanese investment is four times higher.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1994, sub-Saharan Africa attracted just 0.8% of direct foreign investment ($1.8 billion). And there is no evidence that Europeans have invested more than the Japanese or Americans in this region. This is despite the highly optimistic outlook for the situation in Africa offered by the late Ron Brown, the former US Trade Secretary. On returning from a tour of Africa with American businesspeople in February 1994, he remarked that major opportunities were opening up in that continent, with spectacular returns on investments  - at the time, the best in the world. His regret was that so few people were aware of the situation. Undoubtedly more significant still was the declaration made in Washington before his departure for Africa to the effect that the United States would no longer leave African markets exclusively to the former colonial powers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">So although others are beginning to explore the possibilities offered by Africa, Europe is still sceptical. A similar scepticism prevailed during the 1960s when it was assumed that the lot of south-east Asia would be famine, and few development prospects. Given the historical links between Europe and Africa, the geographical proximity of the two continents, and the pressing problems faced by the 'old' continent vis-&agrave;-vis its competitors, such an attitude appears difficult to explain. In the years since the former European colonies in Africa gained independence - and despite the creation of an institutional cooperation framework (the Lom&eacute; Convention, which many regard as a model of development cooperation)  -  many Europeans clearly no longer wish to be involved in Africa. The explanation for this lack of interest may be the difficult conditions within African countries -  obstacles preventing access to markets, the lack of liberalisation or political instability.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But this analysis in not entirely convincing. More ACP countries are democracies than ever before in the post-independence era. As for Africa - a much-debated ACP region  -  it is wrong to talk purely in terms of internal conflict, famines or the AIDS epidemic. There are countries in this continent with growth rates of between 5% and 6%, and several examples of where European companies have successfully penetrated local markets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The need to highlight the existence of genuine business opportunities in ACP countries and to make the European public aware of development aid success stories, were among the main conclusions to come out of the first meeting of a television delegates' network, organised by the European Commission's Development Directorate-General on 31 January 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Any European company chairman interested in expanding into an ACP country - thereby enlarging the company's market and enhancing its competitiveness - is likely to acknowledge the possibilities, if offered back-up from the EU or from national governments. But they will then probably point to the complications which remain -  and with some justification.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With this in mind, it is worth reiterating the fact that specialised institutions exist for facilitating contact with the ACP countries. In 1995, for example, the Centre for the Development of Industry (CDI) was involved in 367 projects, assisting, free of charge, in the expansion or rehabilitation of industrial companies in ACP countries, in partnership with European business. Although the number of such projects is constantly increasing (190 in 1993,229 in 1994), it is still a long way short of what is needed. But it should be stressed that the CDl's approach, which involves promoting the creation of networks, appears to work. The establishment OF ACP contact networks in ACP countries makes it easier to identify potential areas for involvement and to prepare better for European institutional and sectoral networks. There are several successful projects which have led to the creation or safeguarding of jobs in Europe.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Also in 1995, the European Investment Bank (EIB) granted ECU 430 million in loans to businesses in various sectors in 29 ACP countries. This includes an increase in the Bank's activity in Africa over previous years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What, then, of the effect of Europe's development cooperation policies on the European market ? According to the most conservative estimates, for every ECU 100 granted in aid, the Community 'gets back' ECU 48 in the form of jobs, supplies and technical assistance. This figure does not take account of additional 'secondary' business generated by, for example, the supply of spare parts or the provision of technical advice. This business can be quite significant given the degree of penetration achieved by European companies in the markets of many developing countries. Nor does the estimate include any new business opportunities directly arising from the links established between the companies involved in aid projects and the recipient countries. Thus, it is clear that when a project is set up, it may well have extra beneficial effects for Europe through additional flows of goods and services.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The 'return' on aid is even greater in Member States' individual bilateral programmes. For example, tied aid from countries such as Belgium, Italy and the United Kingdom leads to a payback of more than 70%. Another point is that as Europe's industrial rules are harmonised, the success of a single European company in penetrating a particular developing country market may pave the way for companies in other EU Member States, thus benefiting the Union as a whole. Tied aid creates favourable conditions for setting up European companies and for placing European goods and services in other markets. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While the return on aid may be described as satisfactory, the same is not true of the number of companies that benefit or of the actual turnover involved. One wonders whether this weakness is due to a lack of information about existing resources and facilities, or whether there still a lack of confidence about countries which, despite the progress they have made, are still politically unstable and therefore unpredictable.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One might also wonder whether the time is right for investment. Our answer would be that, even though financial speculation is currently governed by global economic considerations, which prevent productive targeting of capital, this situation cannot last. There is a worldwide move to rectify the situation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We all need to be aware that time is no longer on our side. In many sectors, European companies still have a competitive edge over businesses from third countries, owing to their degree of specialisation and technological expertise. But if they are to survive, they must take on a worldwide dimension. In particular, they should pay attention to the comparative advantage that they have in the ACP countries on account of their special skills, historic links, geographical location and, above all, the institutional connections between these developing nations and the 'old' continent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although problems do exist and although both European and ACP bureaucracy can sometimes discourage private operators from exploring the potential of the developing world (and more particularly the ACP region), they should not give up. Europe's challenge is to help them to exploit this potential whilst not raising false hopes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nothing can take the place of the shared experience and confidence which arises spontaneously in full knowledge of the facts. In this regard, we feel, there is still much to be done. In both Europe and the ACP countries, one way to succeed is to increase the number of networks representing industrial, economic and financial interests at various levels, and to assist them in identifying opportunities more effectively. This would help to create a new dynamism and renewed vigour in Europe. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Close - up</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Eritrea: the start of a renaissance ?</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the Courier's issue of July-August 1994, we published a country report on Eritrea. This country became independent in 1993 after almost 30 years of fighting which had bled the county white. Loss of human life, displaced persons, socio-economic disruption and environmental damage have been Eritrea's sad fate in recent times. However, there has now been peace for three years and the Eritrean people are attempting to pick up the threads. Alfonso Artico, a freelance journalist who recently travelled to Eritrea, now offers us a few on-the-spot impressions of his trip, focusing on some current projects which offer hope to this sorely afflicted people</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fisheries at Massawa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The port of Massawa is located on the Red Sea, whose blue waters are teeming with fish. In 1986, the European Union suggested that it would be a suitable place for fisheries development. At the time, the city was a maze of back streets, baking in the sun. Few could have predicted the fate that would befall it five years later. For in 1991, war came to Massawa and 80% of the city was destroyed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Italians, it is said, have 'always' been here, and they once had great plans for the city. Together with Assab, further to the south, Massawa was to be a key point of access to the sea, and a potential launch pad for the, country's struggling economy. The colonial days are long past but, when the Eritrean Popular Liberation Army took over the country after the recent war, the Italians came back to help tackle an immense task. The city, by then, was little more than a pile of rubble.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Help also came from somewhat further afield, in the shape of Professor Seichi Etoh, a Japanese specialist in marine biology. He had made a study of the city in 1989 and he chose to return in 1992 to help in fisheries development. At the outset, his working methods disconcerted the Eritreans who were used to a slightly more relaxed attitude to labour, under the hot sun and eternally blue sky.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Armed with the experience of working in Kenya and a number of other developing countries, Professor Etoh arrived in Massawa and installed himself in a house looking over the sea. After a period of adaptation, to gain his bearings, he took up his new challenge.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The challenge in question is a fisheries project whose main funders are the UNDP, Japan, Italy and the African Development Bank. A total of $7 million has been committed with payments spread over a five-year period. The project began operating in January 1993.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The main problem at the outset was one of skills and qualifications. Important posts were often filled by high-ranking former solders, whose administrative skills were less than satisfactory. Conversely, those with the right qualifications - some of whom were criticised for spending the war years in the lecture theatres of European universities  -  had problems finding work. This was particularly true in the closed and conservative world of the fisherman. After a few teething troubles, Etoh was able to announce that he had the confidence of the government, and his efforts rapidly bore fruit thereafter. He set about reorganising the fishermen's cooperative - a task which entailed overcoming the reluctance of members to adopt new practices. He also arranged for the construction of jetties where vessels could take on supplies. Fish were to be unloaded at one spot, and their diesel tanks would be refilled at a different location. The cost of diesel is 1.41 birr (ECU 0.17) per litre. The fishermen's cooperative, which has 440 members, has 35 000 birr (ECU 4000) in its funds. It is also making repayments on a 1.8 million-birr (ECU 200 000) loan.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'In the beginning, there was frenzied activity, which some regarded as chaos', Seichi Etoh recalls. However, in less than two years, the jetties have been completed and the ice plants -  essential for preserving the fish - are running flat out. Now they are producing eight tonnes of ice a day. The daily catch is about two tonnes of fish.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The real revolution occurred when Seichi Etoh decided to try and organise cooperatives for women, who represent 25% of the workforce in the production chain. He followed up with an even more radical scheme, offering them paid work in the relatively unrewarding but essential field of ship maintainance and repair. This freed the fishermen, most of whom had no remunerative activity outside the fishing season (November to March), to seek work elsewhere during the other seven months of the year. Eritrea, a country where women's potential has not traditionally been acknowledged (or tapped) had never seen the like before. Nowadays, of the 200 who fish out of Massawa, 50 are women who have formed their own organisation - and they generate a considerable profit. They have even opened up a fish restaurant!</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The overall standard of living has increased considerably. This year, fisheries-related production has risen 120% compared with 1995. And the port is doing reasonably well in quality terms. Using the international scale, which ranks the catches from 0 to 10, the quality of fish landings by the Massawa fishermen is rated 6 overall - as against 8 for Japan. 5 for China and 6.5 for Europe. The local market has expanded as a result of efforts to modify local eating habits. People have been taught to grill fish instead of frying it in expensive (and somewhat unhealthy) oil. The message - 'eat grilled fish' - is going out daily on national radio, and women are going into the schools and villages to teach this 'latest' cooking technique.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The local market may be important, but the main target for the increased production is Ethiopia. With the purchase of four refrigerated lorries, it is now possible to transport fish products over long distances. Another important customer is Italy, which currently takes about a third of the total production. Seichi Etoh is hopeful that, following this example, new markets can be found in other parts of Europe.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The success of the Massawa project has exceeded all expectations and, although he downplays the achievement with typical oriental modesty, it is clear that Etoh's bet has paid off. The fishermen have come to understand the advantages to be gained in reorganisation and maintaining their 'tools' of production. And as anticipated, the bulk of the profit from the project is going back to the fishermen. The government has taken care not to cream off too much for itself.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other projects are now under way. Etoh is attempting to persuade the fishermen to give up their wooden craft in favour of ferro-cement vessels but after centuries of doing things in a certain way, it will take more than a few months for the new plans to be adopted. The monthly meetings with representatives from the cooperatives are stormy and animated. However, two vessels are already being built, on the assumption that a practical demonstration is worth far more than a long speech. The 60 people working directly on the project are awaiting the outcome.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This change has become necessary owing to the cost of wood - which is one of the reasons why the fishermen have grown progressively poorer. Timber prices have been rising sharply for some years, particularly in Dubia, the regional centre of the wood trade. The war, in the meantime, sent incomes spiralling downwards.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Overall, the Eritrean fishing fleet has 500 vessels, all made of wood, of which 250 have Massawa as their home port. In previous years, the wood (known as tengi in Eritrean) came from Ethiopia. But this country is facing ecological problems and fishermen have been forced to search elsewhere for building and maintenance materials for their unstable and costly vessels (a 13-metre boat requires 8 m³ of wood). Etoh explains that the new boats, while slower, glide more easily over the water on account of their stability. However, the first attempts at change have not been easy. Indeed, things got so bad that Etoh went on holiday 'for longer than expected', he said, though he took advantage of the break to visit Singapore and buy Chinese tricycles  -  which can now be seen in the streets of Massawa. The reign of the bicycle with a simple wicker basket which could carry just 20 kilos is over. Now, each tricycle can deliver 100 kg of fresh fish, packed in ice. All in all, the programme is running smoothly. Etoh has only to check it from time to time. After all this labour, will the smiling Japanese professor be taking a well-earned rest? 'Probably not,' he says, adding 'I am currently thinking about a chain of restaurants. Fish restaurants of course !'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An unusual 'bank'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The road leading to Gersteti village is so beautiful that it takes your breath away. Multicoloured birds fly lazily above the vehicle carrying the journalists and humanitarian aid workers - who are deep in discussion about the kind of world they wish to create. However, there is a switch in the conversation once they reach the Seraye plateaux. Their attention is drawn to the fields which stretch as far as the eye can see. It doesn't take long to discover that demand for land here far outweighs supply. The situation, which is already critical, has not been helped by the influx of refugees returning from neighbouring countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When the war ended in 1991, everyone's prime concern was to relaunch an agricultural sector ruined by 28 years of combat. Farmers and farming communities, the lifeblood of the countryside, had been mobilised to fight on the front line. In 1990, agricultural production was at such a low level that the word 'negligible' featured prominently in the Ministry of Agriculture's statistics.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Oxfam, which first came to Eritrea in 1978, has been running an unusual project on the Seraye plateaux. Located to the south of Asmara, the capital, this region is the second most densely populated part of the country. Five districts containing 65 villages and 17000 families, were chosen for the project  -  on account of their low rainfall and the fact that it is difficult, and in some cases, impossible, to cultivate the exhausted soil. Local communities, village leaders and politicians all understood that only full-scale collaboration could prevent a food-supply disaster in the province. An organisation was therefore created: the villagers elected 13 representatives (12 men and one woman) and began by setting up a seed bank. There was a severe shortage of seed materials in this devastated country. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The project got off the ground in November 1995 and is set to run for three years. Its objective is simple: to guarantee self-sufficiency in seeds and to provide a reserve during hard times. The 'Seed Bank Committee' has also given training to 40 farmers in seed conservation, terracing and basic agricultural economics. Two wells have been sunk, but these are insufficient for the 40 square kiLom&eacute;tres that require irrigation. Oxfam is putting up the money for the various initiatives while the local community is providing the labour force. It is worth noting that a bag of averagequality cement costs 35 birrs (ECU4), equivalent to one third of a worker's monthly wage. Fourteen different varieties of seed have been stored in sheds - which the locals visit to obtain their supplies. The purchase of 230 quintals of local seeds and the donation of 70 quintals from elsewhere have started the programme off. Next year, Individual farmers will have to repay this 'loan' in kind, with a 10% 'interest payment', also in the form of seeds. The surplus generated will be retained by the bank as a resource to be drawn upon, if necessary, when times are hard.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Advantages</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The local community was quick to understand the advantages to be gained from this system. They were all too aware of the low productivity of their land and up to then, were powerless to resolve the situation. The possibility of falling back on traditional resources to offset production difficulties no longer existed. And the skills they had acquired over the generations were now insufficient, given the poor condition of the soil. In these circumstances, one can well understand their enthusiasm when they saw that 100 kg of seeds per hectare yielded a harvest six times larger than previously. Other elements which contributed to a progressive improvement in conditions were the sinking of new wells, a reduced influx of refugees from Sudan, and a slow but appreciable improvement in the country's general economic situation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As well as being involved in this project, Oxfam is an active member of Acord, an NGO association which extends cash loans at rates much lower than those demanded by the banks. (Acord's rate is 12% per annum with a minimum repayment of 5 birrs per month). Targeted mainly at the most deprived sections of the population, the loans enable the poor to set up small businesses or, more commonly, to purchase agricultural implements, repair irrigation channels and buy cattle. Once again, a village committee manages the transactions. The scheme has brought renewed hope to the most deprived groups. Individual loans have been available since 1994 and the association currently has 163 clients. The total amount lent so far is 878 000 birrs (ECU 110 000).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The combined effects of these programmes - seed banks and preferential loans - are already visible. It would take months to visit all the farms and fields, workshops and stores, where men and women have invested their energies and hopes. Seraye province now produces a third of Eritrea's cereals, a telling illustration of the fact that one does not need billions of dollars for development and humanitarian aid for the work to be effective. In the final analysis, a country's wealth lies in its citizens. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An up-to-date printing plant</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As one strolls down Liberation Avenue, which cuts the city of Asmara in two, one might be forgiven for thinking that 28 years of war have already been forgotten. Surveying the multi-coloured neon signs of the shops, it certainly appears as if the country has turned the corner and the wounds are healing rapidly. One building whose restrained frontage stands outs in sharp contrast is the Adulis printing-works. Adulis was the name of a semi-mythical city founded by the Greeks on the Red Sea in the third millennium before Christ. 'But there is nothing insubstantial about this place', comments Mohamad Shiffa Osman, with a smile. He is one of three expert typesetters who went on a training course in Belgium earlier this year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> The Adulis printing works has its own particular memories of the Eritrean people's struggle for independence. As far back as the 1960s, when the first shots were being fired, the resistance recognised that their fighters and the civil population both had to have access to information. However, it was not until the 1980s that a true propaganda structure came into being. During the war, the Eritrean People's Liberation Army ran a clandestine ministry of information. In Eritrea and elsewhere, this became the channel for conveying practical information, and providing the latest news from the front. It was also used to transmit personal messages, which were delivered to the heart of areas occupied by the Ethiopian Army. 'Our presses were hidden in caves, up in the mountains, and everything was run on generators', Mohamed remembers. The initial amateur approach was quickly replaced by a more professional one. 'We did have professional printers working for us, but it was mainly self-taught comrades'. On-the job apprenticeships had to be fitted in between bouts of fighting!</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'At the time of liberation, in 1991, we set about restoring this printing works, which was founded in 1896 by the Italians', Mohamed explained as he gave us a guided tour of the works. The effort put into relaunching this essential activity soon bore fruit. Within the year, the printing operation was running at a profit - indeed it had a virtual monopoly of printing in the country. The presses were brought down from the mountains on the backs of camels and then taken to Asmara by truck. 'You see this Aurelia 48?', asks Mohamed, pointing to a machine. 'Well, it was up in the north, hidden away in a village'. Throughout our visit, Mohamed draws attention to equipment from an earlier age  -  candidates for the museum which are still in operation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some items have their own story to tell, like the press donated years ago by Oxfam which still churns out thousands of sheets every day. During the war, it was taken from cave to cave, following the army's advance as it conquered new terrain. Most of the Adulis machines, however, were already there, when the decision was taken to restart the operation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The initial budget for the works was a tidy five million birr (ECU 620 000). Today, Adulis has an annual turnover of 20 million birr. Monthly salaries range from 400 birr (ECU 50) for maintenance staff to 1800 birr (ECU 225) for the director, Michael G. Bakhli. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The printing works also acts as a testing ground for workers' social progress. According to Mohamed and the director, the 350 or so people employed at the works benefit from exceptional social cover. If a worker falls ill, his wage is guaranteed for one month, then it drops to 50% in the second month and stops altogether at the end of the third. if a woman is pregnant, she has to take a month's statutory leave and is granted a further two months on full pay. In the event of dismissal, an employee receives two months' wages, although this latter arrangement is gradually changing to one month's wages for each year of service.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Far from resting on the laurels of their success, the Adulis works' directors have appealed for assistance. In order to be at the cutting edge of technology and to have the resources to break into new markets, they need to supplement their knowledge. Therefore, three 'volunteers' spent the three months from January to March this year working in Belgian companies, to the satisfaction of everyone, both hosts and visitors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under Mohamed's gaze, the walls of the workshop have been brightened up with posters which provide a splash of colour. Although the noise from the presses often drowns out conversation, you cannot escape the feeling of hope here. It is like a breath of fresh air, and one leaves with the strong impression of a country that is rising from the ashes. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Developing world</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">ECHO fine-tunes disaster preparedness strategy</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Eva Kaluzynska</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When a cyclone strikes in the Caribbean, beware of giant flying razorblades - airborne sheets of corrugated iron that kill and maim unsuspecting victims every time. 'The use of galvanised iron sheeting for roofing is extremely dangerous in cyclone-prone areas,' says Professor Debarati Guha-Sapir, Director of the Centre for Research on the Epidemiology of Disasters (CRED) at the Universite Catholique de Louvain. 'We know this, and we need to encourage the use of lighter materials, such as thatching, which doesn't kill if it flies off in a gale,' she adds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">That is the kind of issue facing people exposed to unavoidable natural disasters  -  in the Caribbean's case, every year. In 1995, there were 27 tropical storms in the region. CRED has been in the vanguard of monitoring natural disasters and in coming up with solutions to the problems they create since it was set up in 1973. Now it is assisting the European Community Humanitarian Office (ECHO) in developing its new Disaster Prevention, Mitigation and Preparedness Programme (DIPECHO) to cover the next two years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Since 1994, ECHO has spent almost ECU 7 million on 50 disaster prevention operations, at both national and regional levels. Now, instead of just responding to requests for funding from non-governmental organisations, international organisations and governments, ECHO has decided to fine-tune its strategy. It will concentrate its efforts on specific regions known to be particularly vulnerable and prone to natural disasters. We may not know exactly when disasters will strike, but we certainly know where to expect them. The regions selected at present are: the Caribbean, Central America, South East Asia and Bangladesh.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All of them are exposed to repeated emergencies. All of them have a struggle to develop when their efforts are disrupted so frequently. They cannot just pick up where they left off. Loss of life and property is just the most visible aspect of what happens when disaster strikes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The infrastructure, such as it is, takes a hammering. Road and rail links are severed. Communications, electricity and water supplies break down. Add loss of health care and sanitation, and you get populations exceedingly vulnerable to epidemics. Add loss of education facilites, and a vicious spiral of poverty sets in.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An expert in emergency aid cites the sad example of the Aetas, a tribal group that used to live a secluded life on the remote slopes of Mount Pinatubo, the volcano that erupted spectacularly in 1991 in the Philippines. Though the volcano was known to be menacingly active, the Aetas were not evacuated and resettled in time. They fled in panic as disaster struck, to the plains, where they faced a deadly, invisible enemy: measles, a disease to which they had never been exposed. Measles claimed more victims than the volcano itself did in the months that followed. They could have been resettled earlier. And they could have been immunised years before, but weren't.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It's easy to be wise after the event. DlPECHO aims to encourage action before it's too late. The idea behind ECHO's new policy is to take each region, and to identify its hazards and capacity for dealing with disasters. This will help to pinpoint the gaps. Then it will draw up Action Plans that slot into the wider picture of potential development in each case.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DIPECHO projects will involve training personnel in the regions affected to handle disasters, and to strengthen the institutions that can contribute to effective prevention, preparedness and mitigation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some of the solutions are ingenious, low-cost, low-tech ideas. Take, for instance, the use of light, widely-available, inexpensive materials for roofing in earthquake or cyclone-prone zones - an idea poorer countries could adapt from wealthy Japan's experience. Or the construction of safe, raised 'islands' that will stay above the waterline amid flooding in Bangladesh to offer shelter. Or adapting drainage, and changing cropping patterns in Andhra Pradesh, India, to mitigate the effects of cyclones.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In earthquake-prone Central America, protecting roads and bridges, or building schools less prone to collapse is very important. Using the radio or even neighbourhood watch systems to sound the alarm when disaster is imminent can make a big difference to its impact in terms of injuries. Drilling all at risk, from school-age up, to know what to expect and to know what to do is vital.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">DIPECHO did not include Africa in its first selection of regions for Action Plans. This is not to underestimate the gravity or scale of the disasters experienced there, says Professor Guha-Sapir: 'Floods, drought and famine are very frequent events there.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">They are often killers.' Overexploitation of scarce resources and political turmoil compound situations that lead to disasters which seem less dramatic than a volcano eruption, but are no less far-reaching in impact.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The instability in many of the areas worst affected means that African countries lack the institutions needed to prepare for disasters in an organised way, she says. 'There are limits on ECHO's ability to intervene. It's unrealistic to expect the kind of grassroots, technical preparedness we are talking about in the current situation.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ECHO's Jean-Claude Heyraud sums up the new policy: 'As far as preventing, mitigating and preparing for catastrophes goes, the new proactive approach reflects the importance ECHO attaches to this type of action. The DIPECHO programme meets the growing need to evaluate risks in order to reduce loss of life and damage to property. If and when emergency aid is needed, preparation and prevention can help to reduce the scale and cost of such actions.' </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Culture and society</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">African reflections</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">by Seydou Sarr</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The third Festival of African Cinema was held in Brussels on 15-22 June. For one week, film-goers in the Belgian capital filled the auditoria of the Palais des Beaux-Arts, where they discovered new images of an alternative Africa. And as always, when the time came to assess how the Festival had gone, professionals and organisers alike were left pondering the problems facing the African film industry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Organised for the first time in 1994, on the initiative of Diaspora Productions, the Festival had a number of objectives, including that of bringing Africa's finest films to wider public notice. The initiative stemmed from two observations. In the first place, the European public's opinion of Africa is based on what it sees on television -  and that image is of a continent so ravaged by famine, misery and strife that it is incapable of progress. Second, from a professional standpoint, there is no effective distribution network in Belgium for African films. Samba Traore by Burkina Faso's Idrissa Ouedraogo and Hyenes by the Senegalese Djibril Diop Mambety were two rare exceptions in succeeding in getting on to the circuit.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A forum for reflection</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In setting up film-industry meetings, the organisers of the Brussels Festival wanted the event to be a forum for reflection on the problems facing African cinema. In the 40 years it has existed, there has undoubtedly been some progress. It is even possible to speak of genuine mastery of images and cinematographic language. But there are also many problems -  involving production and distribution, a lack of official support, a shortage of private capital and limited access to international markets. At home, meanwhile, African firms face fierce competition from multi-million dollar productions coming out of the USA, Europe and Asia. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Europe has traditionally offered the only feasible route for those seeking technical and financial resources. The principal donors are the European Union, the ACCT (Cultural and Technical Corporation Agency) and the French Ministry of Cooperation. There are, of course, many instances of African directors producing films without taking this route, but these ventures usually have smaller budgets, and insufficient funds to devote to promotion (press releases, trailers etc). As regards distribution in Belgium, directors face an additional difficulty - they have to take the language issue into account (particularly when films are shown in Flanders).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">African professionals are looking at various ways of solving these problems, including the possibility of coproduction with European operators. For some years now, public and private bodies have also been considering the idea of establishing combined co-production teams in a form of partnership, as a way of supporting African cinema. This topic has been on the agenda of other African film festivals (notably in Amiens) and it came up for discussion in Brussels as well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A colloquium on the subject of ACP/Europe co-production was staged on the fringe of the Brussels event. This served to highlight a number of successful experiments in North/South collaboration. One example was the Cape Verdian film Ilheu de Contenda, by Leao Lopes which was made with support from a Belgian production company, Saga Films. This film was screened at the Festival. It also gave an opportunity to discuss a range of other topics. African journalists accredited to the Festival were given the task of drafting a resolution whose conclusions will be submitted to various contributors including FEPACI (the Pan-African Federation of Film-Makers), the European Union, producers and other donors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There was general agreement that a coherent legal framework for organising relationships between directors and producers, on the basis of mutual trust, was badly needed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Positive results</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is worth making a brief assessment of the efforts made by the organisers of the Brussels Festival to offer an improved programme. The showing of shorts at the beginning of a performance is undoubtedly a formula they should employ again. These works are a specialised genre which give young directors the chance to present their first work. The bulk of the shorts that were screened this year were in the form of 'documentaries' based on fiction - but with one foot in the real world. They dealt with people's lives, their daily concerns, and a variety of social phenomena. Thus, we were presented with films dealing with Aids, urban delinquency, the role of women in society and so on.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another positive point the organisers should concentrate on is the space resewed for English and Portuguese-language films. There were eight performances in this category including four feature films in English and two in Portuguese. A further worthwhile element was the space allocated to African women (from Nigeria, Kenya, Zimbabwe and Burkina Faso) who have chosen to use the cinema as a means of expression.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Diaspora Productions' managers are said to be reasonably satisfied with the way the Festival went. They hope it can continue to be held at the Palais des Beaux-Arts, since they see this as one way of liberating African cultural events from the Afro-Brussels 'ghetto' where they have often been held. They are also keen, in future years, for African films to be shown in Brussels cinemas while the Festival is under way. If this happens, film-goers in Brussels will have the pleasure, from next year, of seeing quality works in their usual cinemas. The timing is appropriate since the 1997 Brussels event will follow the Ouagadougou Festival (Fespaco) which traditionally sees the launch of a number of new films.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Family meeting</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The organisers chose to close the 1996 Festival with a fashion parade which gave Pathe 'O, the designer from Cot&eacute; d'Ivoire, the chance to present his collection to the Brussels audience.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the fringes of the Festival, there was also a musical offering in the shape of the Toure Kunda brothers who came to lend their support to filmmakers and other African artistes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are those who would argue that the Brussels Festival has now entered the category of a 'not-to-bemissed' event. Every year, it attracts significant numbers of film-makers from Africa and the diaspora, even when they have no current projects or films to present. There was a real family atmosphere in the corridors of the Palais des Beaux-Arts, due in no doubt to the absence of competition. From the outset, the Diaspora Productions team chose to stage an event at which prizes were not awarded, thereby promoting reflection and contact with the public. It is generally agreed that the Brussels Festival offers a rare opportunity for film-makers to meet and discuss their productions and projects in a relaxed atmosphere.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The credit for this, in the view of many of the participants, lies with Pape Mbaye Sene, one of the guiding lights of the event, who has also been dubbed the 'high priest' of African cinema. It has, in fact, been suggested tongue-in-cheek that 'in Brussels, they award a Pape, not an Oscar'. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">'We make films... but we do not exist!' - interview with Souleymane Cisse</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The future of African cinema seen through the eyes of the Malian film maker, </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In April, The Courier had the opportunity of meeting Souleymane Cisse, one of Africa's most celebrated film-makers, who has won several awards at major international film festivals. His films, such as Yeelen, which was awarded the Prix du Jury in Cannes in 1987 (the first African film to receive such a prestigious accolade), Waati, which was entered at the same festival, and Finye, have already become classics. Cisse is not just a director, he also produces his own films. In 1972, he impressed international critics by single-handedly producing a short film of exceptionally high quality Cinq jours d'une vie -  which won an award at the Carthage Film Festival. By relying, above all, on his own limited resources, combined with a powerful determination to develop and promote Africa's film industry, Souleymane Cisse has an implied but powerful message for the entire African continent. When he went on stage at the Palais des Festivals in 1987 to receive his award for Yeelen, he said that he was accepting it on behalf of all those who did not have the opportunity to speak for themselves. In particular, he dedicated the film to all the South African technicians who had worked together with him on the project. His has made spirited efforts to boost the African film industry and it was in this context that he helped set up the 'Union of African cinema and audiovisual producers and entrepreneurs' last March. This organisation aims to encourage African countries (especially in West Africa), to take the necessary political decisions to ensure the survival and grouwth of African cinema. When we spoke to Souleymane Cisse, our discussion ranged far and wide. We began by asking the film director whether African art gets the recognition it deserves in Europe? He seemed surprised at the question but then, without hesitation, proceeded to explain his own approach - with the emphasis on the political rather than the aesthetic.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The recognition that African art gets in the West has more to do with politics than aesthetic discernment. Such recognition evolves from the spirit of Africa's relations with the other continents, a spirit which is often devoid of all honesty. We stand at the threshold of the 21st century. We should be looking to develop ways of communicating with each other and finding common ground. We should be able to look each other in the eye. When, for example, people in France debate whether or not the Louvre should have a gallery of African art, it begs the question, 'who is asking for what ?'. When some people wonder whether or not African art really is art, they are asking themselves a pointless question. African art is. Nothing more, nothing less. In any case, the West has some highly contradictory views as far as the whole idea of art in Africa is concerned. On the one hand they dispute the fact that the culture of the Ancient Egyptians was, in essence, an African one, and yet on the other hand the characters of Ancient Egypt - in films for example - are always portrayed as dark-skinned. African art is the 'in' thing at the moment, despite the current tendency to belittle Africa. They think that today's Black Americans and Afro-Caribbeans can be made to forget their African roots, but that just will not happen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Generally speaking, do you think that African politicians should devote time and energy to this battle to defend African culture when their countries face such insurmountable material problems ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> -  Once they have gained power, the obsessive preoccupation of our politicians has been to concentrate on economic policies, neglecting their countries' cultural needs. But without a deeply-rooted culture, you cannot discuss matters on equal terms with representatives of other nations. In their heart of hearts, they will not respect you fully. There have been two or three countries which have tried to combine economic development with cultural development - I'm thinking of Guinea under Sekou Toure, Mali under Modibo Keita and Ghana under Kwame Nkrumah, but in one way or another, all three have been thwarted, for their perceptiveness. I am not now commenting on, or necessarily agreeing with, their domestic policies, but rather with the broad vision they shared for Africa as a whole. The fact that Europe is currently in the process of forging the European Union will be an instrumental force in the opening up of other regions of the globe. It was Europe, after all, which divided much of the world into English speakers, French speakers, Portuguese speakers, Spanish speakers and so on. Now that Europeans are themselves seeking to unite their countries, how could they possibly object to a similar union in Africa - for the sake of its cultural identity. This idea of a United Europe is, therefore, a welcome one. What is more, I believe that the issue has already been tackled within relations between the European Union and ACP countries. Not only is Africa the continent closest to Europe; it is in helping to develop the African continent that Europe has most to gain.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· The cultural aspect has already been incorporated into Lom&eacute; IV, but it seems that ACP countries do not attach as much importance as they should to such matters when drawing up their lists of priorities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Many of the politicians in charge of these countries themselves lack any sort of culture. Alternatively, stripped of their own culture, they flaunt that of a foreign land. They say that health care is a priority, that food is a priority, but cultural needs do not figure on their list. Yet culture forms part of an urgent need. You'll see - as soon as any sort of cultural development takes place in a country, or wherever a country already has a viable, thriving culture, its economy will also flourish; of that there is no doubt. A nation which has a highly developed culture will always be able to stand on its own two feet economically. Take, for example, the nations of the former Soviet Union  - their economies may be unstable at the moment. It's only natural that they have to start from scratch, but as long as they manage to hold on to their cultures, they will pull through. These countries will not lag behind as Africa has done.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· It costs money to operate a film industry. Have you found that your reputation as a director has made the financial side of things any easier for you ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - I don't honestly think much has changed in the way we finance our films. Perhaps I should only speak for myself, but I do not believe it is any easier for me than it is for young filmmakers. Mali has no film production facilities, so we are all in the same boat. That is why we organised a colloquium in March this year, aimed at getting a picture of the exact state of West Africa's film industry. What we learned was that it is in pretty bad state. We make films but, in a certain sense, we don't really exist as a film industry. I would dearly like my works to be screened, for example, in Mali, Guinea and Senegal, but that is not possible because the distribution and screening networks are no longer there. Even the most liberal Western countries have passed laws to promote and protect their local film industries, so why don't we do the same ? I cannot make films in the United States without first going through various unions and other professional associations. In France, I cannot distribute my films the way I want, and if I want to make a film, I have to make it through French producers. If people come to work here, they should have to use national producers. The relevant laws were drawn up three or four years ago, but they still haven't been passed. We want all those involved in the film industry to have the opportunity to be true professionals. There should be assistance available to modernise projection rooms and theatres. We are currently in the process of setting up the 'Union of African cinema and audiovisual producers and entrepreneurs' which should help to persuade governments to take our requests into account.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Isn't African cinema also a victim of television ? </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - The problem in Mali is a very simple one. We live in a country where people like to get out and about. The cinema is somewhere they can do that quite easily. So people use it as a place where they can meet up in the evening, just as they like to congregate around the fire to sing and dance. So why are our cinemas empty ? Because when people do go to the cinema, they cannot see the screen properly or they cannot hear the soundtrack, or they are uncomfortable sitting on broken and rickety chairs. If you can provide a suitable and comfortable environment for them, people will start going to the cinema again. That doesn't mean that television doesn't have its place, but people like to go out. This is especially the case with our open air cinemas, which are the perfect places for people to come together, have a chat, enjoy each other's company and relax. A nice auditorium, a good film, and you'll see how the queues will form. All we need to do is upgrade the auditoria, re-equip the projection rooms, overhaul the sound systems, put new chairs in - just a few basic comforts. When people go out to the cinema, it's because they want to escape from their humdrum routine for a while, to dream and unwind.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">African governments should do what they can to enable people to relax and enjoy themselves like this. Going to the cinema is like going to school. People go there to learn something - whether consciously or subconsciously - and to see something different. We really must get rid of this purely commercial vision of the cinema, especially in Africa. It should, first and foremost, be a cultural experience, and only subsequently a commercial exercise. But we also need to be realistic. When helping those involved in promoting the film industry, the government should lay down a precise set of conditions, specifying how and when the loans should be repaid and requiring something in return for their subsidies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· So you think that if the Ministries of Culture in African countries were given greater powers, they would be in a position to carry out this task ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - It is not something solely for the Ministry of Culture. This is the type of approach which should be adopted by the state as a whole, in each country. For example, the government should provide a support fund for the film industry and certain other branches of the arts. Even if they were increased substantially, the meagre budgets allocated to the Ministry of Culture in our countries would still represent paltry sums. In Africa, the department of culture is at the bottom of everybody's list.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· But if you look at the number of African films that have been shown in recent years at Cannes and other international festivals, surely one can afford to be a little more optimistic than you are ? More and more young African filmmakers are releasing films.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - True, but as I said earlier, no progress has been made as far as film production is concerned. In that respect, contrary to what people may think, we are still at square one. Young filmmakers are put off and, as more and more avenues are closed to them, they gradually lose their fighting spirit. A film director has no choice but to be his own producer, his own manager - to do everything himself in fact. The result is that he becomes a jack of all trades and a master of none. During our recent colloquium, we decided to set up smallscale facilities which will deal solely with film production and where young people can go and use their services, thus leaving them free to channel their energies into actually directing their films. In the same way, we intend to set up other structures which will deal exclusively with other aspects of the cinema industry. The goal we have set ourselves is that of fostering professionalism in the West African film industry. Maybe then our governments will listen to us.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· Do you think there is any difference between African countries as far as opportunities are concerned ? For example, Burkina Faso would appear to be the cinema capital of Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - Yes, and no. More often than not, it is African film-makers who have chosen Burkina Faso to stage events connected with the cinema industry because it is a landlocked country. This is what has made it the film capital of Africa, not any deliberate move on the part of the politicians. Having said this, the government in Burkina Faso is also making great efforts, despite its limited resources. But each country has its own potential. We must stop trying to tear this continent apart.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">· You mentioned the former President of your own country, Modibo Keita, as one of those far-sighted enough to appreciate the importance of nurturing African culture. Where does Mali stand at the moment in terms of strengthening its own cultural heritage identity ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - After independence, in the years from 1960 to 1968, there was a time when young people would get together and become involved in various biennial art festivals. We had a series of events which encouraged a kind of a 'cultural vision' nationwide. They were so successful that other countries were soon following our example. After the coup in 1968, however, everything fell apart. In the following 23 years there was a total cultural vacuum, in which young people felt completely disorientated, despite superficial attempts to relaunch the festivals. We are now only just trying to rediscover our cultural roots after a long period of upheaval. What we in Mali do have working in our favour, is the fact that our country is a harmonious patchwork of different peoples, all living together without the slightest trace of bitterness or hatred. We are lucky here because our rulers rarely tried to manipulate our ethnic loyalties to set one group against another. A Malian, irrespective of his roots, will always rejoice in the success of his fellow countrymen, whatever tribe they happen to belong to. We owe our good fortune to a heritage in which our peoples have always respected one another - even when they have faced each other as enemies. It is only as a result of this historic mutual respect that we can now speak of a Malian culture where each individual group of people has its own idiosyncrasies, its own customs, is sensitive towards other cultures and actually rejoices in their differences. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">CTA Bulletin</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">CTA and the promotion of rural development through book distribution</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One of CTA's tasks is to provide information on request to researchers, extension workers, planners, farmers' organisations, trainers and information specialists involved in agricultural development in ACP states. In addition to requested publications, CTA also distributes publications on its own initiative to its target groups. These publications, some 550 titles, are also supplied free of charge and consist of books published by CTA, co-published, or purchased specially because of their relevance. In 1995, almost 65 000 books were posted to ACP countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The people who receive the publications to some extent select themselves, because they write to CTA with requests for information. They find out about its existence through attending CTA seminars held in ACP countries or in Europe, or through seeing copies of Spore (CTA's bi-monthly bulletin in English, French and Portuguese which goes to around 50 000 addresses and is seen by many more), or by word of mouth. Over the years, CTA has built up a mailing list of 42 500 addresses of people and organisations active in some way in agriculture and rural development. Of the total, 37 800 are in ACP countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But there are questions. Are our books getting to those who need them and is the targeting accurate enough? And, most importantly, is this the best way of doing things ? For CTA does not - and cannot - satisfy the total demand for books on agriculture and rural development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">What is the best way?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite the number of addresses on the mailing list, many more people could in theory still be added. Should CTA even try to satisfy this demand ? The publications are free and, if CTA increased its coverage of the demand, it might in some countries hold back the development of local bookselling with a consequent detrimental effect on local publishing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The majority of those now on the mailing list are 'individuals' rather than institutions, libraries, documentation centres, associations, organisations, etc. On the face of it, more people could be reached by sending CTA publications to groups rather than to individuals, but it's not always clear who is an individual in the sense of information not being shared with others. Some individuals are teachers, some are extension agents, some receive publications on behalf of a cooperative, for example.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Because of the importance of information - the driving force behind development  -  CTA has been investigating and giving support to technical publishing and book distribution in Africa over the last few years and is currently examining its own policy on book distribution over the ACP countries as a whole. Part of the context for this policy re-appraisal is the state of bookselling.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Difficulty of book distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Everyone involved in the books business in and for the ACP countries knows that getting books where you want them to go, book distribution, is not straightforward. The reasons for the difficulty are not straightforward either. One development officer remarked of Papua New Guinea that the lack of books outside the capital, Port Moresby, couldn't simply be explained by lack of roads, because in the most out of the way places you could be sure of finding Coca Cola. Is it, then, that the Coca Cola company has superior marketing and distribution arrangements ? Probably so, but it is the nature of the two products which also determines how far they get. Traders will more readily take goods which they know they will be able to sell easily and the immediate satisfaction given by cigarettes or Coca Cola tends to put them before books in the list of priorities for purchase.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Among the ACP countries where CTA sends books and information, many have under-developed road and rail networks while the postal facilities provide a reliable service only to a relatively small part of the country. The local book publishing and bookselling industries are often themselves developing. Potential readers often cannot afford to buy the books and consequently book distribution is the weak link in the chain from writing and publishing a book to selling it. If books can't be sold, new ones can't be published, for the investment finance for a new publishing project has to come from somewhere.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Africa, the lack of a strong local book sector was attributed in part to the traditional oral culture of the continent which left little need for reading. The majority of students would read in order to pass their exams, after which they hardly sought books again to buy or to read.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The main books distributed were therefore textbooks for schools, colleges and for higher education. As long as these were distributed through booksellers, a forum still existed for displaying and raising interest in other books.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Booksellers could also function as sources and conduits of information about the variety of books in print and of their interest to particular groups.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This development was stunted because of the low purchasing power of many people, lack of foreign exchange (except in the CFA franc states), high cost of importing (either books or the raw materials, print machinery and spare parts to manufacture books) and, consequentially, shortage and lack of variety of locally-published books.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition, in some countries the state intervened in school book publishing and supply (for example in Tanzania), so that the bread and butter of the bookselling business disappeared.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Booksellers then either diversified their stock so that they became bookseller-stationers or worse - books came after groceries, footballs, hats, etc., or the booksellers ceased trading in books or closed down.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The publishing-distribution chain in Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Book distribution is part of a chain of activities in the book sector which depend on each other and support each other. The chain starts with an idea for a book which may come from an author or from potential readers who make known their needs and it ends with the published books being bought. The lack of a good book distribution infrastructure in Africa is linked to the lack of a wide variety of books from a good number of publishers and the lack of a market for the books.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At least until South Africa became a democracy, Nigeria probably had the most active publishing industry in Africa with a high level of publishing professionalism. In such a huge country this may not be surprising: there is a large market, state administrations with urban headquarters, and a variety of arrangements for publishing and distributing books. But publishers suffer from a scarcity of investment funds, with high costs of borrowing, which affects their ability to keep books in print and to start new publishing projects. Relatively few technical books are published locally because of the risks when compared with, for example, publishing school textbooks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In such a vast country, the state of book distribution varies from place to place, with cities and large towns obviously having a greater variety of books available for sale than small towns and rural areas. Small traders carry books to the latter; they do not take orders and the books they carry are those that they can get hold of which they think will sell. Would-be readers are frustrated unless they or their friends visit a city. Mail order is not a possibility because the domestic postal service is not trusted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the urban areas, where there are booksellers, an indeterminate number of potential readers cannot afford to buy books, especially those that have been imported. Book piracy is a consequence of this. Booksellers' sales have declined, their turnover has been reduced as has their ability to stay in business. Some institutions in the country buy direct from publishers or from overseas suppliers rather than from booksellers, which further damages them. Booksellers buy books from publishers in small quantities for a fast turn-round which affects publishers' ability to build up investment funds for the next publishing project or for a large reprint with its possibility of reducing unit book costs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This is not to say that technical books are totally unavailable from Nigerian booksellers, but it is clear that only specialised outlets which know their book-buying customers well can risk stocking some of them. Rural dwellers have no chance of buying them without making a big effort in time and money.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In contrast, Senegal has a less developed publishing and bookselling industry than Nigeria, with about a dozen professional publishers and a small network of booksellers, mostly in Dakar and the larger towns in the regions. The most important publishing opportunities in Senegal are in the field of primary school textbooks - where there is competition both within the country, with publishers from other developing states, and from the North. Senegal being a lot smaller than Nigeria, there is only room for one textbook, and primary school book production is not therefore the mainstay of local publishers. The publisher which used to supply all primary and secondary school textbooks for the Ministry of National Education is an exception and is still probably dependent upon educational publishing for its turnover. Few technical books are published; as with books for higher education, they are imported.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The network of booksellers has been decreasing and it is difficult to make a living just by selling books without the back-up of other products to sell. Thus there are bookseller-stationers, bookseller-grocers, kiosks and street sellers, especially of secondhand books. Booksellers tend to order titles in small quantities because they cannot risk being left with unsold stock which ties up their capital. They order little and often. Most school textbooks are distributed through the Ministry of National Education, but booksellers still sell a variety of textbooks, some official and approved and some not. Before the devaluation of the CFA franc, booksellers ordered more from abroad. These books have now doubled in price, making them unaffordable, with a consequent opportunity opened for local publishers to fill a gap.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Apart from the professional publishers, various sorts of publications are being produced and distributed by literacy and post-literacy organisations and a delegated literacy ministry. Some organisations promote literacy for its own sake, while others use the attainment of literacy as the means through which development can spread in rural areas. The publications concern rural development, agriculture, health and nutrition, and rural democracy, amongst others. There is a good variety of different titles and a good supply of cheap and affordable books. Some are sold through booksellers, but most people buy them when they take their literacy courses, while small traders carry them up-country to sell and buy more copies from the publishers with the proceeds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Book aid schemes</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A whole literature exists on book aid schemes. Briefly, book aid comes in two forms, one using the local book sector and the other not to any great extent. The British Government's Educational Low Prices Books Scheme (sadly scheduled to end, at least in its present form, in April 1997) and the French Government's Programme Plus both use the local bookselling industry to make available standard tertiary textbooks and others at subsidised rates. Not all students could afford to buy them, but the two schemes nonetheless promote bookselling and commercial life within ACP countries and beyond. To some extent they safeguard the continuation of fore where up-to-date books can be seen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CTA's books aid scheme does not use the local book sector in terms of book distribution, although cooperation in co-publishing is beginning. The FAO, in distributing publications to ACP and other developing countries, is similar. Books supplied under multilateral and bilateral agencies' projects have tended to sidestep the local book sector, although this has been changing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As with food aid, the question to be answered is whether continuing the aid prolongs the condition ? Or does the analogy with food aid break down in certain circumstances because books are different ?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Improving book distribution in Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Various efforts are being made to improve book markets for African publishers. For example, the African Books Collective, based in Oxford, UK, markets and sells both anglophone and francophone African publishers' selected books in the North and also to other African countries. It is often easier for publishers in the North to sell their books in Africa than it is for African publishers to sell their books across frontiers and in the continent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Publishers Associations have been formed in about a dozen countries with APNET, the African Publishers' Network, celebrating its fourth year as a continental association. CTA supported APNET in the production of the first catalogue of agricultural books published by African publishers. Very recently, an Africa-wide booksellers association has been created.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">CTA and future book distribution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Since CTA started distributing books on agriculture and rural development, publishing and bookselling activities in many ACP countries have multiplied and the context has changed somewhat. As noted at CTA's Montpellier conference in 1995, there is now much information and many documents going from North to South, suited to the planners, research workers and extension agents who process the information and pass it down to the small-scale farmers. Rather, a two-way information route would be more efficient, between farmers who have information to offer as well as information needs and information providers. The growth in requests to CTA for publications from co-operatives and farmer associations and from non-academic libraries and documentation units is evidence that the publications distribution service is fulfilling a need. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The Couriers mailbag</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Earthen architecture</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">I read your article on 'Earthen Architecture', published by the CTA Bulletin in the September-October 1996 issue of The Courier (n° 159) with a great deal of interest.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The article presents such traditional products as rammed earth and adobe which have been used by man since time immemorial as witnessed by constructions and monuments to be found in the countries cited by the authors of the article, as well as industrial products such as the compressed earth block (CEB), which have provoked much interest in many parts of the world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The authors also demonstrate that the use of the compressed earth block has a distinct advantage in that it valorises local raw materials, encourages the setting up of local enterprises and creates employment.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this regard, I would particularly wish to inform you that the Centre for the Development of Industry (CDI) has, for the last ten years, been working on the industrial development of the CEB sector through support to ACP promoters at various levels:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - diagnostic studies of projects and setting-up of production units;</P>
+<P ALIGN="JUSTIFY"> - search for EU technical partners who have economically advantageous technologies and are ready to transfer their know-how;</P>
+<P ALIGN="JUSTIFY">- training of enterprise personnel in CEB production and in the utilisation of this product;</P>
+<P ALIGN="JUSTIFY">- support in the manufacturing of brick presses such as is currently the case in Nigeria.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some 100 small and mediumsized enterprises and non-governmental organisations in ACP countries involved in the CEB sector have benefited from direct CDI assistance. This assistance has, notably, led to the improved technical and economic performance of these enterprises.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Beyond support to projects, the CDI in collaboration with CRATerre actively participates in the industrial promotion of this technology. The Centre recently disseminated 2000 copies of a technical guide entitled 'CEB: Production Equipment' throughout the ACP countries. An exhibition on the compressed earth block and its application took place during the Industrial Mining Forum held in Lusaka, Zambia, in December 1994. Similar exhibitions were held during the Matconstruct Forum (Libreville, Gabon, October 1995) and at the Industrial Partnership event (Bordeaux, France, February 1995). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The standardisation of the compressed earth block is a prerequisite for the development of this sector. The Centre therefore organised a workshop on this topic in Yaounde in 1996 as a follow-up to the Matconstruct Forum. This seminar brought together some 40 ACP and EU participants to discuss the 'CEB: Standardisation' guide currently being prepared by CRATerre for publication in December 1996.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The main objective of the guide is to encourage ACP promoters to manufacture products in conformity with accepted norms and thus facilitate CEB integration in the industrial construction market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Efforts made by the CDI, in collaboration with CRATerre, to develop the CEB sector deserve to be better known. We would therefore look forward to an opportunity to present the Centre's activities in this sector in a future issue of me Courier. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Surendra Sharma, Director, Centre for the Development of Industry,</P>
+<P ALIGN="JUSTIFY">Brussels, Belgium.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Map insets</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thank-you for your informative magazine. I wish you all the best in your endeavours to improve me Courier further. May I suggest that in the Country Report profiles, you include an inset map of the region highlighting the country in question for those readers who may not be familiar with the area.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Andrew Frederick Meya, Kampala, Uganda.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A number of readers have raised this point with us since we have rearranged the cover pages and transferred the ACP and Europe 'regional' maps to the inside back cover. In future, we will endeavour to ensure that there is a cross-reference to this page in the Country Report profile. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Bibliography</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Publications received</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">La politique etrangere du Cameroun (Cameroon's foreign policy) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By Narcisse Mouelle Kombi. Pub. L'Harmattan, Collection «Points de vue» (5-7, rue de l'Ecole Polytechnique, F-75005 Paris). 1996. 238 pp. ISBN 2-73843701-X.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cameroon belongs to the zone formerly called the 'Third World' which is nowadays labelled the 'South'. This region of great diversity currently faces major socio-economic and political conflict, and receives 'multiform' and 'tied' aid from the developed countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This does not, however, prevent it from having a degree of freedom of action in diplomatic terms.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The author, who is a specialist in international law, believes that as a player on the world scene, Cameroon puts its foreign-policy skills to good advantage and has acquired a certain respect in international relations and in global institutions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He argues that Yaounde is attempting to implement a realistic and pragmatic foreign policy, reflecting its own sovereign status and the imperatives of development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the same time, the country is endeavouring to implement the changes forced upon it by modern circumstances.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Le developpement institutionnel - Les organisations a l'epreuve de la specificite et de la concurrence (Institutional development - Organisations based on specificity and competition) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By Arturo Israel. Translated from the English by Alain Claisse. Pub. L'Harmattan (5-7, me de l'Ecole Polytechnique, F-75005 Paris). 1996. 235 pp. 140 FF. ISBN 2-73844322-2.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A graduate of the University of Chile and the London School of Economics, the author has devoted most of his career (particularly within the World Bank) to examining the problems of economic and social development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He has been one of the pioneers of institutional development, a field which is nowadays seen as essential to all development strategies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He argues that institutional development requires not bureaucratisation but the promotion and recognition of two principles in both public and private organisations. These are competition and specificity. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The former induces those involved to improve the quality of their work, whilst forcing them to listen to the 'consumer'. The latter involves qualifications, specialisation and a precise definition of objectives, tasks, resources and results.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">After a critical review of assessment reports produced over a 15-year period by the World Bank in the field of institutional development, Arturo Israel tells us why such development is one of the keys to success in development projects. He demonstrates that a good project being implemented in an unfavourable institutional environment has little chance of achieving positive long-term effects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">La justice internationale face au drame rwandais (International justice confronted by the Rwandan crisis) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under the direction of Jean-Fran&ccedil;oise Dupaquier, with William Bourdon, Pierre-Serge Heger, Frederic Mutagwera, Fran,cois-Xavier Nsanzuwera, Rakiya Omaar, William A. Schabas and Anne-Marie Swartenbroekx. Pub. Karthala (22-24, boulevard Arago, F-75013, Paris). 1996. 248 pp. FF 130. BF. 715. ISBN 2-86537-662-1.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is two years since the genocide and political massacres which resulted in the death of a million people in Rwanda. In this work, the authors describe and analyse the progress made in various legal proceedings in Rwanda itself, in the international arena and in the jurisdictions of Belgium, France, Canada and Switzerland.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some countries have been slow and apparently reluctant to fulfil their international obligations and this has resulted in disappointment and impatience on the part of the victims' families, jurists and human rights activists.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Given the example of the Nuremberg trials, the authors suggest there are good grounds for concluding that international human rights have become less important over the last 50 years. This work allows one to reach a considered opinion. Modern legal instruments provide for the punishment of those responsible for the appalling tragedy in Rwanda. These instruments could be seen as a significant advance in the recognition of human rights by the international community. But what is missing at the moment is the political will (and public pressure) to implement them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Methodologies d'analyse de la mortalite des enfants - Applications au Cameroun (Analytical methodologies in child mortality as applied to Cameroon) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By Amadou Noumbissi. Pub. Braylant-Academia (25, Grand Rue, B-134B Louvainla-Neuve) and L'Harmattan (5-7, rue de l'Ecole Polytechnique, F-75005 Paris). 1996. 305 pp. ISBN 2-87209389-3 (Academia-Braylant) and ISBN 2-7384-3722-2 (L'Harmattan).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Child mortality, always very high in sub-Saharan Africa, varies according to social class, habitat and region. The identification of the social, economic and cultural factors which influence the survival of children depends on the quality of data, and on the relevance of the indicators and statistical models used.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">With the aid of specific examples, this work attempts to demonstrate the origin of a number of sources of bias in so-called classical approaches and the distortion of the truth which a poor choice or detrimental manipulation of statistical models can give rise to.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A teacher and researcher at the Demographic Institute of the Catholic University of Louvain (Belgium), the author proposes methods to take account of the interdependence and synergy which exist between the factors which affect the risk of mortality. He applies these methods to the data gained in two national surveys which were carried out in Cameroon in 1978 and 1991.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Revue Region et Developpement (Region and Development Journal)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pub. L'Harmattan (5-7, rue de l'Ecole Polytechnique, F75005 Paris). 1995. 238 pp. ISBN 2-7384-4125-4</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This half-yearly journal, first launched in 1995, deals with the various socio-economic aspects of regional development. The second issue contains articles which may be of interest to our readers, including: 'Regionalisation, globalisation and polarisation of the world economy: is there room for developing countries?', and 'Housing models in developing countries'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Structural adjustment and ethnicity in Nigeria</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">By Eghosa E. Osaghae. Pub. The Nordic Africa Institute (P.O. Box 1703, S-751 47 Uppsala, Sweden). 1995. 66 pp. ISBN 91-7106373-0.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The author is a lecturer who heads the politics department at the University of Transkei in South Africa. A significant conclusion from his study, undertaken at the Nordic Africa Institute, is that from the ethnic standpoint, the implementation of structural adjustment (with its corollary of reduced state involvement in public life), has had positive effects in Nigeria. This contrasts with the usual perception of the structural adjustment process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The migration experience in Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Collection prepared under the direction of Jonathan Baker and Tade Akin Aina. Pub. The Nordic Africa Institute (P.O. Box 1703, S-751 47 Uppsala, Sweden). 1995. 353 pp. ISBN-91-7106366-8.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This volume aims to take stock of migration in Africa. The causes of the phenomenon are varied and complex, and the authors have chosen an approach which illustrates the diversity of the theories, and methodological and analytical trends involved.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The book offers an empirical assessment of migration in contemporary Africa, focusing particularly on the problem of women migrants. Migration is an important element in the wider development equation and this work fills a gap in the literature.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Challenges to the Nation-State in Africa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Collection prepared under the direction of Adebayo O. Olukoshi and Liisa Laakso. Pub. The Nordic Africa Institute (P.O. Box 1703, S-751 47 Uppsala, Sweden) in collaboration with the Institute of Development Studies, University of Helsinki. 1996. 213 pp. ISBN 91-7106381-1.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The challenge confronting the nation state in contemporary Africa are of great interest to specialists attempting to understand how deconstruction and recomposition of the political identity of populations affects the post-colonial unitarian project. The studies offered in this volume show that this process has often taken ethno-regionalist, religious or separatist forms -  reinforced by economic crisis and the negative effects of structural adjustment, not to mention the legacy of years of political authoritarianism and exclusion dating from the colonial period.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The authors believe that in order to promote national unity and a sense of citizenship in Africa, priority should be given, inter alia, to more representative forms of government, power-sharing and decentralisation, multi-party elections, the reinvention of the post-colonial social contract and cultural autonomy for minority groups.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agenda for Africa's economic renewal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Collection prepared under the direction of Benno Ndulu and Nicolas van de Walle. Pub. Overseas Department Council (1875 Connecticut Avenue, NW, Suite 1012, Washington, DC 20009, USA). 1996. 246 pp. ISBN 1-56000900-4.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For 20 years, sub-Saharan Africa has been experiencing a severe economic crisis. Growth has been stagnant and the result has been reduced living standards for much of the population, and ever-increasing pressure on the continent's political structures. Structural adjustment, advocated by international organisations in an attempt to restore growth in Africa, has not had the anticipated results and has given rise to a number of disputes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this book, 10 African, US and European experts attempt to look beyond the immediate horizon and identify strategies which could be implemented to give renewed vigour to the African economy. They analyse the choices which should be made in key areas such as agriculture, trade and industry, the role of the state and the social sectors. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">News round - up</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<I><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">In brief</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">World congress against the sexual exploitation of children</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first international congress dealing with the problem of the sexual exploitation of children for profit was held in Stockholm from 27 to 31 August. The initiative for the meeting came from ECPAT (End Child Prostitution in Asian Tourism), working in collaboration with the Swedish government, the United Nations Children's Fund (UNICEF) and a group of NGOs supporting the Convention on the Rights of the Child. The congress was attended by government representatives from most of the UN countries, participants from various international and regional organisations (including the UN Centre for Human Rights, the International Labour Organisation, the World Health Organisation, UNESCO, UNHCR and Interpol), NGOs, health professionals and media representatives from across the globe.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The aim of the congress was to draw the international community's attention to the issue of the sexual exploitation of children and to promote the development of national plans to tackle all forms of abuse in this area. It focused particularly on three aspects: child prostitution, the 'trade' in children for sexual purposes, and child pornography.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although there are a number of legal instruments which refer to these problems, the key one for the purposes of the Stockholm meeting was the Convention on the Rights of the Child. In Article 34 of this multilateral treaty, which has been ratified by 186 countries, the signatory states commit themselves to protect children against all forms of exploitation and violence of a sexual nature. For the purposes of the Convention, a child is defined as any human being less than 18 years old, except where the age of majority is lower than 18 in the relevant local legislation (Article 1).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The committee that was responsible for planning the Congress drew up documents on a number of themes including: the revision and application of laws; psycho-social prevention; tourism and child prostitution; those who engage in abuse; hygiene and health; the role of the media; child pornography; education; and human values. These subjects were all examined by working groups during the two-day session.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The congress was addressed by Anita Gradin, Member of the European Commission with responsibility for internal and judicial affairs, and matters relating to immigration. She took the opportunity to underline the point that the traffic in women and children was international. Organised crime, she said, lay at the heart of the 'trade' and it was closely linked to a whole range of other criminal activities. She cited, in this context, kidnapping, forging of documents, 'false' marriages and adoptions, clandestine immigration, violence and forced labour. these, in turn were associated with the drug trade, extortion and murder. The conclusion was that a global action plan and more international cooperation were needed. Ms Gradin acknowledged that existing arrangements had been successful in exposing the existence of paedophile networks but she was convinced that international cooperation should be strengthened further, and that organisations such as Interpol and Europol would be called upon to play a bigger part in the future. The European Commissioner went on to declare that a commitment to the protection of children ought to be a priority. The UN Convention on the Rights of the Child - which is now eight years old -  should not merely tee 'adopted' by all countries. It should, rather, be applied in full and integrated into the legislation of every nation. There was no point, she suggested, in enacting new laws, if the existing ones were not being implemented and the financial resources had not been provided. Ms Gradin reaffirmed the European Commission's commitment to the fight against the exploitation of children. This would be reflected in communications to be drawn up by the Commission for presentation to the Council of Ministers and European Parliament, on the following subjects:  - the treatment of women (on the basis of the recommendations made by the Vienna Conference on this subject, which was held in June 1996);  - sex tourism, notably in certain countries in Asia and Latin America;  - actions designed to eliminate paedophile rings and child pornography networks which make use of new information technologies such as the Internet. During the congress, the Belgian Minister of Foreign Affairs announced that his country would be launching an initiative at the EC's Justice and Internal Affairs Council meeting scheduled for 26 and 27 September. They would be proposing common action designed to strengthen police and judicial cooperation in the fight against the sexual exploitation of children for profit. He believed that it should be possible to take measures both within the framework of the Europol Convention, and by means of new and specific cooperation instruments. The culmination of the Stockholm congress was the adoption of a declaration and an action plan. These foresee strengthened cooperation and coordination among local and national authorities, and a series of measures to protect children, prevent abuse and provide rehabilitation. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">1997: European year against racism </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In a resolution adopted on 23 July, the Council of Ministers formally designated 1997 as the European year against racism. The aims, set out in the resolution, include:  - highlighting the threat posed by racism, xenophobia and antisemitism, in terms of both respect for fundamental rights, and in ensuring the economic and social cohesion of the European Community;  - encouraging reflection and discussion of the measures needed to tackle racism, xenophobia and antisemitism in Europe;  - promoting a sharing of experiences, best practice, and effective strategies drawn up at the local, national and European levels;  - disseminating information on the aforementioned best practice and strategies amongst those most closely involved in the fight against racism, xenophobia and antisemitism, with a view to enhancing the effectiveness of their actions in this area;  - highlighting the advantages of integration policies implemented at the national level, in particular in the fields of employment, education, training and housing;  - taking account, wherever possible, of the experiences of victims of racism, xenophobia and antisemitism, and promoting the participation of these people in society. ECU 6 million will be spent on a series of activities designed to help achieve these objectives during the 'year against racism'. A logo and slogan will be devised, and seminars and conferences will be staged with the aim of strengthening international cooperation (themes will include the role of education in eliminating racism, ways of establishing dialogue, and establishing mutual respect between different communities living in towns and cities). Documents and audiovisual material will be distributed, and an effort will be made to get the message across in the media. There will also be action to encourage information exchanges on best practice, and to increase public awareness of the issue. Prizes will be awarded to media organisations which safeguard the quality of the information they put out and which seek to promote tolerance. A specific effort will be made to counter the racist propaganda now appearing on the Internet.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">WTO banana challenge</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union has set out its legal defence of duty-free preferences for African and Caribbean banana producing countries that are members of the Fourth Lom&eacute; Convention. This took place in September at an initial hearing of a World Trade Organisation (WTO) panel  - convened at the request of a number of competing banana producer nations. African and Caribbean states were permitted to voice their opinion as third part)" in the case, despite an objection from the United States. The EU's banana market arrangements  - notably Protocol 5 of the Lom&eacute; Convention, which sanctions duty-free access  - have twice before come under attack in the Geneva body. Two earlier hearings in the WTO's forerunner, the General Agreement on Tariffs and Trade (GATT), concerned the EU's previous state-to-state regime, and the new single market arrangements which have been in operation since July 1993. The present panel was set up at the request of four Latin American banana producer nations - Ecuador, Honduras, Mexico and Guatemala - together with the United States which is arguing that its domestic banana companies are losing out. The complainants jointly claim that the tariff quota for Latin American nations, the core of regulation 404/93 establishing the EU regime, discriminates against them. They also challenge the licensing arrangements of the so-called 'framework agreement' made under the GATT framework in 1994 with four Latin American nations (Colombia, Costa Rica, Nicaragua and Venezuela). In return for a bigger share of the EU market, these four agreed to refrain from further challenges in the WTO against the EU's banana arrangements.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The panel is expected to give its verdict in March 1997. The hearings are taking place behind closed doors, but it is understood that EU and ACP nations can count on the support of Japan - which currently imposes its own quotas on imports of other items and does not want to be challenged for these - and that of India which wants to show solidarity with the ACP countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Speaking in Geneva, Cot&eacute; d'lvoire's Commodities Minister, Alain Gauze, stressed the heavy dependence of many African and Caribbean states on banana growing. 90% of Dominica's commodity exports are bananas and the crop accounts for 70% of its export receipts and 25% of its Gross Domestic Product.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One ACP representative in Brussels described the task ahead es 'convincing them (the panel) that the banana regime and regulation 404/93 are required to fulfil the obligations of the EU under the Lom&eacute; Convention and the subsequent waiver.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The waiver to which he referred was accorded by GATT to the Lom&eacute; Convention's various non-reciprocal trade preferences in 1994, but it is up for renewal at the end of the year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU has already put in a request for its extension until February 29, 2000, coinciding with the expiry date of Lom&eacute; IV.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The WTO was expected to rule on the renewal of the waiver in mid-October ahead of the panel's decision. If the renewal of the waiver were to be disallowed, the EU and ACP 'defendants' at the panel could find themselves on shaky legal ground.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the meantime, the EU has fixed its 1996 tariff quota, allowing a maximum of 2.553 million tonnes of Latin American bananas to be imported into the Union with a tariff of ECU 75 per tonne.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A further quota of 72 440 tonnes has been allocated to this region following tropical storms Iris, Luis et Marilyn. The damage caused by these storms led to the suspension of supplies of bananas from several Caribbean islands. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">EU banana production is expected to reach 750 000 tonnes in 1996, while preferential imports from the African and Caribbean members of the ACP group have been fixed at 680 000 tonnes. According to latest predictions, the total consumption of this fruit in the European Union in 1996 will be 4030440 tonnes. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">D.P.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Trade and labour standards</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ahead of the first ministerial meeting of the World Trade Organisation (WTO) to be held in December in Singapore, the European Commission has published a discussion paper (COM (96) 402 final) on whether labour standards should be linked to trade - which could mean sanctions for nations which do not comply with globally recognised labour clauses. What is at stake is to draw up globally recognised criteria and implement them without accusations of protectionism from some developing nations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At an informal meeting of EU trade ministers in Dublin on September 18, EC Trade Commissioner, Sir Leon Brittan, said that, in supporting an international code, the European Union had no intention of damaging the competitive advantage of developing nations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many Asian countries, who view the move of the EU and of other industrialised nations as veiled protectionism, do not even want the subject broached at the Singapore meeting. However, mention was made of the link between trade and internationally recognised labour standards in the conclusions of the Uruguay Round of GATT in Marrakesh in 1994, which requested that the WTO do more work on this issue.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The recent Commission paper advances the reasons for an international code: 'Workers in certain sectors in particular perceive that their jobs are under threat from imports from countries which allow unfair or unacceptable working practices.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These concerns cannot be ignored and should be addressed by the world trading system. Otherwise the perception will be - wrongly - that trade liberalisation is the problem and not the solution to the challenge to all societies to create a higher standard of living for all their citizens.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It further makes the point that such a policy is in line with others such as the promotion of democracy, respect for human rights and adherence to the rule of law. The EU has always upheld the view that there is a positive correlation between social progress, economic growth and trade liberalisation. According to the paper: 'There is no question of imposing on developing countries the higher wage levels and better working conditions which pertain in the industrialised world. Nor is this an action designed to re-erect new barriers to trade under cover of a social agenda.'</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU and international bodies are already looking at the kind of global criteria that might be adopted. A report of the International Labour Organisation (ILO), published in 1994, as well as the conclusions of the 1995 World Social Summit in Copenhagen, both suggest that freedom of association, collective bargaining, prohibition of forced labour and the elimination of child labour are top of the list.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A report entitled: 'Trade, Employment and Labour Standards - a study of core workers' rights and international trade', produced this year by the Paris-based Organisation for Economic Cooperation and Development (OECD), looks at the options in depth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jeff Atkinson, trade policy advisor for the NGO, Oxfam UK, suggests that initial negotiations should be limited to matters covered in ILO Conventions 87 and 98. The former deals with freedom of association and protection of the right to organise, while the latter is on the right to organise and collective bargaining. He argues that other Conventions, covering such matters as the right to equal renumeration for men and women workers, freedom from discrimination and the abolition of forced labour, depend on the first two. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A notable omission from Jeff Atkinson's list is ILO Convention 138 on child labour. He does not feel that this Convention adequately addresses the issue. While international concern has focused on the most abusive forms of child labour such as slavery and prostitution, he points out not all child labour is so grossly abusive. Some forms can bring in money for food and shelter, which would otherwise not be available.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">He argues that if conditions are right, employment (say on a family farm or business) can contribute positively to a child's development, by providing an informal learning environment in which social and physical skills can develop.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">'To tackle the symptoms, for example by banning child labour, without addressing the underlying cause is likely to be counterproductive', says Mr Atkinson. He argues that it might induce children to seek illegal work in order to survive, or alternatively that they may end up becoming destitute.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some bodies are already trying to enforce improved standards. Although the ILO cannot implement sanctions, if an ILO member fails to comply with Conventions, a dialogue can be instituted with the defaulting country. It is also running an extensive public campaign against child labour and is assisting the development of social labelling for goods produced which fully respect ILO Conventions.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under its new Generalised System of Preferences (GSP), the EU can remove some trade preferences if goods imported from non-Lom&eacute; developing nations are found to have been made with forced or slave labour. And from January 1, 1998, extra preferences can be given to countries which so request and comply with Conventions 87, 98 and 138. But if the enforcement of a socalled 'Social Clause' does reach the WTO level, some voices are already calling for joint monitoring involving the WTO and that long-time champion of human rights, the ILO. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">The 1996 UNCTAD Report</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A slow world growth rate is revealed in this year's annual report of the United Nations Conference on Trade and Development (UNCTAD), published in September. The global economy expanded by only 2.4% in 1995 compared with a 2.8% increase in 1994. And production is below what it could be, says the report. On the whole, developing nations achieved higher growth rates than their industrialised counterparts in 1995.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1996, world growth is expected to slow further although there will still be 'star performers' in some regions, and particularly slow movers in others. Asia is the continent currently doing best and China has the fastest expanding economy - despite this having slackened in recent years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1995, Africa recorded higher growth than Latin America, according to the Rubens Ricupero, UNCTAD Secretary General. It also managed the first real increase in average per capita income for a long time. This was partly due to commodity prices picking up - they rose 10% on average.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">But not such good news for the continent was a drop in private capital flows, notably direct investment. And the growth rate was highly variable across Africa. In some countries it was above 5% but in others, the economic situation was hit badly by political and armed conflicts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Meanwhile, drought led to lower production in the Sahel. The prospects for 1996 are uncertain according to the report. It noted that even countries whose economies have expanded during 1995 and 1996 will need another ten concurrent years of good economic results to get back to the per capita income they enjoyed 20 years ago.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The report highlights the tremendous difficulties facing many of the heavily-indebted, least developed nations. This is despite the fact that a number of donors have recently written off substantial amounts of some countries' public debts while the Paris Club has rescheduled repayments from other nations. Even if the new arrangements are followed through, UNCTAD is predicting that debt will remain a major burden for many countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One worrying factor is the weight of their multilateral debt and bilateral obligations to creditors other than the Paris Club. Multilateral institutions have implemented a number of measures, but these are of very limited scope. The UNCTAD Secretary General is encouraging multilateral creditors in particular, to put more muscle behind their debt relief plans.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The authors of the report are also recommending the establishment of an agency, within UNCTAD itself, to help developing nations achieve trade diversification and industrialisation strategies for economic growth. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Seminar on NGOs and government relations in humanitarian emergencies</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The British Council is organising an international seminar on the above subject in Oxford, UK, from 12-17 December 1996. The main themes to be covered at the meeting will include:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - the actors in humanitarian assistance;</P>
+<P ALIGN="JUSTIFY"> - funder and donor policy;</P>
+<P ALIGN="JUSTIFY">- government sovereignty;</P>
+<P ALIGN="JUSTIFY">- rights and obligations of intervention;</P>
+<P ALIGN="JUSTIFY">- the role of the beneficiary;</P>
+<P ALIGN="JUSTIFY">- conflicts of interest and areas of cooperation between donor NGOs and host governments, and;</P>
+<P ALIGN="JUSTIFY">- accountability and evaluation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Further information can be obtained from the Marketing Manager, International Seminars, The British Council, 1 Beaumont Place, GB-Oxford, OX1 2PJ.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tel. (44) 1B65 316 636, Fax. (44) 1865 57368.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">E-mail: International. Seminar@britcoun.org </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<I><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The institutions at work</Metadata>
+  </Description>
+-->
+</I><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">COMMON FOREIGN AND SECURITY POLICY</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Within the framework of its Common Foreign and Security Policy (CFSP), the European Union has recently issued a number of statements, details of which are set out below:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Burundi: condemnation of the massacre on 19 July</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 23 July 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union expresses grave concern at the deteriorating situation in Burundi especially at the killing of civilians and other gross violations of human rights which continue to be perpetrated in that country. It vehemently condemns the massacre of civilians in the Bugendana camp for displaced persons on 19 July last and deplores the expulsions of Rwandan refugees against their will. This massacre, following as it does those at Gishubi, Kivyuka, Teza, Mutoyi, Songa and Kamenge, represents a new stage in the vortex of violence, action and reaction putting Burundi at risk of being drawn ever further into a full civil war, the effects of which would be catastrophic for the people of Burundi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU calls on all Burundians to turn away from violence and move singlemindedly along the road to a peaceful and negotiated solution of their problems. It would point to the undertakings given on 25 June 1996 at Arusha during the Summit of Heads of State of the region in favour of dialogue open to all sectors of Burundi's population together with provision of the security measures needed to create the conditions for such dialogue. It would also point out that these undertakings were given formal backing by the Heads of State and Government of the entire continent of Africa when they met from 8 to 10 July at Yaounde under the aegis of the Organisation for African Unity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU believes that only compliance with the undertakings given at Arusha and their swift implementation can restore a climate of confidence and prevent Burundi becoming embroiled in a generalised conflict. As it has already stressed in the Council's statement of 15 and 16 July, the EU reiterates that it is prepared to assist in pursuit of the Arusha objectives in order to restore peace and security in Burundi and it supports the efforts of former President Nyerere and the countries of the region to achieve this.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Burundi: appeal for reconciliation following the coup d'Etat </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 26 July 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union shares the deep concern of the Secretary General of the United Nations, and others, about yesterday's military coup in Burundi.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU urges all sides to avoid recourse to violence and to take all steps to resolve the crisis by exclusively peaceful means.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU believes that the main immediate priority is the humanitarian situation. There must be no further loss of life.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An immediate beginning of a national debate is essential, leading to a real process of national reconciliation, founded on democracy and security for all sections of society.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this regard, the EU commends the efforts of former President Nyerere and regional leaders to broker an all-inclusive, negotiated settlement in Burundi, in peaceful conditions, and urges them to examine the possibility of continuing their efforts in this respect.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU reiterates its firm commitment to the re-establishment of peace in Burundi. The Union is following developments in the country closely, in active consultation with partners in the UN, with the OAU and others, towards the goal of restoring peace and security in Burundi. The EU Special Envoy, Mr Ajello, who is in the region, is actively assisting in this process.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Niger: doubts about the first round election results</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 1 August 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union expresses deep concern about the way in which the first round of the presidential elections in Niger on 7-8 July was conducted. In particular, it deplores the decision taken by the Niger authorities to dissolve the independent national electoral commission during the voting process and to replace it with an alternative body. It is the view of the EU that this decision, by the Niger authorities, casts serious doubts on the credibility of the election results. It requests the Niger authorities to explain this decision and why observers found it impossible to assist in gathering and collating the election results.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU urges the Niger authorities, in dealing with the critical situation which has resulted from their decision, to respect fully the fundamental freedoms of movement, expression and association of the Niger people. It attaches great importance to the restoration of all civil rights.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU will examine, in the light of recent developments, its policies of economic and development cooperation with the Niger authorities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU calls for the full restoration of democratic civilian government in Niger through transparent processes. Free and fair elections will be crucial in this respect. The EU will continue to follow the situation in Niger closely and in particular the preparation, holding and transparency of the forthcoming legislative elections on 22 September. Iceland, the Central European countries associated with the EU and the associated countries Cyprus and Malta align themselves with this declaration.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Swaziland: revision of the Constitution</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 6 August 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The European Union welcomes the announcement by King Mswati III of the names of the new Prime Minister of Swaziland and of the Constitutional Review Commission and is pleased that its membership represents all shades of political opinion in Swaziland.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU wishes to encourage all members of the Constitutional Review Commission to participate fully in its work and expresses confidence that their endeavours will bring about the adoption of a draft democratic constitution acceptable to the people of Swaziland as a whole. It hopes that the Commission will pursue its task energetically and is ready to offer appropriate assistance to the Commission if it so wishes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Burundi: appeal for talks and reconciliation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Declaration of 19 August 1996</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Recalling its declarations of 25 June and 5, 15, 23 and 26 July 1996, the European Union reiterates its deep concern about the situation in Burundi. It urges all sides to refrain from violence and to commit themselves to, and work actively towards, a negotiated and peaceful resolution of the crisis.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU wishes to express its support for the regional leaders, the Organisation of African Unity and the former President of Tanzania, Mr Julius Nyerere, in the efforts which they have been making to assist Burundi to overcome peacefully the grave crisis which it is experiencing, and encourages them to continue their efforts to facilitate the search for a political solution.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU considers it essential for a dialogue to be organised without delay, bringing together all of Burundi's political forces without exception, including representatives of civil society, in order to negotiate a democratic, institutional consensus ensuring security for all.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU is convinced that national reconciliation and civil peace in Burundi can be restored on a lasting basis only through the participation of all sections of society in the principal institutions and bodies of the State.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The EU urges all sides in Burundi to call an immediate halt to the violence and respect the safety of all Burundians.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It reaffirms its willingness to support Burundi's recovery efforts, once the necessary national reconciliation is embarked upon with all the resolve required.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AID FOR REHABILITATION</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Within the framework of the 'European Programme for Reconstruction and Development in South Africa', the Commission has recently decided on financing for the following ten projects:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> - ECU 19.2 million for a development programme covering the management of the public service;</P>
+<P ALIGN="JUSTIFY"> - ECU 17.2 million for technical assistance to the Ministry of Education;</P>
+<P ALIGN="JUSTIFY"> - ECU 16 million for a support programme for Parliament;</P>
+<P ALIGN="JUSTIFY"> - ECU 15 million for the electrification of rural schools;</P>
+<P ALIGN="JUSTIFY"> - ECU 9 million to support the reform process in the police services of the Eastern Cape province;</P>
+<P ALIGN="JUSTIFY"> - ECU 8.9 million for a financing and investment development programme for SMEs;</P>
+<P ALIGN="JUSTIFY"> - ECU 5 million for a programme of rural water supply and sanitation projects to be implemented </P>
+<P ALIGN="JUSTIFY">by the NGO Mvula Trust; </P>
+<P ALIGN="JUSTIFY"> - ECU 4.3 million to support the trade union movement;</P>
+<P ALIGN="JUSTIFY"> - ECU 2.3 million for the 'Soul City 1996' project designed to make full use of the mass media to promote health and development issues;</P>
+<P ALIGN="JUSTIFY"> - ECU 1.9 million to support the 'Truth and National Reconciliation Commission'.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">EUROPEAN DEVELOPMENT FUND</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Following, where required, favourable opinions from the EDF Committee, the Commission has decided to provide grants and special loans from the 5th, 6th and 7th EDFs to finance the following operations (grants unless otherwise stated). Major projects and programmes are highlighted.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economic and social infrastructure</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Burkina Faso: ECU 4.125 million for studies relating to certain road infrastructures. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mauritius: ECU 9 million for an irrigation programme in the northern plains. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Dominica: ECU 1.65 million towards the establishment of refuse treatments systems.  Trade promotion/ structural adjustment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cot&eacute; d'lvoire: ECU 25.5 million to , support the structural adjustment programme. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lesotho: ECU 8.6 million for the fourth structural adjustment programme. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Agriculture/rural development</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ethiopia-Kenya-Uganda: ECU 20 million for a programme to coordinate national activities aimed at achieving sustainable rural development in the region (notably involving the fight against the Tsetse fly)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Education/training</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Caribbean region: ECU 5.9 million towards a post-secondary education training programme in the countries of the OECS (Organisation of Eastern Caribbean States - Antigua &amp; Barbuda, British Virgin Islands, Dominica, Grenada, Montserrat, St Kitts &amp; Nevis, St Lucia, St. Vincent &amp; the Grenadines). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Environment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Malawi: ECU 4.4 million for a social/ participatory programme in the forestry sector as part of the implementation of a national forestry policy. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Institutional support</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">SADC member states: ECU 1.7 million to support the SADC (Southern African Development Community) secretariat in order to strengthen the SADC-EU regional programme. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UEMOA (West Africa Economic and Monetary Union): ECU 12 million to support the regional integration process in the member states (Benin, Burkina Faso, Cot&eacute; d'lvoire, Mali, Niger, Senegal and Togo) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zambia: ECU 1.5 million for a support programme for the Ministry of Finance and Economic Development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">EUROPEAN INVESTMENT  BANK</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During the first half of 1996, the Bank has provided the following loans from its own resources or in the form of risk capital:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Africa/Madagascar: ECU 30 million for ASECNA (I'Agence pour la securite de la navigation aerienne en Afrique et a Madagascar) for the renewal and modernisation of air safety equipment. Botswana: ECU 6.6 million to the Botswana Power Corporation to help increase electricity-generating capacity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Burkina Faso: ECU 6 million to SOFITEX (Societe burkinabe des fibres textiles) for the renewal and extension of its cotton ginneries facility. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mali: ECU 5.3 million to the Societe Energie du Mali for the financing of the Balingue thermal power station. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mauritania: ECU 2 million to SNIM (Societe rationale industrielle et miniere) for the setting up and operation of a mechanical workshop. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mauritania: ECU 1.4 million to the Societe arabe du fer et de l'acier (Arab iron and steel company) for the construction of a foundry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mozambique: ECU 500 000 to Grafites de Ancuabe for the exploitation of a graphite mine.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Zambia: ECU 2 million to the Zambia Venture Capital Fund, set up to subscribe for minority equity stakes in SMEs. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jamaica: ECU 40 million to Telecommunications of Jamaica Ltd for expansion and modernisation of the domestic and international telecommunications network. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">British Virgin Islands: ECU 600 000 to the government for the design and feasibility study of the main airport at Beef Island, Tortola. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tonga: ECU 3.7 million to the Tonga Telecommunications Commission for the development of the country's domestic telecommunications network.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">HUMANITARIAN AID</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ACP countries</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Ethiopia: ECU 5 million for the purchase and distribution of vegetable oils and cereals to refugees living in the country. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kenya: ECU 420 000 for emergency medical assistance in the fight against cholera in the Mandera region.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Somalia: ECU 1.9 million for emergency food aid to the victims of the continuing factional fighting. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sudan: ECU 2.5 million for the purchase and distribution of maize in a transit camp close to the capital (154 000 people) and in the south of the country (1 million people), and for the distribution of sorghum to Ethiopian and Eritrean refugees in the east (200 000 people). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chad: ECU 150 000 to help tackle the cholera epidemic. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Haiti: ECU 10 million for a programme to counter malnutrition and improve basic health care, in particular for women and children in isolated locations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Montserrat: ECU 380 000 to help evacuees in the wake of the recent volcanic eruption. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Non-ACP countries</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Colombia: ECU 1 million for people displaced as a result of drug terrorism and the fighting that has been taking peace between government forces and guerillas. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Costa Rica: ECU 400 000 for the victims of Hurricane Cesar. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Guatemala: ECU 220 000 to train teachers in order to improve education among repatriated communities in the department of Alta Verapaz. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nicaragua: ECU 440 000 to improve conditions for the social and economic reintegration of uprooted populations (people who have been repatriated, displaced or demobilised) in the department of Rio San Juan. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Northern Caucasus: ECU 4.18 million for civilian victims of the war in Chechnya and for refugees in Ossetia and Dagestan. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Iraq: ECU 9 million for food aid, medical provisions, rehabilitation of drinking water systems, sanitary equipment and educational material to assist 3 million people in the north and centre of the country.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Yemen: ECU 150 000 for flood victims. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Cambodia: ECU 290 000 for a programme to construct and distribute artificial limbs to land-mine victims. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thailand (Burmese refugees): ECU 220 000 for 'Mon' refugees from Burma (Myanmar) who have fled the violence in their country. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thailand (Burmese refugees): ECU 500 000 for medical aid in favour of 'Karen' refugees from Burma (Myanmar). </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FOOD AID</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Commission has recently decided to allocate the following aid: </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p90.png"></center><br>
+Table</P>
+
+<!--
+</Section>
+</Section>
+</Section>
+</Section>
+-->
+
+</HTML>
Index: /gsdl/stable/collect/demo/import/ec160e/metadata.xml
===================================================================
--- /gsdl/stable/collect/demo/import/ec160e/metadata.xml	(revision 20131)
+++ /gsdl/stable/collect/demo/import/ec160e/metadata.xml	(revision 20131)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE DirectoryMetadata SYSTEM "http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd">
+<DirectoryMetadata>
+    <FileSet>
+        <FileName>.*</FileName>
+        <Description>
+            <Metadata name="dls.Title">The Courier - NÂ°160 - Nov - Dec 1996 - Dossier Habitat - Country reports: Fiji , Tonga (ec160e)</Metadata>
+            <Metadata mode="accumulate" name="dls.Language">English</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Settlements, Housing, Building - Infrastructure Construction (Roads etc)|Settlements and housing: general works incl. low- cost housing, planning techniques, surveying, etc.</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Development Periodicals and Magazines|The Courier ACP 1990 - 1996 Africa-Caribbean-Pacific - European Union</Metadata>
+            <Metadata mode="accumulate" name="dls.Organization">EC Courier</Metadata>
+        </Description>
+    </FileSet>
+</DirectoryMetadata>
Index: /gsdl/stable/collect/demo/import/fb33fe/fb33fe.htm
===================================================================
--- /gsdl/stable/collect/demo/import/fb33fe/fb33fe.htm	(revision 20131)
+++ /gsdl/stable/collect/demo/import/fb33fe/fb33fe.htm	(revision 20131)
@@ -0,0 +1,890 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META NAME="Generator" CONTENT="Microsoft Word 97">
+<TITLE>&lt;&lt;TOC1&gt;&gt; Farming snails 1: Learning about snails; Building a pen; Food and shelter plants</TITLE>
+</HEAD>
+<BODY>
+
+<B><FONT FACE="Arial" SIZE=2><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Farming snails 1: Learning about snails; Building a pen; Food and shelter plants</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FOOD AND AGRICULTURE ORGANIZATION OF THE UNITED NATIONS</P>
+<P ALIGN="JUSTIFY">Rome 1986</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">P-69</P>
+<P ALIGN="JUSTIFY">ISBN 92-5-102396-4</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&copy; FAO 1986</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Introduction</Metadata>
+  </Description>
+-->
+</B><P ALIGN="CENTER"></P>
+<P ALIGN="JUSTIFY">1. Did you know that many kinds of snails are good to eat?</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">2. Snail meat tastes good and it is also good for you. If you have snail meat to eat, it will help to keep you and your family strong and healthy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p60a.png"></center><br>
+ Family kept strong and healthy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">3. If you want to have snails to eat you can get them in different ways.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">4. Many people gather wild snails that live nearby. Sometimes you can buy snails at the market or from people who gather them to sell to others.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">5. You can also raise your own snails. This is called snail farming. Today, a great many people all over the world farm snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">6. If you farm your own snails, you will always have a supply of fresh snail meat whenever you want it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">7. Then, if your family is not too big and you grow more snails than you need to eat, you can sell what you do not use to your neighbours or at the market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p61a.png"></center><br>
+ Selling snails at the market</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">8. With more food to eat and the money you get by selling snails, you and your family can live better.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">9. However, if your family is big you will need to grow many more snails if you are going to have enough to eat and to sell at the market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p61b.png"></center><br>
+ You need to grow more snails if your family is big</P>
+<P ALIGN="CENTER"></P>
+<P ALIGN="CENTER">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">What do you need to start?</Metadata>
+  </Description>
+-->
+</B><P ALIGN="CENTER"></P>
+<P ALIGN="JUSTIFY">You will need</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> enough snails to start your snail farm</P>
+<P ALIGN="JUSTIFY"></P></DIR>
+
+<P ALIGN="JUSTIFY"><center><img src="f33p61c.png"></center><br>
+ Snail</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> a place near your house with the right kind of soil and the right amount of water for snails to live and grow</P>
+<P ALIGN="JUSTIFY"></P></DIR>
+
+<P ALIGN="JUSTIFY"><center><img src="f33p61d.png"></center><br>
+ A place near your house</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> the kinds of plants that snails need for food and shelter</P>
+<P ALIGN="JUSTIFY"> the materials to build a pen for the snail</P>
+<P ALIGN="JUSTIFY"></P></DIR>
+
+<P ALIGN="JUSTIFY"><center><img src="f33p62a.png"></center><br>
+ Plants that snails need; The materials to build a pen</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">10. If you have or can get all of these things, you can raise snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="CENTER">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Learning about snails</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">11. To farm snails is not hard; however, it is quite different from keeping chickens or ducks or from growing crops such as maize, rice, cassava or groundnuts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">12. Since farming snails is so different from other kinds of farming, you will have to learn a lot of new things.</P>
+<P ALIGN="JUSTIFY">13. One way to learn about snails so that you will be able to farm them is to watch the wild snails that live near you.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p62b.png"></center><br>
+ Watch the wild snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">14. Try to see how they live, how they move and where they go, what plants they like best and what they eat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">15. You can learn many things by watching wild snails that will help you later if you decide to start a snail farm.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p63a.png"></center><br>
+ Wild snail</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">16. Another way to learn about snails is to ask an older farmer who knows a lot about your area. If there are people near you who gather snails to sell to others, they may be able to help you.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">17. In the next part of this booklet, you will begin to learn some things that you need to know to farm snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">What kind of snails can you farm?</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">18. The kind of snails that you can farm are snails that live on land, and there are many kinds of land snails that are good to eat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">19. However, some kinds of land snails are not good to eat and they may even make you very, very sick.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">20. So, you must be very careful when you choose snails to farm. If you are not sure that a snail is good to eat, do not use it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p63b.png"></center><br>
+ Do not use snail unless you are sure it is good to eat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">21. Now look at the drawings on pages 8 to 11 and you will see four kinds of good snails that live in different places.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">22. You may be able to find one of these kinds of snails where you live. Notice that two of them are small and two of them are large.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">23. The smaller kinds of snails, shown on pages 8 and 9, can often be found in places where part of the year is warm and part of the year is cold.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">24. The larger kinds of snails, shown on pages 10 and 11, can often be found in places where it is warm all year round.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p64a.png"></center><br>
+ Helix pomatia</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">This kind of small snail</P>
+<P ALIGN="JUSTIFY">1 can be found in places where part of the year is warm and part of the year is cold</P>
+<P ALIGN="JUSTIFY">2 weighs from 15 to 25 grams and measures from 40 to 50 millimetres</P>
+<P ALIGN="JUSTIFY">3 has a strong shell which is pale brown and off- white</P>
+<P ALIGN="JUSTIFY">4 grows to full size in two to three years if it is well fed</P>
+<P ALIGN="JUSTIFY">5 lays from 30 to 50 eggs each growing season</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p64b.png"></center><br>
+ Helix Pomatia - 30 to 50 small eggs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p64c.png"></center><br>
+ Helix aspersa</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This kind of small snail</P>
+<P ALIGN="JUSTIFY">1 can often be found in places where part of the year is warm and part of the year is cold</P>
+<P ALIGN="JUSTIFY">2 weighs from 4 to 20 grams and measures from 30 to 45 millimetres</P>
+<P ALIGN="JUSTIFY">3 has a weak shell with broken stripes which are light brown to black</P>
+<P ALIGN="JUSTIFY">4 grows to full size in one year if it is well fed</P>
+<P ALIGN="JUSTIFY">5 lays from 40 to 170 eggs one to three times each growing season</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p64d.png"></center><br>
+ Helix aspersa - 40 to 170 small eggs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p65a.png"></center><br>
+ Achatina achatina</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This kind of large snail</P>
+<P ALIGN="JUSTIFY">1 can often be found in places where it is warm all year round</P>
+<P ALIGN="JUSTIFY">2 weighs from 150 to 200 grams or more and measures from 90 to 130 millimetres</P>
+<P ALIGN="JUSTIFY">3 has a very strong brown shell</P>
+<P ALIGN="JUSTIFY">4 grows to full size in two years if it is well fed</P>
+<P ALIGN="JUSTIFY">5 lays from 100 to 300 eggs one to two times each growing season</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p65b.png"></center><br>
+ Achatina achatina - 100 to 300 small eggs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p65c.png"></center><br>
+ Archchatina marginata</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This kind of large snail</P>
+<P ALIGN="JUSTIFY">1 can often be found in places where it is warm all year round</P>
+<P ALIGN="JUSTIFY">2 weighs from 150 to 200 grams or more and measures from 90 to 130 millimetres</P>
+<P ALIGN="JUSTIFY">3 has a very strong brown shell</P>
+<P ALIGN="JUSTIFY">4 grows to full size in two years if it is well fed</P>
+<P ALIGN="JUSTIFY">5 lays from five to ten eggs four to eight times each growing season</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p65d.png"></center><br>
+ Archchatina marginata - five to ten large eggs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">25. If you cannot get one of these snails, you may be able to get others very much like them where you live.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">26. There are many other kinds of good snails. There may even be several kinds of good snails that are eaten where you live.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">27. If snails are eaten where you live, you can farm one of these. Then you will be sure that it is good to eat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Where can you get snails?</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">28. When you are ready to get snails, perhaps you can get them by gathering wild snails that live near you.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p66a.png"></center><br>
+ Gathering wild snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">29. Perhaps you can buy them from people who gather wild snails to sell to others.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p66b.png"></center><br>
+ Buying from one who gathers wild snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">30. You may even be able to buy them from another snail farmer.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p66c.png"></center><br>
+ Buying from another snail farmer</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Note</P>
+<P ALIGN="JUSTIFY">Never term snails that you buy at the market. Snails at the market may have been washed, kept too cold or hurt and they may die soon.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Where can you farm snails?</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">31. A good place for a snail farm is one where there already are snails. If there already are snails, you will know that the soil and the water in the soil are right for snails to live and grow.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">32. However, if there are no snails near where you live it does not mean that you cannot raise snails there.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">33. If you have the right kind of soil with the right amount of water, you can bring good snails from another place to start your snail farm.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The soil and the water in the soil</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">34. Soil is important for snails. Part of the time they live on the soil and part of the time they live in the soil, and to live well, snails need good soil.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p67a.png"></center><br>
+ Snail on the soil; Snail in the soil</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">35. When snails are not on the soil or in the soil, they are on plants which grow in the soil. So, the soil must also be good for the kinds of plants that snails need.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p67b.png"></center><br>
+ Snail on plant</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">36. When snails are in the soil, they are resting or laying their eggs. If the soil has the right amount of water, snails will live well, the eggs they lay will hatch well and the baby snails will come out of the soil easily.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">37. Snails cannot live in hard soil such as heavy clay soils. When heavy clay soil is too dry, snails cannot dig into it to rest and lay their eggs. When heavy clay is too wet, snails and the eggs they lay may die.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">38. Snails cannot live in loose soil such as soils that have a lot of sand. Sandy soils do not hold enough water for snail eggs to hatch.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">39. The drawings on the next page show how a snail digs a hole, lays its eggs, closes the hole and how the baby snails come out when they have hatched.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">40. Snails need calcium from the soil to make their shells. All snails grow better and have stronger shells when there is a lot of calcium in the soil.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">41. So, if you are going to farm snails, you must have a good medium soil that has neither too much clay nor too much sand. It must also have enough calcium and the right amount of water for your snails to live and grow.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Note</P>
+<P ALIGN="JUSTIFY">If you have a garden, you can easily tell if your soll is good for snails. If your green leafy vegetables grow well, snails will also grow well in the same kind of soil</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p68a.png"></center><br>
+ Snails will grow well in a garden</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">1 snail digging a hole</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p68b.png"></center><br>
+ 1 snail digging a hole</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">2 laying the eggs and closing the hole</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p68c.png"></center><br>
+ Snail laying eggs</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">3 baby snails hatching and coming out of the hole</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p68d.png"></center><br>
+ Baby snails hatching and coming out of the hole</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Plants for food and plants for shelter</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">42. Snails need plants for both food and sheller. Most kinds of snails use several kinds for food and several other kinds for shelter.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p69a.png"></center><br>
+ Plants for food and plants for shelter</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">43. They may also use different plants for food and shelter at different times of the year. Sometimes during the growing season snails eat and find shelter on the same plants.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">44. Snails usually hide on shelter plants during the day when it is dry and move to food plants to eat at night or early in the morning when they are wet with dew. However, sometimes snails do eat during the day after it has rained.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">45. If you live in a place which has a season when plants do not grow, snails will dig into the soil to rest and they do not eat then.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">46. During the growing season snails will eat a lot and grow very fast if they have food plants that they like.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">47. So, before you begin you will have to find out exactly what plants they like to eat. To do this you will have to watch snails at night when they eat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p69b.png"></center><br>
+ See what snails eat at night</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">48. You can tell that snails are eating when you see their heads moving as they scrape food into their mouths. You can also tell when a snail has been eating by the holes it makes in the leaves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p69c.png"></center><br>
+ Snail on leaf</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">49. You will also have to find out what plants they like for shelter. To do this you will have to watch snails during the day when they rest.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p70a.png"></center><br>
+ See where snails rest during the day</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">50. It is often difficult to find snails on shelter plants because they are hiding. So, you will have to look very carefully.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p70b.png"></center><br>
+ Snails are hiding on shelter plants</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">51. In addition to the food plants, there are many other kinds of foods that you can put into a pen for your snails to eat. You will learn about these foods and when you should use them in the next booklet in this series.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Dew and rain</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">52. Dew at night in the growing season helps the plants to grow and makes the leaves and the ground wet so that snails can move about.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">53. Rain in the growing season also helps the plants to grow and it cleans the plants of dust and the dirt that snails leave when they move about. The dirt that snails leave may make them sick.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">54. So, it is very important that the food and shelter plants are wet and clean.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">55. When the leaves are wet, snails move easily, eat more and grow well. When the leaves are dry, snails move very little, or not at all, and they grow poorly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p70c.png"></center><br>
+ Wet leaves are good for snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">56. When it rains and the plants are clean, the snails will be healthy. When it does not rain and the plants are dirty, the snails may get sick.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">57. Dew and rain also keep the ground moist so that the snails can move easily and dig into it to rest and to lay their eggs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">58. In the next booklet, you will be told how to wet the leaves of plants and moisten the ground when it is too dry.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Land that is wet</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">59. Land that is very wet, low land that does not drain well or land that floods in the rainy season is not good for snail farming.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p71a.png"></center><br>
+ Low, wet land is bad for snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Wind</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">60. Wind during the growing season is bad because it dries the dew and dries out the snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p71b.png"></center><br>
+ Wind is bad for snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">61. If you decide to farm snails, try to keep them in a place that is protected from the wind.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p71c.png"></center><br>
+ Snails should be farmed in a place protected from the wind</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Where do you keep snails when you farm them?</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">62. If you decide to farm snails you must keep them in a pen. Snails kept in a well- built pen will not get away easily and you can watch them and take care of them well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">63. After the first year you will need at least two pens. If you decide to farm more snails you may want even more pens. You will learn how to use two or more pens in the next booklet.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p72a.png"></center><br>
+ Two pens the second year</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">64. In each pen you can give your snails the right kinds of plants for them to eat and to use as shelter.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">65. In each pen you can put the food and shelter plants near each other so that the snails can move easily from one to the other.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">66. Each pen you build must also keep the snails safe from their enemies. Snails have many enemies. You must be careful to protect them from</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> mice and rats</P>
+<P ALIGN="JUSTIFY"> shrews and moles</P>
+<P ALIGN="JUSTIFY"> walking insects that live on the ground such as ants and beetles</P>
+<P ALIGN="JUSTIFY"> slugs and other snails that eat snail meat</P>
+<P ALIGN="JUSTIFY"> birds that eat snails</P>
+<P ALIGN="JUSTIFY"> frogs and toads</P>
+<P ALIGN="JUSTIFY"> thieves</P>
+<P ALIGN="JUSTIFY"></P></DIR>
+
+<P ALIGN="JUSTIFY"><center><img src="f33p72b.png"></center><br>
+ Protect them from
+</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">67. A snail pen can be small or large depending on how many snails you want to raise. However, when you first begin, start with a small pen. You will need fewer materials. It will be easier to take care of.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">68. In addition, with a small pen you will need fewer snails to begin. When you know more about raising snails, you can build a bigger pen and get more snails to raise.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">69. A good size for a pen is 5 x 5 metres. Later in this booklet you will learn how to build a small pen of this size.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">How many snails will you need when you first begin?</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">70. If you are using small snails like those you have seen on pages 8 and 9 in this booklet, you will need more snails to begin.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">71. If you are using large snails like those you have seen on pages 10 and 11 in this booklet, you will need fewer snails to begin.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">72. With a pen of 5 x 5 metres (25 square metres) you will need</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> 150 snails if you use the small kind (6 for each square metre)</P>
+<P ALIGN="JUSTIFY"> 25 snails if you use the large kind (1 for each square metre).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p73a.png"></center><br>
+ 150 small snails; 25 large snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">How much snail meat can you expect to get?</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">73. The amount of snail meat that you will get from small snails will be about the same as what you would get from large snails. This is because you will use many more small snails than large snails and the meat will be about equal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">74. With one 5 x 5 metre pen you will get 12 to 13 kilograms of snail meat each year and with two 5 x 5 metre pens you will get 24 to 26 kilograms each year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p73b.png"></center><br>
+ 12 to 13 kilograms each year; 24 to 26 kilograms each year</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Now you must decide</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">75. In the first part of this booklet you have learned many things about snails and farming snails. You have learned</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> why it is good to farm snails</P>
+<P ALIGN="JUSTIFY"> what you need to farm snails</P>
+<P ALIGN="JUSTIFY"> what kinds of snails you can farm</P>
+<P ALIGN="JUSTIFY"> how to find plants near you that are good for food and shelter</P>
+<P ALIGN="JUSTIFY"> what kind of soil and how much water in the soil snails need</P>
+<P ALIGN="JUSTIFY"> where to keep snails and how many you need to start</P>
+<P ALIGN="JUSTIFY"></P></DIR>
+
+<P ALIGN="JUSTIFY">76. You may also have been able to learn a lot about snails by watching the wild snails near where you live.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">77. An old farmer may have told you what he knows about snails. Someone who gathers snails to sell to others or another snail farmer may have helped you to learn.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">78. So, now that you know a lot about snails it is time to decide if you would like to start your own snail farm.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">79. If you would like to begin you will learn exactly what to do in the rest of this booklet and in the next booklet.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">How to begin</Metadata>
+  </Description>
+-->
+<P ALIGN="CENTER"></P>
+<P ALIGN="CENTER">&nbsp;</P>
+<P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Choose a place on your land to put your snail farm</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">80. Try to choose a place that is close to your house. That way you will be able to watch your snails, protect them from their enemies and take care of them easily</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p74a.png"></center><br>
+ Close to your house</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">81. In Items 34 to 41 you were told that to farm snails you must have the right kind of soil with the right amount of water.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">82. Remember, if green leafy vegetables grow well in your soil, snails will also grow well in the same kind of soil.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p74b.png"></center><br>
+ If your garden grows well, so will your snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">83. In Items 59 to 61 you were told that low, wet land and wind are bad for snails. So, avoid low, wet places and try to put your snail farm where it is protected from the wind.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p75a.png"></center><br>
+ Avoid low, wet land; Find a place protected from wind</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">84. In Item 63 you were told that after the first year you will need at least two pens and later you may want even more. In Item 69 you were told that it is best to start with a small pen of 5 x 5 metres.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">85. So, try to find a place where you can put at least two or three 5 x 5 metre pens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p75b.png"></center><br>
+ two or three 5 x 5 metre pens</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Clean the site and prepare the ground</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">86. Clean the site and prepare the ground a little before the growing season so that you can build the pen in time to plant the food and shelter plants.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">87. First, mark out a square of 8 x 8 metres on the place that you have chosen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p75c.png"></center><br>
+ Mark and clear the 8 x 8 metre square</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">88. That way, with a pen of 5 x 5 metres in the centre of the square, you will have a path of 1.5 metres all the way around it (see Item 92). If you have enough land, the path can be even wider.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">89. Clear the square of trees, bushes grass, creeping grass and weeds. Take away all of the roots and the big stones that you can.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p76a.png"></center><br>
+ Take away roots and big stones</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">90. Spread the plant material that you have cleaned evenly on the ground and cover the whole square. If there is not enough, bring more plant material from another place.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p76b.png"></center><br>
+ Cover the square with plant materials</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">91. When the plant material is dry, burn it. This will kill the insects, the weed seeds and the roots of creeping grass, and rid the ground of mice, rats and shrews.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p76c.png"></center><br>
+ Burn the plant materials</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Note</P>
+<P ALIGN="JUSTIFY">Insecticides and poisons can also be used to rid your pen of insects, mice, rats and other enemies of snails. However, if you use them, do not use them by yourself because they are very dangerous. Ask someone who knows how to use them, such as your extension agent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">92. Now mark out a smaller square of 5 x 5 metres inside the big square. This is for your first snail pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p77a.png"></center><br>
+ Mark the 5 x 5 metre square</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">93. Dig the ground in the smaller square to a depth of 20 centimetres and turn it over well. As you dig, remove any rubbish or roots that you find.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p77b.png"></center><br>
+ Dig in the ground</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">94. While you are digging, if you see any more insects or any of the enemies of snails, bring more dry plant material and burn the ground again. To farm snails, the area must be free of insects, mice, rats and other enemies.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">95. When you have finished digging, the ground in the 5 x 5 metre square should be as smooth and well worked as it would be if you were planting a vegetable garden.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p77c.png"></center><br>
+ The 5 x 5 metre square should be smooth</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">96. However, do not use any fertilizer, animal manure or compost as you might with a vegetable garden. Fertilizers may burn the snails and animal manure or compost may bring in insects and weed seeds.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Building a pen</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">97. Build a pen for your snails as soon as you can after you have burned the plant material. This is to keep other insects, mice, rats or shrews from getting into your pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">98. A snail pen is a simple fenced- in area and you can build a fence using</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> corrugated sheet metal or plastic sheets</P>
+<P ALIGN="JUSTIFY"> woven plant material</P>
+<P ALIGN="JUSTIFY"> woven plant material with chicken wire</P>
+<P ALIGN="JUSTIFY"></P></DIR>
+
+<P ALIGN="JUSTIFY"><center><img src="f33p78a.png"></center><br>
+ Materials for fence</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Using corrugated sheet metal or plastic sheets</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">99. A fence of corrugated sheet metal or plastic sheets makes the best pen for snails because it keeps out their enemies very well. However, sheet metal or plastic costs a lot of money.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p78b.png"></center><br>
+ A fence of corrugated sheet metal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">100. If you are going to build a pen using corrugated metal or plastic, you must build it in such a way that the enemies of snails cannot get in between the sheets.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Using woven plant material</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">101. To save money, you can build a fence of woven plant material such as split bamboo. If the woven material is tight, it will keep out enough of enemies for you to farm snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p79a.png"></center><br>
+ Woven material</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Using woven plant material with chicken wire</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">102. If you can get fine- mesh chicken wire, you can improve a fence that is made of woven material.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p79b.png"></center><br>
+ Chicken wire</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">103. To do this, first make the fence of chicken wire and then cover it with woven material.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p79c.png"></center><br>
+ First use chicken wire then cover it with woven material</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">104. The chicken wire will keep out rats and other small animals. The woven plant material will keep most of the insects out and keep the snails in.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p79d.png"></center><br>
+ Keep out small animals</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Note</P>
+<P ALIGN="JUSTIFY">With any kind of pen animals such as rats may get in, and this is especially true with pens made only of woven plant material. So, you must always watch for rats and other animals and keep them out.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">How to build the fence</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">105. Build the fence as you would any fence, by driving posts into the ground. Use posts 1.40 metres long. When the posts are in place they should be 1.00 metre above and 0.40 metre below the ground.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p80a.png"></center><br>
+ Drive posts into the ground</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">106. Whatever material you use for the fence of your pen, it should be buried 0.40 metre below the ground.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">107. If you are using woven material you will have to change the bottom of the fence when it rots.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">108. This can be done more easily by making the woven material in two parts, one for the top and one for the bottom. When the bottom part rots, you can change it without having to change the whole fence.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p80b.png"></center><br>
+ Attach top parts first; attach bottom parts second</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Keeping your snails in the pen</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">109. Many of your snails may crawl over the fence and get out of the pen. If you build a flap on the inside at the top of the fence, it will be more difficult for your snails to get out.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">110. However, even with a flap some snails may get out, and for this reason many snail farmers put two flaps on their fence. With two flaps they find that fewer snails get out.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p81a.png"></center><br>
+ With two flaps, your snails will not easily crawl out of the pen</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Note</P>
+<P ALIGN="JUSTIFY">If you make your pen using galvanized sheet metal, you will not need flaps. Snails will not crawl on galvanized sheet metal.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">111. The drawings show you how to build a 5 x 5 metre pen using woven plant material, with and without chicken wire and how to build flaps to keep your snails in.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p81b.png"></center><br>
+ How to build a 5 x 5 metre small pen</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">3 if you are using woven material only, attach it as you were told to do in Item 108</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p82a.png"></center><br>
+ Attach woven material</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">4 If you are using chicken wire and woven material, attach the chicken wire first and then the woven material</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p82b.png"></center><br>
+ Attach the chicken material first</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">5 be sure that the fence cover goes all the way to the bottom of the 0.40- m trench</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p82c.png"></center><br>
+ 0.40- m trench</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">6 fill in the trench</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p82d.png"></center><br>
+ Fill in the trench</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">7 attach the flaps to the inside of the pen</P>
+<P ALIGN="JUSTIFY">Note: use woven material 0.25 m wide for the flaps</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">8 first attach the bottom flap using heavy cord</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p83a.png"></center><br>
+ Use heavy cord</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">9 then attach the top flap</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Plant the food and shelter plants</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">112. You have already been told that you should clean and prepare the site and build your snail pen in time for the planting season.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">113. If it has been only a short time since you dug the ground and worked the soil in your pen, you can begin to plant.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">114. If it has been a long time, dig and work the soil again before you plant. However, as you were told in Item 96, do not use fertilizer, animal manure or compost.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">115. Now you can begin to plant the food and shelter plants. Remember that you should use</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> plants that grow well where you live</P>
+<P ALIGN="JUSTIFY"> plants that last a long time</P>
+<P ALIGN="JUSTIFY"> plants that snails like</P>
+<P ALIGN="JUSTIFY"></P></DIR>
+
+<P ALIGN="JUSTIFY">116. The drawings, show you two ways to plant food and shelter plants in a 5 x 5 metre pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">117. On pages 50 to 55 you will see some food and shelter plants that snails are known to like. Look at them carefully. Perhaps you can find some of them where you live.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Two ways plant food and shelter plants</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">1 if your shelter plants are small, plant your pen like this</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p84a.png"></center><br>
+ Mark three places for small shelter plants</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">2 plant the shelter plants first and then plant the food plants all around the shelter plants</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p84b.png"></center><br>
+ First plant the shelter plants</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">3 if your shelter plants are large, plant your pen like this</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p84c.png"></center><br>
+ Mark only one place for large shelter plants</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">4 plant the shelter plants first and then plant the food plants all around the shelter plants</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p84d.png"></center><br>
+ Leave a path inside the fence</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">RAMPE</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p85a.png"></center><br>
+ Some plants for food</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rape is one of many kinds of smooth- leaved cabbage. It grows from seed and lasts a number of months. Rape is the best food plant for Helix snails (see pages 8 and 9 in this booklet). Many of the other kinds of smooth- leaved cabbage also make good food plants for snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p85b.png"></center><br>
+ Rape</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AFRICAN SPINACH (Amaranthus)</P>
+<P ALIGN="JUSTIFY">This green leafy vegetable is a good food plant for young Achatina and Archachatina snails. However, if you plant African spinach for your snails, they will need other kinds of food plants as well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p85c.png"></center><br>
+ African spinach</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PAPAYA</P>
+<P ALIGN="JUSTIFY">You have already been told that snails can be given food to eat other than the food plants that you have planted in the pen (see also Items 175 to 179 in the next booklet). The tender green leaves and cut- up fruit of the papaya tree are very good for Achatina and Archachatina snails. However, the papaya should not be planted inside the pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p86a.png"></center><br>
+ Papaya</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HORSE- RADISH</P>
+<P ALIGN="JUSTIFY">Horse- radish is a good food and shelter plant for young Helix snails. However, when they are older they will need other kinds of food plants as well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p86b.png"></center><br>
+ Horse- Radish</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">LEAF BEET</P>
+<P ALIGN="JUSTIFY">Leaf beet grows well from seed and lives for one year. It can be used with He/ix snails for both food and for shelter. As a food plant alone it is not the best and you will have to give your snails other food plants as well. However, as a shelter plant it is very good for Helix snails. These snails lay eggs under the beet plants and find shelter around the roots in cold weather.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p86c.png"></center><br>
+ Leaf Beet</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BURDOCK</P>
+<P ALIGN="JUSTIFY">Burdock grows from seed and lives for more than a year. It grows very slowly and you should plant it as soon as you can so that it can grow big enough for your snails. However, once it has grown it makes a good food and shelter plant for almost any kind of snail.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p87a.png"></center><br>
+ Burdock</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BANANA and LOOFAH</P>
+<P ALIGN="JUSTIFY">Banana and loofah plants together provide both food and shelter for Achatina and Archachatina snails. Ripe bananas can be cut up and fed to the snails and they can use the loofah plant for food and for shelter. However, your snails will need other food plants as well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p87b.png"></center><br>
+ Banana and Loofah</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">PLANTAGO</P>
+<P ALIGN="JUSTIFY">Plantago grows well from seed and lasts about two years. It is the best shelter plant for Helix snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p87c.png"></center><br>
+ Plantago</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ASPARAGUS</P>
+<P ALIGN="JUSTIFY">Asparagus lives for many years and it is a good shelter plant for young Achatina and Archachatina snails. However, it is not good for older snails because they are too heavy for asparagus plants.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">When are the plants big enough for food and for shelter?</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">118. The food plants must be big enough to feed your snails and the shelter plants tall enough to cover them and to protect them from the sun.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">119. Depending on the kind of snails that you are raising, most plants will be big enough after they have been growing for about five to six weeks or when they have reached a height of 10 to 20 centimetres.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f33p88a.png"></center><br>
+ Plants will grow to a height of 10 to 20 cm.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">120. When you are sure that the plants are big enough to provide food and shelter, you can begin to collect the snails and put them into the pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">121. In Booklet No. 34, Farming snails 2, you will learn</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> how to choose good snails and how to put them in the pen</P>
+<P ALIGN="JUSTIFY"> how to take care of your snails</P>
+<P ALIGN="JUSTIFY"> when and how to harvest snails</P>
+<P ALIGN="JUSTIFY"> how to prepare snails for cooking</P>
+<P ALIGN="JUSTIFY"></P></DIR>
+
+<P ALIGN="JUSTIFY">122. You will also be told some things that you can do to improve your snail farm so that later when you have more experience you can raise more and better snails.</P></FONT>
+<!--
+</Section>
+</Section>
+</Section>
+-->
+</BODY>
+</HTML>
Index: /gsdl/stable/collect/demo/import/fb33fe/metadata.xml
===================================================================
--- /gsdl/stable/collect/demo/import/fb33fe/metadata.xml	(revision 20131)
+++ /gsdl/stable/collect/demo/import/fb33fe/metadata.xml	(revision 20131)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE DirectoryMetadata SYSTEM "http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd">
+<DirectoryMetadata>
+    <FileSet>
+        <FileName>.*</FileName>
+        <Description>
+            <Metadata name="dls.Title">Farming snails 1: Learning about snails; Building a pen; Food and shelter plants (fb33fe)</Metadata>
+            <Metadata mode="accumulate" name="dls.Language">English</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Agriculture and Food Processing|Better Farming series of FAO and INADES - 46 booklets</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Settlements, Housing, Building - Infrastructure Construction (Roads etc)|Settlements and housing: general works incl. low- cost housing, planning techniques, surveying, etc.</Metadata>
+            <Metadata mode="accumulate" name="dls.Organization">FAO Better Farming series</Metadata>
+         </Description>
+    </FileSet>
+</DirectoryMetadata>
Index: /gsdl/stable/collect/demo/import/fb34fe/fb34fe.htm
===================================================================
--- /gsdl/stable/collect/demo/import/fb34fe/fb34fe.htm	(revision 20131)
+++ /gsdl/stable/collect/demo/import/fb34fe/fb34fe.htm	(revision 20131)
@@ -0,0 +1,672 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META NAME="Generator" CONTENT="Microsoft Word 97">
+<TITLE>&lt;&lt;TOC1&gt;&gt; Farming snails 2: Choosing snails; Care and harvesting; Further improvement</TITLE>
+</HEAD>
+<BODY>
+
+<B><FONT FACE="Arial" SIZE=2><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Farming snails 2: Choosing snails; Care and harvesting; Further improvement</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FOOD AND AGRICULTURE ORGANIZATION OF THE UNITED NATIONS</P>
+<P ALIGN="JUSTIFY">Rome 1986</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">P-69</P>
+<P ALIGN="JUSTIFY">ISBN 92-5-102397-2</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&copy; FAO 1986</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Preface</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first twenty- six volumes in FAO's Better Farming Series were based on the Cours d'apprentissage agricole prepared in C&ocirc;te d'Ivoire by the Institut africain de d&eacute;veloppement &eacute;conomique et social for use by extension workers. Later volumes, beginning with No. 27, have been prepared by FAO for use in agricultural development at the farm and family level. The approach has deliberately been a general one, the intention being to constitute basic prototype outlines to be modified or expanded in each area according to local conditions of agriculture.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many of the booklets deal with specific crops and techniques, while others are intended to give the farmer more general information which can help him to understand why he does what he does, so that he will be able to do it better. Booklets No. 33 and 34 were added to the series owing to a growing interest in small- scale snail farming for food and profit in many countries where FAO's Better Farming Series is widely used.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Adaptations of the series, or of individual volumes in it, have been published in Amharic, Arabic, Bengali, Creole, Hindi, Igala, Indonesian, Kiswahili, Malagasy, SiSwati, Thai and Turkish.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Requests for permission to issue this manual in other languages and to adapt it according to local climatic and ecological conditions are welcomed. They should be addressed to the Director, Publications Division, Food and Agriculture Organization of the United Nations, Via delle Terme di Caracalla, 00100 Rome, Italy.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">The snails</Metadata>
+  </Description>
+-->
+<P ALIGN="CENTER"></P>
+<P ALIGN="CENTER">&nbsp;</P>
+<P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Choosing your snails</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">123. All of the snails that you choose for your pen must be of the same kind.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p093a.png"></center><br>
+ All of the snails that you farm must be the same kind</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">124. You may have found one of the kinds of snails shown on pages 8 to 11 in the last booklet living in your area. You may also have found a different kind of snail.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">125. Now you must learn to choose the beat of the kinds of snails that you have found. When you first begin you will need fully grown snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">126. Remember, that all snails are both male and female and all snails lay eggs. So, when you are looking for snails, you can choose any one that is fully grown.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">127. You can tell that a snail is fully grown because it has a lip on the mouth of its shell. The drawings below show two fully grown snails with lips.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p094a.png"></center><br>
+ Snails which fill and which does not fill their cells</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">128. Look at the drawings again. Notice that although both snails are fully grown, one of them fills its shell and one of them does not.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">129. The snail that does not fill its shell may be sick or it may have lost its water because of dry weather. This snail may not grow well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">130. Choose only snails that fill their shells. Snails that fill their shells will usually grow well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">131. Choose snails that have good, strong shells. Strong shells protect snails from their enemies, and snails with strong shells sell better at the market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">132. Choose the largest of the fully grown snails that you can find from the kind of snail that you are going to farm.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p094b.png"></center><br>
+ Choose the largest snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">133. The larger snails of any kind of snail will be better and healthier and lay more eggs than a snail that is smaller.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">134. In addition, the eggs of large, healthy snails hatch better and the baby snails grow bigger and faster.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">135. Later, when you have more experience in choosing snails, you will learn just how large a fully grown snail should be. You will also learn the different colours of the kind of snail that you are farming.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">136. Then you can choose snails that are the same size and colour that you want your baby snails to be.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Note</P>
+<P ALIGN="JUSTIFY">As you collect your snails, handle them very gently and put them carefully into a container such as a basket so that you can carry them to the pen without hurting them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p095a.png"></center><br>
+ Handle your snails carefully</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Putting your snails in the pen</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">137. Just before you put your snails in the pen, take out all the grass, the creeping grass and the weeds that may have grown while the food and shelter plants were growing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p095b.png"></center><br>
+ Take out all grass, creeping grass and weeds</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">138. Never put snails in a pen in the morning or during the day when the sun is hot. Always put them in the evening when it is cool. This is when they begin to move about and to eat.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p095c.png"></center><br>
+ Always put snacks in the pen in the evening</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">139. If there is no dew and leaves of the plants and the ground are dry, wet them. Items 160 to 165 in this booklet will tell you how.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p096a.png"></center><br>
+ Wet the plants</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">140. When you put snails in the pen, put an equal number of them in four different places.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">141. In the last booklet you were told that for a 5 x 5 metre pen you would need 150 snails if you use the small kind, and 25 snails if you use the large kind. So, if you need</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> 150 snails, put 35 to 40 snails in four places</P>
+<P ALIGN="JUSTIFY"> 25 snails, put 6 snails in three places and 7 snails in one place.</P>
+<P ALIGN="JUSTIFY"></P></DIR>
+
+<P ALIGN="JUSTIFY">142. The arrows in the drawing at the top of the next page will show you where to put snails in a 5 x 5 metre pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p096b.png"></center><br>
+ Where to put the snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Note</P>
+<P ALIGN="JUSTIFY">When you put snails in a pen, never put them near the fence or in a corner of the fence. If you put them near the fence it is easier for them to get out than it is if you put them near the centre of the pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p096c.png"></center><br>
+ Do not put snails in the corner or near the fence</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">143. The morning after you have put your snails in the pen, look to see that they have all moved. If any of them have not moved, put them under shelter plants.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">144. If any snails die, take them out and put in the same number of new snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p097a.png"></center><br>
+ Take out the dead snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">145. At first your snails will try to crawl out of the pen. During this time, go around the pen each morning and put them back.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">146. After about two weeks your snails will become used to their new home and most of them will not try to crawl out.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">147. However, it is a good idea, even after the first two weeks, to check from time to time and put back any of the snails that may have got out of the pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">When to take out the fully grown snails</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">148. When you see a lot of baby snails in your pen, you will no longer need to keep the fully grown snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">149. So, take out all of the fully grown snails that you first put into your pen. You can either eat them or sell them at the market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p097b.png"></center><br>
+ Take out all fully grown snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">150. Now, with only the baby snails left, the food plants in the pen will be more likely to last until the baby snails are big enough to harvest.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">151. Later in this booklet, you will be told when the baby snails are big enough to harvest and how to harvest them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Taking care of your snails</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">152. After you have put your snails in their pen, watch them carefully to see that they are eating well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">153. If you have given them enough of the right kinds of food plants, they will eat a lot and you will have very little to do for them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">154. However, here are some things that you must do</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> wet the plants and moisten the ground</P>
+<P ALIGN="JUSTIFY"> take care of the plants</P>
+<P ALIGN="JUSTIFY"> take away the weeds and the creeping grass</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P></DIR>
+
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Wet the food and shelter plants and moisten the ground</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">155. You have already been told that the leaves of the food and shelter plants must be wet and clean and that the ground must be moist (see Items 52 to 58 in the last booklet).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">156. If there is too lime dew and not enough rainfall during the time when the plants and the snails are growing, you will have to water the plants and the ground yourself.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">157. If it is dry, you should water the plants and the ground at least every second day. However, if it is very dry, you may have to water them every day.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">158. Never water in the morning or during the day when the sun is hot. Always water in the evening at about sunset.</P>
+<P ALIGN="JUSTIFY">159. If you water when the sun is hot, the snails will begin to move away from the shelter plants and the hot sun may kill them before they can find shelter again.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">160. An easy way to wet the plants and moisten the ground is by hand. First fill a bucket with water and wrap a piece of cloth around your hand.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p098a.png"></center><br>
+ Wrap a cloth around your hand</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">161. Then, dip your hand with the cloth into the bucket of water and gently splash the plants and the ground.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p099a.png"></center><br>
+ Gently splash plants and ground</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">162. Continue to splash the plants and the ground gently until you have watered the whole pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">163. When you have finished, the leaves of the plants should be wet and the ground should be moist.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">164. You can tell when the plants are wet enough and the ground is moist enough when you can see your snails moving about easily.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p099b.png"></center><br>
+ Snails move about easily</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">165. Remember: the soil must be moist and not wet in order for snail eggs to hatch.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Note</P>
+<P ALIGN="JUSTIFY">You have already been told that if you live in a place that has a dry season when the plants do not grow, snails dig into the ground to rest. Never water at this time or your snails may come out of the ground when they should not.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Tend the food and shelter plants</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">166. Watch all of your plants to see that they are growing well and that they do not get too tall or too thick.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">167. Plants that are too tall or thick stop the dew from reaching the leaves and stop the rain from washing away the dust and the dirt that snails leave when they move about.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">168. If you see that the plants are not being wet or washed by dew or rain, cut them back.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p101a.png"></center><br>
+ Cut back the plants</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Take away the weeds and creeping grass</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">169. After your snails are in their pen you must be sure to take away all weeds and especially creeping grass as soon as you see them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">170. Creeping grass grows very fast and so thick that it can kill the food and shelter plants. If this happens, your snails will have no food and no place to find shelter.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">171. Taking away weeds and creeping grass when snails are in the pen is very difficult. So, you must be very careful not to hurt them or step on them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">172. If the weeds and creeping grass get too thick, it may be better to move the snails before you take weeds and creeping grass away (see Item 183 in this booklet).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">173. Keep the path around the pen clear of weeds, grass and creeping grass. This will help to keep weed seeds and unwanted plants out of the pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p101b.png"></center><br>
+ Keep the path clean</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">174. If the path is clean, insects will be less likely to cross it to get into the pen and you will be able to see signs of mice, rats and shrews.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Feeding your snails other kinds of food</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">175. There are a number of reasons for giving your snails other kinds of food. Here are a few</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> when you have not planted the right kinds of food plants</P>
+<P ALIGN="JUSTIFY"> when you have too many snails for the number of food plants that you have planted</P>
+<P ALIGN="JUSTIFY"> when most of the food plants in the pen have been eaten by the snails</P>
+<P ALIGN="JUSTIFY"></P></DIR>
+
+<P ALIGN="JUSTIFY">176. If you decide for any of these reasons that you must give your snails other kinds of food, here are some foods that snails like to eat</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> the outside leaves of vegetables such as cabbage or cauliflower</P>
+<P ALIGN="JUSTIFY"> the tops of vegetables such as carrots or beets</P>
+<P ALIGN="JUSTIFY"> ripe banana fruit</P>
+<P ALIGN="JUSTIFY"> most waste fruit and vegetables</P>
+<P ALIGN="JUSTIFY"> cut- up papaya, melon or squash</P>
+<P ALIGN="JUSTIFY"></P></DIR>
+
+<P ALIGN="JUSTIFY"><center><img src="f34p102a.png"></center><br>
+ Food snails eat</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">177. There are many other foods that snails like to eat. If you have some food that you think might be good, try it with your snails and see if they like it.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">178. If your snails are not eating their food plants well, you also can try some others. Cut pieces from the plant that you want to try and put them in the pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">179. If you see that your snails like the new food plants better, you can use these plants when you build the second pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Building the second pen</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">180. In the last booklet you were told that to farm snails you will need at least two pens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p103a.png"></center><br>
+ Two pens needed</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">181 . With two pens you can move your snails from one pen to the other to get rid of any enemies that may have got in.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">182. You can also move your snails to dig the ground and work the soil so that they can dig into the soil to rest and can lay their eggs easily.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">183. With two pens you can move your snails from one pen to the other if the weeds and creeping grass get too thick to take away with snails in the pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">184. You can also plant new food plants when the old ones have been eaten. When you are moving the snails, you can get rid of any of them that have not grown well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">When to build the second pen and how to build it</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">185. Build your second pen a little before the growing season and exactly one year after you built the first pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">186. Begin just as you did before, by cleaning and preparing the ground (see Items 86 to 96 in the last booklet).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">187. However, if you put your second pen near your first pen, be very careful when you burn the plant material not to burn your first pen or harm the snails in it.</P>
+<P ALIGN="JUSTIFY">188. For this reason it is best to leave an open space of at least 3 metres between your first and second pens.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p103b.png"></center><br>
+ Be very carefull when you burn the plant material</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">189. Now you are ready to build the second 5 x 5 metre pen and to plant the food and shelter plants (see Items 97 to 117 in the last booklet).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Putting snails in your second pen</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">190. When the plants in your second pen have grown big enough to provide food and shelter, you can put in the snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p104a.png"></center><br>
+ When the plants are grown, you can bring the snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">191. If the snails in your first pen have grown well, you can use some of them for your second pen. So, collect the right number of the biggest and best snails from your first pen to put in your second pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">192. If the snails in your first pen have not grown well, you will have to begin again with new fully grown snails for your second pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">193. Remember, with your first pen you put in 150 snails if you used the small kind and 25 snails if you used the large kind.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">194. However, different snails lay different amounts of eggs. So with your second pen you may want to change the number of snails that you put in.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">195. If there were too many baby snails for the food plants in your first pen, put fewer fully grown snails in your second pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">196. If there were too few baby snails for the food plants in your first pen, put more fully grown snails in your second pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">197. If you are not sure how many snails to use, it is best to continue to put in 150 if you use small snails and 25 if you use large snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p104b.png"></center><br>
+ 25 Large snails; 150 small snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">198. Later, when you have learned more about the kind of snails that you are using and how many baby snails they have, you will be better able to judge just how many fully grown snails that you should use.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Note</P>
+<P ALIGN="JUSTIFY">Do not forget to take out all of the fully grown snails that you have put in after you see a lot of baby snails in your second pen (see Items 148 to 151 in this booklet).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Harvesting your snails</Metadata>
+  </Description>
+-->
+<P ALIGN="CENTER"></P>
+<P ALIGN="CENTER">&nbsp;</P>
+<P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">When to harvest your snails</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">199. If your snails have grown well, some of them will be big enough to harvest about one year after you have first put snails in the pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">200. If you need any snails to put in another pen, collect them first. So, choose the right number (see Items 193 to 198 in this booklet) of the biggest and best snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">201. Carefully put these snails into a container so that you can carry them to the other pen without hurting them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p105a.png"></center><br>
+ Put snails into a container</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">202. Now you are ready to harvest the rest of your biggest snails. Remember, the best way to harvest is a few snails at a time when you want some to eat or to sell at the market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">203. However, harvest all of the snails by the end of the second year so that you can plant the pen in time for the next growing season.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">How to harvest your snails</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">204. Harvesting snails is done by hand. It is often hard work to find them because they may be hiding.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p105b.png"></center><br>
+ Harvesting snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">205. The easiest time to find the snails is when the plants are wet, after it has rained or at night when there is dew and they are moving about or eating.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">206. You can also put out some of the food that snails like and when they come to eat it, you can collect them easily.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p105c.png"></center><br>
+ Put out some food</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">207. When you are harvesting, handle your snails carefully and put them into a container such as a box or basket or a net sack. However, do not put more than 10 kilograms in a container or you may hurt them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p106a.png"></center><br>
+ Put snails in a container</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">What to do with the snails you harvest</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">208. If you are going to sell the snails, you can carry them to the market in containers like the ones above. However, you must be very careful not to hurt them or break their shells.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">209. Remember, snails with clean shells and well- cared- for snails will sell better at the market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">210. If you want to keep the snails for you and your family to eat later, you can store them alive in containers filled with material such as sawdust or chopped maize husks.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">211. That way you can keep them for as long as six to eight weeks before you use them. The drawings below show you how to store snails this way.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">1 a box is a good container to store snails in</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p106b.png"></center><br>
+ A box</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">2 cover the bottom of the box with about 5 cm of sawdust or chopped maize husks</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p106c.png"></center><br>
+ Cover the bottom of the box with sawdust</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">3 carefully put in a layer of snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">4 cover the snails with about 3 cm of sawdust or chopped maize husks</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p106d.png"></center><br>
+ Cover the snails</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">5 continue to do this until the box is full</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Note: be sure that the top layer of snails is covered</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Preparing snails for cooking</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">212. Before snails can be used you must be sure that there is no food in them. They must be clean inside.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">213. Snails that have been stored in a container (see Items 210 and 211 in this booklet) for more than four days will have no food left in them. They are clean inside.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">214. However, snails which have just been taken from the pen have been eating and are usually full of food.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">215. So, before you can use them you must wait for them to become clean inside. To do this you need only to keep them from eating.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">216. Put them in a container where they can get no food but plenty of air. You can use a covered basket or a net sack.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p107a.png"></center><br>
+ Use a covered basket or a net sack</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">217. Put the basket or sack in a cool place away from the sun. After four days the snails will be clean inside.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p107b.png"></center><br>
+ Put the container away from sun</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">218. All snails must be washed and boiled just before cooking them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">219. First, put them in clean, cool water with a little salt and vinegar.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p107c.png"></center><br>
+ Put them in clean water</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">220. After a short time the water will begin 10 turn white and you will know that the snails are being washed inside.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">221. When the water is very white, take the snails out and empty out the old water. Then put them again in clean, cool water with a little salt and vinegar.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p108a.png"></center><br>
+ Empty out dirty water; wash snails again</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">222. Continue to wash them this way until the water no longer turns white. Then you will know that the snails are completely washed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">223. Now put the snails in boiling water, again with salt and vinegar, and boil them at least five minutes. The snails are now ready to be cooked.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p108b.png"></center><br>
+ Boil snails with salt and vinegar for five minutes</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Note</P>
+<P ALIGN="JUSTIFY">Snail meat can be cooked like any meat or it can be cut into pieces and added to a stew or vegetables. If snails are eaten where you live, there will be many ways to cook them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Further improvement</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">224. After you have been farming snails using two pens for some time, you may find that you and your family could eat or sell more snails if you had them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">225. You can raise more snails by building another pen. You can either build another 5 x 5 metre pen or you can build a still bigger pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">226. You can also raise more snails by taking better care of the snails that you have. If you take better care of your snails, year after year they will become bigger, healthier and stronger and produce more baby snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Building the third pen</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">227. Perhaps the most important thing that you can do to improve your snail farm is to build a third pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p109a.png"></center><br>
+ Build a third pen</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">228. Up until now, using only two pens, you have had to use both of them all of the time so that you could take fully grown snails from one after you had harvested the other.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p109b.png"></center><br>
+ Using two pens</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">229. Today, farmers know that it is not good to grow the same crops in the same place all of the time.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">230. This is also true if you grow the same food and shelter plants in the same pen all of the time.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">231. However, if you plant vegetables in one of your three pens for a year, the vegetables will grow well because of the snail manure in the soil. Afterwards, your food and shelter plants will also grow better because the soil has had a rest.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">232. Also, if you raise snails in the same place all of the time, the sicknesses that they may get would do more harm year after year.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">233. So, if you plant something else for a year or two and then start with snails again, they will be less likely to get sick.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">234. The diagram below shows you how to improve a snail farm by planting a vegetable garden in each pen from to time.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p110a.png"></center><br>
+ Diagram</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Building a bigger pen</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">235. You may want to build a still bigger pen for your third pen so you can grow many more snails.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">236. If you build a 5 x 10 metre pen, you can grow two times as many snails. If you build a 10 x 10 metre pen, you can grow four times as many snails as you did in a 5 x 5 metre pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p110b.png"></center><br>
+ Pens</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">237. However, building a bigger pen is a lot more work and you will need</P>
+<P ALIGN="JUSTIFY"></P><DIR>
+
+<P ALIGN="JUSTIFY"> more land</P>
+<P ALIGN="JUSTIFY"> more materials to build it</P>
+<P ALIGN="JUSTIFY"> more food and shelter plants</P>
+<P ALIGN="JUSTIFY"> more fully grown snails to begin</P>
+<P ALIGN="JUSTIFY"></P></DIR>
+
+<P ALIGN="JUSTIFY">238. You must also be sure that you and your family have enough time to take care of a bigger pen.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">239. If you do decide to build a bigger pen, build it exactly the same way that you built your first 5 x 5 metre pen (see pages 43 to 46 in the last booklet).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p111a.png"></center><br>
+ Building a bigger pen</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Taking better care of your snails</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">240. The better you understand the snails that you are farming, the better you can take care of them. So, you should always watch them and learn as much as you can.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">241. When you have learned the exact kinds of food plants that your snails like to eat, you will see that they grow well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">242. Then, if you always choose the biggest and best snails each time you begin, you will improve the quality of the snails that you are farming.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">243. So, with bigger and better snails and with more pens or bigger pens, you will be able to raise many more snails to eat or to sell and you arid your family will be able to live better.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="f34p111b.png"></center><br>
+ Your family will be able to live better</P>
+<!--
+</Section>
+</Section>
+</Section>
+-->
+
+</HTML>
Index: /gsdl/stable/collect/demo/import/fb34fe/metadata.xml
===================================================================
--- /gsdl/stable/collect/demo/import/fb34fe/metadata.xml	(revision 20131)
+++ /gsdl/stable/collect/demo/import/fb34fe/metadata.xml	(revision 20131)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE DirectoryMetadata SYSTEM "http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd">
+<DirectoryMetadata>
+    <FileSet>
+        <FileName>.*</FileName>
+        <Description>
+            <Metadata name="dls.Title">Farming snails 2: Choosing snails; Care and harvesting; Further improvement (fb34fe)</Metadata>
+            <Metadata mode="accumulate" name="dls.Language">English</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Agriculture and Food Processing|Better Farming series of FAO and INADES - 46 booklets</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Settlements, Housing, Building - Infrastructure Construction (Roads etc)|Settlements and housing: general works incl. low- cost housing, planning techniques, surveying, etc.</Metadata>
+            <Metadata mode="accumulate" name="dls.Organization">FAO Better Farming series</Metadata>
+            <Metadata mode="accumulate" name="dls.Keyword">farm snails</Metadata>
+        </Description>
+    </FileSet>
+</DirectoryMetadata>
Index: /gsdl/stable/collect/demo/import/wb34te/metadata.xml
===================================================================
--- /gsdl/stable/collect/demo/import/wb34te/metadata.xml	(revision 20131)
+++ /gsdl/stable/collect/demo/import/wb34te/metadata.xml	(revision 20131)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE DirectoryMetadata SYSTEM "http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd">
+<DirectoryMetadata>
+    <FileSet>
+        <FileName>.*</FileName>
+        <Description>
+            <Metadata name="dls.Title">Development in practice: Toward Gender Equality (wb34te)</Metadata>
+            <Metadata mode="accumulate" name="dls.Language">English</Metadata>
+            <Metadata mode="accumulate" name="dls.Subject">Women, gender and development, women&apos;s organizations</Metadata>
+            <Metadata mode="accumulate" name="dls.Organization">World Bank</Metadata>
+            <Metadata mode="accumulate" name="dls.Keyword">achieve gender equality</Metadata>
+        </Description>
+    </FileSet>
+</DirectoryMetadata>
Index: /gsdl/stable/collect/demo/import/wb34te/wb34te.htm
===================================================================
--- /gsdl/stable/collect/demo/import/wb34te/wb34te.htm	(revision 20131)
+++ /gsdl/stable/collect/demo/import/wb34te/wb34te.htm	(revision 20131)
@@ -0,0 +1,1910 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META NAME="Generator" CONTENT="Microsoft Word 97">
+<TITLE>&lt;&lt;TOC1&gt;&gt; Development in practice: Toward Gender Equality </TITLE>
+</HEAD>
+<BODY>
+
+<B><FONT SIZE=2><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Development in practice: Toward Gender Equality</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Role of Public Policy</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">@ 1995 The Intentional Bank for Reconstruction and Development / THE WORLD BANK</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">All rights reserved Manufactured in the United States of America First printing July 1995</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Development in Practice series publishes reviews of the World Bank's activities in different regions and sectors. It lays particular emphasis on the progress that is being made and on the policies and practices that hold the most promise of success in the effort to reduce poverty in the developing world.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This book is a product of the staff of the World Bank. and the judgments made herein, do not necessarily reflect the views of its Board of Executive Directors or the countries they represent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Photo credits: Maurice Asseo</P>
+<P ALIGN="JUSTIFY">Library of Congers Cataloging-in-Publication Data</P>
+<P ALIGN="JUSTIFY">Toward gender equality: the role of public policy.  p. cm-(Development in practice)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Includes bibliographer references (p. 70)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ISBN 0-8213-3337-2</P>
+<P ALIGN="JUSTIFY">1. Women-Government policy. </P>
+<P ALIGN="JUSTIFY">2. Women's rights. </P>
+<P ALIGN="JUSTIFY">3. Sex discrimination against women. </P>
+<P ALIGN="JUSTIFY">4. Economic development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">1. Series:</P>
+<P ALIGN="JUSTIFY">Development in practice (Washington. D.C.)</P>
+<P ALIGN="JUSTIFY">HQ 1 236.T68; 1995</P>
+<P ALIGN="JUSTIFY">305.4-dc20 95-631</P>
+<P ALIGN="JUSTIFY">CIP</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="CENTER"></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Foreword</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">TWENTY years ago in Mexico the First World Conference on Women inspired a movement that has helped to reduce gender inequality worldwide. Illiteracy among women is declining, maternal mortality and total fertility rates are beginning to fall. and more women are participating in the labor force than ever before. However. much remains to be done.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In low-income countries women are often denied health care and basic education. Worldwide. women face limited access to financial services, technology. and infrastructure. They are locked into relatively low-productivity work. In addition to performing household tasks and child-rearing duties, women work longer hours for lower pay than most men. And. most discouraging of all. hundreds of thousands of women each year are subject to gender-related violence.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Persistent inequality between women and men constrains a society's productivity and, ultimately slows its rate of economic growth. Although this problem has been generally recognized evidence on the need for corrective action is more controlling today than ever.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report written for the Fourth World Conference on Women is intended as a reference to strategies for promoting gender equality and. consequently enhancing economic efficiency. It pulls together evidence, including case studies, that demonstrates the need for governor action to improve the economic status of women. It points out how public policy can and should support services and infrastructure that provide the highest social returns and that are most heavily used by women. The report also aims to stimulate creative solutions to the problem of gender inequality by high lilting innovative and sometimes not obvious strategies that have proved successful. A study in Morocco, for instance, shows that paving public roads to schools increases by 40 percent the probability that local girls will attend classes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Policy reform that provides an enabling environment for economic growth goes hand in hand with investing in people. The success of one strategy draws on the success of the other. No efforts at gender equality. however, can be successful without the participation of women themselves.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As the international community gathers in Beijing for the Fourth World Conference on Women, the World Bank stands ready to assist client governments in response to the challenges ahead. The Bank believes that by advancing gender equality, governments can greatly enhance the future well-being and prosperity of their people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Armeane M. Choksi Vice President Human Capital Development and Operations Policy The World Bank</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Acknowledgments</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THIS REPORT was prepared by a team led by Kei Kawabata and comprising Alison Evans, Zafiris Tzannatos. Tara Vishwanath, and Rekha Menon. The work was carried out under the direction of Minh Chau Nguyen and the overall guidance of K. Y. Amoako. Valuable contributions were made by Joyce Cacho, Lionel Demery, Shahid Khandker, and Kalanidhi Subbarao.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Background papers for the report were prepared by team members and by Anjana Bhushan; Lynn Brown and Lawrence Haddad; Florencia Castro-Leal, with Ignacio Tavares and Ramon Lopez; Roberta Cohen; Monica Fong: Roger Key, with Beverly Mullings; Andrew Mason; and Veena Siddharth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">An external review group and a Bankwide advisory committee provided valuable guidance at all stages of the report's preparation. Kalpana Bardhan. Pranab Bardhan, Nancy Folbre. and T. Paul Schultz were the external reviewers. Harold Aldennan, Jean-Jacques Dethier, Louise Fox, Sunita Gandhi, Chris Grootaert, Jeffrey Hammer, Tariq Husahl, Elizabeth King, Augusta Molnar, Helena Ribe, and Paula Valad made up the advisory committee. The report was edited by Jo Bischoff, Richard M. Crum, and Fiona Mackintosh; Benjamin Crow provided word-processing and graphics support.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The report also reflects the contributions of the participants in consultations held with nongovenamental organizations on March 1S, 1995, in New York. Data supplied by the United Nations and its agencies. particularly the International Labour Organization, the United Nations Educational, Scientific, and Cultural Organization (UNESCO), the United Nations Statistical Office, and the World Health Organization, were invaluable for the preparation of the report.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The production of the report was made possible by the assistance of the Norwegian Ministry of Foreign Affairs, which has given unwavering support to the protnotion of gender equality.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Definitions and Data Notes</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Definitions</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Expected number of years of formal schooling The total number of years of schooling that a child of a certain age can expect to receive if current enrollment patterns remain unchanged.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Literacy rate. The proportion of the adult population that can read or write. This indicator is not always accurate because it is self-reported and represents past investments in schooling. It is often defined only with respect to selected languages and may not take into account the progress being made in many countries through literacy campaigns.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Life expectancy AT BIRTH The number of years a newborn infant would live if prevailing patterns of mortality at the time of birth were to remain unchanged throughout the child's life.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Maternal mortality ratio. The number of women who die in pregnancy and childbirth per 100,000 live births: A measure of the risk that women face of dying from pregnancy-related causes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Data Notes</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unless otherwise specified, dollar amounts are current U.S. dollars. A billion is a thousand million.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The data used in this report cover a range of time periods and are from more than 100 countries (both developing and industrial).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unless otherwise specified, geographic regions are those used by the World Bank in its analytical and operational work and are defined as follows:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">sub-Saharan  Africa countries south of the Sahara except Africa.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">East Asia and the Pacific: low- and middle-income economies of East and Southeast Asia and the Pacific.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Europe and Central Asia. middle-income European countries and the countries that formed the former Soviet Union.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Latin America anti the Caribbean all American and Caribbean economies south of the United States.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Middle East and North Africa all the economies of North Africa and the Middle East.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">South Asia: Bangladesh, Bhutan, India. Myantnar, Nepal, Pakistan. and Sri Lanka.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Summary</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THREE messages echo throughout this document:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> The causes of gender inequality are complex, linked as they are to the intrahousehold decisionmaking process. However the decisions are made. the intrahousehold allocation of resources is influenced by market signals and institutional norms that do not capture the full benefits to society of investing in women. Low levels of education and training. poor health and nutritional status, and limited access to resources depress women's quality of life and hinder economic efficiency and growth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> It is therefore essential that public policies work to compensate for market failures in the area of gender equality. These policies should equalize opportunities between women and men and redirect resources to those investments with the highest social returns. Of these investments. female education, particularly at the primary and lower-secondary level, is the most important, as it is the catalyst that increases the impact of other investments in health, nutrition, family planning, agriculture, industry, and infrastructure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> Women themselves are agents for change because they play a key role in shaping the welfare of future generations. Public policies cannot be effective without the participation of the target group-in this case. women, who make up more than half the world's people. Their views need to be incorporated into policy formulation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Progress to Date</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over the past two decades considerable progress has been made in reducing the gender gap world wide.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> In 1960. for every 100 boys enrolled in primary school. there were 65 girls. In 1990 the ratio had risen to 85.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> In 1980 an average six-year-old girl in a developing country could expect to attend school for 7.3 years. By 1990 this figure had Increased to 8.4 years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> Since the 1950s the female labor force has grown twice as last as the male labor force. Worldwide, more than 40 percent of women over 15 years of age are now in the labor force; in developing countries women account for 30 percent of the labor force (These figures. it should be noted, do not fully reflect women's participation in the informal sector as unpaid family members in agriculture.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Nevertheless. inequalities between men and women persist in many important areas.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> Despite women s biological advantage, their mortality and morbidity rates frequently exceed those of men, particularly during childhood and the reproductive years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> Traditionally women are employed in lower-pay jobs and in a narrower range of occupations than are men. Women's wages are typically only 60-70 percent of wages earned by men.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> Whether in private sector employment or public sector decisionmaking, women are less likely to be in positions of responsibility than are men.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Why Do Gender Inequalities Persist?</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The causes of the persistent inequality between men and women are only partially understood. In recent years attention has focused on inequalities in the allocation of resources at the household level. as seen in the higher share of education, health. and food expenditures boys receive in comparison with girls. The decisionmaking process within households is complex and is influenced by social and cultural norms market opportunities, and institutional factors. There is considerable proof that the intrahousehold allocation of resources is a key factor in determining the levels of schooling. health. and nutrition accorded household members.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Inequalities in the allocation of household resources matter because education, health. and nutrition are strongly [hiked to well-being, economic efficiency. and growth. Low levels of educational attainment and poor health and nutrition aggravate poor living conditions and reduce an individual's capacity to work productively. Such economic inefficiency represents a significant loss to society and hampers future economic growth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Social returns to investments in women's education and health  a? e significantly greater than for similar investment in men.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The social and economic losses are greatest when women are denied access to basic education and health care. Data from around the world show that private returns to investments in education are the same for women as for men and may even be marginally higher (Psacharopoulos 1994). More importantly. social returns (that is, total benefits to society) to investment in women's education and health are significantly greater than for similar investments in men, largely because of the strong correlation between women's education, health, nutritional status. and fertility levels and the education. health, and productivity of future generations. These correlation are even stronger when women have control over the way resources are allocated within the household.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wage differentials between women and men in the market are closely linked to educational levels and work experience. since on average. women earn 30-40 percent less than teen' it is not surprising that fewer women than men participate in the labor force. This wage disparity, reinforced by discriminality institutional norms, in turn influences the intrahousehold division of resources. A vicious circle ensues as households invest less in daughters than in sons in the belief that investment in girls yields fewer benefits. As a result. many women are unable to work outside the household because they lack the education or experience that men have.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The decision not to participate in the labor force does not necessarily reflect a woman's own choice, no' does it always correspond to the optimum use of household resources. Furthermore. the market wage does not take into account the social benefits of educating and hiring women. Discrimination in households and in the market carries not only private costs for individuals and households but social costs for society as well.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Public policies for reducing gender inequalities are therefore essential for counteracting market failure and improving the well-being of all members of society. Investing in women's education and health expands their choices in labor markets and other income-generating activities and increases the rate of return on a household's most valuable asset-its labor.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The decision to allocate women's time to the type of non wage work women typically carry out within the household. such as child care. food preparation, and, in low-income countries especially, subsistence farming and the collection of fuel wood and water, has less to do with economics than with social conventions and norms. These nones can have a strong influence on the household division of labor, even in industrial economies, where women's levels of human capital are equal to-and some times higher than those of most men</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The economy pays to this inequality in reduced labour productivity today and diminished national output tomorrow</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Whether this division of labor is appropriate is, essentially, for society to decide. However. there is no doubt that women's entry into the labor market and other spheres of the economy is directly affected by the extensive amounts of time they traditionally devote to household maintenance and family care. Most men do not make similar allocations of time in the home. Such inequality constrains women's employment choices and can limit girls' enrollment in schools. The economy pays for this inequality in reduced labor productivity today and diminished national output tomorrow. Public policy can address inequalities in the household division of labor by supporting initiatives that reduce the amount of time women spend doing unpaid work. Examples of such interventions include improved water and sanitation services, rural electrification, and batter transport infrastructure.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Constraints on female employment opportunities arising from the household division of labor are compounded by institutional norms operating within the labor market. Although overt wage discrimination is illegal in many countries, employers frequently segregate jobs or offer less training to women workers. Employers often perceive the returns to investing in women workers as lower than those for men mainly because of women's primary role in childbearing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lack of access to financial services, to land, and to intonation and technology compounds the unequal treatment of women. Requirements for collateral, high transaction costs, and limited mobility and education contribute to women s inability to obtain credit. When women do have access to credit, the effect on household and individual well-being is striking. Bon-owing by women is linked to increased holdings of non-land assets, to improve in the health status of female children, and to an increased probability that girls will enroll in school. Independent access to land is associated with higher productivity and. in some cases, with greater investments by women in land conservation.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Strategies for the Future</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">If the benefits from investing in girls and women are so great and can be quantified. why do households and employers underinvest in women? The main reason is that. as discussed above. markets fail to capture the full benefit to society of' investing in women and girls. Where the market fails or is absent. government must take the lead Public policy can contribute directly and indirectly. to reducing gender inequalities by, for example:</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"> Modifying the legal and regulatory framework to ensure a opportunities </P>
+<P ALIGN="JUSTIFY"> Ensuring macroeconomic stability and improving, microeconomic incentives</P>
+<P ALIGN="JUSTIFY"> Redirecting public policies and public expenditures to those investments with the highest social returns</P>
+<P ALIGN="JUSTIFY"> Adopting targeted interventions that correct for gender inequalities at the micro-level.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Modifying the law to eliminate gender discrimination and equalize opportunities for women and men is an important first step. However. legal reform by itself does not ensure equal treatment. Further public action is required to make sure that gender-neutral laws are enforced at the national and local levels.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sound economic policies and well-functioning markets are essential for growth, employment generation, and the creation of an environment in which the returns to divesting in women and owls can he fully realized. Economic instability and price distortions can hinder the process. Consequently. sound macroeconomic management is critical. In general. two sets of policies are necessary: one emphasizing macroeconomic stability and the elimination of price distortions. the other focusing on labor-demanding growth and a reorientation in public spending toward basic services with high social returns- such as education. health care and water supply.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gender inequalities in the distribution of the benefits of public spending frequently arise because of a bias within households that limits women's access to publicly provided services. In addition, the services provided by public spending often are of less benefit to women than to men. Public policy can help remedy this problem by rearranging expenditure priorities among sectors and within the social sectors. It can ensure support for those services and types of infrastructure that offer the highest social returns to public spending and that are most heavily used by women and children. such as water supply anti sanitation services and rural electrification.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally general policy interventions may not be enough. and programs that specifically target women and girls may be required. Targeting is justified. Governments can no longer afford not to invest in women gable on two grounds. First. because women are disproportionately represented among the poor. targeting women can be an effective strategy for reducing poverty (broadly defined to include limited access to services. re sources, and other capability-enhancing factors). Second. where gender differences are wide, targeting-for example. the provision of stipends so that girls can attend school-they be needed to capture social gains and increase  internal efficiency</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Conclusion</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Governments can no longer afford not to invest in women. The evidence on the high private and social returns to investments in women and girls cannot be ignored. By directing public resources toward policies and projects that reduce gender inequality. policymakers not only promote equality but also lay the groundwork for slower population growth, greater labor productivity, a higher rate of human capital formation, and stronger economic growth However, none of these developments can be sustained without the participial of women themselves. Governments and collaborating institutions must listen more carefully to the voices of individual women. including policymakers. and to women's groups. By working with others to identity and implement policies that promote gender equality, governments can make a real difference to the future well-being and prosperity of their people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Chapter one</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Gender Inequalities Persist</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ALTHOUGH the gap between opportunities for men and women is narrowing. inequalities persist, especially in certain regions. This report examines four major development indicators: educational attainment, maternal mortality. life expectancy. and economic participation outside the household. All four are closely related to each other and in turn are closely correlated with individual well-being. These indicators provide a broad picture of trends in gender inequality and their impact on the relative well-being of women and of men.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Education</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite the progress in raising educational enrollment rates for both males and females across all regions in the past three decades, growth in educational opportunities at all levels for females lags behind that for males (figure 1.1). In 1990 an average six-year-old girl in a developing country could expect to attend school for 8.4 years. The figure had increased from 7.3 years in 1980-but an average boy of the same age in a developing country could expect to attend school for 9.7 years The gender gap in expected years of schooling is widest in some countries in South Asia, the Middle East, and Sub-Saharan Africa (see figure 1.2). Gender differences in access to education are usually worse in minority populations such as refugees and internally displaced persons. of which only a few children go to school.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p16.png"></center><br>
+ School enrollment ratios in developing countries </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The latest available figures show that 77 million girls of primary school age (6-11 years) are not in school, compared with 52 million boys (figure 1.3). Moreover, even these gross enrollment rates often mask high absenteeism and high dropout rates. Dropout rates are notably high in low-income countries but vary by gender worldwide and within regions. The rates for girls tend to be linked to age, peaking at about grade 5 and remaining high at the secondary level (Herz and others 1991) Cultural factors, early marriage, pregnancy, and household responsibilities affect the likelihood that girls will remain in school.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although the gross enrollment rate is an acceptable indicator of progress in education, most studies use literacy rates as an indicator of well-being. Overall illiteracy rates have decreased among adults in low- and middle-income countries, but the percentage of illiterate women in the world is still higher than the percentage of illiterate men. Older women constitute the largest share of the illiterates in the world today, a consequence of past inequalities in access to education. In Sub-Saharan Africa, the Middle East, and South Asia more than 70 percent of women age 25 and older are illiterate (United Nations 1991).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At post-secondary levels. where the gap in enrollment between women and men is wider, there is implicit "gender streaming," or sex segregation, by field of study, even in areas with snore female than male enrollees. Gender streaming. which is widespread in both developing and industrial countries, prevents women from acquiring training in agriculture, forestry, fishing, "hard" sciences, and engineering (figure 1.4).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p17.png"></center><br>
+ Expected years of schooling </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Health</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over the past two decades life expectancy at birth has increased for both men and women in all regions of the world. In industrial countries women tend to outlive men by six to eight years on average: in low-income countries gender differences are much narrower (two to three years). Despite women's biological advantage, female mortality and morbidity rates frequently exceed those of men, particularly during early childhood and the reproductive years.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">During the reproductive period the most Important causes of morbidity and mortality among women are high fertility and abortion rates, vulnerability to sexually transmitted diseases (STDS), genital mutilation. and gender violence. Each year, about 500,000 women worldwide die from the complications of pregnancy and childbirth. Maternal mortality ratios for developing and industrial countries vary greatly: the rates in parts of South Asia are among the world's highest, in some cases exceeding 1,500 per 100.000 live births. In Sub-Saharan Africa where the ratio is 700 maternal deaths per 100.000 live births, a woman runs a 1 in 22 lifetime risk of dying from pregnancy-related causes, but in northern Europe the risk falls to 10 in 100,000 (United Nations 1993). In the transition economies of Eastern Europe and the former Soviet Union, the rates are around 40 to 50 per 100,000 live births</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p18.png"></center><br>
+ Figure 1.3 children not in school 1990 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A major cause of maternal deaths is complications from unsafe abortions. Abortion-related deaths are highest in South and Southeast Asia. followed by Sub-Saharan Africa and Latin America and the Caribbean. Lack of access to contraceptives can mean that abortion, is used as a form of birth control. For example, in parts of Eastern Europe and Central Asia abortions are more numerous than live births (World Bank 1994b), and abortion rates were as high as 1.76 per live birth in Russia prior to the transition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As increasing numbers of women become aware of and learn to use contraceptives, total fertility rates are falling worldwide. The exception is Sub-Saharan Africa where the total fertility rate averaged 6.4 between 1985 have been infected by HIV. The World Health organization (WHO 1994) estimates that more than 13 million women will have been infected by HIV by 2000 and that about 4 million of that number will have died (figure 1.5 In Atrica, where 10 million adults are infected with the virus, ode-half of all newly infected adults are women, and more than 5 million are women of childbearing age. In Asia almost half of all adults newly infected with the virus are women, compared with less than 25 percent just six years ago.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p19.png"></center><br>
+ Figure 1.4 fields of study</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p20.png"></center><br>
+  Figure 1.5 HIV infected women 1995 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The mortality risk for females is high during the reproductive years. but it is even higher during infancy and early childhood. Between 1962 and 1992 INFANT mortality in the developing world decreased by 50 percent (UNICEF 1993 However, in seventeen of the twenty-nine developing countries for which recent survey data are available, female children age 1-4 were found to have higher mortality rates than male children. despite girls? biological advantage (World Bank 1994b). In many of these countries the underlying cause of high mortality among girls is the parents' bias toward boys, who receive the best food and medical care.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Genital mutilation, prevalent in twenty-eight countries, is performed on 2 million young girls yearly. The practice leads to long-term morbidity, complications during childbirth, mental trauma, and even death. Table 1.1 summarizes the best available statistics on this practice for selected countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Employment Work</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The time women spend on paid and unpaid work is typically greater than the time men spend in the labor market (see table 1.2 for an example). Unpaid family work is rarely recorded in official statistics. It manifests itself only indirectly in the labor market in the form of gender differences in labor force participation rates. sector of employment, hours of work, and wage level.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">On the whole. labor force participation rates for women are lower than those for men (figure 1.6). However. these differences are often exaggerated because the definition of the participation rate fails to capture many aspects of women's work, particularly time spent on childbearing, childbearing. and other household tasks. Men are usually in the labor force throughout the prime working years (age 20-60), and their participation rates are typically more than 90 percent in virtually every country. Female participation rates vary widely across countries. In 1990, for every ten men in the labor force there were two women in the Middle East and North Africa, three in South Asia. six in Sub-Saharan Africa, and seven in Southeast Asia (United Nations 1991). Worldwide, 41 percent of women age 15 years or over are in the labor force, but in developing countries the corresponding figure is 31 percent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">These numbers are deceptive, however, because they do not take into account the agricultural work for which women in developing countries are responsible within the family For example, the Dominican census of 1981 reported that only 21 percent of rural women participated in the labor force, but just three years later a special study suggested a figure of 81 percent. The census had omitted such activities as cultivating gardens and caring for domestic animals In India different definitions of what constitutes "work" have resulted in estimated participation rates as low as 13 percent and as high as 88 percent (Beneria 1992).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tens of Millions of Women Suffer Female Genital Mutilation.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="JUSTIFY">Table 1.1 female genital mutilation</P>
+</B><P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=2 CELLPADDING=7 WIDTH=468>
+<TR><TD WIDTH="26%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Country</B></FONT></TD>
+<TD WIDTH="38%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Estimated prevalence (percent)</B></FONT></TD>
+<TD WIDTH="36%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Estimated number of women affected (millions)</B></FONT></TD>
+</TR>
+<TR><TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Djibouti</FONT></TD>
+<TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">98</FONT></TD>
+<TD WIDTH="36%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">0.2</FONT></TD>
+</TR>
+<TR><TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Egypt</FONT></TD>
+<TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">50</FONT></TD>
+<TD WIDTH="36%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">13.5</FONT></TD>
+</TR>
+<TR><TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Eritrea</FONT></TD>
+<TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">90</FONT></TD>
+<TD WIDTH="36%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">1.5</FONT></TD>
+</TR>
+<TR><TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Ethiopia</FONT></TD>
+<TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">90</FONT></TD>
+<TD WIDTH="36%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">22.5</FONT></TD>
+</TR>
+<TR><TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Kenya</FONT></TD>
+<TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">50</FONT></TD>
+<TD WIDTH="36%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">6.3</FONT></TD>
+</TR>
+<TR><TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Nigeria</FONT></TD>
+<TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">50</FONT></TD>
+<TD WIDTH="36%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">29.2</FONT></TD>
+</TR>
+<TR><TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Sierra Leone</FONT></TD>
+<TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">90</FONT></TD>
+<TD WIDTH="36%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">2.0</FONT></TD>
+</TR>
+<TR><TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Sudan</FONT></TD>
+<TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">89</FONT></TD>
+<TD WIDTH="36%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">118</FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Sri Lanka's Dry Zone, Women Work Longer Hours than Men.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="JUSTIFY">Table 1.2 distribution of monthly work hours per month)</P>
+</B><P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=2 CELLPADDING=7 WIDTH=451>
+<TR><TD WIDTH="40%" VALIGN="TOP">&nbsp;</TD>
+<TD WIDTH="31%" VALIGN="TOP" COLSPAN=2>
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Peal. Season</B></FONT></TD>
+<TD WIDTH="29%" VALIGN="TOP" COLSPAN=2>
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Slack season</B></FONT></TD>
+</TR>
+<TR><TD WIDTH="40%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Activity </B></FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Male</B></FONT></TD>
+<TD WIDTH="17%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Female</B></FONT></TD>
+<TD WIDTH="10%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Male</B></FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Female</B></FONT></TD>
+</TR>
+<TR><TD WIDTH="40%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Agricultural production</FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">298</FONT></TD>
+<TD WIDTH="17%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">299</FONT></TD>
+<TD WIDTH="10%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">245</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">235</FONT></TD>
+</TR>
+<TR><TD WIDTH="40%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Household tasks</FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">90</FONT></TD>
+<TD WIDTH="17%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">199</FONT></TD>
+<TD WIDTH="10%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">60</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">220</FONT></TD>
+</TR>
+<TR><TD WIDTH="40%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Fetching water and firewood</FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">30</FONT></TD>
+<TD WIDTH="17%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">50</FONT></TD>
+<TD WIDTH="10%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">:30</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">60</FONT></TD>
+</TR>
+<TR><TD WIDTH="40%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Social and religious duties</FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">8</FONT></TD>
+<TD WIDTH="17%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">12</FONT></TD>
+<TD WIDTH="10%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">15</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">15</FONT></TD>
+</TR>
+<TR><TD WIDTH="40%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Total work hours</FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">426</FONT></TD>
+<TD WIDTH="17%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">560</FONT></TD>
+<TD WIDTH="10%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">350</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">530</FONT></TD>
+</TR>
+<TR><TD WIDTH="40%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Leisure and sleep</FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">294</FONT></TD>
+<TD WIDTH="17%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">160</FONT></TD>
+<TD WIDTH="10%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">370</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">190</FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Women are usually employed in different sectors than men. Most of women's nonagricultural employment is in the service sector. but in developing countries female employment in manufacturing has been increasing and is catching up with female employment in services (ILO/ INSTRAW 1985). Women in manufacturing tend to be concentrated in only a few sub sectors: more than two-thirds of the global labor force in garment production is female. and this subsector absorbs almost one-fifth of the female labor force in manufacturing (UNIDO 1993). Men's employment is more evenly distributed across other sectors such as mining manufacturing, construction, utilities, and transport.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over their lifetime, women change their employment status more often than do men. They are also more likely to be self-employed or employed in occupations with flexible house such as subcontracted home work. Regardless of the sector in which they are employed, women tend to work in a narrow range of occupations. Only a few women are in high-paying jobs or in positions with significant responsibility. Nearly two-thirds of the women in manufacturing ate laborers, machine operators. and production workers; only 5 percent ate professional and technical workers and only 2 percent are administrators and managers (UNIDO 1993). However. there are regional differences: women occupy nearly 60 percent of clerical, sales. and service jobs in Latin America and the Caribbean but fewer than 20 percent of similar positions in South Asia North Africa. and the Middle East (figure 1.7).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p23.png"></center><br>
+ Figure 1.6 rates of participation in the labor force by gender</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Wages paid to women are typically about 60-70 percent of those paid to men. About one-quarter of the gender wage gap is explained by differences in educational levels, labor market experience, and other human capital'' characteristics (Psacharopoulos and Tzannatos 1992 Horton 1994). The gender wage gap can also be explained in part by women's lower participation in the labor market-a consequence of domestic and other demands on their time and, possibly, of discriminatory employment practices.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Significant changes in the global economy have affected patterns of employment and working conditions for men and women worldwide. "Globalization" is associated with the deregulation of product and labor markets, with regionalization. and with the liberalization of international trade. In turn. these processes at-e associated with increased female participation in the labor force and with the at-owing "casualization'' of employment, as seen in the growth of part-time work in industrial economies. However, the net effect of globalization on women workers is not yet clear. Growth in the international traded service sector (for example, banking and telecommunications) seems to have offered women in developing countries greater employment opportunities. In addition, the participation rate of women in manufacturing jobs has increased faster than that of men. Women's average participation in the manufacturing labor force is now around 30 percent for both developing and industrial countries.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p24.png"></center><br>
+ Figure 1.7 types of jobs held by women </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Worldwide, the number of women employed in export manufacturing has been increasing rapidly, even though this sector employs only a small fraction of all women workers. In Mexico, for example, the number of women employed in export manufacturing rose by nearly 15 percent a year in the 1980s (Jurisman and Moreno 1990). However, employment in this sector has been increasing more rapidly for men than for women, partly because of</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">technological upgrading over time and partly; because women are less educated and tend to remain in low-skill occupations (Baden 1992).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Women now account for a growing share ret wage employment they tend to stay longer in the labor force than ever before</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite persistent gender inequalities in the labor market. some recent trends  are encouraging. Increasing educational opportunities and decreasing fertility  rates have fed to an increase in the number of women entering the labor market. since the 1950s the female labor force has expanded twice as fast as the male  labor force. Women now account for a growing share of wage employment. and they tend to stay longer in the labor force than ever before The narrowing of the gender gap in labor force participation is enabling women to accumulate the work experience necessary tot- improving their job opportunities and increasing their amines. In the formal sector more and more women are working in occupations and sectors once dominated by men. and in many countries women s wages relative to men s have increased over time</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The data in this chapter illustrate some aggregate trends but they cannot tell US anything about the processes behind the persistence of gender inequality. For a more detailed look at these processes. We turn in the next chapter to a growing body of empirical evidence generated at the household and enterprise level. These studies provide a telling insight into the way in which gender inequalities are being challenged particularly by women At the same time these inequalities are reinforced by economic, legal. and cultural incentive systems that discriminate against women Discrimination continues despite compelling evidence showing that less inequality especially within the household. is associated with heftier welfare outcomes for children and better economic outcomes for the household as a v hole.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Chapter two</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Gender Inequalities Hamper Growth</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Inequality women and men limits productivity ultimately slows economic growth. early empirical studies (for example, Kuznets 1955) suggested that income inequality would increase with economic growth during the initial phases of development. This chapter, however. starts with the hypothesis that there is not necessarily a tradeoff between inequality and growth and. indeed that high inequality especially as it affects human capital. hampers growth (Fields 1992: Birdsall and Sabot 1994).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Both theory and empirical evidence point to the importance of human capital in creating the necessary conditions for productivity growth and in reducing aggregate inequality in the future. In addition. women s human capital generates benefits for society in the form of lower child mortality.  higher educational attainment improved nutrition. and reduced population growth. Inequalities in the accumulation and use of human capital at-e related to lower economic and social well-being for all.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Household and Intrahousehold Resource Allocation</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In recent years, attempts to explain persistent gender inequalities in the accumulation and use of human capital have focused on the key role of household decisionmaking and tile process of resource allocation within household Households do not make decisions in isolation. however: their decision are linked to market prices and incentives and are influenced by cultural legal and state institutions. These institutions indirectly affect not only the returns on household investment but also access to productive resources and employment outside the house hold.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Household decisions about the allocation of resources have a profound effect on the schooling, health care, and nutrition children receive. The mechanisms used to make these decisions and the effect of the decisions on the well-being of individual household members are not fully understood. Two frameworks for thinking about household decisions are the unitary household model and the collective household model (see box 3.1)</P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=2 CELLPADDING=7 WIDTH=590>
+<TR><TD VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">BOX 2.1 </P>
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Two models of household members having their own prefer decisionmaking encase. Decisions on allocating resources reflect market rates of return. The unitary household model assumes but they also mirror the relative bar that household members pool regaining power of household members sources and allocate them according within the collective (Manser and to a common set of objectives and Brown 1980: McElroy and Homey goals. Households maximize the joint 1981). Bargaining power is a function welfare of their members by allocating of social and cultural norms. as well income and other resources to the in as of such external factors as opposed individuals and enterprises that promise "unities for paid work, laws governing the highest rate of return as reflected inheritance, and control over producing prices and wages. An increase initiative assets and property rights. These household income increases the well factors influence the terms governing being of all household members.</FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Policy interventions based on the sources and decisions about how unitary household model aim to in those resources are used within the crease household welfare, but they household. Thus, an increase in do not necessarily affect all household income may benefit some hold members in the same way. Some household members but leave others household members may be worse unaffected or worse off. The outcome off, for example, if they lose control depends on a member's ability to exover certain resources; others may excise control over resources both in be better off. in which case house-side and outside the household, and it hold welfare is not maximized. cannot be assumed that individual well</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Under the collective household being increases as household income model. the welfare of individual house-rises. (Collective household models do hold members is not synonymous with not exclude the possibility that the universal household welfare. Resources unitary model may be the best approximate not necessarily pooled, and the motion of household decisionmaking household acts as a collective, with in some contexts.)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The collective household model helps explain why gender inequalities persist even though household becomes increase over time The next sections adopt a collective household framework to explain how these inequalities exact costs in forgone productivity, seduced welfare for individuals and households, encl. ultimately. slower economic growth.(fender Inequalities in Human Capital )</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are strong complementaires between education. health. and nutrition on the one hand, and increased well-being, labor productivity, and growth. On the other. Inequalities in resource allocation that limit household members' educational opportunities. access to health care, or nutrition are costly to individuals, households, and the economy as a whole.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Linkages between Education Health, and Nutritious</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the household level. gender differences in access to education are closely related to inequalities in the shares of household education expenditures allocated to boys and to girls This finding stands even though private returns to girls' schooling are similar to or marginally higher than. those to boys' schooling (figure 2.1; see also Schultz 1988: Mwabu 1994). In this case. parental choice reflects the relatively greater restrictions on educational opportunities and employment choices for girls. in comparison with boys. and cultural norms on the appropriate role for girls within the household.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p28.png"></center><br>
+ Figure 2.1 private returns to education</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p29a.png"></center><br>
+ Figure 2.2 education, fertility. and child mortality (a)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY"><center><img src="p29b.png"></center><br>
+ Figure 2.2 education, fertility. and child mortality (b)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">More importantly. the social externalities linked to female education are crucial. Evidence from a large number of countries shows that female education is linked with better health for women and their children and with lower levels (figure 2.2). This link stems from the direct effect of education on the value of a woman's time and consequently. on private returns to her labor. It also stems from the indirect effect of education on the average age at which women marry on their knowledge of basic health care and nutrition, and on reproductive choices (Rosenzweig and Schultz 1982, 1987).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Educating girls and women reduces maternal mortality and fertility rates and increases the demand for health services. A simulation study of seventy two developing countries shows that, with all other factors held constant, a doubling of female secondary school enrollments in 1975 would have reduced tile average fertility rate in 1985 from 5.3 to 3.9 children per household and would have lowered the number of births by 29 percent (Subbarao and Raney 1992. Studies for individual countries have found that one additional year of female schooling can reduce the fertility rate. on average, between 5 and 1 (i) percent (Summers 1994)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Women are more vulnerable than men to micronutrient deficiencies that aggravate poor health (World Batik 1994b). Poor health and nutrition reduce productivity and the chances of reaping gains from investment in education. Intrahousehold inequalities in consumption and nutritional allocations can therefore be a signal of inefficiency Recent estimates suggest that the com effects on morbidity and mortality of just three types of deficiency-in vitamin A, iodine. and iron-could waste as much as 5 percent of gross domestic product (GDP), yet correcting these deficiencies would cost less than 0.3 percent of low-income countries' GDP (World Bank 1994c, pp. 50-51). Studies of women tea producers in Sri Lanka and of women workers in Chinese cotton mills document the reduction in productivity associated with iron deficiencies and the positive effects of in-on supplementation on work and output (Edgerton and others 1979). A study of six villages in Andhra Pradesh, India, found that disabling conditions caused by malnutrition and the prevalence of diseases reduced female labor force participation by 22 percent (Chatterjee 1991).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Physical anti mental abuse can also have deleterious effects on the well-being and productivity of women (table 2.1). Violence against women is widespread in all cultures and cuts across all age and income groups Its consequences. include unwanted pregnancy. infection with STDs, miscarriage partial or permanent disability. and psychological problems such as depression anti low self-esteem. Recent World Bank estimates indicate that in both industrial and developing countries domestic violence and rape cause women of reproductive age to lose a significant percentage of really days. Domestic violence appears to be an example of how the relatively weaker bargaining power of women and the paucity of options for them outside the home can affect the intrahousehold distribution of welfare.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Violence against Women Starts in the Womb and Continues  trough Life</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="JUSTIFY">Table 2.1 Violence against women through the life cycle</P>
+</B><P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=2 CELLPADDING=7 WIDTH=590>
+<TR><TD WIDTH="22%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Phase</B></FONT></TD>
+<TD WIDTH="78%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Type of violence</B></FONT></TD>
+</TR>
+<TR><TD WIDTH="22%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Pre birth</FONT></TD>
+<TD WIDTH="78%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Battering during pregnancy (emotional and physical effects on the ottoman) effects on birth outcome</FONT></TD>
+</TR>
+<TR><TD WIDTH="22%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Infancy</FONT></TD>
+<TD WIDTH="78%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Female infanticide: emotional and physical abuse</FONT></TD>
+</TR>
+<TR><TD WIDTH="22%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Girl hood</FONT></TD>
+<TD WIDTH="78%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Sexual abuse by family members and strangers: forced child prostitution</FONT></TD>
+</TR>
+<TR><TD WIDTH="22%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Adolescence</FONT></TD>
+<TD WIDTH="78%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Dating and courtship violence: economically coerced sex: sexual abuse in the workplace: rape: farce prostitution and trafficking in women</FONT></TD>
+</TR>
+<TR><TD WIDTH="22%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Reproductive</FONT></TD>
+<TD WIDTH="78%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Coerced pregnancy: rape: abuse of women by male partners: down abuse and murder partner homicide psychological abuse sexual abuse of unmarried and childless women: abuse of women with disabilities</FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY">Source: Heise 1993 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Prospects for gainful employment. as well as the availability of basic social services such as water supply and sanitation. also influence women's well-being. The survival chances of female children in India appear to increase as the employment rate for women rises and the earnings differential between men and women decreases Battilan 1988 Dowry and marriage practices. along with household ownership of land are closely linked to women's chances of survival The effect of such practices cannot be over late. Sen's (1990) comparison of female-male mortality rates in China. India. and Sub-Saharan Africa suggest that more than 100 million women are "missing"</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Public spending on social services affects the ability of individuals and households to benefit from their own private spending on human capital. In most industrial countries mortality rates decreased even before modern medical care became widely available, mainly because of improved water supplies and sanitation. The same is likely to hold for the developing world. Public interventions that address market under provision of water and sanitation facilities and shortages of health set-vices such as immunization and family planning-have a significant effect. and one that is probably greater for women than for men.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lack of data makes it difficult to evaluate the effects of public spending on the educational attainment and health of women and men Very little empirical evidence in this area exists, but there is some indication that the proportion of public subsidies for education that benefits females is lower than the proportion that benefits males. In Kenya in 1992-93. for example. public spending on education amounted to the equivalent of an annual subsidy of 605 Kenyan shillings per capita: males received. on average. 670 shillings and females only 543 shillings. In Mexico the gender difference in public education subsidies was somewhat less: in Pakistan males received almost twice the female subsidy. Gender inequalities in the distribution of subsidies are greater at high than at primary levels. In Pakistan girls receive, on average. only 96 rupees a year for secondary school bag. compared with 58 rupees for boys. Box 2.2 explains how these figures are calculated.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Supply-side differences are partly a function of poorly targeted resources (as. for example, when more is spent on tertiary than on primary schooling). More importantly. they reflect differences in household demand for education for girls and boys. If more girls attended anti stayed in school. the proportion of public subsidy going to girls would he greater.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In health care assessing the incidence of public spending by gender is particularly difficult because of the marked differences in the health needs of women and men. These differences are related to different biological re</P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=2 CELLPADDING=7>
+<TR><TD></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY">The main advantage of this type of analysis is that it measures how well public  services are targeted to certain groups in the population, including women, the  poor, and residents of regions of interest.  Requirements anti to women's reproductive and childbearing roles. Some evidence suggests that because of these differences. per capita health cat-e subsidies to women are the same as and sometimes larger than those to men What is clearer is that women are less likely than men to seek health care. including in many countries. hospital care when it is netted and ate mote likely to consult a non medical health cat-e worker (lather than a qualified medical practitioner). Education tends to increase the likelihood that women will seek health care. whether public or  ace the likelihood that women will seek health care. whether public or private (World Bank 1994b). </P>
+<P ALIGN="JUSTIFY">The importance of private and public investments in education and health services that will improve women's well-being is cleat. These services at-e also important for another season: these is important evidence that increases in women's well-being yield important intergenerational benefits and productivity gains in the future World Bank Living Standards Measure Study (LSMS) surveys car-tried out in Nicaragua (1993 Viet Nam 1993) Pakistan (1991), and Cote (1988) suggest that the probability of children being enrolled in school increases with their mother's educational level and that (controlling, for income and household size) girls. particularly those in non poor households. are mote likely to attend school if their mothers attended school. Other studies show that households with educated mothers lend to provide children with greater quantities of mote nutritious food often at a lower cost. than households with poorly educated mothers (Thomas 1990b)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Data from Brazil show that giving women more control over nonlabor income has a larger impact on child measures, nutritional intakes, and the proportion of the household budget devoted to human capital inputs than if men had control of this income (Thomas 1993) Other studies indicate that women spend proportionately mote of the income they control on health care for children than do men. Women also spend more on food products (as opposed to such goods as alcohol and tobacco) than men do (Duraiswamy 1992: Hoddinot and Haddad 1992) But fathers education is also important especially in interaction with mothers' education (Thomas 1990a) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other studies have shown that children's educational attainment is lowest in households whet-e the male head has no schooling In Ghana the impact of a mother's education on her children's schooling is reduced when  their father has no schooling. even after controlling for income and household size (Lavy 1992).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Material health (which is linked to education) also has important intergenerational effects. Children of mothers who are malnourished or sickly or receive inadequate prenatal and delivery cat-e face a greater risk of disease and premature death. Iodine-deficient mothers run a greater risk of giving birth to infants with severe mental retardation and other congenital abnormalities than do healthy mothers. Reduced fertility and improved health for women can increase individual productivity and improve family well-being. When good health is combined with education and access to jobs. the result is higher rates of economic growth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Household and Labor Market Linkages</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The link between the household and the labor market is particularly important. Specialization of labor within the household-whether individually chosen. socially determined. or legally induced-can accentuate gender inequalities in the formal and informal labor markets by leaving most of the unpaid work to women. This situation arises from convention rather than  from comparative advantage Inadequate public and community services.  transport. and housing also often have an uneven effect on the way men and women spend their time and can increase the demand for goods produced at home using unpaid labor (Moser 1994) Thus women may spend its much (or more time on unpaid work as on market work. In some countries this unpaid work contributes as much as one-third to the economy recorded GDP-and even mote to the welfare of poor families.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The amount of time women contribute to household production and maintenance, direct income generation. and family care combined is widely held to exceed that of men Analysis of data from Bangladesh. Botswana. Ghana. Kenya. Pakistan. the Philippines. and Zambia on how rural women spend their time confirms that, although use of time by women, and by different generations of women varies according to location. available technology. household characteristics. and cultural norms. gender bias in time use is widespread.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Women are generally responsible for collecting fuelwood and carrying water. Girls and alder women often do most of this work, although cultural norms in some countries affect women s mobility. The amount of time allocated to these activities is influenced by seasonal patterns of agricultural activity. the availability of substitute goods and services. and environmental changes. A study in Nepal, for instance, found that deforestation associated with a 75 percent rise in the time per trip would increase the time spent gathering fuelwood by 45 percent for all adults and by 50-60 percent for women.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In addition to fuel and water collection, child care is another activity that dominates women s time-although. considering the importance of children to future household welfare, the amount of direct time spent with children is limited. The seven-country study suggests that more time is spent on child cat-e in female-headed households. Female-headed households tend to have high dependency ratios and relatively large numbers of children, Implying more child-care time overall, but not necessarily on a per child basis. (Kumar and Hotchkiss 1988).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">When a large proportion of women's use of time goes unrecorded the design of projects and policies can yield false evaluations of costs and benefits. For example, women's unpaid work may be assumed to have zero value. As a result, women's response to changing incentives may be predicted as being higher than their time constraints actually allow. Project benefits-such as the time saved by locating piped water close to homes or by expanding rural electrification-may also be undervalued. Conversely, the benefits of treeing up time may be far more significant than might have been thought. A study in Tanzania, for example. shows that relieving certain time constraints in a community of smallholder coffee and banana growers increases household cash incomes by 10 percent, labor productivity by 15 percent, and capital productivity by 44 percent (Tibaijuka 1994).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Formal Sector Employment</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Unpaid work and family responsibilities. as well as lack of investment in women's education. are strongly associated with women's relatively low rates of participation and their limited earnings in formal sector labor. Women's participation rates usually dip in the childbearing years, and earnings tend to decline following an interruption in employment. Younger on average, work more hours than older women, and married women with young children tend to work less than childless women and mothers of grown children. The correlation of marriage and childbearing with labor market outcomes can be seen even in industrial countries, where wage differences between married women and men are larger than those between single women and men Similarly, in some developing countries relative earnings decline with age (table 2.2) Children are not the only treason for interruptions in women's labor force participation; caring for ill or aged family members is often a womans responsibility. A study from Hungary estimates that half of all absenteeism by women workers is the direct result of the need to care for sick relatives (Einhorn 1993).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Countries, Single Women Earn More Than Married Women and Younger Women More Than Older Women.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="JUSTIFY">Table 2.2 female-male earnings (adjusted for hours worked) by marital status and age (percent)</P>
+</B><P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=2 CELLPADDING=7 WIDTH=345>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Country</B></FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Female-male</B></FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Earnings ratio</B></FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">By marital status</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Married </FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Single</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Australia</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">69</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">91</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Austria</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">66</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">97</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Germany</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">57</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">103</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Norway</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">72</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">92</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Sweden</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">72</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">94</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Switzerland</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">58</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">94</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">United Kingdom</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">60</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">95</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">United States</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">59</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">96</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Age</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">A 25 </FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">B 45</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Brazil</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">75</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">63</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Colombia</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">94</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">70</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Indonesia</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">81</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">60</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Malaysia</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">82</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">61</FONT></TD>
+</TR>
+<TR><TD WIDTH="38%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Venezuela</FONT></TD>
+<TD WIDTH="27%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">92</FONT></TD>
+<TD WIDTH="35%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">70</FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY">Sources: Blau and Kahn 1992 Sedlacek Gutierrez. and Mohindra 1993 </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thus. women s labor market outcomes can be substantially poorer than those of men because women's employment opportunities are constrained by social arrangements at the family or household level. These social demands are reinforced by legal conventions. Within the labor market itself, social or employer discrimination can affect women and men differently. and these differences are reflected in the resource allocation decisions taken within the household. Although wage discrimination is illegal in many countries, employers may respond to an increase in the supply of workers by segregating jobs by gender or offering less training to women who they perceive as being temporarily attached to the labor force (even if in fact most women never drop out). For example, women in the former Soviet Union are fairly well educated and have high labor force participation. but they are concentrated in occupations requiring fewer skills and less vocational training than men, and, on average. they earn less than men (Fong 1993).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Female Wages Are Lower than Male Wages, but This Is Changing.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="JUSTIFY">Table 2.3 female-male earnings ratio over time Female-male earning 1 ratio (percent) </P>
+</B><P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=2 CELLPADDING=7 WIDTH=496>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Country</B></FONT></TD>
+<TD WIDTH="26%" VALIGN="TOP" COLSPAN=2>
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">First observation</B></FONT></TD>
+<TD WIDTH="25%" VALIGN="TOP" COLSPAN=2>
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Second observation</B></FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">A v Average annual percentage change</B></FONT></TD>
+</TR>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Brazil</FONT></TD>
+<TD WIDTH="11%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">50.2</FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">(1981) </FONT></TD>
+<TD WIDTH="11%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">51.6</FONT></TD>
+<TD WIDTH="13%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">(1990)</FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">0.7</FONT></TD>
+</TR>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Colombia</FONT></TD>
+<TD WIDTH="11%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">67.2</FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">(1984)</FONT></TD>
+<TD WIDTH="11%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">70 2</FONT></TD>
+<TD WIDTH="13%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">(1990)</FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">0.7</FONT></TD>
+</TR>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">C&ocirc;te d'Ivoire</FONT></TD>
+<TD WIDTH="11%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">75.7</FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">(1985)</FONT></TD>
+<TD WIDTH="11%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">81.4</FONT></TD>
+<TD WIDTH="13%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">(1988)</FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">2.4</FONT></TD>
+</TR>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Indonesia</FONT></TD>
+<TD WIDTH="11%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">55.6</FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">(1986)</FONT></TD>
+<TD WIDTH="11%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">60.0</FONT></TD>
+<TD WIDTH="13%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">(1997)</FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">1.3</FONT></TD>
+</TR>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Philippines</FONT></TD>
+<TD WIDTH="11%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">70.9</FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">(1978)</FONT></TD>
+<TD WIDTH="11%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">80.0</FONT></TD>
+<TD WIDTH="13%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">(1988)</FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">1.2</FONT></TD>
+</TR>
+<TR><TD WIDTH="21%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Thailand</FONT></TD>
+<TD WIDTH="11%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">73.5</FONT></TD>
+<TD WIDTH="15%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">(1980)</FONT></TD>
+<TD WIDTH="11%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">79.8</FONT></TD>
+<TD WIDTH="13%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">(1990)</FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">0.8</FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY">Note: Monthly earnings for Indonesia and Thailand rural and urban: for all others urban only</P>
+<P ALIGN="JUSTIFY">Source: Tzanntors 1995</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Women's earnings relative to men's tend to increase over time. A study of six developing countries shows that female earnings relative to male earnings increased by 1 percent a year in the 1980s (table 2.3). There were two reasons for this increase: over the years women entered higher-paying sectors. and within sectors, their pay increased in relation to that of men. This gain would have been even greater had it not been for the effect on wages of increased female participation in the labor force. However, the most visible dimension of gender inequality in the formal labor sector remains the wage difference between men and women. Women's wages are. on average lower those of men by about 30 to 40 percent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Social or employer discrimination can affect women and men difference and these difference are reflected i/? the resource allocation decisions taken within the household</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A recent study of the gender wage gap in Russia shows that after controlling for education differences, the ratio of women's to men's average hourly earnings stands at just over 71 percent: it has remained at that level since the 1960s. Part of the reason for women s lower hourly earnings in Russia and many other countries lies in patterns of occupational segmentation by ,gender. Some analysts argue that women-who do most of the household work in Russian households and also have high participation in the formal labor market cope with the burdens imposed on them by taking less demanding work and devoting less time to advancing their careers (Newell and Reilly 1994).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Informal Sector</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One difficulty analysts face in interpreting trends in women's labor force participation and employment in developing economies is the large number of women engaged in informal sector activities, many of which overlap with subsistence - orientated household or community-based activities. Informal sector employment in most developing countries. whether in microentreprises or in casual work, is an important source of livelihood for women and their households.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The L competitiveness of women's informal sector activities is  constrained by women's limited mobility and lack of access to financial and public sectors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A recent study in Mexico estimates that 41 percent of the work force in Mexico's major-cities is employed in the informal sector (World Bank 1995c). Data from a 1989 survey show that 60 percent of men working in the sector are salaried workers' compared with only 18 percent of women. By contrast. 80 percent of women working in the sector are unpaid family members, as against 27 percent of men. By far the most common activity in the informal sector is commerce (fixed-location or itinerant), followed by repair works food preparation. and sales, and small-scale manufacturing. The sectoral distribution of informal employment reflects the hey role informal workers play in supplying goods and services to low-income consumers. Women tend to be concentrated in commerce and men in services and manufacturing, although the percentage differences are relatively small. Two generalizations can be made on the basis of this study: informal sector workers earn less than workers in large firms and women earn less than men.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another recent study of tour communities in Lusaka. Guayaquil (Ecuador), Metro Manila, and Budapest shows that informal sector activities ate especially important for during periods of economic reform Although the numbers both of men and of women in the labor force tend to increase during these times women rely more on the informal sector than men clot The competitiveness of womens informal sector activities is informal by women's limited mobility and lack of access to financial and public services. Women also tend to specialize in non traded goods and services that show relatively low average returns to labor. Across the tour cities in the study, women earn between 46 and 68 percent of men's wages (Moser 1994)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The ability of informal sector workers to increase their returns depends on access to physical and human capital and their relationship to the institutional and regulatory environment. Contrary to the common belief, many microenterprises face considerable costs associated with the regulatory environment, including registration and licensing fees, as well as outlays for contracts with public authorities concerning zoning regulations and use of public utilities. In Argentina regulatory costs are estimated to absorb as much as 21 percent of the average microfirm's operational expenses. In some sectors, such as manufacturing and construction, the costs of regulation are about 44 percent (World Bank 1994d). In Mexico real regulatory costs. including the costs of compliance and evasion, are about 20 percent of total costs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Regulatory costs also inhibit Job creation in the informal sector. In Argentina across-the-board deregulation could generate as many as 170,000 jobs in small-scale manufacturing alone. Furthermore. poor workers in family-based firms or micro enterprises and particularly women entrepreneurs-often lack access to such basics as water and power. Targeting infrastructure investments to the poor, which takes account of the needs of women entrepreneurs s. can significantly enhance their productivity and earnings.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In rural area where formal markets often are not well developed. informal employment activities play a vital role. In Asia the proportion of female rural wage laborers increased sharply in the 1960s and 1970s. In India women make up a larger proportion of rural wage laborers than of the entire labor force, probably because of growing landlines and poverty among rural households. Rural household labor accounts for a disproportionately large share of employment among the poor and an even larger share among women. Furthermore, a larger proportion of female than male laborers are hired on a casual basis, largely because family arrangements, especially lack of control over property, limit women's ability to work (Hart 1986: Bardhan 1993). Low status in the labor market is also linked to low female indicators in education, health, and nutrition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Providing credit directly to women has a positive effect on  household and individual welfare and improved gender equality.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Social norms affecting decisions within the family about occupational choices or migration can also lead to differential patterns of male and female earnings in informal markets (Bhiswanger and Rosenzweig 1984). Family responsibilities hinder women's geographic mobility, constraining their ability to command high wages and limiting them to certain areas or industries. The concentration of women in certain sectors, especially nontraded goods and set-vices. intensifies competition between women entrepreneurs and wage workers and lowers the returns to female labor. These effects are compounded by women's lack of access to credit. training, and technology.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">(fender Inequality in Access to Assets and Services )</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Access to Financial Markets</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The availability of financial services and access to them are considered important for several reasons. First. savings provide a kind of self-insurance. Second, credit helps households maintain a certain level of consumption at those times when their income fluctuates temporarily. Third, credit can be used to fund investments in capital or other inputs that will yield relatively high returns to production. if households cannot finance such investments from their own savings. A fourth and no less important reason is the role of savings and credit in increasing household members' options outside the home.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Inequalities between women and men in access to financial services- particularly credit--are widely documented. Collateral requirements, high transaction costs. limited mobility and education, and other social and cultural barriers contribute to women's inability to obtain credit (Holt and Ribe 1991). The implications tot household efficiency and individual well-being differ, however, depending on whether the household pools its financial resources. If, as the unitary household model assumes. a household pools its resources the characteristics of individual borrowers are less important than if there is little or no pooling. In the first case. credit resources will be used to meet household needs that have been jointly determined, regardless of who the borrower is. In the second case, the use credit is put to and the needs it then satisfies depend on which household member is borrowing.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A recent study of credit programs in Bangladesh sponsored by the World Bank shows that providing credit directly to women has a positive effect on variables typically associated with household and individual welfare and improved gender equality (Pitt and Khandker 1995). The study looks at three programs in Bangladesh: the Grameen Bank. the Bangladesh Rural Advancement Committee (BRAC), and the Bangladesh Rural Development Board (BRDB). in 1992, women accounted for 94 percent of Grameen Bank members. 82 percent of BRAC members. and 68 percent of BRDB members (Khandker and Khalily 1995; Khandker, Lavy, and Filmer 1994). Only the results for the Grameen Bank are presented here.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Table 2.4 presents the impact of credit obtained by women and men on a variety of social and economic indicators. The results show a clear and positive impact of both male and female borrowing on all indicators of Toward gender equality family welfare especially through an increase in per capita expenditures increases in both boys' and girls schooling, anti a reduction in fertility. Females borrowing has a greater effect on girls' schooling anti per capita expenditure than does male loot-rowing: male borrowing has a greater effect on boys' schooling and fertility than does female borrowing. Interestingly. female borrowing also results in mote female ownership of nonoland assets and an increased supply of female labor to cash - income -earning activities (Pitt and Khandker 1995).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Loans to Women and Men Have Important Welfare Implications.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="JUSTIFY">Table 2 4 welfare effects of Grameen Bank loans (percentage increase)</P>
+</B><P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=545>
+<TR><TD WIDTH="47%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Welfare e change</B></FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Effect of male borrowing</B></FONT></TD>
+<TD WIDTH="26%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Effect female borrowing</B></FONT></TD>
+</TR>
+<TR><TD WIDTH="47%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Increase in boys' schooling</FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">7.2</FONT></TD>
+<TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">6.1</FONT></TD>
+</TR>
+<TR><TD WIDTH="47%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Increase in girls schooling</FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">3.0</FONT></TD>
+<TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">4.7</FONT></TD>
+</TR>
+<TR><TD WIDTH="47%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Increase in per capital expenditure</FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">1.8</FONT></TD>
+<TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">4.3</FONT></TD>
+</TR>
+<TR><TD WIDTH="47%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Reduction in recent fertility</FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">7.4</FONT></TD>
+<TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">3.5</FONT></TD>
+</TR>
+<TR><TD WIDTH="47%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Increase in women's labor supply to cash-income earning activities</FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">0</FONT></TD>
+<TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">10.4</FONT></TD>
+</TR>
+<TR><TD WIDTH="47%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Increase in women nonland assents</FONT></TD>
+<TD WIDTH="28%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">0</FONT></TD>
+<TD WIDTH="26%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">19.9 </FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The introduction of programs such as the Grameen Bank in a village has a positive effect on agricultural and nonagricultural production (Khatidketati Chowdhuty 1994: Rahman and Khandke 1994 The probability that women will be self-employed rather than work for wages increases by 52 percent. The latter finding is important because much of the wage employment open to women in rural areas is very poorly remunerated and can be quite exploitative. Self employment can bring the opportunity of higher returns for women, plus the freedom to integrate their earning activities into other work as they see fit.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Access to financial services alone cannot reduce gender inequalities in the allocation of household resources. A qualitative study reviewing several targeted credit programs in Bangladesh cautions against overgeneralizing about the benefits of giving women access to credit. The study finds that it is difficult to infer that increased borrowing alone improves women's bargaining power because in many rural Bangladesh households the question of who controls the resources is quite complex (Goetz and Sen Gupta 1994). Nevertheless. the possibility of receiving credit (or similarly of working for wages) may give women greater bargaining power within the household. This bargaining power can be used to improve child health and nutrition and may increase the likelihood that children will attend school.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Access to Lund and Property</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The ownership of land and the distributions of land rights influence the productivity of labor and capital resources and the incentive to invest in resource management Private property rights. in particular. are associated with increased access to product and factor markets. especially credit markets. and to public services such as public utilities and agricultural extension. However. relatively little direct evidence exists to link independent owner of land by women with increased access and productivity. One obstacle to empirical work is that women s access to land and property is often mediated trough marriage (A married woman land rights are frequently limited to use rather than ownership.) Future more. complex systems of land tenure make it difficult to generalize about the effects of owner ship on productivity. None some evidence suggests that independent land rights for women could enhance both the efficiency with which resources are used and the well-being of women and their households: (Agarwal 1994).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The possibility of receiving credit may give e women   greater bargaining power within the  household which  can be used to improve child health and nutrition.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">While independent land rights may increase efficiency and household welfare, lack of secure land  appears to be associated with low investments by women in land conservation. In Zimbabwe's communal areas, land that a women acquires is often allocated to her only temporarily: for example, the location of land allotment received from husbands or borrowed from neighbors is usually subject to periodic change (Jackson 1993). The same is true in parts of West Africa (David 1992 Jackson 1994). Uncertainly about the permanence of their control over the land means that women may be reluctant to invest in improvements that will benefit the landowner rather than the user.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A significant trend in recent decades in developing countries has been the move toward private ownership In some countries this trend has been encoulagecl by reforms dealing with land redistribution tenancy or land titling Such reforms are considered important for promoting long-term investments and the adoption of the latest technology They also provide the collateral people need to gain access to credit and other factor markets Ironically, evidence also suggests that perform inequalities in male and female land rights are reinforced by land reform programs For example, in Latin America most reforms are based on the premise that the man of the household its the household head. This presumption means that women (except for widows  and ownership. Even where women and men benefit equally from land reform differences exist between nominal and real land rights (see box 2.3).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the central part of European Russia and in Moldova the lands and assets of state and collective farms are being parceled out in allotments as part of wider economic reforms. Every person who lived and worked on a collective farm receives a share of the land Data show that although on average, women have received a slightly higher proportion of land shares than men, the nonland capital assets of the old farms ale being distributed as property shares on the basis of a formula heavily weighted toward an individual's wage rate and years of employment. Such criteria favor men over women and give men more valuable property chares. Dividends paid on these property shares also tend to be higher than those paid 011 land shares Holt 1995).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Land reform programs that fail to account for gender differences in rights</P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=590>
+<TR><TD VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Box 2.3 who gets access to land? Honduras and Cameroon</P>
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Honduras' Agrarian Modernization Law of 1974 includes a provision giving men age 16 or older the right to access to land, independent of any other qualification. For women. however, this right is restricted to unmarried mothers or widows with dependent children. Furthermore. if a male beneficiary dies or becomes incapacitated. the law gives preference in inheritance rights to a male child over the child's legally married mother. Some 30 percent of rural Honduran households are headed by women at least part time because of the seasonal migration of men to look for work (Saito and Spurling 1992). </FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the northwest and southwest provinces of Cameroon. an estimated 50 percent or more of those who claimed land within the first ten years of land registration (1974-85) were classified as public servants. Over 32 percent of all the remaining land titles went to businesses.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Women make up more than 51 percent of Cameroon s population and do more than 75 percent of the agricultural work. but they are virtually absent from land registers. Only 3.2 percent of all land titles issued in the Northwest Province were given to women; in the Southwest Province the figure was 7.2 percent. For the country as a whole. it is estimated that women obtained under 10 percent of all land certificates (World Bank 1995a).  to own. use, and transfer land may actually exacerbate the insecurity of women's land claims and. as a result, harm household welfare. For example, there is evidence that land titling focused on male household heads has adversely affected women's ability to farm independently. Moreover. intrahousehold inequalities in income and decisionmaking have increased (FAO 1993) In Africa some titling programs have allowed men to take advantage of their control over land to redesignate land formerly cultivated by women as household land. This switch provided the opportunity for men to increase the amount of work they expect from women on household plots. In other cases women have received smaller and less fertile plots than they had before for their personal crops (FAO 1993).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Recognizing women's independent claims to land is therefore an important issue in property reform. In poor households. having rights to land could alleviate both women's own poverty and the household's risk of remaining poor. The season is mainly that women s access to economic resources has a positive effect on household welfare (Agarwal 1994). From the point of view of efficiency, secret land tenure increases the incentive to manage resources efficiently and expands access to formal credit markets. Because secure land tenure can mean greater productivity, it may also increase the household's incentives to invest in women's human capital.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Access to Extension Services</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agricultural extension services provide information training and technology to agricultural producers. Extension services have always been regarded as necessary for agricultural modernization. Given the importance of women's labor to agriculture in most regions, providing women with access to agricultural extension services is essential for current and future productivity. Types of agricultural extension services vary, hut in most countries publicly provided services dominate. Evidence suggests that women have not benefited as much as men have from publicly provided extension services.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Given the importance of women's labor to agriculture it is in most regions providing women with access to agricultural extension services is essential for current  and future of productivity.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A review of five African countries shows that extension agents are most likely to visit male farmers than female farmers (table 2.5) The impact of this inequity on female productivity depends in part on whether women and men within households pool information. There is, however. little evidence to suggest that this happens (see box 2.4). It is important to ensure that extension services reach omen directly, not only to redress gender inequalities but also to maximize productive efficiency. omen play a critical role in production of food and cash crops for the household. in postharvest activities. and in livestock care Men and omen perform different tasks they can substitute for one another only to a limited extent. and this imitation creates different demands for extension information Also, as men leave farms in search of paid employment ill urban areas. women are increasingly managing and operating farms on a regular and full-time basis. Hence. omen are becoming a constituency for extension and research services in their own right (World Bank 1994e)</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="JUSTIFY">Table 2.5 visits by agricultural extension agents (percentage of households visited)</P>
+</B><P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=439>
+<TR><TD WIDTH="37%" VALIGN="TOP" COLSPAN=2>
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Country and year</B></FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Households with female head</B></FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Households with male head</B></FONT></TD>
+</TR>
+<TR><TD WIDTH="37%" VALIGN="TOP" COLSPAN=2>
+<FONT SIZE=2><P ALIGN="JUSTIFY">Kenya. 1989</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">112</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">9</FONT></TD>
+</TR>
+<TR><TD WIDTH="37%" VALIGN="TOP" COLSPAN=2>
+<FONT SIZE=2><P ALIGN="JUSTIFY">Malawi, 1989</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">70</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">58</FONT></TD>
+</TR>
+<TR><TD WIDTH="37%" VALIGN="TOP" COLSPAN=2>
+<FONT SIZE=2><P ALIGN="JUSTIFY">Nigeria 1989</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">37</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">22</FONT></TD>
+</TR>
+<TR><TD WIDTH="37%" VALIGN="TOP" COLSPAN=2>
+<FONT SIZE=2><P ALIGN="JUSTIFY">Tanzania, 1984</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">40</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">20</FONT></TD>
+</TR>
+<TR><TD WIDTH="37%" VALIGN="TOP" COLSPAN=2>
+<FONT SIZE=2><P ALIGN="JUSTIFY">Zambia</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">&nbsp;</TD>
+<TD WIDTH="32%" VALIGN="TOP">&nbsp;</TD>
+</TR>
+<TR><TD WIDTH="4%" VALIGN="TOP">&nbsp;</TD>
+<TD WIDTH="33%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">1982</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">57</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">29</FONT></TD>
+</TR>
+<TR><TD WIDTH="4%" VALIGN="TOP">&nbsp;</TD>
+<TD WIDTH="33%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">1986</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">60</FONT></TD>
+<TD WIDTH="32%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">19</FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P></FONT>
+<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=590>
+<TR><TD VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Box 2.4 do women farmers learn from their husbands?</P>
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A survey of women farmers in Burkina Faso found that 40 percent had some knowledge of modern crop and livestock production technologies. For most of these women, relatives and friends were the source of information; nearly one-third had acquired their knowledge from the extension service, and only 1 percent had heard of the technologies from their husbands.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Men are less likely to pass information on to their wives when crops and tasks are gender specific. In Malawi women claimed that their husbands rarely passed on advice to them: if their husbands did tell them something. the women did not find it relevant to their needs. In India women learned from friends, relatives. neighbors. and sometimes from their husbands. but this second-hand information seldom changed their production patterns (Saito and Spurling 1992). </FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The expansion of agricultural services beyond the public sector is a growing phenomenon in developing economies. The inadequacies of public funding plus the need to provide snore client-oriented services, suggest that the private sector has an important role to play However, women's limited access to land and credit put the many potential benefits offered by extension services out of reach. For example in Kenya's Meru and Maranga areas more than half the women surveyed cited a shortage of cash as their reason for not adopting, technologies that would maximize their output and increase their efficiency. The amount of education omen receive and the efficiency with which they run their farms are also closely linked This tie is particularly significant in light of the fact that one purpose of extension services is to advise farmers on use of modern technology.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Three studies of Kenya found that the gender of the farm manager was, by itself. an insignification factor in output per hectare but that the manager's educational level had a significant effect on farm productivity (Moock 1976: Saito and Spurling 1992: Bindlish and Evenson 1993). Simulations based on these studies suggest that significant gains could accrue to increased investment in women's physical and human capital. As the data in table 2.6 show, if women and men shared the same educational characteristics and input levels. farm-specific yields would increase between 7 and 22 percent. Giving women primary schooling, by itself. would increase yields by 24 percent. Thus under investment in women's education limits growth of agricultural productivity. Well-targeted extension services can help to narrow the differences in productivity that arise from educational inequalities (Schultz 1988)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Increasing Human Capital and Input Levels Would Increase tile Yield for Women Farmers.</P>
+<P ALIGN="JUSTIFY"></P>
+<B><P ALIGN="JUSTIFY">Table 2.6 effects of increasing women farmers' human capital and input levels Increase  yields</P>
+</B><P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=590>
+<TR><TD WIDTH="82%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Policy experiment </B></FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">(percent)</B></FONT></TD>
+</TR>
+<TR><TD WIDTH="82%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Maize farmers Kenya, 1976</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">&nbsp;</TD>
+</TR>
+<TR><TD WIDTH="82%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Effects of giving female farmers sample mean characteristics and input levels</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">7</FONT></TD>
+</TR>
+<TR><TD WIDTH="82%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Effects of giving female farmer s men's education and input levels</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">9</FONT></TD>
+</TR>
+<TR><TD WIDTH="82%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Effects of giving women primary schooling</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">24</FONT></TD>
+</TR>
+<TR><TD WIDTH="82%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Food maize (maize beans and cow pears) farmers</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">&nbsp;</TD>
+</TR>
+<TR><TD WIDTH="82%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Effects of giving female farmer men's education and input levels</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">2.0</FONT></TD>
+</TR>
+<TR><TD WIDTH="82%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Effects of increasing land area to male farmers' levels</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">10.5</FONT></TD>
+</TR>
+<TR><TD WIDTH="82%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">Effects of increasing fertilizer to male farmers' levels</FONT></TD>
+<TD WIDTH="18%" VALIGN="TOP">
+<FONT SIZE=2><P ALIGN="JUSTIFY">1.6</FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Conclusion</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Analysts must look beyond market outcomes to identity the sources of persistent inequality between women and men. The search must focus on the household and its role in the formation of present and future human capital and on institutions beyond the household that reinforce and perpetuate gender inequalities. Gender inequalities within the household affect market outcomes, and these feed back; into household decisionmaking. This process is reinforced by inequalities in access to assets and services beyond the household. Improving the relative status of women within the household and increasing their access to assets and services will increase the returns to investment in human resources and improve the prospects for sustainable economic growth.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">We must look for that which we have been trained not to see  Ann Scales, Yale Law Journal 1986</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Chapter three</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<B><P></P>
+<!--
+<Section>
+  <Description>
+    <Metadata name="Title">Public Policies Matter</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As CHAPTER 2 has shown underivesting in girls and women is inefficient for society as a whole. Correcting for past underinvestment will require a "genders" approach to public policy. How this can be concretely achieved is the topic of this chapter.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Equalizing Opportunities by Modifying, the Legal Framework</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Laws form tile functional framework of the economy and of civil society. Equality in the legal treatment of men and women creates the legitimacy policymakers need to seek change. Legal and regulatory provisions that discriminate against women-that. for example bar married women from seeking employment or prevent women from holding legal title to land-perpetuate gender inequalities and severely restrict women's ability to participate fully in social and economic development.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Modifying the legal framework to  eliminate discrimination and equalize opportunities for women and men is an important goal for public policy at the national and international levels. A supportive legal environment is also vital for other aspects of public policy that have a direct bearing on the opportunities available to women. such as regulations affecting the formal and informal sectors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Four areas of the law are particularly important for equalizing the opportunities available to men and women: land and property rights; labor market policies and employment law: family law: and financial laws and regulations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Land and Property Rights</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Policymakers should ensure that women and men are treated equally in the public allocation of land. Eligibility for land reform programs, for example. should not discriminate against women's perform claims whether the women are heads of households or members of households headed by men. When communities have been resettled or when a project allocates land to participating producers, women should have the same rights to land as men For refugee and displaced women returning to their homelands. often as de facto heads of households. need fair and equal treatment to allow them to establish a Farming or enterprise base as soon as possible. Whet-e land is in short supply, it may be necessary to recognize the land rights of certain groups, as well as their individual rights. The Indian National Sericulture Project is an example; it has leased land to women's groups and promoted women's access to land under state land-grant schemes (Quisumbilig 1994).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Some countries have enacted legislation to ensure gender equality in property and contractual rights. Under China's Law of Succession, for example males and females have equal rights to inheritance. Complementary measures are needed to ensure that women know their rights. Such measures include legal programs and campaigns to make judges and administrators sensitive to gender issues in the area of property rights (see box 2.1)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Labor Market Policies and Employment Law</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Discriminatory labor market policies and employment laws are widespread: examples are bans on hiring married women and restrictions on the type of work pregnant women may pet-form. Labor laws may also restrict female participation in jobs and deny women access to work settings. Even legislation that seeks to promote equal opportunity can have outcomes tot women workers. For example, generous maternity and child-care benefits tot women workers may make hiring women relatively mote costly than hiring men. perpetuating the gender wage gap.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The main issue for public policy its to ensure that fair and equal employment laws exist and are enforced.</P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=590>
+<TR><TD VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Box 3.1 some NGO efforts to promote women's legal literacy</P>
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Schuler and Kadirgamar - Rajasingham (1992) describe innovative approaches by  non governmental organizations to provide women with useful legal knowledge and tools.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Caribbean Association for Feminist Research and Action (CAFRA) has launched "women and the law" projects in five English-speaking Caribbean countries. Using a participatory methodology. the projects aim to create awareness of the law. provide women with legal information that will be useful to them in their daily lives, identify specific areas for action, and influence overall legislative policy. The projects develop educational materials for legal literacy and offer topic specific paralegal training for women's organizations.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The legal literacy program of the Ugandan Women Lawyers' Association (FDA-Uganda) conducts legal literacy campaigns on specified dates each month in different districts. Pairs of FIDA volunteers conduct sessions, using role playing and discussions, on legal topics of relevance to women's lives and provide advice on contacting the FIDA legal clinic for advice and representation. In addition, FIDA and Action for Development broadcast regular radio and television programs on women and the law and publish pamphlets on legal issues of interest to women. </FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In India the Self - Employed Women's Association (SEWA) holds worker education meetings to provide members with legal information and offers one day training sessions on specialized legal information for community leaders. Members of SEWA paralegal staff research cases, prepare briefs, and argue all cases in labor courts for members. SEWA'S legal literacy efforts are part of its overall strategy of action for supporting self-employed women and women in the informal sector.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In this regard. the main issue for public policy is to ensure that fair and equal employment laws exist and are enforced. Such laws should cover employment and employment-related benefits and should not be applied in a way that restricts women's access to the labor market.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In many countries women are protected by special standards in the workplace. These safeguards are of two types. The first includes measures intended to end discrimination in the labor market by requiring equal pay for work of equal value or by prohibiting the exclusion of workers from certain jobs because of gender. The second type protects women in their role as mottles by requiring employers to pay the full cost of maternity leave and provide childcare facilities. restricting night work, and limiting work categorized as dangerous or hazardous.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The first type of labor standard is often difficult to enforce. although nearly 120 countries have enacted equal opportunity laws. In most cases the law is in place but is not enforced. Furthermore. it often applies only to the formal sector of the labor market. leaving large number of women in the informal sector with little protection. More concerted public and private action is required to devise appropriate for enforcement. In additions complementary measures are needed to increase womens chances of entering the labor force. Such measures would include mote met-it-based hiring of women in the public sector and the creation of an appropriate regulatory framework that encourages the establishment of day-care centers private nursery schools. and kindergartens for the children of workers in both the formal and informal sectors. (Box 3.2 describes a day-care projects in Bolivia)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many countries have laws that limit night work. over theme and the use of heavy machinery by women. While well intentioned. these laws. too. can reduce women's employment options by raising the employer's cost of hiring women and perpetuating the notion that women workers are less flexible than male workers. This adverse result occurs because women already tend to have lower levels of capital than men and are limited by traditional notions of what womens work. Devising effective protective legislation for women is thus a difficult balancing act.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Effective laws to protect women must honor the fine line between ensuring sate working conditions for all workers, including women in the informal sector. and providing equal opportunities for all workers seeking employment. Standards relating to maternity leave and child-care benefits are common in the formal sector. To ensure that such standards do not raise the costs of female labor unnecessarily employment legislation should avoid having employers pay benefits directly. Maternity benefits should be funded through general revenue taxes</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Box 3.2 day-care center in Bolivia to enhance the status of women by increasing their employment opportunities in other Latin American countries, and their knowledge of women in Bolivia are over represented , health, and nutrition. The project among the poor, and many live in will establish day-care centers to proficult circumstances. They are twice vice non formal,  home-based, integrals likely as men to be illiterate, their child development for children unaccess to child care is limited, they the age of 6 in thirty-four poor subject to discrimination in hiring ban and purebred areas. Women and wages, and they are restricted benefit from the project either as by law from engaging in certain procure givers employed at the minimum ductive activities. wage or as clients of the centers. The Integrated Child Development children in day care gives women Project, financed by a credit from the more time to search for jobs or to in World Bank's International Development their current situations (Winkler opponent Association designed and Guedes 1995).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Or social security systems rather than by direct contributions from individual employers. In Eastern Europe and Latin America, however, this method of funding benefits has imposed a significant cost on the treasury, raising the question of how much should be paid and for how long.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">One way of addressing this issue is for governments to encourage women and men to share the responsibility for childrearing by adopting legislation allowing either parent to qualify for the leave and benefits associated with having a child (Folbre 1994). Such legislation can be supported by changes in the tax system to ensure equal treatment of workers within the household and a margin tax rate on the earnings of additional workers in the household low enough to avoid creating a disincentive to women's participation in the labor force (Mac Donald 1994). These tax changes can be complemented by legislation that encourages absent to pay child support. Such laws are in place in many Latin American and Caribbean countries. but none systematically monitors transfers (Folbre 1994). Greater efforts to enforce the law are needed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Family Law</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gender inequality in family law can worsen women's bargaining position within and outside the household and affect household welfare and efficiency. As noted in chapter women's bargaining position in relation to Household resource allocation is often a key factor in determining the wellbeing of household members. particularly children. Reforms of family law can enhance women's economic and social opportunities while still respecting cultural norms. For instance the minim age of marriage for women  should be set high enough so that girls can complete secondary schooling: this would help lower fertility rates. (Allowing for exceptions such as parent consent negates the potential fertility benefit.) Marriage contracts should include stipulations guaranteeing the wife's rights. especially on separation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Women's bargaining position in relation to household</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Legal and policy measures can have a direct bearing on the health of women. The law and its enforcement are essential for combating domestic violence against women. If the laws on violence against women are to be enforced, women need to be made aware of the legal recourse available to them and the judiciary and police need to be sensitized to the existence and</P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=590>
+<TR><TD VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Box 3.3 innovative approaches to combating gender violence</P>
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Brazil's women-only police stations are an innovative approach to the problem of violence against women. They have been so successful that other countries-including Argentina, Colombia, Costa Rica, India, Peru, and Uruguay-have emulated them. The police stations have made it easier for women to report gender based crimes of violence, and, with that experience, women are now demanding more support from the police, such as legal counseling and advice. Despite the program's success, the number of convictions for gender-based crimes has not increased, largely because similar innovations have not been made in the  judicial system (Heise, Pitanguy, and Germain 1994). </FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Zimbabwe the Mussasa project provides support and counseling to abused women and sensitizes police and prosecutors to the issues of domestic violence and rape. To ensure the credibility and acceptability of the training, legal professionals are involved in the program. One branch of the criminal justice system-the police department, for example-often hosts training for another, such as prosecutors (Stewart 1992).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Costa Rica El Instituto Legal de las Naciones Unidas y Desarrollo runs gender sensitization training for prosecutors, judges, lawyers, and other professionals who deal with crimes of violence against women (Heise, Pitanguy, and Germain 1994).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Implication of violence against women. Affirmative action policies can increase the number of women police officers lawyers, and judges. Trading police, lawyers, and judges can increase their gender sensitivity. making the legal system more responsive to women's needs. Legal literacy efforts can make women aware of their rights and show them how to use these rights to mobilize for change. Some approaches to dealing with domestic violence are illustrated in box 3.3</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Financial Laws and Regulations</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Access to credit is vital for women, allowing them to manage fluctuations in income and expenditures and to expand their businesses. As we saw in the preceding chapters, credit can be an important source of economic empowerment for women within the household. But in many countries. underdeveloped financial markets, controlled interest rates, and overly rigid backings regulations have led to systems of credit that tend to shut out the pool. many of whom are women If financial institutions are to lend to those unable to obtain credit in the current environment. interest rates must be liberalized. Positive interest rates have important effects on informational money markets, which tend to be more exploitative when formal sector credit is rationed.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Changes in the laws governing access to credit are also vital because women's business profiles often differ from men's. Compared with men. women are more likely to work in low-risk small, and home-based businesses (Rhyne and Holt 1994). This situation creates a demand for small loans that can be obtained without formal, legally secured collateral and that offer relatively flexible repayment terms. Legislation that encourages broad access to financial institutions can increase the availability of these types of loans. but legal changes may also be needed to extend the range of acceptable collateral.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In many countries the regulatory framework contains provisions that are especially punitive to small firms. This adds an additional constraint on women, whose businesses are concentrated at the small end of the size The deregulation of the microentreprise sector would remove implicit disincentives to small-film activity and would relieve some of these Such action would enhance women entrepreneurs' prospects of benefiting from training or credit programs targeted to the microentreprise sector (World Bank 1994d. 1995c).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Redirecting Public Policies and Expenditure to Promote (tender Equality)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is unlikely that legal reform by itself will be sufficient to ensure that women and men ate treated equally. Further public action may be required to guarantee that gentler-neutral laws are enforced at both national and local levels.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Macroeconomic: Policies</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Many developing countries are implementing important policy and institutional reforms to address changing economic conditions on both the domestic and international fronts. These reforms are often supported by international financial institutions and bilateral donors. The pace of reform has varied across countries Those countries that have implemented reforms early on, carried them out consistently, and received adequate financial support have generally enjoyed faster and stronger economic growth than count ties that have undertaken reforms too slowly, too intermittently, or not at all. Where implementation has been slow or the government's commitment weak, economic distortions have tended to multiply and economic trowels to slow. limiting the government's ability to invest in physical and human capital for the future.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is often the poorest groups in society that stand to lose the most from economic distortions. High and rising inflation places a disproportionate tax burden on the poor including low-paid wage workers and those with fixed incomes. For this and other reasons, inflation tends to hit women harder than men. An overvalued currency is also regressive; it keeps the price of goods artificially low. crowding out many locally produced goods. Women's businesses. which ate often concentrated in the informal sector, can be particularly vulnerable to competitions from cheap snorts. An overvalued currency reduces international competitiveness. limiting the availability of foreign exchange for domestic entrepreneurs and constraining business expansion and employment creation. A firm commitment to policy refortify is therefore essential to economic growth and sustainable initiatives for alleviating poverty.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Inflation tends to hit women harder than men.</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Such reforms generally include two kinds of necessary policies. The first emphasizes macroeconomic stability and the removal of price distortions: the second promotes labor-demanding growth in agriculture and industry and better. mote accessible basic social services. mightily in education, health care and water supply. Macroeconomic stability can be achieved by reducing large current account and government budget deficits and by curtailing excessive money and credit expansion. Correct pricing of foreign exchange and of domestic goods and services facilitates trade and investment and promotes growth Reforms of trade and price incentives encourage job creation and higher earnings.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In shots. broadly based economic reforms benefit the poor, as the experiences of diverse countries have shown. Data from the LSMS and similar studies confirm that in Costa Rica, Ethiopia. Than Indonesia, Peru, the Philippines, and Tanzania, declines in poverty rates have accompanied economic reforms. Because of underlying gender inequalities, reductions in poverty do not necessarily improve the economic status of women. Nonetheless. although empirical evidence on changes in women's welfare following reforms is scarce, data from the Philippines suggest that for women. economic reform is by improvements in social indicators and important employment gains (box 3.4). An analysis of household data from Peru indicates that reforms there have not only led to renewed growth and reduced poverty but have also improved the status of female-headed households (box 3.5).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Despite their seminal role in encouraging sustainable. long-term growth. some economic reforms involve transitional costs. for two reasons: the need to implement radical shifts in government policy, and the lag. perhaps of years, between acceleration of economic growth and the realization of the 
+</P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=590>
+<TR><TD VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Box 3.4 social progress and labor force gains for women in the Philippines</P>
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The Philippines began implementing economic reforms in the early 1980s. While political turmoil and some policy slippage have weakened GDP growth over the period and led to the need for further reforms, quality of life indicators have improved during adjustment. For example, by 1990 the incidence of absolute poverty had declined by about one-third (to approximately 20 percent of the population). Maternal and infant mortality rates also declined over the period: in 1980 the infant mortality rate was 52 per 1,000 live births, but by 1990 it had fallen to 41 per 1,000 births (Johansen 1993). </FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The percentage of the population with access to safe drinking water increased between 1980 and 1990, from 65 to 93 percent of the urban population and from 43 to 72 percent of the rural population. The figures for sanitation services showed the same increase, climbing from 81 percent with access in 1980 to 98 per  cent in 1990 among urban dwellers and from 67 to 85 percent among those in rural areas. Secondary school enrollment rates for boys and girls also showed gains. Girls and boys have traditionally reached similar educational levels in the Philippines, a trend that contributed to women's gains in the labor market during adjustment in the 1980s. While labor force participation rates for men rose only slightly, the rates for women increased dramatically, from 23 to 37 percent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">At the same time, women's wages as a percentage of men's grew from 71 to 80 percent between 1978 and 1988 (Tzannatos 1995). A recent study of a low-income community in Manila found that in some private sector jobs women earn more than men, reflecting in part the high educational level among women in the sector. Earnings in the informal sector are generally low for both women and men. although some women have been so successful in their informal sector businesses that their spouses have opted to leave low-paying jobs in the formal sector to participate in their wives enterprises (Moser 1994).  benefits of growth by large segments of the population. The short-term costs can include increases in food prices as subsidies are removed temporary restrictions on credit to control monetary expansion, and cuts in public spending as governments attempt to control budget deficits and reorient spending toward the most important public services. Moreover, inequalities in access to and control over resources and in entry into markets hamper some groups in taking advantage of the opportunities created by economic reform For example, people who are unable to acquire new skills may remain for some thee. Gender inequalities in access to and control over land in rural areas can keep women farmers from taking advantage of changes in the relative prices of tradable and non tradable crops.</P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=590>
+<TR><TD VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Box 3.5 macroeconomic reform and improved living standards in Peru</P>
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Between 1985 and 1990 Peru's economic regime was marked by expansionary monetary and fiscal policies and high levels of government intervention in most areas of the economy. Although these policies led to an initial period of growth, the approach proved unsustainable: by late 1987 growth had given way to hyperinflation and deep recession. During 1988-90 real GDP dropped by an average of 8 percent a year. Real wages and consumption expenditure also fell sharply as inflation soared to 7,600 percent a year in 1990.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In 1990 the new government of President Alberto Fujimori introduced macroeconomic reform measures designed to stabilize the economy, reduce fiscal deficits and inflation, increase market efficiency, and improve the country's competitiveness. Under this reform program inflation declined dramatically, falling to 57 percent in 1992 and to 17 percent in 1994. Real GDP grew by about 20 percent between 1991 and 1994, while real per capita consumption expenditure grew by more than 18.5 percent. LSMS data show that poverty declined by 11 percent-from 55 percent of the population in 1991 to 49 percent in 1994. Although the country experienced a brief contractionary period following the introduction of reform measures, household data from Lima for 1990, 1991, and 1994 indicate that in 1994 per capita expenditure was well above, and the incidence of poverty well below, 1990 levels. </FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Improvements in living standards have been widespread, and the largest gains have been made in some of the country's poorest regions, such as the urban and rural sierra (mountain areas). In most parts of the country, increases in per capita expenditure among households headed by women have been above the national average. In the urban and rural sierra, for example. consumption expenditure by these households increased by 47.7 and 44.8 percent. respectively-figures that compare favorably with increases in per capita expenditure among households headed by men (35 and 28 percent for the same regions).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although both women and men are expected to gain from economic reform in the long run. gender inequalities at the household and market levels can mean that the benefits of reform reach women, especially poor women. only slowly. Reforms must incorporate measures aimed at counter acting shot-term transitional costs. Among the most important are safety nets specifically targeted to vulnerable groups. For example, in fiscal 1994 seventeen of the twenty-three reform programs supported by the World Bank included components aimed specifically at reducing poverty: fourteen of them targeted programs or safety net measures such as labor-intensive public works projects. targeted and social assistance programs, and unemployment and social security schemes (see box 3.6).</P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=590>
+<TR><TD VALIGN="TOP">
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Box 3.6 food coupons improve nutrition in Honduras</P>
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The food coupon program in Honduras, part of a social safety net supported by the World Bank and financed by IDA and other donors, was put in place in 1990 to protect the country's most vulnerable people during economic reforms. Starting with about 182,000 participants, by 1994 the program had expanded its coverage to 345.000 of the estimated 430,000 children at risk of malnutrition. The effort also supports nutrition education for health workers, community groups, and mothers. Because coupons are used instead of food. the government saves some 30 percent over traditional food distribution costs, and the beneficiaries are able to choose the food  they will consume. Beginning in 1995, an adjustment for inflation will maintain the value of the coupons, enabling participants to satisfy a constant proportion of their food needs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The project also supports the development and implementation of a long-term nutrition assistance strategy for Honduras. Although attempting to measure changes in malnutrition is difficult in the short term, there have already been noticeable benefits. Between 1990 and 1993 the number of first-graders with severe or moderate malnutrition dropped by 4 percent. Organizers are now trying to graduate women participants from the program by offering training in basic skills such as food processing and helping them find assembly work in local factories (World Bank 1995b). </FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However, safety nets are not a substitute for a mote integrated approach to economic and social policy that includes appropriate levels of harvest in social services and infrastructure. Recognizing this fact, governments and donors are increasingly incorporating into their reform packages antipoverty initiatives and measures to reduce gender inequality. In Pakistan, for example, the FIDA-financed Public Sector Adjustment. Program provides much needed the financial support for the balance of payments account and reinforces the emphasis on government investment in the social sectors. The program promotes increased access to and improvements in basic education. health. and water supply services that benefit girls and rural areas. It also supports a shift it government education and health spending toward the primary level.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">In fiscal 1994 twelve of twenty-three World Bank economic reform pro emphasized the restructuring public expenditure, primarily to and increase spending on education. health care, and other areas important to poverty reduction such as water supply and sanitation. The Burkina Faso reform program is typical; it supports an increase in the total budgeted amounts for primary education and health services, which are particularly beneficial to the poor and to women. Uganda s program seeks to protect and enhance public expenditures for basic social services. including water supply primary health care and primary education. In the long term, the reform of public spending-especially in the social sectors, physical infrastructure and agricultural research and extension-promises significant benefits) trot women.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Sectoral Investments</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In principle. public expenditures on social services and infrastructure are allocated on a gender-neutral basis; in practice men and women use these services differently. The resulting inequalities frequently perpetuate gender based differences in the accumulation and distribution of human capital within households. Public policy can address this problem by public expenditure priorities between secrets and within social sectors. Further it can support services and types of infrastructure that provide the highest social returns to public spending and are most heavily used by women  and children.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">EDUCATION. Estimations of the private returns to education for a number of countries (Psachatopoulos 1994) show that returns are at least equal for girls anti boys and are often higher for girls. Moreover, these rates do not capture the externalities generated by providing education to girls. The combination of private and social returns provides a clear signal for restructuring the allocations of public resources so as to support female education. Yet incidence analysis for a number of countries for which the necessary data are available reveals that educational subsidies per capita are higher for males than for females This difference is partly a result of the bias in allocation of subsidies toward higher levels of education, where female enrolled is lowest. Distortions in the allocation of public resources, such as the provision of mote money foe male-dominated tertiary institutions than for education that benefits girls, should be corrected by reallocating spending toward basic (primary and lower-secondary) schooling. Targeting these educational levels will have the maximum effect on girls' education and will yield higher social returns for society as a whole. In countries where universal basic education has been achieved and capital markets are unable to help households finance higher education, continuing subsidize higher education may be warranted. The rationale for the subsidy would be the productivity gains associated with a better-trained labor force.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">To correct the bias against enrollment of girls more targeted interventions are need to influence household (see decisionmaking)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">However reallocating public spending toward primary education and later toward higher levels is not sufficient to erase the gender gap in education The bias against enrolling girls in school is evident in both poor and no poor households and applies even at the primary level. To correct this bias, more targeted interventions are needed to influence household decision making</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">HEALTH. Correcting the gender bias in the public financing of health care IS a more complex process than correcting the bias in education. for two main reasons: the marked differences between the health needs of men and women, and the unreliability of household data on demand for health services in comparison with the data on demand tot education). However it is cleat that targeting health services to women implies provision of adequate funding for prenatal care. infant immunization, and mother and child health services. Because of the significant social benefits of providing women with appropriate health care, governments should make basic services ices that benefit women a top priority among, public health care expenditures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There is a critical link between the public provision of health care and women's access to educational opportunities. A mother educated to seek preventive care and early treatment of illness for herself and her children (particularly girls) will reduce the cost of health care and in many cases. prevent premature death. Most of these highly cost-effective services can be supplied in rural clinics and health centers. Public spending should be so allocated as to ensure sufficient funding for these primary health facilities.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">AGRICULTURAL EXTENSION SERVICES. Agricultural extension and research services are widely considered vital to increasing and sustaining agricultural productivity. Many of these services are being provided by the private sector. but in some countries private services need public support, either because certain markets have not yet been developed or because the infrastructure is poorly developed. However. women farmers and small holders are often not served as effectively by public agricultural extension systems as ate and male farmers (FAO 1993). This disparity stems paltry from expend priorities within agricultural extension services. which concentrate resources on the crops and the technology controlled primarily by male commercial farmers. Reallocating public spending on agricultural extension and research services toward crops and technology raised by or used by small holders and women farmers could yield high social returns to public investment and could increase private returns by improving the skills and productivity of small agricultural producers.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Reallocating public spending on agricultural extension  and research services toward crops and technology </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Techniques for small holders and women farmers should take into account the need for quality and cost-effectiveness in public services, Economies of scale can be achieved if extension agents deal with groups of farmers instead of with individuals. This approach also provides a valuable forum for exchanging information. fostering peer learning. sharing expensive equipment. and pooling resources for- credit. Mobile trailing units and flexible hours that fit the crowded schedules of women farmers should also be considered. and more female extension agents should be trained to deal directly with female farmers. Such measures can be introduced without large additional resources if existing expenditures are carefully reallocated.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">INFRASTRUCTURE, Public investment in economic and social infrastructure is vital in facilitated individual and household investment in physical and human capital. However, public expenditures on roads, water supply, and sanitation infrastructure frequently do not meet the needs of those who use the services most heavily. Women are the main users of water services, and it is essential to involve them in designing and implementing water projects. For example. in areas where transport is inadequate and water collection is a daily burden for women and children, the population tends to use the closest available facility rather than the safest one. In such cases. projects that ensure a safe water supply and take into account the specific needs and constraints of the users often have a significant effect on users' health. In two villages in Zaire where a piped water network was installed to provide safe drinking water, the median incidence of diarrhea was halved among children in households located less than a five-minute walk from a public standpipe. Spending allocations that favor public water supply and sanitation improve the general health of the population, save time for women and children. and increase school attendance. A study from Morocco chows that access to tap and well water instead of pond or river water raised school enrollment for both boys and girls (Khandker, Lavy, and Filer 1994).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Women are the main users of water services and it is essential  to involve them in designing and implementing water projects.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Public spending on roads and energy-related facilities (for instance electrification or energy conservation) or other infrastructure is usually assumed to be gander neutral. Yet women and men use these facilities differently The Morocco study cited above found that the availability of electricity increased the rate for girls substantially more than for boys. The study also showed that the presence of a paved road increased by 40 percent the probability that girls would attend school and reduced by 5 percent their probability of dropping out. Overall, improved road conditions increased the probability of school attendance for girls by 32 percent and for boys by 20 percent.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rural electrification can also ease the time constraints on women who must balance household and productive work. Lack of time is often a primary season for women's weak response to economic incentives. especially in rural areas. The case for making public investments in infrastructure would be stronger if gender differences in the use of projects and services, as well as the potential effect of such investment on productivity and social development. were taken into account.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Using Targeting Measures to Narrow the Gender</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">As we have seen. policies that specifically target women or girls can address the needs or this group more efficiently and with greater cost-effectiveness than general policy measures. Female household members tend to allocate resources more directly to children. while men tend to allocate more resources to adults. In households in which resources are not pooled. targeting programs to the household as a where will not necessarily benefit all members equally.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Targeting women directly is justifiable on two grounds. First, to the extent that gender inequalities prevent an economy from realizing its full potential. targeting to women can be an effective strategy for increasing productivity and output Second, where gender differences are wide, targeting may be needed to capture social gains and to increase internal efficiency.</P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=1 CELLPADDING=7>
+<TR><TD></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY">Targeting women is especially when doing so contributes directly to reducing poverty; or when women have particular needs-for example. when maternal mortality is very high. The exceptionally high gender gap in educational enrollments in some countries can be reduced only by policies (including subsidies) that target girls. An obvious example would be policies that affect the private costs of schooling. </P>
+<P ALIGN="JUSTIFY">Female household members tend to allocate resources more  directly to children it while men</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Reducing these direct costs to households Will mean setting new public spending priorities. For example. education institutions for girls especially at the primary level, might be exempted from cost recovery measures. thus increasing the implied public spending subsidy to girls. Similarly. a far; number of publicly funded scholarships can be provided for girls' as has been done in and Guatemala.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Opportunity and travel costs can discourage parents from enrolling especially daughters in school. Some counties have tried to overcome the constraints imposed by opportunity costs by introducing flexible school hours and calendar years and providing child care for younger siblings (box 3.7). In some cases girls who are responsible for looking after their younger brothels and sisters ate allowed to bring them to school.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In countries where cultural values may prevent girls from traveling alone to school. measures are needed that will increase access to safe transport.</P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<TABLE BORDER CELLSPACING=1 CELLPADDING=7>
+<TR><TD>
+<B><FONT SIZE=2><P ALIGN="JUSTIFY">Box 3.8 economic reforms and gender targeting in Mongolia</P>
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Since Mongolia began its transition to a market economy in 1990, the living conditions of the population have deteriorated dramatically. According to the government's estimates, a quarter of all Mongolians are now living below the poverty line. Single women with young children are among the "new" vulnerable groups that have emerged in the wake of the transition. As of December 1993 nearly 72 percent of households headed by single persons, usually women, were estimated to have incomes below the poverty line. (About 28 percent of all households in Mongolia are headed by women). The Mongolian Women's Federation reports that the divorce rate is rising among jobless low-income couples, increasing the number of single-parent households. </FONT></TD>
+</TR>
+</TABLE>
+
+<FONT SIZE=2><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Along with job loss women are affected by the decline in services such as day care and maternity homes.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mothers now have to look after their children at home, which restricts their ability to participate in the labor market and, ironically, increases their dependence on welfare. When herds were privatized, priority was given to people who, according to the government, could take better care of the animals. Unfortunately, this policy adversely affected female-headed households.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The maternal mortality rate has doubled over the past three years. in part because many more babies are being delivered at home. Other factors that have contributed to the rising maternal mortality rate include a decrease in the number of ambulances and the need for patients to pay for the food they consume while they are hospitalized.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In Mongolia, targeting female-headed households, pregnant women, and children is essential for reducing poverty. Social assistance, health care. education, and help in finding employment are particularly important (Subbarao and Ezemenari forthcoming).  change the geographic distribution of primary schools, of provide more boarding facilities. Projects in Pakistan are using school mapping techniques to establish criteria for placing new schools in currently underserved areas. Such programs benefit both girls and boys.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It may be necessary to target women when economic reforms of systemic transitions are occurring. For example, in Mongolia, as well as in other countries making the transition from a socialist to a market economy, women are disproportionately represented among the unemployed and otherwise disadvantaged (box 3.8). Thus, in designing safety nets to mitigate the short negative effects or economic transitions. policymakers need to recognize and evaluate the specific adverse effects on women</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">It is not always necessary to restrict a particular program of benefit exclusively to women: the objective can sometimes be achieved indirectly.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Techniques based on self-selection appear to be particularly efficient. In Zambia. where men have a strong preference for cash wages, offering wages in kind (food) attracted more women workers than men to public works programs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the financial sector. women entrepreneurs are enabled to borrow at market rates of interest when banking institutions adopt innovate collateral requirements, reduce transaction costs, and offer small loans at repeated intervals The Grameen Bank in Bangladesh and Badan Kredit Kecaman in Indonesia do not reserve loans for women specifically: instead. they adopt innovative lending policies the result of which is that women snake up the majority of participants-is 96 percent in a new branch of the Grameen Bank.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Involving Beneficiaries in Public Policy</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Until recently. the absence of input from beneficiaries often let's ignorant about how the costs and benefits of policy changes would be distributed among the population Today the views and needs of potential beneficiaries are being taken into account at both the macroeconomic and sectoral levels. This trend should make it possible to determine who benefits. who does not, and why. A good example of a situation in which a beneficiary's point of view can make a significant difference is in public expenditure reviews. Governments with unsustainable budget deficits must make difficult decisions about the allocation of public resources. Their task can of ten be facilitated by suggestions from the potential beneficiaries themselves, since one of the key questions policymakers face is whether investments as presently allocated are reaching the intended populations efficiently and effectively</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Three broad approaches can be used to guarantee that the views of women and other intended beneficiaries are adequately reflected in policy and project formulation. First. surveys and other methods of collecting statistical data can be designed to ensure that gender-desegregated data are properly collected and analyzed. Second, beneficiary assessments, which use a range of qualitative research methods such as direct observation. selected individual of group interviews. and case studies. can be used to ensure that the views of all groups are adequately represented.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A third approach involves a range of participatory planning and management techniques that reflect a significant transfer of control to the community and local levels. Participatory evaluations use innovative research that allow illiterate and otherwise voiceless groups to express their concerns and priorities. Small grants and credits managed at the local level by NGOs or governments agencies permit a community to choose the projects that best reflect its OWN priorities. Social funds. whereby resources are channeled to demand-driven projects, are one such mechanism While these participatory approaches have been implemented primarily at the local level, they are also beginning to be used to involve the community in regional and national planning. Participatory methods, by helping to create local capacity. ensure the sustainability of projects and programs. They also help establish rational criteria for making public investment choices that incorporate both social and efficiency objectives.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Generating and Analyzing Gender-Desegregated Data</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gender-desegregated data and the capacity to analyze these data provide public policymakers with essential information and enhance the dialogue with agents outside government. One of the most valuable instruments for collecting desegregated data is the household survey. which can provide detailed information that is invaluable in policymaking. Obtaining full gender information in many instances entails only a small increase in costs. since the desegregation itself involves little extra work. However additional resources ate often needed to analyze the data and make it useful to policymakers. Public statistical agencies might analyze gender-desegregated information in partnership with private and academic institutions in order to share the costs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">There are several important steps in collecting useful and accurate data. First. in places where gender -desegregated household data have not yet been collected. special efforts should be made to obtain them. At a minimum data on how individuals use health and educational services should be collected routinely as part of national consumption and expenditure surveys. If household consumption. income or production surveys have already been carried out but little or no gender--desegregated data have been collected, the marginal cost of collection is likely to be quite modest-perhaps on the order of 10 percent of total costs.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Participatory methods help establish rational criteria  for making public investment choose that incorporate  both social and efficiency objectives. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Second. in places where basic gender-desegregated data have already been collected, it is important to gather more data from individuals on consumption and. as much as possible. on income and the ownership of assets. Such data ate vital for developing a deeper understanding of how access to and allocation and control of resources are determined within households. More data on men's and women's access to credit and information services, such as agricultural extension programs, are needed for an understanding of women's limited access to important production inputs. The data also indicate the effectiveness of projects and programs in providing such services to women.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Third, there should be an increased emphasis on collecting panel data (thee series) to facilitate snore detailed analyses of changes in household behavior over time. Because full panel surveys are costly, it may be necessary to adopt less-expensive panel methods and combine them with flexible data collection. Anthropological and participatory research methods can be used to enhance the quality and relevance of formal survey questions, as well as to provide a "reality check" on formal survey responses.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Finally, greater priority needs to be given to gender-disaggregated analysis of existing data sets. This analysis should be carried out not only in social sectors such as health and education but also on such issues as the intrahousehold allocation of time and labor and access to and use of productive resources.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Working in Collaboration</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Governments' ability to identify and implement policies that promote gender equality is greatly enhanced by the active participation of other players from the development community and civil society. These agents include individual women and men, community-based groups, private-for-profit firms, trade unions, non governmental organizations, and multilateral and bilateral agencies. Interaction between public institutions and other actors provides the basis for a more informed policy dialogue on gender issues. It also lays the foundation for operational collaboration and for broadly based support for public policy measures.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Over the past several decades NGOs have become major players in international development. NGOs are by no means homogenous. In the field of development, they range from large volunteer and charity organizations, many of them based in industrial countries, to community-based self-help groups. They also include research institutes, volunteer-sending agencies, religious organizations, professional associations, and lobbying groups.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">NGOs concerned with gender issues have had a particularly important role in designing and implementing gender programs, especially at the grassroots level, and in advocating policy change at the national level NGOs have been effective in providing information and education to women and in helping community-based women's organizations lobby for change. In many countries collaboration between NGOs and governments is still relatively new. Nonetheless, it is growing rapidly-most visibly in the delivery of social and financial services.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">For example, in Peru a proposed basic health and nutrition project aims to improve the quality and accessibility of health and nutritional services, with an emphasis on poor women and children. NGOs are expected to play a major role in implementing the project and will be responsible for 75 percent of training and research, 40 percent of education, and 20 percent of service delivery (World Bank 1994g). In Africa many HIV/AIDS support programs are managed by NGOs with assistance from governments and funds from international donors.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the long run choices made by private sector agents are profoundly important for the persistence  or reduction of gender inequalities </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">In the financial services sector NGOs have found innovative ways of overcoming barriers that women face in access to credit and savings facilities. Among the better-know programs are the Grameen Bank in Bangladesh, ACCION International in Latin America, and the NGO consortium ACCORD in Africa. NGOs have been very successful in organizing village banks and mobile banking systems to reach the rural poor. These credit programs provide women not only with the funds to finance income-generating activities but also with opportunities to acquire basic business skills and to assume leadership positions within their peer groups.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Governments also seek to collaborate with a range of institutions from the private sector. In the long run the choices made by private sector agents- whether households, firms, or trade unions-are profoundly important for the persistence or seduction of gender inequalities. Joint public-private sector initiatives can be vital in changing peoples perceptions about the benefits of investing in or hiring women. The private sector has a comparative advantage in providing certain kinds of services to women-for example, vocational education and training. Collaboration with the private sector- often means that public resources can be reallocated to those investments that offer the highest rate of social return. such as basic education and health care.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Strengthening International Policies to Meet New Challenges</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Not all issues that bear on gender equality can be effectively addressed by individual nations. For example, refugee and displaced women and children account for up to 80 percent of the 50 million refugees and displaced persons worldwide. The sheer numbers of refugee and displaced women and children highlight the urgent need to devise international strategies for dealing with this problem.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The sheer numbers of refugee and displaced women and  children (estimated at 4 million) </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The constraints that refugee and displaced women lace are similar to those faced by other women, only magnified many times. They lack access to health services, even though their health risks are high. Girls often have less access to basic education than in their home countries. With little access to family planning, women s fertility rates may be extraordinarily high at a time when the burden of additional children hinders the chances of survival for both mothers and infants. In the absence of professional abortion services, women may rely on self-induced and unsafe abortions. The proportion of female-headed households is highest in refugee situations, yet the women's income-generating activities and skills are minimal</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">The international response to this type of crisis is usually limited to emergency relief measures. Although vital, these measures often fail to recognize the long-term economic and social costs involved in restructuring the lives of displaced women when they return to their home countries. International public policy has an important role in preparing refugee and displaced women for their future role in rebuilding their societies. Long-term repatriation and development on a regional basis along the lines of the International Conference on Central American Refugees (CIREFCA) in Central America is one approach to involving governments, NGOs and development agencies in a coordinated response to refugee problems. Governments and agencies must make every effort to collaborate in making repatriation viable by establishing development programs that explicitly take account of refugees' needs. Otherwise, chances are high that people will once again be forced to leave their countries. putting at risk national reconciliation efforts.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Another area that demands an international response is the establishment of legal conventions for the enforcement of social justice and human rights. Equality under the law creates the legitimacy policymakers and private individuals need to seek change that will increase well-being and encourage economic opportunity. In certain instances, legitimacy needs to be established at the international level. For this reason it is vitally important that governments ratify the Convention on the Elimination of All Forms of Discrimination against Women. This convention. adopted by the United Nations General Assembly in 1979, provides a framework for action by countries to reduce discrimination against women in political and public life, law and education, employment, health care. commerce. and domestic relations. International conventions of this type provide an important policy lever for women's organizations and other groups in civil society.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Conclusions</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This chapter has presented the rationale for public interventions to promote gender equality. Such interventions are needed because of market failures and social externalities that extend beyond the individual household to affect society in general. For resources to be allocated efficiently, public spending should focus on those investments with the highest social returns. Given the evidence of high social and private returns to investments in women's human capital, public expenditures should give priority to the investments that have the largest impact on the welfare of girls and women, especially in basic education and reproductive and other health care services. Policymakers also need to identify areas in which actions can be taken that would have gender neutral outcomes, including sectoral programs addressing transport and infrastructure, water supply. and sanitation</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">BY directing  public resource toward policies and projects  that reduce gender inequality policy markers are promoting  not only equality today but also higher labor productivity </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Governments can no longer afford not to invest in women. The evidence on private and social returns to investments in women and girls cannot be ignored. By directing public resources toward policies and projects that reduce gender inequality, policy makers are promoted not only equality today but also higher labor productivity, a higher rate of human capital formation, slower population growth. and stronger economic growth tomorrows However, none of these goals can be reached without the participation of women  themselves. Governments and collaborating institutions must listen carefully to the voices of individual women, to women s groups, and to woman policymakers By working with others to identify and implement policies for greater gander equality, governments can take actions that will make a real difference to the future well-being and prosperity of their people.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">Notes</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">1. Birdsall and Sabot (1994) use earlier findings by Barro (1991) to test the relationship between inequality and growth. They find that in Latin America unequal distribution of education. in terms of both quality and quantity, constrained economic growth in the region by reducing opportunities for increasing labor productivity. In East Asia open and relatively equal access to high-quality basic education led to a virtuous circle of high educational performance that stimulated growth and reduced inequality</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">2. Subbarao and Raney (1993) estimate that a doubling of family planning services in 1982 would have reduced the fertility rate from 5.5 to 5 0 and the number of births by 3.5 percent</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">3. The Living Standards Measurement Study (LSMS) is a series of multitopic surveys designed to study multiple aspects of household welfare</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">4. Deforestation is represented by the time required to collect a standard load of fuelwood</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">5. It would be more illuminating to compare wage differences across three categories of women workers: women without children: women with children but with no interruption in employment except for statutory maternity leave: and women with children and with interrupted employment</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">6. Among women workers. 53 percent are in commerce. compared with 33 percent of men. In manufacturing. 16 percent of the workers are men. compared with 14 percent for women. In services, 37 percent are men anti 33 percent are women (World Bank 1995c)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">7. In Bolivia informal moneylenders require borrowers to write postdated checks. If borrowers tail to make timely repayments, these checks are deposited and, as the lender knows will bounce for lack of funds A bounced check is a criminal offense in Bolivia. and the lender can have the borrower arrested The World Bank estimates that about 20 percent of all Bolivian prison inmates-and 40 percent of female inmates imprisoned for 'bouncing' checks and for other collateral-related crimes. In many cases children must live in prison with their mothers (winkler and Guedes, 1995)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">8. The International Conference on Central American Refugees (CIREECA) was held in Guatemala City in May 1989 A total of 126 projects in seven countries were introduced. with an overall investment of $365 million Areas with high densities of returnees were targeted. and special attention was given to projects to support displaced women</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<B><P ALIGN="CENTER"></P>
+<!--
+</Section>
+<Section>
+  <Description>
+    <Metadata name="Title">References</Metadata>
+  </Description>
+-->
+</B><P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agarwal. Bina. 1994. "Gender and Command Over Property: A Critical Gap in Economic Analysis and Policy in South Asia." World/Development 22(10) 22(10): 145578.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Baden. Sally. 1993. "The Impact of Recession and Structural Adjustment on Women's Work in Developing and Developed Countries." Working paper. International Labour Office. Geneva</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bardhan, Kalpana 1993. "Women and Rural Poverty: Some Asian Cases" In M G Quibria, ea., Rural Poverty in Asia Priority Issues and Policy Options. New York: Oxford University Press.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bardhan, Pranab. 1988. "Sex Disparity in Child Survival in Rural India In T. Srinivasan and Pranab Bardhan. eds., Rural Poverty in South Asia. New York: Columbia University Press.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Barro. Robert 1991 "Economic Growth in a Cross-section of Countries' Journal of Economics 106 (May):407 43.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Beneria. Lourdes. 1992. 'Accounting for Women's Work: The Progress of Two Decades.'' World Id Development 20(11): 1547-60.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bindlish. Vishva. and Robert Evenson. 1993. Evaluation of the Performance of T and V Extension it? Kenya. World Bank Technical Paper 208. Washington. D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Binswanger. Hans, and Mark R. Rosenzweig, eds. 1984 Contractual Arrangements Employment and Wages in Rural Labor Markets m Asia. New Haven. Conn.: Yale University Press.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Birdsall, Nancy, and Richard Sabot 1994 ''Inequality as a Constraint on Growth Working Paper. Manila: Asian Development Bank.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Blau. Francine. and Lawrence N. Kahn. 1992 " The Gender Earnings Gap: Learning from International Comparisons" America Economic Review 82 (2):533-38.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Bouis Howarth E., and Eileen T. Kennedy. 1989. "Traditional Cash Crop Schemes' Effects on Production, Consumption and Nutrition: Sugarcane in the Philippines and Kenya." Prepared for IFPRI-INCAP Policy Workshop. Antigua. Guatemala</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Chatterjee. Meera 1991. Indication Women Their Health and Productivity World Bank Discussion Paper 109. Washington. D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">David, Rosalind 1992 The Effects of Male Out-migration on Women's Management of the Natural Resource Base of the Sahel. SOs International, London.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Donors to African Education. 1994. A Statistical Profile of Education in Sub Saharan Africa in the 1980s. Paris.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Duraiswamy. P. 1992. "Child Survival. Preventive Health Care and Schooling in Rural Households of Tamil Nadu: India." Yale University, New Haven, Conn.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Edgerton, V. R. G. W Gardner, Y Ohira. K. A Gunarwardena, and B. Senewiratne 1979 'lron Deficiency Anaemia and Its Effects on Worker Productivity and Activity Patterns' British Medical Journal 2:1546-49.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Einhorn. Barbara. 1993 Citizenship. Gender and Women's Movements in East Cent/al Europe London: Verso</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">FAO (Food and Agriculture Organization) 1993 Rural Poverty Alleviation Polices and Trends Economic and Social Development Paper 113 Rome</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fields, Gary S. 1992 ''Changing Poverty and Inequality in Latin America" Public Finance 47 (Supplement): 59-76.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Folbre. Nancy. 1994. Who Pays for the Kids:' Gender and the Structures of Constraint. London: Routledge</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Fong, Monica 1993. The Role of Women in Rebuilding the Russian Economy. Studies of Economics in Transformation 10 Washington, D.C.: World Bank.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Goetz. Anne Marie. and Rina Sen Gupta. 1994 'Who Takes the Credit'? Gender. Power and Control over Loan Use in Rural Credit Programmes in Bangladesh." Draft University of Sussex, Institute of Development Studies. Brighton, U.K.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hart, Gillian 1986 Power Labor and Livelihood: Processes of Change in Rural Java San Francisco: University of Berkeley Press.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Heise, Lori. 1993 ''Violence Against Women: The Missing Agenda." In Marge Koblinsky. Judith Timyan. and Jill Gay. eds.. The Health of Women A Global</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Perspective Boulder. Colo: Westview</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Heise. Lori. Jacqueline Pitanguy, and Adrienne German. 1994 Violence Against Women The Hidden Health Burden World Bank Discussion Paper 255. Washington, D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Herz, Barbara. and Shahidur Khandker. 1991 Women Work Education and Welfare in Peru. World Bank Discussion Paper 116. Washington. D C</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Herz Barbara, K Subbarao, Masooma Habib. and Laura Raney 1991 Letting Girls Lea/n. Promising Education. World Bank Discussion Paper 1. Washington, D C</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hoddinot, John, and Lawrence Haddad 1992. Does Female Income Insentience Household Expenditures  Evidence from C&ocirc;te d'Ivoire Trinity College. Oxford University, Oxford. U K</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Holt, Sharon. 1995 Gender and Property Rights: Women and Agrarian Reform in Russia and Moldova.' World Bank, Europe and Central Asia Region, Washington, D C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">&nbsp;</P>
+<P ALIGN="JUSTIFY">Horton, Susan 1994. "Women and Industrialization in Asia" University of Toronto. Institute for Policy Analysis</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Hosken, Fran P., ed 1992. Women's International Network News 18(4).</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">ILO/INSTRAW. 1985. Women in Economic Activity: A Global Statistical Survey 1950-2000 Geneva</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jackson. Cecile 1993 "Doing What Comes Naturally? Women and Environment in Development." World Development 21 (12): 1947-63.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Johansen. Frida 1993 Poverty Reduction in East Asia. World Bank Discussion Paper 203. Washington. D C</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Jurisman. Clara, and Araceli Moreno. 1990. ''Women, Labour and Crisis: Mexico." Prepared for International Center for Research on Women (ICRW) project on Weathering Economic Crises: Women's Economic Responses to Recession in Latin America and the Caribbean. ICRW, Washington. D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kalima Rose. 1992. Where Women are Leaders The Sewa Movement in India. London Zed Press</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Khandker. Shahidur R. and Osman H. Chowdhury 1994 "Targeted Credit Programs and Rural Poverty in Bangladesh." World Bank, Education and Social Policy Department. Washington, D.C. and Bangladesh Institute of Development Studies, Dhaka.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Khandker, Shahidur R. and Baqui Khalily. 1995. "Designing a Sustainable Poverty Alleviation Program: The BRAC Strategy in Bangladesh." World Bank, Education and Social Policy Department. Washington, D.C., and Bangladesh Institute of Development Studies, Dhaka</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Khandker, Shahidur R. Baqui Khalily. and Zahed Khan 1993 ''Sustainability of Grameen Bank: What Do We Know ? World Bank. Education and Social Policy Department. Washington. D C, and Bangladesh Institute of Development Studies, Dhaka</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Khandker, Shahidur R., Victor Lavy, and D Filmer. 1994. Schooling and Cognitive in World Bank Discussion Paper 264. Washington. </P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kumar, Shubh K. and David Hotchkiss. 1988 Consequences of Deforestation for Women's Time Allocation Agricultural Production and Nutrition in Hill Areas of Nepal International Food Policy Research Institute Research Report 69 Washington, D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Kuzoets. Simon. 1955 Economic Growth and Income Inequalities." American Economic Review 45 (March): 1-28.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Lavy, Victor. 1992. Investment in Human Capital Schooling Supply in Rural Ghana Living Standards Measurement Study Working Paper 93 Washington, D C: World Bank.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">MacDonald, Martha. 1994. 'Panel Presentation at the Gender Symposium" World Bank. Poverty and Social Policy Department, Washington. D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Manser Marilyn, and Murray Brown 1980 "Marriage and Household Decision making: A Bargaining Analysis " International Economic Review 21:11 44</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">McElroy, Marjorie, and Mary Jean Homey. 1981. "Nash-bargained Household Decisions: Towards a Generalisation of the Theory of Demand" International</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Economic Review 22 (June):333 49</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moock, Peter R 1976 "The Efficiency of Women as Farm Managers: Kenya." American an Journal of Agricultural Economic 58(5):831-35.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Moser, Caroline O. 1992 "Adjustment from Below: Low-income Women, Time and the Triple Role in Guayaquil. Ecuador" In Haleh Ashar and Carolynne Dennis, eds., Women and Adjustment Policies in the Third World. New York: St. Martin Press</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">1994. "Urban Poverty and Social Policy in the Context of Adjustment" World Bank, Urban Development Division, Washington, D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Mwabu, Germano. 1994 "Household Composition and Expenditures on Human Capital Inputs in Kenya" Presented at Northeast Universities Development Conference, Economic Growth Center Yale University, New Haven, Conn</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Newell, Andrew and Barry Reilly 1994. "Pine Gender Wage Gap in Russia. ' World Bank, Europe and Central Asia Country Department 3, Washington. D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Pitt, Mark, and Shahidur Khandker. 1995 "Household and Intrahousehold Impacts of the Grameen Bank and Similar Targeted Credited Programs in Bangladesh " World Bank, Education and Social Policy Department, Washington. D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Population Reference Bureau 1994. The Wood'. Youth 1994 A Special Focus on Reproductive Health Washington. D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Psacharopoulos George 1994. "Returns to Investment in Education: A Global Up-date ' World Development 22(9):1325 43</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Psacharopoulos. George, and Zafiris Tzannatos. 1992 Women's Employment and PUN in Latin America Overview and Methodology. A World Bank Regional and Sectoral Study Washington, D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Agnes. 1994. ''Improving Women's Agricultural Productivity as Farmers and Workers." Education and Social Policy Department Discussion Paper 37. World Bank, Washington. D C</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rahrnan. Rushidan I. and Shahidur Khandker 1994 "Role of Targeted Credit Programs in Promoting Employment and Productivity of the Poor in Bangladesh." World Bank, Education and Social Policy Department. Washington, D.C. and Bangladesh Institute of Development Studies. Dhaka</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rhyne, Elisabeth. and Sharon Holt 1994 ''Women in Finance and Enterprise Development'' Education and Social Policy Department Discussion Paper 40. World Bank. Washington, D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Rosenzweig, Mark. and T. Paul Schultz. 1982 'Market Opportunities. Genetic Endowments, and Intrafamily Resource Distribution: Child Survival in Rural India'' American an Economic Review 72:4:803-15.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">. 1987. 'Fertility and Investments in Human Capital: Estimates of the Consequences of Imperfect Fertility Control in Malaysia.' Journal of Econometrics 36: 163-84</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Saito, Katrine, and Daphne Spurlirio 1992 Developing Agricultural Extension to/ Women Farmers World Bank Discussion Paper 156 Washington. D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Scales, Ann 1986 "The Emergence of Feminist Jurisprudence'' Yale Law Journal 95(7): 1373-1403.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Schuler, Margaret, ed. 1986 Empowerment and the Law Strategies of Third World Women  Washington, D.C.: OEF</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Schuler, Margaret. and Sakuntala Kadirgamar-Rajasingilam. eds 1992 Legal Literary. A TOOL for Women's Empowerment New York: United Nations Development Fund for Women (UNIFEM)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Schultz. T. Paul 1988 ''Education Investments and Returns'' In Hollis Chenery and T.R. Srinivasan. eds. Handbook of Development Economics Amsterdam: North land.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sedlacek, Guilhemie, Leah Gutierrez, and Amit Mohindra 1993. "Women in the Labor Market" World Bank. Education and Social Policy Department Washington, D C</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sen, Amartya 1990 'More Than One Hundred Million Women Are Missing: Women's Survival as a Development Problem." New York Review of Books (December 20):61-66.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Sivard, R L 1985. Women: A World Survey. Washington, D.C.: World Priorities</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Stewart, Sheelagh. 1992. ''Working the System: Sensitizing the Police to the Plight of Women " In Margaret Schuler. ed. Freedom from Violence e: Women Strategies from around the World. New York: United Nations Development Fund for Women (UNIFEM)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Subbarao Kalanidlli. and Kene l Ezemenari Forthcoming "Transition. Poverty and Social Assistance in Mongolia.'' World Bank. Education and Social Policy Department Washington, D C</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Subbarao Kalanidhi. and Laura Raney 1993 Social Gains from Female Education: A Cross-National Stud!. World Bank Discussion Paper 194. Washington! D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Summers, Lawrence H. 1994 Investing in All the People Education Women in Developing Countries ED' Seminar Paper 45 Washington, D.C: World Bank</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Thomas, Duncan 1990a "Household Resources and Child Health in Zimbabwe." Working Paper. Yale University, Economic Grow Center, New Haven, Conn.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">. 1990b Intrahousehold Resource Allocation: An Inferential Approach of Human Resources 25(4):635-64.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">. 1991 Gender Differences in household Resource Allocation. Living Standards Measurement Study Working Paper 79 Washington. D C: World Bank</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">. 1993. "The Distribution of Income and Expenditure within the Household." A Annals of Economics and Statistic 29: 109-35.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tibaijuka, Anna 1994 ''Cost of Differential Gender Roles in African Agriculture: A Case Study of Smallholder Banana-Coffee Fames in the Kagera Region, Tanzania." Journal of Agricultural Economics (U K) 45(1):69-81</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Toubia, Nahid 1993. Female Genital Mutilation: A Call for Global Action. New York: United Nations</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Tzannatos, Zafiris 1995. "Growths, Adjustment, and the Labor Market: Effects on Women Workers." World Bank, Poverty and Social Policy Department, Washington. D.C.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UNESCO (United Nations Educational, Scientific, and Cultural Organization). 1991. 1991. Paris</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">. 1993b Trends and Projections of Enrollment by Level of Education by Age and Sex, 1960-2025. Paris</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UNICEF (United Nations Children's Fund! 1993. The Progress of Nations. New York</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">UNIDO (United Nations Industrial Development Organization). 1993 11 Women in Manu</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Other Recent Development in Practice Books</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Priorities and Strategies for Education: A World Bank Review (also available in French and Spanish)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Better Urban Services: Finding the Right Incentives (also available in French and Spanish)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Strengthening the Effectiveness of Aid: Lessons for Donors</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Enriching Lives: Overcoming Vitamin and Mineral Malnutrition in Developing Countries (also available in French and Spanish)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">A New Agenda for Women's Health and Nutrition (also available in French)</P>
+<P ALIGN="JUSTIFY">Population and Development: Implications for the World Bank</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">East Asia's Trade and Investment: Regional and Global Gains from Liberalization</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Governance: The World Bank's Experience</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Higher Education: The Lessons of Experience (also available in French and Spanish)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Better Health in Africa: Experience and Lessons Learned (also available in French)</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Argentina's Privatization Program: Experience, Issues, and Lessons Sustaining Rapid Development in East Asia and the Pacific</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">THE WORLD BANK A partner in strengthening economies and expanding markets to improve the quality of life for people everywhere, especially the poorest</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Gender equality is not only a matter of social justice but also good economics. It is of foremost importance to women's wellbeing and development. Discrimination means losses in productivity and lower welfare of women, their families, and society at large.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">Although the gender gap is narrowing in education, health, and many other areas, women are still less educated than men, work more hours, and are paid less. The reasons why gender disparities persist are complex, having to do with social and institutional norms, relationships within households, and even lack of information about the benefits of educating and employing women. Despite the weight of social and cultural factors, public policy can influence women's status and well-being. Governments have a leading role in widening the opportunities available to women and extending the services that are vitally important to them.</P>
+<P ALIGN="JUSTIFY"></P>
+<P ALIGN="JUSTIFY">This report outlines what governments and development agencies can do to work toward greater gender equality- one of the best investments a society can make. Public policy can affect investments in health, education, and infrastructure through laws and regulations. It can also affect land ownership, financial services, and access to employment. Not least important, public  policies can affect macroeconomic performance and create a favorable climate for economic development.</P>
+<P ALIGN="JUSTIFY"></P></FONT>
+<!--
+</Section>
+</Section>
+-->
+</BODY>
+</HTML>
Index: /gsdl/stable/collect/demo/metadata/dls.mds
===================================================================
--- /gsdl/stable/collect/demo/metadata/dls.mds	(revision 20131)
+++ /gsdl/stable/collect/demo/metadata/dls.mds	(revision 20131)
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE MetadataSet SYSTEM "http://www.greenstone.org/dtd/MetadataSet/1.0/MetadataSet.dtd">
+<MetadataSet contact="nzdl.org" creator="New Zealand Digital Libraries Project: Greenstone" family="Development Library Subset" lastchanged="Tue Jun 04 10:35:30 2002 - jmt12 on blackbird" namespace="dls">
+    <Name language="en">Development Library Subset Example Metadata</Name>
+    <Description language="en">A metadata set file for use in The Gatherer, created from original metadata found within the Development Library Subset.</Description>
+    <Element name="Title">
+        <Attribute language="en" name="comment"/>
+        <Attribute language="en" name="definition">The title of this resource.</Attribute>
+        <Attribute language="en" name="identifier">Title</Attribute>
+        <Attribute name="version">1.0</Attribute>
+    </Element>
+    <Element name="Organization">
+        <Attribute language="en" name="comment"/>
+        <Attribute language="en" name="definition">The organization responsible for producing this resource.</Attribute>
+        <Attribute language="en" name="identifier">Organization</Attribute>
+        <Attribute name="version">1.0</Attribute>
+    </Element>
+    <Element name="Subject">
+        <Attribute language="en" name="comment">Currently uses a hierarchy.</Attribute>
+        <Attribute language="en" name="definition">The subject of this resource.</Attribute>
+        <Attribute language="en" name="identifier">Subject And Keywords</Attribute>
+        <Attribute name="version">1.0</Attribute>
+    </Element>
+    <Element name="Keyword">
+        <Attribute language="en" name="comment">Informal.</Attribute>
+        <Attribute language="en" name="definition">A more specific indication of what the resource can be used for.</Attribute>
+        <Attribute language="en" name="identifier">Keyword</Attribute>
+        <Attribute name="version">1.0</Attribute>
+    </Element>
+    <Element name="Language">
+        <Attribute language="en" name="comment"/>
+        <Attribute language="en" name="definition">The language of this resource.</Attribute>
+        <Attribute language="en" name="identifier">Language</Attribute>
+        <Attribute name="version">1.0</Attribute>
+    </Element>
+</MetadataSet>
Index: /gsdl/stable/collect/demo/metadata/ex.mds
===================================================================
--- /gsdl/stable/collect/demo/metadata/ex.mds	(revision 20131)
+++ /gsdl/stable/collect/demo/metadata/ex.mds	(revision 20131)
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE MetadataSet [
+
+  <!-- The outer tag of any metadata set. Contains some number of elements.             -->
+  <!-- @param contact     A contact address for the creator.                            -->
+  <!-- @param creator     The name of the entity resposibly for this set.               -->
+  <!-- @param family      The name of this sets family.                                 -->
+  <!-- @param lastchanged The full date, user name and machine name of the last editor. --> 
+  <!--   uses the form:                                                                 -->
+  <!--   Day Mon(th) dd hh:mm:ss yyyy '-' <username> on <machine>                       -->
+  <!-- @param namespace   The namespace of this metadata set.                           -->
+  <!ELEMENT MetadataSet ((Name|Description|Element)+)>
+  <!ATTLIST MetadataSet
+				contact     CDATA #REQUIRED
+				creator     CDATA #REQUIRED
+				description CDATA #REQUIRED
+            family      CDATA #REQUIRED
+				lastchanged CDATA #REQUIRED
+            name        CDATA #REQUIRED
+				namespace   CDATA #REQUIRED>
+
+  <!-- The name of a metadata set. Is language specific. -->
+  <!ELEMENT Name (#PCDATA)>
+  <!ATTLIST Name
+            language CDATA "en">
+
+  <!-- The description of a metadata set. Is language specific. -->
+  <!ELEMENT Description (#PCDATA)>
+  <!ATTLIST Description
+            language CDATA "en">
+
+  <!-- An element in the metadata set. -->
+  <!ELEMENT Element (Attribute*,OptionList?)>
+  <!ATTLIST Element
+            name       CDATA #REQUIRED
+				occurances CDATA "0">
+
+  <!-- Each element has several attribute children. -->
+  <!ELEMENT Attribute (#PCDATA)>
+  <!ATTLIST Attribute
+            name CDATA #REQUIRED>
+
+  <!-- For listing predefined values for this element. -->
+  <!ELEMENT OptionList (Value+)>
+  <!ATTLIST OptionList
+            restricted (true|false) "false">
+]>
+<MetadataSet contact="nzdl.org" creator="New Zealand Digital Libraries Project: Greenstone" family="Extracted Greenstone" lastchanged="Tue May 20 10:30:32 2003 - jmt12 on narya" namespace="ex">
+    <Name language="en">Extracted Greenstone Metadata 1.0</Name>
+    <Description language="en">This document is the reference description, version 1.0 of the automatically extracted Greenstone Metadata Element Set.</Description>
+    <Element name="Encoding">
+        <Attribute language="en" name="comment">Not always available.</Attribute>
+        <Attribute language="en" name="definition">The encoding of the imported document as extracted by Greenstone.</Attribute>
+        <Attribute language="en" name="identifier">Encoding</Attribute>
+    </Element>
+    <Element name="Language">
+        <Attribute language="en" name="comment">Not always available.</Attribute>
+        <Attribute language="en" name="definition">The language of the imported document as extracted by Greenstone.</Attribute>
+        <Attribute language="en" name="identifier">Language</Attribute>
+    </Element>
+    <Element name="Source">
+        <Attribute language="en" name="comment">Hidden in the Librarian Interface as it already shown by the various file trees.</Attribute>
+        <Attribute language="en" name="definition">The filename of the document imported by Greenstone.</Attribute>
+        <Attribute language="en" name="identifier">Source</Attribute>
+    </Element>
+    <Element name="Title">
+        <Attribute language="en" name="comment">Not always available.</Attribute>
+        <Attribute language="en" name="definition">The title of the imported document as extracted by Greenstone.</Attribute>
+        <Attribute language="en" name="identifier">Title</Attribute>
+    </Element>
+</MetadataSet>
Index: /gsdl/stable/collect/demo/metadata/profile.xml
===================================================================
--- /gsdl/stable/collect/demo/metadata/profile.xml	(revision 20131)
+++ /gsdl/stable/collect/demo/metadata/profile.xml	(revision 20131)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE Profiles [
+<!ELEMENT Profiles (Action*)>
+<!ELEMENT Action (#PCDATA)>
+<!ATTLIST Action
+                source     CDATA #REQUIRED
+                target     CDATA "">
+]>
+<Profiles/>
Index: /gsdl/stable/collect/modelcol/etc/collect.cfg
===================================================================
--- /gsdl/stable/collect/modelcol/etc/collect.cfg	(revision 20131)
+++ /gsdl/stable/collect/modelcol/etc/collect.cfg	(revision 20131)
@@ -0,0 +1,25 @@
+creator       **creator**
+maintainer    **maintainer**
+public        **public**
+
+buildtype	mgpp
+
+indexes		text dc.Title,Title Source
+defaultindex	text
+
+levels		document
+
+**plugins**
+
+classify       List -metadata dc.Title;Title -partition_type_within_level constant_size
+classify       List -metadata Source -partition_type_within_level constant_size
+
+collectionmeta collectionname    "**title**"
+collectionmeta iconcollection    ""
+collectionmeta collectionextra   "**about**"
+collectionmeta  .text "_labeltext_"
+collectionmeta	.dc.Title,Title "_labelTitle_"
+collectionmeta	.Source "_labelSource_"
+collectionmeta .document "_textdocument_"
+collectionmeta .section "_textsection_"
+
Index: /gsdl/stable/collect/modelcol/etc/collectionConfig.xml
===================================================================
--- /gsdl/stable/collect/modelcol/etc/collectionConfig.xml	(revision 20131)
+++ /gsdl/stable/collect/modelcol/etc/collectionConfig.xml	(revision 20131)
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CollectionConfig xmlns:gsf="http://www.greenstone.org/greenstone3/schema/ConfigFormat" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<OAI>
+    <ListMetadataFormats>
+     <!--What metadata sets to support is collection specific. To support other metadata schema, simply add a metadataFormat element here.
+         The support of unqualified Dublin Core metadata set is mendatory in the oai specification.
+     -->
+      <metadataFormat metadataPrefix="oai_dc">
+        <metadataPrefix>oai_dc</metadataPrefix>
+        <schema>http://www.openarchives.org/OAI/2.0/oai_dc.xsd</schema>
+        <metadataNamespace>http://www.openarchives.org/OAI/2.0/oai_dc/</metadataNamespace>
+        <!--<metadataElements>dc.Title,dc.Creator,dc.Subject,dc.Description,dc.Publisher,dc.Contributor,dc.Date,dc.Type,dc.Format,dc.Identifier,dc.Source,dc.Language,dc.Relation,dc.Coverage,dc.Rights</metadataElements>              
+        -->
+        <mappingList>
+        <!-- 
+        The mapping is in the form: <publicly supported metadata name>,<mapped metadata name>, short as <A>,<B> 
+        The first metadata name is medatory; if there is no mapped name followed, then the first name must be used by the records and
+        searchable in the database, otherwise it is the mapped name stored in the database. The number of mapping elements matches the
+        number of external metadata of the records. If only one name is present, the returned metadata will use this name plus the retrieved value;
+        if both <A>,<B> are present, the returned metadata will use <A>'s name plus <B>'s value retrieved from database.
+        
+        **Bear in mind: if this mapping list is not present, the standard dc. metadata names (15 in total) will be used to retrieve metadata in the database.
+          
+        **The only case when this mapping is not present is that: 1. this metadata format is oai_dc; 2. the metadata is also stored in the database by Dublin Core's names.
+        -->
+            <mapping>dc.Title,Title</mapping>
+            <!-- This mapping example means that the dc.Title is requested and the value of the metadata Title, which is used in this repository, is returned as response. -->
+        </mappingList>
+     </metadataFormat>
+    </ListMetadataFormats>
+</OAI>    
+    <metadataList>
+        <metadata lang="en" name="creator">**creator**</metadata>
+        <metadata lang="en" name="maintainer">**maintainer**</metadata>
+        <metadata lang="en" name="public">**public**</metadata>
+    </metadataList>
+    <displayItemList>
+        <displayItem assigned="true" lang="en" name="name">**title**</displayItem>
+        <displayItem assigned="true" lang="en" name="description">**about**</displayItem>
+    </displayItemList>
+    <search type="mgpp">
+        <level name="document">
+            <displayItem lang="en" name="name">document</displayItem>
+        </level>
+         <level name="section">
+            <displayItem lang="en" name="name">section</displayItem>
+        </level>
+       <defaultLevel name="document"/>
+        <index name="text">
+            <displayItem lang="en" name="name">text</displayItem>
+        </index>
+        <index name="Title">
+            <displayItem lang="en" name="name">titles</displayItem>
+        </index>
+        <index name="Source">
+            <displayItem lang="en" name="name">filenames</displayItem>
+        </index>
+        <defaultIndex name="text"/>
+        <format name="searchType">plain,form</format>
+        <format><gsf:template match="documentNode">
+                <td valign="top">
+   	           <gsf:link type="document">
+                    <gsf:icon type="document"/>
+                   </gsf:link>
+                </td>
+ 	        <td>
+            	  <gsf:switch>
+                     <gsf:metadata name="Title" select="ancestors" separator=": "/>
+   	             <gsf:when test="exists">
+                      <gsf:metadata name="Title" select="ancestors" separator=": "/>:
+                     </gsf:when>
+                  </gsf:switch>
+	          <gsf:link type="document">
+                  <gsf:metadata name="Title"/>
+                  </gsf:link>
+              </td>
+              </gsf:template>
+           </format>
+    </search>
+    <import>
+        <pluginList>
+            <plugin name="ZIPPlugin"/>
+            <plugin name="GreenstoneXMLPlugin"/>
+            <plugin name="TextPlugin"/>
+            <plugin name="HTMLPlugin"/>
+            <plugin name="EmailPlugin"/>
+            <plugin name="PDFPlugin"/>
+            <plugin name="RTFPlugin"/>
+            <plugin name="WordPlugin"/>
+            <plugin name="PostScriptPlugin"/>
+            <plugin name="PowerPointPlugin"/>
+            <plugin name="ExcelPlugin"/>
+            <plugin name="ImagePlugin"/>
+            <plugin name="ISISPlugin"/>
+            <plugin name="NulPlugin"/>
+	    <plugin name="OAIPlugin"/>
+            <plugin name="MetadataXMLPlugin"/>
+            <plugin name="ArchivesInfPlugin"/>
+            <plugin name="DirectoryPlugin"/>
+        </pluginList>
+    </import>
+    <browse>
+        <classifier name="List">
+          <option name="-metadata" value="dc.Title;Title"/>
+          <option name="-partition_type_within_level" value="constant_size"/>
+       </classifier>
+        <classifier name="List">
+          <option name="-metadata" value="Source"/>
+          <option name="-partition_type_within_level" value="constant_size"/>
+        </classifier>
+        <format>
+             <gsf:template match="documentNode">
+    	         <td valign="top">
+ 	            <gsf:link type="document">
+                       <gsf:icon type="document"/>
+                    </gsf:link>
+                 </td>
+	         <td valign="top">
+                    <gsf:metadata name="srclink"/>
+  	            <gsf:choose-metadata>
+                       <gsf:metadata name="thumbicon"/>
+                       <gsf:metadata name="srcicon"/>
+                   </gsf:choose-metadata>
+                   <gsf:metadata name="/srclink"/>
+                 </td>
+ 	         <td valign="top">
+  	            <gsf:choose-metadata>
+                      <gsf:metadata name="dc.Title"/>
+                      <gsf:metadata name="exp.Title"/>
+                      <gsf:metadata name="Title"/>
+   	              <gsf:default>Untitled</gsf:default>
+                   </gsf:choose-metadata>
+	        <gsf:switch>
+                   <gsf:metadata name="Source"/>
+           	     <gsf:when test="exists">
+                       <br/>
+                    	<i>(<gsf:metadata name="Source"/>)</i>
+                     </gsf:when>
+                </gsf:switch>
+                </td>
+             </gsf:template>
+	  <gsf:template match="classifierNode">
+    	      <td valign="top">
+	           <gsf:link type="classifier">
+                   <gsf:icon type="classifier"/>
+                   </gsf:link>
+              </td>
+ 	      <td valign="top">
+             <gsf:metadata name="srclink"/>
+ 	     <gsf:choose-metadata>
+               <gsf:metadata name="thumbicon"/>
+               <gsf:metadata name="srcicon"/>
+               </gsf:choose-metadata>
+             <gsf:metadata name="/srclink"/>
+              </td>
+	     <td valign="top">
+	        <gsf:choose-metadata>
+                <gsf:metadata name="dc.Title"/>
+                <gsf:metadata name="exp.Title"/>
+                <gsf:metadata name="Title"/>
+	        <gsf:default>Untitled</gsf:default>
+             </gsf:choose-metadata>
+ 	     <gsf:switch>
+                 <gsf:metadata name="Source"/>
+          	    <gsf:when test="exists">
+                    <br/><i>(<gsf:metadata name="Source"/>)</i>
+                 </gsf:when>
+             </gsf:switch>
+             </td>
+             </gsf:template>
+	     <gsf:template match="classifierNode" mode="horizontal">
+      	          <gsf:link type="horizontal">
+                  <gsf:metadata name="Title"/>
+                  </gsf:link>
+              </gsf:template>
+        </format>
+    </browse>
+    <display>
+        <format>
+      <gsf:option name="TOC" value="false"/>
+        </format>
+    </display>
+    <replaceListRef id="gs2-standard"/>
+</CollectionConfig>
Index: /gsdl/stable/collect/modelcol/etc/group.cfg
===================================================================
--- /gsdl/stable/collect/modelcol/etc/group.cfg	(revision 20131)
+++ /gsdl/stable/collect/modelcol/etc/group.cfg	(revision 20131)
@@ -0,0 +1,9 @@
+creator       **creator**
+maintainer    **maintainer**
+public        **public**
+collectgroup  true
+
+
+collectionmeta collectionname    "**title**"
+collectionmeta iconcollection    ""
+collectionmeta collectionextra   "**about**"
Index: /gsdl/stable/collect/modelcol/macros/extra.dm
===================================================================
--- /gsdl/stable/collect/modelcol/macros/extra.dm	(revision 20131)
+++ /gsdl/stable/collect/modelcol/macros/extra.dm	(revision 20131)
@@ -0,0 +1,4 @@
+# extra.dm file
+# You can add collection specific macros in here
+# Lines starting with a '#' are comments.
+# Remember to include the package declaration
Index: /gsdl/stable/common-src/Makefile.in
===================================================================
--- /gsdl/stable/common-src/Makefile.in	(revision 20131)
+++ /gsdl/stable/common-src/Makefile.in	(revision 20131)
@@ -0,0 +1,139 @@
+###########################################################################
+#
+# Makefile -- common code between gsdl runtime and buildtime
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+srcdir = @srcdir@
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+@SET_MAKE@
+CC = @CC@
+CXX = @CXX@
+CFLAGS = @CFLAGS@
+CXXFLAGS = @CXXFLAGS@
+LIBS   = @LIBS@
+MDEFINES =
+
+GSDLOS = @gsdlos@
+
+COMPILE = $(CC) -c
+
+SOURCES = 
+
+OBJECTS = 
+
+ALLFILES = $(OBJECTS)
+
+# indexers are treated slightly differently as we don't want to do make all/install for gs2
+INDEXERSDIR = indexers
+
+# all directories should be compiled
+COMPILEDIRS = packages src/lib src/gdbmedit/txt2db src/gdbmedit/db2txt \
+  src/gdbmedit/gdbmget src/gdbmedit/gdbmset \
+  src/gdbmedit/gdbmkeys src/gdbmedit/gdbmdel \
+  src/getpw 
+
+# a subset of the directories get installed
+INSTALLDIRS = packages src/gdbmedit/db2txt src/gdbmedit/txt2db \
+  src/gdbmedit/gdbmget src/gdbmedit/gdbmset \
+  src/gdbmedit/gdbmkeys src/gdbmedit/gdbmdel \
+  src/getpw 
+
+MODULEDIRS = @MODULEDIRS@
+
+
+all:
+	for odir in $(INDEXERSDIR) $(COMPILEDIRS) $(MODULEDIRS); do \
+	  echo making $@ in $$odir; \
+	  (cd $$odir && $(MAKE) $(MDEFINES) $@) || exit 1; \
+	done
+
+install: 
+	for odir in $(INDEXERSDIR); do \
+	  echo making $@ in $$odir; \
+	  (cd $$odir && $(MAKE) $(MDEFINES) install) || exit 1; \
+	done
+	cp $(INDEXERSDIR)/lucene-gs/LuceneWrapper.jar ../bin/java/	
+	for idir in $(INSTALLDIRS); do \
+	  echo installing $$idir; \
+	  (cd $$idir && $(MAKE) install) || exit 1; \
+	done
+
+gs2: 
+	for odir in $(INDEXERSDIR); do \
+	  echo making $@ in $$odir; \
+	  (cd $$odir && $(MAKE) $(MDEFINES) $@) || exit 1; \
+	done
+	for odir in $(COMPILEDIRS) $(MODULEDIRS); do \
+	  echo making all in $$odir; \
+	  (cd $$odir && $(MAKE) $(MDEFINES) all) || exit 1; \
+	done
+
+install-gs2:
+	for odir in $(INDEXERSDIR); do \
+	  echo making $@ in $$odir; \
+	  (cd $$odir && $(MAKE) $(MDEFINES) $@) || exit 1; \
+	done
+	cp $(INDEXERSDIR)/lucene-gs/LuceneWrapper.jar ../bin/java/	
+	for odir in $(COMPILEDIRS) $(MODULEDIRS); do \
+	  echo making install in $$odir; \
+	  (cd $$odir && $(MAKE) $(MDEFINES) install) || exit 1; \
+	done
+
+distclean: clean
+	rm -f Makefile config.cache config.h config.log stamp-h config.status
+	for subdir in $(COMPILEDIRS) $(INDEXERSDIR); do \
+	  echo cleaning $@ in $$subdir; \
+	  (cd $$subdir && $(MAKE) distclean) || exit 1; \
+	done
+
+clean:
+	for subdir in $(COMPILEDIRS) $(INDEXERSDIR); do \
+	  echo cleaning $@ in $$subdir; \
+	  (cd $$subdir && $(MAKE) clean) || exit 1; \
+	done
+
+# commented out - jrm21 Dec 2004 - can get confused by cvs timestamps
+# (and might run the wrong version of autoconf)
+#
+## For an explanation of the following Makefile rules, see node
+## `Automatic Remaking' in GNU Autoconf documentation.
+#Makefile: Makefile.in config.status
+#	CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+#config.status: configure
+#	./config.status --recheck
+#configure: configure.in aclocal.m4
+#	cd $(srcdir) && autoconf
+#
+#config.h: stamp-h
+#stamp-h: config.h.in config.status
+#	CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status
+#config.h.in: stamp-h.in
+#stamp-h.in: configure.in aclocal.m4 acconfig.h
+#	cd $(srcdir) && autoheader
+#	$(TOUCH) $(srcdir)/stamp-h.in
+
+
+
Index: /gsdl/stable/common-src/aclocal.m4
===================================================================
--- /gsdl/stable/common-src/aclocal.m4	(revision 20131)
+++ /gsdl/stable/common-src/aclocal.m4	(revision 20131)
@@ -0,0 +1,140 @@
+# Local additions to Autoconf macros.
+# Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+# François Pinard <pinard@iro.umontreal.ca>, 1992.
+
+# [TS:Aug/95] - chopped out the NLS stuff which I don't support
+
+## ------------------------------- ##
+## Check for function prototypes.  ##
+## ------------------------------- ##
+
+AC_DEFUN(fp_C_PROTOTYPES,
+[AC_REQUIRE([fp_PROG_CC_STDC])
+AC_MSG_CHECKING([for function prototypes])
+if test "$ac_cv_prog_cc_stdc" != no; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(PROTOTYPES)
+  U= ANSI2KNR=
+else
+  AC_MSG_RESULT(no)
+  U=_ ANSI2KNR=ansi2knr
+fi
+AC_SUBST(U)dnl
+AC_SUBST(ANSI2KNR)dnl
+])
+
+## ----------------------------------------- ##
+## ANSIfy the C compiler whenever possible.  ##
+## ----------------------------------------- ##
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so.  This macro tries various
+# options that select ANSI C on some system or another.  It considers the
+# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and
+# handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{ac_cv_prog_cc_stdc} is set to @samp{no}.  If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN(fp_PROG_CC_STDC,
+[AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
+AC_CACHE_VAL(ac_cv_prog_cc_stdc,
+[ac_cv_prog_cc_stdc=no
+ac_save_CFLAGS="$CFLAGS"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX			-Aa -D_HPUX_SOURCE
+# SVR4			-Xc
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" -Xc
+do
+  CFLAGS="$ac_save_CFLAGS $ac_arg"
+  AC_TRY_COMPILE(
+[#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif	
+], [int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};],
+[ac_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CFLAGS="$ac_save_CFLAGS"
+])
+AC_MSG_RESULT($ac_cv_prog_cc_stdc)
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno) ;;
+  *) CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+])
+
+## --------------------------------------------------------- ##
+## Use AC_PROG_INSTALL, supplementing it with INSTALL_SCRIPT ##
+## substitution.					     ##
+## --------------------------------------------------------- ##
+
+AC_DEFUN(fp_PROG_INSTALL,
+[AC_PROG_INSTALL
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL} -m 755'
+AC_SUBST(INSTALL_SCRIPT)dnl
+])
+
+## ----------------------------------- ##
+## Check if --with-dmalloc was given.  ##
+## ----------------------------------- ##
+
+# I just checked, and GNU rx seems to work fine with a slightly
+# modified GNU m4.  So, I put out the test below in my aclocal.m4,
+# and will try to use it in my things.  The idea is to distribute
+# rx.[hc] and regex.[hc] together, for a while.  The WITH_REGEX symbol
+# (which should also be documented in acconfig.h) is used to decide
+# which of regex.h or rx.h should be included in the application.
+#
+# If `./configure --with-regex' is given, the package will use
+# the older regex.  Else, a check is made to see if rx is already
+# installed, as with newer Linux'es.  If not found, the package will
+# use the rx from the distribution.  If found, the package will use
+# the system's rx which, on Linux at least, will result in a smaller
+# executable file.
+
+AC_DEFUN(fp_WITH_DMALLOC,
+[AC_MSG_CHECKING(if malloc debugging is wanted)
+AC_ARG_WITH(dmalloc,
+[  --with-dmalloc          use dmalloc, as in
+                          ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz],
+[if test "$withval" = yes; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(WITH_DMALLOC)
+  LIBS="$LIBS -ldmalloc"
+  LDFLAGS="$LDFLAGS -g"
+else
+  AC_MSG_RESULT(no)
+fi], [AC_MSG_RESULT(no)])
+])
+
+## --------------------------------- ##
+## Check if --with-regex was given.  ##
+## --------------------------------- ##
+
+AC_DEFUN(fp_WITH_REGEX,
+[AC_MSG_CHECKING(which of rx or regex is wanted)
+AC_ARG_WITH(regex,
+[  --with-regex            use older regex in lieu of GNU rx for matching],
+[if test "$withval" = yes; then
+  ac_with_regex=1
+  AC_MSG_RESULT(regex)
+  AC_DEFINE(WITH_REGEX)
+  AC_LIBOBJ([regex])
+fi])
+if test -z "$ac_with_regex"; then
+  AC_MSG_RESULT(rx)
+  AC_CHECK_FUNC(re_rx_search, , [AC_LIBOBJ([rx])])
+fi
+])
Index: /gsdl/stable/common-src/config.guess
===================================================================
--- /gsdl/stable/common-src/config.guess	(revision 20131)
+++ /gsdl/stable/common-src/config.guess	(revision 20131)
@@ -0,0 +1,1298 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-07-12'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int dummy(){}" > $dummy.c ;
+	for c in cc gcc c89 ; do
+	  ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
+	  if test $? = 0 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	rm -f $dummy.c $dummy.o $dummy.rel ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# Netbsd (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	# Determine the machine/vendor (is the vendor relevant).
+	case "${UNAME_MACHINE}" in
+	    amiga) machine=m68k-unknown ;;
+	    arm32) machine=arm-unknown ;;
+	    atari*) machine=m68k-atari ;;
+	    sun3*) machine=m68k-sun ;;
+	    mac68k) machine=m68k-apple ;;
+	    macppc) machine=powerpc-apple ;;
+	    hp3[0-9][05]) machine=m68k-hp ;;
+	    ibmrt|romp-ibm) machine=romp-ibm ;;
+	    *) machine=${UNAME_MACHINE}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE}" in
+	    i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	cat <<EOF >$dummy.s
+	.data
+\$Lformat:
+	.byte 37,100,45,37,120,10,0	# "%d-%x\n"
+
+	.text
+	.globl main
+	.align 4
+	.ent main
+main:
+	.frame \$30,16,\$26,0
+	ldgp \$29,0(\$27)
+	.prologue 1
+	.long 0x47e03d80 # implver \$0
+	lda \$2,-1
+	.long 0x47e20c21 # amask \$2,\$1
+	lda \$16,\$Lformat
+	mov \$0,\$17
+	not \$1,\$18
+	jsr \$26,printf
+	ldgp \$29,0(\$26)
+	mov 0,\$16
+	jsr \$26,exit
+	.end main
+EOF
+	eval $set_cc_for_build
+	$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+	if test "$?" = 0 ; then
+		case `./$dummy` in
+			0-0)
+				UNAME_MACHINE="alpha"
+				;;
+			1-0)
+				UNAME_MACHINE="alphaev5"
+				;;
+			1-1)
+				UNAME_MACHINE="alphaev56"
+				;;
+			1-101)
+				UNAME_MACHINE="alphapca56"
+				;;
+			2-303)
+				UNAME_MACHINE="alphaev6"
+				;;
+			2-307)
+				UNAME_MACHINE="alphaev67"
+				;;
+		esac
+	fi
+	rm -f $dummy.s $dummy
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    arc64:OpenBSD:*:*)
+	echo mips64el-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hkmips:OpenBSD:*:*)
+	echo mips-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mips-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    sun3*:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	eval $set_cc_for_build
+	$CC_FOR_BUILD $dummy.c -o $dummy \
+	  && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && rm -f $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		eval $set_cc_for_build
+		$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+		rm -f $dummy.c $dummy
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+              case "${HPUX_REV}" in
+                11.[0-9][0-9])
+                  if [ -x /usr/bin/getconf ]; then
+                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+                        esac ;;
+                    esac
+                  fi ;;
+              esac
+              if [ "${HP_ARCH}" = "" ]; then
+              sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+	eval $set_cc_for_build
+	(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+	if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+	rm -f $dummy.c $dummy
+	fi ;;
+	esac
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	eval $set_cc_for_build
+	$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    hppa*:OpenBSD:*:*)
+	echo hppa-unknown-openbsd
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+	echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3D:*:*:*)
+	echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY-2:*:*:*)
+	echo cray2-cray-unicos
+        exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i386-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
+	  big)    echo mips-unknown-linux-gnu && exit 0 ;;
+	  little) echo mipsel-unknown-linux-gnu && exit 0 ;;
+	esac
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev67 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	ld_supported_targets=`cd /; ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;		
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-pc-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-pc-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+	eval $set_cc_for_build
+	$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	echo `uname -p`-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	if test "${UNAME_MACHINE}" = "x86pc"; then
+		UNAME_MACHINE=pc
+	fi
+	echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-[KW]:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+eval $set_cc_for_build
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
Index: /gsdl/stable/common-src/config.h.in
===================================================================
--- /gsdl/stable/common-src/config.h.in	(revision 20131)
+++ /gsdl/stable/common-src/config.h.in	(revision 20131)
@@ -0,0 +1,217 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+#ifndef _GSDL_CONFIG_H
+#define _GSDL_CONFIG_H
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+#undef _ALL_SOURCE
+#endif
+
+/* Define if using alloca.c.  */
+#undef C_ALLOCA
+
+/* Define if big endian */
+#undef WORDS_BIGENDIAN
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro.  */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+#undef HAVE_ALLOCA_H
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+#undef HAVE_DOPRNT
+
+/* Define if you have the vprintf function.  */
+#undef HAVE_VPRINTF
+
+/* Define if on MINIX.  */
+#undef _MINIX
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+#undef off_t
+
+/* Define if the system does not provide POSIX.1 features except
+   with this defined.  */
+#undef _POSIX_1_SOURCE
+
+/* Define if you need to in order for stat and other things to work.  */
+#undef _POSIX_SOURCE
+
+/* Define as the return type of signal handlers (int or void).  */
+#undef RETSIGTYPE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm.  */
+#undef TM_IN_SYS_TIME
+
+/* Define to the name of the distribution.  */
+#undef PACKAGE
+
+/* Define to the version of the distribution.  */
+#undef VERSION
+
+/* Define to 1 if you have the valloc function.  */
+#undef HAVE_VALLOC
+
+/* Define to 1 if ANSI function prototypes are usable.  */
+#undef PROTOTYPES
+
+/* Define if you don't want to use long long's with GCC */
+#undef DISABLE_LONG_LONG
+ 
+/* Define to 1 for better use of the debugging malloc library.  See
+   site ftp.antaire.com in antaire/src, file dmalloc/dmalloc.tar.gz.  */
+#undef WITH_DMALLOC
+
+ 
+/* Define to 1 if GNU regex should be used instead of GNU rx.  */
+#undef WITH_REGEX
+
+/* Some braindead header files do not have the requ'd function declarations */
+#undef HAVE_FGETC_DECL
+#undef HAVE_FREAD_DECL
+
+/* See if have this field in the prstatus_t structure */
+/* It stores the size of the process heap */
+#undef HAVE_PR_BRKSIZE
+
+/* Define FASTCGI if needsbe */
+#undef USE_FASTCGI
+
+/* Define USE_CORBA if needsbe */
+#undef USE_CORBA
+
+/* Define MICO_DIR if needsbe */
+#undef MICO_DIR
+
+/* Define MICO_VERSION if required */
+#undef MICO_VERSION
+
+/* Define if you have the ftime function.  */
+#undef HAVE_FTIME
+
+/* Define if you have the ftruncate function.  */
+#undef HAVE_FTRUNCATE
+
+/* Define if you have the getpagesize function.  */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the getrusage function.  */
+#undef HAVE_GETRUSAGE
+
+/* Define if you have the mallinfo function.  */
+#undef HAVE_MALLINFO
+
+/* Define if you have the select function.  */
+#undef HAVE_SELECT
+
+/* Define if you have the setbuffer function.  */
+#undef HAVE_SETBUFFER
+
+/* Define if you have the strcasecmp function.  */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strerror function.  */
+#undef HAVE_STRERROR
+
+/* Define if you have the strftime function.  */
+#undef HAVE_STRFTIME
+
+/* Define if you have the strstr function.  */
+#undef HAVE_STRSTR
+
+/* Define if you have the strtol function.  */
+#undef HAVE_STRTOL
+
+/* Define if you have the times function.  */
+#undef HAVE_TIMES
+
+/* Define if you have the valloc function.  */
+#undef HAVE_VALLOC
+
+/* Define if you have the <crypt.h> header file.  */
+#undef HAVE_CRYPT_H
+
+/* Define if you have the <dirent.h> header file.  */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <fcntl.h> header file.  */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <limits.h> header file.  */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <memory.h> header file.  */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <ndir.h> header file.  */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <string.h> header file.  */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/dir.h> header file.  */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/ndir.h> header file.  */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/procfs.h> header file.  */
+#undef HAVE_SYS_PROCFS_H
+
+/* Define if you have the <sys/time.h> header file.  */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <unistd.h> header file.  */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the crypt library (-lcrypt).  */
+#undef HAVE_LIBCRYPT
+
+/* Define if you have the g library (-lg).  */
+#undef HAVE_LIBG
+
+/* Define if you have the gdbm library (-lgdbm).  */
+#undef HAVE_LIBGDBM
+
+/* Define if you have the m library (-lm).  */
+#undef HAVE_LIBM
+
+/* Define if you have the stdc++ library (-lstdc++).  */
+#undef HAVE_LIBSTDC__
+
+/* Define if you have gettext (eg glibc) */
+#undef ENABLE_NLS
+
+/* Define if big endian */
+#undef WORDS_BIGENDIAN
+
+#endif /* _GSDL_CONFIG_H */
Index: /gsdl/stable/common-src/config.sub
===================================================================
--- /gsdl/stable/common-src/config.sub	(revision 20131)
+++ /gsdl/stable/common-src/config.sub	(revision 20131)
@@ -0,0 +1,1375 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-06-08'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
+	        | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
+		| pyramid | mn10200 | mn10300 | tron | a29k \
+		| 580 | i960 | h8300 \
+		| x86 | ppcbe | mipsbe | mipsle | shbe | shle \
+		| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+		| hppa64 \
+		| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
+		| alphaev6[78] \
+		| we32k | ns16k | clipper | i370 | sh | sh[34] \
+		| powerpc | powerpcle \
+		| 1750a | dsp16xx | pdp10 | pdp11 \
+		| mips16 | mips64 | mipsel | mips64el \
+		| mips64orion | mips64orionel | mipstx39 | mipstx39el \
+		| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+		| mips64vr5000 | mips64vr5000el | mcore | s390 | s390x \
+		| sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
+		| v850 | c4x \
+		| thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
+		| pj | pjl | h8500 | z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	# FIXME: clean up the formatting here.
+	vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
+	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
+	      | arm-*  | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
+	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+	      | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+	      | xmp-* | ymp-* \
+	      | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
+	      | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
+	      | hppa2.0n-* | hppa64-* \
+	      | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
+	      | alphaev6[78]-* \
+	      | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+	      | clipper-* | orion-* \
+	      | sparclite-* | pdp10-* | pdp11-* | sh-* | sh[34]-* | sh[34]eb-* \
+	      | powerpc-* | powerpcle-* | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
+	      | mips16-* | mips64-* | mipsel-* \
+	      | mips64el-* | mips64orion-* | mips64orionel-* \
+	      | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+	      | mipstx39-* | mipstx39el-* | mcore-* \
+	      | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
+	      | [cjt]90-* \
+	      | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+	      | thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
+	      | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	cray2)
+		basic_machine=cray2-cray
+		os=-unicos
+		;;
+	[cjt]90)
+		basic_machine=${basic_machine}-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mipsel*-linux*)
+		basic_machine=mipsel-unknown
+		os=-linux-gnu
+		;;
+	mips*-linux*)
+		basic_machine=mips-unknown
+		os=-linux-gnu
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	mmix*)
+		basic_machine=mmix-knuth
+		os=-mmixware
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+        pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2)
+		basic_machine=i686-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+	        ;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+	        ;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sparclite-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=t3e-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	windows32)
+		basic_machine=i386-pc
+		os=-windows32-msvcrt
+		;;
+	xmp)
+		basic_machine=xmp-cray
+		os=-unicos
+		;;
+        xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	mips)
+		if [ x$os = x-linux-gnu ]; then
+			basic_machine=mips-unknown
+		else
+			basic_machine=mips-mips
+		fi
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+        cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	c4x*)
+		basic_machine=c4x-none
+		os=-coff
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto*)
+		os=-nto-qnx
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-ns2 )
+	        os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+	        os=-mint
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	pdp10-*)
+		os=-tops20
+		;;
+        pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+        *-gould)
+		os=-sysv
+		;;
+        *-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+        *-sgi)
+		os=-irix
+		;;
+        *-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-vxsim* | -vxworks*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
Index: /gsdl/stable/common-src/configure
===================================================================
--- /gsdl/stable/common-src/configure	(revision 20131)
+++ /gsdl/stable/common-src/configure	(revision 20131)
@@ -0,0 +1,8602 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="src/lib/text_t.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subdirs_all="$ac_subdirs_all packages indexers"
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS PACKAGE VERSION USE_FASTCGI USE_LANGACTION USE_CORBA MICO_DIR USE_Z3950 USE_YAZ ENABLE_ACCENTFOLD USE_SQLITE LDFLAGS CFLAGS CC CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX AWK YACC build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB COMPAT32BITFLAGS MICO_VER CPP EGREP U ANSI2KNR ALLOCA LIBOBJS STATIC gsdlos MODULEDIRS subdirs LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CXX_set=${CXX+set}
+ac_env_CXX_value=$CXX
+ac_cv_env_CXX_set=${CXX+set}
+ac_cv_env_CXX_value=$CXX
+ac_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_env_CXXFLAGS_value=$CXXFLAGS
+ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_cv_env_CXXFLAGS_value=$CXXFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-corba          Enable CORBA support
+  --enable-z3950          Enable Z39.50 client support
+  --disable-yaz           Disable YAZ compilation
+  --disable-accentfold    Disable Accent Folding for MGPP
+  --disable-sqlite        Disable SQLite support
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-micodir          Use installed MICO directory
+  --with-dmalloc          use dmalloc, as in
+                          ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz
+  --with-regex            use older regex in lieu of GNU rx for matching
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers config.h"
+
+
+
+
+
+PACKAGE=gsdl
+VERSION=2.82-svn
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+
+
+
+USE_FASTCGI=0
+if test USE_FASTCGI = 1; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_FASTCGI 1
+_ACEOF
+
+
+fi
+
+if test USE_LANGACTION = 1; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_LANGACTION 1
+_ACEOF
+
+
+fi
+
+# Check whether --enable-corba or --disable-corba was given.
+if test "${enable_corba+set}" = set; then
+  enableval="$enable_corba"
+  USE_CORBA=1
+else
+  USE_CORBA=0
+fi;
+cat >>confdefs.h <<_ACEOF
+#define USE_CORBA $USE_CORBA
+_ACEOF
+
+
+
+
+# Check whether --with-micodir or --without-micodir was given.
+if test "${with_micodir+set}" = set; then
+  withval="$with_micodir"
+  MICO_DIR=$enableval
+else
+  MICO_DIR="default"
+fi;
+cat >>confdefs.h <<_ACEOF
+#define MICO_DIR "$MICO_DIR"
+_ACEOF
+
+
+
+# Check whether --enable-z3950 or --disable-z3950 was given.
+if test "${enable_z3950+set}" = set; then
+  enableval="$enable_z3950"
+  USE_Z3950=1
+else
+  USE_Z3950=0
+fi;
+if test USE_Z3950 = 1; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_Z3950 $USE_Z3950
+_ACEOF
+
+
+fi
+
+# Check whether --enable-yaz or --disable-yaz was given.
+if test "${enable_yaz+set}" = set; then
+  enableval="$enable_yaz"
+  USE_YAZ=0
+else
+  USE_YAZ=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define USE_YAZ $USE_YAZ
+_ACEOF
+
+
+
+# Check whether --enable-accentfold or --disable-accentfold was given.
+if test "${enable_accentfold+set}" = set; then
+  enableval="$enable_accentfold"
+  ENABLE_ACCENTFOLD=0
+else
+  ENABLE_ACCENTFOLD=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define ENABLE_ACCENTFOLD $ENABLE_ACCENTFOLD
+_ACEOF
+
+
+
+# Check whether --enable-sqlite or --disable-sqlite was given.
+if test "${enable_sqlite+set}" = set; then
+  enableval="$enable_sqlite"
+  USE_SQLITE=0
+else
+  USE_SQLITE=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define USE_SQLITE $USE_SQLITE
+_ACEOF
+
+
+
+LDFLAGS=$LDFLAGS
+
+if test -z "$CFLAGS"; then
+CFLAGS=-O2
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+	;;
+    conftest.$ac_ext )
+	# This is the source file.
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
+    * )
+	break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  export ac_cv_exeext
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX 10.20 and later	-Ae
+# HP-UX older versions	-Aa -D_HPUX_SOURCE
+# SVR4			-Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CXX" && break
+done
+test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
+
+  CXX=$ac_ct_CXX
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cxx_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+for ac_prog in 'bison -y' byacc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_YACC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_YACC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+  echo "$as_me:$LINENO: result: $YACC" >&5
+echo "${ECHO_T}$YACC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6
+if test "${ac_cv_target+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_target_alias=$target_alias
+test "x$ac_cv_target_alias" = "x" &&
+  ac_cv_target_alias=$ac_cv_host_alias
+ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6
+target=$ac_cv_target
+target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+	@echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+echo "$as_me:$LINENO: checking to see if architecture is 64-bit" >&5
+echo $ECHO_N "checking to see if architecture is 64-bit... $ECHO_C" >&6
+arch_64bit=no
+case "$host_cpu" in
+x86_64) arch_64bit=yes ;;
+esac
+
+if test "$arch_64bit" = yes; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS="-m32"
+  fi
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS=
+  fi
+fi
+export COMPAT32BITFLAGS
+
+
+
+#moved CORBA MICO directory test to get version of MICO
+if test $USE_CORBA = 1; then
+
+if test $MICO_DIR = "default"; then
+#do something
+MICO_INC="-I packages/mico/mico/include"
+else
+#build the micotest program
+MICO_INC= ""
+if test $MICO_DIR != yes; then
+MICO_INC="-I $MICO_DIR"
+fi
+fi
+
+#get MICO_VER value
+sh -c "$CC -c micotest.cpp -o micotest.o $MICO_INC 2>&1" > /dev/null
+sh -c "$CC -o micotest micotest.o -lstdc++ 2>&1" > /dev/null
+MICO_VER=`./micotest` || MICO_VER=2.3.5
+sh -c "rm micotest"
+sh -c "rm micotest.o"
+
+#do test of MICO_VER
+if test MICO_VER != 0; then
+cat >>confdefs.h <<\_ACEOF
+#define MICO_VER 1
+_ACEOF
+
+
+fi
+#end USE_CORBA test
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+
+echo "$as_me:$LINENO: checking for AIX" >&5
+echo $ECHO_N "checking for AIX... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef _AIX
+  yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+cat >>confdefs.h <<\_ACEOF
+#define _ALL_SOURCE 1
+_ACEOF
+
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest*
+
+
+echo "$as_me:$LINENO: checking for library containing strerror" >&5
+echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6
+if test "${ac_cv_search_strerror+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_strerror=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char strerror ();
+int
+main ()
+{
+strerror ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_strerror="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_strerror" = no; then
+  for ac_lib in cposix; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char strerror ();
+int
+main ()
+{
+strerror ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_strerror="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5
+echo "${ECHO_T}$ac_cv_search_strerror" >&6
+if test "$ac_cv_search_strerror" != no; then
+  test "$ac_cv_search_strerror" = "none required" || LIBS="$ac_cv_search_strerror $LIBS"
+
+fi
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for minix/config.h" >&5
+echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
+echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking minix/config.h usability" >&5
+echo $ECHO_N "checking minix/config.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <minix/config.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking minix/config.h presence" >&5
+echo $ECHO_N "checking minix/config.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <minix/config.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: minix/config.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: minix/config.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for minix/config.h" >&5
+echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_minix_config_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
+echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6
+
+fi
+if test $ac_cv_header_minix_config_h = yes; then
+  MINIX=yes
+else
+  MINIX=
+fi
+
+
+if test "$MINIX" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_SOURCE 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_1_SOURCE 2
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _MINIX 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for ${CC-cc} option to accept ANSI C" >&5
+echo $ECHO_N "checking for ${CC-cc} option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CFLAGS="$CFLAGS"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX			-Aa -D_HPUX_SOURCE
+# SVR4			-Xc
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" -Xc
+do
+  CFLAGS="$ac_save_CFLAGS $ac_arg"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif
+
+int
+main ()
+{
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc="$ac_arg"; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+CFLAGS="$ac_save_CFLAGS"
+
+fi
+
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno) ;;
+  *) CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+
+echo "$as_me:$LINENO: checking for function prototypes" >&5
+echo $ECHO_N "checking for function prototypes... $ECHO_C" >&6
+if test "$ac_cv_prog_cc_stdc" != no; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  cat >>confdefs.h <<\_ACEOF
+#define PROTOTYPES 1
+_ACEOF
+
+  U= ANSI2KNR=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  U=_ ANSI2KNR=ansi2knr
+fi
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6
+if test "${ac_cv_type_off_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((off_t *) 0)
+  return 0;
+if (sizeof (off_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_off_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_off_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
+if test $ac_cv_type_off_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((size_t *) 0)
+  return 0;
+if (sizeof (size_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_size_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_size_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+if test $ac_cv_type_size_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+if test "${ac_cv_header_time+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_time=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_time=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6
+if test $ac_cv_header_time = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TIME_WITH_SYS_TIME 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5
+echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6
+if test "${ac_cv_struct_tm+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <time.h>
+
+int
+main ()
+{
+struct tm *tp; tp->tm_sec;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_struct_tm=time.h
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5
+echo "${ECHO_T}$ac_cv_struct_tm" >&6
+if test $ac_cv_struct_tm = sys/time.h; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TM_IN_SYS_TIME 1
+_ACEOF
+
+fi
+
+
+if test "$ac_cv_prog_cc_stdc" = '-Xc'; then
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+int
+main ()
+{
+ FILE *rubbish = popen("yes", "r");
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+CC="`echo $CC | sed 's/-Xc/-Xa/'`"    ac_cv_prog_cc_stdc='-Xa'
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+
+echo "$as_me:$LINENO: checking for main in -lg" >&5
+echo $ECHO_N "checking for main in -lg... $ECHO_C" >&6
+if test "${ac_cv_lib_g_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lg  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_g_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_g_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_g_main" >&5
+echo "${ECHO_T}$ac_cv_lib_g_main" >&6
+if test $ac_cv_lib_g_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBG 1
+_ACEOF
+
+  LIBS="-lg $LIBS"
+
+fi
+ac_cv_lib_g=ac_cv_lib_g_main
+
+
+echo "$as_me:$LINENO: checking for main in -lm" >&5
+echo $ECHO_N "checking for main in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5
+echo "${ECHO_T}$ac_cv_lib_m_main" >&6
+if test $ac_cv_lib_m_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+fi
+ac_cv_lib_m=ac_cv_lib_m_main
+
+
+echo "$as_me:$LINENO: checking for main in -lcrypt" >&5
+echo $ECHO_N "checking for main in -lcrypt... $ECHO_C" >&6
+if test "${ac_cv_lib_crypt_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypt_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypt_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_main" >&5
+echo "${ECHO_T}$ac_cv_lib_crypt_main" >&6
+if test $ac_cv_lib_crypt_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCRYPT 1
+_ACEOF
+
+  LIBS="-lcrypt $LIBS"
+
+fi
+ac_cv_lib_crypt=ac_cv_lib_crypt_main
+
+if test $ENABLE_ACCENTFOLD = 1; then
+
+echo "$as_me:$LINENO: checking for main in -liconv" >&5
+echo $ECHO_N "checking for main in -liconv... $ECHO_C" >&6
+if test "${ac_cv_lib_iconv_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-liconv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_iconv_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_iconv_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_iconv_main" >&5
+echo "${ECHO_T}$ac_cv_lib_iconv_main" >&6
+if test $ac_cv_lib_iconv_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBICONV 1
+_ACEOF
+
+  LIBS="-liconv $LIBS"
+
+fi
+ac_cv_lib_iconv=ac_cv_lib_iconv_main
+
+fi
+
+
+
+
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5
+echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in dir; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+else
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in x; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+fi
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+
+
+for ac_header in fcntl.h limits.h sys/time.h unistd.h crypt.h string.h memory.h sys/procfs.h sys/stat.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "fread" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_FREAD_DECL 1
+_ACEOF
+
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "fgetc" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_FGETC_DECL 1
+_ACEOF
+
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/procfs.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "pr_brksize" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_PR_BRKSIZE 1
+_ACEOF
+
+fi
+rm -f conftest*
+
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+echo "$as_me:$LINENO: checking for working alloca.h" >&5
+echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6
+if test "${ac_cv_working_alloca_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_working_alloca_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_working_alloca_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5
+echo "${ECHO_T}$ac_cv_working_alloca_h" >&6
+if test $ac_cv_working_alloca_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA_H 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for alloca" >&5
+echo $ECHO_N "checking for alloca... $ECHO_C" >&6
+if test "${ac_cv_func_alloca_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  if HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_alloca_works=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_alloca_works=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5
+echo "${ECHO_T}$ac_cv_func_alloca_works" >&6
+
+if test $ac_cv_func_alloca_works = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA 1
+_ACEOF
+
+else
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble.  Some versions do not even contain alloca or
+# contain a buggy version.  If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=alloca.$ac_objext
+
+cat >>confdefs.h <<\_ACEOF
+#define C_ALLOCA 1
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5
+echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6
+if test "${ac_cv_os_cray+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "webecray" >/dev/null 2>&1; then
+  ac_cv_os_cray=yes
+else
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5
+echo "${ECHO_T}$ac_cv_os_cray" >&6
+if test $ac_cv_os_cray = yes; then
+  for ac_func in _getb67 GETB67 getb67; do
+    as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+    break
+fi
+
+  done
+fi
+
+echo "$as_me:$LINENO: checking stack direction for C alloca" >&5
+echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6
+if test "${ac_cv_c_stack_direction+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_c_stack_direction=0
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+  exit (find_stack_direction () < 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_stack_direction=1
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5
+echo "${ECHO_T}$ac_cv_c_stack_direction" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+if test $ac_cv_c_compiler_gnu = yes; then
+    echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5
+echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6
+if test "${ac_cv_prog_gcc_traditional+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+else
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5
+echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+echo "$as_me:$LINENO: checking return type of signal handlers" >&5
+echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
+if test "${ac_cv_type_signal+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+# undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_signal=void
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_signal=int
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
+echo "${ECHO_T}$ac_cv_type_signal" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+
+for ac_func in vprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+echo "$as_me:$LINENO: checking for _doprnt" >&5
+echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6
+if test "${ac_cv_func__doprnt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define _doprnt to an innocuous variant, in case <limits.h> declares _doprnt.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define _doprnt innocuous__doprnt
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _doprnt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef _doprnt
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char _doprnt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+char (*f) () = _doprnt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != _doprnt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func__doprnt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func__doprnt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5
+echo "${ECHO_T}$ac_cv_func__doprnt" >&6
+if test $ac_cv_func__doprnt = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DOPRNT 1
+_ACEOF
+
+fi
+
+fi
+done
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_func in ftime select strftime strtol getrusage times mallinfo setbuffer getpagesize strerror
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+for ac_func in ftruncate strstr strcasecmp
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+echo "$as_me:$LINENO: checking for textdomain" >&5
+echo $ECHO_N "checking for textdomain... $ECHO_C" >&6
+if test "${ac_cv_func_textdomain+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define textdomain to an innocuous variant, in case <limits.h> declares textdomain.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define textdomain innocuous_textdomain
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char textdomain (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef textdomain
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char textdomain ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_textdomain) || defined (__stub___textdomain)
+choke me
+#else
+char (*f) () = textdomain;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != textdomain;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_textdomain=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_textdomain=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_textdomain" >&5
+echo "${ECHO_T}$ac_cv_func_textdomain" >&6
+if test $ac_cv_func_textdomain = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define ENABLE_NLS  1
+_ACEOF
+
+fi
+
+
+# *** Custom checking (based on GNU tar configure.in) ***
+# ---------------------------------------------------------------------------
+echo "$as_me:$LINENO: checking for HP-UX needing gmalloc" >&5
+echo $ECHO_N "checking for HP-UX needing gmalloc... $ECHO_C" >&6
+if test "`(uname -s) 2> /dev/null`" = 'HP-UX'; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  case $LIBOBJS in
+    "gmalloc.$ac_objext"   | \
+  *" gmalloc.$ac_objext"   | \
+    "gmalloc.$ac_objext "* | \
+  *" gmalloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS gmalloc.$ac_objext" ;;
+esac
+
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_VALLOC 1
+_ACEOF
+
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+for ac_func in valloc
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+fi
+
+# we cannot generate static libraries under Darwin
+echo "$as_me:$LINENO: checking for Apple MacOS X/Darwin" >&5
+echo $ECHO_N "checking for Apple MacOS X/Darwin... $ECHO_C" >&6
+if test "`(uname -s) 2> /dev/null`" = 'Darwin'; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  STATIC=""
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  STATIC="-static "
+fi
+
+
+echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5
+echo $ECHO_N "checking if malloc debugging is wanted... $ECHO_C" >&6
+
+# Check whether --with-dmalloc or --without-dmalloc was given.
+if test "${with_dmalloc+set}" = set; then
+  withval="$with_dmalloc"
+  if test "$withval" = yes; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  cat >>confdefs.h <<\_ACEOF
+#define WITH_DMALLOC 1
+_ACEOF
+
+  LIBS="$LIBS -ldmalloc"
+  LDFLAGS="$LDFLAGS -g"
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+echo "$as_me:$LINENO: checking which of rx or regex is wanted" >&5
+echo $ECHO_N "checking which of rx or regex is wanted... $ECHO_C" >&6
+
+# Check whether --with-regex or --without-regex was given.
+if test "${with_regex+set}" = set; then
+  withval="$with_regex"
+  if test "$withval" = yes; then
+  ac_with_regex=1
+  echo "$as_me:$LINENO: result: regex" >&5
+echo "${ECHO_T}regex" >&6
+  cat >>confdefs.h <<\_ACEOF
+#define WITH_REGEX 1
+_ACEOF
+
+  case $LIBOBJS in
+    "regex.$ac_objext"   | \
+  *" regex.$ac_objext"   | \
+    "regex.$ac_objext "* | \
+  *" regex.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS regex.$ac_objext" ;;
+esac
+
+fi
+fi;
+if test -z "$ac_with_regex"; then
+  echo "$as_me:$LINENO: result: rx" >&5
+echo "${ECHO_T}rx" >&6
+  echo "$as_me:$LINENO: checking for re_rx_search" >&5
+echo $ECHO_N "checking for re_rx_search... $ECHO_C" >&6
+if test "${ac_cv_func_re_rx_search+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define re_rx_search to an innocuous variant, in case <limits.h> declares re_rx_search.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define re_rx_search innocuous_re_rx_search
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char re_rx_search (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef re_rx_search
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char re_rx_search ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_re_rx_search) || defined (__stub___re_rx_search)
+choke me
+#else
+char (*f) () = re_rx_search;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != re_rx_search;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_re_rx_search=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_re_rx_search=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_re_rx_search" >&5
+echo "${ECHO_T}$ac_cv_func_re_rx_search" >&6
+if test $ac_cv_func_re_rx_search = yes; then
+  :
+else
+  case $LIBOBJS in
+    "rx.$ac_objext"   | \
+  *" rx.$ac_objext"   | \
+    "rx.$ac_objext "* | \
+  *" rx.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS rx.$ac_objext" ;;
+esac
+
+fi
+
+fi
+
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+  case $LIBOBJS in
+    "xmalloc.$ac_objext"   | \
+  *" xmalloc.$ac_objext"   | \
+    "xmalloc.$ac_objext "* | \
+  *" xmalloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS xmalloc.$ac_objext" ;;
+esac
+
+  case $LIBOBJS in
+    "error.$ac_objext"   | \
+  *" error.$ac_objext"   | \
+    "error.$ac_objext "* | \
+  *" error.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS error.$ac_objext" ;;
+esac
+
+fi
+
+
+# ---------------------------------------------------------------------------
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+success=no
+echo "$as_me:$LINENO: checking \"whether STL library has known faults\"" >&5
+echo $ECHO_N "checking \"whether STL library has known faults\"... $ECHO_C" >&6
+
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <vector>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  success=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $success = "no"; then
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <vector.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  success="yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test $success = "no"; then
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ospace\\std\\vector>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  success="yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test $success = yes; then
+echo "$as_me:$LINENO: result: \"no\"" >&5
+echo "${ECHO_T}\"no\"" >&6
+else
+echo "$as_me:$LINENO: result: \"yes\"" >&5
+echo "${ECHO_T}\"yes\"" >&6
+{ { echo "$as_me:$LINENO: error: \"STL Broken - Obtain newer version of GNU C Compiler\"" >&5
+echo "$as_me: error: \"STL Broken - Obtain newer version of GNU C Compiler\"" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+gsdlos=`uname | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+# check for running bash under cygwin
+ if test "`echo $gsdlos | sed 's/cygwin//'`" != "$gsdlos" ;
+ then
+  gsdlos=windows
+ fi
+
+
+# check for endianness
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+main ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+  case $LIBOBJS in
+    "xmalloc.o.$ac_objext"   | \
+  *" xmalloc.o.$ac_objext"   | \
+    "xmalloc.o.$ac_objext "* | \
+  *" xmalloc.o.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS xmalloc.o.$ac_objext" ;;
+esac
+
+  case $LIBOBJS in
+    "error.$ac_objext"   | \
+  *" error.$ac_objext"   | \
+    "error.$ac_objext "* | \
+  *" error.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS error.$ac_objext" ;;
+esac
+
+fi
+
+# ---------------------------------------------------------------------------
+
+
+moduleDirs=""
+MODULEDIRS=""
+if test -d modules ; then
+  for x in `find modules -mindepth 1 -maxdepth 2`; do
+    if test -d "$x"; then
+      d="$x/Makefile.in"
+      if test -e "$d"; then
+          moduleDirs="$moduleDirs $x/Makefile"
+        MODULEDIRS="$MODULEDIRS $x"
+      fi
+    fi
+  done
+  echo "Making $moduleDirs in modules directory"
+
+fi
+
+
+# ---------------------------------------------------------------------------
+
+
+
+subdirs="$subdirs packages indexers"
+
+
+# the list of folders in the src folder
+srclist="src/lib/Makefile \
+         src/gdbmedit/db2txt/Makefile \
+         src/gdbmedit/txt2db/Makefile \
+         src/gdbmedit/gdbmget/Makefile \
+         src/gdbmedit/gdbmset/Makefile \
+         src/gdbmedit/gdbmkeys/Makefile \
+         src/gdbmedit/gdbmdel/Makefile \
+         src/getpw/Makefile"
+
+                                        ac_config_files="$ac_config_files packages/Makefile Makefile $srclist $moduleDirs"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "packages/Makefile" ) CONFIG_FILES="$CONFIG_FILES packages/Makefile" ;;
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "$srclist" ) CONFIG_FILES="$CONFIG_FILES $srclist" ;;
+  "$moduleDirs" ) CONFIG_FILES="$CONFIG_FILES $moduleDirs" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@USE_FASTCGI@,$USE_FASTCGI,;t t
+s,@USE_LANGACTION@,$USE_LANGACTION,;t t
+s,@USE_CORBA@,$USE_CORBA,;t t
+s,@MICO_DIR@,$MICO_DIR,;t t
+s,@USE_Z3950@,$USE_Z3950,;t t
+s,@USE_YAZ@,$USE_YAZ,;t t
+s,@ENABLE_ACCENTFOLD@,$ENABLE_ACCENTFOLD,;t t
+s,@USE_SQLITE@,$USE_SQLITE,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@CC@,$CC,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CXX@,$CXX,;t t
+s,@CXXFLAGS@,$CXXFLAGS,;t t
+s,@ac_ct_CXX@,$ac_ct_CXX,;t t
+s,@AWK@,$AWK,;t t
+s,@YACC@,$YACC,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@target@,$target,;t t
+s,@target_cpu@,$target_cpu,;t t
+s,@target_vendor@,$target_vendor,;t t
+s,@target_os@,$target_os,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@LN_S@,$LN_S,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@COMPAT32BITFLAGS@,$COMPAT32BITFLAGS,;t t
+s,@MICO_VER@,$MICO_VER,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@U@,$U,;t t
+s,@ANSI2KNR@,$ANSI2KNR,;t t
+s,@ALLOCA@,$ALLOCA,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@STATIC@,$STATIC,;t t
+s,@gsdlos@,$gsdlos,;t t
+s,@MODULEDIRS@,$MODULEDIRS,;t t
+s,@subdirs@,$subdirs,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+#
+# CONFIG_SUBDIRS section.
+#
+if test "$no_recursion" != yes; then
+
+  # Remove --cache-file and --srcdir arguments so they do not pile up.
+  ac_sub_configure_args=
+  ac_prev=
+  for ac_arg in $ac_configure_args; do
+    if test -n "$ac_prev"; then
+      ac_prev=
+      continue
+    fi
+    case $ac_arg in
+    -cache-file | --cache-file | --cache-fil | --cache-fi \
+    | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+      ac_prev=cache_file ;;
+    -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+    | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \
+    | --c=*)
+      ;;
+    --config-cache | -C)
+      ;;
+    -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+      ac_prev=srcdir ;;
+    -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+      ;;
+    -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+      ac_prev=prefix ;;
+    -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+      ;;
+    *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+    esac
+  done
+
+  # Always prepend --prefix to ensure using the same prefix
+  # in subdir configurations.
+  ac_sub_configure_args="--prefix=$prefix $ac_sub_configure_args"
+
+  ac_popdir=`pwd`
+  for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue
+
+    # Do not complain, so a configure script can configure whichever
+    # parts of a large source tree are present.
+    test -d $srcdir/$ac_dir || continue
+
+    { echo "$as_me:$LINENO: configuring in $ac_dir" >&5
+echo "$as_me: configuring in $ac_dir" >&6;}
+    { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+    cd $ac_dir
+
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      ac_sub_configure="$SHELL '$ac_srcdir/configure.gnu'"
+    elif test -f $ac_srcdir/configure; then
+      ac_sub_configure="$SHELL '$ac_srcdir/configure'"
+    elif test -f $ac_srcdir/configure.in; then
+      ac_sub_configure=$ac_configure
+    else
+      { echo "$as_me:$LINENO: WARNING: no configuration information is in $ac_dir" >&5
+echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
+      ac_sub_configure=
+    fi
+
+    # The recursion is here.
+    if test -n "$ac_sub_configure"; then
+      # Make the cache file name correct relative to the subdirectory.
+      case $cache_file in
+      [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;;
+      *) # Relative path.
+	ac_sub_cache_file=$ac_top_builddir$cache_file ;;
+      esac
+
+      { echo "$as_me:$LINENO: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
+echo "$as_me: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
+      # The eval makes quoting arguments work.
+      eval $ac_sub_configure $ac_sub_configure_args \
+	   --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir ||
+	{ { echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5
+echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+
+    cd $ac_popdir
+  done
+fi
+
+
+
Index: /gsdl/stable/common-src/configure.in
===================================================================
--- /gsdl/stable/common-src/configure.in	(revision 20131)
+++ /gsdl/stable/common-src/configure.in	(revision 20131)
@@ -0,0 +1,352 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl Use autoconf-2.59 or later... it might not work anymore with
+dnl the older 2.1x versions - jrm21 12/2004
+AC_INIT(src/lib/text_t.h)
+AC_CONFIG_HEADER(config.h)
+
+
+
+
+PACKAGE=gsdl
+VERSION=2.82-svn
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+dnl
+dnl Set use of fast cgi
+dnl
+USE_FASTCGI=0
+if test USE_FASTCGI = 1; then
+AC_DEFINE(USE_FASTCGI)
+AC_SUBST(USE_FASTCGI)
+fi
+
+dnl
+dnl Set use of langaction
+dnl
+dnl USE_LANGACTION=0
+if test USE_LANGACTION = 1; then
+AC_DEFINE(USE_LANGACTION)
+AC_SUBST(USE_LANGACTION)
+fi
+
+dnl
+dnl Set use of corba
+dnl
+AC_ARG_ENABLE(corba, [  --enable-corba          Enable CORBA support], USE_CORBA=1, USE_CORBA=0)
+AC_DEFINE_UNQUOTED(USE_CORBA, $USE_CORBA)
+AC_SUBST(USE_CORBA)
+
+AC_ARG_WITH(micodir, [  --with-micodir          Use installed MICO directory], MICO_DIR=$enableval, MICO_DIR="default")
+AC_DEFINE_UNQUOTED(MICO_DIR, "$MICO_DIR")
+AC_SUBST(MICO_DIR)
+
+dnl
+dnl Set use of z39.50
+dnl
+AC_ARG_ENABLE(z3950, [  --enable-z3950          Enable Z39.50 client support], USE_Z3950=1, USE_Z3950=0)
+if test USE_Z3950 = 1; then
+AC_DEFINE(USE_Z3950, $USE_Z3950)
+AC_SUBST(USE_Z3950)
+fi
+
+dnl
+dnl Set use of yaz - now compiled by default even when z3950 support not required
+dnl
+AC_ARG_ENABLE(yaz, [  --disable-yaz           Disable YAZ compilation], USE_YAZ=0, USE_YAZ=1)
+dnl if test USE_YAZ = 1; then
+AC_DEFINE(USE_YAZ, $USE_YAZ)
+AC_SUBST(USE_YAZ)
+dnl fi
+
+dnl 
+dnl disable compilation of accent folding stuff for mgpp (and one day mg)
+dnl
+AC_ARG_ENABLE(accentfold, [  --disable-accentfold    Disable Accent Folding for MGPP], ENABLE_ACCENTFOLD=0, ENABLE_ACCENTFOLD=1)
+AC_DEFINE(ENABLE_ACCENTFOLD, $ENABLE_ACCENTFOLD)
+AC_SUBST(ENABLE_ACCENTFOLD)
+
+dnl
+dnl Set use of SQLite (enabled by default)
+dnl
+AC_ARG_ENABLE(sqlite, [  --disable-sqlite        Disable SQLite support], USE_SQLITE=0, USE_SQLITE=1)
+AC_DEFINE(USE_SQLITE, $USE_SQLITE)
+AC_SUBST(USE_SQLITE)
+
+dnl Checks for programs.
+LDFLAGS=$LDFLAGS
+AC_SUBST(LDFLAGS)
+dnl only set CFLAGS if not already set in environment
+if test -z "$CFLAGS"; then
+CFLAGS=-O2
+fi
+AC_SUBST(CFLAGS)
+
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_AWK
+AC_PROG_YACC
+dnl get $target_cpu, $target_vendor, and $target_os
+dnl (as well as host_*)
+AC_CANONICAL_SYSTEM
+dnl do we actually want this? It adds a prefix based on host, system etc
+dnl AC_ARG_PROGRAM
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+
+AC_MSG_CHECKING(to see if architecture is 64-bit)
+arch_64bit=no
+case "$host_cpu" in
+x86_64) arch_64bit=yes ;;
+esac
+
+if test "$arch_64bit" = yes; then
+  AC_MSG_RESULT(yes)
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS="-m32"
+  fi
+else
+  AC_MSG_RESULT(no)
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS=
+  fi
+fi
+export COMPAT32BITFLAGS
+AC_SUBST(COMPAT32BITFLAGS)
+
+
+#moved CORBA MICO directory test to get version of MICO
+if test $USE_CORBA = 1; then
+
+if test $MICO_DIR = "default"; then
+#do something
+MICO_INC="-I packages/mico/mico/include"
+else
+#build the micotest program
+MICO_INC= ""
+if test $MICO_DIR != yes; then
+MICO_INC="-I $MICO_DIR"
+fi
+fi
+
+#get MICO_VER value
+sh -c "$CC -c micotest.cpp -o micotest.o $MICO_INC 2>&1" > /dev/null
+sh -c "$CC -o micotest micotest.o -lstdc++ 2>&1" > /dev/null
+MICO_VER=`./micotest` || MICO_VER=2.3.5
+sh -c "rm micotest"
+sh -c "rm micotest.o"
+
+#do test of MICO_VER
+if test MICO_VER != 0; then
+AC_DEFINE(MICO_VER)
+AC_SUBST(MICO_VER)
+fi
+#end USE_CORBA test
+fi
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_AIX
+AC_ISC_POSIX
+AC_MINIX
+fp_C_PROTOTYPES
+AC_C_CONST
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl --- This should be in the stdc checking -----------------
+if test "$ac_cv_prog_cc_stdc" = '-Xc'; then
+dnl The Pyramids running SMP_DC.OSx on MIPS r3000 chips with
+dnl /usr/opt/cc3.11/bin/cc treat -Xc as full ANSI mode - no POSIX or
+dnl XOPEN extensions (like popen).
+dnl Unfortunately -D_{XOPEN,POSIX}_SOURCE can't provide all that mg
+dnl needs. So drop back to -Xa
+AC_TRY_COMPILE(
+[#include <stdio.h>
+], [ FILE *rubbish = popen("yes", "r"); ],,
+[CC="`echo $CC | sed 's/-Xc/-Xa/'`"    ac_cv_prog_cc_stdc='-Xa'])
+fi
+dnl ----------------------
+
+
+dnl Checks for libraries.
+dnl check for -lg:
+AC_HAVE_LIBRARY(g)
+dnl check for -lm:
+AC_HAVE_LIBRARY(m)
+dnl check for -lcrypt:
+AC_HAVE_LIBRARY(crypt)
+if test $ENABLE_ACCENTFOLD = 1; then
+AC_HAVE_LIBRARY(iconv)
+fi
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h limits.h sys/time.h unistd.h crypt.h string.h memory.h sys/procfs.h sys/stat.h)
+AC_EGREP_HEADER(fread, stdio.h, AC_DEFINE(HAVE_FREAD_DECL))
+AC_EGREP_HEADER(fgetc, stdio.h, AC_DEFINE(HAVE_FGETC_DECL))
+AC_EGREP_HEADER(pr_brksize, sys/procfs.h, AC_DEFINE(HAVE_PR_BRKSIZE))
+
+dnl Checks for library functions.
+AC_FUNC_ALLOCA
+AC_PROG_GCC_TRADITIONAL
+AC_TYPE_SIGNAL
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(ftime select strftime strtol getrusage times mallinfo setbuffer getpagesize strerror)
+AC_REPLACE_FUNCS(ftruncate strstr strcasecmp)
+
+dnl see if gettext is in libc. (try the textdomain() function).
+AC_CHECK_FUNC(textdomain, AC_DEFINE(ENABLE_NLS ,1) )
+
+# *** Custom checking (based on GNU tar configure.in) ***
+# ---------------------------------------------------------------------------
+AC_MSG_CHECKING(for HP-UX needing gmalloc)
+if test "`(uname -s) 2> /dev/null`" = 'HP-UX'; then
+  AC_MSG_RESULT(yes)
+  AC_LIBOBJ([gmalloc])
+  AC_DEFINE(HAVE_VALLOC)
+else
+  AC_MSG_RESULT(no)
+  AC_CHECK_FUNCS(valloc)
+fi
+
+# we cannot generate static libraries under Darwin
+AC_MSG_CHECKING(for Apple MacOS X/Darwin)
+if test "`(uname -s) 2> /dev/null`" = 'Darwin'; then
+  AC_MSG_RESULT(yes)
+  STATIC=""
+else
+  AC_MSG_RESULT(no)
+  STATIC="-static "
+fi
+AC_SUBST(STATIC)
+
+fp_WITH_DMALLOC
+fp_WITH_REGEX
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+dnl    support functions for alloca.c
+  AC_LIBOBJ([xmalloc])
+  AC_LIBOBJ([error])
+fi
+
+
+# ---------------------------------------------------------------------------
+
+dnl
+dnl Switch into C++
+dnl
+AC_LANG_CPLUSPLUS
+
+dnl
+dnl Check if the STL library has any known faults;
+dnl In GCC 2.7.2.x series, some STL library headers are missing
+dnl a file called "new" which is referred to by other headers
+dnl (eg. vector/vector.h); if this applies, then all use of the
+dnl STL will cause a compile fail, so we'd better let the user
+dnl know now, before things really go wrong!
+dnl
+success=no
+AC_MSG_CHECKING("whether STL library has known faults")
+
+dnl - first shot, try simple good old vector on its own
+AC_TRY_COMPILE(
+[#include <vector>
+], 
+[],
+success=yes,
+)
+
+dnl - try using the .h equivalent
+if test $success = "no"; then
+AC_TRY_COMPILE(
+[#include <vector.h>
+], 
+[],
+success="yes",
+)
+fi
+
+dnl - now try for the objectspace headers
+if test $success = "no"; then
+AC_TRY_COMPILE(
+[#include <ospace\\std\\vector>
+], 
+[],
+success="yes",
+)
+fi
+
+if test $success = yes; then
+AC_MSG_RESULT("no")
+else
+AC_MSG_RESULT("yes")
+AC_MSG_ERROR("STL Broken - Obtain newer version of GNU C Compiler")
+fi
+
+gsdlos=`uname | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+# check for running bash under cygwin
+ if test "`echo $gsdlos | sed 's/cygwin//'`" != "$gsdlos" ;
+ then
+  gsdlos=windows
+ fi
+AC_SUBST(gsdlos)
+
+# check for endianness
+AC_C_BIGENDIAN
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+dnl    support functions for alloca.c
+  AC_LIBOBJ([xmalloc.o])
+  AC_LIBOBJ([error])
+fi
+
+# ---------------------------------------------------------------------------
+
+
+dnl
+dnl Locate all children of the modules folder
+dnl
+moduleDirs=""
+MODULEDIRS=""
+if test -d modules ; then
+  for x in `find modules -mindepth 1 -maxdepth 2`; do
+    if test -d "$x"; then
+      d="$x/Makefile.in"
+      if test -e "$d"; then
+  dnl      echo $d
+        moduleDirs="$moduleDirs $x/Makefile"
+        MODULEDIRS="$MODULEDIRS $x"
+      fi
+    fi
+  done
+  echo "Making $moduleDirs in modules directory"
+  AC_SUBST(MODULEDIRS)
+fi
+
+
+# ---------------------------------------------------------------------------
+
+AC_CONFIG_SUBDIRS(packages indexers)
+
+# the list of folders in the src folder
+srclist="src/lib/Makefile \
+         src/gdbmedit/db2txt/Makefile \
+         src/gdbmedit/txt2db/Makefile \
+         src/gdbmedit/gdbmget/Makefile \
+         src/gdbmedit/gdbmset/Makefile \
+	 src/gdbmedit/gdbmkeys/Makefile \
+	 src/gdbmedit/gdbmdel/Makefile \
+         src/getpw/Makefile"
+
+AC_OUTPUT(packages/Makefile Makefile $srclist $moduleDirs)
+
+
Index: /gsdl/stable/common-src/install-sh
===================================================================
--- /gsdl/stable/common-src/install-sh	(revision 20131)
+++ /gsdl/stable/common-src/install-sh	(revision 20131)
@@ -0,0 +1,238 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
Index: /gsdl/stable/common-src/packages/Makefile.in
===================================================================
--- /gsdl/stable/common-src/packages/Makefile.in	(revision 20131)
+++ /gsdl/stable/common-src/packages/Makefile.in	(revision 20131)
@@ -0,0 +1,69 @@
+###########################################################################
+#
+# Makefile -- Makefile for packages shared between Greenstone build and runtime
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2000 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+USE_SQLITE=@USE_SQLITE@
+
+ifeq ($(USE_SQLITE), 1)
+SQLITE_DIR = sqlite/sqlite-amalgamation-3.5.9
+else
+SQLITE_DIR = 
+endif
+
+# PACKAGEDIRS contains the packages that we want to make and install.  It
+# is assumed that each package will have at least four rules: all, install,
+# clean, and distclean.
+PACKAGEDIRS =	expat gdbm $(SQLITE_DIR) search4j
+
+
+all:
+	for odir in $(PACKAGEDIRS); do \
+          echo making $@ in $$odir; \
+          (cd $$odir && $(MAKE) $(MDEFINES) $@) || exit 1; \
+        done
+ifeq ($(USE_SQLITE), 1)
+# need to do make install in sqlite to get the header files and library into the right place
+	cd $(SQLITE_DIR) && $(MAKE) $(MDEFINES) install
+endif
+
+
+install:
+	for idir in $(PACKAGEDIRS); do \
+          echo installing $$idir; \
+          (cd $$idir && $(MAKE) install) || exit 1; \
+        done
+
+clean:
+	for subdir in $(PACKAGEDIRS); do \
+          echo cleaning $@ in $$subdir; \
+          (cd $$subdir && $(MAKE) clean || exit 0) ; \
+        done
+
+distclean:
+	for subdir in $(PACKAGEDIRS); do \
+          echo cleaning $@ in $$subdir; \
+          (cd $$subdir && $(MAKE) distclean || exit 0) ; \
+        done
Index: /gsdl/stable/common-src/packages/configure
===================================================================
--- /gsdl/stable/common-src/packages/configure	(revision 20131)
+++ /gsdl/stable/common-src/packages/configure	(revision 20131)
@@ -0,0 +1,180 @@
+#! /bin/sh
+
+PACKAGES=`pwd`
+cd ../..
+GSDLHOME=`pwd`
+cd $PACKAGES
+
+GSDLOS=`uname -s |tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+# check for running bash under cygwin
+if test "`echo $GSDLOS | sed 's/cygwin//'`" != "$GSDLOS" ;
+then
+ GSDLOS=windows
+fi
+
+prefix=""
+bindir=""
+HOSTTARGETFLAGS=""
+
+# only some of the packages can take environment variables as options to 
+# configure 
+# format is VAR=value, e.g "LDFLAGS=-static"
+ENVIRONMENT=""
+
+# SQLite support enabled by default, can switch it off with --disable-sqlite
+USE_SQLITE=true
+# yaz compilation enabled by default, can switch it off with --disable-yaz
+USE_YAZ=true
+# z3950 server disabled by default, switch it on with --enable-z3950
+USE_Z3950=false
+# CORBA support disabled by default, switch it on with --enable-corba
+USE_CORBA=false
+MICO_DIR=default
+
+# parse any arguments given from toplevel configure
+while test $# -ne 0; do
+    case "$1" in
+	--cache-file=*)
+	    cache_filename=`echo $1 | sed s/--cache-file=//`
+	    # turn relative path into an absolute path
+	    cache_dir=`echo $cache_filename | sed 's@/[^/]*$@@'`
+	    cache_dir=`cd $cache_dir 2>/dev/null && pwd`
+
+	    cache_basefile=`echo $cache_filename | sed 's@.*/@@'`
+	    cache_file="$cache_dir/$cache_basefile"
+	    if test ! -f "$cache_file"; then
+		CACHE_FILE=""
+	    else
+		CACHE_FILE="--cache-file=$cache_file"
+	    fi
+	    ;;
+	--disable-sqlite)
+	    USE_SQLITE=false
+	    ;;
+	--disable-yaz)
+	    USE_YAZ=false
+	    ;;
+	--enable-z3950)
+	    USE_Z3950=true
+	    ;;
+	--enable-corba)
+	    USE_CORBA=true
+	    ;;
+	--with-micodir=*)
+	    if test $1 = ""; then
+	      $1 = "default"
+            fi
+	    MICO_DIR=$1
+	    ;;       
+	--prefix=*)
+	    prefix=`echo $1 | sed s/--prefix=//`
+	    ;;
+	--bindir=*)
+	    # where to install binaries to
+	    bindir=`echo $1 | sed s/--bindir=//`
+	    # turn relative path into an absolute path
+	    if test -d "$bindir" ; then
+	      bindir=`cd "$bindir" ; pwd `
+	      cd "$PACKAGES"
+	    elif test -z `echo $bindir | sed '/^\// p;D'` ; then
+	      rel_bindir="`echo $bindir | sed s@/.*@@`"
+	      cd "$rel_bindir"
+	      bindir="`pwd`/`echo $bindir | sed s@^[^/]*/@@`"
+	      cd "$PACKAGES"
+	    else
+	      # bindir doesn't exist, and isn't relative
+	      true
+	    fi
+	    ;;
+	--host=* | --target=*)
+	    HOSTTARGETFLAGS="$HOSTTARGETFLAGS $1"
+	    ;;
+	*)
+	    # ignore all other options for now
+	    ;;
+    esac
+    shift
+done
+
+# note! Our GSDL package currently always installs into it's source
+# directory, ignoring any --prefix given to configure.
+# When this is fixed, uncomment the relevant lines below...
+
+##if test -z "$prefix" ; then
+prefix="${GSDLHOME}"
+##fi
+
+##if test -z "$bindir" ; then
+bindir="${prefix}/bin/$GSDLOS"
+##fi
+
+# This loads the top configure's cache file, with variables already set.
+if test -f "$cache_file" ; then
+  . $cache_file
+fi
+
+# we assume that gzip and tar are on the search path.
+# non-GNU versions of tar don't take the -z option.
+
+
+
+# configure expat (needs to be done before XML::Parser
+echo ""
+echo "Configuring expat"
+echo ""
+cd "$PACKAGES/expat"
+if test ! -d expat-1.95.8 ;
+then
+  gzip -dc expat-1.95.8.tar.gz | tar -xf -
+fi
+
+echo CFLAGS="$CFLAGS $COMPAT32BITFLAGS" CXXFLAGS="$CXXFLAGS $COMPAT32BITFLAGS" LDFLAGS="$LDFLAGS $COMPAT32BITFLAGS" ./configure $CACHE_FILE --disable-shared --with-pic --prefix=$PACKAGES/expat --bindir="$bindir" $HOSTTARGETFLAGS $ENVIRONMENT
+
+cd "$PACKAGES/expat/expat-1.95.8" && \
+CFLAGS="$CFLAGS $COMPAT32BITFLAGS" CXXFLAGS="$CXXFLAGS $COMPAT32BITFLAGS" LDFLAGS="$LDFLAGS $COMPAT32BITFLAGS" ./configure $CACHE_FILE --disable-shared --with-pic --prefix=$PACKAGES/expat --bindir="$bindir" $HOSTTARGETFLAGS $ENVIRONMENT
+
+
+# configure GDBM
+echo ""
+echo "Configuring GDBM"
+echo ""
+cd "$PACKAGES/gdbm"
+
+echo CFLAGS="$CFLAGS $COMPAT32BITFLAGS" CXXFLAGS="$CXXFLAGS $COMPAT32BITFLAGS" LDFLAGS="$LDFLAGS $COMPAT32BITFLAGS" ./configure $CACHE_FILE --disable-shared --prefix=$PACKAGES/gdbm $HOSTTARGETFLAGS $ENVIRONMENT
+
+cd "$PACKAGES/gdbm/gdbm-1.8.3" && \
+CFLAGS="$CFLAGS $COMPAT32BITFLAGS" CXXFLAGS="$CXXFLAGS $COMPAT32BITFLAGS" LDFLAGS="$LDFLAGS $COMPAT32BITFLAGS" ./configure $CACHE_FILE --disable-shared --prefix=$PACKAGES/gdbm $HOSTTARGETFLAGS $ENVIRONMENT
+
+
+# configure SQLite
+echo ""
+echo "Configuring SQLite"
+if test x$USE_SQLITE = xtrue ; 
+then
+  echo ""
+  cd "$PACKAGES/sqlite"
+  if test ! -d sqlite-amalgamation-3.5.9 ;
+  then
+    gzip -dc sqlite-amalgamation-3.5.9.tar.gz | tar -xf -
+  fi
+
+  echo CFLAGS="$CFLAGS $COMPAT32BITFLAGS" CXXFLAGS="$CXXFLAGS $COMPAT32BITFLAGS" LDFLAGS="$LDFLAGS $COMPAT32BITFLAGS" ./configure $CACHE_FILE --prefix="$PACKAGES/sqlite" --bindir="$bindir" $HOSTTARGETFLAGS $ENVIRONMENT
+
+  cd "$PACKAGES/sqlite/sqlite-amalgamation-3.5.9" && \
+  CFLAGS="$CFLAGS $COMPAT32BITFLAGS" CXXFLAGS="$CXXFLAGS $COMPAT32BITFLAGS" LDFLAGS="$LDFLAGS $COMPAT32BITFLAGS" ./configure $CACHE_FILE --prefix="$PACKAGES/sqlite" --bindir="$bindir" $HOSTTARGETFLAGS $ENVIRONMENT
+else
+  echo "SQLite support disabled."
+  echo "  add '--enable-sqlite' to the configure command to include SQLite support."
+  echo ""
+fi
+
+# configure search4j
+echo ""
+echo "Configuring search4j"
+echo ""
+cd "$PACKAGES/search4j"
+
+echo CFLAGS="$CFLAGS $COMPAT32BITFLAGS" CXXFLAGS="$CXXFLAGS $COMPAT32BITFLAGS" LDFLAGS="$LDFLAGS $COMPAT32BITFLAGS" ./configure --bindir="$GSDLHOME/bin/$GSDLOS" $CACHE_FILE $HOSTTARGETFLAGS $ENVIRONMENT
+
+cd "$PACKAGES/search4j" && \
+ CFLAGS="$CFLAGS $COMPAT32BITFLAGS" CXXFLAGS="$CXXFLAGS $COMPAT32BITFLAGS" LDFLAGS="$LDFLAGS $COMPAT32BITFLAGS" ./configure --bindir="$GSDLHOME/bin/$GSDLOS" $CACHE_FILE $HOSTTARGETFLAGS $ENVIRONMENT
Index: /gsdl/stable/common-src/packages/expat/Makefile
===================================================================
--- /gsdl/stable/common-src/packages/expat/Makefile	(revision 20131)
+++ /gsdl/stable/common-src/packages/expat/Makefile	(revision 20131)
@@ -0,0 +1,12 @@
+
+all:
+	(cd expat-1.95.8 && $(MAKE) all installlib && cp lib/expat_external.h ../include)
+
+clean:
+	(cd expat-1.95.8 && $(MAKE) clean)
+
+distclean:
+	(cd expat-1.95.8 && $(MAKE) distclean)
+
+install:
+	@echo Expat installed
Index: /gsdl/stable/common-src/packages/gdbm/Makefile
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/Makefile	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/Makefile	(revision 20131)
@@ -0,0 +1,12 @@
+
+all:
+	(cd gdbm-1.8.3 && $(MAKE) all install)
+
+clean:
+	(cd gdbm-1.8.3 && $(MAKE) clean)
+
+distclean:
+	(cd gdbm-1.8.3 && $(MAKE) distclean)
+
+install:
+	@echo GDBM installed
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/COPYING
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/COPYING	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/COPYING	(revision 20131)
@@ -0,0 +1,346 @@
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+	Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/ChangeLog
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/ChangeLog	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/ChangeLog	(revision 20131)
@@ -0,0 +1,574 @@
+
+Tue Oct 15 15:00:11 PDT 2002	Jason Downs (downsj@downsj.com)
+
+	* samp1.cc: Remove.
+
+	* gdbm.3, gdbm.texinfo: 1.8.3.
+
+	* version.c: Version 1.8.3., modernize string (release date is in
+	  American format).
+
+	* gdbmreorg.c: Remove small memory leak.
+
+	* Makefile.in: Use more subs from configure, remove mention of SunOS.
+	  Add support for spec'ing an install time prefix via INSTALL_ROOT.
+
+	* INSTALL: Remove extra text from top.
+
+	* config.guess, config.sub: Update to latest versions.
+
+	* autoconf.h.in: Regenerate.
+
+	* configure.in: Modernize.
+
+	* systems.h: HAVE_ST_BLKSIZE -> HAVE_STRUCT_STAT_ST_BLKSIZE.
+
+Fri Sep 27 16:12:44 PDT 2002	Jason Downs (downsj@downsj.com)
+
+	* Makefile.in: Remove `info' target from all, since we don't even
+	  bother installing the one we built anyway.
+
+	* Fix a few checks against dbf.read_write.
+
+Wed Sep 25 15:19:00 PDT 2002	Jason Downs (downsj@downsj.com)
+
+	* Makefile.in: Remove the dbm and ndbm routines from the main
+	  library, moving them to gdbm_compat.  install-compat now
+	  installs the compat headers and the library.  Increment the
+	  MAJOR number of the shared library due to the removal of
+	  the compat functions.
+
+	* gdbm.3, gdbm.texinfo, version.c: 1.8.1; note gdbm_compat.
+
+	* proto.h: Change _gdbm_fatal() to void.
+
+	* update.c(_gdbm_fatal): Change function declaration to void.
+
+	* update.c(_gdbm_fatal): Change default exit status to 1.
+
+	* gdbmopen.c(gdbm_open): Remove setting of flags since we always check
+	  it against the mask.
+
+	* testdbm.c, testndbm.c: Added stdlib.h inclusions.
+
+	* falloc.c(push_avail_block): Fixed extremely rare case where the
+	  header avail table could fill up, causing us to over flow the
+	  table, corrupting memory, and eventually crashing.  Also forced
+	  merging of blocks within the scope of this routine (possibly
+	  should force them whenever the header avail table is being used).
+
+	* gdbmerrno.c: Fix error count, there are more than 18.
+
+	* gdbmerrno.h: Fix typo; GDBM_OPT_ILLEGAL is 20.
+
+	* gdbmopen.c: Fix typo; s/GDBM_OPENMASK/GDBM_WRITER/.
+
+Tue May 18 19:25:25 PDT 1999	Jason Downs	(downsj@downsj.com)
+
+	* gdbm.3, gdbm.texinfo: Update for 1.8.
+
+	* Makefile.in, configure.in: Switch to using libtool, but without
+	  automake.
+
+	* aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh: New
+	  files (libtool 1.2).
+
+Wed May 12 01:26:15 PDT 1999	Jason Downs	(downsj@downsj.com)
+
+	* gdbmopen.c, gdbmclose.c, gdbmreorg.c: check file_locking before
+	  calling locking macros; add support for setting GDBM_NOLOCK in
+	  gdbm_open().
+
+	* gdbmdefs.h: add file_locking flag to gdbm_file_info.
+
+	* gdbmconst.h, gdbm.proto: add GDBM_NOLOCK flag.
+
+	* gdbmfdesc.c: new file, adds external gdbm_fdesc() routine.
+
+	* gdbm.proto, gdbm.proto2: clean up, use __P, and compress.
+
+	* gdbmerrno.h: kill the enum, add defines for errors.
+
+	* gdbmsetopt.c, testgdbm.c: support GDBM_SYNC/GDBM_SYNCMODE.
+
+	* gdbmopen.c: gdbm_open() now DEFAULTS to ``fast mode''; use
+	  GDBM_SYNC to turn it off.  GDBM_FAST is obsolete and ignored.
+
+	* gdbmconst.h: add GDBM_SYNC and GDBM_SYNCMODE.
+
+	* proto.h, various source files: switch _ARGS to __P.
+
+	* systems.h, various source files: kill word_t, just use int
+	  everywhere.
+
+	* configure.in, autoconf.h.in: remove alloca() goo and modernize.
+
+	* many source files: replace all instances of alloca() with real
+	  malloc()s and free()s.
+
+	* update.c: don't deref NULL in _gdbm_fatal(), and don't use stdio.
+
+[  The following are entries revived from a dead experimental branch. ]
+
+Tue Nov  1 00:35:11 1994  Jason Downs  (downsj@downsj.com)
+
+	* gdbmopen.c (gdbm_open): actually initialize central_free and
+	  coalesce_blocks.
+
+	* gdbmdefs.h: added coalesce_blocks. these should've been bitmapped.
+	  oh well.
+
+	* falloc.c (various routines): made block merging an option.
+
+	* gdbmsetopt.c (gdbm_setopt): added GDBM_COALESCEBLKS option.
+
+	* gdbmconst.h: added GDBM_COALESCEBLKS option.
+
+Fri Jun  3 09:45:19 1994  Jason Downs  (downsj@downsj.com)
+        
+	* falloc.c (_gdbm_free): if central_free is set, all blocks are
+	  put into the header.
+        
+	* gdbmsetopt.c (gdbm_setopt): add GDBM_CENTFREE case.
+        
+	* gdbmdefs.h, gdbmconst.h, gdbm.proto: add central free option.
+
+Fri Jun  3 05:57:36 1994  Jason Downs  (downsj@downsj.com)
+
+	* falloc.c (pop_avail_block): merge block with header, instead
+	  of replace, since header may not be empty any longer.
+
+	* falloc.c (_gdbm_alloc): pop a block off the stack when the
+	  current header is half empty, instead of zero.
+
+Fri Jun  3 05:11:33 1994  Jason Downs  (downsj@downsj.com)
+
+	* gdbmstore.c (gdbm_store): don't alloc new disk if we're replacing
+	  and the records are the same size. suggested by phil a long time
+	  ago.
+
+Fri Jun  3 03:47:46 1994  Jason Downs  (downsj@downsj.com)
+        
+	* falloc.c (_gdbm_put_av_elem): allow adjacent blocks to be
+	  merged. inspired by the enhancement by Tim Howes.
+
+Thu Jun  2 22:15:19 1994  Jason Downs  (downsj@downsj.com)
+
+	* Makefile.in: add installation mode, owner, and group.
+
+Thu Jun  2 04:24:58 1994  Jason Downs  (downsj@downsj.com)
+
+	* Makefile.in: run mkinstalldirs before installing files.
+
+	* mkinstalldirs: new file.
+
+[ End of revived entries. ]
+
+Thu May 19 15:50:04 1994  Jason Downs  (downsj@downsj.com)
+	
+	* NEWS, README: update to 1.7.3.
+	
+	* gdbm.texinfo: update to 1.7.3, slight fixes.
+
+	* gdbm.3: update to 1.7.3, slight reformat.
+
+Thu May 19 14:45:51 1994  Jason Downs  (downsj@downsj.com)
+
+	* gdbmconst.h: removed the header magic numbers from this
+	  branch.
+
+	* version.c: added an include of autoconf.h, updated version
+
+	* gdbm.proto: added a define for GDBM_FASTMODE.
+
+Sun May 15 02:39:48 1994  Jason Downs  (downsj@downsj.com)
+
+	* gdbm.3, gdbm.texinfo: updates for 1.7.2
+	
+	* README, NEWS, version.c: update for 1.7.2
+	
+	* Makefile.in: removed files, changed (drastically) how the
+	  package compiles and installs.
+
+	* bytewise.c, bytewise.h: removed from this branch.
+
+Wed Mar 23 00:44:43 1994  Jason Downs  (downsj@downsj.com)
+
+	* extern.h: removed bogus (old) function declarations.
+
+Mon Mar 14 01:37:09 1994  Jason Downs  (downsj@downsj.com)
+
+	* Makefile.in: added new files.
+
+	* bytewise.c, bytewise.h: new portable byte order conversion
+	  package; supports 64bit longs/16bit ints.
+
+Sun Mar 13 22:56:10 1994  Jason Downs  (downsj@downsj.com)
+
+	* gdbmsetopt.c, gdbmconst.h: added GDBM_FASTMODE option.
+
+	* falloc.c: taught _gdbm_alloc() about the header avail table.
+	  hopefully, this will fix the bloating problem. i dunno, though,
+	  as i've never had that problem, myself.
+
+Sun Dec 26 05:17:04 1993  Jason Downs  (downsj@downsj.com)
+
+	* version.c: made gdbm_version const.
+
+	* gdbmerrno.c: made gdbm_strerror() and it's array const.
+
+	* various files: general clean up, reformating of code.
+
+	* systems.h: put <memory.h> inside of a conditional.
+
+	* configure.in, autoconf.h.in: added check for <memory.h>.
+
+	* systems.h: added a default define of SEEK_SET.
+
+	* bucket.c, gdbmopen.c, gdbmseq.c, gdbmdelete.c, gdbmdefs.h:
+	  cleaned up some uses of word_t.
+
+Tue Nov 16 03:11:56 1993  Jason Downs  (downsj@downsj.com)
+
+	* gdbm.3, gdbm.texinfo: updated versions to 1.3 for release
+
+	* version.c, README, NEWS: updated versions to 1.7.1 for release
+
+Sun Nov 14 17:21:03 1993  Jason Downs  (downsj@downsj.com)
+
+	* Makefile.in: added $(srcdir) to a few file references.
+
+Sat Nov 13 13:56:37 1993  Jason Downs  (downsj@downsj.com)
+
+	* gdbm.3, gdbm.texinfo: added new gdbm_firstkey()/gdbm_nextkey()
+	  documentation.
+
+	* gdbmopen.c: added SGI alloca patch.
+
+	* Makefile.in: changed installation prefix semantics.
+
+Sat Nov 13 01:52:31 1993  Jason Downs  (downsj@downsj.com)
+
+	* various source: redid the AIX alloca declaration. any new files
+	  that call alloca will have to start with the same header.
+
+	* all source, configure.in, Makefile.in: switched over to using
+	  autoconf.h, rather than packing all of the autoconf defs into
+	  the DEFS line.
+
+	* autoconf.h.in: new file.
+
+	* Makefile.in: changed rule for tndbm.o, hopefully making it more
+	  portable.
+
+	* alloca.c: added inclusion of stdlib.h
+
+Fri Nov 12 13:11:03 1993  Jason Downs  (downsj@downsj.com)
+
+	* Makefile.in, configure.in: fixed getop related bugs.
+
+	* systems.h: moved sys/types.h include to top.
+
+Wed Nov  3 17:18:59 1993  Jason Downs  (downsj@downsj.com)
+
+	* version.c: changed version to 1.7, for release.
+
+	* gdbmdefs.h: Moved all system includes to systems.h.
+
+Sun Oct 31 02:50:12 1993  Jason Downs  (downsj@downsj.com)
+
+	* version.c: changed version number to 1.7alpha.
+
+	* gdbm.texinfo: updated to reflect new routines and changes.
+	
+	* getopt.c, getopt.h: Added the GNU getopt.c to the dist, for
+	  compilation of testgdbm and conv2gdbm on machines without getopt().
+	
+	* various source files: changed all appropiate occurances of 'long'
+	  to type 'off_t'. Added off_t check to configure.in.
+
+	* gdbm.3: updated to reflect new routines and changes.
+
+Sat Oct 30 05:20:45 1993  Jason Downs  (downsj@downsj.com)
+
+        * testgdbm.c: Added support for bucket cache and block sizes,
+	  adding -c, -b and -g flags. Must use -g to specify the file
+          name, now.
+
+	* bucket.c, gdbmopen.c, gdbmclose.c, gdbmreorg.c, update.c,
+	  gdbmconst.h, gdbmdefs.h: Implemented dynamic, delayed
+	  initialization, bucket cache. New routine: _gdbm_init_cache().
+
+	* proto.h, gdbmerrno.c, gdbmerrno.h: Added gdbm_setopt() errors
+	  and prototypes.
+
+	* gdbmsetopt.c: New file, implements the gdbm_setopt() routine.
+
+	* testgdbm.c, testndbm.c, testdbm.c, conv2gdbm.c: cleaned up
+	  compiler warnings.
+
+	* update.c: repaired declarations and added prototypes for
+	  static routines, repaired declaration of _gdbm_fatal().
+
+	* falloc.c: repaired declarations and added prototypes for
+	  static routines.
+
+	* gdbmstore.c: commented out unsed variables in gdbm_store().
+
+	* proto.h: added prototypes for _gdbm_read_entry(),
+	  _gdbm_find_key(), and gdbm_sync().
+
+	* bucket.c, proto.h: changed _gdbm_get_bucket() and
+	  _gdbm_write_bucket() over to type void.
+
+Sat Oct 30 00:56:24 1993  Jason Downs  (downsj@downsj.com)
+
+	* gdbmerrno.c, gdbmexists.c, close.c, dbmrdonly.c: New files,
+	  adding the routines gdbm_strerror(), gdbm_exists(), and for
+	  better compatibility with the old dbm/ndbm libraries, the
+	  dbmclose() and dbm_rdonly() routines.
+
+	* various headers: Added prototypes for the new routines, and
+	  rearranged how gdbm.h is generated.
+
+Fri Oct 29 07:02:41 1993  Jason Downs  (downsj@downsj.com)
+
+	* README: split into README, INSTALL, and NEWS.  INSTALL
+	  includes more tips on compiling.  NEWS contains the 'short form'
+	  ChangeLog.
+	
+	* Makefile.in, configure.in: Redid parts of the autoconf
+	  stuff, and repaired many bugs.
+
+	* systems.h: Repaired the alloca declarations, among other
+	  things.
+
+	* various source files: changed all relevant usage of type
+	  'long' to type 'word_t', which will always be 32bits wide.
+	  'word_t' is defined in systems.h.
+
+Fri Jul 30 13:27:24 1993  Phil Nelson  (phil@cs.wwu.edu)
+
+	* findkey.c: Added a check of elem_loc == -1 in determining if
+	  the data cache held the item being looked for.
+
+Tue Jul 20 13:08:47 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+	* gdbm.texinfo: Fixed some errors.
+
+	* Makefile.in: Fixed some errors.
+
+ 	* version.c: Set version to 1.6 for release.
+
+Mon Jul 19 15:02:40 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+	* COPYING: Replaced Version 1 with Version 2.  Also updated
+	  all file notices to refer to version 2.
+
+	* gdbm.texinfo: Updated the documentation.
+
+	* README: Updated to current version.
+
+	* Makefile: updated clean and install.
+
+Wed Jul 14 13:37:44 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+	* Makfile.in: Added samp1.cc to the list of distributed files.
+
+Sat Jun  5 21:35:59 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+	* gdbm.proto, Makefile.in: Added #ifndef _GDBM_H_ protection
+	  for the final gdbm.h file.  Also added prototypes and C++
+	  support.
+
+	* gdbmseq.c: Added gdbm_errno initialization to gdbm_nextkey.
+
+	* gdbmerrno.h and others: Moved the extern definition of
+	  gdbm_erron to gdbmerrno.h from the other files.
+
+Mon May 17 12:32:02 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+	* gdbm.proto: Added GDBM_FAST to the read_write flags.
+
+Sun May 16 12:50:01 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+	* configure.in, Makefile.in: Added autoconf configuration
+	  to gdbm.
+
+Tue Mar 30 00:08:48 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+	* global.c: Set gdbm_errno to GDBM_NO_ERROR to force
+	  it into the data segment.
+
+Sun Mar 28 22:51:40 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+	* gdbmfetch.c: Set return_val.dsize to 0 as a default return
+	  value.  (I was told that was more compatible with dbm/ndbm.)
+
+	* gdbmopen.c: Changed a "sizeof(int)" to "sizeof(long)".
+
+	* testgdbm.c: Changed "char opt" to "int opt" to make sure
+	  opt can be -1.
+
+	* hash.c: Added "unsigned" to declaration of value for
+	  better overflow operation.
+
+	* gdbmreorg.c: Added a free for data.dptr in the main loop.
+	  Also changed the malloc for new_name to an alloca.
+	  Removed all frees on new_name.
+
+Sat Mar 27 23:25:14 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+	* gdbmconst.h, gdbmdefs.h, gdbmopen.c, gdbmreorg.c,
+	  testgdbm.c, update.c, gdbm.h: Added code to allow for a
+	  GDBM_FAST mode in which fsync is not called during
+	  database update mode. Added a new flag "-f" to 
+	  testgdbm to make use of the new fast mode.
+
+	* gdbmsync.c: Added this function to allow a programmer
+	  to use the GDBM_FAST mode but still be able to sync
+	  a database.
+
+	* gdbmopen.c, gdbmdelete.c, gdbmfetch.c, gdbmseq.c, gdbmstore.c,
+	  gdbmreorg.c: Added initialization of gdbm_errno to GDBM_NO_ERROR.
+
+Mon Mar 22 23:03:36 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+	* gdbmclose.c: (gdbmclose) Added a fsync before close to make
+	  sure the file is written to disk before continuing.
+
+Sun Mar 21 21:33:31 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+	* proto.h: Added this as a new file.  It adds ANSI prototypes
+	  for ANSI compilers.
+
+	* gdbmdefs.h: Added an include of proto.h.
+
+	* Makefile: Added proper references to proto.h
+
+	* gdbmopen.c: Changed (int *) casts to (long *) and added
+	  an initialization to dbf->header.
+
+	* gdbmreorg.c: Added an "end update" on the new database and
+	  correctly set up the bucket cache.
+
+	* update.c: (_gdbm_end_update) Added type void to header.
+
+Wed Mar 17 19:14:27 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+	* Changed copyright on all files to include 1993.  Also deleted
+	  all references to my phone number.
+
+Thu Feb 28 17:05:09 1991  Phil Nelson  (phil at strawberry.cs.wwu.edu)
+
+	* Added 1991 to copyright lines on all files.
+
+	* gdbmfetch.c: Fixed a bug introduced by previous changes.
+
+	* version.c:  Updated version to 1.5.
+
+Fri Feb  8 12:27:13 1991  Phil Nelson  (phil at strawberry.cs.wwu.edu)
+
+	* Change author's e-mail address in all comments.
+
+	* gdbmopen.c, systems.h: Changed opening sequence so that a
+	  database will not be truncated in NEWDB mode until the
+	  write has locked the file.
+
+	* testgdbm.c: Fixed a bug that caused a segmentation fault on
+	  one computer.  Also added the flags "-r" for opening the
+	  database as a READER and "-n" for opening the database as
+	  a NEWDB writer.  The default mode remains the WRCREAT mode.
+
+	* Various source files, changed the data types of various
+	  variables from int to long.  This should not make any difference
+	  to systems where sizeof(int) = sizeof(long).  It should make
+	  it easier to move to other systems.
+
+	* gdbmstore.c: Added a check for NULL key or content dptr.  Due to
+	  NULLs being used as error indications, data cannot be NULL also.
+
+	* gdbmfetch.c, gdbmseq.c, fetch.c: Added checks for zero sized
+	  key and content so malloc will not try to allocate zero bytes.
+
+        * gdbmconst.h: Added this file so that all constants are in one
+	  central place.  A few constants can be changed without changing
+	  the header sizes.
+
+Tue Aug 14 13:08:43 1990  Phil Nelson  (phil at unicorn.wwu.edu)
+
+	* Version 1.4 released.  (version.c: Updated to correct version.)
+
+	* Makefile: Added $(LIBS) to link for conv2gdbm.
+
+	* README: Updated to version 1.4 and added a 1.0-1.4 change
+	  statement.
+
+Wed Aug  8 16:57:29 1990  Phil Nelson  (phil at unicorn.wwu.edu)
+
+	* gdbmopen.c: Restructured some code to initialize dbf
+	  more completely.
+
+	* dbm.h: Added a null define to satisfy some versions that
+	  require a dbmclose() call.
+
+	* findkey.c: (_gdbm_findkey) Added a check for the NULL
+	  pointer in ...ca_data.dptr.
+
+	* gdbmdelete.c: Added code to more completely remove the
+	  cache entry for a deleted item.
+
+	* gdbmreorg.c: Added code to finish the transfer of information
+	  from the new_dbf to the orginal dbf.
+
+Fri May 30 08:29:16 1990  Phil Nelson  (phil at unicorn.wwu.edu)
+
+	* gdbmstore.c: Changed a strncpy to bcopy.
+
+Tue May 15 09:55:21 1990  Phil Nelson  (phil at unicorn.wwu.edu)
+
+	* Version 1.3 released.
+
+	* systems.h: Changed the defines for alloca to use the
+	  name builtin_alloca to depend on BUILTIN_ALLOCA instead
+	  of __GNUC__.  Added a definition of BUILTIN_ALLOCA for
+	  GNUC and for sun sparc.
+
+Fri May 11 12:15:56 1990  Phil Nelson  (phil at unicorn.wwu.edu)
+
+	* systems.h: Removed the include for <sys/types> and now
+	  systems.h requires <sys/types> included before it.
+
+	* Makefile: Corrected the makefile to include a file that
+	  was missing before.  Also, switched order of conv2gdbm
+	  and alldbm in the all option.
+
+	* findkey.c (_gdbm_read_entry): Reordered some statements
+	  to make the code more readable.
+
+	* update.c (_gdbm_fatal): Changed fatal message from "dbm fatal:"
+	  to "gdbm fatal:".
+
+Mon Apr 30 10:18:24 1990  Phil Nelson  (phil at unicorn.wwu.edu)
+
+	* Version 1.2 released.
+
+Fri Apr 27 09:49:59 1990  Phil Nelson  (phil at unicorn.wwu.edu)
+
+	* Makefile: Added the dist option.  Similar to the 
+	  addition from hack@ai.mit.edu, but correct.
+
+	* falloc.c (push_avail_block):  Change the avail count
+	  to reflect the correct number of entries.
+
+	* dbminit.c (dbminit): Changed the stat call to stat the
+	  ".dir" file as is done in dbmopen.c (dbm_open).
+
+Tue Apr 10 12:18:40 1990  Phil Nelson  (phil at unicorn.wwu.edu)
+
+	* Version 1.1. released.
+
+	* gdbmopen.c (gdbm_open): Clear out bucket cache.
+
+
+
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/INSTALL
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/INSTALL	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/INSTALL	(revision 20131)
@@ -0,0 +1,118 @@
+This is a generic INSTALL file for utilities distributions.
+If this package does not come with, e.g., installable documentation or
+data files, please ignore the references to them below.
+
+To compile this package:
+
+1.  Configure the package for your system.  In the directory that this
+file is in, type `./configure'.  If you're using `csh' on an old
+version of System V, you might need to type `sh configure' instead to
+prevent `csh' from trying to execute `configure' itself.
+
+The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation, and
+creates the Makefile(s) (one in each subdirectory of the source
+directory).  In some packages it creates a C header file containing
+system-dependent definitions.  It also creates a file `config.status'
+that you can run in the future to recreate the current configuration.
+
+Running `configure' takes a minute or two.  While it is running, it
+prints some messages that tell what it is doing.  If you don't want to
+see the messages, run `configure' with its standard output redirected
+to `/dev/null'; for example, `./configure >/dev/null'.
+
+To compile the package in a different directory from the one
+containing the source code, you must use a version of `make' that
+supports the VPATH variable, such as GNU `make'.  `cd' to the directory
+where you want the object files and executables to go and run
+`configure'.  `configure' automatically checks for the source code in
+the directory that `configure' is in and in `..'.  If for some reason
+`configure' is not in the source code directory that you are
+configuring, then it will report that it can't find the source code.
+In that case, run `configure' with the option `--srcdir=DIR', where
+DIR is the directory that contains the source code.
+
+By default, `make install' will install the package's files in
+/usr/local/bin, /usr/local/lib, /usr/local/man, etc.  You can specify an
+installation prefix other than /usr/local by giving `configure' the option
+`--prefix=PATH'.  Alternately, you can do so by consistently giving a value
+for the `prefix' variable when you run `make', e.g.,
+	make prefix=/usr/gnu
+	make prefix=/usr/gnu install
+
+You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If
+you give `configure' the option `--exec-prefix=PATH' or set the
+`make' variable `exec_prefix' to PATH, the package will use PATH as
+the prefix for installing programs and libraries.  Data files and
+documentation will still use the regular prefix.  Normally, all files
+are installed using the regular prefix.
+
+Another `configure' option is useful mainly in `Makefile' rules for
+updating `config.status' and `Makefile'.  The `--no-create' option
+figures out the configuration for your system and records it in
+`config.status', without actually configuring the package (creating
+`Makefile's and perhaps a configuration header file).  Later, you can
+run `./config.status' to actually configure the package.  You can also
+give `config.status' the `--recheck' option, which makes it re-run
+`configure' with the same arguments you used before.  This option is
+useful if you change `configure'.
+
+Some packages pay attention to `--with-PACKAGE' options to `configure',
+where PACKAGE is something like `gnu-libc' or `x' (for the X Window System).
+The README should mention any --with- options that the package recognizes.
+
+`configure' ignores any other arguments that you give it.
+
+If your system requires unusual options for compilation or linking
+that `configure' doesn't know about, you can give `configure' initial
+values for some variables by setting them in the environment.  In
+Bourne-compatible shells, you can do that on the command line like
+this:
+	CC='gcc -traditional' DEFS=-D_POSIX_SOURCE ./configure
+
+The `make' variables that you might want to override with environment
+variables when running `configure' are:
+
+(For these variables, any value given in the environment overrides the
+value that `configure' would choose:)
+CC		C compiler program.
+		Default is `cc', or `gcc' if `gcc' is in your PATH.
+INSTALL		Program to use to install files.
+		Default is `install' if you have it, `cp' otherwise.
+
+(For these variables, any value given in the environment is added to
+the value that `configure' chooses:)
+DEFS		Configuration options, in the form `-Dfoo -Dbar ...'
+		Do not use this variable in packages that create a
+		configuration header file.
+LIBS		Libraries to link with, in the form `-lfoo -lbar ...'
+
+If you need to do unusual things to compile the package, we encourage
+you to figure out how `configure' could check whether to do them, and
+mail diffs or instructions to the address given in the README so we
+can include them in the next release.
+
+2.  Type `make' to compile the package.  If you want, you can override
+the `make' variables CFLAGS and LDFLAGS like this:
+
+	make CFLAGS=-O2 LDFLAGS=-s
+
+3.  If the package comes with self-tests and you want to run them,
+type `make check'.  If you're not sure whether there are any, try it;
+if `make' responds with something like
+	make: *** No way to make target `check'.  Stop.
+then the package does not come with self-tests.
+
+4.  Type `make install' to install programs, data files, and
+documentation.
+
+5.  You can remove the program binaries and object files from the
+source directory by typing `make clean'.  To also remove the
+Makefile(s), the header file containing system-dependent definitions
+(if the package uses one), and `config.status' (all the files that
+`configure' created), type `make distclean'.
+
+The file `configure.in' is used as a template to create `configure' by
+a program called `autoconf'.  You will only need it if you want to
+regenerate `configure' using a newer version of `autoconf'.
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/Makefile.in
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/Makefile.in	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/Makefile.in	(revision 20131)
@@ -0,0 +1,297 @@
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+top_builddir = .
+VPATH = @srcdir@
+
+CC = @CC@
+LIBTOOL = @LIBTOOL@
+
+# GDBM 1.8.3 builds shared libraries version 3.0
+SHLIB_VER = 3 0 0
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+# File ownership and group
+BINOWN = bin
+BINGRP = bin
+
+MAKEINFO = makeinfo
+TEXI2DVI = texi2dvi
+
+DEFS =
+
+# Where the system [n]dbm routines are...
+LIBS = @LIBS@ -lc
+
+CFLAGS = @CFLAGS@ @COMPAT32BITFLAGS@
+LDFLAGS = @LDFLAGS@ @COMPAT32BITFLAGS@
+
+# Common prefix for installation directories
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+binprefix = $(exec_prefix)
+manprefix = $(prefix)
+
+# Directory in which to put libgdbm.a.
+libdir = @libdir@
+# The include directory for gdbm.h and dbm.h.
+includedir = @includedir@
+# Info and man directories.
+infodir = @infodir@
+man3dir = @mandir@/man3
+manext = 3
+
+#### End of system configuration section. ####
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o
+
+.c.o:
+	$(CC) -c $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) $(CFLAGS) $<
+
+.c.lo:
+	$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) $(CFLAGS) $<
+
+SHELL = /bin/sh
+
+PROGS = libgdbm.la testgdbm testdbm testndbm tndbm tdbm conv2gdbm
+
+DBM_CF = dbminit.c delete.c fetch.c store.c seq.c close.c
+
+NDBM_CF = dbmopen.c dbmdelete.c dbmfetch.c dbmstore.c dbmseq.c \
+	dbmclose.c dbmdirfno.c dbmpagfno.c dbmrdonly.c
+
+GDBM_CF = gdbmopen.c gdbmdelete.c gdbmfetch.c  gdbmstore.c gdbmclose.c \
+	gdbmreorg.c gdbmseq.c gdbmsync.c gdbmerrno.c gdbmexists.c gdbmfdesc.c \
+	gdbmsetopt.c bucket.c falloc.c findkey.c global.c hash.c update.c \
+	version.c gsdlmods.c
+
+TEST_CF = testdbm.c testndbm.c testgdbm.c
+
+
+DBM_OF = dbminit.o delete.o fetch.o store.o seq.o close.o
+
+NDBM_OF = dbmopen.o dbmdelete.o dbmfetch.o dbmstore.o dbmseq.o \
+	dbmclose.o dbmdirfno.o dbmpagfno.o dbmrdonly.o
+
+GDBM_OF = gdbmopen.o gdbmdelete.o gdbmfetch.o  gdbmstore.o gdbmclose.o \
+	gdbmreorg.o gdbmseq.o gdbmsync.o gdbmerrno.o gdbmexists.o gdbmfdesc.o \
+	gdbmsetopt.o bucket.o falloc.o findkey.o global.o hash.o update.o \
+	version.o gsdlmods.o
+
+DBM_LOF = dbminit.lo delete.lo fetch.lo store.lo seq.lo close.lo
+
+NDBM_LOF = dbmopen.lo dbmdelete.lo dbmfetch.lo dbmstore.lo dbmseq.lo \
+	dbmclose.lo dbmdirfno.lo dbmpagfno.lo dbmrdonly.lo
+
+GDBM_LOF = gdbmopen.lo gdbmdelete.lo gdbmfetch.lo  gdbmstore.lo gdbmclose.lo \
+	gdbmreorg.lo gdbmseq.lo gdbmsync.lo gdbmerrno.lo gdbmexists.lo \
+	gdbmfdesc.lo gdbmsetopt.lo bucket.lo falloc.lo findkey.lo global.lo \
+	hash.lo update.lo version.lo gsdlmods.lo
+
+TEX_F = gdbm.aux gdbm.cp gdbm.dvi gdbm.fn gdbm.ky gdbm.log gdbm.pg \
+	gdbm.toc gdbm.tp gdbm.vr
+
+TEXI_F = gdbm.info
+     
+SRCS = $(DBM_CF) $(NDBM_CF) $(GDBM_CF) $(TEST_CF)
+
+# The old all in one library:
+#OBJS = $(DBM_OF) $(NDBM_OF) $(GDBM_OF)
+#
+#LOBJS = $(DBM_LOF) $(NDBM_LOF) $(GDBM_LOF)
+
+# The new split libraries:
+OBJS = $(GDBM_OF)
+LOBJS = $(GDBM_LOF)
+
+C_OBJS = $(DBM_OF) $(NDBM_OF)
+C_LOBJS = $(DBM_LOF) $(NDBM_LOF)
+
+HDRS = gdbmdefs.h extern.h gdbmerrno.h systems.h dbm.h ndbm.h gdbmconst.h \
+	proto.h
+
+#MSCFILES = COPYING ChangeLog Makefile.in README gdbm.3 gdbm.texinfo \
+#	gdbm.info NEWS INSTALL gdbm.proto gdbm.proto2 conv2gdbm.c \
+#	configure configure.in getopt.c getopt.h samp1.cc \
+#	autoconf.h.in install-sh mkinstalldirs config.guess config.sub \
+#	aclocal.m4 ltconfig ltmain.sh
+
+MSCFILES = COPYING ChangeLog Makefile.in README gdbm.3 \
+	NEWS INSTALL gdbm.proto gdbm.proto2 conv2gdbm.c \
+	configure configure.in getopt.c getopt.h samp1.cc \
+	autoconf.h.in install-sh mkinstalldirs config.guess config.sub \
+	aclocal.m4 ltconfig ltmain.sh
+
+DISTFILES = $(SRCS) $(HDRS) $(MSCFILES)
+
+all: libgdbm.la libgdbm_compat.la
+
+progs: $(PROGS)
+
+#install: libgdbm.la gdbm.h gdbm.info
+install: libgdbm.la gdbm.h 
+	$(srcdir)/mkinstalldirs $(INSTALL_ROOT)$(libdir) \
+		$(INSTALL_ROOT)$(includedir) $(INSTALL_ROOT)$(man3dir) \
+		$(INSTALL_ROOT)$(infodir)
+	$(LIBTOOL) $(INSTALL) -c libgdbm.la $(INSTALL_ROOT)$(libdir)/libgdbm.la
+	$(INSTALL_DATA) gdbm.h \
+		$(INSTALL_ROOT)$(includedir)/gdbm.h
+	$(INSTALL_DATA) $(srcdir)/gdbm.3 \
+		$(INSTALL_ROOT)$(man3dir)/gdbm.3
+#	$(INSTALL_DATA) $(srcdir)/gdbm.info \
+#		$(INSTALL_ROOT)$(infodir)/gdbm.info
+
+install-compat:
+	$(srcdir)/mkinstalldirs $(INSTALL_ROOT)$(libdir) \
+		$(INSTALL_ROOT)$(includedir)
+	$(LIBTOOL) $(INSTALL) -c libgdbm_compat.la \
+		$(INSTALL_ROOT)$(libdir)/libgdbm_compat.la
+	$(INSTALL_DATA) $(srcdir)/dbm.h \
+		$(INSTALL_ROOT)$(includedir)/dbm.h
+	$(INSTALL_DATA) $(srcdir)/ndbm.h \
+		$(INSTALL_ROOT)$(includedir)/ndbm.h
+
+#libgdbm.a: $(OBJS) gdbm.h
+#	rm -f libgdbm.a
+#	ar q libgdbm.a $(OBJS)
+#	$(RANLIB) libgdbm.a
+
+libgdbm.la: $(LOBJS) gdbm.h
+	rm -f libgdbm.la
+##	$(CC) -shared $(LDFLAGS) -o libgdbm.so $(LOBJS)
+	$(LIBTOOL) --mode=link $(CC) -Wc,$(LDFLAGS) -o libgdbm.la -rpath $(libdir) \
+		-version-info $(SHLIB_VER) $(LOBJS)
+
+libgdbm_compat.la: $(C_LOBJS) gdbm.h
+	rm -f libgdbm_compat.la
+##	$(CC) -shared $(LDFLAGS) -o libgdbm_compat.so  $(C_LOBJS)
+	$(LIBTOOL) --mode=link $(CC) -Wc,$(LDFLAGS) -o libgdbm_compat.la -rpath $(libdir) \
+		-version-info $(SHLIB_VER) $(C_LOBJS)
+
+gdbm.h:	gdbm.proto gdbmerrno.h gdbm.proto2
+	rm -f gdbm.h
+	cp $(srcdir)/gdbm.proto gdbm.h
+	chmod +w gdbm.h
+	grep _ $(srcdir)/gdbmerrno.h >> gdbm.h
+	cat $(srcdir)/gdbm.proto2 >> gdbm.h
+	chmod -w gdbm.h
+
+testgdbm: testgdbm.o libgdbm.la @LIBOBJS@
+	$(LIBTOOL) $(CC) $(LDFLAGS) -o testgdbm testgdbm.o libgdbm.la @LIBOBJS@
+
+testdbm: testdbm.o libgdbm.la libgdbm_compat.la
+	$(LIBTOOL) $(CC) $(LDFLAGS) -o testdbm testdbm.o libgdbm.la libgdbm_compat.la
+
+tdbm: testdbm.o
+	$(CC) $(LDFLAGS) -o tdbm testdbm.o $(LIBS)
+
+testndbm.o: testndbm.c
+	$(CC) -c -I. -I$(srcdir) $(CFLAGS) $(DEFS) -DGNU $(srcdir)/testndbm.c
+
+testndbm: testndbm.o libgdbm.la libgdbm_compat.la
+	$(LIBTOOL) $(CC) $(LDFLAGS) -o testndbm testndbm.o libgdbm.la libgdbm_compat.la
+
+tndbm.o: testndbm.c
+	cp $(srcdir)/testndbm.c ./tndbm.c
+	$(CC) -c -I. -I$(srcdir) $(CFLAGS) $(DEFS) ./tndbm.c
+	rm -f ./tndbm.c
+
+tndbm: tndbm.o
+	$(CC) $(LDFLAGS) -o tndbm tndbm.o $(LIBS)
+
+conv2gdbm: conv2gdbm.o libgdbm.la @LIBOBJS@
+	$(LIBTOOL) $(CC) $(LDFLAGS) -o conv2gdbm conv2gdbm.o $(LIBS) libgdbm.la @LIBOBJS@
+
+lintgdbm: 
+	lint $(DEFS) $(LFLAGS) $(DBM_CF) $(NDBM_CF) $(GDBM_CF) testgdbm.c
+
+TAGS: $(SRCS)
+	etags $(SRCS)
+
+#info: gdbm.info
+
+#gdbm.info: gdbm.texinfo
+#	$(MAKEINFO) $(srcdir)/gdbm.texinfo
+
+#dvi: gdbm.dvi
+
+#gdbm.dvi: gdbm.texinfo
+#	$(TEXI2DVI) $(srcdir)/gdbm.texinfo
+
+clean:
+	rm -rf $(PROGS) $(TEX_F) *.a *.la *.o *.lo core *.core junk* \
+		.libs _libs
+
+mostlyclean: clean
+
+distclean: clean
+	rm -f Makefile autoconf.h config.status config.cache config.log \
+		gdbm.h libtool $(TEXI_F) *~
+
+realclean: distclean
+	rm -f TAGS
+	-rm -f \
+	  `sed -n 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/gdbm-\1/p' \
+		version.c`.tar.gz
+
+dist:
+	echo \
+	  `sed -n 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/gdbm-\1/p' \
+		version.c` > .fname
+	rm -rf `cat .fname`
+	mkdir `cat .fname`
+	ln $(DISTFILES) `cat .fname`
+	tar chf `cat .fname`.tar `cat .fname`
+	gzip `cat .fname`.tar
+	rm -rf `cat .fname` .fname
+
+# dbm files
+dbminit.o:	autoconf.h gdbmdefs.h proto.h extern.h gdbmerrno.h
+delete.o:	autoconf.h gdbmdefs.h proto.h extern.h
+fetch.o:	autoconf.h gdbmdefs.h proto.h extern.h
+store.o:	autoconf.h gdbmdefs.h proto.h extern.h
+seq.o:		autoconf.h gdbmdefs.h proto.h extern.h
+
+# ndbm files
+dbmopen.o:	autoconf.h gdbmdefs.h extern.h gdbmerrno.h
+dbmdelete.o:	autoconf.h gdbmdefs.h extern.h
+dbmfetch.o:	autoconf.h gdbmdefs.h extern.h
+dbmstore.o:	autoconf.h gdbmdefs.h extern.h
+dbmseq.o:	autoconf.h gdbmdefs.h extern.h
+dbmclose.o:	autoconf.h gdbmdefs.h systems.h
+dbmpagfno.o:	autoconf.h gdbmdefs.h extern.h
+dbmdirfno.o:	autoconf.h gdbmdefs.h extern.h
+
+
+# gdbm files
+gdbmclose.o:	autoconf.h gdbmdefs.h 
+gdbmdelete.o:	autoconf.h gdbmdefs.h gdbmerrno.h 
+gdbmfetch.o:	autoconf.h gdbmdefs.h gdbmerrno.h 
+gdbmfdesc.o:	autoconf.h gdbmdefs.h
+gdbmopen.o:	autoconf.h gdbmdefs.h gdbmerrno.h 
+gdbmreorg.o:	autoconf.h gdbmdefs.h gdbmerrno.h extern.h
+gdbmseq.o:	autoconf.h gdbmdefs.h 
+gdbmstore.o:	autoconf.h gdbmdefs.h gdbmerrno.h 
+
+# gdbm support files
+bucket.o:	autoconf.h gdbmdefs.h
+falloc.o:	autoconf.h gdbmdefs.h
+findkey.o:	autoconf.h gdbmdefs.h
+global.o:	autoconf.h gdbmdefs.h gdbmerrno.h 
+hash.o:		autoconf.h gdbmdefs.h
+update.o:	autoconf.h gdbmdefs.h
+version.o:
+extern.h:
+gdbmdefs.h:	gdbmconst.h systems.h
+	touch gdbmdefs.h
+
+# other programs
+testgdbm.o:	autoconf.h gdbmdefs.h extern.h gdbmerrno.h systems.h
+testdbm.o:	autoconf.h
+testndbm.o:	autoconf.h ndbm.h
+tdbm.o:		autoconf.h
+conv2gdbm.o:	autoconf.h gdbm.h
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/NEWS
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/NEWS	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/NEWS	(revision 20131)
@@ -0,0 +1,82 @@
+CHANGES from 1.8.2 to 1.8.3
+  1.  Various configure related changes and additional updates.
+
+CHANGES from 1.8.1 to 1.8.2
+  1.  Allow `NEWDB'-opened databases to actually, well, store records.
+
+CHANGES from 1.8 to 1.8.1
+  1.  Lots of bug fixes, including a data corruption bug.
+  2.  Updated to current autoconf and libtool.
+  3.  Moved the dbm/ndbm compatibility routines to libgdbm_compat.
+
+CHANGES from 1.7.3 to 1.8
+  1.  Added GDBM_CENTFREE functionality and option.
+  2.  Added GDBM_COALESCEBLKS functionality and option.
+  3.  Added GDBM_NOLOCK flag.
+  4.  Made ``fast'' mode the default, making GDBM_FAST obsolete, and adding
+      the GDBM_SYNC flag and GDBM_SYNCMODE option.
+  5.  Switched to building with libtool.
+
+CHANGES from 1.7.2 to 1.7.3
+  1.  Fixed a couple of last minute problems. (Namely, no autoconf.h in
+      version.c, and no GDBM_FASTMODE in gdbm.h!)
+  2.  Fixed some documentation bugs.
+
+CHANGES from 1.7.1 to 1.7.2
+  1.  Enhanced portability and compile/installation changes.
+  2.  Additional, "fast mode" related gdbm_setopt() option.
+  3.  Growth problems bug fix.
+
+CHANGES from 1.7 to 1.7.1
+  1.  Enhanced portabilty and compile/installation bug fixes.
+  2.  Switched over to using an auto config header.
+  2.  Slight documentation upgrade.
+
+CHANGES from 1.6 to 1.7
+  1.  A new dynamic, delayed initialization, bucket cache.
+  2.  New gdbm_setopt(), gdbm_exists(), and gdbm_strerror() routines.
+  3.  Slightly improved dbm/ndbm compatibility.
+  4.  Greatly improved portability to 64 or 16 bit machines.
+  5.  Various bug fixes.
+
+CHANGES from 1.5 to 1.6
+  1.  New documentation in both man and texinfo formats.
+  2.  Bug fixes.
+  3.  A New "writers" mode that does not fsync the database.
+  4.  Uses Autoconf now.
+
+CHANGES from 1.4 to 1.5:
+  1.  Minor bug fixes.  See the ChangeLog.
+  2.  Added gdbmconst.h to allow users to change the size of the
+      bucket cache in the systems.h file.
+
+CHANGES from 1.0 to 1.4:
+  1.  Mainly bug fixes.
+  2.  A define for "dbmclose()" was added to dbm.h for those few 
+      implementaions that need that call.
+  3.  For details, see the ChangeLog.
+
+CHANGES from 0.9 to 1.0:
+  1.  Makefiles were combined into one and a few new things added to it.
+  2.  Several minor bugs were fixed including a cache bug.
+  3.  Two new calls (dbm_pagfno, dbm_dirfno) were added to the NDBM interface.
+  3.  A conversion program from dbm files to gdbm files was added.
+  4.  Reorganize was changed to allow complex file names. (dir/file form)
+  5.  testgdbm, testndbm, and testdbm were modified to return key and data
+      pairs where needed and to take an optional file name as an argument.
+      testgdbm had some command characters changed.
+  6.  The DBM and NDBM interfaces were separated.
+  7.  An include file for dbm users was added. (dbm.h)
+  8.  The include file for ndbm users was renamed ndbm.h. (It was gndbm.h.)
+
+CHANGES from 0.8 to 0.9:
+  1.  The hash function changed.
+  2.  The file format changed.
+  3.  There was a complete rewrite of falloc.c.
+  4.  There were added compatiblity routines for ndbm.
+  5.  The file names for dbm compatibility routines were made to
+      look like dbm.
+  6.  Test programs changed.
+  7.  Support for System V.
+  8.  Various other small changes.
+  9.  The need for recovery and associated code was removed.
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/README
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/README	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/README	(revision 20131)
@@ -0,0 +1,56 @@
+GNU dbm is a set of database routines that use extendible hashing and
+works similar to the standard UNIX dbm routines.
+
+This is release 1.8.3 of GNU dbm.
+
+To compile gdbm:
+
+   a)  configure <config parameters like -prefix ... see INSTALL>
+   b)  make 
+
+To compile the optional test and conversion programs:
+
+   a)  make progs
+
+To install the basic package:
+
+   a)  make install
+
+To install the optional dbm and ndbm API compatibility library and headers:
+
+   a)  make install-compat
+
+Please report bugs to
+	bug-gnu-utils@gnu.org
+
+------------------------------------------
+
+The files are:
+
+INSTALL		- Installation tips and information.
+NEWS		- New and changed things.
+COPYING		- Copying information.
+README		- This file.
+
+bucket.c, extern.h, falloc.c, findkey.c, gdbm.proto, gdbmclose.c,
+gdbmconst.h gdbmdefs.h, gdbmdelete.c, gdbmerrno.h, gdbmfdesc.c, gdbmfetch.c,
+gdbmsync.c, gdbmopen.c, gdbmreorg.c, gdbmseq.c, gdbmstore.c, global.c, gdbm.h,
+hash.c systems.h, update.c, version.c - Source for GNU dbm library.
+
+dbm.h dbminit.c, delete.c, fetch.c, seq.c, store.c - Source for the
+DBM interface.
+
+dbmclose.c, dbmdelete.c, dbmdirfno.c, dbmfetch.c, dbmopen.c, dbmpagfno.c
+dbmseq.c, dbmstore.c, ndbm.h - Source for the NDBM interface.
+
+Makefile 	- Makefile, will make gdbm.a  (BSD and SYSV)
+testgdbm.c	- A simple test program.
+testdbm.c	- A simple test program.
+testndbm.c	- A simple test program.
+conv2gdbm.c	- A dbm database conversion program.
+
+gdbm.3, gdbm.texinfo - Documentation for gdbm.
+
+The author of GNU dbm may be reached via e-mail to <phil@cs.wwu.edu>,
+and the current maintainer may be reached at <downsj@downsj.com>.
+E-mail may be sent to either, or both, of these people.
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/aclocal.m4
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/aclocal.m4	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/aclocal.m4	(revision 20131)
@@ -0,0 +1,3573 @@
+# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*-
+## Copyright 1996, 1997, 1998, 1999, 2000, 2001
+## Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+## As a special exception to the GNU General Public License, if you
+## distribute this file as part of a program that contains a
+## configuration script generated by Autoconf, you may include it under
+## the same distribution terms that you use for the rest of that program.
+
+# serial 46 AC_PROG_LIBTOOL
+
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Prevent multiple expansion
+define([AC_PROG_LIBTOOL], [])
+])
+
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+_LT_AC_PROG_ECHO_BACKSLASH
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    AC_PATH_MAGIC
+  fi
+  ;;
+esac
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+enable_win32_dll=yes, enable_win32_dll=no)
+
+AC_ARG_ENABLE(libtool-lock,
+  [  --disable-libtool-lock  avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_SAVE
+     AC_LANG_C
+     AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_RESTORE])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+
+  # recent cygwin and mingw systems supply a stub DllMain which the user
+  # can override, but on older systems we have to supply one
+  AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain,
+    [AC_TRY_LINK([],
+      [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*);
+      DllMain (0, 0, 0);],
+      [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])])
+
+  case $host/$CC in
+  *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*)
+    # old mingw systems require "-dll" to link a DLL, while more recent ones
+    # require "-mdll"
+    SAVE_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -mdll"
+    AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch,
+      [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])])
+    CFLAGS="$SAVE_CFLAGS" ;;
+  *-*-cygwin* | *-*-pw32*)
+    # cygwin systems need to pass --dll to the linker, and not link
+    # crt.o which will require a WinMain@16 definition.
+    lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;;
+  esac
+  ;;
+  ])
+esac
+
+_LT_AC_LTCONFIG_HACK
+
+])
+
+# AC_LIBTOOL_HEADER_ASSERT
+# ------------------------
+AC_DEFUN([AC_LIBTOOL_HEADER_ASSERT],
+[AC_CACHE_CHECK([whether $CC supports assert without backlinking],
+    [lt_cv_func_assert_works],
+    [case $host in
+    *-*-solaris*)
+      if test "$GCC" = yes && test "$with_gnu_ld" != yes; then
+        case `$CC --version 2>/dev/null` in
+        [[12]].*) lt_cv_func_assert_works=no ;;
+        *)        lt_cv_func_assert_works=yes ;;
+        esac
+      fi
+      ;;
+    esac])
+
+if test "x$lt_cv_func_assert_works" = xyes; then
+  AC_CHECK_HEADERS(assert.h)
+fi
+])# AC_LIBTOOL_HEADER_ASSERT
+
+# _LT_AC_CHECK_DLFCN
+# --------------------
+AC_DEFUN([_LT_AC_CHECK_DLFCN],
+[AC_CHECK_HEADERS(dlfcn.h)
+])# _LT_AC_CHECK_DLFCN
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_NM])
+AC_REQUIRE([AC_OBJEXT])
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+  lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  ;;
+irix*)
+  symcode='[[BCDEGRST]]'
+  ;;
+solaris* | sysv5*)
+  symcode='[[BDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $host_os in
+mingw*)
+  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[[ABCDGISTW]]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ 	]]\($symcode$symcode*\)[[ 	]][[ 	]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+  rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+	if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext'
+
+	  cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr address;
+}
+lt_preloaded_symbols[[]] =
+{
+EOF
+	  sed "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext
+	  cat <<\EOF >> conftest.$ac_ext
+  {0, (lt_ptr) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  save_LIBS="$LIBS"
+	  save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$no_builtin_flag"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$save_LIBS"
+	  CFLAGS="$save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AC_FD_CC
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AC_FD_CC
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC
+    fi
+  else
+    echo "$progname: failed program was:" >&AC_FD_CC
+    cat conftest.$ac_ext >&5
+  fi
+  rm -f conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+global_symbol_pipe="$lt_cv_sys_global_symbol_pipe"
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  global_symbol_to_cdecl=
+  global_symbol_to_c_name_address=
+else
+  global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl"
+  global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address"
+fi
+if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address";
+then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+# ---------------------------------
+AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR],
+[# Find the correct PATH separator.  Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+  UNAME=${UNAME-`uname 2>/dev/null`}
+  case X$UNAME in
+    *-DOS) lt_cv_sys_path_separator=';' ;;
+    *)     lt_cv_sys_path_separator=':' ;;
+  esac
+  PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
+[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+			      [AC_DIVERT_PUSH(NOTICE)])
+_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+  ;;
+esac
+
+echo=${ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X[$]1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+    then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+   test "X$echo_testing_string" = "X$echo_test_string"; then
+  :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for dir in $PATH /usr/ucb; do
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+	 test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running configure again with it.
+      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+	 echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+	 test "X$echo_testing_string" = "X$echo_test_string"; then
+	# Cool, printf works
+	:
+      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	   test "X$echo_testing_string" = 'X\t' &&
+	   echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	export CONFIG_SHELL
+	SHELL="$CONFIG_SHELL"
+	export SHELL
+	echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	   test "X$echo_testing_string" = 'X\t' &&
+	   echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      else
+	# maybe with a smaller string...
+	prev=:
+
+	for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+	  if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+	  then
+	    break
+	  fi
+	  prev="$cmd"
+	done
+
+	if test "$prev" != 'sed 50q "[$]0"'; then
+	  echo_test_string=`eval $prev`
+	  export echo_test_string
+	  exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+	else
+	  # Oops.  We lost completely, so just stick with echo.
+	  echo=echo
+	fi
+      fi
+    fi
+  fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+   ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(ECHO)
+AC_DIVERT_POP
+])# _LT_AC_PROG_ECHO_BACKSLASH
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                           ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ------------------------------------------------------------------
+AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
+[if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}]
+EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_unknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_AC_TRY_DLOPEN_SELF
+
+# AC_LIBTOOL_DLOPEN_SELF
+# -------------------
+AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
+[if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+          [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+            [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen="dlopen"],
+	  [AC_CHECK_LIB([dl], [dlopen],
+	        [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+	    [AC_CHECK_LIB([svld], [dlopen],
+	          [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+	      [AC_CHECK_LIB([dld], [dld_link],
+	            [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_AC_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      LDFLAGS="$LDFLAGS $link_static_flag"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+    	  lt_cv_dlopen_self_static, [dnl
+	  _LT_AC_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+])# AC_LIBTOOL_DLOPEN_SELF
+
+AC_DEFUN([_LT_AC_LTCONFIG_HACK],
+[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([[\\"\\`$\\\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([[\\"\\`\\\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+need_locks="$enable_libtool_lock"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+if test x"$host" != x"$build"; then
+  ac_tool_prefix=${host_alias}-
+else
+  ac_tool_prefix=
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case $host_os in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+    ;;
+  *)
+    old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="[$]2"
+
+## FIXME: this should be a separate macro
+##
+AC_MSG_CHECKING([for objdir])
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+AC_MSG_RESULT($objdir)
+##
+## END FIXME
+
+
+## FIXME: this should be a separate macro
+##
+AC_ARG_WITH(pic,
+[  --with-pic              try to use only PIC/non-PIC objects [default=use both]],
+pic_mode="$withval", pic_mode=default)
+test -z "$pic_mode" && pic_mode=default
+
+# We assume here that the value for lt_cv_prog_cc_pic will not be cached
+# in isolation, and that seeing it set (from the cache) indicates that
+# the associated values are set (in the cache) correctly too.
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+AC_CACHE_VAL(lt_cv_prog_cc_pic,
+[ lt_cv_prog_cc_pic=
+  lt_cv_prog_cc_shlib=
+  lt_cv_prog_cc_wl=
+  lt_cv_prog_cc_static=
+  lt_cv_prog_cc_no_builtin=
+  lt_cv_prog_cc_can_build_shared=$can_build_shared
+
+  if test "$GCC" = yes; then
+    lt_cv_prog_cc_wl='-Wl,'
+    lt_cv_prog_cc_static='-static'
+
+    case $host_os in
+    aix*)
+      # Below there is a dirty hack to force normal static linking with -ldl
+      # The problem is because libdl dynamically linked with both libc and
+      # libC (AIX C++ library), which obviously doesn't included in libraries
+      # list by gcc. This cause undefined symbols with -static flags.
+      # This hack allows C programs to be linked with "-static -ldl", but
+      # not sure about C++ programs.
+      lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC"
+      ;;
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
+      ;;
+    beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_cv_prog_cc_pic='-fno-common'
+      ;;
+    cygwin* | mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_cv_prog_cc_pic='-DDLL_EXPORT'
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	 lt_cv_prog_cc_pic=-Kconform_pic
+      fi
+      ;;
+    *)
+      lt_cv_prog_cc_pic='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for PIC flags for the system compiler.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      lt_cv_prog_cc_wl='-Wl,'
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_cv_prog_cc_static='-Bstatic'
+      else
+	lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      # Is there a better lt_cv_prog_cc_static that works with the bundled CC?
+      lt_cv_prog_cc_wl='-Wl,'
+      lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive"
+      lt_cv_prog_cc_pic='+Z'
+      ;;
+
+    irix5* | irix6*)
+      lt_cv_prog_cc_wl='-Wl,'
+      lt_cv_prog_cc_static='-non_shared'
+      # PIC (with -KPIC) is the default.
+      ;;
+
+    cygwin* | mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_cv_prog_cc_pic='-DDLL_EXPORT'
+      ;;
+
+    newsos6)
+      lt_cv_prog_cc_pic='-KPIC'
+      lt_cv_prog_cc_static='-Bstatic'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      # All OSF/1 code is PIC.
+      lt_cv_prog_cc_wl='-Wl,'
+      lt_cv_prog_cc_static='-non_shared'
+      ;;
+
+    sco3.2v5*)
+      lt_cv_prog_cc_pic='-Kpic'
+      lt_cv_prog_cc_static='-dn'
+      lt_cv_prog_cc_shlib='-belf'
+      ;;
+
+    solaris*)
+      lt_cv_prog_cc_pic='-KPIC'
+      lt_cv_prog_cc_static='-Bstatic'
+      lt_cv_prog_cc_wl='-Wl,'
+      ;;
+
+    sunos4*)
+      lt_cv_prog_cc_pic='-PIC'
+      lt_cv_prog_cc_static='-Bstatic'
+      lt_cv_prog_cc_wl='-Qoption ld '
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+      lt_cv_prog_cc_pic='-KPIC'
+      lt_cv_prog_cc_static='-Bstatic'
+      if test "x$host_vendor" = xsni; then
+	lt_cv_prog_cc_wl='-LD'
+      else
+	lt_cv_prog_cc_wl='-Wl,'
+      fi
+      ;;
+
+    uts4*)
+      lt_cv_prog_cc_pic='-pic'
+      lt_cv_prog_cc_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_cv_prog_cc_pic='-Kconform_pic'
+	lt_cv_prog_cc_static='-Bstatic'
+      fi
+      ;;
+
+    *)
+      lt_cv_prog_cc_can_build_shared=no
+      ;;
+    esac
+  fi
+])
+if test -z "$lt_cv_prog_cc_pic"; then
+  AC_MSG_RESULT([none])
+else
+  AC_MSG_RESULT([$lt_cv_prog_cc_pic])
+
+  # Check to make sure the pic_flag actually works.
+  AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works])
+  AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl
+    save_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
+    AC_TRY_COMPILE([], [], [dnl
+      case $host_os in
+      hpux9* | hpux10* | hpux11*)
+	# On HP-UX, both CC and GCC only warn that PIC is supported... then
+	# they create non-PIC objects.  So, if there were any warnings, we
+	# assume that PIC is not supported.
+	if test -s conftest.err; then
+	  lt_cv_prog_cc_pic_works=no
+	else
+	  lt_cv_prog_cc_pic_works=yes
+	fi
+	;;
+      *)
+	lt_cv_prog_cc_pic_works=yes
+	;;
+      esac
+    ], [dnl
+      lt_cv_prog_cc_pic_works=no
+    ])
+    CFLAGS="$save_CFLAGS"
+  ])
+
+  if test "X$lt_cv_prog_cc_pic_works" = Xno; then
+    lt_cv_prog_cc_pic=
+    lt_cv_prog_cc_can_build_shared=no
+  else
+    lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic"
+  fi
+
+  AC_MSG_RESULT([$lt_cv_prog_cc_pic_works])
+fi
+##
+## END FIXME
+
+# Check for any special shared library compilation flags.
+if test -n "$lt_cv_prog_cc_shlib"; then
+  AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries])
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[[ 	]]$lt_cv_prog_cc_shlib[[ 	]]" >/dev/null; then :
+  else
+   AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure])
+    lt_cv_prog_cc_can_build_shared=no
+  fi
+fi
+
+## FIXME: this should be a separate macro
+##
+AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works])
+AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl
+  lt_cv_prog_cc_static_works=no
+  save_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
+  AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes])
+  LDFLAGS="$save_LDFLAGS"
+])
+
+# Belt *and* braces to stop my trousers falling down:
+test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static=
+AC_MSG_RESULT([$lt_cv_prog_cc_static_works])
+
+pic_flag="$lt_cv_prog_cc_pic"
+special_shlib_compile_flags="$lt_cv_prog_cc_shlib"
+wl="$lt_cv_prog_cc_wl"
+link_static_flag="$lt_cv_prog_cc_static"
+no_builtin_flag="$lt_cv_prog_cc_no_builtin"
+can_build_shared="$lt_cv_prog_cc_can_build_shared"
+##
+## END FIXME
+
+
+## FIXME: this should be a separate macro
+##
+# Check to see if options -o and -c are simultaneously supported by compiler
+AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext])
+AC_CACHE_VAL([lt_cv_compiler_c_o], [
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+echo "int some_variable = 0;" > conftest.$ac_ext
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory.  Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
+compiler_c_o=no
+if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+  # The compiler can only warn and ignore the option if not recognized
+  # So say no if there are warnings
+  if test -s out/conftest.err; then
+    lt_cv_compiler_c_o=no
+  else
+    lt_cv_compiler_c_o=yes
+  fi
+else
+  # Append any errors to the config.log.
+  cat out/conftest.err 1>&AC_FD_CC
+  lt_cv_compiler_c_o=no
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+])
+compiler_c_o=$lt_cv_compiler_c_o
+AC_MSG_RESULT([$compiler_c_o])
+
+if test x"$compiler_c_o" = x"yes"; then
+  # Check to see if we can write to a .lo
+  AC_MSG_CHECKING([if $compiler supports -c -o file.lo])
+  AC_CACHE_VAL([lt_cv_compiler_o_lo], [
+  lt_cv_compiler_o_lo=no
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -c -o conftest.lo"
+  save_objext="$ac_objext"
+  ac_objext=lo
+  AC_TRY_COMPILE([], [int some_variable = 0;], [dnl
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+    if test -s conftest.err; then
+      lt_cv_compiler_o_lo=no
+    else
+      lt_cv_compiler_o_lo=yes
+    fi
+  ])
+  ac_objext="$save_objext"
+  CFLAGS="$save_CFLAGS"
+  ])
+  compiler_o_lo=$lt_cv_compiler_o_lo
+  AC_MSG_RESULT([$compiler_o_lo])
+else
+  compiler_o_lo=no
+fi
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+if test "$GCC" = yes; then
+  # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+  AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions])
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext"
+  compiler_rtti_exceptions=no
+  AC_TRY_COMPILE([], [int some_variable = 0;], [dnl
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+    if test -s conftest.err; then
+      compiler_rtti_exceptions=no
+    else
+      compiler_rtti_exceptions=yes
+    fi
+  ])
+  CFLAGS="$save_CFLAGS"
+  AC_MSG_RESULT([$compiler_rtti_exceptions])
+
+  if test "$compiler_rtti_exceptions" = "yes"; then
+    no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+  else
+    no_builtin_flag=' -fno-builtin'
+  fi
+fi
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# See if the linker supports building shared libraries.
+AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries])
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+old_archive_from_expsyms_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_into_libs=no
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+link_all_deplibs=unknown
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced.  Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+extract_expsyms_cmds=
+
+case $host_os in
+cygwin* | mingw* | pw32*)
+  # FIXME: the MSVC++ port hasn't been tested in a loooong time
+  # When not using gcc, we currently assume that we are using
+  # Microsoft Visual C++.
+  if test "$GCC" != yes; then
+    with_gnu_ld=no
+  fi
+  ;;
+openbsd*)
+  with_gnu_ld=no
+  ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # If archive_cmds runs LD, not CC, wlarc should be empty
+  wlarc='${wl}'
+
+  # See if GNU ld supports shared libraries.
+  case $host_os in
+  aix3* | aix4* | aix5*)
+    # On AIX, the GNU linker is very broken
+    # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available.
+    ld_shlibs=no
+    cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+
+    # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+    # that the semantics of dynamic libraries on AmigaOS, at least up
+    # to version 4, is to share data among multiple programs linked
+    # with the same dynamic library.  Since this doesn't match the
+    # behavior of shared libraries on other platforms, we can use
+    # them.
+    ld_shlibs=no
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag=unsupported
+      # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec='-L$libdir'
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+
+    extract_expsyms_cmds='test -f $output_objdir/impgen.c || \
+      sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~
+      test -f $output_objdir/impgen.exe || (cd $output_objdir && \
+      if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \
+      else $CC -o impgen impgen.c ; fi)~
+      $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def'
+
+    old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib'
+
+    # cygwin and mingw dlls have different entry points and sets of symbols
+    # to exclude.
+    # FIXME: what about values for MSVC?
+    dll_entry=__cygwin_dll_entry@12
+    dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~
+    case $host_os in
+    mingw*)
+      # mingw values
+      dll_entry=_DllMainCRTStartup@12
+      dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~
+      ;;
+    esac
+
+    # mingw and cygwin differ, and it's simplest to just exclude the union
+    # of the two symbol sets.
+    dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12
+
+    # recent cygwin and mingw systems supply a stub DllMain which the user
+    # can override, but on older systems we have to supply one (in ltdll.c)
+    if test "x$lt_cv_need_dllmain" = "xyes"; then
+      ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext "
+      ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~
+	test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~'
+    else
+      ltdll_obj=
+      ltdll_cmds=
+    fi
+
+    # Extract the symbol export list from an `--export-all' def file,
+    # then regenerate the def file from the symbol export list, so that
+    # the compiled dll only exports the symbol export list.
+    # Be careful not to strip the DATA tag left be newer dlltools.
+    export_symbols_cmds="$ltdll_cmds"'
+      $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~
+      sed -e "1,/EXPORTS/d" -e "s/ @ [[0-9]]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols'
+
+    # If the export-symbols file already is a .def file (1st line
+    # is EXPORTS), use it as is.
+    # If DATA tags from a recent dlltool are present, honour them!
+    archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
+	cp $export_symbols $output_objdir/$soname-def;
+      else
+	echo EXPORTS > $output_objdir/$soname-def;
+	_lt_hint=1;
+	cat $export_symbols | while read symbol; do
+	 set dummy \$symbol;
+	 case \[$]# in
+	   2) echo "   \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
+	   *) echo "     \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;;
+	 esac;
+	 _lt_hint=`expr 1 + \$_lt_hint`;
+	done;
+      fi~
+      '"$ltdll_cmds"'
+      $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~
+      $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~
+      $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags'
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+      wlarc=
+    else
+      archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    fi
+    ;;
+
+  solaris* | sysv5*)
+    if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+      ld_shlibs=no
+      cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+    elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+    wlarc=
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+  esac
+
+  if test "$ld_shlibs" = yes; then
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    case $host_os in
+    cygwin* | mingw* | pw32*)
+      # dlltool doesn't understand --whole-archive et. al.
+      whole_archive_flag_spec=
+      ;;
+    *)
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+	whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+	whole_archive_flag_spec=
+      fi
+      ;;
+    esac
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case $host_os in
+  aix3*)
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+    archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$GCC" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # On IA64, the linker does run time linking by default, so we don't
+      # have to do anything special.
+      aix_use_runtimelinking=no
+      exp_sym_flag='-Bexport'
+      no_entry_flag=""
+    else
+      aix_use_runtimelinking=no
+
+      # Test if we are trying to use run time linking or normal
+      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+      # need to do runtime linking.
+      case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+	for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	done
+      esac
+
+      exp_sym_flag='-bexport'
+      no_entry_flag='-bnoentry'
+    fi
+
+    # When large executables or shared objects are built, AIX ld can
+    # have problems creating the table of contents.  If linking a library
+    # or program results in "error TOC overflow" add -mminimal-toc to
+    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+    hardcode_direct=yes
+    archive_cmds=''
+    hardcode_libdir_separator=':'
+    if test "$GCC" = yes; then
+      case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	collect2name=`${CC} -print-prog-name=collect2`
+	if test -f "$collect2name" && \
+	  strings "$collect2name" | grep resolve_lib_name >/dev/null
+	then
+	  # We have reworked collect2
+	  hardcode_direct=yes
+	else
+	  # We have old collect2
+	  hardcode_direct=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L=yes
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_libdir_separator=
+	fi
+      esac
+
+      shared_flag='-shared'
+    else
+      # not using gcc
+      if test "$host_cpu" = ia64; then
+	shared_flag='${wl}-G'
+      else
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag='${wl}-G'
+	else
+	  shared_flag='${wl}-bM:SRE'
+	fi
+      fi
+    fi
+
+    # It seems that -bexpall can do strange things, so it is better to
+    # generate a list of symbols to export.
+    always_export_symbols=yes
+    if test "$aix_use_runtimelinking" = yes; then
+      # Warning - without using the other runtime loading flags (-brtl),
+      # -berok will link without error, but may produce a broken library.
+      allow_undefined_flag='-berok'
+      hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib'
+      archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+    else
+      if test "$host_cpu" = ia64; then
+	hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+	allow_undefined_flag="-z nodefs"
+	archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+      else
+	hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib'
+	# Warning - without using the other run time loading flags,
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='${wl}-berok'
+	# This is a bit strange, but is similar to how AIX traditionally builds
+	# it's shared libraries.
+	archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname'
+      fi
+    fi
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    # see comment about different semantics on the GNU ld section
+    ld_shlibs=no
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec=' '
+    allow_undefined_flag=unsupported
+    # Tell ltmain to make .lib files, not .a files.
+    libext=lib
+    # FIXME: Setting linknames here is a bad hack.
+    archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+    # The linker will automatically build a .lib file if we build a DLL.
+    old_archive_from_new_cmds='true'
+    # FIXME: Should let the user specify the lib program.
+    old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+    fix_srcfile_path='`cygpath -w "$srcfile"`'
+    ;;
+
+  darwin* | rhapsody*)
+    case "$host_os" in
+    rhapsody* | darwin1.[[012]])
+      allow_undefined_flag='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      allow_undefined_flag='-flat_namespace -undefined suppress'
+      ;;
+    esac
+    # FIXME: Relying on posixy $() will cause problems for
+    #        cross-compilation, but unfortunately the echo tests do not
+    #        yet detect zsh echo's removal of \ escapes.
+    archive_cmds='$nonopt $(test "x$module" = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring'
+    # We need to add '_' to the symbols in $export_symbols first
+    #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    whole_archive_flag_spec='-all_load $convenience'
+    ;;
+
+  freebsd1*)
+    ld_shlibs=no
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # does not break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+  freebsd*)
+    archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    case $host_os in
+    hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;;
+    *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;;
+    esac
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_direct=yes
+    hardcode_minus_L=yes # Not in the search PATH, but as the default
+			 # location of the library.
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  irix5* | irix6*)
+    if test "$GCC" = yes; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+    else
+      archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    link_all_deplibs=yes
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+    else
+      archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+    fi
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  newsos6)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_direct=yes
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+    else
+      case "$host_os" in
+      openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_libdir_flag_spec='-R$libdir'
+        ;;
+      *)
+        archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+        hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+        ;;
+      esac
+    fi
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+    ;;
+
+  osf3*)
+    if test "$GCC" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  osf4* | osf5*)	# as osf3* with the addition of -msym flag
+    if test "$GCC" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+      $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+      #Both c and cxx compiler support -rpath directly
+      hardcode_libdir_flag_spec='-rpath $libdir'
+    fi
+    hardcode_libdir_separator=:
+    ;;
+
+  sco3.2v5*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_shlibpath_var=no
+    runpath_var=LD_RUN_PATH
+    hardcode_runpath_var=yes
+    export_dynamic_flag_spec='${wl}-Bexport'
+    ;;
+
+  solaris*)
+    # gcc --version < 3.0 without binutils cannot create self contained
+    # shared libraries reliably, requiring libgcc.a to resolve some of
+    # the object symbols generated in some cases.  Libraries that use
+    # assert need libgcc.a to resolve __eprintf, for example.  Linking
+    # a copy of libgcc.a into every shared library to guarantee resolving
+    # such symbols causes other problems:  According to Tim Van Holder
+    # <tim.van.holder@pandora.be>, C++ libraries end up with a separate
+    # (to the application) exception stack for one thing.
+    no_undefined_flag=' -z defs'
+    if test "$GCC" = yes; then
+      case `$CC --version 2>/dev/null` in
+      [[12]].*)
+	cat <<EOF 1>&2
+
+*** Warning: Releases of GCC earlier than version 3.0 cannot reliably
+*** create self contained shared libraries on Solaris systems, without
+*** introducing a dependency on libgcc.a.  Therefore, libtool is disabling
+*** -no-undefined support, which will at least allow you to build shared
+*** libraries.  However, you may find that when you link such libraries
+*** into an application without using GCC, you have to manually add
+*** \`gcc --print-libgcc-file-name\` to the link command.  We urge you to
+*** upgrade to a newer version of GCC.  Another option is to rebuild your
+*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer.
+
+EOF
+        no_undefined_flag=
+	;;
+      esac
+    fi
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+    case $host_os in
+    solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+    *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+      whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+    esac
+    link_all_deplibs=yes
+    ;;
+
+  sunos4*)
+    if test "x$host_vendor" = xsequent; then
+      # Use $CC to link under sequent, because it throws in some extra .o
+      # files that make .init and .fini sections work.
+      archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+    else
+      archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+    fi
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4)
+    if test "x$host_vendor" = xsno; then
+      archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes # is this really true???
+    else
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+    fi
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4.3*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_shlibpath_var=no
+    export_dynamic_flag_spec='-Bexport'
+    ;;
+
+  sysv5*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+    hardcode_libdir_flag_spec=
+    hardcode_shlibpath_var=no
+    runpath_var='LD_RUN_PATH'
+    ;;
+
+  uts4*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  dgux*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4*MP*)
+    if test -d /usr/nec; then
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ld_shlibs=yes
+    fi
+    ;;
+
+  sysv4.2uw2*)
+    archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_direct=yes
+    hardcode_minus_L=no
+    hardcode_shlibpath_var=no
+    hardcode_runpath_var=yes
+    runpath_var=LD_RUN_PATH
+    ;;
+
+  sysv5uw7* | unixware7*)
+    no_undefined_flag='${wl}-z ${wl}text'
+    if test "$GCC" = yes; then
+      archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+    else
+      archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+    fi
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    ld_shlibs=no
+    ;;
+  esac
+fi
+AC_MSG_RESULT([$ld_shlibs])
+test "$ld_shlibs" = no && can_build_shared=no
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# Check hardcoding attributes.
+AC_MSG_CHECKING([how to hardcode library paths into programs])
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var"; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$hardcode_shlibpath_var" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+AC_MSG_RESULT([$hardcode_action])
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+  AC_MSG_RESULT([no])
+fi
+##
+## END FIXME
+
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+## FIXME: this should be a separate macro
+##
+# PORTME Fill in your ld.so characteristics
+AC_MSG_CHECKING([dynamic linker characteristics])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}.so$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+	if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	     echo ' yes '
+	     echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	  :
+	else
+	  can_build_shared=no
+	fi
+	;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can
+    # not hardcode correct soname into executable. Probably we can
+    # add versioning support to collect2, so additional links can
+    # be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}.so$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}.so'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  export_dynamic_flag_spec=-rdynamic
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  need_version=no
+  need_lib_prefix=no
+  case $GCC,$host_os in
+  yes,cygwin*)
+    library_names_spec='$libname.dll.a'
+    soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll'
+    postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog .libs/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    ;;
+  yes,mingw*)
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll'
+    sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"`
+    ;;
+  yes,pw32*)
+    library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
+    ;;
+  *)
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  # FIXME: Relying on posixy $() will cause problems for
+  #        cross-compilation, but unfortunately the echo tests do not
+  #        yet detect zsh echo's removal of \ escapes.
+  library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)'
+  soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  *)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  shlibpath_var=SHLIB_PATH
+  shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+  library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+  soname_spec='${libname}${release}.sl$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6*)
+  version_type=irix
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so'
+  case $host_os in
+  irix5*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+    soname_spec='${libname}${release}.so$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case "$host_os" in
+    openbsd2.[[89]] | openbsd2.[[89]].*)
+      shlibpath_overrides_runpath=no
+      ;;
+    *)
+      shlibpath_overrides_runpath=yes
+      ;;
+    esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  libname_spec='$name'
+  need_lib_prefix=no
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_version=no
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+    soname_spec='$libname.so.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# Report the final consequences.
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+  ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+##
+## END FIXME
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+AC_LIBTOOL_DLOPEN_SELF
+
+## FIXME: this should be a separate macro
+##
+if test "$enable_shared" = yes && test "$GCC" = yes; then
+  case $archive_cmds in
+  *'~'*)
+    # FIXME: we may have to deal with multi-command sequences.
+    ;;
+  '$CC '*)
+    # Test whether the compiler implicitly links with -lc since on some
+    # systems, -lgcc has to come before -lc. If gcc already passes -lc
+    # to ld, don't add -lc before -lgcc.
+    AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+    AC_CACHE_VAL([lt_cv_archive_cmds_need_lc],
+    [$rm conftest*
+    echo 'static int dummy;' > conftest.$ac_ext
+
+    if AC_TRY_EVAL(ac_compile); then
+      soname=conftest
+      lib=conftest
+      libobjs=conftest.$ac_objext
+      deplibs=
+      wl=$lt_cv_prog_cc_wl
+      compiler_flags=-v
+      linker_flags=-v
+      verstring=
+      output_objdir=.
+      libname=conftest
+      save_allow_undefined_flag=$allow_undefined_flag
+      allow_undefined_flag=
+      if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
+      then
+	lt_cv_archive_cmds_need_lc=no
+      else
+	lt_cv_archive_cmds_need_lc=yes
+      fi
+      allow_undefined_flag=$save_allow_undefined_flag
+    else
+      cat conftest.err 1>&5
+    fi])
+    AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc])
+    ;;
+  esac
+fi
+need_lc=${lt_cv_archive_cmds_need_lc-yes}
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# The second clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  :
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  test -f Makefile && make "$ltmain"
+fi
+
+if test -f "$ltmain"; then
+  trap "$rm \"${ofile}T\"; exit 1" 1 2 15
+  $rm -f "${ofile}T"
+
+  echo creating $ofile
+
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS \
+    AR AR_FLAGS CC LD LN_S NM SHELL \
+    reload_flag reload_cmds wl \
+    pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+    thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+    library_names_spec soname_spec \
+    RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+    old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \
+    postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \
+    old_striplib striplib file_magic_cmd export_symbols_cmds \
+    deplibs_check_method allow_undefined_flag no_undefined_flag \
+    finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+    global_symbol_to_c_name_address \
+    hardcode_libdir_flag_spec hardcode_libdir_separator  \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+    case $var in
+    reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+    extract_expsyms_cmds | old_archive_from_expsyms_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  cat <<__EOF__ > "${ofile}T"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996-2000 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$need_lc
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# The default C compiler.
+CC=$lt_CC
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_wl
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_pic_flag
+pic_mode=$pic_mode
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$lt_compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# ### END LIBTOOL CONFIG
+
+__EOF__
+
+  case $host_os in
+  aix3*)
+    cat <<\EOF >> "${ofile}T"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | os2*)
+    cat <<'EOF' >> "${ofile}T"
+      # This is a source program that is used to create dlls on Windows
+      # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# #  ifdef __CYGWIN32__
+# #    define __CYGWIN__ __CYGWIN32__
+# #  endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+	# This is a source program that is used to create import libraries
+	# on Windows for dlls which lack them. Don't remove nor modify the
+	# starting and closing comments
+# /* impgen.c starts here */
+# /*   Copyright (C) 1999-2000 Free Software Foundation, Inc.
+#
+#  This file is part of GNU libtool.
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#  */
+#
+# #include <stdio.h>		/* for printf() */
+# #include <unistd.h>		/* for open(), lseek(), read() */
+# #include <fcntl.h>		/* for O_RDONLY, O_BINARY */
+# #include <string.h>		/* for strdup() */
+#
+# /* O_BINARY isn't required (or even defined sometimes) under Unix */
+# #ifndef O_BINARY
+# #define O_BINARY 0
+# #endif
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+#      int fd;
+#      int offset;
+# {
+#   unsigned char b[2];
+#   lseek (fd, offset, SEEK_SET);
+#   read (fd, b, 2);
+#   return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+#     int fd;
+#     int offset;
+# {
+#   unsigned char b[4];
+#   lseek (fd, offset, SEEK_SET);
+#   read (fd, b, 4);
+#   return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+#      void *ptr;
+# {
+#   unsigned char *b = ptr;
+#   return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+#     int argc;
+#     char *argv[];
+# {
+#     int dll;
+#     unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+#     unsigned long export_rva, export_size, nsections, secptr, expptr;
+#     unsigned long name_rvas, nexp;
+#     unsigned char *expdata, *erva;
+#     char *filename, *dll_name;
+#
+#     filename = argv[1];
+#
+#     dll = open(filename, O_RDONLY|O_BINARY);
+#     if (dll < 1)
+# 	return 1;
+#
+#     dll_name = filename;
+#
+#     for (i=0; filename[i]; i++)
+# 	if (filename[i] == '/' || filename[i] == '\\'  || filename[i] == ':')
+# 	    dll_name = filename + i +1;
+#
+#     pe_header_offset = pe_get32 (dll, 0x3c);
+#     opthdr_ofs = pe_header_offset + 4 + 20;
+#     num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+#     if (num_entries < 1) /* no exports */
+# 	return 1;
+#
+#     export_rva = pe_get32 (dll, opthdr_ofs + 96);
+#     export_size = pe_get32 (dll, opthdr_ofs + 100);
+#     nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+#     secptr = (pe_header_offset + 4 + 20 +
+# 	      pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+#     expptr = 0;
+#     for (i = 0; i < nsections; i++)
+#     {
+# 	char sname[8];
+# 	unsigned long secptr1 = secptr + 40 * i;
+# 	unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+# 	unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+# 	unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+# 	lseek(dll, secptr1, SEEK_SET);
+# 	read(dll, sname, 8);
+# 	if (vaddr <= export_rva && vaddr+vsize > export_rva)
+# 	{
+# 	    expptr = fptr + (export_rva - vaddr);
+# 	    if (export_rva + export_size > vaddr + vsize)
+# 		export_size = vsize - (export_rva - vaddr);
+# 	    break;
+# 	}
+#     }
+#
+#     expdata = (unsigned char*)malloc(export_size);
+#     lseek (dll, expptr, SEEK_SET);
+#     read (dll, expdata, export_size);
+#     erva = expdata - export_rva;
+#
+#     nexp = pe_as32 (expdata+24);
+#     name_rvas = pe_as32 (expdata+32);
+#
+#     printf ("EXPORTS\n");
+#     for (i = 0; i<nexp; i++)
+#     {
+# 	unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+# 	printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+#     }
+#
+#     return 0;
+# }
+# /* impgen.c ends here */
+
+EOF
+    ;;
+  esac
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "${ofile}T" || (rm -f "${ofile}T"; exit 1)
+
+  mv -f "${ofile}T" "$ofile" || \
+    (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T")
+  chmod +x "$ofile"
+fi
+##
+## END FIXME
+
+])# _LT_AC_LTCONFIG_HACK
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<<  --enable-shared[=PKGS]  build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<<  --enable-static[=PKGS]  build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<<  --enable-fast-install[=PKGS]  optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_LIBTOOL_PICMODE - implement the --with-pic flag
+# Usage: AC_LIBTOOL_PICMODE[(MODE)]
+#   Where MODE is either `yes' or `no'.  If omitted, it defaults to
+#   `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)])
+
+
+# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+  /*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+  ?:/*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+  ;;
+  *)
+  ac_save_MAGIC_CMD="$MAGIC_CMD"
+  IFS="${IFS=   }"; ac_save_ifs="$IFS"; IFS=":"
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="ifelse([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    egrep "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  MAGIC_CMD="$ac_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+])
+
+
+# AC_PATH_MAGIC - find a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl
+AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])
+
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH(gnu-ld,
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by GCC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | [[A-Za-z]]:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+	test "$with_gnu_ld" != no && break
+      else
+	test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+# AC_PROG_LD_GNU -
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  lt_cv_prog_gnu_ld=yes
+else
+  lt_cv_prog_gnu_ld=no
+fi])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])
+
+# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag,
+[lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+])
+
+# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_CACHE_CHECK([how to recognise dependant libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi4*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin* | mingw* | pw32*)
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  case "$host_os" in
+  rhapsody* | darwin1.[[012]])
+    lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1`
+    ;;
+  *) # Darwin 1.3 on
+    lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+    ;;
+  esac
+  ;;
+
+freebsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20*|hpux11*)
+  lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libc.sl
+  ;;
+
+irix5* | irix6*)
+  case $host_os in
+  irix5*)
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+    ;;
+  *)
+    case $LD in
+    *-32|*"-32 ") libmagic=32-bit;;
+    *-n32|*"-n32 ") libmagic=N32;;
+    *-64|*"-64 ") libmagic=64-bit;;
+    *) libmagic=never-match;;
+    esac
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1"
+    ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  case $host_cpu in
+  alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* )
+    lt_cv_deplibs_check_method=pass_all ;;
+  *)
+    # glibc up to 2.1.1 does not perform some relocations on ARM
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so\.[[0-9]]+\.[[0-9]]+$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+openbsd*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object'
+  else
+    lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  # this will be overridden with pass_all, but let us keep it just in case
+  lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sco3.2v5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  lt_cv_file_magic_test_file=/lib/libc.so
+  ;;
+
+sysv5uw[[78]]* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  esac
+  ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+])
+
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl
+AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    tmp_nm=$ac_dir/${ac_tool_prefix}nm
+    if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      # Tru64's nm complains that /dev/null is an invalid object file
+      if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+	lt_cv_path_NM="$tmp_nm -B"
+	break
+      elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+	lt_cv_path_NM="$tmp_nm -p"
+	break
+      else
+	lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32*)
+  # These system don't have libm
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, main, LIBM="-lm")
+  ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-convenience to the
+# configure arguments.  Note that LIBLTDL and INCLTDL are not
+# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If DIR is not
+# provided, it is assumed to be `libltdl'.  LIBLTDL will be prefixed
+# with '${top_builddir}/' and INCLTDL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case $enable_ltdl_convenience in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+  INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-install to the configure
+# arguments.  Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
+# AC_CONFIG_SUBDIRS called.  If DIR is not provided and an installed
+# libltdl is not found, it is assumed to be `libltdl'.  LIBLTDL will
+# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
+# with '${top_srcdir}/' (note the single quotes!).  If your package is
+# not flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, main,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+    INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    INCLTDL=
+  fi
+])
+
+# old names
+AC_DEFUN([AM_PROG_LIBTOOL],   [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED],  [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC],  [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD],        [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM],        [AC_PROG_NM])
+
+# This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/autoconf.h.in
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/autoconf.h.in	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/autoconf.h.in	(revision 20131)
@@ -0,0 +1,92 @@
+/* autoconf.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define to 1 if you have the `bcopy' function. */
+#undef HAVE_BCOPY
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `flock' function. */
+#undef HAVE_FLOCK
+
+/* Define to 1 if you have the `fsync' function. */
+#undef HAVE_FSYNC
+
+/* Define to 1 if you have the `ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Define to 1 if you have the `getopt' function. */
+#undef HAVE_GETOPT
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `dbm' library (-ldbm). */
+#undef HAVE_LIBDBM
+
+/* Define to 1 if you have the `ndbm' library (-lndbm). */
+#undef HAVE_LIBNDBM
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `rename' function. */
+#undef HAVE_RENAME
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if `st_blksize' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLKSIZE
+
+/* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use
+   `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */
+#undef HAVE_ST_BLKSIZE
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `long' if <sys/types.h> does not define. */
+#undef off_t
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/bucket.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/bucket.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/bucket.c	(revision 20131)
@@ -0,0 +1,354 @@
+/* bucket.c - The routines for playing with hash buckets. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+
+#include "gsdlmods.h"
+
+
+/* Initializing a new hash buckets sets all bucket entries to -1 hash value. */
+void
+_gdbm_new_bucket (dbf, bucket, bits)
+     gdbm_file_info *dbf;
+     hash_bucket *bucket;
+     int bits;
+{
+  int index;
+  
+  /* Initialize the avail block. */
+  bucket->av_count = 0;
+
+  /* Set the information fields first. */
+  bucket->bucket_bits = bits;
+  bucket->count = 0;
+  
+  /* Initialize all bucket elements. */
+  for (index = 0; index < dbf->header->bucket_elems; index++)
+    bucket->h_table[index].hash_value = -1;
+}
+
+
+
+/* Find a bucket for DBF that is pointed to by the bucket directory from
+   location DIR_INDEX.   The bucket cache is first checked to see if it
+   is already in memory.  If not, a bucket may be tossed to read the new
+   bucket.  In any case, the requested bucket is make the "current" bucket
+   and dbf->bucket points to the correct bucket. */
+
+void
+_gdbm_get_bucket (dbf, dir_index)
+     gdbm_file_info *dbf;
+     int dir_index;
+{
+  off_t bucket_adr;	/* The address of the correct hash bucket.  */
+  int   num_bytes;	/* The number of bytes read. */
+  off_t	file_pos;	/* The return address for lseek. */
+  register int index;	/* Loop index. */
+  int b;
+
+  /* Initial set up. */
+  dbf->bucket_dir = dir_index;
+  bucket_adr = dbf->dir [dir_index];
+  
+  if (dbf->bucket_cache == NULL)
+    {
+      if(_gdbm_init_cache(dbf, DEFAULT_CACHESIZE) == -1)
+        _gdbm_fatal(dbf, "couldn't init cache");
+    }
+
+  /* Is that one is not already current, we must find it. */
+  if (dbf->cache_entry->ca_adr != bucket_adr)
+    {
+      /* Look in the cache. */
+      for (index = 0; index < dbf->cache_size; index++)
+        {
+	  if (dbf->bucket_cache[index].ca_adr == bucket_adr)
+	    {
+	      dbf->bucket = dbf->bucket_cache[index].ca_bucket;
+	      dbf->cache_entry = &dbf->bucket_cache[index];
+	      return;
+	    }
+        }
+
+      /* It is not in the cache, read it from the disk. */
+      dbf->last_read = (dbf->last_read + 1) % dbf->cache_size;
+      if (dbf->bucket_cache[dbf->last_read].ca_changed)
+	_gdbm_write_bucket (dbf, &dbf->bucket_cache[dbf->last_read]);
+      dbf->bucket_cache[dbf->last_read].ca_adr = bucket_adr;
+      dbf->bucket = dbf->bucket_cache[dbf->last_read].ca_bucket;
+      dbf->cache_entry = &dbf->bucket_cache[dbf->last_read];
+      dbf->cache_entry->ca_data.elem_loc = -1;
+      dbf->cache_entry->ca_changed = FALSE;
+
+      /* Read the bucket. */
+      file_pos = lseek (dbf->desc, bucket_adr, L_SET);
+      if (file_pos != bucket_adr)
+	_gdbm_fatal (dbf, "lseek error");
+
+      num_bytes = read (dbf->desc, dbf->bucket, dbf->header->bucket_size);
+      if (num_bytes != dbf->header->bucket_size)
+	_gdbm_fatal (dbf, "read error");
+
+      // GREENSTONE CUSTOMISATION: Swap each value in the bucket if the GDBM file is the wrong endianness
+      if (wrong_endianness)
+      {
+	endian_swap_array((int*) dbf->bucket, dbf->header->bucket_size);
+
+	// There is a 4-byte string in each hash table entry that we need to leave alone (because character
+	//   strings are not affected by endianness), so convert these back to how they were originally
+	for (b = 0; b < dbf->header->bucket_elems; b++)
+	{
+	  int* key_start = (int*) dbf->bucket->h_table[b].key_start;
+	  *key_start = endian_swap (*key_start);
+	}
+      }
+    }
+
+  return;
+}
+
+
+/* Split the current bucket.  This includes moving all items in the bucket to
+   a new bucket.  This doesn't require any disk reads because all hash values
+   are stored in the buckets.  Splitting the current bucket may require
+   doubling the size of the hash directory.  */
+void
+_gdbm_split_bucket (dbf, next_insert)
+     gdbm_file_info *dbf;
+     int next_insert;
+{
+  hash_bucket *bucket[2]; 	/* Pointers to the new buckets. */
+
+  int          new_bits;	/* The number of bits for the new buckets. */
+  int	       cache_0;		/* Location in the cache for the buckets. */
+  int	       cache_1;
+  off_t        adr_0;		/* File address of the new bucket 0. */
+  off_t        adr_1;		/* File address of the new bucket 1. */
+  avail_elem   old_bucket;	/* Avail Struct for the old bucket. */
+
+  off_t        dir_start0;	/* Used in updating the directory. */
+  off_t        dir_start1;
+  off_t        dir_end;
+
+  off_t       *new_dir;		/* Pointer to the new directory. */
+  off_t        dir_adr; 	/* Address of the new directory. */
+  int          dir_size;	/* Size of the new directory. */
+  off_t        old_adr[31]; 	/* Address of the old directories. */
+  int          old_size[31]; 	/* Size of the old directories. */
+  int	       old_count;	/* Number of old directories. */
+
+  int          index;		/* Used in array indexing. */
+  int          index1;		/* Used in array indexing. */
+  int          elem_loc;	/* Location in new bucket to put element. */
+  bucket_element *old_el;	/* Pointer into the old bucket. */
+  int	       select;		/* Used to index bucket during movement. */
+
+
+  /* No directories are yet old. */
+  old_count = 0;
+
+  if (dbf->bucket_cache == NULL)
+    {
+      if(_gdbm_init_cache(dbf, DEFAULT_CACHESIZE) == -1)
+        _gdbm_fatal(dbf, "couldn't init cache");
+    }
+
+  while (dbf->bucket->count == dbf->header->bucket_elems)
+    {
+      /* Initialize the "new" buckets in the cache. */
+      do
+	{
+	  dbf->last_read = (dbf->last_read + 1) % dbf->cache_size;
+	  cache_0 = dbf->last_read;
+	}      
+      while (dbf->bucket_cache[cache_0].ca_bucket == dbf->bucket);
+      bucket[0] = dbf->bucket_cache[cache_0].ca_bucket;
+      if (dbf->bucket_cache[cache_0].ca_changed)
+	_gdbm_write_bucket (dbf, &dbf->bucket_cache[cache_0]);
+      do
+	{
+	  dbf->last_read = (dbf->last_read + 1) % dbf->cache_size;
+	  cache_1 = dbf->last_read;
+	}      
+      while (dbf->bucket_cache[cache_1].ca_bucket == dbf->bucket);
+      bucket[1] = dbf->bucket_cache[cache_1].ca_bucket;
+      if (dbf->bucket_cache[cache_1].ca_changed)
+	_gdbm_write_bucket (dbf, &dbf->bucket_cache[cache_1]);
+      new_bits = dbf->bucket->bucket_bits+1;
+      _gdbm_new_bucket (dbf, bucket[0], new_bits);
+      _gdbm_new_bucket (dbf, bucket[1], new_bits);
+      adr_0 = _gdbm_alloc (dbf, dbf->header->bucket_size); 
+      dbf->bucket_cache[cache_0].ca_adr = adr_0;
+      adr_1 = _gdbm_alloc (dbf, dbf->header->bucket_size);
+      dbf->bucket_cache[cache_1].ca_adr = adr_1;
+
+      
+      
+      /* Double the directory size if necessary. */
+      if (dbf->header->dir_bits == dbf->bucket->bucket_bits)
+	{
+	  dir_size = dbf->header->dir_size * 2;
+	  dir_adr  = _gdbm_alloc (dbf, dir_size);
+	  new_dir  = (off_t *) malloc (dir_size);
+	  if (new_dir == NULL) _gdbm_fatal (dbf, "malloc error");
+	  for (index = 0;
+	  	index < dbf->header->dir_size/sizeof (off_t); index++)
+	    {
+	      new_dir[2*index]   = dbf->dir[index];
+	      new_dir[2*index+1] = dbf->dir[index];
+	    }
+	  
+	  /* Update header. */
+	  old_adr[old_count] = dbf->header->dir;
+	  dbf->header->dir = dir_adr;
+	  old_size[old_count] = dbf->header->dir_size;
+	  dbf->header->dir_size = dir_size;
+	  dbf->header->dir_bits = new_bits;
+	  old_count++;
+	  
+	  /* Now update dbf.  */
+	  dbf->header_changed = TRUE;
+	  dbf->bucket_dir *= 2;
+	  free (dbf->dir);
+	  dbf->dir = new_dir;
+	}
+
+      /* Copy all elements in dbf->bucket into the new buckets. */
+      for (index = 0; index < dbf->header->bucket_elems; index++)
+	{
+	  old_el = & (dbf->bucket->h_table[index]);
+	  select = (old_el->hash_value >> (31-new_bits)) & 1;
+	  elem_loc = old_el->hash_value % dbf->header->bucket_elems;
+	  while (bucket[select]->h_table[elem_loc].hash_value != -1)
+	    elem_loc = (elem_loc + 1) % dbf->header->bucket_elems;
+	  bucket[select]->h_table[elem_loc] = *old_el;
+	  bucket[select]->count += 1;
+	}
+      
+      /* Allocate avail space for the bucket[1]. */
+      bucket[1]->bucket_avail[0].av_adr
+	= _gdbm_alloc (dbf, dbf->header->block_size);
+      bucket[1]->bucket_avail[0].av_size = dbf->header->block_size;
+      bucket[1]->av_count = 1;
+      
+      /* Copy the avail elements in dbf->bucket to bucket[0]. */
+      bucket[0]->av_count = dbf->bucket->av_count;
+      index = 0;
+      index1 = 0;
+      if (bucket[0]->av_count == BUCKET_AVAIL)
+	{
+	  /* The avail is full, move the first one to bucket[1]. */
+	  _gdbm_put_av_elem (dbf->bucket->bucket_avail[0],
+			     bucket[1]->bucket_avail,
+			     &bucket[1]->av_count, FALSE);
+	  index = 1;
+	  bucket[0]->av_count --;
+	}
+      for (; index < dbf->bucket->av_count; index++)
+	{
+	  bucket[0]->bucket_avail[index1++] = dbf->bucket->bucket_avail[index];
+	}
+      
+      /* Update the directory.  We have new file addresses for both buckets. */
+      dir_start1 = (dbf->bucket_dir >> (dbf->header->dir_bits - new_bits)) | 1;
+      dir_end = (dir_start1 + 1) << (dbf->header->dir_bits - new_bits);
+      dir_start1 = dir_start1 << (dbf->header->dir_bits - new_bits);
+      dir_start0 = dir_start1 - (dir_end - dir_start1);
+      for (index = dir_start0; index < dir_start1; index++)
+	dbf->dir[index] = adr_0;
+      for (index = dir_start1; index < dir_end; index++)
+	dbf->dir[index] = adr_1;
+      
+      
+      /* Set changed flags. */
+      dbf->bucket_cache[cache_0].ca_changed = TRUE;
+      dbf->bucket_cache[cache_1].ca_changed = TRUE;
+      dbf->bucket_changed = TRUE;
+      dbf->directory_changed = TRUE;
+      dbf->second_changed = TRUE;
+      
+      /* Update the cache! */
+      dbf->bucket_dir = next_insert >> (31-dbf->header->dir_bits);
+      
+      /* Invalidate old cache entry. */
+      old_bucket.av_adr  = dbf->cache_entry->ca_adr;
+      old_bucket.av_size = dbf->header->bucket_size;
+      dbf->cache_entry->ca_adr = 0;
+      dbf->cache_entry->ca_changed = FALSE;
+      
+      /* Set dbf->bucket to the proper bucket. */
+      if (dbf->dir[dbf->bucket_dir] == adr_0)
+	{
+	  dbf->bucket = bucket[0];
+	  dbf->cache_entry = &dbf->bucket_cache[cache_0];
+	  _gdbm_put_av_elem (old_bucket,
+			     bucket[1]->bucket_avail,
+			     &bucket[1]->av_count, FALSE);
+	}
+      else
+	{
+	  dbf->bucket = bucket[1];
+	  dbf->cache_entry = &dbf->bucket_cache[cache_1];
+	  _gdbm_put_av_elem (old_bucket,
+			     bucket[0]->bucket_avail,
+			     &bucket[0]->av_count, FALSE);
+	}
+      
+    }
+
+  /* Get rid of old directories. */
+  for (index = 0; index < old_count; index++)
+    _gdbm_free (dbf, old_adr[index], old_size[index]);
+}
+
+
+/* The only place where a bucket is written.  CA_ENTRY is the
+   cache entry containing the bucket to be written. */
+
+void
+_gdbm_write_bucket (dbf, ca_entry)
+     gdbm_file_info *dbf;
+     cache_elem *ca_entry;
+{
+  int  num_bytes;	/* The return value for write. */
+  off_t file_pos;	/* The return value for lseek. */
+  
+  file_pos = lseek (dbf->desc, ca_entry->ca_adr, L_SET);
+  if (file_pos != ca_entry->ca_adr)
+    _gdbm_fatal (dbf, "lseek error");
+  num_bytes = write (dbf->desc, ca_entry->ca_bucket, dbf->header->bucket_size);
+  if (num_bytes != dbf->header->bucket_size)
+    _gdbm_fatal (dbf, "write error");
+  ca_entry->ca_changed = FALSE;
+  ca_entry->ca_data.hash_val = -1;
+  ca_entry->ca_data.elem_loc = -1;
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/close.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/close.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/close.c	(revision 20131)
@@ -0,0 +1,55 @@
+/* close.c - Close the "original" style database. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the original author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+    The author of this file is:
+       e-mail:  downsj@downsj.com
+
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "extern.h"
+
+
+/* it's unclear whether dbmclose() is *always* a void function in old
+   C libraries. we use int, here. */
+
+int
+dbmclose()
+{
+  if (_gdbm_file != NULL)
+    {
+      gdbm_close (_gdbm_file);
+      _gdbm_file = NULL;
+      if (_gdbm_memory.dptr != NULL) free(_gdbm_memory.dptr);
+      _gdbm_memory.dptr = NULL;
+      _gdbm_memory.dsize = 0;
+    }
+  return (0);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/config.guess
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/config.guess	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/config.guess	(revision 20131)
@@ -0,0 +1,1363 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-09-03'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# This shell variable is my proudest work .. or something. --bje
+
+set_cc_for_build='tmpdir=${TMPDIR-/tmp}/config-guess-$$ ;
+(old=`umask` && umask 077 && mkdir $tmpdir && umask $old && unset old)
+   || (echo "$me: cannot create $tmpdir" >&2 && exit 1) ;
+dummy=$tmpdir/dummy ;
+files="$dummy.c $dummy.o $dummy.rel $dummy" ;
+trap '"'"'rm -f $files; rmdir $tmpdir; exit 1'"'"' 1 2 15 ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	rm -f $files ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;
+unset files'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mipseb-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	eval $set_cc_for_build
+	cat <<EOF >$dummy.s
+	.data
+\$Lformat:
+	.byte 37,100,45,37,120,10,0	# "%d-%x\n"
+
+	.text
+	.globl main
+	.align 4
+	.ent main
+main:
+	.frame \$30,16,\$26,0
+	ldgp \$29,0(\$27)
+	.prologue 1
+	.long 0x47e03d80 # implver \$0
+	lda \$2,-1
+	.long 0x47e20c21 # amask \$2,\$1
+	lda \$16,\$Lformat
+	mov \$0,\$17
+	not \$1,\$18
+	jsr \$26,printf
+	ldgp \$29,0(\$26)
+	mov 0,\$16
+	jsr \$26,exit
+	.end main
+EOF
+	$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+	if test "$?" = 0 ; then
+		case `$dummy` in
+			0-0)
+				UNAME_MACHINE="alpha"
+				;;
+			1-0)
+				UNAME_MACHINE="alphaev5"
+				;;
+			1-1)
+				UNAME_MACHINE="alphaev56"
+				;;
+			1-101)
+				UNAME_MACHINE="alphapca56"
+				;;
+			2-303)
+				UNAME_MACHINE="alphaev6"
+				;;
+			2-307)
+				UNAME_MACHINE="alphaev67"
+				;;
+			2-1307)
+				UNAME_MACHINE="alphaev68"
+				;;
+			3-1307)
+				UNAME_MACHINE="alphaev7"
+				;;
+		esac
+	fi
+	rm -f $dummy.s $dummy && rmdir $tmpdir
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD $dummy.c -o $dummy \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+	rm -f $dummy.c $dummy && rmdir $tmpdir
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD $dummy.c -o $dummy && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+		rm -f $dummy.c $dummy && rmdir $tmpdir
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`$dummy`
+		    if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+		    rm -f $dummy.c $dummy && rmdir $tmpdir
+		fi ;;
+	esac
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD $dummy.c -o $dummy && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+	rm -f $dummy.c $dummy && rmdir $tmpdir
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3D:*:*:*)
+	echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	# Determine whether the default compiler uses glibc.
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#if __GLIBC__ >= 2
+	LIBC=gnu
+	#else
+	LIBC=
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	rm -f $dummy.c && rmdir $tmpdir
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:3*)
+	echo i386-pc-interix3
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i386-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	rm -f $dummy.c && rmdir $tmpdir
+	test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	rm -f $dummy.c && rmdir $tmpdir
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	echo `uname -p`-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0
+rm -f $dummy.c $dummy && rmdir $tmpdir
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/config.sub
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/config.sub	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/config.sub	(revision 20131)
@@ -0,0 +1,1470 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002 Free Software Foundation, Inc.
+
+timestamp='2002-09-05'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k \
+	| m32r | m68000 | m68k | m88k | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \
+	| clipper-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* \
+	| m32r-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39 | mipstx39el \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+	| xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	mmix*)
+		basic_machine=mmix-knuth
+		os=-mmixware
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2)
+		basic_machine=i686-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3d)
+		basic_machine=alpha-cray
+		os=-unicos
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+        tic4x | c4x*)
+		basic_machine=tic4x-unknown
+		os=-coff
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	windows32)
+		basic_machine=i386-pc
+		os=-windows32-msvcrt
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto*)
+		os=-nto-qnx
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/configure
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/configure	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/configure	(revision 20131)
@@ -0,0 +1,9476 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for gdbm 1.8.3.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Find the correct PATH separator.  Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+  UNAME=${UNAME-`uname 2>/dev/null`}
+  case X$UNAME in
+    *-DOS) lt_cv_sys_path_separator=';' ;;
+    *)     lt_cv_sys_path_separator=':' ;;
+  esac
+  PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
+  ;;
+esac
+
+echo=${ECHO-echo}
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+
+EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+    then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+   test "X$echo_testing_string" = "X$echo_test_string"; then
+  :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for dir in $PATH /usr/ucb; do
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+	 test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running configure again with it.
+      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+	 echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+	 test "X$echo_testing_string" = "X$echo_test_string"; then
+	# Cool, printf works
+	:
+      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+	   test "X$echo_testing_string" = 'X\t' &&
+	   echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	export CONFIG_SHELL
+	SHELL="$CONFIG_SHELL"
+	export SHELL
+	echo="$CONFIG_SHELL $0 --fallback-echo"
+      elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+	   test "X$echo_testing_string" = 'X\t' &&
+	   echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	echo="$CONFIG_SHELL $0 --fallback-echo"
+      else
+	# maybe with a smaller string...
+	prev=:
+
+	for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+	  if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+	  then
+	    break
+	  fi
+	  prev="$cmd"
+	done
+
+	if test "$prev" != 'sed 50q "$0"'; then
+	  echo_test_string=`eval $prev`
+	  export echo_test_string
+	  exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+	else
+	  # Oops.  We lost completely, so just stick with echo.
+	  echo=echo
+	fi
+      fi
+    fi
+  fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='gdbm'
+PACKAGE_TARNAME='gdbm'
+PACKAGE_VERSION='1.8.3'
+PACKAGE_STRING='gdbm 1.8.3'
+PACKAGE_BUGREPORT=''
+
+ac_unique_file="gdbmdefs.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S ECHO RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP EGREP LIBTOOL COMPAT32BITFLAGS LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures gdbm 1.8.3 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of gdbm 1.8.3:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-shared=PKGS  build shared libraries default=yes
+  --enable-static=PKGS  build static libraries default=yes
+  --enable-fast-install=PKGS  optimize for fast installation default=yes
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-gnu-ld           assume the C compiler uses GNU ld default=no
+  --with-pic              try to use only PIC/non-PIC objects default=use both
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+gdbm configure 1.8.3
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by gdbm $as_me 1.8.3, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers autoconf.h"
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6
+if test "${ac_cv_target+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_target_alias=$target_alias
+test "x$ac_cv_target_alias" = "x" &&
+  ac_cv_target_alias=$ac_cv_host_alias
+ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6
+target=$ac_cv_target
+target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+	;;
+    conftest.$ac_ext )
+	# This is the source file.
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
+    * )
+	break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  export ac_cv_exeext
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX 10.20 and later	-Ae
+# HP-UX older versions	-Aa -D_HPUX_SOURCE
+# SVR4			-Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_shared=yes
+fi;
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_static=yes
+fi;
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+  enableval="$enable_fast_install"
+  p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_fast_install=yes
+fi;
+# Find the correct PATH separator.  Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+  UNAME=${UNAME-`uname 2>/dev/null`}
+  case X$UNAME in
+    *-DOS) lt_cv_sys_path_separator=';' ;;
+    *)     lt_cv_sys_path_separator=':' ;;
+  esac
+  PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi;
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo "$as_me:$LINENO: checking for ld used by GCC" >&5
+echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+else
+  echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$LD"; then
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+	test "$with_gnu_ld" != no && break
+      else
+	test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  lt_cv_prog_gnu_ld=yes
+else
+  lt_cv_prog_gnu_ld=no
+fi
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
+echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6
+if test "${lt_cv_ld_reload_flag+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
+echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
+echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
+if test "${lt_cv_path_NM+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    tmp_nm=$ac_dir/${ac_tool_prefix}nm
+    if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      # Tru64's nm complains that /dev/null is an invalid object file
+      if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+	lt_cv_path_NM="$tmp_nm -B"
+	break
+      elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+	lt_cv_path_NM="$tmp_nm -p"
+	break
+      else
+	lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi
+fi
+
+NM="$lt_cv_path_NM"
+echo "$as_me:$LINENO: result: $NM" >&5
+echo "${ECHO_T}$NM" >&6
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+echo "$as_me:$LINENO: checking how to recognise dependant libraries" >&5
+echo $ECHO_N "checking how to recognise dependant libraries... $ECHO_C" >&6
+if test "${lt_cv_deplibs_check_method+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi4*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin* | mingw* | pw32*)
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  case "$host_os" in
+  rhapsody* | darwin1.[012])
+    lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1`
+    ;;
+  *) # Darwin 1.3 on
+    lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+    ;;
+  esac
+  ;;
+
+freebsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20*|hpux11*)
+  lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libc.sl
+  ;;
+
+irix5* | irix6*)
+  case $host_os in
+  irix5*)
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+    ;;
+  *)
+    case $LD in
+    *-32|*"-32 ") libmagic=32-bit;;
+    *-n32|*"-n32 ") libmagic=N32;;
+    *-64|*"-64 ") libmagic=64-bit;;
+    *) libmagic=never-match;;
+    esac
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
+    ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  case $host_cpu in
+  alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* )
+    lt_cv_deplibs_check_method=pass_all ;;
+  *)
+    # glibc up to 2.1.1 does not perform some relocations on ARM
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+openbsd*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+  else
+    lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  # this will be overridden with pass_all, but let us keep it just in case
+  lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sco3.2v5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  lt_cv_file_magic_test_file=/lib/libc.so
+  ;;
+
+sysv5uw[78]* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  esac
+  ;;
+esac
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
+echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+
+
+
+
+
+
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo "$as_me:$LINENO: checking command to parse $NM output" >&5
+echo $ECHO_N "checking command to parse $NM output... $ECHO_C" >&6
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+  lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  ;;
+irix*)
+  symcode='[BCDEGRST]'
+  ;;
+solaris* | sysv5*)
+  symcode='[BDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $host_os in
+mingw*)
+  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ 	]\($symcode$symcode*\)[ 	][ 	]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+  rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5
+  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+	if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext'
+
+	  cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+	  sed "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext
+	  cat <<\EOF >> conftest.$ac_ext
+  {0, (lt_ptr) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  save_LIBS="$LIBS"
+	  save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$no_builtin_flag"
+	  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$save_LIBS"
+	  CFLAGS="$save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -f conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+global_symbol_pipe="$lt_cv_sys_global_symbol_pipe"
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  global_symbol_to_cdecl=
+  global_symbol_to_c_name_address=
+else
+  global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl"
+  global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address"
+fi
+if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address";
+then
+  echo "$as_me:$LINENO: result: failed" >&5
+echo "${ECHO_T}failed" >&6
+else
+  echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+fi
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in dlfcn.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the gdbm lists.  ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
+echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAGIC_CMD in
+  /*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+  ?:/*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+  ;;
+  *)
+  ac_save_MAGIC_CMD="$MAGIC_CMD"
+  IFS="${IFS=   }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="/usr/bin:$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    egrep "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  MAGIC_CMD="$ac_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    echo "$as_me:$LINENO: checking for file" >&5
+echo $ECHO_N "checking for file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAGIC_CMD in
+  /*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+  ?:/*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+  ;;
+  *)
+  ac_save_MAGIC_CMD="$MAGIC_CMD"
+  IFS="${IFS=   }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="/usr/bin:$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    egrep "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  MAGIC_CMD="$ac_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  STRIP=$ac_ct_STRIP
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+
+enable_dlopen=no
+enable_win32_dll=no
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+
+fi;
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 4180 "configure"' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
+echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6
+if test "${lt_cv_cc_needs_belf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  lt_cv_cc_needs_belf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+lt_cv_cc_needs_belf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
+echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+need_locks="$enable_libtool_lock"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+if test x"$host" != x"$build"; then
+  ac_tool_prefix=${host_alias}-
+else
+  ac_tool_prefix=
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case $host_os in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+    ;;
+  *)
+    old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+## FIXME: this should be a separate macro
+##
+echo "$as_me:$LINENO: checking for objdir" >&5
+echo $ECHO_N "checking for objdir... $ECHO_C" >&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$as_me:$LINENO: result: $objdir" >&5
+echo "${ECHO_T}$objdir" >&6
+##
+## END FIXME
+
+
+## FIXME: this should be a separate macro
+##
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+  withval="$with_pic"
+  pic_mode="$withval"
+else
+  pic_mode=default
+fi;
+test -z "$pic_mode" && pic_mode=default
+
+# We assume here that the value for lt_cv_prog_cc_pic will not be cached
+# in isolation, and that seeing it set (from the cache) indicates that
+# the associated values are set (in the cache) correctly too.
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+if test "${lt_cv_prog_cc_pic+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+   lt_cv_prog_cc_pic=
+  lt_cv_prog_cc_shlib=
+  lt_cv_prog_cc_wl=
+  lt_cv_prog_cc_static=
+  lt_cv_prog_cc_no_builtin=
+  lt_cv_prog_cc_can_build_shared=$can_build_shared
+
+  if test "$GCC" = yes; then
+    lt_cv_prog_cc_wl='-Wl,'
+    lt_cv_prog_cc_static='-static'
+
+    case $host_os in
+    aix*)
+      # Below there is a dirty hack to force normal static linking with -ldl
+      # The problem is because libdl dynamically linked with both libc and
+      # libC (AIX C++ library), which obviously doesn't included in libraries
+      # list by gcc. This cause undefined symbols with -static flags.
+      # This hack allows C programs to be linked with "-static -ldl", but
+      # not sure about C++ programs.
+      lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC"
+      ;;
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
+      ;;
+    beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_cv_prog_cc_pic='-fno-common'
+      ;;
+    cygwin* | mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_cv_prog_cc_pic='-DDLL_EXPORT'
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	 lt_cv_prog_cc_pic=-Kconform_pic
+      fi
+      ;;
+    *)
+      lt_cv_prog_cc_pic='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for PIC flags for the system compiler.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      lt_cv_prog_cc_wl='-Wl,'
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_cv_prog_cc_static='-Bstatic'
+      else
+	lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      # Is there a better lt_cv_prog_cc_static that works with the bundled CC?
+      lt_cv_prog_cc_wl='-Wl,'
+      lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive"
+      lt_cv_prog_cc_pic='+Z'
+      ;;
+
+    irix5* | irix6*)
+      lt_cv_prog_cc_wl='-Wl,'
+      lt_cv_prog_cc_static='-non_shared'
+      # PIC (with -KPIC) is the default.
+      ;;
+
+    cygwin* | mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_cv_prog_cc_pic='-DDLL_EXPORT'
+      ;;
+
+    newsos6)
+      lt_cv_prog_cc_pic='-KPIC'
+      lt_cv_prog_cc_static='-Bstatic'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      # All OSF/1 code is PIC.
+      lt_cv_prog_cc_wl='-Wl,'
+      lt_cv_prog_cc_static='-non_shared'
+      ;;
+
+    sco3.2v5*)
+      lt_cv_prog_cc_pic='-Kpic'
+      lt_cv_prog_cc_static='-dn'
+      lt_cv_prog_cc_shlib='-belf'
+      ;;
+
+    solaris*)
+      lt_cv_prog_cc_pic='-KPIC'
+      lt_cv_prog_cc_static='-Bstatic'
+      lt_cv_prog_cc_wl='-Wl,'
+      ;;
+
+    sunos4*)
+      lt_cv_prog_cc_pic='-PIC'
+      lt_cv_prog_cc_static='-Bstatic'
+      lt_cv_prog_cc_wl='-Qoption ld '
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+      lt_cv_prog_cc_pic='-KPIC'
+      lt_cv_prog_cc_static='-Bstatic'
+      if test "x$host_vendor" = xsni; then
+	lt_cv_prog_cc_wl='-LD'
+      else
+	lt_cv_prog_cc_wl='-Wl,'
+      fi
+      ;;
+
+    uts4*)
+      lt_cv_prog_cc_pic='-pic'
+      lt_cv_prog_cc_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_cv_prog_cc_pic='-Kconform_pic'
+	lt_cv_prog_cc_static='-Bstatic'
+      fi
+      ;;
+
+    *)
+      lt_cv_prog_cc_can_build_shared=no
+      ;;
+    esac
+  fi
+
+fi
+
+if test -z "$lt_cv_prog_cc_pic"; then
+  echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6
+else
+  echo "$as_me:$LINENO: result: $lt_cv_prog_cc_pic" >&5
+echo "${ECHO_T}$lt_cv_prog_cc_pic" >&6
+
+  # Check to make sure the pic_flag actually works.
+  echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_cv_prog_cc_pic works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_cv_prog_cc_pic works... $ECHO_C" >&6
+  if test "${lt_cv_prog_cc_pic_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      save_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+        case $host_os in
+      hpux9* | hpux10* | hpux11*)
+	# On HP-UX, both CC and GCC only warn that PIC is supported... then
+	# they create non-PIC objects.  So, if there were any warnings, we
+	# assume that PIC is not supported.
+	if test -s conftest.err; then
+	  lt_cv_prog_cc_pic_works=no
+	else
+	  lt_cv_prog_cc_pic_works=yes
+	fi
+	;;
+      *)
+	lt_cv_prog_cc_pic_works=yes
+	;;
+      esac
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+      lt_cv_prog_cc_pic_works=no
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+    CFLAGS="$save_CFLAGS"
+
+fi
+
+
+  if test "X$lt_cv_prog_cc_pic_works" = Xno; then
+    lt_cv_prog_cc_pic=
+    lt_cv_prog_cc_can_build_shared=no
+  else
+    lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic"
+  fi
+
+  echo "$as_me:$LINENO: result: $lt_cv_prog_cc_pic_works" >&5
+echo "${ECHO_T}$lt_cv_prog_cc_pic_works" >&6
+fi
+##
+## END FIXME
+
+# Check for any special shared library compilation flags.
+if test -n "$lt_cv_prog_cc_shlib"; then
+  { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&5
+echo "$as_me: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&2;}
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[ 	]$lt_cv_prog_cc_shlib[ 	]" >/dev/null; then :
+  else
+   { echo "$as_me:$LINENO: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5
+echo "$as_me: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;}
+    lt_cv_prog_cc_can_build_shared=no
+  fi
+fi
+
+## FIXME: this should be a separate macro
+##
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_cv_prog_cc_static works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_cv_prog_cc_static works... $ECHO_C" >&6
+if test "${lt_cv_prog_cc_static_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    lt_cv_prog_cc_static_works=no
+  save_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  lt_cv_prog_cc_static_works=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS="$save_LDFLAGS"
+
+fi
+
+
+# Belt *and* braces to stop my trousers falling down:
+test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static=
+echo "$as_me:$LINENO: result: $lt_cv_prog_cc_static_works" >&5
+echo "${ECHO_T}$lt_cv_prog_cc_static_works" >&6
+
+pic_flag="$lt_cv_prog_cc_pic"
+special_shlib_compile_flags="$lt_cv_prog_cc_shlib"
+wl="$lt_cv_prog_cc_wl"
+link_static_flag="$lt_cv_prog_cc_static"
+no_builtin_flag="$lt_cv_prog_cc_no_builtin"
+can_build_shared="$lt_cv_prog_cc_can_build_shared"
+##
+## END FIXME
+
+
+## FIXME: this should be a separate macro
+##
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_compiler_c_o+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+echo "int some_variable = 0;" > conftest.$ac_ext
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory.  Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
+compiler_c_o=no
+if { (eval echo configure:4756: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+  # The compiler can only warn and ignore the option if not recognized
+  # So say no if there are warnings
+  if test -s out/conftest.err; then
+    lt_cv_compiler_c_o=no
+  else
+    lt_cv_compiler_c_o=yes
+  fi
+else
+  # Append any errors to the config.log.
+  cat out/conftest.err 1>&5
+  lt_cv_compiler_c_o=no
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+fi
+
+compiler_c_o=$lt_cv_compiler_c_o
+echo "$as_me:$LINENO: result: $compiler_c_o" >&5
+echo "${ECHO_T}$compiler_c_o" >&6
+
+if test x"$compiler_c_o" = x"yes"; then
+  # Check to see if we can write to a .lo
+  echo "$as_me:$LINENO: checking if $compiler supports -c -o file.lo" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.lo... $ECHO_C" >&6
+  if test "${lt_cv_compiler_o_lo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+  lt_cv_compiler_o_lo=no
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -c -o conftest.lo"
+  save_objext="$ac_objext"
+  ac_objext=lo
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int some_variable = 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+      # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+    if test -s conftest.err; then
+      lt_cv_compiler_o_lo=no
+    else
+      lt_cv_compiler_o_lo=yes
+    fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  ac_objext="$save_objext"
+  CFLAGS="$save_CFLAGS"
+
+fi
+
+  compiler_o_lo=$lt_cv_compiler_o_lo
+  echo "$as_me:$LINENO: result: $compiler_o_lo" >&5
+echo "${ECHO_T}$compiler_o_lo" >&6
+else
+  compiler_o_lo=no
+fi
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+if test "$GCC" = yes; then
+  # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+  echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext"
+  compiler_rtti_exceptions=no
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int some_variable = 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+      # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+    if test -s conftest.err; then
+      compiler_rtti_exceptions=no
+    else
+      compiler_rtti_exceptions=yes
+    fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS="$save_CFLAGS"
+  echo "$as_me:$LINENO: result: $compiler_rtti_exceptions" >&5
+echo "${ECHO_T}$compiler_rtti_exceptions" >&6
+
+  if test "$compiler_rtti_exceptions" = "yes"; then
+    no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+  else
+    no_builtin_flag=' -fno-builtin'
+  fi
+fi
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# See if the linker supports building shared libraries.
+echo "$as_me:$LINENO: checking whether the linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+old_archive_from_expsyms_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_into_libs=no
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+link_all_deplibs=unknown
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced.  Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+extract_expsyms_cmds=
+
+case $host_os in
+cygwin* | mingw* | pw32*)
+  # FIXME: the MSVC++ port hasn't been tested in a loooong time
+  # When not using gcc, we currently assume that we are using
+  # Microsoft Visual C++.
+  if test "$GCC" != yes; then
+    with_gnu_ld=no
+  fi
+  ;;
+openbsd*)
+  with_gnu_ld=no
+  ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # If archive_cmds runs LD, not CC, wlarc should be empty
+  wlarc='${wl}'
+
+  # See if GNU ld supports shared libraries.
+  case $host_os in
+  aix3* | aix4* | aix5*)
+    # On AIX, the GNU linker is very broken
+    # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available.
+    ld_shlibs=no
+    cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+
+    # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+    # that the semantics of dynamic libraries on AmigaOS, at least up
+    # to version 4, is to share data among multiple programs linked
+    # with the same dynamic library.  Since this doesn't match the
+    # behavior of shared libraries on other platforms, we can use
+    # them.
+    ld_shlibs=no
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag=unsupported
+      # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec='-L$libdir'
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+
+    extract_expsyms_cmds='test -f $output_objdir/impgen.c || \
+      sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~
+      test -f $output_objdir/impgen.exe || (cd $output_objdir && \
+      if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \
+      else $CC -o impgen impgen.c ; fi)~
+      $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def'
+
+    old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib'
+
+    # cygwin and mingw dlls have different entry points and sets of symbols
+    # to exclude.
+    # FIXME: what about values for MSVC?
+    dll_entry=__cygwin_dll_entry@12
+    dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~
+    case $host_os in
+    mingw*)
+      # mingw values
+      dll_entry=_DllMainCRTStartup@12
+      dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~
+      ;;
+    esac
+
+    # mingw and cygwin differ, and it's simplest to just exclude the union
+    # of the two symbol sets.
+    dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12
+
+    # recent cygwin and mingw systems supply a stub DllMain which the user
+    # can override, but on older systems we have to supply one (in ltdll.c)
+    if test "x$lt_cv_need_dllmain" = "xyes"; then
+      ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext "
+      ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~
+	test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~'
+    else
+      ltdll_obj=
+      ltdll_cmds=
+    fi
+
+    # Extract the symbol export list from an `--export-all' def file,
+    # then regenerate the def file from the symbol export list, so that
+    # the compiled dll only exports the symbol export list.
+    # Be careful not to strip the DATA tag left be newer dlltools.
+    export_symbols_cmds="$ltdll_cmds"'
+      $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~
+      sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols'
+
+    # If the export-symbols file already is a .def file (1st line
+    # is EXPORTS), use it as is.
+    # If DATA tags from a recent dlltool are present, honour them!
+    archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
+	cp $export_symbols $output_objdir/$soname-def;
+      else
+	echo EXPORTS > $output_objdir/$soname-def;
+	_lt_hint=1;
+	cat $export_symbols | while read symbol; do
+	 set dummy \$symbol;
+	 case \$# in
+	   2) echo "   \$2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
+	   *) echo "     \$2 @ \$_lt_hint \$3 ; " >> $output_objdir/$soname-def;;
+	 esac;
+	 _lt_hint=`expr 1 + \$_lt_hint`;
+	done;
+      fi~
+      '"$ltdll_cmds"'
+      $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~
+      $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~
+      $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags'
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+      wlarc=
+    else
+      archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    fi
+    ;;
+
+  solaris* | sysv5*)
+    if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+      ld_shlibs=no
+      cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+    elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+    wlarc=
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+  esac
+
+  if test "$ld_shlibs" = yes; then
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    case $host_os in
+    cygwin* | mingw* | pw32*)
+      # dlltool doesn't understand --whole-archive et. al.
+      whole_archive_flag_spec=
+      ;;
+    *)
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+	whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+	whole_archive_flag_spec=
+      fi
+      ;;
+    esac
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case $host_os in
+  aix3*)
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+    archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$GCC" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # On IA64, the linker does run time linking by default, so we don't
+      # have to do anything special.
+      aix_use_runtimelinking=no
+      exp_sym_flag='-Bexport'
+      no_entry_flag=""
+    else
+      aix_use_runtimelinking=no
+
+      # Test if we are trying to use run time linking or normal
+      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+      # need to do runtime linking.
+      case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+	for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	done
+      esac
+
+      exp_sym_flag='-bexport'
+      no_entry_flag='-bnoentry'
+    fi
+
+    # When large executables or shared objects are built, AIX ld can
+    # have problems creating the table of contents.  If linking a library
+    # or program results in "error TOC overflow" add -mminimal-toc to
+    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+    hardcode_direct=yes
+    archive_cmds=''
+    hardcode_libdir_separator=':'
+    if test "$GCC" = yes; then
+      case $host_os in aix4.[012]|aix4.[012].*)
+	collect2name=`${CC} -print-prog-name=collect2`
+	if test -f "$collect2name" && \
+	  strings "$collect2name" | grep resolve_lib_name >/dev/null
+	then
+	  # We have reworked collect2
+	  hardcode_direct=yes
+	else
+	  # We have old collect2
+	  hardcode_direct=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L=yes
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_libdir_separator=
+	fi
+      esac
+
+      shared_flag='-shared'
+    else
+      # not using gcc
+      if test "$host_cpu" = ia64; then
+	shared_flag='${wl}-G'
+      else
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag='${wl}-G'
+	else
+	  shared_flag='${wl}-bM:SRE'
+	fi
+      fi
+    fi
+
+    # It seems that -bexpall can do strange things, so it is better to
+    # generate a list of symbols to export.
+    always_export_symbols=yes
+    if test "$aix_use_runtimelinking" = yes; then
+      # Warning - without using the other runtime loading flags (-brtl),
+      # -berok will link without error, but may produce a broken library.
+      allow_undefined_flag='-berok'
+      hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib'
+      archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+    else
+      if test "$host_cpu" = ia64; then
+	hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+	allow_undefined_flag="-z nodefs"
+	archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+      else
+	hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib'
+	# Warning - without using the other run time loading flags,
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='${wl}-berok'
+	# This is a bit strange, but is similar to how AIX traditionally builds
+	# it's shared libraries.
+	archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname'
+      fi
+    fi
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    # see comment about different semantics on the GNU ld section
+    ld_shlibs=no
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec=' '
+    allow_undefined_flag=unsupported
+    # Tell ltmain to make .lib files, not .a files.
+    libext=lib
+    # FIXME: Setting linknames here is a bad hack.
+    archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+    # The linker will automatically build a .lib file if we build a DLL.
+    old_archive_from_new_cmds='true'
+    # FIXME: Should let the user specify the lib program.
+    old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+    fix_srcfile_path='`cygpath -w "$srcfile"`'
+    ;;
+
+  darwin* | rhapsody*)
+    case "$host_os" in
+    rhapsody* | darwin1.[012])
+      allow_undefined_flag='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      allow_undefined_flag='-flat_namespace -undefined suppress'
+      ;;
+    esac
+    # FIXME: Relying on posixy $() will cause problems for
+    #        cross-compilation, but unfortunately the echo tests do not
+    #        yet detect zsh echo's removal of \ escapes.
+    archive_cmds='$nonopt $(test "x$module" = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring'
+    # We need to add '_' to the symbols in $export_symbols first
+    #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    whole_archive_flag_spec='-all_load $convenience'
+    ;;
+
+  freebsd1*)
+    ld_shlibs=no
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # does not break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+  freebsd*)
+    archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    case $host_os in
+    hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;;
+    *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;;
+    esac
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_direct=yes
+    hardcode_minus_L=yes # Not in the search PATH, but as the default
+			 # location of the library.
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  irix5* | irix6*)
+    if test "$GCC" = yes; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+    else
+      archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    link_all_deplibs=yes
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+    else
+      archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+    fi
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  newsos6)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_direct=yes
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+    else
+      case "$host_os" in
+      openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_libdir_flag_spec='-R$libdir'
+        ;;
+      *)
+        archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+        hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+        ;;
+      esac
+    fi
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+    ;;
+
+  osf3*)
+    if test "$GCC" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  osf4* | osf5*)	# as osf3* with the addition of -msym flag
+    if test "$GCC" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+      $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+      #Both c and cxx compiler support -rpath directly
+      hardcode_libdir_flag_spec='-rpath $libdir'
+    fi
+    hardcode_libdir_separator=:
+    ;;
+
+  sco3.2v5*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_shlibpath_var=no
+    runpath_var=LD_RUN_PATH
+    hardcode_runpath_var=yes
+    export_dynamic_flag_spec='${wl}-Bexport'
+    ;;
+
+  solaris*)
+    # gcc --version < 3.0 without binutils cannot create self contained
+    # shared libraries reliably, requiring libgcc.a to resolve some of
+    # the object symbols generated in some cases.  Libraries that use
+    # assert need libgcc.a to resolve __eprintf, for example.  Linking
+    # a copy of libgcc.a into every shared library to guarantee resolving
+    # such symbols causes other problems:  According to Tim Van Holder
+    # <tim.van.holder@pandora.be>, C++ libraries end up with a separate
+    # (to the application) exception stack for one thing.
+    no_undefined_flag=' -z defs'
+    if test "$GCC" = yes; then
+      case `$CC --version 2>/dev/null` in
+      [12].*)
+	cat <<EOF 1>&2
+
+*** Warning: Releases of GCC earlier than version 3.0 cannot reliably
+*** create self contained shared libraries on Solaris systems, without
+*** introducing a dependency on libgcc.a.  Therefore, libtool is disabling
+*** -no-undefined support, which will at least allow you to build shared
+*** libraries.  However, you may find that when you link such libraries
+*** into an application without using GCC, you have to manually add
+*** \`gcc --print-libgcc-file-name\` to the link command.  We urge you to
+*** upgrade to a newer version of GCC.  Another option is to rebuild your
+*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer.
+
+EOF
+        no_undefined_flag=
+	;;
+      esac
+    fi
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+    case $host_os in
+    solaris2.[0-5] | solaris2.[0-5].*) ;;
+    *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+      whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+    esac
+    link_all_deplibs=yes
+    ;;
+
+  sunos4*)
+    if test "x$host_vendor" = xsequent; then
+      # Use $CC to link under sequent, because it throws in some extra .o
+      # files that make .init and .fini sections work.
+      archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+    else
+      archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+    fi
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4)
+    if test "x$host_vendor" = xsno; then
+      archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes # is this really true???
+    else
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+    fi
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4.3*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_shlibpath_var=no
+    export_dynamic_flag_spec='-Bexport'
+    ;;
+
+  sysv5*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+    hardcode_libdir_flag_spec=
+    hardcode_shlibpath_var=no
+    runpath_var='LD_RUN_PATH'
+    ;;
+
+  uts4*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  dgux*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4*MP*)
+    if test -d /usr/nec; then
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ld_shlibs=yes
+    fi
+    ;;
+
+  sysv4.2uw2*)
+    archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+    hardcode_direct=yes
+    hardcode_minus_L=no
+    hardcode_shlibpath_var=no
+    hardcode_runpath_var=yes
+    runpath_var=LD_RUN_PATH
+    ;;
+
+  sysv5uw7* | unixware7*)
+    no_undefined_flag='${wl}-z ${wl}text'
+    if test "$GCC" = yes; then
+      archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+    else
+      archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+    fi
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    ld_shlibs=no
+    ;;
+  esac
+fi
+echo "$as_me:$LINENO: result: $ld_shlibs" >&5
+echo "${ECHO_T}$ld_shlibs" >&6
+test "$ld_shlibs" = no && can_build_shared=no
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# Check hardcoding attributes.
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var"; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$hardcode_shlibpath_var" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action" >&5
+echo "${ECHO_T}$hardcode_action" >&6
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+striplib=
+old_striplib=
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+##
+## END FIXME
+
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+## FIXME: this should be a separate macro
+##
+# PORTME Fill in your ld.so characteristics
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}.so$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+	if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	     echo ' yes '
+	     echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	  :
+	else
+	  can_build_shared=no
+	fi
+	;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can
+    # not hardcode correct soname into executable. Probably we can
+    # add versioning support to collect2, so additional links can
+    # be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}.so$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}.so'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  export_dynamic_flag_spec=-rdynamic
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  need_version=no
+  need_lib_prefix=no
+  case $GCC,$host_os in
+  yes,cygwin*)
+    library_names_spec='$libname.dll.a'
+    soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
+    postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog .libs/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    ;;
+  yes,mingw*)
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
+    sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"`
+    ;;
+  yes,pw32*)
+    library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/./-/g'`${versuffix}.dll'
+    ;;
+  *)
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  # FIXME: Relying on posixy $() will cause problems for
+  #        cross-compilation, but unfortunately the echo tests do not
+  #        yet detect zsh echo's removal of \ escapes.
+  library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)'
+  soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  *)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  shlibpath_var=SHLIB_PATH
+  shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+  library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+  soname_spec='${libname}${release}.sl$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6*)
+  version_type=irix
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so'
+  case $host_os in
+  irix5*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+    soname_spec='${libname}${release}.so$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case "$host_os" in
+    openbsd2.[89] | openbsd2.[89].*)
+      shlibpath_overrides_runpath=no
+      ;;
+    *)
+      shlibpath_overrides_runpath=yes
+      ;;
+    esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  libname_spec='$name'
+  need_lib_prefix=no
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_version=no
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+    soname_spec='$libname.so.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# Report the final consequences.
+echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+  ;;
+esac
+echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6
+##
+## END FIXME
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  *)
+    echo "$as_me:$LINENO: checking for shl_load" >&5
+echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
+if test "${ac_cv_func_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define shl_load innocuous_shl_load
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef shl_load
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+char (*f) () = shl_load;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != shl_load;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
+echo "${ECHO_T}$ac_cv_func_shl_load" >&6
+if test $ac_cv_func_shl_load = yes; then
+  lt_cv_dlopen="shl_load"
+else
+  echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+  echo "$as_me:$LINENO: checking for dlopen" >&5
+echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
+if test "${ac_cv_func_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define dlopen innocuous_dlopen
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef dlopen
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+char (*f) () = dlopen;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dlopen;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
+echo "${ECHO_T}$ac_cv_func_dlopen" >&6
+if test $ac_cv_func_dlopen = yes; then
+  lt_cv_dlopen="dlopen"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
+echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_svld_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_svld_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
+if test $ac_cv_lib_svld_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
+echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dld_link ();
+int
+main ()
+{
+dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_dld_link=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_dld_link=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
+if test $ac_cv_lib_dld_dld_link = yes; then
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+        test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
+echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 6691 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self" >&6
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      LDFLAGS="$LDFLAGS $link_static_flag"
+      echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
+echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 6789 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+## FIXME: this should be a separate macro
+##
+if test "$enable_shared" = yes && test "$GCC" = yes; then
+  case $archive_cmds in
+  *'~'*)
+    # FIXME: we may have to deal with multi-command sequences.
+    ;;
+  '$CC '*)
+    # Test whether the compiler implicitly links with -lc since on some
+    # systems, -lgcc has to come before -lc. If gcc already passes -lc
+    # to ld, don't add -lc before -lgcc.
+    echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+    if test "${lt_cv_archive_cmds_need_lc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  $rm conftest*
+    echo 'static int dummy;' > conftest.$ac_ext
+
+    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+      soname=conftest
+      lib=conftest
+      libobjs=conftest.$ac_objext
+      deplibs=
+      wl=$lt_cv_prog_cc_wl
+      compiler_flags=-v
+      linker_flags=-v
+      verstring=
+      output_objdir=.
+      libname=conftest
+      save_allow_undefined_flag=$allow_undefined_flag
+      allow_undefined_flag=
+      if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+      then
+	lt_cv_archive_cmds_need_lc=no
+      else
+	lt_cv_archive_cmds_need_lc=yes
+      fi
+      allow_undefined_flag=$save_allow_undefined_flag
+    else
+      cat conftest.err 1>&5
+    fi
+fi
+
+    echo "$as_me:$LINENO: result: $lt_cv_archive_cmds_need_lc" >&5
+echo "${ECHO_T}$lt_cv_archive_cmds_need_lc" >&6
+    ;;
+  esac
+fi
+need_lc=${lt_cv_archive_cmds_need_lc-yes}
+##
+## END FIXME
+
+## FIXME: this should be a separate macro
+##
+# The second clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  :
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  test -f Makefile && make "$ltmain"
+fi
+
+if test -f "$ltmain"; then
+  trap "$rm \"${ofile}T\"; exit 1" 1 2 15
+  $rm -f "${ofile}T"
+
+  echo creating $ofile
+
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS \
+    AR AR_FLAGS CC LD LN_S NM SHELL \
+    reload_flag reload_cmds wl \
+    pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+    thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+    library_names_spec soname_spec \
+    RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+    old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \
+    postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \
+    old_striplib striplib file_magic_cmd export_symbols_cmds \
+    deplibs_check_method allow_undefined_flag no_undefined_flag \
+    finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+    global_symbol_to_c_name_address \
+    hardcode_libdir_flag_spec hardcode_libdir_separator  \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+    case $var in
+    reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+    extract_expsyms_cmds | old_archive_from_expsyms_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  cat <<__EOF__ > "${ofile}T"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996-2000 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$need_lc
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# The default C compiler.
+CC=$lt_CC
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_wl
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_pic_flag
+pic_mode=$pic_mode
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$lt_compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# ### END LIBTOOL CONFIG
+
+__EOF__
+
+  case $host_os in
+  aix3*)
+    cat <<\EOF >> "${ofile}T"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | os2*)
+    cat <<'EOF' >> "${ofile}T"
+      # This is a source program that is used to create dlls on Windows
+      # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# #  ifdef __CYGWIN32__
+# #    define __CYGWIN__ __CYGWIN32__
+# #  endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+	# This is a source program that is used to create import libraries
+	# on Windows for dlls which lack them. Don't remove nor modify the
+	# starting and closing comments
+# /* impgen.c starts here */
+# /*   Copyright (C) 1999-2000 Free Software Foundation, Inc.
+#
+#  This file is part of GNU libtool.
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#  */
+#
+# #include <stdio.h>		/* for printf() */
+# #include <unistd.h>		/* for open(), lseek(), read() */
+# #include <fcntl.h>		/* for O_RDONLY, O_BINARY */
+# #include <string.h>		/* for strdup() */
+#
+# /* O_BINARY isn't required (or even defined sometimes) under Unix */
+# #ifndef O_BINARY
+# #define O_BINARY 0
+# #endif
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+#      int fd;
+#      int offset;
+# {
+#   unsigned char b[2];
+#   lseek (fd, offset, SEEK_SET);
+#   read (fd, b, 2);
+#   return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+#     int fd;
+#     int offset;
+# {
+#   unsigned char b[4];
+#   lseek (fd, offset, SEEK_SET);
+#   read (fd, b, 4);
+#   return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+#      void *ptr;
+# {
+#   unsigned char *b = ptr;
+#   return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+#     int argc;
+#     char *argv[];
+# {
+#     int dll;
+#     unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+#     unsigned long export_rva, export_size, nsections, secptr, expptr;
+#     unsigned long name_rvas, nexp;
+#     unsigned char *expdata, *erva;
+#     char *filename, *dll_name;
+#
+#     filename = argv[1];
+#
+#     dll = open(filename, O_RDONLY|O_BINARY);
+#     if (dll < 1)
+# 	return 1;
+#
+#     dll_name = filename;
+#
+#     for (i=0; filename[i]; i++)
+# 	if (filename[i] == '/' || filename[i] == '\\'  || filename[i] == ':')
+# 	    dll_name = filename + i +1;
+#
+#     pe_header_offset = pe_get32 (dll, 0x3c);
+#     opthdr_ofs = pe_header_offset + 4 + 20;
+#     num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+#     if (num_entries < 1) /* no exports */
+# 	return 1;
+#
+#     export_rva = pe_get32 (dll, opthdr_ofs + 96);
+#     export_size = pe_get32 (dll, opthdr_ofs + 100);
+#     nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+#     secptr = (pe_header_offset + 4 + 20 +
+# 	      pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+#     expptr = 0;
+#     for (i = 0; i < nsections; i++)
+#     {
+# 	char sname[8];
+# 	unsigned long secptr1 = secptr + 40 * i;
+# 	unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+# 	unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+# 	unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+# 	lseek(dll, secptr1, SEEK_SET);
+# 	read(dll, sname, 8);
+# 	if (vaddr <= export_rva && vaddr+vsize > export_rva)
+# 	{
+# 	    expptr = fptr + (export_rva - vaddr);
+# 	    if (export_rva + export_size > vaddr + vsize)
+# 		export_size = vsize - (export_rva - vaddr);
+# 	    break;
+# 	}
+#     }
+#
+#     expdata = (unsigned char*)malloc(export_size);
+#     lseek (dll, expptr, SEEK_SET);
+#     read (dll, expdata, export_size);
+#     erva = expdata - export_rva;
+#
+#     nexp = pe_as32 (expdata+24);
+#     name_rvas = pe_as32 (expdata+32);
+#
+#     printf ("EXPORTS\n");
+#     for (i = 0; i<nexp; i++)
+#     {
+# 	unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+# 	printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+#     }
+#
+#     return 0;
+# }
+# /* impgen.c ends here */
+
+EOF
+    ;;
+  esac
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "${ofile}T" || (rm -f "${ofile}T"; exit 1)
+
+  mv -f "${ofile}T" "$ofile" || \
+    (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T")
+  chmod +x "$ofile"
+fi
+##
+## END FIXME
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Prevent multiple expansion
+
+
+
+echo "$as_me:$LINENO: checking to see if architecture is 64-bit" >&5
+echo $ECHO_N "checking to see if architecture is 64-bit... $ECHO_C" >&6
+arch_64bit=no
+case "$host_cpu" in
+x86_64) arch_64bit=yes ;;
+esac
+
+if test "$arch_64bit" = yes; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS="-m32"
+  fi
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS=
+  fi
+fi
+export COMPAT32BITFLAGS
+
+
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+for ac_header in stdlib.h string.h sys/file.h unistd.h fcntl.h sys/types.h memory.y
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the gdbm lists.  ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+echo "$as_me:$LINENO: checking for main in -ldbm" >&5
+echo $ECHO_N "checking for main in -ldbm... $ECHO_C" >&6
+if test "${ac_cv_lib_dbm_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dbm_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dbm_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dbm_main" >&5
+echo "${ECHO_T}$ac_cv_lib_dbm_main" >&6
+if test $ac_cv_lib_dbm_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDBM 1
+_ACEOF
+
+  LIBS="-ldbm $LIBS"
+
+fi
+
+
+echo "$as_me:$LINENO: checking for main in -lndbm" >&5
+echo $ECHO_N "checking for main in -lndbm... $ECHO_C" >&6
+if test "${ac_cv_lib_ndbm_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lndbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ndbm_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ndbm_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ndbm_main" >&5
+echo "${ECHO_T}$ac_cv_lib_ndbm_main" >&6
+if test $ac_cv_lib_ndbm_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNDBM 1
+_ACEOF
+
+  LIBS="-lndbm $LIBS"
+
+fi
+
+
+
+
+
+
+for ac_func in rename ftruncate flock bcopy fsync
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in getopt
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6
+if test "${ac_cv_type_off_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((off_t *) 0)
+  return 0;
+if (sizeof (off_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_off_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_off_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
+if test $ac_cv_type_off_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for struct stat.st_blksize" >&5
+echo $ECHO_N "checking for struct stat.st_blksize... $ECHO_C" >&6
+if test "${ac_cv_member_struct_stat_st_blksize+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static struct stat ac_aggr;
+if (ac_aggr.st_blksize)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_blksize=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static struct stat ac_aggr;
+if (sizeof ac_aggr.st_blksize)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_blksize=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_stat_st_blksize=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_blksize" >&5
+echo "${ECHO_T}$ac_cv_member_struct_stat_st_blksize" >&6
+if test $ac_cv_member_struct_stat_st_blksize = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+_ACEOF
+
+
+fi
+
+          ac_config_files="$ac_config_files Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by gdbm $as_me 1.8.3, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+gdbm config.status 1.8.3
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "autoconf.h" ) CONFIG_HEADERS="$CONFIG_HEADERS autoconf.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@target@,$target,;t t
+s,@target_cpu@,$target_cpu,;t t
+s,@target_vendor@,$target_vendor,;t t
+s,@target_os@,$target_os,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CPP@,$CPP,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@LN_S@,$LN_S,;t t
+s,@ECHO@,$ECHO,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@LIBTOOL@,$LIBTOOL,;t t
+s,@COMPAT32BITFLAGS@,$COMPAT32BITFLAGS,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/configure.in
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/configure.in	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/configure.in	(revision 20131)
@@ -0,0 +1,50 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT([gdbm], [1.8.3])
+AC_PREREQ(2.54)
+AC_CONFIG_SRCDIR([gdbmdefs.h])
+AC_CONFIG_HEADERS([autoconf.h])
+
+dnl get $target_cpu, $target_vendor, and $target_os
+dnl (as well as host_*)
+AC_CANONICAL_SYSTEM
+
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AM_PROG_LIBTOOL
+dnl AC_PROG_RANLIB
+dnl AC_C_BIGENDIAN([])
+
+AC_MSG_CHECKING(to see if architecture is 64-bit)
+arch_64bit=no
+case "$host_cpu" in
+x86_64) arch_64bit=yes ;;
+esac
+
+if test "$arch_64bit" = yes; then
+  AC_MSG_RESULT(yes)
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS="-m32"
+    LIBTOOLCOMPAT32BITFLAGS="-Wl,-m32"
+  fi
+else
+  AC_MSG_RESULT(no)
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS=
+    LIBTOOLCOMPAT32BITFLAGS=
+  fi
+fi
+export COMPAT32BITFLAGS
+AC_SUBST(COMPAT32BITFLAGS)
+
+
+AC_C_CONST
+AC_CHECK_HEADERS([stdlib.h string.h sys/file.h unistd.h fcntl.h sys/types.h memory.y])
+AC_CHECK_LIB(dbm, main)
+AC_CHECK_LIB(ndbm, main)
+AC_CHECK_FUNCS([rename ftruncate flock bcopy fsync])
+AC_REPLACE_FUNCS(getopt)
+AC_TYPE_OFF_T
+AC_CHECK_MEMBERS([struct stat.st_blksize])
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/conv2gdbm.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/conv2gdbm.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/conv2gdbm.c	(revision 20131)
@@ -0,0 +1,184 @@
+/* conv2gdbm.c - This is a program to convert dbm files to gdbm files. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include <stdio.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include "gdbm.h"
+
+#include "getopt.h"
+
+extern int dbminit ();
+extern datum fetch ();
+extern datum firstkey ();
+extern datum nextkey ();
+
+static void usage();
+
+/* Boolean Constants */
+#define TRUE 1
+#define FALSE 0
+
+int
+main (argc, argv)
+     int argc;
+     char *argv[];
+{
+  GDBM_FILE gfile;	/* The gdbm file. */
+  datum key;		/* Key and data pairs retrieved. */
+  datum data;
+  int   errors;		/* error count. */
+  int   num;		/* insert count. */
+  int   block_size;     /* gdbm block size. */
+  char  quiet;		/* Do work Quietly? */
+  char  option_char;    /* The option character. */
+
+  char *dbm_file, *gdbm_file;   /* pointers to the file names. */
+
+  /* Initialize things. */
+  quiet = FALSE;
+  block_size = 0;
+
+  /* Check for proper arguments. */
+
+  if (argc < 2)
+    usage (argv[0]);
+
+  /* Check for the options.  */
+  while  ( (option_char = getopt (argc, argv, "b:q")) != EOF)
+    {
+      switch (option_char)
+	{
+	case 'b':
+	  block_size = atoi (optarg);
+	  break;
+
+	case 'q':
+	  quiet = TRUE;
+	  break;
+
+	default:
+	  usage (argv[0]);
+	}
+    }
+
+  /* The required dbm file name. */
+  if (argc <= optind)
+    {
+      usage (argv[0]);
+    }
+  else
+    {
+      dbm_file = argv[optind];
+      gdbm_file = argv[optind];
+      optind += 1;
+    }
+
+  /* The optional gdbm file name. */
+  if (argc > optind)
+    {
+      gdbm_file = argv[optind];
+      optind += 1;
+    }
+
+  /* No more arguments are legal. */
+  if (argc > optind)  usage (argv[0]);
+  
+  /* Open the dbm file. */
+  if (dbminit (dbm_file) != 0)
+    {
+      printf ("%s: dbm file not opened\n", argv[0]);
+      exit (2);
+    }
+
+  /* Open the gdbm file.  Since the dbm files have .pag and .dir we
+     will use the file name without any extension.  */
+  gfile = gdbm_open (gdbm_file, block_size, GDBM_WRCREAT, 00664, NULL);
+  if (gfile == NULL)
+    {
+      printf ("%s: gdbm file not opened\n", argv[0]);
+      exit (2);
+    }
+
+
+  /* Do the conversion.  */
+  errors = 0;
+  num = 0;
+
+  if (!quiet)
+    printf ("%s: Converting %s.pag and %s.dir to %s.\n", argv[0], dbm_file,
+	    dbm_file, gdbm_file);
+
+  /* The convert loop - read a key/data pair from the dbm file and insert
+     it into the gdbm file. */
+
+  for (key = firstkey (); key.dptr != NULL; key = nextkey (key))
+    {
+      data = fetch (key);
+      if (gdbm_store (gfile, key, data, GDBM_INSERT) != 0)
+	{
+	  errors++;
+	}
+      else
+	{
+	  num++;
+	  if ( !quiet && ((num % 100) == 0))
+	    {
+	      printf (".");
+	      if ( (num % 7000) == 0)
+		printf ("\n");
+	    }
+	}
+    }
+
+  gdbm_close (gfile);
+
+  if (!quiet)
+    {
+      /* Final reporting. */
+      if (errors)
+	printf ("%s: %d items not inserted into %s.\n", argv[0],
+	        errors, gdbm_file);
+
+      printf  ("%s: %d items inserted into %s.\n", argv[0], num, gdbm_file);
+    }
+  exit(0);
+  /* NOTREACHED */
+}
+
+static void usage (name)
+     char *name;
+{
+  printf ("usage: %s [-q] [-b block_size] dbmfile [gdbmfile]\n", name);
+  exit (2);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbm.h
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbm.h	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbm.h	(revision 20131)
@@ -0,0 +1,52 @@
+/* dbm.h  -  The include file for dbm users.  */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+/* The data and key structure.  This structure is defined for compatibility. */
+typedef struct {
+	char *dptr;
+	int   dsize;
+      } datum;
+
+
+/* These are the routines in dbm. */
+
+extern int	dbminit ();
+
+extern datum	fetch ();
+
+extern int	store ();
+
+extern int	delete ();
+
+extern int	delete ();
+
+extern datum	firstkey ();
+
+extern datum	nextkey ();
+
+extern int	dbmclose ();
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmclose.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmclose.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmclose.c	(revision 20131)
@@ -0,0 +1,43 @@
+/* dbmclose.c - The the dbm file.  This is the NDBM interface. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+
+
+/* Close the DBF file. */
+
+void
+dbm_close (dbf)
+     gdbm_file_info *dbf;
+{
+  gdbm_close (dbf);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmdelete.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmdelete.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmdelete.c	(revision 20131)
@@ -0,0 +1,46 @@
+/* dbmdelete.c - Remove the key and its associated data from the database.
+   This is the NDBM unix interface name.  */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "extern.h"
+
+
+/* Remove the KEYed item and the KEY from the database DBF. */
+
+int
+dbm_delete (dbf,key)
+     gdbm_file_info *dbf;
+     datum key;
+{
+  return gdbm_delete (dbf,key);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmdirfno.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmdirfno.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmdirfno.c	(revision 20131)
@@ -0,0 +1,44 @@
+/* dbmdirfno.c - The .pag file number for NDBM interface. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+
+
+/* Return the file number of the DBF file.  NDBM original wanted the .dir
+   file number.  Since we have only one file number, we return it. */
+
+int
+dbm_dirfno (dbf)
+     gdbm_file_info *dbf;
+{
+  return (dbf->desc);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmfetch.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmfetch.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmfetch.c	(revision 20131)
@@ -0,0 +1,56 @@
+/* dbmfetch.c - Find a key and return the associated data.  */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "extern.h"
+
+
+/* NDBM Look up a given KEY and return the information associated with that
+   KEY. The pointer in the structure that is  returned is a pointer to
+   dynamically allocated memory block.  */
+
+datum
+dbm_fetch (dbf, key)
+     gdbm_file_info *dbf;
+     datum key;
+{
+  datum  ret_val;		/* The return value. */
+
+  /* Free previous dynamic memory, do actual call, and save pointer to new
+     memory. */
+  ret_val = gdbm_fetch (dbf, key);
+  if (_gdbm_fetch_val != NULL) free (_gdbm_fetch_val);
+  _gdbm_fetch_val = ret_val.dptr;
+
+  /* Return the new value. */
+  return ret_val;
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbminit.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbminit.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbminit.c	(revision 20131)
@@ -0,0 +1,126 @@
+/* dbminit.c - Open the file for dbm operations. This looks like the
+   DBM interface. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+#include "extern.h"
+
+/* Initialize dbm system.  FILE is a pointer to the file name.  In
+   standard dbm, the database is found in files called FILE.pag and
+   FILE.dir.  To make gdbm compatable with dbm using the dbminit call,
+   the same file names are used.  Specifically, dbminit will use the file
+   name FILE.pag in its call to gdbm open.  If the file (FILE.pag) has a
+   size of zero bytes, a file initialization procedure is performed,
+   setting up the initial structure in the file.  Any error detected will
+   cause a return value of -1.  No errors cause the return value of 0.
+   NOTE: file.dir will be linked to file.pag. */
+
+int
+dbminit (file)
+     char *file;
+{
+  char* pag_file;	    /* Used to construct "file.pag". */
+  char* dir_file;	    /* Used to construct "file.dir". */
+  struct stat dir_stat;	    /* Stat information for "file.dir". */
+  int ret;
+
+
+  ret = 0;		    /* Default return value. */
+
+  /* Prepare the correct names of "file.pag" and "file.dir". */
+  pag_file = (char *) malloc (strlen (file)+5);
+  dir_file = (char *) malloc (strlen (file)+5);
+  if ((pag_file == NULL) || (dir_file == NULL))
+    {
+      gdbm_errno = GDBM_MALLOC_ERROR;	/* For the hell of it. */
+      return -1;
+    }
+
+  strcpy (pag_file, file);
+  strcat (pag_file, ".pag");
+  strcpy (dir_file, file);
+  strcat (dir_file, ".dir");
+
+  if (_gdbm_file != NULL)
+    gdbm_close (_gdbm_file);
+
+  /* Try to open the file as a writer.  DBM never created a file. */
+  _gdbm_file = gdbm_open (pag_file, 0, GDBM_WRITER, 0, NULL);
+
+  /* If it was not opened, try opening it as a reader. */
+  if (_gdbm_file == NULL)
+    {
+      _gdbm_file = gdbm_open (pag_file, 0, GDBM_READER, 0, NULL);
+  
+      /* Did we successfully open the file? */
+      if (_gdbm_file == NULL)
+	{
+	  gdbm_errno = GDBM_FILE_OPEN_ERROR;
+	  ret = -1;
+	  goto done;
+	}
+    }
+
+  /* If the database is new, link "file.dir" to "file.pag". This is done
+     so the time stamp on both files is the same. */
+  if (stat (dir_file, &dir_stat) == 0)
+    {
+      if (dir_stat.st_size == 0)
+	if (unlink (dir_file) != 0 || link (pag_file, dir_file) != 0)
+	  {
+	    gdbm_errno = GDBM_FILE_OPEN_ERROR;
+	    gdbm_close (_gdbm_file);
+	    ret = -1;
+	    goto done;
+	  }
+    }
+  else
+    {
+      /* Since we can't stat it, we assume it is not there and try
+         to link the dir_file to the pag_file. */
+      if (link (pag_file, dir_file) != 0)
+	{
+	  gdbm_errno = GDBM_FILE_OPEN_ERROR;
+	  gdbm_close (_gdbm_file);
+	  ret = -1;
+	  goto done;
+	}
+    }
+
+  ret = 0;
+
+done:
+  free (dir_file);
+  free (pag_file);
+  return ret;
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmopen.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmopen.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmopen.c	(revision 20131)
@@ -0,0 +1,138 @@
+/* dbmopen.c - Open the file for dbm operations. This looks like the
+   NDBM interface for dbm use. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+#include "extern.h"
+
+/* Initialize ndbm system.  FILE is a pointer to the file name.  In
+   standard dbm, the database is found in files called FILE.pag and
+   FILE.dir.  To make gdbm compatable with dbm using the dbminit call,
+   the same file names are used.  Specifically, dbminit will use the file
+   name FILE.pag in its call to gdbm open.  If the file (FILE.pag) has a
+   size of zero bytes, a file initialization procedure is performed,
+   setting up the initial structure in the file.  Any error detected will
+   cause a return value of -1.  No errors cause the return value of 0.
+   NOTE: file.dir will be ignored and will always have a size of zero.
+   FLAGS and MODE are the same as the open (2) call.  This call will
+   look at the FLAGS and decide what call to make to gdbm_open.  For
+   FLAGS == O_RDONLY, it will be a GDBM_READER, if FLAGS == O_RDWR|O_CREAT,
+   it will be a GDBM_WRCREAT (creater and writer) and if the FLAGS == O_RDWR,
+   it will be a GDBM_WRITER and if FLAGS contain O_TRUNC then it will be
+   a GDBM_NEWDB.  All other values of FLAGS in the flags are
+   ignored. */
+
+gdbm_file_info *
+dbm_open (file, flags, mode)
+     char *file;
+     int flags;
+     int mode;
+{
+  char* pag_file;	    /* Used to construct "file.pag". */
+  char* dir_file;	    /* Used to construct "file.dir". */
+  struct stat dir_stat;	    /* Stat information for "file.dir". */
+  gdbm_file_info *temp_dbf;  /* Temporary file pointer storage. */
+
+
+  /* Prepare the correct names of "file.pag" and "file.dir". */
+  pag_file = (char *) malloc (strlen (file)+5);
+  dir_file = (char *) malloc (strlen (file)+5);
+  if ((pag_file == NULL) || (dir_file == NULL))
+    {
+      gdbm_errno = GDBM_MALLOC_ERROR;	/* For the hell of it. */
+      return NULL;
+    }
+
+  strcpy (pag_file, file);
+  strcat (pag_file, ".pag");
+  strcpy (dir_file, file);
+  strcat (dir_file, ".dir");
+  
+
+  /* Call the actual routine, saving the pointer to the file information. */
+  flags &= O_RDONLY | O_RDWR | O_CREAT | O_TRUNC;
+  if (flags == O_RDONLY)
+    {
+      temp_dbf = gdbm_open (pag_file, 0, GDBM_READER, 0, NULL);
+    }
+  else if (flags == (O_RDWR | O_CREAT))
+    {
+      temp_dbf = gdbm_open (pag_file, 0, GDBM_WRCREAT, mode, NULL);
+    }
+  else if ( (flags & O_TRUNC) == O_TRUNC)
+    {
+      temp_dbf = gdbm_open (pag_file, 0, GDBM_NEWDB, mode, NULL);
+    }
+  else
+    {
+      temp_dbf = gdbm_open (pag_file, 0, GDBM_WRITER, 0, NULL);
+    }
+
+  /* Did we successfully open the file? */
+  if (temp_dbf == NULL)
+    {
+      gdbm_errno = GDBM_FILE_OPEN_ERROR;
+      goto done;
+    }
+
+  /* If the database is new, link "file.dir" to "file.pag". This is done
+     so the time stamp on both files is the same. */
+  if (stat (dir_file, &dir_stat) == 0)
+    {
+      if (dir_stat.st_size == 0)
+	if (unlink (dir_file) != 0 || link (pag_file, dir_file) != 0)
+	  {
+	    gdbm_errno = GDBM_FILE_OPEN_ERROR;
+	    gdbm_close (temp_dbf);
+	    temp_dbf = NULL;
+	    goto done;
+	  }
+    }
+  else
+    {
+      /* Since we can't stat it, we assume it is not there and try
+         to link the dir_file to the pag_file. */
+      if (link (pag_file, dir_file) != 0)
+	{
+	  gdbm_errno = GDBM_FILE_OPEN_ERROR;
+	  gdbm_close (temp_dbf);
+	  temp_dbf = NULL;
+	  goto done;
+	}
+    }
+
+done:
+  free (pag_file);
+  free (dir_file);
+  return temp_dbf;
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmpagfno.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmpagfno.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmpagfno.c	(revision 20131)
@@ -0,0 +1,44 @@
+/* dbmpagfno.c - The .pag file number for NDBM interface. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+
+
+/* Return the file number of the DBF file.  NDBM original wanted the .pag
+   file number.  Since we have only one file number, we return it. */
+
+int
+dbm_pagfno (dbf)
+     gdbm_file_info *dbf;
+{
+  return (dbf->desc);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmrdonly.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmrdonly.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmrdonly.c	(revision 20131)
@@ -0,0 +1,46 @@
+/* dbmrdonly.c - Check to see if a database is read only, NDBM style. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the original author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+    The author of this file is:
+       e-mail:  downsj@downsj.com
+
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+
+
+/* not much of a routine, but should be a function for compatibility. */
+
+int
+dbm_rdonly(dbf)
+    gdbm_file_info *dbf;
+{
+  return (dbf->read_write == GDBM_READER);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmseq.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmseq.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmseq.c	(revision 20131)
@@ -0,0 +1,80 @@
+/* dbmseq.c - Visit all elements in the database.  This is the NDBM
+   interface. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "extern.h"
+
+
+/* NDBM Start the visit of all keys in the database.  This produces
+   something in hash order, not in any sorted order.  DBF is the dbm file
+   information pointer. */
+
+datum
+dbm_firstkey (dbf)
+     gdbm_file_info *dbf;
+{
+  datum ret_val;
+
+  /* Free previous dynamic memory, do actual call, and save pointer to new
+     memory. */
+  ret_val = gdbm_firstkey (dbf);
+  if (_gdbm_memory.dptr != NULL) free (_gdbm_memory.dptr);
+  _gdbm_memory = ret_val;
+
+  /* Return the new value. */
+  return ret_val;
+}
+
+
+/* NDBM Continue visiting all keys.  The next key in the sequence is returned.
+   DBF is the file information pointer. */
+
+datum
+dbm_nextkey (dbf)
+     gdbm_file_info *dbf;
+{
+  datum ret_val;
+
+  /* Make sure we have a valid key. */
+  if (_gdbm_memory.dptr == NULL)
+    return _gdbm_memory;
+
+  /* Call gdbm nextkey with the old value. After that, free the old value. */
+  ret_val = gdbm_nextkey (dbf,_gdbm_memory);
+  if (_gdbm_memory.dptr != NULL) free (_gdbm_memory.dptr);
+  _gdbm_memory = ret_val;
+
+  /* Return the new value. */
+  return ret_val;
+}
+
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmstore.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmstore.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/dbmstore.c	(revision 20131)
@@ -0,0 +1,49 @@
+/* dbmstore.c - Add a new key/data pair to the database. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "extern.h"
+
+
+/* NDBM add a new element to the database.  CONTENT is keyed by KEY.
+   The file on disk is updated to reflect the structure of the new
+   database before returning from this procedure.  */
+
+int
+dbm_store (dbf, key, content, flags)
+     gdbm_file_info *dbf;
+     datum key;
+     datum content;
+     int flags;
+{
+  return gdbm_store (dbf, key, content, flags);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/delete.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/delete.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/delete.c	(revision 20131)
@@ -0,0 +1,45 @@
+/* delete.c - Remove the key and its associated data from the database.
+   This is the original unix interface name.  */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "extern.h"
+
+
+/* Remove the KEYed item and the KEY from the database. */
+
+int
+delete (key)
+     datum key;
+{
+  return gdbm_delete (_gdbm_file, key);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/extern.h
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/extern.h	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/extern.h	(revision 20131)
@@ -0,0 +1,35 @@
+/* extern.h - The collection of external definitions needed. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* The global variables used for the "original" interface. */
+extern gdbm_file_info  *_gdbm_file;
+
+/* Memory for return data for the "original" interface. */
+extern datum _gdbm_memory;
+extern char *_gdbm_fetch_val;
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/falloc.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/falloc.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/falloc.c	(revision 20131)
@@ -0,0 +1,495 @@
+/* falloc.c - The file space management routines for dbm. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993, 1994  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+
+
+/* The forward definitions for this file.  See the functions for
+   the definition of the function. */
+
+static avail_elem get_elem __P((int, avail_elem [], int *));
+static avail_elem get_block __P((int, gdbm_file_info *));
+static void push_avail_block __P((gdbm_file_info *));
+static void pop_avail_block __P((gdbm_file_info *));
+static void adjust_bucket_avail __P((gdbm_file_info *));
+
+/* Allocate space in the file DBF for a block NUM_BYTES in length.  Return
+   the file address of the start of the block.  
+
+   Each hash bucket has a fixed size avail table.  We first check this
+   avail table to satisfy the request for space.  In most cases we can
+   and this causes changes to be only in the current hash bucket.
+   Allocation is done on a first fit basis from the entries.  If a
+   request can not be satisfied from the current hash bucket, then it is
+   satisfied from the file header avail block.  If nothing is there that
+   has enough space, another block at the end of the file is allocated
+   and the unused portion is returned to the avail block.  This routine
+   "guarantees" that an allocation does not cross a block boundary unless
+   the size is larger than a single block.  The avail structure is
+   changed by this routine if a change is needed.  If an error occurs,
+   the value of 0 will be returned.  */
+
+off_t
+_gdbm_alloc (dbf, num_bytes)
+     gdbm_file_info *dbf;
+     int num_bytes;
+{
+  off_t file_adr;		/* The address of the block. */
+  avail_elem av_el;		/* For temporary use. */
+
+  /* The current bucket is the first place to look for space. */
+  av_el = get_elem (num_bytes, dbf->bucket->bucket_avail,
+		    &dbf->bucket->av_count);
+
+  /* If we did not find some space, we have more work to do. */
+  if (av_el.av_size == 0)
+    {
+      /* If the header avail table is less than half full, and there's
+	 something on the stack. */
+      if ((dbf->header->avail.count <= (dbf->header->avail.size >> 1))
+          && (dbf->header->avail.next_block != 0))
+        pop_avail_block (dbf);
+
+      /* check the header avail table next */
+      av_el = get_elem (num_bytes, dbf->header->avail.av_table,
+      			&dbf->header->avail.count);
+      if (av_el.av_size == 0)
+        /* Get another full block from end of file. */
+        av_el = get_block (num_bytes, dbf);
+
+      dbf->header_changed = TRUE;
+    }
+
+  /* We now have the place from which we will allocate the new space. */
+  file_adr = av_el.av_adr;
+
+  /* Put the unused space back in the avail block. */
+  av_el.av_adr += num_bytes;
+  av_el.av_size -= num_bytes;
+  _gdbm_free (dbf, av_el.av_adr, av_el.av_size);
+
+  /* Return the address. */
+  return file_adr;
+  
+}
+
+
+
+/* Free space of size NUM_BYTES in the file DBF at file address FILE_ADR.  Make
+   it avaliable for reuse through _gdbm_alloc.  This routine changes the
+   avail structure. */
+
+void
+_gdbm_free (dbf, file_adr, num_bytes)
+     gdbm_file_info *dbf;
+     off_t file_adr;
+     int num_bytes;
+{
+  avail_elem temp;
+
+  /* Is it too small to worry about? */
+  if (num_bytes <= IGNORE_SIZE)
+    return;
+
+  /* Initialize the avail element. */
+  temp.av_size = num_bytes;
+  temp.av_adr = file_adr;
+
+  /* Is the freed space large or small? */
+  if ((num_bytes >= dbf->header->block_size) || dbf->central_free)
+    {
+      if (dbf->header->avail.count == dbf->header->avail.size)
+	{
+	  push_avail_block (dbf);
+	}
+      _gdbm_put_av_elem (temp, dbf->header->avail.av_table,
+			 &dbf->header->avail.count, dbf->coalesce_blocks);
+      dbf->header_changed = TRUE;
+    }
+  else
+    {
+      /* Try to put into the current bucket. */
+      if (dbf->bucket->av_count < BUCKET_AVAIL)
+	_gdbm_put_av_elem (temp, dbf->bucket->bucket_avail,
+			   &dbf->bucket->av_count, dbf->coalesce_blocks);
+      else
+	{
+	  if (dbf->header->avail.count == dbf->header->avail.size)
+	    {
+	      push_avail_block (dbf);
+	    }
+	  _gdbm_put_av_elem (temp, dbf->header->avail.av_table,
+			     &dbf->header->avail.count, dbf->coalesce_blocks);
+	  dbf->header_changed = TRUE;
+	}
+    }
+
+  if (dbf->header_changed)
+    adjust_bucket_avail (dbf);
+
+  /* All work is done. */
+  return;
+}
+
+
+
+/* The following are all utility routines needed by the previous two. */
+
+
+/* Gets the avail block at the top of the stack and loads it into the
+   active avail block.  It does a "free" for itself!  This can (and is)
+   now called even when the avail block is not empty, so we must be
+   smart about things. */
+
+static void
+pop_avail_block (dbf)
+     gdbm_file_info *dbf;
+{
+  int  num_bytes;		/* For use with the read system call. */
+  off_t file_pos;		/* For use with the lseek system call. */
+  avail_elem new_el;
+  avail_block *new_blk;
+  int index;
+
+  if (dbf->header->avail.count == dbf->header->avail.size)
+    {
+      /* We're kind of stuck here, so we re-split the header in order to
+         avoid crashing.  Sigh. */
+      push_avail_block(dbf);
+    }
+
+  /* Set up variables. */
+  new_el.av_adr = dbf->header->avail.next_block;
+  new_el.av_size = ( ( (dbf->header->avail.size * sizeof (avail_elem)) >> 1)
+			+ sizeof (avail_block));
+
+  /* Allocate space for the block. */
+  new_blk = (avail_block *) malloc (new_el.av_size);
+  if (new_blk == NULL) _gdbm_fatal(dbf, "malloc failed");
+
+  /* Read the block. */
+  file_pos = lseek (dbf->desc, new_el.av_adr, L_SET);
+  if (file_pos != new_el.av_adr)  _gdbm_fatal (dbf, "lseek error");
+  num_bytes = read (dbf->desc, new_blk, new_el.av_size);
+  if (num_bytes != new_el.av_size) _gdbm_fatal (dbf, "read error");
+
+  /* Add the elements from the new block to the header. */
+  index = 0;
+  while (index < new_blk->count)
+    {
+      while(index < new_blk->count
+            && dbf->header->avail.count < dbf->header->avail.size)
+	{
+	   /* With luck, this will merge a lot of blocks! */
+	   _gdbm_put_av_elem(new_blk->av_table[index],
+			     dbf->header->avail.av_table,
+			     &dbf->header->avail.count, TRUE);
+	   index++;
+	}
+      if (dbf->header->avail.count == dbf->header->avail.size)
+        {
+          /* We're kind of stuck here, so we re-split the header in order to
+             avoid crashing.  Sigh. */
+          push_avail_block(dbf);
+	}
+    }
+
+  /* Fix next_block, as well. */
+  dbf->header->avail.next_block = new_blk->next_block;
+
+  /* We changed the header. */
+  dbf->header_changed = TRUE;
+
+  /* Free the previous avail block.   It is possible that the header table
+     is now FULL, which will cause us to overflow it! */
+  if (dbf->header->avail.count == dbf->header->avail.size)
+    {
+      /* We're kind of stuck here, so we re-split the header in order to
+         avoid crashing.  Sigh. */
+      push_avail_block(dbf);
+    }
+
+  _gdbm_put_av_elem (new_el, dbf->header->avail.av_table,
+		     &dbf->header->avail.count, TRUE);
+  free (new_blk);
+}
+
+
+/* Splits the header avail block and pushes half onto the avail stack. */
+
+static void
+push_avail_block (dbf)
+     gdbm_file_info *dbf;
+{
+  int  num_bytes;
+  int  av_size;
+  off_t av_adr;
+  int  index;
+  off_t file_pos;
+  avail_block *temp;
+  avail_elem  new_loc;
+ 
+
+  /* Caclulate the size of the split block. */
+  av_size = ( (dbf->header->avail.size * sizeof (avail_elem)) >> 1)
+            + sizeof (avail_block);
+
+  /* Get address in file for new av_size bytes. */
+  new_loc = get_elem (av_size, dbf->header->avail.av_table,
+		      &dbf->header->avail.count);
+  if (new_loc.av_size == 0)
+    new_loc = get_block (av_size, dbf);
+  av_adr = new_loc.av_adr;
+
+
+  /* Split the header block. */
+  temp = (avail_block *) malloc (av_size);
+  if (temp == NULL) _gdbm_fatal (dbf, "malloc error");
+  /* Set the size to be correct AFTER the pop_avail_block. */
+  temp->size = dbf->header->avail.size;
+  temp->count = 0;
+  temp->next_block = dbf->header->avail.next_block;
+  dbf->header->avail.next_block = av_adr;
+  for (index = 1; index < dbf->header->avail.count; index++)
+    if ( (index & 0x1) == 1)	/* Index is odd. */
+      temp->av_table[temp->count++] = dbf->header->avail.av_table[index];
+    else
+      dbf->header->avail.av_table[index>>1]
+	= dbf->header->avail.av_table[index];
+
+  /* Update the header avail count to previous size divided by 2. */
+  dbf->header->avail.count >>= 1;
+
+  /* Free the unneeded space. */
+  new_loc.av_adr += av_size;
+  new_loc.av_size -= av_size;
+  _gdbm_free (dbf, new_loc.av_adr, new_loc.av_size);
+
+  /* Update the disk. */
+  file_pos = lseek (dbf->desc, av_adr, L_SET);
+  if (file_pos != av_adr) _gdbm_fatal (dbf, "lseek error");
+  num_bytes = write (dbf->desc, temp, av_size);
+  if (num_bytes != av_size) _gdbm_fatal (dbf, "write error");
+  free (temp);
+}
+
+
+
+/* Get_elem returns an element in the AV_TABLE block which is
+   larger than SIZE.  AV_COUNT is the number of elements in the
+   AV_TABLE.  If an item is found, it extracts it from the AV_TABLE
+   and moves the other elements up to fill the space. If no block is 
+   found larger than SIZE, get_elem returns a size of zero.  This
+   routine does no I/O. */
+
+static avail_elem
+get_elem (size, av_table, av_count)
+     int size;
+     avail_elem av_table[];
+     int *av_count;
+{
+  int index;			/* For searching through the avail block. */
+  avail_elem val;		/* The default return value. */
+
+  /* Initialize default return value. */
+  val.av_adr = 0;
+  val.av_size = 0;
+
+  /* Search for element.  List is sorted by size. */
+  index = 0;
+  while (index < *av_count && av_table[index].av_size < size)
+    {
+      index++;
+    }
+
+  /* Did we find one of the right size? */
+  if (index >= *av_count)
+    return val;
+
+  /* Ok, save that element and move all others up one. */
+  val = av_table[index];
+  *av_count -= 1;
+  while (index < *av_count)
+    {
+      av_table[index] = av_table[index+1];
+      index++;
+    }
+
+  return val;
+}
+
+
+/* This routine inserts a single NEW_EL into the AV_TABLE block.
+   This routine does no I/O. */
+
+int
+_gdbm_put_av_elem (new_el, av_table, av_count, can_merge)
+     avail_elem new_el;
+     avail_elem av_table[];
+     int *av_count;
+     int can_merge;		/* We should allow blocks to merge. */
+{
+  int index;			/* For searching through the avail block. */
+  int index1;
+
+  /* Is it too small to deal with? */
+  if (new_el.av_size <= IGNORE_SIZE)
+    return FALSE;
+
+  if (can_merge == TRUE)
+    {
+      /* Search for blocks to coalesce with this one. */
+      index = 0;
+
+      while (index < *av_count)
+	{
+	  /* Can we merge with the previous block? */
+	  if ((av_table[index].av_adr
+	       + av_table[index].av_size) == new_el.av_adr)
+	    {
+	      /* Simply expand the endtry. */
+	      av_table[index].av_size += new_el.av_size;
+	    }
+	    /* Can we merge with the next block? */
+	    else if ((new_el.av_adr
+	      	      + new_el.av_size) == av_table[index].av_adr)
+	      {
+	        /* Update this entry. */
+	        av_table[index].av_adr = new_el.av_adr;
+		av_table[index].av_size += new_el.av_size;
+	      }
+	    /* Not contiguous */
+	    else
+	      {
+		index++;
+		continue;
+	      }
+	    
+	    /* If we got here, we're done. */
+	    return TRUE;
+	}
+    }
+
+  /* Search for place to put element.  List is sorted by size. */
+  index = 0;
+  while (index < *av_count && av_table[index].av_size < new_el.av_size)
+    {
+      index++;
+    }
+
+  /* Move all others up one. */
+  index1 = *av_count-1;
+  while (index1 >= index)
+    {
+      av_table[index1+1] = av_table[index1];
+      index1--;
+    }
+
+  /* Add the new element. */
+  av_table[index] = new_el;
+
+  /* Increment the number of elements. */
+  *av_count += 1;
+
+  return TRUE;
+}
+
+
+
+
+
+/* Get_block "allocates" new file space and the end of the file.  This is
+   done in integral block sizes.  (This helps insure that data smaller than
+   one block size is in a single block.)  Enough blocks are allocated to
+   make sure the number of bytes allocated in the blocks is larger than SIZE.
+   DBF contains the file header that needs updating.  This routine does
+   no I/O.  */
+
+static avail_elem
+get_block (size, dbf)
+     int size;
+     gdbm_file_info *dbf;
+{
+  avail_elem val;
+
+  /* Need at least one block. */
+  val.av_adr  = dbf->header->next_block;
+  val.av_size = dbf->header->block_size;
+
+  /* Get enough blocks to fit the need. */
+  while (val.av_size < size)
+    val.av_size += dbf->header->block_size;
+
+  /* Update the header and return. */
+  dbf->header->next_block += val.av_size;
+
+  /* We changed the header. */
+  dbf->header_changed = TRUE;
+
+  return val;
+  
+}
+
+
+/*  When the header already needs writing, we can make sure the current
+    bucket has its avail block as close to 1/3 full as possible. */
+static void
+adjust_bucket_avail (dbf)
+     gdbm_file_info *dbf;
+{
+  int third = BUCKET_AVAIL / 3;
+  avail_elem av_el;
+
+  /* Can we add more entries to the bucket? */
+  if (dbf->bucket->av_count < third)
+    {
+      if (dbf->header->avail.count > 0)
+	{
+	  dbf->header->avail.count -= 1;
+	  av_el = dbf->header->avail.av_table[dbf->header->avail.count];
+	  _gdbm_put_av_elem (av_el, dbf->bucket->bucket_avail,
+			     &dbf->bucket->av_count, dbf->coalesce_blocks);
+	  dbf->bucket_changed = TRUE;
+	}
+      return;
+    }
+
+  /* Is there too much in the bucket? */
+  while (dbf->bucket->av_count > BUCKET_AVAIL-third
+	 && dbf->header->avail.count < dbf->header->avail.size)
+    {
+      av_el = get_elem (0, dbf->bucket->bucket_avail, &dbf->bucket->av_count);
+      _gdbm_put_av_elem (av_el, dbf->header->avail.av_table,
+			 &dbf->header->avail.count, dbf->coalesce_blocks);
+      dbf->bucket_changed = TRUE;
+    }
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/fetch.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/fetch.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/fetch.c	(revision 20131)
@@ -0,0 +1,56 @@
+/* fetch.c - Find a key and return the associated data.  */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "extern.h"
+
+
+/* Look up a given KEY and return the information associated with that KEY.
+   The pointer in the structure that is  returned is a pointer to dynamically
+   allocated memory block.  This DBM interface uses the NDBM interface. */
+
+datum
+fetch (key)
+     datum key;
+{
+  datum  ret_val;		/* The return value. */
+
+  /* Free previous dynamic memory, do actual call, and save pointer to new
+     memory. */
+  ret_val = gdbm_fetch (_gdbm_file, key);
+  if (_gdbm_fetch_val != NULL) free (_gdbm_fetch_val);
+  _gdbm_fetch_val = ret_val.dptr;
+
+  /* Return the new value. */
+  return ret_val;
+
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/findkey.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/findkey.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/findkey.c	(revision 20131)
@@ -0,0 +1,160 @@
+/* findkey.c - The routine that finds a key entry in the file. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+
+
+/* Read the data found in bucket entry ELEM_LOC in file DBF and
+   return a pointer to it.  Also, cache the read value. */
+
+char *
+_gdbm_read_entry (dbf, elem_loc)
+     gdbm_file_info *dbf;
+     int elem_loc;
+{
+  int num_bytes;		/* For seeking and reading. */
+  int key_size;
+  int data_size;
+  off_t file_pos;
+  data_cache_elem *data_ca;
+
+  /* Is it already in the cache? */
+  if (dbf->cache_entry->ca_data.elem_loc == elem_loc)
+    return dbf->cache_entry->ca_data.dptr;
+
+  /* Set sizes and pointers. */
+  key_size = dbf->bucket->h_table[elem_loc].key_size;
+  data_size = dbf->bucket->h_table[elem_loc].data_size;
+  data_ca = &dbf->cache_entry->ca_data;
+  
+  /* Set up the cache. */
+  if (data_ca->dptr != NULL) free (data_ca->dptr);
+  data_ca->key_size = key_size;
+  data_ca->data_size = data_size;
+  data_ca->elem_loc = elem_loc;
+  data_ca->hash_val = dbf->bucket->h_table[elem_loc].hash_value;
+  if (key_size+data_size == 0)
+    data_ca->dptr = (char *) malloc (1);
+  else
+    data_ca->dptr = (char *) malloc (key_size+data_size);
+  if (data_ca->dptr == NULL) _gdbm_fatal (dbf, "malloc error");
+
+
+  /* Read into the cache. */
+  file_pos = lseek (dbf->desc,
+		    dbf->bucket->h_table[elem_loc].data_pointer, L_SET);
+  if (file_pos != dbf->bucket->h_table[elem_loc].data_pointer)
+    _gdbm_fatal (dbf, "lseek error");
+  num_bytes = read (dbf->desc, data_ca->dptr, key_size+data_size);
+  if (num_bytes != key_size+data_size) _gdbm_fatal (dbf, "read error");
+  
+  return data_ca->dptr;
+}
+
+
+
+/* Find the KEY in the file and get ready to read the associated data.  The
+   return value is the location in the current hash bucket of the KEY's
+   entry.  If it is found, a pointer to the data and the key are returned
+   in DPTR.  If it is not found, the value -1 is returned.  Since find
+   key computes the hash value of key, that value */
+int
+_gdbm_findkey (dbf, key, dptr, new_hash_val)
+     gdbm_file_info *dbf;
+     datum key;
+     char **dptr;
+     int *new_hash_val;		/* The new hash value. */
+{
+  int    bucket_hash_val;	/* The hash value from the bucket. */
+  char  *file_key;		/* The complete key as stored in the file. */
+  int    elem_loc;		/* The location in the bucket. */
+  int    home_loc;		/* The home location in the bucket. */
+  int    key_size;		/* Size of the key on the file.  */
+
+  /* Compute hash value and load proper bucket.  */
+  *new_hash_val = _gdbm_hash (key);
+  _gdbm_get_bucket (dbf, *new_hash_val>> (31-dbf->header->dir_bits));
+
+  /* Is the element the last one found for this bucket? */
+  if (dbf->cache_entry->ca_data.elem_loc != -1 
+      && *new_hash_val == dbf->cache_entry->ca_data.hash_val
+      && dbf->cache_entry->ca_data.key_size == key.dsize
+      && dbf->cache_entry->ca_data.dptr != NULL
+      && bcmp (dbf->cache_entry->ca_data.dptr, key.dptr, key.dsize) == 0)
+    {
+      /* This is it. Return the cache pointer. */
+      *dptr = dbf->cache_entry->ca_data.dptr+key.dsize;
+      return dbf->cache_entry->ca_data.elem_loc;
+    }
+      
+  /* It is not the cached value, search for element in the bucket. */
+  elem_loc = *new_hash_val % dbf->header->bucket_elems;
+  home_loc = elem_loc;
+  bucket_hash_val = dbf->bucket->h_table[elem_loc].hash_value;
+  while (bucket_hash_val != -1)
+    {
+      key_size = dbf->bucket->h_table[elem_loc].key_size;
+      if (bucket_hash_val != *new_hash_val
+	 || key_size != key.dsize
+	 || bcmp (dbf->bucket->h_table[elem_loc].key_start, key.dptr,
+			(SMALL < key_size ? SMALL : key_size)) != 0) 
+	{
+	  /* Current elem_loc is not the item, go to next item. */
+	  elem_loc = (elem_loc + 1) % dbf->header->bucket_elems;
+	  if (elem_loc == home_loc) return -1;
+	  bucket_hash_val = dbf->bucket->h_table[elem_loc].hash_value;
+	}
+      else
+	{
+	  /* This may be the one we want.
+	     The only way to tell is to read it. */
+	  file_key = _gdbm_read_entry (dbf, elem_loc);
+	  if (bcmp (file_key, key.dptr, key_size) == 0)
+	    {
+	      /* This is the item. */
+	      *dptr = file_key+key.dsize;
+	      return elem_loc;
+	    }
+	  else
+	    {
+	      /* Not the item, try the next one.  Return if not found. */
+	      elem_loc = (elem_loc + 1) % dbf->header->bucket_elems;
+	      if (elem_loc == home_loc) return -1;
+	      bucket_hash_val = dbf->bucket->h_table[elem_loc].hash_value;
+	    }
+	}
+    }
+
+  /* If we get here, we never found the key. */
+  return -1;
+
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.3
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.3	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.3	(revision 20131)
@@ -0,0 +1,584 @@
+.ds ve 1.8.3
+.TH GDBM 3 10/15/2002
+.SH NAME
+GDBM - The GNU database manager.  Includes \fBdbm\fR and \fBndbm\fR
+compatability. (Version \*(ve.)
+.SH SYNOPSIS
+.B #include <gdbm.h>
+.PP
+.SM
+.B extern gdbm_error
+.br
+.B gdbm_errno
+.PP
+.B extern char
+.br
+.B *gdbm_version
+.PP
+.B GDBM_FILE
+.br
+.B gdbm_open (name, block_size, read_write, mode, fatal_func)
+.br
+.B char * name;
+.br
+.B int block_size, read_write, mode;
+.br
+.B void (*fatal_func) ();
+.PP
+.B void
+.br
+.B gdbm_close (dbf)
+.br
+.B GDBM_FILE dbf;
+.PP
+.B int
+.br
+.B gdbm_store (dbf, key, content, flag)
+.br
+.B GDBM_FILE dbf;
+.br
+.B datum key, content;
+.br
+.B int flag;
+.PP
+.B datum
+.br
+.B gdbm_fetch (dbf, key)
+.br
+.B GDBM_FILE dbf;
+.br
+.B datum key;
+.PP
+.B int
+.br
+.B gdbm_delete (dbf, key)
+.br
+.B GDBM_FILE dbf;
+.br
+.B datum key;
+.PP
+.B datum
+.br
+.B gdbm_firstkey (dbf)
+.br
+.B GDBM_FILE dbf;
+.PP
+.B datum
+.br
+.B gdbm_nextkey (dbf, key)
+.br
+.B GDBM_FILE dbf;
+.br
+.B datum key;
+.PP
+.B int
+.br
+.B gdbm_reorganize (dbf)
+.br
+.B GDBM_FILE dbf;
+.PP
+.B void
+.br
+.B gdbm_sync (dbf)
+.br
+.B GDBM_FILE dbf;
+.PP
+.B int
+.br
+.B gdbm_exists (dbf, key)
+.br
+.B GDBM_FILE dbf;
+.br
+.B datum key;
+.PP
+.B char *
+.br
+.B gdbm_strerror (errno)
+.br
+.B gdbm_error errno;
+.PP
+.B int
+.br
+.B gdbm_setopt (dbf, option, value, size)
+.br
+.B GDBM_FILE dbf;
+.br
+.B int option;
+.br
+.B int *value;
+.br
+.B int size;
+.PP
+.B int
+.br
+.B gdbm_fdesc (dbf)
+.br
+.B GDBM_FILE dbf;
+.PP
+.PP
+.B DBM Compatability routines:
+.PP
+.B #include <dbm.h>
+.PP
+.SM
+.B int
+.br
+.B dbminit (name)
+.br
+.B char *name;
+.PP
+.B int
+.br
+.B store (key, content)
+.br
+.B datum key, content;
+.PP
+.B datum
+.br
+.B fetch (key)
+.br
+.B datum key;
+.PP
+.B int
+.br
+.B delete (key)
+.br
+.B datum key;
+.PP
+.B datum
+.br
+.B firstkey ()
+.PP
+.B datum
+.br
+.B nextkey (key)
+.br
+.B datum key;
+.PP
+.B int
+.br
+.B dbmclose ()
+.PP
+.PP
+.B NDBM Compatability routines:
+.PP
+.B #include <ndbm.h>
+.PP
+.SM
+.B DBM
+.br
+.B *dbm_open (name, flags, mode)
+.br
+.B char *name;
+.br
+.B int flags, mode;
+.PP
+.B void
+.br
+.B dbm_close (file)
+.br
+.B DBM *file;
+.PP
+.B datum
+.br
+.B dbm_fetch (file, key)
+.br
+.B DBM *file;
+.br
+.B datum key;
+.PP
+.B int
+.br
+.B dbm_store (file, key, content, flags)
+.br
+.B DBM *file;
+.br
+.B datum key, content;
+.br
+.B int flags;
+.PP
+.B int
+.br
+.B dbm_delete (file, key)
+.br
+.B DBM *file;
+.br
+.B datum key;
+.PP
+.B datum
+.br
+.B dbm_firstkey (file)
+.br
+.B DBM *file;
+.PP
+.B datum
+.br
+.B dbm_nextkey (file)
+.br
+.B DBM *file;
+.PP
+.B int
+.br
+.B dbm_error (file)
+.br
+.B DBM *file;
+.PP
+.B int
+.br
+.B dbm_clearerr (file)
+.br
+.B DBM *file;
+.PP
+.B int
+.br
+.B dbm_pagfno (file)
+.br
+.B DBM *file;
+.PP
+.B int
+.br
+.B dbm_dirfno (file)
+.br
+.B DBM *file;
+.PP
+.B int
+.br
+.B dbm_rdonly (file)
+.br
+.B DBM *file;
+
+
+.SH DESCRIPTION
+GNU dbm is a library of routines that manages data files that contain
+key/data pairs.  The access provided is that of storing, 
+retrieval, and deletion by key and a non-sorted traversal of all
+keys.  A process is allowed to use multiple data files at the
+same time.
+
+A process that opens a gdbm file is designated as a "reader" or a
+"writer".  Only one writer may open a gdbm file and many readers may
+open the file.  Readers and writers can not open the gdbm file at the
+same time. The procedure for opening a gdbm file is:
+
+  GDBM_FILE dbf;
+
+  dbf = gdbm_open ( name, block_size, read_write, mode, fatal_func )
+
+\fIName\fR is the name of the file (the complete name,
+gdbm does not append any characters to this name).  \fIBlock_size\fR is
+the size of a single transfer from disk to memory. This parameter is
+ignored unless the file is a new file.  The minimum size is 512.  If
+it is less than 512, dbm will use the stat block size for the file system.
+\fIRead_write\fR can have one of the following values:
+.br
+.B GDBM_READER
+reader
+.br
+.B GDBM_WRITER
+writer
+.br
+.B GDBM_WRCREAT
+writer - if database does not exist create new one
+.br
+.B GDBM_NEWDB
+writer - create new database regardless if one exists
+.br
+For the last three (writers of the database) the following may be added
+added to \fIread_write\fR by bitwise or:
+.B GDBM_SYNC,
+which causes all database operations to be synchronized to the disk, and
+.B GDBM_NOLOCK,
+which prevents the library from performing any locking on the database file.
+The option
+.B GDBM_FAST
+is now obsolete, since gdbm defaults to no-sync mode.
+.br
+\fIMode\fR is the file mode (see \fBchmod(2)\fR and \fBopen(2)\fR) if the
+file is created. \fI(*Fatal_func) ()\fR is a function for dbm to call
+if it detects a fatal error. The only parameter of this function is a string.
+If the value of 0 is provided, gdbm will use a default function.
+
+The return value \fIdbf\fR is the pointer needed by all other routines to
+access that gdbm file.  If the return is the NULL pointer, \fBgdbm_open\fR
+was not successful.  The errors can be found in \fIgdbm_errno\fR for gdbm
+errors and in \fIerrno\fR for system errors.  (For error codes, see
+gdbmerrno.h.)
+
+In all of the following calls, the parameter \fIdbf\fR refers to the pointer
+returned from \fBgdbm_open\fR.
+
+It is important that every file opened is also closed.  This is needed to
+update the reader/writer count on the file.  This is done by:
+
+  gdbm_close (dbf);
+
+
+The database is used by 3 primary routines.  The first stores data in the
+database.
+
+  ret = gdbm_store ( dbf, key, content, flag )
+
+\fIDbf\fR is the pointer returned by \fBgdbm_open\fR.  \fIKey\fR is the
+key data.  \fIContent\fR is the data to be associated with the \fIkey\fR.
+\fIFlag\fR can have one of the following values:
+.br
+.B GDBM_INSERT
+insert only, generate an error if key exists
+.br
+.B GDBM_REPLACE
+replace contents if key exists.
+
+If a reader calls \fBgdbm_store\fR, the return value will be  -1.
+If called with GDBM_INSERT and \fIkey\fR is in the database, the return
+value will be 1.  Otherwise, the return value is 0.
+
+\fINOTICE: If you store data for a key that is already in the data base,
+gdbm replaces the old data with the new data if called with GDBM_REPLACE.
+You do not get two data items for the same key and you do not get an
+error from gdbm_store.
+
+NOTICE: The size in gdbm is not restricted like dbm or ndbm.  Your data
+can be as large as you want.\fR
+
+
+To search for some data:
+
+  content = gdbm_fetch ( dbf, key )
+
+\fIDbf\fR is the pointer returned by \fBgdbm_open\fR.  \fIKey\fR is
+the key data.
+
+
+If the \fIdptr\fR element of the return value is NULL, no data was
+found.  Otherwise the return value is a pointer to the found data.
+The storage space for the \fIdptr\fR element is allocated using
+\fBmalloc(3C)\fR.  \fBGdbm\fI does not automatically free this data.
+It is the programmer's responsibility to free this storage when it is
+no longer needed.\fR
+
+
+To search for some data, without retrieving it:
+
+  ret = gdbm_exists ( dbf, key )
+
+\fIDbf\fR is the pointer returned by \fBgdbm_open\fR.  \fIKey\fR is
+the key data to search for.
+
+If the \fIkey\fR is found within the database, the return value \fIret\fR
+will be true.  If nothing appropiate is found, \fIret\fR will be false.
+This routine is useful for checking for the existance of a record,
+without performing the memory allocation done by \fBgdbm_fetch\fR.
+
+
+To remove some data from the database:
+
+  ret = gdbm_delete ( dbf, key )
+
+\fIDbf\fR is the pointer returned by \fBgdbm_open\fR.  \fIKey\fR is the
+key data.
+
+The return value is -1 if the item is not present or the requester is a reader.
+The return value is 0 if there was a successful delete.
+
+
+The next two routines allow for accessing all items in the database.  This 
+access is not key sequential, but it is guaranteed to visit every key in
+the database once.  (The order has to do with the hash values.)
+
+  key = gdbm_firstkey ( dbf )
+
+  nextkey = gdbm_nextkey ( dbf, key )
+
+\fIDbf\fR is the pointer returned by \fBgdbm_open\fR. \fIKey\fR is the
+key data.
+
+The return values are both of type \fBdatum\fR.  If the \fIdptr\fR
+element of the return value is NULL, there is no first key or next key.
+Again notice that \fIdptr\fR points to data allocated by \fBmalloc(3C)\fR
+and \fBgdbm\fR will not free it for you. 
+
+These functions were intended to visit the database in read-only algorithms,
+for instance, to validate the database or similar operations.
+
+File `visiting' is based on a `hash table'.  \fIgdbm_delete\fR re-arranges the
+hash table to make sure that any collisions in the table do not leave some item
+`un-findable'.  The original key order is NOT guaranteed to remain unchanged in
+ALL instances.  It is possible that some key will not be visited if a loop like
+the following is executed:
+
+   key = gdbm_firstkey ( dbf );
+   while ( key.dptr ) {
+      nextkey = gdbm_nextkey ( dbf, key );
+      if ( some condition ) {
+         gdbm_delete ( dbf, key );
+         free ( key.dptr );
+      }
+      key = nextkey;
+   }
+
+
+The following routine should be used very infrequently.
+  
+  ret = gdbm_reorganize ( dbf )
+
+If you have had a lot of deletions and would like to shrink the space
+used by the \fBgdbm\fR file, this routine will reorganize the database.
+\fBGdbm\fR will not shorten the length of a \fBgdbm\fR file except by
+using this reorganization.  (Deleted file space will be reused.)
+
+
+Unless your database was opened with the GDBM_SYNC flag, gdbm does not
+wait for writes to be flushed to the disk before continuing.
+The following routine can be used to guarantee that the database is
+physically written to the disk file.
+
+  gdbm_sync ( dbf )
+
+It will not return until the disk file state is syncronized with the
+in-memory state of the database.
+
+
+To convert a \fBgdbm\fR error code into English text, use this routine:
+
+  ret = gdbm_strerror ( errno )
+
+Where \fIerrno\fR is of type \fIgdbm_error\fR, usually the global
+variable \fIgdbm_errno\fR.  The appropiate phrase is returned.
+
+
+\fBGdbm\fR now supports the ability to set certain options on an
+already open database.
+
+  ret = gdbm_setopt ( dbf, option, value, size )
+
+Where \fIdbf\fR is the return value from a previous call to \fBgdbm_open\fR,
+and \fIoption\fR specifies which option to set.  The valid options are
+currently:
+
+  \fBGDBM_CACHESIZE\fR - Set the size of the internal bucket
+  cache. This option may only be set once on each \fIGDBM_FILE\fR
+  descriptor, and is set automatically to 100 upon the first
+  access to the database.
+
+  \fBGDBM_FASTMODE\fR - Set \fBfast mode\fR to either on or off.  This
+  allows \fBfast mode\fR to be toggled on an already open and
+  active database. \fIvalue\fR (see below) should be set to either
+  TRUE or FALSE.  \fIThis option is now obsolete.\fR
+
+  \fBGDBM_SYNCMODE\fR - Turn on or off file system synchronization operations.
+  This setting defaults to off; \fIvalue\fR (see below) should be set to either
+  TRUE or FALSE.
+
+  \fBGDBM_CENTFREE\fR - Set \fBcentral free block pool\fR to either on or off.
+  The default is off, which is how previous versions of \fBGdbm\fR
+  handled free blocks. If set, this option causes all subsequent free
+  blocks to be placed in the \fBglobal\fR pool, allowing (in thoery)
+  more file space to be reused more quickly. \fIvalue\fR (see below) should
+  be set to either TRUE or FALSE.
+  \fINOTICE: This feature is still under study.\fR
+
+  \fBGDBM_COALESCEBLKS\fR - Set \fBfree block merging\fR to either on or off.
+  The default is off, which is how previous versions of \fBGdbm\fR
+  handled free blocks. If set, this option causes adjacent free blocks
+  to be merged. This can become a CPU expensive process with time, though,
+  especially if used in conjunction with \fBGDBM_CENTFREE\fR. \fIvalue\fR
+  (see below) should be set to either TRUE or FALSE.
+  \fINOTICE: This feature is still under study.\fR
+
+\fIvalue\fR is the value to set \fIoption\fR to, specified as an integer
+pointer.  \fIsize\fR is the size of the data pointed to by \fIvalue\fR.
+The return value will be -1 upon failure, or 0 upon success.  The global
+variable \fIgdbm_errno\fR will be set upon failure.
+
+For instance, to set a database to use a cache of 10, after opening it
+with \fBgdbm_open\fR, but prior to accessing it in any way, the following
+code could be used:
+
+  int value = 10;
+  
+  ret = gdbm_setopt( dbf, GDBM_CACHESIZE, &value, sizeof(int));
+
+
+If the database was opened with the \fBGDBM_NOLOCK\fR flag, the user may
+wish to perform their own file locking on the database file in order to
+prevent multiple writers operating on the same file simultaneously.
+
+In order to support this, the \fIgdbm_fdesc\fR routine is provided.
+
+  ret = gdbm_fdesc ( dbf )
+
+Where \fIdbf\fR is the return value from a previous call to \fBgdbm_open\fR.
+The return value will be the file descriptor of the database.
+
+The following two external variables may be useful:
+
+\fIgdbm_errno\fR is the variable that contains more information about
+gdbm errors.  (gdbm.h has the definitions of the error values and
+defines gdbm_errno as an external variable.)
+.br
+\fIgdbm_version\fR is the string containing the version information.
+
+
+There are a few more things of interest.  First, \fBgdbm\fR files are
+not "sparse".  You can copy them with the UNIX \fBcp(1)\fR command and
+they will not expand in the copying process.  Also, there is a
+compatibility mode for use with programs that already use UNIX
+\fBdbm\fR.  In this compatibility mode, no \fRgdbm\fR file pointer is
+required by the programmer, and only one file may be opened at a time.
+All users in compatibility mode are assumed to be writers.  If the
+\fBgdbm\fR file is a read only, it will fail as a writer, but will
+also try to open it as a reader.  All returned pointers in datum
+structures point to data that \fBgdbm\fR WILL free.  They should be
+treated as static pointers (as standard UNIX \fBdbm\fR does).
+
+
+.SH LINKING
+This library is accessed by specifying \fI-lgdbm\fR as the last
+parameter to the compile line, e.g.:
+.sp
+	gcc -o prog prog.c -lgdbm
+
+If you wish to use the \fBdbm\fR or \fBndbm\fR compatibility routines,
+you must link in the \fIgdbm_compat\fR library as well.  For example:
+.sp
+	gcc -o prog proc.c -lgdbm -lgdbm_compat
+
+.SH BUGS
+
+.SH "SEE ALSO"
+dbm, ndbm
+
+.SH AUTHOR
+by Philip A. Nelson and Jason Downs.
+Copyright (C) 1990 - 1999 Free Software Foundation, Inc.
+
+GDBM is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GDBM is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GDBM; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+You may contact the original author by:
+.br
+   e-mail:  phil@cs.wwu.edu
+.br
+  us-mail:  Philip A. Nelson
+.br
+Computer Science Department
+.br
+Western Washington University
+.br
+Bellingham, WA 98226
+
+You may contact the current maintainer by:
+.br
+   e-mail:  downsj@downsj.com
+
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.info
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.info	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.info	(revision 20131)
@@ -0,0 +1,756 @@
+This is gdbm.info, produced by makeinfo version 4.2 from
+../gdbm.texinfo.
+
+INFO-DIR-SECTION Programming & development tools
+START-INFO-DIR-ENTRY
+* GDBM: (gdbm).			The GNU database manager.
+END-INFO-DIR-ENTRY
+
+   This file documents the GNU dbm utility.
+
+   Copyright (C) 1989-1999 Free Software Foundation, Inc.
+
+   Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+   Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided also
+that the entire resulting derived work is distributed under the terms
+of a permission notice identical to this one.
+
+   Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions.
+
+
+File: gdbm.info,  Node: Top,  Next: Copying,  Prev: (dir),  Up: (dir)
+
+   GNU `dbm' is a library of functions implementing a hashed database
+on a disk file.  This manual documents GNU `dbm' Version 1.8.3
+(`gdbm').  The software was written by Philip A. Nelson. This document
+was originally written by Pierre Gaumond from texts written by Phil.
+
+* Menu:
+
+Introduction:
+
+* Copying::                    Your rights.
+* Intro::                      Introduction to GNU dbm.
+* List::                       List of functions.
+
+Functions:
+
+* Open::                       Opening the database.
+* Close::                      Closing the database.
+* Store::                      Inserting and replacing records in the database.
+* Fetch::                      Searching records in the database.
+* Delete::                     Removing records from the database.
+* Sequential::                 Sequential access to records.
+* Reorganization::             Database reorganization.
+* Sync::                       Insure all writes to disk have competed.
+* Errors::                     Convert internal error codes into English.
+* Options::                    Setting internal options.
+* Locking::                    File locking.
+
+Other topics:
+
+* Variables::                  Two useful variables.
+* Compatibility::              Compatibility with UNIX dbm and ndbm.
+* Conversion::                 Converting dbm files to gdbm format.
+* Bugs::                       Problems and bugs.
+
+
+File: gdbm.info,  Node: Copying,  Next: Intro,  Prev: Top,  Up: Top
+
+Copying Conditions.
+*******************
+
+   This library is "free"; this means that everyone is free to use it
+and free to redistribute it on a free basis.  GNU `dbm' (`gdbm') is not
+in the public domain; it is copyrighted and there are restrictions on
+its distribution, but these restrictions are designed to permit
+everything that a good cooperating citizen would want to do.  What is
+not allowed is to try to prevent others from further sharing any
+version of `gdbm' that they might get from you.
+
+   Specifically, we want to make sure that you have the right to give
+away copies `gdbm', that you receive source code or else can get it if
+you want it, that you can change these functions or use pieces of them
+in new free programs, and that you know you can do these things.
+
+   To make sure that everyone has such rights, we have to forbid you to
+deprive anyone else of these rights.  For example, if you distribute
+copies `gdbm', you must give the recipients all the rights that you
+have.  You must make sure that they, too, receive or can get the source
+code.  And you must tell them their rights.
+
+   Also, for our own protection, we must make certain that everyone
+finds out that there is no warranty for anything in the `gdbm'
+distribution.  If these functions are modified by someone else and
+passed on, we want their recipients to know that what they have is not
+what we distributed, so that any problems introduced by others will not
+reflect on our reputation.
+
+   `gdbm' is currently distributed under the terms of the GNU General
+Public License, Version 2.  (_NOT_ under the GNU General Library Public
+License.)  A copy the GNU General Public License is included with the
+distribution of `gdbm'.
+
+
+File: gdbm.info,  Node: Intro,  Next: List,  Prev: Copying,  Up: Top
+
+Introduction to GNU `dbm'.
+**************************
+
+   GNU `dbm' (`gdbm')is a library of database functions that use
+extendible hashing and works similar to the standard UNIX `dbm'
+functions.  These routines are provided to a programmer needing to
+create and manipulate a hashed database. (`gdbm' is _NOT_ a complete
+database package for an end user.)
+
+   The basic use of `gdbm' is to store key/data pairs in a data file.
+Each key must be unique and each key is paired with only one data item.
+The keys can not be directly accessed in sorted order.  The basic unit
+of data in `gdbm' is the structure:
+
+       typedef struct {
+                  char *dptr;
+                  int  dsize;
+               } datum;
+
+   This structure allows for arbitrary sized keys and data items.
+
+   The key/data pairs are stored in a `gdbm' disk file, called a `gdbm'
+database.  An application must open a `gdbm' database to be able
+manipulate the keys and data contained in the database.  `gdbm' allows
+an application to have multiple databases open at the same time.  When
+an application opens a `gdbm' database, it is designated as a `reader'
+or a `writer'.  A `gdbm' database opened by at most one writer at a
+time.  However, many readers may open the database open simultaneously.
+Readers and writers can not open the `gdbm' database at the same time.
+
+
+File: gdbm.info,  Node: List,  Next: Open,  Prev: Intro,  Up: Top
+
+List of functions.
+******************
+
+   The following is a quick list of the functions contained in the
+`gdbm' library. The include file `gdbm.h', that can be included by the
+user, contains a definition of these functions.
+
+     #include <gdbm.h>
+     
+     GDBM_FILE gdbm_open(name, block_size, flags, mode, fatal_func);
+     void gdbm_close(dbf);
+     int gdbm_store(dbf, key, content, flag);
+     datum gdbm_fetch(dbf, key);
+     int gdbm_delete(dbf, key);
+     datum gdbm_firstkey(dbf);
+     datum gdbm_nextkey(dbf, key);
+     int gdbm_reorganize(dbf);
+     void gdbm_sync(dbf);
+     int gdbm_exists(dbf, key);
+     char *gdbm_strerror(errno);
+     int gdbm_setopt(dbf, option, value, size);
+     int gdbm_fdesc(dbf);
+
+   The `gdbm.h' include file is often in the `/usr/local/include'
+directory. (The actual location of `gdbm.h' depends on your local
+installation of `gdbm'.)
+
+
+File: gdbm.info,  Node: Open,  Next: Close,  Prev: List,  Up: Top
+
+Opening the database.
+*********************
+
+   Initialize `gdbm' system. If the file has a size of zero bytes, a
+file initialization procedure is performed, setting up the initial
+structure in the file.
+
+   The procedure for opening a `gdbm' file is:
+
+     GDBM_FILE dbf;
+     
+     dbf = gdbm_open(name, block_size, flags, mode, fatal_func);
+
+   The parameters are:
+
+char *name
+     The name of the file (the complete name, `gdbm' does not append any
+     characters to this name).
+
+int block_size
+     It is used during initialization to determine the size of various
+     constructs. It is the size of a single transfer from disk to
+     memory. This parameter is ignored if the file has been previously
+     initialized. The minimum size is 512.  If the value is less than
+     512, the file system blocksize is used, otherwise the value of
+     `block_size' is used.
+
+int flags
+     If `flags' is set to GDBM_READER, the user wants to just read the
+     database and any call to `gdbm_store' or `gdbm_delete' will fail.
+     Many readers can access the database at the same time. If `flags'
+     is set to GDBM_WRITER, the user wants both read and write access
+     to the database and requires exclusive access. If `flags' is set
+     to GDBM_WRCREAT, the user wants both read and write access to the
+     database and if the database does not exist, create a new one. If
+     `flags' is set to GDBM_NEWDB, the user want a new database
+     created, regardless of whether one existed, and wants read and
+     write access to the new database.  The following may also be
+     logically or'd into the database flags: GDBM_SYNC, which causes
+     all database operations to be synchronized to the disk, and
+     GDBM_NOLOCK, which prevents the library from performing any
+     locking on the database file.  The option GDBM_FAST is now
+     obsolete, since `gdbm' defaults to no-sync mode.  Any error
+     detected will cause a return value of NULL and an appropriate
+     value will be in `gdbm_errno' (see Variables). If no errors occur,
+     a pointer to the `gdbm' file descriptor will be returned.
+
+int mode
+     File mode (see chmod(2) and open(2) if the file is created).
+
+void (*fatal_func) ()
+     A function for `gdbm' to call if it detects a fatal error. The only
+     parameter of this function is a string. If the value of NULL is
+     provided, `gdbm' will use a default function.
+
+   The return value, `dbf', is the pointer needed by all other
+functions to access that `gdbm' file. If the return is the NULL pointer,
+`gdbm_open' was not successful. The errors can be found in `gdbm_errno'
+for `gdbm' errors and in `errno' for file system errors (for error
+codes, see `gdbm.h').
+
+   In all of the following calls, the parameter `dbf' refers to the
+pointer returned from `gdbm_open'.
+
+
+File: gdbm.info,  Node: Close,  Next: Store,  Prev: Open,  Up: Top
+
+Closing the database.
+*********************
+
+   It is important that every file opened is also closed. This is
+needed to update the reader/writer count on the file. This is done by:
+
+     gdbm_close(dbf);
+
+   The parameter is:
+
+GDBM_FILE dbf
+     The pointer returned by `gdbm_open'.
+
+   Closes the `gdbm' file and frees all memory associated with the file
+`dbf'.
+
+
+File: gdbm.info,  Node: Store,  Next: Fetch,  Prev: Close,  Up: Top
+
+Inserting and replacing records in the database.
+************************************************
+
+   The function `gdbm_store' inserts or replaces records in the
+database.
+
+     ret = gdbm_store(dbf, key, content, flag);
+
+   The parameters are:
+
+GDBM_FILE dbf
+     The pointer returned by `gdbm_open'.
+
+datum key
+     The `key' data.
+
+datum content
+     The data to be associated with the key.
+
+int flag
+     Defines the action to take when the key is already in the
+     database. The value GDBM_REPLACE (defined in `gdbm.h') asks that
+     the old data be replaced by the new `content'. The value
+     GDBM_INSERT asks that an error be returned and no action taken if
+     the `key' already exists.
+
+   The values returned in `ret' are:
+
+-1
+     The item was not stored in the database because the caller was not
+     an official writer or either `key' or `content' have a NULL dptr
+     field.  Both `key' and `content' must have the dptr field be a
+     non-NULL value.  Since a NULL dptr field is used by other
+     functions to indicate an error, a NULL field cannot be valid data.
+
++1
+     The item was not stored because the argument `flag' was
+     GDBM_INSERT and the `key' was already in the database.
+
+0
+     No error. `content' is keyed by `key'. The file on disk is updated
+     to reflect the structure of the new database before returning from
+     this function.
+
+   If you store data for a `key' that is already in the data base,
+`gdbm' replaces the old data with the new data if called with
+GDBM_REPLACE. You do not get two data items for the same `key' and you
+do not get an error from `gdbm_store'.
+
+   The size in `gdbm' is not restricted like `dbm' or `ndbm'. Your data
+can be as large as you want.
+
+
+File: gdbm.info,  Node: Fetch,  Next: Delete,  Prev: Store,  Up: Top
+
+Searching for records in the database.
+**************************************
+
+   Looks up a given `key' and returns the information associated with
+that key. The pointer in the structure that is  returned is a pointer
+to dynamically allocated memory block. To search for some data:
+
+     content = gdbm_fetch(dbf, key);
+
+   The parameters are:
+
+GDBM_FILE dbf
+     The pointer returned by `gdbm_open'.
+
+datum key
+     The `key' data.
+
+   The datum returned in `content' is a pointer to the data found. If
+the dptr is NULL, no data was found. If dptr is not NULL, then it points
+to data allocated by malloc. `gdbm' does not automatically free this
+data.  The user must free this storage when done using it. This
+eliminates the need to copy the result to save it for later use (you
+just save the pointer).
+
+   You may also search for a particular key without retrieving it,
+using:
+
+     ret = gdbm_exists(dbf, key);
+
+   The parameters are:
+
+GDBM_FILE dbf
+     The pointer returned by `gdbm_open'.
+
+datum key
+     The `key' data.
+
+   Unlike `gdbm_fetch', this routine does not allocate any memory, and
+simply returns true or false, depending on whether the `key' exists, or
+not.
+
+
+File: gdbm.info,  Node: Delete,  Next: Sequential,  Prev: Fetch,  Up: Top
+
+Removing records from the database.
+***********************************
+
+   To remove some data from the database:
+
+     ret = gdbm_delete(dbf, key);
+
+   The parameters are:
+
+GDBM_FILE dbf
+     The pointer returned by `gdbm_open'.
+
+datum key
+     The `key' data.
+
+   The ret value is -1 if the item is not present or the requester is a
+reader.  The ret value is 0 if there was a successful delete.
+
+   `gdbm_delete' removes the keyed item and the `key' from the database
+`dbf'. The file on disk is updated to reflect the structure of the new
+database before returning from this function.
+
+
+File: gdbm.info,  Node: Sequential,  Next: Reorganization,  Prev: Delete,  Up: Top
+
+Sequential access to records.
+*****************************
+
+   The next two functions allow for accessing all items in the
+database. This access is not `key' sequential, but it is guaranteed to
+visit every `key' in the database once. The order has to do with the
+hash values.  `gdbm_firstkey' starts the visit of all keys in the
+database.  `gdbm_nextkey' finds and reads the next entry in the hash
+structure for `dbf'.
+
+     key = gdbm_firstkey(dbf);
+     
+     nextkey = gdbm_nextkey(dbf, key);
+
+   The parameters are:
+
+GDBM_FILE dbf
+     The pointer returned by `gdbm_open'.
+
+datum `key'
+
+datum nextkey
+     The `key' data.
+
+   The return values are both datum. If `key'.dptr or nextkey.dptr is
+NULL, there is no first `key' or next `key'. Again notice that dptr
+points to data allocated by malloc and `gdbm' will not free it for you.
+
+   These functions were intended to visit the database in read-only
+algorithms, for instance, to validate the database or similar
+operations.
+
+   File `visiting' is based on a `hash table'. `gdbm_delete'
+re-arranges the hash table to make sure that any collisions in the
+table do not leave some item `un-findable'. The original key order is
+NOT guaranteed to remain unchanged in ALL instances. It is possible
+that some key will not be visited if a loop like the following is
+executed:
+
+        key = gdbm_firstkey ( dbf );
+        while ( key.dptr ) {
+           nextkey = gdbm_nextkey ( dbf, key );
+           if ( some condition ) {
+              gdbm_delete ( dbf, key );
+              free ( key.dptr );
+           }
+           key = nextkey;
+        }
+
+
+File: gdbm.info,  Node: Reorganization,  Next: Sync,  Prev: Sequential,  Up: Top
+
+Database reorganization.
+************************
+
+   The following function should be used very seldom.
+
+     ret = gdbm_reorganize(dbf);
+
+   The parameter is:
+
+GDBM_FILE dbf
+     The pointer returned by `gdbm_open'.
+
+   If you have had a lot of deletions and would like to shrink the space
+used by the `gdbm' file, this function will reorganize the database.
+`gdbm' will not shorten the length of a `gdbm' file (deleted file space
+will be reused) except by using this reorganization.
+
+   This reorganization requires creating a new file and inserting all
+the elements in the old file `dbf' into the new file. The new file is
+then renamed to the same name as the old file and `dbf' is updated to
+contain all the correct information about the new file. If an error is
+detected, the return value is negative. The value zero is returned
+after a successful reorganization.
+
+
+File: gdbm.info,  Node: Sync,  Next: Errors,  Prev: Reorganization,  Up: Top
+
+Database Synchronization
+************************
+
+   Unless your database was opened with the GDBM_SYNC flag, `gdbm' does
+not wait for writes to be flushed to the disk before continuing.  This
+allows faster writing of databases at the risk of having a corrupted
+database if the application terminates in an abnormal fashion.  The
+following function allows the programmer to make sure the disk version
+of the database has been completely updated with all changes to the
+current time.
+
+     gdbm_sync(dbf);
+
+   The parameter is:
+
+GDBM_FILE dbf
+     The pointer returned by `gdbm_open'.
+
+   This would usually be called after a complete set of changes have
+been made to the database and before some long waiting time.
+`gdbm_close' automatically calls the equivalent of `gdbm_sync' so no
+call is needed if the database is to be closed immediately after the
+set of changes have been made.
+
+
+File: gdbm.info,  Node: Errors,  Next: Options,  Prev: Sync,  Up: Top
+
+Error strings.
+**************
+
+   To convert a `gdbm' error code into English text, use this routine:
+
+     ret = gdbm_strerror(errno)
+
+   The parameter is:
+
+gdbm_error errno
+     The `gdbm' error code, usually `gdbm_errno'.
+
+   The appropiate phrase for reading by humans is returned.
+
+
+File: gdbm.info,  Node: Options,  Next: Locking,  Prev: Errors,  Up: Top
+
+Seting options.
+***************
+
+   `Gdbm' supports the ability to set certain options on an already
+open database.
+
+     ret = gdbm_setopt(dbf, option, value, size);
+
+   The parameters are:
+
+GDBM_FILE dbf
+     The pointer returned by `gdbm_open'.
+
+int option
+     The option to be set.
+
+int *value
+     A pointer to the value to which `option' will be set.
+
+int size
+     The length of the data pointed to by `value'.
+
+   The valid options are:
+
+   GDBM_CACHESIZE - Set the size of the internal bucket cache.  This
+option may only be set once on each GDBM_FILE descriptor, and   is set
+automatically to 100 upon the first access to the database.
+
+   GDBM_FASTMODE - Set fast mode to either on or off.  This allows
+fast mode to be toggled on an already open and active database.
+value (see below) should be set to either TRUE or FALSE.    _This
+option is now obsolete._
+
+   GDBM_SYNCMODE - Turn on or off file system synchronization
+operations.  This   setting defaults to off; value (see below) should
+be set to either TRUE or   FALSE.
+
+   GDBM_CENTFREE - Set central free block pool to either on or off.
+The default is off, which is how previous versions of `Gdbm'   handled
+free blocks.  If set, this option causes all subsequent free   blocks
+to be placed in the _global_ pool, allowing (in theory)   more file
+space to be reused more quickly.  value (see below) should   be set to
+either TRUE or FALSE.    _NOTICE: This feature is still under study._
+
+   GDBM_COALESCEBLKS - Set free block merging to either on or off.
+The default is off, which is how previous versions of `Gdbm'   handled
+free blocks.  If set, this option causes adjacent free blocks   to be
+merged.  This can become a CPU expensive process with time, though,
+especially if used in conjunction with GDBM_CENTFREE.  value (see below)
+ should be set to either TRUE or FALSE.    _NOTICE: This feature is
+still under study._
+
+   The return value will be -1 upon failure, or 0 upon success.  The
+global variable `gdbm_errno' will be set upon failure.
+
+   For instance, to set a database to use a cache of 10, after opening
+it with `gdbm_open', but prior to accessing it in any way, the following
+code could be used:
+
+     int value = 10;
+     ret = gdbm_setopt(dbf, GDBM_CACHESIZE, &value, sizeof(int));
+
+
+File: gdbm.info,  Node: Locking,  Next: Variables,  Prev: Options,  Up: Top
+
+File Locking.
+*************
+
+   With locking disabled (if `gdbm_open' was called with GDBM_NOLOCK),
+the user may want to perform their own file locking on the database file
+in order to prevent multiple writers operating on the same file
+simultaneously.
+
+   In order to support this, the `gdbm_fdesc' routine is provided.
+
+     ret = gdbm_fdesc(dbf);
+
+   The single valid parameter is:
+
+GDBM_FILE dbf
+     The pointer returned by `gdbm_open'.
+
+   The return value will be the file descriptor of the database.
+
+
+File: gdbm.info,  Node: Variables,  Next: Compatibility,  Prev: Locking,  Up: Top
+
+Two useful variables.
+*********************
+
+   The following two variables are variables that may need to be used:
+
+gdbm_error gdbm_errno
+     The variable that contains more information about `gdbm' errors
+     (`gdbm.h' has the definitions of the error values).
+
+char * gdbm_version
+     The string containing the version information.
+
+
+File: gdbm.info,  Node: Compatibility,  Next: Conversion,  Prev: Variables,  Up: Top
+
+Compatibility with standard `dbm' and `ndbm'.
+*********************************************
+
+   GNU `dbm' files are not `sparse'. You can copy them with the UNIX
+`cp' command and they will not expand in the copying process.
+
+   There is a compatibility mode for use with programs that already use
+UNIX `dbm' and UNIX `ndbm'.
+
+   GNU `dbm' has compatibility functions for `dbm'. For `dbm'
+compatibility functions, you need the include file `dbm.h'.
+
+   In this compatibility mode, no `gdbm' file pointer is required by
+the user, and Only one file may be opened at a time. All users in
+compatibility mode are assumed to be writers. If the `gdbm' file is a
+read only, it will fail as a writer, but will also try to open it as a
+reader.  All returned pointers in datum structures point to data that
+`gdbm' WILL free. They should be treated as static pointers (as
+standard UNIX `dbm' does). The compatibility function names are the
+same as the UNIX `dbm' function names. Their definitions follow:
+
+     int dbminit(name);
+     int store(key, content);
+     datum fetch(key);
+     int delete(key);
+     datum firstkey();
+     datum nextkey(key);
+     int dbmclose();
+
+   Standard UNIX `dbm' and GNU `dbm' do not have the same data format
+in the file. You cannot access a standard UNIX `dbm' file with GNU
+`dbm'!  If you want to use an old database with GNU `dbm', you must use
+the `conv2gdbm' program.
+
+   Also, GNU `dbm' has compatibility functions for `ndbm'. For `ndbm'
+compatibility functions, you need the include file `ndbm.h'.
+
+   Again, just like `ndbm', any returned datum can be assumed to be
+static storage. You do not have to free that memory, the `ndbm'
+compatibility functions will do it for you.
+
+   The functions are:
+
+     DBM *dbm_open(name, flags, mode);
+     void dbm_close(file);
+     datum dbm_fetch(file, key);
+     int dbm_store(file, key, `content', flags);
+     int dbm_delete(file, key);
+     datum dbm_firstkey(file);
+     datum dbm_nextkey(file);
+     int dbm_error(file);
+     int dbm_clearerr(file);
+     int dbm_dirfno(file);
+     int dbm_pagfno(file);
+     int dbm_rdonly(file);
+
+   If you want to compile an old C program that used UNIX `dbm' or
+`ndbm' and want to use `gdbm' files, execute the following `cc' command:
+
+     cc ... -L/usr/local/lib -lgdbm -lgdbm_compat
+
+
+File: gdbm.info,  Node: Conversion,  Next: Bugs,  Prev: Compatibility,  Up: Top
+
+Converting `dbm' files to `gdbm' format.
+****************************************
+
+   The program `conv2gdbm' has been provided to help you convert from
+`dbm' databases to `gdbm'. The usage is:
+
+     conv2gdbm [-q] [-b block_size] dbm_file [gdbm_file]
+
+   The options are:
+
+-q
+     Causes `conv2gdbm' to work quietly.
+
+block_size
+     Is the same as in `gdbm_open'.
+
+dbm_file
+     Is the name of the `dbm' file without the `.pag' or `.dir'
+     extensions.
+
+gdbm_file
+     Is the complete file name. If not included, the `gdbm' file name
+     is the same as the `dbm' file name without any extensions. That is
+     `conv2gdbm' `dbmfile' converts the files `dbmfile.pag' and
+     `dbmfile.dir' into a `gdbm' file called `dbmfile'.
+
+
+File: gdbm.info,  Node: Bugs,  Prev: Conversion,  Up: Top
+
+Problems and bugs.
+******************
+
+   If you have problems with GNU `dbm' or think you've found a bug,
+please report it. Before reporting a bug, make sure you've actually
+found a real bug. Carefully reread the documentation and see if it
+really says you can do what you're trying to do. If it's not clear
+whether you should be able to do something or not, report that too; it's
+a bug in the documentation!
+
+   Before reporting a bug or trying to fix it yourself, try to isolate
+it to the smallest possible input file that reproduces the problem. Then
+send us the input file and the exact results `gdbm' gave you. Also say
+what you expected to occur; this will help us decide whether the
+problem was really in the documentation.
+
+   Once you've got a precise problem, send e-mail to:
+
+     Internet: `bug-gnu-utils@prep.ai.mit.edu'.
+     UUCP: `mit-eddie!prep.ai.mit.edu!bug-gnu-utils'.
+
+   Please include the version number of GNU `dbm' you are using. You
+can get this information by printing the variable `gdbm_version' (see
+Variables).
+
+   Non-bug suggestions are always welcome as well. If you have questions
+about things that are unclear in the documentation or are just obscure
+features, please report them too.
+
+   You may contact the author by:
+         e-mail:  phil@cs.wwu.edu
+        us-mail:  Philip A. Nelson
+                  Computer Science Department
+                  Western Washington University
+                  Bellingham, WA 98226
+
+   You may contact the current maintainer by:
+         e-mail:  downsj@downsj.com
+
+
+
+Tag Table:
+Node: Top884
+Node: Copying2359
+Node: Intro4141
+Node: List5557
+Node: Open6509
+Node: Close9380
+Node: Store9815
+Node: Fetch11610
+Node: Delete12859
+Node: Sequential13525
+Node: Reorganization15208
+Node: Sync16163
+Node: Errors17129
+Node: Options17489
+Node: Locking19838
+Node: Variables20426
+Node: Compatibility20850
+Node: Conversion23237
+Node: Bugs24051
+
+End Tag Table
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.proto
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.proto	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.proto	(revision 20131)
@@ -0,0 +1,101 @@
+/* gdbm.h  -  The include file for dbm users.  */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+/* Protection for multiple includes. */
+#ifndef _GDBM_H_
+#define _GDBM_H_
+
+/* Parameters to gdbm_open for READERS, WRITERS, and WRITERS who
+   can create the database. */
+#define  GDBM_READER  0		/* A reader. */
+#define  GDBM_WRITER  1		/* A writer. */
+#define  GDBM_WRCREAT 2		/* A writer.  Create the db if needed. */
+#define  GDBM_NEWDB   3		/* A writer.  Always create a new db. */
+#define  GDBM_FAST    0x10	/* Write fast! => No fsyncs.  OBSOLETE. */
+#define  GDBM_SYNC    0x20	/* Sync operations to the disk. */
+#define  GDBM_NOLOCK  0x40	/* Don't do file locking operations. */
+
+/* Parameters to gdbm_store for simple insertion or replacement in the
+   case that the key is already in the database. */
+#define  GDBM_INSERT  0		/* Never replace old data with new. */
+#define  GDBM_REPLACE 1		/* Always replace old data with new. */
+
+/* Parameters to gdbm_setopt, specifing the type of operation to perform. */
+#define  GDBM_CACHESIZE 1       /* Set the cache size. */
+#define  GDBM_FASTMODE  2       /* Toggle fast mode.  OBSOLETE. */
+#define  GDBM_SYNCMODE	3	/* Turn on or off sync operations. */
+#define  GDBM_CENTFREE  4	/* Keep all free blocks in the header. */
+#define  GDBM_COALESCEBLKS 5	/* Attempt to coalesce free blocks. */
+
+/* The data and key structure.  This structure is defined for compatibility. */
+typedef struct {
+	char *dptr;
+	int   dsize;
+      } datum;
+
+
+/* The file information header. This is good enough for most applications. */
+typedef struct {int dummy[10];} *GDBM_FILE;
+
+/* Determine if the C(++) compiler requires complete function prototype  */
+#ifndef __P
+#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
+#define __P(x) x
+#else
+#define __P(x) ()
+#endif
+#endif
+
+/* External variable, the gdbm build release string. */
+extern char *gdbm_version;	
+
+
+/* GDBM C++ support */
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* These are the routines! */
+
+extern GDBM_FILE gdbm_open __P((char *, int, int, int, void (*)()));
+extern void gdbm_close __P((GDBM_FILE));
+extern int gdbm_store __P((GDBM_FILE, datum, datum, int));
+extern datum gdbm_fetch __P((GDBM_FILE, datum));
+extern int gdbm_delete __P((GDBM_FILE, datum));
+extern datum gdbm_firstkey __P((GDBM_FILE));
+extern datum gdbm_nextkey __P((GDBM_FILE, datum));
+extern int gdbm_reorganize __P((GDBM_FILE));
+extern void gdbm_sync __P((GDBM_FILE));
+extern int gdbm_exists __P((GDBM_FILE, datum));
+extern int gdbm_setopt __P((GDBM_FILE, int, int *, int));
+extern int gdbm_fdesc __P((GDBM_FILE));
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.proto2
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.proto2	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.proto2	(revision 20131)
@@ -0,0 +1,15 @@
+
+/* extra prototypes */
+
+/* GDBM C++ support */
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+extern char *gdbm_strerror __P((gdbm_error));
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.texinfo
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.texinfo	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbm.texinfo	(revision 20131)
@@ -0,0 +1,793 @@
+\input texinfo	@c -*- Texinfo -*-
+@comment %**start of header (This is for running Texinfo on a region.)
+@setfilename gdbm.info
+@settitle gdbm
+@dircategory Programming & development tools
+@direntry
+* GDBM: (gdbm).			The GNU database manager.
+@end direntry
+@c @setchapternewpage odd
+@comment %**end of header (This is for running Texinfo on a region.)
+
+@iftex
+@finalout
+@end iftex
+
+@ifinfo
+This file documents the GNU dbm utility.
+
+Copyright (C) 1989-1999 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through Tex and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end ifinfo
+
+@titlepage
+@null
+@sp 6
+@center @titlefont{GNU dbm}
+@sp 2
+@center A Database Manager
+@sp 2
+@center by Philip A. Nelson and Jason Downs
+@sp 4
+@center Manual by Pierre Gaumond, Philip A. Nelson and Jason Downs
+@sp 1
+@center Edition 1.5
+@sp 1
+@center for GNU @code{dbm}, Version 1.8.3.
+@page
+@null
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1993-99 Free Software Foundation, Inc.
+@sp 2
+
+This is Edition 1.5 of the @cite{GNU @code{dbm} Manual}, for @code{gdbm}
+Version 1.8.3. @*
+Last updated October 15, 2002
+
+Published by the Free Software Foundation @*
+675 Massachusetts Avenue, @*
+Cambridge, MA 02139 USA @*
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Free Software Foundation.
+@end titlepage
+@page
+
+@node Top, Copying, (dir), (dir)
+@ifinfo
+GNU @code{dbm} is a library of functions implementing a hashed database
+on a disk file.  This manual documents GNU @code{dbm} Version 1.8.3
+(@code{gdbm}).  The software was written by Philip A. Nelson. This
+document was originally written by Pierre Gaumond from texts written by
+Phil.
+@end ifinfo
+
+
+@menu
+Introduction:
+
+* Copying::                    Your rights.
+* Intro::                      Introduction to GNU dbm.
+* List::                       List of functions.
+
+Functions:
+
+* Open::                       Opening the database.
+* Close::                      Closing the database.
+* Store::                      Inserting and replacing records in the database.
+* Fetch::                      Searching records in the database.
+* Delete::                     Removing records from the database.
+* Sequential::                 Sequential access to records.
+* Reorganization::             Database reorganization.
+* Sync::                       Insure all writes to disk have competed.
+* Errors::                     Convert internal error codes into English.
+* Options::                    Setting internal options.
+* Locking::                    File locking.
+
+Other topics:
+
+* Variables::                  Two useful variables.
+* Compatibility::              Compatibility with UNIX dbm and ndbm.
+* Conversion::                 Converting dbm files to gdbm format.
+* Bugs::                       Problems and bugs.
+@end menu
+
+@node Copying, Intro, Top, Top
+@chapter Copying Conditions.
+This library is @dfn{free}; this means that everyone is free to use
+it and free to redistribute it on a free basis.  GNU @code{dbm} (@code{gdbm})
+is not in the public domain; it is copyrighted and there
+are restrictions on its distribution, but these restrictions are
+designed to permit everything that a good cooperating citizen would want
+to do.  What is not allowed is to try to prevent others from further
+sharing any version of @code{gdbm} that they might get from
+you.@refill
+
+  Specifically, we want to make sure that you have the right to give
+away copies @code{gdbm}, that you receive
+source code or else can get it if you want it, that you can change these
+functions or use pieces of them in new free programs, and that you know
+you can do these things.@refill
+
+  To make sure that everyone has such rights, we have to forbid you to
+deprive anyone else of these rights.  For example, if you distribute
+copies @code{gdbm}, you must give the recipients all
+the rights that you have.  You must make sure that they, too, receive or
+can get the source code.  And you must tell them their rights.@refill
+
+  Also, for our own protection, we must make certain that everyone finds
+out that there is no warranty for anything in the @code{gdbm} distribution.
+If these functions are modified by someone else and passed on, we want
+their recipients to know that what they have is not what we distributed,
+so that any problems introduced by others will not reflect on our
+reputation.@refill
+
+@code{gdbm} is currently distributed under the terms of the GNU General
+Public License, Version 2.  (@emph{NOT} under the GNU General Library
+Public License.)  A copy the GNU General Public License is included with
+the distribution of @code{gdbm}.
+
+@node Intro, List, Copying, Top
+@chapter Introduction to GNU @code{dbm}.
+
+GNU @code{dbm} (@code{gdbm})is a library of database functions that use
+extendible hashing and works similar to the standard UNIX @code{dbm}
+functions.  These routines are provided to a programmer needing to
+create and manipulate a hashed database. (@code{gdbm} is @emph{NOT} a
+complete database package for an end user.)
+
+The basic use of @code{gdbm} is to store key/data pairs in a data file.
+Each key must be unique and each key is paired with only one data item.
+The keys can not be directly accessed in sorted order.  The basic unit
+of data in @code{gdbm} is the structure:
+
+@example
+  typedef struct @{
+             char *dptr;
+             int  dsize;
+          @} datum;
+@end example
+
+This structure allows for arbitrary sized keys and data items.
+
+The key/data pairs are stored in a @code{gdbm} disk file, called a
+@code{gdbm} database.  An application must open a @code{gdbm} database
+to be able manipulate the keys and data contained in the database.
+@code{gdbm} allows an application to have multiple databases open at the
+same time.  When an application opens a @code{gdbm} database, it is
+designated as a @code{reader} or a @code{writer}.  A @code{gdbm}
+database opened by at most one writer at a time.  However, many readers
+may open the database open simultaneously.  Readers and writers can not
+open the @code{gdbm} database at the same time.
+
+@node List, Open, Intro, Top
+@chapter List of functions.
+
+The following is a quick list of the functions contained in the @code{gdbm}
+library. The include file @code{gdbm.h}, that can be included by the user,
+contains a definition of these functions.
+
+@example
+#include <gdbm.h>
+
+GDBM_FILE gdbm_open(name, block_size, flags, mode, fatal_func);
+void gdbm_close(dbf);
+int gdbm_store(dbf, key, content, flag);
+datum gdbm_fetch(dbf, key);
+int gdbm_delete(dbf, key);
+datum gdbm_firstkey(dbf);
+datum gdbm_nextkey(dbf, key);
+int gdbm_reorganize(dbf);
+void gdbm_sync(dbf);
+int gdbm_exists(dbf, key);
+char *gdbm_strerror(errno);
+int gdbm_setopt(dbf, option, value, size);
+int gdbm_fdesc(dbf);
+@end example
+
+The @code{gdbm.h} include file is often in the @file{/usr/local/include}
+directory. (The actual location of @code{gdbm.h} depends on your local
+installation of @code{gdbm}.)
+
+@node Open, Close, List, Top
+@chapter Opening the database.
+
+Initialize @code{gdbm} system. If the file has a size of zero bytes, a file
+initialization procedure is performed, setting up the initial structure in the
+file.
+
+The procedure for opening a @code{gdbm} file is:
+
+@example
+GDBM_FILE dbf;
+
+dbf = gdbm_open(name, block_size, flags, mode, fatal_func);
+@end example
+
+The parameters are:
+
+@table @asis
+@item char *name
+The name of the file (the complete name, @code{gdbm} does not append any
+characters to this name).
+@item int block_size
+It is used during initialization to determine the size of various constructs. It
+is the size of a single transfer from disk to memory. This parameter is ignored
+if the file has been previously initialized. The minimum size is 512.
+If the value is less than 512, the file system blocksize is used, otherwise the
+value of @code{block_size} is used.
+@item int flags
+If @code{flags} is set to GDBM_READER, the user wants to just read the
+database and any call to @code{gdbm_store} or @code{gdbm_delete} will fail.
+Many readers can access the database at the same time. If @code{flags} is
+set to GDBM_WRITER, the user wants both read and write access to the database
+and requires exclusive access. If @code{flags} is set to GDBM_WRCREAT, the
+user wants both read and write access to the database and if the database does
+not exist, create a new one. If @code{flags} is set to GDBM_NEWDB, the
+user want a new database created, regardless of whether one existed, and wants
+read and write access to the new database.  The following may also be logically
+or'd into the database flags: GDBM_SYNC, which causes all database operations
+to be synchronized to the disk, and GDBM_NOLOCK, which prevents the library
+from performing any locking on the database file.  The option GDBM_FAST is
+now obsolete, since @code{gdbm} defaults to no-sync mode.  Any error detected
+will cause a return value of NULL and an appropriate value will be in
+@code{gdbm_errno} (see Variables). If no errors occur, a pointer to the
+@code{gdbm} file descriptor will be returned.
+@item int mode
+File mode (see chmod(2) and open(2) if the file is created).
+@item void (*fatal_func) ()
+A function for @code{gdbm} to call if it detects a fatal error. The only
+parameter of this function is a string. If the value of NULL is provided,
+@code{gdbm} will use a default function.
+@end table
+
+The return value, @code{dbf}, is the pointer needed by all other functions to
+access that @code{gdbm} file. If the return is the NULL pointer,
+@code{gdbm_open} was not successful. The errors can be found in
+@code{gdbm_errno} for @code{gdbm} errors and in @code{errno} for file system
+errors (for error codes, see @code{gdbm.h}).
+
+In all of the following calls, the parameter @code{dbf} refers to the pointer
+returned from @code{gdbm_open}.
+
+@node Close, Store, Open, Top
+@chapter Closing the database.
+
+It is important that every file opened is also closed. This is needed to
+update the reader/writer count on the file. This is done by:
+
+@example
+gdbm_close(dbf);
+@end example
+
+The parameter is:
+
+@table @asis
+@item GDBM_FILE dbf
+The pointer returned by @code{gdbm_open}.
+@end table
+
+Closes the @code{gdbm} file and frees all memory associated with the file 
+@code{dbf}. 
+
+@node Store, Fetch, Close, Top
+@chapter Inserting and replacing records in the database.
+
+The function @code{gdbm_store} inserts or replaces records in the database.
+
+@example
+ret = gdbm_store(dbf, key, content, flag);
+@end example
+
+The parameters are:
+
+@table @asis
+@item GDBM_FILE dbf
+The pointer returned by @code{gdbm_open}.
+@item datum key
+The @code{key} data.
+@item datum content
+The data to be associated with the key.
+@item int flag
+Defines the action to take when the key is already in the database. The value
+GDBM_REPLACE (defined in @code{gdbm.h}) asks that the old data be replaced by
+the new @code{content}. The value GDBM_INSERT asks that an error be returned
+and no action taken if the @code{key} already exists.
+@end table
+
+The values returned in @code{ret} are:
+
+@table @asis
+@item -1
+The item was not stored in the database because the caller was not an
+official writer or either @code{key} or @code{content} have a NULL dptr field.
+Both @code{key} and @code{content} must have the dptr field be a non-NULL value.
+Since a NULL dptr field is used by other functions to indicate an error, a NULL
+field cannot be valid data.
+@item +1
+The item was not stored because the argument @code{flag} was GDBM_INSERT and
+the @code{key} was already in the database.
+@item 0
+No error. @code{content} is keyed by @code{key}. The file on disk is updated
+to reflect the structure of the new database before returning from this
+function.
+@end table
+
+If you store data for a @code{key} that is already in the data base,
+@code{gdbm} replaces the old data with the new data if called with
+GDBM_REPLACE. You do not get two data items for the same @code{key} and you do
+not get an error from @code{gdbm_store}.
+
+The size in @code{gdbm} is not restricted like @code{dbm} or @code{ndbm}. Your
+data can be as large as you want.
+
+@node Fetch, Delete, Store,Top
+@chapter Searching for records in the database.
+
+Looks up a given @code{key} and returns the information associated with that
+key. The pointer in the structure that is  returned is a pointer to dynamically
+allocated memory block. To search for some data:
+
+@example
+content = gdbm_fetch(dbf, key);
+@end example
+
+The parameters are:
+
+@table @asis
+@item GDBM_FILE dbf
+The pointer returned by @code{gdbm_open}.
+@item datum key
+The @code{key} data.
+@end table
+
+The datum returned in @code{content} is a pointer to the data found. If the
+dptr is NULL, no data was found. If dptr is not NULL, then it points
+to data allocated by malloc. @code{gdbm} does not automatically free this data.
+The user must free this storage when done using it. This eliminates the
+need to copy the result to save it for later use (you just save the pointer).
+
+You may also search for a particular key without retrieving it, using:
+
+@example
+ret = gdbm_exists(dbf, key);
+@end example
+
+The parameters are:
+
+@table @asis
+@item GDBM_FILE dbf
+The pointer returned by @code{gdbm_open}.
+@item datum key
+The @code{key} data.
+@end table
+
+Unlike @code{gdbm_fetch}, this routine does not allocate any memory, and
+simply returns true or false, depending on whether the @code{key} exists,
+or not.
+
+@node Delete, Sequential, Fetch, Top
+@chapter Removing records from the database.
+
+To remove some data from the database:
+
+@example
+ret = gdbm_delete(dbf, key);
+@end example
+
+The parameters are:
+
+@table @asis
+@item GDBM_FILE dbf
+The pointer returned by @code{gdbm_open}.
+@item datum key
+The @code{key} data.
+@end table
+
+The ret value is -1 if the item is not present or the requester is a reader.
+The ret value is 0 if there was a successful delete.
+
+@code{gdbm_delete} removes the keyed item and the @code{key} from the database
+@code{dbf}. The file on disk is updated to reflect the structure of the new
+database before returning from this function.
+
+@node Sequential, Reorganization, Delete, Top
+@chapter Sequential access to records.
+
+The next two functions allow for accessing all items in the database. This
+access is not @code{key} sequential, but it is guaranteed to visit every
+@code{key} in the database once. The order has to do with the hash values.
+@code{gdbm_firstkey} starts the visit of all keys in the database.
+@code{gdbm_nextkey} finds and reads the next entry in the hash structure for
+@code{dbf}.
+
+@example
+key = gdbm_firstkey(dbf);
+
+nextkey = gdbm_nextkey(dbf, key);
+@end example
+
+The parameters are:
+
+@table @asis
+@item GDBM_FILE dbf
+The pointer returned by @code{gdbm_open}.
+@item datum @code{key}
+@item datum nextkey
+The @code{key} data.
+@end table
+
+The return values are both datum. If @code{key}.dptr or nextkey.dptr is NULL,
+there is no first @code{key} or next @code{key}. Again notice that dptr points to
+data allocated by malloc and @code{gdbm} will not free it for you.
+
+These functions were intended to visit the database in read-only algorithms,
+for instance, to validate the database or similar operations.
+
+File @code{visiting} is based on a @code{hash table}. @code{gdbm_delete}
+re-arranges the hash table to make sure that any collisions in the table do not
+leave some item @code{un-findable}. The original key order is NOT guaranteed to
+remain unchanged in ALL instances. It is possible that some key will not be
+visited if a loop like the following is executed:
+
+@example
+@group
+   key = gdbm_firstkey ( dbf );
+   while ( key.dptr ) @{
+      nextkey = gdbm_nextkey ( dbf, key );
+      if ( some condition ) @{
+         gdbm_delete ( dbf, key );
+         free ( key.dptr );
+      @}
+      key = nextkey;
+   @}
+@end group
+@end example
+
+@node Reorganization, Sync, Sequential, Top
+@chapter Database reorganization.
+
+The following function should be used very seldom.
+
+@example
+ret = gdbm_reorganize(dbf);
+@end example
+
+The parameter is:
+
+@table @asis
+@item GDBM_FILE dbf
+The pointer returned by @code{gdbm_open}.
+@end table
+
+If you have had a lot of deletions and would like to shrink the space
+used by the @code{gdbm} file, this function will reorganize the database.
+@code{gdbm} will not shorten the length of a @code{gdbm} file (deleted file space will be
+reused) except by using this reorganization.
+
+This reorganization requires creating a new file and inserting all the elements
+in the old file @code{dbf} into the new file. The new file is then renamed to
+the same name as the old file and @code{dbf} is updated to contain all the
+correct information about the new file. If an error is detected, the return
+value is negative. The value zero is returned after a successful
+reorganization.
+
+@node Sync, Errors, Reorganization, Top
+@chapter Database Synchronization
+
+Unless your database was opened with the GDBM_SYNC flag, @code{gdbm} does not
+wait for writes to be flushed to the disk before continuing.  This allows
+faster writing of databases at the risk of having a corrupted database if
+the application terminates in an abnormal fashion.  The following function
+allows the programmer to make sure the disk version of the 
+database has been completely updated with all changes to the current time.
+
+@example
+gdbm_sync(dbf);
+@end example
+
+The parameter is:
+
+@table @asis
+@item GDBM_FILE dbf
+The pointer returned by @code{gdbm_open}.
+@end table
+
+This would usually be called after a complete set of changes have been
+made to the database and before some long waiting time.
+@code{gdbm_close} automatically calls the equivalent of @code{gdbm_sync}
+so no call is needed if the database is to be closed immediately after
+the set of changes have been made.
+
+@node Errors, Options, Sync, Top
+@chapter Error strings.
+
+To convert a @code{gdbm} error code into English text, use this routine:
+
+@example
+ret = gdbm_strerror(errno)
+@end example
+
+The parameter is:
+
+@table @asis
+@item gdbm_error errno
+The @code{gdbm} error code, usually @code{gdbm_errno}.
+@end table
+
+The appropiate phrase for reading by humans is returned.
+
+@node Options, Locking, Errors, top
+@chapter Seting options.
+
+@code{Gdbm} supports the ability to set certain options on an already
+open database.
+
+@example
+ret = gdbm_setopt(dbf, option, value, size);
+@end example
+
+The parameters are:
+
+@table @asis
+@item GDBM_FILE dbf
+The pointer returned by @code{gdbm_open}.
+@item int option
+The option to be set.
+@item int *value
+A pointer to the value to which @code{option} will be set.
+@item int size
+The length of the data pointed to by @code{value}.
+@end table
+
+The valid options are:
+
+  GDBM_CACHESIZE - Set the size of the internal bucket cache.  This
+  option may only be set once on each GDBM_FILE descriptor, and
+  is set automatically to 100 upon the first access to the database.
+
+  GDBM_FASTMODE - Set fast mode to either on or off.  This allows
+  fast mode to be toggled on an already open and active database.
+  value (see below) should be set to either TRUE or FALSE.
+  @emph{This option is now obsolete.}
+
+  GDBM_SYNCMODE - Turn on or off file system synchronization operations.  This
+  setting defaults to off; value (see below) should be set to either TRUE or
+  FALSE.
+
+  GDBM_CENTFREE - Set central free block pool to either on or off.
+  The default is off, which is how previous versions of @code{Gdbm}
+  handled free blocks.  If set, this option causes all subsequent free
+  blocks to be placed in the @emph{global} pool, allowing (in theory)
+  more file space to be reused more quickly.  value (see below) should
+  be set to either TRUE or FALSE.
+  @emph{NOTICE: This feature is still under study.}
+
+  GDBM_COALESCEBLKS - Set free block merging to either on or off.
+  The default is off, which is how previous versions of @code{Gdbm}
+  handled free blocks.  If set, this option causes adjacent free blocks
+  to be merged.  This can become a CPU expensive process with time, though,
+  especially if used in conjunction with GDBM_CENTFREE.  value (see below)
+  should be set to either TRUE or FALSE.
+  @emph{NOTICE: This feature is still under study.}
+
+The return value will be -1 upon failure, or 0 upon success.  The global
+variable @code{gdbm_errno} will be set upon failure.
+
+For instance, to set a database to use a cache of 10, after opening it
+with @code{gdbm_open}, but prior to accessing it in any way, the following
+code could be used:
+
+@example
+int value = 10;
+ret = gdbm_setopt(dbf, GDBM_CACHESIZE, &value, sizeof(int));
+@end example
+
+@node Locking, Variables, Options, Top
+@chapter File Locking.
+
+With locking disabled (if @code{gdbm_open} was called with GDBM_NOLOCK),
+the user may want to perform their own file locking on the database file
+in order to prevent multiple writers operating on the same file
+simultaneously.
+
+In order to support this, the @code{gdbm_fdesc} routine is provided.
+
+@example
+ret = gdbm_fdesc(dbf);
+@end example
+
+The single valid parameter is:
+
+@table @asis
+@item GDBM_FILE dbf
+The pointer returned by @code{gdbm_open}.
+@end table
+
+The return value will be the file descriptor of the database.
+
+@node Variables, Compatibility, Locking, Top
+@chapter Two useful variables.
+
+The following two variables are variables that may need to be used:
+
+@table @asis
+@item gdbm_error gdbm_errno
+The variable that contains more information about @code{gdbm} errors
+(@code{gdbm.h} has the definitions of the error values).
+@item char * gdbm_version
+The string containing the version information.
+@end table
+
+@node Compatibility, Conversion, Variables, Top
+@chapter Compatibility with standard @code{dbm} and @code{ndbm}.
+
+GNU @code{dbm} files are not @code{sparse}. You can copy them with the UNIX
+@code{cp} command and they will not expand in the copying process.
+
+There is a compatibility mode for use with programs that already use UNIX
+@code{dbm} and UNIX @code{ndbm}.
+
+GNU @code{dbm} has compatibility functions for @code{dbm}. For @code{dbm}
+compatibility functions, you need the include file @code{dbm.h}.
+
+In this compatibility mode, no @code{gdbm} file pointer is required
+by the user, and Only one file may be opened at a time. All users in
+compatibility mode are assumed to be writers. If the @code{gdbm} file is a
+read only, it will fail as a writer, but will also try to open it as a reader.
+All returned pointers in datum structures point to data that @code{gdbm} WILL
+free. They should be treated as static pointers (as standard UNIX @code{dbm}
+does). The compatibility function names are the same as the UNIX @code{dbm}
+function names. Their definitions follow:
+
+@example
+int dbminit(name);
+int store(key, content);
+datum fetch(key);
+int delete(key);
+datum firstkey();
+datum nextkey(key);
+int dbmclose();
+@end example
+
+Standard UNIX @code{dbm} and GNU @code{dbm} do not have the same data
+format in the file. You cannot access a standard UNIX @code{dbm} file with GNU
+@code{dbm}!  If you want to use an old database with GNU @code{dbm}, you must
+use the @code{conv2gdbm} program.
+
+Also, GNU @code{dbm} has compatibility functions for @code{ndbm}. For
+@code{ndbm} compatibility functions, you need the include file @code{ndbm.h}.
+
+Again, just like @code{ndbm}, any returned datum can be assumed to be static
+storage. You do not have to free that memory, the @code{ndbm} compatibility
+functions will do it for you.
+
+The functions are:
+
+@example
+DBM *dbm_open(name, flags, mode);
+void dbm_close(file);
+datum dbm_fetch(file, key);
+int dbm_store(file, key, @code{content}, flags);
+int dbm_delete(file, key);
+datum dbm_firstkey(file);
+datum dbm_nextkey(file);
+int dbm_error(file);
+int dbm_clearerr(file);
+int dbm_dirfno(file);
+int dbm_pagfno(file);
+int dbm_rdonly(file);
+@end example
+
+If you want to compile an old C program that used UNIX @code{dbm} or @code{ndbm}
+and want to use @code{gdbm} files, execute the following @code{cc} command:
+
+@example
+cc ... -L/usr/local/lib -lgdbm -lgdbm_compat
+@end example
+
+@node Conversion, Bugs, Compatibility, Top
+@chapter Converting @code{dbm} files to @code{gdbm} format.
+
+The program @code{conv2gdbm} has been provided to help you convert from @code{dbm}
+databases to @code{gdbm}. The usage is:
+
+@example
+conv2gdbm [-q] [-b block_size] dbm_file [gdbm_file]
+@end example
+
+The options are:
+
+@table @asis
+@item -q
+Causes @code{conv2gdbm} to work quietly.
+@item block_size
+Is the same as in @code{gdbm_open}.
+@item dbm_file
+Is the name of the @code{dbm} file without the @code{.pag} or @code{.dir}
+extensions.
+@item gdbm_file
+Is the complete file name. If not included, the @code{gdbm} file name is the
+same as the @code{dbm} file name without any extensions. That is
+@code{conv2gdbm} @code{dbmfile} converts the files @code{dbmfile.pag} and
+@code{dbmfile.dir} into a @code{gdbm} file called @code{dbmfile}.
+@end table
+
+
+@node Bugs, , Conversion, Top
+@chapter Problems and bugs.
+
+If you have problems with GNU @code{dbm} or think you've found a bug,
+please report it. Before reporting a bug, make sure you've actually
+found a real bug. Carefully reread the documentation and see if it
+really says you can do what you're trying to do. If it's not clear
+whether you should be able to do something or not, report that too; it's
+a bug in the documentation!
+
+Before reporting a bug or trying to fix it yourself, try to isolate it
+to the smallest possible input file that reproduces the problem. Then
+send us the input file and the exact results @code{gdbm} gave you. Also
+say what you expected to occur; this will help us decide whether the
+problem was really in the documentation.
+
+Once you've got a precise problem, send e-mail to:
+
+@example
+Internet: @file{bug-gnu-utils@@prep.ai.mit.edu}.
+UUCP: @file{mit-eddie!prep.ai.mit.edu!bug-gnu-utils}.
+@end example
+
+Please include the version number of GNU @code{dbm} you are using. You can get
+this information by printing the variable @code{gdbm_version} (see Variables).
+
+Non-bug suggestions are always welcome as well. If you have questions
+about things that are unclear in the documentation or are just obscure
+features, please report them too.
+
+You may contact the author by:
+@example
+    e-mail:  phil@@cs.wwu.edu
+   us-mail:  Philip A. Nelson
+             Computer Science Department
+             Western Washington University
+             Bellingham, WA 98226
+@end example
+
+You may contact the current maintainer by:
+@example
+    e-mail:  downsj@@downsj.com
+@end example
+
+@bye
+
+
+
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmclose.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmclose.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmclose.c	(revision 20131)
@@ -0,0 +1,75 @@
+/* gdbmclose.c - Close a previously opened dbm file. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+
+/* Close the dbm file and free all memory associated with the file DBF.
+   Before freeing members of DBF, check and make sure that they were
+   allocated.  */
+
+void
+gdbm_close (dbf)
+     gdbm_file_info *dbf;
+{
+  register int index;	/* For freeing the bucket cache. */
+
+  /* Make sure the database is all on disk. */
+  if (dbf->read_write != GDBM_READER)
+    fsync (dbf->desc);
+
+  /* Close the file and free all malloced memory. */
+  if (dbf->file_locking)
+    {
+#ifdef MSDOS
+      if (dbf->need_filelock) {
+	UNLOCK_FILE(dbf);
+      }
+#else
+      UNLOCK_FILE(dbf);
+#endif
+    }
+  close (dbf->desc);
+  free (dbf->name);
+  if (dbf->dir != NULL) free (dbf->dir);
+
+  if (dbf->bucket_cache != NULL) {
+    for (index = 0; index < dbf->cache_size; index++) {
+      if (dbf->bucket_cache[index].ca_bucket != NULL)
+	free (dbf->bucket_cache[index].ca_bucket);
+      if (dbf->bucket_cache[index].ca_data.dptr != NULL)
+	free (dbf->bucket_cache[index].ca_data.dptr);
+    }
+    free (dbf->bucket_cache);
+  }
+  if ( dbf->header != NULL ) free (dbf->header);
+  free (dbf);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmconst.h
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmconst.h	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmconst.h	(revision 20131)
@@ -0,0 +1,66 @@
+/* gdbmconst.h - The constants defined for use in gdbm. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+/* Start with the constant definitions.  */
+#define  TRUE    1
+#define  FALSE   0
+
+/* Parameters to gdbm_open. */
+#define  GDBM_READER  0		/* READERS only. */
+#define  GDBM_WRITER  1		/* READERS and WRITERS.  Can not create. */
+#define  GDBM_WRCREAT 2		/* If not found, create the db. */
+#define  GDBM_NEWDB   3		/* ALWAYS create a new db.  (WRITER) */
+#define  GDBM_OPENMASK 7	/* Mask for the above. */
+#define  GDBM_FAST    0x10	/* Write fast! => No fsyncs.  OBSOLETE. */
+#define  GDBM_SYNC    0x20	/* Sync operations to the disk. */
+#define  GDBM_NOLOCK  0x40	/* Don't do file locking operations. */
+
+/* Parameters to gdbm_store for simple insertion or replacement in the
+   case a key to store is already in the database. */
+#define  GDBM_INSERT  0		/* Do not overwrite data in the database. */
+#define  GDBM_REPLACE 1		/* Replace the old value with the new value. */
+
+/* Parameters to gdbm_setopt, specifing the type of operation to perform. */
+#define	 GDBM_CACHESIZE	1	/* Set the cache size. */
+#define  GDBM_FASTMODE	2	/* Turn on or off fast mode.  OBSOLETE. */
+#define  GDBM_SYNCMODE	3	/* Turn on or off sync operations. */
+#define  GDBM_CENTFREE	4	/* Keep all free blocks in the header. */
+#define  GDBM_COALESCEBLKS 5	/* Attempt to coalesce free blocks. */
+
+/* In freeing blocks, we will ignore any blocks smaller (and equal) to
+   IGNORE_SIZE number of bytes. */
+#define IGNORE_SIZE 4
+
+/* The number of key bytes kept in a hash bucket. */
+#define SMALL    4
+
+/* The number of bucket_avail entries in a hash bucket. */
+#define BUCKET_AVAIL 6
+
+/* The size of the bucket cache. */
+#define DEFAULT_CACHESIZE  100
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmdefs.h
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmdefs.h	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmdefs.h	(revision 20131)
@@ -0,0 +1,218 @@
+/* gdbmdefs.h - The include file for dbm.  Defines structure and constants. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+*************************************************************************/
+
+#include "systems.h"
+#include "gdbmconst.h"
+
+/* On MacOS X, off_t is "long long int" but on Linux (CentOS) it is "long int" 
+   The following ensure that we use the same for both, and so lets
+   GDBM read the same database files */
+
+#undef off_t
+#define off_t long
+
+/* The type definitions are next.  */
+
+/* The data and key structure.  This structure is defined for compatibility. */
+
+typedef struct {
+	char *dptr;
+	int   dsize;
+      } datum;
+
+
+/* The available file space is stored in an "avail" table.  The one with
+   most activity is contained in the file header. (See below.)  When that
+   one filles up, it is split in half and half is pushed on an "avail
+   stack."  When the active avail table is empty and the "avail stack" is
+   not empty, the top of the stack is popped into the active avail table. */
+
+/* The following structure is the element of the avaliable table.  */
+typedef struct {
+  	int   av_size;		/* The size of the available block. */
+	off_t  av_adr;		/* The file address of the available block. */
+      } avail_elem;
+
+/* This is the actual table. The in-memory images of the avail blocks are
+   allocated by malloc using a calculated size.  */
+typedef struct {
+	int   size;		/* The number of avail elements in the table.*/
+	int   count;		/* The number of entries in the table. */
+	off_t next_block;	/* The file address of the next avail block. */
+	avail_elem av_table[1]; /* The table.  Make it look like an array.  */
+      } avail_block;
+
+/* The dbm file header keeps track of the current location of the hash
+   directory and the free space in the file.  */
+
+typedef struct {
+	int   header_magic;  /* 0x13579ace to make sure the header is good. */
+	int   block_size;    /* The  optimal i/o blocksize from stat. */
+	off_t dir;	     /* File address of hash directory table. */
+	int   dir_size;	     /* Size in bytes of the table.  */
+	int   dir_bits;	     /* The number of address bits used in the table.*/
+	int   bucket_size;   /* Size in bytes of a hash bucket struct. */
+	int   bucket_elems;  /* Number of elements in a hash bucket. */
+	off_t next_block;    /* The next unallocated block address. */
+	avail_block avail;   /* This must be last because of the psuedo
+				array in avail.  This avail grows to fill
+				the entire block. */
+      }  gdbm_file_header;
+
+
+/* The dbm hash bucket element contains the full 31 bit hash value, the
+   "pointer" to the key and data (stored together) with their sizes.  It also
+   has a small part of the actual key value.  It is used to verify the first
+   part of the key has the correct value without having to read the actual
+   key. */
+
+typedef struct {
+	int   hash_value;	/* The complete 31 bit value. */
+	char  key_start[SMALL];	/* Up to the first SMALL bytes of the key.  */
+	off_t data_pointer;	/* The file address of the key record. The
+				   data record directly follows the key.  */
+	int   key_size;		/* Size of key data in the file. */
+	int   data_size;	/* Size of associated data in the file. */
+      } bucket_element;
+
+
+/* A bucket is a small hash table.  This one consists of a number of
+   bucket elements plus some bookkeeping fields.  The number of elements
+   depends on the optimum blocksize for the storage device and on a
+   parameter given at file creation time.  This bucket takes one block.
+   When one of these tables gets full, it is split into two hash buckets.
+   The contents are split between them by the use of the first few bits
+   of the 31 bit hash function.  The location in a bucket is the hash
+   value modulo the size of the bucket.  The in-memory images of the
+   buckets are allocated by malloc using a calculated size depending of
+   the file system buffer size.  To speed up write, each bucket will have
+   BUCKET_AVAIL avail elements with the bucket. */
+
+typedef struct {
+        int   av_count;		   /* The number of bucket_avail entries. */
+        avail_elem bucket_avail[BUCKET_AVAIL];  /* Distributed avail. */
+	int   bucket_bits;	   /* The number of bits used to get here. */
+	int   count;		   /* The number of element buckets full. */
+	bucket_element h_table[1]; /* The table.  Make it look like an array.*/
+      } hash_bucket;
+
+/* We want to keep from reading buckets as much as possible.  The following is
+   to implement a bucket cache.  When full, buckets will be dropped in a
+   least recently read from disk order.  */
+
+/* To speed up fetching and "sequential" access, we need to implement a
+   data cache for key/data pairs read from the file.  To find a key, we
+   must exactly match the key from the file.  To reduce overhead, the
+   data will be read at the same time.  Both key and data will be stored
+   in a data cache.  Each bucket cached will have a one element data
+   cache.  */
+
+typedef struct {
+        int   hash_val;
+	int   data_size;
+	int   key_size;
+	char *dptr;
+	int   elem_loc;
+      }  data_cache_elem;
+
+typedef struct {
+        hash_bucket *   ca_bucket;
+	off_t           ca_adr;
+	char		ca_changed;   /* Data in the bucket changed. */
+	data_cache_elem ca_data;
+      } cache_elem;
+
+
+
+/* This final structure contains all main memory based information for
+   a gdbm file.  This allows multiple gdbm files to be opened at the same
+   time by one program. */
+
+typedef struct {
+	/* Global variables and pointers to dynamic variables used by gdbm.  */
+
+  	/* The file name. */
+	char *name;
+
+	/* The reader/writer status. */
+	int read_write;
+
+	/* Fast_write is set to 1 if no fsyncs are to be done. */
+	int fast_write;
+
+	/* Central_free is set if all free blocks are kept in the header. */
+	int central_free;
+
+	/* Coalesce_blocks is set if we should try to merge free blocks. */
+	int coalesce_blocks;
+
+	/* Whether or not we should do file locking ourselves. */
+	int file_locking;
+
+	/* The fatal error handling routine. */
+	void (*fatal_err) ();
+
+#ifdef MSDOS
+        int need_filelock;
+#endif
+
+	/* The gdbm file descriptor which is set in gdbm_open.  */
+	int desc;
+
+	/* The file header holds information about the database. */
+	gdbm_file_header *header;
+
+	/* The hash table directory from extendible hashing.  See Fagin et al, 
+	   ACM Trans on Database Systems, Vol 4, No 3. Sept 1979, 315-344 */
+	off_t *dir;
+
+	/* The bucket cache. */
+	cache_elem *bucket_cache;
+	int cache_size;
+	int last_read;
+
+	/* Points to the current hash bucket in the cache. */
+	hash_bucket *bucket;
+
+	/* The directory entry used to get the current hash bucket. */
+	int bucket_dir;
+
+	/* Pointer to the current bucket's cache entry. */
+	cache_elem *cache_entry;
+
+
+	/* Bookkeeping of things that need to be written back at the
+	   end of an update. */
+	char  header_changed;
+	char  directory_changed;
+	char  bucket_changed;
+	char  second_changed;
+	
+      } gdbm_file_info;
+
+/* Now define all the routines in use. */
+#include "proto.h"
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmdelete.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmdelete.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmdelete.c	(revision 20131)
@@ -0,0 +1,119 @@
+/* gdbmdelete.c - Remove the key and its associated data from the database. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+
+/* Remove the KEYed item and the KEY from the database DBF.  The file on disk
+   is updated to reflect the structure of the new database before returning
+   from this procedure.  */
+
+int
+gdbm_delete (dbf, key)
+     gdbm_file_info *dbf;
+     datum key;
+{
+  int elem_loc;		/* The location in the current hash bucket. */
+  int last_loc;		/* Last location emptied by the delete.  */
+  int home;		/* Home position of an item. */
+  bucket_element elem;  /* The element to be deleted. */
+  char *find_data;	/* Return pointer from findkey. */
+  int   hash_val;	/* Returned by findkey. */
+  off_t free_adr;       /* Temporary stroage for address and size. */
+  int   free_size;
+
+  /* First check to make sure this guy is a writer. */
+  if (dbf->read_write == GDBM_READER)
+    {
+      gdbm_errno = GDBM_READER_CANT_DELETE;
+      return -1;
+    }
+
+  /* Initialize the gdbm_errno variable. */
+  gdbm_errno = GDBM_NO_ERROR;
+
+  /* Find the item. */
+  elem_loc = _gdbm_findkey (dbf, key, &find_data, &hash_val);
+  if (elem_loc == -1)
+    {
+      gdbm_errno = GDBM_ITEM_NOT_FOUND;
+      return -1;
+    }
+
+  /* Save the element.  */
+  elem = dbf->bucket->h_table[elem_loc];
+
+  /* Delete the element.  */
+  dbf->bucket->h_table[elem_loc].hash_value = -1;
+  dbf->bucket->count -= 1;
+
+  /* Move other elements to guarantee that they can be found. */
+  last_loc = elem_loc;
+  elem_loc = (elem_loc + 1) % dbf->header->bucket_elems;
+  while (elem_loc != last_loc
+	 && dbf->bucket->h_table[elem_loc].hash_value != -1)
+    {
+      home = dbf->bucket->h_table[elem_loc].hash_value
+	     % dbf->header->bucket_elems;
+      if ( (last_loc < elem_loc && (home <= last_loc || home > elem_loc))
+	  || (last_loc > elem_loc && home <= last_loc && home > elem_loc))
+	
+	{
+	  dbf->bucket->h_table[last_loc] = dbf->bucket->h_table[elem_loc];
+	  dbf->bucket->h_table[elem_loc].hash_value = -1;
+	  last_loc = elem_loc;
+	}
+      elem_loc = (elem_loc + 1) % dbf->header->bucket_elems;
+    }
+
+  /* Free the file space. */
+  free_adr = elem.data_pointer;
+  free_size = elem.key_size + elem.data_size;
+  _gdbm_free (dbf, free_adr, free_size);
+
+  /* Set the flags. */
+  dbf->bucket_changed = TRUE;
+
+  /* Clear out the data cache for the current bucket. */
+  if (dbf->cache_entry->ca_data.dptr != NULL)
+    {
+      free (dbf->cache_entry->ca_data.dptr);
+      dbf->cache_entry->ca_data.dptr = NULL;
+    }
+  dbf->cache_entry->ca_data.hash_val = -1;
+  dbf->cache_entry->ca_data.key_size = 0;
+  dbf->cache_entry->ca_data.elem_loc = -1;
+
+  /* Do the writes. */
+  _gdbm_end_update (dbf);
+  return 0;  
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmerrno.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmerrno.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmerrno.c	(revision 20131)
@@ -0,0 +1,64 @@
+/* gdbmerrno.c - convert gdbm errors into english. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the original author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+    The author of this file is:
+       e-mail:  downsj@downsj.com
+
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmerrno.h"
+
+/* this is not static so that applications may access the array if they
+   like. it must be in the same order as the error codes! */
+
+const char * const gdbm_errlist[] = {
+  "No error", "Malloc error", "Block size error", "File open error",
+  "File write error", "File seek error", "File read error",
+  "Bad magic number", "Empty database", "Can't be reader", "Can't be writer",
+  "Reader can't delete", "Reader can't store", "Reader can't reorganize",
+  "Unknown update", "Item not found", "Reorganize failed", "Cannot replace",
+  "Illegal data", "Option already set", "Illegal option"
+};
+
+#define gdbm_errorcount	((sizeof(gdbm_errlist) / sizeof(gdbm_errlist[0])) - 1)
+
+const char *
+gdbm_strerror(error)
+    gdbm_error error;
+{
+  if(((int)error < 0) || ((int)error > gdbm_errorcount))
+    {
+      return("Unknown error");
+    }
+  else
+    {
+      return(gdbm_errlist[(int)error]);
+    }
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmerrno.h
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmerrno.h	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmerrno.h	(revision 20131)
@@ -0,0 +1,55 @@
+/* gdbmerrno.h - The enumeration type describing all the dbm errors. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* gdbm sets the following error codes. */
+#define	GDBM_NO_ERROR		0
+#define	GDBM_MALLOC_ERROR	1
+#define	GDBM_BLOCK_SIZE_ERROR	2
+#define	GDBM_FILE_OPEN_ERROR	3
+#define	GDBM_FILE_WRITE_ERROR	4
+#define	GDBM_FILE_SEEK_ERROR	5
+#define	GDBM_FILE_READ_ERROR	6
+#define	GDBM_BAD_MAGIC_NUMBER	7
+#define	GDBM_EMPTY_DATABASE	8
+#define	GDBM_CANT_BE_READER	9
+#define	GDBM_CANT_BE_WRITER	10
+#define	GDBM_READER_CANT_DELETE	11
+#define	GDBM_READER_CANT_STORE	12
+#define	GDBM_READER_CANT_REORGANIZE	13
+#define	GDBM_UNKNOWN_UPDATE	14
+#define	GDBM_ITEM_NOT_FOUND	15
+#define	GDBM_REORGANIZE_FAILED	16
+#define	GDBM_CANNOT_REPLACE	17
+#define	GDBM_ILLEGAL_DATA	18
+#define	GDBM_OPT_ALREADY_SET	19
+#define	GDBM_OPT_ILLEGAL	20
+
+typedef int gdbm_error;		/* For compatibilities sake. */
+
+extern gdbm_error gdbm_errno;
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmexists.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmexists.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmexists.c	(revision 20131)
@@ -0,0 +1,51 @@
+/* gdbmexists.c - Check to see if a key exists */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 1, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the original author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+    The author of this file is:
+       e-mail:  downsj@downsj.com
+
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+
+/* this is nothing more than a wrapper around _gdbm_findkey(). the
+   point? it doesn't alloate any memory. */
+
+int
+gdbm_exists (dbf, key)
+    gdbm_file_info *dbf;
+    datum key;
+{
+  char *find_data;		/* dummy */
+  int hash_val;		/* dummy */
+
+  return (_gdbm_findkey (dbf, key, &find_data, &hash_val) >= 0);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmfdesc.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmfdesc.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmfdesc.c	(revision 20131)
@@ -0,0 +1,45 @@
+/* gdbfdesc.c - return the file descriptor associated with the database. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1999  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the original author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+    The author of this file is:
+       e-mail:  downsj@downsj.com
+
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+
+/* Return the file number of the DBF file. */
+
+int
+gdbm_fdesc(dbf)
+      gdbm_file_info	*dbf;
+{
+  return (dbf->desc);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmfetch.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmfetch.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmfetch.c	(revision 20131)
@@ -0,0 +1,76 @@
+/* gdbmfetch.c - Find a key and return the associated data.  */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+
+/* Look up a given KEY and return the information associated with that KEY.
+   The pointer in the structure that is  returned is a pointer to dynamically
+   allocated memory block.  */
+
+datum
+gdbm_fetch (dbf, key)
+     gdbm_file_info *dbf;
+     datum key;
+{
+  datum  return_val;		/* The return value. */
+  int    elem_loc;		/* The location in the bucket. */
+  char  *find_data;		/* Returned from find_key. */
+  int    hash_val;		/* Returned from find_key. */
+
+  /* Set the default return value. */
+  return_val.dptr  = NULL;
+  return_val.dsize = 0;
+
+  /* Initialize the gdbm_errno variable. */
+  gdbm_errno = GDBM_NO_ERROR;
+
+  /* Find the key and return a pointer to the data. */
+  elem_loc = _gdbm_findkey (dbf, key, &find_data, &hash_val);
+
+  /* Copy the data if the key was found.  */
+  if (elem_loc >= 0)
+    {
+      /* This is the item.  Return the associated data. */
+      return_val.dsize = dbf->bucket->h_table[elem_loc].data_size;
+      if (return_val.dsize == 0)
+	return_val.dptr = (char *) malloc (1);
+      else
+	return_val.dptr = (char *) malloc (return_val.dsize);
+      if (return_val.dptr == NULL) _gdbm_fatal (dbf, "malloc error");
+      bcopy (find_data, return_val.dptr, return_val.dsize);
+    }
+
+  /* Check for an error and return. */
+  if (return_val.dptr == NULL) gdbm_errno = GDBM_ITEM_NOT_FOUND;
+  return return_val;
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmopen.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmopen.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmopen.c	(revision 20131)
@@ -0,0 +1,522 @@
+/* gdbmopen.c - Open the dbm file and initialize data structures for use. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+
+#include "gsdlmods.h"
+
+
+/* Initialize dbm system.  FILE is a pointer to the file name.  If the file
+   has a size of zero bytes, a file initialization procedure is performed,
+   setting up the initial structure in the file.  BLOCK_SIZE is used during
+   initialization to determine the size of various constructs.  If the value
+   is less than 512, the file system blocksize is used, otherwise the value
+   of BLOCK_SIZE is used.  BLOCK_SIZE is ignored if the file has previously
+   initialized.  If FLAGS is set to GDBM_READ the user wants to just
+   read the database and any call to dbm_store or dbm_delete will fail. Many
+   readers can access the database at the same time.  If FLAGS is set to
+   GDBM_WRITE, the user wants both read and write access to the database and
+   requires exclusive access.  If FLAGS is GDBM_WRCREAT, the user wants
+   both read and write access to the database and if the database does not
+   exist, create a new one.  If FLAGS is GDBM_NEWDB, the user want a
+   new database created, regardless of whether one existed, and wants read
+   and write access to the new database.  Any error detected will cause a 
+   return value of null and an approprate value will be in gdbm_errno.  If
+   no errors occur, a pointer to the "gdbm file descriptor" will be
+   returned. */
+   
+
+gdbm_file_info *
+#ifdef MSDOS
+gdbm_open (file, block_size, flags, mode, fatal_func, need_filelock)
+#else
+gdbm_open (file, block_size, flags, mode, fatal_func)
+#endif
+     char *file;
+     int  block_size;
+     int  flags;
+     int  mode;
+     void (*fatal_func) ();
+#ifdef MSDOS
+     int need_filelock;
+#endif
+{
+  gdbm_file_info *dbf;		/* The record to return. */
+  struct stat file_stat;	/* Space for the stat information. */
+  int         len;		/* Length of the file name. */
+  int         num_bytes;	/* Used in reading and writing. */
+  off_t       file_pos;		/* Used with seeks. */
+  int	      lock_val;         /* Returned by the flock call. */
+  int	      file_block_size;	/* Block size to use for a new file. */
+  int 	      index;		/* Used as a loop index. */
+  char        need_trunc;	/* Used with GDBM_NEWDB and locking to avoid
+				   truncating a file from under a reader. */
+
+  /* Initialize the gdbm_errno variable. */
+  gdbm_errno = GDBM_NO_ERROR;
+
+  /* Allocate new info structure. */
+  dbf = (gdbm_file_info *) malloc (sizeof (gdbm_file_info));
+  if (dbf == NULL)
+    {
+      gdbm_errno = GDBM_MALLOC_ERROR;
+      return NULL;
+    }
+
+  /* Initialize some fields for known values.  This is done so gdbm_close
+     will work if called before allocating some structures. */
+#ifdef MSDOS
+  dbf->need_filelock = need_filelock;
+#endif
+  dbf->dir  = NULL;
+  dbf->bucket = NULL;
+  dbf->header = NULL;
+  dbf->bucket_cache = NULL;
+  dbf->cache_size = 0;
+  
+  /* Save name of file. */
+  len = strlen (file);
+  dbf->name = (char *) malloc (len + 1);
+  if (dbf->name == NULL)
+    {
+      free (dbf);
+      gdbm_errno = GDBM_MALLOC_ERROR;
+      return NULL;
+    }
+  strcpy (dbf->name, file);
+
+  /* Initialize the fatal error routine. */
+  dbf->fatal_err = fatal_func;
+
+  dbf->fast_write = TRUE;	/* Default to setting fast_write. */
+  dbf->file_locking = TRUE;	/* Default to doing file locking. */
+  dbf->central_free = FALSE;	/* Default to not using central_free. */
+  dbf->coalesce_blocks = FALSE; /* Default to not coalescing blocks. */
+
+  /* GDBM_FAST used to determine whethere or not we set fast_write. */
+  if (flags & GDBM_SYNC)
+    {
+      /* If GDBM_SYNC has been requested, don't do fast_write. */
+      dbf->fast_write = FALSE;
+    }
+  if (flags & GDBM_NOLOCK)
+    {
+      dbf->file_locking = FALSE;
+    }
+
+  /* Open the file. */
+  need_trunc = FALSE;
+  switch (flags & GDBM_OPENMASK)
+    {
+      case GDBM_READER:
+#ifdef MSDOS
+	dbf->desc = open (dbf->name, O_RDONLY|O_BINARY, 0);
+#else
+	dbf->desc = open (dbf->name, O_RDONLY, 0);
+#endif
+	break;
+
+      case GDBM_WRITER:
+#ifdef MSDOS
+	dbf->desc = open (dbf->name, O_RDWR|O_BINARY, 0);
+#else
+	dbf->desc = open (dbf->name, O_RDWR, 0);
+#endif
+	break;
+
+      case GDBM_NEWDB:
+#ifdef MSDOS
+	dbf->desc = open (dbf->name, O_RDWR|O_CREAT|O_BINARY, mode);
+#else
+	dbf->desc = open (dbf->name, O_RDWR|O_CREAT, mode);
+#endif
+	need_trunc = TRUE;
+	break;
+
+      default:
+#ifdef MSDOS
+	dbf->desc = open (dbf->name, O_RDWR|O_CREAT|O_BINARY, mode);
+#else
+	dbf->desc = open (dbf->name, O_RDWR|O_CREAT, mode);
+#endif
+	break;
+
+    }
+  if (dbf->desc < 0)
+    {
+      free (dbf->name);
+      free (dbf);
+      gdbm_errno = GDBM_FILE_OPEN_ERROR;
+      return NULL;
+    }
+
+  /* Get the status of the file. */
+  fstat (dbf->desc, &file_stat);
+
+  /* Lock the file in the approprate way. */
+  if ((flags & GDBM_OPENMASK) == GDBM_READER)
+    {
+      if (file_stat.st_size == 0)
+	{
+	  close (dbf->desc);
+	  free (dbf->name);
+	  free (dbf);
+	  gdbm_errno = GDBM_EMPTY_DATABASE;
+	  return NULL;
+	}
+      if (dbf->file_locking)
+	{
+	  /* Sets lock_val to 0 for success.  See systems.h. */
+#ifdef MSDOS
+	  if (dbf->need_filelock) {
+	    READLOCK_FILE(dbf);
+	  }
+	  else {
+	    lock_val = 0;
+	  }
+#else
+	  READLOCK_FILE(dbf);
+#endif
+	}
+    }
+  else if (dbf->file_locking)
+    {
+      /* Sets lock_val to 0 for success.  See systems.h. */
+#ifdef MSDOS
+      if (dbf->need_filelock) {
+	WRITELOCK_FILE(dbf);
+      }
+      else {
+	lock_val = 0;
+      }
+#else
+      WRITELOCK_FILE(dbf);
+#endif
+    }
+  if (dbf->file_locking && (lock_val != 0))
+    {
+      close (dbf->desc);
+      free (dbf->name);
+      free (dbf);
+      if ((flags & GDBM_OPENMASK) == GDBM_READER)
+	gdbm_errno = GDBM_CANT_BE_READER;
+      else
+	gdbm_errno = GDBM_CANT_BE_WRITER;
+      return NULL;
+    }
+
+  /* Record the kind of user. */
+  dbf->read_write = (flags & GDBM_OPENMASK);
+
+  /* If we do have a write lock and it was a GDBM_NEWDB, it is 
+     now time to truncate the file. */
+  if (need_trunc && file_stat.st_size != 0)
+    {
+      TRUNCATE (dbf);
+      fstat (dbf->desc, &file_stat);
+    }
+
+  /* Decide if this is a new file or an old file. */
+  if (file_stat.st_size == 0)
+    {
+
+      /* This is a new file.  Create an empty database.  */
+
+      /* Start with the blocksize. */
+      if (block_size < 512)
+	file_block_size = STATBLKSIZE;
+      else
+	file_block_size = block_size;
+
+      /* Get space for the file header. */
+      dbf->header = (gdbm_file_header *) malloc (file_block_size);
+      if (dbf->header == NULL)
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_MALLOC_ERROR;
+	  return NULL;
+	}
+
+      /* Set the magic number and the block_size. */
+      dbf->header->header_magic = 0x13579ace;
+      dbf->header->block_size = file_block_size;
+     
+      /* Create the initial hash table directory.  */
+      dbf->header->dir_size = 8 * sizeof (off_t);
+      dbf->header->dir_bits = 3;
+      while (dbf->header->dir_size < dbf->header->block_size)
+	{
+	  dbf->header->dir_size <<= 1;
+	  dbf->header->dir_bits += 1;
+	}
+
+      /* Check for correct block_size. */
+      if (dbf->header->dir_size != dbf->header->block_size)
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_BLOCK_SIZE_ERROR;
+	  return NULL;
+	}
+
+      /* Allocate the space for the directory. */
+      dbf->dir = (off_t *) malloc (dbf->header->dir_size);
+      if (dbf->dir == NULL)
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_MALLOC_ERROR;
+	  return NULL;
+	}
+      dbf->header->dir = dbf->header->block_size;
+
+      /* Create the first and only hash bucket. */
+      dbf->header->bucket_elems =
+	(dbf->header->block_size - sizeof (hash_bucket))
+	/ sizeof (bucket_element) + 1;
+      dbf->header->bucket_size  = dbf->header->block_size;
+      dbf->bucket = (hash_bucket *) malloc (dbf->header->bucket_size);
+      if (dbf->bucket == NULL)
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_MALLOC_ERROR;
+	  return NULL;
+	}
+      _gdbm_new_bucket (dbf, dbf->bucket, 0);
+      dbf->bucket->av_count = 1;
+      dbf->bucket->bucket_avail[0].av_adr = 3*dbf->header->block_size;
+      dbf->bucket->bucket_avail[0].av_size = dbf->header->block_size;
+
+      /* Set table entries to point to hash buckets. */
+      for (index = 0; index < dbf->header->dir_size / sizeof (off_t); index++)
+	dbf->dir[index] = 2*dbf->header->block_size;
+
+      /* Initialize the active avail block. */
+      dbf->header->avail.size
+	= ( (dbf->header->block_size - sizeof (gdbm_file_header))
+	 / sizeof (avail_elem)) + 1;
+      dbf->header->avail.count = 0;
+      dbf->header->avail.next_block = 0;
+      dbf->header->next_block  = 4*dbf->header->block_size;
+
+      /* Write initial configuration to the file. */
+      /* Block 0 is the file header and active avail block. */
+      num_bytes = write (dbf->desc, dbf->header, dbf->header->block_size);
+      if (num_bytes != dbf->header->block_size)
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_FILE_WRITE_ERROR;
+	  return NULL;
+	}
+
+      /* Block 1 is the initial bucket directory. */
+      num_bytes = write (dbf->desc, dbf->dir, dbf->header->dir_size);
+      if (num_bytes != dbf->header->dir_size)
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_FILE_WRITE_ERROR;
+	  return NULL;
+	}
+
+      /* Block 2 is the only bucket. */
+      num_bytes = write (dbf->desc, dbf->bucket, dbf->header->bucket_size);
+      if (num_bytes != dbf->header->bucket_size)
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_FILE_WRITE_ERROR;
+	  return NULL;
+	}
+
+      /* Wait for initial configuration to be written to disk. */
+      fsync (dbf->desc);
+
+      free (dbf->bucket);
+    }
+  else
+    {
+      /* This is an old database.  Read in the information from the file
+	 header and initialize the hash directory. */
+
+      gdbm_file_header partial_header;  /* For the first part of it. */
+
+      /* Read the partial file header. */
+      num_bytes = read (dbf->desc, &partial_header, sizeof (gdbm_file_header));
+      if (num_bytes != sizeof (gdbm_file_header))
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_FILE_READ_ERROR;
+	  return NULL;
+	}
+
+      // GREENSTONE CUSTOMISATION: Check if the magic number is reversed
+      // If it is then the GDBM file is the wrong endianness for the current machine
+      wrong_endianness = (partial_header.header_magic == 0xCE9A5713);
+
+      // GREENSTONE CUSTOMISATION: Swap each value in the partial header if the GDBM file is the wrong endianness
+      if (wrong_endianness)
+      {
+	endian_swap_array((int*) &partial_header, sizeof (gdbm_file_header));
+      }
+
+      /* Is the magic number good? */
+      if (partial_header.header_magic != 0x13579ace)
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_BAD_MAGIC_NUMBER;
+	  return NULL;
+	}
+
+      /* GREENSTONE CUSTOMISATION: Debugging output
+      printf("\n");
+      printf("Header magic: %x\n", partial_header.header_magic);
+      printf("Block size: %d\n", partial_header.block_size);
+      printf("Dir: %d\n", partial_header.dir);
+      printf("Dir size: %d\n", partial_header.dir_size);
+      printf("Dir bits: %d\n", partial_header.dir_bits);
+      printf("Bucket size: %d\n", partial_header.bucket_size);
+      printf("Bucket elems: %d\n", partial_header.bucket_elems);
+      printf("Next block: %d\n", partial_header.next_block);
+      printf("\n");
+      */
+
+      /* It is a good database, read the entire header. */
+      dbf->header = (gdbm_file_header *) malloc (partial_header.block_size);
+      if (dbf->header == NULL)
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_MALLOC_ERROR;
+	  return NULL;
+	}
+      bcopy (&partial_header, dbf->header, sizeof (gdbm_file_header));
+      num_bytes = read (dbf->desc, &dbf->header->avail.av_table[1],
+			dbf->header->block_size-sizeof (gdbm_file_header));
+
+      // GREENSTONE CUSTOMISATION: Swap each value in the header if the GDBM file is the wrong endianness
+      if (wrong_endianness)
+      {
+	endian_swap_array((int*) &dbf->header->avail.av_table[1],
+			  dbf->header->block_size-sizeof(gdbm_file_header));
+      }
+
+      if (num_bytes != dbf->header->block_size-sizeof (gdbm_file_header))
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_FILE_READ_ERROR;
+	  return NULL;
+	}
+	
+      /* Allocate space for the hash table directory.  */
+      dbf->dir = (off_t *) malloc (dbf->header->dir_size);
+      if (dbf->dir == NULL)
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_MALLOC_ERROR;
+	  return NULL;
+	}
+
+      /* Read the hash table directory. */
+      file_pos = lseek (dbf->desc, dbf->header->dir, L_SET);
+      if (file_pos != dbf->header->dir)
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_FILE_SEEK_ERROR;
+	  return NULL;
+	}
+
+      num_bytes = read (dbf->desc, dbf->dir, dbf->header->dir_size);
+      if (num_bytes != dbf->header->dir_size)
+	{
+	  gdbm_close (dbf);
+	  gdbm_errno = GDBM_FILE_READ_ERROR;
+	  return NULL;
+	}
+
+      // GREENSTONE CUSTOMISATION: Swap each value in the directory if the GDBM file is the wrong endianness
+      if (wrong_endianness)
+      {
+	endian_swap_array((int*) dbf->dir, dbf->header->dir_size);
+      }
+    }
+
+  /* Finish initializing dbf. */
+  dbf->last_read = -1;
+  dbf->bucket = NULL;
+  dbf->bucket_dir = 0;
+  dbf->cache_entry = NULL;
+  dbf->header_changed = FALSE;
+  dbf->directory_changed = FALSE;
+  dbf->bucket_changed = FALSE;
+  dbf->second_changed = FALSE;
+  
+  /* Everything is fine, return the pointer to the file
+     information structure.  */
+  return dbf;
+
+}
+
+/* initialize the bucket cache. */
+int
+_gdbm_init_cache(dbf, size)
+    gdbm_file_info *dbf;
+    int size;
+{
+register int index;
+
+  if (dbf->bucket_cache == NULL)
+    {
+      dbf->bucket_cache = (cache_elem *) malloc(sizeof(cache_elem) * size);
+      if(dbf->bucket_cache == NULL)
+        {
+          gdbm_errno = GDBM_MALLOC_ERROR;
+          return(-1);
+        }
+      dbf->cache_size = size;
+
+      for(index = 0; index < size; index++)
+        {
+          (dbf->bucket_cache[index]).ca_bucket
+            = (hash_bucket *) malloc (dbf->header->bucket_size);
+          if ((dbf->bucket_cache[index]).ca_bucket == NULL)
+	    {
+              gdbm_errno = GDBM_MALLOC_ERROR;
+	      return(-1);
+            }
+          (dbf->bucket_cache[index]).ca_adr = 0;
+          (dbf->bucket_cache[index]).ca_changed = FALSE;
+          (dbf->bucket_cache[index]).ca_data.hash_val = -1;
+          (dbf->bucket_cache[index]).ca_data.elem_loc = -1;
+          (dbf->bucket_cache[index]).ca_data.dptr = NULL;
+        }
+      dbf->bucket = dbf->bucket_cache[0].ca_bucket;
+      dbf->cache_entry = &dbf->bucket_cache[0];
+    }
+  return(0);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmreorg.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmreorg.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmreorg.c	(revision 20131)
@@ -0,0 +1,231 @@
+/* gdbmreorg.c - Reorganize the database file. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+#include "extern.h"
+
+#if !HAVE_RENAME
+
+/* Rename takes OLD_NAME and renames it as NEW_NAME.  If it can not rename
+   the file a non-zero value is returned.  OLD_NAME is guaranteed to
+   remain if it can't be renamed. It assumes NEW_NAME always exists (due
+   to being used in gdbm). */
+
+static int
+_gdbm_rename (old_name, new_name)
+     char* old_name;
+     char* new_name;
+{
+  if (unlink (new_name) != 0)   
+    return -1;
+
+  if (link (old_name, new_name) != 0)
+    return -1;
+  
+  unlink (old_name);
+  return 0;
+
+}
+
+#define rename _gdbm_rename
+#endif
+
+
+
+/* Reorganize the database.  This requires creating a new file and inserting
+   all the elements in the old file DBF into the new file.  The new file
+   is then renamed to the same name as the old file and DBF is updated to
+   contain all the correct information about the new file.  If an error
+   is detected, the return value is negative.  The value zero is returned
+   after a successful reorganization. */
+
+int
+gdbm_reorganize (dbf)
+     gdbm_file_info *dbf;
+
+{
+  gdbm_file_info *new_dbf;		/* The new file. */
+  char *new_name;			/* A temporary name. */
+  int  len;				/* Used in new_name construction. */
+  datum key, nextkey, data;		/* For the sequential sweep. */
+  struct stat fileinfo;			/* Information about the file. */
+  int  index;				/* Use in moving the bucket cache. */
+
+
+  /* Readers can not reorganize! */
+  if (dbf->read_write == GDBM_READER)
+    {
+      gdbm_errno = GDBM_READER_CANT_REORGANIZE;
+      return -1;
+    }
+  
+  /* Initialize the gdbm_errno variable. */
+  gdbm_errno = GDBM_NO_ERROR;
+
+  /* Construct new name for temporary file. */
+  len = strlen (dbf->name);
+  new_name = (char *) malloc (len + 3);
+  if (new_name == NULL)
+    {
+      gdbm_errno = GDBM_MALLOC_ERROR;
+      return -1;
+    }
+  strcpy (&new_name[0], dbf->name);
+  new_name[len+2] = 0;
+  new_name[len+1] = '#';
+  while ( (len > 0) && new_name[len-1] != '/')
+    {
+      new_name[len] = new_name[len-1];
+      len -= 1;
+    }
+  new_name[len] = '#';
+
+  /* Get the mode for the old file and open the new database. */
+  fstat (dbf->desc, &fileinfo);
+  new_dbf = gdbm_open (new_name, dbf->header->block_size, GDBM_WRCREAT,
+		       fileinfo.st_mode, dbf->fatal_err);
+
+  if (new_dbf == NULL)
+    {
+      free (new_name);
+      gdbm_errno = GDBM_REORGANIZE_FAILED;
+      return -1;
+    }
+
+  
+  /* For each item in the old database, add an entry in the new. */
+  key = gdbm_firstkey (dbf);
+
+  while (key.dptr != NULL)
+    {
+      data = gdbm_fetch (dbf, key);
+      if (data.dptr != NULL)
+ 	{
+	  /* Add the data to the new file. */
+	  if (gdbm_store (new_dbf, key, data, GDBM_INSERT) != 0)
+	    {
+	      gdbm_close (new_dbf);
+	      gdbm_errno = GDBM_REORGANIZE_FAILED;
+	      unlink (new_name);
+	      free (new_name);
+	      return -1;
+	    }
+ 	}
+      else
+ 	{
+	  /* ERROR! Abort and don't finish reorganize. */
+	  gdbm_close (new_dbf);
+	  gdbm_errno = GDBM_REORGANIZE_FAILED;
+	  unlink (new_name);
+	  free (new_name);
+	  return -1;
+ 	}
+      nextkey = gdbm_nextkey (dbf, key);
+      free (key.dptr);
+      free (data.dptr);
+      key = nextkey;
+    }
+
+  /* Write everything. */
+  _gdbm_end_update (new_dbf);
+  gdbm_sync (new_dbf);
+
+
+  /* Move the new file to old name. */
+
+#ifdef MSDOS
+  if (close (new_dbf->desc)
+      || unlink (dbf->name)
+      || rename (new_name, dbf->name)
+      || (new_dbf->desc = open (dbf->name, O_RDWR|O_BINARY)) < 0)
+#else /* not MSDOS */
+  if (rename (new_name, dbf->name) != 0)
+#endif /* not MSDOS */
+    {
+      gdbm_errno = GDBM_REORGANIZE_FAILED;
+      gdbm_close (new_dbf);
+      free (new_name);
+      return -1;
+    }
+
+  /* Fix up DBF to have the correct information for the new file. */
+  if (dbf->file_locking)
+    {
+#ifdef MSDOS
+      if (dbf->need_filelock) {
+	UNLOCK_FILE(dbf);
+      }
+#else
+      UNLOCK_FILE(dbf);
+#endif
+    }
+  close (dbf->desc);
+  free (dbf->header);
+  free (dbf->dir);
+
+  if (dbf->bucket_cache != NULL) {
+    for (index = 0; index < dbf->cache_size; index++) {
+      if (dbf->bucket_cache[index].ca_bucket != NULL)
+	free (dbf->bucket_cache[index].ca_bucket);
+      if (dbf->bucket_cache[index].ca_data.dptr != NULL)
+	free (dbf->bucket_cache[index].ca_data.dptr);
+    }
+    free (dbf->bucket_cache);
+  }
+
+  dbf->desc           = new_dbf->desc;
+  dbf->header         = new_dbf->header;
+  dbf->dir            = new_dbf->dir;
+  dbf->bucket         = new_dbf->bucket;
+  dbf->bucket_dir     = new_dbf->bucket_dir;
+  dbf->last_read      = new_dbf->last_read;
+  dbf->bucket_cache   = new_dbf->bucket_cache;
+  dbf->cache_size     = new_dbf->cache_size;
+  dbf->header_changed    = new_dbf->header_changed;
+  dbf->directory_changed = new_dbf->directory_changed;
+  dbf->bucket_changed    = new_dbf->bucket_changed;
+  dbf->second_changed    = new_dbf->second_changed;
+   
+  free (new_dbf->name);   
+  free (new_dbf);
+  free (new_name);
+
+  /* Make sure the new database is all on disk. */
+  fsync (dbf->desc);
+
+  /* Force the right stuff for a correct bucket cache. */
+  dbf->cache_entry    = &dbf->bucket_cache[0];
+  _gdbm_get_bucket (dbf, 0);
+
+  return 0;
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmseq.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmseq.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmseq.c	(revision 20131)
@@ -0,0 +1,146 @@
+/* gdbmseq.c - Routines to visit all keys.  Not in sorted order. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+
+/* Special extern for this file. */
+extern char *_gdbm_read_entry __P((gdbm_file_info *, int));
+
+
+/* Find and read the next entry in the hash structure for DBF starting
+   at ELEM_LOC of the current bucket and using RETURN_VAL as the place to
+   put the data that is found. */
+
+static void
+get_next_key (dbf, elem_loc, return_val)
+     gdbm_file_info *dbf;
+     int elem_loc;
+     datum *return_val;
+{
+  int   found;			/* Have we found the next key. */
+  char  *find_data;		/* Data pointer returned by find_key. */
+
+  /* Find the next key. */
+  found = FALSE;
+  while (!found)
+    {
+      /* Advance to the next location in the bucket. */
+      elem_loc++;
+      if (elem_loc == dbf->header->bucket_elems)
+	{
+	  /* We have finished the current bucket, get the next bucket.  */
+	  elem_loc = 0;
+
+	  /* Find the next bucket.  It is possible several entries in
+	     the bucket directory point to the same bucket. */
+	  while (dbf->bucket_dir < dbf->header->dir_size / sizeof (off_t)
+		 && dbf->cache_entry->ca_adr == dbf->dir[dbf->bucket_dir])
+	    dbf->bucket_dir++;
+
+	  /* Check to see if there was a next bucket. */
+	  if (dbf->bucket_dir < dbf->header->dir_size / sizeof (off_t))
+	    _gdbm_get_bucket (dbf, dbf->bucket_dir);	      
+	  else
+	    /* No next key, just return. */
+	    return ;
+	}
+      found = dbf->bucket->h_table[elem_loc].hash_value != -1;
+    }
+  
+  /* Found the next key, read it into return_val. */
+  find_data = _gdbm_read_entry (dbf, elem_loc);
+  return_val->dsize = dbf->bucket->h_table[elem_loc].key_size;
+  if (return_val->dsize == 0)
+    return_val->dptr = (char *) malloc (1);
+  else
+    return_val->dptr = (char *) malloc (return_val->dsize);
+  if (return_val->dptr == NULL) _gdbm_fatal (dbf, "malloc error");
+  bcopy (find_data, return_val->dptr, return_val->dsize);
+}
+
+
+/* Start the visit of all keys in the database.  This produces something in
+   hash order, not in any sorted order.  */
+
+datum
+gdbm_firstkey (dbf)
+     gdbm_file_info *dbf;
+{
+  datum return_val;		/* To return the first key. */
+
+  /* Set the default return value for not finding a first entry. */
+  return_val.dptr = NULL;
+
+  /* Initialize the gdbm_errno variable. */
+  gdbm_errno = GDBM_NO_ERROR;
+
+  /* Get the first bucket.  */
+  _gdbm_get_bucket (dbf, 0);
+
+  /* Look for first entry. */
+  get_next_key (dbf, -1, &return_val);
+
+  return return_val;
+}
+
+
+/* Continue visiting all keys.  The next key following KEY is returned. */
+
+datum
+gdbm_nextkey (dbf, key)
+     gdbm_file_info *dbf;
+     datum key;
+{
+  datum  return_val;		/* The return value. */
+  int    elem_loc;		/* The location in the bucket. */
+  char  *find_data;		/* Data pointer returned by _gdbm_findkey. */
+  int    hash_val;		/* Returned by _gdbm_findkey. */
+
+  /* Initialize the gdbm_errno variable. */
+  gdbm_errno = GDBM_NO_ERROR;
+
+  /* Set the default return value for no next entry. */
+  return_val.dptr = NULL;
+
+  /* Do we have a valid key? */
+  if (key.dptr == NULL) return return_val;
+
+  /* Find the key.  */
+  elem_loc = _gdbm_findkey (dbf, key, &find_data, &hash_val);
+  if (elem_loc == -1) return return_val;
+
+  /* Find the next key. */  
+  get_next_key (dbf, elem_loc, &return_val);
+
+  return return_val;
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmsetopt.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmsetopt.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmsetopt.c	(revision 20131)
@@ -0,0 +1,111 @@
+/* gdbmsetopt.c - set options pertaining to a GDBM descriptor. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1993, 1994  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the original author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+    The author of this file is:
+       e-mail:  downsj@downsj.com
+
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+
+/* operate on an already open descriptor. */
+
+/* ARGSUSED */
+int
+gdbm_setopt(dbf, optflag, optval, optlen)
+    gdbm_file_info *dbf;	/* descriptor to operate on. */
+    int optflag;		/* option to set. */
+    int *optval;		/* pointer to option value. */
+    int optlen;			/* size of optval. */
+{
+  switch(optflag)
+    {
+      case GDBM_CACHESIZE:
+        /* Optval will point to the new size of the cache. */
+        if (dbf->bucket_cache != NULL)
+          {
+            gdbm_errno = GDBM_OPT_ALREADY_SET;
+            return(-1);
+          }
+
+        return(_gdbm_init_cache(dbf, ((*optval) > 9) ? (*optval) : 10));
+
+      case GDBM_FASTMODE:
+      	/* Obsolete form of SYNCMODE. */
+	if ((*optval != TRUE) && (*optval != FALSE))
+	  {
+	    gdbm_errno = GDBM_OPT_ILLEGAL;
+	    return(-1);
+	  }
+
+	dbf->fast_write = *optval;
+	break;
+
+      case GDBM_SYNCMODE:
+      	/* Optval will point to either true or false. */
+	if ((*optval != TRUE) && (*optval != FALSE))
+	  {
+	    gdbm_errno = GDBM_OPT_ILLEGAL;
+	    return(-1);
+	  }
+
+	dbf->fast_write = !(*optval);
+	break;
+
+      case GDBM_CENTFREE:
+      	/* Optval will point to either true or false. */
+	if ((*optval != TRUE) && (*optval != FALSE))
+	  {
+	    gdbm_errno = GDBM_OPT_ILLEGAL;
+	    return(-1);
+	  }
+
+	dbf->fast_write = *optval;
+	break;
+
+      case GDBM_COALESCEBLKS:
+      	/* Optval will point to either true or false. */
+	if ((*optval != TRUE) && (*optval != FALSE))
+	  {
+	    gdbm_errno = GDBM_OPT_ILLEGAL;
+	    return(-1);
+	  }
+
+	dbf->fast_write = *optval;
+	break;
+
+      default:
+        gdbm_errno = GDBM_OPT_ILLEGAL;
+        return(-1);
+    }
+
+  return(0);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmstore.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmstore.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmstore.c	(revision 20131)
@@ -0,0 +1,170 @@
+/* gdbmstore.c - Add a new key/data pair to the database. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+
+
+/* Add a new element to the database.  CONTENT is keyed by KEY.  The
+   file on disk is updated to reflect the structure of the new database
+   before returning from this procedure.  The FLAGS define the action to
+   take when the KEY is already in the database.  The value GDBM_REPLACE
+   asks that the old data be replaced by the new CONTENT.  The value
+   GDBM_INSERT asks that an error be returned and no action taken.  A
+   return value of 0 means no errors.  A return value of -1 means that
+   the item was not stored in the data base because the caller was not an
+   official writer. A return value of 0 means that the item was not stored
+   because the argument FLAGS was GDBM_INSERT and the KEY was already in
+   the database. */
+
+int
+gdbm_store (dbf, key, content, flags)
+     gdbm_file_info *dbf;
+     datum key;
+     datum content;
+     int flags;
+{
+  int  new_hash_val;		/* The new hash value. */
+  int  elem_loc;		/* The location in hash bucket. */
+  off_t file_adr;		/* The address of new space in the file.  */
+  off_t file_pos;		/* The position after a lseek. */
+  int  num_bytes;		/* Used for error detection. */
+  off_t free_adr;		/* For keeping track of a freed section. */
+  int  free_size;
+  int   new_size;		/* Used in allocating space. */
+  char *temp;			/* Used in _gdbm_findkey call. */
+
+
+  /* First check to make sure this guy is a writer. */
+  if (dbf->read_write == GDBM_READER)
+    {
+      gdbm_errno = GDBM_READER_CANT_STORE;
+      return -1;
+    }
+
+  /* Check for illegal data values.  A NULL dptr field is illegal because
+     NULL dptr returned by a lookup procedure indicates an error. */
+  if ((key.dptr == NULL) || (content.dptr == NULL))
+    {
+      gdbm_errno = GDBM_ILLEGAL_DATA;
+      return -1;
+    }
+
+  /* Initialize the gdbm_errno variable. */
+  gdbm_errno = GDBM_NO_ERROR;
+
+  /* Look for the key in the file.
+     A side effect loads the correct bucket and calculates the hash value. */
+  elem_loc = _gdbm_findkey (dbf, key, &temp, &new_hash_val);
+
+  /* Initialize these. */
+  file_adr = 0;
+  new_size = key.dsize + content.dsize;
+
+  /* Did we find the item? */
+  if (elem_loc != -1)
+    {
+      if (flags == GDBM_REPLACE)
+	{
+	  /* Just replace the data. */
+	  free_adr = dbf->bucket->h_table[elem_loc].data_pointer;
+	  free_size = dbf->bucket->h_table[elem_loc].key_size
+	              + dbf->bucket->h_table[elem_loc].data_size;
+	  if (free_size != new_size)
+	    {
+	      _gdbm_free (dbf, free_adr, free_size);
+	    }
+	  else
+	    {
+	      /* Just reuse the same address! */
+	      file_adr = free_adr;
+	    }
+	}
+      else
+	{
+	  gdbm_errno = GDBM_CANNOT_REPLACE;
+	  return 1;
+	}
+    }
+
+
+  /* Get the file address for the new space.
+     (Current bucket's free space is first place to look.) */
+  if (file_adr == 0)
+    {
+      file_adr = _gdbm_alloc (dbf, new_size);
+    }
+
+  /* If this is a new entry in the bucket, we need to do special things. */
+  if (elem_loc == -1)
+    {
+      if (dbf->bucket->count == dbf->header->bucket_elems)
+	{
+	  /* Split the current bucket. */
+	  _gdbm_split_bucket (dbf, new_hash_val);
+	}
+      
+      /* Find space to insert into bucket and set elem_loc to that place. */
+      elem_loc = new_hash_val % dbf->header->bucket_elems;
+      while (dbf->bucket->h_table[elem_loc].hash_value != -1)
+	{  elem_loc = (elem_loc + 1) % dbf->header->bucket_elems; }
+
+      /* We now have another element in the bucket.  Add the new information.*/
+      dbf->bucket->count += 1;
+      dbf->bucket->h_table[elem_loc].hash_value = new_hash_val;
+      bcopy (key.dptr, dbf->bucket->h_table[elem_loc].key_start,
+	     (SMALL < key.dsize ? SMALL : key.dsize));
+    }
+
+
+  /* Update current bucket data pointer and sizes. */
+  dbf->bucket->h_table[elem_loc].data_pointer = file_adr;
+  dbf->bucket->h_table[elem_loc].key_size = key.dsize;
+  dbf->bucket->h_table[elem_loc].data_size = content.dsize;
+
+  /* Write the data to the file. */
+  file_pos = lseek (dbf->desc, file_adr, L_SET);
+  if (file_pos != file_adr) _gdbm_fatal (dbf, "lseek error");
+  num_bytes = write (dbf->desc, key.dptr, key.dsize);
+  if (num_bytes != key.dsize) _gdbm_fatal (dbf, "write error");
+  num_bytes = write (dbf->desc, content.dptr, content.dsize);
+  if (num_bytes != content.dsize) _gdbm_fatal (dbf, "write error");
+
+  /* Current bucket has changed. */
+  dbf->cache_entry->ca_changed = TRUE;
+  dbf->bucket_changed = TRUE;
+
+  /* Write everything that is needed to the disk. */
+  _gdbm_end_update (dbf);
+  return 0;
+  
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmsync.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmsync.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gdbmsync.c	(revision 20131)
@@ -0,0 +1,49 @@
+/* gdbmsync.c - Sync the disk with the in memory state. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+
+/* Make sure the database is all on disk. */
+
+void
+gdbm_sync (dbf)
+     gdbm_file_info *dbf;
+{
+
+  /* Initialize the gdbm_errno variable. */
+  gdbm_errno = GDBM_NO_ERROR;
+
+  /* Do the sync on the file. */
+  fsync (dbf->desc);
+
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/getopt.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/getopt.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/getopt.c	(revision 20131)
@@ -0,0 +1,734 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
+   before changing it!
+
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
+   	Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+/* NOTE!!!  AIX requires this to be the first thing in the file.
+   Do not put ANYTHING before it!  */
+#if !defined (__GNUC__) && defined (_AIX)
+ #pragma alloca
+#endif
+
+#include "autoconf.h"
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not __GNUC__ */
+#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__))))
+#include <alloca.h>
+#else
+#ifndef _AIX
+char *alloca ();
+#endif
+#endif /* alloca.h */
+#endif /* not __GNUC__ */
+
+#if !__STDC__ && !defined(const) && IN_GCC
+#define const
+#endif
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef	__GNU_LIBRARY__
+#undef	alloca
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+#include <stdlib.h>
+#else	/* Not GNU C library.  */
+#define	__alloca	alloca
+#endif	/* GNU C library.  */
+
+/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
+   long-named option.  Because this is not POSIX.2 compliant, it is
+   being phased out.  */
+/* #define GETOPT_COMPAT */
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg = 0;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* XXX 1003.2 says this must be 1 before any call.  */
+int optind = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+
+#ifdef	__GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+#include <string.h>
+#define	my_index	strchr
+#define	my_bcopy(src, dst, n)	memcpy ((dst), (src), (n))
+#else
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+char *getenv ();
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+	return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+static void
+my_bcopy (from, to, size)
+     const char *from;
+     char *to;
+     int size;
+{
+  int i;
+  for (i = 0; i < size; i++)
+    to[i] = from[i];
+}
+#endif				/* GNU C library.  */
+
+
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
+  char **temp = (char **) __alloca (nonopts_size);
+
+  /* Interchange the two blocks of data in ARGV.  */
+
+  my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
+  my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
+	    (optind - last_nonopt) * sizeof (char *));
+  my_bcopy ((char *) temp,
+	    (char *) &argv[first_nonopt + optind - last_nonopt],
+	    nonopts_size);
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns `EOF'.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  int option_index;
+
+  optarg = 0;
+
+  /* Initialize the internal data when the first call is made.
+     Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  if (optind == 0)
+    {
+      first_nonopt = last_nonopt = optind = 1;
+
+      nextchar = NULL;
+
+      /* Determine how to handle the ordering of options and nonoptions.  */
+
+      if (optstring[0] == '-')
+	{
+	  ordering = RETURN_IN_ORDER;
+	  ++optstring;
+	}
+      else if (optstring[0] == '+')
+	{
+	  ordering = REQUIRE_ORDER;
+	  ++optstring;
+	}
+      else if (getenv ("POSIXLY_CORRECT") != NULL)
+	ordering = REQUIRE_ORDER;
+      else
+	ordering = PERMUTE;
+    }
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      if (ordering == PERMUTE)
+	{
+	  /* If we have just processed some options following some non-options,
+	     exchange them so that the options come first.  */
+
+	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+	    exchange ((char **) argv);
+	  else if (last_nonopt != optind)
+	    first_nonopt = optind;
+
+	  /* Now skip any additional non-options
+	     and extend the range of non-options previously skipped.  */
+
+	  while (optind < argc
+		 && (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+		 && (longopts == NULL
+		     || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif				/* GETOPT_COMPAT */
+		 )
+	    optind++;
+	  last_nonopt = optind;
+	}
+
+      /* Special ARGV-element `--' means premature end of options.
+	 Skip it like a null option,
+	 then exchange with previous non-options as if it were an option,
+	 then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+	{
+	  optind++;
+
+	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+	    exchange ((char **) argv);
+	  else if (first_nonopt == last_nonopt)
+	    first_nonopt = optind;
+	  last_nonopt = argc;
+
+	  optind = argc;
+	}
+
+      /* If we have done all the ARGV-elements, stop the scan
+	 and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+	{
+	  /* Set the next-arg-index to point at the non-options
+	     that we previously skipped, so the caller will digest them.  */
+	  if (first_nonopt != last_nonopt)
+	    optind = first_nonopt;
+	  return EOF;
+	}
+
+      /* If we have come to a non-option and did not permute it,
+	 either stop the scan or describe it to the caller and pass it by.  */
+
+      if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+	  && (longopts == NULL
+	      || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif				/* GETOPT_COMPAT */
+	  )
+	{
+	  if (ordering == REQUIRE_ORDER)
+	    return EOF;
+	  optarg = argv[optind++];
+	  return 1;
+	}
+
+      /* We have found another option-ARGV-element.
+	 Start decoding its characters.  */
+
+      nextchar = (argv[optind] + 1
+		  + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  if (longopts != NULL
+      && ((argv[optind][0] == '-'
+	   && (argv[optind][1] == '-' || long_only))
+#ifdef GETOPT_COMPAT
+	  || argv[optind][0] == '+'
+#endif				/* GETOPT_COMPAT */
+	  ))
+    {
+      const struct option *p;
+      char *s = nextchar;
+      int exact = 0;
+      int ambig = 0;
+      const struct option *pfound = NULL;
+      int indfound;
+
+      while (*s && *s != '=')
+	s++;
+
+      /* Test all options for either exact match or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name;
+	   p++, option_index++)
+	if (!strncmp (p->name, nextchar, s - nextchar))
+	  {
+	    if (s - nextchar == strlen (p->name))
+	      {
+		/* Exact match found.  */
+		pfound = p;
+		indfound = option_index;
+		exact = 1;
+		break;
+	      }
+	    else if (pfound == NULL)
+	      {
+		/* First nonexact match found.  */
+		pfound = p;
+		indfound = option_index;
+	      }
+	    else
+	      /* Second nonexact match found.  */
+	      ambig = 1;
+	  }
+
+      if (ambig && !exact)
+	{
+	  if (opterr)
+	    fprintf (stderr, "%s: option `%s' is ambiguous\n",
+		     argv[0], argv[optind]);
+	  nextchar += strlen (nextchar);
+	  optind++;
+	  return '?';
+	}
+
+      if (pfound != NULL)
+	{
+	  option_index = indfound;
+	  optind++;
+	  if (*s)
+	    {
+	      /* Don't test has_arg with >, because some C compilers don't
+		 allow it to be used on enums.  */
+	      if (pfound->has_arg)
+		optarg = s + 1;
+	      else
+		{
+		  if (opterr)
+		    {
+		      if (argv[optind - 1][1] == '-')
+			/* --option */
+			fprintf (stderr,
+				 "%s: option `--%s' doesn't allow an argument\n",
+				 argv[0], pfound->name);
+		      else
+			/* +option or -option */
+			fprintf (stderr,
+			     "%s: option `%c%s' doesn't allow an argument\n",
+			     argv[0], argv[optind - 1][0], pfound->name);
+		    }
+		  nextchar += strlen (nextchar);
+		  return '?';
+		}
+	    }
+	  else if (pfound->has_arg == 1)
+	    {
+	      if (optind < argc)
+		optarg = argv[optind++];
+	      else
+		{
+		  if (opterr)
+		    fprintf (stderr, "%s: option `%s' requires an argument\n",
+			     argv[0], argv[optind - 1]);
+		  nextchar += strlen (nextchar);
+		  return optstring[0] == ':' ? ':' : '?';
+		}
+	    }
+	  nextchar += strlen (nextchar);
+	  if (longind != NULL)
+	    *longind = option_index;
+	  if (pfound->flag)
+	    {
+	      *(pfound->flag) = pfound->val;
+	      return 0;
+	    }
+	  return pfound->val;
+	}
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+	 or the option starts with '--' or is not a valid short
+	 option, then it's an error.
+	 Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+#ifdef GETOPT_COMPAT
+	  || argv[optind][0] == '+'
+#endif				/* GETOPT_COMPAT */
+	  || my_index (optstring, *nextchar) == NULL)
+	{
+	  if (opterr)
+	    {
+	      if (argv[optind][1] == '-')
+		/* --option */
+		fprintf (stderr, "%s: unrecognized option `--%s'\n",
+			 argv[0], nextchar);
+	      else
+		/* +option or -option */
+		fprintf (stderr, "%s: unrecognized option `%c%s'\n",
+			 argv[0], argv[optind][0], nextchar);
+	    }
+	  nextchar = (char *) "";
+	  optind++;
+	  return '?';
+	}
+    }
+
+  /* Look at and handle the next option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+	if (opterr)
+	  {
+#if 0
+	    if (c < 040 || c >= 0177)
+	      fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+		       argv[0], c);
+	    else
+	      fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
+#else
+	    /* 1003.2 specifies the format of this message.  */
+	    fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+#endif
+	  }
+	optopt = c;
+	return '?';
+      }
+    if (temp[1] == ':')
+      {
+	if (temp[2] == ':')
+	  {
+	    /* This is an option that accepts an argument optionally.  */
+	    if (*nextchar != '\0')
+	      {
+		optarg = nextchar;
+		optind++;
+	      }
+	    else
+	      optarg = 0;
+	    nextchar = NULL;
+	  }
+	else
+	  {
+	    /* This is an option that requires an argument.  */
+	    if (*nextchar != '\0')
+	      {
+		optarg = nextchar;
+		/* If we end this ARGV-element by taking the rest as an arg,
+		   we must advance to the next element now.  */
+		optind++;
+	      }
+	    else if (optind == argc)
+	      {
+		if (opterr)
+		  {
+#if 0
+		    fprintf (stderr, "%s: option `-%c' requires an argument\n",
+			     argv[0], c);
+#else
+		    /* 1003.2 specifies the format of this message.  */
+		    fprintf (stderr, "%s: option requires an argument -- %c\n",
+			     argv[0], c);
+#endif
+		  }
+		optopt = c;
+		if (optstring[0] == ':')
+		  c = ':';
+		else
+		  c = '?';
+	      }
+	    else
+	      /* We already incremented `optind' once;
+		 increment it again when taking next ARGV-elt as argument.  */
+	      optarg = argv[optind++];
+	    nextchar = NULL;
+	  }
+      }
+    return c;
+  }
+}
+
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+			   (const struct option *) 0,
+			   (int *) 0,
+			   0);
+}
+
+#endif	/* _LIBC or not __GNU_LIBRARY__.  */
+
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == EOF)
+	break;
+
+      switch (c)
+	{
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	  if (digit_optind != 0 && digit_optind != this_option_optind)
+	    printf ("digits occur in two different argv-elements.\n");
+	  digit_optind = this_option_optind;
+	  printf ("option %c\n", c);
+	  break;
+
+	case 'a':
+	  printf ("option a\n");
+	  break;
+
+	case 'b':
+	  printf ("option b\n");
+	  break;
+
+	case 'c':
+	  printf ("option c with value `%s'\n", optarg);
+	  break;
+
+	case '?':
+	  break;
+
+	default:
+	  printf ("?? getopt returned character code 0%o ??\n", c);
+	}
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+	printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/getopt.h
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/getopt.h	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/getopt.h	(revision 20131)
@@ -0,0 +1,129 @@
+/* Declarations for getopt.
+   Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument		(or 0) if the option does not take an argument,
+   required_argument	(or 1) if the option requires an argument,
+   optional_argument 	(or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+#if	__STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define	no_argument		0
+#define required_argument	1
+#define optional_argument	2
+
+#if __STDC__
+#if defined(__GNU_LIBRARY__)
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* not __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+		        const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind,
+			     int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/global.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/global.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/global.c	(revision 20131)
@@ -0,0 +1,82 @@
+/* global.c - The external variables needed for "original" interface and
+   error messages. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+
+
+/* The global variables used for the "original" interface. */
+gdbm_file_info  *_gdbm_file = NULL;
+
+/* Memory for return data for the "original" interface. */
+datum _gdbm_memory = {NULL, 0};	/* Used by firstkey and nextkey. */
+char *_gdbm_fetch_val = NULL;	/* Used by fetch. */
+
+/* The dbm error number is placed in the variable GDBM_ERRNO. */
+gdbm_error gdbm_errno = GDBM_NO_ERROR;
+
+#ifdef MSDOS
+
+#include <io.h>
+#include <windows.h>
+
+/* a simple locking function for windows that uses file descriptors */
+int my_locking(int fh, int lmode, long lockoffset, long nbytes) {
+	int result = -1;
+	int trys = 10;
+
+	lseek (fh, lockoffset, L_SET);
+
+	while (trys > 0 && result != 0) {
+		if (lmode == MY_UNLOCK) {
+			if (UnlockFile((HANDLE)_get_osfhandle(fh),lockoffset,0,nbytes,0))
+				result = 0;
+
+		} else if (lmode == MY_READLOCK) {
+/*			if (LockFileEx((HANDLE)_get_osfhandle(fh),0,0,nbytes,0,0))*/
+			if (LockFile((HANDLE)_get_osfhandle(fh),lockoffset,0,nbytes,0))
+				result = 0;
+
+		} else if (lmode == MY_WRITELOCK) {
+			if (LockFile((HANDLE)_get_osfhandle(fh),lockoffset,0,nbytes,0))
+				result = 0;
+		}
+
+		Sleep(100L);
+		trys--;
+	}
+
+	return result;
+}
+
+#endif
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gsdlmods.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gsdlmods.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gsdlmods.c	(revision 20131)
@@ -0,0 +1,46 @@
+/**********************************************************************
+ *
+ * gsdlmods.c -- C file for endian-swapping functions
+ * Copyright (C) 2008  DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#include "gsdlmods.h"
+
+
+int wrong_endianness = 0;
+
+
+int endian_swap (unsigned int x)
+{
+  return (x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24);
+}
+
+
+void endian_swap_array (int* a, unsigned int l)
+{
+  int i;
+  for (i = 0; i < (l / sizeof(int)); i++)
+  {
+    a[i] = endian_swap (a[i]);
+  }
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gsdlmods.h
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gsdlmods.h	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/gsdlmods.h	(revision 20131)
@@ -0,0 +1,38 @@
+/**********************************************************************
+ *
+ * gsdlmods.h -- H file for endian-swapping functions
+ * Copyright (C) 2008  DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef GSDLMODS_H
+#define GSDLMODS_H
+
+
+extern int wrong_endianness;
+
+int endian_swap (unsigned int x);
+
+void endian_swap_array (int* a, unsigned int l);
+
+
+#endif
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/hash.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/hash.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/hash.c	(revision 20131)
@@ -0,0 +1,58 @@
+/* hash.c - The gdbm hash function. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+
+
+/* This hash function computes a 31 bit value.  The value is used to index
+   the hash directory using the top n bits.  It is also used in a hash bucket
+   to find the home position of the element by taking the value modulo the
+   bucket hash table size. */
+
+int
+_gdbm_hash (key)
+     datum key;
+{
+  unsigned int value;	/* Used to compute the hash value.  */
+  int   index;		/* Used to cycle through random values. */
+
+
+  /* Set the initial value from key. */
+  value = 0x238F13AF * key.dsize;
+  for (index = 0; index < key.dsize; index++)
+    value = (value + (key.dptr[index] << (index*5 % 24))) & 0x7FFFFFFF;
+
+  value = (1103515243 * value + 12345) & 0x7FFFFFFF;  
+
+  /* Return the value. */
+  return((int) value);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/install-sh
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/install-sh	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/install-sh	(revision 20131)
@@ -0,0 +1,250 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/ltmain.sh
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/ltmain.sh	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/ltmain.sh	(revision 20131)
@@ -0,0 +1,4984 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun configure.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.4.2
+TIMESTAMP=" (1.922.2.53 2001/09/11 03:18:52)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+SP2NL='tr \040 \012'
+NL2SP='tr \015\012 \040\040'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+  save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+# Make sure IFS has a sensible default
+: ${IFS=" 	"}
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  echo "$modename: not configured to build any kind of library" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+  arg="$1"
+  shift
+
+  case $arg in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case $prev in
+    execute_dlfiles)
+      execute_dlfiles="$execute_dlfiles $arg"
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case $arg in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+    exit 0
+    ;;
+
+  --config)
+    sed -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0
+    exit 0
+    ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+    exit 0
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --quiet | --silent)
+    show=:
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+fi
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    case $nonopt in
+    *cc | *++ | gcc* | *-gcc*)
+      mode=link
+      for arg
+      do
+	case $arg in
+	-c)
+	   mode=compile
+	   break
+	   ;;
+	esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+	if test -n "$nonopt"; then
+	  $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+	else
+	  $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+	fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case $mode in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    prev=
+    lastarg=
+    srcfile="$nonopt"
+    suppress_output=
+
+    user_target=no
+    for arg
+    do
+      case $prev in
+      "") ;;
+      xcompiler)
+	# Aesthetically quote the previous argument.
+	prev=
+	lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+
+	case $arg in
+	# Double-quote args containing other shell metacharacters.
+	# Many Bourne shells cannot handle close brackets correctly
+	# in scan sets, so we specify it separately.
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+
+	# Add the previous argument to base_compile.
+	if test -z "$base_compile"; then
+	  base_compile="$lastarg"
+	else
+	  base_compile="$base_compile $lastarg"
+	fi
+	continue
+	;;
+      esac
+
+      # Accept any command-line options.
+      case $arg in
+      -o)
+	if test "$user_target" != "no"; then
+	  $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+	  exit 1
+	fi
+	user_target=next
+	;;
+
+      -static)
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Wc,*)
+	args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
+	lastarg=
+	save_ifs="$IFS"; IFS=','
+	for arg in $args; do
+	  IFS="$save_ifs"
+
+	  # Double-quote args containing other shell metacharacters.
+	  # Many Bourne shells cannot handle close brackets correctly
+	  # in scan sets, so we specify it separately.
+	  case $arg in
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	    arg="\"$arg\""
+	    ;;
+	  esac
+	  lastarg="$lastarg $arg"
+	done
+	IFS="$save_ifs"
+	lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
+
+	# Add the arguments to base_compile.
+	if test -z "$base_compile"; then
+	  base_compile="$lastarg"
+	else
+	  base_compile="$base_compile $lastarg"
+	fi
+	continue
+	;;
+      esac
+
+      case $user_target in
+      next)
+	# The next one is the -o target name
+	user_target=yes
+	continue
+	;;
+      yes)
+	# We got the output file
+	user_target=set
+	libobj="$arg"
+	continue
+	;;
+      esac
+
+      # Accept the current argument as the source file.
+      lastarg="$srcfile"
+      srcfile="$arg"
+
+      # Aesthetically quote the previous argument.
+
+      # Backslashify any backslashes, double quotes, and dollar signs.
+      # These are the only characters that are still specially
+      # interpreted inside of double-quoted scrings.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      case $lastarg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	lastarg="\"$lastarg\""
+	;;
+      esac
+
+      # Add the previous argument to base_compile.
+      if test -z "$base_compile"; then
+	base_compile="$lastarg"
+      else
+	base_compile="$base_compile $lastarg"
+      fi
+    done
+
+    case $user_target in
+    set)
+      ;;
+    no)
+      # Get the name of the library object.
+      libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    *)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSfmso]'
+    case $libobj in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case $libobj in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $libobj"
+    else
+      removelist="$libobj"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit 1" 1 2 15
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2*)
+      pic_mode=default
+      ;;
+    esac
+    if test $pic_mode = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit 1" 1 2 15
+    else
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $run ln "$0" "$lockfile" 2>/dev/null; do
+	$show "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit 1
+      fi
+      echo $srcfile > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+	# All platforms use -DPIC, to notify preprocessed assembler code.
+	command="$base_compile $srcfile $pic_flag -DPIC"
+      else
+	# Don't build PIC code
+	command="$base_compile $srcfile"
+      fi
+      if test "$build_old_libs" = yes; then
+	lo_libobj="$libobj"
+	dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+	if test "X$dir" = "X$libobj"; then
+	  dir="$objdir"
+	else
+	  dir="$dir/$objdir"
+	fi
+	libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+	if test -d "$dir"; then
+	  $show "$rm $libobj"
+	  $run $rm $libobj
+	else
+	  $show "$mkdir $dir"
+	  $run $mkdir $dir
+	  status=$?
+	  if test $status -ne 0 && test ! -d $dir; then
+	    exit $status
+	  fi
+	fi
+      fi
+      if test "$compiler_o_lo" = yes; then
+	output_obj="$libobj"
+	command="$command -o $output_obj"
+      elif test "$compiler_c_o" = yes; then
+	output_obj="$obj"
+	command="$command -o $output_obj"
+      fi
+
+      $run $rm "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+	test -n "$output_obj" && $run $rm $removelist
+	exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+	 test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+	echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit 1
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test x"$output_obj" != x"$libobj"; then
+	$show "$mv $output_obj $libobj"
+	if $run $mv $output_obj $libobj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # If we have no pic_flag, then copy the object into place and finish.
+      if (test -z "$pic_flag" || test "$pic_mode" != default) &&
+	 test "$build_old_libs" = yes; then
+	# Rename the .lo from within objdir to obj
+	if test -f $obj; then
+	  $show $rm $obj
+	  $run $rm $obj
+	fi
+
+	$show "$mv $libobj $obj"
+	if $run $mv $libobj $obj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+
+	xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+	if test "X$xdir" = "X$obj"; then
+	  xdir="."
+	else
+	  xdir="$xdir"
+	fi
+	baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"`
+	libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+	# Now arrange that obj and lo_libobj become the same file
+	$show "(cd $xdir && $LN_S $baseobj $libobj)"
+	if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
+	  # Unlock the critical section if it was locked
+	  if test "$need_locks" != no; then
+	    $run $rm "$lockfile"
+	  fi
+	  exit 0
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Allow error messages only from the first compilation.
+      suppress_output=' >/dev/null 2>&1'
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+	# Don't build PIC code
+	command="$base_compile $srcfile"
+      else
+	# All platforms use -DPIC, to notify preprocessed assembler code.
+	command="$base_compile $srcfile $pic_flag -DPIC"
+      fi
+      if test "$compiler_c_o" = yes; then
+	command="$command -o $obj"
+	output_obj="$obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $run $rm "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+	$run $rm $removelist
+	exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+	 test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+	echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit 1
+      fi
+
+      # Just move the object if needed
+      if test x"$output_obj" != x"$obj"; then
+	$show "$mv $output_obj $obj"
+	if $run $mv $output_obj $obj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Create an invalid libtool object if no PIC, so that we do not
+      # accidentally link it into a program.
+      if test "$build_libtool_libs" != yes; then
+	$show "echo timestamp > $libobj"
+	$run eval "echo timestamp > \$libobj" || exit $?
+      else
+	# Move the .lo from within objdir
+	$show "$mv $libobj $lo_libobj"
+	if $run $mv $libobj $lo_libobj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+    fi
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $run $rm "$lockfile"
+    fi
+
+    exit 0
+    ;;
+
+  # libtool link mode
+  link | relink)
+    modename="$modename: link"
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invokation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args="$nonopt"
+    compile_command="$nonopt"
+    finalize_command="$nonopt"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -all-static | -static)
+	if test "X$arg" = "X-all-static"; then
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	else
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	fi
+	build_libtool_libs=no
+	build_old_libs=yes
+	prefer_static_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test $# -gt 0; do
+      arg="$1"
+      shift
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
+	;;
+      *) qarg=$arg ;;
+      esac
+      libtool_args="$libtool_args $qarg"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  compile_command="$compile_command @OUTPUT@"
+	  finalize_command="$finalize_command @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    compile_command="$compile_command @SYMFILE@"
+	    finalize_command="$finalize_command @SYMFILE@"
+	    preload=yes
+	  fi
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      dlfiles="$dlfiles $arg"
+	    else
+	      dlprefiles="$dlprefiles $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  if test ! -f "$arg"; then
+	    $echo "$modename: symbol file \`$arg' does not exist"
+	    exit 1
+	  fi
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    $echo "$modename: only absolute run-paths are allowed" 1>&2
+	    exit 1
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) rpath="$rpath $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) xrpath="$xrpath $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	xcompiler)
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  compile_command="$compile_command $qarg"
+	  finalize_command="$finalize_command $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $wl$qarg"
+	  prev=
+	  compile_command="$compile_command $wl$qarg"
+	  finalize_command="$finalize_command $wl$qarg"
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n $prev
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  compile_command="$compile_command $link_static_flag"
+	  finalize_command="$finalize_command $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	$echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+	continue
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  $echo "$modename: more than one -exported-symbols argument is not allowed"
+	  exit 1
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix*)
+	  compile_command="$compile_command $arg"
+	  finalize_command="$finalize_command $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  if test -z "$absdir"; then
+	    $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+	    exit 1
+	  fi
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "*) ;;
+	*)
+	  deplibs="$deplibs -L$dir"
+	  lib_search_path="$lib_search_path $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$dir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+	  case $host in
+	  *-*-cygwin* | *-*-pw32* | *-*-beos*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-mingw* | *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-openbsd*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  esac
+	 elif test "X$arg" = "X-lc_r"; then
+	  case $host in
+	  *-*-openbsd*)
+	    # Do not include libc_r directly, use -pthread flag.
+	    continue
+	    ;;
+	  esac
+	fi
+	deplibs="$deplibs $arg"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # in order for the loader to find any dlls it needs.
+	  $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
+	  $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  $echo "$modename: only absolute run-paths are allowed" 1>&2
+	  exit 1
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) xrpath="$xrpath $dir" ;;
+	esac
+	continue
+	;;
+
+      -static)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+
+      -Wc,*)
+	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+	  case $flag in
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	    flag="\"$flag\""
+	    ;;
+	  esac
+	  arg="$arg $wl$flag"
+	  compiler_flags="$compiler_flags $flag"
+	done
+	IFS="$save_ifs"
+	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+	;;
+
+      -Wl,*)
+	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+	  case $flag in
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	    flag="\"$flag\""
+	    ;;
+	  esac
+	  arg="$arg $wl$flag"
+	  compiler_flags="$compiler_flags $wl$flag"
+	  linker_flags="$linker_flags $flag"
+	done
+	IFS="$save_ifs"
+	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      # Some other compiler flag.
+      -* | +*)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	;;
+
+      *.lo | *.$objext)
+	# A library or standard object.
+	if test "$prev" = dlfiles; then
+	  # This file was specified with -dlopen.
+	  if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+	    dlfiles="$dlfiles $arg"
+	    prev=
+	    continue
+	  else
+	    # If libtool objects are unsupported, then we need to preload.
+	    prev=dlprefiles
+	  fi
+	fi
+
+	if test "$prev" = dlprefiles; then
+	  # Preload the old-style object.
+	  dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+	  prev=
+	else
+	  case $arg in
+	  *.lo) libobjs="$libobjs $arg" ;;
+	  *) objs="$objs $arg" ;;
+	  esac
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	deplibs="$deplibs $arg"
+	old_deplibs="$old_deplibs $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  dlfiles="$dlfiles $arg"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  dlprefiles="$dlprefiles $arg"
+	  prev=
+	else
+	  deplibs="$deplibs $arg"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+      fi
+    done # argument parsing loop
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$output_objdir" = "X$output"; then
+      output_objdir="$objdir"
+    else
+      output_objdir="$output_objdir/$objdir"
+    fi
+    # Create the object directory.
+    if test ! -d $output_objdir; then
+      $show "$mkdir $output_objdir"
+      $run $mkdir $output_objdir
+      status=$?
+      if test $status -ne 0 && test ! -d $output_objdir; then
+	exit $status
+      fi
+    fi
+
+    # Determine the type of output
+    case $output in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    specialdeplibs=
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      case "$libs " in
+      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+      esac
+      libs="$libs $deplib"
+    done
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+    case $linkmode in
+    lib)
+	passes="conv link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
+	    exit 1
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=no
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+    for pass in $passes; do
+      if test $linkmode = prog; then
+	# Determine which files to process
+	case $pass in
+	dlopen)
+	  libs="$dlfiles"
+	  save_deplibs="$deplibs" # Collect dlpreopened libraries
+	  deplibs=
+	  ;;
+	dlpreopen) libs="$dlprefiles" ;;
+	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+	esac
+      fi
+      for deplib in $libs; do
+	lib=
+	found=no
+	case $deplib in
+	-l*)
+	  if test $linkmode = oldlib && test $linkmode = obj; then
+	    $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2
+	    continue
+	  fi
+	  if test $pass = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
+	  for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
+	    # Search the libtool library
+	    lib="$searchdir/lib${name}.la"
+	    if test -f "$lib"; then
+	      found=yes
+	      break
+	    fi
+	  done
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  fi
+	  ;; # -l
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test $pass = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+	    ;;
+	  prog)
+	    if test $pass = conv; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test $pass = scan; then
+	      deplibs="$deplib $deplibs"
+	      newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    ;;
+	  *)
+	    $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test $pass = link; then
+	    dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) xrpath="$xrpath $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la) lib="$deplib" ;;
+	*.$libext)
+	  if test $pass = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    if test "$deplibs_check_method" != pass_all; then
+	      echo
+	      echo "*** Warning: This library needs some functionality provided by $deplib."
+	      echo "*** I have the capability to make that library automatically link in when"
+	      echo "*** you link to this library.  But I can only do this if you have a"
+	      echo "*** shared version of the library, which you do not appear to have."
+	    else
+	      echo
+	      echo "*** Warning: Linking the shared library $output against the"
+	      echo "*** static library $deplib is not portable!"
+	      deplibs="$deplib $deplibs"
+	    fi
+	    continue
+	    ;;
+	  prog)
+	    if test $pass != link; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	    # If there is no dlopen support or we're linking statically,
+	    # we need to preload.
+	    newdlprefiles="$newdlprefiles $deplib"
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    newdlfiles="$newdlfiles $deplib"
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+	if test $found = yes || test -f "$lib"; then :
+	else
+	  $echo "$modename: cannot find the library \`$lib'" 1>&2
+	  exit 1
+	fi
+
+	# Check to see that this really is a libtool archive.
+	if (sed -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+	  exit 1
+	fi
+
+	ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$ladir" = "X$lib" && ladir="."
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variable installed.
+	installed=yes
+
+	# Read the .la file
+	case $lib in
+	*/* | *\\*) . $lib ;;
+	*) . ./$lib ;;
+	esac
+
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test $linkmode = oldlib && test $linkmode = obj; }; then
+	   # Add dl[pre]opened files of deplib
+	  test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+	  test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+	fi
+
+	if test $pass = conv; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+	      exit 1
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    convenience="$convenience $ladir/$objdir/$old_library"
+	    old_convenience="$old_convenience $ladir/$objdir/$old_library"
+	    tmp_libs=
+	    for deplib in $dependency_libs; do
+	      deplibs="$deplib $deplibs"
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	      tmp_libs="$tmp_libs $deplib"
+	    done
+	  elif test $linkmode != prog && test $linkmode != lib; then
+	    $echo "$modename: \`$lib' is not a convenience library" 1>&2
+	    exit 1
+	  fi
+	  continue
+	fi # $pass = conv
+
+	# Get the name of the library we link against.
+	linklib=
+	for l in $old_library $library_names; do
+	  linklib="$l"
+	done
+	if test -z "$linklib"; then
+	  $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+	  exit 1
+	fi
+
+	# This library was specified with -dlopen.
+	if test $pass = dlopen; then
+	  if test -z "$libdir"; then
+	    $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
+	    exit 1
+	  fi
+	  if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.
+	    dlprefiles="$dlprefiles $lib"
+	  else
+	    newdlfiles="$newdlfiles $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
+	    $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    $echo "$modename: warning: library \`$lib' was moved." 1>&2
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$libdir"
+	    absdir="$libdir"
+	  fi
+	else
+	  dir="$ladir/$objdir"
+	  absdir="$abs_ladir/$objdir"
+	  # Remove this search path later
+	  notinst_path="$notinst_path $abs_ladir"
+	fi # $installed = yes
+	name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+
+	# This library was specified with -dlpreopen.
+	if test $pass = dlpreopen; then
+	  if test -z "$libdir"; then
+	    $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
+	    exit 1
+	  fi
+	  # Prefer using a static library (so that no silly _DYNAMIC symbols
+	  # are required to link).
+	  if test -n "$old_library"; then
+	    newdlprefiles="$newdlprefiles $dir/$old_library"
+	  # Otherwise, use the dlname, so that lt_dlopen finds it.
+	  elif test -n "$dlname"; then
+	    newdlprefiles="$newdlprefiles $dir/$dlname"
+	  else
+	    newdlprefiles="$newdlprefiles $dir/$linklib"
+	  fi
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test $linkmode = lib; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs"
+	  fi
+	  continue
+	fi
+
+	if test $linkmode = prog && test $pass != link; then
+	  newlib_search_path="$newlib_search_path $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
+	    esac
+	    # Need to link against all dependency_libs?
+	    if test $linkalldeplibs = yes; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    case "$tmp_libs " in
+	    *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	    esac
+	    tmp_libs="$tmp_libs $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	link_static=no # Whether the deplib will be linked statically
+	if test -n "$library_names" &&
+	   { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+	  # Link against this shared library
+
+	  if test "$linkmode,$pass" = "prog,link" ||
+	   { test $linkmode = lib && test $hardcode_into_libs = yes; }; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	    if test $linkmode = prog; then
+	      # We need to hardcode the library path
+	      if test -n "$shlibpath_var"; then
+		# Make sure the rpath contains only unique directories.
+		case "$temp_rpath " in
+		*" $dir "*) ;;
+		*" $absdir "*) ;;
+		*) temp_rpath="$temp_rpath $dir" ;;
+		esac
+	      fi
+	    fi
+	  fi # $linkmode,$pass = prog,link...
+
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+
+	  if test "$installed" = no; then
+	    notinst_deplibs="$notinst_deplibs $lib"
+	    need_relink=yes
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    realname="$2"
+	    shift; shift
+	    libname=`eval \\$echo \"$libname_spec\"`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname="$dlname"
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin*)
+		major=`expr $current - $age`
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    soname=`echo $soroot | sed -e 's/^.*\///'`
+	    newlib="libimp-`echo $soname | sed 's/^lib//;s/\.dll$//'`.a"
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      $show "extracting exported symbol list from \`$soname'"
+	      save_ifs="$IFS"; IFS='~'
+	      eval cmds=\"$extract_expsyms_cmds\"
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		$show "$cmd"
+		$run eval "$cmd" || exit $?
+	      done
+	      IFS="$save_ifs"
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      $show "generating import library for \`$soname'"
+	      save_ifs="$IFS"; IFS='~'
+	      eval cmds=\"$old_archive_from_expsyms_cmds\"
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		$show "$cmd"
+		$run eval "$cmd" || exit $?
+	      done
+	      IFS="$save_ifs"
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n $old_archive_from_expsyms_cmds
+
+	  if test $linkmode = prog || test "$mode" != relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = no; then
+		case $host in
+		*-*-sunos*) add_shlibpath="$dir" ;;
+		esac
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test "$hardcode_direct" = yes; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test "$lib_linked" != yes; then
+	      $echo "$modename: configuration error: unsupported hardcode properties"
+	      exit 1
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test $linkmode = prog; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test "$hardcode_direct" != yes && \
+		 test "$hardcode_minus_L" != yes && \
+		 test "$hardcode_shlibpath_var" = yes; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test $linkmode = prog || test "$mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+	      esac
+	      add="-l$name"
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    fi
+
+	    if test $linkmode = prog; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test $linkmode = prog; then
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+
+	  # Try to link the static library
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test "$build_libtool_libs" = yes; then
+	  # Not a shared library
+	  if test "$deplibs_check_method" != pass_all; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    echo
+	    echo "*** Warning: This library needs some functionality provided by $lib."
+	    echo "*** I have the capability to make that library automatically link in when"
+	    echo "*** you link to this library.  But I can only do this if you have a"
+	    echo "*** shared version of the library, which you do not appear to have."
+	    if test "$module" = yes; then
+	      echo "*** Therefore, libtool will create a static module, that should work "
+	      echo "*** as long as the dlopening application is linked with the -dlopen flag."
+	      if test -z "$global_symbol_pipe"; then
+		echo
+		echo "*** However, this would only work if libtool was able to extract symbol"
+		echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+		echo "*** not find such a program.  So, this module is probably useless."
+		echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test "$build_old_libs" = no; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    convenience="$convenience $dir/$old_library"
+	    old_convenience="$old_convenience $dir/$old_library"
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test $linkmode = lib; then
+	  if test -n "$dependency_libs" &&
+	     { test $hardcode_into_libs != yes || test $build_old_libs = yes ||
+	       test $link_static = yes; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) xrpath="$xrpath $temp_xrpath";;
+		   esac;;
+	      *) temp_deplibs="$temp_deplibs $libdir";;
+	      esac
+	    done
+	    dependency_libs="$temp_deplibs"
+	  fi
+
+	  newlib_search_path="$newlib_search_path $absdir"
+	  # Link against this library
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    case "$tmp_libs " in
+	    *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	    esac
+	    tmp_libs="$tmp_libs $deplib"
+	  done
+
+	  if test $link_all_deplibs != no; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      -L*) path="$deplib" ;;
+	      *.la)
+		dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
+		test "X$dir" = "X$deplib" && dir="."
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+		    absdir="$dir"
+		  fi
+		  ;;
+		esac
+		if grep "^installed=no" $deplib > /dev/null; then
+		  path="-L$absdir/$objdir"
+		else
+		  eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  if test -z "$libdir"; then
+		    $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+		    exit 1
+		  fi
+		  if test "$absdir" != "$libdir"; then
+		    $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
+		  fi
+		  path="-L$absdir"
+		fi
+		;;
+	      *) continue ;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$deplibs $path" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      if test $pass = dlpreopen; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test $pass != dlopen; then
+	test $pass != scan && dependency_libs="$newdependency_libs"
+	if test $pass != conv; then
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) lib_search_path="$lib_search_path $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	fi
+
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
+	else
+	  vars="compile_deplibs finalize_deplibs"
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    *)
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) tmp_libs="$tmp_libs $deplib" ;;
+	      esac
+	      ;;
+	    *) tmp_libs="$tmp_libs $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+      if test "$pass" = "conv" &&
+       { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then
+	libs="$deplibs" # reset libs
+	deplibs=
+      fi
+    done # for pass
+    if test $linkmode = prog; then
+      dlfiles="$newdlfiles"
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	$echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+	$echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	$echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+      fi
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      objs="$objs$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+	name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	if test "$module" = no; then
+	  $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+	  eval libname=\"$libname_spec\"
+	else
+	  libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test "$deplibs_check_method" != pass_all; then
+	  $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
+	  exit 1
+	else
+	  echo
+	  echo "*** Warning: Linking the shared library $output against the non-libtool"
+	  echo "*** objects $objs is not portable!"
+	  libobjs="$libobjs $objs"
+	fi
+      fi
+
+      if test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
+      fi
+
+      set dummy $rpath
+      if test $# -gt 2; then
+	$echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  libext=al
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	if test -n "$vinfo"; then
+	  $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+	fi
+
+	if test -n "$release"; then
+	  $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+	fi
+      else
+
+	# Parse the version information argument.
+	save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	IFS="$save_ifs"
+
+	if test -n "$8"; then
+	  $echo "$modename: too many parameters to \`-version-info'" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+
+	current="$2"
+	revision="$3"
+	age="$4"
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+	*)
+	  $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	case $revision in
+	0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+	*)
+	  $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	case $age in
+	0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+	*)
+	  $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	if test $age -gt $current; then
+	  $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  major=.`expr $current - $age`
+	  versuffix="$major.$age.$revision"
+	  # Darwin ld doesn't like 0 for these options...
+	  minor_current=`expr $current + 1`
+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current";
+	  ;;
+
+	irix)
+	  major=`expr $current - $age + 1`
+	  verstring="sgi$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test $loop != 0; do
+	    iface=`expr $revision - $loop`
+	    loop=`expr $loop - 1`
+	    verstring="sgi$major.$iface:$verstring"
+	  done
+
+	  # Before this point, $major must not contain `.'.
+	  major=.$major
+	  versuffix="$major.$revision"
+	  ;;
+
+	linux)
+	  major=.`expr $current - $age`
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  major=`expr $current - $age`
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test $loop != 0; do
+	    iface=`expr $current - $loop`
+	    loop=`expr $loop - 1`
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  verstring="$verstring:${current}.0"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 filesystems.
+	  major=`expr $current - $age`
+	  versuffix="-$major"
+	  ;;
+
+	*)
+	  $echo "$modename: unknown library version type \`$version_type'" 1>&2
+	  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  verstring="0.0"
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=""
+	    ;;
+	  *)
+	    verstring="0.0"
+	    ;;
+	  esac
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+      fi
+
+      if test "$mode" != relink; then
+	# Remove our outputs.
+	$show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+	$run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      for path in $notinst_path; do
+	lib_search_path=`echo "$lib_search_path " | sed -e 's% $path % %g'`
+	deplibs=`echo "$deplibs " | sed -e 's% -L$path % %g'`
+	dependency_libs=`echo "$dependency_libs " | sed -e 's% -L$path % %g'`
+      done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  temp_xrpath="$temp_xrpath -R$libdir"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+	if test $hardcode_into_libs != yes || test $build_old_libs = yes; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) dlfiles="$dlfiles $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) dlprefiles="$dlprefiles $lib" ;;
+	esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    deplibs="$deplibs -framework System"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-openbsd*)
+	    # Do not include libc due to us having libc/libc_r.
+	    ;;
+	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test $build_libtool_need_lc = "yes"; then
+	      deplibs="$deplibs -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behaviour.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $rm conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $rm conftest
+	  $CC -o conftest conftest.c $deplibs
+	  if test $? -eq 0 ; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      name="`expr $i : '-l\(.*\)'`"
+	      # If $name is empty we are operating on a -L argument.
+	      if test -n "$name" && test "$name" != "0"; then
+		libname=`eval \\$echo \"$libname_spec\"`
+		deplib_matches=`eval \\$echo \"$library_names_spec\"`
+		set dummy $deplib_matches
+		deplib_match=$2
+		if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		  newdeplibs="$newdeplibs $i"
+		else
+		  droppeddeps=yes
+		  echo
+		  echo "*** Warning: This library needs some functionality provided by $i."
+		  echo "*** I have the capability to make that library automatically link in when"
+		  echo "*** you link to this library.  But I can only do this if you have a"
+		  echo "*** shared version of the library, which you do not appear to have."
+		fi
+	      else
+		newdeplibs="$newdeplibs $i"
+	      fi
+	    done
+	  else
+	    # Error occured in the first compile.  Let's try to salvage the situation:
+	    # Compile a seperate program for each library.
+	    for i in $deplibs; do
+	      name="`expr $i : '-l\(.*\)'`"
+	     # If $name is empty we are operating on a -L argument.
+	      if test -n "$name" && test "$name" != "0"; then
+		$rm conftest
+		$CC -o conftest conftest.c $i
+		# Did it work?
+		if test $? -eq 0 ; then
+		  ldd_output=`ldd conftest`
+		  libname=`eval \\$echo \"$libname_spec\"`
+		  deplib_matches=`eval \\$echo \"$library_names_spec\"`
+		  set dummy $deplib_matches
+		  deplib_match=$2
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    newdeplibs="$newdeplibs $i"
+		  else
+		    droppeddeps=yes
+		    echo
+		    echo "*** Warning: This library needs some functionality provided by $i."
+		    echo "*** I have the capability to make that library automatically link in when"
+		    echo "*** you link to this library.  But I can only do this if you have a"
+		    echo "*** shared version of the library, which you do not appear to have."
+		  fi
+		else
+		  droppeddeps=yes
+		  echo
+		  echo "*** Warning!  Library $i is needed by this library but I was not able to"
+		  echo "***  make it link in!  You will probably need to install it or some"
+		  echo "*** library that it depends on before this library will be fully"
+		  echo "*** functional.  Installing it before continuing would be even better."
+		fi
+	      else
+		newdeplibs="$newdeplibs $i"
+	      fi
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method
+	  file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    name="`expr $a_deplib : '-l\(.*\)'`"
+	    # If $name is empty we are operating on a -L argument.
+	    if test -n "$name" && test "$name" != "0"; then
+	      libname=`eval \\$echo \"$libname_spec\"`
+	      for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		    potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		    for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null \
+			 | grep " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+			 | sed 10q \
+			 | egrep "$file_magic_regex" > /dev/null; then
+			newdeplibs="$newdeplibs $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		    done
+	      done
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		echo "*** Warning: This library needs some functionality provided by $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have."
+	      fi
+	    else
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	    fi
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    name="`expr $a_deplib : '-l\(.*\)'`"
+	    # If $name is empty we are operating on a -L argument.
+	    if test -n "$name" && test "$name" != "0"; then
+	      libname=`eval \\$echo \"$libname_spec\"`
+	      for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		for potent_lib in $potential_libs; do
+		  if eval echo \"$potent_lib\" 2>/dev/null \
+		      | sed 10q \
+		      | egrep "$match_pattern_regex" > /dev/null; then
+		    newdeplibs="$newdeplibs $a_deplib"
+		    a_deplib=""
+		    break 2
+		  fi
+		done
+	      done
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		echo "*** Warning: This library needs some functionality provided by $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have."
+	      fi
+	    else
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	    fi
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+	       -e 's/ -[LR][^ ]*//g' -e 's/[ 	]//g' |
+	     grep . >/dev/null; then
+	    echo
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	  fi
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library is the System framework
+	  newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
+	  ;;
+	esac
+
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    echo
+	    echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    echo "*** dependencies of module $libname.  Therefore, libtool will create"
+	    echo "*** a static module, that should work as long as the dlopening"
+	    echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      echo
+	      echo "*** However, this would only work if libtool was able to extract symbol"
+	      echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      echo "*** not find such a program.  So, this module is probably useless."
+	      echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    echo "*** The inter-library dependencies that have been dropped here will be"
+	    echo "*** automatically added whenever a program is linked with this library"
+	    echo "*** or is declared to -dlopen it."
+
+	    if test $allow_undefined = no; then
+	      echo
+	      echo "*** Since this library must not contain undefined symbols,"
+	      echo "*** because either the platform does not support them or"
+	      echo "*** it was explicitly requested with -no-undefined,"
+	      echo "*** libtool will only create a static version of it."
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	if test $hardcode_into_libs = yes; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath="$finalize_rpath"
+	  test "$mode" != relink && rpath="$compile_rpath$rpath"
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs="$libdir"
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		dep_rpath="$dep_rpath $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) perm_rpath="$perm_rpath $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir="$hardcode_libdirs"
+	    eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      rpath="$rpath$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+	fi
+
+	shlibpath="$finalize_shlibpath"
+	test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+	fi
+
+	# Get the real and link names of the library.
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	realname="$2"
+	shift; shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname="$realname"
+	fi
+	test -z "$dlname" && dlname=$soname
+
+	lib="$output_objdir/$realname"
+	for link
+	do
+	  linknames="$linknames $link"
+	done
+
+	# Ensure that we have .o objects for linkers which dislike .lo
+	# (e.g. aix) in case we are running --disable-static
+	for obj in $libobjs; do
+	  xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+	  if test "X$xdir" = "X$obj"; then
+	    xdir="."
+	  else
+	    xdir="$xdir"
+	  fi
+	  baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+	  oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+	  if test ! -f $xdir/$oldobj; then
+	    $show "(cd $xdir && ${LN_S} $baseobj $oldobj)"
+	    $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $?
+	  fi
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    $show "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $run $rm $export_symbols
+	    eval cmds=\"$export_symbols_cmds\"
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      $show "$cmd"
+	      $run eval "$cmd" || exit $?
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex"; then
+	      $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+	      $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+	      $run eval '$mv "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+	fi
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	  else
+	    gentop="$output_objdir/${outputname}x"
+	    $show "${rm}r $gentop"
+	    $run ${rm}r "$gentop"
+	    $show "mkdir $gentop"
+	    $run mkdir "$gentop"
+	    status=$?
+	    if test $status -ne 0 && test ! -d "$gentop"; then
+	      exit $status
+	    fi
+	    generated="$generated $gentop"
+
+	    for xlib in $convenience; do
+	      # Extract the objects.
+	      case $xlib in
+	      [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+	      *) xabs=`pwd`"/$xlib" ;;
+	      esac
+	      xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+	      xdir="$gentop/$xlib"
+
+	      $show "${rm}r $xdir"
+	      $run ${rm}r "$xdir"
+	      $show "mkdir $xdir"
+	      $run mkdir "$xdir"
+	      status=$?
+	      if test $status -ne 0 && test ! -d "$xdir"; then
+		exit $status
+	      fi
+	      $show "(cd $xdir && $AR x $xabs)"
+	      $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+	      libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+	    done
+	  fi
+	fi
+
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  linker_flags="$linker_flags $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test "$mode" = relink; then
+	  $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
+	fi
+
+	# Do each of the archive commands.
+	if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	  eval cmds=\"$archive_expsym_cmds\"
+	else
+	  eval cmds=\"$archive_cmds\"
+	fi
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  $show "$cmd"
+	  $run eval "$cmd" || exit $?
+	done
+	IFS="$save_ifs"
+
+	# Restore the uninstalled library and exit
+	if test "$mode" = relink; then
+	  $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+	  exit 0
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+	    $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$deplibs"; then
+	$echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	$echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+	$echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+      fi
+
+      case $output in
+      *.lo)
+	if test -n "$objs$old_deplibs"; then
+	  $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+	  exit 1
+	fi
+	libobj="$output"
+	obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec
+      wl=
+
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+	else
+	  gentop="$output_objdir/${obj}x"
+	  $show "${rm}r $gentop"
+	  $run ${rm}r "$gentop"
+	  $show "mkdir $gentop"
+	  $run mkdir "$gentop"
+	  status=$?
+	  if test $status -ne 0 && test ! -d "$gentop"; then
+	    exit $status
+	  fi
+	  generated="$generated $gentop"
+
+	  for xlib in $convenience; do
+	    # Extract the objects.
+	    case $xlib in
+	    [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+	    *) xabs=`pwd`"/$xlib" ;;
+	    esac
+	    xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+	    xdir="$gentop/$xlib"
+
+	    $show "${rm}r $xdir"
+	    $run ${rm}r "$xdir"
+	    $show "mkdir $xdir"
+	    $run mkdir "$xdir"
+	    status=$?
+	    if test $status -ne 0 && test ! -d "$xdir"; then
+	      exit $status
+	    fi
+	    $show "(cd $xdir && $AR x $xabs)"
+	    $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+	    reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+	  done
+	fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      eval cmds=\"$reload_cmds\"
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  $show "${rm}r $gentop"
+	  $run ${rm}r $gentop
+	fi
+
+	exit 0
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  $show "${rm}r $gentop"
+	  $run ${rm}r $gentop
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	$show "echo timestamp > $libobj"
+	$run eval "echo timestamp > $libobj" || exit $?
+	exit 0
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output="$libobj"
+	eval cmds=\"$reload_cmds\"
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  $show "$cmd"
+	  $run eval "$cmd" || exit $?
+	done
+	IFS="$save_ifs"
+      else
+	# Just create a symlink.
+	$show $rm $libobj
+	$run $rm $libobj
+	xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+	if test "X$xdir" = "X$libobj"; then
+	  xdir="."
+	else
+	  xdir="$xdir"
+	fi
+	baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+	oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+	$show "(cd $xdir && $LN_S $oldobj $baseobj)"
+	$run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $?
+      fi
+
+      if test -n "$gentop"; then
+	$show "${rm}r $gentop"
+	$run ${rm}r $gentop
+      fi
+
+      exit 0
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) output=`echo $output | sed -e 's,.exe$,,;s,$,.exe,'` ;;
+      esac
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+      fi
+
+      if test "$preload" = yes; then
+	if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
+	   test "$dlopen_self_static" = unknown; then
+	  $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+	fi
+      fi
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+	finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+	;;
+      esac
+
+      compile_command="$compile_command $compile_deplibs"
+      finalize_command="$finalize_command $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) perm_rpath="$perm_rpath $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$libdir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      dlsyms=
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	  dlsyms="${outputname}S.c"
+	else
+	  $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+	fi
+      fi
+
+      if test -n "$dlsyms"; then
+	case $dlsyms in
+	"") ;;
+	*.c)
+	  # Discover the nlist of each of the dlfiles.
+	  nlist="$output_objdir/${outputname}.nm"
+
+	  $show "$rm $nlist ${nlist}S ${nlist}T"
+	  $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+	  # Parse the name list into a source file.
+	  $show "creating $output_objdir/$dlsyms"
+
+	  test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+	  if test "$dlself" = yes; then
+	    $show "generating symbol list for \`$output'"
+
+	    test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+	    # Add our own program objects to the symbol list.
+	    progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	    for arg in $progfiles; do
+	      $show "extracting global C symbols from \`$arg'"
+	      $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+	    done
+
+	    if test -n "$exclude_expsyms"; then
+	      $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      $run eval '$mv "$nlist"T "$nlist"'
+	    fi
+
+	    if test -n "$export_symbols_regex"; then
+	      $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      $run eval '$mv "$nlist"T "$nlist"'
+	    fi
+
+	    # Prepare the list of exported symbols
+	    if test -z "$export_symbols"; then
+	      export_symbols="$output_objdir/$output.exp"
+	      $run $rm $export_symbols
+	      $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	    else
+	      $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+	      $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+	      $run eval 'mv "$nlist"T "$nlist"'
+	    fi
+	  fi
+
+	  for arg in $dlprefiles; do
+	    $show "extracting global C symbols from \`$arg'"
+	    name=`echo "$arg" | sed -e 's%^.*/%%'`
+	    $run eval 'echo ": $name " >> "$nlist"'
+	    $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -z "$run"; then
+	    # Make sure we have at least an empty file.
+	    test -f "$nlist" || : > "$nlist"
+
+	    if test -n "$exclude_expsyms"; then
+	      egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	      $mv "$nlist"T "$nlist"
+	    fi
+
+	    # Try sorting and uniquifying the output.
+	    if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+	      :
+	    else
+	      grep -v "^: " < "$nlist" > "$nlist"S
+	    fi
+
+	    if test -f "$nlist"S; then
+	      eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+	    else
+	      echo '/* NONE */' >> "$output_objdir/$dlsyms"
+	    fi
+
+	    $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
+
+	    $echo >> "$output_objdir/$dlsyms" "\
+  {0, (lt_ptr) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	  fi
+
+	  pic_flag_for_symtable=
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    case "$compile_command " in
+	    *" -static "*) ;;
+	    *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+	    esac;;
+	  *-*-hpux*)
+	    case "$compile_command " in
+	    *" -static "*) ;;
+	    *) pic_flag_for_symtable=" $pic_flag -DPIC";;
+	    esac
+	  esac
+
+	  # Now compile the dynamic symbol file.
+	  $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+	  $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+	  # Clean up the generated files.
+	  $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+	  $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+	  # Transform the symbol file into the correct name.
+	  compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+	  finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+	  ;;
+	*)
+	  $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+	  exit 1
+	  ;;
+	esac
+      else
+	# We keep going just in case the user didn't refer to
+	# lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+	# really was required.
+
+	# Nullify the symbol file.
+	compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+	finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test $need_relink = no || test "$build_libtool_libs" != yes; then
+	# Replace the output file specification.
+	compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	$show "$link_command"
+	$run eval "$link_command"
+	status=$?
+
+	# Delete the generated files.
+	if test -n "$dlsyms"; then
+	  $show "$rm $output_objdir/${outputname}S.${objext}"
+	  $run $rm "$output_objdir/${outputname}S.${objext}"
+	fi
+
+	exit $status
+      fi
+
+      if test -n "$shlibpath_var"; then
+	# We should set the shlibpath_var
+	rpath=
+	for dir in $temp_rpath; do
+	  case $dir in
+	  [\\/]* | [A-Za-z]:[\\/]*)
+	    # Absolute path.
+	    rpath="$rpath$dir:"
+	    ;;
+	  *)
+	    # Relative path: add a thisdir entry.
+	    rpath="$rpath\$thisdir/$dir:"
+	    ;;
+	  esac
+	done
+	temp_rpath="$rpath"
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test "$no_install" = yes; then
+	# We don't need to create a wrapper script.
+	link_command="$compile_var$compile_command$compile_rpath"
+	# Replace the output file specification.
+	link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$run $rm $output
+	# Link the executable and exit
+	$show "$link_command"
+	$run eval "$link_command" || exit $?
+	exit 0
+      fi
+
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+	$echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+	$echo "$modename: \`$output' will be relinked during installation" 1>&2
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      $show "$link_command"
+      $run eval "$link_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
+	  else
+	    var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+	    relink_command="$var=\"$var_value\"; export $var; $relink_command"
+	  fi
+	done
+	relink_command="cd `pwd`; $relink_command"
+	relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $echo for shipping.
+      if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+	case $0 in
+	[\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+	*) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+	esac
+	qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+	qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*) exeext=.exe ;;
+	  *) exeext= ;;
+	esac
+	$rm $output
+	trap "$rm $output; exit 1" 1 2 15
+
+	$echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variable:
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    echo=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$echo will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+	$echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  echo >> $output "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" || \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $mkdir \"\$progdir\"
+    else
+      $rm \"\$progdir/\$file\"
+    fi"
+
+	  echo >> $output "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	$echo \"\$relink_command_output\" >&2
+	$rm \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $rm \"\$progdir/\$program\";
+      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $rm \"\$progdir/\$file\"
+  fi"
+	else
+	  echo >> $output "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	echo >> $output "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	# fixup the dll searchpath if we need to.
+	if test -n "$dllsearchpath"; then
+	  $echo >> $output "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	$echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+"
+	case $host in
+	# win32 systems need to use the prog path for dll
+	# lookup to work
+	*-*-cygwin* | *-*-pw32*)
+	  $echo >> $output "\
+      exec \$progdir/\$program \${1+\"\$@\"}
+"
+	  ;;
+
+	# Backslashes separate directories on plain windows
+	*-*-mingw | *-*-os2*)
+	  $echo >> $output "\
+      exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+	  ;;
+
+	*)
+	  $echo >> $output "\
+      # Export the path to the program.
+      PATH=\"\$progdir:\$PATH\"
+      export PATH
+
+      exec \$program \${1+\"\$@\"}
+"
+	  ;;
+	esac
+	$echo >> $output "\
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+	chmod +x $output
+      fi
+      exit 0
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	$show "${rm}r $gentop"
+	$run ${rm}r "$gentop"
+	$show "mkdir $gentop"
+	$run mkdir "$gentop"
+	status=$?
+	if test $status -ne 0 && test ! -d "$gentop"; then
+	  exit $status
+	fi
+	generated="$generated $gentop"
+
+	# Add in members from convenience archives.
+	for xlib in $addlibs; do
+	  # Extract the objects.
+	  case $xlib in
+	  [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+	  *) xabs=`pwd`"/$xlib" ;;
+	  esac
+	  xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+	  xdir="$gentop/$xlib"
+
+	  $show "${rm}r $xdir"
+	  $run ${rm}r "$xdir"
+	  $show "mkdir $xdir"
+	  $run mkdir "$xdir"
+	  status=$?
+	  if test $status -ne 0 && test ! -d "$xdir"; then
+	    exit $status
+	  fi
+	  $show "(cd $xdir && $AR x $xabs)"
+	  $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+	  oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+	done
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+	eval cmds=\"$old_archive_from_new_cmds\"
+      else
+	# Ensure that we have .o objects in place in case we decided
+	# not to build a shared library, and have fallen back to building
+	# static libs even though --disable-static was passed!
+	for oldobj in $oldobjs; do
+	  if test ! -f $oldobj; then
+	    xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'`
+	    if test "X$xdir" = "X$oldobj"; then
+	      xdir="."
+	    else
+	      xdir="$xdir"
+	    fi
+	    baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'`
+	    obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+	    $show "(cd $xdir && ${LN_S} $obj $baseobj)"
+	    $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $?
+	  fi
+	done
+
+	eval cmds=\"$old_archive_cmds\"
+      fi
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$generated"; then
+      $show "${rm}r$generated"
+      $run ${rm}r$generated
+    fi
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      $show "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
+	else
+	  var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+	  relink_command="$var=\"$var_value\"; export $var; $relink_command"
+	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="cd `pwd`; $SHELL $0 --mode=relink $libtool_args"
+      relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
+		eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		if test -z "$libdir"; then
+		  $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+		  exit 1
+		fi
+		newdependency_libs="$newdependency_libs $libdir/$name"
+		;;
+	      *) newdependency_libs="$newdependency_libs $deplib" ;;
+	      esac
+	    done
+	    dependency_libs="$newdependency_libs"
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+	      eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+	      if test -z "$libdir"; then
+		$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+		exit 1
+	      fi
+	      newdlfiles="$newdlfiles $libdir/$name"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+	      eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+	      if test -z "$libdir"; then
+		$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+		exit 1
+	      fi
+	      newdlprefiles="$newdlprefiles $libdir/$name"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  fi
+	  $rm $output
+	  # place dlname in correct position for cygwin
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+	  esac
+	  $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test "$installed" = no && test $need_relink = yes; then
+	    $echo >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+      $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
+      ;;
+    esac
+    exit 0
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg="$nonopt"
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case $arg in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+	files="$files $dest"
+	dest="$arg"
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f) prev="-f" ;;
+      -g) prev="-g" ;;
+      -m) prev="-m" ;;
+      -o) prev="-o" ;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*) ;;
+
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  prev=
+	else
+	  dest="$arg"
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	$echo "$modename: no file or destination specified" 1>&2
+      else
+	$echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test $# -gt 2; then
+	$echo "$modename: \`$dest' is not a directory" 1>&2
+	$echo "$help" 1>&2
+	exit 1
+      fi
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	staticlibs="$staticlibs $file"
+	;;
+
+      *.la)
+	# Check to see that this really is a libtool archive.
+	if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+
+	library_names=
+	old_library=
+	relink_command=
+	# If there is no directory component, then add one.
+	case $file in
+	*/* | *\\*) . $file ;;
+	*) . ./$file ;;
+	esac
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) current_libdirs="$current_libdirs $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) future_libdirs="$future_libdirs $libdir" ;;
+	  esac
+	fi
+
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
+	test "X$dir" = "X$file/" && dir=
+	dir="$dir$objdir"
+
+	if test -n "$relink_command"; then
+	  $echo "$modename: warning: relinking \`$file'" 1>&2
+	  $show "$relink_command"
+	  if $run eval "$relink_command"; then :
+	  else
+	    $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+	    continue
+	  fi
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names
+	if test -n "$2"; then
+	  realname="$2"
+	  shift
+	  shift
+
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
+
+	  # Install the shared library and build the symlinks.
+	  $show "$install_prog $dir/$srcname $destdir/$realname"
+	  $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
+	  if test -n "$stripme" && test -n "$striplib"; then
+	    $show "$striplib $destdir/$realname"
+	    $run eval "$striplib $destdir/$realname" || exit $?
+	  fi
+
+	  if test $# -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    for linkname
+	    do
+	      if test "$linkname" != "$realname"; then
+		$show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+		$run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+	      fi
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  eval cmds=\"$postinstall_cmds\"
+	  save_ifs="$IFS"; IFS='~'
+	  for cmd in $cmds; do
+	    IFS="$save_ifs"
+	    $show "$cmd"
+	    $run eval "$cmd" || exit $?
+	  done
+	  IFS="$save_ifs"
+	fi
+
+	# Install the pseudo-library for information purposes.
+	name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	instname="$dir/$name"i
+	$show "$install_prog $instname $destdir/$name"
+	$run eval "$install_prog $instname $destdir/$name" || exit $?
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+	  ;;
+	*.$objext)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	if test -n "$destfile"; then
+	  $show "$install_prog $file $destfile"
+	  $run eval "$install_prog $file $destfile" || exit $?
+	fi
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+	  $show "$install_prog $staticobj $staticdest"
+	  $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+	fi
+	exit 0
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Do a test to see if this is really a libtool program.
+	if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  # If there is no directory component, then add one.
+	  case $file in
+	  */* | *\\*) . $file ;;
+	  *) . ./$file ;;
+	  esac
+
+	  # Check the variables that should have been set.
+	  if test -z "$notinst_deplibs"; then
+	    $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+	    exit 1
+	  fi
+
+	  finalize=yes
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      # If there is no directory component, then add one.
+	      case $lib in
+	      */* | *\\*) . $lib ;;
+	      *) . ./$lib ;;
+	      esac
+	    fi
+	    libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+	      finalize=no
+	    fi
+	  done
+
+	  relink_command=
+	  # If there is no directory component, then add one.
+	  case $file in
+	  */* | *\\*) . $file ;;
+	  *) . ./$file ;;
+	  esac
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    if test "$finalize" = yes && test -z "$run"; then
+	      tmpdir="/tmp"
+	      test -n "$TMPDIR" && tmpdir="$TMPDIR"
+	      tmpdir="$tmpdir/libtool-$$"
+	      if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+	      else
+		$echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+		continue
+	      fi
+	      file=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	      outputname="$tmpdir/$file"
+	      # Replace the output file specification.
+	      relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+	      $show "$relink_command"
+	      if $run eval "$relink_command"; then :
+	      else
+		$echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+		${rm}r "$tmpdir"
+		continue
+	      fi
+	      file="$outputname"
+	    else
+	      $echo "$modename: warning: cannot relink \`$file'" 1>&2
+	    fi
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyways
+	case $install_prog,$host in
+	/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    destfile=`echo $destfile | sed -e 's,.exe$,,'`
+	    ;;
+	  esac
+	  ;;
+	esac
+	$show "$install_prog$stripme $file $destfile"
+	$run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+	test -n "$outputname" && ${rm}r "$tmpdir"
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      if test -n "$stripme" && test -n "$striplib"; then
+	$show "$old_striplib $oldlib"
+	$run eval "$old_striplib $oldlib" || exit $?
+      fi
+
+      # Do each command in the postinstall commands.
+      eval cmds=\"$old_postinstall_cmds\"
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $0 --finish$current_libdirs'
+    else
+      exit 0
+    fi
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+	libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  eval cmds=\"$finish_cmds\"
+	  save_ifs="$IFS"; IFS='~'
+	  for cmd in $cmds; do
+	    IFS="$save_ifs"
+	    $show "$cmd"
+	    $run eval "$cmd" || admincmds="$admincmds
+       $cmd"
+	  done
+	  IFS="$save_ifs"
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $run eval "$cmds" || admincmds="$admincmds
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    test "$show" = ":" && exit 0
+
+    echo "----------------------------------------------------------------------"
+    echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      echo "   $libdir"
+    done
+    echo
+    echo "If you ever happen to want to link against installed libraries"
+    echo "in a given directory, LIBDIR, you must either use libtool, and"
+    echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+    echo "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      echo "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      echo "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    echo
+    echo "See any operating system documentation about shared libraries for"
+    echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    echo "----------------------------------------------------------------------"
+    exit 0
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit 1
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test ! -f "$file"; then
+	$echo "$modename: \`$file' is not a file" 1>&2
+	$echo "$help" 1>&2
+	exit 1
+      fi
+
+      dir=
+      case $file in
+      *.la)
+	# Check to see that this really is a libtool archive.
+	if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+
+	# If there is no directory component, then add one.
+	case $file in
+	*/* | *\\*) . $file ;;
+	*) . ./$file ;;
+	esac
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  dir="$dir/$objdir"
+	else
+	  $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+	  exit 1
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+	;;
+
+      *)
+	$echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -*) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  # If there is no directory component, then add one.
+	  case $file in
+	  */* | *\\*) . $file ;;
+	  *) . ./$file ;;
+	  esac
+
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved enviroment variables
+      if test "${save_LC_ALL+set}" = set; then
+	LC_ALL="$save_LC_ALL"; export LC_ALL
+      fi
+      if test "${save_LANG+set}" = set; then
+	LANG="$save_LANG"; export LANG
+      fi
+
+      # Now prepare to actually exec the command.
+      exec_cmd='"$cmd"$args'
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+	$echo "export $shlibpath_var"
+      fi
+      $echo "$cmd$args"
+      exit 0
+    fi
+    ;;
+
+  # libtool clean and uninstall mode
+  clean | uninstall)
+    modename="$modename: $mode"
+    rm="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) rm="$rm $arg"; rmforce=yes ;;
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    rmdirs=
+
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$dir" = "X$file"; then
+	dir=.
+	objdir="$objdir"
+      else
+	objdir="$dir/$objdir"
+      fi
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+      test $mode = uninstall && objdir="$dir"
+
+      # Remember objdir for removal later, being careful to avoid duplicates
+      if test $mode = clean; then
+	case " $rmdirs " in
+	  *" $objdir "*) ;;
+	  *) rmdirs="$rmdirs $objdir" ;;
+	esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if (test -L "$file") >/dev/null 2>&1 \
+	|| (test -h "$file") >/dev/null 2>&1 \
+	|| test -f "$file"; then
+	:
+      elif test -d "$file"; then
+	exit_status=1
+	continue
+      elif test "$rmforce" = yes; then
+	continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  . $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    rmfiles="$rmfiles $objdir/$n"
+	  done
+	  test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+	  test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+
+	  if test $mode = uninstall; then
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      eval cmds=\"$postuninstall_cmds\"
+	      save_ifs="$IFS"; IFS='~'
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		$show "$cmd"
+		$run eval "$cmd"
+		if test $? != 0 && test "$rmforce" != yes; then
+		  exit_status=1
+		fi
+	      done
+	      IFS="$save_ifs"
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      eval cmds=\"$old_postuninstall_cmds\"
+	      save_ifs="$IFS"; IFS='~'
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		$show "$cmd"
+		$run eval "$cmd"
+		if test $? != 0 && test "$rmforce" != yes; then
+		  exit_status=1
+		fi
+	      done
+	      IFS="$save_ifs"
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	  fi
+	fi
+	;;
+
+      *.lo)
+	if test "$build_old_libs" = yes; then
+	  oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+	  rmfiles="$rmfiles $dir/$oldobj"
+	fi
+	;;
+
+      *)
+	# Do a test to see if this is a libtool program.
+	if test $mode = clean &&
+	   (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  relink_command=
+	  . $dir/$file
+
+	  rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+	  if test "$fast_install" = yes && test -n "$relink_command"; then
+	    rmfiles="$rmfiles $objdir/lt-$name"
+	  fi
+	fi
+	;;
+      esac
+      $show "$rm $rmfiles"
+      $run $rm $rmfiles || exit_status=1
+    done
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	$show "rmdir $dir"
+	$run rmdir $dir >/dev/null 2>&1
+      fi
+    done
+
+    exit $exit_status
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+    ;;
+  esac
+
+  if test -z "$exec_cmd"; then
+    $echo "$modename: invalid operation mode \`$mode'" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+  fi
+fi # test -z "$show_help"
+
+if test -n "$exec_cmd"; then
+  eval exec $exec_cmd
+  exit 1
+fi
+
+# We need to display help for each of the modes.
+case $mode in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+    --config          show all configuration variables
+    --debug           enable verbose shell tracing
+-n, --dry-run         display commands without modifying any files
+    --features        display basic configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --version         print version information
+
+MODE must be one of the following:
+
+      clean           remove files from the build directory
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+  exit 0
+  ;;
+
+clean)
+  $echo \
+"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -prefer-pic       try to building PIC objects only
+  -prefer-non-pic   try to building non-PIC objects only
+  -static           always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+		    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+		    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+		    specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+  ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/mkinstalldirs
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/mkinstalldirs	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/mkinstalldirs	(revision 20131)
@@ -0,0 +1,35 @@
+#!/bin/sh
+# Make directory hierarchy. 
+# Written by Noah Friedman <friedman@prep.ai.mit.edu>
+# Public domain.
+
+defaultIFS=' 	
+'
+IFS="${IFS-${defaultIFS}}"
+
+errstatus=0
+
+for file in ${1+"$@"} ; do 
+   oIFS="${IFS}"
+   # Some sh's can't handle IFS=/ for some reason.
+   IFS='%'
+   set - `echo ${file} | sed -e 's@/@%@g' -e 's@^%@/@'`
+   IFS="${oIFS}"
+
+   pathcomp=''
+
+   for d in ${1+"$@"} ; do
+     pathcomp="${pathcomp}${d}"
+
+     if test ! -d "${pathcomp}"; then
+        echo "mkdir $pathcomp" 1>&2
+        mkdir "${pathcomp}" || errstatus=$?
+     fi
+
+     pathcomp="${pathcomp}/"
+   done
+done
+
+exit $errstatus
+
+# eof
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/ndbm.h
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/ndbm.h	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/ndbm.h	(revision 20131)
@@ -0,0 +1,71 @@
+/* ndbm.h  -  The include file for ndbm users.  */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+/* Parameters to dbm_store for simple insertion or replacement. */
+#define  DBM_INSERT  0
+#define  DBM_REPLACE 1
+
+
+/* The data and key structure.  This structure is defined for compatibility. */
+typedef struct {
+	char *dptr;
+	int   dsize;
+      } datum;
+
+
+/* The file information header. This is good enough for most applications. */
+typedef struct {int dummy[10];} DBM;
+
+
+/* These are the routines (with some macros defining them!) */
+
+extern DBM 	*dbm_open ();
+
+extern void	 dbm_close ();
+
+extern datum	 dbm_fetch ();
+
+extern int	 dbm_store ();
+
+extern int	 dbm_delete ();
+
+extern int	 dbm_delete ();
+
+extern datum	 dbm_firstkey ();
+
+extern datum	 dbm_nextkey ();
+
+#define		 dbm_error(dbf)  (0)
+
+#define		 dbm_clearerr(dbf)
+
+extern int	 dbm_dirfno ();
+
+extern int	 dbm_pagfno ();
+
+extern int	 dbm_rdonly ();
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/proto.h
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/proto.h	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/proto.h	(revision 20131)
@@ -0,0 +1,79 @@
+/* proto.h - The prototypes for the dbm routines. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+
+*************************************************************************/
+
+
+#ifndef __P
+#ifdef __STDC__
+#define __P(args) args
+#else
+#define __P(args) ()
+#endif
+#endif
+
+/* From bucket.c */
+void _gdbm_new_bucket    __P((gdbm_file_info *, hash_bucket *, int));
+void _gdbm_get_bucket    __P((gdbm_file_info *, int));
+void _gdbm_split_bucket  __P((gdbm_file_info *, int));
+void _gdbm_write_bucket  __P((gdbm_file_info *, cache_elem *));
+
+/* From falloc.c */
+off_t _gdbm_alloc       __P((gdbm_file_info *, int));
+void _gdbm_free         __P((gdbm_file_info *, off_t, int));
+int  _gdbm_put_av_elem  __P((avail_elem, avail_elem [], int *, int));
+
+/* From findkey.c */
+char *_gdbm_read_entry  __P((gdbm_file_info *, int));
+int _gdbm_findkey       __P((gdbm_file_info *, datum, char **, int *));
+
+/* From hash.c */
+int _gdbm_hash __P((datum));
+
+/* From update.c */
+void _gdbm_end_update   __P((gdbm_file_info *));
+void _gdbm_fatal         __P((gdbm_file_info *, char *));
+
+/* From gdbmopen.c */
+int _gdbm_init_cache	__P((gdbm_file_info *, int));
+
+/* The user callable routines.... */
+void  gdbm_close	  __P((gdbm_file_info *));
+int   gdbm_delete	  __P((gdbm_file_info *, datum));
+datum gdbm_fetch	  __P((gdbm_file_info *, datum));
+#ifdef MSDOS
+gdbm_file_info *gdbm_open __P((char *, int, int, int, void (*) (void), int));
+#else
+gdbm_file_info *gdbm_open __P((char *, int, int, int, void (*) (void)));
+#endif
+int   gdbm_reorganize	  __P((gdbm_file_info *));
+datum gdbm_firstkey       __P((gdbm_file_info *));
+datum gdbm_nextkey        __P((gdbm_file_info *, datum));
+int   gdbm_store          __P((gdbm_file_info *, datum, datum, int));
+int   gdbm_exists	  __P((gdbm_file_info *, datum));
+void  gdbm_sync		  __P((gdbm_file_info *));
+int   gdbm_setopt	  __P((gdbm_file_info *, int, int *, int));
+int   gdbm_fdesc	  __P((gdbm_file_info *));
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/seq.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/seq.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/seq.c	(revision 20131)
@@ -0,0 +1,75 @@
+/* seq.c - This is the sequential visit of the database.  This defines two
+   user-visable routines that are used together. This is the DBM interface. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "extern.h"
+
+/* Start the visit of all keys in the database.  This produces something in
+   hash order, not in any sorted order.  */
+
+datum
+firstkey ()
+{
+  datum ret_val;
+
+  /* Free previous dynamic memory, do actual call, and save pointer to new
+     memory. */
+  ret_val = gdbm_firstkey (_gdbm_file);
+  if (_gdbm_memory.dptr != NULL) free (_gdbm_memory.dptr);
+  _gdbm_memory = ret_val;
+
+  /* Return the new value. */
+  return ret_val;
+}
+
+
+/* Continue visiting all keys.  The next key following KEY is returned. */
+
+datum
+nextkey (key)
+     datum key;
+{
+  datum ret_val;
+
+  /* Make sure we have a valid key. */
+  if (key.dptr == NULL)
+    return key;
+
+  /* Call gdbm nextkey with supplied value. After that, free the old value. */
+  ret_val = gdbm_nextkey (_gdbm_file, key);
+  if (_gdbm_memory.dptr != NULL) free (_gdbm_memory.dptr);
+  _gdbm_memory = ret_val;
+
+  /* Return the new value. */
+  return ret_val;
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/store.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/store.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/store.c	(revision 20131)
@@ -0,0 +1,47 @@
+/* store.c - Add a new key/data pair to the database. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "extern.h"
+
+
+/* Add a new element to the database.  CONTENT is keyed by KEY.  The file on
+   disk is updated to reflect the structure of the new database before
+   returning from this procedure.  */
+
+int
+store (key, content)
+     datum key;
+     datum content;
+{
+  return gdbm_store (_gdbm_file, key, content, GDBM_REPLACE);
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/systems.h
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/systems.h	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/systems.h	(revision 20131)
@@ -0,0 +1,165 @@
+/* systems.h - Most of the system dependant code and defines are here. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* Include all system headers first. */
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <stdio.h>
+#if HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#include <sys/stat.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET        0
+#endif
+
+#ifndef L_SET
+#define L_SET SEEK_SET
+#endif
+
+/* Do we have flock?  (BSD...) */
+
+#if HAVE_FLOCK
+
+#ifndef LOCK_SH
+#define LOCK_SH	1
+#endif
+
+#ifndef LOCK_EX
+#define LOCK_EX	2
+#endif
+
+#ifndef LOCK_NB
+#define LOCK_NB 4
+#endif
+
+#ifndef LOCK_UN
+#define LOCK_UN 8
+#endif
+
+#define UNLOCK_FILE(dbf) flock (dbf->desc, LOCK_UN)
+#define READLOCK_FILE(dbf) lock_val = flock (dbf->desc, LOCK_SH + LOCK_NB)
+#define WRITELOCK_FILE(dbf) lock_val = flock (dbf->desc, LOCK_EX + LOCK_NB)
+
+#else
+
+#ifdef MSDOS
+#define MY_UNLOCK    0
+#define MY_READLOCK  1
+#define MY_WRITELOCK 2
+int my_locking(int fh, int lmode, long lockoffset, long nbytes);
+
+#define UNLOCK_FILE(dbf)    my_locking(dbf->desc,MY_UNLOCK,0,10)
+#define READLOCK_FILE(dbf)  lock_val=my_locking(dbf->desc,MY_READLOCK,0,10)
+#define WRITELOCK_FILE(dbf)	lock_val=my_locking(dbf->desc,MY_WRITELOCK,0,10)
+
+#else
+
+/* Assume it is done like System V. */
+
+#define UNLOCK_FILE(dbf) \
+	{					\
+	  struct flock flock;			\
+	  flock.l_type = F_UNLCK;		\
+	  flock.l_whence = SEEK_SET;		\
+	  flock.l_start = flock.l_len = 0L;	\
+	  fcntl (dbf->desc, F_SETLK, &flock);	\
+	}
+#define READLOCK_FILE(dbf) \
+	{					\
+	  struct flock flock;			\
+	  flock.l_type = F_RDLCK;		\
+	  flock.l_whence = SEEK_SET;			\
+	  flock.l_start = flock.l_len = 0L;	\
+	  lock_val = fcntl (dbf->desc, F_SETLK, &flock);	\
+	}
+#define WRITELOCK_FILE(dbf) \
+	{					\
+	  struct flock flock;			\
+	  flock.l_type = F_WRLCK;		\
+	  flock.l_whence = SEEK_SET;			\
+	  flock.l_start = flock.l_len = 0L;	\
+	  lock_val = fcntl (dbf->desc, F_SETLK, &flock);	\
+	}
+#endif
+#endif
+
+/* Do we have bcopy?  */
+#if !HAVE_BCOPY
+#if HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#define bcmp(d1, d2, n)	memcmp(d1, d2, n)
+#define bcopy(d1, d2, n) memcpy(d2, d1, n)
+#endif
+
+/* Do we have fsync? */
+#if !HAVE_FSYNC
+#ifdef MSDOS
+#define fsync(f)
+#else
+#define fsync(f) {sync(); sync();}
+#endif
+#endif
+
+/* Default block size.  Some systems do not have blocksize in their
+   stat record. This code uses the BSD blocksize from stat. */
+
+#if HAVE_STRUCT_STAT_ST_BLKSIZE
+#define STATBLKSIZE file_stat.st_blksize
+#else
+#define STATBLKSIZE 1024
+#endif
+
+/* Do we have ftruncate? */
+#if HAVE_FTRUNCATE
+#define TRUNCATE(dbf) ftruncate (dbf->desc, 0)
+#else
+#define TRUNCATE(dbf) close( open (dbf->name, O_RDWR|O_TRUNC, mode));
+#endif
+
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/testdbm.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/testdbm.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/testdbm.c	(revision 20131)
@@ -0,0 +1,218 @@
+/* testdbm.c - Driver program to test the dbm interface routines. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#include <sys/stat.h>
+
+#define TRUE  1
+#define FALSE 0
+
+typedef struct {
+  char *dptr;
+  int   dsize;
+} datum;
+
+extern datum fetch ();
+extern datum firstkey ();
+extern datum nextkey ();
+
+/* The test program allows one to call all the routines plus the hash function.
+   The commands are single letter commands.  The user is prompted for all other
+   information.  The commands are q (quit), f (fetch), s (store), d (delete),
+   1 (firstkey), n (nextkey) and h (hash function). */
+
+int
+main (argc, argv)
+     int argc;
+     char *argv[];
+{
+
+  char  cmd_ch;
+
+  datum key_data;
+  datum data_data;
+  datum return_data;
+
+  char key_line[500];
+  char data_line[1000];
+
+  char done = FALSE;
+  char sys[255];
+
+  char *file_name;
+
+  /* Argument checking. */
+  if (argc > 2)
+    {
+      printf ("Usage: %s [dbm-file] \n",argv[0]);
+      exit (2);
+    }
+
+  if (argc > 1)
+    {
+      file_name = argv[1];
+    }
+  else
+    {
+      file_name = "junkdbm";
+    }
+
+  /* Initialize */
+  data_data.dptr = data_line;
+
+  if (dbminit (file_name) != 0)
+    {
+      sprintf (sys,"touch %s.pag %s.dir", file_name, file_name);
+      system (sys);
+      if (dbminit (file_name) != 0)
+	{
+	  printf ("dbminit failed.\n");
+	  exit (2);
+	}
+    }
+
+  /* Welcome message. */
+  printf ("\nWelcome to the dbm test program.  Type ? for help.\n\n");
+  
+  while (!done)
+    {
+      printf ("com -> ");
+      cmd_ch = getchar ();
+      while (getchar () != '\n') /* Do nothing. */;
+      switch (cmd_ch)
+	{
+	case 'q':
+	  done = TRUE;
+	  break;
+
+	case 'f':
+	  printf ("key -> ");
+	  gets (key_line);
+	  key_data.dptr = key_line;
+	  key_data.dsize = strlen (key_line)+1;
+	  return_data = fetch (key_data);
+	  if (return_data.dptr != NULL)
+	      printf ("data is ->%s\n\n", return_data.dptr);
+	  else
+	    printf ("No such item found.\n\n");
+	  break;
+
+	case 's':
+	  printf ("key -> ");
+	  gets (key_line);
+	  key_data.dptr = key_line;
+	  key_data.dsize = strlen (key_line)+1;
+	  printf ("data -> ");
+	  gets (data_line);
+	  data_data.dsize = strlen (data_line)+1;
+	  if (store (key_data, data_data) != 0)
+	    printf ("Item not inserted. \n");
+	  printf ("\n");
+	  break;
+
+	case 'd':
+	  printf ("key -> ");
+	  gets (key_line);
+	  key_data.dptr = key_line;
+	  key_data.dsize = strlen (key_line)+1;
+	  if (delete (key_data) != 0)
+	    printf ("Item not found or deleted\n");
+	  printf ("\n");
+	  break;
+
+	case '1':
+	  key_data = firstkey ();
+	  if (key_data.dptr != NULL)
+	    {
+	      return_data = fetch (key_data);
+	      printf ("key  is ->%s\n", key_data.dptr);
+	      printf ("data is ->%s\n\n", return_data.dptr);
+	    }
+	  else
+	    printf ("No such item found.\n\n");
+	  break;
+
+
+	case '2':
+	  key_data = nextkey (key_data);
+	  if (key_data.dptr != NULL)
+	    {
+	      return_data = fetch (key_data);
+	      printf ("key  is ->%s\n", key_data.dptr);
+	      printf ("data is ->%s\n\n", return_data.dptr);
+	    }
+	  else
+	    printf ("No such item found.\n\n");
+	  break;
+
+	case 'c':
+	  {
+	    int temp;
+	    temp = 0;
+	    return_data = firstkey ();
+	    while (return_data.dptr != NULL)
+	      {
+		temp++;
+		return_data = nextkey (return_data);
+	      }
+	    printf ("There are %d items in the database.\n\n", temp);
+	  }
+	  break;
+
+	case '?':
+	  printf ("c - count elements\n");
+	  printf ("d - delete\n");
+	  printf ("f - fetch\n");
+	  printf ("q - quit\n");
+	  printf ("s - store\n");
+	  printf ("1 - firstkey\n");
+	  printf ("2 - nextkey on last return value\n\n");
+	  break;
+
+	default:
+	  printf ("What? \n\n");
+	  break;
+
+	}
+    }
+
+  /* Quit normally. */
+  exit (0);
+
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/testgdbm.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/testgdbm.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/testgdbm.c	(revision 20131)
@@ -0,0 +1,508 @@
+/* testgdbm.c - Driver program to test the database routines and to
+   help debug gdbm.  Uses inside information to show "system" information */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+#include "gdbmerrno.h"
+#include "extern.h"
+
+#include "getopt.h"
+
+extern const char * gdbm_version;
+
+extern const char *gdbm_strerror __P((gdbm_error));
+
+gdbm_file_info *gdbm_file;
+
+/* Debug procedure to print the contents of the current hash bucket. */
+void
+print_bucket (bucket, mesg)
+     hash_bucket *bucket;
+     char *mesg;
+{
+  int  index;
+
+  printf ("******* %s **********\n\nbits = %d\ncount= %d\nHash Table:\n",
+	 mesg, bucket->bucket_bits, bucket->count);
+  printf ("     #    hash value     key size    data size     data adr  home\n");
+  for (index = 0; index < gdbm_file->header->bucket_elems; index++)
+    printf ("  %4d  %12x  %11d  %11d  %11d %5d\n", index,
+	   bucket->h_table[index].hash_value,
+	   bucket->h_table[index].key_size,
+	   bucket->h_table[index].data_size,
+	   bucket->h_table[index].data_pointer,
+	   bucket->h_table[index].hash_value % gdbm_file->header->bucket_elems);
+
+  printf ("\nAvail count = %1d\n", bucket->av_count);
+  printf ("Avail  adr     size\n");
+  for (index = 0; index < bucket->av_count; index++)
+    printf ("%9d%9d\n", bucket->bucket_avail[index].av_adr,
+	                bucket->bucket_avail[index].av_size);
+}
+
+
+void
+_gdbm_print_avail_list (dbf)
+     gdbm_file_info *dbf;
+{
+  int temp;
+  int size;
+  avail_block *av_stk;
+ 
+  /* Print the the header avail block.  */
+  printf ("\nheader block\nsize  = %d\ncount = %d\n",
+	  dbf->header->avail.size, dbf->header->avail.count);
+  for (temp = 0; temp < dbf->header->avail.count; temp++)
+    {
+      printf ("  %15d   %10d \n", dbf->header->avail.av_table[temp].av_size,
+	      dbf->header->avail.av_table[temp].av_adr);
+    }
+
+  /* Initialize the variables for a pass throught the avail stack. */
+  temp = dbf->header->avail.next_block;
+  size = ( ( (dbf->header->avail.size * sizeof (avail_elem)) >> 1)
+	  + sizeof (avail_block));
+  av_stk = (avail_block *) malloc (size);
+  if (av_stk == NULL)
+    {
+      printf("Out of memory\n");
+      exit (2);
+    }
+
+  /* Print the stack. */
+  while (FALSE)
+    {
+      lseek (dbf->desc, temp, L_SET);
+      read  (dbf->desc, av_stk, size);
+
+      /* Print the block! */
+      printf ("\nblock = %d\nsize  = %d\ncount = %d\n", temp,
+	      av_stk->size, av_stk->count);
+      for (temp = 0; temp < av_stk->count; temp++)
+	{
+	  printf ("  %15d   %10d \n", av_stk->av_table[temp].av_size,
+	    av_stk->av_table[temp].av_adr);
+	}
+      temp = av_stk->next_block;
+    }
+}
+
+void
+_gdbm_print_bucket_cache (dbf)
+     gdbm_file_info *dbf;
+{
+  register int index;
+  char changed;
+ 
+  if (dbf->bucket_cache != NULL) {
+    printf(
+      "Bucket Cache (size %d):\n  Index:  Address  Changed  Data_Hash \n",
+      dbf->cache_size);
+    for (index=0; index < dbf->cache_size; index++) {
+      changed = dbf->bucket_cache[index].ca_changed;
+      printf ("  %5d:  %7d  %7s  %x\n",
+	      index,
+	      dbf->bucket_cache[index].ca_adr,
+	      (changed ? "True" : "False"),
+	      dbf->bucket_cache[index].ca_data.hash_val);
+    }
+  } else
+    printf("Bucket cache has not been initialized.\n");
+}
+
+void
+usage (s)
+     char *s;
+{
+  printf(
+      "Usage: %s [-r or -ns] [-b block-size] [-c cache-size] [-g gdbm-file]\n",
+      s);
+  exit (2);
+}
+
+
+/* The test program allows one to call all the routines plus the hash function.
+   The commands are single letter commands.  The user is prompted for all other
+   information.  See the help command (?) for a list of all commands. */
+
+int
+main (argc, argv)
+     int argc;
+     char *argv[];
+
+{
+
+  char  cmd_ch;
+
+  datum key_data;
+  datum data_data;
+  datum return_data;
+
+  char key_line[500];
+  char data_line[1000];
+
+  char done = FALSE;
+  int  opt;
+  char reader = FALSE;
+  char newdb = FALSE;
+  int  fast  = 0;
+
+  int  cache_size = DEFAULT_CACHESIZE;
+  int  block_size = 0;
+
+  char *file_name = NULL;
+
+
+  /* Argument checking. */
+  opterr = 0;
+  while ((opt = getopt (argc, argv, "srnc:b:g:")) != -1)
+    switch (opt) {
+    case 's':  fast = GDBM_SYNC;
+               if (reader) usage (argv[0]);
+               break;
+    case 'r':  reader = TRUE;
+               if (newdb) usage (argv[0]);
+               break;
+    case 'n':  newdb = TRUE;
+               if (reader) usage (argv[0]);
+               break;
+    case 'c':  cache_size = atoi(optarg);
+    	       break;
+    case 'b':  block_size = atoi(optarg);
+               break;
+    case 'g':  file_name = optarg;
+               break;
+    default:  usage(argv[0]);
+    }
+
+  if(file_name == NULL) 
+    file_name = "junk.gdbm";
+
+  /* Initialize variables. */
+  key_data.dptr = NULL;
+  data_data.dptr = data_line;
+
+  if (reader)
+    {
+      gdbm_file = gdbm_open (file_name, block_size, GDBM_READER, 00664, NULL);
+    }
+  else if (newdb)
+    {
+      gdbm_file =
+    	gdbm_open (file_name, block_size, GDBM_NEWDB | fast, 00664, NULL);
+    }
+  else
+    {
+      gdbm_file =
+    	gdbm_open (file_name, block_size, GDBM_WRCREAT | fast, 00664, NULL);
+    }
+  if (gdbm_file == NULL)
+    {
+      printf("gdbm_open failed, %s\n", gdbm_strerror(gdbm_errno));
+      exit (2);
+    }
+
+  if (gdbm_setopt(gdbm_file, GDBM_CACHESIZE, &cache_size, sizeof(int)) == -1)
+    {
+      printf("gdbm_setopt failed, %s\n", gdbm_strerror(gdbm_errno));
+      exit(2);
+    }
+
+  /* Welcome message. */
+  printf ("\nWelcome to the gdbm test program.  Type ? for help.\n\n");
+  
+  while (!done)
+    {
+      printf ("com -> ");
+      cmd_ch = getchar ();
+      if (cmd_ch != '\n')
+	{
+	  char temp;
+	  do
+	      temp = getchar ();
+	  while (temp != '\n' && temp != EOF);
+	}
+      if (cmd_ch == EOF) cmd_ch = 'q';
+      switch (cmd_ch)
+	{
+	
+	/* Standard cases found in all test{dbm,ndbm,gdbm} programs. */
+	case '\n':
+	  printf ("\n");
+	  break;
+
+	case 'c':
+	  {
+	    int temp;
+	    temp = 0;
+	    if (key_data.dptr != NULL) free (key_data.dptr);
+	    return_data = gdbm_firstkey (gdbm_file);
+	    while (return_data.dptr != NULL)
+	      {
+		temp++;
+		key_data = return_data;
+		return_data = gdbm_nextkey (gdbm_file, key_data);
+		free (key_data.dptr);
+	      }
+	    printf ("There are %d items in the database.\n\n", temp);
+	    key_data.dptr = NULL;
+	  }
+	  break;
+
+	case 'd':
+	  if (key_data.dptr != NULL) free (key_data.dptr);
+	  printf ("key -> ");
+	  gets (key_line);
+	  key_data.dptr = key_line;
+	  key_data.dsize = strlen (key_line)+1;
+	  if (gdbm_delete (gdbm_file, key_data) != 0)
+	    printf ("Item not found or deleted\n");
+	  printf ("\n");
+	  key_data.dptr = NULL;
+	  break;
+
+	case 'f':
+	  if (key_data.dptr != NULL) free (key_data.dptr);
+	  printf ("key -> ");
+	  gets (key_line);
+	  key_data.dptr = key_line;
+	  key_data.dsize = strlen (key_line)+1;
+	  return_data = gdbm_fetch (gdbm_file, key_data);
+	  if (return_data.dptr != NULL)
+	    {
+	      printf ("data is ->%s\n\n", return_data.dptr);
+	      free (return_data.dptr);
+	    }
+	  else
+	    printf ("No such item found.\n\n");
+	  key_data.dptr = NULL;
+	  break;
+
+	case 'n':
+	  if (key_data.dptr != NULL) free (key_data.dptr);
+	  printf ("key -> ");
+	  gets (key_line);
+	  key_data.dptr = key_line;
+	  key_data.dsize = strlen (key_line)+1;
+	  return_data = gdbm_nextkey (gdbm_file, key_data);
+	  if (return_data.dptr != NULL)
+	    {
+	      key_data = return_data;
+	      printf ("key is  ->%s\n", key_data.dptr);
+	      return_data = gdbm_fetch (gdbm_file, key_data);
+	      printf ("data is ->%s\n\n", return_data.dptr);
+	      free (return_data.dptr);
+	    }
+	  else
+	    {
+	      printf ("No such item found.\n\n");
+	      key_data.dptr = NULL;
+	    }
+	  break;
+
+	case 'q':
+	  done = TRUE;
+	  break;
+
+	case 's':
+	  if (key_data.dptr != NULL) free (key_data.dptr);
+	  printf ("key -> ");
+	  gets (key_line);
+	  key_data.dptr = key_line;
+	  key_data.dsize = strlen (key_line)+1;
+	  printf ("data -> ");
+	  gets (data_line);
+	  data_data.dsize = strlen (data_line)+1;
+	  if (gdbm_store (gdbm_file, key_data, data_data, GDBM_REPLACE) != 0)
+	    printf ("Item not inserted. \n");
+	  printf ("\n");
+	  key_data.dptr = NULL;
+	  break;
+
+	case '1':
+	  if (key_data.dptr != NULL) free (key_data.dptr);
+	  key_data = gdbm_firstkey (gdbm_file);
+	  if (key_data.dptr != NULL)
+	    {
+	      printf ("key is  ->%s\n", key_data.dptr);
+	      return_data = gdbm_fetch (gdbm_file, key_data);
+	      printf ("data is ->%s\n\n", return_data.dptr);
+	      free (return_data.dptr);
+	    }
+	  else
+	    printf ("No such item found.\n\n");
+	  break;
+
+	case '2':
+	  return_data = gdbm_nextkey (gdbm_file, key_data);
+	  if (return_data.dptr != NULL)
+	    {
+	      free (key_data.dptr);
+	      key_data = return_data;
+	      printf ("key is  ->%s\n", key_data.dptr);
+	      return_data = gdbm_fetch (gdbm_file, key_data);
+	      printf ("data is ->%s\n\n", return_data.dptr);
+	      free (return_data.dptr);
+	    }
+	  else
+	    printf ("No such item found.\n\n");
+	  break;
+
+
+	/* Special cases for the testgdbm program. */
+	case 'r':
+	  {
+	    if (gdbm_reorganize (gdbm_file))
+	      printf ("Reorganization failed. \n\n");
+	    else
+	      printf ("Reorganization succeeded. \n\n");
+	  }
+	  break;
+
+	case 'A':
+	  _gdbm_print_avail_list (gdbm_file);
+	  printf ("\n");
+	  break;
+
+	case 'B':
+	  {
+	    int temp;
+	    char number[80];
+
+	    printf ("bucket? ");
+	    gets (number);
+	    sscanf (number,"%d",&temp);
+
+	    if (temp >= gdbm_file->header->dir_size /4)
+	      {
+		printf ("Not a bucket. \n\n");
+		break;
+	      }
+	    _gdbm_get_bucket (gdbm_file, temp);
+	  }
+	  printf ("Your bucket is now ");
+
+	case 'C':
+	  print_bucket (gdbm_file->bucket, "Current bucket");
+	  printf ("\n current directory entry = %d.\n", gdbm_file->bucket_dir);
+	  printf (" current bucket address  = %d.\n\n",
+		  gdbm_file->cache_entry->ca_adr);
+	  break;
+
+	case 'D':
+	  printf ("Hash table directory.\n");
+	  printf ("  Size =  %d.  Bits = %d. \n\n",gdbm_file->header->dir_size,
+		  gdbm_file->header->dir_bits);
+	  {
+	    int temp;
+
+	    for (temp = 0; temp < gdbm_file->header->dir_size / 4; temp++)
+	      {
+		printf ("  %10d:  %12d\n", temp, gdbm_file->dir[temp]);
+		if ( (temp+1) % 20 == 0 && isatty (0))
+		  {
+		    printf ("*** CR to continue: ");
+		    while (getchar () != '\n') /* Do nothing. */;
+		  }
+	      }
+	  }
+	  printf ("\n");
+	  break;
+
+	case 'F':
+	  {
+	    printf ("\nFile Header: \n\n");
+	    printf ("  table        = %d\n", gdbm_file->header->dir);
+	    printf ("  table size   = %d\n", gdbm_file->header->dir_size);
+	    printf ("  table bits   = %d\n", gdbm_file->header->dir_bits);
+	    printf ("  block size   = %d\n", gdbm_file->header->block_size);
+	    printf ("  bucket elems = %d\n", gdbm_file->header->bucket_elems);
+	    printf ("  bucket size  = %d\n", gdbm_file->header->bucket_size);
+	    printf ("  header magic = %x\n", gdbm_file->header->header_magic);
+	    printf ("  next block   = %d\n", gdbm_file->header->next_block);
+	    printf ("  avail size   = %d\n", gdbm_file->header->avail.size);
+	    printf ("  avail count  = %d\n", gdbm_file->header->avail.count);
+	    printf ("  avail nx blk = %d\n", gdbm_file->header->avail.next_block);
+	    printf ("\n");
+	  }
+	  break;
+
+        case 'H':
+	  if (key_data.dptr != NULL) free (key_data.dptr);
+	  printf ("key -> ");
+	  gets (key_line);
+	  key_data.dptr = key_line;
+	  key_data.dsize = strlen (key_line)+1;
+	  printf ("hash value = %x. \n\n", _gdbm_hash (key_data));
+	  key_data.dptr = NULL;
+	  break;
+
+	case 'K':
+	  _gdbm_print_bucket_cache (gdbm_file);
+	  break;
+
+	case 'V':
+	  printf ("%s\n\n", gdbm_version);
+	  break;
+
+	case '?':
+	  printf ("c - count (number of entries)\n");
+	  printf ("d - delete\n");
+	  printf ("f - fetch\n");
+	  printf ("n - nextkey\n");
+	  printf ("q - quit\n");
+	  printf ("s - store\n");
+	  printf ("1 - firstkey\n");
+	  printf ("2 - nextkey on last key (from n, 1 or 2)\n\n");
+
+	  printf ("r - reorganize\n");
+	  printf ("A - print avail list\n");
+	  printf ("B - get and print current bucket n\n");
+	  printf ("C - print current bucket\n");
+	  printf ("D - print hash directory\n");
+	  printf ("F - print file header\n");
+	  printf ("H - hash value of key\n");
+	  printf ("K - print the bucket cache\n");
+	  printf ("V - print version of gdbm\n");
+	  break;
+
+	default:
+	  printf ("What? \n\n");
+	  break;
+
+	}
+    }
+
+  /* Quit normally. */
+  exit (0);
+
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/testndbm.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/testndbm.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/testndbm.c	(revision 20131)
@@ -0,0 +1,216 @@
+/* testndbm.c - Driver program to test the ndbm interface routines. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_FILE_H
+#include <sys/file.h>
+#endif
+#include <sys/stat.h>
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef GNU
+#include "ndbm.h"
+#else
+#include <ndbm.h>
+#endif
+
+#define TRUE  1
+#define FALSE 0
+
+
+/* The test program allows one to call all the routines plus the hash function.
+   The commands are single letter commands.  The user is prompted for all other
+   information.  The commands are q (quit), f (fetch), s (store), d (delete),
+   1 (firstkey), n (nextkey) and h (hash function). */
+
+int
+main (argc, argv)
+     int argc;
+     char *argv[];
+{
+
+  char  cmd_ch;
+
+  datum key_data;
+  datum data_data;
+  datum return_data;
+
+  char key_line[500];
+  char data_line[1000];
+
+  DBM *dbm_file;
+
+  char done = FALSE;
+
+  char *file_name;
+
+  /* Argument checking. */
+  if (argc > 2)
+    {
+      printf ("Usage: %s [dbm-file] \n",argv[0]);
+      exit (2);
+    }
+
+  if (argc > 1)
+    {
+      file_name = argv[1];
+    }
+  else
+    {
+      file_name = "junkndbm";
+    }
+
+  /* Initialize. */
+  data_data.dptr = data_line;
+
+  dbm_file = dbm_open (file_name, O_RDWR|O_CREAT, 00664);
+  if (dbm_file == NULL)
+    {
+      printf ("dbm_open failed.\n");
+      exit (2);
+    }
+
+  /* Welcome message. */
+  printf ("\nWelcome to the gndbm test program.  Type ? for help.\n\n");
+  
+  while (!done)
+    {
+      printf ("com -> ");
+      cmd_ch = getchar ();
+      while (getchar () != '\n') /* Do nothing. */;
+      switch (cmd_ch)
+	{
+	case 'q':
+	  done = TRUE;
+	  break;
+
+	case 'f':
+	  printf ("key -> ");
+	  gets (key_line);
+	  key_data.dptr = key_line;
+	  key_data.dsize = strlen (key_line)+1;
+	  return_data = dbm_fetch (dbm_file, key_data);
+	  if (return_data.dptr != NULL)
+	      printf ("data is ->%s\n\n", return_data.dptr);
+	  else
+	    printf ("No such item found.\n\n");
+	  break;
+
+	case 's':
+	  printf ("key -> ");
+	  gets (key_line);
+	  key_data.dptr = key_line;
+	  key_data.dsize = strlen (key_line)+1;
+	  printf ("data -> ");
+	  gets (data_line);
+	  data_data.dsize = strlen (data_line)+1;
+	  if (dbm_store (dbm_file, key_data, data_data, DBM_REPLACE) != 0)
+	    printf ("Item not inserted. \n");
+	  printf ("\n");
+	  break;
+
+	case 'd':
+	  printf ("key -> ");
+	  gets (key_line);
+	  key_data.dptr = key_line;
+	  key_data.dsize = strlen (key_line)+1;
+	  if (dbm_delete (dbm_file, key_data) != 0)
+	    printf ("Item not found or deleted\n");
+	  printf ("\n");
+	  break;
+
+	case '1':
+	  key_data = dbm_firstkey (dbm_file);
+	  if (key_data.dptr != NULL)
+	    {
+	      return_data = dbm_fetch (dbm_file, key_data);
+	      printf ("key is ->%s\n", key_data.dptr);
+	      printf ("data is ->%s\n\n", return_data.dptr);
+	    }
+	  else
+	    printf ("No such item found.\n\n");
+	  break;
+
+
+	case '2':
+	  key_data = dbm_nextkey (dbm_file);
+	  if (key_data.dptr != NULL)
+	    {
+	      return_data = dbm_fetch (dbm_file, key_data);
+	      printf ("key is ->%s\n", key_data.dptr);
+	      printf ("data is ->%s\n\n", return_data.dptr);
+	    }
+	  else
+	    printf ("No such item found.\n\n");
+	  break;
+
+	case 'c':
+	  {
+	    int temp;
+	    temp = 0;
+	    return_data = dbm_firstkey (dbm_file);
+	    while (return_data.dptr != NULL)
+	      {
+		temp++;
+		return_data = dbm_nextkey (dbm_file);
+	      }
+	    printf ("There are %d items in the database.\n\n", temp);
+	  }
+	  break;
+
+	case '?':
+	  printf ("c - count elements\n");
+	  printf ("d - delete\n");
+	  printf ("f - fetch\n");
+	  printf ("q - quit\n");
+	  printf ("s - store\n");
+	  printf ("1 - firstkey\n");
+	  printf ("2 - nextkey on last return value\n\n");
+	  break;
+
+	default:
+	  printf ("What? \n\n");
+	  break;
+
+	}
+    }
+
+  /* Quit normally. */
+  dbm_close (dbm_file);
+  exit (0);
+
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/update.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/update.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/update.c	(revision 20131)
@@ -0,0 +1,132 @@
+/* update.c - The routines for updating the file to a consistent state. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+
+/* include system configuration before all else. */
+#include "autoconf.h"
+
+#include "gdbmdefs.h"
+
+static void write_header __P((gdbm_file_info *));
+
+/* This procedure writes the header back to the file described by DBF. */
+
+static void
+write_header (dbf)
+     gdbm_file_info *dbf;
+{
+  int  num_bytes;	/* Return value for write. */
+  off_t file_pos;	/* Return value for lseek. */
+
+  file_pos = lseek (dbf->desc, 0L, L_SET);
+  if (file_pos != 0) _gdbm_fatal (dbf, "lseek error");
+  num_bytes = write (dbf->desc, dbf->header, dbf->header->block_size);
+  if (num_bytes != dbf->header->block_size)
+    _gdbm_fatal (dbf, "write error");
+
+  /* Wait for all output to be done. */
+  if (!dbf->fast_write)
+    fsync (dbf->desc);
+}
+
+
+/* After all changes have been made in memory, we now write them
+   all to disk. */
+void
+_gdbm_end_update (dbf)
+     gdbm_file_info *dbf;
+{
+  int  num_bytes;	/* Return value for write. */
+  off_t file_pos;	/* Return value for lseek. */
+  
+  
+  /* Write the current bucket. */
+  if (dbf->bucket_changed && (dbf->cache_entry != NULL))
+    {
+      _gdbm_write_bucket (dbf, dbf->cache_entry);
+      dbf->bucket_changed = FALSE;
+    }
+
+  /* Write the other changed buckets if there are any. */
+  if (dbf->second_changed)
+    {
+      if(dbf->bucket_cache != NULL)
+        {
+          register int index;
+
+          for (index = 0; index < dbf->cache_size; index++)
+	    {
+	      if (dbf->bucket_cache[index].ca_changed)
+	        _gdbm_write_bucket (dbf, &dbf->bucket_cache[index]);
+            }
+        }
+      dbf->second_changed = FALSE;
+    }
+  
+  /* Write the directory. */
+  if (dbf->directory_changed)
+    {
+      file_pos = lseek (dbf->desc, dbf->header->dir, L_SET);
+      if (file_pos != dbf->header->dir) _gdbm_fatal (dbf, "lseek error");
+      num_bytes = write (dbf->desc, dbf->dir, dbf->header->dir_size);
+      if (num_bytes != dbf->header->dir_size)
+	_gdbm_fatal (dbf, "write error");
+      dbf->directory_changed = FALSE;
+      if (!dbf->header_changed && !dbf->fast_write)
+	fsync (dbf->desc);
+    }
+
+  /* Final write of the header. */
+  if (dbf->header_changed)
+    {
+      write_header (dbf);
+      dbf->header_changed = FALSE;
+    }
+}
+
+
+/* If a fatal error is detected, come here and exit. VAL tells which fatal
+   error occured. */
+
+void
+_gdbm_fatal (dbf, val)
+     gdbm_file_info *dbf;
+     char *val;
+{
+  if ((dbf != NULL) && (dbf->fatal_err != NULL))
+    (*dbf->fatal_err) (val);
+  else
+    {
+      write (STDERR_FILENO, "gdbm fatal: ", 12);
+      if (val != NULL)
+	write (STDERR_FILENO, val, strlen(val));
+      write (STDERR_FILENO, "\n", 1);
+    }
+  exit (1);
+  /* NOTREACHED */
+}
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/version.c
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/version.c	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/version.c	(revision 20131)
@@ -0,0 +1,36 @@
+/* version.c - This is file contains the version number for gdbm source. */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+#include "autoconf.h"
+
+/* Keep a string with the version number in it! */
+const char * gdbm_version = "GDBM version 1.8.3. 10/15/2002"
+#if defined(__STDC__) && defined(__DATE__) && defined(__TIME__)
+		" (built " __DATE__ " " __TIME__ ")"
+#endif
+		;
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/win32.mak
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/win32.mak	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/win32.mak	(revision 20131)
@@ -0,0 +1,76 @@
+###########################################################################
+#
+# win32 makefile -- gdbm
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+DEBUG = 0
+
+AR = lib
+CC = cl
+
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+DEFS = -D__WIN32__ -D_CRT_SECURE_NO_DEPRECATE
+INCLUDES = -I"windows"
+LDFLAGS =
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+
+o = .obj
+
+.SUFFIXES:
+.SUFFIXES: .c $o
+
+.c$o:
+	$(COMPILE) $<
+
+HEADERS = gdbmdefs.h extern.h gdbmerrno.h systems.h gdbmconst.h \
+          proto.h
+
+SOURCES = gdbmopen.c gdbmdelete.c gdbmfetch.c  gdbmstore.c gdbmclose.c \
+	  gdbmreorg.c gdbmseq.c gdbmsync.c gdbmerrno.c gdbmexists.c gdbmsetopt.c \
+	  bucket.c falloc.c findkey.c global.c hash.c update.c \
+	  version.c gsdlmods.c
+
+OBJECTS = gdbmopen$o gdbmdelete$o gdbmfetch$o  gdbmstore$o gdbmclose$o \
+	  gdbmreorg$o gdbmseq$o gdbmsync$o gdbmerrno$o gdbmexists$o gdbmsetopt$o \
+	  bucket$o falloc$o findkey$o global$o hash$o update$o \
+	  version$o gsdlmods$o
+
+all: gdbm.lib
+
+gdbm.lib: $(OBJECTS)
+	  if EXIST gdbm.lib del gdbm.lib
+	  $(AR) -nologo /out:gdbm.lib $(OBJECTS) 
+
+install:
+
+clean:
+	del gdbm.lib
+	del *$o
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/windows/autoconf.h
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/windows/autoconf.h	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/windows/autoconf.h	(revision 20131)
@@ -0,0 +1,94 @@
+/* autoconf.h.in.  Generated from configure.in by autoheader.  */
+
+#define MSDOS
+
+/* Define to 1 if you have the `bcopy' function. */
+#undef HAVE_BCOPY
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `flock' function. */
+#undef HAVE_FLOCK
+
+/* Define to 1 if you have the `fsync' function. */
+#undef HAVE_FSYNC
+
+/* Define to 1 if you have the `ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Define to 1 if you have the `getopt' function. */
+#undef HAVE_GETOPT
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `dbm' library (-ldbm). */
+#undef HAVE_LIBDBM
+
+/* Define to 1 if you have the `ndbm' library (-lndbm). */
+#undef HAVE_LIBNDBM
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `rename' function. */
+#undef HAVE_RENAME
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if `st_blksize' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLKSIZE
+
+/* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use
+   `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */
+#undef HAVE_ST_BLKSIZE
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `long' if <sys/types.h> does not define. */
+#undef off_t
Index: /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/windows/gdbm.h
===================================================================
--- /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/windows/gdbm.h	(revision 20131)
+++ /gsdl/stable/common-src/packages/gdbm/gdbm-1.8.3/windows/gdbm.h	(revision 20131)
@@ -0,0 +1,143 @@
+/* gdbm.h  -  The include file for dbm users.  */
+
+/*  This file is part of GDBM, the GNU data base manager, by Philip A. Nelson.
+    Copyright (C) 1990, 1991, 1993  Free Software Foundation, Inc.
+
+    GDBM is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+
+    GDBM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with GDBM; see the file COPYING.  If not, write to
+    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    You may contact the author by:
+       e-mail:  phil@cs.wwu.edu
+      us-mail:  Philip A. Nelson
+                Computer Science Department
+                Western Washington University
+                Bellingham, WA 98226
+       
+*************************************************************************/
+
+/* Protection for multiple includes. */
+#ifndef _GDBM_H_
+#define _GDBM_H_
+
+/* Parameters to gdbm_open for READERS, WRITERS, and WRITERS who
+   can create the database. */
+#define  GDBM_READER  0		/* A reader. */
+#define  GDBM_WRITER  1		/* A writer. */
+#define  GDBM_WRCREAT 2		/* A writer.  Create the db if needed. */
+#define  GDBM_NEWDB   3		/* A writer.  Always create a new db. */
+#define  GDBM_FAST    0x10	/* Write fast! => No fsyncs.  OBSOLETE. */
+#define  GDBM_SYNC    0x20	/* Sync operations to the disk. */
+#define  GDBM_NOLOCK  0x40	/* Don't do file locking operations. */
+
+/* Parameters to gdbm_store for simple insertion or replacement in the
+   case that the key is already in the database. */
+#define  GDBM_INSERT  0		/* Never replace old data with new. */
+#define  GDBM_REPLACE 1		/* Always replace old data with new. */
+
+/* Parameters to gdbm_setopt, specifing the type of operation to perform. */
+#define  GDBM_CACHESIZE 1       /* Set the cache size. */
+#define  GDBM_FASTMODE  2       /* Toggle fast mode.  OBSOLETE. */
+#define  GDBM_SYNCMODE	3	/* Turn on or off sync operations. */
+#define  GDBM_CENTFREE  4	/* Keep all free blocks in the header. */
+#define  GDBM_COALESCEBLKS 5	/* Attempt to coalesce free blocks. */
+
+/* The data and key structure.  This structure is defined for compatibility. */
+typedef struct {
+	char *dptr;
+	int   dsize;
+      } datum;
+
+
+/* The file information header. This is good enough for most applications. */
+typedef struct {int dummy[10];} *GDBM_FILE;
+
+/* Determine if the C(++) compiler requires complete function prototype  */
+#ifndef __P
+#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
+#define __P(x) x
+#else
+#define __P(x) ()
+#endif
+#endif
+
+/* External variable, the gdbm build release string. */
+extern char *gdbm_version;	
+
+
+/* GDBM C++ support */
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* These are the routines! */
+
+#ifdef MSDOS
+extern GDBM_FILE gdbm_open __P((char *, int, int, int, void (*)(), int));
+#else
+extern GDBM_FILE gdbm_open __P((char *, int, int, int, void (*)()));
+#endif
+extern void gdbm_close __P((GDBM_FILE));
+extern int gdbm_store __P((GDBM_FILE, datum, datum, int));
+extern datum gdbm_fetch __P((GDBM_FILE, datum));
+extern int gdbm_delete __P((GDBM_FILE, datum));
+extern datum gdbm_firstkey __P((GDBM_FILE));
+extern datum gdbm_nextkey __P((GDBM_FILE, datum));
+extern int gdbm_reorganize __P((GDBM_FILE));
+extern void gdbm_sync __P((GDBM_FILE));
+extern int gdbm_exists __P((GDBM_FILE, datum));
+extern int gdbm_setopt __P((GDBM_FILE, int, int *, int));
+extern int gdbm_fdesc __P((GDBM_FILE));
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#define	GDBM_NO_ERROR		0
+#define	GDBM_MALLOC_ERROR	1
+#define	GDBM_BLOCK_SIZE_ERROR	2
+#define	GDBM_FILE_OPEN_ERROR	3
+#define	GDBM_FILE_WRITE_ERROR	4
+#define	GDBM_FILE_SEEK_ERROR	5
+#define	GDBM_FILE_READ_ERROR	6
+#define	GDBM_BAD_MAGIC_NUMBER	7
+#define	GDBM_EMPTY_DATABASE	8
+#define	GDBM_CANT_BE_READER	9
+#define	GDBM_CANT_BE_WRITER	10
+#define	GDBM_READER_CANT_DELETE	11
+#define	GDBM_READER_CANT_STORE	12
+#define	GDBM_READER_CANT_REORGANIZE	13
+#define	GDBM_UNKNOWN_UPDATE	14
+#define	GDBM_ITEM_NOT_FOUND	15
+#define	GDBM_REORGANIZE_FAILED	16
+#define	GDBM_CANNOT_REPLACE	17
+#define	GDBM_ILLEGAL_DATA	18
+#define	GDBM_OPT_ALREADY_SET	19
+#define	GDBM_OPT_ILLEGAL	20
+typedef int gdbm_error;		/* For compatibilities sake. */
+extern gdbm_error gdbm_errno;
+
+/* extra prototypes */
+
+/* GDBM C++ support */
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+extern char *gdbm_strerror __P((gdbm_error));
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
Index: /gsdl/stable/common-src/packages/sqlite/README.txt
===================================================================
--- /gsdl/stable/common-src/packages/sqlite/README.txt	(revision 20131)
+++ /gsdl/stable/common-src/packages/sqlite/README.txt	(revision 20131)
@@ -0,0 +1,10 @@
+This package contains the source code for the sqlite3 executable and library in
+amalgamated form, as downloaded from http://www.sqlite.org. The only modifications
+have been to add a win32.mak file for compiling on Windows.
+
+SQLite is in the public domain and is thus free for use for any purpose,
+commercial or private.
+
+30 May 2008
+Michael Dewsnip
+DL Consulting Ltd. (http://www.dlconsulting.com)
Index: /gsdl/stable/common-src/packages/windows/crypt/README.TXT
===================================================================
--- /gsdl/stable/common-src/packages/windows/crypt/README.TXT	(revision 20131)
+++ /gsdl/stable/common-src/packages/windows/crypt/README.TXT	(revision 20131)
@@ -0,0 +1,7 @@
+This directory contains a win32 port of the crypt library (see the enclosed
+README files for details). To compile with Microsoft Visual C++ unzip
+crypt.zip and run "nmake /f win32.mak" in the top level directory.
+
+Link crypt.lib with your project when compiling Greenstone.
+
+Stefan Boddie (sjboddie@cs.waikato.ac.nz)
Index: /gsdl/stable/common-src/src/gdbmedit/db2txt/Makefile.in
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/db2txt/Makefile.in	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/db2txt/Makefile.in	(revision 20131)
@@ -0,0 +1,82 @@
+###########################################################################
+#
+# Makefile -- common-src/src/gdbmedit/db2txt
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+
+
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@
+GSDLOS = @gsdlos@
+INCLUDES = -I$(COMMON_PACKAGES_DIR)/gdbm/include -I$(COMMON_DIR)/src/lib
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@ @COMPAT32BITFLAGS@
+LIBS = @LIBS@ $(COMMON_PACKAGES_DIR)/gdbm/lib/libgdbm.a
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+CXXLINK = $(CXX) $(LDFLAGS) -o $@
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+SOURCES = \
+	db2txt.cpp
+
+OBJECTS = \
+	db2txt.o
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS)
+
+EXECUTABLE = db2txt
+
+
+# Default target: make the db2txt executable
+all: $(EXECUTABLE)
+
+db2txt: $(EXECUTABLE_OBJECTS)
+	$(CXXLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	$(INSTALL) -d $(GSDL_DIR)/bin/$(GSDLOS)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/bin/$(GSDLOS)
+
+clean:
+	rm -f $(OBJECTS) $(EXECUTABLE)
+
+distclean:
+	rm -f $(OBJECTS) $(EXECUTABLE) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/common-src/src/gdbmedit/db2txt/db2txt.cpp
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/db2txt/db2txt.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/db2txt/db2txt.cpp	(revision 20131)
@@ -0,0 +1,107 @@
+/**********************************************************************
+ *
+ * db2txt.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifdef __WIN32__
+#include "autoconf.h"
+#include "systems.h"
+#include "gdbmconst.h"
+#include "gdbm.h"
+
+#else
+#include <gdbm.h>
+#endif
+
+#include "gsdlconf.h"
+#include <stdlib.h>
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+// use the standard namespace
+#if !defined (GSDL_NAMESPACE_BROKEN)
+#if defined(GSDL_USE_OBJECTSPACE)
+using namespace ospace::std;
+#else
+using namespace std;
+#endif
+#endif
+
+void print_usage (char *program_name) {
+  cerr << "usage: " << program_name << " database-name" << endl << endl;
+}
+
+
+int main (int argc, char *argv[]) {
+  int block_size = 0, i;
+  GDBM_FILE dbf;
+  datum key, value, nextkey;
+      
+  // sanity check
+  if (argc != 2) {
+    print_usage (argv[0]);
+    exit (0);
+  }
+  
+  // open the database
+#ifdef __WIN32__
+  dbf = gdbm_open (argv[1], block_size, GDBM_READER, 00664, NULL, 0);
+#else
+  dbf = gdbm_open  (argv[1], block_size, GDBM_READER, 00664, NULL);
+#endif
+  if (dbf == NULL) {
+    cerr << "couldn't open " << argv[1] << endl;
+    exit (0);
+  }
+
+  key = gdbm_firstkey (dbf);
+  while (key.dptr != NULL) {
+    cout << "[";
+    for (i = 0; i < key.dsize; ++i)
+      cout << key.dptr[i];
+    cout << "]" << endl;
+    value = gdbm_fetch (dbf, key);
+    for (i = 0; i < value.dsize; ++i)
+      cout << value.dptr[i];
+    cout << endl << "----------------------------------------------------------------------" << endl;
+    free(value.dptr);
+
+    /* get next key */
+    nextkey = gdbm_nextkey (dbf, key);
+
+    /* free old key's dptr, otherwise causes memory leak */
+    free(key.dptr); 
+    
+    /* can now safely copy content of nextkey into key */
+    key = nextkey;
+  }
+  
+  gdbm_close (dbf);
+  return 0;
+}
Index: /gsdl/stable/common-src/src/gdbmedit/db2txt/win32.mak
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/db2txt/win32.mak	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/db2txt/win32.mak	(revision 20131)
@@ -0,0 +1,93 @@
+###########################################################################
+#
+# win32 makefile -- db2txt
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDLHOME = ..\..\..\..
+COMMON_DIR = ..\..\..
+
+DEBUG = 0
+GSDL_VC4 = 0
+STLPATH = "$(COMMON_DIR)\packages\windows\stlport\stlport"
+
+AR = lib
+CC = cl
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+LDFLAGS =
+
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H -D_CRT_SECURE_NO_DEPRECATE
+INCLUDES = -I"$(COMMON_DIR)\src\gdbmedit\db2txt" -I"$(COMMON_DIR)\src\lib" -I"$(COMMON_DIR)\indexers\mg\lib" \
+	   -I"$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3" -I"$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3\windows"
+!IF $(GSDL_VC4)
+DEFS=$(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I$(STLPATH)
+!ENDIF
+
+LIBS = "$(COMMON_DIR)\indexers\mg\lib\unitool.obj" "$(COMMON_DIR)\src\lib\gsdllib.lib" \
+       "$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3\gdbm.lib"
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) -nologo $(LDFLAGS)
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $<
+
+ANSI2KNR = 
+o = .obj
+e = .exe
+
+HEADERS = 
+
+SOURCES = db2txt.cpp
+
+OBJECTS = db2txt$o
+
+EXEC = db2txt$e
+
+all : $(EXEC)
+
+install: $(EXEC)
+	if NOT EXIST "$(GSDLHOME)\bin\windows" mkdir "$(GSDLHOME)\bin\windows"
+	copy $(EXEC) "$(GSDLHOME)\bin\windows"
+
+clean:
+	del *$o
+	del $(EXEC)
+
+db2txt$e: $(OBJECTS) $(LIBS)
+	  $(LINK) $(OBJECTS) $(LIBS)
Index: /gsdl/stable/common-src/src/gdbmedit/gdbmdel/Makefile.in
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/gdbmdel/Makefile.in	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/gdbmdel/Makefile.in	(revision 20131)
@@ -0,0 +1,82 @@
+###########################################################################
+#
+# Makefile -- common-src/src/gdbmedit/gdbmdel
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+
+
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@
+GSDLOS = @gsdlos@
+INCLUDES = -I$(COMMON_PACKAGES_DIR)/gdbm/include -I$(COMMON_DIR)/src/lib
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@ @COMPAT32BITFLAGS@
+LIBS = @LIBS@ $(COMMON_PACKAGES_DIR)/gdbm/lib/libgdbm.a
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+CXXLINK = $(CXX) $(LDFLAGS) -o $@
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+SOURCES = \
+	gdbmdel.cpp
+
+OBJECTS = \
+	gdbmdel.o
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS)
+
+EXECUTABLE = gdbmdel
+
+
+# Default target: make the gdbmdel executable
+all: $(EXECUTABLE)
+
+gdbmdel: $(EXECUTABLE_OBJECTS)
+	$(CXXLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	$(INSTALL) -d $(GSDL_DIR)/bin/$(GSDLOS)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/bin/$(GSDLOS)
+
+clean:
+	rm -f $(OBJECTS) $(EXECUTABLE)
+
+distclean:
+	rm -f $(OBJECTS) $(EXECUTABLE) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/common-src/src/gdbmedit/gdbmdel/gdbmdel.cpp
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/gdbmdel/gdbmdel.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/gdbmdel/gdbmdel.cpp	(revision 20131)
@@ -0,0 +1,108 @@
+/**********************************************************************
+ *
+ * gdbmdel -- retrieve a single value from the GDBM database
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifdef __WIN32__
+#include "autoconf.h"
+#include "systems.h"
+#include "gdbmconst.h"
+#include "gdbm.h"
+
+#else
+#include <gdbm.h>
+#endif
+
+#include "gsdlconf.h"
+#include <stdlib.h>
+#include <cstring>
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+// use the standard namespace
+#if !defined (GSDL_NAMESPACE_BROKEN)
+#if defined(GSDL_USE_OBJECTSPACE)
+using namespace ospace::std;
+#else
+using namespace std;
+#endif
+#endif
+
+void 
+print_usage (char *program_name) 
+{
+  cerr << "usage: " << program_name << " <database_path> <key>" << endl;
+  cerr << endl;
+}
+
+
+int main (int argc, char *argv[]) 
+{
+  int block_size = 0;
+  GDBM_FILE dbf;
+  datum key;
+  
+  // sanity check
+  if (argc != 3) 
+    {
+      print_usage (argv[0]);
+      exit (-1);
+    }
+  
+  // open the database
+#ifdef __WIN32__
+  dbf = gdbm_open (argv[1], block_size, GDBM_WRCREAT, 00664, NULL, 1);
+#else
+  dbf = gdbm_open  (argv[1], block_size, GDBM_WRCREAT, 00664, NULL);
+#endif
+  if (dbf == NULL) 
+    {
+      cerr << "Couldn't open " << argv[1] << endl;
+      exit (-1);
+    }
+  
+  key.dsize = strlen(argv[2]);
+  key.dptr = argv[2];
+
+  int status = gdbm_delete (dbf, key); 
+  
+  // status:
+  //   0 == delete OK
+  //  -1 == key does not exist or there was an error
+
+  if (status < 0) {
+    cerr << "Opened database " << argv[1] << endl;
+    cerr << "  but couldn't delete: " << argv[2] << endl;
+  }
+
+  gdbm_close (dbf);
+
+  return status; 
+}
+
Index: /gsdl/stable/common-src/src/gdbmedit/gdbmdel/win32.mak
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/gdbmdel/win32.mak	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/gdbmdel/win32.mak	(revision 20131)
@@ -0,0 +1,93 @@
+###########################################################################
+#
+# win32 makefile -- gdbmdel
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDLHOME = ..\..\..\..
+COMMON_DIR = ..\..\..
+
+USE_STLPORT = 0
+STLPATH = "$(COMMON_DIR)\packages\windows\stlport\stlport"
+
+AR = lib
+CC = cl
+DEBUG = 0
+GSDL_VC4 = 0
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+LDFLAGS =
+
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H
+INCLUDES = -I"$(COMMON_DIR)\src\gdbmedit\gdbmdel" -I"$(COMMON_DIR)\src\lib" -I"$(COMMON_DIR)\indexers\mg\lib" \
+	   -I"$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3" -I"$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3\windows"
+!IF $(USE_STLPORT)
+DEFS=$(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I$(STLPATH)
+!ENDIF
+
+LIBS = "$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3\gdbm.lib"
+
+COMPILE = $(CC) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) $(LDFLAGS)
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $<
+
+ANSI2KNR = 
+o = .obj
+e = .exe
+
+HEADERS = 
+
+SOURCES = gdbmdel.cpp
+
+OBJECTS = gdbmdel$o
+
+EXEC = gdbmdel$e
+
+all : $(EXEC)
+
+install: $(EXEC)
+	if NOT EXIST "$(GSDLHOME)\bin\windows" mkdir "$(GSDLHOME)\bin\windows"
+	copy $(EXEC) "$(GSDLHOME)\bin\windows"
+
+clean:
+	del *$o
+	del $(EXEC)
+
+gdbmdel$e: $(OBJECTS) $(LIBS)
+	  $(LINK) $(OBJECTS) $(LIBS)
Index: /gsdl/stable/common-src/src/gdbmedit/gdbmget/Makefile.in
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/gdbmget/Makefile.in	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/gdbmget/Makefile.in	(revision 20131)
@@ -0,0 +1,82 @@
+###########################################################################
+#
+# Makefile -- common-src/src/gdbmedit/gdbmget
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+
+
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@
+GSDLOS = @gsdlos@
+INCLUDES = -I$(COMMON_PACKAGES_DIR)/gdbm/include -I$(COMMON_DIR)/src/lib
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@ @COMPAT32BITFLAGS@
+LIBS = @LIBS@ $(COMMON_PACKAGES_DIR)/gdbm/lib/libgdbm.a
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+CXXLINK = $(CXX) $(LDFLAGS) -o $@
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+SOURCES = \
+	gdbmget.cpp
+
+OBJECTS = \
+	gdbmget.o
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS)
+
+EXECUTABLE = gdbmget
+
+
+# Default target: make the gdbmget executable
+all: $(EXECUTABLE)
+
+gdbmget: $(EXECUTABLE_OBJECTS)
+	$(CXXLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	$(INSTALL) -d $(GSDL_DIR)/bin/$(GSDLOS)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/bin/$(GSDLOS)
+
+clean:
+	rm -f $(OBJECTS) $(EXECUTABLE)
+
+distclean:
+	rm -f $(OBJECTS) $(EXECUTABLE) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/common-src/src/gdbmedit/gdbmget/gdbmget.cpp
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/gdbmget/gdbmget.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/gdbmget/gdbmget.cpp	(revision 20131)
@@ -0,0 +1,110 @@
+/**********************************************************************
+ *
+ * gdbmget -- retrieve a single value from the GDBM database
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifdef __WIN32__
+#include "autoconf.h"
+#include "systems.h"
+#include "gdbmconst.h"
+#include "gdbm.h"
+
+#else
+#include <gdbm.h>
+#endif
+
+#include "gsdlconf.h"
+#include <stdlib.h>
+#include <cstring>
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+// use the standard namespace
+#if !defined (GSDL_NAMESPACE_BROKEN)
+#if defined(GSDL_USE_OBJECTSPACE)
+using namespace ospace::std;
+#else
+using namespace std;
+#endif
+#endif
+
+void 
+print_usage (char *program_name) 
+{
+  cerr << "usage: " << program_name << " <database_path> <key>" << endl;
+  cerr << endl;
+}
+
+
+int main (int argc, char *argv[]) 
+{
+  int block_size = 0;
+  GDBM_FILE dbf;
+  datum key, value;
+  
+  // sanity check
+  if (argc != 3) 
+    {
+      print_usage (argv[0]);
+      exit (-1);
+    }
+  
+  // open the database
+#ifdef __WIN32__
+  dbf = gdbm_open (argv[1], block_size, GDBM_READER, 00664, NULL, 0);
+#else
+  dbf = gdbm_open  (argv[1], block_size, GDBM_READER, 00664, NULL);
+#endif
+  if (dbf == NULL) 
+    {
+      cerr << "couldn't open " << argv[1] << endl;
+      exit (-1);
+    }
+  
+  key.dsize = strlen(argv[2]);
+  key.dptr = argv[2];
+  value = gdbm_fetch (dbf, key);
+  if (value.dsize > 0) 
+    {
+      for (int i = 0; i < value.dsize; i++)
+        {
+          cout << value.dptr[i];
+        }
+      cout << endl; // used to be printf("\n");
+      // ?? free(value.dptri);
+    } 
+  else 
+    {
+      cout << endl; // used to be printf("\n");
+    }
+  
+  gdbm_close (dbf);
+  return 0;
+}
+
Index: /gsdl/stable/common-src/src/gdbmedit/gdbmget/win32.mak
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/gdbmget/win32.mak	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/gdbmget/win32.mak	(revision 20131)
@@ -0,0 +1,93 @@
+###########################################################################
+#
+# win32 makefile -- gdbmget
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDLHOME = ..\..\..\..
+COMMON_DIR = ..\..\..
+
+USE_STLPORT = 0
+STLPATH = "$(COMMON_DIR)\packages\windows\stlport\stlport"
+
+AR = lib
+CC = cl
+DEBUG = 0
+GSDL_VC4 = 0
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+LDFLAGS =
+
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H
+INCLUDES = -I"$(COMMON_DIR)\src\gdbmedit\gdbmget" -I"$(COMMON_DIR)\src\lib" -I"$(COMMON_DIR)\indexers\mg\lib" \
+	   -I"$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3" -I"$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3\windows"
+!IF $(USE_STLPORT)
+DEFS=$(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I$(STLPATH)
+!ENDIF
+
+LIBS = "$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3\gdbm.lib"
+
+COMPILE = $(CC) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) $(LDFLAGS)
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $<
+
+ANSI2KNR = 
+o = .obj
+e = .exe
+
+HEADERS = 
+
+SOURCES = gdbmget.cpp
+
+OBJECTS = gdbmget$o
+
+EXEC = gdbmget$e
+
+all : $(EXEC)
+
+install: $(EXEC)
+	if NOT EXIST "$(GSDLHOME)\bin\windows" mkdir "$(GSDLHOME)\bin\windows"
+	copy $(EXEC) "$(GSDLHOME)\bin\windows"
+
+clean:
+	del *$o
+	del $(EXEC)
+
+gdbmget$e: $(OBJECTS) $(LIBS)
+	  $(LINK) $(OBJECTS) $(LIBS)
Index: /gsdl/stable/common-src/src/gdbmedit/gdbmkeys/Makefile.in
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/gdbmkeys/Makefile.in	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/gdbmkeys/Makefile.in	(revision 20131)
@@ -0,0 +1,82 @@
+###########################################################################
+#
+# Makefile -- common-src/src/gdbmedit/gdbmkeys
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+
+
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@
+GSDLOS = @gsdlos@
+INCLUDES = -I$(COMMON_PACKAGES_DIR)/gdbm/include -I$(COMMON_DIR)/src/lib
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@ @COMPAT32BITFLAGS@
+LIBS = @LIBS@ $(COMMON_PACKAGES_DIR)/gdbm/lib/libgdbm.a
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+CXXLINK = $(CXX) $(LDFLAGS) -o $@
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+SOURCES = \
+	gdbmkeys.cpp
+
+OBJECTS = \
+	gdbmkeys.o
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS)
+
+EXECUTABLE = gdbmkeys
+
+
+# Default target: make the gdbmkeys executable
+all: $(EXECUTABLE)
+
+gdbmkeys: $(EXECUTABLE_OBJECTS)
+	$(CXXLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	$(INSTALL) -d $(GSDL_DIR)/bin/$(GSDLOS)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/bin/$(GSDLOS)
+
+clean:
+	rm -f $(OBJECTS) $(EXECUTABLE)
+
+distclean:
+	rm -f $(OBJECTS) $(EXECUTABLE) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/common-src/src/gdbmedit/gdbmkeys/gdbmkeys.cpp
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/gdbmkeys/gdbmkeys.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/gdbmkeys/gdbmkeys.cpp	(revision 20131)
@@ -0,0 +1,109 @@
+/**********************************************************************
+ *
+ * gdbmkeys -- retrieve a single value from the GDBM database
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifdef __WIN32__
+#include "autoconf.h"
+#include "systems.h"
+#include "gdbmconst.h"
+#include "gdbm.h"
+
+#else
+#include <gdbm.h>
+#endif
+
+#include "gsdlconf.h"
+#include <stdlib.h>
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+// use the standard namespace
+#if !defined (GSDL_NAMESPACE_BROKEN)
+#if defined(GSDL_USE_OBJECTSPACE)
+using namespace ospace::std;
+#else
+using namespace std;
+#endif
+#endif
+
+void 
+print_usage (char *program_name) 
+{
+  cerr << "usage: " << program_name << " <database_path>" << endl;
+  cerr << endl;
+}
+
+
+
+
+int main (int argc, char *argv[]) {
+  int block_size = 0, i;
+  GDBM_FILE dbf;
+  datum key, nextkey;
+      
+  // sanity check
+  if (argc != 2) {
+    print_usage (argv[0]);
+    exit (0);
+  }
+  
+  // open the database
+#ifdef __WIN32__
+  dbf = gdbm_open (argv[1], block_size, GDBM_READER, 00664, NULL, 0);
+#else
+  dbf = gdbm_open  (argv[1], block_size, GDBM_READER, 00664, NULL);
+#endif
+  if (dbf == NULL) {
+    cerr << "Couldn't open " << argv[1] << endl;
+    exit (0);
+  }
+
+  key = gdbm_firstkey (dbf);
+  while (key.dptr != NULL) {
+    for (i = 0; i < key.dsize; ++i) {
+      cout << key.dptr[i];
+    }
+    cout << endl;
+
+    /* get next key */
+    nextkey = gdbm_nextkey (dbf, key);
+
+    /* free old key's dptr, otherwise causes memory leak */
+    free(key.dptr); 
+    
+    /* can now safely copy content of nextkey into key */
+    key = nextkey;
+  }
+  
+  gdbm_close (dbf);
+  return 0;
+}
+
+
Index: /gsdl/stable/common-src/src/gdbmedit/gdbmkeys/win32.mak
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/gdbmkeys/win32.mak	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/gdbmkeys/win32.mak	(revision 20131)
@@ -0,0 +1,93 @@
+###########################################################################
+#
+# win32 makefile -- gdbmkeys
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDLHOME = ..\..\..\..
+COMMON_DIR = ..\..\..
+
+USE_STLPORT = 0
+STLPATH = "$(COMMON_DIR)\packages\windows\stlport\stlport"
+
+AR = lib
+CC = cl
+DEBUG = 0
+GSDL_VC4 = 0
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+LDFLAGS =
+
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H
+INCLUDES = -I"$(COMMON_DIR)\src\gdbmedit\gdbmkeys" -I"$(COMMON_DIR)\src\lib" -I"$(COMMON_DIR)\indexers\mg\lib" \
+	   -I"$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3" -I"$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3\windows"
+!IF $(USE_STLPORT)
+DEFS=$(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I$(STLPATH)
+!ENDIF
+
+LIBS = "$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3\gdbm.lib"
+
+COMPILE = $(CC) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) $(LDFLAGS)
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $<
+
+ANSI2KNR = 
+o = .obj
+e = .exe
+
+HEADERS = 
+
+SOURCES = gdbmkeys.cpp
+
+OBJECTS = gdbmkeys$o
+
+EXEC = gdbmkeys$e
+
+all : $(EXEC)
+
+install: $(EXEC)
+	if NOT EXIST "$(GSDLHOME)\bin\windows" mkdir "$(GSDLHOME)\bin\windows"
+	copy $(EXEC) "$(GSDLHOME)\bin\windows"
+
+clean:
+	del *$o
+	del $(EXEC)
+
+gdbmkeys$e: $(OBJECTS) $(LIBS)
+	  $(LINK) $(OBJECTS) $(LIBS)
Index: /gsdl/stable/common-src/src/gdbmedit/gdbmset/Makefile.in
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/gdbmset/Makefile.in	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/gdbmset/Makefile.in	(revision 20131)
@@ -0,0 +1,82 @@
+###########################################################################
+#
+# Makefile -- common-src/src/gdbmedit/gdbmset
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+
+
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@
+GSDLOS = @gsdlos@
+INCLUDES = -I$(COMMON_PACKAGES_DIR)/gdbm/include -I$(COMMON_DIR)/src/lib
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@ @COMPAT32BITFLAGS@
+LIBS = @LIBS@ $(COMMON_PACKAGES_DIR)/gdbm/lib/libgdbm.a
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+CXXLINK = $(CXX) $(LDFLAGS) -o $@
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+SOURCES = \
+	gdbmset.cpp
+
+OBJECTS = \
+	gdbmset.o
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS)
+
+EXECUTABLE = gdbmset
+
+
+# Default target: make the gdbmset executable
+all: $(EXECUTABLE)
+
+gdbmset: $(EXECUTABLE_OBJECTS)
+	$(CXXLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	$(INSTALL) -d $(GSDL_DIR)/bin/$(GSDLOS)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/bin/$(GSDLOS)
+
+clean:
+	rm -f $(OBJECTS) $(EXECUTABLE)
+
+distclean:
+	rm -f $(OBJECTS) $(EXECUTABLE) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/common-src/src/gdbmedit/gdbmset/gdbmset.cpp
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/gdbmset/gdbmset.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/gdbmset/gdbmset.cpp	(revision 20131)
@@ -0,0 +1,160 @@
+/**********************************************************************
+ *
+ * gdbmset -- add or replace a single value from the GDBM database
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifdef __WIN32__
+#include "autoconf.h"
+#include "systems.h"
+#include "gdbmconst.h"
+#include "gdbm.h"
+
+#else
+#include <gdbm.h>
+#endif
+
+#include "gsdlconf.h"
+#include <stdlib.h>
+#include <cstring>
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+// use the standard namespace
+#if !defined (GSDL_NAMESPACE_BROKEN)
+#if defined(GSDL_USE_OBJECTSPACE)
+using namespace ospace::std;
+#else
+using namespace std;
+#endif
+#endif
+
+void 
+print_usage (char *program_name) 
+{
+  cerr << "usage: " << program_name << " <database_path> <key> [<value>] [append]" << endl;
+  cerr << "\t- if no value is given then the lexicon indicated by the key is removed" << endl;
+  cerr << "\t- if a value is given followed by 'append' then the value is " << endl;
+  cerr << "\t  added to the existing entry rather than overwriting it" << endl;
+  cerr << endl;
+}
+
+
+int main (int argc, char *argv[]) 
+{
+  // The block_size parameter  is  ignored unless the file is a new file.
+  // If it is less than 512, dbm will use the  stat  block size for the file system.
+  int block_size = 0;
+  GDBM_FILE dbf;
+  datum key;
+  
+  // sanity check
+  if ((argc < 3) || (argc>5)) {
+      print_usage (argv[0]);
+      exit (-1);
+  }
+  
+  // open the database
+#ifdef __WIN32__
+  // On Windows need to make sure the database is generated if it does not already exist
+  // GDBM_WRCREAT flag means: open database for read/write, create if necessary
+  // http://www.rt.com/man/gdbm.3.html is the Unix man page on gdbm_open 
+  // http://trac.greenstone.org/changeset/928 - the 6th param of gdbm_open (only in the
+  // Windows version of the function) was set to 1 when using WRCREAT
+  // http://www.sfr-fresh.com/unix/misc/q-7.11.tar.gz:a/q-7.11/modules/gdbm/README-Gdbm
+  dbf = gdbm_open (argv[1], block_size, GDBM_WRCREAT, 00664, NULL, 1);
+#else
+  dbf = gdbm_open  (argv[1], block_size, GDBM_WRCREAT, 00664, NULL);
+  // dbf = gdbm_open  (argv[1], block_size, GDBM_WRITER, 00664, NULL);
+#endif
+  if (dbf == NULL) 
+    {
+      cerr << "couldn't open database connection to " << argv[1] << endl;
+      exit (-1);
+    }
+  
+  key.dsize = strlen(argv[2]);
+  key.dptr = argv[2];
+
+  if(argc == 5) {
+    
+    if (strcmp(argv[4],"append")==0) {
+      datum orig_content,concat_content;
+
+      //cerr << "Appending [" << argv[2] << "] to '" << argv[3] << "' (length " << strlen(argv[3]) << ")" << endl;
+      // get old value, then top up
+
+      orig_content = gdbm_fetch (dbf, key);
+
+      // append orig_content with argv[3]
+      concat_content.dsize = orig_content.dsize + strlen(argv[3]);
+      char* concat_data = new char[concat_content.dsize +1];//  make room for \0 at end
+      if (orig_content.dsize>0) {
+	strncpy(concat_data,orig_content.dptr,orig_content.dsize);
+	strcpy(&concat_data[orig_content.dsize],argv[3]); // ensures \0 at end
+      }
+      else {
+	// first time key has been used
+	strcpy(concat_data,argv[3]); // ensures \0 at end
+      }
+
+      concat_content.dptr = concat_data;
+      if(gdbm_store(dbf, key, concat_content, GDBM_REPLACE) != 0)
+        {
+          cerr << "failed to set [" << argv[2] << "] to '" << concat_data << "'" << endl;
+        }
+      delete [] concat_data;
+    }
+    else {
+      print_usage (argv[0]);
+      gdbm_close (dbf);
+      exit(-1);
+    }
+  }
+  else if (argc == 4) {
+      datum content;
+
+      //cerr << "Setting [" << argv[2] << "] to '" << argv[3] << "' (length " << strlen(argv[3]) << ")" << endl;
+      content.dsize = strlen(argv[3]);
+      content.dptr = argv[3];
+      if(gdbm_store(dbf, key, content, GDBM_REPLACE) != 0)
+        {
+          cerr << "failed to set [" << argv[2] << "] to '" << argv[3] << "'" << endl;
+        }
+    }
+  else
+    {
+      if(gdbm_delete(dbf, key) != 0)
+        {
+          cerr << "failed to remove [" << argv[2] << "]" << endl;
+        }
+    }
+  gdbm_close (dbf);
+
+  return 0;
+}
Index: /gsdl/stable/common-src/src/gdbmedit/gdbmset/win32.mak
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/gdbmset/win32.mak	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/gdbmset/win32.mak	(revision 20131)
@@ -0,0 +1,93 @@
+###########################################################################
+#
+# win32 makefile -- gdbmset
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDLHOME = ..\..\..\..
+COMMON_DIR = ..\..\..
+
+USE_STLPORT = 0
+STLPATH = "$(COMMON_DIR)\packages\windows\stlport\stlport"
+
+AR = lib
+CC = cl
+DEBUG = 0
+GSDL_VC4 = 0
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+LDFLAGS =
+
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H
+INCLUDES = -I"$(COMMON_DIR)\src\gdbmedit\gdbmset" -I"$(COMMON_DIR)\src\lib" -I"$(COMMON_DIR)\indexers\mg\lib" \
+	   -I"$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3" -I"$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3\windows"
+!IF $(USE_STLPORT)
+DEFS=$(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I$(STLPATH)
+!ENDIF
+
+LIBS = "$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3\gdbm.lib"
+
+COMPILE = $(CC) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) $(LDFLAGS)
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $<
+
+ANSI2KNR = 
+o = .obj
+e = .exe
+
+HEADERS = 
+
+SOURCES = gdbmset.cpp
+
+OBJECTS = gdbmset$o
+
+EXEC = gdbmset$e
+
+all : $(EXEC)
+
+install: $(EXEC)
+	if NOT EXIST "$(GSDLHOME)\bin\windows" mkdir "$(GSDLHOME)\bin\windows"
+	copy $(EXEC) "$(GSDLHOME)\bin\windows"
+
+clean:
+	del *$o
+	del $(EXEC)
+
+gdbmset$e: $(OBJECTS) $(LIBS)
+	  $(LINK) $(OBJECTS) $(LIBS)
Index: /gsdl/stable/common-src/src/gdbmedit/txt2db/Makefile.in
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/txt2db/Makefile.in	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/txt2db/Makefile.in	(revision 20131)
@@ -0,0 +1,87 @@
+###########################################################################
+#
+# Makefile -- common-src/src/gdbmedit/txt2db
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+
+
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@
+GSDLOS = @gsdlos@
+INCLUDES = -I$(COMMON_PACKAGES_DIR)/gdbm/include -I$(COMMON_DIR)/src/lib
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@ @COMPAT32BITFLAGS@
+LIBS = @LIBS@ $(COMMON_PACKAGES_DIR)/gdbm/lib/libgdbm.a
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+CXXLINK = $(CXX) $(LDFLAGS) -o $@
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+SOURCES = \
+	txt2db.cpp
+
+OBJECTS = \
+	txt2db.o
+
+GSDL_LIBS = \
+	$(COMMON_DIR)/src/lib/gsdllib.a \
+	$(COMMON_DIR)/indexers/mg/lib/libmglib.a
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS) \
+	$(GSDL_LIBS)
+
+EXECUTABLE = txt2db
+
+
+# Default target: make the txt2db executable
+all: $(EXECUTABLE)
+
+txt2db: $(EXECUTABLE_OBJECTS)
+	$(CXXLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	$(INSTALL) -d $(GSDL_DIR)/bin/$(GSDLOS)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/bin/$(GSDLOS)
+
+clean:
+	rm -f $(OBJECTS) $(EXECUTABLE)
+
+distclean:
+	rm -f $(OBJECTS) $(EXECUTABLE) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/common-src/src/gdbmedit/txt2db/txt2db.cpp
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/txt2db/txt2db.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/txt2db/txt2db.cpp	(revision 20131)
@@ -0,0 +1,213 @@
+/**********************************************************************
+ *
+ * txt2db.cpp -- 
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the 
+ * University of Waikato, New Zealand.
+ *
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ **********************************************************************/
+
+
+#ifdef __WIN32__
+#include "autoconf.h"
+#include "systems.h"
+#include "gdbmconst.h"
+#include "gdbm.h"
+
+#else
+#include <gdbm.h>
+#endif
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include <stdlib.h>
+#include <cstring>
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+#endif
+
+
+void print_usage (char *program_name) {
+  cerr << "usage: " << program_name << " [options] database-name" << endl << endl;
+  cerr << "options:" << endl;
+  cerr << " -append        append to existing database" << endl << endl;
+}
+
+
+int main (int argc, char *argv[]) {
+  int block_size = 0;
+  GDBM_FILE dbf;
+  char c;
+  text_t key;
+  text_t value;
+  text_t tmp;
+  int num_dashes = 0;
+
+  // sanity check
+  if (argc != 2 && argc != 3) {
+    print_usage (argv[0]);
+    exit (0);
+  }
+  
+  char *dbname;
+  int append = 0;
+  int delkey = 0;
+
+  if (argc == 3) {
+    if (strcmp (argv[1], "-append") == 0) {
+      append = 1;
+      dbname = argv[2];
+    } else {
+      cerr << argv[1] << " is not a valid option." << endl << endl;
+      print_usage (argv[0]);
+      exit (0);
+    }
+  } else dbname = argv[1];
+
+  
+  // open the database
+  // note that GDBM_FAST is obsolete on newer versions of gdbm
+  int read_write = GDBM_NEWDB | GDBM_FAST;
+  if (append) read_write = GDBM_WRCREAT | GDBM_FAST;
+  
+#ifdef __WIN32__
+  dbf = gdbm_open (dbname, block_size, read_write, 00664, NULL, 1);
+#else
+  dbf = gdbm_open  (dbname, block_size, read_write, 00664, NULL);
+#endif
+  if (dbf == NULL) {
+    cerr << "couldn't create " << dbname << endl;
+    exit (0);
+  }
+  
+  cin.get(c);
+  while (!cin.eof()) {
+    num_dashes = 0;
+    key = "";
+    value = "";
+    
+    // Parse out 'key' from [key]\n
+
+    // scan for first occurrence of [
+    while (!cin.eof() && c != '[') cin.get(c);
+
+    if (!cin.eof()) cin.get(c); // skip [
+
+    // now look for closing ], building up 'key' as we go
+    while (!cin.eof() && c != ']') {
+      key.push_back ((unsigned char)c);
+      cin.get(c);
+    }
+
+    if (!cin.eof()) {
+      // most likely an eol char, but if '-', then signifies record
+      // is to be deleted, not added
+      cin.get(c); 
+      if (c == '-') {	
+	delkey = 1;
+      }
+      else {
+	delkey = 0;
+      }
+    }
+    while (!cin.eof() && (c == '\n' || c == '\r')) cin.get(c);
+    
+    // look for 70 dashes
+    tmp = "";
+    while (!cin.eof() && (num_dashes < 70)) {
+      if (c == '\n') {
+	tmp.push_back ((unsigned char)c);
+	num_dashes = 0;	
+	
+      } else if (c == '\r') { 
+	// Here we are able to process both Windows-specific text files 
+	// (containing carriage-return, newline) and Linux text files 
+	// (containing only newline characters) by ignoring the Windows' 
+	// carriage-return altogether so that we produce a uniform database
+	// file from either system's type of text file. 
+	// If we don't ignore the carriage return here, txt.gz files
+	// produced on Windows cause a GS library running on Linux to break.
+	num_dashes = 0;
+
+      } else if (c == '-') {
+	tmp.push_back ((unsigned char)c);
+	++num_dashes;
+	
+      } else {
+	value += tmp;
+	value.push_back ((unsigned char)c);
+	tmp = "";
+	num_dashes = 0;
+      }
+      cin.get(c);
+    }
+    
+    // if the key is not an empty string store this key-value pair
+    if (!key.empty()) {
+      // convert key to a datum datatype
+      datum key_data;
+      key_data.dptr = key.getcstr();
+      if (key_data.dptr == NULL) {
+	cerr << "NULL key_data.dptr" << endl;
+	exit (0);
+      }
+      key_data.dsize = strlen(key_data.dptr);
+
+      if (delkey) {
+	// delete the given key
+	if (gdbm_delete(dbf, key_data) < 0) {
+	  cerr << "gdbm_delete returned an error" << endl;
+	}
+      }
+      else {
+
+	// add/append
+
+	// convert value to a datum datatype
+	datum value_data;
+	value_data.dptr = value.getcstr();
+	if (value_data.dptr == NULL) {
+	  cerr << "NULL value_data.dptr" << endl;
+	  exit (0);
+	}
+	value_data.dsize = strlen(value_data.dptr);
+      
+	// store the value
+	if (gdbm_store (dbf, key_data, value_data, GDBM_REPLACE) < 0) {
+	  cerr << "gdbm_store returned an error" << endl;
+	  exit (0);
+	}
+
+	
+	free(value_data.dptr);
+      }
+
+      free(key_data.dptr);
+    }
+  }
+  
+  gdbm_close (dbf);
+  
+  return 0;
+}
Index: /gsdl/stable/common-src/src/gdbmedit/txt2db/win32.mak
===================================================================
--- /gsdl/stable/common-src/src/gdbmedit/txt2db/win32.mak	(revision 20131)
+++ /gsdl/stable/common-src/src/gdbmedit/txt2db/win32.mak	(revision 20131)
@@ -0,0 +1,93 @@
+###########################################################################
+#
+# win32 makefile -- txt2db
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDLHOME = ..\..\..\..
+COMMON_DIR = ..\..\..
+
+GSDL_VC4 = 0
+STLPATH = "$(COMMON_DIR)\packages\windows\stlport\stlport"
+
+AR = lib
+CC = cl
+DEBUG = 0
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+LDFLAGS =
+
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H -D_CRT_SECURE_NO_DEPRECATE
+INCLUDES = -I"$(COMMON_DIR)\src\gdbmedit\txt2db" -I"$(COMMON_DIR)\src\lib" -I"$(COMMON_DIR)\indexers\mg\lib" \
+	   -I"$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3" -I"$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3\windows"
+!IF $(GSDL_VC4)
+DEFS=$(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I$(STLPATH)
+!ENDIF
+
+LIBS = "$(COMMON_DIR)\indexers\mg\lib\unitool.obj" "$(COMMON_DIR)\src\lib\gsdllib.lib" \
+       "$(COMMON_DIR)\packages\gdbm\gdbm-1.8.3\gdbm.lib"
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) -nologo $(LDFLAGS)
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $<
+
+ANSI2KNR = 
+o = .obj
+e = .exe
+ 
+HEADERS = 
+
+SOURCES = txt2db.cpp
+
+OBJECTS = txt2db$o
+
+EXEC = txt2db$e
+ 
+all : $(EXEC)
+
+install: $(EXEC)
+	if NOT EXIST "$(GSDLHOME)\bin\windows" mkdir "$(GSDLHOME)\bin\windows"
+	copy $(EXEC) "$(GSDLHOME)\bin\windows"
+
+clean:
+	del *.obj
+	del $(EXEC)
+
+txt2db$e: $(OBJECTS) $(LIBS)
+	  $(LINK) $(OBJECTS) $(LIBS)
Index: /gsdl/stable/common-src/src/getpw/Makefile.in
===================================================================
--- /gsdl/stable/common-src/src/getpw/Makefile.in	(revision 20131)
+++ /gsdl/stable/common-src/src/getpw/Makefile.in	(revision 20131)
@@ -0,0 +1,78 @@
+###########################################################################
+#
+# Makefile -- src/getpw
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2000-2008  The New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@
+GSDLOS = @gsdlos@
+INCLUDES = -I$(COMMON_DIR) -I$(COMMON_DIR)/src/lib
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@ @COMPAT32BITFLAGS@
+LIBS = @LIBS@
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+CXXLINK = $(CXX) $(LDFLAGS) -o $@
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+SOURCES = \
+	getpw.cpp
+
+OBJECTS = \
+	getpw.o
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS)
+
+EXECUTABLE = getpw
+
+
+# Default target: make the getpw executable
+all: $(EXECUTABLE)
+
+getpw: $(EXECUTABLE_OBJECTS)
+	$(CXXLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	$(INSTALL) -d $(GSDL_DIR)/bin/$(GSDLOS)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/bin/$(GSDLOS)
+
+clean:
+	rm -f $(OBJECTS) $(EXECUTABLE)
+
+distclean:
+	rm -f $(OBJECTS) $(EXECUTABLE) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/common-src/src/getpw/getpw.cpp
===================================================================
--- /gsdl/stable/common-src/src/getpw/getpw.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/getpw/getpw.cpp	(revision 20131)
@@ -0,0 +1,125 @@
+/**********************************************************************
+ *
+ * getpw.cpp -- 
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the 
+ * University of Waikato, New Zealand.
+ *
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ **********************************************************************/
+
+#define _XOPEN_SOURCE 1
+// This was added for Solaris, but it makes things worse on Solaris for me...
+// #define _XOPEN_SOURCE_EXTENDED 1
+
+#include "gsdlconf.h"
+
+
+// include crypt
+#if defined(__WIN32__)
+#include "crypt.h"
+#else
+
+#include "config.h"
+#if defined(HAVE_CRYPT_H)
+#include <crypt.h>
+#endif
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+/* we are probably in trouble if we have neither crypt.h or unistd.h,
+   but for now we'll do nothing about it... */
+
+#endif  /* not WIN32 */
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+#endif
+
+// use the standard namespace
+#if !defined (GSDL_NAMESPACE_BROKEN)
+#if defined(GSDL_USE_OBJECTSPACE)
+using namespace ospace::std;
+#else
+using namespace std;
+#endif
+#endif
+
+
+#include <string.h>
+//#include <pwd.h>
+
+
+int main (int argc, char *argv[]) {
+
+  int password_ok = 0;
+  char c[129];
+  int i;
+  
+  for (i=0; i<3; i++)  {
+#if defined(__WIN32__)
+    cerr << "Enter password  (will appear on screen): ";
+    char a[129];
+    cin.getline(a, 128);
+#else
+    char *a = getpass("Enter password:");
+#endif
+
+    int len = strlen (a);
+    if (len < 3 || len > 128) {
+      cerr << "Password must be between 3 and 128 characters long. Try again\n";
+      continue;
+    }
+
+    strcpy (c, a);
+
+#if defined(__WIN32__)
+    cerr << "Re-enter password: ";
+    char b[129];
+    cin.getline(b, 128);
+#else
+    char *b = getpass("Re-enter password:");  
+#endif
+
+    if ((strcmp (c, b)) == 0) {
+      password_ok = 1;
+      break;
+    }
+    else {
+      cerr << "Passwords didn't match. Try again.\n";
+    }
+  }
+
+  if (!password_ok) {
+    cerr << "Failed to capture password." << endl;
+    return -1;
+  }
+
+
+  char *salt = "Tp";
+  char *pw = crypt (c, salt);
+
+  cout << pw << "\n";
+  
+  return 0;
+}
Index: /gsdl/stable/common-src/src/getpw/win32.mak
===================================================================
--- /gsdl/stable/common-src/src/getpw/win32.mak	(revision 20131)
+++ /gsdl/stable/common-src/src/getpw/win32.mak	(revision 20131)
@@ -0,0 +1,103 @@
+###########################################################################
+#
+# win32 makefile -- getgw
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+COMMON_DIR = ..\..
+
+COMMON_PACKAGES_DIR = $(COMMON_DIR)\packages
+
+
+GSDL_VC4 = 0
+LOCAL_LIBRARY = 0
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+USE_SQLITE = 1
+USE_MSSQL = 0
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+!IF $(DLL)
+CXXFLAGS = $(CXXFLAGS) -MD
+!ELSE
+!IF ($(DLLDEBUG))
+CXXFLAGS = $(CXXFLAGS) -MDd
+!ENDIF
+!ENDIF
+
+CC = cl
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H -DPARADOCNUM -D_LITTLE_ENDIAN -DSHORT_SUFFIX -D_CRT_SECURE_NO_DEPRECATE
+INCLUDES = -I"$(COMMON_DIR)" -I"$(COMMON_DIR)\src\lib" -I"$(COMMON_DIR)\packages\windows\crypt\crypt"
+LIBS = "$(COMMON_DIR)\src\lib\gsdllib.lib" "$(COMMON_DIR)\packages\windows\crypt\crypt\crypt.lib"
+
+
+!IF $(GSDL_VC4)
+DEFS = $(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I"$(COMMON_PACKAGES_DIR)\windows\stlport\stlport"
+!ENDIF
+
+!IF $(LOCAL_LIBRARY)
+DEFS = $(DEFS) -DGSDL_LOCAL_LIBRARY
+!ENDIF
+
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) -nologo $(LDFLAGS)
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $< 
+
+
+SOURCES = getpw.cpp
+OBJECTS = getpw.obj
+EXEC    = getpw.exe
+
+all: $(EXEC)
+
+install:
+	copy $(EXEC) "$(GSDLHOME)\bin\windows"
+
+clean:
+	del *.obj
+	del $(EXEC)
+
+getpw.exe: $(OBJECTS)
+	$(LINK) $(OBJECTS) $(LIBS) 
+
+
+
+
Index: /gsdl/stable/common-src/src/lib/Makefile.in
===================================================================
--- /gsdl/stable/common-src/src/lib/Makefile.in	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/Makefile.in	(revision 20131)
@@ -0,0 +1,121 @@
+###########################################################################
+#
+# Makefile -- common-src/src/lib
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+#GSDL_DIR = ../../..
+COMMON_DIR = ../..
+
+INDEXERS_DIR = $(COMMON_DIR)/indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+
+
+USE_SQLITE = @USE_SQLITE@
+ifeq ($(USE_SQLITE), 1)
+SQLITE_INCLUDES = -I$(COMMON_PACKAGES_DIR)/sqlite/include
+SQLITE_OBJECTS = sqlitedbclass.o
+SQLITE_SOURCES = sqlitedbclass.cpp
+else
+SQLITE_INCLUDES = 
+SQLITE_OBJECTS = 
+SQLITE_SOURCES = 
+endif
+
+
+AR = ar
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@
+INCLUDES = -I. -I$(COMMON_DIR) -I$(COMMON_PACKAGES_DIR)/gdbm/include -I$(INDEXERS_DIR)/mg/lib $(SQLITE_INCLUDES)
+RANLIB = @RANLIB@
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+SOURCES = \
+	cfgread.cpp \
+	cnfgable.cpp \
+	cnfgator.cpp \
+	dbclass.cpp \
+	display.cpp \
+	fileutil.cpp \
+	gdbmclass.cpp \
+	gsdlsitecfg.cpp \
+	gsdltimes.cpp \
+	gsdltools.cpp \
+	gsdlunicode.cpp \
+	infodbclass.cpp \
+	md5.cpp \
+	OIDtools.cpp \
+	phrases.cpp \
+	text_t.cpp \
+	$(SQLITE_SOURCES)
+
+OBJECTS = \
+	cfgread.o \
+	cnfgable.o \
+	cnfgator.o \
+	dbclass.o \
+	display.o \
+	fileutil.o \
+	gdbmclass.o \
+	gsdlsitecfg.o \
+	gsdltimes.o \
+	gsdltools.o \
+	gsdlunicode.o \
+	infodbclass.o \
+	md5.o \
+	OIDtools.o \
+	phrases.o \
+	text_t.o \
+	$(SQLITE_OBJECTS)
+
+LIBRARY = gsdllib.a
+
+
+# Default target: make gsdllib.a
+all: $(LIBRARY)
+
+gsdllib.a: $(OBJECTS)
+	rm -f $(LIBRARY)
+	$(AR) cru $(LIBRARY) $(OBJECTS)
+	$(RANLIB) $(LIBRARY)
+
+install:
+
+clean:
+	rm -f $(OBJECTS) $(LIBRARY)
+
+distclean:
+	rm -f $(OBJECTS) $(LIBRARY) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/common-src/src/lib/OIDtools.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/OIDtools.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/OIDtools.cpp	(revision 20131)
@@ -0,0 +1,164 @@
+/**********************************************************************
+ *
+ * OIDtools.cpp -- 
+ * Copyright (C) 1999-2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "OIDtools.h"
+
+
+// returns (in top) the top level of OID (i.e. everything
+// up until the first dot)
+void get_top (const text_t &OID, text_t &top)
+{
+  top.clear();
+  if (OID.empty()) return;
+
+  text_t::const_iterator begin = OID.begin();
+  text_t::const_iterator end = OID.end();
+
+  top.appendrange (begin, findchar(begin, end, '.'));
+}	
+
+
+// checks if OID is top level (i.e. contains no dots)
+bool is_top (const text_t &OID)
+{
+  if (OID.empty()) return true;
+
+  text_t::const_iterator here = OID.begin();
+  text_t::const_iterator end = OID.end();
+  here = findchar (here, end, '.');
+
+  if (here == end) return true;
+  return false;
+}
+
+
+// get_parents_array loads the parents array with all the parents of the
+// document or classification specified by OID (not including OID itself)
+void get_parents_array (const text_t &OID, text_tarray &parents)
+{
+  text_t::const_iterator here = OID.begin ();
+  text_t::const_iterator end = OID.end ();
+  text_t thisparent;
+
+  while (here != end) {
+    if (*here == '.') parents.push_back(thisparent);
+    thisparent.push_back(*here);
+    ++here;
+  }
+}
+
+
+// get_parent returns the parent of the document or classification
+// specified by OID
+text_t get_parent (const text_t& OID)
+{
+  if (OID.empty() || is_top (OID)) return g_EmptyText;
+
+  text_t::const_iterator begin = OID.begin();
+  text_t::const_iterator here = (OID.end() - 1);
+
+  while (here >= begin) {
+    if (*here == '.')
+      break;
+    if (here == begin)
+      break;
+    --here;
+  }
+
+  if (here != begin) {
+    text_t parentOID;
+    parentOID.appendrange(begin, here);
+    return parentOID;
+  }
+
+  return g_EmptyText;
+}
+
+
+// takes an OID like ".2 and replaces the " with parent
+void translate_parent (text_t &OID, const text_t &parent)
+{
+  text_t::const_iterator here = OID.begin();
+  text_t::const_iterator end = OID.end();
+  text_t temp;
+
+  while (here != end) {
+    if (*here == '"') temp += parent;
+    else temp.push_back (*here);
+    ++here;
+  }
+  OID = temp;
+}
+
+
+// shrink_parent does the opposite to translate_parent
+void shrink_parent (text_t &OID)
+{
+  text_tarray tmp;
+  splitchar (OID.begin(), OID.end(), '.', tmp);
+  OID = "\"." + tmp.back();
+}
+
+
+// checks if OID uses ".fc", ".lc", ".pr", "rt", ".ns",
+// or ".ps" syntax (first child, last child, parent, root,
+// next sibling, previous sibling)
+bool needs_translating (const text_t &OID)
+{
+  if (OID.size() < 4) return false;
+
+  text_t tail = substr (OID.end()-3, OID.end());
+  if (tail == ".fc" || tail == ".lc" || tail == ".pr" || 
+      tail == ".rt" || tail == ".ns" || tail == ".ps") return true;
+
+  return false;
+}
+
+
+// strips the ".fc", ".lc", ".pr", ".ns",
+// or ".ps" suffix from the end of OID
+void strip_suffix (text_t &OID)
+{
+  text_t tail = substr (OID.end()-3, OID.end());
+  while (tail == ".fc" || tail == ".lc" || tail == ".pr" || 
+	 tail == ".rt" || tail == ".ns" || tail == ".ps") {
+    OID.erase (OID.end()-3, OID.end());
+    tail = substr (OID.end()-3, OID.end());
+  }
+}
+
+
+// is_child_of returns true if OID2 is a child of OID1
+bool is_child_of(const text_t &OID1, const text_t &OID2)
+{
+  text_t parent = get_parent(OID2);
+
+  while (!parent.empty()) {
+    if (parent == OID1) return true;
+    parent = get_parent(parent);
+  }
+
+  return false;
+}
Index: /gsdl/stable/common-src/src/lib/OIDtools.h
===================================================================
--- /gsdl/stable/common-src/src/lib/OIDtools.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/OIDtools.h	(revision 20131)
@@ -0,0 +1,68 @@
+/**********************************************************************
+ *
+ * OIDtools.h -- 
+ * Copyright (C) 1999-2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef OIDTOOLS_H
+#define OIDTOOLS_H
+
+#include "text_t.h"
+
+
+void get_oid (const text_t &OID, text_t &to, size_t level);
+
+// returns (in top) the top level of OID (i.e. everything
+// up until the first dot)
+void get_top (const text_t &OID, text_t &top);
+
+// checks if OID is top level (i.e. contains no dots)
+bool is_top (const text_t &OID);
+
+// get_parents_array loads the parents array with all the parents of the
+// document or classification specified by OID (not including OID itself)
+void get_parents_array (const text_t &OID, text_tarray &parents);
+
+// get_parent returns the parent of the document or classification
+// specified by OID
+text_t get_parent (const text_t& OID);
+
+// takes an OID like ".2.3 and replaces the " with parent
+void translate_parent (text_t &OID, const text_t &parent);
+
+// shrink_parent does the opposite to translate_parent
+void shrink_parent (text_t &OID);
+
+// checks if OID uses ".fc", ".lc", ".pr", ".ns",
+// or ".ps" syntax (first child, last child, parent,
+// next sibling, previous sibling)
+bool needs_translating (const text_t &OID);
+
+// strips the ".fc", ".lc", ".pr", ".ns",
+// or ".ps" suffix from the end of OID
+void strip_suffix (text_t &OID);
+
+// is_child_of returns true if OID2 is a child of OID1
+bool is_child_of(const text_t &OID1, const text_t &OID2);
+
+
+#endif
Index: /gsdl/stable/common-src/src/lib/cfgread.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/cfgread.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/cfgread.cpp	(revision 20131)
@@ -0,0 +1,220 @@
+/**********************************************************************
+ *
+ * cfgread.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "cfgread.h"
+#include <cctype> // for isspace()
+
+int write_ini_line (ofstream &fileout, const text_t &key, const text_t &value) {
+  if (key.empty() || value.empty()) return -1;
+  outconvertclass text_t2ascii;
+  fileout << text_t2ascii << key << "=" << value << "\n";
+  return 0;
+}
+
+int read_ini_line (ifstream &filein, text_t &key, text_t &value) {
+  if (filein.eof()) return -1;
+
+  key.clear();
+  value.clear();
+  char c;
+  filein.get(c);
+
+  int foundeq = 0;
+  while (!filein.eof() && c != '\n') {
+    if (!foundeq && c == '=') {foundeq = 1; filein.get(c);}
+
+    if (foundeq) value.push_back(c);
+    else key.push_back(c);
+    filein.get(c);
+  }
+  if (key.empty()) return 0; // blank line maybe?
+  return 0;
+} 
+
+// write out line of values to cfgfile
+// does nothing fancy - make sure no values contain carriage returns
+int write_cfg_line (ofstream &fileout, const text_tarray &values) {
+  outconvertclass text_t2ascii;
+
+  text_tarray::const_iterator here = values.begin();
+  text_tarray::const_iterator end = values.end();
+
+  bool first = true;
+  while (here != end) {
+    if (first) fileout << text_t2ascii << *here;
+    else fileout << text_t2ascii << "  \"" << *here << "\"";
+    first = false;
+    ++here;
+  }
+  fileout << "\n";
+  return 0;
+}
+
+// same, but use a file descriptor this time
+int write_cfg_line (int fileout, const text_tarray &values) {
+  outconvertclass text_t2ascii;
+
+  text_tarray::const_iterator here = values.begin();
+  text_tarray::const_iterator end = values.end();
+
+  if (here != end) {
+    char *s=here->getcstr();
+    write(fileout,s ,here->size());
+    delete []s;
+
+    ++here;
+  }
+  while (here != end) {
+    write(fileout, " \"", 2);
+    char *s=here->getcstr();
+    write(fileout,s ,here->size());
+    delete []s;
+    write(fileout, "\"", 1);
+
+    ++here;
+  }
+  write(fileout,"\n",1);
+  return 0;
+}
+
+
+// returns 0 on success, -1 on failure
+int read_cfg_line (ifstream &filein, text_tarray &values) {
+  // we split up the line into tokens, pushing each token into the
+  // values array. Quoted phrases are a single token. A "\" at the end
+  // of a line continues onto the next line.
+
+  values.erase(values.begin(), values.end());
+
+  if (!filein.good()) return -1;
+
+  text_t curvalue;
+  char c1;
+  filein.get(c1);
+
+  // skip white space
+  while (!filein.eof() && isspace((unsigned char) c1)) { filein.get(c1); }
+
+    // ignore comments
+  while (c1 == '#') {
+    while (!filein.eof() && c1!='\n' && c1!='\r') { filein.get(c1); }
+    // skip white space...
+    while (!filein.eof() && isspace((unsigned char) c1)) { filein.get(c1); }
+  }
+
+  // deal with all the records on this line (possibly multi-line)
+
+  while (!filein.eof()) {
+    if (c1=='\n' || c1=='\r') { // shouldn't happen?
+      break;
+    }
+
+    // get the next token
+    curvalue.clear();
+      
+    bool inquote=false;
+    char quotemark='"';
+    char preceding='\0'; // 1-char state to allow \" and \'
+    // see if this is a quoted phrase
+    if (c1=='\'' || c1=='\"') { // starts with a quote
+      inquote=true;
+      quotemark = c1;
+      preceding = c1; // just to initialise
+      filein.get(c1);
+    }
+
+    // get token or a whole phrase
+    while (!filein.eof()) {
+      if (isspace((unsigned char) c1)) {
+	if (! inquote) {
+	  // end of token, not inside quote marks
+	  break;
+	} else {
+	  // inside quote marks.
+	  /* Turn eol into space, in case other parsing bits expect eol to
+	     also mean end of parsing... */
+	  c1=' ';
+	}
+      }
+      if (c1 == quotemark && inquote && preceding != '\\') {
+	// end of quoted phrase found
+	inquote=false;
+	filein.get(c1);
+	continue;
+      }
+
+      // add current char to token/phrase
+      // see if current byte is part of a multibyte char (utf-8 only!)
+      unsigned short int c; // text_t uses 16bit unicode
+      unsigned char uc1=(unsigned)c1;
+      if (uc1 < 0x80) {
+	c=uc1;
+      } else if (uc1 >= 0xc0 && uc1 <= 0xdf) {
+	// 2-byte utf-8
+	unsigned char c2;
+	// two byte character
+	filein.get((char&)c2); // get takes a signed char
+	c = ((uc1 & 0x1f) << 6) + (c2 & 0x3f);
+      } else if (uc1 >= 0xe0 && uc1 <= 0xef) {
+	// 3-byte character
+	unsigned char c2, c3;
+	filein.get((char&)c2);
+	filein.get((char&)c3);
+	c = ((uc1 & 0xf) << 12) + ((c2 & 0x3f) << 6)
+	  + (c3 & 0x3f);
+      } else {c=uc1;} // we don't do group2/plane0 (4,5,6-byte utf-8)
+
+      curvalue.push_back(c); // 16bit unicode
+      if (inquote)
+	preceding = c1;
+
+      filein.get(c1);
+    }
+    // we now have a token or a phrase
+    
+    // see if we've reached the end of the line
+    if (c1 == '\n' || c1 == '\r') {
+      if (curvalue != "\\") { // the line DOESN'T continue. End of line.
+	values.push_back(curvalue);
+	break; // end of token/phrase
+      } else {
+	// swallow up the EOL chars
+	while (!filein.eof() && (c1=='\r' || c1=='\n')) filein.get(c1);
+	// the current token "\\" will be cleared below
+      }
+    } else { // no new line seen
+      values.push_back(curvalue);
+    }
+
+    curvalue.clear();
+
+    // remove whitespace (but not newline/CR chars) before next token
+    while (!filein.eof() && (c1==' ' || c1=='\t')) filein.get(c1);
+
+  } // while(1)
+  
+
+  return 0;
+}
Index: /gsdl/stable/common-src/src/lib/cfgread.h
===================================================================
--- /gsdl/stable/common-src/src/lib/cfgread.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/cfgread.h	(revision 20131)
@@ -0,0 +1,48 @@
+/**********************************************************************
+ *
+ * cfgread.h -- reads in configuration files
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef CFGREAD_H
+#define CFGREAD_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <fstream.h>
+#else
+#  include <fstream>
+#endif
+
+// return 0 on success, -1 on failure
+int write_ini_line (ofstream &fileout, const text_t &key, const text_t &value);
+int read_ini_line (ifstream &filein, text_t &key, text_t &value);
+int write_cfg_line (ofstream &fileout, const text_tarray &values);
+int write_cfg_line (int filedesc, const text_tarray &values);
+int read_cfg_line (ifstream &filein, text_tarray &values);
+
+#endif
Index: /gsdl/stable/common-src/src/lib/cnfgable.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/cnfgable.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/cnfgable.cpp	(revision 20131)
@@ -0,0 +1,37 @@
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace/std/iostream>
+#  include <ospace/std/fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#  include <fstream.h>
+#else
+#  include <iostream>
+#  include <fstream>
+#endif
+
+#include "cnfgable.h"
+#include "cfgread.h"
+
+bool configurable::read_configfile (const text_t &filename) {
+  // read in the build configuration file
+  text_t key;
+  text_tarray cfgline;
+  char *cstr = filename.getcstr();
+  ifstream confin (cstr);
+  delete []cstr;
+
+  if (confin) {
+    while (read_cfg_line(confin, cfgline) >= 0) {
+      if (cfgline.size () >= 2) {
+	key = cfgline[0];
+	cfgline.erase(cfgline.begin());
+
+	// configure the collection server
+	this->configure (key, cfgline);
+      }
+    }
+    confin.close ();
+    return true;
+  }
+  return false;
+}
Index: /gsdl/stable/common-src/src/lib/cnfgable.h
===================================================================
--- /gsdl/stable/common-src/src/lib/cnfgable.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/cnfgable.h	(revision 20131)
@@ -0,0 +1,16 @@
+#ifndef CONFIGURABLE_H
+#define CONFIGURABLE_H
+
+#include "text_t.h"
+
+class configurable {
+ public:
+  virtual void configure (const text_t &key, const text_tarray &cfgline) = 0;
+  virtual ~configurable () {}
+
+  bool read_configfile (const text_t &filename);
+ protected:
+  configurable() {}
+};
+
+#endif
Index: /gsdl/stable/common-src/src/lib/cnfgator.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/cnfgator.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/cnfgator.cpp	(revision 20131)
@@ -0,0 +1,52 @@
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace/std/iostream>
+#  include <ospace/std/fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#  include <fstream.h>
+#else
+#  include <iostream>
+#  include <fstream>
+#endif
+
+#include "cnfgator.h"
+
+configurator::configurator(configurable *configureobject) {
+  configureobjs.push_back(configureobject);
+}
+
+void configurator::add_configurable(configurable *configureobject) {
+  configureobjs.push_back(configureobject);
+}
+
+bool configurator::configure(const text_t &filename) {
+  // read in the build configuration file
+  text_t key;
+  text_tarray cfgline;
+  char *cstr = filename.getcstr();
+  ifstream confin (cstr);
+  delete []cstr;
+
+  if (confin) {
+    while (read_cfg_line(confin, cfgline) >= 0) {
+      if (cfgline.size () >= 2) {
+	key = cfgline[0];
+	cfgline.erase(cfgline.begin());
+
+	// configure the configurables
+	configurable *configureObject;
+	vector<configurable *>::iterator configureIter = configureobjs.begin();
+
+	while (configureIter != configureobjs.end()) {
+	  configureObject = *configureIter;
+	  ++configureIter;
+    
+	  configureObject->configure (key, cfgline);
+	}
+      }
+    }
+    confin.close ();
+    return true;
+  }
+  return false;
+}
Index: /gsdl/stable/common-src/src/lib/cnfgator.h
===================================================================
--- /gsdl/stable/common-src/src/lib/cnfgator.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/cnfgator.h	(revision 20131)
@@ -0,0 +1,18 @@
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace/std/vector>
+#else
+#  include <vector>
+#endif
+
+#include "cfgread.h"
+#include "cnfgable.h"
+
+class configurator
+{ 
+ private:
+  vector<configurable *> configureobjs;
+ public:
+  configurator(configurable *configureobject);
+  bool configure(const text_t &filename);
+  void add_configurable(configurable *configureobject);
+};
Index: /gsdl/stable/common-src/src/lib/dbclass.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/dbclass.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/dbclass.cpp	(revision 20131)
@@ -0,0 +1,309 @@
+/**********************************************************************
+ *
+ * dbclass.cpp -- 
+ * Copyright (C) 1999-2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "dbclass.h"
+#include "OIDtools.h"
+#include "unitool.h"
+
+
+dbclass::~dbclass() {}
+
+
+// May be overwritten by subclasses; returns true if exists
+bool dbclass::exists (const text_t& key)
+{
+  text_t data;
+  return getkeydata (key, data);
+}
+
+
+// May be overwritten by subclasses; returns true on success
+bool dbclass::getinfo (const text_t& key, infodbclass &info)
+{
+  text_t data;
+  if (!getkeydata(key, data)) return false;
+
+  // Use getinfoline() to parse the data value into the infodbclass object
+  text_t::iterator data_iterator = data.begin();
+  text_t ikey, ivalue;
+  info.clear();
+  while (getinfoline(data_iterator, data.end(), ikey, ivalue))
+  {
+    info.addinfo(ikey, ivalue);
+  }
+
+  return true;
+}
+
+
+// returns true on success
+bool dbclass::getinfoline (text_t::iterator &here, text_t::iterator end, 
+			   text_t &key, text_t &value)
+{
+  key.clear();
+  value.clear();
+
+  // ignore white space
+  while (here != end && is_unicode_space (*here)) ++here;
+
+  // get the '<'
+  if (here == end || *here != '<') return false;
+  ++here;
+  
+  // get the key
+  while (here != end && *here != '>') {
+    key.push_back(*here);
+    ++here;
+  }
+  
+  // get the '>'
+  if (here == end || *here != '>') return false;
+  ++here;
+  
+  // get the value
+  while (here != end && *here != '\n') {
+    if (*here == '\\') { 
+      // found escape character
+      ++here;
+      if (here != end) {
+	if (*here == 'n') value.push_back ('\n');
+	else if (*here == 'r') value.push_back ('\r');
+	else value.push_back(*here);
+      }
+
+    } else {
+      if(*here != '\r') {
+	// a normal character
+	value.push_back(*here);
+      }
+    }
+
+    ++here;
+  }
+
+  return true;
+}
+
+
+// returns true on success
+bool dbclass::setinfo (const text_t &key, const infodbclass &info)
+{
+  text_t subkey;
+  text_t data;
+
+  // get all the keys and values
+  infodbclass::const_iterator info_here = info.begin();
+  infodbclass::const_iterator info_end = info.end();
+  while (info_here != info_end) {
+    // add the key
+    subkey.clear();
+    subkey.push_back('<');
+    text_t::const_iterator subkey_here = (*info_here).first.begin();
+    text_t::const_iterator subkey_end = (*info_here).first.end();
+    while (subkey_here != subkey_end) {
+      if (*subkey_here == '>') {
+	subkey.push_back('\\'); subkey.push_back('>');
+      } else if (*subkey_here == '\n') {
+	subkey.push_back('\\'); subkey.push_back('n');
+      } else if (*subkey_here == '\r') {
+	subkey.push_back('\\'); subkey.push_back('r');
+      } else if (*subkey_here == '\\') {
+	subkey.push_back('\\'); subkey.push_back('\\');
+      } else {
+	subkey.push_back (*subkey_here);
+      }
+      ++subkey_here;
+    }
+    subkey.push_back('>');
+
+    // add the values
+    text_tarray::const_iterator subvalue_here = (*info_here).second.begin();
+    text_tarray::const_iterator subvalue_end = (*info_here).second.end();
+    while (subvalue_here != subvalue_end) {
+      data += subkey;
+      
+      text_t::const_iterator thissubvalue_here = (*subvalue_here).begin();
+      text_t::const_iterator thissubvalue_end = (*subvalue_here).end();
+      while (thissubvalue_here != thissubvalue_end) {
+	if (*thissubvalue_here == '>') {
+	  data.push_back('\\'); data.push_back('>');
+	} else if (*thissubvalue_here == '\n') {
+	  data.push_back('\\'); data.push_back('n');
+	} else if (*thissubvalue_here == '\r') {
+	  data.push_back('\\'); data.push_back('r');
+	} else if (*thissubvalue_here == '\\') {
+	  data.push_back('\\'); data.push_back('\\');
+	} else {
+	  data.push_back (*thissubvalue_here);
+	}
+	
+	++thissubvalue_here;
+      }
+      
+      data.push_back('\n');
+      ++subvalue_here;
+    }
+
+    ++info_here;
+  }
+
+  return setkeydata(key, data);
+}
+
+
+// replaces the .fc, .lc, .pr, .rt, .ns and .ps syntax (first child, 
+// last child, parent, root, next sibling, previous sibling) 
+// it expects child, parent, etc. to exist if syntax has been used
+// so you should test before using
+text_t dbclass::translate_OID (const text_t &inOID, infodbclass &info)
+{
+  if (inOID.size() < 4) return inOID;
+  if (findchar (inOID.begin(), inOID.end(), '.') == inOID.end()) return inOID;
+
+  text_t OID = inOID;
+  text_tarray tailarray;
+  text_t tail = substr (OID.end()-3, OID.end());
+  if (tail == ".rt") {
+    get_top (inOID, OID);
+    return OID;
+  }
+  while (tail == ".fc" || tail == ".lc" || tail == ".pr" || 
+	 tail == ".ns" || tail == ".ps") {
+    tailarray.push_back(tail);
+    OID.erase (OID.end()-3, OID.end());
+    tail = substr (OID.end()-3, OID.end());
+    if (tail == ".rt") {
+      get_top (inOID, OID);
+      return OID;
+    }
+  }
+
+  if (tailarray.empty()) return inOID;
+  text_tarray::const_iterator begin = tailarray.begin();
+  text_tarray::const_iterator here = tailarray.end() - 1;
+
+  while (here >= begin) {
+
+    if (*here == ".fc")
+      get_first_child (OID, info);
+    else if (*here == ".lc")
+      get_last_child (OID, info);
+    else if (*here == ".pr")
+      OID = get_parent (OID);
+    else if (*here == ".ns")
+      get_next_sibling (OID, info);
+    else if (*here == ".ps")
+      get_previous_sibling (OID, info);
+    
+    if (here == begin)
+      break;
+    --here;
+  }
+
+  return OID;
+}
+
+
+void dbclass::get_first_child (text_t &OID, infodbclass &info)
+{
+  text_t firstchild;
+  if (getinfo (OID, info)) {
+    text_t &contains = info["contains"];
+    if (!contains.empty()) {
+      text_t parent = OID;
+      getdelimitstr (contains.begin(), contains.end(), ';', firstchild);
+      if (firstchild.empty()) OID = contains;
+      else OID = firstchild;
+      if (*(OID.begin()) == '"') translate_parent (OID, parent);
+    }
+  }
+}
+
+
+void dbclass::get_last_child (text_t &OID, infodbclass &info)
+{
+  text_tarray children;
+  if (getinfo (OID, info)) {
+    text_t &contains = info["contains"];
+    if (!contains.empty()) {
+      text_t parent = OID;
+      splitchar (contains.begin(), contains.end(), ';', children);
+      OID = children.back();
+      if (*(OID.begin()) == '"') translate_parent (OID, parent);
+    }
+  }
+}
+
+  
+void dbclass::get_next_sibling (text_t &OID, infodbclass &info)
+{
+  text_tarray siblings;
+  text_t parent = get_parent (OID);
+	     
+  if (getinfo (parent, info)) {
+    text_t &contains = info["contains"];
+    if (!contains.empty()) {
+      splitchar (contains.begin(), contains.end(), ';', siblings);
+      text_tarray::const_iterator here = siblings.begin();
+      text_tarray::const_iterator end = siblings.end();
+      text_t shrunk_OID = OID;
+      shrink_parent (shrunk_OID);
+      while (here != end) {
+	if (*here == shrunk_OID && (here+1 != end)) {
+	  OID = *(here+1);
+	  if (*(OID.begin()) == '"') translate_parent (OID, parent);
+	  break;
+	}
+	++here;
+      }
+    }
+  }
+}
+
+
+void dbclass::get_previous_sibling (text_t &OID, infodbclass &info)
+{
+  text_tarray siblings;
+  text_t parent = get_parent (OID);
+
+  if (getinfo (parent, info)) {
+    text_t &contains = info["contains"];
+    if (!contains.empty()) {
+      splitchar (contains.begin(), contains.end(), ';', siblings);
+      text_tarray::const_iterator here = siblings.begin();
+      text_tarray::const_iterator end = siblings.end();
+      text_t shrunk_OID = OID;
+      shrink_parent (shrunk_OID);
+      while (here != end) {
+	if (*here == shrunk_OID && (here != siblings.begin())) {
+	  OID = *(here-1);
+	  if (*(OID.begin()) == '"') translate_parent (OID, parent);
+	  break;
+	}
+	++here;
+      }
+    }
+  }
+}
Index: /gsdl/stable/common-src/src/lib/dbclass.h
===================================================================
--- /gsdl/stable/common-src/src/lib/dbclass.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/dbclass.h	(revision 20131)
@@ -0,0 +1,113 @@
+/**********************************************************************
+ *
+ * dbclass.h -- 
+ * Copyright (C) 1999-2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef DBCLASS_H
+#define DBCLASS_H
+
+
+#include "text_t.h"
+#include "infodbclass.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#  include <ospace\std\fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#  include <fstream.h>
+#else
+#  include <iostream>
+#  include <fstream>
+#endif
+
+
+#define DB_READER         1
+#define DB_WRITER         2
+#define DB_WRITER_CREATE  3
+
+
+class dbclass
+{
+public:
+  dbclass() { logout = &cerr; }
+  virtual ~dbclass();
+
+  void setlogout (ostream *logout_arg) { logout = logout_arg; }
+
+
+  // -----------------------------------------------------------------------------------------------
+  // These functions MUST be implemented by subclasses, as they are database-specific
+
+  // returns true if opened
+  virtual bool opendatabase (const text_t &filename, int mode, int num_retrys, bool need_filelock) = 0;
+
+  virtual void closedatabase () = 0;
+
+  virtual void deletekey (const text_t &key) = 0;
+
+  // returns file extension string
+  virtual text_t getfileextension () = 0;
+
+  // returns true on success
+  virtual bool getkeydata (const text_t& key, text_t &data) = 0;
+
+  // returns array of keys
+  virtual text_tarray getkeys () = 0;
+
+  // returns true on success
+  virtual bool setkeydata (const text_t &key, const text_t &data) = 0;
+
+
+  // -----------------------------------------------------------------------------------------------
+  // These functions may be overwritten by subclasses, but a default implementation is provided
+
+  // returns true if exists
+  virtual bool exists (const text_t& key);
+
+  // returns true on success
+  virtual bool getinfo (const text_t& key, infodbclass &info);
+
+  // returns true on success
+  virtual bool setinfo (const text_t &key, const infodbclass &info);
+
+
+  // replaces the .c, .p, .n, .l syntax (child, parent, next, previous) 
+  // it expects child, parent, etc. to exist if syntax has been used
+  // so you should test before using
+  text_t translate_OID(const text_t &OID, infodbclass &info);
+
+protected:
+  ostream *logout;
+
+  // returns true on success
+  bool getinfoline (text_t::iterator &here, text_t::iterator end, text_t &key, text_t &value);
+
+  void get_first_child (text_t &OID, infodbclass &info);
+  void get_last_child (text_t &OID, infodbclass &info);
+  void get_next_sibling (text_t &OID, infodbclass &info);
+  void get_previous_sibling (text_t &OID, infodbclass &info);
+};
+
+
+#endif
Index: /gsdl/stable/common-src/src/lib/display.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/display.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/display.cpp	(revision 20131)
@@ -0,0 +1,1834 @@
+/**********************************************************************
+ *
+ * display.cpp -- Context sensitive macro language
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "display.h"
+#include "gsdlunicode.h"
+#include "unitool.h"
+#include <assert.h>
+
+// include to get NULL
+#include <stdlib.h>
+
+text_t displayclass::defaultpackage = "Global";
+
+/////////////////////////////////////
+// misc classes
+/////////////////////////////////////
+
+
+// precedencetype defines a 'precedence value' for each parameter
+typedef map<text_t, double, lttext_t> precedencetype;
+
+
+
+inline bool operator==(const mvalue &x, const mvalue &y) {
+  return (x.filename==y.filename && x.value==y.value);
+}
+
+inline bool operator<(const mvalue &x, const mvalue &y) {
+  return (x.filename<y.filename ||
+	  (x.filename==y.filename && x.filename<y.filename));
+}
+
+
+
+/////////////////////////////////////
+// stuff for parammacros_t
+/////////////////////////////////////
+  
+typedef map<text_t, mvalue, lttext_t> defparammap;
+typedef map<text_t, defparammap, lttext_t> defmacromap;
+typedef map<text_t, defmacromap, lttext_t> defpackagemap;
+
+// all methods in parammacros_t assume the parameters
+// and packages in a standard form and not empty
+class parammacros_t
+{
+protected:
+  defpackagemap macros;
+
+public:
+  typedef defpackagemap::const_iterator const_package_iterator;
+  typedef defpackagemap::size_type package_size_type;
+
+  // setmacro returns 0 if there was no error,
+  //            -1 if it redefined a macro
+  //            -2 if it hid a Global macro
+  //            -3 if it redefined a macro and hid a Global macro
+  //            -4 if either a package, macroname, or params were not supplied
+  int setmacro(const text_t &package,
+	  const text_t &macroname, 
+	  const text_t &params, 
+	  const text_t &filename, 
+	  const text_t &macrovalue);
+
+  void delmacro(const text_t &package,
+	      const text_t &macroname, 
+	      const text_t &params);
+
+  void clear () {macros.erase(macros.begin(), macros.end());}
+
+  // top level stuff
+  const_package_iterator package_begin () const {return macros.begin();}
+  const_package_iterator package_end () const {return macros.end();}
+  bool package_empty () const {return macros.empty();}
+  package_size_type package_size() const {return macros.size();}
+
+  // methods to find things
+  defmacromap *package_find (const text_t &packagename);
+  defparammap *macro_find (const text_t &packagename, 
+			   const text_t &macroname);
+  mvalue *parameter_find (const text_t &packagename, 
+			  const text_t &macroname,
+			  const text_t &parametername);
+};
+
+
+// setmacro returns 0 if there was no error,
+//            -1 if it redefined a macro
+//            -2 if it hid a Global macro
+//            -3 if it redefined a macro and hid a Global macro
+//            -4 if either a package, macroname, or params were not supplied
+int parammacros_t::setmacro(const text_t &package,
+			 const text_t &macroname, 
+			 const text_t &params, 
+			 const text_t &filename, 
+			 const text_t &macrovalue)
+{
+  paramhashtype paramhash;
+
+  defmacromap *macromapptr;
+  defparammap *parammapptr;
+  mvalue *mvalueptr;
+
+  int warning = 0;
+
+  // check to see if we would be hiding a Global macro with the 
+  // same name. Note: it doesn't matter what parameters are used
+  // a Global macro will still be hid by a non-Global one with
+  // the same name.
+  if ((package != displayclass::defaultpackage) && 
+      (macro_find (displayclass::defaultpackage, macroname) != NULL))
+    {
+      warning -= 2; // found the macroname
+    }
+
+  // define this macro
+  macromapptr = &(macros[package]); // -- package
+  parammapptr = &((*macromapptr)[macroname]); // -- macro name
+  // -- parameters
+  if ((*parammapptr).find(params) != (*parammapptr).end()) {
+    warning -= 1; // found the parameters
+  }
+  mvalueptr = &((*parammapptr)[params]);
+
+  // -- value
+  (*mvalueptr).filename = filename;
+  (*mvalueptr).value = macrovalue;
+
+  return warning;
+}
+
+void parammacros_t::delmacro(const text_t &package,
+			     const text_t &macroname, 
+			     const text_t &params)
+{
+  // make sure everything was supplied
+  if (package.empty() || macroname.empty() || params.empty()) return;
+
+  // find the package and macroname
+  defparammap *parammapptr = macro_find(package, macroname);
+  if (parammapptr == NULL) return;
+
+  // find the parameters
+  defparammap::iterator parammapit = parammapptr->find(params);
+  if (parammapit == parammapptr->end()) return;
+
+  // finally delete this element
+  parammapptr->erase(parammapit);
+}
+
+defmacromap *parammacros_t::package_find (const text_t &packagename)
+{
+  if (packagename.empty()) return NULL;
+
+  defpackagemap::iterator it = macros.find(packagename);
+  if (it == macros.end()) return NULL;
+
+  return &((*it).second);
+}
+
+defparammap *parammacros_t::macro_find (const text_t &packagename, 
+					const text_t &macroname)
+{
+  defmacromap *macromapptr = package_find(packagename);
+  if (macromapptr == NULL || macroname.empty()) return NULL;
+  
+  defmacromap::iterator it = (*macromapptr).find(macroname);
+  if (it == (*macromapptr).end()) return NULL;
+
+  return &((*it).second);
+}
+
+mvalue *parammacros_t::parameter_find (const text_t &packagename, 
+					 const text_t &macroname,
+					 const text_t &parametername)
+{
+  defparammap *parammapptr = macro_find(packagename, macroname);
+  if (parammapptr == NULL || parametername.empty()) return NULL;
+
+  defparammap::iterator it = (*parammapptr).find(parametername);
+  if (it == (*parammapptr).end()) return NULL;
+
+  return &((*it).second);
+}
+
+
+
+/////////////////////////////////////
+// stuff for currentmacros_t
+/////////////////////////////////////
+
+typedef map<text_t, mvalue, lttext_t> curmacromap;
+typedef map<text_t, curmacromap, lttext_t> curpackagemap;
+
+// all methods in currentmacros_t assume the parameters
+// and packages in a standard form and not empty
+class currentmacros_t 
+{
+protected:
+  curpackagemap macros;
+
+public:
+  typedef curpackagemap::const_iterator const_package_iterator;
+  typedef curpackagemap::size_type package_size_type;
+
+  // setmacro returns 0 if there was no error,
+  //            -1 if it redefined a macro
+  //            -4 if either a package, or macroname were not supplied
+  int setmacro(const text_t &package,
+	  const text_t &macroname, 
+	  const text_t &filename, 
+	  const text_t &macrovalue);
+
+  void delmacro(const text_t &package,
+		const text_t &macroname);
+
+  void clear () {macros.erase(macros.begin(), macros.end());}
+
+  // top level stuff
+  const_package_iterator package_begin () const {return macros.begin();}
+  const_package_iterator package_end () const {return macros.end();}
+  bool package_empty () const {return macros.empty();}
+  package_size_type package_size() const {return macros.size();}
+
+  // methods to find things
+  curmacromap *package_find (const text_t &packagename);
+  mvalue *macro_find (const text_t &packagename, 
+		      const text_t &macroname);
+};
+
+
+// setmacro returns 0 if there was no error,
+//            -1 if it redefined a macro
+//            -4 if either a package, or macroname were not supplied
+int currentmacros_t::setmacro(const text_t &package,
+			 const text_t &macroname, 
+			 const text_t &filename, 
+			 const text_t &macrovalue)
+{
+  int warning = 0;
+
+  // make sure everything was supplied
+  if (package.empty() || macroname.empty()) return -4;
+
+  // define this macro
+  curmacromap *macromapptr = &(macros[package]);
+  if ((*macromapptr).find(macroname) != (*macromapptr).end()) 
+    {
+      warning -= 1; // found the macroname
+    }
+  mvalue *mvalueptr = &((*macromapptr)[macroname]);
+
+  // -- value
+  (*mvalueptr).filename = filename;
+  (*mvalueptr).value = macrovalue;
+
+  return warning;
+}
+
+void currentmacros_t::delmacro(const text_t &package,
+			     const text_t &macroname)
+{
+  // make sure everything was supplied
+  if (package.empty() || macroname.empty()) return;
+
+  // find the package
+  curmacromap *macromapptr = package_find(package);
+  if (macromapptr == NULL) return;
+
+  // find the macroname
+  curmacromap::iterator macromapit = macromapptr->find(macroname);
+  if (macromapit == macromapptr->end()) return;
+
+  // finally delete this element
+  macromapptr->erase(macromapit);
+}
+
+curmacromap *currentmacros_t::package_find (const text_t &packagename)
+{
+  if (packagename.empty()) return NULL;
+
+  curpackagemap::iterator it = macros.find(packagename);
+  if (it == macros.end()) return NULL;
+
+  return &((*it).second);
+}
+
+mvalue *currentmacros_t::macro_find (const text_t &packagename, 
+				     const text_t &macroname)
+{
+  curmacromap *macromapptr = package_find(packagename);
+  if (macromapptr == NULL || macroname.empty()) return NULL;
+
+  curmacromap::iterator it = (*macromapptr).find(macroname);
+  if (it == (*macromapptr).end()) return NULL;
+
+  return &((*it).second);
+}
+
+
+
+
+/////////////////////////////////////
+// support functions
+/////////////////////////////////////
+
+// this calculation of precedence will make one occurance of a high
+// precedence item override many occurances of lower precedence items
+void calcprecedence (const text_t &precedstr, precedencetype &precedhash) 
+{
+  text_t param;
+  double multiple = 5.0;
+  double nextprec = multiple;
+
+  text_t::const_iterator here, end;
+
+  // set precedhash to an empty hash
+  precedhash.erase(precedhash.begin(), precedhash.end());
+
+  // iterate through paramstring ignoring space and extracting
+  // out key value pairs.
+  here = precedstr.begin();
+  end = precedstr.end();
+  while (here != end) 
+    {
+      // get the next parameter
+      param.clear(); // set param to an empty string
+      
+      while (here != end) 
+	{
+	  if (*here == ',') 
+	    {
+	      // found the end of the parameter
+	      ++here;
+	      break;
+	    } 
+	  else if (*here == ' ') 
+	    {
+	      // do nothing (ignore spaces)
+	    } 
+	  else 
+	    {
+	      // character in parameter
+	      param.push_back (*here); // copy this character
+	    }
+	  
+	  ++here;
+	}
+
+      // if a parameter was found insert its value
+      if (!param.empty()) 
+	{
+	  precedhash[param] = nextprec;
+	  nextprec *= multiple;
+	}
+    }
+}
+
+
+// decides how specific any given parameter is to the page parameters. Returns 
+// negative if any options are different or else the sum of the precedence for
+// the options which match. 
+double getspecificness(const paramhashtype &pageparams, 
+		       const paramhashtype &theseparams, 
+		       const precedencetype &precedhash) 
+{
+  double specificness = 0.0;
+  paramhashtype::const_iterator here, pagevalueit;
+  precedencetype::const_iterator precedit;
+  text_t thesekey, thesevalue, constignore("ignore");
+  
+  here = theseparams.begin();
+  while (here != theseparams.end()) 
+    {
+      thesekey = (*here).first;
+      thesevalue = (*here).second;
+      
+      if (thesekey == constignore) 
+	{
+	  // do nothing, this is a placeholder
+	} 
+      else 
+	{
+	  pagevalueit = pageparams.find(thesekey);
+	  if ((pagevalueit != pageparams.end()) && 
+	      ((*pagevalueit).second == thesevalue)) 
+	    {
+	      // this parameter fits, add its precedence value
+	      precedit = precedhash.find(thesekey);
+	      if (precedit == precedhash.end()) 
+		specificness += 1.0; // no precedence defined
+	      else 
+		  specificness += (*precedit).second;
+	    }
+	  else 
+	    {
+	      return -1.0; // did not match
+	    }
+	}
+
+      ++here;
+    }
+  
+  return specificness;
+}
+
+
+void splitparams (const text_t &paramstring, paramhashtype &paramhash)
+{
+  text_t key;
+  text_t value;
+
+  text_t::const_iterator here, end;
+
+  // set paramhash to an empty hash
+  paramhash.erase(paramhash.begin(), paramhash.end());
+
+  // iterate through paramstring ignoring space and extracting
+  // out key value pairs.
+  here = paramstring.begin();
+  end  = paramstring.end();
+  while (here != end) 
+    {
+      // reset key and value
+      key.clear();
+      value.clear();
+
+      // get key
+      while (here != end) 
+	{
+	  if (*here == ',') 
+	    {
+	      // have a key with no value
+	      break;
+	    } 
+	  else if (*here == '=') 
+	    {
+	      // found the end of the key
+	      ++here; 
+	      break;
+	    } 
+	  else if (*here == ' ') 
+	    {
+	      // do nothing (ignore spaces)
+	    } 
+	  else 
+	    {
+	      // character in key
+	      key.push_back (*here); // copy this character
+	    }
+	  ++here;
+	}
+
+      // get value
+      while (here != end) 
+	{
+	  if (*here == '=') 
+	    {
+	      // multiple values for one key, ignore previous
+	      // values
+	      value.clear();
+	    } 
+	  else if (*here == ',') 
+	    {
+	      // found the end of the value
+	      ++here;
+	      break;
+	    } 
+	  else if (*here == ' ') 
+	    {
+	      // do nothing (ignore spaces)
+	    } 
+	  else 
+	    {
+	      // character in value
+	      value.push_back (*here); // copy this character
+	    }
+	  ++here;
+	}
+    
+      // if a key was found insert the key/value pair in 
+      // the map 
+      if (!key.empty()) 
+	{
+	  paramhash[key] = value;
+	}
+    }
+}
+
+
+void joinparams (const paramhashtype &paramhash, text_t &paramstring)
+{
+  //set paramstring to an empty string
+  paramstring.clear();
+
+  //iterate through the paramhash
+  paramhashtype::const_iterator thepair;
+  int firstparam = 1;
+
+  for (thepair=paramhash.begin();thepair!=paramhash.end(); ++thepair)
+    {
+      if (!firstparam) paramstring.push_back(',');
+      firstparam = 0;
+      
+      // insert pairs of "key=value"
+      text_t thevalue;
+      paramstring.append((*thepair).first);
+      paramstring.push_back('=');
+      paramstring.append((*thepair).second);
+    }
+}
+
+
+
+/////////////////////////////////////
+// parsing support functions
+/////////////////////////////////////
+
+inline int my_isalpha (unsigned short c) 
+{
+  return ((c >= 'A' && c <= 'Z') ||
+	  (c >= 'a' && c <= 'z'));
+} 
+
+inline int my_isalphanum (unsigned short c) 
+{
+  return ((c >= 'A' && c <= 'Z') ||
+	  (c >= 'a' && c <= 'z') || (c >='0' && c <= '9'));
+} 
+ 
+
+
+inline unsigned short my_ttnextchar (text_t::const_iterator &here, 
+				     text_t::const_iterator &end) 
+{
+  if (here != end) 
+    {
+      ++here;
+      if (here != end) return (*here);
+    }
+  return '\0';
+}
+
+
+
+/////////////////////////////////////
+// methods for display
+/////////////////////////////////////
+
+// public methods for display
+
+displayclass::displayclass ()
+{
+  defaultmacros    = new parammacros_t;
+  collectionmacros = new parammacros_t;
+  defaultfiles     = new fileinfomap;
+  
+  orderparamlist = new paramspeclist;
+  currentmacros = new currentmacros_t;
+
+  outc = NULL;
+
+  logout = NULL;
+
+  /* this is a bit of a hack, but if the displayclass has never seen this
+     parameter before when it does openpage() then macros with this set will
+     always be ignored. And we set collection-specific macros after doing
+     openpage() - jrm */
+  allparams.insert("l=en");
+}
+
+
+displayclass::~displayclass ()
+{
+  delete defaultmacros;
+  delete collectionmacros;
+  delete defaultfiles;
+  
+  delete orderparamlist;
+  delete currentmacros;
+}
+  
+// setdefaultmacro adds an entry to the list of default macros 
+// returns 0 if there was no error,
+//        -1 if it redefined a macro
+//        -2 if it hid a Global macro
+//        -3 if it redefined a macro and hid a Global macro
+//        -4 if no macroname was supplied
+int displayclass::setdefaultmacro (const text_t &package, const text_t &macroname, 
+				   const text_t &mparams, const text_t &macrovalue) 
+{
+  return setdefaultmacro (package, macroname, mparams, "memory", macrovalue);
+}
+
+
+
+// as we are using one character lookahead the
+// value of line might be off by one.
+// the input file must be in the utf-8 or unicode format
+// initially for each file isunicode should be set to 0 and 
+// bigendian should be set to 1
+// 0 will be returned when the end of the file has been found
+unsigned short my_uni_get (/*unistream*/ifstream &fin, int &line, 
+			   int &isunicode, int &bigendian) {
+  unsigned short c = 0;
+  
+  if (isunicode) {
+    // unicode text
+    // get the next two characters
+    unsigned char c1 = 0, c2 = 0;
+    
+    if (!fin.eof()) c1=fin.get();
+    if (!fin.eof()) c2=fin.get();
+    else c1 = 0;
+
+    // if they indicate the order get the next character
+    // otherwise just get these characters
+    if (c1 == 0xff && c2 == 0xfe) {
+      bigendian = 0;
+      c = my_uni_get (fin, line, isunicode, bigendian);
+    } else if (c1 == 0xfe && c2 == 0xff) {
+      bigendian = 1;
+      c = my_uni_get (fin, line, isunicode, bigendian);
+    } else c = (bigendian) ? (c1*256+c2) : (c2*256+c1);
+    
+  } else {
+    // utf-8 text
+    // how many characters we get depends on what we find
+    unsigned char c1 = 0, c2 = 0, c3 = 0;
+    while (!fin.eof()) {
+      c1=fin.get();
+      if (c1 == 0xfe || c1 == 0xff) {
+	// switch to unicode
+	isunicode = 1;
+	if (!fin.eof()) c2=fin.get();
+
+	if (c1 == 0xff && c2 == 0xfe) bigendian = 0;
+	else bigendian = 1;
+
+	c = my_uni_get (fin, line, isunicode, bigendian);
+	break;
+
+      } else if (c1 <= 0x7f) {
+	// one byte character
+	c = c1;
+	break;
+
+      } else if (c1 >= 0xc0 && c1 <= 0xdf) {
+	// two byte character
+	if (!fin.eof()) c2=fin.get();
+	c = ((c1 & 0x1f) << 6) + (c2 & 0x3f);
+	break;
+
+      } else if (c1 >= 0xe0 && c1 <= 0xef) {
+	// three byte character
+	if (!fin.eof()) c2=fin.get();
+	if (!fin.eof()) c3=fin.get();
+	c = ((c1 & 0xf) << 12) + ((c2 & 0x3f) << 6) + (c3 & 0x3f);
+	break;
+      }
+
+      // if we get here there was an error in the file, we should
+      // be able to recover from it however, maybe the file is in
+      // another encoding
+    }
+  }
+
+  if (c == '\n') ++line;
+  return c;
+}
+
+
+
+// loads a macro file into the specified macrotable datastructure
+// returns 0 if didn't need to load the file (it was already loaded)
+//         1 if was (re)loaded
+//        -1 an error occurred while trying to load the file
+int displayclass::loadparammacros (parammacros_t* macrotable, const text_t &thisfilename) {
+  // convert the filename to a C string
+  char *filenamestr = thisfilename.getcstr();
+  outconvertclass text_t2ascii;
+
+  // see if we need to open this file -- this isn't implemented yet
+  
+  // open the file
+  //  unistream fin (filenamestr);
+  ifstream fin (filenamestr);
+
+  if (fin.fail()) return -1; // read failed
+
+  text_t package = defaultpackage;
+  int line = 1;
+  int isunicode = 0, bigendian = 1;
+
+  // pre-fetch the next character
+  unsigned short c = my_uni_get(fin, line, isunicode, bigendian);
+
+  text_t macropackage, macroname, macroparameters, macrovalue;
+  int err; // for keeping track of whether an error occurred somewhere
+
+  while (!fin.eof()) {
+    // expect: white space, comment, "package", or macroname
+    if (is_unicode_space(c)) {
+      // found some white-space
+      c = my_uni_get(fin, line, isunicode, bigendian);
+
+    } else if (c == '#') {
+      // found the start of a comment
+      // skip all characters up to the end of the line
+      c = my_uni_get(fin, line, isunicode, bigendian); // skip the '#'
+      while (!fin.eof ()) {
+	if (c == '\n') break;
+	c = my_uni_get(fin, line, isunicode, bigendian);
+      }
+
+    } else if (c == 'p') {
+      // found the start of 'package' (hopefully)
+      // get everything up to the next space
+      text_t tmp;
+      while (!fin.eof() && my_isalpha(c)) {
+	tmp.push_back(c);
+	c = my_uni_get(fin, line, isunicode, bigendian);
+      }
+      // see if we have a package name
+      if (tmp == "package") {
+	// skip all white space
+	while (!fin.eof() && is_unicode_space(c)) 
+	  c = my_uni_get(fin, line, isunicode, bigendian);
+	
+	// get the package name
+	tmp.clear(); // init tmp
+	while (!fin.eof() && my_isalphanum(c)) {
+	  tmp.push_back(c);
+	  c = my_uni_get(fin, line, isunicode, bigendian);
+	}
+	package = tmp;
+	if (package.empty()) package = defaultpackage;
+
+      } else {
+	// error
+	if (logout != NULL) {
+	  (*logout) << text_t2ascii << text_t("Expected 'package' on line ") + line + text_t(" of ") + thisfilename + "\n";
+	}
+      }
+      
+    } else if (c == '_') {
+      // found the start of a macro (hopefully)
+      c = my_uni_get(fin, line, isunicode, bigendian); // skip the _
+
+      // init variables
+      err = 0;
+      macropackage = package;
+      macroname.clear(); // init macroname
+      macroparameters.clear(); // init macroname
+      macrovalue.clear(); // init macroname
+      
+      // get the macro name
+      while ((!fin.eof()) && (!is_unicode_space(c)) && 
+	     (c != '\\') && (c != '_') &&(c != ':') && 
+	     (macroname.size() < 80)) {
+	macroname.push_back(c);
+	c = my_uni_get(fin, line, isunicode, bigendian);
+      }
+	  
+      if (c == ':') {
+	// we actually had the macro package
+	c = my_uni_get(fin, line, isunicode, bigendian); // skip :
+	macropackage = macroname;
+	macroname.clear ();
+	
+	// get the macro name (honest!)
+	while ((!fin.eof()) && (!is_unicode_space(c)) && 
+	       (c != '\\') && (c != '_') &&(c != ':') && 
+	       (macroname.size() < 80)) {
+	  macroname.push_back(c);
+	  c = my_uni_get(fin, line, isunicode, bigendian);
+	}
+      }
+      
+      if (!err && c == '_') {
+	c = my_uni_get(fin, line, isunicode, bigendian); // skip the _
+	
+	// skip all white space
+	while (!fin.eof() && is_unicode_space(c)) c = my_uni_get(fin, line, isunicode, bigendian);
+      } else if (!err) err = 1;
+
+      // get the macro parameters (optional)
+      if (!err && c == '[') {
+	c = my_uni_get(fin, line, isunicode, bigendian); // skip the [
+	while ((!fin.eof()) && (c != '\n') && (c != '\\') && (c != ']')) {
+	  macroparameters.push_back(c);
+	  c = my_uni_get(fin, line, isunicode, bigendian);
+	}
+	
+	if (c == ']') {
+	  c = my_uni_get(fin, line, isunicode, bigendian); // skip the ]
+	  
+	  // skip all white space
+	  while (!fin.eof() && is_unicode_space(c)) c = my_uni_get(fin, line, isunicode, bigendian);
+	} 
+	else if (!err) err = 2;
+      }
+
+      // get the macro value
+      if (!err && c == '{') {
+	c = my_uni_get(fin, line, isunicode, bigendian); // skip the {
+	while ((!fin.eof()) && (c != '}')) {
+	  if (c == '\\') {
+	    macrovalue.push_back(c); // keep the '\'
+	    c = my_uni_get(fin, line, isunicode, bigendian); // store the *next* value regardless
+	    if (!fin.eof()) macrovalue.push_back(c);
+	    c = my_uni_get(fin, line, isunicode, bigendian);
+	  }
+	  macrovalue.push_back(c);
+	  c = my_uni_get(fin, line, isunicode, bigendian);
+	}
+	
+	if (c == '}') {
+	  c = my_uni_get(fin, line, isunicode, bigendian); // skip the }
+	  
+	  // define the macro
+	  err = setparammacro (macrotable, macropackage, macroname, macroparameters,
+			       thisfilename, macrovalue);
+	  if ((err == -1 || err == -3) && logout != NULL) {
+	    (*logout) << text_t2ascii << ("Warning: redefinition of _" + package + ":" + macroname + "_[" + macroparameters + "] on line " + line +  " of " + thisfilename + "\n");
+	    
+	  } else if (err == -2 && logout != NULL) {
+	    // I don't think we really want this warning since it's a very
+	    // common occurance - Stefan.
+
+	    //	    (*logout) << text_t2ascii << "Warning: _" << 
+	    //	      package << ":" << macroname << "_[" << macroparameters <<
+	    //	      "] on line ";
+	    //	    (*logout) << line;
+	    //	    (*logout) << text_t2ascii << " of " << 
+	    //	      thisfilename << " hides a Global macro with the same name\n";
+
+	  } else if (err == -4 && logout != NULL) {
+	    (*logout) << text_t2ascii << text_t("Error: macro name expected on line ") +  line + text_t(" of ") + thisfilename + "\n";
+	  }		  
+	  
+	  err = 0; // for the test below
+	}
+	else if (!err) err = 3;
+      }
+      else if (!err) err = 4;
+      
+      if (err) {
+	// found an error, skip to the end of the line
+	if (logout != NULL) {
+	  text_t message = "Error: ";
+	  if (err == 1) message += "'_'";
+	  else if (err == 2) message += "']'";
+	  else if (err == 3) message += "'}'";
+	  else if (err == 4) message += "'{'";
+	  message += " expected on line ";
+	  message += line;
+	  message += " of " + thisfilename + "\n";
+	  (*logout) << text_t2ascii << message;
+	  
+// 	  (*logout) << text_t2ascii << "Error: ";
+// 	  if (err == 1) (*logout) << text_t2ascii << "'_'";
+// 	  else if (err == 2) (*logout) << text_t2ascii << "']'";
+// 	  else if (err == 3) (*logout) << text_t2ascii << "'}'";
+// 	  else if (err == 4) (*logout) << text_t2ascii << "'{'";
+// 	  (*logout) << text_t2ascii << " expected on line ";
+// 	  (*logout) << line ;
+// 	  (*logout) << text_t2ascii << " of " << thisfilename << "\n";
+	}
+	while (!fin.eof ()) {
+	  if (c == '\n') break;
+	  c = my_uni_get(fin, line, isunicode, bigendian);
+	}
+      }
+      
+    } else {
+      // found an error, skip to the end of the line
+      if (logout != NULL) {
+	(*logout) << text_t2ascii << text_t("Error: Unexpected input on line ") + line + text_t(" of ") + thisfilename + "\n";
+      }
+      while (!fin.eof ()) {
+	if (c == '\n') break;
+	c = my_uni_get(fin, line, isunicode, bigendian);
+      }
+      
+    }
+  }
+  
+  fin.close ();
+  
+  // free up memory
+  delete []filenamestr;
+  return 0;
+}
+
+
+// loads a default macro file (if it isn't already loaded)
+// returns 0 if didn't need to load the file (it was already loaded)
+//         1 if was (re)loaded
+//        -1 an error occurred while trying to load the file
+int displayclass::loaddefaultmacros (const text_t &thisfilename) 
+{
+  return loadparammacros(defaultmacros,thisfilename);
+}
+
+// loads a collection specific macro file 
+// returns 0 if didn't need to load the file (it was already loaded)
+//         1 if was (re)loaded
+//        -1 an error occurred while trying to load the file
+int displayclass::loadcollectionmacros (const text_t &thisfilename) 
+{
+  return loadparammacros(collectionmacros,thisfilename);
+}
+
+
+void displayclass::unloaddefaultmacros () {
+  defaultmacros->clear();
+}
+
+void displayclass::unloadcollectionmacros () {
+  collectionmacros->clear();
+}
+
+// prepares to create a page.
+void displayclass::openpage (const text_t &thispageparams, 
+			const text_t &thisprecedence)
+{
+  // init variables
+  currentmacros->clear();
+
+  // reload any default macro files which have changed.
+  if (checkdefaultmacrofiles() < 0) 
+    {
+      // print error message
+    }
+
+  setpageparams (thispageparams, thisprecedence);
+}
+
+
+// changes the parameters for the current page.
+void displayclass::setpageparams (text_t thispageparams, 
+			     text_t thisprecedence)
+{
+  paramhashtype thissplitparams, splittheseparams;
+  precedencetype precedhash;
+  text_tset::iterator text_tsetit;
+  paramspec tmpps;
+
+  precedence = thisprecedence;
+  calcprecedence(thisprecedence, precedhash);
+
+  splitparams(thispageparams, thissplitparams);
+  joinparams(thissplitparams, thispageparams);
+  params = thispageparams;
+
+  // get a list of parameters with their specificness
+  orderparamlist->erase(orderparamlist->begin(), orderparamlist->end());
+  for (text_tsetit=allparams.begin();
+       text_tsetit!=allparams.end();
+       ++text_tsetit) 
+    {
+      tmpps.param = (*text_tsetit);
+      splitparams(tmpps.param, splittheseparams);
+      tmpps.spec = getspecificness(thissplitparams, splittheseparams, precedhash);
+      if (tmpps.spec >= 0) 
+	{
+	  orderparamlist->push_back (tmpps);
+	}
+    }
+
+  // sort the list
+  sort(orderparamlist->begin(), orderparamlist->end());
+
+#if 0 // debugging
+  outconvertclass text_t2ascii;
+
+  paramspeclist::iterator pshere = orderparamlist->begin();
+  paramspeclist::iterator psend = orderparamlist->end();
+  while (pshere != psend) 
+    {
+      cerr << text_t2ascii << "param=" << (*pshere).param;
+      cerr << " spec=" << (int)((*pshere).spec) << "\n";
+      ++pshere;
+    }
+#endif
+}
+
+
+// overrides (or sets) a macro for the current page.
+// returns 0 if there was no error,
+//        -1 if it redefined a macro
+//        -4 if no macroname was supplied
+int displayclass::setmacro (const text_t &macroname, 
+			    const text_t &package, 
+			    const text_t &macrovalue)
+{
+  // make sure a macroname was supplied
+  if (macroname.empty()) return -4;
+
+  // make package "Global" if it doesn't point to anything yet
+  if (package.empty()) 
+    return currentmacros->setmacro(defaultpackage, macroname, "memory", macrovalue);
+  
+  // set the macro
+  return currentmacros->setmacro(package, macroname, "memory", macrovalue);
+}
+
+int displayclass::setmacroif (const text_t &macro_to_set_and_test,
+			      const text_t &macro_to_set_if_macro_not_set, 
+			      const text_t &macroname, 	
+			      const text_t &package) {
+  
+  if (macroname.empty()) return -4;
+  if (macro_to_set_and_test.empty()) return -40;
+  
+  text_t temp;
+  expandstring(defaultpackage, macro_to_set_and_test, temp);
+  
+  if (package.empty()) {
+    if (temp == macro_to_set_and_test) return currentmacros->setmacro(defaultpackage, macroname, "memory", macro_to_set_if_macro_not_set);
+    return currentmacros->setmacro(defaultpackage, macroname, "memory", macro_to_set_and_test);
+  } else {
+    if (temp == macro_to_set_and_test) return currentmacros->setmacro(package, macroname, "memory", macro_to_set_if_macro_not_set);
+    return currentmacros->setmacro(package, macroname, "memory", macro_to_set_and_test);
+    
+  }
+}
+
+void displayclass::expandstring (const text_t &package, const text_t &inputtext,
+				 text_t &outputtext, int recursiondepth)
+{
+  text_t macroname, macropackage, macroargs;
+  text_t::const_iterator tthere = inputtext.begin();
+  text_t::const_iterator ttend = inputtext.end();
+  unsigned short c = '\0';
+  int openbrackets=0;
+
+  if (package.empty()) expandstring(defaultpackage, inputtext, outputtext, recursiondepth);
+
+  outputtext.clear();
+  // use one-character lookahead
+  if (tthere != ttend) c = (*tthere);
+  while (tthere != ttend) 
+    {
+      if (c == '\\')
+	{
+	  // found an escape character
+	  c = my_ttnextchar (tthere, ttend); // skip the escape character
+	  if (tthere != ttend) 
+	    {
+	      if (c == 'n') outputtext.push_back('\n');
+	      else if (c == 't') outputtext.push_back('\t');
+	      else outputtext.push_back(c);
+	    }
+	  c = my_ttnextchar (tthere, ttend);
+	  
+	} 
+      else if (c == '_') 
+	{
+	  // might have found the start of a macro
+      
+	  // embedded macros (macros within the names
+	  // of other macros) are no longer supported -- Rodger.
+      
+	  // save the current state (in case we need to back out)
+	  text_t::const_iterator savedtthere = tthere;
+	  unsigned short savedc = c;
+	  
+	  macroname.clear();
+	  macropackage = package;
+	  macroargs.clear();
+      
+	  c = my_ttnextchar (tthere, ttend); // skip the '_'
+	  
+	  // get the macroname
+	  while (tthere != ttend && (!is_unicode_space(c)) && 
+		 (c != '\\') && (c != '_') &&(c != ':') && 
+		 (macroname.size() < 80)) 
+	    {
+	      macroname.push_back((unsigned char)c);
+	      c = my_ttnextchar (tthere, ttend);
+	    }
+      
+	  if (c == ':') 
+	    {
+	      // we actually had the macro package
+	      c = my_ttnextchar (tthere, ttend);
+	      macropackage = macroname;
+	      macroname.clear ();
+	
+	      // get the macro name (honest!)
+	      while ((tthere != ttend) && (!is_unicode_space(c)) && 
+		     (c != '\\') && (c != '_') &&(c != ':') && 
+		     (macroname.size() < 80)) 
+		{
+		  macroname.push_back((unsigned char)c);
+		  c = my_ttnextchar (tthere, ttend);
+		}
+	    }
+      
+	  if ((tthere != ttend) && (c == '_') &&
+	      (macroname.size() > 0)) 
+	    {
+	      // found a macro!!!! (maybe)
+	      c = my_ttnextchar (tthere, ttend); // skip the '_'
+	
+	      // get the parameters (if there are any)
+	      if ((tthere != ttend) && (c == '(')) 
+		{
+		  c = my_ttnextchar (tthere, ttend); // skip '('
+	  	  ++openbrackets;
+		  // have to be careful of quotes
+		  unsigned short quote = '\0';
+		  while (tthere != ttend) 
+		    {
+		      if (c == '\\') 
+			{
+			  // have an escape character, save escape 
+			  // character and next character as well
+			  macroargs.push_back (c);
+			  c = my_ttnextchar (tthere, ttend); 
+	      
+			} 
+		      else if (quote == '\0') 
+			{
+			  // not in a quote at the moment
+			  if (c == '(')
+			    {
+			      ++openbrackets;
+			    }
+			  else if (c == ')') 
+			    {
+			      --openbrackets;
+			      if (openbrackets==0) {
+				// found end of the arguments
+				c = my_ttnextchar (tthere, ttend); // skip ')'
+				break;
+			      } else {
+				// nested brackets
+			      }
+			    } 
+			  else if (c == '\'' || c == '\"') 
+			    {
+			      // found a quote
+			      quote = c;
+			    }
+	      
+			} 
+		      else 
+			{
+			  // we are in a quote
+			  if (c == quote) quote = '\0';
+			}
+	    
+		      // save this character
+		      if (tthere != ttend) macroargs.push_back (c);
+		      c = my_ttnextchar (tthere, ttend);
+		    } // while (tthere != ttend)
+		}
+	
+	      //
+	      // we now have the macropackage, macroname, and macroargs
+	      //
+	
+	      // try to expand out this macro
+	      text_t expandedmacro;
+	      if (macro (macroname, macropackage.empty()?defaultpackage:macropackage, macroargs, expandedmacro, recursiondepth)) 
+		{
+		  // append the expanded macro
+		  outputtext += expandedmacro;
+		} 
+	      else
+		{
+		  // wasn't a macro
+		  tthere = savedtthere;
+		  c = savedc;
+		  outputtext.push_back(c); // the '_'
+		  c = my_ttnextchar (tthere, ttend);
+		}
+	
+
+	    }
+	  else
+	    {
+	      // wasn't a macro
+	      tthere = savedtthere;
+	      c = savedc;
+	      outputtext.push_back(c); // the '_'
+	      c = my_ttnextchar (tthere, ttend);
+	    }
+
+	}
+      else 
+	{
+	  // nothing of interest
+	  outputtext.push_back(c); // the '_'
+	  c = my_ttnextchar (tthere, ttend);
+	}
+    } // end of while (tthere != ttend)
+}
+
+ostream *displayclass::setlogout (ostream *thelogout) {
+
+  ostream *oldlogout = logout;
+  logout = thelogout;
+  return oldlogout;
+}
+
+// protected methods for display
+
+// reloads any default macro files which have changed
+// returns 0 no errors occurred
+//        -1 an error occurred while trying to load one of the files
+int displayclass::checkdefaultmacrofiles ()
+{
+  // this isn't implemented yet
+  return 0;
+}
+
+// isdefaultmacro sees if there is an entry in the list of
+// default macros with the given package and macro name
+// returns 0 if no macros in the package or in the global package
+//           were found
+//         1 if no macros in the package were found but a macro
+//           in the global package was found
+//         2 if a macro in the given package was found
+int displayclass::isdefaultmacro (const text_t &package, const text_t &macroname) {
+  // make sure a macroname was supplied
+  if (macroname.empty()) return 0;
+
+  if (!package.empty()) {
+    // check the given package
+    if (defaultmacros->macro_find(package, macroname) != NULL) return 2;
+  }
+    
+  // check the Global package
+  if (defaultmacros->macro_find(defaultpackage, macroname) != NULL) return 1;
+  // not found
+  return 0;
+}
+
+// havemacro sees if there is an entry in the list of macros or
+// default macros with the given package and macro name
+// returns 0 if no macros in the package or in the global package
+//           were found
+//         1 if no macros in the package were found but a macro
+//           in the global package was found
+//         2 if a macro in the given package was found
+//         4 if no macros in the package were found but a macro
+//           in the global package was found in default macros
+//         8 if a macro in the given package was found in default
+int displayclass::havemacro(const text_t &package, const text_t &macroname)
+{
+  // make sure a macroname was supplied
+  if (macroname.empty()) return 0;
+  
+  // make package "Global" if it doesn't point to anything yet
+  if (package.empty()) {
+    // check the Global package in current macros list
+    if (currentmacros->macro_find(defaultpackage, macroname) != NULL) return 1;
+    
+    // check the Global package in default macros list
+    if (defaultmacros->macro_find(defaultpackage, macroname) != NULL) return 4;
+  } else {
+    // check the given package in current macros list
+    if (currentmacros->macro_find(package, macroname) != NULL) return 2;
+    
+    // check the Global package in current macros list
+    if (currentmacros->macro_find(defaultpackage, macroname) != NULL) return 1;
+    
+    // check the given package in default macros list
+    if (defaultmacros->macro_find(package, macroname) != NULL) return 8;
+    
+    // check the Global package in default macros list
+    if (defaultmacros->macro_find(defaultpackage, macroname) != NULL) return 4;
+  }
+
+  // nothing was found
+  return 0;
+}
+  
+  
+// setparammacro adds an entry to the list of default macros 
+// returns 0 if there was no error,
+//        -1 if it redefined a macro
+//        -2 if it hid a Global macro
+//        -3 if it redefined a macro and hid a Global macro
+//        -4 if no macroname was supplied
+int displayclass::setparammacro (parammacros_t* macrotable, 
+				 const text_t &package, 
+				 const text_t &macroname, 
+				 text_t macroparams, 
+				 const text_t &filename,
+				 const text_t &macrovalue) 
+{
+  // make sure a macroname was supplied
+  if (macroname.empty()) return -4;
+
+  // put the parameters in a standard form
+  paramhashtype paramhash;
+  if (macroparams.empty()) macroparams = "ignore=yes";
+  splitparams (macroparams, paramhash);
+  joinparams (paramhash, macroparams);
+
+  // remember these parameters
+  allparams.insert (macroparams);
+
+  // remember this filename (this part isn't finished yet -- Rodger).
+
+  // set the macro
+  if (package.empty()) {
+    return macrotable->setmacro(defaultpackage, macroname, macroparams, filename, macrovalue);
+  } else {
+    return macrotable->setmacro(package, macroname, macroparams, filename, macrovalue);
+  }
+}
+
+// setdefaultmacro adds an entry to the list of default macros 
+// returns 0 if there was no error,
+//        -1 if it redefined a macro
+//        -2 if it hid a Global macro
+//        -3 if it redefined a macro and hid a Global macro
+//        -4 if no macroname was supplied
+int displayclass::setdefaultmacro (const text_t &package, 
+				   const text_t &macroname, 
+				   text_t macroparams, 
+				   const text_t &filename,
+				   const text_t &macrovalue) 
+{
+  return setparammacro(defaultmacros,package,macroname,
+		       macroparams,filename,macrovalue);
+}
+
+// public function
+int displayclass::setcollectionmacro(const text_t &package, 
+				     const text_t &macroname, 
+				     text_t mparams, 
+				     const text_t &macrovalue)
+{
+  return setcollectionmacro(package, macroname, mparams, "memory", macrovalue);
+}
+
+// setcollectionmacro adds an entry to the list of collection specific macros 
+// returns 0 if there was no error,
+//        -1 if it redefined a macro
+//        -2 if it hid a Global macro
+//        -3 if it redefined a macro and hid a Global macro
+//        -4 if no macroname was supplied
+int displayclass::setcollectionmacro (const text_t &package, 
+				      const text_t &macroname,
+				      text_t mparams, 
+				      const text_t &filename,
+				      const text_t &macrovalue) 
+{
+  return setparammacro(collectionmacros,package,macroname,mparams,
+		       filename,macrovalue);
+}
+
+
+// evaluates a boolean expression
+// returns false if expr equals "" or "0". 
+// otherwise returns true *unless* expr is 
+// format "XXXX" eq/ne "dddd" in which case
+// the two quoted strings are compared
+bool displayclass::boolexpr (const text_t &package, const text_t &expr, int recursiondepth) {
+  if (expr.empty()) return false;
+
+  text_t expexpr;
+  if (package.empty()) {
+    expandstring (defaultpackage, expr, expexpr, recursiondepth);
+  } else {
+    expandstring (package, expr, expexpr, recursiondepth);
+  }
+  if (expexpr.empty() || expexpr == "0") return false;
+  // allow \" as start of exp as well as ", cos this is what the GLI writes out
+  if (expr[0] != '\"' && !(expr[0] == '\\' && expr[1] == '"')) {
+    return true;
+  }
+  // don't use expexpr while separating quoted parts of
+  // expression just in case expanded out macros contain
+  // quotes
+  text_t::const_iterator here = expr.begin();
+  text_t::const_iterator end = expr.end();
+
+  int quotecount = 0;
+  text_t string1, expstring1;
+  text_t string2, expstring2;
+  text_t op;
+  text_t combineop;
+  bool result = false; // an empty string is false
+  bool result2 = false;
+
+  while (here != end) {
+    // get a comparison
+    quotecount = 0;
+    string1.clear();
+    string2.clear();
+    op.clear();
+    while (here != end) {
+      if (*here == '\\' && *(here+1) =='"') {
+	++quotecount; // found an escaped quote
+	++here;
+      }
+      else if (*here == '"') ++quotecount;
+      else if (quotecount == 1) string1.push_back(*here);
+      else if ((quotecount == 2) && !is_unicode_space (*here))
+	op.push_back(*here);
+      else if (quotecount == 3) string2.push_back(*here);
+      else if (quotecount >= 4) break;
+      ++here;
+    }
+    
+    expandstring (package, string1, expstring1, recursiondepth);
+    expandstring (package, string2, expstring2, recursiondepth);
+
+    // get next result
+    result2 = true; // any badly formatted string will return true
+    if (op == "eq") result2 = (expstring1 == expstring2);
+    else if (op == "ne") result2 = (expstring1 != expstring2);
+    else if (op == "gt") result2 = (expstring1 > expstring2);
+    else if (op == "ge") result2 = (expstring1 >= expstring2);
+    else if (op == "lt") result2 = (expstring1 < expstring2);
+    else if (op == "le") result2 = (expstring1 <= expstring2);
+    else if (op == "==") result2 = (expstring1.getint() == expstring2.getint());
+    else if (op == "!=") result2 = (expstring1.getint() != expstring2.getint());
+    else if (op == ">") result2 = (expstring1.getint() > expstring2.getint());
+    else if (op == ">=") result2 = (expstring1.getint() >= expstring2.getint());
+    else if (op == "<") result2 = (expstring1.getint() < expstring2.getint());
+    else if (op == "<=") result2 = (expstring1.getint() <= expstring2.getint());
+    else if (op == "sw") result2 = (starts_with(expstring1,expstring2));
+    else if (op == "ew") result2 = (ends_with(expstring1,expstring2));
+
+    // combine the results
+    if (combineop == "&&") result = (result && result2);
+    else if (combineop == "||") result = (result || result2);
+    else result = result2;
+
+    // get next combination operator
+    combineop.clear();
+    while (here != end && *here != '"') {
+      if (!is_unicode_space(*here)) combineop.push_back(*here);
+      ++here;
+    }
+  }
+
+  return result;
+}
+
+
+mvalue* displayclass::macro_find (parammacros_t* macrotable, 
+				  const text_t &packagename,
+				  const text_t &macroname)
+{
+  mvalue *macrovalue = NULL;
+
+  // next look in the named parammacros for the named package
+  if (macrotable->macro_find (packagename, macroname) != NULL)
+    {
+      paramspeclist::iterator paramhere, paramend;
+
+      paramhere = orderparamlist->begin(); paramend = orderparamlist->end();
+      while ((macrovalue == NULL) && (paramhere != paramend))
+	{
+	  macrovalue = macrotable->parameter_find(packagename, macroname,
+						  (*paramhere).param);
+	  ++paramhere;
+	}
+    }
+
+  return macrovalue;
+}
+
+
+// (recursively) expand out a macro
+// returns true  if the macro was found
+//         false if the macro was not found
+// macropackage should never be empty
+bool displayclass::macro (const text_t &macroname, 
+			  const text_t &macropackage, 
+			  const text_t &macroparam, 
+			  text_t &outputtext,
+			  int recursiondepth)
+{
+  assert(!macropackage.empty()); //???
+  //outconvertclass text_t2ascii;
+  text_tlist splitmacroparam;
+  text_t::const_iterator hereit, endit;
+  text_t aparam;
+  unsigned short c = '\0', quote = '\0';
+
+  //  cerr << "r: " << recursiondepth << "\n";
+  // check for deep recursion
+  if (recursiondepth >= MAXRECURSIONDEPTH)
+    {
+      if (logout != NULL)
+	(*logout) << "Warning: deep recursion, limiting macro expansion\n";
+      return false;
+    }
+
+  // check the macropackage
+  //if (macropackage.empty()) macropackage = "Global";
+
+  // get the parameters (but don't expand them)
+  if (macroparam.size() > 0) {
+    // set up for loop
+    hereit = macroparam.begin();
+    endit = macroparam.end();
+    if (hereit != endit) c = (*hereit);
+    int openbrackets=0; // keep track of bracket level eg _If_(1, _macro_(arg))
+			// this allows commas inside brackets (as arguments)
+    while (hereit != endit) {
+      // get the next parameter
+      aparam.clear();
+      quote = '\0'; // not-quoted unless proven quoted
+      
+      // ignore initial whitespace
+      while ((hereit!=endit)&&is_unicode_space(c)) c=my_ttnextchar(hereit,endit);
+      
+      // look for the end of the parameter
+      while (hereit != endit) {
+	if (c == '\\') {
+	  // found escape character, also get next character
+	  aparam.push_back(c);
+	  c = my_ttnextchar (hereit, endit);
+	  if (hereit != endit) aparam.push_back(c);
+	  
+	} else if (quote=='\0' && (c=='\'' /*|| c=='"'*/)) {
+	  // found a quoted section
+	  quote = c;
+	  if (openbrackets>0) aparam.push_back(c);
+
+	} else if (quote!='\0' && c==quote) {
+	  // found the end of a quote
+	  quote = '\0';
+	  if (openbrackets<0) aparam.push_back(c);
+
+	} else if (quote=='\0' && (c==',' || c==')') && openbrackets==0) {
+	  // found the end of a parameter
+	  c = my_ttnextchar (hereit, endit);
+	  break;
+
+	} else if (c=='(') {
+	  aparam.push_back(c);
+	  ++openbrackets;
+	} else if (c==')') {
+	  --openbrackets;
+	  aparam.push_back(c);
+	} else {
+	  // ordinary character
+	  aparam.push_back(c);
+	}
+
+	c = my_ttnextchar (hereit, endit);
+      }
+
+
+      // add this parameter to the list
+      splitmacroparam.push_back(aparam);
+    }
+  }
+
+  if (macroname == "If") {
+    // get the condition, then clause and else clause
+    text_tlist::iterator paramcond = splitmacroparam.begin();
+    text_tlist::iterator paramend = splitmacroparam.end();
+    text_tlist::iterator paramthen = paramend;
+    text_tlist::iterator paramelse = paramend;
+    
+    if (paramcond != paramend) {
+      paramthen = paramcond;
+      ++paramthen;
+    }
+    if (paramthen != paramend) {
+      paramelse = paramthen;
+      ++paramelse;
+    }
+    
+    // will always output something
+    outputtext.clear();
+
+
+    // expand out the first parameter
+    if (paramcond != paramend) {
+      /// text_t tmpoutput;
+      /// expandstring (macropackage, *paramcond, tmpoutput, recursiondepth+1);
+      /// lc (tmpoutput);
+      // test the expanded string
+      if (boolexpr (macropackage, *paramcond, recursiondepth+1)) {
+	//(tmpoutput.size()) && (tmpoutput != "false") && (tmpoutput != "0")) {
+	// true
+	if (paramthen != paramend)
+	  expandstring (macropackage, *paramthen, outputtext, recursiondepth+1);
+      } else {
+	// false
+	if (paramelse != paramend)
+	  expandstring (macropackage, *paramelse, outputtext, recursiondepth+1);
+      }
+    }
+    
+    return true;
+  }
+
+  // try and find this macro
+
+  // this list might be replaced by something a little more
+  // sophisticated in the future.
+  text_tlist packagelist;
+  packagelist.push_back (macropackage);
+  packagelist.push_back ("Global");
+
+  text_tlist::iterator packagehere = packagelist.begin();
+  text_tlist::iterator packageend = packagelist.end();
+  mvalue *macrovalue = NULL;
+  while (packagehere != packageend)
+    {
+      // first look in the currentmacros
+      macrovalue = currentmacros->macro_find(*packagehere, macroname);
+      if (macrovalue != NULL)
+	break;
+
+      macrovalue = currentmacros->macro_find("Style", macroname);
+      if (macrovalue != NULL)
+	break;
+
+      // look in the collection specific macros
+      macrovalue = macro_find(collectionmacros,*packagehere,macroname);
+      if (macrovalue != NULL)
+	break;
+
+      // and again in the collection specific package "Style"
+      macrovalue = macro_find(collectionmacros,(char*)"Style",macroname);
+      if (macrovalue != NULL)
+	break;
+
+      // look in the default macros
+      macrovalue = macro_find(defaultmacros,*packagehere,macroname);
+      if (macrovalue != NULL)
+	break;
+
+      // and again in the package "Style"
+      macrovalue = macro_find(defaultmacros,(char*)"Style",macroname);
+      if (macrovalue != NULL)
+	break;
+      ++packagehere;
+    }
+
+  if (macrovalue != NULL)
+    {
+      // we found a macro
+
+      // replace all the option macros (_1_, _2_, ...) in the value of this macro
+      // and decide if we need to expand the value of this macro
+      bool needsexpansion = false;
+      text_t tempmacrovalue;
+      tempmacrovalue.clear();
+      hereit = macrovalue->value.begin();
+      endit = macrovalue->value.end();
+      if (hereit != endit) c = (*hereit);
+      while (hereit != endit)
+	{
+	  if (c == '\\')
+	    {
+	      // found an escape character
+	      needsexpansion = true;
+	      tempmacrovalue.push_back(c);
+	      c = my_ttnextchar (hereit, endit);
+	      if (hereit != endit) tempmacrovalue.push_back(c);
+	      c = my_ttnextchar (hereit, endit);
+	    }
+	  else if (c == '_')
+	    {
+	      text_t::const_iterator savedhereit = hereit;
+
+	      // attempt to get a number
+	      int argnum = 0;
+	      unsigned short digc = my_ttnextchar (hereit, endit);
+	      while (digc >= '0' && digc <= '9') {
+		argnum = argnum*10 + digc - '0';
+		digc = my_ttnextchar (hereit, endit);
+	      }
+	      if (digc == '_' && argnum > 0) {
+		// found an option macro, append the appropriate text
+		text_tlist::iterator ttlisthere = splitmacroparam.begin();
+		text_tlist::iterator ttlistend = splitmacroparam.end();
+		while ((argnum > 1) && (ttlisthere != ttlistend)) {
+		  --argnum;
+		  ++ttlisthere;
+		}
+		if (ttlisthere != ttlistend) {
+		  tempmacrovalue.append(*ttlisthere);
+		  if (findchar((*ttlisthere).begin(), (*ttlisthere).end(), '_') != (*ttlisthere).end())
+		    needsexpansion = true;
+		}
+
+		c = my_ttnextchar (hereit, endit);
+
+	      } else {
+		// wasn't a option macro
+		needsexpansion = true;
+		tempmacrovalue.push_back(c);
+		hereit = savedhereit;
+		c = my_ttnextchar (hereit, endit);
+	      }
+	    }
+	  else
+	    {
+	      tempmacrovalue.push_back(c);
+	      c = my_ttnextchar (hereit, endit);
+	    }
+	}
+      
+      // recursively replace this macro (if we need to)
+      if (needsexpansion) {
+	expandstring (*packagehere, tempmacrovalue, outputtext, recursiondepth+1);
+      } else {
+	outputtext += tempmacrovalue;
+      }
+
+      return true;
+    }
+
+  // GRB: deal with remaining code properly as it faults
+  return false;
+  outconvertclass text_t2ascii;
+  if (logout != NULL) {
+    (*logout) << text_t2ascii << "Warning: _" << 
+      macropackage << ":" << macroname << "_ not found\n";
+  }
+  
+  return false; // didn't find the macro
+}
+
+
+void displayclass::printdefaultmacros ()
+{
+  defpackagemap::const_iterator packagemapit;
+  defmacromap::const_iterator macromapit;
+  defparammap::const_iterator parammapit;
+  const mvalue *mvalueptr;
+  outconvertclass text_t2ascii;
+
+  text_t packagename, macroname, macroparam;
+  
+  for (packagemapit = defaultmacros->package_begin();
+       packagemapit != defaultmacros->package_end();
+       ++packagemapit) 
+    {
+      packagename = (*packagemapit).first;
+      //     cerr << "***package   : \"" << packagename << "\"\n";
+    
+      for (macromapit = (*packagemapit).second.begin();
+	   macromapit != (*packagemapit).second.end();
+	   ++macromapit) 
+	{
+	  macroname = (*macromapit).first;
+	  //       cerr << "***macroname : \"" << macroname << "\"\n";
+
+	  for (parammapit = (*macromapit).second.begin();
+	       parammapit != (*macromapit).second.end();
+	       ++parammapit) 
+	    {
+	      macroparam = (*parammapit).first;
+	      mvalueptr = &((*parammapit).second);
+	      cerr << text_t2ascii << "package   : \"" << packagename << "\"\n";
+	      cerr << text_t2ascii << "macroname : \"" << macroname << "\"\n";
+	      cerr << text_t2ascii << "parameters: [" << macroparam << "]\n";
+	      cerr << text_t2ascii << "filename  : \"" << mvalueptr->filename << "\"\n";
+	      cerr << text_t2ascii << "value     : {" << mvalueptr->value << "}\n\n";
+	    }
+	}
+    }
+}
+
+void displayclass::printallparams ()
+{
+  text_tset::iterator text_tsetit;
+  outconvertclass text_t2ascii;
+
+  cerr << text_t2ascii << "** allparams\n";
+  for (text_tsetit=allparams.begin();
+       text_tsetit!=allparams.end();
+       ++text_tsetit) {
+    cerr << text_t2ascii << (*text_tsetit) << "\n";
+  }
+  cerr << text_t2ascii << "\n";
+}
+
+
+
+/////////////////////////////////////
+// stuff to do tricky output
+/////////////////////////////////////
+
+displayclass &operator<< (outconvertclass &theoutc, displayclass &display)
+{
+  display.setconvertclass (&theoutc);
+  return display;
+}
+
+displayclass &operator<< (displayclass &display, const text_t &t)
+{
+  outconvertclass *theoutc = display.getconvertclass();
+
+  if (theoutc == NULL) return display;
+  
+  text_t output;
+  display.expandstring (t, output);
+  (*theoutc) << output;
+
+  return display;
+}
Index: /gsdl/stable/common-src/src/lib/display.h
===================================================================
--- /gsdl/stable/common-src/src/lib/display.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/display.h	(revision 20131)
@@ -0,0 +1,341 @@
+/**********************************************************************
+ *
+ * display.h -- Context sensitive macro language
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef DISPLAY_H
+#define DISPLAY_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\vector>
+#  include <ospace\std\list>
+#  include <ospace\std\set>
+#  include <ospace\std\map>
+#  include <ospace\std\algorithm>
+#elif defined(GSDL_USE_STL_H)
+#  include <vector.h>
+#  include <list.h>
+#  include <set.h>
+#  include <map.h>
+#  if defined(GSDL_USE_ALGO_H)
+#    include <algo.h>
+#  else
+#    include <algorithm.h>
+#  endif
+#else
+#  include <vector>
+#  include <list>
+#  include <set>
+#  include <map>
+#  include <algorithm>
+#endif
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#  include <ospace\std\fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#  include <fstream.h>
+
+#define unistream ifstream
+#else
+#  include <iostream>
+#  include <fstream>
+
+typedef std::basic_ifstream<unsigned char> unistream;
+
+#endif
+
+
+// use the standard namespace
+#if defined(GSDL_USE_OBJECTSPACE)
+using namespace ospace::std;
+#elif !defined(GSDL_NAMESPACE_BROKEN)
+using namespace std;
+#endif
+
+
+
+// MAXRECURSIONDEPTH is a cutoff to catch
+// cyclic macros (a includes b and b includes a)
+#define MAXRECURSIONDEPTH 30
+
+// class prototypes
+class parammacros_t;
+class currentmacros_t;
+
+// a few supporting types
+// fileelement isn't finished yet, I have to find out
+// more about getting information about files
+struct fileinfoelement 
+{
+  int otherinfo;
+};
+
+// macro value structure
+struct mvalue
+{
+  text_t filename;
+  text_t value;
+};
+
+inline bool operator==(const fileinfoelement &x, const fileinfoelement &y) {
+  return (x.otherinfo==y.otherinfo);
+}
+
+inline bool operator<(const fileinfoelement &x, const fileinfoelement &y) {
+  return (x.otherinfo<y.otherinfo);
+}
+
+typedef map<text_t, fileinfoelement, lttext_t> fileinfomap;
+
+
+typedef map<text_t, text_t, lttext_t> paramhashtype;
+void splitparams (const text_t &paramstring, paramhashtype &paramhash);
+
+
+struct paramspec 
+{
+  double spec;
+  text_t param;
+};
+
+inline bool operator==(const paramspec& x, const paramspec& y) 
+{
+  return ((x.spec == y.spec) && (x.param == y.param));
+}
+
+inline bool operator!=(const paramspec& x, const paramspec& y) 
+{
+  return ((x.spec != y.spec) || (x.param != y.param));
+}
+
+// note: paramspec is sorted by reverse spec and then param
+
+inline bool operator<(const paramspec& x, const paramspec& y) 
+{
+  return ((x.spec > y.spec) ||
+	  ((x.spec == y.spec) && (x.param < y.param)));
+}
+
+inline bool operator>(const paramspec& x, const paramspec& y) 
+{
+  return ((x.spec < y.spec) ||
+	  ((x.spec == y.spec) && (x.param > y.param)));
+}
+
+typedef vector<paramspec> paramspeclist;
+
+
+
+// NOTE: when macros are used within text they should have
+// underscores '_' on both sides, however, in calls to
+// setdefaultmacro and setmacro they should not have the
+// underscores. So you might have
+//
+// setmacro ("aname", "query", " some text ");
+// expandstring ("_aname_", expandedtext);
+//
+// because the input to expandstring is a block of text, not
+// a macroname
+
+class displayclass 
+{
+public:
+  static text_t defaultpackage;
+
+  displayclass ();
+  ~displayclass ();
+  
+  // isdefaultmacro sees if there is an entry in the list of
+  // default macros with the given package and macro name
+  // returns 0 if no macros in the package or in the global package
+  //           were found
+  //         1 if no macros in the package were found but a macro
+  //           in the global package was found
+  //         2 if a macro in the given package was found
+  int isdefaultmacro (const text_t &package, const text_t &macroname);
+
+  // setdefaultmacro adds an entry to the list of default macros 
+  // returns 0 if there was no error,
+  //        -1 if it redefined a macro
+  //        -2 if it hid a Global macro
+  //        -3 if it redefined a macro and hid a Global macro
+  //        -4 if no macroname was supplied
+  int setdefaultmacro (const text_t &package, 
+		       const text_t &macroname, 
+		       const text_t &params, 
+		       const text_t &macrovalue);
+  
+  // loads a default macro file (if it isn't already loaded)
+  // returns 0 if didn't need to load the file (it was already loaded)
+  //         1 if was (re)loaded
+  //        -1 an error occurred while trying to load the file
+  int loaddefaultmacros (const text_t &thisfilename);
+
+
+  // overrides (or sets) a macro for the current page.
+  // returns 0 if there was no error,
+  //        -1 if it redefined a macro
+  //        -4 if no macroname was supplied
+  int setcollectionmacro (const text_t &package, 
+			  const text_t &macroname, 
+			  text_t params, 
+			  const text_t &macrovalue);
+
+  // loads a collection specific macro file 
+  // returns 0 if didn't need to load the file (it was already loaded)
+  //         1 if was (re)loaded
+  //        -1 an error occurred while trying to load the file
+  int loadcollectionmacros (const text_t &thisfilename);
+
+  // unloads all default macros
+  void unloaddefaultmacros ();
+
+  // unloads all collection specific macros
+  void unloadcollectionmacros ();
+  
+  // prepares to create a page: deletes all macros set with
+  // 'setmacro', checks all the default macro files to see
+  // if any need reloading, and sets the page parameters.
+  void openpage (const text_t &thispageparams, 
+		 const text_t &thisprecedence);
+  
+  // changes the parameters for the current page.
+  void setpageparams (text_t thispageparams, 
+		      text_t thisprecedence);
+  
+  // overrides (or sets) a macro for the current page.
+  // returns 0 if there was no error,
+  //        -1 if it redefined a macro
+  //        -4 if no macroname was supplied
+  int setmacro (const text_t &macroname, 
+		const text_t &package, 
+		const text_t &macrovalue);
+  
+// havemacro sees if there is an entry in the list of macros or
+// default macros with the given package and macro name
+// returns 0 if no macros in the package or in the global package
+//           were found
+//         1 if no macros in the package were found but a macro
+//           in the global package was found
+//         2 if a macro in the given package was found
+//         4 if no macros in the package were found but a macro
+//           in the global package was found in default macros
+//         8 if a macro in the given package was found in default
+  int havemacro(const text_t &package, const text_t &macroname);
+
+  int setmacroif (const text_t &macro_to_set_and_test, 
+		  const text_t &macro_to_set_if_macro_not_set,
+		  const text_t &macroname, 
+		  const text_t& package);
+  
+  inline void expandstring (const text_t &inputtext, text_t &outputtext) { expandstring(defaultpackage, inputtext, outputtext); }
+
+  void expandstring (const text_t &package, const text_t &inputtext,
+		     text_t &outputtext, int recursiondepth = 0);
+
+  // these functions are not ment to be used directly, they are used to permit 
+  // concise stream output like:
+  // cout << text_t2ascii << display << "_amacro_" << "_anothermacro_";
+  void setconvertclass (outconvertclass *theoutc) {outc = theoutc;}
+  outconvertclass *getconvertclass () {return outc;}
+
+  // say where any error logging goes, this can be NULL
+  // if no error logging is desired - returns previous value
+  ostream *setlogout (ostream *thelogout);
+
+  // debug stuff
+  void printdefaultmacros ();
+  void printallparams ();
+
+protected:
+  // special variables to permit trickly output
+  outconvertclass *outc;
+
+  // general variables
+  text_tset        allparams;  // possible parameter combinations
+  parammacros_t *defaultmacros;
+  parammacros_t *collectionmacros;
+  fileinfomap     *defaultfiles;
+  
+  // variables to do with a page expansion
+  text_t params;
+  text_t precedence;
+  paramspeclist *orderparamlist; // ordered by specificness
+  currentmacros_t *currentmacros; // only macros set by setmacro
+
+  // logging variable
+  ostream *logout;
+
+  // reloads any default macro files which have changed
+  // returns 0 no errors occurred
+  //        -1 an error occurred while trying to load one of the files
+  int checkdefaultmacrofiles ();
+
+  int loadparammacros (parammacros_t* macrotable, const text_t &thisfilename);
+
+  int setparammacro (parammacros_t* macrotable,
+		     const text_t &package, 
+		     const text_t &macroname, 
+		     text_t params, const text_t &filename,
+		     const text_t &macrovalue); 
+
+  int setdefaultmacro (const text_t &package, 
+		       const text_t &macroname, 
+		       text_t params, const text_t &filename,
+		       const text_t &macrovalue); 
+
+  int setcollectionmacro(const text_t &package, 
+			 const text_t &macroname, 
+			 text_t params, 
+			 const text_t &filename,
+			 const text_t &macrovalue); 
+  
+  // evaluates a boolean expression
+  bool boolexpr (const text_t &package, const text_t &expr, 
+		 int recursiondepth);
+
+  mvalue* macro_find (parammacros_t* macrotable, 
+		      const text_t &packagename,
+		      const text_t &macroname);
+
+  // (recursively) expand out a macro
+  // returns true  if the macro was found
+  //         false if the macro was not found
+  bool macro (const text_t &macroname, 
+	      const text_t &macropackage, 
+	      const text_t &macroparam, text_t &outputtext,
+	      int recursiondepth);
+};
+
+
+displayclass &operator<< (outconvertclass &theoutc, displayclass &display);
+displayclass &operator<< (displayclass &display, const text_t &t);
+
+#endif
Index: /gsdl/stable/common-src/src/lib/fileutil.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/fileutil.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/fileutil.cpp	(revision 20131)
@@ -0,0 +1,446 @@
+/**********************************************************************
+ *
+ * fileutil.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "fileutil.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#  include <ospace\std\fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#  include <fstream.h>
+#else
+#  include <iostream>
+#  include <fstream>
+#endif
+
+
+// returns the proper concatenation of the two paths
+text_t filename_cat (text_t path1, text_t path2) {
+  text_t::iterator here;
+  text_t::iterator begin;
+  text_t::iterator end;
+
+  // make sure there is just one slash, of the correct type,
+  // at the end of path1 (unless path1 is an empty string).
+  if (!path1.empty()) {
+    // remove all trailing slashes
+    here = path1.end();
+    --here;
+    begin = path1.begin();
+    while (here != begin && (*here == '/' || *here == '\\')) {
+      --here;
+    }
+    ++here;
+    path1.erase(here,path1.end());
+    
+    // add one final slash
+#ifdef __WIN32__
+    path1 += "\\";
+#else
+    path1 += "/";
+#endif 
+  }
+
+  // remove all slashes from the start of path2
+  here = path2.begin();
+  end = path2.end();
+  while (here != end && (*here == '/' || *here == '\\')) {
+    ++here;
+  }
+  path2.erase (path2.begin(), here);
+  
+  text_t fullpath = path1 + path2;
+  
+  // make sure all the right slashes are used
+  here = fullpath.begin();
+  end = fullpath.end();
+  while (here != end) {
+#ifdef __WIN32__
+    if (*here == '/') *here = '\\';
+#else
+    if (*here == '\\') *here = '/';
+#endif
+    ++here ;
+  }
+  return fullpath;
+}
+
+text_t filename_cat (text_t path1, text_t path2, text_t path3) {
+  return filename_cat(filename_cat(path1,path2),path3);
+}
+
+text_t filename_cat (text_t path1, text_t path2, text_t path3, text_t path4) {
+  return filename_cat(filename_cat(filename_cat(path1,path2),path3),path4);
+}
+
+text_t filename_cat (text_t path1, text_t path2, text_t path3, text_t path4, 
+		     text_t path5) {
+  return filename_cat(filename_cat(filename_cat(filename_cat(path1,path2),path3),
+				   path4),path5);
+}
+
+text_t filename_cat (text_t path1, text_t path2, text_t path3, text_t path4, 
+		     text_t path5, text_t path6) {
+  return filename_cat(filename_cat(path1,path2,path3,path4,path5),path6);
+}
+
+// returns true if filename can be opened
+bool file_exists (const text_t &filename) {
+  char *cstr = filename.getcstr();
+#ifdef GSDL_USE_IOS_H
+  ifstream filestream (cstr, ios::in | ios::nocreate);
+#else
+  ifstream filestream (cstr, ios::in);
+#endif
+  delete []cstr;
+  
+  if (filestream) {
+    // file exists
+    filestream.close ();
+    return true;
+  }
+  
+  // file does not exist
+  return false;
+}
+
+// returns true if filename can be opened
+bool file_writable (const text_t &filename) {
+  char *cstr = filename.getcstr();
+#ifdef GSDL_USE_IOS_H
+  ifstream filestream (cstr, ios::out | ios::nocreate);
+#else
+  ifstream filestream (cstr, ios::out);
+#endif
+  delete []cstr;
+  
+  if (filestream) {
+    // file exists
+    filestream.close ();
+    return true;
+  }
+  
+  // file does not exist
+  return false;
+}
+
+#if defined(__WIN32__) && !defined(__GNUC__)
+
+#include <windows.h>
+
+bool directory_exists (const text_t &dirname) {
+  
+  WIN32_FIND_DATA FileData;  
+  HANDLE hSearch; 
+
+  text_t dir = dirname + "\\*";
+  char *dirpath = dir.getcstr();
+  
+  hSearch = FindFirstFile(dirpath, &FileData);
+  if (hSearch == INVALID_HANDLE_VALUE) {
+    delete []dirpath;
+    return false;
+  }
+
+  FindClose (hSearch);
+  delete []dirpath;
+  return true;
+}
+
+bool read_dir (const text_t &dirname, text_tset &filelist) {
+  
+  WIN32_FIND_DATA FileData;  
+  HANDLE hSearch; 
+  
+  text_t dir = dirname + "\\*";
+  char *dirpath = dir.getcstr();
+  
+  hSearch = FindFirstFile(dirpath, &FileData); 
+  if (hSearch == INVALID_HANDLE_VALUE) {
+    delete []dirpath;
+    return false;
+  }
+  
+  text_t filename = FileData.cFileName;
+  if (filename != "." && filename != ".." && filename != "CVS" && filename != ".svn")
+    filelist.insert (filename); 
+  
+  while (FindNextFile(hSearch, &FileData)) {
+    filename = FileData.cFileName;
+    if (filename == "." || filename == ".." || filename == "CVS" || filename == ".svn")
+      continue;
+    filelist.insert (filename); 
+  }
+  
+  FindClose(hSearch);
+  delete []dirpath;
+  
+  return true;
+}
+
+bool read_dir (const text_t &dirname, text_tarray &filelist) {
+  
+  WIN32_FIND_DATA FileData;  
+  HANDLE hSearch; 
+  
+  text_t dir = dirname + "\\*";
+  char *dirpath = dir.getcstr();
+  
+  hSearch = FindFirstFile(dirpath, &FileData); 
+  if (hSearch == INVALID_HANDLE_VALUE) {
+    delete []dirpath;
+    return false;
+  }
+  
+  text_t filename = FileData.cFileName;
+  if (filename != "." && filename != ".." && filename != "CVS" && filename != ".svn")
+    filelist.push_back (filename); 
+  
+  while (FindNextFile(hSearch, &FileData)) {
+    filename = FileData.cFileName;
+    if (filename == "." || filename == ".." || filename == "CVS" || filename == ".svn")
+      continue;
+    filelist.push_back (filename); 
+  }
+  
+  FindClose(hSearch);
+  delete []dirpath;
+
+  return true;
+}
+
+#else
+
+#include <dirent.h>
+
+bool directory_exists (const text_t &dirname) {
+  
+  char *tmp = dirname.getcstr();
+  DIR *dirin = opendir (tmp);
+  delete []tmp;
+  
+  if (dirin == NULL) return false;
+  closedir (dirin);
+  return true;
+}
+
+bool read_dir (const text_t &dirname, text_tset &filelist) {
+  
+  char *tmp = dirname.getcstr();
+  DIR *dirin = opendir (tmp);
+  delete []tmp;
+  
+  if (dirin == NULL) return false;
+  
+  dirent *dirp; 
+  
+  text_t filename;
+  while ((dirp = readdir (dirin)) != NULL) {
+    filename = dirp->d_name;
+    if (filename == "." || filename == ".." || filename == "CVS" || filename == ".svn")
+      continue;
+    filelist.insert (filename);
+  }
+  closedir (dirin);
+  return true;
+}
+
+bool read_dir (const text_t &dirname, text_tarray &filelist) {
+  
+  char *tmp = dirname.getcstr();
+  DIR *dirin = opendir (tmp);
+  delete []tmp;
+  
+  if (dirin == NULL) return false;
+  
+  dirent *dirp; 
+  
+  text_t filename;
+  while ((dirp = readdir (dirin)) != NULL) {
+    filename = dirp->d_name;
+    if (filename == "." || filename == ".." || filename == "CVS" || filename == ".svn")
+      continue;
+    filelist.push_back (filename);
+  }
+  closedir (dirin);
+  return true;
+}
+
+#endif
+
+// returns true if things look like they happened ok
+bool file_copy (const text_t &fromfile, const text_t &tofile) {
+  
+  char *fromfilec = fromfile.getcstr();
+  char *tofilec = tofile.getcstr();
+  bool fail = false;
+
+#ifdef __WIN32__
+  if (CopyFile (fromfilec, tofilec, FALSE) == 0) fail = true;
+
+#else
+
+  ifstream from (fromfilec);
+  if (!from) {
+    fail = true;
+  } else {
+    ofstream to (tofilec);
+    if (!to) {
+      fail = true;
+      from.close();
+    } else {
+      from >> to.rdbuf();
+      from.close();
+      to.close();
+    }
+  }
+
+#endif
+
+  delete []fromfilec;
+  delete []tofilec;
+  if (fail) return false;
+  return true;
+}
+
+// This is a fairly quick and nasty attempt at doing a "tail" on a file
+// (i.e. returning the last numlines lines of filename).  It has one
+// important limitation in that it expects lines to be linelength
+// characters long on average.  This of course makes it possible that it
+// won't return numlines lines if there are some lines that are longer than
+// linelength.  It also makes it fairly inefficient as it always reads in
+// numlines*linelength characters when it most often doesn't need them all.
+// For current needs it's fine though.
+// -- Pass a linelength of 0 to use the default linelength (256 chars).
+// -- The maximum value of linelength is MAXLINELENGTH
+text_t file_tail (const text_t &filename, int numlines, int linelength) {
+
+#define MAXLINELENGTH 2048
+
+  if (numlines < 1) numlines = 1;
+  if (linelength < 1) linelength = 256;
+  if (linelength > MAXLINELENGTH) linelength = MAXLINELENGTH;
+
+  streampos numchars = linelength*numlines;
+
+  text_tarray lines;
+  text_t ret;
+
+  char *filenamec = filename.getcstr();
+  char linec[MAXLINELENGTH];
+  ifstream file_in (filenamec);
+  delete []filenamec;
+  if (file_in) {
+    file_in.seekg (0, ios::end);
+    streampos file_length = file_in.tellg();
+    if (file_length < numchars) numchars = file_length;
+    file_in.seekg (-numchars, ios::end);
+
+    while (!file_in.eof()) {
+      file_in.getline (linec, linelength);
+      ret.setcstr(linec);
+      text_t::const_iterator here = ret.begin();
+      text_t::const_iterator end = ret.end();
+      // make sure line has content
+      while (here != end) {
+	if (*here != '\n' && *here != ' ') {
+	  lines.push_back (ret);
+	  break;
+	}
+	++here;
+      }
+    }
+    file_in.close();
+  }
+
+  ret.clear();
+  int numlinesgot = lines.size();
+  int sindex = 0;
+  if (numlinesgot > numlines) sindex = numlinesgot - numlines;
+  for (int i = sindex; i < numlinesgot; ++i) {
+    ret += lines[i] + "\n";
+  }
+
+  return ret;
+}
+
+#ifdef __WIN32__
+
+#include <direct.h>
+// returns true if directory was created successfully
+bool mk_dir (const text_t &dirname) {
+  char *dirnamec = dirname.getcstr();
+  int rv = _mkdir (dirnamec);
+  delete []dirnamec;
+  if (rv == 0) return true;
+  return false;
+}
+
+#else
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+// returns true if directory was created successfully
+bool mk_dir (const text_t &dirname) {
+  mode_t mode = 0777;
+  char *dirnamec = dirname.getcstr();
+  int rv = mkdir (dirnamec, mode);
+  delete []dirnamec;
+  if (rv == 0) return true;
+  return false;
+}
+
+#endif
+
+// read in file from filename and load into content
+bool read_file (const text_t &filename, text_t &content) {
+
+  content.clear();
+
+  char *filenamec = filename.getcstr();
+#ifdef GSDL_USE_IOS_H
+  ifstream file_in (filenamec, ios::in | ios::nocreate);
+#else
+  ifstream file_in (filenamec, ios::in);
+#endif
+  delete []filenamec;
+
+  if (file_in) {
+    char c;
+    file_in.get(c);
+    while (!file_in.eof ()) {
+      // Casting c to an unsigned char is vital when reading non-ASCII documents
+      content.push_back((unsigned char) c);
+      file_in.get(c);
+    }
+    file_in.close();
+  } else {
+    return false;
+  }
+  return true;
+}
Index: /gsdl/stable/common-src/src/lib/fileutil.h
===================================================================
--- /gsdl/stable/common-src/src/lib/fileutil.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/fileutil.h	(revision 20131)
@@ -0,0 +1,65 @@
+/**********************************************************************
+ *
+ * fileutil.h -- a few useful file utilities
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef FILEUTIL_H
+#define FILEUTIL_H
+
+#include "text_t.h"
+
+
+// returns the proper concatenation of the two paths
+text_t filename_cat (text_t path1, text_t path2);
+text_t filename_cat (text_t path1, text_t path2, text_t path3);
+text_t filename_cat (text_t path1, text_t path2, text_t path3, text_t path4);
+text_t filename_cat (text_t path1, text_t path2, text_t path3, text_t path4, 
+		     text_t path5);
+text_t filename_cat (text_t path1, text_t path2, text_t path3, text_t path4, 
+		     text_t path5, text_t path6);
+
+// returns true if filename can be opened
+bool file_exists (const text_t &filename);
+
+// returns true if filename can be written to
+bool file_writable (const text_t &filename);
+
+// returns true if directory exists
+bool directory_exists (const text_t &dirname);
+
+// note that read_dir appends to filelist, it doesn't clear
+// it first
+bool read_dir (const text_t &dirname, text_tarray &filelist);
+bool read_dir (const text_t &dirname, text_tset &filelist);
+
+bool file_copy (const text_t &fromfile, const text_t &tofile);
+
+text_t file_tail (const text_t &filename, int numlines, int linelength);
+
+// returns true if directory created successfully
+bool mk_dir (const text_t &dirname);
+
+bool read_file (const text_t &filename, text_t &content);
+
+#endif
Index: /gsdl/stable/common-src/src/lib/gdbmclass.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/gdbmclass.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/gdbmclass.cpp	(revision 20131)
@@ -0,0 +1,357 @@
+/**********************************************************************
+ *
+ * gdbmclass.cpp -- 
+ * Copyright (C) 1999-2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gdbmclass.h"
+#include "gsdltools.h"
+#include "gsdlunicode.h"
+#include "fileutil.h"
+#include "stdlib.h"
+#include <cstring>
+
+
+gdbmclass::~gdbmclass()
+{
+  closedatabase();
+}
+
+
+// returns true if opened
+bool gdbmclass::opendatabase (const text_t &filename, int mode, int num_retrys, 
+#ifdef __WIN32__
+			      bool need_filelock
+#else
+                              bool
+#endif
+			      )
+{
+
+  text_t data_location;
+  int block_size = 512;
+  
+  if (gdbmfile != NULL) {
+    if (openfile == filename) return true;
+    else closedatabase ();
+  }
+
+  openfile = filename;
+
+  // Map the DB mode values into GDBM mode values
+  int gdbm_mode = GDBM_READER;
+  if (mode == DB_WRITER)
+  {
+    gdbm_mode = GDBM_WRITER;
+  }
+  else if (mode == DB_WRITER_CREATE)
+  {
+    gdbm_mode = GDBM_WRCREAT;
+  }
+
+  text_t gdbm_filename = filename;
+  if (gdbm_mode == GDBM_READER)
+  {
+    // make sure we have the right file extension. Should be all gdb now.
+    // But need to handle old style ldb/bdb collection dbs
+
+    // If the specified GDBM file doesn't exist, (should be gdb) try the other extensions (we can now read both)
+    if (!file_exists(gdbm_filename))
+    {
+      // should be all gdb now
+      if (ends_with(gdbm_filename, ".gdb")) {
+	gdbm_filename = substr(gdbm_filename.begin(), gdbm_filename.end() - ((text_t) ".gdb").size()) + ".ldb";	
+	
+	if (!file_exists(gdbm_filename)) {
+	  // try bdb as well
+	  gdbm_filename = substr(gdbm_filename.begin(), gdbm_filename.end() - ((text_t) ".ldb").size()) + ".bdb";
+	}
+      }
+    }
+
+    // DEPRECATED -- No longer necessary now that the GDBM library reads both little-endian and big-endian files
+    if (!file_exists(gdbm_filename))
+    {
+      // We're desperate, so try generating the desired GDBM file from a txtgz file
+      gdbm_filename = filename;
+      generate_from_txtgz(gdbm_filename);
+    }
+  }
+
+  char *namebuffer = gdbm_filename.getcstr();
+  do {
+#ifdef __WIN32__
+    gdbmfile = gdbm_open (namebuffer, block_size, gdbm_mode, 00664, NULL, (need_filelock) ? 1 : 0);
+#else
+    gdbmfile = gdbm_open (namebuffer, block_size, gdbm_mode, 00664, NULL);
+#endif
+    --num_retrys;
+  } while (num_retrys>0 && gdbmfile==NULL &&
+	   (gdbm_errno==GDBM_CANT_BE_READER || gdbm_errno==GDBM_CANT_BE_WRITER));
+  delete []namebuffer;
+  
+  if (gdbmfile == NULL && logout != NULL) {
+    outconvertclass text_t2ascii;
+    (*logout) << text_t2ascii << "database open failed on: " << gdbm_filename << "\n";
+  }
+
+  return (gdbmfile != NULL);
+}
+
+
+void gdbmclass::closedatabase ()
+{
+  if (gdbmfile == NULL) return;
+  
+  gdbm_close (gdbmfile);
+  gdbmfile = NULL;
+  openfile.clear();
+}
+
+
+void gdbmclass::deletekey (const text_t &key)
+{
+  if (gdbmfile == NULL) return;
+
+  // get a utf-8 encoded c string of the unicode key
+  datum key_data;
+  key_data.dptr = (to_utf8(key)).getcstr();
+  if (key_data.dptr == NULL) return;
+  key_data.dsize = strlen (key_data.dptr);
+
+  // delete the key
+  gdbm_delete (gdbmfile, key_data);
+
+  // free up the key memory
+  delete []key_data.dptr;
+}
+
+
+// returns file extension string
+text_t gdbmclass::getfileextension ()
+{
+  // now we always use gdb for gdbm files. later on, if we can't find it, we'll try ldb and bdb for backwards compatibility
+  return ".gdb";
+  //if (littleEndian()) return ".ldb";
+  //return ".bdb";
+}
+
+
+// returns true on success
+bool gdbmclass::getkeydata (const text_t& key, text_t &data)
+{
+  datum key_data;
+  datum return_data;
+
+  if (gdbmfile == NULL) return false;
+  
+  // get a utf-8 encoded c string of the unicode key
+  key_data.dptr = (to_utf8(key)).getcstr();
+  if (key_data.dptr == NULL) {
+    if (logout != NULL) (*logout) << "gdbmclass: out of memory" << endl;
+    return false;
+  }
+  key_data.dsize = strlen (key_data.dptr);
+  
+  // fetch the result
+  return_data = gdbm_fetch (gdbmfile, key_data);
+  delete []key_data.dptr;
+  
+  if (return_data.dptr == NULL) return false;
+
+  data.setcarr (return_data.dptr, return_data.dsize);
+  free (return_data.dptr);
+  data = to_uni(data);  // convert to unicode
+
+  return true;
+}
+
+
+// returns array of keys
+text_tarray gdbmclass::getkeys ()
+{
+  text_tarray keys;
+
+  text_t key = getfirstkey();
+  while (!key.empty())
+  {
+    keys.push_back(key);
+    key = getnextkey(key);
+  }
+
+  return keys;
+}
+
+
+// returns true on success
+bool gdbmclass::setkeydata (const text_t &key, const text_t &data)
+{
+  if (gdbmfile == NULL) return false;
+  
+  // store the value
+  datum key_data;
+  datum data_data;
+
+  // get a utf-8 encoded c string of the unicode key
+  key_data.dptr = (to_utf8(key)).getcstr();
+  if (key_data.dptr == NULL) {
+    if (logout != NULL) (*logout) << "gdbmclass: out of memory" << endl;
+    return false;
+  }
+  key_data.dsize = strlen (key_data.dptr);
+
+  data_data.dptr = (to_utf8(data)).getcstr();
+  if (data_data.dptr == NULL) {
+    if (logout != NULL) (*logout) << "gdbmclass: out of memory" << endl;
+    delete []key_data.dptr;
+    return false;
+  }
+  data_data.dsize = strlen (data_data.dptr);
+
+  int ret = gdbm_store (gdbmfile, key_data, data_data, GDBM_REPLACE);
+  delete []key_data.dptr;
+  delete []data_data.dptr;
+
+  return (ret == 0);
+}
+
+
+// ----------------------------------------------------------------------------------------
+//   GDBM-ONLY FUNCTIONS
+// ----------------------------------------------------------------------------------------
+
+// getfirstkey and getnextkey are used for traversing the database
+// no insertions or deletions should be carried out while traversing
+// the database. when there are no keys left to visit in the database
+// an empty string is returned.
+text_t gdbmclass::getfirstkey ()
+{
+  if (gdbmfile == NULL) return g_EmptyText;
+
+  // get the first key
+  datum firstkey_data = gdbm_firstkey (gdbmfile);
+  if (firstkey_data.dptr == NULL) return g_EmptyText;
+
+  // convert it to text_t
+  text_t firstkey;
+  firstkey.setcarr (firstkey_data.dptr, firstkey_data.dsize);
+  free (firstkey_data.dptr);
+  return to_uni(firstkey);  // convert to unicode
+}
+
+
+text_t gdbmclass::getnextkey (const text_t &key)
+{
+  if (gdbmfile == NULL || key.empty()) return g_EmptyText;
+
+  // get a utf-8 encoded c string of the unicode key
+  datum key_data;
+  key_data.dptr = (to_utf8(key)).getcstr();
+  if (key_data.dptr == NULL) return g_EmptyText;
+  key_data.dsize = strlen (key_data.dptr);
+  
+  // get the next key
+  datum nextkey_data = gdbm_nextkey (gdbmfile, key_data);
+  if (nextkey_data.dptr == NULL) {
+    delete []key_data.dptr;
+    return g_EmptyText;
+  }
+
+  // convert it to text_t
+  text_t nextkey;
+  nextkey.setcarr (nextkey_data.dptr, nextkey_data.dsize);
+  free (nextkey_data.dptr);
+  delete []key_data.dptr;
+  return to_uni(nextkey);  // convert to unicode
+}
+
+
+// DEPRECATED -- No longer necessary now that the GDBM library reads both little-endian and big-endian files
+void gdbmclass::generate_from_txtgz (text_t filename)
+{
+    // Looking to read in the database
+    // => check to see if .ldb/.bdb file already there
+    // if not (first time) then generate using txt2db
+
+      // need to generate architecture native GDBM file using txt2db
+
+      // replace sought after gdbm filename ext with ".txt.gz"
+
+      text_t::const_iterator begin = filename.begin();
+      text_t::const_iterator end= filename.end();
+      
+      if (begin != end) {
+	end = end - 1;
+      }
+		
+      text_t::const_iterator here = end;
+
+      bool found_ext = false;
+
+      while (here != begin) {
+	if (*here == '.') {
+	  found_ext = true;
+	  break;
+	}
+	here--;
+      }
+      
+      text_t filename_root;
+
+      if (found_ext) {
+	filename_root = substr(begin,here);
+      }
+      else {
+	filename_root = filename;
+      }
+
+      text_t txtgz_filename = filename_root + ".txt.gz";
+      if (file_exists(txtgz_filename))
+      {
+	//text_t cmd = "gzip --decompress --to-stdout \"" + txtgz_filename + "\"";
+	//cmd += " | txt2db \"" + filename + "\"";
+
+	// Test to make sure Perl is on the path
+	// On Linux, the output of the test goes to STDOUT so redirect it to STDERR
+	text_t cmd_test = "perl -v 1>&2";
+	int rv_test = gsdl_system(cmd_test, true, cerr);
+	if (rv_test != 0) {
+	  cerr << "Tried to find Perl. Return exit value of running " 
+	       << cmd_test <<": "<< rv_test << ", (expected this to be 0)" << endl;
+	  cerr << "Check that Perl is set in your environment variable PATH." << endl;
+	  cerr << "At present, PATH=" << getenv("PATH") << endl;
+	}
+
+	text_t cmd = "perl -S txtgz-to-gdbm.pl \"" + txtgz_filename + "\" \"" + filename + "\"";
+	int rv = gsdl_system(cmd, true, cerr);
+	// For some reason, launching this command with gsdl_system() still returns 1
+	// even when it returns 0 when run from the command-line. We can check whether
+	// we succeeded by looking at whether the output database file was created.
+	if (rv != 0) {
+	  cerr << "Warning, non-zero return value on running command \""
+	       << cmd << "\": " << rv << endl;
+	  if (!file_exists(filename)) {
+	    cerr << "Tried to run command \""<<cmd<<"\", but it failed" << endl;
+	  }
+	}	
+      }
+}
Index: /gsdl/stable/common-src/src/lib/gdbmclass.h
===================================================================
--- /gsdl/stable/common-src/src/lib/gdbmclass.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/gdbmclass.h	(revision 20131)
@@ -0,0 +1,92 @@
+/**********************************************************************
+ *
+ * gdbmclass.h -- 
+ * Copyright (C) 1999-2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef GDBMCLASS_H
+#define GDBMCLASS_H
+
+
+#include "gsdlconf.h"
+#include "dbclass.h"
+
+#ifdef __WIN32__
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+#include "autoconf.h"
+#include "systems.h"
+#include "gdbmconst.h"
+#include "gdbm.h"
+#ifdef __cplusplus
+  }
+#endif
+
+#else
+#include <gdbm.h>
+#endif
+
+
+class gdbmclass : public dbclass
+{
+public:
+  gdbmclass() { gdbmfile = NULL; };
+  ~gdbmclass();
+
+  // returns true if opened
+  bool opendatabase (const text_t &filename, int mode, int num_retrys, bool need_filelock);
+
+  void closedatabase ();
+
+  void deletekey (const text_t &key);
+
+  // returns file extension string
+  text_t getfileextension ();
+
+  // returns true on success
+  bool getkeydata (const text_t& key, text_t &data);
+
+  // returns array of keys
+  text_tarray getkeys ();
+
+  // returns true on success
+  bool setkeydata (const text_t &key, const text_t &data);
+
+protected:
+  text_t openfile;
+  GDBM_FILE gdbmfile;
+
+  // getfirstkey and getnextkey are used for traversing the database
+  // no insertions or deletions should be carried out while traversing
+  // the database. when there are no keys left to visit in the database
+  // an empty string is returned.
+  text_t getfirstkey ();
+  text_t getnextkey (const text_t &key);
+
+  // DEPRECATED -- No longer necessary now that the GDBM library reads both little-endian and big-endian files
+  void generate_from_txtgz (text_t filename);
+};
+
+
+#endif
Index: /gsdl/stable/common-src/src/lib/gsdlconf.h
===================================================================
--- /gsdl/stable/common-src/src/lib/gsdlconf.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/gsdlconf.h	(revision 20131)
@@ -0,0 +1,161 @@
+/**********************************************************************
+ *
+ * gsdlconf.h -- system specific includes
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef GSDLCONF_H
+#define GSDLCONF_H
+
+#define GSDL_VERSION "svn-trunk"
+
+#if defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_) || defined(WIN32)
+#ifndef __WIN32__
+#define __WIN32__ 1
+#endif
+#endif
+
+#if defined(__WIN32__) && !defined(__CYGWIN__)
+#include "../../win32cfg.h"
+#else
+#include "../../config.h"
+#endif
+
+// Note: all macros used in the gsdl software (except the _H macros) should
+// now start with GSDL_
+
+// GSDL_NEED_STRINGS_H should be defined if some string functions
+// needed (like strcasecmp) are in strings.h
+#if defined(__IBMCPP__)
+#  define GSDL_NEED_STRINGS_H
+#endif
+
+// GSDL_USE_IOS_H should be defined if the .h extension needs to
+// be used for the io stream headers
+#if (defined(__GNUG__)  && __GNUG__ + 0 < 3) || defined(__IBMCPP__)
+#  define GSDL_USE_IOS_H 1
+#endif
+
+// GSDL_USE_STL_H should be defined if the .h extension needs to
+// be used for the stl header files
+#if defined(__IBMCPP__)
+#  define GSDL_USE_STL_H 1
+#endif
+
+// GSDL_USE_ALGO_H should be defined if algo.h should be used 
+// instead of algorithm.h
+#if defined(__IBMCPP__)
+#  define GSDL_USE_ALGO_H 1
+#endif
+
+// GSDL_NAMESPACE_BROKEN should be defined if namespaces should
+// not be used
+#if (defined(__GNUG__)  && __GNUG__ + 0 < 3) || defined(__IBMCPP__)
+#  define GSDL_NAMESPACE_BROKEN 1
+#endif
+
+// GSDL_USE_OBJECTSPACE should now be used instead of USE_OBJECTSPACE
+#if defined(USE_OBJECTSPACE)
+#  define GSDL_USE_OBJECTSPACE
+#endif
+
+// GSDL_NEED_DESTROY_USHORT should be defined if the compiler needs
+// a definition for void destroy(short unsigned int *)
+#if defined(__IBMCPP__)
+# define GSDL_NEED_DESTROY_USHORT
+#endif
+
+// mktemp
+
+#if !defined(__WIN32__) || defined(__GNUC__)
+#include <unistd.h>
+#define GSDL_MKTEMP(str) mktemp(str)
+#else
+#include <io.h>
+#define GSDL_MKTEMP(str) _mktemp(str)
+#endif
+
+
+
+// file locking
+
+#if defined(__WIN32__)
+
+#if !defined(LK_UNLOCK) && defined(LK_UNLCK)
+#define LK_UNLOCK LK_UNLCK
+#endif
+
+#include <io.h>
+#include <sys/locking.h>
+
+#define GSDL_UNLOCK_FILE(fd) _locking(fd, LK_UNLCK, 200)
+#define GSDL_LOCK_FILE(fd) lock_val = _locking(fd, LK_NBLCK, 200)
+
+#else     /* not WIN32 */
+
+#if GSDL_USE_FLOCK
+#include <sys/lock.h>
+
+#ifndef LOCK_SH
+#define LOCK_SH	1
+#endif
+
+#ifndef LOCK_EX
+#define LOCK_EX	2
+#endif
+
+#ifndef LOCK_NB
+#define LOCK_NB 4
+#endif
+
+#ifndef LOCK_UN
+#define LOCK_UN 8
+#endif
+
+#define GSDL_UNLOCK_FILE(fd) flock (fd, LOCK_UN)
+#define GSDL_LOCK_FILE(fd) lock_val = flock (fd, LOCK_EX + LOCK_NB)
+
+#else  /* ! GSDL_USE_FLOCK */
+// use fcntl
+#include <fcntl.h>
+#define GSDL_UNLOCK_FILE(fd) \
+	{					\
+	  struct flock flock;			\
+	  flock.l_type = F_UNLCK;		\
+	  flock.l_whence = SEEK_SET;		\
+	  flock.l_start = flock.l_len = 0L;	\
+	  fcntl (fd, F_SETLK, &flock);	\
+	}
+#define GSDL_LOCK_FILE(fd) \
+	{					\
+	  struct flock flock;			\
+	  flock.l_type = F_WRLCK;		\
+	  flock.l_whence = SEEK_SET;			\
+	  flock.l_start = flock.l_len = 0L;	\
+	  lock_val = fcntl (fd, F_SETLK, &flock);	\
+	}
+
+#endif
+#endif
+
+#endif
Index: /gsdl/stable/common-src/src/lib/gsdlsitecfg.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/gsdlsitecfg.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/gsdlsitecfg.cpp	(revision 20131)
@@ -0,0 +1,227 @@
+/**********************************************************************
+ *
+ * gsdlsitecfg.cpp -- 
+ * Copyright (C) 2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "fileutil.h"
+#include "gsdlsitecfg.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace/std/iostream>
+#  include <ospace/std/fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#  include <fstream.h>
+#else
+#  include <iostream>
+#  include <fstream>
+#endif
+
+
+class __site_configuration : public configurable {
+private:
+  text_t *gsdlhome;
+  text_t *collecthome;
+  text_t *httpdomain;
+  text_t *httpprefix;
+  text_t *collection;
+  text_tset *actions;
+  text_tset *browsers;
+  int    *maxrequests;
+public:
+  __site_configuration (text_t *_gsdlhome, text_t* _collecthome, int *_maxrequests) {
+    gsdlhome = _gsdlhome;
+    collecthome = _collecthome;
+    httpdomain = NULL;
+    httpprefix = NULL;
+    collection = NULL;
+    actions = NULL;
+    browsers = NULL;
+    maxrequests = _maxrequests;
+  }
+
+  __site_configuration (text_t *_gsdlhome, text_t* _collecthome, 
+			text_t *_httpdomain, text_t *_httpprefix) {
+    gsdlhome    = _gsdlhome;
+    collecthome  = _collecthome;
+    httpdomain = _httpdomain;
+    httpprefix = _httpprefix;
+    collection = NULL;
+    actions = NULL;
+    browsers = NULL;
+    maxrequests = NULL;
+  }
+
+  __site_configuration (text_t *_gsdlhome, text_t* _collecthome, 
+			text_t *_httpdomain,
+			text_t *_httpprefix, text_t *_collection) {
+    gsdlhome    = _gsdlhome;
+    collecthome  = _collecthome;
+    httpdomain = _httpdomain;
+    httpprefix = _httpprefix;
+    collection = _collection;
+    actions = NULL;
+    browsers = NULL;
+    maxrequests = NULL;
+  }
+
+  __site_configuration (text_t *_httpprefix, text_tset *_actions, text_tset *_browsers) {
+    gsdlhome    = NULL;
+    collecthome  = NULL;
+    httpdomain = NULL;
+    httpprefix = _httpprefix;
+    collection = NULL;
+    actions = _actions;
+    browsers = _browsers;
+    maxrequests = NULL;
+  }
+
+  inline void configure (const text_t &key, const text_tarray &cfgline) {
+    if (gsdlhome != NULL && key == "gsdlhome") {
+      *gsdlhome = cfgline[0];
+
+      if ((collecthome != NULL) && (collecthome->empty())) {
+	// defaults to <gsdlhome>/collect
+	*collecthome = filename_cat(*gsdlhome,"collect");
+      }
+    }
+
+    if (collecthome != NULL && key == "collecthome") {
+      if (!collecthome->empty()) {
+	// if it has been previously set to default, free and then reassign
+	collecthome->clear();
+      }
+      *collecthome = cfgline[0];
+    }
+
+    if (httpprefix != NULL && key == "httpprefix") {
+      *httpprefix = cfgline[0];
+    }
+
+    if (httpdomain != NULL && key == "httpdomain") {
+      *httpdomain = cfgline[0];
+    }
+
+    if (collection != NULL && key == "collection") {
+      *collection = cfgline[0];
+    } 
+
+    if (actions != NULL && key == "actions") {
+      actions->clear();
+      text_tarray::const_iterator thisAction = cfgline.begin();
+      text_tarray::const_iterator endAction = cfgline.end();
+      while (thisAction != endAction) {
+	actions->insert(*thisAction);
+	++thisAction;
+      }
+    } 
+
+    if (browsers != NULL && key == "browsers") {
+      browsers->clear();
+      text_tarray::const_iterator thisBrowser = cfgline.begin();
+      text_tarray::const_iterator endBrowser = cfgline.end();
+      while (thisBrowser != endBrowser) {
+	browsers->insert(*thisBrowser);
+	++thisBrowser;
+      }
+    }
+
+    if (maxrequests != NULL && key == "maxrequests") {
+      *maxrequests = cfgline[0].getint();
+      if ((*maxrequests) < 1) {
+	*maxrequests = 1;
+      }
+    }
+  }
+};
+
+
+// reads site configuration file returning true on success
+// also sets gsdlhome and maxrequests 
+// gsdlsite.cfg should be in same directory as library executable
+bool site_cfg_read (configurator gsdlconfigurator, text_t &gsdlhome, 
+		    text_t& collecthome, int &maxrequests)
+{
+  __site_configuration sitecfg(&gsdlhome, &collecthome, &maxrequests);
+  gsdlconfigurator.add_configurable(&sitecfg);
+
+  // blank the gsdlhome and collecthome text
+  gsdlhome.clear();
+  collecthome.clear();
+
+  if (gsdlconfigurator.configure("gsdlsite.cfg"))
+  {
+    return true;
+  }
+
+  return false;
+}
+
+
+// this version grabs gsdlhome, collecthome, httpdomain and httpprefix, 
+// returns false if it can't find all of them
+bool site_cfg_read (text_t &gsdlhome, text_t& collecthome, text_t &httpdomain, 
+		    text_t &httpprefix)
+{
+  // get gsdlhome etc
+  __site_configuration sitecfg(&gsdlhome, &collecthome, &httpdomain, &httpprefix);
+  configurator gsdlconfigurator(&sitecfg);
+
+  gsdlhome.clear();
+  collecthome.clear();
+  httpdomain.clear();
+  httpprefix.clear();
+
+  if (gsdlconfigurator.configure("gsdlsite.cfg"))
+  {
+    return true;
+  }
+
+  return false;
+}
+
+
+// this version grabs gsdlhome, collecthome, httpdomain, httpprefix, collection, 
+// returns false if it can't find gsdlhome, httpdomain and httpprefix
+bool site_cfg_read (text_t &gsdlhome, text_t& collecthome, text_t &httpdomain, 
+		    text_t &httpprefix, text_t &collection)
+{
+  // get gsdlhome etc
+  __site_configuration sitecfg(&gsdlhome, &collecthome, &httpdomain, &httpprefix, &collection);
+  configurator gsdlconfigurator(&sitecfg);
+	
+  gsdlhome.clear();
+  collecthome.clear();
+  httpdomain.clear();
+  httpprefix.clear();
+  collection.clear();
+	
+  if (gsdlconfigurator.configure("gsdlsite.cfg") &&
+      !gsdlhome.empty() && !collecthome.empty() 
+      && !httpdomain.empty() && !httpprefix.empty())
+  {
+    return true;
+  }	
+
+  return false;
+}
Index: /gsdl/stable/common-src/src/lib/gsdlsitecfg.h
===================================================================
--- /gsdl/stable/common-src/src/lib/gsdlsitecfg.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/gsdlsitecfg.h	(revision 20131)
@@ -0,0 +1,42 @@
+/**********************************************************************
+ *
+ * gsdlsitecfg.h -- 
+ * Copyright (C) 2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef GSDLSITECFG_H
+#define GSDLSITECFG_H
+
+
+#include "cnfgator.h"
+#include "text_t.h"
+
+
+// reads gsdlsite.cfg file returning true on success
+bool site_cfg_read (configurator gsdlconfigurator, text_t &gsdlhome, 
+		    text_t& collecthome, int &maxrequests);
+bool site_cfg_read (text_t &gsdlhome, text_t& collecthome, text_t &httpdomain, text_t &httpprefix);
+bool site_cfg_read (text_t &gsdlhome, text_t& collecthome, text_t &httpdomain, text_t &httpprefix, text_t &collection);
+
+
+#endif
Index: /gsdl/stable/common-src/src/lib/gsdltimes.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/gsdltimes.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/gsdltimes.cpp	(revision 20131)
@@ -0,0 +1,163 @@
+/**********************************************************************
+ *
+ * gsdltimes.cpp -- functions to deal with time
+ * Copyright (C) 1999  DigiLib Systems Limited, New Zealand
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdltimes.h"
+
+// returns a string of the form "YYYY/MM/DD hh:mm:ss" (expressed in
+// Coordinated Universal Time (UTC))
+// returns "" if an error occurs
+// !! Actually, we now return a string in localtime, as text2time returns
+//    a time in localtime (mktime assumes local timezone). - jrm21 Sep 2002
+text_t time2text (time_t time) {
+  // tm *tm_ptr = gmtime(&time);
+  tm *tm_ptr = localtime(&time);
+
+  if (tm_ptr == NULL) return g_EmptyText;
+
+  // year
+  text_t timestr(tm_ptr->tm_year+1900);
+  timestr.push_back('/');
+
+  // month (note the +1)
+  if ((tm_ptr->tm_mon+1) < 10) timestr.push_back('0');
+  timestr += (tm_ptr->tm_mon+1);
+  timestr.push_back('/');
+
+  // day
+  if (tm_ptr->tm_mday < 10) timestr.push_back('0');
+  timestr += tm_ptr->tm_mday;
+  timestr.push_back(' ');
+
+  // hour
+  if (tm_ptr->tm_hour < 10) timestr.push_back('0');
+  timestr += tm_ptr->tm_hour;
+  timestr.push_back(':');
+
+  // minutes
+  if (tm_ptr->tm_min < 10) timestr.push_back('0');
+  timestr += tm_ptr->tm_min;
+  timestr.push_back(':');
+
+  // seconds
+  if (tm_ptr->tm_sec < 10) timestr.push_back('0');
+  timestr += tm_ptr->tm_sec;
+
+  return timestr;
+}
+
+// takes a string like that returned by time2text and returns corresponding time_t
+// returns -1 if an error occurs
+time_t text2time (const text_t &timestr) {
+  tm timetm;
+  text_t tempstr;
+  
+  text_t::const_iterator time_here = timestr.begin();
+  text_t::const_iterator time_end = timestr.end();
+
+  // year
+  if (time_here == time_end) return (time_t) -1;
+  time_here = getdelimitstr (time_here, time_end, '/', tempstr);
+  timetm.tm_year = tempstr.getint() - 1900;
+  if (timetm.tm_year < 0) return (time_t) -1;
+
+  // month (note the -1)
+  if (time_here == time_end) return (time_t) -1;
+  time_here = getdelimitstr (time_here, time_end, '/', tempstr);
+  timetm.tm_mon = tempstr.getint() - 1;
+  if (timetm.tm_mon < 0 || timetm.tm_mon > 11)
+    return (time_t) -1;
+  
+  // day
+  if (time_here == time_end) return (time_t) -1;
+  time_here = getdelimitstr (time_here, time_end, ' ', tempstr);
+  timetm.tm_mday = tempstr.getint();
+  if (timetm.tm_mday < 1 || timetm.tm_mday > 31)
+    return (time_t) -1;
+  
+  // hour
+  if (time_here == time_end) return (time_t) -1;
+  time_here = getdelimitstr (time_here, time_end, ':', tempstr);
+  timetm.tm_hour = tempstr.getint();
+  if (timetm.tm_hour < 0 || timetm.tm_hour > 23)
+    return (time_t) -1;
+  
+  // min
+  if (time_here == time_end) return (time_t) -1;
+  time_here = getdelimitstr (time_here, time_end, ':', tempstr);
+  timetm.tm_min = tempstr.getint();
+  if (timetm.tm_min < 0 || timetm.tm_min > 59)
+    return (time_t) -1;
+  
+  // sec
+  if (time_here == time_end) return (time_t) -1;
+  time_here = getdelimitstr (time_here, time_end, ':', tempstr);
+  timetm.tm_sec = tempstr.getint();
+  if (timetm.tm_sec < 0 || timetm.tm_sec > 59)
+    return (time_t) -1;
+
+  timetm.tm_isdst=0;
+
+  /* This is for darwin - mktime seems to use this, so don't leave it
+     uninitialised!! Maybe the same on freebsd/netbsd?
+  */
+#if defined(__MACH__) && defined(__APPLE__)
+  timetm.tm_gmtoff=0;
+#endif
+
+  // mktime assumes timetm is localtime
+  return mktime (&timetm);
+}
+
+// returns current date and time formatted like "Thu Dec 07 23:43:38 GMT 2000"
+// if ltime is true return value will be expressed in local time, otherwise
+// it'll be Coordinated Universal Time (UTC) - no promises are made that the
+// resulting string will be formatted exactly as expected, especially on windows
+// returns "" if an error occurs
+text_t get_date (bool ltime) {
+
+  tm *tm_ptr = NULL;
+  time_t t = time(NULL);
+  if (ltime) tm_ptr = localtime (&t);
+  else tm_ptr = gmtime (&t);
+  if (tm_ptr == NULL) return g_EmptyText;
+  char *timestr = new char[128];
+  text_t ret;
+
+  // we do this in such an ugly way because windows is kind of flakey when
+  // it comes to timezones
+  if (ltime) {
+    strftime (timestr, 128, "%a %b %d %H:%M:%S %z %Y", tm_ptr);
+    ret.setcstr (timestr);
+  } else {
+    strftime (timestr, 128, "%a %b %d %H:%M:%S", tm_ptr);
+    ret.setcstr (timestr);
+    ret += " GMT ";
+    strftime (timestr, 128, "%Y", tm_ptr);
+    ret += timestr;
+  }
+
+  delete []timestr;
+  return ret;
+}
Index: /gsdl/stable/common-src/src/lib/gsdltimes.h
===================================================================
--- /gsdl/stable/common-src/src/lib/gsdltimes.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/gsdltimes.h	(revision 20131)
@@ -0,0 +1,46 @@
+/**********************************************************************
+ *
+ * gsdltimes.h -- functions to deal with time
+ * Copyright (C) 1999  DigiLib Systems Limited, New Zealand
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef GSDLTIMES_H
+#define GSDLTIMES_H
+
+#include <time.h>
+#include "text_t.h"
+
+// dates are stored in the format YYYY/MM/DD hh:mm:ss
+
+// returns "" if an error occurs
+text_t time2text (time_t time);
+
+// returns -1 if an error occurs
+time_t text2time (const text_t &timestr);
+
+
+// returns formatted date in local or UTC time
+// returns "" if an error occurs
+text_t get_date (bool ltime);
+
+#endif
Index: /gsdl/stable/common-src/src/lib/gsdltools.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/gsdltools.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/gsdltools.cpp	(revision 20131)
@@ -0,0 +1,280 @@
+/**********************************************************************
+ *
+ * gsdltools.cpp -- 
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdltools.h"
+#include "fileutil.h"
+#include "stdlib.h"
+
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace/std/iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+using namespace std;
+#endif
+
+
+#if defined(__WIN32__)
+#include <windows.h>
+#include <process.h>
+#endif
+
+#if !defined (__WIN32__)
+#include <sys/utsname.h>
+#include <unistd.h>
+#endif
+
+
+bool littleEndian() {
+  char s[2] = {'\xFE', '\xEF'};
+
+  if (sizeof(unsigned short) == 2)
+    return *(unsigned short*)s == 0xEFFE;
+  else if (sizeof(unsigned int) == 2)
+    return *(unsigned int*)s == 0xEFFE;
+}
+
+text_t dm_safe (const text_t &instring) {
+
+  text_t outstring;
+  text_t::const_iterator here = instring.begin();
+  text_t::const_iterator end = instring.end();
+  while (here != end) {
+    if (*here == '_' || *here == '\\') outstring.push_back('\\');
+    outstring.push_back(*here);
+    ++here;
+  }
+  return outstring;
+}
+
+void dm_js_safe(const text_t &instring, text_t &outstring)
+{
+  text_t::const_iterator here = instring.begin();
+  text_t::const_iterator end = instring.end();
+  while (here != end) {
+    if (*here == '_') outstring.push_back('\\');
+    else if (*here == '\\' || *here == '\'') {
+      outstring.push_back('\\');
+      outstring.push_back('\\');
+    }
+    outstring.push_back(*here);
+    ++here;
+  }
+}
+
+text_t xml_safe(const text_t &text_string)
+{
+  text_t text_string_safe;
+  text_t::const_iterator here = text_string.begin();
+  text_t::const_iterator end = text_string.end();
+  while (here != end) {
+    if (*here == '&') text_string_safe += "&amp;";
+    else if (*here == '<') text_string_safe += "&lt;";
+    else if (*here == '>') text_string_safe += "&gt;";
+    else text_string_safe.push_back(*here);
+    ++here;
+  }
+  return text_string_safe;
+}
+
+
+// gsdl_system creates a new process for the cmd command (which
+// may contain arguments).
+// cmd should contain the full path of the program to run.
+// The child process inherits the environment of the calling
+// process.
+// If sync is true a synchronous call will be made, otherwise
+// an asyncronous call.
+// If sync is true the return value will be the exit code of
+// the child process or -1 if the child process wasn't started.
+// If sync is false the return value will be 0 if the process
+// was started ok or -1 if it failed.
+int gsdl_system (const text_t &cmd, bool sync, ostream &logout) {
+  if (cmd.empty()) return -1;
+  char *cmd_c = cmd.getcstr();
+
+#if defined (__WIN32__)
+  // the windows version - this is implemented this way
+  // to prevent windows popping up all over the place when
+  // we call a console application (like perl)
+  STARTUPINFO ps = {sizeof(STARTUPINFO), NULL, NULL, NULL,
+                    0, 0, 0, 0, 0, 0,
+                    0, STARTF_USESHOWWINDOW,
+                    SW_HIDE, 0, NULL,
+		    NULL, NULL, NULL};
+  PROCESS_INFORMATION pi;
+  BOOL res = CreateProcess(NULL,
+                           cmd_c,
+                           NULL,
+                           NULL,
+                           FALSE,
+#if defined (GSDL_LOCAL_LIBRARY)
+			   NULL,
+#else
+			   CREATE_NO_WINDOW, // previously this was: DETACHED_PROCESS, 
+			   // see http://msdn.microsoft.com/en-us/library/ms682425.aspx 
+			   // and http://msdn.microsoft.com/en-us/library/ms684863(VS.85).aspx
+#endif
+                           NULL,
+                           NULL,
+                           &ps,
+                           &pi);
+
+  if (!res) {
+    logout << "gsdl_system failed to start " << cmd_c 
+	   << " process, error code " << GetLastError() << endl;
+    delete []cmd_c;
+    return -1;
+  } 
+
+  DWORD ret = 0;
+  if (sync) { // synchronous system call
+    // wait until child process exits.
+    WaitForSingleObject(pi.hProcess, INFINITE);
+    // set ret to exit code of child process
+    GetExitCodeProcess(pi.hProcess, &ret);
+  }
+
+  CloseHandle(pi.hProcess);
+  CloseHandle(pi.hThread);
+
+#else
+  // the unix version
+  int ret = 0;
+  if (sync) { // synchronous system call
+    // make sure the command interpreter is found
+    if (system (NULL) == 0) {
+      logout << "gsdl_system failed to start " << cmd_c
+	     << " process, command interpreter not found" << endl;
+      delete []cmd_c;
+      return -1;
+    }
+    ret = system (cmd_c);
+
+  } else { // asynchronous system call
+    int pid = fork();
+    if (pid == -1) {
+      delete []cmd_c;
+      return -1;
+    }
+    if (pid == 0) {
+      // child process
+      char *argv[4];
+      argv[0] = "sh";
+      argv[1] = "-c";
+      argv[2] = cmd_c;
+      argv[3] = 0;
+      execv("/bin/sh", argv);
+    }
+  }
+#endif
+
+  delete []cmd_c;
+  return ret;
+}
+
+
+static bool gsdl_setenv_done = false;
+static char* retain_gsdlosc   = NULL;
+static char* retain_gsdlhomec = NULL;
+static char* retain_pathc     = NULL;
+
+bool set_gsdl_env_vars (const text_t& gsdlhome) 
+{
+  if (gsdl_setenv_done) { return true; }
+
+  // set up GSDLOS, GSDLHOME and PATH environment variables
+
+  text_t gsdlos, path;
+  unsigned int path_separator = ':';
+
+#if defined (__WIN32__)
+  gsdlos = "windows";
+  path_separator = ';';
+
+  path = filename_cat (gsdlhome, "bin", "windows", "perl", "bin;");
+
+#else
+  struct utsname *buf = new struct utsname();
+  int i = uname (buf);
+  if (i == -1) gsdlos = "linux"; // uname failed, default to linux
+  else gsdlos.setcstr (buf->sysname);
+  delete buf;
+  lc (gsdlos);
+#endif
+
+  // according to getenv documentation (after a bit of digging), *getenv*
+  // is responsible for the char* pointer returned, so no need for us
+  // to free it (in fact that would be a mistake!)
+
+  char* orig_pathc = getenv ("PATH"); 
+  path += filename_cat (gsdlhome, "bin", gsdlos);
+  path.push_back (path_separator);
+  path += filename_cat (gsdlhome, "bin", "script");
+  if (orig_pathc != NULL) {
+    path.push_back (path_separator);
+    path += orig_pathc;
+  }  
+
+  text_t putpath     = "PATH=" + path;
+  text_t putgsdlos   = "GSDLOS=" + gsdlos;
+  text_t putgsdlhome = "GSDLHOME=" + gsdlhome;
+
+  retain_gsdlosc   = putgsdlos.getcstr();
+  retain_gsdlhomec = putgsdlhome.getcstr();
+  retain_pathc     = putpath.getcstr();
+  
+  if ((putenv(retain_gsdlosc)!=0) || (putenv(retain_gsdlhomec)!=0)  
+  || (putenv(retain_pathc)!=0))
+    {
+      // Would be better if the ostream& logout was used here.
+      cerr << "Error setting Greenstone environment variables with putenv()" << endl;
+      // perror("putenv(...): "); // This didn't yield any noticable output under Windows running local library server
+      return false;
+    }
+
+  // Need to keep memory allocated setgsdlosc, setgsdlhomec or pathc around
+  // (i.e. can't delete them).  This is because putenv() doesn't take
+  // a copy, but places them in the actual environment.  
+
+  gsdl_setenv_done = true;
+
+  return true;
+}
+
+
+
+// attempts to work out if perl is functional
+bool perl_ok (ostream &logout) {
+#if defined(__WIN32__)
+  text_t cmd = "perl -e \"exit 0\"";
+#else 
+  text_t cmd = "perl -e 'exit 0'";
+#endif
+  int i = gsdl_system (cmd, true, logout);
+  return (i == 0);
+}
Index: /gsdl/stable/common-src/src/lib/gsdltools.h
===================================================================
--- /gsdl/stable/common-src/src/lib/gsdltools.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/gsdltools.h	(revision 20131)
@@ -0,0 +1,82 @@
+/**********************************************************************
+ *
+ * gsdltools.h -- 
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef GSDLTOOLS_H
+#define GSDLTOOLS_H
+
+// don't actually use this but some windows
+// versions of STL complain about use of 
+// bool keyword without it
+#include "text_t.h"
+
+// returns true if machine is little endian
+bool littleEndian();
+
+// escapes '\' and '_' characters with '\'
+// note that single '\' characters occurring 
+// naturally within text (or filenames!!) will
+// be removed by the dm macro language
+text_t dm_safe (const text_t &instring);
+
+// escapes "\", "'" and "_" characters with '\'
+// note that single '\' characters occurring 
+// naturally within text (or filenames!!) will
+// be removed by the dm macro language
+//WARNING: instring will be appended to outstring
+// so is your responsability to clean the outstring
+// before call this function;
+void dm_js_safe(const text_t &instring, text_t &outstring);
+inline text_t dm_js_safe (const text_t &instring) {text_t outstring; dm_js_safe(instring, outstring); return outstring;}
+
+// Convert '&' to "&amp;", '<' to "&lt;", and '>' to "&gt;"
+text_t xml_safe(const text_t &text_string);
+
+// gsdl_system creates a new process for the cmd command (which
+// may contain arguments).
+// cmd should contain the full path of the program to run.
+// The child process inherits the environment of the calling
+// process.
+// If sync is true a synchronous call will be made, otherwise
+// an asyncronous call.
+// If sync is true the return value will be the exit code of
+// the child process or -1 if the child process wasn't started.
+// If sync is false the return value will be 0 if the process
+// was started ok or -1 if it failed.
+int gsdl_system (const text_t &cmd, bool sync, ostream &logout);
+
+bool set_gsdl_env_vars (const text_t& gsdlhome) ;
+
+// attempts to work out if perl is functional
+bool perl_ok (ostream &logout);
+
+#endif
+
+
+
+
+
+
+
Index: /gsdl/stable/common-src/src/lib/gsdlunicode.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/gsdlunicode.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/gsdlunicode.cpp	(revision 20131)
@@ -0,0 +1,671 @@
+/**********************************************************************
+ *
+ * gsdlunicode.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdlunicode.h"
+
+
+// unitool is currently in mg, if mg is not being used it should
+// be moved into GSDLHOME/lib 
+#include "unitool.h"
+
+#include "fileutil.h"
+
+#include <stdio.h>
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#  include <ospace\std\fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#  include <fstream.h>
+#else
+#  include <iostream>
+#  include <fstream>
+#endif
+
+
+// converts a unicode encode text_t string to a utf-8
+// encoded text_t string
+text_t to_utf8 (text_t::const_iterator here, text_t::const_iterator end) {
+  text_t out;
+
+  unsigned char thischar[MAXUTF8CHARLEN];
+  int i, charlen;
+
+  while (here != end) {
+    charlen = output_utf8_char (*here, thischar, &thischar[MAXUTF8CHARLEN-1]);
+    for (i=0; i<charlen; ++i) out.push_back(thischar[i]);
+    ++here;
+  }
+
+  return out;
+}
+
+// converts a utf-8 encoded text_t string to a unicode
+// encoded text_t string
+text_t to_uni (const text_t &in) {
+  text_t out;
+  unsigned char *in_cstr = (unsigned char *)in.getcstr();
+  unsigned char *here = in_cstr;
+  unsigned char *end = in_cstr;
+
+  unsigned short unichar;
+  int charlen = 0;
+
+  // get the last valid character in the string
+  while (*end != '\0') ++end;
+  --end;
+
+  while ((charlen = parse_utf8_char (here, end, &unichar)) > 0) {
+    out.push_back(unichar);
+    here += charlen;
+  }
+
+  delete []in_cstr;
+
+  return out;
+}
+
+
+// this works for all unicode values < 65536...
+void utf16outconvertclass::convert (char *out, size_t maxlen, size_t &len, status_t &status) {
+  // we should already have text_t* input set...
+  if (input == NULL || out == NULL)
+  {
+    status = finished;
+    return;
+  }
+  unsigned char *output = (unsigned char *)out;
+  text_t::iterator textend = input->end();
+  len = 0;
+  if (maxlen % 2) --maxlen; // we need an even number of output bytes...
+  while ((len < maxlen) && (texthere != textend)) {
+    unsigned short int uni_char=(unsigned short int) *texthere;
+    // big endian utf-16...
+    if (uni_char < 256) {
+      out[len]=0;   
+      out[len+1]=uni_char;
+    } else {
+      out[len]=uni_char >> 8;
+      out[len+1]=uni_char & 255;
+    }
+    len+=2;
+    ++texthere;
+  }
+  if (texthere==textend)
+    status=finished;
+  else
+    status=unfinished;
+}
+
+
+utf8inconvertclass::utf8inconvertclass () {
+  utf8buflen = 0;
+}
+
+void utf8inconvertclass::reset () {
+  start = NULL;
+  len = 0;
+  utf8buflen=0;
+}
+
+void utf8inconvertclass::convert (text_t &output, status_t &status) {
+  output.clear();
+  output.reserve (len/3);
+  
+  if (start == NULL || len == 0) {
+    if (utf8buflen == 0) status = finished;
+    else status = stopped;
+    return;
+  }
+
+  // don't want any funny sign conversions happening
+  unsigned char *here = (unsigned char *)start;
+  unsigned char *end = here+len-1;
+  unsigned short c;
+  size_t realcharlen;
+
+  size_t charlen = getutf8charlen ();
+  while (len > 0) {
+    if (charlen == 0) {
+      // start parsing a new character
+      utf8buflen = 0;
+
+      // fast common case
+      while (len > 3) {
+  	realcharlen = parse_utf8_char (here, end, &c);
+  	output.push_back (c);
+  	here += realcharlen;
+  	len -= realcharlen;
+      }
+
+      utf8buf[utf8buflen++] = *here;
+      ++here;
+      --len;
+      charlen = getutf8charlen ();
+
+    } else if (utf8buflen < charlen) {
+      // assumes charlen is always less than MAXUTF8CHARLEN
+      utf8buf[utf8buflen++] = *here;
+      ++here;
+      --len;
+    }
+
+    if (utf8buflen == charlen) {
+      // got a complete character
+      realcharlen = parse_utf8_char (utf8buf, &utf8buf[utf8buflen-1], &c);
+      output.push_back (c);
+      
+      // move any unparsed characters. If an error occurred some of
+      // the characters might be unused.
+      int i;
+      int diff = utf8buflen - realcharlen;
+      for (i=0; i < diff; ++i) utf8buf[i] = utf8buf[i+diff];
+      utf8buflen = diff;
+      charlen = getutf8charlen ();
+    }
+  }
+
+  start = (char *)here; // save current position
+
+  if (utf8buflen == 0) status = finished;
+  else status = stopped;
+}
+
+
+// returns the length that the current contents of the 
+// utf8buf should be
+size_t utf8inconvertclass::getutf8charlen () {
+  if (utf8buflen == 0) return 0;
+
+  // one byte character
+  if (utf8buf[0] < 0x80) return 1;
+
+  // error, is not the start of a utf-8 character
+  if (utf8buf[0] < 0xc0) return 1;
+
+  // two bute character
+  if (utf8buf[0] < 0xe0) return 2;
+
+  // three byte character
+  if (utf8buf[0] < 0xf0) return 3;
+
+  // error, character too long for unicode
+  return 1;
+}
+
+
+void utf8outconvertclass::reset () {
+  input = NULL;
+  outs = NULL;
+  utf8buflen = 0;
+  utf8bufhere = 0;
+}
+
+// note that convert does not null-terminate the
+// output array of characters
+void utf8outconvertclass::convert (char *output, size_t maxlen, 
+				   size_t &len, status_t &status) {
+  if (input == NULL || output == NULL) {
+    if (utf8buflen == 0) status = finished;
+    else status = unfinished;
+    return;
+  }
+
+  // don't want any funny sign conversions happening
+  unsigned char *uoutput = (unsigned char *)output;
+  text_t::iterator textend = input->end();
+  len = 0;
+  while (len < maxlen) {
+    // empty the contents of the internal buffer
+    if (utf8buflen > 0) {
+      while (len < maxlen && utf8bufhere < utf8buflen) {
+	*uoutput = utf8buf[utf8bufhere];
+	++uoutput;
+	++len;
+	++utf8bufhere;
+      }
+
+      if (utf8bufhere == utf8buflen) {
+	utf8bufhere = 0;
+	utf8buflen = 0;
+      }
+    }
+
+    // fill up the buffer with the next character
+    if (utf8buflen == 0) {
+      if (texthere == textend) break; // finished!
+      if (!rzws || (*texthere != 0x200b))
+	utf8buflen = output_utf8_char (*texthere, utf8buf, 
+				       &utf8buf[MAXUTF8CHARLEN-1]);
+      ++texthere;
+      utf8bufhere = 0;
+    }
+  }
+  
+  if (texthere == textend && utf8buflen == 0) status = finished;
+  else status = unfinished;
+}
+
+
+
+
+
+
+mapdata_t::mapdata_t () {
+
+  // reset all the map ptrs to be NULL
+  for (int i=0; i<256; ++i) {
+    ptrs[i] = (unsigned short *)NULL;
+  }
+
+  // say nothing has been loaded
+  loaded = false;
+}
+
+
+mapconvert::mapconvert () {
+  absentc = 0;
+}
+
+// setmapfile will cause loadmapfile to be called when conversion is
+// needed
+bool mapconvert::setmapfile (const text_t &themapfile, unsigned short theabsentc) {
+  // check to see if the mapfile has been already loaded
+  if (mapdata.loaded && mapfile == themapfile && absentc == theabsentc) return true;
+
+  unloadmapfile ();
+  mapfile = themapfile;
+  absentc = theabsentc;
+  
+  return true;
+}
+
+
+
+// loadmapfile should be called before any conversion is done
+bool mapconvert::loadmapfile (const text_t &themapfile,
+			      unsigned short theabsentc) {
+  FILE *mapfilein = (FILE *)NULL;
+
+  // check to see if the mapfile has been already loaded
+  if (mapdata.loaded && mapfile == themapfile && absentc == theabsentc) return true;
+
+  unloadmapfile ();
+  mapfile = themapfile;
+  absentc = theabsentc;
+
+  // open the map file
+  char *cfilename = mapfile.getcstr();
+  if (cfilename == (char *)NULL) return false;
+  mapfilein = fopen(cfilename, "rb");
+  delete []cfilename; cfilename = NULL;
+
+  if (mapfilein == (FILE *)NULL) return false;
+
+  unsigned char c, n1, n2;
+  unsigned short *arrptr;
+  int i;
+  c = fgetc (mapfilein);
+  while (!feof (mapfilein)) {
+    if (mapdata.ptrs[c] == (unsigned short *)NULL) {
+      // allocate a new array
+      arrptr = new unsigned short[256];
+      mapdata.ptrs[c] = arrptr;
+    } else arrptr = mapdata.ptrs[c];
+
+    // clear the array
+    for (i=0; i<256; ++i) arrptr[i] = 0;
+    
+    // read in this block
+    n1 = fgetc (mapfilein);
+    n2 = fgetc (mapfilein);
+    i=0;
+    while (!feof (mapfilein)) {
+      arrptr[i] = ((unsigned short)n1 << 8) | (unsigned short)n2;
+
+      ++i;
+      if (i >= 256) break;
+      n1 = fgetc (mapfilein);
+      n2 = fgetc (mapfilein);
+    }
+
+    c = fgetc (mapfilein);
+  }
+
+  mapdata.loaded = true;
+
+  return true;
+}
+
+void mapconvert::unloadmapfile () {
+  if (!mapdata.loaded) return;
+
+  for (int i=0; i<256; ++i) {
+    if (mapdata.ptrs[i] != (unsigned short *)NULL) {
+      delete [] mapdata.ptrs[i];
+      mapdata.ptrs[i] = (unsigned short *)NULL;
+    }
+  }
+
+  mapdata.loaded = false;
+}
+
+
+unsigned short mapconvert::convert (unsigned short c) {
+  if (!mapdata.loaded) {
+    if (!mapfile.empty() && loadmapfile (mapfile, absentc)) {
+      // do nothing, successfully loaded database
+    } else return absentc;
+  }
+
+  if (c == 0) return 0; // 0 always maps to 0...
+
+  unsigned short n1 = c >> 8;
+  unsigned short n2 = c & 0xff;
+
+  unsigned short *arrptr = mapdata.ptrs[n1];
+  if (arrptr == (unsigned short *)NULL) return absentc;
+
+  if (arrptr[n2] == 0) return absentc;
+  return arrptr[n2];
+}
+
+text_t mapconvert::convert (const text_t &instr) {
+  if (!mapdata.loaded) return absentc;
+
+  text_t outstr;
+  text_t::const_iterator here = instr.begin();
+  text_t::const_iterator end = instr.end();
+
+  while (here != end) {
+    outstr.push_back(this->convert(*here));
+    ++here;
+  }
+  
+  return outstr;
+}
+
+
+
+
+mapinconvertclass::mapinconvertclass () {
+  m_multibyte = 0;
+  mapbuflen = 0;
+}
+
+void mapinconvertclass::reset () {
+  start = NULL;
+  len = 0;
+  mapbuflen=0;
+}
+
+void mapinconvertclass::convert (text_t &output, status_t &status) {
+  output.clear();
+
+  if (start == NULL || len == 0) {
+    if (mapbuflen == 0) status = finished;
+    else status = stopped;
+    return;
+  }
+
+  // don't want any funny sign conversions happening
+  unsigned char *here = (unsigned char *)start;
+
+  size_t charlen = getmapcharlen ();
+  while (len > 0) {
+    if (charlen == 0) {
+      // start parsing a new character
+      mapbuflen = 0;
+      mapbuf[mapbuflen++] = *here;
+      ++here;
+      --len;
+      charlen = getmapcharlen ();
+
+    } else if (mapbuflen < charlen) {
+      // assumes charlen is always less than MAXMAPCHARLEN
+      mapbuf[mapbuflen++] = *here;
+      ++here;
+      --len;
+    }
+
+    if (mapbuflen == charlen) {
+      // got a complete character
+      if (charlen == 1) {
+	if (mapbuf[0] < 0x80) {
+	  // ascii character
+	  output.push_back (mapbuf[0]);
+	} else {
+	  output.push_back (converter.convert((unsigned short)mapbuf[0]));
+	}
+
+      } else {
+	// two byte character
+	output.push_back (converter.convert(((unsigned short)mapbuf[0] << 8) |
+					    (unsigned short)mapbuf[1]));
+      }
+
+      mapbuflen = 0;
+      charlen = 0;
+    }
+  }
+
+  start = (char *)here; // save current position
+
+  if (mapbuflen == 0) status = finished;
+  else status = stopped;
+}
+
+
+
+mapoutconvertclass::mapoutconvertclass () {
+  m_multibyte = 0;
+  mapbuflen=0; 
+  mapbufhere=0;
+}
+
+void mapoutconvertclass::reset () {
+  input = NULL;
+  outs = NULL;
+  mapbuflen = 0;
+  mapbufhere = 0;
+}
+
+// note that convert does not null-terminate the
+// output array of characters
+void mapoutconvertclass::convert (char *output, size_t maxlen, 
+				 size_t &len, status_t &status) {
+  unsigned short outc;
+
+  if (input == NULL || output == NULL) {
+    if (mapbuflen == 0) status = finished;
+    else status = unfinished;
+    return;
+  }
+
+  // don't want any funny sign conversions happening
+  unsigned char *uoutput = (unsigned char *)output;
+  text_t::iterator textend = input->end();
+  len = 0;
+  while (len < maxlen) {
+    // empty the contents of the internal buffer
+    if (mapbuflen > 0) {
+      while (len < maxlen && mapbufhere < mapbuflen) {
+	*uoutput = mapbuf[mapbufhere];
+	++uoutput;
+	++len;
+	++mapbufhere;
+      }
+
+      if (mapbufhere == mapbuflen) {
+	mapbufhere = 0;
+	mapbuflen = 0;
+      }
+    }
+
+    // fill up the buffer with the next character
+    if (mapbuflen == 0) {
+      if (texthere == textend) break; // finished!
+      if (!rzws || (*texthere != 0x200b)) {
+	if (*texthere < 0x80) {
+	  mapbuf[0] = (unsigned char)*texthere;
+	  mapbuflen = 1;
+	} else {
+	  outc = converter.convert (*texthere);
+	  if (m_multibyte) {
+	    mapbuf[0] = (unsigned char)(outc >> 8);
+	    mapbuf[1] = (unsigned char)(outc & 0xff);
+	    mapbuflen = 2;
+	  } else {
+	    mapbuf[0] = outc;
+	    mapbuflen = 1;
+	  }
+	}
+      }
+
+      ++texthere;
+      mapbufhere = 0;
+    }
+  }
+  
+  if (texthere == textend && mapbuflen == 0) status = finished;
+  else status = unfinished;
+}
+
+
+bool simplemapconvert::loadmapfile (bool in) {
+  if (loaded) return true;
+  if (mapfile.empty()) return false;
+
+  char *cfilename = mapfile.getcstr();
+#ifdef GSDL_USE_IOS_H
+  ifstream mapfilein (cfilename, ios::in | ios::nocreate);
+#else
+  ifstream mapfilein (cfilename, ios::in);
+#endif
+  delete []cfilename;
+  if (!mapfilein) return false;
+
+  char cline[2048];
+  text_t line;
+
+  while (!mapfilein.eof()) {
+    mapfilein.getline (cline, 2048);
+    line.clear();
+    line.appendcstr (cline);
+    if (line.empty()) continue;
+    // remove comments
+    text_t::iterator end = line.end();
+    text_t::iterator here = findchar (line.begin(), end, '#');
+    if (here != end) {
+      line.erase (here, end);
+      if (line.empty()) continue;
+    }
+    
+    text_tarray parts;
+    splitchar (line.begin(), line.end(), '\t', parts);
+    
+    // do some simple sanity checks
+    if (parts.size() < 2) continue;
+    text_t::iterator begin1 = parts[0].begin();
+    text_t::iterator begin2 = parts[1].begin();
+    if (*begin1 != '0' || *(begin1+1) != 'x') continue;
+    if (*begin2 != '0' || *(begin2+1) != 'x') continue;
+    char *from = parts[0].getcstr();
+    char *to = parts[1].getcstr();
+    unsigned int f = 0, t = 0;
+    sscanf (from, "%i", &f);
+    sscanf (to, "%i", &t);
+    delete []from;
+    delete []to;
+    
+    if (in) mapping[(unsigned short)f] = (unsigned short)t;
+    else mapping[(unsigned short)t] = (unsigned short)f;
+  }
+
+  loaded = true;
+  return true;
+}
+
+unsigned short simplemapconvert::convert (unsigned short c, bool in) {
+
+  if (!loaded) 
+    if (!loadmapfile(in)) return absentc;
+  
+  return mapping[c];
+}
+
+
+void simplemapinconvertclass::convert (text_t &output, status_t &status) {
+  output.clear();
+  
+  if (start == NULL || len == 0) {
+    status = finished;
+    return;
+  }
+
+  // don't want any funny sign conversions happening
+  unsigned char *here = (unsigned char *)start;
+  while (len > 0) {
+
+    if (*here < 0x80)
+      output.push_back (*here); // append this character
+    else 
+      output.push_back (converter.convert(*here, true));
+
+    ++here;
+    --len;
+  }
+
+  start = (char *)here; // save current position
+  status = finished;
+}
+
+
+void simplemapoutconvertclass::convert (char *output, size_t maxlen, 
+					size_t &len, status_t &status) {
+
+  if (input == NULL || output == NULL) {
+    status = finished;
+    return;
+  }
+
+  // don't want any funny sign conversions happening
+  unsigned char *uoutput = (unsigned char *)output;
+  text_t::iterator textend = input->end();
+  len = 0;
+  while ((len < maxlen) && (texthere != textend)) {
+
+    if (*texthere < 0x80) *uoutput = (unsigned char)(*texthere);
+    else *uoutput = converter.convert (*texthere, false);
+
+    ++uoutput;
+    ++len;
+    ++texthere;
+  }
+  
+  if (texthere == textend) status = finished;
+  else status = unfinished;
+}
Index: /gsdl/stable/common-src/src/lib/gsdlunicode.h
===================================================================
--- /gsdl/stable/common-src/src/lib/gsdlunicode.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/gsdlunicode.h	(revision 20131)
@@ -0,0 +1,277 @@
+/**********************************************************************
+ *
+ * gsdlunicode.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef GSDLUNICODE_H
+#define GSDLUNICODE_H
+
+#include "text_t.h"
+
+
+// converts a unicode encode text_t string to a utf-8
+// encoded text_t string
+text_t to_utf8 (text_t::const_iterator here, text_t::const_iterator end);
+inline text_t to_utf8 (const text_t &in) {return to_utf8 (in.begin(), in.end());}
+
+// converts a utf-8 encoded text_t string to a unicode
+// encoded text_t string
+text_t to_uni (const text_t &in);
+
+#define MAXUTF8CHARLEN 3
+
+// convert from a utf-8 char stream to the text_t class
+class utf8inconvertclass : public inconvertclass {
+public:
+  utf8inconvertclass();
+  void reset ();
+  void convert (text_t &output, status_t &status);
+
+protected:
+  // buffer to hold unconverted characters in a stream
+  unsigned char utf8buf[MAXUTF8CHARLEN];
+  size_t utf8buflen;
+
+  // returns the length that the current contents of the 
+  // utf8buf should be
+  size_t getutf8charlen ();
+};
+
+
+// This class provides the option of removing zero width
+// spaces (U+200B) during the output. By default this
+// option is turned off. The functionality is actually
+// implemented by the sub-classes, this class just provides
+// the framework for these classes. 
+//
+// Note: by convention reset() should not reset the rzws flag.
+class rzwsoutconvertclass : public outconvertclass {
+public:
+  rzwsoutconvertclass () {rzws = 0;};
+  void set_rzws (int new_rzws) {rzws = new_rzws;};
+
+protected:
+  int rzws;
+};
+
+// utf16 is almost the same as unicode, except for unicode values > 65535.
+class utf16outconvertclass : public rzwsoutconvertclass {
+public:
+  utf16outconvertclass () {};
+  void convert (char *out, size_t maxlen, size_t &len, status_t &status);
+};
+
+
+// Convert from a text_t class to a utf-8 char stream
+class utf8outconvertclass : public rzwsoutconvertclass {
+public:
+  utf8outconvertclass () {utf8buflen=0; utf8bufhere=0;};
+  void reset ();
+  // note that convert does not null-terminate the
+  // output array of characters
+  void convert (char *output, size_t maxlen, 
+		size_t &len, status_t &status);
+
+protected:
+  unsigned char utf8buf[MAXUTF8CHARLEN];
+  size_t utf8buflen;
+  size_t utf8bufhere;
+};
+
+
+// mapdata_t is used by mapconvert to hold the map file data
+class mapdata_t {
+public:
+  mapdata_t();
+  bool loaded;
+  unsigned short *ptrs[256];
+};
+
+// mapconvert is used in situations where conversion is best
+// done using a map file. The mapfile should reside in 
+// gsdlhome/unicode.
+class mapconvert {
+public:
+  mapconvert ();
+  ~mapconvert () {unloadmapfile();};
+
+  // setmapfile will cause loadmapfile to be called when conversion is
+  // needed
+  bool setmapfile (const text_t &themapfile, unsigned short theabsentc);
+
+  // loadmapfile should be called before any conversion is done
+  bool loadmapfile (const text_t &themapfile, unsigned short theabsentc);
+  void unloadmapfile ();
+
+  unsigned short convert (unsigned short c);
+
+  // note that this version of convert has different semantics to
+  // the convertclass version.
+  text_t convert (const text_t &instr);
+
+protected:
+  text_t mapfile;
+  unsigned short absentc;
+  mapdata_t mapdata;
+};
+
+
+
+#define MAXMAPCHARLEN 2
+
+// convert from a gb char stream to the unicode text_t class
+class mapinconvertclass : public inconvertclass {
+public:
+  mapinconvertclass();
+  virtual ~mapinconvertclass() {};
+
+  // setmapfile will cause loadmapfile to be called when conversion is needed
+  bool setmapfile (const text_t &themapfile, unsigned short theabsentc) {
+    return converter.setmapfile (themapfile, theabsentc);
+  };
+
+  // loadmapfile should be called before any conversion takes
+  // place
+  bool loadmapfile (const text_t &themapfile, unsigned short theabsentc) {
+    return converter.loadmapfile (themapfile, theabsentc);
+  };
+
+  void set_multibyte (int new_multibyte) {m_multibyte = new_multibyte;};
+
+  void reset ();
+  void convert (text_t &output, status_t &status);
+
+protected:
+  // buffer to hold unconverted characters in a stream
+  unsigned char mapbuf[MAXMAPCHARLEN];
+  size_t mapbuflen;
+  int m_multibyte;
+
+  // note: multiple instances of mapinconvert class are expensive
+  // as each will have its own copy of the map file data. This
+  // could be reduced by making map2unimap static, but then it
+  // wouldn't be thread safe.
+  mapconvert converter;
+
+  // returns the length that the current contents of the 
+  // mapbuf should be
+  inline size_t getmapcharlen () {
+    if (mapbuflen == 0) return 0;
+    if (mapbuf[0] < 0x80) return 1;
+    if (!m_multibyte) return 1;
+    return 2;
+  }
+};
+
+
+// Convert from a text_t class to a map char stream
+class mapoutconvertclass : public rzwsoutconvertclass {
+public:
+  mapoutconvertclass ();
+  virtual ~mapoutconvertclass() {};
+
+  // setmapfile will cause loadmapfile to be called when conversion is needed
+  bool setmapfile (const text_t &themapfile, unsigned short theabsentc) {
+    return converter.setmapfile (themapfile, theabsentc);
+  };
+
+  // loadmapfile should be called before any conversion takes
+  // place
+  bool loadmapfile (const text_t &themapfile, unsigned short theabsentc) {
+    return converter.loadmapfile (themapfile, theabsentc);
+  };
+
+  void set_multibyte (int new_multibyte) {m_multibyte = new_multibyte;};
+
+  void reset ();
+  void convert (char *output, size_t maxlen, 
+		size_t &len, status_t &status);
+
+protected:
+  unsigned char mapbuf[MAXMAPCHARLEN];
+  size_t mapbuflen;
+  size_t mapbufhere;
+  int m_multibyte;
+
+  mapconvert converter;
+};
+
+
+// Simple input and output converter classes for use with 8 bit encodings
+// using simple textual map files. Map files should contain (at least) two
+// tab-separated fields. The first field is the mapped value and the second
+// field is the unicode value.
+
+struct ltus_t 
+{
+  bool operator()(const unsigned short &t1, const unsigned short &t2) const
+  { return t1 < t2; }
+};
+
+
+class simplemapconvert {
+public:
+  simplemapconvert () {absentc=0; loaded=false;}
+  unsigned short convert (unsigned short c, bool in);
+  void setmapfile (const text_t &themapfile) {mapfile = themapfile;}
+
+protected:
+  bool loadmapfile (bool in);
+
+  map <unsigned short, unsigned short, ltus_t> mapping;
+  bool loaded;
+  text_t mapfile;
+  unsigned short absentc;
+};
+
+
+class simplemapinconvertclass : public inconvertclass {
+public:
+  virtual ~simplemapinconvertclass () {}
+
+  void convert (text_t &output, status_t &status);
+
+  void setmapfile (const text_t &themapfile) {converter.setmapfile(themapfile);}
+  
+protected:
+  simplemapconvert converter;
+};
+
+class simplemapoutconvertclass : public rzwsoutconvertclass {
+public:
+  virtual ~simplemapoutconvertclass () {}
+
+  void convert (char *output, size_t maxlen, 
+		size_t &len, status_t &status);
+
+  void setmapfile (const text_t &themapfile) {converter.setmapfile(themapfile);}
+  
+protected:
+  simplemapconvert converter;
+};
+
+
+
+
+#endif
Index: /gsdl/stable/common-src/src/lib/infodbclass.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/infodbclass.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/infodbclass.cpp	(revision 20131)
@@ -0,0 +1,147 @@
+/**********************************************************************
+ *
+ * infodbclass.cpp -- 
+ * Copyright (C) 1999-2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "infodbclass.h"
+
+
+// constructors
+infodbclass::infodbclass () {
+}
+
+
+void infodbclass::setinfo (const text_t &key, const text_t &value)
+{
+  text_tarray &tarr = info[key];
+  tarr.erase(tarr.begin(), tarr.end());
+  tarr.push_back(value);
+}
+
+
+void infodbclass::setintinfo (const text_t &key, int value)
+{
+  setinfo (key, value);
+}
+
+
+void infodbclass::setcinfo (const text_t &key, unsigned short c)
+{
+  text_t t;
+  t.push_back (c);
+  setinfo (key, t);
+}
+
+
+text_t *infodbclass::getinfo (const text_t &key)
+{
+  iterator here = info.find (key);
+  if (here == info.end()) return NULL;
+
+  if ((*here).second.empty()) return NULL;
+  
+  return &((*here).second[0]);
+}
+
+
+text_t *infodbclass::getinfo (const text_t &key, const text_t& slang)
+{
+  text_tarray *t = getmultinfo(key, slang);
+  if (t == NULL || t->empty()) return NULL;
+  return &((*t)[0]);
+}
+
+
+int infodbclass::getintinfo (const text_t &key)
+{
+  text_t *t = getinfo (key);
+  if (t == NULL) return 0;
+  return t->getint();
+}
+
+
+int infodbclass::getintinfo (const text_t &key, const text_t& slang)
+{
+  text_tarray *t = getmultinfo(key, slang);
+  if (t == NULL || t->empty()) return 0;
+  return (*t)[0].getint();
+}
+
+
+text_t &infodbclass::operator[] (const text_t &key)
+{
+  text_tarray &tarr = info[key];
+  if (tarr.empty()) {
+    text_t e;
+    tarr.push_back(e);
+  }
+  return tarr[0];
+}
+
+
+void infodbclass::addinfo (const text_t &key, const text_t &value)
+{
+  text_tarray &tarr = info[key];
+  tarr.push_back (value);
+}
+
+
+void infodbclass::addintinfo (const text_t &key, int value)
+{
+  addinfo (key, value);
+}
+
+
+void infodbclass::addcinfo (const text_t &key, unsigned short c)
+{
+  text_t t;
+  t.push_back(c);
+  addinfo (key, t);
+}
+
+
+text_tarray *infodbclass::getmultinfo (const text_t &key)
+{
+  iterator here = info.find (key);
+  if (here == info.end()) return NULL;
+
+  return &((*here).second);
+}
+
+
+text_tarray *infodbclass::getmultinfo (const text_t &key, const text_t& slang)
+{
+  iterator here = info.end();
+  if (slang.empty()) {
+    here = info.find (key);
+  }
+  else {
+    here = info.find (key+":"+slang);
+    if (here == info.end()) {
+      here = info.find (key);
+    }
+  }
+  if (here == info.end()) return NULL;
+
+  return &((*here).second);
+}
Index: /gsdl/stable/common-src/src/lib/infodbclass.h
===================================================================
--- /gsdl/stable/common-src/src/lib/infodbclass.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/infodbclass.h	(revision 20131)
@@ -0,0 +1,110 @@
+/**********************************************************************
+ *
+ * infodbclass.h -- 
+ * Copyright (C) 1999-2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef INFODBCLASS_H
+#define INFODBCLASS_H
+
+
+#include "text_t.h"
+
+
+typedef map<text_t, text_tarray, lttext_t> text_tarraymap;
+
+
+// infodbclass is used to store information about a object
+class infodbclass {
+protected:
+  text_tarraymap info;
+  text_t lang;
+
+public:
+  // type support for text_tarraymap
+  typedef text_tarraymap::iterator iterator;
+  typedef text_tarraymap::const_iterator const_iterator;
+  typedef text_tarraymap::reference reference;
+  typedef text_tarraymap::const_reference const_reference;
+  typedef text_tarraymap::size_type size_type;
+  typedef text_tarraymap::difference_type difference_type;
+  typedef text_tarraymap::const_reverse_iterator const_reverse_iterator;
+  typedef text_tarraymap::reverse_iterator reverse_iterator;
+  
+  // constructors
+  infodbclass ();
+
+  // basic container support
+  iterator begin () {return info.begin();}
+  const_iterator begin () const {return info.begin();}
+  iterator end () {return info.end();}
+  const_iterator end () const {return info.end();}
+
+  void erase(iterator pos) {info.erase(pos);}
+  void erase(iterator first, iterator last) {info.erase(first, last);}
+  infodbclass &operator=(const infodbclass &x) {info=x.info;return *this;}
+
+  bool empty () const {return info.empty();}
+  size_type size() const {return info.size();}
+
+
+  // added functionality
+  void clear () {info.erase(info.begin(),info.end());}
+
+  // set default language
+  void set_language(const text_t& str_lang) { lang = str_lang; }
+  const text_t &get_language() const { return lang; }
+
+  // the following functions deal with keys that can only
+  // have one value for compatibility
+  
+  // getinfo returns NULL if there isn't an entry with
+  // 'key' already defined, getintinfo returns 0 if there wasn't an
+  // entry with 'key' defined and operator[] returns "" if
+  // 'key' wasn't already defined (and sets 'key'="").
+  void setinfo (const text_t &key, const text_t &value);
+  void setintinfo (const text_t &key, int value);
+  void setcinfo (const text_t &key, unsigned short c);
+  text_t *getinfo (const text_t &key);
+  // get info overriding language set on this object
+  text_t *getinfo (const text_t &key, const text_t& lang);
+  int getintinfo (const text_t &key);
+  // get info overriding language set on this object
+  int getintinfo (const text_t &key, const text_t& lang);
+  text_t &operator[] (const text_t &key);
+
+
+  // the next set of functions allow you to set and access keys
+  // that can have more than one value
+
+  // getmultinfo returns NULL if there isn't an entry with
+  // 'key' already defined
+  void addinfo (const text_t &key, const text_t &value);
+  void addintinfo (const text_t &key, int value);
+  void addcinfo (const text_t &key, unsigned short c);
+  text_tarray *getmultinfo (const text_t &key);
+  // get info overriding language set on this object
+  text_tarray *getmultinfo (const text_t &key, const text_t& lang);
+};
+
+
+#endif
Index: /gsdl/stable/common-src/src/lib/md5.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/md5.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/md5.cpp	(revision 20131)
@@ -0,0 +1,283 @@
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.	This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+/* Brutally hacked by John Walker back from ANSI C to K&R (no
+   prototypes) to maintain the tradition that Netfone will compile
+   with Sun's original "cc". */
+
+/* Hacked about for use with Greenstone by Stefan Boddie, DL Consulting Ltd
+   (http://www.dlconsulting.co.nz)
+*/
+
+#include <fstream>
+#include <stdio.h>
+#include <memory.h>		 /* for memcpy() */
+#include "md5.h"
+
+#ifdef _LITTLE_ENDIAN
+#define byteReverse(buf, len)	/* Nothing */
+#else
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+void byteReverse(unsigned char *buf, unsigned int longs) {
+  uint32 t;
+  do {
+    t = (uint32) ((unsigned int) buf[3] << 8 | buf[2]) << 16 |
+      ((unsigned int) buf[1] << 8 | buf[0]);
+    *(uint32 *) buf = t;
+    buf += 4;
+  } while (--longs);
+}
+#endif
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(MD5Context *ctx) {
+  ctx->buf[0] = 0x67452301;
+  ctx->buf[1] = 0xefcdab89;
+  ctx->buf[2] = 0x98badcfe;
+  ctx->buf[3] = 0x10325476;
+  
+  ctx->bits[0] = 0;
+  ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(MD5Context *ctx, unsigned char *buf, unsigned int len) {
+  uint32 t;
+  
+  /* Update bitcount */
+  
+  t = ctx->bits[0];
+  if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
+    ctx->bits[1]++; 	/* Carry from low to high */
+  ctx->bits[1] += len >> 29;
+  
+  t = (t >> 3) & 0x3f;	/* Bytes already in shsInfo->data */
+  
+  /* Handle any leading odd-sized chunks */
+  
+    if (t) {
+      unsigned char *p = (unsigned char *) ctx->in + t;
+      
+      t = 64 - t;
+      if (len < t) {
+	memcpy(p, buf, len);
+	return;
+      }
+      memcpy(p, buf, t);
+      byteReverse(ctx->in, 16);
+      MD5Transform(ctx->buf, (uint32 *) ctx->in);
+      buf += t;
+      len -= t;
+    }
+    /* Process data in 64-byte chunks */
+    
+    while (len >= 64) {
+      memcpy(ctx->in, buf, 64);
+      byteReverse(ctx->in, 16);
+      MD5Transform(ctx->buf, (uint32 *) ctx->in);
+      buf += 64;
+      len -= 64;
+    }
+    
+    /* Handle any remaining bytes of data. */
+    
+    memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern 
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Final(unsigned char digest[16], MD5Context *ctx) {
+  unsigned int count;
+  unsigned char *p;
+  
+  /* Compute number of bytes mod 64 */
+  count = (ctx->bits[0] >> 3) & 0x3F;
+  
+  /* Set the first char of padding to 0x80.  This is safe since there is
+     always at least one byte free */
+  p = ctx->in + count;
+  *p++ = 0x80;
+  
+  /* Bytes of padding needed to make 64 bytes */
+  count = 64 - 1 - count;
+  
+  /* Pad out to 56 mod 64 */
+  if (count < 8) {
+    /* Two lots of padding:  Pad the first block to 64 bytes */
+    memset(p, 0, count);
+    byteReverse(ctx->in, 16);
+    MD5Transform(ctx->buf, (uint32 *) ctx->in);
+    
+    /* Now fill the next block with 56 bytes */
+    memset(ctx->in, 0, 56);
+  } else {
+    /* Pad block to 56 bytes */
+    memset(p, 0, count - 8);
+  }
+  byteReverse(ctx->in, 14);
+  
+  /* Append length in bits and transform */
+  ((uint32 *) ctx->in)[14] = ctx->bits[0];
+  ((uint32 *) ctx->in)[15] = ctx->bits[1];
+  
+  MD5Transform(ctx->buf, (uint32 *) ctx->in);
+  byteReverse((unsigned char *) ctx->buf, 4);
+  memcpy(digest, ctx->buf, 16);
+  memset(ctx, 0, sizeof(ctx));        /* In case it's sensitive */
+}
+
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Transform(uint32 buf[4], uint32 in[16]) {
+  register uint32 a, b, c, d;
+  
+  a = buf[0];
+  b = buf[1];
+  c = buf[2];
+  d = buf[3];
+  
+  MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+  MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+  MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+  MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+  MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+  MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+  MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+  MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+  MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+  MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+  
+  MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+  MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+  MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+  MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+  MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+  MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+  MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+  MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+  MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+  MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+  MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+  MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+  
+  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+  MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+  MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+  MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+  MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+  MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+  MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+  MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+  MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+  MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+  MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+  MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+  
+  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+  MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+  MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+  MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+  MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+  MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+  MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+  MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+  MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+  MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+  MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+  MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+    
+  buf[0] += a;
+  buf[1] += b;
+  buf[2] += c;
+  buf[3] += d;
+}
+
+text_t md5data(const text_t &data) {
+
+  unsigned char buffer[16384];
+  int buflen = sizeof(buffer);
+  int i = 0;
+  MD5Context md5c;
+
+  MD5Init(&md5c);
+
+  text_t::const_iterator here = data.begin();
+  text_t::const_iterator end = data.end();
+  while (here != end) {
+    i = 0;
+    while ((i < buflen) && (here != end)) {
+      buffer[i] = (unsigned char)(*here);
+      here++; i++;
+    }
+    MD5Update(&md5c, buffer, i);
+  }
+
+  unsigned char signature[16];
+  text_t rv;
+  MD5Final(signature, &md5c);
+  char *b = new char[8];
+  for (int j = 0; j < sizeof signature; j++) {
+    sprintf(b, "%02x", signature[j]);
+    rv += b;
+  }
+  delete[] b;
+  return rv;
+}
Index: /gsdl/stable/common-src/src/lib/md5.h
===================================================================
--- /gsdl/stable/common-src/src/lib/md5.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/md5.h	(revision 20131)
@@ -0,0 +1,25 @@
+#ifndef MD5_H
+#define MD5_H
+
+#include "text_t.h"
+
+#ifdef __alpha
+typedef unsigned int uint32;
+#else
+typedef unsigned long uint32;
+#endif
+
+struct MD5Context {
+  uint32 buf[4];
+  uint32 bits[2];
+  unsigned char in[64];
+};
+
+void MD5Init(MD5Context *ctx);
+void MD5Update(MD5Context *ctx, unsigned char *buf, unsigned int len);
+void MD5Final(unsigned char digest[16], MD5Context *ctx);
+void MD5Transform(uint32 buf[4], uint32 in[16]);
+
+text_t md5data(const text_t &data);
+
+#endif
Index: /gsdl/stable/common-src/src/lib/mssqldbclass.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/mssqldbclass.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/mssqldbclass.cpp	(revision 20131)
@@ -0,0 +1,499 @@
+/**********************************************************************
+ *
+ * mssqldbclass.cpp -- 
+ * Copyright (C) 2008  DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "mssqldbclass.h"
+#include "gsdlunicode.h"
+#include "unitool.h"
+#include "cfgread.h"
+#include <stdio.h>
+
+#ifdef __WIN32__
+// for Sleep
+#  include <windows.h>
+#else
+// for usleep
+#  include <unistd.h>
+#endif
+
+
+#define MSSQL_MAX_RETRIES 8
+
+
+mssqldbclass::mssqldbclass ()
+{
+  dbptr = NULL;
+  tableid = "";
+  debug = true;
+}
+
+
+mssqldbclass::~mssqldbclass ()
+{
+  closedatabase();
+}
+
+
+// returns true if opened
+bool mssqldbclass::opendatabase (const text_t &filename, int mode, int num_retrys, 
+#ifdef __WIN32__
+                                 bool need_filelock
+#else
+                                 bool
+#endif
+                                 )
+{
+  // Read the database information in from the .mssqldbinfo file
+  debug_output("MSSQL: Read in infodb file:[" + filename + "]\n");
+  text_tmap db_info_map = read_infodb_file(filename);
+  tableid = db_info_map["tableid"];
+  
+  // Initializing connection to MS-SQL
+  debug_output("MSSQL: Opening connection...\n");
+  CoInitialize(NULL);
+  char *db;
+  text_t constr = "Provider=SQLNCLI;DataTypeCompatibility=80;Server=" + db_info_map["mss-host"] + ";User ID=" + db_info_map["username"] + ";Password=" + db_info_map["password"] + ";Initial Catalog=" + db_info_map["database"] + ";AutoTranslate=on;";
+  db = constr.getcstr();
+  
+  // Handle the error when create connection instance failed
+  if (FAILED(dbptr.CreateInstance(__uuidof(Connection)))) 
+  {
+    cerr << "mssqldbclass::opendatabase(): CreateInstance failed." << endl;
+    return false;
+  }
+  
+  // Try to open the database, if it failed, output the error.
+  // Note, the error description is not really helpful, but you can google the
+  // error number and you can always find something helpful
+  try 
+  {
+    dbptr->Open(db, "", "", -1);
+  }
+  catch (_com_error &e)
+  {
+    text_t error;
+    error.setcstr(e.ErrorMessage());
+    cerr << "mssqldbclass::opendatabase(): Open failed (" << error << ")" << endl;
+  }
+  catch (...)
+  {
+    cerr << "mssqldbclass::opendatabase(): Open failed badly." << endl;
+  }
+
+  CoUninitialize();
+
+  return true;
+}
+
+
+void mssqldbclass::closedatabase ()
+{
+  // Close the database and catch any error if failed.
+  if (dbptr != NULL)
+  {
+    debug_output("MSSQL: Closing Database\n");
+    try 
+    {
+      dbptr->Close();
+    }
+    catch (_com_error &e)
+    {
+      text_t error;
+      error.setcstr(e.ErrorMessage());
+      cerr << "mssqldbclass::closedatabase(): Close failed (" << error << ")" << endl;
+    }
+    catch (...)
+    {
+      cerr << "mssqldbclass::closedatabase(): Close failed badly." << endl;
+    }
+    delete dbptr;
+    dbptr = NULL;
+  }
+}
+
+
+// Return the file extension for the mssql's info file
+text_t mssqldbclass::getfileextension ()
+{
+  return ".mssqldbinfo";
+}
+
+
+void mssqldbclass::deletekey (const text_t &key)
+{
+  text_t sql_cmd = "DELETE FROM data_" + tableid + " WHERE one_key=N'" + mssql_safe(key) + "'";
+  dbquery(sql_cmd);
+}
+
+
+// returns true on success
+bool mssqldbclass::getkeydata (const text_t& key, text_t &data)
+{
+  text_t sql_cmd = "SELECT one_value FROM data_" + tableid + " WHERE one_key=N'" + mssql_safe(key) + "'";
+  vector<text_tmap> sql_results;
+  if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
+  {
+    return false;
+  }
+  
+  text_tmap sql_result = sql_results[0];
+  data = sql_result["one_value"];
+  return true;
+}
+
+
+// returns array of keys
+text_tarray mssqldbclass::getkeys ()
+{
+  text_tarray keys;
+  
+  // Get all the entries in the "key" column of the table
+  text_t sql_cmd = "SELECT one_key FROM data_" + tableid;
+  vector<text_tmap> sql_results;
+  if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
+  {
+    return keys;
+  }
+  
+  // Iterate through the keys and add them to the array to be returned
+  vector<text_tmap>::iterator sql_results_iterator = sql_results.begin();
+  while (sql_results_iterator != sql_results.end())
+  {
+    text_tmap sql_result = (*sql_results_iterator);
+    keys.push_back(sql_result["one_key"]);
+    sql_results_iterator++;
+  }
+  
+  return keys;
+}
+
+
+// returns true on success
+bool mssqldbclass::setkeydata (const text_t &key, const text_t &data)
+{
+  // We need to do either an INSERT or UPDATE depending on whether the key already exists
+  if (!exists(key))
+  {
+    text_t sql_cmd = "INSERT INTO data_" + tableid + " (one_key, one_value) VALUES (N'" + mssql_safe(key) + "', N'" + mssql_safe(data) + "')";
+    return dbquery(sql_cmd);
+  }
+  else
+  {
+    text_t sql_cmd = "UPDATE data_" + tableid + " SET one_value='" + mssql_safe(data) + "' WHERE one_key=N'" + mssql_safe(key) + "'";
+    return dbquery(sql_cmd);
+  }
+}
+
+
+// returns array of document OIDs
+text_tarray mssqldbclass::get_documents_with_metadata_value (const text_tarray &metadata_element_names,
+                                                             const text_t &metadata_value,
+                                                             const text_t &sort_by_metadata_element_name)
+{
+  text_tarray document_OIDs;
+  
+  // Check at least one metadata element and a metadata value has been specified
+  if (metadata_element_names.empty() || metadata_value == "")
+  {
+    return document_OIDs;
+  }
+  
+  // Get the entries in the "document_metadata" table where the element and value matches those specified
+  text_t sql_cmd = "SELECT DISTINCT docOID FROM document_metadata_" + tableid + " WHERE element IN (N'" + mssql_safe(metadata_element_names[0]) + "'";
+  for (int i = 1; i < metadata_element_names.size(); i++)
+  {
+    sql_cmd += ",'" + mssql_safe(metadata_element_names[i]) + "'";
+  }
+  sql_cmd += ") AND value='" + mssql_safe(metadata_value) + "'";
+  
+  // If we're sorting the documents by a certain metadata element, extend the SQL command to do this
+  if (sort_by_metadata_element_name != "")
+  {
+    sql_cmd = "SELECT docOID FROM (" + sql_cmd + ") LEFT JOIN (SELECT docOID,value from document_metadata_" + tableid + " WHERE element=N'" + mssql_safe(sort_by_metadata_element_name) + "') USING (docOID) ORDER by value";
+  }
+  
+  // Perform the SQL request
+  vector<text_tmap> sql_results;
+  if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
+  {
+    return document_OIDs;
+  }
+  
+  // Iterate through the documents and add them to the array to be returned
+  vector<text_tmap>::iterator sql_results_iterator = sql_results.begin();
+  while (sql_results_iterator != sql_results.end())
+  {
+    text_tmap sql_result = (*sql_results_iterator);
+    document_OIDs.push_back(sql_result["docOID"]);
+    sql_results_iterator++;
+  }
+  
+  return document_OIDs;
+}
+
+
+// returns array of values
+text_tarray mssqldbclass::get_metadata_values (const text_tarray &metadata_element_names,
+                                               const text_t &metadata_value_filter,
+                                               const text_t &metadata_value_grouping_expression)
+{
+  text_tarray metadata_values;
+  
+  // Check at least one metadata element has been specified
+  if (metadata_element_names.empty())
+  {
+    return metadata_values;
+  }
+  
+  // Get the raw "value" field unless a grouping expression was provided (in this case an edited value is returned)
+  text_t value_select_expression = "value";
+  if (metadata_value_grouping_expression != "")
+  {
+    value_select_expression = metadata_value_grouping_expression;
+  }
+  
+  // Get the entries in the "document_metadata" table where the element matches that specified
+  text_t sql_cmd = "SELECT DISTINCT docOID," + value_select_expression + " FROM document_metadata_" + tableid + " WHERE element IN (N'" + mssql_safe(metadata_element_names[0]) + "'";
+  for (int i = 1; i < metadata_element_names.size(); i++)
+  {
+    sql_cmd += ",N'" + mssql_safe(metadata_element_names[i]) + "'";
+  }
+  sql_cmd += ")";
+    
+  // Add value filter, if one has been defined
+  if (metadata_value_filter != "")
+  {
+    sql_cmd += " AND value GLOB N'" + mssql_safe(metadata_value_filter) + "'";
+  }
+  
+  // Perform the SQL request
+  vector<text_tmap> sql_results;
+  if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
+  {
+    return metadata_values;
+  }
+    
+  // Iterate through the values and add them to the array to be returned
+  vector<text_tmap>::iterator sql_results_iterator = sql_results.begin();
+  while (sql_results_iterator != sql_results.end())
+  {
+    text_tmap sql_result = (*sql_results_iterator);
+    metadata_values.push_back(sql_result[value_select_expression]);
+    sql_results_iterator++;
+  }
+  
+  return metadata_values;
+}
+
+
+//-------------------------------------------------------------------------------------//
+// MS-SQL Private Utilities [START]
+//-------------------------------------------------------------------------------------//
+
+// dbquery(const text_t &sql)
+// Takes a sql statement and executes it
+// Returns false if failed, otherwise true
+bool mssqldbclass::dbquery (const text_t &sql)
+{
+  char *sql_c = sql.getcstr();
+  bool rv = true;
+  
+  // Creating the command instance
+  _CommandPtr cmd;
+  if (FAILED(cmd.CreateInstance(__uuidof(Command))))
+  {
+    cerr << "mssqldbclass::dbquery: CreateInstance failed" << endl;
+    return false;
+  }
+  
+  // Execute the sql statements and catch any error encountered
+  try 
+  {
+    cmd->ActiveConnection = dbptr;
+    cmd->CommandText = sql_c;
+    cmd->Execute(NULL, NULL, adCmdText);
+  }
+  catch (_com_error &e)
+  {
+    text_t error;
+    error.setcstr(e.ErrorMessage());
+    cerr << "mssqldbclass::dbquery: _com_error: (" << sql << ") : (" << error << ")" << endl;
+    rv = false;
+  }
+  catch (...)
+  {
+    cerr << "mssqldbclass::dbquery: unknown error: (" + sql + ")" << endl;
+    rv = false;
+  }
+
+  delete [] sql_c;
+  
+  return rv;
+}
+
+
+// sqlgetarray(const text_t &sql_cmd, vector<text_tmap> &sql_results)
+// Takes a sql statement and returns a vetor of result text_tmaps
+// Each map containing [field] => [value]. Note, all in text_t
+bool mssqldbclass::sqlgetarray (const text_t &sql_cmd,
+                                vector<text_tmap> &sql_results)
+{     
+  _RecordsetPtr rset;
+  bool result = false;
+  char *sql_c = sql_cmd.getcstr();
+  
+  // Create instance of the Recordset and die if failed
+  if (FAILED(rset.CreateInstance(__uuidof(Recordset))))
+  {
+    cerr << "mssqldbclass::sqlgetarray(): CreateInstance failed." << endl;
+    return false;
+  }
+  
+  // Do the query to the database - this can throw exceptions, hence
+  // the try...catch
+  try
+  {      
+    rset->Open(sql_c, dbptr.GetInterfacePtr(), adOpenStatic, adLockReadOnly, adCmdText);
+    
+    // There may have been no results found 
+    if (rset->RecordCount < 1)
+    {
+      debug_output("mssqldbclass::sqlgetarray(): No records found!\n");
+      return true; // Still want to return true even if there is no result found
+    }
+  
+    // Retrieve the informaton and place it into the sql_result map vector
+    // It will be array[["key"=>"values"]]
+    while(!rset->EndOfFile)
+    {
+      text_tmap rowmap;        
+      _variant_t index;
+      index.vt = VT_I2;
+      for (int i = 0; i < rset->Fields->Count; i++)
+      {
+        index.iVal = i;
+        text_t v = "";
+        text_t n = (char *)_bstr_t(rset->Fields->GetItem(index)->Name);
+        if (rset->Fields->GetItem(index)->Value.vt != VT_NULL)
+        {
+          v = convert_bstr_to_textt(rset->Fields->GetItem(index)->Value);
+        }
+        rowmap[n] = v;
+      }
+      sql_results.push_back(rowmap);
+      rset->MoveNext();
+    }
+    result = true;
+  }
+  catch (_com_error &e)
+  {
+    text_t error;
+    error.setcstr(e.ErrorMessage());
+    cerr << "mssqldbclass::sqlgetarray(): Error " << error << endl;
+    result = false;
+  }
+  catch (...)
+  {
+    cerr << "mssqldbclass::sqlgetarray(): Unknown Error" << endl;
+    result = false;
+  }
+
+  delete [] sql_c;
+
+  return result;  
+}
+
+
+text_t mssqldbclass::mssql_safe (const text_t &value_arg)
+{
+  text_t value = value_arg;
+  value.replace("'", "''");
+  return value;
+}
+
+
+// read_infodb_file(text_t filename)
+// Unlike the others (sqlite and gdbm), this is a server-client based database.
+// Therefore, instead of store the actual database, we store the infoserver-client based database.
+// What we want to do here is to have the 
+text_tmap mssqldbclass::read_infodb_file(text_t filename)
+{
+  text_tarray cfgline;
+  text_tmap dbinfo_hash;
+  
+  // Read in the infodb file
+  // It is the same format as all other config file
+  // Therefore let's reuse the confin code
+  char *infodb_cfgc = filename.getcstr();
+  ifstream confin(infodb_cfgc);    
+
+  // Read in the config and store it into the hash
+  if (confin)
+  {
+    while (read_cfg_line(confin, cfgline) >= 0)
+    {
+      if (cfgline.size() == 2)
+      {
+        dbinfo_hash[cfgline[0]] = cfgline[1];
+      }
+    }
+    confin.close();
+  }
+  delete []infodb_cfgc;
+  return dbinfo_hash;
+}
+
+
+void mssqldbclass::debug_output (text_t output_string)
+{
+  // Only ouput this when we want to see the debug message
+  if (debug)
+  {
+    cerr << output_string;
+  }
+}
+
+
+text_t mssqldbclass::convert_bstr_to_textt (_variant_t variant)
+{
+  text_t result = "";
+
+  // For some reasons Windows Server 2003 does not 
+  // allow _bstr_t to be casted to unsigned short* directly
+  // Therefore we need to convert it to wchar_t * then convert
+  // to unsigned short*
+  _bstr_t in = _bstr_t(variant);
+  wchar_t* temp_conv = (wchar_t*)in;
+  unsigned short* ints = (unsigned short*)temp_conv;
+  for (int i = 0 ; i < in.length() ; i++)
+  {     
+    result.push_back(ints[i]);
+  }
+  return result;
+}
+
+//-------------------------------------------------------------------------------------//
+// MS-SQL Private Utilities [END]
+//-------------------------------------------------------------------------------------//
+
Index: /gsdl/stable/common-src/src/lib/mssqldbclass.h
===================================================================
--- /gsdl/stable/common-src/src/lib/mssqldbclass.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/mssqldbclass.h	(revision 20131)
@@ -0,0 +1,94 @@
+/**********************************************************************
+ *
+ * mssqldbclass.h -- 
+ * Copyright (C) 2008  DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef MSSQLDBCLASS_H
+#define MSSQLDBCLASS_H
+
+
+#include "sqldbclass.h"
+//#import "C:\Program Files\Common Files\System\ADO\msado15.dll" no_namespace rename("EOF", "EndOfFile")
+#import "C:\Program Files\Common Files\System\ado\msado27.tlb" no_namespace rename("EOF", "EndOfFile")
+
+
+class mssqldbclass : public sqldbclass
+{
+ private:
+
+  _ConnectionPtr dbptr;
+
+  text_t tableid;
+  
+  // To enable the debug string to be output to cerr.
+  bool debug;
+  
+  text_tmap read_infodb_file (text_t filename);
+
+  void debug_output (text_t output_string);
+
+  text_t convert_bstr_to_textt (_variant_t in);
+
+  bool dbquery (const text_t &sql);
+
+  bool sqlgetarray (const text_t &sql_cmd, vector<text_tmap> &sql_results);
+
+  text_t mssql_safe (const text_t &value_arg);
+  
+ public:
+
+  mssqldbclass ();
+
+  ~mssqldbclass ();
+  
+  // returns true if opened
+  bool opendatabase (const text_t &filename, int mode, int num_retrys, bool need_filelock);
+  
+  void closedatabase ();
+  
+  void deletekey (const text_t &key);
+  
+  text_t getfileextension ();
+  
+  // returns true on success
+  bool getkeydata (const text_t& key, text_t &data);
+  
+  // returns array of keys
+  text_tarray getkeys ();
+  
+  // returns true on success
+  bool setkeydata (const text_t &key, const text_t &data);
+  
+  // returns array of document OIDs
+  text_tarray get_documents_with_metadata_value (const text_tarray &metadata_element_names,
+                                                 const text_t &metadata_value,
+                                                 const text_t &sort_by_metadata_element_name);
+  
+  // returns array of values
+  text_tarray get_metadata_values (const text_tarray &metadata_element_names,
+                                   const text_t &metadata_value_filter,
+                                   const text_t &metadata_value_grouping_expression);
+};
+
+
+#endif
Index: /gsdl/stable/common-src/src/lib/phrases.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/phrases.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/phrases.cpp	(revision 20131)
@@ -0,0 +1,66 @@
+/**********************************************************************
+ *
+ * phrases.cpp -- routines to do with phrases - want to share between colservr
+ * and recpt
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ *********************************************************************/
+
+#include "phrases.h"
+#include "unitool.h" // for is_unicode_letdig
+
+
+void get_phrases (const text_t &querystring, text_tarray &phrases) {
+
+  phrases.erase (phrases.begin(), phrases.end());
+  if (!querystring.empty()) {
+    
+    text_t::const_iterator end = querystring.end();
+    text_t::const_iterator here = findchar (querystring.begin(), end, '"');
+    if (here != end) {
+      text_t tmptext;
+      bool foundquote = false;
+      bool foundbreak = false;
+     while (here != end) {
+	if (*here == '"') {
+	  if (foundquote) {
+	    if (!tmptext.empty() && foundbreak) {
+	      phrases.push_back(tmptext);
+	    }
+	    tmptext.clear();
+	      
+	    foundquote = false;
+	    foundbreak = false;
+	  } else foundquote = true;
+	} else {
+	  if (foundquote) {
+	    if (!is_unicode_letdig(*here)) {
+	      foundbreak = true;
+	    }
+	    tmptext.push_back (*here);
+	  }
+	}
+	++here;
+     }
+    }
+  }
+}
Index: /gsdl/stable/common-src/src/lib/phrases.h
===================================================================
--- /gsdl/stable/common-src/src/lib/phrases.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/phrases.h	(revision 20131)
@@ -0,0 +1,36 @@
+/**********************************************************************
+ *
+ * phrases.h -- routines to do with phrases - want to share between colservr
+ * and recpt
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ *********************************************************************/
+
+#ifndef PHRASES_H
+#define PHRASES_H
+
+#include "text_t.h"
+
+void get_phrases (const text_t &querystring, text_tarray &phrases); 
+
+#endif /* PHRASES_H */
+
Index: /gsdl/stable/common-src/src/lib/sqldbclass.h
===================================================================
--- /gsdl/stable/common-src/src/lib/sqldbclass.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/sqldbclass.h	(revision 20131)
@@ -0,0 +1,56 @@
+/**********************************************************************
+ *
+ * sqldbclass.h -- 
+ * Copyright (C) 2008  DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef SQLDBCLASS_H
+#define SQLDBCLASS_H
+
+
+#include "dbclass.h"
+#include "text_t.h"
+
+
+class sqldbclass : public dbclass
+{
+public:
+  sqldbclass() {}
+  virtual ~sqldbclass() {}
+
+
+  // -----------------------------------------------------------------------------------------------
+  // These functions MUST be implemented by subclasses, as they are database-specific
+
+  // returns array of document OIDs
+  virtual text_tarray get_documents_with_metadata_value (const text_tarray &metadata_element_names,
+							 const text_t &metadata_value,
+							 const text_t &sort_by_metadata_element_name) = 0;
+
+  // returns array of values
+  virtual text_tarray get_metadata_values (const text_tarray &metadata_element_names,
+					   const text_t &metadata_value_filter,
+					   const text_t &metadata_value_grouping_expression) = 0;
+};
+
+
+#endif
Index: /gsdl/stable/common-src/src/lib/sqlitedbclass.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/sqlitedbclass.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/sqlitedbclass.cpp	(revision 20131)
@@ -0,0 +1,388 @@
+/**********************************************************************
+ *
+ * sqlitedbclass.cpp -- 
+ * Copyright (C) 2008  DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "sqlitedbclass.h"
+#include "gsdlunicode.h"
+#include "unitool.h"
+
+#ifdef __WIN32__
+// for Sleep
+#  include <windows.h>
+#else
+// for usleep
+#  include <unistd.h>
+#endif
+
+
+#define SQLITE_MAX_RETRIES 8
+
+
+sqlitedbclass::~sqlitedbclass()
+{
+  closedatabase();
+}
+
+
+// returns true if opened
+bool sqlitedbclass::opendatabase (const text_t &filename, int mode, int num_retrys, 
+#ifdef __WIN32__
+				  bool need_filelock
+#else
+				  bool
+#endif
+			      )
+{
+  // Check if we've already got the database open
+  if (sqlitefile != NULL)
+  {
+    if (openfile == filename) return true;
+    else closedatabase();
+  }
+
+  char *filename_cstr = filename.getcstr();
+  sqlite3_open(filename_cstr, &sqlitefile);
+  delete[] filename_cstr;
+
+  if (sqlitefile == NULL)
+  {
+    (*logout) << "ERROR: sqlitedbclass::opendatabase() failed on: " << filename << "\n";
+    return false;
+  }
+
+  if ((mode == DB_WRITER || mode == DB_WRITER_CREATE) && !sqltableexists("data"))
+  {
+    sqlexec("CREATE TABLE data (key TEXT, value TEXT, PRIMARY KEY(key))");
+  }
+
+  return true;
+}
+
+
+void sqlitedbclass::closedatabase ()
+{
+  if (sqlitefile == NULL) return;
+
+  sqlite3_close(sqlitefile);
+  sqlitefile = NULL;
+  openfile.clear();
+}
+
+
+void sqlitedbclass::deletekey (const text_t &key)
+{
+  text_t sql_cmd = "DELETE FROM data WHERE key='" + sqlite_safe(key) + "'";
+  sqlexec(sql_cmd);
+}
+
+
+// returns array of document OIDs
+text_tarray sqlitedbclass::get_documents_with_metadata_value (const text_tarray &metadata_element_names,
+							      const text_t &metadata_value,
+							      const text_t &sort_by_metadata_element_name)
+{
+  text_tarray document_OIDs;
+
+  // Check at least one metadata element and a metadata value has been specified
+  if (metadata_element_names.empty() || metadata_value == "")
+  {
+    return document_OIDs;
+  }
+
+  // Get the entries in the "document_metadata" table where the element and value matches those specified
+  text_t sql_cmd = "SELECT DISTINCT docOID FROM document_metadata WHERE element IN ('" + sqlite_safe(metadata_element_names[0]) + "'";
+  for (int i = 1; i < metadata_element_names.size(); i++)
+  {
+    sql_cmd += ",'" + sqlite_safe(metadata_element_names[i]) + "'";
+  }
+  sql_cmd += ") AND value='" + sqlite_safe(metadata_value) + "'";
+
+  // If we're sorting the documents by a certain metadata element, extend the SQL command to do this
+  if (sort_by_metadata_element_name != "")
+  {
+    sql_cmd = "SELECT docOID FROM (" + sql_cmd + ") LEFT JOIN (SELECT docOID,value from document_metadata WHERE element='" + sqlite_safe(sort_by_metadata_element_name) + "') USING (docOID) ORDER by value";
+  }
+
+  // Perform the SQL request
+  vector<text_tmap> sql_results;
+  if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
+  {
+    return document_OIDs;
+  }
+
+  // Iterate through the documents and add them to the array to be returned
+  vector<text_tmap>::iterator sql_results_iterator = sql_results.begin();
+  while (sql_results_iterator != sql_results.end())
+  {
+    text_tmap sql_result = (*sql_results_iterator);
+    document_OIDs.push_back(sql_result["docOID"]);
+    sql_results_iterator++;
+  }
+
+  return document_OIDs;
+}
+
+
+// returns file extension string
+text_t sqlitedbclass::getfileextension ()
+{
+  return ".db";
+}
+
+
+// returns true on success
+bool sqlitedbclass::getkeydata (const text_t& key, text_t &data)
+{
+  text_t sql_cmd = "SELECT value FROM data WHERE key='" + sqlite_safe(key) + "'";
+  vector<text_tmap> sql_results;
+  if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
+  {
+    return false;
+  }
+
+  text_tmap sql_result = sql_results[0];
+  data = sql_result["value"];
+  return true;
+}
+
+
+// returns array of keys
+text_tarray sqlitedbclass::getkeys ()
+{
+  text_tarray keys;
+
+  // Get all the entries in the "key" column of the table
+  text_t sql_cmd = "SELECT key FROM data";
+  vector<text_tmap> sql_results;
+  if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
+  {
+    return keys;
+  }
+
+  // Iterate through the keys and add them to the array to be returned
+  vector<text_tmap>::iterator sql_results_iterator = sql_results.begin();
+  while (sql_results_iterator != sql_results.end())
+  {
+    text_tmap sql_result = (*sql_results_iterator);
+    keys.push_back(sql_result["key"]);
+    sql_results_iterator++;
+  }
+
+  return keys;
+}
+
+
+// returns array of values
+text_tarray sqlitedbclass::get_metadata_values (const text_tarray &metadata_element_names,
+						const text_t &metadata_value_filter,
+						const text_t &metadata_value_grouping_expression)
+{
+  text_tarray metadata_values;
+
+  // Check at least one metadata element has been specified
+  if (metadata_element_names.empty())
+  {
+    return metadata_values;
+  }
+
+  // Get the raw "value" field unless a grouping expression was provided (in this case an edited value is returned)
+  text_t value_select_expression = "value";
+  if (metadata_value_grouping_expression != "")
+  {
+    value_select_expression = metadata_value_grouping_expression;
+  }
+
+  // Get the entries in the "document_metadata" table where the element matches that specified
+  text_t sql_cmd = "SELECT DISTINCT docOID," + value_select_expression + " FROM document_metadata WHERE element IN ('" + sqlite_safe(metadata_element_names[0]) + "'";
+  for (int i = 1; i < metadata_element_names.size(); i++)
+  {
+    sql_cmd += ",'" + sqlite_safe(metadata_element_names[i]) + "'";
+  }
+  sql_cmd += ")";
+
+  // Add value filter, if one has been defined
+  if (metadata_value_filter != "")
+  {
+    sql_cmd += " AND value GLOB '" + sqlite_safe(metadata_value_filter) + "'";
+  }
+
+  // Perform the SQL request
+  vector<text_tmap> sql_results;
+  if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
+  {
+    return metadata_values;
+  }
+
+  // Iterate through the values and add them to the array to be returned
+  vector<text_tmap>::iterator sql_results_iterator = sql_results.begin();
+  while (sql_results_iterator != sql_results.end())
+  {
+    text_tmap sql_result = (*sql_results_iterator);
+    metadata_values.push_back(sql_result[value_select_expression]);
+    sql_results_iterator++;
+  }
+
+  return metadata_values;
+}
+
+
+// returns true on success
+bool sqlitedbclass::setkeydata (const text_t &key, const text_t &data)
+{
+  // We need to do either an INSERT or UPDATE depending on whether the key already exists
+  if (!exists(key))
+  {
+    text_t sql_cmd = "INSERT INTO data (key, value) VALUES ('" + sqlite_safe(key) + "', '" + sqlite_safe(data) + "')";
+    return sqlexec(sql_cmd);
+  }
+  else
+  {
+    text_t sql_cmd = "UPDATE data SET value='" + sqlite_safe(data) + "' WHERE key='" + sqlite_safe(key) + "'";
+    return sqlexec(sql_cmd);
+  }
+}
+
+
+// ----------------------------------------------------------------------------------------
+//   SQLITE-ONLY FUNCTIONS
+// ----------------------------------------------------------------------------------------
+
+// sleep for the given number of milliseconds
+void sleep(int m)
+{
+#ifdef __WIN32__
+  Sleep(m);
+#else
+  usleep(m);
+#endif
+}
+
+
+text_t sqlitedbclass::sqlite_safe (const text_t &value_arg)
+{
+  text_t value = value_arg;
+  value.replace("'", "''");
+  return value;
+}
+
+
+// sqlexec simply executes the given sql statement - it doesn't obtain a
+// result set - returns true if the sql statement was executed successfully
+bool sqlitedbclass::sqlexec(const text_t &sql_cmd)
+{
+  if (sqlitefile == NULL) return false;
+
+  char *sql_cmd_cstr = sql_cmd.getcstr();
+
+  int rv = 0;
+  int tries = 0;
+  while ((rv = sqlite3_exec(sqlitefile, sql_cmd_cstr, NULL, NULL, NULL)) == SQLITE_BUSY)
+  {
+    sleep(1000);
+    tries++;
+    if (tries > SQLITE_MAX_RETRIES)
+    {
+      outconvertclass text_t2ascii;
+      (*logout) << text_t2ascii << "max_retries exceeded for sql query: " << sql_cmd << "\n";
+      break;
+    }
+  }
+
+  delete[] sql_cmd_cstr;
+
+  if (rv == SQLITE_OK) return true;
+
+  // sqlite3_exec failed - return false
+  outconvertclass text_t2ascii;
+  (*logout) << text_t2ascii << "Error executing sql statement: " << sql_cmd << "\n";
+  return false;
+}
+
+
+// callback functions for sqlgetarray
+static int sqlgetarray_callback(void *res, int numcols, char **vals, char **columnnames)
+{
+  vector<text_tmap> *result = (vector<text_tmap>*) res;
+  text_tmap row;
+
+  for (int i = 0; i < numcols; i++)
+  {
+    row[columnnames[i]] = "";
+    // vals[i] will be NULL if set to a NULL db value
+    if (vals[i])
+    {
+      row[columnnames[i]] = to_uni(vals[i]);
+    }
+  }
+
+  result->push_back(row);
+  return 0;
+}
+
+
+// sqlgetarray executes sql and returns the result set in sql_results
+bool sqlitedbclass::sqlgetarray(const text_t &sql_cmd, vector<text_tmap> &sql_results)
+{
+  if (sqlitefile == NULL) return false;
+
+  char *sql_cmd_cstr = sql_cmd.getcstr();
+  sql_results.erase(sql_results.begin(), sql_results.end());
+
+  int rv = 0;
+  int tries = 0;
+  while ((rv = sqlite3_exec(sqlitefile, sql_cmd_cstr, sqlgetarray_callback, &sql_results, NULL)) == SQLITE_BUSY)
+  {
+    sleep(1000);
+    tries++;
+    if (tries > SQLITE_MAX_RETRIES)
+    {
+      outconvertclass text_t2ascii;
+      (*logout) << text_t2ascii << "max_retries exceeded for sql query: " << sql_cmd << "\n";
+      break;
+    }
+  }
+
+  delete[] sql_cmd_cstr;
+
+  if (rv == SQLITE_OK) return true;
+
+  // sqlite3_exec failed - return empty result set
+  outconvertclass text_t2ascii;
+  (*logout) << text_t2ascii << "Error executing sql statement: " << sql_cmd << "\n";
+  return false;
+}
+
+
+// returns true if exists
+bool sqlitedbclass::sqltableexists(const text_t &table_name)
+{
+  text_t sql_cmd = "SELECT * FROM sqlite_master WHERE tbl_name='" + sqlite_safe(table_name) + "'";
+  vector<text_tmap> sql_results;
+  if (!sqlgetarray(sql_cmd, sql_results) || sql_results.size() == 0)
+  {
+    return false;
+  }
+
+  return true;
+}
Index: /gsdl/stable/common-src/src/lib/sqlitedbclass.h
===================================================================
--- /gsdl/stable/common-src/src/lib/sqlitedbclass.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/sqlitedbclass.h	(revision 20131)
@@ -0,0 +1,81 @@
+/**********************************************************************
+ *
+ * sqlitedbclass.h -- 
+ * Copyright (C) 2008  DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef SQLITEDBCLASS_H
+#define SQLITEDBCLASS_H
+
+
+#include "sqldbclass.h"
+#include "sqlite3.h"
+
+
+class sqlitedbclass : public sqldbclass
+{
+public:
+  sqlitedbclass() { sqlitefile = NULL; }
+  ~sqlitedbclass();
+
+  // returns true if opened
+  bool opendatabase (const text_t &filename, int mode, int num_retrys, bool need_filelock);
+
+  void closedatabase ();
+
+  void deletekey (const text_t &key);
+
+  // returns array of document OIDs
+  text_tarray get_documents_with_metadata_value (const text_tarray &metadata_element_names,
+						 const text_t &metadata_value,
+						 const text_t &sort_by_metadata_element_name);
+
+  // returns file extension string
+  text_t getfileextension ();
+
+  // returns true on success
+  bool getkeydata (const text_t& key, text_t &data);
+
+  // returns array of keys
+  text_tarray getkeys ();
+
+  // returns array of values
+  text_tarray get_metadata_values (const text_tarray &metadata_element_names,
+				   const text_t &metadata_value_filter,
+				   const text_t &metadata_value_grouping_expression);
+
+  // returns true on success
+  bool setkeydata (const text_t &key, const text_t &data);
+
+protected:
+  text_t openfile;
+  sqlite3* sqlitefile;
+
+  text_t sqlite_safe (const text_t &value_arg);
+
+  bool sqlexec (const text_t &sql_cmd);
+  bool sqlgetarray (const text_t &sql_cmd, vector<text_tmap> &sql_results);
+  bool sqltableexists (const text_t &table_name);
+};
+
+
+#endif
Index: /gsdl/stable/common-src/src/lib/text_t.cpp
===================================================================
--- /gsdl/stable/common-src/src/lib/text_t.cpp	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/text_t.cpp	(revision 20131)
@@ -0,0 +1,971 @@
+/**********************************************************************
+ *
+ * text_t.cpp -- a simple 16-bit character string class
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+#include "text_t.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\algorithm>
+#elif defined(GSDL_USE_STL_H)
+#  if defined(GSDL_USE_ALGO_H)
+#    include <algo.h>
+#  else
+#    include <algorithm.h>
+#  endif
+#else
+#  include <algorithm>
+#endif
+
+#ifdef HAVE_CONFIG_H
+# ifdef __WIN32__
+#  include "win32cfg.h"
+# else
+#  include "config.h"
+# endif
+#endif
+
+#include <cstring>
+
+#include "unitool.h"
+
+const text_t g_EmptyText("");
+
+////////////////////////////////////
+// text_t methods
+////////////////////////////////////
+
+// new stream converter ...
+ostream& operator<< (ostream &o, const text_t &text)
+{
+  text_t::const_iterator ithere = text.begin();
+  text_t::const_iterator itend = text.end();
+
+  while (ithere != itend)
+    {
+      if (*ithere < 256)
+	{
+	  o << (unsigned char)(*ithere);
+	}
+      else 
+	{
+	// put a space or a question mark depending on what
+	// the character is. Question marks tell the user that
+	// they are missing some information.
+	if (is_unicode_space (*ithere)) 
+	  o << ' ';
+	else 
+	  o << '?';
+      }
+      ++ithere;
+    }
+
+  return o;
+}
+
+text_t::text_t () 
+{
+  setencoding(0);
+  clear ();
+}
+
+text_t::text_t (int i) 
+{
+  setencoding(0);
+  clear ();
+  appendint (i);
+}
+
+text_t::text_t (const char *s) 
+{ 
+  setencoding(0);
+  clear ();
+  appendcstr (s);
+}
+
+text_t::text_t (const char *s, size_type nLength)
+{
+  setencoding(0);
+  clear ();
+  appendcarr(s, nLength);
+}
+
+
+void text_t::append (const text_t &t) 
+{
+  text.insert(text.end(), t.begin(), t.end());
+}
+
+void text_t::appendrange (iterator first, iterator last) 
+{
+  text.insert(text.end(), first, last);
+}
+
+void text_t::appendrange (const_iterator first, const_iterator last) 
+{
+  text.insert(text.end(), first, last);
+}
+
+void text_t::appendint (int i)
+{
+  // deal with zeros and negatives
+  if (i == 0) 
+    {
+      text.push_back('0');
+      return;
+    }
+  else if (i < 0)
+    {
+      text.push_back('-');
+      i *= -1;
+    }
+
+  // get a buffer for the conversion
+  int maxbuflen = sizeof(int)*3;
+  char *buf = new char[maxbuflen];
+  int len = 0;
+  
+  // get the number in reverse
+  while (i > 0)
+    {
+      buf[len++] = '0'+ (i%10);
+      i = i/10;
+    }
+
+  // reverse the number
+  while (len > 0)
+    {
+      text.push_back(buf[--len]);
+    }
+
+  delete []buf;
+}
+
+int text_t::getint () const
+{
+  int i = 0;
+  int mult = 1; // become -1 for negative numbers
+
+  const_iterator here = text.begin();
+  const_iterator end = text.end();
+  
+  // do plus and minus signs
+  if (here != end)
+    {
+      if (*here == '-')
+	{
+	  mult = -1;
+	  ++here;
+	}
+      else if (*here == '+')
+	{
+	  mult = 1;
+	  ++here;
+	}
+    }
+
+  // deal with the number
+  while ((here != end) && (*here >= '0') && (*here <= '9'))
+    {
+      i = 10*i + (*here - '0');
+      ++here;
+    }
+
+  i *= mult;
+  return i;
+}
+
+unsigned long text_t::getulong () const
+{
+  unsigned long i = 0;
+
+  const_iterator here = text.begin();
+  const_iterator end = text.end();
+
+  while ((here != end) && (*here >= '0') && (*here <= '9'))
+    {
+      i = 10*i + (*here - '0');
+      ++here;
+    }
+
+  return i;
+}
+
+void text_t::appendcarr (const char *s, size_type len)
+{
+  unsigned char *us = (unsigned char *)s;
+  if (text.capacity() < (text.size() + len + 2)) {
+    text.reserve(text.size() + len + 2);
+  }
+
+  while (len > 0) 
+    {
+      text.push_back (*us); // append this character
+      ++us;
+      --len;
+    }
+}
+
+void text_t::appendcstr (const char *s) 
+{
+  size_t len = strlen(s);
+  if (text.capacity() < (text.size() + len + 2)) {
+    text.reserve(text.size() + len + 2);
+  }
+  
+  unsigned char *us = (unsigned char *)s;
+  while (*us != '\0') 
+    {
+      text.push_back (*us); // append this character
+      ++us;
+    }
+}
+
+
+// strings returned from getcarr and getcstr become the callers 
+// responsibility and should be deallocated with "delete []"
+
+char *text_t::getcarr(size_type &len) const
+{
+  unsigned char *cstr = new unsigned char[size()];
+  len = 0;
+
+  const_iterator ithere = begin();
+  const_iterator itend = end();
+  while (ithere != itend)
+    {
+      if (*ithere < 256) cstr[len] = (unsigned char)(*ithere);
+      else {
+	// put a space or a question mark depending on what
+	// the character is. Question marks tell the user that
+	// they are missing some information.
+	if (is_unicode_space (*ithere)) cstr[len] = ' ';
+	else cstr[len] = '?';
+      }
+      ++len;
+      ++ithere;
+    }
+
+  return (char *)cstr;
+}
+
+char *text_t::getcstr() const
+{
+  unsigned char *cstr = new unsigned char[size() + 1];
+  const_iterator ithere = begin();
+  const_iterator itend = end();
+  int len = 0;
+
+  while (ithere != itend)
+    {
+      if (*ithere < 256) cstr[len] = (unsigned char)(*ithere);
+      else {
+	// put a space or a question mark depending on what
+	// the character is. Question marks tell the user that
+	// they are missing some information.
+	if (is_unicode_space (*ithere)) cstr[len] = ' ';
+	else cstr[len] = '?';
+      }
+      ++len;
+      ++ithere;
+    }
+
+  cstr[len] = '\0';
+
+  return (char *)cstr;
+}
+
+
+int text_t::replace(text_t toreplace, text_t replacement)
+{
+  // Get the beginning and end of the current text
+  text_t::iterator text_begin = text.begin(), text_end = text.end();
+  int count = 0;
+  text_t new_text, temp_text;
+
+  // Loop through and grab the text off the end
+  while (text_begin < text_end)
+  {
+    // Find where the next toreplace is
+    text_t::iterator next_toreplace = findword(text_begin, text_end, toreplace);
+
+    // We've found a match
+    if (next_toreplace != text_end)
+    {
+      new_text.append(substr(text_begin, next_toreplace));
+      new_text.append(replacement);
+      count++;
+      text_begin = next_toreplace + toreplace.size();
+    }
+    // We haven't found a match
+    else
+    {
+      new_text.append(substr(text_begin, text_end));
+      text_begin = text_end;
+    }
+  }
+
+  text.clear();
+  text = new_text.text_as_usvector();
+  return count;
+}
+
+
+// general functions which work on text_ts
+
+// find a character within a range
+text_t::const_iterator findchar (text_t::const_iterator first, text_t::const_iterator last, 
+				 unsigned short c)
+{
+  while (first != last)
+    {
+      if (*first == c) break;
+      ++first;
+    }
+  return first;
+}
+
+text_t::iterator findchar (text_t::iterator first, text_t::iterator last, 
+			   unsigned short c)
+{
+  while (first != last)
+    {
+      if (*first == c) break;
+      ++first;
+    }
+  return first;
+}
+
+text_t::iterator findlastchar (text_t::iterator first, text_t::iterator last_plus_one, 
+			   unsigned short c)
+{
+  text_t::iterator current = (last_plus_one != first) ? last_plus_one - 1 : first;
+  while (current != first) {
+    if (*current == c) break;
+    --current;
+  }
+  if (current == first) {
+    if (*current == c) return current;
+    return last_plus_one;
+  }
+
+  return current;
+}
+
+text_t::const_iterator findword (text_t::const_iterator first, 
+				 text_t::const_iterator last, 
+				 const text_t& word)
+{
+  text_t::const_iterator word_begin = word.begin();
+  text_t::const_iterator word_end = word.end();
+
+  while (first != last)
+    {
+      text_t::const_iterator char_match = first;
+      text_t::const_iterator word_here = word_begin;
+      while (word_here!=word_end)
+	{
+	  if (*char_match != *word_here)
+	    {
+	      break;
+	    }
+	  ++char_match;
+	  ++word_here;
+	}
+      if (word_here==word_end)
+	{
+	  return first;
+	}
+      ++first;
+    }
+  return last; // get to here only if there is no match
+}
+
+text_t::iterator findword (text_t::iterator first, 
+			   text_t::iterator last, 
+			   const text_t& word)
+{
+  text_t::const_iterator word_begin = word.begin();
+  text_t::const_iterator word_end = word.end();
+
+  while (first != last)
+    {
+      text_t::iterator char_match = first;
+      text_t::const_iterator word_here = word_begin;
+      while (word_here!=word_end)
+	{
+	  if (*char_match != *word_here)
+	    {
+	      break;
+	    }
+	  ++char_match;
+	  ++word_here;
+	}
+      if (word_here==word_end)
+	{
+	  return first;
+	}
+      ++first;
+    }
+  return last; // get to here only if there is no match
+}
+
+// get a string up to the next delimiter (which is skipped)
+text_t::const_iterator getdelimitstr (text_t::const_iterator first, 
+				      text_t::const_iterator last,
+				      unsigned short c, text_t &outstr)
+{
+  text_t::const_iterator here = first;
+  here = findchar (first, last, c);
+  outstr.clear();
+  outstr.appendrange (first, here);
+  if (here != last) ++here; // skip c
+  return here;
+}
+
+text_t::iterator getdelimitstr (text_t::iterator first, text_t::iterator last,
+				unsigned short c, text_t &outstr)
+{
+  text_t::iterator here = first;
+  here = findchar (first, last, c);
+  outstr.clear();
+  outstr.appendrange (first, here);
+  if (here != last) ++here; // skip c
+  return here;
+}
+
+text_t::const_iterator getdelimitstr (text_t::const_iterator first, text_t::const_iterator last,
+				      text_t w, text_t &outstr)
+{
+  text_t::const_iterator here = first;
+  here = findword (first, last, w);
+  outstr.clear();
+  outstr.appendrange (first, here);
+  if (here != last) here += w.size(); // skip w
+  return here;
+}
+
+// split a string with a character
+void splitchar (text_t::const_iterator first, text_t::const_iterator last,
+		unsigned short c, text_tset &outlist)
+{
+  outlist.erase(outlist.begin(), outlist.end());
+
+  text_t t;
+
+  while (first != last)
+    {
+      first = getdelimitstr (first, last, c, t);
+      outlist.insert (t);
+    }
+}
+
+void splitchar (text_t::const_iterator first, text_t::const_iterator last,
+		unsigned short c, text_tlist &outlist)
+{
+  outlist.erase(outlist.begin(), outlist.end());
+
+  text_t t;
+
+  while (first != last)
+    {
+      first = getdelimitstr (first, last, c, t);
+      outlist.push_back (t);
+    }
+}
+
+void splitchar (text_t::const_iterator first, text_t::const_iterator last,
+		unsigned short c, text_tarray &outlist)
+{
+  outlist.erase(outlist.begin(), outlist.end());
+
+  text_t t;
+
+  while (first != last)
+    {
+      first = getdelimitstr (first, last, c, t);
+      outlist.push_back (t);
+    }
+}
+
+void splitword (text_t::const_iterator first, text_t::const_iterator last,
+		text_t w, text_tlist &outlist)
+{
+  outlist.erase(outlist.begin(), outlist.end());
+
+  text_t t;
+
+  while (first != last)
+    {
+      first = getdelimitstr (first, last, w, t);
+      outlist.push_back (t);
+    }
+}
+
+// join a string using a character
+void joinchar (const text_tset &inlist, unsigned short c, text_t &outtext)
+{
+  outtext.clear ();
+
+  text_tset::const_iterator here = inlist.begin ();
+  text_tset::const_iterator end = inlist.end ();
+
+  if (here != end) {
+    outtext += *here; ++here;
+    while (here != end) {
+      outtext.push_back (c);
+      outtext += *here;
+      ++here;
+    }
+  }
+}
+
+void joinchar (const text_tlist &inlist, unsigned short c, text_t &outtext)
+{
+  outtext.clear ();
+
+  text_tlist::const_iterator here = inlist.begin ();
+  text_tlist::const_iterator end = inlist.end ();
+  if (here != end) {
+    outtext += *here; ++here;
+    while (here != end) {
+      outtext.push_back (c);
+      outtext += *here;
+      ++here;
+    }
+  }
+}
+
+void joinchar (const text_tarray &inlist, unsigned short c, text_t &outtext)
+{
+  outtext.clear ();
+
+  text_tarray::const_iterator here = inlist.begin ();
+  text_tarray::const_iterator end = inlist.end ();
+  if (here != end) {
+    outtext += *here; ++here;
+    while (here != end) {
+      outtext.push_back (c);
+      outtext += *here;
+      ++here;
+    }
+  }
+}
+
+void joinchar (const text_tlist &inlist, const text_t &c, text_t &outtext)
+{
+  outtext.clear ();
+
+  text_tlist::const_iterator here = inlist.begin ();
+  text_tlist::const_iterator end = inlist.end ();
+  if (here != end) {
+    outtext += *here; ++here;
+    while (here != end) {
+      outtext += c;
+      outtext += *here;
+      ++here;
+    }
+  }
+}
+
+void joinchar (const text_tset &inlist, const text_t &c, text_t &outtext)
+{
+  outtext.clear ();
+
+  text_tset::const_iterator here = inlist.begin ();
+  text_tset::const_iterator end = inlist.end ();
+  if (here != end) {
+    outtext += *here; ++here;
+    while (here != end) {
+      outtext += c;
+      outtext += *here;
+      ++here;
+    }
+  }
+}
+
+void joinchar (const text_tarray &inlist, const text_t &c, text_t &outtext)
+{
+  outtext.clear ();
+
+  text_tarray::const_iterator here = inlist.begin ();
+  text_tarray::const_iterator end = inlist.end ();
+  if (here != end) {
+    outtext += *here; ++here;
+    while (here != end) {
+      outtext += c;
+      outtext += *here;
+      ++here;
+    }
+  }
+}
+
+// count the occurances of a character within a range
+int countchar (text_t::const_iterator first, text_t::const_iterator last,
+	       unsigned short c)
+{
+  int count = 0;
+  while (first != last) {
+    if (*first == c) ++count;
+    ++first;
+  }
+  return count;
+}
+
+// return a substring of string from first up to but not including last
+text_t substr (text_t::const_iterator first, text_t::const_iterator last) {
+
+  text_t substr; substr.reserve(last - first + 2);
+  while (first != last) {
+    substr.push_back(*first);
+    ++first;
+  }
+  return substr;
+}
+
+
+// convert to lowercase
+void lc (text_t::iterator first, text_t::iterator last) {
+  while (first != last) {
+    *first = unicode_tolower(*first);
+    ++first;
+  }
+}
+
+// convert to uppercase
+void uc (text_t::iterator first, text_t::iterator last) {
+  while (first != last) {
+    *first = unicode_toupper(*first);
+    ++first;
+  }
+}
+
+
+// checks to see if it is a number (i.e. contains only 0-9)
+bool is_number (const text_t &text) {
+
+  text_t::const_iterator here = text.begin();
+  text_t::const_iterator end = text.end();
+
+  while (here != end) {
+    if ((*here!='0') && (*here!='1') && (*here!='2') &&
+	(*here!='3') && (*here!='4') && (*here!='5') &&
+	(*here!='6') && (*here!='7') && (*here!='8') &&
+	(*here!='9')) return false;
+    ++here;
+  }
+  return true;
+}
+
+
+// checks to see if the text has any letters or digits
+bool has_unicode_letdig (const text_t &text) {
+  if (text.empty()) return false;
+  
+  text_t::const_iterator here = text.begin();
+  text_t::const_iterator end = text.end();
+  while (here != end) {
+    if (is_unicode_letdig (*here)) return true;
+    ++here;
+  }
+
+  return false;
+}
+
+// checks to see if a text_t starts with the specified prefix
+bool starts_with(const text_t& text, const text_t& prefix) {
+  if (prefix.empty()) return true;
+  if (text.empty() || text.size()<prefix.size()) return false;
+  text_t substring = substr(text.begin(), text.begin()+prefix.size());
+  return substring == prefix;
+}
+// checks to see if a text_t ends with the specified suffix
+bool ends_with(const text_t& text, const text_t& suffix) {
+  if (suffix.empty()) return true;
+  if (text.empty() || text.size() < suffix.size()) return false;
+  text_t substring = substr(text.end()-suffix.size(),text.end());
+  return substring == suffix;
+
+}
+
+
+////////////////////////////////////
+// convertclass methods
+////////////////////////////////////
+
+// conversion classes used for getting information in to and out of
+// the text_t class.
+
+convertclass::convertclass () 
+{
+  // nothing to do
+}
+
+void convertclass::reset ()
+{
+  // nothing to do
+}
+
+
+////////////////////////////////////
+// inconvertclass methods
+////////////////////////////////////
+
+// convert from a char stream to the text_t class
+// the default version assumes the input is a ascii
+// character array
+
+inconvertclass::inconvertclass () 
+{
+  start = NULL;
+  len = 0;
+}
+
+
+void inconvertclass::reset ()
+{
+  start = NULL;
+  len = 0;
+}
+
+void inconvertclass::setinput (char *thestart, size_t thelen)
+{
+  start = thestart;
+  len = thelen;
+}
+
+void inconvertclass::convert (text_t &output, status_t &status)
+{
+  output.clear();
+
+  if (start == NULL || len == 0)
+    {
+      status = finished;
+      return;
+    }
+
+  if (output.capacity() < len + 2)
+    output.reserve(len + 2);
+  
+  // don't want any funny sign conversions happening
+  unsigned char *here = (unsigned char *)start;
+  while (len > 0) 
+    {
+      output.push_back (*here); // append this character
+      ++here;
+      --len;
+    }
+
+  start = (char *)here; // save current position
+  status = finished;
+}
+
+// will treat the text_t as a 8-bit string and convert
+// it to a 16-bit string using the about convert method.
+text_t inconvertclass::convert (const text_t &t) {
+  text_t out;
+  text_t tmpout;
+  status_t status;
+  text_t::const_iterator here = t.begin();
+  text_t::const_iterator end = t.end();
+  unsigned char cbuf[256];
+  size_t cbuflen = 0;
+ 
+  out.clear();
+  if (out.capacity() < t.size() + 2)
+    out.reserve(t.size() + 2);
+  while (here != end) {
+    while (here != end && cbuflen < 256) {
+      cbuf[cbuflen++] = (unsigned char)(*here & 0xff);
+      ++here;
+    }
+
+    if (cbuflen > 0) {
+      setinput ((char *)cbuf, cbuflen);
+      status = unfinished;
+      while (status == unfinished) {
+	convert (tmpout, status);
+	out += tmpout;
+      }
+      cbuflen = 0;
+    }
+  }
+
+  out.setencoding (0); // unicode
+
+  return out;
+}
+
+// an instance of the default inconvertclass to do simple
+// conversions. Note that any functions that use this are
+// not reentrant. If a function needs to be reentrant it
+// should declare its own instance.
+inconvertclass ascii2text_t;
+
+
+////////////////////////////////////
+// outconvertclass methods
+////////////////////////////////////
+
+// Convert from a text_t class to a char stream
+// This default version assumes the output is a ascii
+// character array. If you set the output stream you
+// can use this class to output to a stream using the
+// << operator. The << operator can also be conveniently
+// used to set the output stream by doing something like
+//
+// cout << text_t2ascii << text_tstr << anothertext_tstr;
+//
+outconvertclass::outconvertclass ()
+{
+  input = NULL;
+  outs = NULL;
+}
+
+void outconvertclass::reset ()
+{
+  input = NULL;
+  outs = NULL;
+}
+
+void outconvertclass::setinput (text_t *theinput)
+{
+  input = theinput;
+  if (input != NULL) texthere = input->begin();
+}
+
+void outconvertclass::setdata(text_t *theinput, text_t::iterator thetexthere)
+{
+  input = theinput;     
+  texthere = thetexthere;
+}
+ 
+void outconvertclass::convert (char *output, size_t maxlen, 
+		      size_t &len, status_t &status)
+{
+  if (input == NULL || output == NULL)
+    {
+      status = finished;
+      return;
+    }
+
+  // don't want any funny sign conversions happening
+  unsigned char *uoutput = (unsigned char *)output;
+  text_t::iterator textend = input->end();
+  len = 0;
+  while ((len < maxlen) && (texthere != textend)) 
+    {
+      if (*texthere < 256) *uoutput = (unsigned char)(*texthere);
+      else {
+	// put a space or a question mark depending on what
+	// the character is. Question marks tell the user that
+	// they are missing some information.
+	if (is_unicode_space (*texthere)) *uoutput = ' ';
+	else *uoutput = '?';
+      }
+      ++uoutput;
+      ++len;
+      ++texthere;
+    }
+  
+  if (texthere == textend) status = finished;
+  else status = unfinished;
+}
+
+// will convert the 16-bit string to a 8-bit stream
+// and place the result in a text_t. This method uses
+// the above convert function.
+text_t outconvertclass::convert (const text_t &t) {
+  text_t out;
+  unsigned char cbuf[256];
+  size_t cbuflen = 0;
+  status_t status = unfinished;
+  
+  out.clear(); 
+  if (out.capacity() < t.size() + 2)
+    out.reserve(t.size() + 2);
+  setinput ((text_t *)&t); // discard constant
+  while (status == unfinished) {
+    convert ((char *)cbuf, 256, cbuflen, status);
+    out.appendcarr ((char *)cbuf, cbuflen);
+  }
+
+  out.setencoding (1); // other encoding
+  
+  return out;
+}
+
+
+void outconvertclass::setostream (ostream *theouts)
+{
+  outs = theouts;
+}
+
+ostream *outconvertclass::getostream ()
+{
+  return outs;
+}
+
+
+
+
+// an instance of the default outconvertclass to do simple
+// conversions
+outconvertclass text_t2ascii;
+
+
+
+// stream operators for the output class
+
+outconvertclass &operator<< (ostream &theouts, outconvertclass &outconverter)
+{
+  outconverter.setostream(&theouts);
+  return outconverter;
+}
+
+
+#define STREAMBUFSIZE 256
+outconvertclass &operator<< (outconvertclass &outconverter, const text_t &t)
+{
+  ostream *outstream = outconverter.getostream();
+
+  if (outstream == NULL) return outconverter;
+
+  char outbuf[STREAMBUFSIZE];
+  size_t len;
+  outconvertclass::status_t status = outconvertclass::unfinished;
+
+  // assume that there is no data needing converting
+  // left in the converter
+  outconverter.setinput ((text_t *)(&t)); // note the const -> nonconst conversion
+
+  while (status == outconvertclass::unfinished)
+    {
+      outconverter.convert (outbuf, STREAMBUFSIZE, len, status);
+      if (len > 0) outstream->write(outbuf, len);
+    }
+
+  return outconverter;
+}
Index: /gsdl/stable/common-src/src/lib/text_t.h
===================================================================
--- /gsdl/stable/common-src/src/lib/text_t.h	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/text_t.h	(revision 20131)
@@ -0,0 +1,387 @@
+/**********************************************************************
+ *
+ * text_t.h -- a simple 16-bit character string class
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+
+#ifndef TEXT_T_H
+#define TEXT_T_H
+
+#include "gsdlconf.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\vector>
+#  include <ospace\std\list>
+#  include <ospace\std\set>
+#  include <ospace\std\map>
+#elif defined(GSDL_USE_STL_H)
+#  include <vector.h>
+#  include <list.h>
+#  include <set.h>
+#  include <map.h>
+#else
+#  include <vector>
+#  include <list>
+#  include <set>
+#  include <map>
+#endif
+#include <string>
+
+// use the standard namespace
+#if !defined (GSDL_NAMESPACE_BROKEN)
+#if defined(GSDL_USE_OBJECTSPACE)
+using namespace ospace::std;
+#else
+using namespace std;
+#endif
+#endif
+
+// class prototypes
+class text_t;
+class inconvertclass;
+class outconvertclass;
+
+
+// for those stupid compilers which need it
+#if defined(GSDL_NEED_DESTROY_USHORT)
+inline void destroy(unsigned short *) {};
+inline void destroy(int *) {};
+#endif
+
+typedef vector<unsigned short> usvector;
+extern const text_t g_EmptyText;
+
+// The class text_t can handle long strings which may contain
+// null characters. It uses unsigned shorts to represent up to
+// 64K character values.
+class text_t {
+  public:
+  //type support for ucvector
+  typedef usvector::iterator iterator;
+  typedef usvector::const_iterator const_iterator;
+  typedef usvector::reference reference;
+  typedef usvector::const_reference const_reference;
+  typedef usvector::size_type size_type;
+  typedef usvector::difference_type difference_type;
+  typedef usvector::const_reverse_iterator const_reverse_iterator;
+  typedef usvector::reverse_iterator reverse_iterator;
+  
+protected:
+  usvector text;
+  unsigned short encoding; // 0 = unicode, 1 = other
+  
+public:
+  // constructors
+  text_t ();
+  text_t (int i);
+  text_t (const char *s); // assumed to be a normal c string
+  text_t (const char *s, size_type nLength); // support for arrays of chars
+  void setencoding (unsigned short theencoding) {encoding=theencoding;};
+  unsigned short getencoding () {return encoding;};
+
+  usvector& text_as_usvector() { return text ; };
+  const usvector& text_as_usvector() const { return text ; };
+
+  // basic container support
+  iterator begin () {return text.begin();}
+  const_iterator begin () const {return text.begin();}
+  iterator end () {return text.end();}
+  const_iterator end () const {return text.end();}
+
+  void erase(iterator pos) {text.erase(pos);}
+  void erase(iterator first, iterator last) {text.erase(first, last);}
+  void push_back(unsigned short c) {text.push_back(c);}
+  void pop_back() {text.pop_back();}
+  text_t &operator=(const text_t &x) {text=x.text; encoding=x.encoding; return *this;}
+  reference operator[](size_type n) {return text[n];};
+  const_reference operator[](size_type n) const {return text[n];};
+
+  void reserve (size_type n) {text.reserve(n);}
+  size_type capacity() const { return text.capacity(); }
+  
+  bool empty () const {return text.empty();}
+  size_type size() const {return text.size();}
+  friend inline bool operator!=(const text_t& x, const text_t& y)
+	{return (x.text != y.text);}
+  friend inline bool operator==(const text_t& x, const text_t& y) 
+	{return (x.text == y.text);}
+  friend inline bool operator<(const text_t& x, const text_t& y) 
+	{return (x.text < y.text);}
+  friend inline bool operator>(const text_t& x, const text_t& y) 
+	{return (x.text > y.text);}
+  friend inline bool operator>=(const text_t& x, const text_t& y) 
+	{return (x.text >= y.text);}
+  friend inline bool operator<=(const text_t& x, const text_t& y) 
+	{return (x.text <= y.text);}
+  
+  // added functionality
+  void clear () {text.erase(text.begin(),text.end());}
+  void append (const text_t &t);
+  void appendrange (iterator first, iterator last);
+  void appendrange (const_iterator first, const_iterator last);
+  text_t &operator+= (const text_t &t) {append(t);return *this;}
+
+  // support for integers
+  void appendint (int i);
+  void setint (int i) {clear();appendint(i);}
+  text_t &operator=(int i) {setint (i);return *this;}
+  text_t &operator+= (int i) {appendint(i);return *this;}
+  int getint () const;
+
+  // same as getint but returns an unsigned long
+  unsigned long getulong () const;
+
+  // support for arrays of chars
+  void appendcarr (const char *s, size_type len);
+  void setcarr (char *s, size_type len) {clear();appendcarr(s,len);}
+
+  // support for const null-terminated C strings
+  void appendcstr (const char *s);
+  void setcstr (const char *s) {clear();appendcstr(s);}
+  text_t &operator= (const char *s) {setcstr(s);return *this;} // c string
+  text_t &operator+= (const char *s) {appendcstr(s);return *this;} // c string
+
+  // strings returned from getcarr and getcstr become the callers 
+  // responsibility and should be deallocated with "delete []"
+  char *getcarr(size_type &len) const;
+  char *getcstr() const;
+
+  int replace(text_t toreplace, text_t replacement);
+};
+
+// new stream converter ...
+ostream& operator<< (ostream &o, const text_t &text);
+
+inline text_t operator+(const text_t &t1, const text_t &t2)
+{
+  text_t tnew = t1;
+  tnew.append(t2);
+  return tnew;
+}
+
+inline text_t operator+(const text_t &t1, int i1)
+{
+  text_t tnew = t1;
+  tnew.appendint(i1);
+  return tnew;
+}
+
+inline text_t operator+(const text_t &t1, char *s1)
+{
+  text_t tnew = t1;
+  tnew.appendcstr(s1);
+  return tnew;
+}
+
+
+
+
+struct eqtext_t 
+{
+  bool operator()(const text_t &t1, const text_t &t2) const
+  { return t1 == t2; }
+};
+
+struct lttext_t 
+{
+  bool operator()(const text_t &t1, const text_t &t2) const
+  { return t1 < t2; }
+};
+
+
+// frequently used derived types
+typedef set<text_t,lttext_t> text_tset;
+typedef list<text_t> text_tlist;  // more efficient for insertions/deletions
+typedef vector<text_t> text_tarray; // more space efficient than text_tlist
+typedef map<text_t, text_t, lttext_t> text_tmap;
+
+
+// general functions which work on text_ts
+
+// find a character within a range
+text_t::const_iterator findchar (text_t::const_iterator first, text_t::const_iterator last, 
+				 unsigned short c);
+text_t::iterator findchar (text_t::iterator first, text_t::iterator last, 
+			   unsigned short c);
+// Find the last occurrence of c between first and last_plus_one -1. Returns last_plus_one if not found.
+text_t::iterator findlastchar (text_t::iterator first, text_t::iterator last_plus_one, 
+			       unsigned short c);
+text_t::iterator findword (text_t::iterator first, text_t::iterator last,
+			   const text_t &word);
+text_t::const_iterator findword (text_t::const_iterator first, text_t::const_iterator last, 
+				 const text_t& word);
+
+// get a string up to the next delimiter (which is skipped)
+text_t::const_iterator getdelimitstr (text_t::const_iterator first, 
+				      text_t::const_iterator last,
+				      unsigned short c, text_t &outstr);
+text_t::iterator getdelimitstr (text_t::iterator first, text_t::iterator last,
+				unsigned short c, text_t &outstr);
+
+text_t::const_iterator getdelimitstr (text_t::const_iterator first, text_t::const_iterator last,
+				      text_t w, text_t &outstr);
+
+// split a string with a character
+void splitchar (text_t::const_iterator first, text_t::const_iterator last,
+		unsigned short c, text_tset &outlist);
+void splitchar (text_t::const_iterator first, text_t::const_iterator last,
+		unsigned short c, text_tlist &outlist);
+void splitchar (text_t::const_iterator first, text_t::const_iterator last,
+		unsigned short c, text_tarray &outlist);
+
+void splitword (text_t::const_iterator first, text_t::const_iterator last,
+		text_t w, text_tlist &outlist);
+
+// join a string using a character
+void joinchar (const text_tset &inlist, unsigned short c, text_t &outtext);
+void joinchar (const text_tlist &inlist, unsigned short c, text_t &outtext);
+void joinchar (const text_tarray &inlist, unsigned short c, text_t &outtext);
+void joinchar (const text_tset &inlist, const text_t &c, text_t &outtext);
+void joinchar (const text_tlist &inlist, const text_t &c, text_t &outtext);
+void joinchar (const text_tarray &inlist, const text_t &c, text_t &outtext);
+
+// count the occurances of a character within a range
+int countchar (text_t::const_iterator first, text_t::const_iterator last,
+	       unsigned short c);
+
+// return a substring of string from first up to but not including last
+text_t substr (text_t::const_iterator first, text_t::const_iterator last);
+
+// convert to lowercase
+void lc (text_t::iterator first, text_t::iterator last);
+inline void lc (text_t &t) {lc (t.begin(), t.end());}
+
+// convert to uppercase
+void uc (text_t::iterator first, text_t::iterator last);
+inline void uc (text_t &t) {uc (t.begin(), t.end());}
+
+// checks to see if it is a number (i.e. contains only 0-9)
+bool is_number (const text_t &text);
+
+// checks to see if the text has any letters or digits
+bool has_unicode_letdig (const text_t &text);
+
+// checks to see if a text_t starts with the specified prefix
+bool starts_with(const text_t& text, const text_t& prefix);
+// checks to see if a text_t ends with the specified suffix
+bool ends_with(const text_t& text, const text_t& suffix);
+
+// conversion classes used for getting information in to and out of
+// the text_t class.
+
+class convertclass 
+{
+public:
+  enum status_t {finished, stopped, unfinished};
+  
+  convertclass ();
+  virtual void reset ();
+};
+
+
+
+// convert from a char stream to the text_t class
+// the default version assumes the input is a ascii
+// character array
+class inconvertclass : public convertclass
+{
+public:
+  inconvertclass ();
+  void reset ();
+  void setinput (char *thestart, size_t thelen);
+
+  // output will be cleared before the conversion
+  virtual void convert (text_t &output, status_t &status);
+
+  // will treat the text_t as a 8-bit string and convert
+  // it to a 16-bit string using the about convert method.
+  text_t convert (const text_t &t);
+
+protected:
+  char *start;
+  size_t len;
+};
+
+// to get something which will do the conversion
+// to ascii declare a (non global!) instance like
+// this
+// inconvertclass ascii2text_t;
+
+#if defined(GSDL_USE_IOS_H)
+#include <iostream.h> // darwin doesn't have ostream.h...
+#else
+#include <ostream>
+#endif
+
+// Convert from a text_t class to a char stream
+// This default version assumes the output is a ascii
+// character array. If you set the output stream you
+// can use this class to output to a stream using the
+// << operator. The << operator can also be conveniently
+// used to set the output stream by doing something like
+//
+// cout << text_t2ascii << textstr << anothertextstr;
+//
+// this class assumes that the input text doesn't change
+// while the conversion takes place
+class outconvertclass : public convertclass
+{
+public:
+  outconvertclass ();
+  virtual void reset ();
+  virtual void setinput (text_t *theinput);
+  virtual void setdata(text_t *input, text_t::iterator texthere);
+  // note that convert does not null-terminate the
+  // output array of characters
+  virtual void convert (char *output, size_t maxlen, 
+			size_t &len, status_t &status);
+
+  // will convert the 16-bit string to a 8-bit stream
+  // and place the result in a text_t. This method uses
+  // the above convert function.
+  text_t convert (const text_t &t);
+
+  virtual void setostream (ostream *theouts);
+  ostream *getostream ();
+
+protected:
+  text_t *input;
+  text_t::iterator texthere; // only valid if input is valid
+
+  ostream *outs;
+};
+
+// to get something which will do the conversion
+// to text_t declare a (non global!) instance like
+// this
+// outconvertclass text_t2ascii;
+
+
+// stream operators for the output class
+outconvertclass &operator<< (ostream &theouts, outconvertclass &outconverter);
+outconvertclass &operator<< (outconvertclass &outconverter, const text_t &t);
+
+
+#endif
Index: /gsdl/stable/common-src/src/lib/win32.mak
===================================================================
--- /gsdl/stable/common-src/src/lib/win32.mak	(revision 20131)
+++ /gsdl/stable/common-src/src/lib/win32.mak	(revision 20131)
@@ -0,0 +1,166 @@
+###########################################################################
+#
+# win32 makefile -- lib
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+COMMON_DIR = ..\..
+
+INDEXERS_DIR = $(COMMON_DIR)\indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)\packages
+
+
+GSDL_VC4 = 0
+LOCAL_LIBRARY = 0
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+USE_SQLITE = 1
+USE_MSSQL = 0
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+!IF $(DLL)
+CXXFLAGS = $(CXXFLAGS) -MD
+!ELSE
+!IF ($(DLLDEBUG))
+CXXFLAGS = $(CXXFLAGS) -MDd
+!ENDIF
+!ENDIF
+
+!IF $(USE_MSSQL)
+MSSQL_OBJECTS = mssqldbclass.obj
+MSSQL_SOURCES = mssqldbclass.cpp
+!ELSE
+MSSQL_OBJECTS = 
+MSSQL_SOURCES =
+!ENDIF
+
+!IF $(USE_SQLITE)
+SQLITE_INCLUDES = -I"$(COMMON_PACKAGES_DIR)\sqlite\include"
+SQLITE_OBJECTS = sqlitedbclass.obj
+SQLITE_SOURCES = sqlitedbclass.cpp
+!ELSE
+SQLITE_INCLUDES = 
+SQLITE_OBJECTS = 
+SQLITE_SOURCES = 
+!ENDIF
+
+
+AR = lib
+CC = cl
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H -DPARADOCNUM -D_LITTLE_ENDIAN -DSHORT_SUFFIX -D_CRT_SECURE_NO_DEPRECATE
+INCLUDES = -I"$(COMMON_DIR)" -I"$(INDEXERS_DIR)\mg\lib" \
+	-I"$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3" -I"$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3\windows" \
+	$(SQLITE_INCLUDES)
+
+!IF $(GSDL_VC4)
+DEFS = $(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I"$(COMMON_PACKAGES_DIR)\windows\stlport\stlport"
+!ENDIF
+!IF $(LOCAL_LIBRARY)
+DEFS = $(DEFS) -DGSDL_LOCAL_LIBRARY
+!ENDIF
+
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $< 
+
+
+SOURCES = \
+	cfgread.cpp \
+	cnfgable.cpp \
+	cnfgator.cpp \
+	dbclass.cpp \
+	display.cpp \
+	fileutil.cpp \
+	gdbmclass.cpp \
+	gsdlsitecfg.cpp \
+	gsdltimes.cpp \
+	gsdltools.cpp \
+	gsdlunicode.cpp \
+	infodbclass.cpp \
+	md5.cpp \
+	OIDtools.cpp \
+	phrases.cpp \
+	text_t.cpp \
+	$(SQLITE_SOURCES) \
+	$(MSSQL_SOURCES)
+
+OBJECTS = \
+	cfgread.obj \
+	cnfgable.obj \
+	cnfgator.obj \
+	dbclass.obj \
+	display.obj \
+	fileutil.obj \
+	gdbmclass.obj \
+	gsdlsitecfg.obj \
+	gsdltimes.obj \
+	gsdltools.obj \
+	gsdlunicode.obj \
+	infodbclass.obj \
+	md5.obj \
+	OIDtools.obj \
+	phrases.obj \
+	text_t.obj \
+	$(SQLITE_OBJECTS) \
+        $(MSSQL_OBJECTS)
+
+LIBRARY = gsdllib.lib	
+
+
+# Default target: make gsdllib.lib
+all: $(LIBRARY)
+
+gsdllib.lib : $(OBJECTS)
+	if EXIST $(LIBRARY) del $(LIBRARY)
+	$(AR) -nologo /out:$(LIBRARY) $(OBJECTS)
+
+install:
+
+clean:
+	del *.obj 
+	del $(LIBRARY)
+
+
+# Always recompile gsdltools in case GSDL_LOCAL_LIBRARY has changed
+gsdltools.obj: FORCE
+
+FORCE:
Index: /gsdl/stable/common-src/win32.mak
===================================================================
--- /gsdl/stable/common-src/win32.mak	(revision 20131)
+++ /gsdl/stable/common-src/win32.mak	(revision 20131)
@@ -0,0 +1,185 @@
+###########################################################################
+#
+# win32 makefile -- common code between gsdl runtime and buildtime
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+!IF "$(GSDLHOME)"==""
+GSDLHOME = $(MAKEDIR)
+!ELSE
+GSDLHOME = $(GSDLHOME)
+!ENDIF
+COMMONHOME = $(MAKEDIR)
+GSDL_VC4 = 0
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+USE_SQLITE = 1
+USE_MSSQL = 0
+
+MDEFINES = /f win32.mak
+
+INDEXERSDIR = indexers
+
+COMPILEDIRS = packages\windows\crypt\crypt packages\gdbm\gdbm-1.8.3 \
+	      packages\windows\expat\expat packages\search4j src\lib 
+
+INSTALLDIRS = src\gdbmedit\db2txt src\gdbmedit\txt2db \
+    src\gdbmedit\gdbmset src\gdbmedit\gdbmget \
+    src\gdbmedit\gdbmkeys src\gdbmedit\gdbmdel 
+
+#    src\getpw
+
+PACKAGEDIRS = 
+
+SQLITE_DIR = packages\sqlite\sqlite-amalgamation-3.5.9
+
+MAKECMD = $(MAKE) $(MDEFINES) GSDLHOME="$(GSDLHOME)" BINDIR="$(GSDLHOME)\bin\windows"
+
+!IF $(GSDL_VC4)
+MAKECMD = $(MAKECMD) GSDL_VC4=1
+!ENDIF
+!IF $(DEBUG)
+MAKECMD = $(MAKECMD) DEBUG=1
+!ENDIF
+!IF $(DLL)
+MAKECMD = $(MAKECMD) DLL=1
+!ENDIF
+!IF $(DLLDEBUG)
+MAKECMD = $(MAKECMD) DLLDEBUG=1
+!ENDIF
+!IF $(USE_SQLITE)
+MAKECMD = $(MAKECMD) USE_SQLITE=1
+PACKAGEDIRS = $(PACKAGEDIRS) $(SQLITE_DIR)
+!ENDIF
+!IF $(USE_MSSQL)
+MAKECMD = $(MAKECMD) USE_MSSQL=1
+!ENDIF
+
+MAKECLEANCMD = $(MAKE) $(MDEFINES) GSDLHOME="$(GSDLHOME)" clean
+
+all: win32.mak unzip $(INDEXERSDIR) $(PACKAGEDIRS) $(COMPILEDIRS) $(INSTALLDIRS) 
+
+install: win32.mak $(INDEXERSDIR) $(INSTALLDIRS)
+
+unzip:
+	cd "$(COMMONHOME)"
+	cd packages\windows\crypt
+	if NOT EXIST "crypt" unzip crypt.zip
+	cd "$(COMMONHOME)"
+	cd packages\windows\expat
+	if NOT EXIST "expat" unzip expat.zip
+	cd "$(COMMONHOME)"
+	cd indexers\packages\windows\iconv
+	if NOT EXIST "iconv" unzip iconv.zip
+	cd "$(COMMONHOME)"
+	IF NOT EXIST $(SQLITE_DIR) IF EXIST "$(GSDLHOME)\bin\windows\gunzip.exe" IF EXIST "$(GSDLHOME)\bin\windows\tar.exe" "$(GSDLHOME)\bin\windows\gunzip.exe" -cd "$(SQLITE_DIR).tar.gz" | "$(GSDLHOME)\bin\windows\tar.exe" xv --directory=./packages/sqlite
+	IF NOT EXIST $(SQLITE_DIR) echo ****** Couldn't extract archive $(SQLITE_DIR).tar.gz. Extract it manually, or check that gunzip.exe and tar.exe exist in GSDLHOME\bin\windows. ******
+
+clean:
+	cd "$(COMMONHOME)"
+	cd packages\windows\crypt\crypt
+	$(MAKECLEANCMD)
+	cd "$(COMMONHOME)"
+	cd packages\gdbm\gdbm-1.8.3
+	$(MAKECLEANCMD)
+	cd "$(COMMONHOME)"
+	cd packages\windows\expat\expat
+	$(MAKECLEANCMD)
+	cd "$(COMMONHOME)"
+	cd src\lib
+	$(MAKECLEANCMD)
+	cd "$(COMMONHOME)"
+	cd src\gdbmedit\txt2db
+	$(MAKECLEANCMD)
+	cd "$(COMMONHOME)"
+	cd src\gdbmedit\db2txt
+	$(MAKECLEANCMD)
+	cd "$(COMMONHOME)"
+	cd src\gdbmedit\gdbmget
+	$(MAKECLEANCMD)
+	cd "$(COMMONHOME)"
+	cd src\gdbmedit\gdbmset
+	$(MAKECLEANCMD)
+	cd "$(COMMONHOME)"
+	cd src\gdbmedit\gdbmkeys
+	$(MAKECLEANCMD)
+	cd "$(COMMONHOME)"
+	cd src\gdbmedit\gdbmdel
+	$(MAKECLEANCMD)
+#	cd "$(COMMONHOME)"
+#	cd src\getpw
+#	$(MAKECLEANCMD)
+	cd "$(COMMONHOME)"
+	cd indexers
+	call winMake.bat clean
+	cd "$(COMMONHOME)"
+	cd packages\search4j
+	$(MAKECLEANCMD)
+!IF $(USE_SQLITE)
+	cd "$(COMMONHOME)"
+	cd "$(SQLITE_DIR)"
+	$(MAKECLEANCMD)
+!ENDIF
+	cd "$(COMMONHOME)"
+
+$(COMPILEDIRS): FORCE
+	cd "$(COMMONHOME)"
+	cd "$@"
+	$(MAKECMD)
+	cd "$(GSDLHOME)"
+
+$(INSTALLDIRS): FORCE
+	cd "$(COMMONHOME)"
+	cd "$@"
+	$(MAKECMD)
+	$(MAKECMD) install
+	cd "$(COMMONHOME)"
+
+$(SQLITE_DIR): FORCE
+	cd "$(COMMONHOME)"
+	cd "$@"
+	$(MAKECMD)
+	$(MAKECMD) install
+	cd "$(COMMONHOME)"
+
+$(INDEXERSDIR): FORCE
+	cd "$(COMMONHOME)"
+	cd "$@"
+	set DEBUG=$(DEBUG)
+	if EXIST "$(GSDLHOME)\runtime-src" call winMake.bat all gs2 
+	if EXIST "$(GSDLHOME)\runtime-src" call winMake.bat install gs2
+	if NOT EXIST "$(GSDLHOME)\runtime-src" call winMake.bat all
+	if NOT EXIST "$(GSDLHOME)\runtime-src" call winMake.bat install
+
+	set DEBUG=
+	if NOT EXIST "$(GSDLHOME)\bin\windows" mkdir "$(GSDLHOME)\bin\windows"
+	if NOT EXIST "$(GSDLHOME)\bin\java" mkdir "$(GSDLHOME)\bin\java"
+	for %%i in (bin\*.exe) do \
+	  copy %%i "$(GSDLHOME)\bin\windows"
+	if EXIST "lucene-gs\LuceneWrapper.jar" copy "lucene-gs\LuceneWrapper.jar" "$(GSDLHOME)\bin\java"
+	@if NOT EXIST "lucene-gs\LuceneWrapper.jar" echo Warning: Failed to find lucene-gs\LuceneWrapper.jar.  Greenstone will not be able to use Lucene for indexing
+	cd "$(GSDLHOME)"
+
+FORCE:
+
Index: /gsdl/stable/common-src/win32cfg.h
===================================================================
--- /gsdl/stable/common-src/win32cfg.h	(revision 20131)
+++ /gsdl/stable/common-src/win32cfg.h	(revision 20131)
@@ -0,0 +1,169 @@
+/* config.h.  Generated automatically by configure.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+/* #undef _ALL_SOURCE */
+#endif
+
+/* Define if using alloca.c.  */
+/* #undef C_ALLOCA */
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define if you have alloca, as a function or macro.  */
+#define HAVE_ALLOCA 1
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+/* #define HAVE_ALLOCA_H 1 */
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+/* #undef HAVE_DOPRNT */
+
+/* Define if you have the vprintf function.  */
+#define HAVE_VPRINTF 1
+
+/* Define if on MINIX.  */
+/* #undef _MINIX */
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+/* #undef off_t */
+
+/* Define if the system does not provide POSIX.1 features except
+   with this defined.  */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define if you need to in order for stat and other things to work.  */
+/* #undef _POSIX_SOURCE */
+
+/* Define as the return type of signal handlers (int or void).  */
+#define RETSIGTYPE void
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+/* #define TIME_WITH_SYS_TIME 1 */
+
+/* Define if your <sys/time.h> declares struct tm.  */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define to the name of the distribution.  */
+#define PACKAGE "mg"
+
+/* Define to the version of the distribution.  */
+#define VERSION "1.2"
+
+/* Define to 1 if you have the valloc function.  */
+/* #define HAVE_VALLOC 1 */
+
+/* Define to 1 if ANSI function prototypes are usable.  */
+#define PROTOTYPES 1
+
+ 
+/* Define to 1 for better use of the debugging malloc library.  See
+   site ftp.antaire.com in antaire/src, file dmalloc/dmalloc.tar.gz.  */
+/* #undef WITH_DMALLOC */
+
+ 
+/* Define to 1 if GNU regex should be used instead of GNU rx.  */
+/* #undef WITH_REGEX */
+
+/* Some braindead header files do not have the requ'd function declarations */
+#define HAVE_FGETC_DECL 1
+#define HAVE_FREAD_DECL 1
+
+/* See if have this field in the prstatus_t structure */
+/* It stores the size of the process heap */
+/* #define HAVE_PR_BRKSIZE 1 */
+
+/* Define if you have the ftime function.  */
+/* #undef HAVE_FTIME */
+
+/* Define if you have the getpagesize function.  */
+/* #undef HAVE_GETPAGESIZE */
+
+/* Define if you have the getrusage function.  */
+/* #undef HAVE_GETRUSAGE */
+
+/* Define if you have the mallinfo function.  */
+/* #undef HAVE_MALLINFO */
+
+/* Define if you have the select function.  */
+#define HAVE_SELECT 1
+
+/* Define if you have the setbuffer function.  */
+/* #undef HAVE_SETBUFFER */
+
+/* Define if you have the strerror function.  */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strftime function.  */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the strstr function.  */
+#define HAVE_STRSTR 1
+
+/* Define if you have the strtol function.  */
+#define HAVE_STRTOL 1
+
+/* Define if you have the times function.  */
+/* #define HAVE_TIMES 1 */
+
+/* Define if you have the valloc function.  */
+/* #define HAVE_VALLOC 1 */
+
+/* Define if you have the <dirent.h> header file.  */
+/* #define HAVE_DIRENT_H 1 */
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <limits.h> header file.  */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <memory.h> header file.  */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <ndir.h> header file.  */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <string.h> header file.  */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/dir.h> header file.  */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/ndir.h> header file.  */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <sys/procfs.h> header file.  */
+/* #define HAVE_SYS_PROCFS_H 1 */
+
+/* Define if you have the <sys/time.h> header file.  */
+/* #define HAVE_SYS_TIME_H 1 */
+
+/* Define if you have the <unistd.h> header file.  */
+/* #define HAVE_UNISTD_H 1 */
+
+/* Define if you have the m library (-lm).  */
+#define HAVE_LIBM 1
Index: /gsdl/stable/config.guess
===================================================================
--- /gsdl/stable/config.guess	(revision 20131)
+++ /gsdl/stable/config.guess	(revision 20131)
@@ -0,0 +1,1298 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-07-12'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int dummy(){}" > $dummy.c ;
+	for c in cc gcc c89 ; do
+	  ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
+	  if test $? = 0 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	rm -f $dummy.c $dummy.o $dummy.rel ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# Netbsd (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	# Determine the machine/vendor (is the vendor relevant).
+	case "${UNAME_MACHINE}" in
+	    amiga) machine=m68k-unknown ;;
+	    arm32) machine=arm-unknown ;;
+	    atari*) machine=m68k-atari ;;
+	    sun3*) machine=m68k-sun ;;
+	    mac68k) machine=m68k-apple ;;
+	    macppc) machine=powerpc-apple ;;
+	    hp3[0-9][05]) machine=m68k-hp ;;
+	    ibmrt|romp-ibm) machine=romp-ibm ;;
+	    *) machine=${UNAME_MACHINE}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE}" in
+	    i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	cat <<EOF >$dummy.s
+	.data
+\$Lformat:
+	.byte 37,100,45,37,120,10,0	# "%d-%x\n"
+
+	.text
+	.globl main
+	.align 4
+	.ent main
+main:
+	.frame \$30,16,\$26,0
+	ldgp \$29,0(\$27)
+	.prologue 1
+	.long 0x47e03d80 # implver \$0
+	lda \$2,-1
+	.long 0x47e20c21 # amask \$2,\$1
+	lda \$16,\$Lformat
+	mov \$0,\$17
+	not \$1,\$18
+	jsr \$26,printf
+	ldgp \$29,0(\$26)
+	mov 0,\$16
+	jsr \$26,exit
+	.end main
+EOF
+	eval $set_cc_for_build
+	$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+	if test "$?" = 0 ; then
+		case `./$dummy` in
+			0-0)
+				UNAME_MACHINE="alpha"
+				;;
+			1-0)
+				UNAME_MACHINE="alphaev5"
+				;;
+			1-1)
+				UNAME_MACHINE="alphaev56"
+				;;
+			1-101)
+				UNAME_MACHINE="alphapca56"
+				;;
+			2-303)
+				UNAME_MACHINE="alphaev6"
+				;;
+			2-307)
+				UNAME_MACHINE="alphaev67"
+				;;
+		esac
+	fi
+	rm -f $dummy.s $dummy
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    arc64:OpenBSD:*:*)
+	echo mips64el-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hkmips:OpenBSD:*:*)
+	echo mips-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mips-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    sun3*:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	eval $set_cc_for_build
+	$CC_FOR_BUILD $dummy.c -o $dummy \
+	  && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && rm -f $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		eval $set_cc_for_build
+		$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+		rm -f $dummy.c $dummy
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+              case "${HPUX_REV}" in
+                11.[0-9][0-9])
+                  if [ -x /usr/bin/getconf ]; then
+                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+                        esac ;;
+                    esac
+                  fi ;;
+              esac
+              if [ "${HP_ARCH}" = "" ]; then
+              sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+	eval $set_cc_for_build
+	(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+	if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+	rm -f $dummy.c $dummy
+	fi ;;
+	esac
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	eval $set_cc_for_build
+	$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    hppa*:OpenBSD:*:*)
+	echo hppa-unknown-openbsd
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+	echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3D:*:*:*)
+	echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY-2:*:*:*)
+	echo cray2-cray-unicos
+        exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i386-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
+	  big)    echo mips-unknown-linux-gnu && exit 0 ;;
+	  little) echo mipsel-unknown-linux-gnu && exit 0 ;;
+	esac
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev67 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	ld_supported_targets=`cd /; ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;		
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-pc-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-pc-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+	eval $set_cc_for_build
+	$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
+	rm -f $dummy.c $dummy
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	echo `uname -p`-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	if test "${UNAME_MACHINE}" = "x86pc"; then
+		UNAME_MACHINE=pc
+	fi
+	echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-[KW]:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+eval $set_cc_for_build
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
Index: /gsdl/stable/config.h.in
===================================================================
--- /gsdl/stable/config.h.in	(revision 20131)
+++ /gsdl/stable/config.h.in	(revision 20131)
@@ -0,0 +1,217 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+#ifndef _GSDL_CONFIG_H
+#define _GSDL_CONFIG_H
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+#undef _ALL_SOURCE
+#endif
+
+/* Define if using alloca.c.  */
+#undef C_ALLOCA
+
+/* Define if big endian */
+#undef WORDS_BIGENDIAN
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro.  */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+#undef HAVE_ALLOCA_H
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+#undef HAVE_DOPRNT
+
+/* Define if you have the vprintf function.  */
+#undef HAVE_VPRINTF
+
+/* Define if on MINIX.  */
+#undef _MINIX
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+#undef off_t
+
+/* Define if the system does not provide POSIX.1 features except
+   with this defined.  */
+#undef _POSIX_1_SOURCE
+
+/* Define if you need to in order for stat and other things to work.  */
+#undef _POSIX_SOURCE
+
+/* Define as the return type of signal handlers (int or void).  */
+#undef RETSIGTYPE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm.  */
+#undef TM_IN_SYS_TIME
+
+/* Define to the name of the distribution.  */
+#undef PACKAGE
+
+/* Define to the version of the distribution.  */
+#undef VERSION
+
+/* Define to 1 if you have the valloc function.  */
+#undef HAVE_VALLOC
+
+/* Define to 1 if ANSI function prototypes are usable.  */
+#undef PROTOTYPES
+
+/* Define if you don't want to use long long's with GCC */
+#undef DISABLE_LONG_LONG
+ 
+/* Define to 1 for better use of the debugging malloc library.  See
+   site ftp.antaire.com in antaire/src, file dmalloc/dmalloc.tar.gz.  */
+#undef WITH_DMALLOC
+
+ 
+/* Define to 1 if GNU regex should be used instead of GNU rx.  */
+#undef WITH_REGEX
+
+/* Some braindead header files do not have the requ'd function declarations */
+#undef HAVE_FGETC_DECL
+#undef HAVE_FREAD_DECL
+
+/* See if have this field in the prstatus_t structure */
+/* It stores the size of the process heap */
+#undef HAVE_PR_BRKSIZE
+
+/* Define FASTCGI if needsbe */
+#undef USE_FASTCGI
+
+/* Define USE_CORBA if needsbe */
+#undef USE_CORBA
+
+/* Define MICO_DIR if needsbe */
+#undef MICO_DIR
+
+/* Define MICO_VERSION if required */
+#undef MICO_VERSION
+
+/* Define if you have the ftime function.  */
+#undef HAVE_FTIME
+
+/* Define if you have the ftruncate function.  */
+#undef HAVE_FTRUNCATE
+
+/* Define if you have the getpagesize function.  */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the getrusage function.  */
+#undef HAVE_GETRUSAGE
+
+/* Define if you have the mallinfo function.  */
+#undef HAVE_MALLINFO
+
+/* Define if you have the select function.  */
+#undef HAVE_SELECT
+
+/* Define if you have the setbuffer function.  */
+#undef HAVE_SETBUFFER
+
+/* Define if you have the strcasecmp function.  */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strerror function.  */
+#undef HAVE_STRERROR
+
+/* Define if you have the strftime function.  */
+#undef HAVE_STRFTIME
+
+/* Define if you have the strstr function.  */
+#undef HAVE_STRSTR
+
+/* Define if you have the strtol function.  */
+#undef HAVE_STRTOL
+
+/* Define if you have the times function.  */
+#undef HAVE_TIMES
+
+/* Define if you have the valloc function.  */
+#undef HAVE_VALLOC
+
+/* Define if you have the <crypt.h> header file.  */
+#undef HAVE_CRYPT_H
+
+/* Define if you have the <dirent.h> header file.  */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <fcntl.h> header file.  */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <limits.h> header file.  */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <memory.h> header file.  */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <ndir.h> header file.  */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <string.h> header file.  */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/dir.h> header file.  */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/ndir.h> header file.  */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/procfs.h> header file.  */
+#undef HAVE_SYS_PROCFS_H
+
+/* Define if you have the <sys/time.h> header file.  */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <unistd.h> header file.  */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the crypt library (-lcrypt).  */
+#undef HAVE_LIBCRYPT
+
+/* Define if you have the g library (-lg).  */
+#undef HAVE_LIBG
+
+/* Define if you have the gdbm library (-lgdbm).  */
+#undef HAVE_LIBGDBM
+
+/* Define if you have the m library (-lm).  */
+#undef HAVE_LIBM
+
+/* Define if you have the stdc++ library (-lstdc++).  */
+#undef HAVE_LIBSTDC__
+
+/* Define if you have gettext (eg glibc) */
+#undef ENABLE_NLS
+
+/* Define if big endian */
+#undef WORDS_BIGENDIAN
+
+#endif /* _GSDL_CONFIG_H */
Index: /gsdl/stable/config.sub
===================================================================
--- /gsdl/stable/config.sub	(revision 20131)
+++ /gsdl/stable/config.sub	(revision 20131)
@@ -0,0 +1,1375 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-06-08'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
+	        | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
+		| pyramid | mn10200 | mn10300 | tron | a29k \
+		| 580 | i960 | h8300 \
+		| x86 | ppcbe | mipsbe | mipsle | shbe | shle \
+		| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+		| hppa64 \
+		| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
+		| alphaev6[78] \
+		| we32k | ns16k | clipper | i370 | sh | sh[34] \
+		| powerpc | powerpcle \
+		| 1750a | dsp16xx | pdp10 | pdp11 \
+		| mips16 | mips64 | mipsel | mips64el \
+		| mips64orion | mips64orionel | mipstx39 | mipstx39el \
+		| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+		| mips64vr5000 | mips64vr5000el | mcore | s390 | s390x \
+		| sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
+		| v850 | c4x \
+		| thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
+		| pj | pjl | h8500 | z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	# FIXME: clean up the formatting here.
+	vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
+	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
+	      | arm-*  | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
+	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+	      | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+	      | xmp-* | ymp-* \
+	      | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
+	      | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
+	      | hppa2.0n-* | hppa64-* \
+	      | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
+	      | alphaev6[78]-* \
+	      | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+	      | clipper-* | orion-* \
+	      | sparclite-* | pdp10-* | pdp11-* | sh-* | sh[34]-* | sh[34]eb-* \
+	      | powerpc-* | powerpcle-* | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
+	      | mips16-* | mips64-* | mipsel-* \
+	      | mips64el-* | mips64orion-* | mips64orionel-* \
+	      | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+	      | mipstx39-* | mipstx39el-* | mcore-* \
+	      | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
+	      | [cjt]90-* \
+	      | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+	      | thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
+	      | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	cray2)
+		basic_machine=cray2-cray
+		os=-unicos
+		;;
+	[cjt]90)
+		basic_machine=${basic_machine}-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mipsel*-linux*)
+		basic_machine=mipsel-unknown
+		os=-linux-gnu
+		;;
+	mips*-linux*)
+		basic_machine=mips-unknown
+		os=-linux-gnu
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	mmix*)
+		basic_machine=mmix-knuth
+		os=-mmixware
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+        pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2)
+		basic_machine=i686-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+	        ;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+	        ;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sparclite-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=t3e-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	windows32)
+		basic_machine=i386-pc
+		os=-windows32-msvcrt
+		;;
+	xmp)
+		basic_machine=xmp-cray
+		os=-unicos
+		;;
+        xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	mips)
+		if [ x$os = x-linux-gnu ]; then
+			basic_machine=mips-unknown
+		else
+			basic_machine=mips-mips
+		fi
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+        cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	c4x*)
+		basic_machine=c4x-none
+		os=-coff
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto*)
+		os=-nto-qnx
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-ns2 )
+	        os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+	        os=-mint
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	pdp10-*)
+		os=-tops20
+		;;
+        pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+        *-gould)
+		os=-sysv
+		;;
+        *-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+        *-sgi)
+		os=-irix
+		;;
+        *-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-vxsim* | -vxworks*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
Index: /gsdl/stable/configtest.pl
===================================================================
--- /gsdl/stable/configtest.pl	(revision 20131)
+++ /gsdl/stable/configtest.pl	(revision 20131)
@@ -0,0 +1,1 @@
+print $]
Index: /gsdl/stable/configure
===================================================================
--- /gsdl/stable/configure	(revision 20131)
+++ /gsdl/stable/configure	(revision 20131)
@@ -0,0 +1,8644 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subdirs_all="$ac_subdirs_all common-src build-src runtime-src"
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS PACKAGE VERSION USE_FASTCGI USE_LANGACTION USE_CORBA MICO_DIR USE_Z3950 USE_YAZ ENABLE_ACCENTFOLD USE_SQLITE USE_APACHE_HTTPD LDFLAGS CFLAGS CC CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX AWK YACC build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB COMPAT32BITFLAGS MICO_VER CPP EGREP U ANSI2KNR ALLOCA LIBOBJS STATIC gsdlos MODULEDIRS subdirs LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CXX_set=${CXX+set}
+ac_env_CXX_value=$CXX
+ac_cv_env_CXX_set=${CXX+set}
+ac_cv_env_CXX_value=$CXX
+ac_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_env_CXXFLAGS_value=$CXXFLAGS
+ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_cv_env_CXXFLAGS_value=$CXXFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-corba          Enable CORBA support
+  --enable-z3950          Enable Z39.50 client support
+  --disable-yaz           Disable YAZ compilation
+  --disable-accentfold    Disable Accent Folding for MGPP
+  --disable-sqlite        Disable SQLite support
+  --disable-apache-httpd  Disable Apache httpd support
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-micodir          Use installed MICO directory
+  --with-dmalloc          use dmalloc, as in
+                          ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz
+  --with-regex            use older regex in lieu of GNU rx for matching
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers config.h"
+
+
+PACKAGE=gsdl
+VERSION=2.82-svn
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+
+
+
+
+USE_FASTCGI=0
+if test USE_FASTCGI = 1; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_FASTCGI 1
+_ACEOF
+
+
+fi
+
+if test USE_LANGACTION = 1; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_LANGACTION 1
+_ACEOF
+
+
+fi
+
+# Check whether --enable-corba or --disable-corba was given.
+if test "${enable_corba+set}" = set; then
+  enableval="$enable_corba"
+  USE_CORBA=1
+else
+  USE_CORBA=0
+fi;
+cat >>confdefs.h <<_ACEOF
+#define USE_CORBA $USE_CORBA
+_ACEOF
+
+
+
+
+# Check whether --with-micodir or --without-micodir was given.
+if test "${with_micodir+set}" = set; then
+  withval="$with_micodir"
+  MICO_DIR=$enableval
+else
+  MICO_DIR="default"
+fi;
+cat >>confdefs.h <<_ACEOF
+#define MICO_DIR "$MICO_DIR"
+_ACEOF
+
+
+
+# Check whether --enable-z3950 or --disable-z3950 was given.
+if test "${enable_z3950+set}" = set; then
+  enableval="$enable_z3950"
+  USE_Z3950=1
+else
+  USE_Z3950=0
+fi;
+if test USE_Z3950 = 1; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_Z3950 $USE_Z3950
+_ACEOF
+
+
+fi
+
+# Check whether --enable-yaz or --disable-yaz was given.
+if test "${enable_yaz+set}" = set; then
+  enableval="$enable_yaz"
+  USE_YAZ=0
+else
+  USE_YAZ=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define USE_YAZ $USE_YAZ
+_ACEOF
+
+
+
+# Check whether --enable-accentfold or --disable-accentfold was given.
+if test "${enable_accentfold+set}" = set; then
+  enableval="$enable_accentfold"
+  ENABLE_ACCENTFOLD=0
+else
+  ENABLE_ACCENTFOLD=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define ENABLE_ACCENTFOLD $ENABLE_ACCENTFOLD
+_ACEOF
+
+
+
+# Check whether --enable-sqlite or --disable-sqlite was given.
+if test "${enable_sqlite+set}" = set; then
+  enableval="$enable_sqlite"
+  USE_SQLITE=0
+else
+  USE_SQLITE=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define USE_SQLITE $USE_SQLITE
+_ACEOF
+
+
+
+# Check whether --enable-apache-httpd or --disable-apache-httpd was given.
+if test "${enable_apache_httpd+set}" = set; then
+  enableval="$enable_apache_httpd"
+  USE_APACHE_HTTPD=0
+else
+  USE_APACHE_HTTPD=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define USE_APACHE_HTTPD $USE_APACHE_HTTPD
+_ACEOF
+
+
+
+
+LDFLAGS=$LDFLAGS
+
+if test -z "$CFLAGS"; then
+CFLAGS=-O2
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+	;;
+    conftest.$ac_ext )
+	# This is the source file.
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
+    * )
+	break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  export ac_cv_exeext
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX 10.20 and later	-Ae
+# HP-UX older versions	-Aa -D_HPUX_SOURCE
+# SVR4			-Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CXX" && break
+done
+test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
+
+  CXX=$ac_ct_CXX
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cxx_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+for ac_prog in 'bison -y' byacc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_YACC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_YACC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+  echo "$as_me:$LINENO: result: $YACC" >&5
+echo "${ECHO_T}$YACC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6
+if test "${ac_cv_target+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_target_alias=$target_alias
+test "x$ac_cv_target_alias" = "x" &&
+  ac_cv_target_alias=$ac_cv_host_alias
+ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6
+target=$ac_cv_target
+target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+	@echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+echo "$as_me:$LINENO: checking to see if architecture is 64-bit" >&5
+echo $ECHO_N "checking to see if architecture is 64-bit... $ECHO_C" >&6
+arch_64bit=no
+case "$host_cpu" in
+x86_64) arch_64bit=yes ;;
+esac
+
+if test "$arch_64bit" = yes; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS="-m32"
+  fi
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS=
+  fi
+fi
+export COMPAT32BITFLAGS
+
+
+
+#moved CORBA MICO directory test to get version of MICO
+if test $USE_CORBA = 1; then
+
+if test $MICO_DIR = "default"; then
+#do something
+MICO_INC="-I packages/mico/mico/include"
+else
+#build the micotest program
+MICO_INC= ""
+if test $MICO_DIR != yes; then
+MICO_INC="-I $MICO_DIR"
+fi
+fi
+
+#get MICO_VER value
+sh -c "$CC -c micotest.cpp -o micotest.o $MICO_INC 2>&1" > /dev/null
+sh -c "$CC -o micotest micotest.o -lstdc++ 2>&1" > /dev/null
+MICO_VER=`./micotest` || MICO_VER=2.3.5
+sh -c "rm micotest"
+sh -c "rm micotest.o"
+
+#do test of MICO_VER
+if test MICO_VER != 0; then
+cat >>confdefs.h <<\_ACEOF
+#define MICO_VER 1
+_ACEOF
+
+
+fi
+#end USE_CORBA test
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+
+echo "$as_me:$LINENO: checking for AIX" >&5
+echo $ECHO_N "checking for AIX... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef _AIX
+  yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+cat >>confdefs.h <<\_ACEOF
+#define _ALL_SOURCE 1
+_ACEOF
+
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest*
+
+
+echo "$as_me:$LINENO: checking for library containing strerror" >&5
+echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6
+if test "${ac_cv_search_strerror+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_strerror=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char strerror ();
+int
+main ()
+{
+strerror ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_strerror="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_strerror" = no; then
+  for ac_lib in cposix; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char strerror ();
+int
+main ()
+{
+strerror ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_strerror="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5
+echo "${ECHO_T}$ac_cv_search_strerror" >&6
+if test "$ac_cv_search_strerror" != no; then
+  test "$ac_cv_search_strerror" = "none required" || LIBS="$ac_cv_search_strerror $LIBS"
+
+fi
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for minix/config.h" >&5
+echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
+echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking minix/config.h usability" >&5
+echo $ECHO_N "checking minix/config.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <minix/config.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking minix/config.h presence" >&5
+echo $ECHO_N "checking minix/config.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <minix/config.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: minix/config.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: minix/config.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for minix/config.h" >&5
+echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_minix_config_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
+echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6
+
+fi
+if test $ac_cv_header_minix_config_h = yes; then
+  MINIX=yes
+else
+  MINIX=
+fi
+
+
+if test "$MINIX" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_SOURCE 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_1_SOURCE 2
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _MINIX 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for ${CC-cc} option to accept ANSI C" >&5
+echo $ECHO_N "checking for ${CC-cc} option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CFLAGS="$CFLAGS"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX			-Aa -D_HPUX_SOURCE
+# SVR4			-Xc
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" -Xc
+do
+  CFLAGS="$ac_save_CFLAGS $ac_arg"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif
+
+int
+main ()
+{
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc="$ac_arg"; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+CFLAGS="$ac_save_CFLAGS"
+
+fi
+
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno) ;;
+  *) CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+
+echo "$as_me:$LINENO: checking for function prototypes" >&5
+echo $ECHO_N "checking for function prototypes... $ECHO_C" >&6
+if test "$ac_cv_prog_cc_stdc" != no; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  cat >>confdefs.h <<\_ACEOF
+#define PROTOTYPES 1
+_ACEOF
+
+  U= ANSI2KNR=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  U=_ ANSI2KNR=ansi2knr
+fi
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6
+if test "${ac_cv_type_off_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((off_t *) 0)
+  return 0;
+if (sizeof (off_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_off_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_off_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
+if test $ac_cv_type_off_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((size_t *) 0)
+  return 0;
+if (sizeof (size_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_size_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_size_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+if test $ac_cv_type_size_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+if test "${ac_cv_header_time+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_time=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_time=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6
+if test $ac_cv_header_time = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TIME_WITH_SYS_TIME 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5
+echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6
+if test "${ac_cv_struct_tm+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <time.h>
+
+int
+main ()
+{
+struct tm *tp; tp->tm_sec;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_struct_tm=time.h
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5
+echo "${ECHO_T}$ac_cv_struct_tm" >&6
+if test $ac_cv_struct_tm = sys/time.h; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TM_IN_SYS_TIME 1
+_ACEOF
+
+fi
+
+
+if test "$ac_cv_prog_cc_stdc" = '-Xc'; then
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+int
+main ()
+{
+ FILE *rubbish = popen("yes", "r");
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+CC="`echo $CC | sed 's/-Xc/-Xa/'`"    ac_cv_prog_cc_stdc='-Xa'
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+
+echo "$as_me:$LINENO: checking for main in -lg" >&5
+echo $ECHO_N "checking for main in -lg... $ECHO_C" >&6
+if test "${ac_cv_lib_g_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lg  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_g_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_g_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_g_main" >&5
+echo "${ECHO_T}$ac_cv_lib_g_main" >&6
+if test $ac_cv_lib_g_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBG 1
+_ACEOF
+
+  LIBS="-lg $LIBS"
+
+fi
+ac_cv_lib_g=ac_cv_lib_g_main
+
+
+echo "$as_me:$LINENO: checking for main in -lm" >&5
+echo $ECHO_N "checking for main in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5
+echo "${ECHO_T}$ac_cv_lib_m_main" >&6
+if test $ac_cv_lib_m_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+fi
+ac_cv_lib_m=ac_cv_lib_m_main
+
+
+echo "$as_me:$LINENO: checking for main in -lcrypt" >&5
+echo $ECHO_N "checking for main in -lcrypt... $ECHO_C" >&6
+if test "${ac_cv_lib_crypt_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypt_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypt_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_main" >&5
+echo "${ECHO_T}$ac_cv_lib_crypt_main" >&6
+if test $ac_cv_lib_crypt_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCRYPT 1
+_ACEOF
+
+  LIBS="-lcrypt $LIBS"
+
+fi
+ac_cv_lib_crypt=ac_cv_lib_crypt_main
+
+if test $ENABLE_ACCENTFOLD = 1; then
+
+echo "$as_me:$LINENO: checking for main in -liconv" >&5
+echo $ECHO_N "checking for main in -liconv... $ECHO_C" >&6
+if test "${ac_cv_lib_iconv_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-liconv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_iconv_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_iconv_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_iconv_main" >&5
+echo "${ECHO_T}$ac_cv_lib_iconv_main" >&6
+if test $ac_cv_lib_iconv_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBICONV 1
+_ACEOF
+
+  LIBS="-liconv $LIBS"
+
+fi
+ac_cv_lib_iconv=ac_cv_lib_iconv_main
+
+fi
+
+
+
+
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5
+echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in dir; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+else
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in x; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+fi
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+
+
+for ac_header in fcntl.h limits.h sys/time.h unistd.h crypt.h string.h memory.h sys/procfs.h sys/stat.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "fread" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_FREAD_DECL 1
+_ACEOF
+
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "fgetc" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_FGETC_DECL 1
+_ACEOF
+
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/procfs.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "pr_brksize" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_PR_BRKSIZE 1
+_ACEOF
+
+fi
+rm -f conftest*
+
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+echo "$as_me:$LINENO: checking for working alloca.h" >&5
+echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6
+if test "${ac_cv_working_alloca_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_working_alloca_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_working_alloca_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5
+echo "${ECHO_T}$ac_cv_working_alloca_h" >&6
+if test $ac_cv_working_alloca_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA_H 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for alloca" >&5
+echo $ECHO_N "checking for alloca... $ECHO_C" >&6
+if test "${ac_cv_func_alloca_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  if HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_alloca_works=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_alloca_works=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5
+echo "${ECHO_T}$ac_cv_func_alloca_works" >&6
+
+if test $ac_cv_func_alloca_works = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA 1
+_ACEOF
+
+else
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble.  Some versions do not even contain alloca or
+# contain a buggy version.  If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=alloca.$ac_objext
+
+cat >>confdefs.h <<\_ACEOF
+#define C_ALLOCA 1
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5
+echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6
+if test "${ac_cv_os_cray+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "webecray" >/dev/null 2>&1; then
+  ac_cv_os_cray=yes
+else
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5
+echo "${ECHO_T}$ac_cv_os_cray" >&6
+if test $ac_cv_os_cray = yes; then
+  for ac_func in _getb67 GETB67 getb67; do
+    as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+    break
+fi
+
+  done
+fi
+
+echo "$as_me:$LINENO: checking stack direction for C alloca" >&5
+echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6
+if test "${ac_cv_c_stack_direction+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_c_stack_direction=0
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+  exit (find_stack_direction () < 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_stack_direction=1
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5
+echo "${ECHO_T}$ac_cv_c_stack_direction" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+if test $ac_cv_c_compiler_gnu = yes; then
+    echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5
+echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6
+if test "${ac_cv_prog_gcc_traditional+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+else
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5
+echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+echo "$as_me:$LINENO: checking return type of signal handlers" >&5
+echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
+if test "${ac_cv_type_signal+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+# undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_signal=void
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_signal=int
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
+echo "${ECHO_T}$ac_cv_type_signal" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+
+for ac_func in vprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+echo "$as_me:$LINENO: checking for _doprnt" >&5
+echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6
+if test "${ac_cv_func__doprnt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define _doprnt to an innocuous variant, in case <limits.h> declares _doprnt.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define _doprnt innocuous__doprnt
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _doprnt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef _doprnt
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char _doprnt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+char (*f) () = _doprnt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != _doprnt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func__doprnt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func__doprnt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5
+echo "${ECHO_T}$ac_cv_func__doprnt" >&6
+if test $ac_cv_func__doprnt = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DOPRNT 1
+_ACEOF
+
+fi
+
+fi
+done
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_func in ftime select strftime strtol getrusage times mallinfo setbuffer getpagesize strerror
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+for ac_func in ftruncate strstr strcasecmp
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+echo "$as_me:$LINENO: checking for textdomain" >&5
+echo $ECHO_N "checking for textdomain... $ECHO_C" >&6
+if test "${ac_cv_func_textdomain+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define textdomain to an innocuous variant, in case <limits.h> declares textdomain.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define textdomain innocuous_textdomain
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char textdomain (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef textdomain
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char textdomain ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_textdomain) || defined (__stub___textdomain)
+choke me
+#else
+char (*f) () = textdomain;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != textdomain;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_textdomain=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_textdomain=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_textdomain" >&5
+echo "${ECHO_T}$ac_cv_func_textdomain" >&6
+if test $ac_cv_func_textdomain = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define ENABLE_NLS  1
+_ACEOF
+
+fi
+
+
+# *** Custom checking (based on GNU tar configure.in) ***
+# ---------------------------------------------------------------------------
+echo "$as_me:$LINENO: checking for HP-UX needing gmalloc" >&5
+echo $ECHO_N "checking for HP-UX needing gmalloc... $ECHO_C" >&6
+if test "`(uname -s) 2> /dev/null`" = 'HP-UX'; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  case $LIBOBJS in
+    "gmalloc.$ac_objext"   | \
+  *" gmalloc.$ac_objext"   | \
+    "gmalloc.$ac_objext "* | \
+  *" gmalloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS gmalloc.$ac_objext" ;;
+esac
+
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_VALLOC 1
+_ACEOF
+
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+for ac_func in valloc
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+fi
+
+# we cannot generate static libraries under Darwin
+echo "$as_me:$LINENO: checking for Apple MacOS X/Darwin" >&5
+echo $ECHO_N "checking for Apple MacOS X/Darwin... $ECHO_C" >&6
+if test "`(uname -s) 2> /dev/null`" = 'Darwin'; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  STATIC=""
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  STATIC="-static "
+fi
+
+
+echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5
+echo $ECHO_N "checking if malloc debugging is wanted... $ECHO_C" >&6
+
+# Check whether --with-dmalloc or --without-dmalloc was given.
+if test "${with_dmalloc+set}" = set; then
+  withval="$with_dmalloc"
+  if test "$withval" = yes; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  cat >>confdefs.h <<\_ACEOF
+#define WITH_DMALLOC 1
+_ACEOF
+
+  LIBS="$LIBS -ldmalloc"
+  LDFLAGS="$LDFLAGS -g"
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+echo "$as_me:$LINENO: checking which of rx or regex is wanted" >&5
+echo $ECHO_N "checking which of rx or regex is wanted... $ECHO_C" >&6
+
+# Check whether --with-regex or --without-regex was given.
+if test "${with_regex+set}" = set; then
+  withval="$with_regex"
+  if test "$withval" = yes; then
+  ac_with_regex=1
+  echo "$as_me:$LINENO: result: regex" >&5
+echo "${ECHO_T}regex" >&6
+  cat >>confdefs.h <<\_ACEOF
+#define WITH_REGEX 1
+_ACEOF
+
+  case $LIBOBJS in
+    "regex.$ac_objext"   | \
+  *" regex.$ac_objext"   | \
+    "regex.$ac_objext "* | \
+  *" regex.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS regex.$ac_objext" ;;
+esac
+
+fi
+fi;
+if test -z "$ac_with_regex"; then
+  echo "$as_me:$LINENO: result: rx" >&5
+echo "${ECHO_T}rx" >&6
+  echo "$as_me:$LINENO: checking for re_rx_search" >&5
+echo $ECHO_N "checking for re_rx_search... $ECHO_C" >&6
+if test "${ac_cv_func_re_rx_search+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define re_rx_search to an innocuous variant, in case <limits.h> declares re_rx_search.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define re_rx_search innocuous_re_rx_search
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char re_rx_search (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef re_rx_search
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char re_rx_search ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_re_rx_search) || defined (__stub___re_rx_search)
+choke me
+#else
+char (*f) () = re_rx_search;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != re_rx_search;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_re_rx_search=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_re_rx_search=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_re_rx_search" >&5
+echo "${ECHO_T}$ac_cv_func_re_rx_search" >&6
+if test $ac_cv_func_re_rx_search = yes; then
+  :
+else
+  case $LIBOBJS in
+    "rx.$ac_objext"   | \
+  *" rx.$ac_objext"   | \
+    "rx.$ac_objext "* | \
+  *" rx.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS rx.$ac_objext" ;;
+esac
+
+fi
+
+fi
+
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+  case $LIBOBJS in
+    "xmalloc.$ac_objext"   | \
+  *" xmalloc.$ac_objext"   | \
+    "xmalloc.$ac_objext "* | \
+  *" xmalloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS xmalloc.$ac_objext" ;;
+esac
+
+  case $LIBOBJS in
+    "error.$ac_objext"   | \
+  *" error.$ac_objext"   | \
+    "error.$ac_objext "* | \
+  *" error.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS error.$ac_objext" ;;
+esac
+
+fi
+
+
+# ---------------------------------------------------------------------------
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking that Perl 5 is available" >&5
+echo $ECHO_N "checking that Perl 5 is available... $ECHO_C" >&6
+success="no"
+pl_path="$PATH"
+IFS="${IFS=   }"; pl_save_ifs="$IFS"; IFS=":"
+for pl_dir in $pl_path; do
+  test -z "$pl_dir" && pl_dir=.
+  if test -x $pl_dir/perl; then
+    success="yes"
+    break
+  fi
+done
+IFS="$pl_save_ifs"
+
+if test $success = "yes"; then
+try=`perl configtest.pl` || try="0"
+try=`expr $try \> 5.000`
+if test $try = "1"; then
+echo "$as_me:$LINENO: result: \"yes\"" >&5
+echo "${ECHO_T}\"yes\"" >&6
+else
+success="no"
+fi
+fi
+
+if test $success = "no"; then
+echo "$as_me:$LINENO: result: \"no\"" >&5
+echo "${ECHO_T}\"no\"" >&6
+{ { echo "$as_me:$LINENO: error: \"Perl 5 not available - cannot install\"" >&5
+echo "$as_me: error: \"Perl 5 not available - cannot install\"" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+success=no
+echo "$as_me:$LINENO: checking \"whether STL library has known faults\"" >&5
+echo $ECHO_N "checking \"whether STL library has known faults\"... $ECHO_C" >&6
+
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <vector>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  success=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $success = "no"; then
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <vector.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  success="yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test $success = "no"; then
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ospace\\std\\vector>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  success="yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test $success = yes; then
+echo "$as_me:$LINENO: result: \"no\"" >&5
+echo "${ECHO_T}\"no\"" >&6
+else
+echo "$as_me:$LINENO: result: \"yes\"" >&5
+echo "${ECHO_T}\"yes\"" >&6
+{ { echo "$as_me:$LINENO: error: \"STL Broken - Obtain newer version of GNU C Compiler\"" >&5
+echo "$as_me: error: \"STL Broken - Obtain newer version of GNU C Compiler\"" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+gsdlos=`uname | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+# check for running bash under cygwin
+ if test "`echo $gsdlos | sed 's/cygwin//'`" != "$gsdlos" ;
+ then
+  gsdlos=windows
+ fi
+
+
+# check for endianness
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+main ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+  case $LIBOBJS in
+    "xmalloc.o.$ac_objext"   | \
+  *" xmalloc.o.$ac_objext"   | \
+    "xmalloc.o.$ac_objext "* | \
+  *" xmalloc.o.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS xmalloc.o.$ac_objext" ;;
+esac
+
+  case $LIBOBJS in
+    "error.$ac_objext"   | \
+  *" error.$ac_objext"   | \
+    "error.$ac_objext "* | \
+  *" error.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS error.$ac_objext" ;;
+esac
+
+fi
+
+# ---------------------------------------------------------------------------
+
+moduleDirs=""
+MODULEDIRS=""
+if test -d modules ; then
+  for x in `find modules -mindepth 1 -maxdepth 2`; do
+    if test -d "$x"; then
+      d="$x/Makefile.in"
+      if test -e "$d"; then
+          moduleDirs="$moduleDirs $x/Makefile"
+        MODULEDIRS="$MODULEDIRS $x"
+      fi
+    fi
+  done
+  echo "Making $moduleDirs in modules directory"
+
+fi
+
+
+# ---------------------------------------------------------------------------
+
+# indexers needs a bindir option to get the binaries into the right place
+gsdlprefix=`pwd`
+ac_configure_args="$ac_configure_args --bindir=$gsdlprefix/bin/$gsdlos --libdir=$gsdlprefix/lib/$gsdlos"
+
+
+subdirs="$subdirs common-src build-src runtime-src"
+
+
+# the list of folders in the src folder
+srclist="common-src/Makefile \
+         build-src/Makefile \
+         runtime-src/Makefile"
+
+                              ac_config_files="$ac_config_files Makefile $srclist $moduleDirs"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "$srclist" ) CONFIG_FILES="$CONFIG_FILES $srclist" ;;
+  "$moduleDirs" ) CONFIG_FILES="$CONFIG_FILES $moduleDirs" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@USE_FASTCGI@,$USE_FASTCGI,;t t
+s,@USE_LANGACTION@,$USE_LANGACTION,;t t
+s,@USE_CORBA@,$USE_CORBA,;t t
+s,@MICO_DIR@,$MICO_DIR,;t t
+s,@USE_Z3950@,$USE_Z3950,;t t
+s,@USE_YAZ@,$USE_YAZ,;t t
+s,@ENABLE_ACCENTFOLD@,$ENABLE_ACCENTFOLD,;t t
+s,@USE_SQLITE@,$USE_SQLITE,;t t
+s,@USE_APACHE_HTTPD@,$USE_APACHE_HTTPD,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@CC@,$CC,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CXX@,$CXX,;t t
+s,@CXXFLAGS@,$CXXFLAGS,;t t
+s,@ac_ct_CXX@,$ac_ct_CXX,;t t
+s,@AWK@,$AWK,;t t
+s,@YACC@,$YACC,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@target@,$target,;t t
+s,@target_cpu@,$target_cpu,;t t
+s,@target_vendor@,$target_vendor,;t t
+s,@target_os@,$target_os,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@LN_S@,$LN_S,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@COMPAT32BITFLAGS@,$COMPAT32BITFLAGS,;t t
+s,@MICO_VER@,$MICO_VER,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@U@,$U,;t t
+s,@ANSI2KNR@,$ANSI2KNR,;t t
+s,@ALLOCA@,$ALLOCA,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@STATIC@,$STATIC,;t t
+s,@gsdlos@,$gsdlos,;t t
+s,@MODULEDIRS@,$MODULEDIRS,;t t
+s,@subdirs@,$subdirs,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+#
+# CONFIG_SUBDIRS section.
+#
+if test "$no_recursion" != yes; then
+
+  # Remove --cache-file and --srcdir arguments so they do not pile up.
+  ac_sub_configure_args=
+  ac_prev=
+  for ac_arg in $ac_configure_args; do
+    if test -n "$ac_prev"; then
+      ac_prev=
+      continue
+    fi
+    case $ac_arg in
+    -cache-file | --cache-file | --cache-fil | --cache-fi \
+    | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+      ac_prev=cache_file ;;
+    -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+    | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \
+    | --c=*)
+      ;;
+    --config-cache | -C)
+      ;;
+    -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+      ac_prev=srcdir ;;
+    -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+      ;;
+    -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+      ac_prev=prefix ;;
+    -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+      ;;
+    *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+    esac
+  done
+
+  # Always prepend --prefix to ensure using the same prefix
+  # in subdir configurations.
+  ac_sub_configure_args="--prefix=$prefix $ac_sub_configure_args"
+
+  ac_popdir=`pwd`
+  for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue
+
+    # Do not complain, so a configure script can configure whichever
+    # parts of a large source tree are present.
+    test -d $srcdir/$ac_dir || continue
+
+    { echo "$as_me:$LINENO: configuring in $ac_dir" >&5
+echo "$as_me: configuring in $ac_dir" >&6;}
+    { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+    cd $ac_dir
+
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      ac_sub_configure="$SHELL '$ac_srcdir/configure.gnu'"
+    elif test -f $ac_srcdir/configure; then
+      ac_sub_configure="$SHELL '$ac_srcdir/configure'"
+    elif test -f $ac_srcdir/configure.in; then
+      ac_sub_configure=$ac_configure
+    else
+      { echo "$as_me:$LINENO: WARNING: no configuration information is in $ac_dir" >&5
+echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
+      ac_sub_configure=
+    fi
+
+    # The recursion is here.
+    if test -n "$ac_sub_configure"; then
+      # Make the cache file name correct relative to the subdirectory.
+      case $cache_file in
+      [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;;
+      *) # Relative path.
+	ac_sub_cache_file=$ac_top_builddir$cache_file ;;
+      esac
+
+      { echo "$as_me:$LINENO: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
+echo "$as_me: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
+      # The eval makes quoting arguments work.
+      eval $ac_sub_configure $ac_sub_configure_args \
+	   --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir ||
+	{ { echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5
+echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+
+    cd $ac_popdir
+  done
+fi
+
+
+
Index: /gsdl/stable/configure.in
===================================================================
--- /gsdl/stable/configure.in	(revision 20131)
+++ /gsdl/stable/configure.in	(revision 20131)
@@ -0,0 +1,396 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl Use autoconf-2.59 or later... it might not work anymore with
+dnl the older 2.1x versions - jrm21 12/2004
+AC_INIT()
+AC_CONFIG_HEADER(config.h)
+
+PACKAGE=gsdl
+VERSION=2.82-svn
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+
+dnl
+dnl Set use of fast cgi
+dnl
+USE_FASTCGI=0
+if test USE_FASTCGI = 1; then
+AC_DEFINE(USE_FASTCGI)
+AC_SUBST(USE_FASTCGI)
+fi
+
+dnl
+dnl Set use of langaction
+dnl
+dnl USE_LANGACTION=0
+if test USE_LANGACTION = 1; then
+AC_DEFINE(USE_LANGACTION)
+AC_SUBST(USE_LANGACTION)
+fi
+
+dnl
+dnl Set use of corba
+dnl
+AC_ARG_ENABLE(corba, [  --enable-corba          Enable CORBA support], USE_CORBA=1, USE_CORBA=0)
+AC_DEFINE_UNQUOTED(USE_CORBA, $USE_CORBA)
+AC_SUBST(USE_CORBA)
+
+AC_ARG_WITH(micodir, [  --with-micodir          Use installed MICO directory], MICO_DIR=$enableval, MICO_DIR="default")
+AC_DEFINE_UNQUOTED(MICO_DIR, "$MICO_DIR")
+AC_SUBST(MICO_DIR)
+
+dnl
+dnl Set use of z39.50
+dnl
+AC_ARG_ENABLE(z3950, [  --enable-z3950          Enable Z39.50 client support], USE_Z3950=1, USE_Z3950=0)
+if test USE_Z3950 = 1; then
+AC_DEFINE(USE_Z3950, $USE_Z3950)
+AC_SUBST(USE_Z3950)
+fi
+
+dnl
+dnl Set use of yaz - now compiled by default even when z3950 support not required
+dnl
+AC_ARG_ENABLE(yaz, [  --disable-yaz           Disable YAZ compilation], USE_YAZ=0, USE_YAZ=1)
+dnl if test USE_YAZ = 1; then
+AC_DEFINE(USE_YAZ, $USE_YAZ)
+AC_SUBST(USE_YAZ)
+dnl fi
+
+dnl 
+dnl disable compilation of accent folding stuff for mgpp (and one day mg)
+dnl
+AC_ARG_ENABLE(accentfold, [  --disable-accentfold    Disable Accent Folding for MGPP], ENABLE_ACCENTFOLD=0, ENABLE_ACCENTFOLD=1)
+AC_DEFINE(ENABLE_ACCENTFOLD, $ENABLE_ACCENTFOLD)
+AC_SUBST(ENABLE_ACCENTFOLD)
+
+dnl
+dnl Set use of SQLite (enabled by default)
+dnl
+AC_ARG_ENABLE(sqlite, [  --disable-sqlite        Disable SQLite support], USE_SQLITE=0, USE_SQLITE=1)
+AC_DEFINE(USE_SQLITE, $USE_SQLITE)
+AC_SUBST(USE_SQLITE)
+
+dnl
+dnl Set use of Apache httpd (enabled by default)
+dnl
+AC_ARG_ENABLE(apache-httpd, [  --disable-apache-httpd  Disable Apache httpd support], USE_APACHE_HTTPD=0, USE_APACHE_HTTPD=1)
+AC_DEFINE(USE_APACHE_HTTPD, $USE_APACHE_HTTPD)
+AC_SUBST(USE_APACHE_HTTPD)
+
+
+dnl Checks for programs.
+LDFLAGS=$LDFLAGS
+AC_SUBST(LDFLAGS)
+dnl only set CFLAGS if not already set in environment
+if test -z "$CFLAGS"; then
+CFLAGS=-O2
+fi
+AC_SUBST(CFLAGS)
+
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_AWK
+AC_PROG_YACC
+dnl get $target_cpu, $target_vendor, and $target_os
+dnl (as well as host_*)
+AC_CANONICAL_SYSTEM
+dnl do we actually want this? It adds a prefix based on host, system etc
+dnl AC_ARG_PROGRAM
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+
+AC_MSG_CHECKING(to see if architecture is 64-bit)
+arch_64bit=no
+case "$host_cpu" in
+x86_64) arch_64bit=yes ;;
+esac
+
+if test "$arch_64bit" = yes; then
+  AC_MSG_RESULT(yes)
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS="-m32"
+  fi
+else
+  AC_MSG_RESULT(no)
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS=
+  fi
+fi
+export COMPAT32BITFLAGS
+AC_SUBST(COMPAT32BITFLAGS)
+
+
+#moved CORBA MICO directory test to get version of MICO
+if test $USE_CORBA = 1; then
+
+if test $MICO_DIR = "default"; then
+#do something
+MICO_INC="-I packages/mico/mico/include"
+else
+#build the micotest program
+MICO_INC= ""
+if test $MICO_DIR != yes; then
+MICO_INC="-I $MICO_DIR"
+fi
+fi
+
+#get MICO_VER value
+sh -c "$CC -c micotest.cpp -o micotest.o $MICO_INC 2>&1" > /dev/null
+sh -c "$CC -o micotest micotest.o -lstdc++ 2>&1" > /dev/null
+MICO_VER=`./micotest` || MICO_VER=2.3.5
+sh -c "rm micotest"
+sh -c "rm micotest.o"
+
+#do test of MICO_VER
+if test MICO_VER != 0; then
+AC_DEFINE(MICO_VER)
+AC_SUBST(MICO_VER)
+fi
+#end USE_CORBA test
+fi
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_AIX
+AC_ISC_POSIX
+AC_MINIX
+fp_C_PROTOTYPES
+AC_C_CONST
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl --- This should be in the stdc checking -----------------
+if test "$ac_cv_prog_cc_stdc" = '-Xc'; then
+dnl The Pyramids running SMP_DC.OSx on MIPS r3000 chips with
+dnl /usr/opt/cc3.11/bin/cc treat -Xc as full ANSI mode - no POSIX or
+dnl XOPEN extensions (like popen).
+dnl Unfortunately -D_{XOPEN,POSIX}_SOURCE can't provide all that mg
+dnl needs. So drop back to -Xa
+AC_TRY_COMPILE(
+[#include <stdio.h>
+], [ FILE *rubbish = popen("yes", "r"); ],,
+[CC="`echo $CC | sed 's/-Xc/-Xa/'`"    ac_cv_prog_cc_stdc='-Xa'])
+fi
+dnl ----------------------
+
+
+dnl Checks for libraries.
+dnl check for -lg:
+AC_HAVE_LIBRARY(g)
+dnl check for -lm:
+AC_HAVE_LIBRARY(m)
+dnl check for -lcrypt:
+AC_HAVE_LIBRARY(crypt)
+if test $ENABLE_ACCENTFOLD = 1; then
+AC_HAVE_LIBRARY(iconv)
+fi
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h limits.h sys/time.h unistd.h crypt.h string.h memory.h sys/procfs.h sys/stat.h)
+AC_EGREP_HEADER(fread, stdio.h, AC_DEFINE(HAVE_FREAD_DECL))
+AC_EGREP_HEADER(fgetc, stdio.h, AC_DEFINE(HAVE_FGETC_DECL))
+AC_EGREP_HEADER(pr_brksize, sys/procfs.h, AC_DEFINE(HAVE_PR_BRKSIZE))
+
+dnl Checks for library functions.
+AC_FUNC_ALLOCA
+AC_PROG_GCC_TRADITIONAL
+AC_TYPE_SIGNAL
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(ftime select strftime strtol getrusage times mallinfo setbuffer getpagesize strerror)
+AC_REPLACE_FUNCS(ftruncate strstr strcasecmp)
+
+dnl see if gettext is in libc. (try the textdomain() function).
+AC_CHECK_FUNC(textdomain, AC_DEFINE(ENABLE_NLS ,1) )
+
+# *** Custom checking (based on GNU tar configure.in) ***
+# ---------------------------------------------------------------------------
+AC_MSG_CHECKING(for HP-UX needing gmalloc)
+if test "`(uname -s) 2> /dev/null`" = 'HP-UX'; then
+  AC_MSG_RESULT(yes)
+  AC_LIBOBJ([gmalloc])
+  AC_DEFINE(HAVE_VALLOC)
+else
+  AC_MSG_RESULT(no)
+  AC_CHECK_FUNCS(valloc)
+fi
+
+# we cannot generate static libraries under Darwin
+AC_MSG_CHECKING(for Apple MacOS X/Darwin)
+if test "`(uname -s) 2> /dev/null`" = 'Darwin'; then
+  AC_MSG_RESULT(yes)
+  STATIC=""
+else
+  AC_MSG_RESULT(no)
+  STATIC="-static "
+fi
+AC_SUBST(STATIC)
+
+fp_WITH_DMALLOC
+fp_WITH_REGEX
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+dnl    support functions for alloca.c
+  AC_LIBOBJ([xmalloc])
+  AC_LIBOBJ([error])
+fi
+
+
+# ---------------------------------------------------------------------------
+
+dnl
+dnl Switch into C++
+dnl
+AC_LANG_CPLUSPLUS
+
+dnl
+dnl Now check that Perl is actually around, and can be found
+dnl
+AC_MSG_CHECKING(that Perl 5 is available)
+success="no"
+pl_path="$PATH"
+IFS="${IFS=   }"; pl_save_ifs="$IFS"; IFS=":"
+for pl_dir in $pl_path; do
+  test -z "$pl_dir" && pl_dir=.
+  if test -x $pl_dir/perl; then
+    success="yes"
+    break
+  fi
+done
+IFS="$pl_save_ifs"
+
+dnl
+dnl Perl actually can be run; now we see if it is version 5 by
+dnl running a sample script (which returns a "clean" version number
+dnl and then tests the result using expr.  If perl errors in some
+dnl way (eg. broken Perl executable, missing script), we set a failure
+dnl value ("0") and then proceed as best we can
+dnl
+if test $success = "yes"; then
+try=`perl configtest.pl` || try="0"
+try=`expr $try \> 5.000`
+if test $try = "1"; then
+AC_MSG_RESULT("yes")
+else
+success="no"
+fi
+fi
+
+if test $success = "no"; then
+AC_MSG_RESULT("no")
+AC_MSG_ERROR("Perl 5 not available - cannot install")
+fi
+
+dnl
+dnl Check if the STL library has any known faults;
+dnl In GCC 2.7.2.x series, some STL library headers are missing
+dnl a file called "new" which is referred to by other headers
+dnl (eg. vector/vector.h); if this applies, then all use of the
+dnl STL will cause a compile fail, so we'd better let the user
+dnl know now, before things really go wrong!
+dnl
+success=no
+AC_MSG_CHECKING("whether STL library has known faults")
+
+dnl - first shot, try simple good old vector on its own
+AC_TRY_COMPILE(
+[#include <vector>
+], 
+[],
+success=yes,
+)
+
+dnl - try using the .h equivalent
+if test $success = "no"; then
+AC_TRY_COMPILE(
+[#include <vector.h>
+], 
+[],
+success="yes",
+)
+fi
+
+dnl - now try for the objectspace headers
+if test $success = "no"; then
+AC_TRY_COMPILE(
+[#include <ospace\\std\\vector>
+], 
+[],
+success="yes",
+)
+fi
+
+if test $success = yes; then
+AC_MSG_RESULT("no")
+else
+AC_MSG_RESULT("yes")
+AC_MSG_ERROR("STL Broken - Obtain newer version of GNU C Compiler")
+fi
+
+gsdlos=`uname | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+# check for running bash under cygwin
+ if test "`echo $gsdlos | sed 's/cygwin//'`" != "$gsdlos" ;
+ then
+  gsdlos=windows
+ fi
+AC_SUBST(gsdlos)
+
+# check for endianness
+AC_C_BIGENDIAN
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+dnl    support functions for alloca.c
+  AC_LIBOBJ([xmalloc.o])
+  AC_LIBOBJ([error])
+fi
+
+# ---------------------------------------------------------------------------
+
+dnl
+dnl Locate all children of the modules folder
+dnl
+moduleDirs=""
+MODULEDIRS=""
+if test -d modules ; then
+  for x in `find modules -mindepth 1 -maxdepth 2`; do
+    if test -d "$x"; then
+      d="$x/Makefile.in"
+      if test -e "$d"; then
+  dnl      echo $d
+        moduleDirs="$moduleDirs $x/Makefile"
+        MODULEDIRS="$MODULEDIRS $x"
+      fi
+    fi
+  done
+  echo "Making $moduleDirs in modules directory"
+  AC_SUBST(MODULEDIRS)
+fi
+
+
+# ---------------------------------------------------------------------------
+dnl for Darwin, as our packages don't (yet) correctly guess our system type.
+dnl not needed any more?
+dnl ac_configure_args="$ac_configure_args --build=$build --target=$target"
+
+# indexers needs a bindir option to get the binaries into the right place
+gsdlprefix=`pwd`
+ac_configure_args="$ac_configure_args --bindir=$gsdlprefix/bin/$gsdlos --libdir=$gsdlprefix/lib/$gsdlos"
+AC_CONFIG_SUBDIRS(common-src build-src runtime-src)
+
+# the list of folders in the src folder
+srclist="common-src/Makefile \
+         build-src/Makefile \
+         runtime-src/Makefile"
+
+AC_OUTPUT(Makefile $srclist $moduleDirs)
+
+
Index: /gsdl/stable/etc/BVERSION
===================================================================
--- /gsdl/stable/etc/BVERSION	(revision 20131)
+++ /gsdl/stable/etc/BVERSION	(revision 20131)
@@ -0,0 +1,1 @@
+build version: 2.1
Index: /gsdl/stable/etc/MARC21slim2English.xsl
===================================================================
--- /gsdl/stable/etc/MARC21slim2English.xsl	(revision 20131)
+++ /gsdl/stable/etc/MARC21slim2English.xsl	(revision 20131)
@@ -0,0 +1,20433 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="html"/>
+
+	<xsl:template match="/">
+
+	<html>
+<xsl:apply-templates/>
+</html>
+</xsl:template>
+
+	<xsl:template match="marc:leader">
+<p>LEADER</p>
+<xsl:variable name="leader" select="text()"/>
+<xsl:variable name="leader5" select="substring($leader,6,1)"/>
+<xsl:variable name="leader6" select="substring($leader,7,1)"/>
+<xsl:variable name="leader7" select="substring($leader,8,1)"/>
+<xsl:variable name="leader8" select="substring($leader,9,1)"/>
+<xsl:variable name="leader9" select="substring($leader,10,1)"/>
+<xsl:variable name="leader17" select="substring($leader,18,1)"/>
+<xsl:variable name="leader18" select="substring($leader,19,1)"/>
+<xsl:variable name="leader19" select="substring($leader,20,1)"/>
+
+	<ul>
+
+	<li>
+Record Status:
+			
+<xsl:value-of select="$leader5"/>
+</li>
+
+	<li>
+Type of record:
+			
+<xsl:value-of select="$leader6"/>
+</li>
+
+	<li>
+Bibliographic level:
+			
+<xsl:value-of select="$leader7"/>
+</li>
+
+	<li>
+Type of control:
+			
+<xsl:value-of select="$leader8"/>
+</li>
+
+	<li>
+Undefined:
+			
+<xsl:value-of select="$leader9"/>
+</li>
+
+	<li>
+Encoding level:
+			
+<xsl:value-of select="$leader17"/>
+</li>
+
+	<li>
+Descriptive cataloging form:
+			
+<xsl:value-of select="$leader18"/>
+</li>
+
+	<li>
+Linked record requirement:
+			
+<xsl:value-of select="$leader19"/>
+</li>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=010]">
+<p>LIBRARY OF CONGRESS CONTROL NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+LC control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+NUCMC control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Cancelled/invalid LC control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=011]">
+<p>LINKING LIBRARY OF CONGRESS CONTROL NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Linking LC control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=013]">
+<p>PATENT CONTROL INFORMATION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Country:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Type of number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Status:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Party to document:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=014]">
+<p>LINKAGE NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Linkage number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Source of number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Cancelled/invalid linkage number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=015]">
+<p>NATIONAL BIBLIOGRAPHY NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+National bibliography number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=016]">
+<p>NATIONAL BIBLIOGRAPHIC AGENCY CONTROL NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Canceled/invalid control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=017]">
+<p>COPYRIGHT REGISTRATION NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Copyright registration number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Source (agency assigning number):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=018]">
+<p>COPYRIGHT ARTICLE-FEE CODE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Copyright article-fee code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=020]">
+<p>INTERNATIONAL STANDARD BOOK NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Binding information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Terms of availability:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Cancelled/invalid ISBN:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=022]">
+<p>INTERNATIONAL STANDARD SERIAL NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Incorrect ISSN:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Cancelled ISSN:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=024]">
+<p>OTHER STANDARD IDENTIFIER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Standard recording code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Terms of availability:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Additional codes following the standard number or code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Cancelled/invalid standard code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of code or number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=025]">
+<p>OVERSEAS ACQUISITION NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Overseas acquisition number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=027]">
+<p>STANDARD TECHNICAL REPORT NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Cancelled/invalid STRN:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=028]">
+<p>PUBLISHER NUMBER FOR MUSIC
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Publisher number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=030]">
+<p>CODEN DESIGNATION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+CODEN:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Cancelled/invalid CODEN:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=032]">
+<p>POSTAL REGISTRATION NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Postal registration number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Source (agency assigning number):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=033]">
+<p>DATE/TIME AND PLACE OF AN EVENT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Formatted date/time:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Geographic classification area code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Geographic classification subarea code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=034]">
+<p>CODED CARTOGRAPHIC MATHEMATICAL DATA
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Category of scale:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Constant ratio linear horizontal scale:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Constant ratio linear vertical scale:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Coordinates--westernmost longitude:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Coordinates--easternmost longitude:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Coordinates--northernmost latitude:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Coordinates--southernmost latitude:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Angular scale:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Declination--northern limit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Declination--southern limit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Right ascension--eastern limit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Right ascension--western limit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Equinox:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+G-ring latitude:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+G-ring longitude:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=035]">
+<p>SYSTEM CONTROL NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+System control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Cancelled/invalid system control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=036]">
+<p>ORIGINAL STUDY NUMBER FOR COMPUTER DATA FILES
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Original study number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Source (agency assigning number):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=037]">
+<p>SOURCE OF ACQUISITION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Stock number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Source of stock number/acquisition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Terms of availability:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Form of issue:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Additional format characteristics:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=039]">
+
+	<p>
+LEVEL OF BIBLIOGRAPHIC CONTROL AND CODING DETAIL
+		
+</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Level of rules in bibliographic description:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Level of effort used to assign nonsubject heading access points:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Level of effort used to assign subject headings:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Level of effort used to assign classification:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Number of fixed field character positions coded:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=040]">
+<p>CATALOGING SOURCE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Original cataloging agency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Language of cataloging:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Transcribing agency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Modifying agency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Description conventions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=041]">
+<p>LANGUAGE CODE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Language code of text/sound track or separate title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Language code of summary or abstract/overprinted title or subtitle:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Language code of sung or spoken text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Language code of librettos:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Language code of table of contents:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Language code of accompanying material other than librettos:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Language code of original and/or intermediate translations of text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=042]">
+<p>AUTHENTICATION CODE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Authentication code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=043]">
+<p>GEOGRAPHIC AREA CODE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Geographic area code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Local GAC code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of local code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=044]">
+<p>COUNTRY OF PUBLISHING/PRODUCING ENTITY CODE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Country of publishing/producing entity code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Local subentity code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+ISO subentity code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of local subentity data:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=045]">
+<p>TIME PERIOD OF CONTENT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Time period code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Formatted 9999 B.C. through A.D. time period:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Formatted pre-9999 B.C. time period:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=046]">
+<p>SPECIAL CODED DATES
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Type of date code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Date 1 (B.C. date):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Date 1 (A.D. date):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date 2 (B.C. date):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Date 2 (A.D. date):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=047]">
+<p>FORM OF MUSICAL COMPOSITION CODE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Form of musical composition code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=048]">
+<p>NUMBER OF MUSICAL INSTRUMENTS OR VOICES CODE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Performer or ensemble:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Soloist:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=050]">
+<p>LIBRARY OF CONGRESS CALL NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and number sequence:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Classification number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Supplementary class number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=051]">
+
+	<p>
+LIBRARY OF CONGRESS COPY, ISSUE, OFFPRINT STATEMENT
+		
+</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Classification number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Copy information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=052]">
+<p>GEOGRAPHIC CLASSIFICATION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Geographic classification area code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Geographic classification subarea code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Subject:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Populated place name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Code source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=055]">
+<p>CALL NUMBERS/CLASS NUMBERS ASSIGNED IN CANADA
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Classification number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of call/class number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=058]">
+<p>OTHER GEOGRAPHIC CLASSIFICATION CODE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Geographic classification area code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Geographic classification subarea code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Code source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=060]">
+<p>NATIONAL LIBRARY OF MEDICINE CALL NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Classification number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=061]">
+<p>NATIONAL LIBRARY OF MEDICINE COPY STATEMENT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Classification number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Copy information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=066]">
+<p>CHARACTER SETS PRESENT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Non-ASCII G0 default character set designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Non-ANSEL G1 default character set designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Alternate graphic character set identification:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=070]">
+<p>NATIONAL AGRICULTURAL LIBRARY CALL NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Classification number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=071]">
+<p>NATIONAL AGRICULTURAL LIBRARY COPY STATEMENT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Classification number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Copy information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=072]">
+<p>SUBJECT CATEGORY CODE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Subject category code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Subject category code subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Code source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=073]">
+<p>TYPE OF PROGRAM OR ORGANIZATION CODE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Type of program or organization code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Code source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=074]">
+<p>GPO ITEM NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+GPO item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Cancelled/invalid GPO item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=080]">
+<p>UNIVERSAL DECIMAL CLASSIFICATION NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Universal Decimal Classification number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Common auxiliary subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Edition identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=082]">
+<p>DEWEY DECIMAL CALL NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Classification number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+DDC number--abridged NST version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Edition number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=084]">
+<p>OTHER CLASSIFICATION NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Classification number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=086]">
+<p>GOVERNMENT DOCUMENT CLASSIFICATION NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Classification number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Cancelled/invalid classification number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Number source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=088]">
+<p>REPORT NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Cancelled/invalid report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=090]">
+<p>LOCAL CALL NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Local class number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Local Cutter number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=091]">
+<p>MICROFILM SHELF LOCATION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Microfilm shelf location:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=100]">
+<p>MAIN ENTRY--PERSONAL NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Personal name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Numeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Titles and other words associated with a name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Dates associated with a name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Attribution qualifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Fuller form of name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=110]">
+<p>MAIN ENTRY--CORPORATE NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Corporate name or jurisdiction name as entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Subordinate unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of meeting or treaty signing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section/meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=111]">
+<p>MAIN ENTRY--MEETING NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Meeting name or jurisdiction name as entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Number (BK CF MP MU SE VM MX):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Subordinate unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section/meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Name of meeting following jurisdiction name entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=130]">
+<p>MAIN ENTRY--UNIFORM TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of treaty signing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=210]">
+<p>ABBREVIATED TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Abbreviated title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=211]">
+<p>ACRONYM OR SHORTENED TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Acronym or shortened title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=212]">
+<p>VARIANT ACCESS TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Variant access title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=214]">
+<p>AUGMENTED TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Augmented title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=222]">
+<p>KEY TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Key title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=240]">
+<p>UNIFORM TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of treaty signing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=241]">
+<p>ROMANIZED TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Romanized title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=242]">
+<p>TRANSLATION OF TITLE BY CATALOGING AGENCY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Remainder of title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Remainder of title page transcription /statement of responsibility:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Designation of section:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Name of part/section (BK AM MP MU VM SE):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Language code of translated title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=243]">
+<p>COLLECTIVE UNIFORM TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of treaty signing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=245]">
+<p>TITLE STATEMENT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Remainder of title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Remainder of title page transcription/statement of responsibility:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Designation of section:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Name of part/section (SE):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Inclusive dates:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Bulk dates:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=246]">
+<p>VARYING FORM OF TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Title proper/short title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Remainder of title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Designation of section:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Name of part/section (SE):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Designation of volume and issue number and/or date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=247]">
+<p>FORMER TITLE OR TITLE VARIATIONS
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Title proper/short title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Remainder of title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Designation of section:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Name of part/section (SE):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Designation of volume and issue number and/or date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=250]">
+<p>EDITION STATEMENT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Edition statement:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Remainder of edition statement:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=254]">
+<p>MUSICAL PRESENTATION STATEMENT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Musical presentation statement:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=255]">
+<p>CARTOGRAPHIC MATHEMATICAL DATA
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Statement of scale:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Statement of projection:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Statement of coordinates:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Statement of zone:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Statement of equinox:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Outer G-ring coordinate pairs:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Exclusion G-ring coordinate pairs:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=256]">
+<p>COMPUTER FILE CHARACTERISTICS
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Computer file characteristics:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=257]">
+<p>COUNTRY OF PRODUCING ENTITY FOR ARCHIVAL FILMS
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Country of producing entity for archival films:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=260]">
+<p>PUBLICATION, DISTRIBUTION, ETC. (IMPRINT)
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Place of publication, distribution, etc.:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Name of publisher, distributor, etc.:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Date of publication, distribution, etc.:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Place of manufacture:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Manufacturer:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Date of manufacture:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=263]">
+<p>PROJECTED PUBLICATION DATE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Projected publication date:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=265]">
+<p>SOURCE FOR ACQUISITION/SUBSCRIPTION ADDRESS
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Source for acquisition/subscription address:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=270]">
+<p>ADDRESS
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Address:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+270-b = City:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+State or province:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Country:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Postal code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Title preceding attention name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Attention name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Title following attention name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Type of address:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Specialized telephone number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Telephone number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Fax number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Electronic mail address:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+TDD or TTY number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Contact person:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Title of contact person:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Hours:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=300]">
+<p>PHYSICAL DESCRIPTION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Extent:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Other physical details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Dimensions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Accompanying material:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Type of unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Size of unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=301]">
+<p>PHYSICAL DESCRIPTION FOR FILMS (PRE-AACR 2)
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Extent of item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Sound characteristics:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Color characteristics:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Dimensions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Accompanying material:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Speed:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=302]">
+<p>PAGE OR ITEM COUNT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Page count:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=303]">
+<p>SUBORDINATE ENTITIES
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Name or description:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Schedule:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Contact person:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=304]">
+<p>LINEAR FOOTAGE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Linear footage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=305]">
+
+	<p>
+PHYSICAL DESCRIPTION FOR SOUND RECORDINGS (Pre-AACR 2)
+		
+</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Extent:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Other physical details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Dimensions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Microgroove or standard:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Stereophonic, monaural:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Number of tracks:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Serial identification:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Matrix and/or take number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=306]">
+<p>PLAYING TIME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Playing time:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=307]">
+<p>HOURS, ETC.
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Hours:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Additional information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=308]">
+<p>PHYSICAL DESCRIPTION FOR FILMS (ARCHIVAL)
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Number of reels:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Footage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Sound characteristics:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Color characteristics:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Width:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Presentation format:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=310]">
+<p>CURRENT PUBLICATION FREQUENCY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Current publication frequency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Date of current publication frequency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=311]">
+<p>MEETING ROOMS AND FACILITIES AVAILABLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+General description of facilities:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Name and location:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Physical description:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Capacity:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Equipment available:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Rental fee:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Special restrictions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Accommodations for the disabled:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Contact person:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=312]">
+<p>EQUIPMENT AVAILABLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Type of equipment:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Brand name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Physical description:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Rental fee:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Special restrictions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Accommodations for the disabled:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Contact person:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=315]">
+<p>FREQUENCY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Frequency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Dates of frequency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=321]">
+<p>FORMER PUBLICATION FREQUENCY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Former publication frequency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Dates of former publication frequency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=340]">
+<p>PHYSICAL MEDIUM
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Material base and configuration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Dimensions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Materials applied to surface:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Information recording technique:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Support:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Production rate/ratio:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Location within medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Technical specifications of medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=342]">
+<p>GEOSPATIAL REFERENCE DATA
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Coordinate or distance units:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Latitude resolution:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Longitude resolution:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Standard parallel or oblique line latitude:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Oblique line longitude:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Longitude of central meridian or projection center:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Latitude of projection origin or projection center:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+False easting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+False northing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Scale factor:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Height of perspective point above surface:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Azimuthal angle:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Azimuth measure point longitude or straight vertical longitude from pole:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Landsat number and path number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Zone identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Ellipsoid name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Semi-major axis:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Denominator of flattening ratio:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Vertical resolution:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Vertical encoding method:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Local planar, local, or other projection or grid description:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Local planar or local georeference information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Reference method used:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=343]">
+<p>PLANAR COORDINATE DATA
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Planar coordinate encoding method:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Planar distance units:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Abscissa resolution:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Ordinate resolution:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Distance resolution:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Bearing resolution:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Bearing units:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Bearing reference direction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Bearing reference meridian:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='=']">
+
+	<li>
+ICE:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Price:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Form of issue:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=351]">
+<p>ORGANIZATION AND ARRANGEMENT OF MATERIALS
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Organization:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Arrangement:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Hierarchical level:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=352]">
+<p>DIGITAL GRAPHIC REPRESENTATION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Direct reference method:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Object type:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Object count:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Row count:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Column count:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Vertical count:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Indirect reference description:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=355]">
+<p>SECURITY CLASSIFICATION CONTROL
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Security classification:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Handling instructions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+External dissemination information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Downgrading or declassification event:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Classification system:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Country of origin code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Downgrading date:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Declassification date:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Authorization:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=357]">
+<p>ORIGINATOR DISSEMINATION CONTROL
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Originator control term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Originating agency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Authorized recipients of material:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Other restrictions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=359]">
+<p>RENTAL PRICE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Rental price:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=362]">
+
+	<p>
+DATES OF PUBLICATION AND/OR SEQUENTIAL DESIGNATION
+		
+</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Dates of publication and/or sequential designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Source of information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=440]">
+<p>SERIES STATEMENT/ADDED ENTRY--TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Volume number/sequential designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=490]">
+<p>SERIES STATEMENT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Series statement:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Library of Congress call number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Volume number/sequential designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=500]">
+<p>GENERAL NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+General note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Library of Congress call number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Source of note information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=501]">
+<p>WITH NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+With note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=502]">
+<p>DISSERTATION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Dissertation note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=503]">
+<p>BIBLIOGRAPHIC HISTORY NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Bibliographic history note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=504]">
+<p>BIBLIOGRAPHY, ETC. NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Bibliography, etc. note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Number of references:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=505]">
+<p>FORMATTED CONTENTS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Formatted contents note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Statement of responsibility:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Uniform Resource Identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=506]">
+<p>RESTRICTIONS ON ACCESS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Terms governing access:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Jurisdiction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Physical access provisions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Authorized users:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Authorization:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=507]">
+<p>SCALE NOTE FOR GRAPHIC MATERIAL
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Representative fraction of scale note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Remainder of scale note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=508]">
+<p>CREATION/PRODUCTION CREDITS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Creation/production credits note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=510]">
+<p>CITATION/REFERENCES NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Name of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Dates of coverage of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location within source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=511]">
+<p>PARTICIPANT OR PERFORMER NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Participant or performer note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=512]">
+
+	<p>
+EARLIER OR LATER VOLUMES SEPARATELY CATALOGED NOTE
+		
+</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Earlier or later volumes separately cataloged note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=513]">
+<p>TYPE OF REPORT AND PERIOD COVERED NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Type of report:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Period covered:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=514]">
+<p>DATA QUALITY NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Attribute accuracy report:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Attribute accuracy value:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Attribute accuracy explanation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Logical consistency report:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Completeness report:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Horizontal position accuracy report:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Horizontal position accuracy value:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Horizontal position accuracy explanation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Vertical positional accuracy report:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Vertical positional accuracy value:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Vertical positional accuracy explanation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Cloud cover:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Uniform Resource Identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Display note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=515]">
+<p>NUMBERING PECULIARITIES NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Numbering peculiarities note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Source of note information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=516]">
+<p>TYPE OF COMPUTER FILE OR DATA NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Type of computer file or data note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=517]">
+<p>CATEGORIES OF FILMS NOTE (ARCHIVAL)
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Different formats:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Content descriptors:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Additional animation techniques:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=518]">
+<p>DATE/TIME AND PLACE OF AN EVENT NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Date/time and place of an event note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=520]">
+<p>SUMMARY, ETC.
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Summary, etc.:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Expansion of summary note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Uniform Resource Identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Source of note information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=521]">
+<p>TARGET AUDIENCE NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Target audience note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=522]">
+<p>GEOGRAPHIC COVERAGE NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Geographic coverage note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=523]">
+<p>TIME PERIOD OF CONTENT NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Time period of content note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Dates of data collection note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=524]">
+<p>PREFERRED CITATION OF DESCRIBED MATERIALS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Preferred citation of described materials note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of schema used:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=525]">
+<p>SUPPLEMENT NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Supplement note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Source of note information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=526]">
+<p>STUDY PROGRAM INFORMATION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Program name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Interest level:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Reading level:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Title point value:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=527]">
+<p>CENSORSHIP NOTE
+</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Censorship note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=530]">
+<p>ADDITIONAL PHYSICAL FORM AVAILABLE NOTE
+</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Additional physical form available note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Availability source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Availability conditions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Order number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Uniform Resource Identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Source of note information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=531]">
+<p>ELIGIBILITY, FEES, PROCEDURES NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Eligibility:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Fee:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Admission procedures:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Documents required:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Waiting list:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Waiting period:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=533]">
+<p>REPRODUCTION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Type of reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Place of reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Agency responsible for reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Physical description of reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Series statement of reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Dates of publication and/or sequential designation of issues reproduced:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note about reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Fixed-length data elements of reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=534]">
+<p>ORIGINAL VERSION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry of original:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition statement of original:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Publication, distribution, etc. of original:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Physical description, etc. of original:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Series statement of original:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Key title of original:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Location of original:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note about original:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Introductory phrase:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title statement of original:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=535]">
+<p>LOCATION OF ORIGINALS/DUPLICATES NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Custodian:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Postal address:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Country:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Telecommunications address:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Repository location code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=536]">
+<p>FUNDING INFORMATION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Text of note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Contract number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Grant number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Undifferentiated number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Program element number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Project number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Task number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Work unit number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=537]">
+<p>SOURCE OF DATA NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Source of data note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=538]">
+<p>SYSTEM DETAILS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+System details note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=540]">
+<p>TERMS GOVERNING USE AND REPRODUCTION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Terms governing use and reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Jurisdiction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Authorization:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Authorized users:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=541]">
+<p>IMMEDIATE SOURCE OF ACQUISITION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Source of acquisition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Address:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Method of acquisition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of acquisition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Accession number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Owner:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Purchase price:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Extent:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Type of unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=543]">
+<p>SOLICITATION INFORMATION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Solicitation information note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=544]">
+<p>LOCATION OF OTHER ARCHIVAL MATERIALS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Custodian:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Address:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Country:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Provenance:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=545]">
+<p>BIOGRAPHICAL OR HISTORICAL DATA
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Biographical or historical data:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Expansion:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Uniform Resource Identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=546]">
+<p>LANGUAGE NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Language note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Information code or alphabet:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Source of note information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=547]">
+<p>FORMER TITLE COMPLEXITY NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Former title complexity note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Source of note information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=550]">
+<p>ISSUING BODY NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Issuing body note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Source of note information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=552]">
+<p>ENTITY AND ATTRIBUTE INFORMATION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Entity type label:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Entity type definition and source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Attribute label:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Attribute definition and source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Enumerated domain value:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Enumerated domain value definition and source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Range domain minimum and maximum:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Codeset name and source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Unrepresentable domain:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Attribute units of measurement and resolution:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Beginning date and ending date of attribute values:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Attribute value accuracy:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Attribute value accuracy explanation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Attribute measurement frequency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Entity and attribute overview:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Entity and attribute detail citation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Uniform Resource Identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Display note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=555]">
+<p>CUMULATIVE INDEX/FINDING AIDS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Cumulative index/finding aids note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Availability source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Degree of control:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Bibliographic reference:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Uniform Resource Identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=556]">
+<p>INFORMATION ABOUT DOCUMENTATION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Information about documentation note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=561]">
+<p>OWNERSHIP AND CUSTODIAL HISTORY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+History:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Time of collation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=562]">
+<p>COPY AND VERSION IDENTIFICATION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Identifying markings:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Copy identification:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Version identification:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Presentation format:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Number of copies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=565]">
+<p>CASE FILE CHARACTERISTICS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Number of cases/variables:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Name of variable:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Unit of analysis:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Universe of data:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Filing scheme or code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=567]">
+<p>METHODOLOGY NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Methodology note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=570]">
+<p>EDITOR NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Editor note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Source of note information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=571]">
+<p>VOLUNTEERS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Volunteers note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Special requirements:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=572]">
+<p>AFFILIATION AND OTHER RELATIONSHIPS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Affiliation and other relationships note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=573]">
+<p>CREDENTIALS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Credentials note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=574]">
+<p>TRANSPORTATION AND DIRECTIONS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Transportation and directions note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=575]">
+<p>ACCOMMODATIONS FOR THE DISABLED NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Accommodations for the disabled note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=576]">
+<p>SERVICES AVAILABLE NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Services available note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=580]">
+<p>LINKING ENTRY COMPLEXITY NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Linking entry complexity note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Source of note information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=581]">
+<p>PUBLICATIONS ABOUT DESCRIBED MATERIALS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Publications about described materials note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=582]">
+<p>RELATED COMPUTER FILES NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Related computer files note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=583]">
+<p>ACTION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Action:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Action identification:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Time of action:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Action interval:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Contingency for action:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Authorization:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Jurisdiction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Method of action:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Site of action:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Action agent:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Status:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Extent:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Type of unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Uniform Resource Identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=584]">
+<p>ACCUMULATION AND FREQUENCY OF USE NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Accumulation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Frequency of use:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=585]">
+<p>EXHIBITIONS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Exhibitions note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=586]">
+<p>AWARDS NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Awards note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=587]">
+<p>OTHER INFORMATION AVAILABLE NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Other information available note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=590]">
+<p>LOCAL NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Local note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Provenance:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Condition of individual reels:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=600]">
+<p>SUBJECT ADDED ENTRY--PERSONAL NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Personal name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Numeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Titles and other words associated with a name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Dates associated with a name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Attribution qualifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Fuller form of name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Form subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+General subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Chronological subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Geographic subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of heading or term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=610]">
+<p>SUBJECT ADDED ENTRY--CORPORATE NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Corporate name or jurisdiction name as entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Subordinate unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of meeting or treaty signing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section/meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Form subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+General subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Chronological subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Geographic subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of heading or term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=611]">
+<p>SUBJECT ADDED ENTRY--MEETING NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Meeting name or jurisdiction name as entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Number (BK CF MP MU SE VM MX):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Subordinate unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section/meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Name of meeting following jurisdiction name entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Form subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+General subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Chronological subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Geographic subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of heading or term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=630]">
+<p>SUBJECT ADDED ENTRY--UNIFORM TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of treaty signing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Form subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+General subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Chronological subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Geographic subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of heading or term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=650]">
+<p>SUBJECT ADDED ENTRY--TOPICAL TERM
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Topical term or geographic name as entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Topical term following geographic name as entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location of event:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Active dates:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Form subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+General subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Chronological subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Geographic subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of heading or term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=651]">
+<p>SUBJECT ADDED ENTRY--GEOGRAPHIC NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Geographic name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Geographic name following place entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Form subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+General subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Chronological subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Geographic subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of heading or term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=652]">
+<p>SUBJECT ADDED ENTRY--REVERSED GEOGRAPHIC
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Geographic name of place element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+General subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Chronological subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Geographic subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=653]">
+<p>INDEX TERM--UNCONTROLLED
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Uncontrolled term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=654]">
+<p>SUBJECT ADDED ENTRY--FACETED TOPICAL TERMS
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Focus term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Non-focus term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Facet/hierarchy designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Form subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Chronological subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Geographic subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of heading or term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Material specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=655]">
+<p>INDEX TERM--GENRE/FORM/PHYSICAL CHARACTERISTICS
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Genre/form/physical characteristics:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Non-focus term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Facet/hierarchy designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Form subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+General subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Chronological subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Geographic subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=656]">
+<p>INDEX TERM--OCCUPATION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Occupation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Form subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+General subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Chronological subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Geographic subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=657]">
+<p>INDEX TERM--FUNCTION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Function:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Form subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+General subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Chronological subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Geographic subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=658]">
+<p>INDEX TERM--CURRICULUM OBJECTIVE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main curriculum objective:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Subordinate curriculum objective:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Curriculum code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Correlation factor:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=700]">
+<p>ADDED ENTRY--PERSONAL NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Personal name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Numeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Titles and other words associated with a name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Dates associated with a name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Attribution qualifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Fuller form of name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=705]">
+<p>ADDED ENTRY--PERSONAL NAME (PERFORMER)
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Personal name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Numeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Titles and other words associated with a name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Dates associated with a name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=710]">
+<p>ADDED ENTRY--CORPORATE NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Corporate name or jurisdiction name as entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Subordinate unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of meeting or treaty signing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section/meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=711]">
+<p>ADDED ENTRY--MEETING NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Meeting name or jurisdiction name as entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Number (BK CF MP MU SE VM MX):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Subordinate unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section/meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Name of meeting following jurisdiction name entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=715]">
+<p>ADDED ENTRY--CORPORATE NAME-PERFORMING GROUP
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Corporate name or jurisdiction name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Subordinate unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section/meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Nonprinting information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=720]">
+<p>ADDED ENTRY--UNCONTROLLED NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=730]">
+<p>ADDED ENTRY--UNIFORM TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of treaty signing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=740]">
+
+	<p>
+ADDED ENTRY--UNCONTROLLED RELATED/ANALYTICAL TITLE
+		
+</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Uncontrolled related/analytical title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Institution to which field applies:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=752]">
+<p>ADDED ENTRY--HIERARCHICAL PLACE NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Country:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+State, province, territory:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+County, region, islands area:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+City:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=753]">
+<p>SYSTEM DETAILS ACCESS TO COMPUTER FILES
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Make and model of machine:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Programming language:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Operating system:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=754]">
+<p>ADDED ENTRY--TAXONOMIC IDENTIFICATION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Taxonomic name/taxonomic hierarchical category:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of taxonomic identification:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=755]">
+<p>ADDED ENTRY--PHYSICAL CHARACTERISTICS
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Access term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+General subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Chronological subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Geographic subdivision:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=760]">
+<p>MAIN SERIES ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Parallel title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=762]">
+<p>SUBSERIES ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Parallel title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=765]">
+<p>ORIGINAL LANGUAGE ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Parallel title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=767]">
+<p>TRANSLATION ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Parallel title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=770]">
+<p>SUPPLEMENT/SPECIAL ISSUE ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Parallel title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=772]">
+<p>PARENT RECORD ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Parallel title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=773]">
+<p>HOST ITEM ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Abbreviated title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=774]">
+<p>CONSTITUENT UNIT ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=775]">
+<p>OTHER EDITION ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Language code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Country code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Parallel title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=776]">
+<p>ADDITIONAL PHYSICAL FORM ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Parallel title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=777]">
+<p>ISSUED WITH ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Parallel title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=780]">
+<p>PRECEDING ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Parallel title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=785]">
+<p>SUCCEEDING ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Parallel title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=786]">
+<p>ISSUED WITH ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Period of content:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Abbreviated title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Source contribution:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=787]">
+<p>NONSPECIFIC RELATIONSHIP ENTRY
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Main entry heading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Edition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Qualifying information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Place, publisher, and date of publication:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Relationship information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Physical description of source:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Display text:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Series data for related item:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Material-specific details:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Other item identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Parallel title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Report number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Standard Technical Report Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+International Standard Serial Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+CODEN designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+International Standard Book Number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Control subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=800]">
+<p>SERIES ADDED ENTRY--PERSONAL NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Personal name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Numeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Titles and other words associated with a name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Dates associated with a name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Attribution qualifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Fuller form of name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Volume number/sequential designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=810]">
+<p>SERIES ADDED ENTRY--CORPORATE NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Corporate name or jurisdiction name as entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Subordinate unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of meeting or treaty signing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section/meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Volume number/sequential designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=811]">
+<p>SERIES ADDED ENTRY--MEETING NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Meeting name or jurisdiction name as entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Number (BK CF MP MU SE VM MX):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Subordinate unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section/meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Name of meeting following jurisdiction name entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Volume number/sequential designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=830]">
+<p>SERIES ADDED ENTRY--UNIFORM TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of treaty signing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Volume number/sequential designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=840]">
+<p>SERIES ADDED ENTRY--TITLE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Volume or number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=841]">
+<p>HOLDINGS CODED DATA VALUES
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Type of record:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Fixed-length data elements:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Encoding level:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=842]">
+<p>TEXTUAL PHYSICAL FORM DESIGNATOR
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Textual physical form designator:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=843]">
+<p>REPRODUCTION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Type of reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Place of reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Agency responsible for reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Physical description of reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Series statement of reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Dates of publication and/or sequential designation of issues reproduced:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Note about reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Fixed-length data elements of reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=844]">
+<p>NAME OF UNIT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Name of unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=845]">
+<p>TERMS GOVERNING USE AND REPRODUCTION NOTE
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Terms governing use and reproduction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Jurisdiction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Authorization:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Authorized users:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=850]">
+<p>HOLDING INSTITUTION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Holding institution:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Holdings:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Inclusive dates:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Retention statement:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=851]">
+<p>LOCATION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Name (custodian or owner):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Institutional division:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Street address:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Country:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Location of units:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Repository location code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=852]">
+<p>LOCATION/CALL NUMBER
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Location:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Sublocation or collection:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Shelving location:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Address:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Coded location qualifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+= Qualifier type:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+= Number of units 1-9:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+= Unit type:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Non-coded location qualifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Classification part:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Item part:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Shelving control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Call number prefix:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Shelving form of title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Call number suffix:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Country code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Piece designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Piece physical condition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Copyright article-fee code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Copy number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of classification or shelving scheme:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=853]">
+<p>CAPTIONS AND PATTERN--BASIC BIBLIOGRAPHIC UNIT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+First level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Second level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Third level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Fourth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Fifth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Sixth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Alternative numbering scheme, first level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Alternative numbering scheme, second level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+First level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Second level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Third level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Fourth level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Alternative numbering scheme, chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Copy:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Bibliographic units per next higher level:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Numbering continuity:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Frequency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Calendar change:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Regularity pattern:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=854]">
+<p>CAPTIONS AND PATTERN--SUPPLEMENTARY MATERIAL
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+First level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Second level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Third level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Fourth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Fifth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Sixth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Alternative numbering scheme, first level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Alternative numbering scheme, second level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+First level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Second level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Third level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Fourth level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Alternative numbering scheme, chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Type of supplementary material:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Copy:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Bibliographic units per next higher level:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Numbering continuity:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Frequency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Calendar change:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Regularity pattern:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=855]">
+<p>CAPTIONS AND PATTERN--INDEXES
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+First level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Second level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Third level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Fourth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Fifth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Sixth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Alternative numbering scheme, first level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Alternative numbering scheme, second level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+First level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Second level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Third level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Fourth level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Alternative numbering scheme, chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Type of index:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Copy:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Bibliographic units per next higher level:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Numbering continuity:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Frequency:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Calendar change:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Regularity pattern:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=856]">
+<p>ELECTRONIC LOCATION AND ACCESS
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Field link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Host name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Access number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Compression information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Path:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Electronic name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Uniform resource name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Processor of request:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Instruction:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Bits per second:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Password:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Logon:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Contact for access assistance:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Name of location of host in subfield $a:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Operating system:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Port:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Electronic format type :
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Settings:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+File size:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Terminal emulation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Uniform Resource Identifier:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Hours access method available:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Record control number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Link text :
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Access method:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=863]">
+
+	<p>
+ENUMERATION AND CHRONOLOGY--BASIC BIBLIOGRAPHIC UNIT
+		
+</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+First level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Second level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Third level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Fourth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Fifth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Sixth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Alternative numbering scheme, first level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Alternative numbering scheme, second level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+First level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Second level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Third level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Fourth level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Alternative numbering scheme, chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Converted Gregorian year:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Piece designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Piece physical condition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Copyright article-fee code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Copy number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Break indicator:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=864]">
+
+	<p>
+ENUMERATION AND CHRONOLOGY--SUPPLEMENTARY MATERIAL
+		
+</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+First level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Second level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Third level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Fourth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Fifth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Sixth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Alternative numbering scheme, first level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Alternative numbering scheme, second level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+First level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Second level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Third level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Fourth level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Alternative numbering scheme, chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Converted Gregorian year:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Title of supplementary material:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Piece designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Piece physical condition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Copyright article-fee code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Copy number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Break indicator:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=865]">
+<p>ENUMERATION AND CHRONOLOGY--INDEXES
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+First level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Second level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Third level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Fourth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Fifth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Sixth level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Alternative numbering scheme, first level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Alternative numbering scheme, second level of enumeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+First level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Second level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Third level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Fourth level of chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Alternative numbering scheme, chronology:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Converted Gregorian year:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Title of index:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Piece designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Piece physical condition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Copyright article-fee code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Copy number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Break indicator:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=866]">
+<p>TEXTUAL HOLDINGS--BASIC BIBLIOGRAPHIC UNIT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Textual string:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=867]">
+<p>TEXTUAL HOLDINGS--SUPPLEMENTARY MATERIAL
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Textual holdings:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=868]">
+<p>TEXTUAL HOLDINGS--INDEXES
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Textual holdings:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=870]">
+<p>VARIANT PERSONAL NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Personal name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Numeration:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Titles and other words associated with a name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Dates associated with a name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Tag and sequence number of the field for which 870 is a variant(R):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Fuller form of name:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=871]">
+<p>VARIANT CORPORATE NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Corporate name or jurisdiction name as entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Subordinate unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of meeting or treaty signing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Relator term:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Tag and sequence number of the field for which 871 is a variant(R):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section/meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=872]">
+<p>VARIANT CONFERENCE OR MEETING NAME
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Meeting name or jurisdiction name as entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Number (BK CF MP MU SE VM MX):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Location of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Subordinate unit:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Tag and sequence number of the field for which 872 is a variant(R):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section/meeting:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Name of meeting following jurisdiction name entry element:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Affiliation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Relator code:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=873]">
+<p>VARIANT UNIFORM TITLE HEADING
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Uniform title:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date of treaty signing:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Date of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Miscellaneous information:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Medium:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Tag and sequence number of the field for which 873 is a variant(R):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Form subheading:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Language of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Medium of performance for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Number of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Arranged statement for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Name of part/section of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Key for music:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Version:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Title of a work:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=876]">
+<p>ITEM INFORMATION--BASIC BIBLIOGRAPHIC UNIT
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Internal item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Invalid or cancelled internal item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Cost:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date acquired:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Source of acquisition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Use restrictions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Item status:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Temporary location:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Piece designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Invalid or cancelled piece designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Copy number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=877]">
+<p>ITEM INFORMATION--SUPPLEMENTARY MATERIAL
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Internal item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Invalid or cancelled internal item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Cost:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date acquired:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Source of acquisition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Use restrictions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Item status:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Temporary location:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Piece designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Invalid or cancelled piece designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Copy number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=878]">
+<p>ITEM INFORMATION--INDEXES
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Internal item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Invalid or cancelled internal item number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Cost:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Date acquired:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Source of acquisition:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Use restrictions:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Item status:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Temporary location:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Piece designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Invalid or cancelled piece designation:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Copy number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Nonpublic note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Public note:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Materials specified:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Link and sequence number:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=880]">
+<p>ALTERNATE GRAPHIC REPRESENTATION
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Linkage:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='0']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='1']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Same as associated field:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Undefined; each contains blank (#):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Undefined; each contains blank (#):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='9']">
+
+	<li>
+Undefined; each contains blank (#):
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+
+	<xsl:template match="marc:datafield[@tag=886]">
+<p>FOREIGN MARC INFORMATION FIELD
+		</p>
+
+	<ul>
+
+	<xsl:for-each select="marc:subfield[@code='a']">
+
+	<li>
+Tag of the foreign MARC field/Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='b']">
+
+	<li>
+Content of the foreign MARC field/Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='2']">
+
+	<li>
+Source of data:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='c']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='d']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='e']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='f']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='g']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='h']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='i']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='j']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='k']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='l']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='m']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='n']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='o']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='p']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='q']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='r']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='s']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='t']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='u']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='v']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='w']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='x']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='y']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='z']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='0']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='1']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='3']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='4']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='5']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='6']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='7']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='8']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+
+	<xsl:for-each select="marc:subfield[@code='9']">
+
+	<li>
+Foreign MARC subfield:
+				
+<xsl:value-of select="text()"/>
+</li>
+</xsl:for-each>
+</ul>
+</xsl:template>
+</xsl:stylesheet>
+
+	<!--
+ Stylus Studio meta-information - (c)1998-2002 eXcelon Corp.
+<metaInformation>
+<scenarios ><scenario default="no" name="Ray Charles" userelativepaths="yes" externalpreview="no" url="..\xml\MARC21slim\raycharles.xml" htmlbaseurl="" processortype="internal" commandline="" additionalpath="" additionalclasspath="" postprocessortype="none" postprocesscommandline="" postprocessadditionalpath="" postprocessgeneratedext=""/><scenario default="yes" name="s7" userelativepaths="yes" externalpreview="no" url="..\ifla\sally7.xml" htmlbaseurl="" processortype="internal" commandline="" additionalpath="" additionalclasspath="" postprocessortype="none" postprocesscommandline="" postprocessadditionalpath="" postprocessgeneratedext=""/></scenarios><MapperInfo srcSchemaPath="" srcSchemaRoot="" srcSchemaPathIsRelative="yes" srcSchemaInterpretAsXML="no" destSchemaPath="" destSchemaRoot="" destSchemaPathIsRelative="yes" destSchemaInterpretAsXML="no"/>
+</metaInformation>
+-->
Index: /gsdl/stable/etc/VERSION
===================================================================
--- /gsdl/stable/etc/VERSION	(revision 20131)
+++ /gsdl/stable/etc/VERSION	(revision 20131)
@@ -0,0 +1,3 @@
+gsdl version: svn-trunk
+svn tag: trunk
+build version: 2.1
Index: /gsdl/stable/etc/cronlock.txt
===================================================================
--- /gsdl/stable/etc/cronlock.txt	(revision 20131)
+++ /gsdl/stable/etc/cronlock.txt	(revision 20131)
@@ -0,0 +1,1 @@
+If you are receiving this message, it is because cron.pl has detected a cron.lck file. This may be because cron.pl is still executing. However, it may not be. If cron.lck is in error, please delete it. 
Index: /gsdl/stable/etc/dc2marc-mapping.xml
===================================================================
--- /gsdl/stable/etc/dc2marc-mapping.xml	(revision 20131)
+++ /gsdl/stable/etc/dc2marc-mapping.xml	(revision 20131)
@@ -0,0 +1,252 @@
+<Mapping>
+    <!-- English-->
+    <stopwords lang="en" >
+      <item  name="a " length="2"/>
+      <item  name="an " length="3"/>
+      <item  name="the " length="4"/>
+      <item  name="A " length="2"/>
+      <item  name="An " length="3"/>
+      <item  name="The " length="4"/>
+      <item  name="AN " length="3"/>
+      <item  name="THE " length="4"/>      
+    </stopwords>
+
+    <!--Spain-->
+    <stopwords lang="es">
+      <item  name="uno " length="4"/>
+      <item  name="una " length="4"/>
+      <item  name="el " length="3"/>
+      <item  name="la " length="3"/>
+      <item  name="las " length="4"/>
+      <item  name="los " length="4"/>
+      <item  name="un " length="3"/>
+      <item  name="unos " length="5"/>
+      <item  name="unas " length="5"/>
+    </stopwords>
+
+  <!--Catalan-->
+  <stopwords lang="ca">
+     <item  name="el " length="3"/>
+     <item  name="la " length="3"/>
+     <item  name="les " length="4"/>
+     <item  name="l'" length="2"/>
+     <item  name="un " length="3"/>
+     <item  name="una " length="4"/>
+     <item  name="uns " length="4"/>
+     <item  name="unes " length="5"/>
+     <item  name="es " length="3"/>
+     <item  name="sa " length="3"/>
+     <item  name="ses " length="4"/>
+     <item  name="sos " length="4"/>
+     <item  name="so " length="3"/>
+     <item  name="s'" length="2"/>
+   </stopwords>
+ 
+  <!--German-->  
+  <stopwords lang="de">
+     <item  name="der " length="4"/>
+     <item  name="ein " length="4"/>
+     <item  name="die " length="4"/>
+     <item  name="eine " length="5"/>
+     <item  name="das " length="4"/>
+   </stopwords>
+
+  <!--French-->
+  <stopwords lang="fr">
+     <item  name="le " length="3"/>
+     <item  name="la " length="3"/>
+     <item  name="les " length="4"/>
+     <item  name="un " length="3"/>
+     <item  name="une " length="4"/>
+     <item  name="l'" length="2"/>    
+  </stopwords>
+
+  <!--Italian-->  
+  <stopwords lang="it">
+     <item  name="il " length="3"/>
+     <item  name="lo " length="3"/>
+     <item  name="la " length="3"/>
+     <item  name="gli " length="4"/>
+     <item  name="le " length="3"/>
+     <item  name="un " length="3"/>
+     <item  name="uno " length="4"/>
+     <item  name="una " length="4"/>
+     <item  name="l'" length="2"/>
+     <item  name="un'" length="3"/>
+  </stopwords>
+
+   <!--Galician-->  
+  <stopwords lang="gl">
+     <item  name="o " length="2"/>
+     <item  name="os " length="3"/>
+     <item  name="a " length="2"/>
+     <item  name="as " length="3"/>
+     <item  name="un " length="3"/>
+     <item  name="uns " length="4"/>
+     <item  name="unha " length="5"/>
+     <item  name="unhas " length="6"/>
+   </stopwords> 
+    
+   <recordTypeMapping>
+       <type name="collection" mapping="p"/>
+       <type name="dataset" mapping="m"/>
+       <type name="event" mapping="r"/>
+       <type name="image" mapping="k"/>
+       <type name="interactive resource" mapping="m"/> 
+       <type name="service" mapping="m"/>
+       <type name="software" mapping="m"/>
+       <type name="sound" mapping="i"/>
+       <type name="text" mapping="a"/>      
+    </recordTypeMapping>
+
+    <leader> 
+       <recordLength pos="1" value="00000" />
+       <recordStatus pos="5" value="n" />
+       <recordType pos="6" value="a" />
+       <bibliographiclevel pos="7" value="m" />
+       <controlType pos="8" value=" " />
+       <codingScheme pos="9" value=" " />
+       <indicatorCount pos="10" value="2" />
+       <subfieldCodeCount pos="11" value="2" />
+       <dataBaseAddress pos="12" value="     " />
+       <encodingLevel pos="17" value="3" />
+       <descriptiveCatalogForm pos="18" value="u" />
+       <linkedRecordRequirement pos="19" value=" " />
+       <lpLength pos="20" value="4" />
+       <scpLength pos="21" value="5" />
+       <idLength pos="22" value="0" />
+       <emcpLength pos="23" value="0" /> 
+    </leader>
+        
+    <controlfield tag="001" value="the value of code 001" required="true" />
+    <controlfield tag="002" value="the value of code 002" required="false"/>
+    <controlfield tag="003" value="the value of code 003" required="true"/>
+    <controlfield tag="004" value="the value of code 004" required="false"/>
+    <controlfield tag="005" value="the value of code 005" required="false"/>
+    <controlfield tag="006" value="the value of code 006" required="false"/>
+    <controlfield tag="008" value="the value of code 008" required="true"/>    
+
+<!--this mapping provides duclin core to the following Marc fields mapping:   
+    024 |a[dc.Identifier]
+    245 |a[dc.Title]
+    246 |a[dc.Title] (repeated dc.Title)
+    260 |b[dc.Publisher] |c[dc.Date]
+    500 |a[dc.Coverage] 
+    520 |a[dc.Description]
+    540 |a[dc.Rights]
+    546 |a[dc.Language]
+    653 |a[dc.Subject]
+    655 |s[dc.Type]
+    720 |a[dc.Contributor] |a[dc.Creator]
+    787 |n[dc.Relation]
+    786 |n[dc.Source]
+    856 |q[dc.Format]
+-->
+
+ <!--if the first or second indicator is "nonfiling characters", 
+     one of subfields must have a "nonfiling" attribute with the "true" value
+     to indicate that the begining of this subfield is to be disregarded. 
+     see MarcField 245. 
+-->
+
+<!--If the marc field is same for the repeated metadata (the metadata for the first subfield),
+     set the "multiple" attibute to "true"     
+ -->
+
+<!--If the marc field is different for the repeated metadata (the metadata for the first subfield),
+     set the "repeat" attibute to "true"     
+ -->
+
+<!-- Title  --> 
+<!--
+ <MarcField multiple="false" tag="245" ind1="0" ind2="nonfiling">
+     <subfield code="a" nonfiling="true"  meta="dc.Title" punc=""/>
+ </MarcField>
+
+-->
+
+ <MarcField multiple="false" tag="245" ind1="0" ind2=" ">
+     <subfield code="a" meta="dc.Title" punc=""/>
+ </MarcField>
+
+<!--
+  <MarcField multiple="false" tag="245" ind1="0" ind2=" ">
+     <subfield code="a" meta="dc.Title" punc=""/>
+  </MarcField>
+-->
+
+
+ <MarcField repeat="true" tag="246" ind1="3" ind2="3" >
+     <subfield code="a" meta="dc.Title" punc=""/>
+  </MarcField>
+  
+<!--Coverage -->
+  <MarcField multiple="true" tag="500" ind1=" " ind2=" ">
+     <subfield code="a" meta="dc.Coverage" punc=""/>
+  </MarcField>
+    
+
+<!--Contributor-->
+   <MarcField multiple="true" tag="720" ind1=" " ind2=" ">
+     <subfield code="a" meta="dc.Contributor" punc=","/>
+   </MarcField>
+
+<!--Creator-->
+ <MarcField  multiple="true"  tag="720" ind1=" " ind2=" ">
+     <subfield code="a" meta="dc.Creator" punc=","/>
+ </MarcField>
+
+ <!--Publisher and  Date-->
+   <MarcField  multiple="false" tag="260" ind1=" " ind2=" ">
+     <subfield code="b" meta="dc.Publisher" punc=","/>
+     <subfield code="c" meta="dc.Date" punc=""/> 
+   </MarcField>
+
+ <!-- Descrption -->
+    <MarcField multiple="true" tag="520" ind1=" " ind2=" ">
+       <subfield code="a" meta="dc.Description" punc=""/> 
+    </MarcField>
+   
+  <!--Format -->
+     <MarcField multiple="true" tag="856" ind1=" " ind2=" ">
+       <subfield code="q" meta="dc.Format" punc=""/> 
+    </MarcField>
+   
+
+ <!--Identifier -->
+     <MarcField multiple="true" tag="024" ind1="8" ind2=" ">
+        <subfield code="b" meta="dc.Identifier" punc=""/>
+     </MarcField>
+
+ <!--Language-->
+ <MarcField  multiple="false" tag="546" ind1=" " ind2=" ">
+     <subfield code="a" meta="dc.Language" punc=""/>
+  </MarcField>
+        
+
+  <!-- relation -->
+   <MarcField  multiple="true" tag="787" ind1="0" ind2=" " >
+      <subfield code="n" meta="dc.Relation" punc=""/>
+   </MarcField>
+     
+  <!-- Right -->
+  <MarcField multiple="true" tag="540" ind1=" " ind2=" ">
+      <subfield code="a" meta="dc.Rights" punc=""/>
+  </MarcField>
+
+ <!-- subject --> 
+  <MarcField multiple="true" tag="653" ind1=" " ind2=" ">
+    <subfield code="a" meta="dc.Subject" punc=","/>
+  </MarcField>
+
+<!-- source -->
+ <MarcField multiple="true" tag="786" ind1="0" ind2=" ">
+     <subfield code="n" meta="dc.Source" punc=""/>
+ </MarcField>
+  
+
+ <!-- type -->
+  <MarcField multiple="true" tag="655" ind1=" " ind2="7">
+     <subfield code="a" meta="dc.Type" punc=","/>
+  </MarcField>
+</Mapping>
Index: /gsdl/stable/etc/dc2marc.xsl
===================================================================
--- /gsdl/stable/etc/dc2marc.xsl	(revision 20131)
+++ /gsdl/stable/etc/dc2marc.xsl	(revision 20131)
@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+      	 xmlns:xsltutil="xalan://org.nzdl.gsdl.ApplyXSLTUtil"
+         exclude-result-prefixes="xsltutil">
+
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:param name="mapping" />	
+
+  <xsl:template match="/">
+     <collection>
+           <xsl:apply-templates select="/MARCXML/MetadataList"/>
+      </collection>
+ </xsl:template>
+ 
+  <xsl:template match="MetadataList">
+       <xsl:variable name="lang" >
+       	<xsl:choose>      
+           <xsl:when test="Metadata[@name='dc.Language']">
+                <xsl:value-of select="Metadata[@name='dc.Language']"/>                    
+            </xsl:when>            
+            <!-- comment out this if you want to test dls.Language as well
+             <xsl:when test="Metadata[@name='dls.Language']">
+                <xsl:value-of select="Metadata[@name='dls.Language']"/>                    
+             </xsl:when>
+            -->
+            <xsl:when test="Metadata[@name='Language']">
+                  <xsl:value-of select="Metadata[@name='Language']"/>
+            </xsl:when>           
+           <!-- the defualt language is english --> 
+            <xsl:otherwise>
+                 <xsl:value-of select="en"/>	
+             </xsl:otherwise>
+           </xsl:choose>   
+       </xsl:variable>	
+      <xsl:variable name="item" select="$mapping/stopwords[@lang=$lang]/item"/>
+      <record>
+	  <xsl:apply-templates select="$mapping/leader">
+	     <xsl:with-param name="source" select="." />   
+	  </xsl:apply-templates>                 
+          <xsl:apply-templates select="$mapping/controlfield[@required='true']" /> 
+      	  <xsl:apply-templates select="$mapping/MarcField" >
+	      <xsl:with-param name="source" select="." /> 
+              <xsl:with-param name="item" select="$item" />   
+	  </xsl:apply-templates>                       
+      </record>   
+  </xsl:template>
+
+  <xsl:template match="leader">
+     <xsl:param  name="source" />	
+      <leader>
+         <xsl:for-each select="*">
+           <xsl:choose>
+             <xsl:when test="@pos='3' and count($source/Metadata[@name='dc.Type'])=1">
+                <xsl:apply-templates select="$mapping/recordTypeMapping/type[1]" mode="mapping-type" >
+                  <xsl:with-param name="dctype" select="$source/Metadata[@name='dc.Type'][1]/text()"/>     
+                </xsl:apply-templates>
+            </xsl:when> 
+            <xsl:when test="@pos='3' and count($source/Metadata[@name='dc.Type'])=2
+                                     and $source/Metadata[@name='dc.Type' and text()='collection']">
+                <xsl:apply-templates select="$mapping/recordTypeMapping/type[1]" mode="mapping-type" >
+                  <xsl:with-param name="dctype" select="$source/Metadata[@name='dc.Type' and text()!='collection']/text()"/>
+                </xsl:apply-templates>                     
+            </xsl:when> 
+             <xsl:when test="@pos='3' and count($source/Metadata[@name='dc.Type'])=2" >
+                <xsl:apply-templates select="$mapping/recordTypeMapping/type[1]" mode="mapping-type" >
+                  <xsl:with-param name="dctype" select="$source/Metadata[@name='dc.Type'][1]"/>
+                </xsl:apply-templates>                     
+            </xsl:when>   
+            <xsl:when test="@pos='3' and count($source/Metadata[@name='dc.Type'])>2 ">
+                  <xsl:value-of select="'m'"/>
+            </xsl:when> 
+            <xsl:when test="@pos='4' and $source/Metadata[@name='dc.Type' and text()='collection']">
+                <xsl:value-of select="'c'"/>
+            </xsl:when>
+            <xsl:otherwise>
+                 <xsl:value-of select="@value"/>	
+             </xsl:otherwise>
+           </xsl:choose>      
+         </xsl:for-each>
+       </leader>  
+  </xsl:template>
+
+    
+  <xsl:template match="type" mode="mapping-type">
+   <xsl:param name="dctype" />  
+     <xsl:variable name="typename" select="@name"/>    
+      <xsl:choose>     
+           <xsl:when test="$dctype=$typename or count(following-sibling::*)=0">
+               <xsl:choose>
+                 <xsl:when test="count(following-sibling::*) !=0 ">
+                     <xsl:value-of select="@mapping"/>                                      
+                 </xsl:when>                                      
+                 <xsl:otherwise>
+                       <xsl:value-of select="'a'"/>  
+                 </xsl:otherwise>               
+               </xsl:choose> 
+           </xsl:when>
+         <xsl:otherwise>
+             <xsl:apply-templates select="following-sibling::*[1]" mode="mapping-type" >
+                <xsl:with-param name="dctype" select="$dctype" />                   
+             </xsl:apply-templates>
+         </xsl:otherwise>
+      </xsl:choose>
+  </xsl:template>
+ 
+  <xsl:template match="controlfield">
+     <controlfield tag="{@tag}"><xsl:value-of select="@value"/></controlfield>  
+  </xsl:template>
+ 
+ 
+  <xsl:template match="MarcField">
+   <xsl:param  name="source" />  
+   <xsl:param  name="item" /> 
+   <xsl:variable name="this" select="."/> 
+   <xsl:choose>
+      <xsl:when test="@multiple='true'">
+        <xsl:variable name="meta" select="subfield[1]/@meta"/>       
+        <xsl:for-each select="$source/Metadata[@name=$meta]">
+         <xsl:apply-templates select="$this/subfield[1]" mode="testing"> 
+                <xsl:with-param name="pos" select="position()"/> 
+	        <xsl:with-param name="source" select="$source"/>
+                <xsl:with-param name="item" select="$item"/> 
+            </xsl:apply-templates>
+        </xsl:for-each>
+      </xsl:when>
+      <xsl:when test="@repeat='true'">
+        <xsl:variable name="meta" select="subfield[1]/@meta"/>
+        <xsl:for-each select="$source/Metadata[@name=$meta][position()!=1]">
+           <xsl:apply-templates select="$this/subfield[1]" mode="testing"> 
+               <xsl:with-param name="pos" select="position()+1"/> 
+	       <xsl:with-param name="source" select="$source"/>
+               <xsl:with-param name="item" select="$item"/>  
+            </xsl:apply-templates>
+        </xsl:for-each>
+      </xsl:when>
+       <xsl:otherwise>
+         <xsl:apply-templates select="subfield[1]" mode="testing">
+           <xsl:with-param name="pos" select="'0'"/> 
+	   <xsl:with-param name="source" select="$source"/> 
+           <xsl:with-param name="item" select="$item"/>  
+         </xsl:apply-templates>
+       </xsl:otherwise> 
+    </xsl:choose>        
+  </xsl:template>
+  
+  <xsl:template match="subfield" mode="testing">
+     <xsl:param name="pos"/>
+     <xsl:param  name="source" /> 
+     <xsl:param  name="item" />
+     <xsl:variable name="meta" select="@meta"/>
+     <xsl:choose>     
+       <xsl:when test="count($source/Metadata[@name=$meta]) >0">
+          <datafield>
+             <xsl:apply-templates select="../@*" mode="mapping-attribute">
+               <xsl:with-param name="source" select="$source"/>
+                <xsl:with-param name="item" select="$item"/>
+             </xsl:apply-templates>                                      
+             <xsl:apply-templates select="../subfield[not(@nonfiling)]" >                       
+               <xsl:with-param name="pos" select="$pos"/> 
+               <xsl:with-param name="source" select="$source"/>
+             </xsl:apply-templates>   
+         </datafield>
+       </xsl:when>
+       <xsl:otherwise>
+             <xsl:apply-templates select="following-sibling::*[1]" mode="testing" >
+                    <xsl:with-param name="pos" select="$pos"/> 
+            	    <xsl:with-param name="source" select="$source"/>
+                    <xsl:with-param name="item" select="$item"/>
+             </xsl:apply-templates> 
+         </xsl:otherwise>
+      </xsl:choose>       
+  </xsl:template>
+  
+
+  <xsl:template match="@*" mode="mapping-attribute" >
+     <xsl:param name="source" />
+     <xsl:param name="item" /> 	
+     <xsl:variable name="name" select="name()"/>
+     <xsl:variable name="value" select="."/>
+     <xsl:choose> 
+     <xsl:when test="starts-with($name,'ind') and $value='nonfiling'">
+         <xsl:variable name="meta" select="../subfield[@nonfiling='true']/@meta"/>
+         <xsl:variable name="content" select="$source/Metadata[@name=$meta]/text()"/>  
+         <xsl:apply-templates select="$item[1]" mode="mapping-item">
+             <xsl:with-param name='name' select="$name"/>
+             <xsl:with-param name='content' select="$content"/>
+             <xsl:with-param name='subfield' select="../subfield[@nonfiling='true']"/>
+	     <xsl:with-param name='source' select="$source"/>
+         </xsl:apply-templates>     
+      </xsl:when>
+      <xsl:otherwise>      
+        <xsl:if test="starts-with($name,'ind') or starts-with($name,'tag') ">
+          <xsl:call-template name="addAttribute" >
+             <xsl:with-param name='name' select="$name"/>
+             <xsl:with-param name='value' select="$value"/>         
+          </xsl:call-template>    
+        </xsl:if>
+      </xsl:otherwise>   
+    </xsl:choose> 
+ </xsl:template>
+
+  
+ <xsl:template match="item" mode="mapping-item">
+     <xsl:param name="name" />
+     <xsl:param name="content" />
+     <xsl:param name="subfield" />
+     <xsl:param name="source" />
+
+  <xsl:variable name="itemname" select="@name"/>
+  <xsl:variable name="lowercasecontent" select="xsltutil:toLowerCase($content)"/>		
+      <xsl:choose>     
+           <xsl:when test="starts-with($lowercasecontent,$itemname) or count(following-sibling::*)=0">
+               <xsl:choose>
+                 <xsl:when test="starts-with($lowercasecontent,$itemname)" >              
+                      <xsl:call-template name="addAttribute" >
+                         <xsl:with-param name="name" select="$name"/>
+                         <xsl:with-param name="value" select="@length"/>         
+                      </xsl:call-template>          
+                      <xsl:apply-templates select="$subfield" >
+                         <xsl:with-param name="length" select="@length" />
+                         <xsl:with-param name="content" select="$content" />
+	                 <xsl:with-param name="source" select="$source" />                  
+                      </xsl:apply-templates>
+                 </xsl:when>                                      
+                 <xsl:otherwise>
+                      <xsl:call-template name="addAttribute" >
+                          <xsl:with-param name="name" select="$name"/>
+                          <xsl:with-param name="value" select="'0'"/>         
+                      </xsl:call-template>          
+                      <xsl:apply-templates select="$subfield" >
+                          <xsl:with-param name="length" select="'0'" />
+                          <xsl:with-param name="content" select="$content" />
+                          <xsl:with-param name="source" select="$source" />                   
+                      </xsl:apply-templates>  
+                 </xsl:otherwise>               
+               </xsl:choose> 
+           </xsl:when>
+         <xsl:otherwise>
+             <xsl:apply-templates select="following-sibling::*[1]" mode="mapping-item" >
+                <xsl:with-param name="name" select="$name" />
+                <xsl:with-param name="content" select="$content" />
+                <xsl:with-param name="subfield" select="$subfield" />
+	        <xsl:with-param name="source" select="$source" />     
+             </xsl:apply-templates>
+         </xsl:otherwise>
+      </xsl:choose>
+  </xsl:template>
+
+  
+  <xsl:template name="addAttribute">
+      <xsl:param name="value" />
+      <xsl:param name="name" />
+      <xsl:attribute name="{$name}"><xsl:value-of select="$value"/></xsl:attribute>
+  </xsl:template>
+
+ 
+
+  <xsl:template match="subfield">
+     <xsl:param name="length" />
+     <xsl:param name="content" />
+     <xsl:param name="pos" />         
+     <xsl:param name="source" />
+     <xsl:variable name="meta" select="@meta" />
+     <xsl:variable name="punc" select="@punc" /> 
+     <xsl:if test="$source/Metadata[@name=$meta]">
+      <xsl:choose>
+        <xsl:when test="@nonfiling='true'">
+          <subfield code="{@code}"><xsl:value-of select="$content"/><xsl:value-of select="@punc"/></subfield>
+        </xsl:when>
+        <xsl:when test="$pos >0">
+           <subfield code="{@code}">
+                <xsl:value-of select="$source/Metadata[@name=$meta][$pos]"/><xsl:value-of select="$punc"/>
+           </subfield>
+        </xsl:when>
+        <xsl:otherwise>
+           <subfield code="{@code}">
+                <xsl:value-of select="$source/Metadata[@name=$meta]"/><xsl:value-of select="$punc"/>
+           </subfield> 
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>         
+  </xsl:template>
+  
+</xsl:stylesheet>
Index: /gsdl/stable/etc/main.cfg
===================================================================
--- /gsdl/stable/etc/main.cfg	(revision 20131)
+++ /gsdl/stable/etc/main.cfg	(revision 20131)
@@ -0,0 +1,291 @@
+# This file must be utf-8 encoded
+#
+# This is the main configuration file for configuring
+# your Greenstone receptionist (the bit responsible for the way
+# things are displayed) and contains information common
+# to the interface of all collections served by the site.
+
+# Email address of the webmaster of this Greenstone installation
+# If maintainer is set to "NULL" EmailEvents and EmailUserEvents
+# will be disabled.
+maintainer      NULL
+
+# Outgoing (SMTP) mail server for this Greenstone installation.
+# This will default to mail.maintainer-domain if it's not set
+# (i.e. if maintainer is greenstone@cs.waikato.ac.nz then MailServer
+# will default to mail.cs.waikato.ac.nz). If MailServer doesn't
+# resolve to a valid SMTP server then the EmailEvents and
+# EmailUserEvents options (see below) won't be functional. Likewise,
+# turning off EmailEvents and EmailUserEvents will remove any 
+# reliance on MailServer.
+MailServer      NULL
+
+# Set status to "enabled" if you want the Maintenance and
+# Administration facility to be available.
+status  	disabled
+
+# Set collector to "enabled" if you want the "collector"
+# end-user collection building facility to be available.
+# This allows creation of new collections via a web interface.
+# No longer maintained.
+collector       disabled
+
+# Set depositor to "enabled" if you want the "depositor"
+# (aka institutional repository) facility to be available.
+# This enables addition of new documents and metadata to existing collections
+depositor       disabled
+
+# Set gliapplet to "enabled" if you want remote users
+# to be able to build collections on your server through an applet
+# version of GLI
+gliapplet       disabled
+
+# Set logcgiargs to "true" to keep a log of usage information in
+# $GSDLHOME/etc/usage.txt.
+logcgiargs      false
+
+# Set usecookies to "true" to use cookies to identify users (cookie 
+# information will be written to the usage log if logcgiargs is
+# true).
+usecookies      false
+
+# LogDateFormat sets the format that timestamps will be stored in the usage
+# log (i.e. if logcgiargs is enabled). It takes the following values:
+# LocalTime: (the default) The local time and date in the form 
+#            "Thu Dec 07 23:47:00 NZDT 2000".
+# UTCTime: Coordinated universal time (GMT) in the same format as LocalTime.
+# Absolute: Integer value representing the number of seconds since 
+#           00:00:00 1/1/1970 GMT
+LogDateFormat   LocalTime
+
+# Log any events that Greenstone deems important in 
+# $GSDLHOME/etc/events.txt. 
+# The only events that are currently implemented come from the 
+# collector (e.g. someone just built/deleted the following collection)
+# LogEvents may take values of:
+# AllEvents: All important events
+# CollectorEvents: Just those events originating from the collector
+#                  (e.g. someone just built a collection)
+# disabled: Don't log events
+LogEvents       disabled
+
+# Email the maintainer whenever any event occurs. EmailEvents
+# takes the same values as LogEvents.
+# Note that perl must be installed for EmailEvents or
+# EmailUserEvents to work.
+EmailEvents     disabled
+
+# In some cases it may be appropriate to email the user about a
+# certain event (e.g. notification from the collector that a collection
+# was built successfully)
+EmailUserEvents false
+
+
+# The list of display macro files used by this receptionist
+macrofiles      tip.dm style.dm base.dm query.dm help.dm pref.dm about.dm \
+                document.dm browse.dm status.dm authen.dm users.dm html.dm \
+                extlink.dm gsdl.dm extra.dm home.dm collect.dm deposit.dm docs.dm \
+		bsummary.dm gti.dm gli.dm nav_css.dm languages.dm dynamicclassifier.dm \
+		english.dm english2.dm french.dm french2.dm spanish.dm \
+		spanish2.dm russian.dm russian2.dm \
+		amharic.dm amharic2.dm arabic.dm arabic2.dm armenian.dm armenian2.dm \
+		bengali.dm bulgarian.dm \
+		catalan.dm catalan2.dm chinese-trad.dm chinese-trad2.dm \
+		chinese.dm chinese2.dm croatian.dm czech.dm czech2.dm dari.dm \
+		dutch.dm farsi.dm farsi2.dm finnish.dm gaelic.dm \
+		galician.dm galician2.dm \
+		georgian.dm georgian2.dm german.dm german2.dm greek.dm gujarati.dm hebrew.dm \
+		hindi.dm hungarian.dm hungarian2.dm indo.dm indo2.dm \
+		italian.dm italian2.dm japanese.dm japanese2.dm \
+		kannada.dm kazakh.dm kazakh2.dm kirghiz.dm  \
+		latvian.dm latvian2.dm malayalam.dm malayalam2.dm maori.dm \
+		marathi.dm marathi2.dm \
+		mongolian.dm mongolian2.dm nepali.dm polish.dm port-br.dm port-pt.dm \
+		pushto.dm romanian.dm romanian2.dm serbian.dm sinhalese.dm \
+		slovak.dm slovak2.dm tamil.dm telugu.dm thai.dm thai2.dm \
+		turkish.dm turkish2.dm ukrainian.dm urdu.dm urdu2.dm \
+		vietnamese.dm vietnamese2.dm
+		  
+
+# Define the interface languages and encodings supported by this receptionist
+
+# An "Encoding" line defines an encoding to be used by the receptionist.
+# Uncomment "Encoding" lines to include an encoding on your "preferences" page.
+# Encoding line options are:
+# shortname -- The standard charset label for the given encoding. The
+#              shortname option is mandatory.
+# longname  -- The display name of the given encoding. If longname isn't set
+#              it will default to using shortname instead.
+# map       -- The name of the map file (i.e. the .ump file) for use when
+#              converting between unicode and the given encoding. The map
+#              option is mandatory for all encoding lines except the
+#              special case for utf8.
+# multibyte -- This optional argument should be set for all encodings that use
+#              multibyte characters.
+
+# The utf8 encoding is handled internally and doesn't require a map file.
+# As a rule the utf8 encoding should always be enabled, especially if you
+# have collections of documents that may not all be in the same
+# language/encoding.
+Encoding shortname=utf-8 "longname=Unicode (UTF-8)"
+
+# This is very experimental, and you almost certainly don't need it
+#Encoding shortname=utf-16be "longname=Unicode (UTF-16BE)"
+
+# The ISO-8859 series
+Encoding shortname=iso-8859-1 "longname=Western (ISO-8859-1)" map=8859_1.ump
+#Encoding shortname=iso-8859-2 "longname=Central European (ISO-8859-2)" map=8859_2.ump
+#Encoding shortname=iso-8859-3 "longname=Latin 3 (ISO-8859-3)" map=8859_3.ump
+#Encoding shortname=iso-8859-4 "longname=Latin 4 (ISO-8859-4)" map=8859_4.ump
+#Encoding shortname=iso-8859-5 "longname=Cyrillic (ISO-8859-5)" map=8859_5.ump
+#Encoding shortname=iso-8859-6 "longname=Arabic (ISO-8859-6)" map=8859_6.ump
+#Encoding shortname=iso-8859-7 "longname=Greek (ISO-8859-7)" map=8859_7.ump
+#Encoding shortname=iso-8859-8 "longname=Hebrew (ISO-8859-8)" map=8859_8.ump
+#Encoding shortname=iso-8859-9 "longname=Turkish (ISO-8859-9)" map=8859_9.ump
+#Encoding shortname=iso-8859-15 "longname=Western (ISO-8859-15)" map=8859_15.ump
+
+# Windows codepages
+Encoding shortname=windows-1250 "longname=Central European (Windows-1250)" map=win1250.ump
+Encoding shortname=windows-1251 "longname=Cyrillic (Windows-1251)" map=win1251.ump
+#Encoding shortname=windows-1252 "longname=Western (Windows-1252)" map=win1252.ump
+Encoding shortname=windows-1253 "longname=Greek (Windows-1253)" map=win1253.ump
+Encoding shortname=windows-1254 "longname=Turkish (Windows-1254)" map=win1254.ump
+Encoding shortname=windows-1255 "longname=Hebrew (Windows-1255)" map=win1255.ump
+Encoding shortname=windows-1256 "longname=Arabic (Windows-1256)" map=win1256.ump
+#Encoding shortname=windows-1257 "longname=Baltic (Windows-1257)" map=win1257.ump
+#Encoding shortname=windows-1258 "longname=Vietnamese (Windows-1258)" map=win1258.ump
+#Encoding shortname=windows-874 "longname=Thai (Windows-874)" map=win874.ump
+#Encoding shortname=cp866 "longname=Cyrillic (DOS)" map=dos866.ump
+#Encoding shortname=cp850 "longname=Latin-1 (DOS)" map=dos850.ump
+#Encoding shortname=cp852 "longname=Central European (DOS)" map=dos852.ump
+
+# KOI8 Cyrillic encodings
+#Encoding shortname=koi8-r "longname=Cyrillic (KOI8-R)" map=koi8_r.ump
+#Encoding shortname=koi8-u "longname=Cyrillic (KOI8-U)" map=koi8_u.ump
+
+# CJK encodings (note that Shift-JIS Japanese isn't currently supported)
+Encoding shortname=gbk "longname=æ±è¯­ (Chinese Simplified GBK)" map=gbk.ump multibyte
+Encoding shortname=big5 "longname=æŒ¢èª (Chinese Traditional Big5)" map=big5.ump multibyte
+Encoding shortname=euc-jp "longname=Japanese (EUC)" map=euc_jp.ump multibyte
+Encoding shortname=euc-kr "longname=Korean (UHC)" map=uhc.ump multibyte
+
+
+# A "Language" line defines an interface language to be used by the
+# interface. Note that it is possible to display only a subset of the
+# specified languages on the preferences page for a given collection by
+# using the "PreferenceLanguages" format option in your collect.cfg
+# configuration file.
+# Arguments are:
+# shortname        -- ISO 639 two letter language symbol. The shortname
+#                     argument is mandatory.
+# longname         -- The display name for the given language. If longname
+#                     isn't set it will default to using shortname instead.
+# default_encoding -- The encoding to use by default when using the given
+#                     interface language. This should be set to the
+#                     "shortname" of a valid "Encoding" line
+Language shortname=am longname=Amharic default_encoding=utf-8
+Language shortname=ar longname=Arabic default_encoding=windows-1256
+Language shortname=bg longname=Bulgarian default_encoding=utf-8
+Language shortname=bn "longname=àŠ¬àŠŸàŠàŠ²àŠŸ (Bengali)" default_encoding=utf-8
+Language shortname=ca "longname=CatalÃ  (Catalan)" default_encoding=utf-8
+Language shortname=cs "longname=Äesky (Czech)" default_encoding=utf-8
+Language shortname=de "longname=Deutsch (German)" default_encoding=utf-8
+Language shortname=el "longname=ÎÎ»Î»Î·ÎœÎ¹ÎºÎ¬ (Greek)" default_encoding=windows-1253
+Language shortname=gu "longname=àªà«àªàª°àªŸàª€à« (Gujarati)" default_encoding=utf-8
+Language shortname=en longname=English default_encoding=utf-8
+Language shortname=es "longname=EspaÃ±ol (Spanish)" \
+	 default_encoding=utf-8
+Language shortname=fa longname=Farsi default_encoding=utf-8
+Language shortname=fi longname=Finnish default_encoding=utf-8
+Language shortname=fr "longname=FranÃ§ais (French)" \
+	default_encoding=utf-8
+Language shortname=gd "longname=Gaelic (Scottish)" default_encoding=utf-8
+Language shortname=gl longname=Galician default_encoding=utf-8
+Language shortname=he longname=Hebrew default_encoding=windows-1255
+Language shortname=hi longname=Hindi default_encoding=utf-8
+Language shortname=hr longname=Croatian default_encoding=windows-1250
+Language shortname=hu longname=Hungarian default_encoding=utf-8
+Language shortname=hy longname=Armenian default_encoding=utf-8
+Language shortname=id "longname=Bahasa Indonesia (Indonesian)" default_encoding=utf-8
+Language shortname=it longname=Italiano default_encoding=utf-8
+Language shortname=ja "longname=æ¥æ¬èª (Japanese)" default_encoding=utf-8
+Language shortname=ka longname=Georgian default_encoding=utf-8
+Language shortname=kk "longname=ÒÐ°Ð·Ð°Ò (Kazakh)" default_encoding=utf-8
+Language shortname=kn longname=Kannada default_encoding=utf-8
+Language shortname=ky "longname=ÐÑÑÐ³ÑÐ·ÑÐ° (Kirghiz)" default_encoding=utf-8
+Language shortname=lv longname=Latvian default_encoding=utf-8
+Language shortname=mi "longname=MÄori" default_encoding=utf-8
+Language shortname=ml "longname=Malayalam" default_encoding=utf-8
+Language shortname=mr "longname=Marathi" default_encoding=utf-8
+Language shortname=mn "longname=ÐÐŸÐœÐ³ÐŸÐ» (Mongolian)" default_encoding=utf-8
+Language shortname=ne "longname=à€šà¥à€ªà€Ÿà€² (Nepali)" default_encoding=utf-8
+Language shortname=nl "longname=Nederlands (Dutch)" default_encoding=utf-8
+Language shortname=pl "longname=Polski (Polish)" default_encoding=utf-8
+Language shortname=prs "longname=Dari" default_encoding=utf-8
+Language shortname=ps "longname=Pushto" default_encoding=utf-8
+Language shortname=pt-br "longname=PortuguÃªs-BR (Brasil)" \
+	default_encoding=utf-8
+Language shortname=pt-pt "longname=PortuguÃªs-PT (Portugal)" \
+	default_encoding=utf-8
+Language shortname=ro longname=Romanian default_encoding=utf-8
+Language shortname=ru "longname=ÑÑÑÑÐºÐžÐ¹ (Russian)" default_encoding=windows-1251
+Language shortname=si "longname=à·à·à¶à·à¶œ (Sinhala)" default_encoding=utf-8
+Language shortname=sk "longname=SlovenÄina (Slovak)" default_encoding=utf-8
+Language shortname=sr longname=Serbian default_encoding=utf-8
+Language shortname=ta longname=Tamil default_encoding=utf-8
+Language shortname=te longname=Telugu default_encoding=utf-8
+Language shortname=th longname=Thai default_encoding=utf-8
+Language shortname=tr longname=Turkish default_encoding=windows-1254
+Language shortname=uk longname=Ukrainian default_encoding=utf-8
+Language shortname=ur longname=Urdu default_encoding=utf-8
+Language shortname=vi "longname=Tiáº¿ng Viá»t (Vietnamese)" default_encoding=utf-8
+Language shortname=zh "longname=ç®äœäž­æ (Simplified Chinese)" default_encoding=gbk
+Language shortname=zh-tr "longname=ç¹é«äž­æ (Traditional Chinese)" default_encoding=big5
+
+
+# Define any additional page parameters to be used by the above macro files
+# (the current default page parameters are c (collection) and l (language)
+
+# Define v (version -- text or graphic) page parameter and give it a default
+# value of 0 (0 = text version off)
+pageparam       v 0
+
+# Set the precedence given to the page parameters. This effects which macro 
+# will be selected for display when there are multiple versions of the same 
+# macro with different page parameters.
+# e.g. Given a macroprecedence of "c,v,l" and the following macro definitions:
+# _content_ []
+# _content_ [l=en]
+# _content_ [c=demo]
+# _content_ [v=1]
+# _content_ [l=fr,v=1,c=hdl]
+# If the corresponding cgi arguments were set to l=en&v=1&c=hdl then the
+# _content_[v=1] macro would be selected for display. It would be selected 
+# ahead of the _content_[l=en] macro because "v" has a higher precedence 
+# than "l". The _content_[l=fr,v=1,c=hdl] macro would not be selected 
+# because one of the page parameters is completely wrong ("l").
+macroprecedence c,v,l
+
+
+# Define any additional cgi arguments. Most cgi arguments are built into
+# Greenstone but it's possible to define them here (or set defaults for
+# existing built-in cgi arguments).
+
+# define the "v" cgi argument (to correspond to the "v" page parameter defined
+# above).
+cgiarg          shortname=v longname=version multiplechar=false argdefault=0 \
+                defaultstatus=weak savedarginfo=must
+
+# set a default value for the built-in "a" cgi argument
+cgiarg          shortname=a argdefault=p
+
+# set a default value for the built-in "p" cgi argument
+cgiarg          shortname=p argdefault=home
+
+# set the default encoding to utf-8
+cgiarg          shortname=w argdefault=utf-8
+
+# If you want an intermediate page to warn users that they've clicked on 
+# an external link, then uncomment the following line
+#cgiarg		shortname=el argdefault=prompt
+
Index: /gsdl/stable/etc/marc2dc.txt
===================================================================
--- /gsdl/stable/etc/marc2dc.txt	(revision 20131)
+++ /gsdl/stable/etc/marc2dc.txt	(revision 20131)
@@ -0,0 +1,83 @@
+#
+# This file is used by MARCPlug for mapping MARC field numbers to
+# Dublin Core metadata.
+#
+# The field numbers listed in this file are for USMARC / MARC21.
+#
+# Lines beginning with "#" are comments.
+# The format for these files are:
+#  <number> -> GreenstoneMetadataName
+#
+# This is based on the Library of Congress MARC -> Dublin Core mapping as 
+# found at  http://www.loc.gov/marc/marc2dc.html
+#
+# The problem with that is that some mappings are conditional on
+# subfield values...
+
+### Contributor	###
+
+### Coverage	###
+651, 662 -> dc.Coverage
+751, 752 -> dc.Coverage
+
+### Creator	###
+# Note, the LOC crosswalk uses dc.Contributor instead of dc.Creator
+720 -> dc.Creator
+100, 110, 111	-> dc.Creator
+700, 710, 711 -> dc.Creator
+
+### Date	###
+# Control field substring, not currently supported by mapping
+# 008/07-10		  -> dc.Date 
+260$c$g     -> dc.Date
+
+### Description	###
+# 520 = "Summary, Note"
+500-505, 507-529 -> dc.Description
+531-539, 541-545, 547-599 -> dc.Description
+
+### Format ###
+340 -> dc.Format
+856$q -> dc.Format
+
+### Identifier	###
+020$a, 022$a, 024$a  -> dc.Identifier
+856$q -> dc.Identifier
+
+### Language	###
+# Control field substring, not currently supported by mapping
+# 008/35-37		  -> dc.Language		# ISO 639-2 encoding 
+
+041$a$b$d$e$f$g$h$j -> dc.Language
+546 -> dc.Language
+
+### Publisher	###
+260$a$b -> dc.Publisher
+
+### Relation	###
+# 787 = "Nonspecific Relationship Note"
+787$o$t -> dc.Relation
+530, 760-785 -> dc.Relation
+## should be the following, but what does this mean??
+# 530, 760-787$o$t -> dc.Relation
+
+### Rights	###
+506, 540 -> dc.Rights
+
+### Source	###
+786$o$t -> dc.Source
+534$t -> dc.Source
+
+### Subject	###
+#050, 060, 080, 082 -> dc.Subject
+600, 610, 611, 630, 650, 653 -> dc.Subject
+
+### Title	###
+245, 246	-> dc.Title
+
+
+### Type	###
+655 -> dc.Type
+# Leader fields not currently supported by mapping
+# Leader06, Leader07	  -> dc.Type		
+
Index: /gsdl/stable/etc/marc2qdc.txt
===================================================================
--- /gsdl/stable/etc/marc2qdc.txt	(revision 20131)
+++ /gsdl/stable/etc/marc2qdc.txt	(revision 20131)
@@ -0,0 +1,91 @@
+
+
+# The following mapping is based on the Library of Congress crosswalk given at:
+#   http://www.loc.gov/marc/marc2dc.html
+
+245			  -> dc.Title				
+130, 210, 240, 242, 246	  -> dc.Title^alternative	
+730, 740		  -> dc.Title^alternative	
+
+# LOC crosswalk uses dc.Contributor...
+100, 110, 111		  -> dc.Creator			
+700, 710, 711		  -> dc.Creator			
+720			  -> dc.Creator
+
+# at later date might want to distinguish between
+# (LCSH encoding, 2nd indicator=0) and (MeSH encoding, 2nd indicator=2)
+600, 610, 611, 630, 650	  -> dc.Subject		        # LCSH or MeSH encoding	
+050			  -> dc.Subject		        # LCC encoding
+082			  -> dc.Subject			# DDC encoding
+080			  -> dc.Subject			# UDC encoding
+
+500-504, 507-519, 521-529 -> dc.Description
+531-539, 541-545, 547-599 -> dc.Description
+505			  -> dc.Description^tableofContents
+520			  -> dc.Description^abstract	# First indicator=3
+
+260$a$b			  -> dc.Publisher			
+
+260$c$g			  -> dc.Date^created		
+533$d			  -> dc.Date^created
+260$c			  -> dc.Date^issued
+# Control field substring, not currently supported by mapping
+# 008/07-10		  -> dc.Date^issued   
+
+# Leader fields not currently supported by mapping
+# Leader06, Leader07	  -> dc.Type			# DCMI Type Vocabulary
+655			  -> dc.Type			# Subfield $2=dct
+
+856$q			  -> dc.Format			# IMT encoding
+300$a			  -> dc.Format^extent
+533$e			  -> dc.Format^extent
+340$a			  -> dc.Format^medium
+
+856$u			  -> dc.Identifier		# URI encoding
+
+786$o			  -> dc.Source			# URI encoding
+
+# Control field substring, not currently supported
+# 008/35-37		  -> dc.Language		# ISO 639-2 encoding 
+041			  -> dc.Language		# ISO 639-2 encoding 
+546			  -> dc.Language		# RFC1766 encoding
+
+775			  -> dc.Relation^isVersionOf	
+786$n$t			  -> dc.Relation^isVersionOf	
+775,786$o		  -> dc.Relation^isVersionOf	# URI encoding
+775$n$t			  -> dc.Relation^hasVersion	
+775$o			  -> dc.Relation^hasVersion	# URL encoding
+785$n$t			  -> dc.Relation^isReplacedBy	
+785$o			  -> dc.Relation^isReplacedBy	# URL encoding
+780$n$t			  -> dc.Relation^replaces	
+780$o			  -> dc.Relation^replaces	# URL encoding
+538			  -> dc.Relation^requires	
+760	  		  -> dc.Relation^isPartOf	
+773$n$t			  -> dc.Relation^isPartOf	
+440,490,800,810,811,830	  -> dc.Relation^isPartOf
+760,773$o		  -> dc.Relation^isPartOf	# URL encoding
+774$n$t			  -> dc.Relation^hasPart		
+774$o			  -> dc.Relation^hasPart	# URL encoding
+510			  -> dc.Relation^isReferencedBy	
+776$n$t			  -> dc.Relation^isFormatOf	
+530			  -> dc.Relation^isFormatOf	
+776$o			  -> dc.Relation^isFormatOf	# URL encoding
+530$u			  -> dc.Relation^isFormatOf	# URL encoding
+776$n$t			  -> dc.Relation^hasFormat	
+530			  -> dc.Relation^hasFormat		
+776$o			  -> dc.Relation^hasFormat	# URL encoding
+530$u			  -> dc.Relation^hasFormat	# URL encoding
+
+522, 651		  -> dc.Coverage^spatial		
+255			  -> dc.Coverage^spatial	# Some 255 information equivalent to DC encoding scheme but different syntax
+ 			
+650$z			  -> dc.Coverage^spatial
+752			  -> dc.Coverage^spatial
+
+043$c,044$c		  -> dc.Coverage^spatial	# ISO 3166 encoding
+651			  -> dc.Coverage^spatial	# Subfield $2=tgn # Encoding TGN
+513$b			  -> dc.Coverage^temporal	
+033$a			  -> dc.Coverage^temporal	
+
+506, 540		  -> dc.Rights			
+
Index: /gsdl/stable/etc/oai.cfg
===================================================================
--- /gsdl/stable/etc/oai.cfg	(revision 20131)
+++ /gsdl/stable/etc/oai.cfg	(revision 20131)
@@ -0,0 +1,105 @@
+# OAI Server Configuration
+
+# This is the main configuration file for configuring your Greenstone oai server.
+# The server is a cgi program called oaiserver (oaiserver.exe on Windows).
+# Some basic commands that you can send it are:
+# ....cgi-bin/oaiserver.cgi?verb=Identify
+# ....cgi-bin/oaiserver.cgi?verb=ListSets
+# ....cgi-bin/oaiserver.cgi?verb=ListMetadataFormats
+# ....cgi-bin/oaiserver.cgi?verb=ListIdentifiers&set=xxx (1.1 only)
+# ....cgi-bin/oaiserver.cgi?verb=ListIdentifiers&set=xxx&metadataPrefix=oai_dc (2.0 only)
+# ....cgi-bin/oaiserver.cgi?verb=ListRecords&set=xxx&metadataPrefix=oai_dc
+# ....cgi-bin/oaiserver.cgi?verb=GetRecord&identifier=xxx&metadataPrefix=oai_dc
+
+#The List verbs (ListSets, ListIdentifiers, ListRecords) all return a 
+#sequence of items. The 'resumeafter' paramter below indicates how many 
+#records to return - if this number is less than the number matching the 
+#request, then a resumption token is returned. To use this to get the 
+#next set of documents, you need to issue the same request again, with 
+#an additional parameter: resumptionToken=xxx
+#For example, 
+# ....cgi-bin/oaiserver.cgi?verb=ListRecords&set=demo&metadataPrefix=oai_dc&resumptionToken=gsdloai:demo,,11-
+
+# For more information about the OAI-PMH protocol, see 
+# http://www.openarchives.org/
+
+# Strings containing spaces should be enclosed in double quotes ""
+
+#the baseURL used by the oaiserver
+#Example: baseURL "http://your-domain-name/cgi-bin/oaiserver.cgi"
+baseURL "your-own-baseURL-goes-here"
+
+# the base address of gsdl directory
+#Example: baseDocRoot "http://your-domain-name/gsdl"
+baseDocRoot "your-own-base-document-root-goes-here"
+
+# The OAI repository name - human readable
+repositoryName ""
+
+# The central administrative email address for the repository.
+maintainer  ""
+
+# Which version of OAI the repository supports, 1.1 or 2.0
+# (The server supports both)
+oaiversion "2.0"
+
+# How many records to output before needing a resumption token
+# A value of -1 will return all records for a request
+resumeafter  -1
+
+# Other free text items describing the repository. There is no restriction 
+# on the number of items, or item names
+# The format is like the following:
+# oaiinfo "item name" "item value"
+# Examples may include sponsor, purpose, size...
+
+# A list of collections that should be made available to OAI clients. By
+# default, collections are not available.
+# There can be more than one line: each line must start with oaicollection, 
+# and this is followed by one or more collection names. The collection name 
+# is the name of the collection's folder in the collect directory.
+oaicollection demo oai-e 
+
+# Metadata mapping information. At present, Greenstone's OAI server 
+# supports the following metadata formats.
+# oai_dc (OAI standard for Dublin Core)
+# gsdl_qdc (Greenstone format for Qualified Dublin Core)
+# rfc1807 (OAI standard for RFC 1807 format)
+
+# the list of metadata formats this server should support (Choose from the 
+# above list)
+oaimetadata oai_dc gsdl_qdc
+
+# Metadata in other formats must be mapped to these formats. This can be done 
+# in this file, or for a particular collection, in its collect.cfg file.
+
+# The format is like
+# oaimapping <greenstone fieldname> <metadataPrefix.fieldname>
+
+# The Greenstone field names can be unqualified (Title, Subject) or 
+# qualified by a namespace (dc.Title, dls.Subject). These mapping rules 
+# will apply to the entire repository. Collection specific rules can also 
+# be specified in this file using a collection name qualifier. This is 
+# the collection name followed by a colon (demo:Title, demo:dls.Title). 
+# Mappings specified in a collect.cfg file do not need the collection 
+# qualifier.
+
+# Details about the Dublin Core metadata format can be found at
+# http://dublincore.org/
+# Elements include Title, Creator, Subject, Description, Publisher, 
+# Contributor, Date, Type, Format, Identifier, Source, Language, 
+# Relation, Coverage, Rights
+
+# mappings for the dls metadata set
+# for dublin core (oai_dc metadata prefix)
+oaimapping dls.Title oai_dc.title
+oaimapping dls.Subject oai_dc.subject
+oaimapping dls.Language oai_dc.language
+oaimapping dls.Organization oai_dc.publisher
+# for qualified dublin core (gsdl_qdc metadata prefix)
+oaimapping dls.Title gsdl_qdc.title
+oaimapping dls.Subject gsdl_qdc.subject
+oaimapping dls.Language gsdl_qdc.language
+oaimapping dls.Organization gsdl_qdc.publisher
+
+
Index: /gsdl/stable/etc/packages/example.dbi
===================================================================
--- /gsdl/stable/etc/packages/example.dbi	(revision 20131)
+++ /gsdl/stable/etc/packages/example.dbi	(revision 20131)
@@ -0,0 +1,109 @@
+# -*- perl -*-
+# This is an example configuration file for greenstone's DBPlug
+# (DataBase plugin).
+#
+# This config file should be a fragment of perl, specifying how to
+# get records out of a database. This uses perl's DBI module, which
+# includes back-ends for mysql, postgresql, comma separated values (CSV),
+# MS Excel, ODBC, sybase, etc...
+#
+# You need to install the separate backends - For example, on debian you
+# need the libdbi-perl base package and then the libdbd-mysql-perl,
+# libdbd-csv-perl, libdbd-pg-perl and/or libdbd-sybase-perl (etc) packages.
+
+
+# debugging. Set to 0 if you don't want extra information printed
+# out during greenstone's import process.
+#
+$dbplug_debug=1;
+
+
+# If these are commented out, then we will use the plugin's defaults.
+# However, you might want to override them here if you know what they
+# are for this particular database
+# run "$ pluginfo.pl DBPlug | less" to see a list of valid encodings
+# Language metadata isn't really necessary unless you want indexes by language
+# However, Encoding is important, for converting data to utf8
+#
+
+$language = "en";
+$encoding = "iso_8859_1";
+
+
+# Data Source.
+# This is going to be dependent on which back-end you use. Note that these
+# strings are case-sensitive.
+# Eg, for postgres, it is "DBI:Pg:dbname=<database>".
+# For mysql, it might look like "DBI:mysql:database=<database>;host=localhost"
+# For the CSV (comma-separated values text-file) backend, try something like
+#   'DBI:CSV:f_dir=/path/to/directory/containing/csvfile;csv_quote_char=\";csv_sep_char=	'
+# with an embedded tab character for tab-separated instead of the
+# default comma-separated.
+
+$db='';
+
+# If you need a username and password to connect to this database,
+# uncomment these lines and fill in the details
+#
+#$username='';
+#$password='';
+
+# DBI does not allow you to use multiple SQL statements at once. So if
+# you want to execute two statements (for example, to prep the data by
+# creating a temporary table), uncomment and use this as the first statement.
+ 
+#$sql_query_prime = 'CREATE TEMP TABLE foo AS
+# SELECT t1.ID, t2.name
+# FROM table1 AS t1 JOIN table2 AS t2
+# ON t1.ID = t2.ID ';
+
+# sql query required to get your rows out of the database. Each row will
+# become a separate greenstone document.
+#
+#$sql_query = 'SELECT id, name, data FROM foo JOIN table2 WHERE something';
+# For CSV, the table name is the file name. Eg:
+#$sql_query = 'SELECT * FROM values.txt'
+# CSV may also require DOS '\r\n'-style line endings instead of unix '\n'.
+# It is easier if your data file does not have a dot '.' in it, as that is
+# not a valid character in an SQL table name (although it works for simple
+# SELECTS but not joins).
+
+$sql_query='';
+
+# a map of database field names to Greenstone metadata field names.
+# You should have a "Title" field and a "text" field, at a minimum.
+# If you want to give records a unique identifier from a database field
+# rather than have greenstone perform a hash on the document, also provide
+# an "Identifier" metadata field.
+# If you do map something to Identifier, make sure that the field is unique
+# for each record, and also note that because greenstone does special things
+# if this field is only numeric, DBPlug will add some letters to the front
+# if this is the case.
+#
+#%db_to_greenstone_fields=(
+#			  "name" => "Title",
+#			  "data" => "text",
+#			  "id" => "Identifier"
+#			  );
+
+%db_to_greenstone_fields=(
+
+			  );
+
+# finally, you can declare subroutines here to post-process the fields
+# in case you want to do any mark up or processing of it. 
+# For example, you might want to do HTML formatting.
+# The subroutine's name should be the greenstone metadata field name,
+# followed by "_callback", and must end with "}" in the first column.
+#
+#sub text_callback {
+#    my $text=shift;
+#    # do markup stuff...
+#    return $text;
+#}
+#
+#sub Title_callback {
+#    my $title=shift;
+#    return ucfirst($title); # uppercase first letter
+#}
+
Index: /gsdl/stable/etc/packages/phind/stopword/en/brown.sw
===================================================================
--- /gsdl/stable/etc/packages/phind/stopword/en/brown.sw	(revision 20131)
+++ /gsdl/stable/etc/packages/phind/stopword/en/brown.sw	(revision 20131)
@@ -0,0 +1,2009 @@
+a
+aah
+aback
+abed
+abjectly
+ablaze
+ably
+abnormally
+aboard
+about
+abreast
+abroad
+abroade
+abruptly
+absently
+absentmindedly
+absolutely
+abstractly
+absurdly
+abundantly
+academically
+accidentally
+according
+accordingly
+accurately
+accusingly
+acourse
+acoustically
+across
+actively
+actually
+actuarially
+acutely
+adamantly
+additionally
+adequately
+administratively
+admirably
+admiringly
+admittedly
+adrift
+advantageously
+adversely
+advisedly
+afar
+affectingly
+affectionately
+affirmatively
+afield
+afloat
+afoot
+aforethought
+afresh
+after
+afterward
+afterwards
+aftuh
+again
+against
+agayne
+aggressively
+agilely
+agin
+ago
+agreeably
+agriculturally
+ah
+ahah
+ahead
+ahem
+ahn
+ai
+aimlessly
+airily
+ajar
+alarmingly
+alas
+albeit
+alertly
+algebraically
+alike
+all
+allegedly
+allso
+almost
+aloft
+alone
+along
+alongside
+aloud
+alreadeh
+already
+also
+alternately
+alternatively
+altho
+although
+altogether
+altruistically
+always
+am
+amazingly
+ambitiously
+ame
+amen
+amicably
+amid
+amidst
+among
+amongst
+amorphously
+amply
+amusedly
+amusingly
+an
+analogously
+analytically
+anatomically
+anciently
+and
+anesthetically
+anew
+angrily
+anhydrously
+ani
+annually
+another
+anti
+anxiously
+any
+anybody
+anye
+anyhow
+anymore
+anyone
+anyplace
+anythin
+anything
+anyway
+anyways
+anywhere
+apart
+apiece
+apologetically
+appallingly
+apparently
+appraisingly
+appreciably
+appreciatively
+apprehensively
+appropriately
+approvingly
+approximately
+aptly
+arbitrarily
+are
+aristocratically
+around
+arrogantly
+artfully
+artificially
+artistically
+as
+asham
+ashore
+aside
+askance
+askew
+asleep
+associatively
+assuredly
+astonishingly
+astray
+astride
+astronomically
+asunder
+asymmetrically
+asymptotically
+at
+atonally
+atop
+atrociously
+att
+atta
+attentively
+attractively
+audibly
+aurally
+auspiciously
+austerely
+authentically
+authoritatively
+automatically
+avidly
+aw
+away
+awaye
+awfully
+awhile
+awkwardly
+axially
+aye
+backstage
+backstairs
+backward
+backwards
+badly
+bah
+bannnnnng
+barely
+basically
+be
+beautifully
+because
+beefore
+been
+befoh
+before
+beforehand
+behahn
+behaviorally
+behind
+bein
+being
+beinge
+belatedly
+believably
+belligerently
+below
+beneath
+beside
+besides
+between
+bewilderedly
+bewilderingly
+beyond
+bi
+billion
+biologically
+bitterly
+blandly
+bleakly
+blindly
+blissfully
+blithely
+bluntly
+boastfully
+bodily
+boldly
+bong
+both
+bravely
+brazenly
+breathlessly
+briefly
+brightly
+brilliantly
+briskly
+broadly
+brokenly
+brusquely
+brutally
+busily
+but
+by
+callously
+calmly
+can
+candidly
+cannot
+capably
+carefully
+carelessly
+casually
+catastrophically
+categorically
+causally
+cautiously
+ceaselessly
+centrally
+ceremonially
+ceremoniously
+certainly
+characteristically
+charmingly
+cheaply
+cheerfully
+chemically
+chiefly
+childishly
+chronically
+chronologically
+circa
+circumspectly
+clairaudiently
+classically
+cleanly
+clearly
+cleverly
+clinically
+clockwise
+closely
+clumsily
+coarsely
+cogently
+cohesively
+colde
+coldly
+collectively
+comfortably
+comically
+commercially
+commonly
+compactly
+comparatively
+compassionately
+competently
+competitively
+completely
+comprehensively
+compulsively
+concededly
+conceivably
+conceptually
+concerning
+conclusively
+concretely
+concurrently
+confidentially
+confidently
+consanguineously
+consciously
+consequently
+considerably
+considerately
+consisently
+consistently
+conspicuously
+constantly
+constructively
+consummately
+contemptuously
+contentedly
+continentally
+continually
+continuously
+contradictorily
+contrarily
+conveniently
+conventionally
+conversely
+convincingly
+convulsively
+coolly
+copiously
+correctly
+correlatively
+correspondingly
+cortically
+cosily
+coud
+coudn
+could
+courageously
+courteously
+covertly
+coyly
+crazily
+creatively
+credibly
+crisply
+critically
+crossways
+crosswise
+crucially
+crudely
+cruelly
+culturally
+cunningly
+curiously
+currently
+curtly
+curvaceously
+customarily
+cynically
+d
+da
+daintily
+dammit
+damnit
+dandily
+dangerously
+darkly
+dearly
+deathly
+decently
+deceptively
+decidedly
+decisively
+deeply
+defiantly
+definitely
+dejectedly
+deliberately
+delicately
+deliciously
+delightfully
+demandingly
+demonstrably
+denominationally
+depending
+deplorably
+depressingly
+dere
+derisively
+despairingly
+desperately
+despite
+determinedly
+devastatingly
+devotedly
+devoutly
+dey
+diagonally
+dialectically
+diametrically
+did
+diddle
+didn
+differently
+diffusely
+diligently
+dimensionally
+dimly
+directionally
+directly
+disapprovingly
+disconcertingly
+discordantly
+discreetly
+dismally
+dispassionately
+disproportionately
+distally
+distantly
+distastefully
+distinctively
+distinctly
+distractedly
+disturbingly
+divinely
+dizzily
+do
+doan
+docilely
+doctrinally
+does
+doggedly
+doggone
+dogmatically
+domestically
+dominantly
+doo
+dost
+doubly
+doubtfully
+doubtingly
+doubtless
+dourly
+down
+downright
+downstairs
+downwind
+dramatically
+drastically
+dreadfully
+dreamlessly
+drowsily
+drunkenly
+druther
+dryly
+dully
+duly
+during
+dutifully
+dynamically
+each
+eagerly
+earnestly
+easily
+eastward
+eclectically
+economically
+edgewise
+editorially
+eerily
+effectively
+efficaciously
+efficiently
+effortlessly
+egregiously
+eh
+eight
+eighteen
+eighteenth
+eighth
+eighty
+either
+elaborately
+electrically
+elegantly
+eleven
+eleventh
+eloquently
+else
+elsewhere
+em
+embarrassingly
+eminently
+emotionally
+emphatically
+empirically
+enchantingly
+encouragingly
+endlessly
+enduringly
+energetically
+engagingly
+enny
+enormously
+enough
+enterprisingly
+enthusiastically
+entirely
+enviably
+enviously
+epicyclically
+equally
+equidistantly
+equitably
+ere
+erotically
+erratically
+erroneously
+especially
+essentially
+etcetera
+ether
+ethically
+evenly
+eventfully
+eventshahleh
+eventually
+evenutally
+ever
+everlastingly
+every
+everybody
+everyone
+everything
+everywhere
+evidently
+exactly
+exasperatingly
+exceedingly
+excellently
+except
+excepting
+exceptionally
+excessively
+excitedly
+excluding
+exclusively
+exhaustingly
+exhaustively
+expansively
+expectantly
+expectedly
+expeditiously
+experientially
+experimentally
+expertly
+explicitly
+explosively
+expressly
+exquisitely
+extempore
+extensively
+externally
+extraordinarily
+extremely
+exuberantly
+exultantly
+facetiously
+faintly
+fairly
+faithfully
+familiarly
+fantastically
+farther
+fascinatingly
+fatally
+favorably
+fearfully
+fearlessly
+feebly
+fer
+ferociously
+fervently
+feverishly
+few
+fewer
+fiercely
+fifteen
+fifteenth
+fifth
+fiftieth
+fifty
+finally
+financially
+finely
+firmly
+first
+fitfully
+five
+flagrantly
+flamboyantly
+flatly
+flatteringly
+fluently
+focally
+foh
+fondly
+foolishly
+for
+forcibly
+foremost
+forever
+formally
+former
+formerly
+formidably
+forth
+forthrightly
+fortunately
+forty
+foully
+four
+fourteen
+fourteenth
+fourth
+fragmentarily
+frankly
+frantically
+freely
+frenziedly
+frequently
+freshly
+friendlily
+frighteningly
+frightfully
+from
+frowningly
+frugally
+fruitfully
+fruitlessly
+fully
+functionally
+fundamentally
+furiously
+furthermore
+furtively
+fussily
+futhermore
+gaily
+gaspingly
+gawdamighty
+generally
+generously
+gently
+genuinely
+geographically
+geometrically
+girlishly
+gladly
+glaringly
+gleefully
+glibly
+globally
+gloomily
+gloriously
+glumly
+godamit
+goddamit
+goddammit
+golly
+goodbye
+goodnight
+goody
+goolick
+goooolick
+gorgeously
+gosh
+governmentally
+gracefully
+graciously
+gradually
+grammatically
+grandly
+graphically
+gratefully
+gratifyingly
+gratingly
+gratis
+gratuitously
+gravely
+greatly
+greedily
+greenly
+grevouselye
+grimly
+grossly
+grotesquely
+grudgingly
+ha
+habitually
+had
+hadd
+haf
+haggardly
+haint
+half
+halfways
+haltingly
+handsomely
+haphazardly
+happily
+harder
+hardly
+harmlessly
+harmoniously
+harro
+harshly
+has
+hast
+hastily
+hath
+haughtily
+have
+having
+he
+healthily
+heartily
+heatedly
+heavily
+hello
+helpfully
+helplessly
+hence
+henceforth
+henh
+her
+here
+hereabouts
+hereafter
+hereby
+herein
+hereinafter
+heretofore
+hereunto
+herewith
+heroically
+hers
+herself
+hesitantly
+hesitatingly
+hev
+hevin
+hey
+hi
+hideously
+highly
+hilariously
+him
+himself
+himselfe
+hir
+his
+hisself
+historically
+hither
+hitherto
+hmpf
+hoarsely
+homeward
+homewards
+homogeneously
+honestly
+honorably
+hopefully
+hopelessly
+horizontally
+horribly
+horrifyingly
+hotly
+how
+howe
+however
+howsomever
+hubba
+huh
+humanely
+humanly
+humbly
+humiliatingly
+hundred
+hundredth
+hurriedly
+huskily
+hydraulically
+hym
+hyperbolically
+hypnotically
+hypothalamically
+hys
+hytt
+ideally
+identically
+idiotically
+idly
+if
+illegally
+imaginatively
+immeasurably
+immediately
+immensely
+impassively
+impatiently
+impeccably
+imperceptibly
+imperfectly
+imperiously
+impersonally
+implausibly
+implicitly
+importantly
+importunately
+impossibly
+imprecisely
+improbably
+improperly
+imprudently
+impudently
+in
+inadequately
+inadvertently
+inasmuch
+incessantly
+incidentally
+including
+incoherently
+incomparably
+incompletely
+inconspicuously
+inconveniently
+increasingly
+incredibly
+incredulously
+incurably
+indecisively
+indeed
+indefinitely
+indelibly
+independently
+indignantly
+indirectly
+indiscriminantly
+indisputably
+individually
+indolently
+indoors
+industrially
+industriously
+ineffectively
+ineptly
+inescapably
+inevitably
+inexorably
+inexplicably
+inexpressibly
+infernally
+infinitely
+infinitesimally
+informally
+infra
+infrequently
+ingeniously
+inherently
+initially
+inland
+innocently
+inordinately
+insanely
+insidiously
+insofar
+insolently
+insomma
+instantaneously
+instantly
+instead
+instinctively
+instrumentally
+insufficiently
+insuperably
+intellectually
+intelligently
+intensely
+intensively
+intentionally
+intently
+interestingly
+intermittently
+internally
+internationally
+intimately
+into
+intramuscularly
+intricately
+intriguingly
+intrinsically
+intuitively
+invariably
+inversely
+invisibly
+involuntarily
+inwardly
+ironically
+irrationally
+irredeemably
+irregularly
+irreparably
+irresistibly
+irreversibly
+irrevocably
+irritably
+is
+isothermally
+it
+its
+itself
+jaggedly
+jealously
+jist
+jocularly
+jointly
+joyfully
+joyously
+jubilantly
+judiciously
+july
+jurisprudentially
+justifiably
+justly
+kaboom
+keenly
+kin
+kinda
+kinesthetically
+knowingly
+laboriously
+lahk
+lak
+largely
+last
+lastly
+lately
+latter
+laudably
+laughingly
+lavishly
+lazily
+least
+legally
+legitimately
+lengthily
+less
+lest
+lewdly
+liberally
+lightly
+likewise
+limply
+linearly
+linguistically
+listlessly
+literally
+litle
+lo
+locally
+logically
+loosely
+lopsidedly
+loudly
+lovingly
+luckily
+lustily
+m
+macroscopically
+madly
+magically
+magnetically
+magnificently
+mah
+maht
+mai
+mainly
+majestically
+maliciously
+manifestly
+manually
+many
+manye
+marginally
+markedly
+marketwise
+marvelously
+masterfully
+materially
+mathematically
+may
+maybe
+maye
+mayst
+me
+meaningfully
+meanwhile
+measurably
+mechanically
+mechanochemically
+medically
+mee
+meekly
+melodically
+mentally
+mercifully
+mercilessly
+merely
+merrily
+methodically
+meticulously
+metrically
+microscopically
+midway
+might
+mightily
+mildly
+militantly
+militarily
+million
+mimetically
+mine
+minimally
+minus
+minutely
+miraculously
+miserably
+mistakenly
+mmm
+mmmm
+mockingly
+moderately
+modestly
+momentarily
+monolithically
+monumentally
+moodily
+mor
+morally
+more
+moreover
+morosely
+mortally
+most
+mostly
+mountainously
+mournfully
+movingly
+much
+municipally
+musically
+must
+mutely
+mutually
+my
+myn
+myne
+myself
+mysteriously
+n
+na
+nae
+naively
+nakedly
+namely
+narrowly
+nary
+natch
+nationally
+naturally
+naught
+naw
+nawt
+nay
+nearly
+nearsightedly
+neatly
+necessarily
+needlessly
+negatively
+neither
+nervously
+nether
+never
+nevertheless
+next
+nicely
+nigh
+nightly
+nilly
+nimbly
+nine
+nineteen
+nineteenth
+ninetieth
+ninety
+ninth
+no
+nobody
+noisily
+nominally
+noncommittally
+nondescriptly
+none
+nonetheless
+nonspecifically
+nope
+nor
+normally
+northward
+nostalgically
+not
+notably
+noth
+nothin
+nothing
+noticeably
+notoriously
+nott
+notwithstanding
+now
+nowadays
+nowhere
+nuf
+numbingly
+numerically
+o
+objectively
+obligingly
+obliquely
+obscurely
+obviously
+occasionally
+octillion
+oddly
+of
+off
+offensively
+officially
+offstage
+oft
+often
+oftener
+oftentimes
+oh
+okay
+ominously
+on
+once
+onct
+one
+oneself
+onleh
+only
+onto
+ontologically
+onward
+onwards
+oooo
+oops
+openly
+operationally
+optically
+or
+orally
+ordinarily
+organically
+organizationally
+originally
+ornately
+ostensibly
+other
+otherwise
+ought
+our
+ours
+ourselves
+out
+outdoors
+outstandingly
+outwardly
+over
+overboard
+overland
+overly
+overtly
+overwhelmingly
+ovuh
+owly
+ownself
+painfully
+painlessly
+painstakingly
+palely
+palpably
+paradoxically
+parenthetically
+partially
+particularly
+partly
+passionately
+passively
+paternally
+patiently
+peacefully
+peculiarly
+per
+perchance
+perennially
+perfectly
+perforce
+perfunctorily
+perhaps
+perilously
+periodically
+peripherally
+permanently
+perpendicularly
+perpetually
+persistently
+personally
+persuasively
+pervasively
+perversely
+philosophically
+photographically
+physically
+physiologically
+pictorially
+piecewise
+pinkly
+piously
+pip
+pitifully
+pitilessly
+pityingly
+plainly
+plastically
+pleasantly
+pleasingly
+plumb
+plus
+poetically
+poignantly
+pointedly
+politely
+politically
+pompously
+poorly
+popularly
+positively
+possibly
+potentially
+powerfully
+practically
+prayerfully
+precariously
+precisely
+precociously
+predictably
+predominantly
+predominately
+preferably
+preferentially
+prematurely
+preponderantly
+presente
+presently
+presentlye
+presumably
+prettily
+pretty
+previously
+primarily
+primly
+principally
+privately
+probably
+probly
+prodigally
+professedly
+professionally
+profitably
+profoundly
+profusely
+progressively
+prominently
+promptly
+pronto
+properly
+prophetically
+proportionally
+proportionately
+protectively
+proudly
+provocatively
+prudentially
+prudently
+psychically
+psychologically
+publically
+publicly
+pugh
+punctually
+pungently
+purely
+purportedly
+purposefully
+purposely
+purposively
+pursuant
+quadrillion
+qualitatively
+quantitatively
+querulously
+questioningly
+quickly
+quietly
+quintillion
+quite
+quitely
+racially
+radically
+rakishly
+randomly
+rapidly
+rarely
+rather
+rationally
+raucously
+readily
+realistically
+really
+reasonably
+reassuringly
+rebelliously
+recently
+recklessly
+rectlinearly
+recurrently
+reflexly
+refreshingly
+regarding
+regardless
+regionally
+regretfully
+regrettably
+regularly
+relatively
+relentlessly
+reliably
+religiously
+reluctantly
+remarkably
+remotely
+repeatedly
+reportedly
+reproducibly
+reprovingly
+reputedly
+residentially
+resignedly
+resolutely
+resourcefully
+respectfully
+respectively
+responsibly
+responsively
+restively
+restlessly
+reverently
+rhythmically
+richly
+ridiculously
+rightfully
+rightly
+rigidly
+rigorously
+rollickingly
+romantically
+rotationally
+roughly
+roughtly
+roundly
+routinely
+rudely
+ruefully
+ruggedly
+ruthlessly
+sadly
+safely
+same
+sarcastically
+satirically
+satisfactorily
+savagely
+scarcely
+scathingly
+schematically
+scholastically
+scientifically
+scornfully
+scrupulously
+searchingly
+seasonally
+second
+secondarily
+secondly
+secretly
+securely
+sedately
+sedulously
+seekingly
+seemingly
+seldom
+selectively
+semantically
+senselessly
+sensibly
+sensitively
+separately
+septillion
+serenely
+seriously
+seven
+seventeen
+seventeenth
+seventh
+seventy
+several
+severally
+severely
+severly
+sextillion
+sexually
+sha
+shabbily
+shakily
+shall
+shamefacedly
+sharply
+shatteringly
+she
+shh
+shiningly
+shockingly
+shortly
+should
+shrewdly
+shrilly
+shucks
+shuld
+shulde
+shyly
+sidewise
+signally
+significantly
+silently
+similarly
+simply
+simultaneously
+since
+sincerely
+single
+singlehandedly
+singly
+singularly
+sinuously
+six
+sixteen
+sixteenth
+sixth
+sixty
+skeptically
+skilfully
+skillfully
+sleepily
+sleeplessly
+slightly
+slimly
+sloppily
+slowly
+sluggishly
+slyly
+smartly
+smilingly
+smolderingly
+smoothly
+snobbishly
+snugly
+so
+sobbingly
+soberly
+socially
+sociologically
+soddenly
+soe
+sofar
+softly
+solely
+solemnly
+solidly
+some
+somebody
+someday
+somehow
+someone
+someplace
+somethin
+something
+sometime
+sometimes
+somewhat
+somewhere
+somewheres
+sompin
+sonuvabitch
+soon
+sooner
+soothingly
+sorely
+soulfully
+soundly
+sourly
+sparsely
+spatially
+specially
+specifically
+spectacularly
+spectrally
+speculatively
+speedily
+spiritually
+splendidly
+spontaneously
+squarely
+sssshoo
+staggeringly
+starkly
+startlingly
+statistically
+steadfastly
+steadily
+stealthily
+steamily
+steeply
+sternly
+stiffly
+stirringly
+stolidly
+stonily
+stoutly
+straightway
+strangely
+strategically
+strenuously
+strictly
+strikingly
+stringently
+strongly
+structurally
+stubbornly
+studiously
+stunningly
+stupidly
+subconsciously
+subjectively
+subsequently
+substantially
+substantively
+subtly
+successfully
+successively
+succinctly
+suddenly
+sufficiently
+suitably
+sulkily
+sullenly
+superbly
+superficially
+supinely
+supposedly
+supposing
+supra
+supremely
+surely
+surprisingly
+surreptitiously
+suspiciously
+sweepingly
+sweetly
+swiftly
+sycophantically
+symbolically
+symmetrically
+sympathetically
+synce
+syntactically
+systematically
+ta
+tacitly
+tactically
+tactually
+tangibly
+tantalizingly
+tarantara
+tardily
+tartly
+tauntingly
+tearfully
+technically
+technologically
+tediously
+telepathically
+temperately
+temporally
+temporarily
+temptingly
+ten
+tenaciously
+tenderly
+tenfold
+tensely
+tentatively
+tenth
+tenuously
+terribly
+tersely
+testily
+than
+thar
+that
+thatt
+thay
+the
+theare
+thease
+theatrically
+thee
+thees
+thei
+their
+theirs
+them
+themselves
+thence
+thenceforth
+theoretically
+ther
+there
+thereabouts
+thereafter
+thereby
+therefor
+therefore
+therefrom
+therein
+thereof
+thereon
+thereto
+theretofore
+thereunder
+thereupon
+therewith
+thermally
+thermodynamically
+these
+thet
+they
+thickly
+thine
+thinly
+third
+thirdly
+thirteen
+thirteenth
+thirtieth
+thirty
+this
+thither
+thoroughly
+those
+thou
+though
+thoughtfully
+thoughtlessly
+thousand
+thousandth
+threateningly
+three
+thrice
+through
+throughout
+thru
+thum
+thus
+thy
+tighter
+tightly
+till
+timidly
+tiredly
+tirelessly
+to
+together
+tonally
+too
+totally
+toward
+towardes
+towards
+traditionally
+tragically
+transversally
+transversely
+tremendously
+tremulously
+trillion
+triumphantly
+truly
+trustfully
+trustingly
+truthfully
+tunelessly
+twelfth
+twelve
+twentieth
+twenty
+twice
+twirlingly
+twise
+two
+typically
+u
+ugh
+uh
+uhhu
+ultimately
+ultracentrifugally
+ultrasonically
+um
+umm
+unaccountably
+unambiguously
+unanimously
+unappeasably
+unashamedly
+unavoidably
+unbearably
+unbelievably
+unblinkingly
+unceasingly
+uncertainly
+uncomfortably
+uncommonly
+uncomplainingly
+unconcernedly
+unconditionally
+unconsciously
+uncritically
+undeniably
+underfoot
+underneath
+understandably
+understandingly
+underway
+undoubtedly
+unduly
+uneasily
+unequally
+unequivocally
+unerringly
+unexpectedly
+unfailingly
+unfairly
+unfalteringly
+unfortunately
+unfunnily
+unhappily
+unhesitatingly
+unhurriedly
+uniformly
+unilaterally
+unimpeachably
+unintentionally
+uninterruptedly
+uniquely
+universally
+unknowingly
+unless
+unlike
+unluckily
+unmanageably
+unmistakably
+unnaturally
+unnecessarily
+unnnt
+unobtrusively
+unofficially
+unpleasantly
+unpredictably
+unqualifiedly
+unquestionably
+unquestioningly
+unrealistically
+unreasonably
+unreassuringly
+unreservedly
+unrestrictedly
+unselfishly
+unsmilingly
+unsteadily
+unsuccessfully
+unsuitably
+until
+unto
+unusually
+unutterably
+unwaveringly
+unwillingly
+unwisely
+unwittingly
+up
+upon
+uppermost
+uppon
+uproariously
+upside
+upstate
+upwards
+urgently
+us
+usefully
+uselessly
+usually
+utterly
+vaguely
+vainly
+valiantly
+validly
+variously
+vastly
+vehemently
+verbally
+verbatim
+verie
+versa
+versus
+vertically
+very
+via
+victoriously
+vigorously
+violently
+virtually
+visibly
+visually
+vitally
+vividly
+vocally
+vocationally
+vociferously
+volumetrically
+voluntarily
+voraciously
+warily
+warmly
+warningly
+was
+waspishly
+we
+weakly
+wearily
+wee
+weirdly
+were
+westward
+westwards
+wetly
+whad
+what
+whatever
+whatsoever
+wheare
+when
+whence
+whenever
+wher
+where
+whereas
+whereby
+whereever
+wherefore
+wherein
+whereon
+whereupon
+wherever
+wherewith
+whether
+which
+whichever
+whitely
+who
+whoe
+whoever
+wholeheartedly
+wholly
+whom
+whoosh
+whose
+whosoever
+why
+wickedly
+widely
+wil
+wildly
+wilfully
+will
+willfully
+willingly
+willy
+wilt
+wisely
+wistfully
+with
+withal
+within
+without
+wittingly
+wod
+woefully
+wold
+wolde
+wolfishly
+wonderfully
+wonderingly
+wondrously
+wordlessly
+worriedly
+would
+wow
+wrongly
+wryly
+wuh
+ya
+ye
+yea
+yeah
+yearningly
+yehhh
+yes
+yesiree
+yet
+yff
+yon
+yonder
+yooee
+you
+your
+yours
+yourself
+yourselves
+yow
+ys
+yuh
+zealously
+zero
+zoooop
+zounds
Index: /gsdl/stable/etc/packages/phind/stopword/fr/JASIS.sw
===================================================================
--- /gsdl/stable/etc/packages/phind/stopword/fr/JASIS.sw	(revision 20131)
+++ /gsdl/stable/etc/packages/phind/stopword/fr/JASIS.sw	(revision 20131)
@@ -0,0 +1,215 @@
+a
+afin
+ai
+ainsi
+aprÃšs
+attendu
+au
+aujourd
+auquel
+aussi
+autre
+autres
+aux
+auxquelles
+auxquels
+avait
+avant
+avec
+avoir
+c
+car
+ce
+ceci
+cela
+celle
+celles
+celui
+cependant
+certain
+certaine
+certaines
+certains
+ces
+cet
+cette
+ceux
+chez
+ci
+combien
+comme
+comment
+concernant
+contre
+d
+dans
+de
+debout
+dedans
+dehors
+delÃ 
+depuis
+derriÃšre
+des
+desquelles
+desquels
+dessous
+dessus
+devant
+devers
+devra
+divers
+diverse
+diverses
+doit
+donc
+dont
+du
+duquel
+durant
+dÃšs
+elle
+elles
+en
+entre
+environ
+est
+et
+etc
+etre
+eux
+exceptÃ©
+hormis
+hors
+hui
+hÃ©las
+il
+ils
+j
+je
+jusqu
+jusque
+l
+la
+laquelle
+le
+lequel
+les
+lesquelles
+lesquels
+leur
+leurs
+lorsque
+lui
+lÃ 
+ma
+mais
+malgrÃ©
+me
+merci
+mes
+mien
+mienne
+miennes
+miens
+moi
+moins
+mon
+moyennant
+mÃªme
+mÃªmes
+n
+ne
+ni
+non
+nos
+notre
+nous
+nÃ©anmoins
+nÃŽtre
+nÃŽtres
+on
+ou
+out
+outre
+oÃ¹
+par
+parmi
+partant
+pas
+passÃ©
+pendant
+plein
+plus
+plusieurs
+pour
+pourquoi
+proche
+prÃšs
+puisque
+qu
+quand
+que
+quel
+quelle
+quelles
+quels
+qui
+quoi
+quoique
+revoici
+revoilÃ 
+s
+sa
+sans
+sauf
+se
+selon
+seront
+ses
+si
+sien
+sienne
+siennes
+siens
+sinon
+soi
+soit
+son
+sont
+sous
+suivant
+sur
+ta
+te
+tes
+tien
+tienne
+tiennes
+tiens
+toi
+ton
+tous
+tout
+toute
+toutes
+tu
+un
+une
+va
+vers
+voici
+voilÃ 
+vos
+votre
+vous
+vu
+vÃŽtre
+vÃŽtres
+y
+Ã 
+Ã§a
+Ãšs
+Ã©tÃ©
+Ãªtre
+ÃŽ
Index: /gsdl/stable/etc/packages/rtftohtm/ansi.gen
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/ansi.gen	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/ansi.gen	(revision 20131)
@@ -0,0 +1,215 @@
+# RTF ANSI character set (\ansi) general map
+# These are taken from the ISO-Latin-1 (ISO-8859-1) encodings, with
+# a few additions
+
+# Field 1 is the standard character name which the character value in
+# field 2 maps onto.  (It doesn't mean "to produce the character in field 1,
+# use the value in field 2.)
+# jrm21 - ie, given the input in field 2, what name do we use for it?
+
+# The character value may be given either as a single character (which will be
+# converted to the ASCII value of the character), or in numeric format, either
+# in decimal or 0xyy as hex yy.  Single or double quotes may be used to quote
+# characters.
+
+# characters in ASCII range (00-127)
+
+formula		0x06
+nobrkhyphen	0x1e
+opthyphen	0x1f
+
+space		" "
+exclam		!
+quotedbl	'"'
+numbersign	#
+dollar		$
+percent		%
+ampersand	&
+quoteright	"'"
+parenleft	(
+parenright	)
+asterisk	*
+plus		+
+comma		,
+hyphen		-
+period		.
+slash		/
+zero		0
+one		1
+two		2
+three		3
+four		4
+five		5
+six		6
+seven		7
+eight		8
+nine		9
+colon		:
+semicolon	;
+less		<
+equal		=
+greater		>
+question	?
+at		@
+A		A
+B		B
+C		C
+D		D
+E		E
+F		F
+G		G
+H		H
+I		I
+J		J
+K		K
+L		L
+M		M
+N		N
+O		O
+P		P
+Q		Q
+R		R
+S		S
+T		T
+U		U
+V		V
+W		W
+X		X
+Y		Y
+Z		Z
+bracketleft	[
+backslash	\
+bracketright	]
+asciicircum	^
+underscore	_
+quoteleft	"`"
+a		a
+b		b
+c		c
+d		d
+e		e
+f		f
+g		g
+h		h
+i		i
+j		j
+k		k
+l		l
+m		m
+n		n
+o		o
+p		p
+q		q
+r		r
+s		s
+t		t
+u		u
+v		v
+w		w
+x		x
+y		y
+z		z
+braceleft	{
+bar		|
+braceright	}
+asciitilde	~
+
+# non-ASCII characters (128-255)
+null		0x80
+
+nobrkspace	0xa0
+exclamdown	0xa1
+cent		0xa2
+sterling	0xa3
+currency	0xa4
+yen		0xa5
+brokenbar	0xa6
+section		0xa7
+dieresis	0xa8
+copyright	0xa9
+ordfeminine	0xaa
+guillemotleft	0xab
+logicalnot	0xac
+opthyphen	0xad
+registered	0xae
+macron		0xaf
+degree		0xb0
+plusminus	0xb1
+twosuperior	0xb2
+threesuperior	0xb3
+acute		0xb4
+mu		0xb5
+paragraph	0xb6
+periodcentered	0xb7
+cedilla		0xb8
+onesuperior	0xb9
+ordmasculine	0xba
+guillemotright	0xbb
+onequarter	0xbc
+onehalf		0xbd
+threequarters	0xbe
+questiondown	0xbf
+Agrave		0xc0
+Aacute		0xc1
+Acircumflex	0xc2
+Atilde		0xc3
+Adieresis	0xc4
+Aring		0xc5
+AE		0xc6
+Ccedilla	0xc7
+Egrave		0xc8
+Eacute		0xc9
+Ecircumflex	0xca
+Edieresis	0xcb
+Igrave		0xcc
+Iacute		0xcd
+Icircumflex	0xce
+Idieresis	0xcf
+Eth		0xd0
+Ntilde		0xd1
+Ograve		0xd2
+Oacute		0xd3
+Ocircumflex	0xd4
+Otilde		0xd5
+Odieresis	0xd6
+multiply	0xd7
+Oslash		0xd8
+Ugrave		0xd9
+Uacute		0xda
+Ucircumflex	0xdb
+Udieresis	0xdc
+Yacute		0xdd
+Thorn		0xde
+germandbls	0xdf
+agrave		0xe0
+aacute		0xe1
+acircumflex	0xe2
+atilde		0xe3
+adieresis	0xe4
+aring		0xe5
+ae		0xe6
+ccedilla	0xe7
+egrave		0xe8
+eacute		0xe9
+ecircumflex	0xea
+edieresis	0xeb
+igrave		0xec
+iacute		0xed
+icircumflex	0xee
+idieresis	0xef
+eth		0xf0
+ntilde		0xf1
+ograve		0xf2
+oacute		0xf3
+ocircumflex	0xf4
+otilde		0xf5
+odieresis	0xf6
+divide		0xf7
+oslash		0xf8
+ugrave		0xf9
+uacute		0xfa
+ucircumflex	0xfb
+udieresis	0xfc
+yacute		0xfd
+thorn		0xfe
+ydieresis	0xff
Index: /gsdl/stable/etc/packages/rtftohtm/ansi.sym
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/ansi.sym	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/ansi.sym	(revision 20131)
@@ -0,0 +1,114 @@
+# RTF ANSI character set (\ansi) Symbol font map
+
+# Field 1 is the standard character name which the character value in
+# field 2 maps onto.  (It doesn't mean "to produce the character in field 1,
+# use the value in field 2.)
+
+# The character value may be given either as a single character (which will be
+# converted to the ASCII value of the character), or in numeric format, either
+# in decimal or 0xyy as hex yy.  Single or double quotes may be used to quote
+# characters.
+
+# characters in ASCII range (00-127)
+
+formula		0x06
+nobrkhyphen	0x1e
+opthyphen	0x1f
+
+space		" "
+exclam		!
+universal	'"'
+mathnumbersign	#
+existential	$
+percent		%
+ampersand	&
+suchthat	"'"
+parenleft	(
+parenright	)
+mathasterisk	*
+mathplus	+
+comma		,
+mathminus	-
+period		.
+slash		/
+zero		0
+one		1
+two		2
+three		3
+four		4
+five		5
+six		6
+seven		7
+eight		8
+nine		9
+colon		:
+semicolon	;
+less		<
+mathequal	=
+greater		>
+question	?
+congruent	@
+Alpha		A
+Beta		B
+Chi		C
+Delta		D
+Epsilon		E
+Phi		F
+Gamma		G
+Eta		H
+Iota		I
+# J		J
+Kappa		K
+Lambda		L
+Mu		M
+Nu		N
+Omicron		O
+Pi		P
+Theta		Q
+Rho		R
+Sigma		S
+Tau		T
+Upsilon		U
+varsigma	V
+Omega		W
+Xi		X
+Psi		Y
+Zeta		Z
+bracketleft	[
+backslash	\
+bracketright	]
+asciicircum	^
+underscore	_
+quoteleft	"`"
+alpha		a
+beta		b
+chi		c
+delta		d
+epsilon		e
+phi		f
+gamma		g
+eta		h
+iota		i
+# j		j
+kappa		k
+lambda		l
+mu		m
+nu		n
+omicron		o
+pi		p
+theta		q
+rho		r
+sigma		s
+tau		t
+upsilon		u
+# xxx		v
+omega		w
+xi		x
+psi		y
+zeta		z
+braceleft	{
+bar		|
+braceright	}
+mathtilde	~
+
+# non-ASCII characters (128-255)
Index: /gsdl/stable/etc/packages/rtftohtm/cpg1252.gen
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/cpg1252.gen	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/cpg1252.gen	(revision 20131)
@@ -0,0 +1,244 @@
+# RTF Windows Codepage-1252 character set (\ansi) general map
+# Note (jrm21) - this is basically a modified version of the ANSI map.
+
+# Field 1 is the standard character name which the character value in
+# field 2 maps onto.  (It doesn't mean "to produce the character in field 1,
+# use the value in field 2.)
+
+# The character value may be given either as a single character (which will be
+# converted to the ASCII value of the character), or in numeric format, either
+# in decimal or 0xyy as hex yy.  Single or double quotes may be used to quote
+# characters.
+
+# printable characters in ASCII range (00-127)
+
+formula		0x06
+nobrkhyphen	0x1e
+opthyphen	0x1f
+
+space		" "	# 0x20
+exclam		!	# 0x21
+quotedbl	'"'	# 0x22
+numbersign	#	# 0x23
+dollar		$	# 0x24
+percent		%	# 0x25
+ampersand	&	# 0x26
+quoteright	"'"	# 0x27
+parenleft	(	# 0x28
+parenright	)	# 0x29
+asterisk	*	# 0x2a
+plus		+	# 0x2b
+comma		,	# 0x2c
+hyphen		-	# 0x2d
+period		.	# 0x2e
+slash		/	# 0x2f
+zero		0	# 0x30
+one		1	# 0x31
+two		2	# 0x32
+three		3	# 0x33
+four		4	# 0x34
+five		5	# 0x35
+six		6	# 0x36
+seven		7	# 0x37
+eight		8	# 0x38
+nine		9	# 0x39
+colon		:	# 0x3a
+semicolon	;	# 0x3b
+less		<	# 0x3c
+equal		=	# 0x3d
+greater		>	# 0x3e
+question	?	# 0x3f
+at		@	# 0x40
+A		A	# 0x41
+B		B	# 0x42
+C		C	# 0x43
+D		D	# 0x44
+E		E	# 0x45
+F		F	# 0x46
+G		G	# 0x47
+H		H	# 0x48
+I		I	# 0x49
+J		J	# 0x4a
+K		K	# 0x4b
+L		L	# 0x4c
+M		M	# 0x4d
+N		N	# 0x4e
+O		O	# 0x4f
+P		P	# 0x50
+Q		Q	# 0x51
+R		R	# 0x52
+S		S	# 0x53
+T		T	# 0x54
+U		U	# 0x55
+V		V	# 0x56
+W		W	# 0x57
+X		X	# 0x58
+Y		Y	# 0x59
+Z		Z	# 0x5a
+bracketleft	[	# 0x5b
+backslash	\	# 0x5c
+bracketright	]	# 0x5d
+asciicircum	^	# 0x5e
+underscore	_	# 0x5f
+quoteleft	"`"	# 0x60
+a		a	# 0x61
+b		b	# 0x62
+c		c	# 0x63
+d		d	# 0x64
+e		e	# 0x65
+f		f	# 0x66
+g		g	# 0x67
+h		h	# 0x68
+i		i	# 0x69
+j		j	# 0x6a
+k		k	# 0x6b
+l		l	# 0x6c
+m		m	# 0x6d
+n		n	# 0x6e
+o		o	# 0x6f
+p		p	# 0x70
+q		q	# 0x71
+r		r	# 0x72
+s		s	# 0x73
+t		t	# 0x74
+u		u	# 0x75
+v		v	# 0x76
+w		w	# 0x77
+x		x	# 0x78
+y		y	# 0x79
+z		z	# 0x7a
+braceleft	{	# 0x7b
+bar		|	# 0x7c
+braceright	}	# 0x7d
+asciitilde	~	# 0x7e
+# undefined (delete)	# 0x7f
+
+# non-ASCII characters (128-255)
+euro		0x80
+# undefined	0x81
+quotesinglbase	0x82 # single low-9 quotation mark
+florin		0x83 # f with hook (fnof) ## not sure if florin is right...
+quotedblbase	0x84 # double low-9 quotation mark
+ellipsis	0x85
+dagger		0x86
+daggerdbl	0x87
+circumflex	0x88 # modifier
+perthousand	0x89
+Scaron		0x8a
+guilsinglleft	0x8b
+OE		0x8c # OE ligature
+# undefined	0x8d
+Zcaron		0x8e
+# undefined	0x8f
+# undefined	0x90
+quoteleft	0x91 # single quote left - use ascii for now
+quoteright	0x92 # single quote right - use ascii for now
+quotedblleft	0x93
+quotedblright	0x94
+bullet		0x95
+endash		0x96
+emdash		0x97
+asciitilde	0x98 # use ascii tilde
+trademark	0x99
+scaron		0x9a
+guilsinglright	0x9b # single rightpointing quotemark
+oe		0x9c
+# undefined	0x9d
+zcaron		0x9e
+Ydieresis	0x9f # Y with diaeresis
+nobrkspace	0xa0
+exclamdown	0xa1
+cent		0xa2
+sterling	0xa3
+currency	0xa4
+yen		0xa5
+brokenbar	0xa6
+section		0xa7
+dieresis	0xa8
+copyright	0xa9
+ordfeminine	0xaa
+guillemotleft	0xab
+logicalnot	0xac
+opthyphen	0xad
+registered	0xae
+macron		0xaf
+degree		0xb0
+plusminus	0xb1
+twosuperior	0xb2
+threesuperior	0xb3
+acute		0xb4
+mu		0xb5
+paragraph	0xb6
+periodcentered	0xb7
+cedilla		0xb8
+onesuperior	0xb9
+ordmasculine	0xba
+guillemotright	0xbb
+onequarter	0xbc
+onehalf		0xbd
+threequarters	0xbe
+questiondown	0xbf
+Agrave		0xc0
+Aacute		0xc1
+Acircumflex	0xc2
+Atilde		0xc3
+Adieresis	0xc4
+Aring		0xc5
+AE		0xc6
+Ccedilla	0xc7
+Egrave		0xc8
+Eacute		0xc9
+Ecircumflex	0xca
+Edieresis	0xcb
+Igrave		0xcc
+Iacute		0xcd
+Icircumflex	0xce
+Idieresis	0xcf
+Eth		0xd0
+Ntilde		0xd1
+Ograve		0xd2
+Oacute		0xd3
+Ocircumflex	0xd4
+Otilde		0xd5
+Odieresis	0xd6
+multiply	0xd7
+Oslash		0xd8
+Ugrave		0xd9
+Uacute		0xda
+Ucircumflex	0xdb
+Udieresis	0xdc
+Yacute		0xdd
+Thorn		0xde
+germandbls	0xdf
+agrave		0xe0
+aacute		0xe1
+acircumflex	0xe2
+atilde		0xe3
+adieresis	0xe4
+aring		0xe5
+ae		0xe6
+ccedilla	0xe7
+egrave		0xe8
+eacute		0xe9
+ecircumflex	0xea
+edieresis	0xeb
+igrave		0xec
+iacute		0xed
+icircumflex	0xee
+idieresis	0xef
+eth		0xf0
+ntilde		0xf1
+ograve		0xf2
+oacute		0xf3
+ocircumflex	0xf4
+otilde		0xf5
+odieresis	0xf6
+divide		0xf7
+oslash		0xf8
+ugrave		0xf9
+uacute		0xfa
+ucircumflex	0xfb
+udieresis	0xfc
+yacute		0xfd
+thorn		0xfe
+ydieresis	0xff
Index: /gsdl/stable/etc/packages/rtftohtm/cpg1252.sym
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/cpg1252.sym	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/cpg1252.sym	(revision 20131)
@@ -0,0 +1,221 @@
+# RTF ANSI character set (\ansi) general map
+# These are taken from the ISO-Latin-1 (ISO-8859-1) encodings, with
+# a few additions
+
+# Field 1 is the standard character name which the character value in
+# field 2 maps onto.  (It doesn't mean "to produce the character in field 1,
+# use the value in field 2.)
+
+# The character value may be given either as a single character (which will be
+# converted to the ASCII value of the character), or in numeric format, either
+# in decimal or 0xyy as hex yy.  Single or double quotes may be used to quote
+# characters.
+
+# jrm21 - the character name is used when outputting a particular character
+# code. This name is then looked up in the *-gen file to see what to output
+# for that symbol name. It's a bit round-about...
+
+# characters in ASCII range (00-127)
+
+formula		0x06
+nobrkhyphen	0x1e
+opthyphen	0x1f
+
+space		" "
+exclam		!
+quotedbl	'"'
+numbersign	#
+dollar		$
+percent		%
+ampersand	&
+quoteright	"'"
+parenleft	(
+parenright	)
+asterisk	*
+plus		+
+comma		,
+hyphen		-
+period		.
+slash		/
+zero		0
+one		1
+two		2
+three		3
+four		4
+five		5
+six		6
+seven		7
+eight		8
+nine		9
+colon		:
+semicolon	;
+less		<
+equal		=
+greater		>
+question	?
+at		@
+A		A
+B		B
+C		C
+D		D
+E		E
+F		F
+G		G
+H		H
+I		I
+J		J
+K		K
+L		L
+M		M
+N		N
+O		O
+P		P
+Q		Q
+R		R
+S		S
+T		T
+U		U
+V		V
+W		W
+X		X
+Y		Y
+Z		Z
+bracketleft	[
+backslash	\
+bracketright	]
+asciicircum	^
+underscore	_
+quoteleft	"`"
+a		a
+b		b
+c		c
+d		d
+e		e
+f		f
+g		g
+h		h
+i		i
+j		j
+k		k
+l		l
+m		m
+n		n
+o		o
+p		p
+q		q
+r		r
+s		s
+t		t
+u		u
+v		v
+w		w
+x		x
+y		y
+z		z
+braceleft	{
+bar		|
+braceright	}
+asciitilde	~
+
+# non-ASCII characters (128-255)
+#ellipsis		0x85
+#dagger		0x86
+#daggerdbl	0x87
+
+nobrkspace	0xa0
+exclamdown	0xa1
+cent		0xa2
+sterling	0xa3
+currency	0xa4
+yen		0xa5
+brokenbar	0xa6
+section		0xa7
+dieresis	0xa8
+copyright	0xa9
+ordfeminine	0xaa
+guillemotleft	0xab
+logicalnot	0xac
+opthyphen	0xad
+registered	0xae
+macron		0xaf
+degree		0xb0
+plusminus	0xb1
+twosuperior	0xb2
+threesuperior	0xb3
+acute		0xb4
+mu		0xb5
+paragraph	0xb6
+periodcentered	0xb7
+#asterisk	0xb7
+cedilla		0xb8
+onesuperior	0xb9
+ordmasculine	0xba
+guillemotright	0xbb
+onequarter	0xbc
+onehalf		0xbd
+threequarters	0xbe
+questiondown	0xbf
+Agrave		0xc0
+Aacute		0xc1
+Acircumflex	0xc2
+Atilde		0xc3
+Adieresis	0xc4
+Aring		0xc5
+AE		0xc6
+Ccedilla	0xc7
+Egrave		0xc8
+Eacute		0xc9
+Ecircumflex	0xca
+Edieresis	0xcb
+Igrave		0xcc
+Iacute		0xcd
+Icircumflex	0xce
+Idieresis	0xcf
+Eth		0xd0
+Ntilde		0xd1
+Ograve		0xd2
+Oacute		0xd3
+Ocircumflex	0xd4
+Otilde		0xd5
+Odieresis	0xd6
+multiply	0xd7
+Oslash		0xd8
+Ugrave		0xd9
+Uacute		0xda
+Ucircumflex	0xdb
+Udieresis	0xdc
+Yacute		0xdd
+Thorn		0xde
+germandbls	0xdf
+agrave		0xe0
+aacute		0xe1
+acircumflex	0xe2
+atilde		0xe3
+adieresis	0xe4
+aring		0xe5
+ae		0xe6
+ccedilla	0xe7
+egrave		0xe8
+eacute		0xe9
+ecircumflex	0xea
+edieresis	0xeb
+igrave		0xec
+iacute		0xed
+icircumflex	0xee
+idieresis	0xef
+eth		0xf0
+ntilde		0xf1
+ograve		0xf2
+oacute		0xf3
+ocircumflex	0xf4
+otilde		0xf5
+odieresis	0xf6
+divide		0xf7
+oslash		0xf8
+ugrave		0xf9
+uacute		0xfa
+ucircumflex	0xfb
+udieresis	0xfc
+yacute		0xfd
+thorn		0xfe
+ydieresis	0xff
Index: /gsdl/stable/etc/packages/rtftohtm/html-map
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/html-map	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/html-map	(revision 20131)
@@ -0,0 +1,265 @@
+# Output sequence map for rtftohtml
+
+# Field 1 is the standard character name.  Field 2 is the output sequence
+# to produce for that character.
+
+# The output sequence is simply a string of characters.  If it contains
+# whitespace, it may be quoted.  If it contains quotes, it may be quoted
+# with a different quote character.
+
+null		''
+# characters in ASCII range (32-127)
+
+space		" "
+exclam		!
+quotedbl	'"'
+numbersign	#
+dollar		$
+percent		%
+ampersand	&amp;
+quoteright	"'"
+parenleft	(
+parenright	)
+asterisk	*
+plus		+
+comma		,
+hyphen		-
+period		.
+slash		/
+zero		0
+one		1
+onesuperior	&sup1;
+two		2
+twosuperior	&sup2;
+three		3
+threesuperior	&sup3;
+four		4
+five		5
+six		6
+seven		7
+eight		8
+nine		9
+colon		:
+semicolon	;
+less		&lt;
+equal		=
+greater		&gt;
+question	?
+at		@
+A		A
+B		B
+C		C
+D		D
+E		E
+F		F
+G		G
+H		H
+I		I
+J		J
+K		K
+L		L
+M		M
+N		N
+O		O
+P		P
+Q		Q
+R		R
+S		S
+T		T
+U		U
+V		V
+W		W
+X		X
+Y		Y
+Z		Z
+bracketleft	[
+backslash	\
+bracketright	]
+asciicircum	^
+underscore	_
+quoteleft	"`"
+a		a
+b		b
+c		c
+d		d
+e		e
+f		f
+g		g
+h		h
+i		i
+j		j
+k		k
+l		l
+m		m
+n		n
+o		o
+p		p
+q		q
+r		r
+s		s
+t		t
+u		u
+v		v
+w		w
+x		x
+y		y
+z		z
+braceleft	{
+bar		|
+braceright	}
+asciitilde	~
+
+# non-ASCII
+# use HTML 4.0 entity names where practical
+# starting at decimal code 160
+nobrkspace	&nbsp;
+# inverted exclamation mark 161
+cent		&cent;
+sterling	&pound;
+currency	&curren;
+yen		&yen;
+#netscape will only do this in utf-8: brokenbar	&brvbar;
+brokenbar	|
+section		&sect;
+# uml / diaeresis = 168
+copyright	&copy;
+copyrightsans	&copy;
+
+
+# Latin Extended-A
+OE		&OElig;
+oe		&oelig;
+Scaron		&Scaron;
+scaron		&scaron;
+Ydieresis	&Yuml;
+
+acute		"'"
+angleleft	[
+angleright	&gt;
+approxequal	~
+arrowboth	&lt;-&gt;
+arrowdblboth	&lt;=&gt;
+arrowdblleft	&lt;=
+arrowdblright	=&gt;
+arrowleft	&lt;-
+arrowright	-&gt;
+#bullet		*
+bullet		&middot;
+circumflex	^
+# next 2 have named entities, which netscape 4 doesn't use...
+# unicode &#8224; and &#8225;
+dagger		&#134;
+daggerdbl	&#135;
+
+degree		&deg;
+delta		d
+divide		&divide;
+dotlessi	i
+ellipsis	...
+# next 2 have named entities, which netscape 4 doesn't use...
+endash		&#150;
+emdash		&#151;
+euro		&euro;
+fi		fi
+fl		fl
+fraction	/
+grave		"`"
+greaterequal	&gt;=
+# &#171; # was &lt;&lt;
+guillemotleft	&laquo;
+# &#187; # was &gt;&gt;
+guillemotright	&raquo;
+# netscape 4.7 doesn't do this? - unicode: &#2039; or &lsaquo;
+guilsinglleft	&lt;
+# ditto? unicode: &#203A; or &rsaquo;
+guilsinglright	&gt;
+lessequal	&lt;=
+logicalnot	&not;
+mathasterisk	*
+mathequal	=
+mathminus	-
+mathnumbersign	'#'
+mathplus	+
+mathtilde	~
+minus		-
+mu		&micro;
+multiply	&times;
+nobrkhyphen	-
+
+notequal	!=
+onehalf		&frac12;
+onequarter	&frac14;
+periodcentered	&middot;
+plusminus	&plusmn;
+quotedblbase	,,
+quotedblleft	'"'
+quotedblright	'"'
+quotesinglbase	,
+registered	&reg;
+registersans	&reg;
+threequarters	&frac34;
+tilde		~
+trademark	&trade;
+AE		&AElig;
+Aacute      &Aacute;
+Acircumflex &Acirc;
+Agrave      &Agrave;
+Aring       &Aring;
+Atilde		&Atilde;
+Adieresis	&Auml;
+Ccedilla	&Ccedil;
+#ETH		&ETH;
+Eacute	&Eacute;
+Ecircumflex	&Ecirc;
+Egrave	&Egrave;
+Edieresis	&Euml;
+Iacute	&Iacute;
+Icircumflex	&Icirc;
+Igrave	&Igrave;
+Idieresis	&Iuml;
+Ntilde	&Ntilde;
+Oacute	&Oacute;
+Ocircumflex	&Ocirc;
+Ograve	&Ograve;
+Oslash	&Oslash;
+#Otilde	&Otilde;
+Odieresis	&Ouml;
+#THORN	&THORN;
+Uacute	&Uacute;
+Ucircumflex	&Ucirc;
+Ugrave	&Ugrave;
+Udieresis	&Uuml;
+#Yacute	&Yacute;
+ae		&aelig;
+aacute	&aacute;
+acircumflex	&acirc;
+agrave	&agrave;
+aring	&aring;
+atilde	&atilde;
+adieresis	&auml;
+ccedilla	&ccedil;
+eacute	&eacute;
+ecircumflex	&ecirc;
+egrave	&egrave;
+#eth	&eth;
+edieresis	&euml;
+iacute	&iacute;
+icircumflex	&icirc;
+igrave	&igrave;
+idieresis	&iuml;
+ntilde	&ntilde;
+oacute	&oacute;
+ocircumflex	&ocirc;
+ograve	&ograve;
+oslash	&oslash;
+otilde	&otilde;
+odieresis	&ouml;
+germandbls	&szlig;
+#thorn	&thorn;
+uacute	&uacute;
+ucircumflex	&ucirc;
+ugrave	&ugrave;
+udieresis	&uuml;
+yacute	&yacute;
+ydieresis	&yuml;
+newline	<br>
Index: /gsdl/stable/etc/packages/rtftohtm/html-trn
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/html-trn	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/html-trn	(revision 20131)
@@ -0,0 +1,214 @@
+# Starting with rtftohtml 2.7, all html-trans files have a version number
+# The version number must appear before any other tables.
+.Version,3
+
+# Paragraph Style Tags table
+# Format:
+#"name","starttag","endtag","col2mark","tabmark","parmark",allowtext,cannest,DeleteCol1,fold,TocStyl
+.PTag
+"Normal","","\n","\t","\t","<p>\n",1,0,0,1,0
+"h1","<h1>\n","</h1>\n","\t","\t","<br>\n",0,0,0,1,1
+"h2","<h2>\n","</h2>\n","\t","\t","<br>\n",0,0,0,1,2
+"h3","<h3>\n","</h3>\n","\t","\t","<br>\n",0,0,0,1,3
+"h4","<h4>\n","</h4>\n","\t","\t","<br>\n",0,0,0,1,4
+"h5","<h5>\n","</h5>\n","\t","\t","<br>\n",0,0,0,1,5
+"h6","<h6>\n","</h6>\n","\t","\t","<br>\n",0,0,0,1,6
+"ul","<ul>\n<li>","</ul>","\t","\t","\n<li>",1,1,0,1,0
+"ul-d","<ul>\n<li>","</ul>","\t","\t","\n<li>",1,1,1,1,0
+"ol","<ol>\n<li>","</ol>","\t","\t","\n<li>",1,1,0,1,0
+"ol-d","<ol>\n<li>","</ol>","\t","\t","\n<li>",1,1,1,1,0
+"dl","<dl>\n<dt>","</dl>","\n<dd>","\t","\n<dt>",1,1,0,1,0
+"TERM","<dl>\n<dt>","</dl>","\t","\t","\n<dt>",1,1,0,1,0
+"DEF","<dd>","","\t","\t","\n<br>",1,1,0,1,0
+"dir","<dir>\n<li>","</dir>","\n<li>","\n<li>","\n<li>",0,1,0,1,0
+"menu","<menu>\n<li>","</menu>\n","\n<li>","\n<li>","\n<li>",0,1,0,1,0
+"address","<address>","</address>\n","\t","\t","<br>\n",1,0,0,1,0
+"pre","\n<pre>\n","\n</pre>\n","\t","\t","\n",0,0,0,0,0
+"blockquote","<blockquote>","</blockquote>","\t","\t","\n",1,0,0,1,0
+"hr","<hr>","","","","",1,0,0,1,0
+# This is a required entry; tables will be formatted with this entry
+"_Table","\n<pre>\n","\n</pre>\n","\t","\t","\n",0,0,0,0,0
+
+# Text STyle Tags table
+# Format
+# "name","Starttag","Endtag"
+.TTag
+"b","<b>","</b>"
+"i","<i>","</i>"
+"u","<u>","</u>"
+"em","<em>","</em>"
+"cite","<cite>","</cite>"
+"tt","<tt>","</tt>"
+"strong","<strong>","</strong>"
+"code","<code>","</code>"
+"samp","<samp>","</samp>"
+"kbd","<kbd>","</kbd>"
+"var","<var>","</var>"
+"dfn","<dfn>","</dfn>"
+"sup","<sup>","</sup>"
+
+# Text Match Table
+# Format:
+# "Font",FontSize,Match,Mask,"TextStyleName"
+# "" is don't care for fonts
+# 0 is don't care for font size
+# Special names for TextStyleName
+# _Discard - text will not be output
+# _Name    - text will be used for an named anchor
+# _HRef    - text is an href
+# _Hot     - end of this text marks the end of hot text
+# _Literal - text is sent thorough without any translation
+# The order of bits for match and mask is:
+#    v^bDWUHACSOTIB - Bold
+#    v^bDWUHACSOTI - Italic
+#    v^bDWUHACSOT - StrikeThrough
+#    v^bDWUHACSO - Outline
+#    v^bDWUHACS - Shadow
+#    v^bDWUHAC - SmallCaps
+#    v^bDWUHA - AllCaps
+#    v^bDWUH - Hidden
+#    v^bDWU - Underline
+#    v^bDW - Word Underline
+#    v^bD - Dotted Underline
+#    v^b - Double Underline
+#    v^ - SuperScript
+#    v - SubScript
+#    v^bDWUIACSOTIB
+.TMatch
+#
+# First do specials, because they are higher priority than other matches
+# 
+# double-underline/not hidden -> hot text
+# double-underline/hidden -> href
+#    v^bDWUHACSOTIB,v^bDWUHACSOTIB
+"",0,00100000000000,00100010000000,"_Hot"
+"",0,00100010000000,00100010000000,"_HRef"
+
+# hidden/shadow -> literal
+#    v^bDWUHACSOTIB,v^bDWUHACSOTIB
+"",0,00000010010000,00000010010000,"_Literal"
+
+# hidden/outline -> Name
+#    v^bDWUHACSOTIB,v^bDWUHACSOTIB
+"",0,00000010001000,00000010001000,"_Name"
+
+# hidden/all other hiddens are discarded
+"",0,00000010000000,00000010000000,"_Discard"
+
+# All other Superscripts just superscripts
+#    v^bDWUHACSOTIB,v^bDWUHACSOTIB
+"",0,01000000000000,01000000000000,"sup"
+
+# Regular matches - You can have multiple of these active
+
+# monospace fonts -> tt
+"Courier",0,00000000000000,00000000000000,"tt"
+"Monoco",0,00000000000000,00000000000000,"tt"
+
+# bold -> bold
+#    v^bDWUHACSOTIB,v^bDWUHACSOTIB
+"",0,00000000000001,00000000000001,"b"
+
+# italic/underline -> cite, italic/nounderline -> italic
+#    v^bDWUHACSOTIB,v^bDWUHACSOTIB
+"",0,00000000000010,00000100000010,"i"
+"",0,00000100000010,00000100000010,"cite"
+
+# any underline without italic -> underline
+#    v^bDWUHACSOTIB,v^bDWUHACSOTIB
+"",0,00010000000000,00111100000010,"u"
+"",0,00001000000000,00111100000010,"u"
+"",0,00000100000000,00111100000010,"u"
+"",0,00100000000000,00111100000010,"u"
+
+# outline,shadow -> em
+#    v^bDWUHACSOTIB,v^bDWUHACSOTIB
+"",0,00000000001000,00000000001000,"em"
+"",0,00000000010000,00000000010000,"em"
+
+
+# Format:
+# "Paragraph Style",NestLevel,"ParagraphStyleName"
+# First Entry is the default if no style match. Should be level 0 
+# point to a Paragraph style with no markup
+.PMatch
+"Normal",0,"Normal"
+# This is a required entry; tables will be formatted with this entry
+"_Table",0,"_Table"
+"heading 1",0,"h1"
+"heading 2",0,"h2"
+"heading 3",0,"h3"
+"heading 4",0,"h4"
+"heading 5",0,"h5"
+"heading 6",0,"h6"
+"ol",0,"ol"
+"ol 1",1,"ol"
+"ol 2",2,"ol"
+"ol 3",3,"ol"
+"ol 4",4,"ol"
+"ol 5",5,"ol"
+"ul",0,"ul"
+"ul 1",1,"ul"
+"ul 2",2,"ul"
+"ul 3",3,"ul"
+"ul 4",4,"ul"
+"ul 5",5,"ul"
+"numbered list",0,"ol-d"
+"numbered list 1",1,"ol-d"
+"numbered list 2",2,"ol-d"
+"numbered list 3",3,"ol-d"
+"numbered list 4",4,"ol-d"
+"numbered list 5",5,"ol-d"
+"bullet list",0,"ul-d"
+"bullet list 1",1,"ul-d"
+"bullet list 2",2,"ul-d"
+"bullet list 3",3,"ul-d"
+"bullet list 4",4,"ul-d"
+"bullet list 5",5,"ul-d"
+"dir",0,"dir"
+"dir 1",1,"dir"
+"dir 2",2,"dir"
+"dir 3",3,"dir"
+"dir 4",4,"dir"
+"dir 5",5,"dir"
+"small gloss",0,"dl"
+"small gloss 1",1,"dl"
+"small gloss 2",2,"dl"
+"small gloss 3",3,"dl"
+"small gloss 4",4,"dl"
+"small gloss 5",5,"dl"
+"glossary",0,"dl"
+"glossary 1",1,"dl"
+"glossary 2",2,"dl"
+"glossary 3",3,"dl"
+"glossary 4",4,"dl"
+"glossary 5",5,"dl"
+"menu",0,"menu"
+"menu 1",1,"menu"
+"menu 2",2,"menu"
+"menu 3",3,"menu"
+"menu 4",4,"menu"
+"menu 5",5,"menu"
+"pre",0,"pre"
+"blockquote",0,"blockquote"
+"address",0,"address"
+"hr",0,"hr"
+# the following paragraph styles will be discarded
+"toc 1",0,"_Discard"
+"toc 2",0,"_Discard"
+"toc 3",0,"_Discard"
+"toc 4",0,"_Discard"
+"toc 5",0,"_Discard"
+"index 1",0,"_Discard"
+"index 2",0,"_Discard"
+"index 3",0,"_Discard"
+"index 4",0,"_Discard"
+"index 5",0,"_Discard"
+"TERM",0,"TERM"
+"DEF",1,"DEF"
+"TERM 1",1,"TERM"
+"DEF 1",2,"DEF"
+"TERM 2",2,"TERM"
+"DEF 2",3,"DEF"
+"HTML",0,"_Literal"
+"footnote text",0,"Normal"
Index: /gsdl/stable/etc/packages/rtftohtm/mac.gen
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/mac.gen	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/mac.gen	(revision 20131)
@@ -0,0 +1,243 @@
+# RTF Macintosh character set (\mac) general map
+
+# Field 1 is the standard character name which the character value in
+# field 2 maps onto.  (It doesn't mean "to produce the character in field 1,
+# use the value in field 2.)
+
+# The character value may be given either as a single character (which will be
+# converted to the ASCII value of the character), or in numeric format, either
+# in decimal or 0xyy as hex yy.  Single or double quotes may be used to quote
+# characters.
+
+# characters in ASCII range (00-127)
+
+formula		0x06
+nobrkhyphen	0x1e
+opthyphen	0x1f
+
+space		" "
+exclam		!
+quotedbl	'"'
+numbersign	#
+dollar		$
+percent		%
+ampersand	&
+quoteright	"'"
+parenleft	(
+parenright	)
+asterisk	*
+plus		+
+comma		,
+hyphen		-
+period		.
+slash		/
+zero		0
+one		1
+two		2
+three		3
+four		4
+five		5
+six		6
+seven		7
+eight		8
+nine		9
+colon		:
+semicolon	;
+less		<
+equal		=
+greater		>
+question	?
+at		@
+A		A
+B		B
+C		C
+D		D
+E		E
+F		F
+G		G
+H		H
+I		I
+J		J
+K		K
+L		L
+M		M
+N		N
+O		O
+P		P
+Q		Q
+R		R
+S		S
+T		T
+U		U
+V		V
+W		W
+X		X
+Y		Y
+Z		Z
+bracketleft	[
+backslash	\
+bracketright	]
+asciicircum	^
+underscore	_
+quoteleft	"`"
+a		a
+b		b
+c		c
+d		d
+e		e
+f		f
+g		g
+h		h
+i		i
+j		j
+k		k
+l		l
+m		m
+n		n
+o		o
+p		p
+q		q
+r		r
+s		s
+t		t
+u		u
+v		v
+w		w
+x		x
+y		y
+z		z
+braceleft	{
+bar		|
+braceright	}
+asciitilde	~
+
+# non-ASCII characters (128-255)
+
+# ?? Ygrave		0x07
+# ?? yacute		0x08
+Adieresis	0x80
+Aring		0x81
+Ccedilla	0x82
+Eacute		0x83
+Ntilde		0x84
+Odieresis	0x85
+Udieresis	0x86
+aacute		0x87
+agrave		0x88
+acircumflex	0x89
+adieresis	0x8a
+atilde		0x8b
+aring		0x8c
+ccedilla	0x8d
+eacute		0x8e
+egrave		0x8f
+ecircumflex	0x90
+edieresis	0x91
+iacute		0x92
+igrave		0x93
+icircumflex	0x94
+idieresis	0x95
+ntilde		0x96
+oacute		0x97
+ograve		0x98
+ocircumflex	0x99
+odieresis	0x9a
+otilde		0x9b
+uacute		0x9c
+ugrave		0x9d
+ucircumflex	0x9e
+udieresis	0x9f
+dagger		0xa0
+degree		0xa1
+cent		0xa2
+sterling	0xa3
+section		0xa4
+bullet		0xa5
+paragraph	0xa6
+germandbls	0xa7
+registered	0xa8
+copyright	0xa9
+trademark	0xaa
+acute		0xab
+dieresis	0xac
+notequal	0xad
+AE		0xae
+Oslash		0xaf
+infinity	0xb0
+plusminus	0xb1
+lessequal	0xb2
+greaterequal	0xb3
+yen		0xb4
+mu		0xb5
+partialdiff	0xb6
+Sigma		0xb7
+Pi		0xb8
+pi		0xb9
+integral	0xba
+ordfeminine	0xbb
+ordmasculine	0xbc
+Omega		0xbd
+ae		0xbe
+oslash		0xbf
+questiondown	0xc0
+exclamdown	0xc1
+logicalnot	0xc2
+radical		0xc3
+florin		0xc4
+approxequal	0xc5
+Delta		0xc6
+guillemotleft	0xc7
+guillemotright	0xc8
+ellipsis	0xc9
+nobrkspace	0xca
+Agrave		0xcb
+OE		0xce
+oe		0xcf
+endash		0xd0
+emdash		0xd1
+quotedblleft	0xd2
+quotedblright	0xd3
+quoteleft	0xd4
+quoteright	0xd5
+divide		0xd6
+lozenge		0xd7
+ydieresis	0xd8
+Ydieresis	0xd9
+fraction	0xda
+currency	0xdb
+guilsinglleft	0xdc
+guilsinglright	0xdd
+fi		0xde
+fl		0xdf
+daggerdbl	0xe0
+periodcentered	0xe1
+quotesinglbase	0xe2
+quotedblbase	0xe3
+perthousand	0xe4
+Acircumflex	0xe5
+Ecircumflex	0xe6
+Aacute		0xe7
+Edieresis	0xe8
+Egrave		0xe9
+Iacute		0xea
+Icircumflex	0xeb
+Idieresis	0xec
+Igrave		0xed
+Oacute		0xee
+Ocircumflex	0xef
+apple		0xf0
+Ograve		0xf1
+Uacute		0xf2
+Ucircumflex	0xf3
+Ugrave		0xf4
+dotlessi	0xf5
+circumflex	0xf6
+tilde		0xf7
+macron		0xf8
+breve		0xf9
+dotaccent	0xfa
+ring		0xfb
+cedilla		0xfc
+hungarumlaut	0xfd
+ogonek		0xfe
+caron		0xff
Index: /gsdl/stable/etc/packages/rtftohtm/mac.sym
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/mac.sym	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/mac.sym	(revision 20131)
@@ -0,0 +1,241 @@
+# RTF Macintosh character set (\mac) Symbol font map
+
+# Field 1 is the standard character name which the character value in
+# field 2 maps onto.  (It doesn't mean "to produce the character in field 1,
+# use the value in field 2.)
+
+# The character value may be given either as a single character (which will be
+# converted to the ASCII value of the character), or in numeric format, either
+# in decimal or 0xyy as hex yy.  Single or double quotes may be used to quote
+# characters.
+
+# characters in ASCII range (00-127)
+
+formula		0x06
+nobrkhyphen	0x1e
+opthyphen	0x1f
+
+space		" "
+exclam		!
+universal	'"'
+mathnumbersign	#
+existential	$
+percent		%
+ampersand	&
+suchthat	"'"
+parenleft	(
+parenright	)
+mathasterisk	*
+mathplus	+
+comma		,
+mathminus	-
+period		.
+slash		/
+zero		0
+one		1
+two		2
+three		3
+four		4
+five		5
+six		6
+seven		7
+eight		8
+nine		9
+colon		:
+semicolon	;
+less		<
+mathequal	=
+greater		>
+question	?
+congruent	@
+Alpha		A
+Beta		B
+Chi		C
+Delta		D
+Epsilon		E
+Phi		F
+Gamma		G
+Eta		H
+Iota		I
+# J		J
+Kappa		K
+Lambda		L
+Mu		M
+Nu		N
+Omicron		O
+Pi		P
+Theta		Q
+Rho		R
+Sigma		S
+Tau		T
+Upsilon		U
+varsigma	V
+Omega		W
+Xi		X
+Psi		Y
+Zeta		Z
+bracketleft	[
+backslash	\
+bracketright	]
+asciicircum	^
+underscore	_
+quoteleft	"`"
+alpha		a
+beta		b
+chi		c
+delta		d
+epsilon		e
+phi		f
+gamma		g
+eta		h
+iota		i
+# j		j
+kappa		k
+lambda		l
+mu		m
+nu		n
+omicron		o
+pi		p
+theta		q
+rho		r
+sigma		s
+tau		t
+upsilon		u
+# xxx		v
+omega		w
+xi		x
+psi		y
+zeta		z
+braceleft	{
+bar		|
+braceright	}
+mathtilde	~
+
+# non-ASCII characters (128-255)
+
+# Adieresis	0x80
+# Aring		0x81
+# Ccedilla	0x82
+# Eacute	0x83
+# Ntilde	0x84
+# Odieresis	0x85
+# Udieresis	0x86
+# aacute	0x87
+# agrave	0x88
+# acircumflex	0x89
+# adieresis	0x8a
+# atilde	0x8b
+# aring		0x8c
+# ccedilla	0x8d
+# eacute	0x8e
+# egrave	0x8f
+# ecircumflex	0x90
+# edieresis	0x91
+# iacute	0x92
+# igrave	0x93
+# icircumflex	0x94
+# idieresis	0x95
+# ntilde	0x96
+# oacute	0x97
+# ograve	0x98
+# ocircumflex	0x99
+# odieresis	0x9a
+# otilde	0x9b
+# uacute	0x9c
+# ugrave	0x9d
+# ucircumflex	0x9e
+# udieresis	0x9f
+# dagger	0xa0
+# degree	0xa1
+minute		0xa2
+lessequal	0xa3
+fraction	0xa4
+infinity	0xa5
+florin		0xa6
+club		0xa7
+diamond		0xa8
+heart		0xa9
+spade		0xaa
+arrowboth	0xab
+arrowleft	0xac
+arrowup		0xad
+arrowright	0xae
+arrowdown	0xaf
+degree		0xb0
+plusminus	0xb1
+second		0xb2
+greaterequal	0xb3
+multiply	0xb4
+proportional	0xb5
+partialdiff	0xb6
+bullet		0xb7
+divide		0xb8
+notequal	0xb9
+equivalence	0xba
+approxequal	0xbb
+ellipsis	0xbc
+arrowvertex	0xbd
+arrowhorizex	0xbe
+carriagereturn	0xbf
+aleph		0xc0
+Ifraktur	0xc1
+Rfraktur	0xc2
+weierstrass	0xc3
+circlemultiply	0xc4
+circleplus	0xc5
+emptyset	0xc6
+intersection	0xc7
+union		0xc8
+propersuperset	0xc9
+reflexsuperset	0xca
+notsubset	0xcb
+propersubset	0xce
+reflexsubset	0xcf
+angle		0xd0
+gradient	0xd1
+registered	0xd2
+copyright	0xd3
+trademark	0xd4
+product		0xd5
+radical		0xd6
+periodcentered	0xd7
+logicalnot	0xd8
+logicaland	0xd9
+logicalor	0xda
+arrowdblboth	0xdb
+arrowdblleft	0xdc
+arrowdblup	0xdd
+arrowdblright	0xde
+arrowdbldown	0xdf
+lozenge		0xe0
+angleleft	0xe1
+registersans	0xe2
+copyrightsans	0xe3
+trademarksans	0xe4
+Sigma		0xe5
+# Ecircumflex	0xe6
+# Aacute	0xe7
+# Edieresis	0xe8
+# Egrave	0xe9
+# Iacute	0xea
+# Icircumflex	0xeb
+# Idieresis	0xec
+# Igrave	0xed
+# Oacute	0xee
+# Ocircumflex	0xef
+apple		0xf0
+angleright	0xf1
+# Uacute	0xf2
+# Ucircumflex	0xf3
+# Ugrave	0xf4
+# dotlessi	0xf5
+# circumflex	0xf6
+# tilde		0xf7
+# macron	0xf8
+# breve		0xf9
+# dotaccent	0xfa
+# ring		0xfb
+# cedilla	0xfc
+# hungarumlaut	0xfd
+# ogonek	0xfe
+# caron		0xff
Index: /gsdl/stable/etc/packages/rtftohtm/pc.gen
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/pc.gen	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/pc.gen	(revision 20131)
@@ -0,0 +1,243 @@
+# RTF PC character set (\pc) general map
+
+# Field 1 is the standard character name which the character value in
+# field 2 maps onto.  (It doesn't mean "to produce the character in field 1,
+# use the value in field 2.)
+
+# The character value may be given either as a single character (which will be
+# converted to the ASCII value of the character), or in numeric format, either
+# in decimal or 0xyy as hex yy.  Single or double quotes may be used to quote
+# characters.
+
+# characters in ASCII range (32-127)
+
+formula		0x06
+nobrkhyphen	0x1e
+opthyphen	0x1f
+
+space		" "
+exclam		!
+quotedbl	'"'
+numbersign	#
+dollar		$
+percent		%
+ampersand	&
+quoteright	"'"
+parenleft	(
+parenright	)
+asterisk	*
+plus		+
+comma		,
+hyphen		-
+period		.
+slash		/
+zero		0
+one		1
+two		2
+three		3
+four		4
+five		5
+six		6
+seven		7
+eight		8
+nine		9
+colon		:
+semicolon	;
+less		<
+equal		=
+greater		>
+question	?
+at		@
+A		A
+B		B
+C		C
+D		D
+E		E
+F		F
+G		G
+H		H
+I		I
+J		J
+K		K
+L		L
+M		M
+N		N
+O		O
+P		P
+Q		Q
+R		R
+S		S
+T		T
+U		U
+V		V
+W		W
+X		X
+Y		Y
+Z		Z
+bracketleft	[
+backslash	\
+bracketright	]
+asciicircum	^
+underscore	_
+quoteleft	"`"
+a		a
+b		b
+c		c
+d		d
+e		e
+f		f
+g		g
+h		h
+i		i
+j		j
+k		k
+l		l
+m		m
+n		n
+o		o
+p		p
+q		q
+r		r
+s		s
+t		t
+u		u
+v		v
+w		w
+x		x
+y		y
+z		z
+braceleft	{
+bar		|
+braceright	}
+asciitilde	~
+
+# non-ASCII characters (128-255)
+
+Ccedilla	0x80
+udieresis	0x81
+eacute		0x82
+acircumflex	0x83
+adieresis	0x84
+agrave		0x85
+aring		0x86
+ccedilla	0x87
+ecircumflex	0x88
+edieresis	0x89
+egrave		0x8a
+idieresis	0x8b
+icircumflex	0x8c
+igrave		0x8d
+Adieresis	0x8e
+Aring		0x8f
+Eacute		0x90
+ae		0x91
+AE		0x92
+ocircumflex	0x93
+odieresis	0x94
+ograve		0x95
+ucircumflex	0x96
+ugrave		0x97
+ydieresis	0x98
+Odieresis	0x99
+Udieresis	0x9a
+cent		0x9b
+sterling	0x9c
+yen		0x9d
+ucircumflex	0x9e
+florin		0x9f
+aacute		0xa0
+iacute		0xa1
+oacute		0xa2
+uacute		0xa3
+ntilde		0xa4
+Ntilde		0xa5
+ordfeminine	0xa6
+ordmasculine	0xa7
+questiondown	0xa8
+copyright	0xa9
+trademark	0xaa
+acute		0xab
+dieresis	0xac
+exclamdown	0xad
+guillemotleft	0xae
+guillemotright	0xaf
+space		0xb0
+plusminus	0xb1
+lessequal	0xb2
+bar		0xb3
+yen		0xb4
+mu		0xb5
+partialdiff	0xb6
+Sigma		0xb7
+Pi		0xb8
+pi		0xb9
+integral	0xba
+ordfeminine	0xbb
+ordmasculine	0xbc
+Omega		0xbd
+ae		0xbe
+logicalnot	0xbf
+questiondown	0xc0
+exclamdown	0xc1
+logicalnot	0xc2
+radical		0xc3
+emdash		0xc4
+approxequal	0xc5
+delta		0xc6
+guillemotleft	0xc7
+guillemotright	0xc8
+ellipsis	0xc9
+nobrkspace	0xca
+Agrave		0xcb
+Atilde		0xcc
+Otilde		0xcd
+OE		0xce
+oe		0xcf
+endash		0xd0
+emdash		0xd1
+quotedblleft	0xd2
+quotedblright	0xd3
+quoteleft	0xd4
+quoteright	0xd5
+divide		0xd6
+lozenge		0xd7
+ydieresis	0xd8
+Ydieresis	0xd9
+fraction	0xda
+Ydieresis	0xdb
+guilsinglleft	0xdc
+greater		0xdd
+less		0xde
+fl		0xdf
+a		0xe0
+germandbls	0xe1
+quotesinglbase	0xe2
+pi		0xe3
+Sigma		0xe4
+Acircumflex	0xe5
+mu		0xe6
+Aacute		0xe7
+Edieresis	0xe8
+Egrave		0xe9
+Omega		0xea
+partialdiff	0xeb
+infinity	0xec
+oslash		0xed
+e		0xee
+Ocircumflex	0xef
+equal		0xf0
+plusminus	0xf1
+greaterequal	0xf2
+lessequal	0xf3
+integral	0xf4
+integral	0xf5
+divide		0xf6
+approxequal	0xf7
+degree		0xf8
+bullet		0xf9
+bullet		0xfa
+radical		0xfb
+cedilla		0xfc
+hungarumlaut	0xfd
+ogonek		0xfe
+nobrkspace	0xff
Index: /gsdl/stable/etc/packages/rtftohtm/pc.sym
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/pc.sym	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/pc.sym	(revision 20131)
@@ -0,0 +1,115 @@
+# RTF PC character set (\pc) Symbol font map
+
+# Field 1 is the standard character name which the character value in
+# field 2 maps onto.  (It doesn't mean "to produce the character in field 1,
+# use the value in field 2.)
+
+# The character value may be given either as a single character (which will be
+# converted to the ASCII value of the character), or in numeric format, either
+# in decimal or 0xyy as hex yy.  Single or double quotes may be used to quote
+# characters.
+
+# characters in ASCII range (00-127)
+
+formula		0x06
+nobrkhyphen	0x1e
+opthyphen	0x1f
+
+space		" "
+exclam		!
+universal	'"'
+mathnumbersign	#
+existential	$
+percent		%
+ampersand	&
+suchthat	"'"
+parenleft	(
+parenright	)
+mathasterisk	*
+mathplus	+
+comma		,
+mathminus	-
+period		.
+slash		/
+zero		0
+one		1
+two		2
+three		3
+four		4
+five		5
+six		6
+seven		7
+eight		8
+nine		9
+colon		:
+semicolon	;
+less		<
+mathequal	=
+greater		>
+question	?
+congruent	@
+Alpha		A
+Beta		B
+Chi		C
+Delta		D
+Epsilon		E
+Phi		F
+Gamma		G
+Eta		H
+Iota		I
+# J		J
+Kappa		K
+Lambda		L
+Mu		M
+Nu		N
+Omicron		O
+Pi		P
+Theta		Q
+Rho		R
+Sigma		S
+Tau		T
+Upsilon		U
+varsigma	V
+Omega		W
+Xi		X
+Psi		Y
+Zeta		Z
+bracketleft	[
+backslash	\
+bracketright	]
+asciicircum	^
+underscore	_
+quoteleft	"`"
+alpha		a
+beta		b
+chi		c
+delta		d
+epsilon		e
+phi		f
+gamma		g
+eta		h
+iota		i
+# j		j
+kappa		k
+lambda		l
+mu		m
+nu		n
+omicron		o
+pi		p
+theta		q
+rho		r
+sigma		s
+tau		t
+upsilon		u
+# xxx		v
+omega		w
+xi		x
+psi		y
+zeta		z
+braceleft	{
+bar		|
+braceright	}
+mathtilde	~
+
+# non-ASCII characters (128-255)
+
Index: /gsdl/stable/etc/packages/rtftohtm/pca.gen
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/pca.gen	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/pca.gen	(revision 20131)
@@ -0,0 +1,244 @@
+# RTF PC-A character set (\pca) general map
+
+# Field 1 is the standard character name which the character value in
+# field 2 maps onto.  (It doesn't mean "to produce the character in field 1,
+# use the value in field 2.)
+
+# The character value may be given either as a single character (which will be
+# converted to the ASCII value of the character), or in numeric format, either
+# in decimal or 0xyy as hex yy.  Single or double quotes may be used to quote
+# characters.
+
+# characters in ASCII range (32-127)
+
+formula		0x06
+nobrkhyphen	0x1e
+opthyphen	0x1f
+
+space		" "
+exclam		!
+quotedbl	'"'
+numbersign	#
+dollar		$
+percent		%
+ampersand	&
+quoteright	"'"
+parenleft	(
+parenright	)
+asterisk	*
+plus		+
+comma		,
+hyphen		-
+period		.
+slash		/
+zero		0
+one		1
+two		2
+three		3
+four		4
+five		5
+six		6
+seven		7
+eight		8
+nine		9
+colon		:
+semicolon	;
+less		<
+equal		=
+greater		>
+question	?
+at		@
+A		A
+B		B
+C		C
+D		D
+E		E
+F		F
+G		G
+H		H
+I		I
+J		J
+K		K
+L		L
+M		M
+N		N
+O		O
+P		P
+Q		Q
+R		R
+S		S
+T		T
+U		U
+V		V
+W		W
+X		X
+Y		Y
+Z		Z
+bracketleft	[
+backslash	\
+bracketright	]
+asciicircum	^
+underscore	_
+quoteleft	"`"
+a		a
+b		b
+c		c
+d		d
+e		e
+f		f
+g		g
+h		h
+i		i
+j		j
+k		k
+l		l
+m		m
+n		n
+o		o
+p		p
+q		q
+r		r
+s		s
+t		t
+u		u
+v		v
+w		w
+x		x
+y		y
+z		z
+braceleft	{
+bar		|
+braceright	}
+asciitilde	~
+
+# non-ASCII characters (128-255)
+
+
+Ccedilla	0x80
+udieresis	0x81
+eacute		0x82
+acircumflex	0x83
+adieresis	0x84
+agrave		0x85
+aring		0x86
+ccedilla	0x87
+ecircumflex	0x88
+edieresis	0x89
+egrave		0x8a
+idieresis	0x8b
+icircumflex	0x8c
+igrave		0x8d
+Adieresis	0x8e
+Aring		0x8f
+Eacute		0x90
+ae		0x91
+AE		0x92
+ocircumflex	0x93
+odieresis	0x94
+ograve		0x95
+ucircumflex	0x96
+ugrave		0x97
+ydieresis	0x98
+Odieresis	0x99
+Udieresis	0x9a
+oslash		0x9b
+sterling	0x9c
+Oslash		0x9d
+# ???		0x9e
+florin		0x9f
+aacute		0xa0
+iacute		0xa1
+oacute		0xa2
+uacute		0xa3
+ntilde		0xa4
+Ntilde		0xa5
+ordfeminine	0xa6
+ordmasculine	0xa7
+questiondown	0xa8
+registered	0xa9
+logicalnot	0xaa
+# ???		0xab
+# ???		0xac
+exclamdown	0xad
+guillemotleft	0xae
+guillemotright	0xaf
+# ???		0xb0
+# ???		0xb1
+# ???		0xb2
+# ???		0xb3
+# ???		0xb4
+# ???		0xb5
+# ???		0xb6
+Agrave		0xb7
+copyright	0xb8
+# ???		0xb9
+# ???		0xba
+# ???		0xbb
+# ???		0xbc
+cent		0xbd
+yen		0xbe
+# ???		0xbf
+# ???		0xc0
+# ???		0xc1
+# ???		0xc2
+# ???		0xc3
+# ???		0xc4
+# ???		0xc5
+atilde		0xc6
+Atilde		0xc7
+# ???		0xc8
+# ???		0xc9
+# ???		0xca
+# ???		0xcb
+# ???		0xcc
+# ???		0xcd
+# ???		0xce
+# ???		0xcf
+partialdiff	0xd0
+# ???		0xd1
+# ???		0xd2
+# ???		0xd3
+# ???		0xd4
+# ???		0xd5
+# ???		0xd6
+# ???		0xd7
+# ???		0xd8
+# ???		0xd9
+# ???		0xda
+# ???		0xdb
+# ???		0xdc
+# ???		0xdd
+# ???		0xde
+# ???		0xdf
+# ???		0xe0
+germandbls	0xe1
+# ???		0xe2
+# ???		0xe3
+otilde		0xe4
+Otilde		0xe5
+mu		0xe6
+# ???		0xe7
+# ???		0xe8
+# ???		0xe9
+# ???		0xea
+# ???		0xeb
+# ???		0xec
+# ???		0xed
+# ???		0xee
+acute		0xef
+endash		0xf0
+plusminus	0xf1
+equal		0xf2
+# ???		0xf3
+paragraph	0xf4
+section		0xf5
+divide		0xf6
+# ???		0xf7
+degree		0xf8
+dieresis	0xf9
+bullet		0xfa
+# ???		0xfb
+# ???		0xfc
+# ???		0xfd
+# ???		0xfe
+nobrkspace	0xff
Index: /gsdl/stable/etc/packages/rtftohtm/pca.sym
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/pca.sym	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/pca.sym	(revision 20131)
@@ -0,0 +1,115 @@
+# RTF PC-A character set (\pca) Symbol font map
+
+# Field 1 is the standard character name which the character value in
+# field 2 maps onto.  (It doesn't mean "to produce the character in field 1,
+# use the value in field 2.)
+
+# The character value may be given either as a single character (which will be
+# converted to the ASCII value of the character), or in numeric format, either
+# in decimal or 0xyy as hex yy.  Single or double quotes may be used to quote
+# characters.
+
+# characters in ASCII range (00-127)
+
+formula		0x06
+nobrkhyphen	0x1e
+opthyphen	0x1f
+
+space		" "
+exclam		!
+universal	'"'
+mathnumbersign	#
+existential	$
+percent		%
+ampersand	&
+suchthat	"'"
+parenleft	(
+parenright	)
+mathasterisk	*
+mathplus	+
+comma		,
+mathminus	-
+period		.
+slash		/
+zero		0
+one		1
+two		2
+three		3
+four		4
+five		5
+six		6
+seven		7
+eight		8
+nine		9
+colon		:
+semicolon	;
+less		<
+mathequal	=
+greater		>
+question	?
+congruent	@
+Alpha		A
+Beta		B
+Chi		C
+Delta		D
+Epsilon		E
+Phi		F
+Gamma		G
+Eta		H
+Iota		I
+# J		J
+Kappa		K
+Lambda		L
+Mu		M
+Nu		N
+Omicron		O
+Pi		P
+Theta		Q
+Rho		R
+Sigma		S
+Tau		T
+Upsilon		U
+varsigma	V
+Omega		W
+Xi		X
+Psi		Y
+Zeta		Z
+bracketleft	[
+backslash	\
+bracketright	]
+asciicircum	^
+underscore	_
+quoteleft	"`"
+alpha		a
+beta		b
+chi		c
+delta		d
+epsilon		e
+phi		f
+gamma		g
+eta		h
+iota		i
+# j		j
+kappa		k
+lambda		l
+mu		m
+nu		n
+omicron		o
+pi		p
+theta		q
+rho		r
+sigma		s
+tau		t
+upsilon		u
+# xxx		v
+omega		w
+xi		x
+psi		y
+zeta		z
+braceleft	{
+bar		|
+braceright	}
+mathtilde	~
+
+# non-ASCII characters (128-255)
+
Index: /gsdl/stable/etc/packages/rtftohtm/rtf-ctrl
===================================================================
--- /gsdl/stable/etc/packages/rtftohtm/rtf-ctrl	(revision 20131)
+++ /gsdl/stable/etc/packages/rtftohtm/rtf-ctrl	(revision 20131)
@@ -0,0 +1,769 @@
+# number of control words
+766
+# control word table
+6 0 "vern"
+6 5 "edmins"
+6 6 "yr"
+6 7 "mo"
+6 8 "dy"
+6 9 "hr"
+6 10 "min"
+6 11 "sec"
+6 12 "nofpages"
+6 13 "nofwords"
+6 14 "nofchars"
+6 15 "id"
+6 16 "chdate"
+6 17 "chdpl"
+6 18 "chdpa"
+6 19 "chtime"
+6 20 "chpgn"
+6 21 "sectnum"
+6 22 "chftn"
+6 23 "chatn"
+6 24 "chftnsep"
+6 25 "chftnsepc"
+6 26 "cell"
+6 27 "row"
+6 28 "par"
+6 28 "\n"
+6 28 "\r"
+6 29 "sect"
+6 30 "page"
+6 31 "column"
+6 32 "line"
+6 33 "softpage"
+6 34 "softcol"
+6 35 "softline"
+6 36 "softlheight"
+6 37 "tab"
+6 38 "emdash"
+6 39 "endash"
+6 40 "emspace"
+6 41 "enspace"
+6 42 "bullet"
+6 43 "lquote"
+6 44 "rquote"
+6 45 "ldblquote"
+6 46 "rdblquote"
+6 47 "|"
+6 49 "~"
+6 50 "-"
+6 51 "_"
+6 52 "*"
+6 53 "ltrmark"
+6 54 "rtlmark"
+6 55 "zwj"
+6 56 "zwnj"
+6 57 "chpict"
+6 59 "version"
+12 0 "plain"
+12 1 "b"
+12 2 "caps"
+12 37 "cgrid"
+12 3 "deleted"
+12 4 "dn"
+12 5 "sub"
+12 6 "nosupersub"
+12 7 "expnd"
+12 8 "expndtw"
+12 9 "kerning"
+12 38 "langfe"
+12 39 "langfenp"
+12 35 "lang"
+12 40 "langnp"
+12 10 "f"
+12 11 "fs"
+12 12 "i"
+12 13 "outl"
+12 14 "revised"
+12 15 "revauth"
+12 16 "revdttm"
+12 17 "scaps"
+12 18 "shad"
+12 19 "strike"
+12 20 "ul"
+12 21 "uld"
+12 22 "uldb"
+12 23 "ulnone"
+12 24 "ulw"
+12 25 "up"
+12 26 "super"
+12 27 "v"
+12 28 "cf"
+12 29 "cb"
+12 30 "rtlch"
+12 31 "ltrch"
+12 32 "noproof"
+12 33 "cs"
+12 34 "cchs"
+12 36 "gray"
+11 0 "pard"
+11 1 "s"
+11 2 "hyphpar"
+11 3 "intbl"
+11 104 "itap"
+11 4 "keep"
+11 6 "keepn"
+11 7 "level"
+11 8 "noline"
+11 5 "nowidctlpar"
+11 105 "widctlpar"
+11 7 "outlinelevel"
+11 9 "pagebb"
+11 10 "sbys"
+11 11 "ql"
+11 12 "qr"
+11 13 "qj"
+11 14 "qc"
+11 15 "fi"
+11 16 "li"
+11 16 "lin"
+11 17 "ri"
+11 17 "rin"
+11 17 "curi"
+11 106 "adjustright"
+11 18 "sb"
+11 19 "sa"
+11 20 "sl"
+11 21 "slmult"
+11 22 "subdocument"
+11 23 "rtlpar"
+11 24 "ltrpar"
+11 25 "tx"
+11 26 "tql"
+11 27 "tqr"
+11 28 "tqc"
+11 29 "tqdec"
+11 30 "tb"
+11 31 "tldot"
+11 32 "tlhyph"
+11 33 "tlul"
+11 34 "tlth"
+11 35 "tleq"
+11 36 "pnlvl"
+11 37 "pnlvlblt"
+11 38 "pnlvlbody"
+11 39 "pnlvlcont"
+11 40 "pnnumonce"
+11 41 "pnacross"
+11 42 "pnhang"
+11 43 "pnrestart"
+11 44 "pncard"
+11 45 "pndec"
+11 46 "pnucltr"
+11 47 "pnucrm"
+11 48 "pnlcltr"
+11 49 "pnlcrm"
+11 50 "pnord"
+11 51 "pnordt"
+11 52 "pnb"
+11 53 "pni"
+11 54 "pncaps"
+11 55 "pnscaps"
+11 56 "pnul"
+11 57 "pnuld"
+11 58 "pnuldb"
+11 59 "pnulnone"
+11 60 "pnulw"
+11 61 "pnstrike"
+11 62 "pncf"
+11 63 "pnf"
+11 64 "pnfs"
+11 65 "pnindent"
+11 66 "pnsp"
+11 67 "pnprev"
+11 68 "pnqc"
+11 69 "pnql"
+11 70 "pnqr"
+11 71 "pnstart"
+11 72 "brdrt"
+11 73 "brdrb"
+11 74 "brdrl"
+11 75 "brdrr"
+11 76 "brdrbtw"
+11 77 "brdrbar"
+11 78 "box"
+11 79 "brdrs"
+11 80 "brdrth"
+11 81 "brdrsh"
+11 82 "brdrdb"
+11 83 "brdrdot"
+11 83 "brdrdash"
+11 85 "brdrhair"
+11 86 "brdrw"
+11 87 "brdrcf"
+11 88 "brsp"
+11 89 "shading"
+11 90 "bghoriz"
+11 91 "bgvert"
+11 92 "bgfdiag"
+11 93 "bgbdiag"
+11 94 "bgcross"
+11 95 "bgdcross"
+11 96 "bgdkhoriz"
+11 97 "bgdkvert"
+11 98 "bgdkfdiag"
+11 99 "bgdkbdiag"
+11 100 "bgdkcross"
+11 101 "bgdkdcross"
+11 102 "cfpat"
+11 103 "cbpat"
+11 39 "ls"
+11 40 "ilvl"
+9 0 "sectd"
+9 1 "endnhere"
+9 2 "binfsxn"
+9 3 "binsxn"
+9 4 "ds"
+9 5 "sbknone"
+9 6 "sbkcol"
+9 7 "sbkpage"
+9 8 "sbkeven"
+9 9 "sbkodd"
+9 10 "cols"
+9 11 "colsx"
+9 12 "colno"
+9 13 "colsr"
+9 14 "colw"
+9 15 "linebetcol"
+9 16 "linemod"
+9 17 "linex"
+9 18 "linestarts"
+9 19 "linerestart"
+9 20 "lineppage"
+9 21 "linecont"
+9 22 "pgwsxn"
+9 23 "pghsxn"
+9 24 "marglsxn"
+9 25 "margrsxn"
+9 26 "margtsxn"
+9 27 "margbsxn"
+9 28 "guttersxn"
+9 29 "lndscpsxn"
+9 30 "titlepg"
+9 31 "headery"
+9 32 "footery"
+9 33 "pgnstarts"
+9 34 "pgncont"
+9 35 "pgnrestart"
+9 36 "pgnx"
+9 37 "pgny"
+9 38 "pgndec"
+9 39 "pgnucrm"
+9 40 "pgnlcrm"
+9 41 "pgnucltr"
+9 42 "pgnlcltr"
+9 43 "pgnhnsh"
+9 44 "pgnhnsp"
+9 45 "pgnhnsc"
+9 46 "pgnhnsm"
+9 47 "pgnhnsn"
+9 48 "vertalt"
+9 49 "vertalb"
+9 50 "vertalc"
+9 51 "vertalj"
+9 52 "rtlsect"
+9 53 "ltrsect"
+9 54 "horzsect"
+9 55 "vertsect"
+9 100 "sectexpand"
+9 100 "sectlinegrid"
+9 100 "sectdefaultcl"
+9 100 "sectspecifycl"
+9 100 "sectspecifyl"
+9 100 "sectspecifygen"
+9 56 "pgnhn"
+9 57 "sectunlocked"
+8 160 "uc"
+8 0 "deftab"
+8 1 "hyphhotz"
+8 2 "hyphconsec"
+8 3 "hyphcaps"
+8 4 "hyphauto"
+8 5 "linestart"
+8 6 "fracwidth"
+8 7 "makeback"
+8 7 "makebackup"
+8 8 "defformat"
+8 9 "psover"
+8 10 "doctemp"
+8 11 "deflang"
+8 150 "deflangfe"
+8 151 "windowcaption"
+8 152 "doctype"
+8 153 "fromtext"
+8 154 "fromhtml"
+8 155 "horzdoc"
+8 156 "vertdoc"
+8 157 "jcompress"
+8 158 "jexpand"
+8 159 "lnongrid"
+8 78 "viewkind"
+8 79 "viewscale"
+8 79 "viewzk"
+8 12 "fet"
+8 13 "endnotes"
+8 14 "enddoc"
+8 15 "ftntj"
+8 16 "ftnbj"
+8 17 "aendnotes"
+8 18 "aenddoc"
+8 19 "aftntj"
+8 20 "aftnbj"
+8 21 "ftnstart"
+8 22 "aftnstart"
+8 23 "ftnrstpg"
+8 24 "ftnrestart"
+8 25 "ftnrstcont"
+8 26 "aftnrestart"
+8 27 "aftnrstcont"
+8 28 "ftnnar"
+8 29 "ftnnalc"
+8 30 "ftnnauc"
+8 31 "ftnnrlc"
+8 32 "ftnnruc"
+8 33 "ftnnchi"
+8 34 "aftnnar"
+8 35 "aftnnalc"
+8 36 "aftnnauc"
+8 37 "aftnnrlc"
+8 38 "aftnnruc"
+8 39 "aftnnchi"
+8 40 "paperw"
+8 41 "paperh"
+8 42 "psz"
+8 43 "margl"
+8 44 "margr"
+8 45 "margt"
+8 46 "margb"
+8 47 "facingp"
+8 48 "gutter"
+8 49 "margmirror"
+8 50 "landscape"
+8 51 "pgnstart"
+8 52 "widowctrl"
+8 53 "linkstyles"
+8 54 "notabind"
+8 55 "wraptrsp"
+8 56 "prcolbl"
+8 57 "noextrasprl"
+8 58 "nocolbal"
+8 59 "cvmme"
+8 60 "sprstsp"
+8 61 "sprsspbf"
+8 62 "otblrul"
+8 63 "transmf"
+8 64 "swpbdr"
+8 65 "brkfrm"
+8 82 "formprot"
+8 83 "allprot"
+8 84 "formshade"
+8 85 "formdisp"
+8 86 "printdata"
+8 87 "revprot"
+8 88 "revisions"
+8 89 "revprop"
+8 90 "revbar"
+8 91 "annotprot"
+8 92 "rtldoc"
+8 93 "ltrdoc"
+8 94 "cts"
+8 95 "dghspace"
+8 96 "dgvspace"
+8 97 "dghorigin"
+8 98 "dgvorigin"
+8 99 "dghshow"
+8 100 "dgvshow"
+8 101 "dgsnap"
+8 102 "dgmargin"
+8 103 "pgbrdrhead"
+8 104 "pgbrdrfoot"
+8 105 "aspalpha"
+8 106 "aspnum"
+8 107 "faauto"
+8 66 "truncex"
+8 67 "bdbfhdr"
+8 68 "dntblnsbdb"
+8 69 "expshrtn"
+8 70 "lytexcttp"
+8 71 "lytprtmet"
+8 72 "msmcap"
+8 73 "nolead"
+8 74 "nospaceforul"
+8 75 "noultrlspc"
+8 76 "noxlattoyen"
+8 77 "oldas"
+8 78 "lnbrkrule"
+8 79 "bdrrlswsix"
+8 81 "sprstsm"
+8 80 "nolnhtadjtbl"
+7 0 "additive"
+7 1 "sbasedon"
+7 2 "snext"
+7 3 "sautoupd"
+13 32 "emfblip"
+13 33 "pngblip"
+13 34 "jpegblip"
+13 36 "nonshppict"
+13 0 "macpict"
+13 1 "pmmetafile"
+13 2 "wmetafile"
+13 3 "dibitmap"
+13 4 "wbitmap"
+13 5 "wbmbitspixel"
+13 6 "wbmplanes"
+13 7 "wbmwidthbytes"
+13 8 "picw"
+13 9 "pich"
+13 10 "picwgoal"
+13 11 "pichgoal"
+13 10 "picwGoal"
+13 11 "pichGoal"
+13 12 "picscalex"
+13 13 "picscaley"
+13 14 "picscaled"
+13 15 "piccropt"
+13 16 "piccropb"
+13 17 "piccropl"
+13 18 "piccropr"
+13 19 "picbmp"
+13 20 "picbpp"
+13 21 "bin"
+13 22 "blipupi"
+13 24 "bliptag"
+15 0 "width"
+15 1 "height"
+3 0 "fonttbl"
+3 1 "falt"
+3 2 "fonteb"
+3 3 "fontfile"
+3 4 "filetbl"
+3 5 "file"
+3 6 "colortbl"
+3 7 "stylesheet"
+3 8 "keycode"
+3 9 "revtbl"
+3 10 "info"
+3 11 "title"
+3 12 "subject"
+3 13 "author"
+3 14 "operator"
+3 15 "keywords"
+3 16 "comment"
+3 18 "doccomm"
+3 19 "verscomm"
+3 20 "nextfile"
+3 21 "template"
+3 22 "ftnsep"
+3 23 "ftnsepc"
+3 24 "ftncn"
+3 25 "aftnsep"
+3 26 "aftnsepc"
+3 27 "aftncn"
+3 29 "pnseclvl"
+3 30 "header"
+3 31 "footer"
+3 32 "headerl"
+3 33 "headerr"
+3 34 "headerf"
+3 35 "footerl"
+3 36 "footerr"
+3 37 "footerf"
+3 38 "pntext"
+3 39 "pn"
+3 40 "pntxta"
+3 41 "pntxtb"
+3 42 "bkmkstart"
+3 43 "bkmkend"
+3 44 "pict"
+3 45 "object"
+3 46 "objclass"
+3 47 "objname"
+3 48 "objtime"
+3 49 "objdata"
+3 50 "objalias"
+3 51 "objsect"
+3 53 "objitem"
+3 54 "objtopic"
+3 52 "result"
+3 55 "do"
+3 56 "footnote"
+3 57 "atrfstart"
+3 58 "atrfend"
+3 59 "atnid"
+3 60 "atnauthor"
+3 61 "annotation"
+3 62 "atnref"
+3 63 "atntime"
+3 64 "atnicn"
+3 65 "field"
+3 66 "fldinst"
+3 67 "fldrslt"
+3 68 "datafield"
+3 69 "xe"
+3 70 "txe"
+3 71 "rxe"
+3 72 "tc"
+3 73 "NeXTGraphic"
+3 74 "NeXTHelpMarker"
+3 28 "NeXTHelpLink"
+3 75 "buptim"
+3 76 "creatim"
+3 77 "printim"
+3 78 "revtim"
+3 79 "dptxbxtext"
+3 80 "fontemb"
+3 81 "tcn"
+3 35 "shppict"
+3 41 "listtext"
+3 79 "private"
+3 82 "shpgrp"
+4 0 "fnil"
+4 1 "froman"
+4 2 "fswiss"
+4 3 "fmodern"
+4 4 "fscript"
+4 5 "fdecor"
+4 6 "ftech"
+4 7 "fbidi"
+23 0 "fcharset"
+23 1 "fprq"
+23 2 "cpg"
+23 3 "ftnil"
+23 4 "fttruetype"
+24 0 "fid"
+24 1 "frelative"
+24 2 "fosnum"
+25 0 "fvalidmac"
+25 1 "fvaliddos"
+25 2 "fvalidntfs"
+25 3 "fvalidhpfs"
+25 4 "fnetwork"
+5 0 "red"
+5 1 "green"
+5 2 "blue"
+2 2 "mac"
+2 0 "ansi"
+2 3 "pc"
+2 4 "pca"
+2 1 "ansicpg"
+10 0 "trowd"
+10 1 "trgaph"
+10 2 "cellx"
+10 3 "clmgf"
+10 4 "clmrg"
+10 5 "trql"
+10 6 "trqr"
+10 7 "trqc"
+10 8 "trleft"
+10 9 "trrh"
+10 10 "trhdr"
+10 11 "trkeep"
+10 12 "rtlrow"
+10 13 "ltrrow"
+10 14 "trbrdrt"
+10 15 "trbrdrl"
+10 16 "trbrdrb"
+10 17 "trbrdrr"
+10 18 "trbrdrh"
+10 19 "trbrdrv"
+10 20 "clbrdrb"
+10 21 "clbrdrt"
+10 22 "clbrdrl"
+10 23 "clbrdrr"
+10 42 "clvertalt"
+10 43 "clvertalc"
+10 44 "clvertalb"
+10 45 "cltxlrtb"
+10 46 "cltxlbrl"
+10 24 "clshdng"
+10 25 "clbghoriz"
+10 26 "clbgvert"
+10 27 "clbgfdiag"
+10 28 "clbgbdiag"
+10 29 "clbgcross"
+10 30 "clbgdcross"
+10 31 "clbgdkhoriz"
+10 31 "clbgdkhor"
+10 32 "clbgdkvert"
+10 33 "clbgdkfdiag"
+10 34 "clbgdkbdiag"
+10 35 "clbgdkcross"
+10 36 "clbgdkdcross"
+10 37 "clcfpat"
+10 38 "clcbpat"
+16 0 "flddirty"
+16 1 "fldedit"
+16 2 "fldlock"
+16 3 "fldpriv"
+16 4 "fldalt"
+18 0 "absw"
+18 1 "absh"
+18 2 "phmrg"
+18 3 "phpg"
+18 4 "phcol"
+18 5 "posx"
+18 6 "posnegx"
+18 7 "posxc"
+18 8 "posxi"
+18 9 "posxo"
+18 10 "posxr"
+18 11 "posxl"
+18 12 "pvmrg"
+18 13 "pvpg"
+18 14 "pvpara"
+18 15 "posy"
+18 16 "posnegy"
+18 17 "posyil"
+18 18 "posyt"
+18 19 "posyc"
+18 20 "posyb"
+18 21 "nowrap"
+18 22 "dxfrtext"
+18 23 "dfrmtxtx"
+18 24 "dfrmtxty"
+18 25 "dyfrtext"
+18 26 "dropcapli"
+18 27 "dropcapt"
+19 0 "objemb"
+19 1 "objlink"
+19 2 "objautlink"
+19 3 "objsub"
+19 4 "objpub"
+19 5 "objicemb"
+19 6 "linkself"
+19 7 "objupdate"
+19 8 "objlock"
+19 9 "objh"
+19 10 "objw"
+19 11 "objsetsize"
+19 12 "objalign"
+19 13 "objtransy"
+19 14 "objcropt"
+19 15 "objcropb"
+19 16 "objcropl"
+19 17 "objcropr"
+19 18 "objscalex"
+19 19 "objscaley"
+19 20 "rsltrtf"
+19 21 "rsltpict"
+19 22 "rsltbmp"
+19 23 "rslttxt"
+19 24 "rsltmerge"
+19 25 "bkmkpub"
+19 26 "pubauto"
+22 0 "ab"
+22 1 "acaps"
+22 2 "acf"
+22 3 "adn"
+22 4 "aexpnd"
+22 5 "af"
+22 6 "afs"
+22 7 "ai"
+22 8 "alang"
+22 9 "aoutl"
+22 10 "ascaps"
+22 11 "ashad"
+22 12 "astrike"
+22 13 "aul"
+22 14 "auld"
+22 15 "auldb"
+22 16 "aulnone"
+22 17 "aulw"
+22 18 "aup"
+20 0 "ftnalt"
+21 0 "alt"
+21 1 "shift"
+21 2 "ctrl"
+21 3 "fn"
+14 0 "bkmkcolf"
+14 1 "bkmkcoll"
+27 0 "xef"
+27 1 "bxe"
+27 2 "ixe"
+17 0 "tcf"
+17 1 "tcl"
+26 0 "dolock"
+26 1 "dobxpage"
+26 2 "dobxcolumn"
+26 3 "dobxmargin"
+26 4 "dobypage"
+26 6 "dobymargin"
+26 7 "dodhgt"
+26 8 "dpgroup"
+26 9 "dpcount"
+26 10 "dpendgroup"
+26 11 "dparc"
+26 12 "dpcallout"
+26 13 "dpellipse"
+26 14 "dpline"
+26 15 "dppolygon"
+26 16 "dppolyline"
+26 17 "dprect"
+26 18 "dptxbx"
+26 19 "dpx"
+26 20 "dpxsize"
+26 21 "dpy"
+26 22 "dpysize"
+26 23 "dpcoa"
+26 24 "dpcoaccent"
+26 25 "dpcobestfit"
+26 26 "dpcoborder"
+26 27 "dpcodabs"
+26 28 "dpcodbottom"
+26 29 "dpcodcenter"
+26 30 "dpcodtop"
+26 31 "dpcolength"
+26 32 "dpcominusx"
+26 33 "dpcominusy"
+26 34 "dpcooffset"
+26 35 "dpcosmarta"
+26 36 "dpcotdouble"
+26 37 "dpcotright"
+26 38 "dpcotsingle"
+26 39 "dpcottriple"
+26 40 "dptxbxmar"
+26 42 "dproundr"
+26 43 "dpptx"
+26 44 "dppty"
+26 45 "dppolycount"
+26 46 "dparcflipx"
+26 47 "dparcflipy"
+26 48 "dplinecob"
+26 49 "dplinecog"
+26 50 "dplinecor"
+26 51 "dplinepal"
+26 52 "dplinedado"
+26 53 "dplinedadodo"
+26 54 "dplinedash"
+26 55 "dplinedot"
+26 56 "dplinegray"
+26 57 "dplinehollow"
+26 58 "dplinesolid"
+26 59 "dplinew"
+26 60 "dpaendhol"
+26 61 "dpaendl"
+26 62 "dpaendsol"
+26 63 "dpaendw"
+26 64 "dpastarthol"
+26 65 "dpastartl"
+26 66 "dpastartsol"
+26 67 "dpastartw"
+26 68 "dpfillbgcb"
+26 69 "dpfillbgcg"
+26 70 "dpfillbgcr"
+26 71 "dpfillbgpal"
+26 72 "dpfillbggray"
+26 73 "dpfillfgcb"
+26 74 "dpfillfgcg"
+26 75 "dpfillfgcr"
+26 76 "dpfillfgpal"
+26 77 "dpfillfggray"
+26 78 "dpfillpat"
+26 79 "dpshadow"
+26 80 "dpshadx"
+26 81 "dpshady"
+26 82 "dobypara"
+0 -1 "rtf"
+1 -1 "deff"
Index: /gsdl/stable/etc/packages/wv/wvHtml.xml
===================================================================
--- /gsdl/stable/etc/packages/wv/wvHtml.xml	(revision 20131)
+++ /gsdl/stable/etc/packages/wv/wvHtml.xml	(revision 20131)
@@ -0,0 +1,376 @@
+<main>
+<charentity>
+<begin>HTML</begin>
+</charentity>
+
+<document>
+<begin>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/REC-html40/loose.dtd&quot;&gt;
+&lt;html&gt; 
+&lt;head&gt; 
+&lt;META HTTP-EQUIV=&quot;Content-Type&quot; CONTENT=&quot;text/html; charset=<charset/>&quot;&gt;
+&lt;META NAME=&quot;GENERATOR&quot; CONTENT=&quot;wvWare/<version/>&quot;&gt;
+&lt;title&gt; 
+<title/>
+&lt;/title&gt; 
+&lt;/head&gt; 
+&lt;body bgcolor=&quot;#FFFFFF&quot; text=&quot;#000000&quot; link=&quot;#0000ee&quot; vlink=&quot;#551a8b&quot;&gt;
+</begin>
+<end>
+&lt;/body&gt;
+&lt;/html&gt;
+</end>
+</document>
+
+<section>
+<begin>
+&lt;!--Section Begins--&gt;&lt;br&gt;
+</begin>
+<end>
+&lt;!--Section Ends--&gt;
+</end>
+</section>
+
+<justification>
+<left>left</left>
+<right>right</right>
+<center>center</center>
+<block>left</block>
+<asian>&lt;!--Could Someone who sees this tag tell me what was is this type of justification, asian languages only i thing--&gt;</asian>
+</justification>
+
+<numbering>
+<Arabic>type=&quot;1&quot;</Arabic>
+<UpperRoman>type=&quot;I&quot;</UpperRoman>
+<LowerRoman>type=&quot;i&quot;</LowerRoman>
+<UpperCaseN>type=&quot;A&quot;</UpperCaseN>
+<LowerCaseN>type=&quot;a&quot;</LowerCaseN>
+</numbering>
+
+<border>
+<noned>none</noned>
+<singled>solid</singled>
+<thickd>solid</thickd>
+<doubled>double</doubled>
+<number4d>double</number4d>
+<hairlined>solid</hairlined>
+<dotd>dotted</dotd>
+<dashlargegapd>dashed</dashlargegapd>
+<dotdashd>dotted</dotdashd>
+<dotdotdashd>dotted</dotdotdashd>
+<tripled>double</tripled>
+<thin-thicksmallgapd>dashed</thin-thicksmallgapd>
+<thick-thinsmallgapd>dashed</thick-thinsmallgapd>
+<thin-thick-thinsmallgapd>dashed</thin-thick-thinsmallgapd>
+<thin-thickmediumgapd>dashed</thin-thickmediumgapd>
+<thick-thinmediumgapd>dashed</thick-thinmediumgapd>
+<thin-thick-thinmediumgapd>dashed</thin-thick-thinmediumgapd>
+<thin-thicklargegapd>dashed</thin-thicklargegapd>
+<thick-thinlargegapd>dashed</thick-thinlargegapd>
+<thin-thick-thinlargegapd>dashed</thin-thick-thinlargegapd>
+<waved>solid</waved>
+<doublewaved>double</doublewaved>
+<dashsmallgapd>sashed</dashsmallgapd>
+<dashdotstrokedd>dashed</dashdotstrokedd>
+<emboss3Dd>ridge</emboss3Dd>
+<engrave3Dd>groove</engrave3Dd>
+<defaultd>ridge</defaultd>
+</border>
+
+<!-- <begin>&lt;ol <nfc/> start=&quot;<start/>&quot;&gt; -->
+<olist>
+<begin>&lt;ol <nfc/>&gt;
+</begin>
+<end>&lt;/ol&gt;</end>
+</olist>
+
+<ulist>
+<begin>&lt;ul&gt;
+</begin>
+<end>&lt;/ul&gt;</end>
+</ulist>
+
+<!-- <begin>&lt;li&gt;</begin> -->
+<entry>
+<begin>&lt;li value=&quot;<start/>&quot;&gt;</begin>
+<end>&lt;/li&gt;</end>
+</entry>
+
+
+<!-- 
+this tableoverride option can be used to turn off handling of
+these tags in tables, which I find is necessary for at least netscape
+-->
+<tableoverrides>
+<ParaBefore>0</ParaBefore>
+<ParaRight>0</ParaRight>
+<ParaAfter>0</ParaAfter>
+<ParaLeft>0</ParaLeft>
+<ParaLeft1>0</ParaLeft1>
+<VertMergedCells>0</VertMergedCells>
+</tableoverrides>
+
+<table>
+<begin>&lt;table width=&quot;<tablerelwidth/>%&quot; border=&quot;1&quot; cols=&quot;<no_cols/>&quot; rows=&quot;<no_rows/>&quot;&gt;</begin>
+<end>&lt;/table&gt;</end>
+</table>
+
+<row>
+<begin>&lt;tr&gt;</begin>
+<end>&lt;/tr&gt;</end>
+</row>
+
+<cell>
+<begin>&lt;td bgcolor=&quot;<cellbgcolor/>&quot; width=&quot;<cellrelwidth/>%&quot; rowspan=&quot;<rowspan/>&quot; colspan=&quot;<colspan/>&quot;&gt;</begin>
+<end>&lt;/td&gt;</end>
+</cell>
+
+<paragraph>
+<begin>
+<table.end/>
+<table.begin/>
+<row.begin/><cell.begin/><olist.end/><olist.begin/><ulist.end/><ulist.begin/><entry.begin/><text.begin/>
+</begin>
+<end>
+<text.end/><entry.end/><olist.end/><ulist.end/><cell.end/><row.end/>
+</end>
+</paragraph>
+
+<!-- these are all the character properties that can show up in word -->
+<bold><begin>&lt;b&gt;</begin><end>&lt;/b&gt;</end></bold>
+<italic><begin>&lt;i&gt;</begin><end>&lt;/i&gt;</end></italic>
+
+<!--
+text that has been deleted and will be displayed with strikethrough when
+revision marked text is to be displayed
+
+use either this line...
+--> 
+<RMarkDel><begin>&lt;s&gt;</begin><end>&lt;/s&gt;&lt;a href=&quot;#author<ibstRMarkDel/>&quot;&gt;[Author ID<ibstRMarkDel/>: at <dttmRMarkDel/> ]&lt;/a&gt;</end></RMarkDel>
+
+<!--
+or uncomment below to make deleted text dissappear (well, become commented out)
+-->
+<!--
+<RMarkDel><begin>&lt;!-&#45;</begin><end>-&#45;&gt;</end></RMarkDel>
+-->
+
+<!-- Overwriting char props. like CaPs->CAPS SmallCaps->smallcaps -->
+<outline><begin></begin><end></end></outline>
+<smallcaps><begin>&lt;span style=&quot;text-transform:lowercase&quot;&gt;</begin><end>&lt;/span&gt;</end></smallcaps>
+<caps><begin>&lt;span style=&quot;text-transform:uppercase&quot;&gt;</begin><end>&lt;/span&gt;</end></caps>
+<vanish><begin></begin><end></end></vanish>
+
+<!--If you uncomment this then the annotation text links will become commented out by html tags-->
+<!--
+<vanish><begin>&lt;!-&#45;</begin><end>-&#45;&gt;</end></vanish>
+-->
+
+<!--
+text that has been newly typed since the last time revision marks have been accepted
+and will be displayed with underline when revision marked text is to be displayed
+
+use either this line...
+-->
+<RMark><begin>&lt;u&gt;</begin><end>&lt;/u&gt;&lt;a href=&quot;#author<ibstRMark/>&quot;&gt;[Author ID<ibstRMark/>: at <dttmRMark/>]&lt;/a&gt;</end></RMark>
+
+<!--
+or uncomment below to make the underline dissappear
+-->
+<!--
+<RMark><begin></begin><end></end></RMark>
+-->
+
+
+<strike><begin>&lt;s&gt;</begin><end>&lt;/s&gt;</end></strike>
+<shadow><begin></begin><end></end></shadow>
+<lowercase><begin></begin><end></end></lowercase>
+<emboss><begin></begin><end></end></emboss>
+<imprint><begin></begin><end></end></imprint>
+<!--double strike-->
+<dstrike><begin>&lt;s&gt;</begin><end>&lt;/s&gt;</end></dstrike>
+
+<!--
+ftc's
+&
+hps
+
+keep them for font face and do that later.
+-->
+
+<super><begin>&lt;sup&gt;</begin><end>&lt;/sup&gt;</end></super>
+<sub><begin>&lt;sub&gt;</begin><end>&lt;/sub&gt;</end></sub>
+
+<singleu><begin>&lt;u&gt;</begin><end>&lt;/u&gt;</end></singleu>
+<wordu><begin>&lt;u&gt;</begin><end>&lt;/u&gt;</end></wordu>
+<doubleu><begin>&lt;u&gt;</begin><end>&lt;/u&gt;</end></doubleu>
+<dottedu><begin>&lt;u&gt;</begin><end>&lt;/u&gt;</end></dottedu>
+<hiddenu><begin>&lt;u&gt;</begin><end>&lt;/u&gt;</end></hiddenu>
+<thicku><begin>&lt;u&gt;</begin><end>&lt;/u&gt;</end></thicku>
+<dashu><begin>&lt;u&gt;</begin><end>&lt;/u&gt;</end></dashu>
+<dotu><begin>&lt;u&gt;</begin><end>&lt;/u&gt;</end></dotu>
+<dotdashu><begin>&lt;u&gt;</begin><end>&lt;/u&gt;</end></dotdashu>
+<dotdotdashu><begin>&lt;u&gt;</begin><end>&lt;/u&gt;</end></dotdotdashu>
+<waveu><begin>&lt;u&gt;</begin><end>&lt;/u&gt;</end></waveu>
+
+<!--
+text whose properties have been changed since the last time revision marks have been accepted
+and will be displayed with a note showing the change points.
+
+use either this line (which admit it a bit scary looking, but harmless)...
+--> 
+<PropRMark><begin>&lt;a href=&quot;#author<ibstPropRMark/>&quot;&gt;-&#45;&amp;gt;&lt;/a&gt;</begin><end>&lt;a href=&quot;#author<ibstPropRMark/>&quot;&gt;[Author ID<ibstPropRMark/>: at <dttmPropRMark/>]&lt;/a&gt;</end></PropRMark>
+
+<!--
+or uncomment below to make the notes dissappear
+-->
+<!--
+<PropRMark><begin></begin><end></end></PropRMark>
+-->
+
+<!--
+<color>
+-->
+<Black><begin>Black</begin><end></end></Black>
+<Blue><begin>Blue</begin><end></end></Blue>
+<Cyan><begin>Cyan</begin><end></end></Cyan>
+<Green><begin>Green</begin><end></end></Green>
+<Magenta><begin>Magenta</begin><end></end></Magenta>
+<Red><begin>Red</begin><end></end></Red>
+<Yellow><begin>Yellow</begin><end></end></Yellow>
+<White><begin>White</begin><end></end></White>
+<DkBlue><begin>DarkBlue</begin><end></end></DkBlue>
+<DkCyan><begin>DarkCyan</begin><end></end></DkCyan>
+<DkGreen><begin>DarkGreen</begin><end></end></DkGreen>
+<DkMagenta><begin>DarkMagenta</begin><end></end></DkMagenta>
+<DkRed><begin>DarkRed</begin><end></end></DkRed>
+<DkYellow><begin>#8b8b00</begin><end></end></DkYellow>
+<DkGray><begin>DarkGray</begin><end></end></DkGray>
+<LtGray><begin>LightGrey</begin><end></end></LtGray>
+<!--
+</color>
+-->
+
+<!--
+<animation>
+-->
+<LasVegas><begin>&lt;blink&gt;</begin><end>&lt;/blink&gt;</end></LasVegas>
+<BackgroundBlink><begin>&lt;blink&gt;</begin><end>&lt;/blink&gt;</end></BackgroundBlink>
+<SparkleText><begin>&lt;blink&gt;</begin><end>&lt;/blink&gt;</end></SparkleText>
+<MarchingAnts><begin>&lt;blink&gt;</begin><end>&lt;/blink&gt;</end></MarchingAnts>
+<MarchingRedAnts><begin>&lt;blink&gt;</begin><end>&lt;/blink&gt;</end></MarchingRedAnts>
+<Shimmer><begin>&lt;blink&gt;</begin><end>&lt;/blink&gt;</end></Shimmer>
+<!--
+</animation>
+-->
+
+<!--
+I dont understand what this one is, and ive never come across it
+
+use this sample line (which admit it a bit scary looking, but harmless)...
+-->
+<DispFldRMark><begin>&lt;a href=&quot;#author<ibstDispFldRMark/>&quot;&gt;--&amp;gt;&lt;/a&gt;</begin><end>&lt;a href=&quot;#author<ibstDispFldRMark/>&quot;&gt;[Author ID<ibstDispFldRMark/>: at <dttmDispFldRMark/> (<xstDispFldRMark/>)]&lt;/a&gt;</end></DispFldRMark>
+
+<!--
+or uncomment below to ignore it, the previous might even crash wv ?
+-->
+<!--
+<DispFldRMark><begin></begin><end></end></DispFldRMark>
+-->
+
+<animation>
+<begin><LasVegas.begin/><BackgroundBlink.begin/><SparkleText.begin/><MarchingAnts.begin/><MarchingRedAnts.begin/><Shimmer.begin/></begin>
+<end><Shimmer.end/><MarchingRedAnts.end/><MarchingAnts.end/><SparkleText.end/><BackgroundBlink.end/><LasVegas.end/></end>
+</animation>
+
+<fontstr>
+<begin>&lt;font color=&quot;<black.begin/><blue.begin/><cyan.begin/><green.begin/><magenta.begin/><red.begin/><yellow.begin/><white.begin/><dkblue.begin/><dkcyan.begin/><dkgreen.begin/><dkmagenta.begin/><dkred.begin/><dkyellow.begin/><dkgray.begin/><ltgray.begin/>&quot;&gt;</begin>
+<end><ltgray.end/><dkgray.end/><dkyellow.end/><dkred.end/><dkmagenta.end/><dkgreen.end/><dkcyan.end/><dkblue.end/><white.end/><yellow.end/><red.end/><magenta.end/><green.end/><cyan.end/><blue.end/><black.end/>&lt;/font&gt;</end>
+</fontstr>
+
+<comment>
+<begin>
+&lt;a href=&quot;#comment<ibstAnno/> &quot;&gt;-&#45;&amp;gt;&lt;/a&gt;
+</begin>
+<end>&lt;a href=&quot;#comment<ibstAnno/> &quot;&gt;[Author:<xstUsrInitl/>]&lt;/a&gt;
+</end>
+</comment>
+
+<style name="Normal">
+<character>
+<begin><PropRMark.begin/><DispFldRMark.begin/><animation.begin/><fontstr.begin/><bold.begin/><italic.begin/><strike.begin/><RMarkDel.begin/><outline.begin/><smallcaps.begin/><caps.begin/><vanish.begin/><RMark.begin/><shadow.begin/><lowercase.begin/><emboss.begin/><imprint.begin/><dstrike.begin/><super.begin/><sub.begin/><singleu.begin/><wordu.begin/><doubleu.begin/><dottedu.begin/><hiddenu.begin/><thicku.begin/><dashu.begin/><dotu.begin/><dotdashu.begin/><dotdotdashu.begin/><waveu.begin/></begin>
+<end><waveu.end/><dotdotdashu.end/><dotdashu.end/><dotu.end/><dashu.end/><thicku.end/><hiddenu.end/><dottedu.end/><doubleu.end/><wordu.end/><singleu.end/><sub.end/><super.end/><dstrike.end/><imprint.end/><emboss.end/><lowercase.end/><shadow.end/><RMark.end/><vanish.end/><caps.end/><smallcaps.end/><outline.end/><RMarkDel.end/><strike.end/><italic.end/><bold.end/><fontstr.end/><animation.end/><DispFldRMark.end/><PropRMark.end/></end>
+</character>
+
+<!-- Netscape does handle this correctly yet, here is how each different side of the border should work.
+border-top: thin <bordertopstyle/> <bordertopcolor/>;
+border-left: thin <borderleftstyle/> <borderleftcolor/>;
+border-right: thin <borderrightstyle/> <borderrightcolor/>;
+border-bottom: thin <borderbottomstyle/> <borderbottomcolor/>
+-->
+
+
+<pmargin>
+<begin>margin: <mmParaBefore/> <mmParaRight/> <mmParaAfter/> <mmParaLeft/>;</begin>
+</pmargin>
+
+<pborder>
+<begin>
+border: thin <borderleftstyle/> <borderleftcolor/>;
+<!--
+border-top: thin <bordertopstyle/> <bordertopcolor/>;
+border-left: thin <borderleftstyle/> <borderleftcolor/>;
+border-right: thin <borderrightstyle/> <borderrightcolor/>;
+border-bottom: thin <borderbottomstyle/> <borderbottomcolor/>
+-->
+</begin>
+</pborder>
+
+<text>	
+<begin>&lt;p&gt;&lt;div name=&quot;<stylename/>&quot; align=&quot;<just/>&quot; style=&quot;<paramargin/> <paraborder/> padding: <mmPadTop/> <mmPadRight/> <mmPadBottom/> <mmPadLeft/>; &quot;&gt; 
+
+&lt;p style=&quot;text-indent: <mmParaLeft1/>; text-align: <just/>; line-height: <mmLineHeight/>; color: <parafgcolor/>; background-color: <parabgcolor/>; &quot;&gt;</begin>
+
+<end>&lt;/p&gt;&lt;/div&gt;</end>
+</text>
+
+<picture>
+<begin>
+&lt;img <htmlAlignGuess/> width=&quot;<pixPicWidth/>&quot; height=&quot;<pixPicHeight/>&quot; alt=&quot;0x01 graphic&quot; src=&quot;placeholder.png&quot;&gt;<htmlNextLineGuess/>
+</begin>
+</picture>
+
+</style>
+
+<!--we need to be override the character properties-->
+<!--
+<style name="Normal">
+<character>
+<begin><PropRMark.begin/><DispFldRMark.begin/><animation.begin/><fontstr.begin/><bold.begin/><italic.begin/><strike.begin/><RMarkDel.begin/><outline.begin/><smallcaps.begin/><caps.begin/><vanish.begin/><RMark.begin/><shadow.begin/><lowercase.begin/><emboss.begin/><imprint.begin/><dstrike.begin/><super.begin/><sub.begin/><singleu.begin/><wordu.begin/><doubleu.begin/><dottedu.begin/><hiddenu.begin/><thicku.begin/><dashu.begin/><dotu.begin/><dotdashu.begin/><dotdotdashu.begin/><waveu.begin/></begin>
+<end><waveu.end/><dotdotdashu.end/><dotdashu.end/><dotu.end/><dashu.end/><thicku.end/><hiddenu.end/><dottedu.end/><doubleu.end/><wordu.end/><singleu.end/><sub.end/><super.end/><dstrike.end/><imprint.end/><emboss.end/><lowercase.end/><shadow.end/><RMark.end/><vanish.end/><caps.end/><smallcaps.end/><outline.end/><RMarkDel.end/><strike.end/><italic.end/><bold.end/><fontstr.end/><animation.end/><DispFldRMark.end/><PropRMark.end/></end>
+</character>
+
+<text>	
+<begin>&lt;div name=&quot;<stylename/>&quot;  align=&quot;<just/>&quot;&gt;&lt;p&gt;</begin>
+<end>&lt;/p&gt;&lt;/div&gt;</end>
+</text>
+
+</style>
+
+<style name="Heading 1">
+
+<character>
+<begin></begin>
+<end></end>
+</character>
+
+<text>	
+<begin>&lt;div name=&quot;<stylename/>&quot;  align=&quot;<just/>&quot;&gt;&lt;H1&gt;</begin>
+<end>&lt;/H1&gt;&lt;/div&gt;</end>
+</text>
+
+
+
+</style>
+-->
+
+</main>
Index: /gsdl/stable/etc/packages/z3950/bib1-mapping.txt
===================================================================
--- /gsdl/stable/etc/packages/z3950/bib1-mapping.txt	(revision 20131)
+++ /gsdl/stable/etc/packages/z3950/bib1-mapping.txt	(revision 20131)
@@ -0,0 +1,32 @@
+# Mapping between Bib1 Attributes and Dublin Core
+
+# These are the Dublin Core Use Attributes
+1097 dc.Title
+1098 dc.Creator
+1099 dc.Subject
+1100 dc.Description
+1101 dc.Publisher
+1102 dc.Date
+1103 dc.Type
+1104 dc.Identifier
+1105 dc.Language
+1106 dc.Contributor
+1107 dc.Format
+1108 dc.Source
+1109 dc.Relation
+1110 dc.Coverage
+1111 dc.Rights
+
+# These are general Bib1 Use attributes
+# The Greenstone z3950 client uses 1016 (=Any), 1, 4 for querying
+1       Creator
+4	Title
+9	Subject
+13	Subject
+21	Subject
+31	Date
+54	Language
+1003	Creator
+1020	Contributor
+
+
Index: /gsdl/stable/etc/packages/z3950/z3950.cfg
===================================================================
--- /gsdl/stable/etc/packages/z3950/z3950.cfg	(revision 20131)
+++ /gsdl/stable/etc/packages/z3950/z3950.cfg	(revision 20131)
@@ -0,0 +1,37 @@
+[GSDL2.1] # config file version
+#
+# This file specifies a list of z39.50 servers to use.
+# Each field is separated by white-space.
+# If you want a " character inside a string, escape it - ie \" or ""
+
+#
+# Each server configuration consists of a stanza. The items are described here:
+#	Item				Description
+#	###############			########################
+#	collectname			<GSDL internal name (alphanumeric) >
+#	servername:port			<Internet address (def. port is 210) >
+#	dbname				<z39.50 server database name>
+#	"humanname"			<Brief description>
+#	icon "url to icon"		<optional GSDL icon (eg collection) >
+#	smallicon "url to small icon"	<optional GSDL icon (eg homepage) >
+#	About "about text"		<optional>
+
+
+# For a list of servers to test against, see
+# http://www.loc.gov/z3950/agency/resources/testport.html
+
+# For an exhaustive list of servers to try, have a look at
+#  http://www.indexdata.dk/targettest/
+
+
+# To connect to the Library of Congress z3950 server, uncomment the following:
+
+#LOC
+#  z3950.loc.gov:7090
+#  Voyager
+#  "Library of Congress z39.50 server"
+#  About "This is the z39.50 interface to the US LoC catalogue
+#         system. It contains approximately 12 million bibliographic records.
+#         For server capabilities, look at
+#         <a href=\"http://lcweb.loc.gov/z3950/lcserver.html\">their web 
+#         pages</a>."
Index: /gsdl/stable/etc/qdc2marc-mapping.xml
===================================================================
--- /gsdl/stable/etc/qdc2marc-mapping.xml	(revision 20131)
+++ /gsdl/stable/etc/qdc2marc-mapping.xml	(revision 20131)
@@ -0,0 +1,354 @@
+<Mapping>
+    <!-- English-->
+    <stopwords lang="en" >
+      <item  name="a " length="2"/>
+      <item  name="an " length="3"/>
+      <item  name="the " length="4"/>   
+    </stopwords>
+
+    <!--Spain-->
+    <stopwords lang="es">
+      <item  name="uno " length="4"/>
+      <item  name="una " length="4"/>
+      <item  name="el " length="3"/>
+      <item  name="la " length="3"/>
+      <item  name="las " length="4"/>
+      <item  name="los " length="4"/>
+      <item  name="un " length="3"/>
+      <item  name="unos " length="5"/>
+      <item  name="unas " length="5"/>
+    </stopwords>
+
+  <!--Catalan-->
+  <stopwords lang="ca">
+     <item  name="el " length="3"/>
+     <item  name="la " length="3"/>
+     <item  name="les " length="4"/>
+     <item  name="l'" length="2"/>
+     <item  name="un " length="3"/>
+     <item  name="una " length="4"/>
+     <item  name="uns " length="4"/>
+     <item  name="unes " length="5"/>
+     <item  name="es " length="3"/>
+     <item  name="sa " length="3"/>
+     <item  name="ses " length="4"/>
+     <item  name="sos " length="4"/>
+     <item  name="so " length="3"/>
+     <item  name="s'" length="2"/>
+   </stopwords>
+ 
+  <!--German-->  
+  <stopwords lang="de">
+     <item  name="der " length="4"/>
+     <item  name="ein " length="4"/>
+     <item  name="die " length="4"/>
+     <item  name="eine " length="5"/>
+     <item  name="das " length="4"/>
+   </stopwords>
+
+  <!--French-->
+  <stopwords lang="fr">
+     <item  name="le " length="3"/>
+     <item  name="la " length="3"/>
+     <item  name="les " length="4"/>
+     <item  name="un " length="3"/>
+     <item  name="une " length="4"/>
+     <item  name="l'" length="2"/>    
+  </stopwords>
+
+  <!--Italian-->  
+  <stopwords lang="it">
+     <item  name="il " length="3"/>
+     <item  name="lo " length="3"/>
+     <item  name="la " length="3"/>
+     <item  name="gli " length="4"/>
+     <item  name="le " length="3"/>
+     <item  name="un " length="3"/>
+     <item  name="uno " length="4"/>
+     <item  name="una " length="4"/>
+     <item  name="l'" length="2"/>
+     <item  name="un'" length="3"/>
+  </stopwords>
+
+   <!--Galician-->  
+  <stopwords lang="gl">
+     <item  name="o " length="2"/>
+     <item  name="os " length="3"/>
+     <item  name="a " length="2"/>
+     <item  name="as " length="3"/>
+     <item  name="un " length="3"/>
+     <item  name="uns " length="4"/>
+     <item  name="unha " length="5"/>
+     <item  name="unhas " length="6"/>
+   </stopwords> 
+    
+   <recordTypeMapping>
+       <type name="collection" mapping="p"/>
+       <type name="dataset" mapping="m"/>
+       <type name="event" mapping="r"/>
+       <type name="image" mapping="k"/>
+       <type name="interactive resource" mapping="m"/> 
+       <type name="service" mapping="m"/>
+       <type name="software" mapping="m"/>
+       <type name="sound" mapping="i"/>
+       <type name="text" mapping="a"/>      
+    </recordTypeMapping>
+
+    <leader> 
+        <recordLength pos="1" value="00000" />
+       <recordStatus pos="5" value="n" />
+       <recordType pos="6" value="a" />
+       <bibliographiclevel pos="7" value="m" />
+       <controlType pos="8" value=" " />
+       <codingScheme pos="9" value=" " />
+       <indicatorCount pos="10" value="2" />
+       <subfieldCodeCount pos="11" value="2" />
+       <dataBaseAddress pos="12" value="     " />
+       <encodingLevel pos="17" value="3" />
+       <descriptiveCatalogForm pos="18" value="u" />
+       <linkedRecordRequirement pos="19" value=" " />
+       <lpLength pos="20" value="4" />
+       <scpLength pos="21" value="5" />
+       <idLength pos="22" value="0" />
+       <emcpLength pos="23" value="0" />
+    </leader>
+        
+    <controlfield tag="001" value="the value of code 001" required="true" />
+    <controlfield tag="002" value="the value of code 002" required="false"/>
+    <controlfield tag="003" value="the value of code 003" required="true"/>
+    <controlfield tag="004" value="the value of code 004" required="false"/>
+    <controlfield tag="005" value="the value of code 005" required="false"/>
+    <controlfield tag="006" value="the value of code 006" required="false"/>
+    <controlfield tag="008" value="the value of code 008" required="true"/>    
+
+<!--this mapping provides qualified duclin core to the following Marc fields mapping:   
+    024 |a[dc.Identifier]
+    041 |a[dc.Language]   
+ 
+    245 |a[dc.Title]
+    246 |a[dc.Title^alternative]    
+    260 |b[dc.Publisher] |c[dc.Date^issued] |g[dc.Date^created]
+    
+    300 |a[dc.Format^extent] 
+    307 |a[dc.Date^available]     
+    340 |a[dc.Format^medium]
+
+    500 |a[dc.Coverage] 
+    505 |a[dc.Description^tableOfContents]
+    510 |a[dc.Relation^isReferencedBy]
+    513 |b[dc.Coverage^spatial]           
+    518 |a[dc.Date^valid]
+    520 |a[dc.Description]
+    520 |a[dc.Description^abstract]
+    522 |a[dc.Coverage^temporal]
+    538 |a[dc.Relation^requires]
+    540 |a[dc.Rights^accessRights] |b[dc.RightsHolder]
+    540 |a[dc.Rights^license] |b[dc.RightsHolder]
+    540 |a[dc.Rights] |b[dc.RightsHolder]
+    546 |a[dc.Language]
+    583 |d[dc.Date^modified] 
+
+
+    650 |a[dc.Subject]
+    655 |a[dc.Type]
+    
+    720 |a[dc.Contributor] |a[dc.Creator]
+    774 |n[dc.Relation^hasPart]
+    774 |n[dc.Relation^^isPartOf]
+    775 |n[dc.Relation^hasVersion]
+    775 |n[dc.Relation^isVersionOf]
+    776 |n[dc.Relation^hasFormat]
+    776 |n[dc.Relation^isFormatOf]
+    780 |t[dc.Relation^replaces]
+    785 |t[dc.Relation^isReplacedBy]
+    786 |o[dc.Source]
+    787 |o[dc.Relation]    
+
+    856 |q[dc.Format]
+
+ 
+-->
+
+<!-- Contributor -->
+ <MarcField multiple="true" tag="720" ind1=" " ind2=" ">
+   <subfield code="a" meta="dc.Contributor" punc=","/>
+ </MarcField>
+
+<!--Coverage -->
+  <MarcField multiple="true" tag="500" ind1=" " ind2=" ">
+     <subfield code="a" meta="dc.Coverage" punc=""/>
+  </MarcField>
+  <MarcField multiple="true" tag="522" ind1=" " ind2=" ">
+     <subfield code="a" meta="dc.Coverage^temporal" punc=""/>
+  </MarcField>
+  <MarcField multiple="true" tag="513" ind1=" " ind2=" ">
+     <subfield code="b" meta="dc.Coverage^spatial" punc=""/>
+  </MarcField>
+
+ <!--Creator-->
+ <MarcField  multiple="true"  tag="720" ind1=" " ind2=" ">
+     <subfield code="a" meta="dc.Creator" punc=","/>
+ </MarcField>   
+
+  <!--Publisher and  Date-->
+   <MarcField  multiple="false" tag="260" ind1=" " ind2=" ">
+     <subfield code="b" meta="dc.Publisher" punc=","/>
+     <subfield code="c" meta="dc.Date^issued" punc=""/> 
+     <subfield code="g" meta="dc.Date^created" punc=""/>
+   </MarcField>
+
+ <!--Date-->
+    <MarcField  multiple="true"   tag="307" ind1=" " ind2=" ">
+       <subfield code="a" meta="dc.Date^available" punc=""/> 
+   </MarcField>         
+     
+   <MarcField  multiple="true"   tag="583" ind1=" " ind2=" ">
+       <subfield code="d" meta="dc.Date^modified" punc=""/> 
+   </MarcField>
+  
+   <MarcField  multiple="true"   tag="518" ind1=" " ind2=" ">
+       <subfield code="a" meta="dc.Date^valid" punc=""/> 
+   </MarcField>
+
+<!-- Descrption -->
+    <MarcField  multiple="true" tag="520" ind1=" " ind2=" ">
+       <subfield code="a" meta="dc.Description" punc=""/> 
+    </MarcField>
+
+    <MarcField  multiple="true"  tag="520" ind1=" " ind2=" ">
+        <subfield code="a" meta="dc.Description^abstract" punc=""/> 
+    </MarcField>
+
+    <MarcField  multiple="true"  tag="505" ind1="0" ind2=" ">
+       <subfield code="a" meta="dc.Description^tableOfContents" punc=""/>
+    </MarcField>
+
+
+<!--Format -->
+     <MarcField  multiple="true"  tag="856" ind1=" " ind2=" ">
+       <subfield code="q" meta="dc.Format" punc=""/> 
+    </MarcField>
+    <MarcField  multiple="true"  tag="300" ind1=" " ind2=" ">
+        <subfield code="a" meta="dc.Format^extent" punc=""/> 
+    </MarcField>
+    <MarcField  multiple="true"  tag="340" ind1="0" ind2=" ">
+       <subfield code="a" meta="dc.Format^medium" punc=""/>
+    </MarcField>
+
+ <!--Identifier -->
+     <MarcField multiple="true" tag="024" ind1="8" ind2=" ">
+        <subfield code="b" meta="dc.Identifier" punc=""/>
+     </MarcField>
+
+
+ <!--Language-->
+ <MarcField  multiple="false" tag="041" ind1=" " ind2=" ">
+     <subfield code="a" meta="dc.Language" punc=""/>
+  </MarcField>
+
+<!-- relation -->
+  <MarcField multiple="true"  tag="787" ind1="0" ind2=" " >
+      <subfield code="o" meta="dc.Relation" punc=""/>
+  </MarcField>
+
+  <MarcField multiple="true"  tag="538" ind1=" " ind2=" ">
+        <subfield code="a" meta="dc.Relation^requires" punc=""/>
+  </MarcField>
+
+  <MarcField multiple="true" tag="510" ind1="0" ind2=" ">
+     <subfield code="a" meta="dc.Relation^isReferencedBy" punc=""/>
+  </MarcField>
+ 
+  <!--no entry in the crosstalk spec
+  <MarcField name="dc.Relation^conformsTo" />
+ -->
+  
+  <MarcField multiple="true" tag="776" ind1="0" ind2=" ">
+     <subfield code="n" meta="dc.Relation^hasFormat" punc=""/>
+  </MarcField>
+
+  <MarcField multiple="true" tag="774" ind1="0" ind2=" ">
+     <subfield code="n" meta="dc.Relation^hasPart" punc=""/>
+  </MarcField>
+
+  <MarcField multiple="true" tag="775" ind1="0" ind2=" ">
+      <subfield code="n" meta="dc.Relation^hasVersion" punc=""/>
+  </MarcField>
+
+ <MarcField multiple="true" tag="776" ind1="0" ind2=" ">
+     <subfield code="n" meta="dc.Relation^isFormatOf" punc=""/>
+  </MarcField>
+
+  <MarcField multiple="true" tag="774" ind1="0" ind2=" ">
+     <subfield code="n" meta="dc.Relation^isPartOf" punc=""/>
+  </MarcField>
+
+  <MarcField multiple="true"  tag="785" ind1="0" ind2="0">
+     <subfield code="t" meta="dc.Relation^isReplacedBy" punc=""/>
+  </MarcField>
+
+ <!--has no entry in crosstalk spec
+   <MarcField name="dc.Relation^isRequiredBy"/>
+ -->
+
+ <MarcField multiple="true" tag="775" ind1="0" ind2=" ">
+       <subfield code="n" meta="dc.Relation^isVersionOf" punc=""/>
+ </MarcField>
+
+<!--has no entry in crosstalk spec
+      <MarcField name="dc.Relation^references" >
+      </MarcField>
+-->
+
+ <MarcField multiple="true" tag="780" ind1="0" ind2="0">
+    <subfield code="t" meta="dc.Relation^replaces" punc=""/>
+ </MarcField>
+
+ <!--Rights: additional qualified entries ???-->
+  <MarcField multiple="false"  tag="540" ind1=" " ind2=" ">
+    <subfield code="a" meta="dc.Rights" punc=""/>
+    <subfield code="b" meta="dc.RightsHolder" punc=""/>
+  </MarcField>
+
+  <MarcField   multiple="false"  tag="540" ind1=" " ind2=" ">
+    <subfield code="a" meta="dc.Rights^accessRights" punc=""/>
+    <subfield code="b" meta="dc.RightsHolder" punc=""/>
+  </MarcField>
+
+  <MarcField multiple="false" tag="540" ind1=" " ind2=" ">
+     <subfield code="a" meta="dc.Rights^license" punc=""/>
+     <subfield code="b" meta="dc.RightsHolder" punc=""/>
+  </MarcField>
+
+   <!-- Source -->
+  <MarcField  multiple="true" tag="786" ind1="0" ind2=" ">
+     <subfield code="o" meta="dc.Source" punc=""/>
+  </MarcField>
+  
+
+ <!--subject-->
+  <MarcField  multiple="true"  tag="650" ind1=" " ind2="0">
+    <subfield code="a" meta="dc.Subject" punc=" :"/>
+  </MarcField>
+
+<!--Title-->
+  <MarcField  multiple="false" tag="245" ind1="1" ind2="nonfiling">
+     <subfield code="a" meta="dc.Title" punc=""/>
+  </MarcField>
+ 
+  <MarcField multiple="true" tag="246" ind1="3" ind2="3">
+    <subfield code="a" meta="dc.Title" punc=""/>
+  </MarcField>
+
+
+  <MarcField multiple="true" tag="246" ind1="3" ind2="3">
+    <subfield code="a" meta="dc.Title^alternative" punc=""/>
+  </MarcField>
+
+
+ <!-- type -->
+  <MarcField multiple="true" tag="655" ind1=" " ind2="7">
+     <subfield code="a" meta="dc.Type" punc=""/>
+  </MarcField>
+  
+</Mapping>
Index: /gsdl/stable/findjava.sh
===================================================================
--- /gsdl/stable/findjava.sh	(revision 20131)
+++ /gsdl/stable/findjava.sh	(revision 20131)
@@ -0,0 +1,159 @@
+# We will already be in the correct folder (GLI folder), which would
+# contain a compiled up search4j if this GLI is part of an installation.
+# If a search4j executable is not there, then it means this is an SVN checkout. 
+# In such a case, it's up to the user checking things out to ensure JAVA_HOME
+# is set and moreover points to the correct version of the Java.
+
+# Function to check if any JAVA_HOME is set and if so, try using that
+function try_java {
+    MIN_DISPLAY_VERSION=${1};
+
+    if [ "x$JAVA_HOME" = "x" -o ! -f "$JAVA_HOME/bin/java" ]; then
+	no_java "$MIN_DISPLAY_VERSION"
+	return $?
+    else
+	# There is a JAVA_HOME already set, we're going to try using that
+	javapath="$JAVA_HOME/bin/java"
+
+	# Print a warning that we're going to use whatever JAVA_HOME is set (fingers crossed)
+	echo
+	if [ "x$gslang" = "x" -o "$gslang" = "en" ]; then
+	    echo "***************************************************************************"
+	    echo "WARNING: "
+	    echo "Found a JAVA_HOME at $JAVA_HOME. Attempting to use this."
+	    echo "However, you need to have a Java $MIN_DISPLAY_VERSION or higher installed."
+	    echo "***************************************************************************"
+	fi
+	echo
+	echo "Java:"
+	echo $javapath
+	echo
+	return 0
+    fi
+}
+
+function no_java {
+    MIN_DISPLAY_VERSION=${1};
+
+    echo
+    if [ "$gslang" = "es" ]; then
+	echo "No se pudo localizar una versión apropiada de Java. Usted deberá "
+	echo "instalar un Ambiente de Ejecución Java (versión $MINIMUM_DISPLAY_VERSION o superior) "
+	echo "antes de correr la Interfaz de la $PROGNAME."
+    elif [ "$gslang" = "fr" ]; then
+	echo "Une version adéquate de Java n'a pas pu être localisée."
+	echo "Vous devez installer un Java Runtime Environment (version $MINIMUM_DISPLAY_VERSION ou"
+	echo "supérieur) avant de démarrer $PROGNAME."
+	echo "Si vous avez Java installé sur votre ordinateur veuillez vérifier la variable"
+	echo "d'environnement JAVA_HOME."
+    elif [ "$gslang" = "ru" ]; then
+	echo "îÅ ÕÄÁÌÏÓØ ÏÐÒÅÄÅÌÉÔØ ÍÅÓÔÏÎÁÈÏÖÄÅÎÉÅ ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÅÊ ×ÅÒÓÉÉ Java."
+	echo "÷Ù ÄÏÌÖÎÙ ÕÓÔÁÎÏ×ÉÔØ Java Runtime Environment (×ÅÒÓÉÀ $MINIMUM_DISPLAY_VERSION ÉÌÉ ×ÙÛÅ)"
+	echo "ÐÅÒÅÄ ××ÏÄÏÍ ÂÉÂÌÉÏÔÅÞÎÏÇÏ $PROGNAME."
+    else
+	echo "Failed to locate an appropriate version of Java. You must install a"
+	echo "Java Runtime Environment (version $MINIMUM_DISPLAY_VERSION or greater) before running the"
+	echo "$PROGNAME."
+	echo "If you have Java intalled on your machine please set the environment variable JAVA_HOME."
+    fi
+    return 1
+}
+
+function set_java_exec {	
+    SEARCH4J_EXECUTABLE=${1};
+    MINIMUM_JAVA_VERSION=${2};
+    MIN_DISPLAY_VERSION=${3};
+
+    # Give search4j a hint to find Java depending on the platform
+    if [ $GSDLOS = linux ]; then
+	HINT=`cd $GSDLHOME;pwd`/packages/jre
+    elif [ $GSDLOS = darwin ]; then
+	HINT=/System/Library/Frameworks/JavaVM.framework/Home
+    fi	
+    
+    javapath="`"$SEARCH4J_EXECUTABLE" -e -p "$HINT" -m $MINIMUM_JAVA_VERSION`"
+
+    if [ "$?" != "0" ]; then
+	
+        OLDVER="`"$SEARCH4J_EXECUTABLE" -v -p "$HINT"`"
+	
+        if [ "$?" = "0" ]; then
+	    
+            if [ "$gslang" = "es" ]; then
+                echo "La versión del Ambiente de Ejecución Java (JRE por sus siglas en "
+                echo "inglés) que usted tiene instalada es demasiado vieja para ejecutar "
+                echo "la Interfaz de la $PROGNAME. Por favor instale "
+                echo "una nueva versión del Ambiente de Ejecución Java (versión $MIN_DISPLAY_VERSION o "
+                echo "posterior) y ejecute nuevamente este guión."
+            elif [ "$gslang" = "fr" ]; then
+                echo "La version de Java Runtime Environment que vous avez installée est"
+                echo "trop vielle pour faire fonctionner $PROGNAME."
+                echo "Veuillez installer une nouvelle version du JRE (version $MIN_DISPLAY_VERSION ou plus"
+                echo "récente) et redémarrez le script."
+            elif [ "$gslang" = "ru" ]; then
+                echo "÷ÅÒÓÉÑ Java Runtime Environment, ËÏÔÏÒÕÀ ÷Ù ÕÓÔÁÎÏ×ÉÌÉ, ÏÞÅÎØ ÓÔÁÒÁ,"
+                echo "ÞÔÏÂÙ ÕÐÒÁ×ÌÑÔØ ÂÉÂÌÉÏÔÅÞÎÙÍ $PROGNAME. ðÏÖÁÌÕÊÓÔÁ, "
+                echo "ÕÓÔÁÎÏ×ÉÔÅ ÎÏ×ÕÀ ×ÅÒÓÉÀ JRE (×ÅÒÓÉÀ $MIN_DISPLAY_VERSION ÉÌÉ ÂÏÌÅÅ ÎÏ×ÕÀ) É"
+                echo "ÐÅÒÅÕÓÔÁÎÏ×ÉÔÅ ÜÔÏÔ ÓËÒÉÐÔ"
+            else
+                echo "The version of the Java Runtime Environment you have installed ($OLDVER)"
+                echo "is too old to run the $PROGNAME. Please install a new"
+                echo "version of the JRE (version $MIN_DISPLAY_VERSION or newer) and rerun this script."
+            fi
+            return 1
+	    
+        else
+	    no_java "$MIN_DISPLAY_VERSION"
+	    return $?
+        fi
+	
+    fi
+    echo "Java:"
+    echo $javapath
+    echo
+    return 0
+}
+
+
+## ---- Check Java ----
+# Some users may set this line manually
+#JAVA_HOME=
+gslang=$1
+PROGNAME=$2
+MINIMUM_JAVA_VERSION=1.4.0_00
+MIN_DISPLAY_VERSION=1.4
+
+# sus out search4j
+# first look for compiled search4j executable inside the current folder
+if [ -x search4j ]; then
+    SEARCH4J_EXECUTABLE=search4j	
+elif [ -x "$GSDLHOME/bin/$GSDLOS/search4j" ]; then
+    SEARCH4J_EXECUTABLE=$GSDLHOME/bin/$GSDLOS/search4j
+elif [ -x "$GSDL3SRCHOME/bin/$GSDLOS/search4j" ]; then
+    SEARCH4J_EXECUTABLE=$GSDL3SRCHOME/bin/search4j
+elif [ -x "../bin/$GSDLOS/search4j" ]; then
+    SEARCH4J_EXECUTABLE=../bin/$GSDLOS/search4j
+elif [ -x "../bin/search4j" ]; then
+    SEARCH4J_EXECUTABLE=../bin/search4j
+else
+    echo "Couldn't determine the location of the search4j executable"
+    echo "If you are running Greenstone2"
+    echo "   * check GSDLHOME is set"
+    echo "   * check bin/$GSDLOS/search4j exists"
+    echo "   * check bin/$GSDLOS/search4j is executable"
+    echo "If you are running Greenstone3"
+    echo "   * check GSDL3SRCHOME is set"
+    echo "   * check bin/search4j exists"
+    echo "   * check bin/search4j is executable"
+    echo "   * try running 'ant compile-search4j'"
+fi
+
+# Now run set_java_exec with search4j if we found one, else try javahome
+if [ "x$SEARCH4J_EXECUTABLE" != "x" ]; then
+    set_java_exec "$SEARCH4J_EXECUTABLE" "$MINIMUM_JAVA_VERSION" "$MIN_DISPLAY_VERSION"
+    retval=$?
+else
+    try_java "$MIN_DISPLAY_VERSION"
+    retval=$?
+fi
+return $retval
Index: /gsdl/stable/glisite.cfg.in
===================================================================
--- /gsdl/stable/glisite.cfg.in	(revision 20131)
+++ /gsdl/stable/glisite.cfg.in	(revision 20131)
@@ -0,0 +1,11 @@
+[gsdl]
+enterlib=/gsdl
+keeplog=0
+consolelog=0
+portnumber=80
+externalaccess=0
+autoenter=1
+browser=3
+start_browser=0
+address_resolution_method=2
+
Index: /gsdl/stable/gs2-server.sh
===================================================================
--- /gsdl/stable/gs2-server.sh	(revision 20131)
+++ /gsdl/stable/gs2-server.sh	(revision 20131)
@@ -0,0 +1,130 @@
+#!/bin/bash
+serverlang=en
+
+java_min_version=1.4.0_00
+PROGNAME="gs2-server"
+
+function autoset_gsdl_home() {
+
+  # remove leading ./ if present
+  prog="${0#./}"
+
+  isrelative="${prog%%/*}"
+
+  if [ ! -z "$isrelative" ] ; then
+    # some text is left after stripping
+    # => is relative
+    prog="$PWD/$prog"
+  fi
+
+  fulldir="${prog%/*}"
+
+  # remove trailing /. if present
+  eval "$1=\"${fulldir%/.}\""
+}
+
+function isinpath() {
+  for file in `echo $1 | sed 's/:/ /g'`; do
+    if [ "$file" == "$2" ]; then
+      echo true
+      return
+    fi
+  done
+  echo false
+}
+
+
+echo "Greenstone 2 Server"
+echo "Copyright (C) 2009, New Zealand Digital Library Project, University Of Waikato"
+echo "This software comes with ABSOLUTELY NO WARRANTY; for details see LICENSE.txt"
+echo "This is free software, and you are welcome to redistribute it"
+
+##  -------- Run the Greenstone 2 Server --------
+
+##  ---- Determine GSDLHOME ----
+gsdl2path=
+
+# Some users may set the above line manually
+if [ -z "$gsdl2path" ]; then
+   autoset_gsdl_home gsdl2path
+fi
+
+# Setup Greenstone2, unless it has already been done
+if [ -z "$GSDLHOME" ]; then 
+  pushd "$gsdl2path" > /dev/null
+  source ./setup.bash
+  popd > /dev/null
+fi
+
+
+# First test that there is actually something that can be run...
+# Exit if the apache-httpd folder doesn't exist for some reason
+# (The errors reported when the apache webserver does not exist 
+# in the correct location are not at all helpful).
+if [ ! -d "$GSDLHOME/apache-httpd" ]; then
+    echo ""
+    echo "UNABLE TO CONTINUE: There is no apache-httpd directory."
+    echo "It does not look like the local apache webserver has been installed."
+    echo "Exiting..."
+    echo ""
+    exit 1
+fi
+
+# If there's no llssite.cfg file, copy from the template
+if [ ! -e "$GSDLHOME/llssite.cfg" ]; then
+    if [ -e "$GSDLHOME/llssite.cfg.in" ]; then
+    cp "$GSDLHOME/llssite.cfg.in" "$GSDLHOME/llssite.cfg"
+    else
+    echo "Warning: could not find llssite.cfg.in to create llssite.cfg from."
+    fi
+fi
+
+##  ---- Determine GSDLHOME ----
+# Set this to true if you want the Greenstone server interface to run in the background
+# and not print any error messages to the x-term.
+silent=
+
+# JRE_HOME or JAVA_HOME must be set correctly to run this program
+search4j -m $java_min_version &> /dev/null
+# for some reason, Mac requires an echo after the above
+echo
+if [ "$?" == "0" ]; then
+    # In Java code, '...getResourceAsStream("build.properties")'
+    # needs up to be in the right directory when run
+    pushd "$gsdl2path" > /dev/null
+
+
+    #CLASSPATH
+    if [ `isinpath "$CLASSPATH" "$GSDLHOME/lib/java"` == "false" ]; then
+        CLASSPATH="$GSDLHOME/lib/java:$CLASSPATH"
+        for JARFILE in lib/java/*.jar; do
+            CLASSPATH="$CLASSPATH:$GSDLHOME/$JARFILE"
+        done
+        export CLASSPATH
+        echo "  - Adjusted CLASSPATH"
+
+    else
+        echo "  - CLASSPATH already correct"
+    fi
+
+    ## ---- Check Java ----
+    # call the script with source, so that we have the variables it sets ($javapath)
+    exit_status=0
+    source ./findjava.sh "$serverlang" "$PROGNAME"
+    exit_status=$?
+    if [ "$exit_status" -eq 1 ]; then
+        exit 1;
+    fi
+
+    if [ "x$silent" == "x" -o "x$silent" != "xtrue" ]; then 
+        # verbose mode, show all output, but then we can't run the server interface in the background
+	"$javapath" org.greenstone.server.Server2 "$GSDLHOME" "$serverlang" $*
+    else
+        # If we launch the Greenstone Server Interface application in the background (with & at end)
+        # need to redirect any STDERR (STDOUT) output to /dev/null first, else output will hog the x-term.
+	"$javapath" org.greenstone.server.Server2 "$GSDLHOME" "$serverlang" $* > /dev/null &
+    fi
+
+    popd > /dev/null
+fi
+
Index: /gsdl/stable/gsicontrol.bat
===================================================================
--- /gsdl/stable/gsicontrol.bat	(revision 20131)
+++ /gsdl/stable/gsicontrol.bat	(revision 20131)
@@ -0,0 +1,193 @@
+@echo off
+
+setlocal
+set testdone=0
+set target=%1
+set configfile=%2
+
+:: Need to get greenstone installation directory
+:: set cwd=%CD%
+
+set MONITOR_SUCCESS=MAKE SUCCESSFUL
+set MONITOR_FAILED=MAKE FAILED
+set MONITOR_FINISHED=MAKE DONE
+
+:: check that we have >=1 and <=2 arguments
+:chkargs
+if "%target%" == "" goto :usage
+if not "%3" == "" goto :usage
+	goto begincmd
+
+
+:usage
+echo.
+echo    Usage: %0 command
+echo           where command is any of the following: 
+echo    web-start
+echo    web-stop
+echo    web-restart
+echo    configure-admin
+echo    configure-web    [config-filename]
+echo    configure-apache [config-filename]
+echo    configure-cgi
+
+::echo    web-status
+::echo    web-graceful
+::echo    test-gsdlhome
+::echo    web-stop-tested
+echo.
+goto exit
+
+
+:begincmd
+:: web-stop-tested command assumes GSDLHOME/greenstone environment is already set
+if "%target%" == "web-stop-tested" goto stoptest
+
+:: For all other commands, the greenstone environment needs to be set first before they can be run
+:testgsdl
+if NOT "%GSDLHOME%" == "" goto commands
+        echo.
+	echo Environment variable GSDLHOME not set.
+	echo   This needs to be set to run the gsicontrol command %target%.
+	echo   Have you run setup.bat?
+	echo.
+	goto exit
+
+
+::MAIN MENU
+:commands
+if "%target%" == "web-start" goto start
+if "%target%" == "web-stop" goto stop
+if "%target%" == "web-restart" goto restart
+if "%target%" == "web-status" goto status
+if "%target%" == "web-graceful" goto graceful
+if "%target%" == "configure-admin" goto cfgadmin
+if "%target%" == "configure-web" goto cfgweb
+if "%target%" == "configure-apache" goto cfgapach
+if "%target%" == "configure-cgi" goto cfgcgi
+if "%target%" == "test-gsdlhome" goto testgsdl
+if "%target%" == "portcon" goto portcon1
+	:: unknown command
+	goto usage
+
+:start
+"%GSDLHOME%\bin\windows\starthttpd.exe" GS2_APACHE_HTTPD "%GSDLHOME%\apache-httpd\windows\bin\httpd.exe"
+echo %MONITOR_SUCCESS%
+echo %MONITOR_FINISHED%
+goto exit
+
+:stop
+if exist "%GSDLHOME%\apache-httpd\%GSDLOS%\conf\httpd.conf" "%GSDLHOME%\bin\windows\stophttpd.exe" GS2_APACHE_HTTPD
+rem if exist "%GSDLHOME%\apache-httpd\%GSDLOS%\conf\httpd.conf" "%GSDLHOME%\apache-httpd\%GSDLOS%\bin\apachectl" stop
+echo %MONITOR_SUCCESS%
+echo %MONITOR_FINISHED% 
+goto exit
+
+:restart
+if exist "%GSDLHOME%\apache-httpd\%GSDLOS%\conf\httpd.conf" "%GSDLHOME%\bin\windows\stophttpd.exe" GS2_APACHE_HTTPD
+:: wait 2s, see http://malektips.com/dos0017.html. The 2 in the 2nd line is variable
+ping 127.0.0.1 -n 2 -w 1000 > nul
+ping 127.0.0.1 -n 2 -w 1000> nul
+::"%GSDLHOME%\bin\windows\starthttpd.exe" GS2_APACHE_HTTPD "%GSDLHOME%\apache-httpd\windows\bin\httpd.exe"
+goto start
+
+:status
+:graceful
+::echo Command %target% is not yet operational (no local apache web server included in this release).
+goto exit
+
+:stoptest
+if exist "%GSDLHOME%\apache-httpd\%GSDLOS%\conf\httpd.conf" "%GSDLHOME%\bin\windows\stophttpd.exe" GS2_APACHE_HTTPD
+rem if exist "%GSDLHOME%\apache-httpd\%GSDLOS%\conf\httpd.conf" "%GSDLHOME%\apache-httpd\%GSDLOS%\bin\apachectl" stop
+goto exit
+
+::configure-web
+::configure-cgi
+:cfgweb
+:cfgcgi
+if exist "%GSDLHOME%\cgi-bin\gsdlsite.cfg" goto cgimsg
+	echo Configuring cgi-bin\gsdlsite.cfg
+	set gsdlpath=%GSDLHOME%
+	for /F "delims=*" %%T in ('"echo %gsdlpath%| bin\windows\sed.exe s@\\@\\\\@g"') do set safepath=%%T
+	bin\windows\sed.exe "s@\*\*GSDLHOME\*\*@\"%safepath%\"@g" cgi-bin/gsdlsite.cfg.in > cgi-bin/gsdlsite.cfg
+	set gsdlpath=
+	set safepath=
+	goto cgifin
+
+:cgimsg
+echo WARNING: Nothing done for make configure-cgi.
+echo    If you wish to regenerate the file
+echo    %GSDLHOME%\cgi-bin\gsdlsite.cfg
+echo    from scratch, delete the existing file first.
+echo.
+
+:cgifin
+if "%target%" == "configure-cgi" goto exit
+if "%target%" == "configure-web" goto cfgapach
+
+::configure-apache
+:cfgapach
+if exist "%GSDLHOME%\llssite.cfg" goto :exit 
+if not exist "%GSDLHOME%\llssite.cfg.in" goto :exit
+	copy llssite.cfg.in llssite.cfg
+	set configfile="%GSDLHOME%\llssite.cfg"
+	goto exit
+
+::configure-admin
+:cfgadmin
+echo.
+echo Configuring admin user password:
+for /F %%T in ('getpw') do set encrypted_password=%%T
+
+:: Have to create an intermediate file in the following, because echoing
+:: lines straight into a pipe adds spaces before the end of each line.
+:: When piping, need to double-escape the angle brackets with three hat signs,
+:: but when redirecting to a file, need to escape only once (one hat sign). 
+if ERRORLEVEL 0 (
+	(
+	echo [admin]
+	echo ^<enabled^>true
+	echo ^<groups^>administrator,colbuilder,all-collections-editor
+	echo ^<password^>%encrypted_password%
+	echo ^<username^>admin
+	) > "%GSDLHOME%\etc\users.txt"
+	type "%GSDLHOME%\etc\users.txt" | txt2db -append "%GSDLHOME%\etc\users.gdb"
+	del "%GSDLHOME%\etc\users.txt"	
+) else (
+	echo Did not set password 
+)
+goto exit
+
+::configure-port-and-connection
+:portcon1
+set /p port=Enter port number to use:
+set /p connect=Allow external connections [yes/no]:
+if "%connect%" == "yes" set allowfrom="all" goto portcon2
+if "%connect%" == "y" set allowfrom="all" goto portcon2
+set allowfrom="127.0.0.1"
+
+:portcon2
+if "%port%" == "" goto exit
+	set _sed="bin\windows\sed.exe"
+	set gsdlpath=%GSDLHOME%
+	for /F "delims=*" %%T in ('"echo %gsdlpath%| bin\windows\sed.exe s@\\@\/@g"') do set safepath=%%T
+
+	echo Port: %port%
+	echo Stopping web server (if running)
+	if not exist "%GSDLHOME%\apache-httpd\%GSDLOS%\conf\httpd.conf"	echo missing conf file
+	if exist "%GSDLHOME%\apache-httpd\%GSDLOS%\conf\httpd.conf" "%GSDLHOME%\bin\windows\stophttpd.exe" GS2_APACHE_HTTPD
+	echo Setting config file to use port %port%
+bin\windows\sed.exe "s@\*\*GSDLHOME\*\*@\"%safepath%\"@g" cgi-bin/gsdlsite.cfg.in > cgi-bin/gsdlsite.cfg
+	type "%GSDLHOME%\apache-httpd\%GSDLOS%\conf\httpd.conf.in" | %_sed% "s@\*\*PORT\*\*@%port%@g" | %_sed% "s@\*\*CONNECTION\*\*@%allowfrom%@g" | %_sed% "s@\*\*GSDLHOME\*\*@%safepath%@g" | %_sed% "s@\*\*APACHE_HOME_OS\*\*@%safepath%\/apache-httpd\/%GSDLOS%@g" > "%GSDLHOME%\apache-httpd\%GSDLOS%\conf\httpd.conf"
+	echo Type '%0 web-start' to start the web server running on port %port%
+	echo Done
+	set port=
+	set connect=
+	set allowfrom=
+	set _sed=
+	set safepath=
+	set gsdlpath=
+
+
+:exit
+endlocal
Index: /gsdl/stable/gsicontrol.sh
===================================================================
--- /gsdl/stable/gsicontrol.sh	(revision 20131)
+++ /gsdl/stable/gsicontrol.sh	(revision 20131)
@@ -0,0 +1,218 @@
+#!/bin/bash
+
+testdone=0
+
+function test-gsdlhome {
+    if [ $testdone == "0" ] ; then
+        if test -z "$GSDLHOME" ; then
+	    echo "" ;
+  	    echo "Environment variable GSDLHOME not set." ;
+	    echo "  This needs to be set to run this gsicontrol command." ;
+	    echo "  Have you run 'source setup.bash'?" ;
+	    echo "" ;
+	    exit 1
+        else
+	    echo "Using: " ;
+	    echo "  GSDLHOME = $GSDLHOME" ;
+	    echo "  GSDLOS   = $GSDLOS" ; 
+        fi
+	testdone=1
+    fi
+}  
+
+function configure-cgi {
+    test-gsdlhome
+    if test ! -e $GSDLHOME/cgi-bin/gsdlsite.cfg ; then
+	echo "Configuring cgi-bin/gsdlsite.cfg" ;
+	sed "s@\*\*GSDLHOME\*\*@$GSDLHOME@g" cgi-bin/gsdlsite.cfg.in > cgi-bin/gsdlsite.cfg ;
+    else
+	echo "WARNING: Nothing done for make configure-cgi." ;
+	echo "   If you wish to regenerate the file " ;
+	echo "   $GSDLHOME/cgi-bin/gsdlsite.cfg" ;
+	echo "   from scratch, delete the existing file first." ;
+    fi
+}
+
+function configure-admin {
+    test-gsdlhome
+    echo "" ;
+    echo "Configuring admin user password:" ;
+    encrypted_password=`getpw` ;
+    if [ $? = "0" ] ; then
+	echo -e "[admin]\n<enabled>true\n<groups>administrator,colbuilder,all-collections-editor\n<password>$encrypted_password\n<username>admin" \
+	    | txt2db -append "$GSDLHOME/etc/users.gdb" ;
+    else
+	echo "Did not set password" ;
+    fi
+    echo ""
+}
+
+
+function _configure-port-and-connection {
+    test-gsdlhome
+    echo "Enter port number to use:"
+    read port ;
+    echo "Allow external connections [yes/no]:"
+    read connection ;
+    if [ $connection = "yes" ] || [ $connection = "y" ] ; then
+        allowfrom="all"
+    else 
+        allowfrom="127.0.0.1"
+    fi
+
+    if test ! -z $port ; then
+	echo "Port: $port" ;
+	echo "Stopping web server (if running)" ;
+	web-stop-tested ;
+	echo "Setting config file to use port $port";
+	cat "$GSDLHOME/apache-httpd/$GSDLOS/conf/httpd.conf.in" \
+	| sed "s@\*\*PORT\*\*@$port@g" \
+	| sed "s@\*\*CONNECTION\*\*@$allowfrom@g" \
+	| sed "s@\*\*GSDLHOME\*\*@$GSDLHOME@g" \
+	| sed "s@\*\*APACHE_HOME_OS\*\*@$GSDLHOME/apache-httpd/$GSDLOS@g" \
+	> "$GSDLHOME/apache-httpd/$GSDLOS/conf/httpd.conf" ;
+	echo "Type '$0 web-start' to start the web server running on port $port" ;
+    fi ;
+    echo "Done" ;
+}
+
+
+MONITOR_SUCCESS="MAKE SUCCESSFUL"
+MONITOR_FAILED="MAKE FAILED"
+MONITOR_FINISHED="MAKE DONE"
+
+function configure-apache {
+    test-gsdlhome
+    configfile=$1 ;
+# if no configfile given, launch it with llssite.cfg. Create it from the template if needed.
+    if [ "x$configfile" = "x" ]; then
+	if test ! -e "$GSDLHOME/llssite.cfg" && test -e "$GSDLHOME/llssite.cfg.in" ; then
+	    cp "$GSDLHOME/llssite.cfg.in" "$GSDLHOME/llssite.cfg" ;
+	fi
+	configfile="$GSDLHOME/llssite.cfg";
+    fi ;
+    echo "Configuring the apache webserver..." ;
+    port=`egrep "^portnumber" $configfile | awk -F= '{print $2}'` ;
+
+    externalaccess=`egrep "^externalaccess" $configfile | awk -F= '{print $2}'` ;
+    if [ $externalaccess == "1" ] ; then 
+	externalaccess="yes"
+    else
+	externalaccess="no"
+    fi
+
+    echo -e "$port\n$externalaccess" | _configure-port-and-connection ;
+    if test -e "$GSDLHOME/apache-httpd/$GSDLOS/conf/httpd.conf" ; then
+	echo $MONITOR_SUCCESS;
+    else
+	echo $MONITOR_FAILED;
+    fi
+    echo $MONITOR_FINISHED
+}
+
+function configure-web {
+    configure-cgi
+    configure-apache $1
+}
+
+function web-status {
+    test-gsdlhome
+    $GSDLHOME/apache-httpd/$GSDLOS/bin/apachectl status
+}
+
+function web-start { 
+    test-gsdlhome
+    $GSDLHOME/apache-httpd/$GSDLOS/bin/apachectl start
+    echo $MONITOR_SUCCESS
+    echo $MONITOR_FINISHED
+}
+
+function web-restart {
+    test-gsdlhome
+    $GSDLHOME/apache-httpd/$GSDLOS/bin/apachectl restart
+    echo $MONITOR_SUCCESS
+    echo $MONITOR_FINISHED
+}
+
+function web-graceful {
+    test-gsdlhome
+    $GSDLHOME/apache-httpd/$GSDLOS/bin/apachectl graceful
+    echo $MONITOR_SUCCESS
+    echo $MONITOR_FINISHED
+}
+
+function web-stop-tested {
+# This version runs without testing for GSDLHOME
+# Useful to be run as a target when we know test-gsdlhome has already
+# been done.  This avoids a unnecessary repetition of printing
+# out the values of GSDLHOME and GSDLOS
+    if test -e "$GSDLHOME/apache-httpd/$GSDLOS/conf/httpd.conf" ; then
+	$GSDLHOME/apache-httpd/$GSDLOS/bin/apachectl stop ;
+    fi
+}
+
+function web-stop {
+    test-gsdlhome
+    web-stop-tested
+    echo $MONITOR_SUCCESS
+    echo $MONITOR_FINISHED
+}
+
+function usage {
+    echo ""
+    echo "   Usage: $0 <command>"
+    echo "          where <command> is any of the following: "
+    echo "   web-start"
+    echo "   web-stop"
+    echo "   web-restart"
+    echo "   web-status"
+    echo "   web-graceful"
+    echo "   configure-admin"
+    echo "   configure-web [config-filename]"
+    echo "   configure-apache [config-filename]"
+    echo "   configure-cgi"
+    echo "   test-gsdlhome"
+    echo "   web-stop-tested"
+    echo ""
+}
+
+
+if [[ $# < 1  || $# > 2 ]] ; then
+    usage
+    exit 0
+fi
+
+target=$1
+configfile=$2
+
+case $target in
+    web-start)
+	web-start;;
+    web-stop)
+	web-stop;;
+    web-restart)
+	web-restart;;
+    web-status)
+	web-status;;
+    web-graceful)
+	web-graceful;;
+    configure-admin)
+	configure-admin;;
+    configure-web)
+	configure-web $configfile;;
+    configure-apache)
+	configure-apache $configfile;;
+    configure-cgi)
+	configure-cgi;;
+    test-gsdlhome)
+	test-gsdlhome;;
+    web-stop-tested)
+	web-stop-tested;;
+    *)
+	echo
+        echo "Command unrecognised: $target"
+	usage;;
+
+esac
+
+exit;
Index: /gsdl/stable/gsterm.sh
===================================================================
--- /gsdl/stable/gsterm.sh	(revision 20131)
+++ /gsdl/stable/gsterm.sh	(revision 20131)
@@ -0,0 +1,3 @@
+#!/bin/bash
+source setup.bash
+/bin/bash --rcfile .gstermrc
Index: /gsdl/stable/install-sh
===================================================================
--- /gsdl/stable/install-sh	(revision 20131)
+++ /gsdl/stable/install-sh	(revision 20131)
@@ -0,0 +1,238 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
Index: /gsdl/stable/lib/java/log4j.properties.in
===================================================================
--- /gsdl/stable/lib/java/log4j.properties.in	(revision 20131)
+++ /gsdl/stable/lib/java/log4j.properties.in	(revision 20131)
@@ -0,0 +1,62 @@
+## greenstone home 
+gsdl2.home=@gsdl2home@
+
+##Configure log4j's operation at the meta level                              
+##Observe log4j parsing this file
+#log4j.debug=true
+##Set this to false for log4j to actually obey the log4j.disable property(next)
+log4j.disableOverride=false
+##Disable all logging in all categories for messages with priority equal to
+##or lower than the one given here
+log4j.disable=DEBUG
+
+#####configure the loggers####
+##general logger                                                   
+log4j.rootCategory=INFO, infolog
+
+##usage logger
+log4j.category.org.greenstone.gsdl3.LibraryServlet=INFO, usagelog
+log4j.additivity.org.greenstone.gsdl3.LibraryServlet=false
+
+##server logger
+##Set to INFO if you want INFO (success) messages to appear as well
+##Set to WARN if you want to turn INFO and DEBUG messages off.
+log4j.category.org.greenstone.server=INFO, serverlog
+log4j.additivity.org.greenstone.server=false
+
+#####configure appenders and their oprions####                                  
+##general logger
+log4j.appender.infolog=org.apache.log4j.RollingFileAppender
+log4j.appender.infolog.File=${gsdl2.home}/etc/logs-gsi/greenstone.log
+#Control the maximum log file size
+log4j.appender.infolog.MaxFileSize=100KB
+#Keep backup file(s) (backups will be in filename.1, .2, .3 etc.)
+log4j.appender.infolog.MaxBackupIndex=3
+
+##usage logger
+log4j.appender.usagelog=org.apache.log4j.RollingFileAppender
+log4j.appender.usagelog.File=${gsdl2.home}/etc/logs-gsi/usage.log
+#Control the maximum log file size
+log4j.appender.usagelog.MaxFileSize=1000KB
+
+##Server's logger
+log4j.appender.serverlog=org.apache.log4j.RollingFileAppender
+log4j.appender.serverlog.File=${gsdl2.home}/etc/logs-gsi/server.log
+
+
+#####Configure appender layouts and their options#### 
+## general logger layout
+log4j.appender.infolog.layout=org.apache.log4j.PatternLayout
+log4j.appender.infolog.layout.ConversionPattern=%-5p: [%d{yyyy-MM-dd hh:mm:ss}] %C{1}.%M()%n %m%n
+
+##usage logger layout
+# Usage log contains:                                                        
+#      loggingTime + servletName + args (in URL plus saved in a session) +  
+#      remoteAddress + sessionID + browerInfo                               
+log4j.appender.usagelog.layout=org.apache.log4j.PatternLayout
+log4j.appender.usagelog.layout.ConversionPattern=[%d{yyyy-MM-dd hh:mm:ss}] %m%n
+
+##server logger layout
+log4j.appender.serverlog.layout=org.apache.log4j.PatternLayout
+log4j.appender.serverlog.layout.ConversionPattern=%-5p: [%d{yyyy-MM-dd hh:mm:ss}] %C{1}.%M()%n %m%n
+
Index: /gsdl/stable/lib/java/server.properties
===================================================================
--- /gsdl/stable/lib/java/server.properties	(revision 20131)
+++ /gsdl/stable/lib/java/server.properties	(revision 20131)
@@ -0,0 +1,39 @@
+#greenstone.version=Version 2-trunk
+Server2Settings.Port=Apache port:
+Server2Settings.URL=Library URL prefix:
+Server2Control.Version=Version 2-trunk
+Server2Control.Title=Greenstone 2 Digital Library
+
+#greenstone.version=Version 3.2
+Server3Settings.Port=Tomcat port:
+Server3Settings.URL=Servlet:
+Server3Control.Version=Version 3-trunk
+Server3Control.Title=Greenstone3 Digital Library
+
+ServerSettings.Title=Server settings
+ServerSettings.Auto_Start=Enter the library automatically
+ServerSettings.OK=OK
+ServerSettings.Cancel=Cancel
+ServerSettings.DefaultBrowser=Default browser
+ServerSettings.OtherBrowser=Other browser
+ServerSettings.ChooseBrowser=Enter library using:
+ServerSettings.Browse=Browse
+
+ServerControl.EnterLibrary=Enter Library
+ServerControl.RestartLibrary=Restart Library
+ServerControl.StartServer=Start Server
+ServerControl.Frame_Title=Greenstone Server
+ServerControl.Help_RestartLibrary=Press the 'Restart Library' button to restart the server, launch a browser and enter the library.\nYou can change server settings from the File menu.
+ServerControl.Help_EnterLibrary=Press the 'Enter Library' button to launch a browser and enter the library.\nYou can change server settings from the File menu.
+ServerControl.Starting=Starting server...
+ServerControl.Configuring=Configuring server...
+ServerControl.Stopping=Stopping server...
+ServerControl.LaunchingBrowser=Launching browser...
+ServerControl.LaunchBrowser=Launch browser
+ServerControl.Menu.File=File
+ServerControl.Menu.Settings=Settings...
+ServerControl.Menu.Exit=Exit
+ServerControl.Error={0} failed, please check server.log in {1} for details. 
+ServerControl.Failed={0} failed
+ServerControl.Success={0} success
+ServerSetting.SettingChanged=The new settings will be available after the server has been restarted
Index: /gsdl/stable/llssite.cfg.in
===================================================================
--- /gsdl/stable/llssite.cfg.in	(revision 20131)
+++ /gsdl/stable/llssite.cfg.in	(revision 20131)
@@ -0,0 +1,10 @@
+[gsdl]
+enterlib=/gsdl
+keeplog=0
+consolelog=0
+portnumber=80
+externalaccess=0
+autoenter=0
+browser=3
+start_browser=1
+address_resolution_method=2
Index: /gsdl/stable/macros/about.dm
===================================================================
--- /gsdl/stable/macros/about.dm	(revision 20131)
+++ /gsdl/stable/macros/about.dm	(revision 20131)
@@ -0,0 +1,89 @@
+# this file must be UTF-8 encoded
+package about
+
+#######################################################################
+# Icons
+#######################################################################
+
+# _imagethispage_ set in nav_css/nav_ns4 macro files
+
+# don't want link to 'about' page
+_imagecollection_ {_If_("_iconcollection_" ne "",
+	<img class="icon" src="_iconcollection_" alt="_collectionname_" title="_collectionname_">,_imagecollectionv_)}
+_imagecollection_ [v=1] {_imagecollectionv_}
+_imagecollectionv_ {<p class="collectiontitle">_collectionname_</p>}
+#######################################################################
+# about page content 
+#######################################################################
+
+_pagetitle_ {_collectionname_}
+
+_content_ {
+_optnavigationbar_
+
+<div class="document">
+_If_("_cgiargqt_" ne "1",
+     _If_("_cgiargu_" ne "1",_aboutqueryform_)
+    )		   
+_If_(_Global:collectionextra_,<p>_textabout_)
+_textsubcollections_
+
+<div class="section">
+<h3>_help:textsimplehelpheading_</h3>
+_help:simplehelp_
+</div>
+
+</div>
+}
+
+
+# _aboutqueryform_ is reset to "" in the server if the collection isn't
+# searchable or if the search form is a fielded form (and therefore too
+# big to fit)
+_aboutqueryform_ {
+<div class="queryform">
+_query:queryform_
+</div>
+
+<div class="divbar">&nbsp;</div>
+}
+
+_textabout_ {
+<div class="section">
+<h3>_textabcol_</h3>
+_Global:collectionextra_
+</div>
+}
+
+# set from within server
+_textsubcollections_ {}
+
+_aboutCollage_ {}
+_classifier_ {}
+_collageempty_ {There is no collage classifier defined for this collection!}
+_collageapplet_ {
+
+ <p>
+ <center>
+
+ <applet CODEBASE="_httpprefix_/bin/java" code="org.nzdl.gsdl.GsdlCollageApplet.GsdlCollageApplet.class" 
+         archive="GsdlCollageApplet.jar" width="445" height="250">
+ 
+	 <param name="gwcgi" value="_gwcgi_">
+         <param name="collection" value="_cgiargc_"> 
+     	 <param name="classifier" value="CL_classifier_.1">
+	   
+     	 <param name="hrefMustHave" value="cl=CL_classifier_.1">
+     	 <param name="imageMustNotHave" value="hl=%x=%gt=%gc=%.pr">
+
+     <param name="imageType" value=".jpg%.png">  
+     <param name="verbosity" value="5">
+     <param name="maxDepth" value="3">
+     <param name="refreshDelay" value="1500">
+     <param name="isJava2" value="auto">
+
+ </applet>
+
+ </center>
+ <p>
+}
Index: /gsdl/stable/macros/amharic.dm
===================================================================
--- /gsdl/stable/macros/amharic.dm	(revision 20131)
+++ /gsdl/stable/macros/amharic.dm	(revision 20131)
@@ -0,0 +1,978 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Amharic Language text and icon macros 
+# Translated by Yohannes Mulugeta and Abiyot Bayou
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=am] {ááµáá¶áœ}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=am] {áá ááá­á€}  
+_textdate_ [l=am] {ášá³á°áá áµ ááá€}  
+_textnumpages_ [l=am] {ášááœ á¥ááµá€}  
+
+_textsignin_ [l=am] {áá£}  
+
+_textdefaultcontent_ [l=am] {ášá°á ášáá áá
+ ááá á áá»ááá¢ áá° ááªááµá¶á á²áá³á áá­á¥ášáª áááááµ ášáááá«á
+á áá° áá áááá» á áá«á­ áá­á ášáá­ á«ááá ášááá» á áá«á­ á°á ááá¢}  
+
+_textdefaulttitle_ [l=am] {áá€áµá²á€á (GSDL) áµá
+á°áµ}  
+
+_textbadcollection_ [l=am] {á­á
+ á­ááœáµ ("_cvariable_" ášá°á£á) á áá
+ ášááªááµá¶á á²áá³á áá¥ášáª ááµá¥ á áá°á«ááá¢}  
+
+_textselectpage_ [l=am] {-- ááœ áášá¥ --}  
+
+_collectionextra_ [l=am] {á­á
+ á­ááœáµ _about:numdocs_ á°áá¶áœá á­ááá¢ á­ááœá± ášá°áá ášá áš _about:builddate_áááµ á ááµ ááá¢}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=am] {<p>á­á
+ á­ááœáµ ášá«áá _numdocs_ _If_("_numdocs_" eq "1",á°ááµ,á°áá¶áœ), á á á
+ááá _numbytes_ á«á
+á á áá ášá°ááááážá áœáááœ á¥á áá³á³á³ á­ááá¢
+<p><a href="_httppagex_(bsummary)">á¥áá
+á á á
+ á¥á³á°á­á</a> ášáá
+á á­ááœáµ ááá£á³ ááášáµ áµáœááá
+á¢
+}  
+
+_textdescrcollection_ [l=am] {}
+_textdescrabout_ [l=am] {áµá ááœ}  
+_textdescrhome_ [l=am] {ááá» ááœ}  
+_textdescrhelp_ [l=am] {á¥áá ááœ}  
+_textdescrpref_ [l=am] {ášáá­á« ááœ}  
+_textdescrgreenstone_ [l=am] {ááªááµá¶á á²áá³á áá­á¥ášáª á¶ááµáá­}  
+_textdescrusab_ [l=am] {ááá áá á«áµážáášá
+ áááµáá?}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=am] {ááá}  
+_labelSearch_ [l=am] {ááá}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=am] {á­ááµ}  
+_labelTitle_ [l=am] {á­áá¶áœ}  
+_textCreator_ [l=am] {áá£áª}  
+_labelCreator_ [l=am] {áá£áªááœ}  
+_textSubject_ [l=am] {á­áá° áá³á­}  
+_labelSubject_ [l=am] {áá³á®áœ}  
+_textDescription_ [l=am] {ááá}  
+_labelDescription_ [l=am] {áááá«}  
+_textPublisher_ [l=am] {á á³á³á}  
+_labelPublisher_ [l=am] {á á³á³áááœ}  
+_textContributor_ [l=am] {á áµá°ááœáŠ á«á°ášá}  
+_labelContributor_ [l=am] {á áµá°ááœáŠ á«á°ášá}  
+_textDate_ [l=am] {áá}  
+_labelDate_ [l=am] {áááœ}  
+_textType_ [l=am] {áá­ááµ}  
+_labelType_ [l=am] {áá­ááµ}  
+_textFormat_ [l=am] {áá­ááµ}  
+_labelFormat_ [l=am] {áá­áá¶áœ}  
+_textIdentifier_ [l=am] {ááá«}  
+_labelIdentifier_ [l=am] {ááá«ááœ}  
+_textSource_ [l=am] {ášáá­á áµá}  
+_labelSource_ [l=am] {ášáá­á áµááœ}  
+_textLanguage_ [l=am] {ááá}  
+_labelLanguage_ [l=am] {áááááœ}  
+_textRelation_ [l=am] {áááááµ}  
+_labelRelation_ [l=am] {áááááµ}  
+_textCoverage_ [l=am] {áœáá}  
+_labelCoverage_ [l=am] {áœáá}  
+_textRights_ [l=am] {áá¥á¶áœ}  
+_labelRights_ [l=am] {áá¥á¶áœ}  
+
+# DLS metadata set
+_textOrganization_ [l=am] {áµá­á
+áµ}  
+_labelOrganization_ [l=am] {áµá­á
+á¶áœ}  
+_textKeyword_ [l=am] {ááá áá}  
+_labelKeyword_ [l=am] {ááá áááµ}  
+_textHowto_ [l=am] {á¥ááŽáµ}  
+_labelHowto_ [l=am] {á¥ááŽáµ}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=am] {áášá}  
+_labelPhrase_ [l=am] {áášááœ}  
+_textCollage_ [l=am] {á®áá
+}  
+_labelCollage_ [l=am] {á®áá
+}  
+_textBrowse_ [l=am] {á áµáµ}  
+_labelBrowse_ [l=am] {á áµáµ}  
+_textTo_ [l=am] {áá°}  
+_labelTo_ [l=am] {á}  
+_textFrom_ [l=am] {áš}  
+_labelFrom_ [l=am] {áš}  
+_textAcronym_ [l=am] {áá
+á»áš áá}  
+_labelAcronym_ [l=am] {áá
+á»áš áááµ}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=am] {á  _1_ á áµáµ}  
+
+_textdescrSearch_ [l=am] {ášá°áá°á ááá¶áœá ááá}  
+_textdescrType_ [l=am] {á áá¥áµ áá­ááµ á áµáµ}  
+_textdescrIdentifier_ [l=am] {á áá¥áµ ááá« á áµáµ}  
+_textdescrSource_ [l=am] {á áá­á ášááá» áµá á áµáµ}  
+_textdescrTo_ [l=am] {á  áá° (To) ááµá­ á áá áá á áµáµ}  
+_textdescrFrom_ [l=am] {á  ášáá
+ (From) ááµáš á áá áá á áµáµ}  
+_textdescrCollage_ [l=am] {á ááµá á­ááœáµ á áµáµ}  
+_textdescrAcronym_ [l=am] {áá
+á»áš áááµá á áµáµ}  
+_textdescrPhrase_ [l=am] {áášááœá á áµáµ}  
+_textdescrHowto_ [l=am] {á¥ááŽáµ á¥áá°ááášá
+ á áµáµ}  
+_textdescrBrowse_ [l=am] {á°áá¶áœá á áµáµ}  
+_texticontext_ [l=am] {á°áá±á á°ááášáµ}  
+_texticonclosedbook_ [l=am] {á­á
+á á°ááµ á­ááµá á­áá±á á°ááášáµ}  
+_texticonnext_ [l=am] {áá° ááá¥áá á­áá}  
+_texticonprev_ [l=am] {áá° ááµáá á­áá}  
+
+_texticonworld_ [l=am] {ášáµášááœ á°áá±á á°ááášáµ}  
+
+_texticonmidi_ [l=am] {ášá€áá á­á²á á­ (MIDI) á°áá±á á°ááášáµ}  
+_texticonmsword_ [l=am] {ášáá­á­á®á¶ááµ áá­áµ á°áá±á á°ááášáµ}  
+_texticonmp3_ [l=am] {ášá€áá3 (MP3) á°áá±á á°ááášáµ}  
+_texticonpdf_ [l=am] {ášáá²á€á á°áá±á á°ááášáµ}  
+_texticonps_ [l=am] {ášááµáµáµá­áªááµ á°áá±á á°ááášáµ}  
+_texticonppt_ [l=am] {ášááá­ áá­ááµ á°áá±á á°ááášáµ}  
+_texticonrtf_ [l=am] {ášá á­á²á€á á°áá±á á°ááášáµ}  
+_texticonxls_ [l=am] {ášáá­á­á®á¶ááµ á€á­áµá€á á°áá±á á°ááášáµ}  
+
+_page_ [l=am] {áá
+}  
+_pages_ [l=am] {áááœ}  
+_of_ [l=am] {áš}  
+_vol_ [l=am] {á­áá}  
+_num_ [l=am] {á.}  
+
+_textmonth00_ [l=am] {}
+_textmonth01_ [l=am] {á¥á­}  
+_textmonth02_ [l=am] {ášá«á²áµ}  
+_textmonth03_ [l=am] {ááá¢áµ}  
+_textmonth04_ [l=am] {áá«áá«}  
+_textmonth05_ [l=am] {áááŠáµ}  
+_textmonth06_ [l=am] {á°á}  
+_textmonth07_ [l=am] {ááá}  
+_textmonth08_ [l=am] {áááŽ}  
+_textmonth09_ [l=am] {ááµášášá}  
+_textmonth10_ [l=am] {á¥á
+ááµ}  
+_textmonth11_ [l=am] {á
+á³á­}  
+_textmonth12_ [l=am] {á³á
+á³áµ}  
+
+_textdocument_ [l=am] {á°ááµ}  
+_textsection_ [l=am] {á­áá}  
+_textparagraph_ [l=am] {á áááœ}  
+
+_magazines_ [l=am] {ááœááµ}  
+
+_nzdlpagefooter_ [l=am] {<div class="divbar">Â </div>
+<p><a href="http://www.nzdl.org">ášáá ááááµ á²áá³á áá­á¥ášáª áá®áá­áµ</a>
+<br><a href="http://www.cs.waikato.ac.nz">ášá®áááá°á­ á³á­ááµ áµáá
+á­áµ á­áá</a>, 
+<a href="http://www.waikato.ac.nz">áá­á«á¶ á©áášá­á²á²</a>, 
+áá ááááµ}  
+
+_linktextHOME_ [l=am] {ááá»}  
+_linktextHELP_ [l=am] {á¥áá}  
+_linktextPREFERENCES_ [l=am] {áá­á«ááœ}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=am] {ááªááµá¶á á²áá³á áá­á¥ášáª}  
+
+_textnocollections_ [l=am] {ááá áá­ááµ ášáá°á« (ášá°ááá£á á«áá°áá°á ) á­ááœáµ ášáá}  
+
+_textadmin_ [l=am] {ášá áµá°á³á°á­ ááœ}  
+_textabgs_ [l=am] {áµá ááªááµá¶á}  
+_textgsdocs_ [l=am] {ášááªááµá¶á áááá¥áµ}  
+
+_textdescradmin_ [l=am] {á á²áµ á°á ááááœá ááášáá­á£ á á²áµá°á á£á á­ááœá¶áœ áá­ášá°á ááá áášá áááááµ á ááªááµá¶á á á«á«á áá­ ášáŽá­áá­ áášáááœá áááááµ á«áµáœáá}  
+
+_textdescrgogreenstone_ [l=am] {áµá ááªááµá¶á á¶ááµáá­á áµá áá ááááµ á²áá³á áá­á¥ášáª áá®áá­áµ á áá£á¥ á­ááá­áá }  
+
+_textdescrgodocs_ [l=am] {ášááªááµá¶á á á ááá áœáááœ}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=am] {ášáá¥ášáªá«á á á­áááœ}  
+_textdescrgli_ [l=am] {á á²áµ á­ááœáµ áááá á­á£ á«á á­ááœá¶áœ áá­ ááášáá­ áá­á ááµá°á«ášá« áááµášá áá­á á­ááœá¶áœá ááá¥ááµ á­ášá³á}  
+
+package collector
+
+_textcollector_ [l=am] {á°á¥á³á¢á}  
+_textdescrcollector_ [l=am] {á­á
+ ášáá¥ášáªá«áá á á­ááá
+ áááµá á­áœááá£ á¥á á¥á áá ášáá­á¥ášáªá«áá á á­ááá
+ áá áá á­áášá£áá¢ }  
+
+package depositor
+
+_textdepositor_ [l=am] {á áµááá©}  
+_textdescrdepositor_ [l=am] {á°áá¶áœá á£ááµ á­ááœá¶áœ ááµá¥ ááášáá­ á­ášá³áá}  
+
+package gti
+
+_textgti_ [l=am] {ášááªááµá¶á á°á­áá á á­áááœ}  
+_textdescrtranslator_ [l=am] {áá³á á¥á ášáááá ášááªááµá¶á áµáªáµ áááášáµ á­ášá³á}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=am] {áµááá
+ á­ááœáµ}  
+
+_textsubcols1_ [l=am] {<p>á á ááá­ á­ááœá± _1_ áááµ á­ááœá¶áœá á«á ááááá¢ 
+á áá ášááááµá€
+<blockquote>}  
+
+_textsubcols2_ [l=am] {</blockquote>
+á¥ášá°á ááá­ á«áá áááµ á­ááœáµ áááá
+ áá­á ááááá¥
+ášáá­á« ááá áá áá á­á»ááá¢}  
+
+_titleabout_ [l=am] {áµá}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=am] {ášáá­á¥ášáªáá á­ážááá á­áá áá}  
+_texticonclosedbookshelf_ [l=am] {á­á
+á ášáá­á¥ášáªáá á­áá á áá­ááµ á­áá¶áœá á°ááášáµ}  
+_texticonopenbook_ [l=am] {á­á
+á áá
+áá áá}  
+_texticonclosedfolder_ [l=am] {á­á
+á á áá á áá­ááµ á­áá¶áœá á°ááášáµ}  
+_texticonclosedfolder2_ [l=am] {áááµ á­ááá á­ááµá€}  
+_texticonopenfolder_ [l=am] {á­á
+á á áá áá}  
+_texticonopenfolder2_ [l=am] {áááµ á­áá ááá€}  
+_texticonsmalltext_ [l=am] {ášáœááá á­ážááá á­áá á°ááášáµ}  
+_texticonsmalltext2_ [l=am] {áœááá á°ááášáµ}  
+_texticonpointer_ [l=am] {ášá áá á­áá}  
+_texticondetach_ [l=am] {á­á
+áá ááœ á á á²áµ ááµá®áµ áá­ á­ááµ}  
+_texticonhighlight_ [l=am] {ášááááá« ááá¶áœá áášá¥}  
+_texticonnohighlight_ [l=am] {ášááááá« ááá¶áœá á áµáášá¥}  
+_texticoncontracttoc_ [l=am] {ááá«áá á°á¥áµá¥}  
+_texticonexpandtoc_ [l=am] {ááá«áá áá­á}  
+_texticonexpandtext_ [l=am] {áááá áœáááœ á á³á­}  
+_texticoncontracttext_ [l=am] {á áá á°áá­á á áááµ á­áááœ á¥á» áœáá á á³á­}  
+_texticonwarning_ [l=am] {<b>ááµá áááá«á€ </b>}  
+_texticoncont_ [l=am] {á­áá¥á?}  
+
+_textltwarning_ [l=am] {<div class="buttons">_imagecont_</div>
+_iconwarning_ á¥áá
+ á áœááá ááµááµ á áááá«á
+ ášáá³á© á á­á«á³ á³á³ááœá á«ááá«á
+}  
+
+_textgoto_ [l=am] {ááµ áá° ááœ}  
+_textintro_ [l=am] {<i>(ášááá¢á« áœáá)</i>}  
+
+_textCONTINUE_ [l=am] {áµáá¥ááá
+?}  
+
+_textEXPANDTEXT_ [l=am] {áœááá áá­á}  
+
+_textCONTRACTCONTENTS_ [l=am] {á­áá±á á°á¥áµá¥}  
+
+_textDETACH_ [l=am] {á áá
+}  
+
+_textEXPANDCONTENTS_ [l=am] {á­áá±á áá­á}  
+
+_textCONTRACT_ [l=am] {áœááá á°á¥áµá¥}  
+
+_textHIGHLIGHT_ [l=am] {ááášá¥}  
+
+_textNOHIGHLIGHT_ [l=am] {ášá°áášá  á¥áá³á­áá­}  
+
+_textPRINT_ [l=am] {á áµá}  
+
+_textnextsearchresult_ [l=am] {ášááá¥áá ášááá áá€áµ}  
+_textprevsearchresult_ [l=am] {ášááµáá ááá áá€áµ}  
+
+# macros for printing page
+_textreturnoriginal_ [l=am] {áá° ááááªá«á ááœ á°áááµ}  
+_textprintpage_ [l=am] {á­á
+á ááœ á áµá}  
+_textshowcontents_ [l=am] {ááá«áá á á³á­}  
+_texthidecontents_ [l=am] {ááá«áá á°á¥á
+}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=am] {_If_(_thislast_á£áá€áµ _thisfirst_ - _thislast_ áá€ _cgiargq_ áá á­á
+á£ áá€ _cgiargq_ áá á­á
+ ášááµáá ášáá)}  
+_textnoquerytitle_ [l=am] {ášááá ááœ}  
+
+_textsome_ [l=am] {á¥ááµ}  
+_textall_ [l=am] {ááá}  
+_textboolean_ [l=am] {á¡áá«á}  
+_textranked_ [l=am] {á á°ášá}  
+_textnatural_ [l=am] {á°áá¥á®á á}  
+_textsortbyrank_ [l=am] {ášá°ááá
+ááµ á°ášá}  
+_texticonsearchhistorybar_ [l=am] {ášááá á³áªá­}  
+
+_textifeellucky_ [l=am] {áá°ááááµ á­á°ááá!}  
+
+#alt text for query buttons
+_textusequery_ [l=am] {á­á
+á áá á­á
+ á°á áá}  
+_textfreqmsg1_ [l=am] {ášáááµ áá¥á­á€}  
+_textpostprocess_ [l=am] {_If_(_quotedquery_,<br><i>áááááµ ááµá ášá°ááá _quotedquery_</i>
+)}  
+_textinvalidquery_ [l=am] {á°áá£á­ááµ ášááá ášáá á­á
+ áášá}  
+_textstopwordsmsg_ [l=am] {ášáášá°ááµ áááµ ášá°ááá± á áááážá á°áµá°ááá€}  
+_textlucenetoomanyclauses_ [l=am] {áá á­á
+á
+ á á­á«á³ ášááá ááá¶áœá á­ááá€ á¥á£á­á
+ ášá°áá°á áá á­á
+ á áá áá áá­á­á¢}  
+
+_textmorethan_ [l=am] {á­á áá£á}  
+_textapprox_ [l=am] {áµá}  
+_textnodocs_ [l=am] {ááá á­á ášá°áµáá á°ááµ á áá°áááá¢}  
+_text1doc_ [l=am] {1 á°ááµ ášáá á­á áá­ áá¥ááá¢}  
+_textlotsdocs_ [l=am] {á°áá¶á¹ ášáá ášá áá­ á°áµááá°ááá¢}  
+_textmatches_ [l=am] {á°áµáá}  
+_textbeginsearch_ [l=am] {ááá ááá­}  
+_textrunquery_ [l=am] {áá á­áá á á°áªáµ}  
+_textclearform_ [l=am] {á
+á¹á á áœá³}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=am] {áááµ
+}  
+_textinfield_ [l=am] {... á ááµá­}  
+
+
+_textadvquery_ [l=am] {áá­á á áá¥á³ áá á­á
+ á áµáá£}  
+_textallfields_ [l=am] {ááá ááµá®áœ}  
+_texttextonly_ [l=am] {áœáá á¥á»}  
+_textand_ [l=am] {á¥á}  
+_textor_ [l=am] {áá­á}  
+_textandnot_ [l=am] {á¥á á áµá°áá­}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=am] {ááá á _indexselection_ _If_(_jselection_,áš _jselection_ )_If_(_gselection_,á  _gselection_ á°ášá )_If_(_nselection_,á  _nselection_ ááá ) ášááá¶á¹ _querytypeselection_ ášá«á _If_(_sfselection_,\,_allowformbreak_ ášááááá áá€áµ á  _sfselection_ áá°á­á°á­)}  
+
+_textadvancedsearch_ [l=am] {ááá _indexselection_ _If_(_jselection_,áš _jselection_ )_If_(_gselection_,á  _gselection_ á°ášá )_If_(_nselection_,á  _nselection_ááá ) _querytypeselection_ áá á­á
+ á áá áá}  
+
+_textadvancedmgppsearch_ [l=am] {ááá _indexselection_ _If_(_jselection_,áš _jselection_ )_If_(_gselection_,á  _gselection_ á°ášá )_If_(_nselection_,á  _nselection_ááá ) á¥á áá€á±á á  _formquerytypeadvancedselection_ áá°á­á°á­}  
+
+_textadvancedlucenesearch_ [l=am] {ááá _indexselection__If_(_jselection_, áš _jselection_)_If_(_gselection_, á  _gselection_ á°ášá)_If_(_nselection_, á  _nselection_ ááá)_If_(_sfselection_,\,_allowformbreak_ áá€á±á á  _sfselection_\ á°á­á°á­,) á }  
+
+_textformsimplesearch_ [l=am] {ááá _If_(_jselection_, _jselection_)_If_(_gformselection_, á  _gformselection_ á°ášá)_If_(_nselection_, á  _nselection_ ááá)_If_(_sfselection_,\, áá€á±á á  _sfselection_ á á°á­á°á­ \,) áš _formquerytypesimpleselection_ áš }  
+
+_textformadvancedsearchmgpp_ [l=am] {ááá _If_(_jselection_,_jselection_ )_If_(_gformselection_,á  _gformselection_ á°ášá )_If_(_nselection_,á  _nselection_ ááá )á¥á áá€á±á á  _formquerytypeadvancedselection_ á
+á°á á°ášá°á á á³á­ }  
+
+_textformadvancedsearchlucene_ [l=am] {ááá _If_(_jselection_, _jselection_)_If_(_gformselection_,  á  _gformselection_ á°ášá)_If_(_nselection_, á  _nselection_ ááá)_If_(_sfselection_,\, áá€á±á á  _sfselection_ áá°á­áµá­\,) á}  
+
+_textnojsformwarning_ [l=am] {ááµá áááá«á€ á¥ášá°á ááá­ á£áá ášáµášááœ áá ááµá¥ áá« áµá­áªááµ á¥áá³á­á°á« á°á°ááá¢ <br> ášá
+á
+ ášááá ááŽá ááá áá á¥áá²á°á« á áµá­ááá¢}  
+_textdatesearch_ [l=am] {á áá
+ á­ááœáµ ááµá¥ á«á á°áá²áœá á áááµ áá©ááµ (ášáá
+ áá á¥áµášá¥áá
+ áá) áááá á­á»ááá£ áá­á ášá°áá°á áá ášá«á á°ááµá áááá á­á»ááá¢á­á
+ ášááá á°ášááª á£á
+áª ááá¢}  
+_textstartdate_ [l=am] {ášááááªá« (áá­á á¥á») ááá€}  
+_textenddate_ [l=am] {ášáášášá» ááá€}  
+_textbc_ [l=am] {á.á.}  
+_textad_ [l=am] {C.E.}  
+_textexplaineras_ [l=am] {C.E. á¥á B.C.E áš A.D. á¥á B.C.á áá«á®áœ áážáá¢ á¥ááá
+ ááá¶áœ á ášáµááá á£á
+á áá­ áá©ááµ á³á«ášá "Common Era" á¥á "Before the Common Era" áááá ášááá­á áážáá¢}  
+
+_textstemon_ [l=am] {(á ááá
+ ášáášá­á±áµá áááµ á áá°á)}  
+
+_textsearchhistory_ [l=am] {ášáá á­á
+ á³áªá­}  
+
+#text macros for search history
+_textnohistory_ [l=am] {ášááá á³áªá­ ááµá¥ ááá ášáá}  
+_texthresult_ [l=am] {áá€áµ}  
+_texthresults_ [l=am] {áá€á¶áœ}  
+_texthallwords_ [l=am] {ááá áááµ}  
+_texthsomewords_ [l=am] {á¥ááµ áááµ}  
+_texthboolean_ [l=am] {á¡áá«á}  
+_texthranked_ [l=am] {á á°ášá}  
+_texthcaseon_ [l=am] {ášáááµ áá á á ááµ ááá á áá áµ}  
+_texthcaseoff_ [l=am] {á áá³á­ ášá³áá}  
+_texthstemon_ [l=am] {ášá°ášášášá}  
+_texthstemoff_ [l=am] {á«áá°ášášášá}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=am] {áááá¶áœ á¥áá°áášá°áá á°áµá°á«á­áááá¢ ášáµáš ááœ áááá«áá âáááµâ ("back") á áá«á­ á áµá áá -- á áá«á© á«á°ááá¥ášáá áá°áá ášá áµ á­áááµáááá¢ áµáááá á á¥á± ááµá­ ášáá­ á£áá ášááá ášáµá áá­ á«ááµ á áá«á®áœ á áá±á á á
+ á áµá­áá¢ }  
+_textsetprefs_ [l=am] {áá­á« á áµááá¥}  
+_textsearchprefs_ [l=am] {ášááá áá­á«}  
+_textcollectionprefs_ [l=am] {ášá­ááœáµ áá­á«}  
+_textpresentationprefs_ [l=am] {ášá
+á£á« áá­á«}  
+_textpreferences_ [l=am] {áá­á«}  
+_textcasediffs_ [l=am] {ášáá°á áá á áá©ááµ}  
+_textignorecase_ [l=am] {ášáá°á áá­ááµ áá©ááµá á áµááá­áµ}  
+_textmatchcase_ [l=am] {ášáá°á áá­ááµ ášááµ ááá á á áá áµ}  
+_textwordends_ [l=am] {ášáá áášášá»ááœ}  
+_textstem_ [l=am] {ášáá áášášá»ááœá á áµááášáµ}  
+_textnostem_ [l=am] {áá áá ááá ááá³á°á á áá áµ}  
+_textaccentdiffs_ [l=am] {ášáá¬ áá©ááµá€}  
+_textignoreaccents_ [l=am] {ááá áá¬ááœá á áµááášáµ}  
+_textmatchaccents_ [l=am] {ášááá áá¬ááœ ááá³á°á á áá£ážá}  
+
+_textprefop_ [l=am] {á  _hitsperpageoption_ áá€áµ áá á á ááœ ááµá¥ á áµáš _maxdocoption_ á«á
+á áá€áµ á­á°á£áá¢}  
+_textextlink_ [l=am] {ášááª áµáš ááŸáœá ááááµá€}  
+_textintlink_ [l=am] {ááá»á á°ááµ ášá°áá°á°áá€}  
+_textlanguage_ [l=am] {á á­áááœ ááá}  
+_textencoding_ [l=am] {áášá»á€}  
+_textformat_ [l=am] {ášá á­áááœ áá­ááµá€}  
+_textall_ [l=am] {ááá}  
+_textquerymode_ [l=am] {ášáá á­á
+ ááá³á€}  
+_textsimplemode_ [l=am] {ááá ášáá á­á
+ áá­ááµ}  
+_textadvancedmode_ [l=am] {ášáá ášáá á­á
+ ááŽ (!, &, | á¥á á
+áá á áá áá á¡áá«á ááá áááµášá á«áµáœáá)}  
+_textlinkinterm_ [l=am] {ášáážáááªá« ááœ á áá áá}  
+_textlinkdirect_ [l=am] {á áá¥á³ áá° á¥áá
+ ááµ}  
+_textdigitlib_ [l=am] {ášá²áá³á áá­á¥ášáª}  
+_textweb_ [l=am] {ášáµášááœ}  
+_textgraphical_ [l=am] {áµááá}  
+_texttextual_ [l=am] {áœááá}  
+_textcollectionoption_ [l=am] {<p>
+ášáá«á°á± áááµ á­ááœá¶áœá€
+<br>}  
+
+_textsearchtype_ [l=am] {ášáá á­á
+ áá­á€}  
+_textformsearchtype_ [l=am] {_formnumfieldoption_ á áá áá ášá°áášá¹ ááµá®áœ}  
+_textplainsearchtype_ [l=am] {á  _boxsizeoption_ ášáá á­á
+ ááœ ášá°ááá° áá}  
+_textregularbox_ [l=am] {áá á ááµáá­}  
+_textlargebox_ [l=am] {áµáá
+}  
+
+_textrelateddocdisplay_ [l=am] {á°ááá
+ á°áá¶áœá á á³á­}  
+_textsearchhistory_ [l=am] {ášááá á³áªá­á€}  
+_textnohistory_ [l=am] {ášááá á³áªá­ ášáá}  
+_texthistorydisplay_ [l=am] {_historynumrecords_ ášááá á³áªá­ ááááŠáœá á á³á­ }  
+_textnohistorydisplay_ [l=am] {ášááá á³áªá­ á á³á³á­}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=am] {á°áá¶áœá ááá°á­á°á­ ášá°á ááá}  
+_textalsoshowing_ [l=am] {á á°ášááª ášáá«á³ášá}  
+_textwith_ [l=am] {á¢á á}  
+_textdocsperpage_ [l=am] {ášá°ááµ á¥ááµ á ááœ}  
+
+_textfilterby_ [l=am] {ášáá³ááá á°áá¶áœ ášá«ááµ}  
+_textall_ [l=am] {ááá}  
+_textany_ [l=am] {ááááá}  
+_textwords_ [l=am] {á«ááµ ááá¶áœ}  
+_textleaveblank_ [l=am] {áááá á°áá¶áœ áááááµ á­á
+áá á³á¥á á£á¶ á¥áá²áá áá°á}  
+
+_browsebuttontext_ [l=am] {âá°áá¶áœá á á
+á°á á°ášá°á á°á­áµá­â}  
+
+_nodata_ [l=am] {<i>á³á³ ášáá</i>}  
+_docs_ [l=am] {á°áá¶áœ}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=am] {á¥áá}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=am] {á°áá¶áœá á  _1_ ááá°áµ áš _2_ á áá«á­á á á
+ á ááµášá}  
+
+_textSearchhelp_ [l=am] {áš _labelSearch_ á áá«á­á á áá áá á áœáá ááµá¥ ášááá ášá°áá°á ááá¶áœá ááá}  
+_textTohelp_ [l=am] {áš _labelTo_  á áá«á­á á áá áá á°áá¶áœá á  áá° (To) ááµá­ ááá}  
+_textFromhelp_ [l=am] {á
+áµáá¶áœá á  áš(From) ááµá­ ááá°áµ _labelFrom_ á áá«á­á á á
+ ááµášá}  
+_textBrowsehelp_ [l=am] {á°áá¶áœá á áµáµ}  
+_textAcronymhelp_ [l=am] {áš _labelAcronym_ á áá«á­á á á
+ á ááµášá á°áá¶áœá á ááá»áš áá á­áá³ážá á áá áá á áµáµ}  
+_textPhrasehelp_ [l=am] {áš _labelPhrase_ á áá«á­á á áá áá á á°áá¶áœ ááµá¥ ášá°ášá°á± áášááœá á áµáµá¢ á­á
+ ášáááµ (phind) áášá áááá á­á áááá¢}  
+
+_texthelptopicstitle_ [l=am] {á­áá° áá³á­}  
+
+_textreadingdocs_ [l=am] {á°áá¶áœá á¥ááŽáµ ááá á¥ á­á»áá}  
+
+_texthelpreadingdocs_ [l=am] {<p>á ááµ áá
+áá áá­ áá­á á°ááµ áá­ ááµášáµá
+á ááá
+ áµáœááá
+á£ áá­áá«á±á á á­áá±á£ áá­á ášááµ áá
+ áœáá ááµá á áá ášá«áµá á áµá°áá« á á©á áµááá³á­á¢ á á áá³ááµ á­ááœá¶áœ á­á
+ ášááá« áá­ á á¥á® á­áááá£ á áááœ á°áá ášáá
+ áá¥á©á  ášá³á¥á áá­  á áá«á á á²áµ áá
+ ááµáášá¥ á¥á áá° ááµ áá° áá áááµá á«áµáœááá¢ á ááá«á áá­ á£ á áá á«áá
+á áµ á­áá á­ááµ áá á¥á á­á³á«áá£ á¥á áá°á á­áœáá -  á áááá¹á á á
+ á ááµášá áá­ááµá ááááµ á­á»ááá¢ áááááµ ášáá­ ášá°áášááá áá
+áááµ á á
+ ááµášá ááá¢</p>
+
+<p>ášáµá­ ášáá³ášá á áá á«áá
+á áµ á­áá á
+áá ááá¢ á¥á«áá á¥á
+ áµáµááµá£ ášá³áœ áá° ááá¥áá á­áá ášáááµáµ áá­á áá° áá ášááááµ ááµáµ á­áááá¢</p>
+
+<p>ášá­áá± áá­á ášááµ áá
+ ááµá á á³áœ á áá«á®áœ á áá¢ á áá á«áá
+á áµá á­áá á
+áááá­á áá
+áá á¥áá³á áááµááµ
+<i>_document:textEXPANDTEXT_</i> áá­ á á
+á¢ á°áá± áµáá
+ ášááá£ áµááœ áá áááµáµ á­áœáá á¥á ášá®áááá°á©á áááª á á£á á­ááµá³á! ášá°áá±á ááá« á¥áá³á áááµááµ <i>_document:textEXPANDCONTENTS_</i> áá­ á á
+ á áµá­á á¥áá ášá­áá±á á á
+áá á­áááœ á¥á á áµá© á«ááµá áá áášáµ á«áµáœááá¢ ááá á°ááµ á á²áµ ášáááá« ááµá®áµ ááá­ááµ <i>_document:textDETACH_</i> áá­ á á
+ á áµá­áá¢ (á­á
+ áááµ á°áá¶áœá áááá³ášá­ áá­á áááá á¥ á­á á
+ááá¢) á áášášá»áá£ ááá áµá³á«ááµ ááá á«á°ášá­á£ážá áááµ á°ááá á­á³á«áá¢ áµááá±á ááá¥ááµ <i>_document:textNOHIGHLIGHT_</i> á á
+ á áµá­áá¢</p
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=am] {á­á
+á áá°á­á°áªá« á­ááµ}  
+_texthelpopenbook_ [l=am] {á­á
+á áá
+áá á­ááµ/áá}  
+_texthelpviewtextsection_ [l=am] {ášáœááá á­áááá á­áá á°ááášáµ}  
+_texthelpexpandtext_ [l=am] {áááá áœáá áá³á­á°á£ áá­á á¥áá³á áá°á}  
+_texthelpexpandcontents_ [l=am] {ááá«áá ááá­ááµ áá­á á¥áá³á áá°á}  
+_texthelpdetachpage_ [l=am] {á­áá ááœ á á á²áµ ááµá®áµ á­ááµ}  
+
+_texthelpsectionarrows_ [l=am] {áá° á ááá/ášááá¥áá á­áá ááµ}  
+
+
+_texthelpsearchingtitle_ [l=am] {ášá°áá°á áááµá á¥ááŽáµ áááá á­á»áá}  
+
+_texthelpsearching_ [l=am] {<p>
+  ášááááá« áá áá­á£ á¥ááµá áá á­á
+ á ááá ááááááµá€ <p>
+
+  <ol><li>ááµááá  á«á°á¥ášáá áá­á°á
+ á áá£
+      <li>á¥áá áá á á á ááá­ áááá áááµ áá áá­áµ ášá°áá°ááµá áááµ á¥á» áá ášááµáááá 
+      <li>ááá¶á¹á á ááááá« áŠá³á áá­ ááážá 
+      <li>áá¥áá <i>ááá ááá­</i> ášáááá á áá«á­ á á
+ á áµá­á
+  </ol>
+
+<p>áá á­á
+ á áá³á°á­áá áµ ááá£ ášáá á­á áá­ ášáááá±  áš áá« á°áá¶áœ á­ááµ á­áá£áá¢ áášášá»á áá­ áá° ááá¥áá áá« á°áá¶áœ ášáááµáµ á áá«á­ á áá¢ ášáá áá° áŠáµá°áá áá«áá¹ á°áá¶áœ áá­á áá° ááááªá« áá«áá¹ ášáááµá± á áá«á®áœ á­áá«áá£ á¥á«á á­áá¥ááá¢ ááášáµ ášá áá±á á°ááµ á­ááµ á á
+ á áµá­áá£ áá­á ášáá á«ááœáá áµááœá¬ á áá«á­ á°á ááá¢
+
+<p>á¢á á  á¥á°áš 100 á«á
+á á°ááµ á¢áá£ ááá¢ á­á
+á áá¥á­ á áá á ááµ áá­ á«ááá
+  <i>_Global:linktextPREFERENCES_</i> á áá«á­ á á
+ á ááµášá ááášá­ á­á»ááá¢<p>
+}  
+
+_texthelpquerytermstitle_ [l=am] {ášááááá« áááµ}  
+_texthelpqueryterms_ [l=am] {<p>á áá á­á
+ á³á¥á ááµá¥ ášá°á°ášá á áá  á¥ááµ á áá­áá­ ášá°ááá  ááá¶áœ áá­á áášááœ  á°ááµá°á âášááááá« ááâ á°á¥áá á­á á«áá¢ ášááááá« áá áá°áá  áá¥á­ ášá«á áá á áá áá­á á áµáá
+ášá° á¥á
+áµ ("...") ááµáµ ášá°á°ášá°á© ááá¶áœá ášá«á ááá¢ áááµ á áá«ášáážá á£á á£á¶ áŠá³ á áá«áááµ á­áá£á ááá¢ áááœ ááá­á¶áœ ááá³á ášáá ááá­á¶áœ á²áá á°áá£á«ážá áá­ á¥áá° á£á¶ áŠá³ ááá¶áœ ááá£á á á­áááá¢ áµáááá ášááá
+ ááá­á¶áœ ášáááµ áá«ášá á²áá á¥áá°áá á­áá á«áá¢  á áá
+á áá­áá«áµ ášá°áá°á ášáá ááá­á¶áœá ášá«á ááá¶áœá áá­á¶ áááá á á­áœááá¢ 
+
+<p>ááá³áá£ ášáášá°áá áá á­á
+<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>ášáášá°áá áá­ á°áá³á³á­ á°á°á­á á­áá°á³á<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}  
+
+_texthelpmgppsearching_ [l=am] {á  á€áááá (MGPP) áá°ááá£ á­ááœáµ á°ášááª á áá«á®áœ á áá¢ 
+
+<ul>
+<li>á áá á­á
+ áášášá» áá­ áš<b>*</b> ááá­áµá ááµášá áá<b>ášáááá­á£ážá</b> áá­ á áá á­ááá³áá£ ááá³á <b>comput*</b> ášááá á  <b>comput</b> ášáááá© áááµ áá­ á áá ášááá³áá¢
+<li><b>/x</b> ášááá á°áá áá ááµ áá­á ášáá« á áá­ ááá ášáá á­á
+ áááµ á­á¥á°áµ á­á°á£áá£ ááá³á <b>computer/10 science</b> ášááá áš science á­áá
+ computer áááá áá 10 á¥á¥á á­á¥á°áµ á­á°á£á - á°áá¶áœá á á°ášá á áá«áµááá¥á áµ ááá¢
+</ul>
+}  
+
+_texthelplucenesearching_ [l=am] {á  áá°á (Lucene) áá°ááá£ á­ááœáµ á°ášááª á áá«á®áœ á áá¢ 
+
+<ul>
+<li><b>?</b> á¥áá° á¥á«á ááá­ áá°á ášááá ááá³ ááááá áá°á áá­á á«áááááá¢ ááá³á <b>b?t</b> ášááá áš <b>bet</b>, áš <b>bit</b> á¥á áš <b>bat</b> ááá° áááµ áá­ á áá á­ááá³áá¢
+<li><b>*</b> á¥áá° á ááµ áá°á ášááá ááá³ á¥áá° á¥á áá°ááµ áá á«áááááá¢ ááá³á <b>comput*</b> ášááá á  <b>comput</b> ášáááá© áááµ áá­ á áá á­ááá³áá¢
+</ul>}  
+
+_texthelpquerytypetitle_ [l=am] {ášáá á­á
+ á á­ááµ}  
+_texthelpquerytype_ [l=am] {<p>áááµ áá­ááµ ášá°áá«áª áá á­ááœ á áá¢
+
+<ul>
+  <li>áš <b>áááá</b> áááµá ášá«á áá á­á
+.  á­á
+ áá á­á
+ ášá°á°á áá áááµ á áá ášá«á á°ááµ (á­áá áá­á á­ááµ) á­ááááá¢áá á­áá ášáá«áá á°áá¶áœ á á°áá á©á áµ á
+á°á á°ášá°á á°á°á­áµášá á­á³á«áá¢ 
+<p>
+
+  <li>áš <b>á°áá°á</b> áááµá ášá«á áá á­á
+á¢  á ááááá á°ááµ ááµá¥ á­ááá á°á¥á ášáááá± ááá¶áœá ááá­áá­á€ ášá°áášáá©áµ ááá¶áœ áá­ á£áážá á°áá³á³á­ááµ áá á ááá á­á á°áááœ ášáá á°áá¶áœ á á
+á°á á°ášá°á áá¥á°á á­á°ášá°á«áá¢ áá á«á
+á á°áááœ ááá°áá áááá
+á£
+
+      <p><ul>
+        <li> á°ááµ ášááááá« áá áá­ á°áá³á³á­ ášáá ááá¶áœ á á¥ááµ ášá«áá á°ááµ ášá áá  á°ááá
+ á­áááá€
+        <li> ášáá°á á áááµ á­áá
+ á á­ááœá± ááµáµ á á¥ááµ ášáá­áá  áááµ ášá áá  á áá áážáá€ 
+        <li> á á«á­á­ á°áá¶áœ ášáµááá
+ á°áá¶áœ ášá áá  á°ááá
+ á­áááá¢
+      </ul>
+</ul>
+
+<p>ášá°ááááá á«á
+á ášááááá« áá áá áá á­á»áá -- áá á.ááá­ áá­á á ááµ á áááœ ááá á­áœááá¢ á ááµ áá á¥á» á¥á
+á áá­ ášáá á°áá¶á¹ áá á ááµá£ážá á á°á°áááá áá á á
+á°á á°ášá°á á­á° á­á°á£ážááá¢<p>
+}  
+
+_texthelpadvancedsearchtitle_ [l=am] {áš  _1_ ášááá áá­ááá á áá áá ášáá ááá áá«ááµ}  
+
+_texthelpadvancedsearch_ [l=am] {<p>ášáá áá á­á
+ ááá³á ášáášá¥á­ (á ááááµ) áµááœ áášáµ á«á ášááááá« ááááµ á­áá­ááá¢ _selectadvancedsearch_
+}  
+
+_texthelpadvsearchmg_ [l=am] {á á€áá (MG) á­ááœáµ áá­ ášáá°ášá ášáá ááá ášá°ášá á¥á ášáŠáá«á ášá°á£á á áá«á®áœá á­á°á£áá¢
+áš <b>á°ášá</b> ááá á  <a href="\#query-type">_texthelpquerytypetitle_</a> ášá°ááášá°á <b>á¥ááµ</b> ááá áá­ á°áá³á³á­ ááá¢
+<p>_texthelpbooleansearch_
+}  
+
+_texthelpbooleansearch_ [l=am] {áš <b>á¡áá«á</b> ááá ááŽ   & (á "and")á£ | (á "or")á£ á¥á ! (á "not")á£ áášáá ááá­á¶áœá á áá áá ááá¶áœá áá£áá­á á¥áá²áá á¡áµá áááá á­ á
+áá áá ááá á­áá
+á³áá¢
+<p>
+ááá³áá£ <b>snail & farming</b> ášááá áá á­á
+ <b>snail</b> AND <b>farming</b>á£ ášáááµá áááµ á á ááµááµ ášá«á á°áá¶áœá á­ááááá¢ á áá á á©á <b>snail | farming</b> ášáá áá á­á
+ ášáá <b>snail</b> áá­á <b>farming</b> ášáááµ ááá¶áœ á áá±á ášá«á á°áá¶áœ á­ááááá¢
+<b>snail !farming</b> ášáá áá á­á
+ ášáá <b>snail</b> ášáááá ášá«á ááá­ áá <b>farming</b> ášáááá  á«áá«á°á± á°áá¶áœá á­ááááá¢
+<p>
+ášá áá  áá­á°á ášáá«áá¡ áá á­ááœ ášááá¹á á áááááá á
+áá á áá áá áááµášáµ á­á»ááá¢ ááá³áá£ <b>(sheep | cattle) & (farm | station)</b>á£ áá­á <b>sheep | cattle | goat !pig</b>á¢
+
+}  
+
+_texthelpadvsearchmgpp_ [l=am] {á  á€áááá (MGPP) á­ááœáµ ášášáá ááá á¡áá«á ášáááœá á­á áááá¢ _texthelpbooleansearch_
+<p>áá€á±á <b>á á°ášá</b> á
+á°á á°ášá°á á­ááá£áá£ á <b>á°áá°á</b> ááá á¥áá°á°á áá°á á  <a href="\#query-type">_texthelpquerytypetitle_</a>á£ ááµá¥ áá­á á  "natural" (áá­á "build") á
+á°á á°ášá°á ááááá¢ á­á
+ á
+á°á á°ášá°á á°áá¶á¹ á­ááœá± á²áá á­ á áá ášá áá°áµ á
+á°á á°ášáµá ááá¢ 
+<p>
+á°ášááª ášáááœ <b>NEARx</b> á¥á <b>WITHINx</b> áážáá¢
+NEARx ášááá ášáá  ášáááµ áá á­á
+ áááµá ášá°ááµ áá­ ááááá³ážá á ááášáážá á«ááá ášáá°á á­ááµ ášáááµá ááá¢ WITHINx ášááá á°áá ášáááµáá ááá°áá á°á­á (term) ášááááªá«á á°á­á (term) á ááá á á á°áá°á áááµ ááµá¥ ášáášá°áµá áµ ááá¢ á­á
+ áš NEAR áá­ á°áá³á³á­ áá ááá­ áá á
+á°á á°ášá°á á áµááá ááá¢ á
+áµá áá¥ á­áá± 20 ááá¢
+}  
+
+_texthelpadvancedsearchextra_ [l=am] {ááµá³áá»á€ ááá ášáá³á«áá°á á ááá áá á­á
+ ááá³á á áá áá ášáá á¥ááá
+á ášáááœ á áá áµá« áá­ á á­áááá¢}  
+
+_texthelpadvsearchlucene_ [l=am] {á áá°á á­ááœá¶áœ ášáá ááá ááá«ááµ ášá¡áá«á ášáááœá á°á ááá¢ _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=am] {á ááµá­ ášá°áá°á ááá}  
+
+_texthelpformsearch_ [l=am] {<p>á ááµá­ ášá°ášááá ááá áááááœá á ááµá®áœ á áá£áá­ ááááá ášáá«áµáœá ááµá á­áá¥á«áá¢ ááá³áá£ "Smith" ášáááá ášá­ááµ ááµá­ AND "snail farming" ášáááá ášá­áá° ááµá­ á á£áá® áááá á­á»ááá¢ á ááá ášáá á­á
+ ááŽ á á
+á áá­ á«ááµ ááµáá®áœ á ášáááœá áá°á á ášáá á ááµáá­ ááá á á«ááµ á£á
+áªá ášá«á áážáá¢ á ášá«á³ážá ášá°ááá¡áµ ášá
+áœ áá á ááµáá®áœ ANDá (á "all" ááá) áá­á ORá (á "some" ááá) á áá áá áá£áá© á­áœááá¢ á á¥á«áá³áá± ááµá­ ááµá¥ ášááá¡ ááá¶áœá á á°áá³á³á­ ááá©áá£áá© á­áœááá¢ á ááá
+ áá á­á
+ ááŽ ášáá°á³áœ á°ášááœ áá­áá­á á°á á
+á AND/OR/NOT á ááµá®á¹ áá«ášá á á°áá«áš ááááµ á áá£áá­ á¥áá²áá á ááµá®á¹ ááµá£á ášá¡áá«á ášáááœ áá áá á­á»ááá¢}  
+
+_texthelpformstemming_ [l=am] {á  "fold" á¥á á  "stem" á³á¥ááœ á ááµá­ ááµá¥ á«á ááá¶áœ á áá­ááµ ášá³á á© áá­á ášá°á®ášá®á áááážáá ááááá
+ á­ášá³áá¢ á ááá±á á³á¥ááœ ááá ášá
+á
+ ááá á á
+áµá áá¥á¥áá³á­á°á© ááááá¢}  
+
+_textdatesearch_ [l=am] {á áááµ áááá}  
+
+_texthelpdatesearch_ [l=am] {ášáá ááá ášáááá
+ áááµ áá­ ášááá£á á á°áá¶áœ á£á»áá­ á á°áá°á ášáá áááá ááµá¥ á«á á­áµá°á¶áœá ášá«á á°áá¶áœá ááááá á«áµáœááá¢ á á°áá°á áááµ áá­á ááá³áµ áá«ášá á«á á°áá¶áœá áááá á­áœááá¢ á¥áá
+ áá­ áá°á®á­á áµ ášááá£á á áá
+ ášááá ááŽ ášááµ ášááá áá ááµáá£áµ á á«áµáááá --  ááá á¥á» á ááµáá£áµ áááá á­á»ááá¢ á á°ášááªá á áááá áááœá ášááµ ááµáá£áµ á á«áµááááá£ ááá ááá áá­ááµ áá á«ááá£ áááá ášáá ááá  á³á­á«ááµ ášáá°ášáá áášá áá­ á ááµ á á­ááµ á­áááá¢<p>}  
+
+_texthelpdatehowtotitle_ [l=am] {á­á
+á ááœá³ á¥ááŽáµ áá ááá€}  
+_texthelpdatehowto_ [l=am] {<ul>
+   <li>á á ááµ á á°áá°á áááµ á«á á°áá¶áœá áááááá€<p>
+   <ul>
+       <li>ááá á¥áá°áá³á°á­áá ášááá ááá á áµáá£á¢
+       <li>ášááµááááá áááµ "ášááááªá« (áá­á á¥á») áá" á ááá á³á¥á ááµáµ á áµáá£á¢
+       <li>á«áµáá£ážá áá ášá­á­áµá¶áµ áá°áµ á ááµ ášáá "á.á." ("B.C.E") ášáááá á áá«á­ ááá á«áµáá£á á
+á áµ á³á¥á á á³áœ á«áá á°áá³áœ ááá­áá­ ááµá¥ áášáµá¢ 
+       <li>ášáá
+ á ááµ á áá°á á ááá áá
+áµ á¥áá°áá³á°á­áá ááááá ááá­á¢
+   </ul>
+<p><li>ášá°áá°á ááá ášáážáá áá­á á ááá³áµ áá«ášá á«á á°áá¶áœá áááááá€<p>
+   <ul>
+       <li>>ááá á¥áá°áá³á°á­áá ášááá ááá á áµáá£á¢
+       <li>ášáá°ááá áá "ášááááªá« (áá­á á¥á») áá" á ááá á³á¥á ááµá¥ á áµáá£á¢
+       <li>áá áá ášááá­á áá áá "ášáášášá» áá" á ááá á£á¥á ááµá¥ á áµáá£á¢.
+       <li>ášá­á­áµá¶áµ áá°áµ á ááµ ááá ááá«á¶áœ"á.á." ("B.C.E") ášáááá á áá«á­ áá á«áµáá£á
+á áµ á³á¥á áá¥á á«áá ášáá°á³áœ á°áá³áœ ááá­áá­ ááµá¥ áášá¥á¢ 
+       <li>ášáá
+ á ááµ á áá°á á ááá áá
+áµ á¥áá°áá³á°á­áá ááááá ááá­á¢
+   </ul>    
+</ul><p>
+}  
+
+_texthelpdateresultstitle_ [l=am] {ášáááá
+ áá€á¶áœ ášáá°á©á áµ ááááµ}  
+_texthelpdateresults_ [l=am] {á á á ááá­ á áááá­ áµá 1903 ášáááá­ á°ááµ áááá ášáá°á á áµá 1903 ášá°á»á á°áá¶áœá á¥áá á  1903 ášá°á»á áá£áá» ááœááá¶áœá á á­á°ááá¢ ááá ášá°áá¶áœ áá ášá°ááá á áµá ááááµ á°ášáµá 1903á  ášáá® ášá°áá°á áá ášáážáá á°áá¶áœá (ááá³á áš 1899-1911) á­á°á£áá€ ášáá
+á á áá­ ášáœáá áµáážá 1903  ášáá«á°áµá áµ ášááá áµ á­áá ááá ášá«á (ááá³á 20áá á­áá áááá£ 20áá á­áá ááá) á°áá¶áœá á­á°á£áá¢ á­á
+ ášáá«á³ášá ášá áá³ááµ á°áá¶áœ áááá á¥á
+á áá­ ášááá ášáá áá¥á­ á°áá¶á¹ á á«ááµ áœáá ááµá¥ á°á«á¶ ášááá ááá ááá¢<p>}  
+
+_textchangeprefs_ [l=am] {áá­á«á
+á ááášá­}  
+
+_texthelppreferences_ [l=am] {<p>ášáá á ááµ áá­ <i>_Global:linktextPREFERENCES_</i> ášáááá á áá«á­ á á
+ áµá³á°á­á ášá á­áááá 
+á áá³ááµ á£á
+áªá«áµ áá«áµá
+ á áá«ááœ ááá© ááášá­ áµáœááá
+á¢
+}  
+
+_texthelpcollectionprefstitle_ [l=am] {ášá­ááœáµ áá­á«}  
+_texthelpcollectionprefs_ [l=am] {<p>á áá³ááµ á­ááœá¶áœ á ááµá£ážá ášá°áá«á© áááµ á­ááœá¶áœá áá­á á­áœááá¢
+á¥ááá
+ áááµ á­ááœá¶áœ á á°áá¥á áá­á á¥áá° á ááµ á­ááœáµ ááá áá«ááµá£ážá á­áœááá¢
+á áááá á ááá áá
+áµ áááá ášáá«á«áµá³ážá áááµ á­ááœá¶áœ áááášá¥ ášáá­á« ááá áá áá á­á»ááá¢
+}  
+
+_texthelplanguageprefstitle_ [l=am] {ášááá áá­á«}  
+_texthelplanguageprefs_ [l=am] {<p>á¥á«áá³áá± á­ááœáµ á
+áµá áá¥ ášá áá«ášá¥ ááá á ááá£ ááá­ áá áá° áá ááá ááášá­ á­á»ááá¢ á á°ášááª ááªááµá¶á ááááá« áá€áµ á²á«áµá°ááá ášáá ááá áµá ášá¢áá®á²áá áµá¬áá ááášá­ á­á»áá --á¶áá°áá© ášááµáááá á
+áµá áá¥ á­áá­á£áá£ ááá­ áá á á áá³ááµ áááá«ááœ ášá°ááááá á¢áá®á²áá áµá¬á á ááášá­ áá°áá¹á ááášáµ ááµá°á«á­á áá«áµááá á­áœááá¢ ááá á­ááœá¶áœ áš áµá³áá³á­áµ áá«áá«á á á­ááá
+ áá° á
+ááá áá°ááá áááášá­ á«áµáœááá¢ á­á
+ ášáášáµ á¥á­á ááá£áœá á°á ááááœ á ááá°á á¥áá²á«áá¡ áá­á áá° áááá­ á ááá­á­ áá³áªá« á¥áá²á«á³áá¡ á­ášá³ážááá¢}  
+
+_texthelppresentationprefstitle_ [l=am] {ášá áá«ášá¥ áá­á«}  
+_texthelppresentationprefs_ [l=am] {á¥áá° á­ááœá± ááá³á£ ášá°áá±á á áá«ášá¡ áááá£á á­ á¥á á áá«á®áœ ááá© á­áœááá¢ 
+
+<p>ášáµáš áá
+ á­ááœá¶áœ á ášáá á ááµ áá­ á«ááá ášááªááµá¶áá á á³áœ á áá á¥áá³á­áá­ ášá°á­ááááá£ á¥áá á ááŽ ááá á«á«ááµá
+ á áá ášáááá°á áµá­á­áá áµášáá
+ áá­ á«á ááªááµá¶á á«áµá á³á­ááá
+á¢  á°ášááª ááá ááášááá áááá«á
+á á áá áá áá° áá á°áááµ. á¥ááá
+ á­ááœá¶áœ ášá­ááœá± áµá
+á³á áá­á¥ášáª á¥ááµáµáá£ ášáá«á°á­ááá á á«á«á¥ á á
+ áµá³á°á­á ášááá£áá   ášááªááµá¶áá ášááµá áááá« áááá­áµ á¥áá³á­áá­ á¥ááµá³á°á­á á«áµáœáááá¢ á¥áá á á áá³ááµ ášáµášáá
+ á­ááœá¶áœ á  "ááá áá€áµ" áá
+ áá­ á«áá á á«á«á¥ á áá¥á³ áá° á«á± á©á á­á€á á­ááµ á á­ááµ ááá£á á­  á­á»ááá¢ 
+}  
+
+_texthelpsearchprefstitle_ [l=am] {ášááá áá­á«}  
+_texthelpsearchprefs_ [l=am] {<p>áá° "ášáá" ášáá á­á
+ ááá³ á ááášá­ ááá¶áœá á  & (á "and"), | (á "or"), á¥á ! (á "not") á áá«á«á áá áá á²á»áá£ á á¡áµá ááá áááµ ášá
+áá ááá­áµá  á«áµááá áá áá á­á»ááá¢ á­á
+ ášá°á»á áá á­ááœá ááášááá á­ášá³áá¢ <p>_selectsearchtypeprefs_
+<p>_selectwordmodificationprefs_
+<p>ášááá á³áªá­á áá ááá£ ášáášášá»áá¹á áá á­ááœ áášáµ á«áµáœááá¢ á­á
+ á°áá á¥ááá
+ áá á­ááœ á ááá á áá»á»á á¥áá°áá ááá áá á«áµáœááá¢
+<p>á áášášá»áá£ášááá áá€áµá
+á á¥á á á¥á«áá³áá± áá á°á­áªá áá­ ášáá³ášáá áá¥á­ áááá£á á­ á«áµáœááá¢ 
+}  
+
+_textcasefoldprefs_ [l=am] {á¥ááµ á áá«á®áœ á ááá áá
+áµ á«áá³áá á ááµá°á áá°ááµ ááááµ á ááááá³ážáá á­áá£á á«áá¢ ááá³áá€ "_preferences:textignorecase_" ášá°áášá á£ <i>snail farming</i> ášááá áá áá­ á¥áá° <i>Snail Farming</i> á¥á <i>SNAIL FARMING</i> á­áá°á³áá¢}  
+_textstemprefs_ [l=am] {á¥ááµ á áá«á®áœ ášáááµ áášášá»ááœá á ááá áá
+áµ ááá áá  áá­á á«ááá áá ááá³ááœá á­áá£á á«áá¢ ááá³áá£ "_preferences:textstem_" ášá°áášá á£ <i>snail farming</i> ášááá áš <i>snails farm</i> á¥á áš <i>snail farmer</i> áá­ á á ááµ á á­ááµ á­á³á«áá¢ á­á
+ á£áá áá á áµá­ášá ášáá°á«á á á¥ááááá ááá áá°á»á áœáá ááá¢ _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=am] {á¥ááµ á áá«á®áœ á ááá ááµá¥ ášáá£á¥ ááá­áµ á«áážáá ášááážá á°áá³á³á­ ááá«áµ á á°áá³á³á­ááµ ááááµ á ááááá³ážáá á­áá£á á«áá¢
+ááá³áá€ "_preferences:textignoreaccents_" ášá°áášá á£ <i>fÃ©dÃ©ration</i> ášááá áá áá­ á¥áá° <i>fedÃ©ration</i> á¥á <i>federation</i> á­áá°á³áá¢
+}  
+ 
+_textstemoptionsprefs_ [l=am] {ášáá­ á  "_texthelpquerytermstitle_" ášááááá« áá³á áªá« áá³áªá« áá áá ášá áá  á ááºá áá¥á°á ááá á­áœááá¢}  
+
+_textsearchtypeprefsplain_ [l=am] {ášá áááœ ášááµá°á«ášá ááá ááá«ááµ ášáá«áµáœá ášáá á­á
+ á³á¥á ááááµ ášá»ááá¢ áµáá
+ áá á á«ááá áœáá ááááá áá¥áá± ášááá­á ááá¢}  
+
+_textsearchtypeprefsform_ [l=am] {á ááááá« á
+á¹ áá­ ášáá³á©áµá ááµá®áœ ááášá­ á­á»ááá¢}  
+
+_textsearchtypeprefsboth_ [l=am] {ášá­ááœá±á á ááá á á­ááµ á  âáá°á áâ á¥á á  âááµá­ áá° á°ášáááâ ášááá á á­áá¶áœ áá«ášá áááá­ á­á»ááá¢ 
+<ul>
+<li>áá°á á ááá áá á ášáá á­á
+ á£á¥á á­á°á£áá¢ _textsearchtypeprefsplain_</li>
+<li>á ááµá­ ášá°ášááá ááá ášá¢ááŽá­á±á ášá°áá«á© á­áá áá­ ááá ášáá«ášááá á á­á«á³ ášáá á­á
+ á£á¥ááœ á­á°á£áá¢ á­á
+á á á°áá© ááµá®áœ áá­ á á ááµ áá ááá áááµášá á­ášá³á _textsearchtypeprefsform_ </li>
+</ul>
+}  
+
+
+
+_texttanumbrowseoptions_ [l=am] {á áá
+ á­ááœáµ áášáááœá ááááá _numbrowseoptions_ áááá¶áœ á áá€}  
+
+_textsimplehelpheading_ [l=am] {á  _collectionname_ á­ááœáµ ááµá¥ áášáá á¥ááŽáµ áááá á¥áá°áá»á}  
+
+_texthelpscopetitle_ [l=am] {ášáá á­á áá°á á³á­}  
+_texthelpscope_ [l=am] {<p>
+á á¥ááá¹ á­ááœá¶áœ ááá ášáá³ášáááá£ážáá á¢ááŽá­á¶áœ á¥ááµá³áá­á¥ á«á°ášáááá¢ ááá³áá£ ášá°á«á²á ášá­ááµ á¢ááŽá­á¶áœ áá³áá­áµ áµáœááá
+á¢ áá­á ášá­ááá á¥á ášá áááœ á¢ááŽá­á¶áœá ááá© á­áœááá¢ á á á ááá­ ášáµáááá á¢ááŽá­áµ á¥áµá áá ááááá«áá ášáá«áá á°áá¶áœ á³áááá
+á¢ 
+<p>á°áá¶á¹ ááœáá ášááá£ á¥áá± á°áµáá á áá áŠá³ á­ášáá³áá¢ 
+}  
Index: /gsdl/stable/macros/amharic2.dm
===================================================================
--- /gsdl/stable/macros/amharic2.dm	(revision 20131)
+++ /gsdl/stable/macros/amharic2.dm	(revision 20131)
@@ -0,0 +1,1204 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Amharic Language text and icon macros 
+# -- this file contains text that is of less importance
+# 
+# Translated by Yohannes Mulugeta and Abiyot Bayou
+#
+######################################################################
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=am] {á°áá¶áœá¢}  
+_lastupdate_ [l=am] {áášášá» ášá°á»á»áá áµ}  
+_ago_ [l=am] {áááµ á ááµá¢}  
+_colnotbuilt_ [l=am] {á­ááœáµ á áá°ááá£á}  
+
+### taken from here
+
+_textpoem_ [l=am] {<p>áªá« áá« á² ááªáá£
+<br>áªá« áŽá« á² á«á®áá®áá£
+<br>áªá« ááááá á² áá
+
+<p>á°ááá áá¥á³ á á á«á£á¢á
+ á­áµááá£
+<br>áá®á
+ á áá á á áá á­ááá£
+<br>ášáá
+á«ááµ ááá
+ á¥áá° á ááá£á«á ááªááµá¶á ášáá°áá° á­ááá¢ 
+}  
+
+_textgreenstone_ [l=am] {<p>ááªááµá¶á á áá ááááµ ášááá á ášáá ášášá áš á²ááá­ (áá­ á¥áá°áá
+ á¶ááµáá­)   ááá¢ á ááª á£á
+áá áá
+á ášá°á¥  áááµ á á£á ášá°ášá ášá ášáááµáá¶áœ áá áá ášáááá ááá¢ <i>áá­á©á</i> /ášáášá á­á . <i>áá­á©á</i> ášá°á£á áá­á á«áá ááááµ á ááµá¡ á áá á­á­áá á°á¥á áµááá³áá áµááá á­á
+á á£ááá á¥áŽáµ á
+áá¥ ášáá ááá áµ ášá²áá³á áá­á¥ášáª áá®áá­áµ áááµá³ááµ ášá°áášá° ááá¢ á­á
+á áááµááá£á°á
+áááµáá£ á³ááááµáá£ á¥áá«á¬áá£ áá­á áááµááá£ áµáá³á á á­á ááµá
+á á«ááá­á³áá¢á ááªááµá¶á á²áá³á áá­á¥ášáª á á­á áá­ ášáá³ášá á«á <i>áá±</i> áá­á á
+á¥ášáµáá ášáá
+ áá®áá­áµ á á£á ášáá ášá ááµ á€á°á°á¥ áá­áµ ááá¢ á¥á
+ áá¥á
+ á áá«á«á á áá¥ááµá£ á«ááµá
+á°áµáá£ á á£á á á°áá ááá© ááµášáµ á­á»ááá¢ á¥áá á­á
+ á¥á á¥ á á á¶ááµáá­ áá­ á¥áá²á°á« á¥ááááááá£ áš <i>áá±</i>  á°áá³áá á«á ášáŽá­áááá á«áá á«ááá­á³áá¢ </p>}  
+
+_textaboutgreenstone_ [l=am] {<p>ááªááµá¶á ášá²áá³á áá­á¥ášáª á­ááœá¶áœá áááµá«áµá ááá°á«ášáµ ášáá«áááá ášá¶ááµáá®áœ áµá¥áµá¥ ááá¢ ááªááµá¶á á á²áµ á áá ááá© áášáá ááá ááá­á á á¢áá°á­ááµ áá­ áá­á á á°áá£á¢ á²á² áá­ ááá°á á«áµáœááá¢ ááªááµá¶á ášá°áááá á <b>áá ááááµ ášá²áá³á áá­á¥ášáª áá®áá­áµ</b> á  <b>áá«á­á¶ á©áášá­á²áŽ</b> á²ááá£ ášá°á°á«áá ášáá°á«ášá áš <b>á©ááµá®</b> á¥á áš <b>áááá á¢áá á€áááŠ</b> áá­ á áá« á ááá ááá¢  ááªááµá¶á áááš áá°á¥ášááœ á¶ááµáá­ á²ááá£ á áá€áá© ášá
+áá¥ áááµ áá°ášáµ áš  <a
+ref="http://greenstone.org">http://greenstone.org</a> áµášáá
+ áá­ á­áááá¢
+</p>
+
+<p>ášá¶ááµáá© á áá á°á ááááœá áááá áµ ááá€ á á°áá­ á©áášá­á²á²ááœá£ á á¥á«á° ááá
+ááµá ášá
+áá¥ ááááá« á°áááµ ášá«á³ážá ášáá á²áá³á áá­á¥ášáª á¥áá²áá¥á© áááµášá ááá¢ á²áá³á áá­á¥ášáªááœ áášá á¥ááŽáµ á¥áá°áá°á«á­á á á©ááµá® á áá­ áá
+á ášá°á¥á á°áááµ ááµá¥ á áµáá
+á­áµá£ á á³á­ááµá á£á
+á áá­áá£ á á áá ááªá«á á á°áá­ á áá°á áá­ á á á áá®áœ áášá á¥ááŽáµ á¥áá°ááá áµá­ááá ášáá áá»á»á« á¥á«á°ášá ááá¢  á­á
+ á¶ááµáá­ áá€á³á ášáá ášá²áá³á áá­á¥ášáªááœá á¥á
+á áá­ á áááá áášáá áááá«áµ á á
+áá¥ ááááá« áµáá« á¥áá°ááá á°áµá á¥áá°á­áááá¢ </p>
+
+<p>á­á
+ á¶ááµáá­ ášá°ááááá ášá°á°á«ášá á¥áá° á ááááá ášáµá¥á¥á­ á¥ášáµ á áááŽ áá­ 2000 (á¥áá° á áá®ááá«á á áá£á á­) á á¶áµáµ á°áááµ ááá á á°áá°ášá° á á«ááµ ááá¢.
+</p>
+
+<p>
+<a href="http://nzdl.org"><b>á  áá«á­á¶ á©áášá­á²áŽ ášáá ááááµ á²áá³á áá­á¥ášáª áá®áá­áµ </b></a>
+<br>
+ááªááµá¶á á¶ááµáá­ á«á°áá ášáá
+ áá®áá­áµ á²ááá£ á­á
+ á
+áá® ááá ááááµ ášá©ááµá® áá®áá«á á áµá°áá
+áŠ á¥áá²áá á³áµáŠ á áá ááááµ ášá©ááµá® á¥áá«á á®ááœá ášá®áá©áá¬áœá á­áá-á®ááœá ášáá°á ááá¢ </p>
+
+<p>
+<a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+class="logo"></a>
+<a href="http://www.unesco.org"><b>á á°á£á á©áµ ááááµá³áµ ášáµáá
+á­áµá£ ášá³á­ááµáá£ ášá£á
+á áµá­á
+áµ </b></a>
+<br>
+á ááá áá­ ášáµáá
+á­áµá£ ášá³á­ááµáá£ ášá£á
+á áášá áµá­á­áµá á á°áá­ áášáá á áá°á áá­ á£á á áá®áœ á¥áá²áá ááµá«á ášá©ááµá® áá¥ áá¥ášá á²áá ášá ášá ááááµá³áµá áášá áááá á á°áá£á­ ááááá á°áµááá£ á ááá ááá ášááœá áášááá£ ášá®ááá¬áœá áŽá­ááá á áá
+ ášááµ ááá áá³áªá« áá á­á³á«áá¢ 
+</p>
+
+<p>
+<a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>ášáá©áá á¢áá á€áááŠá£ á ááµáá­áá£ á€ááášá</b></a>
+<br>
+á­á
+ áá®áá­áµ ášáá°á«á ášá°á£á á©áµ ááááµá³áµ ááªááœá ááááµá³á á£ááá áµá­á
+á¶áœ á²ááá£ áá°á áááœ á¥áµááµ ášáá á á°áá¶áœá á²áá³á­á  á ááµášáá áášáá á«áá­áá« á³á³á á áá®áœ á¥áá²á«áááµ á ááµášá ášáá°á© á ááááœá ášá³áááµ áá­ á ááá ááá¢ 
+</p>
+}  
+
+
+_textdescrselcol_ [l=am] {á­ááœáµ áášá¥}  
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=am] {á ááá» áá áá­ á°ášááª á á«áµ á áá«á®áœ á á}  
+
+_textnocollections_ [l=am] {<p>á áá á ááªááµá¶á áá«á ááµá¥ ááá á­ááœáµ ášááá¢ 
+á­ááœáµá áááµáá£áµ áá­á á á²áµ á­ááœáµ áááá á­
+<ul><li>á­á
+á á°á áá<a href="_httppagecollector_">á°á¥á³á¢á</a> 
+<li>ášááªááµá¶á á°áá£á¢ á²á² á«áá
+ á­ááœá¶á¹á ášá°áá£á¢ á²á°á áá­ áá«á áµáœááá
+ 
+</ul>
+}  
+
+_text1coll_ [l=am] {á­á
+ ášááªááµá¶á áá«á 1 á­ááœáµ á­áá}  
+
+_textmorecolls_ [l=am] {á­á
+ ášááªááµá¶á áá«á _1_ á­ááœáµ á­áá}  
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=am] {ášáá­ á ááá}  
+_textlinknotfound_ [l=am] {ášááµá¥ á ááá á áá°ááá}  
+
+_textextlinkcontent_ [l=am] {ášáášá¥ášá á ááá á áá á«áá
+á áµ á­ááœáµ áá­ ááá¢ á­á
+áá á ááá áášáµ ášááá­á áááá
+ áá° á¢áá°á­ááµ ááá£áµ ášá»áá£ <a href="_nexturl_">áá°ááµ áááµ</a> áµáœááá
+á€ á áá ááá« ášáááá
+á ášáá°áá "back" á áá«á­ á áá áá áá° ááµáá á°ááµá
+ á°áááµá¢
+}  
+
+_textlinknotfoundcontent_ [l=am] {ášá áá¥á¥á­ áá­ á áá áá­áá«áµá£ ášáášá¥ášá ášááµá¥ á ááá ášááá¢ á­á
+ áááá£áµ á¥ášá°á ááá­á áµ á£á á­ááœáµ áµá
+á°áµ ááá á­áœááá¢ áááá
+á áá°áá "back" á áá«á­ á áá áá áá° ááµáá á°ááµá
+ á°áááµá¢}  
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=am] {<h3>áá° "_2_" á­ááœáµ</h3><p> ášáášá¥ášá á ááá áš "_collectionname_" á­ááœáµ (áá°"_2_" á­ááœáµ á­ááµáµáá) áá­ ááá¢
+   á­á
+áá á ááá á  "_2_" á­ááœáµ ááµá¥ áášáµ ášáááá
+ 
+    <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">áá°ááµ áá°á
+</a> á°ááášá°áá€ 
+    á áá ááá« ášáááá
+á ášáá°áá "back" á áá«á­ á áá áá áá° ááµáá á°ááµá
+ á°áááµá¢
+}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=am] {ááªááµá¶á á²áá³á áá­á¥ášáª}  
+
+_textusername_ [l=am] {ášá°áááá­ áµá}  
+_textpassword_ [l=am] {á­áá áá}  
+
+_textmustbelongtogroup_ [l=am] {á áµá³ááµá£ á­á
+áá áá
+ ááá áá áš "_cgiargug_" á¡áµá á á£á ááá á«áµááááá¢}  
+
+_textmessageinvalid_ [l=am] {ášá ášášá áá
+ áá° ááµá¥ ášááá¢á« áááµ á­áááá<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>) á¥á£á­á
+ ášááªááµá¶áá ášá°áááá­ áµáá á­áá áá á áµáá£á¢}  
+
+_textmessagefailed_ [l=am] {ášá­áá áá áá­á ášá°áááá­ á¥á áµá­á­á á á­á°ááá¢}  
+
+_textmessagedisabled_ [l=am] {á­á
+á­á³á£ ááá«á
+ á³áá·áá¢ á¥á£á­á
+á áá¥ááµá°á©á á ááá­á¢}  
+
+_textmessagepermissiondenied_ [l=am] {á­á
+á­á³á£ á­á
+áá áá
+ ááááµ á áµáœááá¢}  
+
+_textmessagestalekey_ [l=am] {ášá°ášá°áášá á ááá á«ášá ááá¢ á¥á£á­á
+á á­á
+áá áá
+ ááá áá ášá­áá ááá
+á á áµáá£á¢}  
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=am] {<p>á­á
+ ááªááµá¶á áá«á ááá áááá£ á á«á«áµáµáá¢ áá­áá«á±á 
+áááá£áµá€
+<ol>
+ <li>ááªááµá¶á ášá°á«áá ášá°áá£á¢ á²á² á á®ááá­áµ  áá«á á áá áá ááá¢
+ <li>ááªááµá¶á ášá°á«áá á á¢áá°á­ááµ áá­ ášáá°á«ášáá á ááášáµ ááá¢
+</ol>
+ášáááá áááá£áá áš <i>docs</i>
+áá
+á°á­ áá­  áá­á ášá°áá£á¢ á²á² áá­á <a href="http://www.greenstone.org">http://www.greenstone.org</a> á ááá¥ááµ áá³áá áµáœááá
+á¢
+}  
+
+_textuserguide_ [l=am] {ášá°áááá­ áááªá«}  
+_textinstallerguide_ [l=am] {ášá«áá áááªá«}  
+_textdeveloperguide_ [l=am] {ášá ááá áááªá«}  
+_textpaperguide_ [l=am] {ášáášááµ áá° á­ááœáµ}  
+_textorganizerguide_ [l=am] {á ááááá á áá áá}  
+
+_textgsdocstitle_ [l=am] {ááªáá°á¶á áááá£}  
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=am] {á­ááœáµá ááá£}  
+
+_textviewbildsummary_ [l=am] {á­á
+áá á áá áá ášáá
+á á­ááœáµ<a href="_httppagex_(bsummary)" target=_top> ášááá£á³áá áá ááá«</a> ášá áá  áááášáµ áµáœááá
+á¢
+}  
+_textview_ [l=am] {á­ááœáµ á°áá­ášáµ}  
+
+_textbild1_ [l=am] {á­ááœá± á áá á¥ášá°ááá£ ááá€ á­á
+ áááá£áµ ášá°áá°á áá á­ááµá³áá¢ ášá³áœ á«áá ášá­ááœáµ á áá°á«ášáµ ááá³ ááµáá­ áµá áá°á± á áµá°á«ášáµ á­á°á¥ááá¢}  
+
+_textbild2_ [l=am] {ášááá£á³ áá°á±á á ááááá áá áááµááá£ á­á
+á á á
+ á áµá­á <br>á¥ášá°á«á
+á áµ á«áá á­áááá¢}  
+
+_textstopbuild_ [l=am] {ááá£á³áá á áá}  
+
+_textbild3_ [l=am] {á­á
+áá ááœ áµáµá°á (á¥á ášááá£á³ áá°á±á á  "stop building" á áá«á­ á«áá°ášáášá) á­ááœá± ááá£á³áá á­áá¥áá á²ášá­áµ á á°á³á« áááŽ á­á«ááá¢}  
+
+_textbuildcancelled_ [l=am] {ááá£á³ á°áá­á§á}  
+
+_textbildcancel1_ [l=am] {á­ááœá±á ášáááá£áµ áá°á± á°áá­á§áá¢ ášá³áœ á«ááá á¢á«áá á áá«á­ á áá áá á­ááœáµá
+ áá­ ááá¥ á áµá­áá ášááá£á³áá áá°áµ á¥áá°áá ááá­á¢}  
+
+_textbsupdate1_ [l=am] {ášááá£á³ ááá³ á  1 á¶á®ááµ áá°á¥ áá»á»á}  
+_textbsupdate2_ [l=am] {ášááá£á³ ááá³ áá»á»á á }  
+_textseconds_ [l=am] {áŽá®áá¶áœ}  
+
+_textfailmsg11_ [l=am] {á­á
+ á­ááœáµ ááá á³á³ áµáááá á á­ááá£áá¢ ášáášá¥á«ážá áá­ááœ áá­á áá
+á°á®áœ á¢á«ááµ á áá± á  <i>áŽá³ ááá­</i> ááœ á­áá«áá€ á¥á ááªááµá¶á áášááá á­áœááá¢}  
+
+_textfailmsg21_ [l=am] {á­ááœá± ááá°ášáµ á áá»áá (import.pl á°áá­á§á)á¢}  
+_textfailmsg31_ [l=am] {á­ááœá± ááá°ášáµ á áá»áá (buildcol.pl á°áá­á§á)á¢}  
+_textfailmsg41_ [l=am] {á­ááœá± á á°á³á« ááá³ á°ááµá­á·á ááá­ áá ááá«á á á­áááá¢}  
+_textfailmsg71_ [l=am] {á­ááœá±á ááááá£áµ áµáµáá­á­ ášáá°á á á áµá
+á°áµ á°ášáµá·á}  
+
+
+_textblcont_ [l=am] {ášááá£á³á áááá¥ ášáášá°ááá áášá á­á­ááá€	áá}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=am] {á
+áµááá¥ ááá
+á­}  
+_textmore_ [l=am] {ášá áá }  
+_textinfo_ [l=am] {ášá­ááœáµ áášá}  
+_textsrce_ [l=am] {ášá³á³ ááá­}  
+
+_textdel_ [l=am] {á­ááœáµá á°á­á}  
+_textexpt_ [l=am] {á­ááœá±á áá° ááª á áá£á}  
+
+_textdownloadingfiles_ [l=am] {áá­ááœ á ááášáµ áá­ âŠ}  
+_textimportingcollection_ [l=am] {á­ááœáµá á ááµáá£áµ áá­ âŠ}  
+_textbuildingcollection_ [l=am] {á­ááœá± á ááá£á³ áá­ âŠ}  
+_textcreatingcollection_ [l=am] {á­ááœáµ á ááá á­ áá­ âŠ}  
+
+_textcollectorblurb_ [l=am] {<i>á¥á¥á­ ášáá«áŽ á«á­áá! 
+<br>ášáášá ášááœá¶áœá áá°á«ááµá áá°á«ášáµ áááááµá ášáá á­á
+ áá³áš á ááá ášáááá­á
+ á ááµ á á°áá¥ áá°á¥ á áá¥á
+á¢
+ášá
+á áá³á®áœ á á ášá
+á áá¥áµá ášáá³á°á á€ á°ááµá áá­á á
+ááá ááááµ áá»á áááµ ááááœ á á³áá ááµá áµ á­á»áá áááµ á ášá°ááá¢
+áá
+á áªá áá³á®áœá á áá€ á­ááœá¶áœ ášáá
+á ášá°á¡á ááá áááµ áá­á á­ áá»á á áá£ážáá¢
+á¥á ášáµá-ááá£á­ áá³á®áœá á áá€ á ááµá ááá­ áá á°á¥á ááááœ á á­áá­á¥áá¢
+<br>ááášá áá«áááµ á¥ááá áµá¥ á¥á á á áá£á¡ á°á ááá áµá¢
+</i>
+}  
+
+_textcb1_ [l=am] {á°á¥á³á¢á á á²áµ á­ááœáµ áááá á­á£ ááá»á»á áá­á á£áá áá­ ááášáá­á£ áá­á á­ááœáµá ááá°ášá á­ášá³ááá¢ á­á
+áá áááµášá ášáá«áµááááá áášá ášáá á­á
+ á°ášá³á³á­ áµášáá
+ áµáá«áá
+á¢}  
+
+_textcb2_ [l=am] {á ááááªá«á£ ášááµ ááá°á á}  
+
+_textwec_ [l=am] {á£áá áá­ áµá«á áµá£ á³á³ á áµáá£á áµ áá­á á°á­ááá¢}  
+
+_textcb3_ [l=am] {ášá²áá³á áá­á¥ášáª á­ááœá¶áœá ááá°á«ááµ áá­á ááá»á»á áá° ááµá¥ ááá£áµ ášááµ ááá¢ ášá
+á áááœ áá° á®áááá°á­á
+ áá¥á°á áášá á¥áá³á­áá­á© ááášáášá ááá¢ ááµá³áá»á€ áá¥ááá á²á£á áá° ááµá¥ áá¥á°á
+ áš 30 á°áá á áá­ ášáášá
+ áá²áá á¥ááµáµáá£ á­á°ášááá¢ á­á
+ ášáááá£ á áµášáá
+! - á¥áá°áá á¥ááµáµáá£ áµáá ááá
+ á¥á á«áášá¥á­á áµ áµáá¥ááá
+á¢}  
+
+_textcb4_ [l=am] {á¥á£á­á
+ ášááªááµá¶áá á°áááá­ áµáá á­áá áá á áµáá£á£ á¥á áá° ááµá¥ áááá£áµ á áá«á©á á á
+ á áµá­áá¢}  
+
+_textfsc_ [l=am] {ááááªá« ášááµá°á«á áµá á­ááœáµ áášá¥ (ááá ášáá­á á­ááœá¶áœ á áá
+ áá­áá­ á ášá³á©á)á¢}  
+
+_textwtc_ [l=am] {á áášá¥ášá ášááœáµá£}  
+_textamd_ [l=am] {ášá áá  á³á³ á ááµáá£áµ á¥áá°áá á­ááœá±á á á³á¥á­}  
+_textetc_ [l=am] {ášá­ááœáµ áá
+ášáµ áá­áá á ááá á­ááœá±á á¥áá°áá ááá£á}  
+_textdtc_ [l=am] {á­ááœá±á áá á áá á°á­á}  
+_textetcfcd_ [l=am] {á­ááœá±á á  ááá¶ááµ á°áá£á¢ á²á² á«á±á á¢áá²á«áµáá³ áá° ááª áµá°á°á }  
+_textcaec_ [l=am] {ááµááá ášá°áá áš á­ááœáµá ááášá­}  
+_textnwec_ [l=am] {ááá»á»á áááá áµ ášááœá ááá á­ááœáµ ášááá¢}  
+_textcianc_ [l=am] {á á²áµ á­ááœáµ ááá á­}  
+_texttsosn_ [l=am] {á á²áµ ášá²áá³á áá­á¥ášáª á­ááœáµ áááá á­ ášáá«á°áœá á­ááááœ á á
+á°á á°ášá°áá€}  
+_textsin_ [l=am] {áµáá á¥ááµ (á¥áá²áá á°á«á«á¥ áášáááœáá)}  
+_textswts_ [l=am] {ášáŽá³ ááá© á¬ášáµ á¥áá°áá á¥ááµ}  
+_textatco_ [l=am] {ášáá
+ášáµ á áá«á®áœá á áµá°á«á­á (áášáá°á á°á áá á¥á»)}  
+_textbtc_ [l=am] {á­ááœá±á "ááá£" (ášá³áœ á°ááášáµ)}  
+_textpvyh_ [l=am] {ášáµá«á
+á áá€áµ á°ááášá°áá¢}  
+
+_texttfsiw_ [l=am] {á á«á°áá á
+á°á á°ášá°á á®áááá°á© áááá áµá« ášáá°á«á áµ ááá¢ á  "building"
+áá°áµ á®áááá°á© áááá áášá á áá ášáá°á«á áµá áá ááážááá áášá  ááµá«á á áµááá ášáááµá áá á á ááµ áá­ ášáá«á°á­áá áµ ááá¢ ááá­ áá áášááá ááááªá« ááá°á á«áµááááá¢}  
+
+_textadab_ [l=am] {ášáá
+ á á³áœ á«áá ááµá ášáµ á¥áá³áá
+ áááá
+ á­ášá³ááá¢ á á
+ ášáá³á°á­áá áá° á
+á°á á°ášá°á ášáááµáµá
+á á ášáááŽ á áá«á­ ááá¢ á á
+á°á á°ášá°á ááµá¥ á°áµááµá£ á áá«á®á¹ áá° á¢á« á­áášá«áá¢ á ááµá áá­ á«ááá á ášáááŽáá á áá«á­ á á
+ á ááµášá áá° á áá°áá áá
+ ááááµ á­á»ááá¢ }  
+
+_textwyar_ [l=am] {ááá áµáµááá£ á ášáááŽáá "ášá­ááœáµ áášá" á áá«á­ á á
+ á ááµášá á á²áµ á²áá³á áá­á¥ášáª á­ááœáµ ááá á­ áááá­á¢}  
+
+
+_texteambs_ [l=am] {ášá¢áá­á á áµá«á» ášááµ áá ááµ á áá áµ}  
+_textpsea_ [l=am] {á¥á£á­á
+ á¢áá­á á áµá«á»áá á áá
+ ááá©á€ username@domain á áµá­á­á á áµááá¥}  
+_textdocmbs_ [l=am] {ášá­ááœá± áááá« áá ááµ ášááµ á áá áµ}  
+
+_textwcanc_ [l=am] {á á²áµ á­ááœáµ á ááµáá¥á­á áµ áá áµá á³á³ ááá­á á áá³ááµ ášááá¢á« áá«áááœá ááµáá£áµ á­áá­á¥ááá¢ á á°á¥á³á¢á á¥á­á³ á­á áá°áµ á¥áá° á ááµ á°ášá³á³á­ áµášáá
+ á­ááá«áá¢ á áá ášá³áœ á£áá á áá áá­  ášáá«á³á­á
+ ášáá ááááµá áááœ á á
+á°á á°ášá°á ááá¢ }  
+
+_texttfc_ [l=am] {ášá­ááœá± á­ááµá€}  
+
+_texttctiasp_ [l=am] {ášá­ááœá± á­á¥áµ á á²áá³á áá­á¥ášáª ááµá¥ ášá­ááœá±á á­ááµ áááášáµ ášáá«áááá á á­á­ áášá ááá¢ á­á¥áµ ááá ášááœá áá³áááœ
+"Computer Science Technical Reports" á¥á "Humanity Development Library" áážáá¢
+}  
+
+_textcea_ [l=am] {ášá¢áá­á á áµá«á»á€}  
+
+_textteas_ [l=am] {á­á
+ ášá¢áá­á á áµá«á» áá­ááœá± ášááááªá« ášáááá áŠá³ ááá¢ ááªááµá¶á á¶ááµáá­ á¥á­á á²áá¥ááá£ ášáá­áá« áªáá­áµ á áá
+ á áµá«á» á­áá«áá¢ ášá¢áá­á á áµá«á» á áá
+ ááá© á áµá­á­á á áµáá£á€ <tt>name@domain</tt>á¢}  
+
+_textatc_ [l=am] {áµááá
+ á­ááœáµá€}  
+
+_texttiasd_ [l=am] {á­á
+ áááá« ášáá«á¥á«á«á áá°ášá³á áµáááá á á­ááœáµ ááµá¥ áá«á°áµ áµáááá£á áá¢  áá³á­ ááá¢ á­ááœá± á ááá£á áµ áá á ááááªá«á áá
+ áá­ á­á³á«áá¢}  
+
+_textypits_ [l=am] {á á
+á°á á°ášá°á ááµá¥ á«áá
+á áµ áŠá³ ášá³áœ á£á ááµáµ á­ááášá³áá¢ á áá
+ áá áš"á­ááœáµ áášá" á°ášá áá­ ááá¢ áááá áá£ á ášáááŽáá "ášá³á³ ááá­" á áá«á­ á á
+ á áµá­áá¢ }  
+
+_srcebadsources_ [l=am] {<p>ášá°áášáá©áµ á ááµ áá­á ášáá« á áá­ ášáá¥á áµ ááá®áœ á áá°ááá (áá¥á _iconcross_ á¥áá°á°á ááá)á¢ 
+<p>á­á
+ ááá ášááœáá
+<ul>
+<li>ášáá­á á€áá²á áµášáá
+ áá­á á©á á­á€á á³á­áá­ á²áá­ ááá¢
+<li>áá° á¢áá°á­ááµ á áááááµ ááµá«á
+ ááááªá« áá°áá á«áµááááá¢
+<li>áááááµ ášáášá©áµ á©á á­á€á ášá¬á áá­á£ áá (á­á
+ á¥á áá áá° ášá¢áá°á­ááµ áááá£áµ ášá°áááá­ á¥áá á­áá áá á áá áá ášáá«áµáááá áµ áá)á¢
+</ul>
+<p>á­á
+ á©á á­á€á á áááá« ášáá³ášá ášááá£ áááá£áµ á á á«á£á¢á
+ ášá³áš áá­á ášá°áá á  á©á á­á€á á
+áááœ ášáá£ ááá¢ á¥áá°á áá£áá£ á¥áá°áá
+ á á­ááµ á
+áááœ á áá
+ ááá³ á á­á³á­áá¢ á áá
+ áá á ááááªá« ááá á áááá
+ á áá³áá á¥ááµá³áá­á°á á¥ááá­á«ááá¢
+}  
+
+_textymbyco_ [l=am] {p>ášá­ááœáµá
+á áá°ášáµ á áášá°ááµ á á áá± 
+<ul>
+<li> á á
+áµááá¥ ááá
+á­
+<dl><dd>á á²á± á­ááœáµ áááá£áµ áš á áœá²á€áá€á á°áá¶áœ (.htm, .html), á
+ááá á°áá¶áœ (.txt, .text), ášá€áá€áµ áá­áµ á°áá¶áœ (.doc), ášáá²á€á á°áá¶áœ (.pdf) áá­á
+áš"m-box" á
+á­áá° á¢áá­á á°áá¶áœ (.mbx).</dd></dl>
+<li>á£á á á°áá áš áµá¥áµá¥
+<dl><dd>á á á²á± á­ááœáµá
+ á«ááµ áá­ááœ ááááªá« ááµáááá ášáá ášáá ášá°áá ášá áµá¥áµá¥ áá­ á áá­ááµ ášááµ á ááµ ááá á áá áµá¢</dd></dl>
+</ul>
+}  
+
+_textbtco_ [l=am] {ášá­ááœá±á áá°ášáµ á }  
+_textand_ [l=am] {á á²áµ á³á³ á áµáá£}  
+_textad_ [l=am] {á³á³ ááµáá£áµá€}  
+
+_texttftysb_ [l=am] {ášá³áœ ášá ááµášá áá­á áá° á­ááœá± á­áá£áá¢ á­ááœáµ ááµá¥ ášáá ášá áá­á á¥áá°áá á áááµá áµá
+á á ášááá¥á€
+á áá ááá« áááµ á ááµ á ášááµ á
+áááœ ášáááá¢ áá­ááœ ášááá©áµ á áá á±á« áµáážá ááá£ áµášáááœ á áá  áµášáá
+ á áµá«á»áœáá¢
+}  
+
+_textis_ [l=am] {ášáá¥ááµ ááá®áœá€}  
+
+_textddd1_ [l=am] {<p>áá­áá ááá°ášá file:// áá­á ftp:// ášááµá áá ášááá€ á« áá­á á­áá­á³áá¢
+
+<p>http:// ášá°á ááá­ á¥áá° ááá³á á­áá°áá á©á á­á€áá
+ áá°á á áµášáá
+ áá­á ášáá­ááœ áá­áá­ á áááá«á
+ áá­ á­á°á¥ááá¢ áµášáá
+ ášááá£ á« áá
+ á­áá­á³á - á¥á ááá ášáá ášá°ááááµ áááœá£ á¥á ááá á á¥ášáážá ášá°ááá áááœáá£ááá°... - á­á
+ ááá ášááœáá ášá©á á­á€á á á³áœ ááá á á ááµ áµášáá
+ áá­ á²áá ááá¢
+
+<p>áá
+á°á­á
+á ááá°á­á file:// áá­á ftp:// ášá°á ááá­á£ áá­á áá°
+áá­ááœ áá­áá­ ášááá«áá http://  á©á á­á€á ášááá£ ááá á áá
+á°á­á
+ ááµá¥ á¥á á áµá© á«á áá
+á°á®áœ á á­ááœá± ááµá¥ á­á«á°á³áá¢
+
+<p>ášá áá  áá¥ááµ á³á¥ááœá áááááµ "ášá áá  ááá­" ášáááá á áá«á­ á á
+ á áµá­áá¢
+}  
+
+_textddd2_ [l=am] {<p>ášá ášááŽ á áá«á®áœ á áá±á á á
+ á áµá­áá¢ášáá°á á°á áá ášááá­ ášá­ááœáµ áá
+ášáµ ááµá°á«ášá áá«áµáááá
+ á­áœááá¢ á¥áá°á áá«á­á£ á áá¥á³ áá° ááá£á³ á°ášá ááµ. á áµá³ááµá£ áá ááá á¢áá áá° ááµáá ááá³ á ášáááŽáá á áá«á­ á á
+ á ááµášá ááááµá áášáµ áµáœááá
+á¢}  
+
+
+
+_textreset_ [l=am] {áá­á­}  
+
+
+_texttryagain_ [l=am] {á¥á£á­á
+ <a href="_httppagecollector_" target=_top>á°á¥á³á¢áá á¥áá°áá á áµáá³</a> á¥á á áá°áá áá­á­á¢}  
+
+
+_textretcoll_ [l=am] {áá° á°á¥á³á¢á á°áááµ}  
+
+_textdelperm_ [l=am] {ášá°áá°ááµ áá­á ááá áš _cgiargbc1dirname_ á­ááœáµ áá°ášá á áá»ááá¢ áá­áá«áµ ááá ášááœááµá€
+<ul>
+<li>ááªááµá¶á _gsdlhome_/collect/_cgiargbc1dirname_ áá
+á°á­ ááá°ášá áááµ ášáááá¢<br>
+ášá
+áá áá
+á°á­ á á¥á
+á
+ ááµáááµ áá«áµáááá
+ á­áœáá áš_cgiargbc1dirname_ á­ááœáµá ášáá
+ á®áááá°á­ áá­ á áµááá¶ ááášášáµá¢</li>
+<li>ááªáá°á¶á áš _gsdlhome_/bin/script/delcol.pl áá®áá«áá áá«áµá¬á°á á áá»ááá¢ á­á
+ áá­á ášááá á¥á ášáá°á« áááá á ášááá¥á¢</li>
+</ul
+}  
+
+_textdelinv_ [l=am] {áš _cgiargbc1dirname_ ášááœáµ ášá°ášáášá áá­á ášáá«áááá ááá¢ ášáá¥áá± áá°áµ á°á°á­ááá¢}  
+
+_textdelsuc_ [l=am] {áš _cgiargbc1dirname_ á­ááœáµ á á°á³á« ááá³ á°á°á­ááá¢}  
+
+_textclonefail_ [l=am] {áš _cgiargclonecol_ á­ááœáµ áá«á£ á áá»ááá¢ áá­áá«áµ ááá ášááœááµá€
+<ul>
+<li> áš _cgiargclonecol_ á­ááœáµ á áá°áá ášá
+<li> áš _cgiargclonecol_ á­ááœáµ collect.cfg ášáá£á áá
+ášáµ áá­á ášááá
+<li> ááªáá°á¶á áš collect.cfg áá
+ášáµ áá­áá ášááá á¥ áááµ ášááá
+</ul>}  
+
+_textcolerr_ [l=am] {ášá°á¥á³á¢ áµá
+á°áµ}  
+
+_texttmpfail_ [l=am] {á°á¥á³á¢á ášááá«á áá­á áá­á áá
+á°á­ áá«áá¥ áá­á áá
+á á áá»ááá¢ áá­áá«áµ ááá ášááœááµá€
+<ul>
+<li> ááªááµá¶á _gsdlhome_/tmp áá
+á°á­ áá­ ááá á¥ áá­á ááá á á­áœááá¢
+</ul>
+}  
+
+_textmkcolfail_ [l=am] {á°á¥á³á¢á áá á²á± á­ááœáµ ášáá«áµááááá (mkcol.pl failed) ášáá
+á°á­ ááá
+á­ ááá á­ á áá»ááá¢ áá­áá«áµ ááá ášááœááá€
+<ul>
+<li> ááªáá°á¶á _gsdlhome_/tmp áá
+á°á­ áá­ áááá áááµ á³á­áášá á²áá­á¢
+<li> mkcol.pl ášá°á£á ášáášá áµá­áªááµ áµá
+á°áµá¢
+</ul>
+}  
+
+_textnocontent_ [l=am] {ášá°á¥á³á¢á áµá
+á°áµá€ áá á²á± á­ááœáµ ááá áá­ááµ áµá á áá°á°á ááá¢ á°á¥á³á¢áá á¥áá°áá á ááµáá³áµ ášááááªá« ááá­á¢}  
+
+_textrestart_ [l=am] {á°á¥á³á¢áá á¥áá°áá á áµáá³á}  
+
+_textreloaderror_ [l=am] {á á²áµ á­ááœáµá áµáµáá¥á­ áµá
+á°áµ á°ášáµá·áá¢ á­á
+ ááá ášááœáá
+ááªááµá¶á á áááá«á
+ "reload" áá­á "back"  á áá«á®áœ ááš á²áá£ ááá¢ (á¥á£á­á
+ á­ááœáµá á á°á¥á³á¢á áµáµáá¥á­ á¥ááá
+á á áá«á®áœ á áµá áá)á¢  á°á¥á³á¢áá á¥áá°áá ášááááªá« á¥áá²áá³ á áµá­ááá¢
+}  
+
+_textexptsuc_ [l=am] {áš _cgiargbc1dirname_ á­ááœáµ áá° _gsdlhome_/tmp/exported\__cgiargbc1dirname_ áá
+á°á­ á á°á³á« ááá³ á°áá³áá¢}  
+
+_textexptfail_ [l=am] {<p>_cgiargbc1dirname_ á­ááœáµá áá° ááª ááá­ á áá»ááá¢
+
+<p>á­á
+ ááá ášááœáá áµ áá­áá«áµ ááªááµá¶á á²á«á áá° ááª ášááášá á áµááá á á«á á á¥á®áµ á áá°á«ááá¢<ul>
+
+ <li>ááªáá°á¶áá áš á°áá£á¢ á²á² áá­ ášá«áá­ á­á
+ á á«á á á¥á®áµ á á­á«áá á áá°á á¥á«áµá
+ á "ášáµá°á" ášá á«á«á ááŽ á«ááá­á¥ášá á áµá°áá­á¢
+ á¥áá°áá á áá«á á°áá¥ áá°ášáµ á­ááµá
+ ááµá¥ áá³á«áµá³ážá áµáœááá
+á¢
+
+ <li>ááªáá°á¶áá ášá«áášá áš áµášáá
+ áµá­á­áµ áá­ ášáá á°ášááª áá¬á
+ ááášáµá á áá«á á­á
+áá á°áá£á­ áá³ááá áµáœááá
+á¢ á¥á£á­á
+
+ á­á
+áá áµášáá
+ <a href="http://www.greenstone.org">http://www.greenstone.org</a> áá¥á áá­á áá°ášááª áášá á  <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a> á¢áá­á á áµá­áá¢
+
+</ul>
+}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=am] {<p> á¥á£á­á
+ ášáášá°ááá áášá á¥ááµá _textintro_ ášáááá á á
+ á áµá­áá¢ </p>}  
+
+_textcaec_ [l=am] {ááµááá á á°áá ášá á­ááœáµ áá­ ááµáá£áµ}  
+_textbild_ [l=am] {áá­ááµá á á á«á
+á}  
+_textintro_ [l=am] {áá­á áášá¥}  
+_textconfirm_ [l=am] {áášááá«}  
+_textselect_ [l=am] {á­ááœáµ áášá¥}  
+_textmeta_ [l=am] {áá³á³á³ áµá¥}  
+
+_texttryagain_ [l=am] {á¥á£á­á
+ <a href="_httppagedepositor_" target=_top>á áµááá©á á¥áá°áá á áµáá³</a> á¥á á áá°áá áá­á­á¢}  
+
+_textselectcol_ [l=am] {á á²áµ á°ááµ ášáá³áµáá£á áµá á­ááœáµ áášá¥á¢}  
+_textfilename_ [l=am] {áá­á á°á­á}  
+_textfilesize_ [l=am] {áá­á áá á}  
+
+_textretcoll_ [l=am] {áá° á áµááá© á°áááµ}  
+
+
+_texttmpfail_ [l=am] {á áµááá© ááá á áá­á áá­á áá
+á°á­ áá­ ááá ááá á¥ á áá»ááá¢ áá­áá«áµá€
+<ul>
+<li> ááªáá°á¶á _gsdlhome_/tmp áá
+á°á­ áá­ ášááá á¥á áá ášááá áá¥áµ ášáááá¢
+</ul>
+}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=am] {ááªáá°á¶á ášá¶áá°áá®áœ áµá¥áµá¥ á²áá ášá²áá³á áá­á¥ášáª á­ááœá¶áœá ááµá°áááµ ášááœáá á á²áµ á­ááœá¶áœá áááµá«áµ á«áááááá¢ ááªáá°á¶á á á²áµ á áá ááááµ áášáá ášáá áááªá« á¥á áášááá á á¢áá°á­ááµ áá­á á á°áá£á¢ á²á² áá­ áá°á á«áµáœááá¢  ááªáá°á¶á ášá°á°á«á á áá«á­á¶ á©áá­á­á²á² ááµá¥ ášááááááµ ášá²áá³á áá­á¥ášáª áá®áá­áµ á²áá ášá°á°á«ášá ášá©ááµá® á¥á áááá á¢áá á áááŠ áá­ á áá°á£á á­ ááá¢ ááªáá°á¶á á­áá°-ááá­ á¶ááµáá­ á²ááá£ áš <i>http://greenstone.org</i> áµášáá
+ áá­ á áá áá© á á ááá­ ášá
+áá¥ áááµ áá°ášáµ á­áááá¢}  
+
+_textgreenstone2_ [l=am] {áš ááááááµ ášá²áá³á áá­á¥ášáª áµášáá
+ (<a
+href="http://nzdl.org">http://nzdl.org</a>) á á­á«á³ áá³áááœáá£ ááá á ááªááµá¶á á¶ááµáá­ ášá°á°á©á£ ášá«á á²áá ááááá á°á áá«áááá áá ááá áµ á­áœááá¢ áá³ááá¹ ášá¥á áá­ááµ ášááááá«á ášáá°á» á áá«á®áœá á²á«áµášá±á£ á á ášá¥áá£ á á»á­ááá£ á ááªáá£ á¥áá²áá á áµáááœá á á¥ááááá áááááœ á­ááœáµáá á«á«áµá³áá¢ ášá°áá°á ášááá á­ááœáµáá á­á­ááá¢ 
+}  
+
+_textplatformtitle_ [l=am] {áááµáá­á}  
+_textgreenstone3_ [l=am] {ááªáá°á¶á á  ááá¶ááµá£ á©áá­áµ á¥á áá­ áŠá€áµ á€á­áµ áá­ á­á°á«áá¢ ááªááµá¶á á ááá ášááá¶ááµ áá­á«á£á©áá­áµ á¥á áá­ áŠá€áµ á€á­áµ áá­ áá²á«á ááá áá á¥áá²á«áµáœá ášá°ááá á£á­ááª áµá­á­áµ á ááá¢áµá­á­á± ášá°áá áááš áá°áá­ á²á«á­áµáµá£ áááš áá°áá©á á áá­á­á®á¶ááµ á²++ áá­á áá²á² áá°áá³áµ á­á»ááá¢ ááªááµá¶á á áá ášááááµ ášá ááŒ áá¥á°á­ášá­ á¥á áá­á áá­ á á¥á® á­á°á«áá¢   ášá°á áá á á­ááá ášáµá­ áá­á ášáá¥ áááá«á€ ááµáµá¬á ááªáá°á­ áá­á á¢áá°á­ááµ á€á­áµááášá­ áá áá á­áœááá¢ }  
+
+_textgreenstone4_ [l=am] {á á­á«á³ ášá°ááµ á­ááœá¶áœ á  á°áá£á¢-á²á² ááá ášááªááµá¶á á¶áá°áá­á á áá áá á­á°á«á«áá¢ ááá³áá£ áš <i>áá©ááá² á°ášáááááµ áá­á¥ášáª</i> áš 1,230 á
+áµáá¶áœá áš á á«ááá²áá á¥áµáš ášáá ááœá
+á áµášáµ á°áá¶áœá á­á á­áááá¢ á á³á³á á áá®áœ ááµá¥ ááá á ááœá á á°á« á®áááá°á­ áá­ á­á°á«áá¢ áášááá á áááá£ á á­á¥á° áá³á­ á áá°áµá£ á á­á¥á± á áá°áµá£ ááá°âŠááááµ á²á»áá€ ášáá»á
+ááµáá ášááµ ááœ áášáµ á­á»ááá¢}  
+
+_textcustomisationtitle_ [l=am] {ááµáááµ}  
+_textgreenstone5_ [l=am] {ááªááµá¶á á²áá°á á á°áá­ á á£á áá°áá£ áá«áµáá ááµáá á ááœá ááá© á³áµáŠ ááá¢ á á²áµ ášá°ááµá ášáá³á³á³ á
+á­ááµ á áá­á ááá "áááááµ" ("plugins") á ááá áá«á°áµ á­á»ááá¢ ášáá áá« á°á«á­áá£  á á²áµ ášáá³á³á³ ááááá« ááá
+á­ "á­áá²áášá®áœá" ("classifiers") á ááá áµá« áá­ ááá á­á»ááá¢ ášá°á áá á á­ááá
+á ášáá«áá­á áá«áª áááµášá "áá­á®ááœá "("macros") á ááá á áá­á® ááá á ááá ááášá­ á­á»ááá¢ ášá®á á« áá®á¶á®á ááªááœ (áá³á áá«) áááá ášá°ááµ á­ááœáµ ááááá«ááœá ááá áá ášáµáœááá¢ á áášášá»áá£ ášá²++á£ ášáá­á áááš áá°áá©á ááááµá á á»áœá áá áá á­á»ááá¢}  
+
+_textdocumentationtitle_ [l=am] {áááá£}  
+_textdocuments_ [l=am] {áááªááµá¶á á¶ááµáá­ áá á á°á áááá£ á­áááá¢}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=am] {ášá áµá«á» áá­áá­}  
+_textmailinglist_ [l=am] {áµá ááªááµá¶á á²áá³á áá­á¥ášáª á¶ááµáá­ áááá«ášáµ ášáá«áµáœá ášá áµá«á» áá­áá­ á áá¢ ášááªáá°á¶á ááá á°á ááááœ áá° á áµá«á» áá­áá© ááá£áµá ášá«á³ážáá á áµá°áá
+áŠ ááµášá á­á á á
+á£ážááá¢ á°áá á áááááá£ áá°áá
+ áµášáá
+ ááµ<a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a> á¢ 
+
+ááµ á áµá«á» áá­áá© ááá­áµ áááá­á£ ášá
+áá á áµá«á»  á°á áá<a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a> á¢
+}  
+
+_textbugstitle_ [l=am] {á¥áá
+áá¶áœ}  
+_textreport_ [l=am] {á­á
+ á¶ááµáá­ á áµá­á­á á¥áá°áá°á«áá
+ áášááá¥ á¥ááááááá¢ á¥á£á­á
+ áááááá á¥áá
+ááµ áá°áá
+ <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a> áªáá­áµ á áµá­áá¢}  
+
+_textgs3title_ [l=am] {á ááµá  áµá«ááœ}  
+_textgs3_ [l=am] {ááªááµá¶á 3 áá á áá á¥áá°áá  ášá°áá°áá ášá°á°áá áš á²áá ášááªááµá¶á 2á (ášá ááá)  áááá á¥á
+ááœ ášá«á áá - ááá³áá£ áá³á á¥á ááá£ á£á á¥á áááµáá­áá£ á á£á ášáááá­ ááá¢ ááªááµá¶á 3 ášá ááá á²á°á°á áááá á£á
+áªá«áµ á²á«á«áµáµá£áá°áá á°á³áá ááá€ áááµáá£ ááá ááá¥ á³á­á°ášá á áá á«áá áá­á ášá°áá ášá á­ááœá¶áœ áááá£áµá ááá³áµ á­á»ááá¢ ááªááµá¶á á áá« ááá ášá°áá á²ááá£ ášá°ááášá á¥áá° á áµá áášá¥ áá ášáá á á€á­áµá€áá€á ááá«áµ ášááœá ááááœ  ááá€ áµááá
+ á á²áµáµáªá¢ááµáµ ááœá ášáá°á«á á¥áá°á áµááááá± á á°áá«á© á áááá®áœ áá­ áá°á«á­ ášááœá ááá¢ á­á
+ áááá­ ááµá ášááªááµá¶áá ášáá°áá ášáá³áá/ášáá°á á£á á á á
+áá á­ášáášááá¢ ášááªááµá¶á 3 áááá£á ášáášá« áµá­á­á± áš <a href="http://www.greenstone.org/greenstone3.html">ášááªááµá¶á 3 ááá» áá
+</a> áá­ ááášáµ á­á»ááá¢}  
+
+_textcreditstitle_ [l=am] {áá}  
+
+_textwhoswho_ [l=am] {ášááªáá°á¶á á¶ááµáá­ ášá¥á á°ááœ áµá¥á¥á­ áá€áµ ááá¢ á®áá­ áá­áá¥ á¥á áµáŽáá áŠáŽ ááá ááá³áá ášáááœ áážáá¢ á áµá°áá
+áŠ á«á ášášá± á°ááœ áµá áá­áá­á€ áŽáªáµ á£á­áá áªá
+á£ áá­á
+ á¡á«ááá£ ááá ážáá£ áá­á­á á²ááµááá£ á«á³áªá á¶áá£ á€ááª á±áášá­á£ á«á­á ááµááá£ááŠá ááááµá£ á³á áá¬á­á£ áá áá­áá­á°áá£ á­á¬á­á
+-ááááá£ á³á­áá ááŽáá£ áá­á¶á áá­áá°á­á£ á á­ááá­áµ ááªááá­á£ á¶áµ áªáµá£ á¢á á®áá­áµá£ áá á¶áá°áá£ á¥á áµá±áá­áµ áªáŽáµ áážá á¢ áááœ ášááááááµ ášá²áá³á áá­á¥ášáª áá®áá­áµ á á£ááµ á¶ááµáá© á²áá°á  ášáá­á­á ášáá ášá³á» á áµá°áá
+áŠ á«á°ášááµá€ áášá­ á áášáá­á£ á³á á á«áááááá£ ááµ áááµá£ áµá²á­ áááµá£ á² á³á« áªááá£ ááŒá ááµáµá£ ááá« áááªá£ ááª áá­áµá°áá£ áŽá­ áá®ááµá£ á¥á áá­áµ á°áá áážáá¢ á á°ášááª á áá
+ áµá­á­áµ ášá°á«á°á± áš áá€áá©-áááµ (GNU-licensed ) á¥á
+ááœáá€ MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE á¥á XLHTML áá ášášá±áá áá áááá°áááœá  á¥ááááááá¢
+}  
+
+_textaboutgslong_ [l=am] {áµá ááªááµá¶á á¶ááµáá­}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=am] {á áá á«á ášá°áááá®áœ áá­áá­}  
+_textuser_ [l=am] {á°áááá­}  
+_textas_ [l=am] {ášáááá¥ áááŽ}  
+_textgroups_ [l=am] {á¡áµááœ}  
+_textcomment_ [l=am] {á áµá°á«ášáµ}  
+_textadduser_ [l=am] {á á²áµ á°áááá­ á áµáá£}  
+_textedituser_ [l=am] {á áá}  
+_textdeleteuser_ [l=am] {á áµáááµ}  
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=am] {ášá°áááá­á áášá á áá}  
+_textadduser_ [l=am] {á á²áµ á°áááá­ á áµáá£}  
+
+_textaboutusername_ [l=am] {ášá­áá áá á­ááá á 2 á¥á á 30 ááá (áá°á) ááá ášááµ ááá á áá áµá¢ áááááá ášá áá áá¥á­ áááá£  '.', á¥á '_' áá­á á­áœááá¢}  
+
+_textaboutpassword_ [l=am] {ášá­áá áá á­ááá á 2 á¥á á 30 ááá (áá°á) ááá ášááµ ááá á áá áµá¢ áááááá áá°á á ášá áµáª (ASCII) ááá  áá­á á­áœááá¢}  
+
+_textoldpass_ [l=am] {á­á
+ ááµá­ á£á¶ ášáá ášááµááá á­áá áá á­á­ááá¢}  
+_textenabled_ [l=am] {ášáá}  
+_textdisabled_ [l=am] {ášáášá}  
+
+_textaboutgroups_ [l=am] {á¡áµááœ á á®á ášá°ááš áá­áá­ ááá£ ášá®á á áá á­áá°áµ á á³áµášáá¢}  
+
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=am] {á°áááá­á á áµáááµ}  
+_textremwarn_ [l=am] {á°áááá­ <b>_cgiargumun_</b> á áµášáá²á«áá ááµáááµ áááááá?}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=am] {ášá­áá áá áá­á­}  
+_textoldpw_ [l=am] {ášááµáá ášá­áá áá}  
+_textnewpw_ [l=am] {á á²áµ ášá­áá áá}  
+_textretype_ [l=am] {á á²á±á ášá­áá áá á°ááá á áµáá£}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=am] {ášá­áá ááá
+ á á°á³á« ááá³ á°ááá§áá¢}  
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=am] {ášá°áááá­ áµá á á«áááááá¢}  
+_textinvalidpassword_ [l=am] {ášá­áá áá á á«áááááá¢}  
+_textemptypassword_ [l=am] {á¥á£á­á
+ ááá
+ á°áááá­ ááá» ášá­áá áá á áµáá£}  
+_textuserexists_ [l=am] {á­á
+ á°áááá­ ááµáááá á áá£ á¥á£á­á
+ áá ášá°áááá­ áµá á áµáá£á¢}  
+
+_textusernameempty_ [l=am] {á¥á£á­á
+ ášá°áááá­ áµáá
+á á áµáá£á¢}  
+_textpasswordempty_ [l=am] {ášááµá ášá­áá ááá
+á ááµáá£áµ ááµ á­ááá¢}  
+_textnewpass1empty_ [l=am] {á á²á±á ášá­áá áá á áµáá£á á°ááá
+á á áµáá£á¢}  
+_textnewpassmismatch_ [l=am] {ááá± á
+á ášá­áá áá á áá° áá­ááµ á á­á°ááá¢}  
+_textnewinvalidpassword_ [l=am] {á«áµáá£ážá ášá­áá áá á á«áááááá¢}  
+_textfailed_ [l=am] {ášá°áááá­ áµáá
+ áá­á ášá­áá ááá
+ áµá­á­á á á­á°áá}  
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=am] {ášááªááµá¶á áµáªáµ áá¥á­}  
+_textframebrowser_ [l=am] {á­á
+áá ááášáµ áá¬á áášáµ ášááœá áááá« ášááµ á«áµááááá}  
+_textusermanage_ [l=am] {ášá°áááá­ á á«á«á}  
+_textlistusers_ [l=am] {ášá°áááá®áœ áá­áá­}  
+_textaddusers_ [l=am] {á á²áµ á°áááá­ á áµáá£}  
+_textchangepasswd_ [l=am] {á­áá áá áá­á­}  
+_textinfo_ [l=am] {ášáŽá­áá«á áášá}  
+_textgeneral_ [l=am] {á á ááá­}  
+_textarguments_ [l=am] {áááª á¥áŽá¶áœ}  
+_textactions_ [l=am] {áµá­áá¶áœ}  
+_textbrowsers_ [l=am] {áááá«ááœ}  
+_textprotocols_ [l=am] {áá®á¶á®ááœ}  
+_textconfigfiles_ [l=am] {áá
+ášá° áá­ááœ}  
+_textlogs_ [l=am] {ááááŠáœ}  
+_textusagelog_ [l=am] {ášá á ááá áááá¥}  
+_textinitlog_ [l=am] {ášá¢ááµ áááá¥}  
+_texterrorlog_ [l=am] {áááá  áµá
+á°áµ}  
+_textadminhome_ [l=am] {ášá áµá°á³á³áªá áµáá«}  
+_textreturnhome_ [l=am] {ášááªááµá¶á ááá» ááœ}  
+_titlewelcome_ [l=am] {á áµá°á³á°á­}  
+_textmaas_ [l=am] {á«ááµ ášá¥ááá ášá áµá°á³á°á­ á ááááá¶áœá€}  
+_textvol_ [l=am] {áá¥á³ áááá¥á á°ááášáµ}  
+_textcmuc_ [l=am] {á­ááœá¶áœá áá á­á£ á ááá£ á¥áá²áá á á»áœá}  
+_textati_ [l=am] {ášáŽá­áá«á áášáááœá á¥áá° áááª á¥áŽá¶áœ ááááµ}  
+
+_texttsaa_ [l=am] {á­á
+ á áááááµ ášáááá á áá
+ ááœ áá« á á©á áá­ á£á ášáá á á³áœ á áá ááá¢}  
+
+_textcolstat_ [l=am] {ášá­ááœáµ ááá³}  
+
+_textcwoa_ [l=am] {á­ááœá¶áœ "running" ášáá ááá­áµ ášáá«á³á©áµ áš build.cfg
+áá­áážá á²áá­á£ á¥ááá
+ áá­ááœ á°áá£á¢ á²ááá£ áµá­á­áá ášáá builddate ááµá­ (áááµá ášáá® ášá áá )á£ á¥áá²áá
+á á­ááœá± á áá áá
+á°á­ (áááµáá£ ášá¢ááá²áá áá
+á°á­ ááµá¥ á³á­áá)
+ááµá¥ á²áá ááá¢
+}  
+
+_textcafi_ [l=am] {áµá á­ááœáµ áášá <i>abbrev.</i> ášáááá á á
+ á áµá­á}  
+_textcctv_ [l=am] {á­ááœáµá ááášáµ <i>collection.</i> ášáááá á á
+ á áµá­á}  
+_textsubc_ [l=am] {ááá¡á á áµáá£}  
+_texteom_ [l=am] {main.cfg ášá°á£á áá­áá ášáá­ááµ áµá
+á°áµ}  
+_textftum_ [l=am] {main.cfg á áá»á»á á°áµáá³á}  
+_textmus_ [l=am] {main.cfg á á°á³á« ááá³ á³áµá·á}  
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=am] {áš "_collectionname_" á­ááœáµ ááá£á³ áá ááá«}  
+_textflog_ [l=am] {áš "_collectionname_" á­ááœáµ ášáá°áá­á áááá¥}  
+_textilog_ [l=am] {áš "_collectionname_" á­ááœáµ ááµá áµ áááá¥}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=am] {á áµá°á«ášáµ áá­}  
+
+_greenstoneusabilitytext_ [l=am] {ááªáá°á¶á á ááá³á}  
+
+_textwhy_ [l=am] {<p>á­á
+á áªáá­áµ ááá­ á áµážááª áá­á ášáá«áµášáá
+ áµášáá
+ á¥áá°áá áá
+ áá³á« ááááµ ááá¢}  
+_textextraforform_ [l=am] {á
+áá ášááµ ááááµ ášáá¥á
+á - áááááá áášá á­ášá³áá¢}  
+_textprivacybasic_ [l=am] {áªáá­á± ášáá­áá áµáµááášá°á áµááá ášá áµá ááªááµá¶á áµášáá
+ ááá£ á á ááášáµ ášá°á ááá­á áµ áŽá­ááá (á á°ášááªá ášá°á ážááá áášá)á¢}  
+_textstillsend_ [l=am] {á­á
+áá áªáá­áµ á ááá ááá­ áµááááá
+?}  
+
+_texterror_ [l=am] {áµá
+á°áµ}  
+_textyes_ [l=am] {á á}  
+_textno_ [l=am] {á á­ááá}  
+_textclosewindow_ [l=am] {ááµá®áµ áá}  
+_textabout_ [l=am] {áµá}  
+_textprivacy_ [l=am] {ášáá}  
+_textsend_ [l=am] {áá­}  
+_textdontsend_ [l=am] {á áµáá­}  
+_textoptionally_ [l=am] {á¥áá° á áá«á­}  
+
+_textunderdev_ [l=am] {áá­áá­ á¥á­á³á ášáášášá» áµáªáµ áá­ á­áááá¢}  
+
+_textviewdetails_ [l=am] {áá­áá­ áªáá­á±á á°ááášáµ}  
+_textmoredetails_ [l=am] {ášá áá  áá­áá­}  
+_texttrackreport_ [l=am] {á­á
+á áªáášáµ áááá¥}  
+_textcharacterise_ [l=am] {áá áá­ááµ áœáá­ áá}  
+_textseverity_ [l=am] {áœáá© áá á«á
+á á áµášá áá}  
+ 
+_textbadrender_ [l=am] {áá á¥ááá³ á­ááµáá}  
+_textcontenterror_ [l=am] {ášá­ááµ áµá
+á°áµ}  
+_textstrangebehaviour_ [l=am] {á«áá°ááá° á£á
+áª}  
+_textunexpected_ [l=am] {á«áá°á á á ááá­ á°ášá°á°}  
+_textfunctionality_ [l=am] {ááá áá ášáášá¥áµ}  
+_textother_ [l=am] {áá}  
+
+_textcritical_ [l=am] {áá³á}  
+_textmajor_ [l=am] {á á°áá}  
+_textmedium_ [l=am] {áá«ášáá}  
+_textminor_ [l=am] {áµááœ}  
+_texttrivial_ [l=am] {ááá}  
+
+_textwhatdoing_ [l=am] {áá áá á­ áááµá«áµ ášááášá?}  
+_textwhatexpected_ [l=am] {áá á¥áá²áá áµá á¥ááá
+?}  
+_textwhathappened_ [l=am] {á áµá­á­á áá á°ášá°á°?}  
+
+_cannotfindcgierror_ [l=am] {<h2>á­á
+á­á³!</h2>ášá áááá©á áá®áá«á á "_linktextusab_" á áá«á­ ááááµ á áá»ááá¢}  
+
+_textusabbanner_ [l=am] {ášááªáá°á¶á á®á©-á°á³á­á á°áá°á
+}  
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=am] {áµá
+á°áµ á°ášáµá·á}  
+
+_textgtihome_ [l=am] {á¥ááá
+ áááœ ášááªááµá¶áá áá³á á¥á áµáá ááá»á»á á«áááá¢ á¥ááá
+á ááá áá
+<ul>
+  <li>ášááªááµá¶áá ášá°áá°á á­áá áá° á á²áµ ááá áá°á­áá
+  <li>ášá¥áááááá á á­ááá
+ á²áášá­ ááµááá ášá°á°á®áááá á á­ááá
+ áá»á»á (ááá³áá£ á á³á²áµ ááªááµá¶á ááááá«ááœ á²áá á©) 
+  <li>áµá­áá áá­ áµá
+á°áµ á²áá á­ áášá
+</ul>
+
+ášáá°ášáááá áá­á á áá«áá£ á°ášá³á³á­ ášáá áµášáááœ á­áá­á¡áááá¢ 
+ášááááá á á­ááá
+ áášá á áášá á áá°ášáá áá¥áá¢ 
+á¥ááá¹ áášááœ áš á€áœá²á€áá€á áá«á áµá¥áááœá á­áááá€ á¥ááá
+á ááá°á­áá ááášá­ ášáá¥á
+á ááá­áá áµá­áá ááµá¥ á¥áá³á á°áážáá¢ á á°ášááá¥áµ á«á ááá¶áœ (áááµá _á¥áá²áá
+_) á á­á°ášáááá¢ 
+<p>
+ášáá³á»áœáá á áá á«ááá  ášááá á á­ááá
+ ášáá ášá°á°ášáá áášááœ ááµá­áá á á­áá­á¡áá
+áá¢ á áá³ááµ áá áµá­ááá á­áá­á ááá­ áá ášá¢áááááá á
+áá ášá°áášáš ááá á­áœááá¢ á áá
+ áá ášá°á°ášááá ášáá­á¥ááá á¥á áášááá  á¥á á áµáááá ášáá áá»á»á á«áµááááá¢
+<p>
+ášá°á»á»á á ááµ áµá­ááá ááášáá£ "ááµáááá ášá°á°á®áá" ášáááá á°á ááá¢ 
+<p>
+á¥á«áá³áá± áá
+ á  "_textgtisubmit_" á áá«á­ á­ášá­á³áá¢ á áá«á©á áµáµá«ááá£ á  nzdl.org á°áá­á¶ á á°á«á ááªááµá¶á áá­ áá²á«áá ááá¥ á«áá£áá¢ á­á
+á áµášáá
+ áááááµ á¥á«áá³áá± áá
+ áá­ á áá«á­ á á¥á®áµ á­áášááá¢ 
+}  
+
+_textgtiselecttlc_ [l=am] {á¥á£á­á
+á áááá
+á áášá¥}  
+
+#for status page
+_textgtiviewstatus_ [l=am] {ášáááá ááá ášáµá­áá áááŽ ááááášáµ á á
+ ááµášá }  
+_textgtiviewstatusbutton_ [l=am] {ááá³áá áááášáµ}  
+_textgtistatustable_ [l=am] {ášááá ááá áµá­áá ááá³}  
+_textgtilanguage_ [l=am] {ááá}  
+_textgtitotalnumberoftranslations_ [l=am] {á á
+áá ášáµá­áááœ á¥ááµ}  
+
+_textgtiselecttfk_ [l=am] {á á£á­á
+ ášááµá°á«á áµá áá­á áášá¥}  
+
+_textgticoredm_ [l=am] {ááªááµá¶á á á­ááá (áá)}  
+_textgtiauxdm_ [l=am] {ášááªááµá¶á á á­ááá (áŠááááª)}  
+_textgtiglidict_ [l=am] {ášáá áááá  áááµ}  
+_textgtiglihelp_ [l=am] {ášáá áá­á}  
+_textgtiperlmodules_ [l=am] {ášáá­á ááááœ}  
+_textgtitutorials_ [l=am] {á±á¶áªá«á ááááááœ}  
+_textgtigreenorg_ [l=am] {Greenstone.org}  
+_textgtigs3core_ [l=am] {ášááªááµá¶á3 á á­ááá
+ (á
+áµááá¥)}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=am] {ášááªááµá¶á á ááá
+ áááªá«}  
+_textgtiinstallmanual_ [l=am] {ášááªááµá¶á ášá«áá áááªá«}  
+_textgtipapermanual_ [l=am] {ášááªááµá¶á ášáášááµ áá° á­ááœáµ áááªá«}  
+_textgtiusermanual_ [l=am] {ášááªááµá¶á á°áááá­ áááªá«}  
+
+_textgtienter_ [l=am] {áá£}  
+
+_textgticorrectexistingtranslations_ [l=am] {ááµááá ášá°á°á®áááá á áµá°á«á­á}  
+_textgtidownloadtargetfile_ [l=am] {áá­á á áá­áµ}  
+_textgtiviewtargetfileinaction_ [l=am] {á­á
+á áá­á á áµá­ááµ á°ááášáµ}  
+_textgtitranslatefileoffline_ [l=am] {á­á
+áá áá­á ášááµáá­ ááª ááá
+ á°á­ááá}  
+
+_textgtinumchunksmatchingquery_ [l=am] {á°áááœ ášáááµ ášá
+áá á¥ááµ}  
+
+_textgtinumchunkstranslated_ [l=am] {áµá­áá ášá°á°á«áážá}  
+_textgtinumchunksrequiringupdating_ [l=am] {áš, _1_ ááµá¥ áá»á»á« á­áááá}  
+_textgtinumchunksrequiringtranslation_ [l=am] {ááª áµá­áááœ}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=am] {áµá­áá ášá°á°á«áážá á¥ááµ}  
+_textgtinumchunksrequiringupdating2_ [l=am] {áá»á»á« ášáááááµ áµá­áááœ á¥ááµ}  
+_textgtinumchunksrequiringtranslation2_ [l=am] {ááª áµá­áá á¥ááµ}  
+
+_textgtienterquery_ [l=am] {áá³áµá°á­á­á ášááášá áœáá ááµá¥ áááµá áá­á á
+ášáá á ááµáá£áµ á áµá°á«á­á}  
+_textgtifind_ [l=am] {á áá}  
+
+_textgtitranslatingchunk_ [l=am] {áš <i>_1_</i> á²á°á®áá}  
+_textgtiupdatingchunk_ [l=am] {ášá
+ááá á á«á á²á»á»á <i>_1_</i>}  
+_textgtisubmit_ [l=am] {á áµá°ááá}  
+
+_textgtilastupdated_ [l=am] {áášášá» ášá°á»á»á}  
+
+_textgtitranslationfilecomplete_ [l=am] {á­á
+á áá­á á áá»á»áá
+ á¥ááá°áááá -- á áá á°ááá·á!<p>á­á
+á ášáá­ ášá°á áá°áá á ááá á áá áá á ášáá
+á áá­á á
+á ááášáµ áµáœááá
+á£ á¥áá áá°ááµ á ááá£á ášááªááµá¶á áµá­á­áµ ááµá¥ á­á«á°á³áá¢}  
+
+_textgtiofflinetranslation_ [l=am] {á­á
+áá ášááªááµá¶á á­áá ášááµáá­ ááª á áá­á­á®á¶ááµ á€á­áµá€á ááµá°ášáá áµáœááá
+á¢ 
+<ol>
+<li>ášáá
+ áá­ <a href="_gwcgi_?a=gti&p=excel&e=_compressedoptions_">á­á
+áá áá­á</a> á áá­á°áá¢
+<li>ášáášá°áá áá­á á áá­á­á®á¶ááµ á€á­áµá€á á­ááµá á áá­á­á®á¶ááµ á€á­áµá€á áá­á­á¡á­ (.xls)  á
+á­á
+ á áµááá áá¢ 
+<li>áµá­ááá á á°ááá á á³á¥á ááµá¥ á áµáá£á¢
+<li>áááá áááµ áµáµášá­á£ áš . xls áá­áá áá° <a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>áášáá¢
+</ol>
+}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=am] {ášááªáá°á¶á ášáá­á ášáªá«á á á­ááá
+}  
+_textglihelp_ [l=am] {<p>á áµá³ááµ GLI ášáá°á«á áš ááªáá°á¶á áá­ á á¥á® ááá£ á¥á á³á³á¢ ášáá«á°á­áá á ááªáá°á¶á áá«á á­áá áá
+á°á­ ááµá¥ á¥áá°á°á«á ááá¢ ááªááµá¶á ášá°á«áá á á¢áá°á­ááµ áá­ ášáá°á«ášáá á ááášáµ ášááá£ áá­á ášá°áá£á¢ á²á² ášá°á«á ášááá£ á­á
+ ááá á­áœááá¢</p>
+
+<h4>GLI á ááá¶ááµ áá­  á²áá</h4>
+
+ášáá­á¥ášáªá«á á á­ááá
+á á ááá¶ááµ áá­ ááááá­ áš<i>Start</i>ááá« <i>Programs</i>áá¥á áš<i>Greenstone Digital Library</i>ááµá¥  áš<i>Librarian Interface</i> ášáááá áášá¥á¢
+
+<h4>GLI á á©áá­áµ áá­ á²áá</h4>
+
+GLI á á©áá­áµ áá­ á¥áá²á°á« áááµášáá£ áá° á ááªáá°á¶á áá«á áµá­ áá° <i>gli</i> áá
+á°á­ áá­á­á£ áá¥áá
+ <i>gli.sh</i> ášáááá áá­á áá­á á°á­áªááµ á áµáá³áá¢ 
+
+<h4>GLI á áá­ áŠá€áµ á€á­áµ áá­</h4>
+
+á áá­áá°á­ ááµá¥á£ <i>Applications</i> ášáááá áášá¥á¢ áá¥á <i>Greenstone</i> ášáááá (ááªáá°á¶áá á
+áµááá¥ áŠá³ áá­ ášá°á«á)á£ á¥á áá¥á <i>GLI</i> ášáááá áµáá á« á áµáá³á¢
+}  
Index: /gsdl/stable/macros/arabic.dm
===================================================================
--- /gsdl/stable/macros/arabic.dm	(revision 20131)
+++ /gsdl/stable/macros/arabic.dm	(revision 20131)
@@ -0,0 +1,1577 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Arabic Language text and icon macros 
+# Many thanks to Kamal Mustafa (updated March 2009) and Usama Salama (updated September 2004)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=ar] {Ø§ÙØ¯ÙØ±ÙØ§Øª}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=ar] {Ø§ÙÙ
+ØµØ¯Ø±:}
+_textdate_ [l=ar] {ØªØ§Ø±ÙØ® Ø§ÙÙØŽØ±:}
+_textnumpages_ [l=ar] {Ø¹Ø¯Ø¯ Ø§ÙØµÙØ­Ø§Øª:}
+
+_textsignin_ [l=ar] {ØªØ³Ø¬ÙÙ Ø¯Ø®ÙÙ}
+
+_textdefaultcontent_ [l=ar] {Ø§ÙØµÙØ­Ø© Ø§ÙÙ
+Ø·ÙÙØšØ© ÙØ§ ÙÙ
+ÙÙ Ø§ÙØ¹Ø«ÙØ± Ø¹ÙÙÙØ§ . Ù
+Ù ÙØ¶ÙÙ Ø§Ø³ØªØ®Ø¯Ù
+ Ø²Ø± Ø§ÙØªØ±Ø§Ø¬Ø¹ ÙÙÙØµÙÙ ÙØµÙØ­Ø© Ù
+ÙØªØšØ© GREENSTONE Ø§ÙØ±ÙÙ
+ÙØ© Ù
+Ø±Ø© Ø£Ø®Ø±Ù.}
+
+_textdefaulttitle_ [l=ar] {Ø®Ø·Ø£ GDSL}
+
+_textbadcollection_ [l=ar] {ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© (Ø§ÙÙ
+Ø³Ù
+Ø§Ø© "_cvariable_") ÙÙØ³Øª Ù
+Ø­Ù
+ÙØ© Ø¹ÙÙ ÙØžØ§Ù
+ Ø§ÙÙ
+ÙØªØšØ© Ø§ÙØ±ÙÙ
+ÙØ© GREENSTONE }
+
+_textselectpage_ [l=ar] {ÙÙ Ø§Ø®ØªØ± ØµÙØ­Ø© --}
+
+_collectionextra_ [l=ar] {ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ØªØ­ØªÙÙ Ø¹ÙÙ:_about:numdocs_ ÙØ«ÙÙØ©. 
+Ø¢Ø®Ø± ØªØ§Ø±ÙØ® ÙÙØªØ­Ø¯ÙØ« ÙÙÙ
+ _about:builddate_. }
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=ar] {<p>ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ØªØ­ØªÙÙ Ø¹ÙÙ _numdocs_ _If_("_numdocs_" eq "1",ÙØ«ÙÙØ©,ÙØ«Ø§ØŠÙ), Ù
+Ù Ø¥Ø¬Ù
+Ø§ÙÙ _numbytes_.
+<p><a href="_httppagex_(bsummary)">Ø§Ø¶ØºØ· ÙÙØ§</a> ÙØ¹Ø±Ø¶ Ù
+ÙØ®Øµ ÙØ­Ø§ÙØ© ØšÙØ§Ø¡ ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©.
+}  
+
+_textdescrcollection_ [l=ar] {}
+_textdescrabout_ [l=ar] {ØªØ¹Ø±ÙÙ}
+_textdescrhome_ [l=ar] {Ø§ÙØµÙØ­Ø© Ø§ÙØ±ØŠÙØ³ÙØ©}
+_textdescrhelp_ [l=ar] {ØµÙØ­Ø© Ø§ÙÙ
+Ø³Ø§Ø¹Ø¯Ø©}
+_textdescrpref_ [l=ar] {ØµÙØ­Ø© Ø§ÙØ®ÙØ§Ø±Ø§Øª}
+_textdescrgreenstone_ [l=ar] {ØšØ±ÙØ§Ù
+Ø¬ Ø§ÙÙ
+ÙØªØšØ© Ø§ÙØ±ÙÙ
+ÙØ© Greenstone}
+_textdescrusab_ [l=ar] {Ù
+Ø§ Ø§ÙØ¬Ø²Ø¡ Ø§ÙØ°Ù ÙØ¬Ø¯ØªÙ ØµØ¹Øš Ø§ÙØ§Ø³ØªØ®Ø¯Ø§Ù
+ ?}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=ar] {ØšØ­Ø«}  
+_labelSearch_ [l=ar] {ØšØ­Ø«}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=ar] {Ø§ÙØ¹ÙÙØ§Ù}  
+_labelTitle_ [l=ar] {Ø§ÙØ¹ÙØ§ÙÙÙ}  
+_textCreator_ [l=ar] {Ø§ÙÙ
+ÙØŽÙØ¡}  
+_labelCreator_ [l=ar] {Ø§ÙÙ
+Ø€ÙÙÙÙ}  
+_textSubject_ [l=ar] {Ø§ÙÙ
+ÙØ¶ÙØ¹}  
+_labelSubject_ [l=ar] {Ø§ÙÙ
+ÙØ¶ÙØ¹Ø§Øª}
+_textDescription_ [l=ar] {ÙØµÙ}  
+_labelDescription_ [l=ar] {Ø§ÙØ§ÙØµØ§Ù}  
+_textPublisher_ [l=ar] {Ø§ÙÙØ§ØŽØ±}  
+_labelPublisher_ [l=ar] {Ø§ÙÙØ§ØŽØ±ÙÙ}  
+_textContributor_ [l=ar] {Ø§ÙÙ
+ØŽØ§Ø±ÙÙÙ}  
+_labelContributor_ [l=ar] {Ø§ÙÙ
+Ø³Ø§ÙÙ
+ÙÙ}  
+_textDate_ [l=ar] {Ø§ÙØªØ§Ø±ÙØ®}  
+_labelDate_ [l=ar] {Ø§ÙØªÙØ§Ø±ÙØ®}
+_textType_ [l=ar] {ÙÙØ¹}  
+_labelType_ [l=ar] {Ø£ÙÙØ§Ø¹}  
+_textFormat_ [l=ar] {ÙÙØ¹ Ø§ÙÙ
+ÙÙ}  
+_labelFormat_ [l=ar] {Ø£ØŽÙØ§Ù}  
+_textIdentifier_ [l=ar] {Ø§ÙÙ
+Ø­Ø¯Ø¯}  
+_labelIdentifier_ [l=ar] {Ø§ÙÙ
+Ø¹Ø±ÙÙÙ }  
+_textSource_ [l=ar] {Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙ}  
+_labelSource_ [l=ar] {Ø§Ø³Ù
+Ø§Ø¡ Ø§ÙÙ
+ÙÙØ§Øª}
+_textLanguage_ [l=ar] {ÙØºØ©}  
+_labelLanguage_ [l=ar] {Ø§ÙÙØºØ©}
+_textRelation_ [l=ar] {Ø¹ÙØ§ÙØ©}  
+_labelRelation_ [l=ar] {Ø¹ÙØ§ÙØ§Øª}  
+_textCoverage_ [l=ar] {Ø§ÙØªØºØ·ÙØ©}  
+_labelCoverage_ [l=ar] {Ø§ÙØºÙØ§Ù}  
+_textRights_ [l=ar] {Ø­ÙÙÙ}  
+_labelRights_ [l=ar] {Ø§ÙØ­ÙÙÙ}  
+
+# DLS metadata set
+_textOrganization_ [l=ar] {Ø§ÙÙ
+ÙØžÙ
+Ø©}  
+_labelOrganization_ [l=ar] {Ù
+ÙØžÙ
+Ø§Øª}  
+_textKeyword_ [l=ar] {ÙÙÙ
+Ø© Ù
+ÙØªØ§Ø­ÙØ©}  
+_labelKeyword_ [l=ar] {Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙÙ
+ÙØªØ§Ø­ÙØ©}
+_textHowto_ [l=ar] {Ø¥Ø±ØŽØ§Ø¯Ø§Øª}  
+_labelHowto_ [l=ar] {Ø¥Ø±ØŽØ§Ø¯Ø§Øª}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=ar] {Ø¹ØšØ§Ø±Ø©}  
+_labelPhrase_ [l=ar] {Ø§ÙØ¹ØšØ§Ø±Ø§Øª}  
+_textCollage_ [l=ar] {Collage}  
+_labelCollage_ [l=ar] {Collage}  
+_textBrowse_ [l=ar] {ØªØµÙØ­}  
+_labelBrowse_ [l=ar] {ØªØµÙØ­}  
+_textTo_ [l=ar] {Ø¥ÙÙ}  
+_labelTo_ [l=ar] {Ø¥ÙÙ}
+_textFrom_ [l=ar] {Ù
+Ù}  
+_labelFrom_ [l=ar] {Ù
+Ù}
+_textAcronym_ [l=ar] {Ø§ÙÙ
+Ø®ØªØµØ±Ø§Øª}  
+_labelAcronym_ [l=ar] {Ù
+Ø®ØªØµØ±Ø§Øª}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=ar] {ØªØµÙØ­ Ø¹Ù Ø·Ø±ÙÙ _1_}  
+
+_textdescrSearch_ [l=ar] {Ø§ÙØšØ­Ø« Ø¹Ù Ù
+ØµØ·ÙØ­ Ù
+Ø­Ø¯Ø¯}
+_textdescrType_ [l=ar] {Ø§ÙØªØµÙØ­ ØšÙÙØ¹ Ø§ÙÙ
+ØµØ¯Ø±}  
+_textdescrIdentifier_ [l=ar] {Ø§ÙØªØµÙØ­ ØšÙØ§Ø³Ø·Ø© Ù
+Ø¹Ø±Ù Ø§ÙÙ
+ØµØ¯Ø±}  
+_textdescrSource_ [l=ar] {ØªØµÙØ­ ØšØ§Ø³Ù
+ Ø§ÙÙ
+ÙÙ}  
+_textdescrTo_ [l=ar] {ØªØµÙØ­ ØšØ­ÙÙ "Ø¥ÙÙ"}  
+_textdescrFrom_ [l=ar] {ØªØµÙØ­ ØšØ­ÙÙ "Ù
+Ù"}  
+_textdescrCollage_ [l=ar] {ØªØµÙØ­ Ø¹Ù Ø·Ø±ÙÙ collage}  
+_textdescrAcronym_ [l=ar] {ØªØµÙØ­ Ø§ÙÙ
+Ø®ØªØµØ±Ø§Øª}  
+_textdescrPhrase_ [l=ar] {ØªØµÙØ­ Ø§ÙØ¹ØšØ§Ø±Ø§Øª}  
+_textdescrHowto_ [l=ar] {ØªØµÙØ­ Ø£ÙØ³Ø§Ù
+ "Ø¥Ø±ØŽØ§Ø¯Ø§Øª"}  
+_textdescrBrowse_ [l=ar] {ØªØµÙØ­ Ø§ÙÙØ«Ø§ØŠÙ}  
+_texticontext_ [l=ar] {Ø¹Ø±Ø¶ Ø§ÙÙØ«ÙÙØ©}
+_texticonclosedbook_ [l=ar] {ÙØªØ­ Ø§ÙÙØ«ÙÙØ© ÙØ¹Ø±Ø¶ Ø§ÙÙ
+Ø­ØªÙÙØ§Øª}
+_texticonnext_ [l=ar] {Ø§ÙÙØ³Ù
+ Ø§ÙØªØ§ÙÙ}
+_texticonprev_ [l=ar] {Ø§ÙÙØ³Ù
+ Ø§ÙØ³Ø§ØšÙ}
+
+_texticonworld_ [l=ar] {Ø¹Ø±Ø¶ Ø§ÙÙØ«ÙÙØ©}  
+
+_texticonmidi_ [l=ar] {Ø¹Ø±Ø¶ ÙØ«ÙÙØ© Ù
+Ù ÙÙØ¹ MIDI}
+_texticonmsword_ [l=ar] {Ø¹Ø±Ø¶ ÙØ«ÙÙØ© Ù
+Ù ÙÙØ¹ Microsoft Word}
+_texticonmp3_ [l=ar] {Ø¹Ø±Ø¶ Ù
+Ø³ØªÙØ¯ Ø§Ù
+ ØšÙ Ø«Ø±Ù}  
+_texticonpdf_ [l=ar] {Ø¹Ø±Ø¶ ÙØ«ÙÙØ© Ù
+Ù ÙÙØ¹ PDF}  
+_texticonps_ [l=ar] {Ø¹Ø±Ø¶ ÙØ«ÙÙØ© Ù
+Ù ÙÙØ¹ PostScrip}  
+_texticonppt_ [l=ar] {Ø¹Ø±Ø¶ ÙØ«ÙÙØ© Ù
+Ù ÙÙØ¹ PowerPoint}  
+_texticonrtf_ [l=ar] {Ø¹Ø±Ø¶ ÙØ«ÙÙØ© Ù
+Ù ÙÙØ¹ RTF}  
+_texticonxls_ [l=ar] {Ø¹Ø±Ø¶ ÙØ«ÙÙØ© Ù
+Ù ÙÙØ¹  Excel}  
+
+_page_ [l=ar] {Ø§ÙØµÙØ­Ø©}
+_pages_ [l=ar] {Ø§ÙØµÙØ­Ø§Øª}
+_of_ [l=ar] {Ù
+Ù }
+_vol_ [l=ar] {Ù
+Ø¬ÙØ¯}
+_num_ [l=ar] {Ø±ÙÙ
+}
+
+_textmonth00_ [l=ar] {}
+_textmonth01_ [l=ar] {ÙÙØ§ÙØ±}
+_textmonth02_ [l=ar] {ÙØšØ±Ø§ÙØ±}
+_textmonth03_ [l=ar] {Ù
+Ø§Ø±Ø³}
+_textmonth04_ [l=ar] {Ø£ØšØ±ÙÙ}
+_textmonth05_ [l=ar] {Ù
+Ø§ÙÙ}
+_textmonth06_ [l=ar] {ÙÙÙÙÙ}
+_textmonth07_ [l=ar] {ÙÙÙÙÙ}
+_textmonth08_ [l=ar] {Ø£ØºØ³Ø·Ø³}
+_textmonth09_ [l=ar] {Ø³ØšØªÙ
+ØšØ±}
+_textmonth10_ [l=ar] {Ø£ÙØªÙØšØ±}
+_textmonth11_ [l=ar] {ÙÙÙÙ
+ØšØ±}
+_textmonth12_ [l=ar] {Ø¯ÙØ³Ù
+ØšØ±}
+
+_textdocument_ [l=ar] {Ø§ÙÙØ«ÙÙØ©}
+_textsection_ [l=ar] {Ø§ÙÙØ³Ù
+}
+_textparagraph_ [l=ar] {ÙÙØ±Ø©}
+_textchapter_ [l=ar] {ÙØµÙ}
+_textbook_ [l=ar] {ÙØªØ§Øš}
+
+_magazines_ [l=ar] {Ø§ÙÙ
+Ø¬ÙØ§Øª}
+
+_nzdlpagefooter_ [l=ar] {<div class="divbar">&nbsp;</div>
+<p><a href="_gwcgi_">Ù
+ØŽØ±ÙØ¹ Ø§ÙÙ
+ÙØªØšØ© Ø§ÙØ¥ÙÙÙØªØ±ÙÙÙØ© - ÙÙÙØ²ÙÙØ§ÙØ¯Ø§</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">ÙØ³Ù
+ Ø¹ÙÙÙ
+ Ø§ÙØ­Ø§Ø³Øš</a>, 
+<a href="http://www.waikato.ac.nz">Ø¬Ø§Ù
+Ø¹Ø© ÙØ§ÙÙØ§ØªÙ</a>, ÙÙÙØ²ÙÙØ§ÙØ¯Ø§}
+
+_linktextHOME_ [l=ar] {Ø§ÙØ±ØŠÙØ³ÙØ©}
+_linktextHELP_ [l=ar] {Ù
+Ø³Ø§Ø¹Ø¯Ø©}
+_linktextPREFERENCES_ [l=ar] {Ø§ÙØ®ÙØ§Ø±Ø§Øª}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=ar] {Ø§ÙÙ
+ÙØªØšØ© Ø§ÙØ±ÙÙ
+ÙØ© Greenstone}  
+
+_textnocollections_ [l=ar] {ØºÙØ± ØµØ§ÙØ­(Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù ØšÙØ§Ø¡ ÙÙØŽØ±) Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ù
+ØªØ§Ø­Ø©}  
+
+_textadmin_ [l=ar] {ØµÙØ­Ø© Ø§ÙØ¥Ø¯Ø§Ø±Ø©}  
+_textabgs_ [l=ar] {Ø¹Ù ØšØ±ÙØ§Ù
+Ø¬ Greenstone}  
+_textgsdocs_ [l=ar] {ÙØ«Ø§ØŠÙ Greenstone}  
+
+_textdescradmin_ [l=ar] {ØªÙ
+ÙÙÙ Ù
+Ù Ø¥Ø¶Ø§ÙØ© Ù
+Ø³ØªØ®Ø¯Ù
+ÙÙ Ø¬Ø¯Ø¯Ø ÙØ¥Ø¹Ø·Ø§Ø¡ ØªØ¹ÙÙÙ
+Ø§Øª ÙÙÙØ© Ø¹Ù Ø¹Ù
+ÙÙØ© ØªØ«ØšÙØª ØšØ±ÙØ§Ù
+Ø¬ Greenstone}  
+
+_textdescrgogreenstone_ [l=ar] {ØªØ®ØšØ±Ù Ø¹Ù ØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙÙ
+ØŽØ±ÙØ¹ Ø§ÙÙ
+ÙØªØšØ© Ø§ÙØ±ÙÙ
+ÙØ© ÙÙÙÙØ²ÙÙØ§ÙØ¯Ø§ Ø­ÙØ« ØšØ¯Ø£ Ø§ÙÙØžØ§Ù
+.}  
+
+_textdescrgodocs_ [l=ar] {Ø£Ø¯ÙØ© Greenstone}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=ar] {ÙØ§Ø¬ÙØ© Ø§ÙÙ
+ÙØªØšÙ}  
+_textdescrgli_ [l=ar] {ÙØ³Ø§Ø¹Ø¯Ù ÙØ¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ø¬Ø¯ÙØ¯Ø©Ø Ø£Ù ØªØ¹Ø¯ÙÙ ÙØ¥Ø¶Ø§ÙØ© Ø¥ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ù
+ÙØ¬ÙØ¯Ø© ÙØ¹ÙØ§Ø Ø£Ù Ø­Ø°Ù Ù
+Ø¬Ù
+ÙØ¹Ø§Øª.}  
+
+package collector
+
+_textcollector_ [l=ar] {Ø§ÙÙ
+Ø¬Ù
+Ø¹}  
+_textdescrcollector_ [l=ar] {ÙØ³ØšÙ ÙØ°Ø§ ÙØ§Ø¬ÙØ© Ù
+ÙØªØšÙ Greenstone  ÙÙÙØ£ØºØ±Ø§Ø¶ Ø§ÙØ¹Ù
+ÙÙØ©Ø ÙØ¬Øš Ø§Ø³ØªØ®Ø¯Ø§Ù
+ ÙØ§Ø¬ÙØ© Ù
+ÙØªØšÙ Greenstone ØšØ¯ÙØ§ Ù
+Ù Ø§ÙÙ
+Ø¬Ù
+Ø¹..}  
+
+package depositor
+
+_textdepositor_ [l=ar] {Ø§ÙÙ
+ÙØ¯Ø¹}  
+_textdescrdepositor_ [l=ar] {ÙØ³Ø§Ø¹Ø¯Ù Ø¹ÙÙ Ø¥Ø¶Ø§ÙØ© ÙØ«Ø§ØŠÙ Ø¥ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙÙ
+ÙØ¬ÙØ¯Ø© ÙØ¹ÙØ§Ù}  
+
+package gti
+
+_textgti_ [l=ar] {ÙØ§Ø¬ÙØ© Ø§ÙÙ
+ØªØ±Ø¬Ù
+ }  
+_textdescrtranslator_ [l=ar] {ÙØ³Ø§Ø¹Ø¯Ù Ø¹ÙÙ ØªØ­Ø¯ÙØ« Ø§ÙÙØ³Ø® Ù
+ØªØ¹Ø¯Ø¯Ø© Ø§ÙÙØºØ§Øª ÙÙØ§Ø¬ÙØ§Øª ØšØ±ÙØ§Ù
+Ø¬ Greenstone  }  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=ar] {Ø¹Ù ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}
+
+_textsubcols1_ [l=ar] {<p>Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙÙØ§Ù
+ÙØ© ØªØ­ØªÙÙ Ø¹ÙÙ  _1_ Ù
+Ø¬Ù
+ÙØ¹Ø© ÙØ±Ø¹ÙØ©. 
+ÙØ§ÙÙ
+ØªØ§Ø­ Ù
+ÙÙØ§ Ø­Ø§ÙÙØ§ ÙÙ:
+<blockquote>}
+
+_textsubcols2_ [l=ar] {</blockquote>
+ÙÙ
+ÙÙÙ ÙØ­Øµ Ø£Ù Ø§Ø³ØªØšØ¯Ø§Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙÙØ±Ø¹ÙØ© Ø§ÙØªÙ ØªØ³Ø®Ø¯Ù
+ÙØ§ Ø­Ø§ÙÙØ§Ù ÙØ°ÙÙ ÙÙ ØµÙØ­Ø© Ø§ÙØ®ÙØ§Ø±Ø§Øª}
+
+_titleabout_ [l=ar] {Ø­ÙÙ}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=ar] {Ø£ØºÙÙ ÙØ°Ø§ Ø§ÙÙØ³Ù
+ Ù
+Ù Ø§ÙÙ
+ÙØªØšØ©}
+_texticonclosedbookshelf_ [l=ar] {Ø§ÙØªØ­ ÙØ°Ø§ Ø§ÙÙØ³Ù
+ ÙØ§Ø¹Ø±Ø¶ Ø§ÙÙ
+Ø­ØªÙÙØ§Øª}
+_texticonopenbook_ [l=ar] {Ø£ØºÙÙ ÙØ°Ø§ Ø§ÙÙØªØ§Øš}
+_texticonclosedfolder_ [l=ar] {Ø§ÙØªØ­ ÙØ°Ø§ Ø§ÙØ³Ø¬Ù Ù Ø§Ø¹Ø±Ø¶ Ù
+Ø­ØªÙØ§Ù}
+_texticonclosedfolder2_ [l=ar] {Ø§ÙØªØ­ Ø§ÙÙØ³Ù
+ Ø§ÙÙØ±Ø¹Ù:}
+_texticonopenfolder_ [l=ar] {Ø£ØºÙÙ ÙØ°Ø§ Ø§ÙÙ
+Ø¬ÙØ¯}
+_texticonopenfolder2_ [l=ar] {Ø£ØºÙÙ Ø§ÙÙØ³Ù
+ Ø§ÙÙØ±Ø¹Ù:}
+_texticonsmalltext_ [l=ar] {Ø¹Ø±Ø¶ ÙØ°Ø§ Ø§ÙØ¬Ø²Ø¡ Ù
+Ù Ø§ÙÙØµ}
+_texticonsmalltext2_ [l=ar] {Ø¹Ø±Ø¶ Ø§ÙÙØµ:}
+_texticonpointer_ [l=ar] {Ø§ÙÙØ³Ù
+ Ø§ÙØ­Ø§ÙÙ}
+_texticondetach_ [l=ar] {Ø§ÙØªØ­ ÙØ°Ù Ø§ÙØµÙØ­Ø© ÙÙ ÙØ§ÙØ°Ø© Ø¬Ø¯ÙØ¯Ø©}
+_texticonhighlight_ [l=ar] {Ù
+ÙØ² Ù
+ØµØ·ÙØ­ Ø§ÙØšØ­Ø«}
+_texticonnohighlight_ [l=ar] {ÙØ§ ØªÙ
+ÙØ² Ù
+ØµØ·ÙØ­Ø§Øª Ø§ÙØšØ­Ø«}
+_texticoncontracttoc_ [l=ar] {Ø¥Ø®ÙØ§Ø¡ ØªÙØ§ØµÙÙ Ø§ÙÙ
+Ø­ØªÙÙØ§Øª}
+_texticonexpandtoc_ [l=ar] {Ø¹Ø±Ø¶ ØªÙØ§ØµÙÙ Ø§ÙÙ
+Ø­ØªÙÙØ§Øª}
+_texticonexpandtext_ [l=ar] {Ø¹Ø±Ø¶ ÙØ§Ù
+Ù Ø§ÙÙØµ}
+_texticoncontracttext_ [l=ar] {Ø¹Ø±Ø¶ Ø§ÙÙØµ ÙÙØ· ÙÙÙØ³Ù
+ Ø§ÙÙ
+Ø®ØªØ§Ø±}
+_texticonwarning_ [l=ar] {<b> ØªØ­Ø°ÙØ±: </b>}
+_texticoncont_ [l=ar] {ÙØ§ØµÙ}
+
+_textltwarning_ [l=ar] {<div class="buttons">_imagecont_</div>
+_iconwarning_ ØªÙ
+Ø¯ÙØ¯ Ø§ÙÙØµ Ø³ÙÙØªØ¬ Ø¹ÙÙ ÙÙ
+ ÙØšÙØ± Ù
+Ù Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙÙ
+Ø¹Ø±ÙØ¶Ø© Ø¯Ø§Ø®Ù ÙØ°Ø§ Ø§ÙÙ
+ØªØµÙØ­
+}
+
+_textgoto_ [l=ar] {Ø§Ø°ÙØš Ø¥ÙÙ Ø§ÙØµÙØ­Ø©}
+_textintro_ [l=ar] {<i>(ØªÙØ¯ÙÙ
+)</i>}
+
+_textCONTINUE_ [l=ar] {ÙØ§ØµÙ?}
+
+_textEXPANDTEXT_ [l=ar] {ØªÙ
+Ø¯ÙØ¯\nØ§ÙÙØµ}  
+
+_textCONTRACTCONTENTS_ [l=ar] {ØªÙÙÙØµ ÙØ§ØŠÙ
+Ø©\nØ§ÙÙ
+Ø­ØªÙÙØ§Øª}  
+
+_textDETACH_ [l=ar] {ÙØ§ÙØ°Ø© Ø¬Ø¯ÙØ¯Ø©}
+
+_textEXPANDCONTENTS_ [l=ar] {ØªÙ
+Ø¯ÙØ¯ ÙØ§ØŠÙ
+Ø©\nØ§ÙÙ
+Ø­ØªÙÙØ§Øª}  
+
+_textCONTRACT_ [l=ar] {ØªÙÙÙØµ Ø§ÙÙØµ}  
+
+_textHIGHLIGHT_ [l=ar] {Ø§ÙØªÙ
+ÙÙØ²}  
+
+_textNOHIGHLIGHT_ [l=ar] {Ø¹Ø¯Ù
+ Ø§ÙØªÙ
+ÙÙØ²}  
+
+_textPRINT_ [l=ar] {Ø·ØšØ§Ø¹Ø©}  
+
+_textnextsearchresult_ [l=ar] {ÙØªÙØ¬Ø© Ø§ÙØšØ­Ø« Ø§ÙØªØ§ÙÙØ©}  
+_textprevsearchresult_ [l=ar] {ÙØªÙØ¬Ø© Ø§ÙØšØ­Ø« Ø§ÙØ³Ø§ØšÙØ©}  
+
+# macros for printing page
+_textreturnoriginal_ [l=ar] {Ø§ÙØ¹ÙØ¯Ø© ÙÙØµÙØ­Ø© Ø§ÙØ£ØµÙÙØ©}  
+_textprintpage_ [l=ar] {Ø·ØšØ§Ø¹Ø© ÙØ°Ù Ø§ÙØµÙØ­Ø©}  
+_textshowcontents_ [l=ar] {Ø¹Ø±Ø¶ ÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+Ø­ØªÙÙØ§Øª}  
+_texthidecontents_ [l=ar] {Ø¥Ø®ÙØ§Ø¡ ÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+Ø­ØªÙÙØ§Øª}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=ar] {_If_(_thislast_ ÙØªØ§ØŠØ¬ _thisfirst_ _thislast_ Ø§ÙØšØ­Ø« :  _cgiargq_, ÙØ§ ÙÙØ¬Ø¯ Ù
+Ø·Ø§ØšÙØ© ÙÙØšØ­Ø«  _cgiargq_)}
+_textnoquerytitle_ [l=ar] {ØµÙØ­Ø© Ø§ÙØšØ­Ø«}
+
+_textsome_ [l=ar] {ØšØ¹Ø¶}
+_textall_ [l=ar] {ÙÙ}
+_textboolean_ [l=ar] {ØšÙÙÙÙÙ}
+_textranked_ [l=ar] {Ù
+ØµÙÙ}
+_textnatural_ [l=ar] {Ø§ÙØ·ØšÙØ¹ÙØ©}
+_textsortbyrank_ [l=ar] {ØªØ±ØªÙØš Ø§ÙØµÙØ§Ø­ÙØ©}  
+_texticonsearchhistorybar_ [l=ar] {ØªØ§Ø±ÙØ® Ø§ÙØšØ­Ø«}
+
+_textifeellucky_ [l=ar] {Ø¶Ø±ØšØ© Ø­Øž !}  
+
+#alt text for query buttons
+_textusequery_ [l=ar] {Ø§Ø³ØªØ®Ø¯Ù
+ ÙØ°Ø§ Ø§ÙØšØ­Ø«}
+_textfreqmsg1_ [l=ar] {Ø¹Ø¯Ø¯ Ø§ÙØ¥ØµØ§ØšØ§Øª: }  
+_textpostprocess_ [l=ar] {_If_(_quotedquery_,<br><i> ØªÙ
+ ØªØ¬ÙÙØ²Ù ÙØ¥ÙØ¬Ø§Ø¯ _quotedquery_</i>
+)}
+_textinvalidquery_ [l=ar] {Ø®Ø·Ø£ ÙÙ ØµÙØ§ØºØ© Ø§ÙØšØ­Ø«}
+_textstopwordsmsg_ [l=ar] {Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙØªØ§ÙÙØ© ØŽØ§ØŠØ¹Ø© Ø¬Ø¯Ø§ ÙÙØ¯ ØªÙ
+ ØªØ¬Ø§ÙÙÙØ§:}  
+_textlucenetoomanyclauses_ [l=ar] {ÙØ­ØªÙÙ Ø·ÙØšÙ Ø¹ÙÙ Ø¹Ø¯Ø¯ ÙØšÙØ± Ù
+Ù Ù
+ØµØ·ÙØ­Ø§Øª Ø§ÙØšØ­Ø«Ø ÙØ¶ÙØ§Ù ÙÙ
+ ØšØªØ­Ø¯ÙØ¯ Ø·ÙØšÙ Ø£ÙØ«Ø±.}  
+
+_textmorethan_ [l=ar] {Ø£ÙØ«Ø± Ù
+Ù}
+_textapprox_ [l=ar] {Ø­ÙÙ}
+_textnodocs_ [l=ar] {ÙØ§ ØªÙØ¬Ø¯ ÙØ«Ø§ØŠÙ ØªØ·Ø§ØšÙ Ø§ÙØšØ­Ø«}  
+_text1doc_ [l=ar] {ÙØ«ÙÙØ© ÙØ§Ø­Ø¯Ø© ØªØ·Ø§ØšÙ Ø§ÙØšØ­Ø«}
+_textlotsdocs_ [l=ar] {Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ØªØ·Ø§ØšÙ Ø§ÙØšØ­Ø«.}  
+_textmatches_ [l=ar] {Ø§ÙÙ
+Ø·Ø§ØšÙØ§Øª}
+_textbeginsearch_ [l=ar] {Ø§ØšØ¯Ø£ Ø§ÙØšØ­Ø«}
+_textrunquery_ [l=ar] {ØªÙÙÙØ° Ø§ÙØšØ­Ø«}  
+_textclearform_ [l=ar] {Ù
+Ø³Ø­ Ø§ÙØšÙØ§ÙØ§Øª}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=ar] {Ø§ÙÙÙÙ
+Ø§Øª}  
+_textinfield_ [l=ar] {... ÙÙ Ø­ÙÙ}  
+_textfoldstem_ [l=ar] {(Ù
+ØºÙÙØ Ù
+ÙØ±Ø¹)}  
+
+_textadvquery_ [l=ar] {Ø£Ù Ø§Ø¯Ø®Ù Ø§ÙØšØ­Ø« Ù
+ØšØ§ØŽØ±Ø© :}  
+_textallfields_ [l=ar] {ÙÙ Ø§ÙØ­ÙÙÙ}  
+_texttextonly_ [l=ar] {ÙØµ ÙÙØ·}
+_textand_ [l=ar] {Ù}  
+_textor_ [l=ar] {Ø£Ù}  
+_textandnot_ [l=ar] {ÙÙÙØ³}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=ar] {Ø§ØšØ­Ø« _indexselection_ _If_(_jselection_, Ù
+Ø±ØªØšØ·Ø© ØšÙ _jselection_ )_If_(_gselection_, ÙÙ _gselection_ Ù
+Ø³ØªÙÙ )_If_(_nselection_,ÙÙ _nselection_ ÙØºØ© )Ø§ÙØªÙ ØªØ­ØªÙÙ Ø¹ÙÙ _querytypeselection_ Ù
+Ù Ø§ÙÙÙÙ
+Ø§Øª_If_(_sfselection_,\,_allowformbreak_ ÙØ±Ø² Ø§ÙÙØªØ§ØŠØ¬ ØšÙØ§Ø³Ø·Ø© _sfselection_)
+}  
+
+_textadvancedsearch_ [l=ar] {Ø§ØšØ­ÙØ« _indexselection_ _If_(_jselection_,Ù
+Ù _jselection_)_If_(_gselection_,ÙÙ Ù
+Ø³ØªÙÙ _gselection_ )_If_(_nselection_,ÙÙ ÙØºØ© _nselection_ )Ø§ÙØªÙ ØªØ­ØªÙÙ Ø¹ÙÙ Ø§ÙÙÙÙ
+Ø§Øª_querytypeselection_}
+
+_textadvancedmgppsearch_ [l=ar] {Ø§ØšØ­Ø« _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,ÙÙ _gselection_ Ù
+Ø³ØªÙÙ )_If_(_nselection_,in _nselection_ ÙØºØ© ) Ù Ø£Ø¹Ø±Ø¶ Ø§ÙÙØªØ§ØŠØ¬ ÙÙ ØªØ±ØªÙØš  _formquerytypeadvancedselection_}  
+
+_textadvancedlucenesearch_ [l=ar] {Ø§ÙØšØ­Ø« _indexselection__If_(_jselection_, Ù
+Ù _jselection_) _If_(_gselection_, ÙÙ _gselection_ Ù
+Ø³ØªÙÙ)_If_(_nselection_, ÙÙ _nselection_ ÙØºØ©)_If_(_sfselection_,\,_allowformbreak_ ÙØ±Ø² Ø§ÙÙØªØ§ØŠØ¬ Øš _sfselection_\,) ÙÙ }  
+
+_textformsimplesearch_ [l=ar] {Search_If_(_jselection_, _jselection_)_If_(_gformselection_, ÙÙ _gformselection_ Ù
+Ø³ØªÙÙ)_If_(_nselection_, ÙÙ _nselection_ ÙØºØ©)_If_(_sfselection_,\, ÙØ±Ø² Ø§ÙÙØªØ§ØŠØ¬ ØšÙØ§Ø³Ø·Ø© _sfselection_\,) ÙÙ _formquerytypesimpleselection_ Ù
+Ù}  
+
+_textformadvancedsearchmgpp_ [l=ar] {Search_If_(_jselection_,_jselection_ )_If_(_gformselection_, ÙÙ  _gformselection_ Ù
+Ø³ØªÙÙ )_If_(_nselection_, ÙÙ _nselection_ ÙØºØ© ) ÙØ§Ø¹Ø±Ø¶ ÙØªØ§ØŠØ¬ Ø§ÙØšØ­Ø« ÙÙ Ø§ÙØªØ±ØªÙØš  _formquerytypeadvancedselection_}  
+
+_textformadvancedsearchlucene_ [l=ar] {Search _If_(_jselection_, _jselection_)_If_(_gformselection_,  ÙÙ _gformselection_ level)_If_(_nselection_, ÙÙ  _nselection_ language)_If_(_sfselection_,\, ÙØ±Ø² Ø§ÙÙØªØ§ØŠØ¬ ØšÙØ§Ø³Ø·Ø© _sfselection_\,) Ù}  
+
+_textnojsformwarning_ [l=ar] {ØªØ­Ø°ÙØ±: Javascript ØºÙØ± Ù
+Ù
+ÙÙ ØªØŽØºÙÙÙ Ø§ÙØ¢Ù Ø ÙØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙØšØ­Ø« ÙÙ
+ ØšØªØŽØºÙÙÙ Ø£ÙÙØ§Ù.}
+_textdatesearch_ [l=ar] {ÙÙ
+ÙÙ Ø§ÙØšØ­Ø« ÙÙ ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø¹Ù Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ÙÙØ§ Ù
+Ø¯Ù ØªØ§Ø±ÙØ®Ù Ø Ø£Ù Ø§ÙØªÙ ØªØ­ØªÙÙ Ø¹ÙÙ ØªØ§Ø±ÙØ® Ù
+Ø­Ø¯Ø¯. ÙÙÙ Ø£Ù
+Ø± Ø§Ø®ØªÙØ§Ø±Ù ÙÙ Ø¹Ù
+ÙÙØ© Ø§ÙØšØ­Ø«}  
+_textstartdate_ [l=ar] {ØšØ¯Ø§ÙØ© Ù
+Ù (Ø£Ù ØšØªØ§Ø±ÙØ®) :}
+_textenddate_ [l=ar] {ØªØ§Ø±ÙØ® Ø§ÙÙÙØ§ÙØ© :}
+_textbc_ [l=ar] {B.C.E.}
+_textad_ [l=ar] {C.E.}
+_textexplaineras_ [l=ar] {C.E. and B.C.E are alternatives for A.D. and B.C. respectively.  These terms are considered to be culture indiscriminate, and stand for "Common Era" and "Before the Common Era"}  
+
+_textstemon_ [l=ar] {(ØªØ¬Ø§ÙÙ ÙÙØ§ÙØ§Øª Ø§ÙÙÙÙ
+Ø§Øª)}
+
+_textsearchhistory_ [l=ar] {ØªØ§Ø±ÙØ® Ø§ÙØšØ­Ø«}
+
+#text macros for search history
+_textnohistory_ [l=ar] {ØªØ§Ø±ÙØ® Ø§ÙØšØ­Ø« ÙÙØ³ Ù
+ØªÙØ§ÙØ±}
+_texthresult_ [l=ar] {Ø§ÙÙØªÙØ¬Ø©}
+_texthresults_ [l=ar] {Ø§ÙÙØªØ§ØŠØ¬}
+_texthallwords_ [l=ar] {ÙÙ Ø§ÙÙÙÙ
+Ø§Øª}
+_texthsomewords_ [l=ar] {ØšØ¹Ø¶ Ø§ÙÙÙÙ
+Ø§Øª}
+_texthboolean_ [l=ar] {ØšÙÙÙÙÙ}
+_texthranked_ [l=ar] {Ù
+ØµÙÙ}
+_texthcaseon_ [l=ar] {Ø­Ø§ÙØ© Ø§ÙØ£Ø­Ø±Ù}
+_texthcaseoff_ [l=ar] {Ù
+ØºÙÙ}
+_texthstemon_ [l=ar] {Ù
+ÙØ±Ø¹}
+_texthstemoff_ [l=ar] {ØºÙØ± Ù
+ÙØ±Ø¹}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=ar] {ØªÙ
+ Ø¶ØšØ· Ø§ÙØ®ÙØ§Ø±Ø§Øª . ÙØ§ ØªØ³ØªØ®Ø¯Ù
+ Ø²Ø± Ø§ÙØªØ±Ø§Ø¬Ø¹ Ø­ØªÙ ÙØ§ ØªÙØºÙ Ø®ÙØ§Ø±Ø§ØªÙ Ø§ÙØ¬Ø¯ÙØ¯Ø©. ÙÙ
+ÙÙ Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø£Ù Ù
+Ù Ø§ÙØ£Ø²Ø±Ø§Ø± Ø§ÙÙ
+ÙØ¬ÙØ¯Ø© ÙÙ Ø§ÙØµÙØ­Ø©}
+_textsetprefs_ [l=ar] {Ø¶ØšØ· Ø§ÙØ®ÙØ§Ø±Ø§Øª}
+_textsearchprefs_ [l=ar] {Ø®ÙØ§Ø±Ø§Øª Ø§ÙØšØ­Ø«}
+_textcollectionprefs_ [l=ar] {Ø®ÙØ§Ø±Ø§Øª Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}
+_textpresentationprefs_ [l=ar] {Ø®ÙØ§Ø±Ø§Øª Ø§ÙØ¹Ø±Ø¶}
+_textpreferences_ [l=ar] {Ø§ÙØ®ÙØ§Ø±Ø§Øª}
+_textcasediffs_ [l=ar] {Ø­Ø§ÙØ© Ø§ÙØ£Ø­Ø±Ù:}
+_textignorecase_ [l=ar] {ØªØ¬Ø§ÙÙ Ø­Ø§ÙØ© Ø§ÙØ£Ø­Ø±Ù}
+_textmatchcase_ [l=ar] {ØªØ·Ø§ØšÙ Ø­Ø§ÙØ© Ø§ÙØ£Ø­Ø±Ù (ÙØšÙØ±Ø©/ØµØºÙØ±Ø©)}
+_textwordends_ [l=ar] {ÙÙØ§ÙØ§Øª Ø§ÙÙÙÙ
+Ø§Øª :}  
+_textstem_ [l=ar] {ØªØ¬Ø§ÙÙ ÙÙØ§ÙØ§Øª Ø§ÙÙÙÙ
+Ø§Øª}
+_textnostem_ [l=ar] {ØªØ·Ø§ØšÙ ÙØ§Ù
+Ù Ø§ÙÙÙÙ
+Ø© }
+_textaccentdiffs_ [l=ar] {Ø§Ø®ØªÙØ§ÙØ§Øª Ø§ÙØªØŽÙÙÙ Ø¹ÙÙ Ø§ÙØ£Ø­Ø±Ù:}  
+_textignoreaccents_ [l=ar] {ØªØ¬Ø§ÙÙ Ø§ÙØªØŽÙÙÙ Ø¹ÙÙ Ø§ÙØ­Ø±ÙÙ}  
+_textmatchaccents_ [l=ar] {ÙØ¬Øš Ù
+Ø¶Ø§ÙØ§Ø© Ø§ÙØªØŽÙÙÙ Ø¹ÙÙ Ø§ÙØ­Ø±ÙÙ}  
+
+_textprefop_ [l=ar] {Ø¹Ø¯Ø¯ Ø§ÙØªØ³Ø¬ÙÙØ§Øª Ø§ÙÙ
+Ø³ØªØ±Ø¬Ø¹Ø©_maxdocoption_ ØªØ³Ø¬ÙÙØ© Ø Ø§Ø¹Ø±Ø¶ _hitsperpageoption_ ØªØ³Ø¬ÙÙØ© ÙÙ Ø§ÙØµÙØ­Ø©.}  
+_textextlink_ [l=ar] {Ø§ÙÙØµÙÙ Ø¥ÙÙ ØµÙØ­Ø© ÙÙØš Ø®Ø§Ø±Ø¬ÙØ©}
+_textintlink_ [l=ar] {Ù
+ØµØ¯Ø± Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙÙ
+Ø³ØªØ±Ø¬Ø¹Ø© Ù
+Ù :}  
+_textlanguage_ [l=ar] {ÙØºØ© ÙØ§Ø¬ÙØ© Ø§ÙØ§Ø³ØªØ®Ø¯Ø§Ù
+:}
+_textencoding_ [l=ar] {ÙØžØ§Ù
+ Ø§ÙØªØ±Ù
+ÙØ²}
+_textformat_ [l=ar] {ÙÙ
+Ø· ÙØ§Ø¬ÙØ© Ø§ÙØ§Ø³ØªØ®Ø¯Ø§Ù
+:}
+_textall_ [l=ar] {ÙÙ}
+_textquerymode_ [l=ar] {ÙÙ
+Ø· Ø§ÙØšØ­Ø« :}  
+_textsimplemode_ [l=ar] {ÙÙ
+Ø· Ø§ÙØšØ­Ø« Ø§ÙØšØ³ÙØ·}
+_textadvancedmode_ [l=ar] {Ø§ÙØšØ­Ø« Ø§ÙÙ
+ØªÙØ¯Ù
+ (ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙØšØ­Ø« Ø§ÙØšÙÙÙÙÙ ØšØ§ÙØ¹ÙØ§Ù
+Ø§Øª |Ø &Ø !Ø ÙØ§ÙØ£ÙÙØ§Ø³)}
+_textlinkinterm_ [l=ar] {Ø¹ØšØ± ØµÙØ­Ø© ÙØ³ÙØ·Ø©}
+_textlinkdirect_ [l=ar] {Ø§ÙØ°ÙØ§Øš Ù
+ØšØ§ØŽØ±Ø©}
+_textdigitlib_ [l=ar] {Ø§ÙÙ
+ÙØªØšØ© Ø§ÙØ±ÙÙ
+ÙØ©}
+_textweb_ [l=ar] {Ø§ÙÙÙØš}
+_textgraphical_ [l=ar] {Ø±Ø³ÙÙ
+Ù}
+_texttextual_ [l=ar] {ÙØµÙ}
+_textcollectionoption_ [l=ar] {<p>
+Ø§ÙÙØµÙÙ Ø§ÙÙØ±Ø¹ÙØ© ØªØ¶Ù
+ :
+<br>}
+
+_textsearchtype_ [l=ar] {Ø£Ø³ÙÙØš Ø§ÙØšØ­Ø«}  
+_textformsearchtype_ [l=ar] {Ø§ÙØ­ÙÙÙ ØšÙ _formnumfieldoption_}  
+_textplainsearchtype_ [l=ar] {Ù
+Ø±ØšØ¹ Ø§ÙØšØ­Ø« Ø§ÙØ¹Ø§Ø¯Ù  _boxsizeoption_}  
+_textregularbox_ [l=ar] {Ø³Ø·Ø± ÙØ§Ø­Ø¯}  
+_textlargebox_ [l=ar] {ÙØšÙØ±}  
+
+_textrelateddocdisplay_ [l=ar] {Ø¹Ø±Ø¶ Ø§ÙÙØ«Ø§ØŠÙ Ø°Ø§Øª Ø§ÙØ¹ÙØ§ÙØ©}  
+_textsearchhistory_ [l=ar] {ØªØ§Ø±ÙØ® Ø§ÙØšØ­Ø«:}  
+_textnohistory_ [l=ar] {ÙØ§ ÙÙØ¬Ø¯ ØªØ§Ø±ÙØ® ØšØ­Ø«}  
+_texthistorydisplay_ [l=ar] {Ø¹Ø±Ø¶ _historynumrecords_ ØªØ³Ø¬ÙÙØ§Øª ØªØ§Ø±ÙØ® Ø§ÙØšØ­Ø«}
+_textnohistorydisplay_ [l=ar] {ÙØ§ ØªØ¹Ø±Ø¶ ØªØ§Ø±ÙØ® Ø§ÙØšØ­Ø«}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=ar] {Ø±ØªØš Ø§ÙÙØ«Ø§ØŠÙ ØšÙ}  
+_textalsoshowing_ [l=ar] {Ø£ÙØ¶Ø§Ù Ø¹Ø±Ø¶}
+_textwith_ [l=ar] {Ù
+Ø¹ Ø¹ÙÙ Ø§ÙØ£ÙØ«Ø±}
+_textdocsperpage_ [l=ar] {ÙØ«Ø§ØŠÙ ÙÙØµÙØ­Ø© Ø§ÙÙØ§Ø­Ø¯Ø©}  
+
+_textfilterby_ [l=ar] {Ù
+Ø­ØªÙÙØ§Øª Ø§ÙÙØ«Ø§ØŠÙ}  
+_textall_ [l=ar] {ÙÙ}
+_textany_ [l=ar] {Ø£Ù}
+_textwords_ [l=ar] {Ù
+Ù Ø§ÙÙÙÙ
+Ø§Øª}
+_textleaveblank_ [l=ar] {Ø§ØªØ±Ù ÙØ°Ø§ Ø§ÙÙ
+Ø±ØšØ¹ ÙØ§Ø±ØºØ§Ù ÙØ§Ø³ØªØ±Ø¬Ø§Ø¹ ÙÙ Ø§ÙÙØ«Ø§ØŠÙ}  
+
+_browsebuttontext_ [l=ar] {"Ø±ØªØš Ø§ÙÙØ«Ø§ØŠÙ"}  
+
+_nodata_ [l=ar] {<i>ØšØ¯ÙÙ ØšÙØ§ÙØ§Øª</i>}
+_docs_ [l=ar] {Ø§ÙÙØ«Ø§ØŠÙ}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=ar] {Ù
+Ø³Ø§Ø¹Ø¯Ø©}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=ar] {ØªØµÙØ­ Ø§ÙÙØ«Ø§ØŠÙ Ø¹Ù Ø·Ø±ÙÙ _1_ ØšØ§ÙØ¶ØºØ· Ø¹ÙÙ Ø§ÙØ²Ø± _2_}  
+
+_textSearchhelp_ [l=ar] {Ø§ØšØ­Ø« Ø¹Ù ÙÙÙ
+Ø§Øª Ù
+Ø­Ø¯Ø¯Ø© ØªÙØ¬Ø¯ ÙÙ ÙØµ Ø§ÙÙØ«ÙÙØ© Ø¹Ù Ø·Ø±ÙÙ Ø§ÙØ¶ØºØ· Ø¹ÙÙ Ø²Ø± _labelSearch_}  
+_textTohelp_ [l=ar] {ØªØµÙØ­ Ø§ÙÙØ«Ø§ØŠÙ Ø¹Ù Ø­ÙÙ "Ø¥ÙÙ" ØšØ§ÙØ¶ØºØ· Ø¹ÙÙ Ø²Ø± _labelTo_}  
+_textFromhelp_ [l=ar] {ØªØµÙØ­ Ø§ÙØ¥ØµØ¯Ø§Ø±Ø§Øª Ø¹Ù Ø·Ø±ÙÙ Ø­ÙÙ  ØšØ§ÙØ¶ØºØ· Ø¹ÙÙ Ø§ÙØ²Ø±  _labelFrom_ }  
+_textBrowsehelp_ [l=ar] {ØªØµÙØ­ Ø§ÙÙØ«Ø§ØŠÙ}  
+_textAcronymhelp_ [l=ar] {ØªØµÙØ­ Ø§ÙÙØªØ§ØŠØ¬ Ø¹Ù Ø·Ø±ÙÙ Ø§ÙÙ
+Ø®ØªØµØ±Ø§Øª Ø§ÙÙ
+ÙØ¬ÙØ¯Ø© ØšØ§ÙØ¶ØºØ· Ø¹ÙÙ Ø²Ø± _labelAcronym_}  
+_textPhrasehelp_ [l=ar] {ØªØµÙØ­ Ø§ÙØ¹ØšØ§Ø±Ø§Øª Ø§ÙØªÙ ÙØ±Ø¯Øª ÙÙ Ø§ÙÙØ«Ø§ØŠÙ Ø¹Ù Ø·Ø±ÙÙ Ø§ÙØ¶ØºØ· Ø¹ÙÙ Ø²Ø± _labelPhrase_. }  
+
+_texthelptopicstitle_ [l=ar] {Ø§ÙÙ
+ÙØ¶ÙØ¹Ø§Øª}  
+
+_textreadingdocs_ [l=ar] {ÙÙÙ ØªÙØ±Ø£ Ø§ÙÙØ«Ø§ØŠÙ}  
+
+_texthelpreadingdocs_ [l=ar] {"<p>ÙØžÙØ± Ø¹ÙÙØ§Ù Ø§ÙÙØªØ§Øš ÙØµÙØ±Ø© Ø§ÙØºÙØ§Ù ÙÙ Ø£Ø¹ÙÙ ÙØ³Ø§Ø± Ø§ÙØµÙØ­Ø©. ÙÙÙ ØšØ¹Ø¶ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª ÙØµØ­Øš ÙØ°Ø§ ÙØ§ØŠÙ
+Ø© Ù
+Ø­ØªÙÙØ§Øª ÙÙÙ ØšØ¹Ø¶ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙØ£Ø®Ø±Ù ÙØµØ­Øš Ø°ÙÙ Ø±ÙÙ
+ Ø§ÙØµÙØ­Ø© Ø§ÙØ­Ø§ÙÙØ© Ù
+Ù Ø§ÙÙØªØ§Øš Ù
+Ø¹ Ø£Ø³ÙÙ
+ ØªÙ
+ÙÙÙ Ù
+Ù Ø§ÙØ§ØªØ¬Ø§Ù Ø¥ÙÙ Ø§ÙØ£Ù
+Ø§Ù
+ Ø£Ù Ø§ÙØ®ÙÙ. ÙÙ
+Ø§ Ø£Ù Ø§ÙÙØ³Ù
+ Ø§ÙØ­Ø§ÙÙ ÙÙÙÙ Ù
+Ù
+ÙØ² ØšØšÙØ· Ø£Ø³ÙØ¯ ÙÙ ÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+Ø­ØªÙÙØ§Øª. ÙÙÙ ØšØ¹Ø¶ Ø§ÙØ­Ø§ÙØ§Øª Ø§ÙØ£Ø®Ø±Ù ØªÙÙÙ ÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+Ø­ØªÙÙØ§Øª Ø§ÙÙ
+ØµØ§Ø­ØšØ© ÙØ§ØšÙØ© ÙÙØªÙ
+Ø¯ÙØ¯ Ø¹Ù Ø·Ø±ÙÙ Ø§ÙØ¶ØºØ· Ø¹ÙÙ Ø²Ø± Ø§ÙÙ
+Ø¬ÙØ¯.</p>
+
+<p>Ø¥ÙÙ Ø£Ø³ÙÙ Ù
+Ù ÙØ°Ø§ ÙÙØ¬Ø¯ Ø§ÙÙØµ Ø§ÙØ®Ø§Øµ ØšØ§ÙÙØ³Ù
+ Ø§ÙØ­Ø§ÙÙ. ÙØ¹ÙØ¯ ÙØ±Ø§Ø¡Ø© ÙØ°Ø§ Ø§ÙÙØµ Ø¥ÙÙ ÙÙØ§ÙØªÙØ Ø³ØªØ¬Ø¯ Ø£Ù ÙÙØ§Ù Ø£Ø³ÙÙ
+ ÙÙ ÙÙØ§ÙØ© Ø§ÙØµÙØ­Ø© ÙØªÙØªÙÙ ØšÙ Ø¥ÙÙ Ø§ÙÙØ³Ù
+ Ø§ÙØªØ§ÙÙ Ø£Ù Ø§ÙØ³Ø§ØšÙ Ù
+Ù ÙØ°Ø§ Ø§ÙÙØªØ§Øš.
+
+<p>ÙÙØ¬Ø¯ ØªØ­Øª Ø§ÙØ¹ÙÙØ§Ù Ø£Ù ØµÙØ±Ø© ØºÙØ§Ù Ø§ÙÙØªØ§Øš ØšØ¹Ø¶ Ø§ÙØ®ÙØ§Ø±Ø§ØªØ ØšØ§ÙØ¶ØºØ· Ø¹ÙÙ 
+<i>_document:textEXPANDTEXT_</i> ÙØ¹Ø±Ø¶ Ø§ÙÙØµ Ø§ÙØ®Ø§Øµ ØšØ§ÙÙØ³Ù
+ Ø£Ù Ø§ÙÙØªØ§Øš Ø§ÙØ­Ø§ÙÙ. ÙØ¥Ø°Ø§ ÙØ§Ù Ø§ÙÙØµ ÙÙ ÙØ°Ø§ Ø§ÙØ­Ø§ÙØ© ÙØšÙØ± ÙØ¥Ù ÙØ°Ø§ Ø§ÙØ¥Ø¬Ø±Ø§Ø¡ ÙØ¯ ÙØ£Ø®Ø° ÙÙØª Ø£Ø·ÙÙ ÙÙØ­ØªØ§Ø¬ Ø¥ÙÙ Ø°Ø§ÙØ±Ø© ÙÙ
+ØšÙÙØªØ± Ø£ÙØšØ±!Ø ÙØšØ§ÙØ¶ØºØ· Ø¹ÙÙ <i>_document:textEXPANDCONTENTS_</i>  Ø³ÙÙ ÙØªÙ
+ Ø¹Ø±Ø¶ ÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+Ø­ØªÙÙØ§Øª Ø§ÙØªÙØµÙÙÙØ© Ø§ÙÙØ§Ù
+ÙØ© ÙØ§ÙØªÙ ØªØŽÙ
+Ù Ø¹ÙØ§ÙÙÙ Ø§ÙÙØµÙÙ ÙØ§ÙØ£ÙØ³Ø§Ù
+ Ø§ÙÙØ±Ø¹ÙØ©. ÙØšØ§ÙØ¶ØºØ· Ø¹ÙÙ <i>_document:textDETACH_</i> ÙØªÙ
+ ÙØªØ­ Ø§ÙÙØ«ÙÙØ© ÙÙ ÙØ§ÙØ°Ø© Ø¬Ø¯ÙØ¯Ø© (ÙÙÙØ¯ ÙØ°Ø§ Ø§ÙØ®ÙØ§Ø± ÙÙ Ø­Ø§ÙØ© Ø§ÙÙ
+ÙØ§Ø±ÙØ© ØšÙÙ Ø¹Ø¯Ø© ÙØ«Ø§ØŠÙ Ø£Ù ÙØ±Ø§Ø¡Ø© ÙØ«ÙÙØªÙÙ ÙÙ ÙÙØ³ Ø§ÙÙÙØª.) ÙØ£Ø®ÙØ±Ø§Ù ÙØ¥Ù Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙØªÙ ÙØªÙ
+ Ø§ÙØšØ­Ø« ØšÙØ§ ØªÙÙÙ Ù
+Ù
+ÙØ²Ø© ÙÙ ÙØµ Ø§ÙÙØ«ÙÙØ©. ÙØšØ§ÙØ¶ØºØ· Ø¹ÙÙ<i>_document:textNOHIGHLIGHT_</i> ÙØ¥Ø²Ø§ÙØ© ØªÙ
+ÙÙØ² ÙØ°Ù Ø§ÙÙÙÙ
+Ø§Øª Ø¯Ø§Ø®Ù Ø§ÙÙØ«ÙÙØ© Ø§ÙÙ
+Ø¹Ø±ÙØ¶Ø© Ø­Ø§ÙÙØ§Ù.</p>
+"
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=ar] {ÙØªØ­ ÙØ°Ø§ Ø§ÙÙØ³Ù
+}
+_texthelpopenbook_ [l=ar] {ÙØªØ­/ØºÙÙ ÙØ°Ø§ Ø§ÙÙØªØ§Øš}
+_texthelpviewtextsection_ [l=ar] {Ø¹Ø±Ø¶ Ø§ÙÙØµ}
+_texthelpexpandtext_ [l=ar] {Ø¹Ø±Ø¶/Ø¥Ø®ÙØ§Ø¡ ÙÙ Ø§ÙÙØµ}
+_texthelpexpandcontents_ [l=ar] {Ø¹Ø±Ø¶/Ø¥Ø®ÙØ§Ø¡ ØªÙØ§ØµÙÙ Ø§ÙÙ
+Ø­ØªÙÙØ§Øª}
+_texthelpdetachpage_ [l=ar] {ÙØªØ­ ÙØ°Ù Ø§ÙØµÙØ­Ø© ÙÙ ÙØ§ÙØ°Ø© Ø¬Ø¯ÙØ¯Ø©}
+_texthelphighlight_ [l=ar] {Ù
+ÙØ² Ø£Ù ÙØ§ ØªÙ
+ÙØ² Ø§ÙÙ
+ØµØ·ÙØ­Ø§Øª Ø§ÙØªÙ ØªÙ
+ Ø§ÙØšØ­Ø« ØšÙØ§}  
+_texthelpsectionarrows_ [l=ar] {Ø¥Ø°ÙØš Ø¥ÙÙ Ø§ÙÙØ³Ù
+ Ø§ÙØ³Ø§ØšÙ/Ø§ÙØªØ§ÙÙ}  
+
+
+_texthelpsearchingtitle_ [l=ar] {ÙÙÙÙØ© Ø§ÙØšØ­Ø« Ø¹Ù ÙÙÙ
+Ø§Øª Ù
+Ø­Ø¯Ø¯Ø©}
+
+_texthelpsearching_ [l=ar] {<p>
+ Ù
+Ù ØµÙØ­Ø© Ø§ÙØšØ­Ø«Ø ÙÙ
+ ØšØ¥Ø¬Ø±Ø§Ø¡ Ø§ÙØšØ­Ø« ØšØ§ÙØ®Ø·ÙØ§Øª Ø§ÙØªØ§ÙÙØ©:<p>
+
+   <ol><li>Ø­Ø¯Ø¯ Ø§ÙÙ
+ØµØ·ÙØ­Ø§Øª Ø§ÙØªÙ ØªØ±ÙØ¯ ØšØ­Ø«ÙØ§
+       <li>Ø­Ø¯Ø¯ Ù
+Ø§ Ø¥Ø°Ø§ ÙÙØª ØªØ±ÙØ¯ Ø§ÙØšØ­Ø« ØšÙÙ Ø§ÙÙÙÙ
+Ø§Øª Ø£Ù ØšØ¹Ø¶ Ù
+ÙÙØ§
+       <li>Ø¥Ø¯Ø®Ù Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙØªÙ ØªØ±ÙØ¯ Ø§ÙØšØ­Ø« ØšÙØ§
+       <li>Ø§Ø¶ØºØ· Ø¹ÙÙ Ø²Ø± <i>Ø§ØšØ¯Ø£ Ø§ÙØšØ­Ø«</i> 
+   </ol>
+
+ <p>Ø¹ÙØ¯ Ø¥Ø¬Ø±Ø§Ø¡ Ø§ÙØšØ­Ø«Ø Ø³ØªØžÙØ± 20 ÙØ«ÙÙØ© Ù
+Ù Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ØªØ·Ø§ØšÙ Ø§ÙØšØ­Ø«. ÙÙØ§Ù Ø²Ø± ÙÙ ÙÙØ§ÙØ© Ø§ÙØµÙØ­Ø© ÙØ£Ø®Ø°Ù Ø¥ÙÙ Ø§ÙÙ 20 ÙØ«ÙÙØ© Ø§ÙØªØ§ÙÙØ©. ÙÙÙ Ø§ÙØµÙØ­Ø© Ø§ÙØªØ§ÙÙØ© ØªØ¬Ø¯ Ø²Ø± Ø£ÙØ¶Ø§Ù ÙØ£Ø®Ø°Ù ÙÙØµÙØ­Ø© Ø§ÙØ«Ø§ÙØ«Ø© ÙØ²Ø± Ø¢Ø®Ø± ÙØ¹ÙØ¯ ØšÙ ÙÙØµÙØ­Ø© Ø§ÙØ³Ø§ØšÙØ©. ÙØšØ§ÙØ¶ØºØ· Ø¹ÙÙ Ø¹ÙÙØ§Ù Ø£Ù Ù
+Ù Ø§ÙÙØ«Ø§ØŠÙ ÙØªÙ
+ Ø¹Ø±Ø¶ ÙØ°Ù Ø§ÙÙØ«ÙÙØ©.
+
+ <p>Ø§ÙØ­Ø¯ Ø§ÙØ£ÙØµÙ ÙØ¹Ø¯Ø¯ ÙØªØ§ØŠØ¬ Ø§ÙØšØ­Ø« ÙÙ 50 ÙØ«ÙÙØ©. ÙÙÙÙ ÙÙ
+ÙÙ ØªØºÙÙØ± ÙØ°Ø§ Ø§ÙØ±ÙÙ
+ ØšØ§ÙØ¶ØºØ· Ø¹ÙÙ Ø²Ø±
+   <i>_Global:linktextPREFERENCES_</i> Ø®ÙØ§Ø±Ø§Øª ÙÙ Ø£Ø¹ÙÙ Ø§ÙØµÙØ­Ø©.<p>  
+}  
+
+_texthelpquerytermstitle_ [l=ar] {Ù
+ØµØ·ÙØ­Ø§Øª Ø§ÙØšØ­Ø«}
+_texthelpqueryterms_ [l=ar] {<p> ØªÙØ³Ø± Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙØªÙ ÙØªÙ
+ Ø§ÙØšØ­Ø« ØšÙØ§ Ø¥ÙÙ "Ù
+ØµØ·ÙØ­Ø§Øª Ø§ÙØšØ­Ø«". ÙÙ Ù
+ØµØ·ÙØ­ ÙØ­ØªÙÙ Ø¹ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ù Ø§ÙØ£Ø­Ø±Ù ÙØ§ÙØ£Ø±ÙØ§Ù
+. ÙÙÙØµÙ ØšÙÙ Ø§ÙÙ
+ØµØ·ÙØ­Ø§Øª Ø§ÙÙ
+Ø³Ø§ÙØ© Ø§ÙØšÙØ¶Ø§Ø¡. ÙØ£Ù Ø¹ÙØ§ÙØ© ØªØ±ÙÙÙ
+ ØªØ¹ØªØšØ± Ù
+Ø³Ø§ÙØ© ØšÙØ¶Ø§Ø¡ ÙÙØªÙ
+ ØªØ¬Ø§ÙÙÙØ§ ÙÙ Ø¹Ù
+ÙÙØ© Ø§ÙØšØ­Ø« Ø£Ù Ø£ÙÙ ÙØ§ ÙÙ
+ÙÙ Ø§ÙØšØ­Ø« ØšØ£Ù Ù
+Ù Ø¹ÙØ§Ù
+Ø§Øª Ø§ÙØªØ±ÙÙÙ
+.
+
+<p>Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù Ø§ÙØšØ­Ø«<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>Ø³ÙÙ ØªØ¹Ø§Ù
+Ù Ø¹ÙÙ Ø£ÙÙØ§<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}
+
+_texthelpmgppsearching_ [l=ar] {ØšØ§ÙÙØ³ØšØ© ÙÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙØªÙ ØšÙÙØª ØšÙMGPP ÙØ¥Ù ÙÙØ§Ù Ù
+Ø²ÙØ¯ Ù
+Ù Ø§ÙØ®ÙØ§Ø±Ø§Øª Ø³ØªÙÙÙ Ù
+ØªØ§Ø­Ø©. 
+
+<ul>
+<li>Ø§ÙØ¹ÙØ§Ù
+Ø© <b>*</b> ÙÙ ÙÙØ§ÙØ© Ù
+ØµØ·ÙØ­ Ø§ÙØšØ­Ø« ØªØ³ØªØ±Ø¬Ø¹ ÙÙ Ø§ÙÙÙØ§Ù
+Ø§Øª Ø§ÙØªÙ<b>ØªØšØ¯Ø£ </b> ØšÙØ°Ù Ø§ÙÙÙÙ
+Ø©, ÙÙ
+Ø«ÙØ§Ù: <b>comput*</b> ØªØ³ØªØ±Ø¬Ø¹ ÙÙ Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙØªÙ ØªØšØ¯Ø£ ØšÙ <b>comput</b>.
+<li>Ø§ÙØ¹ÙØ§Ù
+Ø© <b>/x</b> ÙÙ
+ÙÙ Ø£Ù ØªØ³ØªØ®Ø¯Ù
+ ÙÙÙ ØªØ¹Ø·Ù Ø£ÙÙ
+ÙØ© Ø£ÙØšØ± ÙÙØ§Ø­Ø¯ Ø£Ù Ø£ÙØ«Ø± Ù
+Ù Ù
+ØµØ·ÙØ­Ø§Øª Ø§ÙØšØ­Ø«, ÙÙ
+Ø«ÙØ§Ù: <b>computer/10 science</b> ØªØ¹Ø·Ù ÙÙÙ
+Ø© computer Ø£ÙÙ
+ÙØ© Ø£ÙØšØ± ØšØ¹ØŽØ± Ù
+Ø±Ø§Øª Ù
+Ù ÙÙÙ
+Ø© science ÙÙ ØªØ±ØªÙØš Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙÙ
+Ø³ØªØ±Ø¬Ø¹Ø©.
+</ul>
+}  
+
+_texthelplucenesearching_ [l=ar] {ØšØ§ÙÙØ³ØšØ© ÙÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙÙ
+ØšÙÙØ© ØšÙ Lucene Ù
+Ø¬Ù
+ÙØ¹Ø© Ø£Ø®Ø±Ù Ù
+Ù Ø§ÙØ®ÙØ§Ø±Ø§Øª ØªÙÙÙ Ù
+ØªØ§Ø­Ø©. 
+
+<ul>
+<li><b>?</b> ÙÙ
+ÙÙ Ø£Ù ØªØ³ØªØ®Ø¯Ù
+ ÙØšØ¯ÙÙ Ø¹Ù Ø­Ø±Ù ÙØ§Ø­Ø¯ ÙÙ Ø¹Ù
+ÙÙØ© Ø§ÙØšØ­Ø«. Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù, <b>b?t</b> Ø³ÙÙ ÙØªÙ
+ Ø§Ø³ØªØ±Ø¬Ø§Ø¹ <b>bet</b>, <b>bit</b> and <b>bat</b> etc.
+<li><b>*</b> ÙÙ
+ÙÙ Ø£Ù ØªØ³ØªØ®Ø¯ ÙØšØ¯ÙÙ ÙØ£ÙØ«Ø± Ù
+Ù Ø­Ø±Ù ÙÙ Ø¹Ù
+ÙÙØ© Ø§ÙØšØ­Ø«. Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù, <b>comput*</b> Ø³ÙÙ ØªØ³ØªØ±Ø¬Ø¹ ÙÙ Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙØªÙ ØªØšØ¯Ø£ ØšÙ<b>comput</b>.
+</ul>
+ÙÙÙ Ù
+Ù ÙØ§ØªÙÙ Ø§ÙØ¹ÙØ§Ù
+ØªÙÙ ÙÙ
+ÙÙ Ø£Ù ÙØ³ØªØ®Ø¯Ù
+Ø§ ÙÙ Ù
+ÙØªØµÙ Ø£Ù ÙÙØ§ÙØ© Ø§ÙÙÙÙ
+Ø© ÙÙÙÙ ÙØ§ ÙÙ
+ÙÙ Ø§Ø³ØªØ®Ø¯Ø§Ù
+ÙÙ
+Ø§ ÙÙ Ø£Ù Ø§ÙÙÙÙ
+Ø© .}  
+
+_texthelpquerytypetitle_ [l=ar] {ÙÙ
+Ø· Ø§ÙØšØ­Ø«}
+_texthelpquerytype_ [l=ar] {<p>ÙÙØ§Ù ÙÙ
+Ø·Ø§Ù ÙÙØšØ­Ø« 
+
+<ul>
+  <li>ØšØ­Ø« Ø¹Ù<b>ÙÙ</b> Ø§ÙÙÙÙ
+Ø§Øª.  Ø­ÙØ« ÙØªÙ
+ Ø§ÙØšØ­Ø« ÙÙ ÙÙ Ù
+Ù Ø§ÙÙØ«Ø§ØŠÙ Ø£Ù Ø§ÙÙØµÙÙ Ø£Ù Ø§ÙØ¹ÙÙØ§ÙØ ÙØ§ÙØªÙ ØªØ­ØªÙÙ Ø¹ÙÙ ÙÙ Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙØªÙ ØªÙ
+ ØªØ­Ø¯ÙØ¯ÙØ§. ÙØ§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ØªØ·Ø§ØšÙ Ø§ÙØšØ­Ø« ÙØªÙ
+ Ø¹Ø±Ø¶ÙØ§ ÙÙ ØªØ±ØªÙØš ÙØ¬Ø§ØŠÙ.
+
+  <li>ØšØ­Ø« Ø¹Ù<b>ØšØ¹Ø¶</b> Ø§ÙÙÙÙ
+Ø§Øª.  Ø­ÙØ« ÙØªÙ
+ Ø§ÙØšØ­Ø« Ø¹Ù Ø§ÙÙÙÙ
+Ø§Øª Ù
+ÙØ±Ø¯Ø© ØªØžÙØ± ÙÙ Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ØªØšØ­Ø« ÙÙÙØ§. ÙÙØªÙ
+ Ø¹Ø±Ø¶ Ø§ÙÙØ«Ø§ØŠÙ ØšØ§ÙØªØ±ØªÙØš Ø§ÙØ°Ù ÙØ­ÙÙ Ø£Ø¹ÙÙ Ù
+Ø¯Ù ÙØªØ·Ø§ØšÙ Ù
+Ø¹ Ø°ÙØ± Ù
+Ø¯Ù ØªØ·Ø§ØšÙ ÙÙ ÙØ«ÙÙØ© Ù
+Ø¹ Ù
+ØµØ·ÙØ­Ø§Øª Ø§ÙØšØ­Ø«Ø
+
+      <p><ul>
+        <li> ÙØšÙØ¯Ø± Ù
+Ø§ ØªØ­ØªÙÙ Ø§ÙÙØ«ÙÙØ© Ø¹ÙÙ Ù
+ØµØ·ÙØ­Ø§Øª Ø§ÙØšØ­Ø« ØšÙØ¯Ø± Ù
+Ø§ ØªØµØšØ­ Ø£ÙØ±Øš ÙÙØªØ·Ø§ØšÙ Ù
+Ø¹ ÙØ°Ø§ Ø§ÙØšØ­Ø«Ø
+        <li> Ø§ÙÙ
+ØµØ·ÙØ­Ø§Øª Ø§ÙÙØ§Ø¯Ø±Ø© Ø£ÙØ«Ø± Ø£ÙÙ
+ÙØ© Ù
+Ù Ø§ÙÙ
+ØµØ·ÙØ­Ø§Øª Ø§ÙÙ
+ØªÙØ±Ø±Ø©Ø
+        <li> Ø§ÙÙØ«ÙÙØ© Ø§ÙÙØµÙØ±Ø© ØªØ·Ø§ØšÙ Ø£ÙØ¶Ù Ù
+Ù Ø§ÙÙØ«ÙÙØ© Ø§ÙØ·ÙÙÙØ©.
+      </ul>
+</ul>
+
+<p>ÙØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø£ÙØšØ± Ø¹Ø¯Ø¯ Ù
+Ù
+ÙÙ Ù
+Ù Ø§ÙÙ
+ØµØ·ÙØ­Ø§Øª Ø§ÙÙ
+ØªÙØ±Ø±Ø© Ø£Ù Ø¹ØšØ§Ø±Ø© Ø£Ù Ø­ØªÙ ÙÙØ±Ø© ÙØ§Ù
+ÙØ©Ø Ø¥Ø°Ø§ Ø­Ø¯Ø¯Øª Ù
+ØµØ·ÙØ­ ÙØ§Ø­Ø¯ Ø Ø³ÙÙ ØªØ±ØªØš Ø§ÙÙØ«Ø§ØŠÙ ÙÙÙ ÙØ°Ø§ ØªØ±Ø¯Ø¯ ÙØ°Ø§ Ø§ÙÙ
+ØµØ·ÙØ­ ÙÙÙØ§.<p>
+}  
+
+_texthelpadvancedsearchtitle_ [l=ar] {Ø§ÙØšØ­Ø« Ø§ÙÙ
+ØªÙØ¯Ù
+ ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+  Ù
+Ø­Ø±Ù Ø§ÙØšØ­Ø« _1_ }  
+
+_texthelpadvancedsearch_ [l=ar] {<p>  Ø¥Ø°Ø§ ÙÙØª ÙØ¯ Ø§Ø®ØªØ±Øª ÙÙ
+Ø· Ø§ÙØšØ­Ø« Ø§ÙÙ
+ØªÙØ¯Ù
+ Ù
+Ù (Ø§ÙØ®ÙØ§Ø±Ø§Øª)Ø ÙØ³ØªØ¬Ø¯Ø®ÙØ§Ø±Ø§Øª ØšØ­Ø« Ù
+Ø®ØªÙÙØ© ÙÙÙÙØ§ .
+}  
+
+_texthelpadvsearchmg_ [l=ar] {Ø§ÙØšØ­Ø« Ø§ÙÙ
+ØªÙØ¯Ù
+ ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª MG ÙÙ
+ÙÙÙ Ù
+Ù Ø§ÙØ§Ø®ØªÙØ§Ø± ØšÙÙ Ø®ÙØ§Ø±ÙÙ, Ø§ÙÙØŠØ§Øª ÙØ§ÙØšÙÙÙØ§ÙÙ.
+Ø§ÙØšØ­Ø« <b>ØšØ§ÙÙØŠØ§Øª</b> ÙØŽØšÙ ØªÙ
+Ø§Ù
+Ø§ Ø¥Ù
+ÙØ§ÙÙØ© Ø§ÙØšØ­Ø« <b>ØšØ¹Ø¶ Ø£Ù some</b> Ø§ÙØªÙ ÙÙ
+ÙÙ ÙØ±Ø§Ø¡Ø© ØŽØ±Ø­ÙØ§ ÙÙ <a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_
+}  
+
+_texthelpbooleansearch_ [l=ar] {Ø§ÙØšØ­Ø« <b>Ø§ÙØšÙÙÙÙÙ</b> ÙØ³Ù
+Ø­ ÙÙ ØšØ£Ù ØªØ¬Ù
+Ø¹ ÙÙ Ø§ÙØšØ­Ø« ØšÙÙ Ù
+ØµØ·ÙØ­ÙÙ ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙØ¹ÙØ§Ù
+Ø© (&)  (ÙÙÙ
+Ø¹Ø§Ù
+Ù "Ù"), ÙØ§ÙØ¹ÙØ§Ù
+Ø© (|) (ÙÙÙ
+Ø¹Ø§Ù
+Ù "Ø£Ù"), ÙØ§ÙØ¹ÙØ§Ù
+Ø© (!)(ÙÙÙ
+Ø¹Ø§Ù
+Ù "ÙÙØ³"), ÙÙ
+Ø§ ÙÙ
+ÙÙ ÙÙØ§ Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙÙÙØ³ÙÙ () ÙØªØ¬Ù
+ÙØ¹ Ø¹Ù
+ÙÙØ§Øª ØšÙÙÙÙÙØ© Ù
+Ø¹Ø§Ù. Ø³ÙØ­Ø¯Ø¯ Ø§ÙØšØ±ÙØ§Ù
+Ø¬ Ø§ÙØ¹ÙØ§Ù
+Ø© (|) ØªÙÙØ§ØŠÙØ§ ÙØ®Ø§ØµÙØ© ÙÙØšØ­Ø« Ø§ÙØšÙÙÙÙÙ ÙØ§ÙØªÙ ØªØ¹ÙÙ (Ø§ÙÙ
+Ø¹Ø§Ù
+Ù "Ø£Ù").
+<p>
+Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù, <b>snail & farming</b> Ø³ÙÙ ØªØ³ØªØ±Ø¬Ø¹ Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ØªØ­ØªÙÙ Ø¹ÙÙ Ø§ÙÙ
+ØµØ·ÙØ­ÙÙ Ù
+Ø¹Ø§Ù ÙÙ ÙÙØ³ Ø§ÙÙØµ <b>snail</b> "Ù" <b>farming</b>, ØšÙÙÙ
+Ø§ <b>snail | farming</b> Ø³ÙÙ ØªØ³ØªØ±Ø¬Ø¹ Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ØªØ­ØªÙÙ Ø¹ÙÙ Ø£Ù Ù
+ÙÙÙ
+Ø§ Ø£Ù ÙÙØ§ÙÙ
+Ø§ <b>snail</b> "Ø£Ù" <b>farming</b>.
+<b>snail !farming</b> Ø³ÙÙ ØªØ³ØªØ±Ø¬Ø¹ Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ØªØ­ØªÙÙ Ø¹ÙÙ <b>snail</b> ÙÙÙÙ ÙØ§ ØªØ­ØªÙÙ <b>farming</b>.
+<p>
+ÙÙ
+Ø§ ÙÙ
+ÙÙ ØªØ­Ø¯ÙØ¯ Ø§Ø³ØªØ±Ø§ØªÙØ¬ÙØ§Øª ØšØ­Ø« Ø£ÙØ«Ø± Ø¯ÙØ© ÙØªØ¹ÙÙØ¯ Ø¹Ù Ø·Ø±ÙÙ Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ù
+Ø²ÙØ¬ Ù
+Ù Ø§ÙÙ
+Ø¹Ø§Ù
+ÙØ§Øª Ø§ÙØšÙÙÙÙÙØ© ÙØ§ÙØ£ÙÙØ§Øµ. Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù, <b>(sheep | cattle) & (farm | station)</b>, or <b>sheep | cattle | goat !pig</b>.
+}  
+
+_texthelpadvsearchmgpp_ [l=ar] {Ø§ÙØšØ­Ø« Ø§ÙÙ
+ØªÙØ¯Ù
+ ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª MGPP ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙÙ
+Ø¹Ø§Ù
+ÙØ§Øª Ø§ÙØšÙÙÙÙÙØ©. _texthelpbooleansearch_
+<p>ÙÙ
+ÙÙ ÙÙØªØ§ØŠØ¬ Ø§ÙØšØ­Ø« Ø£Ù ØªØ¹Ø±Ø¶ ÙÙ <b>ØªØ±ØªÙØš</b> Ù
+Ø¹ÙÙØ ÙÙ
+Ø§ ÙÙ Ù
+ØŽØ±ÙØ­ ÙÙ <b>ØšØ¹Ø¶</b> Ø§ÙØšØ­Ø« ÙÙ <a href=""\#query-type"">_texthelpquerytypetitle_</a>Ø Ø£Ù ØšØªØ±ØªÙØš Ø¹Ù
+ÙÙØ© ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©. ÙÙÙ Ø§ÙØªØ±ØªÙØš Ø§ÙØ°Ù Ø±ØªØšØª ÙÙÙ Ø§ÙÙØ«Ø§ØŠÙ Ø£Ø«ÙØ§Ø¡ Ø¹Ù
+ÙÙØ© Ø¥ÙØŽØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©).ØªØ³ØªØ®Ø¯Ù
+ <b>NEARx</b>ÙØªØ­Ø¯ÙØ¯ Ø§ÙÙÙÙ
+Ø© Ø§ÙØ£ÙØšØ± <
+ØªÙØ¬Ø¯ Ù
+Ø¹Ø§Ù
+ÙØ§Øª Ø£Ø®Ø±Ù ØªØŽÙ
+Ù  <b>NEARx</b> Ù <b>WITHINx</b>.
+NEARx ØªØ³ØªØ®Ø¯Ù
+ ÙØªØ­Ø¯ÙØ¯ Ø§ÙÙ
+Ø³Ø§ÙØ© ØšÙÙ Ø§ÙÙ
+ØµØ·ÙØ­Ø§Øª Ø§ÙÙ
+ØšØ­ÙØ«Ø© ÙØšØ§ÙØªØ§ÙÙ ÙØ¬Øš Ø£Ù ØªØ­ØªÙÙ Ø¹ÙÙ Ù
+ØµØ·ÙØ­ÙÙ ÙÙØšØ­Ø« ÙÙ ÙØ°Ù Ø§ÙÙØ«ÙÙØ©.
+WITHINx ÙØ­Ø¯Ø¯ Ø£Ù ÙÙÙÙ Ø§ÙÙ
+ØµØ·ÙØ­ Ø§ÙØ«Ø§ÙÙ ÙØ¬Øš Ø£Ù ÙÙÙÙ ØšØ¹Ø¯ Ø¹Ø¯Ø¯ Ù
+Ø­Ø¯Ø¯ Ù
+Ù Ø§ÙÙÙÙ
+Ø§Øª <i>ØšØ¹Ø¯</i>  Ø§ÙÙ
+ØµØ·ÙØ­ Ø§ÙØ£ÙÙ ÙÙ Ø§ÙØšØ­Ø« Ø£Ù Ø£ÙÙØ§ ØŽØšÙÙØ§ ØšÙ NEAR ÙÙÙÙ ØšØ¹Ø¯ Ø§ÙÙ
+ØµØ·ÙØ­ Ø§ÙØ£ÙÙ ÙÙØ· ÙÙÙØ³ ØšØ¹Ø¯ ÙÙØšÙ Ø§ÙÙ
+ØµØ·ÙØ­ Ø§ÙØ£ÙÙ. ÙØ§ÙÙ
+Ø³Ø§ÙØ© Ø§ÙØªÙÙØ§ØŠÙØ© Ø§ÙÙ
+Ø³Ø¬ÙØ© ÙÙ Ø§ÙØšØ±ÙØ§Ù
+Ø¬ ÙÙ 20.
+
+}  
+
+_texthelpadvancedsearchextra_ [l=ar] {Ù
+ÙØ§Ø­ØžØ©: ÙÙ ÙØ°Ù Ø§ÙÙ
+Ø¹Ø§Ù
+ÙØ§Øª ØªÙÙÙ ØºÙØ± Ù
+ÙØ¹ÙØ© ÙÙ ÙÙØª ØªÙÙÙ
+ ØšØ§ÙØšØ­Ø« Ù
+Ù Ø®ÙØ§Ù ÙÙ
+Ø· Ø§ÙØšØ­Ø« Ø§ÙØšØ³ÙØ·.}  
+
+_texthelpadvsearchlucene_ [l=ar] {Ø§ÙØšØ­Ø« Ø§ÙÙ
+ØªÙØ¯Ù
+ ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© Lucene ØªØ³ØªØ®Ø¯ Ù
+Ø¹Ø§Ù
+ÙØ§Øª Ø§ÙØšØ­Ø« Ø§ÙØšÙÙÙÙÙ. _texthelpbooleansearch_
+}  
+
+_texthelpformsearchtitle_ [l=ar] {Ø§ÙØšØ­Ø« ØšØ§ÙØ­ÙÙÙ}  
+
+_texthelpformsearch_ [l=ar] {Ø§ÙØšØ­Ø« ØšØ§ÙØ­ÙÙÙ ÙØ¹Ø·ÙÙ Ø§ÙÙØ±ØµØ© ÙÙ ØªØ¬Ù
+Ø¹ ØšÙÙ Ø¹Ø¯Ø© ØšÙØ§ÙØ§Øª Ø­ÙÙÙ ÙÙ ÙÙØ³ Ø§ÙØšØ­Ø«. ÙØ¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§ÙØ ÙÙ
+ÙÙÙ Ø§ÙØšØ­Ø« Ø¹Ù <p>"Smith" ÙÙ Ø§ÙØ¹ÙÙØ§Ù ÙÙØ°ÙÙ "snail farming" ÙÙ Ø§ÙÙ
+ÙØ¶ÙØ¹ . ÙÙ ÙÙ
+Ø· Ø§ÙØšØ­Ø« Ø§ÙØšØ³ÙØ· ÙÙ ÙØªÙ
+ Ø§ÙØªØ¹Ø§Ù
+Ù Ù
+Ø¹ ÙÙ Ø³Ø·Ø± ÙÙ Ø§ÙØšØ­Ø« Ø¹ÙÙ Ø£ÙÙ Ø³Ø·Ø± Ù
+ÙÙØµÙ.  ÙÙØ°Ù Ø§ÙØ£Ø³Ø·Ø± Ø§ÙÙ
+ÙÙØµÙØ© ÙØªÙ
+ Ø§ÙØ±ØšØ· ØšÙÙÙØ§ ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙÙ
+Ø¹Ø§Ù
+Ù AND ÙÙ Ø­Ø§ÙØ© Ø§Ø®ØªÙØ§Ø± Ø§ÙÙÙ all ÙØšØ§ÙÙ
+Ø¹Ø§Ù
+Ù OR ÙÙ Ø­Ø§ÙØ© Ø§Ø®ØªÙØ§Ø± ØšØ¹Ø¶ some. ÙØ§ÙÙ
+ØµØ·ÙØ­Ø§Øª Ø£ÙØ¶Ø§ ÙÙ ÙÙ Ø­ÙÙ ØšØ­Ø« ÙØªÙ
+ Ù
+Ø¹Ø§Ù
+ÙØªÙØ§ ØšÙÙØ³ Ø§ÙØ·Ø±ÙÙØ©. ÙÙ ÙÙ
+Ø· Ø§ÙØšØ­Ø« Ø§ÙÙ
+ØªÙØ¯Ù
+Ø ÙÙ
+ÙÙÙ ØªØ­Ø¯ÙØ¯ ØšØ­Ø« Ù
+Ø¬Ù
+Ø¹ ÙÙ ÙÙ Ù
+Ù Ù/Ø£Ù/ÙÙØ³ AND/OR/NOT ØšÙÙ Ø§ÙØ­ÙÙÙ ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+ÙØ³Ø¯ÙØ©Ø ÙÙÙ
+ÙÙÙ Ø¯Ø§Ø®Ù ÙÙ Ø­ÙÙ ØšØ­Ø« Ø£Ù ØªØ­Ø¯Ø¯ Ø£ÙØ¶Ø§ Ù
+Ø¹Ø§Ù
+Ù Ø±ØšØ· . }  
+
+_texthelpformstemming_ [l=ar] {The "fold" and "stem" boxes allow you to specify whether the terms inside that field are casefolded or stemmed. These are both switched off by default for advanced form searching.}  
+
+_textdatesearch_ [l=ar] {Ø§ÙØšØ­Ø« ØšØ§ÙØªØ§Ø±ÙØ®}  
+
+_texthelpdatesearch_ [l=ar] {ÙÙ
+ÙÙÙ Ø§ÙØšØ­Ø« ÙÙ Ø§ÙØªØ§Ø±ÙØ® Ù
+Ù Ø§ÙØ­ØµÙÙ Ø¹ÙÙ ÙØ«Ø§ØŠÙ ØªØ·Ø§ØšÙ Ù
+ØµØ·ÙØ­ Ø§ÙØšØ­Ø« ÙÙÙÙ ÙÙ Ø¥Ø·Ø§Ø± Ø²Ù
+ÙÙ Ù
+Ø­Ø¯Ø¯. Ù
+Ø¹ Ù
+ÙØ§Ø­ØžØ© Ø£ÙÙ ÙÙ
+ÙÙ Ø§ÙØšØ­Ø« ÙÙ Ø§ÙØªØ§Ø±ÙØ® Ø¯ÙÙ ÙØ¬ÙØ¯ Ù
+ØµØ·ÙØ­ Ù
+ÙØ¶ÙØ¹Ù Ø­ÙØ« ÙÙÙÙ Ø§ÙØšØ­Ø« ÙÙ Ø§ÙØªØ§Ø±ÙØ® ÙÙØ·Ø ÙÙ
+Ø§ ÙÙ
+ÙÙ Ø§ÙØ§Ø³ØªØºÙØ§Ø¡ Ø¹Ù ØªØ­Ø¯ÙØ¯ Ø§ÙØªØ§Ø±ÙØ® ÙÙ Ø§ÙØšØ­Ø« ÙØ°ÙÙ ÙØ¹Ø·Ù Ø§ÙÙØªØ§ØŠØ¬ ØšØºØ¶ Ø§ÙÙØžØ± Ø¹Ù ØªØ§Ø±ÙØ®ÙØ§.<p>
+}  
+
+_texthelpdatehowtotitle_ [l=ar] {ÙÙÙÙØ© Ø§ÙØ§Ø³ØªØ®Ø¯Ø§Ù
+:}
+_texthelpdatehowto_ [l=ar] {<ul>
+   <li>ÙÙØšØ­Ø« Ø¹Ù Ø§ÙÙØ«Ø§ØŠÙ ÙÙ Ø³ÙØ© ÙØ§Ø­Ø¯Ø© :<p>
+   <ul>
+       <li>Ø§Ø¯Ø®Ù Ù
+ØµØ·ÙØ­ Ø§ÙØšØ­Ø« ØšØ§ÙØ·Ø±ÙÙØ© Ø§ÙÙ
+Ø¹ØªØ§Ø¯Ø©.
+       <li>Ø§Ø¯Ø®Ù Ø§ÙØ³ÙØ© Ø§ÙØªÙ ØªØ±ÙØ¯ ØªØ­Ø¯ÙØ¯ÙØ§ ÙÙ Ù
+Ø±ØšØ¹ "ØšØ¯Ø§ÙØ© Ù
+Ù (Ø£Ù ØšØªØ§Ø±ÙØ®)".
+       <li>Ø¥Ø°Ø§ ÙØ§Ù Ø§ÙØªØ§Ø±ÙØ® Ø§ÙÙ
+Ø±Ø§Ø¯ ØªØ­Ø¯ÙØ¯Ù ÙØšÙ ÙØªØ±Ø© Ø²Ù
+ÙÙØ© Ù
+ØŽÙÙØ±Ø© (Ù
+Ø«Ù: ÙØªØ±Ø© ÙØšÙ Ø§ÙÙ
+ÙÙØ§Ø¯Ø Ø§Ø®ØªØ± "Ù.Ù
+." Ù
+Ù Ø§ÙÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+ÙØ³Ø¯ÙØ© Ø§ÙØªÙ Ø¥ÙÙ Ø¬ÙØ§Ø± ÙØ°Ø§ Ø§ÙÙ
+Ø±ØšØ¹. 
+       <li>Ø«Ù
+ Ø§ØšØ¯Ø£ Ø§ÙØšØ­Ø« ØšØ§ÙØ·Ø±ÙÙØ© Ø§ÙÙ
+Ø¹ØªØ§Ø¯Ø©
+   </ul>
+<p><li>ÙÙØšØ­Ø« Ø¹Ù Ø§ÙÙØ«Ø§ØŠÙ ÙÙ ÙØªØ±Ø© Ø²Ù
+ÙÙØ©:<p>
+   <ul>
+       <li>Ø§Ø¯Ø®Ù Ù
+ØµØ·ÙØ­ Ø§ÙØšØ­Ø« ØšØ§ÙØ·Ø±ÙÙØ© Ø§ÙÙ
+Ø¹ØªØ§Ø¯Ø©.
+       <li>Ø§Ø¯Ø®Ù ØªØ§Ø±ÙØ® Ø§ÙØšØ¯Ø§ÙØ© ÙÙ Ù
+Ø±ØšØ¹ "ØšØ¯Ø§ÙØ© Ù
+Ù (Ø£Ù ØšØªØ§Ø±ÙØ®)". 
+       <li>Ø§Ø¯Ø®Ù ØªØ§Ø±ÙØ® Ø§ÙÙÙØ§ÙØ© ÙÙ Ù
+Ø±ØšØ¹ "ØªØ§Ø±ÙØ® Ø§ÙÙÙØ§ÙØ©".
+       <li>Ø§Ø®ØªØ± "Ù.Ù
+." Ù
+Ù Ø§ÙÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+ÙØ³Ø¯ÙØ© Ø¥ÙÙ Ø¬ÙØ§Ø± ÙØ°Ø§ Ø§ÙÙ
+Ø±ØšØ¹ ÙØ°ÙÙ ÙÙ Ø­Ø§ÙØ© Ø§ÙØªØ¹ØšÙØ± Ø¹Ù ÙØªØ±Ø© Ù
+Ø§ ÙØšÙ Ø§ÙÙ
+ÙÙØ§Ø¯. 
+       <li>Ø«Ù
+ Ø§ØšØ¯Ø£ Ø§ÙØšØ­Ø« ØšØ§ÙØ·Ø±ÙÙØ© Ø§ÙÙ
+Ø¹ØªØ§Ø¯Ø©.
+   </ul>    
+</ul><p>
+}  
+
+_texthelpdateresultstitle_ [l=ar] {Ø§ÙØ·Ø±ÙÙØ© Ø§ÙØªÙ ØªØ³ØªØ®Ø±Ø¬ ØšÙØ§ Ø§ÙÙØªØ§ØŠØ¬}
+_texthelpdateresults_ [l=ar] {Ø¹ÙÙ ÙØ¬Ù Ø§ÙØ¹Ù
+ÙÙ
+ ØšØ§ÙØšØ­Ø« ÙÙ Ø³ÙØ© Ù
+Ø«Ù 1903 ÙÙ ØªØ³ØªØ±Ø¬Ø¹ Ø¥ÙØ§ Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙÙ
+Ø€Ø±Ø®Ø© ØšÙØ°Ø§ Ø§ÙØ¹Ø§Ù
+ ÙÙØ·. ÙÙÙÙ ØšØ§ÙØšØ­Ø« ÙÙ ÙØªØ±Ø© Ø²Ù
+ÙÙØ© Ù
+Ø«Ù (1899- 1911) ÙØªÙ
+ Ø§Ø³ØªØ±Ø¬Ø§Ø¹ Ø§ÙÙØ«Ø§ØŠÙ ØšÙ
+Ø§ ÙÙÙØ§ ÙØ«Ø§ØŠÙ Ø¹Ø§Ù
+ 1903. ÙÙØ°ÙÙ Ø§ÙÙØªØš Ø§ÙØªÙ ÙØžÙØ± ÙÙ ÙØµÙØ§ Ø§ÙÙØ±Ù Ø§ÙØ°Ù ØªÙØªÙ
+Ù Ø¥ÙÙÙ Ø§ÙÙØªØ±Ø© Ø§ÙØ²Ù
+ÙÙØ© (Ù
+Ø«Ø§Ù: Ø§ÙÙØ±Ù Ø§ÙØ¹ØŽØ±ÙÙ ÙÙ ÙØ°Ù Ø§ÙØ­Ø§ÙØ©). ÙÙØ°Ø§ ÙØ¹ÙÙ Ø£ÙÙ Ù
+Ù Ø§ÙÙ
+Ù
+ÙÙ Ø£ÙØ§ ÙØžÙØ± ØªØ§Ø±ÙØ® Ø§ÙØšØ­Ø« ÙÙ Ø§ÙÙØ«ÙÙØ© Ø­ÙØ« ÙØ·ØšÙ Ø§ÙØšØ­Ø« ÙÙ ÙØªØ±Ø© Ø²Ù
+ÙÙØ© ÙÙÙØ³ Ø³ÙØ© Ù
+Ø­Ø¯Ø¯Ø©. <p>
+}  
+
+_textchangeprefs_ [l=ar] {ØªØºÙÙØ± Ø§ÙØ®ÙØ§Ø±Ø§Øª}
+
+_texthelppreferences_ [l=ar] {<p>Ø¹ÙØ¯ Ø§ÙØ¶ØºØ· Ø¹ÙÙ Ø²Ø± <i>Ø§ÙØ®ÙØ§Ø±Ø§Øª</i> ÙÙ Ø£Ø¹ÙÙ Ø§ÙØµÙØ­Ø© ÙÙ
+ÙÙ ØªØºÙÙØ± ØšØ¹Ø¶ Ù
+ÙØ²Ø§Øª Ø§ÙÙØ§Ø¬ÙØ© ÙØªØªÙØ§Ø³Øš Ù
+Ø¹ Ø§Ø­ØªÙØ§Ø¬Ø§ØªÙ Ø§ÙØ®Ø§ØµØ©.
+}  
+
+_texthelpcollectionprefstitle_ [l=ar] {Ø®ÙØ§Ø±Ø§Øª Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}
+_texthelpcollectionprefs_ [l=ar] {ØšØ¹Ø¶ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª ØªØªÙÙÙ Ù
+Ù Ù
+Ø¬Ù
+ÙØ¹Ø§Øª ÙØ±Ø¹ÙØ© ÙØ§ÙØªÙ ÙÙ
+ÙÙ Ø§ÙØšØ­Ø« ÙÙ ÙÙ Ù
+ÙÙØ§ Ù
+ÙÙØ±Ø¯Ø© Ø£Ù Ø§ÙØšØ­Ø« ÙÙÙØ§ Ø¬Ù
+ÙØ¹Ø§Ù ÙÙØ­Ø¯Ø© ÙØ§Ø­Ø¯Ø©. ÙØ°Ø§ ÙÙ
+ÙÙÙ Ø§Ø®ØªÙØ§Ø± Ø£Ù Ù
+Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙÙØ±Ø¹ÙØ© Ø§ÙØªÙ ØªØ±ÙØ¯ Ø§ÙØšØ­Ø« ÙÙÙØ§Ø ÙØ°ÙÙ Ù
+Ù ØµÙØ­Ø© Ø§ÙØ®ÙØ§Ø±Ø§Øª.
+}
+
+_texthelplanguageprefstitle_ [l=ar] {Ø®ÙØ§Ø±Ø§Øª Ø§ÙÙØºØ©}
+_texthelplanguageprefs_ [l=ar] {ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© ÙÙØ§ ÙØºØ© Ø¹Ø±Ø¶ Ù
+Ø­Ø¯Ø¯Ø© Ø³ÙÙØ§ÙØ ÙÙÙÙ ÙÙ
+ÙÙ ØªØšØ¯ÙÙ ÙØºØ© Ø§ÙØ¹Ø±Ø¶ ÙÙ Ø­Ø§ÙØ© Ø§ÙØ­Ø§Ø¬Ø© ÙØ°ÙÙ. ÙÙ
+Ø§ ÙÙ
+ÙÙ Ø§Ø³ØªØšØ¯Ø§Ù ÙØžØ§Ù
+ Ø§ÙØªØ±Ù
+ÙØ² Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙÙ Greenstone. ÙØšØ§ÙØ±ØºÙ
+ Ù
+Ù Ø£Ù Ø§ÙØšØ±ÙØ§Ù
+Ø¬ ÙØ®ØªØ§Ø± ÙØžØ§Ù
+ Ø§ÙØªØ±Ù
+ÙØ² Ø§ÙÙ
+ÙØ§ØŠÙ
+ ØªÙÙØ§ØŠÙØ§Ù Ø¥ÙØ§ Ø£ÙÙ ÙØªÙØ­ Ø¥Ù
+ÙØ§ÙÙØ© Ø§Ø®ØªÙØ§Ø± ÙØžØ§Ù
+ ØªØ±Ù
+ÙØ² Ø¢Ø®Ø± Ø­ØªÙ ØªØ¹Ø·Ù ØŽÙÙ Ø§ÙØ¹Ø±Ø¶ Ø§ÙØ£ÙØ¶Ù ØšØ§ÙÙØ³ØšØ© ÙÙÙ
+ØªØµÙØ­ Ø§ÙØ°Ù ØªØ³ØªØ®Ø¯Ù
+Ù. ØšØ§ÙØ¥Ø¶Ø§ÙØ© Ø¥ÙÙ Ø°ÙÙ ÙØ¥Ù ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª ØªØ¹Ø·Ù Ø¥Ù
+ÙØ§ÙÙØ© Ø§ÙØªØšØ¯ÙÙ ØšÙÙ ÙØ§Ø¬ÙØ© Ø§ÙØ¹Ø±Ø¶ Ø§ÙØ±Ø³ÙÙ
+ÙØ©. ÙÙÙÙÙ ÙØ°Ø§ Ù
+ÙÙØ¯Ø§Ù ÙÙ Ø­Ø§ÙØ© Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ Ø§ÙÙ
+Ø¹Ø§Ù ØšØµØ±ÙØ§Ù Ø§ÙØ°Ù ÙØ³ØªØ®Ø¯Ù
+ Ø®Ø·ÙØ· Ø°Ø§Øª Ø£Ø­Ø¬Ø§Ù
+ ÙØšÙØ±Ø© ÙÙ
+Ø³Ø§Ø¹Ø¯Ø§Øª ØµÙØªÙØ© Ù
+Ø¹ Ø§ÙÙ
+Ø®Ø±Ø¬Ø§Øª Ø§ÙØ£Ø³Ø§Ø³ÙØ©.
+}
+
+_texthelppresentationprefstitle_ [l=ar] {Ø®ÙØ§Ø±Ø§Øª Ø§ÙØ¹Ø±Ø¶}
+_texthelppresentationprefs_ [l=ar] {ØšØ§ÙÙØ³ØšØ© ÙÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙÙØ§Ø­Ø¯Ø©Ø ÙÙÙÙ ÙÙØ§Ù Ø¹Ø¯Ø© Ø®ÙØ§Ø±Ø§Øª ÙÙ
+ÙÙ Ø¶ØšØ·ÙØ§ ÙÙØªØ­ÙÙ
+ ÙÙ Ø¹Ø±Ø¶ ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©.
+
+<p>ÙÙØ¬Ø¯ Ø¥Ù
+ÙØ§ÙÙØ© ÙÙ Ø§ÙØ¹Ø±Ø¶ Ø§ÙØ®Ø§Øµ ØšÙ
+ÙØ¹ ØžÙÙØ± ØŽØ±ÙØ· Ø§ÙØªØµÙØ­ Ø§ÙØ®Ø§Øµ ØšØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙÙØ³Ù ÙÙ Ø£Ø¹ÙÙ Ø§ÙØµÙØ­Ø©Ø Ø­ÙØ« ØªÙÙÙ ÙØªÙØ¬Ø© Ø§ÙØšØ­Ø« Ø§ÙÙ
+Ø®ØªØ§Ø±Ø© ØšØ¯ÙÙ ØŽØ±ÙØ· Ø¹ÙÙÙ ÙÙØªØµÙØ­ ÙÙÙ ÙØ°Ù Ø§ÙØ­Ø§ÙØ© ÙØ³ØªØ®Ø¯Ù
+ Ø²Ø± Ø§ÙØ±Ø¬ÙØ¹ Ø§ÙØ®Ø§Øµ ØšØ§ÙÙ
+ØªØµÙØ­ Ø¹ÙØ¯ Ø§ÙØ±ØºØšØ© ÙÙ Ø¥Ø¬Ø±Ø§Ø¡ ØšØ­Ø« Ø¢Ø®Ø±. ÙÙ
+Ø§ ÙÙØ¬Ø¯ Ø®ÙØ§Ø± Ø£ÙØ¶Ø§Ù ÙÙ
+ÙØ¹ Ø±Ø³Ø§ØŠÙ Ø§ÙØªÙØšÙÙ Ø§ÙØ®Ø§ØµØ© ØšØ§ÙØ§ÙØªÙØ§Ù Ø¥ÙÙ ØµÙØ­Ø§Øª Ø§ÙÙÙØš Ø§ÙØ®Ø§Ø±Ø¬ÙØ©. ÙÙ
+Ø§ ÙÙØ¬Ø¯ Ø®ÙØ§Ø± ÙÙØªØ­ÙÙ
+ ÙÙ Ø·Ø±ÙÙØ© Ø§ÙØ§ÙØªÙØ§Ù Ù
+Ù ØµÙØ­Ø© ÙØªØ§ØŠØ¬ Ø§ÙØšØ­Ø« ÙØ¹ÙÙØ§Ù URL Ù
+ØšØ§ØŽØ±Ø© Ø£Ù
+ ÙÙÙØ³Ø®Ø© Ø§ÙÙ
+ÙØ¬ÙØ¯Ø© ÙÙ Ø§ÙÙ
+ÙØªØšØ© Ø§ÙØ±ÙÙ
+ÙØ© ÙÙÙ ÙØªÙØ¬Ø© Ù
+Ù ÙØªØ§ØŠØ¬ Ø§ÙØšØ­Ø«.
+}
+
+_texthelpsearchprefstitle_ [l=ar] {Ø®ÙØ§Ø±Ø§Øª Ø§ÙØšØ­Ø«}
+_texthelpsearchprefs_ [l=ar] {<p>ÙÙ
+ÙÙÙ Ø§ÙØªØ­ÙÙÙ Ø¥ÙÙ ÙÙ
+Ø· Ø§ÙØšØ­Ø« "Ø§ÙÙ
+ØªÙØ¯Ù
+" ÙØ§ÙØ°Ù ÙÙ
+ÙÙÙ Ù
+Ù Ø§ÙØ¬Ù
+Ø¹ ØšÙÙ Ù
+ØµØ·ÙØ­Ø§Øª Ø§ÙØšØ­Ø« ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø¹ÙØ§Ù
+Ø© & ÙÙÙ
+Ø¹Ø§Ù
+Ù (Ùand) Ù| ÙÙÙ
+Ø¹Ø§Ù
+Ù (Ø£Ùor) Ù! ÙÙÙ
+Ø¹Ø§Ù
+Ù (ÙÙØ³not)Ø ÙØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙØ£ÙÙØ§Ø³ ÙÙØšØ­Ø« ØšØ§ÙØ¹ØšØ§Ø±Ø§Øª ÙÙ
+Ø§ ÙÙ. ÙÙØ³Ù
+Ø­ ÙÙ ÙØ°Ø§ ØšØªØ­Ø¯ÙØ¯ Ù
+Ø²ÙØ¯ Ù
+Ù Ø¹ÙØ§ØµØ± Ø§ÙØšØ­Ø«.
+<p>_selectsearchtypeprefs_
+<p>_selectwordmodificationprefs_
+<p>ÙÙ
+ÙÙÙ Ø£Ù ØªÙØ¹Ù Ø®ÙØ§Ø± ØªØ³Ø¬ÙÙ ØªØ§Ø±ÙØ® Ø§ÙØšØ­Ø«Ø ÙØ§ÙØ°Ù ÙÙ
+ÙÙÙ Ù
+Ù Ø¹Ø±Ø¶ Ø¢Ø®Ø± Ù
+Ø¬Ù
+ÙØ¹Ø© Ø¹Ù
+ÙÙØ§Øª ØšØ­Ø« ÙÙ
+Øª ØšÙØ§. ÙØ°Ø§ ÙØ³ÙÙ Ù
+Ù Ø¹Ù
+ÙÙØ© Ø§ÙØªØ¹Ø¯ÙÙ Ø¹ÙÙ Ø¹Ù
+ÙÙØ§Øª ØšØ­Ø« Ø³Ø§ØšÙØ©.
+<p>ÙÙ
+Ø§ ÙÙ
+ÙÙÙ Ø§ÙØªØ­ÙÙ
+ ÙÙ Ø¹Ø¯Ø¯ Ø§ÙÙØªØ§ØŠØ¬ Ø§ÙÙ
+Ø³ØªØ±Ø¬Ø¹Ø© ÙÙ Ø§ÙØšØ­Ø«Ø ÙÙØ°ÙÙ Ø¹Ø¯Ø¯ Ø§ÙÙØªØ§ØŠØ¬ Ø§ÙÙ
+Ø¹Ø±ÙØ¶Ø© ÙÙ Ø§ÙØŽØ§ØŽØ© Ø§ÙÙØ§Ø­Ø¯Ø©.}  
+
+_textcasefoldprefs_ [l=ar] {ÙØ³Ø§Ø¹Ø¯ ÙØ°Ø§ Ø§ÙØ§Ø®ØªÙØ§Ø± Ø¹ÙÙ Ø§ÙØªÙ
+ÙÙØ² ØšÙÙ Ø§ÙØ­Ø±ÙÙ Ø§ÙÙØšÙØ±Ø© ÙØ§ÙØ­Ø±ÙÙ Ø§ÙØµØºÙØ±Ø© ÙÙ Ø§ÙÙØºØ© Ø§ÙØ¥ÙØ¬ÙÙØ²ÙØ© . ÙØ¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù ÙÙ ØªÙ
+ Ø§Ø®ØªÙØ§Ø± "_preferences:textignorecase_"Ø ÙØ³ÙÙ ÙØªÙ
+ Ø§ÙØªØ¹Ø§Ù
+Ù Ù
+Ø¹ <i>snail farming</i> ØšÙÙØ³ Ø§ÙØ·Ø±ÙÙØ© Ø§ÙØªÙ ÙØªÙ
+ Ø§ÙØªØ¹Ø§Ù
+Ù ØšÙØ§ Ù
+Ø¹ <i>Snail Farming</i> Ù <i>SNAIL FARMING</i> ÙÙ Ø¹Ù
+ÙÙØ© Ø§ÙØšØ­Ø«}  
+_textstemprefs_ [l=ar] {ÙÙ
+ÙÙ ÙØ°Ø§ Ø§ÙØ®ÙØ§Ø± Ù
+Ù Ø¹Ù
+ÙÙØ© ØªØ¬Ø§ÙÙ ÙÙØ§ÙØ© Ø§ÙÙÙÙ
+Ø§Øª . ÙØ¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù ÙÙ ØªÙ
+ Ø§Ø®ØªÙØ§Ø± "_preferences:textstem_"Ø ÙØ³ÙÙ ÙØªÙ
+ Ø§ÙØšØ­Ø« ÙÙ ÙÙ Ù
+Ù <i>snail farming</i> Ù <i>snails farm</i> Ù <i>snail farmer</i> ÙÙØ£ÙÙØ§ Ø¹ØšØ§Ø±Ø© ØšØ­Ø« ÙØ§Ø­Ø¯Ø©. ÙÙØ°Ù Ø§ÙØ®Ø§ØµÙØ© ØªØ¹Ù
+Ù ÙÙØ· ØšØŽÙÙ Ø¬ÙØ¯ Ù
+Ø¹ Ø§ÙÙØºØ© Ø§ÙØ¥ÙØ¬ÙÙØ²ÙØ© . _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=ar] {ÙØ³Ø§Ø¹Ø¯ ÙØ°Ø§ ÙÙ Ø§ÙØ§Ø®ØªÙØ§Ø± Ù
+Ø§ Ø¥Ø°Ø§ ÙØ§Ù Ø§ÙØšØ­Ø« Ø³ÙÙÙÙ Ø­Ø³Ø§Ø³Ø§ ÙØ­Ø§ÙØ© Ø§ÙØ­Ø±ÙØ© Ø¹ÙÙ Ø§ÙØ­Ø±ÙÙ accented Ù unaccented . ÙØ¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§ÙØ ÙÙ ØªÙ
+ Ø§Ø®ØªÙØ§Ø± "_preferences:textignoreaccents_" Ø ÙØ³ÙÙ ÙØªÙ
+ Ø§ÙØªØ¹Ø§ÙÙ
+ Ù
+Ø¹  <i>fÃ©dÃ©ration</i> ÙÙ Ø¹Ù
+ÙÙØ© Ø§ÙØšØ­Ø« ØšÙÙØ³ Ø§ÙØ·Ø±ÙÙØ© Ø§ÙØªÙ ÙØªÙ
+ Ø§ÙØªØ¹Ø§Ù
+Ù ØšÙØ§ Ù
+Ø¹  <i>fedÃ©ration</i> Ø£Ù Ø£ÙÙ ÙØ§ ÙØ±Ù ØšÙÙÙÙ
+ ÙÙ Ø¹Ù
+ÙÙØ© Ø§ÙØšØ­Ø«.}  
+ 
+_textstemoptionsprefs_ [l=ar] {Ø±ØšÙ
+Ø§ ÙÙÙÙ Ù
+Ù Ø§ÙÙ
+ÙØ§Ø³Øš Ø£ÙØ«Ø± Ø£Ù ØªØ³ØªØ®Ø¯Ù
+ ÙÙ Ø§ÙØšØ­Ø« Ø¹Ù
+ÙÙØ© Ø§ÙØšØªØ±  Ø§ÙÙ
+ØŽØ±ÙØ­Ø© Ø£Ø¹ÙØ§Ù ÙÙ "_texthelpquerytermstitle_".}  
+
+_textsearchtypeprefsplain_ [l=ar] {ÙÙ
+ÙÙ Ø§ÙØ­ØµÙÙ Ø¹ÙÙ Ù
+Ø±ØšØ¹ ØšØ­Ø« Ø£ÙØšØ±Ø Ø§ÙØ£Ù
+Ø± Ø§ÙØ°Ù ÙØ³ÙÙ Ø¹Ù
+ÙÙØ© Ø§ÙØšØ­Ø« ØšÙÙØ±Ø© ÙØ§Ù
+ÙØ©. ÙÙÙ ÙØ³ÙÙØ© Ø¬ÙØ¯Ø© ÙØ³Ø±ÙØ¹Ø© ÙÙØšØ­Ø« ØšÙØµ ÙØšÙØ±.}  
+
+_textsearchtypeprefsform_ [l=ar] {ÙÙ
+ÙÙÙ ØªØºÙÙØ± Ø¹Ø¯Ø¯ Ø§ÙØ­ÙÙÙ Ø§ÙÙ
+Ø¹Ø±ÙØ¶Ø© ÙÙ ØµÙØ­Ø© Ø§ÙØšØ­Ø«}  
+
+_textsearchtypeprefsboth_ [l=ar] {ÙÙ
+ÙÙÙ Ø§ÙØªØ­ÙÙÙ Ù
+Ù Ø·Ø±ÙÙØ© ØšØ­Ø« Ø¹Ø§Ø¯ÙØ© ÙØ·Ø±ÙÙØ© ØšØ­Ø« ØšØ§ÙØ­ÙÙÙ.
+<ul>
+<il>Ø§ÙØšØ­Ø« Ø§ÙØ¹Ø§Ø¯Ù ÙØ¹Ø·ÙÙ Ù
+Ø±ØšØ¹ ØšØ­Ø« ÙØ§Ø­Ø¯. _textsearchtypeprefsplain_ </il>
+<il>Ø§ÙØšØ­Ø« ØšØ§ÙØ­ÙÙÙ ÙØ¹Ø·ÙÙ Ø¹Ø¯Ø¯ Ù
+Ù Ù
+Ø±ØšØ¹Ø§Øª Ø§ÙØšØ­Ø«Ø ÙÙ Ù
+ÙÙÙ
+ ÙØšØ­Ø« ÙÙ Ø­ÙÙ Ù
+Ø®ØªÙÙ Ù
+Ù Ø­ÙÙÙ Ø§ÙÙØŽØ§Ù Ø§ÙØ®Ø§Øµ ØšØ§ÙÙØ§Ø¹Ø¯Ø©. ÙÙØ°Ø§ ÙÙ
+ÙÙ Ù
+Ù Ø§ÙØšØ­Ø« ÙÙ Ø¹Ø¯Ø© Ø­ÙÙÙ ÙÙ ÙÙØ³ Ø§ÙÙÙØª. _textsearchtypeprefsform_ </li>
+</ul>}  
+
+
+
+_texttanumbrowseoptions_ [l=ar] {ÙÙØ¬Ø¯ _numbrowseoptions_Ø·Ø±Ù ÙÙÙØµÙÙ ÙÙÙ
+Ø¹ÙÙÙ
+Ø§Øª ÙÙ ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©:}
+
+_textsimplehelpheading_ [l=ar] {ÙÙÙ ØªØ¬Ø¯ Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© _collectionname_ }
+
+_texthelpscopetitle_ [l=ar] {ÙØ·Ø§Ù Ø§ÙØšØ­Ø«}  
+_texthelpscope_ [l=ar] {<p>
+ÙÙ Ù
+Ø¹ØžÙ
+ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª ÙÙ
+ÙÙÙ Ø§Ø®ØªÙØ§Ø± ÙØŽØ§ÙØ§Øª Ù
+Ø®ØªÙÙØ© ÙÙØšØ­Ø« Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù ÙÙØ§Ù ÙØŽØ§Ù ØšØ§ÙÙ
+Ø€ÙÙ Ø£Ù ÙØŽØ§Ù ØšØ§ÙØ¹ÙÙØ§Ù. ÙØ£ÙØ¶Ø§Ù ÙÙØ§Ù ÙØŽØ§Ù Ø§ÙÙØµÙÙ ÙÙØŽØ§Ù Ø§ÙÙØ±Ø§Øª. ÙØ¹ÙÙ ÙØ¬Ù Ø§ÙØ¹Ù
+ÙÙ
+ Ø§ÙÙØ«ÙÙØ© Ø§ÙÙ
+Ø·Ø§ØšÙØ© ÙÙØšØ­Ø« ØªØ³ØªØ±Ø¬Ø¹ ØšØºØ¶ Ø§ÙÙØžØ± Ø¹Ù Ø§ÙÙØŽØ§Ù Ø§ÙØ°Ù ØªØšØ­Ø« ÙÙÙ.
+<p>ÙØºØ°Ø§ ÙØ§ÙØª Ø§ÙÙØ«ÙÙØ© Ø¹ØšØ§Ø© Ø¹Ù ÙØªØšØ ÙØ¥ÙÙØ§ Ø³ÙÙ ÙØªÙ
+ Ø§Ø³ØªØ±Ø¬Ø§Ø¹ÙØ§ ÙØ¹Ø±Ø¶ ÙØªØ§ØŠØ¬ÙØ§ ÙÙ Ø§ÙÙ
+ÙØ§Ù Ø§ÙØ°Ù ÙÙØ¬Ø¯ ÙÙÙ Ù
+ØµØ·ÙØ­ Ø§ÙØšØ­Ø«
+}
Index: /gsdl/stable/macros/arabic2.dm
===================================================================
--- /gsdl/stable/macros/arabic2.dm	(revision 20131)
+++ /gsdl/stable/macros/arabic2.dm	(revision 20131)
@@ -0,0 +1,2399 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# English Language text and icon macros 
+# -- this file contains text that is of less importance
+#
+# Many thanks to Kamal Mustafa (updated March 2009)
+#
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=ar] {Ø§ÙÙØ«Ø§ØŠÙ.}  
+_lastupdate_ [l=ar] {Ø§Ø®Ø± ØªØ¹Ø¯ÙÙ}  
+_ago_ [l=ar] {Ø£ÙØ§Ù
+ Ù
+Ø¶Øª.}  
+_colnotbuilt_ [l=ar] {Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ÙÙ
+ ØªØšÙÙ}  
+
+### taken from here
+
+_textpoem_ [l=ar] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>may peace and calmness surround you,
+<br>may you reside in the warmth of a summer's haze,
+<br>may the ocean of your travels be as smooth as the polished greenstone.
+}  
+
+_textgreenstone_ [l=ar] {<p>Ø¥Ù ÙÙÙ
+Ø© Greenstone ØªØŽÙØ± Ø¥ÙÙ Ø£Ø­Ø¯ Ø§ÙØ£Ø­Ø¬Ø§Ø± Ø§ÙÙÙÙØ³Ø© Ø§ÙØªÙ ØªÙØ¬Ø¯ ÙÙ ÙÙÙØ²ÙÙØ§ÙØ¯Ø§. ÙÙØ§ÙØª ÙØ°Ù Ø§ÙØ£Ø­Ø¬Ø§Ø± ÙÙ ØªÙØ§ÙÙØ¯ Ù
+Ø¬ØªÙ
+Ø¹ Ø§ÙÙ
+Ø§ÙØ±Ù Maori ÙÙ Ø£Ø¹ÙÙ Ø¬Ø§ØŠØ²Ø©. Ø­ÙØ« ØžÙÙØ§ Ø£Ù ÙØ°Ù Ø§ÙØ£Ø­Ø¬Ø§Ø± ÙÙ
+ÙÙÙØ§ Ø£Ù ØªÙ
+ØªØµ <i>wairua</i>Ø ÙÙÙ Ø±ÙØ­ ÙÙØ© Ø§ÙØ­ÙØ§Ø©Ø ÙØ°Ø§ ÙÙØ¯ ÙØ§ÙØª ØŽØ¹Ø§Ø± Ù
+ÙØ§Ø³Øš ÙÙ
+ØŽØ±ÙØ¹ Ù
+ÙØªØšØ© Ø±ÙÙ
+ÙØ© Ø°Ù Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø¹Ø§Ù
+. ÙÙÙ
+Ø¹Ø§Ù ÙØ°Ù Ø§ÙØ§Ø­Ø¬Ø§Ø± ÙØ¯Ù Ø¹ÙÙ Ø§ÙØ®ÙØ±Ø ÙØŽÙØ§ÙÙØªÙØ§ ØªØ¯Ù Ø¹ÙÙ Ø§ÙØ§Ø­ØªØ±Ø§Ù
+ ÙØµÙØ§ØšØªÙØ§ ØªØ¯Ù Ø¹ÙÙ Ø§ÙØŽØ§Ø¬Ø§Ø¹Ø© ÙØ£Ø·Ø±Ø§ÙÙØ§ Ø§ÙØ­Ø§Ø¯Ø© ØªØ¯Ù Ø¹ÙÙ Ø§ÙØ¹Ø¯Ù. Ø£Ù
+Ø§ Ø§ÙÙØ·Ø¹Ø© Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+Ø© ÙÙ ØŽØ¹Ø§Ø± ØšØ±ÙØ§Ù
+Ø¬ Greenstone Ø¹ØšØ§Ø±Ø© Ø¹Ù <i>patu</i> Ø£Ù Ø£Ø¯Ø§Ø© ÙØªØ§Ù Ø£Ø«Ø±ÙØ© Ù
+Ù
+ÙÙÙØ© ÙØ£Ø­Ø¯ Ø£Ø¹Ø¶Ø§Ø¡ Ø§ÙÙ
+ØŽØ±ÙØ¹.
+ÙÙØ§ÙØª ÙØ°Ù Ø§ÙØ£Ø¯Ø§Ø© Ø³Ø±ÙØ¹Ø© ÙØ¯ÙÙÙØ© ÙÙØ§Ø¬Ø¹Ø©. ÙÙ
+Ø§ ÙØ±Ø¬ÙÙ Ø£Ù ØªÙÙÙ ÙÙØ³ ÙØ°Ù Ø§ÙØ¬ÙØ¯Ø© ÙÙ ØšØ±ÙØ§Ù
+Ø¬ÙØ§</p>}  
+
+_textaboutgreenstone_ [l=ar] {<p>Ø£Ø¹Ø¯ Greenstone ÙØšÙØ§Ø¡ ÙÙØŽØ± Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙÙ
+ÙØªØšØ§Øª Ø§ÙØ±ÙÙ
+ÙØ©. Ø­ÙØ« ÙÙØ¯Ù
+ Ø·Ø±ÙÙØ© Ø¬Ø¯ÙØ¯Ø© ÙØªÙØžÙÙ
+ ÙÙØŽØ± Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø¹ÙÙ Ø§ÙØ¥ÙØªØ±ÙØª Ø£Ù Ø¹ÙÙ Ø§ÙÙØ±Øµ Ø§ÙÙ
+Ø¯Ù
+Ø¬. ÙÙÙ ØšØ±ÙØ§Ù
+Ø¬ Ù
+ÙØªØ¬ Ù
+Ù ÙØšÙ <b>Ù
+ØŽØ±ÙØ¹ Ù
+ÙØªØšØ© ÙÙÙØ²ÙÙØ§ÙØ¯Ø§ Ø§ÙØ±ÙÙ
+ÙØ©</b> ÙÙ <b>Ø¬Ø§Ù
+Ø¹Ø© ÙØ§ÙÙØ§ØªÙ</b>Ø ÙÙØ¯ ØªÙ
+ ØªØ·ÙÙØ±Ù ÙØªÙØ²ÙØ¹Ù ØšØ§ÙØªØ¹Ø§ÙÙ Ù
+Ø¹ <b>Ø§ÙÙÙÙØ³ÙÙ</b> ÙØ¬Ù
+Ø¹ÙØ© <b>Human Info NGO</b>. ÙÙÙ ØšØ±ÙØ§Ù
+Ø¬ Ù
+ÙØªÙØ­ Ø§ÙÙ
+ØµØ¯Ø± Ù
+Ù Ø®ÙØ§Ù Ø§ÙØ¹ÙÙØ§Ù <a
+href="http://greenstone.org">http://greenstone.org</a> ØšÙ
+ÙØ¬Øš Ø§ØªÙØ§ÙÙØ© GNU General Public License.
+</p>
+
+<p>Ø§ÙÙØ¯Ù Ù
+Ù ÙØ°Ø§ Ø§ÙØšØ±ÙØ§Ù
+Ø¬ ÙÙ ØªÙ
+ÙÙÙ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ÙÙ Ø®Ø§ØµØ© ÙÙ Ø§ÙØ¬Ø§Ù
+Ø¹Ø§Øª ÙØ§ÙÙ
+ÙØªØšØ§Øª ÙÙ
+Ø€Ø³Ø³Ø§Øª Ø§ÙØ®Ø¯Ù
+Ø© Ø§ÙØ¹Ø§Ù
+Ø© Ø§ÙØ£Ø®Ø±Ù Ù
+Ù ØšÙØ§Ø¡ Ù
+ÙØªØšØªÙÙ
+ Ø§ÙØ±ÙÙ
+ÙØ©. ÙØ§ÙÙ
+ÙØªØšØ§Øª Ø§ÙØ±ÙÙ
+ÙØ© ÙÙ Ø§ÙØ£Ø³Ø§Ø³ ÙÙ ØªØ¬Ø¯ÙØ¯Ø© ÙØ·Ø±ÙÙØ© ØšØ« Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª ØšÙ
+ÙØ¬Øš Ø§Ø­ØªÙØ§Ø¬Ø§Øª ØŽØ±ÙØ§Ø¡ Ø§ÙÙÙÙØ³ÙÙ Ù
+Ù Ø¬Ù
+Ø¹ÙØ§Øª ÙÙ
+Ø¹Ø§ÙØ¯ ÙÙ Ù
+Ø¬Ø§Ù Ø¹ÙÙÙ
+ Ø§ÙØªØ±ØšÙØ© ÙØ§ÙØ«ÙØ§ÙØ© ÙÙ Ø£ÙØ­Ø§Ø¡ Ø§ÙØ¹Ø§ÙÙ
+Ø ÙØ¹ÙÙ Ø§ÙØ£Ø®Øµ ÙÙ Ø§ÙØ¯ÙÙ Ø§ÙÙØ§Ù
+ÙØ©. ÙÙØ­Ù ÙØ£Ù
+Ù Ø£Ù ÙØŽØ¬Ø¹ ÙØ°Ø§ Ø§ÙØšØ±ÙØ§Ù
+Ø¬ ØªÙØ¹ÙÙ Ø¯ÙØ± Ø§ÙÙ
+ÙØªØšØ© Ø§ÙØ±ÙÙ
+ÙØ© ÙÙ Ù
+ØŽØ§Ø±ÙØ© Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª ÙØ¥ØªØ§Ø­ØªÙØ§ ÙÙØ§ÙØ© Ø§ÙÙØ§Ø³.
+</p>
+
+<p>Ø·ÙØ± ØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙÙØ²Ø¹ ÙØªØ¹Ø§ÙÙ Ø¯ÙÙÙ ØšÙÙ Ø«ÙØ§Ø« Ø¬ÙØ§Øª ÙÙ Ø£ØºØ³Ø·Ø³ 2000.
+</p>
+
+<p>
+<a href="http://nzdl.org"><b>Ù
+ØŽØ±ÙØ¹ Ù
+ÙØªØšØ© ÙÙÙØ²ÙÙØ§ÙØ¯Ø§ Ø§ÙØ±ÙÙ
+ÙØ© ÙÙ Ø¬Ø§Ù
+Ø¹Ø© ÙØ§ÙÙØ§ØªÙ</b></a>
+<br>
+ÙÙØ¯ ÙÙ
+Ø§ ØšØ±ÙØ§Ù
+Ø¬ Greenstone Ù
+Ù ÙØ°Ø§ Ø§ÙÙ
+ØŽØ±ÙØ¹ Ø«Ù
+ Ø§Ø¹ØªÙ
+Ø¯ ØšØ¹Ø¯ Ø°ÙÙ Ù
+Ù ÙØšÙ ÙÙØŠØ© Ø§ÙØ§ØªØµØ§ÙØ§Øª Ø§ÙÙØ±Ø¹ÙØ© Ù
+Ù ÙØ¬ÙØ© Ø§ÙÙÙÙ
+ÙØ© Ø§ÙÙÙÙØ³ÙÙ ÙÙ ÙÙÙØ²ÙÙØ§ÙØ¯Ø§ ÙØ¬Ø²Ø¡ Ù
+Ù Ù
+Ø³Ø§ÙÙ
+Ø§Øª ÙÙÙØ²ÙÙØ§ÙØ¯Ø§ ÙÙ ØšØ±ÙØ§Ù
+Ø¬ Ø§ÙÙÙÙØ³ÙÙ.
+</p>
+
+<p>
+<a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+class="logo"></a>
+<a href="http://www.unesco.org"><b>Ø§ÙÙÙÙØ³ÙÙ</b></a>
+<br>
+Ø¥Ù Ø¹Ù
+ÙÙØ© ØšØ« Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª ÙÙ Ù
+Ø¬Ø§ÙØ§Øª Ø§ÙØªØ¹ÙÙÙ
+ ÙØ§ÙØ¹ÙÙÙ
+ ÙØ§ÙØ«ÙØ§ÙØ© ÙÙ Ø£ÙØ­Ø§Ø¡ Ø§ÙØ¹Ø§ÙÙ
+ ÙØ¹ÙÙ Ø§ÙØ£Ø®Øµ ÙÙ Ø§ÙØ¯ÙÙ Ø§ÙÙØ§Ù
+ÙØ© ÙÙ Ø£Ø­Ø¯ Ø£ÙÙ
+ Ø£ÙØ¯Ø§Ù Ø§ÙÙÙÙØ³ÙÙ Ù
+ØªØšÙØ¹Ø§Ù ØšØšØ±ÙØ§Ù
+Ø¬ Ø¥ØªØ§Ø­Ø© Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙØ­ÙÙÙ
+ÙØ© ÙÙØ¬Ù
+ÙØ¹Ø ÙÙÙØ§ ØªÙÙÙ ØªÙÙÙÙÙØ¬ÙØ§ Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª ÙØ§ÙØ§ØªØµØ§ÙØ§Øª Ø§ÙÙ
+ØªØ§Ø­Ø© Ù
+Ù Ø£ÙÙ
+ Ø§ÙØ£Ø¯ÙØ§Øª ÙÙ ÙØ°Ø§ Ø§ÙØ³ÙØ§Ù.
+</p>
+
+<p>
+<a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>The Human Info NGO, based in Antwerp, Belgium</b></a>
+<br>
+ÙØ¹Ù
+Ù ÙØ°Ø§ Ø§ÙÙ
+ØŽØ±ÙØ¹ Ù
+Ø¹ Ù
+Ù Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ù ÙÙØ§ÙØ§Øª Ø§ÙØ£Ù
+Ù
+ Ø§ÙÙ
+ØªØ­Ø¯Ø© ÙØ§ÙÙ
+ÙØžÙ
+Ø§Øª ØºÙØ± Ø§ÙØ­ÙÙÙ
+ÙØ© Ø§ÙØ£Ø®Ø±ÙØ ÙÙØ¯ Ø§ÙØªØ³Øš Ø³Ù
+Ø¹Ø© Ø¹Ø§ÙÙ
+ÙØ© ÙÙ Ø¹Ø§ÙÙ
+ Ø±ÙÙ
+ÙØ© Ø§ÙÙØ«Ø§ØŠÙ ÙÙ Ù
+Ø¬Ø§Ù Ø§ÙØªÙÙ
+ÙØ© Ø§ÙØšØŽØ±ÙØ© ÙØ¥ØªØ§Ø­ØªÙØ§ ØšØŽÙÙ ÙØ§Ø³Ø¹Ø ÙÙØ°Ø§ ØšØªÙØ²ÙØ¹ Ù
+Ø¬Ø§ÙÙ ÙÙ Ø§ÙØ¯ÙÙ Ø§ÙÙØ§Ù
+ÙØ© ÙØšØ³Ø¹Ø± Ø§ÙØªÙÙÙØ© ÙÙØ¯ÙÙ Ø§ÙØ£Ø®Ø±Ù.
+</p>
+
+
+
+}  
+
+
+_textdescrselcol_ [l=ar] {Ø§Ø®ØªØ± Ù
+Ø¬Ù
+ÙØ¹Ø©}  
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=ar] {ÙÙØ¬Ø¯ Ø¹Ø¯Ø¯ Ø£Ø±ØšØ¹Ø© Ø£Ø²Ø±Ø§Ø± Ø£Ø®Ø±Ù ÙÙ Ø§ÙØµÙØ­Ø© Ø§ÙØ±ØŠÙØ³ÙØ©}  
+
+_textnocollections_ [l=ar] {<p>ÙØ§ ÙÙØ¬Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ù
+ØªØ§Ø­Ø© Ø­Ø§ÙÙØ§Ù ÙÙ Greenstone. 
+ÙØ¥Ø¶Ø§ÙØ© ØšØ¹Ø¶ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª ÙÙ
+ÙÙÙ
+<ul><li>Ø§Ø³ØªØ®Ø¯Ø§Ù
+ <a href="_httppagecollector_">Ø§ÙÙ
+Ø¬Ù
+Ø¹</a> ÙØšÙØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ø¬Ø¯ÙØ¯Ø©
+    <li>Ø¥Ø°Ø§ ÙØ§Ù ÙØ¯ÙÙ Ø§ÙÙØ±Øµ Ø§ÙÙ
+Ø¯Ù
+Ø¬ ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙÙ
+ÙÙÙ ØªØ­Ù
+ÙÙ ØšØ¹Ø¶ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ù
+Ù Ø¹ÙÙÙ</ul>}  
+
+_text1coll_ [l=ar] {Ø§ÙØªØ«ØšÙØª Ø§ÙØ­Ø§ÙÙ ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙØ­ØªÙÙ Ø¹ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© ÙØ§Ø­Ø¯Ø©}  
+
+_textmorecolls_ [l=ar] {ØªØ«ØšÙØª ØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙØ­ØªÙÙ Ø¹ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª _1_ }  
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=ar] {Ø±Ø§ØšØ·Ø© Ø®Ø§Ø±Ø¬ÙØ©}  
+_textlinknotfound_ [l=ar] {Ø§ÙØ±Ø§ØšØ·Ø© Ø§ÙØ¯Ø§Ø®ÙÙØ© ØºÙØ± Ù
+ÙØ¬ÙØ¯Ø©}  
+
+_textextlinkcontent_ [l=ar] {ÙÙØ¯ ÙÙ
+Øª ØšØ§Ø®ØªÙØ§Ø± Ø±Ø§ØšØ·Ø© ØªØ­ÙÙ Ø¥ÙÙ Ø®Ø§Ø±Ø¬ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙØ­Ø§ÙÙØ©Ø Ø¥Ø°Ø§ ÙÙØª ØªØ±ÙØ¯ Ø¹Ø±Ø¶ ÙØ°Ù Ø§ÙØ±Ø§ØšØ·Ø© ÙÙØ¯ÙÙ Ø§ØªØµØ§Ù ØšØ§ÙØ¥ÙØªØ±ÙØª ÙÙ
+ÙÙÙ <a href="_nexturl_">Ø§ÙØªÙØ¯Ù
+</a> Ø¥ÙÙ ÙØ°Ù Ø§ÙØµÙØ­Ø©Ø ÙØ¥Ù ÙÙØª ØªØ±ÙØ¯ Ø§ÙØ¹ÙØ¯Ø© Ø§Ø³ØªØ®Ø¯Ù
+ Ø²Ø± Ø§ÙÙ
+ØªØµÙØ­ "Back" ÙÙØ¹ÙØ¯Ø© ÙÙÙØ«ÙÙØ© Ø§ÙØ³Ø§ØšÙØ©}  
+
+_textlinknotfoundcontent_ [l=ar] {ÙØ³ØšØš Ø®Ø§Ø±Ø¬ Ø¹Ù Ø¥Ø±Ø§Ø¯ØªÙØ§Ø Ø§ÙØ±Ø§ØšØ·Ø© Ø§ÙØ¯Ø§Ø®ÙÙØ© Ø§ÙØªÙ Ø§Ø®ØªØ±ØªÙØ§ ÙÙØ³Øª Ù
+ÙØ¬ÙØ¯Ø©. ÙÙ
+ÙÙ Ø£Ù ÙÙÙÙ Ø§ÙØ³ØšØš ÙÙ Ø®Ø·Ø£ ÙÙ Ù
+ØµØ¯Ø± Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©Ø ÙÙ
+ÙÙÙ Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø²Ø± Ø§ÙØ±Ø¬ÙØ¹ "Back" ÙÙØ¹ÙØ¯Ø© ÙÙÙØ«ÙÙØ© Ø§ÙØ³Ø§ØšÙØ©.}  
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=ar] {<h3>Ø±Ø§ØšØ·Ø© Ø¥ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø©"_2_" </h3>
+
+<p> Ø§ÙØ±Ø§ØšØ·Ø© Ø§ÙØªÙ Ø§Ø®ØªØ±ØªÙØ§ ØªØ­ÙÙ Ø¥ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© "_collectionname_"
+    (ØªØ­ÙÙ Ø¥Ù Ù
+Ø¬Ù
+ÙØ¹Ø©"_2_" ).
+    Ø¥Ø°Ø§ Ø£Ø±Ø¯Øª Ø¹Ø±Ø¶ ÙØ°Ø§ Ø§ÙØ±Ø§ØšØ· ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© "_2_" ÙÙ
+ÙÙÙ
+    <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">Ø§ÙØªÙØ¯Ù
+</a> Ø¥ÙÙ ÙØ°Ù Ø§ÙØµÙØ­Ø©; 
+    Ø£Ù Ø§Ø³ØªØ®Ø¯Ù
+ Ø²Ø± "back" ÙÙ Ù
+ØªØµÙØ­Ù ÙÙØ¹ÙØ¯Ø© Ø¥ÙÙ Ø§ÙÙØ«ÙÙØ© Ø§ÙØ³Ø§ØšÙØ©.
+}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=ar] {Ø§ÙÙ
+ÙØªØšØ© Ø§ÙØ±ÙÙ
+ÙØ© Greenstone}  
+
+_textusername_ [l=ar] {Ø§Ø³Ù
+ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+}  
+_textpassword_ [l=ar] {ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ±}  
+
+_textmustbelongtogroup_ [l=ar] {ÙØ§Ø­Øž Ø£ÙÙ ÙØ¬Øš Ø£Ù ØªÙÙÙ Ù
+Ù Ù
+Ø¬Ù
+ÙØ¹Ø© "_cgiargug_" ÙÙ ØªØ¯Ø®Ù ÙÙØ°Ù Ø§ÙØµÙØ­Ø©}  
+
+_textmessageinvalid_ [l=ar] {Ø§ÙØµÙØ­Ø© Ø§ÙØªÙ Ø·ÙØšØª Ø¹Ø±Ø¶ÙØ§ ØªØªØ·ÙØš Ù
+ÙÙ Ø¥Ø¬Ø±Ø§Ø¡Ø§Øª Ø§ÙØ¯Ø®ÙÙ.<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)
+Ù
+Ù ÙØ¶ÙÙ Ø§Ø¯Ø®Ù Ø§Ø³Ù
+ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ± Ø§ÙØ®Ø§ØµØ© ØšÙ Greenstone.}  
+
+_textmessagefailed_ [l=ar] {ÙÙØ§Ù Ø®Ø·Ø£ ÙÙ Ø§Ø³Ù
+ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ Ø£Ù ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ±.}  
+
+_textmessagedisabled_ [l=ar] {Ø¹ÙÙØ§ÙØ ÙÙØ¯ ØªÙ
+ ÙÙÙ Ø­Ø³Ø§ØšÙ. Ù
+Ù ÙØ¶ÙÙ Ø§ØªØµÙ ØšÙ
+Ø¯ÙØ± ÙØ°Ø§ Ø§ÙÙ
+ÙÙØ¹.}  
+
+_textmessagepermissiondenied_ [l=ar] {Ø¹ÙÙØ§ÙØ ØºÙØ± Ù
+ØµØ±Ø­ ÙÙ ØšØ¯Ø®ÙÙ ÙØ°Ù Ø§ÙØµÙØ­Ø©.}  
+
+_textmessagestalekey_ [l=ar] {Ø§ÙØ±Ø§ØšØ·Ø© Ø§ÙØªÙ ØªØªØšØ¹ÙØ§ ÙÙ
+ ØªØ¹Ø¯ ØªØ¹Ù
+Ù.
+Ù
+Ù ÙØ¶ÙÙ Ø£Ø¯Ø®Ù ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ± Ø­ØªÙ ØªØµÙ Ø¥ÙÙ ÙØ°Ù Ø§ÙØµÙØ­Ø©.}  
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=ar] {<p>ÙØ°Ø§ Ø§ÙØªØ«ØšÙØª ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙØ§ ÙØ­ØªÙÙ Ø¹ÙÙ Ø£Ù ØªÙØ«ÙÙ. Ø±ØšÙ
+Ø§ ÙÙÙÙ Ø°ÙÙ ØšØ³ØšØš:
+<ol>
+<li>ØšØ±ÙØ§Ù
+Ø¬ Greenstone Ù
+Ø«ØšØª Ù
+Ù Ø§ÙÙØ±Øµ Ø§ÙÙ
+Ø¯Ù
+Ø¬ ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙØªØ«ØšÙØª Ø§ÙÙ
+ØµØºØ±.
+<li>ØšØ±ÙØ§Ù
+Ø¬ Greenstone Ù
+Ø«ØšØª Ù
+Ù Ø¹ÙÙ Ø§ÙØ¥ÙØªØ±ÙØª.
+</ol>
+ÙÙ ÙÙØ§ Ø§ÙØ­Ø§ÙØªÙÙ ÙÙ
+ÙÙÙ Ø§ÙØ­ØµÙÙ Ø¹ÙÙ ØšÙØ§ÙØ§Øª Ø§ÙØªÙØ«ÙÙ Ù
+Ù Ù
+Ø¬ÙØ¯ <i>docs</i> ÙÙ ÙØ±Øµ Greenstone Ø£Ù ØšØ²ÙØ§Ø±Ø© Ø§ÙØ¹ÙÙØ§Ù Ø§ÙØªØ§ÙÙ <a
+href="http://www.greenstone.org">http://www.greenstone.org</a>.
+}  
+
+_textuserguide_ [l=ar] {Ø¯ÙÙÙ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+}  
+_textinstallerguide_ [l=ar] {Ø¯ÙÙÙ ØªØ«ØšÙØª Ø§ÙØšØ±ÙØ§Ù
+Ø¬}  
+_textdeveloperguide_ [l=ar] {Ø¯ÙÙÙ Ø§ÙÙ
+Ø·ÙØ± (Ø§ÙÙ
+ØšØ±Ù
+Ø¬)}  
+_textpaperguide_ [l=ar] {Ù
+Ù Ø§ÙÙØ±Ù Ø¥ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª}  
+_textorganizerguide_ [l=ar] {Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙÙ
+ÙØžÙ
+}  
+
+_textgsdocstitle_ [l=ar] {ÙØ«Ø§ØŠÙ Greenstone}  
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=ar] {ØšÙØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø©}  
+_textbildsuc_ [l=ar] {ØªÙ
+ ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ØšÙØ¬Ø§Ø­.}  
+_textviewbildsummary_ [l=ar] {ÙÙ
+ÙÙÙ <a href="_httppagex_(bsummary)" target=_top>Ø¹Ø±Ø¶ Ù
+ÙØ®Øµ Ø¹Ù
+ÙÙØ© Ø§ÙØšÙØ§Ø¡</a> Ø§ÙØ®Ø§Øµ ØšÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©.
+}  
+_textview_ [l=ar] {Ø§Ø¹Ø±Ø¶ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}  
+
+_textbild1_ [l=ar] {ÙØªÙ
+ Ø§ÙØ¢Ù ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©: ÙØ¯ ÙØ³ØªØºØ±Ù ÙØ°Ø§ ØšØ¹Ø¶ Ø§ÙÙÙØª. ØªØ§ØšØ¹ Ø­Ø§ÙØ© ØªÙØ¯Ù
+ Ø¹ÙÙ
+ÙØ© Ø§ÙØšÙØ§Ø¡ ÙÙØ§.}  
+
+_textbild2_ [l=ar] {ÙØ¥ÙÙØ§Ù Ø¹Ù
+ÙÙØ© Ø§ÙØšÙØ§Ø¡ ÙÙ Ø£Ù ÙÙØª ÙÙ
+ÙÙÙ Ø§ÙØ¶ØºØ· ÙÙØ§.<br> Ø³ØªØšÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙØªÙ ØªØ¹Ù
+Ù Ø¹ÙÙÙØ§ Ø¯ÙÙ ØªØºÙØ±.  
+}  
+
+_textstopbuild_ [l=ar] {ÙÙÙ Ø¹Ù
+ÙÙØ© Ø§ÙØšÙØ§Ø¡}  
+
+_textbild3_ [l=ar] {Ø¥Ø°Ø§ ØªØ±ÙØª ÙØ°Ù Ø§ÙØµÙØ­Ø© (ÙÙÙ
+ ØªÙØº Ø¹Ù
+ÙÙØ© Ø§ÙØšÙØ§Ø¡ ØšØ§ÙØ¶ØºØ· Ø¹ÙÙ Ø²Ø± "ÙÙÙ Ø§ÙØšÙØ§Ø¡")Ø Ø³ØªØ³ØªÙ
+Ø± Ø¹Ù
+ÙÙØ© ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ÙØªØ«ØšØª ØšÙ
+Ø¬Ø±Ø¯ Ø§ÙØªÙ
+Ø§ÙÙØ§.}  
+
+_textbuildcancelled_ [l=ar] {Ø§ÙØºÙ Ø§ÙØšÙØ§Ø¡}  
+
+_textbildcancel1_ [l=ar] {Ø£ÙØºÙØª Ø¹Ù
+ÙÙØ© ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©. Ø§Ø³ØªØ®Ø¯Ù
+ Ø§ÙØ£Ø²Ø±Ø§Ø± Ø§ÙØµÙØ±Ø§Ø¡ ØšØ£Ø³ÙÙ ÙÙØªØºÙÙØ± ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø£Ù Ø£Ø¹Ø¯ ØªÙÙÙØ° Ø¹Ù
+ÙÙØ© Ø§ÙØšÙØ§Ø¡ Ù
+Ù Ø§ÙØšØ¯Ø§ÙØ©.}  
+
+_textbsupdate1_ [l=ar] {Building status update in 1 second}  
+_textbsupdate2_ [l=ar] {ØªØ­Ø¯ÙØ« Ø­Ø§ÙØ© Ø§ÙØšÙØ§Ø¡ ÙÙ}  
+_textseconds_ [l=ar] {Ø«ÙØ§ÙÙ}  
+
+_textfailmsg11_ [l=ar] {ÙØ§ ÙÙ
+ÙÙ ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø­ÙØ« ÙØ§ ÙÙØ¬Ø¯ ØšÙØ§ ØšÙØ§ÙØ§Øª. ØªØ£ÙØ¯ Ù
+Ù Ø£ÙÙ ÙÙØ¬Ø¯ Ø¹ÙÙ Ø§ÙØ£ÙÙ Ù
+Ø¬ÙØ¯ Ø£Ù Ù
+ÙÙ Ù
+Ø­Ø¯Ø¯ ÙÙ ØµÙØ­Ø© <i>Ù
+ØµØ¯Ø± Ø§ÙØšÙØ§ÙØ§Øª</i> Ø¹ÙÙ Ø£Ù ÙÙÙÙ Ù
+Ù Ø§ÙÙÙØ¹ Ø§ÙØ°Ù ÙÙ
+ÙÙ ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone Ø§ÙØªØ¹Ø§Ù
+Ù Ù
+Ø¹Ù Ø£Ù
+Ø§ ÙÙ Ø­Ø§ÙØ© Ø§Ø®ØªÙØ§Ø± Ù
+Ø¬ÙØ¯ ÙÙØ¬Øš Ø£ÙØ¶Ø§ Ø£Ù ÙÙÙÙ Ù
+Ø­ØªÙÙØ§ Ø¹ÙÙ Ù
+ÙÙØ§Øª Ù
+Ù Ø§ÙÙÙØ¹ Ø§ÙØ°Ù ÙØªØ¹Ø§Ù
+Ù Ù
+Ø¹Ù Ø§ÙØšØ±ÙØ§Ù
+Ø¬.}  
+
+_textfailmsg21_ [l=ar] {ÙØ§ ÙÙ
+ÙÙ ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© (ÙØŽÙ ÙÙ Ù
+ÙÙ import.pl)}  
+_textfailmsg31_ [l=ar] {ÙØ§ ÙÙ
+ÙÙ ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© (ÙØŽÙ ÙÙ Ù
+ÙÙ buildcol.pl).}  
+_textfailmsg41_ [l=ar] {Ø¹Ù
+ÙÙØ© Ø¥ÙØŽØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ØªÙ
+Øª ØšÙØ¬Ø§Ø­ ÙÙÙÙ ÙØ§ ÙÙ
+ÙÙ ØªØ«ØšÙØªÙØ§.}  
+_textfailmsg71_ [l=ar] {Ø­Ø¯Ø« Ø®Ø·Ø£ ØºÙØ± Ù
+ØªÙÙØ¹ Ø£Ø«ÙØ§Ø¡ Ù
+Ø­Ø§ÙÙØ© ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}  
+
+
+_textblcont_ [l=ar] {Ø³Ø¬Ù Ø§ÙØšÙØ§Ø¡ ÙØ­ØªÙÙ Ø¹ÙÙ Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙØªØ§ÙÙØ©:}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=ar] {Ø§ÙÙÙÙÙ Ø§ÙØªÙÙØ§ØŠÙ}  
+_textmore_ [l=ar] {Ù
+Ø²ÙØ¯}  
+_textinfo_ [l=ar] {Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}  
+_textsrce_ [l=ar] {Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙÙ
+ØµØ¯Ø±ÙØ©}  
+_textconf_ [l=ar] {Ø­Ø¯Ø¯ Ø®ØµØ§ØŠØµ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}  
+_textdel_ [l=ar] {Ø­Ø°Ù Ù
+Ø¬Ù
+ÙØ¹Ø©}  
+_textexpt_ [l=ar] {ØªØµØ¯ÙØ± Ù
+Ø¬Ù
+ÙØ¹Ø©}  
+
+_textdownloadingfiles_ [l=ar] {ØªØ­Ù
+ÙÙ Ø§ÙÙ
+ÙÙØ§Øª ...}  
+_textimportingcollection_ [l=ar] {ØªØµØ¯ÙØ± Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ...}  
+_textbuildingcollection_ [l=ar] {ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ...}  
+_textcreatingcollection_ [l=ar] {Ø¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø© ...}  
+
+_textcollectorblurb_ [l=ar] {<i>Ø§ÙÙÙÙ
+ Ø£ÙÙÙ Ù
+Ù Ø§ÙØ³ÙÙ
+ØªÙÙÙ
+ Ø¹Ù
+ÙÙØ© ØšÙØ§Ø¡ ÙØªÙØ²ÙØ¹ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ø¹ÙÙ Ù
+Ø³ØŠÙÙÙØ© ÙØšÙØ±Ø© Ø§ÙØªÙ ÙØ¯ ØªØ¬Ø¹ÙÙ ØªÙÙØ± Ù
+ÙÙØ§ ÙØšÙ Ø£Ù ØªØšØ¯Ø£.
+ÙÙÙØ§Ù ÙØ¶Ø§ÙØ§ ØªØªØ¹ÙÙ ØšØ­ÙÙÙ Ø§ÙÙ
+ÙÙÙØ© Ø§ÙÙÙØ±ÙØ©: ÙÙÙØ³ Ù
+Ø¹ÙÙ Ø£ÙÙ ÙÙ
+ÙÙÙ Ø§ÙÙØµÙÙ Ø¥ÙÙ Ø§ÙÙØ«Ø§ØŠÙ Ø£ÙÙ ÙÙ
+ÙÙÙ Ø£Ù ØªØ¹Ø·ÙÙØ§ ÙØºÙØ±Ù.
+ÙÙØ°ÙÙ ÙÙØ¬Ø¯ ÙØ¶Ø§ÙØ§ Ø§Ø¬ØªÙ
+Ø§Ø¹ÙØ©: ÙÙØ¬Øš Ø£Ù ØªØ­ØªØ±Ù
+ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙØ¹Ø§Ø¯Ø§Øª ÙØ§ÙØªÙØ§ÙÙØ¯ Ø§ÙØ®Ø§ØµØ© ØšØ§ÙÙ
+Ø¬ØªÙ
+Ø¹ Ø§ÙØ°Ù Ø³ØªÙØŽØ± ÙÙÙ.
+ÙÙ
+Ø§ ÙÙØ¬Ø¯ Ø£Ø®ÙØ§ÙÙØ§Øª Ø¹Ø§Ù
+Ø©: ÙÙÙØ§Ù Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù Ø£ØŽÙØ§Ø¡ ÙØ§ ÙØµØ­ Ø£Ù ØªÙÙÙ Ù
+ØªØ§Ø­Ø© ÙÙØºÙØ±.
+<br>Ù
+Ù Ø­ÙÙ
+Ø© Ø§ÙØ§ÙØªÙ
+Ø§Ù
+ ØšÙÙØ© Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª ÙØ§Ø³ØªØ®Ø¯Ø§Ù
+ÙØ§ ÙÙ Ù
+Ø­ÙÙØ§
+</i>}  
+
+_textcb1_ [l=ar] {ÙØ³Ø§Ø¹Ø¯ "Ø§ÙÙ
+Ø¬Ù
+Ø¹" Ø¹ÙÙ Ø¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ø¬Ø¯ÙØ¯Ø©Ø Ø£Ù Ø§ÙØªØ¹Ø¯ÙÙ ÙØ§ÙØ¥Ø¶Ø§ÙØ© Ø¥ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ù
+ÙØ¬ÙØ¯Ø© ÙØ¹ÙØ§Ù. ÙÙÙÙØ§Ù
+ ØšÙØ°Ø§ Ø³ØªØ¬Ø¯ Ø¥Ø±ØŽØ§Ø¯Ø§Øª Ù
+ØªØªØ§ØšØ¹Ø© Ø¹Ù Ø§ÙØµÙØ­Ø§Øª Ø§ÙØªÙ ØªØªØ·ÙØš Ø¥Ø¶Ø§ÙØ© Ù
+Ø¹ÙÙÙ
+Ø§Øª.}  
+
+_textcb2_ [l=ar] {ÙÙ Ø§ÙØšØ¯Ø§ÙØ© ÙØ¬Øš Ø£Ù ØªØ­Ø¯Ø¯ Ù
+Ø§ Ø¥Ø°Ø§}  
+_textcnc_ [l=ar] {Ø¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø© Ø¬Ø¯ÙØ¯Ø©}  
+_textwec_ [l=ar] {Ø§ÙØ¹Ù
+Ù ÙÙ ÙØ§Ø­Ø¯Ø© Ù
+ÙØ¬ÙØ¯Ø© Ø£Ù Ø¥Ø¶Ø§ÙØ© ØšÙØ§ÙØ§Øª ÙÙØ§ Ø£Ù Ø­Ø°ÙÙØ§.}  
+
+_textcb3_ [l=ar] {ÙÙÙ ØªØšÙÙ Ø£Ù ØªØ¹Ø¯Ù ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ø±ÙÙ
+ÙØ© ÙØ¬Øš Ø£Ù ØªÙÙÙ
+ ØšØ¹Ù
+ÙÙØ© Ø§ÙØ¯Ø®ÙÙ.
+ÙØ°Ø§ Ø§ÙØ¥Ø¬Ø±Ø§Ø¡ ÙØ­Ù
+ÙÙ Ù
+Ù Ø¯Ø®ÙÙ Ø¢Ø®Ø±ÙÙ Ø¹ÙÙ Ø­Ø§Ø³ØšÙ ÙØªØºÙÙØ± Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙØ®Ø§ØµØ© ØšÙ.
+Ù
+ÙØ§Ø­ØžØ©: ÙØ£Ø³ØšØ§Øš Ø£Ù
+Ù Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø³ÙÙ ÙØªÙ
+ Ø®Ø±ÙØ¬Ù Ù
+Ù Ø§ÙØšØ±ÙØ§Ù
+Ø¬ ØšØ¹Ø¯ 30 Ø¯ÙÙÙØ© Ù
+Ù ÙÙØª Ø¯Ø®ÙÙÙ. ÙÙØ§ Ø¯Ø§Ø¹Ù ÙÙÙÙÙ Ø¥Ù Ø­Ø¯Ø« ÙØ°Ø§! -- ÙØ³ÙÙ ÙØªÙ
+ Ø¯Ø¹ÙØªÙ ÙÙØ¯Ø®ÙÙ Ù
+Ø±Ø© Ø£Ø®Ø±Ù ÙÙÙ
+ÙÙÙ Ø§ÙØ§Ø³ØªÙ
+Ø±Ø§Ø± ÙÙ ÙÙØ³ Ø§ÙÙ
+ÙØ§Ù Ø§ÙØ°Ù ØªØ±ÙØªÙ.}  
+
+_textcb4_ [l=ar] {Ù
+Ù ÙØ¶ÙÙ Ø£Ø¯Ø®Ù Ø§Ø³Ù
+ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ±Ø Ø«Ù
+ Ø§Ø¶ØºØ· Ø§ÙØ²Ø± ÙØªØ³Ø¬Ù Ø¯Ø®ÙÙÙ.}  
+
+_textfsc_ [l=ar] {Ø§Ø®ØªØ± Ø£ÙÙØ§ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙØªÙ ØªØ±ÙØ¯ Ø£Ù ØªØ¹Ù
+Ù Ù
+Ø¹ÙØ§ (Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙÙ
+Ø­Ù
+ÙØ© Ù
+Ù Ø¹Ù
+ÙÙØ© Ø§ÙØªØ¹Ø¯ÙÙ Ø³ÙÙ ÙÙ ØªØžÙØ± ÙÙ ÙØ°Ù Ø§ÙÙØ§ØŠÙ
+Ø©).}  
+
+_textwtc_ [l=ar] {ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙØªÙ ÙÙ
+Øª ØšØ§Ø®ØªÙØ§Ø±ÙØ§Ø ÙÙ
+ÙÙÙ}  
+_textamd_ [l=ar] {Ø£Ø¶Ù Ù
+Ø²ÙØ¯ Ù
+Ù Ø§ÙØšÙØ§ÙØ§Øª ÙÙÙ
+ ØšØ¥Ø¹Ø§Ø¯Ø© ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}  
+_textetc_ [l=ar] {Ø¹Ø¯Ù Ù
+ÙÙ Ø®ØµØ§ØŠØµ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø«Ù
+ Ø£Ø¹Ø¯ ØšÙØ§Ø¡ÙØ§}  
+_textdtc_ [l=ar] {Ø¥Ø­Ø°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ØšØ§ÙÙØ§Ù
+Ù}  
+_textetcfcd_ [l=ar] {ØªØµØ¯ÙØ± Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø¥ÙÙ ÙØ±Øµ Ù
+Ø¯Ù
+Ø¬ ÙØ¹Ù
+Ù ØªÙÙØ§ØŠÙØ§ Ù
+Ø¹ ÙØžØ§Ù
+ Windows}  
+_textcaec_ [l=ar] {ØªØºÙÙØ± Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+ÙØ¬ÙØ¯Ø©}  
+_textnwec_ [l=ar] {ÙØ§ ÙÙØ¬Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ù
+ØµØ±Ø­ ØšØ§ÙØªØ¹Ø¯ÙÙ ÙÙ Ù
+Ø­ØªÙÙØ§ØªÙØ§}  
+_textcianc_ [l=ar] {Ø¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø© Ø¬Ø¯ÙØ¯Ø©}  
+_texttsosn_ [l=ar] {ÙÙ ØªØªØ§ØšØ¹ Ø¹Ù
+ÙØ© Ø¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+ÙØªØšØ© Ø±ÙÙ
+ÙØ© Ø¬Ø¯ÙØ¯Ø© ÙØ¥Ù Ø§ÙØ®Ø·Ø© Ø§ÙØªÙ ØªØ­ØªØ§Ø¬ÙØ§ ÙÙ:}  
+_textsin_ [l=ar] {Ø­Ø¯Ø¯ Ø§ÙØ§Ø³Ù
+ (ÙØ§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙØ£Ø®Ø±Ù Ø§ÙÙ
+Ø±ØªØšØ·Ø©)}  
+_textswts_ [l=ar] {Ø­Ø¯Ø¯ Ù
+ÙØ§Ù ÙØ±ÙØ¯ Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙÙ
+ØµØ¯Ø±ÙØ©}  
+_textatco_ [l=ar] {ØªØ¹Ø¯ÙÙ Ø®ÙØ§Ø±Ø§Øª Ø§ÙØ®ØµØ§ØŠØµ (ÙÙÙ
+Ø³ØªØ®Ø¯Ù
+ Ø§ÙÙ
+Ø­ØªØ±Ù ÙÙØ·)}  
+_textbtc_ [l=ar] {"ØšÙØ§Ø¡" Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©(Ø£ÙØžØ± ØšØ£Ø³ÙÙ)}  
+_textpvyh_ [l=ar] {Ø§Ø¹Ø±Ø¶ Ø§ÙØ¢Ù Ø¹Ù
+ÙÙ ØšÙÙ ÙØ®Ø±.}  
+
+_texttfsiw_ [l=ar] {ÙÙÙÙ
+ Ø§ÙÙÙ
+ØšÙÙØªØ± ØšØ§ÙÙ
+Ø±Ø­ÙØ© Ø§ÙØ±Ø§ØšØ¹Ø© ØšØ§ÙÙØ§Ù
+Ù. Ø­ÙØ« ÙÙØŽÙØ¡ ÙÙ Ù
+Ø±Ø­ÙØ© "Ø§ÙØšÙØ§Ø¡" ÙÙ Ø§ÙÙØŽØ§ÙØ§Øª ÙÙØ¬Ù
+Ø¹ ÙØ§ÙØ© Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙÙ
+Ø·ÙÙØšØ© ÙØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©. ÙÙÙÙ ÙØ¬Øš ÙÙ Ø§ÙØšØ¯Ø§ÙØ© Ø£Ù ØªØ­Ø¯Ø¯ Ø£ÙØª ÙØ°Ù Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª .}  
+
+_textadab_ [l=ar] {ÙÙ Ø§ÙØŽÙÙ Ø§ÙØ°Ù ÙØžÙØ± ØšØ£Ø³ÙÙ Ø³ÙØ³Ø§Ø¹Ø¯Ù ÙØªØ­Ø¯ÙØ¯ Ù
+ÙÙØ¹Ù.
+Ø§ÙØ²Ø± Ø§ÙØ£Ø®Ø¶Ø± ÙØ³ØªØ®Ø¯Ù
+ ÙØšØ¯Ø§ÙØ© ØªÙÙÙØ° Ø¹Ù
+ÙÙØ§Øª Ù
+ØªØªØ§ÙÙØ©. ÙØšÙ
+Ø¬Ø±Ø¯ ÙÙ ØªØ¯Ø®Ù ÙÙ ØªÙÙ Ø§ÙØ¹Ù
+ÙÙØ§Øª Ø³ÙÙ ÙØªØºÙØ± ÙÙÙÙ Ø¥ÙÙ Ø§ÙÙÙÙ Ø§ÙØ£ØµÙØ±. ÙÙÙ
+ÙÙÙ Ø§ÙØ±Ø¬ÙØ¹ ÙÙØµÙØ­Ø© Ø§ÙØ³Ø§ØšÙØ© ØšØ§ÙØ¶ØºØ· Ø¹ÙÙ Ø§ÙØ²Ø± Ø§ÙØ£ØµÙØ± ÙÙ Ø§ÙØŽÙÙ.}  
+
+_textwyar_ [l=ar] {Ø¹ÙØ¯Ù
+Ø§ ØªÙÙÙ Ù
+Ø³ØªØ¹Ø¯Ø Ø§Ø¶ØºØ· Ø¹ÙÙ Ø§ÙØ²Ø± Ø§ÙØ£Ø®Ø¶Ø± Ø§ÙØ®Ø§Øµ ØšÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ÙØªØšØ¯Ø£ ÙÙ Ø¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+ÙØªØšØªÙ Ø§ÙØ±ÙÙ
+ÙØ© Ø§ÙØ¬Ø¯ÙØ¯Ø©!}  
+
+_textcnmbs_ [l=ar] {ÙØ¬Øš ØªØ­Ø¯ÙØ¯ Ø§Ø³Ù
+ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}  
+_texteambs_ [l=ar] {Ø¹ÙÙØ§Ù Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙÙØªØ±ÙÙÙ ÙØ¬Øš Ø£Ù ÙØ­Ø¯Ø¯}  
+_textpsea_ [l=ar] {Ø­Ø¯Ø¯ Ø¹ÙÙØ§Ù Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ Ù
+ØªØšØ¹Ø§ Ø§ÙØµÙØ§ØºØ© username@domain}  
+_textdocmbs_ [l=ar] {ÙØµÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ÙØ¬Øš Ø£Ù ÙØ­Ø¯Ø¯}  
+
+_textwcanc_ [l=ar] {Ø¹ÙØ¯ Ø¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø© Ø¬Ø¯ÙØ¯Ø© Ø³ØªØ­ØªØ§Ø¬ Ø¥ÙÙ Ø¥Ø¯Ø®Ø§Ù ØšØ¹Ø¶ Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙÙ
+ØšØ¯ØŠÙØ© Ø¹Ù Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙÙ
+ØµØ¯Ø±ÙØ©. ÙÙØ°Ù Ø§ÙØ¹Ù
+ÙÙØ© ØªÙÙÙ ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ù ØµÙØ­Ø§Øª Ø§ÙØ¥ÙØªØ±ÙØª ØªÙØ±Ø£ Ø¹Ù Ø·Ø±ÙÙ Ø§ÙÙ
+Ø¬Ù
+Ø¹. ÙÙÙ Ø£Ø³ÙÙ Ø§ÙØµÙØ­Ø© ÙØ¹Ø±Ø¶ Ø§ÙØŽØ±ÙØ· ØªØªØ§ØšØ¹ Ø§ÙØµÙØ­Ø§Øª Ø§ÙØªÙ Ø§ÙØªÙ
+ÙØª.}  
+
+_texttfc_ [l=ar] {Ø¹ÙÙØ§Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©:}  
+
+_texttctiasp_ [l=ar] {Ø¹ÙÙØ§Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ÙÙ Ø¹ØšØ§Ø±Ø© Ø¹Ù Ø¬Ù
+ÙØ© ÙØµÙØ±Ø© ØªØ³ØªØ®Ø¯Ù
+ ÙÙ Ø§ÙÙ
+ÙØªØšØ© Ø§ÙØ±ÙÙ
+ÙØ© ÙØªÙ
+ÙÙØ² Ø§ÙÙ
+Ø­ØªÙÙØ§Øª ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©. Ù
+Ø«Ù: Computer Science Technical Reports" Ù"Humanity Development Library."}  
+
+_textcea_ [l=ar] {Ø¹ÙÙØ§Ù Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ:}  
+
+_textteas_ [l=ar] {ÙØ°Ø§ Ø§ÙØ¹ÙÙØ§Ù Ø§ÙØ¥ÙÙØªØ±ÙÙÙ ÙØ¹Ø¯ ÙÙØ·Ø© Ø§ÙØ§ØªØµØ§Ù Ø§ÙØ£ÙÙÙ ÙÙÙ
+Ø¬Ù
+ÙØ¹Ø©.
+ Ø¥Ø°Ø§ Ù
+Ø§ Ø§ÙØªØŽÙ ØšØ±ÙØ§Ù
+Ø¬ Greenstone Ø®Ø·Ø£ Ù
+Ø§Ø ÙØ³ÙÙ ÙÙÙÙ
+ ØšØ¥Ø±Ø³Ø§Ù ØªÙØ±ÙØ± ØªØŽØ®ÙØµÙ ÙÙÙ
+ØŽÙÙØ© Ø¹ÙÙ ÙØ°Ø§ Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ. ÙØ°Ø§ ÙÙ
+ ØšØ¥Ø¯Ø®Ø§Ù Ø¹ÙÙØ§Ù Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ ØšØ§ÙØµÙØºØ© Ø§ÙØªØ§ÙÙØ©:
+<tt>name@domain</tt>.
+}  
+
+_textatc_ [l=ar] {Ø¹Ù ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©:}  
+
+_texttiasd_ [l=ar] {ÙØ°Ø§ ÙØŽØ±Ø­ Ø§ÙØ£Ø³Ø³ Ø§ÙØªÙ ØªØ­ÙÙ
+ Ù
+Ø§ ØªØ­ØªÙÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©. ÙØªØžÙØ± ÙÙ Ø§ÙØµÙØ­Ø© Ø§ÙØ£ÙÙÙ ÙØ¹Ø±Ø¶ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©Ø}  
+
+_textypits_ [l=ar] {Ù
+ÙÙØ¹Ù ÙÙ Ø§ÙØªØ³ÙØ³Ù Ù
+ÙØ¶Ø­ ØšÙØ§Ø³Ø·Ø© Ø§ÙØ³ÙÙ
+ Ø§ÙØ³ÙÙÙ -- ÙÙ
+ ÙØ°Ù Ø§ÙØ­Ø§ÙØ© Ø Ø§Ù "Ù
+Ø¹ÙÙÙ
+Ø© Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©" Ù
+Ø±Ø­ÙØ©
+Ù
+ØµØ¯Ø± Ø§ÙØšÙØ§ÙØ§Øª "Ø²Ø±"
+}  
+
+_srcebadsources_ [l=ar] {<p>ÙØ§Ø­Ø¯ Ø£Ù Ø£ÙØ«Ø± Ù
+Ù Ù
+ØµØ§Ø¯Ø± Ø§ÙØ¥Ø¯Ø®Ø§Ù ÙÙØ³Øª Ù
+ØªØ§Ø­Ø© (marked
+_iconcross_ below).
+
+<p>ÙØ¯ ÙÙÙÙ ÙØ°Ø§ ØšØ³ØšØš
+<ul>
+<li>Ø¹Ø¯Ù
+ ÙØ¬ÙØ¯ Ø§ÙÙ
+ÙÙ Ø£Ù Ø§ØªØµØ§Ù FTP Ø£ÙURL.
+<li>You need to dial up your ISP first.
+<li>You are trying to access a URL from behind a firewall (this is the case
+if you normally have to present a username and password to access the
+internet).
+</ul>
+
+<p>If this is a URL that you can see in your browser, it may be coming from
+a locally cached copy. Unfortunately, locally cached copies are invisible
+to our mirroring process. In this case we recommend that you download the
+pages using your browser first.
+}  
+
+_textymbyco_ [l=ar] {<p>ÙÙ
+ÙÙÙ Ø£Ù ØªØ£Ø³Ø³ Ù
+Ø¬Ù
+ÙØ¹ØªÙ Ø¹ÙÙ
+ <ul>
+ <li>Ø§ÙÙÙÙÙ Ø§ÙØ¥ÙØªØ±Ø§Ø¶Ù <dl><dd>ÙÙ
+ÙÙ Ø§Ù ØªØ­ØªÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙØ¬Ø¯ÙØ¯Ø© Ø¹ÙÙ Ø§ÙØ£ØŽÙØ§Ù : HTML, plain text, ""m-box"" email, PDF, RTF, MS Word, PostScript, PowerPoint, 
+ Excel, images, CDS/ISIS. (.mbx).</dd></dl>
+ <li>Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙÙ
+ÙØ¬ÙØ¯Ø©
+ <dl><dd>Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØªÙ Ø³ØªÙÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙØ¬Ø¯ÙØ¯Ø© ÙØ¬Øš Ø£Ù ØªÙÙÙ Ù
+Ù ÙÙØ³ ÙÙØ¹ Ø§ÙÙ
+ÙÙØ§Øª ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙÙ
+ÙØ¬ÙØ¯Ø©</dd></dl>
+ </ul>}  
+
+_textbtco_ [l=ar] {Ø£Ø³Ø³ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}  
+_textand_ [l=ar] {Ø£Ø¶Ù ØšÙØ§ÙØ§Øª Ø¬Ø¯ÙØ¯Ø©}  
+_textad_ [l=ar] {Ø§Ø¶Ø§ÙØ© ØšÙØ§ÙØ§Øª :}  
+
+_texttftysb_ [l=ar] {Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØªÙ ØªÙ
+ ØªØ­Ø¯ÙØ¯ÙØ§ Ø³ÙÙ ÙØªÙ
+ Ø¥Ø¶Ø§ÙØªÙØ§ ÙÙÙ
+Ø¬Ù
+ÙØ¹Ø©. ØªØ£ÙØ¯ Ù
+Ù Ø£Ù ÙÙ
+ ØªÙÙ
+ ØªØ­Ø¯ÙØ¯ Ù
+ÙÙØ§Øª ØªÙ
+ Ø§Ø®ØªÙØ§Ø±ÙØ§ Ø­ØªÙ ÙØ§ ØªØªØ¶Ù
+Ù Ù
+Ø¬Ù
+ÙØ¹ØªÙ ÙØ³Ø®ØªÙÙ Ù
+Ù ÙØ°Ø§ Ø§ÙÙ
+ÙÙ. ÙØªØ­Ø¯Ø¯ Ø§ÙÙ
+ÙÙØ§Øª ØšÙØªØ§ØšØ© ÙØ§Ù
+Ù Ù
+Ø³Ø§Ø±ÙØ§ ÙÙ
+Ø§ ØªØ­Ø¯Ø¯ ØµÙØ­Ø§Øª Ø§ÙØ¥ÙØªØ±ÙØª ØšÙØªØ§ØšØ© Ø¹ÙÙØ§ÙÙØ§.}  
+
+_textis_ [l=ar] {Ø§Ø¯Ø®Ù Ø§ÙÙ
+ØµØ§Ø¯Ø±:}  
+
+_textddd1_ [l=ar] {<p>Ø¥Ø°Ø§ ÙÙØª ØªØ³ØªØ®Ø¯Ù
+ Ù
+ÙÙ :// Ø£Ù ftp:// ÙØªØ­Ø¯ÙØ¯ Ù
+ÙÙØ ÙØ¥Ù ÙØ°Ø§ Ø§ÙÙ
+ÙÙ Ø³ÙÙ ÙØªÙ
+ ØªØ­Ù
+ÙÙÙ.
+
+<p>Ø¥Ø°Ø§ ÙÙØª ØªØ³ØªØ®Ø¯Ù
+ http:// ÙØ³ÙØ¹ØªÙ
+Ø¯ Ø§ÙØ£Ù
+Ø± ÙÙØ§ Ø¹ÙÙ Ù
+Ø§ Ø¥Ø°Ø§ ÙØ§Ù Ø§ÙØ¹ÙÙØ§Ù ÙØ¹Ø·ÙÙ ØµÙØ­Ø© Ø¥ÙØªØ±ÙØª Ø¹Ø§Ø¯ÙØ© Ø£Ù ÙØ§ØŠÙ
+Ø© ØšÙ
+ÙÙØ§Øª. 
+
+<p>Ø¥Ø°Ø§ ÙÙØª ØªØ³ØªØ®Ø¯Ù
+ Ù
+ÙÙ :// Ø£Ù ftp:// ÙÙÙ ØªØ­Ø¯Ø¯ Ù
+Ø¬ÙØ¯ Ø£Ù Ø¯ÙÙÙ Ø£Ù ØªØ¹Ø·Ù Ø¹ÙÙØ§Ù http:// ÙØ­ÙÙ ØšØ¯ÙØ±Ù Ø¥ÙÙ ÙØ§ØŠÙ
+Ø© ØšØ§ÙÙ
+ÙÙØ§Øª ÙØ¥Ù ÙÙ Ø§ÙÙ
+ÙÙØ§Øª ÙÙ ÙØ°Ø§ Ø§ÙÙ
+Ø¬ÙØ¯ ÙØ§ÙÙ
+Ø¬ÙØ¯Ø§Øª Ø§ÙÙØ±Ø¹ÙØ© Ø§ÙØªÙ Ø¯Ø§Ø®ÙÙ Ø³ÙÙ ØªÙÙÙ Ø¶Ù
+Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©.
+
+<p>Ø§Ø¶ØºØ· Ø¹ÙÙ Ø²Ø± "Ù
+Ø²ÙØ¯ Ù
+Ù Ø§ÙÙ
+ØµØ§Ø¯Ø±" ÙÙÙ ØªØ­ØµÙ Ø¹ÙÙ Ù
+Ø±ØšØ¹Ø§Øª Ø¥Ø¶Ø§ÙØ© Ø£Ø®Ø±Ù.}  
+
+_textddd2_ [l=ar] {<p>Ø§Ø¶ØºØ· Ø¹ÙÙ Ø§ÙØ£Ø²Ø±Ø§Ø± Ø§ÙØ®Ø¶Ø±Ø§Ø¡. Ø¥Ø°Ø§ ÙÙØª Ù
+Ø³ØªØ®Ø¯Ù
+ Ù
+Ø­ØªØ±Ù Ø±ØšÙ
+Ø§ ØªØ³ØªØ·ÙØ¹ Ø¶ØšØ· Ø®ØµØ§ØŠØµ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©. ØšØ®ÙØ§Ù Ø°ÙÙ Ø§Ø°ÙØš Ø¥ÙÙ Ø®Ø·ÙØ© Ø§ÙØšÙØ§Ø¡ Ù
+ØšØ§ØŽØ±Ø©. ÙØªØ°ÙØ± Ø£ÙÙ ÙÙ
+ÙÙÙ Ø§ÙØ±Ø¬ÙØ¹ Ø¥ÙÙ Ø£Ù Ù
+Ù Ø§ÙØ®Ø·ÙØ§Ø· Ø§ÙØ³Ø§ØšÙØ© ØšØ§ÙØ¶ØºØ· Ø¹ÙÙ Ø§ÙØ²Ø± Ø§ÙØ£ØµÙØ± Ø§ÙØ®Ø§Øµ ØšÙØ§.}  
+
+_textconf1_ [l=ar] {<p>ÙØªÙ
+ Ø§ÙØªØ­ÙÙ
+ ÙÙ ØšÙØ§Ø¡ ÙØ¹Ø±Ø¶ ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø¹Ù Ø·Ø±ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ù Ø§ÙÙ
+Ø­Ø¯Ø¯Ø§Øª ÙÙ "Ù
+ÙÙ Ø§ÙØ®ØµØ§ØŠØµ".  Ø­ÙØ« ÙÙ
+ÙÙ ÙÙÙ
+Ø³ØªØ®Ø¯Ù
+ Ø§ÙÙ
+Ø­ØªØ±Ù Ø£Ù ÙØ³ØªØšØ¯Ù ÙØ°Ù Ø§ÙØ®ØµØ§ØŠØµ.
+
+<center><p><b>Ø¥Ù ÙÙØª Ù
+Ø³ØªØ®Ø¯Ù
+ ØºÙØ± Ù
+Ø­ØªØ±Ù, Ø¥Ø°ÙØš Ø¥ÙÙ Ø£Ø³ÙÙ Ø§ÙØµÙØ­Ø©.</b></center> 
+
+<p>ÙØ§Ø³ØªØšØ¯Ø§Ù Ø§ÙØ®ØµØ§ØŠØµ Ø§ÙÙ
+ÙØ¬ÙØ¯Ø©, ÙÙ
+ ØšØªØ¹Ø¯ÙÙ Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙØªÙ ØªØžÙØ± ØšØ£Ø³ÙÙ.
+Ø¥Ø°Ø§ ÙÙ
+Øª ØšØªØ¹Ø¯ÙÙØ§Øª ØºÙØ± ØµØ­ÙØ­Ø©, Ø¥Ø¶ØºØ· Ø¹ÙÙ Ø²Ø± "Reset" ÙÙØ¹ÙØ¯Ø© Ø¥ÙÙ Ø§ÙØ®ØµØ§ØŠØµ Ø§ÙØ£ØµÙÙØ©.
+}  
+
+_textreset_ [l=ar] {ØšØ§ÙÙ}  
+
+
+_texttryagain_ [l=ar] {Ø±Ø¬Ø§Ø¡ <a href="_httppagecollector_" target=_top>Ø§Ø³ØªØ£ÙØ§Ù Ø§ÙÙ
+Ø¬Ù
+Ù
+ÙØ¹Ø© ÙØ§ÙÙ
+Ø­Ø§ÙÙØ© Ù
+Ø±Ø© Ø§Ø®Ø±Ù</a>
+}  
+
+
+_textretcoll_ [l=ar] {Ø§ÙØ¹ÙØ¯Ø© Ø¥ÙÙ Ø§ÙÙ
+Ø¬Ù
+Ø¹}  
+
+_textdelperm_ [l=ar] {ØšØ¹Ø¶ Ø£Ù ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© _cgiargbc1dirname_ ÙØ§ ÙÙ
+ÙÙ Ù
+Ø­ÙÙØ§Ø Ø±ØšÙ
+Ø§ ÙÙÙÙ Ø§ÙØ³ØšØš:
+<ul>
+<li>Ø£Ù ØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙØ§ ÙØ³Ù
+Ø­ ØšØ¥Ø²Ø§ÙØ© _gsdlhome_/collect/_cgiargbc1dirname_
+<br>ÙØ§Ù
+ÙØ³.
+Ø±ØšÙ
+Ø§ ØªØ­ØªØ§Ø¬ Ø¥ÙÙ Ø¥Ø²Ø§ÙØ© ÙØ°Ø§ Ø§ÙÙØ§Ù
+ÙØ³ ÙØ¯ÙÙØ§Ù ÙÙÙ ØªÙÙ
+Ù Ø¹Ù
+ÙÙØ© Ø¥Ø²Ø§ÙØ© _cgiargbc1dirname_
+Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ù ÙØ°Ø§ Ø§ÙØ­Ø§Ø³Øš.</li>
+<li> ÙØ§ ÙÙ
+ÙÙ ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone Ø£Ù ÙØŽØºÙ ØšØ±ÙØ§Ù
+Ø¬ _gsdlhome_/bin/script/delcol.pl. ØªØ£ÙØ¯ Ù
+Ù Ø£Ù Ø§ÙÙ
+ÙÙ ÙØ§ØšÙ ÙÙÙØ±Ø§Ø¡Ø© ÙØ§ÙØªØŽØºÙÙ.</li>
+</ul>
+
+}  
+
+_textdelinv_ [l=ar] {Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© _cgiargbc1dirname_ Ù
+Ø­Ù
+ÙØ© Ù
+Ù Ø¥Ø¬Ø±Ø§Ø¡ Ø§ÙØ­Ø°Ù Ø£Ù ØºÙØ± ØµØ§ÙØ­Ø©. ÙÙØ¯ Ø£ÙØºÙØª Ø¹Ù
+ÙÙØ© Ø§ÙØ­Ø°Ù.}  
+
+_textdelsuc_ [l=ar] {ØªÙ
+ Ø­Ø°Ù Ù
+Ø¬Ù
+ÙØ¹Ø© _cgiargbc1dirname_ ØšÙØ¬Ø§Ø­.}  
+
+_textclonefail_ [l=ar] {Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© _cgiargclonecol_ ÙØ§ ÙÙ
+ÙÙ Ø§Ø³ØªÙØ³Ø§Ø®ÙØ§. ÙØ£Ø³ØšØ§Øš Ø°ÙÙ ÙØ¯ ØªÙÙÙ: 
+<ul>
+<li> Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© _cgiargclonecol_ ØºÙØ± Ù
+ÙØ¬ÙØ¯Ø©
+<li> Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© _cgiargclonecol_ ÙÙØ³ ÙÙØ§ Ù
+ÙÙ Ø§ÙØ®ØµØ§ØŠØµ collect.cfg 
+<li> ØšØ±ÙØ§Ù
+Ø¬ Greenstone ØºÙØ± Ù
+ØµØ±Ø­ ÙÙ ØšØ§ÙØªØ¹Ø§Ù
+Ù Ù
+Ø¹ Ù
+ÙÙ Ø§ÙØ®ØµØ§ØŠØµ collect.cfg 
+</ul>}  
+
+_textcolerr_ [l=ar] {Ø®Ø·Ø£ ÙÙ Ø§ÙÙ
+Ø¬Ù
+Ø¹.}  
+
+_texttmpfail_ [l=ar] {ÙØŽÙ Ø§ÙÙ
+Ø¬Ù
+Ø¹ ÙÙ Ø§ÙÙØ±Ø§Ø¡Ø© Ø£Ù Ø§ÙÙØªØ§ØšØ© Ø¥ÙÙ Ø§ÙÙ
+ÙÙ Ø§ÙÙ
+Ø€ÙØª Ø£Ù Ø§ÙÙ
+Ø¬ÙØ¯Ø Ù
+Ù Ø§ÙÙ
+Ù
+ÙÙ Ø£Ù ÙÙÙÙ Ø§ÙØ³ØšØš
+<ul>
+<li> Ø£Ù ØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙÙØ³ ÙÙ Ø§ÙØ­Ù ÙÙ Ø§ÙÙØªØ§ØšØ© Ø£Ù Ø§ÙÙØ±Ø§Ø¡Ø© ÙÙ Ø§ÙÙ
+Ø¬ÙØ¯ _gsdlhome_/tmp
+     .
+</ul>}  
+
+_textmkcolfail_ [l=ar] {Ø§ÙÙ
+Ø¬Ù
+Ø¹ ÙØŽÙ ÙÙ Ø¥ÙØŽØ§Ø¡ ÙÙÙÙ Ø§ÙØ¯ÙÙÙ Ø§ÙÙ
+Ø·ÙÙØš Ù
+Ù ÙØšÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙØ¬Ø¯ÙØ¯Ø©
+(mkcol.pl failed). ÙØ¯ ÙÙÙÙ Ø§ÙØ³ØšØš:
+<ul>
+<li> ØºÙØ± Ù
+ØµØ±Ø­ ÙÙ Greenstone ØšØ§ÙÙØªØ§ØšØ© Ø¹ÙÙ Ù
+ÙÙ _gsdlhome_/tmp
+     directory.
+<li> mkcol.pl perl script errors.
+</ul>
+}  
+
+_textnocontent_ [l=ar] {Ø®Ø·Ø£ ÙÙ Ø§ÙÙ
+Ø¬Ù
+Ø¹: ÙÙ
+ ÙØªÙ
+ ÙØªØ§ØšØ© Ø§Ø³Ù
+ ÙÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙØ¬Ø¯ÙØ¯Ø©. Ø­Ø§ÙÙ Ø¥Ø¹Ø§Ø¯Ø© ØªØŽØºÙÙ Ø§ÙÙ
+Ø¬Ù
+Ø¹ Ù
+Ù Ø§ÙØšØ¯Ø§ÙØ©.}  
+
+_textrestart_ [l=ar] {Ø¥Ø¹Ø§Ø¯Ø© ØªØŽØºÙÙ Ø§ÙÙ
+Ø¬Ù
+Ø¹}  
+
+_textreloaderror_ [l=ar] {Ø­Ø¯Ø« Ø®Ø·Ø£ Ø£Ø«ÙØ§Ø¡ Ø¹Ù
+ÙÙØ© Ø¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø© Ø¬Ø¯ÙØ¯Ø©. Ø±ØšÙ
+Ø§ ÙÙÙÙ ÙØ°Ø§ ØšØ³ØšØš ÙÙ Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø²Ø±Ù "Back" Ø£Ù "Reload" (Ù
+Ù ÙØ¶ÙÙ ØªØ¬ÙØš Ø§Ø³ØªØ®Ø¯Ø§Ù
+ ÙØ°Ù Ø§ÙØ£Ø²Ø±Ø§Ø± Ø£Ø«ÙØ§Ø¡ Ø¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø© Ø¹Ù Ø·Ø±ÙÙ Ø§ÙÙ
+Ø¬Ù
+Ø¹). ÙØ§ÙØ¢Ù ÙÙØ¶Ù Ø£Ù ØªØ¹ÙØ¯ ØªØŽØºÙÙ Ø§ÙÙ
+Ø¬Ù
+Ø¹ Ù
+Ù Ø§ÙØšØ¯Ø§ÙØ©.}  
+
+_textexptsuc_ [l=ar] {ØªÙ
+ ØªØµØ¯ÙØ± Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© _cgiargbc1dirname_ ØšÙØ¬Ø§Ø­ Ø¥ÙÙ Ø¯ÙÙÙ
+_gsdlhome_/tmp/exported\__cgiargbc1dirname_ .}  
+
+_textexptfail_ [l=ar] {<p>ÙØŽÙ ÙÙ ØªØµØ¯ÙØ± Ù
+Ø¬Ù
+ÙØ¹Ø© _cgiargbc1dirname_ 
+ 
+ <p>Ø±ØšÙ
+Ø§ ÙØ±Ø¬Ø¹ Ø°ÙÙ Ø¥ÙÙ Ø£Ù  ØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙÙ
+ ÙÙÙ Ù
+Ø«ØšØª ØšÙØ§Ù
+Ù Ø§ÙÙ
+ÙÙÙØ§Øª Ø§ÙØªÙ ØªØ¯Ø¹Ù
+ ÙØžÙÙØ© "ØªØµØ¯ÙØ± Ø¥ÙÙ ÙØ±Øµ Ù
+Ø¯Ù
+Ø¬" "".
+ <ul>
+ 
+ <li>Ø¥Ø°Ø§ ÙÙ
+Øª ØšØªØ«ØšÙØª ÙØ³Ø®Ø© Ù
+Ù ØšØ±ÙØ§Ù
+Ø¬ Greenstone Ø£ÙØ¯Ù
+ Ù
+Ù Ø§ÙØ¥ØµØ¯Ø§Ø±Ø© 2.70w Ù
+Ù Ø§ÙÙØ±Øµ Ø§ÙÙ
+Ø¯Ù
+Ø¬ ÙÙÙ ØªÙÙÙ ÙØ°Ù Ø§ÙÙ
+ÙÙÙØ§Øª Ù
+Ø«ØšØªØ© Ù
+Ø¹ Ø§ÙØšØ±ÙØ§Ù
+Ø¬ Ø¥ÙØ§ Ø¥Ø°Ø§ ÙÙØª ÙØ¯ ÙÙ
+Øª ØšØ¥Ø®ØªÙØ§Ø±ÙØ§ .
+ ÙÙ
+ÙÙÙ Ø¥Ø¶Ø§ÙØ© ÙØ°Ù Ø§ÙÙ
+ÙÙÙØ§Øª ÙÙØšØ±ÙØ§Ù
+Ø¬ Ø§ÙÙ
+Ø«ØšØª ØšØ¥Ø¹Ø§Ø¯Ø© ØªØŽØºÙÙ Ø¹Ù
+ÙÙØ© Ø§ÙØªØ«ØšÙØª.
+ 
+ <li>Ø£Ù
+Ø§ Ø¥Ø°Ø§ ÙÙØª ÙØ¯ ÙÙ
+Øª ØšØªØ«ØšÙØª ØšØ±ÙØ§Ù
+Ø¬ Greenstone Ù
+Ù  Ø§ÙØ¥ÙØªØ±ÙØª ÙØ³ÙÙ ØªØ­ØªØ§Ø¬ Ø¥ÙÙ ØªØ­Ù
+ÙÙ ÙØªØ«ØšÙØª Ø­Ø²Ù
+ Ø£Ø®Ø±Ù ØªØ­ØªÙÙ Ø¹ÙÙ ÙØ°Ù Ø§ÙÙØžÙÙØ©. 
+ ÙÙ
+Ø²ÙØ¯ Ù
+Ù Ø§ÙØªÙØ§ØµÙÙ Ù
+Ù ÙØ¶ÙÙ ÙÙ
+ ØšØ²ÙØ§Ø±Ø© <a href=""http://www.greenstone.org"">http://www.greenstone.org</a> Ø£Ù Ø±Ø§Ø³Ù Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ <a
+  href=""mailto:greenstone@cs.waikato.ac.nz"">greenstone@cs.waikato.ac.nz</a}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=ar] {<p> Ø­Ø¯Ø¯ Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙØªØ§ÙÙØ© Ø¹Ù Ø§ÙÙ
+ÙÙ Ø«Ù
+ Ø§Ø®ØªØ± _textintro_ Ù
+Ù Ø£Ø³ÙÙ. </p>
+}  
+
+_textcaec_ [l=ar] {Ø¥Ø¶Ø§ÙØ© Ø¥ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+ÙØ¬ÙØ¯Ø©}  
+_textbild_ [l=ar] {Ù
+Ø§Ø¯Ø© Ù
+ÙØ¯Ø¹Ø©}  
+_textintro_ [l=ar] {Ø§Ø®ØªØ± Ù
+ÙÙ}  
+_textconfirm_ [l=ar] {ØªØ£ÙÙØ¯}  
+_textselect_ [l=ar] {Ø§Ø®ØªØ± Ù
+Ø¬Ù
+ÙØ¹Ø©}  
+_textmeta_ [l=ar] {Ø­Ø¯Ø¯ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§}  
+_textselectoption_ [l=ar] {Ø£Ø®ØªØ± Ù
+Ø¬Ù
+ÙØ¹Ø©...}  
+
+_texttryagain_ [l=ar] {Ù
+Ù ÙØ¶ÙÙ <a href="_httppagedepositor_" target=_top>Ø£Ø¹Ø¯ ØªØŽØºÙÙ Ù
+Ø®Ø²Ù Ø§ÙØšÙØ§ÙØ§Øª</a>
+ÙØ­Ø§ÙÙ Ù
+Ø±Ø© Ø£Ø®Ø±Ù.
+}  
+
+_textselectcol_ [l=ar] {Ø§Ø®ØªØ± Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙØªÙ ØªÙØ¯ Ø£Ù ØªØ¶ÙÙ Ø¥ÙÙÙØ§ ÙØ«ÙÙØ© Ø¬Ø¯ÙØ¯Ø©.
+}  
+_textfilename_ [l=ar] {Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙ}  
+_textfilesize_ [l=ar] {Ø­Ø¬Ù
+ Ø§ÙÙ
+ÙÙ}  
+
+_textretcoll_ [l=ar] {Ø¹ÙØ¯Ø© Ø¥ÙÙ Ø§ÙÙ
+Ø®Ø²Ù}  
+
+
+_texttmpfail_ [l=ar] {ÙØŽÙ Ø§ÙÙ
+Ø®Ø²Ù ÙÙ Ø§ÙÙØ±Ø§Ø¡Ø© Ù
+Ù Ø£Ù Ø§ÙÙØªØ§ØšØ© Ø¹ÙÙ Ø§ÙÙ
+ÙÙ Ø§ÙÙ
+Ø€ÙØª Ø£Ù Ø§ÙÙ
+Ø¬ÙØ¯. ÙØ¯ ÙÙÙÙ Ø§ÙØ³ØšØš ÙÙ:
+<ul>
+<li> ØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙÙØ³ ÙÙ Ø§ÙØ­Ù ÙÙ Ø§ÙÙØ±Ø§Ø¡Ø© Ø£Ù Ø§ÙÙØªØ§ØšØ© Ø¹ÙÙ Ø§ÙÙ
+Ø¬ÙØ¯_gsdlhome_/tmp.
+</ul>}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=ar] {Greenstone Ø¹ØšØ§Ø±Ø© Ø¹Ù ØšØ±ÙØ§Ù
+Ø¬ ÙÙ
+ÙÙÙ Ù
+Ø¹Ø§ÙØ¬Ø© Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙØ±ÙÙ
+ÙØ© ÙÙÙ
+ÙØªØšØ© ÙÙØ°ÙÙ Ø¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ø¬Ø¯ÙØ¯Ø©. ÙØ¹Ø·Ù Ø§ÙØšØ±ÙØ§Ù
+Ø¬ Ø·Ø±ÙÙØ© Ø¬Ø¯ÙØ¯Ø© ÙØªÙØžÙÙ
+ Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª ÙÙØŽØ±ÙØ§ Ø¹ÙÙ Ø§ÙØ¥ÙØªØ±ÙØª Ø£Ù Ø¹ÙÙ CD-ROM.
+Greenstone ÙØªÙ
+ Ø§ÙØ¹Ù
+Ù Ø¹ÙÙÙØ§ Ù
+Ù ÙØšÙ "Ù
+ØŽØ±ÙØ¹ Ø§ÙÙ
+ÙØªØšØ© Ø§ÙØ±ÙÙ
+ÙØ© ÙÙÙÙØ²ÙÙØ§ÙØ¯Ø§" ÙÙ Ø¬Ø§Ù
+Ø¹Ø© ÙØ§ÙÙØ§ØªÙØ ÙÙÙØ²Ø¹ ØšØ§ÙØªØ¹Ø§ÙÙ Ù
+Ø¹ Ù
+ÙØžÙ
+Ø© Ø§ÙÙÙÙØ³ÙÙ ÙØ¬Ù
+Ø¹ÙØ© ÙÙÙÙ
+Ø§Ù Ø¥ÙÙÙ. ÙÙ
+Ø§ Ø£ÙÙ ØšØ±ÙØ§Ù
+Ø¬ Ù
+ÙØªÙØ­ Ø§ÙÙ
+ØµØ¯Ø±Ø ÙÙ
+ØªØ§Ø­ ÙÙ Ù
+ÙÙØ¹ <i>http://greenstone.org</i> ØšÙ
+ÙØ¬Øš Ø±Ø®ØµØ© Ø§ÙØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙØ¹Ø§Ù
+ GNU General Public
+License.}  
+
+_textgreenstone2_ [l=ar] {Ù
+ÙÙØ¹ Ù
+ÙØªØšØ© ÙÙÙØ²ÙÙØ§ÙØ¯Ø§ Ø§ÙØ±ÙÙ
+ÙØ© (<a
+href="http://nzdl.org">http://nzdl.org</a>) ÙØ­ØªÙÙ Ø¹ÙÙ Ø£Ù
+Ø«ÙØ© ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª, ØšØ§ÙØ·ØšØ¹ ÙÙÙØ§ Ù
+ÙØŽØ£Ø© ØšØšØ±ÙØ§Ù
+Ø¬ GreenstoneØ ÙÙ
+ØªØ§Ø­Ø© ÙÙØªØµÙØ­ Ù
+Ù ÙØšÙ Ø§ÙØ¬Ù
+ÙØ¹. ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª ØšÙØ§ Ø£Ù
+Ø«ÙØ© ÙØ«ÙØ±Ø© ÙØ®ÙØ§Ø±Ø§Øª Ø§ÙØšØ­Ø« ÙØ§ÙØªØµÙØ­Ø ÙØªØŽÙ
+Ù Ø¹ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª ÙÙ Ø§ÙÙØºØ§Øª Ø§ÙØ¹Ø±ØšÙØ© ÙØ§ÙØµÙÙÙØ© ÙØ§ÙÙØ±ÙØ³ÙØ© ÙØ§ÙÙ
+Ø§ÙØ±Ù ÙØ§ÙØ¥Ø³ØšØ§ÙÙØ©Ø ÙØ¶ÙØ§Ù Ø¹Ù Ø§ÙØ¥ÙØ¬ÙÙØ²ÙØ©. ÙÙ
+Ø§ ØªØŽÙ
+Ù ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø¹ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ù
+ÙØ³ÙÙÙØ© Ø£ÙØ¶Ø§.}  
+
+_textplatformtitle_ [l=ar] {Ø§ÙØšÙÙØ© Ø§ÙØªØ­ØªÙØ©}  
+_textgreenstone3_ [l=ar] {ÙØ¹Ù
+Ù ØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙÙ ØšÙØŠØ§Øª Ø¹Ù
+Ù WindowsØ ÙUnixØ ÙMac OS X. ÙØŽÙ
+Ù Ø§ÙØšØ±ÙØ§Ù
+Ø¬ Ø¹ÙÙ ØšØ±Ù
+Ø¬ÙØ§Øª Ø«ÙØ§ØŠÙØ© Ø¬Ø§ÙØ²Ø© ÙÙØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ù
+Ø¹ ÙÙ Ù
+Ù WindowsØ ÙUnixØ ÙMac OS X. ÙÙ
+Ø§ ØªØŽÙ
+Ù Ù
+ØµØ¯Ø± ÙÙØ¯ Ø§ÙØšØ±Ù
+Ø¬Ø© ÙÙÙØžØ§Ù
+Ø ÙØ§ÙØ°Ù ÙÙ
+ÙÙ Ø§ÙØªØ¹Ø§Ù
+Ù Ù
+Ø¹Ù ØšÙØºØ© ++C Ø£Ù gcc. ÙÙ
+Ø§ ÙØ¹Ù
+Ù ØšØ±ÙØ§Ù
+Ø¬ Greenstone ØšÙ
+ØµØ§Ø­ØšØ© Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ù Ø§ÙØšØ±Ø§Ù
+Ø¬ Ø§ÙÙ
+ØªØ§Ø­Ø© Ù
+Ø¬Ø§ÙØ§Ù ÙÙÙ Ø®Ø§Ø¯Ù
+ ØŽØšÙØ© Apache Ù PERL. Ø£Ù
+Ø§ ÙØ§Ø¬ÙØ© Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙÙÙ ØªØ¹Ù
+Ù Ù
+Ø¹ ÙÙ Ù
+Ù Netscape Navigator Ø£Ù Internet Explorer.}  
+
+_textgreenstone4_ [l=ar] {Ø§ÙÙØ«ÙØ± Ù
+Ù Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙÙØ«Ø§ØŠÙ ØªÙØ²Ø¹ Ø¹ÙÙ Ø£ÙØ±Ø§Øµ Ù
+Ø¯Ù
+Ø¬Ø© ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ ØšØ±ÙØ§Ù
+Ø¬ Greenstone . Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§ÙØ Ù
+Ø¬Ù
+ÙØ¹Ø© <i>Humanity Development Library</i> ØªØ­ØªÙÙ Ø¹ÙÙ Ø¥ØµØ¯Ø§Ø±Ø§Øª ÙÙ Ù
+ÙØ¶ÙØ¹Ø§Øª ØªØªØ±Ø§ÙØ­ Ù
+Ø§ ØšÙÙ Ø§ÙÙ
+Ø­Ø§Ø³ØšØ© ÙØ§ÙØµØ­Ø©. ÙÙÙ ØªØ¹Ù
+Ù Ø¹ÙÙ Ø­ÙØ§Ø³Øš ØšÙØ¯Ø±Ø§Øª 1.23 ÙÙÙ Ø§ÙØªÙ ØªÙØªØŽØ± ÙÙ Ø§ÙØ¯ÙÙ Ø§ÙÙØ§Ù
+ÙØ©. ÙÙÙ
+ÙÙ Ø§ÙÙØµÙÙ ÙÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø¹Ù Ø·Ø±ÙÙ Ø§ÙØšØ­Ø« Ø£Ù Ø§ÙØªØµÙØ­ ØšØ§ÙØ¯ÙÙ Ø£Ù Ø§ÙØ¹ÙÙØ§Ù Ø£Ù Ø§ÙÙ
+ÙØžÙ
+Ø© Ø£Ù ØªØµÙØ­ ÙØ§ØŠÙ
+Ø© "ÙÙÙ" how-tosØ Ø£Ù ØšØ§Ø³ØªØ¹Ø±Ø§Ø¶ Ø¹ØŽÙØ§ØŠÙ ÙØ£ØºÙÙØ© Ø§ÙÙØªØš.}  
+
+_textcustomisationtitle_ [l=ar] {Ø¥Ù
+ÙØ§ÙÙØ© Ø§ÙØªØ¹Ø¯ÙÙ}  
+_textgreenstone5_ [l=ar] {ØµÙ
+Ù
+ ØšØ±ÙØ§Ù
+Ø¬ Greenstone Ø®ØµÙØµØ§Ù ÙÙÙÙØ± Ø¯Ø±Ø¬Ø© Ø¹Ø§ÙÙØ© Ù
+Ù Ø§ÙÙ
+Ø±ÙÙØ© ÙØ¥Ù
+ÙØ§ÙÙØ© Ø§ÙØªØ¹Ø¯ÙÙ ÙØ§ÙØªÙØ³Ø¹. ÙØ§ÙÙØ«Ø§ØŠÙ Ø§ÙØ¬Ø¯ÙØ¯Ø© ÙØ§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ Ø§ÙØ®Ø§ØµØ© ØšÙØ§ ØªØ³ÙÙ Ø¹Ù Ø·Ø±ÙÙ ØšØ±Ù
+Ø¬ÙØ§Øª ØµØºÙØ±Ø© "plugins" ØšÙØºØ© (Perl). ÙÙ
+Ø§ ÙÙ
+ÙÙ ØªÙÙÙÙ ØªØ±ÙÙØšØ© ØªØµÙØ­ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ Ø¹Ù Ø·Ø±ÙÙ ÙØªØ§ØšØ© "Ø§ÙØªØµÙÙÙØ§Øª". ÙÙØ°Ù Ø§ÙÙØ§Ø¬ÙØ© Ø§ÙØªÙ ØªØ¹ØªÙ
+Ø¯ Ø¹ÙÙ Ø·Ø±ÙÙØ© (look-and-feel) Ø£Ù Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙÙØ£Ø±Ø© ÙØªØ­Ø¯ÙØ¯ Ø§ÙØ§Ø®ØªÙØ§Ø±Ø§Øª ÙÙ
+ÙÙ Ø§Ø³ØªØšØ¯Ø§ÙÙØ§ ØšØ·Ø±ÙÙØ© Ø£Ø®Ø±Ù Ø£ÙØ«Ø± ØªØ¹ÙÙØ¯Ø§ ØªØ³ØªØ®Ø¯Ù
+ Ø§ÙÙ
+Ø§ÙØ±Ù Ø§ÙØªÙ ØªÙØªØš ØšÙØºØ© ØšØ³ÙØ·Ø© ÙØ³ØšÙØ§Ù. ÙÙ
+Ø§ ÙØ³Ø§ÙÙ
+ ØšØ±ÙØªÙÙÙÙ Corba ÙÙ Ø¥Ø¹Ø·Ø§Ø¡ ÙÙ Ø§ÙØ¥Ù
+ÙØ§ÙÙØ§Øª Ø§ÙØ®Ø§ØµØ© ØšØ§ÙØªØ¹Ø§Ù
+Ù Ù
+Ø¹ ÙØ«Ø§ØŠÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª. ÙØ°Ø§ ÙÙØ¯ ØªÙ
+Øª Ø§ÙØšØ±Ù
+Ø¬Ø© ØšÙØºØ© C++ ÙPerl ÙØ§ÙØªÙ ØªØªØ§Ø­ Ø¹Ù
+ÙÙØ© Ø§ÙØªØ¹Ø¯ÙÙ ÙÙÙØ§ ØšØ³ÙÙÙØ©.}  
+
+_textdocumentationtitle_ [l=ar] {ÙØ«Ø§ØŠÙ Ø§ÙØšØ±ÙØ§Ù
+Ø¬}  
+_textdocuments_ [l=ar] {ØªØªÙØ§ÙØ± Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ù ÙØ«Ø§ØŠÙ ØŽØ±Ø­ ØšØ±ÙØ§Ù
+Ø¬ Greenstone.}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=ar] {Ø§ÙÙØ§ØŠÙ
+Ø© Ø§ÙØšØ±ÙØ¯ÙØ©}  
+_textmailinglist_ [l=ar] {ÙÙØ¬Ø¯ ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone ÙØ§ØŠÙ
+Ø© ØšØ±ÙØ¯ÙØ© Ù
+Ø®ØµØµØ© ÙÙÙÙØ§ØŽ Ø­ÙÙ Ø§ÙØšØ±ÙØ§Ù
+Ø¬. Ø­ÙØ« ÙÙÙÙ
+ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ÙÙ Ø§ÙÙØŽØ·ÙÙ ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone ØšØ§ÙØ§ØŽØªØ±Ø§Ù ÙØ§ÙØªÙØ§Ø¹Ù ÙØ§ÙÙ
+Ø³Ø§ÙÙ
+Ø© Ù
+Ù Ø®ÙØ§Ù ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©. ÙÙØ§ØŽØªØ±Ø§Ù ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø¥Ø°ÙØš Ø¥ÙÙ .<a
+-href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone
+users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+ÙØ§Ø±Ø³Ø§Ù Ø±Ø³Ø§ÙØ© Ø§ÙÙ Ø§ÙÙØ§ØŠÙ
+Ø© Ø§ÙØšØ±ÙØ¯ÙØ©Ø Ø§Ø³ØªØ®Ø¯Ù
+ Ø§ÙØ¹ÙÙØ§Ù Ø§ÙØªØ§ÙÙ <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>.}  
+
+_textbugstitle_ [l=ar] {Ø§ÙØ£Ø¹Ø·Ø§Ù}  
+_textreport_ [l=ar] {ÙØ±ÙØ¯ Ø£Ù ÙØªØ£ÙØ¯ Ù
+Ù Ø£Ù ÙØ°Ø§ Ø§ÙØšØ±ÙØ§Ù
+Ø¬ ÙØ¹Ù
+Ù Ø¬ÙØ¯Ø§Ù Ù
+Ø¹Ù. Ù
+Ù ÙØ¶ÙÙ Ø£Ø®ØšØ±ÙØ§ Ø¹Ù Ø£Ù Ø¹Ø·Ù Ø¹ÙÙ Ø§ÙÙØ§ØŠÙ
+Ø© Ø§ÙØšØ±ÙØ¯ÙØ© <a href=""mailto:greenstone@cs.waikato.ac.nz"">greenstone@cs.waikato.ac.nz</a"}  
+
+_textgs3title_ [l=ar] {ÙÙ Ø§ÙØ£Ø¹Ù
+Ø§Ù}  
+_textgs3_ [l=ar] {Greenstone 3 is a complete redesign and reimplementation which 
+retains all the advantages of Greenstone 2 (the current version)--for example, 
+it is multilingual, multiplatform, and highly configurable. It 
+incorporates all the features of the existing system, and is backwards 
+compatible: that is, it can build and run existing collections without 
+modification. Written in Java, it is structured as a network of 
+independent modules that communicate using XML: thus it runs in a 
+distributed fashion and can be spread across different servers as 
+necessary. This modular design increases the flexibility and 
+extensibility of Greenstone. Documentation and experimental releases of Greenstone 3 can be downloaded from the <a href="http://www.greenstone.org/greenstone3.html">Greenstone 3 home page</a>.
+ØšØ±ÙØ§Ù
+Ø¬ Greenstone 3 ÙÙ Ø¹ØšØ§Ø±Ø© Ø¹Ù Ø¥Ø¹Ø§Ø¯Ø© ØªØµÙ
+ÙÙ
+ ÙØªÙÙÙØ° ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone 2 Ù
+Ø¹ Ø§ÙØ§Ø­ØªÙØ§Øž ØšÙÙ Ø§ÙÙ
+Ù
+ÙØ²Ø§Øª Ø§ÙÙ
+ÙØ¬ÙØ¯Ø© ÙÙÙ -- Ø¹ÙÙ Ø³ØšÙÙ Ù
+Ø«Ø§Ù ÙÙÙ Ù
+ØªØ¹Ø¯Ø¯ Ø§ÙÙØºØ§Øª ÙÙØ¹Ù
+Ù Ù
+Ø¹ ØšÙØŠØ§Øª Ø¹Ù
+Ù Ù
+ØªØ¹Ø¯Ø¯Ø© ÙØšÙ ÙØ¯Ø±Ø© Ø¹Ø§ÙÙØ© Ø¹ÙÙ Ø§ÙØªØ¹Ø¯ÙÙ. ÙÙ
+Ø§ ÙÙÙÙ
+ ØšØªØ¶Ù
+ÙÙ ÙØ§ÙØ© Ø§ÙÙ
+ÙØ²Ø§Øª Ø§ÙÙ
+ÙØ¬ÙØ¯Ø© ÙÙ Ø§ÙØ¥ØµØ¯Ø§Ø±Ø© Ø§ÙØ­Ø§ÙÙØ© ÙÙ
+Ø§ Ø£ÙÙ Ù
+ØªÙØ§ÙÙ Ù
+Ø¹ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙÙ
+ÙØŽØŠØ© ØšÙØ³Ø® ÙØ¯ÙÙ
+Ø©}  
+
+_textcreditstitle_ [l=ar] {Ø§ÙÙ
+ØŽØ§Ø±ÙÙÙ}  
+
+_textwhoswho_ [l=ar] {The Greenstone software is a collaborative effort between many
+people. Rodger McNab and Stefan Boddie are the principal architects and
+implementors.  Contributions have been made by David Bainbridge, George
+Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John
+McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd
+Reed, Bill Rogers, John Thompson, and Stuart Yeates. Other members of the New Zealand
+Digital Library project provided advice and inspiration in the design of
+the system: Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka
+Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols and Lloyd Smith. We would also like to
+acknowledge all those who have contributed to the GNU-licensed packages
+included in this distribution: MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE and XLHTML.
+}  
+
+_textaboutgslong_ [l=ar] {Ø¹Ù ØšØ±ÙØ§Ù
+Ø¬ Greenstone}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=ar] {ÙØ§ØŠÙ
+Ø© ØšØ§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ÙÙ Ø§ÙØ­Ø§ÙÙÙÙ}  
+_textuser_ [l=ar] {Ù
+Ø³ØªØ®Ø¯Ù
+}  
+_textas_ [l=ar] {Ø­Ø§ÙØ© Ø§ÙØ­Ø³Ø§Øš}  
+_textgroups_ [l=ar] {Ù
+Ø¬Ù
+ÙØ¹Ø§Øª}  
+_textcomment_ [l=ar] {ØªØ¹ÙÙÙ}  
+_textadduser_ [l=ar] {Ø£Ø¶Ù Ù
+Ø³ØªØ®Ø¯Ù
+ Ø¬Ø¯ÙØ¯}  
+_textedituser_ [l=ar] {ØªØ­Ø±ÙØ±}  
+_textdeleteuser_ [l=ar] {Ø­Ø°Ù}  
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=ar] {ØªØ­Ø±ÙØ± Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+}  
+_textadduser_ [l=ar] {Ø¥Ø¶Ø§ÙØ© Ù
+Ø³ØªØ®Ø¯Ù
+ Ø¬Ø¯ÙØ¯}  
+
+_textaboutusername_ [l=ar] {Ø§Ø³Ù
+ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙØ¬Øš Ø£ÙØ§ ÙÙÙ Ø¹Ù Ø­Ø±ÙÙÙ ÙÙØ§ ÙØ²ÙØ¯ Ø¹Ù Ø«ÙØ§Ø«ÙÙ Ø­Ø±ÙØ§Ù. ÙÙ
+Ø§ ÙÙ
+ÙÙ Ø£Ù ÙØ­ØªÙÙ Ø¹ÙÙ Ø¹ÙØ§Ù
+ØªÙ '.' Ù'_'.}  
+
+_textaboutpassword_ [l=ar] {ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ± ÙØ¬Øš Ø£Ù ØªÙÙÙ Ù
+ÙÙÙØ© Ù
+Ù 3 Ø¥ÙÙ 128 Ø­Ø±ÙÙ. ÙÙÙ
+ÙÙ Ø£Ù ØªØ­ØªÙÙ  Ø¹ÙÙ Ø¢Ù Ø­Ø±ÙÙ Ø¢Ø³ÙÙ Ø¹Ø§Ø¯ÙØ© ÙØ§ØšÙØ© ÙÙØ·ØšØ§Ø¹Ø©.}  
+
+_textoldpass_ [l=ar] {Ø¥Ø°Ø§ ØªØ±Ù ÙØ°Ø§ Ø§ÙØ­ÙÙ ÙØ§Ø±ØºØ§Ù ÙØ³ØªØžÙ ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ± Ø§ÙÙØ¯ÙÙ
+Ø© ÙÙ Ø§ÙÙØ§Ø¹ÙØ©.}  
+_textenabled_ [l=ar] {Ù
+ÙØ¹Ù}  
+_textdisabled_ [l=ar] {Ù
+Ø¹Ø·Ù}  
+
+_textaboutgroups_ [l=ar] {Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø¹ØšØ§Ø±Ø© Ø¹Ù ÙØ§ØŠÙ
+Ø© ÙÙØµÙ Ø¹ÙØ§ØµØ±ÙØ§ "ÙØµÙØ©"Ø ÙØ§ ØªØ¶Ø¹ Ù
+Ø³Ø§ÙØ© ØšØ¹Ø¯ Ø§ÙÙØµÙØ©}  
+_textavailablegroups_ [l=ar] {ØªØªØ¶Ù
+Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙÙ
+Ø¹Ø±ÙØ© Ø§ÙÙ
+ØŽØ±Ù Ø§ÙØ¥Ø¯Ø§Ø±Ù Ù Ø§ÙØ¢Ø®Ø±ÙÙ Ø§ÙØ°ÙÙ ÙÙÙ
+ Ø§ÙØ­Ù ÙÙ ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø¹Ù ØšØ¹Ø¯ ØšØ¥Ø³ØªØ®Ø¯Ø§Ù
+ ÙØ§Ø¬ÙØ© Ø§ÙÙ
+ÙØªØšÙ Ø£Ù Ø§ÙÙ
+Ø³ØªÙØ¯Ø¹ :
+ <ul>
+ <li><b>Ø§ÙÙ
+ØŽØ±Ù</b>: ÙØ¹Ø·Ù Ø­Ù Ø§ÙØ¯Ø®ÙÙ Ù ØªØºÙØ± Ø¥Ø¹Ø¯Ø§Ø¯ Ø§ÙÙ
+ÙÙØ¹ Ù Ø­Ø³Ø§ØšØ§Øª Ø§ÙÙ
+ØªØ³ØªØ®Ø¯Ù
+ÙÙ.
+ <li><b>Ù
+Ø­Ø±Ø±-Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª-Ø§ÙØŽØ®ØµÙØ©</b>: ÙØ¹Ø·Ù Ø­Ù Ø§ÙØ¯Ø®ÙÙ ÙØ¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª ØŽØ®ØµÙØ© Ø¬Ø¯ÙØ¯Ø©
+ <li><b>&lt;Ø¥Ø³Ù
+-Ù
+Ø¬Ù
+ÙØ¹Ø©&gt;-Ù
+Ø­Ø±Ø±-Ù
+Ø¬Ù
+ÙØ¹Ø©</b>: ÙØ¹Ø·Ù Ø­Ù Ø§ÙØ¯Ø®ÙÙ Ù ØªØ­Ø¯ÙØ« Ø¥Ø³Ù
+ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© "Ø¥Ø³Ù
+-Ù
+Ø¬Ù
+ÙØ¹Ø©" , Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù, reports-collection-editor.
+ <li><b>Ù
+Ø­Ø±Ø±-ÙÙ-Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª</b>: ÙØ¹Ø·Ù Ø­Ù Ø§ÙØ¯Ø®ÙÙ ÙØ¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª ØŽØ®ØµÙØ© Ù Ø¯ÙÙÙØ© Ù ØªØ­Ø¯ÙØ«  <b>ÙÙ</b> Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª.
+ </ul>
+ }  
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=ar] {Ø­Ø°Ù Ù
+Ø³ØªØ®Ø¯Ù
+}  
+_textremwarn_ [l=ar] {ÙÙ ØªØ±ÙØ¯ Ø­Ø°Ù ÙØ°Ø§ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙÙØ§ØŠÙØ§Ù <b>_cgiargumun_</b>?}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=ar] {ØªØºÙÙØ± ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ±}  
+_textoldpw_ [l=ar] {ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ± Ø§ÙÙØ¯ÙÙ
+Ø©}  
+_textnewpw_ [l=ar] {ÙÙÙ
+Ø© Ù
+Ø±ÙØ± Ø¬Ø¯ÙØ¯Ø©}  
+_textretype_ [l=ar] {Ø§Ø¹Ø¯ ÙØªØ§ØšØ© ØšØ§Ø³ÙØ±Ø¯ Ø¬Ø¯ÙØ¯Ø©}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=ar] {ØªÙ
+ ØªØºÙÙØ± ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ± ØšÙØ¬Ø§Ø­.}  
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=ar] {Ø§Ø³Ù
+ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ØºÙØ± ØµØ­ÙØ­}  
+_textinvalidpassword_ [l=ar] {ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ± ØºÙØ± ØµØ§ÙØ­Ø©.}  
+_textemptypassword_ [l=ar] {Ù
+Ù ÙØ¶ÙÙ Ø£Ø¯Ø®Ù ÙÙÙ
+Ø© Ù
+Ø±ÙØ± ÙÙØ°Ø§ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+.}  
+_textuserexists_ [l=ar] {ÙØ°Ø§ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ Ù
+ÙØ¬ÙØ¯ ØšØ§ÙÙØ¹ÙØ Ù
+Ù ÙØ¶ÙÙ Ø£Ø¯Ø®Ù Ø§Ø³Ù
+ Ù
+Ø³ØªØ®Ø¯Ù
+ Ø¢Ø®Ø±.}  
+
+_textusernameempty_ [l=ar] {Ù
+Ù ÙØ¶ÙÙ Ø£Ø¯Ø®Ù Ø§Ø³Ù
+ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+.}  
+_textpasswordempty_ [l=ar] {ÙØ¬Øš Ø£Ù ØªØ¯Ø®Ù ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ± Ø§ÙØ³Ø§ØšÙØ©.}  
+_textnewpass1empty_ [l=ar] {Ø£Ø¯Ø®Ù ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ± Ø§ÙØ¬Ø¯ÙØ¯Ø© Ø«Ù
+ Ø£Ø¹Ø¯ Ø¥Ø¯Ø®Ø§ÙÙØ§.}  
+_textnewpassmismatch_ [l=ar] {ÙÙÙ
+ØªØ§ Ø§ÙÙ
+Ø±ÙØ± Ø§ÙÙØªØ§Ù Ø£Ø¯Ø®ÙØªÙÙ
+Ø§ ÙÙØ³Ø§ Ù
+ØªØ·Ø§ØšÙØªØ§Ù.}  
+_textnewinvalidpassword_ [l=ar] {ÙÙØ¯ Ø£Ø¯Ø®ÙØª ÙÙÙ
+Ø© Ù
+Ø±ÙØ± ØºÙØ± ØµØ§ÙØ­Ø©.}  
+_textfailed_ [l=ar] {Ø¥Ù
+Ø§ Ø§Ø³Ù
+ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ Ø£Ù ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ± ÙØ§Ù ØºÙØ± ØµØ­ÙØ­.}  
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=ar] {Ø±ÙÙ
+ Ø¥ØµØ¯Ø§Ø±Ø© Greenstone}  
+_textframebrowser_ [l=ar] {ÙØ¬Øš Ø£Ù ÙÙÙÙ ÙØ¯ÙÙ Ù
+ØªØµÙØ­ ÙÙØšÙ Ø§ÙØ¥Ø·Ø§Ø±Ø§Øª ÙØ±Ø€ÙÙ ÙØ°Ø§.}  
+_textusermanage_ [l=ar] {Ø¥Ø¯Ø§Ø±Ø© Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ÙÙ}  
+_textlistusers_ [l=ar] {Ø§Ø¹Ø±Ø¶ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ÙÙ}  
+_textaddusers_ [l=ar] {Ø£Ø¶Ù Ù
+Ø³ØªØ®Ø¯Ù
+ Ø¬Ø¯ÙØ¯}  
+_textchangepasswd_ [l=ar] {ØªØºÙÙØ± ÙÙÙ
+Ø© Ø§ÙÙ
+Ø±ÙØ±}  
+_textinfo_ [l=ar] {Ù
+Ø¹ÙÙÙ
+Ø§Øª ÙÙÙØ©}  
+_textgeneral_ [l=ar] {Ø¹Ø§Ù
+}  
+_textarguments_ [l=ar] {ÙÙØ§ØŽØ§Øª}  
+_textactions_ [l=ar] {Ø§ÙØ£ÙØ¹Ø§Ù}  
+_textbrowsers_ [l=ar] {Ù
+ØªØµÙØ­Ø§Øª}  
+_textprotocols_ [l=ar] {ØšØ±ÙØªÙÙÙÙØ§Øª}  
+_textconfigfiles_ [l=ar] {Ù
+ÙÙØ§Øª Ø§ÙØ®ØµØ§ØŠØµ}  
+_textlogs_ [l=ar] {Ø³Ø¬ÙØ§Øª}  
+_textusagelog_ [l=ar] {Ø³Ø¬Ù Ø§ÙØ§Ø³ØªØ®Ø¯Ø§Ù
+}  
+_textinitlog_ [l=ar] {Ø³Ø¬Ù ØšØ±ÙØ§Ù
+Ø¬ Ø§ÙØšØ¯Ø¡}  
+_texterrorlog_ [l=ar] {Ø³Ø¬Ù Ø£Ø®Ø·Ø§Ø¡}  
+_textadminhome_ [l=ar] {ØµÙØ­Ø© Ø§ÙØ¥Ø¯Ø§Ø±Ø©}  
+_textreturnhome_ [l=ar] {ØµÙØ­Ø© Greenstone}  
+_titlewelcome_ [l=ar] {Ø§ÙØ¥Ø¯Ø§Ø±Ø©}  
+_textmaas_ [l=ar] {Ø®Ø¯Ù
+Ø§Øª Ø§ÙØµÙØ§ÙØ© ÙØ§ÙØ¥Ø¯Ø§Ø±Ø© Ø§ÙÙ
+ØªØ§Ø­Ø© ØªØŽÙ
+Ù Ø¹ÙÙ:}  
+_textvol_ [l=ar] {view on-line logs}  
+_textcmuc_ [l=ar] {Ø¥ÙØŽØ§Ø¡ ÙØµÙØ§ÙØ© ÙØªØ­Ø¯ÙØ« Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª}  
+_textati_ [l=ar] {Ù
+Ø¹ÙÙÙ
+Ø§Øª ØªÙÙÙØ© Ù
+Ø«Ù CGI}  
+
+_texttsaa_ [l=ar] {ØªÙØ¯Ù
+ ÙØ°Ù Ø§ÙØ®Ø¯Ù
+Ø© ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙØŽØ±ÙØ· Ø§ÙØ¬Ø§ÙØšÙ ÙÙØµÙØ­Ø©}  
+
+_textcolstat_ [l=ar] {Ø­Ø§ÙØ© Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}  
+
+_textcwoa_ [l=ar] {Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø³ØªØžÙØ± ÙÙØ· Ø§Ø°Ø§ ØšÙÙØªÙÙ
+ Ù "ÙØ¹Ù
+ÙÙ" Ø§Ø°Ø§ ÙÙ
+ build.cfg
+(Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+ÙØ¬ÙØ¯Ø© Ø ÙÙ Ù
+ÙØ±ÙØ¡Ø© Ø ØªØ­ØªÙÙ Ø¹ÙÙ Ø­ÙÙ ØªØ§Ø±ÙØ® ØšÙÙØ© Ø³ÙÙÙ
+Ø©)
+Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù > 0 ÙÙ
+Ø¬ÙØ¯  ÙÙØ±Ø³ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª  ( Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù ÙÙØ³ Ù
+Ø¬ÙØ¯ Ø§ÙØšÙÙØ©)
+}  
+
+_textcafi_ [l=ar] {Ø§Ø¶ØºØ· Ø¹ÙÙ <i>abbrev.</i> .ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø¹Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}  
+_textcctv_ [l=ar] {Ø§Ø¶ØºØ· Ø¹ÙÙ <i>Ù
+Ø¬Ù
+ÙØ¹Ø©</i> ÙØ¹Ø±Ø¶ ØªÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©}  
+_textsubc_ [l=ar] {Ø³ÙÙ
+ Ø§ÙØªØºÙÙØ±Ø§Øª}  
+_texteom_ [l=ar] {Ø®Ø·Ø£ ÙÙ ÙØªØ­ Ù
+ÙÙ main.cfg}  
+_textftum_ [l=ar] {ÙØŽÙ ÙÙ ØªØ­Ø¯ÙØ« Ù
+ÙÙ main.cfg}  
+_textmus_ [l=ar] {ØªÙ
+ ØªØ­Ø¯ÙØ« Ø§ÙÙ
+ÙÙ main.cfg ØšÙØ¬Ø§Ø­}  
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=ar] {Ø¥ÙØŽØ§Ø¡ Ù
+ÙØ®Øµ ÙÙ
+Ø¬Ù
+ÙØ¹Ø© "_collectionname_" }  
+_textflog_ [l=ar] {Ø³Ø¬Ù Ø§ÙØ¥Ø®ÙØ§ÙØ§Øª ÙÙÙ
+Ø¬Ù
+ÙØ¹Ø© "_collectionname_"}  
+_textilog_ [l=ar] {ØµØ¯Ø± Ø³Ø¬Ù Ù
+Ø¬Ù
+ÙØ¹Ø© "_collectionname_"}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=ar] {Ø§Ø±Ø³Ù Ø±Ø£ÙÙ}  
+
+_greenstoneusabilitytext_ [l=ar] {Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Greenstone}  
+
+_textwhy_ [l=ar] {<p>Ø¥Ø±Ø³Ø§Ù ÙØ°Ø§ Ø§ÙØªÙØ±ÙØ± ÙØ¹ÙÙ Ø£ÙÙ ÙØ¬Ø¯Øª ØµØ¹ÙØšØ© Ø£Ù Ù
+ØŽÙÙØ© ÙÙ Ø§Ø³ØªØ¹Ø±Ø§Ø¶ ÙØ°Ù Ø§ÙØµÙØ­Ø©.}  
+_textextraforform_ [l=ar] {ÙÙØ³ Ù
+Ù Ø§ÙØ¶Ø±ÙØ±Ù Ù
+ÙØ¡ Ø§ÙÙÙ
+ÙØ°Ø¬ ØšØ§ÙÙØ§Ù
+Ù -- Ø£Ù Ù
+Ø¹ÙÙÙ
+Ø§Øª ÙÙØ§ Ø³ØªÙÙØ¯.}  
+_textprivacybasic_ [l=ar] {<p>Ø³ÙÙ ÙØ­ØªÙÙ Ø§ÙØªÙØ±ÙØ± ÙÙØ· Ø¹ÙÙ Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø¹Ù ØµÙØ­Ø© Greenstone Ø§ÙØªÙ ÙØ§ÙØª ØªØ¹Ø±Ø¶Ø ÙØ§ÙØ·Ø±ÙÙØ© Ø§ÙØªÙ ÙØ§ÙØª ØªØ¹Ø±Ø¶ ØšÙØ§(ØšØ§ÙØ¥Ø¶Ø§ÙØ© Ø¥ÙÙ Ø£Ù Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø§Ø®ØªÙØ§Ø±ÙØ© Ø£Ø®Ø±Ù ØªÙØ¯Ù
+ÙØ§).}  
+_textstillsend_ [l=ar] {ÙÙ Ù
+Ø§Ø²ÙØª ØªØ±ÙØ¯ Ø¥Ø±Ø³Ø§Ù ÙØ°Ø§ Ø§ÙØªÙØ±ÙØ±Ø}  
+
+_texterror_ [l=ar] {Ø®Ø·Ø£}  
+_textyes_ [l=ar] {ÙØ¹Ù
+}  
+_textno_ [l=ar] {ÙØ§}  
+_textclosewindow_ [l=ar] {Ø§ØºÙÙ Ø§ÙÙØ§ÙØ°Ø©}  
+_textabout_ [l=ar] {Ø¹Ù}  
+_textprivacy_ [l=ar] {Ø§ÙØ®ØµÙØµÙØ©}  
+_textsend_ [l=ar] {Ø§Ø±Ø³Ù}  
+_textdontsend_ [l=ar] {ÙØ§ ØªØ±Ø³Ù}  
+_textoptionally_ [l=ar] {Ø§Ø®ØªÙØ§Ø±Ù}  
+
+_textunderdev_ [l=ar] {Ù
+Ø¹Ø§ÙÙØ© Ø§ÙØªÙØ§ØµÙÙ Ø³ÙÙ ØªÙÙÙ Ù
+ØªØ§Ø­Ø© ÙÙ Ø§ÙÙØ³Ø®Ø© Ø§ÙÙÙØ§ØŠÙØ©}  
+
+_textviewdetails_ [l=ar] {Ø¹Ø±Ø¶ ØªÙØ§ØµÙÙ Ø§ÙØªÙØ±ÙØ±}  
+_textmoredetails_ [l=ar] {Ù
+Ø²ÙØ¯ Ù
+Ù Ø§ÙØªÙØ§ØµÙÙ}  
+_texttrackreport_ [l=ar] {ØªØ§ØšØ¹ ÙØ°Ø§ Ø§ÙØªÙØ±ÙØ±}  
+_textcharacterise_ [l=ar] {Ù
+Ø§ ÙÙØ¹ Ø§ÙÙ
+ØŽÙÙØ©}  
+_textseverity_ [l=ar] {Ø¥ÙÙ Ø£Ù Ù
+Ø¯Ù ÙØšÙØº Ø³ÙØ¡ Ø§ÙÙ
+ØŽÙÙØ©}  
+ 
+_textbadrender_ [l=ar] {Ø§ÙØµÙØ­Ø© ØªØšØ¯Ù ØºÙØ± Ø·ØšÙØ¹ÙØ©}  
+_textcontenterror_ [l=ar] {Ø®Ø·Ø£ ÙÙ Ø§ÙÙ
+Ø­ØªÙÙ}  
+_textstrangebehaviour_ [l=ar] {Ø³ÙÙÙ ØºØ±ÙØš}  
+_textunexpected_ [l=ar] {Ø­Ø¯Ø« ØŽÙØ¡ ØºÙØ± Ù
+ØªÙÙØ¹}  
+_textfunctionality_ [l=ar] {ØµØ¹Øš Ø§ÙØ§Ø³ØªØ®Ø¯Ø§Ù
+}  
+_textother_ [l=ar] {Ø¢Ø®Ø±Ù}  
+
+_textcritical_ [l=ar] {Ø®Ø·ÙØ±}  
+_textmajor_ [l=ar] {Ø®Ø·ÙØ±}  
+_textmedium_ [l=ar] {Ù
+ØªÙØ³Ø·}  
+_textminor_ [l=ar] {Ø£ÙÙ}  
+_texttrivial_ [l=ar] {ÙØ±Ø¹Ù}  
+
+_textwhatdoing_ [l=ar] {Ù
+Ø§ Ø§ÙØ°Ù ÙÙØª ØªØ­Ø§ÙÙ ÙØ¹ÙÙØ}  
+_textwhatexpected_ [l=ar] {Ù
+Ø§Ø°Ø§ ÙÙØª ØªØªÙÙØ¹ Ø£Ù ÙØ­Ø¯Ø«Ø}  
+_textwhathappened_ [l=ar] {Ù
+Ø§Ø§ÙØ°Ù Ø­Ø¯Ø« ØšØ§ÙÙØ¹ÙØ}  
+
+_cannotfindcgierror_ [l=ar] {<h2>Ø¹ÙÙØ§Ù!</h2>ÙÙ
+ Ø£ØªÙ
+ÙÙ Ù
+Ù Ø§ÙØ¹Ø«ÙØ± Ø¹ÙÙ ØšØ±Ø§Ù
+Ø¬ Ø§ÙØ®Ø§Ø¯Ù
+ Ø§ÙØ®Ø§ØµØ±Ø© ØšØ§ÙØ²Ø± "_linktextusab_".}  
+
+_textusabbanner_ [l=ar] {ØŽØ±ÙØ· ØšØ±ÙØ§Ù
+Ø¬ Greenstone}  
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=ar] {Ø­Ø¯Ø« Ø®Ø·Ø£ Ù
+Ø§}  
+
+_textgtihome_ [l=ar] {ØªØ³Ø§Ø¹Ø¯Ù ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ù Ø§ÙØµÙØ­Ø§Øª ÙÙ ØªØ­Ø³ÙÙ Ø¹Ù
+ÙÙØ© Ø¯Ø¹Ù
+ Ø§ÙÙØºØ§Øª Ø§ÙÙ
+ØªØ¹Ø¯Ø¯Ø© ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone . ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ ÙØ°Ù Ø§ÙØµÙØ­Ø§Øª ÙÙ
+ÙÙÙ
+<ul>
+  <li>ØªØ±Ø¬Ù
+Ø© Ø£Ø¬Ø²Ø§Ø¡ Ù
+Ù ØšØ±ÙØ§Ù
+Ø¬ Greenstone Ø¥ÙÙ ÙØºØ© Ø¬Ø¯ÙØ¯Ø©
+  <li>ØªØ­Ø¯ÙØ« ØªØ±Ø¬Ù
+Ø© Ø£Ø­Ø¯ Ø§ÙÙØ§Ø¬ÙØ§Øª Ø¹ÙØ¯Ù
+Ø§ ØªØªØºÙØ± Ø§ÙÙØ§Ø¬ÙØ© Ø§ÙØ£ØµÙÙØ© Ø§ÙØ¥ÙØ¬ÙÙØ²ÙØ© (Ù
+Ø«Ø§Ù: Ø¥Ø¶Ø§ÙØ© Ø¥Ù
+ÙØ§ÙØ§Øª Ø¬Ø¯ÙØ¯Ø© Ø¥ÙÙ Ø§ÙØšØ±ÙØ§Ù
+Ø¬)
+  <li>ØªØµØ­ÙØ­ Ø£Ø®Ø·Ø§Ø¡ ÙÙ Ø§ÙØªØ±Ø¬Ù
+Ø© Ø§ÙØ­Ø§ÙÙØ©
+</ul>
+
+Ø³ÙÙ ÙØªÙ
+ Ø¹Ø±Ø¶ Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ù Ø§ÙØµÙØ­Ø§Øª ÙÙ ÙØ§Ø­Ø¯Ø© ØªØ­ØªÙÙ Ø¹ÙÙ Ø¹ØšØ§Ø±Ø© Ù
+Ø­Ø¯Ø¯Ø© ÙÙØªØ±Ø¬Ù
+Ø©.
+Ø³ÙÙ ÙØªÙ
+ Ø§ÙØ¹Ù
+Ù ØšØªØ±Ø¬Ù
+Ø© Ø§ÙÙØ§Ø¬ÙØ§Øª Ø¹ØšØ§Ø±Ø© ØšØ¹Ø¯ Ø¹ØšØ§Ø±Ø©.
+ÙØ«ÙØ± Ù
+Ù ÙØ°Ù Ø§ÙØ¹ØšØ§Ø±Ø§Øª ÙØ­ØªÙÙ Ø¹ÙÙ Ø£ÙØ§Ù
+Ø± HTML : ÙÙÙØ§ ÙØ¬Øš Ø¹ÙÙÙ Ø£ÙØ§ ØªØ­Ø§ÙÙ ØªØ±Ø¬Ù
+Ø© ÙØ°Ù Ø§ÙØ£ÙØ§Ù
+Ø± ÙÙÙÙ Ø­Ø§ÙØž Ø¹ÙÙÙØ§ ÙÙ
+Ø§ ÙÙ ÙÙ Ø§ÙÙØ³Ø®Ø© Ø§ÙÙ
+ØªØ±Ø¬Ù
+Ø©. ÙØ°ÙÙ Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙÙ
+Ø­ØªÙØ§Ø© ØšÙÙ Ø¹ÙØ§Ù
+Ø© Ø§ÙØŽØ±Ø·Ø© Ø§ÙØªØ­ØªÙØ© underscores (Ù
+Ø«Ù : _this_ ) ÙØ¬Øš Ø£ÙØ§ ØªØªØ±Ø¬Ù
+ Ø£ÙØ¶Ø§Ù ÙÙÙ Ø¹ØšØ§Ø±Ø© Ø¹Ù Ø£Ø³Ù
+Ø§Ø¡ ÙØšØ±Ø§Ù
+Ø¬ Ù
+ØµØºØ±Ø© Ø¯Ø§Ø®Ù ØšØ±ÙØ§Ù
+Ø¬ Greenstone.
+<p>
+Ø¥Ø°Ø§ ÙÙØª ØªØ­Ø¯Ø« ØªØ±Ø¬Ù
+Ø© ÙØ§Ø¬ÙØ© Ù
+ÙØ¬ÙØ¯Ø© ÙÙÙ ØªØ¬Ø¯ Ø¹ØšØ§Ø±Ø© ÙÙÙ ØªØ±Ø¬Ù
+Ø© ØªÙ
+Øª Ù
+Ù ÙØšÙ. ÙÙÙ ØšØ¹Ø¶ Ø§ÙØ£Ø­ÙØ§Ù ÙÙÙÙ ÙÙØ§Ù ØªØ±Ø¬Ù
+Ø© Ù
+Ø§ ÙÙÙÙ Ø§ÙÙ
+ÙØ§ØšÙ Ø§ÙØ¥ÙØ¬ÙÙØ²Ù ÙØ¯ ØªÙ
+ ØªØºÙÙØ±Ù . ÙÙ ÙØ°Ù Ø§ÙØ­Ø§ÙØ© Ø³ÙÙ ÙØªÙ
+ Ø¹Ø±Ø¶ Ø§ÙØªØ±Ø¬Ù
+Ø© Ø§ÙØ­Ø§ÙÙØ© ÙØ¹ÙÙÙ Ø£Ù ØªÙÙÙ
+ ØšØ¹Ù
+ÙÙØ© ØªØ­Ø¯ÙØ« Ø§ÙØªØ±Ø¬Ù
+Ø© ÙÙ Ø­Ø§ÙØ© Ø§ÙØ¶Ø±ÙØ±Ø©.
+<p>
+ÙÙ Ø­Ø§ÙØ© ØªØµØ­ÙØ­ ØªØ±Ø¬Ù
+Ø© ÙØ¯ ØªÙ
+ ÙØ¹ÙØ§ ØªØ­Ø¯ÙØ«ÙØ§Ø Ø§Ø³ØªØ®Ø¯Ù
+ Ø±Ø§ØšØ·Ø© "ØªØµØ­ÙØ­ ØªØ±Ø¬Ù
+Ø© Ù
+ÙØ¬ÙØ¯Ø©" ÙØ§ÙÙ
+ØªØ§Ø­Ø© ÙÙÙ Ø¹ØšØ§Ø±Ø© Ù
+Ù Ø§ÙØ¹ØšØ§Ø±Ø§Øª Ø§ÙÙ
+ØªØ±Ø¬Ù
+Ø© Ø¹ÙÙ ØšØ±ÙØ§Ù
+Ø¬ Greenstone.
+<p>
+ÙÙ ØµÙØ­Ø© ØªÙØªÙÙ ØšØ²Ø± "_textgtisubmit_" . Ø¹ÙØ¯Ù
+Ø§ ØªØ¶ØºØ· Ø¹ÙÙÙ Ø³ÙÙ ØªØªÙ
+ Ø§ÙØªØ¹Ø¯ÙÙØ§Øª ÙÙ Ø§ÙØ­Ø§Ù Ø¹ÙÙ ØšØ±ÙØ§Ù
+Ø¬ Greenstone Ø¹ÙÙ Ù
+ÙÙØ¹ nzdl.org . ÙÙÙØ¬Ø¯ ÙÙ ÙÙ ØµÙØ­Ø© Ø²Ø± Ø®Ø§Øµ ÙØ­ÙÙÙ Ø¥ÙÙ ÙØ°Ø§ Ø§ÙÙ
+ÙÙØ¹.
+
+}  
+
+_textgtiselecttlc_ [l=ar] {Ù
+Ù ÙØ¶ÙÙ Ø§Ø®ØªØ± Ø§ÙÙØºØ©}  
+
+#for status page
+_textgtiviewstatus_ [l=ar] {Ø§Ø¶ØºØ· ÙØ¹Ø±Ø¶ Ø­Ø§ÙØ© Ø§ÙØªØ±Ø¬Ù
+Ø© Ø§ÙØ­Ø§ÙÙØ© ÙÙÙ Ø§ÙÙØºØ§Øª
+}  
+_textgtiviewstatusbutton_ [l=ar] {Ø§Ø¹Ø±Ø¶ Ø§ÙØ­Ø§ÙØ©}  
+_textgtistatustable_ [l=ar] {ÙØ§ØŠÙ
+Ø© ØšØ­Ø§ÙØ© Ø§ÙØªØ±Ø¬Ù
+Ø© ÙÙÙ ÙÙØºØ§Øª}  
+_textgtilanguage_ [l=ar] {Ø§ÙÙØºØ©}  
+_textgtitotalnumberoftranslations_ [l=ar] {Ø¥Ø¬Ù
+Ø§ÙÙ Ø¹Ø¯Ø¯ Ø§ÙØªØ±Ø¬Ù
+Ø§Øª}  
+
+_textgtiselecttfk_ [l=ar] {Ù
+Ù ÙØ¶ÙÙ Ø§Ø®ØªØ± Ù
+ÙÙ ÙÙØªÙ
+ Ø§ÙØ¹Ù
+Ù Ø¹ÙÙÙ}  
+
+_textgticoredm_ [l=ar] {ÙØ§Ø¬ÙØ© Ø§ÙØšØ±ÙØ§Ù
+Ø¬ (Ø§ÙØ£Ø³Ø§Ø³ÙØ©)}  
+_textgtiauxdm_ [l=ar] {ÙØ§Ø¬ÙØ© Ø§ÙØšØ±ÙØ§Ù
+Ø¬ (Ø§ÙÙ
+Ø³Ø§Ø¹Ø¯Ø©)}  
+_textgtiglidict_ [l=ar] {ÙØ§Ù
+ÙØ³ GLI}  
+_textgtiglihelp_ [l=ar] {Ù
+Ø³Ø§Ø¹Ø¯Ø© GLI}  
+_textgtiperlmodules_ [l=ar] {ØšØ±Ø§Ù
+Ø¬ Perl}  
+_textgtitutorials_ [l=ar] {ØªØ¯Ø±ÙØšØ§Øª}  
+_textgtigreenorg_ [l=ar] {Greenstone.org}  
+_textgtigs3interface_ [l=ar] {ÙØ§Ø¬ÙØ© Greenstone3}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=ar] {Ø¯ÙÙÙ Ù
+Ø·ÙØ± (Ù
+ØšØ±Ù
+Ø¬) Greenstone}  
+_textgtiinstallmanual_ [l=ar] {Ø¯ÙÙÙ ØªØ«ØšÙØª Greenstone}  
+_textgtipapermanual_ [l=ar] {Ø¯ÙÙÙ Greenstone ÙÙØªØ­ÙÙÙ Ù
+Ù Ø£ÙØ±Ø§Ù Ø¥ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª}  
+_textgtiusermanual_ [l=ar] {Ø¯ÙÙÙ Ù
+Ø³ØªØ®Ø¯Ù
+ Greenstone}  
+
+_textgtienter_ [l=ar] {Ø£Ø¯Ø®Ù}  
+
+_textgticorrectexistingtranslations_ [l=ar] {ØªØµØ­ÙØ­ ØªØ±Ø¬Ù
+Ø© Ù
+ÙØ¬ÙØ¯Ø©}  
+_textgtidownloadtargetfile_ [l=ar] {Ø­Ù
+Ù Ø§ÙÙ
+ÙÙ}  
+_textgtiviewtargetfileinaction_ [l=ar] {Ø§Ø³ØªØ¹Ø±Ø¶ ÙØ°Ø§ Ø§ÙÙ
+ÙÙ ÙÙÙ ÙØ¹Ù
+Ù}  
+_textgtitranslatefileoffline_ [l=ar] {ØªØ±Ø¬Ù
+ ÙØ°Ø§ Ø§ÙÙ
+ÙÙ Ø®Ø§Ø±Ø¬ Ø§ÙÙ
+ÙÙØ¹}  
+
+_textgtinumchunksmatchingquery_ [l=ar] {Ø¹Ø¯Ø¯ Ø£Ø¬Ø²Ø§Ø¡ Ø§ÙØªØ±Ø¬Ù
+Ø© Ø§ÙØªÙ ØªÙ
+ Ø§Ø³ØªØ±Ø¬Ø§Ø¹ÙØ§}  
+
+_textgtinumchunkstranslated_ [l=ar] {Ø¹Ù
+ÙÙØ© ØªØ±Ø¬Ù
+Ø© ØªÙ
+Øª}  
+_textgtinumchunksrequiringupdating_ [l=ar] {ÙØ°ÙÙ ØªØ­ØªØ§Ø¬ Ø¥ÙÙ _1_ ØªØ­Ø¯ÙØ«}  
+_textgtinumchunksrequiringtranslation_ [l=ar] {Ø¹Ø¯Ø¯ Ø§ÙØªØ±Ø¬Ù
+Ø§Øª Ø§ÙØšØ§ÙÙØ©:}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=ar] {Ø¹Ø¯Ø¯ Ø§ÙØªØ±Ø¬Ù
+Ø§Øª Ø§ÙØªÙ ØªÙ
+Øª}  
+_textgtinumchunksrequiringupdating2_ [l=ar] {Ø¹Ø¯Ø¯ Ø§ÙØªØ±Ø¬Ù
+Ø§Øª Ø§ÙØªÙ ØªØ­ØªØ§Ø¬ Ø¥ÙÙ ØªØ­Ø¯ÙØ«}  
+_textgtinumchunksrequiringtranslation2_ [l=ar] {Ø¹Ø¯Ø¯ Ø§ÙØªØ±Ø¬Ù
+Ø§Øª Ø§ÙÙ
+ØªØšÙÙØ©}  
+
+_textgtienterquery_ [l=ar] {Ø£Ø¯Ø®Ù Ø§ÙÙÙÙ
+Ø© Ø£Ù Ø§ÙØ¬Ù
+ÙØ© Ø§ÙØªÙ ØªØ±ÙØ¯ ØªØµØ­ÙØ­ÙØ§}  
+_textgtifind_ [l=ar] {Ø§ØšØ­Ø«}  
+
+_textgtitranslatingchunk_ [l=ar] {ØªØ±Ø¬Ù
+Ø© Ø§ÙÙØµ <i>_1_</i>}  
+_textgtiupdatingchunk_ [l=ar] {ØªØ­Ø¯ÙØ« Ø§ÙÙØµ <i>_1_</i>}  
+_textgtisubmit_ [l=ar] {Ø£Ø±Ø³Ù}  
+
+_textgtilastupdated_ [l=ar] {Ø¢Ø®Ø± ØªØ­Ø¯ÙØ«}  
+
+_textgtitranslationfilecomplete_ [l=ar] {ØŽÙØ±Ø§Ù ÙÙ Ø¹ÙÙ ØªØ­Ø¯ÙØ« ÙØ°Ø§ Ø§ÙÙ
+ÙÙ -- ÙÙØ¯ Ø§ÙØªÙ
+Ù Ø§ÙØ¢Ù!<p>ÙÙ
+ÙÙÙ ØªØ­Ù
+ÙÙ ÙØ³Ø®Ø© Ù
+Ù ÙØ°Ø§ Ø§ÙÙ
+ÙÙ ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙØ±Ø§ØšØ·Ø© "Ø­Ù
+Ù Ø§ÙÙ
+ÙÙ" ØšØ£Ø¹ÙÙØ ÙØ§ÙØ°Ù Ø³ÙÙ ÙØªÙ
+ ØªØ¶Ù
+ÙÙÙ ÙÙ Ø§ÙØ¥ØµØ¯Ø§Ø±Ø§Øª Ø§ÙØªØ§ÙÙØ© ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone.}  
+
+_textgtiofflinetranslation_ [l=ar] {ÙÙ
+ÙÙÙ ØªØ±Ø¬Ù
+Ø© ÙØ°Ø§ Ø§ÙØ¬Ø²Ø¡ Ù
+Ù  Greenstone Ø®Ø§Ø±Ø¬ Ø§ÙÙ
+ÙÙØ¹ ØšØ¥Ø³ØªØ®Ø¯Ø§Ù
+ Ù
+ÙÙ Ù
+ØµÙÙÙØ© Microsoft Excel :
+
+<ol>
+<li>ØªÙØ²ÙÙ <a href=""_gwcgi_?a=gti&p=excel&tct=work&e=_compressedoptions_" ">ÙØ°Ø§ Ø§ÙÙ
+ÙÙ</a> ÙÙÙ Ø§ÙØ¹Ù
+Ù Ø§ÙÙ
+ØªØšÙÙ Ø Ø£Ù <a href=""_gwcgi_?a=gti&p=excel&tct=all&e=_compressedoptions_""> ÙØ°Ø§ Ø§ÙÙ
+ÙÙ</a> ÙÙÙ Ø§ÙØ£Ø³Ø·Ø± ÙÙ ÙØ°Ù Ø§ÙÙØ­Ø¯Ø©.
+<li>Ø§ÙØªØ­ Ø§ÙÙ
+ÙÙ Ø§ÙÙ
+ÙØ²Ù ÙÙ Microsoft Excel (Office 2003/XP Ø£Ù Ø¢Ù ÙØ³Ø®Ø© Ø£Ø­Ø¯Ø« Ù
+Ø·ÙÙØšØ© ) ÙÙÙ
+ ØšØ­ÙØžÙ ÙÙ
+ÙÙ Microsoft Excel workbook (.xls) .
+<li>Ø£Ø¯Ø®Ù Ø§ÙØªØ±Ø¬Ù
+Ø§Øª ÙÙ Ø§ÙÙ
+Ø±ØšØ¹Ø§Øª Ø§ÙÙ
+ØªÙÙØ±Ø©.
+<li>Ø¹ÙØ¯Ù
+Ø§ ØªÙØªÙÙ Ù
+Ù ØªØ±Ø¬Ù
+Ø© ÙÙ Ø§ÙØ£Ø³Ø·Ø± ØØ£Ø¹Ø¯ Ø¥Ø±Ø³Ø§Ù Ù
+ÙÙ .xls ØšØ§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ Ø¥ÙÙ <a href=""mailto:_gtiadministratoremail_"">_gtiadministratoremail_</a>.
+</ol>
+}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=ar] {ÙØ§Ø¬ÙØ© Ø§ÙÙ
+ÙØªØšÙ ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone}  
+_textglihelp_ [l=ar] {ÙØ§Ø¬ÙØ© Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙÙ
+ÙØªØšÙ Greenstone Librarian Interface (GLI) ØªØ³Ù
+Ø­ ÙÙ ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ ÙØžØ§ØŠÙ ØšØ±ÙØ§Ù
+Ø¬ Greenstone Ù
+Ù Ø®ÙØ§Ù ÙØ§Ø¬ÙØ© Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø³ÙÙØ© ÙØªØ¹ØªÙ
+Ø¯ Ø¹ÙÙ Ø§ÙÙØ£Ø±Ø©. Ø­ÙØ« ÙÙ
+ÙÙÙ ØªØ¬Ù
+ÙØ¹ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ù
+Ù Ø§ÙÙØ«Ø§ØŠÙ ÙØªØ³ØªÙØ±Ø¯ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ Ø§ÙØ®Ø§ØµØ© ØšÙØ§ Ø£Ù ØªØ­Ø¯Ø¯ÙØ§ ØšÙÙØ³Ù Ø«Ù
+ ØªÙÙÙ Ø¹Ù
+ÙÙØ© ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©.
+ <p>
+ÙØ§Ø­Øž Ø£Ù GLI ÙØ¹Ù
+Ù Ù
+Ù Ø®ÙØ§Ù ØšØ±ÙØ§Ù
+Ø¬ GreenstoneØ ÙÙÙØªØ±Ø¶ Ø£Ù ÙØªÙ
+ ØªØ«ØšÙØªÙ ÙÙ Ù
+Ø¬ÙØ¯ ÙØ±Ø¹Ù Ù
+Ù Ù
+Ø¬ÙØ¯ Greenstone. ÙÙØ°Ù Ø§ÙØ­Ø§ÙØ© Ø®Ø§ØµØ© ØšÙ
+Ø§ Ø¥Ø°Ø§ ÙÙØª Ø­Ù
+ÙØª Ø§ÙØšØ±ÙØ§Ù
+Ø¬ Ù
+Ù Ø¹ÙÙ Ø§ÙØ¥ÙØªØ±ÙØª Ø£Ù ÙÙ
+Øª ØªØ«ØšÙØªÙ Ù
+Ù Ø¹ÙÙ ÙØ±Øµ Greenstone Ø§ÙÙ
+Ø¯Ù
+Ø¬.
+
+ 
+<h4>ØªØŽØºÙÙ GLI ÙÙ ØšÙØŠØ© Windows </h4>
+ 
+ØŽØºÙ ÙØ§Ø¬ÙØ© Ø§ÙÙ
+ÙØªØšÙ ÙÙ ØšÙØŠØ© Windows ØšØ§Ø®ØªÙØ§Ø± <i>Greenstone Digital Library</i> Ù
+Ù ÙØ³Ù
+ <i>Ø§ÙØšØ±Ø§Ù
+Ø¬</i> ÙÙ ÙØ§ØŠÙ
+Ø© <i>Ø¥ØšØ¯Ø£</i> Ø«Ù
+ Ø§Ø®ØªÙØ§Ø± <i>Librarian Interface</i>. 
+
+ 
+<h4>ØªØŽØºÙÙ GLI ÙÙ ØšÙØŠØ© Unix</h4>
+ 
+ÙØªØŽØºÙÙ GLI ÙÙ ØšÙØŠØ© Unix, Ø§ÙØªÙÙ Ø¥ÙÙ Ù
+Ø¬ÙØ¯ <i>gli</i> Ø£Ø«ÙØ§Ø¡ ØªØ«ØšÙØª ØšØ±ÙØ§Ù
+Ø¬ GreenstoneØ Ø«Ù
+ ÙÙ
+ ØšØªØŽØºÙÙ Ø§ÙÙ
+ÙÙ <i>gli.sh</i> . 
+ 
+<h4>ØªØŽØºÙÙ GLI ÙÙ ØšÙØŠØ© Mac OS X</h4>
+
+ÙÙ Ù
+ØªØµÙØ­ Ø§ÙÙ
+ÙÙØ§Øª , ØªØµÙØ­ Ø­ØªÙ ØªØµÙ Ø¥ÙÙ  <i>Applications</i> Ø«Ù
+ <i>Greenstone</i>
+(ÙØ°Ø§ ÙÙ Ø­Ø§ÙØ© ØªØ«ØšÙØª Ø§ÙØšØ±ÙØ§Ù
+Ø¬ ÙÙ Ø§ÙÙ
+Ø³Ø§Ø±Ø§Øª Ø§ÙÙ
+Ø¹Ø±ÙØ© ØªÙÙØ§ØŠÙØ§ ÙÙØªØ«ØšÙØª), Ø«Ù
+ ØŽØºÙ  <i>GLI</i> application}  
Index: /gsdl/stable/macros/armenian.dm
===================================================================
--- /gsdl/stable/macros/armenian.dm	(revision 20131)
+++ /gsdl/stable/macros/armenian.dm	(revision 20131)
@@ -0,0 +1,795 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Armenian Language text and icon macros 
+# Many thanks to Tigran Zargaryan (translated January 2004)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=hy] {ÕÕ¡ÖÕ¢Õ¥ÖÕ¡Õ¯Õ¡Õ¶Õ¶Õ¥Ö}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=hy] {Õ°Õ²ÕžÖÕŽ Õ¡Õ²Õ¢ÕµÕžÖÖÕ«Õ¶}
+_textdate_ [l=hy] {Õ°ÖÕ¡Õ¿Õ¡ÖÕ¡Õ¯ÕŽÕ¡Õ¶ Õ¡ÕŽÕœÕ¡Õ©Õ«ÕŸ`}
+_textnumpages_ [l=hy] {Õ§Õ»Õ¥ÖÕ« ÖÕ¡Õ¶Õ¡Õ¯}
+
+_textsignin_ [l=hy] {ÕÕžÖÕ¿Ö}
+
+_textdefaultcontent_ [l=hy] {ÕÕ¶Õ¿ÖÕŸÕžÕ² Õ§Õ»Õš Õ¹Õ« Õ£Õ¿Õ¶ÕŸÕžÖÕŽ: ÕÕ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Ö
+Õ€Õ«Õ¿Õ¡Õ¯Õ« 'Õ°Õ¥Õ¿' Õ¯ÕžÕ³Õ¡Õ¯Õš Õ¯Õ¡ÕŽ ÕÕžÖÕ¶ Õ¯ÕžÕ³Õ¡Õ¯Õš` ÕŸÕ¥ÖÕ¡Õ€Õ¡ÕŒÕ¶Õ¡Õ¬ÕžÖ
+Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶:}
+
+_textdefaulttitle_ [l=hy] {GSDL ÕœÕ­Õ¡Õ¬}
+
+_textbadcollection_ [l=hy] {Ô±ÕµÕœ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ (Õ¡Õ¶ÕžÖÕ¶Õš "_cvariable_") Õ¯Õ¡ÖÕ£Õ¡Õ¢Õ¥ÖÕŸÕ¡Õ® Õ¹Õ§ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« Õ¿ÕŸÕµÕ¬ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« ÕŸÖÕ¡:}
+
+_textselectpage_ [l=hy] {ÔžÕ¶Õ¿ÖÕ«Ö Õ§Õ»}
+
+_collectionextra_ [l=hy] {Ô±ÕµÕœ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ§ _about:numdocs_ ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©: 
+ÕÕ¥ÖÕ»Õ«Õ¶ Õ¡Õ¶Õ£Õ¡ÕŽ Õ¡ÕµÕ¶ ÕœÕ¿Õ¥Õ²Õ®ÕŸÕ¥Õ¬ Õ§ _about:builddate_ Ö
+Ö Õ¡ÕŒÕ¡Õ»:}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=hy] {<p>Ô±ÕµÕœ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ§ _numdocs_ _If_("_numdocs_" Õ°Õ¡ÕŸÕ¡ÕœÕ¡Ö "1",ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©,/Õ¥Ö/), ÕšÕ¶Õ€Õ¡ÕŽÕ¥Õ¶Õš _numbytes_.
+<p><a href="_httppagex_(bsummary)">ÕÕ¥Õ²ÕŽÕ«Ö </a> Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« ÕœÕ¿Õ¥Õ²Õ®ÕŽÕ¡Õ¶ Õ°Õ¡ÕŽÕ¡ÕŒÕžÕ¿Õ¡Õ£ÖÕžÖÕ©ÕµÕžÖÕ¶Õš Õ€Õ«Õ¿Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö:
+}
+
+_textdescrcollection_ [l=hy] {}
+_textdescrabout_ [l=hy] {Ô·Õ»Õ« ÕŽÕ¡ÕœÕ«Õ¶}
+_textdescrhome_ [l=hy] {ÕÕ¶Õ¡ÕµÕ«Õ¶ Õ§Õ»}
+_textdescrhelp_ [l=hy] {ÕÕ£Õ¶ÕžÖÕ©ÕµÕ¡Õ¶ Õ§Õ»}
+_textdescrpref_ [l=hy] {ÕÕ¡Õ­ÕšÕ¶Õ¿ÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕ« Õ§Õ»}
+_textdescrgreenstone_ [l=hy] {Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« Õ®ÖÕ¡Õ£ÖÕ¡Õ·Õ¡Ö}
+_textdescrusab_ [l=hy] {Ô»Õ¶Õ¹ ÕžÖ Õ£Õ¿Õ¥Õ¬ Õ¥Õœ, Õ€ÕªÕŸÕ¡Ö Õ§ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=hy] {ÕÖÕžÕ¶ÕžÖÕŽ}  
+_labelSearch_ [l=hy] {ÕÖÕžÕ¶ÕžÖÕŽ}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=hy] {ÕÕ¥ÖÕ¶Õ¡Õ£Õ«Ö}  
+_labelTitle_ [l=hy] {ÕÕ¥ÖÕ¶Õ¡Õ£ÖÕ¥Ö Ô±-Õ}
+_textCreator_ [l=hy] {ÕÕ¿Õ¥Õ²Õ®ÕžÕ²}  
+_labelCreator_ [l=hy] {ÕÕ¥Õ²Õ«Õ¶Õ¡Õ¯Õ¶Õ¥Ö Ô±-Õ}
+_textSubject_ [l=hy] {Ô±ÕŒÕ¡ÖÕ¯Õ¡}  
+_labelSubject_ [l=hy] {Ô±ÕŒÕ¡ÖÕ¯Õ¡Õ¶Õ¥Ö}
+_textDescription_ [l=hy] {ÕÕ¯Õ¡ÖÕ¡Õ£ÖÕžÖÕ©ÕµÕžÖÕ¶}  
+_labelDescription_ [l=hy] {ÕÕ¯Õ¡ÖÕ¡Õ£ÖÕ«Õ¹Õ«Õ¥Ö}  
+_textPublisher_ [l=hy] {ÕÖÕ¡Õ¿Õ¡ÖÕ¡Õ¯Õ«Õ¹}  
+_labelPublisher_ [l=hy] {ÕÖÕ¡Õ¿Õ¡ÖÕ¡Õ¯Õ«Õ¹Õ¶Õ¥Ö}  
+_textContributor_ [l=hy] {Ô±Õ»Õ¡Õ¯Õ«Ö}  
+_labelContributor_ [l=hy] {Ô±Õ»Õ¡Õ¯Õ«ÖÕ¶Õ¥Ö}  
+_textDate_ [l=hy] {Ô±ÕŽÕœÕ¡Õ©Õ«ÕŸ}  
+_labelDate_ [l=hy] {Ô±ÕŽÕœÕ¡Õ©ÕŸÕ¥Ö}
+_textType_ [l=hy] {ÕÕºÕ«Ö}  
+_labelType_ [l=hy] {ÕÕ¥ÕœÕ¡Õ¯Õ¶Õ¥Ö}  
+_textFormat_ [l=hy] {ÕÖÕ¡Õ¹Õ¡Ö}  
+_labelFormat_ [l=hy] {ÕÖÕ¡Õ¹Õ¡ÖÕ¥Ö}  
+_textIdentifier_ [l=hy] {ÕÕžÖÕµÕ¶Õ¡Õ¯Õ¡Õ¶Õ¡ÖÕ«Õ¹}  
+_labelIdentifier_ [l=hy] {ÕÕžÖÕµÕ¶Õ¡ÖÕ«Õ¹Õ¶Õ¥Ö}  
+_textSource_ [l=hy] {ÕÕ¡ÕµÕ¬Õ« Õ¡Õ¶ÕŸÕ¡Õ¶ÕžÖÕŽ}  
+_labelSource_ [l=hy] {ÕÕ¡ÕµÕ¬Õ« Õ¡Õ¶ÕžÖÕ¶Õ¶Õ¥Ö}
+_textLanguage_ [l=hy] {ÔŒÕ¥ÕŠÕžÖ}  
+_labelLanguage_ [l=hy] {ÔŒÕ¥ÕŠÕžÖ}
+_textRelation_ [l=hy] {Ô¿Õ¡ÕºÕŸÕ¡Õ®ÕžÖÕ©ÕµÕžÖÕ¶}  
+_labelRelation_ [l=hy] {ÕÕ¡ÖÕ¡Õ¢Õ¥ÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö}  
+_textCoverage_ [l=hy] {ÔŸÕ¡Õ®Õ¯ÕžÖÕµÕ©}  
+_labelCoverage_ [l=hy] {ÔŸÕ¡Õ®Õ¯ÕžÖÕµÕ©}  
+_textRights_ [l=hy] {Ô»ÖÕ¡ÕŸÕžÖÕ¶ÖÕ¶Õ¥Ö}  
+_labelRights_ [l=hy] {Ô»ÖÕ¡ÕŸÕžÖÕ¶ÖÕ¶Õ¥Ö}  
+
+# DLS metadata set
+_textOrganization_ [l=hy] {Ô¿Õ¡ÕŠÕŽÕ¡Õ¯Õ¥ÖÕºÕžÖÕ©ÕµÕžÖÕ¶}  
+_labelOrganization_ [l=hy] {Ô¿Õ¡ÕŠÕŽÕ¡Õ¯Õ¥ÖÕºÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö}  
+_textKeyword_ [l=hy] {Ô²Õ¡Õ¶Õ¡Õ¬Õ« Õ¢Õ¡ÕŒ}  
+_labelKeyword_ [l=hy] {Ô²Õ¡Õ¶Õ¡Õ¬Õ« Õ¢Õ¡ÕŒÕ¥Ö}
+_textHowto_ [l=hy] {Ô»Õ¶Õ¹ÕºÕ¥Õœ}  
+_labelHowto_ [l=hy] {Ô»Õ¶Õ¹ÕºÕ¥Õœ}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=hy] {Ô±ÖÕ¿Õ¡Õ°Õ¡ÕµÕ¿ÕžÖÕ©ÕµÕžÖÕ¶}  
+_labelPhrase_ [l=hy] {Ô²Õ¡ÕŒÕ¥Ö}
+_textCollage_ [l=hy] {Ô¿ÕžÕ¬Õ¡Õª}  
+_labelCollage_ [l=hy] {Ô¿ÕžÕ¬Õ¡Õª}  
+_textBrowse_ [l=hy] {Ô¹Õ¥ÖÕ©Õ¥Õ¬}  
+_labelBrowse_ [l=hy] {Ô¹Õ¥ÖÕ©Õ«Ö}  
+_textTo_ [l=hy] {ÕÕ«Õ¶Õ¹Ö}  
+_labelTo_ [l=hy] {Ô±ÕµÕ¶Õ¿Õ¥Õ²}
+_textFrom_ [l=hy] {ÕÕ¯ÕœÕ¡Õ®}  
+_labelFrom_ [l=hy] {Ô±ÕµÕœÕ¿Õ¥Õ²Õ«Ö}
+_textAcronym_ [l=hy] {Ô±Õ¯ÖÕžÕ¶Õ«ÕŽ}  
+_labelAcronym_ [l=hy] {Ô±ÖÖÕžÕ¶Õ«ÕŽÕ¶Õ¥Ö}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=hy] {Ô¹Õ¥ÖÕ©Õ«Ö ÕšÕœÕ¿ _1_}  
+
+_textdescrSearch_ [l=hy] {ÕÖÕžÕ¶Õ¥Õ¬ Õ°Õ¡Õ¿ÕžÖÕ¯ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥Ö Õ£Õ¿Õ¶Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö}
+_textdescrType_ [l=hy] {Ô¹Õ¥ÖÕ©Õ«Ö ÕšÕœÕ¿ ÕºÕ¡Õ·Õ¡ÖÕ« Õ¿Õ¥ÕœÕ¡Õ¯Õ«}  
+_textdescrIdentifier_ [l=hy] {Ô¹Õ¥ÖÕ©Õ«Ö ÕšÕŽÕ¿ ÕºÕ¡Õ·Õ¡ÖÕ« Õ¶ÕžÖÕµÕ¶Õ¡ÖÕ«Õ¹Õ«}  
+_textdescrSource_ [l=hy] {Ô¹Õ¥ÖÕ©Õ¥Õ¬ ÕšÕœÕ¿ Õ¶Õ¡Õ­Õ¶Õ¡Õ¯Õ¡Õ¶ ÖÕ¡ÕµÕ¬Õ« Õ¡Õ¶ÕŸÕ¡Õ¶}
+_textdescrTo_ [l=hy] {Ô¹Õ¥ÖÕ©Õ¥Õ¬ ÕšÕœÕ¿ Ô±ÕµÕ¶Õ¿Õ¥Õ²Õ«Ö Õ€Õ¡Õ·Õ¿Õ«}
+_textdescrFrom_ [l=hy] {Ô¹Õ¥ÖÕ©Õ¥Õ¬ ÕšÕœÕ¿ Ô±ÕµÕœÕ¿Õ¥Õ²Õ«Ö Õ€Õ¡Õ·Õ¿Õ«}
+_textdescrCollage_ [l=hy] {Ô¹Õ¥ÖÕ©Õ«Ö ÕšÕœÕ¿ ÕºÕ¡Õ¿Õ¯Õ¥ÖÕ« Õ¯ÕžÕ¬Õ¡ÕªÕ«}  
+_textdescrAcronym_ [l=hy] {Ô¹Õ¥ÖÕ©Õ¥Õ¬ Õ¡ÖÖÕžÕ¶Õ«ÕŽÕ¶Õ¥ÖÕš}
+_textdescrPhrase_ [l=hy] {Ô¹Õ¥ÖÕ©Õ¥Õ¬ ÕšÕœÕ¿ Õ¡ÖÕ¿Õ¡Õ°Õ¡ÕµÕ¿ÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕ«}
+_textdescrHowto_ [l=hy] {Ô¹Õ¥ÖÕ©Õ¥Õ¬ ÕšÕœÕ¿ Õ€Õ¡ÕœÕ¥ÖÕ«}
+_textdescrBrowse_ [l=hy] {Ô¹Õ¥ÖÕ©Õ¥Õ¬}
+_texticontext_ [l=hy] {ÔŽÕ«Õ¿Õ¥Õ¬ ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš}
+_texticonclosedbook_ [l=hy] {Õ¢Õ¡ÖÕ¥Ö Õ¡ÕµÕœ ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš Ö Õ€Õ«Õ¿Õ¥Ö Õ¢ÕžÕŸÕ¡Õ¶Õ€Õ¡Õ¯ÕžÖÕ©ÕµÕžÖÕ¶Õš}
+_texticonnext_ [l=hy] {Õ°Õ¡Õ»ÕžÖÕ€ Õ¢Õ¡ÕªÕ«Õ¶}
+_texticonprev_ [l=hy] {Õ¶Õ¡Õ­ÕžÖÕ€ Õ¢Õ¡ÕªÕ«Õ¶}
+
+_texticonworld_ [l=hy] {ÔŽÕ«Õ¿Õ«Ö ÕžÕœÕ¿Õ¡ÕµÕ¶Õ« ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš}  
+
+_texticonmidi_ [l=hy] {ÔŽÕ«Õ¿Õ¥Ö MIDI ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš}
+_texticonmsword_ [l=hy] {ÔŽÕ«Õ¿Õ¥Ö ÕÕ¡ÕµÖÖÕžÕœÕžÖÕ© ÕÖÕžÖÕ€ ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš:}
+_texticonmp3_ [l=hy] {ÔŽÕ«Õ¿Õ¥Ö MP3 ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš}
+_texticonpdf_ [l=hy] {ÔŽÕ«Õ¿Õ¥Ö PDF ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš}
+_texticonps_ [l=hy] {ÔŽÕ«Õ¿Õ¥Ö PostScript ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš}
+_texticonppt_ [l=hy] {ÔŽÕ«Õ¿Õ¥Ö PowerPoint ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš}
+_texticonrtf_ [l=hy] {ÔŽÕ«Õ¿Õ¥Ö RTF ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš}
+_texticonxls_ [l=hy] {ÔŽÕ«Õ¿Õ¥Õ¬ ÕÕ¡ÕµÖÖÕžÕœÕžÖÕ© Ô·ÖÕœÕ¥Õ¬  ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš}
+
+_page_ [l=hy] {Õ§Õ»}
+_pages_ [l=hy] {Õ§Õ»Õ¥Ö}
+_of_ [l=hy] {Õ«Ö}
+_vol_ [l=hy] {ÕÕ¡Õ¿ÕžÖ}
+_num_ [l=hy] {ÕÕŽ.}
+
+_textmonth00_ [l=hy] {}
+_textmonth01_ [l=hy] {ÕÕžÖÕ¶ÕŸÕ¡Ö}
+_textmonth02_ [l=hy] {ÕÕ¥Õ¿ÖÕŸÕ¡Ö}
+_textmonth03_ [l=hy] {ÕÕ¡ÖÕ¿}
+_textmonth04_ [l=hy] {Ô±ÕºÖÕ«Õ¬}
+_textmonth05_ [l=hy] {ÕÕ¡ÕµÕ«Õœ}
+_textmonth06_ [l=hy] {ÕÕžÖÕ¶Õ«Õœ}
+_textmonth07_ [l=hy] {ÕÕžÖÕ¬Õ«Õœ}
+_textmonth08_ [l=hy] {ÕÕ£ÕžÕœÕ¿ÕžÕœ}
+_textmonth09_ [l=hy] {ÕÕ¥ÕºÕ¿Õ¥ÕŽÕ¢Õ¥Ö}
+_textmonth10_ [l=hy] {ÕÕžÕ¯Õ¿Õ¥ÕŽÕ¢Õ¥Ö}
+_textmonth11_ [l=hy] {ÕÕžÕµÕ¥ÕŽÕ¢Õ¥Ö}
+_textmonth12_ [l=hy] {ÔŽÕ¥Õ¯Õ¿Õ¥ÕŽÕ¢Õ¥Ö}
+
+_textdocument_ [l=hy] {ÕÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©}
+_textsection_ [l=hy] {Ô²Õ¡ÕªÕ«Õ¶}
+_textparagraph_ [l=hy] {ÕÕ¡ÖÕ¡Õ£ÖÕ¡Ö}
+
+_magazines_ [l=hy] {Ô±ÕŽÕœÕ¡Õ£ÖÕ¥Ö}
+
+_nzdlpagefooter_ [l=hy] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">ÕÕžÖ Ô¶Õ¥Õ¬Õ¡Õ¶Õ€Õ«Õ¡ÕµÕ« Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« Õ¶Õ¡Õ­Õ¡Õ£Õ«Õ®</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">ÕÕ¡ÕŽÕ¡Õ¯Õ¡ÖÕ£Õ¹Õ¡ÕµÕ«Õ¶ Õ£Õ«Õ¿ÕžÖÕ©ÕµÕ¡Õ¶ Õ¢Õ¡ÕªÕ¡Õ¶ÕŽÕžÖÕ¶Ö</a>, 
+<a href="http://www.waikato.ac.nz">ÕÕ¡ÕµÕ¯Õ¡Õ¿ÕžÕ« Õ°Õ¡ÕŽÕ¡Õ¬ÕœÕ¡ÖÕ¡Õ¶</a>, 
+ÕÕžÖ Ô¶Õ¥Õ¬Õ¡Õ¶Õ€Õ«Õ¡}
+
+_linktextHOME_ [l=hy] {ÕÕžÖÕ¶}
+_linktextHELP_ [l=hy] {ÕÕ£Õ¶ÕžÖÕ©ÕµÕžÖÕ¶}
+_linktextPREFERENCES_ [l=hy] {ÕÔ±ÔœÔ±ÕÔ±ÕÕÕÕÔ¹Õ
+ÕÕÕÕÔµÕ}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=hy] {Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶}  
+
+
+
+
+_textdescradmin_ [l=hy] {Ô¹ÕžÖÕµÕ¬ Õ§ Õ¿Õ¡Õ¬Õ«Õœ Õ¡ÕŸÕ¥Õ¬Õ¡ÖÕ¶Õ¥Õ¬ Õ¶ÕžÖ Ö
+Õ£Õ¿ÕŸÕžÕ²Õ¶Õ¥Ö, Õ°Õ¡Õ¶ÖÕ¡Õ£ÕžÖÕŽÕ¡ÖÕ« Õ§ Õ¢Õ¥ÖÕžÖÕŽ Õ°Õ¡ÕŽÕ¡Õ¯Õ¡ÖÕ£ÕžÖÕŽ Õ¡ÕŒÕ¯Õ¡ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕš, Õ¿ÖÕ¡ÕŽÕ¡Õ€ÖÕžÖÕŽ Õ§ Õ¿Õ¥Õ­Õ¶Õ«Õ¯Õ¡Õ¯Õ¡Õ¶ Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶ Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ°Õ¡ÕŽÕ¡Õ¯Õ¡ÖÕ£Õ« Õ¯Õ¡ÖÕ£Õ¡Õ¢Õ¥ÖÕŽÕ¡Õ¶ Õ°Õ¡ÕŽÕ¡ÖÖ}  
+
+_textdescrgogreenstone_ [l=hy] {ÕÕ¡Õ¿ÕŽÕžÖÕŽ Õ§ Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ®ÖÕ¡Õ£ÖÕ« Ö ÕÕžÖ Ô¶Õ¥Õ¬Õ¡Õ¶Õ€Õ¡Õ¯Õ¡Õ¶ Ô¹ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶ Õ¶Õ¡Õ­Õ¡Õ£Õ®Õ« ÕŽÕ¡ÕœÕ«Õ¶
+}  
+
+
+
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textdescrgli_ [l=hy] {ÕÕ£Õ¶ÕžÖÕŽ Õ§ ÕœÕ¿Õ¥Õ²Õ®Õ¥Õ¬ÕžÖ Õ¶ÕžÖ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥Ö, Õ±ÖÕ¡ÖÕžÕ­Õ¥Õ¬ Õ¯Õ¡ÕŽ Õ¡ÕŸÕ¥Õ¬Õ¡ÖÕ¶Õ¥Õ¬ Õ£ÕžÕµÕžÖÕ©ÕµÕžÖÕ¶ ÕžÖÕ¶Õ¥ÖÕžÕ²Õ¶Õ¥ÖÕ«Õ¶, Õ¯Õ¡ÕŽ Õ°Õ¥ÕŒÕ¡ÖÕ¶Õ¥Õ¬ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕšÖ
+}  
+
+package collector
+
+_textcollector_ [l=hy] {ÕÕ¡ÕŸÕ¡ÖÕ«Õ¹}  
+
+package depositor
+
+_textdescrdepositor_ [l=hy] {ÕÕ£Õ¶ÕžÖÕŽ Õ§ Õ¡ÕŸÕ¥Õ¬Õ¡ÖÕ¶Õ¥Õ¬ÕžÖ Õ£ÕžÕµÕžÖÕ©ÕµÕžÖÕ¶ ÕžÖÕ¶Õ¥ÖÕžÕ² Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕ«Õ¶ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÖ
+}  
+
+package gti
+
+_textgti_ [l=hy] {Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ©Õ¡ÖÕ£ÕŽÕ¡Õ¶Õ«Õ¹Õ« ÕŽÕ«Õ»Õ¥ÖÕ¥Õœ}  
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=hy] {Ô±ÕµÕœ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« ÕŽÕ¡ÕœÕ«Õ¶}
+
+_textsubcols1_ [l=hy] {<p>ÕÕ²Õ» Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ§ _1_ Õ¥Õ¶Õ©Õ¡Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥Ö: 
+ÕÕ¡ÕœÕ¡Õ¶Õ¥Õ¬Õ«Õ¶Õ¥ÖÕ¶ Õ¥Õ¶`
+<blockquote>}
+
+_textsubcols2_ [l=hy] {</blockquote>
+ÔŽÕžÖ Õ¯Õ¡ÖÕžÕ² Õ¥Õœ ÕœÕ¿ÕžÖÕ£Õ¥Õ¬ Õ©Õ¥ ÕžÖ Õ¥Õ¶Õ©Õ¡Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕ¶ Õ¥Õœ 
+Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕžÖÕŽ ÕÕ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕ« Õ§Õ»ÕžÖÕŽ:}
+
+_titleabout_ [l=hy] {ÕŽÕ¡ÕœÕ«Õ¶}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=hy] {ÖÕ¡Õ¯Õ«Ö Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« Õ¡ÕµÕœ Õ¢Õ¡ÕªÕ«Õ¶Õš}
+_texticonclosedbookshelf_ [l=hy] {Õ¢Õ¡ÖÕ«Ö Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« Õ¡ÕµÕœ Õ¢Õ¡ÕªÕ«Õ¶Õš Ö Õ€Õ«Õ¿Õ«Ö Õ¢ÕžÕŸÕ¡Õ¶Õ€Õ¡Õ¯ÕžÖÕ©ÕµÕžÖÕ¶Õš}
+_texticonopenbook_ [l=hy] {ÖÕ¡Õ¯Õ«Ö Õ¡ÕµÕœ Õ£Õ«ÖÖÕš}
+_texticonclosedfolder_ [l=hy] {Ô²Õ¡ÖÕ«Ö Õ¡ÕµÕœ Õ©Õ²Õ©Õ¡ÕºÕ¡Õ¶Õ¡Õ¯Õš Ö Õ€Õ«Õ¿Õ«Ö Õ¢ÕžÕŸÕ¡Õ¶Õ€Õ¡Õ¯ÕžÖÕ©ÕµÕžÖÕ¶Õš}
+_texticonclosedfolder2_ [l=hy] {Õ¢Õ¡ÖÕ«Ö Õ¥Õ¶Õ©Õ¡Õ¢Õ¡ÕªÕ«Õ¶Õš}
+_texticonopenfolder_ [l=hy] {ÖÕ¡Õ¯Õ«Ö Õ¡ÕµÕœ Õ©Õ²Õ©Õ¡ÕºÕ¡Õ¶Õ¡Õ¯Õš}
+_texticonopenfolder2_ [l=hy] {ÖÕ¡Õ¯Õ«Ö Õ¥Õ¶Õ©Õ¡Õ¢Õ¡ÕªÕ«Õ¶Õš}
+_texticonsmalltext_ [l=hy] {Õ€Õ«Õ¿Õ«Ö Õ¿Õ¥ÖÕœÕ¿Õ« Õ¡ÕµÕœ Õ¢Õ¡ÕªÕ«Õ¶Õš}
+_texticonsmalltext2_ [l=hy] {Õ€Õ«Õ¿Õ«Ö Õ¿Õ¥ÖÕœÕ¿Õš}
+_texticonpointer_ [l=hy] {ÕšÕ¶Õ©Õ¡ÖÕ«Õ¯ Õ¢Õ¡ÕªÕ«Õ¶}
+_texticondetach_ [l=hy] {Ô²Õ¡ÖÕ«Ö Õ¡ÕµÕœ Õ§Õ»Õš Õ¶ÕžÖ ÕºÕ¡Õ¿ÕžÖÕ°Õ¡Õ¶ÕžÖÕŽ}
+_texticonhighlight_ [l=hy] {ÔžÕ¶Õ€Õ£Õ®Õ«Ö ÖÕ¶Õ¿ÖÕŸÕžÕ² Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥ÖÕš}
+_texticonnohighlight_ [l=hy] {ÕÕ« Õ£ÕžÖÕ¶Õ¡ÖÕžÕ­Õ«Ö ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥ÖÕš}
+_texticoncontracttoc_ [l=hy] {ÕÕ¥Õ²ÕŽÕ«Ö Õ¢ÕžÕŸÕ¡Õ¶Õ€Õ¡Õ¯ÕžÖÕ©ÕµÕžÖÕ¶Õš}
+_texticonexpandtoc_ [l=hy] {ÔžÕ¶Õ€Õ¬Õ¡ÕµÕ¶Õ«Ö Õ¢ÕžÕŸÕ¡Õ¶Õ€Õ¡Õ¯ÕžÖÕ©ÕµÕžÖÕ¶Õš}
+_texticonexpandtext_ [l=hy] {Ô±ÖÕ¿Õ¡Õ®Õ«Ö ÕžÕ²Õ» Õ¿Õ¥ÖÕœÕ¿Õš}
+_texticoncontracttext_ [l=hy] {Ô±ÖÕ¿Õ¡Õ®Õ«Ö ÕŽÕ«Õ¡ÕµÕ¶ ÕšÕ¶Õ¿ÖÕŸÕ¡Õ® ÕšÕ¶Õ©Õ¡ÖÕ«Õ¯ Õ¢Õ¡ÕªÕ¶Õ« Õ°Õ¡ÕŽÕ¡Ö}
+_texticonwarning_ [l=hy] {<b>Ô¶Õ£ÕžÖÕ·Õ¡ÖÕžÖÕŽ: </b>}
+_texticoncont_ [l=hy] {ÕÕ¡ÖÕžÖÕ¶Õ¡Õ¯Õ¥ÕÕ¬}
+
+_textltwarning_ [l=hy] {<div class="buttons">_imagecont_</div>
+_iconwarning_Ô±ÕµÕœÕ¿Õ¥Õ² Õ¿Õ¥ÖÕœÕ¿Õš ÕšÕ¶Õ€Õ¬Õ¡ÕµÕ¶Õ¥Õ¬ÕžÕŸ, Õ¯Õ°Õ¡Õ¶Õ£Õ¥ÖÕ¶Õ« Õ¿ÕŸÕµÕ¡Õ¬Õ¶Õ¥ÖÕ« 
+ÕŽÕ¥Õ® ÖÕ¡Õ¶Õ¡Õ¯Õ« Õ¡ÖÕ¿Õ¡Õ®ÕŽÕ¡Õ¶
+}
+
+_textgoto_ [l=hy] {Õ£Õ¶Õ¡ Õ§Õ»}
+_textintro_ [l=hy] {<i>(Õ¶Õ¥ÖÕ¡Õ®Õ¡Õ¯Õ¡Õ¶ Õ¿Õ¥ÖÕœÕ¿)</i>}
+
+_textCONTINUE_ [l=hy] {ÕÔ±ÕÕÕÕÔ±Ô¿ÔµÕÔŒ?}
+
+_textEXPANDTEXT_ [l=hy] {ÔžÕÔŽÔŒÔ±Õ
+ÕÔµÔŒ\nÕÔµÕÕÕÔž}
+
+_textCONTRACTCONTENTS_ [l=hy] {ÕÔµÕÕÔµÔŒ\nÔ²ÕÕÔ±ÕÔŽÔ±Ô¿ÕÕÔ¹Õ
+ÕÕÕÔž}
+
+_textDETACH_ [l=hy] {Ô±ÕÔ±ÕÕÕÔ±ÕÕÔµÔŒ}
+
+_textEXPANDCONTENTS_ [l=hy] {ÔžÕÔŽÔŒÔ±Õ
+ÕÔµÔŒ\nÔ²ÕÕÔ±ÕÔŽÔ±Ô¿ÕÕÔ¹Õ
+ÕÕÕÔž}
+
+_textCONTRACT_ [l=hy] {ÕÔµÕÕÔµÔŒ ÕÔµÕÕÕÔž}
+
+_textHIGHLIGHT_ [l=hy] {Ô³ÕÕÕÔ±ÕÕÔœÕÕÕ}
+
+_textNOHIGHLIGHT_ [l=hy] {ÕÔ³ÕÕÕÔ±ÕÕÔœÔµÔŒ}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=hy] {_If_(_thislast_,results _thisfirst_ - _thislast_ Õ°Õ¡ÖÖÕŽÕ¡Õ¶ Õ°Õ¡ÕŽÕ¡Ö: _cgiargq_,ÕÕ¯Õ¡Õ¶ Õ°Õ¡ÕŽÕšÕ¶Õ¯Õ¶ÕžÖÕŽÕ¶Õ¥Ö Õ°Õ¡ÖÖÕŽÕ¡Õ¶Õš: _cgiargq_)}
+_textnoquerytitle_ [l=hy] {ÕÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ§Õ»}
+
+_textsome_ [l=hy] {ÕžÖÕžÕ·}
+_textall_ [l=hy] {Õ¢ÕžÕ¬ÕžÖÕš}
+_textboolean_ [l=hy] {Õ¢ÕžÖÕ¬ÕµÕ¡Õ¶}
+_textranked_ [l=hy] {Õ£Õ¶Õ¡Õ°Õ¡Õ¿ÕŸÕ¡Õ®}
+_textnatural_ [l=hy] {Õ¢Õ¶Õ¡Õ¯Õ¡Õ¶}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=hy] {ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ ÕºÕ¡Õ¿ÕŽÕžÖÕ©ÕµÕžÖÕ¶}
+
+_textifeellucky_ [l=hy] {ÔµÕœ Õ°Õ¡Õ»ÕžÕ²Õ¡Õ¯ Õ¥ÕŽÖ}  
+
+#alt text for query buttons
+_textusequery_ [l=hy] {Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ«Ö Õ¡ÕµÕœ Õ°Õ¡ÖÖÕžÖÕŽÕš}
+_textfreqmsg1_ [l=hy] {Ô²Õ¡ÕŒÕ« Õ°Õ¡Õ·ÕŸÕ«Õ¹}
+_textpostprocess_ [l=hy] {_If_(_quotedquery_,<br><i>Õ°Õ¥Õ¿-Õ£ÕžÖÕ®ÕšÕ¶Õ©Õ¡Ö, ÕžÖÕžÕ¶ÕŽÕ¡Õ¶ Õ°Õ¡ÕŽÕ¡Ö _quotedquery_</i>
+)}
+_textinvalidquery_ [l=hy] {Õ°Õ¡ÖÖÕŽÕ¡Õ¶ ÕœÕ­Õ¡Õ¬ Õ·Õ¡ÖÕ¡Õ°ÕµÕžÖÕœÕžÖÕ©ÕµÕžÖÕ¶}
+_textstopwordsmsg_ [l=hy] {ÕÕ¥Õ¿ÖÕµÕ¡Õ¬ Õ¢Õ¡ÕŒÕ¥ÖÕš Õ·Õ¡Õ¿ ÕšÕ¶Õ€Õ°Õ¡Õ¶ÕžÖÖ Õ¥Õ¶, Ö Õ¡Õ¶Õ¿Õ¥ÕœÕŸÕžÖÕŽ Õ¥Õ¶Ö}  
+_textlucenetoomanyclauses_ [l=hy] {ÕÕ¡ÖÖÕžÖÕŽÕš Õ¹Õ¡ÖÕ«Ö Õ·Õ¡Õ¿ ÕžÖÕžÕ¶ÕŽÕ¡Õ¶ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥Ö Õ§ ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽÖ Ô¿Õ¡Õ¿Õ¡ÖÕ«Ö Õ¡ÕŒÕ¡ÕŸÕ¥Õ¬ Õ³Õ·Õ£ÖÕ«Õ¿ Õ°Õ¡ÖÖÕžÖÕŽÖ}  
+
+_textmorethan_ [l=hy] {Ô±ÕŸÕ¥Õ¬Õ«Õ¶}
+_textapprox_ [l=hy] {ÕÕ¡ÕœÕ«Õ¶}
+_textnodocs_ [l=hy] {ÕÕ¯Õ¡Õ¶ Õ°Õ¡ÕŽÕ¡ÕºÕ¡Õ¿Õ¡ÕœÕ­Õ¡Õ¶ÕžÕ² ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥Ö}
+_text1doc_ [l=hy] {1 ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ© Õ§ Õ°Õ¡ÕŽÕ¡ÕºÕ¡Õ¿Õ¡ÕœÕ­Õ¡Õ¶ÕžÖÕŽ Õ°Õ¡ÖÖÕŽÕ¡Õ¶Õš:}
+_textlotsdocs_ [l=hy] {ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš Õ°Õ¡ÕŽÕ¡ÕºÕ¡Õ¿Õ¡ÕœÕ­Õ¡Õ¶ÕžÖÕŽ Õ§ Õ°Õ¡ÖÖÕŽÕ¡Õ¶Õš}
+_textmatches_ [l=hy] {ÕÕ¡ÕŽÕ¡ÕºÕ¡Õ¿Õ¡ÕœÕ­Õ¡Õ¶ÕžÖÕŽ Õ§}
+_textbeginsearch_ [l=hy] {ÕÕ¯ÕœÕ«Ö ÖÕ¶Õ¿ÖÕžÖÕŽÕš}
+_textrunquery_ [l=hy] {Ô¿Õ¡Õ¿Õ¡ÖÕ«Ö Õ°Õ¡ÖÖÕžÖÕŽÕš}
+_textclearform_ [l=hy] {ÕÕ¡ÖÖÕ«Ö Õ±ÖÕš}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=hy] {Ô²Õ¡ÕŒ Õ¯Õ¡ÕŽ Õ¡ÖÕ¿Õ¡Õ°Õ¡ÕµÕ¿ÕžÖÕ©ÕµÕžÖÕ¶}
+_textinfield_ [l=hy] {âŠ Õ€Õ¡Õ·Õ¿ÕžÖÕŽ}
+_textfoldstem_ [l=hy] {(ÕœÕ¥Õ²ÕŽÕ«Õ¹, Õ£Õ¬Õ­Õ«Õ¯)}
+
+_textadvquery_ [l=hy] {Ô¿Õ¡ÕŽ ÕŽÕžÖÕ¿Ö Õ¡ÖÕ¡ Õ°Õ¡ÖÖÕžÖÕŽÕš ÕžÖÕ²Õ²Õ¡Õ¯Õ«ÕžÖÕ¥Õ¶}
+_textallfields_ [l=hy] {Õ¢ÕžÕ¬ÕžÖ Õ€Õ¡Õ·Õ¿Õ¥ÖÕš}
+_texttextonly_ [l=hy] {ÕŽÕ«Õ¡ÕµÕ¶ Õ¿Õ¥ÖÕœÕ¿}
+_textand_ [l=hy] {Ö}
+_textor_ [l=hy] {Õ¯Õ¡ÕŽ}
+_textandnot_ [l=hy] {Ö ÕžÕ¹}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=hy] {ÕÕ¶Õ¿ÖÕ«Ö _indexselection_ _If_(_jselection_, of _jselection_) _If_(_gselection_,  _gselection_ ÕŽÕ¡Õ¯Õ¡ÖÕ€Õ¡Õ¯) _If_(_nselection_, in _nselection_ Õ¬Õ¥ÕŠÕŸÕžÖÕŽ) ÕžÖÕš ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ§ _querytypeselection_ Õ¢Õ¡ÕŒÕ¥Ö}
+
+_textadvancedsearch_ [l=hy] {ÕÕ¶Õ¿ÖÕžÖÕŽ _indexselection_ _If_(_jselection_, of _jselection_) _If_(_gselection_, at _gselection_ level)_If_(_nselection_,  _nselection_ Õ¬Õ¥ÕŠÕŸÕ« ÕŽÕ¥Õ») Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬ÕžÕŸ _querytypeselection_ Õ°Õ¡ÖÖÕžÖÕŽÕš}
+
+_textadvancedmgppsearch_ [l=hy] {ÕÖÕžÕ¶Õ«Ö _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,ÕœÖÕ¡Õ¶ÕžÖÕŽ _gselection_ level )_If_(_nselection_,in _nselection_ language ) Ö Õ¡ÖÕ¿Õ¡Õ®Õ«Ö Õ¡ÖÕ€ÕµÕžÖÕ¶ÖÕ¶Õ¥ÖÕš _formquerytypeadvancedselection_ order}  
+
+_textadvancedlucenesearch_ [l=hy] {ÕÖÕžÕ¶Õ«Ö _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ ÕŽÕ¡Õ¯Õ¡ÖÕ€Õ¡Õ¯ )_If_(_nselection_,in _nselection_ Õ¬Õ¥ÕŠÕŸÕžÖÕŽ )Õ°Õ¡ÕŽÕ¡Ö}  
+
+_textformsimplesearch_ [l=hy] {ÕÕ¶Õ¿ÖÕ«Ö _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_, _nselection_ Õ¬Õ¥ÕŠÕŸÕžÖÕŽ) _formquerytypesimpleselection_ Õ°Õ¡ÕŽÕ¡Ö}
+
+_textformadvancedsearch_ [l=hy] {ÕÕ¶Õ¿ÖÕ«Ö _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ Õ¬Õ¥ÕŠÕžÖ )Ö Õ¡ÖÕ¿Õ¡Õ®Õ«Ö Õ¡ÖÕ€ÕµÕžÖÕ¶ÖÕ¶Õ¥ÖÕš _formquerytypeadvancedselection_ Õ°Õ¥ÖÕ©Õ¡Õ¯Õ¡Õ¶ÕžÖÕ©ÕµÕ¡ÕŽÕ¢}
+
+
+_textnojsformwarning_ [l=hy] {Ô¶Õ£ÕžÖÕ·Õ¡ÖÕžÖÕŽ: ÕÕž ÕžÕœÕ¿Õ¡ÕµÕ¶Õ« Õ€Õ«Õ¿Õ¡Õ¯ÕžÖÕŽ ÕÕ¡ÕŸÕ¡ÕœÕ¯ÖÕ«ÕºÕ¿Õš Õ¡Õ¶Õ»Õ¡Õ¿ÕŸÕ¡Õ® Õ§: <br>ÕÖÕ¡Õ¹Õ¡ÖÕžÕŸ ÖÕ¶Õ¿ÖÕžÖÕŽ Õ¯Õ¡Õ¿Õ¡ÖÕ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö, ÕŽÕ«Õ¡ÖÖÕžÖ Õ¡ÕµÕ¶:}
+_textdatesearch_ [l=hy] {Ô±ÕµÕœ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ Õ¯Õ¡ÖÕžÕ² Õ§ Õ®Õ¡ÕŒÕ¡ÕµÕ¥Õ¬ ÖÕ¶Õ¿ÖÕ¥Õ¬ÕžÖ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥Ö Õ¿ÖÕŸÕ¡Õ® Õ¡ÕŽÕœÕ¡Õ©ÕŸÕ¥ÖÕ« Õ¿Õ«ÖÕžÖÕµÕ©ÕžÖÕŽ, Õ¯Õ¡ÕŽ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥Ö ÕžÖÕžÕ¶Ö ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ¥Õ¶ ÕžÖÕžÕ·Õ¡Õ¯Õ« Õ¡ÕŽÕœÕ¡Õ©Õ«ÕŸ: ÕÕ¡ ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ ÕžÕ¹ ÕºÕ¡ÖÕ¿Õ¡Õ€Õ«Ö Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶ Õ§:}
+_textstartdate_ [l=hy] {ÕÕ¯ÕŠÕ¢Õ« (Õ¯Õ¡ÕŽ ÕŽÕ«Õ¡Õ¯) Õ¡ÕŽÕœÕ¡Õ©Õ«ÕŸ:}
+_textenddate_ [l=hy] {Ô±ÕŽÕœÕ¡Õ©ÕŸÕ« ÕŸÕ¥ÖÕ»:}
+_textbc_ [l=hy] {B.C.E.}
+_textad_ [l=hy] {C.E.}
+_textexplaineras_ [l=hy] {C.E. Ö B.C.E Õ¡ÕµÕ¬ÕšÕ¶Õ¿ÖÕ¡Õ¶ÖÕ¶Õ¥Ö Õ¥Õ¶ ÕŽ.Õ©. Ö ÕŽ.Õ©.Õ¡ Õ°Õ¡ÕŽÕ¡Ö Õ°Õ¡ÕŽÕ¡ÕºÕ¡Õ¿Õ¡ÕœÕ­Õ¡Õ¶Õ¡Õ¢Õ¡Ö: Ô±ÕµÕœ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥ÖÕš ÕŽÕ·Õ¡Õ¯ÕžÖÕ©Õ¡ÕµÕ«Õ¶ Õ¡ÕŒÕžÖÕŽÕžÕŸ Õ­Õ¿ÖÕ¡Õ¯Õ¡Õ¶ÕžÖÕ©ÕµÕžÖÕ¶Õ«Ö ÕŠÕ¥ÖÕ® Õ¥Õ¶, Ö Õ°Õ¡ÕŽÕ¡ÕºÕ¡Õ¿ÕœÕ­Õ¡Õ¶ÕžÖÕŽ Õ¥Õ¶ "ÔžÕ¶Õ©Õ¡ÖÕ«Õ¯ Õ€Õ¡ÖÕ¡Õ·ÖÕ»Õ¡Õ¶" Ö "ÕÕ«Õ¶Õ¹ ÕšÕ¶Õ©Õ¡ÖÕ«Õ¯ Õ€Õ¡ÖÕ¡Õ·ÖÕ»Õ¡Õ¶Õš"}
+
+_textstemon_ [l=hy] {(Õ¡Õ¶Õ¿Õ¥ÕœÕ¥Õ¬ Õ¢Õ¡ÕŒÕ¥ÖÕ« ÕŸÕ¥ÖÕ»Õ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš)}
+
+_textsearchhistory_ [l=hy] {ÕÕ¶Õ¿ÖÕŽÕ¡Õ¶ ÕºÕ¡Õ¿ÕŽÕžÖÕ©ÕµÕžÖÕ¶}
+
+#text macros for search history
+_textnohistory_ [l=hy] {ÕÕ¶Õ¿ÖÕŽÕ¡Õ¶ ÕºÕ¡Õ¿ÕŽÕžÖÕ©ÕµÕžÖÕ¶Õš ÕŽÕ¡Õ¿Õ¹Õ¥Õ¬Õ« Õ¹Õ§}
+_texthresult_ [l=hy] {Õ¡ÖÕ€ÕµÕžÖÕ¶Ö}
+_texthresults_ [l=hy] {Õ¡ÖÕ€ÕµÕžÖÕ¶ÖÕ¶Õ¥Ö}
+_texthallwords_ [l=hy] {Õ¢ÕžÕ¬ÕžÖ Õ¢Õ¡ÕŒÕ¥ÖÕš}
+_texthsomewords_ [l=hy] {ÕžÖÕžÕ· Õ¢Õ¡ÕŒÕ¥Ö}
+_texthboolean_ [l=hy] {Õ¢ÕžÖÕ¬ÕµÕ¡Õ¶}
+_texthranked_ [l=hy] {Õ£Õ¶Õ¡Õ°Õ¡Õ¿ÕŸÕ¡Õ®}
+_texthcaseon_ [l=hy] {Õ€Õ¥ÕºÖÕš ÕºÕ¥Õ¿Ö Õ§ Õ°Õ¡ÕŽÕšÕ¶Õ¯Õ¶Õ«}
+_texthcaseoff_ [l=hy] {Õ€Õ¥ÕºÖÕš Õ¡Õ¶Õ¿Õ¥ÕœÕŸÕ¡Õ®}
+_texthstemon_ [l=hy] {ÖÕ¡Õ¯ÕŸÕ¡Õ®}
+_texthstemoff_ [l=hy] {Õ¹ÖÕ¡Õ¯ÕŸÕ¡Õ®}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=hy] {ÕÕ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš Õ€ÖÕŸÕ¡Õ® Õ¥Õ¶ Õ°Õ¥Õ¿ÖÕµÕ¡Õ¬ Õ¯Õ¥ÖÕº: ÕÕ« Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ«Ö ÖÕž Õ€Õ«Õ¿Õ¡Õ¯Õ«
+"Õ°Õ¥Õ¿" Õ¯ÕžÕ³Õ¡Õ¯Õš - Õ¡ÕµÕ¶ Õ¯Õ»Õ¶Õ»Õ« Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš! ÕÕžÕ­Õ¡ÖÕ¥Õ¶Õš, ÕœÕ¥Õ²ÕŽÕ«Ö ÕœÕ¿ÕžÖÖ Õ¡ÕŒÕ¯Õ¡
+Õ¯ÕžÕ³Õ¡Õ¯Õ¶Õ¥ÖÕ«Ö ÕžÖÖÕ«ÖÕ¥ ÕŽÕ¥Õ¯Õ« ÕŸÖÕ¡:}
+_textsetprefs_ [l=hy] {Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕ« Õ¯Õ¡ÖÕ£Õ¡Õ¢Õ¥ÖÕžÖÕŽ}
+_textsearchprefs_ [l=hy] {ÕÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö}
+_textcollectionprefs_ [l=hy] {ÕÕ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö}
+_textpresentationprefs_ [l=hy] {ÕÕžÖÖÕ¡Õ€ÖÕŽÕ¡Õ¶ Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö}
+_textpreferences_ [l=hy] {ÕÕ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö}
+_textcasediffs_ [l=hy] {ÔŽÕ¥ÕºÖÕ¥ÖÕ« Õ¿Õ¡ÖÕ¢Õ¥ÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö:}
+_textignorecase_ [l=hy] {Õ¡Õ¶Õ¿Õ¥ÕœÕ«Ö Õ€Õ¥ÕºÖÕ¥ÖÕ« Õ¿Õ¡ÖÕ¢Õ¥ÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš}
+_textmatchcase_ [l=hy] {ÕŸÕ¥ÖÕ«Õ¶/ÕœÕ¿ÕžÖÕ«Õ¶ Õ€Õ¥ÕºÖÕš ÕºÕ¥Õ¿Ö Õ§ Õ°Õ¡ÕŽÕšÕ¶Õ¯Õ¶Õ«}
+_textwordends_ [l=hy] {Ô²Õ¡ÕŒÕ¥ÖÕ« ÕŸÕ¥ÖÕ»Õ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö:}
+_textstem_ [l=hy] {Õ¡Õ¶Õ¿Õ¥ÕœÕ«Ö Õ¢Õ¡ÕŒÕ¥ÖÕ« ÕŸÕ¥ÖÕ»Õ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš}
+_textnostem_ [l=hy] {Õ¢Õ¡ÕŒÕš Õ¡ÕŽÕ¢ÕžÕ²Õ»ÕžÕŸÕ«Õ¶ ÕºÕ¥Õ¿Ö Õ§ Õ°Õ¡ÕŽÕšÕ¶Õ¯Õ¶Õ«}
+_textprefop_ [l=hy] {ÕÕ¥ÖÕ¡Õ€Õ¡ÖÕ±Õ«Ö _maxdocoption_ ÖÕ¡Õ¶Õ¡Õ¯Õ«Õ¶, Õ°Õ¡ÕŽÕ¡ÕºÕ¡Õ¿Õ¡ÕœÕ­Õ¡Õ¶Õ¡Õ¢Õ¡Ö _hitsperpageoption_ Õ¡ÖÕ€ÕµÕžÖÕ¶Ö ÕŽÕ¥Õ¯ Õ§Õ»ÕžÖÕŽ:}
+_textextlink_ [l=hy] {ÕÕžÖÕ¿Ö Õ¡ÖÕ¿Õ¡ÖÕ«Õ¶ ÕžÕœÕ¿Õ¡ÕµÕ¶Õ« Õ§Õ»Õ¥ÖÕ«Õ¶}
+_textintlink_ [l=hy] {ÕÕ«ÕŽÕ¶Õ¡Õ¯Õ¡Õ¶ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥Ö Õ£Õ¿Õ¶ÕŸÕ¡Õ®}
+_textlanguage_ [l=hy] {ÕÕ«Õ»Õ¥ÖÕ¥ÕœÕ« Õ¬Õ¥ÕŠÕžÖ:}
+_textencoding_ [l=hy] {Ô¿ÕžÕ€Õ¡ÕŸÕžÖÕžÖÕŽ:}
+_textformat_ [l=hy] {ÕÕ«Õ»Õ¥ÖÕ¥ÕœÕ« ÖÕžÖÕŽÕ¡Õ¿:}
+_textall_ [l=hy] {Õ¡ÕŽÕ¢ÕžÕ²Õ»Õš}
+_textquerymode_ [l=hy] {ÕÕ¡ÖÖÕŽÕ¡Õ¶ ÕŸÕ«Õ³Õ¡Õ¯:}
+_textsimplemode_ [l=hy] {ÕºÕ¡ÖÕŠ Õ°Õ¡ÖÖÕŽÕ¡Õ¶ ÕŸÕ«Õ³Õ¡Õ¯}
+_textadvancedmode_ [l=hy] {Õ­ÕžÖÕ¡ÖÕŸÕ¡Õ® Õ°Õ¡ÖÖÕŽÕ¡Õ¶ ÕŸÕ«Õ³Õ¡Õ¯ (Õ©ÕžÖÕµÕ¬Õ¡Õ¿ÖÕžÖÕŽ Õ§ Õ¢ÕžÖÕ¬ÕµÕ¡Õ¶ ÕžÖÕžÕ¶ÕžÖÕŽÕ¶Õ¥Ö !, &, |, Ö ÖÕ¡Õ¯Õ¡Õ£Õ®Õ¥ÖÕ« Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕŽÕ¡ÕŽÕ¢)}
+_textlinkinterm_ [l=hy] {ÕŽÕ«Õ»Õ¡Õ¶Õ¯ÕµÕ¡Õ¬ Õ§Õ»Õ« ÕŽÕ«Õ»ÕžÕŸ}
+_textlinkdirect_ [l=hy] {ÕžÖÕ²Õ²Õ¡Õ¯Õ« Õ£Õ¶Õ¡ Õ¡ÕµÕ¶Õ¿Õ¥Õ²}
+_textdigitlib_ [l=hy] {Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶}
+_textweb_ [l=hy] {ÕžÕœÕ¿Õ¡ÕµÕ¶}
+_textgraphical_ [l=hy] {Ô³ÖÕ¡ÖÕ«Õ¯Õ¡Õ¯Õ¡Õ¶}
+_texttextual_ [l=hy] {ÕÕ¥ÖÕœÕ¿Õ¡ÕµÕ«Õ¶}
+_textcollectionoption_ [l=hy] {<p>
+ÔžÕ¶Õ€Õ£ÖÕ¯ÕŽÕ¡Õ¶ Õ¥Õ¶Õ©Õ¡Õ¯Õ¡ Õ¥Õ¶Õ©Õ¡Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥Ö:
+<br>}
+
+_textrelateddocdisplay_ [l=hy] {Õ¡ÖÕ¿Õ¡Õ®Õ«Ö Õ¯Õ¡ÕºÕŸÕ¡Õ® ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš}
+_textsearchhistory_ [l=hy] {ÕÕ¶Õ¿ÖÕŽÕ¡Õ¶ ÕºÕ¡Õ¿ÕŽÕžÖÕ©ÕµÕžÖÕ¶:}
+_textnohistory_ [l=hy] {ÕÕ¶Õ¿ÖÕŽÕ¡Õ¶ ÕºÕ¡Õ¿ÕŽÕžÖÕ©ÕµÕžÖÕ¶Õ¶ Õ¡ÕŒÕ¯Õ¡ Õ¹Õ§}
+_texthistorydisplay_ [l=hy] {Õ¡ÖÕ¿Õ¡Õ®Õ«Ö _historynumrecords_ ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ ÕºÕ¡Õ¿ÕŽÕžÖÕ©ÕµÕ¡Õ¶ Õ£ÖÕ¡ÕŒÕžÖÕŽÕ¶Õ¥ÖÕš}
+_textnohistorydisplay_ [l=hy] {ÕŽÕ« Õ¡ÖÕ¿Õ¡Õ®Õ«Ö ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ ÕºÕ¡Õ¿ÕŽÕžÖÕ©ÕµÕžÖÕ¶Õš}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=hy] {ÕÖÕžÕ¶ÕŽÕ¡Õ¶ Õ±Ö:}
+_textplainsearch_ [l=hy] {Ô±ÕŠÕ¡Õ¿ ÖÕ¶Õ¿ÖÕžÖÕŽ:}
+_textqueryboxsize_ [l=hy] {ÕÕ¡ÖÖÕŽÕ¡Õ¶ ÕºÕ¡Õ¿ÕžÖÕ°Õ¡Õ¶Õ« Õ¹Õ¡ÖÕš:}
+_textregbox_ [l=hy] {Õ¯Õ¡Õ¶ÕžÕ¶Õ¡ÕŸÕžÖ Õ°Õ¡ÖÖÕŽÕ¡Õ¶ ÕºÕ¡Õ¿ÕžÖÕ°Õ¡Õ¶}
+_textbigbox_ [l=hy] {Õ°Õ¡ÖÖÕŽÕ¡Õ¶ ÕŽÕ¥Õ® ÕºÕ¡Õ¿ÕžÖÕ°Õ¡Õ¶}
+_textformtype_ [l=hy] {ÕÕ¥ÕœÕ¡Õ¯Õ« Õ±Ö}
+_textsimple_ [l=hy] {ÕºÕ¡ÖÕŠ}
+_textadvanced_ [l=hy] {Õ­ÕžÖÕ¡ÖÕŸÕ¡Õ®}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=hy] {Õ°Õ¥Õ¿}
+_textfields_ [l=hy] {Õ€Õ¡Õ·Õ¿Õ¥Ö}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=hy] {ÕÕ¥ÕœÕ¡Õ¯Õ¡ÕŸÕžÖÕ«Ö ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš ÕšÕœÕ¿}
+_textalsoshowing_ [l=hy] {Õ¶Õ¡Ö ÖÕžÖÕµÖ Õ¿Õ¡Õ¬}
+_textwith_ [l=hy] {Õ¡ÕŒÕ¶ÕŸÕ¡ÕŠÕ¶}
+_textdocsperpage_ [l=hy] {ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ© ÕšÕœÕ¿ Õ§Õ»Õ«}
+
+_textfilterby_ [l=hy] {Ô³Õ¿Õ«Ö ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥Ö` ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÕ²}
+_textall_ [l=hy] {Õ¢ÕžÕ¬ÕžÖÕš}
+_textany_ [l=hy] {Õ¯Õ¡ÕŽÕ¡ÕµÕ¡Õ¯Õ¡Õ¶}
+_textwords_ [l=hy] {Õ¢Õ¡ÕŒÕ¥Ö}
+_textleaveblank_ [l=hy] {Õ©ÕžÕ² Õ¡ÕµÕœ ÕŸÕ¡Õ¶Õ€Õ¡Õ¯Õš Õ€Õ¡Õ¿Õ¡ÖÕ¯, Õ¢ÕžÕ¬ÕžÖ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš ÕœÕ¿Õ¡Õ¶Õ¡Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö}
+
+_browsebuttontext_ [l=hy] {"ÕÕ¥ÕœÕ¡Õ¯Õ¡ÕŸÕžÖÕ«Ö ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš"}
+
+_nodata_ [l=hy] {<i>Õ¿ÕŸÕµÕ¡Õ¬Õ¶Õ¥Ö Õ¹Õ¯Õ¡Õ¶</i>}
+_docs_ [l=hy] {ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥Ö}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=hy] {ÕÕ£Õ¶ÕžÖÕ©ÕµÕžÖÕ¶}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=hy] {Ô¹Õ¥ÖÕ©Õ«Ö ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš ÕšÕœÕ¿ _1_ ÕœÕ¥Õ²ÕŽÕ¥Õ¬ÕžÕŸ _2_ Õ¯ÕžÕ³Õ¡Õ¯Õš}  
+
+_textSearchhelp_ [l=hy] {ÕžÖÕžÕ¶Õ«Ö ÕžÖÕžÕ·Õ¡Õ¯Õ« Õ¢Õ¡ÕŒÕ¥Ö, ÕžÖÕžÕ¶Ö Õ°Õ¡Õ¶Õ€Õ«ÕºÕžÖÕŽ Õ¥Õ¶ Õ¿Õ¥ÖÕœÕ¿ÕžÖÕŽ ÕœÕ¥Õ²ÕŽÕ¥Õ¬ÕžÕŸ _labelSearch_ Õ¯ÕžÕ³Õ¡Õ¯Õš}  
+_textTohelp_ [l=hy] {Õ©Õ¥ÖÕ©Õ«Ö ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš ÕšÕœÕ¿ ÕÖÕ Õ€Õ¡Õ·Õ¿Õ« ÕœÕ¥Õ²ÕŽÕ¥Õ¬ÕžÕŸ _labelTo_ Õ¯ÕžÕ³Õ¡Õ¯Õš}  
+_textFromhelp_ [l=hy] {Õ©Õ¥ÖÕ©Õ«Ö Õ°ÖÕ¡Õ¿Õ¡ÖÕ¡Õ¯ÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš ÕšÕœÕ¿ ÕÖÕÔ»Õ Õ€Õ¡Õ·Õ¿Õ«, ÕœÕ¥Õ²ÕŽÕ¥Õ¬ÕžÕŸ _labelFrom_ Õ¯ÕžÕ³Õ¡Õ¯Õš}  
+_textBrowsehelp_ [l=hy] {Ô¹Õ¥ÖÕ©Õ«Ö ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš}  
+_textAcronymhelp_ [l=hy] {Ô¹Õ¥ÖÕ©Õ«Ö ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš ÕšÕœÕ¿ Õ¡Õ¯ÖÕžÕ¶Õ«ÕŽÕ« Õ°Õ¡Õ¶Õ€Õ«ÕºÕŽÕ¡Õ¶ ÕœÕ¥Õ²ÕŽÕ¥Õ¬ÕžÕŸ _labelAcronym_ Õ¯ÕžÕ³Õ¡Õ¯Õš}  
+_textPhrasehelp_ [l=hy] {Õ©Õ¥ÖÕ©Õ«Ö ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©ÕžÖÕŽ Õ°Õ¡Õ¶Õ€Õ«ÕºÕžÕ² Õ¡ÖÕ¿Õ¡Õ°Õ¡ÕµÕ¿ÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš ÕœÕ¥Õ²ÕŽÕ¥Õ¬ÕžÕŸ _labelPhrase_ Õ¯ÕžÕ³Õ¡Õ¯ÕšÖÕÕ¡ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕžÖÕŽ Õ§ Õ¡ÖÕ¿Õ¡Õ°Õ¡ÕµÕ¿ÕžÖÕ©ÕµÕ¡Õ¶ Õ€Õ«Õ¿Õ¡Õ¯ÕšÖ}  
+
+_texthelptopicstitle_ [l=hy] {ÔœÕžÖÕ¡Õ£ÖÕ¥Ö}
+
+_textreadingdocs_ [l=hy] {Ô»Õ¶Õ¹ÕºÕ¥Õœ Õ¯Õ¡ÖÕ€Õ¡Õ¬ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš}
+
+_texthelpreadingdocs_ [l=hy] {<p>Ô¿Õ¡ÖÕžÕ² Õ¥Ö Õ¡ÕœÕ¥Õ¬, Õ©Õ¥ Õ¥ÖÕ¢ Õ¥Ö Õ°Õ¡ÕœÕ¥Õ¬ Õ¡Õ¶Õ°Õ¡Õ¿Õ¡Õ¯Õ¡Õ¶ Õ£ÖÖÕ« Õ¯Õ¡ÕŽ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ«,
+ÖÕ¡Õ¶ÕŠÕ« Õ€ÖÕ¡Õ¶Ö ÕŸÕ¥ÖÕ¶Õ¡Õ£Õ«ÖÕš, Õ¯Õ¡ÕŽ Õ¡ÕŒÕ¡Õ»Õ«Õ¶ Õ§Õ»Õ« Õ¶Õ¯Õ¡ÖÕš Õ¥ÖÖÕžÖÕŽ Õ¥Õ¶ Õ§Õ»Õ« ÕŸÕ¥ÖÕ«Õ¶ Õ±Õ¡Õ­
+ÕŽÕ¡ÕœÕžÖÕŽ: ÕÖÕžÕ· Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕžÖÕŽ ÕœÕ¡ ÕžÖÕ²Õ¥Õ¯ÖÕŸÕžÖÕŽ Õ§ Õ¶Õ¡Ö Õ¢ÕžÕŸÕ¡Õ¶Õ€Õ¡Õ¯ÕžÖÕ©ÕµÕ¡ÕŽÕ¢,
+ÕŽÕ«Õ¶Õ¹ ÕžÖÖÕ«Õ·Õ¶Õ¥ÖÕžÖÕŽ Õ¯Õ¡ÖÕ¥Õ¬Õ« Õ§ Õ¿Õ¥ÕœÕ¶Õ¥Õ¬ ÕšÕ¶Õ©Õ¡ÖÕ«Õ¯ Õ§Õ»Õ« Õ°Õ¡ÕŽÕ¡ÖÕš Ö Õ¡ÕŒÕ¡Õ¶Õ±Õ«Õ¶ ÕºÕ¡Õ¿ÕžÖÕ°Õ¡Õ¶, 
+ÕžÖÕ¿Õ¥Õ²Õ«Ö Õ¯Õ¡ÖÕ¥Õ¬Õ« Õ§ ÕšÕ¶Õ¿ÖÕ¥Õ¬ Õ¶ÕžÖ Õ§Õ» Ö Õ£Õ¶Õ¡Õ¬ Õ¡ÕŒÕ¡Õ» Õ¯Õ¡ÕŽ Õ°Õ¥Õ¿: Ô²ÕžÕŸÕ¡Õ¶Õ€Õ¡Õ¯ÕžÖÕ©ÕµÕžÖÕ¶ÕžÖÕŽ
+ÕšÕ¶Õ©Õ¡ÖÕ«Õ¯ ÕŽÕ¡ÕœÕ« ÕŸÕ¥ÖÕ¶Õ¡Õ£Õ«ÖÕš Õ©Õ¡ÕŸ Õ§, Ö Õ¢ÕžÕŸÕ¡Õ¶Õ€Õ¡Õ¯ÕžÖÕ©ÕµÕžÖÕ¶Õš ÕšÕ¶Õ€Õ¡ÖÕ±Õ¡Õ¯Õ¡ÕŸÕžÕ² Õ§,
+-- ÕœÕ¥Õ²ÕŽÕ¥Ö Õ©Õ²Õ©Õ¡ÕºÕ¡Õ¶Õ¡Õ¯Õ¶Õ¥ÖÕ« ÕŸÖÕ¡ Õ€ÖÕ¡Õ¶Ö Õ¢Õ¡ÖÕ¥Õ¬ÕžÖ Õ¯Õ¡ÕŽ ÖÕ¡Õ¯Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö. 
+ÕœÕ¥Õ²ÕŽÕ¥Ö Õ¢Õ¡ÖÕŸÕ¡Õ® Õ£ÖÖÕ« ÕºÕ¡Õ¿Õ¯Õ¥ÖÕ«Õ¯Õ« ÕŸÖÕ¡, Õ¡ÕµÕ¶ ÖÕ¡Õ¯Õ¥Õ¬ÕžÖ Õ¶ÕºÕ¡Õ¿Õ¡Õ¯ÕžÕŸ:</p>
+
+<p>ÕÕ¿ÕžÖÖ Õ¢Õ¥ÖÕŸÕ¡Õ® Õ§ ÕšÕ¶Õ©Õ¡ÖÕ«Õ¯ Õ¢Õ¡ÕªÕ¶Õ« Õ¢Õ¡ÖÕ¡Õ¿ÖÕžÖÕ©ÕµÕžÖÕ¶Õš: ÔµÖÕ¢ Õ¡ÕµÕ¶ Õ¯Õ¡ÖÕ€Õ¡Ö, 
+Õ¯Õ¿Õ¥ÕœÕ¶Õ¥Ö ÕœÕ¬Õ¡ÖÕ¶Õ¥Ö, Õ±Õ¥ÕŠ Õ°Õ¡Õ»ÕžÖÕ€ Õ¢Õ¡ÕªÕ«Õ¶Õ¶Õ¥Ö Õ¿Õ¡Õ¶Õ¥Õ¬ÕžÖ Õ¯Õ¡ÕŽ Õ°Õ¥Õ¿ Õ¿Õ¥Õ²Õ¡ÖÕžÕ­Õ¥Õ¬ÕžÖ 
+Õ°Õ¡ÕŽÕ¡Ö: </p>
+
+<p>ÕÕ¥ÖÕ¶Õ¡Õ£ÖÕ«Ö Õ¯Õ¡ÕŽ Õ¡ÕŒÕ¡Õ»Õ«Õ¶ Õ§Õ»Õ« Õ¶Õ¯Õ¡ÖÕ«Ö Õ¶Õ¥ÖÖÖ Õ¯Õ¡Õ¶ ÕŽÕ« ÖÕ¡Õ¶Õ« Õ¯ÕžÕ³Õ¡Õ¯Õ¶Õ¥Ö: ÕÕ¥Õ²ÕŽÕ«Ö
+<i>ÕšÕ¶Õ€Õ¬Õ¡ÕµÕ¶Õ«Ö Õ¿Õ¥ÖÕœÕ¿Õš</i> ÕšÕ¶Õ©Õ¡ÖÕ«Õ¯ Õ¢Õ¡ÕªÕ¶Õ« ÕžÕ²Õ» Õ¿Õ¥ÖÕœÕ¿Õš Õ¢Õ¡ÖÕ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö:
+ÔµÕ©Õ¥ ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš ÕšÕ¶Õ€Õ¡ÖÕ±Õ¡Õ¯ Õ§, ÕœÕ¡ Õ¯Õ¡ÖÕžÕ² Õ§ Õ¥ÖÕ¯Õ¡Ö Õ¿ÖÕ¥Õ¬ Ö Õ¯Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕŸÕ« 
+ÕŽÕ¥ÖÕ¥Õ¶Õ¡ÕµÕ¡Õ¯Õ¡Õ¶ ÕŽÕ¥Õ® Õ°Õ«Õ·ÕžÕ²ÕžÖÕ©ÕµÕžÖÕ¶: ÕÕ¥Õ²ÕŽÕ«Ö <i>ÕšÕ¶Õ€Õ¬Õ¡ÕµÕ¶Õ«Ö Õ¢ÕžÕŸÕ¡Õ¶Õ€Õ¡Õ¯ÕžÖÕ©ÕµÕžÖÕ¶Õš</i> 
+ÕžÕ²Õ» Õ¢ÕžÕŸÕ¡Õ¶Õ€Õ¡Õ¯ÕžÖÕ©ÕµÕžÖÕ¶Õš Õ¡ÕµÕ¶ÕºÕ¥Õœ ÕšÕ¶Õ€Õ¬Õ¡ÕµÕ¶Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö, ÕžÖ Õ¯Õ¡ÖÕžÕ²Õ¡Õ¶Õ¡Õœ Õ€Õ«Õ¿Õ¥Õ¬ Õ¢ÕžÕ¬ÕžÖ
+Õ£Õ¬ÕžÖÕ­Õ¶Õ¥ÖÕ« ÕŸÕ¥ÖÕ¶Õ¡Õ£ÖÕ¥ÖÕš Ö Õ¥Õ¶Õ©Õ¡Õ£Õ¬ÕžÖÕ­Õ¶Õ¥ÖÕš: ÕÕ¥Õ²ÕŽÕ«Ö <i>Õ¡ÕŒÕ¡Õ¶Õ±Õ¶Õ¡ÖÕ¶Õ¥Õ¬</i> Õ€Õ«Õ¿ÕŽÕ¡Õ¶ Õ¶ÕžÖ
+ÕºÕ¡Õ¿ÕžÖÕ°Õ¡Õ¶ Õ¢Õ¡ÖÕ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö: (ÕÕ¡ Ö
+Õ£Õ¿Õ¡Õ¯Õ¡Ö Õ§, Õ¥Õ©Õ¥ ÖÕ¡Õ¶Õ¯Õ¡Õ¶ÕžÖÕŽ Õ¥Ö Õ°Õ¡ÕŽÕ¥ÕŽÕ¡Õ¿Õ¥Õ¬ Õ«ÖÕ¡Ö Õ°Õ¥Õ¿
+ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš, Õ¯Õ¡ÕŽ ÕŽÕ«Õ¡Õ¶Õ£Õ¡ÕŽÕ«Ö Õ¯Õ¡ÖÕ€Õ¡Õ¬ Õ¥ÖÕ¯ÕžÖ ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©): ÕÕ¥ÖÕ»Õ¡ÕºÕ¥Õœ, Õ¥ÖÕ¢ Õ¯Õ¡Õ¿Õ¡ÖÕžÖÕŽ Õ¥Õœ 
+ÖÕ¶Õ¿ÖÕžÖÕŽ, ÕžÖÕžÕ¶ÕŸÕžÕ² Õ¢Õ¡ÕŒÕ¥ÖÕš Õ¶Õ¥ÖÕ¯ÕŸÕ¡Õ® Õ¥Õ¶ Õ¬Õ«Õ¶ÕžÖÕŽ: ÕÕ¥Õ²ÕŽÕ«Ö <i>Õ¹Õ¶Õ¥ÖÕ¯Õ¥Õ¬</i> ÕœÕ¡ Õ¡Õ¶Õ»Õ¡Õ¿Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö:</p>
+}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=hy] {Ô²Õ¡ÖÕ«Ö Õ¡ÕµÕœ Õ£ÖÖÕ¡Õ€Õ¡ÖÕ¡Õ¯Õš}
+_texthelpopenbook_ [l=hy] {Ô²Õ¡ÖÕ«Ö/ÖÕ¡Õ¯Õ«Ö Õ¡ÕµÕœ Õ£Õ«ÖÖÕš}
+_texthelpviewtextsection_ [l=hy] {ÔŽÕ«Õ¿Õ«Ö Õ¿Õ¥ÖÕœÕ¿Õ« Õ¡ÕµÕœ Õ¢Õ¡ÕªÕ«Õ¶Õš}
+_texthelpexpandtext_ [l=hy] {Ô±ÖÕ¿Õ¡Õ®Õ«Ö Õ¯Õ¡ÕŽ ÕžÕ¹ Õ¬ÖÕ«ÕŸ` Õ¿Õ¥ÖÕœÕ¿Õš}
+_texthelpexpandcontents_ [l=hy] {ÔžÕ¶Õ€Õ¬Õ¡ÕµÕ¶Õ«Ö Õ¯Õ¡ÕŽ ÕžÕ¹Õ Õ¢ÕžÕŸÕ¡Õ¶Õ€Õ¡Õ¯ÕžÖÕ©ÕµÕžÖÕ¶Õš}
+_texthelpdetachpage_ [l=hy] {Ô²Õ¡ÖÕ«Ö Õ¡ÕµÕœ Õ§Õ»Õš Õ¶ÕžÖ ÕºÕ¡Õ¿ÕžÖÕ°Õ¡Õ¶ÕžÖÕŽ}
+_texthelphighlight_ [l=hy] {ÕÕ¥ÖÕ¯Õ«Ö Õ¯Õ¡ÕŽ ÕžÕ¹` ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥ÖÕš}
+_texthelpsectionarrows_ [l=hy] {Ô³Õ¶Õ¡ Õ¶Õ¡Õ­ÕžÖÕ€/Õ°Õ¡Õ»ÕžÖÕ€ Õ¢Õ¡ÕªÕ«Õ¶}  
+
+
+_texthelpsearchingtitle_ [l=hy] {Ô»Õ¶Õ¹ÕºÕ¥Õœ ÕžÖÕžÕ¶Õ¥Õ¬ ÕšÕœÕ¿ ÕžÖÕžÕ·Õ¡Õ¯Õ« Õ¢Õ¡ÕŒÕ¥ÖÕ«}
+
+_texthelpsearching_ [l=hy] {<p>
+  ÕÕ¶Õ¿ÖÕŽÕ¡Õ¶ ÕºÕ¡Õ¿ÕžÖÕ°Õ¡Õ¶Õ«Ö, Õ¯Õ¡Õ¿Õ¡ÖÕ«Ö Õ°Õ¥Õ¿ÖÕµÕ¡Õ¬ ÖÕ¡ÕµÕ¬Õ¥ÖÕš:<p>
+  
+  <ol><li>ÕÖÕžÕ·Õ«Ö Õ©Õ¥ Õ«Õ¶Õ¹ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥Ö Õ¥Õœ ÕžÖÕŠÕžÖÕŽ ÖÕ¶Õ¿ÖÕ¥Õ¬
+      <li>ÕÕœÕ¿Õ¡Õ¯Õ¥ÖÖÕžÖ, ÕžÖÕŠÕžÖÕŽ Õ¥Õœ ÖÕ¶Õ¿ÖÕ¥Õ¬ ÕšÕœÕ¿ Õ¢ÕžÕ¬ÕžÖ Õ©Õ¥ ÕŽÕ«Õ¡ÕµÕ¶ ÕžÖÕžÕ· Õ¢Õ¡ÕŒÕ¥ÖÕ«:
+      <li>ÕÕžÖÕ¿Ö Õ¡ÖÕ¡ ÖÕ¶Õ¿ÖÕžÕŸÕ« Õ¢Õ¡ÕŒÕ¥ÖÕš
+      <li>ÕÕ¥Õ²ÕŽÕ«Ö <i>ÕÕ¯ÕœÕ«Ö ÖÕ¶Õ¿ÖÕžÖÕŽÕš</i> Õ¯ÕžÕ³Õ¡Õ¯Õš
+  </ol>
+
+<p> <p>ÔµÖÕ¢ Õ°Õ¡ÖÖÕžÖÕŽÕš Õ¯Õ¡Õ¿Õ¡ÖÕŸÕ¡Õ® Õ§, Õ¡ÕŒÕ¡Õ»Õ«Õ¶ ÖÕœÕ¡Õ¶ Õ°Õ¡ÕŽÕšÕ¶Õ¯Õ¶ÕžÕ² ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕ« ÕŸÕ¥ÖÕ¶Õ¡Õ£ÖÕ¥ÖÕš Õ¯Õ¡ÖÕ¿Õ¡Õ®ÕŸÕ¥Õ¶: ÕÕ¥ÖÖÖÕ« ÕŽÕ¡ÕœÕžÖÕŽ Õ¯Õ¡ Õ¯ÕžÕ³Õ¡Õ¯, ÕžÖÕš Õ¢Õ¡ÖÕžÖÕŽ Õ§ Õ°Õ¡Õ»ÕžÖÕ€ ÖÕœÕ¡Õ¶ ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš: Ô±ÕµÕœÕ¿Õ¥Õ² Õ¯Õ¡Õ¶ Õ¯ÕžÕ³Õ¡Õ¯Õ¶Õ¥Ö, ÕžÖÕžÕ¶Ö Ö
+Õ£Õ¶ÕžÖÕ©ÕµÕ¡ÕŽÕ¢ Õ¯Õ¡ÖÕžÕ² Õ¥Ö Õ¿Õ¥Õ²Õ¡Õ·Õ¡ÖÕªÕŸÕ¥Õ¬ Õ€Õ¥ÕºÕ« Õ°Õ¡Õ»ÕžÖÕ€ ÖÕœÕ¡Õ¶ Õ£ÖÕ¡ÕŒÕžÖÕŽÕš, Ö Õ¯Õ¡ÕŽ Õ°Õ¥Õ¿ ÕŸÕ¥ÖÕ¡Õ€Õ¡ÕŒÕ¶Õ¡Õ¬ Õ€Õ¥ÕºÕ« Õ¡ÕŒÕ¡Õ»Õ«Õ¶ ÖÕœÕ¡Õ¶ÕµÕ¡Õ¯Õ«Õ¶: ÔµÕŸ Õ¡ÕµÕœÕºÕ¥Õœ Õ·Õ¡ÖÕžÖÕ¶Õ¡Õ¯: ÕÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš Õ€Õ«Õ¿Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö, ÕœÕ¥Õ²ÕŽÕ«Ö ÕŸÕ¥ÖÕ¶Õ¡Õ£ÖÕ« ÕŸÖÕ¡, Õ¯Õ¡ÕŽ Õ¯ÕžÕ²ÖÕ« ÖÕžÖÖÕ«Õ¯ Õ¯ÕžÕ³Õ¡Õ¯Õš:
+
+<p>Ô±ÕŽÕ¥Õ¶Õ¡Õ·Õ¡Õ¿Õš Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖ Õ§ 100 ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ© Õ£Õ¿Õ¶Õ¥Õ¬: ÔµÕ©Õ¥ Õ¡ÕµÕœ Õ©Õ«ÕŸÕš ÖÕ¡Õ¶Õ¯Õ¡Õ¶ÕžÖÕŽ Õ¥Ö ÖÕžÕ­Õ¥Õ¬, Õ¡ÕºÕ¡ ÕœÕ¥Õ²ÕŽÕ¥Ö
+  <i>Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö</i> Õ¯ÕžÕ³Õ¡Õ¯Õš, ÕžÖÕš Õ£Õ¿Õ¶ÕŸÕžÖÕŽ Õ§ Õ§Õ»Õ« ÕŸÕ¥ÖÖÕžÖÕŽ:<p>
+}
+
+_texthelpquerytermstitle_ [l=hy] {ÕÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥Ö}
+_texthelpqueryterms_ [l=hy] {<p>Ô»Õ¶Õ¹ Õ§Õ¬ ÕŽÕžÖÕ¿Ö Õ¡Õ¶Õ¥Ö Õ°Õ¡ÖÖÕŽÕ¡Õ¶ ÕºÕ¡Õ¿ÕžÖÕ°Õ¡Õ¶ÕžÖÕŽ, Õ€ÖÕ¡Õ¶Ö Õ¯Õ¶Õ¥ÖÕ¯Õ¡ÕµÕ¡ÖÕŸÕ¥Õ¶ Õ¢Õ¡ÕŒÕ¥ÖÕ« ÖÕžÖÖÕ¡Õ¯Õ« Õ¿Õ¥ÕœÖÕžÕŸ, ÕžÖÕžÕ¶Ö Õ¯ÕžÕ¹ÕŸÕžÖÕŽ Õ¥Õ¶ âÖÕ¶ÖÕŽÕ¡Õ¶ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥Öâ: Ô±ÕŽÕ¥Õ¶ Õ¿Õ¥ÖÕŽÕ«Õ¶ Õ¯Õ¡ÕŠÕŽÕŸÕ¡Õ® Õ§ Õ¡ÕµÕ¢Õ¢Õ¥Õ¶Õ¡Õ¯Õ¡Õ¶ Ö Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ¶Õ«Õ·Õ¥ÖÕ«Ö: ÕÕ¥ÖÕŽÕ«Õ¶Õ¶Õ¥ÖÕš Õ¢Õ¡ÕªÕ¡Õ¶ÕŸÕ¡Õ® Õ¥Õ¶ Õ«ÖÕ¡ÖÕ«Ö Õ¢Õ¡ÖÕ¡Õ¿Õ¶Õ¥ÖÕžÕŸ: Õ¥Õ©Õ¥ Õ¡ÕŒÕ¯Õ¡ Õ§ ÕžÖÖÕ§ Õ¯Õ¥Õ¿Õ¡Õ€ÖÕ¡Õ¯Õ¡Õ¶ Õ¶Õ·Õ¡Õ¶, Õ¡ÕºÕ¡ ÕœÖÕ¡Õ¶Ö Õ®Õ¡ÕŒÕ¡ÕµÕžÖÕŽ Õ¥Õ¶ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥ÖÕš Õ«ÖÕ¡ÖÕ«Ö Õ¡Õ¶Õ»Õ¡Õ¿Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö, Õ¡ÕµÕœÕ«Õ¶ÖÕ¶ Õ¯Õ¡Õ¿Õ¡ÖÕžÖÕŽ Õ¥Õ¶ Õ¢Õ¡ÖÕ¡Õ¿Õ« Õ€Õ¥Ö: ÔµÕŸ ÕœÖÕ¡Õ¶Ö Õ¡Õ¶Õ¿Õ¥ÕœÕŸÕžÖÕŽ Õ¥Õ¶: ÕÕ¶Õ¡ÖÕ¡ÕŸÕžÖ Õ¹Õ§ ÖÕ¶Õ¿ÖÕ¥Õ¬ ÕšÕœÕ¿ Õ¢Õ¡ÕŒÕ¥ÖÕ«, ÕžÖÕžÕ¶Ö ÕšÕ¶Õ€Õ£ÖÕ¯ÕžÖÕŽ Õ¥Õ¶ Õ¯Õ¥Õ¿Õ¡Õ€ÖÕ¡Õ¯Õ¡Õ¶ Õ¶Õ·Õ¡Õ¶Õ¶Õ¥Ö:
+
+<p>ÕÖÕ«Õ¶Õ¡Õ¯, Õ°Õ¥Õ¿ÖÕµÕ¡Õ¬ Õ°Õ¡ÖÖÕžÖÕŽÕš<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>Õ¯Õ¬Õ«Õ¶Õ« Õ¶ÕžÖÕµÕ¶Õš, Õ«Õ¶Õ¹<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}
+
+_texthelpmgppsearching_ [l=hy] {MGPP Ö
+Õ£Õ¶ÕžÖÕ©ÕµÕ¡ÕŽÕ¢ ÕœÕ¿Õ¥Õ²Õ®ÕŸÕ¡Õ® Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕ« Õ°Õ¡ÕŽÕ¡Ö ÖÕœ ÕŽÕ« ÖÕ¡Õ¶Õ« ÕšÕ¶Õ¿ÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö Õ¥Õ¶ Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖÖ
+
+<ul>
+<li>ÕÕ«Õ· <b>*</b> Õ°Õ¡ÖÖÕŽÕ¡Õ¶ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ« ÕŸÕ¥ÖÕ»ÕžÖÕŽ Õ£Õ¿Õ¶ÕžÖÕŽ Õ§ Õ¢ÕžÕ¬ÕžÖ Õ¡ÕµÕ¶ Õ¢Õ¡ÕŒÕ¥ÖÕš ÕžÖÕžÕ¶Ö <b>ÕœÕ¯ÕœÕŸÕžÖÕŽ Õ¥Õ¶</b> Õ¡ÕµÕ€ Õ¢Õ¡ÕŒÕžÕŸ, Õ¡ÕµÕœÕ«Õ¶ÖÕ¶Õ <b>Õ°Õ¡Õ·ÕŸ*</b> Õ¯Õ°Õ¡ÕŽÕ¡ÕºÕ¡Õ¿Õ¡ÕœÕ­Õ¡Õ¶Õ¥Õ¶ Õ¢ÕžÕ¬ÕžÖ Õ¢Õ¡ÕŒÕ¥ÖÕš ÕžÖÕžÕ¶Ö ÕœÕ¯ÕœÕŸÕžÖÕŽ Õ¥Õ¶ <b>Õ°Õ¡Õ·ÕŸ</b> Õ¢Õ¡ÕŒÕžÕŸÖ
+<li><b>/x</b> Õ¯Õ¡ÖÕ¥Õ¬Õ« Õ§ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬, Õ°Õ¡ÖÖÕŽÕ¡Õ¶ ÕŽÕ¥Õ¯ Õ¯Õ¡ÕŽ ÕŽÕ« ÖÕ¡Õ¶Õ« Õ¢Õ¡ÕŒÕ¥ÖÕ« Õ¡ÕŸÕ¥Õ¬Õ« Õ¢Õ¡ÖÕ±Ö ÖÕ¡Õ· Õ¿Õ¡Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö, Ö
+ÖÕ«Õ¶Õ¡Õ¯ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕ«Õ¶ ÖÕ¡Õ·Õ¥Ö Õ¿Õ¡Õ¬ÕžÖÖ <b>Õ°Õ¡ÕŽÕ¡Õ¯Õ¡ÖÕ£Õ«Õ¹/10 Õ£Õ«Õ¿ÕžÖÕ©ÕµÕžÖÕ¶</b> Õ°Õ¡ÖÖÕžÖÕŽÕš Õ°Õ¡ÕŽÕ¡Õ¯Õ¡ÖÕ£Õ«Õ¹ Õ¢Õ¡ÕŒÕ«Õ¶ 10 Õ¡Õ¶Õ£Õ¡ÕŽ Õ¡ÕŸÕ¥Õ¬Õ« ÖÕ¡Õ· Õ§ Õ¿Õ¡Õ¬Õ«Õœ ÖÕ¡Õ¶ Õ©Õ¥ Õ£Õ«Õ¿ÕžÖÕ©ÕµÕžÖÕ¶ Õ¢Õ¡ÕŒÕ«Õ¶Ö
+</ul>
+}  
+
+_texthelplucenesearching_ [l=hy] {Lucene Ö
+Õ£Õ¶ÕžÖÕ©ÕµÕ¡ÕŽÕ¢ ÕºÕ¡Õ¿ÖÕ¡ÕœÕ¿ÕŸÕ¡Õ® Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕ« Õ°Õ¡ÕŽÕ¡Ö ÕŽÕ« ÖÕ¡Õ¶Õ« Õ¡ÕµÕ¬ ÕšÕ¶Õ¿ÖÕ¡Õ¶ÖÕ¶Õ¥Ö Õ¥Õ¶ ÕŽÕ¡Õ¿Õ¹Õ¥Õ¬Õ«Ö 
+
+<ul>
+<li><b>?</b> Õ¯Õ¡ÖÕžÕ² Õ§ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕŸÕ¥Õ¬ ÕžÖÕºÕ¥Õœ Õ­ÕŽÕ¢Õ¡ÕµÕ«Õ¶ Õ¶Õ«Õ· ÕžÖÖÕ§ ÕŽÕ¥Õ¯ Õ¶Õ«Õ·Õ« Õ¿Õ¥Õ²ÕžÖÕŽÖ ÕÖÕ«Õ¶Õ¡Õ¯Õ <b>b?t</b> Õ¯Õ£Õ¿Õ¶Õ«  <b>bet</b>, <b>bit</b> Ö <b>bat</b> Ö Õ¡ÕµÕ¬Õ¶Ö
+<li><b>*</b> Õ¯Õ¡ÖÕžÕ² Õ§ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕŸÕ¥Õ¬ ÕžÖÕºÕ¥Õœ Õ­ÕŽÕ¢Õ¡ÕµÕ«Õ¶ Õ¶Õ«Õ· ÕŽÕ« ÖÕ¡Õ¶Õ« Õ¿Õ¡ÕŒÕ¥ÖÕ« ÖÕžÕ­Õ¡ÖÕ¥Õ¶Ö ÕÖÕ«Õ¶Õ¡Õ¯Õ  <b>comput*</b> Õ°Õ¡ÕŽÕ¡ÕºÕ¡Õ¿Õ¡ÕœÕ­Õ¡Õ¶ÕžÖÕŽ Õ¥Õ¶ Õ¢ÕžÕ¬ÕžÖ Õ¡ÕµÕ¶ Õ¢Õ¡ÕŒÕ¥ÖÕš, ÕžÖÕžÕ¶Ö ÕœÕ¯ÕœÕŸÕžÖÕŽ Õ¥Õ¶ <b>comput</b>.
+</ul>
+Ô±ÕµÕœ Õ¥ÖÕ¯ÕžÖ Õ­ÕŽÕ¢Õ¡ÕµÕ«Õ¶ Õ¶Õ«Õ·Õ¥ÖÕš Õ¯Õ¡ÕºÕžÕ² Õ¥Õ¶ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕŸÕ¥Õ¬ Õ¡ÖÕ¿Õ¡Õ°Õ¡ÕµÕ¿ÕžÖÕ©ÕµÕ¡Õ¶ ÕŽÕ¥Õ»Õ¿Õ¥Õ²ÕžÖÕŽ Õ¯Õ¡ÕŽ ÕŸÕ¥ÖÕ»ÕžÖÕŽÖÕÕ¥Õ¶ Õ¯Õ¡ÖÕžÕ² Õ¬Õ«Õ¶Õ¥Õ¬ Õ¡ÖÕ¿Õ¡Õ°Õ¡ÕµÕ¿ÕžÖÕ©ÕµÕ¡Õ¶ ÕœÕ¯ÕŠÕ¢ÕžÖÕŽÖ}  
+
+_texthelpquerytypetitle_ [l=hy] {ÕÕ¡ÖÖÕŽÕ¡Õ¶ Õ¿Õ¥ÕœÕ¡Õ¯}
+_texthelpquerytype_ [l=hy] {<p>Ô¿Õ¡Õ¶ Õ¥ÖÕ¯ÕžÖ Õ¿Õ¡ÖÕ¢Õ¥Ö Õ¿Õ¥ÕœÕ¡Õ¯Õ« Õ°Õ¡ÖÖÕžÖÕŽÕ¶Õ¥Ö.
+
+<ul>
+  <li>ÕÕ¡ÖÖÕžÖÕŽÕ¶Õ¥Ö <b>Õ¢ÕžÕ¬ÕžÖ</b> Õ¢Õ¡ÕŒÕ¥ÖÕ« Õ°Õ¡ÕŽÕ¡Ö: Ô±ÕµÕœ Õ€Õ¥ÕºÖÕžÖÕŽ ÖÕ¶Õ¿ÖÕŸÕžÖÕŽ Õ¥Õ¶ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš, (Õ¯Õ¡ÕŽ
+      Õ£Õ¬ÕžÖÕ­Õ¶Õ¥ÖÕš, Õ¯Õ¡ÕŽ ÕŸÕ¥ÖÕ¶Õ¡Õ£ÖÕ¥ÖÕš) ÕžÖÕžÕ¶Ö ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ¥Õ¶ Õ±Õ¥Ö Õ¯ÕžÕ²ÕŽÕ«Ö Õ¶Õ·ÕŸÕ¡Õ® Õ¢ÕžÕ¬ÕžÖ Õ¢Õ¡ÕŒÕ¥ÖÕš:
+      Ô±ÕµÕ¶ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš, ÕžÖÕžÕ¶Ö Õ¢Õ¡ÕŸÕ¡ÖÕ¡ÖÕžÖÕŽ Õ¥Õ¶ Õ°Õ¡ÖÖÕŽÕ¡Õ¶Õš, Õ¡ÖÕ¿Õ¡Õ®ÕŸÕžÖÕŽ Õ¥Õ¶ Õ¿Õ¥ÕœÕ¡Õ¯Õ¡ÕŸÕžÖÕŸÕ¡Õ® ÕšÕœÕ¿   
+      Õ¡ÕµÕ¢Õ¢Õ¥Õ¶Õ¡Õ¯Õ¡Õ¶ 
+      Õ¯Õ¡ÖÕ£Õ«.<p>
+
+  <li>ÕÕ¡ÖÖÕžÖÕŽÕ¶Õ¥Ö <b>ÕžÖÕžÕ·</b> Õ¢Õ¡ÕŒÕ¥ÖÕ« Õ°Õ¡ÕŽÕ¡Ö: ÕÕ¡ÖÕŠÕ¡ÕºÕ¥Õœ Õ¶Õ·Õ¥Ö ÕŽÕ« ÖÕ¡Õ¶Õ« Õ¿Õ¥ÖÕŽÕ«Õ¶, ÕžÖ ÕžÖÕŠÕžÖÕŽ Õ¥Ö 
+      Õ£Õ¿Õ¶Õ¥Õ¬ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕžÖÕŽ:  
+      Ô¿Õ¡ÖÕ¿Õ¡Õ®ÕŸÕ¥Õ¶ Õ¡ÕµÕ¶ Õ°Õ¡Õ»ÕžÖÕ€Õ¡Õ¯Õ¡Õ¶ÕžÖÕ©ÕµÕ¡ÕŽÕ¢, Õ©Õ¥ Õ«Õ¶Õ¹ÖÕ¡Õ¶ ÕŽÕžÕ¿ Õ¥Õ¶ Õ¡ÕµÕ€ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥ÖÕš Õ°Õ¡ÖÖÕŽÕ¡Õ¶Õš: ÔµÖÕ¢ 
+      ÕžÖÕžÕ·ÕŸÕžÖÕŽ Õ§
+
+      ÕŽÕžÕ¿Õ«Õ¯ÕžÖÕ©ÕµÕ¡Õ¶ Õ¹Õ¡ÖÕš,
+
+      <p><ul>
+        <li> ÕžÖÖÕ¡Õ¶ Õ·Õ¡Õ¿ ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥Ö Õ¯Õ¡Õ¶ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©ÕžÕšÕŽ, Õ¡ÕµÕ¶ÖÕ¶Õ¡ ÕŽÕ¥Õ® Õ§ Õ°Õ¡ÕŽÕšÕ¶Õ¯Õ¶Õ¥Õ¬Õ«ÕžÖÕ©ÕµÕžÖÕ¶Õš
+        <li> Õ°Õ¡ÕŠÕŸÕ¡Õ€Õ¥Õº Õ°Õ¡Õ¶Õ€Õ«ÕºÕžÕ² Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥ÖÕš Õ¡ÕŸÕ¥Õ¬Õ« Õ¯Õ¡ÖÖÕžÖ Õ¥Õ¶, ÖÕ¡Õ¶ Õ©Õ¥ Õ°Õ¡Õ³Õ¡Õ­ ÕºÕ¡Õ¿Õ¡Õ°ÕžÕ²Õ¶Õ¥ÖÕš
+        <li> Õ¯Õ¡ÖÕ³ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš Õ¡ÕŸÕ¥Õ¬Õ« Õ¬Õ¡ÕŸÕ¶ Õ¥Õ¶ ÖÕ¡Õ¶ Õ©Õ¥ Õ¥ÖÕ¯Õ¡ÖÕ¶Õ¥ÖÕš:
+      </ul>
+</ul>
+
+<p>ÕÕ£Õ¿Õ¡Õ£ÕžÖÕ®Õ«Ö Õ¡ÕµÕ¶ÖÕ¡Õ¶ ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥Ö, ÕžÖÖÕ¡Õ¶ ÕžÖ ÕžÖÕŠÕžÖÕŽ Õ¥Õœ. Õ¡ÕŽÕ¢ÕžÕ²Õ»Õ¡Õ¯Õ¡Õ¶ 
+Õ¶Õ¡Õ­Õ¡Õ€Õ¡ÕœÕžÖÕ©ÕµÕžÖÕ¶ Õ¯Õ¡ÕŽ Õ§Õ¬ Õ¬ÖÕ«ÕŸ ÕºÕ¡ÖÕ¡Õ£ÖÕ¡Ö: Õ¥Õ©Õ¥ Õ¶Õ·Õ¥Ö ÕŽÕ«Õ¡ÕµÕ¶ ÕŽÕ¥Õ¯ Õ¿Õ¥ÖÕŽÕ«Õ¶, ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš
+Õ¯Õ€Õ¡ÕœÕ¡Õ¯Õ¡ÖÕ£ÕŸÕ¥Õ¶ ÕšÕœÕ¿ Õ€ÖÕ¡ Õ°Õ¡Õ¶Õ€Õ«ÕºÕŽÕ¡Õ¶ Õ°Õ¡Õ³Õ¡Õ­Õ¡Õ¯Õ¡Õ¶ÕžÖÕ©ÕµÕ¡Õ¶: <p>
+}
+
+_texthelpadvancedsearchtitle_ [l=hy] {ÔœÕžÖÕ¡ÖÕŸÕ¡Õ® ÖÕ¶Õ¿ÖÕžÖÕŽ}  
+
+_texthelpadvancedsearch_ [l=hy] {<p>ÔµÕ©Õ¥ ÕšÕ¶Õ¿ÖÕ¥Õ¬ Õ¥Õœ Õ­ÕžÖÕ¡ÖÕŸÕ¡Õ® Õ°Õ¡ÖÖÕŽÕ¡Õ¶ Õ¿Õ¥ÕœÕ¡Õ¯Õš(Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕžÖÕŽ) Õ¡ÕºÕ¡ ÕžÖÕ¶Õ¥Õœ ÕŽÕ« ÖÕžÖÖ Õ¡ÕµÕ¬ ÕžÖÕžÕ¶ÕŽÕ¡Õ¶ Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÖ _selectadvancedsearch_
+}  
+
+_texthelpadvsearchmg_ [l=hy] {ÔœÕžÖÕ¡ÖÕŸÕ¡Õ® ÖÕ¶Õ¿ÖÕžÖÕŽÕš MG Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕžÖÕŽ Õ¿Õ¡Õ¬Õ«Õœ Õ§ Õ¥ÖÕ¯ÕžÖ Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õ ÕšÕœÕ¿ ÖÕ¡Õ·Õ¥ÖÕ« Ö Õ¢ÕžÖÕ¬ÕµÕ¡Õ¶Ö
+ÔžÕœÕ¿ <b>ÖÕ¡Õ·Õ¥ÖÕ«</b> ÕžÖÕžÕ¶ÕžÖÕŽÕš Õ³Õ·Õ£ÖÕ¿ÕžÖÕ¥Õ¶ Õ¶ÕžÖÕµÕ¶Õ¶ Õ§ Õ«Õ¶Õ¹ <b>Õ¡ÕµÕ¶</b> ÕžÖÕžÕ¶ÕžÖÕŽÕš ÕžÖÕš Õ¶Õ¯Õ¡ÖÕ¡Õ£ÖÕŸÕ¡Õ® Õ§  <a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_
+}  
+
+_texthelpbooleansearch_ [l=hy] {<b>Ô²ÕžÖÕ¬ÕµÕ¡Õ¶</b> ÕžÖÕžÕ¶ÕžÖÕŽÕš Õ©ÕžÖÕµÕ¬ Õ§ Õ¿Õ¡Õ¬Õ«Õœ ÕŽÕ«Õ¡ÕŸÕžÖÕ¥Õ¬ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥ÖÕš Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬ÕžÕŸ & ("ÔµÕ"), | ("Ô¿Ô±Õ"), Ö ! ("ÕÕ"), Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬ÕžÕŸ ÖÕ¡Õ¯Õ¡Õ£Õ®Õ¥ÖÕ Õ¥Õ©Õ¥ Õ­ÕŽÕ¢Õ¡ÕŸÕžÖÕŽÕ¡Õ¶ ÕºÕ¡Õ°Õ¡Õ¶Õ» Õ¯Õ¡ÖÔŒÕŒÕ¡Õ¯ÕµÕ¡Ö Õ£ÕžÖÕ®ÕžÕ²ÕžÖÕ©ÕµÕžÖÕ¶Õ¶ Õ§ | ("Ô¿Ô±Õ")Ö
+<p>
+ÕÖÕ«Õ¶Õ¡Õ¯, <b>snail & farming</b> Õ¯Õ£Õ¿Õ¶Õ« ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥Ö, ÕžÖÕžÕ¶Ö ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ¥Õ¶ Õ¥ÖÕ¯ÕžÖ Õ¢Õ¡ÕŒÕ¶ Õ§Õ¬Õ <b>snail</b> ÔµÕ <b>farming</b>, Õ«ÕœÕ¯ <b>snail | farming</b> Õ¯Õ£Õ¿Õ¶Õ« ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥Ö, ÕžÖÕžÕ¶Ö ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ¥Õ¶ Õ¯Õ¡ÕŽ <b>snail</b> Ô¿Ô±Õ <b>farming</b>.
+<b>snail !farming</b> Õ¯Õ£Õ¿Õ¶Õ« ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥Ö, ÕžÖÕžÕ¶Ö ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ¥Õ¶ <b>snail</b> ÔµÕ ÕÔµÕ ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ <b>farming</b>.
+<p>
+Ô±ÕŒÕ¡ÕŸÕ¥Õ¬ Õ³Õ·Õ£ÖÕ«Õ¿ Õ°Õ¡ÖÖÕžÖÕŽÕ¶Õ¥Ö Õ¯Õ¡ÖÕ¥Õ¬Õ« Õ§ Õ±ÖÕ¡ÕŸÕžÖÕ¥Õ¬ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬ÕžÕŸ Õ£ÕžÖÕ®ÕžÕ²ÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕ« Ö ÖÕ¡Õ¯Õ¡Õ£Õ®Õ¥ÖÕ« Õ°Õ¡ÕŽÕ¡Õ€ÖÕžÖÕ©ÕµÕžÖÕ¶ÕšÖÕÖÕ«Õ¶Õ¡Õ¯, <b>(sheep | cattle) & (farm | station)</b>, Õ¯Õ¡ÕŽ <b>sheep | cattle | goat !pig</b>.
+}  
+
+_texthelpadvsearchmgpp_ [l=hy] {ÔœÕžÖÕ¡ÖÕŸÕ¡Õ® ÖÕ¶Õ¿ÖÕžÖÕŽÕ¶Õ¥ÖÕš MGPP Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕžÖÕŽ ÕºÕ¡Õ°Õ¡Õ¶Õ»ÕžÖÕŽ Õ¥Õ¶ Ô²ÕžÖÕ¬ÕµÕ¡Õ¶ Ö
+ÕºÕ¥ÖÕ¡Õ¿ÕžÖÕ¶Õ¥ÖÕ« Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕžÖÕŽÖ_texthelpbooleansearch_
+<p>Ô±ÖÕ€ÕµÕžÖÕ¶ÖÕ¶Õ¥ÖÕš Õ¯Õ¡ÖÕžÕ² Õ¥Õ¶ Õ¡ÖÕ¿Õ¡Õ®ÕŸÕ¥Õ¬ <b>ÕšÕœÕ¿ ÖÕ¡Õ·Õ¥ÖÕ«ranked</b> Õ°Õ¥ÖÕ©Õ¡Õ¯Õ¡Õ¶ÕžÖÕ©ÕµÕ¡Õ¶, Õ«Õ¶Õ¹ÕºÕ¥Õœ Õ¶Õ¯Õ¡ÖÕ¡Õ£ÖÕŸÕ¡Õ® Õ§ <b>ÕžÖÕžÕ·</b> ÕžÖÕžÕ¶ÕžÖÕŽÕ¶Õ¥ÖÕ« Õ°Õ¡ÕŽÕ¡Ö Õ±Õ¥ÕŒÕ¶Õ¡ÖÕ¯ÕžÖÕŽ <a href="\#query-type">_texthelpquerytypetitle_</a>, Õ¯Õ¡ÕŽ ÕšÕœÕ¿ "Õ¯Õ¡ÕŒÕžÖÖÕŽÕ¡Õ¶" Õ°Õ¥ÖÕ©Õ¡Õ¯Õ¡Õ¶ÕžÖÕ©ÕµÕ¡Õ¶Ö ÕÕ¡ Õ¡ÕµÕ¶ Õ°Õ¥ÖÕ©Õ¡Õ¯Õ¡Õ¶ÕžÖÕ©ÕµÕžÖÕ¶Õ¶ Õ§, ÕšÕœÕ¿ ÕžÖÕ« ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš Õ€Õ¡ÕœÕ¡ÕŸÕžÖÕŸÕ¥Õ¬ Õ¥Õ¶ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« ÕœÕ¿Õ¥Õ²Õ®ÕŽÕ¡Õ¶ ÕªÕ¡ÕŽÕ¡Õ¶Õ¡Õ¯Ö 
+<p>
+ÕÕ¥Õ¿Õ¡Õ£Õ¡ Õ£ÕžÖÕ®ÕžÕ²ÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš Õ¶Õ¥ÖÕ¡ÕŒÕžÖÕŽ Õ¥Õ¶ <b>NEARx</b> and <b>WITHINx</b>.
+NEARx Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕŸÕžÖÕŽ Õ§ ÕœÕ¡Õ°ÕŽÕ¡Õ¶Õ¥Õ¬ÕžÖ ÕŽÕ¥Õ®Õ¡Õ£ÕžÖÕµÕ¶ Õ°Õ¥ÕŒÕ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õš (x Õ¢Õ¡ÕŒÕ¥Ö) ÕžÖÕžÕŸ Õ¥ÖÕ¯ÕžÖ Õ°Õ¡ÖÖÕžÖÕŽÕ¶Õ¥ÖÕ« Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥ÖÕš ÕºÕ¥Õ¿Ö Õ§ Õ£Õ¿Õ¶ÕŸÕ¥Õ¶ Õ«ÖÕ¡ÖÕ«Ö Õ°Õ¥ÕŒÕžÖÖ
+WITHINx ÕœÕ¡Õ°ÕŽÕ¡Õ¶ÕžÖÕŽ Õ§ ÕžÖ Õ¥ÖÕ¯ÖÕžÖÕ€ Õ¿Õ¥ÖÕŽÕ«Õ¶Õš ÕºÕ¥Õ¿Ö Õ§ Õ°Õ¡Õ¶Õ€Õ«ÕºÕ« Õ¡ÕŒÕ¡Õ»Õ«Õ¶ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ«Ö x Õ¢Õ¡ÕŒ Õ°Õ¥Õ¿ÕžÖÕÕ¡ Õ¶ÕŽÕ¡Õ¶ Õ§ NEAR Õ¢Õ¡ÕµÖ Õ°Õ¡Õ»ÕžÖÕ€Õ¡Õ¯Õ¡Õ¶ÕžÖÕ©ÕµÕžÖÕ¶Õš Õ¯Õ¡ÖÖÕžÖ Õ§Ö ÔŒÕŒÕ¡Õ¯ÕµÕ¡Ö Õ°Õ¥ÕŒÕ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õš 20 Õ§Ö
+}  
+
+_texthelpadvsearchlucene_ [l=hy] {ÔœÕžÖÕ¡ÖÕŸÕ¡Õ® ÖÕ¶Õ¿ÖÕžÖÕŽÕ¶Õ¥ÖÕš Lucene Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕžÖÕŽ Õ¥Õ¶ Õ¢ÕžÖÕ¬ÕµÕ¡Õ¶ Õ£ÕžÖÕ®ÕžÕ²ÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÖ _texthelpbooleansearch_
+}  
+_textdatesearch_ [l=hy] {ÕÖÕžÕ¶ÕžÖÕŽ ÕšÕœÕ¿ Ô±ÕŽÕœÕ¡Õ©ÕŸÕ¥ÖÕ«}
+
+_texthelpdatesearch_ [l=hy] {ÕÕ¶Õ¿ÖÕžÖÕŽÕš ÕšÕœÕ¿ Õ¿Õ¡ÖÕ¥Õ©ÕŸÕ¥ÖÕ« Õ©ÕžÖÕµÕ¬ Õ§ Õ¿Õ¡Õ¬Õ«Õœ Õ£Õ¿Õ¶Õ¥Õ¬ Õ¡ÕµÕ¶ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš, ÕžÖÕžÕ¶Ö 
+Õ£Õ¿Õ¶ÕŸÕžÖÕŽ Õ¥Õ¶ ÕºÕ¡Õ°Õ¡Õ¶Õ»ÕŸÕžÕ² ÕªÕ¡ÕŽÕ¡Õ¶Õ¡Õ¯Õ¡Õ°Õ¡Õ¿ÕŸÕ¡Õ®ÕžÖÕŽ: Ô¿Õ¡ÖÕžÕ² Õ¥Õœ ÖÕ¶Õ¿ÖÕ¥Õ¬  
+ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš,  ÕšÕœÕ¿ ÕžÖÕžÕ·Õ¡Õ¯Õ« Õ¿Õ¡ÖÕŸÕ¡ Õ¯Õ¡ÕŽ ÕªÕ¡ÕŽÕ¡Õ¶Õ¡Õ¯Õ¡Õ°Õ¡Õ¿ÕŸÕ¡Õ®Õ«: ÕÕ¯Õ¡Õ¿Õ« 
+ÕžÖÕ¶Õ¥ÖÕ¥Ö, ÕžÖ Õ¢Õ¡ÖÕ« Õ¿Õ¡ÖÕ¥Õ©ÕŸÕ«Ö, ÕžÖÕžÕ¶ÕŽÕ¡Õ¶ Õ¡ÕµÕ¬ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥Ö Õ¹Õ¥Ö Õ¯Õ¡ÖÕžÕ² Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬: 
+Ô²Õ¡ÖÕ« Õ¡ÕµÕ€, Õ¥Õ©Õ¥ ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ°Õ¡ÕŽÕ¡Ö ÕžÕ¹ ÕŽÕ« Õ¡ÕŽÕœÕ¡Õ©Õ«ÕŸ ÕŽÕžÖÕ¿Ö Õ¹Õ¥Ö Õ¡ÖÕ¥Õ¬, Õ¡ÕºÕ¡  ÕœÕ¡
+Õ°Õ¡ÕŽÕ¡ÖÕªÕ¥Ö Õ§ ÕžÖ ÖÕ¶Õ¿ÖÕžÖÕŽ Õ¹Õ« Õ«ÖÕ¡Õ¯Õ¡Õ¶Õ¡ÖÕŸÕ«: <p>
+}
+
+_texthelpdatehowtotitle_ [l=hy] {Ô»Õ¶Õ¹ÕºÕ¥Õœ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬ Õ¡ÕµÕœ Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õš:}
+_texthelpdatehowto_ [l=hy] {<ul>
+   <li>ÕÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕ« ÕžÖÕžÕ¶ÕžÖÕŽ ÕšÕœÕ¿ ÕŽÕ¥Õ¯ Õ¿Õ¡ÖÕŸÕ¡ Õ¯Õ¿ÖÕŸÕ¡Õ®ÖÕ«:<p>
+   <ul>
+       <li>ÕÕžÖÕ¿Ö Õ¡ÖÕ¡ ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ¡ÖÕ¿Õ¡Õ°Õ¡ÕµÕ¿ÕžÖÕ©ÕµÕžÖÕ¶Õš:
+       <li>ÕÕžÖÕ¿Ö Õ¡ÖÕ¡ ÕºÕ¡Õ°Õ¡Õ¶Õ»ÕŸÕžÕ² Õ¿Õ¡ÖÕ¥Õ©Õ«ÕŸÕš  "ÕÕ¯ÕŠÕ¢Õ« (Õ¯Õ¡ÕŽ ÕŽÕ«Õ¡Õ¯) Õ¡ÕŽÕœÕ¡Õ©Õ«ÕŸ" Õ€Õ¡Õ·Õ¿ÕžÖÕŽ:
+       <li>ÔµÕ©Õ¥ Õ¿Õ¡ÖÕ¥Õ©Õ«ÕŸÕš ÕŽÕ«Õ¶Õ¹ ÕšÕ¶Õ©Õ¡ÖÕ«Õ¯ ÕªÕ¡ÕŽÕ¡Õ¶Õ¡Õ¯Õ¡Õ·ÖÕ»Õ¡Õ¶Õ¶ Õ§, (Õ¯ÕžÕ¹ÕŸÕžÖÕŽ Õ§ Õ¶Õ¡Ö ÕŽÕ«Õ¶Õ¹ 
+           ÕÖÕ«ÕœÕ¿ÕžÕœÕš), Õ¢Õ¡ÖÕŸÕžÕ² ÕšÕ¶Õ¿ÖÕ¡ÖÕ¡Õ¶Õ¯Õ«Ö ÕšÕ¶Õ¿ÖÕ«Ö "B.C.E" 
+           Õ¡ÕŒÕ¡Õ»Õ¡ÖÕ¯Õš:
+       <li>ÕÕ¯ÕœÕ«Ö ÕžÖÕžÕ¶ÕžÖÕŽÕš:
+   </ul>
+<p><li>ÕÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕ« ÕžÖÕžÕ¶ÕžÖÕŽ ÕšÕœÕ¿ ÕžÖÕžÕ·Õ¡Õ¯Õ« ÕªÕ¡ÕŽÕ¡Õ¶Õ¡Õ¯Õ¡Õ°Õ¡Õ¿ÕŸÕ¡Õ®Õ«:<p>
+   <ul>
+       <li>ÕÕžÖÕ¿Ö Õ¡ÖÕ¡ ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥ÖÕš, Õ«Õ¶Õ¹ÕºÕ¥Õœ Õ¯Õ¡ÖÕ£Õ¶ Õ§.
+       <li>ÕÕžÖÕ¿Ö Õ¡ÖÕ¡ ÕœÕ¯ÕŠÕ¢Õ¶Õ¡Õ¯Õ¡Õ¶ Õ¿Õ¡ÖÕ¥Õ©Õ«ÕŸÕš "ÕÕ¯ÕŠÕ¢Õ« (Õ¯Õ¡ÕŽ ÕŽÕ«Õ¡Õ¯) Õ¡ÕŽÕœÕ¡Õ©Õ«ÕŸ" Õ€Õ¡Õ·Õ¿ÕžÖÕŽ.
+       <li>ÕÕžÖÕ¿Ö Õ¡ÖÕ¡ ÕŸÕ¥ÖÕ»Õ« Õ¿Õ¡ÖÕ¥Õ©Õ«ÕŸÕš " Ô±ÕŽÕœÕ¡Õ©ÕŸÕ« ÕŸÕ¥ÖÕ»: " Õ€Õ¡Õ·Õ¿ÕžÖÕŽ.
+       <li>ÔžÕ¶Õ¿ÖÕ«Ö "B.C.E" Õ¡ÕŒÕ¡Õ»Õ¡ÖÕ¯Õš Õ¢Õ¡ÖÕŸÕžÕ² ÕšÕ¶Õ¿ÖÕ¡ÖÕ¡Õ¶Õ¯Õ«Ö 
+           (ÕœÕ¡ Õ°Õ¡ÕµÕ¿Õ¶Õ« Õ§ Õ¶Õ¡Ö ÕŽÕ«Õ¶Õ¹ ÕÖÕ«ÕœÕ¿ÕžÕœÕš):
+       <li>ÕÕ¯ÕœÕ«Ö ÕžÖÕžÕ¶ÕžÖÕŽÕš:
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=hy] {Ô»Õ¶Õ¹Õ¥Õœ Õ§ Õ¡Õ·Õ­Õ¡Õ¿ÕžÖÕŽ ÕžÖÕžÕ¶ÕžÖÕŽÕš}
+_texthelpdateresults_ [l=hy] {ÔžÕ¶Õ€Õ°Õ¡Õ¶ÖÕ¡ÕºÕ¥Õœ Õ¡ÕœÕ¡Õ®, 1903 Õ©. ÕŽÕ¡ÕœÕ«Õ¶ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕ« ÕžÖÕžÕ¶ÕžÖÕŽÕš Õ¹Õ« ÕŸÕ¥ÖÕ¡Õ€Õ¡ÖÕ±Õ¶Õ« 1903 Õ©. Õ°ÖÕ¡Õ¿Õ¡ÖÕ¡Õ¯ÕŸÕ¡Õ® Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Õ£ÖÖÕ¥ÖÕš: Ô±ÕµÕ¶ÕžÖÕ¡ÕŽÕ¥Õ¶Õ¡ÕµÕ¶Õ«ÕŸ Õ°Õ¡Õ·ÕŸÕ« Õ¡ÕŒÕ¶Õ¥Õ¬ÕžÕŸ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕ« ÕžÖÕžÕ¶ÕŽÕ¡Õ¶ Õ¿Õ¡ÖÕ¥Õ©ÕŸÕ¥ÖÕ« Õ¥Õ²Õ¡Õ¶Õ¡Õ¯Õš, Õ¯Õ¡ÖÕ¥Õ¬Õ« Õ§ Õ¡ÕœÕ¥Õ¬, ÕžÖ Õ¯Õ£Õ¿Õ¶ÕŸÕ¥Õ¶ Õ¡ÕµÕ¶ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš, ÕžÖÕžÕ¶Ö Õ¿Õ¡ÖÕ¥Õ©ÕŸÕ¥ÖÕ« Õ¿Õ«ÖÕžÖÕµÕ©ÕžÖÕŽ (Ö
+ÖÕ«Õ¶Õ¡Õ¯` 1899-1911) Õ¡ÕŒÕ¯Õ¡ Õ§ Õ¶Õ¡Ö 1903, Õ«Õ¶Õ¹ÕºÕ¥Õœ Õ¶Õ¡Ö Õ¶ÖÕ¡Õ¶Ö, ÕžÖÕžÕ¶ÖÕžÖÕŽ 1903 Õ©. Õ¿ÕŸÕµÕ¡Õ¬ Õ€Õ¡ÖÕ¡Õ·ÖÕ»Õ¡Õ¶Õ« ÕŽÕ¡ÕœÕ¶ Õ§ (Ö
+ÖÕ«Õ¶Õ¡Õ¯ 20ÖÕ€ Õ€Õ¡Ö Õ¯Õ¡ÕŽ ÖÕœÕ¡Õ¶Õ¥ÖÕžÖÕ€ Õ€Õ¡Ö): ÕÕ¡ Õ¶Õ·Õ¡Õ¶Õ¡Õ¯ÕžÖÕŽ Õ§, ÕžÖ ÕžÖÕžÕ· ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕ« Õ°Õ¡ÕŽÕ¡Ö ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ¿Õ¡ÖÕ¥Õ©ÕŸÕ¥ÖÕš Õ¡ÕŒÕ¯Õ¡ Õ¹Õ¥Õ¶ Õ¬Õ«Õ¶Õ« ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ« Õ¿Õ¥ÖÕœÕ¿ÕžÖÕŽ: ÔžÕœÕ¿ Õ¿Õ«ÖÕžÖÕµÕ©Õ« ÕžÖÕžÕ¶ÕŽÕ¡Õ¶ ÕºÕ¡ÖÕ¡Õ£Õ¡ÕµÕžÖÕŽ, Õ¡ÕµÕœ Õ¡ÕŽÕ¥Õ¶Õš Õ¯Õ«ÖÕ¡ÕŒÕ¥Õ¬Õ« Õ§ Õ¿Õ«ÖÕžÖÕµÕ©Õ« ÖÕ¡Õ¶Õ¯Õ¡ÖÕ¡Õ® Õ¿Õ¡ÖÕ¥Õ©ÕŸÕ« Õ°Õ¡ÕŽÕ¡Ö:<p>
+
+}
+
+_textchangeprefs_ [l=hy] {ÕÕ¥Ö Õ¶Õ¡Õ­ÕšÕ¶Õ¿ÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕ« ÖÕžÖÕžÕ­ÕžÖÕŽ:}
+
+_texthelppreferences_ [l=hy] {<p>ÔµÖÕ¢ ÕœÕ¥Õ²ÕŽÕžÖÕŽ Õ¥Õœ Õ§Õ»Õ« ÕŸÕ¥ÖÖÕžÖÕŽ Õ¡ÕŒÕ¯Õ¡<i>Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö</i> Õ¯ÕžÕ³Õ¡Õ¯Õš, Õ¡ÕºÕ¡ Õ¯Õ¡ÖÕžÕ² Õ¥Õœ ÖÕžÕ­Õ¥Õ¬ ÕŽÕ«Õ»Õ¥ÖÕ¥ÕœÕ« ÕžÖÕžÕ· Õ¡ÖÕªÕ¥ÖÕ¶Õ¥Ö, ÖÕž ÕºÕ¡Õ°Õ¡Õ¶Õ»Õ¶Õ¥ÖÕ«Õ¶ Õ¢Õ¡ÕŸÕ¡ÖÕ¡ÖÕ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö:
+}
+
+_texthelpcollectionprefstitle_ [l=hy] {ÕÕ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö}
+_texthelpcollectionprefs_ [l=hy] {ÕÖÕžÕ· Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥Ö ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ¥Õ¶ Õ¥Õ¶Õ©Õ¡Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥Ö, ÕžÖÕžÕ¶ÖÕ«Ö ÕµÕžÖÖÕ¡ÖÕ¡Õ¶Õ¹ÕµÕžÖÖÕžÖÕŽ Õ¯Õ¡ÖÕ¥Õ¬Õ« Õ§ Õ¯Õ¡ÕŠÕŽÕ¡Õ¯Õ¥ÖÕºÕ¥Õ¬ Õ¡Õ¶Õ¯Õ¡Õ­ ÖÕ¶Õ¿ÖÕžÖÕŽ, Õ¯Õ¡ÕŽ Õ¯Õ¡ÖÕ¥Õ¬Õ« Õ§ ÖÕ¶Õ¿ÖÕ¥Õ¬ ÕžÕ²Õ» Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶: ÕÕ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö Õ§Õ»Õ«Ö Õ¯Õ¡ÖÕžÕ² Õ¥Ö ÕžÖÕžÕ·Õ¥Õ¬, Õ©Õ¥ ÕžÖ Õ¥Õ¶Õ©Õ¡Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕš ÕšÕ¶Õ€Õ£ÖÕ¯Õ¥Õ¬ ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ ÕŽÕ¥Õ»:
+}
+
+_texthelplanguageprefstitle_ [l=hy] {ÔŒÕ¥ÕŠÕŸÕ¡Õ¯Õ¡Õ¶ Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö}
+_texthelplanguageprefs_ [l=hy] {Ô±ÕŽÕ¥Õ¶ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖ ÕžÖÕ¶Õ« Õ¶Õ¥ÖÕ¯Õ¡ÕµÕ¡ÖÕŽÕ¡Õ¶ Õ¬ÕŒÕ¡Õ¯ÕµÕ¡Ö Õ¬Õ¥ÕŠÕžÖ: Ô²Õ¡ÕµÖ Õ¥Õ©Õ¥ ÖÕ¡Õ¶Õ¯Õ¡Õ¶ÕžÖÕŽ Õ¥Ö, Õ¯Õ¡ÖÕžÕ² Õ¥Ö Õ¡Õ¶ÖÕ¶Õ¥Õ¬ ÕŽÕ¥Õ¯ Õ¡ÕµÕ¬ Õ¬Õ¥ÕŠÕŸÕ«: Ô²ÕžÕ¬ÕžÖ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕš Õ©ÕžÖÕµÕ¬ Õ¥Õ¶ Õ¿Õ¡Õ¬Õ«Õœ Õ¡Õ¶ÖÕ¶Õ¥Õ¬ Õ£ÖÕ¡ÖÕ«Õ¯Õ¡Õ¯Õ¡Õ¶ ÕŽÕ«Õ»Õ¥ÖÕ¥ÕœÕ«Ö Õ¿Õ¥ÖÕœÕ¿Õ¡ÕµÕ«Õ¶Õ«: ÕÕ¡ Õ°Õ¡Õ¿Õ¯Õ¡ÕºÕ¥Õœ Ö
+Õ£Õ¿Õ¡Õ¯Õ¡Ö Õ§ Õ¿Õ¥ÕœÕžÕ²Õ¡Õ¯Õ¡Õ¶ Õ­Õ¡Õ¶Õ£Õ¡ÖÕžÖÕŽÕ¶Õ¥Ö ÕžÖÕ¶Õ¥ÖÕžÕ² ÕŽÕ¡ÖÕ€Õ¯Õ¡Õ¶Ö Õ°Õ¡ÕŽÕ¡Ö, Õ¥ÖÕ¢ ÕºÕ¥Õ¿Ö Õ§ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬ ÕºÕ¡ÕœÕ¿Õ¡ÕŒÕ¡ÕµÕ«Õ¶ Õ¬Õ¡ÕµÕ¶ Õ¿Õ¡ÕŒÕ¡Õ¿Õ¥ÕœÕ¡Õ¯Õ¶Õ¥Ö Õ¯Õ¡ÕŽ Õ±Õ¡ÕµÕ¶Õ« ÕœÕ«Õ¶Õ©Õ¥ÕŠÕ¡Õ¿ÕžÖÕ¶Õ¥Ö:
+}
+
+_texthelppresentationprefstitle_ [l=hy] {ÕÕ¥ÖÕ¯Õ¡ÕµÕ¡ÖÕŽÕ¡Õ¶ Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö}
+_texthelppresentationprefs_ [l=hy] {Ô¿Õ¡Õ­ÕŸÕ¡Õ® Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ«Ö, Õ¯Õ¡ÖÕžÕ² Õ¥Ö ÕšÕ¶Õ¿ÖÕ¥Õ¬ Õ¶Õ¥ÖÕ¯Õ¡ÕµÕ¡ÖÕŽÕ¡Õ¶ ÕŸÕ¥ÖÕ¡Õ°ÕœÕ¯ÕŽÕ¡Õ¶ ÕºÕ¡ÕµÕŽÕ¡Õ¶Õ¶Õ¥ÖÕš:
+
+<p>ÕÕœÕ¿Õ¡ÕµÕ¶Õ« Õ§Õ»Õ¥ÖÕ« Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕš ÕºÕ¡ÕœÕ«ÕŸÕ¡ÖÕ¶ÕžÖÕŽ Õ¥Õ¶ Õ¡ÕŽÕ¥Õ¶ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ« ÕŸÕ¥ÖÕ«Õ¶ ÕŽÕ¡ÕœÕžÖÕŽ Õ¡ÕŒÕ¯Õ¡   
+Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õ« Õ¯Õ¡ÕŒÕ¡ÕŸÕ¡ÖÕŽÕ¡Õ¶ Õ¿ÕžÕ²Õš: Ô±ÕµÕœÕºÕ«ÕœÕžÕŸ ÕŽÕ¥Õ¯ Õ¡Õ¶Õ£Õ¡ÕŽ ÖÕ¶Õ¿ÖÕžÖÕŽ Õ¯Õ¡Õ¿Õ¡ÖÕ¥Õ¬ÕžÕŸ, ÕžÖÕ²Õ²Õ¡Õ¯Õ«ÕžÖÕ¥Õ¶  
+Õ¯Õ¡Õ¶Õ£Õ¶ÕžÖÕŽ Õ¥Ö ÕžÕœÕ¿Õ¡ÕµÕ¶Õ« Õ³Õ·Õ£ÖÕ«Õ¿ Õ§Õ»Õ« ÕŸÖÕ¡, Õ¡ÕŒÕ¡Õ¶Ö Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õ« Õ²Õ¥Õ¯Õ¡ÕŸÕ¡ÖÕžÕ² Õ¿ÕžÕ²Õ«: ÕÕ¥Õ¯ Õ¡ÕµÕ¬ ÖÕ¶Õ¿ÖÕžÖÕŽ 
+Õ¯Õ¡Õ¿Õ¡ÖÕ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö ÕºÕ¥Õ¿Ö Õ§ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Ö Õ€Õ«Õ¿Õ¡Õ¯Õ« âÕ°Õ¥Õ¿â Õ¯ÕžÕ³Õ¡Õ¯Õš: Ô±ÕµÕœ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕš Õ¶Õ¡Ö Õ©ÕžÖÕµÕ¬ Õ¥Õ¶ 
+Õ¿Õ¡Õ¬Õ«Õœ ÕºÕ¡ÕœÕ«ÕŸÕ¡ÖÕ¶Õ¥Õ¬ Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õ« ÕŠÕ£ÕžÖÕ·Õ¡ÖÕ¶ÕžÕ² Õ°Õ¡Õ²ÕžÖÕ€ÕžÖÕŽÕ¶Õ¥ÖÕš Õ¡ÕµÕ¶ Õ€Õ¥ÕºÖÕ¥ÖÕžÖÕŽ, Õ¥ÖÕ¢ ÕœÕ¥Õ²ÕŽÕžÖÕŽ Õ¥Ö 
+Õ¯Õ¡ÕºÕ¥ÖÕ« ÕŸÖÕ¡, ÕžÖÕžÕ¶Ö Õ¿Õ¡Õ¶ÕžÖÕŽ Õ¥Õ¶ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕ«Ö Õ€ÕžÖÖÕœ, Õ¯Õ¡ÕŽ ÕžÖÕ²Õ²Õ¡Õ¯Õ«ÕžÖÕ¥Õ¶ 
+ÕžÕœÕ¿Õ¡ÕµÕ¶Õ« ÕŸÖÕ¡: ÕÖÕžÕ· ÕÕœÕ¿Õ¡ÕµÕ¶Õ¡ÕµÕ«Õ¶ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕ« Õ°Õ¡ÕŽÕ¡Ö Õ¯Õ¡ÖÕ¥Õ¬Õ« Õ§ ÕŸÕ¥ÖÕ¡Õ°ÕœÕ¯Õ¥Õ¬ Õ¡ÖÕ€ÕµÕžÖ Õ¯Õ¡ÕºÕ¥ÖÕš 
+âÕÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ¡ÖÕ€ÕµÕžÖÕ¶ÖÕ¶Õ¥Öâ Õ§Õ»Õ«Ö Õ¿Õ¡Õ¶ÕžÖÕŽ Õ¥Õ¶ ÕžÖÕ²Õ²Õ¡Õ¯Õ«ÕžÖÕ¥Õ¶ Õ€Õ¥ÕºÕ« ÕÕ¡ÕŽÕšÕ¶Õ€Õ°Õ¡Õ¶ÕžÖÖ ÕºÕ¡Õ·Õ¡ÖÕ« ÕžÖÕœÕ«Õ¹Õ« ÕŸÖÕ¡ 
+Õ©Õ¥ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« Õ§Õ»Õ« ÕºÕ¡Õ¿Õ³Õ¥Õ¶Õ« ÕŸÖÕ¡:
+}
+
+_texthelpsearchprefstitle_ [l=hy] {ÕÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö}
+_texthelpsearchprefs_ [l=hy] {<p>ÔµÖÕ¯ÕžÖ ÕŠÕžÖÕµÕ£ Õ¯ÕžÕ³Õ¡Õ¯Õ¶Õ¥Ö ÕŸÕ¥ÖÕ¡Õ°ÕœÕ¯ÕžÖÕŽ Õ¥Õ¶ Õ¿Õ¥ÖÕœÕ¿Õ« Õ¿Õ¥ÕœÕ¡Õ¯Õš ÕžÖÕš Õ¡ÕŒÕ¯Õ¡ Õ§ ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ ÕŽÕ¥Õ»: Ô±ÕŒÕ¡Õ»Õ«Õ¶ 
+Õ¢Õ¡ÕŠÕŽÕžÖÕ©ÕµÕžÖÕ¶Õš (ÕºÕ«Õ¿Õ¡Õ¯Õ¡ÕŸÕžÖÕŸÕ¡Õ® ÕžÖÕºÕ¥Õœ "ÕºÕ¡Õ¿Õ³Õ¡ÕŒÕ¡ÕµÕ«Õ¶ Õ¿Õ¡ÖÕ¢Õ¥ÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö") ÕŸÕ¥ÖÕ¡Õ°ÕœÕ¯ÕžÖÕŽ Õ§, Õ¡ÖÕ€ÕµÕžÖ 
+ÕœÕ¿Õ¥Õ²Õ¶Õ¡Õ·Õ¡ÖÕ« ÕŸÕ¥ÖÕ«Õ¶ Ö ÕœÕ¿ÕžÖÕ«Õ¶ Õ¶Õ«Õ·Õ¥ÖÕš Õ°Õ¡ÕŽÕšÕ¶Õ¯Õ¶ÕžÖÕŽ Õ¥Õ¶: ÔµÖÕ¯ÖÕžÖÕ€Õš ("Õ¢Õ¡ÕŒÕ« ÕŸÕ¥ÖÕ»Õ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö") 
+ÕŸÕ¥ÖÕ¡Õ°ÕœÕ¯ÕžÖÕŽ Õ§ Õ¡ÖÕ€ÕµÕžÖ Õ¡Õ¶Õ¿Õ¥ÕœÕ¥Õ¬ Õ¢Õ¡ÕŒÕ¥ÖÕ« ÕŸÕ¥ÖÕ»Õ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš Õ©Õ¥ ÕžÕ¹: ÕÕ¶Õ¡ÖÕ¡ÕŸÕžÖ Õ§ ÕœÕ¿Õ¡Õ¶Õ¡Õ¬ Õ°Õ¡ÖÖÕŽÕ¡Õ¶ 
+Õ¬Õ¡ÕµÕ¶ ÕºÕ¡Õ¿ÕžÖÕ°Õ¡Õ¶, Õ¡ÕµÕ¶ÕºÕ¥Õœ ÕžÖ  Õ¯Õ¡ÖÕ¥Õ¬Õ« Õ§ Õ«ÖÕ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¥Õ¬ ÕºÕ¡ÖÕ¡Õ£ÖÕ¡ÖÕ¡ÕµÕ«Õ¶-Õ°Õ«ÕŽÕ¶ÕŸÕ¡Õ® ÕžÖÕžÕ¶ÕžÖÕŽÕ¶Õ¥Ö: 
+
+<p>ÕÖÕ«Õ¶Õ¡Õ¯, Õ¥Õ©Õ¥ <i>Õ¡Õ¶Õ¿Õ¥ÕœÕ¥Õ¬ Õ€Õ¥ÕºÖÕ¥ÖÕ« Õ¿Õ¡ÖÕ¢Õ¥ÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš</i> Ö
+<i>Õ¡Õ¶Õ¿Õ¥ÕœÕ¥Õ¬ Õ¢Õ¡ÕŒÕ¥ÖÕ« ÕŸÕ¥ÖÕ»Õ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš</i> Õ¯ÕžÕ³Õ¡Õ¯Õ¶Õ¥ÖÕš ÕšÕ¶Õ¿ÖÕŸÕ¡Õ® Õ¥Õ¶, Õ°Õ¥Õ¿ÖÕµÕ¡Õ¬ Õ°Õ¡ÖÖÕžÖÕŽÕš<p>
+    <ul><kbd>African building</kbd></ul>
+      <p>Õ¯ÕšÕ¶Õ¯Õ¡Õ¬ÕŸÕ« ÕžÖÕºÕ¥Õœ Õ¶ÕžÖÕµÕ¶Õš, Õ«Õ¶Õ¹<p>
+      <ul><kbd>africa builds</kbd></ul><p>
+      ÖÕ¡Õ¶ÕŠÕ« "African" Õ¢Õ¡ÕŒÕ« ÕŽÕ¥Õ®Õ¡Õ¿Õ¡ÕŒ A Õ¿Õ¡ÕŒÕš Õ¯Õ±ÖÕ¡ÖÕžÕ­ÕŸÕ« Õ«Ö ÖÕžÖÖÕ¡Õ¿Õ¡ÕŒÕ«Õ¶, Ö "n" ÕžÖ "ing" 
+      ÕŸÕ¥ÖÕ»Õ¡Õ®Õ¡Õ¶ÖÕ¶Õ¥ÖÕš Õ€ÕžÖÖÕœ Õ¯ÕŽÕ²ÕŸÕ¥Õ¶ "African" Ö "building" Õ¢Õ¡ÕŒÕ¥ÖÕ«Ö: ÕÕ¡Ö  "s" Õ¯Õ°Õ¡Õ¶ÕŸÕ«
+      "builds" Õ¢Õ¡ÕŒÕ«Ö):
+
+<p>Ô¿Õ¡ÖÕ¥Õ¬Õ« Õ§ Õ¡Õ¶ÖÕ¶Õ¥Õ¬ "Õ­ÕžÖÕ¡ÖÕŸÕ¡Õ®" Õ°Õ¡ÖÖÕŽÕ¡Õ¶ ÕŸÕ«Õ³Õ¡Õ¯Õ«Õ¶, ÕžÖÕš Õ©ÕžÖÕµÕ¬ Õ§ Õ¿Õ¡Õ¬Õ«Õœ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬
+AND (&), OR (|), NOT (!) Õ¿Õ¥ÖÕŽÕ«Õ¶Õ¶Õ¥ÖÕš: ÕÕ¡ Õ©ÕžÖÕµÕ¬ Õ§ Õ¿Õ¡Õ¬Õ«Õœ Õ±ÖÕ¡Õ¯Õ¥ÖÕºÕ¥Õ¬ Õ¡ÕŸÕ¥Õ¬Õ« Õ³Õ·Õ£ÖÕ«Õ¿ Õ°Õ¡ÖÖÕžÖÕŽÕ¶Õ¥Ö: 
+Ô¿Õ¡ÖÕ¥Õ¬Õ« Õ§ ÕŽÕ«Õ¡ÖÕ¶Õ¥Õ¬ ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ ÕºÕ¡Õ¿ÕŽÕžÖÕ©ÕµÕ¡Õ¶ Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õš, ÕžÖÕš ÖÕžÖÕµÖ Õ§ Õ¿Õ¡Õ¬Õ«Õœ ÕŸÕ¥ÖÕ»Õ«Õ¶ ÕŽÕ« ÖÕ¡Õ¶Õ« 
+Õ°Õ¡ÖÖÕžÖÕŽÕ¶Õ¥ÖÕš: ÕÕ¡ Õ°Õ¥Õ·Õ¿Õ¡ÖÕ¶ÕžÖÕŽ Õ§ Ö
+Õ£Õ¿ÕŸÕ¥Õ¬ÕžÕŸ Õ¶Õ¡Õ­ÕžÖÕ€ ÖÕ¶Õ¿ÖÕžÖÕŽÕ¶Õ¥ÖÕ«Ö, Õ«ÖÕ¡Õ¯Õ¡Õ¶Õ¡ÖÕ¶Õ¥Õ¬ Õ€ÖÕ¡Õ¶Ö ÕŽÕ« 
+ÖÕ«Õ¹ Õ±ÖÕ¡ÖÕžÕ­ÕŸÕ¡Õ® Õ¿Õ¡ÖÕ¢Õ¥ÖÕ¡Õ¯Õ¶Õ¥ÖÕš: ÕÕ¥ÖÕ»Õ¡ÕºÕ¥Õœ, ÕµÕžÖÖÕ¡ÖÕ¡Õ¶Õ¹ÕµÕžÖÖ ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ°Õ¡ÕŽÕ¡Ö Õ¯Õ¡ÖÕ¥Õ¬Õ« Õ§ ÕŸÕ¥ÖÕ¡Õ°ÕœÕ¯Õ¥Õ¬ 
+ÕŸÕ¥ÖÕ¡Õ€Õ¡ÖÕ±ÕŸÕ¡Õ® ÖÕ¶Õ¿ÖÕŽÕ¡Õ¶ Õ¢Õ¡ÕŠÕŽÕžÖÕ©ÕµÕžÖÕ¶Õš:
+}
+
+_texttanumbrowseoptions_ [l=hy] {Ô±ÕŒÕ¯Õ¡ Õ¥Õ¶ _numbrowseoptions_ Õ¥Õ²Õ¡Õ¶Õ¡Õ¯Õ¶Õ¥Ö Õ¡ÕµÕœ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« ÕŽÕ¥Õ» Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶ Õ£Õ¿Õ¶Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö: }
+
+_textsimplehelpheading_ [l=hy] {Ô»Õ¶Õ¹ÕºÕ¥Õœ Õ£Õ¿Õ¶Õ¥Õ¬ Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶ _collectionname_ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« ÕŽÕ¥Õ»}
+
+_texthelpscopetitle_ [l=hy] {ÕÕ¡ÖÖÕŽÕ¡Õ¶ Õ¿Õ«ÖÕžÖÕµÕ©}
+_texthelpscope_ [l=hy] {<p>
+ÕÕ¡Õ¿ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕžÖÕŽ ÕžÖÕžÕ¶ÕŽÕ¡Õ¶ Õ°Õ¡ÕŽÕ¡Ö Õ¯Õ¡ÖÕžÕ² Õ¥Ö ÕšÕ¶Õ¿ÖÕ¥Õ¬ Õ¿Õ¡ÖÕ¢Õ¥Ö ÖÕžÖÖÕ«Õ¹Õ¶Õ¥Ö: 
+ÕÖÕ«Õ¶Õ¡Õ¯, Õ¯Õ¡ÖÕžÕ² Õ¥Õ¶ Õ¬Õ«Õ¶Õ¥Õ¬ Õ°Õ¥Õ²Õ«Õ¶Õ¡Õ¯Õ¶Õ¥ÖÕ« Õ¯Õ¡ÕŽ ÕŸÕ¥ÖÕ¶Õ¡Õ£ÖÕ¥ÖÕ« ÖÕžÖÖÕ«Õ¹Õ¶Õ¥Ö: Ô¿Õ¡ÕŽ ÕºÕ¡ÖÕ¡Õ£ÖÕ¡ÖÕ¶Õ¥ÖÕ«  
+ÖÕžÖÖÕ«Õ¹Õ¶Õ¥Ö:
+ÔžÕ¶Õ€Õ°Õ¡Õ¶ÖÕ¡ÕºÕ¥Õœ, ÖÕ¡ÕœÕ¿Õ¡Õ©ÕžÖÕ²Õ©Õš Õ£Õ¿Õ¶ÕŸÕžÖÕŽ Õ§, Õ¡Õ¶Õ¯Õ¡Õ­ Õ©Õ¥ Õ«Õ¶Õ¹ ÖÕžÖÖÕ«Õ¹ÕžÕŸ Õ¥Õœ ÖÕ¶Õ¿ÖÕžÖÕŽ:
+<p>ÔµÕ©Õ¥ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕš Õ£ÖÖÕ¥Ö Õ¥Õ¶, Õ¶ÖÕ¡Õ¶Ö Õ¯Õ¢Õ¡ÖÕŸÕ¥Õ¶ Õ°Õ¡ÕŽÕ¡ÕºÕ¡Õ¿Õ¡ÕœÕ­Õ¡Õ¶ Õ¿Õ¥Õ²ÕžÖÕŽ:
+
+
+}
Index: /gsdl/stable/macros/armenian2.dm
===================================================================
--- /gsdl/stable/macros/armenian2.dm	(revision 20131)
+++ /gsdl/stable/macros/armenian2.dm	(revision 20131)
@@ -0,0 +1,785 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# English Language text and icon macros 
+# -- this file contains text that is of less importance
+######################################################################
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=hy] {ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÖ}  
+_lastupdate_ [l=hy] {ÕÕ¥ÖÕ»Õ«Õ¶ Õ©Õ¡ÖÕŽÕ¡ÖÕžÖÕŽ}  
+_ago_ [l=hy] {Ö
+Ö Õ¡ÕŒÕ¡Õ»}  
+
+
+
+
+_textgreenstone_ [l=hy] {<p>Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õš Õ€Õ¡ Õ¯Õ«ÕœÕ¡Õ©Õ¡Õ¶Õ¯Õ¡ÖÕªÕ¥Ö ÖÕ¡Ö Õ§, ÕžÖÕš (Õ«Õ¶Õ¹ÕºÕ¥Õœ Ö Õ¡ÕµÕœ Õ®ÖÕ¡Õ£ÖÕ¡Õ·Õ¡ÖÕš) ÕœÕ¯ÕŠÕ¢Õ¶Õ¡ÕŸÕžÖÕŸÕ¥Õ¬ Õ§ ÕÕžÖ Ô¶Õ¥Õ¬Õ¡Õ¶Õ€Õ«Õ¡ÕµÕžÖÕŽÖÔ±ÕŸÕ¡Õ¶Õ€Õ¡Õ¯Õ¡Õ¶ ÕÕ¡ÕžÖÕ«Õ¶Õ¥ÖÕ« Õ°Õ¡ÕŽÕ¡ÕµÕ¶ÖÕžÖÕŽ Õ¡ÕµÕ¶ Õ¡ÕµÕ¶ Õ¡ÕŽÕ¥Õ¶Õ¡Õ¢Õ¡ÖÕ±Ö Õ£Õ¶Õ¡Õ°Õ¡Õ¿ÕŸÕ¡Õ®Õ¶ Õ§ÖÕ¡ÕµÕ¶ Õ¯Õ¡ÖÕžÕ² Õ§ Õ¡Õ¢ÕœÕžÖÕ¢Õ¡ÖÕ¶Õ¥Õ¬ Ö ÕºÕ¡Õ°Õ¥Õ¬ <i>ÕŸÕ¡ÕµÖÕžÖÕ¡Õ¶ (wairua)</i>,
+ÕžÖÕš Õ¯Õ¥Õ¶ÕœÕ¡Õ¯Õ¡Õ¶ ÕžÖÕªÕ¥ÖÕ« ÕžÕ£Õ«Õ¶ Õ§, Ö Õ°Õ¡ÕŽÕ¡ÕºÕ¡Õ¿Õ¡ÕœÕ­Õ¡Õ¶ÕžÖÕŽ Õ§ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« Õ¶Õ¡Õ­Õ¡Õ£Õ®Õ« Õ­ÕžÖÕ°ÖÕ€Õ¡Õ¶Õ«Õ·ÕšÖ ÕÖÕ¡ ÖÕ¡ÕµÕ¬Õš Õ¶Õ·Õ¡Õ¶Õ¡Õ¯ÕžÖÕŽ Õ§ ÕžÕ²ÕžÖÕŽÕ¡Õ®ÕžÖÕ©ÕµÕžÖÕ¶. Õ³Õ¡ÕŒÕ¡Õ£Õ¡ÕµÕ©ÕžÖÕŽÕšÕ Õ¡ÕŠÕ¶ÕŸÕžÖÕ©ÕµÕžÖÕ¶. Õ¡ÕŽÖÕžÖÕ©ÕµÕžÖÕ¶ÕšÕ ÖÕ¡Õ»ÕžÖÕ©ÕµÕžÖÕ¶. Ö ÕœÕžÖÖ Õ·Õ¥Õ²Õ¢Õš Õ¯Õ¶Õ·Õ¡Õ¶Õ¡Õ¯Õ« Õ¡ÖÕ€Õ¡ÖÕ¡ÕžÖÕ©ÕµÕžÖÕ¶ÖÕÕ¡ÖÕ« Õ¯Õ¿ÕžÖÕš ÕžÖÕš Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕŸÕžÖÕŽ Õ§ ÕžÖÕºÕ¥Õœ Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« Õ­ÕžÖÕ°ÖÕ€Õ¡Õ¶Õ«Õ· Õ€Õ¡ <i>ÕºÕ¡Õ©ÕžÖ Õ§ (patu)</i>
+Õ¯Õ¡ÕŽ ÕŽÕ¡ÖÕ¿Õ¡Õ¯Õ¡Õ¶ Õ¡Õ¯ÕžÖÕŽÕ¢, Ö ÕŽÕ¥Ö Õ¶Õ¡Õ­Õ¡Õ£Õ®Õ« Õ¡Õ¶Õ€Õ¡ÕŽÕ¶Õ¥ÖÕ«Ö ÕŽÕ¥Õ¯Õ« ÕšÕ¶Õ¿Õ¡Õ¶Õ¥Õ¯Õ¡Õ¶ Õ°Õ¡ÖÕœÕ¿ÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕ«Ö Õ§Ö
+ÕÕ¥ÕŒÕ¶Õ¡ÕŽÕ¡ÖÕ¿Õ« ÕªÕ¡ÕŽÕ¡Õ¶Õ¡Õ¯ Õ€ÖÕ¡ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕžÖÕŽÕš Õ·Õ¡Õ¿ Õ¡ÖÕ¡Õ£ Õ§, Õ·Õ¡Õ¿ Õ°Õ¡ÕŸÕ¡Ö Ö Õ·Õ¡Õ¿ Õ¡ÕŽÕ¢ÕžÕ²Õ»Õ¡Õ¯Õ¡Õ¶ÖÕÕ¥Õ¶Ö ÕžÖÕŠÕžÖÕŽ Õ¥Õ¶Ö ÕŽÕ¿Õ¡Õ®Õ¥Õ¬, ÕžÖ Õ¡ÕµÕœ Õ°Õ¡Õ¿Õ¯Õ¡Õ¶Õ«Õ·Õ¶Õ¥ÖÕš Õ¢Õ¶ÕžÖÕžÕ· Õ¥Õ¶ Õ¶Õ¡Ö ÕŽÕ¥Ö Õ¶Õ¡Õ­Õ¡Õ£Õ®Õ¡Õ® Õ®ÖÕ¡Õ£ÖÕ¡Õ·Õ¡ÖÕ«Õ¶, Ö <i>ÕºÕ¡Õ©ÕžÖÕ« (patu)</i> ÕœÕ¡ÕµÖÕ« ÕºÕ¥Õœ ÕœÕžÖÖ Õ·Õ¥Õ¢Õš Õ¢Õ¶ÕžÖÕžÕ·ÕžÖÕŽ Õ§ Õ¡ÕŽÕ¥Õ¶Õ¡ÕŠÕ¡ÖÕ£Õ¡ÖÕ¡Õ® Õ¿Õ¥Õ­Õ«ÕžÕ¬ÕžÕ£Õ«Õ¡ÕµÕ« Õ¯Õ«ÖÕ¡ÕŒÕžÖÕŽÕšÖ</p>
+}  
+
+
+
+
+
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+# should have arguments of collection, collectionname and link
+
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=hy] {Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶}  
+
+_textusername_ [l=hy] {Ö
+Õ£Õ¿ÕŸÕžÕ²Õ« Õ¡Õ¶ÕŸÕ¡Õ¶ÕžÖÕŽ}  
+
+
+
+
+_textmessageinvalid_ [l=hy] {ÕÕ¥Ö Õ¯ÕžÕ²ÕŽÕ«Ö Õ¡ÕŒÕ¡Õ»Õ¡ÖÕ¯ÕŸÕžÕ² Õ§Õ»Õš ÕºÕ¡Õ°Õ¡Õ¶Õ»ÕžÖÕŽ Õ§ Õ£ÖÕ¡Õ¶ÖÕžÖÕŽÖ<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)
+ÕÕžÖÕ¿Ö Õ¡ÖÕ¥Ö Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õ« Ö
+Õ£Õ¿ÕŸÕžÕ²Õ« Õ¡Õ¶ÕžÖÕ¶Õš Ö Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡ÕŒÕšÖ}  
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+_textuserguide_ [l=hy] {ÕÕ£Õ¿ÕŸÕžÕ²Õ« ÕžÖÕ²Õ¥ÖÕžÖÕµÖ}  
+
+_textdeveloperguide_ [l=hy] {ÕÕ¡Õ­Õ¡Õ£Õ®ÕžÕ²Õ« ÕžÖÕ²Õ¥ÖÕžÖÕµÖ}  
+
+
+
+
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=hy] {ÕÕ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« Õ¯Õ¡ÕŒÕžÖÖÕžÖÕŽ}  
+
+
+
+
+
+
+
+
+_textstopbuild_ [l=hy] {Õ¯Õ¡Õ¶Õ£Õ¶Õ¥ÖÕ¶Õ¥Õ¬ Õ¯Õ¡ÕŒÕžÖÖÕžÖÕŽÕš}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textfailmsg21_ [l=hy] {ÕÕ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ Õ°Õ¿Õ¡ÖÕ¡ÕŸÕžÖ Õ¹Õ§ Õ¯Õ¡ÕŒÕžÖÖÕ¥Õ¬ (import.pl Õ¹Õ¯Õ¡ÕµÕ¡ÖÕ¡ÕŸ)Ö}  
+_textfailmsg31_ [l=hy] {ÕÕ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖ Õ¹Õ§ Õ¯Õ¡ÕŒÕžÖÖÕ¥Õ¬ (buildcol.pl Õ¹Õ¯Õ¡ÕµÕ¡ÖÕ¡ÕŸ)Ö}  
+
+
+
+
+_textblcont_ [l=hy] {Ô¿Õ¡ÕŒÕžÖÖÕŽÕ¡Õ¶ Õ¬ÕžÕ£ ÖÕ¡ÕµÕ¬Õš ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ§ Õ°Õ¥Õ¿ÖÕµÕ¡Õ¬ Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶ÕšÖ}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=hy] {Õ¬ÕŒÕ¡Õ¯ÕµÕ¡Ö Õ¯Õ¡ÕŒÕžÖÖÕŸÕ¡Õ®Ö}  
+
+_textinfo_ [l=hy] {ÕÕ¡ÕŸÕ¡ÖÕ«Õ¹Õ« Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶}  
+
+
+_textbild_ [l=hy] {_wizard:textbild_}  
+
+_textdel_ [l=hy] {ÕÕ¥ÕŒÕ¡ÖÕ¶Õ¥Õ¬ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Ö}  
+
+_textbildsuc_ [l=hy] {_wizard:textbildsuc_}  
+
+
+
+_textimportingcollection_ [l=hy] {ÕÕ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« Õ¶Õ¥ÖÕŽÕžÖÕ®ÕžÖÕŽ ...}  
+
+_textcreatingcollection_ [l=hy] {ÕÕ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« ÕœÕ¿Õ¥Õ²Õ®ÕžÖÕŽâŠ}  
+
+
+
+_textcb1_ [l=hy] {Ô¿ÕžÖÕ¿Õ¡Õ¯Õ«Õ¹Õš Ö
+Õ£Õ¶ÕžÖÕŽ Õ§ ÕœÕ¿Õ¥Õ²Õ®Õ¥Õ¬ÕžÖ Õ¶ÕžÖ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥Ö, Õ©Õ¡ÖÕŽÕ¡ÖÕ¶Õ¥Õ¬ Õ¯Õ¡ÕŽ Õ¡ÕŸÕ¥Õ¬Õ¡ÖÕ¶Õ¥Õ¬ Õ¥Õ²Õ¡Õ®Õ¶Õ¥ÖÕ«Õ¶, Õ¯Õ¡ÕŽ Õ»Õ¶Õ»Õ¥Õ¬ Õ¥Õ²Õ¡Õ®Õ¶Õ¥ÖÕšÖ ÕÕ¡ Õ¯Õ¡Õ¿Õ¡ÖÕ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö ÔŽÕžÖÖ Õ¯Õ¡Õ¶ÖÕ¶Õ¥Ö ÕÕœÕ¿Õ¡ÕµÕ¶Õ« Õ§Õ»Õ¥ÖÕžÕŸ, ÕžÖÕžÕ¶Ö Õ¯ÕºÕ¡Õ°Õ¡Õ¶Õ»Õ¥Õ¶ Õ¡Õ¶Õ°ÖÕ¡ÕªÕ¥Õ·Õ¿ Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Õ¿ÕŸÕžÕ©ÕµÕžÖÕ¶ÕšÖ}  
+
+_textcb2_ [l=hy] {ÕÕ¡Õ­ Ö Õ¡ÕŒÕ¡Õ» ÕžÖÕžÕ·Õ¥Ö Õ¡ÖÕ€ÕµÕžÖ}  
+
+
+
+_textcb3_ [l=hy] {Ô¹ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕ« ÖÕžÖÕžÕ­ÕŽÕ¡Õ¶ Õ¯Õ¡ÕŽ Õ¯Õ¡ÕŒÕžÖÖÕŽÕ¡Õ¶ Õ°Õ¡ÕŽÕ¡Ö ÕºÕ¥Õ¿Ö Õ§ Õ£ÖÕ¡Õ¶ÖÕŸÕ¥ÖÖÕÕ¡ Õ¡Õ¶Õ°ÖÕ¡ÕªÕ¥Õ·Õ¿ Õ§ ÕÕ¥ÕŠ ÕºÕ¡Õ·Õ¿ÕºÕ¡Õ¶Õ¥Õ¬ÕžÖ Õ¡ÕµÕ¬ÕžÖ Õ¯ÕžÕ²ÕŽÕ«Ö ÕÕ¥Ö Õ°Õ¡ÕŽÕ¡Õ¯Õ¡ÖÕ£Õ¹Õ« Õ¿ÕŸÕµÕ¡Õ¬Õ¶Õ¥ÖÕš ÖÕžÖÕžÕ­Õ¥Õ¬ÕžÖÖÖÕÕ¯Õ¡Õ¿Õ« ÕžÖÕ¶Õ¥ÖÕ¥Ö, ÕžÖ Õ¡Õ¶ÕŸÕ¿Õ¡Õ¶Õ£ÕžÖÕ©ÕµÕ¡Õ¶ Õ¶Õ¯Õ¡Õ¿Õ¡ÕŒÕžÖÕŽÕ¶Õ¥ÖÕ«Ö Õ¥Õ¬Õ¶Õ¥Õ¬ÕžÕŸ ÔŽÕžÖÖ Õ¯Õ¡Õ¶Õ»Õ¡Õ¿ÕŸÕ¥Ö Õ°Õ¡ÕŽÕ¡Õ¯Õ¡ÖÕ£Õ«Ö ÕÕ¥Ö Õ£ÖÕ¡Õ¶ÖÕžÖÕŽÕ«Ö 30 ÖÕžÕºÕ¥ Õ¡Õ¶ÖÖ ÔµÕ©Õ¥ ÕœÕ¡ ÕºÕ¡Õ¿Õ¡Õ°Õ« ÕŽÕ«Ö Õ¡Õ¶Õ°Õ¡Õ¶Õ£ÕœÕ¿Õ¡ÖÕ¥ÖÕ ÔŽÕžÖÖ Õ¶ÕžÖÕ«Ö Õ¯Õ°ÖÕ¡ÕŸÕ«ÖÕŸÕ¥Ö ÕŽÕžÖÕ¿Ö Õ£ÕžÖÕ®Õ¥Õ¬ÕžÖ Ö Õ¯Õ·Õ¡ÖÕžÖÕ¶Õ¡Õ¯Õ¥Ö Õ¡Õ·Õ­Õ¡Õ¿Õ¡Õ¶ÖÕš Õ¡ÕµÕ¶Õ¿Õ¥Õ²Õ«Ö ÕžÖÕ¿Õ¥Õ² ÕžÖ Õ¯Õ¡Õ¶Õ£ Õ¥Ö Õ¡ÕŒÕ¥Õ¬Ö}  
+
+
+
+
+
+
+
+
+
+
+_textcaec_ [l=hy] {Ô±ÕŒÕ¯Õ¡ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« ÖÕžÖÕžÕ­ÕžÖÕŽ}  
+
+
+
+
+
+
+
+
+
+
+
+_textadab_ [l=hy] {ÕÕ¿ÕžÖÖ Õ¡ÖÕ¿Õ¡Õ®ÕŸÕžÖÕŽ Õ§ Õ€Õ«Õ¡Õ£ÖÕ¡ÕŽ, ÕžÖÕš Õ¯Ö
+Õ£Õ¶Õ« Õ¯ÕžÕ²ÕŽÕ¶ÕžÖÕžÕ·ÕŸÕ¥Õ¬ÕžÖ Õ©Õ¥ ÕžÖÕ¿Õ¥Õ² Õ¥ÕœÖÔ¿Õ¡Õ¶Õ¡Õ¹ Õ¯ÕžÕ³Õ¡Õ¯Õš Õ¡ÕºÕ¡Õ°ÕžÕŸÕžÖÕŽ Õ§ Õ¿Õ¥Õ²Õ¡Õ·Õ¡ÖÕªÕš Õ¿Õ«ÖÕžÖÕµÕ©ÕžÖÕŽÖÕÕ¡ÖÕ»ÕŸÕ¥Õ¬ÕžÕŸ Õ¶ÖÕ¡Õ¶ÕžÖÕŽ Õ¯ÕžÕ³Õ¡Õ¯Õ¶Õ¥ÖÕš Õ¯ÖÕžÕ­Õ¥Õ¶ Õ£ÕžÖÕµÕ¶Õš Õ€Õ¡ÕŒÕ¶Õ¡Õ¬ÕžÕŸ Õ€Õ¥Õ²Õ«Õ¶Ö Ô¿Õ¡ÖÕžÕ² Õ¥Õœ ÕŸÕ¥ÖÕ¡Õ€Õ¡ÕŒÕ¶Õ¡Õ¬ Õ¶Õ¡Õ­ÕžÖÕ€ Õ§Õ» ÕœÕ¥Õ²ÕŽÕ¥Õ¬ÕžÕŸ Õ€Õ«Õ¡Õ£ÖÕ¡ÕŽÕ« ÕŸÖÕ¡ Õ¡ÕŒÕ¯Õ¡ Õ°Õ¡ÕŽÕ¡ÕºÕ¡Õ¿Õ¡ÕœÕ­Õ¡Õ¶ Õ€Õ¥Õ²Õ«Õ¶ Õ¯ÕžÕ³Õ¡Õ¯Õ« ÕŸÖÕ¡Ö}  
+
+_textwyar_ [l=hy] {ÔµÖÕ¢ ÕžÖ ÕºÕ¡Õ¿ÖÕ¡ÕœÕ¿ Õ¥Õœ, ÕœÕ¥Õ²ÕŽÕ«Ö Õ¯Õ¡Õ¶Õ¡Õ¹ Õ£ÕžÖÕµÕ¶Õ« "collection information" Õ¯ÕžÕ³Õ¡Õ¯ÕšÕ Õ¶ÕžÖ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« ÕœÕ¿Õ¥Õ²Õ®ÕžÖÕŽÕš ÕœÕ¯ÕœÕ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡ÖÖ}  
+
+
+
+_textpsea_ [l=hy] {ÕÕ·Õ¿Õ¥Ö Õ§Õ¬. ÖÕžÕœÕ¿Õ« Õ°Õ¡ÕœÖÕ¥Õ¶ Õ¡ÕµÕœ Õ±ÖÕ¡Õ¹Õ¡ÖÕžÕŸÕ username@domain}  
+_textdocmbs_ [l=hy] {ÕÕ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« Õ¶Õ¯Õ¡ÖÕ¡Õ£ÖÕžÖÕ©ÕµÕžÖÕ¶Õš ÕºÕ¥Õ¿Ö Õ§ ÕžÖÕžÕ·ÕŸÕ«Ö}  
+
+
+
+
+
+
+
+
+
+
+
+_textatc_ [l=hy] {Ô±ÕµÕœ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« ÕŽÕ¡ÕœÕ«Õ¶}  
+
+
+
+_textypits_ [l=hy] {Ô±ÕµÕœ Õ·Õ¡ÖÖÕžÖÕŽ ÕÕ¥Ö Õ€Õ«ÖÖÕš ÖÕžÖÕµÖ Õ§ Õ¿ÖÕŸÕ¡Õ® Õ¶Õ¥ÖÖÖÕžÖÕŽ Õ¡ÕŒÕ¯Õ¡ ÕœÕ¬Õ¡ÖÕžÕŸÕ Õ¿ÕŸÕµÕ¡Õ¬ Õ€Õ¥ÕºÖÕžÖÕŽ "Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« ÕŽÕ¡ÕœÕ«Õ¶" ÖÕžÖÕ¬ÕžÖÕŽÖÕÕ¡ÖÕžÖÕ¶Õ¡Õ¯Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö ÕœÕ¥Õ²ÕŽÕ¥Ö
+"Õ¶Õ¡Õ­Õ¶Õ¡Õ¯Õ¡Õ¶ Õ¿ÕŸÕµÕ¡Õ¬Õ¶Õ¥Ö" Õ¯Õ¡Õ¶Õ¡Õ¹ Õ¯ÕžÕ³Õ¡Õ¯ÕšÖ
+}  
+
+_srcebadsources_ [l=hy] {<p>ÕÕ¥Ö Õ¯ÕžÕ²ÕŽÕ«Ö ÕœÕ¡Õ°ÕŽÕ¡Õ¶ÕŸÕ¡Õ® ÕŽÕ¥Õ¯ Õ¯Õ¡ÕŽ ÕŽÕ« ÖÕ¡Õ¶Õ« ÕŽÕžÖÕ¿ÖÕ« Õ¡Õ²Õ¢ÕµÕžÖÖÕ¶Õ¥ÖÕš ÕŽÕ¡Õ¿Õ¹Õ¥Õ¬Õ« Õ¹Õ¥Õ¶ (Õ¶Õ·ÕŸÕ¡Õ®
+_iconcross_ below).
+
+<p>ÕÕ¡Õ¿Õ³Õ¡ÕŒÕš Õ¯Õ¡ÖÕžÕ² Õ§ Õ¬Õ«Õ¶Õ¥Õ¬
+<ul>
+<li>ÕÕ¡ÕµÕ¬Õš, FTP Õ¯Õ¡ÕµÖÕš Õ¯Õ¡ÕŽ URL Õ£ÕžÕµÕžÖÕ©ÕµÕžÖÕ¶ Õ¹ÕžÖÕ¶Õ«Ö
+<li>ÕÕ¯ÕŠÕ¢Õ«Ö ÕºÕ¥Õ¿Ö Õ§ Õ¯Õ¡Õº Õ°Õ¡ÕœÕ¿Õ¡Õ¿Õ¥Õ¬ Ô»Õ¶Õ¿Õ¥ÖÕ¶Õ¥Õ¿ Õ®Õ¡ÕŒÕ¡ÕµÕžÖÕ©ÕµÕ¡Õ¶ ÕŽÕ¡Õ¿Õ¡Õ¯Õ¡ÖÕ¡ÖÕ« Õ°Õ¥Õ¿Ö
+<li>ÕÕžÖÕ±ÕžÖÕŽ Õ¥Õœ ÕŽÕ«Õ¡Õ¶Õ¡Õ¬ Õ¯Õ¡ÕµÖÕ« ÕºÕ¡Õ·Õ¿ÕºÕ¡Õ¶Õ«Õ¹ ÕºÕ¡Õ¿Õ« Õ°Õ¥Õ¿ÖÕ«Ö (ÕœÕ¡ Õ¡ÕµÕ¶ Õ€Õ¥ÕºÖÕ¶ Õ§ Õ¥ÖÕ¢ Õ€ÕžÖ ÕºÕ¥Õ¿Ö Õ§ ÕŽÕžÖÕ¿Ö Õ¡Õ¶Õ¥Õœ Õ£ÖÕ¡Õ¶ÖÕŽÕ¡Õ¶ Õ¡Õ¶ÕžÖÕ¶ Ö Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡ÕŒ)Ö
+</ul>
+
+<p>Õ¥Õ©Õ¥ ÕœÕ¡ Õ°Õ¥Õ¶Ö Õ¡ÕµÕ¶ URL Õ§, ÕžÖÕš Õ¿Õ¥ÕœÕ¶ÕžÖÕŽ Õ¥Õœ Õ€Õ«Õ¿Õ¡Õ¯ÕžÖÕŽ, Õ°Õ¡ÕŸÕ¡Õ¶Õ¡Õ¯Õ¡Õ¶ Õ§ Õ¡ÕµÕ¶ Õ£Õ¡Õ¬Õ«Õœ Õ§ Õ¿Õ¥Õ²Õ¡ÕµÕ«Õ¶ ÕºÕ¡Õ°ÕŸÕ¡Õ® Õ°Õ«Õ·ÕžÕ²ÕžÖÕ©ÕµÕ¡Õ¶ ÕºÕ¡Õ¿Õ³Õ¥Õ«ÖÖÔŽÕªÕ¢Õ¡Õ­Õ¿Õ¡Õ¢Õ¡Ö, Õ¿Õ¥Õ²Õ¡ÕµÕ«Õ¶ ÕºÕ¡Õ°ÕŸÕ¡Õ® Õ°Õ«Õ·ÕžÕ²ÕžÖÕ©ÕµÕ¡Õ¶ ÕºÕ¡Õ¿Õ³Õ¥Õ¶ Õ¿Õ¥ÕœÕ¡Õ¶Õ¥Õ¬Õ« Õ¹Õ§ Õ°Õ¡ÕµÕ¥Õ¬Õ¡ÕµÕ«Õ¶ Õ£ÕžÖÕ®ÕšÕ¶Õ©Õ¡ÖÕ« Õ°Õ¡ÕŽÕ¡ÖÖÔ±ÕµÕœ Õ€Õ¥ÕºÖÕžÖÕŽ Õ­ÕžÖÕ°ÕžÖÖÕ€ Õ¥Õ¶Ö Õ¿Õ¡Õ¬Õ«Õœ Õ¢Õ¥ÕŒÕ¶Õ¡Õ©Õ¡ÖÕ¥Õ¬ Õ§Õ»Õ¥ÖÕš ÕœÕ¯ÕŠÕ¢Õ¶Õ¡ÕºÕ¥Õœ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬ÕžÕŸ Õ€Õ«Õ¿Õ¡Õ¯ÕšÖ}  
+
+
+
+_textbtco_ [l=hy] {ÕÕ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖ Õ°Õ«ÕŽÕ¶ÕŸÕ¡Õ®}  
+_textand_ [l=hy] {Ô±ÕŸÕ¥Õ¬Õ¡ÖÖÕžÖ Õ¶ÕžÖ Õ¿ÕŸÕµÕ¡Õ¬}  
+_textad_ [l=hy] {ÕÕŸÕµÕ¡Õ¬Õ¶Õ¥ÖÕ« Õ¡ÕŸÕ¥Õ¬Õ¡ÖÕžÖÕŽÖ}  
+
+_texttftysb_ [l=hy] {ÕÕ¥Ö Õ¯ÕžÕ²ÕŽÕ«Ö Õ¶Õ·ÕŸÕ¡Õ® ÖÕ¡ÕµÕ¬Õ¥ÖÕš Õ¯Õ¡ÕŸÕ¥Õ¬Õ¡ÖÕŸÕ¥Õ¶ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ«Õ¶Ö ÕÕ¡ÕŽÕžÕŠÕŸÕ¡Õ® Õ¥Õ²Õ¥Ö ÕžÖ Õ¹Õ¥Ö ÕŸÕ¥ÖÕ¡ÕšÕ¶Õ¿ÖÕžÖÕŽ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕµÕžÖÕŽ Õ¡ÖÕ€Õ¥Õ¶ Õ¡ÕŒÕ¯Õ¡ ÖÕ¡ÕµÕ¬Õ¥ÖÕš. Õ°Õ¡Õ¯Õ¡ÕŒÕ¡Õ¯ Õ€Õ¥ÕºÖÕžÖÕŽ Õ¯ÕœÕ¿Õ¥Õ²Õ®ÕŸÕ« Õ¥ÖÕ¯ÕžÖ Ö
+ÖÕ«Õ¶Õ¡Õ¯Ö ÕÕ¡ÕµÕ¬Õ¥ÖÕš Õ¢Õ¶ÕžÖÕ©Õ¡Õ£ÖÕŸÕžÖÕŽ Õ¥Õ¶ Õ«ÖÕ¥Õ¶Ö Õ¬ÖÕ«ÕŸ ÕžÖÕ²Õ«ÕžÕŸ, ÕžÕœÕ¿Õ¡ÕµÕ¶Õ« Õ§Õ»Õ¥ÖÕš Õ«ÖÕ¥Õ¶Ö Õ¢Õ¡ÖÕ¡ÖÕ±Õ¡Õ¯ ÕÕœÕ¿Õ¡ÕµÕ¶Õ« Õ°Õ¡ÕœÖÕ¥ÕžÕŸÖ}  
+
+
+
+
+
+
+
+_textconf1_ [l=hy] {<p>ÕÕ¥Ö Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« Õ¯Õ¡ÕŒÕžÖÖÕžÖÕŽÕš Ö Õ¶Õ¥ÖÕ¯Õ¡ÕµÕ¡ÖÕžÖÕŽÕš ÕŸÕ¥ÖÕ¡Õ°ÕœÕ¯ÕŸÕžÖÕŽ Õ¥Õ¶ Õ°Õ¡Õ¿ÕžÖÕ¯ ÖÕ¡ÕµÕ¬Õ« Õ¯ÕžÕ²ÕŽÕ«ÖÖ ÕÕžÖÕ±ÕŸÕ¡Õ® Ö
+Õ£Õ¿ÕŸÕžÕ²Õ¶Õ¥ÖÕš Õ¯Õ¡ÖÕžÕ² Õ¥Õ¶ ÖÕ¡Õ¶Õ¯Õ¡Õ¶Õ¡Õ¬ ÖÕžÖÕžÕ­Õ¥Õ¬ÕžÖ Õ¡ÕµÕ€ Õ¡ÖÕªÕ¥ÖÕ¶Õ¥ÖÕšÖ
+
+<center><p><b>ÔµÕ©Õ¥ ÖÕžÖÕ±ÕŸÕ¡Õ® Ö
+Õ£Õ¿ÕŸÕžÕ² Õ¹Õ¥Ö, Õ¡ÕºÕ¡ ÕºÕ¡ÖÕŠÕ¡ÕºÕ¥Õœ Õ£Õ¶Õ¡ Õ§Õ»Õ« ÕŸÕ¥ÖÕ»Ö</b></center> 
+
+<p>ÔžÕ¶Õ€Õ°Õ¡Õ¶ÕžÖÖ Õ¿ÕŸÕµÕ¡Õ¬Õ¶Õ¥ÖÕš ÖÕžÖÕžÕ­Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö Õ­ÕŽÕ¢Õ¡Õ£ÖÕ¥Ö ÕœÕ¿ÕžÖÖ Õ¥Õ²Õ¡Õ® Õ¿ÕŸÕµÕ¡Õ¬Õ¶Õ¥ÖÕšÖ ÔµÕ©Õ¥ ÕœÕ­Õ¡Õ¬ÕŸÕ¥Õ¬ Õ¥Ö, ÕœÕ¥Õ²ÕŽÕ¥Ö "Reset" Õ¯ÕžÕ³Õ¡Õ¯Õš, Õ¶Õ¡Õ­Õ¶Õ¡Õ¯Õ¡Õ¶ Õ¡ÖÕªÕ¥ÖÕ¶Õ¥ÖÕš ÕŸÕ¥ÖÕ¡Õ¯Õ¡Õ¶Õ£Õ¶Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡ÖÖ}  
+
+_textreset_ [l=hy] {ÕÕ¥ÖÕ¡Õ¯Õ¡Õ¶Õ£Õ¶Õ¥Õ¬}  
+
+
+
+
+
+_textstopbuild_ [l=hy] {_wizard:textstopbuild_}  
+
+
+
+
+
+_textbildcancel1_ [l=hy] {_wizard:textbildcancel1_}  
+
+
+
+_textbsupdate2_ [l=hy] {_wizard:textbsupdate2_}  
+_textseconds_ [l=hy] {_wizard:textseconds_}  
+
+
+
+_textfailmsg21_ [l=hy] {_wizard:textfailmsg21_}  
+
+
+_texttryagain_ [l=hy] {ÔœÕ¶Õ€ÖÕŸÕžÖÕŽ Õ§ <a href="_httppagecollector_" target=_top>ÕŸÕ¥ÖÕ¡Õ¢Õ¥ÕŒÕ¶Õ¡ÕŸÕžÖÕ¥Õ¬ Õ°Õ¡ÕŸÕ¡ÖÕ«Õ¹Õš</a>
+Ö ÖÕžÖÕ±Õ¥Õ¬ Õ¶ÕžÖÕ«ÖÖ
+}  
+
+_textfailmsg31_ [l=hy] {_wizard:textfailmsg31_}  
+
+_textfailmsg71_ [l=hy] {_wizard:textfailmsg71_}  
+
+
+
+
+
+_textdelinv_ [l=hy] {_cgiargbc1dirname_ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ ÕºÕ¡Õ·Õ¿ÕºÕ¡Õ¶ÕŸÕ¡Õ® Õ§ Õ¯Õ¡ÕŽ ÕœÕ­Õ¡Õ¬ Õ§Ö ÕÕ¶Õ»Õ¥Õ¬Õš Õ¹Õ¥Õ²Õ¡ÖÕ¯ÕŸÕ¡Õ® Õ§Ö}  
+
+_textdelsuc_ [l=hy] {_cgiargbc1dirname_ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ Õ°Õ¡Õ»ÕžÕ²ÕžÖÕ©ÕµÕ¡ÕŽÕ¢ Õ»Õ¶Õ»ÕŸÕ¥Õ¬ Õ§Ö}  
+
+_textclonefail_ [l=hy] {_cgiargclonecol_ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖ Õ¹Õ§ Õ¯Õ¬ÕžÕ¶Õ¡ÕŸÕžÖÕ¥Õ¬Ö ÕÕ¶Õ¡ÖÕ¡ÕŸÕžÖ ÕºÕ¡Õ¿Õ³Õ¡ÕŒÕ¶Õ¥Ö Õ¯Õ¡ÖÕžÕ² Õ¥Õ¶ Õ¬Õ«Õ¶Õ¥Õ¬Õ
+<ul>
+<li> _cgiargclonecol_ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ Õ£ÕžÕµÕžÖÕ©ÕµÕžÖÕ¶ Õ¹ÕžÖÕ¶Õ«
+<li> _cgiargclonecol_ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ Õ¹ÕžÖÕ¶Õ« collect.cfg Õ¯Õ¡ÕŒÕžÖÖÕŸÕ¡Õ®ÖÕ¡ÕµÕ«Õ¶ ÖÕ¡ÕµÕ¬Õš
+<li> Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õš Õ¹ÕžÖÕ¶Õ« Õ©ÕžÖÕµÕ¬Õ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶ Õ¯Õ¡ÖÕ€Õ¡Õ¬ÕžÖ collect.cfg Õ¯Õ¡ÕŒÕžÖÖÕŸÕ¡Õ®ÖÕ¡ÕµÕ«Õ¶ ÖÕ¡ÕµÕ¬Õš
+</ul>
+}  
+
+
+
+
+
+_textmkcolfail_ [l=hy] {Ô¿ÕžÖÕ¿Õ¡Õ¯Õ«Õ¹Õ«Õ¶ Õ¹Õ°Õ¡Õ»ÕžÕ²ÕŸÕ¥Õ® ÕœÕ¿Õ¥Õ²Õ®Õ¥Õ¬ Õ¶ÕžÖ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« Õ¯ÕžÕ²ÕŽÕ«Ö ÕºÕ¡Õ°Õ¡Õ¶Õ»ÕŸÕžÕ² Õ©Õ²Õ©Õ¡ÕºÕ¡Õ¶Õ¡Õ¯Õ« Õ¯Õ¡ÕŒÕžÖÖÕŸÕ¡Õ®ÖÕš (mkcol.pl failed). ÕÕ¶Õ¡ÖÕ¡ÕŸÕžÖ ÕºÕ¡Õ¿Õ³Õ¡ÕŒÕ¶Õ¥ÖÕ¶ Õ¥Õ¶Õ
+<ul>
+<li> Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õš Õ¹ÕžÖÕ¶Õ« Õ¡ÖÕ¿ÕžÕ¶ÕžÖÕ©ÕµÕžÖÕ¶ Õ£ÖÕ¥Õ¬ÕžÖ _gsdlhome_/tmp
+     Õ©Õ²Õ©Õ¡ÕºÕ¡Õ¶Õ¡Õ¯ÕžÖÕŽÖ
+<li> mkcol.pl perl Õ¯ÕžÕ€Õ« ÕœÕ­Õ¡Õ¬Ö
+</ul>
+}  
+
+
+
+
+
+
+
+_textexptsuc_ [l=hy] {_cgiargbc1dirname_ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶ Õ°Õ¡Õ»ÕžÕ²ÕžÖÕ©ÕµÕ¡ÕŽÕ¢ Õ¡ÖÕ¿Õ¡Õ°Õ¡Õ¶ÕŸÕ¥Õ¬ Õ§ _gsdlhome_/tmp/exported\__cgiargbc1dirname_ Õ©Õ²Õ©Õ¡ÕºÕ¡Õ¶Õ¡Õ¯ÕžÖÕŽÖ
+}  
+
+
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+_textdepositorblurb_ [l=hy] {<p> ÕÕ·Õ£ÖÕ¿ÕžÖÕ¥Õ¶ Õ¢Õ¶ÕžÖÕžÕ·Õ¥Ö Õ°Õ¥Õ¿ÖÕµÕ¡Õ¬ Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õš Ö ÕœÕ¥Õ²ÕŽÕ¥Ö _textintro_ . </p>}  
+
+
+
+
+
+
+
+
+
+
+
+
+_textview_ [l=hy] {_wizard:textview_}  
+
+
+
+
+
+
+
+
+_textbuildcancelled_ [l=hy] {_wizard:textbuildcancelled_}  
+
+
+
+
+
+
+
+_texttryagain_ [l=hy] {ÔœÕ¶Õ€ÖÕŸÕžÖÕŽ Õ§ <a href="_httppagedepositor_" target=_top>ÕŸÕ¥ÖÕ¡Õ£ÕžÖÕ®Õ¡ÖÕ¯Õ¥Õ¬ Õ€Õ¥ÕºÕžÕŠÕ«Õ¿Õ¡ÖÕš Ö </a>ÖÕžÖÕ±Õ¥Õ¬ Õ¶ÕžÖÕ«ÖÖ
+
+}  
+
+
+_textfailmsg41_ [l=hy] {_wizard:textfailmsg41_}  
+
+
+
+
+
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=hy] {Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õš Õ€Õ¡ Õ®ÖÕ¡Õ£ÖÕ¡ÕµÕ«Õ¶ ÕŽÕ«Õ»Õ¡ÕŸÕ¡ÕµÖ Õ§, ÕžÖÕš Õ®Õ¡ÕŒÕ¡ÕµÕžÖÕŽ Õ§ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕ« ÕœÕ¿Õ¥Õ²Õ®ÕŽÕ¡Õ¶ Ö Õ€ÖÕ¡Õ¶Ö ÕœÕºÕ¡ÕœÕ¡ÖÕ¯ÕŽÕ¡Õ¶ Õ°Õ¡ÕŽÕ¡ÖÖÔ±ÕµÕ¶ Õ¿ÖÕ¡ÕŽÕ¡Õ€ÖÕžÖÕŽ Õ§ Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Õ¿ÕŸÕžÖÕ©ÕµÕ¡Õ¶ Õ¯Õ¡ÕŠÕŽÕ¡Õ¯Õ¥ÖÕºÕŽÕ¡Õ¶ Ö Õ¡ÕµÕ¶ Ô»Õ¶Õ¿Õ¥ÖÕ¶Õ¥Õ¿ÕžÖÕŽ Õ¯Õ¡ÕŽ Õ­Õ¿Õ¡ÕœÕ¡Õ¬Õ«Õ¯Õ« ÕŸÖÕ¡ Õ°ÖÕ¡Õ¿Õ¡ÖÕ¡Õ¯Õ¥Õ¬ÕžÖ Õ¶ÕžÖ Õ¥Õ²Õ¡Õ¶Õ¡Õ¯ÖÔ³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õš Õ©ÕžÕ²Õ¡ÖÕ¯ÕŸÕ¡Õ® Õ§ ÕÕ¡ÕµÕ¯Õ¡Õ¿ÕžÕµÕ« Õ°Õ¡ÕŽÕ¡Õ¬ÕœÕ¡ÖÕ¡Õ¶ÕžÖÕŽÕ ÕÕžÖ Ô¶Õ¥Õ¬Õ¡Õ¶Õ€Õ¡Õ¯Õ¡Õ¶ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶ Õ¶Õ¡Õ­Õ¡Õ£Õ®Õ« Õ·ÖÕ»Õ¡Õ¶Õ¡Õ¯Õ¶Õ¥ÖÕžÖÕŽ, Ö Õ¿Õ¡ÖÕ¡Õ®ÕŸÕžÖÕŽ Õ§ Õ
+ÕÕÕÔµÕÔ¿Õ-Õ« Ö ÕÕµÕžÖÕŽÕ¡Õ¶ Õ«Õ¶ÖÕž Õ°Õ¡ÕœÕ¡ÖÕ¡Õ¯Õ¡Õ¯Õ¡Õ¶ Õ¯Õ¡ÕŠÕŽÕ¡Õ¯Õ¥ÖÕºÕžÖÕ©ÕµÕ¡Õ¶ Õ°Õ¥Õ¿ Õ°Õ¡ÕŽÕ¡Õ¿Õ¥Õ²ÖÔ±ÕµÕ¶ Ô²Õ¡Ö Ô¿ÕžÕ€Õ¥ÖÕžÕŸ Õ®ÖÕ¡Õ£ÖÕ¡Õ·Õ¡Ö Õ§, ÕŽÕ¡Õ¿Õ¹Õ¥Õ¬Õ« <i>http://greenstone.org</i> GNU Õ°Õ¡ÕŽÕšÕ¶Õ€Õ°Õ¡Õ¶ÕžÖÖ Õ°Õ¡Õ¶ÖÕ¡ÕµÕ«Õ¶ Õ¡ÖÕ¿ÕžÕ¶Õ¡Õ£ÖÕ« ÕºÕ¡ÕµÕŽÕ¡Õ¶Õ¶Õ¥ÖÕ« Õ°Õ¡ÕŽÕ¡Õ±Õ¡ÕµÕ¶Ö}  
+
+_textgreenstone2_ [l=hy] {ÕÕžÖ Ô¶Õ¥Õ¬Õ¡Õ¶Õ€Õ¡Õ¯Õ¡Õ¶ Õ©ÕŸÕ¡ÕµÕ«Õ¶ Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ« Õ¯Õ¡ÕµÖ (<a
+href="http://nzdl.org">http://nzdl.org</a>) ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ§ Õ¢Õ¡ÕŠÕŽÕ¡Õ©Õ«ÕŸ Ö
+ÖÕ«Õ¶Õ¡Õ¯Õ¥Õ¬Õ« Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥Ö, Õ¢ÕžÕ¬ÕžÖÕš ÕœÕ¿Õ¥Õ²Õ®ÕŸÕ¡Õ® Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õ« Õ®ÖÕ¡Õ£ÖÕ¡ÕµÕ«Õ¶ ÕŽÕ«Õ»Õ¡ÕŸÕ¡ÕµÖÕžÖÕŽ, Ö Õ¡ÕµÕœ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕš ÕŽÕ¡Õ¿Õ¹Õ¥Õ¬Õ« Õ¥Õ¶ ÕžÖÕ·Õ¡Õ€Õ«Ö ÕŠÕ¶Õ¶ÕŽÕ¡Õ¶ Õ°Õ¡ÕŽÕ¡ÖÖ ÔŽÖÕ¡Õ¶Ö ÖÕžÖÖÕ¡Õ€ÖÕžÖÕŽ Õ¥Õ¶ ÕžÖÕžÕ¶ÕŽÕ¡Õ¶ Ö Õ€Õ«Õ¿ÕŽÕ¡Õ¶ Õ¿Õ¡ÖÕ¢Õ¥Ö Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš, Ö ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ¥Õ¶ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥Ö Ô±ÖÕ¡Õ¢Õ¥ÖÕ¥Õ¶, ÕÕ«Õ¶Õ¡ÖÕ¥Õ¶, ÕÕ¡ÕžÖÕ«, Ô»ÕœÕºÕ¡Õ¶Õ¥ÖÕ¥Õ¶ Õ«Õ¶Õ¹ÕºÕ¥Õœ Õ¶Õ¡Ö Ô±Õ¶Õ£Õ¬Õ¥ÖÕ¥Õ¶ Õ¬Õ¥ÕŠÕžÖÕ¶Õ¥ÖÕžÕŸÖ Ô±ÕµÕœÕ¿Õ¥Õ² Õ¯Õ¡Õ¶ Õ¶Õ¡Ö ÕžÖÕžÕ· Õ¥ÖÕ¡ÕªÕ·Õ¿Õ¡Õ¯Õ¡Õ¶ Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÖ}  
+
+_textplatformtitle_ [l=hy] {ÕºÕ¬Õ¡Õ¿ÖÕžÖÕŽ}  
+_textgreenstone3_ [l=hy] {Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õš Õ¡Õ·Õ­Õ¡Õ¿ÕžÖÕŽ Õ§ ÕÖÕ«Õ¶Õ€ÕžÕŠ, Õ
+ÕžÖÕ¶Õ«ÖÕœ, Ö ÕÕ¡Ö OS X ÕŽÕ«Õ»Õ¡ÕŸÕ¡ÕµÖÕ¥ÖÕžÖÕŽÖ Ô±ÕŒÕ¡ÖÕŸÕžÖÕŽ Õ§ ÕÖÕ«Õ¶Õ€ÕžÕŠ, Õ
+ÕžÖÕ¶Õ«ÖÕœ, Ö ÕÕ¡Ö OS X ÕŽÕ«Õ»Õ¡ÕŸÕ¡ÕµÖÕ¥ÖÕžÖÕŽ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕŽÕ¡Õ¶ Õ°Õ¡ÕŽÕ¡Ö ÕºÕ¡Õ¿ÖÕ¡ÕœÕ¿Õ« Õ¯ÕžÕ€Õ¥ÖÕžÕŸÖ ÕÕ¥ÖÕ¡ÕŒÕžÖÕŽ Õ§ Õ¶Õ¡Ö Õ°Õ¡ÕŽÕ¡Õ¯Õ¡ÖÕ£Õ« ÕžÕ²Õ» ÕœÕ¯ÕŠÕ¢Õ¶Õ¡Õ¯Õ¡Õ¶ Õ¯ÕžÕ€Õ¥ÖÕš, ÕžÖÕš Õ¯Õ¡ÖÕ¥Õ¬Õ« Õ§ Õ¯ÕžÕŽÕºÕ«Õ¬Õ¡ÖÕ¶Õ¥Õ¬ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬ÕžÕŸ ÕÕ¡ÕµÖÖÕžÕœÕžÖÕ© C++ or gcc.  Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õš Õ¡Õ·Õ­Õ¡Õ¿ÕžÖÕŽ Õ§ Õ¶Õ¡Ö Õ¡ÕŠÕ¡Õ¿ ÕŽÕ¡Õ¿Õ¹Õ¥Õ¬Õ« Ö
+ÕªÕ¡Õ¶Õ€Õ¡Õ¯ Õ®ÖÕ¡Õ£ÖÕ¥ÖÕ« Õ°Õ¥Õ¿. Apache Ö PERL. ÕÕ£Õ¿ÕŸÕžÕ²Õ« ÕŽÕ«Õ»Õ¥ÖÕ¥ÕœÕš Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕžÖÕŽ Õ§ ÕžÕœÕ¿Õ¡ÕµÕ¶Õ« Õ€Õ«Õ¿Õ¡Õ¯Õ ÕœÕžÕŸÕžÖÕ¡Õ¢Õ¡Ö Netscape Navigator Õ¯Õ¡ÕŽ Internet Explorer.
+}  
+
+
+
+
+
+
+
+_textdocuments_ [l=hy] {Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ°Õ¡ÕŽÕ¡Õ¯Õ¡ÖÕ£Õ« Õ°Õ¡ÕŽÕ¡Ö Õ¯Õ¡ ÕšÕ¶Õ€Õ¡ÖÕ±Õ¡Õ¯ Õ±Õ¥ÕŒÕ¶Õ¡ÖÕ¯Ö}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+
+_textmailinglist_ [l=hy] {Ô³ÕžÕµÕžÖÕ©ÕµÕžÖÕ¶ ÕžÖÕ¶Õ« Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ°Õ¡ÕŽÕ¡Õ¯Õ¡ÖÕ£Õ« ÖÕ¶Õ¶Õ¡ÖÕ¯ÕžÖÕŽÕ¶Õ¥ÖÕ« Õ­ÕžÖÕŽÕ¢Ö Ô±Õ¯Õ¿Õ«ÕŸ ÕŽÕ¡ÕœÕ¶Õ¡Õ¯Õ«ÖÕ¶Õ¥ÖÕš ÕºÕ¥Õ¿Ö Õ§ Õ¡Õ»Õ¡Õ¯ÖÕ¥Õ¶ ÕŽÕ¡ÕœÕ¶Õ¡Õ¯ÖÕ¥Õ¬ÕžÕŸ ÖÕ¶Õ¶Õ¡ÖÕ¯ÕžÖÕŽÕ¶Õ¥ÖÕ«Õ¶ÖÔ²Õ¡ÕªÕ¡Õ¶ÕžÖÕ€Õ¡Õ£ÖÕŸÕ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö, Õ¡ÕµÖÕ¥Õ¬Õ¥Ö  <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+
+ÕÕ¶Õ¶Õ¡ÖÕ¯ÕžÖÕŽÕ¶Õ¥ÖÕ« ÖÕžÖÖÕ¡Õ¯Õ«Õ¶ Õ°Õ¡Õ²ÕžÖÕ€Õ¡Õ£ÖÕžÖÕ©ÕµÕžÖÕ¶ ÕžÖÕ²Õ¡ÖÕ¯Õ¥Õ¬ÕžÖ Õ¶ÕºÕ¡Õ¿Õ¡Õ¯ÕžÕŸ, Õ°Õ¡ÕœÖÕ¥Õ¡Õ£ÖÕ¥Ö Õ¡ÕµÕ¶  <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>.
+}  
+
+
+
+
+
+
+
+
+
+
+
+_textaboutgslong_ [l=hy] {Õ£ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ®ÖÕ¡Õ£ÖÕ¡Õ·Õ¡ÖÕ« ÕŽÕ¡ÕœÕ«Õ¶}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textuser_ [l=hy] {Ö
+Õ£Õ¿ÕŸÕžÕ²}  
+
+_textgroups_ [l=hy] {Õ­ÕŽÕ¢Õ¥Ö}  
+
+
+
+_textdeleteuser_ [l=hy] {Õ°Õ¥ÕŒÕ¡ÖÕ¶Õ¥Õ¬}  
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=hy] {ÔœÕŽÕ¢Õ¡Õ£ÖÕ¥Õ¬ Ö
+Õ£Õ¿ÕŸÕžÕ²Õ« Õ¿ÕŸÕµÕ¡Õ¬Õ¶Õ¥ÖÕš}  
+
+
+
+
+
+
+
+
+_textdisabled_ [l=hy] {Õ¯Õ¡ÕœÕ¥ÖÕŸÕ¡Õ® Õ§}  
+
+
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=hy] {ÕÕ¥ÕŒÕ¡ÖÕ¶Õ¥Õ¬ Ö
+Õ£Õ¿ÕŸÕžÕ²Õ«Õ¶}  
+
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+_textnewpw_ [l=hy] {Õ¶ÕžÖ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡ÕŒ}  
+_textretype_ [l=hy] {Õ¶ÕžÖÕ«Ö ÕŽÕžÖÕ¿Ö Õ¡ÖÕ¥Ö Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡ÕŒÕš}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=hy] {ÕÕ¥Ö Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡ÕŒÕš Õ°Õ¡Õ»ÕžÕ²ÕžÖÕ©ÕµÕ¡ÕŽÕ¢ ÖÕžÖÕžÕ­ÕŸÕ¥Õ¬ Õ§Ö}  
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=hy] {ÕÕ­Õ¡Õ¬ ÕÕ£Õ¿ÕŸÕžÕ²Õ« Õ¡Õ¶ÕžÖÕ¶Ö}  
+
+_textemptypassword_ [l=hy] {ÕÕžÖÕ¿Ö Õ¡ÖÕ¥Ö Õ¡ÕµÕœ Ö
+Õ£Õ¿ÕŸÕžÕ²Õ« ÕœÕ¯ÕŠÕ¢Õ¶Õ¡Õ¯Õ¡Õ¶ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡ÕŒÕšÖ}  
+
+
+
+_textpasswordempty_ [l=hy] {ÕÕ¥Õ¿Ö Õ§ ÕŽÕžÖÕ¿Ö Õ¡Õ¶Õ¥Ö Õ°Õ«Õ¶ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡ÕŒÕšÖ}  
+
+_textnewpassmismatch_ [l=hy] {ÕÕ¥Ö Õ¶ÕžÖ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡ÕŒÕ« Õ¥ÖÕ¯ÕžÖ Õ¿Õ¡ÖÕ¢Õ¥ÖÕ¡Õ¯Õ¶Õ¥ÖÕš Õ¹Õ¥Õ¶ Õ°Õ¡ÕŽÕšÕ¶Õ¯Õ¶ÕžÖÕŽÖ}  
+_textnewinvalidpassword_ [l=hy] {ÕÕžÖÕ¿Ö Õ¥Ö Õ¡ÖÕ¥Õ¬ ÕœÕ­Õ¡Õ¬ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡ÕŒÖ}  
+_textfailed_ [l=hy] {ÕÕ£Õ¿ÕŸÕžÕ²Õ« Õ¡Õ¶ÕžÖÕ¶Õš Õ¯Õ¡ÕŽ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡ÕŒÕš ÕœÕ­Õ¡Õ¬ Õ¥Õ¶Ö}  
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+_textusermanage_ [l=hy] {ÕÕ£Õ¿Õ¡Õ£ÕžÖÕ®ÕžÕ²Õ« Õ¯Õ¡ÕŒÕ¡ÕŸÕ¡ÖÕžÖÕŽ}  
+
+_textaddusers_ [l=hy] {Õ¡ÕŸÕ¥Õ¬Õ¡ÖÖÕžÖ Õ¶ÕžÖ Ö
+Õ£Õ¿ÕŸÕžÕ²}  
+
+
+_textgeneral_ [l=hy] {ÕšÕ¶Õ€Õ°Õ¡Õ¶ÕžÖÖ}  
+_textarguments_ [l=hy] {ÖÕ¡ÕœÕ¿Õ¡ÖÕ¯Õ¶Õ¥Ö}  
+_textactions_ [l=hy] {Õ£ÕžÖÕ®ÕžÕ²ÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö}  
+
+_textprotocols_ [l=hy] {Õ°Õ¡ÕŽÕ¡Õ±Õ¡ÕµÕ¶Õ¡Õ£ÖÕ¥Ö}  
+_textconfigfiles_ [l=hy] {ÕÖÕ¡ÕŸÕžÖÕŽÕ¡Õ¶ ÖÕ¡ÕµÕ¬Õ¥Ö}  
+_textlogs_ [l=hy] {Ô³ÖÕ¡Õ¶ÖÕžÖÕŽÕ¶Õ¥Ö}  
+_textusagelog_ [l=hy] {Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®ÕŽÕ¡Õ¶ Õ£ÖÕ¡Õ¶ÖÕžÖÕŽÕ¶Õ¥Ö}  
+
+
+_textadminhome_ [l=hy] {Õ¡Õ€ÕŽÕ«Õ¶Õ«ÕœÕ¿ÖÕ¡Õ¿ÕžÖÕ« Õ§Õ»}  
+_textreturnhome_ [l=hy] {Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Õ¿Õ¶Õ¡ÕµÕ«Õ¶ Õ§Õ»}  
+
+
+
+
+
+
+
+
+
+
+_textcwoa_ [l=hy] {ÕÕ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕš Õ¯Õ¥ÖÖÕ¡Õ¶ "Õ¯Õ¡Õ¿Õ¡ÖÕŸÕžÕ²" Õ¥Õ©Õ¥ Õ€ÖÕ¡Õ¶Ö build.cfg ÖÕ¡ÕµÕ¬Õ¥ÖÕš Õ£ÕžÕµÕžÖÕ©ÕµÕžÖÕ¶ ÕžÖÕ¶Õ¥Õ¶, Õ¯Õ¡ÖÕ€Õ¡ÖÕŸÕžÕ² Õ¥Õ¶, ÕºÕ¡ÖÕžÖÕ¶Õ¡Õ¯ÕžÖÕŽ Õ¥Õ¶ ÕœÕ¿Õ¥Õ²Õ®ÕŽÕ¡Õ¶ Õ¡ÕŽÕœÕ¡Õ©ÕŸÕ« Õ€Õ¡Õ·Õ¿Õš Õ«ÖÕ¡Õ¯Õ¡Õ¶ Õ§ ( > 0), Ö Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥ÖÕ« Õ«Õ¶Õ€Õ¥ÖÕœÕ« Õ©Õ²Õ©Õ¡ÕºÕ¡Õ¶Õ¡Õ¯ÕžÖÕŽ Õ¥Õ¶ (Õ¡ÕµÕœÕ«Õ¶ÖÕ¶ Õ¹Õ¥Õ¶ Õ£Õ¿Õ¶ÕŸÕžÖÕŽ Õ¯Õ¡ÕŒÕ¡ÖÕŽÕ¡Õ¶ Õ©Õ²Õ©Õ¡ÕºÕ¡Õ¶Õ¡Õ¯ÕžÖÕŽ)Ö}  
+
+
+
+_textsubc_ [l=hy] {ÕÕ¡ÕœÕ¿Õ¡Õ¿Õ¥Ö ÖÕžÖÕžÕ­ÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕš}  
+_texteom_ [l=hy] {ÕÕ­Õ¡Õ¬ main.cfg Õ¢Õ¡ÖÕ¥Õ¬Õ«ÕœÖ}  
+
+
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=hy] {Ô¿Õ¡ÕŒÕžÖÖÕ«Ö "_collectionname_" Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ« Õ°Õ¡ÕŽÕ¡ÕŒÕžÕ¿Õ¡Õ£ÖÕžÖÕ©ÕµÕžÖÕ¶ÕšÖ}  
+
+
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+
+
+
+
+_textwhy_ [l=hy] {<p>ÕÖÕ²Õ¡ÖÕ¯Õ¥Õ¬ÕžÕŸ Õ¡ÕµÕœ Õ°Õ¡Õ·ÕŸÕ¥Õ¿ÕŸÕžÕŽÕ©ÕµÕžÖÕ¶Õš ÕŽÕ« ÕŽÕ«Õ»ÕžÖ Õ§ Õ¿Õ¥Õ²Õ¥Õ¯Õ¡ÖÕ¶Õ¥Õ¬ÕžÖ, ÕžÖ Õ¡ÕµÕœ Õ¯Õ¡ÕµÖÕš Õ¢Õ¡ÖÕ€ Õ§ Õ¯Õ¡ÕŽ Õ°Õ«Õ¡ÕœÕ©Õ¡ÖÕ¥ÖÕ¶ÕžÕ²Ö
+}  
+
+
+
+
+
+
+_textno_ [l=hy] {ÕÕ¹}  
+
+
+_textprivacy_ [l=hy] {ÕÕ¡ÕœÕ¶Õ¡ÕŸÕžÖ}  
+
+
+_textoptionally_ [l=hy] {ÕÕ¹ ÕºÕ¡ÖÕ¿Õ¡Õ€Õ«Ö}  
+
+_textunderdev_ [l=hy] {Õ¶Õ¡Õ­Õ¶Õ¡Õ¯Õ¡Õ¶ Õ€Õ«Õ¿ÕŽÕ¡Õ¶ ÕŽÕ¡Õ¶ÖÕ¡ÕŽÕ¡ÕœÕ¶Õ¥ÖÕš ÕŽÕ¡Õ¿Õ¹Õ¥Õ¬Õ« Õ¯Õ¬Õ«Õ¶Õ¥Õ¶ ÕŸÕ¥ÖÕ»Õ¶Õ¡Õ¯Õ¡Õ¶ Õ¿Õ¡ÖÕ¢Õ¥ÖÕ¡Õ¯ÕžÖÕŽÖ}  
+
+
+_textmoredetails_ [l=hy] {ÕÕ¡Õ¶ÖÕ¡ÕŽÕ¡ÕœÕ¶Õ¥Ö}  
+_texttrackreport_ [l=hy] {ÕÕœÕ¯Õ¥Ö Õ¡ÕµÕœ Õ°Õ¡Õ·ÕŸÕ¥Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õš}  
+
+
+ 
+_textbadrender_ [l=hy] {Ô·Õ»Õš Õ€Õ«Õ¿ÕŸÕžÖÕŽ Õ§ Õ¿Õ¡ÖÕžÖÕ«Õ¶Õ¡Õ¯}  
+_textcontenterror_ [l=hy] {Ô²ÕžÕŸÕ¡Õ¶Õ€Õ¡Õ¯ÕžÖÕ©ÕµÕ¡Õ¶ ÕœÕ­Õ¡Õ¬}  
+_textstrangebehaviour_ [l=hy] {ÕÕ¡ÖÖ
+ÖÕ«Õ¶Õ¡Õ¯ ÕºÕ¡Õ°ÕŸÕ¡Õ®Ö}  
+
+_textfunctionality_ [l=hy] {ÔŽÕªÕŸÕ¡Ö Õ§ Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬}  
+
+
+
+_textmajor_ [l=hy] {ÔŒÕžÖÖÕ»}  
+
+
+_texttrivial_ [l=hy] {Ô±Õ¶Õ¶Õ·Õ¡Õ¶}  
+
+
+_textwhatexpected_ [l=hy] {Ô»ÕÕ¶Õ¹ Õ¥Ö Õ¡Õ¯Õ¶Õ¯Õ¡Õ¬ÕžÖÕŽ ÕžÖ Õ¿Õ¥Õ²Õ« Õ¯ÕžÖÕ¶Õ¥Õ¶Õ¡Ö}  
+
+
+_cannotfindcgierror_ [l=hy] {<h2>ÕÕ¡ÕŸÕžÖÕŽ Õ¥ÕŽ!<h2>ÕÕ¥ÕŽ Õ¯Õ¡ÖÕžÕ² Õ£Õ¿Õ¶Õ¥Õ¬ ÕœÕ¥ÖÕŸÕ¥ÖÕ¡ÕµÕ«Õ¶ Õ®ÖÕ¡Õ£Õ«ÖÕš "_linktextusab_" Õ¯ÕžÕ³Õ¡Õ¯Õ« Õ°Õ¡ÕŽÕ¡ÖÖ}  
+
+
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=hy] {ÕÕ¡ÕµÕ¿Õ¶Õ¡Õ¢Õ¥ÖÕŸÕ¥Õ¬ Õ§ ÕœÕ­Õ¡Õ¬}  
+
+
+
+
+
+
+
+_textgticoredm_ [l=hy] {Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õ« ÕŽÕ«Õ»Õ¥ÖÕ¥Õœ (Õ°Õ«ÕŽÕ¶Õ¡Õ¯Õ¡Õ¶)}  
+_textgtiauxdm_ [l=hy] {Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ ÕŽÕ«Õ»Õ¥ÖÕ¥Õœ (Õ¥ÖÕ¯ÖÕžÖÕ€Õ¡Õ¯Õ¡Õ¶)}  
+
+_textgtiglihelp_ [l=hy] {GLI ÕÕ£Õ¶ÕžÖÕ©ÕµÕžÖÕ¶}  
+
+_textgtitutorials_ [l=hy] {ÕÖÕœÕžÖÖÕžÕ²Õ¡Õ¯Õ¡Õ¶ ÕŸÕ¡ÖÕªÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö}  
+_textgtigreenorg_ [l=hy] {Greenstone.org}  
+
+
+
+_textgticorrectexistingtranslations_ [l=hy] {ÕÖÕ²Õ²Õ«Ö Õ¡ÕŒÕ¯Õ¡ Õ©Õ¡ÖÕ£ÕŽÕ¡Õ¶ÕžÖÕ©ÕµÕžÖÕ¶Õš}  
+
+
+
+
+
+
+
+
+
+
+_textgtifind_ [l=hy] {Ô³ÕÔ»Õ}  
+
+_textgtitranslatingchunk_ [l=hy] {ÕÕ¥ÖÕœÕ¿Õ« Õ°Õ¡Õ¿ÕŸÕ¡Õ®Õ« Õ©Õ¡ÖÕ£ÕŽÕ¡Õ¶ÕžÖÕ©ÕµÕžÖÕ¶ <i>_1_</i>}  
+
+
+
+_textgtilastupdated_ [l=hy] {ÕÕ¥ÖÕ»Õ«Õ¶ Õ©Õ¡ÖÕŽÕ¡ÖÕžÖÕŽ}  
+
+_textgtitranslationfilecomplete_ [l=hy] {ÕÕ¶ÕžÖÕ°Õ¡Õ¯Õ¡Õ¬ÕžÖÕ©ÕµÕžÖÕ¶ Õ¡ÕµÕœ ÖÕ¡ÕµÕ¬Õš Õ©Õ¡ÖÕŽÕ¡ÖÕ¶Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡ÖÖ Ô±ÕµÕ¶ Õ°Õ«ÕŽÕ¡ Õ¡ÕŽÕ¢ÕžÕ²Õ»Õ¡Õ¯Õ¡Õ¶ Õ§Ö <p>Ô¿Õ¡ÖÕžÕ² Õ¥Õœ Õ¢Õ¥ÕŒÕ¶Õ¡Õ©Õ¡ÖÕ¥Õ¬ Õ¡ÕµÕœ ÖÕ¡ÕµÕ¬Õ« ÕºÕ¡Õ¿Õ³Õ¥Õ¶Õš, Ö
+Õ£Õ¿Õ¡Õ£ÕžÖÕ®Õ¥Õ¬ÕžÕŸ ÕŸÕ¥ÖÖÕžÖÕŽ Õ¢Õ¥ÖÕŸÕ¡Õ® Õ¯Õ¡ÕºÕš, Ö Õ¡ÕµÕ¶ Õ¶ÕžÖÕµÕ¶ÕºÕ¥Õœ Õ¯ÕšÕ¶Õ€Õ£ÖÕ¯ÕŸÕ« Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õ« Õ°Õ¥Õ¿Õ¡Õ£Õ¡ Õ©ÕžÕ²Õ¡ÖÕ¯ÕžÖÕŽÕ¶Õ¥ÖÕžÖÕŽÖ}  
+
+
+############
+# gli page
+############
+package gli
+
+
+_textglihelp_ [l=hy] {<p>Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õ« Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ¡ÕŸÕ¡ÖÕ« ÕŽÕ«Õ»Õ¥ÖÕ¥ÕœÕš (Ô³Ô³Õ) Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶ Õ§ ÕšÕ¶Õ±Õ¥ÕŒÕžÖÕŽ ÕžÖÕ¶Õ¥Õ¶Õ¡Õ¬ Õ°Õ¥Õ·Õ¿ ÕŽÕžÖÕ¿Ö Õ€Õ¥ÕºÕ« Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õ« ÖÕžÖÕ¶Õ¯ÖÕ«ÕžÕ¶Õ¡Õ¬ Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥ÖÕšÖ ÕÕ¡ Õ°Õ¶Õ¡ÖÕ¡ÕŸÕžÖÕžÖÕ©ÕµÕžÖÕ¶ Õ§ ÕšÕ¶Õ±Õ¥ÕŒÕžÖÕŽ Õ°Õ¡ÕŸÕ¡ÖÕ¥Õ¬ ÖÕ¡ÕœÕ¿Õ¡Õ©Õ²Õ©Õ¥ÖÕ« Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÕ¶Õ¥Ö, Õ¶Õ¥ÖÕŽÕžÖÕ®Õ¥Õ¬ Õ¯Õ¡ÕŽ Õ¶Õ·Õ¡Õ¶Õ¡Õ¯Õ¥Õ¬ ÕŽÕ¥Õ¿Õ¡Õ¿ÕŸÕµÕ¡Õ¬Õ¶Õ¥Ö, Ö Õ¯Õ¡ÕŒÕžÖÖÕ¥Õ¬ Õ€ÖÕ¡Õ¶Ö ÕžÖÕºÕ¥Õœ Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õ« Õ°Õ¡ÕŸÕ¡ÖÕ¡Õ®ÕžÖÖ</p>
+
+<p>ÕÕ¯Õ¡Õ¿Õ« ÕžÖÕ¶Õ¥ÖÕ¥Ö ÕžÖ Ô³Ô³Õ Õ¡Õ·Õ­Õ¡Õ¿ÕžÖÕŽ Õ§ Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õ« Õ°Õ¥Õ¿ Õ°Õ¡ÕŽÕ¡Õ¿Õ¥Õ², Ö Õ¥Õ¶Õ©Õ¡Õ€ÖÕŸÕžÖÕŽ Õ§ ÕžÖ Õ¡ÕµÕ¶ Õ¿Õ¥Õ²Õ¡Õ€ÖÕŸÕ¡Õ® Õ§ Õ¶ÕžÖÕµÕ¶ Õ©Õ²Õ©Õ¡ÕºÕ¡Õ¶Õ¡Õ¯ÕžÖÕŽ, ÕžÖÕ¿Õ¥Õ² Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶Õ¶ Õ§ Õ¿Õ¥Õ²Õ¡Õ€ÖÕŸÕ¡Õ®Ö ÔµÕ©Õ¥ </p>
+
+<h4>Ô³Ô³Õ-Õ« Õ¡Õ·Õ­Õ¡Õ¿Õ¥ÖÕ¶Õ¥Õ¬Õš ÕÖÕ«Õ¶Õ€ÕžÕŠ ÕŽÕ«Õ»Õ¡ÕŸÕ¡ÕµÖÕžÖÕŽ</h4>
+ 
+Ô²Õ¥ÕŒÕ¶Õ¡ÕŸÕžÖÕ¥Ö Õ£ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ¡ÕŸÕ¡ÖÕ¡Õ« ÕŽÕ«Õ»Õ¥ÖÕ¥ÕœÕš ÕšÕ¶Õ¿ÖÕ¥Õ¬ÕžÕŸ <i>Ô³ÖÕ«Õ¶ÕœÕ©ÕžÕžÖÕ¶ Ô¹ÕŸÕ¡ÕµÕ«Õ¶ Ô³ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶</i>  <i>ÔŸÖÕ¡Õ£ÖÕ¥Ö</i> Õ­ÕŽÕ¢Õ«Ö <i>ÕÕ¯ÕœÕ¥Õ¬ Start</i> ÕšÕ¶Õ¿ÖÕ¡ÖÕ¡Õ¶Õ¯Õ«Ö, Ö ÕšÕ¶Õ¿ÖÕ¥Õ¬ÕžÕŸ <i>Ô³ÖÕ¡Õ€Õ¡ÖÕ¡Õ¶Õ¡ÕŸÕ¡ÖÕ« ÕÕ«Õ»Õ¥ÖÕ¥Õœ</i>Ö 
+
+<h4>Ô³Ô³Õ-Õ« Õ¡Õ·Õ­Õ¡Õ¿Õ¥ÖÕ¶Õ¥Õ¬Õš Õ
+ÕžÖÕ¶Õ«ÖÕœ ÕŽÕ«Õ»Õ¡ÕŸÕ¡ÕµÖÕžÖÕŽ</h4>
+
+Õ
+ÕžÖÕ¶Õ«ÖÕœ ÕŽÕ«Õ»Õ¡ÕŸÕ¡ÕµÖÕžÖÕŽ Õ¡Õ·Õ­Õ¡Õ¿Õ¥Õ¬ÕžÖ Õ°Õ¡ÕŽÕ¡Ö Õ¿Õ¥Õ²Õ¡ÖÕžÕ­ÕŸÕ¥Ö <i>gli</i> Õ©Õ²Õ©Õ¡ÕºÕ¡Õ¶Õ¡Õ¯, Õ¡ÕºÕ¡ Õ¡Õ·Õ­Õ¡Õ¿Õ¥ÖÖÕ¥Ö <i>gli.sh</i> Õ®ÖÕ¡Õ£Õ«ÖÕšÖ 
+
+<h4>Ô³Ô³Õ-Õ« Õ¡Õ·Õ­Õ¡Õ¿Õ¥ÖÕ¶Õ¥Õ¬Õš Mac OS X ÕŽÕ«Õ»Õ¡ÕŸÕ¡ÕµÖÕžÖÕŽ</h4>
+
+ÕÕ¥Õ²Õ¡ÖÕžÕ­ÕŸÕ¥Ö Õ€Õ¥ÕºÕ« <i>Applications</i> Õ¡ÕºÕ¡ <i>Greenstone</i> (Õ¥Õ©Õ¥ Õ¿Õ¥Õ²Õ¡Õ€ÖÕ¥Õ¬ Õ¥Ö Õ¬ÕŒÕ¡Õ¯ÕµÕ¡Ö Õ©Õ²Õ©Õ¡ÕºÕ¡Õ¶Õ¡Õ¯ÕžÖÕŽ), Õ¡ÕºÕ¡ Õ¢Õ¥ÕŒÕ¶Õ¡ÕŸÕžÖÕ¥Ö <i>GLI</i> Õ¯Õ«ÖÕ¡ÕŒÕžÖÕ©ÕµÕžÖÕ¶ÕšÖ
+}  
Index: /gsdl/stable/macros/authen.dm
===================================================================
--- /gsdl/stable/macros/authen.dm	(revision 20131)
+++ /gsdl/stable/macros/authen.dm	(revision 20131)
@@ -0,0 +1,65 @@
+# this file must be UTF-8 encoded
+
+package authen
+
+#######################################################################
+# page content                     
+#######################################################################
+
+_pagetitle_ {_textGSDLtitle_}
+
+_content_ {
+<br><br><br><br>
+<form name="login" method="get" action="_gwcgi_">
+<input type=hidden name="e" value="_If_(_cgiarger_,_cgiarger_,_decodedcompressedoptions_)">
+_hiddenargs_
+<center><table width="_pagewidth_">
+<tr><td>
+_messagestatus_
+</td></tr>
+
+<tr><td>
+<table><tr><td>_textusername_</td>
+<td><input type="text" name="un" value="_cgiargun_" size=10></td>
+<td></td></tr>
+<tr><td>_textpassword_</td>
+<td><input type="password" name="pw" size="10"></td>
+<td><input type="submit" value="_textsignin_"></td>
+</tr>
+</table>
+</td></tr>
+</table>
+</center>
+</form>
+}
+
+
+_messageinvalid_ {_textmessageinvalid_}
+
+_messagefailed_ {_textmessagefailed_}
+
+_messageenabled_ {}
+
+_messagedisabled_ {_textmessagedisabled_}
+
+_messagepermissiondenied_ {_textmessagepermissiondenied_}
+
+_messagestalekey_ {_textmessagestalekey_}
+
+
+#################################
+# when authentication is accepted
+#################################
+
+package authenok
+
+
+#######################################################################
+# page content                     
+#######################################################################
+
+_pagetitle_ {_authen:textGSDLtitle_}
+
+_content_ {
+_authen:messagestatus_
+}
Index: /gsdl/stable/macros/base.dm
===================================================================
--- /gsdl/stable/macros/base.dm	(revision 20131)
+++ /gsdl/stable/macros/base.dm	(revision 20131)
@@ -0,0 +1,403 @@
+# this file must be UTF-8 encoded
+#######################################################################
+# GLOBAL MACROS 
+#######################################################################
+
+package Global
+
+##########
+
+_optsite_ {}
+
+
+##########
+
+_htmlextra_ {}
+
+# now defined in nav_css/nav_ns4 macro files
+#_starthighlight_ {<b><u>}
+#_endhighlight_ {</u></b>}
+
+#######################################################################
+# page content
+#
+# these should always be overridden for each page/collection 
+#######################################################################
+
+_content_ {<p><h2>oops</h2>
+_textdefaultcontent_}
+_pagetitle_ {_textdefaulttitle_}
+_imagethispage_ {}
+_iconcollection_ {}
+_collectionname_ {}
+
+
+package Global
+  
+
+_imagecollection_ {_If_("_iconcollection_" ne "",
+<a href="_httppageabout_"><img class="icon" src="_iconcollection_" alt="_collectionname_" title="_collectionname_"></a>,
+_imagecollectionv_)}
+_imagecollection_ [v=1] {_imagecollectionv_}
+_imagecollectionv_ {_If_(_collectionname_,<p class="collectiontitle"><a class="collectiontitle" href="_httppageabout_">_collectionname_</a></p>)}
+
+#######################################################################
+# these width macros are read in by the server when calculating 
+# width of navigation bar etc. There should be one for each 
+# classification that this receptionist supports, one for the 
+# search button, and the _pagewidth_ macro which is the total width
+# of the page
+#######################################################################
+
+# width of tabs when displaying tables of contents
+_tabwidth_ {25}
+
+_pagewidth_ {537}
+# defaultwidth is the width buttons default to if not included in this list
+_defaultwidth_ {87}
+_searchwidth_ {_widthtsrchx_}
+
+#######################################################################
+# Macros whose values are set from within the server at runtime. These 
+# are here only for reference and to set default values if required.           
+#######################################################################
+
+# _win32_ will be set to 1 if we're on windows
+_win32_ {}
+
+# all cgi args are set as _cgiargX_ macros - those I've put here 
+# are those that need to default to something
+_cgiargd_ {}
+_cgiargcl_ {}
+
+# set from within the query action
+_hselection_ {}
+_jselection_ {}
+_nselection_ {}
+#level (granularity) selection for mgpp
+_gselection_ {}
+#level selection for form searching - dont have paragraph
+_gformselection_ {_gselection_} 
+_fqfselection_ {}
+# sort field for lucene
+_sfselection_ {}
+
+#######################################################################
+# navigation bar 
+#
+#######################################################################
+# Most of the stuff to do with navigation bars is now defined in nav_css.dm 
+# and nav_ns4.dm
+
+_dynamicclassifiernavbarentries_ {}
+_navigationbar_ {}
+_widthtspace_ {2}
+
+_navlinktitle_ {_If_("_label_1__" eq "\_label_1_\_",_1_,_label_1__)}
+_navlinkalt_ {_If_("_textdescr_1__" ne "\_textdescr_1_\_", _textdescr_1__, _If_("_text_1__" eq "\_text_1_\_",_textdescrdefault_(_1_),_textdescrdefault_(_text_1__)) }
+
+#######################################################################
+# global navigation links
+#######################################################################
+
+# _globallinks_ is now defined in nav_css and nav_ns4 macro files
+
+#######################################################################
+# general web macros 
+#######################################################################
+
+_gsdltop_ {_top}
+
+#######################################################################
+# http macros 
+#
+# These contain the url without any quotes
+#######################################################################
+
+# _httpprefix_ and _httpweb_ defined by the server
+_httpimages_ {_httpweb_/images}
+_httpscript_ {_httpweb_/script}
+_httpstyle_ {_httpweb_/style}
+_httpflash_ {_httpweb_/flash}
+_httpjava_ {_httpweb_/java}
+
+# old macros, for backwards compatibility
+_httpimg_ {_httpimages_}
+
+# collection versions of the same directories
+_httpcimages_ {_httpcollection_/images}
+_httpcscript_ {_httpcollection_/script}
+_httpcstyle_ {_httpcollection_/style}
+_httpcflash_ {_httpcollection_/flash}
+_httpcjava_ {_httpcollection_/java}
+
+_httpassocdir_ {_httpcollection_/index/assoc}
+_httpdocimg_ {_httpassocdir_/_thisOID_}
+# old macros, for backwards compatibility
+_httpcollimg_  {_httpcollection_/index/assoc}
+
+_httpcollection_ {_httpprefix_/collect/_cgiargc_}
+
+_httppagex_ {_gwcgi_?e=_compressedoptions_&amp;a=p&amp;p=_1_}
+_httppagestatus_ {_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=frameset}
+_httppagetranslator_ {_gwcgi_?e=_compressedoptions_&amp;a=gti&amp;p=home}
+_httppagecollector_ {_gwcgi_?e=_compressedoptions_&amp;a=collector&amp;p=intro}
+_httppagedepositor_ {_gwcgi_?e=_compressedoptions_&amp;a=depositor&amp;p=select}
+_httppagegli_ {_httppagex_(gli)}
+_httppageabout_ {_httppagex_(about)}
+#_httppagehome_ {_httppagex_(home)}
+###_httppagehome_ {http://www.nzdl.org/cgi-bin/dblibrary?a=p&amp;p=home}
+_httppagehome_ {_gwcgi_?a=p&amp;p=home&amp;l=_cgiargl_&amp;w=_cgiargw_}
+_httppagehelp_ {_httppagex_(help)}
+_httppagepref_ {_httppagex_(preferences)}
+_httppagedocs_ {_httppagex_(docs)}
+_httpclearhistory_ {_gwcgi_?e=_compressedoptions_&amp;a=dh}
+
+_httpgreenstone_ {_httppagex_(gsdl)}
+_httpdownload_ {http://www.nzdl.org/download}
+_httppublications_ {_httpdownload_/greenstone/publications}
+
+_httpcurrentdocument_ {_gwcgi_?e=_compressedoptions_&amp;cl=_cgiargcl_&amp;d=_cgiargd_}
+_httpquery_ {_gwcgi_?e=_compressedoptions_&amp;a=q}
+_httpBrowse_ {_gwcgi_?e=_compressedoptions_&amp;a=br}
+
+# _httpdoc_ is the same as _httpdocument_ - _httpdocument_
+# may occasionally be altered by the server however
+_httpdocument_ {_gwcgi_?e=_compressedoptions_&amp;a=d}
+_httpdoc_  {_gwcgi_?e=_compressedoptions_&amp;a=d}
+
+_httpdocumenthandle_ {_httpprefix_handle/_1_/_2_}
+
+_httpextlink_ {_gwcgi_?e=_compressedoptions_&amp;a=extlink}
+_httpbuild_ {_gwcgi_?e=_compressedoptions_&amp;a=bc}
+
+# this is obsolete now (still used by collector). done by stylesheet instead
+_httpiconchalk_ {_httpimg_/chalk.gif}
+_widthchalk_ {2000}
+_heightchalk_ {10}
+
+_httpicondivb_ {_httpimg_/divb.gif}
+# these sizes are obsolete, now done in style sheet
+_widthdivb_ {_pagewidth_}
+_heightdivb_ {17}
+
+_httpicongsdl_ {_httpimg_/gsdl.gif}
+_widthgsdl_ {140}
+_heightgsdl_ {77}
+
+_httpiconitext_ {_httpimg_/itext.gif}
+_widthitext_ {16}
+_heightitext_ {21}
+
+_httpiconiworld_ {_httpimg_/iworld.gif}
+_widthiworld_ {16}
+_heightiworld_ {21}
+
+_httpiconiunknown_ {_httpimg_/iunknown.gif}
+_widthiunknown_ {16}
+_heightiunknown_ {21}
+
+_httpiconibtext_ {_httpimg_/ibtext.gif}
+_widthibtext_ {16}
+_heightibtext_ {21}
+
+_httpiconimpegvideo_ {_httpimg_/impegvid.gif}
+_widthimpegvideo_ {29}
+_heightimpegvideo_ {32}
+
+_httpiconiqtvideo_ {_httpimg_/iqtvideo.gif}
+_widthiqtvideo_ {29}
+_heightiqtvideo_ {32}
+
+_httpiconirmvideo_ {_httpimg_/irmvideo.gif}
+_widthirmvideo_ {29}
+_heightirmvideo_ {32}
+
+_httpiconless_ {_httpimg_/less.gif}
+_widthless_ {30}
+_heightless_ {16}
+
+_httpiconmore_ {_httpimg_/more.gif}
+_widthmore_ {30}
+_heightmore_ {16}
+
+_httpiconspacer_ {_httpimg_/spacer.gif}
+_widthspacer_ {42}
+_heightspacer_ {4}
+
+_httpicontabspace_ {_httpimg_/tabspace.gif}
+_widthtabspace_ {23}
+_heighttabspace_ {1}
+
+_httpicontspace_ {_httpimg_/bg_green.png}
+_heighttspace_ {17}
+
+_httpiconwarning_ {_httpimg_/warning.gif}
+_widthwarning_ {30}
+_heightwarning_ {29}
+
+_widthhhome_ {200}
+_heighthhome_ {57}
+
+_httpiconarrrght_ {_httpimg_/arrrght.gif}
+_widtharrrght_ {23}
+_heightarrrght_ {15}
+
+_httpiconopenbook_ {_httpimg_/openbook.gif}
+_widthopenbook_ {28}
+_heightopenbook_ {23}
+
+_httpiconaopenbk_ {_httpimg_/aopenbk.gif}
+_widthaopenbk_ {28}
+_heightaopenbk_ {23}
+
+_httpiconopenfldr_ {_httpimg_/openfldr.gif}
+_widthopenfldr_ {23}
+_heightopenfldr_ {15}
+
+_httpiconaopenfdr_ {_httpimg_/aopenfdr.gif}
+_widthaopenfdr_ {23}
+_heightaopenfdr_ {15}
+
+_httpiconbook_ {_httpimg_/book.gif}
+_widthbook_ {18}
+_heightbook_ {11}
+
+_httpiconabook_ {_httpimg_/abook.gif}
+_widthabook_ {18}
+_heightabook_ {11}
+
+_httpiconbshelf_ {_httpimg_/bshelf.gif}
+_widthbshelf_ {20}
+_heightbshelf_ {16}
+
+_httpiconabshelf_ {_httpimg_/abshelf.gif}
+_widthabshelf_ {20}
+_heightabshelf_ {16}
+
+_httpiconsmtext_ {_httpimg_/smtext.gif}
+_widthsmtext_ {23}
+_heightsmtext_ {15}
+
+_httpiconasmtext_ {_httpimg_/asmtext.gif}
+_widthasmtext_ {23}
+_heightasmtext_ {15}
+
+_httpiconclsdfldr_ {_httpimg_/clsdfldr.gif}
+_widthclsdfldr_ {23}
+_heightclsdfldr_ {15}
+
+_httpiconaclsdfdr_ {_httpimg_/aclsdfdr.gif}
+_widthaclsdfdr_ {23}
+_heightaclsdfdr_ {15}
+
+_httpiconimidi_ {_httpimg_/imidi.gif}
+_widthimidi_ {16}
+_heightimidi_ {21}
+
+_httpiconimsword_ {_httpimg_/imsword.gif}
+_widthimsword_ {26}
+_heightimsword_ {26}
+
+_httpiconimp3_ {_httpimg_/imp3.gif}
+_widthimp3_ {25}
+_heightimp3_ {20}
+
+_httpiconipdf_ {_httpimg_/ipdf.gif}
+_widthipdf_ {26}
+_heightipdf_ {26}
+
+_httpiconips_ {_httpimg_/ips.gif}
+_widthips_ {25}
+_heightips_ {32}
+
+_httpiconippt_ {_httpimg_/ippt.gif}
+_widthippt_ {32}
+_heightippt_ {30}
+
+_httpiconirtf_ {_httpimg_/irtf.gif}
+_widthirtf_ {29}
+_heightirtf_ {32}
+
+_httpiconixls_ {_httpimg_/iexcel.gif}
+_widthixls_ {32}
+_heightixls_ {30}
+
+_httpiconspace_ {_httpimg_/space.gif}
+
+#######################################################################
+# Icons 
+#
+# Must not include links (so they can be used as links). If you want to
+# include links use _image
+#######################################################################
+
+_iconnext_{<img src="_httpiconmore_" align="absbottom"
+width="_widthmore_" height="_heightmore_" border="0" alt="_texticonnext_" title="_texticonnext_">}
+_iconnext_[v=1] {_texticonnext_}
+
+_iconprev_{<img src="_httpiconless_" align="absbottom"
+width="_widthless_" height="_heightless_" border="0" alt="_texticonprev_" title="_texticonprev_">}
+_iconprev_[v=1] {_texticonprev_}
+
+_icontext_ {<img class="icon" src="_httpiconitext_" width="_widthitext_" height="_heightitext_" alt="_texticontext_" title="_texticontext_">}
+_icontext_[v=1] {_texticontext_}
+
+_iconworld_ {<img class="icon" src="_httpiconiworld_" width="_widthiworld_" height="_heightiworld_" alt="_texticonworld_" title="_texticonworld_">}
+_iconworld_[v=1] {_texticonworld_}
+
+_iconunknown_ {<img class="icon" src="_httpiconiunknown_" width="_widthiunknown_" height="_heightiunknown_" alt="_texticonunknown_" title="_texticonunknown_">}
+_iconunknown_[v=1] {_texticonunknown_}
+
+_iconblanktext_ {<img class="icon" src="_httpiconibtext_" width="_widthibtext_" height="_heightibtext_">}
+_iconblanktext_[v=1] {}
+
+_iconclosedbook_ {<img class="icon" src="_httpiconbook_" width="_widthbook_" height="_heightbook_" alt="_texticonclosedbook_" title="_texticonclosedbook_">}
+_iconclosedbook_ [v=1] {<small><b>_texticonclosedbook_: </b></small>}
+_iconclosedbook_ [v=1,l=zh]{<small><_font_><b>_texticonclosedbook_: </b></font></small>}
+
+_icondoc_ {<img class="icon" src="_httpiconimsword_" width="_widthimsword_" height="_heightimsword_" alt="_texticonmsword_" title="_texticonmsword_">}
+_icondoc_[v=1] {_texticonmsword_}
+
+_iconmp3_ {<img class="icon" src="_httpiconimp3_" width="_widthimp3_" height="_heightimp3_" alt="_texticonmp3_" title="_texticonmp3_">}
+_iconmp3_[v=1] {_texticonmp3_}
+
+_iconmidi_ {<img class="icon" src="_httpiconimidi_" width="_widthimidi_" height="_heightimidi_" alt="_texticonmidi_" title="_texticonmidi_">}
+_iconmidi_[v=1] {_texticonmidi_}
+
+_iconpdf_ {<img class="icon" src="_httpiconipdf_" width="_widthipdf_" height="_heightipdf_" alt="_texticonpdf_" title="_texticonpdf_">}
+_iconpdf_[v=1] {_texticonpdf_}
+
+_iconps_ {<img class="icon" src="_httpiconips_" width="_widthips_" height="_heightips_" alt="_texticonps_" title="_texticonps_">}
+_iconps_[v=1] {_texticonps_}
+
+_iconppt_ {<img class="icon" src="_httpiconippt_" width="_widthippt_" height="_heightippt_" alt="_texticonppt_" title="_texticonppt_">}
+_iconppt_[v=1] {_texticonppt_}
+
+_iconrtf_ {<img class="icon" src="_httpiconirtf_" width="_widthirtf_" height="_heightirtf_" alt="_texticonrtf_" title="_texticonrtf_">}
+_iconrtf_[v=1] {_texticonrtf_}
+
+_iconxls_ {<img class="icon" src="_httpiconixls_" width="_widthixls_" height="_heightixls_" alt="_texticonxls_" title="_texticonxls_">}
+_iconxls_[v=1] {_texticonxls_}
+
+#######################################################################
+# Image links 
+#
+# These might include a link (not like an _icon_
+#######################################################################
+
+
+_imagegreenstone_ {<img class="icon" src="_httpicongsdl_" width="_widthgsdl_" height="_heightgsdl_" alt="_textdescrgreenstone_" title="_textdescrgreenstone_">}
+
+_imagegreenstone_[v=1] {_textdescrgreenstone_}
+
+###########################################################################
+# Metadata formatting stuff
+#
+#
+###########################################################################
+package format
+
+# _1_ is Year, _2_ is month, _3_ is day
+_date_ {_If_("_3_" ne "",_3_ )_If_("_2_" ne "",_textmonth_2__ )_If_("_1_" ne "",_1_)}
+
Index: /gsdl/stable/macros/bengali.dm
===================================================================
--- /gsdl/stable/macros/bengali.dm	(revision 20131)
+++ /gsdl/stable/macros/bengali.dm	(revision 20131)
@@ -0,0 +1,897 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Bengali Language text and icon macros 
+# Many thanks to Prasenjit Majumder (translated January 2005)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=bn] {àŠžàŠŸàŠ®à§àŠ¿àŠàŠ¿}
+_textsource_ [l=bn] {àŠvàŠž àŠ
+àŠšà§àŠ§àŠŸàŠ¬àŠš   }
+_textdate_ [l=bn] {àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸàŠ° àŠ€àŠŸàŠ°àŠ¿àŠ:}
+_textnumpages_ [l=bn] {àŠªàŠŸàŠ€àŠŸàŠ° àŠžàŠàŠà§àŠ¯àŠŸ}
+
+_textsignin_ [l=bn] {àŠªà§àŠ°àŠ¬à§àŠ¶ àŠàŠ°à§àŠš  }
+
+_textdefaultcontent_ [l=bn] {àŠ
+àŠšà§àŠ°à§àŠ§ àŠàŠ°àŠŸ àŠªàŠŸàŠ€àŠŸ àŠà§àŠ²àŠŸ àŠ¯àŠŸàŠ¬à§ àŠšàŠŸà¥€ àŠŠà§àŠŸ àŠàŠ°à§ àŠàŠªàŠšàŠŸàŠ° àŠ¬à§àŠ°àŠŸàŠàŠàŠŸàŠ°à§àŠ° ' àŠªà§àŠàŠšà§ ' àŠ¬à§àŠ€àŠŸàŠ® àŠàŠ¿àŠªà§àŠš  àŠ
+àŠ¥àŠ¬àŠŸ àŠà§àŠ°à§àŠšàŠžàŠà§àŠš àŠ¡àŠ¿àŠàŠ¿àŠàŠŸàŠ² àŠ²àŠŸàŠàŠ¬à§àŠ°à§àŠ°à§àŠ€à§ àŠ«àŠ¿àŠ°à§ àŠ¯à§àŠ€à§ àŠàŠªàŠ°à§àŠ° àŠªà§àŠ°àŠ¥àŠ®àŠ¿àŠ àŠ¬à§àŠ€àŠŸàŠ® àŠàŠ¿àŠªà§àŠšà¥€}
+
+_textdefaulttitle_ [l=bn] {àŠàŠ¿ àŠàŠž àŠ¡àŠ¿ àŠàŠ²   àŠ€à§àŠ°à§àŠàŠ¿}
+
+_textbadcollection_ [l=bn] {àŠàŠ àŠžàŠàŠà§àŠ°àŠ¹àŠàŠ¿ àŠ¬àŠ°à§àŠ€àŠ®àŠŸàŠš àŠà§àŠ°à§àŠšàŠžà§àŠà§àŠš àŠ¡àŠ¿àŠàŠ¿àŠàŠŸàŠ² àŠ²àŠŸàŠàŠ¬à§àŠ°à§àŠ°à§àŠ€à§ àŠšà§àŠ}
+
+_textselectpage_ [l=bn] {àŠªàŠŸàŠ€àŠŸ àŠ¬àŠŸàŠà§àŠš}
+
+_collectionextra_ [l=bn] {àŠàŠ àŠžàŠàŠà§àŠ°àŠ¹à§ àŠàŠà§_about:numdocs_àŠšàŠ¥àŠ¿ àŠàŠ àŠžàŠàŠà§àŠ°àŠ¹  àŠ¶à§àŠ· àŠšàŠ¿àŠ°à§àŠ®àŠŸàŠš   àŠ¹à§à§ àŠàŠ¿àŠ²_about:builddate_àŠŠàŠ¿àŠš àŠàŠà§}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=bn] {<p>àŠàŠ àŠžàŠàŠà§àŠ°àŠ¹à§ àŠàŠà§ _numdocs_ _If_("_numdocs_" àŠžàŠ®à§àŠàŠ°àŠ£ "à§§ " àŠšàŠ¥àŠ¿ , àŠšàŠ¥àŠ¿àŠà§àŠ²àŠ¿ ),àŠ®à§àŠ  _numbytes_.
+<p><a href="_httppagex_(bsummary)">àŠà§àŠ²àŠ¿àŠ àŠàŠ°à§àŠš</a>  àŠàŠ àŠžàŠàŠà§àŠ°àŠ¹à§àŠ°  àŠžàŠàŠà§àŠ·àŠ¿àŠªà§àŠ€ àŠ¬àŠ¿àŠ¬àŠ°àŠ£à§ àŠŠà§àŠàŠ¬àŠŸàŠ° àŠàŠšà§àŠ¯  }
+
+_textdescrcollection_ [l=bn] {}
+_textdescrabout_ [l=bn] {àŠªàŠŸàŠ€àŠŸàŠàŠ¿àŠ° àŠžàŠ®à§àŠªàŠ°à§àŠà§ àŠàŠŸàŠšà§àŠš}
+_textdescrhome_ [l=bn] {àŠ¶à§àŠ°à§àŠ° àŠªàŠŸàŠ€àŠŸ}
+_textdescrhelp_ [l=bn] {àŠžàŠŸàŠ¹àŠŸàŠ¯à§àŠ¯àŠ°  àŠàŠšà§àŠ¯ àŠàŠ àŠªàŠŸàŠ€àŠŸàŠàŠ¿ àŠŠà§àŠà§àŠš }
+_textdescrpref_ [l=bn] {àŠªàŠàŠšà§àŠŠà§àŠ° àŠªàŠŸàŠ€àŠŸ}
+_textdescrgreenstone_ [l=bn] {àŠšàŠ¿àŠàŠàŠ¿àŠ²à§àŠ¯àŠŸàŠšà§àŠ¡ àŠ¡àŠ¿àŠàŠ¿àŠàŠŸàŠ² àŠ²àŠŸàŠàŠ¬à§àŠ°à§àŠ°à§ àŠžàŠ«àŠàŠà§àŠŸàŠ°}
+_textdescrusab_ [l=bn] {àŠàŠ¿ àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ° àŠàŠ°àŠ€à§  àŠ
+àŠžà§àŠ¬àŠ¿àŠ§à§ àŠ¹àŠà§àŠà§ ?}
+
+_textdescrSearch_ [l=bn] {àŠ¬àŠ¿àŠ¶à§àŠ· àŠ¶àŠ¬à§àŠŠàŠàŠ¿ àŠàŠà§àŠà§àŠš }
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=bn] {àŠ¬àŠ°à§àŠšàŠŸàŠšà§àŠà§àŠ°àŠ®àŠ¿àŠ àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ® àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš}
+# -- Missing translation: _textdescrCreator_
+# -- Missing translation: _textdescrSubject_
+_textdescrDescription_ [l=bn] {àŠ¬àŠ°à§àŠ£àŠšàŠŸ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrPublisher_ [l=bn] {àŠªà§àŠ°àŠàŠŸàŠ¶àŠ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrContributor_ [l=bn] {àŠ
+àŠ¬àŠŠàŠŸàŠšàŠàŠŸàŠ°à§àŠ° àŠšàŠŸàŠ®  àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrDate_ [l=bn] {àŠ€àŠŸàŠ°àŠ¿àŠ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrType_ [l=bn] {àŠžàŠ®à§àŠªàŠŠà§àŠ° àŠ¬àŠ¿àŠ­àŠŸàŠ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš}
+_textdescrFormat_ [l=bn] {àŠ«àŠ°à§àŠ®àŠŸàŠ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrIdentifier_ [l=bn] {àŠžàŠ®à§àŠªàŠŠ àŠšàŠ¿àŠ°à§àŠŠà§àŠ¶àŠ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrSource_ [l=bn] {àŠ«àŠŸàŠàŠ²à§àŠ° àŠšàŠŸàŠ® àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš}
+# -- Missing translation: _textdescrLanguage_
+_textdescrRelation_ [l=bn] {àŠžàŠ®à§àŠªàŠ°à§àŠ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrCoverage_ [l=bn] {àŠ
+àŠšà§àŠ§àŠŸàŠ¬àŠš àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠŠà§àŠà§àŠš }
+_textdescrRights_ [l=bn] {àŠ
+àŠ§àŠ¿àŠàŠŸàŠ° àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš}
+
+_textdescrOrganization_ [l=bn] {àŠžàŠàŠàŠ àŠš àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrKeyword_ [l=bn] {àŠà§ àŠà§àŠŸàŠ°à§àŠ¡ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrHowto_ [l=bn] {àŠ¬àŠ¿àŠ­àŠŸàŠ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrList_ [l=bn] {àŠšàŠ¥àŠ¿ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrSeries_ [l=bn] {àŠžwàŠà§àŠ¯àŠŸ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš}
+_textdescrTo_ [l=bn] {àŠ€à§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš}
+_textdescrFrom_ [l=bn] {àŠ¥à§àŠà§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠŠà§àŠà§àŠš}
+_textdescrTopic_ [l=bn] {àŠ¬àŠ¿àŠ¶à§àŠ· àŠžàŠàŠà§àŠ¯àŠŸ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš}
+_textdescrBrowse_ [l=bn] {àŠŠà§àŠà§àŠš}
+_textdescrCollage_ [l=bn] {àŠàŠ¬àŠ¿àŠà§àŠ²àŠ¿àŠ° àŠà§àŠ²àŠŸàŠ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrPeople_ [l=bn] {àŠ¬àŠ°à§àŠšàŠŸàŠšà§àŠà§àŠ°àŠ®àŠ¿àŠ àŠàŠ°à§àŠ®à§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrAcronym_ [l=bn] {àŠ®à§àŠšà§àŠ¡àŠ®àŠŸàŠ² àŠ¶àŠ¬à§àŠŠàŠà§àŠ²àŠ¿ àŠŠà§àŠà§àŠš}
+_textdescrPhrase_ [l=bn] {àŠ¶àŠ¬à§àŠŠ àŠžàŠ®àŠ·à§àŠàŠ¿ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrArtist_ [l=bn] {àŠ¶àŠ¿àŠ²à§àŠªà§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸàŠàŠ¿ àŠŠà§àŠà§àŠš}
+_textdescrVolume_ [l=bn] {àŠàŠšà§àŠ¡ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš}
+_textdescrCountries_ [l=bn] {àŠŠà§àŠ¶ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+_textdescrCaptions_ [l=bn] {àŠàŠ¬àŠ¿àŠà§àŠ²àŠ¿àŠ° àŠšàŠŸàŠ® àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠŠà§àŠà§àŠš }
+
+
+_labelSearch_ [l=bn] {àŠàŠà§àŠà§àŠš }
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=bn] {àŠšàŠ®à§àŠšàŠŸ àŠ àŠ¥à§àŠà§ àŠà§àŠ¡}
+# -- Missing translation: _labelCreator_
+# -- Missing translation: _labelSubject_
+_labelDescription_ [l=bn] {àŠ¬àŠ¿àŠ¬àŠ°àŠšà§}
+_labelPublisher_ [l=bn] {àŠªà§àŠ°àŠàŠŸàŠ¶àŠàŠàŠ£}
+_labelContributor_ [l=bn] {àŠ
+àŠ¬àŠŠàŠŸàŠšàŠàŠŸàŠ°àŠ¿}
+_labelDate_ [l=bn] {àŠ€àŠŸàŠ°àŠ¿àŠàŠà§àŠ²àŠ¿}
+_labelType_ [l=bn] {àŠ°àŠàŠ®àŠ­à§àŠŠ }
+_labelFormat_ [l=bn] {àŠ«àŠ°àŠ®à§àŠ¯àŠàŠž}
+_labelIdentifier_ [l=bn] {àŠšàŠ¿àŠ°à§àŠŠà§àŠ¶àŠ}
+_labelSource_ [l=bn] {àŠ«àŠŸàŠàŠ²àŠà§àŠ²àŠ¿àŠ° àŠšàŠŸàŠ®}
+# -- Missing translation: _labelLanguage_
+_labelRelation_ [l=bn] {àŠžàŠ®à§àŠªàŠ°à§àŠ }
+_labelCoverage_ [l=bn] {àŠ
+àŠšà§àŠ§àŠŸàŠ¬àŠš}
+_labelRights_ [l=bn] {àŠ
+àŠ§àŠ¿àŠàŠŸàŠ°}
+
+_labelOrg_ [l=bn] {àŠžàŠàŠàŠ àŠš }
+_labelKeyword_ [l=bn] {àŠàŠ¿àŠà§àŠŸàŠ°à§àŠ¡}
+_labelHow_ [l=bn] {àŠàŠ¿ àŠàŠ°à§}
+_labelSeries_ [l=bn] {àŠ
+àŠšà§àŠà§àŠ°àŠ®  }
+_labelList_ [l=bn] {àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ}
+_labelTo_ [l=bn] {àŠ€à§}
+_labelFrom_ [l=bn] {àŠ¥à§àŠà§}
+_labelTopic_ [l=bn] {àŠ¬àŠ¿àŠ·à§}
+_labelBrwse_ [l=bn] {àŠŠà§àŠà§àŠš }
+_labelCollage_ [l=bn] {àŠà§àŠ²àŠŸàŠ}
+_labelBrows_ [l=bn] {àŠŠà§àŠà§àŠš }
+_labelPeople_ [l=bn] {àŠ²à§àŠàŠàŠšà§àŠ° àŠ¬àŠ°à§àŠšàŠŸàŠšà§àŠà§àŠ°àŠ®àŠ¿àŠ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ }
+_labelAcronym_ [l=bn] {àŠ®à§àŠšà§àŠ¡àŠ®àŠŸàŠ² àŠ¶àŠ¬à§àŠŠ }
+_labelPhrase_ [l=bn] {àŠ¶àŠ¬à§àŠŠ àŠžàŠ®àŠ·à§àŠàŠ¿ }
+_labelArtist_ [l=bn] {àŠ¶àŠ¿àŠ²à§àŠªà§}
+_labelVolume_ [l=bn] {àŠàŠšà§àŠ¡}
+_labelCaptions_ [l=bn] {àŠ¬àŠ¿àŠ·à§ àŠšàŠŸàŠ®}
+_labelCountries_ [l=bn] {àŠŠà§àŠ¶àŠà§àŠ²àŠ¿}
+
+_texticontext_ [l=bn] {àŠšàŠ¥àŠ¿àŠàŠ¿ àŠ¬àŠŸ àŠ«àŠŸàŠàŠ²àŠàŠ¿ àŠŠà§àŠà§àŠš}
+_texticonclosedbook_ [l=bn] {àŠ¬àŠ¿àŠ·à§àŠ¬àŠžà§àŠ€à§ àŠŠà§àŠàŠŸàŠ° àŠàŠšà§àŠ¯ àŠàŠ àŠšàŠ¥àŠ¿àŠàŠ¿ àŠà§àŠ²à§àŠš}
+_texticonnext_ [l=bn] {àŠªàŠ°à§àŠ° àŠ
+àŠ§à§àŠ¯àŠŸà§}
+_texticonprev_ [l=bn] {àŠàŠà§àŠ° àŠ
+àŠ§à§àŠ¯àŠŸà§}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=bn] {àŠ®àŠ¿àŠ¡àŠ¿  àŠ«àŠŸàŠàŠ²àŠàŠ¿ àŠŠà§àŠà§àŠš}
+_texticonmsword_ [l=bn] {àŠ®àŠŸàŠàŠà§àŠ°à§àŠžàŠ«àŠ àŠà§àŠŸàŠ°à§àŠ¡ àŠ«àŠŸàŠàŠ²àŠàŠ¿ àŠŠà§àŠà§àŠš}
+# -- Missing translation: _texticonmp3_
+_texticonpdf_ [l=bn] {àŠªàŠ¿àŠ¡àŠ¿àŠàŠ« àŠ«àŠŸàŠàŠ²àŠàŠ¿ àŠŠà§àŠà§àŠš}
+_texticonps_ [l=bn] {àŠªà§àŠžà§àŠàŠà§àŠ°àŠ¿àŠªà§àŠ àŠ«àŠŸàŠàŠ²àŠàŠ¿ àŠŠà§àŠà§àŠš}
+_texticonppt_ [l=bn] {àŠªàŠŸàŠà§àŠŸàŠ° àŠªà§à§àŠšà§àŠ àŠ«àŠŸàŠàŠ²àŠàŠ¿ àŠŠà§àŠà§àŠš}
+_texticonrtf_ [l=bn] {àŠàŠ°àŠàŠ¿àŠàŠ« àŠ«àŠŸàŠàŠ²àŠàŠ¿ àŠŠà§àŠà§àŠš}
+_texticonxls_ [l=bn] {àŠ®àŠŸàŠàŠà§àŠ°à§àŠžàŠ«àŠ àŠàŠàŠžà§àŠ² àŠ«àŠŸàŠàŠ²àŠàŠ¿ àŠŠà§àŠà§àŠš}
+
+_page_ [l=bn] {àŠªàŠŸàŠ€àŠŸ}
+_pages_ [l=bn] {àŠªàŠŸàŠ€àŠŸàŠà§àŠ²àŠ¿}
+_of_ [l=bn] {àŠàŠ°}
+_vol_ [l=bn] {àŠàŠšà§àŠ¡}
+_num_ [l=bn] {àŠšàŠŸ}
+
+_textmonth00_ [l=bn] {}
+_textmonth01_ [l=bn] {àŠàŠŸàŠšà§à§àŠŸàŠ°à§}
+_textmonth02_ [l=bn] {àŠ«à§àŠ¬à§àŠ°à§à§àŠŸàŠ°à§}
+_textmonth03_ [l=bn] {àŠ®àŠŸàŠ°à§àŠ}
+_textmonth04_ [l=bn] {àŠàŠªà§àŠ°àŠ¿àŠ²}
+_textmonth05_ [l=bn] {àŠ®à§}
+_textmonth06_ [l=bn] {àŠà§àŠš}
+_textmonth07_ [l=bn] {àŠà§àŠ²àŠŸàŠ}
+_textmonth08_ [l=bn] {àŠ
+àŠàŠžà§àŠ}
+_textmonth09_ [l=bn] {àŠžà§àŠªà§àŠà§àŠ®à§àŠ¬àŠ°}
+_textmonth10_ [l=bn] {àŠ
+àŠàŠà§àŠ¬àŠ°}
+_textmonth11_ [l=bn] {àŠšàŠ­à§àŠ®à§àŠ¬àŠ°}
+_textmonth12_ [l=bn] {àŠ¡àŠ¿àŠžà§àŠ®à§àŠ¬àŠ°}
+
+_textdocument_ [l=bn] {àŠšàŠ¥àŠ¿}
+_textsection_ [l=bn] {àŠ¬àŠ¿àŠ­àŠŸàŠ}
+_textparagraph_ [l=bn] {àŠ
+àŠšà§àŠà§àŠà§àŠŠ}
+
+_magazines_ [l=bn] {àŠªàŠ€à§àŠ°àŠ¿àŠàŠŸ}
+
+_nzdlpagefooter_ [l=bn] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">àŠšàŠ¿àŠàŠàŠ¿àŠ²à§àŠ¯àŠŸàŠšà§àŠ¡ àŠ¡àŠ¿àŠàŠ¿àŠàŠŸàŠ² àŠ²àŠŸàŠàŠ¬à§àŠ°à§àŠ°à§ àŠªà§àŠ°àŠà§àŠà§àŠ </a>
+<br><a href="http://www.cs.waikato.ac.nz">àŠàŠ®à§àŠªàŠ¿àŠàŠàŠŸàŠ° àŠ¬àŠ¿àŠà§àŠàŠŸàŠš àŠ¬àŠ¿àŠ­àŠŸàŠ</a>, 
+<a href="http://www.waikato.ac.nz">àŠà§àŠŸàŠàŠ¿àŠà§ àŠ¬àŠ¿àŠ¶à§àŠ¬àŠ¬àŠ¿àŠŠà§àŠ¯àŠŸàŠ²à§</a>, 
+àŠšàŠ¿àŠàŠàŠ¿àŠ²à§àŠ¯àŠŸàŠšà§àŠ¡}
+
+_linktextHOME_ [l=bn] {àŠ¹à§àŠ® / àŠà§àŠ¹}
+_linktextHELP_ [l=bn] {àŠžàŠŸàŠ¹àŠŸàŠ¯à§àŠ¯}
+_linktextPREFERENCES_ [l=bn] {àŠªàŠàŠšà§àŠŠ}
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=bn] {àŠàŠ àŠžàŠàŠà§àŠ°àŠ¹ àŠžàŠ®à§àŠ¬àŠšà§àŠ§à§}
+
+_textsubcols1_ [l=bn] {<p>àŠžàŠ®à§àŠªà§àŠ°à§àŠš àŠžàŠàŠà§àŠ°àŠ¹àŠàŠ¿ àŠàŠ àŠ¿àŠ€ àŠ¹à§à§àŠà§ _1_ àŠ
+àŠšà§àŠžàŠàŠà§àŠ°àŠ¹ àŠšàŠ¿à§à§ 
+àŠ¬àŠ°à§àŠ€àŠ®àŠŸàŠšà§ àŠ¯à§àŠà§àŠ²àŠ¿ àŠªàŠŸàŠà§àŠŸ àŠ¯àŠŸàŠ¬à§
+<blockquote>}
+
+_textsubcols2_ [l=bn] {</blockquote>
+àŠàŠªàŠšàŠ¿ àŠŠà§àŠàŠ€à§ ( àŠàŠ¬àŠ àŠªàŠ°àŠ¿àŠ¬àŠ°à§àŠ€àŠš àŠàŠ°àŠ€à§ ) àŠªàŠŸàŠ°à§àŠš àŠ¯à§ àŠ
+àŠšà§àŠžàŠàŠà§àŠ°àŠ¹àŠà§àŠ²àŠ¿ àŠ¬àŠ°à§àŠ€àŠ®àŠŸàŠšà§ àŠàŠªàŠšàŠŸàŠ° àŠ
+àŠà§àŠ°àŠŸàŠ§àŠ¿àŠàŠŸàŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸà§ àŠàŠà§}
+
+
+_titleabout_ [l=bn] {àŠžàŠ®à§àŠªàŠ°à§àŠà§}
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhcreat_
+# -- Missing translation: _texticonhsubj_
+# -- Missing translation: _texticonhlang_
+
+
+_texticonopenbookshelf_ [l=bn] {àŠà§àŠ°àŠšà§àŠ¥àŠŸàŠàŠŸàŠ°à§àŠ° àŠàŠ àŠ
+wàŠ¶àŠàŠ¿ àŠ¬àŠšà§àŠ§ àŠàŠ°à§àŠš}
+_texticonclosedbookshelf_ [l=bn] {àŠà§àŠ°àŠšà§àŠ¥àŠŸàŠàŠŸàŠ°à§àŠ° àŠàŠ àŠ
+wàŠ¶àŠàŠ¿ àŠà§àŠ²à§àŠš àŠàŠ¬w àŠŠà§àŠà§àŠš}
+_texticonopenbook_ [l=bn] {àŠàŠ àŠ¬àŠàŠàŠ¿ àŠ¬àŠšà§àŠ§ àŠàŠ°à§àŠ£}
+_texticonclosedfolder_ [l=bn] {àŠ«à§àŠ²à§àŠ¡àŠŸàŠ°àŠàŠ¿ àŠà§àŠ²à§àŠš àŠàŠ¬àŠ àŠŠà§àŠà§àŠš  }
+_texticonclosedfolder2_ [l=bn] {àŠ
+àŠšà§ - àŠ
+wàŠ¶ âàŠà§àŠ²à§àŠš}
+_texticonopenfolder_ [l=bn] {àŠàŠ àŠ«à§àŠ²à§àŠ¡àŠŸàŠ°àŠàŠ¿ àŠ¬àŠšà§àŠ§ àŠàŠ°à§àŠš}
+_texticonopenfolder2_ [l=bn] {àŠ
+àŠšà§ àŠ
+wàŠ¶àŠàŠ¿ àŠ¬àŠšà§àŠ§ àŠàŠ°à§àŠš}
+_texticonsmalltext_ [l=bn] {àŠ®à§àŠ²àŠªàŠŸàŠ à§àŠ° àŠàŠ àŠªàŠ°àŠ¬àŠ°à§àŠ€àŠ¿ àŠ
+wàŠ¶àŠàŠ¿ àŠŠà§àŠà§àŠš }
+_texticonsmalltext2_ [l=bn] {àŠ®à§àŠ²àŠªàŠŸàŠ  àŠŠà§àŠà§àŠš àŠ}
+_texticonpointer_ [l=bn] {àŠ¬àŠ°à§àŠ€àŠ®àŠŸàŠš àŠ
+wàŠ¶}
+_texticondetach_ [l=bn] {àŠšàŠ€à§àŠš àŠàŠŸàŠšàŠŸàŠ²àŠŸà§ àŠàŠ àŠªàŠŸàŠ€àŠŸàŠàŠ¿ àŠà§àŠ²à§àŠš}
+_texticonhighlight_ [l=bn] {àŠàŠà§àŠàŠŸàŠ°àŠ®àŠ€à§ àŠ¶àŠ¬à§àŠŠàŠà§àŠ²à§ àŠ¹àŠŸàŠàŠ²àŠŸàŠàŠ àŠàŠ°à§àŠš}
+_texticonnohighlight_ [l=bn] {àŠàŠà§àŠàŠŸàŠ°àŠ®àŠ€à§  àŠ¶àŠ¬à§àŠŠàŠà§àŠ²à§ àŠ¹àŠŸàŠàŠ²àŠŸàŠàŠ àŠàŠ°àŠ¬à§àŠš àŠšàŠŸ}
+_texticoncontracttoc_ [l=bn] {àŠà§àŠ¬àŠ¿àŠ²à§àŠ° àŠ¬àŠ¿àŠ¬àŠ°àŠ£àŠà§àŠ²àŠ¿ àŠ®à§àŠà§ àŠ«à§àŠ²à§àŠš}
+_texticonexpandtoc_ [l=bn] {àŠ¬àŠ¿àŠ¬àŠ°àŠšà§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸàŠàŠ¿  àŠžàŠ®à§àŠªà§àŠ°àŠžàŠŸàŠ°àŠ¿àŠ€  àŠàŠ°à§àŠ£}
+_texticonexpandtext_ [l=bn] {àŠžàŠ¬ àŠ²à§àŠàŠŸ àŠŠà§àŠàŠŸàŠš}
+_texticoncontracttext_ [l=bn] {àŠ¶à§àŠ§à§àŠ®àŠŸàŠ€à§àŠ° àŠ¬àŠ°à§àŠ€àŠ®àŠŸàŠšà§ àŠàŠ¿àŠ¹à§àŠšàŠ¿àŠ€  àŠ
+àŠàŠ¶ àŠŠà§àŠàŠŸàŠš}
+_texticonwarning_ [l=bn] {<b>àŠžàŠ€àŠ°à§àŠàŠàŠ°àŠ£ àŠ </b>}
+_texticoncont_ [l=bn] {àŠàŠ²àŠ¬à§?}
+
+_textltwarning_ [l=bn] {<div class="buttons">_imagecont_</div>
+_iconwarning_àŠ®à§àŠ²àŠªàŠŸàŠ àŠà§ àŠžàŠ®à§àŠªà§àŠ°àŠžàŠŸàŠ°àŠ¿àŠ€ àŠàŠ°à§ àŠàŠªàŠšàŠŸàŠ° àŠ¬àŠ°àŠŸàŠàŠàŠŸàŠ°à§àŠ° àŠàŠšà§àŠ¯ àŠàŠàŠŸàŠšà§ àŠ
+àŠšà§àŠ àŠ€àŠ¥à§àŠ¯  àŠ€à§àŠ°àŠ¿ àŠ¹àŠ¬à§
+}
+
+_textgoto_ [l=bn] {àŠªàŠŸàŠ€àŠŸà§ àŠ¯à§àŠ€à§}
+_textintro_ [l=bn] {<i>(àŠžà§àŠàŠšàŠŸàŠ®à§àŠ²àŠ àŠ®à§àŠ²àŠªàŠŸàŠ )</i>}
+
+_textCONTINUE_ [l=bn] {àŠàŠ²àŠ¬à§ ??}
+
+_textEXPANDTEXT_ [l=bn] {àŠžàŠ®à§àŠªà§àŠ°àŠžàŠŸàŠ°àŠ£\nàŠ®à§àŠ²àŠªàŠŸàŠ }
+
+_textCONTRACTCONTENTS_ [l=bn] {àŠà§àŠà§àŠ€àŠ¿\nàŠžà§àŠàŠ¿àŠªàŠ€à§àŠ°}
+
+_textDETACH_ [l=bn] {àŠàŠ²àŠŸàŠŠàŠŸ}
+
+_textEXPANDCONTENTS_ [l=bn] {àŠžàŠ®à§àŠªà§àŠ°àŠžàŠŸàŠ°àŠ£\nàŠžà§àŠàŠ¿àŠªàŠ€à§àŠ°}
+
+_textCONTRACT_ [l=bn] {àŠà§àŠà§àŠ€àŠ¿\nàŠ®à§àŠ²àŠªàŠŸàŠ }
+
+_textHIGHLIGHT_ [l=bn] {àŠ¹àŠŸàŠàŠ²àŠŸàŠàŠàŠ¿w}
+
+_textNOHIGHLIGHT_ [l=bn] {àŠšà§\nàŠ¹àŠŸàŠàŠ²àŠŸàŠàŠàŠ¿}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=bn] {_If_(_thislast_àŠ«àŠ²àŠŸàŠ«àŠ² _thisfirst_ - _thislast_ àŠªà§àŠ°àŠ¶à§àŠšà§àŠ° àŠàŠšà§àŠ¯ _cgiargq_,àŠªà§àŠ°àŠ¶à§àŠšà§àŠ° àŠžàŠŸàŠ¥à§ àŠà§àŠš àŠàŠ¿àŠà§ àŠ®àŠ¿àŠ²à§àŠà§ àŠšàŠŸàŠ _cgiargq_)}
+_textnoquerytitle_ [l=bn] {àŠªàŠŸàŠ€àŠŸ àŠàŠà§àŠà§àŠš}
+
+_textsome_ [l=bn] {àŠàŠ¿àŠà§}
+_textall_ [l=bn] {àŠžàŠ¬}
+_textboolean_ [l=bn] {àŠ¬à§àŠ²àŠ¿à§àŠŸàŠš}
+_textranked_ [l=bn] {àŠ
+àŠ¬àŠžà§àŠ¥àŠŸàŠš}
+_textnatural_ [l=bn] {àŠžàŠŸàŠ§àŠŸàŠ°àŠ£}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=bn] {àŠàŠà§àŠàŠŸàŠ° àŠàŠ€àŠ¿àŠ¹àŠŸàŠž }
+
+_textifeellucky_ [l=bn] {àŠàŠ®àŠ¿ àŠ­àŠŸàŠà§àŠ¯àŠ¬àŠŸàŠš àŠ®àŠšà§ àŠàŠ°àŠàŠ¿ ! }
+
+#alt text for query buttons
+_textusequery_ [l=bn] {àŠàŠ àŠªà§àŠ°àŠ¶à§àŠš àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ° àŠàŠ°à§àŠš}
+_textfreqmsg1_ [l=bn] {àŠ¶àŠ¬à§àŠŠ àŠàŠ£àŠšàŠŸ àŠ}
+_textpostprocess_ [l=bn] {_If_(_quotedquery_,<br><i> àŠàŠà§àŠàŠŸàŠ° àŠàŠšà§àŠ¯ àŠªàŠ°àŠ¬àŠ°à§àŠ€à§ àŠªàŠŠàŠà§àŠ·à§àŠª_quotedquery_</i>
+)}
+_textinvalidquery_ [l=bn] {àŠªà§àŠ°àŠ¶à§àŠšà§àŠ° àŠ­à§àŠ² àŠ§àŠ°àŠ£}
+
+_textmorethan_ [l=bn] {àŠàŠ°àŠ¥à§àŠà§ àŠ¬à§àŠ¶à§}
+_textapprox_ [l=bn] {àŠžàŠ®à§àŠªàŠ°à§àŠà§}
+_textnodocs_ [l=bn] {àŠà§àŠš àŠšàŠ¥àŠ¿ àŠªà§àŠ°àŠ¶à§àŠšà§àŠ° àŠžàŠŸàŠ¥à§ àŠ®àŠ¿àŠ²à§àŠà§ àŠšàŠŸà¥€}
+_text1doc_ [l=bn] {àŠàŠàŠàŠ¿ àŠšàŠ¥àŠ¿ àŠªà§àŠ°àŠ¶à§àŠšà§àŠ° àŠžàŠŸàŠ¥à§ àŠ®àŠ¿àŠ²à§àŠà§à¥€}
+_textlotsdocs_ [l=bn] {àŠšàŠ¥àŠ¿ àŠªà§àŠ°àŠ¶à§àŠšà§àŠ° àŠžàŠŸàŠ¥à§ àŠ®àŠ¿àŠ²à§àŠà§à¥€}
+_textmatches_ [l=bn] {àŠ®à§àŠ²à§}
+_textbeginsearch_ [l=bn] {àŠàŠà§àŠàŠŸ àŠ¶à§àŠ°à§}
+_textrunquery_ [l=bn] {àŠªà§àŠ°àŠ¶à§àŠš àŠàŠŸàŠ²àŠŸàŠš}
+_textclearform_ [l=bn] {àŠ«àŠ°à§àŠ® àŠàŠŸàŠ²àŠ¿ àŠàŠ°à§àŠš}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=bn] {àŠ¶àŠ¬à§àŠŠ àŠ¬àŠŸ àŠ¶àŠ¬à§àŠŠàŠžàŠ®àŠ·à§àŠàŠ¿}
+_textinfield_ [l=bn] {àŠà§àŠ·à§àŠ€à§àŠ°à§}
+_textfoldstem_ [l=bn] {( àŠ­àŠàŠŸàŠ , àŠ®à§àŠ²àŠ¶àŠ¬à§àŠŠ )}
+
+_textadvquery_ [l=bn] {àŠ
+àŠ¥àŠ¬àŠŸ àŠžàŠ°àŠŸàŠžàŠ°àŠ¿ àŠàŠàŠàŠ¿ àŠªà§àŠ°àŠ¶à§àŠš àŠŠàŠ¿àŠš àŠ}
+_textallfields_ [l=bn] {àŠžàŠ¬ àŠà§àŠ·à§àŠ€à§àŠ°  }
+_texttextonly_ [l=bn] {àŠ¶à§àŠ§à§àŠ®àŠŸàŠ€à§àŠ° àŠ®à§àŠ²àŠªàŠŸàŠ }
+_textand_ [l=bn] {àŠàŠ¬w}
+_textor_ [l=bn] {àŠ
+àŠ¥àŠ¬àŠŸ}
+_textandnot_ [l=bn] {àŠàŠ¬w àŠšàŠŸ}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=bn] {àŠàŠšà§àŠ¯ àŠàŠà§àŠà§àŠš _indexselection_ _If_(_jselection_,àŠàŠ°,_jselection_ )_If_(_gselection_,àŠ€à§ _gselection_ àŠžà§àŠ€àŠ° )_If_(_nselection_,àŠ€à§ _nselection_ àŠ­àŠŸàŠ·àŠŸ )àŠ¯à§àŠàŠŸ àŠ§àŠŸàŠ°àŠ£ àŠàŠ°à§ _querytypeselection_ àŠ¶àŠ¬à§àŠŠà§àŠ°}
+
+_textadvancedsearch_ [l=bn] {àŠàŠà§àŠà§àŠš _indexselection_ _If_(_jselection_,àŠàŠ° _jselection_ )_If_(_gselection_,àŠ€à§ _gselection_ àŠžà§àŠ€àŠ° )_If_(_nselection_ àŠ€à§ _nselection_ àŠ­àŠŸàŠ·àŠŸ ) àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ° àŠàŠ°à§ _querytypeselection_ àŠªà§àŠ°àŠ¶à§àŠš}
+
+_textformsimplesearch_ [l=bn] {àŠàŠà§àŠà§àŠš _If_(_jselection_,_jselection_ )_If_(_gformselection_ àŠ€à§ _gformselection_ àŠžà§àŠ€àŠ° )_If_(_nselection_àŠ€à§ _nselection_ àŠ­àŠŸàŠ·àŠŸ )àŠàŠšà§àŠ¯ _formquerytypesimpleselection_  àŠ€à§}
+
+_textformadvancedsearch_ [l=bn] {àŠàŠà§àŠà§àŠš _If_(_jselection_,_jselection_ )_If_(_gformselection_àŠ€à§ _gformselection_ àŠžà§àŠ€àŠ° )_If_(_nselection_àŠ€à§ _nselection_àŠ­àŠŸàŠ·àŠŸ )àŠàŠ¬w àŠ«àŠ²àŠŸàŠ«àŠ² àŠŠà§àŠàŠŸàŠš _formquerytypeadvancedselection_ àŠžàŠŸàŠàŠ¿à§à§à¥€}
+
+
+_textnojsformwarning_ [l=bn] {àŠžàŠ€àŠ°à§àŠà§àŠàŠ°àŠ£ àŠ àŠàŠªàŠšàŠŸàŠ° àŠà§à§àŠ¬ àŠ¬à§àŠ°àŠŸàŠàŠàŠŸàŠ°à§àŠ° àŠàŠŸàŠ­àŠŸàŠžà§àŠà§àŠ°àŠ¿àŠªà§àŠ àŠàŠàŠš àŠ
+àŠžàŠ®àŠ°à§àŠ¥à¥€    <br> àŠàŠà§àŠàŠŸàŠ° àŠàŠšàŠ¯ àŠŠà§àŠŸ àŠàŠ°à§ àŠàŠàŠŸàŠà§ àŠžàŠ®àŠ°à§àŠ¥ àŠàŠ°à§àŠšà¥€}
+_textdatesearch_ [l=bn] {àŠŠà§àŠàŠ¿ àŠ€àŠŸàŠ°àŠ¿àŠà§àŠ° àŠ®àŠ§à§àŠ¯àŠ¬àŠ°à§àŠ€à§ àŠžà§àŠ®àŠŸ àŠ¬àŠŸ àŠà§àŠš àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ àŠ€àŠŸàŠ°àŠ¿àŠà§àŠ° àŠàŠšà§àŠ¯ àŠàŠ àŠžwàŠà§àŠ°àŠ¹ àŠàŠà§àŠàŠŸ àŠ¯à§àŠàŠ€à§ àŠªàŠŸàŠ°à§à¥€ àŠàŠàŠ¿ àŠàŠàŠàŠ¿ àŠàŠà§àŠàŠŸàŠ®àŠŸàŠ«àŠ¿àŠ àŠªàŠŠà§àŠ§àŠ€àŠ¿à¥€ }
+_textstartdate_ [l=bn] {àŠ¶à§àŠ°à§ ( àŠ
+àŠ¥àŠ¬àŠŸ àŠ¶à§àŠ§à§àŠ®àŠŸàŠ€à§àŠ°) àŠ€àŠŸàŠ°àŠ¿àŠ àŠ}
+_textenddate_ [l=bn] {àŠ¶à§àŠ· àŠ€àŠŸàŠ°àŠ¿àŠ àŠ}
+_textbc_ [l=bn] {àŠ¬àŠ¿ àŠžàŠ¿ àŠ}
+_textad_ [l=bn] {àŠžàŠ¿ àŠ}
+_textexplaineras_ [l=bn] {àŠžàŠ¿ àŠ  àŠ àŠ¬àŠ¿ àŠžàŠ¿ àŠ  àŠ¹àŠ²  àŠ àŠ¡àŠ¿ àŠ àŠ¬àŠ¿ àŠžàŠ¿ - à§à§àŠ° àŠªàŠ°àŠ¿àŠ¬àŠ°à§àŠ€àŠ¿àŠ€ àŠ°à§àŠªà¥€ àŠžàŠ¿ àŠ àŠ¹àŠ² àŠà§àŠ·à§àŠ àŠªàŠ°àŠ¬àŠ°à§àŠ€à§ àŠžàŠ®à§ àŠàŠ¬w àŠ¬àŠ¿ àŠžàŠ¿ àŠ àŠ¹àŠ² àŠà§àŠ·à§àŠ àŠªàŠ°àŠ¬àŠ°à§àŠ€à§ àŠžàŠ®à§}
+
+_textstemon_ [l=bn] {(àŠ¶àŠ¬à§àŠŠà§àŠ° àŠ¶à§àŠ·àŠŸwàŠ¶àŠà§ àŠàŠªà§àŠà§àŠ·àŠŸ àŠàŠ°à§ )}
+
+_textsearchhistory_ [l=bn] {àŠàŠà§àŠàŠŸàŠ° àŠàŠ€àŠ¿àŠ¹àŠŸàŠž}
+
+#text macros for search history
+_textnohistory_ [l=bn] {àŠàŠà§àŠàŠŸàŠ° àŠàŠ€àŠ¿àŠ¹àŠŸàŠž -à§à§àŠ° àŠžàŠŸàŠ¥à§ àŠà§àŠš àŠšàŠ¥àŠ¿ àŠ®àŠ¿àŠ²àŠà§ àŠšàŠŸà¥€}
+_texthresult_ [l=bn] {àŠ«àŠ²àŠŸàŠ«àŠ²}
+_texthresults_ [l=bn] {àŠ«àŠ²àŠŸàŠ«àŠ²àŠà§àŠ²àŠ¿}
+_texthallwords_ [l=bn] {àŠžàŠ¬ àŠ¶àŠ¬à§àŠŠ}
+_texthsomewords_ [l=bn] {àŠàŠ¿àŠà§ àŠ¶àŠ¬à§àŠŠ}
+_texthboolean_ [l=bn] {àŠ¬à§àŠ²àŠ¿à§àŠŸàŠš}
+_texthranked_ [l=bn] {àŠ
+àŠ¬àŠžà§àŠ¥àŠŸàŠš}
+_texthcaseon_ [l=bn] {àŠà§àŠàŠ¹àŠŸàŠ€ àŠ¬à§àŠ¹àŠŸàŠ€ àŠ
+àŠà§àŠ·àŠ° àŠ
+àŠ¬àŠ¶à§àŠ¯àŠ àŠ®àŠ¿àŠ²àŠ¬à§}
+_texthcaseoff_ [l=bn] {àŠà§àŠžàŠ«à§àŠ²à§àŠ¡à§àŠ¡}
+_texthstemon_ [l=bn] {àŠ®à§àŠ²àŠ¶àŠ¬à§àŠŠ}
+_texthstemoff_ [l=bn] {àŠ®à§àŠ²àŠ¶àŠ¬à§àŠŠà§àŠ° àŠªà§àŠ°àŠ€à§àŠ¯à§ àŠ¬àŠŸ àŠ¬àŠ¿àŠ­àŠà§àŠ€àŠ¿àŠ¯à§àŠà§àŠ€ àŠ°à§àŠª}
+
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=bn] {àŠàŠ°àŠàŠ®àŠ­àŠŸàŠ¬à§ àŠªàŠàŠšà§àŠŠ àŠ àŠ¿àŠ àŠàŠ°àŠŸ àŠ¹à§à§àŠà§ à¥€ àŠ¬à§àŠ°àŠŸàŠàŠàŠŸàŠ°à§àŠ° ' àŠªà§àŠàŠšà§' àŠ¬à§àŠ€àŠŸàŠ® àŠàŠ¿àŠªàŠ¬à§àŠš àŠšàŠŸ - àŠàŠ°àŠ²à§ àŠžàŠ¬ àŠàŠ²à§àŠ®à§àŠ²à§ àŠàŠ°à§ àŠŠà§àŠ¬à§! àŠªàŠ°àŠ¿àŠ¬àŠ°à§àŠ€à§, àŠàŠªàŠ°à§àŠ° àŠ¯à§àŠà§àŠš àŠªàŠàŠšà§àŠŠ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸàŠ° àŠ¬à§àŠ€àŠŸàŠ® àŠàŠ¿àŠªà§àŠšà¥€
+}
+_textsetprefs_ [l=bn] {àŠªàŠàŠšà§àŠŠ àŠ àŠ¿àŠ àŠàŠ°àŠŸ}
+_textsearchprefs_ [l=bn] {àŠªàŠàŠšà§àŠŠ àŠàŠà§àŠàŠŸ}
+# -- Missing translation: _textcollectionprefs_
+_textpresentationprefs_ [l=bn] {àŠàŠªàŠžà§àŠ¥àŠŸàŠªàŠšà§àŠ° àŠªàŠàŠšà§àŠŠ}
+_textpreferences_ [l=bn] {àŠªàŠàŠšà§àŠŠ àŠ
+àŠšà§àŠ¯àŠŸà§à§}
+_textcasediffs_ [l=bn] {àŠà§àŠàŠ¹àŠŸàŠ€ àŠ¬à§àŠ¹àŠŸàŠ€ àŠ
+àŠà§àŠ·àŠ° àŠàŠ²àŠŸàŠŠàŠŸ àŠ}
+_textignorecase_ [l=bn] {àŠà§àŠàŠ¹àŠŸàŠ€ àŠ¬à§àŠ¹àŠŸàŠ€ àŠ
+àŠà§àŠ·àŠ° àŠàŠªà§àŠà§àŠ·àŠŸ àŠàŠ°à§àŠš àŠ}
+_textmatchcase_ [l=bn] {àŠà§àŠàŠ¹àŠŸàŠ€ / àŠ¬à§àŠ¹àŠŸàŠ€ àŠ
+àŠà§àŠ·àŠ° àŠ®à§àŠ²àŠŸàŠ¬à§àŠš}
+_textwordends_ [l=bn] {àŠ¶àŠ¬à§àŠŠà§àŠ° àŠ¶à§àŠ·àŠŸwàŠ¶ àŠ}
+_textstem_ [l=bn] {àŠ¶àŠ¬à§àŠŠà§àŠ° àŠ¶à§àŠ·àŠŸwàŠ¶ àŠàŠªà§àŠà§àŠ·àŠŸ àŠàŠ°à§àŠš}
+_textnostem_ [l=bn] {àŠžàŠ¬ àŠ¶àŠ¬à§àŠŠ àŠ
+àŠ¬àŠ¶à§àŠ¯àŠ àŠ®àŠ¿àŠ²àŠ¬à§ }
+_textprefop_ [l=bn] {àŠªàŠ°à§àŠ¯àŠšà§àŠ€ àŠ«àŠ¿àŠ°à§àŠš _maxdocoption_àŠŠàŠ¿à§à§ àŠàŠàŠŸàŠ€  _hitsperpageoption_ àŠªà§àŠ°àŠ€àŠ¿ àŠªàŠŸàŠ€àŠŸà§ àŠàŠàŠŸàŠ€à¥€}
+_textextlink_ [l=bn] {àŠ¬àŠŸàŠàŠ°à§àŠ° àŠà§à§àŠ¬ àŠªàŠŸàŠ€àŠŸ  àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ°}
+_textintlink_ [l=bn] {àŠvàŠž àŠšàŠ¥àŠ¿àŠà§ àŠšàŠ¿à§à§ àŠàŠžàŠŸ àŠ¹à§à§àŠà§ àŠ¥à§àŠà§ àŠ}
+_textlanguage_ [l=bn] {àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ°àŠ¿àŠ àŠ­àŠŸàŠ·àŠŸ}
+_textencoding_ [l=bn] {àŠàŠšàŠà§àŠ¡àŠ¿w àŠ}
+_textformat_ [l=bn] {àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ°àŠ¿àŠ àŠ«àŠ°àŠ®à§àŠ¯àŠàŠž}
+_textall_ [l=bn] {àŠžàŠ¬àŠàŠ¿àŠà§}
+_textquerymode_ [l=bn] {àŠªà§àŠ°àŠ¶à§àŠš àŠ§àŠ°àŠ£àŠ}
+_textsimplemode_ [l=bn] {àŠžàŠ¹àŠ àŠªà§àŠ°àŠ¶à§àŠš àŠ§àŠ°àŠ£}
+_textadvancedmode_ [l=bn] {àŠàŠàŠŸàŠ® àŠªà§àŠ°àŠ¶à§àŠš àŠ§àŠ°àŠ£( àŠ¬à§àŠ²àŠ¿à§àŠŸàŠš àŠàŠà§àŠàŠŸàŠ° àŠ
+àŠšà§àŠ®àŠ€àŠ¿ àŠŠà§à§ !,&,à¥€ àŠàŠ¬w àŠ¬àŠšà§àŠ§àŠšà§ àŠ¬àŠ¬àŠ¹àŠŸàŠ° àŠàŠ°à§ )  }
+_textlinkinterm_ [l=bn] {àŠ®àŠ§à§àŠ¯àŠžà§àŠ€àŠ€àŠŸàŠàŠŸàŠ°à§ àŠªàŠŸàŠ€àŠŸ àŠŠàŠ¿à§à§ }
+_textlinkdirect_ [l=bn] {àŠžà§àŠàŠŸàŠžà§àŠàŠ¿ àŠžà§àŠàŠŸàŠšà§ àŠ¯àŠŸàŠš}
+_textdigitlib_ [l=bn] {àŠ¡àŠ¿àŠàŠ¿àŠàŠŸàŠ² àŠ²àŠŸàŠàŠ¬à§àŠ°à§àŠ°à§}
+_textweb_ [l=bn] {àŠà§à§àŠ¬}
+_textgraphical_ [l=bn] {àŠàŠ àŠ¬àŠ¿àŠ·à§àŠ}
+_texttextual_ [l=bn] {àŠ²à§àŠàŠ¿àŠ}
+_textcollectionoption_ [l=bn] {<p>
+àŠªà§àŠ°àŠ¬à§àŠ¶à§àŠ° àŠàŠšà§àŠ¯ àŠ
+àŠšà§-àŠžwàŠà§àŠ°àŠ¹
+<br>}
+
+_textrelateddocdisplay_ [l=bn] {àŠžàŠ®à§àŠ®àŠšà§àŠ§àŠ¿àŠ€ àŠšàŠ¥àŠ¿àŠà§àŠ²àŠ¿ àŠŠà§àŠàŠŸà§}
+_textsearchhistory_ [l=bn] {àŠàŠà§àŠàŠŸàŠ° àŠàŠ€àŠ¿àŠ¹àŠŸàŠž àŠ}
+_textnohistory_ [l=bn] {àŠà§àŠš àŠàŠà§àŠàŠŸàŠ° àŠàŠ€àŠ¿àŠ¹àŠŸàŠž àŠšà§àŠ}
+_texthistorydisplay_ [l=bn] {àŠŠà§àŠàŠŸàŠ _historynumrecords_ àŠàŠà§àŠàŠŸàŠ° àŠàŠ€àŠ¿àŠ¹àŠŸàŠž}
+_textnohistorydisplay_ [l=bn] {àŠàŠà§àŠàŠŸàŠ° àŠàŠ€àŠ¿àŠ¹àŠŸàŠž àŠšà§àŠ àŠŠà§àŠàŠŸàŠ¬à§ àŠšàŠŸ}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=bn] {àŠàŠà§àŠàŠŸàŠ° àŠ¥à§àŠà§ àŠ}
+_textplainsearch_ [l=bn] {àŠžàŠŸàŠ§àŠŸàŠ°àŠ£ àŠàŠà§àŠàŠŸ àŠ}
+_textqueryboxsize_ [l=bn] {àŠªà§àŠ°àŠ¶à§àŠš àŠ¬àŠŸàŠžà§àŠ àŠàŠàŠŸàŠ° àŠ}
+_textregbox_ [l=bn] {àŠžàŠŸàŠ§àŠŸàŠ°àŠ£ àŠªà§àŠ°àŠ¶à§àŠš àŠ¬àŠŸàŠžà§àŠ}
+_textbigbox_ [l=bn] {àŠ¬à§ àŠªà§àŠ°àŠ¶à§àŠš àŠ¬àŠŸàŠžà§àŠ }
+_textformtype_ [l=bn] {àŠªà§àŠ°àŠàŠŸàŠ°àŠ­à§àŠŠ àŠ¥à§àŠà§àŠ}
+_textsimple_ [l=bn] {àŠžàŠ¹àŠ}
+_textadvanced_ [l=bn] {àŠàŠàŠŸàŠ®}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=bn] {àŠžàŠŸàŠ¥à§}
+_textfields_ [l=bn] {àŠà§àŠ·à§àŠ€à§àŠ°àŠà§àŠ²àŠ¿}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=bn] {àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠšàŠ¥àŠ¿ àŠžàŠŸàŠàŠŸàŠš}
+_textalsoshowing_ [l=bn] {àŠŠà§àŠàŠŸàŠà§àŠà§}
+_textwith_ [l=bn] {àŠžàŠ¬àŠà§à§à§ àŠ¬à§àŠ¶àŠ¿}
+_textdocsperpage_ [l=bn] {àŠªàŠŸàŠ€àŠŸàŠªàŠ¿àŠà§ àŠšàŠ¥àŠ¿}
+
+_textfilterby_ [l=bn] {àŠ¯àŠŸ àŠšàŠ¥àŠ¿ àŠàŠà§ àŠªàŠŸàŠ¬à§àŠš}
+_textall_ [l=bn] {àŠžàŠ¬àŠàŠ¿àŠà§}
+_textany_ [l=bn] {àŠ¯à§àŠà§àŠš}
+_textwords_ [l=bn] {àŠ¶àŠ¬à§àŠŠ-à§à§àŠ° }
+_textleaveblank_ [l=bn] {àŠžàŠ¬ àŠšàŠŸàŠ¥àŠ¿ àŠªà§àŠ€à§ àŠàŠ àŠàŠàŠàŠ¿ àŠ«àŠàŠŸàŠàŠŸ àŠ°àŠŸàŠà§àŠš}
+
+_browsebuttontext_ [l=bn] {"àŠžàŠàŠà§àŠ·àŠ¿àŠªà§àŠ€ àŠšàŠ¥àŠ¿"}
+
+_nodata_ [l=bn] {<i>àŠà§àŠš  àŠ€àŠ¥à§àŠ¯ àŠšà§àŠ</i>}
+_docs_ [l=bn] {àŠšàŠ¥àŠ¿}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=bn] {àŠžàŠŸàŠ¹àŠŸàŠ¯à§àŠ¯}
+_textSearchshort_ [l=bn] {àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ  àŠ¶àŠ¬à§àŠŠ àŠàŠà§àŠà§àŠš}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=bn] {àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ® àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ  }
+_textCreatorshort_ [l=bn] {àŠ²à§àŠàŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ}
+# -- Missing translation: _textSubjectshort_
+_textDescriptionshort_ [l=bn] {àŠ¬àŠ¿àŠ¬àŠ°àŠ£ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ  }
+_textPublishershort_ [l=bn] {àŠªà§àŠ°àŠàŠŸàŠ¶àŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ  }
+_textContributorshort_ [l=bn] {àŠ
+àŠ¬àŠŠàŠŸàŠšàŠàŠŸàŠ°àŠ¿ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ }
+_textDateshort_ [l=bn] {àŠ€àŠŸàŠ°àŠ¿àŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ  àŠªàŠàŠšà§àŠŠ  }
+_textTypeshort_ [l=bn] {àŠªà§àŠ°àŠàŠŸàŠ°àŠ­à§àŠŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ}
+_textFormatshort_ [l=bn] {àŠ«àŠ°àŠ®à§àŠ¯àŠàŠž àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ  }
+_textIdentifiershort_ [l=bn] {àŠšàŠ¿àŠ°à§àŠŠà§àŠ¶àŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ  }
+_textSourceshort_ [l=bn] {àŠ«àŠŸàŠàŠ²à§àŠ° àŠšàŠŸàŠ® àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ}
+# -- Missing translation: _textLanguageshort_
+_textRelationshort_ [l=bn] {àŠžàŠ®à§àŠªàŠ°à§àŠ  àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ  }
+_textCoverageshort_ [l=bn] {àŠ
+àŠšà§àŠ§àŠŸàŠ¬àŠš àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ   }
+_textRightsshort_ [l=bn] {àŠ
+àŠ§àŠ¿àŠàŠŸàŠ° àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ  }
+
+_textSeriesshort_ [l=bn] {àŠà§àŠ°àŠ®àŠšà§àŠ¬à§ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ  }
+_textToshort_ [l=bn] {àŠ€à§ àŠà§àŠ·à§àŠ€à§àŠ° àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ}
+_textFromshort_ [l=bn] {àŠ¥à§àŠà§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªàŠàŠšà§àŠŠ  }
+_textBrowseshort_ [l=bn] {àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠŠà§àŠà§àŠš}
+_textOrganizationshort_ [l=bn] {àŠžwàŠàŠ àŠš  àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ  }
+_textHowtoshort_ [l=bn] {àŠàŠ¿ àŠàŠ°à§ ' àŠ¶à§àŠšàŠ¬à§àŠš àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ  }
+_textTopicshort_ [l=bn] {àŠªà§àŠ°àŠžàŠà§àŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ}
+_textPeopleshort_ [l=bn] {àŠ®àŠŸàŠšà§àŠ·àŠàŠš àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ  }
+_textAcronymshort_ [l=bn] {àŠ®à§àŠšà§àŠ¡àŠ®àŠŸàŠ² àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ }
+_textPhraseshort_ [l=bn] {àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸà§ àŠ¥àŠŸàŠàŠŸ àŠ¶àŠ¬à§àŠŠ àŠžàŠ®àŠ·à§àŠàŠ¿  àŠŠà§àŠà§àŠš  }
+_textArtistshort_ [l=bn] {àŠ¶àŠ¿àŠ²à§àŠªà§ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ }
+_textKeywordshort_ [l=bn] {àŠàŠ¿àŠà§àŠŸàŠ°à§àŠ¡ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ  }
+_textVolumeshort_ [l=bn] {àŠàŠšà§àŠ¡ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ}
+_textCountriesshort_ [l=bn] {àŠŠà§àŠ¶à§àŠ° àŠšàŠŸàŠ® àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ   }
+_textdefaultshorttext_ [l=bn] {àŠ
+àŠàŠ¿àŠ¹à§àŠšàŠ¿àŠ€ àŠ¶à§àŠ°à§àŠšà§ àŠ¬àŠ¿àŠ­àŠŸàŠ}
+
+_textSearchlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš<i>àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ  àŠ¶àŠ¬à§àŠŠ àŠàŠà§àŠàŠ€à§</i> àŠ¯à§àŠàŠ¿ ' àŠàŠà§àŠà§àŠš ' àŠªàŠŸàŠ€àŠŸà§ àŠ²à§àŠàŠŸ àŠàŠà§ à¥€ àŠàŠàŠ¿àŠ àŠ¶à§àŠ°à§àŠ° àŠªà§àŠ°àŠ¥àŠ® àŠàŠ¬w àŠ
+àŠªàŠ° àŠªàŠŸàŠ€àŠŸà§ àŠ¯à§àŠ€à§ àŠªàŠŸàŠ°àŠ¬à§àŠš àŠàŠ¿àŠªà§ <i>àŠàŠà§àŠà§àŠš </i>àŠ¬à§àŠ€àŠŸàŠ® à¥€   }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ® àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ </i> àŠàŠ¿àŠªà§ <i>àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ®àŠà§àŠ²àŠ¿</i>àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠ¬àŠà§à§àŠ° àŠšàŠŸàŠ® àŠ¬àŠ°à§àŠ£àŠŸàŠšà§àŠžàŠŸàŠ°à§ àŠžàŠŸàŠàŠ¿à§à§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠ²à§àŠàŠ àŠ¹àŠ¿àŠžàŠŸàŠ¬à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠŠà§àŠàŠ€à§</i> àŠàŠ¿àŠªà§ <i>àŠ²à§àŠàŠ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ </i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿ àŠ²à§àŠàŠàŠŠà§àŠ° àŠšàŠŸàŠ® àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠžàŠŸàŠàŠŸàŠšà§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠªà§àŠ°àŠàŠŸàŠ¶ àŠàŠ°àŠ¬à§à¥€ }
+
+_textSubjectlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš   <i>àŠ¬àŠ¿àŠ·à§ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i>àŠàŠ¿àŠªà§ <i>àŠ¬àŠ¿àŠ·à§</i>àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠ¬àŠà§à§àŠ° àŠžwàŠà§àŠ°àŠ¹ àŠ¥à§àŠà§ àŠ¬àŠ¿àŠ·à§à§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+_textDescriptionlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠ¬àŠ¿àŠ¬àŠ°àŠ£ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i>àŠàŠ¿àŠªà§ <i>àŠ¬àŠ¿àŠ¬àŠ°àŠ£</i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿ àŠ¬àŠ¿àŠ¬àŠ°àŠ£à§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€  }
+
+_textPublisherlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i> àŠªà§àŠ°àŠàŠŸàŠ¶àŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ </i>àŠàŠ¿àŠªà§ <i> àŠªà§àŠ°àŠàŠŸàŠ¶àŠ </i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠªà§àŠ°àŠàŠŸàŠ¶àŠà§à§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+_textContributorlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i> àŠ
+àŠ¬àŠŠàŠŸàŠšàŠàŠŸàŠ°àŠ¿ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ </i>àŠàŠ¿àŠªà§<i>àŠ
+àŠ¬àŠŠàŠŸàŠšàŠàŠŸàŠ°àŠ¿ </i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿ àŠ
+àŠ¬àŠŠàŠŸàŠšàŠàŠŸàŠ°àŠ¿àŠŠà§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€  }
+
+_textDatelong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš<i> àŠ€àŠŸàŠ°àŠ¿àŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i> àŠàŠ¿àŠªà§ <i>àŠ€àŠŸàŠ°àŠ¿àŠ </i>àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿ àŠžàŠŸwàŠà§àŠ¯àŠ®àŠŸàŠšà§ àŠžàŠ®àŠžà§àŠ€ àŠžwàŠà§àŠ¯àŠŸàŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€  }
+
+_textTypelong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i> àŠªà§àŠ°àŠàŠŸàŠ°àŠ­à§àŠŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i>àŠàŠ¿àŠªà§ <i>àŠªà§àŠ°àŠàŠŸàŠ°àŠ­à§àŠŠ</i>àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠªà§àŠ°àŠàŠŸàŠ°àŠ­à§àŠŠà§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+_textFormatlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš<i>àŠ«àŠ°àŠ®à§àŠ¯àŠàŠž àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i> àŠàŠ¿àŠªà§ <i>àŠ«àŠ°àŠ®à§àŠ¯àŠàŠž</i>  àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿ àŠ«àŠ°àŠ®à§àŠ¯àŠàŠž-à§à§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€  }
+
+_textIdentifierlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš  <i>àŠšàŠ¿àŠ°à§àŠŠà§àŠ¶àŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ </i> àŠàŠ¿àŠªà§  <i>àŠšàŠ¿àŠ°à§àŠŠà§àŠ¶àŠ </i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠšàŠ¿àŠ°à§àŠŠà§àŠ¶àŠà§à§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠ«àŠŸàŠàŠ²à§àŠ° àŠšàŠŸàŠ® àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ </i>àŠàŠ¿àŠªà§  <i>àŠ«àŠŸàŠàŠ²à§àŠ° àŠšàŠŸàŠ® </i>àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠ®à§àŠ²  àŠ«àŠŸàŠàŠ²à§àŠ° àŠšàŠŸàŠ®  àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠžàŠŸàŠàŠ¿à§à§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+_textLanguagelong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš  <i>àŠ­àŠŸàŠ·àŠŸ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i>àŠàŠ¿àŠªà§ <i>àŠ­àŠŸàŠ·àŠŸ</i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠ­àŠŸàŠ·àŠŸ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠžàŠŸàŠàŠŸàŠšà§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€  }
+
+_textRelationlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠžàŠ®à§àŠªàŠ°à§àŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i> àŠàŠ¿àŠªà§ <i>àŠžàŠ®à§àŠªàŠ°à§àŠ</i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿   àŠžàŠ®à§àŠªàŠ°à§àŠ -à§à§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+_textCoveragelong_ [l=bn] {<p> àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš  <i>àŠ
+àŠšà§àŠ§àŠŸàŠ¬àŠš àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i>àŠàŠ¿àŠªà§  <i>àŠ
+àŠšà§àŠ§àŠŸàŠ¬àŠš  </i>  àŠ¬à§àŠ€àŠŸàŠ® à¥€  }
+
+_textRightslong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠ
+àŠ§àŠ¿àŠàŠŸàŠ°  àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ </i> àŠàŠ¿àŠªà§ <i>àŠ
+àŠ§àŠ¿àŠàŠŸàŠ°  </i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ }
+
+
+
+_textOrganizationlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠžwàŠàŠ àŠš àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i>àŠàŠ¿àŠªà§<i> àŠžwàŠàŠ àŠš</i>àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠžwàŠàŠ àŠšà§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€  }
+
+_textHowtolong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>' àŠàŠ¿ àŠàŠ°à§ ' àŠ¶à§àŠšàŠ¬à§àŠš àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ </i>àŠàŠ¿àŠªà§ <i> ' àŠàŠ¿ àŠàŠ°à§ ' </i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿ ' àŠàŠ¿ àŠàŠ°à§ ' àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+_textTopiclong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i> àŠªà§àŠ°àŠžàŠà§àŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i>àŠàŠ¿àŠªà§  <i> àŠªà§àŠ°àŠžàŠà§àŠ </i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠ àŠ¿àŠàŠŸàŠšàŠŸ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+_textTolong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i> àŠ€à§  àŠà§àŠ·à§àŠ€à§àŠ° àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ </i>àŠàŠ¿àŠªà§  <i> àŠ€à§ / àŠªà§àŠ°àŠ€àŠ¿ </i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠ àŠ¿àŠàŠŸàŠšàŠŸ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+_textFromlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠ¥à§àŠà§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i>àŠàŠ¿àŠªà§ <i>àŠ¥à§àŠà§</i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿ àŠªà§àŠ°à§àŠ°àŠà§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€  }
+
+_textSerieslong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš  <i>àŠà§àŠ°àŠ®àŠšà§àŠ¬à§ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ </i>àŠàŠ¿àŠªà§ <i>àŠà§àŠ°àŠ®àŠšà§àŠ¬à§</i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠ¬àŠ°à§àŠ€àŠ®àŠŸàŠš àŠžwàŠà§àŠ°àŠ¹ àŠ¥à§àŠà§ àŠà§àŠ°àŠ®àŠšà§àŠ¬à§à§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+_textBrowselong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš  <i>àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠŠà§àŠàŠ€à§ </i> àŠàŠ¿àŠªà§  
+<i> àŠŠà§àŠà§àŠš  </i>  àŠ¬à§àŠ€àŠŸàŠ® à¥€   }
+
+_textPeoplelong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠ®àŠŸàŠšà§àŠ·àŠàŠš àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i>àŠàŠ¿àŠªà§ <i>àŠ®àŠŸàŠšà§àŠ·àŠàŠš</i>àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠ®àŠŸàŠšà§àŠ·à§à§àŠ° àŠªàŠŠàŠ¬àŠ¿ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+_textAcronymlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠ®à§àŠšà§àŠ¡àŠ®àŠŸàŠ² àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ </i> àŠàŠ¿àŠªà§  <i>àŠ®à§àŠšà§àŠ¡àŠ®àŠŸàŠ²</i>àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠ®à§àŠšà§àŠ¡àŠ®àŠŸàŠ² àŠ¶àŠ¬à§àŠŠ àŠàŠ¬w àŠ€àŠŸàŠŠà§àŠ° àŠžà§àŠ¥àŠŸàŠš àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠªà§àŠ°àŠàŠŸàŠ¶ àŠàŠ°àŠ¬à§à¥€  }
+
+_textPhraselong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš  <i> àŠ¶àŠ¬à§àŠŠ àŠžàŠ®àŠ·à§àŠàŠ¿ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i> àŠàŠ¿àŠªà§ <i>àŠ¶àŠ¬à§àŠŠ àŠžàŠ®àŠ·à§àŠàŠ¿ </i>àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿ àŠ«àŠŸàŠàŠšà§àŠ¡ àŠ¶àŠ¬à§àŠŠ àŠžàŠ®àŠ·à§àŠàŠ¿ àŠ¬à§àŠ°àŠŸàŠàŠàŠŸàŠ° àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ° àŠàŠ°à§à¥€  }
+
+_textArtistlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠ¶àŠ¿àŠ²à§àŠªà§ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ </i>àŠàŠ¿àŠªà§  <i> àŠ¶àŠ¿àŠ²à§àŠªà§  </i>àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿   àŠ¶àŠ¿àŠ²à§àŠªà§àŠŠà§àŠ° àŠšàŠŸàŠ® àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠžàŠŸàŠàŠŸàŠšà§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠªà§àŠ°àŠàŠŸàŠ¶ àŠàŠ°àŠ¬à§à¥€  }
+
+_textKeywordlong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠàŠ¿àŠà§àŠŸàŠ°à§àŠ¡ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i>àŠàŠ¿àŠªà§<i>àŠàŠ¿àŠà§àŠŸàŠ°à§àŠ¡</i>   àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿ àŠàŠ¿àŠà§àŠŸàŠ°à§àŠ¡à§à§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€ }
+
+_textVolumelong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš <i>àŠàŠšà§àŠ¡ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i>àŠàŠ¿àŠªà§ <i>àŠàŠšà§àŠ¡</i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿  àŠàŠšà§àŠ¡-à§à§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€}
+
+_textCaptionslong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš   <i>àŠ¬àŠ¿àŠ·à§ àŠšàŠŸàŠ® àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ </i>àŠàŠ¿àŠªà§<i>àŠ¬àŠ¿àŠ·à§àŠšàŠŸàŠ® </i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿ àŠ¬àŠ¿àŠ·à§ àŠšàŠŸàŠ®à§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠªà§àŠ°àŠàŠŸàŠ¶ àŠàŠ°àŠ¬à§à¥€ }
+
+_textCountrieslong_ [l=bn] {<p>àŠàŠªàŠšàŠ¿ àŠªàŠŸàŠ°à§àŠš<i>àŠŠà§àŠ¶à§àŠ° àŠšàŠŸàŠ® àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§</i>àŠàŠ¿àŠªà§  <i>àŠŠà§àŠ¶ </i> àŠ¬à§àŠ€àŠŸàŠ® à¥€ àŠàŠàŠ¿ àŠŠà§àŠ¶à§àŠ° àŠšàŠŸàŠ®à§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§à¥€ }
+
+
+_textdefaultlongtext_ [l=bn] {<p>àŠàŠ¿àŠªà§àŠš <i>àŠ
+àŠà§àŠšàŠŸ</i> àŠ¬à§àŠ€àŠŸàŠ® àŠªà§àŠ°àŠàŠŸàŠ¶àŠšàŠŸ àŠŠà§àŠàŠŸàŠ° àŠàŠšàŠ¯ ( àŠ
+àŠà§àŠšàŠŸ àŠà§àŠ·à§àŠ€à§àŠ° àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠžàŠŸàŠàŠŸàŠšà§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ )     à¥€}
+
+
+_textreadingdocs_ [l=bn] {àŠàŠ¿ àŠàŠ°à§ àŠšàŠ¥àŠ¿ àŠªà§àŠ€à§ àŠ¹à§}
+
+_texthelpreadingdocs_ [l=bn] {
+<p>àŠªàŠŸàŠ€àŠŸàŠ° àŠ¬àŠàŠŸ àŠŠàŠ¿àŠà§àŠ° àŠàŠªàŠ°à§ àŠ¥àŠŸàŠàŠŸ àŠšàŠ¥àŠ¿àŠ° àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ® àŠ¬àŠŸ àŠªà§àŠ°àŠà§àŠàŠŠà§àŠ° àŠàŠ¬àŠ¿ àŠŠà§àŠà§ àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ àŠ¬àŠ àŠ¬àŠŸ àŠšàŠ¥àŠ¿àŠ€à§ àŠàŠªàŠšàŠ¿ àŠ¯à§àŠ€à§ àŠªàŠŸàŠ°à§àŠš à¥€àŠàŠ¿àŠà§ àŠàŠ¿àŠà§ àŠšàŠ¥àŠ¿àŠ° àŠà§àŠ·à§àŠ€à§àŠ°à§ àŠžà§àŠà§àŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠ¥àŠŸàŠà§ àŠàŠ¬àŠŸàŠ° àŠàŠ¿àŠà§ àŠšàŠ¥àŠ¿àŠ° àŠà§àŠ·à§àŠ€à§àŠ°à§ àŠªàŠŸàŠ€àŠŸàŠ° àŠšàŠ®à§àŠ¬àŠ° àŠàŠ° àŠ¬àŠŸàŠžà§àŠ àŠ¥àŠŸàŠà§ àŠ¯àŠŸ àŠàŠªàŠšàŠŸàŠà§ àŠàŠà§àŠ° àŠªàŠŸàŠ€àŠŸ àŠ¬àŠŸ àŠªàŠ°à§àŠ° àŠªàŠŸàŠ€àŠŸà§ àŠ¯à§àŠ€à§ àŠžàŠŸàŠ¹àŠŸàŠ¯à§àŠ¯ àŠàŠ°à§ à¥€àŠžà§àŠà§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸà§ àŠ¬àŠ°à§àŠ€àŠ®àŠŸàŠš àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ® àŠ®à§àŠàŠŸ àŠ
+àŠà§àŠ·àŠ°à§ àŠ²à§àŠàŠŸ àŠ¥àŠŸàŠà§,  àŠàŠ¬w àŠ€àŠŸàŠ²àŠ¿àŠàŠŸàŠàŠ¿ àŠ¬à§ àŠàŠ°àŠŸ àŠ¯àŠŸà§à¥€ àŠàŠà§àŠ²àŠ¿ àŠà§àŠ²àŠ€à§ àŠ¬àŠŸ àŠ¬àŠšà§àŠ§ àŠàŠ°àŠ€à§ àŠ«à§àŠ²àŠ¡àŠŸàŠ°àŠàŠ¿àŠ€à§ àŠàŠ¿àŠªà§àŠš ; àŠ¬àŠšà§àŠ§ àŠàŠ°àŠ€à§ àŠàŠªàŠ°à§àŠ° àŠà§àŠ²àŠŸ àŠ¬àŠàŠàŠ¿àŠ€à§  àŠàŠ¿àŠªà§àŠš à¥€</p>
+
+<p>àŠšà§àŠà§ àŠ¬àŠ°à§àŠ€àŠ®àŠŸàŠš àŠ
+wàŠ¶àŠàŠ¿ àŠ²à§àŠàŠŸ àŠàŠà§ à¥€àŠ¯àŠàŠš àŠàŠàŠ¿ àŠªà§àŠ¬à§àŠš àŠ€àŠàŠš àŠšà§àŠà§àŠ° àŠ€à§àŠ° àŠàŠà§àŠ° àŠ¬àŠŸ àŠªàŠ°à§àŠ° àŠªàŠŸàŠ€àŠŸà§ àŠšàŠ¿à§à§ àŠ¯àŠŸàŠ¬à§à¥€</p>
+
+<p> àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ® àŠ¬àŠŸ àŠªà§àŠ°àŠà§àŠàŠŠà§àŠ° àŠšà§àŠà§ àŠàŠ¿àŠà§ àŠ¬à§àŠ€àŠŸàŠ® àŠàŠà§ à¥€ àŠàŠ¿àŠªà§àŠš
+<i>àŠ²à§àŠàŠŸ àŠ¬à§ àŠàŠ°</i> àŠ¬àŠ°à§àŠ€àŠ®àŠŸàŠš àŠ
+wàŠ¶à§àŠ° àŠ²à§àŠàŠŸ àŠ¬àŠŸ àŠ¬àŠ àŠ¬à§ àŠàŠ°àŠ€à§ à¥€ àŠ¯àŠŠàŠ¿ àŠ²à§àŠàŠŸ àŠàŠ®àŠšàŠ¿àŠ€à§àŠ àŠ¬à§ àŠ¹à§ , àŠ¬à§àŠ¶à§ àŠžàŠ®à§ àŠàŠ° àŠ®à§àŠ®à§àŠ°à§ àŠ²àŠŸàŠàŠ¬à§ ! àŠàŠ¿àŠªà§àŠš  <i>àŠžà§àŠà§ àŠ¬à§ àŠàŠ°</i>àŠžà§àŠà§ àŠ¬à§ àŠàŠ°àŠ€à§ àŠ¯àŠŸàŠ€à§ àŠžà§àŠà§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠ¬à§ àŠàŠ°à§ àŠ¯àŠŸàŠ€à§ àŠžàŠ¬ àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ® , àŠ
+àŠšà§àŠà§àŠà§àŠŠ àŠ¬àŠŸ àŠ
+àŠšà§ àŠ
+wàŠ¶ àŠŠà§àŠàŠ€à§ àŠªàŠŸàŠ°à§àŠš ; àŠàŠ¿àŠªà§àŠš<i>àŠàŠ²àŠŸàŠŠàŠŸ </i>àŠàŠ àŠšàŠ¥àŠ¿àŠ° àŠàŠšà§àŠ¯àŠšà§àŠ àŠšàŠ€à§àŠš àŠ¬à§àŠ°àŠŸàŠàŠàŠŸàŠ° àŠàŠŸàŠšàŠŸàŠ²àŠŸ àŠà§àŠ²àŠ€à§ à¥€( àŠŠà§àŠàŠ¿ àŠšàŠ¥àŠ¿ àŠªà§àŠŸ àŠ¬àŠŸ àŠ€à§àŠ²àŠšàŠŸàŠ° àŠàŠšà§àŠ¯àŠŸ àŠàŠàŠ¿ àŠ­àŠŸàŠ²à§ ) àŠªàŠ°àŠ¿àŠ¶à§àŠ àŠàŠªàŠšàŠ¿ àŠ¯à§ àŠ¶àŠ¬à§àŠŠ àŠàŠà§àŠàŠà§àŠš àŠžà§àŠàŠ¿ àŠ¹àŠŸàŠàŠ²àŠŸàŠàŠ àŠ¹à§ à¥€àŠàŠ¿àŠªà§àŠš <i>àŠ¹àŠŸàŠàŠ²àŠŸàŠàŠ àŠšà§</i> àŠ¹àŠŸàŠàŠ²àŠŸàŠàŠ àŠžàŠ°àŠŸàŠ€à§</p>
+}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=bn] {àŠ¬àŠà§à§àŠ° àŠ¥àŠŸàŠàŠàŠ¿ àŠà§àŠ²à§àŠš}
+_texthelpopenbook_ [l=bn] {àŠàŠ àŠ¬àŠàŠàŠ¿ àŠà§àŠ²à§àŠš àŠ¬àŠŸ àŠ¬àŠšà§àŠ§ àŠàŠ°à§àŠš}
+_texthelpviewtextsection_ [l=bn] {àŠ²à§àŠàŠŸàŠ° àŠàŠ àŠ
+wàŠ¶àŠàŠ¿ àŠŠà§àŠà§àŠš }
+_texthelpexpandtext_ [l=bn] {àŠžàŠ¬ àŠ²à§àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§, àŠšàŠŸ àŠŠà§àŠàŠŸàŠ¬à§ àŠšàŠŸ}
+_texthelpexpandcontents_ [l=bn] {àŠžà§àŠà§ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠ¬àŠŸà§àŠŸàŠ¬à§ , àŠšàŠŸ àŠ¬àŠŸà§àŠŸàŠ¬à§ àŠšàŠŸ}
+_texthelpdetachpage_ [l=bn] {àŠàŠ àŠªàŠŸàŠ€àŠŸàŠàŠ¿ àŠšàŠ€à§àŠš àŠàŠŸàŠšàŠŸàŠ²àŠŸà§ àŠà§àŠ²à§àŠš}
+_texthelphighlight_ [l=bn] {àŠàŠà§àŠàŠŸ àŠ¶àŠ¬à§àŠŠ àŠ¹àŠŸàŠàŠ²àŠŸàŠàŠ àŠ¹àŠ¬à§ , àŠàŠ¿ àŠ¹àŠ¬à§ àŠšàŠŸ}
+
+
+_texthelpsearchingtitle_ [l=bn] {àŠàŠ¿àŠ­àŠŸàŠ¬à§ àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ àŠ¶àŠ¬à§àŠŠ àŠàŠà§àŠàŠ€à§ àŠ¹àŠ¬à§}
+
+_texthelpsearching_ [l=bn] {
+<p>
+àŠàŠà§àŠàŠŸàŠ° àŠªàŠŸàŠ€àŠŸ àŠ¥à§àŠà§ àŠàŠ àŠªàŠŠàŠà§àŠ·à§àŠªàŠà§àŠ²àŠ¿àŠ° àŠŠà§àŠ¬àŠŸàŠ°àŠŸ àŠàŠàŠàŠ¿ àŠªà§àŠ°àŠ¶à§àŠš àŠ€à§àŠ°à§ àŠàŠ°à§àŠš àŠ<p>
+  
+  <ol><li>àŠàŠ¿ àŠàŠà§àŠàŠ€à§ àŠ¹àŠ¬à§
+      <li> àŠžàŠ¬ àŠšàŠŸ àŠàŠ¿àŠà§ àŠàŠ¿àŠà§ àŠ¶àŠ¬à§àŠŠ  àŠàŠà§àŠàŠ€à§ àŠàŠŸàŠš
+      <li> àŠ¯à§ àŠ¶àŠ¬à§àŠŠ  àŠàŠà§àŠàŠ€à§ àŠàŠŸàŠš àŠ€àŠŸ àŠ²àŠ¿àŠà§àŠš
+      <li>àŠàŠ¿àŠªà§àŠš <i> àŠàŠà§àŠàŠŸ àŠ¶à§àŠ°à§</i>àŠ¬à§àŠ€àŠŸàŠ®
+  </ol>
+
+<p>àŠ¬à§àŠ€àŠŸàŠ® àŠ¥àŠŸàŠàŠ¬à§ àŠ¯àŠŸàŠ° àŠŠà§àŠ¬àŠŸàŠ°àŠŸ àŠªàŠ°àŠ¬àŠ°à§àŠ€à§ àŠà§à§àŠ¿àŠàŠŸ àŠšàŠ¥àŠ¿ àŠ¬àŠŸ àŠàŠà§àŠ° àŠà§à§àŠ¿àŠàŠŸ àŠšàŠ¥àŠ¿  àŠŠà§àŠàŠŸàŠ¬à§ àŠàŠ¬w  àŠàŠàŠ­àŠŸàŠ¬à§ àŠàŠ²àŠ¬à§à¥€ àŠŠà§àŠàŠŸàŠ° àŠàŠšà§àŠ¯  àŠ¯à§àŠà§àŠš àŠšàŠ¥àŠ¿àŠ° àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ®à§ àŠàŠ¿àŠªà§àŠš àŠ¬àŠŸ àŠªàŠŸàŠ¶à§àŠ° àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ® àŠ¬à§àŠ€àŠŸàŠ® àŠàŠ¿àŠªà§àŠš à¥€
+
+<p>àŠžàŠ°à§àŠ¬àŠŸàŠ§àŠ¿àŠ àŠàŠàŠ¶à§àŠàŠŸ àŠšàŠ¥àŠ¿ àŠŠà§àŠàŠŸàŠ¬à§à¥€àŠàŠ àŠžwàŠà§àŠ¯àŠŸ àŠªàŠ°àŠ¿àŠ¬àŠ°à§àŠ€àŠš àŠàŠ°àŠ€à§ àŠªàŠŸàŠ°à§àŠš àŠàŠ¿àŠªà§
+  <i> àŠªàŠàŠšà§àŠŠ </i>àŠ¬à§àŠ€àŠŸàŠ® àŠ¯àŠŸ àŠªàŠŸàŠ€àŠŸàŠ° àŠàŠªàŠ°à§ àŠàŠà§<p>
+}
+
+_texthelpquerytermstitle_ [l=bn] {àŠàŠà§àŠàŠŸ àŠ¶àŠ¬à§àŠŠ}
+_texthelpqueryterms_ [l=bn] {
+<p> àŠªà§àŠ°àŠ¶à§àŠš àŠ¬àŠŸàŠžà§àŠà§ àŠ¯àŠŸàŠ àŠ²àŠ¿àŠà§àŠš àŠšàŠŸ àŠà§àŠš àŠ€àŠŸ àŠªàŠ°àŠ¿àŠ¬àŠ°à§àŠ€àŠ¿àŠ€ àŠ¹à§ àŠàŠàŠàŠŸ àŠ¶àŠ¬à§àŠŠ  àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠ¯àŠŸàŠ° àŠšàŠŸàŠ® ' àŠàŠà§àŠàŠŸ àŠ¶àŠ¬à§àŠŠàŠà§àŠ²àŠ¿'  à¥€àŠªà§àŠ°àŠ€à§àŠ¯à§àŠ àŠ¶àŠ¬à§àŠŠà§ àŠ¬àŠ°à§àŠ£àŠ®àŠŸàŠ²àŠŸ àŠ àŠžwàŠà§àŠ¯àŠŸ àŠàŠŸà§àŠŸ àŠàŠ° àŠàŠ¿àŠà§àŠ àŠ¥àŠŸàŠà§àŠšàŠŸà¥€ àŠªà§àŠ°àŠ€à§àŠ¯à§àŠ àŠ¶àŠ¬à§àŠŠ àŠ«àŠàŠŸàŠàŠŸ àŠŠàŠ¿à§à§ àŠàŠ²àŠŸàŠŠàŠŸ àŠàŠ°àŠŸ àŠ¥àŠŸàŠà§ à¥€ àŠ¯àŠ€àŠ¿àŠàŠ¿àŠ¹à§àŠšà§àŠ° àŠà§àŠ·à§àŠ€à§àŠ°à§ àŠ«àŠàŠŸàŠàŠŸ àŠàŠŸà§àŠàŠŸ àŠ¥àŠŸàŠà§ à¥€ àŠ¯àŠ€àŠ¿àŠàŠ¿àŠ¹à§àŠšàŠ¯à§àŠà§àŠ€ àŠ¶àŠ¬à§àŠŠ àŠàŠªàŠšàŠ¿ àŠàŠà§àŠàŠ€à§ àŠªàŠŸàŠ°à§àŠš àŠšàŠŸ à¥€
+
+<p> àŠàŠŠàŠŸàŠ¹àŠ°àŠ£ àŠ¹àŠ¿àŠžàŠŸàŠ¬à§ , àŠªà§àŠ°àŠ¶à§àŠš<p>
+    <ul><kbd>àŠªà§àŠ°àŠ¶àŠŸàŠšà§àŠ€ àŠ®àŠ¹àŠŸàŠžàŠŸàŠàŠ°à§àŠ° àŠŠà§àŠ¬à§àŠªà§àŠ° àŠàŠà§àŠ°à§- àŠ«àŠ°à§àŠ·à§àŠà§àŠ°à§àŠ àŠžàŠ¿àŠžà§àŠà§àŠ® àŠ«àŠ° àŠžàŠŸàŠžà§àŠà§àŠšàŠ¿àŠ¬àŠ¿àŠ²àŠ¿àŠàŠ¿ ( à§§à§¯à§©à§© )</kbd></ul>
+      <p>àŠ¹àŠ¿àŠžàŠŸàŠ¬à§ àŠà§àŠ°àŠ¹àŠ£ àŠ¹àŠ¬à§ <p>
+      <ul><kbd>àŠªà§àŠ°àŠ¶àŠŸàŠšà§àŠ€ àŠ®àŠ¹àŠŸàŠžàŠŸàŠàŠ°à§àŠ° àŠŠà§àŠ¬à§àŠªà§àŠ° àŠàŠà§àŠ°à§- àŠ«àŠ°à§àŠ·à§àŠà§àŠ°à§ àŠžàŠ¿àŠžà§àŠà§àŠ® àŠ«àŠ° àŠžàŠŸàŠžà§àŠà§àŠšàŠ¿àŠ¬àŠ¿àŠ²àŠ¿àŠàŠ¿  à§§à§¯à§©à§©  </kbd></ul><p>
+}
+
+_texthelpquerytypetitle_ [l=bn] {àŠªà§àŠ°àŠ¶à§àŠšà§àŠ° àŠ§àŠ°àŠ£}
+_texthelpquerytype_ [l=bn] {
+<p>àŠŠà§ àŠ§àŠ°àŠ£à§àŠ° àŠªà§àŠ°àŠ¶à§àŠš àŠ¹àŠ€à§ àŠªàŠŸàŠ°à§
+
+<ul>
+  <li>àŠàŠšà§àŠ¯ àŠªà§àŠ°àŠ¶à§àŠš <b>àŠžàŠ¬</b>àŠ¶àŠ¬à§àŠŠà§àŠ° à¥€ àŠàŠàŠ¿ àŠŠà§àŠà§ àŠšàŠ¥àŠ¿ ( àŠ
+àŠ¥àŠ¬àŠŸ àŠ
+àŠšà§àŠà§àŠà§àŠŠ , àŠ
+àŠ¥àŠ¬àŠŸ àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ® ) àŠ¯à§ àŠ¶àŠ¬à§àŠŠàŠà§àŠ²àŠ¿ àŠàŠªàŠšàŠ¿ àŠàŠŸàŠš à¥€àŠ¯à§àŠžàŠ®àŠžà§àŠ€ àŠšàŠ¥àŠ¿àŠà§àŠ²à§ àŠ®à§àŠ²à§ àŠžà§àŠà§àŠ²à§ àŠ¬àŠ°à§àŠ£àŠŸàŠšà§àŠžàŠŸàŠ°à§ àŠŠà§àŠàŠŸà§à¥€<p>
+
+  <li>àŠàŠšà§àŠ¯ àŠªà§àŠ°àŠ¶à§àŠš  <b>àŠàŠ¿àŠà§</b>àŠ¶àŠ¬à§àŠŠà§àŠ° à¥€ àŠšàŠ¥àŠ¿àŠ€à§ àŠ¯à§àŠžàŠ®àŠžà§àŠ€ àŠ¶àŠ¬à§àŠŠàŠà§àŠ²à§ àŠàŠà§àŠàŠà§àŠš àŠ€àŠŸàŠ° àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ àŠŠà§àŠàŠŸàŠ¬à§ à¥€ àŠªà§àŠ°àŠ¶à§àŠšà§àŠ° àŠžàŠŸàŠ¥à§ àŠ¯àŠ€ àŠàŠŸàŠàŠŸàŠàŠŸàŠàŠ¿ àŠšàŠ¥àŠ¿ àŠ®àŠ¿àŠ²àŠ¬à§ àŠžà§àŠà§àŠ²à§ àŠŠà§àŠàŠŸàŠ¬à§à¥€àŠ¯àŠàŠš  àŠ®à§àŠ²àŠŸàŠ° àŠ¡àŠ¿àŠà§àŠ°à§ àŠšàŠ¿àŠ°à§àŠ£à§ àŠàŠ°àŠŸ àŠ¹àŠ¬à§ 
+
+      <p><ul>
+        <li> àŠ¯àŠ€àŠ¬à§àŠ¶à§ àŠàŠà§àŠàŠŸ àŠ¶àŠ¬à§àŠŠ àŠšàŠ¥àŠ¿àŠ€à§ àŠ¥àŠŸàŠàŠ¬à§ ,  àŠ€àŠ€ àŠàŠŸàŠàŠŸàŠàŠŸàŠàŠ¿ àŠ®àŠ¿àŠ²àŠ¬à§
+        <li> àŠ¬à§àŠ¶à§ àŠ®à§àŠ²àŠŸ àŠ¶àŠ¬à§àŠŠà§àŠ° àŠ¥à§àŠà§ àŠàŠ® àŠ®à§àŠ²àŠŸ àŠ¶àŠ¬à§àŠŠ àŠ¬à§àŠ¶à§ àŠà§àŠ°à§àŠ€à§àŠ¬àŠªà§àŠ°à§àŠ£ ;
+        <li> àŠ¬à§ àŠšàŠ¥àŠ¿àŠ° àŠ¥à§àŠà§ àŠà§àŠ àŠšàŠ¥àŠ¿ àŠ¬à§àŠ¶à§ àŠ­àŠŸàŠ²à§ àŠ®à§àŠ²à§à¥€
+      </ul>
+</ul>
+
+<p> àŠ¯àŠ€àŠà§àŠ¶à§ àŠ¶àŠ¬à§àŠŠ àŠàŠà§àŠà§àŠš- àŠªà§àŠ°à§ àŠ¬àŠŸàŠà§àŠ¯ àŠ¬àŠŸ àŠªà§àŠ°à§ àŠ
+àŠšà§àŠà§àŠà§àŠŠà¥€ àŠ¯àŠŠàŠ¿ àŠ®àŠŸàŠ€à§àŠ° àŠàŠàŠàŠŸ àŠ¶àŠ¬à§àŠŠ àŠ¹à§ àŠ€àŠŸàŠ¹àŠ²à§ àŠ€àŠŸàŠ° àŠàŠªàŠžà§àŠ¥àŠ¿àŠ€àŠ¿àŠ° àŠžwàŠà§àŠ¯àŠŸ àŠ
+àŠšà§àŠ¯àŠŸà§à§ àŠšàŠ¥àŠ¿ àŠžàŠŸàŠàŠ¿à§à§ àŠŠà§àŠàŠŸàŠ¬à§à¥€<p>
+}
+
+_textdatesearch_ [l=bn] {àŠ€àŠŸàŠ°àŠ¿àŠ àŠ
+àŠšà§àŠžàŠŸàŠ°à§ àŠàŠà§àŠàŠà§}
+
+_texthelpdatesearch_ [l=bn] {
+àŠ€àŠŸàŠ°àŠ¿àŠ àŠàŠà§àŠ àŠàŠªàŠšàŠŸàŠà§ àŠŠà§à§ àŠžà§àŠ àŠžà§àŠ¬àŠ¿àŠ§àŠŸ àŠ¯àŠŸàŠ€à§ àŠàŠàŠàŠ¿ àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ àŠžàŠ®à§àŠàŠŸàŠ²à§ àŠàŠà§ àŠ¯àŠŸàŠà§àŠŸ àŠàŠàŠšàŠŸ àŠžàŠ®à§àŠªàŠ°à§àŠàŠ¿àŠ€ àŠšàŠ¥àŠ¿àŠàŠ¿ àŠªàŠŸàŠà§àŠŸ àŠ¯àŠŸà§ àŠàŠªàŠšàŠŸàŠ° àŠàŠà§àŠàŠŸ àŠ¶àŠ¬à§àŠŠ àŠ
+àŠšà§à§àŠŸàŠ¯à§ à¥€àŠàŠªàŠšàŠ¿ àŠàŠàŠŸàŠ§àŠ¿àŠ àŠ¬àŠàŠ°à§àŠ° àŠ¬àŠŸ àŠà§àŠš àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ àŠ¬àŠàŠ°à§àŠ° àŠšàŠ¥àŠ¿ àŠàŠà§àŠàŠ€à§ àŠªàŠŸàŠ°à§àŠšà¥€ àŠàŠªàŠšàŠ¿  àŠà§àŠš àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ àŠàŠà§àŠàŠŸ àŠ¶àŠ¬à§àŠŠ àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ° àŠšàŠŸ àŠàŠ°à§ àŠ¶à§àŠ§à§ àŠ€àŠŸàŠ°àŠ¿àŠ àŠŠàŠ¿à§à§ àŠàŠà§àŠàŠ€à§ àŠªàŠŸàŠ°à§àŠš; àŠàŠàŠŸà§àŠŸàŠ àŠàŠà§àŠàŠŸà§ àŠ€àŠŸàŠ°àŠ¿àŠ àŠ¬àŠ¬àŠ¹àŠŸàŠ° àŠšàŠŸ àŠàŠ°àŠ²à§àŠ àŠàŠ²àŠ¬à§ , àŠ¯àŠŠàŠ¿ àŠàŠªàŠšàŠ¿  àŠà§àŠš àŠ€àŠŸàŠ°àŠ¿àŠ àŠšàŠŸ àŠŠà§àŠš àŠ€àŠŸàŠ¹àŠ²à§ àŠžà§àŠ¬àŠŸàŠ­àŠŸàŠ¬àŠ¿àŠ àŠ€àŠŸàŠ°àŠ¿àŠ àŠ¬àŠ¿àŠ¹à§àŠš àŠàŠà§àŠà§àŠ° àŠ®àŠ€à§ àŠàŠŸàŠ àŠàŠ°àŠ¬à§à¥€
+<p>
+}
+
+_texthelpdatehowtotitle_ [l=bn] {àŠàŠ¿ àŠàŠ°à§ àŠàŠ àŠ¬à§àŠ¶àŠ¿àŠ·à§àŠà§àŠ¯ àŠ¬àŠ¬àŠ¹àŠŸàŠ° àŠàŠ°àŠ€à§ àŠ¹à§ àŠ}
+_texthelpdatehowto_ [l=bn] {
+<ul>
+   <li>àŠàŠ àŠ¬àŠàŠ°à§àŠ° àŠšàŠ¥àŠ¿ àŠàŠà§àŠ àŠàŠ°àŠ€à§ àŠ¹àŠ²à§ àŠ:<p>
+   <ul>
+       <li>àŠžàŠŸàŠ§àŠ°àŠ£àŠ€  àŠ¯àŠŸ àŠàŠ°à§àŠš àŠ€à§àŠ®àŠšàŠ àŠàŠà§àŠàŠŸàŠ° àŠàŠšà§àŠ¯ àŠàŠàŠàŠŸ àŠ¶àŠ¬à§àŠŠ àŠ²àŠ¿àŠà§àŠš
+       <li> àŠ¯à§ àŠ¬àŠàŠ° àŠàŠŸàŠš àŠžà§àŠàŠ¿ " àŠ¶à§àŠ°à§ ( àŠ
+àŠ¥àŠ¬àŠŸ  àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ ) àŠ€àŠŸàŠ°àŠ¿àŠ " àŠ¬àŠŸàŠžà§àŠà§ àŠ²àŠ¿àŠà§àŠš
+       <li>àŠ¯àŠŠàŠ¿ àŠàŠªàŠšàŠŸàŠ° àŠ€àŠŸàŠ°àŠ¿àŠàŠàŠ¿ àŠšàŠ€à§àŠš àŠ¯à§àŠà§àŠ° àŠàŠà§ ( àŠà§àŠ·à§àŠàŠªà§àŠ°à§àŠ¬àŠŸàŠ¬à§àŠŠà§ ) , àŠ€àŠŸàŠ¹àŠ²à§ àŠªà§àŠ² àŠ¡àŠŸàŠàŠš àŠ®à§àŠšà§ àŠ¥à§àŠà§ ' àŠ¬àŠ¿ àŠžàŠ¿ àŠ ' àŠ¬àŠ¿àŠàŠ²à§àŠª àŠªàŠàŠšà§àŠŠ àŠàŠ°à§àŠš àŠªàŠŸàŠ¶à§àŠ° àŠ¬àŠŸàŠžà§àŠà§à¥€  
+       <li>àŠžàŠŸàŠ§àŠ°àŠ£àŠ€  àŠ¯àŠŸ àŠàŠ°à§àŠš àŠ€à§àŠ®àŠšàŠ àŠàŠà§àŠàŠŸ àŠ¶à§àŠ°à§ àŠàŠ°à§àŠš
+   </ul>
+<p><li>àŠàŠªàŠšàŠ¿ àŠàŠàŠŸàŠ§àŠ¿àŠ àŠ¬àŠàŠ°à§àŠ° àŠ¬àŠŸ àŠà§àŠš àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ àŠ¬àŠàŠ°à§àŠ° àŠšàŠ¥àŠ¿ àŠàŠà§àŠàŠŸàŠ° àŠàŠšà§àŠ¯ <p>
+   <ul>
+       <li>àŠžàŠŸàŠ§àŠ°àŠ£àŠ€  àŠ¯àŠŸ àŠàŠ°à§àŠš àŠ€àŠŸàŠ àŠàŠà§àŠàŠŸ àŠ¶àŠ¬à§àŠŠ -à§à§àŠ° àŠàŠšà§àŠ¯ àŠ²àŠ¿àŠà§àŠš
+       <li>àŠªà§àŠ°à§àŠ¬à§àŠ° àŠ€àŠŸàŠ°àŠ¿àŠàŠàŠ¿ àŠ²àŠ¿àŠà§àŠš  " àŠ¶à§àŠ°à§ ( àŠ
+àŠ¥àŠ¬àŠŸ àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ ) àŠ€àŠŸàŠ°àŠ¿àŠ " àŠ¬àŠŸàŠžà§àŠà§ 
+       <li>àŠªàŠ°àŠ¬àŠ°à§àŠ€à§ àŠ€àŠŸàŠ°àŠ¿àŠàŠàŠ¿ àŠ²àŠ¿àŠà§àŠš  " àŠ¶à§àŠ· àŠ€àŠŸàŠ°àŠ¿àŠ " àŠ¬àŠŸàŠžà§àŠà§ 
+       <li> ' àŠ¬àŠ¿ àŠžàŠ¿ àŠ ' àŠ¬àŠ¿àŠàŠ²à§àŠª àŠªàŠàŠšà§àŠŠ àŠàŠ°à§àŠš àŠªàŠŸàŠ¶à§àŠ° àŠªà§àŠ² àŠ¡àŠŸàŠàŠš àŠ®à§àŠšà§ àŠ¥à§àŠà§ ; àŠªàŠ°à§àŠ° àŠ€àŠŸàŠ°àŠ¿àŠàŠàŠ¿ àŠ²àŠ¿àŠà§àŠš àŠšàŠ€à§àŠš àŠ¯à§àŠà§àŠ° àŠàŠà§ ( àŠà§àŠ·à§àŠàŠªà§àŠ°à§àŠ¬àŠŸàŠ¬à§àŠŠà§ ) 
+       <li>àŠžàŠŸàŠ§àŠ°àŠ£àŠ€  àŠ¯àŠŸ àŠàŠ°à§àŠš àŠ€à§àŠ®àŠšàŠ àŠàŠà§àŠàŠŸ àŠ¶à§àŠ°à§ àŠàŠ°à§àŠš
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=bn] {àŠ¯à§àŠ­àŠŸàŠ¬à§ àŠàŠªàŠšàŠŸàŠ° àŠàŠà§àŠàŠŸàŠ° àŠ«àŠ²àŠŸàŠ«àŠ² àŠªàŠŸàŠà§àŠŸ àŠ¯àŠŸàŠ¬à§}
+_texthelpdateresults_ [l=bn] {
+<p> àŠžàŠŸàŠ§àŠŸàŠ°àŠ£àŠ€ à§§à§¯à§Šà§© àŠžàŠŸàŠ²à§àŠ° àŠšàŠ¥àŠ¿ àŠŠà§àŠàŠŸàŠ¬à§ àŠšàŠŸ à¥€ àŠžà§àŠ€àŠ°àŠŸw àŠà§àŠš àŠàŠàŠàŠ¿ àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ àŠžàŠ®à§àŠžà§àŠ®àŠŸàŠ° àŠ®àŠ§à§àŠ¯à§àŠàŠŸàŠ° àŠšàŠ¥àŠ¿ àŠŠà§àŠàŠŸàŠ¬à§ ( àŠàŠŠàŠŸàŠ¹àŠ°àŠ£ àŠ à§§à§®à§¯à§¯ - à§§à§¯à§§à§§ ) àŠ¯àŠŸàŠ° àŠ®àŠ§à§àŠ¯à§ à§§à§¯à§Šà§© àŠàŠà§ , àŠàŠàŠŸà§àŠŸàŠ àŠžà§àŠžàŠ®àŠžà§àŠ€ àŠšàŠ¥àŠ¿ àŠ¯àŠŸàŠ° àŠ®àŠ§à§àŠ¯à§ à§§à§¯à§Šà§© -à§à§àŠ° àŠàŠ²à§àŠ²à§àŠ àŠàŠà§ ( àŠ¯à§àŠ®àŠš à§šà§Š àŠ€àŠ® àŠ¶àŠ€àŠŸàŠ¬à§àŠŠà§ àŠ¬àŠŸ àŠà§à§àŠ¿ àŠ€àŠ® àŠ¶àŠ€àŠŸàŠ¬à§àŠŠà§)à¥€ àŠ
+àŠ°à§àŠ¥àŠŸv àŠšàŠ¥àŠ¿àŠ€à§ àŠžàŠ¬àŠžàŠ®à§ àŠàŠªàŠšàŠŸàŠ° àŠàŠà§àŠàŠŸ àŠ€àŠŸàŠ°àŠ¿àŠ àŠŠà§àŠàŠŸ àŠ¯àŠŸàŠ¬à§ àŠšàŠŸ à¥€ àŠà§àŠš àŠàŠàŠàŠ¿ àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ àŠžàŠ®à§àŠžà§àŠ®àŠŸàŠ° àŠ®àŠ§à§àŠ¯à§àŠàŠŸàŠ° àŠšàŠ¥àŠ¿ àŠàŠà§àŠàŠŸàŠ° àŠàŠšà§àŠ¯ àŠžàŠ¬ àŠ€àŠŸàŠ°àŠ¿àŠà§àŠ° àŠàŠšà§àŠ¯àŠ àŠ€àŠŸ àŠªà§àŠ°àŠ¬àŠ°à§àŠ€àŠ¿àŠ€ àŠ¹àŠ¬à§à¥€
+}
+
+_textchangeprefs_ [l=bn] {àŠàŠªàŠšàŠŸàŠ° àŠªàŠàŠšà§àŠŠ àŠªàŠ°àŠ¿àŠ¬àŠ°à§àŠ€àŠš àŠ¹àŠà§àŠà§}
+
+_texthelppreferences_ [l=bn] {
+
+<p>àŠ¯àŠàŠš àŠàŠªàŠšàŠ¿ àŠàŠ¿àŠªàŠ¬à§àŠš<i>àŠªàŠàŠšà§àŠŠ</i> àŠªàŠŸàŠ€àŠŸàŠ° àŠàŠªàŠ°à§àŠ° àŠ¬à§àŠ€àŠŸàŠ® , àŠàŠªàŠšàŠŸàŠ° àŠàŠà§àŠà§àŠ®àŠ€à§ àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ°à§àŠ° àŠ¬à§àŠ¶àŠ¿àŠ·à§àŠà§àŠ¯ àŠªàŠ°àŠ¿àŠ¬àŠ°à§àŠ€àŠš àŠàŠ°àŠ€à§ àŠªàŠŸàŠ°àŠ¬à§àŠšà¥€
+}
+
+_texthelpcollectionprefstitle_ [l=bn] {àŠžwàŠà§àŠ°àŠ¹ àŠªàŠàŠšà§àŠŠ }
+_texthelpcollectionprefs_ [l=bn] {
+àŠàŠàŠàŠ¿ àŠžwàŠà§àŠ°àŠ¹à§ àŠ
+àŠšà§àŠ àŠ
+àŠšà§àŠžwàŠà§àŠ°àŠ¹ àŠàŠà§, àŠ¯àŠŸ àŠàŠ àŠàŠàŠ àŠ¹àŠ¿àŠžàŠŸàŠ¬à§ àŠàŠ²àŠŸàŠŠàŠŸ àŠàŠ²àŠŸàŠŠàŠŸ àŠ­àŠŸàŠ¬à§ àŠ¬àŠŸ àŠàŠàŠžàŠŸàŠ¥à§ àŠàŠà§àŠàŠŸ àŠ¯à§àŠ€à§ àŠªàŠŸàŠ°à§à¥€àŠ¯àŠŠàŠ¿ àŠ€àŠŸàŠ àŠ¹à§ àŠ€àŠ¬à§ 
+ àŠà§àŠš àŠ
+àŠšà§àŠžwàŠà§àŠ°àŠ¹ àŠàŠªàŠšàŠŸàŠ° àŠªàŠàŠšà§àŠŠà§àŠ° àŠªàŠŸàŠ€àŠŸà§ àŠ
+àŠšà§àŠ€àŠ°à§àŠ­à§àŠà§àŠ€ àŠ¹àŠ¬à§ àŠ€àŠŸ àŠàŠªàŠšàŠ¿ àŠªàŠàŠšà§àŠŠ àŠàŠ°àŠ€à§ àŠªàŠŸàŠ°à§àŠšà¥€
+}
+
+_texthelplanguageprefstitle_ [l=bn] {àŠ­àŠŸàŠ·àŠŸ àŠªàŠàŠšà§àŠŠ}
+_texthelplanguageprefs_ [l=bn] {
+ àŠªà§àŠ°àŠ€à§àŠ¯à§àŠ àŠžwàŠà§àŠ°àŠ¹à§àŠ° àŠšàŠ¿àŠàŠžà§àŠ¬ àŠ­àŠŸàŠ·àŠŸ àŠàŠà§ àŠ¯àŠŸ àŠªàŠ°àŠ¿àŠ¬àŠ°à§àŠ€àŠšàŠ¯à§àŠà§àŠ¯ à¥€ àŠàŠªàŠšàŠ¿ àŠ¬à§àŠ°àŠŸàŠàŠàŠŸàŠ°à§ àŠ«àŠ²àŠŸàŠ«àŠ² àŠŠà§àŠàŠŸàŠšà§àŠ° àŠàŠšà§àŠ¯ àŠà§àŠ°à§àŠšàŠžà§àŠà§àŠšà§àŠ° àŠàŠšàŠà§àŠ¡àŠ¿w   àŠªàŠŠà§àŠ§àŠ€àŠ¿àŠ àŠªàŠ°àŠ¿àŠ¬àŠ°à§àŠ€àŠš àŠàŠ°àŠ€à§ àŠªàŠŸàŠ°à§àŠš -- àŠžàŠ«à§âàŠàŠà§àŠŸàŠ° àŠàŠªàŠ¯à§àŠà§àŠ€ àŠªàŠŠà§àŠ§àŠ€àŠ¿ àŠªàŠàŠšà§àŠŠ àŠàŠ°à§ àŠàŠ¿àŠšà§àŠ€à§ àŠà§àŠš àŠà§àŠš àŠ¬à§àŠ°àŠŸàŠàŠàŠŸàŠ°à§ àŠ­àŠŸàŠ²à§ àŠŠà§àŠ¶à§àŠ¯ àŠŠà§àŠàŠŸàŠ° àŠàŠšà§àŠ¯ àŠ
+àŠšà§àŠ¯
+ àŠàŠšàŠà§àŠ¡àŠ¿w àŠªàŠŠà§àŠ§àŠ€àŠ¿ àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ° àŠ¹à§à¥€ àŠžàŠ¬ àŠžwàŠà§àŠ°àŠ¹àŠ àŠàŠªàŠšàŠŸàŠà§ àŠàŠ àŠ­àŠ¿àŠ€à§àŠ€àŠ¿àŠ àŠ«àŠ°àŠ®à§àŠ¯àŠàŠž àŠ¥à§àŠà§ àŠ²à§àŠàŠ¿àŠ àŠ«àŠ°àŠ®à§àŠ¯àŠàŠž-àŠ àŠ¯à§àŠ€à§à¥€ àŠ¯àŠŸàŠ°àŠŸ àŠ«àŠ²àŠŸàŠ«àŠ²à§àŠ° àŠàŠšà§àŠ¯    àŠ¬à§ àŠªàŠ°à§àŠŠàŠŸàŠ° àŠ«àŠšà§àŠ àŠ¬àŠŸ àŠ¶àŠ¬à§àŠŠ àŠžàŠ¿àŠšà§àŠ¥à§àŠžàŠŸàŠàŠàŠŸàŠ°  àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ° àŠàŠ°à§àŠš àŠ€àŠŸàŠŠà§àŠ° àŠàŠšà§àŠ¯ àŠàŠàŠ¿ àŠàŠªàŠ¯à§àŠà§àŠ€à¥€ 
+}
+
+_texthelppresentationprefstitle_ [l=bn] {àŠàŠªàŠžà§àŠ¥àŠŸàŠªàŠšàŠŸ àŠªàŠàŠšà§àŠŠàŠà§àŠ²àŠ¿}
+_texthelppresentationprefs_ [l=bn] {
+àŠà§àŠš àŠšàŠ¿àŠ°à§àŠŠàŠ¿àŠ·à§àŠ àŠžwàŠà§àŠ°àŠ¹à§àŠ° àŠàŠªàŠ° àŠ­àŠ¿àŠ€à§àŠ€àŠ¿ àŠàŠ°à§ , àŠàŠªàŠšàŠ¿ àŠàŠªàŠžà§àŠ¥àŠŸàŠªàŠšà§àŠ° àŠ¬àŠ¿àŠ­àŠ¿àŠšà§àŠš àŠ¬àŠ¿àŠàŠ²à§àŠª àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ° àŠàŠ°àŠ€à§ àŠªàŠŸàŠ°à§àŠšà¥€
+
+<p>àŠà§à§àŠ¬àŠªàŠŸàŠ€àŠŸ àŠžwàŠà§àŠ°àŠ¹ àŠªà§àŠ°àŠ€à§àŠ¯à§àŠàŠàŠ¿ àŠšàŠ¥àŠ¿àŠ° àŠàŠªàŠ°à§àŠ°  àŠà§àŠ°à§àŠšàŠžà§àŠà§àŠš àŠšà§àŠ­àŠ¿àŠà§àŠ¶àŠŸàŠš àŠŠàŠšà§àŠ¡àŠà§ àŠžàŠŸàŠªà§àŠ°à§àŠž àŠàŠ°àŠ€à§ àŠ
+àŠ§àŠ¿àŠàŠŸàŠ° àŠŠà§à§à¥€àŠ¯àŠŸàŠ€à§ àŠžà§àŠ àŠžàŠ®àŠžà§àŠ€ àŠà§à§àŠ¬ àŠªàŠŸàŠ€àŠŸà§ àŠàŠªàŠšàŠŸàŠà§ àŠ«àŠ¿àŠ°àŠ¿à§à§ àŠŠà§à§ àŠ¯àŠŸ àŠàŠªàŠšàŠ¿ àŠàŠàŠ¬àŠŸàŠ° àŠàŠà§àŠà§àŠà§àŠš àŠàŠ¬w àŠ¯àŠŸàŠ° àŠžàŠŸàŠ¥à§ àŠà§àŠ°à§àŠšàŠžà§àŠà§àŠš àŠ¹à§àŠ¡àŠŸàŠ°à§àŠ° àŠà§àŠš àŠ®àŠ¿àŠ² àŠšà§àŠà¥€ àŠªà§àŠšàŠàŠ°àŠŸà§ àŠàŠà§àŠàŠŸàŠ° àŠàŠšà§àŠ¯ àŠ¬à§àŠ°àŠŸàŠàŠàŠŸàŠ°à§àŠ° " àŠªà§àŠàŠš " àŠ¬à§àŠ€àŠŸàŠ® àŠàŠ¿àŠªà§àŠšà¥€ àŠàŠ àŠžwàŠà§àŠ°àŠ¹ àŠàŠªàŠšàŠŸàŠà§ àŠà§àŠ°à§àŠšàŠžà§àŠà§àŠš àŠžàŠ€àŠ°à§àŠà§àŠàŠ°àŠ£ àŠ¬àŠŸàŠ°à§àŠ€àŠŸàŠà§  àŠžàŠŸàŠªà§àŠ°à§àŠž àŠàŠ°àŠ€à§ àŠ
+àŠ§àŠ¿àŠàŠŸàŠ° àŠŠà§à§, àŠ¯àŠàŠš  àŠàŠªàŠšàŠ¿ àŠà§à§àŠ¬àŠªàŠŸàŠ€àŠŸ àŠ¬àŠŸ àŠžwàŠà§àŠ°àŠ¹à§àŠ° àŠªàŠŸàŠ€àŠŸ àŠ¥à§àŠà§ àŠ¬à§àŠ°àŠ¿à§à§ àŠ¯à§àŠ€à§ àŠàŠŸàŠšà¥€ àŠàŠ¬w àŠàŠ¿àŠà§ àŠàŠ¿àŠà§ àŠžwàŠà§àŠ°àŠ¹à§àŠ° àŠà§àŠ·à§àŠ€à§àŠ°à§  àŠà§àŠš àŠªà§àŠ°àŠ¶à§àŠšà§àŠ° àŠªàŠ°àŠ¿àŠªà§àŠ°à§àŠà§àŠ·àŠ¿àŠ€à§ " àŠàŠà§àŠàŠŸàŠ° àŠ«àŠ²àŠŸàŠ«àŠ² " àŠà§à§àŠ¬ àŠ àŠ¿àŠàŠŸàŠšàŠŸ àŠ¬àŠŸ àŠ¡àŠ¿àŠàŠ¿àŠà§àŠ¯àŠŸàŠ² àŠà§àŠ°àŠšà§àŠ¥àŠŸàŠàŠŸàŠ°à§ àŠ°àŠŸàŠàŠŸ àŠžwàŠà§àŠ°àŠ¹à§àŠ° àŠ
+àŠšà§àŠ°à§àŠªà§àŠ° àŠªàŠŸàŠ€àŠŸà§ àŠ¯àŠŸàŠà§àŠŸ àŠàŠªàŠšàŠ¿ àŠšàŠ¿à§àŠšà§àŠ€à§àŠ°àŠ£ àŠàŠ°àŠ€à§ àŠªàŠŸàŠ°à§àŠšà¥€
+}
+
+_texthelpsearchprefstitle_ [l=bn] {àŠªàŠàŠšà§àŠŠ àŠàŠà§àŠà§àŠš}
+_texthelpsearchprefs_ [l=bn] {
+<p>àŠàŠªàŠšàŠ¿ àŠ¯àŠŸ àŠàŠà§àŠàŠ€à§ àŠàŠŸàŠš àŠ€àŠŸ àŠŠà§ àŠà§à§àŠŸ àŠ¬à§àŠ€àŠŸàŠ® àŠšàŠ¿à§àŠšà§àŠ€à§àŠ°àŠ£ àŠàŠ°à§à¥€ àŠªà§àŠ°àŠ¥àŠ®àŠàŠ¿ àŠ àŠ¿àŠ àŠàŠ°à§ ( " àŠà§àŠàŠ¹àŠŸàŠ€  àŠ¬à§àŠ¹àŠŸàŠ€ àŠªàŠŸàŠ°à§àŠ¥àŠà§àŠ¯ " àŠ²à§àŠàŠŸ ) àŠà§àŠàŠ¹àŠŸàŠ€  àŠ¬à§àŠ¹àŠŸàŠ€ àŠ®à§àŠ²àŠŸàŠšà§ àŠšàŠ¿à§àŠšà§àŠ€à§àŠ°àŠ£ àŠàŠ°à§à¥€ àŠŠà§àŠ¬àŠ¿àŠ€à§à§àŠàŠ¿ ( " àŠ¶àŠ¬à§àŠŠà§àŠ° àŠ¶à§àŠ·àŠŸwàŠ¶ " ) àŠšàŠ¿à§àŠšà§àŠ€à§àŠ°àŠ£ àŠàŠ°à§ àŠ¯àŠŸ àŠŠà§àŠà§ àŠ¶àŠ¬à§àŠŠà§àŠ° àŠ¶à§àŠ·àŠŸwàŠ¶ àŠàŠªà§àŠà§àŠ·àŠŸ àŠàŠ°àŠŸ àŠ¹à§à§àŠà§ àŠàŠ¿ àŠšàŠŸà¥€ àŠ¬à§ àŠªà§àŠ°àŠ¶à§àŠš àŠ¬àŠŸàŠžà§àŠ àŠªàŠŸàŠà§àŠŸàŠ° àŠžàŠ®à§àŠ­àŠŸàŠ¬àŠšàŠŸ àŠàŠà§ , àŠ¯àŠŸàŠ€à§ àŠàŠªàŠšàŠ¿ àŠžàŠ¹àŠà§àŠ àŠ
+àŠšà§àŠà§àŠŠ àŠ¹àŠ¿àŠžà§àŠ¬à§ àŠàŠà§àŠàŠ€à§ àŠªàŠŸàŠ°à§àŠšà¥€àŠ¬à§ àŠ²à§àŠàŠŸ àŠàŠà§àŠàŠŸàŠ° àŠàŠšà§àŠ¯ àŠàŠàŠ¿ àŠàŠªàŠ¯à§àŠà§àŠ€à¥€
+
+<p>àŠàŠŠàŠŸàŠ¹àŠ°àŠ£ àŠ¹àŠ¿àŠžàŠŸàŠ¬à§ àŠ¬à§àŠ€àŠŸàŠ®àŠà§àŠ²àŠ¿ <i>àŠà§àŠàŠ¹àŠŸàŠ€  àŠ¬à§àŠ¹àŠŸàŠ€ àŠªàŠŸàŠ°à§àŠ¥àŠà§àŠ¯</i>àŠàŠ¬w<i>àŠ¶àŠ¬à§àŠŠà§àŠ° àŠ¶à§àŠ·àŠŸwàŠ¶ àŠàŠªà§àŠà§àŠ·àŠŸ àŠàŠ°à§</i>àŠªàŠàŠšà§àŠŠ àŠàŠ°à§àŠà§ , àŠªà§àŠ°àŠ¶à§àŠš<p>
+    <ul><kbd>àŠàŠ«à§àŠ°àŠ¿àŠàŠŸàŠ° àŠ¬àŠŸàŠ°àŠ¿àŠàŠ°</kbd></ul>
+      <p>àŠàŠ°àŠàŠ®àŠ­àŠŸàŠ¬à§ àŠà§àŠ°àŠ¹àŠ£ àŠàŠ°àŠŸ àŠ¹àŠ¬à§<p>
+      <ul><kbd>àŠàŠ«à§àŠ°àŠ¿àŠàŠŸ àŠ€à§àŠ°à§ àŠàŠ°à§</kbd></ul><p>
+àŠà§àŠšàŠšàŠŸ " àŠàŠ«à§àŠ°àŠ¿àŠàŠŸ " - à§à§àŠ° àŠ¬à§àŠ¹àŠŸàŠ€à§àŠ° àŠ
+àŠà§àŠ·àŠ° àŠà§àŠàŠ¹àŠŸàŠ€à§àŠ° àŠ
+àŠà§àŠ·àŠ°à§ àŠ°à§àŠªàŠŸàŠšà§àŠ€àŠ°àŠ¿àŠ€ àŠ¹àŠ¬à§ àŠàŠ¬w àŠ¶à§àŠ·à§àŠ° "àŠàŠš" àŠàŠ° " àŠw " àŠ¯àŠ¥àŠŸàŠà§àŠ°àŠ®à§ " àŠàŠ«à§àŠ°àŠ¿àŠàŠŸàŠš" àŠàŠ¬w  " àŠ¬àŠ¿àŠ²àŠ¡àŠ¿w " àŠ¥à§àŠà§ àŠ¬àŠŸàŠŠ àŠ¯àŠŸàŠ¬à§ ( àŠàŠàŠŸà§àŠŸàŠ " àŠ¬àŠ¿àŠ²à§àŠ¡àŠž " àŠ¥à§àŠà§ " àŠàŠž " àŠ¬àŠŸàŠŠ àŠ¯àŠŸàŠ¬à§ )à¥€
+
+<p>àŠàŠªàŠšàŠ¿ " àŠàŠàŠŸàŠ® " àŠªà§àŠ°àŠ¶à§àŠš àŠ§àŠ°àŠ£à§ àŠ¯à§àŠ€à§ àŠªàŠŸàŠ°à§àŠš , àŠ¯àŠŸ àŠàŠ¬w(&), àŠ
+àŠ¥àŠ¬àŠŸ(à¥€) àŠàŠ¬w àŠšàŠŸ (! ) àŠ¬à§àŠ¯àŠ¬àŠ¹àŠŸàŠ° àŠàŠ°à§ àŠ¶àŠ¬à§àŠŠ àŠ¯à§àŠà§àŠ€ àŠàŠ°àŠ€à§ àŠ
+àŠ§àŠ¿àŠàŠŸàŠ° àŠŠà§à§ à¥€ àŠàŠàŠ¿ àŠàŠ°àŠ àŠ­àŠŸàŠ²à§ àŠ­àŠŸàŠ¬à§ àŠªà§àŠ°àŠ¶à§àŠš àŠàŠ°àŠ€à§ àŠžàŠŸàŠ¹àŠŸàŠ¯à§àŠ¯ àŠàŠ°à§ à¥€ àŠàŠªàŠšàŠ¿ àŠ¶à§àŠ· àŠàŠ¿àŠà§ àŠªà§àŠ°àŠ¶à§àŠš -à§à§àŠ° àŠàŠà§àŠàŠŸàŠ° àŠàŠ€àŠ¿àŠ¹àŠŸàŠžà§àŠ° àŠ¬à§àŠ¶àŠ¿àŠ·à§àŠà§àŠ¯ àŠŠà§àŠàŠ€à§ àŠªàŠŸàŠ°à§àŠš à¥€ àŠàŠàŠ¿ àŠ¶à§àŠ· àŠàŠ¿àŠà§ àŠªà§àŠ°àŠ¶à§àŠš -à§à§àŠ°  àŠªàŠ°àŠ¿àŠ¬àŠ°à§àŠ€àŠ¿àŠ€ àŠ°à§àŠª àŠŠà§àŠàŠ€à§ àŠžàŠŸàŠ¹àŠŸàŠ¯à§àŠ¯ àŠàŠ°à§ à¥€ àŠ
+àŠ¬àŠ¶à§àŠ·à§ àŠàŠªàŠšàŠ¿ àŠàŠàŠŸàŠ€ àŠàŠ°àŠŸàŠ° àŠžwàŠà§àŠ¯àŠŸ àŠàŠ¬w àŠªà§àŠ°àŠ€à§àŠ¯à§àŠ àŠªàŠŸàŠ€àŠŸà§ àŠ¥àŠŸàŠàŠŸ àŠžwàŠà§àŠ¯àŠŸàŠà§ àŠšàŠ¿à§àŠšà§àŠ€à§àŠ°àŠ£ àŠàŠ°àŠ€à§ àŠªàŠŸàŠ°à§àŠšà¥€
+}
+
+_texttanumbrowseoptions_ [l=bn] {àŠàŠàŠŸàŠšà§ àŠàŠà§ _numbrowseoptions_ àŠ€àŠ¥à§àŠ¯ àŠàŠà§àŠàŠŸàŠ° àŠàŠªàŠŸà§  àŠ}
+
+_textsimplehelpheading_ [l=bn] {àŠàŠ¿ àŠàŠ°à§ àŠžwàŠà§àŠ°àŠ¹ àŠ¥à§àŠà§ àŠ€àŠ¥àŠ¯ àŠàŠà§àŠàŠ€à§ àŠ¹à§ _collectionname_ àŠžwàŠà§àŠ°àŠ¹ }
+
+_texthelpscope_ [l=bn] {
+<p>
+àŠ¬àŠ¿àŠ­àŠ¿àŠšà§àŠš àŠžwàŠà§àŠ°àŠ¹à§ àŠàŠà§àŠàŠŸàŠ° àŠàŠšàŠ¯ àŠàŠªàŠšàŠ¿ àŠ¬àŠ¿àŠ­àŠ¿àŠšà§àŠš àŠžà§àŠà§ àŠ¬àŠ¬àŠ¹àŠŸàŠ° àŠàŠ°àŠ€à§ àŠªàŠŸàŠ°à§àŠšà¥€àŠàŠŠàŠŸàŠ¹àŠ°àŠ£ àŠ¹àŠ¿àŠžàŠŸàŠ¬à§ , àŠ²à§àŠàŠ àŠ¬àŠŸ àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ® àŠ¬àŠŸ àŠ
+àŠšà§àŠà§àŠà§àŠŠ àŠ¬àŠŸ àŠªàŠ°àŠ¿àŠà§àŠàŠŠà§àŠ° àŠžà§àŠà§ àŠ¥àŠŸàŠàŠ€à§ àŠªàŠŸàŠ°à§à¥€ àŠžàŠŸàŠ§àŠŸàŠ°àŠ£àŠ€ àŠàŠªàŠšàŠ¿ àŠ¯à§àŠ®àŠš àŠ§àŠ°àŠ£à§àŠ° àŠžà§àŠà§àŠ àŠàŠà§àŠà§àŠš àŠšàŠŸ àŠà§àŠš àŠžàŠ®à§àŠªà§àŠ°à§àŠ£ àŠ®à§àŠ²àŠŸàŠšà§ àŠšàŠ¥àŠ¿àŠà§ àŠ«àŠ¿àŠ°àŠ¿à§à§ àŠŠà§àŠà§àŠŸ àŠ¹à§à¥€            
+
+<p>àŠ¯àŠŠàŠ¿ àŠšàŠ¥àŠ¿ àŠ¬àŠ àŠ¹à§ àŠ€àŠŸàŠ¹àŠ²à§ àŠ€àŠŸ àŠ¯àŠ¥àŠŸàŠ¯àŠ¥ àŠžà§àŠ¥àŠŸàŠšà§àŠ àŠà§àŠ²àŠŸ àŠ¹àŠ¬à§à¥€
+}
Index: /gsdl/stable/macros/browse.dm
===================================================================
--- /gsdl/stable/macros/browse.dm	(revision 20131)
+++ /gsdl/stable/macros/browse.dm	(revision 20131)
@@ -0,0 +1,115 @@
+# this file must be UTF-8 encoded
+
+package browse
+
+#######################################################################
+# headers
+# these are overridden so we can put an onLoad event handler
+# in the <body> tag of this page - for mgpp, form search pages
+#######################################################################
+
+#copied from prefs 
+
+_header_ {_cgihead_
+_htmlhead_(onLoad="ccont(0)")_startspacer__pagebanner_
+}
+
+
+_content_{
+	
+	
+
+	_optnavigationbar_
+	
+	_browseinterface_
+
+<div class="divbar">&nbsp;</div>
+
+	_classifications_
+	
+
+	<div id="mydiv"></div>
+	<div><layer id="mylayer"top=350 left=280 width="100%"></layer></div>	
+
+}
+
+
+_runtimebrowsescript_{}
+
+_browseinterface_{
+
+<form name=BrowseForm method=get action="_gwcgi_">
+
+<input type=hidden name="a" value="br">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+       <p>
+       _textfilterby_ _anyallselect_ _textwords_<br> 
+       _filterbox_<br>
+ 
+	<font size=-1><i>(_textleaveblank_)</i></font><p>	      	      
+       
+       _textsortby_ _browsebox1_, _textalsoshowing_ _browsebox2_ _textwith_ 
+       _docnum_ _textdocsperpage_
+       <span align = right> _browsebutton_ </span><p>
+</form>  
+
+}
+
+_browsebutton_{<input type=submit value=_browsebuttontext_ align=right>}
+
+_docnum_{
+<select name="bnu">
+	<option _If_("_cgiargbnu_" eq "5", selected)>5
+	<option _If_("_cgiargbnu_" eq "10", selected)>10
+	<option _If_("_cgiargbnu_" eq "20", selected)>20
+	<option _If_("_cgiargbnu_" eq "50", selected)>50
+	<option value="-1" _If_("_cgiargbnu_" eq "-1", selected)>max
+</select>
+}
+
+_filterbox_{<input type=text name="bft" value="_cgiargbft_" size=60>}
+
+
+_anyallselect_{
+<select name="bt">
+	<option value="0"_If_(_cgiargbt_,, selected)>_textany_
+	<option value="1"_If_(_cgiargbt_, selected)>_textall_
+</select>
+}
+
+_classifications_{
+}
+ 	
+_pagescriptextra_ {
+var tbl = new Array()
+
+function ccont(current)\{
+  if(document.getElementById) \{
+    document.getElementById("mydiv").innerHTML = tbl[current]; 
+   \}	
+  else if(document.all)\{
+    mydiv.innerHTML=tbl[current]
+  \}
+  else if(document.layers)\{
+    document.mylayer.document.write(tbl[current])
+    document.mylayer.document.close()
+   \}
+  
+\}      
+
+_runtimebrowsescript_
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/macros/bsummary.dm
===================================================================
--- /gsdl/stable/macros/bsummary.dm	(revision 20131)
+++ /gsdl/stable/macros/bsummary.dm	(revision 20131)
@@ -0,0 +1,24 @@
+# this file must be UTF-8 encoded
+
+package bsummary
+
+_pagetitle_ {_collectionname_}
+
+_content_ {
+<center>
+_optnavigationbar_
+<h3>_textilog_</h3>
+</center>
+<p>_importlog_
+
+<center>
+<h3>_textflog_</h3>
+</center>
+<p>_faillog_
+
+<center>
+<h3>_textbsummary_</hs>
+</center>
+<p>_buildlog_
+
+}
Index: /gsdl/stable/macros/bulgarian.dm
===================================================================
--- /gsdl/stable/macros/bulgarian.dm	(revision 20131)
+++ /gsdl/stable/macros/bulgarian.dm	(revision 20131)
@@ -0,0 +1,676 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# English Language text and icon macros 
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=bg] {ÐÐµÑÐžÐŸÐŽÐžÑÐœÐž ÐžÐ·ÐŽÐ°ÐœÐžÑ}  
+
+_textdate_ [l=bg] {ÐŽÐ°ÑÐ° ÐœÐ° Ð¿ÑÐ±Ð»ÐžÐºÑÐ²Ð°ÐœÐµ:}  
+_textnumpages_ [l=bg] {ÑÑÑÐ°ÐœÐžÑÐž:}  
+
+_textsignin_ [l=bg] {Ð²Ð»ÐµÐ·}  
+
+_textdefaultcontent_ [l=bg] {Ð¡ÑÑÐ°ÐœÐžÑÐ°ÑÐ° ÐœÐµ ÐŒÐŸÐ¶Ðµ ÐŽÐ° Ð±ÑÐŽÐµ ÐœÐ°ÐŒÐµÑÐµÐœÐ°. ÐÐžÑÑÐµÐœÐµ Ð±ÑÑÐŸÐœÐ° ÐŸÐ¿Ð±Ð°ÑÐœÐŸ ÐœÐ° ÐÐ°ÑÐžÑ Ð±ÑÐ°ÑÐ·ÑÑ ÐžÐ»Ðž Ð±ÑÑÐŸÐœÐ° ÐœÐ°ÑÐ°Ð»ÐŸ, ÑÐ·Ð° ÐŽÐ° ÑÐµ Ð²ÑÑÐœÐµÑÐµ Ð² ÐœÐ°ÑÐ°Ð»ÐœÐ°ÑÐ° ÑÑÑÐ°ÐœÐžÑÐ° ÐœÐ° Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ° ÐÑÐžÐ¹ÐœÑÑÐŸÑÐœ.}  
+
+
+
+
+
+
+
+
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=bg] {<p>Ð¢Ð°Ð·Ðž Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ° ÑÑÐŽÑÑÐ¶Ð° _numdocs_ _If_("_numdocs_" eq "1",document,documents), Ð²ÑÐ·Ð»ÐžÐ·Ð°ÑÐž ÐœÐ° _numbytes_.
+<p><a href="_httppagex_(bsummary)">ÐÐ»ÐžÐºÐœÐµÑÐµ ÑÑÐº,</a> Ð·Ð° ÐŽÐ° Ð²ÐžÐŽÐžÑÐµ ÐºÑÐ°ÐºÑÐŸ ÐŸÐ¿ÐžÑÐ°ÐœÐžÐµ ÐœÐ° Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ°ÑÐ°.}  
+
+_textdescrcollection_ [l=bg] {}
+
+_textdescrhome_ [l=bg] {ÐÐ°ÑÐ°Ð»ÐŸ}  
+
+
+_textdescrgreenstone_ [l=bg] {ÐÑÐžÐ¹ÐœÑÑÐŸÑÐœ ÑÐžÑÑÐŸÐ²Ð° Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ°}  
+
+
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=bg] {Ð Ð°Ð·Ð³Ð»ÐµÐŽÐ°Ð¹ Ð°Ð·Ð±ÑÑÐµÐœ ÑÐ¿ÐžÑÑÐº ÐœÐ° Ð·Ð°Ð³Ð»Ð°Ð²ÐžÑÑÐ°}  
+
+
+
+
+
+
+
+
+
+_textdescrSource_ [l=bg] {Ð Ð°Ð·Ð³Ð»ÐµÐŽÐ°Ð¹ Ð¿ÐŸ ÐŸÑÐžÐ³ÐžÐœÐ°Ð»ÐœÐŸ ÐžÐŒÐµ ÐœÐ° ÑÐ°Ð¹Ð»Ð°}  
+
+
+
+
+
+
+
+
+_textdescrList_ [l=bg] {Ð Ð°Ð·Ð³Ð»ÐµÐŽÐ°Ð¹ÑÐµ ÑÐ¿ÐžÑÑÐº Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐžÑÐµ}  
+
+_textdescrTo_ [l=bg] {Ð Ð°Ð·Ð³Ð»ÐµÐŽÐ°Ð¹ Ð¿ÐŸ Ð¿ÐŸÐ»Ðµ ÐÐŸ}  
+
+
+
+
+
+
+
+_textdescrArtist_ [l=bg] {Ð Ð°Ð·Ð³Ð»ÐµÐŽÐ°Ð¹ Ð°Ð²ÑÐŸÑÐž}  
+
+
+_textdescrCaptions_ [l=bg] {Ð Ð°Ð·Ð³Ð»ÐµÐŽÐ°Ð¹ Ð¿ÐŸ ÑÐŸÑÐŸ}  
+
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=bg] {ÐÐ°Ð³Ð»Ð°Ð²ÐžÑ Ð-Ð¯}  
+
+_labelSubject_ [l=bg] {Ð¢ÐµÐŒÐž}  
+
+
+
+
+_labelDate_ [l=bg] {ÐÐ°ÑÐž}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_labelAcronym_ [l=bg] {Ð¡ÑÐºÑÐ°ÑÐµÐœÐžÑ}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_texticonmp3_ [l=bg] {ÐÐžÐ¶ÑÐµ MP3 ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°.}  
+
+
+
+_texticonrtf_ [l=bg] {ÐÐžÐ¶ÑÐµ RTF ÐŽÐŸÐºÑÐŒÐµÐœÑ}  
+
+
+
+_pages_ [l=bg] {ÑÑÑÐ°ÐœÐžÑÐž}  
+
+
+
+
+_textmonth00_ [l=bg] {}
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textdocument_ [l=bg] {ÐÐŸÐºÑÐŒÐµÐœÑ}  
+
+
+
+_magazines_ [l=bg] {Ð¡Ð¿ÐžÑÐ°ÐœÐžÑ}  
+
+
+
+
+_linktextHELP_ [l=bg] {ÐÐŸÐŒÐŸÑ}  
+
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+_textsubcols1_ [l=bg] {<p>ÐŠÑÐ»Ð°ÑÐ° ÐºÐŸÑÐµÐºÑÐžÑ ÑÑÐŽÑÑÐ¶Ðµ _1_ Ð¿ÐŸÐŽÐºÐŸÐ»ÐµÐºÑÐžÐž. 
+ÐÐ°Ð»ÐžÑÐœÐžÑÐµ Ð² ÐŒÐŸÐœÐµÑÐ° ÑÐ°:
+<blockquote>}  
+
+_textsubcols2_ [l=bg] {</blockquote>
+ÐÐŸÐ¶ÐµÑÐµ ÐŽÐ° Ð²ÐžÐŽÐžÑÐµ Ðž Ð¿ÑÐŸÐŒÐµÐœÐžÑÐµ ÐºÐŸÐž Ð¿ÐŸÐŽÐºÐŸÐ»ÐµÐºÑÐžÐž ÐžÐ·Ð¿ÐŸÐ»Ð·Ð²Ð°ÑÐµ ÐŸÑ ÑÑÑÐ°ÐœÐžÑÐ° ÐÑÐµÐŽÐ¿ÐŸÑÐžÑÐ°ÐœÐžÑ.}  
+
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+
+_texticonopenbookshelf_ [l=bg] {Ð·Ð°ÑÐ²ÐŸÑÐž ÑÐŸÐ·Ðž ÑÐ°Ð·ÐŽÐµÐ» ÐœÐ° Ð±ÐžÐ±Ð»ÐžÐµÑÐµÐºÐ°ÑÐ°}  
+
+_texticonopenbook_ [l=bg] {Ð·Ð°ÑÐ²ÐŸÑÐµÑÐµ ÐºÐœÐžÐ³Ð°ÑÐ°}  
+_texticonclosedfolder_ [l=bg] {ÐÑÐ²ÐŸÑÐž Ð¿Ð°Ð¿ÐºÐ°ÑÐ°, Ð·Ð° ÐŽÐ° Ð²ÐžÐŽÐžÑ ÑÑÐŽÑÑÐ¶Ð°ÐœÐžÐµÑÐŸ}  
+
+
+
+
+
+
+
+
+
+_texticoncontracttoc_ [l=bg] {ÐÐ°ÑÐ²ÐŸÑÐž ÑÑÐŽÑÑÐ¶Ð°ÐœÐžÐµÑÐŸ}  
+
+
+_texticoncontracttext_ [l=bg] {ÐÐŸÐºÐ°Ð¶Ðž ÑÐµÐºÑÑ ÑÐ°ÐŒÐŸ Ð·Ð° ÐžÐ·Ð±ÑÐ°ÐœÐ°ÑÐ° ÑÐµÐºÑÐžÑ}  
+
+
+
+_textltwarning_ [l=bg] {<div class="buttons">_imagecont_</div>
+_iconwarning_Ð Ð°Ð·ÑÐžÑÑÐŒÐ°ÐœÐµÑÐŸ ÐœÐ° ÑÐµÐºÑÑÐ° ÑÐµ ÐŽÐŸÐ²ÐµÐŽÐµ ÐŽÐŸ Ð³ÐŸÐ»ÑÐŒÐŸ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ, ÐºÐŸÑÑÐŸ ÐŽÐ°ÑÐµ Ð·Ð°ÑÐµÐŽÐž Ð²Ð²Ñ ÐÐ°ÑÐžÑ Ð±ÑÐ°ÑÐ·ÑÑ}  
+
+
+
+
+
+
+
+
+_textCONTRACTCONTENTS_ [l=bg] {?Ð·Ð°ÑÐ²ÐŸÑÐž ÑÑÐŽÑÑÐ¶Ð°ÐœÐžÐµÑÐŸ?}  
+
+_textDETACH_ [l=bg] {ÐÐ¢ÐÐÐ§Ð}  
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=bg] {_If_(_thislast_,results _thisfirst_ - _thislast_ for query: _cgiargq_,ÐÑÐŒÐ° ÑÑÐŸÑÐ²ÐµÑÑÑÐ²ÐžÑ Ð·Ð°: _cgiargq_)}  
+_textnoquerytitle_ [l=bg] {Ð¢ÑÑÑÐµÐœÐµ}  
+
+
+
+
+
+
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+
+
+
+
+#alt text for query buttons
+
+_textfreqmsg1_ [l=bg] {ÐÑÐŒÐž:}  
+
+
+
+
+
+
+
+
+_textmatches_ [l=bg] {Ð¡ÑÐŸÑÐ²ÐµÑÑÑÐ²ÐžÑ}  
+
+
+
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=bg] {ÐÑÐŒÐ° ÐžÐ»Ðž ÑÑÐ°Ð·Ð°}  
+
+
+
+
+_textallfields_ [l=bg] {Ð²ÑÐžÑÐºÐž Ð¿ÐŸÐ»ÐµÑÐ°}  
+_texttextonly_ [l=bg] {ÑÐ°ÐŒÐŸ ÑÐµÐºÑÑ}  
+
+
+
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=bg] {Ð¢ÑÑÑÐž Ð·Ð°  _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_, Ð² _gselection_ level )_If_(_nselection_,in _nselection_ language )ÑÑÐŽÑÑÐ¶Ð°Ñ _querytypeselection_ ÐŸÑ ÐŽÑÐŒÐžÑÐµ}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textdatesearch_ [l=bg] {ÐÐŸÐ¶ÐµÑÐµ ÐŽÐ° ÑÑÑÑÐžÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐž Ð¿ÐŸ ÐŽÐ°ÑÐ° ÐžÐ»Ðž ÐŽÐŸÐºÑÐŒÐµÐœÑÐž, ÐºÐŸÐžÑÐŸ ÑÑÐŽÑÑÐ¶Ð°Ñ ÑÐ¿ÐµÑÐžÑÐžÑÐœÐ° ÐŽÐ°ÑÐ°. Ð¢ÐŸÐ²Ð° Ðµ ÐŸÐ¿ÑÐžÐŸÐœÐ°Ð»ÐœÐ° ÑÑÐœÐºÑÐžÐŸÐœÐ°Ð»ÐœÐŸÑÑ.}  
+
+
+
+_textad_ [l=bg] {Ðœ.Ðµ.}  
+_textexplaineras_ [l=bg] {Ðœ.Ðµ. Ðž Ð¿Ñ.Ðœ.Ðµ. ÑÐ° Ð°Ð»ÑÐµÑÐœÐ°ÑÐžÐ²Ðž ÐœÐ° ÑÐ». Ð¥Ñ. Ðž Ð¿Ñ.Ð¥Ñ. ÑÑÐŸÑÐ²ÐµÑÐœÐŸ. Ð¡ÑÐžÑÐ°Ñ ÑÐµ Ð·Ð° ÐºÑÐ»ÑÐµÑÐœÐŸÐœÐµÐ·Ð°Ð²ÐžÑÐžÐŒÐµ Ðž ÐŸÐ·ÐœÐ°ÑÐ°Ð²Ð°Ñ - ÐœÐ°ÑÐ°ÑÐ° ÐµÑÐ° Ðž Ð¿ÑÐµÐŽÐž ÐœÐ°ÑÐ°ÑÐ° ÐµÑÐ°.}  
+
+
+
+
+
+#text macros for search history
+
+_texthresult_ [l=bg] {ÑÐµÐ·ÑÐ»ÑÐ°Ñ}  
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+_textsearchprefs_ [l=bg] {ÐÑÐµÐŽÐ¿ÐŸÑÐžÑÐ°ÐœÐžÑ Ð·Ð° ÑÑÑÑÐµÐœÐµ}  
+
+_textpresentationprefs_ [l=bg] {ÐÑÐµÐŽÐ¿ÐŸÑÐžÑÐ°ÐœÐžÑ Ð·Ð° Ð¿ÑÐµÐ·ÐµÐœÑÐ°ÑÐžÑÑÐ°}  
+
+
+
+
+
+
+
+
+
+_textintlink_ [l=bg] {ÐÐ·Ñ
+ÐŸÐŽÐœÐžÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐž ÑÐ° Ð²Ð·ÐµÑÐž ÐŸÑ:}  
+_textlanguage_ [l=bg] {ÐÐ·ÐžÐº ÐœÐ° ÐžÐœÑÐµÑÑÐµÐ¹ÑÐ°:}  
+
+
+
+
+
+
+_textlinkinterm_ [l=bg] {ÑÑÐµÐ· ÑÑÑÐ°ÐœÐžÑÐ° Ð¿ÐŸÑÑÐµÐŽÐœÐžÐº}  
+_textlinkdirect_ [l=bg] {ÐŸÑÐžÐŽÐž ÐŽÐžÑÐµÐºÑÐœÐŸ}  
+
+
+
+
+
+
+
+
+
+
+
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+
+
+
+
+
+
+
+
+
+# used in "with 4 fields" in the form search box
+
+
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+
+
+
+_textdocsperpage_ [l=bg] {ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° ÐœÐ° ÑÑÑÐ°ÐœÐžÑÐ°}  
+
+
+
+_textany_ [l=bg] {Ð²ÑÐµÐºÐž}  
+
+_textleaveblank_ [l=bg] {ÐŸÑÑÐ°Ð²Ðž Ð¿Ð¿ÐŸÐ»ÐµÑÐŸ Ð¿ÑÐ°Ð·ÐœÐŸ Ð·Ð° Ð²ÑÐžÑÐºÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÐž}  
+
+
+
+
+
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+
+
+
+
+
+_textDateshort_ [l=bg] {ÑÐ°Ð·Ð³Ð»ÐµÐŽÐ°Ð¹ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐžÑÐµ Ð¿ÐŸ ÐŽÐ°ÑÐ°}  
+
+
+_textIdentifiershort_ [l=bg] {ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑ Ð¿ÐŸ ÑÐžÐŒÐ²ÐŸÐ»}  
+
+
+
+
+
+
+
+
+_textFromshort_ [l=bg] {ÑÐ°Ð·Ð³Ð»ÐµÐŽÐ°Ð¹ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐžÑÐµ Ð¿ÐŸ Ð¿ÐŸÐ»ÐµÑÐŸ ÐÑ}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+
+
+# Not true DC, kept for legacy reasons
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Not true DC, kept for legacy reasons
+
+
+_textLanguagelong_ [l=bg] {<p>ÐÐŸÐ¶ÐµÑÐµ <i>ÐŽÐ° ÑÐ°Ð·Ð³Ð»ÐµÐ¶ÐŽÐ°ÑÐµ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐžÑÐµ Ð¿ÐŸ ÐµÐ·ÐžÐº</i> ÐºÐ°ÑÐŸ ÐœÐ°ÑÐžÑÐœÐµÑÐµ Ð±ÑÑÐŸÐœÐ°<i>ÐµÐ·ÐžÑÐž</i>.  ÐÐ·Ð²ÐµÐ¶ÐŽÐ° ÑÐ¿ÐžÑÑÐº ÐœÐ° ÑÑÐŽÑÑÐ¶Ð°ÐœÐžÐµÑÐŸ ÑÐŸÑÑÐžÑÐ°Ðœ Ð¿ÐŸ ÐµÐ·ÐžÑÐž.  }  
+
+
+
+
+
+
+
+
+
+_textOrganizationlong_ [l=bg] {<p>ÐÐŸÐ¶ÐµÑÐµ <i>ÐŽÐ° ÑÐ°Ð·Ð³Ð»ÐµÐ¶ÐŽÐ°ÑÐµ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐž Ð¿ÐŸ ÐŸÑÐ³Ð°ÐœÐžÑÐžÑ,</i> ÐºÐ°ÑÐŸ ÐœÐ°ÑÐžÑÐœÐµÑÐµ Ð±ÑÑÐŸÐœÐ°<i> ÐŸÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÐž</i>.  ÐÐ·Ð²ÐµÐ¶ÐŽÐ° ÑÐ¿ÐžÑÑÐº ÐœÐ° ÐŸÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÐžÑÐµ.}  
+
+
+
+_textTopiclong_ [l=bg] {<p>ÐÐŸÐ¶ÐµÑÐµ <i> ÐŽÐ° ÑÐ°Ð·Ð³Ð»ÐµÐŽÐ°ÑÐµ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐžÑÐµ Ð¿ÐŸ ÑÐµÐŒÐ°</i> ÐºÐ°ÑÐŸ ÐœÐ°ÑÐžÑÐœÐµÑÐµ Ð±ÑÑÐŸÐœÐ° <i>ÑÐµÐŒÐ°</i>.  ÐÐ·Ð²ÐµÐ¶ÐŽÐ° ÑÐ¿ÐžÑÑÐº Ñ ÑÐµÐŒÐžÑÐµ.}  
+
+_textTolong_ [l=bg] {<p>ÐÐŸÐ¶ÐµÑÐµ <i> ÐŽÐ° ÑÐ°Ð·Ð³Ð»ÐµÐ¶ÐŽÐ°ÑÐµ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐž Ð¿ÐŸ Ð¿ÐŸÐ»ÐµÑÐŸ ÐÐ</i> ÐºÐ°ÑÐŸ ÐœÐ°ÑÐžÑÐœÐµÑÐµ Ð±ÑÑÐŸÐœÐ° <i>ÐŽÐŸ</i>.  ÐÐ·Ð²ÐµÐ¶ÐŽÐ° ÑÐµ ÑÐ¿ÐžÑÑÐº Ñ Ð°ÐŽÑÐµÑÐ°ÑÐžÑÐµ.  }  
+
+_textFromlong_ [l=bg] {<p>ÐÐŸÐ¶ÐµÑÐµ <i>ÐŽÐ° ÑÐ°Ð·Ð³Ð»ÐµÐŽÐ°ÑÐµ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐžÑÐµ Ð¿ÐŸ Ð¿ÐŸÐ»ÐµÑÐŸ ÐÑ</i> ÐºÐ°ÑÐŸ ÐœÐ°ÑÐžÑÐœÐµÑÐµ Ð±ÑÑÐŸÐœÐ° <i>ÐÑ</i>.  ÐÐ·Ð²ÐµÐ¶ÐŽÐ° ÑÐ¿ÐžÑÑÐº Ñ ÐžÐ·Ð¿ÑÐ°ÑÐ°ÑÐžÑÐµ.  }  
+
+
+
+
+
+
+
+
+
+
+
+_textArtistlong_ [l=bg] {<p>ÐÐŸÐ¶ÐµÑÐµ<i>ÐŽÐ° ÑÐ°Ð·Ð³Ð»ÐµÐ¶ÐŽÐ°ÑÐµ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐžÑÐµ Ð¿Ð° Ð°Ð²ÑÐŸÑ</i> ÐºÐ°ÑÐŸ ÐœÐ°ÑÐžÑÑÐœÐµÑÐµ Ð±ÑÑÐŸÐœÐ°<i>Ð°Ð²ÑÐŸÑÐž</i>. ÐÐ·Ð²ÐµÐ¶ÐŽÐ° ÑÐžÑÑÐº ÐœÐ° ÑÑÐŽÑÑÐ¶Ð°ÐœÐžÐµÑÐŸ ÑÐŸÑÑÐžÑÐ°Ðœ Ð¿ÐŸ Ð°Ð²ÑÐŸÑÐž.}  
+
+
+
+_textVolumelong_ [l=bg] {<p>ÐÐŸÐ¶ÐµÑÐµ <i>ÐŽÐ° ÑÐ°Ð·Ð³Ð»ÐµÐ¶ÐŽÐ°ÑÐµ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐžÑÐµ Ð¿ÐŸ ÑÐŸÐŒ </i> ÐºÐ°ÑÐŸ ÐœÐ°ÑÐžÑÐœÐµÑÐµ Ð±ÑÑÐŸÐœÐ°<i>ÑÐŸÐŒÐŸÐ²Ðµ</i>. ÐÐ·Ð²ÐµÐ¶ÐŽÐ° ÑÐ¿ÐžÑÑÐº Ñ ÑÐŸÐŒÐŸÐ²ÐµÑÐµ. }  
+
+
+
+_textCountrieslong_ [l=bg] {<p>ÐÐŸÐ¶ÐµÑÐµ <i>ÐŽÐ° ÑÐ°Ð·Ð³Ð»ÐµÐŽÐ°ÑÐµ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐžÑÐµ Ð¿ÐŸ ÐŽÑÑÐ¶Ð°Ð²Ðž </i> ÐºÐ°ÑÐŸ ÐœÐ°ÑÐžÑÐœÐµÑÐµ Ð±ÑÑÐŸÐœÐ°<i>ÐŽÑÑÐ¶Ð°Ð²Ðž</i>. ÐÐ·Ð²ÐµÐ¶ÐŽÐ° ÑÐ¿ÐžÑÑÐº Ñ ÐŽÑÑÐ¶Ð°Ð²ÐžÑÐµ. }  
+
+
+
+
+
+_texthelptopicstitle_ [l=bg] {Ð¢ÐµÐŒÐž}  
+
+
+
+_texthelpreadingdocs_ [l=bg] {<p>You can tell when you have arrived at an individual book or document
+because its title, or a photograph of the front cover, appears at the top
+left of the page. In some collections this is accompanied by a table of
+contents, while others contain just the number of the current page along
+with a box that allows you to select a new page and go forward and
+backward. In the table of contents, the current section heading is in bold
+face, and the table is expandable -- click on the folders to open or close
+them; click on the open book at the top to close it.</p>
+
+<p>Underneath is the text of the current section. When you have read
+through it, there are arrows at the bottom to take you on to the next
+section or back to the previous one.</p>
+
+<p>Below the title or front-cover photograph are some buttons. Click on
+<i>_document:textEXPANDTEXT_</i> to expand out the whole text of the current section, or
+book. If the document is large, this could take a long time and use a lot
+of memory! Click on <i>_document:textEXPANDCONTENTS_</i> to expand out the whole table of
+contents so that you can see the titles of all chapters and
+subsections. Click on <i>_document:textDETACH_</i> to make a new browser window for this
+document. (This is useful if you want to compare documents, or read two at
+once.) Finally, when you do a search the words you search for are
+highlighted. Click on <i>_document:textNOHIGHLIGHT_</i> to remove highlighting.</p>
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=bg] {ÐÑÐ²ÐŸÑÐž ÑÐŸÐ·Ðž ÑÐ°ÑÑ}  
+
+_texthelpviewtextsection_ [l=bg] {ÐÐžÐ¶ÑÐµ ÐžÐ·Ð±ÑÐ°ÐœÐŸÑÐŸ ÐŸÑ ÑÐµÐºÑÑÐ°}  
+
+
+_texthelpdetachpage_ [l=bg] {ÐÑÐ²ÐŸÑÐž ÑÑÑÐ°ÐœÐžÑÐ°ÑÐ° Ð² ÐœÐŸÐ² Ð¿ÑÐŸÐ·ÐŸÑÐµÑ}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_texthelplanguageprefstitle_ [l=bg] {ÐÐ·ÐžÐºÐŸÐ²Ðž Ð¿ÑÐµÐŽÐ¿ÐŸÑÐžÑÐ°ÐœÐžÑ}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+_texthelpscope_ [l=bg] {<p>
+Ð Ð¿ÐŸÐ²ÐµÑÐµÑÐŸ ÑÐ±ÐŸÑÐœÐžÑÐž ÐŒÐŸÐ¶ÐµÑÐµ ÐŽÐ° ÐžÐ·Ð±ÐµÑÐµÑÐµ ÑÐ°Ð·Ð»ÐžÑÐœÐž ÐžÐŽÐµÐºÑÐž Ð·Ð° ÑÑÑÑÐµÐœÐµ. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, Ð°Ð²ÑÐŸÑ, Ð·Ð°Ð³Ð»Ð°Ð²ÐžÐµ, Ð¿Ð°ÑÐ°Ð³ÑÐ°Ñ ÐžÐ»Ðž Ð³Ð»Ð°Ð²Ð°. ÐÐ°ÑÐŸ Ð¿ÑÐ°Ð²ÐžÐ»ÐŸ ÑÐžÑÑÐµÐŒÐ°ÑÐ° ÐžÐ·Ð²ÐµÐ¶ÐŽÐ° ÑÐµÐ»ÐžÑ ÑÑÐŸÑÐ²ÐµÑÑÑÐ²Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑ, ÐœÐµÐ·Ð°Ð²ÐžÑÐžÐŒÐŸ ÐŸÑ ÐžÐ·Ð±ÑÐ°ÐœÐžÑ ÐžÐœÐŽÐµÐºÑÐ» 
+<p>ÐÐºÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÐžÑÐµ ÑÐ° ÐºÐœÐžÐ³Ðž, ÑÐµ ÑÐµ Ð±ÑÐŽÐ°Ñ ÐŸÑÐ²ÐŸÑÐµÐœÐž ÐœÐ° ÑÑÐŸÑÐ²ÐµÑÐœÐŸÑÐŸ ÐŒÑÑÑÐŸ.}  
Index: /gsdl/stable/macros/catalan2.dm
===================================================================
--- /gsdl/stable/macros/catalan2.dm	(revision 20131)
+++ /gsdl/stable/macros/catalan2.dm	(revision 20131)
@@ -0,0 +1,779 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Catalan Language text and icon macros 
+# -- this file contains text that is of less importance
+# -- to translate when creating a new interface language
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=ca] {documents. }
+_lastupdate_ [l=ca] {Ãltima actualitzaciÃ³}
+_ago_ [l=ca] {dies enrere.}
+_colnotbuilt_ [l=ca] {ColÂ·lecciÃ³ no construÃ¯da.}
+
+_textpoem_ [l=ca] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>que la pau i la calma t'envoltin,
+<br>que visquis en la calidesa de la calitja d'estiu,
+<br>que l'oceÃ  dels teus viatges sigui tan llis com la pedra verda polida.
+}
+
+_textgreenstone_ [l=ca] {<p>Greenstone (pedra verda) Ã©s una pedra semipreciosa que (com aquest programari) procedeix de Nova Zelanda. A la societat tradicional dels maoris, era la substÃ ncia mÃ©s preuada i cobejada de totes. Pot absorbir i conservar el <i>wairua</i>, que Ã©s un esperit o forÃ§a vital, i estÃ  dotada de virtuts tradicionals que la converteixen en un emblema escaient per a un projecte de biblioteca digital de domini pÃºblic. La seva brillantor representa la caritat; la seva transparÃšncia, l'honestedat; la seva duresa, el coratge; i el tall esmolat que pot adquirir, la justÃ­cia. La talla de pedra que apareix en el logotip de la Biblioteca Digital de Greenstone Ã©s un <i>patu</i>, una mena de porra de lluita, i una herÃšncia familiar d'un dels components del projecte. En un combat cos a cos, la seva escomesa era molt rÃ pida, precisa i completa. Hem volgut conferir aquestes mateixes qualitats al nostre programari, i que el tall esmolat del <i>patu</i> simbolitzi l'aspecte avanÃ§at i avantguardista de la tecnologia.  }
+
+_textaboutgreenstone_ [l=ca] {<p>Greenstone Ã©s un conjunt de programes informÃ tics per a la construcciÃ³ i difusiÃ³ de colÂ·leccions de biblioteca digital. Proporciona una nova forma d'organitzar la informaciÃ³ i de publicar-la a Internet o en cd-rom. Elaborat pel <b>Projecte de Biblioteca Digital de Nova Zelanda</b> a la <b>Universitat de Waikato</b>, es distribueix en colÂ·laboraciÃ³ amb la <b>UNESCO</b> i la <b>ONG Human Info </b>.  Ãs un programari de codi font obert que es pot obtenir a <a
+href="http://greenstone.org">http://greenstone.org</a> d'acord amb les condicions de la LlicÃšncia PÃºblica General GNU. 
+<p>L'objectiu del programari Ã©s que els usuaris, especialment en universitats, biblioteques i altres institucions de servei pÃºblic, puguin crear les seves prÃ²pies biblioteques digitals. Aquestes biblioteques estan transformant radicalment el mÃštode de distribuciÃ³ i adquisiciÃ³ de coneixements utilitzat per la UNESCO amb els seus interlocutors en els camps de l'educaciÃ³, la ciÃšncia i la cultura arreu del mÃ³n, i molt especialment als paÃ¯sos en vies de desenvolupament.  El nostre desig Ã©s que aquest programari estimuli l'Ãºs efectiu de les biblioteques digitals per compartir informaciÃ³ i posar-la a disposiciÃ³ del pÃºblic en general. 
+
+
+<p>Aquest programari s'elabora i es distribueix grÃ cies a una iniciativa de cooperaciÃ³ internacional acordada l'agost del 2000 entre tres institucions.
+
+<table border="0">
+<tr valign="top">
+<td>
+<a href="http://nzdl.org"><b>Projecte de Biblioteca Digital de Nova Zelanda a la Universitat de Waikato</b></a>
+<br>
+El programari de Greenstone ha sorgit d'aquest projecte i la iniciativa ha rebut el suport de la SubcomissiÃ³ de ComunicaciÃ³ de la ComissiÃ³ Nacional de Nova Zelanda per a la UNESCO com a part de la contribuciÃ³ de Nova Zelanda al programa de la UNESCO. 
+</td>
+<td></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://www.unesco.org"><b>OrganitzaciÃ³ de Nacions Unides per a l'EducaciÃ³, la CiÃšncia i la Cultura (UNESCO)</b></a>
+<br>
+La difusiÃ³ mundial d'informaciÃ³ en matÃšria d'educaciÃ³, ciÃšncia i cultura, especialment en els paÃ¯sos en vies de desenvolupament, Ã©s un dels objectius principals de la UNESCO, que la duu a terme mitjanÃ§ant el programa intergovernamental "InformaciÃ³ per a tothom". Amb aquest fi, es consideren eines importants la informaciÃ³ apropiada i de fÃ cil accÃ©s i la tecnologia de la comunicaciÃ³.
+</td>
+<td><a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+border="0"></a></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://humaninfo.org"><b>L'ONG Human Info, amb seu a Anvers, BÃšlgica</b></a>
+<br>
+Aquest projecte, impulsat per organismes de l'ONU i altres ONG, gaudeix de prestigi mundial per la seva tasca de digitalitzar documentaciÃ³ d'interÃšs per al desenvolupament humÃ  i donar-hi difusiÃ³ pÃºblica, de manera gratuÃ¯ta per als paÃ¯sos en desenvolupament i a preu de cost per als paÃ¯sos desenvolupats.  </td>
+<td><a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" border="0"></a></td>
+</tr>
+</table>
+}
+
+_textdescrselcol_ [l=ca] {seleccioneu una colÂ·lecciÃ³}
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=ca] {Hi ha quatre botons mÃ©s a la pÃ gina principal}
+
+_textnocollections_ [l=ca] {<p>Actualment no hi ha cap colÂ·lecciÃ³ disponible en aquesta instalÂ·laciÃ³ de Greenstone.  
+Per afegir colÂ·leccions, podeu: 
+<ul><li>Utilitzar<a href="_httppagecollector_">el colÂ·leccionista</a> per construir noves colÂ·leccions
+    <li>Si teniu un cd-rom de Greenstone, podeu instalÂ·lar colÂ·leccions des del cd-rom 
+</ul>
+}
+
+_text1coll_ [l=ca] {Aquesta instalÂ·laciÃ³ de Greenstone contÃ© 1 colÂ·lecciÃ³}
+
+_textmorecolls_ [l=ca] {Aquesta instalÂ·laciÃ³ de Greenstone contÃ© _1_ colÂ·leccions}
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=ca] {EnllaÃ§ extern}
+_textlinknotfound_ [l=ca] {No s'ha trobat l'enllaÃ§ intern}
+
+_textextlinkcontent_ [l=ca] {L'enllaÃ§ que heu seleccionat Ã©s extern a qualsevol de les vostres colÂ·leccions seleccionades actualment.
+    Si encara voleu visualitzar aquest enllaÃ§ i el vostre navegador tÃ© accÃ©s a la web, podeu <a href="_nexturl_">avanÃ§ar</a> fins a aquesta pÃ gina; en cas contrari, pitgeu el botÃ³ "retrocÃ©s" per tornar al document anterior. }
+
+_textlinknotfoundcontent_ [l=ca] {L'enllaÃ§ intern que heu seleccionat no existeix. AixÃ² es deu segurament a un error a la colÂ·lecciÃ³ font. Pitgeu el botÃ³ "retrocÃ©s" per tornar al document anterior. }
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=ca] {<h3>EnllaÃ§ amb la colÂ·lecciÃ³ "_2_" </h3>
+
+<p> L'enllaÃ§ que heu seleccionat Ã©s extern a la colÂ·lecciÃ³ "_collectionname_"
+    (connecta amb la colÂ·lecciÃ³ "_2_").
+    Si voleu visualitar aquest enllaÃ§ a la colÂ·lecciÃ³ "_2_" podeu  
+    <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">avanÃ§ar</a> fins a aquesta pÃ gina; 
+    en cas contrari, pitgeu el botÃ³ "retrocÃ©s" del vostre navegador per tornar al document anterior.
+}
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=ca] {Biblioteca Digital de Greenstone}
+
+_textusername_ [l=ca] {nom d'usuari}
+_textpassword_ [l=ca] {contrasenya}
+
+_textmustbelongtogroup_ [l=ca] {AvÃ­s: heu de pertÃ nyer al grup "_cgiargug_" per entrar a aquesta pÃ gina}
+
+_textmessageinvalid_ [l=ca] {La pÃ gina que heu demanat exigeix que us identifiqueu.<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)
+IntroduÃ¯u el nom d'usuari i la contrasenya de Greenstone.}
+
+_textmessagefailed_ [l=ca] {Hi ha un error en el nom d'usuari o la contrasenya.}
+
+_textmessagedisabled_ [l=ca] {Disculpeu, el vostre compte ha estat inhabilitat. Poseu-vos en contacte amb l'administrador d'aquest lloc web.}
+
+_textmessagepermissiondenied_ [l=ca] {Disculpeu, perÃ² no teniu permÃ­s per entrar a aquesta pÃ gina.}
+
+_textmessagestalekey_ [l=ca] {L'enllaÃ§ que heu seguit ja no Ã©s vÃ lid. IntroduÃ¯u la contrasenya per entrar a aquesta pÃ gina. }
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=ca] {<p>Aquesta instalÂ·laciÃ³ de Greenstone no contÃ© cap tipus de documentaciÃ³. AixÃ² pot ser perquÃš: 
+<ol>
+ <li>Greenstone es va instalÂ·lar a partir d'un cd-rom en versiÃ³ compacta.
+ <li>Greenstone es va instalÂ·lar a partir d'una distribuciÃ³ baixada d'Internet.
+</ol>
+En qualsevol cas, podeu obtenir la documentaciÃ³ al directori <i>docs</i>
+d'un cd-rom de Greenstone o a la web <a
+href="http://www.greenstone.org">http://www.greenstone.org</a>.
+}
+
+_textuserguide_ [l=ca] {Guia de l'usuari}
+_textinstallerguide_ [l=ca] {Guia de l'instalÂ·lador}
+_textdeveloperguide_ [l=ca] {Guia del programador}
+_textpaperguide_ [l=ca] {Del paper a la colÂ·lecciÃ³ }
+_textorganizerguide_ [l=ca] {Ãs de l'organitzador}
+
+_textgsdocstitle_ [l=ca] {documentaciÃ³ de Greenstone}
+
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=ca] {estructura per defecte}
+_textmore_ [l=ca] {mÃ©s}
+_textinfo_ [l=ca] {InformaciÃ³ de la colÂ·lecciÃ³}
+_textsrce_ [l=ca] {Dades font}
+_textconf_ [l=ca] {Configura la colÂ·lecciÃ³}
+_textbild_ [l=ca] {Construeix la colÂ·lecciÃ³}
+_textview_ [l=ca] {Visualitza la colÂ·lecciÃ³}
+_textdel_ [l=ca] {Suprimeix la colÂ·lecciÃ³}
+_textexpt_ [l=ca] {Exporta la colÂ·lecciÃ³}
+
+_textdownloadingfiles_ [l=ca] {EstÃ  baixant fitxers...}
+_textimportingcollection_ [l=ca] {EstÃ  important la colÂ·lecciÃ³...}
+_textbuildingcollection_ [l=ca] {EstÃ  construint la colÂ·lecciÃ³... }
+_textcreatingcollection_ [l=ca] {estÃ  creant la colÂ·lecciÃ³...}
+
+_textcollectorblurb_ [l=ca] {<i>La ploma tÃ© mÃ©s forÃ§a que l'espasa!
+<br>Construir i distribuir colÂ·leccions d'informaciÃ³ implica responsabilitats que cal plantejar-se detingudament abans de comenÃ§ar. Hi ha qÃŒestions legals de drets d'autor: tenir accÃ©s a documents no significa necessÃ riament que els pugueu posar a disposiciÃ³ de terceres persones. 
+Hi ha qÃŒestions socials: les colÂ·leccions han de respectar els costums de la societat de la qual provenen els documents.
+I hi ha qÃŒestions Ãštiques: hi ha coses que simplement no es poden posar a disposiciÃ³ de terceres persones. 
+<br>Tingueu molt en compte el poder de la informaciÃ³ i feu-la servir amb prudÃšncia.
+</i>
+}
+
+_textcb1_ [l=ca] {El "colÂ·leccionista" us ajuda a crear noves colÂ·leccions, modificar les que ja existeixen o afegir-hi elements i suprimir colÂ·leccions. Per dur a terme aquestes tasques, us guiarÃ  per una seqÃŒÃšncia de pÃ gines web que us demanaran la informaciÃ³ necessÃ ria. }
+
+_textcb2_ [l=ca] {Primer heu de decidir si}
+_textcnc_ [l=ca] {crea una nova colÂ·lecciÃ³}
+_textwec_ [l=ca] {treballar amb una d'existent, afegint-hi dades o suprimint-la. }
+
+_textcb3_ [l=ca] {Per construir o modificar colÂ·leccions de la biblioteca digital, us heu d'identificar. AixÃ² Ã©s per protegir-vos d'altres persones que vulguin entrar al vostre ordinador i alterar-ne la informaciÃ³. Nota: per raons de seguretat, us haureu d'identificar cada 30 minuts. Quan passi aixÃ², no us preocupeu!  Una vegada identificats, podreu continuar allÃ  on ho havÃ­eu deixat. }
+
+_textcb4_ [l=ca] {IntroduÃ¯u els vostre nom d'usuari i la contrasenya de Greenstone i pitgeu el botÃ³ per entrar.}
+
+_textfsc_ [l=ca] {En primer lloc, seleccioneu la colÂ·lecciÃ³ amb quÃš voleu treballar (les colÂ·leccions protegides contra escriptura no apareixeran en aquesta llista). }
+
+_textwtc_ [l=ca] {Amb la colÂ·lecciÃ³ que heu seleccionat, podeu}
+_textamd_ [l=ca] {Afegeix mÃ©s dades i torna a construir la colÂ·lecciÃ³}
+_textetc_ [l=ca] {Modificar el fitxer de configuraciÃ³ de la colÂ·lecciÃ³ i tornar-la a construir }
+_textdtc_ [l=ca] {Suprimeix tota la colÂ·lecciÃ³}
+_textetcfcd_ [l=ca] {Exportar la colÂ·lecciÃ³ per gravar-la en un cd-rom que s'instalÂ·li automÃ ticament a Windows}
+_textcaec_ [l=ca] {Canviar una colÂ·lecciÃ³ existent}
+_textnwec_ [l=ca] {No hi ha disponible per a modificaciÃ³ cap colÂ·lecciÃ³ que permeti l'escriptura }
+_textcianc_ [l=ca] {Crear una nova colÂ·lecciÃ³}
+_texttsosn_ [l=ca] {La seqÃŒÃšncia de passos necessaris per crear una nova colÂ·lecciÃ³ a la biblioteca digital Ã©s:}
+_textsin_ [l=ca] {N'especifica el nom (i dades associades)}
+_textswts_ [l=ca] {Especifica d'on procedeixen les dades font}
+_textatco_ [l=ca] {Ajusta les opcions de configuraciÃ³ (nomÃ©s per a usuaris avanÃ§ats)}
+_textbtc_ [l=ca] {"Construir" la colÂ·lecciÃ³ (vegeu mÃ©s avall)}
+_textpvyh_ [l=ca] {Admireu la vostra obra!}
+
+_texttfsiw_ [l=ca] {El quart pas Ã©s quan l'ordinador fa tota la feina. Durant el procÃ©s de "construcciÃ³", l'ordinador crea tots els Ã­ndexs i recopila tota la informaciÃ³ necessÃ ria perquÃš el sistema funcioni. PerÃ² primer cal que especifiqueu la informaciÃ³. }
+
+_textadab_ [l=ca] {A sota apareix un diagrama que us ajudarÃ  a saber on us trobeu. Pitgeu el botÃ³ verd per continuar avanÃ§ant per la seqÃŒÃšncia. Quan avanceu, els botons es tornaran de color groc. Podeu tornar a la pÃ gina anterior pitjant el botÃ³ groc corresponent al diagrama. }
+
+_textwyar_ [l=ca] {Quan estigueu a punt, pitgeu el botÃ³ verd "informaciÃ³ de la colÂ·lecciÃ³" per comenÃ§ar a crear la nova colÂ·lecciÃ³ de la biblioteca digital. }
+
+_textcnmbs_ [l=ca] {Cal especificar el nom de la colÂ·lecciÃ³}
+_texteambs_ [l=ca] {Cal especificar l'adreÃ§a de correu electrÃ²nic}
+_textpsea_ [l=ca] {Comproveu que l'adreÃ§a de correu electrÃ²nic correspongui al format usuari@domini}
+_textdocmbs_ [l=ca] {Cal especificar la descripciÃ³ de la colÂ·lecciÃ³}
+
+_textwcanc_ [l=ca] {En crear una nova colÂ·lecciÃ³ caldrÃ  incorporar algunes informacions preliminars sobre les dades font. Aquest procÃ©s estÃ  estructurat en forma d'una sÃšrie de pÃ gines web, supervisades pel colÂ·leccionista. La barra al peu de la pÃ gina us mostra la seqÃŒÃšncia de pÃ gines que s'han d'emplenar.}
+
+_texttfc_ [l=ca] {TÃ­tol de la colÂ·lecciÃ³:}
+
+_texttctiasp_ [l=ca] {El tÃ­tol de la colÂ·lecciÃ³ Ã©s una frase curta que servirÃ  per identificar el contingut de la colÂ·lecciÃ³ en tota la biblioteca digital. Per exemple, "Informes tÃšcnics d'informÃ tica" o "Biblioteca per al desenvolupament de la humanitat".}
+
+_textcea_ [l=ca] {AdreÃ§a electrÃ²nica de contacte:}
+
+_textteas_ [l=ca] {Aquesta adreÃ§a de correu electrÃ²nic constitueix el primer punt de contacte per a la colÂ·lecciÃ³. Si el programari de Greenstone detecta un problema, envia un informe diagnÃ²stic a aquesta adreÃ§a. Escriviu una adreÃ§a de correu electrÃ²nic en la seva forma completa: <tt>nom@domini</tt>.}
+
+_textatc_ [l=ca] {Sobre aquesta colÂ·lecciÃ³:}
+
+_texttiasd_ [l=ca] {AixÃ² Ã©s un enunciat que descriu els principis que regeixen els elements que formen part d'aquesta colÂ·lecciÃ³. ApareixerÃ  a la pimera pÃ gina de presentaciÃ³ de la colÂ·lecciÃ³.   }
+
+_textypits_ [l=ca] {La vostra posiciÃ³ a la seqÃŒÃšncia s'indica amb una fletxa per sota--en aquest cas, la fase d'"informaciÃ³ de la colÂ·lecciÃ³". Per continuar, pitgeu el botÃ³ verd "dades font". }
+
+_srcebadsources_ [l=ca] {<p>Un o mÃ©s dels fitxers font que heu especificat no estÃ  disponible (marcats _iconcross_ a sota).
+
+<p>AixÃ² pot ser perquÃš <ul>
+<li>El fitxer, el lloc FTP o l'URL no existeixen.
+<li>Primer us heu de connectar a Internet.
+<li>Esteu intentant accedir a un URL protegit per un tallafoc (aixÃ² passa si normalment heu de donar un nom d'usuari i una contrasenya per accedir a Internet).
+</ul>
+
+<p>Si aquest Ã©s un URL que podeu veure en el vostre navegador, el problema podria venir d'una cÃ²pia que es trobi a la memÃ²ria cau local. Malauradament, aquestes cÃ²pies sÃ³n invisibles per al procÃ©s de rÃšplica de Greenstone. En aquest cas, us recomanem que baixeu les pÃ gines des del vostre navegador. 
+}
+
+_textymbyco_ [l=ca] {<p>Podeu basar la colÂ·lecciÃ³ en:
+<ul>
+<li>L'estructura per defecte 
+<dl><dd>La nova colÂ·lecciÃ³ pot contenir documents html (.htm, .html), documents de text (.txt, .text), documents de MS Word (.doc), documents PDF (.pdf) o documents
+de correu electrÃ²nic amb el format "m-box" (.mbx).</dd></dl>
+<li>Una colÂ·lecciÃ³ existent
+<dl><dd>Els fitxers de la nova colÂ·lecciÃ³ han de ser exactament del mateix tipus que els que es varen utilitzar per construir la colÂ·lecciÃ³ existent.</dd></dl>
+</ul>
+}
+
+_textbtco_ [l=ca] {Basa la colÂ·lecciÃ³ en}
+_textand_ [l=ca] {Afegeix noves dades}
+_textad_ [l=ca] {Afegir dades:}
+
+_texttftysb_ [l=ca] {Els fitxers que especifiqueu a sota s'afegiran a la colÂ·lecciÃ³. Comproveu que no torneu a especificar fitxers que ja es troben a la colÂ·lecciÃ³, perquÃš, si no, se'n faran dues cÃ²pies. Els fitxers s'identifiquen pel nom complet i el directori on estan guardats; les pÃ gines web, per la seva adreÃ§a web absoluta. }
+
+_textis_ [l=ca] {Fonts de dades:}
+
+_textddd1_ [l=ca] {<p>Si utilitzeu file:// o ftp:// per especificar un fitxer, aquest baixarÃ . 
+
+<p>Si utilitzeu http:// el resultat dependrÃ  del fet que l'URL us mostri una pÃ gina web normal al vostre navegador o una llista de fitxers. Si us mostra una pÃ gina, aquesta baixarÃ  juntament amb  totes les pÃ gines amb quÃš estigui vinculada mitjanÃ§ant enllaÃ§os, sempre que es trobin en el mateix lloc web, a l'URL inicial.
+
+<p>Si utilitzeu file:// o ftp:// per especificar una carpeta o un directori, o introduÃ¯u un 
+http:// URL que dugui a una llista de fitxers, tot el que contingui la carpeta i totes les subcarpetes s'inclouran a la colÂ·lecciÃ³. 
+
+<p>Pitgeu el botÃ³ "mÃ©s fonts" per obtenir mÃ©s quadres d'introducciÃ³.
+}
+
+_textddd2_ [l=ca] {<p>Pitgeu un dels botons verds. Si sou un usuari avanÃ§at, potser voldreu ajustar la configuraciÃ³ de la colÂ·lecciÃ³.  Una altra possibilitat Ã©s anar directament a la fase de construcciÃ³. Recordeu que sempre podeu tornar a una fase anterior del procÃ©s pitjant el botÃ³ groc corresponent. 
+}
+
+_textconf1_ [l=ca] {<p>La construcciÃ³ i la presentaciÃ³ de la vostra colÂ·lecciÃ³ estan controlades per les especificacions contingudes en un "fitxer de configuraciÃ³" especial. Els usuaris avanÃ§ats que ho desitgin, poden modificar els parÃ metres de configuraciÃ³. 
+
+<center><p><b>Si no sou un usuari avanÃ§at, aneu al final de la pÃ gina.</b></center> 
+
+<p>Per modificar els parÃ metres de configuraciÃ³, canvieu les dades que apareixen a sota. Si cometeu un error, pitgeu "Restaurar" per restablir els parÃ metres originals de la configuraciÃ³.
+}
+
+_textreset_ [l=ca] {Restaura}
+
+_textbild1_ [l=ca] {S'estÃ  construint la colÂ·lecciÃ³. AixÃ² pot durar una estona. La lÃ­nia d'estat que apareix mÃ©s avall indica com progressa l'operaciÃ³.  }
+
+_textbild2_ [l=ca] {Per aturar el procÃ©s de construcciÃ³ en qualsevol moment, pitgeu aquÃ­. 
+<br>La colÂ·lecciÃ³ amb quÃš esteu treballant restarÃ  intacta.
+}
+
+_textstopbuild_ [l=ca] {interromp la construcciÃ³}
+
+_textbild3_ [l=ca] {Si sortiu d'aquesta pÃ gina (i no heu cancelÂ·lat el procÃ©s de construcciÃ³ amb el botÃ³ "interromp la construcciÃ³"), es continuarÃ  construint la colÂ·lecciÃ³ i s'instalÂ·larÃ  un cop completat el procÃ©s.}
+
+_textbuildcancelled_ [l=ca] {ConstrucciÃ³ cancelÂ·lada}
+
+_textbildcancel1_ [l=ca] {S'ha cancelÂ·lat el procÃ©s de construcciÃ³ de la colÂ·lecciÃ³. Amb els botons grocs que apareixen a sota podeu modificar la colÂ·lecciÃ³ o tornar a iniciar el procÃ©s de construcciÃ³. }
+
+_textbsupdate1_ [l=ca] {ActualitzaciÃ³ d'estat de construcciÃ³ d'aquÃ­ a 1 segon}
+_textbsupdate2_ [l=ca] {ActualitzaciÃ³ d'estat de construcciÃ³ d'aquÃ­ a }
+_textseconds_ [l=ca] {segons}
+_textbildsuc_ [l=ca] {La colÂ·lecciÃ³ s'ha construÃ¯t satisfactÃ²riament. }
+
+_textviewbildsummary_ [l=ca] {Per a mÃ©s informaciÃ³, podeu<a href="_httppagex_(bsummary)&c=_cgiargbc1dirname_" target=_top>visualitzar el resum de construcciÃ³</a> d'aquesta colÂ·lecciÃ³. }
+
+_textfailmsg11_ [l=ca] {La colÂ·lecciÃ³ no s'ha pogut construir perquÃš no contÃ© cap dada. Comproveu que existeixi almenys un dels directoris o fitxers que heu especificat a la pÃ gina <i>dades font</i> i que sigui d'un tipus o  (si es tracta d'un directori) que contingui fitxers d'un tipus que Greenstone pugui processar.
+}
+
+_textfailmsg21_ [l=ca] {No s'ha pogut construir la colÂ·lecciÃ³ (import.pl ha fallat). }
+_textblcont_ [l=ca] {El registre de construcciÃ³ contÃ© la informaciÃ³ segÃŒent:}
+
+_texttryagain_ [l=ca] {Per favor, <a href="_httppagecollector_" target=_top>torneu a fer arrencar el colÂ·leccionista</a>
+i  intenteu-ho de nou. 
+}
+
+_textfailmsg31_ [l=ca] {No s'ha pogut construir la colÂ·lecciÃ³ (buildcol.pl ha fallat).}
+_textfailmsg41_ [l=ca] {La colÂ·lecciÃ³ s'ha construÃ¯t satisfactÃ²riament perÃ² no s'ha pogut instalÂ·lar. }
+_textfailmsg71_ [l=ca] {S'ha produÃ¯t un error inesperat quan s'intentava construir la colÂ·lecciÃ³  }
+_textretcoll_ [l=ca] {Torna al colÂ·leccionista}
+
+_textdelperm_ [l=ca] {No s'ha pogut suprimir tota o una part de la colÂ·lecciÃ³ _cgiargbc1dirname_ . AixÃ² pot ser perquÃš:
+<ul>
+<li> Greenstone no tÃ© permÃ­s per suprimir el directori _gsdlhome_/collect/_cgiargbc1dirname_.<br>
+Potser haureu d'eliminar aquest directori manualment per completar la supressiÃ³ de la colÂ·lecciÃ³ _cgiargbc1dirname_ d'aquest ordinador.</li>
+<li>Greenstone no pot executar el programa _gsdlhome_/bin/script/delcol.pl. Comproveu que aquest fitxer es pugui llegir i executar.</li>
+</ul>
+}
+
+_textdelinv_ [l=ca] {La colÂ·lecciÃ³  _cgiargbc1dirname_ estÃ  protegida o no Ã©s vÃ lida. S'ha cancelÂ·lat la supressiÃ³. 
+}
+
+_textdelsuc_ [l=ca] {La colÂ·lecciÃ³  _cgiargbc1dirname_ s'ha suprimit satisfactÃ²riament.}
+
+_textclonefail_ [l=ca] {La colÂ·lecciÃ³  _cgiargclonecol_ no s'ha pogut clonar. AixÃ² pot ser perquÃš: 
+<ul>
+<li> La colÂ·lecciÃ³ _cgiargclonecol_ no existeix
+<li> La colÂ·lecciÃ³  _cgiargclonecol_ no tÃ© el fitxer de configuraciÃ³ collect.cfg 
+<li> Greenstone no tÃ© permÃ­s per llegir el fitxer de configuraciÃ³ collect.cfg 
+</ul>
+}
+
+_textcolerr_ [l=ca] {Error en el colÂ·leccionista.}
+
+_texttmpfail_ [l=ca] {El colÂ·leccionista no ha pogut realitzar cap operaciÃ³ de lectura o escriptura en el fitxer o directori temporal. AixÃ² pot ser perquÃš: <ul>
+<li> Greenstone no tÃ© accÃ©s de lectura/escriptura al directori _gsdlhome_/tmp.
+   </ul>}
+
+_textmkcolfail_ [l=ca] {El colÂ·leccionista no ha pogut crear l'estructura de directori que requereix la nova colÂ·lecciÃ³ (mkcol.pl ha fallat). AixÃ² pot ser perquÃš:
+<ul>
+<li> Greenstone no tÃ© permÃ­s per escriure al directori _gsdlhome_/tmp.
+<li> Hi ha errors en el guiÃ³ Perl mkcol.pl.
+</ul>
+}
+
+_textnocontent_ [l=ca] {Error en el colÂ·leccionista: no s'ha donat nom a la nova colÂ·lecciÃ³. Proveu de tornar a fer arrencar el colÂ·leccionista des del principi. }
+
+_textrestart_ [l=ca] {Torna a fer arrencar el colÂ·leccionista}
+
+_textreloaderror_ [l=ca] {S'ha produÃ¯t un error durant la creaciÃ³ de la nova colÂ·lecciÃ³. Podria ser que Greenstone s'haguÃ©s confÃ³s pel vostre Ãºs dels botons "tornar a carregar" o "retrocÃ©s" del vostre navegador (procureu no fer servir aquests botons durant la creaciÃ³ d'una colÂ·lecciÃ³ amb el colÂ·leccionista). Ãs recomanable tornar a fer arrencar el colÂ·leccionista des del principi. }
+
+_textexptsuc_ [l=ca] {La colÂ·lecciÃ³  _cgiargbc1dirname_ s'ha exportat satisfactÃ²riament al directori _gsdlhome_/tmp/exported\__cgiargbc1dirname_. }
+
+_textexptfail_ [l=ca] {<p>No s'ha pogut exportar la colÂ·lecciÃ³ _cgiargbc1dirname_ .
+
+<p>Ãs probable que sigui perquÃš Greenstone es va instalÂ·lar sense els components necessaris per a la funciÃ³ "Exportar colÂ·lecciÃ³".  
+<ul>
+
+ <li>Si vÃ reu instalÂ·lar Greenstone des d'un cd-rom, aquests components no s'hauran instalÂ·lat llevat que els haguÃ©ssiu seleccionat durant una instalÂ·laciÃ³ "personalitzada". Els podeu afegir a la instalÂ·laciÃ³ tornant a executar el procediment d'instalÂ·laciÃ³.
+
+ <li>Si vÃ reu instalÂ·lar Greenstone des d'una distribuciÃ³ a Internet, haureu de baixar i instalÂ·lar un paquet addicional per poder habilitar aquesta funciÃ³. Podeu obtenir mÃ©s informaciÃ³ a <a href="http://www.greenstone.org">http://www.greenstone.org</a> o enviant un correu a <a  href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>.
+
+</ul>
+}
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=ca] {Greenstone Ã©s un conjunt de programes informÃ tics que serveix per accedir a les colÂ·leccions de biblioteques digitals i per crear noves colÂ·leccions. Ofereix una nova manera d'organitzar la informaciÃ³ i de publicar-la a Internet o en cd-rom. Creat pel Projecte de Biblioteca Digital de Nova Zelanda a la Universitat de Waikato, aquest programari es distribueix en colÂ·laboraciÃ³ amb la UNESCO i l'ONG Human Info. Ãs un programari de codi font obert i es pot obtenir a <i>http://greenstone.org</i> d'acord amb les condicions de la LlicÃšncia PÃºblica General GNU. }
+
+_textgreenstone2_ [l=ca] {El lloc web de la Biblioteca Digital de Nova Zelanda (<a
+href="http://nzdl.org">http://nzdl.org</a>) contÃ© nombrosos exemples de colÂ·leccions creades amb el programari de Greenstone i que es poden consultar lliurement. Ofereixen exemples de diverses opcions de cerca i navegaciÃ³ i inclouen colÂ·leccions en Ã rab, xinÃšs, francÃšs, maori i castellÃ , a mÃ©s d'anglÃšs. TambÃ© hi ha algunes colÂ·leccions de mÃºsica.  }
+
+_textplatformtitle_ [l=ca] {plataforma}
+_textgreenstone3_ [l=ca] {Greenstone funciona amb Windows, Unix i Mac OS X. La distribuciÃ³ inclou binaris a punt d'utilitzar per a totes les versions de Windows, Linux i Mac OS X. TambÃ© contÃ© un codi font complet per al sistema, que es pot compilar amb Microsoft C++ o gcc.  Greenstone funciona amb un programari associat que tambÃ© es pot obtenir de forma gratuÃ¯ta: el servidor web Apache i el PERL. La interfÃ­cie d'usuari utilitza un navegador web com ara Netscape Navigator o Internet Explorer.
+}
+
+_textgreenstone4_ [l=ca] {Moltes colÂ·leccions de documents es distribueixen en cd-rom amb el programari de Greenstone. Per exemple, la <i>Biblioteca per al desenvolupament de la humanitat</i> contÃ© 1.230 publicacions que tracten temes tan diversos com la comptabilitat o la depuraciÃ³ d'aigÃŒes. S'hi pot accedir des d'ordinadors molt senzills, com els que se solen trobar als paÃ¯sos en vies de desenvolupament. La informaciÃ³ es pot trobar mitjanÃ§ant cerques o consultes per tema, tÃ­tols, organitzacions, llistes Com o per visualitzaciÃ³ aleatÃ²ria de portades de llibres. }
+
+_textcustomisationtitle_ [l=ca] {personalitzaciÃ³}
+_textgreenstone5_ [l=ca] {Greenstone estÃ  especialment dissenyat perquÃš es pugui personalitzar i ampliar a voluntat. Greenstone pot tractar nous formats de documents i metadades escrivint "connectors" (<i>plugins</i>), en
+llenguatge Perl. TambÃ© es poden aplicar noves estructures de navegaciÃ³ en les metadades escrivint "classificadors". La interfÃ­cie d'usuari i la presentaciÃ³ es poden modificar utilitzant les "macros" escrites en un senzill llenguatge de macros. El protocol Corba permet que els agents (per exemple en llenguatge Java) utilitzin totes les funcions disponibles a les colÂ·leccions de documents. Finalment, es pot modificar el codi font en C++ i Perl.
+}
+
+_textdocumentationtitle_ [l=ca] {documentaciÃ³}
+_textdocuments_ [l=ca] {EstÃ  disponible la documentaciÃ³ completa del programari de Greenstone.}
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=ca] {llista de correu electrÃ²nic}
+_textmailinglist_ [l=ca] {Exsteix una llista de correu electrÃ²nic pensada especialment per al debat sobre el programari de la biblioteca digital de Greenstone. Ãs recomanable i desitjable que els usuaris actius de Greenstone participin en aquest debat. Us hi podeu inscriure a  <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+
+Per enviar un missatge a la llista, adreceu-lo a <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>.
+}
+
+_textbugstitle_ [l=ca] {errors lÃ²gics o de programaciÃ³}
+_textreport_ [l=ca] {El nostre desig Ã©s que aquest programari funcioni correctament. Per aixÃ² us preguem que ens informeu de qualsevol problema que hi detecteu a <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>
+}
+
+_textgs3title_ [l=ca] {en fase d'elaboraciÃ³}
+# -- Missing translation: _textgs3_
+
+_textcreditstitle_ [l=ca] {crÃšdits}
+
+_textwhoswho_ [l=ca] {El programari de Greenstone Ã©s el fruit de la colÂ·laboraciÃ³ de moltes persones. Rodger McNab i Stefan Boddie en sÃ³n els principals arquitectes i programadors. TambÃ© hi han fet aportacions David Bainbridge, George Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd Reed, Bill Rogers, John Thompson i Stuart Yeates. Altres membres del Projecte de Biblioteca Digital de Nova Zelanda han aportat valuoses idees i suggeriments al disseny del sistema: Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka
+Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols i Lloyd Smith. TambÃ© volem donar les grÃ cies a tots aquells que han contribuÃ¯t als paquets amb llicÃšncia de GNU que s'inclouen en aquesta dstribuciÃ³: MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE i XLHTML.
+}
+
+_textaboutgslong_ [l=ca] {sobre el programari de Greenstone}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=ca] {Llista d'usuaris actuals}
+_textuser_ [l=ca] {usuari
+}
+_textas_ [l=ca] {estat del compte}
+_textgroups_ [l=ca] {grups}
+_textcomment_ [l=ca] {comentari}
+_textadduser_ [l=ca] {afegeix un nou usuari}
+_textedituser_ [l=ca] {edita}
+_textdeleteuser_ [l=ca] {suprimeix}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=ca] {Edita informaciÃ³ d'usuari}
+_textadduser_ [l=ca] {Afegeix un nou usuari}
+
+_textaboutusername_ [l=ca] {Els noms d'usuari han de ser d'entre 2 i 30 carÃ cters. Poden contenir carÃ cters alfanumÃšrics,  '.' i '_'.}
+
+_textaboutpassword_ [l=ca] {Les contrasenyes han de ser d'entre 3 i 128 carÃ cters. Poden contenir tots els carÃ cters normals d'ASCII que es poden imprimir. }
+
+_textoldpass_ [l=ca] {Si aquest camp estÃ  en blanc, es conservarÃ  l'antiga contrasenya. }
+_textenabled_ [l=ca] {habilitat}
+_textdisabled_ [l=ca] {inhabilitat}
+
+_textaboutgroups_ [l=ca] {Els grups sÃ³n llistes que se separen amb comes, no poseu espais desprÃ©s de les comes. }
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=ca] {Suprimeix un usuari}
+_textremwarn_ [l=ca] {Segur que voleu suprimir permanentment l'usuari <b>_cgiargumun_</b>?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=ca] {Canvia la contrasenya}
+_textoldpw_ [l=ca] {antiga contrasenya}
+_textnewpw_ [l=ca] {nova contrasenya}
+_textretype_ [l=ca] {torneu a escriure la nova contrasenya}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=ca] {La vostra contrasenya ha estat canviada. }
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=ca] {El nom d'usuari no Ã©s vÃ lid.}
+_textinvalidpassword_ [l=ca] {La contrasenya no Ã©s vÃ lida.}
+_textemptypassword_ [l=ca] {Per favor, escriviu una contrasenya inicial per a aquest usuari}
+_textuserexists_ [l=ca] {Aquest usuari ja existeix; per favor, escriviu un altre nom d'usuari.}
+
+_textusernameempty_ [l=ca] {Per favor, escriviu el vostre nom d'usuari.}
+_textpasswordempty_ [l=ca] {Heu d'introduir la contrasenya antiga.}
+_textnewpass1empty_ [l=ca] {IntroduÃ¯u la nova contrasenya i desprÃ©s torneu-la a escriure.}
+_textnewpassmismatch_ [l=ca] {Les dues versions de la nova contrasenya no coincideixen.}
+_textnewinvalidpassword_ [l=ca] {Heu escrit una contrasenya no vÃ lida.}
+_textfailed_ [l=ca] {Hi ha un error en el nom d'usuari o la contrasenya.}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=ca] {NÃºmero de versiÃ³ de Greenstone}
+_textframebrowser_ [l=ca] {Per visualitzar aixÃ² us cal un navegador que accepti marcs ("frames").}
+_textusermanage_ [l=ca] {AdministraciÃ³ d'usuaris}
+_textlistusers_ [l=ca] {llista d'usuaris}
+_textaddusers_ [l=ca] {afegeix un nou usuari}
+_textchangepasswd_ [l=ca] {canvia la contrasenya}
+_textinfo_ [l=ca] {InformaciÃ³ tÃšcnica}
+_textgeneral_ [l=ca] {general}
+_textarguments_ [l=ca] {arguments}
+_textactions_ [l=ca] {accions}
+_textbrowsers_ [l=ca] {navegadors}
+_textprotocols_ [l=ca] {protocols}
+_textconfigfiles_ [l=ca] {Fitxers de configuraciÃ³}
+_textlogs_ [l=ca] {Registres}
+_textusagelog_ [l=ca] {resgistre d'Ãºs}
+_textinitlog_ [l=ca] {registre d'inicialitzaciÃ³}
+_texterrorlog_ [l=ca] {registre d'errors}
+_textadminhome_ [l=ca] {pÃ gina principal de l'administraciÃ³}
+_textreturnhome_ [l=ca] {PÃ gina principal de Greenstone}
+_titlewelcome_ [l=ca] {AdministraciÃ³ }
+_textmaas_ [l=ca] {Els serveis de manteniment i administraciÃ³ sÃ³n els segÃŒents:}
+_textvol_ [l=ca] {visualitza els registres en lÃ­nia}
+_textcmuc_ [l=ca] {crea, mantÃ© i actualitza colÂ·leccions}
+_textati_ [l=ca] {accedeix a informaciÃ³ tÃšcnica com ara arguments CGI}
+
+_texttsaa_ [l=ca] {Es pot accedir a aquests serveis mitjanÃ§ant la barra de navegaciÃ³ situada a  l'esquerra de la pÃ gina.}
+
+_textcolstat_ [l=ca] {Estat de la colÂ·lecciÃ³}
+
+_textcwoa_ [l=ca] {Una colÂ·lecciÃ³ nomÃ©s apareixerÃ  com a "running" (en funcionament) si el fitxer build.cfg existeix, es pot llegir i contÃ© un camp vÃ lid de "builddate" (data de construcciÃ³), Ã©s a dir, > 0, i Ã©s al directori Ã­ndex de la colÂ·lecciÃ³ (Ã©s a dir, NO al directori de construcciÃ³). }
+
+_textcafi_ [l=ca] {pitgeu <i>abrev.</i> per obtenir informaciÃ³ sobre la colÂ·lecciÃ³}
+_textcctv_ [l=ca] {pitgeu <i>colÂ·lecciÃ³</i> per visualitzar una colÂ·lecciÃ³}
+_textsubc_ [l=ca] {Aplica canvis}
+_texteom_ [l=ca] {Error en obrir main.cfg}
+_textftum_ [l=ca] {No s'ha pogut actualitzar main.cfg}
+_textmus_ [l=ca] {s'ha actualitzat satisfactÃ²riament el fitxer main.cfg }
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=ca] {Resum de construcciÃ³ de la colÂ·lecciÃ³  _collectionname_ }
+_textflog_ [l=ca] {Error en el registre de la colÂ·lecciÃ³  _collectionname_ }
+
+
+############################################################################
+#
+# This stuff is only used by the usability (I'd like to Complain) stuff
+#
+############################################################################
+package Global
+
+_greenstoneusabilitytext_ [l=ca] {Capacitat d'Ãºs de Greenstone}
+
+_textwhy_ [l=ca] {<p>Enviar aquest informe Ã©s una manera d'indicar que la pÃ gina que mirÃ veu us ha semblat difÃ­cil d'utilitzar o frustrant.}
+_textextraforform_ [l=ca] {No cal que empleneu el formulari -- qualsevol informaciÃ³ serÃ  d'utilitat.}
+_textprivacybasic_ [l=ca] {<p>L'informe nomÃ©s contindrÃ  informaciÃ³ sobre la pÃ gina web de Greenstone que estÃ veu visualitzant i sobre la tecnologia que emprÃ veu per visualitzar-la (a mÃ©s de qualsevol informaciÃ³ opcional que doneu). }
+_textstillsend_ [l=ca] {Encara voleu enviar aquest informe?}
+
+_texterror_ [l=ca] {error}
+_textyes_ [l=ca] {SÃ­}
+_textno_ [l=ca] {No}
+_textclosewindow_ [l=ca] {Tanca la finestra}
+_textabout_ [l=ca] {Sobre}
+_textprivacy_ [l=ca] {Privadesa}
+_textsend_ [l=ca] {Envia}
+_textdontsend_ [l=ca] {No enviÃ¯s}
+_textoptionally_ [l=ca] {Opcionalment}
+
+_textunderdev_ [l=ca] {La vista preliminar dels detalls estarÃ  disponible a la versiÃ³ final.}
+
+_textviewdetails_ [l=ca] {Mostra els detalls de l'informe}
+_textmoredetails_ [l=ca] {MÃ©s detalls}
+_texttrackreport_ [l=ca] {Segueix el recorregut d'aquest informe}
+_textcharacterise_ [l=ca] {Quina mena de problema Ã©s}
+_textseverity_ [l=ca] {Com Ã©s de greu el problema?}
+ 
+_textbadrender_ [l=ca] {La pÃ gina es veu rara}
+_textcontenterror_ [l=ca] {Error de contingut}
+_textstrangebehaviour_ [l=ca] {Comportament estrany}
+_textunexpected_ [l=ca] {S'ha produÃ¯t un fet inesperat}
+_textfunctionality_ [l=ca] {DifÃ­cil d'utilitzar}
+_textother_ [l=ca] {Altre}
+
+_textcritical_ [l=ca] {CrÃ­tic}
+_textmajor_ [l=ca] {Greu}
+_textmedium_ [l=ca] {MitjÃ }
+_textminor_ [l=ca] {Lleu}
+_texttrivial_ [l=ca] {Trivial}
+
+_textwhatdoing_ [l=ca] {QuÃš intentÃ veu fer?}
+_textwhatexpected_ [l=ca] {QuÃš pensÃ veu que passaria?}
+_textwhathappened_ [l=ca] {QuÃš ha passat realment?}
+
+_cannotfindcgierror_ [l=ca] {<h2>Disculpeu!</h2>No\\ s'han trobat els programes del servidor per al botÃ³ "Vull\\ formular una queixa".}
+
+_textusabbanner_ [l=ca] {el rÃštol d'estil koru de Greenstone }
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+# -- Missing translation: _textgti_
+
+# -- Missing translation: _textgtierror_
+
+# -- Missing translation: _textgtihome_
+
+# -- Missing translation: _textgtiselecttlc_
+
+# -- Missing translation: _textgtiselecttfk_
+
+# -- Missing translation: _textgticoredm_
+# -- Missing translation: _textgtiauxdm_
+# -- Missing translation: _textgtiglidict_
+# -- Missing translation: _textgtiperlmodules_
+# -- Missing translation: _textgtigreenorg_
+
+# -- Missing translation: _textgtienter_
+
+# -- Missing translation: _textgticorrectexistingtranslations_
+# -- Missing translation: _textgtidownloadtargetfile_
+# -- Missing translation: _textgtiviewtargetfileinaction_
+
+# -- Missing translation: _textgtinumchunksmatchingquery_
+
+# -- Missing translation: _textgtinumchunkstranslated_
+# -- Missing translation: _textgtinumchunksrequiringupdating_
+# -- Missing translation: _textgtinumchunksrequiringtranslation_
+
+# -- Missing translation: _textgtienterquery_
+# -- Missing translation: _textgtifind_
+
+# -- Missing translation: _textgtitranslatingchunk_
+# -- Missing translation: _textgtiupdatingchunk_
+# -- Missing translation: _textgtisubmit_
+
+# -- Missing translation: _textgtilastupdated_
+
+# -- Missing translation: _textgtitranslationfilecomplete_
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=ca] {la interficie del bibliotecari de Greenstone}
+_textglihelp_ [l=ca] {La InterfÃ­cie del Bibliotecari de Greenstone (GLI) us facilita l'accÃ©s a les funcions de Greenstone mitjanÃ§ant una interfÃ­cie fÃ cil d'utilitzar en la qual nomÃ©s cal "apuntar i pitjar". AixÃ² us permet recopilar grups de documents, importar o assignar metadades i incorporar-les a una colÂ·lecciÃ³ de Greenstone. 
+ <p>
+Recordeu que la GLI s'executa juntament amb Greenstone i que suposa que estÃ  instalÂ·lada en un subdirectori de la vostra instalÂ·laciÃ³ de Greenstone. Aquest serÃ  el cas si heu baixat una de les distribucions de Greenstone d'Internet, o si l'heu instalÂ·lada a partir d'un cd-rom de Greenstone.
+ 
+ 
+<h4>Executar la GLI des de Windows</h4>
+ 
+Si treballeu amb Windows, feu arrencar la interfÃ­cie del bibliotecari seleccionant <i>Biblioteca Digital Greenstone</i> a la secciÃ³ <i>Programes</i> del menÃº <i>Inici</i> i triant <i>InterfÃ­cie del bibliotecari</i>. 
+
+ 
+<h4>Excutar la GLI des d'Unix</h4>
+ 
+Per executar la GLI des d'Unix, canvieu al directori <i>gli</i> de la vostra instalÂ·laciÃ³ de Greenstone i llavors executeu el guiÃ³ <i>gli.sh</i>. 
+ 
+<h4>Executar la GLI des de Mac OS X</h4>
+
+En el cercador, aneu a <i>Aplicacions</i> i d'allÃ  a <i>Greenstone</i>
+(si heu instalÂ·lat Greenstone a la ubicaciÃ³ per defecte), i llavors feu arrencar l'aplicaciÃ³ <i>GLI</i>.
+}
+
Index: /gsdl/stable/macros/chinese-trad.dm
===================================================================
--- /gsdl/stable/macros/chinese-trad.dm	(revision 20131)
+++ /gsdl/stable/macros/chinese-trad.dm	(revision 20131)
@@ -0,0 +1,859 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Traditional Chinese Language text and icon macros
+# Many thanks to Shu-Jen Show and team (translated November 2004) 
+# Many thanks to Lilly Ho (updated February 2009)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=zh-tr] {éèª}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=zh-tr] {åèäŸæºïŒ}
+_textdate_ [l=zh-tr] {åºçæ¥æïŒ}
+_textnumpages_ [l=zh-tr] {çžœé æžïŒ}
+
+_textsignin_ [l=zh-tr] {ç»å
+¥}
+
+_textdefaultcontent_ [l=zh-tr] {æŸäžå°ç¶²é ïŒè«æ"äžäžé "æ"éŠé ",åå°Geeenstone æžäœåæžé€šã}
+
+_textdefaulttitle_ [l=zh-tr] {Greenstoneç³»çµ±é¯èª€}
+
+_textbadcollection_ [l=zh-tr] {éåè³æåº«(called "_cvariable_") æ²æå®è£åšæ­€Greenstoneæžäœåæžé€šç³»çµ±è£¡ã}
+
+_textselectpage_ [l=zh-tr] {-- éžåçé æž --}
+
+_collectionextra_ [l=zh-tr] {éåè³æåº«å
+å« _about:numdocs_ ä»œæä»¶ã
+æåŸæŽæ°çº _about:builddate_ å€©ä¹åã}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=zh-tr] {<p>éåå
+žèè³æåº«å
+å« _numdocs_ _If_("_numdocs_" eq "1",ä»œæä»¶,ä»œæä»¶)ïŒå
+±æ _numbytes_ çæå­å metadataã
+<p><a href="_httppagex_(bsummary)">æäžéè£</a>ä»¥æª¢èŠå»ºç«éåè³æåº«æçæèŠã}  
+
+_textdescrcollection_ [l=zh-tr] {}
+_textdescrabout_ [l=zh-tr] {éæŒé }
+_textdescrhome_ [l=zh-tr] {éŠé }
+_textdescrhelp_ [l=zh-tr] {åž®å©é¡µ}
+_textdescrpref_ [l=zh-tr] {åäººåå¥œèš­å®é }
+_textdescrgreenstone_ [l=zh-tr] {Greenstone æžäœåæžé€šè»é«}
+_textdescrusab_ [l=zh-tr] {äœ åšäœ¿çšäžæç¢°å°ä»éºŒå°é£åïŒ}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=zh-tr] {æå°}  
+_labelSearch_ [l=zh-tr] {æå°}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=zh-tr] {æšé¡}  
+_labelTitle_ [l=zh-tr] {æšé¡}  
+_textCreator_ [l=zh-tr] {åµäœè
+}  
+_labelCreator_ [l=zh-tr] {äœè
+}  
+_textSubject_ [l=zh-tr] {äž»é¡}  
+_labelSubject_ [l=zh-tr] {äž»é¡}
+_textDescription_ [l=zh-tr] {æè¿°}  
+_labelDescription_ [l=zh-tr] {æè¿°}
+_textPublisher_ [l=zh-tr] {åºçè
+}  
+_labelPublisher_ [l=zh-tr] {åºçè
+}
+_textContributor_ [l=zh-tr] {è²¢ç»è
+}  
+_labelContributor_ [l=zh-tr] {è²¢ç»è
+}
+_textDate_ [l=zh-tr] {æ¥æ}  
+_labelDate_ [l=zh-tr] {æ¥æ}
+_textType_ [l=zh-tr] {çš®é¡}  
+_labelType_ [l=zh-tr] {çš®é¡}
+_textFormat_ [l=zh-tr] {æ ŒåŒ}  
+_labelFormat_ [l=zh-tr] {æ ŒåŒ}
+_textIdentifier_ [l=zh-tr] {éå®è
+}  
+_labelIdentifier_ [l=zh-tr] {ç¢ºèªè
+}
+_textSource_ [l=zh-tr] {æªæ¡åçš±}  
+_labelSource_ [l=zh-tr] {æªæ¡å}
+_textLanguage_ [l=zh-tr] {èªèš}  
+_labelLanguage_ [l=zh-tr] {èªèš}
+_textRelation_ [l=zh-tr] {éä¿}  
+_labelRelation_ [l=zh-tr] {éä¿}
+_textCoverage_ [l=zh-tr] {èŠèç¯å}  
+_labelCoverage_ [l=zh-tr] {ç¯å}
+_textRights_ [l=zh-tr] {æ¬å}  
+_labelRights_ [l=zh-tr] {æ¬å©}
+
+# DLS metadata set
+_textOrganization_ [l=zh-tr] {çµç¹}  
+_labelOrganization_ [l=zh-tr] {çµç¹}  
+_textKeyword_ [l=zh-tr] {ééµè©}  
+_labelKeyword_ [l=zh-tr] {ééµå­}
+_textHowto_ [l=zh-tr] {åŠäœ}  
+_labelHowto_ [l=zh-tr] {åŠäœ}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=zh-tr] {æ
+£çšèª}  
+_labelPhrase_ [l=zh-tr] {çèª}  
+_textCollage_ [l=zh-tr] {çŸè¡æŒè²Œ}  
+_labelCollage_ [l=zh-tr] {åèŒ¯}  
+_textBrowse_ [l=zh-tr] {çèŠœ}  
+_labelBrowse_ [l=zh-tr] {çèŠœ}  
+_textTo_ [l=zh-tr] {å»}  
+_labelTo_ [l=zh-tr] {æªæ­¢æŒ}
+_textFrom_ [l=zh-tr] {ç±}  
+_labelFrom_ [l=zh-tr] {éå§æŒ}
+_textAcronym_ [l=zh-tr] {éŠå­æ¯ççž®å¯«}  
+_labelAcronym_ [l=zh-tr] {çž®å¯«å­}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=zh-tr] {ä»¥ _1_ çèŠœ}  
+
+_textdescrSearch_ [l=zh-tr] {æŸå°æŽç²Ÿç¢ºçå­äž²}
+_textdescrType_ [l=zh-tr] {äŸè³æºé¡åçèŠœ}  
+_textdescrIdentifier_ [l=zh-tr] {äŸè³æºç¢ºèªè
+çèŠœ}  
+_textdescrSource_ [l=zh-tr] {äŸåå§æªåçèŠœ}  
+_textdescrTo_ [l=zh-tr] {äŸæªæ­¢æŒæ¬äœçèŠœ}  
+_textdescrFrom_ [l=zh-tr] {äŸéå§æ¬äœçèŠœ}  
+_textdescrCollage_ [l=zh-tr] {äŸåœ±åéçèŠœ}  
+_textdescrAcronym_ [l=zh-tr] {äŸçž®å¯«å­çèŠœ}  
+_textdescrPhrase_ [l=zh-tr] {äŸçèªçèŠœ}  
+_textdescrHowto_ [l=zh-tr] {äŸ âåŠäœ..âæ¹åŒäŸçèŠœ}  
+_textdescrBrowse_ [l=zh-tr] {çèŠœæä»¶}  
+_texticontext_ [l=zh-tr] {åé±æä»¶}
+_texticonclosedbook_ [l=zh-tr] {æéæ­€æä»¶äžŠäžæª¢èŠå
+§å®¹}
+_texticonnext_ [l=zh-tr] {å°äžäžæ®µèœ}
+_texticonprev_ [l=zh-tr] {ååäžæ®µèœ}
+
+_texticonworld_ [l=zh-tr] {æª¢èŠç¶²é çæä»¶}  
+
+_texticonmidi_ [l=zh-tr] {æª¢èŠMIDIæä»¶}
+_texticonmsword_ [l=zh-tr] {æª¢èŠMicrosoft Wordæä»¶}
+_texticonmp3_ [l=zh-tr] {æª¢èŠ MP3 æ ŒåŒçæä»¶}  
+_texticonpdf_ [l=zh-tr] {æª¢èŠ PDF æä»¶}  
+_texticonps_ [l=zh-tr] {æª¢èŠ PostScript æä»¶}  
+_texticonppt_ [l=zh-tr] {æª¢èŠ PowerPoint æä»¶}  
+_texticonrtf_ [l=zh-tr] {æª¢èŠ RTF æä»¶}  
+_texticonxls_ [l=zh-tr] {æª¢èŠ Microsoft Excel æä»¶}  
+
+_page_ [l=zh-tr] {é }
+_pages_ [l=zh-tr] {é }
+_of_ [l=zh-tr] {ç}
+_vol_ [l=zh-tr] {å}  
+_num_ [l=zh-tr] {åŠ}
+
+_textmonth00_ [l=zh-tr] {}
+_textmonth01_ [l=zh-tr] {äžæ}
+_textmonth02_ [l=zh-tr] {äºæ}
+_textmonth03_ [l=zh-tr] {äžæ}
+_textmonth04_ [l=zh-tr] {åæ}
+_textmonth05_ [l=zh-tr] {äºæ}
+_textmonth06_ [l=zh-tr] {å
+­æ}
+_textmonth07_ [l=zh-tr] {äžæ}
+_textmonth08_ [l=zh-tr] {å
+«æ}
+_textmonth09_ [l=zh-tr] {ä¹æ}
+_textmonth10_ [l=zh-tr] {åæ}
+_textmonth11_ [l=zh-tr] {åäžæ}
+_textmonth12_ [l=zh-tr] {åäºæ}
+
+_textdocument_ [l=zh-tr] {æä»¶}
+_textsection_ [l=zh-tr] {åæ®µ}
+_textparagraph_ [l=zh-tr] {æ®µèœ}
+
+_magazines_ [l=zh-tr] {æå}
+
+_nzdlpagefooter_ [l=zh-tr] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">çŽè¥¿è­æžäœåæžé€šèšç«</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">è³èšç§å­žç³»æ</a>, 
+<a href="http://www.waikato.ac.nz">Waikatoå€§å­ž</a>, 
+çŽè¥¿è­}
+
+_linktextHOME_ [l=zh-tr] {éŠé }
+_linktextHELP_ [l=zh-tr] {å¹«å©}
+_linktextPREFERENCES_ [l=zh-tr] {åäººåå¥œèš­å®é }
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=zh-tr] {Greenstone æžäœåæžé€š}
+
+_textnocollections_ [l=zh-tr] {æ²æåé©çå
+žèè³æåº«ï¹äŸåŠå·²å»ºç«åå
+¬å
+±çï¹å¯äŸäœ¿çš}  
+
+_textadmin_ [l=zh-tr] {ç®¡çé é¢}
+_textabgs_ [l=zh-tr] {éæŒGreenstone}
+_textgsdocs_ [l=zh-tr] {Greenstone æä»¶}
+
+_textdescradmin_ [l=zh-tr] {å
+èš±äœ æ°å¢æ°çäœ¿çšè
+ïŒåœæŽç³»çµ±è£¡çè³æåº«å
+žèè³èšïŒæäŸGreenstoneå®è£çæè¡è³èšã}
+
+_textdescrgogreenstone_ [l=zh-tr] {åèšŽäœ æéGreenstoneè»é«åçŽè¥¿è­æžäœåæžé€šèšç«çæ²¿é©ã}
+
+_textdescrgodocs_ [l=zh-tr] {Greenstone æå}
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=zh-tr] {åæžé€šå¡ä»é¢}
+_textdescrgli_ [l=zh-tr] {åå©äœ å»ºç«æ°çè³æåº«ïŒå°å·²æçè³æåº«åä¿®æ¹æ°å¢æä»¶ïŒæåªé€è³æåº«ã}
+
+package collector
+
+_textcollector_ [l=zh-tr] {è³æåº«å
+žèä»é¢}
+_textdescrcollector_ [l=zh-tr] {éåèŒæ©æŒåæžé€šé€šé·ä»é¢ççŒå±ïŒåæçºäºå€§éšåå¯Šéçç®çïŒèæ¡çšåæžé€šé€šé·ä»é¢ã}  
+
+package depositor
+
+_textdepositor_ [l=zh-tr] {å­æ¬Ÿè
+}  
+_textdescrdepositor_ [l=zh-tr] {åå©æšå å
+¥æä»¶è³çŸå­çå
+žèè³æåº«}  
+
+package gti
+
+_textgti_ [l=zh-tr] {Greenstone ç¿»è­¯ä»é¢}  
+_textdescrtranslator_ [l=zh-tr] {åå©äœ ç¶­æææ°çGreenstonå€èªèšçæ¬ã}
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=zh-tr] {éæŒéåè³æåº«}
+
+_textsubcols1_ [l=zh-tr] {<p>éåè³æåº«ç± _1_ å­è³æåº«çµæïŒä»åäœæŒïŒ
+<blockquote>
+}
+
+_textsubcols2_ [l=zh-tr] {</blockquote>
+äœ å¯ä»¥åšåäººåå¥œèš­å®é æ¥è©¢ïŒäžŠä¿®æ¹ïŒç®åæ­£åšäœ¿çšäž­çè³æåº«ã}
+
+_titleabout_ [l=zh-tr] {éæŒ}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=zh-tr] {ééæ¬æ®µèœ}
+_texticonclosedbookshelf_ [l=zh-tr] {éåæ¬æ®µèœäžŠæª¢èŠå
+¶å
+§å®¹}
+_texticonopenbook_ [l=zh-tr] {ééæ¬æž}
+_texticonclosedfolder_ [l=zh-tr] {éåæ­€è³æå€ŸäžŠæª¢èŠç®é}
+_texticonclosedfolder2_ [l=zh-tr] {éåæ­€å­åæ®µïŒ}
+_texticonopenfolder_ [l=zh-tr] {ééæ­€è³æå€Ÿ}
+_texticonopenfolder2_ [l=zh-tr] {ééæ­€å­åæ®µïŒ}
+_texticonsmalltext_ [l=zh-tr] {æª¢èŠæ­€æ®µæå­}
+_texticonsmalltext2_ [l=zh-tr] {æª¢èŠæå­ïŒ }
+_texticonpointer_ [l=zh-tr] {ç®åæ®µèœ}
+_texticondetach_ [l=zh-tr] {åšæ°èŠçªéåæ­€é }
+_texticonhighlight_ [l=zh-tr] {æšç€ºæå°ä¹ééµå­}
+_texticonnohighlight_ [l=zh-tr] {äžèŠæšç€ºæå°ä¹ééµå­}
+_texticoncontracttoc_ [l=zh-tr] {ééç®æ¬¡åè¡š}
+_texticonexpandtoc_ [l=zh-tr] {å±éç®æ¬¡}
+_texticonexpandtext_ [l=zh-tr] {é¡¯çŸæä»¶å
+šæ}
+_texticoncontracttext_ [l=zh-tr] {éå°æéžåçæ®µèœåªé¡¯ç€ºæå­}
+_texticonwarning_ [l=zh-tr] {<b>è­ŠåïŒ</b>}
+_texticoncont_ [l=zh-tr] {æ¯åŠç¹ŒçºïŒ}
+
+_textltwarning_ [l=zh-tr] {<div class="buttons">_imagecont_</div>
+_iconwarning_è¥èŠå±éæ­€æä»¶ä¹å
+šæåå°æåšäœ ççèŠœåšäžæ¬¡é¡¯ç€ºå€§éçè³æ
+}
+
+_textgoto_ [l=zh-tr] {å°è©²é }
+_textintro_ [l=zh-tr] {<i>(åèšæå­)</i>}
+
+_textCONTINUE_ [l=zh-tr] {ç¹ŒçºïŒ?}
+
+_textEXPANDTEXT_ [l=zh-tr] {å±éæå­}  
+
+_textCONTRACTCONTENTS_ [l=zh-tr] {ééç®é}  
+
+_textDETACH_ [l=zh-tr] {éåæ°èŠçª}
+
+_textEXPANDCONTENTS_ [l=zh-tr] {éåç®é}  
+
+_textCONTRACT_ [l=zh-tr] {ééæå­}  
+
+_textHIGHLIGHT_ [l=zh-tr] {åçœé¡¯ç€º}  
+
+_textNOHIGHLIGHT_ [l=zh-tr] {äžåçœé¡¯ç€º}  
+
+_textPRINT_ [l=zh-tr] {åå°}  
+
+_textnextsearchresult_ [l=zh-tr] {äžäžåæå°çµæ}  
+_textprevsearchresult_ [l=zh-tr] {åäžåæå°çµæ}  
+
+# macros for printing page
+_textreturnoriginal_ [l=zh-tr] {éååäŸçé é¢}  
+_textprintpage_ [l=zh-tr] {åå°éé }  
+_textshowcontents_ [l=zh-tr] {é¡¯ç€ºç®é}  
+_texthidecontents_ [l=zh-tr] {é±èç®é}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=zh-tr] {_If_(_thislast_,results _thisfirst_ - _thislast_ éå°æ¥è©¢: _cgiargq_ïŒæå°äžå°ç¬Šåçæ¢ä»¶: _cgiargq_)}
+_textnoquerytitle_ [l=zh-tr] {æå°é é¢}
+
+_textsome_ [l=zh-tr] {éšå}
+_textall_ [l=zh-tr] {å
+šéš}
+_textboolean_ [l=zh-tr] {åžæéèŒ¯}
+_textranked_ [l=zh-tr] {æå}
+_textnatural_ [l=zh-tr] {èªç¶}
+_textsortbyrank_ [l=zh-tr] {é©å®çç­çŽ}  
+_texticonsearchhistorybar_ [l=zh-tr] {æå°æ­·å²çŽé}
+
+_textifeellucky_ [l=zh-tr] {æèŠºåŸå¹žé!}
+
+#alt text for query buttons
+_textusequery_ [l=zh-tr] {äœ¿çšéåæ¥è©¢é 
+ç®}
+_textfreqmsg1_ [l=zh-tr] {ç¬Šåçå­æž: }
+_textpostprocess_ [l=zh-tr] {_If_(_quotedquery_,<br><i> åŸèçå»çŒçŸ _quotedquery_</i>
+)}
+_textinvalidquery_ [l=zh-tr] {é¯èª€çæ¥è©¢èªæ³}
+_textstopwordsmsg_ [l=zh-tr] {ä»¥äžçå­å¥éæŒæ®éèè¢«å¿œç¥ïŒ}  
+_textlucenetoomanyclauses_ [l=zh-tr] {æšçæ¥è©¢èªæ³å
+æ¬å€ªå€çæå°è©åœïŒè«åè©ŠäžåæŽæç¢ºçæ¥è©¢ã}  
+
+_textmorethan_ [l=zh-tr] {å€§æŒ}
+_textapprox_ [l=zh-tr] {éæŒ}
+_textnodocs_ [l=zh-tr] {æ²ææä»¶ç¬Šåæ¥è©¢çæ¢ä»¶ã}
+_text1doc_ [l=zh-tr] {äžä»œæä»¶ç¬Šåæ¥è©¢çæ¢ä»¶ã}
+_textlotsdocs_ [l=zh-tr] {ç¬Šåæ¥è©¢æ¢ä»¶ä¹æä»¶ã}
+_textmatches_ [l=zh-tr] {åç¬Šå}
+_textbeginsearch_ [l=zh-tr] {éå§æå°}
+_textrunquery_ [l=zh-tr] {éå§æå°}  
+_textclearform_ [l=zh-tr] {æž
+é€è¡šæ Œ}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=zh-tr] {å­å¥}  
+_textinfield_ [l=zh-tr] {... åšé å}
+_textfoldstem_ [l=zh-tr] {(è³æå€Ÿ, çµå°Ÿ)}
+
+_textadvquery_ [l=zh-tr] {æçŽæ¥èŒžå
+¥æ¥è©¢èªæ³ïŒ}  
+_textallfields_ [l=zh-tr] {å
+šéšæ¬äœ}  
+_texttextonly_ [l=zh-tr] {åªéæå­}
+_textand_ [l=zh-tr] {å}  
+_textor_ [l=zh-tr] {æ}  
+_textandnot_ [l=zh-tr] {åäžå
+æ¬}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=zh-tr] {åš _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_, at _gselection_ level )_If_(_nselection_,in _nselection_ language ) é²è¡æå°ïŒå
+å« _querytypeselection_ ç words_If_(_sfselection_,\,_allowformbreak_ sorting results by _sfselection_)}  
+
+_textadvancedsearch_ [l=zh-tr] {åš _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language ) é²è¡æå°ïŒå¯äœ¿çš _querytypeselection_ èªæ³æ¥è©¢}  
+
+_textadvancedmgppsearch_ [l=zh-tr] {åš _indexselection_ _If_(_jselection_,associated with _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language ) é²è¡æå°ïŒäžŠå°çµæé¡¯ç€ºæŒ _formquerytypeadvancedselection_ orderïŒä»¥äœ}  
+
+_textadvancedlucenesearch_ [l=zh-tr] {åš _indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ sorting results by _sfselection_\,) é²è¡æå° ïŒä»¥äœ}  
+
+_textformsimplesearch_ [l=zh-tr] {åš _If_(_jselection_, _jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language) é²è¡æå°ïŒä»¥ _formquerytypesimpleselection_ æ¥è©¢}  
+
+_textformadvancedsearchmgpp_ [l=zh-tr] {åš _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language ) é²è¡æå°ïŒäžŠå°çµæä»¥ã_formquerytypeadvancedselection_ æ¬¡åºé¡¯ç€ºåºäŸïŒ}  
+
+_textformadvancedsearchlucene_ [l=zh-tr] {åš _If_(_jselection_, _jselection_)_If_(_gformselection_,  at _gformselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\, sorting results by _sfselection_\,) é²è¡æå°ïŒä»¥äœ }  
+
+_textnojsformwarning_ [l=zh-tr] {è­Šå: Javascript å·è¡ç°å¢è¢«çèŠœåšééäºïŒ<br>çºäºèŠå·è¡è¡šæ Œæ¥è©¢è«éåJavascriptã}
+_textdatesearch_ [l=zh-tr] {éåè³æåº«åšæ¥è©¢æå¯ä»¥åŠå€åå äžæéæ¢ä»¶}
+_textstartdate_ [l=zh-tr] {éå§ (æéå¶) æ¥æ:}
+_textenddate_ [l=zh-tr] {çµææ¥æ:}
+_textbc_ [l=zh-tr] {è¥¿å
+å}
+_textad_ [l=zh-tr] {è¥¿å
+}
+_textexplaineras_ [l=zh-tr] {C.E. å B.C.E çºè¥¿å
+ (A.D) èè¥¿å
+å (B.C) ä¹åçŸ©è©ïŒåå¥ä»£è¡š "Common Era" è "Before the Common Era"}  
+
+_textstemon_ [l=zh-tr] {(å¿œç¥å­å°Ÿ)}
+
+_textsearchhistory_ [l=zh-tr] {æ¥è©¢æ­·å²èšé}
+
+#text macros for search history
+_textnohistory_ [l=zh-tr] {æ¥è©¢æ­·å²çŽéäžå­åš}
+_texthresult_ [l=zh-tr] {çµæ}
+_texthresults_ [l=zh-tr] {çµæ}
+_texthallwords_ [l=zh-tr] {ææå­æž}
+_texthsomewords_ [l=zh-tr] {äžäºå­}
+_texthboolean_ [l=zh-tr] {åžæéèŒ¯}
+_texthranked_ [l=zh-tr] {æå}
+_texthcaseon_ [l=zh-tr] {å€§å°å¯«éäžèŽ}
+_texthcaseoff_ [l=zh-tr] {å¿œç¥å€§å°å¯«}
+_texthstemon_ [l=zh-tr] {å¿œç¥æå­çµå°Ÿ}
+_texthstemoff_ [l=zh-tr] {æå­çµå°ŸéäžèŽ}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=zh-tr] {ä»¥äžå°èš­å®åäººåå¥œïŒè«å¿äœ¿çšçèŠœåšçåå°äžäžé æéïŒä»¥å
+ç¡æ³å®æåäººåå¥œèš­å®ïŒè«äœ¿çšäžæ¹å·¥å
+·åçæéã}
+_textsetprefs_ [l=zh-tr] {èš­å®åäººåå¥œ}
+_textsearchprefs_ [l=zh-tr] {æ¥è©¢åäººåå¥œ}
+_textcollectionprefs_ [l=zh-tr] {èéåäººåå¥œ}
+_textpresentationprefs_ [l=zh-tr] {é¡¯ç€ºåäººåå¥œèš­å®}
+_textpreferences_ [l=zh-tr] {åäººåå¥œ}
+_textcasediffs_ [l=zh-tr] {å€§å°å¯«èŠçºäžå:}
+_textignorecase_ [l=zh-tr] {å€§å°å¯«èŠçºçžå}  
+_textmatchcase_ [l=zh-tr] {å€§å°å¯«éå®å
+šäžèŽ}  
+_textwordends_ [l=zh-tr] {æå­çµå°ŸïŒ}  
+_textstem_ [l=zh-tr] {å¿œç¥æå­çµå°Ÿ}  
+_textnostem_ [l=zh-tr] {æŽåæå­å¿
+é äžèŽ}  
+_textaccentdiffs_ [l=zh-tr] {äžåçå£é³}  
+_textignoreaccents_ [l=zh-tr] {å¿œç¥å£é³}  
+_textmatchaccents_ [l=zh-tr] {å¿
+éå»åå£é³}  
+
+_textprefop_ [l=zh-tr] {æå€åå³ _maxdocoption_ åæ¥è©¢çµæïŒäžé é¡¯ç€º _hitsperpageoption_ åæ¥è©¢çµæã}
+_textextlink_ [l=zh-tr] {è®åå€éšç¶²é :}
+_textintlink_ [l=zh-tr] {éæ°åå°åå§æä»¶:}
+_textlanguage_ [l=zh-tr] {ä»é¢èªèš:}
+_textencoding_ [l=zh-tr] {ç·šç¢Œæ¹åŒ:}
+_textformat_ [l=zh-tr] {ä»é¢æ ŒåŒ:}
+_textall_ [l=zh-tr] {å
+šéš}
+_textquerymode_ [l=zh-tr] {æ¥è©¢æš¡åŒïŒ}  
+_textsimplemode_ [l=zh-tr] {ç°¡å®æ¥è©¢æš¡åŒ}  
+_textadvancedmode_ [l=zh-tr] {é²éæ¥è©¢æš¡åŒï¹å¯äœ¿çš !ã&ã| çéèŒ¯æ§éç®å­åçèªé²è¡æå°ï¹}  
+_textlinkinterm_ [l=zh-tr] {éééæ¥ç¶²é }
+_textlinkdirect_ [l=zh-tr] {çŽæ¥é£å°}
+_textdigitlib_ [l=zh-tr] {æžäœåæžé€š}
+_textweb_ [l=zh-tr] {ç¶²ç«}
+_textgraphical_ [l=zh-tr] {ååœ¢}
+_texttextual_ [l=zh-tr] {æå­}
+_textcollectionoption_ [l=zh-tr] {<p>
+å­è³æåº«æä»¶å
+æ¬:
+<br>}
+
+_textsearchtype_ [l=zh-tr] {æ¥è©¢èªæ³æ¬ŸåŒ}  
+_textformsearchtype_ [l=zh-tr] {å¡«æ»¿ _formnumfieldoption_ æ¬äœ}  
+_textplainsearchtype_ [l=zh-tr] {æ­£åžžç _boxsizeoption_ æ¥è©¢èªæ³é 
+ç®}  
+_textregularbox_ [l=zh-tr] {å®è¡}  
+_textlargebox_ [l=zh-tr] {å€§}  
+
+_textrelateddocdisplay_ [l=zh-tr] {ååºçžéæä»¶}
+_textsearchhistory_ [l=zh-tr] {æ¥è©¢çŽéïŒ}  
+_textnohistory_ [l=zh-tr] {äžèŠæ¥è©¢çŽé}  
+_texthistorydisplay_ [l=zh-tr] {ååº _historynumrecords_ çæ¥è©¢çæ­·å²çŽé}  
+_textnohistorydisplay_ [l=zh-tr] {äžèŠååºæ¥è©¢çæ­·å²çŽé}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=zh-tr] {æä»¶æåºäŸ}
+_textalsoshowing_ [l=zh-tr] {äžèµ·é¡¯ç€º}
+_textwith_ [l=zh-tr] {æå€ä»¥}
+_textdocsperpage_ [l=zh-tr] {æä»¶äž­çæ¯äžé }
+
+_textfilterby_ [l=zh-tr] {ååŸæä»¶å
+§å®¹}
+_textall_ [l=zh-tr] {å
+šéš}
+_textany_ [l=zh-tr] {ä»»äœ}
+_textwords_ [l=zh-tr] {å±¬æŒäžæ®µè©±}
+_textleaveblank_ [l=zh-tr] {äžéžææ­€é 
+ç®ïŒä»¥åŸå°æææä»¶}  
+
+_browsebuttontext_ [l=zh-tr] {"æä»¶æåº"}
+
+_nodata_ [l=zh-tr] {<i>æ²æè³æ</i>}
+_docs_ [l=zh-tr] {æä»¶}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=zh-tr] {å¹«å©}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=zh-tr] {æäžäž  _2_ éµïŒä»¥ _1_ äŸçèŠœæä»¶ã}  
+
+_textSearchhelp_ [l=zh-tr] {æäž  _labelSearch_  éµïŒä»¥æå°åºçŸæŒæå­å
+§çç¹å®å­å¥}  
+_textTohelp_ [l=zh-tr] {æäžäž _labelTo_ éµïŒä»¥æªæ­¢æŒæ¬äœçèŠœæä»¶}  
+_textFromhelp_ [l=zh-tr] {æäžäž _labelFrom_ éµïŒä»¥æ ¹æ From æ¬äœäŸçèŠœæä»¶ã}  
+_textBrowsehelp_ [l=zh-tr] {çèŠœæä»¶}  
+_textAcronymhelp_ [l=zh-tr] {æäžäž _labelAcronym_ éµïŒä»¥æ ¹æéŠå­æ¯çž®å¯«çæ¬¡åºäŸçèŠœæä»¶ã}  
+_textPhrasehelp_ [l=zh-tr] {æäž_labelPhrase_ éµïŒä»¥çèŠœåºçŸæŒæä»¶ççèªãéæ¯å©çš phind çèªçèŠœåšã}  
+
+_texthelptopicstitle_ [l=zh-tr] {ç®é}
+
+_textreadingdocs_ [l=zh-tr] {åŠäœé±è®æä»¶}
+
+_texthelpreadingdocs_ [l=zh-tr] {<p>è®åæäžåæä»¶æïŒééå°é¢æåçå°±ç¥éè¢å¹æ­£åšé¡¯ç€ºåªäžåæä»¶ãäžäºå
+žèè³æåº«çå°é¢æéæ¯ç®éè¡šïŒèæäºå
+žèè³æåº«å
+å
+æ¬ç®åçé ç¢Œåå¯ä»¥éžæåé²åŸéçéžé 
+ãç®éè¡šæ¯å¯å±éçïŒæäžç®éè¡šå¯æéæééæä»¶ïŒæäžæéæä»¶çäžæ¹åå¯ä»¥ééå®ã</p>
+
+<p>åšäžé¢æ¯ç®åéšåçæ¬æïŒç¶æšå·²ç¶è®éæïŒåºéšæäžåç®­é ­å¯ä»¥è®æšå°äžäžç« ç¯ææ¯åå°åäžç« ç¯ã</p>
+
+<p>åšæšé¡æå°é¢äžçæéïŒæäž<i>_document:textEXPANDTEXT_</i>ïŒä»¥å±éæç« ææžæ¬å
+§å®¹ãåŠææä»¶å€ªå€§ïŒå°æè±è²»èŒå€çæéèèšæ¶é«ïŒæäž<i>_document:textEXPANDCONTENTS_</i>å°å±éæŽä»œç®éïŒæšèœçèŠå
+šéšç« ç¯åæšé¡ãæäž<i>_document:textDETACH_</i>ä»¥æ°èŠçªéåæä»¶ãï¹ç¶æšæ³æ¯èŒæåæé±è®å
+©ç¯æç« ïŒéååèœåŸæçšãï¹æåŸïŒç¶æšæå°æïŒææå°çæå­æè¢«åçœé¡¯ç€ºïŒæäž<i>_document:textNOHIGHLIGHT_</i>åæç§»é€æå­çåçœé¡¯ç€ºã</p>}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=zh-tr] {éåæžæ«}
+_texthelpopenbook_ [l=zh-tr] {æé/éäžéæ¬æž}
+_texthelpviewtextsection_ [l=zh-tr] {çéæ®µæå­çç« ç¯}
+_texthelpexpandtext_ [l=zh-tr] {ååºæäžååºæå­}
+_texthelpexpandcontents_ [l=zh-tr] {å±éæäžå±éå
+§å®¹}
+_texthelpdetachpage_ [l=zh-tr] {ä»¥æ°èŠçªéåéäžé }
+_texthelphighlight_ [l=zh-tr] {æšç€ºæäžæšç€ºæå°é 
+ç®}
+_texthelpsectionarrows_ [l=zh-tr] {å»åäžåæäžäžåç« ç¯}  
+
+
+_texthelpsearchingtitle_ [l=zh-tr] {åŠäœæå°ç¹å®æç« }
+
+_texthelpsearching_ [l=zh-tr] {<p>
+ åšæå°é é¢å¯ä»¥åç°¡å®çæ¥è©¢æ­¥é©ïŒ<p>
+
+ <ol><li>æå®èŠæå°çé 
+ç®
+     <li>æå°æŽæ®µéæ¯éšåæå­
+     <li>èŒžå
+¥æèŠæå°çæå­
+     <li>æäž <i>éå§æå°</i> æé
+ </ol>
+
+<p>ç¶æå°å®ææïŒæ¯é æé¡¯ç€º 20 åç¬Šåçæä»¶è³æãæšå¯ä»¥æäžäžæéïŒä»¥é¡¯ç€ºäžäžçµ 20 åçæä»¶è³æïŒæé¡¯ç€ºåäžçµ 20 åçæä»¶è³æïŒåŠæ­€é¡æšãæäžäžä»»äœæä»¶è³æçé¡ç®é£çµææéçæéïŒæšäŸ¿å¯ä»¥é±è®æéçæä»¶è³æå
+§å®¹ã
+
+<p>æå€å¯ä»¥é¡¯ç€º 50 åæä»¶è³æãæšå¯ä»¥æäžé é¢äžæ¹ç<i>_Global:linktextPREFERENCES_</i>æéïŒä»¥æ¹è®é¡¯ç€ºæžéã<p>}  
+
+_texthelpquerytermstitle_ [l=zh-tr] {æå°è©åœ}  
+_texthelpqueryterms_ [l=zh-tr] {<p>èŒžå
+¥çä»»äœè³æçš±çº"æå°é 
+ç®" ïŒèæ¯åæå°é 
+ç®åªå¯æ¯å­æ¯ææ¯æžå­ãæå°æ¢ä»¶ä¹éçšç©ºçœåéïŒæšé»ç¬Šèæè¢«èŠçºç©ºçœèè¢«å¿œç¥ïŒæä»¥äžå¯å°æå°æ¢ä»¶èš­çºæšé»ç¬Šèã
+
+<p>æ¥è©¢çç¯äŸ<p>
+   <ul><kbd> Agro-forestry in the Pacific Islands. Systems for Sustainability(1993)</kbd></ul>
+     <p>åä»¥äžèŠçºçžå<p>
+     <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>}  
+
+_texthelpmgppsearching_ [l=zh-tr] {ç± MGPP å»ºæçå
+žèè³æåº«ïŒå¯æäŸå
+¶ä»éžæã
+<ul>
+<li><b>*</b>æŸåšæ¥è©¢è©åœçæ«ç«¯ïŒåå¯é
+å°ææä»¥éå­å¥çºéŠçå­å¥ãäŸåŠïŒ<b>comput*</b>å¯ä»¥é
+å°ææä»¥ <b>comput</b> çºéŠçå­å¥ã.
+<li><b>/x</b>å¯çµŠäºæ¥è©¢è©åœäžåæå€æŒäžåçæŽé«åéãäŸåŠïŒç¶æåæä»¶æïŒ<b>computer/10 science</b>åè¡šç€ºçµŠäº computer 10 åå€æŒ science çåéã
+</ul>}  
+
+_texthelplucenesearching_ [l=zh-tr] {ç± Lucene å»ºæçå
+žèè³æåº«ïŒå¯æäŸå
+¶ä»éžæã
+<ul>
+<li><b>?</b>å¯çšäœçºè¬çšå­å
+ (wildcard)ïŒä»¥åä»£åå¥çå­æ¯ã äŸåŠïŒ<b>b?t</b>å¯é
+å°æ<b>bet</b>ã<b>bit</b>æ<b>bat</b>ç­ç­ã
+<li><b>*</b>å¯çšäœçºè¬çšå­å
+ (wildcard)ïŒä»¥åä»£å€æŒäžåçå­æ¯ãäŸåŠïŒ<b>comput*</b>å¯é
+å°æææä»¥<b>comput</b>çºå§çè±æå­æ¯ã
+</ul>
+ææçè¬çšå­å
+ (wildcard) éœå¯æŸåšè©åœçäž­å€®ææ«ç«¯ïŒäœå»äžå¯æŸåšæå°è©åœçéå§ã}  
+
+_texthelpquerytypetitle_ [l=zh-tr] {æ¥è©¢é¡å}
+_texthelpquerytype_ [l=zh-tr] {<p>å
+©çš®äžåé¡åçæ¥è©¢èªæ³ã
+
+<ul>
+ <li>æ¥è©¢<b>èæ¥è©¢èªæ³é 
+ç®å®å
+š</b>çžåïŒæ¥è©¢å°çæä»¶(ç« ç¯æè
+æšé¡)å
+å«æšå·²ç¶æå®çå
+šéšééµè©å°äŸå­æ¯æåºèååºäŸ ã<p>
+<p>
+
+<li>æ¥è©¢<b>èæ¥è©¢èªæ³é 
+ç®éšå</b> çžåïŒå°æ¥è©¢å°çæä»¶ååºïŒäžŠäŸç
+§èæ¥è©¢é 
+ç®ççžäŒŒåºŠäŸæåºã
+
+     <p><ul>
+       <li>æ¥è©¢é 
+ç®æå€ïŒæåŸå°çæå°çµææè¶æ¥è¿æèŠç;
+       <li>çšçšç¹çæ¥è©¢é 
+ç®æèŒäžè¬çæ¥è©¢é 
+ç®æå°èŒäœ³;
+       <li>èŒç­çæ¥è©¢é 
+ç®ææ¯èŒé·çæ¥è©¢é 
+ç®æŽææŒç¬Šåæä»¶å
+§å®¹ã
+     </ul>
+</ul>
+
+<p>äœ¿çšå€äžé»æ¥è©¢é 
+ç®ïŒåæ¯æŽæ®µå¥å­ææç« ïŒåŠææšåªäœ¿çšäžåæ¥è©¢é 
+ç®ïŒæå°ççµæå°äŸæ¥è©¢é 
+ç®åšæä»¶äž­åºçŸçé »çäŸæåºã<p>}  
+
+_texthelpadvancedsearchtitle_ [l=zh-tr] {äœ¿çš _1_ æå°åšïŒä»¥äœé²éæå°}  
+
+_texthelpadvancedsearch_ [l=zh-tr] {<p>åè¥æšå·²éžæé²éæ¥è©¢åèœï¹åšæçææäž­ï¹ïŒæšåææäžåçæå°éžæã}  
+
+_texthelpadvsearchmg_ [l=zh-tr] {MG å
+žèè³æåº«çé²éæå°ïŒåå¥çºæšæäŸå
+©é 
+éžæïŒéçŽæ§åéèŒ¯æ§ã
+<b>éçŽæ§</b>æå°æ¯çžç­æŒ<a href="\#query-type">_texthelpquerytypetitle_</a>æåœ¢å®¹ç<b>éšä»œ</b>æå°ã
+<p>_texthelpbooleansearch_}  
+
+_texthelpbooleansearch_ [l=zh-tr] {<b>éèŒ¯æ§</b>æå°è®æšäœ¿çšäžåçéèŒ¯æ§éç®å­äŸçµåå­å¥ïŒäŸåŠïŒ& ï¹ä»£è¡šãåãï¹ã|ï¹ä»£è¡šãæãï¹ã èå !ï¹ä»£è¡šãåŠãï¹ã
+<p>
+èäŸäŸèªªïŒ<b>snail & farming</b>æå°ææå«æ<b>snail</b>å<b>farming</b>çæä»¶çžé
+äžèµ·ïŒè<b>snail | farming</b>åå°å«æ<b>snail</b>æ<b>farming</b>çæä»¶çžé
+äžèµ·ãè³æŒ<b>sanil ! farming</b>åå°å«æ<b>snail</b>ïŒäœäžå
+æ¬<b>farming</b>çæä»¶çžé
+äžèµ·ã
+<p>
+é©ç¶å°éçšéç®å­äŸçµåæå°æ¥è©¢ïŒå¯åŸåºæŽæºç¢ºççµæãäŸåŠïŒ<b>(sheep | cattle) & (farm | station)</b>ïŒæ<b>sheep | cattle | goat !pig</b>.}  
+
+_texthelpadvsearchmgpp_ [l=zh-tr] {MGPP å
+žèè³æåº«çé²éæå°æ¯äœ¿çšéèŒ¯éç®å­ (operator) çã_texthelpbooleansearch_
+<p>æ­£åŠ<a href="\#query-type">_texthelpquerytypetitle_</a>æåœ¢å®¹ç<b>éšä»œ</b>æå°ïŒçµæéœä»¥<b>éçŽæ§</b>æãèªç¶ãï¹ãå»ºç«ãï¹çæ¬¡åºäŸé¡¯ç€ºãåŸè
+(ãèªç¶ãæãå»ºç«ãæ¬¡åºï¹æ¯ææä»¶æŒè£œäœå
+žèè³æåº«ææå»ºæçæ¬¡åºã
+<p>
+é²äžæ­¥çéç®å­å
+æ¬<b>NEARx</b>å<b>WITHINx</b>ãNEARx æ¯çšäŸæåºæé·çè·é¢ï¹x å­å¥ï¹ïŒéè·é¢å¯ä»¥åéæä»¶å
+§çå
+©çµæ¥è©¢ã
+WITHINx æåºç¬¬äºçµ<i>ç·æ¥è</i>ç¬¬äžçµåºçŸç x å­å¥ïŒæ
+æ³é¡äŒŒ NEARïŒäœæ¬¡åºçžå°å°èŒçºéèŠãé èš­çè·é¢çº 20ã}  
+
+_texthelpadvancedsearchextra_ [l=zh-tr] {æ³šæïŒåè¥æšéžæç°¡ææ¥è©¢åèœïŒéäºéç®å­ (operators) å°æå
+šéšè¢«å¿œç¥ã}  
+
+_texthelpadvsearchlucene_ [l=zh-tr] {Lucene å
+žèè³æåº«çé²éæå°äœ¿çšéèŒ¯éç®å­ã _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=zh-tr] {æ¬äœæå°}  
+
+_texthelpformsearch_ [l=zh-tr] {<p>æ¬äœæå°è®æšå¯ä»¥åäœµæ¬äœïŒä»¥äœæå°ãäŸåŠïŒæšå¯ä»¥åææå°é¡ç® "Smith" åäž»é¡ "snail farming"ãåšç°¡ææ¥è©¢åèœè£ïŒè¡šæ Œå
+§çæ¯äžè¡åŠæ­£åžžçå®è¡æå°ãè¡šæ Œå
+§çåå¥è¡æ¯ç± ANDï¹ä»¥äŸææçæå°ï¹æ OR ï¹ä»¥äŸéšä»œçæå°ï¹çµæïŒèæ¬äœå
+§çè©åœäºŠä»¥éæ¹æ³çµæãåšé²éæ¥è©¢åèœè£ïŒæäžæž
+å®äŸ¿å¯ä»¥æåºæ¬äœéäžåç AND/OR/NOT çµåïŒèåšæ¬äœå
+§ïŒæšåå¯äŸ¿çšéèŒ¯æ§éç®å­ã}  
+
+_texthelpformstemming_ [l=zh-tr] {è³æå€Ÿ (Fold) åçµå°Ÿ (stem) å­ç®±è®æšæåºæ¬äœå
+§çè©åœæ¯ casefoldïŒéæ¯ stemãäžè« casefold æ stemïŒååšé²éæå°å
+§èš­å®çºééã}  
+
+_textdatesearch_ [l=zh-tr] {æ¥è©¢æå¯ä»¥åŠå€åå äžæéæ¢ä»¶}  
+
+_texthelpdatesearch_ [l=zh-tr] {äŸæ¥ææå°å¯ä»¥æŸåºç¬Šåæäžæéæ¢ä»¶çæä»¶ïŒå¯ä»¥åªèŒžå
+¥æéäŸæå°ïŒæéå¯ä»¥æ¯æç¢ºçæéé»ææ¯äžæ®µåéçæéã<p>
+}
+
+_texthelpdatehowtotitle_ [l=zh-tr] {åŠäœäœ¿çš:}
+_texthelpdatehowto_ [l=zh-tr] {<ul>
+  <li>çšæç¢ºçæéæ¢ä»¶æå°:<p>
+  <ul>
+      <li>èŒžå
+¥æ¢ä»¶ã
+      <li>åš "éå§æé" æ¬èŒžå
+¥æéã
+      <li>åŠæäœ èŒžå
+¥çæéæ¯è¥¿å
+åååšéžå®äž­éžæ"B.C.E"éžé 
+ã
+      <li>éå§äŸæ¢ä»¶æå°ã
+  </ul>
+<p><li>å°æŸäžåæç¢ºæéæäžæ®µæéçè³æ:<p>
+  <ul>
+      <li>èŒžå
+¥æ¢ä»¶ã
+      <li>åš"éå§(å¯äž)æé"æ¬äœäž­èŒžå
+¥éå§æéã
+      <li>åš"çµææé"æ¬äœäž­èŒžå
+¥çµææéã
+      <li>åŠæäœ èŒžå
+¥çæéæ¯è¥¿å
+åååšéžå®äž­éžæ"B.C.E"éžé 
+ã
+      <li>éå§äŸæ¢ä»¶æå°ã   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=zh-tr] {æå°çµæçæ¹æ³ã}  
+_texthelpdateresults_ [l=zh-tr] {åŠææå°1903å¹Žçæä»¶äžŠéæå°1903å¹Žå¯«çæä»¶èæ¯æå°è1903æéçæä»¶ïŒåŠæç¡æ³æå°å°æç¢ºæ¥æççžéæä»¶ïŒæèš±å¯ä»¥çšåéæå°ïŒäŸåŠ:1903å°±ä»æŒ20è21äžçŽçåéå
+§ã<p>
+}
+
+_textchangeprefs_ [l=zh-tr] {æŽæ¹åäººåå¥œ}
+
+_texthelppreferences_ [l=zh-tr] {<p>ç¶æšæäžäžåšé é¢æäžæ¹ç<i>åäººåå¥œ</i> æéïŒæšäŸ¿å¯ä»¥å æåäººåå¥œèäœåºç¹å®çæ¹è®ã}  
+
+_texthelpcollectionprefstitle_ [l=zh-tr] {è³æåº«åäººåå¥œèš­å®}
+_texthelpcollectionprefs_ [l=zh-tr] {äžäºå
+žèè³æåº«å
+æ¬äžäºå­éåïŒè®çšæ¶å¯äœåå¥æå°ææ¯äžèµ·æå°ãå æ­€ïŒæšå¯ä»¥åšåå¥œçæå°é é¢äž­éžææå°å­éåéžé 
+ã
+}  
+
+_texthelplanguageprefstitle_ [l=zh-tr] {èªèšåå¥œ}
+_texthelplanguageprefs_ [l=zh-tr] {æ¯åå
+žèè³æåº«éœæé èš­çèªèšïŒäœæ¯æšå¯ä»¥æ¹æåå¥œçèªèšãæšäºŠå¯ä»¥æ¹è® Greenstone çºèŒžåºè³çèŠœåšææ¡çšçé èš­çç·šç¢Œç³»çµ±é
+çœ®ïŒäœæ¯æäºçèŠœåšæå æ¡çšäžåçç·šç¢Œç³»çµ±é
+çœ®èç²åŸæŽå¥œçèŠèŠºææïŒæçšçæ¶èå
+èš±æšåŸæšæºçååœ¢ä»é¢èœå°æå­ä»é¢ïŒéé»å°æŒæèŠèŠºéç€èäœ¿çšå€§åå­é«æèªèšè­å¥åšççšæ¶ç¹å¥æçšã}  
+
+_texthelppresentationprefstitle_ [l=zh-tr] {æå°åå¥œèš­å®}
+_texthelppresentationprefs_ [l=zh-tr] {æ ¹æäžåå
+žèè³æåº«çæå°ïŒæšå¯ä»¥èš­å®äžåçæå°åå¥œã
+ïŒp>ç¶²é å
+žèè³æåº«å
+èš±åšæ¯åé éŠäžé¡¯ç€º Greenstone çå°èªåïŒéæš£æšå¯ä»¥çŽæ¥çèŠœæéåçç¶²é ïŒäžŠäžæé¡¯ç€ºä»»äœ Greenstone çé éŠãæšäºŠå¯ä»¥çšçèŠœåšç"åå°äžäžé "æéé²è¡åŠå€çæ¥è©¢ãç¶æšæäžæåè¶
+é£çµèé¢éæžç¢Œåæžé€šçæåïŒéäºè³æåº«éå¯å
+èš±æšäžé¡¯ç€º Greenstone çè­Šåèšæ¯ãåšäžäºç¶²é çå
+žèè³æåº«äž­ïŒæšå¯ä»¥æ§å¶"æ¥è©¢çµæ"é æ¯åŠçŽæ¥é£æ¥å°å¯ŠéçURLïŒéæ¯æžç¢Œåæžé€šçåä»œã}  
+
+_texthelpsearchprefstitle_ [l=zh-tr] {æå°çåå¥œ}
+_texthelpsearchprefs_ [l=zh-tr] {<p>æšå¯ä»¥äœ¿æ¹çšé²éæ¥è©¢æš¡åŒïŒä»¥å
+èš±æšäœ¿çš AND (&)ãOR (|) å NOT (!) äŸçµåè©åœæçèªäœæå°ïŒä»¥åŸåºæŽç²Ÿç¢ºçæ¥è©¢ã
+<p>_selectsearchtypeprefs_
+<p>_selectwordmodificationprefs_
+
+<p>æšäºŠå¯ä»¥éåæ¥è©¢æ­·å²åèœïŒä»¥é¡¯ç€ºæè¿æ¥è©¢éçäžäºçŽéïŒéäºŠæ¹äŸ¿æšæ¹è®å
+åçæ¥è©¢æ¢ä»¶ã
+<p>æåŸïŒæšä¹å¯ä»¥æ¹è®ååºç¬Šåè³æçæžç®ïŒèåæ¯é ååºçæžç®ã}  
+
+_textcasefoldprefs_ [l=zh-tr] {ç¶é²è¡æå°æïŒäžå°æéææ§èå­æ¯çå€§å¯«æå°å¯«ãèäŸäŸèªªïŒè¥æšéžæ "_preferences:textignorecase_"ïŒ<i>snail farming</i>å°æè¢«èŠçºç­åæŒ<i>Snail Farming</i>å<i>SNAIL FARMING</i>ã}  
+_textstemprefs_ [l=zh-tr] {åšæå°æïŒäžå°æéææ±ºå®æ¯åŠå¿œç¥å­å¥çå°ŸéšãäŸåŠïŒè¥å·²éžæ _preferences:textstem_ïŒ<i>snail farming</i> éœæçäœçº <i>snails farm</i>å<i>snail farmer</i>ãäœæ¯ïŒéæ
+æ³åªé©çšæŒè±æçæç«  _selectstemoptionsprefs_ã}  
+_textaccentfoldprefs_ [l=zh-tr] {ç¶é²è¡æå°æïŒäžå°æéææ§èè¿äŒŒçå­æ¯çŒé³ãèäŸäŸèªªïŒè¥æšéžæ "_preferences:textignoreaccents_"ïŒ<i>fÃ©dÃ©ration</i>å°æè¢«èŠçºç­åæŒ<i>fedÃ©ration</i>å<i>federation</i>ã}  
+ 
+_textstemoptionsprefs_ [l=zh-tr] {å©çšäžè¿°æåçæå°è©åœ truncation åèœ "_texthelpquerytermstitle_"ïŒæèŒçºæ¹äŸ¿ææºç¢ºã}  
+
+_textsearchtypeprefsplain_ [l=zh-tr] {æšå¯ä»¥åŸå°èŒå€§çæ¥è©¢é 
+ç®ïŒè®æšå¯ä»¥å®¹æå°äœ¿çšæ®µèœå€§å°äŸé²è¡æå°ãæšæçŒçŸéæš£æå éæå°ç¹å€çæå­ã}  
+
+_textsearchtypeprefsform_ [l=zh-tr] {æšå¯ä»¥æ¹è®é¡¯ç€ºæŒæå°è¡šæ Œå
+§çæ¬äœæžç®ã}  
+
+_textsearchtypeprefsboth_ [l=zh-tr] {æšå¯ä»¥èœè®å
+žèè³æåº«çæå°åœ¢åŒïŒæ­£åžžåæ¬äœæå°ã 
+<ul>
+<li>æ­£åžžæå°æäŸå®äžçæ¥è©¢é 
+ç® _textsearchtypeprefsplain_</li>
+<li>æ¬äœæå°æäŸæžåæ¥è©¢é 
+ç®ïŒä»¥æ¥è©¢äžåæ¬äœççŽ¢åŒïŒéäºŠé©
+äœ¿æå°å¯åæéæŽå€§æå°è³äžåçæ¬äœã_textsearchtypeprefsform_ </li>
+</ul>}  
+
+
+
+_texttanumbrowseoptions_ [l=zh-tr] {çš _numbrowseoptions_ çš®æ¹åŒäŸæå°è³æåº«äž­çæä»¶è³æ:}
+
+_textsimplehelpheading_ [l=zh-tr] {åŠäœåš_collectionname_è³æåº«äž­æŸè³æ}
+
+_texthelpscopetitle_ [l=zh-tr] {æ¥è©¢çç¯å}
+_texthelpscope_ [l=zh-tr] {<p>
+åšå€§å€æžçå
+žèè³æåº«äž­ïŒæšå¯ä»¥çšäžåçæå°çŽ¢åŒäŸæå°ãäŸåŠïŒäœ¿çšäœè
+ææšé¡çŽ¢åŒäŸæå°ïŒæä»¥ç« ç¯ææ®µèœçŽ¢åŒäŸæå°ãäžè¬äŸèªªïŒäœ¿çšèŒçšç¹çæ¥è©¢çŽ¢åŒïŒæææŸå°å®å
+šçžç¬Šçæä»¶ã
+<p>åŠææä»¶æ¯äžæ¬æžïŒåæå°æžæ¬éåšåé©çé æžã}  
Index: /gsdl/stable/macros/chinese-trad2.dm
===================================================================
--- /gsdl/stable/macros/chinese-trad2.dm	(revision 20131)
+++ /gsdl/stable/macros/chinese-trad2.dm	(revision 20131)
@@ -0,0 +1,1339 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Traditional Chinese Language text and icon macros  
+# -- this file contains text that is of less importance
+# -- to translate when creating a new interface language
+# 
+# Many thanks to Lilly Ho (updated February 2009)
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=zh-tr] {æä»¶ã}
+_lastupdate_ [l=zh-tr] {æåŸæŽæ°}
+_ago_ [l=zh-tr] {å€©åã}
+_colnotbuilt_ [l=zh-tr] {æ¬²å»ºç«çè³æåº«ã}
+
+### taken from here
+
+_textpoem_ [l=zh-tr] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,  
+<br>kia tere te karohirohi, 
+<br>kia papapounamu te moana 
+
+<p>may peace and calmness surround you,  
+<br>may you reside in the warmth of a summer's haze,  
+<br>may the ocean of your travels be as smooth as the polished greenstone. 
+}
+
+_textgreenstone_ [l=zh-tr] {<p>Greenstone æ¯äžçš®ç¢æŒçŽè¥¿è­çç¶ å¯¶ç³ï¹åŠéå¥è»ä»¶çåçš±ï¹ãåšå³çµ±çæ¯å©äººç€Ÿæè£ïŒGreenstone æ¯ææç©è³ªçç²Ÿé«ïŒäºŠæ¯æçè²ŽåçœæçãGreenstone æ¢å¯ä»¥åžæ¶åææéæ°£/çåœå<i>wairua</i>ïŒèäžè³Šæå³çµ±çŸåŸ·çç¹æ§ãå æ­€ïŒGreenstone æ¯å
+¬å
+±é åæžç¢Œåæžé€šèšå (public-domain digital library project) çè±¡åŸœãGreenstone çå
+åœ©ä»£è¡šæ
+æïŒå®çééä»£è¡šèª å¯ŠïŒå®çå 
+ç¡¬ä»£è¡šåæ°£ïŒèå®æèœæ¿åçå©åä»£è¡šæ­£çŸ©ãGreenstone æžç¢Œåæžé€šè»ä»¶çæšèªæ¯äžåéå» <i>patu</i> ï¹ææææ£ï¹ïŒäºŠæ¯éåæžç¢Œåæžé€šèšåäž­ææå¡çå³å®¶ä¹å¯¶ãåšåŸææ°åœ¹äž­ïŒGreenstone çå³éè¡šçŸæ¯å¿«éãæºç¢ºåå®æŽçãæååžæéå¥è»ä»¶ææå³çµ± Greenstone çç¹æ§ïŒèéå©ç<i>patu</i>åè±¡åŸµéå¥è»ä»¶èµ°åç§æçåç«¯ã</p>
+}  
+
+_textaboutgreenstone_ [l=zh-tr] {<p> Greenstoneæ¯å»ºç«åå³äœæžäœåæžé€šå
+žèçè»é«çšåŒïŒå®
+æäŸäºäžåæŽç·šè³èšäžçŒè¡šæŒç¶²è·¯æCD-ROMçæ°æ¹æ³ãGreenstoneæ¯<b>Waikato
+å€§å­ž</b>è<b>çŽè¥¿è­æžäœåæžé€šèšç«å°çµ</b>å»ºæ§ïŒåæå<b>UNESCO</b>å<b>Human Info NGO</b>æåäœçŒå±åå³äœãå®æ¯open-sourceçè»é«ïŒåš<a herf="http://greenstone.org">http://greenstone.org</a> äžéµå
+¥æ¢ä»¶
+GNU General Public LicenseïŒ å³å¯ç²åŸäŸèªhttp://greenstone.org under the terms of 
+the GNUäžè¬æ§å
+¬éææ¬ã 
+
+
+<p>æ­€è»é«çç®çæ¯èŠè®äœ¿çšè
+ïŒå°€å
+¶æ¯åšå€§å­žã åæžé€šãåå
+¶ä»å
+¬å
+±æåæ©æ§è£¡
+çäœ¿çšè
+ïŒå»å»ºæ§å±¬æŒä»åèªå·±çæžäœåæžé€šïŒæžäœåæžé€šæ­£è¢«åŸ¹åºå°æ¹è¯åŠ
+äœè®äžçåå°å°€å
+¶æ¯éçŒäž­åå®¶åèUNESCOåäœçæç§æé åçç€Ÿåèæ©æ§
+æ£æ­åçŽ¢æ±è³èšïŒæååææ­€è»é«èœæ¿åµæžäœåæžé€šææçéçŒïŒä»¥åäº«è³èšäžŠ
+å°å
+¶æŸçœ®åšå
+¬å
+±ç¶²åã 
+
+
+<p>æ­€è»é«æ¯ç±ä»¥äžäžæ¹é¢æŒ2000å¹Ž8æåéå
+±ååäœéçŒç: 
+
+<table border="0">
+<tr valign="top">
+<td>
+<a href="http://nzdl.org"><b>New Zealand Digital Library Project at the University of Waikato</b></a>
+<br>
+<p> Greenstoneè»é«ç¶ç±æ­€èšç«èªç,äžŠç±unescoçŽè¥¿è­åå®¶å§å¡æç¶²è·¯å­å§å¡æèæžïŒåçºçŽè¥¿è­å°UNESCOèšåçè²¢ç»ã
+
+</td>
+<td></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://www.unesco.org"><b>United Nations Educational, Scientific and Cultural Organization</b></a>
+<br>
+å
+šçæç§æè³èšçå³æ­ïŒå°€å
+¶æ¯å°éçŒäž­åå®¶çå©çïŒ æ¯UNESCOåšå
+æ¿åºéè¿œæ±çäž­å¿ç®æšãèåšæ­€è­°é¡äž,é©åå¯åŸçå³æ­ç§æå·¥å
+·äºŠæ¯åç­
+éèŠã 
+</td>
+<td><a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+border="0"></a></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://humaninfo.org"><b>The Human Info NGO, based in Antwerp, Belgium</b></a>
+<br>
+æ­€èšååè¯ååæ©æ§åå
+¶ä»éæ¿åºçµç¹åäœïŒåšæžäœåäººé¡çŒå±è­°é¡æä»¶äž
+å»ºç«äºäžçè²è­œïŒäžäœå°å
+šäººé¡ççŠç¥çŒå±å ä»¥æžäœåèšéïŒè³æå¯å»£æ³
+å°ååŸïŒåæéçŒäž­åå®¶äžçšè±äžåé¢ïŒèå
+¶ä»çåå®¶ä¹ç¯çäºç¶è²»ã 
+</td>
+<td><a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" border="0"></a></td>
+</tr>
+</table>
+}
+
+
+_textdescrselcol_ [l=zh-tr] {éžæå
+žèè³æåº«}
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=zh-tr] {åšéŠé æååäžäžæ­¥æé}
+
+_textnocollections_ [l=zh-tr] {<p>ç®ååšGreenstoneå
+§ç¡ä»»äœå
+žèè³æåº«ïŒæ¬²å å
+¥å
+žèè³æåº«å¯çšäžåä»»äžæ¹æ³ïŒ 
+<ul><li>â¢	äœ¿çš<a href="_httppagecollector_">è³æåº«å
+žèä»é¢</a>äŸå»ºç«æ°çå
+žèã
+<li>â¢	åŠææšæGreenston cd-romïŒå¯åŸ cd-romäŸå®è£å
+žèã</ul> 
+}
+
+_text1coll_ [l=zh-tr] {Greenstonå®è£å
+å«äžé 
+å
+žè}
+
+_textmorecolls_ [l=zh-tr] {Greenstonå®è£å
+å«äžé 
+å
+žè}
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=zh-tr] {å€éšé£çµ}
+_textlinknotfound_ [l=zh-tr] {æªçŒçŸå
+§éšé£çµ}  
+
+_textextlinkcontent_ [l=zh-tr] {äœ æéžæçåçºç®åæéžå
+žèè³æåº«çå€éšé£çµã
+åŠæäœ ä»ç¶åžæé¡¯ç€ºæ­€é£çµèäžäœ ççèŠœåšä»¥é²å
+¥æ­€ç¶²
+ç«ïŒäœ å¯ä»¥âåé²âå°æ­€é é¢ ïŒ 
+åŠåäœ¿çšçèŠœåšç<a href="_nexturl_">âåäžé â</a>éµïŒåå°å
+åçé é¢
+}
+
+_textlinknotfoundcontent_ [l=zh-tr] {ç±æŒè¶
+éå¯æ§å¶ç¯åä¹æ
+ïŒäœ æéžæçå
+§éšé£çµäžŠäž
+å­åšïŒéå¯èœæ¯ç±æŒäŸæºæä»¶çé¯èª€ïŒäœ å¯äœ¿çšçèŠœåšçâåäžé âéµïŒåå°å
+
+åçé é¢ã}
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=zh-tr] {<h3> é£çµè³ "_2_" å
+žèè³æåº« </h3>
+
+<p> æšæéžæçé£çµçº "_collectionname_" å
+žèè³æåº«çå€éšé£çµ (é£çµè³ "_2_" å
+žèè³æåº«)ãåŠæ
+Ÿæª¢èŠæŒ "_2_" å
+žèè³æåº«å
+§çé£çµïŒæšå¯ä»¥æäžäž<a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_"> éè£çé£çµ</a>ïŒä»¥ååŸè©²é ïŒæè
+ïŒæäžäžçèŠœåšçãåå°äžäžé ãéµïŒä»¥åå°åäžé ã}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=zh-tr] {Greenstone æžäœåæžé€š}
+
+_textusername_ [l=zh-tr] {äœ¿çšè
+åçš±}
+_textpassword_ [l=zh-tr] {å¯ç¢Œ}
+
+_textmustbelongtogroup_ [l=zh-tr] {æ³šæïŒäœ å¿
+é å±¬æŒ "_cgiargug_" éåçŸ€çµæèœçå°æ­€é }
+
+_textmessageinvalid_ [l=zh-tr] {äœ æè«æ±é²å
+¥çé é¢éèŠç»å
+¥ïŒ<br>
+_If_(_cgiargug_,[è«æ³šæäœ å¿
+é å±¬æŒ "_cgiargug_" çŸ€çµæèœé²å
+¥æ­€ç¶²é ] <br>)
+è«èŒžå
+¥äœ ç Greenstone äœ¿çšè
+åçš±åå¯ç¢ŒïŒ}
+
+_textmessagefailed_ [l=zh-tr] {äœ¿çšè
+åçš±æå¯ç¢Œé¯èª€ïŒ}
+
+_textmessagedisabled_ [l=zh-tr] {æ±æ­ïŒäœ çåž³èç¡æïŒè«èæ¬ç«çç¶²ç«ç®¡çå¡é£çµ¡ã}
+
+_textmessagepermissiondenied_ [l=zh-tr] {æ±æ­ïŒäœ æ²ææ¬éé²å
+¥æ­€ç¶²é ïŒ}
+
+_textmessagestalekey_ [l=zh-tr] {é£çµå€±æïŒè«èŒžå
+¥äœ çå¯ç¢Œä»¥é²å
+¥æ­€ç¶²é }
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=zh-tr] {<p>Greenstoneå®è£æ²æå
+å«ä»»äœæä»¶ä¹å¯èœåå çºïŒ 
+<ol>
+<li>1.	äœ¿çšGreenstone CD-ROM çç°¡æå®è£ã
+<li>2.	åŸinternetäœ¿çšGreenstone äžèŒå®è£ã
+</ol>
+ä»¥äžå
+©çš®æ¹åŒå¯ä»¥ç²åŸæä»¶ïŒåŸ Greenstone CD-ROMç<i>docs</i>ç®éæå° 
+ <a href="http://www.greenstone.org">http://www.greenstone.org</a>
+}
+
+_textuserguide_ [l=zh-tr] {äœ¿çšè
+æå}
+_textinstallerguide_ [l=zh-tr] {å®è£è
+æå}
+_textdeveloperguide_ [l=zh-tr] {éçŒè
+æå}
+_textpaperguide_ [l=zh-tr] {åŸçŽæ¬å°å
+žè}
+_textorganizerguide_ [l=zh-tr] {äœ¿çšOrganizer}
+
+_textgsdocstitle_ [l=zh-tr] {Greenstone ç³»çµ±æä»¶ã}
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=zh-tr] {å»ºç«å
+žèè³æåº«}  
+_textbildsuc_ [l=zh-tr] {å
+žèè³æåº«å·²æåå°å»ºç«ã}  
+_textviewbildsummary_ [l=zh-tr] {æééåå
+žèè³æåº«çé²äžæ­¥è³æïŒæšå¯ä»¥äœ¿çš<a href="_httppagex_(bsummary)" target=_top>éåé£çµ</a>ïŒä»¥æª¢èŠå·²å»ºç«çå
+žèè³æåº«ä¹éçšçŽéã}  
+_textview_ [l=zh-tr] {æª¢èŠå
+žèè³æåº«}  
+
+_textbild1_ [l=zh-tr] {å
+žèè³æåº«æ­£åšå»ºç«äž­ïŒéæé²è¡ãå·è¡çæ
+é¡¯ç€ºæŒäžæ¹ã}  
+
+_textbild2_ [l=zh-tr] {æäžäžéè£ïŒä»¥çµæ­¢å»ºç«éçšã
+<br>å·¥äœäž­çå
+žèè³æåº«å°äžååœ±é¿ã}  
+
+_textstopbuild_ [l=zh-tr] {çµæ­¢å»ºç«éçš}  
+
+_textbild3_ [l=zh-tr] {åŠèŠé¢ééé  (äžŠæªæéµçµæ­¢å»ºç«éçš)ïŒå
+žèè³æåº«å°æç¹Œçºé²è¡å»ºç«åå®è£éçšïŒçŽè³æŽåçšåºå®æçºæ­¢ã}  
+
+_textbuildcancelled_ [l=zh-tr] {å»ºç«éçšå·²è¢«åæ¶}  
+
+_textbildcancel1_ [l=zh-tr] {å
+žèè³æåº«å»ºç«éçšå·²è¢«åæ¶ãæäžäžä»¥äžçé»è²éµïŒä»¥æŽæ¹å
+žèè³æåº«æéæ°ååå»ºç«éçšã}  
+
+_textbsupdate1_ [l=zh-tr] {å»ºç«çæ
+å°æŒ 1 ç§å
+§æŽæ°}  
+_textbsupdate2_ [l=zh-tr] {å»ºç«çæ
+æŽæ°æ¥æçº}  
+_textseconds_ [l=zh-tr] {ç§}  
+
+_textfailmsg11_ [l=zh-tr] {ç±æŒå
+žèè³æåº«äžŠæªå²å­è³æïŒå
+žèè³æåº«å æ­€äžèœå»ºç«ãè«ç¢ºå®è³å°æäžåç®éææªæ¡æ¯åºçŸæŒ<i>åå§æžæ</i>çç¶²é äžïŒèåææ¯ Greenstone èœå€ å·è¡çäžçš®æªæ¡ã }  
+
+_textfailmsg21_ [l=zh-tr] {å
+žèè³æåº«äžèœå»ºç« (æ»å
+¥ import.pl å€±æ)ã}  
+_textfailmsg31_ [l=zh-tr] {å
+žèè³æåº«äžèœå»ºç« (å»ºç« buildcol.pl å€±æ).}  
+_textfailmsg41_ [l=zh-tr] {å
+žèè³æåº«ç¶å·²æåå»ºç«ïŒäœäžèœå®è£ã}  
+_textfailmsg71_ [l=zh-tr] {åè©Šå»ºç«å
+žèè³æåº«çæåïŒé¯èª€åºçŸã}  
+
+
+_textblcont_ [l=zh-tr] {å»ºç«æ¥èªå
+æ¬ä»¥äžçè³èšïŒ}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=zh-tr] {é èš­æ¶æ§}
+_textmore_ [l=zh-tr] {æŽå€}
+_textinfo_ [l=zh-tr] {å
+žèè³æåº«è³èš}
+_textsrce_ [l=zh-tr] {äŸæºæä»¶è³æ}
+_textconf_ [l=zh-tr] {èš­å®å
+žèè³æåº«}
+_textdel_ [l=zh-tr] {åªé€å
+žèè³æåº«}  
+_textexpt_ [l=zh-tr] {å¯åºå
+žèè³æåº«}
+
+_textdownloadingfiles_ [l=zh-tr] {äžèŒæªæ¡âŠ}
+_textimportingcollection_ [l=zh-tr] {å¯å
+¥å
+žèè³æåº«âŠ}
+_textbuildingcollection_ [l=zh-tr] {å»ºç«å
+žèè³æåº«âŠ}
+_textcreatingcollection_ [l=zh-tr] {å»ºç«å
+žèè³æåº«âŠ}
+
+_textcollectorblurb_ [l=zh-tr] {<i>ç­éæŒåïŒ
+<br>å»ºç«åå³éæä»¶å
+žèéåž¶èäœ å¿
+é åšäžéå§åå³é æ·±æçè²¬ä»»ïŒå­åšæŒè€è£œç
+æ³åŸåé¡: å¯ä»¥åçšæä»¶äžŠäžè¡šç€ºäœ äžå®å¯ä»¥å³éçµŠä»äººïŒå­åšæŒç€Ÿæäžçç­è­°: 
+ææçæä»¶å¿
+é å°éå®äŸæºèçå°æ¹é¢šä¿ïŒåæä¹å­åšéåŸ·çåé¡ : æäºäºäžæ
+èŒæå°è®å¥äººå¯ä»¥å©çšïŒ
+<br>å°è³èšçåœ±é¿åå¿
+é æé³ïŒåæææºæ
+§å°äœ¿çšå®ã
+</i>
+}
+
+_textcb1_ [l=zh-tr] {è³æåº«å
+žèä»é¢å¯åå©äœ å»ºç«æ°çå
+žèè³æåº«ïŒæŽæ°åå¢å çŸå­çå
+žèè³æåº«ïŒæåªé€å
+žèè³æåº«ïŒèŠåå°åè¿°çåèœïŒå¯äŸåŸªç¶²é è³èšçæåŒã
+}
+
+_textcb2_ [l=zh-tr] {éŠå
+, äœ å¿
+é æ±ºå®æ¯åŠ}
+_textcnc_ [l=zh-tr] {å»ºç«æ°çå
+žèè³æåº«}
+_textwec_ [l=zh-tr] {æŒå·²å­åšçå
+žèè³æåº«äž­æ°å¢æåªé€è³æ}
+
+_textcb3_ [l=zh-tr] {äœ å¿
+é ç°œçœ²ä»¥äŸ¿å»ºç«
+ææŽæ°æžäœåæžé€šå
+žèïŒæ­€èå¯ä»¥ä¿è­·äœ äŸèªå
+¶å®å°æ¹ç»å
+¥äœ çé»è
+ŠäžŠæ¹è®è³
+èšçè¡çºãæ³šæïŒåºæŒå®å
+šçç±ïŒæ¯30åéæééåŸïŒäœ å°è¢«èªåç»åºïŒåŠæ
+çŒçæ­€çæ³ïŒå¥æå¿ïŒ è«åç»å
+¥ïŒåæå¯ä»¥åŸå
+åé¢éä¹èç¹Œçºå·è¡ã
+}
+
+_textcb4_ [l=zh-tr] {è«èŒžå
+¥äœ åšGreenston çäœ¿çšè
+åçš±åå¯ç¢ŒäžŠé»éžæéµäœ¿ç»å
+¥ã}
+
+_textfsc_ [l=zh-tr] {éŠå
+éžæå·è¡å
+åéžéçå
+žèè³æåº« (é²æ­¢å¯«å
+¥çå
+žèè³æåº«äžæé¡¯ç€ºåšæ­€ç®éäž) }
+
+_textwtc_ [l=zh-tr] {æŒäœ å·²éžæçå
+žèè³æåº«äž­ïŒäœ å¯ä»¥
+}
+_textamd_ [l=zh-tr] {å¢å æŽå€æä»¶åéå»ºå
+žèè³æåº«}
+_textetc_ [l=zh-tr] {ç·šèŒ¯å
+žèè³æåº«çµæ§æªæ¡äžŠéå»ºè³æåº«}
+_textdtc_ [l=zh-tr] {å®å
+šåªé€å
+žèè³æåº«}
+_textetcfcd_ [l=zh-tr] {å¯åºå
+žèè³æåº«ïŒå¯«å
+¥å°self-installing Windows CD-ROM}
+_textcaec_ [l=zh-tr] {æŽæ¹å·²å­åšçå
+žèè³æåº«}
+_textnwec_ [l=zh-tr] {æ²æå¯å¯«å
+¥çè³æåº«å
+žèå¯æ¿äŸä¿®æ¹}
+_textcianc_ [l=zh-tr] {å»ºç«æ°çå
+žèè³æåº«}
+_texttsosn_ [l=zh-tr] {å»ºç«æ°çæžäœåæžé€š
+å
+žèè³æåº«æéçæ­¥é©é åºïŒ}
+_textsin_ [l=zh-tr] {æå®åçš± (åçžéè³èš)}
+_textswts_ [l=zh-tr] {æå®äŸæºè³ææçä»¶è·¯åŸæç¶²å}
+_textatco_ [l=zh-tr] {èª¿æŽè³æåº«èš­å®æª (é²éäœ¿çšè
+)}
+_textbtc_ [l=zh-tr] {"å»ºç«"å
+žèè³æåº« (åŠ
+äž)}
+_textpvyh_ [l=zh-tr] {æª¢èŠææ}
+
+_texttfsiw_ [l=zh-tr] {ç¬¬ååæ­¥é©æ¯ééé»è
+Šå·è¡ææå·¥äœïŒåš "å»ºç«è³æåº«"çéçšäž­ïŒé»è
+Šå»ºç«æææä»¶ççŽ¢åŒäžŠæ¶éä»»äœå»ºç«ææéèŠçè³èšå°ãäœéŠå
+äœ å¿
+é æç¢ºæåºæä»¶è³èšã
+}
+
+_textadab_ [l=zh-tr] {åå»ºç«çéçšäž­äžæ¹çåç€ºååºçŸå°åå©äœ è¿œè¹€
+ç®åçæåšäœçœ®ïŒäœ å¿
+é é»éžç¶ è²çéµä»¥ç¹Œçº.ïŒå®ææïŒæ­€éµæè®æé»è²ïŒé»
+éžåç€ºäž­çžæçé»è²éµäœ å¯ä»¥åå°äžäžé ã
+}
+
+_textwyar_ [l=zh-tr] {ç¶æºåå®æåŸïŒé»éžâå
+žèè³æåº«è³èšâæéå¯ä»¥éå§å»ºç«äœ çæ°æžäœåæžé€šå
+žèè³æåº«! }
+
+_textcnmbs_ [l=zh-tr] {ç¢ºç«å
+žèè³æåº«åçš±}
+_texteambs_ [l=zh-tr] {ç¢ºç«é»å­éµä»¶å°å}
+_textpsea_ [l=zh-tr] {è«ç¢ºç«æ­€è¡šäž­é»å­éµä»¶å°åïŒäœ¿çšè
+åçš±@ç¶²å }
+_textdocmbs_ [l=zh-tr] {ç¢ºç«å
+žèè³æåº«çæè¿°}
+
+_textwcanc_ [l=zh-tr] {ç¶å»ºç«äžæ°çå
+žèè³æåº«äœ éèŠèŒžå
+¥äžäºæéäŸæºè³æçå
+æ±ºè³èšïŒæ­€æ­¥é©æ¯ç±äžç³»åç¶²é å»ºæ§æçïŒç±æ¶èè
+ç£çé é¢äžæ¹çæ©«åé¡¯ç€ºæéå®æé æžçé åºã
+}
+
+_texttfc_ [l=zh-tr] {å
+žèè³æåº«åçš±:}
+
+_texttctiasp_ [l=zh-tr] {å
+žèå
+žèè³æåº«åçš±æ¯äžç°¡ç­çèªïŒåšæžäœåæžé€šäž­çšäŸåèŸšå
+žèå
+§å®¹çïŒ
+äŸåŠâé»è
+Šæè¡å ±åâåâäººé¡çŒå±åæžé€šâ
+}
+
+_textcea_ [l=zh-tr] {é»å­éµä»¶è¯çµ¡å°åïŒ }
+
+_textteas_ [l=zh-tr] {æ­€é»å­éµä»¶å°åçºçç¬¬äžéè¯çµ¡çªå£ïŒè¥Greenstoneè»é«è¥åµæž¬å°
+åé¡ïŒèšºæ·å ±åæéå°æ­€å°åïŒèŒžå
+¥å®æŽçé»å­éµä»¶å°å:<tt>åçš±@ç¶²å</tt>. 
+}
+
+_textatc_ [l=zh-tr] {éæŒéåå
+žèè³æåº«:}
+
+_texttiasd_ [l=zh-tr] {çºæè¿°æ­€å
+žèè³æåº«çå®æšïŒç¶é²å
+¥å
+žèè³æåº«æïŒå®æ¯ç¬¬äžåè¢«é¡¯ç€ºåºäŸçç«é¢ã 
+}
+
+_textypits_ [l=zh-tr] {äžæ¹çç®­é ­è¡šç€ºäœ æåšçé åº--åšç®åçæ
+æ³äžæ¯âå
+žèè³æåº«è³èšâéæ®µïŒæç¶ è²çâäŸæºè³æâéµå³å¯ç¹Œçº.. 
+}
+
+_srcebadsources_ [l=zh-tr] {<p>äžåæå€åèŒžå
+¥ä¹äŸæºè³ææä»¶ç¡æ³è¢«åèå° (æšç€º _iconcross_ åŠäž) :
+
+<p>å¯èœé æçåå  
+<ul>
+<li>â¢	æªæ¡è·¯åŸ, FTPç«æç¶²åäžå­åšã
+<li>â¢	ç¢ºèªé»è
+Šç¶²è·¯éèšæ¯åŠæ­£åžžã
+<li>â¢	äœ èŠæ±åç
+§çç¶²è·¯æä»¶éééåž³èå¯ç¢Œæèœå€ å­åã
+</ul>
+
+<p>éç¶è©²ç¶²åäžçæä»¶å¯ä»¥åšäœ ççèŠœåšäžçå°ïŒäœå®æå¯èœåªæ¯äœ é»è
+Šå
+§çæ«å­æªïŒåŸäžå¹žçæ¬å°ç«¯æ«å­æªå°ç¡æ³åšè³æåº«å»ºç«çéçšäž­è¢«åç
+§å°ïŒåšéçš®æ
+æ³äžæåå»ºè­°å
+å°è©²æä»¶äžèŒå°æ¬å°ç«¯å²å­åŸïŒåé²è¡è³æåº«çå»ºç«ã
+}
+
+_textymbyco_ [l=zh-tr] {<p>äœ çå
+žèè³æåº«å¯ä»¥å»ºç«åšä»¥äžä»»äžçš®åºç€äž 
+<ul>
+<li>â¢	åå§æ¶æ§ 
+<dl><dd>æ°çå
+žèå¯å
+å« htmlæª (.htm, .html)ïŒçŽæå­æª (.txt, .text)ïŒMS Word æª 
+(.doc)ïŒ PDF æª (.pdf) æ "m-box" æ ŒåŒé»å­éµä»¶æª (.mbx)ã<dd><dl>
+<li>â¢	å·²å­åšçå
+žè 
+<dl><dd>åšæ°æ¶èå
+§çæªæ¡å¿
+é åçŸææ¶èäžæš¡äžæš£ã<dd><dl>
+</ul>
+}  
+
+_textbtco_ [l=zh-tr] {å
+žèè³æåº«åºç€}
+_textand_ [l=zh-tr] {å¢å æ°è³æ}
+_textad_ [l=zh-tr] {å¢å è³æïŒ}
+
+_texttftysb_ [l=zh-tr] {å¢å äžåæå®æªæ¡æŒå
+žèè³æåº«å
+§ïŒè«ç¢ºèªæªæ¡æªéèŠæå®ïŒåŠåå°æå
+©
+ä»œåæš£çæªæ¡ïŒè«äœ¿çšå®æŽçè·¯åŸåçš±äŸèŸšè­æªæ¡ïŒç¶²é èŠçšçšäžç¡äºçç¶²
+åã 
+}
+
+_textis_ [l=zh-tr] {èŒžå
+¥è³ææä»¶äŸæºïŒ}
+
+_textddd1_ [l=zh-tr] {<p>è¥äœ äœ¿çš file:// æ ftp:// äŸæå®äžåæªæ¡ïŒå³å¯äžèŒè©²æª.
+
+<p>è¥äœ äœ¿çš http://ååæ±ºæŒURLæ¯åŠåšäœ ççèŠœåšäžçµŠäœ äžåæ­£åžžçç¶²é ææªæ¡
+ç®éïŒè¥çºäžç¶²é ,åæäžèŒè©²ç¶²é âè¥å®(å)é£çµèš±å€ç¶²é åææç¶²é éœæè¢«äž
+èŒ.â å³URLäžåäžç¶²ç«å
+§çç¶²é éœæè¢«äžèŒã 
+
+<p>è¥äœ äœ¿çš file:// æftp:// äŸæå®äžæªæ¡å€Ÿæç®é,ææ¯http:// URLçµŠäºäœ æªæ¡ç®
+éïŒåæªæ¡å€Ÿåå®ä¹äžçå­æªæ¡å€Ÿéœæè¢«å
+å«åšå
+žèè³æåº«å
+§ã
+ 
+<p>é»éžâæŽå€è³ææä»¶äŸæºâéµå¯åŸå°æŽå€èŒžå
+¥æ¬äœã 
+}
+
+_textddd2_ [l=zh-tr] {<p>é»éžä»»äžç¶ éµïŒè¥äœ æ¯é²éäœ¿çšè
+äœ å¯ä»¥èª¿æŽå
+žèè³æåº«çµæ§æè
+çŽæ¥å°å»ºæ§éæ®µãèšåŸïŒåªèŠé»éžé»éµå°±å¯åå°åäžéæ®µã
+}
+
+_textconf1_ [l=zh-tr] {<p>å
+žèè³æåº«çå»ºæ§ååçŸéœæ¯ç±âçµæ§æªâæ§å¶ïŒé²éäœ¿çšè
+å¯æ¹è®å
+¶èš­å®ã 
+<center><p><b>è¥äœ äžæ¯é²éäœ¿çšè
+, è«çŽæ¥å°ç¶²é åºéš..</b></center> 
+<p>ä¿®æ¹äžåè³æå³å¯æŽæ¹çµæ§èš­å®ïŒè¥èŒžå
+¥é¯èª€åé»éžâååŸ©âéµåå°åèš­å®
+}
+
+_textreset_ [l=zh-tr] {åŸ©å}
+
+
+_texttryagain_ [l=zh-tr] {è«<a href="_httppagecollector_" target=_top>éæ°ååå
+žèè³æåº«ä»é¢</a>äžŠéè©Š
+}
+
+
+_textretcoll_ [l=zh-tr] {åå°å
+žèè³æåº«ä»é¢}
+
+_textdelperm_ [l=zh-tr] {éšåæå
+šéš _cgiargbc1dirname_ å
+žèè³æåº«ç¡æ³åªé€ïŒå¯èœåå çºïŒ
+<ul> 
+<li>â¢	Greenstone ç¡åªé€_gsdlhome_/collect/_cgiargbc1dirname_ ç®éçèš±å¯ã 
+äœ éèŠäººå·¥ç§»é€_cgiargbc1dirname_å
+žèè³æåº«ã</li>
+<li>â¢	Greenstone ç¡æ³å·è¡_gsdlhome_/bin/script/delcol.plçšåŒïŒè«ç¢ºå®æ­€æªæ¡å¯
+è®å¯«åå·è¡ã</li>
+</ul>
+}
+
+_textdelinv_ [l=zh-tr] {_cgiargbc1dirname_ å
+žèè³æåº«è¢«ä¿è­·æç¡æïŒåæ¶åªé€ã 
+}
+
+_textdelsuc_ [l=zh-tr] {æååªé€_cgiargbc1dirname_å
+žèè³æåº«ã}
+
+_textclonefail_ [l=zh-tr] {ç¡æ³è€è£œ _cgiargclonecol_ å
+žèè³æåº«ïŒå¯èœåå çºïŒ
+<ul>
+<li>â¢	_cgiargclonecol_ collection äžå­åšã 
+<li>â¢	_cgiargclonecol_ collection æ²æ collect.cfg è®æžæªã 
+<li>â¢	Greenstone æ²æè®åcollect.cfg è®æžæªçèš±å¯ã 
+</ul>
+}
+
+_textcolerr_ [l=zh-tr] {å
+žèè³æåº«ä»é¢é¯èª€}
+
+_texttmpfail_ [l=zh-tr] {å­æ¬Ÿè
+äžèœè®åææå¯«è³èšææªæ¡æåéãå¯èœåºçŸçåå æïŒ
+<ul>
+<li>Greenstone æ²æè®å/æå¯«è³ _gsdlhome_/tmp åéçæ¬é
+</ul>
+}  
+
+_textmkcolfail_ [l=zh-tr] {åšæ°å
+žèäžå
+žèè³æåº«ä»é¢ç¡æ³å»ºç«ç®éçµæ§ (mkcol.pl å€±æ)å¯èœåå çºïŒ
+<ul>
+<li>â¢	Greenstone æ²æå¯«å
+¥ _gsdlhome_/tmp ç®éçèš±å¯ã
+<li>â¢	mkcol.pl perlæè¿°é¯èª€ã 
+</ul>
+}
+
+_textnocontent_ [l=zh-tr] {å
+žèè³æåº«ä»é¢é¯èª€ïŒæ°å
+žèè³æåº«ç¡åçš±ïŒåŸé ­éå§éæ°ååå
+žèè³æåº«ä»é¢ã}
+
+_textrestart_ [l=zh-tr] {éæ°ååå
+žèè³æåº«ä»é¢}
+
+_textreloaderror_ [l=zh-tr] {å»ºç«æ°å
+žèè³æåº«ææèª€ïŒéå¯èœæ¯
+å çºGreenstoneå·²è¢«çèŠœåšäœ¿çšâéæ°èŒå
+¥âæâè¿åâéµæ··æ·(è«æŒå»ºç«æ°å
+žèè³æåº«æé¿å
+äœ¿çšæ­€äºéµ)ïŒå»ºè­°äœ éæ°ååå
+žèè³æåº«ä»é¢ã
+}
+
+_textexptsuc_ [l=zh-tr] {æåèŒžåº _cgiargbc1dirname_å
+žèè³æåº« è³ _gsdlhome_/tmp/exported\__cgiargbc1dirname_ ç®éã 
+}
+
+_textexptfail_ [l=zh-tr] { <p>ç¡æ³èŒžåº _cgiargbc1dirname_ çå
+žèè³æåº«ã
+
+<p>éå¯èœæ¯å çº Greenstone æ²æå®è£æ¯æŽãèŒžåºè³å
+ç¢ãåèœçå¿
+èŠå
+ä»¶ã 
+<ul>
+<li> åè¥äœ äœ¿çšå
+ç¢å®è£ 2.70 æä¹åçæ¬ç GreenstoneïŒé€éæšåšå®è£æéžæãé²ééžé 
+ãïŒåŠåéäºå
+ä»¶äžæè¢«å®è£ãæšå¿
+é éæ°å®è£ GreenstoneïŒäžŠå å
+¥éåå¿
+èŠå
+ä»¶ã
+<li> åè¥äœ äœ¿çšç¶²è·¯å®è£ïŒæšå¿
+é äžèŒåå®è£é¡å€å¥ä»¶ïŒæ¹å¯äœ¿çšæ­€é 
+åèœãè©³æ
+è«çèŠœç¶²å <a href="http://www.greenstone.org">http://www.greenstone.org</a> æ <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">å å
+¥éµå¯æž
+å®</a>
+</ul>}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=zh-tr] {<p> è«èªªæä»¥äžæªæ¡çè³æåæ _textintro_ </p>}  
+
+_textcaec_ [l=zh-tr] {å å
+¥çŸå­çå
+žèè³æåº«}  
+_textbild_ [l=zh-tr] {å­å
+¥é 
+ç®}  
+_textintro_ [l=zh-tr] {éžææªæ¡}  
+_textconfirm_ [l=zh-tr] {ç¢ºå®}  
+_textselect_ [l=zh-tr] {éžæå
+žèè³æåº«}  
+_textmeta_ [l=zh-tr] {èªªæå
+æžæ}  
+_textselectoption_ [l=zh-tr] {éžæå
+žèè³æåº«}  
+
+_texttryagain_ [l=zh-tr] {è«<a href="_httppagedepositor_" target=_top>éæ°éå§å­æ¬Ÿè
+</a>ç¶åŸååè©Šã\}  
+
+_textselectcol_ [l=zh-tr] {éžæäžåèŠå¢å æ°æä»¶çå
+žèè³æåº«}  
+_textfilename_ [l=zh-tr] {æªæ¡åçš±}  
+_textfilesize_ [l=zh-tr] {æªæ¡å€§å°}  
+
+_textretcoll_ [l=zh-tr] {éåè³å­æ¬Ÿè
+}  
+
+
+_texttmpfail_ [l=zh-tr] {å­æ¬Ÿè
+äžèœè®åææå¯«è³èšææªæ¡æåéãå¯èœåºçŸçåå æïŒ
+<ul>
+<li> Greenstone æ²æè®å/æå¯«è³ _gsdlhome_/tmp åéçæ¬é
+</ul>}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=zh-tr] {Greenstoneæ¯äžå¥æææåæžäœåæžé€šå
+žèåå»ºæ§å
+žèèœåçè»é«ïŒå®æäŸäºæŽåè³èšçæ°æ¹æ³åçšç¶²è·¯æCD-ROMå
+¬éè³èšãGreenstone æ¯ç±Waikatoå€§å­žççŽè¥¿è­æžäœåæžé€šèšç«è£œé ïŒåUNESCOåHuman Info NGOåäœçŒè¡çãå®æ¯open-sourceè»é«ïŒ
+åš<i>http://greenstone.org</i> äžéµå
+¥GNU General Public License å¯ååŸã 
+}
+
+_textgreenstone2_ [l=zh-tr] {çŽè¥¿è­æžäœåæžé€šç¶²ç« (<a href="http://nzdl.org">http://nzdl.org</a>) å
+å«äºç¡æžçš
+Greenstoneè»é«å»ºç«å¯äŸç²Ÿè®çæ¶èç¯æ¬ïŒå®åæ¯åçš®æå°åçèŠœéžæçç¯äŸ,
+å
+¶äž­å
+æ¬äºé¿æäŒ¯ãäž­åãæ³åãæ¯å©ãè¥¿ç­çåè±åçå
+žèïŒéæäžäºé³æšç
+å
+žèã
+}
+
+_textplatformtitle_ [l=zh-tr] {å¹³å°}
+_textgreenstone3_ [l=zh-tr] {Greenstoneå¯åš WindowsãUnix å Mac OS Xäžå·è¡ãå
+¶åäœæ¶µèäºWindowsã LinuxåMac OS X çå¯å·è¡æªïŒå®ä¹å
+å«äºå¯è¢«Microsoft C++ægccç·šè­¯çå®æŽç³»çµ±åå§ç¢Œã
+Greenstoneäœ¿çšå
+è²»ççžéè»ïŒApache Webserver å PERLïŒäœ¿çšè
+ä»é¢æçšçç¶²é çèŠœåšïŒå
+žåç Netscape Navigator æ Internet Explorerã 
+}
+
+_textgreenstone4_ [l=zh-tr] {æåŸå€å
+žèè³æåº«çæä»¶ééGreenstoneè»é«å
+ç¢çæ£äœïŒäŸåŠ
+<i>Humanity Development Library</i>å
+§å«1,230ä»œåçšæ°Žè¡çççžéçµ±èšæä»¶ïŒ
+ä»åªéèŠåšç¡¬é«ç­çŽèŠæ±äžé«å°é»è
+Šäžå·è¡ïŒéäºé»è
+Šä¹åŸå®¹æåšéçŒäž­åå®¶å
+§ååŸïŒ
+æä»¶å¯ééå
+šæçééµå­æ¥è©¢ïŒææ¯ä»¥äžåçæ¹åŒäŸçèŠœæŽåå
+žèè³æåº«å
+§çæä»¶
+(äŸäž»é¡ïŒäŸæšé¡ïŒäŸåºçåçµç¹ïŒäŸ "åŠäœ..")ïŒçè³ä¹å¯çèŠœæ¯äžæ¬æžçå°é¢ã}
+
+_textcustomisationtitle_ [l=zh-tr] {é¡§å®¢å°å}
+_textgreenstone5_ [l=zh-tr] {Greenstone å
+·æé«æŽå
+
+æ§åä»¥é¡§å®¢çºå°åçè§å¿µèèš­èšãæ°çæä»¶åè©®éè³ææ ŒåŒèç±èš­èš "plugins" (in Perl)äŸæäŸãåçïŒæ°çä»¥äžåè©®éè³æçèŠœçæ¶æ§èœå€ èç±èš­èš"classifiers" äŸå·è¡ãçšç°¡å®çå·šéèªèšå¯«âå·šéâïŒå¯è®æŽäœ¿çšè
+ä»é¢çåçŸæ¹åŒãCorbaåå®è®ä»£çäºº(äŸåŠJava)äœ¿çšåæä»¶å
+žèè³æåº«æéçèš­åïŒæåŸïŒ å¯çšC++åPerlçäŸä¿®å®åå§ç¢Œã
+}
+
+_textdocumentationtitle_ [l=zh-tr] {æä»¶}
+_textdocuments_ [l=zh-tr] {Greenstoneä¹æäŸå€§éå€æš£çç³»çµ±æä»¶ã}
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=zh-tr] {éµå¯æž
+å®}
+_textmailinglist_ [l=zh-tr] {éµå¯æž
+å®äž»èŠæ¯çºäºèšè«Greenstoneæžäœåæžé€šè»é«ãGreenstoneçç¶åžžäœ¿çš
+è
+æèæ
+®å å
+¥éµå¯æž
+å®åå å
+¥èšè«ãèšé±è«è³<a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">
+https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+
+å¯éèšæ¯å°æž
+å®ç
+å°åçº<a href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+greenstone-users@list.scms.waikato.ac.n</a>z. 
+}
+
+_textbugstitle_ [l=zh-tr] {Bugs}
+_textreport_ [l=zh-tr] {çºç¢ºä¿éè»ä»¶éäœæ­£åžžïŒåŠæšåšäœ¿çšæçŒçŸæä»»äœåé¡ïŒæè«é»éµ<a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>ã}  
+
+_textgs3title_ [l=zh-tr] {åšç¢åäž­}
+_textgs3_ [l=zh-tr] {Greenstone 3 æ¯ä¿çGreenston 2(ç®åç)çåªé»åŸéæ°èš­èšåå·è¡ççæ¬-äŸåŠïŒå®æ¯å€èªèšãå€å¹³å°åé«åºŠåœæ§é
+çœ®ïŒå®å
+å«äºçŸæç³»çµ±çç¹è²äžåäžçžå®¹ïŒä¹å°±æ¯èªªïŒå®äžéä¿®æ¹å³å¯å»ºæ§åå·è¡çŸæå
+žèè³æåº«ïŒå®æ¯çšJavaå¯«çïŒç±äœ¿çšXMLæºéççšç«æš¡çµç¶²è·¯æå»ºæ§ïŒå æ­€å®æ¯äœ¿çšæŽŸéçæš¡åŒäžå¿
+èŠæå¯æŽå±å°äžåçäŒºæ
+åšãéçš®æš¡çµèš­èšå¢å äºGreenstoneçåœæ§åæŽå
+
+æ§.ïŒæ°çé èšæŒ2003å¹Ž12æ23æ¥éå§è©ŠçšïŒç³»çµ±çèµ·å§èš­èšç¥è¿°æŒâGreenstone 3çèš­èš:ïŒä»¥ä»£çäººçšåŒçºåºç€çâåæ
+æžäœåæžé€š" (äžèŒ<a href="http://www.greenstone.org/manuals/gs3design.pdf">PDF</a>).
+}
+
+_textcreditstitle_ [l=zh-tr] {è®æ}
+
+_textwhoswho_ [l=zh-tr] {Greenstoneè»é«æ¯èš±å€äººéååäœæç¢ççã Rodger McNab å Stefan Boddie 
+æ¯äž»èŠçèš­èšåž«åå·è¡è
+ïŒ David Bainbridgeã George Buchananã Hong Chenã
+Michael DewsnipãKatherine DonãElke DunckerãCarl GutwinãGeoff Holmesã
+Dana McKayã John McPhersonã Craig Nevill-Manningã Dynal PatelãGordon 
+Paynterã Bernhard Pfahringerã Todd Reedã Bill RogersãJohn Thompsonå Stuart 
+Yeatesä¹æèš±å€è²¢ç»ãçŽè¥¿è­æžäœåæžé€šçæå¡ä¹æäŸäºå¯¶è²Žçå»ºè­°åç³»çµ±èš­
+èšçéæïŒ Mark ApperleyãSally Jo Cunninghamã Matt JonesãSteve Jonesã Te 
+Taka Keeganã Michel Lootsã Malika Mahouiã Gary Marsdenã Dave Nichols å 
+Lloyd Smithã æåä¹èŠæè¬å°å
+å«åšæ­€çæ¬å
+§çGNU-èš±å¯å¥è£ïŒ MGã 
+GDBMã PDFTOHTMLãPERLã WGETãWVWARE å XLHTMLæè²¢ç»çäºº. 
+}
+
+_textaboutgslong_ [l=zh-tr] {éæŒ Greenstone è»é«}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=zh-tr] {é¡¯ç€ºç®åäœ¿çšè
+}
+_textuser_ [l=zh-tr] {äœ¿çšè
+}
+_textas_ [l=zh-tr] {ç®ååž³èçæ
+}
+_textgroups_ [l=zh-tr] {çŸ€çµ}
+_textcomment_ [l=zh-tr] {èš»è§£}
+_textadduser_ [l=zh-tr] {å å
+¥æ°äœ¿çšè
+}
+_textedituser_ [l=zh-tr] {ç·šèŒ¯}
+_textdeleteuser_ [l=zh-tr] {åªé€}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=zh-tr] {ç·šèŒ¯äœ¿çšè
+è³èš}
+_textadduser_ [l=zh-tr] {å¢å æ°äœ¿çšè
+}
+
+_textaboutusername_ [l=zh-tr] {äœ¿çšè
+åçš±é çº2~30åå­ïŒå¯å
+æ¬ææžå­ïŒ '.'ïŒ å '_'. 
+}
+
+_textaboutpassword_ [l=zh-tr] {å¯ç¢Œé çº3~128åASCIIå­}
+
+_textoldpass_ [l=zh-tr] {è¥æ­€æ¬ç©ºçœïŒå°ä¿çèå¯ç¢Œã}
+_textenabled_ [l=zh-tr] {çæ}
+_textdisabled_ [l=zh-tr] {ç¡æ}
+
+_textaboutgroups_ [l=zh-tr] {çŸ€çµçºäžéèåéçè¡šå®ïŒéèåŸäžå¯æç©ºæ Œã}
+_textavailablegroups_ [l=zh-tr] {é å
+èš­å®çŸ€çµïŒå
+æ¬ç®¡çè
+ãå
+¶ä»æ¬éåé
+è
+ (äŸåŠäœ¿çšåæžé€šé€šé·ä»é¢ïŒä»¥å»ºç«é ç«¯å
+žèè³æåº«) æå­æ¬Ÿè
+ïŒ
+<ul>
+<li><b>ç®¡çè
+</b>ïŒ çµŠäºå
+èš±ïŒä»¥é²å
+¥åæŽæ¹ç¶²ç«çé
+çœ®åäœ¿çšè
+åž³æ¶è³æ
+<li><b>åäºº-å
+žèè³æåº«-ç·šèŒ¯</b>ïŒ çµŠäºå
+èš±ïŒä»¥å»ºç«æ°çåäººå
+žèè³æåº«
+<li><b><å
+žèè³æåº«-åçš±>-å
+žèè³æåº«-ç·šèŒ¯</b>ïŒçµŠäºå
+èš±ïŒä»¥å»ºç«åç·šèŒ¯ "collection-name" çå
+žèè³æåº«ïŒäŸåŠïŒå ±å-å
+žèè³æåº«-ç·šèŒ¯
+<li><b>ææ-å
+žèè³æåº«-ç·šèŒ¯</b>ïŒçµŠäºå
+èš±ïŒä»¥å»ºç«/ç·šèŒ¯æ°çåäººåç°çå
+žèè³æåº«<b>ææ</b>å
+žèè³æåº«
+</ul>}  
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=zh-tr] {åªé€äœ¿çšè
+}
+_textremwarn_ [l=zh-tr] {äœ ç¢ºå®èŠæ°žä¹
+åªé€äœ¿çšè
+_cgiargumun_?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=zh-tr] {æŽæ¹å¯ç¢Œ}
+_textoldpw_ [l=zh-tr] {èå¯ç¢Œ}
+_textnewpw_ [l=zh-tr] {æ°å¯ç¢Œ}
+_textretype_ [l=zh-tr] {åèŒžå
+¥äžæ¬¡æ°å¯ç¢Œ}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=zh-tr] {äœ çå¯ç¢ŒæŽæ¹æåïŒ}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=zh-tr] {äœ¿çšè
+åçš±é¯èª€}
+_textinvalidpassword_ [l=zh-tr] {å¯ç¢Œé¯èª€.}
+_textemptypassword_ [l=zh-tr] {è«èŒžå
+¥äœ¿çšè
+æåèš­å®çå¯ç¢Œ}
+_textuserexists_ [l=zh-tr] {äœ¿çšè
+åçš±å·²å­åšïŒè«èŒžå
+¥å
+¶ä»äœ¿çšè
+åçš±ã}
+
+_textusernameempty_ [l=zh-tr] {è«èŒžå
+¥äœ¿çšè
+åçš±.}
+_textpasswordempty_ [l=zh-tr] {è«èŒžå
+¥èå¯ç¢Œ}
+_textnewpass1empty_ [l=zh-tr] {èŒžå
+¥äœ çæ°å¯ç¢ŒåŸïŒååšéè€èŒžå
+¥äžæ¬¡}
+_textnewpassmismatch_ [l=zh-tr] {èŒžå
+¥äºæ¬¡çæ°å¯ç¢Œäžçžå}
+_textnewinvalidpassword_ [l=zh-tr] {èŒžå
+¥å¯ç¢Œé¯èª€}
+_textfailed_ [l=zh-tr] {äœ¿çšè
+åçš±æå¯ç¢ŒèŒžå
+¥é¯èª€}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=zh-tr] {Greenstone çæ¬}
+_textframebrowser_ [l=zh-tr] {äœ ççèŠœåšéèŠæ¯æŽåèœæèœå»è§çå®ã}
+_textusermanage_ [l=zh-tr] {äœ¿çšè
+ç®¡ç}
+_textlistusers_ [l=zh-tr] {ååºäœ¿çšè
+}
+_textaddusers_ [l=zh-tr] {å å
+¥æ°çäœ¿çšè
+}
+_textchangepasswd_ [l=zh-tr] {è®æŽå¯ç¢Œ}
+_textinfo_ [l=zh-tr] {ç³»çµ±è³èš}
+_textgeneral_ [l=zh-tr] {äžè¬è³èš}
+_textarguments_ [l=zh-tr] {ç³»çµ±åæž}
+_textactions_ [l=zh-tr] {Actionè³èš}
+_textbrowsers_ [l=zh-tr] {çèŠœåšè³èš}
+_textprotocols_ [l=zh-tr] {åå®è³èš}
+_textconfigfiles_ [l=zh-tr] {èš­å®æª}
+_textlogs_ [l=zh-tr] {æ¥èª}
+_textusagelog_ [l=zh-tr] {äœ¿çšäž­ä¹æ¥èª}
+_textinitlog_ [l=zh-tr] {èµ·å§æ¥èª}
+_texterrorlog_ [l=zh-tr] {é¯èª€æ¥èª}
+_textadminhome_ [l=zh-tr] {ç®¡çè
+éŠé }
+_textreturnhome_ [l=zh-tr] {GreenstoneéŠé }
+_titlewelcome_ [l=zh-tr] {ç®¡çè
+ }
+_textmaas_ [l=zh-tr] {ç¶­è­·åç®¡çæåçå
+å«åšå
+§ïŒ}
+_textvol_ [l=zh-tr] {è§çç·äžæ¥èª}
+_textcmuc_ [l=zh-tr] {ç¢çïŒç¶­è­·åæŽæ°å
+žèè³æåº«}
+_textati_ [l=zh-tr] {å­åç³»çµ±è³èšïŒäŸåŠCGI åŒæž}
+
+_texttsaa_ [l=zh-tr] {éäºæåå­åæ¯äœ¿çšåšå·Šæéé é¢ä¹æ¹åèªè¡æ£ }
+
+_textcolstat_ [l=zh-tr] {å
+žèè³æåº«çæ
+}
+
+_textcwoa_ [l=zh-tr] {å
+žèæåªæåºçŸâå·è¡äž­âïŒç¶å®åå»ºç« ä¹cfgæªæ¡å­åšäž
+å¯è®åïŒäžŠäžåšå
+žèè³æåº«ä¹çŽ¢åŒå­å
+žäž­ã(ä¹å°±æ¯äžåšå»ºç«äž­ä¹ç®éãïŒ
+_textcafi_ [l=zh-tr] {æ abbrevéµ. å¯ä»¥æª¢èŠå
+žèè³æåº«è³èš}
+
+_textcafi_ [l=zh-tr] {æ<i>abbrev.</i>å¯ä»¥æª¢èŠå
+žèè³æåº«çç°¡ä»}
+_textcctv_ [l=zh-tr] {æå
+žèè³æåº«éµå»è§çè³æåº«æ
+åœ¢}
+_textsubc_ [l=zh-tr] {ç¢ºèªè®æŽ}
+_texteom_ [l=zh-tr] {éå main.cfgé¯èª€}
+_textftum_ [l=zh-tr] {æŽæ° main.cfgå€±æ}
+_textmus_ [l=zh-tr] {æŽæ°main.cfg æå}
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=zh-tr] {å»ºç« _collectionname_ å
+žèè³æåº«çéçšçŽé}  
+_textflog_ [l=zh-tr] {_collectionname_ å
+žèè³æåº«çå€±ææ¥èª}  
+_textilog_ [l=zh-tr] {å¯å
+¥"_collectionname_" å
+žèè³æåº«çæ¥èª}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=zh-tr] {éåºä¿¡æ¯}  
+
+_greenstoneusabilitytext_ [l=zh-tr] {Greenstone ä¹å¯çšæ§}
+
+_textwhy_ [l=zh-tr] {<p>éåºéä»œå ±åæ¯äžåæ¹æ³ïŒä»¥æåºäžäºææª¢èŠå°é£æå€±æä¹ç¶²é ã}  
+_textextraforform_ [l=zh-tr] {äœ ç¡é å¡«å®è¡šæ Œ â ä»»äœèšæ¯éœæå¹«å©ã}
+_textprivacybasic_ [l=zh-tr] {<p>éä»œå ±ååªå
+å«æšææª¢èŠæé Greenstone ç¶²é ä¹ä¿¡æ¯ïŒèåæšæäœ¿çšçæª¢èŠæè¡ ï¹å äžæšææäŸä¹éžææ§è³èšï¹ã}  
+_textstillsend_ [l=zh-tr] {æšæ¯åŠä»èèŠéåºéä»œå ±åïŒ}  
+
+_texterror_ [l=zh-tr] {é¯èª€}
+_textyes_ [l=zh-tr] {æ¯}  
+_textno_ [l=zh-tr] {åŠ}  
+_textclosewindow_ [l=zh-tr] {ééèŠçª}  
+_textabout_ [l=zh-tr] {æé}
+_textprivacy_ [l=zh-tr] {ç§äž}
+_textsend_ [l=zh-tr] {éåº}
+_textdontsend_ [l=zh-tr] {äžèŠéåº}  
+_textoptionally_ [l=zh-tr] {éžææ§ç}  
+
+_textunderdev_ [l=zh-tr] {æåŸä¿®æ­£ççæ¬å°å
+æ¬è©³çŽ°é èŠœå ±åçåèœã}  
+
+_textviewdetails_ [l=zh-tr] {æª¢èŠè©³çŽ°çå ±å}  
+_textmoredetails_ [l=zh-tr] {æŽè©³çŽ°}  
+_texttrackreport_ [l=zh-tr] {è¿œè¹€éä»œå ±å}  
+_textcharacterise_ [l=zh-tr] {éæ¯å±¬æŒåªäžé¡åé¡}  
+_textseverity_ [l=zh-tr] {éåé¡åŸç³ç³}  
+ 
+_textbadrender_ [l=zh-tr] {é é¢çèµ·äŸåŸå¥æª}  
+_textcontenterror_ [l=zh-tr] {å
+§å®¹é¯èª€}  
+_textstrangebehaviour_ [l=zh-tr] {å¥æªçè¡çº}  
+_textunexpected_ [l=zh-tr] {çŒçæªèœé æä¹æ
+æ³}  
+_textfunctionality_ [l=zh-tr] {åŸé£äœ¿çš}  
+_textother_ [l=zh-tr] {å
+¶ä»}  
+
+_textcritical_ [l=zh-tr] {è©è«ç}  
+_textmajor_ [l=zh-tr] {åŽéç}  
+_textmedium_ [l=zh-tr] {äž­ç­ç}  
+_textminor_ [l=zh-tr] {èŒå°ç}  
+_texttrivial_ [l=zh-tr] {ç£ç¢ç}  
+
+_textwhatdoing_ [l=zh-tr] {æšåè©Šåä»éºŒ?}  
+_textwhatexpected_ [l=zh-tr] {æšæåŸ
+äœäºçŒç?}  
+_textwhathappened_ [l=zh-tr] {å¯ŠéäžçŒçäœäº?}  
+
+_cannotfindcgierror_ [l=zh-tr] {<h2>å°äžèµ·ïŒ</h2>æªèœæŸåº ãææ¬²æèšŽãçäŒºæåšçšåŒã}  
+
+_textusabbanner_ [l=zh-tr] {the Greenstone koru-é¡å æšèª}
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=zh-tr] {çŒçé¯èª€}  
+
+_textgtihome_ [l=zh-tr] {éé åå©æšæ¹å Greenstone çå€èªèšæ¯æŽãå©çšéåæ¯æŽïŒäœ å¯ä»¥
+<ul>
+  <li> çºéšä»œç Greenstone ç¿»è­¯äžäºæ°èªèš
+  <li> åšè±èªä»é¢æææ¹è®æ (äŸåŠåŒé²æ°ç Greenstone èš­å)ïŒæŽæ°çŸå­çèªèšä»é¢
+  <li> ç³Ÿæ­£çŸæç¿»è­¯çé¯èª€
+</ul>
+
+äžç³»åçç¶²é å°æåçŸæšççŒåïŒéå
+æ¬éèŠç¿»è­¯çè©åœã
+éééæ­¥ç¿»è­¯èªèšçä»é¢ïŒæšå¯ä»¥ç¹Œçºã
+èš±å€è©åœåå
+æ¬ HTML æ ŒåŒçæä»€ïŒæšäžæè©²åè©Šç¿»è­¯éäºè©åœïŒå»èŠåè©Šä¿æéäºè©åœæŒå·²ç¿»è­¯ççæ¬ãäžäºå·²æäžåç·çè©åœ (äŸåŠ _this_ ) äŸ¿äžæè©²ç¿»è­¯äº (å éæ¯ Greenstone "macro" åçš±)ã
+<p>
+åè¥æšæ­£åšæŽæ°çŸå­çèªèšä»é¢ïŒå·²ç¿»è­¯çè©åœå°äžæåçŸæŒæšççŒåãææåïŒå·²ç¿»è­¯ççæ¬äžŠæªè·éšè±æçæ¬æ¹è®ãåšéæ
+æ³äžïŒGreenstone å°ææäŸçŸæçç¿»è­¯ïŒè®æšæéèŠæå¯ä»¥æª¢æ¥åèªææŽæ°ã
+<p>
+åŠèŠç³Ÿæ­£å·²æŽæ°çç¿»è­¯ïŒå¯äœ¿çš Greenstone æäŸç "Correct existing translations" åèœã
+<p>
+æ¯é éœä»¥ "_textgtisubmit_" æéçºçµçµãç¶æšæäžæ­€æéïŒåéå®è£ Greenstone æŒ nzdl.org çæ¹è®éŠ¬äžåºçŸïŒèäžæ¯é åæåºçŸäžåæéå»é²å
+¥éåç¶²åã}  
+
+_textgtiselecttlc_ [l=zh-tr] {è«éžæèªèš}  
+
+#for status page
+_textgtiviewstatus_ [l=zh-tr] {æäžäžæ­€éµïŒä»¥æª¢èŠææèªèšçç¿»è­¯çæ
+}  
+_textgtiviewstatusbutton_ [l=zh-tr] {æª¢èŠçæ
+}  
+_textgtistatustable_ [l=zh-tr] {ååºææèªèšçç¿»è­¯çæ
+}  
+_textgtilanguage_ [l=zh-tr] {èªèš}  
+_textgtitotalnumberoftranslations_ [l=zh-tr] {ç¿»è­¯ççžœæž}  
+
+_textgtiselecttfk_ [l=zh-tr] {è«éžæéèŠå·¥äœçæªæ¡}  
+
+_textgticoredm_ [l=zh-tr] {Greenstone ä»é¢ (äž»èŠ)}  
+_textgtiauxdm_ [l=zh-tr] {Greenstone ä»é¢ (èŒå©)}  
+_textgtiglidict_ [l=zh-tr] {GLI åé}  
+_textgtiglihelp_ [l=zh-tr] {GLI å©æ}  
+_textgtiperlmodules_ [l=zh-tr] {Perl æš¡åŒ}  
+_textgtitutorials_ [l=zh-tr] {åäººç·Žç¿}  
+_textgtigreenorg_ [l=zh-tr] {Greenstone.org}  
+_textgtigs3interface_ [l=zh-tr] {Greenstone3 ä»é¢}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=zh-tr] {Greenstone éçŒæå}  
+_textgtiinstallmanual_ [l=zh-tr] {Greenstone å®è£è
+æå}  
+_textgtipapermanual_ [l=zh-tr] {Greenstone æå (æŽ»é è³æŽåå
+žèè³æåº«)}  
+_textgtiusermanual_ [l=zh-tr] {Greenstone äœ¿çšè
+æå}  
+
+_textgtienter_ [l=zh-tr] {èŒžå
+¥}  
+
+_textgticorrectexistingtranslations_ [l=zh-tr] {ç³Ÿæ­£çŸå­çç¿»è­¯}  
+_textgtidownloadtargetfile_ [l=zh-tr] {äžèŒæªæ¡}  
+_textgtiviewtargetfileinaction_ [l=zh-tr] {æª¢èŠéåæªæ¡}  
+_textgtitranslatefileoffline_ [l=zh-tr] {é¢ç·ç¿»è­¯éåæªæ¡}  
+
+_textgtinumchunksmatchingquery_ [l=zh-tr] {é
+åé¡åçæå­æžç®}  
+
+_textgtinumchunkstranslated_ [l=zh-tr] {ç¿»è­¯ç¶å·²å®æ}  
+_textgtinumchunksrequiringupdating_ [l=zh-tr] {å æ­€ïŒ _1_ éèŠæŽæ°}  
+_textgtinumchunksrequiringtranslation_ [l=zh-tr] {é€äžçç¿»è­¯}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=zh-tr] {å·²å®æç¿»è­¯çæžç®}  
+_textgtinumchunksrequiringupdating2_ [l=zh-tr] {éèŠæŽæ°çç¿»è­¯æžç®}  
+_textgtinumchunksrequiringtranslation2_ [l=zh-tr] {é€äžçç¿»è­¯æžç®}  
+
+_textgtienterquery_ [l=zh-tr] {èŒžå
+¥æšæ¬²ç³Ÿæ­£çå­å¥æçèª}  
+_textgtifind_ [l=zh-tr] {å°æŸ}  
+
+_textgtitranslatingchunk_ [l=zh-tr] {ç¿»è­¯æå­ <i>_1_</i>}  
+_textgtiupdatingchunk_ [l=zh-tr] {æŽæ°æå­ <i>_1_</i>}  
+_textgtisubmit_ [l=zh-tr] {éåº}  
+
+_textgtilastupdated_ [l=zh-tr] {æåŸæŽæ°}  
+
+_textgtitranslationfilecomplete_ [l=zh-tr] {å€è¬æŽæ°éæªæ¡ - æŽæ°çŸå·²å®æïŒ<p>å©çšä»¥äžçé£çµïŒæšå¯ä»¥äžèŒéæªæ¡çå¯æ¬ãéé£çµäºŠæèšèŒæŒæ°çŒäœç Greenstone äžã}  
+
+_textgtiofflinetranslation_ [l=zh-tr] {å©çš Microsoft Excel æŽ»é ç°¿è¡šæ Œæªæ¡ïŒæšå¯ä»¥é¢ç·ç¿»è­¯ééšä»œç GreenstoneïŒ
+<ol>
+<li>äžèŒ<a href="_gwcgi_?a=gti&p=excel&e=_compressedoptions_">æªæ¡</a>.
+<li> éåå·²äžèŒç Microsoft Excel æªæ¡ (Office 2003/XP æèŒæ°ççæ¬) åå²å­çº Microsoft Excel å·¥äœè¡š (.xls) æ ŒåŒã
+<li> æŒå·²æäŸçæ¹æ Œå
+§èŒžå
+¥ç¿»è­¯ã
+<li> ç¶äœ å®æç¿»è­¯ææçå­äž²ïŒé»éµ .xls æ ŒåŒçæªæ¡è³<a href="mailto:_gtiadministratoremail_"> _gtiadministratoremail_</a>ã
+</ol>}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=zh-tr] {Greenstone åæžé€šå¡ç¶­è­·ä»é¢}
+_textglihelp_ [l=zh-tr] {<p>Greenstone çåæžé€šé€šé·ä»é¢ (Greenstone Librarian Interface, GLI) çºæšæäŸææŒäœ¿çšçãé»éžåæéµãä»é¢ïŒä»¥æ¹äŸ¿æšäœ¿çšäžåç Greenstone åèœãåæïŒäºŠå®¹èš±æšæ¶éæä»¶ãå¯å
+¥æé
+çœ®å
+æžæïŒèåå»ºç« Greenstone å
+žèè³æåº«ã 
+
+<p>è«æ³šæ GLI æ¯è Greenstone äŒºæåšç«¯äžèµ·å·è¡çïŒèäž GLI æ¯å®è£æŒ Greenstone çå­ç®éãåè¥æšå·²äžèŒå
+¶äž­äžå Greenstone çå
+ä»¶ïŒæå·²åŸ Greenstone å
+ç¢äž­éžåå®è£ïŒæ
+æ³åæ¯äžæš£çã
+
+<h4>åš Windows èŠçªå·è¡ GLI</h4>
+
+åŠèŠåš Windows èŠçªå·è¡åæžé€šé€šé·ä»é¢ïŒå
+åš<i>éå§</i>å·¥å
+·åäž­ïŒéžå<i>çšåŒé</i>ïŒç¶åŸïŒåš<i>Greenstone æžç¢Œåæžé€š</i>çç®éå
+§ïŒéžå<i>åæžé€šé€šé·ä»é¢</i>ã
+
+<h4>åš Unix èŠçªå·è¡ GLI</h4>
+
+åŠèŠåš Unix èŠçªå·è¡ GLIïŒå
+åš Greenstone å®è£çšåºäž­æŽæ¹ <i>gli</i> ç®éïŒåå·è¡ <i>gli.sh</i> scriptã
+
+<h4>åš Mac OS X èŠçªå·è¡ GLI</h4>
+
+çèŠœ<i>æçšçšåŒ</i>äžŠéžå<i>Greenstone</i> (åŠæšå·²å®è£ Greenstone åšé èš­çäœçœ®å
+§)ïŒç¶åŸå·è¡<i>GLI</i>æçšçšåŒã}  
Index: /gsdl/stable/macros/chinese.dm
===================================================================
--- /gsdl/stable/macros/chinese.dm	(revision 20131)
+++ /gsdl/stable/macros/chinese.dm	(revision 20131)
@@ -0,0 +1,908 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Chinese Language text and icon macros 
+# Many thanks to Andrew Yan Han (updated August 2004)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=zh] {æå¿}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=zh] {æ¥æºåèïŒ}
+_textdate_ [l=zh] {åºçæ¥æïŒ}
+_textnumpages_ [l=zh] {æ»é¡µæ°}
+
+_textsignin_ [l=zh] {ç»åœ}
+
+_textdefaultcontent_ [l=zh] {æªåç°æšèŠæ±ççœé¡µãè¯·çšæµè§åšâåéâé®æäžé¢çhomeé®éåç»¿å®ç³æ°å­åŸä¹ŠéŠã}
+
+_textdefaulttitle_ [l=zh] {ç»¿å®ç³æ°å­åŸä¹ŠéŠéè¯¯}
+
+_textbadcollection_ [l=zh] {æ­€ç»¿å®ç³æ°å­åŸä¹ŠéŠæ²¡æå®è£
+æ¬æ¶è ("_cvariable_") ã }
+
+_textselectpage_ [l=zh] {â éæ©é¡µâ}
+
+_collectionextra_ [l=zh] {æ¬æ¶èç°æ _about:numdocs_ ææ¡£ã å®æè¿æŽæ°äž_about:builddate_ æ¥åã}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=zh] {<p>æ¬æ¶èç°æ_numdocs_ _If_("_numdocs_" eq "1",document,documents), æ»å
+± _numbytes_.
+<p><a href="_httppagex_(bsummary)">ç¹å»è¿é</a> æµè§æ¬æ¶è build summary ã
+}
+
+_textdescrcollection_ [l=zh] {}
+_textdescrabout_ [l=zh] {å
+³äºé¡µ}
+_textdescrhome_ [l=zh] {äž»é¡µ}
+_textdescrhelp_ [l=zh] {åž®å©é¡µ}
+_textdescrpref_ [l=zh] {éé¡¹é¡µ}
+_textdescrgreenstone_ [l=zh] {ç»¿å®ç³æ°å­åŸä¹ŠéŠèœ¯ä»¶}
+_textdescrusab_ [l=zh] {æšåšäœ¿çšäž­æäœå°éŸïŒ}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=zh] {æ¥è¯¢}  
+_labelSearch_ [l=zh] {æ¥è¯¢}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=zh] {æ é¢}  
+_labelTitle_ [l=zh] {æ é¢ A-Z}
+_textCreator_ [l=zh] {äœè
+}  
+_labelCreator_ [l=zh] {äœè
+ A-Z}
+_textSubject_ [l=zh] {äž»é¢}  
+_labelSubject_ [l=zh] {äž»é¢}
+_textDescription_ [l=zh] {æè¿°}  
+_labelDescription_ [l=zh] {æè¿°}  
+_textPublisher_ [l=zh] {åºçè
+}  
+_labelPublisher_ [l=zh] {åºçè
+}  
+_textContributor_ [l=zh] {èŽ¡ç®è
+}  
+_labelContributor_ [l=zh] {èŽ¡ç®äºº}  
+_textDate_ [l=zh] {æ¥æ}  
+_labelDate_ [l=zh] {æ¥å­}
+_textType_ [l=zh] {ç±»å}  
+_labelType_ [l=zh] {ç±»å}  
+_textFormat_ [l=zh] {æ ŒåŒ}  
+_labelFormat_ [l=zh] {æ ŒåŒ}  
+_textIdentifier_ [l=zh] {æ è¯}  
+_labelIdentifier_ [l=zh] {æ è¯}  
+_textSource_ [l=zh] {æä»¶å}  
+_labelSource_ [l=zh] {æä»¶å}
+_textLanguage_ [l=zh] {è¯­èš}  
+_labelLanguage_ [l=zh] {è¯­èš}
+_textRelation_ [l=zh] {å
+³ç³»}  
+_labelRelation_ [l=zh] {å
+³ç³»}  
+_textCoverage_ [l=zh] {èåŽ}  
+_labelCoverage_ [l=zh] {èåŽ}  
+_textRights_ [l=zh] {çæ}  
+_labelRights_ [l=zh] {çæ}  
+
+# DLS metadata set
+_textOrganization_ [l=zh] {ç»ç»}  
+_labelOrganization_ [l=zh] {ç»ç»}  
+_textKeyword_ [l=zh] {å
+³é®è¯}  
+_labelKeyword_ [l=zh] {å
+³é®è¯}
+_textHowto_ [l=zh] {åŠäœ}  
+_labelHowto_ [l=zh] {åŠäœ}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=zh] {ç­è¯­}  
+_labelPhrase_ [l=zh] {ç­å¥}
+_textCollage_ [l=zh] {åé}  
+_labelCollage_ [l=zh] {åé}
+_textBrowse_ [l=zh] {æµè§}  
+_labelBrowse_ [l=zh] {æµè§}  
+_textTo_ [l=zh] {å°}  
+_labelTo_ [l=zh] {æªæ­¢äº}
+_textFrom_ [l=zh] {ä»}  
+_labelFrom_ [l=zh] {åŒå§äº}
+_textAcronym_ [l=zh] {è¯å€Ž}  
+_labelAcronym_ [l=zh] {è¯å€Ž}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=zh] {æ_1_æµè§}  
+
+_textdescrSearch_ [l=zh] {ç¹å®èåŽæ£çŽ¢}
+_textdescrType_ [l=zh] {æèµæºç±»åæµè§}  
+_textdescrIdentifier_ [l=zh] {æèµæºæ è¯æ¥æµè§}  
+_textdescrSource_ [l=zh] {æåå§æä»¶åæµè§}
+_textdescrTo_ [l=zh] {æ"æªæ­¢äº"åæµè§}
+_textdescrFrom_ [l=zh] {æâåŒå§äºâæµè§}
+_textdescrCollage_ [l=zh] {æåŸçæ¥é
+}
+_textdescrAcronym_ [l=zh] {æµè§è¯å€Ž}
+_textdescrPhrase_ [l=zh] {æµè§ç­è¯}
+_textdescrHowto_ [l=zh] {æåŠäœæµè§}
+_textdescrBrowse_ [l=zh] {æµè§}
+_texticontext_ [l=zh] {æµè§ææ¡£}
+_texticonclosedbook_ [l=zh] {æåŒè®°åœå¹¶æµè§å
+å®¹}
+_texticonnext_ [l=zh] {è®¿é®äžäžåå
+}
+_texticonprev_ [l=zh] {è®¿é®åäžåå
+}
+
+_texticonworld_ [l=zh] {é
+è¯»çœäžæä»¶}  
+
+_texticonmidi_ [l=zh] {æµè§MIDIææ¡£}
+_texticonmsword_ [l=zh] {æµè§åŸ®èœ¯Wordææ¡£}
+_texticonmp3_ [l=zh] {æµè§MP3æä»¶}  
+_texticonpdf_ [l=zh] {æµè§PDFææ¡£}
+_texticonps_ [l=zh] {æµè§PostScriptææ¡£}
+_texticonppt_ [l=zh] {æµè§PowerPointææ¡£}
+_texticonrtf_ [l=zh] {æµè§RTFææ¡£}
+_texticonxls_ [l=zh] {æµè§åŸ®èœ¯Excelææ¡£}
+
+_page_ [l=zh] {é¡µ}
+_pages_ [l=zh] {é¡µ}
+_of_ [l=zh] {ç}
+_vol_ [l=zh] {å}
+_num_ [l=zh] {åŠ}
+
+_textmonth00_ [l=zh] {}
+_textmonth01_ [l=zh] {äžæ}
+_textmonth02_ [l=zh] {äºæ}
+_textmonth03_ [l=zh] {äžæ}
+_textmonth04_ [l=zh] {åæ}
+_textmonth05_ [l=zh] {äºæ}
+_textmonth06_ [l=zh] {å
+­æ}
+_textmonth07_ [l=zh] {äžæ}
+_textmonth08_ [l=zh] {å
+«æ}
+_textmonth09_ [l=zh] {ä¹æ}
+_textmonth10_ [l=zh] {åæ}
+_textmonth11_ [l=zh] {åäžæ}
+_textmonth12_ [l=zh] {åäºæ}
+
+_texttext_ [l=zh] {ææ¬}  
+_labeltext_ [l=zh] {_texttext_}  
+_textdocument_ [l=zh] {ææ¡£}
+_textsection_ [l=zh] {æ®µèœ}
+_textparagraph_ [l=zh] {æ®µèœ}
+_textchapter_ [l=zh] {ç« è}  
+_textbook_ [l=zh] {èæä¹Š}  
+
+_magazines_ [l=zh] {æå¿}
+
+_nzdlpagefooter_ [l=zh] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">æ°è¥¿å
+°æ°å­åŸä¹ŠéŠé¡¹ç®</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">çµèç§å­Šç³»</a>, 
+<a href="http://www.waikato.ac.nz">åšç§åŸå€§å­Š</a>, 
+æ°è¥¿å
+°}
+
+_linktextHOME_ [l=zh] {äž»é¡µ}
+_linktextHELP_ [l=zh] {åž®å©}
+_linktextPREFERENCES_ [l=zh] {éé¡¹}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=zh] {ç»¿å®ç³æ°å­åŸä¹ŠéŠ}  
+
+_textnocollections_ [l=zh] {æ å¯çšçæ¶èïŒæ¯åŠïŒå»ºæçåå
+¬å
+±çïŒ}  
+
+_textadmin_ [l=zh] {ç®¡çé¡µé¢}  
+_textabgs_ [l=zh] {å
+³äºç»¿å®ç³ç³»ç»}  
+_textgsdocs_ [l=zh] {ç»¿å®ç³ææ¡£}  
+
+_textdescradmin_ [l=zh] {å
+è®žæšå å
+¥æ°çšæ·ïŒæ»ç»ç³»ç»äž­çæ¶èïŒæäŸç»¿å®ç³å®è£
+çææ¯ä¿¡æ¯ïŒ}  
+
+_textdescrgogreenstone_ [l=zh] {åè¯æšç»¿å®ç³èœ¯ä»¶åæ°è¥¿å
+°æ°å­åŸä¹ŠéŠé¡¹ç®}  
+
+_textdescrgodocs_ [l=zh] {ç»¿å®ç³è¯Žæä¹Š}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=zh] {éŠåçé¢}  
+_textdescrgli_ [l=zh] {åž®å©æšäº§çæ°çæ¶èïŒä¿®æ¹ïŒæ·»å æè
+å é€å­åšçæ¶èïŒ}  
+
+package collector
+
+_textcollector_ [l=zh] {æ¶é}  
+_textdescrcollector_ [l=zh] {æ¬å±é¢å
+äºéŠåçé¢ïŒéŠåçé¢æŽå éåäºå€§éšåçå®é
+åºçšïŒ}  
+
+package depositor
+
+_textdepositor_ [l=zh] {æçš¿äºº}  
+_textdescrdepositor_ [l=zh] {æšå¯ä»¥æææ¡£å å
+¥ç°æçæ¶èäž­}  
+
+package gti
+
+_textgti_ [l=zh] {ç»¿å®ç³ç¿»è¯çé¢}  
+_textdescrtranslator_ [l=zh] {åž®å©æšæŽæ°å°ç»¿å®ç³çå€è¯­ç§çšæ·çé¢çææ°çæ¬}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=zh] {å
+³äºæ¬æ¶è}
+
+_textsubcols1_ [l=zh] {<p> æ­€å
+šéšæ¶èç± _1_ subcollections ç»æã 
+å®ä»¬åšïŒ
+<blockquote>}
+
+_textsubcols2_ [l=zh] {</blockquote>
+æšå¯ä»¥åšéé¡¹é¡µæ¥è¯¢ïŒå¹¶ä¿®æ¹ïŒç°äœ¿çšçéã}
+
+_titleabout_ [l=zh] {å
+³äº}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=zh] {å
+³é­æ¬é¡¹}
+_texticonclosedbookshelf_ [l=zh] {æåŒæ¬é¡¹å¹¶äžæµè§å
+å®¹}
+_texticonopenbook_ [l=zh] {å
+³é­æ¬ä¹Š}
+_texticonclosedfolder_ [l=zh] {æåŒæä»¶å€¹å¹¶äžæµè§ç®åœ}
+_texticonclosedfolder2_ [l=zh] {æåŒæ­€èïŒ}
+_texticonopenfolder_ [l=zh] {å
+³é­æä»¶å€¹}
+_texticonopenfolder2_ [l=zh] {å
+³é­æ­€èïŒ}
+_texticonsmalltext_ [l=zh] {æµè§æ­€éšä»œææ¬}
+_texticonsmalltext2_ [l=zh] {æµè§ææ¬ïŒ}
+_texticonpointer_ [l=zh] {æ¬é¡¹}
+_texticondetach_ [l=zh] {åšæ°çªå£æŸç€ºæ¬é¡µ}
+_texticonhighlight_ [l=zh] {çªåºæŸç€ºæ¥è¯¢é¡¹}
+_texticonnohighlight_ [l=zh] {äžèŠçªåºæŸç€ºæ¥è¯¢é¡¹}
+_texticoncontracttoc_ [l=zh] {å
+³é­ç®åœè¡š}
+_texticonexpandtoc_ [l=zh] {æ©å±ç®åœè¡š}
+_texticonexpandtext_ [l=zh] {æŸç€ºææææ¬}
+_texticoncontracttext_ [l=zh] {å¯¹éå®çæ®µèœåªæŸç€ºæå­}
+_texticonwarning_ [l=zh] {<b>è­ŠåïŒ</b>}
+_texticoncont_ [l=zh] {ç»§ç»­ïŒ}
+
+_textltwarning_ [l=zh] {<div class="buttons">_imagecont_</div>
+_iconwarning_å±åŒæ­€ææ¬å°äŒåšæšçæµè§åšæŸç€ºå€§éçå
+å®¹
+}
+
+_textgoto_ [l=zh] {éŸæ¥å°é¡µ}
+_textintro_ [l=zh] {<i>(ä»ç»)</i>}
+
+_textCONTINUE_ [l=zh] {ç»§ç»­ïŒ??}
+
+_textEXPANDTEXT_ [l=zh] {å±åŒææ¬}
+
+_textCONTRACTCONTENTS_ [l=zh] {å
+³é­ç®åœ}
+
+_textDETACH_ [l=zh] {æ°çªå£æŸç€º}
+
+_textEXPANDCONTENTS_ [l=zh] {æåŒç®åœ}
+
+_textCONTRACT_ [l=zh] {å
+³é­ææ¬}
+
+_textHIGHLIGHT_ [l=zh] {çªåºæŸç€º}
+
+_textNOHIGHLIGHT_ [l=zh] {äžçªåºæŸç€º}
+
+_textPRINT_ [l=zh] {æå°}  
+
+_textnextsearchresult_ [l=zh] {äžäžäžªæ¥è¯¢ç»æ}  
+_textprevsearchresult_ [l=zh] {å
+åçæ¥è¯¢ç»æ}  
+
+# macros for printing page
+_textreturnoriginal_ [l=zh] {åå°èµ·å§é¡µ}  
+_textprintpage_ [l=zh] {æå°æ¬é¡µ}  
+_textshowcontents_ [l=zh] {æŸç€ºæ é¢}  
+_texthidecontents_ [l=zh] {éèæ é¢}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=zh] {_If_(_thislast_,results _thisfirst_ - _thislast_ æ¥è¯¢: _cgiargq_,æªåç°: _cgiargq_)}
+_textnoquerytitle_ [l=zh] {æ¥æŸé¡µ}
+
+_textsome_ [l=zh] {éšå}
+_textall_ [l=zh] {å
+šéš}
+_textboolean_ [l=zh] {åžå°}
+_textranked_ [l=zh] {æå}
+_textnatural_ [l=zh] {èªç¶}
+_textsortbyrank_ [l=zh] {å
+³èæå}  
+_texticonsearchhistorybar_ [l=zh] {æ¥è¯¢åå²}
+
+_textifeellucky_ [l=zh] {ææ°äžéïŒ}  
+
+#alt text for query buttons
+_textusequery_ [l=zh] {äœ¿çšæ­€æ¥è¯¢}
+_textfreqmsg1_ [l=zh] {è¯è¯­æ»è®¡ïŒ}
+_textpostprocess_ [l=zh] {_If_(_quotedquery_,<br><i>åå€çå»åç°_quotedquery_</i>
+)}
+_textinvalidquery_ [l=zh] {éæ³çæå¯»è¯­æ³}
+_textstopwordsmsg_ [l=zh] {ä»¥äžçè¯è¯­å€ªæ®éæä»¥çç¥äºïŒ}  
+_textlucenetoomanyclauses_ [l=zh] {æšçæ¥è¯¢æå€ªå€çæ¥è¯¢è¯ïŒè¯·åè¯æŽå ç¡®å®çæ¥è¯¢ã}  
+
+_textmorethan_ [l=zh] {å€äº}
+_textapprox_ [l=zh] {å
+³äº}
+_textnodocs_ [l=zh] {æ²¡æææ¡£ç¬Šåæå¯»æ¡ä»¶ã}
+_text1doc_ [l=zh] {1äžªææ¡£ç¬Šåæ¥è¯¢æ¡ä»¶ã}
+_textlotsdocs_ [l=zh] {äžªææ¡£ç¬Šåæå¯»æ¡ä»¶ã}
+_textmatches_ [l=zh] {ç¬Šå}
+_textbeginsearch_ [l=zh] {åŒå§æ¥è¯¢}
+_textrunquery_ [l=zh] {æ§è¡æ¥è¯¢}
+_textclearform_ [l=zh] {æž
+é€è¡šæ Œ}
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=zh] {è¯æç­å¥}
+_textinfield_ [l=zh] {âŠ åšå}
+_textfoldstem_ [l=zh] {(æä»¶å€¹, ç»å°Ÿ)}
+
+_textadvquery_ [l=zh] {æè
+çŽæ¥èŸå
+¥æ¥è¯¢è¯­å¥ïŒ}
+_textallfields_ [l=zh] {å
+šéš}
+_texttextonly_ [l=zh] {åªéææ¬}
+_textand_ [l=zh] {"äžâè¿ç®}
+_textor_ [l=zh] {æè
+}
+_textandnot_ [l=zh] {âäžåŠâè¿ç®}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=zh] {æ _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_, at _gselection_ level )_If_(_nselection_,in _nselection_ language )æ¥è¯¢å
+å« _querytypeselection_ æé®è¯çè®°åœ}
+
+_textadvancedsearch_ [l=zh] {_indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language )äœ¿çš _querytypeselection_ è¯­å¥æ¥è¯¢}
+
+_textadvancedmgppsearch_ [l=zh] {æ¥è¯¢_indexselection__If_(_jselection_,ïŒå
+³èäº_jselection_ )_If_(_gselection_,ïŒäº_gselection_çº§å«)_If_(_nselection_,ïŒåäº_nselection_è¯­)ïŒå¹¶æ_formquerytypeadvancedselection_æ¬¡åºæŸç€ºç»æ}  
+
+_textadvancedlucenesearch_ [l=zh] {æ¥è¯¢_indexselection__If_(_jselection_,ïŒå
+³èäº_jselection_)_If_(_gselection_,ïŒäº_gselection_çº§å«)_If_(_nselection_,ïŒåäº_nselection_è¯­)_If_(_sfselection_,\,_allowformbreak_ïŒæ_sfselection_æåºç»æ\,) }  
+
+_textformsimplesearch_ [l=zh] {_If_(_jselection_, _jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )ä»¥ _formquerytypesimpleselection_ æ¥è¯¢}
+
+_textformadvancedsearchmgpp_ [l=zh] {æ¥è¯¢_If_(_jselection_,_jselection_ )_If_(_gformselection_,ïŒäº_gformselection_çº§å«)_If_(_nselection_,ïŒåäº_nselection_è¯­)ïŒå¹¶æ_formquerytypeadvancedselection_æ¬¡åºæŸç€ºç»æ
+}  
+
+_textformadvancedsearchlucene_ [l=zh] {æ¥è¯¢_If_(_jselection_,_jselection_)_If_(_gformselection_,ïŒäº_gformselection_çº§å«)_If_(_nselection_,ïŒåäº_nselection_è¯­)_If_(_sfselection_,\,ïŒæ _sfselection_æåºç»æ\,)}  
+
+_textnojsformwarning_ [l=zh] {è­ŠåïŒæšæµè§åšçJavascriptè¢«çŠçšäºã <br>èŠäœ¿çšæ¥è¯¢åèœïŒè¯·å¯çšå®ã}
+_textdatesearch_ [l=zh] {æ¬æ¶èå¯ä»¥ææ¥æèåŽæå
+å«äžäžªç¹å®çæ¥å­æ¥è¿è¡æ¥è¯¢.è¿æ¯æ¥è¯¢çäžé¡¹å¯éæ©åèœ.}
+_textstartdate_ [l=zh] {åŒå§ïŒæéå¶ïŒæ¥æïŒ}
+_textenddate_ [l=zh] {å®ææ¥æïŒ}
+_textbc_ [l=zh] {å
+¬å
+å}
+_textad_ [l=zh] {å
+¬å
+}
+_textexplaineras_ [l=zh] {C.E. å B.C.E æ¯å
+¬å
+(A.D.)åå
+¬å
+å(B.C.)åä¹è¯. è¿äºè¯è¯­è¢«è®€äžºæ¯æåå·®åŒ, è¡šç€º"ç°åš" å"å
+äºç°åš".}
+
+_textstemon_ [l=zh] {ïŒå¿œç¥è¯å°ŸïŒ}
+
+_textsearchhistory_ [l=zh] {æ¥è¯¢åå²}
+
+#text macros for search history
+_textnohistory_ [l=zh] {æ¥è¯¢åå²äžå­åš}
+_texthresult_ [l=zh] {ç»æ}
+_texthresults_ [l=zh] {ç»æ}
+_texthallwords_ [l=zh] {ææè¯è¯­}
+_texthsomewords_ [l=zh] {äžäºè¯è¯­}
+_texthboolean_ [l=zh] {åžå°}
+_texthranked_ [l=zh] {æå}
+_texthcaseon_ [l=zh] {å€§å°åå¿
+é¡»ç¬Šå}
+_texthcaseoff_ [l=zh] {å¿œç¥å€§å°å}
+_texthstemon_ [l=zh] {ç»å°Ÿ}
+_texthstemoff_ [l=zh] {æ ç»å°Ÿ}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=zh] {éé¡¹å·²ç»æä»¥äžè®Ÿå®. è¯·äžèŠäœ¿çšæµè§åšç"åé"é® - è¿æ ·çè¯å°äŒéæ°è®Ÿçœ®éé¡¹. è¯·ç¹å»äžé¢çæ¥é
+æ¡çæé®.
+}
+_textsetprefs_ [l=zh] {è®Ÿçœ®éé¡¹}
+_textsearchprefs_ [l=zh] {æ¥è¯¢éé¡¹}
+_textcollectionprefs_ [l=zh] {æ¶èéé¡¹}
+_textpresentationprefs_ [l=zh] {æŸç€ºéé¡¹}
+_textpreferences_ [l=zh] {éé¡¹}
+_textcasediffs_ [l=zh] {åºåå€§å°åïŒ}
+_textignorecase_ [l=zh] {å¿œç¥å€§å°å}
+_textmatchcase_ [l=zh] {å€§å/å°åå¿
+é¡»ç¬Šå}
+_textwordends_ [l=zh] {è¯ç»å°Ÿ}
+_textstem_ [l=zh] {å¿œç¥è¯ç»å°Ÿ}
+_textnostem_ [l=zh] {å
+šéšè¯å¿
+é¡»ç¬Šå }
+_textaccentdiffs_ [l=zh] {è¯­æ°è¯å·®å«ïŒ}  
+_textignoreaccents_ [l=zh] {å¿œç¥è¯­æ°è¯}  
+_textmatchaccents_ [l=zh] {è¯­é³å­ç¬Šå¿
+é¡»å¹é
+}  
+
+_textprefop_ [l=zh] {æ¥è¯¢æå€äŒ åã
+ã _maxdocoption_ æ¡è®°åœïŒæ¯é¡µæŸç€º
+_hitsperpageoption_ æ¡è®°åœ}
+_textextlink_ [l=zh] {æ¥é
+å€éšçœé¡µïŒ}
+_textintlink_ [l=zh] {åç°æºææ¡£ç±ïŒ}
+_textlanguage_ [l=zh] {çé¢è¯­èšïŒ}
+_textencoding_ [l=zh] {çŒç æ¹åŒïŒ}
+_textformat_ [l=zh] {çé¢æ ŒåŒïŒ}
+_textall_ [l=zh] {å
+šéš}
+_textquerymode_ [l=zh] {æ¥è¯¢æš¡åŒ:}
+_textsimplemode_ [l=zh] {ç®åæ¥è¯¢æ¹åŒ}
+_textadvancedmode_ [l=zh] {é«çº§æ¥è¯¢æ¹åŒ(å¯ä»¥äœ¿çš !ã&ã| åæ¬å·æ¥è¿è¡åžå°æ¥è¯¢)}
+_textlinkinterm_ [l=zh] {ç±äž­éŽé¡µ}
+_textlinkdirect_ [l=zh] {çŽæ¥éŸæ¥å°}
+_textdigitlib_ [l=zh] {æ°å­åŸä¹ŠéŠ}
+_textweb_ [l=zh] {çœ}
+_textgraphical_ [l=zh] {åŸåœ¢}
+_texttextual_ [l=zh] {æå­}
+_textcollectionoption_ [l=zh] {<p>
+äžçº§æ¶èå
+æ¬:
+<br>}
+
+_textsearchtype_ [l=zh] {æ¥è¯¢é£æ ŒïŒ}  
+_textformsearchtype_ [l=zh] {_formnumfieldoption_ åºåæ¥æ}  
+_textplainsearchtype_ [l=zh] {æã_boxsizeoption_ æ®éæ¥è¯¢é¡¹}  
+_textregularbox_ [l=zh] {åäžçº¿}  
+_textlargebox_ [l=zh] {å€§}  
+
+_textrelateddocdisplay_ [l=zh] {æŸç€ºçžå
+³çææ¡£}
+_textsearchhistory_ [l=zh] {æ¥è¯¢åå²}
+_textnohistory_ [l=zh] {æ æ¥è¯¢åå²}
+_texthistorydisplay_ [l=zh] {æŸç€ºè¿å» _historynumrecords_æ¡æ¥è¯¢}
+_textnohistorydisplay_ [l=zh] {äžæŸç€ºæ¥è¯¢åå²}
+
+_textbookoption_ [l=zh] {èæä¹Šæµè§æš¡åŒ}  
+_textbookvieweron_ [l=zh] {æ¯}  
+_textbookvieweroff_ [l=zh] {åŠ}  
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=zh] {æåææ¡£æ}
+_textalsoshowing_ [l=zh] {è¿æŸç€º}
+_textwith_ [l=zh] {æå€ä»¥}
+_textdocsperpage_ [l=zh] {ææ¡£äž­æ¯é¡µ}
+
+_textfilterby_ [l=zh] {ææ¡£å
+å«}
+_textall_ [l=zh] {å
+šéš}
+_textany_ [l=zh] {ä»»äœ}
+_textwords_ [l=zh] {è¯ç}
+_textleaveblank_ [l=zh] {äžéæ­€é¡¹ä»¥è·åŸææææ¡£}
+
+_browsebuttontext_ [l=zh] {âææ¡£æåºâ}
+
+_nodata_ [l=zh] {<i>æ æ°æ®</i>}
+_docs_ [l=zh] {ææ¡£}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=zh] {åž®å©}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=zh] {ç¹å»ã_2_ é®æ _1_ æµè§ææ¡£}  
+
+_textSearchhelp_ [l=zh] {ç¹å»_labelSearch_é®æ¥æ¥è¯¢åºç°åšæ­£æäž­çç¹å«è¯è¯­}  
+_textTohelp_ [l=zh] {ç¹å»ã_labelTo_ãé®æ¥æ "To" æµè§ææ¡£}  
+_textFromhelp_ [l=zh] {ç¹å» _labelFrom_ é®æ¥æïŒä»" å­æ®µæ¥æµè§}  
+_textBrowsehelp_ [l=zh] {æµè§ææ¡£}  
+_textAcronymhelp_ [l=zh] {ç¹å» _labelAcronym_ é®æ¥æè¯å€Žæµè§ææ¡£}  
+_textPhrasehelp_ [l=zh] {ç¹å» _labelPhrase_ æé®æ¥æµè§åšæä»¶äž­åºç°çç­è¯­ïŒå®æ¯äœ¿çš phind ç­è¯­æµè§åšã}  
+
+_texthelptopicstitle_ [l=zh] {ç®åœ}
+
+_textreadingdocs_ [l=zh] {åŠäœé
+è¯»ææ¡£}
+
+_texthelpreadingdocs_ [l=zh] {<p>åœè¿å
+¥æäžææ¡£æ¶ïŒéè¿å°é¢æåŸçæšå°±ç¥éå±å¹æ­£åšæŸç€ºåªäžäžªææ¡£ãæäºæ¶èçå°é¢æèŸ¹æ¯ç®åœè¡šïŒèæäºæ¶èä»
+å
+æ¬ç°åšçé¡µç åå¯ä»¥éæ©åè¿åéçéé¡¹ãç®åœè¡šæ¯å¯æ©å±çïŒåå»æ­€ç®åœè¡šå¯å®ç°æåŒæå
+³é­ææ¡£ïŒåå»é¡¶éšæåŒçææ¡£ä»¥å
+³é­å®ã</p>
+<p>ç®åœè¡šäžé¢æ¯åœåéšä»œçææ¬ïŒåšæ­€ä¹åæäž€äžªç®­å€Žåå«æåäžäžéšä»œæåäžéšä»œææ¬ã</p>
+
+<p>åšå°é¢äžæ¹æäžäžªæé®ïŒåå»<i>âå±åŒææ¬â</i>å³æåŒåœåç« èæä¹Šç®çå
+šéšææ¬ãåå»âæåŒç®åœâæåŒæŽäžªç®åœè¡šïŒæšå¯ä»¥çå°ææç« èçç®åœïŒåå»ââæ°çªå£æŸç€ºâåæåŒåŠäžæµè§çªæŸç€ºè¯¥å±å¹ïŒè¿äžªåèœåšæ³èŠæ¯èŸäžåçä¹Šæåæ¶é
+è¯»äž€æ¬ä¹Šæ¶æ¯åŸæçšçïŒãæåïŒåœæšæ¥è¯¢çæ¶åæ¥è¯¢è¯æ¯çªåºæŸç€ºçïŒ ç¹å»<i>çªåºæŸç€ºæ¥è¯¢é¡¹</i>åæ¶æ¬åèœã
+}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=zh] {æåŒä¹Šæ}
+_texthelpopenbook_ [l=zh] {æåŒ/å
+³é­æ­€ä¹Š}
+_texthelpviewtextsection_ [l=zh] {æµè§åœåç« è}
+_texthelpexpandtext_ [l=zh] {æŸç€ºææææ¬ïŒæäžæŸç€º}
+_texthelpexpandcontents_ [l=zh] {æåŒç®åœïŒæå
+³é­}
+_texthelpdetachpage_ [l=zh] {åšæ°çªå£æåŒæ¬é¡µ}
+_texthelphighlight_ [l=zh] {çªåºæŸç€ºæè
+äžçªåºæŸç€ºæçŽ¢è¯}  
+_texthelpsectionarrows_ [l=zh] {è®¿é®äžäžåå
+}  
+
+
+_texthelpsearchingtitle_ [l=zh] {åŠäœæç¹å®å­æ¥è¯¢}
+
+_texthelpsearching_ [l=zh] {<p>
+ä»æ¥è¯¢é¡µïŒæä»¥äžç®åçæ­¥éª€èŸå
+¥æ¥è¯¢é¡¹ïŒ<p>
+  
+  <ol><li>æææšæ³èŠæ¥è¯¢çæä»¶
+      <li>éæ©æ¯æ¥è¯¢ææå­è¿æ¯éšä»œå­
+      <li>èŸå
+¥èŠæ¥è¯¢çå­
+      <li>åå»âåŒå§æ¥è¯¢â
+  </ol>
+ <p>è¿è¡æ¥è¯¢åïŒç¬¬äžç»ïŒïŒæ¡ç¬Šåæ¥è¯¢æ¡ä»¶çææ¡£çäž»é¢åäŒæŸç€ºåºæ¥ïŒåšæ­€ïŒïŒæ¡ææ¡£ä¹åæäžæé®å¯ä»¥æåäžäžç»ïŒïŒæ¡ææ¡£ïŒä»è¯¥å±å¹äœ å¯çå°äž€äžªæé®ïŒäžäžªæé®æåç¬¬äžç»ïŒïŒæ¡ææ¡£ïŒåŠå€äžäžªæé®çšæ¥è¿åäžäžç»é¢ææ¡£ãåå»ä»»äžææ¡£çé¢åæå
+¶æèŸ¹çå°æé®ïŒå°±å¯è¿è¡é
+è¯»æ­€ææ¡£çè¯Šç»å
+å®¹ã
+
+<p>æå€è¿åïŒïŒïŒæ¡è®°åœïŒåŠèŠæ¹åè¯¥æ°ç®ïŒè¯·åå»é¡µé¢å³äžæ¹çâéé¡¹â
+}
+
+_texthelpquerytermstitle_ [l=zh] {æ¥è¯¢é¡¹}
+_texthelpqueryterms_ [l=zh] {<p>èŸå
+¥å°æ¥è¯¢æ¡äž­çå
+å®¹ïŒå°è¢«èœ¬åæäžäžªå«åæ¥è¯¢é¡¹çåå­éïŒæ¥è¯¢é¡¹å¯ä»¥æ¯æ±å­ãé¿æäŒ¯å­æ¯ææ°å­ïŒæ¥è¯¢é¡¹ä¹éŽä»¥ç©ºæ ŒéŽéãæ¥è¯¢é¡¹äž­çå
+¶ä»çç¬Šå·ïŒäŸåŠæ ç¹ç¬Šå·ïŒåäŒè¢«å¿œç¥ïŒå¹¶è¢«çäœç©ºæ Œå€çïŒå æ­€äžèœæ¥è¯¢å
+å«æ ç¹ç¬Šå·çè¯ã 
+<p>äŸåŠïŒæ¥è¯¢<p>
+    <ul><kbd>    å
+å®¹å
+æ¬ïŒèœ¯ä»¶å·¥çšïŒ1999ïŒ</kbd></ul>
+      <p>äžäžé¢çæ¥è¯¢é¡¹çç»ææ¯çžåç<p>
+      <ul><kbd>å
+å®¹å
+æ¬ïŒèœ¯ä»¶å·¥çš1999</kbd></ul><p>
+}
+
+_texthelpmgppsearching_ [l=zh] {éçšMGPPåŒææå»ºçæ¶èæä»¥äžå ç§çéæ©:
+<ul>
+<li><b>*</b>æ¿ä»£ç¬ŠåšæçŽ¢è¯è¯­çç»å°Ÿå¯ä»¥ç¬Šåææä»¥æ­€æçŽ¢è¯è¯­<b>åŒå§</b>çè¯è¯­, æ¯åŠ. <b>comput*</b> ç¬Šåææä»¥<b>comput</b>åŒå§çè¯è¯­.
+<li><b>/x</b>å¯ä»¥çšäºæçŽ¢è¯è¯­çå æ, æ¯åŠ, åœæåææ¡£çæ¶å, <b>computer/10 science</b> ç» computer æ¯ science 10åçå æ.
+</ul>
+}  
+
+_texthelplucenesearching_ [l=zh] {éçšLuceneåŒææå»ºçæ¶èæå ç§éæ©ã
+<ul>
+<li><b>?</b>æ¿ä»£ç¬Šå¯ä»¥çšäºæ¿ä»£ä»»äœå­ç¬Šã äžŸäŸïŒ
+<b>b?t</b> å¯ä»¥ç¬Šå <b>bet</b>, <b>bit</b> and <b>bat</b> ç­è¯è¯­.
+<li><b>*</b>æ¿ä»£ç¬Šå¯ä»¥çšäºæ¿ä»£äžäžªæè
+å€äžªå­ç¬Š. äžŸäŸ, 
+<b>comput*</b> å¯ä»¥çšäºæ¿ä»£ææ<b>comput</b>åŒå€Žçè¯è¯­.
+</ul>
+è¿äž€äžªæ¿ä»£ç¬Šå¯ä»¥çšäºè¯è¯­çäž­éŽæè
+å°Ÿéš, äœæ¯ä»ä»¬äžå¯ä»¥çšäºæçŽ¢è¯è¯­çåŒå€Ž. }  
+
+_texthelpquerytypetitle_ [l=zh] {æ¥è¯¢ç±»å}
+_texthelpquerytype_ [l=zh] {<p><ul>å¯ä»¥æäž€ç§äžåçæ¹åŒæ¥è¯¢ïŒ<p>
+<li>æ¥è¯¢ææçå­ãåšè¿ç§æ
+åµäžç³»ç»å°æ¥æŸå
+æ¬<b>ææ</b>åšæ¥è¯¢é¡¹æå®çå­çææ¡£ïŒæç« èïŒæ é¢ïŒãç¬Šåæ¡ä»¶çææ¡£å°æé¡ºåºæŸç€ºåšå±å¹äžã
+  <li>æ¥è¯¢éšä»œå­ãç³»ç»ä»
+æ¥æŸå
+å«æ¥è¯¢é¡¹äž­ä»»æäžäžªæå äžªå­çææ¡£ïŒæä»¶æå
+¶äžæ¥è¯¢å
+å®¹æç¬ŠåçšåºŠæ¥æŸç€ºïŒåšå³å®ç¬Šåæ¥è¯¢æ¡ä»¶ççšåºŠæ¶ïŒ
+      <p><ul>
+        <li> ãå
+å«è¶å€çæ¥è¯¢é¡¹çè®°åœïŒå
+¶ç¬Šåçè¶é«ïŒ
+        <li> ãçœè§çæ¥è¯¢é¡¹æ¯åžžè§çæ¥è¯¢é¡¹æŽéèŠïŒ
+        <li> ãç­è®°åœæ¯é¿è®°åœçç¬ŠåççšåºŠé«ã
+      </ul>  <p>åšå¯èœçæ
+åµäžïŒäœ¿çšå°œå¯èœå€çæ¥è¯¢é¡¹ïŒäžäžªå¥å­æè
+äžäžªæ®µèœãåŠæåªç»äžäžªæ¥è¯¢é¡¹ïŒæ¥è¯¢ç»æå°æç
+§å
+¶åšææ¡£äž­åºç°çé¢çè¿è¡æåºã</p>
+}
+
+_texthelpadvancedsearchtitle_ [l=zh] {é«çº§æ¥è¯¢éçš _1_ æçŽ¢åŒæ}  
+
+_texthelpadvancedsearch_ [l=zh] {<p>åŠææšå·²ç»éäž­é«çº§æ¥è¯¢æ¹åŒïŒåšéé¡¹äž­ïŒïŒæ¥è¯¢éé¡¹äŒçšæäžåã}  
+
+_texthelpadvsearchmg_ [l=zh] {åšMGææ¡£äž­çé«çº§æ¥è¯¢æäž€ç§éæ©ïŒ æåºååžå°ã 
+æåºçæ¥è¯¢ååš<a href="\#query-type">_texthelpquerytypetitle_</a>æè¿°çå®å
+šäžæ ·ã
+<p>_texthelpbooleansearch_}  
+
+_texthelpbooleansearch_ [l=zh] {<b>åžå°</b>æ¥è¯¢å
+è®žæšéçš & ("äž"), | ("æè
+"), and ! ("äž")è¿ç®ç¬Š, éçšæ¬å·æ¥è¿è¡æ¥è¯¢ïŒç³»ç»å
+å®çè¿ç®ç¬Šæ¯ | ("æè
+").
+<p>
+æ¯åŠïŒã<b>snail & farming</b> å¯ä»¥æŸå°ææå
+æ¬<b>snail</b>äž<b>farming</b>çææ¡£, è <b>snail | farming</b>å¯ä»¥æŸå°ææå
+æ¬<b>snail</b>æè
+å
+æ¬<b>farming</b>çææ¡£.
+<b>snail !farming</b>å¯ä»¥æŸå°ææå
+æ¬<b>snail</b>ïŒäœæ¯äžå
+æ¬<b>farming</b>çææ¡£.
+<p>
+æŽå€çç²Ÿç¡®çæ¥è¯¢å¯ä»¥éçšæ¬å·åè¿ç®ç¬ŠïŒæ¯åŠ, <b>(sheep | cattle) & (farm | station)</b>, or <b>sheep | cattle | goat !pig</b>.
+}  
+
+_texthelpadvsearchmgpp_ [l=zh] {MGPPçé«çº§æ¥è¯¢æ¹åŒéçšçæ¯åžå°é»èŸè¿ç®ç¬Šã_texthelpbooleansearch_
+<p>ç»æå¯ä»¥<b>æåº</b>æŸç€º, åŠåš<b>éšå</b>æ¥è¯¢äž­<a href="\#query-type">_texthelpquerytypetitle_</a>ææè¿°ç, æè
+æâèªç¶âïŒæè
+âåå»ºâïŒçæåºæŸç€ºã âèªç¶âæåºæ¯æåšåå»ºéŠèæ¶ææ¡£çå€çé¡ºåºã
+<p>
+å
+¶ä»è¿ç®ç¬Šå
+æ¬<b>äžŽè¿x</b>å<b>åºåx</b>ãäžŽè¿xçšäºæå®å¹é
+ææ¡£äž­äž€äžªæ¥è¯¢è¯ä¹éŽçæå€§éŽéïŒxäžªè¯ïŒãåºåxæå®ç¬¬äºäžªæ£çŽ¢è¯å¿
+é¡»åºç°åšç¬¬äžäžªè¯<i>ä¹å</i>çxäžªè¯å
+ãè¿ç±»äŒŒäºé»è¿è¿ç®ç¬ŠäœåŒºè°é¡ºåºçéèŠæ§ãçŒºççè·çŠ»äžº20äžªè¯ã}  
+
+_texthelpadvancedsearchextra_ [l=zh] {æ³šéïŒåŠææšåšç®åæ¥è¯¢äž­ïŒè¿äºè¿ç®ç¬ŠäŒè¢«å
+šéšå¿œç¥ïŒ}  
+
+_texthelpadvsearchlucene_ [l=zh] {åš Lucene æ¶èçé«çº§æçŽ¢äž­äœ¿çšåžå°è¿ç®ã _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=zh] {ææ¡ä»¶çæ¥è¯¢}  
+
+_texthelpformsearch_ [l=zh] {<p>åæ¥è¯¢å¯ä»¥æäŸäžåçâåºåâç»åæ¥è¯¢ããæ¯åŠïŒåšæ é¢äž­æ¥è¯¢"Smith"ååšäž»é¢äž­æ¥è¯¢"snail farming"ããåšç®åæ¥è¯¢äž­ïŒæ¯äžªç»å¯ä»¥æ¯ "äž(AND)"æè
+ "æ(OR)" æ¥è¯¢ããåšé«çº§æ¥è¯¢äž­ïŒãæšå¯ä»¥åšåè¡šäž­å®ä¹äžåçAND/OR/NOT ç»åæ¹åŒïŒãå¹¶äžåšåºåäž­äœ¿çšåžå°è¿ç®ç¬Šå·ïŒã}  
+
+_texthelpformstemming_ [l=zh] {æšå¯ä»¥å®ä¹åšâæä»¶å€¹â åâç»å°Ÿâé¡¹äž­æ¯åŠæ¥è¯¢è¯æå æè
+å»æè¯å°Ÿã è¿äºéé¡¹åšé«çº§æ¥è¯¢åå§çæ¶åæ¯å
+³é­çã}  
+
+_textdatesearch_ [l=zh] {åžŠæ¥ææ¥è¯¢}
+
+_texthelpdatesearch_ [l=zh] {æšå¯ä»¥äœ¿çšæ¥ææ¥è¯¢æ¥æ¥æŸææ¡£åç¬Šååšæäžªæ¶éŽæ®µçäºä»¶ãæšå¯ä»¥ææå¹Žææäºå¹Žè¿è¡æ¥è¯¢ææ¡£ãè¯·æ³šæïŒæšå¯ä»¥ä»
+ä»
+æ¥è¯¢æ¥æèäžçšå
+¶ä»æ¥è¯¢è¯ïŒä¹å¯ä»¥åšæ¥è¯¢äž­äžäœ¿çšæ¥æãåŠææšäžäœ¿çšä»»äœæ¥æïŒé£ä¹ç³»ç»å°±äžäŒè¿è¡æ¥ææ¥è¯¢ã<p>
+}
+
+_texthelpdatehowtotitle_ [l=zh] {åŠäœäœ¿çšè¿é¡¹åèœïŒ}
+_texthelpdatehowto_ [l=zh] {<ul>
+   <li>æ¥è¯¢æå¹Žçææ¡£ïŒ<p>
+   <ul>
+       <li>èŸå
+¥æ­£åžžçæ¥è¯¢è¯ã 
+       <li>åšâåŒå§ïŒæä»
+ïŒæ¥æâé¡¹äž­èŸå
+¥æšéèŠæ¥æŸçå¹Žä»œã
+       <li>åŠææšçæ¥ææ¯å
+¬å
+åïŒè¯·åšæ¥è¯¢é¡¹æçäžæèåäž­éæ©âå
+¬å
+åâéé¡¹ "ã
+       <li>åŒå§æšçæ¥è¯¢ã
+   </ul>
+<p><li>æ¥è¯¢åšè·šè¶å¹Žä»œçææ¡£ïŒ<p>
+   <ul><li>èŸå
+¥æ­£åžžçæ¥è¯¢è¯ã 
+       <li>åšâåŒå§ïŒæä»
+ïŒæ¥æâé¡¹äž­èŸå
+¥æšéèŠæ¥æŸçåŒå§å¹Žä»œã  <li>åšâæªæ­¢æ¥æâé¡¹äž­èŸå
+¥æšéèŠæ¥æŸçæªæ­¢å¹Žä»œã
+       <li>åŠææšçæ¥ææ¯å
+¬å
+åïŒè¯·åšæ¥è¯¢é¡¹æçäžæèåäž­éæ©âå
+¬å
+åâéé¡¹ "ã
+       <li>åŒå§æšçæ¥è¯¢ã
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=zh] {æšçæ¥è¯¢å·¥äœçæ¹æ³}
+_texthelpdateresults_ [l=zh] {äžè¬æ¥è¯ŽïŒæ¥æŸ1903å¹Žçææ¡£çæ¥è¯¢äžäŒåç°ææ¡£ ïŒæ¯åŠè¯ŽïŒåºçäº1903å¹ŽçæåŒä¹ŠïŒïŒ èæŸå°å
+³äº1903çææ¡£ã äœæ¯ïŒææ¡£æ¥æçæ¥è¯¢äŒåç°ææ¡£çæ¥æïŒæ¯åŠ1899-1911ïŒå
+æ¬1903ïŒèäžè¿äºææ¡£çéšåæå­å
+æ¬1903ïŒæ¯åŠ20äžçºªïŒãè¿å°±æå³å¯¹äºæäºææ¡£ïŒæšçæ¥è¯¢æ¥æå°äžäŒåšææ¡£çå
+å®¹éåºç°ã
+å¯¹äºè·šè¶å¹Žä»œæ¥è¯¢ïŒäžé¢çè§£ééçšäºææè·šè¶çæ¥æã<p>
+}
+
+_textchangeprefs_ [l=zh] {ä¿®æ¹æšçéé¡¹}
+
+_texthelppreferences_ [l=zh] {<p>åœç¹å»æ¬é¡µäžéšç<i>éé¡¹</i>ïŒæšå¯ä»¥æ ¹æ®æšçèŠæ±ä¿®æ¹çé¢çæäºç¹æ§ã
+}
+
+_texthelpcollectionprefstitle_ [l=zh] {æ¶èéé¡¹}
+_texthelpcollectionprefs_ [l=zh] {æäºæ¶èç±å äžªäžçº§æ¶èç»æïŒæšå¯ä»¥åç¬æå
+šéšæ¥è¯¢å®ä»¬ã
+æšå¯ä»¥åšéé¡¹é¡µéæ©åéçäžçº§æ¶èæ¥è¿è¡æ¥è¯¢ã
+}
+
+_texthelplanguageprefstitle_ [l=zh] {è¯­èšéé¡¹}
+_texthelplanguageprefs_ [l=zh] {æ¯äžªæ¶èæé¢å
+è®Ÿå®çè¯­èšïŒäœæ¯æšå¯ä»¥éæ©æšåæ¬¢çè¯­èšãæšè¿å¯ä»¥æ¹åç»¿å®ç³èœ¯ä»¶äžºèŸåºå°æµè§åšéçšçé¢è®ŸççŒç ç³»ç»é
+çœ®ïŒäœæ¯æäºæµè§åšå¯ä»¥éçšäžåççŒç ç³»ç»é
+çœ®èè·åŸæŽå¥œçè§è§ææãæçšçæ¶èå
+è®žæšä»æ åçåŸåœ¢çé¢èœ¬å°æå­çé¢ãè¿å¯¹äºè§è§æçŒºé·èäœ¿çšå€§æŸç€ºå­äœæè¯­èšè¯å«åšççšæ·ç¹å«æå¥œå€ã
+}
+
+_texthelppresentationprefstitle_ [l=zh] {è¡šèŸŸæ¹åŒéé¡¹}
+_texthelppresentationprefs_ [l=zh] {å¯¹äºç¹å«çæ¶èïŒæšå¯ä»¥æå ç§éé¡¹æ¥æ§å¶è¡šèŸŸæ¹åŒã
+
+<p>çœé¡µæ¶èå
+è®žäžæŸç€ºç»¿å®ç³èœ¯ä»¶çå¯Œèªæ¡åšæ¯äžªé¡µéŠïŒè¿æ ·æšå¯ä»¥çŽæ¥æµè§æå¹é
+ççœé¡µïŒèäžæŸç€ºä»»äœç»¿å®ç³èœ¯ä»¶çé¡µéŠãæšå¯ä»¥çšæµè§åšçâåéâé®è¿è¡äžäžæ¬¡çæ¥æŸãåœæšç¹å»æäžªè¿æ¥èçŠ»åŒæ°å­åŸä¹ŠéŠçæ¶åïŒè¿äºæ¶èè¿å
+è®žæšäžæŸç€ºç»¿å®ç³èœ¯ä»¶çè­Šåä¿¡æ¯ãåšæäºçœé¡µæ¶èäž­æšå¯ä»¥æ§å¶åš"æ¥è¯¢ç»æ"é¡µæ¯åŠçŽæ¥éŸæ¥å°å®é
+çURL,è¿æ¯æ°å­åŸä¹ŠéŠçå€ä»œ.
+}
+
+_texthelpsearchprefstitle_ [l=zh] {æ¥è¯¢éé¡¹}
+_texthelpsearchprefs_ [l=zh] {<p>äž€å¯¹éé¡¹æ§å¶æ¥è¯¢å¹é
+çæå­.ç¬¬äžå¯¹(æ æ"åºå«å€§å°å")æ§å¶æ¯åŠå€§å°åå¿
+é¡»å¹é
+. ç¬¬äºå¯¹("è¯è¯­ç»å°Ÿ")æ§å¶æ¯åŠå¿œç¥è¯è¯­ç»å°Ÿ. è¿å¯èœè·åŸèŸå€çæ¥è¯¢ç»æ, è¿æ ·çè¯æšå¯ä»¥åŸå®¹æåŸè¿è¡æ®µèœæ¥è¯¢. æšå¯èœäŒå¯¹å€§éçæå­çå¿«éæ¥è¯¢çéåºŠæå°æè®¶.
+
+<p>äŸåŠ,åŠææé®<i>å¿œç¥å€§å°å</i>å
+<i>å¿œç¥è¯è¯­ç»å°Ÿ</i>è¢«éæ©äºçè¯, æ¥è¯¢<p>
+    <ul><kbd>African building</kbd></ul>
+      <p>å°äŒå<p>
+      <ul><kbd>africa builds</kbd></ul>äžæ ·å¯¹åŸ
+.<p>
+      è¿æ¯å äžºå€§åå­ç¬Š"African"å°äŒèœ¬åæå°å, å¹¶äž"African"çç»å°Ÿ"n"å"building"çç»å°Ÿ"ing" å°äŒè¢«å»æ("s" å°äŒä»"builds"äž­è¢«å»æ).
+
+<p>æšå¯ä»¥ä»éçš"é«çº§"æ¥è¯¢æ¹åŒ, å®å
+è®žæšç»åè¯è¯­AND (&), OR (|), å NOT (!)æ¥è¿è¡é«çº§æ¥æŸ. è¿æ ·æšå¯ä»¥å®ä¹æŽç²Ÿç¡®çæ¥è¯¢.æšè¿å¯ä»¥æåŒæ¥è¯¢åå²åèœ, æ¥è¯¢åå²äŒæŸç€ºæšæè¿çå æ¬¡æ¥è¯¢, è¿æ ·å¯ä»¥æŽç®åçè¿è¡åä»¥ååçšåŸ®äžåçæ¥è¯¢. æå,æšå¯ä»¥æ§å¶æ¥è¯¢ç»æçæ°éåæ¯å±æŸç€ºçç»ææ°é.
+}
+
+_textcasefoldprefs_ [l=zh] {äžå¯¹æé®æ§å¶åšæ¥è¯¢çæ¶åæ¯åŠç¬Šåå€§åæè
+å°åã æ¯åŠïŒåŠæâ_preferences:textignorecase_âè¢«éæ©çæ¶åïŒ <i>snail farming</i>å°äŒå¹é
+<i>Snail Farming</i> å<i>SNAIL FARMING</i>}  
+_textstemprefs_ [l=zh] {äžå¯¹æé®æ§å¶åšæ¥è¯¢äž­æ¯åŠå¿œç¥è¯å°Ÿã æ¯åŠïŒåŠæéæ©äº "_preferences:textstem_", <i>snail farming</i> å°äŒå¹é
+ <i>snails farm</i> å <i>snail farmer</i>. è¿ç§æ¹æ³åšè±è¯­äž­å¯ä»¥æ­£åžžäœ¿çš. _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=zh] {äžå¯¹æé®æ§å¶åšæ¥è¯¢çæ¶åæ¯åŠå¹é
+æè¯­é³çå­ç¬Šã æ¯åŠïŒ åŠæéæ©äº"_preferences:textignoreaccents_", <i>fÃ©dÃ©ration</i> å¯ä»¥å¹é
+<i>fedÃ©ration</i> å<i>federation</i>.}  
+ 
+_textstemoptionsprefs_ [l=zh] {äœ¿çšåš"_texthelpquerytermstitle_"æè¿°çæªç­æ¥è¯¢è¯å¯èœäŒæŽå æ¹äŸ¿ååç¡®ïŒ}  
+
+_textsearchtypeprefsplain_ [l=zh] {åšå¯èœçæ
+åµäžïŒäœ¿çšå€§çæ¥è¯¢æ¡ïŒæšå¯ä»¥å®¹æå°è¿è¡äžäžªæ®µèœçæçŽ¢ïŒæ¥æŸå€§éçæå­è®¯æ¯å°ååŸåºä¹ææå°è¿
+éã}  
+
+_textsearchtypeprefsform_ [l=zh] {æšå¯ä»¥æ¹ååšæ¥è¯¢é¡µé¢äž­çæ¥è¯¢åºåçæ°é}  
+
+_textsearchtypeprefsboth_ [l=zh] {æšå¯ä»¥éæ©ïŒæ®éïŒæ¥è¯¢æè
+æ¯ïŒåïŒæ¥è¯¢ïŒ
+<ul>
+<li>æ®éæ¥è¯¢æäŸäžäžªæ¥è¯¢èŸå
+¥å£. _textsearchtypeprefsplain_</li>
+<li>åæ¥è¯¢æäŸå äžªæ¥è¯¢èŸå
+¥å£, æ¯äžäžªå¯ä»¥æ¥è¯¢çŽ¢åŒçäžååºåïŒè¿æ ·æ¥è¯¢å¯ä»¥åæ¶æ£çŽ¢äžåçåºå. _textsearchtypeprefsform_ </li>
+</ul>
+}  
+
+
+
+_texttanumbrowseoptions_ [l=zh] {åšæ¬æ¶èå
+å
+±æ_numbrowseoptions_ç§æ¹æ³æ¥æ¥è¯¢ä¿¡æ¯:}
+
+_textsimplehelpheading_ [l=zh] {åŠäœåš_collectionname_æ¶èå
+æ¥æŸä¿¡æ¯}
+
+_texthelpscopetitle_ [l=zh] {æ¥è¯¢èåŽ}
+_texthelpscope_ [l=zh] {<p>
+æšå¯ä»¥éæ©åšäžåççŽ¢åŒè¿è¡æ¥è¯¢. äŸåŠæäœè
+åæ é¢æ¥è¯¢, æè
+ç« èåæ®µèœçŽ¢åŒãäžè¬æ¥è¯Ž,
+æ è®ºåšä»ä¹èåŽå
+è¿è¡æ¥è¯¢ïŒæ¥è¯¢ç»æéœå°æ¯ç¬ŠåçæŽäžªææ¡£ã<p>åŠæææ¡£æ¯ä¹Šç±çè¯,é£ä¹ææ¡£äŒåšåéçäœçœ®æåŒ.
+}
Index: /gsdl/stable/macros/chinese2.dm
===================================================================
--- /gsdl/stable/macros/chinese2.dm	(revision 20131)
+++ /gsdl/stable/macros/chinese2.dm	(revision 20131)
@@ -0,0 +1,1121 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Simplified Chinese Language text and icon macros 
+# -- this file contains text that is of less importance
+#
+# Contributions made by Kevin Fong
+# 
+######################################################################
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=zh] {æä»¶ã}  
+_lastupdate_ [l=zh] {æè¿æŽæ°ç}  
+_ago_ [l=zh] {å å€©åã}  
+_colnotbuilt_ [l=zh] {æ¶èæ²¡æåå»ºã}  
+
+### taken from here
+
+_textpoem_ [l=zh] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>may peace and calmness surround you,
+<br>may you reside in the warmth of a summer's haze,
+<br>may the ocean of your travels be as smooth as the polished greenstone.}  
+
+_textgreenstone_ [l=zh] {<p>Greenstoneæ¯äžç§äº§äºæ°è¥¿å
+°çç»¿å®ç³ïŒå°±åè¿å¥èœ¯ä»¶ïŒãåšäŒ ç»çæ¯å©ç€ŸäŒäž­ïŒå®æ¯åšææç©èŽšäž­æçèŽµåæåæ¬¢è¿çãå®å¯ä»¥åžæ¶åä¿ç<i>wairua</i>ïŒäžç§ç²Ÿç¥æçåœåïŒäžèµæäŒ ç»çŸåŸ·çç¹æ§äœ¿å®æäžºå
+¬å
+±é¢åæ°å­åŸä¹ŠéŠè®¡åçåŸœç« ãå®çå
+æ³œä»£è¡šæ
+åïŒå®çééä»£è¡šè¯å®ïŒå®çåç¡¬ä»£è¡šåæ°ïŒå®æèœæ¿åçå©åä»£è¡šæ­£ä¹ãç»¿å®ç³æ°å­åŸä¹ŠéŠèœ¯ä»¶æ å¿äž­éå»ç<i>patu</i>ææå»çæ£æ£æ¯æä»¬è¿äžªè®¡åäž­äžäœæåçäŒ å®¶å®ãåšåŸæææäž­å®çè¡šç°æ¯éåžžå¿«éïŒç²Ÿç¡®åå®æŽçãæä»¬åžææä»¬çèœ¯ä»¶ä¹æ¥æè¿äºç¹èŽšïŒ<i>patu</i>é£ååäŒŒçéå©èŸ¹çŒè±¡åŸçææ¯çåçŒã</p>}  
+
+_textaboutgreenstone_ [l=zh] {<p>ç»¿å®ç³ïŒGreenstoneïŒæ°å­åŸä¹ŠéŠèœ¯ä»¶æ¯å»ºç«äžååæ°å­åŸä¹ŠéŠéŠèçèœ¯ä»¶å¥ä»¶ïŒå®æäŸç»ç»ä¿¡æ¯äžéè¿äºèçœæå
+çåºççæ°éåŸãç»¿å®ç³ç±<b>æå¡æå€§å­Š</b>ç<b>æ°è¥¿å
+°æ°å­åŸä¹ŠéŠé¡¹ç®ç»</b>å¶äœïŒåæ¶äž<b>èååœæè²ç§ææåç»ç»ïŒUNESCOïŒ</b>åäººç±»ä¿¡æ¯éæ¿åºç»ç»ïŒHuman Info NGOïŒåäœåŒåäžåè¡ãå®æ¯åšGNUéçšå
+¬å
+±è®žå¯æ¡æ¬ŸäžååžçåŒæºå€è¯­ç§èœ¯ä»¶ïŒå¯ä»<a href="http://greenstone.org">http://greenstone.org</a>è·åŸã
+</p>
+
+<p>è¿èœ¯ä»¶æ¯éå¯¹äºææççšæ·ïŒç¹å«æ¯åšå€§å­ŠïŒåŸä¹ŠéŠåå
+¶ä»çå
+¬å
+±æå¡æºææ¥åå»ºä»ä»¬èªå·±çæ°å­åŸä¹ŠéŠãæ°å­åŸä¹ŠéŠæ­£åšåœ»åºçåé©åŠäœè®©äžçåå°ïŒå°€å
+¶æ¯åå±äž­åœå®¶äž­çïŒäžUNESCOåäœçæè²ãç§å­Šåæåé¢åçç€Ÿåºäžæºæååžäžè·åä¿¡æ¯ãæä»¬åžææ­€èœ¯ä»¶èœä¿è¿æ°å­åŸä¹ŠéŠçææåŒåå±ïŒä»¥åäº«ä¿¡æ¯å¹¶å°å
+¶æŸçœ®åšå
+¬å
+±é¢åã
+</p>
+
+<p>è¿èœ¯ä»¶æ¯äº2000å¹Ž8æåšäžæ¹åœé
+åäœåªåå»ºç«äžè¢«åŒååååžçã
+</p>
+
+<p>
+<a href="http://nzdl.org"><b>æå¡æå€§å­Šçæ°è¥¿å
+°æ°å­åŸä¹ŠéŠé¡¹ç®</b></a>
+<br>
+ç»¿å®ç³ç³»ç»èœ¯ä»¶åšè¿äžªå·¥çšäž­èèœïŒèå®çåèµ·æ¯ç±æ°è¥¿å
+°åœå®¶å§ä»»ç»äºUNESCOçä¿¡æ¯å¯å§ä»»åŠæ°è¥¿å
+°èŽ¡ç®å°UNESCOçé¡¹ç®ã
+</p>
+
+<p>
+<a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+class="logo"></a>
+<a href="http://www.unesco.org"><b>èååœæè²ç§å­Šæåç»ç»</b></a>
+<br>
+éè¿å
+šäžçæè²ç§å­Šæåä¿¡æ¯çååžïŒç¹å«æ¯å¯¹åå±äž­åœå®¶çå©çïŒæ¯UNESCOåšåæ¿åºéŽè¿œæ±çäž­å¿ç®æ ãåšæ­€è®®é¢äžïŒéåœå¯åŸçä¿¡æ¯äŒ æ­ç§æå·¥å
+·äºŠæ¯åç­éèŠã
+</p>
+
+<p>
+<a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>äººç±»ä¿¡æ¯éæ¿åºç»ç»ïŒåºäºæ¯å©æ¶çå®ç¹å«æ®</b></a>
+<br>
+æ­€è®¡åäžèååœæºæåå
+¶ä»éæ¿åºç»ç»åäœïŒå¹¶åšæ°å­åäººç±»åå±è®®é¢äžå»ºç«äºäžçå£°èªïŒäžäœå°äººç±»åå±çå©çæ°å­åïŒå¹¶å°å
+¶å¹¿æ³æ®åïŒäŸåå±äž­åœå®¶å
+èŽ¹è·åïŒå¯¹å
+¶ä»åœå®¶ä¹èçäºç»èŽ¹ã
+</p>
+}  
+
+
+_textdescrselcol_ [l=zh] {éæ©äžäžªæ¶è}  
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=zh] {æ­€å€åšéŠé¡µäŒæåäžªæé®}  
+
+_textnocollections_ [l=zh] {<p>åšè¿ç»¿å®ç³ç³»ç»çå®è£
+äž­æ²¡æç°å­å¯çšçæ¶èã 
+äžºäºæ·»å äžäºæ¶èæšå¯ä»¥
+<ul><li>äœ¿çš<a href="_httppagecollector_">åå»ºè
+</a>æ¥å»ºç«æ°çæ¶è
+    <li>åŠææšæç»¿å®ç³çå
+ççïŒæšå¯ä»¥ä»å
+çäž­å®è£
+æ¶è
+</ul>}  
+
+_text1coll_ [l=zh] {æ­€Greensstoneçå®è£
+å
+å« 1 äžªæ¶è}  
+
+_textmorecolls_ [l=zh] {æ­€ç»¿å®ç³ç³»ç»çå®è£
+å
+æ¬_1_äžªæ¶è}  
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=zh] {å€éšéŸæ¥}  
+_textlinknotfound_ [l=zh] {æŸäžå°å
+éšéŸæ¥}  
+
+_textextlinkcontent_ [l=zh] {æšéæ©çè¿äžªéŸæ¥æ¯å°ä»»äœäžäžªæšæè¿éæ©çæ¶èçå€éšéŸæ¥ãåŠææšä»ç¶æ³æ¥çè¿äžªéŸæ¥åæšçæµè§åšå·²ç»åšè®¿é®è¿äžªçœé¡µïŒæšå¯ä»¥<a href="_nexturl_">åè¿</a>å°è¿é¡µé¢ïŒåŠåçšæšçæµè§åšçâè¿åâæé®éåå°ä¹åçæä»¶ã}  
+
+_textlinknotfoundcontent_ [l=zh] {åšæšæ§å¶çåå äžïŒæšéæ©çå
+éšéŸæ¥äžå­åšãè¿å¯èœç±äºæ¥æºæ¶èäž­çäžäžªéè¯¯ãçšæšçæµè§åšçâè¿åâæé®éåå°ä¹åçæä»¶ã}  
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=zh] {<h3>è¿æ¥å°æ¶èâ_2_â</h3>
+
+<p>æšéæ©çéŸæ¥æ¯å°æ¶èâ_collectionname_âçäžäžªå€éšéŸæ¥ïŒå®æ¯è¿æ¥å°æ¶èâ_2_âïŒãåŠææšæ³æ¥çåšæ¶èâ_2_âçè¿äžªéŸæ¥ïŒæšå¯ä»¥<a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">åè¿</a> å°è¿äžªé¡µé¢ïŒåŠåçšæšçæµè§åšçâè¿åâæé®éåå°ä¹åçæä»¶ã}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=zh] {ç»¿å®ç³æ°å­åŸä¹ŠéŠ}  
+
+_textusername_ [l=zh] {çšæ·å}  
+_textpassword_ [l=zh] {å¯ç }  
+
+_textmustbelongtogroup_ [l=zh] {æ³šææšå¿
+é¡»æ¯å±äºâ_cgiargug_âç»æèœè®¿é®æ­€é¡µé¢}  
+
+_textmessageinvalid_ [l=zh] {<br>)
+è¯·èŸå
+¥æšç»¿å®ç³ç³»ç»ççšæ·ååå¯ç ã}  
+
+_textmessagefailed_ [l=zh] {æšèŸå
+¥ççšæ·åæå¯ç äžæ­£ç¡®ã}  
+
+_textmessagedisabled_ [l=zh] {åŸæ±æ­ïŒæšçåžå·äžèœäœ¿çšãè¯·èç»æ­€çœç«çç«ç¹ç®¡çåã}  
+
+_textmessagepermissiondenied_ [l=zh] {åŸæ±æ­,æšæ²¡æè¶³å€çæéè®¿é®è¿äžªé¡µé¢ã}  
+
+_textmessagestalekey_ [l=zh] {æšä»äºçéŸæ¥ç°å·²å€±æã
+è¯·èŸå
+¥æšçå¯ç æ¥è®¿é®æ­€é¡µé¢ã}  
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=zh] {<p>è¿äžªç»¿å®ç³ç³»ç»çå®è£
+äžå
+æ¬ä»»äœçæä»¶è®°åœãè¿å¯èœæ¯å äžºïŒ
+<ol>
+ <li>ç»¿å®ç³ç³»ç»æ¯çšæ¥èªå
+ççå°åå®è£
+å
+å®è£
+çã
+ <li>ç»¿å®ç³ç³»ç»æ¯çšæ¥èªäºèçœäžèœœçäžäžªåè¡çæ¬å
+å®è£
+çã
+</ol>
+åšä»»äœäžäžªæ
+åµæšå¯èœä»ç»¿å®ç³çå
+çäž­ç<i>docs</i>ç®åœäž­æè
+è®¿é®<a href="http://www.greenstone.org">http://www.greenstone.org</a>åŸå°æä»¶è®°åœã}  
+
+_textuserguide_ [l=zh] {äœ¿çšæå}  
+_textinstallerguide_ [l=zh] {å®è£
+è
+æå}  
+_textdeveloperguide_ [l=zh] {åŒåè
+æå}  
+_textpaperguide_ [l=zh] {ä»æä»¶å°æ¶è}  
+_textorganizerguide_ [l=zh] {äœ¿çšç»ç»è
+}  
+
+_textgsdocstitle_ [l=zh] {ç»¿å®ç³æä»¶è®°åœ}  
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=zh] {åå»ºæ¶è}  
+_textbildsuc_ [l=zh] {æ¶èåå»ºæåã}  
+_textviewbildsummary_ [l=zh] {æšå¯ä»¥<a href="_httppagex_(bsummary)" target=_top>æ¥çåå»ºçæèŠ</a>ç¥éæ­€æ¶èçæŽå€è¯Šç»èµæã
+}  
+_textview_ [l=zh] {æ¥çæ¶è}  
+
+_textbild1_ [l=zh] {æ­€æ¶èæ­£åšè¢«åå»ºäž­ïŒè¿å¯èœäŒè±äžäºæ¶éŽæ¥å®æãäžé¢çåå»ºç¶æçº¿æäŸäºå
+³äºæäœåŠäœåšå€ççåéŠã}  
+
+_textbild2_ [l=zh] {åšä»»äœæ¶éŽåæ­¢åå»ºå€çïŒç¹å»è¿éã<br>æšæ­£åšåçæ¶èäŒå®æŽæ çŒºå°ä¿çã}  
+
+_textstopbuild_ [l=zh] {åæ­¢åå»º}  
+
+_textbild3_ [l=zh] {åŠææšå©äžè¿é¡µé¢ïŒåæ²¡æçšâåæ­¢åå»ºâçæé®æ¥åæ¶åå»ºïŒæ¶èäŒç»§ç»­åå»ºååšé¡ºå©å®ææ¶è¢«å®è£
+ã}  
+
+_textbuildcancelled_ [l=zh] {åæ¶åå»º}  
+
+_textbildcancel1_ [l=zh] {æ¶èçåå»ºå€çå·²è¢«åæ¶ãäœ¿çšäžé¢çé»è²æé®æ¥å¯¹æšçæ¶èåä¿®æ¹æéæ°åŒå§åå»ºå€çã}  
+
+_textbsupdate1_ [l=zh] {åå»ºç¶æåšäžç§å
+æŽæ°}  
+_textbsupdate2_ [l=zh] {åå»ºç¶ææŽæ°}  
+_textseconds_ [l=zh] {ç¬¬äº}  
+
+_textfailmsg11_ [l=zh] {å äžºè¿æ¶èæ²¡æå
+å«ä»»äœæ°æ®ïŒäžèœè¢«åå»ºãè¯·ç¡®å®è³å°äžäžªæšæå®çç®åœææ¡£æ¡<i>åå§æ°æ®</i>é¡µé¢å­åšåæ¯äžäžªç±»åæè
+ïŒåšäžäžªç®åœçæ
+åµäžïŒå
+å«å€äžªç»¿å®ç³ç³»ç»èœå€ççåç±»åæ¡£æ¡ã}  
+
+_textfailmsg21_ [l=zh] {æ­€æ¶èäžèœè¢«å»ºç«(import.pl failed)ã}  
+_textfailmsg31_ [l=zh] {æ­€æ¶èäžèœè¢«åå»ºçïŒbuildcol.plå€±èŽ¥ïŒã}  
+_textfailmsg41_ [l=zh] {æ­€æ¶èå·²è¢«æåå°åå»ºäœäžèœè¢«å®è£
+ã}  
+_textfailmsg71_ [l=zh] {åœå°è¯åå»ºæšçæ¶èæ¶æäžäžªäžå¯é¢æçéè¯¯åºç°}  
+
+
+_textblcont_ [l=zh] {åå»ºæ¥å¿å
+å«ä»¥äžä¿¡æ¯ïŒ}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=zh] {é»è®€ç»æ}  
+_textmore_ [l=zh] {æŽå€}  
+_textinfo_ [l=zh] {æ¶èä¿¡æ¯}  
+_textsrce_ [l=zh] {æ¥æºæ°æ®}  
+_textconf_ [l=zh] {é
+çœ®æ¶è}  
+_textdel_ [l=zh] {å é€æ¶è}  
+_textexpt_ [l=zh] {å¯Œåºæ¶è}  
+
+_textdownloadingfiles_ [l=zh] {äžèœœæ¡£æ¡äž­âŠ}  
+_textimportingcollection_ [l=zh] {å¯Œå
+¥æ¶èäž­âŠ}  
+_textbuildingcollection_ [l=zh] {æ¶èå»ºç«äž­ ...}  
+_textcreatingcollection_ [l=zh] {åå»ºæ¶èäž­âŠ}  
+
+_textcollectorblurb_ [l=zh] {<i>ç¬æ¯åæŽåŒºå€§ïŒ
+<br>åå»ºåååžä¿¡æ¯æ¶èæ¿èœœçäžå®çèèŽ£ïŒè¿äºèèŽ£éèŠåšåŒå§ä¹åå ä»¥èèã
+æå
+³äºçæçæ³åŸé®é¢ïŒèœå€è®¿é®æä»¶å¹¶äžæå³çæšå¯ä»¥å°è¿äºæä»¶ç»äºå
+¶ä»äººã
+æç€ŸäŒé®é¢ïŒæ¶èåºè¯¥å°éæä»¶æååºçç€ŸäŒçé£ä¿ä¹ æ¯ã
+è¿æéåŸ·é®é¢ïŒæäºäžè¥¿æ¬èº«å°±äžåºè¯¥è¢«å
+¶ä»äººè·åŸã
+<br>èŠå¯¹ä¿¡æ¯çåéææå¹¶äžææºå°äœ¿çšä¿¡æ¯ã
+</i>}  
+
+_textcb1_ [l=zh] {åå»ºè
+å¯ä»¥åž®æšåå»ºæ°çæ¶èïŒä¿®æ¹ææ·»å ç°å­çæ¶èïŒåæè
+å é€æ¶èãæšäŒè¢«äžäžªç³»åèŠæ±éèŠä¿¡æ¯ççœé¡µææå¯Œæ¥å®ç°ã}  
+
+_textcb2_ [l=zh] {éŠå
+ïŒæšå¿
+é¡»å³å®æ¯åŠ}  
+_textcnc_ [l=zh] {åå»ºæ°æ¶è}  
+_textwec_ [l=zh] {å¯¹ç°å­çæ¶èè¿è¡æ·»å æ°æ®æè
+å é€ã}  
+
+_textcb3_ [l=zh] {äžºäºåå»ºæè
+ä¿®æ¹æ°å­åŸä¹ŠéŠæ¶èïŒæšå¿
+é¡»å
+ç»åœãè¿æ¯äžºäºé²èå«äººç»åœæšççµèååšä¿®æ¹ä¿¡æ¯ãæ³šæïŒäžºäºå®å
+šçåå ïŒä»æšç»åœååŒå§æ¯30åéè¿å»åæšäŒèªåšå°ç»åºãåŠæè¿åçäºïŒäžçšæ
+å¿ïŒ-æšäŒè¢«éè¯·åæ¬¡ç»åœåå¯ä»¥ç»§ç»­æšçå·¥äœã}  
+
+_textcb4_ [l=zh] {è¯·èŸå
+¥æšçç»¿å®ç³çšæ·ååå¯ç ïŒç¶åç¹å»æé®æ¥ç»åœã}  
+
+_textfsc_ [l=zh] {éŠå
+éæ©æšæ³ç»§ç»­è¿è¡çæ¶èïŒæåå
+¥ä¿æ€çæ¶èäžäŒåºç°åšè¿äžªåè¡šäž­ïŒã}  
+
+_textwtc_ [l=zh] {å
+³äºæšæéæ©çæ¶èïŒæšå¯ä»¥}  
+_textamd_ [l=zh] {æ·»å æ°æ®åéå»ºæ¶è}  
+_textetc_ [l=zh] {çŒèŸæ¶èçé
+çœ®æ¡£æ¡åéæ°åå»ºæ­€æ¶è}  
+_textdtc_ [l=zh] {å®å
+šå é€æ¶è}  
+_textetcfcd_ [l=zh] {åå
+¥äžäžªèªæå®è£
+çWindowså
+çæ¥å¯Œåºæ¶è}  
+_textcaec_ [l=zh] {æ¹åç°å­çæ¶è}  
+_textnwec_ [l=zh] {æ²¡æå¯åå
+¥çæ¶èå¯ä»¥ä¿®æ¹}  
+_textcianc_ [l=zh] {æ°å»ºæ¶è}  
+_texttsosn_ [l=zh] {éèŠåå»ºäžäžªæ°æ°å­åŸä¹ŠéŠæ¶èçé¡ºåºæ­¥éª€æ¯ïŒ}  
+_textsin_ [l=zh] {æå®å®çåå­ïŒåçžå
+³ä¿¡æ¯ïŒ}  
+_textswts_ [l=zh] {æå®åå§æ°æ®çæ¥æº}  
+_textatco_ [l=zh] {è°æŽé
+çœ®éé¡¹ïŒåªéé«çº§çšæ·ïŒ}  
+_textbtc_ [l=zh] {âåå»ºâè¿äžªæ¶èïŒè§äžæïŒ}  
+_textpvyh_ [l=zh] {åŸèªè±ªå°æ¥çæšçæå·¥èº}  
+
+_texttfsiw_ [l=zh] {ç¬¬åæ­¥æ¯è®¡ç®æºå€çæææäœçæåšãåšâå»ºç«âè¿çšäž­ïŒè®¡ç®æºå¶é åºææççŽ¢åŒåæä»»äœèœä»€å
+¶è¿è¡çå
+¶ä»ä¿¡æ¯éååšäžèµ·ãäœæšèŠå
+æå®é£äºä¿¡æ¯ã}  
+
+_textadab_ [l=zh] {åšäžé¢æŸç€ºçåŸè¡šäŒåž®å©æšæçœæšæåšçå°æ¹ãæšå¯ä»¥äŸæ¬¡å°ç¹å»é£ç»¿è²æé®æ¥ç»§ç»­åŒå±ãåœæšæé¡ºåºä»ç»æ£æ¥å®åïŒé£äºæé®äŒåæé»è²ãæšå¯ä»¥åšåŸè¡šäž­ç¹å»çžåºçé»è²æé®åå°ä¹åçé¡µé¢ã}  
+
+_textwyar_ [l=zh] {åœæšåå€å®æ¯ïŒç¹å»ç»¿è²æé®âæ¶èä¿¡æ¯âæ¥åŒå§åå»ºæšæ°çæ°å­åŸä¹ŠéŠæ¶èïŒ}  
+
+_textcnmbs_ [l=zh] {å¿
+é¡»æå®æ¶èçåå­}  
+_texteambs_ [l=zh] {å¿
+é¡»æå®çµå­é®ç®±å°å}  
+_textpsea_ [l=zh] {è¯·æå®çµå­é®ä»¶å°åäºè¿ç§åœ¢åŒïŒçšæ·å@åå}  
+_textdocmbs_ [l=zh] {æ¶èçæè¿°å¿
+é¡»è¢«è¯Šç»è¯Žæ}  
+
+_textwcanc_ [l=zh] {åœå»ºç«äžäžªæ°çæ¶èæ¶ïŒæšéèŠèŸå
+¥äžäºåå§èµæçåæ­¥æ°æ®ãè¿äžªè¿çšæ¯è¢«å»ºç«æäžç³»ååšæ¶èå®¶æ£æ¥äžççœé¡µé¡µé¢ãåšé¡µé¢åºéšçæ å¯ä»¥æŸç€ºåºå·²ç»å®æé¡µé¢çé¡ºåºã}  
+
+_texttfc_ [l=zh] {æ¶èçæ é¢ïŒ}  
+
+_texttctiasp_ [l=zh] {æ¶èçæ é¢æ¯äžäžªéåæŽäžªæ°å­åŸä¹ŠéŠçç­è¯­ïŒçšæ¥è¯å«æ¶èçå
+å®¹ãå®äŸçæ é¢å
+æ¬æ"Computer Science Technical Reports"å"Humanity Development Library"ã
+}  
+
+_textcea_ [l=zh] {èç³»çµå­é®ä»¶å°åïŒ}  
+
+_textteas_ [l=zh] {è¿äžªçµå­é®ä»¶å°åæå®æ¶èçç¬¬äžäžªèç»ç¹ãåŠæç»¿å®ç³èœ¯ä»¶äŸŠæ¥å°äžäžªé®é¢ïŒäžäžªè¯æ­æ¥åäŒè¢«åéå°è¿äžªå°åãèŸå
+¥äžäžªå®æŽåœ¢åŒççµå­é®ä»¶å°åïŒ<tt>åå­@åå</tt>ã}  
+
+_textatc_ [l=zh] {å
+³äºæ­€æ¶èïŒ}  
+
+_texttiasd_ [l=zh] {è¿æ¯äžäžªæè¿°å
+æ¬åšæ¶èäž­çç®¡çæ³åçå£°æãåœæ¶èåç°æ¶å®äŒåºç°åšç¬¬äžäžªé¡µé¢ã}  
+
+_textypits_ [l=zh] {åšäžé¢çç®­å€ŽäŒæåºäœ é¡ºæ¬¡çäœçœ®--åšè¿ç§æ
+åµäžïŒæ¯"collection information"çé¶æ®µãç¹å»ç»¿è²æé®"source data"æ¥ç»§ç»­è¿è¡ã}  
+
+_srcebadsources_ [l=zh] {<p>äœ æå®çäžäžªæå€äžªçèŸå
+¥æ¥æºèµææ¯äžå¯çšç(åšäžé¢æ è®°äžº_iconcross_)ã
+
+<p>è¿å¯èœæ¯å äžº
+<ul>
+<li>æ¡£æ¡ïŒFTPç«ç¹æURLäžå­åšã
+<li>äœ éŠå
+éèŠè¿æ¥äœ ççœç»äŸåºåã
+<li>äœ æ­£åšå°è¯ä»é²ç«å¢åé¢è®¿é®äžäžªURL(åŠæäœ å¿
+é¡»æ­£åžžå°èŸå
+¥çšæ·ååå¯ç æ¥è®¿é®äºèçœå°±æ¯è¿ç§æ
+åµ)ã
+</ul>
+
+<p>åŠæè¿æ¯äœ èœåšæµè§åšçå°çURLïŒå¯èœæ¥èªäºäžäžªæ¬å°ççŒå²å¯æ¬ãäžå¹žçæ¯ïŒæ¬å°ççŒå²å¯æ¬æ¯æä»¬çéåå€çè¿çšäž­æ¯äžå¯è§çãåšè¿ç§æ
+åµäžæä»¬å»ºè®®äœ å
+çšæµè§åšäžèœœè¿äºé¡µé¢ã}  
+
+_textymbyco_ [l=zh] {<p>æšçéŠèå¯ä»¥åšä»¥äžéæ©çåºç¡äžæå»ºïŒ
+<ul>
+<li>çŒºçç»æ
+<dl><dd>æ°å»ºçéŠèå¯å
+å«ä»¥äžæ ŒåŒçæä»¶ïŒHTMLïŒçº¯ææ¬ææ¡£ïŒâm-boxâæ ŒåŒççµå­é®ä»¶ææ¡£ïŒPDFïŒRTFïŒMS WordïŒPostScriptïŒPowerPointïŒExcelïŒåŸçïŒCDS/ISISã</dd></dl>
+<li>äžäžªç°å­çéŠè
+<dl><dd>æ°å»ºéŠèäž­çæä»¶ç±»åå¿
+é¡»äžç°å­éŠèäž­çæä»¶ç±»åäžèŽã</dd></dl>
+</ul>}  
+
+_textbtco_ [l=zh] {æ¶èå»ºç«äº}  
+_textand_ [l=zh] {æ·»å æ°æ°æ®}  
+_textad_ [l=zh] {æ·»å æ°æ®ïŒ}  
+
+_texttftysb_ [l=zh] {äœ åšäžé¢æå®çæä»¶äŒè¢«å å
+¥å°æ¶èãç¡®å®äœ æ²¡æéå€æå®å·²ç»åšæ¶èéçæ¡£æ¡ïŒåŠåäŒå
+æ¬äž€ä»œå¯æ¬ãå
+šè·¯åŸåäŒè¯å«è¿äºæ¡£æ¡ïŒçœé¡µç±ç»å¯¹é¡µé¢å°åæ¥è®°åœã}  
+
+_textis_ [l=zh] {èŸå
+¥æ¥æºèµæïŒ}  
+
+_textddd1_ [l=zh] {<p>åŠææšçšfile://æè
+ftp://æ¥æå®äžäžªæ¡£æ¡ïŒé£æ¡£æ¡å°äŒè¢«äžèœœã
+
+<p>åŠææšäœ¿çšhttp://ïŒå®åå³äºé£URLæ¯åŠèœç»æšçæµè§åšäžäžªæ­£åžžççœé¡µïŒæè
+äžäžªæ¡£æ¡çåè¡šãåŠææ¯äžäžªé¡µé¢ïŒé£é¡µé¢å°äŒè¢«äžèœœã -- ä»¥åææè¿æ¥è¿é¡µé¢åè¿é¡µé¢è¿æ¥å°çéŸæ¥ç­ç­ -- æäŸä»ä»¬åšURLäžäžæ ·çç«ç¹ã
+
+<p>åŠææšäœ¿çšfile://æè
+ftp://æ¥æå®äžäžªæä»¶å€¹æè
+ç®åœïŒææäŸäžäžªèœåŒå¯Œåºäžäžªæ¡£æ¡åè¡šçhttp:// URLïŒææåšæä»¶å€¹çäžè¥¿åå®çæä»¥å­æä»¶å€¹éœäŒè¢«å
+å«åšè¿äžªæ¶èäž­ã
+
+<p>ç¹å»âæŽå€æ¥æºèµæâæé®æ¥æ·»å æŽå€çèŸå
+¥ç©ºæ Œã}  
+
+_textddd2_ [l=zh] {<p>ç¹å»å
+¶äž­äžäžªç»¿æé®ãåŠææšæ¯é«çº§çšæ·ïŒæšå¯èœæ³è°æŽæ¶èçé
+çœ®ãåäžºéæ©ïŒçŽæ¥å°åå»ºé¶æ®µãè®°äœïŒæšéæ¶éœå¯ä»¥ç¹å»å®çé»è²æé®æ¥éæ°è®¿é®ä¹åçé¶æ®µã}  
+
+_textconf1_ [l=zh] {<p>æšæ¶èçåå»ºåè¡šèŸŸéœè¢«æ§å¶åšäžäžªç¹å«çâé
+çœ®æä»¶âéçè¯Žæä¹Šãé«çº§çšæ·å¯èœæ³ä¿®æ¹é£äºé
+çœ®çè®Ÿå®ã
+
+<center><p><b>åŠææšäžæ¯äžäžªé«çº§çšæ·ïŒåªéå°è¿é¡µé¢çåºéšã</b></center> 
+
+<p>äžºäºä¿®æ¹é
+çœ®çè®Ÿå®ïŒçŒèŸåºç°åšäžé¢çæ°æ®ãåŠææšåäºäžäžªéè¯¯çéæ©ïŒç¹å»âéçœ®âæ¥æ¢å€å°åå§çé
+çœ®è®Ÿå®ã}  
+
+_textreset_ [l=zh] {éçœ®}  
+
+
+_texttryagain_ [l=zh] {è¯·<a href="_httppagecollector_" target=_top>éæ°å¯åšæ¶èè
+</a>ååå°è¯ã }  
+
+
+_textretcoll_ [l=zh] {åå°æ¶èè
+}  
+
+_textdelperm_ [l=zh] {æ¶è_cgiargbc1dirname_çéšä»œæè
+å
+šéšäžèœè¢«å é€ãåå å¯èœæïŒ
+<ul>
+<li>ç»¿å®ç³ç³»ç»æ²¡ææéæ¥å é€_gsdlhome_/collect/_cgiargbc1dirname_ç®åœã<br>
+æšå¯èœéèŠæåšç§»é€è¿äžªç®åœæ¥å®ææ¶è_cgiargbc1dirname_ä»è¿éšçµèäž­çç§»é€ã</li>
+<li>ç»¿å®ç³ç³»ç»äžèœè¿è¡çšåº_gsdlhome_/bin/script/delcol.plãè¯·ç¡®å®è¿äžªæ¡£æ¡æ¯å¯è¯»ååå¯æ§è¡çã</li>
+</ul>}  
+
+_textdelinv_ [l=zh] {æ¶è_cgiargbc1dirname_æ¯è¢«ä¿æ€çæè
+æ æçãå é€å·²è¢«åæ¶ã}  
+
+_textdelsuc_ [l=zh] {_cgiargbc1dirname_ æ¶èå·²ç»è¢«æåå°å é€ã}  
+
+_textclonefail_ [l=zh] {æ¶è_cgiargclonecol_äžèœè¢«å€å¶çãåå å¯èœæïŒ
+<ul>
+<li>æ­€æ¶è_cgiargclonecol_äžå­åš
+<li>æ­€æ¶è_cgiargclonecol_æ²¡æé
+çœ®æ¡£æ¡collect.cfg
+<li>ç»¿å®ç³ç³»ç»æ²¡ææéæ¥è¯»åé
+çœ®æ¡£æ¡collect.cfg
+</ul>}  
+
+_textcolerr_ [l=zh] {æ¶èè
+éè¯¯ã}  
+
+_texttmpfail_ [l=zh] {æ¶èè
+è¯»åäžäžªäžŽæ¶æä»¶æç®åœå€±èŽ¥ãå¯èœçåå æïŒ
+<ul>
+<li>ç»¿å®ç³æ²¡æè¯»/åè®¿é®å°_gsdlhome_/tmpç®åœã
+</ul>}  
+
+_textmkcolfail_ [l=zh] {æ°æ¶èçæ¶èè
+åå»ºèŠæ±çç®åœç»æå€±èŽ¥ïŒmkcol.pl failedïŒãå¯èœçåå æïŒ
+<ul>
+<li>ç»¿å®ç³æ²¡ææéåå
+¥_gsdlhome_/tmpç®åœã
+ <li>Perlèæ¬mkcol.plåºéã
+</ul>}  
+
+_textnocontent_ [l=zh] {æ¶èè
+åºéïŒæ²¡æç»æ°æ¶èåœåãå°è¯ä»äžåŒå§éæ°å¯åšæ¶èè
+ã}  
+
+_textrestart_ [l=zh] {éæ°å¯åšæ¶èè
+}  
+
+_textreloaderror_ [l=zh] {åœåå»ºæ°æ¶èæ¶åºç°äºäžäžªéè¯¯ãè¿å¯èœæ¯ç±äºäœ¿çšæšæµè§åšçâå·æ°âæâè¿åâæé®æ¶ïŒåœçšæ¶èè
+åå»ºäžäžªæ¶èæ¶è¯·å°œéé¿å
+äœ¿çšè¿äºæé®ïŒä»€ç»¿å®ç³ç³»ç»ååŸå°æçãå»ºè®®æšä»äžåŒå§æ¶éæ°å¯åšæ¶èè
+ã}  
+
+_textexptsuc_ [l=zh] {æ¶è_cgiargbc1dirname_å·²è¢«æåå°å¯Œåºå°_gsdlhome_/tmp/exported\__cgiargbc1dirname_ç®åœäžã}  
+
+_textexptfail_ [l=zh] {<p>å¯ŒåºéŠè_cgiargbc1dirname_å€±èŽ¥ã
+
+<p>è¿åŸå¯èœæ¯å äžºç»¿å®ç³åšå®è£
+æ¶çŒºå°äºæ¯æâå¯ŒåºéŠèâåèœçå¿
+èŠç»ä»¶ã
+<ul>
+
+ <li>åŠææšæ¯å
+çå®è£
+ç»¿å®ç³ç³»ç»çïŒè¿äºç»ä»¶äžäŒè¢«å®è£
+ïŒé€éæšåšâèªå®ä¹âå®è£
+æ¶éæ©ä»ä»¬ãæšå¯ä»¥éæ°è¿è¡å®è£
+çšåºæ¥æ·»å ä»ä»¬ã  
+
+ <li>åŠææšæ¯ä»çœé¡µååžäž­æ¥å®è£
+ç»¿å®ç³ç³»ç»çïŒæšå°éèŠäžèœœåå®è£
+äžäžªéå çå®è£
+å¥æ¥åŸå°è¿äžªåèœãè¯·è®¿é®<a href="http://www.greenstone.org">http://www.greenstone.org</a>æè
+åçµå­é®ä»¶å°<a
+ href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>åŸå°æŽå€çè¯Šç»èµæã
+
+</ul>}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=zh] {<p>è¯·æå®ä»¥äžçæ¡£æ¡ä¿¡æ¯åç¹å»äžé¢ç _textintro_ ã</p>}  
+
+_textcaec_ [l=zh] {å¢å ç°æçæ¶è}  
+_textbild_ [l=zh] {å­æŸé¡¹ç®}  
+_textintro_ [l=zh] {éæ©æ¡£æ¡}  
+_textconfirm_ [l=zh] {ç¡®è®€}  
+_textselect_ [l=zh] {éæ©æ¶è}  
+_textmeta_ [l=zh] {æå®å
+æ°æ®}  
+_textselectoption_ [l=zh] {éæ©éŠè}  
+
+_texttryagain_ [l=zh] {è¯·<a href="_httppagedepositor_" target=_top>éæ°å¯åšå­æŸè
+</a>ååå°è¯ã}  
+
+_textselectcol_ [l=zh] {éæ©æšæ³æ·»å æ°æä»¶çæ¶è}  
+_textfilename_ [l=zh] {æä»¶å}  
+_textfilesize_ [l=zh] {åœæ¡£}  
+
+_textretcoll_ [l=zh] {åå°å­æŸè
+}  
+
+
+_texttmpfail_ [l=zh] {å­æŸè
+è¯»åäžäžªäžŽæ¶æä»¶æç®åœå€±èŽ¥ãå¯èœçåå æïŒ
+<ul>
+<li>ç»¿å®ç³æ²¡æè¯»/åè®¿é®å°_gsdlhome_/tmpç®åœã
+</ul>}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=zh] {ç»¿å®ç³æ°å­åŸä¹ŠéŠèœ¯ä»¶æ¯å»ºç«äžååæ°å­åŸä¹ŠéŠéŠèçèœ¯ä»¶å¥ä»¶ãå®æäŸç»ç»ä¿¡æ¯å¹¶éè¿äºèçœæå
+çåºççæ°éåŸãç»¿å®ç³ç±æå¡æå€§å­Šçæ°è¥¿å
+°æ°å­åŸä¹ŠéŠé¡¹ç®å¶äœïŒäžèååœæè²ç§å­Šæåç»ç»ïŒUNESCOïŒåäººç±»ä¿¡æ¯éæ¿åºç»ç»ïŒHuman Info NGOïŒåäœåŒåäžåè¡ãå®æ¯åšGNUéçšå
+¬å
+±è®žå¯æ¡æ¬ŸäžååžçåŒæºå€è¯­ç§èœ¯ä»¶ïŒå¯ä»<i>http://greenstone.org</i>è·åŸã}  
+
+_textgreenstone2_ [l=zh] {æ°è¥¿å
+°æ°å­åŸä¹ŠéŠçœåïŒ<a href="http://nzdl.org">http://nzdl.org</a>ïŒå
+æ¬äŒå€çæ¶èèäŸå
+¬åŒå°æäŸç»æšç»è¯»ïŒå
+šéšéœç±ç»¿å®ç³èœ¯ä»¶æ¥åäœçãä»ä»¬ä»¥åç§åæ ·çæçŽ¢åæµè§éé¡¹äœäžºäŸå­ïŒå
+å«çæ¶èæé¿æäŒ¯è¯­çïŒäž­æçïŒæ³æçïŒæ¯å©æçåè¥¿ç­çæçïŒä¹æè±æçãåæ¶ä¹æäžäºå
+³äºé³ä¹çæ¶èã}  
+
+_textplatformtitle_ [l=zh] {å¹³å°}  
+_textgreenstone3_ [l=zh] {Greenstoneè¿è¡äºWindowsïŒUnix å Mac OS X ãå®çåè¡å
+æ¬éçšäºææçWindowsçæ¬ä»¥åLinux å Mac OS X å¯äœ¿çšçèœ¯ä»¶å
+ãå®è¿å
+æ¬äºå®åçç³»ç»æºä»£ç ïŒå¯ä»¥åšMicrosoft C++ æè
+ gcc ç³»ç»äžçŒè¯ãGreenstoneå¯ä»¥äžçžå
+³çå
+èŽ¹è·åèœ¯ä»¶å
+±åè¿è¡ïŒApache Webserver å PERLãå
+¶çšæ·çé¢äœ¿çšçœé¡µæµè§åšïŒç¹å«æ¯Netscape Navigator æè
+ Internet Explorerã}  
+
+_textgreenstone4_ [l=zh] {åŸå€æä»¶çæ¶èæ¯çšç»¿å®ç³èœ¯ä»¶äºå
+çåè¡ãäŸåŠïŒ<i>äººç±»åå±åŸä¹ŠéŠ</i>å
+å«ä»äŒè®¡å­Šå°æ°Žæºå«çåœç±»ç1,230äžªåºçç©ãå®è¿è¡äºåç¹å«åšåå±äž­åœå®¶èœæŸå°çæå°çå€çè®Ÿå€ãä¿¡æ¯å¯çšæçŽ¢æ¥è®¿é®ïŒéè¿äž»é¢ïŒæ é¢åç»ç»æ¥æµè§ïŒä¹å¯æµè§äžäžªæåŒåè¡šïŒåéæºå°æ¥çä¹Šæ¬çå°é¢ã}  
+
+_textcustomisationtitle_ [l=zh] {çšæ·å}  
+_textgreenstone5_ [l=zh] {ç»¿å®ç³æ¯ç¹å«å°è¢«è®Ÿè®¡äžºé«å»¶å±ååçšæ·åçãçŒåâæä»¶çšåºâ(çšPerl)å¯æäŸæ°æä»¶åå
+æ°æ®æ ŒåŒãç±»äŒŒå°ïŒçŒåâåç±»åšâå¯å®ç°æ°çå
+æ°æ®æµè§ç»æãçšæ·çé¢çå€è§åæè§å¯è¢«çšç®åå®è¯­èšçŒåçâå®âæ¥æ¹åãäžäžªCorbaåè®®å¯å
+
+è®žä»£çïŒåŠJAVAïŒäœ¿çšææäžæä»¶æ¶èæå
+³èçå·¥å
+·ãæåïŒåšC++åPerlçæºä»£ç ä¿®æ¹æ¯å¯çšçåå¯è®¿é®çã}  
+
+_textdocumentationtitle_ [l=zh] {æä»¶è®°åœ}  
+_textdocuments_ [l=zh] {å¯¹äºç»¿å®ç³èœ¯ä»¶çå¹¿å€§æä»¶è®°åœæ¯å¯åŸå°çã}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=zh] {é®ä»¶åè¡š}  
+_textmailinglist_ [l=zh] {é®ä»¶åè¡šäž»èŠæäŸäºå
+³äºGreenstoneæ°å­åŸä¹ŠéŠèœ¯ä»¶çè®šè®ºãGreenstoneçäœ¿çšäž­çšæ·åºè¯¥èèå å
+¥æ­€é®ä»¶åè¡šåäžºè®šè®ºäœåºèŽ¡ç®ãèŠè®¢é
+ Greenstone é®ä»¶åè¡šïŒè¯·è¿å
+¥ <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>ã
+
+èŠç»åè¡šçæååä¿¡,å¯ä»¥çŽæ¥åä¿¡å° <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>ã}  
+
+_textbugstitle_ [l=zh] {çšåºåºé}  
+_textreport_ [l=zh] {æä»¬åžææ¬èœ¯ä»¶èœåŸå¥œå°äžºæšå·¥äœãè¯·æ¥åä»»äœçšåºéè¯¯å°<a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">é®ä»¶åè¡š</a>}  
+
+_textgs3title_ [l=zh] {åšå·¥äœ}  
+_textgs3_ [l=zh] {ç»¿å®ç³ç³»ç»3æ¯äžäžªå®å
+šéæ°è®Ÿè®¡åéæ°å®æœïŒä¿ççææç»¿å®ç³ç³»ç»2ïŒæè¿çæ¬ïŒçæå©å çŽ --äŸåŠïŒå®æ¯äžäžªå¯äœ¿çšå€ç§è¯­èšçïŒå¯å€å¹³å°åå¯é«é
+çœ®çãå®åå¹¶ç°æç³»ç»çæä»¥ç¹åŸäžæ¯ååå
+Œå®¹çïŒ æŽç¡®åå°è¯ŽïŒå®äžçšåä¿®æ¹å°±èœå€åå»ºåè¿è¡ç°æçæ¶èãçŒåäºJAVAïŒå®åæ¯è¢«äžäžªçèœçšXMLäº€æµçç¬ç«æš¡åççœç»æææïŒå æ­€åŠæå¿
+èŠïŒå®å¯è¿è¡äºäžäžªå¯ååžçåœ¢åŒåå¯è¢«äŒ æ­äºäžåæå¡åšãè¿äžªç»ä»¶è®Ÿè®¡å¢å äºç»¿å®ç³ç³»ç»çéåºæ§åå¯å»¶å±æ§ãç»¿å®ç³ç³»ç»3çæä»¶è®°åœåè¯éªçæ¬å¯ä»<a href="http://www.greenstone.org/greenstone3.html">ç»¿å®ç³ç³»ç»3éŠé¡µ</a>äžèœœã}  
+
+_textcreditstitle_ [l=zh] {ä¿¡çš}  
+
+_textwhoswho_ [l=zh] {ç»¿å®ç³ç³»ç»èœ¯ä»¶æ¯äžäžªåŸå€äººäžèµ·åååäœçææãRodger McNabåStefan Boddieæ¯äž»èŠçå»ºç«è
+åæ§è¡è
+ãäœåºèŽ¡ç®çæDavid Bainbridge, George BuchananïŒHong ChenïŒMichael DewsnipïŒKatherine DonïŒElke DunckerïŒCarl GutwinïŒGeoff HolmesïŒDana McKayïŒJohn McPhersonïŒCraig Nevill-ManningïŒDynal PatelïŒGordon PaynterïŒBernhard PfahringerïŒTodd ReedïŒBill RogersïŒJohn ThompsonåStuart Yeatesãæ°è¥¿å
+°æ°å­åŸä¹ŠéŠå·¥çšçå
+¶ä»æååšç³»ç»çè®Ÿè®¡æ¹é¢æäŸäºå»ºè®®åçµæïŒMark ApperleyïŒSally Jo CunninghamïŒMatt JonesïŒSteve JonesïŒTe Taka KeeganïŒMichel LootsïŒMalika MahouiïŒGary MarsdenïŒDave NicholsåLloyd Smithãæä»¬æ¿æç­è°¢ææå
+æ¬åšè¿äžªåè¡çäœåºèŽ¡ç®çGNU-licensed packagesïŒMGïŒGDBMïŒPDFTOHTMLïŒPERLïŒWGETïŒWVWAREåXLHTMLã}  
+
+_textaboutgslong_ [l=zh] {å
+³äºç»¿å®ç³èœ¯ä»¶}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=zh] {åœåççšæ·æž
+å}  
+_textuser_ [l=zh] {çšæ·}  
+_textas_ [l=zh] {åžæ·ç¶æ}  
+_textgroups_ [l=zh] {ç»}  
+_textcomment_ [l=zh] {æè§}  
+_textadduser_ [l=zh] {å¢å æ°çšæ·}  
+_textedituser_ [l=zh] {çŒèŸ}  
+_textdeleteuser_ [l=zh] {å é€}  
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=zh] {çŒèŸçšæ·ä¿¡æ¯}  
+_textadduser_ [l=zh] {æ·»å æ°çšæ·}  
+
+_textaboutusername_ [l=zh] {çšæ·åå¿
+é¡»åš2å°30ä¹éŽçå­ç¬Šé¿åºŠãä»ä»¬å¯å
+æ¬æå­äžæ°å­çå­ç¬ŠïŒâ.â,åâ_âã}  
+
+_textaboutpassword_ [l=zh] {å¯ç å¿
+é¡»äžº3å°128äžªå­ç¬Šçé¿åºŠïŒå¯å
+å«ä»»äœå¯æ­£åžžæŸç€ºçASCIIå­ç¬Šã
+}  
+
+_textoldpass_ [l=zh] {åŠæè¿æ äžºç©ºçœçïŒæ§å¯ç äŒè¢«ä¿çã}  
+_textenabled_ [l=zh] {æ¿æŽ»ç}  
+_textdisabled_ [l=zh] {äžå¯çšç}  
+
+_textaboutgroups_ [l=zh] {ç»æ¯äžäžªçšéå·åéçåè¡šïŒäžèŠåšéå·åæŸä»»äœçç©ºæ Œã}  
+_textavailablegroups_ [l=zh] {é¢å®ä¹ççšæ·ç»å
+æ¬ç®¡çååå
+¶ä»æ¥æäœ¿çšåŸä¹ŠéŠåçé¢ææçš¿çé¢è¿çšåå»ºéŠèççšæ·ç»ïŒ
+<ul>
+<li><b>administrator</b>ïŒç®¡çåïŒïŒæ¥æè®¿é®åæŽæ¹ç«ç¹é
+çœ®äžçšæ·èŽŠæ·æéã
+<li><b>personal-collections-editor</b>ïŒäžªäººéŠèçŒèŸè
+ïŒïŒæ¥æåå»ºæ°çäžªäººéŠèçæéã
+<li><b><collection-name>-collection-editor</b>ïŒ<éŠèå>-collection-editorïŒæäžªéŠèççŒèŸè
+ïŒïŒæ¥æåå»ºåæŽæ¹æå®éŠèåïŒ"collection-name"ïŒéŠèçæéïŒæ¯åŠïŒreports-collection-editor.
+<li><b>all-collections-editor</b>ïŒææéŠèçŒèŸè
+ïŒïŒæ¥æåå»ºæ°çäžªäººéŠèäžå
+šå±éŠèçæéïŒä»¥åçŒèŸ<b>ææ</b>éŠèçæéã
+</ul>
+}  
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=zh] {å é€äžäžªçšæ·}  
+_textremwarn_ [l=zh] {æšççæ³æ°žä¹
+å°ç§»é€çšæ·<b>_cgiargumun_</b>åïŒ}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=zh] {ä¿®æ¹å¯ç }  
+_textoldpw_ [l=zh] {æ§å¯ç }  
+_textnewpw_ [l=zh] {æ°å¯ç }  
+_textretype_ [l=zh] {éæ°èŸå
+¥æ°å¯ç }  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=zh] {æšçå¯ç å·²è¢«æåå°ä¿®æ¹ã}  
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=zh] {çšæ·åæ æã}  
+_textinvalidpassword_ [l=zh] {å¯ç æ æã}  
+_textemptypassword_ [l=zh] {è¯·èŸå
+¥æ­€çšæ·çåå§åå¯ç ã}  
+_textuserexists_ [l=zh] {æ­€çšæ·å·²å­åšïŒè¯·èŸå
+¥åŠäžäžªçšæ·åã}  
+
+_textusernameempty_ [l=zh] {è¯·èŸå
+¥æšççšæ·åã}  
+_textpasswordempty_ [l=zh] {äœ å¿
+é¡»èŸå
+¥åæ¥çå¯ç ã}  
+_textnewpass1empty_ [l=zh] {èŸå
+¥æšçæ°å¯ç ïŒç¶ååéæ°èŸå
+¥ã}  
+_textnewpassmismatch_ [l=zh] {æšçäž€äžªçæ¬çæ°å¯ç äžçžç¬Šã}  
+_textnewinvalidpassword_ [l=zh] {æšèŸå
+¥äºäžäžªæ æçå¯ç ã}  
+_textfailed_ [l=zh] {æšççšæ·åæå¯ç äžæ­£ç¡®ã}  
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=zh] {ç»¿å®ç³ççæ¬å·}  
+_textframebrowser_ [l=zh] {æšå¿
+é¡»æäžäžªèœè®©æµè§åšæ¥å¯çè¿äžªçæ¡æ¶ã}  
+_textusermanage_ [l=zh] {çšæ·ç®¡ç}  
+_textlistusers_ [l=zh] {è®°å
+¥ååå
+ççšæ·}  
+_textaddusers_ [l=zh] {æ·»å æ°çšæ·}  
+_textchangepasswd_ [l=zh] {æ¹åå¯ç }  
+_textinfo_ [l=zh] {ææ¯äžçä¿¡æ¯}  
+_textgeneral_ [l=zh] {äžè¬ç}  
+_textarguments_ [l=zh] {è®ºç¹}  
+_textactions_ [l=zh] {è¡äžº}  
+_textbrowsers_ [l=zh] {æµè§åš}  
+_textprotocols_ [l=zh] {åè®®}  
+_textconfigfiles_ [l=zh] {é
+çœ®æ¡£æ¡}  
+_textlogs_ [l=zh] {æ¥å¿}  
+_textusagelog_ [l=zh] {äœ¿çšæ¥å¿}  
+_textinitlog_ [l=zh] {åå§åæ¥å¿}  
+_texterrorlog_ [l=zh] {éè¯¯æ¥å¿}  
+_textadminhome_ [l=zh] {ç®¡ç°éŠé¡µ}  
+_textreturnhome_ [l=zh] {ç»¿å®ç³éŠé¡µ}  
+_titlewelcome_ [l=zh] {ç®¡ç}  
+_textmaas_ [l=zh] {å¯çšçç»Žæ€åç®¡çæå¡å
+æ¬æïŒ}  
+_textvol_ [l=zh] {å¯çåšçº¿æ¥å¿}  
+_textcmuc_ [l=zh] {åå»ºïŒç»Žæ€åæŽæ°æ¶è}  
+_textati_ [l=zh] {è®¿é®ææ¯ä¿¡æ¯åŠCGIè®ºç¹}  
+
+_texttsaa_ [l=zh] {è¿äºæå¡å¯ä»¥äœ¿çšé¡µé¢å·ŠæèŸ¹çå¯Œèªæ¡æ¥å€çã}  
+
+_textcolstat_ [l=zh] {æ¶èç¶æ}  
+
+_textcwoa_ [l=zh] {åŠæbuild.cfgæ¡£æ¡å­åšïŒäžå¯è¯»çïŒå
+å«äžäžªææçåå»ºæ¥æïŒåŠ >0ïŒïŒå­æŸäºæ¶èççŽ¢åŒç®åœäžïŒåŠ äžåšåé ç®åœäžïŒïŒæ¶èå°åªäŒåºç°âè¿è¡äž­âã}  
+
+_textcafi_ [l=zh] {ç¹å»<i>çŒ©å</i>æ¥æ¥çæ¶èçä¿¡æ¯}  
+_textcctv_ [l=zh] {ç¹å»<i>æ¶è</i>æ¥æ¥çæ¶è}  
+_textsubc_ [l=zh] {æäº€ä¿®æ¹}  
+_texteom_ [l=zh] {main.cfgæåŒåºé}  
+_textftum_ [l=zh] {main.cfgæŽæ°å€±èŽ¥}  
+_textmus_ [l=zh] {main.cfgæŽæ°æå}  
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=zh] {äžºâ_collectionname_âæ¶èåå»ºæèŠ}  
+_textflog_ [l=zh] {æ¶èâ_collectionname_âè®°åœæ¥å¿å€±èŽ¥}  
+_textilog_ [l=zh] {å¯Œå
+¥æ¶è"_collectionname_"çæ¥å¿}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=zh] {åéåéŠ}  
+
+_greenstoneusabilitytext_ [l=zh] {Greenstoneçå¯çšæ§}  
+
+_textwhy_ [l=zh] {<p>åéè¿äžªæ¥åæ¯æ å¿çæšå·²ç»æŸå°æšèœæ¥çå°éŸåé»æ ççœé¡µçäžäžªæ¹æ³ã}  
+_textextraforform_ [l=zh] {æšäžå¿
+å¡«åè¿äžªè¡šæ Œ -- ä»»äœä¿¡æ¯éœæåž®å©ã}  
+_textprivacybasic_ [l=zh] {<p>æ­€æ¥åå°åªå
+å«æšæ¥ççå
+³äºç»¿å®ç³çœé¡µçä¿¡æ¯ïŒåæšçšäºæ¥ççææ¯ïŒå äžä»»äœæšå¯æäŸçéæ©æ§ä¿¡æ¯ïŒã}  
+_textstillsend_ [l=zh] {æšä»ç¶æ³åéè¿äžªæ¥ååïŒ}  
+
+_texterror_ [l=zh] {éè¯¯}  
+_textyes_ [l=zh] {æ¯}  
+_textno_ [l=zh] {åŠ}  
+_textclosewindow_ [l=zh] {å
+³é­çªå£}  
+_textabout_ [l=zh] {å
+³äº}  
+_textprivacy_ [l=zh] {ç§é}  
+_textsend_ [l=zh] {åé}  
+_textdontsend_ [l=zh] {äžèŠåé}  
+_textoptionally_ [l=zh] {å¯éæ©å°}  
+
+_textunderdev_ [l=zh] {åšæåççæ¬å¯ä»¥æè¯Šç»èµæçé¢è§ã}  
+
+_textviewdetails_ [l=zh] {æ¥çæ¥åçè¯Šç»èµæ}  
+_textmoredetails_ [l=zh] {æŽå€çè¯Šç»èµæ}  
+_texttrackreport_ [l=zh] {è¿œèžªæ­€æ¥å}  
+_textcharacterise_ [l=zh] {è¿æ¯åªç§é®é¢}  
+_textseverity_ [l=zh] {è¿é®é¢æå€äž¥éç}  
+ 
+_textbadrender_ [l=zh] {çœé¢çäŒŒå¥æªç}  
+_textcontenterror_ [l=zh] {ç®åœéè¯¯}  
+_textstrangebehaviour_ [l=zh] {å¥æªçè¡äžº}  
+_textunexpected_ [l=zh] {ææ³äžå°çäºæ
+åçäº}  
+_textfunctionality_ [l=zh] {éŸäºäœ¿çš}  
+_textother_ [l=zh] {å
+¶ä»ç}  
+
+_textcritical_ [l=zh] {è¯è®ºç}  
+_textmajor_ [l=zh] {äž¥éç}  
+_textmedium_ [l=zh] {åªä»}  
+_textminor_ [l=zh] {æ¬¡èŠ}  
+_texttrivial_ [l=zh] {ä»·åŒäžé«ç}  
+
+_textwhatdoing_ [l=zh] {æšä¹ååšå°è¯åä»ä¹äºæ
+ïŒ}  
+_textwhatexpected_ [l=zh] {æšé¢æä»ä¹äºæ
+åçäºïŒ}  
+_textwhathappened_ [l=zh] {å®é
+äžä»ä¹äºæ
+åçäºïŒ}  
+
+_cannotfindcgierror_ [l=zh] {<h2>åŸæ±æ­ïŒ</h2>äžèœäžºâ_linktextusab_âæé®æŸå°çžå
+³çæå¡åšçšåºã}  
+
+_textusabbanner_ [l=zh] {Korué£æ ŒçGreenstoneæ è¯­}  
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=zh] {åçéè¯¯}  
+
+_textgtihome_ [l=zh] {è¿äºé¡µé¢åž®å©äœ æ¹å Greenstone çå€ç§è¯­èšçæ¯æã è¿çšä»ä»¬ïŒäœ èœå€
+<ul>
+  <li>æéšä»œçGreenstoneç¿»è¯æäžç§æ°çè¯­èš
+  <li>åœè±æçé¢æ¹åæ¶ïŒç°æçäžç§è¯­èšä¹å¯ä»¥åŸå°æŽæ°(åŠïŒå¯¹äºæ°çGreenstoneå·¥å
+·)
+  <li>æŽæ­£ç°æçç¿»è¯éè¯¯
+</ul>
+
+äžç³»åçœé¡µå°äŒåç°åšäœ çé¢åïŒæ¯äžªéœå
+å«èéèŠç¿»è¯çç­è¯­ãäœ å¯ä»¥æç­è¯­æ¥è¿è¡è¯¥è¯­èšçé¢çç¿»è¯ãåŸå€ç­è¯­å
+å«HTMLæ ŒåŒçåœä»€ïŒäœ äžåºè¯¥äŒåŸå»ç¿»è¯ä»ä»¬ïŒèå®æŽæ çŒºå°ä¿çåšç¿»è¯è¿ççæ¬éãæ æäžåçº¿çå­è¯(å _this_) ä¹äžåºè¯¥è¢«ç¿»è¯(ä»ä»¬äžºGreenstoneç"macro"åå­)ã
+<p>
+åŠæäœ åšæŽæ°äžäžªç°æçè¯­èšçé¢ïŒäœ äžäŒçå°å·²ç»å­åšäžäžªç¿»è¯çç­è¯­ãææ¶åäžäžªç¿»è¯å·²å­åšäœè±æçåæå·²ç»è¢«æ¹åäºãåšè¿ç§æ
+åµäžåœåçç¿»è¯äŒè¢«æäŸåºæ¥èäœ åºè¯¥æ£æ¥ïŒåŠæå¿
+èŠå°±éèŠæŽæ­£å®ã
+<p>
+çšåšGreenstoneçæ¯äžªéšä»œéœå¯ä»¥æŸå°ç"Correct existing translations"å·¥å
+·æ¥ä¿®æ­£äžäžªå·²ç»è¢«æŽæ­£è¿çç¿»è¯ã
+<p>
+æ¯é¡µä»¥"_textgtisubmit_"æé®æ¥ç»æãåœäœ æäžå®æ¶ïŒä¿®æ­£äŒç«å»å°è¢«æ¹åå°Greenstoneåšnzdl.orgçåç¬å®è£
+ãäžäžªæé®äŒè¢«æäŸåšæ¯äžªé¡µé¢æ¥è¿æ¥å°è¿äžªç«ç¹ã
+}  
+
+_textgtiselecttlc_ [l=zh] {è¯·éæ©æšçè¯­èš}  
+
+#for status page
+_textgtiviewstatus_ [l=zh] {ç¹å»æ¥çæè¿çææè¯­èšç¿»è¯ç¶æ}  
+_textgtiviewstatusbutton_ [l=zh] {æ¥çç¶æ}  
+_textgtistatustable_ [l=zh] {æè¿çææè¯­èšç¿»è¯ç¶ææž
+å}  
+_textgtilanguage_ [l=zh] {è¯­èš}  
+_textgtitotalnumberoftranslations_ [l=zh] {èœ¬æ¢æ»æ°}  
+
+_textgtiselecttfk_ [l=zh] {è¯·éæ©ç»§ç»­å·¥äœçæ¡£æ¡}  
+
+_textgticoredm_ [l=zh] {ç»¿å®ç³ç³»ç»çé¢ïŒæ žå¿ïŒ}  
+_textgtiauxdm_ [l=zh] {ç»¿å®ç³ç³»ç»çé¢ïŒèŸ
+å©ïŒ}  
+_textgtiglidict_ [l=zh] {GLIç®åœ}  
+_textgtiglihelp_ [l=zh] {GLIåž®å©}  
+_textgtiperlmodules_ [l=zh] {Perlæš¡å}  
+_textgtitutorials_ [l=zh] {æåç»ä¹ }  
+_textgtigreenorg_ [l=zh] {Greenstone.org}  
+_textgtigs3interface_ [l=zh] {ç»¿å®ç³ç³»ç»3çé¢
+
+	"Predefined groups include administrator and others which assign rights for remote collection building using the Librarian Interface or the Depositor:
+<ul>
+<li><b>administrator</b>: Gives permission to access and change site configuration and user accounts.
+<li><b>personal-collections-editor</b>: Gives permission to create new personal collections
+<li><b><collection-name>-collection-editor</b>: Gives permission to create and edit the "collection-name" collection, for example, reports-collection-editor.
+<li><b>all-collections-editor</b>: Gives permission to create new personal and global collections and edit <b>all</b> collections.
+</ul>
+"}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=zh] {ç»¿å®ç³åŒåè
+æå}  
+_textgtiinstallmanual_ [l=zh] {ç»¿å®ç³å®è£
+æå}  
+_textgtipapermanual_ [l=zh] {è®ºæå°æ¶èçGreenstoneæå}  
+_textgtiusermanual_ [l=zh] {ç»¿å®ç³çšæ·æå}  
+
+_textgtienter_ [l=zh] {èŸå
+¥}  
+
+_textgticorrectexistingtranslations_ [l=zh] {ä¿®æ¹ç°å­çç¿»è¯}  
+_textgtidownloadtargetfile_ [l=zh] {äžèœœæ¡£æ¡}  
+_textgtiviewtargetfileinaction_ [l=zh] {å¯çæ­€æ¡£æ¡çè¿èœ¬}  
+_textgtitranslatefileoffline_ [l=zh] {çŠ»çº¿ç¿»è¯è¿æ¡£æ¡}  
+
+_textgtinumchunksmatchingquery_ [l=zh] {ææ¬çæ®µäžæ¥è¯¢å¹é
+çæ°é}  
+
+_textgtinumchunkstranslated_ [l=zh] {ç¿»è¯å®æ}  
+_textgtinumchunksrequiringupdating_ [l=zh] {å¯¹æ­€ïŒ_1_éèŠæŽæ°}  
+_textgtinumchunksrequiringtranslation_ [l=zh] {å©äœçç¿»è¯}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=zh] {å·²å®æçç¿»è¯æ°é}  
+_textgtinumchunksrequiringupdating2_ [l=zh] {éèŠæŽæ°çç¿»è¯æ°é}  
+_textgtinumchunksrequiringtranslation2_ [l=zh] {å©äœçç¿»è¯æ°é}  
+
+_textgtienterquery_ [l=zh] {èŸå
+¥æšæ³ä¿®æ¹çä»ææ¬çæ®µæ¥çè¯æç­è¯­}  
+_textgtifind_ [l=zh] {æ¥æŸ}  
+
+_textgtitranslatingchunk_ [l=zh] {ç¿»è¯ææ¬çæ®µ<i>_1_</i>}  
+_textgtiupdatingchunk_ [l=zh] {æŽæ°ææ¬çæ®µ<i>_1_</i>}  
+_textgtisubmit_ [l=zh] {æäº€}  
+
+_textgtilastupdated_ [l=zh] {æè¿çæŽæ°}  
+
+_textgtitranslationfilecomplete_ [l=zh] {æè°¢æŽæ°è¿æ¡£æ¡ -- å·²ç»å®æïŒ<p>æšå¯ä»¥çšäžé¢çéŸæ¥äžèœœäžä»œè¿äžªæ¡£æ¡ïŒåå®å°äŒå
+æ¬åšå°æ¥ååžçç»¿å®ç³èœ¯ä»¶äž­ã}  
+
+_textgtiofflinetranslation_ [l=zh] {æšå¯ä»¥çšåŸ®èœ¯çè¡šæ Œå€çèœ¯ä»¶Excelççµå­å¶è¡šæ¡£æ¡æ¥çŠ»çº¿ç¿»è¯ç»¿å®ç³çè¿éšåïŒ
+
+<ol>
+<li>äžèœœ<a href="_gwcgi_?a=gti&p=excel&tct=work&e=_compressedoptions_">æ¬æä»¶</a>è·åææå©äœçç¿»è¯ïŒæè
+<a href="_gwcgi_?a=gti&p=excel&tct=all&e=_compressedoptions_">æ¬æä»¶</a>è·åæ¬ç¿»è¯æš¡åäž­çææå­äž²ã
+<li>åšè¡šæ Œå€çèœ¯ä»¶ExcelæåŒæ­€äžèœœçæä»¶ïŒæ­€åèœéèŠåŸ®èœ¯åå
+¬èœ¯ä»¶Office2003/XPæä»¥äžçæ¬ïŒïŒå¹¶åŠå­äžºäžå¡æåïŒ.xlsïŒæ ŒåŒã
+<li>åšæäŸçç©ºæ ŒéèŸå
+¥ç¿»è¯ã
+<li>åœæšå®æææå­äž²çç¿»è¯åïŒæ.xlsæä»¶çšçµå­é®ä»¶çåœ¢åŒåéå°<a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>ã
+</ol>
+}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=zh] {ç»¿å®ç³åŸä¹Šç®¡çåçé¢}  
+_textglihelp_ [l=zh] {<p>ç»¿å®ç³åŸä¹Šç®¡çåçé¢ïŒGLIïŒèœè®©æšä»äžäžªå®¹æäœ¿çšçâpoint and clickâçé¢æ¥è®¿é®ç»¿å®ç³çåèœãè¿äžªå¯å
+è®žæšæ¶èäžç³»åçæä»¶ïŒå¯Œå
+¥æåé
+å
+æ°æ®ïŒååå»ºä»ä»¬å°ç»¿å®ç³çæ¶èäž­ã</p>
+
+<p>æ³šæçæ¯GLIæ¯åç»¿å®ç³ç³»ç»èåè¿è¡çïŒéåçæ¹æ³æ¯å®è¢«å®çœ®åšæšç»¿å®ç³çå®è£
+äž­çäžäžªå­ç®åœéãåŠææšæ³äžèœœç»¿å®ç³çå
+¶äž­äžäžªåè¡ïŒæè
+ä»ç»¿å®ç³çå
+ççå®ïŒå°äŒæ¯è¿æ ·çäžäžªæ
+åµã</p>
+
+<h4>åšWindowsç³»ç»ç¯å¢äžè¿è¡GLI</h4>
+
+åšWindowsäžä»<i>åŒå§</i>èåäž­ç<i>çšåº</i>éæ©<i>ç»¿å®ç³æ°å­åŸä¹ŠéŠ</i>ïŒéå®<i>åŸä¹Šç®¡çåçé¢</i> è¿æ¥åŸä¹Šç®¡çåçé¢ã 
+
+<h4>åšUnixç³»ç»ç¯å¢äžè¿è¡GLI</h4>
+
+äžºäºåšUnixäžè¿è¡GLIïŒå
+èœ¬æ¢å°æšçç»¿å®ç³å®è£
+ç®åœ<i>gli</i>äžç¶åè¿è¡<i>gli.sh</i>èæ¬ã 
+
+<h4>åšMac OS Xç³»ç»ç¯å¢äžè¿è¡GLI</h4>
+
+åšåç°è
+ïŒæµè§å°<i>åºçšçšåº</i>ç¶å<i>ç»¿å®ç³ç³»ç»</i>ïŒåŠææšæç»¿å®ç³å®è£
+å°é»è®€çäœçœ®ïŒïŒä¹åè¿æ¥å°<i>GLI</i>åºçšçšåºã}  
Index: /gsdl/stable/macros/collect.dm
===================================================================
--- /gsdl/stable/macros/collect.dm	(revision 20131)
+++ /gsdl/stable/macros/collect.dm	(revision 20131)
@@ -0,0 +1,884 @@
+# this file must be UTF-8 encoded
+
+package collector
+
+_imagethispage_ {<a href="_httppagecollector_">_textcollector_</a>}
+
+# _pagescriptextra_ will be set to the appropriate _***scriptextra_
+# macro from within the server
+_pagescriptextra_ {}
+
+# a plain header for those pages that need it (the _pagebanner_ macro
+# will be set to this by the server for those pages.
+_plainbanner_ {}
+
+# dont want links to "help" or "preferences" pages from within
+# collector
+_globallinks_ {_homelink_}
+
+#######################################################################
+# icons
+
+_iconcross_ {<img src="_httpimg_/cross.gif">}
+_iconcross_ [v=1] {<b>no</b>}
+_icontick_ {<img src="_httpimg_/tick.gif">}
+_icontick_ [v=1] {<b>yes</b>}
+_iconblank_ {<img src="_httpimg_/blank.gif">}
+_iconblank_ [v=1] {}
+
+_imagemore_ {<a href="javascript:more()" onMouseover="roll('more',1);" onMouseOut="roll('more',0);"><img
+name="more" src="_httpimg_/moreof.gif" onLoad="gbutton(this,'_httpimg_/moreon.gif');" border=0 alt="_textmore_"
+title="_textmore_" align=top></a>}
+_imagemore_ [v=1] {_textmore_}
+
+_icongreyarrow_ {<img src="_httpimg_/grarrow.gif">}
+_icongreyuparrow_ {<img src="_httpimg_/guarrow.gif">}
+_iconstop_ {<img src="_httpimg_/stop.gif" border=0>}
+
+
+#######################################################################
+# http macros 
+
+_httpinfo_ {_gwcgi_?e=_compressedoptions_&p=info}
+_httpsrce_ {_gwcgi_?e=_compressedoptions_&p=srce}
+_httpconf_ {_gwcgi_?e=_compressedoptions_&p=conf}
+_httpbild_ {_gwcgi_?e=_compressedoptions_&p=bild}
+_httpview_ {_gwcgi_?a=p&p=about&c=_cgiargbc1dirname_}
+_httpdel_  {javascript:do\_delete();}
+_httpexpt_ {_gwcgi_?e=_compressedoptions_&p=expt}
+
+
+#######################################################################
+# intro
+#######################################################################
+
+_introscriptextra_ {}
+
+_introcontent_ {
+<form name="collectorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center>
+<h2>_textcollector_</h2>
+<p>_textcollectorblurb_
+</center>
+<div class="divbar">&nbsp;</div>
+<p>_textcb1_
+<p>_textcb2_
+<ul>
+<input type=radio name=p value=new checked>
+_textcnc_
+<br>
+<input type=radio name=p value=existing>
+_textwec_
+</ul>
+<div class="divbar">&nbsp;</div>
+<p>_textcb3_
+<p>_textcb4_
+
+<table><tr><td width=80>_authen:textusername_</td>
+<td><input type="text" name="un" value="" size=10></td>
+<td></td></tr>
+<tr><td>_authen:textpassword_</td>
+<td><input type="password" name="pw" size=10></td>
+<td><input type="submit" value="_textsignin_"></td>
+</tr>
+</table>
+<div class="divbar">&nbsp;</div>
+</td></tr>
+</table></center>
+
+</form>
+}
+
+
+#######################################################################
+# existing (Changing an existing collection page)
+#######################################################################
+
+_existingscriptextra_ {
+function check\_submit (gotopage) \{
+  var form = document.collectorform;
+  if (gotopage == "srce") \{
+    form.bc1esrce.value = "1";
+  \}
+  if (gotopage == "conf") \{
+    form.bc1econf.value = "1";
+  \}
+  form.p.value = gotopage;
+  form.submit();
+\}
+
+function do\_delete () \{
+  var form = document.collectorform;  
+  var i = form.bc1dirname.selectedIndex;
+  var del = confirm ("Confirm deletion of " + form.bc1dirname.options[i].value + " collection?");
+  if (del) \{
+    form.bc1dodelete.value = "1";
+    form.submit();
+  \}
+\}
+}
+
+_changeexisting_ {
+<p>_textfsc_
+<br>_fullnamemenu_<br>
+<p>_textwtc_
+
+<table class=collectorbar cellspacing=6>
+<tr><td width=20 align=right valign=bottom>1.</td>
+<td class=collectorbargreen valign=bottom><a href=_httpsrce_>_textsrce_</a></td>
+<td valign=bottom>_textamd_</td></tr>
+<tr><td align=right valign=bottom>2.</td>
+<td class=collectorbargreen valign=bottom><a href=_httpconf_>_textconf_</a></td>
+<td valign=bottom>_textetc_</td></tr>
+<tr><td align=right valign=bottom>3.</td>
+<td class=collectorbargreen valign=bottom><a href=_httpdel_>_textdel_</a></td>
+<td valign=bottom>_textdtc_</td></tr>
+<tr><td align=right valign=bottom>4.</td>
+<td class=collectorbargreen valign=bottom><a href=_httpexpt_>_textexpt_</a></td>
+<td valign=bottom>_textetcfcd_</td></tr>
+</table>
+}
+
+_existingcontent_ {
+<form name="collectorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+<input type=hidden name="bc1dodelete" value="0">
+<input type=hidden name="bc1esrce" value="0">
+<input type=hidden name="bc1econf" value="0">
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center><h2>_textcaec_</h2></center>
+<div class="divbar">&nbsp;</div>
+_If_("_fullnamemenu_" eq "",<p>_textnwec_,_changeexisting_)
+<div class="divbar">&nbsp;</div>
+</td></tr>
+</table></center>
+</form>
+}
+
+
+#######################################################################
+# new (Create a new collection page)
+#######################################################################
+
+_newscriptextra_ {}
+
+_newcontent_ {
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center><h2>_textcianc_</h2></center>
+<div class="divbar">&nbsp;</div>
+
+<p>_texttsosn_
+<table class=wizardbar cellspacing=6>
+<tr><td width=20 align=right valign=bottom>1.</td>
+    <td class=wizardbargrey valign=bottom>_textinfo_</td>
+    <td valign=bottom>_textsin_</td></tr>
+<tr><td align=right valign=bottom>2.</td>
+    <td class=wizardbargrey valign=bottom>_textsrce_</td>
+    <td valign=bottom>_textswts_</td></tr>
+<tr><td align=right valign=bottom>3.</td>
+    <td class=wizardbargrey valign=bottom>_textconf_</td>
+    <td valign=bottom>_textatco_</td></tr>
+<tr><td align=right valign=bottom>4.</td>
+    <td class=wizardbargrey valign=bottom>_textbild_</td>
+    <td valign=bottom>_textbtc_</td></tr>
+<tr><td align=right valign=bottom>5.</td>
+    <td class=wizardbargrey valign=bottom>_textview_</td>
+    <td valign=bottom>_textpvyh_</td></tr>
+</table>
+
+<p>_texttfsiw_
+<div class="divbar">&nbsp;</div>
+<p>_textadab_
+<p>_textwyar_
+<p><center>
+_collectorbar_
+</center>
+
+</td></tr>
+</table></center>
+}
+
+
+#######################################################################
+# info (Collection information page)
+#######################################################################
+
+_infoscriptextra_ {
+function check\_submit (gotopage) \{
+  var form = document.collectorform;
+  if (form.bc1fullname.value.match(/^\\s*$/))
+  \{
+    alert("_textcnmbs_");
+    form.bc1fullname.focus();
+    return;
+  \}
+  else if (form.bc1contactemail.value.match(/^\\s*$/))
+  \{     
+    alert("_texteambs_");
+    form.bc1contactemail.focus();
+    return;
+  \}
+  else if (!form.bc1contactemail.value.match(/^([^@]+)@(.+)$/))
+  \{
+    alert("_textpsea_");
+    form.bc1contactemail.focus();
+    return;
+  \}
+  else if (form.bc1aboutdesc.value.match(/^\\s*$/))
+  \{
+    alert("_textdocmbs_");
+    form.bc1aboutdesc.focus();
+    return;
+  \}
+  form.p.value = gotopage;
+  form.submit();
+\}
+}
+
+_infocontent_ {
+<form name="collectorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+<input type=hidden name="bc1infochanged" value="0">
+
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center>
+<h2>_textinfo_</h2>
+</center>
+<div class="divbar">&nbsp;</div>
+
+<p>_textwcanc_
+<h4>_texttfc_</h4>
+<input type="text" name="bc1fullname" value="_cgiargbc1fullname_"
+onChange="document.collectorform.bc1infochanged.value=1;") size=72>
+<br>_texttctiasp_
+<h4>_textcea_</h4>
+<input type="text" name="bc1contactemail" value="_cgiargbc1contactemail_"
+onChange="document.collectorform.bc1infochanged.value=1;" size=72>
+<br>
+_textteas_
+
+<h4>_textatc_</h4>
+<textarea name="bc1aboutdesc"  cols=72 rows=6 wrap=physical
+onChange="document.collectorform.bc1infochanged.value=1;">
+_cgiargbc1aboutdesc_
+</textarea>
+<br>_texttiasd_
+
+<div class="divbar">&nbsp;</div>
+
+<p>_textypits_
+<p><center>
+_collectorbar_
+</center>
+
+</td></tr>
+</table></center>
+
+</form>
+}
+
+
+#######################################################################
+# srce (Source data page)
+#######################################################################
+
+# _fullnamemenu is set from within the server. If it's empty there are
+# no valid collections 
+_fullnamemenu_ {}
+
+_srcescriptextra_ {
+var selectedindex = _selectedindex_;
+
+function check\_submit (gotopage) \{
+  var form = document.collectorform;
+  form.p.value = gotopage;
+  form.bc1fromsrce.value = "1";
+  form.submit();
+\}
+
+function menuchange () \{
+  var form = document.collectorform;
+  var warnlist = new Array (_warnindex_);
+
+  if (warnlist[form.bc1clonecol.selectedIndex] == 1) \{
+    alert ("The collection you are cloning has a non-standard input file\\n" +
+           "format, and/or uses metadata specified in auxiliary files.  If your\\n" +
+	   "new input lacks this information, some browsing facilities may not\\n" +
+           "work properly.");
+  \}
+
+  if (form.bc1clonecol.selectedIndex == 0) \{
+    form.bc1clone.value = "0";
+  \} else \{
+    form.bc1clone.value = "1";
+  \}
+
+  if (form.bc1clonecol.selectedIndex == selectedindex) \{
+    form.bc1clonechanged.value = "0";
+  \} else \{
+    form.bc1clonechanged.value = "1";
+  \}
+\}
+
+function more () \{
+  var form = document.collectorform;
+  form.bc1inputnum.value = parseInt(form.bc1inputnum.value) + 3;
+  form.p.value = "srce";
+  if (!form.action.match(/sources$/)) \{
+    form.action += "#sources";
+  \}
+  form.submit();
+\}
+}
+
+_srcenew_ {
+<center>
+<h2>_textsrce_</h2>
+</center>
+<div class="divbar">&nbsp;</div>
+_If_("_badsources_" eq "1",_srcebadsources_,_srcenewcontent_)
+}
+
+_srcenewcontent_ {
+_textymbyco_
+<p>_textbtco_
+_fullnamemenu_
+<div class="divbar">&nbsp;</div>
+}
+
+_srceappend_ {
+<center>
+<h2>_textand_</h2>
+</center>
+<div class="divbar">&nbsp;</div>
+<h4>_textad_</h4>
+_texttftysb_
+}
+
+_srcecontent_ {
+<form name="collectorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+<input type=hidden name="bc1fromsrce" value="0">
+<input type=hidden name="bc1clonechanged" value="0">
+<input type=hidden name="bc1clone" value="_cgiargbc1clone_">
+<input type=hidden name="bc1inputnum" value="_cgiargbc1inputnum_">
+
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+_If_("_cgiargbc1esrce_" eq "1",_srceappend_,_srcenew_)
+
+<a name="sources"></a>
+<h4>_textis_</h4>
+_sourcelist_
+
+_textddd1_
+<div class="divbar">&nbsp;</div>
+_textddd2_
+<p><center>
+_collectorbar_
+</center>
+
+</td></tr>
+</table></center>
+
+</form>
+}
+
+
+#######################################################################
+# conf (Configure collection page)
+#######################################################################
+
+_confscriptextra_ {
+var changed = 0;
+
+function check\_submit (gotopage) \{
+  var form = document.collectorform;
+  form.bc1cfgchanged.value = changed;
+  form.p.value = gotopage;
+  form.submit();
+\}
+
+function reset\_button () \{
+  document.collectorform.reset();
+  changed = 0;
+\}
+}
+
+_confcontent_ {
+<form name="collectorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+<input type=hidden name="bc1cfgchanged" value="_cgiargbc1cfgchanged_">
+
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center>
+<h2>_textconf_</h2>
+</center>
+<div class="divbar">&nbsp;</div>
+_textconf1_
+
+<p><textarea name="cfgfile" cols=72 rows=18 wrap=off onChange="changed=1;">
+_cfgfile_
+</textarea>
+<table><tr valign=top>
+<td><a href="javascript:reset\_button();">_iconstop_</a></td>
+<td><a href="javascript:reset\_button();">_textreset_</a></td>
+</tr></table>
+
+<p><center>
+_collectorbar_
+</center>
+
+</td></tr>
+</table></center>
+
+</form>
+}
+
+
+#######################################################################
+# bild (main frameset for build page)
+#######################################################################
+
+_bildcontent_ {
+<html>
+<head>
+<script>
+<!--
+function check\_submit (gotopage) \{
+  var form = document.collectorform;
+  form.p.value = gotopage;
+  form.submit();
+\}
+// -->
+</script>
+</head>
+
+<form name="collectorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+
+<frameset rows="*,160" border=0>
+  <noframes><body bgcolor="#ffffff">
+  <p>You must have a frame enabled browser to obtain feedback
+  on how the building process is progressing. The collection <i>will</i>
+  continue to build as normal however.
+
+  <table>
+  <tr valign=center><td>
+  To stop the building process at any time, click here.
+  <br>The collection you are working on will remain intact.
+  </td>
+  <td><input type="submit" value="stop building"></td>
+  </table>
+
+  </body>
+  </noframes>
+  <frame src="_gwcgi_?e=_compressedoptions_&p=bildframe1">
+  <frame src="_gwcgi_?e=_compressedoptions_&p=bildstatus&c=_cgiargbc1dirname_">
+</frameset>
+</html>
+}
+
+#######################################################################
+# bildframe1
+#######################################################################
+
+# header overridden to allow base target to be set
+# also no page banner to maximise what we can fit in the frame without scrolling
+_bildframe1header_ {_cgihead_
+<html>
+<head>
+<base target=_top>
+<title>_pagetitle_</title>
+_globalscripts_
+</head>
+<body class="bgimage">
+_startspacer_
+}
+_bildframe1header_[v=1] {_cgihead_
+<html>
+<head>
+<base target=_top>
+<title>_pagetitle_</title>
+_globalscripts_
+</head>
+<body class="bgimage">
+}
+_bildframe1scriptextra_ {}
+_bildframe1content_ {
+<form name="collectorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="bildcancel">
+
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center>
+<h2>_textbild_</h2>
+</center>
+<div class="divbar">&nbsp;</div>
+<p>
+_textbild1_
+<p>
+
+<table>
+<tr valign=center><td>
+_textbild2_
+</td>
+<td><input type="submit" value="_textstopbuild_"></td>
+</table>
+
+<p>
+_textbild3_
+</td></tr>
+</table></center>
+</form>
+}
+
+
+#######################################################################
+# bildcancel
+#######################################################################
+
+_bildcancelscriptextra_ {
+function check\_submit (gotopage) \{
+  var form = document.collectorform;
+  form.p.value = gotopage;
+  form.submit();
+\}
+}
+_bildcancelcontent_ {
+<form name="collectorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+
+</form>
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center>
+<h2>_textbuildcancelled_</h2>
+</center>
+<div class="divbar">&nbsp;</div>
+<p>
+_textbildcancel1_
+<p><center>
+_collectorbar_
+</center>
+
+</td></tr>
+</table></center>
+}
+
+
+#######################################################################
+# bildstatus
+#######################################################################
+
+# special header for status page
+_bildstatusheader_ {_cgihead_
+_htmlhead_(class="bgimage" onLoad="initialize();")_startspacer_
+}
+_bildstatusheader_[v=1] {_cgihead_
+_htmlhead_(onLoad="initialize();")
+}
+
+_bildstatusscriptextra_ {
+var timer = 5;
+function initialize() \{
+  setTimeout("count_down()",1000);
+\}
+
+function count_down() \{
+  if (timer==0) \{
+    window.status = "";
+    document.collectorform.submit();
+  \} else \{
+    if (timer==1) \{
+	window.status = "_textbsupdate1_";
+    \} else \{
+	window.status = "_textbsupdate2_ "+timer+" _textseconds_";
+    \}
+    timer--;
+    setTimeout("count_down()",1000);
+  \}	
+\}
+}
+
+_bildstatuscontent_ {
+<form name="collectorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<center>
+<table width=_pagewidth_>
+<tr><td>
+_statusline_
+</td></tr>
+</table></center>
+</form>
+}
+
+
+#######################################################################
+# bilddone
+#######################################################################
+
+_bilddoneheader_ {_cgihead_
+_htmlhead_(class="bgimage")_startspacer_
+}
+_bilddonescriptextra_ {}
+_bilddonecontent_ {
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<p>_textbildsuc_
+
+<p>_textviewbildsummary_
+
+<p><center>
+_collectorbar_
+</center>
+
+</td></tr>
+</table></center>
+}
+
+
+#######################################################################
+# bildfail
+#######################################################################
+
+_bildfailheader_ {_cgihead_
+_htmlhead_(class="bgimage")_startspacer_
+}
+_bildfailscriptextra_ {
+function check\_submit (gotopage) \{
+  var form = document.collectorform;
+  form.p.value = gotopage;
+  form.submit();
+\}
+}
+_bildfailcontent_ {
+<form name="collectorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+
+</form>
+<center>
+<table width=_pagewidth_>
+<tr><td>
+_textfailmsg_
+</td></tr>
+</table></center>
+}
+
+# _textfailmsg_ will be set to one of the following macros from within
+# the server
+
+_textfailmsg1_ {
+_textfailmsg11_
+<p><center>
+_collectorbar_
+</center>
+}
+
+_textfailmsg6_ {_textfailmsg1_}
+
+_textfailmsg2_ {
+_textfailmsg21_
+<p>_textblcont_
+<p>_faillog_
+<p>_texttryagain_
+}
+
+_textfailmsg3_ {
+_textfailmsg31_
+<p>_textblcont_
+<p>_faillog_
+<p>_texttryagain_
+}
+
+_textfailmsg4_ {
+_textfailmsg41_
+<p>_textblcont_
+<p>_faillog_
+}
+
+_textfailmsg5_ {_textfailmsg4_}
+
+_textfailmsg7_ {
+_textfailmsg71_
+<p>_texttryagain_
+}
+
+#######################################################################
+# Error and message pages
+#######################################################################
+
+_messagehead_ {
+<form name="collectorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+}
+
+_messagefoot_ {
+<p>
+<a href="javascript:document.collectorform.submit();">_textretcoll_</a>
+<div class="divbar">&nbsp;</div>
+</td></tr>
+</table></center>
+</form>
+}
+
+_messagefootnolink_ {
+<div class="divbar">&nbsp;</div>
+</td></tr>
+</table></center>
+</form>
+}
+
+_delpermissioncontent_ {
+_messagehead_
+<p>
+_textdelperm_
+_messagefoot_
+}
+
+_delinvalidcontent_ {
+_messagehead_
+<p>
+_textdelinv_
+_messagefoot_
+}
+
+_delsuccesscontent_ {
+_messagehead_
+<p>
+_textdelsuc_
+_messagefoot_
+}
+
+_clonefailcontent_ {
+_messagehead_
+<input type=hidden name="bc1clone" value="0">
+<p>_textclonefail_
+_messagefoot_
+}
+
+_genericcontent_ {
+_messagehead_
+<p>_textcolerr_
+_messagefoot_
+}
+
+_tmpfailcontent_ {
+_messagehead_
+<p>
+_texttmpfail_
+_messagefoot_
+}
+
+_mkcolfailcontent_ {
+_messagehead_
+<p>_textmkcolfail_
+_messagefoot_
+}
+
+_nocollectioncontent_ {
+_messagehead_
+<p>_textnocontent_
+<br><a href="_httppagecollector_">_textrestart_</a>
+<p>
+_messagefootnolink_
+}
+
+_reloaderrorcontent_ {
+_messagehead_
+<p>_textreloaderror_
+<br><a href="_httppagecollector_">_textrestart_</a>
+<p>
+_messagefootnolink_
+}
+
+_exptscriptextra_ {}
+
+_exptsuccesscontent_ {
+_messagehead_
+<input type=hidden name=p value=existing>
+<p>_textexptsuc_
+_messagefoot_
+}
+
+_exptfailcontent_ {
+_messagehead_
+<input type=hidden name=p value=existing>
+_textexptfail_
+_messagefoot_
+}
+
+
+###################################################
+## text macros that are defined by another package
+###################################################
+
+_textbild_ {_wizard:textbild_}
+_textview_ {_wizard:textview_}
+_textbildsuc_ {_wizard:textbildsuc_}
+_textviewbildsummary_ {_wizard:textviewbildsummary_}
+
+_textbild1_ {_wizard:textbild1_}
+
+_textbild2_ {_wizard:textbild2_}
+
+_textstopbuild_ {_wizard:textstopbuild_}
+
+_textbild3_ {_wizard:textbild3_}
+
+_textbuildcancelled_ {_wizard:textbuildcancelled_}
+
+_textbildcancel1_ {_wizard:textbildcancel1_}
+
+
+_textbsupdate1_ {_wizard:textbsupdate1_}
+_textbsupdate2_ {_wizard:textbsupdate2_}
+_textseconds_ {_wizard:textseconds_}
+
+
+_textfailmsg11_ {_wizard:textfailmsg11_}
+_textfailmsg21_ {_wizard:textfailmsg21_}
+_textblcont_ {_wizard:textblcont_}
+
+_textfailmsg31_ {_wizard:textfailmsg31_}
+_textfailmsg41_ {_wizard:textfailmsg41_}
+_textfailmsg71_ {_wizard:textfailmsg71_}
+
Index: /gsdl/stable/macros/croatian.dm
===================================================================
--- /gsdl/stable/macros/croatian.dm	(revision 20131)
+++ /gsdl/stable/macros/croatian.dm	(revision 20131)
@@ -0,0 +1,766 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Croatian Language text and icon macros 
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=hr] {Serijske publikacije}
+_textsource_ [l=hr] {izvor: }
+_textdate_ [l=hr] {datum izdavanja: }
+_textnumpages_ [l=hr] {broj stranica: }
+
+_textsignin_ [l=hr] {prijavi se}
+
+_textdefaultcontent_ [l=hr] {TraÅŸena stranica nije pronaÄena. Molimo vas koristite funkciju 
+"back" na vaÅ¡em pregledniku ili funkciju "home" za povratak u Greenstone Digital Library.}
+
+_textdefaulttitle_ [l=hr] {GSDL PogreÅ¡ka}
+
+# -- Missing translation: _textbadcollection_
+
+# -- Missing translation: _textselectpage_
+
+_collectionextra_ [l=hr] {Ova zbirka sadrÅŸi _about:numdocs_ dokumen(a)ta. 
+Zadnji put je bila aÅŸurirana prije _about:builddate_ dana.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=hr] {<p>Ova zbirka se sastoji od _numdocs_ _If_("_numdocs_" eq "1",dokumenta,dokumenta), sa ukupno _numbytes_.
+<p><a href="_httppagex_(bsummary)">Klikni ovdje</a> za pristup sistemskim podacima o zbirci.}
+
+_textdescrcollection_ [l=hr] {}
+_textdescrabout_ [l=hr] {O zbirci}
+_textdescrhome_ [l=hr] {Naslovna stranica}
+_textdescrhelp_ [l=hr] {PomoÄ}
+_textdescrpref_ [l=hr] {Postavke}
+_textdescrgreenstone_ [l=hr] {Greenstone Digital Library Softver}
+# -- Missing translation: _textdescrusab_
+
+_textdescrSearch_ [l=hr] {TraÅŸi prema odreÄenim pojmovima}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=hr] {Pregledaj abecedni popis naslova}
+_textdescrCreator_ [l=hr] {Pregledaj abecedni popis autora}
+_textdescrSubject_ [l=hr] {Pregledaj prema podruÄjima po kojima je razvrstana graÄa}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=hr] {Pregledaj prema datumu}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+_textdescrSource_ [l=hr] {Pregledaj prema izvornom nazivu datoteke}
+_textdescrLanguage_ [l=hr] {Pregledaj prema jeziku}
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=hr] {Pregledaj prema nazivu organizacije}
+_textdescrKeyword_ [l=hr] {Pregledaj prema kljuÄnim rijeÄima}
+_textdescrHowto_ [l=hr] {Pregledaj "Kako da" kategoriju}
+_textdescrList_ [l=hr] {Pregledaj popis dokumenata ukljuÄenih u zbirku}
+_textdescrSeries_ [l=hr] {Pregledaj prema izdanju}
+# -- Missing translation: _textdescrTo_
+# -- Missing translation: _textdescrFrom_
+_textdescrTopic_ [l=hr] {Pregledaj specijalni izbor tema}
+_textdescrBrowse_ [l=hr] {Pregledaj}
+# -- Missing translation: _textdescrCollage_
+_textdescrPeople_ [l=hr] {Pregledaj abecedni popis osoba}
+_textdescrAcronym_ [l=hr] {Pregled akronima}
+_textdescrPhrase_ [l=hr] {Pregled fraza}
+_textdescrArtist_ [l=hr] {Pregled umjetnika}
+# -- Missing translation: _textdescrVolume_
+# -- Missing translation: _textdescrCountries_
+# -- Missing translation: _textdescrCaptions_
+
+
+_labelSearch_ [l=hr] {TraÅŸi}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=hr] {Naslovi A-Z}
+_labelCreator_ [l=hr] {Autori A-Z}
+_labelSubject_ [l=hr] {PodruÄja}
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=hr] {Datumi}
+# -- Missing translation: _labelType_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+_labelSource_ [l=hr] {Datoteke}
+_labelLanguage_ [l=hr] {Jezik}
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=hr] {Organizacije}
+_labelKeyword_ [l=hr] {KljuÄne rijeÄi}
+_labelHow_ [l=hr] {Kako da}
+_labelSeries_ [l=hr] {Nizovi}
+_labelList_ [l=hr] {Ispis}
+# -- Missing translation: _labelTo_
+# -- Missing translation: _labelFrom_
+_labelTopic_ [l=hr] {Teme}
+_labelBrwse_ [l=hr] {Pregled}
+# -- Missing translation: _labelCollage_
+_labelBrows_ [l=hr] {Pregled}
+_labelPeople_ [l=hr] {Ljudi A-Z}
+_labelAcronym_ [l=hr] {Akronimi}
+_labelPhrase_ [l=hr] {Fraze}
+_labelArtist_ [l=hr] {Umjetnici}
+# -- Missing translation: _labelVolume_
+# -- Missing translation: _labelCaptions_
+# -- Missing translation: _labelCountries_
+
+_texticontext_ [l=hr] {Pogledaj dokument}
+_texticonclosedbook_ [l=hr] {otvori ovaj dokument i pogledaj njegov sadrÅŸaj}
+_texticonnext_ [l=hr] {sljedeÄi odjeljak}
+_texticonprev_ [l=hr] {prethodni odjeljak}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=hr] {Pogledaj dokument u MIDI formatu}
+_texticonmsword_ [l=hr] {Pogledaj dokument u Microsoft Word formatu}
+_texticonmp3_ [l=hr] {Pogledaj dokument u MP3 formatu}
+_texticonpdf_ [l=hr] {Pogledaj dokument u PDF formatu}
+_texticonps_ [l=hr] {Pogledaj dokument u PostScript formatu}
+_texticonppt_ [l=hr] {Pogledaj dokument PowerPoint formatu}
+_texticonrtf_ [l=hr] {Pogledaj dokument u RTF formatu}
+_texticonxls_ [l=hr] {Pogledaj dokument u Microsoft Excel formatu}
+
+_page_ [l=hr] {stranica }
+_pages_ [l=hr] {stranice}
+_of_ [l=hr] {od }
+_vol_ [l=hr] {Br.}
+_num_ [l=hr] {Br.}
+
+_textmonth00_ [l=hr] {}
+_textmonth01_ [l=hr] {SijeÄanj}
+_textmonth02_ [l=hr] {VeljaÄa}
+_textmonth03_ [l=hr] {OÅŸujak}
+_textmonth04_ [l=hr] {Travanj}
+_textmonth05_ [l=hr] {Svibanj}
+_textmonth06_ [l=hr] {Lipanj}
+_textmonth07_ [l=hr] {Srpanj}
+_textmonth08_ [l=hr] {Kolovoz}
+_textmonth09_ [l=hr] {Rujan}
+_textmonth10_ [l=hr] {Listopad}
+_textmonth11_ [l=hr] {Studeni}
+_textmonth12_ [l=hr] {Prosinac}
+
+# -- Missing translation: _textdocument_
+# -- Missing translation: _textsection_
+# -- Missing translation: _textparagraph_
+
+_magazines_ [l=hr] {Äasopisi}
+
+_nzdlpagefooter_ [l=hr] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}
+
+_linktextHOME_ [l=hr] {NASLOVNA}
+_linktextHELP_ [l=hr] {POMOÄ}
+_linktextPREFERENCES_ [l=hr] {POSTAVKE}
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=hr] {O zbirci}
+
+_textsubcols1_ [l=hr] {<p>Cijela zbirka sadrÅŸi _1_ podzbirk(i)e. 
+Trenutno su dostupne: 
+<blockquote>}
+
+_textsubcols2_ [l=hr] {</blockquote>
+MoÅŸeÅ¡ provjeriti (i promijeniti) podzbirku koju trenutno koristiÅ¡ na stranici Postavke.}
+
+
+_titleabout_ [l=hr] {o zbirci}
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+# -- Missing translation: _texticonhcoll_
+# -- Missing translation: _texticonhto_
+# -- Missing translation: _texticonhfrom_
+# -- Missing translation: _texticonhvol_
+# -- Missing translation: _texticonhcapt_
+# -- Missing translation: _texticonhcount_
+
+_texticonopenbookshelf_ [l=hr] {zatvori ovaj odjeljak zbirke}
+_texticonclosedbookshelf_ [l=hr] {otvori ovaj odjeljak zbirke i pogledaj sadrÅŸaj}
+_texticonopenbook_ [l=hr] {zatvori dokument}
+_texticonclosedfolder_ [l=hr] {otvori ovu mapu i pogledaj sadrÅŸaj}
+_texticonclosedfolder2_ [l=hr] {otvori pod-odjeljak: }
+_texticonopenfolder_ [l=hr] {zatvori mapu}
+_texticonopenfolder2_ [l=hr] {zatvori pod-odjeljak: }
+_texticonsmalltext_ [l=hr] {Pogledaj tekst ovog odjeljka}
+_texticonsmalltext2_ [l=hr] {pogledaj tekst: }
+_texticonpointer_ [l=hr] {trenutni odjeljak}
+_texticondetach_ [l=hr] {Otvori ovu stranicu u novom prozoru}
+_texticonhighlight_ [l=hr] {OznaÄi traÅŸene pojmove}
+_texticonnohighlight_ [l=hr] {Nemoj oznaÄavati traÅŸene pojmove}
+_texticoncontracttoc_ [l=hr] {SaÅŸmi prikaz sadrÅŸaja}
+_texticonexpandtoc_ [l=hr] {PrikaÅŸi sadrÅŸaj}
+_texticonexpandtext_ [l=hr] {PrikaÅŸi cijeli tekst}
+_texticoncontracttext_ [l=hr] {PrikaÅŸi tekst samo trenutno oznaÄenog odjeljka}
+_texticonwarning_ [l=hr] {<b>Upozorenje: </b>}
+_texticoncont_ [l=hr] {nastavak?}
+
+_textltwarning_ [l=hr] {<div class="buttons">_imagecont_</div>
+_iconwarning_Dodavanje novog teksta Äe generirati veliku koliÄinu podataka 
+za prikaz u VaÅ¡em pregledniku
+}
+
+_textgoto_ [l=hr] {idi na stranicu}
+_textintro_ [l=hr] {<i>(uvodni tekst)</i>}
+
+_textCONTINUE_ [l=hr] {NASTAVAK?}
+
+_textEXPANDTEXT_ [l=hr] {PRIKAÅœI\nTEKST}
+
+_textCONTRACTCONTENTS_ [l=hr] {SAÅœMI\nSADRÅœAJ}
+
+_textDETACH_ [l=hr] {NOVI\nPROZOR}
+
+_textEXPANDCONTENTS_ [l=hr] {PRIKAÅœI\nSADRÅœAJ}
+
+_textCONTRACT_ [l=hr] {SAÅœMI\nTEKST}
+
+_textHIGHLIGHT_ [l=hr] {OZNAÄAVANJE}
+
+_textNOHIGHLIGHT_ [l=hr] {BEZ\nOZNAÄAVANJA}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=hr] {_If_(_thislast_,results _thisfirst_ - _thislast_ za upit: _cgiargq_, Ne zadovoljava upit: _cgiargq_)}
+_textnoquerytitle_ [l=hr] {PretraÅŸivanje}
+
+_textsome_ [l=hr] {_If_(_cgiargb_,nizane,neke)}
+_textall_ [l=hr] {_If_(_cgiargb_,booleove,sve)}
+# -- Missing translation: _textboolean_
+# -- Missing translation: _textranked_
+# -- Missing translation: _textnatural_
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=hr] {Popis prethodnih pretraÅŸivanja}
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+_textusequery_ [l=hr] {koristi ovaj upit}
+_textfreqmsg1_ [l=hr] {Broj rijeÄi: }
+# -- Missing translation: _textpostprocess_
+# -- Missing translation: _textinvalidquery_
+
+_textmorethan_ [l=hr] {ViÅ¡e od }
+_textapprox_ [l=hr] {O }
+_textnodocs_ [l=hr] {Nijedan dokument ne zadovoljava upit.}
+_text1doc_ [l=hr] {1 dokument zadovoljava upit.}
+_textlotsdocs_ [l=hr] {dokumenta zadovoljavaju upit.}
+_textmatches_ [l=hr] {Zadovoljava }
+_textbeginsearch_ [l=hr] {PoÄetak pretraÅŸivanja}
+_textrunquery_ [l=hr] {IzvrÅ¡i upit}
+_textclearform_ [l=hr] {Novi upit}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=hr] {RijeÄ ili frazu}
+_textinfield_ [l=hr] {... u polju}
+# -- Missing translation: _textfoldstem_
+
+_textadvquery_ [l=hr] {Ili unesi upit izravno:}
+_textallfields_ [l=hr] {Sva polja}
+# -- Missing translation: _texttextonly_
+_textand_ [l=hr] {i}
+_textor_ [l=hr] {ili}
+_textandnot_ [l=hr] {i ne}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=hr] {TraÅŸi prema _indexselection_ _If_(_jselection_, of _jselection_) _If_(_gselection_, at _gselection_ level) _If_(_nselection_, in _nselection_ language) koji sadrÅŸi _querytypeselection_ rijeÄi}
+
+_textadvancedsearch_ [l=hr] {TraÅŸi _indexselection_ _If_(_jselection_,of _jselection_) _If_(_gselection_, at _gselection_ level)_If_(_nselection_, in _nselection_ language) koristeÄi _querytypeselection_ upite}
+
+_textformsimplesearch_ [l=hr] {TraÅŸi prema _If_(_jselection_, _jselection_) _If_(_gselection_, at _gselection_ level) _If_(_nselection_, in _nselection_ language)
+koji sadrÅŸi _formquerytypesimpleselection_ of}
+
+_textformadvancedsearch_ [l=hr] {TraÅŸi _If_(_jselection_,_jselection_) _If_(_gselection_, at _gselection_ level)_If_(_nselection_, in _nselection_ language) 
+i prikaÅŸi rezultate po _formquerytypeadvancedselection_ redu}
+
+
+# -- Missing translation: _textnojsformwarning_
+# -- Missing translation: _textdatesearch_
+# -- Missing translation: _textstartdate_
+# -- Missing translation: _textenddate_
+# -- Missing translation: _textbc_
+# -- Missing translation: _textad_
+# -- Missing translation: _textexplaineras_
+
+_textstemon_ [l=hr] {(ne uzima u obzir krajeve rijeÄi)}
+
+_textsearchhistory_ [l=hr] {Popis prethodnih pretraÅŸivanja}
+
+#text macros for search history
+_textnohistory_ [l=hr] {Popis prethodnih pretraÅŸivanja nije dostupan}
+_texthresult_ [l=hr] {rezultat}
+_texthresults_ [l=hr] {rezultata}
+_texthallwords_ [l=hr] {sve rijeÄi}
+_texthsomewords_ [l=hr] {neke rijeÄi}
+_texthboolean_ [l=hr] {booleov}
+_texthranked_ [l=hr] {nizan}
+_texthcaseon_ [l=hr] {prepoznaje velika slova}
+_texthcaseoff_ [l=hr] {ne prepoznaje velika slova}
+_texthstemon_ [l=hr] {nepotpuna rijeÄ}
+_texthstemoff_ [l=hr] {potpuna rijeÄ}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=hr] {Postavke su podeÅ¡ene kako slijedi. Ne koristite gumb za povratak u pregledniku
+kako bi postavljene vrijednosti i saÄuvali! Umjesto toga, kliknite na 
+jednu od gornjih poveznica za nastavak. }
+_textsetprefs_ [l=hr] {podesi postavke}
+_textsearchprefs_ [l=hr] {Postavke pretraÅŸivanja}
+_textcollectionprefs_ [l=hr] {Postavke zbirke}
+_textpresentationprefs_ [l=hr] {Postavke prezentacije ili prikaza}
+_textpreferences_ [l=hr] {Postavke}
+_textcasediffs_ [l=hr] {Razlika izmeÄu malih i velikih slova:}
+_textignorecase_ [l=hr] {ne uzimaj u obzir razliku izmeÄu malih i velikih slova}
+_textmatchcase_ [l=hr] {razlika izmeÄu malih i velikih slova mora biti uzeta u obzir:}
+_textwordends_ [l=hr] {Krajevi rijeÄi:}
+_textstem_ [l=hr] {ne uzimaj u obzir krajeve rijeÄi}
+_textnostem_ [l=hr] {cijela rijeÄ mora biti uzeta u obzir}
+_textprefop_ [l=hr] {Vrati do _maxdocoption_ zadovoljavajuÄih odgovora na upit i prikaÅŸi ih _hitsperpageoption_ po stranici.}
+_textextlink_ [l=hr] {Pristup vanjskim mreÅŸnim stranicama:}
+_textintlink_ [l=hr] {Izvorni dokumenti pronaÄeni u:}
+_textlanguage_ [l=hr] {Jezik suÄelja:}
+_textencoding_ [l=hr] {Kodiranje:}
+_textformat_ [l=hr] {Format suÄelja:}
+_textall_ [l=hr] {sve}
+_textquerymode_ [l=hr] {NaÄini pretraÅŸivanja:}
+_textsimplemode_ [l=hr] {jednostavno pretraÅŸivanje}
+_textadvancedmode_ [l=hr] {napredno pretraÅŸivanje (dopuÅ¡tena uporaba Booleovih operatora !, &, |, i zagrada)}
+_textlinkinterm_ [l=hr] {kroz posredniÄku stranicu}
+_textlinkdirect_ [l=hr] {idi izravno tamo}
+_textdigitlib_ [l=hr] {digitalna knjiÅŸnica}
+_textweb_ [l=hr] {web}
+_textgraphical_ [l=hr] {GrafiÄko}
+_texttextual_ [l=hr] {Tekstualno}
+_textcollectionoption_ [l=hr] {<p>
+Subcollections to include:
+<br>}
+
+_textrelateddocdisplay_ [l=hr] {prikaÅŸi srodne dokumente}
+_textsearchhistory_ [l=hr] {Popis prethodnih pretraÅŸivanja:}
+# -- Missing translation: _textnohistory_
+_texthistorydisplay_ [l=hr] {prikaÅŸi _historynumrecords_ popis prethodnih pretraÅŸivanja}
+_textnohistorydisplay_ [l=hr] {nemoj prikazati popis prethodnih pretraÅŸivanja}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=hr] {obrazac pretraÅŸivanja}
+# -- Missing translation: _textplainsearch_
+_textqueryboxsize_ [l=hr] {VeliÄina okvira za upit:}
+_textregbox_ [l=hr] {obiÄni okvir za upit}
+_textbigbox_ [l=hr] {veliki okvir za upit}
+_textformtype_ [l=hr] {Tip obrasca:}
+_textsimple_ [l=hr] {jednostavno}
+_textadvanced_ [l=hr] {napredno}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=hr] {sa}
+_textfields_ [l=hr] {polja}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+# -- Missing translation: _textsortby_
+# -- Missing translation: _textalsoshowing_
+# -- Missing translation: _textwith_
+# -- Missing translation: _textdocsperpage_
+
+# -- Missing translation: _textfilterby_
+# -- Missing translation: _textall_
+# -- Missing translation: _textany_
+# -- Missing translation: _textwords_
+# -- Missing translation: _textleaveblank_
+
+# -- Missing translation: _browsebuttontext_
+
+# -- Missing translation: _nodata_
+# -- Missing translation: _docs_
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=hr] {PomoÄ}
+_textSearchshort_ [l=hr] {pretraÅŸivanjem prema pojedinim rijeÄima}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=hr] {pristupom traÅŸenoj graÄi putem naslova}
+_textCreatorshort_ [l=hr] {pristupom traÅŸenoj graÄi putem imena autora}
+_textSubjectshort_ [l=hr] {pristupom traÅŸenoj graÄi preko podruÄja po kojima je razvrstana}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=hr] {pristupom traÅŸenoj graÄi odabirom vremena njenog nastanka}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=hr] {pristupom traÅŸenoj graÄi putem naziva datoteka}
+_textLanguageshort_ [l=hr] {pristupom traÅŸenoj graÄi putem odabira jezika}
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=hr] {pristupom traÅŸenoj graÄi putem naziva nizova}
+# -- Missing translation: _textToshort_
+# -- Missing translation: _textFromshort_
+_textBrowseshort_ [l=hr] {pregledavanjem digitalne graÄe}
+_textOrganizationshort_ [l=hr] {pristupom traÅŸenoj graÄi putem naziva organizacija}
+_textHowtoshort_ [l=hr] {pristupom traÅŸenoj graÄi putem "Kako da" kategorije}
+_textTopicshort_ [l=hr] {pristupom traÅŸenoj graÄi putem naziva tema}
+_textPeopleshort_ [l=hr] {pristupom traÅŸenoj graÄi putem imena osoba}
+_textAcronymshort_ [l=hr] {pristupom traÅŸenoj graÄi putem akronima}
+_textPhraseshort_ [l=hr] {pregledavanjem fraza koje se javljaju u digitalnoj graÄi}
+_textArtistshort_ [l=hr] {pristupom traÅŸenoj graÄi putem imena umjetnika}
+_textKeywordshort_ [l=hr] {pristupom traÅŸenoj graÄi putem kljuÄnih rijeÄi}
+# -- Missing translation: _textVolumeshort_
+# -- Missing translation: _textCountriesshort_
+_textdefaultshorttext_ [l=hr] {klasifikacijom koja nije definirana}
+
+_textSearchlong_ [l=hr] {<p>MoÅŸete <i>pretraÅŸivati prema pojedinim rijeÄima</i> koje se pojavljuju u tekstu
+ na stranici "traÅŸi". To je prva stranica koja se prikazuje kod otvaranja zbirke 
+, a kojoj se moÅŸe pristupiti sa drugih stranica zbirke pritiskom na gumb 
+ <i>traÅŸi</i>.  }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi putem naslova dokumenta i odjeljaka unutar dokumenta</i> pritiskom na gumb
+ <i>naslovi a-z</i>.  Prikazuje se popis naslova prema abecednom redu.  }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi putem imena autora</i> pritiskom na gumb
+ <i>autori a-z</i>.  Prikazuje se popis knjiga sortiran prema imenu autora.  }
+
+_textSubjectlong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi preko podruÄja u kojima je razsvrstana</i> pritiskom na gumb
+ <i>podruÄja</i>.  Prikazuje se popis podruÄja po kojima je graÄa razvrstana, reprezentirana tzv. policama za knjige.  }
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi odabirom datuma odnosno vremena njenog nastanka </i> pritiskom na gumb
+ <i>datumi</i>.  Prikazuje se popis svih izdanja sortiran kronoloÅ¡ki.  }
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=hr] {<p>MoÅŸete <i>pristupiti traÅŸenoj graÄi putem naziva datoteka</i> pritiskom na gumb
+ <i>datoteke</i>.  Prikazuje se popis izvornih datoteka ukljuÄenih u zbirku prema abecednom redu.  }
+
+_textLanguagelong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi putem odabira jezika</i> pritiskom na gumb
+ <i>jezici</i>.  Prikazuje se popis jezika kojima je zbirka zastupljena.  }
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi putem naziva organizacija
+</i> pritiskom na gumb <i>organizacije</i>.  Prikazuje se popis naziva organizacija. }
+
+_textHowtolong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi putem "Kako da" kategorije</i>
+pritiskom na gumb <i>kako da</i>.  Prikazuje se popis "Kako da" fraza.  }
+
+_textTopiclong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi putem naziva tema</i> pritiskom na gumb
+ <i>teme</i>.  Prikazuje se popis zastupljenih tema.  }
+
+# -- Missing translation: _textTolong_
+
+# -- Missing translation: _textFromlong_
+
+_textSerieslong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi putem naziva nizova</i> pritiskom na gumb
+ <i>nizovi</i>.  Prikazuje se popis nizova koji su trenutno zastupljeni u zbirci.  }
+
+_textBrowselong_ [l=hr] {<p>MoÅŸete <i>pregledavati graÄu</i> pritiskom na gumb
+<i>pregled</i>.  }
+
+_textPeoplelong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi putem imena osoba</i> pritiskom na gumb
+ <i>ljudi a-z</i>.  Prikazuje se popis osoba sortiran prema njihovim prezimenima.  }
+
+_textAcronymlong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi putem akronima koji se u njoj javljaju</i> pritiskom na gumb
+ <i>akronimi</i>.  Prikazuje se popis akronima i mjesta gdje se pojavljuju.  }
+
+_textPhraselong_ [l=hr] {<p>MoÅŸete <i>pregledavati fraze koje se javljaju u graÄi</i> pritiskom na gumb
+ <i>fraze</i>.  Prikazuje se popis fraza zastupljenih u zbirci.  }
+
+_textArtistlong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi putem imena umjetnika</i> pritiskom na gumb
+ <i>umjetnici</i>.  Prikazuje se popis imena umjetnika.  }
+
+_textKeywordlong_ [l=hr] {<p>MoÅŸete <i>pristupiti graÄi putem kljuÄnih rijeÄi</i> pritiskom na gumb <i>kljuÄne rijeÄi</i>. 
+Prikazuje se lista kljuÄnih rijeÄi u obliku kazala. }
+
+# -- Missing translation: _textVolumelong_
+
+# -- Missing translation: _textCaptionslong_
+
+# -- Missing translation: _textCountrieslong_
+
+
+_textdefaultlongtext_ [l=hr] {<p>Kliknite na gumb <i>nepoznato</i> da pregledavate
+ graÄu (sortiranu prema nepoznatom polju).  }
+
+_texthelptopicstitle_ [l=hr] {Teme}
+
+_textreadingdocs_ [l=hr] {Kako Äitati dokumente}
+
+_texthelpreadingdocs_ [l=hr] {
+<p>Kada otvorite zasebni dokument njegov naslov i autor se pojavljuju u lijevom gornjem kutu stranice 
+(Ponekad to moze biti i slika, naprimjer dobivena skeniranjem korica knjige, koja reprezentira dokument).   
+Pored njih se nalazi podatak o stranici na kojoj se trenutno nalazite, te se nudi moguÄnost odabira sljedeÄe stranice ili povratak na prethodnu. 
+Ove moguÄnosti su opcionalne i moraju se posebno definirati u konfiguracijskim postavkama.
+
+<p>Ispod se prikazuje tekst odjeljka na kojem se trenutno nalazite. Na dnu svake stranice moguÄe je postaviti vodiÄe u obliku strelica 
+koji vode na narednu ili prethodnu stranicu odjeljka.
+
+<p>Ispod naslova i autora odnosno zasebne slike koja predstavlja dokument nalaze se tri gumba. Klikom na <i>prikaÅŸi 
+tekst</i> prikazat Äe se cijeli tekst dokumenta. 
+Ako je rijeÄ o velikom dokumentu moÅŸda Äe trebati vremena da se on uÄita u preglednik. 
+Klikom na <i>novi prozor</i> dokument Äe se otvoriti u novom prozoru preglednika (Ovo je korisno ako ÅŸelite uporediti dokumente ili ih Äitati istovremeno.)  
+KonaÄno, kod pretraÅŸivanja traÅŸeni pojam je u tekstu oznaÄen ÅŸutom bojom.
+Klikom na <i>bez oznacavanja</i> otklanjate ovu moguÄnost.
+}
+
+# help about the icons
+_texthelpexpandtext_ [l=hr] {PrikaÅŸi cijeli tekst, ili ne}
+_texthelpdetachpage_ [l=hr] {Otvori stranicu u novom prozoru}
+_texthelphighlight_ [l=hr] {OznaÄi traÅŸene pojmove, ili ne}
+
+
+_texthelpsearchingtitle_ [l=hr] {Kako pretraÅŸivati prema pojedinim rijeÄima}
+
+_texthelpsearching_ [l=hr] {
+<p>
+  Na stranici za pretraÅŸivanje, moÅŸete oblikovati upit na osnovu ovih jednostavnih koraka:<p>
+  
+  <ol><li>PobliÅŸe oznaÄiti traÅŸeni pojam
+      <li>Odrediti hoÄe li se pretraÅŸivanje obaviti prema svim ili samo nekim rijeÄima zadanim u prethodnom koraku
+      <li>Upisati rijeÄi koje ÅŸelite pronaÄi
+      <li>Kliknuti na gumb <i>PoÄetak pretraÅŸivanja</i>
+  </ol>
+
+<p>Na zaslonu Äe se potom prikazati najviÅ¡e dvadeset naslova koji prema definiranim kriterijima 
+zadovoljavaju upit. Pri dnu stranice se nalazi gumb koji omoguÄuje prikaz narednih dvadeset dokumenata itd.
+Klikom na naslov dokumenta prikazuje se tekst dokumenta.
+
+<p>NajviÅ¡e 100 dokumenta koji prema odabranim kriterijima zadovoljavaju upit mogu biti vraÄeni kao rezultati pretrage. 
+Broj prikazanih rezultata moÅŸete takoÄer promijeniti na stranici <i>postavke</i> digitalne zbirke.<p>
+}
+
+_texthelpquerytermstitle_ [l=hr] {TraÅŸeni pojmovi}
+_texthelpqueryterms_ [l=hr] {
+<p>Å to god da unesete u okvir za upit interpretira se kao niz rijeÄi poznat pod nazivom "traÅŸeni pojmovi".
+ Svaki traÅŸeni pojam se moÅŸe sastojati od slova i brojki. Pojmovi su odvojeni razmakom. 
+ Znakovi interpunkcije se zanemaruju te se tretiraju kao razmaci. 
+ To znaÄi da ne moÅŸete pretraÅŸivati putem rijeÄi koje u sebi sadrÅŸe znakove interpunkcije.
+
+<p>Naprimjer, upit<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>biti Äe tretiran kao da ste upisali:<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}
+
+_texthelpquerytypetitle_ [l=hr] {Vrste upita}
+_texthelpquerytype_ [l=hr] {
+<p>Postoje dvije vrste upita.
+
+<ul>
+  <li>Upiti za <b>sve</b> rijeÄi.  Ova vrsta upita pretraÅŸuje dokumente (ili
+      poglavlja, ili naslove) koji sadrÅŸe sve rijeÄi navedene u upitu.
+      Dokumenti koji zadovoljavaju upit prikazuju se prema abecednom redu.<p>
+
+  <li>Upiti za <b>neke</b> rijeÄi.  Upiti ove vrste vraÄaju popis pojmova koji se najvjerojatnije pojavljuju u dokumentima koji se pretraÅŸuju.
+  Dokumenti se prikazuju prema stupnju zadovoljenja upita. 
+  Kod odreÄivanja stupnja zadovoljenja upita:
+      <p><ul>
+        <li> dokument sadrÅŸi viÅ¡e traÅŸenih pojmova, stupanj je viÅ¡i;
+        <li> rijetki pojmovi su mnogo vaÅŸniji od onih koji se ÄeÅ¡Äe upotrebljavaju;
+        <li> kraÄi dokumenti su bolje rjeÅ¡enje od duljih.
+        </ul>
+</ul>
+
+<p>MoÅŸete koristiti onoliko traÅŸenih pojmova koliko ÅŸelite - cijele reÄenice,
+ili Äak cijele odlomke. Ako specificirate samo jedan pojam, dokumenti u odgovoru Äe biti prikazani u redosljedu prema
+uÄestalosti pojavljivanja traÅŸenog pojma u njima.<p>
+}
+
+# -- Missing translation: _textdatesearch_
+
+# -- Missing translation: _texthelpdatesearch_
+
+_textchangeprefs_ [l=hr] {Izmjena VaÅ¡ih postavki}
+
+_texthelppreferences_ [l=hr] {
+<p>Ako kliknete na gumb <i>postavke</i> na vrhu svake stranice, moÄi Äe te  
+mijenjati neka svojstva prikaza zbirke u suÄelju, te prema VaÅ¡im Å
+Ÿeljama i potrebama utjecati na neke postavke pretraÅŸivanja.
+}
+_texthelpcollectionprefstitle_ [l=hr] {Postavke zbirki}
+_texthelpcollectionprefs_ [l=hr] {
+Neke zbirke ukljuÄuju viÅ¡e pojedinaÄnih zbirki, koje se onda mogu pretraÅŸivati ili zasebno ili zajedno.
+MoÅŸete odabrati koju pojedinaÄnu zbirku ÅŸelite ukljuÄiti u VaÅ¡e pretraÅŸivanje na stranici Postavke.
+}
+
+_texthelplanguageprefstitle_ [l=hr] {JeziÄne postavke}
+_texthelplanguageprefs_ [l=hr] {
+Iako svaka zbirka ima odreÄenu vrijednost jezika koji se upotrebljava za predstavljanje zbirke, 
+moÅŸete odabrati i neki drugi jezik.
+Isto tako, moÅŸete promjeniti i kodnu stranicu za zadovoljavajuÄi prikaz znakova u pregledniku.
+Sve zbirke dopuÅ¡taju odabir izmeÄu standardnog grafiÄkog i tekstualnog suÄelja.
+Ovo je naroÄito pogodno za korisnike sa posebnim potrebama koji rabe veÄe ekrane ili 
+sintetizatore govora kao krajnje izlaze.
+}
+
+_texthelppresentationprefstitle_ [l=hr] {Postavke prikaza}
+_texthelppresentationprefs_ [l=hr] {
+Ovisno o pojedinoj zbirci, postoji nekoliko naÄina uspostavljanja nadzora njenog prikaza.
+
+<p>Zbirke mreÅŸnih stranica dopuÅ¡taju neprikazivanje 
+Greenstone navigacijskih gumba na vrhu stranice dokumenata koji zadovoljavaju upit. 
+Drugim rijeÄima, nakon zavrÅ¡enog pretraÅŸivanja moÅŸete uÄitati mreÅŸnu stranicu koja zadovoljava upit 
+bez pojavljivanja bilo kakvog Greenstone zaglavlja na uÄitanoj stranici. 
+Za naredno pretraÅŸivanje prisiljeni ste koristiti opciju preglednika 
+za povratak na prethodnu stranicu (klikom na "back" gumb).  
+Isto tako, ove su zbirke u moguÄnosti sprijeÄiti pojavljivanje Greenstone upozoravajuÄe poruke 
+u sluÄaju klika na poveznicu koja vas vodi izvan zbirke digitalne knjiÅŸnice odnosno na sam Web. 
+U nekim mreÅŸnim zbirkama moÅŸete uÄiniti da poveznice sa stranica izlistanih rezultata 
+vode ravno na pripadajuÄe URL-ove mreÅŸnih stranica koje zadovoljavaju upit a ne na kopije tih 
+dokumenata pohranjenih u digitalnoj zbirci. 
+}
+
+_texthelpsearchprefstitle_ [l=hr] {Postavke pretraÅŸivanja}
+_texthelpsearchprefs_ [l=hr] {
+<p>
+Dva para radio-gumba kontroliraju oblik teksta zadanog u upitu. Prvi par 
+(nazvan "Razlika izmeÄu malih i velikih slova") odreÄuje da li je razlikovanje malih i velikih slova u 
+postavljenom upitu vaÅŸna. Drugi par ("Krajevi rijeÄi") odreÄuje hoÄe li krajevi rijeÄi u postavljenom upitu
+biti ignorirani ili ne. Isto tako, postoji moguÄnost postavljanja upita u velikom okviru za upit Å¡to pruÅŸa
+moguÄnost oblikovanja upita putem cijelih odlomaka. To naroÄito pomaÅŸe kod pretraÅŸivanja velike koliÄine 
+teksta.
+
+<p>Naprimjer, ako su odabrane postavke pretraÅŸivanja <i>ignoriraj razliku izmeÄu malih i velikih slova</i> i
+<i>ignoriraj krajeve rijeÄi</i> upit<p>
+    <ul><kbd>African building</kbd></ul>
+      <p>bio bi tretiran isto kao i <p>
+      <ul><kbd>africa builds</kbd></ul><p>
+      jer se veliko slovo u "African", ovim odabranim postavkama pretraÅŸivanja, pretvara u malo slovo
+      , dok se nastavci "n" i "ing" potpuno uklanjaju (naravno, kao i nastavak "s" u rijeÄi "builds").
+
+<p>MoÅŸete odabrati i moguÄnost naprednog pretraÅŸivanja koja dopuÅ¡ta u upitu kombinaciju pojmova i Booleovih operatora AND (&),
+OR (|) i NOT (!). Ovo pridonosi uspjeÅ¡nijem oblikovanju upita.
+Isto tako, moÅŸete ukljuÄiti i Popis prethodnih pretraÅŸivanja Å¡to vam daje moguÄnost 
+laganog preoblikovanja prethodnih upita s ciljem dobivanja Å¡to toÄnijih odgovora. KonaÄno, moÅŸete kontrolirati i broj 
+ vraÄenih odgovora na postavljeni upit jednostavnim odabirom ponuÄenih brojeva u padajuÄem izborniku.
+}
+
+_texttanumbrowseoptions_ [l=hr] {Postoji _numbrowseoptions_ naÄina kako pronaÄi traÅŸenu informaciju u zbirci:}
+
+_textsimplehelpheading_ [l=hr] {Kako pronaÄi traÅŸenu informaciju u _collectionname_ }
+
+_texthelpscopetitle_ [l=hr] {Opseg upita}
+_texthelpscope_ [l=hr] {
+<p>
+U veÄini zbirki moÅŸete odabrati pretraÅŸivanje prema razliÄitim indeksima. Primjerice, moÅŸete pretraÅŸivati prema 
+indeksu autora ili naslova. Isto tako, moÅŸete pretraÅŸivati prema indeksima odjeljka ili odlomka. OpÄenito govoreÄi, 
+traÅŸeni dokument je moguÄe pronaÄi neovisno o tome koji se indeks koristi. 
+<p>Ako su dokumenti knjige, otvoriti Äe se upravo na odgovarajuÄim mjestima.
+}
Index: /gsdl/stable/macros/czech.dm
===================================================================
--- /gsdl/stable/macros/czech.dm	(revision 20131)
+++ /gsdl/stable/macros/czech.dm	(revision 20131)
@@ -0,0 +1,852 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Czech Language text and icon macros 
+# Many thanks to Roman Chyla and Jakub Rehan (translated 2003 & 2004)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=cs] {Periodika}
+_textsource_ [l=cs] {zdroj }
+_textdate_ [l=cs] {datum publikovÃ¡nÃ­: }
+_textnumpages_ [l=cs] {poÄet stran: }
+
+_textsignin_ [l=cs] {pÅihlÃ¡sit se}
+
+_textdefaultcontent_ [l=cs] {PoÅŸadovanÃ¡ strÃ¡nka nemohla bÃœt nalezena. ProsÃ­me, pouÅŸijte tlaÄÃ­tko 'zpÄt' pro nÃ¡vrat do digitÃ¡lnÃ­ knihovny Greenstone .}
+
+_textdefaulttitle_ [l=cs] {Chyba GSDL}
+
+_textbadcollection_ [l=cs] {Tato kolekce (nazvanÃ¡ "_cvariable_") nenÃ­ nainstalovÃ¡na na tomto systÃ©mu knihovny Greenstone.}
+
+_textselectpage_ [l=cs] {-- Select Page --}
+
+_collectionextra_ [l=cs] {Tato kolekce obsahuje _about:numdocs_ dokumentÅ¯. Byla vytvoÅena pÅed _about:builddate_ dny.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=cs] {<p>Tato kolekce obsahuje _numdocs_ _If_("_numdocs_" eq "1",dokument,documentÅ¯), celkem _numbytes_ B.
+<p><a href="_httppagex_(bsummary)">KliknÄte sem!</a> - souhrn ÃºdajÅ¯ o tÃ©to kolekci.
+}
+
+_textdescrcollection_ [l=cs] {}
+_textdescrabout_ [l=cs] {O tÃ©to kolekci}
+_textdescrhome_ [l=cs] {Homepage}
+_textdescrhelp_ [l=cs] {NÃ¡povÄda}
+_textdescrpref_ [l=cs] {NastavenÃ­}
+_textdescrgreenstone_ [l=cs] {Greenstone Digital Library Software}
+_textdescrusab_ [l=cs] {Co se VÃ¡m zdÃ¡lo obtÃ­ÅŸnÃ©?}
+
+_textdescrSearch_ [l=cs] {Hledej urÄitÃ© vÃœrazy}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=cs] {ProchÃ¡zej abecednÃ­ seznam nÃ¡zvÅ¯}
+_textdescrCreator_ [l=cs] {Listuj abecednÃ­m seznamem autorÅ¯}
+_textdescrSubject_ [l=cs] {Listuj pÅedmÄtovÃœmi kategoriemi}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=cs] {ProchÃ¡zej podle data}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+_textdescrSource_ [l=cs] {ProchÃ¡zej podle pÅ¯vodnÃ­ch jmen}
+_textdescrLanguage_ [l=cs] {ProchÃ¡zej podle jazyka}
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=cs] {ProchÃ¡zej organizace}
+_textdescrKeyword_ [l=cs] {ProchÃ¡zej klÃ­ÄovÃ¡ slova}
+_textdescrHowto_ [l=cs] {ProchÃ¡zej kategorie 'Jak na to'}
+_textdescrList_ [l=cs] {Listuj seznamem dokumentÅ¯}
+_textdescrSeries_ [l=cs] {Listuj ÄÃ­sly}
+_textdescrTo_ [l=cs] {ProchÃ¡zej podle pole 'Pro:'}
+_textdescrFrom_ [l=cs] {ProchÃ¡zej podle pole 'Od'}
+_textdescrTopic_ [l=cs] {ProchÃ¡zej speciÃ¡lnÃ­mi kategoriemi}
+_textdescrBrowse_ [l=cs] {ProchÃ¡zej}
+_textdescrCollage_ [l=cs] {ProchÃ¡zej podle kolÃ¡ÅŸÃ­ obrÃ¡zkÅ¯}
+_textdescrPeople_ [l=cs] {Listuj abecednÃ­m seznamem osob}
+_textdescrAcronym_ [l=cs] {ProchÃ¡zej zkratky}
+_textdescrPhrase_ [l=cs] {ProchÃ¡zej frÃ¡ze}
+_textdescrArtist_ [l=cs] {ProchÃ¡zej jmÃ©na umÄlcÅ¯}
+_textdescrVolume_ [l=cs] {ProchÃ¡zej podle roÄnÃ­ku}
+_textdescrCountries_ [l=cs] {ProchÃ¡zej podle zemÃ­}
+_textdescrCaptions_ [l=cs] {ProchÃ¡zej podle popiskÅ¯ fotografiÃ­}
+
+
+_labelSearch_ [l=cs] {Hledej}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=cs] {NÃ¡zvy A-Z}
+_labelCreator_ [l=cs] {AutoÅi A-Z}
+_labelSubject_ [l=cs] {PÅedmÄt}
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=cs] {Datumy}
+# -- Missing translation: _labelType_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+_labelSource_ [l=cs] {NÃ¡zvy souborÅ¯}
+_labelLanguage_ [l=cs] {Jazyk}
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=cs] {Organizace}
+_labelKeyword_ [l=cs] {KlÃ­ÄovÃ¡ slova}
+_labelHow_ [l=cs] {Jak na to}
+_labelSeries_ [l=cs] {ÄÃ­sla}
+_labelList_ [l=cs] {Seznam}
+_labelTo_ [l=cs] {Pro}
+_labelFrom_ [l=cs] {Od}
+_labelTopic_ [l=cs] {TÃ©mata}
+_labelBrwse_ [l=cs] {ProchÃ¡zej}
+_labelCollage_ [l=cs] {KolÃ¡ÅŸe}
+_labelBrows_ [l=cs] {ProchÃ¡zej}
+_labelPeople_ [l=cs] {LidÃ© A-Z}
+_labelAcronym_ [l=cs] {Zkratky}
+_labelPhrase_ [l=cs] {FrÃ¡ze}
+_labelArtist_ [l=cs] {UmÄlci}
+_labelVolume_ [l=cs] {RoÄnÃ­ky}
+_labelCaptions_ [l=cs] {Popisky}
+_labelCountries_ [l=cs] {ZemÄ}
+
+_texticontext_ [l=cs] {Zobraz dokument}
+_texticonclosedbook_ [l=cs] {OtevÅi dokument a ukaÅŸ obsah}
+_texticonnext_ [l=cs] {dalÅ¡Ã­ oddÃ­l}
+_texticonprev_ [l=cs] {pÅedchozÃ­ oddÃ­l}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=cs] {UkaÅŸ MIDI dokument}
+_texticonmsword_ [l=cs] {UkaÅŸ Microsoft Word document}
+_texticonmp3_ [l=cs] {UkaÅŸ MP3 dokument}
+_texticonpdf_ [l=cs] {UkaÅŸ PDF dokument}
+_texticonps_ [l=cs] {UkaÅŸ PostScript dokument}
+_texticonppt_ [l=cs] {UkaÅŸ PowerPoint dokument}
+_texticonrtf_ [l=cs] {UkaÅŸ RTF dokument}
+_texticonxls_ [l=cs] {UkaÅŸ Microsoft Excel dokument}
+
+_page_ [l=cs] {strana }
+_pages_ [l=cs] {strany}
+_of_ [l=cs] {z }
+_vol_ [l=cs] {RoÄ.}
+_num_ [l=cs] {Ä.}
+
+_textmonth00_ [l=cs] {}
+_textmonth01_ [l=cs] {Leden}
+_textmonth02_ [l=cs] {Ãnor}
+_textmonth03_ [l=cs] {BÅezen}
+_textmonth04_ [l=cs] {Duben}
+_textmonth05_ [l=cs] {KvÄten}
+_textmonth06_ [l=cs] {Äerven}
+_textmonth07_ [l=cs] {Äervenec}
+_textmonth08_ [l=cs] {Srpen}
+_textmonth09_ [l=cs] {ZÃ¡ÅÃ­}
+_textmonth10_ [l=cs] {ÅÃ­jen}
+_textmonth11_ [l=cs] {Listopad}
+_textmonth12_ [l=cs] {Prosinec}
+
+_textdocument_ [l=cs] {Dokument}
+_textsection_ [l=cs] {Sekce}
+_textparagraph_ [l=cs] {Odstavec}
+
+_magazines_ [l=cs] {Äasopisy}
+
+_nzdlpagefooter_ [l=cs] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">Projekt New Zealand Digital Library </a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Ãstav poÄÃ­taÄovÃ© vÄdy</a>, 
+<a href="http://www.waikato.ac.nz">Universita Waikato</a>, 
+NovÃœ ZÃ©land}
+
+_linktextHOME_ [l=cs] {DOMÅ®}
+_linktextHELP_ [l=cs] {NÃPOVÄDA}
+_linktextPREFERENCES_ [l=cs] {NASTAVENÃ}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=cs] {DigitÃ¡lnÃ­ knihovna Greenstone}
+_textadmin_ [l=cs] {StrÃ¡nka administrÃ¡tora}
+_textabgs_ [l=cs] {O Greenstone}
+_textgsdocs_ [l=cs] {Dokumentace Greenstone}
+
+_textdescradmin_ [l=cs] {Dovoluje pÅidÃ¡vat novÃ© uÅŸivatele, vytvÃ¡Ået souhrny o kolekcÃ­ch v systÃ©mu a podÃ¡vat technickÃ© informace o instalaci}
+
+_textdescrgogreenstone_ [l=cs] {PovÃ­ vÃ¡m o programu Greenstone a o projektu NovozÃ©landskÃ© digitÃ¡lnÃ­ knihovny, kde Greenstone vzniknul}
+
+_textdescrgodocs_ [l=cs] {PÅÃ­ruÄky Greenstone}
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=cs] {RozhranÃ­ Librarian}
+_textdescrgli_ [l=cs] {PomÃ¡hÃ¡ vytvÃ¡Ået novÃ© kolekce, upravovat existujÃ­cÃ­ nebo je mazat.}
+
+package collector
+
+_textcollector_ [l=cs] {Collector}
+_textdescrcollector_ [l=cs] {PÅedchldce rozhranÃ­ Libraran - pro vÄtÅ¡inu ÃºÄelÅ¯ by mÄlo bÃœt vyuÅŸÃ­vÃ¡no rozhranÃ­ Librarian.}
+
+package depositor
+
+
+package gti
+
+_textdescrtranslator_ [l=cs] {PomÃ¡hÃ¡ udrÅŸet jazykovÃ© mutace Greenstone aktuÃ¡lnÃ­}
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=cs] {O tÃ©to kolekci}
+
+_textsubcols1_ [l=cs] {<p>KompletnÃ­ sbÃ­rka obsahuje urÄitÃœ poÄet kolekcÃ­: _1_ . 
+V souÄasnosti pÅÃ­stupnÃ© jsou:
+<blockquote>}
+
+_textsubcols2_ [l=cs] {</blockquote>
+Na strÃ¡nce 'NastavenÃ­' mÅ¯ÅŸete zkontrolovat (a mÄnit) aktuÃ¡lnÃ­ (sub)kolekce.}
+
+
+_titleabout_ [l=cs] {o nÃ¡s}
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+
+_texticonopenbookshelf_ [l=cs] {ZavÅi tuto sekci knihovny}
+_texticonclosedbookshelf_ [l=cs] {OtevÅÃ­t tuto sekci knihovny a ukÃ¡zat obsah}
+_texticonopenbook_ [l=cs] {ZavÅi tuto knihu}
+_texticonclosedfolder_ [l=cs] {OtevÅÃ­t tuto sloÅŸku a ukÃ¡zat obsah}
+_texticonclosedfolder2_ [l=cs] {OtevÅÃ­t podsekci: }
+_texticonopenfolder_ [l=cs] {ZavÅi tuto sloÅŸku}
+_texticonopenfolder2_ [l=cs] {ZavÅi tuto podsekci: }
+_texticonsmalltext_ [l=cs] {UkaÅŸ tuto sekci textu}
+_texticonsmalltext2_ [l=cs] {UkaÅŸ text: }
+_texticonpointer_ [l=cs] {AktuÃ¡lnÃ­ sekce}
+_texticondetach_ [l=cs] {OtevÅÃ­t tuto strÃ¡nku v novÃ©m oknÄ}
+_texticonhighlight_ [l=cs] {ZvÃœrazni hledanÃ© termÃ­ny}
+_texticonnohighlight_ [l=cs] {NezvÃœrazÅuj hledanÃ© termÃ­ny}
+_texticoncontracttoc_ [l=cs] {Sbalit obsah}
+_texticonexpandtoc_ [l=cs] {Rozvinout obsah}
+_texticonexpandtext_ [l=cs] {UkÃ¡zat veÅ¡kerÃœ text}
+_texticoncontracttext_ [l=cs] {UkÃ¡zat text pouze pro aktuÃ¡lnÃ­ sekci}
+_texticonwarning_ [l=cs] {<b>UpozornÄnÃ­: </b>}
+_texticoncont_ [l=cs] {PokraÄovat?}
+
+_textltwarning_ [l=cs] {<div class="buttons">_imagecont_</div>
+_iconwarning_VÃ¡Å¡ prohlÃ­ÅŸeÄ bude muset zobrazit velkÃ© mnoÅŸstvÃ­ textu.
+}
+
+_textgoto_ [l=cs] {jÃ­t na stranu}
+_textintro_ [l=cs] {<i>(ÃºvodnÃ­ text)</i>}
+
+_textCONTINUE_ [l=cs] {POKRAÄOVAT??}
+
+_textEXPANDTEXT_ [l=cs] {ROZVINOUT\nTEXT}
+
+_textCONTRACTCONTENTS_ [l=cs] {SBALIT\nOBSAH}
+
+_textDETACH_ [l=cs] {OTEVÅÃT V\nNOVÃM OKNÄ}
+
+_textEXPANDCONTENTS_ [l=cs] {ROZVINOUT\nOBSAH}
+
+_textCONTRACT_ [l=cs] {SBALIT\nTEXT}
+
+_textHIGHLIGHT_ [l=cs] {ZVÃRAZNÄNÃ}
+
+_textNOHIGHLIGHT_ [l=cs] {BEZ\nZVÃRAZNÄNÃ}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=cs] {_If_(_thislast_,vÃœsledky _thisfirst_ - _thislast_ na dotaz: _cgiargq_,ÅœÃ¡dnÃ© vÃœsledky na dotaz: _cgiargq_)}
+_textnoquerytitle_ [l=cs] {VyhledÃ¡vacÃ­ strana}
+
+_textsome_ [l=cs] {nÄkterÃ¡}
+_textall_ [l=cs] {vÅ¡echny}
+_textboolean_ [l=cs] {booleovskÃ©}
+_textranked_ [l=cs] {klasifikovanÃœ}
+_textnatural_ [l=cs] {pÅirozenÃœ}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=cs] {historie dotazÅ¯}
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+_textusequery_ [l=cs] {pouÅŸij tento dotaz}
+_textfreqmsg1_ [l=cs] {PoÄet slov: }
+_textpostprocess_ [l=cs] {_If_(_quotedquery_,<br><i>zpracovÃ¡no kvÅ¯li vyhledÃ¡nÃ­ _quotedquery_</i>
+)}
+_textinvalidquery_ [l=cs] {Å patnÃ¡ syntaxe dotazu}
+
+_textmorethan_ [l=cs] {VÃ­ce neÅŸ }
+_textapprox_ [l=cs] {Kolem }
+_textnodocs_ [l=cs] {Nebyl nalezen ÅŸÃ¡dnÃœ dokument. Zkontrolujte prosÃ­m dotaz a nastavenÃ­.}
+_text1doc_ [l=cs] {Nalezen  1  dokument.}
+_textlotsdocs_ [l=cs] {dokument(Å¯) souhlasÃ­ s dotazem.}
+_textmatches_ [l=cs] {VÃœsledky}
+_textbeginsearch_ [l=cs] {Hledej}
+_textrunquery_ [l=cs] {SpusÅ¥ dotaz}
+_textclearform_ [l=cs] {VymaÅŸ formulÃ¡Å}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=cs] {Slovo nebo frÃ¡zi}
+_textinfield_ [l=cs] {... v poli}
+_textfoldstem_ [l=cs] {(velikost znakÅ¯, stemming)}
+
+_textadvquery_ [l=cs] {Nebo zadejte dotaz pÅÃ­mo:}
+_textallfields_ [l=cs] {VÅ¡echna pole}
+_texttextonly_ [l=cs] {poue text}
+_textand_ [l=cs] {a}
+_textor_ [l=cs] {nebo}
+_textandnot_ [l=cs] {a ne}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=cs] {Hledej _indexselection_ _If_(_jselection_, z _jselection_) _If_(_gselection_, na _gselection_ Ãºrovni) _If_(_nselection_, v jazyce _nselection_ ) obsahujÃ­cÃ­ _querytypeselection_ ze slov}
+
+_textadvancedsearch_ [l=cs] {Hledej _indexselection_ _If_(_jselection_,z _jselection_) _If_(_gselection_, na Ãºrovni _gselection_ )_If_(_nselection_, v jazyce _nselection_) pomocÃ­ _querytypeselection_ dotazÅ¯}
+
+_textformsimplesearch_ [l=cs] {Hledej _If_(_jselection_, _jselection_) _If_(_gselection_, na Ãºrovni _gselection_) _If_(_nselection_, v jazyce _nselection_)
+obsahujÃ­cÃ­ _formquerytypesimpleselection_ z}
+
+_textformadvancedsearch_ [l=cs] {Hledej _If_(_jselection_,_jselection_) _If_(_gselection_, na Ãºrovni _gselection_)_If_(_nselection_, v jazyce _nselection_) 
+a zobraz vÃœsledky v _formquerytypeadvancedselection_ poÅadÃ­}
+
+
+_textnojsformwarning_ [l=cs] {UpozoznÄnÃ­: Javascript nenÃ­ ve vaÅ¡em prohlÃ­ÅŸeÄÃ­ povolen.<br>Chcete-li pouÅŸÃ­t prohledÃ¡vÃ¡nÃ­ podle polÃ­, prosÃ­m povolte jeho spouÅ¡tÄnÃ­.}
+_textdatesearch_ [l=cs] {V tÃ©to kolekci mÅ¯ÅŸete hledat dokumenty podle urÄitÃ©ho data, a nebo dokumenty v rÃ¡mci urÄitÃ©ho ÄasovÃ©ho rozmezÃ­. Je to volitelnÃ¡ moÅŸnost vyhledÃ¡vÃ¡nÃ­.}
+_textstartdate_ [l=cs] {PoÄÃ¡teÄnÃ­ (nebo jedinÃ©) datum:}
+_textenddate_ [l=cs] {KoncovÃ© datum:}
+_textbc_ [l=cs] {pÅ.n.l.}
+_textad_ [l=cs] {n.l.}
+_textexplaineras_ [l=cs] {C.E. a B.C.E pÅedstavujÃ­ alternativu pro A.D.(naÅ¡eho letopoÄtu) a B.C.(PÅed Kristem).  C.E. a B.C.E. jsou poklÃ¡dÃ¡ny za kulturnÄ nezÃ¡vislÃ¡ ÄasovÃ¡ vymezenÃ­. Zkratky jsou rozepsÃ¡ny jako 'Common Era' a 'Before the Common Era'}
+
+_textstemon_ [l=cs] {(ignoruj (anglickÃ©) koncovky)}
+
+_textsearchhistory_ [l=cs] {Historie dotazÅ¯}
+
+#text macros for search history
+_textnohistory_ [l=cs] {Historie dotazÅ¯ nenÃ­ dostupnÃ¡}
+_texthresult_ [l=cs] {vÃœsledek}
+_texthresults_ [l=cs] {zÃ¡znamÅ¯}
+_texthallwords_ [l=cs] {vÅ¡echna slova}
+_texthsomewords_ [l=cs] {nejmÃ©nÄ 1 slovo}
+_texthboolean_ [l=cs] {booleovskÃœ}
+_texthranked_ [l=cs] {klasifikovanÃœ}
+_texthcaseon_ [l=cs] {zÃ¡leÅŸÃ­ na velikosti pÃ­sma}
+_texthcaseoff_ [l=cs] {nezÃ¡leÅŸÃ­ na velikosti pÃ­sma}
+_texthstemon_ [l=cs] {automatickÃ© doplnÄnÃ­ koncovek }
+_texthstemoff_ [l=cs] {celÃ© slovo musÃ­ souhlasit}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=cs] {NastavenÃ­ bya zmÄnÄna. NepouÅŸÃ­vejte tlaÄÃ­tka "zpÄt" - zmÄna by se neprojevila! PouÅŸijte nÄkterÃ© z tlaÄÃ­tek na naÅ¡em navigaÄnÃ­m panelu.
+}
+_textsetprefs_ [l=cs] {uloÅŸ nastavenÃ­}
+_textsearchprefs_ [l=cs] {NastavenÃ­ vyhledÃ¡vÃ¡nÃ­}
+_textcollectionprefs_ [l=cs] {NastavenÃ­ pro kolekce}
+_textpresentationprefs_ [l=cs] {NastavenÃ­ prezentace}
+_textpreferences_ [l=cs] {NastavenÃ­}
+_textcasediffs_ [l=cs] {VELKÃ,malÃ¡ pÃ­smena:}
+_textignorecase_ [l=cs] {ignoruj velikost znakÅ¯}
+_textmatchcase_ [l=cs] {velkÃ¡/malÃ¡ pÃ­smena musÃ­ souhlasit}
+_textwordends_ [l=cs] {AnglickÃ© koncovky:}
+_textstem_ [l=cs] {automaticky doplÅ}
+_textnostem_ [l=cs] {celÃ¡ slova musÃ­ souhlasit}
+_textprefop_ [l=cs] {Vyhledej _maxdocoption_ zÃ¡znamÅ¯. Zobraz _hitsperpageoption_ na jednÃ© strÃ¡nce.}
+_textextlink_ [l=cs] {PÅÃ­stup k externÃ­m webovÃœm strÃ¡nkÃ¡m:}
+_textintlink_ [l=cs] {ZdrojovÃ© dokumenty zÃ­skÃ¡ny z:}
+_textlanguage_ [l=cs] {Jazyk rozhranÃ­:}
+_textencoding_ [l=cs] {KÃ³dovÃ¡nÃ­:}
+_textformat_ [l=cs] {FormÃ¡t rozhranÃ­:}
+_textall_ [l=cs] {vÅ¡echny}
+_textquerymode_ [l=cs] {MÃ³d dotazu:}
+_textsimplemode_ [l=cs] {jednoduchÃœ dotaz}
+_textadvancedmode_ [l=cs] {rozÅ¡Ã­ÅenÃœ dotaz (booleovskÃ© operÃ¡tory &, |, ! a zÃ¡vorky)}
+_textlinkinterm_ [l=cs] {pÅes vloÅŸenou strÃ¡nku}
+_textlinkdirect_ [l=cs] {jdi tam pÅÃ­mo}
+_textdigitlib_ [l=cs] {digitÃ¡lnÃ­ knihovna}
+_textweb_ [l=cs] {web}
+_textgraphical_ [l=cs] {GrafickÃœ}
+_texttextual_ [l=cs] {TextovÃœ}
+_textcollectionoption_ [l=cs] {<p>
+Subkolekce k zobrazenÃ­:
+<br>}
+
+_textrelateddocdisplay_ [l=cs] {zobraz pÅÃ­buznÃ© dokumenty}
+_textsearchhistory_ [l=cs] {Historie dotazÅ¯}
+_textnohistory_ [l=cs] {Historie dotazÅ¯ nenÃ­ dostupnÃ¡}
+_texthistorydisplay_ [l=cs] {ukaÅŸ _historynumrecords_ poslednÃ­ch dotazÅ¯}
+_textnohistorydisplay_ [l=cs] {nozobrazuj historii dotazÅ¯}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=cs] {Do polÃ­:}
+_textplainsearch_ [l=cs] {JednoduchÃ© hledÃ¡nÃ­:}
+_textqueryboxsize_ [l=cs] {Velikost formulÃ¡Åe:}
+_textregbox_ [l=cs] {normÃ¡lnÃ­}
+_textbigbox_ [l=cs] {zvÄtÅ¡enÃœ}
+_textformtype_ [l=cs] {Forma dotazu:}
+_textsimple_ [l=cs] {jednoduchÃœ}
+_textadvanced_ [l=cs] {rozÅ¡Ã­ÅenÃœ}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=cs] {s}
+_textfields_ [l=cs] {pole}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=cs] {SetÅiÄ dokumenty podle}
+_textalsoshowing_ [l=cs] {ukazujÃ­cÃ­ takÃ©}
+_textwith_ [l=cs] {nejvÃœÅ¡e s}
+_textdocsperpage_ [l=cs] {dokumenty na strÃ¡nce}
+
+_textfilterby_ [l=cs] {Jen dokumenty obsahujÃ­cÃ­}
+_textall_ [l=cs] {vÅ¡echny}
+_textany_ [l=cs] {jakÃ¡koliv}
+_textwords_ [l=cs] {ze slov}
+_textleaveblank_ [l=cs] {ponechte toto pole prÃ¡zdnÃ©, chcete-li obdrÅŸet vÅ¡echny dokumenty}
+
+_browsebuttontext_ [l=cs] {"SetÅiÄ dokumenty"}
+
+_nodata_ [l=cs] {<i>ÅŸÃ¡dnÃ¡ data</i>}
+_docs_ [l=cs] {dokumenty}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=cs] {NÃ¡povÄda}
+_textSearchshort_ [l=cs] {hledÃ¡nÃ­ konkrÃ©tnÃ­ch slov}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=cs] {prochÃ¡zet dokumenty podle nÃ¡zvÅ¯}
+_textCreatorshort_ [l=cs] {prochÃ¡zet dokumenty podle autorÅ¯}
+_textSubjectshort_ [l=cs] {prochÃ¡zet dokumenty podle pÅedmÄtÅ¯}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=cs] {prochÃ¡zet dokumenty podle datumÅ¯}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=cs] {prochÃ¡zet dokumenty podle nÃ¡zvÅ¯ souborÅ¯}
+_textLanguageshort_ [l=cs] {prochÃ¡zet dokumenty podle jazykÅ¯}
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=cs] {prochÃ¡zet dokumenty podle ÄÃ­sel}
+_textToshort_ [l=cs] {prochÃ¡zet dokumenty podle pole 'Pro'}
+_textFromshort_ [l=cs] {prochÃ¡zet dokumenty podle pole 'Od'}
+_textBrowseshort_ [l=cs] {prochÃ¡zet dokumenty}
+_textOrganizationshort_ [l=cs] {prochÃ¡zet dokumenty podle organizacÃ­}
+_textHowtoshort_ [l=cs] {prochÃ¡zenÃ­ dokumentÅ¯ pomocÃ­ poloÅŸek 'jak na to'}
+_textTopicshort_ [l=cs] {prochÃ¡zet dokumenty podle tÃ©mat}
+_textPeopleshort_ [l=cs] {prochÃ¡zet dokumenty podle lidÃ­}
+_textAcronymshort_ [l=cs] {prochÃ¡zet dokumenty podle vÃœskytu zkratky}
+_textPhraseshort_ [l=cs] {prochÃ¡zet frÃ¡ze vyskytujÃ­cÃ­ se v dokumentech}
+_textArtistshort_ [l=cs] {prochÃ¡zet dokumenty podle umÄlcÅ¯}
+_textKeywordshort_ [l=cs] {prochÃ¡zet dokumenty podle klÃ­ÄovÃœch slov}
+_textVolumeshort_ [l=cs] {pÅÃ­stup k dokumentÅ¯ podle roÄnÃ­ku/svazku}
+_textCountriesshort_ [l=cs] {prochÃ¡zet dokumenty podle zemÃ­}
+_textdefaultshorttext_ [l=cs] {nedefinovanÃ¡ klasifikace}
+
+_textSearchlong_ [l=cs] {<p>MÅ¯ÅŸete <i>hledat konkrÃ©tnÃ­ slova</i>, kterÃ¡ se vyskytujÃ­ v textu,
+na strÃ¡nce "hledej". Je to prvnÃ­ strÃ¡nka, kterÃ¡ se zobrazÃ­ kdyÅŸ otevÅete kolekci
+a lze ji kdykoliv pozdÄji otevÅÃ­t  stisknutÃ­m tlaÄÃ­tka <i>hledej</i>.  }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle nÃ¡zvÅ¯</i>
+stisknutÃ­m tlaÄÃ­tka <i>nÃ¡zvy a-z</i>. TÃ­m zobrazÃ­te seznam dokumentÅ¯ setÅÃ­dÄnÃœch podle nÃ¡zvu.}
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle jejich autorÅ¯</i>
+stisknutÃ­m tlaÄÃ­tka <i>autoÅÃ­ a-z</i>. TÃ­m zobrazÃ­te seznam dokumentÅ¯ setÅÃ­dÄnÃœch podle jmÃ©n autorÅ¯.}
+
+_textSubjectlong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle pÅedmÄtÅ¯</i>
+stisknutÃ­m tlaÄÃ­tka <i>pÅedmety</i>. TÃ­m zobrazÃ­te seznam pÅedmÄtÅ¯, reprezentovanÃœch pomocÃ­ polic knihovny.}
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle datumÅ¯</i>
+stisknutÃ­m tlaÄÃ­tka <i>datumy</i>. TÃ­m zobrazÃ­te seznam vÅ¡ech dokumentÅ¯, setÅÃ­dÄnÃœch podle datumÅ¯ vytvoÅenÃ­.}
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle nÃ¡zvÅ¯ souborÅ¯</i>
+stisknutÃ­m tlaÄÃ­tka <i>nÃ¡zvy souborÅ¯</i>. TÃ­m zobrazÃ­te seznam poloÅŸek setÅÃ­dÄnÃœch podle nÃ¡zvÅ¯ souborÅ¯.}
+
+_textLanguagelong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle jazykÅ¯</i>
+stisknutÃ­m tlaÄÃ­tka <i>jazyky</i>. TÃ­m zobrazÃ­te seznam ploÅŸek setÅÃ­dÄnÃœch podle jazyka.}
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle organizacÃ­</i>
+stisknutÃ­m tlaÄÃ­tka <i>organizace</i>. TÃ­m zobrazÃ­te seznam organizacÃ­.}
+
+_textHowtolong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty pomocÃ­ vÃœpisu poloÅŸek 'Jak na to'</i>
+stisknutÃ­m tlaÄÃ­tka <i>Jak na to</i>. TÃ­m zobrazÃ­te seznam ÅetÄzcÅ¯ 'jak na to'.}
+
+_textTopiclong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle tÃ©mat</i>
+stisknutÃ­m tlaÄÃ­tka <i>tÃ©mata</i>. TÃ­m zobrazÃ­te seznam tÃ©mat k prochÃ¡zenÃ­.}
+
+_textTolong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle obsahu pole 'Pro'</i>
+stisknutÃ­m tlaÄÃ­tka <i>pro</i>. TÃ­m zobrazÃ­te seznam adres.}
+
+_textFromlong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle pole 'Od'</i>
+stisknutÃ­m tlaÄÃ­tka <i>Od</i>. TÃ­m zobrazÃ­te seznam odesilatelÅ¯.}
+
+_textSerieslong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle ÄÃ­sel</i>
+stisknutÃ­m tlaÄÃ­tka <i>ÄÃ­sla</i>. TÃ­m zobrazÃ­te seznam tÄch ÄÃ­sel, kterÃ© jsou aktuÃ¡lnÄ v kolekci.}
+
+_textBrowselong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty</i> stisknutÃ­m tlaÄÃ­tka
+<i>prochÃ¡zet</i>.  }
+
+_textPeoplelong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle lidÃ­</i>
+stisknutÃ­m tlaÄÃ­tka <i>lidÃ©</i>. TÃ­m zobrazÃ­te seznam poloÅŸek setÅÃ­dÄnÃœ podle pÅÃ­jmÄnÃ­.}
+
+_textAcronymlong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle vÃœskytÅ¯ zkratky</i> stisknutÃ­m tlaÄÃ­tka <i>zkratky</i>. 
+TÃ­m zobrazÃ­te seznam zkratek a mÃ­st, ve kterÃœch se vyskytujÃ­.}
+
+_textPhraselong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet frÃ¡ze kterÃ© se vyskytujÃ­ v dokumentech</i>
+stisknutÃ­m tlaÄÃ­tka <i>frÃ¡ze</i>. TÃ­m zobrazÃ­te prohlÃ­ÅŸeÄ frÃ¡zÃ­ Phind.}
+
+_textArtistlong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenety podle umÄlcÅ¯</i> stisknutÃ­m tlaÄÃ­tka <i>umÄlci</i>.
+TÃ­m zobrazÃ­te seznam poloÅŸech setÅÃ­dÄnÃœch podle jmÃ©na umÄlce.}
+
+_textKeywordlong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle klÃ­ÄovÃœch slov</i>
+stisknutÃ­m tlaÄÃ­tka <i>klÃ­ÄovÃ¡ slova</i>. TÃ­m zobrazÃ­te seznam klÃ­ÄovÃœch slov.}
+
+_textVolumelong_ [l=cs] {<p> MÅ¯ÅŸete <i>zobrazit dokumenty podle roÄnÃ­ku</i>. KdyÅŸ zmÃ¡Äknete tlaÄÃ­tko <i>roÄnÃ­kÅ¯</i>, objevÃ­ se seznam roÄnÃ­kÅ¯/svazkÅ¯.}
+
+_textCaptionslong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle popiskÅ¯</i> stisknutÃ­m tlaÄÃ­tka <i>popisky</i>.
+TÃ­m zobrazÃ­te seznam popiskÅ¯.}
+
+_textCountrieslong_ [l=cs] {<p>MÅ¯ÅŸete <i>prochÃ¡zet dokumenty podle zemÃ­</i>
+stisknutÃ­m tlaÄÃ­tka <i>zemÄ</i>. TÃ­m zobrazÃ­te seznam zemÃ­.}
+
+
+_textdefaultlongtext_ [l=cs] {<p>StisknÄte tlaÄÃ­tko <i>neznÃ¡mÃ©</i> pro prochÃ¡zenÃ­ dokumentÅ¯
+(seznam je tÅÃ­dÄn podle neznÃ¡mÃ©ho pole)}
+
+_texthelptopicstitle_ [l=cs] {TÃ©mata}
+
+_textreadingdocs_ [l=cs] {Jak ÄÃ­st dokumenty}
+
+_texthelpreadingdocs_ [l=cs] {
+<p>KdyÅŸ se vÃ¡m v hornÃ­ ÄÃ¡sti strÃ¡nky zobrazÃ­ nÃ¡zev dokumentu, fotografie
+nebo pÅebal knihy, poznÃ¡te, ÅŸe jste se dostali ke konkrÃ©tnÃ­mu dokumentu Äi knize.
+V nÄkterÃœch kolekcÃ­ch je zobrazen takÃ© obsah, kdeÅŸto jinÃ© mohou obsahovat
+napÅÃ­klad jen ÄÃ­slo aktuÃ¡lnÃ­ strÃ¡nky spolu s textovÃœm polem pro pÅÃ­mÃœ vÃœbÄr
+strÃ¡nky a Å¡ipkami pro pÅechod na pÅedchozÃ­/nÃ¡sledujÃ­cÃ­ strÃ¡nku. V obsahu
+je aktuÃ¡lnÄ zobrazenÃ¡ strÃ¡nka zvÃœraznÄna tuÄnÄ a obsah lze rovÃ­jet --
+kliknutÃ­ na sloÅŸky je otevÃ­rÃ¡ a zavÃ­rÃ¡; kliknutÃ­ na otevÅenou knihu na vrcholu
+obsahu ji zavÅe.</p>
+
+<p>Pod obsahem (pÅÃ­padnÄ navigacÃ­ mezi strÃ¡nkami) se nachÃ¡zÃ­ text
+vybranÃ© sekce. Jakmile jej pÅeÄtete, mÅ¯ÅŸete pomocÃ­ Å¡ipek v dolnÃ­ ÄÃ¡sti strÃ¡nky
+pÅejÃ­t na dalÅ¡Ã­ sekci nebo se vrÃ¡tit zpÄt k pÅedchozÃ­.</p>
+
+<p>Pod nÃ¡zvem nebo pÅebalem se nachÃ¡zÃ­ nÄkolik tlaÄÃ­tek. KliknutÃ­m na
+<i>rozvinout text</i> se v oknÄ zobrazÃ­ celÃœ text aktuÃ¡lnÃ­ sekce nebo
+knihy. Pokud je dokument velkÃœ, mÅ¯ÅŸe to zabrat dlouhou dobu a spotÅebovat
+znaÄnou ÄÃ¡st operaÄnÃ­ pamÄti! KliknutÃ­m na <i>rozvinout obsah</i> se
+zobrazÃ­ vÅ¡echny ÃºrovnÄ obsahu dokumentu, takÅŸe jsou vidÄt nÃ¡zvy vÅ¡ech 
+kapitol a sekcÃ­. KliknutÃ­m na <i>zobrazit v novÃ©m oknÄ</i> se prohlÃ­ÅŸenÃœ
+dokument otevÅe v novÃ©m oknÄ prohlÃ­ÅŸeÄe (coÅŸ je uÅŸiteÄnÃ©, chcete-li dokumenty
+porovnÃ¡vat nebo ÄÃ­st dva zÃ¡roveÅ). A koneÄnÄ, hledanÃ¡ slova jsou zvÃœraznÄna
+(kliknutÃ­m na <i>bez zvÃœraznÄnÃ­</i> lze zvÃœrazÅovÃ¡nÃ­ slov zruÅ¡it).</p>
+}
+
+ # help about the icons
+_texthelpopenbookshelf_ [l=cs] {OtevÅit tuto polici}
+_texthelpopenbook_ [l=cs] {OtevÅÃ­t/zavÅÃ­t tuto knihu}
+_texthelpviewtextsection_ [l=cs] {ProhlÃ­ÅŸet tuto sekci textu}
+_texthelpexpandtext_ [l=cs] {Zobrazit nebo nezobrazovat celÃœ text}
+_texthelpexpandcontents_ [l=cs] {Rozvinout nebo sbalit obsah}
+_texthelpdetachpage_ [l=cs] {OtevÅÃ­t strÃ¡nku v novÃ©m onkÄ}
+_texthelphighlight_ [l=cs] {ZvÃœraznit nebo nezvÃœraÅovat hledanÃ¡ slova}
+
+_texthelpsearchingtitle_ [l=cs] {Jak hledat konkrÃ©tnÃ­ slova}
+
+_texthelpsearching_ [l=cs] {
+<p>
+  HledÃ¡nÃ­ lze uskuteÄnit pomocÃ­ strÃ¡nky "hledej" provedenÃ­m nÃ¡sledujÃ­ch 
+  jednoduchÃœch krokÅ¯:
+  
+  <ol><li>UrÄete, jakÃ© vÃœrazy chcete vyhledÃ¡vat
+      <li>RozhodnÄte se, zda chcete hledat vÅ¡echna slova vÃœrazu nebo jen nÄkterÃ¡
+      <li>NapiÅ¡te slova, kterÃ¡ chcete vyhledat
+      <li>KliknÄte na tlaÄÃ­tko <i>Hledej</i>
+  </ol>
+
+<p>Po vyhodnocenÃ­ dotazu se na strÃ¡nce zobrazÃ­ nÃ¡zvy prvnÃ­ch dvaceti odpovÃ­dajÃ­cÃ­ch
+dokumentÅ¯. Na konci seznamu je tlaÄÃ­tko, kterÃ© zobrazÃ­ dalÅ¡Ã­ch dvacet vÃœsledkÅ¯.
+Odtamtud mÃ¡te moÅŸnost zobrazit tÅetÃ­ dvacÃ­tku vÃœsledkÅ¯ nebo se vrÃ¡tit k tÃ© prvnÃ­ ...
+a tak podobnÄ pro ostatnÃ­ strÃ¡nky s vÃœsledky. KliknutÃ­ na nÃ¡zev dokumentu nebo na malÃ©
+tlaÄÃ­tko umÃ­stÄnÃ© vedle nÃ¡zvu danÃœ dokument zobrazÃ­.
+
+<p>StandardnÄ je nastaveno nabÃ­dnutÃ­ prvnÃ­ch 100 nalezenÃœch vÃœsledkÅ¯, 
+tento limit lze zmÄnit na strÃ¡nce <i>nastavenÃ­</i> (na kterou se lze
+dostat kliknutÃ­m na stejnojmennÃ© tlaÄÃ­tko umÃ­stÄnÃ© na vrcholu strÃ¡nky)<p>
+}
+
+_texthelpquerytermstitle_ [l=cs] {VyhledÃ¡vacÃ­ vÃœrazy}
+_texthelpqueryterms_ [l=cs] {
+<p>VÅ¡e co napÃ­Å¡ete do pole pro zadÃ¡vÃ¡nÃ­ dotazÅ¯ je interpretovÃ¡no jako
+seznam slov, nazÃœvanÃœch "vyhledÃ¡vacÃ­ vÃœrazy". KaÅŸdÃœ vÃœraz obsahuje pouze
+znaky abecedy a ÄÃ­slice. VÃœrazy jsou oddÄleny mezerami. VÅ¡echny ostatnÃ­
+znaky (jako je napÅÃ­klad interpunkce) slouÅŸÃ­ jako oddÄlovaÄe vÃœrazÅ¯ stejnÄ jako 
+by to byly mezery a jsou ignorovÃ¡ny. NenÃ­ moÅŸnÃ© hledat slova, kterÃ¡ obsahujÃ­
+interpunkci.
+
+<p>NapÅÃ­klad dotaz<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>bude vyhodnocen stejnÄ jako<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}
+
+_texthelpquerytypetitle_ [l=cs] {Druhy dotazÅ¯}
+_texthelpquerytype_ [l=cs] {
+<p>ExistujÃ­ dva rÅ¯znÃ© druhy dotazÅ¯.
+
+<ul>
+  <li>Dotazy na <b>vÅ¡echna</b> slova.  PÅi jejich vyhodnocovÃ¡nÃ­ jsou
+      hledÃ¡ny dokumenty, kterÃ© obsahujÃ­ vÅ¡echna zadanÃ¡ slova. VyhovujÃ­cÃ­
+      dokumenty jsou zobrazeny setÅÃ­dÄnÃ© podle abecedy.<p>
+
+  <li>Dotazy na <b>nÄkterÃ¡</b> ze slov. ZadÃ¡te slova, u nichÅŸ je pravdÄpodobnÃ©,
+      ÅŸe se objevÃ­ v odkumentech, kterÃ© hledÃ¡te. Dokumenty jsou potÃ© zobrazeny
+      v poÅadÃ­, kterÃ© odpovÃ­dÃ¡ tomu, do jakÃ© mÃ­ry odpovÃ­dajÃ­ dotazu. PÅi urÄovÃ¡nÃ­ stupnÄ
+      shody,
+
+      <p><ul>
+        <li> ÄÃ­m vÃ­ce hledanÃœch vÃœrazÅ¯ dokument obsahuje, tÃ­m vÃ­ce souhlasÃ­ s dotazem;
+        <li> ojedinÄlÃ© vÃœrazy jsou dÅ¯leÅŸitÄjÅ¡Ã­ neÅŸ ty obvyklÃ©;
+        <li> krÃ¡tkÃ© dokumenty se shodujÃ­ lÃ©pe neÅŸ ty dlouhÃ©.
+      </ul>
+</ul>
+
+<p>PouÅŸÃ­vejte tolik vyhledÃ¡vacÃ­ch vÃœrazÅ¯ kolik uznÃ¡te za vhodnÃ© -- celou vÄtu
+nebo i celÃœ odstavec. Pokud urÄÃ­te pouze jeden vÃœraz, dokumenty budou seÅazeny
+podle frekvence jeho vÃœskytu<p>
+}
+
+_textdatesearch_ [l=cs] {ProhledÃ¡vÃ¡nÃ­ v tÃ©to kolekci lze omezit na urÄitÃ© datum v dokumentech obsaÅŸenÃ©, a nebo na urÄitÃ© ÄasovÃ© rozmezÃ­. Toto je nepovinnÃ¡ volba.}
+
+_texthelpdatesearch_ [l=cs] {
+HledÃ¡nÃ­ podle datumÅ¯ umoÅŸÅuje nalÃ©zt dokumenty, kterÃ© odpovÃ­dajÃ­ hledanÃœm
+vÃœrazÅ¯m a zÃ¡roveÅ spadajÃ­ do urÄitÃ©ho ÄasovÃ©ho obdobÃ­. MÅ¯ÅŸete hledat 
+dokumenty od urÄitÃ©ho roku nebo rozsahu let. VÅ¡imnÄte si, ÅŸe nemusÃ­te
+zadat ÅŸÃ¡dnÃ© hledanÃ© vÃœrazy -- mÅ¯ÅŸete vyhledÃ¡vat jen podle samotnÃ©ho datumu;
+a takÃ© ÅŸe nemusÃ­te pÅi svÃ©m vyhledÃ¡vÃ¡nÃ­ datumy pouÅŸÃ­vat. Pokud nezadÃ¡te
+ÅŸÃ¡dnÃ© datumy, je to stejnÃ©, jako by prohledÃ¡vÃ¡nÃ­ podle datumÅ¯ neexistovalo.<p>
+}
+
+_texthelpdatehowtotitle_ [l=cs] {Jak vyuÅŸÃ­vat tÃ©to moÅŸnosti:}
+_texthelpdatehowto_ [l=cs] {
+<ul>
+   <li>Pro hledÃ¡nÃ­ dokumentÅ¯ tÃœkajÃ­cÃ­ch se jednoho roku:<p>
+   <ul>
+       <li>NapiÅ¡te jakÃœkoliv hledanÃœ vÃœraz stejnÄ jako byste to dÄlali obyÄejnÄ.
+       <li>NapiÅ¡te hledanÃœ rok do pole "Start (or only) date".
+       <li>Pokud vaÅ¡e datum sahÃ¡ do obdobÃ­ pÅed Kristem, vyberte moÅŸnost "B.C.E"
+             z vÃœbÄrovÃ©ho seznamu umÃ­stÄnÃ©ho vedle pole.
+       <li>SpusttÄ vyhledÃ¡vÃ¡nÃ­ jako to dÄlÃ¡te obyÄejnÄ.
+   </ul>
+<p><li>Pro hledÃ¡nÃ­ dokumentÅ¯ tÃœkajÃ­cÃ­ch se ÄasovÃ©ho obdobÃ­ nebo rozsahu let:<p>
+   <ul>
+       <li>NapiÅ¡te jakÃœkoliv hledanÃœ vÃœraz stejnÄ jako byste to dÄlali obyÄejnÄ.
+       <li>NapiÅ¡te dÅÃ­vÄjÅ¡Ã­ hledanÃœ rok do pole "Start (or only) date".
+       <li>NapiÅ¡tÄ pozdÄjÅ¡Ã­ hledanÃœ rok do pole "End date".
+       <li>Vyberte moÅŸnost "B.C.E" vedle polÃ­ s rokem pÅed Kristem.
+       <li>SpusttÄ vyhledÃ¡vÃ¡nÃ­ jako to dÄlÃ¡te obyÄejnÄ.
+   </ul>
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=cs] {JakÃœm zpÅ¯sobem jsou hledÃ¡ny vÃœsledky na uvedenÃ© dotazy}
+_texthelpdateresults_ [l=cs] {
+ObecnÄ ÅeÄeno, hledÃ¡nÃ­ dokumentÅ¯ o roce 1903 nevrÃ¡tÃ­ dokumenty, kterÃ© odkazujÃ­ knihy napsanÃ© v roce 1903, ale pouze dokumenty o 1903. NicmÃ©nÄ za pouÅŸÃ­tÃ­ zpÅ¯sobu, kterÃœm jsou hledÃ¡ny datumy dokumentÅ¯, vrÃ¡tÃ­ uvedenÃœ dotaz  dokumenty, kterÃ© majÃ­ pÅiÅazen rozsah datumÅ¯ (napÅÃ­klad 1899-1911) do nejÅŸ spadÃ¡ i hledanÃ© datum. StejnÄ tak budou nalezeny dokumenty, jejichÅŸ textovÃ© nÃ¡zvy obsahujÃ­ stoletÃ­, do nejÅŸ rok 1903 patÅÃ­ (napÅÃ­klad "20th century" nebo "twentieth century"). To znamenÃ¡, ÅŸe pro nÄkterÃ© dokumenty se hledanÃ© datumy nebudou nachÃ¡zet v textu dokumentu. PÅi hledÃ¡nÃ­ ÄasovÃ©ho obdobÃ­ se vÅ¡e co bylo uvedeno vztahuje na kaÅŸdÃœ rok zadanÃ©ho ÄasovÃ©ho rozmezÃ­.<p>
+}
+
+_textchangeprefs_ [l=cs] {ZmÄna vaÅ¡ich nastavenÃ­}
+
+_texthelppreferences_ [l=cs] {
+<p>KdyÅŸ stisknete tlaÄÃ­tko <i>nastavenÃ­</i>, kterÃ© se nachÃ¡zÃ­ v hornÃ­ ÄÃ¡sti strÃ¡nky,
+budete mÃ­t moÅŸnost mÄnit nÄkterÃ© vlastnosti rozhranÃ­ tak, aby vyhovovaly vaÅ¡Ã­m poÅŸadavkÅ¯m.
+}
+
+_texthelpcollectionprefstitle_ [l=cs] {NastavenÃ­ pro kolekce}
+_texthelpcollectionprefs_ [l=cs] {
+NÄkterÃ© kolekce se sklÃ¡dajÃ­ z vÃ­ce podkolekcÃ­, kterÃ© mohou bÃœt prohledÃ¡vÃ¡ny
+nezÃ¡visle nebo najednou jako celek. V takovÃ©m pÅÃ­padÄ mÅ¯ÅŸete na strÃ¡nce
+NastavenÃ­ zvolit, kterÃ© podkolekce majÃ­ bÃœt zahrnuty do vyhledÃ¡vÃ¡nÃ­.
+}
+
+_texthelplanguageprefstitle_ [l=cs] {NastavenÃ­ jazyka}
+_texthelplanguageprefs_ [l=cs] {
+KaÅŸdÃ¡ kolekce mÃ¡ nastaven vÃœchozÃ­ jazyk, v nÄmÅŸ je zobrazena, ale je moÅŸnÃ©
+zvolit i jazyk jinÃœ. StejnÄ tak je moÅŸnÃ© mÄnit schÃ©ma kÃ³dovÃ¡nÃ­ pouÅŸÃ­vanÃ©
+v rÃ¡mci Greenstone pro zobrazovÃ¡nÃ­ vÃœstupu v prohlÃ­ÅŸeÄi -- software vybere
+smyslupnou vÃœchozÃ­ hodnotu, u nÄkterÃœch prohlÃ­ÅŸeÄÅ¯ je vÅ¡ak lepÅ¡Ã­ zvolit
+kÃ³dovacÃ­ schÃ©ma manuÃ¡lnÄ. VÅ¡echny kolekce vÃ¡m umoÅŸÅujÃ­ zmÄnit standardnÃ­
+grafickÃ© rozhranÃ­ na textovÃ©. To je zvlÃ¡Å¡tÄ uÅŸiteÄnÃ© pro zrakovÄ postiÅŸenÃ©
+uÅŸivatele, kteÅÃ­ pak mohou pouÅŸÃ­vat velkÃ© fonty nebo vÃœstup z hlasovÃ©ho 
+syntetizÃ¡toru.
+}
+
+_texthelppresentationprefstitle_ [l=cs] {NastavenÃ­ prezentace}
+_texthelppresentationprefs_ [l=cs] {
+V zÃ¡vislosti na kolekcÃ­ch mohou bÃœt k dispozici nÄkterÃ¡ nastavenÃ­, kterÃ¡ ovlivnÃ­
+zpÅ¯sob prezentace.
+
+<p>Kolekce internetovÃœch strÃ¡nek umoÅŸÅujÃ­ zruÅ¡it navigaÄnÃ­ panel Greenstone, kterÃœ je
+umÃ­stÄnÃœ v hornÃ­ ÄÃ¡sti kaÅŸdÃ© strÃ¡nky s dokumentem, takÅŸe po ukonÄenÃ­ vyhledÃ¡vÃ¡nÃ­
+a vÃœbÄru z vÃœsledkÅ¯ se dostanete na konkrÃ©tnÃ­ internetovou strÃ¡nku, kterÃ¡ vÅ¡ak nebude
+obsahovat hlaviÄku Greenstone. Pro dalÅ¡Ã­ vyhledÃ¡vÃ¡nÃ­ musÃ­te ve vaÅ¡em prohlÃ­ÅŸeÄi pouÅŸÃ­t
+tlaÄÃ­tko "zpÃ¡tky". Tyto kolekce takÃ© umoÅŸÅujÃ­ potlaÄit varovnÃ© vÃœpisy systÃ©mu
+Greenstone ve chvÃ­li, kdyÅŸ zvolÃ­te odkaz, kterÃœ vÃ¡s zavede mimo kolekci digitÃ¡lnÃ­
+knihovny - na strÃ¡nky umÃ­stÄnÃ© na internetu. A v nÄkterÃœch internetovÃ© kolekcÃ­ch
+mÅ¯ÅŸete kontrolovat, zda vÃ¡s odkazy na strÃ¡nce vÃœsledkÅ¯ vyhledÃ¡vÃ¡nÃ­ dostanou 
+pÅÃ­mo na danÃ© URL a ne na kopii dokumentu uloÅŸenou v digitÃ¡lnÃ­ knihovnÄ.
+}
+
+_texthelpsearchprefstitle_ [l=cs] {NastavenÃ­ vyhledÃ¡vÃ¡nÃ­}
+_texthelpsearchprefs_ [l=cs] {
+<p>ZpÅ¯sob porovnÃ¡vÃ¡nÃ­ textu pÅi vyhledÃ¡vÃ¡nÃ­ ÅÃ­dÃ­ dva pÃ¡ry tlaÄÃ­tek. PrvnÃ­ dvojice
+(oznaÄenÃ¡ "VELKÃ,malÃ¡ pÃ­smena") urÄuje, zda musÃ­ souhlasit velikost pÃ­smen.
+DruhÃ¡ dvojice ("anglickÃ© koncovky" (<i>word endings</i>)) urÄuje, budou ignorovÃ¡ny anglickÃ©
+ koncovky slov. Je moÅŸnÃ© zvolit vÄtÅ¡Ã­ rozmÄr oblasti pro zadÃ¡vÃ¡nÃ­ dotazÅ¯, takÅŸe
+lze snadno provÃ¡dÄt i prohledÃ¡vÃ¡nÃ­ podle obsahu celÃœch odstavcÅ¯. Pro velkÃ© objemy textu
+je pÅekvapivÄ rychlÃ©.
+
+<p>Jsou-li napÅÃ­klad vybrÃ¡na tlaÄÃ­tka <i>ignoruj velikost znakÅ¯</i> a
+<i>automaticky doplÅ</i>, dotaz<p>
+    <ul><kbd>African building</kbd></ul>
+      <p>bude zpracovÃ¡n stejnÄ jako<p>
+      <ul><kbd>africa builds</kbd></ul><p>
+      protoÅŸe velkÃ© pÃ­smeno ve slovÄ "African" bude transformovÃ¡no na
+      malÃ© a ze slov "African" a "building" budou odstranÄny pÅÃ­pony "n" a "ing" (stejnÄ tak bude "s"
+      odstranÄno ze slova "builds").
+
+<p>Je moÅŸnÃ© zvolit "rozÅ¡Ã­ÅenÃœ" mÃ³d vyhledÃ¡vÃ¡nÃ­, kterÃœ dovoluje kombinovat vÃœrazy pomocÃ­
+logickÃœch operÃ¡torÅ¯ AND (&), OR (|), a NOT (!). DÃ­ky tomu je moÅŸnÃ© zadÃ¡vat pÅesnÄjÅ¡Ã­ dotazy.
+Lze takÃ© zapnout moÅŸnost zobrazovÃ¡nÃ­ historie hledÃ¡nÃ­, kterÃ¡ ukazuje nÄkolik poslednÃ­ch dotazÅ¯
+a umoÅŸÅuje snadno opakovat mÃ­rnÄ pozmÄnÄnÃ© dotazy znovu. A koneÄne lze takÃ© urÄit maximÃ¡lnÃ­ poÄet
+vÃœsledkÅ¯, vrÃ¡cenÃœch pÅi hledÃ¡nÃ­ vÃœrazu.}
+
+_texttanumbrowseoptions_ [l=cs] {Existuje _numbrowseoptions_ zpÅ¯sob(Å¯), jak hledat informace v tÃ©to kolekci:}
+
+_textsimplehelpheading_ [l=cs] {Jak hledat informace v kolekci _collectionname_}
+
+_texthelpscopetitle_ [l=cs] {Rozsah dotazÅ¯}
+_texthelpscope_ [l=cs] {
+<p>
+Ve vÄtÅ¡inÄ kolekcÃ­ mÅ¯ÅŸete vybrat prohledÃ¡vÃ¡nÃ­ rÅ¯znÃœch indexÅ¯. NapÅÃ­klad mohou existovat
+indexy autorÅ¯ nebo nÃ¡zvÅ¯. Nebo to mohou bÃœt indexy kapitol a odstavcÅ¯. VÃœsledkem
+hledÃ¡nÃ­ jsou vÅŸdy dokumenty, kterÃ© plnÄ odpovÃ­dajÃ­ dotazu - to platÃ­ nezÃ¡visle na 
+prohledÃ¡vanÃ©m indexu.
+<p>JestliÅŸe dokumenty jsou knihami, budou otevÅeny na sprÃ¡vnÃ©m mÃ­stÄ.}
Index: /gsdl/stable/macros/czech2.dm
===================================================================
--- /gsdl/stable/macros/czech2.dm	(revision 20131)
+++ /gsdl/stable/macros/czech2.dm	(revision 20131)
@@ -0,0 +1,842 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Czech Language text and icon macros 
+# Many thanks to Roman Chyla and Jakub Rehan (translated 2003 & 2004)
+#
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=cs] {dokumentÅ¯.}
+_lastupdate_ [l=cs] {Naposledy aktualizovÃ¡no}
+_ago_ [l=cs] {dny.}
+_colnotbuilt_ [l=cs] {Kolekce nebyla vytvoÅena.}
+
+_textpoem_ [l=cs] {<br>
+<h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino, 
+<br>kia tere te karohirohi, 
+<br>kia papapounamu te moana
+
+<p>kÃ©ÅŸ mÃ­r a vÃ¡nek tÄ provÃ¡zÃ­,
+<br>kÃ©ÅŸ zÅ¯stÃ¡vÃ¡Å¡ ve slunci letnÃ­ho oparu,
+<br>a oceÃ¡n tvÃœch poutÃ­ aÅ¥ je hladkÃœ jako greenstone.}
+
+_textgreenstone_ [l=cs] {<p>
+Greenstone je polodrahokam, kterÃœ (stejnÄ jako tento program) pochÃ¡zÃ­ z NovÃ©ho ZÃ©landu.
+V tradiÄnÃ­ maorskÃ© spoleÄnosti je povaÅŸovÃ¡n za najcennÄjÅ¡Ã­ latku. MÅ¯ÅŸe do sebe pÅijmout
+a podrÅŸet <i>wairua</i>, coÅŸ je "duch" a nebo taky "ÅŸivotnÃ­ sÃ­la". Greenstone je opÅeden
+tradiÄnÃ­mi ctnostmi, kterÃ© z nÄj dÄlajÃ­ vhodnÃœ emblÃ©m pro vÄÅejnÄ-pÅÃ­stupnÃœ projekt digitÃ¡lnÃ­ knihovny
+. Jeho lesk je dobrotivÃœ; jeho prÅ¯svitnost je vzneÅ¡enÃ¡; jeho pevnost odvÃ¡ÅŸnÃ¡ a jeho ostrÃ© hrany spravedlivÃ©. 
+VyÅezÃ¡vanÃœ kÃ¡men, kterÃœ vidÃ­te v logu Greenstone, je <i>patu</i> - bojovÃ¡ zbraÅ. Je to rodinnÃ© dÄdictvÃ­ jednoho
+ze zaklÃ¡dajÃ­cÃ­ch ÄlenÅ¯ Greenstone. V boji mÅ¯ÅŸe proti muÅŸi jsou argumenty <i>patu</i>  velmi rychlÃ©, pÃ¡dnÃ© a zdrcujÃ­cÃ­. 
+RÃ¡di bychom si mysleli, ÅŸe tyto kvality se pÅenÃ¡Å¡ejÃ­ i na nÃ¡Å¡ program; ostÅÃ­ <i>patu</i> je rozhranÃ­m naÅ¡Ã­ technologie.}
+
+_textaboutgreenstone_ [l=cs] {<p>
+Greenstone je balÃ­kem programÅ¯ pro vytvÃ¡ÅenÃ­ a distribuci digitÃ¡lnÃ­ kolekcÃ­. NabÃ­zÃ­ novÃœ zpÅ¯sob organizace
+a publikovÃ¡nÃ­ informacÃ­ na internetu a na discÃ­ch CD-ROM.
+
+<p>Greenstone je vyvÃ­jen v rÃ¡mci projektu <b>New Zealand Digital Library</b> a distribuovÃ¡n v kooperaci
+s <b>UNESCO</b> a s nevlÃ¡dnÃ­ organizacÃ­ <b>Human Info NGO</b>. 
+
+Je to program s otevÅenÃœm kÃ³dem a distribuuje se pod licencÃ­ GNU General Public License
+z <a href"http://greenstone.org">http://greenstone.org</a>.
+<p>
+Tento projekt chce dÃ¡t uÅŸivatelÅ¯m nÃ¡stroje pro vytvÃ¡ÅenÃ­ vlastnÃ­ch digitÃ¡lnÃ­ch kolekcÃ­ (a to zejmÃ©na uÅŸivatelÅ¯ z univerzit,
+knihoven a dalÅ¡Ã­ch veÅejnÄ prospÄÅ¡nÃœch institucÃ­). V ÄlenskÃœch zemÃ­ch UNESCO, ale takÃ© v rozvojovÃœch zemÃ­ch hrajÃ­
+digitÃ¡lnÃ­ knihovny dÅ¯leÅŸitou roli pÅi rozÅ¡iÅovÃ¡nÃ­ iformacÃ­ v oblastech vzdÄlÃ¡vÃ¡nÃ­, vÄdy a kultury. VÄÅÃ­me, ÅŸe tento projekt
+podpoÅÃ­ efektivnÃ­ vyuÅŸitÃ­ digitÃ¡lnÃ­ knihoven v jejich Ãºkolu sdÃ­let a rozÅ¡iÅovat informace ve spoleÄnosti.<p>Tento software
+je vyvÃ­jen a distribuovÃ¡n od srpna 2000 v rÃ¡mci mezinÃ¡rodnÃ­ spoluprÃ¡ce mezi:
+<table border="0">
+<tr valign="top">
+<td>
+<a href="http://nzdl.org"><b>projekt New Zealand Digital Library na UniversitÄ Waikato</b></a> 
+<br>
+Zde Greenstone vznikl. Byl podporovÃ¡n KomisÃ­ pro komunikaci, kterÃ¡ je souÄÃ¡stÃ­ novozÃ©landskÃ©ho NÃ¡rodnÃ­ho sekretariÃ¡tu pro UNESCO (jako souÄÃ¡st pÅÃ­spÄvku NovÃ©ho ZÃ©landu do programu UNESCO).
+</td>
+<td></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://www.unesco.org"><b>United Nations Educational, Scientific and Cultural Organization</b></a> 
+
+KlÃ­ÄovÃœm cÃ­lem UNESCO je rozÅ¡iÅovÃ¡nÃ­ informacÃ­ pro vÄdu, vzdÄlÃ¡vÃ¡nÃ­ a kulturnÃ­ rozvoj. ZvlÃ¡Å¡tÄ dostupnost tÄchto informacÃ­ v rozvojovÃœch zemÃ­ch, je centrÃ¡lnÃ­m bodem mezivlÃ¡dnÃ­ho programu "Informace pro vÅ¡echny"; kvalitnÃ­ a dostupnÃ¡ informaÄnÃ­ a komunikaÄnÃ­ technologie se v tomto kontextu jevÃ­ jako dÅ¯leÅŸitÃœ nÃ¡stroj.
+</td>
+<td><a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+border="0"></a></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://humaninfo.org"><b>NevlÃ¡dnÃ­ organizace Human Info, se sÃ­dlem v AntverpÃ¡ch, Belgie</b></a> 
+
+Tento projekt, spolupracujÃ­cÃ­ s agenturami SpojenÃœch nÃ¡rodÅ¯ (UN) a s dalÅ¡Ã­mi nevlÃ¡dnÃ­mi organizacemi, si zÃ­skal svÄtovÃ© uznÃ¡nÃ­ dÃ­ky digitalizaci a zpÅÃ­stupnÄnÃ­ dokumentÅ¯ pro rozvoj zemÃ­ tÅetÃ­ho svÄta. SbÃ­rky jsou distribuovÃ¡ny rozvojovÃœm zemÃ­m zdarma, ostatnÃ­m za Ãºhradu nÃ¡kladÅ¯ na vÃœrobu.
+</td>
+<td><a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" border="0"></a></td>
+</tr>
+</table> 
+}
+
+
+_textdescrselcol_ [l=cs] {zvolit kolekci}
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=cs] {Na domovskÃ© strÃ¡nce jsou dalÅ¡Ã­ ÄtyÅi tlaÄÃ­tka}
+
+_textnocollections_ [l=cs] {<p>V souÄasnÃ© dobÄ nejsou v rÃ¡mci tÃ©to instalace Greenstone k dispozici ÅŸÃ¡dnÃ© kolekce.
+Pro pÅÃ­dÃ¡nÃ­ kolekcÃ­ mÅ¯ÅŸete
+<ul>
+ <li>pouÅŸÃ­t <a href="_httppagecollector_">Collector</a> pro vytvoÅenÃ­ novÃœch kolekcÃ­</li>
+ <li>pokud mÃ¡te CD-ROM Greenstone, mÅ¯ÅŸete naisntalovat kolekce z CD-ROM
+</ul>}
+
+_text1coll_ [l=cs] {Tato instalace Greenstone obsahuje 1 kolekci}
+
+_textmorecolls_ [l=cs] {PoÄet kolekcÃ­ v rÃ¡mci tÃ©to instalace Greenstone: _1_}
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=cs] {ExternÃ­ odkaz}
+_textlinknotfound_ [l=cs] {InternÃ­ odkaz nenalezen}
+
+_textextlinkcontent_ [l=cs] {ZvolenÃœ odkaz vede k externÃ­mu dokumentu (vzhledem k vaÅ¡im souÄasnÃœm kolekcÃ­m).
+PÅejete-li si zobrazit odkazovanou strÃ¡nku a vÃ¡Å¡ prohlÃ­ÅŸeÄ mÃ¡ pÅÃ­stup k internetu, mÅ¯ÅŸete
+<a href"_nexturl_">pouÅŸÃ­t tento odkaz</a>; v opaÄnÃ©m pÅÃ­padÄ se vraÅ¥te pomocÃ­ tlaÄÃ­tka "zpÄt" ve vaÅ¡em prohlÃ­ÅŸeÄi.}
+
+_textlinknotfoundcontent_ [l=cs] {InternÃ­ odkaz, kterÃœ jste zvolili, neexistuje. PÅÃ­Äiny tÃ©to chyby jsou mimo naÅ¡e pole pÅ¯sobnostÃ­.
+NejpravdÄpodobnÄjÅ¡Ã­ pÅÃ­Äinou je chyba ve zdrojovÃœch dokumentech kolekce.
+Pro nÃ¡vrat k poslednÃ­mu dokumentu pouÅŸijte ve vaÅ¡em prohlÃ­ÅŸeÄi tlaÄÃ­tko "zpÄt".}
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=cs] {<h3>Odkaz ke kolekci "_2_" </h3>
+
+<p>
+Odkaz, kterÃœ jste zvolili je externÃ­. Odkazuje na kolekci "_2_". PÅejete-li si zobrazit dokument z kolece "_2_" mÅ¯ÅŸete pouÅŸÃ­t <a href"_httpdoc_&c_1_&cl_cgiargcl_&d_3_">tento odkaz</a>; v opaÄnÃ©m pÅÃ­padÄ pouÅŸijte tlaÄÃ­tka "zpÄt" ve vaÅ¡em prohlÃ­ÅŸeÄi.}
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=cs] {DigitÃ¡lnÃ­ knihovna Greenstone}
+
+_textusername_ [l=cs] {pÅihlaÅ¡ovacÃ­ jmÃ©no}
+_textpassword_ [l=cs] {heslo}
+
+_textmustbelongtogroup_ [l=cs] {Pozn. MusÃ­te patÅit do skupiny "_cgiargug_"}
+
+_textmessageinvalid_ [l=cs] {PoÅŸadovanÃ¡ strÃ¡nka vyÅŸaduje autentifikaci.<br> 
+_If_(_cgiargug_, [_textmustbelongtogroup_])<br>
+ProsÃ­m zadejte pÅihlaÅ¡ovacÃ­ jmÃ©ho a heslo. }
+
+_textmessagefailed_ [l=cs] {BuÄ VaÅ¡e pÅihlaÅ¡ovacÃ­ jmÃ©no, nebo heslo jsou neplatnÃ©.}
+
+_textmessagedisabled_ [l=cs] {PromiÅte, VÃ¡Å¡ ÃºÄet byl zablokovÃ¡n. ProsÃ­m kontaktujte sprÃ¡vce tÃ©to sÃ­tÄ.}
+
+_textmessagepermissiondenied_ [l=cs] {PromiÅte, nemÃ¡te oprÃ¡vnÄnÃ­ pÅistupovat k tÃ©to strÃ¡nce.}
+
+_textmessagestalekey_ [l=cs] {Odkaz je zastaralÃœ, prosÃ­m zadejte VaÅ¡e heslo.}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=cs] {<p>
+Tato instalace Greenstone neobsahuje ÅŸÃ¡dnou dokumentaci. 
+MoÅŸnÃ© pÅÃ­Äiny:
+<ol>
+ <li>Greenstone byl nainstalovÃ¡n v kompaktnÃ­ verzi (z disku CD-ROM ).
+ <li>Greenstone byl nainstalovÃ¡n z internetu.
+</ol>
+V obou pÅÃ­padech mÅ¯ÅŸete zÃ­skat dokumentaci buÄ z adresÃ¡Åe <i>docs</i> na disku
+Greenstone CD-ROM, a nebo z <a href"http://www.greenstone.org">http://www.greenstone.org</a>. }
+
+_textuserguide_ [l=cs] {PÅÃ­ruÄka uÅŸivatele}
+_textinstallerguide_ [l=cs] {InstalaÄnÃ­ pÅÃ­ruÄka}
+_textdeveloperguide_ [l=cs] {"PÅÃ­ruÄka administrÃ¡tora"}
+_textpaperguide_ [l=cs] {PÅÃ­ruÄka 'Od papÃ­ru ke kolekci'}
+_textorganizerguide_ [l=cs] {PouÅŸÃ­vÃ¡nÃ­ nÃ¡stroje 'Organizer'}
+
+_textgsdocstitle_ [l=cs] {Dokumentace Greenstone}
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=cs] {vÃœchozÃ­ nastavenÃ­}
+_textmore_ [l=cs] {vÃ­ce}
+_textinfo_ [l=cs] {Informace o kolekci}
+_textsrce_ [l=cs] {ZdrojovÃ¡ data}
+_textconf_ [l=cs] {Konfigurovat kolekci}
+_textbild_ [l=cs] {VytvoÅit kolekci}
+_textview_ [l=cs] {UkÃ¡zat kolekci}
+_textdel_ [l=cs] {Smazat kolekci}
+_textexpt_ [l=cs] {Exportovat kolekci}
+
+_textdownloadingfiles_ [l=cs] {Stahuji soubory...}
+_textimportingcollection_ [l=cs] {Importuji kolekci...}
+_textbuildingcollection_ [l=cs] {VytvÃ¡ÅÃ­m kolekci...}
+_textcreatingcollection_ [l=cs] {vytvÃ¡ÅenÃ­ kolekce...}
+
+_textcollectorblurb_ [l=cs] {<i>Pero je mocnÄjÅ¡Ã­ neÅŸ meÄ!
+<br>
+Tvorba a distrubuce informacÃ­ s sebou pÅinÃ¡Å¡Ã­ zodpovÄdnost, kterou byste si mÄli uvÄdomit jeÅ¡tÄ pÅed tÃ­m,
+neÅŸ zaÄnete. Nejsou to pouze prÃ¡vnÃ­ problÃ©my kolem autorskÃœch prÃ¡v (to, ÅŸe mÃ¡te pÅÃ­stup k dokumentÅ¯m
+jeÅ¡tÄ neznamenÃ¡, ÅŸe je mÅ¯ÅŸete dÃ¡t druhÃœm); existujÃ­ i dalÅ¡Ã­ otÃ¡zky sociÃ¡lnÃ­ a etickÃ© povahy. ZohledÅuje
+kolekce zvyky komunity, kterÃ¡ vytvoÅila dokumenty? Jsou vÅ¡echny texty vhodnÃ© k tomu, aby byly dÃ¡ny
+k dispozici druhÃœm? 
+<br> 
+BuÄte vnÃ­mavÃ­ k sÃ­le informacÃ­ a pouÅŸÃ­vejte ji moudÅe.</i>}
+
+_textcb1_ [l=cs] {Collector VÃ¡m pomÅ¯ÅŸe vytvoÅit novÃ© nebo zmÄnit Äi smazat  existujÃ­cÃ­ kolekce.
+CelÃœm procesem VÃ¡s provedede soubor strÃ¡nek, kterÃ© budou postupnÄ vyÅŸadovat zadÃ¡nÃ­ potÅebnÃœch informacÃ­.}
+
+_textcb2_ [l=cs] {NejdÅÃ­ve musÃ­te rozhodnout jestli}
+_textcnc_ [l=cs] {vytvoÅit novou kolekci}
+_textwec_ [l=cs] {pracovat s existujÃ­cÃ­mi kolekcemi, pÅidÃ¡vat do nich data nebo kolekci smazat.}
+
+_textcb3_ [l=cs] {Chcete-li vytvÃ¡Ået nebo mÄnit digitÃ¡lnÃ­ kolekce, musÃ­te se pÅihlÃ¡sit. TÃ­mto zabrÃ¡nÃ­me ostatnÃ­m, aby se pÅihlÃ¡sili k vaÅ¡emu poÄÃ­taÄi a zmÄnili vaÅ¡e sbÃ­rky.
+UpozornÄnÃ­: kvÅ¯li bezpeÄnostnÃ­m dÅ¯vodÅ¯m budete kaÅŸdÃœch 30 minut poÅŸÃ¡dÃ¡nÃ­ o znovu-zadÃ¡nÃ­ hesla. Po pÅihlÃ¡Å¡enÃ­ budete moci pokraÄovat prÃ¡vÄ z
+toho mÃ­sta, kde byla vaÅ¡e prÃ¡ce pÅeruÅ¡ena.}
+
+_textcb4_ [l=cs] {ProsÃ­m zadejte pÅihlaÅ¡ovacÃ­ jmÃ©no a heslo pro Greenstone a stisknÄte tlaÄÃ­tko pro pÅihlÃ¡Å¡enÃ­.}
+
+_textfsc_ [l=cs] {NejdÅÃ­ve vyberte kolekci, se kterou chcete pracovat (kolekce se zapnutou ochranou proti zÃ¡pisu se v tomto seznamu neobjevÃ­).}
+
+_textwtc_ [l=cs] {S kolekcÃ­, kterou jste zvolili, mÅ¯ÅŸete}
+_textamd_ [l=cs] {PÅidat dalÅ¡Ã­ data a znovu vytvoÅit kolekci}
+_textetc_ [l=cs] {Upravit konfiguraÄnÃ­ soubor a znovu vytvoÅit kolekci}
+_textdtc_ [l=cs] {ÃplnÄ smazat kolekci}
+_textetcfcd_ [l=cs] {Exportovat kolekci a vytvoÅit instalaÄnÃ­ CD-ROM pro Windows}
+_textcaec_ [l=cs] {MÄnÃ­m existujÃ­cÃ­ kolekci}
+_textnwec_ [l=cs] {NenÃ­ k dispozici ÅŸÃ¡dnÃ¡ kolekce, do nÃ­ÅŸ je povolen zÃ¡pis.}
+_textcianc_ [l=cs] {VytvÃ¡ÅÃ­m novou kolekci}
+_texttsosn_ [l=cs] {PoÅadÃ­ krokÅ¯ potÅebnÃœch pro vytvoÅenÃ­ novÃ© kolekce digitÃ¡lnÃ­ knihovny je nÃ¡sledujÃ­cÃ­:}
+_textsin_ [l=cs] {Zadejte jejÃ­ jmÃ©no (a doplÅujÃ­cÃ­ informace)}
+_textswts_ [l=cs] {UrÄit odkud pochÃ¡zejÃ­ zdrojovÃ¡ data}
+_textatco_ [l=cs] {Upravit konfiguraÄnÃ­ nastavenÃ­ (pouze pro zkuÅ¡enÃ©h uÅŸivatele)}
+_textbtc_ [l=cs] {"VytvoÅit" kolekci (viz. nÃ­ÅŸe)}
+_textpvyh_ [l=cs] {Zobrazit vÃœsledek }
+
+_texttfsiw_ [l=cs] {Ve ÄtvrtÃ©m kroku uÅŸ bude pracovat jenom poÄÃ­taÄ.
+PÅi budovÃ¡nÃ­ jsou vytvoÅeny indexy a shromÃ¡ÅŸdÄny
+vÅ¡echny informace potÅebnÃ© pro fungovÃ¡nÃ­ kolekce.
+Nejprve ale musÃ­te urÄit, kterÃ© informace to budou.}
+
+_textadab_ [l=cs] {Diagram ve spodnÃ­ ÄÃ¡sti strÃ¡nky VÃ¡m pomÅ¯ÅŸe urÄit mÃ­sto, kde se prÃ¡vÄ nachÃ¡zÃ­te. ZelenÃ© tlaÄÃ­tko VÃ¡s posunuje do nÃ¡sledujÃ­cÃ­ fÃ¡ze, ÅŸlutÃ© tlaÄÃ­tko zase do fÃ¡ze pÅedchozÃ­.
+ZÃ¡roveÅ s tÃ­m, jak postupujete jednotlivÃœmi fÃ¡zemi, se tlaÄÃ­tka obarvovujÃ­ ÅŸlutÄ.}
+
+_textwyar_ [l=cs] {AÅŸ budete hotovi, zmÃ¡ÄknÄte zelenÃ© tlaÄÃ­tko "informace o kolekci". Proces tvorby zaÄne.}
+
+_textcnmbs_ [l=cs] {JmÃ©no kolekce musÃ­ bÃœt specifikovÃ¡no}
+_texteambs_ [l=cs] {EmailovÃ¡ adresa musÃ­ bÃœt vyplnÄna}
+_textpsea_ [l=cs] {ProsÃ­m specifikujte emailovou adresu ve tvaru: jmenouzivatele@domena}
+_textdocmbs_ [l=cs] {Popis kolekce mustÃ­ bÃœt doplnÄn}
+
+_textwcanc_ [l=cs] {PÅi vytvÃ¡ÅenÃ­ novÃ© kolekce musÃ­te zadat nÄkterÃ© dÅ¯leÅŸitÃ© informace o zdrojovÃœch datech.
+Tento proces je strukturovÃ¡n do sÃ©rie strÃ¡nek, nad nimiÅŸ mÃ¡ dohled Collector.
+LiÅ¡ta ve spodnÃ­ ÄÃ¡sti strÃ¡nky vÃ¡m ukÃ¡ÅŸe, ve kterÃ© fÃ¡zi se prÃ¡vÄ nachÃ¡zÃ­te.}
+
+_texttfc_ [l=cs] {NÃ¡zev kolekce:}
+
+_texttctiasp_ [l=cs] {KaÅŸdÃ¡ kolekce mÃ¡ nÃ¡zev; je to krÃ¡tkÃ¡ frÃ¡ze, kterÃ¡ identifikuje obsah kolekce.
+NapÅ. "Computer Science Technical Reports" nebo "Humanity Development Library".}
+
+_textcea_ [l=cs] {KontaktnÃ­ emailovÃ¡ adresa:}
+
+_textteas_ [l=cs] {Tato emailovÃ¡ adresa urÄuje, kdo je kontaktnÃ­ osobou pro danou sbÃ­rku.
+Jestli Greenstone objevÃ­ nÄjakÃœ problÃ©m, zaÅ¡le diagnostickou zprÃ¡vu na tuto adresu.
+Zadejte emailovou adresu v plnÃ©m tvaru: <tt>jmeno@domena</tt>.}
+
+_textatc_ [l=cs] {O tÃ©to kolekci:}
+
+_texttiasd_ [l=cs] {Toto je prohlÃ¡Å¡enÃ­, kterÃ© popisuje celou kolekci. PÅi zobrazenÃ­ kolekce je zobrazeno na ÃºvodnÃ­ strÃ¡nce.}
+
+_textypits_ [l=cs] {VaÅ¡e aktuÃ¡lnÃ­ pozice je naznaÄena pomocÃ­ Å¡ipky -- v tomto pÅÃ­padÄ je to fÃ¡ze "informace o kolekci".
+Chcete-li pokraÄovat, zmÃ¡ÄknÄte zelenÃ© tlaÄÃ­tko "zdrojovÃ¡ data"}
+
+_srcebadsources_ [l=cs] {<p>
+Jeden nebo i nÄkolik zdrojÅ¯, kterÃ© jste zadali, jsou nedosaÅŸitelnÃ© (znaÄeny _iconcross_ ).<p>MoÅŸnÃ© pÅÃ­Äiny <u><li>Soubor, FTP server nebo URL adresa neexistujÃ­. <li>Nejste pÅipojeni na internet. <li>PokouÅ¡Ã­te se pÅistoupit ke strÃ¡nce zpoza firewallu (kdyÅŸ musÃ­te zadÃ¡vat pÅihlaÅ¡ovacÃ­ jmÃ©no a heslo, abyste se dostali do internetu). </ul><p>Pokud vidÃ­te strÃ¡nku s touto URL adresou ve VaÅ¡em prohlÃ­ÅŸeÄi, mÅ¯ÅŸe pochÃ¡zet i z doÄasnÃ© lokÃ¡lnÄ uloÅŸenÃ© kopie. LokÃ¡lnÃ­ kopie (cache) jsou bohuÅŸel pro nÃ¡Å¡ importovacÃ­ program neviditelnÃ©. DoporuÄujeme strÃ¡nky stÃ¡hnout a uloÅŸit pomocÃ­ VaÅ¡eho prohlÃ­ÅŸeÄe.}
+
+_textymbyco_ [l=cs] {<p>
+MÅ¯ÅŸete zaloÅŸit svoji kolekci buÄ
+<ul>
+<li> na standardnÃ­m nastavenÃ­
+<dl><dd>NovÃ¡ kolekce mÅ¯ÅŸe obsahovat html dokumenty (.htm, .html), jednoduchÃœ text(.txt, .text),
+dokumenty MS Word (.doc), PDF dokumenty (.pdf) nebo formÃ¡t "m-box" emailovÃœch souborÅ¯ (.mbx)</dd></dl>
+<li>na nÄkterÃ© z existujÃ­cÃ­ch sbÃ­rek
+<dl><dd> Soubory ve vaÅ¡Ã­ novÃ© kolekci musejÃ­ bÃœt stejnÃ©ho typu jako ty, kterÃ© byly pouÅŸity v existujÃ­cÃ­ sbÃ­rce.</dd></dl>
+</ul> }
+
+_textbtco_ [l=cs] {ZaloÅŸit kolekci na}
+_textand_ [l=cs] {PÅidat novÃ¡ data}
+_textad_ [l=cs] {PÅidÃ¡vat data:}
+
+_texttftysb_ [l=cs] {Soubory, kterÃ© urÄÃ­te niÅŸe na tÃ©to strÃ¡nce, budou pÅidÃ¡ny do kolekce. UjistÄte se, ÅŸe existujÃ­ v kolekci pouze
+jednou; v opaÄnÃ©m pÅÃ­padÄ se v kolekci objevÃ­ duplikÃ¡ty. Soubory jsou identifikovÃ¡ny podle svÃ©
+plnÃ© cesty, webovÃ© strÃ¡nky podle svÃ© absolutnÃ­ adresy.}
+
+_textis_ [l=cs] {Zdroje pro import:}
+
+_textddd1_ [l=cs] {<p>
+Pokud pouÅŸijete <b>file://</b> nebo <b>ftp://</b>, abyste urÄili jeden soubor, potom bude staÅŸen pouze ten jedinÃœ soubor.
+
+<p>Pokud pouÅŸijete  <b>http://</b>, vÃœsledek bude zÃ¡viset na tom, jestli zadanÃ¡ URL adresa odkazuje na normÃ¡lnÃ­ web. strÃ¡nku,
+jak ji vidÃ­te v prohlÃ­ÅŸeÄi, a nebo na adresÃ¡Å strÃ¡nek. JestliÅŸe je to normÃ¡lnÃ­ strÃ¡nka, bude importovÃ¡na a spolu s nÃ­ takÃ© dokumenty,
+na kterÃ© odkazuje (stahovÃ¡nÃ­ se nezastavÃ­ u prvnÃ­ch odkazÅ¯, ale bude sledovat dalÅ¡Ã­ odkazy a stÃ¡hne vÅ¡echny odkazovanÃ© dokumenty
+z <b>danÃ©ho</b> serveru (URL).
+<p>JestliÅŸe pouÅŸijete URL, kterÃ© odkazuje na adresÃ¡Å <b>http://</b>  (<b>ftp://</b>, <b>file://</b>), tak potom bude importovÃ¡n veÅ¡kerÃœ
+obsah danÃ© sloÅŸky (vÄetnÄ podsloÅŸek).<p>
+Chcete-li vÃ­ce polÃ­Äek pro zadÃ¡nÃ­ adresy, zmÃ¡ÄknÄte tlaÄÃ­tko "vÃ­ce zdrojÅ¯".}
+
+_textddd2_ [l=cs] {<p>
+ZmÃ¡ÄknÄte jedno ze zelenÃœch tlaÄÃ­tek. Nejste-li zkuÅ¡enÃœmi uÅŸivateli, pokraÄujte do dalÅ¡Ã­ho kroku.
+Zapamatujte si, ÅŸe se mÅ¯ÅŸete vÅŸdy do pÅedchozÃ­ho kroku tÃ­m, ÅŸe zmÃ¡Äknete ÅŸlutÃ© tlaÄÃ­tko.}
+
+_textconf1_ [l=cs] {<p>
+Tvorba a zpÅ¯sob zobrazenÃ­ vaÅ¡Ã­ kolekce je kontrolovÃ¡n nastavenÃ­m
+ve speciÃ¡lnÃ­m konfiguraÄnÃ­m souboru. ZkuÅ¡enÃ­ uÅŸivatelÃ© jej pravdÄpodobnÄ
+budou chtÃ­t zmÄnit.
+<center><p>
+<b>Pokud nejste zkuÅ¡enÃœmi uÅŸivateli, jednoduÅ¡e pÅejdÄte na dalÅ¡Ã­ strÃ¡nku.</b></center>
+<p>Chcete-li zmÄnit nastavenÃ­, upravte ÅÃ¡dky, kterÃ© jsou zobrazeny nÃ­ÅŸe.
+Pokud udÄlÃ¡te chybu, mÅ¯ÅŸete pouÅŸÃ­t tlaÄÃ­tka "Reset" - objevÃ­ se pÅ¯vodnÃ­ konfiguraÄnÃ­ soubor.}
+
+_textreset_ [l=cs] {Reset}
+
+_textbild1_ [l=cs] {Kolekce se nynÃ­ vytvÃ¡ÅÃ­: mÅ¯ÅŸe to chvÃ­li trvat. ÅÃ¡dek ve spodnÃ­ ÄÃ¡sti obrazovky naznaÄuje prÃ¡vÄ probÃ­hajÃ­cÃ­ operace.}
+
+_textbild2_ [l=cs] {Pokud chcete ukonÄit proces tvorby, mÅ¯ÅŸete kdykoli kliknout zde. <br> 
+Kolekce na kterÃ© se prÃ¡vÄ pracuje zÅ¯stane nezmÄnÄna.}
+
+_textstopbuild_ [l=cs] {zastavit tvorbu}
+
+_textbild3_ [l=cs] {Pokud tuto strÃ¡nku opustÃ­te (a nezruÅ¡Ã­te tvorbu kolekce pomocÃ­ tlaÄÃ­tka "stop"), proces bude pokraÄovat a po ÃºspÄÅ¡nÃ©m dokonÄenÃ­ bude kolekce automaticky nainstalovÃ¡na.}
+
+_textbuildcancelled_ [l=cs] {Tvorba zruÅ¡ena}
+
+_textbildcancel1_ [l=cs] {Tvorba kolekce byla zruÅ¡ena. PouÅŸijte ÅŸlutÃ©ho tlaÄÃ­tka vespodu, pokud chcete zmÄnit konfiguraci, a nebo spusÅ¥te tvorbu znovu.}
+
+_textbsupdate1_ [l=cs] {IndikÃ¡tor tvorby se akturalizuje za 1 sekundu}
+_textbsupdate2_ [l=cs] {IndikÃ¡tor tvorby aktualizovÃ¡n v }
+_textseconds_ [l=cs] {sekund}
+_textbildsuc_ [l=cs] {Kolekce byla ÃºspÄÅ¡nÄ vytvoÅena.}
+
+_textviewbildsummary_ [l=cs] {MÅ¯ÅŸete zobrazit<a href"_httppagex_(bsummary)&c_cgiargbc1dirname_" target_top>detailnÃ­ zprÃ¡vu</a> o tvorbÄ kolekce.}
+
+_textfailmsg11_ [l=cs] {Kolekce nemohla bÃœt vytvoÅena, protoÅŸe neobsahuje ÅŸÃ¡dnÃ¡ data. UjistÄte se, ÅŸe alespoÅ
+jeden adresÃ¡Å nebo soubor, kterÃœ jste zadali na strÃ¡nce <i>zdrojovÃ¡ data</i>, existuje
+a obsahuje typ informacÃ­, kterÃ© Greenstone dokÃ¡ÅŸe zpracovat.}
+
+_textfailmsg21_ [l=cs] {Kolekce nemohla bÃœt vytvoÅena (chyba import.pl).}
+_textblcont_ [l=cs] {ZprÃ¡va obsahuje nÃ¡sledujÃ­cÃ­ informace:}
+
+_texttryagain_ [l=cs] {ProsÃ­m <a href"_httppagecollector_" target_top>znovu spusÅ¥te Collector</a> a zkuste vÅ¡e znovu.}
+
+_textfailmsg31_ [l=cs] {Kolekce nemohla bÃœt vytvoÅena (chyba buildcol.pl).}
+_textfailmsg41_ [l=cs] {Kolekce byla ÃºspÄÅ¡nÄ vytvoÅena, ale nemohla bÃœt nainstalovÃ¡na.}
+_textfailmsg71_ [l=cs] {BÄhem pokusu o vytvoÅenÃ­ kolekce nastala neoÄekÃ¡vanÃ¡ chyba.}
+_textretcoll_ [l=cs] {VrÃ¡tit se do Collector}
+
+_textdelperm_ [l=cs] {NÄkterÃ© z _cgiargbc1dirname_ kolekcÃ­ nemohly bÃœt smazÃ¡ny. MoÅŸnÃ© pÅÃ­Äiny jsou:<ul>
+<li>Greenstone nemÃ¡ oprÃ¡vnÄnÃ­ mazat adresÃ¡Å _gsdlhome_/collect/_cgiargbc1dirname_.<br>
+Budete muset odstranit tuto kolekci ruÄnÄ, aby zmizela ÃºplnÄ z tohoto poÄÃ­taÄe.</li>
+<li>Greenstone nemÅ¯ÅŸe spustit program _gsdlhome_/bin/script/delcol.pl UjistÄte se,
+ÅŸe soubor mÃ¡ nastaveny atributy "ke ÄtenÃ­" a "spustitelnÃœ".</li></ul>}
+
+_textdelinv_ [l=cs] {Kolekce _cgiargbc1dirname_ je uzamÄena, a nebo je naplatnÃ¡. SmazÃ¡nÃ­ bylo zruÅ¡eno.}
+
+_textdelsuc_ [l=cs] {Kolekce _cgiargbc1dirname_ byla ÃºspÄÅ¡nÄ smazÃ¡na.}
+
+_textclonefail_ [l=cs] {_cgiargclonecol_ kolekce nemohla bÃœt zkopÃ­rovÃ¡na. MoÅŸnÃ© pÅÃ­Äiny jsou:
+<ul>
+<li>Kolekce _cgiargclonecol_ neexistuje</li>
+<li>Kolekce _cgiargclonecol_ postrÃ¡dÃ¡ konfiguraÄnÃ­ soubor (collect.cfg)</li>
+<li>Greenstone nemÃ¡ oprÃ¡vnÄnÃ­ ÄÃ­st z collect.cfg</li>
+</ul>}
+
+_textcolerr_ [l=cs] {Chyba Collector}
+
+_texttmpfail_ [l=cs] {Collector hlÃ¡sÃ­, ÅŸe nemohl ÄÃ­st nebo zapisovat dovnitÅ doÄasnÃ©ho adresÃ¡Åe (souboru).
+MoÅŸnÃ© pÅÃ­Äiny jsou:
+<ul>
+<li>Greenstone nemÃ¡ oprÃ¡vnÄnÃ­ zapisovat/ÄÃ­st do adressÃ¡Åe _gsdlhome_/tmp.<./li>
+</ul>}
+
+_textmkcolfail_ [l=cs] {Collector hlÃ¡sÃ­ chybu pÅi vytvÃ¡ÅenÃ­ adresÃ¡ÅovÃ© struktury (chyba mkcol.pl).
+MoÅŸnÃ© pÅÃ­Äiny jsou:
+<ul>
+<li>Greenstone nemÃ¡ oprÃ¡vnÄnÃ­ zapisovat do adresÃ¡Åe _gsdlhome_/tmp</li>
+<li>chyba v perl skriptu mkcol.pl</li>
+</ul> 
+}
+
+_textnocontent_ [l=cs] {Chyba Collector: pro novou kolekci nebylo specifikovÃ¡no ÅŸÃ¡dnÃ© jmÃ©no. Restartujte Collector od zaÄÃ¡tku.}
+
+_textrestart_ [l=cs] {Restartovat Collector}
+
+_textreloaderror_ [l=cs] {BÄhem tvorby novÃ© kolekce se objevila chyba. Greenstone mohl bÃœt zmaten tÃ­m,
+ÅŸe jste ve VaÅ¡em prohlÃ­ÅŸeÄi pouÅŸili tlaÄÃ­tka "aktualizuj" a nebo "zpÄt"i. Vyvarujte se prosÃ­m
+pouÅŸÃ­vÃ¡nÃ­ tÄchto tlaÄÃ­tek bÄhem procesu tvorby kolekce. DoporuÄujeme
+restartovat Collector od zaÄÃ¡tku.}
+
+_textexptsuc_ [l=cs] {Kolekce _cgiargbc1dirname_ byla ÃºspÄÅ¡nÄ exportovÃ¡na do adresÃ¡Åe _gsdlhome_/tmp/exported\__cgiargbc1dirname_ }
+
+_textexptfail_ [l=cs] {<p>
+Chyba pÅi exportu kolekce _cgiargbc1dirname_ .<p>
+Tato chyba je pravdÄpodobnÄ zpÅ¯sobena tÃ­m, ÅŸe Greenstone byl nainstalovÃ¡n bez komponent nezbytnÃœch
+pro fungovÃ¡nÃ­ funkce exportovÃ¡nÃ­ kolekce.
+<ul>
+<li>Pokud jste instalovali Greenstone z disku CD-ROM, tyto balÃ­Äky nebyly pÅidÃ¡ny. Volba je dostupnÃ¡ pouze
+pÅi typu instalace "Custom". MÅ¯ÅŸete vÅ¡ak spustit instalaci znovu a vybrat Custom - "Export Collection".</li>
+
+<li>Jestli jste instalovali Greenstone z jinÃ©ho zdroje, budete si muset stÃ¡hnout pÅÃ­davnÃœ balÃ­Äek. ProsÃ­m navÅ¡tivte
+<a href"http://www.greenstone.org">http://www.greenstone.org</a> a nebo napiÅ¡te na
+<a href"mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>, poskytneme vÃ¡m dalÅ¡Ã­ informace.</li>
+
+</ul>}
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=cs] {Greenstone je balÃ­kem programÅ¯, kterÃ© majÃ­ schopnost vytvÃ¡Ået a prezentovat kolekce v rÃ¡mci digitÃ¡lnÃ­ch knihoven.
+NabÃ­zÃ­ novÃœ zpÅ¯sob organizovÃ¡nÃ­ a publikovÃ¡nÃ­ informacÃ­ na internetu i na CD-ROM. Greenstone je vyvÃ­jen
+v rÃ¡mci projektu New Zealand Digital Library na universitÄ Waikato, a je distribuovÃ¡n ve spoluprÃ¡ci s UNESCO
+a nevlÃ¡dnÃ­ organizacÃ­ Human Info. Je to otevÅenÃœ systÃ©m (open-source), dostupnÃœ z <i>http://greenstone.org</i>
+za podmÃ­nek GNU General Public License.}
+
+_textgreenstone2_ [l=cs] {InternetovÃ© strÃ¡nky projektu New Zealand Digital library (<a href"http://nzdl.org">http://nzdl.org</a>)
+obsahujÃ­ mnoÅŸstvÃ­ ukÃ¡zek hotovÃœch kolekcÃ­. VÅ¡echny byly vytvoÅeny v programu Greenstone
+a pÅedvÃ¡dÄjÃ­ jeho moÅŸnosti vyhledÃ¡vÃ¡nÃ­ a prohlÃ­ÅŸenÃ­. Naleznete tam kolekce arabskÃ©, ÄÃ­nskÃ©,
+francouzskÃ©, v jazyce Maori nebo ve Å panÄlÅ¡tinÄ Äi AngliÄtinÄ a takÃ© nÄkolik kolekcÃ­ hudebnÃ­ch.}
+
+_textplatformtitle_ [l=cs] {platforma}
+_textgreenstone3_ [l=cs] {Greenstone funguje v operaÄnÃ­ch systÃ©mech Windows i Unix a Mac OS X. DistrubuÄnÃ­ balÃ­Äky obsahujÃ­
+hotovÃ© binÃ¡rnÃ­ instalace pro Windows a pro Linux a Mac OS X. K dipozici je takÃ© kompletnÃ­ zdrojovÃœ
+kÃ³d, kterÃœ lze kompilovat pomocÃ­ Microsoft C++ nebo gcc. Greenstone pouÅŸÃ­vÃ¡ volnÄ Å¡iÅitelnÃ© programy,
+kterÃ© jsou takÃ© k dispozici: webserver Apache a PERL. RozhranÃ­ pro Greenstone vyuÅŸÃ­vÃ¡ webovÃœ prohlÃ­ÅŸeÄ
+(napÅ. Netscape Navigator nebo Internet Explorer).}
+
+_textgreenstone4_ [l=cs] {Mnoho kolekcÃ­ je distribuovÃ¡no na CD-ROM discÃ­ch s programem Greenstone. NapÅ. <i>Humanity Development Library</i>,
+kterÃ¡ obsahuje 1 230 publikacÃ­ sahajÃ­cÃ­ od oblasti ÃºÄetnictvÃ­ k hygienÄ pitnÃ© vody. 
+Distribuce majÃ­ minimÃ¡lnÃ­ nÃ¡roky na vÃœkon poÄÃ­taÄe a proto se hodÃ­ i do podmÃ­nek,
+kterÃ© jsou v rozvojovÃœch zemÃ­ch. Dokumenty lze prohledÃ¡vat, ale i prohlÃ­ÅŸet podle pÅedmÄtovÃœch hesel,
+nÃ¡zvÅ¯, organizacÃ­, seznamÅ¯ "Jak na .." Äi nÃ¡hodnÄ podle kniÅŸnÃ­ch pÅebalÅ¯.}
+
+_textcustomisationtitle_ [l=cs] {pÅizpÅ¯sobenÃ­}
+_textgreenstone5_ [l=cs] {Greenstone je speciÃ¡lnÄ navrÅŸen tak, aby se dal rozÅ¡iÅovat a upravovat. NovÃ© formÃ¡ty
+dokumentÅ¯ i metadat se pÅipojujÃ­ pomocÃ­ (Perl) "pluginÅ¯" a "klasifikÃ¡torÅ¯". Vzhled
+uÅŸivatelskÃ©ho rozhranÃ­ lze mÄnit pomocÃ­ "maker" napsanÃœch pomocÃ­ jednoduchÃ©ho makrojazyka.
+Protokol Corba dovoluje programÅ¯m (agenti - napsanÃ­ napÅÃ­klad v programovacÃ­m jazyce Java),
+aby vyuÅŸÃ­vali procedur pÅipojenÃœch ke sbÃ­rkÃ¡m. A koneÄnÄ, zdrojovÃœ kÃ³d napsanÃœ v C++ a v Perl je
+k dispozici pro dalÅ¡Ã­ Ãºpravy.}
+
+_textdocumentationtitle_ [l=cs] {dokumentace}
+_textdocuments_ [l=cs] {K dispozici je rozsÃ¡hlÃ¡ dokumentace software Greenstone.}
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=cs] {e-mailovÃ¡ konference}
+_textmailinglist_ [l=cs] {Pro diskuse o pouÅŸÃ­vÃ¡nÃ­ digitÃ¡lnÃ­ knihovny Greenstone existujÃ­ emailovÃ¡ konference.
+K pÅihlÃ¡Å¡enÃ­ pouÅŸijte strÃ¡nky <a href"https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+Chcete-li odeslat zprÃ¡vu, zaÅ¡lete ji na <a href"mailto:greenstone-users@list.scms.waikato.ac.nz" >greenstone-users@list.scms.waikato.ac.nz</a>. }
+
+_textbugstitle_ [l=cs] {chyby}
+_textreport_ [l=cs] {Chceme se ujistit, ÅŸe tento program dÄlÃ¡ svou prÃ¡ci dobÅe. ProsÃ­me hlaste jakoukoliv
+chybu na <a href"mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>.  }
+
+_textgs3title_ [l=cs] {v pracÃ­ch}
+_textgs3_ [l=cs] {Greenstone 3 je kompletnÃ­m pÅepracovÃ¡nÃ­m a novou implementacÃ­, kterÃ¡
+zachovÃ¡vÃ¡ vÅ¡echny vÃœhody Greenstone 2 (souÄasnÃ¡ verze). NapÅÃ­klad je
+vÃ­cejazyÄnÃœ, multiplatformnÃ­ a znaÄnÄ konfigurovatelnÃœ. SluÄuje vÅ¡echny
+rysy existujÃ­cÃ­ho systÃ©mu a zachovÃ¡vÃ¡ zpÄtnou kompatibilitu: to znamenÃ¡,
+ÅŸe umoÅŸÅuje vytvÃ¡Ået a provozovat existujÃ­cÃ­ kolekce bez nutnosti jejich Ãºpravy.
+SystÃ©m je naprogramovÃ¡n v jazyce Java a je strukturovÃ¡n jako sÃ­t nezÃ¡vislÃœch modulÅ¯
+komunikujÃ­cÃ­ch za pouÅŸitÃ­ XML: dÃ­ky tomu mÅ¯ÅŸe fungovat v distribuovanÃ© podobÄ a
+v pÅÃ­padÄ potÅeby mÅ¯ÅŸe bÃœt umÃ­stÄn na nÄkolika rÅ¯znÃœch serverech. Toto modulÃ¡rnÃ­
+pojetÃ­ zvÄtÅ¡uje pÅizpÅ¯sobivost a rozÅ¡iÅitelnost systÃ©mu Greenstone. NovÃ¡ verze
+by mÄla bÃœt pro experimentÃ¡lnÃ­ vyuÅŸitÃ­ k dipozici od 23. prosince 2003.
+ZÃ¡kladnÃ­ nÃ¡vrh systÃ©mu je nestÃ­nÄn v dokumentu "The design of Greenstone 3:
+An agent based dynamic digital library" (nahrÃ¡t  <a href="http://www.greenstone.org/manuals/gs3design.pdf">PDF</a>).}
+
+_textcreditstitle_ [l=cs] {o autorech}
+
+_textwhoswho_ [l=cs] {Greenstone je vÃœsledkem tÃœmovÃ© prÃ¡ce mnoha lidÃ­. HlavnÃ­mi architekty systÃ©mu jsou Rodger McNab a Stefan Boddie.
+DalÅ¡Ã­mi pÅispÄvatali byli David Bainbridge, George Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker,
+Carl Gutwin, Geoff Holmes, Dana McKay, John McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer,
+Todd Reed, Bill Rogers, John Thompson, and Stuart Yeates. OstatnÃ­ ÄlenovÃ© projektu poskytovali rady a inspiraci pro design systÃ©mu :
+Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols
+a Lloyd Smith. A chceme takÃ© upozornit na vÅ¡echny ty, kteÅÃ­ pÅispÄli do GNU programÅ¯ zahrnutÃœch v tÃ©to distribuci:
+MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE a XLHTML.}
+
+_textaboutgslong_ [l=cs] {o programu Greenstone}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=cs] {Skupina aktuÃ¡lnÃ­ch uÅŸivatelÅ¯}
+_textuser_ [l=cs] {uÅŸivatel
+}
+_textas_ [l=cs] {stav ÃºÄtu}
+_textgroups_ [l=cs] {skupiny}
+_textcomment_ [l=cs] {poznÃ¡mky}
+_textadduser_ [l=cs] {pÅidat novÃ©ho uÅŸivatele}
+_textedituser_ [l=cs] {editovat}
+_textdeleteuser_ [l=cs] {smazat}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=cs] {Editovat informace o uÅŸivateli}
+_textadduser_ [l=cs] {PÅidat novÃ©ho uÅŸivatele}
+
+_textaboutusername_ [l=cs] {UÅŸivatelskÃ© jmÃ©no musÃ­ mÃ­t dÃ©lku 2-30 znakÅ¯. MÅ¯ÅŸe obsahovat alfanumerickÃ© znaky, teÄku(.) a podtrÅŸÃ­tko ( _ ).}
+
+_textaboutpassword_ [l=cs] {Heslo musÃ­ mÃ­t dÃ©lku 3-128 znakÅ¯. MÅ¯ÅŸe obsahovat tisknutelnÃ© znaky ASCII.}
+
+_textoldpass_ [l=cs] {Pokud je toto pole prÃ¡zdnÃ©, bude zachovÃ¡no starÃ© heslo.}
+_textenabled_ [l=cs] {povoleno}
+_textdisabled_ [l=cs] {zakÃ¡zÃ¡no}
+
+_textaboutgroups_ [l=cs] {ÄlenovÃ© skupiny se oddÄlujÃ­ ÄÃ¡rkou, prosÃ­m nevklÃ¡dejte ÅŸÃ¡dnÃ© mezery.}
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=cs] {smazat uÅŸivatele}
+_textremwarn_ [l=cs] {SkuteÄnÄ chcete zcela odstranit uÅŸivatele <b>_cgiargumun_</b>?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=cs] {ZmÄnit heslo}
+_textoldpw_ [l=cs] {starÃ© heslo}
+_textnewpw_ [l=cs] {novÃ© heslo}
+_textretype_ [l=cs] {zadejte heslo jeÅ¡tÄ jednou}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=cs] {VaÅ¡e heslo bylo ÃºspÄÅ¡nÄ zmÄnÄno.}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=cs] {UÅŸivatelskÃ© jmÃ©no nenÃ­ platnÃ©.}
+_textinvalidpassword_ [l=cs] {Heslo nenÃ­ platnÃ©.}
+_textemptypassword_ [l=cs] {Zadejte prosÃ­m vÃœchozÃ­ heslo pro tohoto uÅŸivatele.}
+_textuserexists_ [l=cs] {Tento uÅŸivatel uÅŸ existuje, prosÃ­m zvolte jinÃ© jmÃ©no.}
+
+_textusernameempty_ [l=cs] {ProsÃ­m, vloÅŸte vaÅ¡e uÅŸivatelskÃ© jmÃ©ho.}
+_textpasswordempty_ [l=cs] {MusÃ­te zadat pÅ¯vodnÃ­ heslo.}
+_textnewpass1empty_ [l=cs] {Zadejte vaÅ¡e novÃ© heslo a potvrÄte jej jeÅ¡tÄ jednou.}
+_textnewpassmismatch_ [l=cs] {DvÄ verze vaÅ¡eho hesla se od sebe liÅ¡Ã­.}
+_textnewinvalidpassword_ [l=cs] {Zadali jste neplatnÃ© heslo.}
+_textfailed_ [l=cs] {UÅŸivatelskÃ© jmÃ©no nebo heslo nebylo sprÃ¡vnÃ©.}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=cs] {Verze Greenstone}
+_textframebrowser_ [l=cs] {VÃ¡Å¡ prohlÃ­ÅŸeÄ musÃ­ bÃœt schopen zobrazovat rÃ¡mce (frames).}
+_textusermanage_ [l=cs] {SprÃ¡va uÅŸivatelÅ¯}
+_textlistusers_ [l=cs] {seznam uÅŸivatelÅ¯}
+_textaddusers_ [l=cs] {pÅidat novÃ©ho uÅŸivatele}
+_textchangepasswd_ [l=cs] {zmÄnit heslo}
+_textinfo_ [l=cs] {TechnickÃ© informace}
+_textgeneral_ [l=cs] {vÅ¡eobecnÄ}
+_textarguments_ [l=cs] {argumenty}
+_textactions_ [l=cs] {akce}
+_textbrowsers_ [l=cs] {prohlÃ­ÅŸeÄ}
+_textprotocols_ [l=cs] {protokoly}
+_textconfigfiles_ [l=cs] {Soubory s konfiguracÃ­}
+_textlogs_ [l=cs] {Protokol o aktivitÃ¡ch}
+_textusagelog_ [l=cs] {protokol o pouÅŸitÃ­}
+_textinitlog_ [l=cs] {protokol o vstupech}
+_texterrorlog_ [l=cs] {soubor o chybÃ¡ch}
+_textadminhome_ [l=cs] {domov sprÃ¡vce}
+_textreturnhome_ [l=cs] {Greenstone home}
+_titlewelcome_ [l=cs] {Administrace}
+_textmaas_ [l=cs] {DostupnÃ© sluÅŸby pro administraci a ÃºdrÅŸbu zahrnujÃ­:}
+_textvol_ [l=cs] {zobrazit on-line pÅÃ­stupy}
+_textcmuc_ [l=cs] {vytvoÅit, udrÅŸovat a aktualizovat kolekce}
+_textati_ [l=cs] {pÅÃ­stup k technickÃœm informacÃ­, jako napÅ. CGI argumenty}
+
+_texttsaa_ [l=cs] {Tyto sluÅŸby se aktivujÃ­ pouÅŸitÃ­m krajnÃ­ navigaÄnÃ­ liÅ¡ty na levÃ© stranÄ obrazovky.}
+
+_textcolstat_ [l=cs] {Status kolekce}
+
+_textcwoa_ [l=cs] {Kolekce budou mÃ­t atribut "spuÅ¡tÄnÃ¡", pouze pokud jejich konfiguraÄnÃ­ soubory existujÃ­
+(build.cfg), jsou ÄitelnÃ©, obsahujÃ­ platnÃ¡ pole data vytvoÅenÃ­ (tj. > 0) a jsou v adresÃ¡Åi index
+(tzn. ne uvnitÅ adresÃ¡Åe building). }
+
+_textcafi_ [l=cs] {kliknÄte na <i>abbrev.</i> pro informace o danÃ© kolekci}
+_textcctv_ [l=cs] {kliknÄte na <i>kolekci<i> pro zobrazenÃ­}
+_textsubc_ [l=cs] {UloÅŸit zmÄny}
+_texteom_ [l=cs] {Chyba pÅi otevÃ­rÃ¡nÃ­ main.cfg}
+_textftum_ [l=cs] {ZmÄna main.cfg se nezdaÅila}
+_textmus_ [l=cs] {main.cfg ÃºspÄÅ¡nÄ aktualizovÃ¡n}
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=cs] {VytvoÅit souhrn o kolekci _collectionname_}
+_textflog_ [l=cs] {Soubor se zprÃ¡vou o ztracenÃœch souborech _collectionname_}
+
+
+############################################################################
+#
+# This stuff is only used by the usability (I'd like to Complain) stuff
+#
+############################################################################
+package Global
+
+_greenstoneusabilitytext_ [l=cs] {PouÅŸitelnost Greenstone}
+
+_textwhy_ [l=cs] {<p>
+TÃ­m, ÅŸe odeÅ¡lete tuto zprÃ¡vu, nÃ¡m dÃ¡te najevo, ÅŸe prohlÃ­ÅŸenÃ¡ strÃ¡nka byla sloÅŸitÃ¡ Äi odrazujÃ­cÃ­.}
+_textextraforform_ [l=cs] {NemusÃ­te vyplnit celÃœ formulÃ¡Å -- jakÃ©koliv informace pomohou.}
+_textprivacybasic_ [l=cs] {<p>
+ZprÃ¡va bude obsahovat pouze informace o webovÃ© strÃ¡nce, kterou jste prÃ¡vÄ vidÄli a informace o technice, kterou jste k jejÃ­mu zobrazenÃ­ pouÅŸÃ­vali (plus dodateÄnÃ© informace, kterÃ© nÃ¡m napÃ­Å¡ete).}
+_textstillsend_ [l=cs] {PÅejete si odeslat tuto zprÃ¡vu?}
+
+_texterror_ [l=cs] {chyba}
+_textyes_ [l=cs] {Ano}
+_textno_ [l=cs] {Ne}
+_textclosewindow_ [l=cs] {ZavÅÃ­t okno}
+_textabout_ [l=cs] {O}
+_textprivacy_ [l=cs] {SoukromÃ©}
+_textsend_ [l=cs] {Odeslat}
+_textdontsend_ [l=cs] {NeodesÃ­lat}
+_textoptionally_ [l=cs] {VolitelnÄ}
+
+_textunderdev_ [l=cs] {DetailnÃ­ pÅehled bude k dispozici ve finÃ¡lnÃ­ verzi.}
+
+_textviewdetails_ [l=cs] {UkÃ¡zat detailnÃ­ zprÃ¡vu}
+_textmoredetails_ [l=cs] {VÃ­ce podrobnostÃ­}
+_texttrackreport_ [l=cs] {Sledovat tuto zprÃ¡vu}
+_textcharacterise_ [l=cs] {Co to je za problÃ©m}
+_textseverity_ [l=cs] {Jak zÃ¡vaÅŸnÃœ je to problÃ©m}
+ 
+_textbadrender_ [l=cs] {StrÃ¡nka vypadÃ¡ divnÄ}
+_textcontenterror_ [l=cs] {Chyba obsahu}
+_textstrangebehaviour_ [l=cs] {PodivnÃ© chovÃ¡nÃ­}
+_textunexpected_ [l=cs] {Stalo se nÄco neoÄekÃ¡vanÃ©ho}
+_textfunctionality_ [l=cs] {ObtÃ­ÅŸnÃ© pouÅŸÃ­vÃ¡nÃ­}
+_textother_ [l=cs] {JinÃ©}
+
+_textcritical_ [l=cs] {KrickÃœ}
+_textmajor_ [l=cs] {ZÃ¡vaÅŸnÃœ}
+_textmedium_ [l=cs] {StÅednÃ­}
+_textminor_ [l=cs] {OkrajovÃœ}
+_texttrivial_ [l=cs] {NicotnÃœ}
+
+_textwhatdoing_ [l=cs] {Co jste chtÄli udÄlat?}
+_textwhatexpected_ [l=cs] {Co jste oÄekÃ¡vali?}
+_textwhathappened_ [l=cs] {Co se stalo?}
+
+_cannotfindcgierror_ [l=cs] {<h2>OmlouvÃ¡me se.</h2>Nelze najÃ­t pÅÃ­sluÅ¡nÃ© programy na serveru (pro sluÅŸbu "RÃ¡d bych poznamenal...").}
+
+_textusabbanner_ [l=cs] {koru-style baner pro Greenstone}
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+# -- Missing translation: _textgti_
+
+# -- Missing translation: _textgtierror_
+
+# -- Missing translation: _textgtihome_
+
+# -- Missing translation: _textgtiselecttlc_
+
+# -- Missing translation: _textgtiselecttfk_
+
+# -- Missing translation: _textgticoredm_
+# -- Missing translation: _textgtiauxdm_
+# -- Missing translation: _textgtiglidict_
+# -- Missing translation: _textgtiperlmodules_
+# -- Missing translation: _textgtigreenorg_
+
+# -- Missing translation: _textgtienter_
+
+# -- Missing translation: _textgticorrectexistingtranslations_
+# -- Missing translation: _textgtidownloadtargetfile_
+# -- Missing translation: _textgtiviewtargetfileinaction_
+
+# -- Missing translation: _textgtinumchunksmatchingquery_
+
+# -- Missing translation: _textgtinumchunkstranslated_
+# -- Missing translation: _textgtinumchunksrequiringupdating_
+# -- Missing translation: _textgtinumchunksrequiringtranslation_
+
+# -- Missing translation: _textgtienterquery_
+# -- Missing translation: _textgtifind_
+
+# -- Missing translation: _textgtitranslatingchunk_
+# -- Missing translation: _textgtiupdatingchunk_
+# -- Missing translation: _textgtisubmit_
+
+# -- Missing translation: _textgtilastupdated_
+
+# -- Missing translation: _textgtitranslationfilecomplete_
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=cs] {rohranÃ­ Greenstone Librarian}
+_textglihelp_ [l=cs] {RozhranÃ­ Librarian (zkracovÃ¡no jako GLI polde <i>Greenstone Librarian Interface</i>) poskytuje
+snadno pouÅŸitelnÃœ pÅÃ­stup k funkcÃ­m systÃ©mu Greenstone formou grafickÃ©ho uÅŸivatelskÃ©ho rozhranÃ­.
+To umoÅŸÅuje shormaÅŸÄovat skupiny dokumentÅ¯, importovat a pÅiÅazovat metadata a vytvÃ¡Ået kolekce
+digitÃ¡lnÃ­ knihovny Greenstone.
+<p>
+GLI pracuje ve spojenÃ­ s Greenstone a pÅedpoklÃ¡dÃ¡ se, ÅŸe je nainstalovÃ¡n v podadresÃ¡Åi
+instalace Greenstone. To platÃ­ pokud jste nahrÃ¡li jednu z distirbucÃ­ Greenstone z internetu nebo
+jste ji nainstalovali z CD-ROM.
+
+
+<h4>SpuÅ¡tÄnÃ­ GLI ve Windows</h4>
+
+Ve Windows spustÃ­te Librarian pÅes hlavnÃ­ menu (<i>Start</i>) a poloÅŸky
+ <i>Programy</i>, <i>Greenstone Digital Library</i> vÃœbÄrem <i>Greenstone Librarian Interface</i>.
+
+ 
+<h4>SpuÅ¡tÄnÃ­ GLI pod Unixem</h4>
+
+Pro spuÅ¡tÄnÃ­ GLI pod Unixem otevÅete podadresÃ¡Å <i>gli</i> adresÃ¡Åe instalace Greenstone 
+a spusÅ¥te skript <i>gli.sh</i>.}
+
Index: /gsdl/stable/macros/dari.dm
===================================================================
--- /gsdl/stable/macros/dari.dm	(revision 20131)
+++ /gsdl/stable/macros/dari.dm	(revision 20131)
@@ -0,0 +1,1375 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# English Language text and icon macros 
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=prs] {Ø³ÙØ³ÙÙ ÙØ§}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=prs] {Ù
+ÙØšØ¹ :}  
+_textdate_ [l=prs] {ØªØ§Ø±ÙØ® ÙØŽØ± :}  
+_textnumpages_ [l=prs] {ØªØ¹Ø¯Ø§Ø¯ ØµÙØ­Ø§Øª :}  
+
+_textsignin_ [l=prs] {ÙØ±ÙØ¯ }  
+
+_textdefaultcontent_ [l=prs] {ØµÙØ­Ù Ù
+ÙØ±Ø¯ Ø¯Ø±Ø®ÙØ§Ø³Øª ØŽÙ
+Ø§ ÙØ§ÙØª ÙØŽØ¯. ÙØ·ÙØ§ Ø§Ø² Ø¯ÙÙ
+Ù ØšØ§Ø²Ú¯ØŽØª ÙØ§ÙØŽÚ¯Ø± Ø®ÙØ¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ÙÙØ¯ ÙØ§ ØšØ± Ø±ÙÙ Ø¯ÙÙ
+Ù Ø®Ø§ÙÙ ØšØ±Ø§Ù ØšØ§Ø²Ú¯ØŽØª ØšÙ ÙØªØ§ØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ÙÙÙÙ ÙÙÙØ¯ .}  
+
+_textdefaulttitle_ [l=prs] {Ø®Ø·Ø§Ù GSDL}  
+
+_textbadcollection_ [l=prs] {Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù (ØšÙØ§Ù
+ "_cvariable_") Ø¯Ø± Ø³ÙØ³ØªÙ
+ ÙØªØ§ØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ÙØµØš ÙØŽØ¯Ù Ø§Ø³Øª.}  
+
+_textselectpage_ [l=prs] {ØµÙØ¬Ù Ø§ÙØªØ®Ø§Øš}  
+
+_collectionextra_ [l=prs] {Ø¯Ø± Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù ØªØ¹Ø¯Ø§Ø¯ _about:numdocs_  Ø³ÙØ¯ ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ .
+Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù _about:builddate_ Ø±ÙØ² ÙØšÙ Ø³Ø§Ø®ØªÙ ØŽØ¯Ù Ø§Ø³Øª .}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=prs] {<p>Ø¯Ø± Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù  _numdocs_ _If_("_numdocs_" eq "1",Ø³ÙØ¯,Ø³ÙØ¯), ØšÙ ØžØ±ÙÙØª  _numbytes_.
+<p><a href="_httppagex_(bsummary)">Ø§ÙÙØ¬Ø§ ÙÙÙÙ ÙÙÙØ¯</a>ØšØ±Ø§Ù Ø§ÙØ¬Ø§Ø¯ Ú¯Ø²Ø§Ø±ØŽ Ø®ÙØ§ØµÙ Ø§Ø·ÙØ§Ø¹Ø§Øª Ù
+Ø¬Ù
+ÙØ¹Ù.
+}  
+
+_textdescrcollection_ [l=prs] {}  
+_textdescrabout_ [l=prs] {Ø¯Ø±ØšØ§Ø±Ù ØµÙØ­Ù}  
+_textdescrhome_ [l=prs] {Ø®Ø§ÙÙ}  
+_textdescrhelp_ [l=prs] {ØµÙØ­Ù Ø±Ø§ÙÙÙ
+Ø§ÛÛ}  
+_textdescrpref_ [l=prs] {ØµÙØ­Ù ØªÙØžÙÙ
+Ø§Øª}  
+_textdescrgreenstone_ [l=prs] {ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± ÙØªØ§ØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}  
+_textdescrusab_ [l=prs] {Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² ÙØ¯Ø§Ù
+ Ù
+ÙØ±Ø¯ Ø±Ø§ Ø¯ØŽÙØ§Ø± ÙØ§ÙØªÙØ¯ Ø}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=prs] {Ø¬Ø³ØªØ¬Ù}  
+_labelSearch_ [l=prs] {Ø¬Ø³ØªØ¬Ù}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=prs] {Ø¹ÙÙØ§Ù}  
+_labelTitle_ [l=prs] {Ø¹ÙÙØ§Ù Ø§-Ù}  
+
+_labelCreator_ [l=prs] {ÙÙÙØ³ÙØ¯Ú¯Ø§Ù Ø§-Ù}  
+_textSubject_ [l=prs] {Ù
+Ø¶Ù
+ÙÙ}  
+_labelSubject_ [l=prs] {Ù
+ÙØ¶ÙØ¹Ø§Øª}  
+_textDescription_ [l=prs] {ØŽØ±Ø­}  
+_labelDescription_ [l=prs] {ØªØŽØ±ÛØ­Ø§Øª}  
+_textPublisher_ [l=prs] {ÙØ§ØŽØ±}  
+_labelPublisher_ [l=prs] {ÙØ§ØŽØ±ÛÙ}  
+_textContributor_ [l=prs] {ÙÙ
+Ú©Ø§Ø±}  
+_labelContributor_ [l=prs] {ÙÙ
+Ú©Ø§Ø±Ø§Ù}  
+_textDate_ [l=prs] {ØªØ§Ø±ÛØ®}  
+_labelDate_ [l=prs] {ØªØ§Ø±ÙØ® ÙØ§}  
+
+_labelType_ [l=prs] {Ø§ÙÙØ§Ø¹}  
+_textFormat_ [l=prs] {Ø³Ø§Ø®ØªØ§Ø±}  
+
+_textIdentifier_ [l=prs] {Ù
+Ø¹Ø±ÙÛ Ú©ÙÙØ¯Ù}  
+_labelIdentifier_ [l=prs] {Ù
+Ø¹Ø±ÙÛ Ú©ÙÙØ¯Ù}  
+_textSource_ [l=prs] {ÙØ§Ù
+ Ø¯ÙØ³ÛÙ}  
+_labelSource_ [l=prs] {ÙØ§Ù
+ Ø¯ÙØ³ÛÙ ÙØ§}  
+_textLanguage_ [l=prs] {Ø²ØšØ§Ù}  
+_labelLanguage_ [l=prs] {Ø²ØšØ§ÙÙØ§}  
+_textRelation_ [l=prs] {Ø§Ø±ØªØšØ§Ø·}  
+_labelRelation_ [l=prs] {Ø§Ø±ØªØšØ§Ø·Ø§Øª}  
+_textCoverage_ [l=prs] {Ø§Ø­ØªÙØ§}  
+
+_textRights_ [l=prs] {Ø­ÙÙÙ}  
+_labelRights_ [l=prs] {Ø­ÙÙÙ}  
+
+# DLS metadata set
+_textOrganization_ [l=prs] {Ø³Ø§Ø²Ù
+Ø§Ù}  
+_labelOrganization_ [l=prs] {Ø³Ø§Ø²Ù
+Ø§ÙÙØ§}  
+_textKeyword_ [l=prs] {Ú©ÙÛØ¯ Ø­Ø±ÙÙ}  
+_labelKeyword_ [l=prs] {ÙÙÙ
+Ø§Øª ÙÙÙØ¯Ù}  
+_textHowto_ [l=prs] {ÚÙ Ø·ÙØ±Û}  
+_labelHowto_ [l=prs] {ÚÚ¯ÙÙÙ}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=prs] {Ø¹ØšØ§Ø±Øª}  
+_labelPhrase_ [l=prs] {Ø¹ØšØ§Ø±Ø§Øª ÙØ§Ù
+Ú©Ù
+Ù}  
+
+
+_textBrowse_ [l=prs] {Ù
+Ø±ÙØ±}  
+
+_textTo_ [l=prs] {ØšÙ}  
+_labelTo_ [l=prs] {ØªØ§}  
+_textFrom_ [l=prs] {Ø§Ø²}  
+_labelFrom_ [l=prs] {Ø§Ø²}  
+_textAcronym_ [l=prs] {Ù
+Ø®ÙÙ}  
+_labelAcronym_ [l=prs] {Ù
+Ø®ÙÙØ§Øª}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=prs] {Ù
+Ø±ÙØ± ØªÙØ³Ø· _1_}  
+
+_textdescrSearch_ [l=prs] {Ø¬Ø³ØªØ¬Ù ØšØ±Ø§Ù Ø¹ØšØ§Ø±Ø§Øª Ø®Ø§Øµ}  
+_textdescrType_ [l=prs] {Ù
+Ø±ÙØ± ØšÙ ÙÙØ¹ Ù
+ÙØšØ¹}  
+_textdescrIdentifier_ [l=prs] {Ù
+Ø±ÙØ± ØšØ§ Ù
+ÙØšØ¹ Ù
+Ø¹Ø±ÙÛ Ú©ÙÙØ¯Ù}  
+_textdescrSource_ [l=prs] {Ù
+Ø±ÙØ± ØšØ± Ø§Ø³Ø§Ø³ ÙØ§Ù
+ Ø§ØµÙÙ ÙŸØ±ÙÙØ¯Ù}  
+_textdescrTo_ [l=prs] {Ù
+Ø±ÙØ± ØšØ± Ø­Ø³Øš ÙØšÙØ¯ ØªØ§}  
+_textdescrFrom_ [l=prs] {Ù
+Ø±ÙØ± ØšØ± Ø­Ø³Øš Ø±ØŽØªÙ Ø§Ø²}  
+
+_textdescrAcronym_ [l=prs] {Ù
+Ø±ÙØ± Ù
+ØªØ¶Ø§Ø¯ÙØ§}  
+_textdescrPhrase_ [l=prs] {Ù
+Ø±ÙØ± Ø¹ØšØ§Ø±Ø§Øª}  
+_textdescrHowto_ [l=prs] {Ù
+Ø±ÙØ± Ø¯Ø³ØªÙ ÙØ§Ù ÚÚ¯ÙÙÚ¯Ù Ø§ÙØ¬Ø§Ù
+ ÙØ§Ø±ÙØ§}  
+_textdescrBrowse_ [l=prs] {Ù
+Ø±ÙØ± Ø§Ø³ÙØ§Ø¯}  
+_texticontext_ [l=prs] {Ø±ÙÙØª Ø³ÙØ¯}  
+_texticonclosedbook_ [l=prs] {ØšØ§Ø²ÙØ±Ø¯Ù Ø³ÙØ¯ Ù Ø±ÙÙØª Ù
+Ø­ØªÙÙØ§Øª Ø¢Ù}  
+_texticonnext_ [l=prs] {ØšØ®ØŽ ØšØ¹Ø¯Ù}  
+_texticonprev_ [l=prs] {ØšØ®ØŽ ÙØšÙÙ}  
+
+_texticonworld_ [l=prs] {Ø±ÙÛØª Ø³ÙØ¯ ÙØš}  
+
+_texticonmidi_ [l=prs] {Ø±ÙÙØª Ø³ÙØ¯ MIDI}  
+_texticonmsword_ [l=prs] {Ø±ÙÛØª Ø³ÙØ¯Microsoft Word}  
+_texticonmp3_ [l=prs] {Ø±ÙÙØª Ø³ÙØ¯ MP3}  
+_texticonpdf_ [l=prs] {Ø±ÙÙØª Ø³ÙØ¯ PDF}  
+_texticonps_ [l=prs] {Ø±ÙÙØª Ø³ÙØ¯ ÙŸØ³Øª Ø§Ø³ÙØ±ÙÙŸØª}  
+_texticonppt_ [l=prs] {Ø±ÙÙØª Ø³ÙØ¯ PowerPoint}  
+_texticonrtf_ [l=prs] {Ø±ÙÙØª Ø³ÙØ¯ RTF}  
+_texticonxls_ [l=prs] {Ø±ÙÙØª Ø³ÙØ¯ Ù
+Ø§ÙÙØ±ÙØ³Ø§ÙØª Ø§ÙØ³Ù}  
+
+_page_ [l=prs] {ØµÙØ­Ù}  
+_pages_ [l=prs] {ØµÙØ­Ø§Øª}  
+_of_ [l=prs] {Ø§Ø²}  
+_vol_ [l=prs] {Ø¬ÙØ¯ }  
+_num_ [l=prs] {ØŽÙ
+Ø§Ø±Ù }  
+
+_textmonth00_ [l=prs] {}  
+_textmonth01_ [l=prs] {Ø¬ÙÙØ±Û}  
+_textmonth02_ [l=prs] {ÙÙØ±ÙÙ}  
+_textmonth03_ [l=prs] {Ù
+Ø§Ø±Ú}  
+_textmonth04_ [l=prs] {Ø§ÙŸØ±ÛÙ}  
+_textmonth05_ [l=prs] {Ù
+Ù}  
+_textmonth06_ [l=prs] {Ø¬ÙÙ}  
+_textmonth07_ [l=prs] {Ø¬ÙÙØ§Ù}  
+_textmonth08_ [l=prs] {Ø§Ú¯Ø³Øª}  
+_textmonth09_ [l=prs] {Ø³ÙŸØªØ§Ù
+ØšØ±}  
+_textmonth10_ [l=prs] {Ø§Ú©ØªÙØšØ±}  
+_textmonth11_ [l=prs] {ÙÙÙ
+ØšØ±}  
+_textmonth12_ [l=prs] {Ø¯Ø³Ø§Ù
+ØšØ±}  
+
+_textdocument_ [l=prs] {Ø³ÙØ¯}  
+_textsection_ [l=prs] {ØšØ®ØŽ}  
+_textparagraph_ [l=prs] {ÙŸØ§Ø±Ø§Ú¯Ø±Ø§Ù}  
+
+_magazines_ [l=prs] {Ù
+Ø¬ÙØ§Øª}  
+
+
+
+_linktextHOME_ [l=prs] {Ø®Ø§ÙÙ}  
+_linktextHELP_ [l=prs] {Ø±Ø§ÙÙÙ
+Ø§ÙÙ}  
+_linktextPREFERENCES_ [l=prs] {ØªØ±Ø¬ÛØ­Ø§Øª}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=prs] {Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÛØ¬ÛØªØ§Ù Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ}  
+
+_textnocollections_ [l=prs] {ØºÛØ± ÙØ§ØšÙ ÙŸØ²ÛØ±ØŽ(i.e. built and public)Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ Ù
+ÙØ¬ÙØ¯ Ø§Ø³Øª.}  
+
+
+_textabgs_ [l=prs] {Ø¯Ø± ØšØ§Ø±Ù Ú¯Ø±ÛÙ Ø³ØªÙÙ}  
+
+
+_textdescradmin_ [l=prs] {Ø§ÛÙ ÙØ³Ù
+Øª Ø§Ø·ÙØ§Ø¹Ø§Øª ÙÙÛ Ø¯Ø±ØšØ§Ø±Ù ÙØµØš Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ù
+Û Ø¯ÙØ¯ Ù ØšÙ ØŽÙ
+Ø§ Ø§Ø¬Ø§Ø²Ù Ù
+Û Ø¯ÙØ¯ ØªØ§ Ú©Ø§Ø±ØšØ±Ø§Ù Ø¬Ø¯ÛØ¯ Ø§ÛØ¬Ø§Ø¯ ÙÙ
+Ø§ÛÛØ¯ Ù Ø§Ø·ÙØ§Ø¹Ø§Øª Ù
+Ø®ØªØµØ±Û Ø¯Ø±ØšØ§Ø±Ù Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û Ø³ÛØ³ØªÙ
+ ÙØŽØ§Ù Ù
+Û Ø¯ÙØ¯ }  
+
+_textdescrgogreenstone_ [l=prs] {ØªÙØ¶ÛØ­Ø§ØªÛ ØšØ±Ø§Û ØŽÙ
+Ø§ Ø¯Ø±ØšØ§Ø±Ù ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ù ÙŸØ±ÙÚÙ Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÛØ¬ÛØªØ§Ù Ø²ÛÙØ§ÙØ¯ Ø¬Ø¯ÛØ¯ Ø¬Ø§ÛÛ Ú©Ù Ø§ÛÙ ÙŸØ±ÙÚÙ ÙØŽØ§Øª Ú¯Ø±ÙØªÙ Ø§Ø³Øª }  
+
+
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=prs] {Ø±Ø§ØšØ· Ú©ØªØ§ØšØ¯Ø§Ø±}  
+_textdescrgli_ [l=prs] {ØšØ§ ØŽÙ
+Ø§ ÙÙ
+Ú©Ø§Ø±Û Ù
+ÛÙÙ
+Ø§ÛØ¯ ØªØ§ Ù
+Ø¬Ù
+ÙØ¹ÙØ§ Ø¬Ø¯ÛØ¯ Ø±Ø§ Ø§ÛØ¬Ø§Ø¯ ÙÙ
+Ø§ØŠÛØ¯Ø Ø¯Û Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+ÙØ¬ÙØ¯ ØªØºÛØ± ÙØ§Ø¶Ø§ÙÙ Ú©Ø§Ø±Û Ù
+ÛØªÙØ§ÙÛØ¯Ø ÙÛØ§ Ù
+Ø¬Ù
+ÙØ¹Ù Ø±Ø§ ÙŸØ§Ú© Ú©Ø±Ø¯Ù Ù
+ÛØªÙØ§ÙÛØ¯.}  
+
+package collector
+
+_textcollector_ [l=prs] {Ø¬Ù
+Ø¹ Ø¢ÙØ±Û Ú©ÙÙØ¯Ù}  
+
+
+package depositor
+
+_textdepositor_ [l=prs] {Ø°Ø®ÛØ±Ù Ú©ÙÙØ¯Ù}  
+_textdescrdepositor_ [l=prs] {ØšØ§ ØŽÙ
+Ø§ ÙÙ
+Ú©Ø§Ø±Û Ù
+ÛÚ©ÙØ¯ ØªØ§ Ø§Ø³ÙØ§Ø¯ Ø±Ø§ØšØ§ Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+ÙØ¬ÙØ¯ Ø§Ø¶Ø§ÙÙ Ú©ÙÛØ¯}  
+
+package gti
+
+_textgti_ [l=prs] {Ø±Ø§ØšØ· Ù
+ØªØ±Ø¬Ù
+ Ú¯Ø±ÛÙ Ø³ØªÙÙ}  
+_textdescrtranslator_ [l=prs] {ØšÙ ØŽÙ
+Ø§ Ú©Ù
+Ú© Ù
+Û Ú©ÙØ¯ ØªØ§ ÙØ³Ø® ÚÙØ¯Ø²ØšØ§ÙÙ Ø±Ø§ØšØ· Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ø±Ø§ ØšÙ Ø±ÙØ² ÙÚ¯Ù Ø¯Ø§Ø±ÛØ¯}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=prs] {Ø¯Ø±ØšØ§Ø±Ù Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù}  
+
+_textsubcols1_ [l=prs] {<p>ÙÙ Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù ØŽØ§Ù
+Ù _1_ Ø²ÙØ±Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+Ù ØšØ§ØŽØ¯. 
+Ø¢ÙÙØ§ÙÙ ÙÙ ÙØ§ØšÙ Ø¯Ø³ØªØ±Ø³Ù ÙØ³ØªÙØ¯ Ø¹ØšØ§Ø±ØªÙØ¯ Ø§Ø²::
+<blockquote>}  
+
+_textsubcols2_ [l=prs] {</blockquote>
+ØŽÙ
+Ø§ Ø§Ø² Ø·Ø±ÙÙ ØµÙØ­Ù ØªØ±Ø¬ÛØ­Ø§Øª Ù
+Ù ØªÙØ§ÙÙØ¯ Ø²ÙØ±Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Ù Ù
+ÙØ±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù Ø®ÙØ¯ Ø±Ø§ ØšØšÙÙÙØ¯ ÙØ§ ØªØºÙÙØ± Ø¯ÙÙØ¯.}  
+
+_titleabout_ [l=prs] {Ø¯Ø±ØšØ§Ø±Ù}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=prs] {ØšØ³ØªÙ Ø§ÙÙ ØšØ®ØŽ ÙØªØ§ØšØ®Ø§ÙÙ}  
+_texticonclosedbookshelf_ [l=prs] {ØšØ§Ø²ÙØ±Ø¯Ù Ø§ÙÙ ØšØ®ØŽ Ø§Ø² ÙØªØ§ØšØ®Ø§ÙÙ Ù Ø±ÙÙØª Ù
+Ø­ØªÙÙØ§Øª}  
+_texticonopenbook_ [l=prs] {ØšØ³ØªÙ ÙØªØ§Øš}  
+_texticonclosedfolder_ [l=prs] {Ø§ÛÙ Ø¯ÙØ³ÛÙ Ø±Ø§ ØšØ§Ø² ÙÙ
+ÙØ¯Ù ÙÙ
+Ø­ØªÙÛØ§Øª Ø§ÙØ±Ø§ÙØŽØ§Ù Ø¯ÙÛØ¯}  
+_texticonclosedfolder2_ [l=prs] {ØšØ§Ø²ÙÙ
+ÙØ¯Ù Ø²ÛØ±ØšØ®ØŽ:}  
+_texticonopenfolder_ [l=prs] {ØšØ³ØªÙ ÙŸÙØŽÙ}  
+_texticonopenfolder2_ [l=prs] {ØšØ³ØªÙ Ø²ÛØ±ØšØ®ØŽ:}  
+_texticonsmalltext_ [l=prs] {Ø±ÙÙØª Ø§ÙÙ ØšØ®ØŽ Ø§Ø² Ù
+ØªÙ }  
+_texticonsmalltext2_ [l=prs] {Ø±ÙÙØª Ù
+ØªÙ :}  
+_texticonpointer_ [l=prs] {ØšØ®ØŽ ÙØ¹ÙÙ}  
+_texticondetach_ [l=prs] {ØšØ§Ø² Ú©Ø±Ø¯Ù ØµÙØ­Ù Ø¯Ø± Ú©ÙÛÚ©ÛÙ Ø¬Ø¯ÛØ¯}  
+_texticonhighlight_ [l=prs] {ØšØ±Ø¬Ø³ØªÙ ÙØ±Ø¯Ù Ø¹ØšØ§Ø±Ø§Øª Ø¬Ø³ØªØ¬ÙØŽØ¯Ù}  
+_texticonnohighlight_ [l=prs] {Ø¹ØšØ§Ø±Ø§Øª Ø¬Ø³ØªØ¬Ù ØšØ±Ø¬Ø³ØªÙ ÙØŽÙØ¯}  
+_texticoncontracttoc_ [l=prs] {Ø¬Ù
+Ø¹ ÙØ±Ø¯Ù ÙÙØ±Ø³Øª Ù
+Ø­ØªÙÙØ§Øª}  
+_texticonexpandtoc_ [l=prs] {ØšØ§Ø²ÙØ±Ø¯Ù ÙÙØ±Ø³Øª Ù
+Ø­ØªÙÙØ§Øª}  
+_texticonexpandtext_ [l=prs] {ÙÙ
+Ø§ÙØŽ ÙÙ
+Ù Ù
+ØªÙ}  
+_texticoncontracttext_ [l=prs] {ØšØ±Ø§Ù ØšØ®ØŽ Ø§ÙØªØ®Ø§Ù ÙÙØ· Ù
+ØªÙ ÙÙ
+Ø§ÙØŽ Ø¯Ø§Ø¯Ù ØŽÙØ¯}  
+_texticonwarning_ [l=prs] {<b>Ø§Ø®Ø·Ø§Ø±: </b>}  
+_texticoncont_ [l=prs] {Ø§Ø¯Ø§Ù
+Ù Ø}  
+
+_textltwarning_ [l=prs] {<div class="buttons">_imagecont_</div>
+_iconwarning_Ø§ÙÙ Ù
+ØªÙ Ø­Ø§ÙÙ Ø§Ø·ÙØ§Ø¹Ø§Øª ØšØ³ÙØ§Ø±Ù Ø²ÙØ§Ø¯Ù ØšØ±Ø§Ù Ù
+Ø±ÙØ±Ú¯Ø± ØŽÙ
+Ø§ Ø§Ø³Øª
+}  
+
+_textgoto_ [l=prs] {ØšØ±Ù ØšÙ ØµÙØ­Ù}  
+_textintro_ [l=prs] {<i>(Ù
+ØªÙ Ù
+Ø¹Ø±ÙÛ)</i>}  
+
+_textCONTINUE_ [l=prs] {Ø§Ø¯Ø§Ù
+Ù}  
+
+_textEXPANDTEXT_ [l=prs] {ØšØ§Ø²ÙØ±Ø¯Ù Ù
+ØªÙ}  
+
+_textCONTRACTCONTENTS_ [l=prs] {Ø¬Ù
+Ø¹ ÙØ±Ø¯Ù\nÙ
+Ø­ØªÙÙØ§Øª}  
+
+_textDETACH_ [l=prs] {Ø¬Ø¯Ø§Ø³Ø§Ø²Ù}  
+
+_textEXPANDCONTENTS_ [l=prs] {ÙØ³Ø¹Øª Ø¯Ø§Ø¯Ù ØšÙ Ù
+Ø­ØªÙÛØ§Øª}  
+
+_textCONTRACT_ [l=prs] {Ø¬Ù
+Ø¹\nÙØ±Ø¯Ù Ù
+ØªÙ}  
+
+_textHIGHLIGHT_ [l=prs] {ØšØ±Ø¬Ø³ØªÙ ÙÙ
+ÙØ¯Ù}  
+
+_textNOHIGHLIGHT_ [l=prs] {ØšØ¯ÙÙ ØšØ±Ø¬Ø³ØªÙ ÙÙ
+Ø§ÙÙ}  
+
+
+
+_textnextsearchresult_ [l=prs] {ÙØªÛØ¬Ù Ø¬Ø³ØªØ¬ÙÛ Ø¢ØªÛ}  
+_textprevsearchresult_ [l=prs] {ÙØªØ§ÛØ¬ Ø¬Ø³ØªØ¬ÙÛ ÙØšÙÛ}  
+
+# macros for printing page
+_textreturnoriginal_ [l=prs] {ØšØ§Ø²Ú¯ØŽØª ØšÙ ØµÙØ­Ù Ø§ØµÙÛ}  
+_textprintpage_ [l=prs] {ÚØ§ÙŸ Ø§ÛÙ ØµÙØ­Ù}  
+_textshowcontents_ [l=prs] {ÙÙ
+Ø§ÛØŽ Ø¬Ø¯ÙÙ Ù
+Ø­ØªÙÛØ§Øª}  
+_texthidecontents_ [l=prs] {Ø¹Ø¯Ù
+ ÙÙ
+Ø§ÛØŽ Ø¬Ø¯ÙÙ Ù
+Ø­ØªÙÛØ§Øª}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=prs] {_If_(_thislast_,results _thisfirst_ - _thislast_ for query: _cgiargq_,ØªØ·Ø§ØšÙÛ ÛØ§ÙØª ÙØŽØ¯: _cgiargq_)}  
+_textnoquerytitle_ [l=prs] {ØµÙØ¬Ù Ø¬Ø³ØªØ¬Ù}  
+
+_textsome_ [l=prs] {ØšØ¹Ø¶Ù}  
+_textall_ [l=prs] {ÙÙ
+Ù}  
+_textboolean_ [l=prs] {Ù
+ÙØ·ÙÛ}  
+_textranked_ [l=prs] {Ø¯Ø±Ø¬Ù ØšÙØ¯Û ØŽØ¯Ù
+}  
+_textnatural_ [l=prs] {Ø·ØšÛØ¹Û}  
+
+_texticonsearchhistorybar_ [l=prs] {Ø¬Ø³ØªØ¬Ù ØªØ§Ø±ÛØ®}  
+
+_textifeellucky_ [l=prs] {Ù
+Ù Ø®ÙØ¯ Ø±Ø§ Ø®ÙØŽ ØšØ®Øª Ø§Ø­Ø³Ø§ Ù
+ÛÚ©ÙÙ
+!}  
+
+#alt text for query buttons
+_textusequery_ [l=prs] {Ø§Ø² Ø§ÙÙ ÙŸØ±Ø³ Ù Ø¬Ù Ø§Ø³ØªÙØ§Ø¯Ù ÙÙÙØ¯}  
+_textfreqmsg1_ [l=prs] {ØªØ¹Ø¯Ø§Ø¯ Ú©ÙÙ
+Ù :}  
+_textpostprocess_ [l=prs] {_If_(_quotedquery_,<br><i>ÙŸØ±ÙØ³Ø³ ØŽØ¯Ù ØšØ±Ø§Û ÛØ§ÙØªÙ _quotedquery_</i>
+)}  
+_textinvalidquery_ [l=prs] {Ø¯Ø³ØªÙØ± ÙŸØ±Ø³ Ù Ø¬ÙÛ Ø§ØŽØªØšØ§Ù}  
+_textstopwordsmsg_ [l=prs] {Ú©ÙÛÙ
+Ø§Øª Ø°ÛÙ ØšØ³ÛØ§Ø¯ Ø¹Ø§Ù
+ ÙØ§Ø² ÙØžØ± Ø§ÙØ¯Ø§Ø®ØªÙ ØŽØ¯Ù:}  
+_textlucenetoomanyclauses_ [l=prs] {ÙŸØ±Ø³ ÙØ¬Ù ØŽÙ
+Ø§ Ø§ØµØ·ÙØ§Ø­Ø§Øª Ø²ÛØ§Ø¯Û Ø¯Ø§Ø±Ø¯ ÙØ·Ù ÙÙ
+ÙØ¯Ù ÙŸØ±Ø³ØŽ ØªØ§Ù Ø§Ø®ØªØµØ§ØµÛ ØªØ± ØšØ³Ø§Ø²ÛØ¯.}  
+
+_textmorethan_ [l=prs] {ØšÛØŽØªØ± Ø§Ø²}  
+_textapprox_ [l=prs] {Ø¯Ø±ØšØ§Ø±Ù }  
+_textnodocs_ [l=prs] {Ø³ÙØ¯Û Ù
+Ø·Ø§ØšÙ Ø¬Ø³ØªØ¬Ù ÛØ§ÙØª ÙØŽØ¯ .}  
+_text1doc_ [l=prs] {1Ø³ÙØ¯ ØšØ§ ÙŸØ±Ø³ ÙØ¬Ù Ù
+Ø·Ø§ØšÙØª Ø¯Ø§Ø±Ø¯.}  
+_textlotsdocs_ [l=prs] {Ø§Ø³ÙØ§Ø¯Û Ú©Ù ØšØ§ ÙŸØ±Ø³ Ù Ø¬Ù ØªØ·ØšÛÙ Ú©Ø±Ø¯Ù Ø§ÙØ¯ .}  
+_textmatches_ [l=prs] {ØªØ·ØšÛÙ Ù
+Û Ú©ÙØ¯}  
+_textbeginsearch_ [l=prs] {Ø¢ØºØ§Ø² Ø¬Ø³ØªØ¬Ù}  
+_textrunquery_ [l=prs] {Ø§Ø¬Ø±Ø§Û ÙŸØ±Ø³ Ù Ø¬Ù}  
+_textclearform_ [l=prs] {ÙŸØ§Ú© Ú©Ø±Ø¯Ù ÙØ±Ù
+}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=prs] {ÙÙÙ
+Ù ÙØ§ Ø¹ØšØ§Ø±Øª}  
+_textinfield_ [l=prs] {... Ø¯Ø± ÙÛÙØ¯ }  
+
+
+_textadvquery_ [l=prs] {ÛØ§ Ù
+Ø³ØªÙÛÙ
+Ø§ ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ :}  
+_textallfields_ [l=prs] {ÙÙ
+Ù Ø±ØŽØªÙ ÙØ§}  
+_texttextonly_ [l=prs] {ÙÙØ· Ù
+ØªÙÙ}  
+_textand_ [l=prs] {Ù}  
+_textor_ [l=prs] {ÛØ§}  
+_textandnot_ [l=prs] {Ù ÙÙ }  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=prs] {Ø¬Ø³ØªØ¬Ù ØšØ±Ø§Û Ù
+ÙØ§Ø±Ø¯Û _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_, at _gselection_ level )_If_(_nselection_,in _nselection_ language ) Ú©Ù ØŽØ§Ù
+Ù _querytypeselection_ ØšØ§ØŽØ¯}  
+
+_textadvancedsearch_ [l=prs] {Ø¬Ø³ØªØ¬Ù _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,Ø¯Ø± Ø²ØšØ§Ù _nselection_ )ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² ÙŸØ±Ø³ Ù Ø¬ÙÛ _querytypeselection_ }  
+
+_textadvancedmgppsearch_ [l=prs] {Ø¬Ø³ØªØ¬ÙÛ _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language ) Ù ÙÙ
+Ø§ÛØŽ ÙØªØ§ÛØ¬ ØšØ± Ø­Ø³Øš _formquerytypeadvancedselection_ }  
+
+
+
+_textformsimplesearch_ [l=prs] {Ø¬Ø³ØªØ¬ÙÛ _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,Ø¯Ø± Ø²ØšØ§Ù _nselection_  )ØšØ±Ø§Û _formquerytypesimpleselection_ of}  
+
+_textformadvancedsearchmgpp_ [l=prs] {Ø¬Ø³ØªØ¬ÙÛ _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )Ù ÙÙ
+Ø§ÛØŽ ÙØªØ§ÛØ¬ ØšØ± Ø­Ø³Øš  _formquerytypeadvancedselection_ }  
+
+_textformadvancedsearchlucene_ [l=prs] {Ø¬Ø³ØªØ¬ÙÛ _If_(_jselection_, _jselection_)_If_(_gformselection_,  Ø¯Ø± _gformselection_ level)_If_(_nselection_, Ø¯Ø± Ø²ØšØ§Ù _nselection_ language)_If_(_sfselection_,\,  ØšÙ ØªØ±ØªÛØš _sfselection_\,)  ØšØ±Ø§Û }  
+
+_textnojsformwarning_ [l=prs] {ØªØ°Ú¯Ø± : Ø¬Ø§ÙØ§ Ø§Ø³Ú©Ø±ÛÙŸØª Ø¯Ø± Ù
+Ø±ÙØ±Ú¯Ø± ØŽÙ
+Ø§ ØºÛØ± ÙØ¹Ø§Ù ØŽØ¯Ù Ø§Ø³Øª  <br>ØšØ±Ø§Û Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ø¬Ø³ØªØ¬Ù Ø¢Ù Ø±Ø§ ÙØ¹Ø§Ù ÙÙ
+Ø§ÛÛØ¯.}  
+_textdatesearch_ [l=prs] {Ø¯Ø± Ø§ÛÙ Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+Û ØªÙØ§Ù Ø¯Ø± ØšØ§Ø²Ù Ø²Ù
+Ø§ÙÛ ÛØ§ Ø§Ø³ÙØ§Ø¯Û Ú©Ù ØªØ§Ø±ÛØ® Ø®Ø§ØµÛ Ø¯Ø± Ø¢ÙÙØ§ ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ Ø¬Ø³ØªØ¬Ù Ú©Ø±Ø¯ . Ø§ÛÙ ÙÛÚÚ¯Û Ø§Ø®ØªÛØ§Ø±Û Ø¬Ø³ØªØ¬Ù Ù
+Û ØšØ§ØŽØ¯ .}  
+_textstartdate_ [l=prs] {ØªØ§Ø±ÙØ® ØŽØ±ÙØ¹(ÙØ§ ÙÙØ·)}  
+_textenddate_ [l=prs] {ØªØ§Ø±ÛØ® ÙŸØ§ÛØ§Ù :}  
+_textbc_ [l=prs] {B.C.E.}  
+_textad_ [l=prs] {C.E.}  
+_textexplaineras_ [l=prs] {C.E. Ù B.C.E.  ØšÙ ØªØ±ØªÛØš Ø¬Ø§ÛÚ¯Ø²ÛÙ A.D. Ù B.C. Ù
+Û ØšØ§ØŽÙØ¯ . Ø§ÛÙ Ø¹ØšØ§Ø±Ø§Øª ÙØ§Ø±Øº Ø§Ø² ØªÙØ§ÙØªÙØ§Û ÙØ±ÙÙÚ¯Û Ø Ù
+Ø®ÙÙ Common Era Ù Before Common era Ù
+Û ØšØ§ØŽÙØ¯ .}  
+
+_textstemon_ [l=prs] {(ÚØŽÙ
+ ÙŸÙØŽÙ Ø§Ø² Ø§ÙØªÙØ§Ù ÙØºØ§Øª)}  
+
+_textsearchhistory_ [l=prs] {Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù}  
+
+#text macros for search history
+_textnohistory_ [l=prs] {Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù Ù
+ÙØ¬ÙØ¯ ÙÛØ³Øª}  
+_texthresult_ [l=prs] {ÙØªÛØ¬Ù}  
+_texthresults_ [l=prs] {ÙØªØ§ÛØ¬}  
+_texthallwords_ [l=prs] {ØªÙ
+Ø§Ù
+ Ú©ÙÙ
+Ø§Øª}  
+_texthsomewords_ [l=prs] {ØšØ¹Ø¶Û Ú©ÙÙ
+Ø§Øª}  
+_texthboolean_ [l=prs] {Ù
+ÙØ·ÙÛ}  
+_texthranked_ [l=prs] {ØµÙ ØšÙØ¯Û ØŽØ¯Ù}  
+_texthcaseon_ [l=prs] {Ù
+ÙØ±Ø¯ ØšØ§ÛØ¯ ØªØ·ØšÛÙ Ú©ÙØ¯}  
+
+_texthstemon_ [l=prs] {Ù
+ØŽØªÙ ØŽØ¯Ù }  
+_texthstemoff_ [l=prs] {ØºÛØ± Ù
+ØŽØªÙ}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=prs] {ØªØ±Ø¬ÛØ­Ø§Øª Ø°Ø®ÛØ±Ù ØŽØ¯Ù Ø§ÙØ¯ . Ø§Ø² Ø¯Ú©Ù
+Ù ØšØ§Ø²Ú¯ØŽØª Ù
+Ø±ÙØ±Ú¯Ø± Ø®ÙØ¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙÚ©ÙÛØ¯ Ø²ÛØ±Ø§ ØªÙØžÛÙ
+Ø§Øª Ø±Ø§ ØšØ± Ù
+Û Ú¯Ø±Ø¯Ø§ÙØ¯ Ø¯Ø± Ø¹ÙØ¶ Ø±ÙÛ ÛÚ©Û Ø§Ø² Ø¯Ú©Ù
+Ù ÙØ§Û ÙÙØ§Ø± Ø¯Ø³ØªØ±Ø³Û ØšØ§ÙØ§ Ú©ÙÛÚ© Ú©ÙÛØ¯ .}  
+_textsetprefs_ [l=prs] {ØªØ±ØªÛØš Ø§ÙÙÛØªÙØ§}  
+_textsearchprefs_ [l=prs] {Ø¬Ø³ØªØ¬ÙÛ ØªØ±Ø¬ÛØ­Ø§Øª}  
+_textcollectionprefs_ [l=prs] {ØªØ±Ø¬ÛØ­Ø§Øª Ù
+Ø¬Ù
+ÙØ¹Ù}  
+_textpresentationprefs_ [l=prs] {Ø§Ø±Ø§ØŠÙ ØªÙØžÛÙ
+Ø§Øª}  
+_textpreferences_ [l=prs] {ØªØ±Ø¬ÛØ­Ø§Øª}  
+_textcasediffs_ [l=prs] {ØšØ²Ø±Ú¯Û ÙÚ©ÙÚÚ©Û Ø­Ø±ÙÙ :}  
+_textignorecase_ [l=prs] {ÚØŽÙ
+ ÙŸÙØŽÛ Ø§Ø² ØšØ²Ø±Ú¯Û Ù Ú©ÙÚÚ©Û Ø­Ø±ÙÙ}  
+_textmatchcase_ [l=prs] {Ú©ÙÚÚ©Û Ù ØšØ²Ø±Ú¯Û Ø­Ø±ÙÙ ØšØ§ÛØ¯ ÙØ­Ø§Øž ØŽÙØ¯}  
+_textwordends_ [l=prs] {Ø§ÙØªÙØ§Û Ú©ÙÙ
+Ø§Øª :}  
+_textstem_ [l=prs] {ÚØŽÙ
+ ÙŸÙØŽÛ Ø§Ø² Ø§ÙØªÙØ§Û Ú©ÙÙ
+Ø§Øª}  
+_textnostem_ [l=prs] {ØªÙ
+Ø§Ù
+ ÙØºØ§Øª ØšØ§ÛØ¯ ØªØ·Ø§ØšÙ Ú©ÙØ¯}  
+_textaccentdiffs_ [l=prs] {ØªÙØ§ÙØªÙØ§Û ÙÙØ¬Ù:}  
+
+_textmatchaccents_ [l=prs] {ÙÙØ¬Ù ÙØ§ ØšØ§ÛØ¯ ØªØ·Ø§ØšÙ Ú©ÙØ¯}  
+
+_textprefop_ [l=prs] {Ø­Ø¯Ø§Ú©Ø«Ø± _maxdocoption_ Ù
+ÙØ±Ø¯ ÙØŽØ§Ù Ø¯Ø§Ø¯Ù ØŽÙØ¯ ØšØ§ _hitsperpageoption_ Ù
+ÙØ±Ø¯ Ø¯Ø± ÙØ± ØµÙØ­Ù .}  
+_textextlink_ [l=prs] {Ø¯Ø³ØªØ±Ø³Û ØšÙ ØµÙØ­Ø§Øª ÙØš Ø®Ø§Ø±Ø¬Û :}  
+_textintlink_ [l=prs] {Ø§Ø³ÙØ§Ø¯ Ø§ØµÙÛ ØšØ§Ø²ÛØ§ØšÛ ØŽØ¯Ù Ø§Ø³Øª Ø§Ø² :}  
+_textlanguage_ [l=prs] {Ø²ØšØ§Ù Ø±Ø§ØšØ· :}  
+_textencoding_ [l=prs] {Ú©Ø¯ Ø²ØšØ§Ù ØµÙØ­Ù :}  
+_textformat_ [l=prs] {ÙØ§ÙØš Ø±Ø§ØšØ·:}  
+_textall_ [l=prs] {ÙÙ
+Ù}  
+_textquerymode_ [l=prs] {ÙÙØ¹ ÙŸØ±Ø³ ÙØ¬Ù :}  
+_textsimplemode_ [l=prs] {Ø­Ø§ÙØª ÙŸØ±Ø³ Ù Ø¬ÙÛ Ø³Ø§Ø¯Ù}  
+_textadvancedmode_ [l=prs] {Ø­Ø§ÙØª ÙŸØ±Ø³ Ù Ø¬ÙÛ ÙŸÛØŽØ±ÙØªÙ ( Ù
+Û ØªÙØ§ÙÛØ¯ Ø§Ø² Ø¹Ù
+ÙÚ¯Ø±ÙØ§Û Ù
+ÙØ·ÙÛ ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² ! Ø & Ø | Ù ÙŸØ±Ø§ÙØªØ² Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ÛÛØ¯ )}  
+_textlinkinterm_ [l=prs] {Ø§Ø²Ø·Ø±ÛÙ ØµÙØ­Ù Ù
+ÛØ§ÙÛ}  
+_textlinkdirect_ [l=prs] {Ù
+Ø³ØªÙÛÙ
+ ØšØ±Ù ØšÙ :}  
+_textdigitlib_ [l=prs] {Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÛØ¬ÛØªØ§Ù}  
+_textweb_ [l=prs] {ÙØš}  
+_textgraphical_ [l=prs] {ØªØ±Ø³ÛÙ
+Û}  
+_texttextual_ [l=prs] {Ù
+ØªÙÛ}  
+_textcollectionoption_ [l=prs] {<p>
+Ø²ÛØ±Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ÛÛ Ú©Ù ØŽØ§Ù
+Ù Ù
+Û ØŽÙØ¯ :
+<br>}  
+
+_textsearchtype_ [l=prs] {ØŽÚ©Ù ÙŸØ±Ø³ ÙØ¬Ù:}  
+_textformsearchtype_ [l=prs] {ØªÙÛÙ ØŽØ¯Ù ØšØ§ ÙÛÙØ¯ÙØ§Û _formnumfieldoption_}  
+
+_textregularbox_ [l=prs] {Ø®Ø· Ù
+ÙÙØ±Ø¯}  
+_textlargebox_ [l=prs] {Ú©ÙØ§Ù}  
+
+_textrelateddocdisplay_ [l=prs] {ÙÙ
+Ø§ÛØŽ Ø§Ø³ÙØ§Ø¯ Ù
+Ø±ØªØšØ·}  
+_textsearchhistory_ [l=prs] {Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù :}  
+_textnohistory_ [l=prs] {Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬ÙÛÛ ÙØ¬ÙØ¯ ÙØ¯Ø§Ø±Ø¯}  
+_texthistorydisplay_ [l=prs] {ÙÙ
+Ø§ÛØŽ _historynumrecords_ ØªØ¹Ø¯Ø§Ø¯ Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù }  
+_textnohistorydisplay_ [l=prs] {ÙØŽØ§Ù ÙØ¯Ø§Ø¯Ù Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=prs] {ØªØ±ØªÛØš Ø§Ø³ÙØ§Ø¯ ØšØ±Ø­Ø³Øš}  
+_textalsoshowing_ [l=prs] {ØšØ¹ÙØ§ÙÙ ÙÙ
+Ø§ÙØŽ }  
+_textwith_ [l=prs] {ØšØ§ ØšÙØŽØªØ±ÙÙ }  
+_textdocsperpage_ [l=prs] {Ø³ÙØ¯ Ø¯Ø± ØµÙØ­Ù}  
+
+_textfilterby_ [l=prs] {Ø§Ø³ÙØ§Ø¯Ù ÙÙ Ø­Ø§ÙÙ }  
+_textall_ [l=prs] {ÙÙ
+Ù}  
+_textany_ [l=prs] {ÙØ±}  
+_textwords_ [l=prs] {Ø§Ø² ÙÙÙ
+Ù}  
+_textleaveblank_ [l=prs] {ØšØ±Ø§Ù ØšÙ Ø¯Ø³Øª Ø¢ÙØ±Ø¯Ù ÙÙ
+Ù Ø§Ø³ÙØ§Ø¯ Ø§ÙÙ ÙØ³Ù
+Øª Ø±Ø§ Ø®Ø§ÙÙ ØšÚ¯Ø°Ø§Ø±ÙØ¯ }  
+
+_browsebuttontext_ [l=prs] {"Ù
+Ø±ØªØš Ø³Ø§Ø²Ù Ø§Ø³ÙØ§Ø¯"}  
+
+_nodata_ [l=prs] {<i>ØšØ¯ÙÙ Ø§Ø·ÙØ§Ø¹Ø§Øª</i>}  
+_docs_ [l=prs] {Ø§Ø³ÙØ§Ø¯}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=prs] {ÙÙ
+Ù}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=prs] {ØšØ±Ø§Û Ù
+Ø±ÙØ± Ø§Ø³ÙØ§Ø¯ ÙØžØ± ØšÙ _1_ ØšØ§ÙØ§Û Ø¯Ú©Ù
+Ù _2_ Ú©ÙÛÚ© Ú©ÙÛØ¯}
+
+_textSearchhelp_ [l=prs] {ØšØ§ Ú©ÙÛÚ© ÙÙ
+ÙØ¯Ù ØšØ§ÙØ§Û _labelSearch_ Ù
+ÛØªÙØ§ÙÛØ¯ Ú©Ù Ú©ÙÛÙ
+Ù Ø®Ø§ØµÛ Ø±Ø§ Ø¯Ø± Ù
+ØªÙ Ø¬Ø³ØªØ¬Ù ÙÙ
+Ø§ØŠÛØ¯}  
+
+_textFromhelp_ [l=prs] {ØšØ§ Ú©ÙÛÚ© ÙÙ
+ÙØ¯Ù ØšØ§ÙØ§Û Ø¯Ú©Ù
+Ù_labelFrom_ ÙØŽØ±Ø§Øª Ø±Ø§ ØªÙØ³Ø· ÙÛÙØ¯ Ø§Ø² ÙØŽØ§Ù Ø¯ÙÛØ¯.}  
+_textBrowsehelp_ [l=prs] {Ù
+Ø±ÙØ±Ø§Ø³ÙØ§Ø¯}  
+_textAcronymhelp_ [l=prs] {Ù
+Ø±ÙØ± ØšÙ Ù
+Ø®ÙÙØ§Øª Ú©Ù ØšØ§Ú©ÙÛÚ© ÙÙ
+ÙØ¯Ù ØšØ§ÙØ§Û Ø¯Ú©Ù
+Ù _labelAcronym_ØšÙ
+ÛØ§Ù Ù
+ÛØ§ÛØ¯.}  
+
+
+_texthelptopicstitle_ [l=prs] {Ù
+ÙØ¶ÙØ¹Ø§Øª}  
+
+_textreadingdocs_ [l=prs] {ÚÚ¯ÙÙÙ Ø§Ø³ÙØ§Ø¯ Ø±Ø§ ØšØ®ÙØ§ÙÛÙ
+}  
+
+_texthelpreadingdocs_ [l=prs] {<p>
+Ø§Ø² Ø¢ÙØ¬Ø§ÛÛ Ú©Ù Ø¯Ø± ÙØ³Ù
+Øª ØšØ§ÙØ§ Ø³Ù
+Øª ÚÙŸ ÙØ± ØµÙØ­Ù Ø¹ÙÙØ§Ù Ø³ÙØ¯ ÛØ§ Ø¹Ú©Ø³ Ø¬ÙØ¯ Ø¢Ù Ø¯Ø±Ø¬ ØŽØ¯Ù Ø§Ø³Øª
+Ù
+Û ØªÙØ§ÙÛØ¯ ØšØšÛÙÛØ¯ ØšÙ Ú©ØªØ§Øš ÛØ§ Ø³ÙØ¯ Ø®Ø§ØµÛ Ø¯Ø³Øª ÛØ§ÙØªÙ Ø§ÛØ¯ . Ø¯Ø± ØšØ¹Ø¶Û Ø§Ø² Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§
+ØšÙ ÙÙ
+Ø±Ø§Ù ÙÙØ±Ø³Øª Ù
+Ø­ØªÙÛØ§Øª Ø¯ÛØ¯Ù Ù
+ØŽ ÙØ¯ Ù Ø¯Ø± ØšØ¹Ø¶Û ØŽØ§Ù
+Ù ØŽÙ
+Ø§Ø±Ù ØµÙØ­Ù ÙØ¹ÙÛ Ù ÙØ³Ù
+ØªÛ ØšØ±Ø§Û
+ØªØ¹ÛÛÙ ØµÙØ­Ù Ù Ø±ÙØªÙ ØšÙ ØµÙØ­Ù Ù
+ØŽØ®ØµÛ ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ . Ø¯Ø± ÙÙØ±Ø³Øª Ù
+Ø­ØªÙÛØ§Øª ØšØ®ØŽ Ø¬Ø§Ø±Û ÙŸØ±Ø±ÙÚ¯ 
+Ù
+Û ØšØ§ØŽØ¯ Ù Ø¬Ø¯ÙÙ ÙÛØ² ÙØ§ØšÙ ØšØ§Ø² ØŽØ¯Ù Ø§Ø³Øª . ØšØ§ Ú©ÙÛÚ© ØšØ± Ø±ÙÛ ÙŸÙØŽÙ ÙØ§ Ù
+Û ØªÙØ§Ù ØšØ§Ø² ÛØ§ ØšØ³ØªÙ ØŽØ§Ù Ú©Ø±Ø¯ .
+</p>
+
+<p>Ø¯Ø± ÙØ³Ù
+Øª ÙŸØ§ÛÛÙ Ù
+ØªÙ ØšØ®ØŽ ÙØ±Ø§Ø± Ø¯Ø§Ø±Ø¯. Ú©Ù ÙÙØªÛ Ø®ÙØ§ÙØ¯Ù ØŽØ¯Ù ÙÙØŽ ÙØ§ÛÛ ØšØ±Ø§Û 
+Ø±ÙØªÙ ØšÙ ØšØ®ØŽ ØšØ¹Ø¯ ÛØ§ ÙØšÙ ÙØ¬Ù Ø¯Ø§Ø±Ø¯ </p>
+
+<p>Ø¯Ø± Ø²ÛØ± Ø¹ÙÙØ§Ù ÛØ§ Ø¹Ú©Ø³ ØªØ¹Ø¯Ø§Ø¯ Ø¯Ú©Ù
+Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯. ØšØ±Ø±ÙÛ 
+<i>ØšØ§Ø²Ú©Ø±Ø¯Ù Ù
+ØªÙ</i> Ú©ÙÛÚ© Ú©ÙÛØ¯ ØªØ§ ØªÙ
+Ø§Ù
+ Ù
+ØªÙ ØšØ®ØŽ ÛØ§ Ú©ØªØ§Øš Ø¬Ø§Ø±Û ÙÙ
+Ø§ÛØŽ Ø¯Ø§Ø¯Ù ØŽÙØ¯. 
+Ø§ÙØšØªÙ Ø§Ú¯Ø± Ø³ÙØ¯ ØšØ²Ø±Ú¯ ØšØ§ØŽØ¯ ÙÙØª Ú¯ÛØ± Ù Ø­Ø§ÙØžÙ Ú¯ÛØ± Ø®ÙØ§ÙØ¯ ØšÙØ¯ . 
+ØšØ§ Ú©ÙÛÚ© ØšØ±Ø±ÙÛ  <i>ØšØ§Ø²Ú©Ø±Ø¯Ù Ù
+Ø­ØªÙÛØ§Øª</i> ÙÙØ±Ø³Øª Ù
+Ø­ØªÙÛØ§Øª ÙØŽØ§Ù Ø¯Ø§Ø¯Ù Ø®ÙÙØ¯ ØŽØ¯ 
+Ù Ù
+Û ØªÙØ§ÙÛØ¯ Ø¹ÙØ§ÙÛÙ ØªÙ
+Ø§Ù
+ ÙØµÙÙ Ù Ø²ÛØ± ÙØµÙ ÙØ§ Ø±Ø§ ØšØšÛÙÛØ¯ .ØšØ§ Ú©ÙÛÚ© ØšØ±Ø±ÙÛ 
+ <i>ÙØ·Ø¹</i> ÙŸÙØ¬Ø±Ù Ø¬Ø¯ÛØ¯Û ØšØ±Ø§Û Ø§ÛÙ Ø³ÙØ¯ ØšØ§Ø² Ø®ÙØ§ÙØ¯ ØŽØ¯ . (ØšØ®ØµÙØµ ÙÙØªÛ Ù
+ÙÛØ¯ Ø§Ø³Øª Ú©Ù ØšØ®ÙØ§ÙÛØ¯ Ø¯Ù Ø³ÙØ¯ Ø±Ø§ Ù
+ÙØ§ÛØ³Ù Ú©ÙÛØ¯ Ù ÛØ§ ØšØ§ ÙÙ
+ ØšØ®ÙØ§ÙÛØ¯ 
+ .) ØšØ§ÙØ§Ø®Ø±Ù ÙÙØªÛ Ø¬Ø³ØªØ¬Ù Ù
+Û Ú©ÙÛØ¯ Ú©ÙÙ
+Ø§Øª Ù
+ÙØ±Ø¯ Ø¬Ø³ØªØ¬Ù ØšØ±Ø¬Ø³ØªÙ Ù
+Û ØŽÙØ¯ Ù ØšØ§ Ú©ÛÚ© Ø±ÙØ³ <i>ØšØ¯ÙÙ ØšØ±Ø¬Ø³ØªÙ Ø³Ø§Ø²Û</i> 
+ Ø§ÛÙ ØšØ±Ø¬Ø³ØªÙ Ø³Ø§Ø²Û ØŽØ¯Ù ÙØ§ Ø­Ø°Ù Ù
+Û ØŽÙÙØ¯.</p>
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=prs] {ØšØ§Ø² Ú©Ø±Ø¯Ù Ø§ÛÙ ÙÙØ³Ù Ú©ØªØ§Øš}  
+_texthelpopenbook_ [l=prs] {ØšØ§Ø²Ú©Ø±Ø¯Ù/ØšØ³ØªÙ Ú©ØªØ§Øš}  
+_texthelpviewtextsection_ [l=prs] {Ø±ÙÛØª Ø§ÛÙ ØšØ®ØŽ Ø§Ø² Ù
+ØªÙ}  
+_texthelpexpandtext_ [l=prs] {ÙÙ
+Ø§ÛØŽ Ù
+ØªÙ Ú©Ù ÙÛØ§ Ø¹Ø¯Ù
+ ÙÙ
+Ø§ÛØŽ}  
+_texthelpexpandcontents_ [l=prs] {ØšØ§Ø²Ú©Ø±Ø¯Ù ÙÙØ±Ø³Øª Ù
+Ø­ØªÙÛØ§Øª ÛØ§ ØšØ³ØªÙ Ø¢Ù}  
+_texthelpdetachpage_ [l=prs] {ØšØ§Ø² Ú©Ø±Ø¯Ù Ø§ÛÙ ØµÙØ­Ù Ø¯Ø± ÛÚ© ØµÙØ­Ù Ø¬Ø¯ÛØ¯}  
+_texthelphighlight_ [l=prs] {ØšØ±Ø¬Ø³ØªÙ Ø³Ø§Ø²Û Ú©ÙÙ
+Ø§Øª Ù
+ÙØ±Ø¯ Ø¬Ø³ØªØ¬Ù ÛØ§ Ø¹Ø¯Ù
+ ØšØ±Ø¬Ø³ØªÙ Ø³Ø§Ø²Û}  
+_texthelpsectionarrows_ [l=prs] {ØšÙ ØšØ®ØŽ ÙØšÙÛ/Ø¢ØªÛ ØšØ±ÙÛØ¯}  
+
+
+_texthelpsearchingtitle_ [l=prs] {ÚÚ¯ÙÙÙ Ú©ÙÙ
+Ø§Øª Ø®Ø§ØµÛ Ø±Ø§ Ø¬Ø³ØªØ¬Ù Ú©ÙÛÙ
+}  
+
+
+
+_texthelpquerytermstitle_ [l=prs] {Ø¬Ø³ØªØ¬ÙÛ Ø¹ØšØ§Ø±Ø§Øª}  
+_texthelpqueryterms_ [l=prs] {<p>
+ÙØ± ÚÛØ²Û Ú©Ù Ø¯Ø± Ø¬Ø¹ÛÙ Ø³ÙØ§Ù ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ ØšÙ Ø¹ÙÙØ§Ù ÙÙØ±Ø³ØªÛ Ø§Ø² Ú©ÙÙ
+Ø§Øª Ø¹ØšØ§Ø±Ø§Øª Ø¬Ø³ØªØ¬Ù ÙØ§Ù
+ Ø¯Ø§Ø±Ø¯ .
+ÙØ± Ø¹ØšØ§Ø±Øª ÚÛØ²Û Ø¬Ø² Ø­Ø±ÙÙ Ù Ø§Ø¹Ø¯Ø§Ø¯ ÙÛØ³Øª . Ø¹ØšØ§Ø±Ø§Øª ØšØ§ ÙØ¶Ø§Û Ø®Ø§ÙÛ Ø§Ø² ÙÙ
+ Ø¬Ø¯Û Ù
+ÛØŽÙÙØ¯ . Ø§Ú¯Ø±
+ÙØ± Ú©Ø§Ø±Ø§Ú©ØªØ± Ø¯ÛÚ¯Ø±Û Ù
+Ø§ÙÙØ¯ ÙÙØ·Ù Ú¯Ø°Ø§Ø±Û Ø§Ø³ØªÙØ§Ø¯Ù ØŽÙØ¯ ØšÙ Ø¹ÙÙØ§Ù ÙØ¶Ø§Û Ø®Ø§ÙÛ ØšØ±Ø§Û Ø¬Ø¯Ø§Ú©Ø±Ø¯Ù 
+Ø¹ØšØ§Ø±Ø§Øª Ø¯Ø± ÙØžØ± Ú¯Ø±ÙØªÙ Ø®ÙØ§ÙØ¯ ØŽØ¯ Ù Ø­Ø±Ù Ø®ÙØ§ÙÙØ¯ ØŽØ¯ . Ø¹ØšØ§Ø±Ø§ØªÛ Ú©Ù ØŽØ§Ù
+Ù Ø¹ÙØ§ØŠÙ
+ ÙÙØ·Ù Ú¯Ø°Ø§Ø±Û ØšØ§ØŽÙØ¯ 
+ÙØ§ØšÙ Ø¬Ø³ØªØ¬Ù ÙÛØ³ØªÙØ¯ .
+<p>ØšØ±Ø§Û Ù
+Ø«Ø§Ù Ø³ÙØ§Ù<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p> Ù
+Ø§ÙÙØ¯ Ø§ÛÙ Ù
+ÙØ±Ø¯ Ø®ÙØ§ÙØ¯ ØšÙØ¯: <p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+
+_texthelpquerytype_ [l=fa] {
+<p>Ø¯Ù ÙÙØ¹ ÙŸØ±Ø³ Ù Ø¬Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ :
+
+<ul>
+  <li>Ø¬Ø³ØªØ¬Ù ØšØ±Ø§Û  <b>ÙÙ
+Ù</b> Ú©ÙÙ
+Ø§Øª.  ØŽØ§Ù
+Ù Ø§Ø³ÙØ§Ø¯Û Ù
+Û ØŽÙØ¯ (ÛØ§ ÙØµÙÙ ÛØ§ Ø¹ÙØ§ÙÛÙ)
+   Ú©Ù ØªÙ
+Ø§Ù
+ Ú©ÙÙ
+Ø§Øª Ù
+ÙØ±Ø¯ ÙØžØ± ØŽÙ
+Ø§ Ø¯Ø± Ø¢Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±ÙØ¯ .
+      Ø§Ø³ÙØ§Ø¯Û Ú©Ù ØªØ·ØšÛÙ Ú©ÙÙØ¯ ØšÙ ØªØ±ØªÛØš Ø§ÙÙØšØ§ÛÛ ÙØŽØ§Ù Ø¯Ø§Ø¯Ù Ø®ÙØ§ÙØ¯ ØŽØ¯.<p>
+
+  <li>Ø¬Ø³ØªØ¬ÙÛ ØšØ±Ø§Û  <b>ØšØ¹Ø¶Û </b> Ø§Ø² Ú©ÙÙ
+Ø§Øª.  ÙÙØ±Ø³ØªÛ Ø§Ø² Ø¹ØšØ§Ø±Ø§Øª Ú©Ù Ù
+Ù
+Ú©Ù Ø§Ø³Øª Ø¯Ø± Ø³ÙØ¯ ÙØ¬ÙØ¯ Ø¯Ø§ØŽØªÙ 
+  ØšØ§ØŽÙØ¯.  ÙØªØ§ÛØ¬ ØšØ± Ø§Ø³Ø§Ø³ Ù
+ÛØ²Ø§Ù ØªØ·Ø§ØšÙ ØšØ§ Ø¬Ø³ØªØ¬Ù ÙØŽØ§Ù Ø¯Ø§Ø¯Ù Ù
+Û ØŽÙÙØ¯ .  
+  Ø¯Ø± ØªØ¹ÛÛÙ Ù
+ÛØ²Ø§Ù ØªØ·Ø§ØšÙ,
+
+      <p><ul>
+        <li> ÙØ±ÚÙ ØšÛØŽØªØ± Ø§Ø² Ø¹ØšØ§Ø±Ø§Øª Ø¬Ø³ØªØ¬Ù Ø¯Ø§ØŽØªÙ ØšØ§ØŽØ¯ ØšÛØŽØªØ± ØªØ·Ø§ØšÙ Ø¯Ø§Ø±Ø¯
+        <li> Ø¹ØšØ§Ø±Ø§Øª ÙØ§Ø¯Ø± ØšÛØŽØªØ± Ø§Ø² Ø¹ØšØ§Ø±Ø§Øª Ø¹Ù
+ÙÙ
+Û Ù
+ÙÙ
+ ÙØ³ØªÙØ¯
+        <li> Ø§Ø³ÙØ§Ø¯ Ú©ÙØªØ§Ù Ù
+ÙÙ
+ØªØ± Ø§Ø² Ø§Ø³ÙØ§Ø¯ ØšÙÙØ¯ ÙØ³ØªÙØ¯.
+      </ul>
+</ul>
+
+<p>ÙØ± ØªØ¹Ø¯Ø§Ø¯ ÙØšØ§Ø±Øª Ú©Ù Ù
+Û Ø®ÙØ§ÙÛØ¯ ØšØ±Ø§Û Ø¬Ø³ØªØ¬Ù ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ ÛÚ© Ø¬Ù
+ÙÙ ÛØ§ Ø­ØªÛ ÛÚ© ÙŸØ§Ø±Ø§Ú¯Ø±Ø§Ù.
+Ø§Ú¯Ø± ØªÙÙØ§ ÛÚ© Ø¹ØšØ§Ø±Øª ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ ØšØ± Ø­Ø³Øš ØªÚ©Ø±Ø§Ø± Ø¢Ù Ø¹ØšØ§Ø±Øª ÙØªØ§ÛØ¬ Ù
+Ø±ØªØš Ø®ÙØ§ÙÙØ¯ ØŽØ¯.<p>
+}  
+
+_texthelpmgppsearching_ [l=prs] {Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û Ú©Ù ØšØ§ MGPPØªÙÛÙ ØŽØ¯Ù Ú¯Ø²ÛÙÙ ÙØ§Û Ø¯ÛÚ¯Ø±Û ÙÛØ² ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯.}  
+
+_texthelplucenesearching_ [l=prs] {ØšØ±Ø§Û Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û Ø³Ø§Ø®ØªÙ ØŽØ¯Ù ØšØ§ Lucene ØªØ¹Ø¯Ø§Ø¯ Ú¯Ø²ÛÙÙ Ø¯ÛÚ¯Ø± ÙØ§ØšÙ Ø§Ø³ØªÙØ§Ø¯Ù ÙØ³ØªÙØ¯ .
+<ul>
+<li><b>?</b> Ù
+Û ØªÙØ§ÙØ¯ ØšÙ Ø¬Ø§Û ÛÚ© Ø­Ø±Ù Ù
+ÙØ±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙØ±Ø§Ø± Ú¯ÛØ±Ø¯ Ù
+Ø«ÙØ§ , <b>b?t</b> ØªØ·ØšÛÙ Ù
+Û Ú©ÙØ¯ ØšØ§  <b>bet</b>, <b>bit</b> Ù <b>bat</b> Ù ØºÛØ±Ù.
+<li><b>*</b> Ù
+Û ØªÙØ§ÙØ¯ ØšÙ Ø¬Ø§Û ÚÙØ¯ÛÙ Ø­Ø±Ù Ù
+ÙØ±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙØ±Ø§Ø± Ú¯ÛØ±Ø¯ Ù
+Ø«ÙØ§ , <b>comput*</b> ØªØ·ØšÛÙ Ù
+Û Ú©ÙØ¯ ØšØ§ ØªÙ
+Ø§Ù
+ Ú©ÙÙ
+Ø§ØªÛ Ú©Ù ØšØ§ <b>comput</b> ØŽØ±ÙØ¹ Ù
+Û ØŽÙÙØ¯.
+</ul>
+ÙØ± Ø¯ÙÛ Ø§ÛÙ Ø¹ØšØ§Ø±Ø§Øª Ù
+Û ØªÙØ§ÙØ¯ Ø¯Ø±Ù
+ÛØ§Ù ÛØ§ Ø§ÙØªÙØ§Û Ø¹ØšØ§Ø±Øª Ù
+ÙØ±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙØ±Ø§Ø± Ú¯ÛØ±Ø¯ . Ø§Ù
+Ø§ Ø¯Ø± Ø§ØšØªØ¯Ø§Û Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù ÙÙ
+Û ØªÙØ§ÙÙØ¯ ÙØ±Ø§Ø± Ú¯ÛØ±ÙØ¯ .
+
+}  
+
+_texthelpquerytypetitle_ [l=prs] {ÙÙØ¹Ù ÙŸØ±Ø³ØŽ}  
+_texthelpquerytype_ [l=prs] {Ø¯ÙÙÙØ¹Ù ÙŸØ±Ø³ ÙØ¬Ù ÙØ¬ÙØ¯Ø¯Ø§Ø±ÛØ¯.
+
+<ul>
+  <li>ÙŸØ±Ø³ ÙØ¬Ù ØšØ®Ø§Ø·Ø±<b>ÙÙ
+Ù</b>Ú©ÙÛÙ
+Ø§Øª. Ú©Ù Ø§ÛÙÙØ§ ØšØ±Ø§Û Ø§Ø³ÙØ§Ø¯ (ÛØ§ ØšØ§Øš ÙÛØ§ Ø¹ÙÙØ§Ù) Ø¬Ø³ØªØ¬Ù Ù
+ÛÚ©ÙØ¯ Ú©Ù ÙÙ
+Ù Ú©ÙÛÙ
+Ø§Øª Ø±Ø§Ø¯Ø±ØšØ± Ù
+ÛÚ¯ÛØ±Ø¯ Ú©Ù ØŽÙ
+Ø§ Ù
+Ø®ØªØµ ÙÙ
+Ø¯Ù Ø§ÛØ¯.
+ÙØ§Ø³ÙØ§Ø¯ÛÚ©Ù ØšÙ ÙŸØ±Ø³ØŽ Ù
+Ø·Ø§ØšÙØª Ú©ÙØ¯ Ø¯Ø± Ø­Ø§ÙØª Ø³Ø§Ø®ØªÙ ØŽØ¯Ù ÙØŽØ§Ù Ø¯Ø§Ø¯Ù ØŽØ¯Ù Ø§Ø³Øª.
+<p>
+
+  <li>ÙŸØ±Ø³ØŽ ÙØ§ ØšØ±Ø§Û <b>ØšØ¹Ø¶Û</b>Ø§Ø² Ú©ÙÛÙ
+Ø§Øª. ØªÙÙØ§ ÙØ³Øª ØšØ¹Ø¶Û Ø§Ø² Ø§ØµØ·ÙØ§Ø­Ø§Øª Ú©Ù ØŽÙ
+Ø§ Ø¯Ø± Ø§Ø³ÙØ§Ø¯ ØšØ±Ø§ÛØŽ Ø¬Ø³ØªØ¬Ù Ù
+ÛÙÙ
+ÙØ¯ÛØ¯ ÙØŽØ§Ù Ø¯Ø§Ø¯Ù ØŽØ¯Ù. Ø§Ø³ÙØ§Ø¯ ÙØŽØ§Ù Ø¯Ø§Ø¯Ù ØŽØ¯Ù Ú©Ù ØªØ§ÚÛ Ø­Ø¯Û ØšÙ ÙŸØ±Ø³ØŽ ØŽÙ
+Ø§ Ù
+Ø·Ø§ØšÙØª Ù
+ÛÚ©ÙØ¯. ÙÙØªÛ Ø¯Ø±Ø¬Ù Ù
+Ø·Ø§ØšÙØª ØªØ¹ÛÙ Ù
+ÛÚ©ÙÛØ¯.}  
+
+_texthelpadvancedsearchtitle_ [l=prs] {ØšØ±Ø§Û Ø¬Ø³ØªØ¬ÙÛ ÙŸØŽØ±ÙØªÙ Ø§Ø² _1_ Ø¬Ø³ØªØ¬ÙÚ¯Ø± Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ØŠÛØ¯}  
+
+
+
+_texthelpadvsearchmg_ [l=prs] {ØšØ±Ø§Û Ø¬Ø³ØªØ¬Ù Û ÙŸÛØŽØ±ÙØªÙ Ø¯Ø±Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û MG ØšÙ ØŽÙ
+Ø§ Ø¯Ù Ø§ÙØªØ®Ø§ Øš Ù
+ÛØšØ®ØŽØ¯Ø ØµÙ ØšÙØ¯Û ÙØ³ÛØ³ØªÙ
+ ØšÙÙÛÙ.
+ÛÚ© Ø¬Ø³ØªØ¬ÙÛ <b>ranked</b>Ø¹ÛÙ Ù
+Ø§ÙÙØ¯ Ø¬Ø³ØªØ¬ÙÛ<b>some</b> Ø§Ø³Øª Ù
+Ø«ÙÛÚ©Ù Ø¯Ø±<a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_ØªØŽØ±ÛØ­ ØŽØ¯Ù.}  
+
+
+
+
+
+_texthelpadvancedsearchextra_ [l=prs] {ÙÚ©ØªÙ : Ø§ÛÙ Ø¹Ù
+ÙÚ©Ø±Ø¯ÙØ§ Ø¯Ø± ØµÙØ±Øª Ø§ÛÙÚ©Ù Ø­Ø§ÙØª Ø¬Ø³ØªØ¬ÙÛ Ø³Ø§Ø¯Ù ÙØ¹Ø§Ù ØšØ§ØŽÙØ¯ Ù
+ÙØ±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙØ±Ø§Ø± ÙÙ
+Û Ú¯ÛØ±ÙØ¯ .}  
+
+_texthelpadvsearchlucene_ [l=prs] {ØšØ±Ø§Û Ø¬Ø³ØªØ¬ÙÛ ÙŸÛØŽØ±ÙØªÙ ØªØ± Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ Ø¯Ø±LuceneÚ©Ø§Ø±Ú¯Ø°Ø§Ø±Û Ø³ÛØ³ØªÙ
+ ØšÙÙÛÙ Ø±Ø§Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ØŠÛØ¯. _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=prs] {Ø¬Ø³ØªØ¬ÙÛ Ø±ØŽØªÙ ÛÛ}  
+
+
+
+
+
+_textdatesearch_ [l=prs] {Ø¬Ø³ØªØ¬Ù ØšØ§ ØªØ§Ø±ÙØ®}  
+
+_texthelpdatesearch_ [l=prs] {Ø¬Ø³ØªØ¬ÙÛ ØšÙ Ú©Ù
+Ú© ØªØ§Ø±ÛØ® Ø§Ø³ÙØ§Ø¯Û Ø±Ø§ ØšÛØ§ØšÛØ¯ Ú©Ù Ø¹ÙØ§ÙÙ ØšØ± Ø§ÛÙÚ©Ù Ø¹ØšØ§Ø±Ø§Øª Ù
+ÙØ±Ø¯ Ø¬Ø³ØªØ¬ÙÛ ØŽÙ
+Ø§ 
+Ø¯Ø± Ø¢Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ Ø¯Ø± ÛÚ© Ù
+Ø­Ø¯ÙØ¯Ù Ø²Ù
+Ø§ÙÛ Ø®Ø§Øµ ÙÙ
+ ÙØ±Ø§Ø± Ú¯Ø±ÙØªÙ Ø§Ø³Øª . ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ Ø§Ø³ÙØ§Ø¯Û Ø±Ø§ Ø¯Ø± ÛÚ© Ø³Ø§Ù 
+Ù
+ØŽØ®Øµ ÛØ§ Ø¯Ø± Ù
+Ø­Ø¯ÙØ¯Ù Ø§Û Ø§Ø² Ø³Ø§ÙÙØ§ ÙØ±Ø§Ø± Ø¯Ø§Ø±ÙØ¯ . ØªÙØ¬Ù Ø¯Ø§ØŽØªÙ ØšØ§ØŽÛØ¯ Ú©Ù Ù
+Ø¬ØšÙØ± ÙÛØ³ØªÛØ¯ Ø®ØªÙ
+Ø§ Ø¹ØšØ§Ø±ØªÛ 
+ØšØ±Ø§Û Ø¬Ø³ØªØ¬Ù ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ ØšÙÚ©Ù Ù
+Û ØªÙØ§ÙÛØ¯ ØªÙÙØ§ ØšØ§ Ù
+ØŽØ®Øµ Ú©Ø±Ø¯Ù ØªØ§Ø±ÛØ® Ø¬Ø³ØªØ¬Ù ÙÙ
+Ø§ÛÛØ¯ .
+ÙÙ
+ÚÙÛÙ ÙØ§Ø²Ù
+ ÙÛØ³Øª Ú©Ù Ø§Ø² ØªØ§Ø±ÛØ® Ø¯Ø± Ø¬Ø³ØªØ¬Ù Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ÛÛØ¯ Ù Ø§Ú¯Ø± ØªØ§Ø±ÛØ®Û ÙØ§Ø±Ø¯ ÙÚ©ÙÛØ¯
+Ù
+Ø§ÙÙØ¯ Ø§ÛÙ Ø§Ø³Øª Ú©Ù Ø§ØµÙØ§ Ø¬Ø³ØªØ¬ÙÛ ØªØ§Ø±ÛØ® ÙØ¬ÙØ¯ ÙØ¯Ø§Ø±Ø¯ .
+}  
+
+_texthelpdatehowtotitle_ [l=prs] {ÚÚ¯ÙÙÚ¯Û Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ø§ÛÙ ÙÛÚÚ¯Û}  
+_texthelpdatehowto_ [l=prs] {<ul>
+   <li>ØšØ±Ø§Û Ø¬Ø³ØªØ¬ÙÛ Ø§Ø³ÙØ§Ø¯ Ø¯Ø± ÛÚ© Ø³Ø§Ù Ù
+Ø¹ÛÙ :<p>
+   <ul>
+       <li>Ø¹ØšØ§Ø±Ø§Øª Ù
+ÙØ±Ø¯ Ø¬Ø³ØªØ¬Ù Ø®ÙØ¯ Ø±Ø§ ØšÙ ØŽÛÙÙ Ù
+Ø¹Ù
+ÙÙ ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ 
+       <li>Ø¯Ø± ÙØ³Ù
+Øª "ØªØ§Ø±ÛØ® Ø¢ØºØ§Ø² (ÛØ§ ÙÙØ·)" Ø³Ø§Ù Ù
+ÙØ±Ø¯ ÙØžØ± Ø±Ø§ ÙØ§Ø±Ø¯ Ú©ÙÛØ¯.
+       <li>Ø§Ú¯Ø± ØªØ§Ø±ÛØ® Ù
+ÙØ±Ø¯ ÙØžØ± ØŽÙ
+Ø§ ÙØšÙ Ø§Ø² Ø¹ØµØ± Ø­Ø§Ø¶Ø± Ø§Ø³Øª (ÙØšÙ Ø§Ø² Ù
+Ø³ÛØ­) 
+ Ú¯Ø²ÛÙÙ ÙŸÛØŽ Ø§Ø² Ù
+ÛÙØ§Ø¯ Ù
+Ø³ÛØ­ Ø±Ø§ Ø§Ø² Ù
+ÙÙÛ Ú©ÙØ§Ø± ÙØ³Ù
+Øª ØªØ§Ø±ÛØ® Ø§ÙØªØ®Ø§Øš Ú©ÙÛØ¯.
+       <li>Ù
+Ø§ÙÙØ¯ ÙÙ
+ÛØŽÙ Ø¬Ø³ØªØ¬ÙÛ Ø®ÙØ¯ Ø±Ø§ Ø¢ØºØ§Ø² Ú©ÙÛØ¯
+   </ul>
+<p><li>ØšØ±Ø§Û Ø¬Ø³ØªØ¬Ù Ø¯Ø± ÛÚ© ØšØ§Ø²Ù Ø²Ù
+Ø§ÙÛ ÛØ§ ØšÛÙ Ø¯ÙØ³Ø§Ù :<p>
+   <ul>
+       <li>Ø¹ØšØ§Ø±Ø§Øª Ù
+ÙØ±Ø¯ Ø¬Ø³ØªØ¬Ù Ø®ÙØ¯ Ø±Ø§ ØšÙ ØŽÛÙÙ Ù
+Ø¹Ù
+ÙÙ ÙØ§Ø±Ø¯ Ú©ÙÛØ¯
+       <li>ØªØ§Ø±ÛØ® Ø§ØšØªØ¯Ø§ Ø±Ø§ Ø¯Ø± ÙØ³Ù
+Øª "ØªØ§Ø±ÛØ® Ø¢ØºØ§Ø²(ÛØ§ÙÙØ·)" ÙØ§Ø±Ø¯ Ú©ÙÛØ¯
+       <li>ØªØ§Ø±ÛØ® Ø§ÙØªÙØ§ Ø±Ø§ Ø¯Ø± ÙØ³Ù
+Øª "ØªØ§Ø±ÛØ® Ø§ÙØªÙØ§" ÙØ§Ø±Ø¯ Ú©ÙÛØ¯.
+       <li>Ø§Ú¯Ø± ØªØ§Ø±ÛØ® Ù
+ÙØ±Ø¯ ÙØžØ± ØŽÙ
+Ø§ ÙØšÙ Ø§Ø² Ø¹ØµØ± Ø­Ø§Ø¶Ø± Ø§Ø³Øª (ÙØšÙ Ø§Ø² Ù
+Ø³ÛØ­) 
+ Ú¯Ø²ÛÙÙ ÙŸÛØŽ Ø§Ø² Ù
+ÛÙØ§Ø¯ Ù
+Ø³ÛØ­ Ø±Ø§ Ø§Ø² Ù
+ÙÙÛ Ú©ÙØ§Ø± ÙØ³Ù
+Øª ØªØ§Ø±ÛØ® Ø§ÙØªØ®Ø§Øš Ú©ÙÛØ¯.
+       <li>Ù
+Ø§ÙÙØ¯ ÙÙ
+ÛØŽÙ Ø¬Ø³ØªØ¬ÙÛ Ø®ÙØ¯ Ø±Ø§ Ø¢ØºØ§Ø² Ú©ÙÛØ¯
+   </ul>    
+</ul><p>
+}  
+
+_texthelpdateresultstitle_ [l=prs] {ÚÚ¯ÙÙÙ ÙØªØ§ÛØ¬ Ø¬Ø³ØªØ¬ÙÛ ØŽÙ
+Ø§ ÛØ§ÙØª Ù
+Û ØŽÙØ¯}  
+_texthelpdateresults_ [l=prs] {Ù
+Ø¹Ù
+ÙÙØ§ Ø¬Ø³ØªØ¬ÙÛ Ø§Ø³ÙØ§Ø¯ Ø¯Ø±ØšØ§Ø±Ù 1903 Ø§Ø³ÙØ§Ø¯Û Ø±Ø§ Ø¯Ø± Ø§ÛÙ Ø³Ø§Ù ÙÙØŽØªÙ ØŽØ¯Ù Ø§ÙØ¯ ØšØ± ÙÙ
+Û Ú¯Ø±Ø¯Ø§ÙØ¯ ØšÙÚ©Ù Ø§Ø³ÙØ§Ø¯Û Ø¯Ø±ØšØ§Ø±Ù 1903 Ø±Ø§ ØšØ±Ù
+Û Ú¯Ø±Ø¯Ø§ÙØ¯ . ÙÙÛ ØšØ§ ØªÙØ¬Ù ØšÙ Ø­Ø§ÙØªÛ Ú©Ù Ø¯Ø± Ø§Ø³ÙØ§Ø¯ ØªØ§Ø±ÛØ® ÙØ§ ÙØ¬ÙØ¯ Ø¯Ø§Ø±ÙØ¯  Ø§Ø³ÙØ§Ø¯Û Ø±Ø§ Ú©Ù ØšØ§ Ù
+Ø­Ø¯ÙØ¯Ù Ø²Ù
+Ø§ÙÛ Ø®Ø§ØµÛ Ù
+Ø«ÙØ§ 1899-1911 Ú©Ù ØŽØ§Ù
+Ù 1903 ÙÙ
+ Ù
+Û ØŽÙØ¯ Ù Ø§Ø³ÙØ§Ø¯Û Ú©Ù Ù
+Ø«ÙØ§ Ø­Ø§ÙÛ ÙØ±ÙÛ Ú©Ù Ø³Ø§Ù 1903 Ø¯Ø± Ø¢Ù Ø§Ø³Øª Ù
+Ø§ÙÙØ¯ ÙØ±Ù ØšÛØ³ØªÙ
+ ÛØ§ Ø¯ÙØ§Ø²Ø¯ÙÙ
+ ØªØŽØ®ÛØµ Ø¯Ø§Ø¯Ù Ù
+Û ØŽÙØ¯ . ØªÙØ¬Ù Ú©ÙÛØ¯ Ú©Ù Ø¯Ø± ØšØ¹Ø¶Û Ø§Ø³ÙØ§Ø¯ ØªØ§Ø±ÛØ® ÙØ§ ÙØ§ÙØ¹Ø§ Ø¯Ø± Ù
+ØªÙ ÙÛØ³ØªÙØ¯ . ØšØ±Ø§Û ÛÚ© Ø¬Ø³ØªØ¬ÙÛ Ù
+Ø­Ø¯ÙØ¯Ù Ø§Û ØŽØ§Ù
+Ù ÙÙ
+Ù ØªØ§Ø±ÛØ® ÙØ§ Ø¯Ø± Ø§ÛÙ Ù
+Ø­Ø¯ÙØ¯Ù Ù
+Û ØŽÙØ¯ .<p>
+}  
+
+_textchangeprefs_ [l=prs] {ØªØºÙÙØ± ØªÙØžÙÙ
+Ø§Øª}  
+
+_texthelppreferences_ [l=prs] {<p>ØšØ§ Ú©ÙÛÚ© ØšØ± Ø±ÙÛ Ø¯Ú©Ù
+Ù <i>ØªÙØžÛÙ
+Ø§Øª</i> Ø¯Ø± ØšØ§ÙØ§Û ØµÙØ­Ù ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ ØªØ§ ØšØ¹Ø¶Û ÙÛÚÚ¯ÛÙØ§Û Ø±Ø§ØšØ· Ú©Ø§Ø±ØšØ±Û
+Ø±Ø§ ØšØ§ ØªÙØ¬Ù ØšÙ ÙÛØ§Ø² Ø®ÙØ¯ ØªØºÛÛØ± Ø¯ÙÛØ¯. 
+}  
+
+_texthelpcollectionprefstitle_ [l=prs] {ØªÙØžÛÙ
+Ø§Øª Ù
+Ø¬Ù
+ÙØ¹Ù}  
+_texthelpcollectionprefs_ [l=prs] {ØšØ¹Ø¶Û Ø§Ø² Ù
+Ø¬Ù
+ÙØ¹ ÙØ§ ØŽØ§Ù
+Ù ÚÙØ¯ÛÙ Ø²ÛØ± Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ³ØªÙØ¯ Ú©Ù Ù
+ÛØªÙØ§Ù ØšÙ ØµÙØ±Øª Ù
+Ø³ØªÙÙ ÛØ§ ØšØ§ÙÙ
+
+Ø¬Ø³ØªØ¬Ù ØŽÙÙØ¯ . Ú©Ù Ø¯Ø± Ø§ÛÙ ÙØ³Ù
+Øª Ù
+Û ØªÙØ§ÙÛØ¯ Ù
+ØŽØ®Øµ Ú©ÙÛØ¯ ÚÙ Ø²ÛØ± Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ÛÛ Ø¯Ø± Ø¬Ø³ØªØ¬ÙÛ
+ØŽÙ
+Ø§ ØšØ§ØŽÙØ¯ .
+}  
+
+_texthelplanguageprefstitle_ [l=prs] {ØªÙØžÛÙ
+Ø§Øª Ø²ØšØ§Ù}  
+_texthelplanguageprefs_ [l=prs] {ÙØ± Ù
+Ø¬Ù
+ÙØ¹Ù ÛÚ© Ø²ØšØ§Ù ÙŸÛØŽ Ú¯Ø²ÛØ¯Ù Ø¯Ø§Ø±Ø¯ Ø§Ù
+Ø§ Ø¯Ø± ØµÙØ±Øª ØªÙ
+Ø§ÛÙ Ù
+Û ØªÙØ§ÙÛØ¯ ØšÙ Ø²ØšØ§Ù Ø¯ÛÚ¯Ø±Û 
+Ø¢Ù Ø±Ø§ ØªØºÛÛØ± Ø¯ÙÛØ¯ . ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ Ø±ÙØŽ Ú©Ø¯Ú¯Ø°Ø§Ø±Û ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± ØšØ±Ø§Û Ø®Ø±ÙØ¬Û Ù
+Ø±ÙØ±Ú¯Ø± Ø±Ø§ ØªØºÛÛØ± Ø¯ÙÛØ¯ .
+Ø§ÙØšØªÙ ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± ØšÙ ØµÙØ±Øª ÙŸÛØŽ Ú¯Ø²ÛØ¯Ù Ø±ÙØŽ Ù
+ÙØ§Ø³Øš Ø±Ø§ Ø§ÙØªØ®Ø§Øš Ù
+Û Ú©ÙØ¯ Ø§Ù
+Ø§ Ø¯Ø± ØšØ¹Ø¶Û Ù
+Ø±ÙØ±Ú¯Ø± ÙØ§
+Ù
+Û ØªÙØ§Ù ØšØ§ Ø³Ø§ÛØ± Ø±ÙØŽ ÙØ§ ÙØªÛØ¬Ù ØšÙØªØ±Û Ú¯Ø±ÙØª . Ø¯Ø± ØªÙ
+Ø§Ù
+ Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ Ù
+Û ØªÙØ§Ù ÙØ§ÙØš Ú¯Ø±Ø§ÙÛÚ©Û Ø±Ø§ØšØ· Ø±Ø§ ØšÙ Ù
+ØªÙÛ 
+ØªØºÛÛØ± Ø¯Ø§Ø±Ø¯ Ú©Ù ØšÙ Ø®ØµÙØµ ØšØ±Ø§Û Ø§ÙØ±Ø§Ø¯Û Ú©Ù Ø¯Ø± Ø¯ÛØ¯ Ù
+ØŽÚ©Ù Ø¯Ø§Ø±ÙØ¯ ØšØ³ÛØ§Ø± Ù
+ÙÛØ¯ Ø§Ø³Øª Ø²ÛØ±Ø§ Ù
+Û ØªÙØ§ÙÙØ¯ Ø§Ø² Ø®Ø·ÙØ· 
+Ø¯Ø±ØŽØª ØªØ± ÛØ§ Ø®ÙØ§ÙÙØ¯Ù ÙØ§Û Ù
+ØªÙ Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ÛÙØ¯ .
+}  
+
+_texthelppresentationprefstitle_ [l=prs] {Ø§Ø±Ø§ØŠÙ ØªØ±Ø¬ÛØ­Ø§Øª}  
+_texthelppresentationprefs_ [l=prs] {Depending on the particular collection, there may be several options you can
+set that control the presentation.
+ØšØ§ ØªÙØ¬Ù ØšÙ ÙØ± Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+Û ØªÙØ§Ù ÚÙØ¯ÛÙ Ú¯Ø²ÛÙÙ Ù
+Ø±ØªØšØ· ØšØ§ Ø§Ø±Ø§ØŠÙ Ø±Ø§ ØªÙØžÛÙ
+ ÙÙ
+ÙØ¯.
+<p>
+Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Û Ø§Ø² ØµÙØ­Ø§Øª ÙØš ØŽÙ
+Ø§ Ø±Ø§ ÙØ§Ø¯Ø± Ù
+Û Ø³Ø§Ø²Ø¯ ØªØ§ ÙÙØ§Ø± ÙØ±Ø§Ù
+ÛÙ ØšØ§ÙØ§Û ÙØ± ØµÙØ­Ù Ø±Ø§ ØªØºÛÛØ± Ø¯ÙÛØ¯  ØšÙØ§ØšØ±Ø§ÛÙ
+Ù
+Û ØªÙØ§ÙÛØ¯ ØµÙØ­Ø§Øª Ù
+ÙØ±Ø¯ ÙØžØ± Ø®ÙØ¯ Ø±Ø§ ØšØ¯ÙÙ Ø³Ø±ØµÙØ­Ù ÙØ§Û Ø§Ø³ØªØ§ÙØ¯Ø§Ø±Ø¯ Ø·Ø±Ø§Ø­Û ÙÙ
+Ø§ÛÛØ¯ . 
+Ø­ØªÛ Ù
+Û ØªÙØ§ÙØ¯ ÙŸÛØ§Ù
+ ÙØ§Û Ø§Ø®Ø·Ø§Ø± Ø³ÛØ³ØªÙ
+ Ø±Ø§ ØªØºÛÛØ± Ø¯ÙÛØ¯ Ù Ø­ØªÛ Ø¯Ø± ØšØ¹Ø¶Û ØµÙØ­Ø§Øª Ù
+Û ØªÙØ§ÙÛØ¯ Ø¯Ø± ØµÙØ­Ù
+ÙØªØ§ÛØ¬ Ø¬Ø³ØªØ¬Ù Ø·ÙØ±Û ØªÙØžÛÙ
+ Ú©ÙÛØ¯ Ú©Ù ØšÙ Ø¬Ø§Û ÙÙ
+Ø§ÛØŽ ÙØ³Ø®Ù Ø°Ø®ÛØ±Ù ØŽØ¯Ù Ø¯Ø± ØšØ±ÙØ§Ù
+Ù ÙØ³Ø®Ù ÙØ§ÙØ¹Û ÙÙ
+Ø§ÛØŽ ÛØ§ØšØ¯ .
+}  
+
+_texthelpsearchprefstitle_ [l=prs] {Ø¬Ø³ØªØ¬ÙÛ ØªØ±Ø¬ÛØ­Ø§Øª}  
+_texthelpsearchprefs_ [l=prs] {<p>
+Ø¯Ù Ø¬ÙØª Ø¯Ú©Ù
+Ù ÙØ­ÙÙ ØªØ·ØšÛÙ Ù
+ØªÙÙ Ø±Ø§ Ø¯Ø± Ø¬Ø³ØªØ¬ÙÙØ§ Ú©ÙØªØ±Ù Ù
+Û Ú©ÙÙØ¯ . Ø§ÙÙÛÙ Ú¯Ø²ÛÙÙ(ØªÙØ§ÙØª Ø­Ø§ÙØª Ø­Ø±ÙÙ) ØªØ¹ÛÛÙ Ù
+Û Ú©ÙØ¯ Ú©Ù
+Ú©ÙÚÚ© Ù ØšØ²Ø±Ú¯Û Ø­Ø±ÙÙ Ù
+Ø¯ ÙØžØ± ÙØ±Ø§Ø± Ú¯ÛØ±Ø¯ ÛØ§ Ø®ÛØ± . Ø¯ÙÙ
+ÛÙ Ú¯Ø²ÛÙÙ(Ø§ÙØªÙØ§Û Ú©ÙÙ
+Ø§Øª) ØªØ¹ÛÛÙ Ù
+Û Ú©ÙØ¯ Ú©Ù Ø§Ø² Ø§ÙØªÙØ§Û Ú©ÙÙ
+Ø§Øª
+ÚØŽÙ
+ ÙŸÙØŽÛ ØŽÙØ¯ ÛØ§ Ø®ÛØ± . Ù
+Ù
+Ú©Ù Ø§Ø³Øª Ø¬Ø¹ØšÙ ÙŸØ±Ø³ Ù Ø¬ÙÛ ØšØ²Ø±Ú¯Û ÙØ§Ø²Ù
+ Ø¯Ø§ØŽØªÙ ØšØ§ØŽØ¯ Ú©Ù ØšØªÙØ§ÙÛØ¯ Ø¬Ø³ØªØ¬ÙÛ Ù
+ØªÙÙ ÙŸØ§Ø±Ø§Ú¯Ø±Ø§ÙÛ
+Ø§ÙØ¬Ø§Ù
+ Ø¯ÙÛØ¯ . Ø¬Ø³ØªØ¬ÙÛ Ù
+ÙØ§Ø¯ÛØ± Ø²ÛØ§Ø¯Û Ù
+ØªÙ ØšØ³ÛØ§Ø± Ø³Ø±ÛØ¹ Ø§Ø³Øª .
+
+<p>ØšØ±Ø§Û Ù
+Ø«Ø§Ù Ø§Ú¯Ø±  <i>ÚØŽÙ
+ ÙŸÙØŽÛ Ø§Ø² Ø­Ø§ÙØª Ø­Ø±ÙÙ</i> Ù
+<i>ÚØŽÙ
+ ÙŸÙØŽÛ Ø§Ø² Ø§ÙØªÙØ§Û Ú©ÙÙ
+Ø§Øª</i> Ø§ÙØªØ®Ø§Øš ØŽØ¯Ù ØšØ§ØŽÙØ¯ , Ø¬Ø³ØªØ¬ÙÛ<p>
+    <ul><kbd>African building</kbd></ul>
+      <p>Ø¯Ø±Ø³Øª Ù
+Ø§ÙÙØ¯<p>
+      <ul><kbd>africa builds</kbd></ul> Ø®ÙØ§ÙØ¯ ØšÙØ¯<p>
+      Ø²ÛØ±Ø§ Ø­Ø±Ù ØšØ²Ø±Ú¯ "African" ØšÙ Ú©ÙÚÚ© ØªØšØ¯ÛÙ Ø®ÙØ§ÙØ¯ ØŽØ¯, 
+  Ù ÙŸØ³ÙÙØ¯  "n" Ù "ing" Ø­Ø°Ù Ø®ÙØ§ÙÙØ¯ ØŽØ¯
+      "African" Ù "building" ÙÙ
+ ØšÙ ÙÙ
+ÛÙ ØªØ±ØªÛØš (ÙÙ
+ÚÙÛÙ, "s" Ø§Ø²
+      "builds" Ø­Ø°Ù Ø®ÙØ§ÙØ¯ ØŽØ¯).
+
+<p>
+ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ ØšÙ Ø­Ø§ÙØª ÙŸØ±Ø³ Ù Ø¬ÙÛ ÙŸÛØŽØ±ÙØªÙ ØšØ±ÙÛØ¯ Ú©Ù Ø¯Ø± Ø¢Ù ÙØ§Ø¯Ø± Ø®ÙØ§ÙÛØ¯ ØšÙØ¯ Ø§Ø² Ø¹Ù
+ÙÚ¯Ø±ÛÙØ§Û Ù& ÛØ§ | Ù ÙÙ! 
+Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛØ¯ ØªØ§ ÙŸØ±Ø³ Ù Ø¬ÙÛÙØ§Û Ø¯ÙÛÙ ØªØ±Û Ø¯Ø§ØŽØªÙ ØšØ§ØŽÛØ¯ . ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù Ø±Ø§ ÙØ¹Ø§Ù Ú©ÙÛØ¯ 
+ØªØ§ Ø¢Ø®Ø±ÛÙ Ø¬Ø³ØªØ¬ÙÙØ§Û Ø®ÙØ¯ Ø±Ø§ ØšØšÛÙÛØ¯ . ØšÙ Ø§ÛÙ Ø·Ø±ÛÙ Ù
+Û ØªÙØ§ÙÛØ¯ Ø¬Ø³ØªØ¬ÙÙØ§Û Ø®ÙØ¯ Ø±Ø§ Ø§ØµÙØ§Ø­ Ù Ù
+ÙØ±Ø¯ 
+Ø§Ø³ØªÙØ§Ø¯Ù Ù
+Ø¬Ø¯Ø¯ ÙØ±Ø§Ø± Ø¯ÙÛØ¯ . Ø¯Ø± Ø¢Ø®Ø± ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ ØªØ¹Ø¯Ø§Ø¯ ÙØªØ§ÛØ¬ ØšØ±Ú¯ØŽØªÛ Ù ØªØ¹Ø¯Ø§Ø¯ ÙÙ
+Ø§ÛØŽ ÙØŽØ§Ù Ø¯Ø§Ø¯Ù ØŽØ¯Ù Ø¯Ø± 
+ÙØ± ØµÙØ­Ù Ø±Ø§ Ù
+Ø¹ÛÙ Ú©ÙÛØ¯ .}  
+
+
+
+
+ 
+
+
+_textsearchtypeprefsplain_ [l=prs] {Ø§ÛÙ Ù
+Ù
+Ú©Ù Ø§Ø³Øª Ú©Ù ÛÚ© ØšÚ©Ø³ Ú©ÙØ§Ù ÙŸØ±Ø³ ÙØ¬Ù Ø±Ø§ØšØ¯Ø³Øª Ø¢Ø±ÛØ¯Ø ÙÙÙØ°Ø§ ØŽÙ
+Ø§ ØšÙ Ø¢Ø³Ø§ÙÛ Ù
+ÛØªÙØ§ÙÛØ¯ Ú©Ù paragraph-sizedØ¬Ø³ØªØ¬Ù ÙÙ
+Ø§ØŠÛØ¯. Ø§ÛÙ ÙØ§ØšÙ ØªØ¹Ø¬Øš Ø³Ø±ÛØ¹ Ø¬Ø³ØªØ¬Ù ØšØ±Ø§Û ÛÚ© Ù
+ÙØ¯Ø§Ø± Ø²ÛØ§Ø¯ Ù
+ØªÙÙ Ù
+ÛØšØ§ØŽØ¯.}  
+
+_textsearchtypeprefsform_ [l=prs] {ØŽÙ
+Ø§ Ù
+ÛØªÙØ§ÙÛØ¯ Ú©Ù ÙÙ
+Ø±Ù ÙÛÙØ¯ Ø±Ø§ Ú©Ù Ø¯Ø± ÙÙØ±Ù
+ Ø¬Ø³ØªØ¬Ù ÙØŽØ§Ù Ø¯Ø§Ø¯Ù ØŽØ¯Ù ØªØºÛØ± Ø¯ÙÛØ¯.}  
+
+
+
+
+
+_texttanumbrowseoptions_ [l=prs] {ØšØ±Ø§Û ÛØ§ÙØªÙ Ø§Ø·ÙØ§Ø¹Ø§Øª Ø¯Ø± Ø§ÛÙ Ù
+Ø¬Ù
+ÙØ¹Ù _numbrowseoptions_ Ø±Ø§Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ .}  
+
+_textsimplehelpheading_ [l=prs] {ÚÚ¯ÙÙÙ Ø§Ø·ÙØ§Ø¹Ø§ØªÛ Ø¯Ø±Ù
+Ø¬Ù
+ÙØ¹Ù _collectionname_ ØšÛØ§ØšÛÙ
+ }  
+
+_texthelpscopetitle_ [l=prs] {Ù
+Ø­Ø¯ÙØ¯Ù ÙŸØ±Ø³ Ù Ø¬ÙÙØ§}  
+_texthelpscope_ [l=prs] {<p>
+ Ø¯Ø± Ø§ØºÙØš Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ Ø§ÛÙØ¯Ú©Ø³ ÙØ§Û Ù
+Ø®ØªÙÙÛ Ø±Ø§ ØšØ±Ø§Û Ø¬Ø³ØªØ¬Ù Ø§ÙØªØ®Ø§Øš Ú©ÙÛØ¯ . ØšØ±Ø§Û Ù
+Ø«Ø§Ù
+Ø§ÛÙØ¯Ú©Ø³ ÙØ§Û ÙÙÛØ³ÙØ¯Ù ÛØ§ Ø¹ÙÙØ§Ù . ÛØ§ ØŽØ§ÛØ¯ ÙØµÙ Ù ÙŸØ§Ø±Ø§Ú¯Ø±Ø§Ù . Ù
+Ø¹Ù
+ÙÙØ§ 
+Ù
+ØªÙ Ú©Ø§Ù
+ÙØ§ Ù
+Ø·Ø§ØšÙ ØšØ¯ÙÙ ØªÙØ¬Ù ØšÙ Ø§ÛÙØ¯Ú©Ø³ Ù
+ÙØ±Ø¯ ÙØžØ± ØŽÙ
+Ø§ ØšÙ Ø¯Ø³Øª Ù
+Û Ø¢ÛØ¯ .
+<p>Ø§Ú¯Ø± Ø§Ø³ÙØ§Ø¯ Ú©ØªØ§Øš ØšØ§ØŽÙØ¯ Ø¯Ø± Ù
+Ø­Ù Ù
+ÙØ§Ø³Øš ØšØ§Ø² Ø®ÙØ§ÙÙØ¯ ØŽØ¯.
+}  
Index: /gsdl/stable/macros/dateqry.dm
===================================================================
--- /gsdl/stable/macros/dateqry.dm	(revision 20131)
+++ /gsdl/stable/macros/dateqry.dm	(revision 20131)
@@ -0,0 +1,144 @@
+# this file must be UTF-8 encoded
+
+package query
+
+
+#######################################################################
+# Macros whose values are set from within the server at runtime. These 
+# are here only for reference and to set default values if required.           
+#######################################################################
+
+_quotedquery_ {}
+_freqmsg_ {}
+_resultline_ {}
+_thisfirst_ {}
+_thislast_ {}
+_nextfirst_ {}
+_nextlast_ {}
+_prevfirst_ {}
+_prevlast_ {}
+_searchhistorylist_ {}
+
+_imagethispage_ {_labelSearch_}
+
+#######################################################################
+# icons
+#######################################################################
+
+_queryresultsbar_ {
+<div class="divbar">
+<p class="navbar">_texthresults_</p>
+</div>
+}
+
+# _iconnext_ and _iconprev_ are overridden in this package as we
+# don't want alt text here
+_iconnext_{<img src="_httpiconmore_" width=_widthmore_ height=_heightmore_ border=0 align=top>}
+_iconnext_ [v=1] {}
+_iconprev_{<img src="_httpiconless_" width=_widthless_ height=_heightless_ border=0 align=top>}
+_iconprev_ [v=1] {}
+
+
+
+#######################################################################
+# page content
+#######################################################################
+
+_pagetitle_ {_If_(_cgiargq_,_textquerytitle_,_textnoquerytitle_)}
+
+_content_ {
+_optnavigationbar_
+
+_queryform_
+_If_(_searchhistorylist_,<center>
+_searchhistorylist_
+</center>)
+_If_(_cgiargq_,_queryresultsbar_
+<small>
+_freqmsg_
+_textpostprocess_</small><br>
+,<center><div class="divbar">&nbsp;</div></center>)<br>
+_resultline_<p>
+}
+
+_queryform_ {
+<!-- query form -->
+<form name=QueryForm method=get action="_gwcgi_">
+
+<input type=hidden name="a" value="q">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="r" value="1">
+<input type=hidden name="hs" value="1">
+<input type=hidden name="g" value="Document" 
+<center>
+<table><tr><td>
+<nobr>
+	_textselect_<br>
+<nobr>	
+</tr></td>
+<tr><td>
+<nobr>
+	<center>
+	<input type="text" name="q" value="_cgiargq_" size="50">
+	<input type="submit" value="_textbeginsearch_">
+	</center>
+</nobr>
+</tr></td>
+<tr><td>
+	_textdatesearch_<br>
+</tr></td>
+<tr><td>
+	<center>
+_textstartdate_
+<input type="text" name="ds" value = "_cgiargds_"size="4" maxlength="4">
+<select name="dsbc" value="_cgiargdsbc_" size="1">
+	<option value = "0"_If_(_cgiargdsbc_,, selected)>_textad_
+	<option value = "1"_If_(_cgiargdsbc_, selected)>_textbc_
+</select> 
+_textenddate_
+<input type="text" name="de" value = "_cgiargde_" size="4" maxlength="4"> 
+<select name="debc" size="1">
+	<option value = "0" _If_(_cgiargdebc_,, selected)>_textad_
+	<option value = "1" _If_(_cgiargdebc_, selected)>_textbc_
+</select> 
+</center>	  
+</tr></td>
+<tr><td>
+_textexplaineras_
+</tr></td>
+</table>
+</center>
+</form>
+<!-- end of query form -->
+}
+
+_textselect_ {_If_(_cgiargb_,_textadvancedsearch_,_textsimplesearch_)}
+
+# we want to put the links to previous/next pages of results
+# in the footer
+_pagefooterextra_ {
+<center>
+<table cellspacing=0 cellpadding=0 width=_pagewidth_>
+<tr>
+<td align=left>_If_(_prevfirst_,<a href="_httpquery_&r=_prevfirst_">_iconprev__textmatches__prevfirst_ - _prevlast_</a>)</td>
+<td align=right>_If_(_nextfirst_,<a href="_httpquery_&r=_nextfirst_">_textmatches__nextfirst_ - _nextlast__iconnext_</a>)</td>
+</tr></table>
+</center>
+}
+
+_querytypeselection_ {
+<select name="t">
+<option value="1"_If_(_cgiargt_, selected)>_textsome_
+<option value="0"_If_(_cgiargt_,, selected)>_textall_
+</select>
+}
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/macros/deposit.dm
===================================================================
--- /gsdl/stable/macros/deposit.dm	(revision 20131)
+++ /gsdl/stable/macros/deposit.dm	(revision 20131)
@@ -0,0 +1,792 @@
+# this file must be UTF-8 encoded
+
+package depositor
+
+_imagethispage_ {<a href="_httppagedepositor_">_textdepositor_</a>}
+
+# _pagescriptextra_ will be set to the appropriate _***scriptextra_
+# macro from within the server
+_pagescriptextra_ {}
+
+# a plain header for those pages that need it (the _pagebanner_ macro
+# will be set to this by the server for those pages.
+_plainbanner_ {}
+
+# dont want links to help" or "preferences" pages from within
+# collector
+_globallinks_ {_homelink_}
+
+# metadata fields that will be displayed in the step1 page, 
+# this is determined by the depositormetadata macro defined in the collection's collect.cfg
+_metadataconf_ {var DepositorMDFields = new Array();}
+
+# store any existing metadata values
+_cachedmetadatavalues_ {var CachedMDValues = new Array();}
+
+#######################################################################
+# steps
+
+_numsteps_ {3}
+
+# clashes with general text (in english2.dm) about what to do at this stage
+# now it doesn't appear in wizard bar, is it needed?
+##_textselect_ {The Depositor}
+_textstep1_ {_textmeta_}
+_textstep2_ {_textintro_}
+_textstep3_ {_textconfirm_}
+
+_laststep_ {bild}
+_textlaststep_ {_textbild_}
+
+
+#######################################################################
+# icons
+
+_iconcross_ {<img src="_httpimg_/cross.gif">}
+_iconcross_ [v=1] {<b>no</b>}
+_icontick_ {<img src="_httpimg_/tick.gif">}
+_icontick_ [v=1] {<b>yes</b>}
+_iconblank_ {<img src="_httpimg_/blank.gif">}
+_iconblank_ [v=1] {}
+
+_imagemore_ {<a href="javascript:more()" onMouseover="roll('more',1);" onMouseOut="roll('more',0);"><img
+name="more" src="_httpimg_/moreof.gif" onLoad="gbutton(this,'_httpimg_/moreon.gif');" border=0 alt="_textmore_"
+title="_textmore_" align=top></a>}
+_imagemore_ [v=1] {_textmore_}
+
+_icongreyarrow_ {<img src="_httpimg_/grarrow.gif">}
+_icongreyuparrow_ {<img src="_httpimg_/guarrow.gif">}
+_iconstop_ {<img src="_httpimg_/stop.gif" border=0>}
+
+
+#######################################################################
+# http macros 
+
+_httpinfo_ {_gwcgi_?e=_compressedoptions_&p=info}
+_httpsrce_ {_gwcgi_?e=_compressedoptions_&p=srce}
+_httpconf_ {_gwcgi_?e=_compressedoptions_&p=conf}
+_httpbild_ {_gwcgi_?e=_compressedoptions_&p=bild}
+_httpview_ {_gwcgi_?a=p&p=about&c=_cgiargdi1dirname_}
+_httpdel_  {javascript:do\_delete();}
+_httpexpt_ {_gwcgi_?e=_compressedoptions_&p=expt}
+
+
+#######################################################################
+# select // this really should be intro
+#######################################################################
+
+# _fullnamemenu_ has previous collection selected. Since there is no button
+# on this page to proceed, we reset the drop down box to have no collection
+# selected.
+_selectheader_ {_cgihead_
+_htmlhead_(class="bgimage" onLoad="initialize();")_startspacer_
+}
+
+
+_selectscriptextra_ {
+
+function initialize() \{
+  document.depositorform.di1dirname.value = "";
+\}
+
+function check\_submit (gotopage) \{
+  var form = document.depositorform;
+  form.p.value = gotopage;
+
+  // if 'dirname' given, then link to cgiarg c so collection specific macros work
+  if (form.di1dirname) \{
+    form.c.value = form.di1dirname.value;
+  \}
+
+  form.submit();
+\}
+
+function menuchange() \{
+
+  _buildtypearray_
+
+  var form = document.depositorform;
+
+  if (form.di1dirname.value == "") \{
+    alert("Please choose a collection first");
+  \}
+  else \{
+    var pos = form.di1dirname.selectedIndex;
+    var bt = buildtype[pos];
+    if (bt=="") \{ bt = "mg"; \}
+    form.di1buildtype.value = bt;
+
+    check\_submit('step1');  
+  \}
+\}
+
+}
+
+_selectcontent_ {
+<form name="depositorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="intro">
+<input type=hidden name="c" value="">
+<input type=hidden name="di1buildtype" value="">
+
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center><h2>_textselect_</h2></center>
+<div class="divbar">&nbsp;</div>
+
+<p> <em>_textselectcol_</em>
+
+<p>_fullnamemenu_<br><br>
+<div class="divbar">&nbsp;</div>
+</td></tr>
+</table>
+</center>
+</form>
+}
+
+
+#######################################################################
+# step 1
+#######################################################################
+
+#here goes the "memorization" macros for each form field.  
+#_di1md.Title_ {_If_("_:cgiargdi1md.Title_" eq  "_cgiargdi1md.Title_",_cgiargdi1md.Title_,)}
+#_di1md.Creator_ {_If_("_:cgiargdi1md.Creator_" eq  "_cgiargdi1md.Creator_",_cgiargdi1md.Creator_,)}
+#_di1md.Description_ {_If_("_:cgiargdi1md.Description_" eq  "_cgiargdi1md.Description_",_cgiargdi1md.Description_,)}
+#_di1md.Subject_ {_If_("_:cgiargdi1md.Subject_" eq "_cgiargdi1md.Subject_",_cgiargdi1md.Subject,)}
+
+_step1scriptextra_ {
+
+_metadataconf_
+_cachedmetadatavalues_
+
+function loadForm() \{
+
+	var formcontainer = document.getElementById('formcontainer');
+	
+	if (!formcontainer) \{
+		return;
+	\}
+	
+	for (i=0; i < DepositorMDFields.length; i++) \{
+		if (DepositorMDFields[i]==null) \{
+			continue;
+		\}
+		metadataField = DepositorMDFields[i];
+		
+		var labelCell = document.createElement("td");
+		labelCell.innerHTML = metadataField.label + ": ";
+		labelCell.setAttribute("title", metadataField.tooltip);							
+
+		var cachedValue;
+		if(CachedMDValues[0] !=null && CachedMDValues[0]["di1md." + metadataField.name])\{
+			cachedValue = CachedMDValues[0]["di1md." + metadataField.name];
+		\} else \{
+			cachedValue = "";
+		\}
+		
+		var inputObj; 
+		if (metadataField.type=="text") \{
+			inputObj = document.createElement("input");				
+			inputObj.setAttribute("type","text");			
+			inputObj.setAttribute("size","74");	
+			inputObj.setAttribute("value", cachedValue);
+		\} 
+		else if (metadataField.type=="textarea") \{
+			inputObj = document.createElement("textarea");				
+			inputObj.setAttribute("rows","5");
+			inputObj.setAttribute("cols", "40");
+			inputObj.innerHTML = cachedValue;
+		\}	
+		inputObj.setAttribute("name", "di1md."+ metadataField.name);		
+		
+		var inputCell = document.createElement("td");
+		inputCell.appendChild(inputObj);		
+								
+		var entry = document.createElement("tr");	
+		entry.appendChild(labelCell);
+		entry.appendChild(inputCell);
+		
+		formcontainer.appendChild(entry);
+	\}
+\}
+
+function check\_submit (gotopage) \{
+  var form = document.depositorform;
+  form.p.value = gotopage;
+  form.submit();
+\}
+
+if (window.addEventListener) window.addEventListener("load", loadForm, false);
+else if (window.attachEvent) window.attachEvent("onload", loadForm);
+
+}
+
+_step1content_ {
+
+<form name="depositorform" method=post action="_gwcgi_" enctype="multipart/form-data">
+
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+
+
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center>
+<h2>_textstep1_</h2>
+<p>_textdepositorblurb_
+</center>
+<div class="divbar">&nbsp;</div>
+<ul>
+
+<!--input goes here-->
+<!--dynamic load the metadata elements as configured in the collection's collect.cfg-->
+<p><table id="formcontainer"></table>
+
+<div class="divbar">&nbsp;</div>
+</td></tr>
+<tr><td>_depositorbar_</td></tr>
+</table></center>
+
+</form>
+
+}
+
+#######################################################################
+# step 2
+#######################################################################
+
+_userfile_ {_If_("_:cgiargdi1userfile_" eq  "_cgiargdi1userfile_",_cgiargdi1userfile_,)}
+
+_step2scriptextra_ {
+
+function check\_submit (gotopage) \{
+  var form = document.depositorform;
+  form.p.value = gotopage;
+  form.submit();
+\}
+}
+
+_step2content_ {
+<form name="depositorform" method=post action="_gwcgi_" enctype="multipart/form-data">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center><h2>_textstep2_</h2></center>
+<div class="divbar">&nbsp;</div>
+<p>_textfilename_: <input type=file name=di1userfileinfo value="_userfile_"></p>
+<div class="divbar">&nbsp;</div>
+</td></tr>
+<tr><td>_depositorbar_</td></tr>
+</table>
+</center>
+</form>
+}
+
+#######################################################################
+# step 3
+#######################################################################
+
+#here goes the "memorization" macros for each form field.  
+#_di1_ {_If_("_:cgiargdi1md.Title_" eq  "_cgiargdi1md.Title_",_cgiargdi1md.Title_,)}
+#_di1md.Creator_ {_If_("_:cgiargdi1md.Creator_" eq  "_cgiargdi1md.Creator_",_cgiargdi1md.Creator_,)}
+
+_step3scriptextra_ {
+
+function check\_submit (gotopage) \{
+  var form = document.depositorform;
+  form.p.value = gotopage;
+  form.submit();
+\}
+}
+
+_step3content_ {
+<form name="depositorform" method=post action="_gwcgi_" enctype="multipart/form-data">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center><h2>_textstep3_</h2></center>
+<div class="divbar">&nbsp;</div>
+<p>_textfilename_: _di1userfile_ </p>
+<p>_textfilesize_: _di1userfilesize_ </p> 
+<div class="divbar">&nbsp;</div>
+</td></tr>
+<tr><td>_depositorbar_</td></tr>
+</table>
+</center>
+</form>
+}
+
+#######################################################################
+# bild (main frameset for build page)
+#######################################################################
+
+_bildcontent_ {
+<html>
+<head>
+<!--
+<script>
+function check\_submit (gotopage) \{
+  var form = document.depositorform;
+  form.p.value = gotopage;
+  form.submit();
+\}
+</script>
+-->
+</head>
+
+<form name="depositorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+
+<frameset rows="*,160" border=0>
+  <noframes><body bgcolor="#ffffff">
+  <p>You must have a frame enabled browser to obtain feedback
+  on how the building process is progressing. The collection <i>will</i>
+  continue to build as normal however.</p>
+
+  <table>
+  <tr valign=center><td>
+  To stop the building process at any time, click here.
+  <br>The collection you are working on will remain intact.
+  </td>
+  <td><input type="submit" value="stop building"></td>
+  </table>
+
+  </body>
+  </noframes>
+  <frame src="_gwcgi_?e=_compressedoptions_&p=bildframe1">
+  <frame src="_gwcgi_?e=_compressedoptions_&p=bildstatus">
+</frameset>
+</html>
+}
+
+#######################################################################
+# bildframe1
+#######################################################################
+
+# header overridden to allow base target to be set
+
+_bildframe1header_ {_cgihead_
+<html>
+<head>
+<base target=_top>
+<title>_pagetitle_</title>
+_globalscripts_
+_cssheader_
+</head>
+<body class="bgimage">
+_startspacer__pagebanner_
+}
+
+
+_bildframe1header_[v=1] {_cgihead_
+<html>
+<head>
+<base target=_top>
+<title>_pagetitle_</title>
+_globalscripts_
+</head>
+<body class="bgimage">
+_pagebanner_
+}
+
+_bildframe1scriptextra_ {}
+
+_bildframe1content_ {
+<form name="depositorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="bildcancel">
+
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center>
+<h2>_textbild_</h2>
+</center>
+<div class="divbar">&nbsp;</div>
+<p>
+_depositor:textbild1_
+<p>
+
+<table>
+<tr valign=center><td>
+_depositor:textbild2_
+</td>
+<td><input type="submit" value="_depositor:textstopbuild_"></td>
+</table>
+
+<p>
+_depositor:textbild3_
+</td></tr>
+</table></center>
+</form>
+}
+
+
+#######################################################################
+# bildcancel
+#######################################################################
+
+_bildcancelscriptextra_ {
+function check\_submit (gotopage) \{
+  var form = document.depositorform;
+  form.p.value = gotopage;
+  form.submit();
+\}
+}
+_bildcancelcontent_ {
+<form name="depositorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+
+</form>
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center>
+<h2>_depositor:textbuildcancelled_</h2>
+</center>
+<div class="divbar">&nbsp;</div>
+<p>
+_depositor:textbildcancel1_
+<p><center>
+_depositorbar_
+</center>
+
+</td></tr>
+</table></center>
+}
+
+
+#######################################################################
+# bildstatus
+#######################################################################
+
+# special header for status page
+_bildstatusheader_ {_cgihead_
+_htmlhead_(class="bgimage" onLoad="initialize();")_startspacer_
+}
+_bildstatusheader_[v=1] {_cgihead_
+_htmlhead_(onLoad="initialize();")
+}
+
+_bildstatusscriptextra_ {
+var timer = 5;
+function initialize() \{
+  setTimeout("count_down()",1000);
+\}
+
+function count_down() \{
+  if (timer==0) \{
+    window.status = "";
+    document.depositorform.submit();
+  \} else \{
+    if (timer==1) \{
+	window.status = "_textbsupdate1_";
+    \} else \{
+	window.status = "_textbsupdate2_ "+timer+" _textseconds_";
+    \}
+    timer--;
+    setTimeout("count_down()",1000);
+  \}	
+\}
+}
+
+_bildstatuscontent_ {
+<form name="depositorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+
+<center>
+<table width=_pagewidth_>
+<tr><td><center>
+_statusline_
+</center>
+</td></tr>
+</table></center>
+</form>
+}
+
+
+#######################################################################
+# bilddone
+#######################################################################
+
+_bilddoneheader_ {_cgihead_
+_htmlhead_(class="bgimage")_startspacer_
+}
+_bilddonescriptextra_ {
+
+function check\_submit (gotopage) \{
+  var form = document.depositorform;
+  form.p.value = gotopage;
+  form.submit();
+\}
+
+}
+
+
+_bilddonecontent_ {
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<p>_textbildsuc_
+
+<p>_textviewbildsummary_
+
+<p><center>
+_depositorbar_
+</center>
+
+</td></tr>
+</table></center>
+}
+
+
+#######################################################################
+# bildfail
+#######################################################################
+
+_bildfailheader_ {_cgihead_
+_htmlhead_(class="bgimage")_startspacer_
+}
+_bildfailscriptextra_ {
+function check\_submit (gotopage) \{
+  var form = document.depositorform;
+  form.p.value = gotopage;
+  form.submit();
+\}
+}
+_bildfailcontent_ {
+<form name="depositorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="p" value="_cgiargp_">
+
+</form>
+
+<table width=_pagewidth_>
+<tr><td>
+_textfailmsg_
+</td></tr>
+<tr><td>
+</td></tr>
+</table></center>
+}
+
+# _textfailmsg_ will be set to one of the following macros from within
+# the server
+
+_textfailmsg1_ {
+_textfailmsg11_
+<p><center>
+_depositorbar_
+</center>
+}
+
+_textfailmsg6_ {_textfailmsg1_}
+
+_textfailmsg2_ {
+_textfailmsg21_
+<p>_textblcont_
+<p>_faillog_
+<p>_texttryagain_
+}
+
+_textfailmsg3_ {
+_textfailmsg31_
+<p>_textblcont_
+<p>_faillog_
+<p>_texttryagain_
+}
+
+_textfailmsg4_ {
+_textfailmsg41_
+<p>_textblcont_
+<p>_faillog_
+}
+
+_textfailmsg5_ {_textfailmsg4_}
+
+_textfailmsg7_ {
+_textfailmsg71_
+<p>_texttryagain_
+}
+
+#######################################################################
+# Error and message pages
+#######################################################################
+
+_messagehead_ {
+<form name="depositorform" method=post action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+
+<center>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+}
+
+_messagefoot_ {
+<p>
+<a href="javascript:document.depositorform.submit();">_textretcoll_</a>
+<div class="divbar">&nbsp;</div>
+</td></tr>
+</table></center>
+</form>
+}
+
+_messagefootnolink_ {
+<div class="divbar">&nbsp;</div>
+</td></tr>
+</table></center>
+</form>
+}
+
+#_delpermissioncontent_ {
+#_messagehead_
+#<p>
+#_textdelperm_
+#_messagefoot_
+#}
+
+#_delinvalidcontent_ {
+#_messagehead_
+#<p>
+#_textdelinv_
+#_messagefoot_
+#}
+
+#_delsuccesscontent_ {
+#_messagehead_
+#<p>
+#_textdelsuc_
+#_messagefoot_
+#}
+
+#_clonefailcontent_ {
+#_messagehead_
+#<input type=hidden name="bc1clone" value="0">
+#<p>_textclonefail_
+#_messagefoot_
+#}
+
+_genericcontent_ {
+_messagehead_
+<p>_textcolerr_
+_messagefoot_
+}
+
+_tmpfailcontent_ {
+_messagehead_
+<p>
+_texttmpfail_
+_messagefoot_
+}
+
+#_mkcolfailcontent_ {
+#_messagehead_
+#<p>_textmkcolfail_
+#_messagefoot_
+#}
+
+_nocollectioncontent_ {
+_messagehead_
+<p>_textnocontent_
+<br><a href="_httppagedepositor_">_textrestart_</a>
+<p>
+_messagefootnolink_
+}
+
+#_reloaderrorcontent_ {
+#_messagehead_
+#<p>_textreloaderror_
+#<br><a href="_httppagedepositor_">_textrestart_</a>
+#<p>
+#_messagefootnolink_
+#}
+
+_exptscriptextra_ {}
+
+#_exptsuccesscontent_ {
+#_messagehead_
+#<input type=hidden name=p value=existing>
+#<p>_textexptsuc_
+#_messagefoot_
+#}
+
+#_exptfailcontent_ {
+#_messagehead_
+#<input type=hidden name=p value=existing>
+#_textexptfail_
+#_messagefoot_
+#}
+
+#######################################################################
+# depositonly
+#######################################################################
+
+_depositonlyscriptextra_ {}
+
+_depositonlycontent_ {
+
+<center>
+<em>Thanks for using the Depositor! Cick <a href="_gwcgi_">here</a> to return to the Greenstone home page. </em>
+<table width=_pagewidth_>
+<tr><td>
+<div class="divbar">&nbsp;</div>
+<center><h2>_textstep3_</h2></center>
+<div class="divbar">&nbsp;</div>
+<p>_textfilename_: _di1userfile_ </p>
+<p>_textfilesize_: _di1userfilesize_ </p> 
+<div class="divbar">&nbsp;</div>
+</td></tr>
+<tr><td></td></tr>
+</table>
+</center>
+
+}
+
+###################################################
+## text macros that are defined by another package
+###################################################
+
+
+_textbsupdate1_ {_wizard:textbsupdate1_}
+_textbsupdate2_ {_wizard:textbsupdate2_}
+_textseconds_ {_wizard:textseconds_}
+
+_textbildsuc_ {_wizard:textbildsuc_}
+_textviewbildsummary_ {_wizard:textviewbildsummary_}
+
+_textview_ {_wizard:textview_}
+_textbild1_ {_wizard:textbild1_}
+
+_textbild2_ {_wizard:textbild2_}
+
+_textstopbuild_ {_wizard:textstopbuild_}
+
+_textbild3_ {_wizard:textbild3_}
+
+_textbuildcancelled_ {_wizard:textbuildcancelled_}
+
+_textbildcancel1_ {_wizard:textbildcancel1_}
+
+_textfailmsg11_ {_wizard:textfailmsg11_}
+_textfailmsg21_ {_wizard:textfailmsg21_}
+_textblcont_ {_wizard:textblcont_}
+
+_textfailmsg31_ {_wizard:textfailmsg31_}
+_textfailmsg41_ {_wizard:textfailmsg41_}
+_textfailmsg71_ {_wizard:textfailmsg71_}
Index: /gsdl/stable/macros/docs.dm
===================================================================
--- /gsdl/stable/macros/docs.dm	(revision 20131)
+++ /gsdl/stable/macros/docs.dm	(revision 20131)
@@ -0,0 +1,34 @@
+# this file must be UTF-8 encoded
+
+package docs
+
+# set from within server
+_documentation_ {}
+
+#######################################################################
+# global navigation links
+#######################################################################
+
+_globallinks_ {_homelink_}
+
+#######################################################################
+# page content
+#######################################################################
+
+_httpdocs_ {_httpprefix_/docs}
+
+_pagetitle_ {_home:textgsdocs_ - _textdescrgreenstone_}
+
+_content_ {
+<div id="content">
+<div class="divbar">
+<p class="navbar">
+_textgsdocstitle_
+</p>
+</div>
+
+_If_(_documentation_,_documentation_,_textnodocumentation_)
+
+_nzdlpagefooter_
+</div>
+}
Index: /gsdl/stable/macros/document.dm
===================================================================
--- /gsdl/stable/macros/document.dm	(revision 20131)
+++ /gsdl/stable/macros/document.dm	(revision 20131)
@@ -0,0 +1,518 @@
+# this file must be UTF-8 encoded
+
+package document
+
+#######################################################################
+# macros set from within the server
+#######################################################################
+
+_imagethispage_ {}
+_httpprevarrow_ {}
+_httpnextarrow_ {}
+_pagetitle_ {}
+_phindclassifier_ {}
+_collageclassifier_ {}
+
+# custom header for individual document
+_documentheader_ {} 
+
+#custom css links for individual document
+_csslink_{
+   <link rel="stylesheet" href="_cssfilelink_" type="text/css" 
+    charset="UTF-8"   _linktagend_ 
+  <link rel="alternate stylesheet" href="_httpstyle_/preview-document.css" 
+    type="text/css" 
+    title="Preview Document" charset="UTF-8" media="screen"  _linktagend_
+   <link rel="stylesheet" href="_httpstyle_/print-document.css" type="text/css"
+    charset="UTF-8" media="print"  _linktagend_ 
+}
+
+#######################################################################
+# page content
+#######################################################################
+
+_tocopen_ {<div class="top" _tocopenextra_>}
+_tocclose_ {</div>}
+
+_nextsearchresult_ {_If_("_cgiargsrn_" ne "0",<li id="nextresult"><a href="_httpquery_&amp;ifl=1&amp;ifln=_cgiargsrn_">_textnextsearchresult_</a></li>)}
+
+_prevsearchresult_ {_If_("_cgiargsrp_" ne "0",<li id="prevresult"><a href="_httpquery_&amp;ifl=1&amp;ifln=_cgiargsrp_">_textprevsearchresult_</a></li>)}
+
+_content_ {
+_optnavigationbar_
+
+_If_(_phindclassifier__collageclassifier_,
+<p style="text-align: center;">
+_phindclassifier_
+_collageclassifier_
+</p>
+)
+
+_If_("_cgiargcl_" eq "search",
+<ul id="searchresults">
+_prevsearchresult_
+_nextsearchresult_
+</ul>)
+
+<div class="document">
+
+
+}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitlepage_ {_texticonhtitle_}
+_textCreatorpage_ {_texticonhcreat_}
+_textSubjectpage_ {_texticonhsubj_}
+_textDescriptionpage_ {_texticonhdesc_}
+_textPublisherpage_ {_texticonhpubl_}
+_textContributorpage_ {_texticonhcontr_}
+_textDatepage_ {_texticonhdate_}
+_textTypepage_ {_texticonhtype_}
+_textFormatpage_ {_texticonhform_}
+_textIdentifierpage_ {_texticonhident_}
+_textSourcepage_ {_texticonhsrc_}
+_textLanguagepage_ {_texticonhlang_}
+_textRelationpage_ {_texticonhrel_}
+_textCoveragepage_ {_texticonhcover_}
+_textRightspage_ {_texticonhright_}
+
+_textTopage_ {_texticonhto_}
+_textFrompage_ {_texticonhfrom_}
+_textSeriespage_ {_texticonhser_}
+_textHowtopage_ {_texticonhhow_}
+_textOrganizationpage_ {_texticonhorg_}
+_textBrowsepage_ {_texticonhbrwse_}
+_textCollagepage_ {_texticonhcoll_}
+_textPeoplepage_ {_texticonhpeople_}
+_textAcronympage_ {_texticonhacronym_}
+_textPhrasepage_ {_texticonhphrases_}
+_textArtistpage_ {_texticonhartist_}
+_textKeywordpage_ {_texticonhkw_}
+_textVolumepage_ {_texticonhvol_}
+_textCaptionspage_ {_texticonhcapt_}
+_textCountriespage_ {_texticonhcount_}
+
+#######################################################################
+# navigation arrows
+#
+#######################################################################
+
+# these two may be reset to "" by the server
+_navarrowsbottom_ {_navarrows_}
+_navarrowstop_ {_navarrows_}
+
+_navarrows_ {<center>
+<table width=_pagewidth_ cellpadding=0 cellspacing=0 border=0>
+<tr><td align=left valign=top>
+_prevarrow_
+</td><td align=right valign=top>
+_nextarrow_
+</td></tr></table>
+</center>
+}
+
+_prevarrow_ {_If_(_httpprevarrow_,<a href="_httpprevarrow_">_iconprev_</a>)}
+_nextarrow_ {_If_(_httpnextarrow_,<a href="_httpnextarrow_">_iconnext_</a>)}
+
+_navarrows_ [v=1] {<p>
+_prevarrow_<br>
+_nextarrow_
+}
+
+#######################################################################
+# the goto form
+#######################################################################
+
+_gotoform_ {
+<form name="GotoForm" method="get" action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="d" value="_cgiargd_">
+<input type=hidden name="cl" value="_cgiargcl_">
+<input type="text" name="gp" size="3" maxlength="4">
+<input type="submit" value="_textgoto_">
+</form>
+}
+
+_textnumpages_ {&nbsp;<i>(_1_ _pages_)</i>}
+_parentarrow_ {}
+_prevtitle_ {}
+_nexttitle_ {}
+
+#######################################################################
+# the phind applet
+#
+# The phind applet is only required on phind classifier pages.
+# Consequently, the _phindclassifier_ macro is not usually set.  On screens
+# where it is required, _phindclassifier_ resolves to _phindapplet_, and
+# the following macro is loaded into the web page.
+#######################################################################
+
+_phindapplet_ {
+<APPLET CODEBASE="_httpjava_" CODE="org.nzdl.gsdl.Phind.Phind.class" ARCHIVE="Phind.jar" WIDTH=500 HEIGHT=400>
+  <PARAM NAME=library      VALUE="_gwcgi_?e=_compressedoptions_">
+  <PARAM NAME=phindcgi     VALUE="_gwcgi_?a=phind">
+  <PARAM NAME=collection   VALUE="_cgiargc_">
+  <PARAM NAME=classifier   VALUE="_phindnumber_">
+
+  <PARAM NAME=orientation  VALUE="vertical">
+  <PARAM NAME=depth        VALUE="2">
+  <PARAM NAME=resultorder VALUE="L,l,E,e,D,d">
+
+  <PARAM NAME=backdrop     VALUE="_httpimg_/phindbg1.jpg">
+  <PARAM NAME=fontsize     VALUE="10">
+  <PARAM NAME=blocksize    VALUE="10">
+
+  The Phind java applet.
+</APPLET>
+}
+
+_collageapplet_ {
+ <applet CODEBASE="_httpjava_" 
+     code="org.nzdl.gsdl.GsdlCollageApplet.GsdlCollageApplet.class"
+     archive="GsdlCollageApplet.jar" 
+     width="_collagexdim_" height="_collageydim_">
+
+        <param name="gwcgi" value="_gwcgi_">
+        <param name="collection" value="_cgiargc_">
+        <param name="classifier" value="_cgiargcl_.1">
+
+        <param name="hrefMustHave" value="cl=_cgiargcl_.1">
+        <param name="imageMustNotHave" value="hl=\%x=\%gt=\%gc=\%.pr">
+
+        <param name="imageType" value="_collageimageType_">
+        <param name="verbosity" value="_collageverbosity_">
+        <param name="maxDepth" value="_collagemaxDepth_">
+        <param name="maxDisplay" value="_collagemaxDisplay_">
+        <param name="refreshDelay" value="_collagerefreshDelay_">
+        <param name="isJava2" value="_collageisJava2_">
+        <param name="bgcolor" value="_collagebgcolor_">
+        <param name="documentroot" value="_httpimg_">	
+ </applet>
+
+<center>
+_collagecaption_
+</center>
+}
+
+
+_flashbook_ {
+ <div id="bookdiv">
+ </div>
+
+ <script type="text/javascript">
+ var myWidth = "100%";
+ myHeight = 800;
+ 
+ var img_cover = '_httpassocdir_/_thisOID_/cover.jpg';
+ var doc_url = document.URL; 
+ doc_url = doc_url.replace(/(&|\\?)book=[a-z]+/gi,'');
+ doc_url += '&book=flashxml'; 
+  
+ var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;//get windows or not
+ //Only for Windows computers because Greenstone webserver doesn't allow us to pass parameters to Flash.
+ //These methods is called by the Flash program to get all the necessary parameters for the book
+ //However, it will only work for IE 5.0 and later, Firefox 1.0 and later, Mozilla 1.7.5 and later
+ //Netscape 8.0 and later, Safari 1.3 and later
+ function getDocURL() \{ return doc_url; \}
+ function getImgCover() \{ return img_cover; \}
+ function getStageW() \{ return -1; \}
+ function getStageH() \{ return -1; \}
+
+
+ var flash_plug_html = "";
+ flash_plug_html += '<OBJECT align="middle" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" \\n';
+ flash_plug_html += '  codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" \\n';
+ flash_plug_html += '  height="';
+ flash_plug_html += myHeight + '" id="Book" swLiveConnect="true" align="middle"\\n';
+ flash_plug_html += '  width="';
+ flash_plug_html += myWidth + '">\\n';
+ 
+ flash_plug_html += '    <PARAM name="allowScriptAccess" value="always" />\\n';
+ flash_plug_html += '    <PARAM name="movie" value="_httpflash_/Book.swf';
+ if (isWin == false) 
+ \{
+    flash_plug_html += '?src_image=' + escape(img_cover);
+    flash_plug_html += '&amp;doc_url=' + escape(doc_url);
+ \}
+ flash_plug_html += '" />\\n';
+ flash_plug_html += '    <PARAM name="quality" value="high" />\\n';
+ flash_plug_html += '    <PARAM name="bgcolor" value="#FFFFFF" />\\n';
+ flash_plug_html += '    <EMBED align="middle" \\n';
+ flash_plug_html += '      allowScriptAccess="always" swLiveConnect="true" \\n';
+ flash_plug_html += '      bgcolor="#FFFFFF" height="';
+ flash_plug_html += myHeight + '" name="Book" \\n';
+ flash_plug_html += '      pluginspage="http://www.macromedia.com/go/getflashplayer" \\n';
+ flash_plug_html += '      quality="high" \\n';
+ flash_plug_html += '      src=\\'_httpflash_/Book.swf';
+ if (isWin == false) 
+ \{
+    flash_plug_html += '?src_image=' + escape(img_cover);
+    flash_plug_html += '&amp;doc_url=' + escape(doc_url);
+ \}
+ flash_plug_html += '\\'\\n'; 
+ flash_plug_html += '      type="application/x-shockwave-flash" width="';
+ flash_plug_html += myWidth + '" />\\n';
+ flash_plug_html += '</OBJECT>\\n';
+
+ var flash_div = document.getElementById("bookdiv");
+ flash_div.innerHTML = flash_plug_html;
+ </script>
+}
+
+#######################################################################
+# icons
+#######################################################################
+
+_iconsmalltext_ {<img src="_httpiconsmtext_" class="icon" width=_widthsmtext_ height=_heightsmtext_ alt="_texticonsmalltext_" title="_texticonsmalltext_">}
+_iconsmalltext_ [v=1] {<small><b>_texticonsmalltext2_</b></small>}
+
+_iconarrowsmalltext_ {<img src="_httpiconasmtext_" class="icon" width=_widthasmtext_ height=_heightasmtext_ alt="_texticonsmalltext_" title="_texticonsmalltext_">}
+_iconarrowsmalltext_ [v=1] {<small><b>->_texticonsmalltext2_</b></small>}
+
+_iconclosedfolder_ {<img src="_httpiconclsdfldr_" class="icon" width=_widthclsdfldr_ height=_heightclsdfldr_ alt="_texticonclosedfolder_" title="_texticonclosedfolder_">}
+_iconclosedfolder_ [v=1] {<small><b>_texticonclosedfolder2_</b></small>}
+
+_iconarrowclosedfolder_ {<img src=_httpiconaclsdfdr_" class="icon" width=_widthaclsdfdr_ height=_heightaclsdfdr_ alt="_texticonclosedfolder_" title="_texticonclosedfolder_">}
+_iconarrowclosedfolder_ [v=1] {<small><b>->_texticonclosedfolder2_</b></small>}
+
+_iconopenfolder_ {<img src="_httpiconopenfldr_" class="icon" width=_widthopenfldr_ height=_heightopenfldr_ alt="_texticonopenfolder_" title="_texticonopenfolder_">}
+_iconopenfolder_ [v=1] {<small><b>_texticonopenfolder2_</b></small>}
+
+_iconarrowopenfolder_ {<img src="_httpiconaopenfdr_" class="icon" width=_widthaopenfdr_ height=_heightaopenfdr_ alt="_texticonopenfolder_" title="_texticonopenfolder_">}
+_iconarrowopenfolder_ [v=1] {<small><b>->_texticonopenfolder2_</b></small>}
+
+_iconarrowclosedbook_ {<img src="_httpiconabook_" width=_widthabook_ height=_heightabook_ class="icon" alt="_texticonclosedbook_" title="_texticonclosedbook_">}
+_iconarrowclosedbook_ [v=1] {<small><b>->_texticonclosedbook_: </b></small>}
+
+_iconopenbook_ {<img src="_httpiconopenbook_" width=_widthopenbook_ height=_heightopenbook_ class="icon" alt="_texticonopenbook_" title="_texticonopenbook_">}
+_iconopenbook_ [v=1] {<small><b>_texticonopenbook_: </b></small>}
+
+_iconarrowopenbook_ {<img src="_httpiconaopenbk_" width=_widthaopenbk_ height=_heightaopenbk_ class="icon" alt="_texticonopenbook_" title="_texticonopenbook_">}
+_iconarrowopenbook_ [v=1] {<small><b>->_texticonopenbook_: </b></small>}
+
+_iconopenbookshelf_ {<img src="_httpiconbshelf_" class="icon" width=_widthbshelf_ height=_heightbshelf_ alt="_texticonopenbookshelf_" title="_texticonopenbookshelf_">}
+_iconopenbookshelf_ [v=1] {<small><b>_texticonopenbookshelf_: </b></small>}
+
+_iconarrowopenbookshelf_ {<img src="_httpiconabshelf_" class="icon" width=_widthabshelf_ height=_heightabshelf_ alt="_texticonopenbookshelf_" title="_texticonopenbookshelf_">}
+_iconarrowopenbookshelf_ [v=1] {<small><b>->_texticonopenbookshelf_: </b></small>}
+
+_iconclosedbookshelf_ {<img src="_httpiconbshelf_" class="icon" width=_widthbshelf_ height=_heightbshelf_ alt="_texticonclosedbookshelf_" title="_texticonclosedbookshelf_">}
+_iconclosedbookshelf_ [v=1] {<small><b>_texticonclosedbookshelf_: </b></small>}
+
+_iconarrowclosedbookshelf_ {<img src="_httpiconabshelf_" class="icon" width=_widthabshelf_ height=_heightabshelf_ alt="_texticonclosedbookshelf_" title="_texticonclosedbookshelf_">}
+_iconarrowclosedbookshelf_ [v=1] {<small><b>->_texticonclosedbookshelf_: </b></small>}
+
+_iconpointer_ {<img src="_httpiconarrrght_" class="icon" width=_widtharrrght_ height=_heightarrrght_>}
+_iconpointer_ [v=1] {<small><b>_texticonpointer_-> </b></small>}
+
+_iconwarning_ {<img src="_httpiconwarning_" width="_widthwarning_" height="_heightwarning_" class="icon" align="left">}
+_iconwarning_ [v=1] {_texticonwarning_}
+
+
+#######################################################################
+# images
+#######################################################################
+
+_coverimage_ {<img alt="Cover Image" onError="src='_httpimg_/blank.gif'" src="_httpassocdir_/_thisOID_/cover.jpg">}
+
+_docbutton_ {<div class="button"><span class="button" title="_3_"><a href="_1_">_2_</a></span></div>
+}
+
+# can't use _docbutton_ macro for detach button as we need to include target
+_imagedetach_ {<div class="button"><span class="button"><a href="_httpcurrentdocument_&amp;x=1" target="\_blank" title="_texticondetach_">_textDETACH_</a></span></div>}
+
+_imageprint_{<div class="button"><span class="button"><a href="javascript:print_preview()">_textPRINT_</a></span></div>}
+
+
+_imagehighlight_ {_docbutton_(_httpcurrentdocument_&amp;hl=1&amp;gc=_cgiarggc_&amp;gt=_cgiarggt_,_textHIGHLIGHT_,_texticonhighlight_)}
+
+_imagenohighlight_ {_docbutton_(_httpcurrentdocument_&amp;hl=0&amp;gc=_cgiarggc_&amp;gt=_cgiarggt_,_document:textNOHIGHLIGHT_,_document:texticonnohighlight_)}
+
+_imagecontracttoc_ {_docbutton_(_httpcurrentdocument_&amp;gc=0,_textCONTRACTCONTENTS_,_texticoncontracttoc_)}
+
+_imageexpandtoc_ {_docbutton_(_httpcurrentdocument_&amp;gc=1,_textEXPANDCONTENTS_,_texticonexpandtoc_)}
+
+_imagecontracttext_ {_docbutton_(_httpcurrentdocument_&amp;gt=0,_textCONTRACT_,_texticoncontracttext_)}
+
+_imageexpandtext_ {_docbutton_(_httpcurrentdocument_&amp;gt=1,_textEXPANDTEXT_,_texticonexpandtext_)}
+
+_imagecont_ {_docbutton_(_httpcurrentdocument_&amp;gt=2,_textCONTINUE_,_texticoncont_)}
+
+
+#######################################################################
+# print preview script
+#######################################################################
+
+
+_pagescriptextra_{
+
+ var style_display_old;
+ var show = true;
+ var toc_top;
+
+ function has_toc(){
+     var div_nodes = document.getElementsByTagName("div");    
+     for (var i=0;i < div_nodes.length ; i++ )\{
+          var div_node = div_nodes[i];
+          if (div_node.className =="toc" && div_node.childNodes.length > 1)
+             \{
+                 return true;
+             \}
+      \}
+   
+    return false;
+ \}
+
+ function hide_toc()\{
+     var div_nodes = document.getElementsByTagName("div");    
+     for (var i=0;i < div_nodes.length ; i++ )\{
+          var div_node = div_nodes[i];
+          if (div_node.className =="toc")
+             \{
+               style_display_old = div_node.style.display; 
+               toc_top = document.getElementById("toc_top"); 
+               if (toc_top)
+                div_node.parentNode.insertBefore(toc_top,div_node);
+                div_node.style.display = "none";
+             \};
+      \}  
+
+ \}  
+
+
+ function show_toc()\{
+  
+     var div_nodes = document.getElementsByTagName("div");    
+     for (var i=0;i < div_nodes.length ; i++ )\{
+          var div_node = div_nodes[i];
+          if (div_node.className =="toc")
+             \{
+               div_node.style.display = style_display_old;
+               if (toc_top)
+                  div_node.insertBefore(toc_top,div_node.firstChild);    
+              \}; 
+      \}
+
+ \}  
+
+  
+  function switch_toc()\{
+     var toc_link =  document.getElementById("toc_link");
+       while (toc_link.hasChildNodes()) \{
+       	  toc_link.removeChild(toc_link.firstChild);
+	\}  
+    if (show)\{
+        toc_link.appendChild(document.createTextNode('_textshowcontents_'));
+        show = false;
+        hide_toc(); 
+    \}
+  else\{
+       toc_link.appendChild(document.createTextNode('_texthidecontents_'));
+      show = true;
+      show_toc();
+    \}
+
+  \}
+    
+  function print_preview() \{
+   // Switch the stylesheet
+    setActiveStyleSheet("Preview Document");
+    add_print_message(); 
+  \}
+
+  function add_print_message()\{
+     if (document.getElementById)\{
+        var print_message = document.createElement('ul');
+	    print_message.id = 'print-message'; 
+            print_message.className = "printmessage";  
+        
+         var cancel_print_link = document.createElement('li');
+         cancel_print_link.className = "cancelprint"
+         cancel_print_link.onclick = function()\{ cancel_print(); return false;\}; 
+         cancel_print_link.appendChild(document.createTextNode('_textreturnoriginal_'));
+          print_message.appendChild(cancel_print_link);  
+
+          
+           var print_link = document.createElement('li');
+           print_link.onclick = function()\{ window.print(); return false;\};
+           print_link.appendChild(document.createTextNode('_textprintpage_'));
+           print_message.appendChild(print_link); 
+
+    if (has_toc())\{  
+	  var toc_link = document.createElement('li');
+          toc_link.id = "toc_link";
+          toc_link.onclick = function()\{ switch_toc(); return false;\};
+          toc_link.appendChild(document.createTextNode('_texthidecontents_'));                 
+          print_message.appendChild(toc_link);   
+         \}
+
+         //insert the print message node
+         var div_nodes = document.getElementsByTagName("div");    
+         for (var i=0;i < div_nodes.length ; i++ )\{
+            var div_node = div_nodes[i];
+             if (div_node.className =="document")\{         
+                 var parent = div_node.parentNode;
+                 parent.insertBefore(print_message,div_node);
+           \}
+        \}
+     \}
+
+  \}
+  
+ 
+ function cancel_print() \{
+	// Destroy the preview message 
+   var print_message = document.getElementById('print-message');
+   var parent = print_message.parentNode;
+   parent.removeChild(print_message);
+	
+    show_toc();
+    // Switch back stylesheet
+    setActiveStyleSheet("default");
+  \}
+
+ function setActiveStyleSheet(title) \{
+    var i, a, main;
+    for(i=0; (a = document.getElementsByTagName("link")[i]); i++) \{
+      if(a.getAttribute("rel").indexOf("style") != -1
+         && a.getAttribute("title")) \{
+        a.disabled = true;
+        if(a.getAttribute("title") == title) a.disabled = false;
+    \}
+   \ }
+  \}
+
+}
+
+
+#######################################################################
+# headers/footers
+#######################################################################
+
+
+# header overridden for text pages
+_textheader_ {_cgihead_
+_htmlhead_
+_startspacer_
+
+<!-- document:textheader -->
+<div id="banner">
+<div class="pageinfo"><p class="bannerlinks">_globallinks_</p></div>
+<div class="collectimage">_imagecollection_</div>
+</div>
+<div class="bannerextra">_pagebannerextra_</div>
+}
+
+_textheader_ [v=1] {_cgihead_
+_htmlhead_
+_globallinks_
+}
+
+_footer_ {
+</div> <!-- document:footer -->
+
+<div class="navarrowsbottom">
+_navarrowsbottom_
+</div>
+_endspacer__htmlfooter_
+}
Index: /gsdl/stable/macros/dutch.dm
===================================================================
--- /gsdl/stable/macros/dutch.dm	(revision 20131)
+++ /gsdl/stable/macros/dutch.dm	(revision 20131)
@@ -0,0 +1,757 @@
+ # this file must be UTF-8 encoded
+######################################################################
+#
+# Dutch Language text and icon macros, translated 8.9.2000
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=nl] {Tijdschriften}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=nl] {bron ref:}  
+_textdate_ [l=nl] {datum van uitgave:}  
+_textnumpages_ [l=nl] {aantal pagina's}  
+
+_textsignin_ [l=nl] {log in}  
+
+_textdefaultcontent_ [l=nl] {De vereisde pagina kon niet worden gevonden. 
+Gebruik de terug knop van de browser of de home knop om naar de hoofdpagina 
+van de Greenstone Digitale Bibliotheek terug te keren.}
+
+_textdefaulttitle_ [l=nl] {GSDL Error}
+
+_textbadcollection_ [l=nl] {Deze collectie ("_cvariable_" genaamd) is in dit Greenstone digitale bibliotheeksysteem niet geÃ¯nstalleerd}  
+
+_textselectpage_ [l=nl] {-'- Kies pagina '-'-}  
+
+_collectionextra_ [l=nl] {Deze collectie bevat _about:numdocs_ documenten. 
+De collectie werd _about:builddate_ dagen geleden gebouwd.}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=nl] {<p>Deze collectie bevat  _numdocs_ _If_("_numdocs_" eq "1",document,documenten), in het totaal _numbytes_ geÃ¯ndexeerde tekst en metadata.
+<p><a href="_httppagex_(bsummary)">Klik hier</a> om het overzicht van het bouwen van deze colletie te zien.
+}  
+
+_textdescrcollection_ [l=nl] {}
+_textdescrabout_ [l=nl] {Informatie-pagina}
+_textdescrhome_ [l=nl] {Hoofdpagina}
+_textdescrhelp_ [l=nl] {Helppagina}
+_textdescrpref_ [l=nl] {Voorkeuren-pagina}  
+_textdescrgreenstone_ [l=nl] {Greenstone Digital Library Software}
+_textdescrusab_ [l=nl] {Wat vond U moeilijk te gebruiken?}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=nl] {Zoek}  
+_labelSearch_ [l=nl] {Zoeken}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=nl] {Titel}  
+_labelTitle_ [l=nl] {Titels}  
+_textCreator_ [l=nl] {Creator}  
+_labelCreator_ [l=nl] {Creators}  
+_textSubject_ [l=nl] {Onderwerp}  
+_labelSubject_ [l=nl] {Onderwerpen}
+_textDescription_ [l=nl] {Beschrijving}  
+_labelDescription_ [l=nl] {Beschrijvingen}  
+_textPublisher_ [l=nl] {Uitgever}  
+_labelPublisher_ [l=nl] {Uitgevers}  
+_textContributor_ [l=nl] {Medewerker}  
+_labelContributor_ [l=nl] {Medewerkers}  
+_textDate_ [l=nl] {Datum}  
+_labelDate_ [l=nl] {Datums}
+_textType_ [l=nl] {Soort}  
+_labelType_ [l=nl] {Soorten}  
+_textFormat_ [l=nl] {Formaat}  
+_labelFormat_ [l=nl] {Formaten}  
+_textIdentifier_ [l=nl] {Identifier}  
+_labelIdentifier_ [l=nl] {identifiers}  
+_textSource_ [l=nl] {Bestandsnaam}  
+_labelSource_ [l=nl] {Bestandsnamen}  
+_textLanguage_ [l=nl] {Taal}  
+_labelLanguage_ [l=nl] {Talen}  
+_textRelation_ [l=nl] {Relatie}  
+_labelRelation_ [l=nl] {Relaties}  
+_textCoverage_ [l=nl] {Dekking}  
+_labelCoverage_ [l=nl] {Dekking}  
+_textRights_ [l=nl] {Rechten}  
+_labelRights_ [l=nl] {Rechten}  
+
+# DLS metadata set
+_textOrganization_ [l=nl] {Organisatie}  
+_labelOrganization_ [l=nl] {Organisaties}  
+_textKeyword_ [l=nl] {Trefwoord}  
+_labelKeyword_ [l=nl] {Trefwoorden}  
+_textHowto_ [l=nl] {Hoe te}  
+_labelHowto_ [l=nl] {Hoe te}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=nl] {Woordgroep}  
+_labelPhrase_ [l=nl] {Woordgroepen}  
+_textCollage_ [l=nl] {Collatie}  
+_labelCollage_ [l=nl] {Collatie}  
+_textBrowse_ [l=nl] {Grasduinen}  
+_labelBrowse_ [l=nl] {Grasduinen}  
+_textTo_ [l=nl] {Naar}  
+_labelTo_ [l=nl] {Aan}  
+_textFrom_ [l=nl] {Van}  
+_labelFrom_ [l=nl] {Afzender}
+_textAcronym_ [l=nl] {Acroniem}  
+_labelAcronym_ [l=nl] {Afkortingen}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=nl] {Grasduinen op _1_}  
+
+_textdescrSearch_ [l=nl] {Zoeken naar specifieke termen}  
+_textdescrType_ [l=nl] {Grasduinen in de soorten bronnen}  
+_textdescrIdentifier_ [l=nl] {Grasduinen in identifiers van de bronnen}  
+_textdescrSource_ [l=nl] {Grasduinen in de oorspronkelijke bestandsnamen}  
+_textdescrTo_ [l=nl] {Grasduinen op het Aan-veld}  
+_textdescrFrom_ [l=nl] {Grasduinen in Van-veld}  
+_textdescrCollage_ [l=nl] {Grasduinen in beeldverzameling}  
+_textdescrAcronym_ [l=nl] {Grasduinen in afkortingen}  
+_textdescrPhrase_ [l=nl] {Grasduinen met woordgroepen}  
+_textdescrHowto_ [l=nl] {Grasduinen in hel}  
+_textdescrBrowse_ [l=nl] {Grasduinen in documenten}  
+_texticontext_ [l=nl] {Documenten weergeven}
+_texticonclosedbook_ [l=nl] {document openen en inhoud op het scherm brengen}  
+_texticonnext_ [l=nl] {naar de volgende sectie}
+_texticonprev_ [l=nl] {naar de vooafgaande sectie}
+
+_texticonworld_ [l=nl] {Bekijk het Web-document}  
+
+_texticonmidi_ [l=nl] {Bekijk het MIDI-document}  
+_texticonmsword_ [l=nl] {Bekijk het Microsoft Word-document}  
+_texticonmp3_ [l=nl] {Bekijk het MP3-document}  
+_texticonpdf_ [l=nl] {Bekijk het PDF-document}  
+_texticonps_ [l=nl] {Bekijk het PostScript-document}  
+_texticonppt_ [l=nl] {Bekijk het PowerPoint-document}  
+_texticonrtf_ [l=nl] {Bekijk het RTF-document}  
+_texticonxls_ [l=nl] {Bekijk het Microsoft Excel-document}  
+
+_page_ [l=nl] {pagina }
+_pages_ [l=nl] {pagina's}  
+_of_ [l=nl] {uit }
+_vol_ [l=nl] {Deel}  
+_num_ [l=nl] {Nr.}  
+
+_textmonth00_ [l=nl] {}
+_textmonth01_ [l=nl] {Januari}
+_textmonth02_ [l=nl] {Februari}
+_textmonth03_ [l=nl] {Maart}
+_textmonth04_ [l=nl] {April}
+_textmonth05_ [l=nl] {Mei}
+_textmonth06_ [l=nl] {Juni}
+_textmonth07_ [l=nl] {Juli}
+_textmonth08_ [l=nl] {Augustus}
+_textmonth09_ [l=nl] {September}
+_textmonth10_ [l=nl] {oktober}  
+_textmonth11_ [l=nl] {November}
+_textmonth12_ [l=nl] {December}
+
+_textdocument_ [l=nl] {Document}
+_textsection_ [l=nl] {Sectie}
+_textparagraph_ [l=nl] {Alinea}
+
+_magazines_ [l=nl] {tijdschriften}
+
+_nzdlpagefooter_ [l=nl] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}
+
+_linktextHOME_ [l=nl] {HOOFDPAGINA}
+_linktextHELP_ [l=nl] {HELP}
+_linktextPREFERENCES_ [l=nl] {VOORKEUREN}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=nl] {Greenstone Digitale Bibliotheek}  
+
+_textnocollections_ [l=nl] {Er zijn geen geldige, d.w.z. Gebouwde en publiek toegankelijke collecties beschikbaar}  
+
+_textadmin_ [l=nl] {Administratiepagina}  
+_textabgs_ [l=nl] {Over Greenstone}  
+_textgsdocs_ [l=nl] {Documentatie over Greenstone}  
+
+_textdescradmin_ [l=nl] {Geeft de mogelijkheid nieuwe gebruikers toe te voegen, geeft een samenvatting van de collecties in het systeem. 
+Geeft technische informatie over de installatie van Greenstone}  
+
+_textdescrgogreenstone_ [l=nl] {Beschrijft de Greenstone programmatuur en het New Zealand Digital Library Project waaruit zij voortkomt}  
+
+_textdescrgodocs_ [l=nl] {Greenstone handleidingen}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=nl] {De Library Interface}  
+_textdescrgli_ [l=nl] {Helpt nieuwe collecties te maken, bestaande te veranderen of uit te breiden, en
+collecties te verwijderen}  
+
+package collector
+
+_textcollector_ [l=nl] {De Collector}  
+_textdescrcollector_ [l=nl] {Dit is ouder dan de "librarian interface" en in de praktijk kan voor de meeste doeleinden beter de "librarian interface" gebruikt worden}  
+
+package depositor
+
+_textdepositor_ [l=nl] {De Depositor}  
+_textdescrdepositor_ [l=nl] {Helpt documenten toe te voegen aan bestaande collecties}  
+
+package gti
+
+_textgti_ [l=nl] {De interface van de Greenstone Vertaler}  
+_textdescrtranslator_ [l=nl] {Helpt U de veeltalige versies van de Greenstone interface up to date te houden}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=nl] {Over deze collectie}  
+
+_textsubcols1_ [l=nl] {<p>De volledige collectie bevat _1_ subcollecties:
+Nu beschikbaar zijn: <blockquote>}  
+
+_textsubcols2_ [l=nl] {</blockquote>
+Voor het kijken en veranderen welke subcollecties in gebruik zijn,
+ga naar de voorkeurenpagina.}  
+
+_titleabout_ [l=nl] {informatie}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=nl] {sluit dit gedeelte van de bibliotheek}  
+_texticonclosedbookshelf_ [l=nl] {Open dit tgedeelte van de bibliotheek en bring de inhoud op het scherm.}
+_texticonopenbook_ [l=nl] {Sluit dit boek}
+_texticonclosedfolder_ [l=nl] {Open deze map en toon de inhoud op het scherm}  
+_texticonclosedfolder2_ [l=nl] {open deze sub-sectie:}  
+_texticonopenfolder_ [l=nl] {Sluit deze map: }
+_texticonopenfolder2_ [l=nl] {sluit deze sub-sectie: }  
+_texticonsmalltext_ [l=nl] {Geef deze sectie van de tekst weer}
+_texticonsmalltext2_ [l=nl] {geef tekst weer: }  
+_texticonpointer_ [l=nl] {Actueele sectie}
+_texticondetach_ [l=nl] {Open en nieuw venster voor deze pagina}
+_texticonhighlight_ [l=nl] {Accentueer zoektermen}  
+_texticonnohighlight_ [l=nl] {Accentueer zoek termen niet}
+_texticoncontracttoc_ [l=nl] {Inhoudsopgave inkorten}
+_texticonexpandtoc_ [l=nl] {Inhoudsopgave uitbreiden}  
+_texticonexpandtext_ [l=nl] {Hele tekst weergeven}
+_texticoncontracttext_ [l=nl] {Alleen maar geselecteerde tekst weergeven}
+_texticonwarning_ [l=nl] {<b>Waarschuiving: </b>}
+_texticoncont_ [l=nl] {Doorgaan?}  
+
+_textltwarning_ [l=nl] {<div class="buttons">_imagecont_</div>
+_iconwarning_Het Uitbreiden van deze tekst zal 
+een grote hoeveelheid gegevens produceren die door 
+uw browser moeten weergegeven
+}  
+
+_textgoto_ [l=nl] {Ga naar pagina}
+_textintro_ [l=nl] {<i>(Inleidende tekst)</i>}
+
+_textCONTINUE_ [l=nl] {DOORGAAN?}  
+
+_textEXPANDTEXT_ [l=nl] {TEKST UITBREIDEN}  
+
+_textCONTRACTCONTENTS_ [l=nl] {INHOUD INKRIMPEN}  
+
+_textDETACH_ [l=nl] {NIEUW VENSTER}  
+
+_textEXPANDCONTENTS_ [l=nl] {INHOUD UITBREIDEN}  
+
+_textCONTRACT_ [l=nl] {TEKST INKRIMPEN}  
+
+_textHIGHLIGHT_ [l=nl] {ACCENTUEREN}  
+
+_textNOHIGHLIGHT_ [l=nl] {NIET ACCENTUEREN}  
+
+_textPRINT_ [l=nl] {AFDRUKKEN}  
+
+_textnextsearchresult_ [l=nl] {volgend zoekresultaat}  
+_textprevsearchresult_ [l=nl] {vorig zoekresultaat}  
+
+# macros for printing page
+_textreturnoriginal_ [l=nl] {Ga terug naar de oorspronkelijke pagina}  
+_textprintpage_ [l=nl] {Druk deze pagina af}  
+_textshowcontents_ [l=nl] {Toon de inhoudsopgave}  
+_texthidecontents_ [l=nl] {Verberg de inhoudsopgave}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=nl] {_If_(_thislast_, _thisfirst_ - _thislast_ resultaten voor de zoekactie: _cgiargq_,geen resultaat voor de zoekactie: _cgiargq_)}
+_textnoquerytitle_ [l=nl] {Zoek pagina}
+
+_textsome_ [l=nl] {sommige}  
+_textall_ [l=nl] {alle}
+_textboolean_ [l=nl] {boolse}
+_textranked_ [l=nl] {naar relevantie geordend
+}  
+_textnatural_ [l=nl] {natuurlijk}  
+_textsortbyrank_ [l=nl] {rangschikking naar relevantie}  
+_texticonsearchhistorybar_ [l=nl] {zoekgeschiedenis}  
+
+_textifeellucky_ [l=nl] {Ik ben gelukkig!}  
+
+#alt text for query buttons
+_textusequery_ [l=nl] {gebruik deze vraag}  
+_textfreqmsg1_ [l=nl] {aantal woorden: }
+_textpostprocess_ [l=nl] {_If_(_quotedquery_,<br><i>verder verwerkt om _quotedquery_ te vinden</i>
+)}
+_textinvalidquery_ [l=nl] {Fout in de syntaxis van de vraag}  
+_textstopwordsmsg_ [l=nl] {De volgende woorden zijn te algemeen en worden genegeerd:}  
+_textlucenetoomanyclauses_ [l=nl] {Uw vraag bevat te veel zoektermen; probeer een meer specifieke vraag, alsublieft}  
+
+_textmorethan_ [l=nl] {Meer dan }
+_textapprox_ [l=nl] {Ongeveer }
+_textnodocs_ [l=nl] {Geen documenten gevonden.}
+_text1doc_ [l=nl] {1 document voldoet aan de zoekvraag.}  
+_textlotsdocs_ [l=nl] {documenten gevonden.}
+_textmatches_ [l=nl] {passende teksten }
+_textbeginsearch_ [l=nl] {Begin zoekactie}
+_textrunquery_ [l=nl] {Voer de zoekvraag uit}  
+_textclearform_ [l=nl] {Maak formulier leeg}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=nl] {Woorden}  
+_textinfield_ [l=nl] {... in veld}  
+_textfoldstem_ [l=nl] {(hoofdletters, woordstammen)}  
+
+_textadvquery_ [l=nl] {Of voer de zoekvraag rechtstreeks in:}  
+_textallfields_ [l=nl] {alle velden}  
+_texttextonly_ [l=nl] {alleen tekst}  
+_textand_ [l=nl] {en}  
+_textor_ [l=nl] {of}  
+_textandnot_ [l=nl] {en niet}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=nl] {Zoek in _indexselection_ _If_(_jselection_, verbonden met _jselection_ )_If_(_gselection_, at _gselection_ niveau )_If_(_nselection_, in _nselection_ language ) dat bevat(ten) _querytypeselection_ van de woorden _If_(_sfselection_,\,_allowformbreak_ resultaten gesorteerd volgens  _sfselection_)
+}  
+
+_textadvancedsearch_ [l=nl] {Doorzoek _indexselection_ _If_(_jselection_,of _jselection_)_If_(_gselection_, op het _gselection_ niveau)_If_(_nselection_, in _nselection_ taal) met een _querytypeselection_ zoekvraag}  
+
+_textadvancedmgppsearch_ [l=nl] {Zoek in _indexselection_ _If_(_jselection_, verbonden met _jselection_ )_If_(_gselection_,at _gselection_ niveau )_If_(_nselection_,in _nselection_ language ), en toon resultaten in _formquerytypeadvancedselection_ volgorde, voorr}  
+
+_textadvancedlucenesearch_ [l=nl] {Zoek in _indexselection__If_(_jselection_, verbonden met _jselection_)_If_(_gselection_, op _gselection_ niveau )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ resultaten gesorteerd volgens  _sfselection_\,) voor}  
+
+_textformsimplesearch_ [l=nl] {Zoek in _If_(_jselection_, _jselection_)_If_(_gformselection_, at _gformselection_ niveau )_If_(_nselection_, in _nselection_ taal)_If_(_sfselection_,\,  resultaten gesorteerd naar _sfselection_\,) voor _formquerytypesimpleselection_ van}  
+
+_textformadvancedsearchmgpp_ [l=nl] {Zoek in _If_(_jselection_,_jselection_ )_If_(_gformselection_,op _gformselection_ niveau )_If_(_nselection_,in _nselection_ taal )en toon resultaten in _formquerytypeadvancedselection_ volgorde: }  
+
+_textformadvancedsearchlucene_ [l=nl] {Zoek in _If_(_jselection_, _jselection_)_If_(_gformselection_,  at _gformselection_ niveau )_If_(_nselection_, in _nselection_ taal)_If_(_sfselection_,\, resultaten gesorteerd naar _sfselection_\,) voor}  
+
+_textnojsformwarning_ [l=nl] {Waarschuwing: Javascript is in Uw webbrowser afgezet. <br>Om een zoekformulier te kunnen gebruiken, moet U het aanzetten.}  
+_textdatesearch_ [l=nl] {Deze collectie kan doorzocht worden naar documenten die binnen een bepaalde tijdsperiode vallen, of documenten die een bepaalde datum bevatten. Dit is een optioneel kenmerk van de zoekactie.}  
+_textstartdate_ [l=nl] {Begin- (of enige) datum}  
+_textenddate_ [l=nl] {Einddatum:}  
+_textbc_ [l=nl] {Voor Chr./B.C.E.}  
+_textad_ [l=nl] {Na Chr./ C.E.}  
+_textexplaineras_ [l=nl] {C.E. en B.C.E. zijn alternatieven voor respectievelijk "na Chr." en "voor Chr." C.E. en B.C.E. worden als cultureel niet-discriminerend beschouwd en zijn afkortingen van "Common Era" en "Before Common Era"}  
+
+_textstemon_ [l=nl] {(woorduitgangen negeeren)}  
+
+_textsearchhistory_ [l=nl] {Zoekgeschiedenis}  
+
+#text macros for search history
+_textnohistory_ [l=nl] {De zoekgeschiedenis bevat geen zoekvragen}  
+_texthresult_ [l=nl] {resultaat}  
+_texthresults_ [l=nl] {resultaten}  
+_texthallwords_ [l=nl] {alle woorden}  
+_texthsomewords_ [l=nl] {sommige woorden}  
+_texthboolean_ [l=nl] {booleaans}  
+_texthranked_ [l=nl] {naar relevantie geordend}  
+_texthcaseon_ [l=nl] {hoodlettergebruik moet overeenstemmen}  
+_texthcaseoff_ [l=nl] {hoofdlettergebruik hoeft niet overeen te stemmen}  
+_texthstemon_ [l=nl] {gestript tot woordstammen}  
+_texthstemoff_ [l=nl] {niet gestript tot woordstammen}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=nl] {Voorkeuren moeten als volgt worden opgeslagen: klik op een van de knoppen van de ingangen 
+bovenaan; gebruik niet de "terug"-knop van uw browser - daardoor wordt de voorkeuren teruggezet.}  
+_textsetprefs_ [l=nl] {Sla voorkeuren op}  
+_textsearchprefs_ [l=nl] {Voorkeuren bij het zoeken}  
+_textcollectionprefs_ [l=nl] {Voorkeuren voor collecties}  
+_textpresentationprefs_ [l=nl] {Voorkeuren bij de presentatie}  
+_textpreferences_ [l=nl] {Voorkeuren}  
+_textcasediffs_ [l=nl] {Hoofdletters / kleine letters}  
+_textignorecase_ [l=nl] {negeer verschil hoofd-/kleine letters}  
+_textmatchcase_ [l=nl] {hoofdletters en kleine letters moeten exact overeenstemmen}  
+_textwordends_ [l=nl] {Woorduitgangen:}  
+_textstem_ [l=nl] {negeer woorduitgangen}  
+_textnostem_ [l=nl] {hele woord moet overeenstemmen}  
+_textaccentdiffs_ [l=nl] {Verschillen in accenten:}  
+_textignoreaccents_ [l=nl] {ignoreer accenten en diacritische tekens}  
+_textmatchaccents_ [l=nl] {accenten en diacritische tekens moeten overeenkomen}  
+
+_textprefop_ [l=nl] {Weergeven van maximaal _maxdocoption_ treffers met maximaal _hitsperpageoption_ treffers per pagina.}
+_textextlink_ [l=nl] {Toegang tot externe Webpagina's: }  
+_textintlink_ [l=nl] {Brondocumenten opgevraagd van:}  
+_textlanguage_ [l=nl] {Taal van de interface:}  
+_textencoding_ [l=nl] {Codering: }  
+_textformat_ [l=nl] {Formaat van het interface:}  
+_textall_ [l=nl] {alle}
+_textquerymode_ [l=nl] {Zoekmethode:}  
+_textsimplemode_ [l=nl] {eenvoudige zoekmodus}  
+_textadvancedmode_ [l=nl] {geavanceerde zoekmodus (staat booleaans zoeken met gebruik van !, &, |, en ronde haakjes toe)}  
+_textlinkinterm_ [l=nl] {via tussenpagina}  
+_textlinkdirect_ [l=nl] {Ga direct naar de Webpagina}
+_textdigitlib_ [l=nl] {de digitale bibliotheek}
+_textweb_ [l=nl] {Het Web}
+_textgraphical_ [l=nl] {Grafisch}
+_texttextual_ [l=nl] {Tekst}
+_textcollectionoption_ [l=nl] {<p>
+Ondercollecties die ingesloten moeten worden:
+<br>}
+
+_textsearchtype_ [l=nl] {Zoekstijl:}  
+_textformsearchtype_ [l=nl] {opgedeeld in  _formnumfieldoption_ fields velden}  
+_textplainsearchtype_ [l=nl] {normaal met _boxsizeoption_ zoekveld}  
+_textregularbox_ [l=nl] {eenregelig}  
+_textlargebox_ [l=nl] {groot}  
+
+_textrelateddocdisplay_ [l=nl] {toon verwante documenten}  
+_textsearchhistory_ [l=nl] {Zoekgeschiedenis:}  
+_textnohistory_ [l=nl] {Geen zoekgeschiedenis}  
+_texthistorydisplay_ [l=nl] {geef _historynumrecords_ zoekvragen in de zoekgeschiedenis weer}  
+_textnohistorydisplay_ [l=nl] {toon de zoekgeschiedenis niet}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=nl] {Sorteer documenten op}  
+_textalsoshowing_ [l=nl] {toont ook}  
+_textwith_ [l=nl] {met ten hoogste}  
+_textdocsperpage_ [l=nl] {documenten per pagina}  
+
+_textfilterby_ [l=nl] {Zoek docuenten bevattend}  
+_textall_ [l=nl] {alle}  
+_textany_ [l=nl] {iedere}  
+_textwords_ [l=nl] {van de woorden}  
+_textleaveblank_ [l=nl] {laat deze box leeg om alle documenten te krijgen}  
+
+_browsebuttontext_ [l=nl] {"Sorteer documenten"}  
+
+_nodata_ [l=nl] {<i>geen gegevens</i>}  
+_docs_ [l=nl] {documenten}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=nl] {Help}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=nl] {grasduinen op  _1_ door te klikken op de _2_-knop}  
+
+_textSearchhelp_ [l=nl] {zoeken naar bepaalde woorden die in de tekst voorkomen door te klikken op de  _labelSearch_-knop}  
+_textTohelp_ [l=nl] {Grasduin documenten op Aan-veld door te klikken op de _labelTo_-knop}  
+_textFromhelp_ [l=nl] {grasduin documenten naar Van-veld door te klikken op de _labelFrom_-knop}  
+_textBrowsehelp_ [l=nl] {grasduin in de documenten}  
+_textAcronymhelp_ [l=nl] {grasduin door documenten met afkortingen door te klikken op de _labelAcronym_knop}  
+_textPhrasehelp_ [l=nl] {Klik op de  _labelPhrase_ knop om te grasduinen op woordgroepen. Hierbij wordt de phind phrase browser gebruikt.}  
+
+_texthelptopicstitle_ [l=nl] {Onderwerpen}  
+
+_textreadingdocs_ [l=nl] {Hoe kan ik documenten lezen?}  
+
+_texthelpreadingdocs_ [l=nl] {<p>U bent bij een individueel boek of document aangekomen, als de titel of een afbeelding er van links boven aan de pagina 
+verschijnen.  In sommige collecties verschijnt een inhoudsopgave, terwijl in andere 
+(bijv. als de "paged image" optie is gebruikt) alleen het paginanummer wordt getoond
+met daarnaast een box die het mogelijk maakt een nieuwe pagina te selecteren en vooruit of
+achteruit te gaan. In de inhoudsopgave is de actuele sectiekop vet weergegeven, en de tabel is 
+uitbreidbaar -- klik op de folders om ze te openen of te sluiten; klik op het open boek bovenaan 
+om het te openen of te sluiten. </p>
+
+<p>Onderaan de pagina bevindt zich de tekst van de sectie.  U kunt gebruik maken van de 
+pijlen onderaan de pagina om naar de volgende of voorafgaande sectie komen.</p>
+
+<p>Onder de titel of afbeelding bevinden zich enige knoppen. Klik op de knop <i>_document:textEXPANDTEXT_</i> 
+om de hele tekst van de betreffende sectie of gehele document te zien. Bij grote documenten kan dit
+heel wat tijd en geheugen in beslag nemen! Klik op de knop <i>_document:textEXPANDCONTENTS_</i> om 
+de inhoudsopgave uit te vouwen zodat U de titels van alle hoofdstukken en subsecties kunt zien. Klik op 
+<i>_document:textDETACH_</i> om een nieuw venster voor het document te openen.  (Dit kan handig
+zijn, als U documenten wilt vergelijkenn of als U twee documenten tegelijk wilt lezen.) 
+Na het uitvoeren van een zoekactie, worden de woorden waarnaar U gezocht hebt 
+geaccentueerd. Wilt U dit ongedaan maken, dan klikt U op de knop <i>_document:textNOHIGHLIGHT_</i>.
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=nl] {Open deze boekenkast}  
+_texthelpopenbook_ [l=nl] {Open/sluit dit boek}  
+_texthelpviewtextsection_ [l=nl] {Geef deze sectie van de tekst weer}  
+_texthelpexpandtext_ [l=nl] {Geef de hele tekst weer, of niet}
+_texthelpexpandcontents_ [l=nl] {Expandeer de inhoudsopgave, of niet}  
+_texthelpdetachpage_ [l=nl] {Open een nieuw venster voor deze pagina}  
+_texthelphighlight_ [l=nl] {Accentueer zoektermen of niet}
+_texthelpsectionarrows_ [l=nl] {Ga naar de volgende/vorige sectie}  
+
+
+_texthelpsearchingtitle_ [l=nl] {Zoeken naar bepaalde worden}
+
+_texthelpsearching_ [l=nl] {<p>
+  In de pagina "zoek" kuntU met de enkele eenvoudige stappen een zoekvraag formuleren:<p>
+
+  <ol><li>Specificer waarnaar U wilt zoeken.
+      <li>Geef aan of U naar sommige of naar alle woorden wilt zoeken.
+      <li>Typ de woorden in waarnaar gezocht moet worden.
+      <li>Klik op de knop <i>Begin zoeken<i>
+  </ol>
+
+<p>Na het uitvoeren van een zoekactie worden de titels van twintig gevonden documenten getoond.
+Onderaan de pagina is een knop om naar de volgende 20 titels te gaan.  
+Vandaar kunt U of terug naar de vooafgaande pagina of  vooruit naar de volgende pagina. 
+Klik op de titel of op de knop ernaast om een document te zien.
+
+<p>Er worden maximaal 50 gevonden documenten weergegeven.  U kunt dit maximum 
+veranderen via de knop <i>preferenties</I> bovenaan de pagina.<p>
+}  
+
+_texthelpquerytermstitle_ [l=nl] {Zoektermen}
+_texthelpqueryterms_ [l=nl] {<p>Alle woorden in de zoekvraagbox worden als zoektermen geÃ¯nterpreteerd. Zoektermen mogen alleen 
+letters en nummers bevatten. Zoektermen worden gesepareerd door een spatie. Alle andere tekens 
+(zoals komma's of vraagtekens) worden als seperatoren geÃ¯nterpreteerd.  Ze zijn dus identiek met 
+spaties en worden genegeerd als onderdeel van zoektermen.  Het is dus niet mogelijk om naar 
+woorden te zoeken die dit soort tekens bevatten.
+
+<p>Bij voorbeeld de zoekvraag <p>
+    <ul><kbd>'s-Maandags</kbd></ul>
+      <p>is hetzelfde als <p>
+      <ul><kbd>s Maandags</kbd></ul><p>
+}  
+
+_texthelpmgppsearching_ [l=nl] {Voor collecties gebouwd met de zoekmachine MGPP zijn enkele extra opties beschikbaar.
+
+<ul>
+<li>Een <b>*</b> aan het eind van een zoekterm vindt alle woorden die met dat woord beginnen, bijvoorbeeld <b>comput*</b> vindt alle woorden die beginnen met <b>comput</b>.
+<li><b>/x</b> kan worden gebruikt om een hoger gewicht te gven aan een of meer zoektermen, bijvoorbeeld <b>computer/10 wetenschap</b> geeft computer 10 maal meer gewicht dan wetenschap 
+bij het rangschikken van documenten naar relevantie.
+</ul>}  
+
+_texthelplucenesearching_ [l=nl] {Voor collecties gebouwd met de zoekmachine Lucene zijn enkele extra opties beschikbaar.
+
+<ul>
+<li><b>?</b> kan worden gebruikt als plaatshouder voor Ã©Ã©n letter. Bijvoorbeeld: <b>b?l</b> vindt  <b>bel</b>, <b>bil</b> and <b>bal</b>enz..
+<li><b>*</b> kan worden gebruikt als plaatshouder voor meerdere letters. Bijvoorbeeld: <b>comput*</b> vindt alle woorden die beginnen met <b>comput</b>.
+</ul>}  
+
+_texthelpquerytypetitle_ [l=nl] {Type zoekvragen}  
+
+
+_texthelpadvancedsearchtitle_ [l=nl] {Geavanceerd zoeken met gebuikmaking van de _1_ zoekmachine}  
+
+_texthelpadvancedsearch_ [l=nl] {<p>Als U de geavanceerde zoekmethode heeft gekozen (bij de voorkeuren) heeft U iets afwijkende zoekopties.}  
+
+_texthelpadvsearchmg_ [l=nl] {Geadvanceerd zoeken in MG collecties geeft twee opties, naar relevantie en booleaans.
+Een <b>naar relevantie is precies hetzelfde als de <b>sommige<b> zoekactie beschreven in <a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_}  
+
+_texthelpbooleansearch_ [l=nl] {Een <b>booleaanse</b> zoekactie geeft U de mogelijkheid termen te combineren
+door gebruik te maken van & (voor "en"), | (voor "of") en ! (voor "niet") en desgewenst voor groeperen van ronde haakjes. De default operator is | (voor "of").
+<p>
+Bijvoorbeeld: <b>slang & landbouw</b> vindt doumenten waarin zowel <b>slang</b> als <b>landbouw</b> voorkomen, terwijl <b>slang | landbouw</b> documenten vindt waar of <b>slang></b> of <b><landbouw</b> voorkomen of beide woorden.
+<b>slang !landbouw</b> vindt documenten waarin <b>slang</b> voorkomt MAAR NIET <b>landbouw</b>.
+<p>
+Preciesere zoekacties kunnen worden gespecificeerd door het gebruik van operatoren en ronde haakjes. Bijvoorbeeld <b>(schapen | runderen) & (boerderijen | natuurgebieden)</b> of <b>(schappen | runderen | geiten !varkens)</b>}  
+
+_texthelpadvsearchmgpp_ [l=nl] {In geavanceerde zoekacties in MGPP collecties kunnen boleaanse operatoren gebruikt worden. _texthelpbooleansearch_
+<p>De resultaten kunnen naar <b>relevantie</b> geordend getoond worden, zoals voor de <b>sommige</b> zoekactie beschreven in <a href="\#query-type">_texthelpquerytypetitle_</a>, of in de "natuurlijke" (or "gebouwde") volgorde. Dit is de volgorde waarin de documenten verwerkt werden bij het opbouwen van de collectie.
+<p>
+Andere operatoren zijn <b>NEARx</b> en <b>WITHINx</b>.
+NEARx wordt gebruikt om de maximale afstand (x woorden) aan te geven
+die tussen twee zoektermen mag voorkomen.
+WITHINx geeft aan dat de tweede zoekterm moet voorkomen binnen x woorden <i>achter</i> de eerste term. Dit lijkt op NEAR maar de volgorde van de zoektermen is van belang. De default afstand is 20.
+}  
+
+_texthelpadvancedsearchextra_ [l=nl] {LET OP: Deze operatoren worden allemaal genegeerd als u in de eenvoudige zoekmodus bent}  
+
+_texthelpadvsearchlucene_ [l=nl] {Geavanceerd zoeken in Lucene collecties gebruikt booleaanse operatoren. _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=nl] {Zoeken op bepaalde velden}  
+
+_texthelpformsearch_ [l=nl] {<p>Zoeken met velden geeft de mogelijkheid zoekacties in verschillende velden te combineren. Men kan bijvoorbeeld zoeken op "Utrecht" in de tiel en "Tramweg" als trefwoord. In de eenvoudige zoekmodus gedraagt elke regel zich als een normale eenregelige zoekactie. De afzonderlijke regels worden gecombineerd met een (booleaanse) "en" (bij een "alle" zoekactie) of een (booleaanse) "of" (bij een "sommige" zoekactie). Termen binnen een regel worden op dezelfde manier gecombineerd. In de geavanceerde modus}  
+
+_texthelpformstemming_ [l=nl] {De "hoofdletters" en "woordstam" boxen geeft U de mogelijkheid aan te geven of bij de woorden in het veld verschil gemaakt wordt tussen hoofdletters en kleine letters en of met de stammen van de woorden gezocht moet worden}  
+
+_textdatesearch_ [l=nl] {Zoeken met datums}  
+
+_texthelpdatesearch_ [l=nl] {Zoeken met datums geeft U de mogelijkheid om documenten te vinden die aan uw zoektermen voldoen, maar ook handelen over gebeurtenissen die binnen een bepaalde periode vallen. U kunt zoeken naar documenten over een bepaald jaar, of over een reeks van jaren. Let wel: U kunt met datums alleen zoeken en U hoeft geen datums te gebruiken. Als U geen datums dan wordt ook niet op datum gezocht.}  
+
+_texthelpdatehowtotitle_ [l=nl] {Hoe deze mogelijkheid re gebruiken:}  
+_texthelpdatehowto_ [l=nl] {<ul>
+   <li>Om te zoeken naar documenten over een bepaald jaar:<p>
+   <ul>
+       <li>Type uw gewone zoektermen in als anders.
+       <li>Type het jaar dat U zoekt in het "Begindatum (of enigste)" venster.
+       <li>Als Uw datum voor de " common era" (ook bekend als Voor
+           Christus), kies dan de "B.C.E" optie van het pulldown menu naast die
+          venster.
+       <li>Start uw zoekactie zoals U altijd doet.
+   </ul>
+<p><li>Om te zoeken naar documenten over een periode of reeks jaren:<p>
+   <ul>
+       <li>Type uw gewone zoektermen in als anders..
+       <li>Type de vroegste datum in  "Begindatum (of enigste)" venster.
+       <li>Type de laatste datum in de "Einddatum" venster.
+       <li>Selecteer "B.C.E" option van het pulldown menu naast het venster voor 
+          iedere datum voor de "Common Era" (ook bekend als voor Christus).
+       <li>Start uw zoekactie zoals U altijd doet.
+   </ul>    
+</ul><p>}  
+
+_texthelpdateresultstitle_ [l=nl] {De manier waarop het resultaat van uw zoekactie werkt}  
+_texthelpdateresults_ [l=nl] {In het algemeen zal een zoekactie naar documenten over het jaar 1903 geen documenten opleveren, gepubliceerd in dat jaar, bijvoorbeeld een naslagwerk, maar documenten waarin het jaar 903 besproken wordt. Echter, gezien de manier waarop deze zoekmogelijkheid werkt, zullen documenten die een reeks jaren bespreken waarbinnen 1903 valt, gevonden worden, en ook documenten waarin de eeuw waarbinnen het gezochte jaar valt (bijvoorbeeld 20e eeuw of twintigste eeuw). Het is dus mogelijk dat documenten gevonden waarin het gezochte jaar niet voorkomt. Voor een zoekactie naar een reeks jaren geldt dit voor ieder jaar binnen deze reeks.}  
+
+_textchangeprefs_ [l=nl] {Het veranderen van voorkeuren}  
+
+_texthelppreferences_ [l=nl] {<p>Als U klikt op de <i>_Global:linktextPREFERENCES_</i> knop bovenaan de pagina kunt U
+sommige kenmerken van de interface aan Uw vereisten aanpassen.
+}  
+
+_texthelpcollectionprefstitle_ [l=nl] {Collectie-voorkeuren}  
+_texthelpcollectionprefs_ [l=nl] {<p>Sommige collecties bevatten meerdere sub-collecties.  Deze kunnen individueel doorzocht worden of 
+als een geheel.  Op de pagina voor voorkeuren kunt U kiezen welke sub-collecties in de zoekacties 
+opgenomen moeten worden.
+}  
+
+_texthelplanguageprefstitle_ [l=nl] {Taalvoorkeuren}  
+_texthelplanguageprefs_ [l=nl] {<p>Elke collectie heeft een default taal voor de presentatie, maar U kunt desgewenst een 
+andere taal kiezen. U kunt ook het encoding schema voor tekens die Greenstone naar het 
+scherm stuurt, veranderen - de software kiest zinvolle defaults, maar voor sommige browers kan een 
+ander schema nodig zijn om alle tekens correct weer te geven.
+Bij elke collectie kunt U van een grafische interface switchen naar een gebaseerd op tekst. Dit is vooral 
+nuttig voor blinden en slechtzienden die een groter lettertype wensen of zich de output willen laten voorlezen 
+door een spraaksynthesizer.}  
+
+_texthelppresentationprefstitle_ [l=nl] {Presentatie-voorkeuren}  
+_texthelppresentationprefs_ [l=nl] {Afhankelijk van het type collectiezijn er verschillende opties om de presentatie van 
+de collectie te veranderen.
+
+In collecties van Web-pagina's kan de Greenstone navigatielijst bovenaan elke pagina 
+onderdrukt worden, zodat U direct na het uitvoeren van een zoekactie op de juiste 
+Web-pagina komt zonder een Greenstone navigatielijst.   Om in deze situatie een 
+nieuwe zoekactie uit te voeren moet U gebruik maken van  de 'terug'-knop van de 
+browser. Bij deze collecties kunt U ook Greenstones waarschuwing op het scherm 
+onderdrukken dat U op een link klikt die U buiten de digitale bibliotheek en op het Web 
+voert.
+
+In enkele Web-collecties is het mogelijk om te kiezen of de links op de pagina met 
+zoekresultaten U rechtstreeks naar de actuele URL voeren in plaats van naar de kopie 
+in de digitale bibliotheek.
+}  
+
+_texthelpsearchprefstitle_ [l=nl] {Voorkeuren bij zoeken}  
+_texthelpsearchprefs_ [l=nl] {
+<p>U kunt ook voor een geavanceerde form van zoeken kiezen.  In de geavanceerde modus 
+kunt U termen combineren door AND (&), OR (I), and NOT (!) te gebruiken, met desgewenst 
+ronde haakjes voor het vormen van groepen. 
+Op deze manier zijn preciesere zoekvragen te  formuleren. 
+<p>_selectsearchtypeprefs_
+<p>_selectwordmodificationprefs_
+<p>U kunt de zoekgeschiedenisoptie oproepen. Deze optie 
+laat U de laatste eerder gebruikte zoekvragen zien. Dit maakt het eenvoudiger 
+eerdere vragen met kleine veranderingen te herhalen.
+<p>U kunt ook het maximum aantal gevonden documenten dat getoond wordt en het 
+maximum aantal documenten per pagina veranderen.
+}  
+
+_textcasefoldprefs_ [l=nl] {Twee knoppen regelen of hoofletters en kleine letters overeen moeten stemmen bij het zoeken. Bijvoorbeeld, als "_preferences:textignorecase_" is geselecteerd, dan zal <i>snail farming</i> hetzelfde opleveren als <i>Snail Farming</i> en <i>SNAIL FARMING</i>.}  
+_textstemprefs_ [l=nl] {Twee knoppen regelen of woorduitgangen bij het zoeken genegeerd worden of niet. Bijvoorbeeld: als "_preferences:textstem_" is gekozen dan zal <i>snail farming</i> op dezelfde manier verwerkt worden als <i>snails farm</i> en <i>snail farmer</i>. Dit werkt op het moment alleen werkelijk goed voor Engels.  _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=nl] {Twee knoppen regelen of woorden met en zonder accenten hetzelfde zoekresultaat leveren. Bijvoorbeeld: als "_preferences:textignoreaccents_" is geselecteerd, dan zal <i>fÃ©dÃ©ration</i> hetzelfde resultaat leveren als  <i>fedÃ©ration</i>en <i>federation</i>.}  
+ 
+_textstemoptionsprefs_ [l=nl] {Het kan gemakkelijker en preciser zijn de truncatiemogelijkheid te gebruiken die hierboven is beschreven in  "_texthelpquerytermstitle_".}  
+
+_textsearchtypeprefsplain_ [l=nl] {Het is mogelijk een groter zoekvenster op te roepen voor zoekvragen die het formaat van een alinea hebben. Het is verrassend hoe snel grote hoeveelheden tekst doorzocht kunnen worden.}  
+
+_textsearchtypeprefsform_ [l=nl] {U kunt het aantal velden dat in het zoekformulier getoond wordt, veranderen}  
+
+_textsearchtypeprefsboth_ [l=nl] {U kunt bij het zoeken op woorden switchen tussen "normaal" zoeken en zoeken met "velden". 
+<ul>
+<li>Normaal zoeken geeft Ã©Ã©n invulveld. _textsearchtypeprefsplain_</li>
+<li>Bij zoeken met velden ziet U een aantal velden, ieder voor ander veld van de index. Dit maakt het mogelijk in verschillende velden tegelijk te zoeken. _textsearchtypeprefsform_ </li>
+</ul>}  
+
+
+
+_texttanumbrowseoptions_ [l=nl] {Er zijn _numbrowseoptions_ mogelijkheden om informatie in 
+deze collectie op te sporen:}  
+
+_textsimplehelpheading_ [l=nl] {Hoe informatie te vinden in de _collectionname_ collectie}  
+
+_texthelpscopetitle_ [l=nl] {Omvang van zoekvragen}
+_texthelpscope_ [l=nl] {<p>
+In de meeste collecties kunt U verschillende indexen kiezen voor Uw zoekacties.  Er zouden auteurs- 
+en titel indexen aanwezig kunnen zijn of hoofdstuk- en alinea indexen. In het algemeen worden documenten die precies voldaan aan uw vraag
+altijd worden gevonden onafhankelijk van de gebruikte index.  
+<p> Boeken worden geopened op het relevante stuk tekst.
+}  
Index: /gsdl/stable/macros/dynamicclassifier.dm
===================================================================
--- /gsdl/stable/macros/dynamicclassifier.dm	(revision 20131)
+++ /gsdl/stable/macros/dynamicclassifier.dm	(revision 20131)
@@ -0,0 +1,15 @@
+# this file must be UTF-8 encoded
+
+package dynamicclassifier
+
+
+# Use the standard page header
+_header_ {_Style:header_}
+
+# Dynamic classifier pages have the standard navigation bar and then what is generated by dynamicclassifieraction
+_content_ {
+_optnavigationbar_
+}
+
+# Use the standard page footer
+_footer_ {_Style:footer_}
Index: /gsdl/stable/macros/english.dm
===================================================================
--- /gsdl/stable/macros/english.dm	(revision 20131)
+++ /gsdl/stable/macros/english.dm	(revision 20131)
@@ -0,0 +1,869 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# English Language text and icon macros 
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ {Periodicals}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ {source ref: }
+_textdate_ {publication date: }
+_textnumpages_ {no. of pages: }
+
+_textsignin_ {sign in}
+
+_textdefaultcontent_ {The requested page could not be found. Please use
+your browsers 'back' button or the above home button to return to the
+Greenstone Digital Library.}
+
+_textdefaulttitle_ {GSDL Error}
+
+_textbadcollection_ {This collection (called "_cvariable_") is not installed on this Greenstone digital library system.}
+
+_textselectpage_ {-- Select Page --}
+
+_collectionextra_ {This collection contains _about:numdocs_ documents. 
+It was last built _about:builddate_ days ago.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ {
+<p>This collection contains _numdocs_ _If_("_numdocs_" eq "1",document,documents), a total of _numbytes_ of indexed text and metadata.
+<p><a href="_httppagex_(bsummary)">Click here</a> to view the build summary for this collection.
+}
+
+_textdescrcollection_ {}
+_textdescrabout_ {About page}
+_textdescrhome_ {Home page}
+_textdescrhelp_ {Help page}
+_textdescrpref_ {Preferences page}
+_textdescrgreenstone_ {Greenstone Digital Library Software}
+_textdescrusab_ {What did you find hard to use?}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ {Search}
+_labelSearch_ {Search}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ {Title}
+_labelTitle_ {Titles}
+_textCreator_ {Creator}
+_labelCreator_ {Creators}
+_textSubject_ {Subject}
+_labelSubject_ {Subjects}
+_textDescription_ {Description}
+_labelDescription_ {Descriptions}
+_textPublisher_ {Publisher}
+_labelPublisher_ {Publishers}
+_textContributor_ {Contributor}
+_labelContributor_ {Contributors}
+_textDate_ {Date}
+_labelDate_ {Dates}
+_textType_ {Type}
+_labelType_ {Types}
+_textFormat_ {Format}
+_labelFormat_ {Formats}
+_textIdentifier_ {Identifier}
+_labelIdentifier_ {Identifiers}
+_textSource_ {Filename}  # Not true DC, kept for legacy reasons
+_labelSource_ {Filenames}  # Not true DC, kept for legacy reasons
+_textLanguage_ {Language}
+_labelLanguage_ {Languages}
+_textRelation_ {Relation}
+_labelRelation_ {Relations}
+_textCoverage_ {Coverage}
+_labelCoverage_ {Coverage}
+_textRights_ {Rights}
+_labelRights_ {Rights}
+
+# DLS metadata set
+_textOrganization_ {Organization}
+_labelOrganization_ {Organizations}
+_textKeyword_ {Keyword}
+_labelKeyword_ {Keywords}
+_textHowto_ {How to}
+_labelHowto_ {How to}
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ {Phrase}
+_labelPhrase_ {Phrases}
+_textCollage_ {Collage}
+_labelCollage_ {Collage}
+_textBrowse_ {Browse}
+_labelBrowse_ {Browse}
+_textTo_ {To}
+_labelTo_ {To}
+_textFrom_ {From}
+_labelFrom_ {From}
+_textAcronym_ {Acronym}
+_labelAcronym_ {Acronyms}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ {Browse by _1_}
+
+_textdescrSearch_ {Search for specific terms}
+_textdescrType_ {Browse by resource type}
+_textdescrIdentifier_ {Browse by resource identifier}
+_textdescrSource_ {Browse by original filename}  # Not true DC, kept for legacy reasons
+_textdescrTo_ {Browse by To field}
+_textdescrFrom_ {Browse by From field}
+_textdescrCollage_ {Browse by image collage}
+_textdescrAcronym_ {Browse acronyms}
+_textdescrPhrase_ {Browse phrases}
+_textdescrHowto_ {Browse how to categories}
+_textdescrBrowse_ {Browse documents}
+_texticontext_ {View the document}
+_texticonclosedbook_ {open this document and view contents}
+_texticonnext_ {to next section}
+_texticonprev_ {to previous section}
+
+_texticonworld_ {View the web document}
+
+_texticonmidi_ {View the MIDI document}
+_texticonmsword_ {View the Microsoft Word document}
+_texticonmp3_ {View the MP3 document}
+_texticonpdf_ {View the PDF document}
+_texticonps_ {View the PostScript document}
+_texticonppt_ {View the PowerPoint document}
+_texticonrtf_ {View the RTF document}
+_texticonxls_ {View the Microsoft Excel document}
+
+_page_ {page }
+_pages_ {pages}
+_of_ { of }
+_vol_ {Volume}
+_num_ {No.}
+
+_textmonth00_ {}
+_textmonth01_ {January}
+_textmonth02_ {February}
+_textmonth03_ {March}
+_textmonth04_ {April}
+_textmonth05_ {May}
+_textmonth06_ {June}
+_textmonth07_ {July}
+_textmonth08_ {August}
+_textmonth09_ {September}
+_textmonth10_ {October}
+_textmonth11_ {November}
+_textmonth12_ {December}
+
+_texttext_ {Text}
+_labeltext_ {_texttext_}
+_textdocument_ {Document}
+_textsection_ {Section}
+_textparagraph_ {Paragraph}
+_textchapter_ {Chapter}
+_textbook_ {Book}
+
+_magazines_ {Magazines}
+
+_nzdlpagefooter_ {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}
+
+_linktextHOME_ {HOME}
+_linktextHELP_ {HELP}
+_linktextPREFERENCES_ {PREFERENCES}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ {Greenstone Digital Library}
+
+_textnocollections_ {No valid (i.e. built and public) collections are available}
+
+_textadmin_ {Administration Page}
+_textabgs_ {About Greenstone}
+_textgsdocs_ {Greenstone Documentation}
+
+_textdescradmin_ {
+Allows you to add new users, summarizes the collections in the system,
+gives technical information on the Greenstone installation
+}
+
+_textdescrgogreenstone_ {
+Tells you about the Greenstone software and the New Zealand Digital Library
+Project where it originated
+}
+
+_textdescrgodocs_ {Greenstone manuals}
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ {The Librarian Interface}
+_textdescrgli_ {
+Helps you create new collections, modify or add to existing ones, or delete
+collections
+}
+
+package collector
+
+_textcollector_ {The Collector}
+_textdescrcollector_ {
+This predates the Librarian Interface, and for most practical purposes the Librarian Interface should be used instead
+}
+
+package depositor
+
+_textdepositor_ {The Depositor}
+_textdescrdepositor_  {
+Helps you to add documents to existing collections
+}
+
+package gti
+
+_textgti_ {The Greenstone Translator Interface}
+_textdescrtranslator_ {
+Helps you keep the multilingual versions of the Greenstone interface
+up to date
+}
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ {About this collection}
+
+_textsubcols1_ {<p>The complete collection comprises _1_ subcollections. 
+Those currently available are:
+<blockquote>}
+
+_textsubcols2_ {</blockquote>
+You can check (and alter) which subcollections you are 
+currently using on the Preferences page.}
+
+_titleabout_ {about}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ {close this section of the library}
+_texticonclosedbookshelf_ {open this section of the library and view contents}
+_texticonopenbook_ {close this book}
+_texticonclosedfolder_ {Open this folder and view contents}
+_texticonclosedfolder2_ {open sub-section: }
+_texticonopenfolder_ {close this folder}
+_texticonopenfolder2_ {close sub-section: }
+_texticonsmalltext_ {View this section of the text}
+_texticonsmalltext2_ {view text: }
+_texticonpointer_ {current section}
+_texticondetach_ {Open this page in a new window}
+_texticonhighlight_ {Highlight search terms}
+_texticonnohighlight_ {Don't highlight search terms}
+_texticoncontracttoc_ {Collapse table of contents}
+_texticonexpandtoc_ {Expand table of contents}
+_texticonexpandtext_ {Display all text}
+_texticoncontracttext_ {Display text only for currently selected section}
+_texticonwarning_ {<b>Warning: </b>}
+_texticoncont_ {continue?}
+
+_textltwarning_ {<div class="buttons">_imagecont_</div>
+_iconwarning_Expanding the text here will generate a large 
+amount of data for your browser to display
+}
+
+_textgoto_ {go to page}
+_textintro_ { <i>(introductory text)</i>}
+
+_textCONTINUE_ {CONTINUE?}
+
+_textEXPANDTEXT_ {EXPAND TEXT}
+
+_textCONTRACTCONTENTS_ {CONTRACT CONTENTS}
+
+_textDETACH_ {DETACH}
+
+_textEXPANDCONTENTS_ {EXPAND CONTENTS}
+
+_textCONTRACT_ {CONTRACT TEXT}
+
+_textHIGHLIGHT_ {HIGHLIGHTING}
+
+_textNOHIGHLIGHT_ {NO HIGHLIGHTING}
+
+_textPRINT_ {PRINT}
+
+_textnextsearchresult_{next search result}
+_textprevsearchresult_{previous search result}
+
+# macros for printing page
+_textreturnoriginal_ {Return to the original page}
+_textprintpage_ {Print this page}
+_textshowcontents_ {Show the table of contents}
+_texthidecontents_ {Hide the table of contents}
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ {_If_(_thislast_,results _thisfirst_ - _thislast_ for query: _cgiargq_,No matches for query: _cgiargq_)}
+_textnoquerytitle_ {Search page}
+
+_textsome_ {some}
+_textall_ {all}
+_textboolean_ {boolean}
+_textranked_ {ranked}
+_textnatural_ {natural}
+_textsortbyrank_ {relevance rank}
+_texticonsearchhistorybar_ {search history}
+
+_textifeellucky_ {I'm feeling lucky!}
+
+#alt text for query buttons
+_textusequery_ {use this query}
+_textfreqmsg1_ {Word count: }
+_textpostprocess_ {_If_(_quotedquery_,<br><i>post-processed to find _quotedquery_</i>
+)}
+_textinvalidquery_ {Invalid query syntax}
+_textstopwordsmsg_ {The following words are too common and were ignored: }
+_textlucenetoomanyclauses_ {Your query contained too many search terms; please try a more specific query.}
+
+_textmorethan_ {More than }
+_textapprox_ {About }
+_textnodocs_ {No documents matched the query.}
+_text1doc_ {1 document matched the query.}
+_textlotsdocs_ {documents matched the query.}
+_textmatches_ {Matches }
+_textbeginsearch_ {Begin Search}
+_textrunquery_ {Run Query}
+_textclearform_ {Clear Form}
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ {Words}
+_textinfield_ {... in field}
+_textfoldstem_ {(fold, stem)}
+
+_textadvquery_ {Or enter a query directly:}
+_textallfields_ {all fields}
+_texttextonly_ {text only}
+_textand_ {and}
+_textor_ {or}
+_textandnot_ {and not}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+# the space after "level" (before the right bracket) is required, otherwise no space between "Search" and "in"
+
+_textsimplesearch_ {Search in _indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ sorting results by _sfselection_) for _querytypeselection_ of the words}
+
+_textadvancedsearch_ {Search in _indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level )_If_(_nselection_, in _nselection_ language) using _querytypeselection_ query}
+
+_textadvancedmgppsearch_ {Search in _indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level )_If_(_nselection_, in _nselection_ language), and display results in _formquerytypeadvancedselection_ order, for}
+
+_textadvancedlucenesearch_ {Search in _indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ sorting results by _sfselection_\,) for }
+
+# the space after "Search" is required, otherwise no space between "Search" and "in"
+
+_textformsimplesearch_ {Search _If_(_jselection_, in _jselection_)_If_(_gformselection_, at _gformselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\, sorting results by _sfselection_\,) for _formquerytypesimpleselection_ of }
+
+_textformadvancedsearchmgpp_ {Search _If_(_jselection_, in _jselection_)_If_(_gformselection_, at _gformselection_ level )_If_(_nselection_, in _nselection_ language), and display results in _formquerytypeadvancedselection_ order, for }
+
+_textformadvancedsearchlucene_ {Search _If_(_jselection_, in _jselection_)_If_(_gformselection_, at _gformselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\, sorting results by _sfselection_\,) for }
+
+_textnojsformwarning_ {Warning: Javascript is disabled in your web browser. <br>To use form searching, please enable it.}
+_textdatesearch_ {This collection can be searched for documents within a date range, or documents that contain a particular date. This is an optional feature of the search.}
+_textstartdate_ {Start (or only) date:}
+_textenddate_ {End date:}
+_textbc_ {B.C.E.}
+_textad_ {C.E.}
+_textexplaineras_ {C.E. and B.C.E are alternatives for A.D. and B.C. respectively.  These terms are considered to be culture indiscriminate, and stand for "Common Era" and "Before the Common Era"} 
+
+_textstemon_ { (ignoring word endings)}
+
+_textsearchhistory_ {Search History}
+
+#text macros for search history
+_textnohistory_ {No entries in the search history}
+_texthresult_ {result}
+_texthresults_ {results}
+_texthallwords_ {all words}
+_texthsomewords_ {some words}
+_texthboolean_ {boolean}
+_texthranked_ {ranked}
+_texthcaseon_ {case must match}
+_texthcaseoff_ {casefolded}
+_texthstemon_ {stemmed}
+_texthstemoff_ {unstemmed}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ {
+Preferences have been set as follows. Do not use your browser's
+"back" button - it will unset them! Instead, click one of the
+buttons on the access bar above.
+}
+_textsetprefs_ {set preferences}
+_textsearchprefs_ {Search preferences}
+_textcollectionprefs_ {Collection preferences}
+_textpresentationprefs_ {Presentation preferences}
+_textpreferences_ {Preferences}
+_textcasediffs_ {Case differences:}
+_textignorecase_ {ignore case differences}
+_textmatchcase_ {upper/lower case must match}
+_textwordends_ {Word endings:}
+_textstem_ {ignore word endings}
+_textnostem_ {whole word must match}
+_textaccentdiffs_ {Accent differences:}
+_textignoreaccents_ {ignore accents}
+_textmatchaccents_ {accents must match}
+
+_textprefop_ {Return up to _maxdocoption_ hits with _hitsperpageoption_ hits per page.}
+_textextlink_ {Access to external Web pages:}
+_textintlink_ {Source documents retrieved from:}
+_textlanguage_ {Interface language:}
+_textencoding_ {Encoding:}
+_textformat_ {Interface format:}
+_textall_ {all}
+_textquerymode_ {Query mode:}
+_textsimplemode_ {simple query mode}
+_textadvancedmode_ {advanced query mode (allows boolean searching using !, &amp;, |, and parentheses)}
+_textlinkinterm_ {through intermediate page}
+_textlinkdirect_ {go directly there}
+_textdigitlib_ {the digital library}
+_textweb_ {the web}
+_textgraphical_ {Graphical}
+_texttextual_ {Textual}
+_textcollectionoption_ {<p>
+Subcollections to include:
+<br>}
+
+_textsearchtype_ {Query style:}
+_textformsearchtype_ {fielded with _formnumfieldoption_ fields}
+_textplainsearchtype_ {normal with _boxsizeoption_ query box}
+_textregularbox_ {single line}
+_textlargebox_ {large}
+
+_textrelateddocdisplay_ {display related documents}
+_textsearchhistory_ {Search history:}
+_textnohistory_ {No search history}
+_texthistorydisplay_ {display _historynumrecords_ search history records}
+_textnohistorydisplay_ {do not display search history}
+
+_textbookoption_  {Book viewer mode:}
+_textbookvieweron_ {on}
+_textbookvieweroff_ {off}
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ {Sort documents by}
+_textalsoshowing_ {also showing}
+_textwith_ {with at most}
+_textdocsperpage_ {documents per page}
+
+_textfilterby_ {Get documents containing}
+_textall_ {all}
+_textany_ {any}
+_textwords_ {of the words}
+_textleaveblank_ {leave this box blank to get all the documents}	    
+
+_browsebuttontext_ {"Sort Documents"}
+
+_nodata_ {<i>no data</i>}
+_docs_ {documents}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ {Help}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_{browse documents by _1_ by clicking the _2_ button}
+
+_textSearchhelp_ {search for particular words that appear in the text by clicking the _labelSearch_ button}
+_textTohelp_ {browse documents by To field by clicking the _labelTo_ button}
+_textFromhelp_ {browse documents by From field by clicking the _labelFrom_ button}
+_textBrowsehelp_ {browse documents}
+_textAcronymhelp_ {browse documents by acronym occurrence by clicking the _labelAcronym_ button}
+_textPhrasehelp_ {browse phrases occurring in documents by clicking the _labelPhrase_ button. This uses the phind phrase browser.}
+
+_texthelptopicstitle_ {Topics}
+
+_textreadingdocs_ {How to read the documents}
+
+_texthelpreadingdocs_ {
+<p>You can tell when you have arrived at an individual book or document
+because its title, or an image of the front cover, appears at the top
+left of the page. In some collections, a table of contents appears, while in others 
+(eg. when the paged image option is used) 
+just the page number is shown, along with a box that allows you to select a 
+new page and go forward and backward. In the table of contents, the current 
+section heading is in bold face, and the table is expandable -- click on the folders 
+to open or close them; click on the open book at the top to close it.</p>
+
+<p>Underneath is the text of the current section. When you have read
+through it, there are arrows at the bottom to take you on to the next
+section or back to the previous one.</p>
+
+<p>Below the title or front-cover image are some buttons. Click on
+<i>_document:textEXPANDTEXT_</i> to expand out the whole text of the current section, or
+book. If the document is large, this could take a long time and use a lot
+of memory! Click on <i>_document:textEXPANDCONTENTS_</i> to expand out the whole table of
+contents so that you can see the titles of all chapters and
+subsections. Click on <i>_document:textDETACH_</i> to make a new browser window for this
+document. (This is useful if you want to compare documents, or read two at
+once.) Finally, when you do a search the words you search for are
+highlighted. Click on <i>_document:textNOHIGHLIGHT_</i> to remove highlighting.</p>
+}
+
+# help about the icons
+_texthelpopenbookshelf_ {Open this bookshelf}
+_texthelpopenbook_ {Open/close this book}
+_texthelpviewtextsection_ {View this section of the text}
+_texthelpexpandtext_ {Display all text, or not}
+_texthelpexpandcontents_ {Expand table of contents, or not}
+_texthelpdetachpage_ {Open this page in a new window}
+_texthelphighlight_ {Highlight search terms, or not}
+_texthelpsectionarrows_ {Go to the previous/next section}
+
+
+_texthelpsearchingtitle_ {How to search for particular words}
+
+_texthelpsearching_ {
+<p>
+  From the search page, you make a query in these simple steps:<p>
+  
+  <ol><li>Specify what items you want to search
+      <li>Say whether you want to search for all or just some of the words
+      <li>Type in the words you want to search for
+      <li>Click the <i>Begin Search</i> button
+  </ol>
+
+<p>When you make a query, the titles of twenty matching documents will be shown.
+There is a button at the end to take you on to the next twenty documents.  From
+there you will find buttons to take you on to the third twenty or back to the
+first twenty, and so on.  Click the title of any document, or the little button
+beside it, to see it.
+
+<p>A maximum of 50 is imposed on the number of
+  documents returned.  You can change this number by clicking the
+  <i>_Global:linktextPREFERENCES_</i> button at the top of the page.<p>
+}
+
+_texthelpquerytermstitle_ {Search terms}
+_texthelpqueryterms_ {
+<p>Whatever you type into the query box is interpreted as a list of words or phrases
+called "search terms."  A term is a single word containing only letters and digits, or a phrase consisting of a sequence of words enclosed in double quotes ("...").  Terms are separated by white spaces.  If any other characters such
+as punctuation appear, they serve to separate terms just as though they were
+spaces.  And then they are ignored.  You can't search for words that include
+punctuation.
+
+<p>For example, the query<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>will be treated the same as<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}
+
+_texthelpmgppsearching_ {
+For collections built with MGPP a few other options are available. 
+
+<ul>
+<li>A <b>*</b> at the end of a query term  matches all words <b>starting with</b> that word, e.g. <b>comput*</b> matches all words starting with <b>comput</b>.
+<li><b>/x</b> can be used to give higher weight to one or more of the query terms, eg <b>computer/10 science</b> gives computer 10 times more weight than science when ranking documents.
+</ul>
+}
+
+_texthelplucenesearching_ {
+For collections built with Lucene a few other options are available. 
+
+<ul>
+<li><b>?</b> can be used as a wildcard in place of a single letter. For example, <b>b?t</b> will match  <b>bet</b>, <b>bit</b> and <b>bat</b> etc.
+<li><b>*</b> can be used as a wildcard in place of multiple letters. For example, <b>comput*</b> matches all words starting with <b>comput</b>.
+</ul>
+Both of these wildcards can be used in the middle of a term, or at the end. They cannot be used at the start of a search term.
+}
+
+_texthelpquerytypetitle_ {Query type}
+_texthelpquerytype_ {
+<p>There are two different kinds of query.
+
+<ul>
+  <li>Queries for <b>all</b> of the words.  These look for documents (or
+      chapters, or titles) that contain all the words you have specified.
+      Documents that satisfy the query are displayed, in build order.
+<p>
+
+  <li>Queries for <b>some</b> of the words.  Just list some terms that are
+      likely to appear in the documents you are looking for.  Documents are
+      displayed in order of how closely they match the query.  When determining
+      the degree of match,
+
+      <p><ul>
+        <li> the more search term occurrences a document contains, the closer it matches;
+        <li> terms which are rare in the collection as a whole are more important than common ones;
+        <li> short documents match better than long ones.
+      </ul>
+</ul>
+
+<p>Use as many search terms as you like--a whole sentence, or even a
+whole paragraph.  If you specify only
+one term, documents will be ordered by its frequency of occurrence.<p>
+}
+
+_texthelpadvancedsearchtitle_ {Advanced searching using the _1_ search engine}
+
+_texthelpadvancedsearch_ {
+<p>If you have selected advanced query mode (in preferences) you have slightly different search options. 
+}
+
+_texthelpadvsearchmg_ {
+Advanced searching in MG collections gives you two options, ranked and boolean.
+A <b>ranked</b> search is exactly the same as the <b>some</b> search descibed in <a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_
+}
+
+_texthelpbooleansearch_ {
+A <b>boolean</b> search allows you to combine terms
+using &amp; (for "and"), | (for "or"), and ! (for "not"), using parentheses for grouping if desired. The default operator is | (for "or").
+<p>
+For example, <b>snail &amp; farming</b> will match documents which contain both <b>snail</b> AND <b>farming</b>, whereas <b>snail | farming</b> will match documents that contain either <b>snail</b> OR <b>farming</b>.
+<b>snail !farming</b> will match documents that contain <b>snail</b> AND DO NOT contain <b>farming</b>.
+<p>
+More precise queries can be specified using combinations of operators and parentheses. For example, <b>(sheep | cattle) &amp; (farm | station)</b>, or <b>sheep | cattle | goat !pig</b>.
+}
+
+_texthelpadvsearchmgpp_ {
+Advanced searches in MGPP collections use boolean operators. _texthelpbooleansearch_
+<p>The results can be displayed in <b>ranked</b> order, as described for the <b>some</b> search in <a href="\#query-type">_texthelpquerytypetitle_</a>, or in "natural" (or "build") order. The latter is the order that documents were processed during the creation of the collection.
+<p>
+Further operators include <b>NEARx</b> and <b>WITHINx</b>.
+NEARx is used to specify the maximum distance (x words) 
+which can separate two query terms for a document to match.
+WITHINx specifies that the second term must occur within x words <i>after</i> the first term. This is similar to NEAR but the order is important. The default distance is 20.
+}
+
+_texthelpadvancedsearchextra_{NOTE: These operators are all ignored if you are searching in simple query mode.}
+
+_texthelpadvsearchlucene_ {
+Advanced searches in Lucene collections use boolean operators. _texthelpbooleansearch_
+}
+
+_texthelpformsearchtitle_ {Fielded searching}
+
+_texthelpformsearch_ {
+<p>Fielded searching provides the opportunity to combine searches across fields. For example, one can search for "Smith" in Title AND "snail farming" in Subject. In simple query mode, each line of the form behaves like a normal single line search. The individual lines of the form are combined using AND (for an "all" search) or OR (for a "some" search). Terms inside the field are also combined the same way. In advanced mode, you can specify different combinations of AND/OR/NOT between the fields using the drop-down lists, and inside a field you can use boolean operators.
+}
+
+_texthelpformstemming_ {The "fold" and "stem" boxes allow you to specify whether the terms inside that field are casefolded or stemmed. These are both switched off by default for advanced form searching.}
+
+_textdatesearch_ {Searching with Dates}
+
+_texthelpdatesearch_ {
+Date search lets you find documents that, as well as matching your search 
+terms, are about events within a certain timeframe.  You can search for 
+documents from a certain year or from a range of years.  Note that you do not 
+have to have any search terms -- you can search by date alone; and also that 
+you do not have to use dates in your search, if you do not type any dates in it
+ is just the same as if the date search didn't exist.<p>
+}
+
+_texthelpdatehowtotitle_ {How to use this feature:}
+_texthelpdatehowto_ {
+<ul>
+   <li>To search for documents about a single year:<p>
+   <ul>
+       <li>Type in any ordinary search terms as you normally would.
+       <li>Type the year you want into the "Start (or only) date" box.
+       <li>If your date is from before the common era (also known as before 
+           Christ), choose the "B.C.E" option from the pulldown menu next to that
+           box.
+       <li>Begin your search as you ordinarily would.
+   </ul>
+<p><li>To search for documents about a time period or range of years:<p>
+   <ul>
+       <li>Type in any ordinary search terms as you normally would.
+       <li>Type the earlier date into the "Start (or only) date" box.
+       <li>Type the later date into the "End date" box.
+       <li>Select "B.C.E" option from the pulldown menu next to any date from before 
+           the common era (also known as before Christ).
+       <li>Begin your search as you ordinarily would.
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ {The way results of your search work}
+_texthelpdateresults_ {
+Generally speaking a search for documents about the year 1903 will not return documents that, say, reference books written in 1903, just documents about 1903.  However, the way that the documents' dates are found, it will return documents that have a date range (for example 1899-1911) that includes 1903, and also those documents which, as part of their text name the century that 1903 is a part of (for example 20th century or twentieth century).  This means that for some documents, the dates in your search will not actually appear in the document text.  For a range search, all of this applies to every date in the range.<p>
+}
+
+_textchangeprefs_ {Changing your preferences}
+
+_texthelppreferences_ {
+<p>When you click the <i>_Global:linktextPREFERENCES_</i> button at the top of the page you will
+be able to change some features of the interface to suit your own requirements.
+}
+
+_texthelpcollectionprefstitle_ {Collection preferences}
+_texthelpcollectionprefs_ {
+<p>Some collections comprise several subcollections, which can be searched
+independently or together, as one unit.  If so, you can select which
+subcollections to include in your searches on the Preferences page.
+}
+
+_texthelplanguageprefstitle_ {Language preferences}
+_texthelplanguageprefs_ {
+<p>Each collection has a default presentation language, but you can switch to
+a different language if you like.  You can also alter the encoding scheme
+used by Greenstone for output to the browser -- the software chooses
+sensible defaults, but with some browsers it may be necessary to switch to 
+a different encoding scheme to ensure correct character display.
+All collections allow you to
+switch from the standard graphical interface format to a textual one. This
+is particularly useful for visually impaired users who use large screen
+fonts or speech synthesizers for output.
+}
+
+_texthelppresentationprefstitle_ {Presentation preferences}
+_texthelppresentationprefs_ {
+Depending on the particular collection, there may be several options you can
+set that control the presentation.
+
+<p>Collections of Web pages allow you to suppress the Greenstone navigation bar at
+the top of each document page, so that once you have done a search you land at
+the exact Web page that matches without any Greenstone header.  To do another
+search you will have to use your browser's "back" button.  These collections
+also allow you to suppress Greenstone's warning message when you click a link
+that takes you out of the digital library collection and on to the Web itself.
+And in some Web collections you can control whether the links on the search
+results page take you straight to the actual URL in question, rather than to
+the digital library's copy of the page.
+}
+
+_texthelpsearchprefstitle_ {Search preferences}
+_texthelpsearchprefs_ {
+<p>You can switch to an "advanced" query mode which allows you to combine terms
+using &amp; (for "and"), | (for "or"), and ! (for "not"), using parentheses for 
+grouping if desired. This allows you to specify more precise queries. 
+<p>_selectsearchtypeprefs_
+<p>_selectwordmodificationprefs_
+<p>You can turn on the search history feature, which shows you your last few
+queries.  This makes it easy to repeat slightly modified versions of previous
+queries. 
+<p>Finally, you can control the number of hits returned, and the
+number presented on each screenful.
+}
+
+_textcasefoldprefs_ {A pair of buttons controls whether upper and lower case must match when searching. For example, if "_preferences:textignorecase_" is selected, <i>snail farming</i> will be treated the same as <i>Snail Farming</i> and <i>SNAIL FARMING</i>.}
+_textstemprefs_{A pair of buttons controls whether to ignore word endings or not when searching. For example, if "_preferences:textstem_" is selected, <i>snail farming</i> will be treated the same as <i>snails farm</i> and <i>snail farmer</i>. This currently only works properly for English language text. _selectstemoptionsprefs_}
+_textaccentfoldprefs_ {A pair of buttons controls whether accented and unaccented letters must match when searching. For example, if "_preferences:textignoreaccents_" is selected, <i>fÃ©dÃ©ration</i> will be treated the same as <i>fedÃ©ration</i> and <i>federation</i>.}
+ 
+_textstemoptionsprefs_ {It may be more convenient and precise to use the search term truncation facility described above in "_texthelpquerytermstitle_".}
+
+_textsearchtypeprefsplain_ {It is possible to get a large query box, so that you can easily do paragraph-sized searching. It is surprisingly quick to search for large amounts of text.}
+
+_textsearchtypeprefsform_ {You can change the number of fields shown in the search form.}
+
+_textsearchtypeprefsboth_ {You can switch the search type of the collection between "normal" search, and "fielded" search. 
+<ul>
+<li>Normal search provides a single query box. _textsearchtypeprefsplain_</li>
+<li>Fielded search provides a number of query boxes, each querying a different field of the index. This enables searching over different fields at once. _textsearchtypeprefsform_ </li>
+</ul>
+}
+
+
+
+_texttanumbrowseoptions_ {There are _numbrowseoptions_ ways to find information in this collection:}
+
+_textsimplehelpheading_ {How to find information in the _collectionname_ collection}
+
+_texthelpscopetitle_ {Scope of queries}
+_texthelpscope_ {
+<p>
+In most collections you are given a choice of different indexes to search. For example, there might
+be author or title indexes. Or there might be chapter or paragraph indexes. Generally,
+the full matching document is returned regardless of which index you search.
+<p>If documents are books, they will be opened at the appropriate place.
+}
Index: /gsdl/stable/macros/english2.dm
===================================================================
--- /gsdl/stable/macros/english2.dm	(revision 20131)
+++ /gsdl/stable/macros/english2.dm	(revision 20131)
@@ -0,0 +1,1170 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Language text and icon macros 
+# -- this file contains text that is of less importance
+######################################################################
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ { documents. }
+_lastupdate_ {Last updated}
+_ago_ {days ago.}
+_colnotbuilt_ {Collection not built.}
+
+### taken from here
+
+_textpoem_ {
+<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>may peace and calmness surround you,
+<br>may you reside in the warmth of a summer's haze,
+<br>may the ocean of your travels be as smooth as the polished greenstone.
+}
+
+_textgreenstone_ { 
+<p>Greenstone is a semi-precious stone that (like this software) is sourced
+in New Zealand.  In traditional Maori society it was the most highly prized
+and sought after of all substances.  It can absorb and hold <i>wairua</i>,
+which is a spirit or life force, and is endowed with traditional virtues
+that make it an appropriate emblem for a public-domain digital library
+project.  Its lustre shows charity; its translucence, honesty; its
+toughness, courage; and the sharp edge it can take, justice.  The carved
+piece used in the Greenstone Digital Library Software logo is a <i>patu</i>
+or fighting club, and is a family heirloom of one of our project members.
+In hand-to-hand combat its delivery is very quick, very accurate, and very
+complete.  We like to think these qualities also apply to our software, the
+razor sharp edge of the <i>patu</i> symbolizing the leading edge of
+technology.</p>
+}
+
+_textaboutgreenstone_ {
+<p>Greenstone is a suite of software for building and distributing digital
+library collections. It provides a new way of organizing information and
+publishing it on the Internet or on CD-ROM.  Greenstone is produced by the
+<b>New Zealand Digital Library Project</b> at the <b>University of
+Waikato</b>, and developed and distributed in cooperation with
+<b>UNESCO</b> and the <b>Human Info NGO</b>.  It is open-source
+software, available from <a
+href="http://greenstone.org">http://greenstone.org</a> under the terms of
+the GNU General Public License.
+</p>
+
+<p>The aim of the software is to empower users, particularly in
+universities, libraries, and other public service institutions, to
+build their own digital libraries.  Digital libraries are radically
+reforming how information is disseminated and acquired in UNESCO's
+partner communities and institutions in the fields of education,
+science and culture around the world, and particularly in developing
+countries.  We hope that this software will encourage the effective
+deployment of digital libraries to share information and place it in
+the public domain.
+</p>
+
+<p>This software is developed and distributed as an international
+cooperative effort established in August 2000 among three parties.
+</p>
+
+<p>
+<a href="http://nzdl.org"><b>New Zealand Digital Library Project at the University of Waikato</b></a>
+<br>
+Greenstone software grew out of this project, and this initiative
+has been endorsed by the Communication Sub-Commission of the New
+Zealand National Commission for UNESCO as part of New Zealand's
+contribution to UNESCO's programme.
+</p>
+
+<p>
+<a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+class="logo"></a>
+<a href="http://www.unesco.org"><b>United Nations Educational, Scientific and Cultural Organization</b></a>
+<br>
+The dissemination of educational, scientific and cultural information
+throughout the world, and particularly its availability in developing
+countries, is central to UNESCO's goals as pursued within its
+intergovernmental Information for All Programme, and appropriate,
+accessible information and communication technology is seen as an important
+tool in this context.
+</p>
+
+<p>
+<a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>The Human Info NGO, based in Antwerp, Belgium</b></a>
+<br>
+This project works with UN agencies and other NGOs, and has established
+a worldwide reputation for digitizing documentation of interest to
+human development and making it widely available, free of charge to
+developing nations and on a cost-recovery basis to others.
+</p>
+}
+
+
+_textdescrselcol_ {select a collection}
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ {There are four further buttons on the home page}
+
+_textnocollections_ {
+<p>There are currently no collections available to this Greenstone installation. 
+To add some collections you may either
+<ul><li>Use <a href="_httppagecollector_">The Collector</a> to build new collections
+    <li>If you have a Greenstone cd-rom you may install collections from cd-rom
+</ul>
+}
+
+_text1coll_ {This Greenstone installation contains 1 collection}
+
+_textmorecolls_ {This Greenstone installation contains _1_ collections}
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ {External Link}
+_textlinknotfound_ {Internal Link not Found}
+
+_textextlinkcontent_ {The link you have selected is external to any of your currently selected collections.
+    If you still wish to view this link and your browser has access to 
+    the Web, you can <a href="_nexturl_">go forward</a> to this page; otherwise 
+    use your browsers "back" button to return to the previous document.}
+
+_textlinknotfoundcontent_ {For reasons beyond our control, the internal link you have selected 
+    does not exist.  This is probably due to an error in the source collection.
+    Use your browsers "back" button to return to the previous document.}
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ {
+
+<h3>Link to "_2_" collection</h3>
+
+<p> The link you have selected is external to the "_collectionname_"
+    collection (it links to the "_2_" collection).
+    If you wish to view this link in the "_2_" collection you can 
+    <a href="_httpdoc_&amp;c=_1_&amp;cl=_cgiargcl_&amp;d=_3_">go forward</a> to this page; 
+    otherwise use your browsers "back" button to return to the previous document.
+}
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ {Greenstone Digital Library}
+
+_textusername_ {username}
+_textpassword_ {password}
+
+_textmustbelongtogroup_ {Note that you must belong to the "_cgiargug_" group to access this page}
+
+_textmessageinvalid_ {The page you have requested requires you to sign in.<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)
+Please enter your Greenstone username and password.}
+
+_textmessagefailed_ {Either your username or password was incorrect.}
+
+_textmessagedisabled_ {Sorry, your account has been disabled. Please contact
+the webmaster for this site.}
+
+_textmessagepermissiondenied_ {Sorry, you do not have permission to access this page.}
+
+_textmessagestalekey_ {The link you have followed is now stale. 
+Please enter your password to access this page.}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ {
+<p>This Greenstone installation does not include any documentation. This
+may be because:
+<ol>
+ <li>Greenstone was installed from CD-ROM using a compact installation.
+ <li>Greenstone was installed from a distribution downloaded from the
+ internet.
+</ol>
+In either case you may obtain the documentation either from the <i>docs</i>
+directory of a Greenstone CD-ROM or by visiting <a
+href="http://www.greenstone.org">http://www.greenstone.org</a>.
+}
+
+_textuserguide_ {User's Guide}
+_textinstallerguide_ {Installer's Guide}
+_textdeveloperguide_ {Developer's Guide}
+_textpaperguide_ {From Paper to Collection}
+_textorganizerguide_ {Using the Organizer}
+
+_textgsdocstitle_ {greenstone documentation}
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ {Build collection}
+_textbildsuc_ {Collection built successfully.}
+_textviewbildsummary_ {
+You may <a href="_httppagex_(bsummary)" target=_top>view the build
+summary</a> of this collection for further details.
+}
+_textview_ {View collection}
+
+_textbild1_ {
+The collection is now being built: this might take some time. The building
+status line below gives feedback on how the operation is progressing.
+}
+
+_textbild2_ {
+To stop the building process at any time, click here.
+<br>The collection you are working on will remain unchanged.
+}
+
+_textstopbuild_ {stop building}
+
+_textbild3_ {
+If you leave this page (and have not cancelled the building process with
+the "stop building" button) the collection will continue to build and will
+be installed upon successful completion.
+}
+
+_textbuildcancelled_ {Build cancelled}
+
+_textbildcancel1_ {
+The collection building process was cancelled. Use the yellow buttons below
+to make changes to your collection or restart the building process.
+}
+
+_textbsupdate1_ {Building status update in 1 second}
+_textbsupdate2_ {Building status update in}
+_textseconds_ {seconds}
+
+_textfailmsg11_ {
+The collection could not be built as it contains no data. Make sure that at
+least one of the directories or files you specified on the <i>source
+data</i> page exists and is of a type or (in the case of a directory)
+contains files of a type, that Greenstone can process.
+}
+
+_textfailmsg21_ {The collection could not be built (import.pl failed).}
+_textfailmsg31_ {The collection could not be built (buildcol.pl failed).}
+_textfailmsg41_ {The collection was built successfully but could not be installed.}
+_textfailmsg71_ {An unexpected error occurred while attempting to build your collection}
+
+
+_textblcont_ {The build log contains the following information:}
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ {default structure}
+_textmore_ {more}
+_textinfo_ {Collection information}
+_textsrce_ {Source data}
+_textconf_ {Configure collection}
+_textdel_ {Delete collection}
+_textexpt_ {Export collection}
+
+_textdownloadingfiles_ {Downloading files ...}
+_textimportingcollection_ {Importing collection ...}
+_textbuildingcollection_ {Building collection ...}
+_textcreatingcollection_ {creating collection ...}
+
+_textcollectorblurb_ {
+<i>The pen is mightier than the sword!
+<br>Building and distributing information collections carries responsibilities
+that you may want to reflect on before you begin.
+There are legal issues of copyright: being able to access documents doesn't
+mean you can necessarily give them to others.
+There are social issues:  collections should respect the customs of the
+community out of which the documents arise.
+And there are ethical issues: some things simply should not be made 
+available to others.
+<br>Be sensitive to the power of information and use it wisely.
+</i>
+}
+
+_textcb1_ {
+The Collector helps you to create new collections, modify or add to
+existing ones, or delete collections.  To do this you will be guided through a
+sequence of Web pages which request the information that is needed.
+}
+
+_textcb2_ {First, you must decide whether to}
+_textcnc_ {create a new collection}
+_textwec_ {work with an existing one, adding data to it or deleting it.}
+
+_textcb3_ {
+In order to build or modify digital library collections you must sign in.
+This is to protect you from others logging in to your computer and altering
+the information on it.  Note: for security reasons you will be
+automatically logged out once a 30 minute period has elapsed since you
+logged in.  If this happens, don't worry! -- you will be invited to log in
+again and can continue from where you left off.
+}
+
+_textcb4_ {
+Please enter your Greenstone username and password, and click the button to
+sign in.
+}
+
+_textfsc_ {
+First select the collection that you want to work with (write protected
+collections won't appear in this list).
+}
+
+_textwtc_ {With the collection you have selected, you can}
+_textamd_ {Add more data and rebuild the collection}
+_textetc_ {Edit the collection configuration file and rebuild the collection}
+_textdtc_ {Delete the collection entirely}
+_textetcfcd_ {Export the collection for writing to a self-installing Windows CD-ROM}
+_textcaec_ {Changing an existing collection}
+_textnwec_ {No write-enabled collections are available for modifying}
+_textcianc_ {Creating a new collection}
+_texttsosn_ {The sequence of steps needed to create a new digital library collection is:}
+_textsin_ {Specify its name (and associated information)}
+_textswts_ {Specify where the source data comes from}
+_textatco_ {Adjust the configuration options (advanced users only)}
+_textbtc_ {"Build" the collection (see below)}
+_textpvyh_ {Proudly view your handiwork.}
+
+_texttfsiw_ {
+The fourth step is where the computer does all the work.  In the "building"
+process the computer makes all the indexes and gathers together any other
+information that is required to make things work.  But first you have to
+specify the information.
+}
+
+_textadab_ {
+A diagram appears below that will help you keep track of where you are.
+The green button is the one that you click to carry on in the sequence.  As
+you go through the sequence, the buttons will change to yellow.  You can
+return to a previous page by clicking on the corresponding yellow button in
+the diagram.
+}
+
+_textwyar_ {
+When you are ready, click the green "collection information" button to
+begin creating your new digital library collection!
+}
+
+_textcnmbs_ {Collection name must be specified}
+_texteambs_ {Email address must be specified}
+_textpsea_ {Please specify email address in the form: username@domain}
+_textdocmbs_ {Description of collection must be specified}
+
+_textwcanc_ {
+When creating a new collection you need to enter some preliminary
+information about the source data.  This process is structured as a series
+of Web pages, overseen by The Collector.  The bar at the bottom of the page
+shows you the sequence of pages to be completed.
+}
+
+_texttfc_ {Title for collection:}
+
+_texttctiasp_ {
+The collection title is a short phrase used throughout the digital library
+to identify the content of the collection.  Example titles include
+"Computer Science Technical Reports" and "Humanity Development Library."
+}
+
+_textcea_ {Contact email address:}
+
+_textteas_ {
+This email address specifies the first point of contact for the collection.
+If the Greenstone software detects a problem, a diagnostic report is sent
+to this address.  Enter an email address in its full form:
+<tt>name@domain</tt>.
+}
+
+_textatc_ {About this collection:}
+
+_texttiasd_ {
+This is a statement describing the principles governing what is included in
+the collection.  It appears on the first page when the collection is
+presented.
+}
+
+_textypits_ {
+Your position in the sequence is indicated by an arrow underneath--in this
+case, the "collection information" stage.  To proceed, click the green
+"source data" button.
+}
+
+_srcebadsources_ {
+<p>One or more of the input sources you specified is unavailable (marked
+_iconcross_ below).
+
+<p>This might be because
+<ul>
+<li>The file, FTP site or URL does not exist.
+<li>You need to dial up your ISP first.
+<li>You are trying to access a URL from behind a firewall (this is the case
+if you normally have to present a username and password to access the
+internet).
+</ul>
+
+<p>If this is a URL that you can see in your browser, it may be coming from
+a locally cached copy. Unfortunately, locally cached copies are invisible
+to our mirroring process. In this case we recommend that you download the
+pages using your browser first.
+}
+
+_textymbyco_ {
+<p>You may base your collection on either
+<ul>
+<li>The default structure
+<dl><dd>The new collection may contain documents in the following formats:
+HTML, plain text, "m-box" email, PDF, RTF, MS Word, PostScript, PowerPoint, 
+Excel, images, CDS/ISIS. </dd></dl>
+<li>An existing collection
+<dl><dd>The files in your new collection must be exactly the same type as those
+used to build the existing one.</dd></dl>
+</ul>
+}
+
+_textbtco_ {Base the collection on}
+_textand_ {Add new data}
+_textad_ {Adding data:}
+
+_texttftysb_ {
+The files that you specify below will be added to the collection. Make sure
+that you do not re-specify files that are already in the collection:
+otherwise two copies will be included. Files are identified by their full
+pathname, Web pages by their absolute Web address.
+}
+
+_textis_ {Input sources:}
+
+_textddd1_ {
+<p>If you use file:// or ftp:// to specify a file, that file will be
+downloaded.
+
+<p>If you use http:// it depends on whether the URL gives you a normal web
+page in your browser, or a list of files.  If a page, that page will be
+downloaded -- and so will all pages it links to, and all pages they link
+to, etc. -- provided they reside on the same site, below the URL.
+
+<p>If you use file:// or ftp:// to specify a folder or directory, or give a
+http:// URL that leads to a list of files, everything in the folder and all
+its sub-folders will be included in the collection.
+
+<p>Click the "more sources" button to get more input boxes.
+}
+
+_textddd2_ {
+<p>Click one of the green buttons. If you are an advanced user you may want
+to adjust the collection configuration. Alternatively, go straight to the
+building stage. Remember, you can always revisit an earlier stage by
+clicking its yellow button.
+}
+
+_textconf1_ {
+<p>The building and presentation of your collection are controlled by
+specifications in a special "configuration file".  Advanced users may want
+to alter the configuration settings.
+
+<center><p><b>If you are not an advanced user, just go to the bottom of the
+page.</b></center> 
+
+<p>To alter the configuration settings, edit the data that appears below.
+If you make a mistake, click on "Reset" to reinstate the original
+configuration settings.
+}
+
+_textreset_ {Reset}
+
+
+_texttryagain_ {
+Please <a href="_httppagecollector_" target=_top>restart the collector</a>
+and try again.
+}
+
+
+_textretcoll_ {Return to the collector}
+
+_textdelperm_ {
+Some or all of the _cgiargbc1dirname_ collection could not be
+deleted. Possible causes are:
+<ul>
+<li> Greenstone does not have permission to delete the _gsdlhome_/collect/_cgiargbc1dirname_
+directory.<br>
+You may need to remove this directory manually to complete the removal of the _cgiargbc1dirname_
+collection from this computer.</li>
+<li>Greenstone can not run the program _gsdlhome_/bin/script/delcol.pl. Make sure that this file is readable and executable.</li>
+</ul>
+}
+
+_textdelinv_ {
+The _cgiargbc1dirname_ collection is protected or invalid. Deletion was cancelled.
+}
+
+_textdelsuc_ {The _cgiargbc1dirname_ collection was successfully deleted.}
+
+_textclonefail_ {
+The _cgiargclonecol_ collection cound not be cloned. Possible causes are:
+<ul>
+<li> The _cgiargclonecol_ collection doesn't exist
+<li> The _cgiargclonecol_ collection has no collect.cfg configuration file
+<li> Greenstone does not have permission to read the collect.cfg configuration file
+</ul>
+}
+
+_textcolerr_ {Collector error.}
+
+_texttmpfail_ {
+The collector failed to read from or write to a temporary file or
+directory. Possible causes are:
+<ul>
+<li> Greenstone does not have read/write access to the _gsdlhome_/tmp
+     directory.
+</ul>
+}
+
+_textmkcolfail_ {
+The collector failed to create the directory structure required by the new
+collection (mkcol.pl failed). Possible causes are:
+<ul>
+<li> Greenstone does not have permission to write to the _gsdlhome_/tmp
+     directory.
+<li> mkcol.pl perl script errors.
+</ul>
+}
+
+_textnocontent_ {
+Collector error: no collection name was provided for the new collection. Try 
+restarting the Collector from the beginning.
+}
+
+_textrestart_ {Restart the Collector}
+
+_textreloaderror_ {
+An error occurred while creating the new collection. This may have been due
+to Greenstone getting confused by the use of your browser's "reload" or
+"back" buttons (please try to avoid using these buttons while creating a
+collection with the Collector).  It is recommended that you restart the
+Collector from the beginning.
+}
+
+_textexptsuc_ {
+The _cgiargbc1dirname_ collection was successfully exported to the
+_gsdlhome_/tmp/exported\__cgiargbc1dirname_ directory.
+}
+
+_textexptfail_ {
+<p>Failed to export the _cgiargbc1dirname_ collection.
+
+<p>This is likely to be because Greenstone was installed without the
+necessary components to support the "Export to CD-ROM" function.
+<ul>
+
+ <li>If you installed a Greenstone version earlier than 2.70w from a CD-ROM 
+ these components won't have been installed unless you selected them 
+ during a "Custom" install. You may add them to your installation by re-running 
+ the installation procedure.
+
+ <li>If you installed Greenstone from a web distribution you will need to
+ download and install an additional package to enable this function. Please
+ visit <a href="http://www.greenstone.org">http://www.greenstone.org</a> or
+ <a
+ href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">the mailing list</a>
+ for further details.
+
+</ul>
+}
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ {
+
+<p> Please specify the following file information and click _textintro_ below. </p>
+
+}
+
+_textcaec_ {Adding to an Existing Collection}
+_textbild_ {Deposit Item}
+_textintro_ {Select File}
+_textconfirm_ {Confirmation}
+_textselect_ {Select Collection}
+_textmeta_ {Specify Metadata}
+_textselectoption_ {select collection ...}
+
+_texttryagain_ {
+Please <a href="_httppagedepositor_" target=_top>restart the depositor</a>
+and try again.
+}
+
+_textselectcol_ {Select the collection to which you would like to add a new document.}
+_textfilename_ {Filename}
+_textfilesize_ {Filesize}
+
+_textretcoll_ {Return to the depositor}
+
+
+_texttmpfail_ {
+The depositor failed to read from or write to a temporary file or
+directory. Possible causes are:
+<ul>
+<li> Greenstone does not have read/write access to the _gsdlhome_/tmp
+     directory.
+</ul>
+}
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ {
+Greenstone is a suite of software which has the ability to serve digital
+library collections and build new collections.  It provides a new way of
+organizing information and publishing it on the Internet or on CD-ROM.
+Greenstone is produced by the New Zealand Digital Library Project at the
+University of Waikato, and distributed in cooperation with UNESCO and the
+Human Info NGO. It is open-source software, available from
+<i>http://greenstone.org</i> under the terms of the GNU General Public
+License.
+}
+
+_textgreenstone2_ {
+The New Zealand Digital Library website (<a
+href="http://nzdl.org">http://nzdl.org</a>) contains numerous example
+collections, all created with the Greenstone software, which are publicly
+available for you to peruse. They exemplify various searching and browsing
+options, and include collections in Arabic, Chinese, French, Maori, and
+Spanish, as well as English. There are also some music collections.
+}
+
+_textplatformtitle_ {platform}
+_textgreenstone3_ {
+Greenstone runs on Windows, Unix and Mac OS X. The distribution includes ready-to-use
+binaries for all versions of Windows, and for Linux and Mac OS X. It also includes
+complete source code for the system, which can be compiled using Microsoft
+C++ or gcc.  Greenstone works with associated software that is also freely
+available: the Apache Webserver and PERL. The user interface uses a Web
+browser: typically Netscape Navigator or Internet Explorer.
+}
+
+_textgreenstone4_ {
+Many document collections are distributed on CD-ROM using the Greenstone
+software. For example, the <i>Humanity Development Library</i> contains
+1,230 publications ranging from accounting to water sanitation. It runs on
+minimal computing facilities such as those typically found in developing
+countries. The information can be accessed by searching, browsing by
+subject, browsing by titles, browsing by organisation, browsing a list of
+how-tos, and by randomly viewing the book covers.
+}
+
+_textcustomisationtitle_ {customisation}
+_textgreenstone5_ {
+Greenstone is specifically designed to be highly extensible and
+customisable. New document and metadata formats are accommodated by writing
+"plugins" (in Perl). Analogously, new metadata browsing structures can be
+implemented by writing "classifiers." The user interface look-and-feel can
+be altered using "macros" written in a simple macro language. A Corba
+protocol allows agents (e.g. in Java) to use all the facilities associated
+with document collections. Finally, the source code, in C++ and Perl, is
+available and accessible for modification.
+}
+
+_textdocumentationtitle_ {documentation}
+_textdocuments_ {Extensive documentation for the Greenstone software is available.}
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ {mailing list}
+_textmailinglist_ {
+There is a mailing list intended primarily for discussions about the
+Greenstone digital library software.  Active users of Greenstone should
+consider joining the mailing list and contributing to the discussions.
+To subscribe, go to  <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+
+To send a message to the list, address it to <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>.
+}
+
+_textbugstitle_ {bugs}
+_textreport_ {
+We want to ensure that this software works well for you.  Please report any
+bugs to <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">the mailing list</a>.
+}
+
+_textgs3title_ {in the works}
+_textgs3_ {Greenstone 3 is a complete redesign and reimplementation which 
+retains all the advantages of Greenstone 2 (the current version)--for example, 
+it is multilingual, multiplatform, and highly configurable. It 
+incorporates all the features of the existing system, and is backwards 
+compatible: that is, it can build and run existing collections without 
+modification. Written in Java, it is structured as a network of 
+independent modules that communicate using XML: thus it runs in a 
+distributed fashion and can be spread across different servers as 
+necessary. This modular design increases the flexibility and 
+extensibility of Greenstone. Documentation and experimental releases of Greenstone 3 can be downloaded from the <a href="http://www.greenstone.org/greenstone3.html">Greenstone 3 home page</a>.}
+
+_textcreditstitle_ {credits}
+
+_textwhoswho_ {
+The Greenstone software is a collaborative effort between many
+people. Rodger McNab and Stefan Boddie are the principal architects and
+implementors.  Contributions have been made by David Bainbridge, George
+Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John
+McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd
+Reed, Bill Rogers, John Thompson, and Stuart Yeates. Other members of the New Zealand
+Digital Library project provided advice and inspiration in the design of
+the system: Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka
+Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols and Lloyd Smith. We would also like to
+acknowledge all those who have contributed to the GNU-licensed packages
+included in this distribution: MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE and XLHTML.
+}
+
+_textaboutgslong_ {about the greenstone software}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ {List of current users}
+_textuser_ {user}
+_textas_ {account status}
+_textgroups_ {groups}
+_textcomment_ {comment}
+_textadduser_ {add a new user}
+_textedituser_ {edit}
+_textdeleteuser_ {delete}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ {Edit user information}
+_textadduser_ {Add a new user}
+
+_textaboutusername_ {
+Usernames must be between 2 and 30 characters long. They can contain
+alphanumeric characters, '.', and '_'.
+}
+
+_textaboutpassword_ {
+Passwords must be between 3 and 128 characters long. They can contain any
+normal printable ASCII characters.
+}
+
+_textoldpass_ {If this field is blank the old password will be kept.}
+_textenabled_ {enabled}
+_textdisabled_ {disabled}
+
+_textaboutgroups_ {
+Groups is a comma separated list, do not put spaces after the commas.
+}
+_textavailablegroups_ {
+Predefined groups include administrator and others which assign rights for remote collection building using the Librarian Interface or the Depositor:
+<ul>
+<li><b>administrator</b>: Gives permission to access and change site configuration and user accounts.
+<li><b>personal-collections-editor</b>: Gives permission to create new personal collections
+<li><b>&lt;collection-name&gt;-collection-editor</b>: Gives permission to create and edit the "collection-name" collection, for example, reports-collection-editor.
+<li><b>all-collections-editor</b>: Gives permission to create new personal and global collections and edit <b>all</b> collections.
+</ul>
+}
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ {Delete a user}
+_textremwarn_ {Do you really want to permanently remove user <b>_cgiargumun_</b>?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ {Change password}
+_textoldpw_ {old password}
+_textnewpw_ {new password}
+_textretype_ {retype new password}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ {Your password was successfully changed.}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ {The username is invalid.}
+_textinvalidpassword_ {The password is invalid.}
+_textemptypassword_ {Please enter an initial password for this user.}
+_textuserexists_ {This user already exists, please enter another username.}
+
+_textusernameempty_ {Please enter your username.}
+_textpasswordempty_ {You must enter your old password.}
+_textnewpass1empty_ {Enter your new password and then retype it.}
+_textnewpassmismatch_ {The two versions of your new password did not match.}
+_textnewinvalidpassword_ {You entered an invalid password.}
+_textfailed_ {Either your username or password was incorrect.}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ {Greenstone version number}
+_textframebrowser_ {You must have a frame enabled browser to view this.}
+_textusermanage_ {User management}
+_textlistusers_ {list users}
+_textaddusers_ {add a new user}
+_textchangepasswd_ {change password}
+_textinfo_ {Technical information}
+_textgeneral_ {general}
+_textarguments_ {arguments}
+_textactions_ {actions}
+_textbrowsers_ {browsers}
+_textprotocols_ {protocols}
+_textconfigfiles_ {Configuration files}
+_textlogs_ {Logs}
+_textusagelog_ {usage log}
+_textinitlog_ {init log}
+_texterrorlog_ {error log}
+_textadminhome_ {admin home}
+_textreturnhome_ {Greenstone home}
+_titlewelcome_ { Administration }
+_textmaas_ {Maintenance and administration services available include:}
+_textvol_ {view on-line logs}
+_textcmuc_ {create, maintain and update collections}
+_textati_ {access technical information such as CGI arguments}
+
+_texttsaa_ {
+These services are accessed using the side navigation bar on the lefthand
+side of the page.
+}
+
+_textcolstat_ {Collection Status}
+
+_textcwoa_ {
+Collections will only appear as "running" if their build.cfg
+files exist, are readable, contain a valid builddate field (i.e. > 0),
+and are in the collection's index directory (i.e. NOT the building
+directory).
+}
+
+_textcafi_ {click <i>abbrev.</i> for information on a collection}
+_textcctv_ {click <i>collection</i> to view a collection}
+_textsubc_ {Submit Changes}
+_texteom_ {Error opening main.cfg}
+_textftum_ {Failed to update main.cfg}
+_textmus_ {main.cfg updated successfully}
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ {Build summary for "_collectionname_" collection}
+_textflog_ {Fail log for "_collectionname_" collection}
+_textilog_ {Import log for "_collectionname_" collection}
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ {SEND FEEDBACK}
+
+_greenstoneusabilitytext_ {Greenstone Usability}
+
+_textwhy_ {<p>Sending this report is a way of indicating you have found the web page you were viewing difficult or frustrating.}
+_textextraforform_ {You do not have to fill out the form -- any information will help.}
+_textprivacybasic_ {<p>The report will contain only information about the Greenstone web page you were viewing, and the technology you were using to view it (plus any optional information you provide).}
+_textstillsend_ {Would you still like to send this report?}
+
+_texterror_ {error}
+_textyes_ {Yes}
+_textno_ {No}
+_textclosewindow_ {Close Window}
+_textabout_ {About}
+_textprivacy_ {Privacy}
+_textsend_ {Send}
+_textdontsend_ {Don\\'t Send}
+_textoptionally_ {Optionally}
+
+_textunderdev_ {Details preview will be available in the final version.}
+
+_textviewdetails_ {View report details}
+_textmoredetails_ {More details}
+_texttrackreport_ {Track this report}
+_textcharacterise_ {What kind of problem is it}
+_textseverity_ {How bad is the problem}
+ 
+_textbadrender_ {Page looks strange}
+_textcontenterror_ {Content error}
+_textstrangebehaviour_ {Strange behaviour}
+_textunexpected_ {Something unexpected happened}
+_textfunctionality_ {Hard to use}
+_textother_ {Other}
+
+_textcritical_ {Critical}
+_textmajor_ {Serious}
+_textmedium_ {Medium}
+_textminor_ {Minor}
+_texttrivial_ {Trivial}
+
+_textwhatdoing_ {What were you trying to do?}
+_textwhatexpected_ {What did you expect to happen?}
+_textwhathappened_ {What actually happened?}
+
+_cannotfindcgierror_ {<h2>Sorry!</h2>Can\\'t find the server programs for the "_linktextusab_" button.}
+
+_textusabbanner_ {the Greenstone koru-style banner}
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ {An error has occurred}
+
+_textgtihome_ {
+These pages help you improve Greenstone's multilingual language support. Using them, you can
+<ul>
+  <li>translate parts of Greenstone into a new language
+  <li>update an existing language interface when the English language interface changes (eg. for new Greenstone facilities)
+  <li>correct errors in existing translations
+</ul>
+
+You will be presented with a series of web pages, each containing
+a phrase to translate.
+You proceed by translating the language interface phrase by phrase.
+Many phrases contain HTML formatting commands: you should not
+attempt to translate these but preserve them intact in the translated
+version. Words flanked by underscores (like _this_) should not be
+translated either (they're Greenstone "macro" names).
+<p>
+If you are updating an existing language interface you will not be presented
+with phrases for which a translation already exists. Sometimes a translation
+exists but the English text has since been changed. In this case the current
+translation will be provided and you should check and update this if necessary.
+<p>
+To correct a translation that has already been updated, use the "Correct existing translations" facility available for each part of Greenstone.
+<p>
+Each page ends with a "_textgtisubmit_" button. When you press it, changes are
+made immediately to a separate Greenstone installation at nzdl.org. A button
+is provided on each page to access this site.
+}
+
+_textgtiselecttlc_ {Please select your language}
+
+#for status page
+_textgtiviewstatus_ {Click to view the current translation status for all languages}
+_textgtiviewstatusbutton_ {VIEW STATUS}
+_textgtistatustable_ {List of current translation status for all languages}
+_textgtilanguage_ {Language}
+_textgtitotalnumberoftranslations_ {Total number of translations}
+
+_textgtiselecttfk_ {Please select a file to work on}
+
+_textgticoredm_ {Greenstone Interface (Core)}
+_textgtiauxdm_ {Greenstone Interface (Auxiliary)}
+_textgtiglidict_ {GLI Dictionary}
+_textgtiglihelp_ {GLI Help}
+_textgtiperlmodules_ {Perl Modules}
+_textgtitutorials_ {Tutorial Exercises}
+_textgtigreenorg_ {Greenstone.org}
+_textgtigs3interface_ {Greenstone 3 Interface}
+
+#for greenstone manuals
+_textgtidevmanual_ {Greenstone Developer's Manual}
+_textgtiinstallmanual_ {Greenstone Installer's Manual}
+_textgtipapermanual_ {Greenstone Manual for Paper to Collection}
+_textgtiusermanual_ {Greenstone User's Manual}
+
+_textgtienter_ {ENTER}
+
+_textgticorrectexistingtranslations_ {Correct existing translations}
+_textgtidownloadtargetfile_ {Download file}
+_textgtiviewtargetfileinaction_ {View this file in action}
+_textgtitranslatefileoffline_ {Translate this file offline}
+
+_textgtinumchunksmatchingquery_ {Number of text fragments matching the query}
+
+_textgtinumchunkstranslated_ {translations done}
+_textgtinumchunksrequiringupdating_ {Of these, _1_ require updating}
+_textgtinumchunksrequiringtranslation_ {translations remaining}
+
+#for status page
+_textgtinumchunkstranslated2_ {number of translations done}
+_textgtinumchunksrequiringupdating2_ {number of translations requiring updating}
+_textgtinumchunksrequiringtranslation2_ {number of translations remaining}
+
+_textgtienterquery_ {Enter a word or phrase from the text fragment you want to correct}
+_textgtifind_ {FIND}
+
+_textgtitranslatingchunk_ {Translating text fragment <i>_1_</i>}
+_textgtiupdatingchunk_ {Updating text fragment <i>_1_</i>}
+_textgtisubmit_ {SUBMIT}
+
+_textgtilastupdated_ {Last updated}
+
+_textgtitranslationfilecomplete_ {Thank you for updating this file -- it is now complete!<p>You can download a copy of this file using the link above, and it will also be included in future releases of Greenstone.}
+
+_textgtiofflinetranslation_ {
+You can translate this part of Greenstone offline using a Microsoft Excel spreadsheet file:
+
+<ol>
+<li>Download either <a href="_gwcgi_?a=gti&amp;p=excel&amp;tct=work&amp;e=_compressedoptions_">this file</a> for all the remaining work, or <a href="_gwcgi_?a=gti&amp;p=excel&amp;tct=all&amp;e=_compressedoptions_">this file</a> for all the strings in this module.
+<li>Open the downloaded file in Microsoft Excel (Office 2003/XP or more recent versions is required) and save as Microsoft Excel workbook (.xls) format.
+<li>Enter the translations in the boxes provided.
+<li>When you have finished translating all the strings, e-mail the .xls file to <a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>.
+</ol>
+}
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ {the greenstone librarian interface}
+_textglihelp_ {
+<p>The Greenstone Librarian Interface (GLI) gives you access to Greenstone's functionality from an easy-to-use, 'point and click' interface. This allows you to collect sets of documents, import or assign metadata, and build them into a Greenstone collection.</p>
+
+<p>Note that the GLI is run in conjunction with Greenstone, and assumes that it is installed in a subdirectory of your Greenstone installation. If you have downloaded one of the Greenstone distributions, or installed from a Greenstone CD-ROM, this will be the case.</p>
+
+<h4>Running the GLI under Windows</h4>
+ 
+Launch the librarian interface under Windows by selecting <i>Greenstone Digital Library</i> from the <i>Programs</i> section of the <i>Start</i> menu and choosing <i>Librarian Interface</i>. 
+
+<h4>Running the GLI under Unix</h4>
+
+To run the GLI under Unix, change to the <i>gli</i> directory in your Greenstone installation, then run the <i>gli.sh</i> script. 
+
+<h4>Running the GLI under Mac OS X</h4>
+
+In the finder, browse to <i>Applications</i> then <i>Greenstone</i> (if you installed Greenstone into the default location), and then launch the <i>GLI</i> application.
+}
Index: /gsdl/stable/macros/exported_home.dm
===================================================================
--- /gsdl/stable/macros/exported_home.dm	(revision 20131)
+++ /gsdl/stable/macros/exported_home.dm	(revision 20131)
@@ -0,0 +1,131 @@
+# this file must be UTF-8 encoded
+
+package home
+
+# This file is used as the homepage for collections exported to CD-ROM - the CDs dont contain the functionality to run the collector etc, so we remove that stuff from the home page.
+
+# set the title of the home page to be "greenstone digital library"
+# in the currently chosen language
+
+_pagetitle_ {_textdescrgreenstone_}
+
+#######################################################################
+# global navigation links
+#######################################################################
+
+# overridden here as we don't want 'home' links on this page
+
+# home:helplink and home:preflink set in nav_css/ns4 macro files
+_globallinks_ {_helplink_ _preflink_}
+
+#######################################################################
+# icons
+#######################################################################
+
+_iconmusiclibrary_ {<img src="_httpicontmusic_" border="1" alt="meldex music library" title="meldex music library">}
+
+_imagecollection_ {<img src="_httpimg_/gsdlhead.gif" alt="_textdescrgreenstone_">}
+
+#######################################################################
+# http macros 
+#
+# These contain the url without any quotes
+#######################################################################
+
+_httppagegsdl_ {_httppagex_(gsdl)}
+_httppagehomehelp_ {_httppagex_(homehelp)}
+_httppagehomepref_ {_httppagex_(homepref)}
+
+#######################################################################
+# page content                     
+#######################################################################
+
+_content_ {
+<div id="content">
+<div class="divbar">
+<p class="navbar">
+_textdescrselcol_
+</p>
+</div>
+
+<div class="section">
+_homeextra_
+</div>
+
+<div class="divbar">&nbsp;</div>
+}
+
+package homehelp
+
+_imagecollection_ {<a href="_httppagehome_"><img src="_httpimg_/gsdlhead.gif" border="0"></a>}
+
+_collectionlist_ {}
+
+_globallinks_ {_homelink_}
+
+_content_ {
+<div id="content">
+
+<div class="divbar">&nbsp;</div>
+
+<div class="section">
+<p>
+<table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+  <td valign="top" align="center">_imagegreenstone_</td>
+  <td valign="top">_gsdl:textgreenstone1_
+  <br><br>
+  </td>
+ </tr>
+</table>
+</div>
+
+<div class="divbar">&nbsp;</div>
+
+<div class="section">
+_If_(_collectionlist_,_collectionlist_,_textnocollections_)
+</div>
+
+<div class="divbar">&nbsp;</div>
+
+</div>
+}
+
+
+package homepref
+_pagetitle_ {_preferences:textpreferences_ - _textdescrgreenstone_}
+
+_imagecollection_ {<a href="_httppagehome_"><img src="_httpimg_/gsdlhead.gif" border="0"></a>}
+
+_globallinks_ {_homelink_}
+
+_pagescriptextra_ {_preferences:pagescriptextra_}
+
+_content_ {
+<div id="content">
+
+<div class="divbar">&nbsp;</div>
+
+<div class="section">
+<form name="PrefForm" method="get" action="_gwcgi_">
+<h3>_preferences:textpresentationprefs_</h3>
+
+<table border="0">
+<tr valign="top">
+<td>_preferences:textlanguage_</td>
+<td>_languageoption_</td>
+</tr>
+<tr valign="top">
+<td>_preferences:textencoding_</td>
+<td>_encodingoption_</td>
+</tr>
+<tr valign="top">
+_preferences:formatoption_
+</tr>
+</table>
+</div>
+
+<div class="divbar">&nbsp;</div>
+
+</div> <!-- \_homepref:content\_ -->
+}
Index: /gsdl/stable/macros/extlink.dm
===================================================================
--- /gsdl/stable/macros/extlink.dm	(revision 20131)
+++ /gsdl/stable/macros/extlink.dm	(revision 20131)
@@ -0,0 +1,19 @@
+# this file must be UTF-8 encoded
+
+package extlink
+
+_header_ {_htmlhead_}
+
+_foundcontent_ {
+
+<h3>_textextlink_</h3>
+
+<p> _textextlinkcontent_
+}
+
+_notfoundcontent_ {
+
+<h3>_textlinknotfound_</h3>
+
+<p> _textlinknotfoundcontent_
+}
Index: /gsdl/stable/macros/extra.dm
===================================================================
--- /gsdl/stable/macros/extra.dm	(revision 20131)
+++ /gsdl/stable/macros/extra.dm	(revision 20131)
@@ -0,0 +1,7 @@
+
+
+# The intention of this file is to provide a placeholder for collection
+# specific new macros (it is therefore intentionally empty).  For a given
+# collection, if the collection designer setups up an 'extra.dm' file in
+# the collection's macro directory then any macros defined within it will
+# be available for that collection.
Index: /gsdl/stable/macros/farsi.dm
===================================================================
--- /gsdl/stable/macros/farsi.dm	(revision 20131)
+++ /gsdl/stable/macros/farsi.dm	(revision 20131)
@@ -0,0 +1,1566 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Farsi Language text and icon macros 
+# Many thanks to Mohammed Karimi Yazdi (translated February 2004)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=fa] {Ú¯Ø§ÙÙØ§Ù
+Ù ÙØ§}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=fa] {Ù
+ÙØšØ¹ :}
+_textdate_ [l=fa] {ØªØ§Ø±ÙØ® ÙØŽØ± :}
+_textnumpages_ [l=fa] {ØªØ¹Ø¯Ø§Ø¯ ØµÙØ­Ø§Øª :}
+
+_textsignin_ [l=fa] {ÙØ±ÙØ¯}
+
+_textdefaultcontent_ [l=fa] {ØµÙØ­Ù Ù
+ÙØ±Ø¯ Ø¯Ø±Ø®ÙØ§Ø³Øª ØŽÙ
+Ø§ ÙØ§ÙØª ÙØŽØ¯. ÙØ·ÙØ§ Ø§Ø² Ø¯ÙÙ
+Ù ØšØ§Ø²Ú¯ØŽØª ÙØ§ÙØŽÚ¯Ø± Ø®ÙØ¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ÙÙØ¯ ÙØ§ ØšØ± Ø±ÙÙ Ø¯ÙÙ
+Ù Ø®Ø§ÙÙ ØšØ±Ø§Ù ØšØ§Ø²Ú¯ØŽØª ØšÙ ÙØªØ§ØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ÙÙÙÙ ÙÙÙØ¯ .}
+
+_textdefaulttitle_ [l=fa] {Ø®Ø·Ø§Ù GSDL}
+
+_textbadcollection_ [l=fa] {Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù (ØšÙØ§Ù
+ "_cvariable_") Ø¯Ø± Ø³ÙØ³ØªÙ
+ ÙØªØ§ØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ÙØµØš ÙØŽØ¯Ù Ø§Ø³Øª.}
+
+_textselectpage_ [l=fa] {ØµÙØ¬Ù Ø§ÙØªØ®Ø§Øš}
+
+_collectionextra_ [l=fa] {Ø¯Ø± Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù ØªØ¹Ø¯Ø§Ø¯ _about:numdocs_  Ø³ÙØ¯ ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ .
+Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù _about:builddate_ Ø±ÙØ² ÙØšÙ Ø³Ø§Ø®ØªÙ ØŽØ¯Ù Ø§Ø³Øª .}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=fa] {<p> Ø§ÛÙ Ù
+Ø¬Ù
+ÙØ¹Ù Ø­Ø§ÙÛ _numdocs_ _If_("_numdocs_" eq "1",document,documents), a total of _numbytes_  Ø§Ø² Ù
+ØªÙ ÙÙ
+Ø§ÛÙ ØŽØ¯Ù Ù Ø§ØšØ±Ø¯Ø§Ø¯Ù Ø§Ø³Øª. 
+<p>ØšØ±Ø§Û Ù
+ØŽØ§ÙØ¯Ù Ú¯Ø²Ø§Ø±ØŽ Ø®ÙØ§ØµÙ Ø³Ø§Ø®Øª Ø§ÛÙ Ù
+Ø¬Ù
+ÙØ¹Ù <a href="_httppagex_(bsummary)">Ø§ÛÙØ¬Ø§ Ø±Ø§ Ú©ÙÛÚ© Ú©ÙÛØ¯</a>}  
+
+_textdescrcollection_ [l=fa] {}
+_textdescrabout_ [l=fa] {Ø¯Ø±ØšØ§Ø±Ù}
+_textdescrhome_ [l=fa] {Ø®Ø§ÙÙ}
+_textdescrhelp_ [l=fa] {Ø±Ø§ÙÙÙ
+Ø§ÙÙ}
+_textdescrpref_ [l=fa] {ØªÙØžÙÙ
+Ø§Øª}
+_textdescrgreenstone_ [l=fa] {ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± ÙØªØ§ØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}
+_textdescrusab_ [l=fa] {Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² ÙØ¯Ø§Ù
+ Ù
+ÙØ±Ø¯ Ø±Ø§ Ø¯ØŽÙØ§Ø± ÙØ§ÙØªÙØ¯ Ø}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=fa] {Ø¬Ø³ØªØ¬Ù}  
+_labelSearch_ [l=fa] {Ø¬Ø³ØªØ¬Ù}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=fa] {Ø¹ÙÙØ§Ù}  
+_labelTitle_ [l=fa] {Ø¹ÙØ§ÙÛÙ}  
+_textCreator_ [l=fa] {Ø§ÛØ¬Ø§Ø¯ Ú©ÙÙØ¯Ù}  
+_labelCreator_ [l=fa] {Ù
+ÙÙÙØ§Ù}  
+_textSubject_ [l=fa] {Ù
+ÙØ¶ÙØ¹}  
+_labelSubject_ [l=fa] {Ù
+ÙØ¶ÙØ¹Ø§Øª}
+_textDescription_ [l=fa] {ØŽØ±Ø­}  
+_labelDescription_ [l=fa] {ØªÙØµÛÙØ§Øª}  
+_textPublisher_ [l=fa] {ÙØ§ØŽØ±}  
+_labelPublisher_ [l=fa] {ÙØ§ØŽØ±Ø§Ù}  
+_textContributor_ [l=fa] {ØŽØ±ÛÚ©}  
+_labelContributor_ [l=fa] {Ù
+ØŽØ§Ø±Ú©Øª Ú©ÙÙØ¯Ú¯Ø§Ù}  
+_textDate_ [l=fa] {ØªØ§Ø±ÛØ®}  
+_labelDate_ [l=fa] {ØªØ§Ø±ÙØ® ÙØ§}
+_textType_ [l=fa] {ÙÙØ¹}  
+_labelType_ [l=fa] {Ø§ÙÙØ§Ø¹}  
+_textFormat_ [l=fa] {ÙØ±Ù
+Øª}  
+_labelFormat_ [l=fa] {ÙØ±Ù
+ØªÙØ§}  
+_textIdentifier_ [l=fa] {ØŽØ§Ø®Øµ}  
+_labelIdentifier_ [l=fa] {ØŽØ§Ø®ØµÙØ§}  
+_textSource_ [l=fa] {ÙØ§Ù
+ ÙŸØ±ÙÙØ¯Ù}  
+_labelSource_ [l=fa] {ÙØ§Ù
+ ÙŸØ±ÙÙØ¯Ù ÙØ§}
+_textLanguage_ [l=fa] {Ø²ØšØ§Ù}  
+_labelLanguage_ [l=fa] {Ø²ØšØ§Ù}
+_textRelation_ [l=fa] {Ø§Ø±ØªØšØ§Ø·}  
+_labelRelation_ [l=fa] {Ø±ÙØ§ØšØ·}  
+_textCoverage_ [l=fa] {Ø¯Ø§Ù
+ÙÙ Ø²ÛØ± ÙŸÙØŽØŽ}  
+_labelCoverage_ [l=fa] {Ø¯Ø§Ù
+ÙÙ Ø²ÛØ± ÙŸÙØŽØŽ}  
+_textRights_ [l=fa] {Ø­ÙÙÙ}  
+_labelRights_ [l=fa] {Ø­ÙÙÙ}  
+
+# DLS metadata set
+_textOrganization_ [l=fa] {Ø³Ø§Ø²Ù
+Ø§Ù}  
+_labelOrganization_ [l=fa] {Ø³Ø§Ø²Ù
+Ø§ÙÙØ§}  
+_textKeyword_ [l=fa] {Ú©ÙÛØ¯ÙØ§ÚÙ}  
+_labelKeyword_ [l=fa] {ÙÙÙ
+Ø§Øª ÙÙÙØ¯Ù}
+_textHowto_ [l=fa] {ÚÚ¯ÙÙÚ¯Û}  
+_labelHowto_ [l=fa] {ÚÚ¯ÙÙÚ¯Û}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=fa] {Ø¹ØšØ§Ø±Øª}  
+_labelPhrase_ [l=fa] {Ø¹ØšØ§Ø±Ø§Øª}
+
+
+_textBrowse_ [l=fa] {Ù
+Ø±ÙØ± Ú©Ø±Ø¯Ù}  
+_labelBrowse_ [l=fa] {Ù
+Ø±ÙØ± Ú©Ø±Ø¯Ù}  
+_textTo_ [l=fa] {ØšÙ}  
+_labelTo_ [l=fa] {ØªØ§}
+_textFrom_ [l=fa] {Ø§Ø²}  
+_labelFrom_ [l=fa] {Ø§Ø²}
+_textAcronym_ [l=fa] {Ø³Ø±ÙØ§Ù
+}  
+_labelAcronym_ [l=fa] {Ù
+ØªØ¶Ø§Ø¯ÙØ§}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=fa] {Ù
+Ø±ÙØ± Ú©Ø±Ø¯Ù ØšÙØ³ÛÙÙ_1_}  
+
+_textdescrSearch_ [l=fa] {Ø¬Ø³ØªØ¬Ù ØšØ±Ø§Ù Ø¹ØšØ§Ø±Ø§Øª Ø®Ø§Øµ}
+_textdescrType_ [l=fa] {Ù
+Ø±ÙØ± Ú©Ø±Ø¯Ù}  
+_textdescrIdentifier_ [l=fa] {Ù
+Ø±ÙØ±Ú©Ø±Ø¯Ù ØšØ§ ØŽØ§Ø®Øµ Ù
+ÙØ§ØšØ¹}  
+_textdescrSource_ [l=fa] {Ù
+Ø±ÙØ± ØšØ± Ø§Ø³Ø§Ø³ ÙØ§Ù
+ Ø§ØµÙÙ ÙŸØ±ÙÙØ¯Ù}
+_textdescrTo_ [l=fa] {Ù
+Ø±ÙØ± ØšØ± Ø­Ø³Øš ÙØšÙØ¯ ØªØ§}
+_textdescrFrom_ [l=fa] {Ù
+Ø±ÙØ± ØšØ± Ø­Ø³Øš ÙÙÙØ¯ Ø§Ø²}
+_textdescrCollage_ [l=fa] {Ù
+Ø±ÙØ± Ú©Ø±Ø¯Ù ØšØ§ ØªØ±Ú©ÛØš Ø±ÙÚ¯ ØªØµØ§ÙÛØ±}  
+_textdescrAcronym_ [l=fa] {Ù
+Ø±ÙØ± Ù
+ØªØ¶Ø§Ø¯ÙØ§}
+_textdescrPhrase_ [l=fa] {Ù
+Ø±ÙØ± Ø¹ØšØ§Ø±Ø§Øª}
+_textdescrHowto_ [l=fa] {Ù
+Ø±ÙØ± Ø¯Ø³ØªÙ ÙØ§Ù ÚÚ¯ÙÙÚ¯Ù Ø§ÙØ¬Ø§Ù
+ ÙØ§Ø±ÙØ§}
+_textdescrBrowse_ [l=fa] {Ù
+Ø±ÙØ±}
+_texticontext_ [l=fa] {Ø±ÙÙØª Ø³ÙØ¯}
+_texticonclosedbook_ [l=fa] {ØšØ§Ø²ÙØ±Ø¯Ù Ø³ÙØ¯ Ù Ø±ÙÙØª Ù
+Ø­ØªÙÙØ§Øª Ø¢Ù}
+_texticonnext_ [l=fa] {ØšØ®ØŽ ØšØ¹Ø¯Ù}
+_texticonprev_ [l=fa] {ØšØ®ØŽ ÙØšÙÙ}
+
+_texticonworld_ [l=fa] {Ø±ÙÛØª Ø³ÙØ¯ ÙØš}  
+
+_texticonmidi_ [l=fa] {Ø±ÙÙØª Ø³ÙØ¯ MIDI}
+_texticonmsword_ [l=fa] {Ø±ÙÙØª Ø³ÙØ¯ Ù
+Ø§ÙÙØ±ÙØ³Ø§ÙØª ÙØ±Ø¯}
+_texticonmp3_ [l=fa] {Ø±ÙÙØª Ø³ÙØ¯ MP3}
+_texticonpdf_ [l=fa] {Ø±ÙÙØª Ø³ÙØ¯ PDF}
+_texticonps_ [l=fa] {Ø±ÙÙØª Ø³ÙØ¯ PostScript}  
+_texticonppt_ [l=fa] {Ø±ÙÙØª Ø³ÙØ¯ PowerPoint}
+_texticonrtf_ [l=fa] {Ø±ÙÙØª Ø³ÙØ¯ RTF}
+_texticonxls_ [l=fa] {Ø±ÙÙØª Ø³ÙØ¯ Microsoft Excel}  
+
+_page_ [l=fa] {ØµÙØ­Ù}
+_pages_ [l=fa] {ØµÙØ­Ø§Øª}
+_of_ [l=fa] {Ø§Ø²}
+_vol_ [l=fa] {Ø¬ÙØ¯}
+_num_ [l=fa] {ØŽÙ
+Ø§Ø±Ù}
+
+_textmonth00_ [l=fa] {}
+_textmonth01_ [l=fa] {ÚØ§ÙÙÙÙ}
+_textmonth02_ [l=fa] {ÙÙØ±ÙÙ}
+_textmonth03_ [l=fa] {Ù
+Ø§Ø±Ø³}
+_textmonth04_ [l=fa] {Ø¢ÙØ±ÙÙ}
+_textmonth05_ [l=fa] {Ù
+Ù}
+_textmonth06_ [l=fa] {Ø¬ÙØŠÙ}
+_textmonth07_ [l=fa] {Ø¬ÙÙØ§Ù}
+_textmonth08_ [l=fa] {Ø¢Ú¯ÙØ³Øª}
+_textmonth09_ [l=fa] {Ø³ÙŸØªØ§Ù
+ØšØ±}
+_textmonth10_ [l=fa] {Ø§ÙØªØšØ±}
+_textmonth11_ [l=fa] {ÙÙØ§Ù
+ØšØ±}
+_textmonth12_ [l=fa] {Ø¯Ø³Ø§Ù
+ØšØ±}
+
+_textdocument_ [l=fa] {Ø³ÙØ¯}
+_textsection_ [l=fa] {ØšØ®ØŽ}
+_textparagraph_ [l=fa] {ÙŸØ§Ø±Ø§Ú¯Ø±Ø§Ù}
+
+_magazines_ [l=fa] {Ù
+Ø¬ÙØ§Øª}
+
+_nzdlpagefooter_ [l=fa] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">ÙŸØ±ÙÚÙ ÙØªØ§ØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù ÙÙÙØ²ÙÙÙØ¯</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Ù
+Ø±ÙØ² Ø¹ÙÙÙ
+ Ø±Ø§ÙØ§ÙÙ </a>, 
+<a href="http://www.waikato.ac.nz">Ø¯Ø§ÙØŽÚ¯Ø§Ù ÙØ§ÙÙØ§ØªÙ</a>, 
+ÙÙÙØ²ÙÙÙØ¯}
+
+_linktextHOME_ [l=fa] {Ø®Ø§ÙÙ}
+_linktextHELP_ [l=fa] {Ø±Ø§ÙÙÙ
+Ø§ÙÙ}
+_linktextPREFERENCES_ [l=fa] {ØªÙØžÙÙ
+Ø§Øª}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=fa] {Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÛØ¬ÛØªØ§Ù Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ}  
+
+_textnocollections_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û Ù
+Ø¹ØªØšØ±Û  Ø¯Ø± Ø¯Ø³ØªØ±Ø³ ÙÛØ³ØªÙØ¯}  
+
+_textadmin_ [l=fa] {ØµÙØ­Ù Ù
+Ø¯ÛØ±ÛØª}  
+_textabgs_ [l=fa] {Ø¯Ø±ØšØ§Ø±Ù Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ}  
+_textgsdocs_ [l=fa] {Ù
+Ø³ØªÙØ¯Ø§Øª Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ}  
+
+_textdescradmin_ [l=fa] {Ø§ÛÙ ÙØ³Ù
+Øª Ø§Ø·ÙØ§Ø¹Ø§Øª ÙÙÛ Ø¯Ø±ØšØ§Ø±Ù ÙØµØš Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ù
+Û Ø¯ÙØ¯ Ù ØšÙ ØŽÙ
+Ø§ Ø§Ø¬Ø§Ø²Ù Ù
+Û Ø¯ÙØ¯ ØªØ§ Ú©Ø§Ø±ØšØ±Ø§Ù Ø¬Ø¯ÛØ¯ Ø§ÛØ¬Ø§Ø¯ ÙÙ
+Ø§ÛÛØ¯ Ù Ø§Ø·ÙØ§Ø¹Ø§Øª Ù
+Ø®ØªØµØ±Û Ø¯Ø±ØšØ§Ø±Ù Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û Ø³ÛØ³ØªÙ
+ ÙØŽØ§Ù Ù
+Û Ø¯ÙØ¯}  
+
+_textdescrgogreenstone_ [l=fa] {ØªÙØ¶ÛØ­Ø§ØªÛ ØšØ±Ø§Û ØŽÙ
+Ø§ Ø¯Ø±ØšØ§Ø±Ù ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ù ÙŸØ±ÙÚÙ Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÛØ¬ÛØªØ§Ù ÙÛÙØ²ÛÙÙØ¯ Ø¬Ø§ÛÛ Ú©Ù Ø§ÛÙ ÙŸØ±ÙÚÙ ÙØŽØ§Øª Ú¯Ø±ÙØªÙ Ø§Ø³Øª}  
+
+_textdescrgodocs_ [l=fa] {Ø±Ø§ÙÙÙ
+Ø§ÙØ§Û Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=fa] {Ø±Ø§ØšØ· Ú©ØªØ§ØšØ¯Ø§Ø±}  
+_textdescrgli_ [l=fa] {ØšÙ ØŽÙ
+Ø§ Ø¯Ø± Ø§ÛØ¬Ø§Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û Ø¬Ø¯ÛØ¯Ø ØªØºÛØ± Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û Ù
+ÙØ¬ÙØ¯Ø ÛØ§ Ø­Ø°Ù Ø¢ÙÙØ§ Ú©Ù
+Ú© Ù
+Û Ú©ÙØ¯}  
+
+package collector
+
+_textcollector_ [l=fa] {Ø¬Ù
+Ø¹ Ø¢ÙØ±Û Ú©ÙÙØ¯Ù}  
+_textdescrcollector_ [l=fa] {Ø§ÙÙ ØšØ®ØŽ ÙØšÙ Ø§Ø² Ø±Ø§ØšØ· ÙØªØ§ØšØ¯Ø§Ø± Ù
+Ù Ø¢ÙØ¯Ø Ø§Ù
+Ø§ ØšÙ Ø¹ÙØª ÛÚ©Ø³Ø±Û Ø§ÙØ¯Ø§Ù Ú©Ø§Ø±ØšØ±Ø¯ÛØ Ø±Ø§ØšØ· Ú©ØªØ§ØšØ¯Ø§Ø± ØšØ§ÛØ¯ ØšØ¬Ø§Û Ø¢Ù Ø§Ø³ØªÙØ§Ø¯Ù ØŽÙØ¯.}  
+
+package depositor
+
+_textdepositor_ [l=fa] {ÙØ§Ø³ÙŸØ§Ø±ÙØ¯Ù}  
+_textdescrdepositor_ [l=fa] {ÙÙ
+Ù Ù
+Ù ÙÙØ¯ ØªØ§ ØŽÙ
+Ø§ Ø§Ø³ÙØ§Ø¯ Ø±Ø§ ØšÙ Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Ù Ø¬Ø§Ø±Ù Ø§Ø¶Ø§ÙÙ ÙÙÙØ¯}  
+
+package gti
+
+_textgti_ [l=fa] {Ø±Ø§ØšØ· Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ ÙÛÚÙ Ù
+ØªØ±Ø¬Ù
+}  
+_textdescrtranslator_ [l=fa] {ØšÙ ØŽÙ
+Ø§ Ú©Ù
+Ú© Ù
+Û Ú©ÙØ¯ ØªØ§ ÙØ³Ø® ÚÙØ¯Ø²ØšØ§ÙÙ Ø±Ø§ØšØ· Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ø±Ø§ ØšÙ Ø±ÙØ² ÙÚ¯Ù Ø¯Ø§Ø±ÛØ¯}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=fa] {Ø¯Ø±ØšØ§Ø±Ù Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù}
+
+_textsubcols1_ [l=fa] {<p>ÙÙ Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù ØŽØ§Ù
+Ù _1_ Ø²ÙØ±Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+Ù ØšØ§ØŽØ¯. 
+Ø¢ÙÙØ§ÙÙ ÙÙ ÙØ§ØšÙ Ø¯Ø³ØªØ±Ø³Ù ÙØ³ØªÙØ¯ Ø¹ØšØ§Ø±ØªÙØ¯ Ø§Ø²::
+<blockquote>}
+
+_textsubcols2_ [l=fa] {</blockquote>
+ØŽÙ
+Ø§ Ø§Ø² Ø·Ø±ÙÙ ØµÙØ­Ù ØªÙØžÙÙ
+Ø§Øª Ù
+Ù ØªÙØ§ÙÙØ¯ Ø²ÙØ±Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Ù Ù
+ÙØ±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù Ø®ÙØ¯ Ø±Ø§ ØšØšÙÙÙØ¯ ÙØ§ ØªØºÙÙØ± Ø¯ÙÙØ¯.}
+
+_titleabout_ [l=fa] {Ø¯Ø±ØšØ§Ø±Ù}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=fa] {ØšØ³ØªÙ Ø§ÙÙ ØšØ®ØŽ ÙØªØ§ØšØ®Ø§ÙÙ}
+_texticonclosedbookshelf_ [l=fa] {ØšØ§Ø²ÙØ±Ø¯Ù Ø§ÙÙ ØšØ®ØŽ Ø§Ø² ÙØªØ§ØšØ®Ø§ÙÙ Ù Ø±ÙÙØª Ù
+Ø­ØªÙÙØ§Øª}
+_texticonopenbook_ [l=fa] {ØšØ³ØªÙ ÙØªØ§Øš}
+_texticonclosedfolder_ [l=fa] {ØšØ§Ø²ÙØ±Ø¯Ù ÙŸÙØŽÙ Ù Ø±ÙÙØª Ù
+Ø­ØªÙÙØ§Øª}
+_texticonclosedfolder2_ [l=fa] {ÙØ§Ø²ÙØ±Ø¯Ù Ø²ÙØ±ØšØ®ØŽ}
+_texticonopenfolder_ [l=fa] {ØšØ³ØªÙ ÙŸÙØŽÙ}
+_texticonopenfolder2_ [l=fa] {ØšØ³ØªÙ Ø²ÙØ± ØšØ®ØŽ}
+_texticonsmalltext_ [l=fa] {Ø±ÙÙØª Ø§ÙÙ ØšØ®ØŽ Ø§Ø² Ù
+ØªÙ}
+_texticonsmalltext2_ [l=fa] {Ø±ÙÙØª Ù
+ØªÙ :}
+_texticonpointer_ [l=fa] {ØšØ®ØŽ ÙØ¹ÙÙ}
+_texticondetach_ [l=fa] {ØšØ§Ø²ÙØ±Ø¯Ù ØµÙØ­Ù Ø¯Ø± ÙŸÙØ¬Ø±Ù Ø¬Ø¯ÙØ¯}
+_texticonhighlight_ [l=fa] {ØšØ±Ø¬Ø³ØªÙ ÙØ±Ø¯Ù Ø¹ØšØ§Ø±Ø§Øª Ø¬Ø³ØªØ¬ÙØŽØ¯Ù}
+_texticonnohighlight_ [l=fa] {Ø¹ØšØ§Ø±Ø§Øª Ø¬Ø³ØªØ¬Ù ØšØ±Ø¬Ø³ØªÙ ÙØŽÙØ¯}
+_texticoncontracttoc_ [l=fa] {Ø¬Ù
+Ø¹ ÙØ±Ø¯Ù ÙÙØ±Ø³Øª Ù
+Ø­ØªÙÙØ§Øª}
+_texticonexpandtoc_ [l=fa] {ØšØ§Ø²ÙØ±Ø¯Ù ÙÙØ±Ø³Øª Ù
+Ø­ØªÙÙØ§Øª}
+_texticonexpandtext_ [l=fa] {ÙÙ
+Ø§ÙØŽ ÙÙ
+Ù Ù
+ØªÙ}
+_texticoncontracttext_ [l=fa] {ØšØ±Ø§Ù ØšØ­ØŽ Ø§ÙØªØ®Ø§Ù ÙÙØ· Ù
+ØªÙ ÙÙ
+Ø§ÙØŽ Ø¯Ø§Ø¯Ù ØŽÙØ¯}
+_texticonwarning_ [l=fa] {<b>Ø§Ø®Ø·Ø§Ø±: </b>}
+_texticoncont_ [l=fa] {Ø§Ø¯Ø§Ù
+Ù Ø}
+
+_textltwarning_ [l=fa] {<div class="buttons">_imagecont_</div>
+_iconwarning_Ø§ÙÙ Ù
+ØªÙ Ø­Ø§ÙÙ Ø§Ø·ÙØ§Ø¹Ø§Øª ØšØ³ÙØ§Ø±Ù Ø²ÙØ§Ø¯Ù ØšØ±Ø§Ù Ù
+Ø±ÙØ±Ú¯Ø± ØŽÙ
+Ø§ Ø§Ø³Øª}
+
+_textgoto_ [l=fa] {ØšØ±Ù ØšÙ ØµÙØ­Ù}
+_textintro_ [l=fa] {<i>(Ù
+Ø¹Ø±ÙÙ)</i>}
+
+_textCONTINUE_ [l=fa] {Ø§Ø¯Ø§Ù
+Ù}
+
+_textEXPANDTEXT_ [l=fa] {ØšØ§Ø²ÙØ±Ø¯Ù Ù
+ØªÙ}
+
+_textCONTRACTCONTENTS_ [l=fa] {Ø¬Ù
+Ø¹ Ú©Ø±Ø¯Ù Ù
+Ø­ØªÙÛØ§Øª}  
+
+_textDETACH_ [l=fa] {Ø¬Ø¯Ø§Ø³Ø§Ø²Ù}
+
+_textEXPANDCONTENTS_ [l=fa] {ØšØ§Ø²Ú©Ø±Ø¯Ù Ù
+Ø­ØªÙÛØ§Øª}  
+
+_textCONTRACT_ [l=fa] {Ø¬Ù
+Ø¹ Ú©Ø±Ø¯Ù Ù
+ØªÙ}  
+
+_textHIGHLIGHT_ [l=fa] {ØšØ±Ø¬Ø³ØªÙ ÙÙ
+Ø§ÛÛ}  
+
+_textNOHIGHLIGHT_ [l=fa] {ØšØ¯ÙÙ ØšØ±Ø¬Ø³ØªÙ ÙÙ
+Ø§ÛÛ}  
+
+_textPRINT_ [l=fa] {ÚØ§ÙŸ}  
+
+_textnextsearchresult_ [l=fa] {ÙØªØ§ÙØ¬ Ø¬Ø³ØªØ¬ÙÙ ØšØ¹Ø¯Ù}  
+_textprevsearchresult_ [l=fa] {ÙØªØ§ÛØ¬ Ø¬Ø³ØªØ¬ÙÛ ÙØšÙÛ}  
+
+# macros for printing page
+_textreturnoriginal_ [l=fa] {ØšØ§Ø²Ú¯ØŽØª ØšÙ ØµÙØ­Ù Ù
+ØšØ¯Ø§}  
+_textprintpage_ [l=fa] {ÚØ§ÙŸ Ø§ÛÙ ØµÙØ­Ù}  
+_textshowcontents_ [l=fa] {ÙÙ
+Ø§ÛØŽ Ø¬Ø¯ÙÙ Ù
+Ø­ØªÙÛØ§Øª}  
+_texthidecontents_ [l=fa] {Ø¹Ø¯Ù
+ ÙÙ
+Ø§ÛØŽ Ø¬Ø¯ÙÙ Ù
+Ø­ØªÙÛØ§Øª}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=fa] {_If_(_thislast_,results _thisfirst_ - _thislast_ for query: _cgiargq_,ØªØ·Ø§ØšÙÛ ÛØ§ÙØª ÙØŽØ¯: _cgiargq_)}
+_textnoquerytitle_ [l=fa] {ØµÙØ¬Ù Ø¬Ø³ØªØ¬Ù}
+
+_textsome_ [l=fa] {ØšØ¹Ø¶Ù}
+_textall_ [l=fa] {ÙÙ
+Ù}
+_textboolean_ [l=fa] {Ù
+ÙØ·ÙÛ}
+_textranked_ [l=fa] {Ø¯Ø±Ø¬Ù ØšÙØ¯Û ØŽØ¯Ù}
+_textnatural_ [l=fa] {Ø·ØšÛØ¹Û}
+_textsortbyrank_ [l=fa] {ØªØ±ØªÛØš Ù
+Ø±ØªØšØ·}  
+_texticonsearchhistorybar_ [l=fa] {Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù}
+
+_textifeellucky_ [l=fa] {Ù
+Ù Ø§Ø­Ø³Ø§Ø³ Ø®ÙØŽØšØ®ØªÛ Ù
+Û Ú©ÙÙ
+!}  
+
+#alt text for query buttons
+_textusequery_ [l=fa] {Ø§Ø² Ø§ÙÙ ÙŸØ±Ø³ Ù Ø¬Ù Ø§Ø³ØªÙØ§Ø¯Ù ÙÙÙØ¯}
+_textfreqmsg1_ [l=fa] {ØªØ¹Ø¯Ø§Ø¯ Ú©ÙÙ
+Ù :}
+_textpostprocess_ [l=fa] {_If_(_quotedquery_,<br><i>ÙŸØ±Ø¯Ø§Ø²ØŽ ØŽØ¯Ù ØšØ±Ø§Û ÛØ§ÙØªÙ _quotedquery_</i>
+)}
+_textinvalidquery_ [l=fa] {Ø¯Ø³ØªÙØ± ÙŸØ±Ø³ Ù Ø¬ÙÛ Ø§ØŽØªØšØ§Ù}
+_textstopwordsmsg_ [l=fa] {ÙÙØ§Øª Ø²ÛØ± Ø®ÛÙÛ Ú©ÙÛ Ø§ÙØ¯ Ù ÙØ§Ø¯ÛØ¯Ù Ú¯Ø±ÙØªÙ ØŽØ¯ÙØ¯:}  
+_textlucenetoomanyclauses_ [l=fa] {Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬ÙÛ ØŽÙ
+Ø§ Ø­Ø§ÙÛ Ø§ØµØ·ÙØ§Ø­Ø§Øª Ø¬Ø³ØªØ¬ÙÛ Ø²ÛØ§Ø¯Û ØšÙØ¯ØÙØ·ÙØ§ ØšØ§ Ø§ÙØªØ®Ø§Øš Ø¹ØšØ§Ø±Ø§Øª Ø®Ø§Øµ ØªØ± Ø¯ÙØšØ§Ø±Ù Ø³Ø¹Û Ú©ÙÛØ¯.}  
+
+_textmorethan_ [l=fa] {ØšÛØŽØªØ± Ø§Ø²}
+_textapprox_ [l=fa] {Ø¯Ø±ØšØ§Ø±Ù}
+_textnodocs_ [l=fa] {Ø³ÙØ¯Û Ù
+Ø·Ø§ØšÙ Ø¬Ø³ØªØ¬Ù ÛØ§ÙØª ÙØŽØ¯ .}
+_text1doc_ [l=fa] {1 Ø³ÙØ¯ ØšØ§ ÙŸØ±Ø³ Ù Ø¬Ù ØªØ·ØšÛÙ Ø¯Ø§Ø±Ø¯ .}
+_textlotsdocs_ [l=fa] {Ø§Ø³ÙØ§Ø¯Û Ú©Ù ØšØ§ ÙŸØ±Ø³ Ù Ø¬Ù ØªØ·ØšÛÙ Ú©Ø±Ø¯Ù Ø§ÙØ¯ .}
+_textmatches_ [l=fa] {ØªØ·ØšÛÙ Ù
+Û Ú©ÙØ¯}
+_textbeginsearch_ [l=fa] {Ø¢ØºØ§Ø² Ø¬Ø³ØªØ¬Ù}
+_textrunquery_ [l=fa] {Ø§Ø¬Ø±Ø§Û Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù}  
+_textclearform_ [l=fa] {ÙŸØ§Ú© Ú©Ø±Ø¯Ù ÙØ±Ù
+}
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=fa] {Ú©ÙÙ
+Ø§Øª}  
+_textinfield_ [l=fa] {... Ø¯Ø± ÙÛÙØ¯}
+
+
+_textadvquery_ [l=fa] {ÛØ§ Ù
+Ø³ØªÙÛÙ
+Ø§ ÛÚ© Ø¹ØšØ§Ø±Øª Ø¬Ø³Ø¬Ù Ø±Ø§ ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ :}  
+_textallfields_ [l=fa] {ÙÙ
+Ù ÙÛÙØ¯ÙØ§}
+_texttextonly_ [l=fa] {ÙÙØ· Ù
+ØªÙÙ}
+_textand_ [l=fa] {Ù}
+_textor_ [l=fa] {ÛØ§}
+_textandnot_ [l=fa] {Ù ÙÙ}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=fa] {Ø¬Ø³ØªØ¬Ù ØšØ±Ø§Û Ù
+ÙØ§Ø±Ø¯Û _indexselection_ _If_(_jselection_,Ø§Ø²_jselection_ )_If_(_gselection_, Ø¯Ø± _gselection_ Ø³Ø·Ø­ )_If_(_nselection_,Ø¯Ø± _nselection_ language ) Ú©Ù ØŽØ§Ù
+Ù _querytypeselection_ ØšØ§ØŽØ¯}  
+
+_textadvancedsearch_ [l=fa] {Ø¬Ø³ØªØ¬Ù _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,Ø¯Ø± Ø²ØšØ§Ù _nselection_ )ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² ÙŸØ±Ø³ Ù Ø¬ÙÛ _querytypeselection_}
+
+_textadvancedmgppsearch_ [l=fa] {Ø¬Ø³ØªØ¬ÙÛ _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language ) Ù ÙÙ
+Ø§ÛØŽ ÙØªØ§ÛØ¬ ØšØ± Ø­Ø³Øš _formquerytypeadvancedselection_}  
+
+_textadvancedlucenesearch_ [l=fa] {Ø¬Ø³ØªØ¬Ù(Ú©Ø±Ø¯Ù) _indexselection__If_(_jselection_, of _jselection_)_If_(_gselection_, at _gselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ sorting results by _sfselection_\,) ØšØ±Ø§Û"}  
+
+_textformsimplesearch_ [l=fa] {Ø¬Ø³ØªØ¬ÙÛ _If_(_jselection_, _jselection_)_If_(_gformselection_, Ø¯Ø± _gformselection_ Ø³Ø·Ø­ )_If_(_nselection_, Ø¯Ø± _nselection_ language)_If_(_sfselection_,\, Ù
+Ø±ØªØš Ú©Ø±Ø¯Ù ÙØªØ§ÛØ¬ ØšØ§}  
+
+_textformadvancedsearchmgpp_ [l=fa] {Ø¬Ø³ØªØ¬ÙÛ _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )Ù ÙÙ
+Ø§ÛØŽ ÙØªØ§ÛØ¬ ØšØ± Ø­Ø³Øš  _formquerytypeadvancedselection_}  
+
+_textformadvancedsearchlucene_ [l=fa] {Ø¬Ø³ØªØ¬ÙÛ _If_(_jselection_, _jselection_)_If_(_gformselection_,  Ø¯Ø± _gformselection_ level)_If_(_nselection_, Ø¯Ø± Ø²ØšØ§Ù _nselection_ language)_If_(_sfselection_,\,  ØšÙ ØªØ±ØªÛØš _sfselection_\,)  ØšØ±Ø§Û}  
+
+_textnojsformwarning_ [l=fa] {ØªØ°Ú¯Ø± : Ø¬Ø§ÙØ§ Ø§Ø³Ú©Ø±ÛÙŸØª Ø¯Ø± Ù
+Ø±ÙØ±Ú¯Ø± ØŽÙ
+Ø§ ØºÛØ± ÙØ¹Ø§Ù ØŽØ¯Ù Ø§Ø³Øª  <br>ØšØ±Ø§Û Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ø¬Ø³ØªØ¬Ù Ø¢Ù Ø±Ø§ ÙØ¹Ø§Ù ÙÙ
+Ø§ÛÛØ¯.}
+_textdatesearch_ [l=fa] {Ø¯Ø± Ø§ÛÙ Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+Û ØªÙØ§Ù Ø¯Ø± ØšØ§Ø²Ù Ø²Ù
+Ø§ÙÛ ÛØ§ Ø§Ø³ÙØ§Ø¯Û Ú©Ù ØªØ§Ø±ÛØ® Ø®Ø§ØµÛ Ø¯Ø± Ø¢ÙÙØ§ ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ Ø¬Ø³ØªØ¬Ù Ú©Ø±Ø¯ . Ø§ÛÙ ÙÛÚÚ¯Û Ø§Ø®ØªÛØ§Ø±Û Ø¬Ø³ØªØ¬Ù Ù
+Û ØšØ§ØŽØ¯ .}
+_textstartdate_ [l=fa] {ØªØ§Ø±ÙØ® ØŽØ±ÙØ¹(ÙØ§ ÙÙØ·)}
+_textenddate_ [l=fa] {ØªØ§Ø±ÛØ® ÙŸØ§ÛØ§Ù :}
+_textbc_ [l=fa] {B.C.E.}
+_textad_ [l=fa] {C.E.}
+_textexplaineras_ [l=fa] {C.E. Ù B.C.E.  ØšÙ ØªØ±ØªÛØš Ø¬Ø§ÛÚ¯Ø²ÛÙ A.D. Ù B.C. Ù
+Û ØšØ§ØŽÙØ¯ . Ø§ÛÙ Ø¹ØšØ§Ø±Ø§Øª ÙØ§Ø±Øº Ø§Ø² ØªÙØ§ÙØªÙØ§Û ÙØ±ÙÙÚ¯Û Ø Ù
+Ø®ÙÙ Common Era Ù Before Common era Ù
+Û ØšØ§ØŽÙØ¯ .}  
+
+_textstemon_ [l=fa] {(ÚØŽÙ
+ ÙŸÙØŽÙ Ø§Ø² Ø§ÙØªÙØ§Ù ÙÙÙ
+Ø§Øª)}
+
+_textsearchhistory_ [l=fa] {Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù}
+
+#text macros for search history
+_textnohistory_ [l=fa] {Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù Ù
+ÙØ¬ÙØ¯ ÙÛØ³Øª}
+_texthresult_ [l=fa] {ÙØªÛØ¬Ù}
+_texthresults_ [l=fa] {ÙØªØ§ÛØ¬}
+_texthallwords_ [l=fa] {ØªÙ
+Ø§Ù
+ Ú©ÙÙ
+Ø§Øª}
+_texthsomewords_ [l=fa] {ØšØ¹Ø¶Û Ú©ÙÙ
+Ø§Øª}
+_texthboolean_ [l=fa] {Ù
+ÙØ·ÙÛ}
+_texthranked_ [l=fa] {Ø¯Ø±Ø¬Ù ØšÙØ¯Û ØŽØ¯Ù}
+_texthcaseon_ [l=fa] {Ù
+ÙØ±Ø¯ ØšØ§ÛØ¯ ØªØ·ØšÛÙ Ú©ÙØ¯}
+
+_texthstemon_ [l=fa] {Ù
+ØŽØªÙ ØŽØ¯Ù}
+_texthstemoff_ [l=fa] {ØºÛØ± Ù
+ØŽØªÙ}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=fa] {ØªÙØžÛÙ
+Ø§Øª Ø°Ø®ÛØ±Ù ØŽØ¯Ù Ø§ÙØ¯ . Ø§Ø² Ø¯Ú©Ù
+Ù ØšØ§Ø²Ú¯ØŽØª Ù
+Ø±ÙØ±Ú¯Ø± Ø®ÙØ¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙÚ©ÙÛØ¯ Ø²ÛØ±Ø§ ØªÙØžÛÙ
+Ø§Øª Ø±Ø§ ØšØ± Ù
+Û Ú¯Ø±Ø¯Ø§ÙØ¯ Ø¯Ø± Ø¹ÙØ¶ Ø±ÙÛ ÛÚ©Û Ø§Ø² Ø¯Ú©Ù
+Ù ÙØ§Û ÙÙØ§Ø± Ø¯Ø³ØªØ±Ø³Û ØšØ§ÙØ§ Ú©ÙÛÚ© Ú©ÙÛØ¯ .}
+_textsetprefs_ [l=fa] {Ø°Ø®ÛØ±Ù ØªÙØžÛÙ
+Ø§Øª}
+_textsearchprefs_ [l=fa] {ØªÙØžÛÙ
+Ø§Øª Ø¬Ø³ØªØ¬Ù}
+_textcollectionprefs_ [l=fa] {ØªÙØžÛÙ
+Ø§Øª Ù
+Ø¬Ù
+ÙØ¹Ù}
+_textpresentationprefs_ [l=fa] {Ø§Ø±Ø§ØŠÙ ØªÙØžÛÙ
+Ø§Øª}
+_textpreferences_ [l=fa] {ØªÙØžÛÙ
+Ø§Øª}
+_textcasediffs_ [l=fa] {ØšØ²Ø±Ú¯ Ù Ú©ÙÚÚ©Û Ø­Ø±ÙÙ :}
+_textignorecase_ [l=fa] {ÙØ§Ø¯ÛØ¯Ù Ú¯Ø±ÙØªÙ ØšØ²Ø±Ú¯Û Ù Ú©ÙÚÚ©Û Ø­Ø±ÙÙ}  
+_textmatchcase_ [l=fa] {Ú©ÙÚÚ©Û / ØšØ²Ø±Ú¯Û Ø­Ø±ÙÙ ØšØ§ÛØ¯ ÙØ­Ø§Øž ØŽÙØ¯}  
+_textwordends_ [l=fa] {Ø§ÙØªÙØ§Û Ú©ÙÙ
+Ø§Øª :}
+_textstem_ [l=fa] {ÙØ§Ø¯ÛØ¯Ù Ú¯Ø±ÙØªÙ Ø§ÙØªÙØ§Û Ú©ÙÙ
+Ø§Øª}  
+_textnostem_ [l=fa] {ØªÙ
+Ø§Ù
+ Ú©ÙÙ
+Ù ØšØ§ÛØ¯ Ù
+Ø·Ø§ØšÙØª Ú©ÙØ¯}  
+_textaccentdiffs_ [l=fa] {ØªÙØ§ÙØªÙØ§Û ÙÙØ¬Ù:}  
+_textignoreaccents_ [l=fa] {ÙØ§Ø¯ÛØ¯Ù Ú¯Ø±ÙØªÙ Ø§Ú©Ø³Ø§ÙÙØ§}  
+_textmatchaccents_ [l=fa] {Ø§Ú©Ø³Ø§ÙÙØ§ ØšØ§ÛØ¯ Ù
+Ø·Ø§ØšÙØª Ø¯Ø§ØŽØªÙ ØšØ§ØŽÙØ¯}  
+
+_textprefop_ [l=fa] {Ø­Ø¯Ø§Ú©Ø«Ø± _maxdocoption_ Ù
+ÙØ±Ø¯ ÙØŽØ§Ù Ø¯Ø§Ø¯Ù ØŽÙØ¯ ØšØ§ _hitsperpageoption_ Ù
+ÙØ±Ø¯ Ø¯Ø± ÙØ± ØµÙØ­Ù .}
+_textextlink_ [l=fa] {Ø¯Ø³ØªØ±Ø³Û ØšÙ ØµÙØ­Ø§Øª ÙØš Ø®Ø§Ø±Ø¬Û :}
+_textintlink_ [l=fa] {Ø§Ø³ÙØ§Ø¯ Ø§ØµÙÛ ØšØ§Ø²ÛØ§ØšÛ ØŽØ¯Ù Ø§Ø³Øª Ø§Ø² :}
+_textlanguage_ [l=fa] {Ø²ØšØ§Ù Ø±Ø§ØšØ· :}
+_textencoding_ [l=fa] {Ú©Ø¯ Ø²ØšØ§Ù ØµÙØ­Ù :}
+_textformat_ [l=fa] {ÙØ§ÙØš Ø±Ø§ØšØ·:}
+_textall_ [l=fa] {ÙÙ
+Ù}
+_textquerymode_ [l=fa] {Ø­Ø§ÙØª Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù:}  
+_textsimplemode_ [l=fa] {Ø­Ø§ÙØª Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬ÙÛ Ø³Ø§Ø¯Ù}  
+_textadvancedmode_ [l=fa] {Ø­Ø§ÙØª Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù ÙŸÛØŽØ±ÙØªÙ ( Ù
+Û ØªÙØ§ÙÛØ¯ Ø§Ø² Ø¹Ù
+ÙÚ¯Ø±ÙØ§Û Ù
+ÙØ·ÙÛ ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² ! Ø & Ø | Ù ÙŸØ±Ø§ÙØªØ² Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ÛÛØ¯ )}  
+_textlinkinterm_ [l=fa] {Ø§Ø² Ø·Ø±ÛÙ ØµÙØ­Ù ÙØ§Ø³Ø·}
+_textlinkdirect_ [l=fa] {Ù
+Ø³ØªÙÛÙ
+ ØšØ±Ù ØšÙ :}
+_textdigitlib_ [l=fa] {Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÛØ¬ÛØªØ§Ù}
+_textweb_ [l=fa] {ÙØš}
+_textgraphical_ [l=fa] {Ú¯Ø±Ø§ÙÛÚ©Û}
+_texttextual_ [l=fa] {Ù
+ØªÙÛ}
+_textcollectionoption_ [l=fa] {<p>
+Ø²ÛØ±Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ÛÛ Ú©Ù ØŽØ§Ù
+Ù Ù
+Û ØŽÙØ¯ :
+<br>}
+
+_textsearchtype_ [l=fa] {Ø³ØšÚ© Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù:}  
+_textformsearchtype_ [l=fa] {ØªÙÛÙ ØŽØ¯Ù ØšØ§ ÙÛÙØ¯ÙØ§Û _formnumfieldoption_}  
+_textplainsearchtype_ [l=fa] {Ù
+Ø¹Ù
+ÙÙÛ ØšØ§  _boxsizeoption_ ØšØ§Ú©Ø³ Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù}  
+_textregularbox_ [l=fa] {Ø®Ø· Ù
+ÙÙØ±Ø¯}  
+_textlargebox_ [l=fa] {ØšØ²Ø±Ú¯Øª}  
+
+_textrelateddocdisplay_ [l=fa] {ÙÙ
+Ø§ÛØŽ Ø§Ø³ÙØ§Ø¯ Ù
+Ø±ØªØšØ·}
+_textsearchhistory_ [l=fa] {Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù :}
+_textnohistory_ [l=fa] {Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬ÙÛÛ ÙØ¬ÙØ¯ ÙØ¯Ø§Ø±Ø¯}
+_texthistorydisplay_ [l=fa] {ÙÙ
+Ø§ÛØŽ _historynumrecords_ ÙŸÛØŽÛÙÙ ÙØ§Û Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù}  
+_textnohistorydisplay_ [l=fa] {ÙØŽØ§Ù ÙØ¯Ø§Ø¯Ù Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=fa] {Ù
+Ø±ØªØš Ø³Ø§Ø²Ù Ø§Ø³ÙØ§Ø¯ ØšØ± Ø­Ø³Øš}
+_textalsoshowing_ [l=fa] {ØšØ¹ÙØ§ÙÙ ÙÙ
+Ø§ÙØŽ}
+_textwith_ [l=fa] {ØšØ§ ØšÙØŽØªØ±ÙÙ}
+_textdocsperpage_ [l=fa] {Ø³ÙØ¯ Ø¯Ø± ØµÙØ­Ù}
+
+_textfilterby_ [l=fa] {Ø§Ø³ÙØ§Ø¯Ù ÙÙ Ø­Ø§ÙÙ}
+_textall_ [l=fa] {ÙÙ
+Ù}
+_textany_ [l=fa] {ÙØ±}
+_textwords_ [l=fa] {Ø§Ø² ÙÙÙ
+Ù}
+_textleaveblank_ [l=fa] {ØšØ±Ø§Ù ØšÙ Ø¯Ø³Øª Ø¢ÙØ±Ø¯Ù ÙÙ
+Ù Ø§Ø³ÙØ§Ø¯ Ø§ÙÙ ÙØ³Ù
+Øª Ø±Ø§ Ø®Ø§ÙÙ ØšÚ¯Ø°Ø§Ø±ÙØ¯}
+
+_browsebuttontext_ [l=fa] {"Ù
+Ø±ØªØš Ø³Ø§Ø²Ù Ø§Ø³ÙØ§Ø¯"}
+
+_nodata_ [l=fa] {<i>ØšØ¯ÙÙ Ø§Ø·ÙØ§Ø¹Ø§Øª</i>}
+_docs_ [l=fa] {Ø§Ø³ÙØ§Ø¯}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=fa] {ÙÙ
+Ù}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=fa] {Ù
+Ø±ÙØ± Ú©Ø±Ø¯Ù Ø§Ø³ÙØ§Ø¯ ØšØ§ _1_ Ú©ÙÛÚ© _2_ Ø¯Ú©Ù
+Ù}  
+
+_textSearchhelp_ [l=fa] {Ø¬ÙØª Ø¬Ø³ØªØ¬ÙÛ ÙØºØ§Øª ØšØ®ØµÙØµ Ù
+ÙØ¬ÙØ¯ Ø¯Ø± Ù
+ØªÙ Ø§Ø² Ø¯Ú©Ù
+Ù _labelSearch_ Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ÛÛØ¯.}  
+_textTohelp_ [l=fa] {Ø§Ø³ÙØ§Ø¯ Ø±Ø§ ØšØ§ Ø§ØšØ²Ø§Ø± To field ØšÙØ³ÛÙÙ Ø¯Ú©Ù
+Ù _labelTo_ Ù
+Ø±ÙØ± Ú©ÙÛØ¯.}  
+_textFromhelp_ [l=fa] {Ø§ÙØªØŽØ§Ø±Ø§Øª Ø±Ø§ ØšÙØ³ÛÙÙ ÙÛÙØ¯ From ØšØ§ Ú©ÙÛÚ© Ø¯Ú©Ù
+Ù  _labelFrom_ Ù
+Ø±ÙØ± Ú©ÙÛØ¯}
+_textBrowsehelp_ [l=fa] {Ù
+Ø±ÙØ± Ú©Ø±Ø¯Ù Ø§Ø³ÙØ§Ø¯}  
+_textAcronymhelp_ [l=fa] {Ø§Ø³ÙØ§Ø¯ Ø±Ø§ ØšØ§ Ø­Ø¶ÙØ± Ø³Ø±ÙØ§Ù
+ ØšÙØ³ÛÙÙ  Ø¯Ú©Ù
+Ù _labelAcronym_ Ù
+Ø±ÙØ± Ú©ÙÛØ¯}  
+_textPhrasehelp_ [l=fa] {Ø§ØµØ·ÙØ§Ø­Ø§Øª Ù
+ÙØ¬ÙØ¯ Ø¯Ø± Ø§Ø³ÙØ§Ø¯ Ø±Ø§ ØšØ§ Ú©ÙÛØ¯ ØšØ± Ø±ÙÛ Ø¯Ú©Ù
+Ù _labelPhrase_ Ù
+Ø±ÙØ± ÙÙ
+Ø§ÛÛØ¯.}  
+
+_texthelptopicstitle_ [l=fa] {Ù
+ÙØ¶ÙØ¹Ø§Øª}  
+
+_textreadingdocs_ [l=fa] {ÚÚ¯ÙÙÙ Ø§Ø³ÙØ§Ø¯ Ø±Ø§ ØšØ®ÙØ§ÙÛÙ
+}
+
+_texthelpreadingdocs_ [l=fa] {<p>
+Ø§Ø² Ø¢ÙØ¬Ø§ÛÛ Ú©Ù Ø¯Ø± ÙØ³Ù
+Øª ØšØ§ÙØ§ Ø³Ù
+Øª ÚÙŸ ÙØ± ØµÙØ­Ù Ø¹ÙÙØ§Ù Ø³ÙØ¯ ÛØ§ Ø¹Ú©Ø³ Ø¬ÙØ¯ Ø¢Ù Ø¯Ø±Ø¬ ØŽØ¯Ù Ø§Ø³Øª
+Ù
+Û ØªÙØ§ÙÛØ¯ ØšØšÛÙÛØ¯ ØšÙ Ú©ØªØ§Øš ÛØ§ Ø³ÙØ¯ Ø®Ø§ØµÛ Ø¯Ø³Øª ÛØ§ÙØªÙ Ø§ÛØ¯ . Ø¯Ø± ØšØ¹Ø¶Û Ø§Ø² Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§
+ØšÙ ÙÙ
+Ø±Ø§Ù ÙÙØ±Ø³Øª Ù
+Ø­ØªÙÛØ§Øª Ø¯ÛØ¯Ù Ù
+ØŽ ÙØ¯ Ù Ø¯Ø± ØšØ¹Ø¶Û ØŽØ§Ù
+Ù ØŽÙ
+Ø§Ø±Ù ØµÙØ­Ù ÙØ¹ÙÛ Ù ÙØ³Ù
+ØªÛ ØšØ±Ø§Û
+ØªØ¹ÛÛÙ ØµÙØ­Ù Ù Ø±ÙØªÙ ØšÙ ØµÙØ­Ù Ù
+ØŽØ®ØµÛ ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ . Ø¯Ø± ÙÙØ±Ø³Øª Ù
+Ø­ØªÙÛØ§Øª ØšØ®ØŽ Ø¬Ø§Ø±Û ÙŸØ±Ø±ÙÚ¯ 
+Ù
+Û ØšØ§ØŽØ¯ Ù Ø¬Ø¯ÙÙ ÙÛØ² ÙØ§ØšÙ ØšØ§Ø² ØŽØ¯Ù Ø§Ø³Øª . ØšØ§ Ú©ÙÛÚ© ØšØ± Ø±ÙÛ ÙŸÙØŽÙ ÙØ§ Ù
+Û ØªÙØ§Ù ØšØ§Ø² ÛØ§ ØšØ³ØªÙ ØŽØ§Ù Ú©Ø±Ø¯ .
+</p>
+
+<p>Ø¯Ø± ÙØ³Ù
+Øª ÙŸØ§ÛÛÙ Ù
+ØªÙ ØšØ®ØŽ ÙØ±Ø§Ø± Ø¯Ø§Ø±Ø¯. Ú©Ù ÙÙØªÛ Ø®ÙØ§ÙØ¯Ù ØŽØ¯Ù ÙÙØŽ ÙØ§ÛÛ ØšØ±Ø§Û 
+Ø±ÙØªÙ ØšÙ ØšØ®ØŽ ØšØ¹Ø¯ ÛØ§ ÙØšÙ ÙØ¬Ù Ø¯Ø§Ø±Ø¯ </p>
+
+<p>Ø¯Ø± Ø²ÛØ± Ø¹ÙÙØ§Ù ÛØ§ Ø¹Ú©Ø³ ØªØ¹Ø¯Ø§Ø¯ Ø¯Ú©Ù
+Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯. ØšØ±Ø±ÙÛ 
+<i>ØšØ§Ø²Ú©Ø±Ø¯Ù Ù
+ØªÙ</i> Ú©ÙÛÚ© Ú©ÙÛØ¯ ØªØ§ ØªÙ
+Ø§Ù
+ Ù
+ØªÙ ØšØ®ØŽ ÛØ§ Ú©ØªØ§Øš Ø¬Ø§Ø±Û ÙÙ
+Ø§ÛØŽ Ø¯Ø§Ø¯Ù ØŽÙØ¯. 
+Ø§ÙØšØªÙ Ø§Ú¯Ø± Ø³ÙØ¯ ØšØ²Ø±Ú¯ ØšØ§ØŽØ¯ ÙÙØª Ú¯ÛØ± Ù Ø­Ø§ÙØžÙ Ú¯ÛØ± Ø®ÙØ§ÙØ¯ ØšÙØ¯ . 
+ØšØ§ Ú©ÙÛÚ© ØšØ±Ø±ÙÛ  <i>ØšØ§Ø²Ú©Ø±Ø¯Ù Ù
+Ø­ØªÙÛØ§Øª</i> ÙÙØ±Ø³Øª Ù
+Ø­ØªÙÛØ§Øª ÙØŽØ§Ù Ø¯Ø§Ø¯Ù Ø®ÙÙØ¯ ØŽØ¯ 
+Ù Ù
+Û ØªÙØ§ÙÛØ¯ Ø¹ÙØ§ÙÛÙ ØªÙ
+Ø§Ù
+ ÙØµÙÙ Ù Ø²ÛØ± ÙØµÙ ÙØ§ Ø±Ø§ ØšØšÛÙÛØ¯ .ØšØ§ Ú©ÙÛÚ© ØšØ±Ø±ÙÛ 
+ <i>ÙØ·Ø¹</i> ÙŸÙØ¬Ø±Ù Ø¬Ø¯ÛØ¯Û ØšØ±Ø§Û Ø§ÛÙ Ø³ÙØ¯ ØšØ§Ø² Ø®ÙØ§ÙØ¯ ØŽØ¯ . (ØšØ®ØµÙØµ ÙÙØªÛ Ù
+ÙÛØ¯ Ø§Ø³Øª Ú©Ù ØšØ®ÙØ§ÙÛØ¯ Ø¯Ù Ø³ÙØ¯ Ø±Ø§ Ù
+ÙØ§ÛØ³Ù Ú©ÙÛØ¯ Ù ÛØ§ ØšØ§ ÙÙ
+ ØšØ®ÙØ§ÙÛØ¯ 
+ .) ØšØ§ÙØ§Ø®Ø±Ù ÙÙØªÛ Ø¬Ø³ØªØ¬Ù Ù
+Û Ú©ÙÛØ¯ Ú©ÙÙ
+Ø§Øª Ù
+ÙØ±Ø¯ Ø¬Ø³ØªØ¬Ù ØšØ±Ø¬Ø³ØªÙ Ù
+Û ØŽÙØ¯ Ù ØšØ§ Ú©ÛÚ© Ø±ÙØ³ <i>ØšØ¯ÙÙ ØšØ±Ø¬Ø³ØªÙ Ø³Ø§Ø²Û</i> 
+ Ø§ÛÙ ØšØ±Ø¬Ø³ØªÙ Ø³Ø§Ø²Û ØŽØ¯Ù ÙØ§ Ø­Ø°Ù Ù
+Û ØŽÙÙØ¯.</p>}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=fa] {ØšØ§Ø² Ú©Ø±Ø¯Ù Ø§ÛÙ ÙÙØ³Ù Ú©ØªØ§Øš}
+_texthelpopenbook_ [l=fa] {ØšØ§Ø²Ú©Ø±Ø¯Ù/ØšØ³ØªÙ Ú©ØªØ§Øš}
+_texthelpviewtextsection_ [l=fa] {Ø±ÙÛØª Ø§ÛÙ ØšØ®ØŽ Ø§Ø² Ù
+ØªÙ}
+_texthelpexpandtext_ [l=fa] {ÙÙ
+Ø§ÛØŽ ÛØ§ Ø¹Ø¯ Ù
+ÙÙ
+Ø§ÛØŽ ØªÙ
+Ø§Ù
+ Ù
+ØªÙ}
+_texthelpexpandcontents_ [l=fa] {ØšØ§Ø²Ú©Ø±Ø¯Ù ÙÙØ±Ø³Øª Ù
+Ø­ØªÙÛØ§Øª ÛØ§ ØšØ³ØªÙ Ø¢Ù}
+_texthelpdetachpage_ [l=fa] {ØšØ§Ø² Ú©Ø±Ø¯Ù Ø§ÛÙ ØµÙØ­Ù Ø¯Ø± ÛÚ© ØµÙØ­Ù Ø¬Ø¯ÛØ¯}
+_texthelphighlight_ [l=fa] {ØšØ±Ø¬Ø³ØªÙ Ø³Ø§Ø²Û Ú©ÙÙ
+Ø§Øª Ù
+ÙØ±Ø¯ Ø¬Ø³ØªØ¬Ù ÛØ§ Ø¹Ø¯Ù
+ ØšØ±Ø¬Ø³ØªÙ Ø³Ø§Ø²Û}
+_texthelpsectionarrows_ [l=fa] {Ø±ÙØªÙ ØšÙ ØšØ®ØŽ ÙØšÙÛ/ØšØ¹Ø¯Û}  
+
+
+_texthelpsearchingtitle_ [l=fa] {ÚÚ¯ÙÙÙ Ú©ÙÙ
+Ø§Øª Ø®Ø§ØµÛ Ø±Ø§ Ø¬Ø³ØªØ¬Ù Ú©ÙÛÙ
+}
+
+_texthelpsearching_ [l=fa] {<p>
+  Ø§Ø² ØµÙØ­Ù Ø¬Ø³ØªØ¬Ù ØšÙ Ø±Ø§Ø­ØªÛ Ù
+Û ØªÙØ§ÙÛØ¯ ØšÙ Ø±ÙØŽ Ø²ÛØ± Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ÛÛØ¯:<p>
+  
+  <ol><li>Ù
+ÙØ§Ø±Ø¯ Ù
+ÙØ±Ø¯ Ø¬Ø³ØªØ¬ÙÛ Ø®ÙØ¯ Ø±Ø§ Ø³Ø§Ø¯Ù Ú©ÙÛØ¯
+      <li>Ø¢ÙÚÙ Ù
+Û Ø®ÙØ§ÙÛØ¯ ØšÛØ§ØšÛØ¯ ØšØ§ ÙÙ
+Ù ÛØ§ ØšØ±Ø®Û Ú©ÙÙ
+Ø§Øª Ø¢Ù Ù
+Ø±ÙØ± Ú©ÙÛØ¯
+      <li>Ú©ÙÙ
+Ø§ØªÛ Ú©Ù Ù
+Û Ø®ÙØ§ÙÛØ¯ ØšÛØ§ØšÛØ¯ ÙØ§Ø±Ø¯ ÙÙ
+Ø§ÛÛØ¯
+      <li>Ø±ÙÛ Ø¯Ú©Ù
+Ù <i>Ø¢ØºØ§Ø² Ø¬Ø³ØªØ¬Ù</i> Ú©ÙÛÚ© Ú©ÙÛØ¯
+  </ol>
+
+<p>
+ÙÙØªÛ Ø¬Ø³ØªØ¬Ù Ø§ÙØ¬Ø§Ù
+ Ù
+Û ØŽÙØ¯ Ø¹ÙØ§ÙÛÙ Ø§Ø³ÙØ§Ø¯ Ù
+Ø·Ø§ØšÙ ÙØŽØ§Ù Ø¯Ø§Ø¯Ù Ø®ÙØ§ÙØ¯ ØŽØ¯ .Ø¯Ø± Ø§ÙØªÙØ§ Ø¯Ú©Ù
+Ù Ø§Û
+ØšØ±Ø§Û Ø¯ÛØ¯Ù ØšÛØ³Øª ÙØªÛØ¬Ù ØšØ¹Ø¯Û ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ Ù Ø¯Ø± Ø¢ÙØ¬Ø§ Ø¯Ú©Ù
+Ù ÙØ§ÛÛ ØšØ±Ø§Û Ø¯ÛØ¯Ù ÙØªØ§ÛØ¬ ØšØ¯Û Ù ÙØšÙÛ Ù ÙØžØ§ÛØ± 
+Ø¢Ù Ø®ÙØ§ÙØ¯ ØšÙØ¯ . ØšØ§ Ú©ÙÛÚ© ØšØ± Ø±ÙÛ Ø¹ÙÙØ§Ù ÙØ± Ø³ÙØ¯ ÛØ§ Ø¯Ú©Ù
+Ù Ú©ÙÚÚ© Ú©Ø§Ø± Ø¢Ù Ù
+Û ØªÙØ§ÙÛØ¯ Ø³ÙØ¯ Ø±Ø§ ØšØšÛÙÛØ¯
+<p>Ø­Ø¯Ø§Ú©Ø«Ø± ØµØ¯ ÙØªÛØ¬Ù Ø¯ÛØ¯Ù Ù
+Û ØŽÙØ¯.  ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ ØšØ§ Ú©ÙÛÚ© ØšØ±Ø±ÙÛ Ø¯Ú©Ù
+Ù
+  <i>ØªÙØžÛÙ
+Ø§Øª</i> Ø¯Ø± ØšØ§ÙØ§Û ØµÙØ­Ù Ø§ÛÙ Ø¹Ø¯Ø¯ Ø±Ø§ ØªØºÛÛØ± Ø¯ÙÛØ¯.<p>}
+
+_texthelpquerytermstitle_ [l=fa] {Ø¬Ø³ØªØ¬ÙÛ Ø¹ØšØ§Ø±Ø§Øª}
+_texthelpqueryterms_ [l=fa] {<p>
+ÙØ± ÚÛØ²Û Ú©Ù Ø¯Ø± Ø¬Ø¹ÛÙ Ø³ÙØ§Ù ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ ØšÙ Ø¹ÙÙØ§Ù ÙÙØ±Ø³ØªÛ Ø§Ø² Ú©ÙÙ
+Ø§Øª Ø¹ØšØ§Ø±Ø§Øª Ø¬Ø³ØªØ¬Ù ÙØ§Ù
+ Ø¯Ø§Ø±Ø¯ .
+ÙØ± Ø¹ØšØ§Ø±Øª ÚÛØ²Û Ø¬Ø² Ø­Ø±ÙÙ Ù Ø§Ø¹Ø¯Ø§Ø¯ ÙÛØ³Øª . ÙØšØ§Ø±Ø§Øª ØšØ§ ÙØ¶Ø§Û Ø®Ø§ÙÛ Ø§Ø² ÙÙ
+ Ø¬Ø¯Û Ù
+ÛØŽÙÙØ¯ . Ø§Ú¯Ø±
+ÙØ± Ú©Ø§Ø±Ø§Ú©ØªØ± Ø¯ÛÚ¯Ø±Û Ù
+Ø§ÙÙØ¯ ÙÙØ·Ù Ú¯Ø°Ø§Ø±Û Ø§Ø³ØªÙØ§Ø¯Ù ØŽÙØ¯ ØšÙ Ø¹ÙÙØ§Ù ÙØ¶Ø§Û Ø®Ø§ÙÛ ØšØ±Ø§Û Ø¬Ø¯Ø§Ú©Ø±Ø¯Ù 
+Ø¹ØšØ§Ø±Ø§Øª Ø¯Ø± ÙØžØ± Ú¯Ø±ÙØªÙ Ø®ÙØ§ÙØ¯ ØŽØ¯ Ù Ø­Ø±Ù Ø®ÙØ§ÙÙØ¯ ØŽØ¯ . Ø¹ØšØ§Ø±Ø§ØªÛ Ú©Ù ØŽØ§Ù
+Ù Ø¹ÙØ§ØŠÙ
+ ÙÙØ·Ù Ú¯Ø°Ø§Ø±Û ØšØ§ØŽÙØ¯ 
+ÙØ§ØšÙ Ø¬Ø³ØªØ¬Ù ÙÛØ³ØªÙØ¯ .
+<p>ØšØ±Ø§Û Ù
+Ø«Ø§Ù Ø³ÙØ§Ù<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p> Ù
+Ø§ÙÙØ¯ Ø§ÛÙ Ù
+ÙØ±Ø¯ Ø®ÙØ§ÙØ¯ ØšÙØ¯: <p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+
+_texthelpquerytype_ [l=fa] {
+<p>Ø¯Ù ÙÙØ¹ ÙŸØ±Ø³ Ù Ø¬Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ :
+
+<ul>
+  <li>Ø¬Ø³ØªØ¬Ù ØšØ±Ø§Û  <b>ÙÙ
+Ù</b> Ú©ÙÙ
+Ø§Øª.  ØŽØ§Ù
+Ù Ø§Ø³ÙØ§Ø¯Û Ù
+Û ØŽÙØ¯ (ÛØ§ ÙØµÙÙ ÛØ§ Ø¹ÙØ§ÙÛÙ)
+   Ú©Ù ØªÙ
+Ø§Ù
+ Ú©ÙÙ
+Ø§Øª Ù
+ÙØ±Ø¯ ÙØžØ± ØŽÙ
+Ø§ Ø¯Ø± Ø¢Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±ÙØ¯ .
+      Ø§Ø³ÙØ§Ø¯Û Ú©Ù ØªØ·ØšÛÙ Ú©ÙÙØ¯ ØšÙ ØªØ±ØªÛØš Ø§ÙÙØšØ§ÛÛ ÙØŽØ§Ù Ø¯Ø§Ø¯Ù Ø®ÙØ§ÙØ¯ ØŽØ¯.<p>
+
+  <li>Ø¬Ø³ØªØ¬ÙÛ ØšØ±Ø§Û  <b>ØšØ¹Ø¶Û </b> Ø§Ø² Ú©ÙÙ
+Ø§Øª.  ÙÙØ±Ø³ØªÛ Ø§Ø² Ø¹ØšØ§Ø±Ø§Øª Ú©Ù Ù
+Ù
+Ú©Ù Ø§Ø³Øª Ø¯Ø± Ø³ÙØ¯ ÙØ¬ÙØ¯ Ø¯Ø§ØŽØªÙ 
+  ØšØ§ØŽÙØ¯.  ÙØªØ§ÛØ¬ ØšØ± Ø§Ø³Ø§Ø³ Ù
+ÛØ²Ø§Ù ØªØ·Ø§ØšÙ ØšØ§ Ø¬Ø³ØªØ¬Ù ÙØŽØ§Ù Ø¯Ø§Ø¯Ù Ù
+Û ØŽÙÙØ¯ .  
+  Ø¯Ø± ØªØ¹ÛÛÙ Ù
+ÛØ²Ø§Ù ØªØ·Ø§ØšÙ,
+
+      <p><ul>
+        <li> ÙØ±ÚÙ ØšÛØŽØªØ± Ø§Ø² Ø¹ØšØ§Ø±Ø§Øª Ø¬Ø³ØªØ¬Ù Ø¯Ø§ØŽØªÙ ØšØ§ØŽØ¯ ØšÛØŽØªØ± ØªØ·Ø§ØšÙ Ø¯Ø§Ø±Ø¯
+        <li> Ø¹ØšØ§Ø±Ø§Øª ÙØ§Ø¯Ø± ØšÛØŽØªØ± Ø§Ø² Ø¹ØšØ§Ø±Ø§Øª Ø¹Ù
+ÙÙ
+Û Ù
+ÙÙ
+ ÙØ³ØªÙØ¯
+        <li> Ø§Ø³ÙØ§Ø¯ Ú©ÙØªØ§Ù Ù
+ÙÙ
+ØªØ± Ø§Ø² Ø§Ø³ÙØ§Ø¯ ØšÙÙØ¯ ÙØ³ØªÙØ¯.
+      </ul>
+</ul>
+
+<p>ÙØ± ØªØ¹Ø¯Ø§Ø¯ ÙØšØ§Ø±Øª Ú©Ù Ù
+Û Ø®ÙØ§ÙÛØ¯ ØšØ±Ø§Û Ø¬Ø³ØªØ¬Ù ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ ÛÚ© Ø¬Ù
+ÙÙ ÛØ§ Ø­ØªÛ ÛÚ© ÙŸØ§Ø±Ø§Ú¯Ø±Ø§Ù.
+Ø§Ú¯Ø± ØªÙÙØ§ ÛÚ© Ø¹ØšØ§Ø±Øª ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ ØšØ± Ø­Ø³Øš ØªÚ©Ø±Ø§Ø± Ø¢Ù Ø¹ØšØ§Ø±Øª ÙØªØ§ÛØ¬ Ù
+Ø±ØªØš Ø®ÙØ§ÙÙØ¯ ØŽØ¯.<p>}
+
+_texthelpmgppsearching_ [l=fa] {ØšØ±Ø§Û Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û Ø³Ø§Ø®ØªÙ ØŽØ¯Ù ØªÙØ³Ø· MGPP Ú¯Ø²ÛÙÙ ÙØ§Û Ø§ÙØªØ®Ø§ØšÛ Ø¯ÛÚ¯Ø±Û ÙÛØ² Ù
+ÙØ¬ÙØ¯ Ø§Ø³Øª.
+<ul>
+Ø¹ÙØ§Ù
+Øª <li>A <b>*</b> Ø¯Ø± Ø§ÙØªÙØ§Û Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬ÙØ ØªÙ
+Ø§Ù
+Û ÙØºØ§ØªÛ Ø±Ø§ Ú©Ù ØšØ§ Ø¢Ù Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù <b>ØŽØ±ÙØ¹ ØŽØ¯Ù</b> ØšØ§Ø²ÛØ§ØšÛ Ù
+Û Ú©ÙØ¯. ØšØ±Ø§Û ÙÙ
+ÙÙÙØ <b>comput*</b> ØªÙ
+Ø§Ù
+Û ÙØºØ§ØªÛ Ø±Ø§ Ú©Ù ØšØ§ <b>comput</b> ØŽØ±ÙØ¹ ØŽØ¯Ù Ø§ÙØ¯ Ø±Ø§ ØšØ§Ø²ÛØ§ØšÛ Ù
+Û Ú©ÙØ¯.
+Ø¹ÙØ§Ù
+Øª <li><b>/x</b> Ù
+Û ØªÙØ§ÙØ¯ Ø¬ÙØª Ø§Ø±Ø²ØŽ Ø¯ÙÛ ØšÛØŽØªØ± ØšÙ ÛÚ© ÛØ§ ÚÙØ¯ Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù Ø§Ø³ØªÙØ§Ø¯Ù ØŽÙØ¯. ØšØ±Ø§Û ÙÙ
+ÙÙÙ Ø¹ØšØ§Ø±Øª <b>computer/10 science</b>Ø Ø§Ø±Ø²ØŽÛ Ù
+Ø¹Ø§Ø¯Ù 10ØšØ±Ø§ØšØ± ØšÛØŽØªØ± ØšØ±Ø§Û ÙØ§ÚÙ computer ÙØ³ØšØª ØšÙ science ÙØ§ØŠÙ Ù
+Û ØŽÙØ¯.}  
+
+_texthelplucenesearching_ [l=fa] {ØšØ±Ø§Û Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û Ø³Ø§Ø®ØªÙ ØŽØ¯Ù ØšØ§ Lucene ØªØ¹Ø¯Ø§Ø¯ Ú¯Ø²ÛÙÙ Ø¯ÛÚ¯Ø± ÙØ§ØšÙ Ø§Ø³ØªÙØ§Ø¯Ù ÙØ³ØªÙØ¯ .
+<ul>
+<li><b>?</b> Ù
+Û ØªÙØ§ÙØ¯ ØšÙ Ø¬Ø§Û ÛÚ© Ø­Ø±Ù Ù
+ÙØ±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙØ±Ø§Ø± Ú¯ÛØ±Ø¯ Ù
+Ø«ÙØ§ , <b>b?t</b> ØªØ·ØšÛÙ Ù
+Û Ú©ÙØ¯ ØšØ§  <b>bet</b>, <b>bit</b> and <b>bat</b> Ù ØºÛØ±Ù.
+<li><b>*</b> Ù
+Û ØªÙØ§ÙØ¯ ØšÙ Ø¬Ø§Û ÚÙØ¯ÛÙ Ø­Ø±Ù Ù
+ÙØ±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙØ±Ø§Ø± Ú¯ÛØ±Ø¯ Ù
+Ø«ÙØ§ , <b>comput*</b> ØªØ·ØšÛÙ Ù
+Û Ú©ÙØ¯ ØšØ§ ØªÙ
+Ø§Ù
+ Ú©ÙÙ
+Ø§ØªÛ Ú©Ù ØšØ§ <b>comput</b> ØŽØ±ÙØ¹ Ù
+Û ØŽÙÙØ¯.
+</ul>
+ÙØ± Ø¯ÙÛ Ø§ÛÙ Ø¹ØšØ§Ø±Ø§Øª Ù
+Û ØªÙØ§ÙØ¯ Ø¯Ø±Ù
+ÛØ§Ù ÛØ§ Ø§ÙØªÙØ§Û Ø¹ØšØ§Ø±Øª Ù
+ÙØ±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙØ±Ø§Ø± Ú¯ÛØ±Ø¯ . Ø§Ù
+Ø§ Ø¯Ø± Ø§ØšØªØ¯Ø§Û Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù ÙÙ
+Û ØªÙØ§ÙÙØ¯ ÙØ±Ø§Ø± Ú¯ÛØ±ÙØ¯ .}  
+
+_texthelpquerytypetitle_ [l=fa] {ÙÙØ¹ Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù}  
+_texthelpquerytype_ [l=fa] {<p> Ø¯Ù ÙÙØ¹ Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªÙ ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯:
+<ul>
+<li>
+Ø¹ØšØ§Ø±Ø§Øª Ø¬Ø³ØªØ¬Ù ØšØ±Ø§Û <b>ÙÙ
+Ù</b> ÙØºØ§Øª. 
+Ø§ÛÙ Ù
+ÙØ±Ø¯ Ø§Ø³ÙØ§Ø¯ (ÛØ§ ÙØµÙ ÙØ§Ø ÛØ§ Ø¹ÙÙØ§Ù ÙØ§) ÛÛ Ø±Ø§ ØŽØ§Ù
+Ù Ù
+Û ØŽÙØ¯ Ú©Ù ØªÙ
+Ø§Ù
+Û ÙØºØ§ØªÛ Ø±Ø§ Ú©Ù ØŽÙ
+Ø§ Ù
+ØŽØ®Øµ Ú©Ø±Ø¯Ù ØšÙØ¯ÛØ¯Ø Ø¯Ø± ØšØ± Ø¯Ø§Ø±Ø¯.
+Ø§Ø³ÙØ§Ø¯Û Ú©Ù ØšØ§ Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù Ù
+Ø·Ø§ØšÙØª Ø¯Ø§Ø±ÙØ¯Ø Ø¯Ø± ØªØ±ØªÛØš Ø³Ø§Ø®ØªÙ ØŽØ¯Ù ÙÙ
+Ø§ÛØŽ Ø¯Ø§Ø¯Ù Ù
+Û ØŽÙÙØ¯.
+<p>
+
+<li>
+Ø¹ØšØ§Ø±Ø§Øª Ø¬Ø³ØªØ¬Ù ØšØ±Ø§Û <b>ØšØ±Ø®Û </b> Ø§Ø² ÙØºØ§Øª
+Ø§ÛÙ Ù
+ÙØ±Ø¯ ØµØ±ÙØ§ ÙØºØ§ØªÛ Ø±Ø§ ØŽØ§Ù
+Ù Ù
+Û ØŽÙØ¯ Ú©Ù Ø¯Ø± Ø§Ø³ÙØ§Ø¯ Ù
+ÙØ±Ø¯ ÙØžØ± ØŽÙ
+Ø§ Ø§Ø­ØªÙ
+Ø§ÙØ§ ÙØ¬ÙØ¯ Ø¯Ø§ØŽØªÙ ØšØ§ØŽÙØ¯. Ø§Ø³ÙØ§Ø¯ 
+ØšØ±Ø§Ø³Ø§Ø³ Ù
+ÛØ²Ø§Ù ÙØ²Ø¯ÛÚ© ØšÙØ¯Ù ØšÙ Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù ØšØ§Ø²ÛØ§ØšÛ Ù
+Û ØŽÙÙØ¯. ÙÙÚ¯Ø§Ù
+ ØªØ¹ÛÛÙ Ø¯Ø±Ø¬Ù Ù
+Ø·Ø§ØšÙØªØ
+<p><ul>
+<li> 
+<li> ØšÙ Ø·ÙØ± Ú©ÙÛ ÙØºØ§ØªÛ Ú©Ù ØšÙ ÙØ³ØšØª Ú©Ù
+ØªØ± ØªÚ©Ø±Ø§Ø± ØŽØ¯Ù Ø§ÙØ¯ Ø§Ø² Ø§Ø±Ø²ØŽ ØšÛØŽØªØ±Û ÙØ³ØšØª ØšÙ ÙØºØ§Øª Ø¹Ù
+Ù
+ÙÙ
+Û Ø ØšØ±Ø®ÙØ±Ø¯Ø§Ø±ÙØ¯Ø
+<li>Ø§Ø³ÙØ§Ø¯ Ù
+Ø®ØªØµØ±ØªØ± Ø¯Ø± ØšØ§Ø²ÛØ§ØšÛ Ø§Ø² ØªØ·Ø§ØšÙ ØšÙØªØ±Û ÙØ³ØšØª ØšÙ Ø§Ø³ÙØ§Ø¯ Ø·ÙÙØ§ÙÛ ØšØ±Ø®ÙØ±Ø¯Ø§Ø±ÙØ¯
+     </ul>
+</ul>
+
+<p> ÙØ± ØªØ¹Ø¯Ø§Ø¯ Ø§ØµØ·ÙØ§Ø­ Ø¬Ø³ØªØ¬Ù Ú©Ù Ø¯ÙØ³Øª Ø¯Ø§Ø±ÛØ¯ - ÛÚ© Ø¬Ù
+ÙÙ Ú©Ø§Ù
+Ù ÛØ§ Ø­ØªÛ ÛÚ© ÙŸØ§Ø±Ø§Ú¯Ø±Ø§ÙØ Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛØ¯Ø Ø§Ù
+Ø§ ØªÙØ¬Ù Ø¯Ø§ØŽØªÙ ØšØ§ØŽÛØ¯
+Ú©Ù ÚÙØ§ÙÚÙ ØŽÙ
+Ø§ ØµØ±ÙØ§ Ø§Ø² ÛÚ© Ø§ØµØ·ÙØ§Ø­ Ø¬ÙØª Ø¬Ø³ØªØ¬Ù Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛØ¯Ø Ø§Ø³ÙØ§Ø¯ ØšØ§Ø²ÛØ§ØšÛ ØŽØ¯Ù ØšØ± Ø§Ø³Ø§Ø³ ØšØ³Ø§Ù
+Ø¯ Ø­Ø¶ÙØ± Ø¢ÙØ Ù
+Ø±ØªØš Ø®ÙØ§ÙÙØ¯ ØŽØ¯. <p>}  
+
+_texthelpadvancedsearchtitle_ [l=fa] {Ø¬Ø³ØªØ¬ÙÛ ÙŸÛØŽØ±ÙØªÙ ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ù
+ÙØªÙØ± Ø¬Ø³ØªØ¬ÙÛ _1_}  
+
+_texthelpadvancedsearch_ [l=fa] {<p> Ø§Ú¯Ø± ØŽÙ
+Ø§ Ø¯Ø± ØªÙØžÛÙ
+Ø§Øª Ø­Ø§ÙØª Ø¬Ø³ØªØ¬ÙÛ ÙŸÛØŽØ±ÙØªÙ Ø±Ø§ Ø§ÙØªØ®Ø§Øš Ú©Ø±Ø¯Ù Ø§ÛØ¯Ø Ø¯Ø± Ø§ÛÙ ØµÙØ±Øª Ø§Ø®ØªÛØ§Ø±Ø§Øª Ø¬Ø³ØªØ¬ÙÛ Ù
+ØªÙØ§ÙØªÛ Ø®ÙØ§ÙÛØ¯ Ø¯Ø§ØŽØª._selectadvancedsearch_}  
+
+_texthelpadvsearchmg_ [l=fa] {Ø¬Ø³ØªØ¬ÙÛ Ø¯Ø± Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û MGØ Ø¯Ù Ø§Ù
+Ú©Ø§Ù Ø±Ø§ Ø¯Ø± Ø§Ø®ØªÛØ§Ø± ØŽÙ
+Ø§ ÙØ±Ø§Ø± Ø®ÙØ§ÙØ¯ Ø¯Ø§Ø¯Ø Ø±ØªØšÙ ØšÙØ¯Û Ù Ø¹Ù
+ÙÚ¯Ø±ÙØ§Û ØšÙÙÛ.
+ÛÚ© Ø¬Ø³ØªØ¬ÙÛ <b>Ø±ØªØšÙ ØšÙØ¯Û ØŽØ¯Ù</b> Ø¯ÙÛÙØ§ Ù
+ØŽØ§ØšÙ Ø§Ø³Øª ØšØ§ <b>ØšØ±Ø®Û</b> Ø¬Ø³ØªØ¬ÙÙØ§  Ú©Ù Ø¯Ø± <a href="\#query-type">_texthelpquerytypetitle_</a> ØŽØ±Ø­ Ø¯Ø§Ø¯Ù ØŽØ¯.
+<p>_texthelpbooleansearch_}  
+
+_texthelpbooleansearch_ [l=fa] {ÛÚ© Ø¬Ø³ØªØ¬ÙÛ <b>ØšÙÙÛ</b> ØšÙ ØŽÙ
+Ø§ Ø§ÛÙ Ø§Ù
+Ú©Ø§Ù Ø±Ø§ Ù
+Û Ø¯ÙØ¯ Ú©Ù ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² & (ØšØ¬Ø§Û"and") Ù I (ØšØ¬Ø§Û "or") Ù ! (ØšØ±Ø§Û"not") Ù ÙÙØ§ÛØªØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² ÙŸØ±Ø§ÙØªØ² ØšØ±Ø§Û Ú¯Ø±ÙÙ ØšÙØ¯ÛØ Ø§ØµØ·ÙØ§Ø­Ø§Øª Ø±Ø§ ØªØ±Ú©ÛØš Ú©ÙÛØ¯. Ø¹Ù
+ÙÚ¯Ø± ÙŸÛØŽ ÙØ±Ø¶ I (ØšØ±Ø§Û"or") Ø§Ø³Øª.
+<p>
+ØšØ±Ø§Û ÙÙ
+ÙÙÙØ <b>snail & farming</b> Ø§Ø³ÙØ§Ø¯Û Ø±Ø§ ØšØ§Ø²ÛØ§ØšÛ Ø®ÙØ§ÙØ¯ ÙØ± Ø¯ÙÛ b>snail</b> Ù <b>farming</b> Ø¯Ø± Ø¢ÙÙØ§ Ù
+ÙØ¬ÙØ¯ ØšØ§ØŽØ¯Ø Ø¯Ø± Ø­Ø§ÙÛÚ©Ù <b>snail | farming</b>Ø Ø§Ø³ÙØ§Ø¯Û Ø±Ø§ ØšØ§Ø²ÛØ§ØšÛ Ø®ÙØ§ÙØ¯ Ú©Ø±Ø¯ Ú©Ù ÛØ§ <b>snail</b> ÛØ§ <b>farming</b> Ø±Ø§ Ø¯Ø± ØšØ±Ø¯Ø§ØŽØªÙ ØšØ§ØŽØ¯.
+<b>snail !farming</b> Ø§Ø³ÙØ§Ø¯Û Ø±Ø§ ØšØ§Ø²ÛØ§ØšÛ Ø®ÙØ§ÙØ¯ Ú©Ø±Ø¯ Ú©Ù Ø¯Ø± Ø¢ÙÙØ§ <b>snail</b> Ù
+ÙØ¬ÙØ¯ ØšØ§ØŽØ¯ ÙÙ <b>farming</b>.
+<p>
+Ø¹ØšØ§Ø±Ø§Øª Ø¬Ø³ØªØ¬ÙÛ Ø¯ÙÛÙ ØªØ± ØšØ§ ØšÙØ±Ù Ú¯ÛØ±Û Ø§Ø² ØªØ±Ú©ÛØšÛ Ø§Ø² Ø¹Ù
+ÙÚ¯Ø±ÙØ§ Ù ÙŸØ±Ø§ÙØªØ² Ù
+ÙØ¯ÙØ± Ø®ÙØ§ÙØ¯ ØšÙØ¯. ØšØ±Ø§Û ÙÙ
+ÙÙÙØ <b>(sheep | cattle) & (farm | station)</b>, or <b>sheep | cattle | goat !pig</b>.}  
+
+_texthelpadvsearchmgpp_ [l=fa] {Ø¬Ø³ØªØ¬ÙÛ ÙŸÛØŽØ±ÙØªÙ Ø¯Ø± Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û MGPP ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ø¹Ù
+ÙÚ¯Ø±ÙØ§Û ØšÙÙÛ Ø§ÙØ¬Ø§Ù
+ Ù
+Û Ú¯ÛØ±Ø¯._texthelpbooleansearch_
+<p> ÙØªØ§ÛØ¬ Ø¯Ø± ÛÚ© ØªØ±ØªÛØš <b>Ø±ØªØšÙ ØšÙØ¯Û ØŽØ¯Ù</b> ÙØ§ØšÙ Ø§Ø±Ø§ØŠÙ ÙØ³ØªÙØ¯ ÙÙ
+Ø§ÙØ·ÙØ± Ú©ÙØ ØšØ±Ø§Û <b>ØšØ±Ø®Û</b> Ø¬Ø³ØªØ¬ÙÙØ§ Ø¯Ø± <a href="\#query-type">_texthelpquerytypetitle_</a> ØŽØ±Ø­ Ø¯Ø§Ø¯Ù ØŽØ¯Ø ÛØ§ Ø¯Ø± ØªØ±ØªÛØš "Ø·ØšÛØ¹Û"(ÛØ§ "Ø³Ø§Ø®ØªÙ ØŽØ¯Ù"). Ø§ÛÙ ØªØ±ØªÛØšÛ Ø§Ø³Øª Ú©Ù Ø§Ø³ÙØ§Ø¯ Ø¯Ø± Ø·Û ÙØ±Ø§ÛÙØ¯ Ø§ÛØ¬Ø§Ø¯ ÙŸØ±Ø¯Ø§Ø²ØŽ ØŽØ¯ÙØ¯.
+<b>NEARx</b> and <b>WITHINx</b> Ø§Ø² Ø¯ÛÚ¯Ø± Ø¹Ù
+ÙÚ¯Ø±ÙØ§Û Ù
+ÙØ±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙØ³ØªÙØ¯.
+Ø¹Ù
+ÙÚ¯Ø± NEARx Ø¬ÙØª ØªØŽØ®ÛØµ ØšÛØŽØªØ±ÛÙ ÙØ§ØµÙÙ ØšÛÙ Ø¯Ù Ø¹ØšØ§Ø±Øª Ø¬Ø³Ø¬ÙÛ Ù
+Ø¬Ø§ÙØ± ØšÙ Ú©Ø§Ø± Ù
+Û Ø±ÙØ¯ ØªØ§ ØšØ§ ÛÚ© Ø³ÙØ¯ ØªØ·Ø§ØšÙ Ø¯Ø§ØŽØªÙ ØšØ§ØŽØ¯.
+Ø¹Ù
+ÙÚ¯Ø± WITHINx Ù
+ØŽØ®Øµ Ù
+Û Ú©ÙØ¯ Ú©Ù Ø§ØµØ·ÙØ§Ø­ Ø¯ÙÙ
+ ØšØ§ÛØ¯ Ø¯Ø± Ø¯Ø§Ø®Ù Ú©ÙÙ
+Ø§Øªx ÙÙÛ <i>ØšØ¹Ø¯ Ø§Ø²</i> Ø§ØµØ·ÙØ§Ø­ Ø§ÙÙÛ Ù
+ÙØ¬ÙØ¯ ØšØ§ØŽØ¯. Ø§ÛÙ Ø¹Ù
+ÙÚ¯Ø± Ù
+ØŽØ§ØšÙ NEAR Ø¹Ù
+Ù Ù
+Û Ú©ÙØ¯ ØšØ§ Ø§ÛÙ ØªÙØ§ÙØª Ú©Ù ØªØ±ØªÛØš Ù
+ÙÙ
+ Ø§Ø³Øª.
+ÙØ§ØµÙÙ ÙŸÛØŽ ÙØ±Ø¶ 20 Ø§Ø³Øª.}
+
+_texthelpadvancedsearchextra_ [l=fa] {ÙÚ©ØªÙ : Ø§ÛÙ Ø¹Ù
+ÙÚ¯Ø±ÙØ§ Ø¯Ø± ØµÙØ±Øª Ø§ÛÙÚ©Ù Ø­Ø§ÙØª Ø¬Ø³ØªØ¬ÙÛ Ø³Ø§Ø¯Ù ÙØ¹Ø§Ù ØšØ§ØŽÙØ¯ Ù
+ÙØ±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙØ±Ø§Ø± ÙÙ
+Û Ú¯ÛØ±ÙØ¯ .}  
+
+_texthelpadvsearchlucene_ [l=fa] {Ø¬Ø³ØªØ¬Ù ÙŸÛØŽØ±ÙØªÙ Ø¯Ø± Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û Lucene ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ø¹Ù
+ÙÚ¯Ø±ÙØ§Û ØšÙÙÛ Ø§ÙØ¬Ø§Ù
+ Ù
+Û Ú¯ÛØ±Ø¯._texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=fa] {Ø¬Ø³ØªØ¬ÙÛ Ù
+ØšØªÙÛ ØšØ± ÙÛÙØ¯}  
+
+_texthelpformsearch_ [l=fa] {Ø¬Ø³ØªØ¬ÙÛ Ù
+ØšØªÙÛ ØšØ± ÙÛÙØ¯ Ø§ÛÙ Ø§Ù
+Ú©Ø§Ù Ø±Ø§ ÙØ±Ø§ÙÙ
+ Ù
+Û Ø¢ÙØ±Ø¯ ØªØ§ ÙØ±Ø§ÛÙØ¯ Ø¬Ø³ØªØ¬Ù Ø§Ø² Ø·Ø±ÛÙ ÙÛÙØ¯ÙØ§ Ù
+ÙØ³Ø¬Ù
+ ØªØ± ØŽÙØ¯. ØšØ±Ø§Û ÙÙ
+ÙÙÙØ ÛÚ© ÙÙØ± Ù
+Ù
+Ú©Ù Ø§Ø³ØªØ ØšØ§ ÙØ§Ø±Ø¯ Ú©Ø±Ø¯Ù "Smith" Ø¯Ø± Ø¹ÙÙØ§Ù Ù "snail farming" Ø¯Ø± Ù
+ÙØ¶ÙØ¹Ø Ø¬Ø³ØªØ¬Ù Ø±Ø§ Ø§ÙØ¬Ø§Ù
+ Ø¯ÙØ¯.
+Ø¯Ø± Ø­Ø§ÙØª  Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬ÙÛ Ø³Ø§Ø¯ÙØ ÙØ± Ø®Ø·Û Ø¯Ø± ÙØ±Ù
+ ÙÙ
+Ø§ÙÙØ¯ ÛÚ© Ø®Ø· Ø¬Ø³ØªØ¬ÙÛ Ø³Ø§Ø¯Ù Ø¹Ù
+Ù Ù
+Û Ú©ÙØ¯. Ø®Ø·ÙØ· Ù
+ÙØ­ØµØ± ØšÙ ÙØ±Ø¯ ÙØ±Ù
+ ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² AND (ØšØ±Ø§Û Ø¬Ø³ØªØ¬ÙÛ "Ú©ÙÛ") Ù OR (ØšØ±Ø§Û Ø¬Ø³ØªØ¬ÙÛ "Ù
+ÙØ±Ø¯Û")Ø ØªØ±Ú©ÛØš Ù
+Û ØŽÙÙØ¯. Ø§ØµØ·ÙØ§Ø­Ø§Øª Ø¯Ø§Ø®Ù ÙÛÙØ¯ ÙÛØ² 
+ØšØ§ Ø±ÙØŽÛ Ù
+ØŽØ§ØšÙ ØªØ±Ú©ÛØš Ù
+Û ØŽÙÙØ¯. Ø¯Ø± Ø­Ø§ÙØª ÙŸÛØŽØ±ÙØªÙØ ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ ØªØ±Ú©ÛØšØ§Øª Ù
+Ø®ØªÙÙÛ Ø§Ø² AND/OR/NOTÙ
+Ø§ØšÛÙ ÙÛÙØ¯ÙØ§ ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² ÙÛØ³ØªÙØ§Û Ø¢ØšØŽØ§Ø±Û Ù
+ØŽØ®Øµ Ú©ÙÛØ¯Ø Ù Ø¯Ø± Ø¯Ø§Ø®Ù ÙÛÙØ¯ Ø§Ø² Ø¹Ù
+ÙÚ¯Ø±ÙØ§Û ØšÙÙÛÙ Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛØ¯.}  
+
+_texthelpformstemming_ [l=fa] {ØšØ§ÙØ³ÙØ§Ù "fold" Ù "stem" ØšÙ ØŽÙ
+Ø§ ÙÙ
+Ù Ù
+Ù ÙÙØ¯ ØªØ§ ØªØŽØ®ÙØµ Ø¯ÙÙØ¯ ÙÙ Ø¢ÙØ§ Ø§ØµØ·ÙØ§Ø­Ø§Øª Ø¯Ø§Ø®Ù Ø¢Ù ÙÙÙØ¯ casefoded ÙØ§ stemmed ÙØ³ØªÙØ¯. Ø¯Ø± Ø­Ø§ÙØª Ø¬Ø³ØªØ¬ÙÙ ÙŸÙØŽØ±ÙØªÙ ÙØ± Ø¯ÙÙ Ø¢ÙÙØ§ ØšØ·ÙØ± ÙŸÛØŽ ÙØ±Ø¶ Ø®Ø§Ù
+ÙØŽ Ù
+Ù ØŽÙÙØ¯.}  
+
+_textdatesearch_ [l=fa] {Ø¯Ø± Ø­Ø§Ù Ø¬Ø³ØªØ¬Ù ØšØ§ ØªØ§Ø±ÙØ®}  
+
+_texthelpdatesearch_ [l=fa] {Ø¬Ø³ØªØ¬ÙÛ ØšÙ Ú©Ù
+Ú© ØªØ§Ø±ÛØ® Ø§Ø³ÙØ§Ø¯Û Ø±Ø§ ØšÛØ§ØšÛØ¯ Ú©Ù Ø¹ÙØ§ÙÙ ØšØ± Ø§ÛÙÚ©Ù Ø¹ØšØ§Ø±Ø§Øª Ù
+ÙØ±Ø¯ Ø¬Ø³ØªØ¬ÙÛ ØŽÙ
+Ø§ 
+Ø¯Ø± Ø¢Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ Ø¯Ø± ÛÚ© ØšØ§Ø²Ù Ø²Ù
+Ø§ÙÛ Ø®Ø§Øµ ÙÙ
+ ÙØ±Ø§Ø± Ú¯Ø±ÙØªÙ Ø§Ø³Øª . ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ Ø§Ø³ÙØ§Ø¯Û Ø±Ø§ Ø¯Ø± ÛÚ© Ø³Ø§Ù 
+Ù
+ØŽØ®Øµ ÛØ§ Ø¯Ø± Ù
+Ø­Ø¯ÙØ¯Ù Ø§Û Ø§Ø² Ø³Ø§ÙÙØ§ ÙØ±Ø§Ø± Ø¯Ø§Ø±ÙØ¯ . ØªÙØ¬Ù Ø¯Ø§ØŽØªÙ ØšØ§ØŽÛØ¯ Ú©Ù Ù
+Ø¬ØšÙØ± ÙÛØ³ØªÛØ¯ Ø®ØªÙ
+Ø§ Ø¹ØšØ§Ø±ØªÛ 
+ØšØ±Ø§Û Ø¬Ø³ØªØ¬Ù ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ ØšÙÚ©Ù Ù
+Û ØªÙØ§ÙÛØ¯ ØªÙÙØ§ ØšØ§ Ù
+ØŽØ®Øµ Ú©Ø±Ø¯Ù ØªØ§Ø±ÛØ® Ø¬Ø³ØªØ¬Ù ÙÙ
+Ø§ÛÛØ¯ .
+ÙÙ
+ÚÙÛÙ ÙØ§Ø²Ù
+ ÙÛØ³Øª Ú©Ù Ø§Ø² ØªØ§Ø±ÛØ® Ø¯Ø± Ø¬Ø³ØªØ¬Ù Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ÛÛØ¯ Ù Ø§Ú¯Ø± ØªØ§Ø±ÛØ®Û ÙØ§Ø±Ø¯ ÙÚ©ÙÛØ¯
+Ù
+Ø§ÙÙØ¯ Ø§ÛÙ Ø§Ø³Øª Ú©Ù Ø§ØµÙØ§ Ø¬Ø³ØªØ¬ÙÛ ØªØ§Ø±ÛØ® ÙØ¬ÙØ¯ ÙØ¯Ø§Ø±Ø¯ .}
+
+_texthelpdatehowtotitle_ [l=fa] {ÚÚ¯ÙÙÚ¯Û Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ø§ÛÙ ÙÛÚÚ¯Û}
+_texthelpdatehowto_ [l=fa] {<ul>
+   <li>ØšØ±Ø§Û Ø¬Ø³ØªØ¬ÙÛ Ø§Ø³ÙØ§Ø¯ Ø¯Ø± ÛÚ© Ø³Ø§Ù Ù
+Ø¹ÛÙ :<p>
+   <ul>
+       <li>Ø¹ØšØ§Ø±Ø§Øª Ù
+ÙØ±Ø¯ Ø¬Ø³ØªØ¬Ù Ø®ÙØ¯ Ø±Ø§ ØšÙ ØŽÛÙÙ Ù
+Ø¹Ù
+ÙÙ ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ 
+       <li>Ø¯Ø± ÙØ³Ù
+Øª "ØªØ§Ø±ÛØ® Ø¢ØºØ§Ø² (ÛØ§ ÙÙØ·)" Ø³Ø§Ù Ù
+ÙØ±Ø¯ ÙØžØ± Ø±Ø§ ÙØ§Ø±Ø¯ Ú©ÙÛØ¯.
+       <li>Ø§Ú¯Ø± ØªØ§Ø±ÛØ® Ù
+ÙØ±Ø¯ ÙØžØ± ØŽÙ
+Ø§ ÙØšÙ Ø§Ø² Ø¹ØµØ± Ø­Ø§Ø¶Ø± Ø§Ø³Øª (ÙØšÙ Ø§Ø² Ù
+Ø³ÛØ­) 
+ Ú¯Ø²ÛÙÙ ÙŸÛØŽ Ø§Ø² Ù
+ÛÙØ§Ø¯ Ù
+Ø³ÛØ­ Ø±Ø§ Ø§Ø² Ù
+ÙÙÛ Ú©ÙØ§Ø± ÙØ³Ù
+Øª ØªØ§Ø±ÛØ® Ø§ÙØªØ®Ø§Øš Ú©ÙÛØ¯.
+       <li>Ù
+Ø§ÙÙØ¯ ÙÙ
+ÛØŽÙ Ø¬Ø³ØªØ¬ÙÛ Ø®ÙØ¯ Ø±Ø§ Ø¢ØºØ§Ø² Ú©ÙÛØ¯
+   </ul>
+<p><li>ØšØ±Ø§Û Ø¬Ø³ØªØ¬Ù Ø¯Ø± ÛÚ© ØšØ§Ø²Ù Ø²Ù
+Ø§ÙÛ ÛØ§ ØšÛÙ Ø¯ÙØ³Ø§Ù :<p>
+   <ul>
+       <li>Ø¹ØšØ§Ø±Ø§Øª Ù
+ÙØ±Ø¯ Ø¬Ø³ØªØ¬Ù Ø®ÙØ¯ Ø±Ø§ ØšÙ ØŽÛÙÙ Ù
+Ø¹Ù
+ÙÙ ÙØ§Ø±Ø¯ Ú©ÙÛØ¯
+       <li>ØªØ§Ø±ÛØ® Ø§ØšØªØ¯Ø§ Ø±Ø§ Ø¯Ø± ÙØ³Ù
+Øª "ØªØ§Ø±ÛØ® Ø¢ØºØ§Ø²(ÛØ§ÙÙØ·)" ÙØ§Ø±Ø¯ Ú©ÙÛØ¯
+       <li>ØªØ§Ø±ÛØ® Ø§ÙØªÙØ§ Ø±Ø§ Ø¯Ø± ÙØ³Ù
+Øª "ØªØ§Ø±ÛØ® Ø§ÙØªÙØ§" ÙØ§Ø±Ø¯ Ú©ÙÛØ¯.
+       <li>Ø§Ú¯Ø± ØªØ§Ø±ÛØ® Ù
+ÙØ±Ø¯ ÙØžØ± ØŽÙ
+Ø§ ÙØšÙ Ø§Ø² Ø¹ØµØ± Ø­Ø§Ø¶Ø± Ø§Ø³Øª (ÙØšÙ Ø§Ø² Ù
+Ø³ÛØ­) 
+ Ú¯Ø²ÛÙÙ ÙŸÛØŽ Ø§Ø² Ù
+ÛÙØ§Ø¯ Ù
+Ø³ÛØ­ Ø±Ø§ Ø§Ø² Ù
+ÙÙÛ Ú©ÙØ§Ø± ÙØ³Ù
+Øª ØªØ§Ø±ÛØ® Ø§ÙØªØ®Ø§Øš Ú©ÙÛØ¯.
+       <li>Ù
+Ø§ÙÙØ¯ ÙÙ
+ÛØŽÙ Ø¬Ø³ØªØ¬ÙÛ Ø®ÙØ¯ Ø±Ø§ Ø¢ØºØ§Ø² Ú©ÙÛØ¯
+   </ul>    
+</ul><p>}
+
+_texthelpdateresultstitle_ [l=fa] {ÚÚ¯ÙÙÙ ÙØªØ§ÛØ¬ Ø¬Ø³ØªØ¬ÙÛ ØŽÙ
+Ø§ ÛØ§ÙØª Ù
+Û ØŽÙØ¯}
+_texthelpdateresults_ [l=fa] {Ù
+Ø¹Ù
+ÙÙØ§ Ø¬Ø³ØªØ¬ÙÛ Ø§Ø³ÙØ§Ø¯ Ø¯Ø±ØšØ§Ø±Ù 1903 Ø§Ø³ÙØ§Ø¯Û Ø±Ø§ Ø¯Ø± Ø§ÛÙ Ø³Ø§Ù ÙÙØŽØªÙ ØŽØ¯Ù Ø§ÙØ¯ ØšØ± ÙÙ
+Û Ú¯Ø±Ø¯Ø§ÙØ¯ ØšÙÚ©Ù Ø§Ø³ÙØ§Ø¯Û Ø¯Ø±ØšØ§Ø±Ù 1903 Ø±Ø§ ØšØ±Ù
+Û Ú¯Ø±Ø¯Ø§ÙØ¯ . ÙÙÛ ØšØ§ ØªÙØ¬Ù ØšÙ Ø­Ø§ÙØªÛ Ú©Ù Ø¯Ø± Ø§Ø³ÙØ§Ø¯ ØªØ§Ø±ÛØ® ÙØ§ ÙØ¬ÙØ¯ Ø¯Ø§Ø±ÙØ¯  Ø§Ø³ÙØ§Ø¯Û Ø±Ø§ Ú©Ù ØšØ§Ø²Ù Ø²Ù
+Ø§ÙÛ Ø®Ø§ØµÛ Ù
+Ø«ÙØ§ 1899-1911 Ú©Ù ØŽØ§Ù
+Ù 1903 ÙÙ
+ Ù
+Û ØŽÙØ¯ Ù Ø§Ø³ÙØ§Ø¯Û Ú©Ù Ù
+Ø«ÙØ§ Ø­Ø§ÙÛ ÙØ±ÙÛ Ú©Ù Ø³Ø§Ù 1903 Ø¯Ø± Ø¢Ù Ø§Ø³Øª Ù
+Ø§ÙÙØ¯ ÙØ±Ù ØšÛØ³ØªÙ
+ ÛØ§ Ø¯ÙØ§Ø²Ø¯ÙÙ
+ ØªØŽØ®ÛØµ Ø¯Ø§Ø¯Ù Ù
+Û ØŽÙØ¯ . ØªÙØ¬Ù Ú©ÙÛØ¯ Ú©Ù Ø¯Ø± ØšØ¹Ø¶Û Ø§Ø³ÙØ§Ø¯ ØªØ§Ø±ÛØ® ÙØ§ ÙØ§ÙØ¹Ø§ Ø¯Ø± Ù
+ØªÙ ÙÛØ³ØªÙØ¯ . ØšØ±Ø§Û ÛÚ© Ø¬Ø³ØªØ¬ÙÛ Ù
+Ø­Ø¯ÙØ¯Ù Ø§Û ØŽØ§Ù
+Ù ÙÙ
+Ù ØªØ§Ø±ÛØ® ÙØ§ Ø¯Ø± Ø§ÛÙ Ù
+Ø­Ø¯ÙØ¯Ù Ù
+Û ØŽÙØ¯ .<p>}
+
+_textchangeprefs_ [l=fa] {ØªØºÙÙØ± ØªÙØžÙÙ
+Ø§Øª}
+
+_texthelppreferences_ [l=fa] {<p>ØšØ§ Ú©ÙÛÚ© ØšØ± Ø±ÙÛ Ø¯Ú©Ù
+Ù <i>ØªÙØžÛÙ
+Ø§Øª</i> Ø¯Ø± ØšØ§ÙØ§Û ØµÙØ­Ù ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ ØªØ§ ØšØ¹Ø¶Û ÙÛÚÚ¯ÛÙØ§Û Ø±Ø§ØšØ· Ú©Ø§Ø±ØšØ±Û
+Ø±Ø§ ØšØ§ ØªÙØ¬Ù ØšÙ ÙÛØ§Ø² Ø®ÙØ¯ ØªØºÛÛØ± Ø¯ÙÛØ¯.}
+
+_texthelpcollectionprefstitle_ [l=fa] {ØªÙØžÛÙ
+Ø§Øª Ù
+Ø¬Ù
+ÙØ¹Ù}
+_texthelpcollectionprefs_ [l=fa] {ØšØ¹Ø¶Û Ø§Ø² Ù
+Ø¬Ù
+ÙØ¹ ÙØ§ ØŽØ§Ù
+Ù ÚÙØ¯ÛÙ Ø²ÛØ± Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ³ØªÙØ¯ Ú©Ù Ù
+ÛØªÙØ§Ù ØšÙ ØµÙØ±Øª Ù
+Ø³ØªÙÙ ÛØ§ ØšØ§ÙÙ
+
+Ø¬Ø³ØªØ¬Ù ØŽÙÙØ¯ . Ú©Ù Ø¯Ø± Ø§ÛÙ ÙØ³Ù
+Øª Ù
+Û ØªÙØ§ÙÛØ¯ Ù
+ØŽØ®Øµ Ú©ÙÛØ¯ ÚÙ Ø²ÛØ± Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ÛÛ Ø¯Ø± Ø¬Ø³ØªØ¬ÙÛ
+ØŽÙ
+Ø§ ØšØ§ØŽÙØ¯ .}
+
+_texthelplanguageprefstitle_ [l=fa] {ØªÙØžÛÙ
+Ø§Øª Ø²ØšØ§Ù}
+_texthelplanguageprefs_ [l=fa] {ÙØ± Ù
+Ø¬Ù
+ÙØ¹Ù ÛÚ© Ø²ØšØ§Ù ÙŸÛØŽ Ú¯Ø²ÛØ¯Ù Ø¯Ø§Ø±Ø¯ Ø§Ù
+Ø§ Ø¯Ø± ØµÙØ±Øª ØªÙ
+Ø§ÛÙ Ù
+Û ØªÙØ§ÙÛØ¯ ØšÙ Ø²ØšØ§Ù Ø¯ÛÚ¯Ø±Û 
+Ø¢Ù Ø±Ø§ ØªØºÛÛØ± Ø¯ÙÛØ¯ . ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ Ø±ÙØŽ Ú©Ø¯Ú¯Ø°Ø§Ø±Û ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± ØšØ±Ø§Û Ø®Ø±ÙØ¬Û Ù
+Ø±ÙØ±Ú¯Ø± Ø±Ø§ ØªØºÛÛØ± Ø¯ÙÛØ¯ .
+Ø§ÙØšØªÙ ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± ØšÙ ØµÙØ±Øª ÙŸÛØŽ Ú¯Ø²ÛØ¯Ù Ø±ÙØŽ Ù
+ÙØ§Ø³Øš Ø±Ø§ Ø§ÙØªØ®Ø§Øš Ù
+Û Ú©ÙØ¯ Ø§Ù
+Ø§ Ø¯Ø± ØšØ¹Ø¶Û Ù
+Ø±ÙØ±Ú¯Ø± ÙØ§
+Ù
+Û ØªÙØ§Ù ØšØ§ Ø³Ø§ÛØ± Ø±ÙØŽ ÙØ§ ÙØªÛØ¬Ù ØšÙØªØ±Û Ú¯Ø±ÙØª . Ø¯Ø± ØªÙ
+Ø§Ù
+ Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ Ù
+Û ØªÙØ§Ù ÙØ§ÙØš Ú¯Ø±Ø§ÙÛÚ©Û Ø±Ø§ØšØ· Ø±Ø§ ØšÙ Ù
+ØªÙÛ 
+ØªØºÛÛØ± Ø¯Ø§Ø±Ø¯ Ú©Ù ØšÙ Ø®ØµÙØµ ØšØ±Ø§Û Ø§ÙØ±Ø§Ø¯Û Ú©Ù Ø¯Ø± Ø¯ÛØ¯ Ù
+ØŽÚ©Ù Ø¯Ø§Ø±ÙØ¯ ØšØ³ÛØ§Ø± Ù
+ÙÛØ¯ Ø§Ø³Øª Ø²ÛØ±Ø§ Ù
+Û ØªÙØ§ÙÙØ¯ Ø§Ø² Ø®Ø·ÙØ· 
+Ø¯Ø±ØŽØª ØªØ± ÛØ§ Ø®ÙØ§ÙÙØ¯Ù ÙØ§Û Ù
+ØªÙ Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ÛÙØ¯ .}
+
+_texthelppresentationprefstitle_ [l=fa] {ØªÙØžÛÙ
+Ø§Øª Ø§Ø±Ø§ØŠÙ}
+_texthelppresentationprefs_ [l=fa] {Depending on the particular collection, there may be several options you can
+set that control the presentation.
+ØšØ§ ØªÙØ¬Ù ØšÙ ÙØ± Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+Û ØªÙØ§Ù ÚÙØ¯ÛÙ Ú¯Ø²ÛÙÙ Ù
+Ø±ØªØšØ· ØšØ§ Ø§Ø±Ø§ØŠÙ Ø±Ø§ ØªÙØžÛÙ
+ ÙÙ
+ÙØ¯.
+<p>
+Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Û Ø§Ø² ØµÙØ­Ø§Øª ÙØš ØŽÙ
+Ø§ Ø±Ø§ ÙØ§Ø¯Ø± Ù
+Û Ø³Ø§Ø²Ø¯ ØªØ§ ÙÙØ§Ø± ÙØ±Ø§Ù
+ÛÙ ØšØ§ÙØ§Û ÙØ± ØµÙØ­Ù Ø±Ø§ ØªØºÛÛØ± Ø¯ÙÛØ¯  ØšÙØ§ØšØ±Ø§ÛÙ
+Ù
+Û ØªÙØ§ÙÛØ¯ ØµÙØ­Ø§Øª Ù
+ÙØ±Ø¯ ÙØžØ± Ø®ÙØ¯ Ø±Ø§ ØšØ¯ÙÙ Ø³Ø±ØµÙØ­Ù ÙØ§Û Ø§Ø³ØªØ§ÙØ¯Ø§Ø±Ø¯ Ø·Ø±Ø§Ø­Û ÙÙ
+Ø§ÛÛØ¯ . 
+Ø­ØªÛ Ù
+Û ØªÙØ§ÙØ¯ ÙŸÛØ§Ù
+ ÙØ§Û Ø§Ø®Ø·Ø§Ø± Ø³ÛØ³ØªÙ
+ Ø±Ø§ ØªØºÛÛØ± Ø¯ÙÛØ¯ Ù Ø­ØªÛ Ø¯Ø± ØšØ¹Ø¶Û ØµÙØ­Ø§Øª Ù
+Û ØªÙØ§ÙÛØ¯ Ø¯Ø± ØµÙØ­Ù
+ÙØªØ§ÛØ¬ Ø¬Ø³ØªØ¬Ù Ø·ÙØ±Û ØªÙØžÛÙ
+ Ú©ÙÛØ¯ Ú©Ù ØšÙ Ø¬Ø§Û ÙÙ
+Ø§ÛØŽ ÙØ³Ø®Ù Ø°Ø®ÛØ±Ù ØŽØ¯Ù Ø¯Ø± ØšØ±ÙØ§Ù
+Ù ÙØ³Ø®Ù ÙØ§ÙØ¹Û ÙÙ
+Ø§ÛØŽ ÛØ§ØšØ¯ .}
+
+_texthelpsearchprefstitle_ [l=fa] {ØªÙØžÛÙ
+Ø§Øª Ø¬Ø³ØªØ¬Ù}
+_texthelpsearchprefs_ [l=fa] {<p>
+Ø¯Ù Ø¬ÙØª Ø¯Ú©Ù
+Ø® ÙØ­ÙÙ ØªØ·ØšÛÙ Ù
+ØªÙÙ Ø±Ø§ Ø¯Ø± Ø¬Ø³ØªØ¬ÙÙØ§ Ú©ÙØªØ±Ù Ù
+Û Ú©ÙÙØ¯ . Ø§ÙÙÛÙ Ú¯Ø²ÛÙÙ(ØªÙØ§ÙØª Ø­Ø§ÙØª Ø­Ø±ÙÙ) ØªØ¹ÛÛÙ Ù
+Û Ú©ÙØ¯ Ú©Ù
+Ú©ÙÚÚ© Ù ØšØ²Ø±Ú¯Û Ø­Ø±ÙÙ Ù
+Ø¯ ÙØžØ± ÙØ±Ø§Ø± Ú¯ÛØ±Ø¯ ÛØ§ Ø®ÛØ± . Ø¯ÙÙ
+ÛÙ Ú¯Ø²ÛÙÙ(Ø§ÙØªÙØ§Û Ú©ÙÙ
+Ø§Øª) ØªØ¹ÛÛÙ Ù
+Û Ú©ÙØ¯ Ú©Ù Ø§Ø² Ø§ÙØªÙØ§Û Ú©ÙÙ
+Ø§Øª
+ÚØŽÙ
+ ÙŸÙØŽÛ ØŽÙØ¯ ÛØ§ Ø®ÛØ± . Ù
+Ù
+Ú©Ù Ø§Ø³Øª Ø¬Ø¹ØšÙ ÙŸØ±Ø³ Ù Ø¬ÙÛ ØšØ²Ø±Ú¯Û ÙØ§Ø²Ù
+ Ø¯Ø§ØŽØªÙ ØšØ§ØŽØ¯ Ú©Ù ØšØªÙØ§ÙÛØ¯ Ø¬Ø³ØªØ¬ÙÛ Ù
+ØªÙÙ ÙŸØ§Ø±Ø§Ú¯Ø±Ø§ÙÛ
+Ø§ÙØ¬Ø§Ù
+ Ø¯ÙÛØ¯ . Ø¬Ø³ØªØ¬ÙÛ Ù
+ÙØ§Ø¯ÛØ± Ø²ÛØ§Ø¯Û Ù
+ØªÙ ØšØ³ÛØ§Ø± Ø³Ø±ÛØ¹ Ø§Ø³Øª .
+
+<p>ØšØ±Ø§Û Ù
+Ø«Ø§Ù Ø§Ú¯Ø±  <i>ÚØŽÙ
+ ÙŸÙØŽÛ Ø§Ø² Ø­Ø§ÙØª Ø­Ø±ÙÙ</i> Ù
+<i>ÚØŽÙ
+ ÙŸÙØŽÛ Ø§Ø² Ø§ÙØªÙØ§Û Ú©ÙÙ
+Ø§Øª</i> Ø§ÙØªØ®Ø§Øš ØŽØ¯Ù ØšØ§ØŽÙØ¯ , Ø¬Ø³ØªØ¬ÙÛ<p>
+    <ul><kbd>African building</kbd></ul>
+      <p>Ø¯Ø±Ø³Øª Ù
+Ø§ÙÙØ¯<p>
+      <ul><kbd>africa builds</kbd></ul> Ø®ÙØ§ÙØ¯ ØšÙØ¯<p>
+      Ø²ÛØ±Ø§ Ø­Ø±Ù ØšØ²Ø±Ú¯ "African" ØšÙ Ú©ÙÚÚ© ØªØšØ¯ÛÙ Ø®ÙØ§ÙØ¯ ØŽØ¯, 
+  Ù ÙŸØ³ÙÙØ¯  "n" Ù "ing" Ø­Ø°Ù Ø®ÙØ§ÙÙØ¯ ØŽØ¯
+      "African" Ù "building" ÙÙ
+ ØšÙ ÙÙ
+ÛÙ ØªØ±ØªÛØš (ÙÙ
+ÚÙÛÙ, "s" Ø§Ø²
+      "builds" Ø­Ø°Ù Ø®ÙØ§ÙØ¯ ØŽØ¯).
+
+<p>
+ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ ØšÙ Ø­Ø§ÙØª ÙŸØ±Ø³ Ù Ø¬ÙÛ ÙŸÛØŽØ±ÙØªÙ ØšØ±ÙÛØ¯ Ú©Ù Ø¯Ø± Ø¢Ù ÙØ§Ø¯Ø± Ø®ÙØ§ÙÛØ¯ ØšÙØ¯ Ø§Ø² Ø¹Ù
+ÙÚ¯Ø±ÛÙØ§Û Ù& ÛØ§ | Ù ÙÙ! 
+Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛØ¯ ØªØ§ ÙŸØ±Ø³ Ù Ø¬ÙÛÙØ§Û Ø¯ÙÛÙ ØªØ±Û Ø¯Ø§ØŽØªÙ ØšØ§ØŽÛØ¯ . ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ Ø³Ø§ØšÙÙ Ø¬Ø³ØªØ¬Ù Ø±Ø§ ÙØ¹Ø§Ù Ú©ÙÛØ¯ 
+ØªØ§ Ø¢Ø®Ø±ÛÙ Ø¬Ø³ØªØ¬ÙÙØ§Û Ø®ÙØ¯ Ø±Ø§ ØšØšÛÙÛØ¯ . ØšÙ Ø§ÛÙ Ø·Ø±ÛÙ Ù
+Û ØªÙØ§ÙÛØ¯ Ø¬Ø³ØªØ¬ÙÙØ§Û Ø®ÙØ¯ Ø±Ø§ Ø§ØµÙØ§Ø­ Ù Ù
+ÙØ±Ø¯ 
+Ø§Ø³ØªÙØ§Ø¯Ù Ù
+Ø¬Ø¯Ø¯ ÙØ±Ø§Ø± Ø¯ÙÛØ¯ . Ø¯Ø± Ø¢Ø®Ø± ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ ØªØ¹Ø¯Ø§Ø¯ ÙØªØ§ÛØ¬ ØšØ±Ú¯ØŽØªÛ Ù ØªØ¹Ø¯Ø§Ø¯ ÙÙ
+Ø§ÛØŽ ÙØŽØ§Ù Ø¯Ø§Ø¯Ù ØŽØ¯Ù Ø¯Ø± 
+ÙØ± ØµÙØ­Ù Ø±Ø§ Ù
+Ø¹ÛÙ Ú©ÙÛØ¯ .}
+
+_textcasefoldprefs_ [l=fa] {ÛÚ© Ø¬ÙØª Ø¯Ú©Ù
+Ù ØªØ·Ø§ØšÙ Ø­Ø±ÙÙ Ú©ÙÚÚ© Ù ØšØ²Ø±Ú¯ Ø±Ø§ Ø¯Ø± ÙÙÚ¯Ø§Ù
+ ÚØ³ØªÚÙ Ú©ÙØªØ±Ù Ù
+Û Ú©ÙÙØ¯. ØšØ±Ø§Û ÙÙ
+ÙÙÙ Ø Ø§Ú¯Ø± "_preferences:textignorecase_" Ø§ÙØªØ®Ø§Øš ØŽÙØ¯Ø <i>snail farming</i> Ø¯ÙÛÙØ§ ÙÙ
+Ø§ÙÙØ¯  <i>Snail Farming</i>  <i>SNAIL FARMING</i> ØªÙÙÛ Ù
+Û ØŽÙØ¯.}  
+_textstemprefs_ [l=fa] {ÛÚ© Ø¬ÙØª Ø§Ø² Ø¯Ú©Ù
+Ù ÙØ§ Ø¯Ø± ÙÙÚ¯Ø§Ù
+ Ø¬Ø³ØªØ¬Ù Ú©ÙØªØ±Ù Ù
+Û Ú©ÙÙØ¯ Ú©Ù Ø¢ÛØ§ Ø§ÙØªÙØ§Û Ú©ÙÙ
+Ø§Øª Ø¯Ø± ÙÙÚ¯Ø§Ù
+ Ø¬Ø³ØªØ¬Ù ØšÙ Ø­Ø³Ø§Øš ØšÛØ§ÛÙØ¯ ÛØ§ ÙÙØ ØšØ±Ø§Û ÙÙ
+ÙÙÙ Ø§Ú¯Ø± "_preferences:textstem_" Ø§ÙØªØ®Ø§Øš ØŽÙØ¯Ø <i>snail farming</i> ÙÙ
+Ø§ÙÙØ¯ <i>snails farm</i> Ù <i>snail farmer</i> ØšÙ Ø­Ø³Ø§Øš Ù
+Û Ø¢ÛØ¯. Ø§ÛÙ Ø§Ù
+Ú©Ø§Ù ÙØ¹ÙØ§ ØšØ±Ø§Û Ù
+ØªÙÙ ØšÙ Ø²ØšØ§Ù Ø§ÙÚ¯ÙÛØ³Û ØšÙ Ø¯Ø±Ø³ØªÛ Ú©Ø§Ø±Ø§ÛÛ Ø¯Ø§Ø±Ø¯._selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=fa] {ØªØ·Ø§ØšÙ Ø­Ø±ÙÙ ØšØ§ØµØ¯Ø§ Ù ØšÛ ØµØ¯Ø§ Ø¯Ø± ÙÙÚ¯Ø§Ù
+ Ø¬Ø³ØªØ¬Ù ØªÙØ³Ø· ÛÚ© Ø¬ÙØª Ø¯Ú©Ù
+Ù Ú©ÙØªØ±Ù Ù
+Û ØŽÙØ¯. ØšØ±Ø§Û ÙÙ
+ÙÙÙØ Ø§Ú¯Ø±"_preferences:textignoreaccents_" Ø§ÙØªØ®Ø§Øš ØŽÙØ¯Ø <i>fÃ©dÃ©ration</i> Ø¯ÙÛÙØ§ ÙÙ
+Ø§ÙÙØ¯ <i>fedÃ©ration</i> <i>federation</i> ØªÙÙÛ Ù
+Û ØŽÙØ¯.}  
+ 
+_textstemoptionsprefs_ [l=fa] {Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ø§Ù
+Ú©Ø§Ù Ú©ÙØªØ§Ù Ø³Ø§Ø²Û Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù ÙÙ
+Ø§ÙØ·ÙØ± Ú©Ù Ø¯Ø± ØšØ§ÙØ§ ØŽØ±Ø­ Ø¢Ù Ø¢Ù
+Ø¯"_texthelpquerytermstitle_" ØšØ§Ø¹Ø« Ø³ÙÙÙØª Ù ØšÙ ÙØ³ØšØª Ø¯ÙØª Ø¯Ø± Ø¬Ø³ØªØ¬Ù Ù
+Û ØŽÙØ¯.}  
+
+_textsearchtypeprefsplain_ [l=fa] {Ø§ÛÙ Ø§Ù
+Ú©Ø§Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ Ú©Ù ØŽÙ
+Ø§ Ø§Ú©Ø³ Ø¬Ø³ØªØ¬ÙÛ Ø·ÙÙØ§ÙÛ ØªØ±Û Ø±Ø§ ØšÙ Ø¯Ø³Øª ØšÛØ§ÙØ±ÛØ¯Ø Ø§Ø² Ø§ÛÙ Ø±Ù Ù
+Û ØªÙØ§ÙÛØ¯ ØšÙ Ø³ÙÙÙØª Ø¬Ø³ØªØ¬ÙÙØ§Û ÙŸØ§Ø±Ø§Ú¯Ø±Ø§ÙÛ ÙÛØ² Ø§ÙØ¬Ø§Ù
+ Ø¯ÙÛØ¯. Ø§ÛÙ Ø§Ù
+Ú©Ø§Ù Ø¯Ø± Ø¬Ø³ØªØ¬ÙÛ Ù
+ÙØ§Ø¯ÛØ± Ø²ÛØ§Ø¯ Ù
+ØªÙÛ ØšÙ Ù
+ÙÛØ¯ Ø§Ø³Øª.}  
+
+_textsearchtypeprefsform_ [l=fa] {ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ ØªØ¹Ø¯Ø§Ø¯ ÙÛÙØ¯ÙØ§ Ø±Ø§ Ø¯Ø± ÙØ±Ù
+ Ø¬Ø³ØªØ¬Ù ØªØºÛÛØ± Ø¯ÙÛØ¯}  
+
+_textsearchtypeprefsboth_ [l=fa] {Ø¯Ù ÙÙØ¹ ØŽÛÙÙ Ø¬Ø³ØªØ¬Ù Ø¯Ø± Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯Ø Ø¬Ø³ØªØ¬ÙÛ"Ù
+Ø¹Ù
+ÙÙÛ" Ù Ø¬Ø³ØªØ¬ÙÛ "Ù
+ØšØªÙÛ ØšØ± ÙÛÙØ¯".
+<ul>
+Ø¬Ø³Ø¬ÙÛ Ù
+Ø¹Ù
+ÙÙÛ  ÙÙØ· Ø§Ø² ÛÚ© ØšØ§Ú©Ø³ Ø¬ÙØª ÙØ±ÙØ¯ Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù ØšØ±Ø®ÙØ±Ø¯Ø§Ø± Ø§Ø³Øª._textsearchtypeprefsplain_ <li></li>
+<li>
+Ø¬Ø³ØªØ¬ÙÛ Ù
+ØšØªÛ ØšØ± ÙÛÙØ¯ ØªØ¹Ø¯Ø§Ø¯ ØšØ§Ú©Ø³ÙØ§Û ØšÛØŽØªØ±Û Ø¬ÙØª ÙØ±ÙØ¯ Ø¹ØšØ§Ø±Øª Ø¬Ø³ØªØ¬Ù ÙØ±Ø§ÙÙ
+ Ù
+Û Ú©ÙØ¯ Ú©Ù ÙØ± Ú©Ø¯Ø§Ù
+ Ø§Ø² Ø¢ÙÙØ§ ÙÛÙØ¯ Ù
+ØªÙØ§ÙØªÛ Ø±Ø§ Ø¬Ø³Ø¬ØªÙ Ù
+Û Ú©ÙØ¯. Ø§ÛÙ Ø§Ù
+Ø±Ø Ø§Ù
+Ú©Ø§Ù Ø¬Ø³ØªØ¬ÙÛ ÙÛÙØ¯ÙØ§Û Ù
+Ø®ØªÙÙÛ Ø±Ø§ ØšÙ ÛÚ©ØšØ§Ø±Ù ÙØ±Ø§ÙÙ
+ Ù
+ÛÚ©ÙØ¯.
+</ul>}  
+
+
+
+_texttanumbrowseoptions_ [l=fa] {ØšØ±Ø§Û ÛØ§ÙØªÙ Ø§Ø·ÙØ§Ø¹Ø§Øª Ø¯Ø± Ø§ÛÙ Ù
+Ø¬Ù
+ÙØ¹Ù _numbrowseoptions_ Ø±Ø§Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯ .}
+
+_textsimplehelpheading_ [l=fa] {ÚÚ¯ÙÙÙ Ø§Ø·ÙØ§Ø¹Ø§ØªÛ Ø¯Ø±Ù
+Ø¬Ù
+ÙØ¹Ù _collectionname_ ØšÛØ§ØšÛÙ
+}
+
+_texthelpscopetitle_ [l=fa] {Ù
+Ø­Ø¯ÙØ¯Ù ÙŸØ±Ø³ Ù Ø¬ÙÙØ§}
+_texthelpscope_ [l=fa] {<p>
+ Ø¯Ø± Ø§ØºÙØš Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ Ø§ÛÙØ¯Ú©Ø³ ÙØ§Û Ù
+Ø®ØªÙÙÛ Ø±Ø§ ØšØ±Ø§Û Ø¬Ø³ØªØ¬Ù Ø§ÙØªØ®Ø§Øš Ú©ÙÛØ¯ . ØšØ±Ø§Û Ù
+Ø«Ø§Ù
+Ø§ÛÙØ¯Ú©Ø³ ÙØ§Û ÙÙÛØ³ÙØ¯Ù ÛØ§ Ø¹ÙÙØ§Ù . ÛØ§ ØŽØ§ÛØ¯ ÙØµÙ Ù ÙŸØ§Ø±Ø§Ú¯Ø±Ø§Ù . Ù
+Ø¹Ù
+ÙÙØ§ 
+Ù
+ØªÙ Ú©Ø§Ù
+ÙØ§ Ù
+Ø·Ø§ØšÙ ØšØ¯ÙÙ ØªÙØ¬Ù ØšÙ Ø§ÛÙØ¯Ú©Ø³ Ù
+ÙØ±Ø¯ ÙØžØ± ØŽÙ
+Ø§ ØšÙ Ø¯Ø³Øª Ù
+Û Ø¢ÛØ¯ .
+<p>Ø§Ú¯Ø± Ø§Ø³ÙØ§Ø¯ Ú©ØªØ§Øš ØšØ§ØŽÙØ¯ Ø¯Ø± Ù
+Ø­Ù Ù
+ÙØ§Ø³Øš ØšØ§Ø² Ø®ÙØ§ÙÙØ¯ ØŽØ¯.}
Index: /gsdl/stable/macros/farsi2.dm
===================================================================
--- /gsdl/stable/macros/farsi2.dm	(revision 20131)
+++ /gsdl/stable/macros/farsi2.dm	(revision 20131)
@@ -0,0 +1,2121 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Language text and icon macros 
+# -- this file contains text that is of less importance
+######################################################################
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=fa] {Ù
+Ø¯Ø§Ø±Ú©}  
+_lastupdate_ [l=fa] {Ø¢Ø®Ø±ÙÙ Ø±ÙØ²Ø¢Ù
+Ø¯Ø³Ø§Ø²Ù}  
+_ago_ [l=fa] {Ø±ÙØ²ÙØ§Ù ÙŸÙØŽÙÙ}  
+_colnotbuilt_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù Ø³Ø§Ø®ØªÙ ÙØŽØ¯.}  
+
+### taken from here
+
+_textpoem_ [l=fa] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+<p>Ù
+Ù
+Ú©Ù Ø§Ø³Øª ØµÙØ­ Ù Ø¢Ø±Ø§Ù
+ØŽ ØŽÙ
+Ø§ Ø±Ø§ Ø§Ø­Ø§Ø·Ù Ú©ÙØ¯Ø
+<br> Ù
+Ù
+Ú©Ù Ø§Ø³Øª ØŽÙ
+Ø§ Ø¯Ø± Ø²ÛØ± Ú¯Ø±Ù
+Ø§Û Ù
+ÙØ§ÛÙ
+ ØªØ§ØšØ³ØªØ§Ù ØšÙ Ø³Ø± ØšØšØ±ÛØ¯Ø
+<p> Ù
+Ù
+Ú©Ù Ø§Ø³Øª Ø§ÙÛØ§ÙÙØ³ Ù
+Ø³ÛØ±ÙØ§ Ù Ø³ÙØ±ÙØ§Û ØŽÙ
+Ø§ ØšÙ Ø§ÙØ¯Ø§Ø²Ù Ø³ØªÙÙÙØ§Û Ø³ØšØ² ÙÛÙ
+ØªÛ Ù Ø¬ÙØ§Ø¯Ø§Ø¯Ù ØŽØ¯ÙØ ÙÙ
+ÙØ§Ø± ØšØ§ØŽØ¯.
+}  
+
+_textgreenstone_ [l=fa] {<p> 
+Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ø³ÙÚ¯Û ÙØ³ØšØªØ§ ÙÛÙ
+ØªÛ Ø§Ø³Øª (Ø¯Ø±Ø³Øª Ù
+Ø§ÙÙØ¯ Ø§ÛÙ ÙØ±Ù
+ Ø§ÙØ²Ø§Ø±) Ú©Ù ÙŸÛØŽÛÙÙ Ø¢Ù ØšÙ ÙÛÙØ²ÙÙØ¯ ØšØ± Ù
+Û Ú¯Ø±Ø¯Ø¯. Ø¯Ø± Ø¬Ø§Ù
+Ø¹Ù Ø³ÙØªÛ Ù
+Ø§ØŠÙØ±Û ØšØ³ÛØ§Ø± ØšØ§Ø§Ø±Ø²ØŽ ØšÙØ¯Ù Ù ØšØ¹Ø¯ Ø§Ø² ÙÙ
+Ù ÙØšÙ ÙØ§ Ø§Ø¹Ø·Ø§ Ù
+Û ØŽØ¯. Ø§ÛÙ Ø³ÙÚ¯ Ù
+Û ØªÙØ§ÙØ¯<i> ÙØ§ÛØ±ÙØ¢</i>   Ø±Ø§ Ø¬Ø°Øš Ù ÙÚ¯ÙØ¯Ø§Ø±Û Ú©ÙØ¯ Ú©Ù Ø±ÙØ­ ÛØ§ ÙÛØ±ÙÛ Ø²ÙØ¯Ú¯Û Ø§Ø³Øª Ù ØšØ§ ÙØ¶ÛÙØª ÙØ§Û Ø³ÙØªÛ ÙÛØ² ØªØ¯Ø¹Û Ù
+Û Ú©ÙØ¯ Ú©Ù Ø§ÛÙ ÙØ§ÚÙ Ø±Ø§ ØšØ±Ø§Û ÙŸØ±ÙÚÙ Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÛØ¬ÛØªØ§Ù ØšØ§ Ù
+ÙØ§ØµØ¯ Ø§Ø³ØªÙØ§Ø¯Ù Ø¹Ù
+ÙÙ
+Û ØªÙ
+Ø«ÛÙ Ù
+ÙØ§Ø³ØšÛ Ú©Ø±Ø¯Ù Ø§Ø³Øª. Ø¯Ø±Ø®ØŽØ§ÙÛ Ø¢Ù ÙÙ
+Ø§Ø¯ Ø®ÛØ±Ø®ÙØ§ÙÛØ ØŽÙØ§ÙÛØª Ø¢Ù ÙÙ
+Ø§Ø¯ Ø¯Ø±Ø³ØªÚ©Ø§Ø±ÛØ Ø§Ø³ØªØ­Ú©Ø§Ù
+ Ø¢Ù ÙÙ
+Ø§Ø¯ Ø¬Ø±Ø§Øª Ù ÙØšÙ ØªÛØ² Ø¢Ù ÙÙ
+Ø§Ø¯ Ø¹Ø¯Ø§ÙØª Ù
+Û ØšØ§ØŽØ¯. ÙØ·Ø¹Ù Ø­Ú© ØŽØ¯Ù Ø¢Ù Ø¯Ø± Ø¢Ø±Ù
+ ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÛØ¬ÛØªØ§Ù Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ ÛÚ©   
+ <i>ÙŸØ§ØªÙ</i>
+ÛØ§ Ú¯Ø±Ø² Ù
+ØšØ§Ø±Ø²Ù Ø§Ø³Øª
+Ú©Ù ÛØ§Ø¯Ú¯Ø§Ø± Ù
+ÙØ±ÙØ«Û ÛÚ©Û Ø§Ø² Ø§Ø¹Ø¶Ø§Û ÙŸØ±ÙÚÙ Ù
+Û ØšØ§ØŽØ¯. Ø¯Ø± Ù
+ØšØ§Ø±Ø²Ù Ø¯Ø³Øª ØšØ§ Ø¯Ø³Øª Ø§ÙØªÙØ§Ù Ø¢Ù ØšØ³ÛØ§Ø± Ø³Ø±ÛØ¹Ø Ø¯ÙÛÙ Ù ØšØ³ÛØ§Ø± Ú©Ø§Ù
+Ù Ù
+Û ØšØ§ØŽØ¯. Ù
+Ø§ ØšÙ Ø§ÛÙ ÙÚ©Ø± ÙØ³ØªÛÙ
+ Ú©Ù Ø§ÛÙ ÙÛÚÚ¯Û ÙØ§ Ø±Ø§ ØšØ±Ø§Û ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ø®ÙØ¯Ù
+Ø§Ù ÙŸÛØ§Ø¯Ù Ø³Ø§Ø²Û Ú©ÙÛÙ
+. ÙØšÙ ØªÛØ² 
+  <i>ÙŸØ§ØªÙ</i>
+  ÙÙ
+Ø§Ø¯ ÙØšÙ ØªÛØ² ÙÙØ§ÙØ±Û Ø§Ø³Øª. </p>}  
+
+_textaboutgreenstone_ [l=fa] {<p>Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ ØžØ±Ù ÙØ±Ù
+ Ø§ÙØ²Ø§Ø±Û ØšØ±Ø§Û Ø§ÛØ¬Ø§Ø¯ Ù ØªÙØ²ÛØ¹ Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Û Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÛØ¬ÛØªØ§Ù Ø§Ø³Øª. 
+Ø§ÛÙ ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± ØŽÛÙÙ Ø¬Ø¯ÛØ¯Û Ø±Ø§ ØšØ±Ø§Û Ø³Ø§Ø²Ù
+Ø§ÙØ¯ÙÛ Ø§Ø·ÙØ§Ø¹Ø§Øª Ù Ø§ÙØªØŽØ§Ø± Ø¢Ù Ø¯Ø± Ø§ÛÙØªØ±ÙØª ÛØ§ ÙÙØ­ 
+ÙØŽØ±Ø¯Ù ÙØ±Ø§ÙÙ
+ Ù
+Û Ø¢ÙØ±Ø¯. Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ ØªÙØ³Ø· ÙŸØ±ÙÚÙ Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÛØ¬ÛØªØ§Ù ÙÛÙØ²ÙÙØ¯ ØªÙÙÛØ¯ Ù
+Û 
+ØŽÙØ¯. </b> Ø¯Ø± <b>Ø¯Ø± Ø¯Ø§ÙØŽÚ¯Ø§Ù ÙØ§ÛÚ©Ø§ØªÙ </b>Ù ØšØ§ ÙÙ
+Ú©Ø§Ø±Û 
+<b>ÛÙÙØ³Ú©Ù</b> Ù  <b>Ø³Ø§Ø²Ù
+Ø§Ù ØºÛØ± Ø¯ÙÙØªÛ ÙÛÙÙ
+Ù Ø§ÛÙÙÙ</b> ØªÙØ³Ø¹Ù Ù ØªÙØ²ÛØ¹ Ù
+Û ØŽÙØ¯. Ø§ÛÙ ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± ÛÚ© ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ú©Ø¯ Ù
+ÙØšØ¹ ØšØ§Ø² Ø§Ø³Øª Ú©Ù Ø§Ø² Ø·Ø±ÛÙ <a
+href="http://greenstone.org">http://greenstone.org</a> Ù ØªØ­Øª Ù
+ÙØ±Ø±Ø§Øª Ú¯ÙØ§ÙÛ Ø¹Ù
+ÙÙ
+Û Ø¬Û Ø§ÙÙ ÛÙ ÙØ§ØšÙ Ø¯Ø³ØªØ±Ø³ Ù
+Û ØšØ§ØŽØ¯
+</p>
+
+<p>ÙØ¯Ù Ø§ÛÙ ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± ØªÙØ§ÙÙ
+ÙØ¯Ø³Ø§Ø²Û Ú©Ø§Ø±ØšØ±Ø§ÙØ ØšÙ ÙÛÚÙ Ø¯Ø± Ø¯Ø§ÙØŽÚ¯Ø§Ù ÙØ§Ø Ú©ØªØ§ØšØ®Ø§ÙÙ ÙØ§ Ù Ø³Ø§ÛØ± Ù
+ÙØ³Ø³Ø§Øª Ø®Ø¯Ù
+Ø§Øª Ø¹Ù
+ÙÙ
+Û Ø§Ø³Øª ØªØ§ ØšØªÙØ§ÙÙØ¯ Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÛØ¬ÛØªØ§Ù Ø®ÙØ¯ Ø±Ø§ Ø§ÛØ¬Ø§Ø¯ Ú©ÙÙØ¯. Ú©ØªØ§ØšØ®Ø§ÙÙ ÙØ§Û Ø¯ÛØ¬ÛØªØ§Ù ØšÙ ØµÙØ±Øª ØšÙÛØ§Ø¯Û ÙØ­ÙÙ Ø§ØŽØ§Ø¹Ù Ù Ú¯Ø±Ø¯Ø¢ÙØ±Û Ø§Ø·ÙØ§Ø¹Ø§Øª Ø¯Ø± Ù
+ÙØ³Ø³Ø§Øª Ù Ù
+Ø¬Ø§Ù
+Ø¹ ÙÙ
+Ú©Ø§Ø± ÛÙÙØ³Ú©Ù  Ø¯Ø± Ø²Ù
+ÛÙÙ ÙØ§Û Ø¢Ù
+ÙØ²ØŽØ Ø¹ÙÙ
+ Ù ÙØ±ÙÙÚ¯ Ø¯Ø± Ø³Ø±Ø§Ø³Ø± Ø¬ÙØ§Ù ØšÙ ÙÛÚÙ Ø¯Ø± Ú©ØŽÙØ±ÙØ§Û Ø¯Ø± Ø­Ø§Ù ØªÙØ³Ø¹Ù Ø±Ø§ Ø¯Ú¯Ø±Ú¯ÙÙ Ù
+Û Ú©ÙØ¯.Ø§Ù
+ÛØ¯ÙØ§Ø±ÛÙ
+ Ú©Ù Ø§Û ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ø§ÙÚ¯ÛØ²Ù Ø§Û ØšØ±Ø§Û ØšÙ Ú©Ø§Ø±Ú¯ÛØ±Û Ù
+ÙØ«Ø± Ú©ØªØ§ØšØ®Ø§ÙÙ ÙØ§Û Ø¯ÛØ¬ÛØªØ§Ù Ø¯Ø± Ø±Ø§Ø³ØªØ§Û ØšÙ Ø§ØŽØªØ±Ø§Ú© Ú¯Ø°Ø§Ø±Û Ø§Ø·ÙØ§Ø¹Ø§Øª Ù Ø¯Ø± Ø§Ø®ØªÛØ§Ø± Ú¯Ø°Ø§ØŽØªÙ Ø¢Ù ØšØ±Ø§Û Ø¹Ù
+ÙÙ
+ Ø§ÛØ¬Ø§Ø¯ Ú©ÙØ¯. 
+ </p>
+
+<p>Ø§ÛÙ ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ø¯Ø± ÙØ§ÙØš ÛÚ© ÙÙ
+Ú©Ø§Ø±Û ØšÛÙ Ø§ÙÙ
+ÙÙÛ ØªÙØ³Ø¹Ù ÛØ§ÙØª Ù ØªÙØ²ÛØ¹ ØŽØ¯ Ú©Ù Ø¯Ø± Ø¢Ú¯ÙØ³Øª Ø³Ø§Ù 2000 Ù
+ÛØ§Ù Ø³Ù ØšØ®ØŽ ØŽÚ©Ù Ú¯Ø±ÙØª 
+</p>
+
+<p>
+<a href="http://nzdl.org"><b>ÙŸØ±ÙÚÙ Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÛØ¬ÛØªØ§Ù ÙÛÙØ²ÙÙØ¯ Ø¯Ø± Ø¯Ø§ÙØŽÚ¯Ø§Ù ÙØ§ÛÚ©Ø§ØªÙ</b></a>
+
+</p>
+<p>
+Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ø§Ø² Ø¯Ù Ø§ÛÙ ÙŸØ±ÙÚÙ Ø±ØŽØ¯ Ú©Ø±Ø¯ Ù Ø§ÛÙ Ø§ÙØ¯Ø§Ù
+
+Ø§Ø² Ø³ÙÛ Ú©Ù
+ÛØ³ÛÙÙ ÙØ±Ø¹Û Ø§Ø±ØªØšØ§Ø·Ø§Øª Ú©Ù
+ÛØ³ÛÙ Ù
+ÙÛ ÛÙÙØ³Ú©ÙÛ ÙÛÙØ²ÙÙØ¯ Ù
+ÙØ±Ø¯ Ø­Ù
+Ø§ÛØª ÙØ±Ø§Ø± Ú¯Ø±ÙØª Ø
+<br>
+<a href="http://www.unesco.org"><img alt="Ø¢Ø±Ù
+ Ø³Ø§Ø²Ù
+Ø§Ù ÛÙÙØ³Ú©Ù" src="_httpimg_/unesco.gif"
+class="logo"></a>
+<a href="http://www.unesco.org"><b>Ø³Ø§Ø²Ù
+Ø§Ù Ø¢Ù
+ÙØ²ØŽÛØ Ø¹ÙÙ
+Û Ù ÙØ±ÙÙÚ¯Û Ù
+ÙÙ Ù
+ØªØ­Ø¯</b></a>
+<br>
+Ø§ØŽØ§Ø¹Ù Ø§Ø·ÙØ§Ø¹Ø§Øª Ø¢Ù
+ÙØ²ØŽÛØ Ø¹ÙÙ
+Û Ù ÙØ±ÙÙÚ¯Û Ø¯Ø± Ø³Ø±Ø§Ø³Ø± Ø¬ÙØ§Ù ØšÙ ÙÛÚÙ Ø¯Ø³ØªØ±Ø³ ÙŸØ°ÛØ±Û Ø¢Ù Ø¯Ø± Ú©ØŽÙØ±ÙØ§Û Ø¯Ø± Ø­Ø§Ù ØªÙØ³Ø¹ÙØ ÙØ¯Ù Ø§ØµÙÛ ÛÙÙØ³Ú©ÙØ³Øª Ú©Ù Ø¯Ø± ÙØ§ÙØš ØšØ±ÙØ§Ù
+Ù Ø§Ø·ÙØ§Ø¹Ø§Øª ØšØ±Ø§Û ÙÙ
+Ù ÙŸÛÚ¯ÛØ±Û Ù
+Û Ú©ÙØ¯Ø Ù ÙÙØ§ÙØ±Û Ø§Ø·ÙØ§Ø¹Ø§Øª Ù Ø§Ø±ØªØšØ§Ø·Ø§Øª Ù
+ÙØ§Ø³Øš Ù Ø¯Ø³ØªØ±Ø³ ÙŸØ°ÛØ± Ø¯Ø±Ø§ÛÙ Ø²Ù
+ÛÙÙ ØšÙ Ø¹ÙÙØ§Ù Ø§ØšØ²Ø§Ø± Ù
+ÙÙ
+ Ø¯Ø± ÙØžØ± Ú¯Ø±ÙØªÙ Ù
+Û ØŽÙØ¯.
+  </p>
+
+<p>
+<a href="http://humaninfo.org"><img alt="Ø¢Ø±Ù
+ ÙÛÙÙ
+Ù Ø§ÛÙÙÙ" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>ÙÛÙÙ
+Ù Ø§ÛÙÙÙØ Ù
+Ø³ØªÙØ± Ø¯Ø± Ø¢ÙØªÙØ±ÙŸ ØšÙÚÛÚ©</b></a>
+<br>
+Ø§ÛÙ ÙŸØ±ÙÚÙ ØšØ§ ÙÙ
+Ú©Ø§Ø±Û Ø¢Ø²Ø§ÙØ³ ÙØ§Û Ø³Ø§Ø²Ù
+Ø§Ù Ù
+ÙÙ Ù Ø³Ø§ÛØ± Ø³Ø§Ø²Ù
+Ø§Ù ÙØ§Û ØºÛØ± Ø¯ÙÙØªÛ ØªØ¯Ø§ÙÙ
+ Ù
+Û ÛØ§ØšØ¯Ø Ù  Ø¯Ø± Ø²Ù
+ÛÙÙ Ø¯ÛØ¬ÛØªØ§Ù Ø³Ø§Ø²Û Ù
+Ø¯Ø§Ø±Ú© Ù
+Ø±ØªØšØ· ØšØ§ ØªÙØ³Ø¹Ù Ø§ÙØ³Ø§ÙÛ Ù Ø¯Ø³ØªØ±Ø³ ÙŸØ°ÛØ± Ø³Ø§Ø®ØªÙ Ø¢Ù Ø¯Ø± Ø³Ø·Ø­ Ú¯Ø³ØªØ±Ø¯ÙØ ØšØ¯ÙÙ ÙØ²ÛÙÙ ØšØ±Ø§Û Ú©ØŽÙØ±ÙØ§Û Ø¯Ø± Ø­Ø§Ù ØªÙØ³Ø¹Ù Ù ØµØ±ÙØ§ ØªØ§Ù
+ÛÙ ÙØ²ÛÙÙ ÙØ§ ØšØ±Ø§Û Ø³Ø§ÛØ±ÛÙ Ø¢ÙØ§Ø²Ù Ø¬ÙØ§ÙÛ Ú©Ø³Øš Ú©Ø±Ø¯Ù Ø§Ø³Øª  
+ </p>}  
+
+
+_textdescrselcol_ [l=fa] {Ø§ÙØªØ®Ø§Øš ÛÚ© Ù
+Ø¬Ù
+ÙØ¹Ù}  
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=fa] {Ø¯Ø± ØµÙØ­Ù Ø§ØµÙÙ ÚÙØ§Ø± Ø¯ÙÙ
+Ù ØšÙØŽØªØ± ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯}  
+
+_textnocollections_ [l=fa] {<p>Ø¯Ø± Ø­Ø§Ù Ø­Ø§Ø¶Ø± ØšØ±Ø§Û Ø§ÛÙ ÙØµØš Ø§Ø² Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ ÙÛÚ Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Û Ø¯Ø± Ø¯Ø³ØªØ±Ø³ ÙÙ
+Û ØšØ§ØŽØ¯. ØšØ±Ø§Û 
+Ø§ÙØ²ÙØ¯Ù Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+Û ØªÙØ§ÙÛØ¯ ÛÚ©Û Ø§Ø² Ø±ÙØŽ ÙØ§Û Ø²ÛØ± Ø±Ø§ ØšØ±Ú¯Ø²ÛÙÛØ¯<ul><li>Ø§Ø² <a href="_httppagecollector_">Ù
+Ø¬Ù
+ÙØ¹Ù Ø³Ø§Ø²</a> ØšØ±Ø§Û Ø§ÛØ¬Ø§Ø¯ 
+Ù
+Ø¬Ù
+ÙØ¹Ù Ø¬Ø¯ÛØ¯ Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛØ¯<li>ÚÙØ§ÙÚÙ ÙÙØ­ ÙØŽØ±Ø¯Ù Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ø±Ø§ Ø¯Ø§ØŽØªÙ ØšØ§ØŽÛØ¯ Ù
+Û 
+ØªÙØ§ÙÛØ¯ Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ Ø±Ø§ Ø§Ø² ÙÙØ­ ÙØŽØ±Ø¯Ù ÙØµØš Ú©ÙÛØ¯</ul>}  
+
+_text1coll_ [l=fa] {Ø§ÙÙ ÙØµØš Ø§Ø² Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ØŽØ§Ù
+Ù -1- Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+Ù Ú¯Ø±Ø¯Ø¯}  
+
+_textmorecolls_ [l=fa] {Ø§ÙÙ ÙØµØš Ø§Ø² Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ØŽØ§Ù
+Ù -1- Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+Ù Ú¯Ø±Ø¯Ø¯}  
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=fa] {ÙÙÙÙ Ø®Ø§Ø±Ø¬Ù}  
+_textlinknotfound_ [l=fa] {ÙÙÙÙ Ø¯Ø§Ø®ÙÙ ÙØ§ÙØª ÙØŽØ¯}  
+
+_textextlinkcontent_ [l=fa] {ÙÙÙÙÙ ÙÙ ØŽÙ
+Ø§ Ø§ÙØªØ®Ø§Øš ÙÙ
+ÙØ¯Ù Ø§ÙØ¯ ØšØ±Ø§Ù ÙØ± ÙØ¯Ø§Ù
+ Ø§Ø² Ù
+Ø¬ÙØ¹Ù ÙØ§Ù Ø§ÙØªØ®Ø§Øš ØŽØ¯Ù Ø¬Ø§Ø±Ù Ø®Ø§Ø±Ø¬Ù Ø§Ø³Øª.
+Ø§Ú¯Ø± ØŽÙ
+Ø§ ØšÙ Ø§ÙÙØªØ±ÙØª Ø¯Ø³ØªØ±Ø³Ù Ø¯Ø§Ø±ÙØ¯ Ù ÙÙÙØ² Ù
+Ù Ø®ÙØ§ÙÙØ¯ Ø§ÙÙ ÙÙÙÙ Ø±Ø§ Ù
+ØŽØ§ÙØ¯Ù ÙÙÙØ¯Ø Ù
+Ù ØªÙØ§ÙÙØ¯ ØšÙ Ø§ÙÙ ØµÙØ­Ù ÙÙÙÙ
+Ø¯ÙÙØ¯<a href="_nexturl_">go forward</a>Ø Ø¯Ø± ØºÙØ± Ø§ÙÙ ØµÙØ±Øª Ø¬ÙØª ØšØ§Ø²Ú¯ØŽØª ØšÙ Ø³ÙØ¯ ÙØšÙÙ Ø§Ø² Ø¯ÙÙ
+Ù "back" Ù
+Ø±ÙØ±Ú¯Ø± Ø®ÙØ¯ Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ÙÙØ¯.}  
+
+_textlinknotfoundcontent_ [l=fa] {ØšÙ Ø¯ÙØ§ÙÙÙ Ø®Ø§Ø±Ø¬ Ø§Ø² ÙÙØªØ±Ù Ù
+Ø§Ø ÙÙÙÙ Ø¯Ø§Ø®ÙÙ ÙÙ ØŽÙ
+Ø§ Ø§ÙØªØ®Ø§Øš ÙÙ
+ÙØ¯Ù Ø§ÙØ¯ Ù
+ÙØ¬ÙØ¯ ÙÙØ³Øª. Ø§ÙÙ 
+Ù
+Ù
+ÙÙ Ø§Ø³Øª ØšÙ Ø®Ø§Ø·Ø± ÙØ¬ÙØ¯ Ø®Ø·Ø§ Ø¯Ø± Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+ÙØšØ¹ ØšØ§ØŽØ¯. Ø¬ÙØª ØšØ§Ø²Ú¯ØŽØª ØšÙ Ø³ÙØ¯ 
+ÙØšÙÙ Ø¯ÙÙ
+Ù "back" Ø§Ø³ØªÙØ§Ø¯Ù ÙÙÙØ¯.}  
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=fa] {<h3>ÙŸÛÙÙØ¯ ØšÙ Ù
+Ø¬Ù
+ÙØ¹Ù "_2_" </h3>
+
+<p> ÙŸÛÙÙØ¯Û Ú©Ù ØŽÙ
+Ø§ Ø§ÙØªØ®Ø§Øš Ú©Ø±Ø¯Ù Ø§ÛØ¯ ØšØ±Ø§Û Ù
+Ø¬Ù
+ÙØ¹Ù "_collectionname_" ÙŸÛÙÙØ¯ 
+Ø®Ø§Ø±Ø¬Û Ø§Ø³Øª (ØšÙ Ù
+Ø¬Ù
+ÙØ¹Ù "_2_" ÙŸÛÙÙØ¯ Ù
+Û Ø¯ÙØ¯). ÚÙØ§ÙÚÙ Ù
+Û Ø®ÙØ§ÙÛØ¯ ØªØ§ Ø§ÛÙ ÙŸÛÙÙØ¯ Ø±Ø§ 
+Ø¯Ø± Ù
+Ø¬Ù
+ÙØ¹Ù "_2_" ØšØšÛÙÛØ¯ Ù
+Û ØªÙØ§ÙÛØ¯
+<a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">ØšÙ Ø§ÛÙ ØµÙØ­Ù</a> ØšØ±ÙÛØ¯Ø Ø¯Ø± ØºÛØ± 
+Ø§ÛÙØµÙØ±Øª ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ø¯Ú©Ù
+Ù Back Ù
+Ø±ÙØ±Ú¯Ø± Ø®ÙØ¯ ØšÙ 
+Ù
+Ø¬Ù
+ÙØ¹Ù "_2_" ÙŸÛØŽÛÙ ØšØ±Ú¯Ø±Ø¯ÛØ¯}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=fa] {ÙØªØ§ØšØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}  
+
+_textusername_ [l=fa] {ÙØ§Ù
+ ÙØ§Ø±ØšØ±Ù}  
+_textpassword_ [l=fa] {Ø±Ù
+Ø² Ø¹ØšÙØ±}  
+
+_textmustbelongtogroup_ [l=fa] {ØªÙØ¬Ù Ø¯Ø§ØŽØªÙ ØšØ§ØŽÙØ¯ ÙÙ ØŽÙ
+Ø§ Ø¬ÙØª Ø¯Ø³ØªØ±Ø³Ù ØšÙ Ø§ÙÙ ØµÙØ­Ù ØšØ§ÙØ¯ Ø¬Ø²Ù Ú¯Ø±ÙÙ "cgiargug-"ØšØ§ØŽÙØ¯}  
+
+_textmessageinvalid_ [l=fa] {ØµÙØ­Ù Ø§Ù ÙÙ ØŽÙ
+Ø§ Ø¯Ø±Ø®ÙØ§Ø³Øª ÙØ±Ø¯Ù Ø§ÙØ¯ ÙÙØ§Ø² ØšÙ sign in Ø¯Ø§Ø±Ø¯. <br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)
+ÙØ·ÙØ§ ÙØ§Ù
+ Ú©Ø§Ø±ØšØ±Û Ù Ø±Ù
+Ø² Ø¹ØšÙØ± Ø±Ø§ ÙØ§Ø±Ø¯ ÙÙ
+Ø§ÛÛØ¯.}  
+
+_textmessagefailed_ [l=fa] {ÙØ§Ù
+ ÙØ§Ø±ØšØ±Ù ÙØ§ Ø±Ù
+Ø² Ø¹ØšÙØ± ØŽÙ
+Ø§ ÙØ§Ø¯Ø±Ø³Øª ØšÙØ¯.}  
+
+_textmessagedisabled_ [l=fa] {ØšØšØšØ®ØŽÙØ¯Ø Ø­Ø³Ø§Øš ØŽÙ
+Ø§ ØºÙØ±ÙØ¹Ø§Ù ØŽØ¯Ù Ø§Ø³Øª. ÙØ·ÙØ§ ØšØ§ ÙØš Ù
+Ø³ØªØ± Ø§ÙÙ Ø³Ø§ÙØª ØªÙ
+Ø§Ø³ ØšÚ¯ÙØ±ÙØ¯.}  
+
+_textmessagepermissiondenied_ [l=fa] {Ù
+ØªØ§Ø³ÙØ§ÙÙ ØŽÙ
+Ø§ Ø§Ø² Ø§Ø®ØªÙØ§Ø± ÙØ§ÙÙ Ø¬ÙØª Ø¯Ø³ØªØ±Ø³Ù ØšÙ Ø§ÙÙ ØµÙØ­Ù ØšØ±Ø®ÙØ±Ø¯Ø§Ø± ÙÙØ³ØªÙØ¯.}  
+
+_textmessagestalekey_ [l=fa] {ÙÛÙÚ© Ù
+ÙØ±Ø¯ ÙØžØ± ØŽÙ
+Ø§ ØšÙ ÙØ­Ø§Øž Ø²Ù
+Ø§ÙÛ Ø§Ø² Ø§Ø¹ØªØšØ§Ø± Ø³Ø§ÙØ· Ø§Ø³Øª. ÙØ·ÙØ§ Ø¬ÙØª Ø¯Ø³ØªØ±Ø³Ù ØšÙ Ø§ÙÙ ØµÙØ­Ù Ø±Ù
+Ø² Ø¹ØšÙØ± Ø®ÙØ¯ Ø±Ø§ ÙØ§Ø±Ø¯ ÙÙÙØ¯.}  
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=fa] {<p>ÙØ³Ø®Ù ÙØµØš ØŽØ¯Ù ÙØ¹ÙÛ ÙÛÚ Ù
+Ø³ØªÙØ¯Ø§ØªÛ Ø±Ø§ Ø¯Ø± ØšØ±ÙÙ
+Û Ú¯ÛØ±Ø¯. Ø§ÛÙ Ø§Ù
+Ø± Ù
+Ù
+Ú©Ù  Ø§Ø³Øª ÙØ§ØŽÙ Ø§Ø²  
+Ø¯ÙØ§ÛÙ Ø²ÛØ± ØšØ§ØŽØ¯:
+<ol>
+ <li>Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ø§Ø² Ø·Ø±ÛÙ ÙÙØ¬ ÙØŽØ±Ø¯Ù Ù ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² ÙØµØš ÙØŽØ±Ø¯Ù ÙØµØš ØŽØ¯Ù Ø§Ø³Øª.
+ <li>Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ø§Ø² Ø·Ø±ÛÙ ÛÚ©Û Ø§Ø² ÙØ³Ø®Ù ÙØ§Û Ø§ÛÙØªØ±ÙØª Ø¯Ø§ÙÙÙØ¯ ØŽØ¯Ù Ø§Ø³Øª.</ol>
+Ø¯Ø± ÙØ± ØµÙØ±Øª Ù
+Û ØªÙØ§ÙÛØ¯ Ù
+Ø³ØªÙØ¯Ø§Øª Ø¢Ù Ø±Ø§ Ø§Ø² Ø·Ø±ÛÙ Ø¯Ø§ÛØ±Ú©ØªÙØ±Û docs 
+ÙÙØ­ ÙØŽØ±Ø¯Ù ÛØ§ Ø§Ø² Ø·Ø±ÛÙ Ù
+Ø±Ø§Ø¬Ø¹Ù ØšÙ ÙØš Ø³Ø§ÛØª <a
+href="http://www.greenstone.org">http://www.greenstone.org</a> ØšÙ Ø¯Ø³Øª 
+ØšÛØ§ÙØ±ÛØ¯. </body>}  
+
+_textuserguide_ [l=fa] {Ø±Ø§ÙÙÙ
+Ø§Ù Ø§Ø³ØªÙØ§Ø¯Ù ÙÙÙØ¯Ù}  
+_textinstallerguide_ [l=fa] {Ø±Ø§ÙÙÙ
+Ø§Ù ÙØµØš ÙÙÙØ¯Ù}  
+_textdeveloperguide_ [l=fa] {Ø±Ø§ÙÙÙ
+Ø§Ù Ù
+Ø±ØšÙØ· ØšÙ ØªÙØ³Ø¹Ù Ø¯ÙÙØ¯Ù ÙØ§}  
+_textpaperguide_ [l=fa] {Ø§Ø² Ù
+ÙØ§ÙÙ ØšÙ Ù
+Ø¬Ù
+ÙØ¹Ù}  
+_textorganizerguide_ [l=fa] {Ø¯Ø± Ø­Ø§Ù Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ø³Ø§Ø²Ù
+Ø§Ù Ø¯ÙÙØ¯Ù}  
+
+_textgsdocstitle_ [l=fa] {Ù
+Ø³ØªÙØ¯ Ø³Ø§Ø²Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}  
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=fa] {Ø³Ø§Ø®ØªÙ Ù
+Ø¬Ù
+ÙØ¹Ù}  
+_textbildsuc_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù ØšØ§ Ù
+ÙÙÙÙØª Ø³Ø§Ø®ØªÙ ØŽØ¯.}  
+_textviewbildsummary_ [l=fa] {"Ø¬ÙØª Ù
+ØŽØ§ÙØ¯Ù Ø¬Ø²ØŠÙØ§Øª ØšÙØŽØªØ± ØšÙ Ø§ÙÙ Ø¢Ø¯Ø±Ø³ Ù
+Ø±Ø§Ø¬Ø¹Ù ÙÙÙØ¯<a href="_httppagex_(bsummary)" target=_top>view the build
+summary</a>"}  
+_textview_ [l=fa] {Ù
+ØŽØ§ÙØ¯Ù Ù
+Ø¬Ù
+ÙØ¹Ù}  
+
+_textbild1_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù Ø¯Ø± Ø­Ø§Ù Ø³Ø§Ø®ØªÙ ØŽØ¯Ù Ø§Ø³Øª: Ø§ÙÙ Ù
+Ù
+ÙÙ Ø§Ø³Øª ÚÙØ¯ ÙØ­ØžÙ Ø·ÙÙ ØšÙØŽØ¯. ÙÙØ§Ø± ÙØ¶Ø¹ÙØª Ø³Ø§Ø®ØªÙ Ø¯Ø± ÙŸØ§ÛÛÙ ØšØ§Ø®ÙØ±Ø¯
+ÚÚ¯ÙÙÚ¯Ù ÙØ±Ø§ÙÙØ¯ Ø³Ø§Ø®ØªÙ Ø±Ø§ ÙØŽØ§Ù Ù
+Ù Ø¯ÙØ¯.}  
+
+_textbild2_ [l=fa] {ØšØ±Ø§Û ØªÙÙÙ ÙØ±Ø§ÙÙØ¯ Ø³Ø§Ø®ØªÙ Ø§ÙÙØ¬Ø§ Ø±Ø§ ÙÙÙÙ ÙÙÙØ¯. <br> Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Ù ÙÙ ØŽÙ
+Ø§ Ø±ÙÙ Ø¢Ù ÙØ§Ø± Ù
+Ù ÙÙÙØ¯
+Ø¯Ø³Øª ÙØ®ÙØ¯Ù ØšØ§ÙÙ Ø®ÙØ§ÙØ¯ Ù
+Ø§ÙØ¯.}
+
+_textstopbuild_ [l=fa] {ØªÙÙÙ ÙØ±Ø§ÙÙØ¯ Ø³Ø§Ø®ØªÙ}  
+
+_textbild3_ [l=fa] {Ø§Ú¯Ø± ØŽÙ
+Ø§ Ø§ÙÙ ØµÙØ­Ù Ø±Ø§ Ø±ÙØ§ ÙÙÙØ¯( Ù ØšØ§ Ø¯ÙÙ
+Ù "ØªÙÙÙ Ø³Ø§Ø®ØªÙ" Ø¢Ù Ø±Ø§ Ù
+ØªÙÙÙ ÙÙÙÙØ¯) Ø³Ø§Ø®ØªÙ Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Ø¯Ø§Ù
+Ù
+Ø®ÙØ§ÙØ¯ ÛØ§ÙØª Ù ÙŸØ³ Ø§Ø² ØªÚ©Ù
+ÛÙ Ù
+ÙÙÙÛØª Ø¢Ù
+ÛØ²Ø ÙØµØš Ø®ÙØ§ÙØ¯ ØŽØ¯.}  
+
+_textbuildcancelled_ [l=fa] {Ø³Ø§Ø®ØªÙ ÙØºÙ ØŽØ¯}  
+
+_textbildcancel1_ [l=fa] {ÙØ±Ø§ÙÙØ¯ Ø³Ø§Ø®ØªÙ Ù
+Ø¬Ù
+ÙØ¹Ù ÙØºÙ ØŽØ¯. Ø¬ÙØª Ø§Ø¹Ù
+Ø§Ù ØªØºÙÙØ±Ø§Øª Ù Ø±Ø§Ù Ø§ÙØ¯Ø§Ø²Ù Ù
+Ø¬Ø¯Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ù Ø¯ÙÙ
+Ù Ø²Ø±Ø¯ Ø±Ø§ ÙÙÙÙ ÙÙÙØ¯.}  
+
+_textbsupdate1_ [l=fa] {ÙØ¶Ø¹ÙØª Ø³Ø§Ø®ØªÙ Ø¯Ø± 1 Ø«Ø§ÙÙÙ Ø±ÙØ²Ø¢Ù
+Ø¯ ØŽØ¯}  
+_textbsupdate2_ [l=fa] {Ø±ÙØ²Ø¢Ù
+Ø¯Ø³Ø§Ø®ØªÙ ÙØ¶Ø¹ÙØª Ø³Ø§Ø®ØªÙ}  
+_textseconds_ [l=fa] {Ø«Ø§ÙÙÙ ÙØ§}  
+
+_textfailmsg11_ [l=fa] {The collection could not be built as it contains no data. Make sure that at
+least one of the directories or files you specified on the <i>source
+data</i> page exists and is of a type or (in the case of a directory)
+contains files of a type, that Greenstone can process.
+"
+	"Ø¯Ø± ØµÙØ±ØªÛ Ú©Ù ÙÛÚ Ø¯Ø§Ø¯Ù Ø§Û ÙØ¬ÙØ¯ ÙØ¯Ø§ØŽØªÙ ØšØ§ØŽØ¯ Ù
+Ø¬Ù
+ÙØ¹Ù Ø§ÛØ¬Ø§Ø¯ ÙÙ
+Û ØŽÙØ¯. Ø§Ø·Ù
+ÛÙØ§Ù Ú©Ø³Øš Ú©ÙÛØ¯ Ú©Ù Ø­Ø¯Ø§ÙÙ ÛÚ©Û Ø§Ø² Ø¯Ø§ÛØ±Ú©ØªÙØ±Û ÙØ§ ÛØ§ ÙØ§ÛÙ ÙØ§ÛÛ Ú©Ù ØšÙ Ø¹ÙÙØ§Ù <i>Ø¯Ø§Ø¯Ù Ù
+ÙØšØ¹</i> Ù
+ØŽØ®Øµ Ú©Ø±Ø¯Ù Ø§ÛØ¯Ø Ù
+ÙØ¬ÙØ¯ ØšÙØ¯Ù Ù Ø§Ø² ÙÙØ¹ ÙØ§ÛÙ ÙØ§ÛÛ Ø§Ø³Øª Ú©Ù Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ù
+Û ØªÙØ§ÙØ¯ ÙŸØ±Ø¯Ø§Ø²ØŽ Ú©ÙØ¯.}  
+
+_textfailmsg21_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù ÙÙ
+Ù ØªÙØ§ÙØ¯ Ø§ÙØ¬Ø§Ø¯ Ú¯Ø±Ø¯Ø¯ ( import.pl Ø§ÙØ¬Ø§Ù
+ ÙØŽØ¯).}  
+_textfailmsg31_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù ÙÙ
+Ù ØªÙØ§ÙØ¯ Ø§ÙØ¬Ø§Ø¯ Ú¯Ø±Ø¯Ø¯ (buildcol.pl Ø§ÙØ¬Ø§Ù
+ ÙØŽØ¯).}  
+_textfailmsg41_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù ØšØ§ Ù
+ÙÙÙÙØª Ø§ÙØ¬Ø§Ø¯ ØŽØ¯ Ø§Ù
+Ø§ ÙÙ
+Ù ØªÙØ§ÙØ¯ ÙØµØš Ú¯Ø±Ø¯Ø¯.}  
+_textfailmsg71_ [l=fa] {Ø®Ø·Ø§Ù ÙŸÙØŽ ØšÙÙÙ ÙØŽØ¯Ù Ø§Ù Ø¯Ø± Ø­ÙÙ ØªÙØ§ØŽ Ø¬ÙØª Ø³Ø§Ø®ØªÙ Ù
+Ø¬Ù
+ÙØ¹Ù Ø±Ø® Ø¯Ø§Ø¯.}  
+
+
+_textblcont_ [l=fa] {Ø«ØšØª ÙÙØ§ÙØ¹ Ø³Ø§Ø®ØªÙ ØŽØ§Ù
+Ù Ø§Ø·ÙØ§Ø¹Ø§Øª Ø²ÙØ± Ø§Ø³Øª:}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=fa] {Ø³Ø§Ø®ØªØ§Ø± ÙŸÙØŽ ÙØ±Ø¶}  
+_textmore_ [l=fa] {ØšÙØŽØªØ±}  
+_textinfo_ [l=fa] {Ø§Ø·ÙØ§Ø¹Ø§Øª Ù
+Ø¬Ù
+ÙØ¹Ù}  
+_textsrce_ [l=fa] {Ø¯Ø§Ø¯Ù ÙØ§Ù Ù
+ÙØšØ¹}  
+_textconf_ [l=fa] {ÙŸÛÚ©Ø± ØšÙØ¯Û Ù
+Ø¬Ù
+ÙØ¹Ù}  
+_textdel_ [l=fa] {Ø­Ø°Ù ÙØ±Ø¯Ù Ù
+Ø¬Ù
+ÙØ¹Ù}  
+_textexpt_ [l=fa] {ØµØ¯ÙØ± Ù
+Ø¬Ù
+ÙØ¹Ù}  
+
+_textdownloadingfiles_ [l=fa] {Ø¯Ø± Ø­Ø§Ù Ø¯Ø§ÙÙÙØ¯ ÙÙ
+ÙØ¯Ù ÙØ§ÙÙ...}  
+_textimportingcollection_ [l=fa] {Ø¯Ø± Ø­Ø§Ù ÙØ§Ø±Ø¯ ÙÙ
+ÙØ¯Ù Ù
+Ø¬Ù
+ÙØ¹Ù...}  
+_textbuildingcollection_ [l=fa] {... Ø¯Ø± Ø­Ø§Ù Ø³Ø§Ø®ØªÙ Ù
+Ø¬Ù
+ÙØ¹Ù}  
+_textcreatingcollection_ [l=fa] {Ø¯Ø± Ø­Ø§Ù Ø§ÙØ¬Ø§Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ù ...}  
+
+_textcollectorblurb_ [l=fa] {<i> Ù
+Ø·Ù
+ØŠÙ ÙØ³ØªÛÙ
+ Ú©Ù Ù
+ØšØ§Ø±Ø²Ù ØšØ§ ÙÙÙ
+ Ú©Ø§Ø±Ø¢Ù
+Ø¯ØªØ± Ø§Ø² Ù
+ØšØ§Ø±Ø²Ù ØšØ§ ØŽÙ
+ØŽÛØ± Ø§Ø³Øª!
+<br>Ø³Ø§Ø®ØªÙ Ù ØªÙØ²ÙØ¹ ÙØ±Ø¯Ù Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Ù Ø§Ø·ÙØ§Ø¹Ø§ØªÙ Ù
+Ø³ØŠÙÙÙØªÙØ§ÙÙ Ø¯Ø± ØšØ±Ø¯Ø§Ø±Ø¯ ÙÙ
+ØŽÙ
+Ø§ Ù
+Ù
+ÙÙ Ø§Ø³Øª ÙØšÙ Ø§Ø² ØŽØ±ÙØ¹ ØšØ®ÙØ§ÙÙØ¯ Ù
+ÙØ¹ÙØ³ ÙÙÙØ¯.
+Ø§Ø² ÙØ­Ø§Øž ÙØ§ÙÙÙÙ ÙŸÙ Ø¢Ù
+Ø¯ÙØ§ÙÙ ÙØ§ÙÙÙÙ ÙØ§ØŽÙ Ø§Ø² ÙÙŸÙ Ø±Ø§ÙØª ÙØ¬ÙØ¯ Ø¯Ø§Ø±ÙØ¯
+ØšÙ Ø¹ÙÙØ§Ù Ù
+Ø«Ø§Ù Ø¯Ø³ØªØ±Ø³Ù ØšÙ Ø§Ø³ÙØ§Ø¯ ØšÙ Ø§ÙÙ Ù
+ÙÙÙÙ
+ ÙÙØ³Øª ÙÙ Ø§ÙØ²Ø§Ù
+Ø§ ØšØªÙØ§ÙÙØ¯ 
+Ø¢ÙÙØ§ Ø±Ø§ Ø¯Ø± Ø§Ø®ØªÙØ§Ø± Ø¯ÙÚ¯Ø±Ø§Ù ÙØ±Ø§Ø± Ø¯ÙÙØ¯.
+<br> ÙØ¯Ø±Øª Ø§Ø·ÙØ§Ø¹Ø§Øª Ø±Ø§ ØºÙÛÙ
+Øª ØšØŽÙ
+Ø§Ø±ÛØ¯ Ù Ø¢Ù Ø±Ø§ Ø®Ø±Ø¯Ù
+ÙØ¯Ø§ÙÙ ØšÙ Ú©Ø§Ø± ØšØšØ±ÛØ¯.
+</i>}  
+
+_textcb1_ [l=fa] {Ú¯Ø±Ø¯Ø¢ÙØ±ÙØ¯Ù Ø¯Ø± Ø§ÛØ¬Ø§Ø¯ Ø ØªØºÙÛØ± Ø Ø§Ø¶Ø§ÙÙ ÙÙ
+ÙØ¯Ù ÙØ§ Ø­Ø°Ù Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Ù Ø¬Ø¯ÙØ¯ ØšÙ ØŽÙ
+Ø§ ÙÙ
+Ù Ù
+Ù ÙÙØ¯.
+Ø¬ÙØª Ø§ÙØ¬Ø§Ù
+ Ø§ÙÙ Ø§Ù
+Ø± ØŽÙ
+Ø§ Ø§Ø² Ø·Ø±ÙÙ ÙÙ Ø³Ø±Ù ØµÙØ­Ø§Øª ÙØš ÙÙ Ø§Ø·ÙØ§Ø¹Ø§Øª Ù
+ÙØ±Ø¯ 
+ÙÙØ§Ø² Ø±Ø§ Ø¯Ø± Ø®ÙØ§Ø³Øª Ù
+Ù ÙÙØ¯Ø Ø±Ø§ÙÙÙ
+Ø§ÙÙ Ø®ÙØ§ÙÙØ¯ ØŽØ¯.}  
+
+_textcb2_ [l=fa] {Ø§ØšØªØ¯Ø§ ØØŽÙ
+Ø§ ØšØ§ÙØ¯ ØªØµÙ
+ÙÙ
+ ØšÚ¯ÙØ±ÙØ¯ ÙÙ ÚÙ ÙØ§Ø±Ù Ø§ÙØ¬Ø§Ù
+ Ø¯ÙÙØ¯}  
+_textcnc_ [l=fa] {Ø§ÙØ¬Ø§Ø¯ ÙØ±Ø¯Ù Ù
+Ø¬Ù
+ÙØ¹Ù Ø¬Ø¯ÙØ¯}  
+_textwec_ [l=fa] {ØšØ§ Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+ÙØ¬ÙØ¯ ÙØ§Ø± ÙÙÙØ¯Ø Ø¯Ø§Ø¯Ù ÙØ§ÙÙ Ø±Ø§ ØšÙ Ø¢Ù Ø§Ø¶Ø§ÙÙ Ù ÙØ§ Ø­Ø°Ù ÙÙÙØ¯.}  
+
+_textcb3_ [l=fa] {ØšØ±Ø§Û Ø³Ø§Ø®ØªÙ ÙØ§ ØªØºÙÙØ± Ø¯Ø§Ø¯Ù Ù
+Ø¬Ù
+ÙØ¹Ù  ÙØ§Ù Ú©ØªØ§ØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØªØ§Ù ØŽÙ
+Ø§ 
+ØšØ§ÙØ¯ ØšÙ Ø³ÙØ³ØªÙ
+ ÙØ§Ø±Ø¯ ØŽÙÙØ¯.Ø§ÙÙ Ø§Ù
+Ø± ØšÙ Ø¬ÙØª Ø§ÙÙ Ø§Ø³Øª ÙÙ Ø¯ÙÚ¯Ø±Ø§Ù ØšÙ Ø³ÙØ³ØªÙ
+ ØŽÙ
+Ø§ 
+ÙØ§Ø±Ø¯ ÙØŽÙÙØ¯ Ù Ø§Ø·ÙØ§Ø¹Ø§Øª Ø±Ø§ ØªØºÙÛØ± ÙØ¯ÙÙØ¯. ØªÙØ¬Ù Ú©ÙÛØ¯ Ú©Ù ØšÙØ§ ØšÙ Ø¯ÙØ§ÛÙ Ø§Ù
+ÙÛØªÛ ØŽÙ
+Ø§ ÙŸØ³ Ø§Ø² Ú¯Ø°ØŽØª 30 Ø¯ÙÛÙÙ Ø§Ø² Ø³ÛØ³ØªÙ
+ Ø®Ø§Ø±Ø¬ Ø®ÙØ§ÙÛØ¯ ØŽØ¯. ÚÙØ§ÙÚÙ Ø§ÛÙ Ø§Ù
+Ø± Ø§ØªÙØ§Ù Ø§ÙØªØ§Ø¯ ÙÚ¯Ø±Ø§Ù ÙØšØ§ØŽÛØ¯ Ø§Ø² ØŽÙ
+Ø§ Ø®ÙØ§Ø³ØªÙ Ù
+Û ØŽÙØ¯ Ú©Ù Ø¯ÙØšØ§Ø±Ù ØšÙ Ø³ÛØ³ØªÙ
+ ÙØ§Ø±Ø¯ ØŽÙÛØ¯ Ù Ø§Ø² Ø¢ÙØ¬Ø§ÛÛÚ©Ù Ú©Ø§Ø± Ù
+Û Ú©Ø±Ø¯ÛØ¯ Ú©Ø§Ø± Ø®ÙØ¯ Ø±Ø§ Ø§Ø¯Ø§Ù
+Ù Ø¯ÙÛØ¯}  
+
+_textcb4_ [l=fa] {ÙØ·ÙØ§ ÙØ§Ù
+ ÙØ§Ø±ØšØ±Ù Ù Ø±Ù
+Ø² Ø¹ØšÙØ±  Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø®ÙØ¯ Ø±Ø§ ÙØ§Ø±Ø¯ ÙÙ
+Ø§ÙÙØ¯Ø Ù Ø¯ÙÙ
+Ù Ø±Ø§ Ø¬ÙØª ÙØ±ÙØ¯ ØšÙ Ø³ÙØ³ØªÙ
+ ÙÙÙÙ ÙÙ
+Ø§ÙÙØ¯.}  
+
+_textfsc_ [l=fa] {Ø¯Ø± Ù
+Ø±Ø­ÙÙ Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Ù Ø±Ø§ ÙÙ ØŽÙ
+Ø§ ØšØ§ Ø¢Ù ÙØ§Ø± Ù
+Ù ÙÙÙØ¯ Ø§ÙØªØ®Ø§Øš ÙÙÙØ¯(Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Ù Ù
+Ø­Ø§ÙØžØª ØŽØ¯Ù Ø¯Ø± Ø§ÙÙ ÙÙØ³Øª Ù
+ØŽØ§ÙØ¯Ù ÙØ®ÙØ§ÙÙØ¯ ØŽØ¯.}  
+
+_textwtc_ [l=fa] {ØšØ§ Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Ù ÙÙ ØŽÙ
+Ø§ Ø§ÙØªØ®Ø§Øš ÙÙ
+ÙØ¯Ù Ø§ÙØ¯Ø ØŽÙ
+Ø§ Ù
+Ù ØªÙØ§ÙÙØ¯}  
+_textamd_ [l=fa] {Ø¯Ø§Ø¯Ù ÙØ§Ù ØšÙØŽØªØ±Ù Ø±Ø§ Ø§Ø¶Ø§ÙÙ Ú©ÙÛØ¯ Ù Ù
+Ø¬Ù
+ÙØ¹Ù Ø±Ø§ Ø¯ÙØšØ§Ø±Ù ØšØ³Ø§Ø²ÙØ¯}  
+_textetc_ [l=fa] {ÙŸÙÙØ±ØšÙØ¯Ù Ù
+Ø¬Ù
+ÙØ¹Ù Ø±Ø§ ÙÙØ±Ø§ÙØŽ ÙØ±Ø¯Ù Ù Ø¯ÙØšØ§Ø±Ù Ù
+Ø¬Ù
+ÙØ¹Ù Ø±Ø§ Ø§Ø² ÙÙ ØšØ³Ø§Ø²ÛØ¯}  
+_textdtc_ [l=fa] {Ø­Ø°Ù ÙØ±Ø¯Ù ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù}  
+_textetcfcd_ [l=fa] {ØµØ¯ÙØ± Ù
+Ø¬Ù
+ÙØ¹Ù Ø¬ÙØª Ø±Ø§ÙØª ØšØ± Ø±ÙÙ ÙÙ CD-ROM ÙØ§ØšÙ ÙØµØš}  
+_textcaec_ [l=fa] {Ø¯Ø± Ø­Ø§Ù ØªØºÙÙØ±Ø¯Ø§Ø¯Ù ÛÚ© Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+ÙØ¬ÙØ¯}  
+_textnwec_ [l=fa] {ÙÙÚ Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ØšÙ Ø¯Ø±Ø¬ ÙØ±Ø¯Ù Ø¬ÙØª ØªØºÛÙØ± Ù
+ÙØ¬ÙØ¯ ÙÙØ³Øª.}  
+_textcianc_ [l=fa] {Ø¯Ø± Ø­Ø§Ù Ø§ÙØ¬Ø§Ø¯ ÙØ±Ø¯Ù Ù
+Ø¬Ù
+ÙØ¹Ù Ø¬Ø¯ÙØ¯}  
+_texttsosn_ [l=fa] {ØªØ±ØªÙØš Ù
+Ø±Ø§Ø­ÙÙ Ø±Ø§ ÙÙ Ø¬ÙØª Ø§ÙØ¬Ø§Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ù ÙØªØ§ØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù ÙØ§Ø²Ù
+ Ø§Ø³Øª Ø¹ØšØ§Ø±ØªÙØ¯ Ø§Ø² :}  
+_textsin_ [l=fa] {Ù
+ØŽØ®Øµ ÙØ±Ø¯Ù ÙØ§Ù
+ Ø¢Ù (Ù Ø§Ø·ÙØ§Ø¹Ø§Øª ÙØ§ØšØ³ØªÙ)}  
+_textswts_ [l=fa] {Ù
+ØŽØ®Øµ ÙÙÙØ¯ ÙÙ Ø¯Ø§Ø¯Ù ÙØ§Ù Ù
+ÙØšØ¹ Ø§Ø² ÙØ¬Ø§ Ù
+Ù Ø¢ÙÙØ¯}  
+_textatco_ [l=fa] {Ø¹ÙØ§ØµØ± ÙŸÙÙØ±ØšÙØ¯Ù Ø±Ø§ ØªÙØžÙÙ
+ ÙÙÙØ¯(ÙÙØ· ÙØ§Ø±ØšØ±Ø§Ù ÙŸÙØŽØ±ÙØªÙ)}  
+_textbtc_ [l=fa] {Ø³Ø§Ø®ØªÙ Ù
+Ø¬Ù
+ÙØ¹Ù (ØšÙ Ø²ÙØ± ÙÚ¯Ø§Ù ÙÙÙØ¯)}  
+_textpvyh_ [l=fa] {ØšØ§ Ø§ÙØªØ®Ø§Ø± ÙØªÙØ¬Ù ÙØ§Ø±Ù Ø®ÙØ¯ Ø±Ø§ Ù
+ØŽØ§ÙØ¯Ù ÙÙÙØ¯.}  
+
+_texttfsiw_ [l=fa] {Ù
+Ø±Ø­ÙÙ ÚÙØ§Ø±Ù
+ Ø¬Ø§ÙÙ Ø§Ø³Øª ÙÙ ÙØ§Ù
+ÙŸÙÙØªØ± ØªÙ
+Ø§Ù
+ ÙØ§Ø±ÙØ§ Ø±Ø§ Ø§ÙØ¬Ø§Ù
+ Ø¯Ø§Ø¯Ù Ø§Ø³Øª. Ø¯Ø± ÙØ±Ø§ÙÙØ¯ "Ø³Ø§Ø®ØªÙ"Ø ÙØ§Ù
+ÙŸÙÙØªØ±
+ØªÙ
+Ø§Ù
+Ù ÙÙ
+Ø§ÙÙ ÙØ§ Ø±Ø§ Ù
+Ù Ø³Ø§Ø²Ø¯ Ù Ø³Ø§ÙØ± Ø§Ø·ÙØ§Ø¹Ø§ØªÙ Ø±Ø§ ÙÙ ÙØ§Ø²Ù
+ ØšØ§ØŽØ¯
+Ø¬Ù
+Ø¹ Ø¢ÙØ±Ù Ù
+Ù ÙÙØ¯ Ø§ÙØšØªÙ ØŽÙ
+Ø§ ØšØ§ÙØ¯ Ø§Ø·ÙØ§Ø¹Ø§Øª Ù
+ÙØ±Ø¯ ÙØžØ± Ø±Ø§ Ù
+ØŽØ®Øµ ÙÙÙØ¯.}  
+
+_textadab_ [l=fa] {ÙÙ
+ÙØ¯Ø§Ø±Ù ÙÙ Ø¯Ø± Ø²ÙØ± Ù
+ØŽØ§ÙØ¯Ù Ù
+Ù ØŽÙØ¯ ØšÙ ØŽÙ
+Ø§ Ø¯Ø± ÙØ§ÙØªÙ Ù
+Ø³ÙØ±Ù ÙÙ Ø¯Ø± Ø¢Ù ÙØ³ØªÙØ¯ ÙÙ
+Ù Ø®ÙØ§ÙØ¯ ÙØ±Ø¯.
+ØšØ§ ÙÙÙÙ Ø¯ÙÙ
+Ù Ø³ØšØ² ØŽÙ
+Ø§ ØšØ±Ø§Ø³Ø§Ø³ ÙÙ
+Ø§Ù ØªÙØ§ÙÙ ÙØšÙÙ Ø§Ø¯Ø§Ù
+Ù Ø®ÙØ§ÙÙØ¯ Ø¯Ø§Ø¯. ÙÙ
+ÚÙØ§Ù ÙÙ ØŽÙ
+Ø§ ØšÙ ØªØ±ØªÙØš
+Ø¬ÙÙ Ù
+Ù Ø±ÙÙØ¯Ø Ø¯ÙÙ
+Ù ÙØ§ ØšÙ Ø±ÙÚ¯ Ø²Ø±Ø¯ ØªØºÙÙØ± ÙŸÙØ¯Ø§ Ø®ÙØ§ÙØ¯ ÙØ±Ø¯. ØŽÙ
+Ø§ ØšØ§ ÙÙÙÙ 
+Ø¯ÙÙ
+Ù Ø²Ø±Ø¯ Ù
+ØŽØ§ØšÙ Ù
+Ù ØªÙØ§ÙÙØ¯ ØšÙ ØµÙØ­Ø§Øª ÙØšÙ ØšØ±Ú¯Ø±Ø¯ÙØ¯.}  
+
+_textwyar_ [l=fa] {ÙÙÚ¯Ø§Ù
+Ù ÙÙ Ø¢Ù
+Ø§Ø¯Ù ØŽØ¯ÙØ¯Ø ØšØ± Ø±ÙÙ Ø¯ÙÙ
+Ù Ø³ØšØ²"Ø§Ø·ÙØ§Ø¹Ø§Øª Ù
+Ø¬Ù
+ÙØ¹Ù" ÙÙÙÙ ÙÙÙØ¯ ØªØ§ Ø®ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù Ø¬Ø¯ÙØ¯ ÙØªØ§ØšØ®Ø§ÙÙ
+Ø¯ÙØ¬ÙØªØ§Ù ØŽÙ
+Ø§ ØŽØ±ÙØ¹  ØŽÙØ¯ .}  
+
+_textcnmbs_ [l=fa] {ÙØ§Ù
+ Ù
+Ø¬Ù
+ÙØ¹Ù ØšØ§ÙØ¯ Ù
+ØŽØ®Øµ Ú¯Ø±Ø¯Ø¯}  
+_texteambs_ [l=fa] {Ø¢Ø¯Ø±Ø³ ÙŸØ³Øª Ø§ÙÙØªØ±ÙÙÙÙ ØšØ§ÙØ¯ Ù
+ØŽØ®Øµ ØŽÙØ¯}  
+_textpsea_ [l=fa] {ÙØ·ÙØ§ Ø¢Ø¯Ø±Ø³ ÙŸØ³Øª Ø§ÙÙØªØ±ÙÙÙÙÙ Ø±Ø§ ØšÙ ØŽÚ©Ù Ù
+ÙØ§ØšÙ ÙØ§Ø±Ø¯ ÙÙÙØ¯: username@domain}  
+_textdocmbs_ [l=fa] {ØªÙØµÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù ØšØ§ÙØ¯ Ù
+ØŽØ®Øµ Ú¯Ø±Ø¯Ø¯.}  
+
+_textwcanc_ [l=fa] {ÙÙÚ¯Ø§Ù
+Ù Ø§ÙØ¬Ø§Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ù Ø¬Ø¯ÙØ¯ ÙØ§Ø²Ù
+ Ø§Ø³Øª ÙÙ Ø§Ø·ÙØ§Ø¹Ø§Øª Ù
+ÙØ¯Ù
+Ø§ØªÙ Ø¯Ø± Ù
+ÙØ±Ø¯ Ø¯Ø§Ø¯Ù ÙØ§Ù Ù
+ÙØšØ¹ Ø±Ø§ ÙØ§Ø±Ø¯ ÙÙ
+Ø§ÙÙØ¯.
+Ø§ÙÙ ÙØ±Ø§ÙÙØ¯ ØšÙ ØµÙØ±Øª Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Ù Ø§Ø² ØµÙØ­Ø§Øª ÙØš ØªØŽÙÙÙ Ù
+Ù Ú¯Ø±Ø¯Ø¯Ø ÙÙ ØªÙØ³Ø· Ú¯Ø±Ø¯Ø¢ÙØ±Ø¯ÙØ¯Ù ÙØ±Ø§ÙÙ
+ ØŽØ¯Ù Ø§Ø³Øª.
+ÙÙØ§Ø± ÙŸØ§ÙÙÙ ØµÙØ­Ù ØªØ±ØªÙØš ØµÙØ­Ø§ØªÛ Ú©Ù ØšØ§ÛØ¯ ØªÚ©Ù
+ÛÙ ØŽÙØ¯ Ø±Ø§ ÙØŽØ§Ù Ù
+Ù Ø¯ÙØ¯.}  
+
+_texttfc_ [l=fa] {Ø¹ÙÙØ§ÙÙ Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù:}  
+
+_texttctiasp_ [l=fa] {Ø¹ÙÙØ§Ù Ù
+Ø¬Ù
+ÙØ¹Ù Ø¹ØšØ§Ø±Øª ÙÙØªØ§ÙÙ Ø§Ø³Øª ÙÙ Ø¯Ø± Ø³Ø±Ø§Ø³Ø± ÙØªØ§ØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù Ø¬ÙØª ØŽÙØ§Ø³Ø§ÙÙ Ù
+Ø­ØªÙØ§Ù Ù
+Ø¬Ù
+ÙØ¹Ù ØšÙ ÙØ§Ø± 
+Ù
+Ù Ø±ÙØ¯. ØšÙ Ø¹ÙÙØ§Ù Ù
+Ø«Ø§Ù "Ø¹ÙÙÙ
+ ÙØ§Ù
+ÙŸÙÙØªØ± Ù Ú¯Ø²Ø§Ø±ØŽØ§Øª ÙÙÙ" Ù " ÙØªØ§ØšØ®Ø§ÙÙ ØªÙØ³Ø¹Ù Ø§ÙØ³Ø§ÙÛ"}  
+
+_textcea_ [l=fa] {ØšØ§ Ø§ÙÙ Ø¢Ø¯Ø±Ø³ Ø§ÙÙ
+ÙÙ ØªÙ
+Ø§Ø³ ØšÚ¯ÙØ±ÙØ¯:}  
+
+_textteas_ [l=fa] {Ø§ÙÙ Ø¢Ø¯Ø±Ø³ ÙŸØ³ Ø§ÙÙØªØ±ÙÙÙÙÙ ÙÙØ·Ù ØŽØ±ÙØ¹ ØªÙ
+Ø§Ø³ ØšØ±Ø§Ù Ù
+Ø¬Ù
+ÙØ¹Ù Ø±Ø§ Ù
+ØŽØ®Øµ Ù
+Ù ÙÙØ¯. 
+Ø§Ú¯Ø± ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ù
+ØŽÙÙ Ø®Ø§ØµÙ Ø±Ø§ Ø±Ø¯ÙØ§ØšÙ ÙÙ
+ÙØ¯Ø ÙÙ Ú¯Ø²Ø§Ø±ØŽ ØªØŽØ®ÙØµÙ ØšØ±Ø§Ù Ø§ÙÙ 
+Ø¢Ø¯Ø±Ø³ Ø§Ø±Ø³Ø§Ù Ù
+Ù Ú¯Ø±Ø¯Ø¯. Ø¢Ø¯Ø±Ø³ ÙŸØ³Øª Ø§ÙÙØªØ±ÙÙÙÙÙ Ø±Ø§ ØšÙ ØµÙØ±Øª ÙØ§Ù
+Ù ÙØ§Ø±Ø¯ ÙÙÙØ¯.}  
+
+_textatc_ [l=fa] {Ø¯Ø± ØšØ§Ø±Ù Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù :}  
+
+_texttiasd_ [l=fa] {Ø§ÙÙ ØªÙØ¶ÙØ­Ø§ØªÙ Ø§Ø³Øª ÙÙ Ø§ØµÙÙ ÙØ§ØžØ± ØšØ± Ø§ÙÙÙÙ Ù
+Ø¬Ù
+ÙØ¹Ù ØŽØ§Ù
+Ù ÚÙ Ù
+ÙØ§Ø±Ø¯Ù Ù
+Ù ØŽÙØ¯ Ø±Ø§ ØªÙØµÙÙ Ù
+Ù ÙÙØ¯ 
+Ù Ø¯Ø± ÙÙÚ¯Ø§Ù
+ Ø§Ø±Ø§ØŠÙ Ù
+Ø¬Ù
+ÙØ¹Ù Ø¯Ø± ØµÙØ­Ù Ø§ÙÙ Ø§Ø±Ø§ØŠÙ Ù
+Ù Ú¯Ø±Ø¯Ø¯.}  
+
+_textypits_ [l=fa] {Ù
+ÙÙØ¹ÙØª ØŽÙ
+Ø§ Ø¯Ø± Ø§ÙÙ Ù
+Ø±Ø§Ø­Ù ØšØ§ Ø±Ø¯ÙÙÙ ØšÙØ³ÙÙÙ ÙÙ ÙÙØŽ Ø¯Ø± Ø²ÙØ± Ø¢Ù Ù
+ØŽØ®Øµ ØŽØ¯Ù Ø§Ø³Øª-- Ø¯Ø± Ø§ÙÙØ¬Ø§ 
+ØŽÙ
+Ø§ Ø¯Ø± Ù
+Ø±Ø­ÙÙ "Ø§Ø·ÙØ§Ø¹Ø§Øª Ù
+Ø¬Ù
+ÙØ¹Ù"  ÙØ³ØªÙØ¯. Ø¯ÙÙ
+Ù Ø³ØšØ² "Ø¯Ø§Ø¯Ù ÙØ§Ù Ù
+ÙØšØ¹"Ø±Ø§  Ø¬ÙØª Ø¬ÙÙØ±ÙØªÙ ÙÙÙÙ ÙÙÙØ¯.}  
+
+_srcebadsources_ [l=fa] {<p>ÛÚ© ÛØ§ ÚÙØ¯ ØªØ§ Ø§Ø² Ù
+ÙØ§ØšØ¹Û Ú©Ù ØŽÙ
+Ø§ Ù
+ØŽØ®Øµ Ú©Ø±Ø¯Ù 
+Ø§ÛØ¯ Ø¯Ø³ØªØ±Ø³ ÙŸØ°ÛØ± ÙÙ
+Û ØšØ§ØŽØ¯ (ØŽÙ
+Ø§ÛÙ ÙØ§Û Ø¹ÙØ§Ù
+Øª Ø¯Ø§Ø± ØŽØ¯Ù Ø¯Ø± ÙŸØ§ÛÛÙ)
+
+<p>Ø§ÛÙ Ú©Ø§Ø± Ù
+Û ØªÙØ§ÙØ¯ ØšÙ Ø¯ÙØ§ÛÙ Ø²ÛØ± ØšØ§ØŽØ¯
+<ul>
+<li>ÙØ§ÛÙØ Ø³Ø§ÛØª Ø§Ù ØªÛ ÙŸÛ ÛØ§ ÛÙ Ø¢Ø± Ø§ÙÙ Ù
+ÙØ¬ÙØ¯ 
+ÙÛØ³Øª
+<li>ØŽÙ
+Ø§ Ø§ØšØªØ¯Ø§ ØšØ§ÛØ³ØªÛ ØšÙ Ø¢Û Ø§ÙØ³ ÙŸÛ Ø®ÙØ¯ ÙØµÙ 
+ØŽÙÛØ¯
+<li>ØŽÙ
+Ø§ Ù
+Ù
+Ú©Ù Ø§Ø³Øª Ø§Ø² Ø¯Ø§Ø®Ù ÛÚ© Ø¯ÛÙØ§Ø± Ø¢ØªØŽ Ù
+Û 
+Ø®ÙØ§ÙÛØ¯ ØšÙ ÛÙ Ø¢Ø± Ø¢Ù ÙØµÙ ØŽÙÛØ¯ (Ø§ÛÙ Ø²Ù
+Ø§ÙÛ Ù
+ØµØ¯Ø§Ù Ø¯Ø§Ø±Ø¯ Ú©Ù ØŽÙ
+Ø§ ØšÙ ØµÙØ±Øª Ù
+Ø¹Ù
+ÙÙ ØšØ±Ø§Û 
+Ø¯Ø³ØªØ±Ø³Û ØšÙ Ø§ÛÙØªØ±ÙØª ÙÛØ§Ø² ØšÙ ÙØ§Ù
+ Ú©Ø§Ø±ØšØ±Û Ù Ø±Ù
+Ø² Ø¹ØšÙØ± Ø¯Ø§Ø±ÛØ¯)
+</ul>
+
+<p>ÚÙØ§ÙÚÙ Ø§ÛÙ Ø¢Ø¯Ø±Ø³Ø Ø¢Ø¯Ø±Ø³Û Ø§Ø³Øª Ú©Ù Ù
+Û ØªÙØ§ÙÛØ¯ 
+Ø¯Ø± Ù
+Ø±ÙØ±Ú¯Ø± Ø®ÙØ¯ Ø¢Ù Ø±Ø§ ØšØšÛÙÛØ¯Ø Ù
+Ù
+Ú©Ù Ø§Ø³Øª Ø¢ÙÛ ØšØ§ØŽØ¯ Ú©Ù Ø¯Ø± Ú©ÙØŽ Ù
+Ø­ÙÛ ØŽÙ
+Ø§ Ú©ÙŸÛ ØŽØ¯Ù 
+Ø§Ø³Øª. Ù
+ØªØ§Ø³ÙØ§ÙÙ Ú©ÙŸÛ ÙØ§Û Ú©ÙØŽ ØŽØ¯Ù Ø§Ø² Ø·Ø±ÛÙ ÙØ±Ø§ÛÙØ¯ÙØ§Û ØšØ§Ø²ØªØ§ØšÛ Ù
+Ø§ ÙØ§ØšÙ Ø±ÙÛØª ÙÛØ³Øª. 
+Ø¯Ø± Ø§ÛÙ Ø­Ø§ÙØª ØªÙØµÛÙ Ù
+Ø§ Ø§ÛÙ Ø§Ø³Øª Ú©Ù ØŽÙ
+Ø§ Ø§ØšØªØ¯Ø§ ØµÙØ­Ø§Øª Ø±Ø§ ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ù
+Ø±ÙØ±Ú¯Ø± Ø®ÙØ¯ 
+Ø¯Ø§ÙÙÙØ¯ Ú©ÙÛØ¯.}  
+
+_textymbyco_ [l=fa] {<p>ØŽÙ
+Ø§ Ù
+Ù
+Ú©Ù Ø§Ø³Øª Ù
+Ø¬Ù
+ÙØ¹Ù Ø®ÙØ¯ Ø±Ø§ ØšØ±Ø§Ø³Ø§Ø³ ÛÚ©Û Ø§Ø² Ù
+ÙØ§Ø±Ø¯ Ø²ÛØ± ØšÙØ§ Ú©ÙÛØ¯
+<ul>
+<li>Ø³Ø§Ø®ØªØ§Ø± ÙŸÛØŽÙØ±Ø¶
+<dl><dd>Ù
+Ø¬Ù
+ÙØ¹Ù Ø¬Ø¯ÛØ¯ Ù
+Û ØªÙØ§ÙØ¯ Ù
+Ø¯Ø§Ø±Ú© html (.htm, 
+.html)Ø Ù
+Ø¯Ø§Ø±Ú© MS Word (.doc)Ø 
+Ù
+Ø¯Ø±Ú© PDF (.pdf) ÛØ§ ÙØ±Ù
+Øª
+"m-box" Ù
+Ø¯Ø§Ø±Ú© ÙŸØ³Øª Ø§ÙÚ©ØªØ±ÙÙÛÚ© (.mbx) 
+ØšØ§ØŽØ¯.</dd></dl>
+<li>An existing collectionÛÚ© Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+ÙØ¬ÙØ¯<dl><dd>Ø§ÛÙ ÙØ§ÛÙ ÙØ§ Ø¯Ø± Ù
+Ø¬Ù
+ÙØ¹Ù Ø¬Ø¯ÛØ¯ ØŽÙ
+Ø§ 
+ØšØ§ÛØ³ØªÛ Ø¯ÙÛÙØ§ Ù
+ØŽØ§ØšÙ ÙÙØ¹ ÙØ§ÛÙ ÙØ§Û Ù
+ÙØ±Ø¯ Ø§Ø³ØªÙØ§Ø¯Ù ØšØ±Ø§Û Ø§ÛØ¬Ø§Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+ÙØ¬ÙØ¯ ØšØ§ØŽØ¯.</dd></dl>
+</ul>}  
+
+_textbtco_ [l=fa] {Ø§ÛØ¬Ø§Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ù ØšØ± Ù
+ØšÙØ§Û}  
+_textand_ [l=fa] {Ø§ÙØ±ÙØ¯Ù Ø¯Ø§Ø¯Ù ÙØ§Ù Ø¬Ø¯ÙØ¯}  
+_textad_ [l=fa] {Ø¯Ø± Ø­Ø§Ù Ø§Ø¶Ø§ÙÙ ÙÙ
+ÙØ¯Ù Ø¯Ø§Ø¯Ù:}  
+
+_texttftysb_ [l=fa] {ÙØ§ÙÙÙØ§ÙÙ Ø±Ø§ ÙÙ ØŽÙ
+Ø§ Ø¯Ø± Ø²ÙØ± Ù
+ØŽØ®Øµ ÙÙ
+ÙØ¯Ù Ø§ÙØ¯ ØšÙ Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Ø¶Ø§ÙÙ Ø®ÙØ§ÙØ¯ ØŽØ¯. Ù
+Ø·Ù
+ØŠÙ ØŽÙÙØ¯ ÙÙ ØŽÙ
+Ø§ ÙØ§ÙÙÙØ§ÙÙ Ø±Ø§
+ÙÙ
+ Ø§ÙÙÙÙ Ø¯Ø± Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ³ØªÙØ¯Ø Ø§ÙØªØ®Ø§Øš ÙÙÙÙØ¯: Ø¯Ø± ØºÙØ± Ø§ÙÙ ØµÙØ±Øª Ø¯Ù ÙÙŸÙ ØšÙ Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Ø¶Ø§ÙÙ Ø®ÙØ§ÙÙØ¯ ØŽØ¯.
+ÙØ§ÙÙÙØ§ ØšÙ ÙØ³ÙÙÙ Ù
+Ø³ÙØ± ÙØ§Ù
+Ù Ø¢ÙÙØ§ Ø Ù ØµÙØ­Ø§Øª ÙØš ØšØ§ Ø¢Ø¯Ø±Ø³ ÙØ§Ù
+Ù Ø¢ÙÙØ§ Ù
+ØŽØ®Øµ Ù
+Ù Ú¯Ø±Ø¯ÙØ¯.}  
+
+_textis_ [l=fa] {Ù
+ÙØ§ØšØ¹ ÙØ±ÙØ¯Ù:}  
+
+_textddd1_ [l=fa] {Ø§Ú¯Ø± ØŽÙ
+Ø§ Ø¬ÙØª Ù
+ØŽØ®Øµ ÙÙ
+ÙØ¯Ù ÙØ§ÙÙ ØŽÙ
+Ø§ Ø§Ø² file:// ÙØ§ ftp:// Ø§Ø³ØªÙØ§Ø¯Ù ÙÙÙØ¯Ø ÙØ§ÙÙ Ø¯Ø§ÙÙÙØ¯ Ø®ÙØ§ÙØ¯ ØŽØ¯.
+
+Ø§Ú¯Ø± ØŽÙ
+Ø§ Ø§Ø²http:// Ø§Ø³ØªÙØ§Ø¯Ù ÙÙÙØ¯ ØšÙ Ø§ÙÙ ØšØ³ØªÚ¯Ù Ø¯Ø§Ø±Ø¯ ÚÙ URL Ø®Ø§ØµÙ 
+ÙÙ ØµÙØ­Ù ÙØš Ø³Ø§Ø¯Ù ÙØ§ ÙÙØ³ØªÙ Ø§Ø² ÙØ§ÙÙÙØ§ Ø±Ø§ Ø¯Ø± Ø§Ø®ØªÙØ§Ø± Ù
+Ù Ú¯Ø°Ø§Ø±Ø¯. Ø§Ú¯Ø± 
+ÙÙ ØµÙØ­Ù ÙØš ØšØ§ØŽØ¯Ø Ø¯Ø§ÙÙÙØ¯ Ø®ÙØ§ÙØ¯ ØŽØ¯-Ø¢Ù ØµÙØ­Ù Ù ØªÙ
+Ø§Ù
+ ØµÙØ­Ø§ØªÙ ÙÙ ØšÙ Ø¢ÙÙØ§ 
+ÙÙÙÙ Ø¯Ø§Ø¯Ù ØŽØ¯Ù Ù Ø¢ÙÙØ§ ØšÙ Ø§ÙÙ ØµÙØ­Ù ÙÙÙÙ Ø¯Ø§Ø¯Ù Ø§ÙØ¯- Ø¯Ø± ØµÙØ±ØªÙ ÙÙ Ø¢ÙÙØ§ Ø¯Ø± ÙÙ
+Ø§Ù Ø³Ø§ÙØª ÙØ§ Ø²ÙØ± ØŽØ§Ø®Ù Ø¢Ù URL ØšØ§ØŽÙØ¯.
+
+Ø§Ú¯Ø± ØŽÙ
+Ø§ Ø§Ø² file:// ÙØ§ ftp:// Ø¬ÙØª Ù
+ØŽØ®Øµ ÙØ±Ø¯Ù 
+ÙÙ ÙÙÙØ¯Ø± ÙØ§ Ø¯Ø§ÙØ±ÙØªÙØ±Ù Ø§Ø³ØªÙØ§Ø¯Ù ÙÙ
+Ø§ÙÙØ¯Ø ÙØ§ ÙÙ http:// URL ÙÙ ØšÙ ÙÙØ³ØªÙ 
+Ø§Ø² ÙØ§ÙÙÙØ§ Ù
+ÙØªÙÙ Ù
+Ù Ú¯Ø±Ø¯Ø¯Ø ÙØ± ÚÙØ²Ù Ø¯Ø± Ø¢Ù ÙÙÙØ¯Ø± Ù ØªÙ
+Ø§Ù
+Ù Ø²ÙØ± ÙÙÙØ¯Ø±ÙØ§ Ø¯Ø± Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ±Ø§Ø± Ø®ÙØ§ÙÙØ¯ Ú¯Ø±ÙØª.
+
+Ø¬ÙØª ØšÙ Ø¯Ø³Øª Ø¢ÙØ±Ø¯Ù ØšØ§ÙØ³ÙØ§Ù ØšÙØŽØªØ±ØØšØ± Ø±ÙÙ Ø¯ÙÙ
+Ù "Ù
+ÙØ§ØšØ¹ ØšÙØŽØªØ±" ÙÙÙÙ ÙÙÙØ¯.}  
+
+_textddd2_ [l=fa] {ØšØ± Ø±ÙÙ ÙÙÙ Ø§Ø² Ø¯ÙÙ
+Ù ÙØ§Ù Ø³ØšØ² ÙÙÙÙ ÙÙÙØ¯. Ø§Ú¯Ø± ØŽÙ
+Ø§ ÙØ§Ø±ØšØ±Ù ØšØ§ Ø³Ø·Ø­ ÙŸÙØŽØ±ÙØªÙ ÙØ³ØªÙØ¯Ø 
+Ù
+Ù
+ÙÙ Ø§Ø³Øª ÙÙØ§Ø² ØšÙ ØªØºÙÙØ± Ø¯Ø§Ø¯Ù ØªÙØžÙÙ
+Ø§Øª Ù
+Ø±ØšÙØ· ØšÙ ÙŸÙÙØ±ØšÙØ¯Ù Ù
+Ø¬Ù
+ÙØ¹Ù ØšØ§ØŽÙØ¯.Ù
+Ø³ØªÙÙÙ
+Ø§ 
+ØšÙ Ù
+Ø±Ø­ÙÙ Ø³Ø§Ø®ØªÙ ØšØ±ÙÙØ¯. ØšÙ ÙØ§Ø¯ Ø¯Ø§ØŽØªÙ ØšØ§ØŽÙØ¯Ø Ø¬ÙØª Ù
+ØŽØ§ÙØ¯Ù Ø¯ÙØšØ§Ø±Ù
+ÙÙ Ù
+Ø±Ø­ÙÙ ØšØ± Ø±ÙÙ Ø¯ÙÙ
+Ù Ø²Ø±Ø¯ Ø¢Ù Ù
+Ø±Ø­ÙÙ ÙÙÙÙ ÙÙÙØ¯.}  
+
+_textconf1_ [l=fa] {Ø³Ø§Ø®ØªÙ Ù Ø§Ø±Ø§ØŠÙ Ù
+Ø¬Ù
+ÙØ¹Ù ØŽÙ
+Ø§ ØšÙ ÙØ³ÙÙÙ ØŽØ§Ø®ØµÙØ§Ù Ø®Ø§ØµÙ Ø¯Ø± "configuration file" ÙÙØªØ±Ù Ù
+Ù ØŽÙØ¯.
+ÙØ§Ø±ØšØ±Ø§Ù ÙŸÙØŽØ±ÙØªÙ Ù
+Ù
+ÙÙ Ø§Ø³Øª ØšØ± Ø­Ø³Øš ÙÙØ§Ø² ØªÙØžÙÙ
+Ø§Øª ÙŸÙÙØ±ØšÙØ¯Ù Ø±Ø§ ØªØºÙÙØ± Ø¯ÙÙØ¯.
+Ø§Ú¯Ø± ØŽÙ
+Ø§ ÙÙ ÙØ§Ø±ØšØ± ØšØ§ Ø³Ø·Ø­ ÙŸÙØŽØ±ÙØªÙ ÙÙØ³ØªÙØ¯Ø ÙÙØ· ØšÙ ÙŸØ§ÙÙÙ ØµÙØ­Ù ØšØ±ÙÙØ¯.
+Ø¬ÙØª Ø¹ÙØ¶ ÙÙ
+ÙØ¯Ù ØªÙØžØšÙÙ
+Ø§Øª ÙŸÙÙØ±ØšÙØ¯Ù Ø§Ø·ÙØ§Ø¹Ø§ØªÙ Ø±Ø§ ÙÙ Ø¯Ø± Ø²ÙØ± Ù
+ØŽØ§ÙØ¯Ù Ù
+Ù ØŽÙÙØ¯Ø
+ÙÙØ±Ø§ÙØŽ ÙÙÙØ¯. Ø§Ú¯Ø± Ø§ØŽØªØšØ§Ù ÙØ±Ø¯ÙØ¯ ØšØ± Ø±ÙÙ Ø¯ÙÙ
+Ù "reset" Ø¬ÙØª
+ØšØ±Ú¯ØŽØª ØšÙ ØªÙØžÙÙ
+Ø§Øª Ø§ÙÙÙÙ ÙÙÙÙ ÙÙÙØ¯.}  
+
+_textreset_ [l=fa] {ØšØ§Ø²ÙØŽØ§ÙÛ}  
+
+
+_texttryagain_ [l=fa] {ÙØ·ÙØ§ <a href="_httppagecollector_" target=_top> Ú¯Ø±Ø¯Ø¢ÙØ±ÙØ¯Ù Ø±Ø§ Ø§Ø² ÙÙ ØŽØ±ÙØ¹ ÙÙÙØ¯ </a> Ù Ø¯ÙØšØ§Ø±Ù Ø³Ø¹Ù ÙÙÙØ¯.}  
+
+
+_textretcoll_ [l=fa] {ØšÙ Ú¯Ø±Ø¯Ø¢ÙØ±ÙØ¯Ù ØšØ±Ú¯Ø±Ø¯ÙØ¯}  
+
+_textdelperm_ [l=fa] {ÙÙ
+Ù ÛØ§ ØšØ®ØŽÛ Ø§Ø² Ù
+Ø¬Ù
+ÙØ¹Ù_cgiargbc1dirname_ ÙÙ
+Û ØªÙØ§ÙØ¯ Ø­Ø°Ù ØŽÙØ¯. Ø¯ÙØ§ÛÙ Ø§Ø­ØªÙ
+Ø§ÙÛ Ù
+Ù
+Ú©Ù Ø§Ø³Øª ÛÚ©Û Ø§Ø² Ù
+ÙØ§Ø±Ø¯ Ø²ÛØ± ØšØ§ØŽØ¯:  <ul>
+<li>Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø§Ø² Ø§Ø®ØªÙØ§Ø± ÙØ§Ø±ÙÙ Ø¬ÙØª Ø­Ø°Ù Ø¯Ø§ÙØ±ÙØªÙØ±Ù _gsdlhome_/collect/_cgiargbc1dirname_ ØšØ±Ø®ÙØ±Ø¯Ø§Ø± ÙÙØ³Øª.
+
+Ø¬ÙØª ØšØ±Ø¯Ø§ØŽØªÙ Ù
+Ø¬Ù
+ÙØ¹Ù _cgiargbc1dirname_ ØŽÙ
+Ø§ Ù
+Ù
+ÙÙ Ø§Ø³Øª Ù
+Ø¬ØšÙØ± ØšØ§ØŽÙØ¯ ØšÙ ØµÙØ±Øª Ø¯Ø³ØªÙ Ø§ÙÙ Ø¯Ø§ÙØ±ÙØªÙØ±Ù Ø±Ø§ Ø­Ø°Ù ÙÙÙØ¯.
+
+Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ÙØ§Ø¯Ø± ØšÙ Ø±Ø§Ù Ø§ÙØ¯Ø§Ø²Ù ØšØ±ÙØ§Ù
+Ù _gsdlhome_/bin/script/delcol.pl ÙÙØ³Øª. Ù
+Ø·Ù
+ØŠÙ ØŽÙÙØ¯ ÙÙ Ø¢ÙØ§ Ø§ÙÙ ÙØ§ÙÙ ÙØ§ØšÙ Ø®ÙØ§ÙØ¯Ù Ø§Ø³Øª.}  
+
+_textdelinv_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù_cgiargbc1dirname_ Ø­ÙØ§ØžØª ØŽØ¯Ù ÙØ§ ØšÙ Ø§Ø¹ØªØšØ§Ø± Ø§Ø³Øª. Ø­Ø°Ù ÙØ±Ø¯Ù ÙØºÙ ØŽØ¯.}  
+
+_textdelsuc_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù _cgiargbc1dirname_ ØšØ§ Ù
+ÙÙÙÙØª Ø­Ø°Ù ØŽØ¯.}  
+
+_textclonefail_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù _cgiargclonecol_ ÙÙ
+Ù ØªÙØ§ÙØ¯ ØšØ§Ø²ØªÙÙÙØ¯ ØŽÙØ¯. Ø¯ÙØ§ÙÙ Ø§Ø­ØªÙ
+Ø§ÙÙ Ø§ÙÙ ÙØ§ ÙØ³ØªÙØ¯:
+<ul>
+<li>Ù
+Ø¬Ù
+ÙØ¹Ù _cgiargclonecol_ Ù
+ÙØ¬ÙØ¯ ÙÙØ³Øª.
+<li>Ù
+Ø¬Ù
+ÙØ¹Ù _cgiargclonecol_ Ø¯Ø§Ø±Ø§Ù ÙØ§ÙÙ ÙŸÙÙØ±ØšÙØ¯Ù collect.cfg ÙÙØ³Øª.
+<li>Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø§Ø² Ù
+Ø¬ÙØ² ÙØ§ÙÙ Ø¬ÙØª Ø®ÙØ§ÙØ¯Ù collect.cfg ØšØ±Ø®ÙØ±Ø¯Ø§Ø± ÙÙØ³Øª.
+<ul/>}  
+
+_textcolerr_ [l=fa] {Ø®Ø·Ø§ Ø¯Ø± Ú¯Ø±Ø¯Ø¢ÙØ±ÙØ¯Ù}  
+
+_texttmpfail_ [l=fa] {Ú¯Ø±Ø¯Ø¢ÙØ±ÙØ¯Ù Ø¯Ø± Ø®ÙØ§ÙØ¯Ù ÙØ§ Ø¯Ø±Ø¬ Ø¯Ø± ÙØ§ÙÙ ÙØ§ Ø¯Ø§ÙØ±ÙØªÙØ±Ù Ù
+ÙÙØª Ù
+ÙÙÙ ÙØŽØ¯. Ø¯ÙØ§ÙÙ Ø§Ø­ØªÙ
+Ø§ÙÙ Ø¹ØšØ§Ø±ØªÙØ¯ Ø§Ø²:
+Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø¯Ø§Ø±Ø§Ù Ø¯Ø³ØªØ±Ø³Ù Ø®ÙØ§ÙØ¯Ù/Ø¯Ø±Ø¬ ÙØ±Ø¯Ù ØšÙ Ø¯Ø§ÙØ±ÙØªÙØ±Ù _gsdlhome_/tmp ÙÙØ³Øª.}  
+
+_textmkcolfail_ [l=fa] {Ú¯Ø±Ø¯Ø¢ÙØ±ÙØ¯Ù Ù
+ÙÙÙ ØšÙ Ø³Ø§Ø®Øª Ø¯Ø§ÙØ±ÙØªÙØ±Ù ÙÙ ØªÙØ³Ø· Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Ø²Ù
+ ØšÙØ¯Ø ÙØŽØ¯(mkcol.pl Ø±Ø¯ ØŽØ¯). Ø¯ÙØ§ÙÙ Ø§Ø­ØªÙ
+Ø§ÙÙ Ø¹ØšØ§Ø±ØªÙØ¯ Ø§Ø²:
+<ul>
+<li>Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø§Ø² Ø§Ø®ØªÙØ§Ø± ÙØ§ÙÙ Ø¬ÙØª ÙÙØŽØªÙ ÙÙØ§ Ø¯Ø±Ø¬ ÙØ±Ø¯Ù Ø¯Ø± Ø¯Ø§ÙØ±ÙØªÙØ±Ù _gsdlhome_/tmp ØšØ±Ø®ÙØ±Ø¯Ø§Ø± ÙÙØ³Øª.  
+<li>Ø®Ø·Ø§Û ÙØ§ØŽÛ Ø§Ø² Ø§Ø³Ú©Ø±ÛÙŸØª ÙŸØ±Ù mkcol.pl
+</ul>}  
+
+_textnocontent_ [l=fa] {Ø®Ø·Ø§Ù Ú¯Ø±Ø¯Ø¢ÙØ±ÙØ¯Ù. ÙÙÚ ÙØ§Ù
+Ù ØšØ±Ø§Ù Ù
+Ø¬Ù
+ÙØ¹Ù ØšØ±Ú¯Ø²ÙØ¯Ù ÙØŽØ¯Ù. Ú¯Ø±Ø¯Ø¢ÙØ±ÙØ¯Ù Ø±Ø§ Ø§Ø² ÙÙ ØŽØ±ÙØ¹ ÙÙÙØ¯}  
+
+_textrestart_ [l=fa] {Ú¯Ø±Ø¯Ø¢ÙØ±ÙØ¯Ù Ø±Ø§ Ø§Ø² ÙÙ ØŽØ±ÙØ¹ ÙÙÙØ¯.}  
+
+_textreloaderror_ [l=fa] {Ø¯Ø± Ø­ÙÙ Ø§ÙØ¬Ø§Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ù Ø¬Ø¯ÙØ¯ ÙÙ Ø®Ø·Ø§ Ø±Ø® Ø¯Ø§Ø¯. Ø§ÙÙ Ù
+Ù
+ÙÙ Ø§Ø³Øª ØšÙ Ø¹ÙØª Ø§ÙÙ ØšØ§ØŽØ¯ ÙÙ Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù ØŽÙ
+Ø§ Ø§Ø² Ø¯ÙÙ
+Ù ÙØ§Ù "reload" ÙØ§ "back" Ø¯ÚØ§Ø± Ø§Ø®ØªÙØ§Ù ØŽØ¯Ù ØšØ§ØŽØ¯.(ÙØ·ÙØ§ Ø³Ø¹Ù ÙÙÙØ¯ Ø¯Ø± Ø­ÙÙ Ø§ÙØ¬Ø§Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Ø² Ø§ÙÙ Ø¯ÙÙ
+Ù ÙØ§ Ø§Ø³ØªÙØ§Ø¯Ù ÙÙÙÙØ¯.) Ø¯Ø± Ø¶Ù
+Ù ØªÙØµÙÙ Ù
+Ù ØŽÙØ¯ Ú¯Ø±Ø¯Ø¢ÙØ±ÙØ¯Ù Ø±Ø§ Ø§Ø² ÙÙ ØŽØ±ÙØ¹ ÙÙÙØ¯.}  
+
+_textexptsuc_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù _cgiargbc1dirname_ØšØ§ Ù
+ÙÙÙÙØª ØšÙ Ø¯Ø§ÙØ±ÙØªÙØ±Ù _gsdlhome_/tmp/exported\__cgiargbc1dirname_ØµØ§Ø¯Ø± ØŽØ¯.}  
+
+_textexptfail_ [l=fa] {ØµØ§Ø¯Ø± ÙØ±Ø¯Ù Ù
+Ø¬Ù
+ÙØ¹Ù _cgiargbc1dirname_ Ø§ÙØ¬Ø§Ù
+ ÙÚ¯Ø±ÙØª.<p>
+
+Ø§ÙÙ Ù
+Ù
+ÙÙ Ø§Ø³Øª ØšÙ Ø¹ÙØª Ø¹Ø¯Ù
+ ÙØµØš Ø¯Ø±Ø³Øª Ø§Ø¬Ø²Ø§Ù Ø¶Ø±ÙØ±Ù "Export Collection" ØšØ§ØŽØ¯.<p>
+<ul>
+<li> Ø§Ú¯Ø± Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø±Ø§ Ø§Ø² Ø·Ø±ÙÙ CD-ROM ÙØµØš ÙØ±Ø¯Ù Ø§ÙØ¯ Ø§ÙÙ Ø§Ø¬Ø²Ø§Ø¡ ÙØµØš ÙØŽØ¯Ù Ø§ÙØ¯ 
+Ù
+Ú¯Ø± Ø§ÙÙÙÙ Ø¢ÙÙØ§ Ø±Ø§ Ø¯Ø± Ø·Ù ÙØµØš Ù
+Ø®ØªØµ ØšÙ ÙØ§Ø±ØšØ± Ø§ÙØªØ®Ø§Øš ÙØ±Ø¯Ù ØšØ§ØŽÙØ¯.ØŽÙ
+Ø§ Ù
+Ù ØªÙØ§ÙÙØ¯ ØšØ§ Ø§Ø¶Ø§ÙÙ ÙÙ
+ÙØ¯Ù 
+Ø¯Ø± Ø¬Ø±ÙØ§Ù ÙØµØš ØšØ¹Ø¯Ù Ø¢ÙÙØ§ Ø±Ø§ ÙØµØš ÙÙÙØ¯.
+
+<li> Ø§Ú¯Ø± Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø±Ø§ Ø§Ø² Ø·Ø±ÙÙ ÙØ³Ø®Ù Ø¯Ø§ÙÙÙØ¯Ù ÙØµØš ÙØ±Ø¯Ù Ø§ÙØ¯Ø Ø¬ÙØª ÙØ¹Ø§Ù ÙØ±Ø¯Ù Ø§ÙÙ ØªØ§ØšØ¹ ØšØ§ÙØ¯ ØšØ³ØªÙ ÙØ§Ù 
+Ø¯ÙÚ¯Ø±Ù Ø±Ø§ ÙÙØ² Ø¯Ø§ÙÙÙØ¯ ÙÙÙØ¯. ÙØ·ÙØ§ Ø¬ÙØª Ù
+ØŽØ§ÙØ¯Ù Ø¬Ø²ØŠÙØ§Øª ØšÙØŽØªØ± ØšÙ URL Ø²ÙØ± Ù
+Ø±Ø§Ø¬Ø¹Ù ÙÙÙØ¯:
+<a href="http://www.greenstone.org">http://www.greenstone.org</a>
+Ù ØšØ§ ØšÙ Ø¢Ø¯Ø±Ø³ ÙŸØ³Øª Ø§ÙÙØªØ±ÙÙÙÙÙ Ø²ÙØ± Ø§ÙÙ
+ÙÙ ØšÙØ±Ø³ØªÙØ¯:
+ href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a><a
+</ul>}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=fa] {ÙØ·ÙØ§ Ø§Ø·ÙØ§Ø¹Ø§Øª ÙØ§ÛÙ Ø²ÛØ± Ø±Ø§ Ù
+ØŽØ®Øµ ÙÙ
+ÙØ¯Ù Ù Ø±ÙÛ  _textintro_ Ú©ÙÛÚ© ÙÙ
+Ø§ÛÛØ¯.<p>}  
+
+_textcaec_ [l=fa] {Ø¯Ø± Ø­Ø§Ù Ø§Ø¶Ø§ÙÙ ÙÙ
+ÙØ¯Ù ØšÙ Ù
+Ø¬Ù
+ÙØ¹Ù Ù
+ÙØ¬ÙØ¯}  
+_textbild_ [l=fa] {Ø§ÙÙØ§Ù
+ Ø³ÙŸØ±Ø¯Ù Ø§Û}  
+_textintro_ [l=fa] {Ø§ÙØªØ®Ø§Øš ÙÙ
+ÙØ¯Ù ÙØ§ÙÙ}  
+_textconfirm_ [l=fa] {ØªØ§ÛÛØ¯}  
+_textselect_ [l=fa] {Ø§ÙØªØ®Ø§Øš Ù
+Ø¬Ù
+ÙØ¹Ù}  
+_textmeta_ [l=fa] {Ù
+ØŽØ®Øµ ÙÙ
+ÙØ¯Ù Ø§ØšØ±Ø¯Ø§Ø¯Ù}  
+
+
+_texttryagain_ [l=fa] {ÙØ·ÙØ§ <a href="_httppagedepositor_" target=_top>Ø§Ù
+Ø§ÙØª Ø¯ÙÙØ¯Ù Ø§Ø² Ù
+Ø¬Ø¯Ø¯Ø§ Ø±Ø§Ù Ø§ÙØ¯Ø§Ø²Ù ÙÙÙØ¯</a> Ù Ø¯ÙØšØ§Ø±Ù Ø³Ø¹Ù ÙÙÙØ¯.}  
+
+_textselectcol_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Û Ø±Ø§ Ú©Ù ÙØµØ¯ Ø¯Ø§Ø±ÛØ¯ Ø§Ø³ÙØ§Ø¯ Ø¬Ø¯ÛØ¯Û ØšÙ Ø¢Ù Ø§Ø¶Ø§ÙÙ Ú©ÙÛØ¯Ø Ø§ÙØªØ®Ø§Øš ÙÙ
+Ø§ÛÛØ¯.}  
+_textfilename_ [l=fa] {ÙØ§Ù
+ ÙØ§ÛÙ}  
+_textfilesize_ [l=fa] {Ø§ÙØ¯Ø§Ø²Ù ÙØ§ÛÙ}  
+
+_textretcoll_ [l=fa] {ØšØ§Ø²ÙØŽØª ØšÙ Ø§Ù
+Ø§ÙØª Ø¯ÙÙØ¯Ù}  
+
+
+_texttmpfail_ [l=fa] {Ø§Ù
+Ø§ÙØª Ø¯ÙÙØ¯Ù Ø¯Ø± Ø®ÙØ§ÙØ¯Ù ÙØ§ ÙÙØŽØªÙ Ø¯Ø± ÙØ§ÙÙ ÙØ§ Ø¯Ø§ÙØ±ÙØªÙØ±Ù Ù
+ÙÙØª Ù
+ÙÙÙ ÙØŽØ¯. Ø¯ÙØ§ÙÙ Ø§Ø­ØªÙ
+Ø§ÙÙ Ø¹ØšØ§Ø±ØªÙØ¯ Ø§Ø²:
+<ul>
+Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ø§Ø² Ø§Ø¹ØªØšØ§Ø± Ú©Ø§ÙÛ Ø¬ÙØª ÙÙØŽØªÙ/Ø®ÙØ§ÙØ¯Ù Ø¯Ø± Ù
+Ø³ÛØ±  _gsdlhome_/tmp ØšØ±Ø®ÙØ±Ø¯Ø§Ø± ÙÛØ³Øª. <li>
+<ul/>}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=fa] {Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø§Ø² Ù
+Ø¬Ù
+ÙØ¹Ù ØšØ±ÙØ§Ù
+Ù ÙØ§ÙÙ Ø§Ø³Øª ÙÙ ÙØ§ØšÙÙØª Ø³Ø±ÙÙØ³ Ø¯ÙÙ ØšÙ Ù
+Ø¬Ù
+ÙØ¹Ù ÙØªØ§ØšØ®Ø§ÙÙ ÙØ§Ù Ø¯ÙØ¬ÙØªØ§ÙÙ 
+Ù Ø§ÙØ¬Ø§Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Ù Ø¬Ø¯ÙØ¯ Ø±Ø§ Ø¯Ø§Ø±Ø§Ø³Øª. Ø¢Ù ØŽÙÙÙ Ø¬Ø¯ÙØ¯Ù Ø§Ø² Ø³Ø§Ø²Ù
+Ø§ÙØ¯ÙÙ Ù Ø§ÙØªØŽØ§Ø± Ø§Ø·ÙØ§Ø¹Ø§Øª Ø±ÙÙ Ø§ÙÙØªØ±ÙØª 
+Ù CD-ROM ÙØ±Ø§ÙÙ
+ Ù
+Ù ÙÙØ¯.Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ØªÙØ³Ø· ÙŸØ±ÙÚÙ ÙØªØ§ØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù ÙÙÙØ²ÙÙÙØ¯ Ø¯Ø± Ø¯Ø§ÙØŽÚ¯Ø§Ù ÙØ§ÙÙØ§ØªÙ
+ØªÙÙÙØ¯Ø Ù ØšØ§ ÙÙ
+ÙØ§Ø±Ù ÙÙÙØ³ÙÙ Ù Human Info NGO ØªÙØ²ÙØ¹ Ù
+Ù Ú¯Ø±Ø¯Ø¯.}  
+
+_textgreenstone2_ [l=fa] {ÙØš Ø³Ø§ÙØª ÙØªØ§Ø®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù ÙÙÙØ²ÙÙÙØ¯ (<a
+href="http://nzdl.org">http://nzdl.org</a>) ØŽØ§Ù
+Ù Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Ù ÙÙ
+ÙÙÙ ÙØ±Ø§ÙØ§ÙÙ Ø§Ø³ØªØ ÙÙ ÙÙ
+Ù Ø¢ÙÙØ§ ØªÙØ³Ø· 
+ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø§ÙØ¬Ø§Ø¯ ØŽØ¯Ù Ø§ÙØ¯Ø Ù Ø¬ÙØª Ø§Ø³ØªÙØ§Ø¯Ù Ù ØšØ±Ø±Ø³Ù Ø¹Ù
+ÙÙ
+ Ù
+ÙØ¬ÙØ¯ Ø§Ø³Øª. Ø¢ÙÙØ§  
+ÙÙ
+ÙÙÙ ÙØ§Û Ú¯ÙÙØ§Ú¯ÙÙÙ Ø¬Ø³ØªØ¬Ù Ù Ù
+Ø±ÙØ± Ø±Ø§Ø Ø¯Ø± Ù
+Ø¬Ù
+ÙØ¹Ù Ø²ØšØ§ÙÙØ§Ù Ø¹Ø±ØšÙØ ÚÙÙÙØ ÙØ±Ø§ÙØ³ÙÙØ Ø²ÙÙØ§ÙØ¯Ù Ù Ø§Ø³ÙŸØ§ÙÙØ§ÙÙØ Ù ÙÙ
+ÚÙÙÙ Ø§ÙÚ¯ÙÙØ³Ù
+ÙØ±Ø§ÙÙ
+ Ø¢ÙØ±Ø¯Ù Ø§ÙØ¯. Ø¯Ø± Ø¶Ù
+Ù ÙÙ
+ÙÙÙ ÙØ§ÙÙ Ø§Ø² Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Ù Ù
+ÙØ³ÛÙÛ ÙÙØ² Ù
+ÙØ¬ÙØ¯ ÙØ³ØªÙØ¯.}  
+
+_textplatformtitle_ [l=fa] {Ø³ÙÙ}  
+_textgreenstone3_ [l=fa] {Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ØšØ± Ø±ÙÙ Ø³ÙØ³ØªÙ
+ Ø¹Ø§Ù
+ÙÙØ§Ù Windows, Unix Ù Mac OSX Ø±Ø§Ù Ø§ÙØ¯Ø§Ø²Ù Ù
+Ù ØŽÙØ¯. ØªÙØ²ÙØ¹ ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± ØŽØ§Ù
+Ù ÙØ³Ø®Ù 
+Ø¢Ù
+Ø§Ø¯Ù Ù ÙØ§ØšÙ Ø§Ø³ØªÙØ§Ø¯Ù ØšØ±Ø§Ù ØªÙ
+Ø§Ù
+Ù Ø³ÙØ³ØªÙ
+ Ø¹Ø§Ù
+ÙÙØ§Ù ÙÙÙ Ø§ÙØ°ÙØ± Ø§Ø³Øª ÙÙ ØšÙ ØµÙØ±Øª ÙØ¯ Ù
+ÙØšØ¹ ØšØ§Ø² ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ø²ØšØ§ÙÙØ§Ù
+C++ ÙØ§ gcc ÙØ±Ø§ÙÙ
+ Ù
+Ù Ú¯Ø±Ø¯Ø¯. Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ØšØ§ ÙØ±Ù
+ Ø§ÙØ²Ø§Ø±ÙØ§Ù Ø±Ø§ÙÚ¯Ø§Ù ÙÙ
+Ø±Ø§Ù Ø®ÙØ¯ ÙØ§Ø± Ù
+Ù ÙÙØ¯: 
+Apache Webserver Ù PERL. Ø±Ø§ØšØ· ÙØ§Ø±ØšØ± ÙÙØ² Ø§Ø² Ù
+Ø±ÙØ±Ú¯Ø±ÙØ§Ù Ø¹Ù
+Ø¯Ù ÙØš Ù
+Ø«Ù Netscape Navigator Ù Internet Explorer Ø§Ø³ØªÙØ§Ø¯Ù Ù
+Û Ú©ÙØ¯.}  
+
+_textgreenstone4_ [l=fa] {ØšØ³ÙØ§Ø±Ù Ø§Ø² Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§Ù Ø§Ø³ÙØ§Ø¯ ØšØ± Ø±ÙÙ CD-ROM Ù ØšØ§ ØšÙØ±Ù Ú¯ÙØ±Ù Ø§Ø² ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ù
+ÙØªØŽØ± Ù
+Ù Ú¯Ø±Ø¯ÙØ¯.
+ØšØ±Ø§Ù ÙÙ
+ÙÙÙ <i>Humanity Development Library</i> Ù
+ØŽØªÙ
+Ù ØšØ± 1Ø230 Ø³ÙØ¯ Ø§Ø² Ø¹ÙÙÙ
+ Ø­Ø³Ø§ØšØ¯Ø§Ø±Ù Ú¯Ø±ÙØªÙ ØªØ§ Ø§ØµÙÙ ØšÙØ³Ø§Ø²Ù ØªØµÙÙÙ ÙØ§Ø¶ÙØ§Øš Ø§Ø³Øª. Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ØšØ±Ø±ÙÙ ÙØ§Ù
+ÙŸÙÙØªØ±ÙØ§Ù Ø­ØªÙ ØšØ§ ÙÙ
+ØªØ±ÙÙ Ø§Ù
+ÙØ§ÙØ§Øª ÙØ±Ù
+ Ø§ÙØ²Ø§Ø±Ù Ù Ø³Ø®Øª Ø§ÙØ²Ø§Ø±Ù 
+ÙÙ Ø¯Ø± ÙØŽÙØ±ÙØ§Ù Ø¯Ø±Ø­Ø§Ù ØªÙØ³Ø¹Ù ÙÙØ² ÙØ§ÙØª Ù
+Ù Ú¯Ø±Ø¯Ø¯Ø Ø±Ø§Ù Ø§ÙØ¯Ø§Ø²Ù Ù
+Ù ØŽÙØ¯. Ø§Ø·ÙØ§Ø¹Ø§Øª Ù
+ÙØ¬ÙØ¯ Ø§Ø² Ø·Ø±Ù Ù
+Ø®ØªÙÙ ÙØ§ØšÙ Ø¯Ø³ØªØ±Ø³Ù ÙØ³ØªÙØ¯ Ø§Ø² Ø¬Ù
+ÙÙ Ø¬Ø³ØªØ¬ÙØ Ù
+Ø±ÙØ± Ù
+ÙØ¶ÙØ¹ÙØ Ù
+Ø±ÙØ± ØšØ± Ø§Ø³Ø§Ø³ Ø¹ÙÙØ§ÙØ Ø³Ø§Ø²Ù
+Ø§Ù Ù Ø­ØªÙ Ù
+ØŽØ§ÙØ¯Ù Ù
+Ø±ÙØ±Ù Ø¬ÙØ¯ Ù
+ÙØ§ØšØ¹...}  
+
+_textcustomisationtitle_ [l=fa] {Ø³Ø§Ø®Øª ØšØ± Ø§Ø³Ø§Ø³ Ø³ÙØ§Ø±ØŽ}  
+
+
+_textdocumentationtitle_ [l=fa] {Ù
+Ø³ØªÙØ¯Ø³Ø§Ø²Ù}  
+_textdocuments_ [l=fa] {Ù
+Ø³ØªÙØ¯Ø³Ø§Ø²Ù ØšØ³ÙØ·Ù ØšØ±Ø§Ù ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ù
+ÙØ¬ÙØ¯ Ø§Ø³Øª.}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=fa] {Ú¯Ø±ÙÙ ØšØ­Ø« ØšÙØ³ÛÙÙ Ø§ÛÙ
+ÛÙ}  
+_textmailinglist_ [l=fa] {ÙÙØ³ØªÙ Ø§Ø² ÙŸØ³ØªÙØ§Ù Ø§ÙÙØªØ±ÙÙÙÙÙ Ø¬ÙØª ØšØ­Ø« Ø¯Ø± ØšØ§Ø±Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ØšÙ ÙØ¬ÙØ¯ Ø¢Ù
+Ø¯Ù Ø§ÙØ¯. ÙØ§Ø±ØšØ±Ø§Ù ÙØ¹Ø§Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø­ØªÙ
+Ø§ ØšØ§ÙØ¯ Ø¯Ø± Ø§ÙÙ ØšØ­Ø«ÙØ§ ØŽØ±ÙØª Ø¯Ø§ØŽØªÙ ØšØ§ØŽÙØ¯.
+Ø¬ÙØª Ø¹Ø¶ÙÙØª Ù Ù
+ØŽØ§Ø±ÙØª Ø¯Ø± Ø§ÙÙ Ú¯Ø±ÙÙ Ø¢Ø¯Ø±Ø³ Ø²ÙØ± ØšØ±ÙÙØ¯: <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>
+ÙÙ
+ÚÙÙÙ Ø¬ÙØª ØŽØ±ÙØª Ø¯Ø± Ù
+ØšØ§Ø­Ø« ØšÙ Ø§ÙÙ Ø¢Ø¯Ø±Ø³ ÙŸÙØ§Ù
+ Ø§Ø±Ø³Ø§Ù ÙÙÙØ¯: <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>}  
+
+_textbugstitle_ [l=fa] {Ø®Ø·Ø§ÙØ§}  
+_textreport_ [l=fa] {Ø§Ø² Ø¢ÙØ¬Ø§ ÙÙ Ù
+Ø§ ÙØµØ¯ Ø¯Ø§Ø±ÙÙ
+ Ø§Ø² ÙØ§Ø±Ø§ÙÙ ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ù
+Ø·ÙØ¹ ØŽÙÙÙ
+Ø ÙØ·ÙØ§ ÙØ± ÙÙØ¹ Ø®Ø·Ø§ÙÙ Ø±Ø§ Ø¯Ø± Ø­ÙÙ ÙØ§Ø±
+ØšØ§ Ø¢Ù ØšÙ Ø¢Ø¯Ø±Ø³ Ø²ÙØ± Ú¯Ø²Ø§Ø±ØŽ Ø¯ÙÙØ¯:<a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>}  
+
+_textgs3title_ [l=fa] {Ø¯Ø± Ø¢Ø«Ø§Ø±}  
+_textgs3_ [l=fa] {Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ 3 Ø·Ø±Ø§Ø­Ù Ø¯ÙØšØ§Ø±Ù Ù Ù
+ÙÙ
+ÙÙ Ø¹Ø§ÙÙ ØšØ±Ø§Ù ÙØ³Ø®Ù ÙØšÙÙ Ø¢Ù(Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ 2) Ø§Ø³Øª ÙÙ Ø¹ÙØ§ÙÙ ØšØ± Ø¯Ø§Ø±Ø§ ØšÙØ¯Ù
+Ù
+Ø²Ø§ÙØ§Ù ÙØ³Ø®Ù ÙØ§ Ù ÙØšÙÙ Ø§Ø² Ø¬Ù
+ÙÙ ÚÙØ¯ Ø²ØšØ§ÙÙ ØšÙØ¯ÙØ multiplatformØ ØªÙØ§ÙØ§ÙÙ ÙŸÙÙØ± Ø³Ø§Ø²Ù Ø¹Ø§ÙÙØ 
+ØšÙ Ú¯ÙÙÙ Ø§Ù ØšÙÙÙÙ ØªØ± Ù Ø¯ÙØ¯Ú¯Ø§ÙÙØ§Ù ØªØ®ØµØµÙ ØªØ± Ø§Ø±ØªÙØ§Ø¡ ÙØ§ÙØªÙ Ø§Ø³Øª. Ø§ÙÙ ÙØ³Ø®Ù ØªÙ
+Ø§Ù
+Ù ÙÙÚÚ¯ÙÙØ§Ù Ø³ÙØ³ØªÙ
+ ÙØ¹ÙÙ Ø±Ø§ ØšØ§ ÙØ§Ø³ØªÙÙØ§Ù 
+Ø§Ø±ØªÙØ§Ø¡ Ø¯Ø§Ø¯Ù ØŽØ¯Ù ØªØ±ÙÙØš ÙÙ
+ÙØ¯Ù : Ø§Ø² Ø¬Ù
+ÙÙ Ø§ÙÙÙÙ ØªÙØ§ÙØ§ÙÙ Ø³Ø§Ø®ØªÙ Ù Ø§Ø¬Ø±Ø§Ù Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ¹ÙÙ Ø±Ø§ ØšØ¯ÙÙ Ø§ØµÙØ§Ø­ Ù ØªØºÙÙØ± Ø¯Ø§Ø±Ø§Ø³Øª. 
+Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ø²ØšØ§Ù Ø¬Ø§ÙØ§Ø Ø¢Ù Ø±Ø§ ØšØ¹ÙÙØ§Ù ØŽØšÙÙ Ø§Ù Ø§Ø² Ù
+Ø§ÚÙÙÙØ§Ù Ù
+Ø³ØªÙÙ ØšØ§ Ø§Ù
+ÙØ§Ù Ø§Ø±ØªØšØ§Ø· ØšØ§ Ø²ØšØ§Ù XML Ø³Ø§Ø®ØªØ§Ø± ÙØ§ÙØªÙ Ø§Ø³Øª: ØšÙØ§ØšØ±Ø§ÙÙ 
+Ù
+Ù ØªÙØ§ÙØ¯ ØšØ± Ø±ÙÙ Ø³Ø±ÙØ±ÙØ§Ù Ù
+Ø®ØªÙÙ Ø¯Ø± ØµÙØ±Øª ÙØ²ÙÙ
+ Ø±Ø§Ù Ø§ÙØ¯Ø§Ø²Ù Ù Ø§Ø¬Ø±Ø§ Ú¯Ø±Ø¯Ø¯.
+Ø§ÙÙ Ù
+Ø¯Ù ÙŸÙØŽ Ø³Ø§Ø®ØªÙ ÙØ§ØšÙÙØª Ø§ÙØ¹Ø·Ø§Ù Ù ØªÙØ³Ø¹Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø±Ø§ Ø§ÙØ²Ø§ÙØŽ Ù
+Ù Ø¯ÙØ¯. Ù
+Ø³ØªÙØ¯Ø³Ø§Ø²Ù Ù Ø§ÙØªØŽØ§Ø± Ø¢Ø²Ù
+Ø§ÙØŽÙ Ú¯ÙÙ Ø§Ø³ØªÙÙ 3 
+ØšØ§ Ø¯Ø§ÙÙÙØ¯ Ø§Ø² Ø·Ø±ÙÙ ÙØš Ø³Ø§ÙØª Ø¢Ù Ù
+ÙØ³Ø± Ø§Ø³Øª.<a href="http://www.greenstone.org/greenstone3.html">Greenstone 3 home page</a>}  
+
+_textcreditstitle_ [l=fa] {Ø§Ø¹ØªØšØ§Ø±ÙØ§}  
+
+_textwhoswho_ [l=fa] {Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø­Ø§ØµÙ ØªÙØ§ØŽÙ Ù
+ØŽØªØ±Ù Ù
+Ø§ØšÙÙ Ø§ÙØ±Ø§Ø¯ Ø²ÙØ§Ø¯Ù Ø§Ø³Øª.Rodger McNab Ù Stefan Boddie ØšØ§ÙÙØ§Ù Ø§ØµÙÙ Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ÙØ³ØªÙØ¯ 
+Ù ÙÙ
+ÙØ§Ø±Ø§Ù Ø§ØµÙÙ Ø¯Ø± Ø§ÙÙ ÙŸØ±ÙÚÙ Ø¹ØšØ§Ø±ØªÙØ¯ Ø§Ø²: David Bainbridge, George
+Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John
+McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd
+Reed, Bill Rogers, John Thompson, Ù Stuart Yeates.
+Ø³Ø§ÙØ± ÙŸØ±ÙÚÙ ÙØªØ§ØšØ®Ø§ÙÙ Ø¯ÙØ¬ÙØªØ§Ù ÙÙÙØ²ÙÙÙØ¯ ÙÙ ØšÙ ÙØ± ÙØ­ÙÙ ØšØ§ Ø§ÙØ¯Ù ÙØ§ Ù ÙØžØ±Ø§Øª Ø®ÙØ¯ Ù
+Ø§ Ø±Ø§ Ø¯Ø± Ø·Ø±Ø§Ø­Ù Ø³ÙØ³ØªÙ
+ ÙØ§Ø±Ù ÙÙ
+ÙØ¯ÙØ¯ Ø¹ØšØ§Ø±ØªÙØ¯ Ø§Ø²:
+Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka
+Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols Ù Lloyd Smith.
+Ø¯Ø± Ø§ÙÙØ¬Ø§ ÙØ§Ø²Ù
+ Ø§Ø³Øª ÙÙ Ø§Ø² Ø§ÙØ±Ø§Ø¯Ù ÙÙ Ø¯Ø± Ø§ÙØªØŽØ§Ø± ØšØ³ØªÙ ÙØ§Ù Ù
+Ø¬ÙØ²Ø¯Ø§Ø±  GNU (MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE Ù XLHTML)Ù
+Ø§ Ø±Ø§ ÙØ§Ø±Ù Ø¯Ø§Ø¯ÙØ¯ ØªØŽÙØ± Ù ÙØ¯Ø±Ø¯Ø§ÙÙ Ø®ÙØ¯ Ø±Ø§ Ø§ØšØ±Ø§Ø² ÙÙÙÙ
+.}  
+
+_textaboutgslong_ [l=fa] {Ø¯Ø±ØšØ§Ø±Ù ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=fa] {ÙÙØ³Øª ÙØ§Ø±ØšØ±Ø§Ù Ø¬Ø§Ø±Ù}  
+_textuser_ [l=fa] {ÙØ§Ø±ØšØ±}  
+_textas_ [l=fa] {ÙØ¶Ø¹ÙØª Ø­Ø³Ø§Øš ÙØ§Ù ÙØ§Ø±ØšØ±Ù}  
+_textgroups_ [l=fa] {Ú¯Ø±ÙÙ ÙØ§}  
+_textcomment_ [l=fa] {ØªÙØ¶ÙØ­}  
+_textadduser_ [l=fa] {Ø§ÙØ²ÙØ¯Ù ÙØ§Ø±ØšØ± Ø¬Ø¯ÙØ¯}  
+_textedituser_ [l=fa] {ÙÙØ±Ø§ÙØŽ ÙØ±Ø¯Ù}  
+_textdeleteuser_ [l=fa] {Ø­Ø°Ù ÙØ±Ø¯Ù}  
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=fa] {ÙÙØ±Ø§ÙØŽ Ø§Ø·ÙØ§Ø¹Ø§Øª ÙØ§Ø±ØšØ±}  
+_textadduser_ [l=fa] {Ø§Ø¶Ø§ÙÙ ÙÙ
+ÙØ¯Ù ÙØ§Ø±ØšØ± Ø¬Ø¯ÙØ¯}  
+
+_textaboutusername_ [l=fa] {ÙØ§Ù
+ ÙØ§Ø±ØšØ±Ù ØšØ§ÙØ¯ ØšÙÙ 2 ØªØ§ 30 ÙØ§Ø±Ø§ÙØªØ± ØšØ§ØŽØ¯ ÙÙ Ù
+Ù ØªÙØ§ÙØ¯ ØŽØ§Ù
+Ù ÙØ§Ø±Ø§ÙØªØ±ÙØ§ Ø§ÙÙØšØ§ÙÙØ '.', Ù '_' ØšØ§ØŽØ¯.}  
+
+_textaboutpassword_ [l=fa] {Ø±Ù
+Ø²Ø¹ØšÙØ±ÙØ§ ØšØ§ÙØ¯ ØšÙÙ 3 ØªØ§ 128 ÙØ§Ø±Ø§ÙØªØ± ØšØ§ØŽÙØ¯ ÙÙ Ù
+Ù ØªÙØ§ÙÙØ¯ ØŽØ§Ù
+Ù ÙØ± ÙØ§Ø±Ø§ÙØªØ± ÙØ§ØšÙ ÚØ§ÙŸ Ø¯Ø± ÙØ±Ù
+Øª ASCII ØšØ§ØŽÙØ¯.}  
+
+_textoldpass_ [l=fa] {Ø§Ú¯Ø± Ø§ÙÙ ÙÙÙØ¯ Ø®Ø§ÙÙ Ø§Ø³Øª Ø±Ù
+Ø² Ø¹ØšÙØ± ÙØ¯ÙÙ
+Ù ÙÚ¯ÙØ¯Ø§Ø±Ù Ø®ÙØ§ÙØ¯ ØŽØ¯.}  
+_textenabled_ [l=fa] {ÙØ¹Ø§Ù}  
+_textdisabled_ [l=fa] {ØºÙØ±ÙØ¹Ø§Ù}  
+
+_textaboutgroups_ [l=fa] {ÙÙØ³ØªÙØ§ÙÙ ÙÙ ØšØ§ ÙØ§Ù
+Ø§ Ø¬Ø¯Ø§ ØŽØ¯Ù Ø§ÙØ¯ Ú¯Ø±ÙÙ ÙØ³ØªÙØ¯Ø ÙØ·ÙØ§ ØšØ¹Ø¯ Ø§Ø² ÙØ§Ù
+Ø§ÙØ§ ÙØ§ØµÙÙ ÙÚ¯Ø°Ø§Ø±ÙØ¯}  
+
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=fa] {Ø­Ø°Ù ÙÙ ÙØ§Ø±ØšØ±}  
+_textremwarn_ [l=fa] {Ø¢ÙØ§ ØŽÙ
+Ø§ ÙØ§ÙØ¹Ø§ Ù
+Ù Ø®ÙØ§ÙÙØ¯ ØšØ±Ø§Ù ÙÙ
+ÙØŽÙ ÙØ§Ø±ØšØ± Ø±Ø§ Ø­Ø°Ù ÙÙÙØ¯<b>_cgiargumun_</b>Ø}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=fa] {Ø±Ù
+Ø²Ø¹ØšÙØ± Ø±Ø§ ØªØºÙÙØ± Ø¯ÙÙØ¯.}  
+_textoldpw_ [l=fa] {Ø±Ù
+Ø²Ø¹ØšÙØ± ÙØ¯ÙÙ
+Ù}  
+_textnewpw_ [l=fa] {Ø±Ù
+Ø² Ø¹ØšÙØ± Ø¬Ø¯ÙØ¯}  
+_textretype_ [l=fa] {Ø±Ù
+Ø² Ø¹ØšÙØ± Ø¬Ø¯ÙØ¯ Ø±Ø§ ÙØ§Ø±Ø¯ ÙÙÙØ¯.}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=fa] {Ø±Ù
+Ø² Ø¹ØšÙØ± ØŽÙ
+Ø§ ØšØ§ Ù
+ÙÙÙÙØª ØªØºÙÙØ± ÙØ§ÙØª.}  
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=fa] {ÙØ§Ù
+ ÙØ§Ø±ØšØ±Ù ÙØ§Ø¯Ø±Ø³Øª Ø§Ø³Øª.}  
+_textinvalidpassword_ [l=fa] {Ø±Ù
+Ø² Ø¹ØšÙØ± ÙØ§Ø¯Ø±Ø³Øª Ø§Ø³Øª.}  
+_textemptypassword_ [l=fa] {ÙØ·ÙØ§ Ø±Ù
+Ø² Ø¹ØšÙØ± Ø¢ØºØ§Ø²ÙÙ Ø±Ø§ ØšØ±Ø§Ù Ø§ÙÙ ÙØ§Ø±ØšØ± ÙØ§Ø±Ø¯ ÙÙ
+Ø§ÙÙØ¯}  
+_textuserexists_ [l=fa] {Ø§ÙÙ ÙØ§Ø±ØšØ± Ø§Ø² ÙŸÛØŽ Ù
+ÙØ¬ÙØ¯ Ø§Ø³ØªØ ÙØ·ÙØ§ ÙØ§Ù
+ ÙØ§Ø±ØšØ±Ù Ø¯ÙÚ¯Ø±Ù ÙØ§Ø±Ø¯ ÙÙÙØ¯.}  
+
+_textusernameempty_ [l=fa] {ÙØ·ÙØ§ ÙØ§Ù
+ ÙØ§Ø±ØšØ±Ù Ø±Ø§ ÙØ§Ø±Ø¯ ÙÙÙØ¯.}  
+_textpasswordempty_ [l=fa] {ØŽÙ
+Ø§ ØšØ§ÙØ¯ Ø±Ù
+Ø² Ø¹ØšÙØ± ÙØ¯ÙÙ
+Ù Ø®ÙØ¯ Ø±Ø§ ÙØ§Ø±Ø¯ ÙÙÙØ¯.}  
+_textnewpass1empty_ [l=fa] {Ø±Ù
+Ø² Ø¹ØšÙØ± Ø¬Ø¯ÙØ¯ Ø®ÙØ¯ Ø±Ø§ ÙØ§Ø±Ø¯ ÙÙÙØ¯ Ø³ÙŸØ³ Ø¢Ù Ø±Ø§ Ù
+Ø¬Ø¯Ø¯Ø§ ÙØ§Ø±Ø¯ ÙÙÙØ¯.}  
+_textnewpassmismatch_ [l=fa] {Ø±Ù
+Ø²Ø¹ØšÙØ±ÙØ§Ù ØŽÙ
+Ø§ Ù
+Ø·Ø§ØšÙØª ÙØ¯Ø§Ø±Ø¯.}  
+_textnewinvalidpassword_ [l=fa] {ØŽÙ
+Ø§ ÙÙ Ø±Ù
+Ø² Ø¹ØšÙØ± ÙØ§Ø¯Ø±Ø³Øª ÙØ§Ø±Ø¯ ÙÙ
+ÙØ¯Ù Ø§ÙØ¯.}  
+_textfailed_ [l=fa] {Ø±Ù
+Ø² Ø¹ØšÙØ± ÙØ§ ÙØ§Ù
+ ÙØ§Ø±ØšØ±Ù ØŽÙ
+Ø§ ÙØ§Ø¯Ø±Ø³Øª ØšÙØ¯.}  
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=fa] {ØŽÙ
+Ø§Ø±Ù ÙØ³Ø®Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}  
+_textframebrowser_ [l=fa] {Ø¬ÙØª Ù
+ØŽØ§ÙØ¯Ù Ø§ÙÙ ØšØ§ÙØ¯ ÙØ§ÙØšÙ Ø±Ø§ Ø¯Ø§ØŽØªÙ ØšØ§ØŽÙØ¯ ÙÙ Ø§Ù
+ÙØ§Ù Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ù
+Ø±ÙØ±Ú¯Ø± Ø±Ø§ Ø¯Ø§ØŽØªÙ ØšØ§ØŽØ¯.}  
+_textusermanage_ [l=fa] {Ù
+Ø¯ÙØ±ÙØª ÙØ§Ø±ØšØ±}  
+_textlistusers_ [l=fa] {ÙÙØ³Øª ÙÙ
+ÙØ¯Ù ÙØ§Ø±ØšØ±Ø§Ù}  
+_textaddusers_ [l=fa] {Ø§ÙØ²ÙØ¯Ù ÙØ§Ø±ØšØ± Ø¬Ø¯ÙØ¯}  
+_textchangepasswd_ [l=fa] {ØªØºÙÙØ± Ø¯Ø§Ø¯Ù Ø±Ù
+Ø² Ø¹ØšÙØ±}  
+_textinfo_ [l=fa] {Ø§Ø·ÙØ§Ø¹Ø§Øª ÙÙÙ}  
+_textgeneral_ [l=fa] {Ø¹Ù
+ÙÙ
+Ù}  
+_textarguments_ [l=fa] {Ø¢Ø±Ú¯ÙÙ
+Ø§Ù ÙØ§}  
+_textactions_ [l=fa] {Ø¹Ù
+Ù ÙØ§}  
+_textbrowsers_ [l=fa] {Ù
+Ø±ÙØ±Ú¯Ø±ÙØ§}  
+_textprotocols_ [l=fa] {ÙŸØ±ÙØªÙÙÙØ§}  
+_textconfigfiles_ [l=fa] {ÙØ§ÛÙÙØ§Û ÙŸÙÙØ±ØšÙØ¯Ù}  
+_textlogs_ [l=fa] {Ø«ØšØª ÙÙØ§ÙØ¹}  
+_textusagelog_ [l=fa] {Ø«ØšØª ÙÙØ§ÙØ¹ ÙØ§Ø±ØšØ±Ø¯ÙŸØ°ÛØ±Û}  
+_textinitlog_ [l=fa] {Ø«ØšØª ÙÙØ§ÙØ¹ Ø¢ØºØ§Ø²ÙÙ}  
+_texterrorlog_ [l=fa] {Ø«ØšØª ÙÙØ§ÙØ¹ Ø®Ø·Ø§ÙØ§}  
+_textadminhome_ [l=fa] {ØµÙØ­Ù Ø§ØµÙÛ Ù
+Ø¯ÙØ±}  
+_textreturnhome_ [l=fa] {ØµÙØ­Ù Ø®Ø§ÙÚ¯Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}  
+_titlewelcome_ [l=fa] {Ù
+Ø¯ÙØ±ÙØª}  
+_textmaas_ [l=fa] {Ø®Ø¯Ù
+Ø§Øª Ù
+Ø¯ÙØ±ÙØª Ù ØªØ¹Ù
+ÙØ± Ù ÙÚ¯ÙØ¯Ø§Ø±Ù Ù
+ÙØ¬ÙØ¯ Ø¹ØšØ§Ø±ØªÙØ¯ Ø§Ø²:}  
+_textvol_ [l=fa] {Ù
+ØŽØ§ÙØ¯ Ø«ØšØª ÙÙØ§ÙØ¹ÙØ§Ù ÙŸÙÙØ³ØªÙ}  
+_textcmuc_ [l=fa] {Ø®ÙÙØ ÙÚ¯ÙØ¯Ø§Ø±Ù Ù Ø±ÙØ²Ø¢Ù
+Ø¯Ø³Ø§Ø²Ù Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§}  
+_textati_ [l=fa] {Ø¯Ø³ØªØ±Ø³Ù ØšÙ Ø§Ø·ÙØ§Ø¹Ø§Øª ÙÙÙ ÙÙ
+Ø§ÙÙØ¯ Ù
+ØšØ§Ø­Ø« Ù
+Ø±ØšÙØ· ØšÙ CGI}  
+
+_texttsaa_ [l=fa] {Ø§ÙÙ Ø®Ø¯Ù
+Ø§Øª ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² ÙÙØ§Ø± Ø±Ø§ÙØšØ±Ù Ø³Ù
+Øª ÚÙŸ ØµÙØ­Ù ÙØ§ØšÙ Ø¯Ø³ØªØ±Ø³Ù Ø§Ø³Øª.}  
+
+_textcolstat_ [l=fa] {ÙØ¶Ø¹ÙØª Ù
+Ø¬Ù
+ÙØ¹Ù}  
+
+_textcwoa_ [l=fa] {Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ ØµØ±ÙØ§ ÙÙÚ¯Ø§Ù
+Û ØšØ§ Ø¹ÙÙØ§Ù Ø¯Ø± Ø­Ø§Ù Ø±Ø§Ù Ø§ÙØ¯Ø§Ø²Û ØžØ§ÙØ± Ù
+Û ØŽÙÙØ¯ Ú©Ù ÙØ§ÛÙÙØ§Û 
+build.cfg 
+Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ Ù
+ÙØ¬ÙØ¯ Ù ÙØ§ØšÙ Ø®ÙØ§ÙØ¯Ù ØšØ§ØŽÙØ¯Ø 
+Ø­Ø§ÙÛ ÙØ§ÛÙ ØªØ§Ø±ÛØ® Ø³Ø§Ø®Øª Ù
+Ø¹ØšØªØ± ØšØ§ØŽÙØ¯ Ù Ø¯Ø± Ø¯Ø§ÛØ±Ú©ØªÙØ±Û ÙÙ
+Ø§ÛÙ Ù
+Ø¬Ù
+ÙØ¹Ù ÙØ§ ÙØ¬ÙØ¯ Ø¯Ø§ØŽØªÙ ØšØ§ØŽÙØ¯.}  
+
+_textcafi_ [l=fa] {<i>abbrev.</i> Ø±Ø§ ØšØ±Ø§Ù Ø§Ø·ÙØ§Ø¹Ø§Øª Ù
+Ø±ØšÙØ· ØšÙ Ù
+Ø¬Ù
+ÙØ¹Ù ÙÙÙÙ ÙÙÙØ¯}  
+_textcctv_ [l=fa] {<i>collection</i>Ø±Ø§ Ø¬ÙØª Ù
+ØŽØ§ÙØ¯Ù Ù
+Ø¬Ù
+ÙØ¹Ù ÙÙÙÙ ÙÙÙØ¯}  
+_textsubc_ [l=fa] {Ø«ØšØª ØªØºÙÙØ±Ø§Øª}  
+_texteom_ [l=fa] {Ø®Ø·Ø§ Ø¯Ø± ØšØ§Ø²Ú©Ø±Ø¯Ùmain.cfg}  
+_textftum_ [l=fa] {Ø±ÙØ²Ø¢Ù
+Ø¯Ø³Ø§Ø²Ù main.cfg ØšØ§ Ù
+ÙÙÙÙØª Ø§ÙØ¬Ø§Ù
+ ÙØŽØ¯.}  
+_textmus_ [l=fa] {main.cfgØšØ§ Ù
+ÙÙÙÙØª Ø±ÙØ²Ø¢Ù
+Ø¯ ØŽØ¯.}  
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=fa] {ÙØ·ÙØ§ Ø®ÙØ§ØµÙ Ù
+Ø±ØšÙØ· ØšÙ Ù
+Ø¬Ù
+ÙØ¹Ù "_collectionname_" Ø±Ø§  Ø§ÛØ¬Ø§Ø¯ Ú©ÙÛØ¯}  
+_textflog_ [l=fa] {Ø¹Ù
+ÙÙØ§Øª ÙØ±ÙØ¯ ØšÙ Ù
+Ø¬Ù
+ÙØ¹Ù "_collectionname_" Ø±Ø¯ ØŽØ¯.}  
+_textilog_ [l=fa] {ØµÙØ±Øª Ø¹Ù
+ÙÙØ§Øª ØšØ±Ø§Ù Ù
+Ø¬Ù
+ÙØ¹Ù "_collectionname_" Ø±Ø§ ÙØ§Ø±Ø¯ ÙÙÙØ¯.}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=fa] {ÙØ±Ø³ØªØ§Ø¯Ù ØšØ§Ø²Ø®ÙØ±Ø¯}  
+
+_greenstoneusabilitytext_ [l=fa] {Ø§Ø³ØªÙØ§Ø¯Ù ÙŸØ°ÛØ±Û Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}  
+
+_textwhy_ [l=fa] {<p> Ø§Ø±Ø³Ø§Ù Ø§ÙÙ Ú¯Ø²Ø§Ø±ØŽ ØšÙØ§ÙÚ¯Ø± Ø§ÙÙ Ø§Ø³Øª ÙÙ ØµÙØ­Ù ÙØšÙ Ø±Ø§ ÙÙ ØŽÙ
+Ø§ Ø¯Ø± Ø­Ø§Ù Ù
+ØŽØ§ÙØ¯Ù Ø¢Ù ÙØ³ØªÙØ¯ Ø¯Ø§Ø±Ø§Ù Ù
+ØŽÙÙ Ù ÙØ§ Ø§Ù
+ÙØ¯ ÙÙÙØ¯Ù Ø§Ø³Øª.}  
+_textextraforform_ [l=fa] {You do not have to fill out the form -- any information will help.
+	ÙØ§Ø²Ù
+ ÙÙØ³Øª ÙØ±Ù
+ Ø±Ø§ ØªÙÙ
+ÙÙ ÙÙÙØ¯-- ÙØ± Ø§Ø·ÙØ§Ø¹Ø§ØªÙ Ù
+Ù ØªÙØ§ÙØ¯ ÙÙ
+Ù ÙÙÙØ¯Ù ØšØ§ØŽØ¯.}  
+_textprivacybasic_ [l=fa] {Ú¯Ø²Ø§Ø±ØŽ ØµØ±ÙØ§ Ø­Ø§ÙÙ Ø§Ø·ÙØ§Ø¹Ø§ØªÙ Ø¯Ø± ØšØ§Ø±Ù ØµÙØ­Ù ÙØš Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø®ÙØ§ÙØ¯ ØšÙØ¯ ÙÙ ØŽÙ
+Ø§ Ø¯Ø± Ø­Ø§Ù Ù
+ØŽØ§ÙØ¯Ù Ø¢Ù
+ØšÙØ¯ÙØ¯Ø Ù ØªÙÙÙÙÙâÚÙ Ø§Ù ÙÙ ØŽÙ
+Ø§ Ø¬ÙØª Ù
+ØŽØ§ÙØ¯Ù Ø¢Ù Ø§Ø³ØªÙØ§Ø¯Ù Ù
+Ù ÙØ±Ø¯ÙØ¯(ØšØ¹ÙØ§ÙÙ ÙÙ Ø³Ø±Ù Ø§Ø·ÙØ§Ø¹Ø§Øª Ø§ÙØªØ®Ø§ØšÙ ÙÙ ØŽÙ
+Ø§ ÙØ±Ø§ÙÙ
+ Ø¢ÙØ±Ø¯Ù Ø§ÙØ¯.)}  
+_textstillsend_ [l=fa] {Ø¢ÙØ§ ØŽÙ
+Ø§ ÙÙÙØ² Ø®ÙØ§ÙØ§Ù Ø§Ø±Ø³Ø§Ù Ø§ÙÙ Ú¯Ø²Ø§Ø±ØŽ ÙØ³ØªÙØ¯Ø}  
+
+_texterror_ [l=fa] {Ø®Ø·Ø§}  
+_textyes_ [l=fa] {ØšÙÛ}  
+_textno_ [l=fa] {ÙÙ}  
+_textclosewindow_ [l=fa] {ØšØ³ØªÙ ÙŸÙØ¬Ø±Ù}  
+_textabout_ [l=fa] {Ø¯Ø±ØšØ§Ø±Ù}  
+_textprivacy_ [l=fa] {Ù
+Ø­Ø±Ù
+Ø§ÙÚ¯Ù}  
+_textsend_ [l=fa] {ÙØ±Ø³ØªØ§Ø¯Ù}  
+_textdontsend_ [l=fa] {ÙÙ
+Ù ÙØ±Ø³ØªØ¯}  
+_textoptionally_ [l=fa] {Ø§ÙØªØ®Ø§ØšÙ}  
+
+_textunderdev_ [l=fa] {ÙÙ
+Ø§ÙØŽ Ø¬Ø²ØŠÙØ§Øª Ø¯Ø± ÙØ³Ø®Ù ÙÙØ§ÙÙ Ù
+ÙØ¬ÙØ¯ Ø®ÙØ§ÙØ¯ ØšÙØ¯.}  
+
+_textviewdetails_ [l=fa] {Ù
+ØŽØ§ÙØ¯Ù Ø¬Ø²ØŠÙØ§Øª Ú¯Ø²Ø§Ø±ØŽ}  
+_textmoredetails_ [l=fa] {Ø¬Ø²ØŠÙØ§Øª ØšÙØŽØªØ±}  
+_texttrackreport_ [l=fa] {Ø±Ø¯ÙØ§ØšÙ ÙØ±Ø¯Ù Ø§ÙÙ Ú¯Ø²Ø§Ø±ØŽ}  
+_textcharacterise_ [l=fa] {ÚÙ ÙÙØ¹ Ù
+ØŽÙÙÙ Ø§Ø³Øª}  
+_textseverity_ [l=fa] {Ù
+ØŽÚ©Ù ØªØ§ ÚÙ Ø­Ø¯ Ø¬Ø¯Û Ø§Ø³Øª}  
+ 
+_textbadrender_ [l=fa] {ØµÙØ­Ù ÙØ§ØŽÙØ§Ø®ØªÙ Ø§Ø³Øª}  
+_textcontenterror_ [l=fa] {Ø®Ø·Ø§Ù Ù
+Ø­ØªÙÙ}  
+_textstrangebehaviour_ [l=fa] {Ø±ÙØªØ§Ø± ÙØ§ØŽÙØ§Ø³}  
+_textunexpected_ [l=fa] {Ù
+ÙØ§Ø±Ø¯ ÙŸÙØŽ ØšÙÙÙ ÙØŽØ¯Ù Ø§Ù Ø§ØªÙØ§Ù Ø§ÙØªØ§Ø¯Ù Ø§Ø³Øª}  
+_textfunctionality_ [l=fa] {Ø¬ÙØª Ø§Ø³ØªÙØ§Ø¯Ù Ø³Ø®Øª Ø§Ø³Øª}  
+_textother_ [l=fa] {Ø¯ÙÚ¯Ø±}  
+
+_textcritical_ [l=fa] {ÙØ¶Ø¹ÙØª ØšØ­Ø±Ø§ÙÙ}  
+_textmajor_ [l=fa] {Ø¬Ø¯Ù}  
+_textmedium_ [l=fa] {Ø­Ø¯ Ù
+ØªÙØ³Ø·}  
+_textminor_ [l=fa] {ÙÙÚÙ Ù ÙØ±Ø¹Ù}  
+_texttrivial_ [l=fa] {Ø¬Ø²ØŠÙ}  
+
+_textwhatdoing_ [l=fa] {ØŽÙ
+Ø§ Ø¯Ø± ØªÙØ§ØŽÙØ¯ ÚÙ ÙØ§Ø±Ù Ø±Ø§ Ø§ÙØ¬Ø§Ù
+ Ø¯ÙÙØ¯Ø}  
+_textwhatexpected_ [l=fa] {ØŽÙ
+Ø§ Ø§ÙØªØžØ§Ø± Ø¯Ø§Ø±ÙØ¯ ÚÙ ÚÙØ²Ù Ø±Ø® Ø¯ÙØ¯Ø}  
+_textwhathappened_ [l=fa] {Ø¹Ù
+ÙØ§ ÚÙ ÚÛØ²Û ÙŸÛØŽ Ø¢Ù
+Ø¯Ø}  
+
+_cannotfindcgierror_ [l=fa] {Ù
+ØªØ§Ø³ÙØ§ÙÙ! Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ÙØ§Ø¯Ø± ØšÙ ÙŸÙØ¯Ø§ ÙØ±Ø¯Ù ØšØ±ÙØ§Ù
+Ù ÙØ§Ù Ø³Ø±ÙØ± ØšØ±Ø§Ù Ø¯ÙÙ
+Ù"_linktextusab_" ÙÙØ³Øª.}  
+
+_textusabbanner_ [l=fa] {ØšÙØ± koru-style Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}  
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=fa] {ÙÙ Ø®Ø·Ø§ Ø±Ø® Ø¯Ø§Ø¯Ù Ø§Ø³Øª}  
+
+_textgtihome_ [l=fa] {Ø§ÙÙ ØµÙØ­Ù ÙØ§ ØšÙ ØŽÙ
+Ø§ ÙÙ
+Ù Ù
+Ù ÙÙØ¯ ØªØ§ ÙŸØŽØªÙØšØ§ÙÙ ÚÙØ¯ Ø²ØšØ§ÙÙ Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø±Ø§ Ø§Ø±ØªÙØ§Ø¡ Ø¯ÙÛØ¯. ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ø¢ÙÙØ§ ØŽÙ
+Ø§ Ù
+Ù ØªÙØ§ÙÙØ¯
+<ul>
+  <li>ØšØ®ØŽÙØ§Û Ù
+ÙØ¬ÙØ¯ Ø¯Ø± Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ø±Ø§ ØšÙ Ø²ØšØ§ÙÛ Ø¬Ø¯ÛØ¯ ØªØ±Ø¬Ù
+Ù Ú©ÙÛØ¯
+  <li>Ø¯ÙÙÚ¯Ø§Ù
+Û Ú©Ù Ø±Ø§ØšØ· Ú©Ø§Ø±ØšØ± Ø§ÙÚ¯ÙÛØ³Û ØªØºÛÛØ¯ Ú©Ø±Ø¯ ØŽÙ
+Ø§ Ù
+Û ØªÙØ§ÙÛØ¯ Ø±Ø§ØšØ· Ú©Ø§Ø±ØšØ± Ù
+ÙØ¬ÙØ¯ Ø±Ø§ Ø±ÙØ²Ø¢Ù
+Ø¯ Ú©ÙÛØ¯ (ØšÙ Ø¹ÙÙØ§Ù Ù
+Ø«Ø§Ù Ø¬ÙØª ÙØ§ØšÙÛØªÙØ§Û Ø¬Ø¯ÛØ¯ Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ)
+  <li>Ø®Ø·Ø§ÙØ§ Ø±Ø§ Ø¯Ø± ØªØ±Ø¬Ù
+Ù ÙØ§Û Ù
+ÙØ¬ÙØ¯ ØªØµÛÛØ­ Ú©ÙÛØ¯
+</ul>
+ÙÙ Ø³Ø±Ù Ø§Ø² ØµÙØ­Ø§Øª ØšÙ ØŽÙ
+Ø§ ÙØŽØ§Ù Ø¯Ø§Ø¯Ù Ø®ÙØ§ÙØ¯ ØŽØ¯Ø ÙØ± ÙØ¯Ø§Ù
+ ØŽØ§Ù
+Ù Ø¹ØšØ§Ø±ØªÙ Ø§Ø³Øª ÙÙ ØšÙ ØªØ±Ø¬Ù
+Ù ÙÙØ§Ø² Ø¯Ø§Ø±Ø¯.
+ØšØ§ ØªØ±Ø¬Ù
+Ù Ø¹ØšØ§Ø±ØªÙØ§Ù Ù
+Ø®ØªÙÙ ØªØ±Ø¬Ù
+Ù Ø±Ø§ Ø§Ø¯Ø§Ù
+Ù Ø¯ÙÛØ¯. ØšØ³ÙØ§Ø±Ù Ø§Ø² Ø¹ØšØ§Ø±ØªÙØ§ Ø­Ø§ÙÙ ÙØ¯ÙØ§Ù HTML Ø§Ø³Øª ÙÙ ÙØ²ÙÙ
+Ù ØšÙ ØªØ±Ø¬Ù
+Ù
+Ø¢ÙÙØ§ ÙÙØ³Øª: ØŽÙ
+Ø§ ÙØšØ§ÙØ¯ Ø¢ÙÙØ§ Ø±Ø§ ØªØ±Ø¬Ù
+Ù ÙÙÙØ¯ ØšÙÙÙ ØšØ§ÙØ¯ Ø¢ÙÙØ§ Ø±Ø§ Ø¯Ø± Ø¬Ø§Ù Ø¯ÙÙÙ Ø®ÙØ¯ ÙØ±Ø§Ø± Ø¯ÙÙØ¯. ÙØºØ§ØªÙ ÙÙ Ø²ÙØ± Ø¢ÙÙØ§ Ø®Ø· ÙØŽÙØ¯Ù ØŽØ¯Ù Ø§Ø³Øª
+ÙÙ
+Ø§ÙÙØ¯ ( _this_) Ø±Ø§ ÙÙØ² ÙØšØ§ÙØ¯ ØªØ±Ø¬Ù
+Ù ÙÙÙØ¯.
+
+Ø§Ú¯Ø± Ø¯Ø± Ø­Ø§Ù Ø±ÙØ²Ø¢Ù
+Ø¯Ø³Ø§Ø²Û Ø±Ø§ØšØ· Ú©Ø§Ø±ØšØ± Ù
+ÙØ¬ÙØ¯ ÙØ³ØªÛØ¯ ØšØ§ Ø§ÛÙ Ø¹ØšØ§Ø±Øª Ú©Ù "ØªØ±Ø¬Ù
+Ù Ù
+ÙØ±Ø¯ ÙØžØ± ÙŸÛØŽ Ø§Ø² Ø§ÛÙ Ù
+ÙØ¬ÙØ¯ ØšÙØ¯Ù Ø±ÙØšÙ Ø±Ù ÙØ®ÙØ§ÙÛØ¯ ØŽØ¯"
+Ø¯Ø± ØšØ±Ø®Û Ù
+ÙØ§Ø±Ø¯ ØªØ±Ø¬Ù
+Ù Ù
+ÙØ¬ÙØ¯ Ø§Ø³Øª Ø§Ù
+Ø§ Ù
+ØªÙ Ø§ÙÚ¯ÙÛØ³Û ÙÙÙØ² Ø¯Ø± Ø­Ø§Ù ØªØºÛÛØ± Ù Ø§ØµÙØ§Ø­ Ø§Ø³Øª. Ø¯Ø± Ø§ÛÙ Ù
+ÙØ±Ø¯ ØªØ±Ø¬Ù
+Ù 
+Ø¬Ø§Ø±Û Ø§Ø±Ø§ØŠÙ Ø¯Ø§Ø¯Ù Ø®ÙØ§ÙØ¯ ØŽØ¯ Ù ØŽÙ
+Ø§ Ø¯Ø± ØµÙØ±Øª ÙØ²ÙÙ
+ ØšØ§ÛØ¯ Ø¢ÙØ±Ø§ ÙÛØ±Ø§ÛØŽ Ù Ø±ÙØ²Ø¢Ù
+Ø¯ Ú©ÙÛØ¯.
+<p>
+ÚÙØ§ÙÚÙ Ø¯Ø± Ø®ÙØ§Ù ÙØ§Ø± ØšØ§ Ø±Ø§ØšØ· ÙØ§Ø±ØšØ± ØšÙ Ù
+ÙØ§Ø±Ø¯Ù ØšØ±Ø®ÙØ±Ø¯ÙØ¯ ÙÙ ÙÙØ§Ø² ØšÙ ØªØµÙÙØ­ Ø¯Ø§ØŽØª Ø¢Ù Ø±Ø§ ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² Ú¯Ø²ÙÙÙ  "Correct existing translations"
+ØšØ±Ø§Ù ÙØ± ØšØ®ØŽ Ø§Ø² Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ØªØµÙÙØ­ ÙÙ
+Ø§ÙÙØ¯.
+<p>
+ÙØ± ØµÙØ­Ù ØšØ§ Ø¯ÙÙ
+Ù  "_textgtisubmit_" ØšÙ ÙŸØ§ÙØ§Ù Ù
+Ù Ø±Ø³Ø¯. ØšØ§ ÙÙÙÙ Ø§ÙÙ Ø¯ÙÙ
+Ù ØªØºÙÙØ±Ø§Øª Ø¯Ø± ÙØ§ÙÙ ÙØµØšÙ Ø¬Ø¯Ø§Ú¯Ø§ÙÙ Ø§Ù Ø¯Ø± Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ 
+nzdl.org Ø±Ø® Ø®ÙØ§ÙØ¯ Ø¯Ø§Ø¯. Ø§ÙÙ Ø¯ÙÙ
+Ù Ø¯Ø± ÙØ± ØµÙØ­Ù Ø§Ù ÙØ¬ÙØ¯ Ø¯Ø§Ø±Ø¯.}  
+
+_textgtiselecttlc_ [l=fa] {ÙØ·ÙØ§ Ø²ØšØ§Ù Ù
+ÙØ±Ø¯ ÙØžØ± Ø®ÙØ¯ Ø±Ø§ Ø§ÙØªØ®Ø§Øš ÙÙÙØ¯}  
+
+#for status page
+_textgtiviewstatus_ [l=fa] {ÙØ·ÙØ§ Ø¬ÙØª Ù
+ØŽØ§ÙØ¯Ù ÙØ¶Ø¹ÙØª Ø¬Ø§Ø±Ù ØªØ±Ø¬Ù
+Ù ØšØ±Ø§Ù ØªÙ
+Ø§Ù
+Ù Ø²ØšØ§ÙÙØ§ ÙÙÙÙ ÙÙÙØ¯}  
+_textgtiviewstatusbutton_ [l=fa] {Ù
+ØŽØ§ÙØ¯Ù ÙØ¶Ø¹ÙØª}  
+_textgtistatustable_ [l=fa] {ÙÙØ³ØªÙ Ø§Ø² ÙØ¶Ø¹ÙØª Ø¬Ø§Ø±Ù ØªØ±Ø¬Ù
+Ù ØšØ±Ø§Ù ØªÙ
+Ø§Ù
+Ù Ø²ØšØ§ÙÙØ§}  
+_textgtilanguage_ [l=fa] {Ø²ØšØ§Ù}  
+_textgtitotalnumberoftranslations_ [l=fa] {ØªØ¹Ø¯Ø§Ø¯ Ú©Ù ØªØ±Ø¬Ù
+Ù ÙØ§}  
+
+_textgtiselecttfk_ [l=fa] {ÙØ·ÙØ§ ÙØ§ÙÙÙ Ø±Ø§ Ø¬ÙØª ÙØ§Ø± Ø§ÙØªØ®Ø§Øš ÙÙÙØ¯}  
+
+_textgticoredm_ [l=fa] {Ø±Ø§ØšØ· ÙØ§Ø±ØšØ± Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ(Ø§ØµÙÙ)}  
+_textgtiauxdm_ [l=fa] {Ø±Ø§ØšØ· ÙØ§Ø±ØšØ± Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ(ÙÙ
+ÙÙ)}  
+_textgtiglidict_ [l=fa] {ÙØ§ÚÙ ÙØ§Ù
+Ù GLI}  
+_textgtiglihelp_ [l=fa] {Ø±Ø§ÙÙÙ
+Ø§Û GLI}  
+_textgtiperlmodules_ [l=fa] {Ù
+Ø§ÚÙÙÙØ§Ù Perl}  
+_textgtitutorials_ [l=fa] {ØªÙ
+Ø±ÙÙ Ø¢Ù
+ÙØ²ØŽÙ}  
+_textgtigreenorg_ [l=fa] {Greenstone.org}  
+_textgtigs3core_ [l=fa] {Ø±Ø§ØšØ· ÙØ§Ø±ØšØ± Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ 3 (ÙŸÙØŽ ÙØ±Ø¶)}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=fa] {Ø¯Ø³ØªÙØ§Ù
+Ù ØªÙØ³Ø¹Ù Ø¯ÙÙØ¯Ú¯Ø§Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}  
+_textgtiinstallmanual_ [l=fa] {Ø¯Ø³ØªÙØ§Ù
+Ù ÙØµØš ÙÙÙØ¯Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}  
+_textgtipapermanual_ [l=fa] {Ø¯Ø³ØªÙØ§Ù
+Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ ØšØ±Ø§Ù Ù
+ÙØ§ÙÙ ØšÙ Ù
+Ø¬Ù
+ÙØ¹Ù}  
+_textgtiusermanual_ [l=fa] {Ø¯Ø³ØªÙØ§Ù
+Ù ÙØ§Ø±ØšØ±Ø§Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}  
+
+_textgtienter_ [l=fa] {ÙØ±ÙØ¯}  
+
+_textgticorrectexistingtranslations_ [l=fa] {ØªØ±Ø¬Ù
+Ù ÙØ§Ù ØµØ­ÙØ­ Ù
+ÙØ¬ÙØ¯}  
+_textgtidownloadtargetfile_ [l=fa] {Ø¯Ø§ÙÙÙØ¯ ÙÙ
+ÙØ¯Ù ÙØ§ÙÙ}  
+_textgtiviewtargetfileinaction_ [l=fa] {Ù
+ØŽØ§ÙØ¯Ù Ø§ÙÙ ÙØ§ÙÙ Ø¯Ø± Ø¹Ù
+Ù}  
+_textgtitranslatefileoffline_ [l=fa] {Ø§ÙÙ ÙØ§ÙÙ Ø±Ø§ ØšÙ ØµÙØ±Øª ØšØ±ÙÙ Ø®Ø·Ù ØªØ±Ø¬Ù
+Ù ÙÙÙØ¯}  
+
+_textgtinumchunksmatchingquery_ [l=fa] {ØªØ¹Ø¯Ø§Ø¯ Ø§Ø¬Ø²Ø§Ù Ù
+ØªÙÙ ÙÙ ØšØ§ Ø¬Ø³ØªØ¬Ù Ù
+Ø·Ø§ØšÙØª Ù
+Ù ÙÙØ¯}  
+
+_textgtinumchunkstranslated_ [l=fa] {ØªØ±Ø¬Ù
+Ù ÙØ§ Ø§ÙØ¬Ø§Ù
+ ØŽØ¯}  
+_textgtinumchunksrequiringupdating_ [l=fa] {Ø§Ø² Ø§ÙÙÙØ§  _1_  ÙÙØ§Ø² ØšÙ Ø±ÙØ²Ø¢Ù
+Ø¯Ø³Ø§Ø²Ù Ø¯Ø§Ø±Ø¯}  
+_textgtinumchunksrequiringtranslation_ [l=fa] {ØªØ±Ø¬Ù
+Ù ÙØ§Û ØšØ§ÙÛ Ù
+Ø§ÙØ¯Ù}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=fa] {ØªØ¹Ø¯Ø§Ø¯ ØªØ±Ø¬Ù
+Ù ÙØ§Ù Ø§ÙØ¬Ø§Ù
+ ØŽØ¯Ù}  
+_textgtinumchunksrequiringupdating2_ [l=fa] {ØªØ¹Ø¯Ø§Ø¯ ØªØ±Ø¬Ù
+Ù ÙØ§ÙÙ ÙÙ ÙÙØ§Ø² ØšÙ Ø±ÙØ²Ø¢Ù
+Ø¯Ø³Ø§Ø²Ù Ø¯Ø§Ø±Ø¯}
+_textgtinumchunksrequiringtranslation2_ [l=fa] {ØªØ¹Ø¯Ø§Ø¯ ØªØ±Ø¬Ù
+Ù ÙØ§ÙÙ ÙÙ ØšØ§ÙÙ Ù
+Ø§ÙØ¯Ù Ø§Ø³Øª}  
+
+_textgtienterquery_ [l=fa] {ÙØºØª ÙØ§ Ø¹ØšØ§Ø±ØªÙ Ø±Ø§ Ù
+Ù Ø®ÙØ§ÙÙØ¯ Ø§ØµÙØ§Ø­ ÙÙÙØ¯ ÙØ§Ø±Ø¯ ÙÙÙØ¯}  
+_textgtifind_ [l=fa] {ÙØ§ÙØªÙ}  
+
+_textgtitranslatingchunk_ [l=fa] {ØªØ±Ø¬Ù
+Ù ÙØ·Ø¹Ù Ø§Û Ø§Ø² Ù
+ØªÙ<i>_1_</i>}  
+_textgtiupdatingchunk_ [l=fa] {Ø¯Ø± Ø­Ø§Ù Ø±ÙØ²Ø¢Ù
+Ø¯ Ø³Ø§Ø²Ù Ù
+ØªÙ <i>_1_</i>}  
+_textgtisubmit_ [l=fa] {ÙØ§Ú¯Ø°Ø§Ø±Ù}  
+
+_textgtilastupdated_ [l=fa] {Ø¢Ø®Ø±ÙÙ Ø±ÙØ²Ø¢Ù
+Ø¯Ø³Ø§Ø²Ù}  
+
+_textgtitranslationfilecomplete_ [l=fa] {ØªØŽÙØ± Ø§Ø² ØŽÙ
+Ø§ Ø¬ÙØª Ø¯Ø§ÙÙÙØ¯ ÙÙ
+ÙØ¯Ù Ø§ÙÙ ÙØ§ÙÙ--Ø§ÙÙÙÙ Ø§ÛÙ Ú©Ø§Ø± ØšÙ ØµÙØ±Øª Ú©Ø§Ù
+Ù Ø§ÙØ¬Ø§Ù
+ ØŽØ¯. ØŽÙ
+Ø§ Ù
+Ù ØªÙØ§ÙÙØ¯ ÙÙ ÙÙŸÙ Ø§Ø² Ø§ÙÙ ÙØ§ÙÙ Ø±Ø§ ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² ÙÙÙÙ ÙÙÙØ Ø¯Ø§ÙÙÙØ¯ 
+ÙÙÙØ¯ ÙÙ Ø§ÙØšØªÙ Ø¯Ø± Ø§ÙØªØŽØ§Ø±ÙØ§Ù ØšØ¹Ø¯Ù Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø§Ø¹Ù
+Ø§Ù Ø®ÙØ§ÙØ¯ ØŽØ¯.}  
+
+_textgtiofflinetranslation_ [l=fa] {ØŽÙ
+Ø§ Ù
+Ù ØªÙØ§ÙÙØ¯ Ø§ÙÙ ÙØ³Ù
+Øª Ø§Ø² Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ Ø±Ø§ ØšÙ ØµÙØ±Øª ØšØ±ÙÙ Ø®Ø·Ù ØšØ§ Ø§Ø³ØªÙØ§Ø¯Ù Ø§Ø² ÙØ§ÙÙ ØµÙØ­Ù Ú¯Ø³ØªØ±Ø¯Ù Microsoft Excel ØªØ±Ø¬Ù
+Ù ÙÙÙØ¯:
+<ol>
+<li> Ø§ÛÙ ÙØ§ÛÙ Ø±Ø§ Ø¯Ø§ÙÙÙØ¯ Ú©ÙÛØ¯:</a><a href="_gwcgi_?a=gti&p=excel&e=_compressedoptions_">
+<li> ÙØ§ÛÙ Ø¯Ø§ÙÙÙØ¯ ØŽØ¯Ù Ø±Ø§ Ø¯Ø± Microsoft Excel Ù Ø¢Ù Ø±Ø§ ØšØ§ ÙØ±Ù
+Øª Microsoft Excel workbook(.xls) Ø°Ø®ÛØ±Ù Ú©ÙÛØ¯.
+<li> ØªØ±Ø¬Ù
+Ù ÙØ§ Ø±Ø§ Ø¯Ø± ØšØ§Ú©Ø³ÙØ§Û Ù
+ÙØ¬ÙØ¯ ÙØ§Ø±Ø¯ Ú©ÙÛØ¯.
+<li> ÙÙÚ¯Ø§Ù
+Û Ú©Ù ØŽÙ
+Ø§ ØªØ±Ø¬Ù
+Ù ØªÙ
+Ø§Ù
+Û Ø±ØŽØªÙ ÙØ§ Ø±Ø§ ØªÙ
+Ø§Ù
+ Ú©Ø±Ø¯ÛØ¯Ø ÙØ§ÛÙ .xls Ù
+ÙØ±Ø¯ Ø±Ø§ ØšÙ Ø§ÛÙ Ø¢Ø¯Ø±Ø³ ØšÙØ±Ø³ØªÛØ¯.
+<a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>.
+</ol>}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=fa] {Ø±Ø§ØšØ· ÙØªØ§ØšØ¯Ø§Ø±Ú¯Ø±ÙÙ Ø§Ø³ØªÙÙ}  
+_textglihelp_ [l=fa] {<p>Ø±Ø§ØšØ· Ú©Ø§Ø±ØšØ± Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ(<span lang="en-us">GLI</span>)&nbsp; Ø§Ù
+Ú©Ø§Ù Ø¯Ø³ØªØ±Ø³Û ØšÙ 
+Ú©Ø§Ø±ØšØ±Ø¯ÙØ§Û Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ø±Ø§ Ø§Ø² Ø·Ø±ÛÙ ÛÚ© Ø±Ø§ØšØ· Ú©Ø§Ø±ØšØ± Ø±Ø§Ø­Øª ØšØ±Ø§Û Ø§Ø³ØªÙØ§Ø¯Ù Ù ØšØ§ ÙØ§ØšÙÛØª Ø§ØŽØ±Ù 
+Ù Ú©ÙÛÚ© ÙØ±Ø§ÙÙ
+ Ù
+Û Ø¢ÙØ±Ø¯. Ø§ÛÙ Ø±Ø§ØšØ· ØŽÙ
+Ø§ Ø±Ø§ ÙØ§Ø¯Ø± Ù
+Û Ø³Ø§Ø²Ø¯ ØªØ§ Ù
+Ø¬Ù
+ÙØ¹Ù Ø§Û Ø§Ø² Ù
+Ø¯Ø§Ø±Ú© Ø±Ø§ 
+Ú¯Ø±Ø¯Ø¢ÙØ±ÛØ ÙØ§Ø±Ø¯ Ú©ÙÛØ¯ ÛØ§ Ø§ØšØ±Ø¯Ø§Ø¯Ù Ø§Û ØšØ±Ø§Û Ø¢ÙÙØ§ Ø§Ø®ØªØµØ§Øµ Ø¯ÙÛØ¯ Ù Ø¢ÙÙØ§ Ø±Ø§ Ø¯Ø± ÙØ§ÙØš ÛÚ© 
+Ù
+Ø¬Ù
+ÙØ¹Ù Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ø§ÛØ¬Ø§Ø¯ Ú©ÙÛØ¯. </p>
+
+<p>ØªÙØ¬Ù Ø¯Ø§ØŽØªÙ ØšØ§ØŽÛØ¯ Ú©Ù <span lang="en-us">GLI</span>&nbsp; Ø¯Ø± ÙÙ
+Ú¯Ø±Ø§ÛÛ ØšØ§ Ú¯Ø±ÛÙ 
+Ø§Ø³ØªÙÙ Ø§Ø¬Ø±Ø§ Ù
+Û ØŽÙØ¯ Ù ÙØ±Ø¶ ØšØ± Ø§ÛÙ Ø§Ø³Øª Ú©Ù Ø¯Ø± ÛÚ© Ø¯Ø§ÛØ±Ú©ÙÙØ±Û ÙØ±Ø¹Û Ø¯Ø± Ù
+Ø­Ù ÙØµØš Ú¯Ø±ÛÙ 
+Ø§Ø³ØªÙÙ ÙØµØš ØŽØ¯Ù Ø§Ø³Øª. ÚÙØ§ÙÚÙ ÛÚ©Û Ø§Ø² ÙØ³Ø®Ù ÙØ§Û Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ Ø±Ø§ Ø¯Ø§ÙÙÙØ¯ Ú©Ø±Ø¯Ù ØšØ§ØŽÛØ¯ ÛØ§ 
+Ø§Ø² ÙÙØ­ ÙØŽØ±Ø¯Ù Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ ÙØµØš Ú©Ø±Ø¯Ù ØšØ§ØŽÛØ¯Ø Ø§ÛÙ Ø§Ù
+Ø± Ù
+ØµØ¯Ø§Ù Ø®ÙØ§ÙØ¯ Ø¯Ø§ØŽØª.</p>
+
+<h4>Ø§Ø¬Ø±Ø§Û GLI ØªØ­Øª ÙÛÙØ¯ÙØ²</h4>
+
+Ø±Ø§ØšØ· Ú©ØªØ§ØšØ¯Ø§Ø± ØªØ­Øª ÙÛÙØ¯ÙØ² Ø±Ø§ ØšØ§ Ø§ÙØªØ®Ø§ØšGreenstone Digital 
+LibraryØ§Ø² ÙÛØ³Øª ØšØ±ÙØ§Ù
+Ù ÙØ§Û Ù
+ÙØ¬ÙØ¯ Ø¯Ø± Ø¯Ú©Ù
+Ù Start 
+Ù Ø§ÙØªØ®Ø§Øš Ú¯Ø²ÛÙÙ Librarian Interface Ø¢ØºØ§Ø² Ú©ÙÛØ¯.<h4>Ø§Ø¬Ø±Ø§Û
+GLI ØªØ­Øª ÛÙÙÛÚ©Ø³</h4>
+
+ØšØ±Ø§Û Ø§Ø¬Ø±Ø§Û GLIØªØ­Øª ÛÙÙÛÚ©Ø³Ø Ø¯Ø§ÛØ±Ú©ØªÙØ±Û
+gli Ø±Ø§ Ø¯Ø± Ù
+Ø­Ù ÙØµØš Ú¯Ø±ÛÙ Ø§Ø³ØªÙÙ ØªØºÛÛØ± Ø¯Ø§Ø¯Ù Ù Ø³ÙŸØ³ Ø§Ø³Ú©Ø±ÛÙŸØª
+gli.sh Ø±Ø§ Ø§Ø¬Ø±Ø§ Ú©ÙÛØ¯.<h4>Ø§Ø¬Ø±Ø§Û GLI
+ØªØ­Øª Ø³ÛØ³ØªÙ
+ Ø¹Ø§Ù
+Ù Ù
+Ú©ÛÙØªØ§ØŽ X </h4>
+
+Ø¯Ø± ØšØ±ÙØ§Ù
+Ù finder Ø§ØšØªØ¯Ø§ 
+Applications Ù Ø³ÙŸØ³ Greenstone (Ø¯Ø± ØµÙØ±ØªÛ Ú©Ù Ú¯Ø±ÛÙ 
+Ø§Ø³ØªÙÙ Ø±Ø§ Ø¯Ø± Ù
+Ø­Ù ÙŸÛØŽÙØ±Ø¶ ÙØµØš Ú©Ø±Ø¯Ù ØšØ§ØŽÛØ¯) Ø±Ø§ Ù
+Ø±ÙØ± Ú©ÙÛØ¯Ø Ù Ø³ÙŸØ³ ØšØ±ÙØ§Ù
+Ù Ú©Ø§Ø±ØšØ±Ø¯Û
+GLI Ø¢ØºØ§Ø² Ú©ÙÛØ¯.}  
Index: /gsdl/stable/macros/finnish.dm
===================================================================
--- /gsdl/stable/macros/finnish.dm	(revision 20131)
+++ /gsdl/stable/macros/finnish.dm	(revision 20131)
@@ -0,0 +1,777 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Finnish Language text and icon macros 
+# Many thanks to Steve Legrand (translated October 2003)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=fi] {Aikakausjulkaisut}
+_textsource_ [l=fi] {lÃ€hdeviite:}
+_textdate_ [l=fi] {julkaisupÃ€ivÃ€mÃ€Ã€rÃ€:}
+_textnumpages_ [l=fi] {sivumÃ€Ã€rÃ€:}
+
+_textsignin_ [l=fi] {kirjoittaudu sisÃ€Ã€n}
+
+_textdefaultcontent_ [l=fi] {Haettua sivua ei lÃ¶ytynyt. PÃ€Ã€set takaisin Greenstone digitaaliseen kirjastoon napsauttamalla selaajan 'Edellinen'-painiketta tai yllÃ€olevaa 'Alkuun'-painiketta.}
+
+_textdefaulttitle_ [l=fi] {GSDL virhe}
+
+_textbadcollection_ [l=fi] {TÃ€tÃ€ kokoelmaa (nimeltÃ€Ã€n "_cvariable_ ) ei ole asennettu Greenstone digitaaliseen kirjastosysteemiin.}
+
+_textselectpage_ [l=fi] {-- Valitse Sivu --}
+
+_collectionextra_ [l=fi] {TÃ€mÃ€ kokoelma sisÃ€ltÃ€Ã€ _about:numdocs_ dokumenttia.
+Kokoelmaa on viimeksi muokattu _about:builddate_.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=fi] {<p>TÃ€mÃ€ kokoelma sisÃ€ltÃ€Ã€ _numdocs_ _If_("_numdocs_" on "1", dokumenttia), yhteensÃ€  _numbytes_.
+<p><a href="_httppagex_(bsummary)">Napsauttamalla tÃ€hÃ€n hiirellÃ€</a> saat nÃ€kyviin koostetun yhteenvedon kokoelmasta.}
+
+_textdescrcollection_ [l=fi] {}
+_textdescrabout_ [l=fi] {Versiotiedot sivu}
+_textdescrhome_ [l=fi] {Alkusivu}
+_textdescrhelp_ [l=fi] {Ohje sivu}
+_textdescrpref_ [l=fi] {Asetukset-sivu}
+_textdescrgreenstone_ [l=fi] {Greenstone Digitaalinen Kirjasto -ohjelma}
+_textdescrusab_ [l=fi] {MikÃ€ on mielestÃ€si vaikeakÃ€yttÃ¶istÃ€?}
+
+_textdescrSearch_ [l=fi] {Erikoistermien haku}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=fi] {Selaa nimikkeitÃ€ aakkosittain}
+_textdescrCreator_ [l=fi] {Selaa tekijÃ¶itÃ€ aakkosittain}
+_textdescrSubject_ [l=fi] {Selaa aihealueittain}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=fi] {Selaa pÃ€ivÃ€mÃ€Ã€rittÃ€in}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+_textdescrSource_ [l=fi] {Selaa alkuperÃ€isellÃ€ tiedostonimellÃ€}
+_textdescrLanguage_ [l=fi] {Selaa kielen perusteella}
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=fi] {Selaa organisaatioittain}
+_textdescrKeyword_ [l=fi] {Selaa avainsanoittain}
+_textdescrHowto_ [l=fi] {Selaa How to -luokkia}
+_textdescrList_ [l=fi] {Selaa dokumenttiluetteloa}
+_textdescrSeries_ [l=fi] {Selaa julkaisunumeroita}
+_textdescrTo_ [l=fi] {Selaa kohteittain}
+_textdescrFrom_ [l=fi] {Selaa lÃ€hdekentittÃ€in}
+_textdescrTopic_ [l=fi] {Selaa erikoisaiheittain}
+_textdescrBrowse_ [l=fi] {Selaa}
+# -- Missing translation: _textdescrCollage_
+_textdescrPeople_ [l=fi] {Selaa henkilÃ¶itÃ€ aakkosittain}
+_textdescrAcronym_ [l=fi] {Selaa akronyymejÃ€}
+_textdescrPhrase_ [l=fi] {Selaa lausekkeita}
+_textdescrArtist_ [l=fi] {Selaa taiteilijoita}
+_textdescrVolume_ [l=fi] {Selaa volyymeittain}
+_textdescrCountries_ [l=fi] {Selaa maitten nimiÃ€ kÃ€yttÃ€en}
+_textdescrCaptions_ [l=fi] {Selaa kuvatekstejÃ€ kÃ€yttÃ€en}
+
+
+_labelSearch_ [l=fi] {Haku}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=fi] {Nimikkeet A-Z}
+_labelCreator_ [l=fi] {TekijÃ€t A-Z}
+_labelSubject_ [l=fi] {Aiheet}
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=fi] {PÃ€ivÃ€mÃ€Ã€rÃ€t}
+# -- Missing translation: _labelType_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+_labelSource_ [l=fi] {Tiedostonimet}
+_labelLanguage_ [l=fi] {Kieli}
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=fi] {Organisaatio}
+_labelKeyword_ [l=fi] {Avainsanat}
+_labelHow_ [l=fi] {How to}
+_labelSeries_ [l=fi] {Sarjat}
+_labelList_ [l=fi] {Listaus}
+_labelTo_ [l=fi] {Kohde}
+_labelFrom_ [l=fi] {LÃ€hde}
+_labelTopic_ [l=fi] {Aihealueet}
+_labelBrwse_ [l=fi] {Selaus}
+# -- Missing translation: _labelCollage_
+_labelBrows_ [l=fi] {Selaa}
+_labelPeople_ [l=fi] {HenkilÃ¶t A-Z}
+_labelAcronym_ [l=fi] {Akronyymit}
+_labelPhrase_ [l=fi] {Lausekkeet}
+_labelArtist_ [l=fi] {Taiteilijat}
+_labelVolume_ [l=fi] {Volyymit}
+_labelCaptions_ [l=fi] {Selitteet}
+_labelCountries_ [l=fi] {Maat}
+
+_texticontext_ [l=fi] {Tarkastele dokumenttia}
+_texticonclosedbook_ [l=fi] {avaa tÃ€mÃ€ dokumentti ja tarkastele sen sisÃ€ltÃ¶Ã€}
+_texticonnext_ [l=fi] {seuraavaan osaan}
+_texticonprev_ [l=fi] {edelliseen osaan}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=fi] {Tarkastele MIDI dokumenttia}
+_texticonmsword_ [l=fi] {Tarkastele Microsoft Word dokumenttia}
+_texticonmp3_ [l=fi] {Tarkastele MP3 dokumenttia}
+_texticonpdf_ [l=fi] {Tarkastele PDF dokumenttia}
+_texticonps_ [l=fi] {Tarkastele PostScript dokumenttia}
+_texticonppt_ [l=fi] {Tarkastele PowerPoint dokumenttia}
+_texticonrtf_ [l=fi] {Tarkastele RTF dokumenttia}
+_texticonxls_ [l=fi] {Tarkastele Microsoft Excel dokumenttia}
+
+_page_ [l=fi] {sivu}
+_pages_ [l=fi] {sivua}
+# -- Missing translation: _of_
+_vol_ [l=fi] {Vol.}
+_num_ [l=fi] {No.}
+
+_textmonth00_ [l=fi] {}
+_textmonth01_ [l=fi] {Tammikuu}
+_textmonth02_ [l=fi] {Helmikuu}
+_textmonth03_ [l=fi] {Maaliskuu}
+_textmonth04_ [l=fi] {Huhtikuu}
+_textmonth05_ [l=fi] {Toukokuu}
+_textmonth06_ [l=fi] {KesÃ€kuu}
+_textmonth07_ [l=fi] {HeinÃ€kuu}
+_textmonth08_ [l=fi] {Elokuu}
+_textmonth09_ [l=fi] {Syyskuu}
+_textmonth10_ [l=fi] {Lokakuu}
+_textmonth11_ [l=fi] {Marraskuu}
+_textmonth12_ [l=fi] {Joulukuu}
+
+_textdocument_ [l=fi] {Dokumentti}
+_textsection_ [l=fi] {Osa}
+_textparagraph_ [l=fi] {Kappale}
+
+_magazines_ [l=fi] {Aikakauslehdet}
+
+_nzdlpagefooter_ [l=fi] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}
+
+_linktextHOME_ [l=fi] {ALKU}
+_linktextHELP_ [l=fi] {OHJE}
+_linktextPREFERENCES_ [l=fi] {ASETUKSET}
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=fi] {Tietoja tÃ€stÃ€ kokoelmasta}
+
+_textsubcols1_ [l=fi] {<p>TÃ€ydelliseen kokoelmaan sisÃ€ltyy _1_ osakokoelmaa. 
+TÃ€llÃ€ hetkellÃ€ ovat saatavissa:
+<blockquote>}
+
+_textsubcols2_ [l=fi] {</blockquote>
+Voit tarkistaa (ja muokata) niitÃ€ osakokoelmia, joita kÃ€ytÃ€t tÃ€llÃ€ hetkellÃ€ Asetukset-sivulla.}
+
+_titleabout_ [l=fi] {YleistÃ€}
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+# -- Missing translation: _texticonhcoll_
+
+_texticonopenbookshelf_ [l=fi] {sulje tÃ€mÃ€ kirjaston osa}
+_texticonclosedbookshelf_ [l=fi] {avaa tÃ€mÃ€ kirjaston osa ja tarkastele sen sisÃ€ltÃ¶Ã€}
+_texticonopenbook_ [l=fi] {sulje tÃ€mÃ€ kirja}
+_texticonclosedfolder_ [l=fi] {Avaa tÃ€mÃ€ kansio ja tarkastele sen sisÃ€ltÃ¶Ã€}
+_texticonclosedfolder2_ [l=fi] {avaa alaosasto:}
+_texticonopenfolder_ [l=fi] {sulje tÃ€mÃ€ kansio}
+_texticonopenfolder2_ [l=fi] {sulje alaosasto:}
+_texticonsmalltext_ [l=fi] {Tarkastele tekstin tÃ€tÃ€ osaa}
+_texticonsmalltext2_ [l=fi] {tarkastele tekstiÃ€:}
+_texticonpointer_ [l=fi] {nykyinen osa-alue}
+_texticondetach_ [l=fi] {Avaa tÃ€mÃ€ sivu uudessa ikkunassa}
+_texticonhighlight_ [l=fi] {Korosta hakutermejÃ€}
+_texticonnohighlight_ [l=fi] {ÃlÃ€ korosta hakutermejÃ€}
+_texticoncontracttoc_ [l=fi] {TiivistÃ€ sisÃ€llysluetteloa}
+_texticonexpandtoc_ [l=fi] {Laajenna sisÃ€llysluetteloa}
+_texticonexpandtext_ [l=fi] {NÃ€ytÃ€ koko teksti}
+_texticoncontracttext_ [l=fi] {NÃ€ytÃ€ teksti vain valitulle osalle}
+_texticonwarning_ [l=fi] {<b>Huom! </b>}
+_texticoncont_ [l=fi] {jatka?}
+
+_textltwarning_ [l=fi] {<div class="buttons">_imagecont_</div>
+_iconwarning_Jos laajennat tekstiÃ€ tÃ€ssÃ€ kohden, selaajan nÃ€yttÃ¶alueeseen tulee suuri mÃ€Ã€rÃ€ tietoja
+}
+
+_textgoto_ [l=fi] {sivulle}
+_textintro_ [l=fi] {<i>(johdanto)</i>}
+
+_textCONTINUE_ [l=fi] {JATKA??}
+
+_textEXPANDTEXT_ [l=fi] {LAAJENNA\nTEKSTIÃ}
+
+_textCONTRACTCONTENTS_ [l=fi] {TIIVISTÃ\nSISÃLTÃÃ}
+
+_textDETACH_ [l=fi] {UUTEEN\nIKKUNAAN}
+
+_textEXPANDCONTENTS_ [l=fi] {LAAJENNA\nSISÃLTÃÃ}
+
+_textCONTRACT_ [l=fi] {TIIVISTÃ\nTEKSTIÃ}
+
+_textHIGHLIGHT_ [l=fi] {KOROSTUS}
+
+_textNOHIGHLIGHT_ [l=fi] {EI\nKOROSTUSTA}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=fi] {_If_(_thislast_,antaa tuloksen _thisfirst_ - _thislast_ kyselylle: _cgiargq_,Kysely ei tÃ€smÃ€Ã€: _cgiargq_)}
+_textnoquerytitle_ [l=fi] {Hakusivu}
+
+_textsome_ [l=fi] {joitain}
+_textall_ [l=fi] {kaikki}
+_textboolean_ [l=fi] {boolen logiikan mukainen}
+_textranked_ [l=fi] {asetettu jÃ€rjestykseen}
+_textnatural_ [l=fi] {luonnollinen}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=fi] {hakuhistoria}
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+_textusequery_ [l=fi] {kÃ€ytÃ€ tÃ€tÃ€ kyselyÃ€}
+_textfreqmsg1_ [l=fi] {Sanojen lukumÃ€Ã€rÃ€: }
+_textpostprocess_ [l=fi] {_If_(_quotedquery_,<br><i>jÃ€lkikÃ€siteltynÃ€ lÃ¶ytÃ€Ã€ _quotedquery_:n</i>
+)}
+_textinvalidquery_ [l=fi] {VÃ€Ã€rÃ€ kyselysyntaksi}
+
+_textmorethan_ [l=fi] {EnemmÃ€n kuin}
+_textapprox_ [l=fi] {Noin}
+_textnodocs_ [l=fi] {YksikÃ€Ã€n dokumentti ei vastaa kyselyÃ€.}
+_text1doc_ [l=fi] {1 dokumentti vastaa kyselyÃ€.}
+_textlotsdocs_ [l=fi] {dokumenttia vastaa kyselyÃ€.}
+_textmatches_ [l=fi] {Tulokset }
+_textbeginsearch_ [l=fi] {Aloita Haku}
+_textrunquery_ [l=fi] {Suorita Kysely}
+_textclearform_ [l=fi] {TyhjennÃ€ lomake}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=fi] {Sana tai lause}
+_textinfield_ [l=fi] {... kentÃ€ssÃ€}
+_textfoldstem_ [l=fi] {(kokoerojen poisto, sanojen vartalot)}
+
+_textadvquery_ [l=fi] {Tai kirjoita kysely suoraan:}
+_textallfields_ [l=fi] {kaikki kentÃ€t}
+_texttextonly_ [l=fi] {vain tekstiÃ€}
+_textand_ [l=fi] {ja}
+_textor_ [l=fi] {tai}
+_textandnot_ [l=fi] {ja ei}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=fi] {Hae _indexselection_ _If_(_jselection_, _jselection_) _If_(_gselection_, _gselection_-tasolla) _If_(_nselection_, _nselection_ -kielellÃ€) jotka sisÃ€ltÃ€vÃ€t _querytypeselection_ sanoista}
+
+_textadvancedsearch_ [l=fi] {Hae _indexselection_ _If_(_jselection_, _jselection_) _If_(_gselection_, _gselection_-tasolla)_If_(_nselection_,  _nselection_-kielellÃ€) kÃ€yttÃ€mÃ€llÃ€ _querytypeselection_-kyselyÃ€}
+
+_textformsimplesearch_ [l=fi] {Hae _If_(_jselection_,_jselection_ )_If_(_gformselection_,_gformselection_-tasolla )_If_(_nselection_,in _nselection_-kielellÃ€ )_formquerytypesimpleselection_}
+
+_textformadvancedsearch_ [l=fi] {Hae _If_(_jselection_,_jselection_ )_If_(_gformselection_, _gformselection_-tasolla )_If_(_nselection_, _nselection_-kielellÃ€ )ja nÃ€ytÃ€ tulokset _formquerytypeadvancedselection_-jÃ€rjestyksessÃ€.}
+
+
+_textnojsformwarning_ [l=fi] {Huom: JavascriptiÃ€ ei ole aktivoitu selaimessasi. <br>Aktivoimalla sen voit kÃ€yttÃ€Ã€ lomakehakua.}
+_textdatesearch_ [l=fi] {TÃ€stÃ€ kokoelmasta voidaan hakea dokumentteja tiettyjen pÃ€ivÃ€mÃ€Ã€rien sisÃ€ltÃ€ tai dokumentteja, jotka sisÃ€ltÃ€vÃ€t tietyn pÃ€ivÃ€mÃ€Ã€rÃ€n. TÃ€mÃ€ on hakuvaihtoehto.}
+_textstartdate_ [l=fi] {Aloitus (tai ainoa) pÃ€ivÃ€mÃ€Ã€rÃ€}
+_textenddate_ [l=fi] {Viimeinen pÃ€ivÃ€:}
+_textbc_ [l=fi] {eKr.}
+_textad_ [l=fi] {jKr.}
+_textexplaineras_ [l=fi] {jKr ja eKr vastaavat englanninkielisiÃ€ termejÃ€ A.D. ja B.C. NÃ€mÃ€ termit ovat kulttuurisidonnaisia ja merkitsevÃ€t suunnilleen "nykyistÃ€ aikakautta" ja "ennen nykyistÃ€ aikakautta".}
+
+_textstemon_ [l=fi] {(sanojen loppuja ei otettu huomioon)}
+
+_textsearchhistory_ [l=fi] {Hakuhistoria}
+
+#text macros for search history
+_textnohistory_ [l=fi] {Hakuhistoriaa ei ole.}
+_texthresult_ [l=fi] {tulos}
+_texthresults_ [l=fi] {tulokset}
+_texthallwords_ [l=fi] {kaikki sanat}
+_texthsomewords_ [l=fi] {jotkut sanat}
+_texthboolean_ [l=fi] {boolen logiikan mukainen}
+_texthranked_ [l=fi] {asetettu jÃ€rjestykseen}
+_texthcaseon_ [l=fi] {kirjainten kokojen tÃ€ytyy tÃ€smÃ€tÃ€}
+_texthcaseoff_ [l=fi] {kirjainten kokoerojen poisto}
+_texthstemon_ [l=fi] {vartaloidut sanat}
+_texthstemoff_ [l=fi] {sanat ilman vartaloa}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=fi] {Asetukset on tehty seuraavalla tavalla. ÃlÃ€ kÃ€ytÃ€ selaajasi
+"Edellinen"-painiketta - tÃ€mÃ€ poistaa asetukset! Sen sijaan, napsauta
+jotain ylÃ€puolella olevan kÃ€yttÃ¶palkin painikkeista.
+}
+_textsetprefs_ [l=fi] {voimassa olevat asetukset}
+_textsearchprefs_ [l=fi] {Haun asetukset}
+_textcollectionprefs_ [l=fi] {Kokoelman asetukset}
+_textpresentationprefs_ [l=fi] {Esityksen asetukset}
+_textpreferences_ [l=fi] {Asetukset}
+_textcasediffs_ [l=fi] {Kirjainten kokoerot}
+_textignorecase_ [l=fi] {Ã€lÃ€ ota huomioon kirjainten kokoeroja}
+_textmatchcase_ [l=fi] {isojen/pienten kirjaimien tÃ€ytyy tÃ€smÃ€tÃ€}
+_textwordends_ [l=fi] {Sanojen loput:}
+_textstem_ [l=fi] {Ã€lÃ€ ota huomioon sanojen loppuja}
+_textnostem_ [l=fi] {koko sanan tÃ€ytyy tÃ€smÃ€tÃ€}
+_textprefop_ [l=fi] {Palauta enintÃ€Ã€n _maxdocoption_ hakutulosta,  _hitsperpageoption_ sivua kohden.}
+_textextlink_ [l=fi] {Ulkopuolisten verkkosivujen kÃ€yttÃ¶:}
+_textintlink_ [l=fi] {LÃ€hdedokumenttien alkuperÃ€:}
+_textlanguage_ [l=fi] {KÃ€yttÃ¶liittymÃ€n kieli:}
+_textencoding_ [l=fi] {MerkintÃ€jÃ€rjestelmÃ€:}
+_textformat_ [l=fi] {KÃ€yttÃ¶liittymÃ€muoto:}
+_textall_ [l=fi] {kaikki}
+_textquerymode_ [l=fi] {Kyselymuoto:}
+_textsimplemode_ [l=fi] {yksinkertainen kyselymuoto}
+_textadvancedmode_ [l=fi] {edistynyt kyselykÃ€ytÃ€ntÃ¶ (mahdollistaa boolen logiikan mukaisen haun !-, &- ja | -operaattoreilla, ja sulkumerkkien kÃ€ytÃ¶n)}
+_textlinkinterm_ [l=fi] {vÃ€lisivun kautta}
+_textlinkdirect_ [l=fi] {mene sinne suoraan}
+_textdigitlib_ [l=fi] {digitaalinen kirjasto}
+_textweb_ [l=fi] {Internet-verkko}
+_textgraphical_ [l=fi] {Graafinen}
+_texttextual_ [l=fi] {Tekstuaalinen}
+_textcollectionoption_ [l=fi] {<p>
+Alikokoelmat sisÃ€ltÃ€vÃ€t:
+<br>}
+
+_textrelateddocdisplay_ [l=fi] {nÃ€ytÃ€ yhteenkuuluvat dokumentit}
+_textsearchhistory_ [l=fi] {Hakuhistoria:}
+_textnohistory_ [l=fi] {Ei hakuhistoriaa}
+_texthistorydisplay_ [l=fi] {nÃ€ytÃ€ _historynumrecords_ hakuhistoriatietuetta}
+_textnohistorydisplay_ [l=fi] {Ã€lÃ€ nÃ€ytÃ€ hakuhistoriaa}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=fi] {Lomakehaku:}
+_textplainsearch_ [l=fi] {Tavallinen haku:}
+_textqueryboxsize_ [l=fi] {Kyselyruudun koko:}
+_textregbox_ [l=fi] {tavallinen kyselyruutu}
+_textbigbox_ [l=fi] {iso kyselyruutu}
+_textformtype_ [l=fi] {Lomaketyyppi:}
+_textsimple_ [l=fi] {yksinkertainen}
+_textadvanced_ [l=fi] {edistynyt}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=fi] {kanssa}
+_textfields_ [l=fi] {kentÃ€t}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=fi] {JÃ€rjestÃ€ dokumentit}
+_textalsoshowing_ [l=fi] {nÃ€kyvillÃ€ myÃ¶s}
+_textwith_ [l=fi] {enintÃ€Ã€n}
+_textdocsperpage_ [l=fi] {dokumenttia sivua kohden+B450}
+
+_textfilterby_ [l=fi] {Hae dokumentit jotka sisÃ€ltÃ€vÃ€t}
+_textall_ [l=fi] {kaikki}
+_textany_ [l=fi] {mikÃ€ tahansa}
+_textwords_ [l=fi] {sanoista}
+_textleaveblank_ [l=fi] {jÃ€ttÃ€mÃ€llÃ€ tÃ€mÃ€n ruudun tyhjÃ€ksi saat kaikki dokumentit}
+
+_browsebuttontext_ [l=fi] {"JÃ€rjestÃ€ dokumentit"}
+
+_nodata_ [l=fi] {<i>ei tietoja</i>}
+_docs_ [l=fi] {dokumentit}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=fi] {Ohje}
+_textSearchshort_ [l=fi] {hakemalla tiettyjÃ€ sanoja}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=fi] {hakemalla julkaisuja nimikkeiden perusteella}
+_textCreatorshort_ [l=fi] {hakemalla julkaisuja tekijÃ¶ittÃ€in}
+_textSubjectshort_ [l=fi] {hakemalla julkaisuja aiheittain}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=fi] {hakemalla julkaisuja pÃ€ivÃ€mÃ€Ã€rittÃ€in}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=fi] {hakemalla julkaisuja tiedostonimien perusteella}
+_textLanguageshort_ [l=fi] {hakemalla julkaisuja kielilajituksen avulla}
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=fi] {hakemalla julkaisuja sarjoittain}
+_textToshort_ [l=fi] {hakemalla julkaisuja Kohde-kenttien avulla}
+_textFromshort_ [l=fi] {hakemalla julkaisuja lÃ€hteittÃ€in}
+_textBrowseshort_ [l=fi] {selaa julkaisuja}
+_textOrganizationshort_ [l=fi] {hakemalla julkaisuja organisaatioden avulla}
+_textHowtoshort_ [l=fi] {hakemalla julkaisuja "How to"-luettelon avulla}
+_textTopicshort_ [l=fi] {hakemalla julkaisuja aihealueittain}
+_textPeopleshort_ [l=fi] {hakemalla julkaisuja henkilÃ¶iden nimien avulla}
+_textAcronymshort_ [l=fi] {hakemalla julkaisuja akronyymeittÃ€in}
+_textPhraseshort_ [l=fi] {selaa julkaisuissa esiintyviÃ€ lausekkeita}
+_textArtistshort_ [l=fi] {hakemalla julkaisuja taiteilijoittain}
+_textKeywordshort_ [l=fi] {hakemalla julkaisuja avainsanojen avulla}
+_textVolumeshort_ [l=fi] {hakemalla julkaisuja volyymien perusteella}
+_textCountriesshort_ [l=fi] {hakemalla julkaisuja maittain}
+_textdefaultshorttext_ [l=fi] {mÃ€Ã€rittelemÃ€tÃ¶n luokitus}
+
+_textSearchlong_ [l=fi] {<p><i>Hae tiettyjÃ€ sanoja, </i> jotka
+esiintyvÃ€t tekstissÃ€, "haku"-sivun avulla. TÃ€mÃ€ on se sivu, joka tulee nÃ€yttÃ¶Ã¶n,
+kun aloitat. Sivulle pÃ€Ã€see muilta sivuilta napsauttamalla
+ <i>haku</i>-painiketta.  }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=fi] {<p><i>Hae julkaisuja nimikkeiden avulla</i> 
+napsauttamalla <i>nimikkeet a-z</i>-painiketta  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n
+luettelon kirjoista aakkosjÃ€rjestyksessÃ€.  }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=fi] {<p><i>Hae julkaisuja tekijÃ¶iden nimien perusteella</i> 
+napsauttamalla <i>authors a-z</i>-painiketta  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n tekijÃ¶iden nimien avulla
+jÃ€rjestetyn luettelon kirjoista.  }
+
+_textSubjectlong_ [l=fi] {<p><i>Hae julkaisuja aiheittain</i> 
+napsauttamalla <i>aiheet</i>-painiketta.  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n
+kirjahyllyjen avulla esitettÃ€vÃ€n aiheluettelon. }
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=fi] {<p><i>Hae julkaisuja pÃ€ivÃ€mÃ€Ã€rien avulla</i> napsauttamalla
+ <i>dates</i>-painiketta.  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n luettelon kaikista aiheista aikajÃ€rjestyksessÃ€.  }
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=fi] {<p><i>Hae julkaisuja tiedostonimien perusteella</i> 
+napsauttamalla <i>filenames</i>-painiketta  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n
+alkuperÃ€isiin tiedostonimiin perustuvan lajittelun..  }
+
+_textLanguagelong_ [l=fi] {<p><i>Hae julkaisuja kielten perusteella</i> 
+napsauttamalla <i>languages</i>-painiketta  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n
+kieliin perustuvan lajittelun.  }
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=fi] {<p><i>Hae julkaisuja organisaatioiden
+perusteella</i> napsauttamalla <i>organisaatiot</i>-painiketta. 
+TÃ€mÃ€ tue nÃ€yttÃ¶Ã¶n organisaatioihin perustuvan luettelon.  }
+
+_textHowtolong_ [l=fi] {<p><i>Hae julkaisuja "How to"-luettelon avulla</i>
+napsauttamalla <i>how to</i>-painiketta.  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n
+luettelon How to -ohjeista.  }
+
+_textTopiclong_ [l=fi] {<p><i>Hae julkaisuja aihealueittain</i> 
+napsauttamalla <i>topic</i>-painiketta.  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n
+selattavaksi aihealueet.  }
+
+_textTolong_ [l=fi] {<p><i>Hae julkaisuja Kohde-kentÃ€n avulla</i> 
+napsauttamalla <i>to</i>-painiketta  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n kohteiden osoitteisiin perustuvan listan.  }
+
+_textFromlong_ [l=fi] {<p><i>Hae julkaisuja LÃ€hteen avulla</i> 
+napsauttamalla <i>from</i>-painiketta.  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n luettelon lÃ€hettÃ€jistÃ€.  }
+
+_textSerieslong_ [l=fi] {<p><i>Hae julkaisuja sarjojen perusteella</i> 
+napsauttamalla <i>series</i>-painiketta.  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n sarjat,
+jotka ovat kokoelmassa.  }
+
+_textBrowselong_ [l=fi] {<p><i>Selaa julkaisuja</i> napsauttamalla
+<i>browse</i>-painiketta.  }
+
+_textPeoplelong_ [l=fi] {<p><i>Hae eri henkilÃ¶iden julkaisuja</i> 
+napsauttamalla <i>people a-z</i>-painiketta.  
+TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n sukunimiin perustuvan lajittelun. }
+
+_textAcronymlong_ [l=fi] {<p><i>Hae julkaisuja akronyymien avulla</i> napsauttamalla<i>acronyms</i>-painiketta.  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n luettelon akronyymeistÃ€
+ja niiden esiintymispaikoista.  }
+
+_textPhraselong_ [l=fi] {<p><i>Selaa julkaisuissa esiintyviÃ€ lausekkeita</i>
+napsauttamalla <i>phrases</i>-painiketta. TehtÃ€vÃ€Ã€n kÃ€ytetÃ€Ã€n phind-lausekeselainta. }
+
+_textArtistlong_ [l=fi] {<p><i>Hae julkaisuja taiteilijoiden nimien perusteella</i> 
+napsauttamalla <i>taiteilijat</i>-painiketta  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n
+taiteilijoittain jÃ€rjestetyn luettelon.  }
+
+_textKeywordlong_ [l=fi] {<p><i>Hae julkaisuja avainsanojen avulla</i> 
+napsauttamalla <i>keywords</i>-painiketta.  TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n luettelon avainsanoista. }
+
+_textVolumelong_ [l=fi] {<p><i>Hae julkaisuja volyymien perusteella</i> 
+napsauttamalla <i>volumes</i>-painiketta TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n volyymiluettelon. }
+
+_textCaptionslong_ [l=fi] {<p><i>Hae julkaisuja selitteiden avulla</i> napsauttamalla
+<i>captions</i>-painiketta. TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n luettelon selitteistÃ€. }
+
+_textCountrieslong_ [l=fi] {<p><i>Hae julkaisuja maittain</i> napsauttamalla
+<i>countries</i>-painiketta. TÃ€mÃ€ tuo nÃ€yttÃ¶Ã¶n luettelon maista. }
+
+
+_textdefaultlongtext_ [l=fi] {<p>Napsauttamalla <i>unknown</i>-painiketta voit
+selata julkaisuja (tuntemattoman kentÃ€n perusteella).  }
+
+_texthelptopicstitle_ [l=fi] {Aihealueet}
+
+_textreadingdocs_ [l=fi] {Miten dokumentteja luetaan}
+
+_texthelpreadingdocs_ [l=fi] {
+<p>TiedÃ€t, minkÃ€ kirjan tai dokumentin kohdalla kulloinkin olet, 
+tarkastelemalla sivun vasenta ylÃ€laitaa, missÃ€ kirjan tai dokumentin
+nimen tai sen kansilehden kuvan pitÃ€isi nÃ€kyÃ€. Joissakin kokoelmissa
+on vain sisÃ€llysluettelo, kun taas joissakin nÃ€kyy  sivunumero,
+jonka viereisen ruudun avulla voit valita uuden sivun eteen- tai taakse pÃ€in.
+Valitun osan otsake on lihavoitu sisÃ€llysluettelossa, jota voi laajentaa:
+voit avata ja sulkea kansioita niitÃ€ napsauttamalla, voit myÃ¶s sulkea
+avatun kirjan napsauttamalla sen ylÃ€osaan.</p>
+
+<p>Alapuolella on valitun osan teksti. Kun olet sen lukenut, 
+pÃ€Ã€set seuraavaan tai edelliseen osaan kÃ€yttÃ€mÃ€llÃ€ alalaidassa olevia nuolia.</p>
+
+<p> Kirjan tai dokumentin nimen tai sen kansilehden kuvan alapuolella
+on joitain painikkeita. Voit laajentaa valitun osan koko tekstin tai kirjan
+napsauttamalla <i>laajenna tekstiÃ€</i> painiketta. Jos dokumentti on suuri, 
+voi aikaa ja muistia kulua paljon. Saat osien otsakkeet ja aliosat nÃ€yttÃ¶Ã¶n, 
+kun laajennat koko sisÃ€llysluetteloa napsauttamalla <i>tiivistÃ€ tekstiÃ€</i>
+-painiketta. Uuden dokumentin selainikkunan saat esiin napsauttamalla
+<i>uuteen ikkunaan</i>-painiketta. (TÃ€stÃ€ on hyÃ¶tyÃ€ dokumentteja vertailtaessa
+tai kahta dokumenttia yhtaikaa luettaessa.) Lopuksi, suoritettuasi sanahaun, 
+sanat, joita hait, nÃ€kyvÃ€t korostettuina. Voit hÃ€vittÃ€Ã€ korostuksen 
+halutessasi napsauttamalla <i>ei korostusta</i>-painiketta.</p>
+}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=fi] {Avaa tÃ€mÃ€ kirjahylly}
+_texthelpopenbook_ [l=fi] {Avaa/sulje tÃ€mÃ€ kirja}
+_texthelpviewtextsection_ [l=fi] {Tarkastele tÃ€tÃ€ tekstin osaa}
+_texthelpexpandtext_ [l=fi] {NÃ€ytÃ€ koko teksti?}
+_texthelpexpandcontents_ [l=fi] {Laajenna sisÃ€llysluetteloa?}
+_texthelpdetachpage_ [l=fi] {Avaa tÃ€mÃ€ sivu uudessa ikkunassa}
+_texthelphighlight_ [l=fi] {Korosta hakutermejÃ€?}
+
+_texthelpsearchingtitle_ [l=fi] {Miten haetaan tiettyjÃ€ sanoja?}
+_texthelpsearching_ [l=fi] {
+<p>
+  Haun tekeminen hakusivulta onnistuu helposti seuraavin toimenpitein:<p>
+  
+  <ol><li>MÃ€Ã€rittele haun kohteet
+      <li>Kerro, haluatko etsiÃ€ kaikilla sanoilla vai vain joillakin niistÃ€
+      <li>Kirjoita sanat, joilla haluat suorittaa haun
+      <li>Napsauta <i>Aloita Haku</i>-painiketta
+  </ol>
+
+<p>Kun suoritat haun, kahdenkymmenen tÃ€smÃ€Ã€vÃ€n dokumentin nimet tulevat
+nÃ€yttÃ¶Ã¶n. Seuraavat kaksikymmentÃ€ dokumenttia saat esiin alapuolella olevan
+painikkeen avulla. EdettyÃ€si lÃ¶ydÃ€t painikkeet kahdellekymmenelle
+dokumentille sekÃ€ eteen ettÃ€ taaksepÃ€in. Dokumentin saat nÃ€yttÃ¶Ã¶n
+napsauttamalla dokumentin nimeÃ€ tai sen vieressÃ€ olevaa pientÃ€ painiketta.
+
+<p>Palautettujen dokumenttien mÃ€Ã€rÃ€ on rajoitettu sataan. Voit muuttaa tÃ€tÃ€
+  lukua napsauttamalla <i>asetukset</i>-painiketta sivun ylÃ€reunassa.<p>
+}
+
+
+_textdatesearch_ [l=fi] {Haku pÃ€ivÃ€mÃ€Ã€rien perusteella}
+
+_texthelpdatesearch_ [l=fi] {
+PÃ€ivÃ€mÃ€Ã€rÃ€haun avulla voit etsiÃ€ dokumentteja, jotka vastaavat hakutermejÃ€
+ja kÃ€sittelevÃ€t tapahtumia tietyn ajanjakson ajalta. Voit hakea dokumentteja
+tietyltÃ€ vuodelta tai tiettyjen vuosien jaksolta. Et kuitenkaan vÃ€lttÃ€mÃ€ttÃ€ tarvitse
+hakutermejÃ€ - voit hakea pelkÃ€stÃ€Ã€n pÃ€ivÃ€mÃ€Ã€rien avulla; jos taas et kÃ€ytÃ€ 
+pÃ€ivÃ€mÃ€Ã€riÃ€, pÃ€ivÃ€mÃ€Ã€rÃ€haku ei aktivoidu.<p>
+}
+
+_texthelpdatehowtotitle_ [l=fi] {PÃ€ivÃ€mÃ€Ã€rÃ€haun kÃ€yttÃ¶tapa:}
+_texthelpdatehowto_ [l=fi] {
+<ul>
+   <li>Tiettyyn vuoteen keskittyvien dokumenttien haku:<p>
+   <ul>
+       <li>Kirjoita hakutermit tavalliseen tapaan.
+       <li>NÃ€ppÃ€ile haluamasi vuosi "Aloitus (tai ainoa) pÃ€ivÃ€mÃ€Ã€rÃ€" ruutuun.
+       <li>Jos pÃ€ivÃ€mÃ€Ã€rÃ€ on ennen nykyisen ajanlaskun alkua (eKr), 
+             valitse "eKr" vaihtoehto ruudun viereisestÃ€ pudotusvalikosta.
+       <li>Aloita haku tavalliseen tapaan.
+   </ul>
+<p><li>Dokumenttien haku useiden vuosien jaksolta:<p>
+   <ul>
+       <li>Kirjoita hakutermit tavalliseen tapaan.
+       <li>NÃ€ppÃ€ile aloituspÃ€ivÃ€mÃ€Ã€rÃ€ "Aloitus (tai ainoa) pÃ€ivÃ€mÃ€Ã€rÃ€" -ruutuun.
+       <li>NÃ€ppÃ€ile pÃ€Ã€ttymispÃ€ivÃ€mÃ€Ã€rÃ€ "Viimeinen pÃ€ivÃ€mÃ€Ã€rÃ€" -ruutuun
+       <li>Jos pÃ€ivÃ€mÃ€Ã€rÃ€ on ennen nykyisen ajanlaskun alkua (eKr), 
+             valitse "eKr" vaihtoehto ruudun viereisestÃ€ pudotusvalikosta.
+       <li>Aloita haku tavalliseen tapaan.
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresults_ [l=fi] {
+Yleisesti ottaen esimerkiksi vuoteen 1903 keskittyvÃ€ dokumenttihaku ei palauta vuonna 1903 kirjoitettuihin hakuteoksiin viittaavia dokumentteja, vaan  tÃ€hÃ€n vuoteen liittyviÃ€ dokumentteja vuoden molemmin puolin. Toisin sanoen, dokumentit voivat olla vaikkapa vuosijaksolta 1899-1911 ja sisÃ€ltÃ€vÃ€t vuoden 1903. Mutta on huomattava, ettÃ€ myÃ¶s dokumentit, joiden tekstissÃ€ esiintyy se vuosisata, johon vuosi 1903 kuuluu (esimerkiksi 20. vuosisata tai kahdeskymmenes vuosisata) tulevat haetuksi. TÃ€mÃ€ merkitsee sitÃ€, ettÃ€ joissakin palautetuissa dokumenteissa ei hakupÃ€ivÃ€mÃ€Ã€rÃ€Ã€ esiinny. Hauissa, joissa keskitytÃ€Ã€n useiden vuosien jaksoon, kaikki pÃ€ivÃ€mÃ€Ã€rÃ€t kÃ€sitellÃ€Ã€n yllÃ€kuvatun prosessin mukaisesti.
+<p>
+}
+
+_textchangeprefs_ [l=fi] {Asetusten vaihto}
+
+_texthelppreferences_ [l=fi] {
+
+<p>Napsauttamalla <i>asetukset</i>-painiketta sivun ylÃ€osassa
+voit muokata joitain kÃ€yttÃ¶liittymÃ€n ominaisuuksia tarkoitukseesi sopivaksi.
+ }
+
+_texthelpcollectionprefstitle_ [l=fi] {Kokoelman asetukset}
+_texthelpcollectionprefs_ [l=fi] {
+Jotkut kokoelmat koostuvat useista osakokoelmista, joihin haku voidaan
+kohdistaa kuhunkin erikseen tai jotka voidaan kÃ€sitellÃ€ yhtenÃ€ kokonaisuutena.
+TÃ€llaisissa tapauksissa, kÃ€yttÃ€mÃ€llÃ€ Asetukset-sivua, voit valita ne osakokoelmat, jotka haluat sisÃ€llyttÃ€Ã€
+haun piiriin.
+}
+
+_texthelplanguageprefstitle_ [l=fi] {Kielen asetukset}
+_texthelplanguageprefs_ [l=fi] {
+Jokaisella kokoelmalla on oma esityskielensÃ€ oletuksena, mutta voit vaihtaa
+kieltÃ€ halutessasi. Voit myÃ¶s muuttaa Greenstonen kÃ€yttÃ€mÃ€Ã€ merkintÃ€jÃ€rjestelmÃ€Ã€
+selainta varten -- ohjelmisto valitsee jÃ€rkevÃ€ltÃ€ tuntuvat oletukset, mutta
+joidenkin selainten kohdalla niiden visuaalista esitystapaa voi parantaa
+kÃ€yttÃ€mÃ€llÃ€ jotain toista merkintÃ€jÃ€rjestelmÃ€Ã€. Kukin kokoelma voidaan
+esittÃ€Ã€ joko standardinmukaisen graafisen kÃ€yttÃ¶liittymÃ€formaatin avulla
+tai tekstinÃ€. NÃ€kÃ¶vammaisia ajatellen tÃ€mÃ€ on erittÃ€in hyÃ¶dyllinen piirre,  
+koska suurien nÃ€yttÃ¶jen fontteja ja puhesyntetisaattoreja voidaan tÃ€llÃ¶in kÃ€yttÃ€Ã€.
+}
+
+_texthelppresentationprefstitle_ [l=fi] {Esityksen asetukset}
+_texthelppresentationprefs_ [l=fi] {
+Kokoelmasta riippuen, kÃ€ytettÃ€vissÃ€si voi olla useita vaihtoehtoja esityksen kontrolloimiseksi.
+
+<p>Internetin verkkosivukokoelmia kÃ€sitellessÃ€ voit hÃ€vittÃ€Ã€ Greenstone navigointipalkin
+dokumentin ylÃ€osasta: tÃ€llÃ¶in haun jÃ€lkeen pÃ€Ã€dyt hakemallesi sivulle,
+eikÃ€ Greenstone palkkia enÃ€Ã€ nÃ€y sillÃ€. Jos aiot suorittaa uuden haun tÃ€mÃ€n jÃ€lkeen,
+kÃ€ytÃ€ selaimen "Edellinen"-painiketta. Voit myÃ¶s poistaa varoitusviestin, jonka 
+Greenstone antaa aina, kun napsautat linkkiÃ€, joka ohjaa kÃ€yttÃ€jÃ€n digitaalisen
+kirjaston ulkopuoliseen internet-maailmaan. Joidenkin verkkosivukokoelmien
+kohdalla voit pÃ€Ã€ttÃ€Ã€, seuraatko "Haun Tulokset" -sivun linkkejÃ€ suoraan
+kyseenomaiseen URLiin, vai sen kopioon digitaalisessa kirjastossa.
+}
+
+_texthelpsearchprefstitle_ [l=fi] {Haun asetukset}
+_texthelpsearchprefs_ [l=fi] {
+ <p>Tekstin mallihaussa kÃ€ytetÃ€Ã€n kahdenlaisia painikkeita: "Kirjainkoot"
+-painikkeita kÃ€ytetÃ€Ã€n isojen ja pienten kirjainten eroja ja "Sanojen pÃ€Ã€tteet" 
+-painikkeita sanojen pÃ€Ã€tteitÃ€ huomioonotettaessa. Voit myÃ¶s kÃ€yttÃ€Ã€
+suurta hakuruutua, mikÃ€ mahdollistaa jopa kappaleen laajuiset haut.
+Suurtenkin tekstikokonaisuuksien haku onnistuu hÃ€mmÃ€styttÃ€vÃ€n nopeasti.
+
+<p>Voit kÃ€yttÃ€Ã€ "edistyneempÃ€Ã€" hakumuotoa, jossa voit yhdistellÃ€ hakutermejÃ€
+loogisten operaattoreiden, AND (&), OR (|) ja NOT (!), avulla. NÃ€in saat
+tehtyÃ€ tarkempia hakuja. Voit myÃ¶s kÃ€yttÃ€Ã€ hakuhistoria-ominaisuutta, joka
+nÃ€yttÃ€Ã€ viimeisimmÃ€t suoritetut haut. TÃ€mÃ€n avulla on helppo muokata ja
+toistaa jo tehtyjÃ€ hakuja. On myÃ¶s mahdollista rajoittaa palautettujen hakutulosten
+mÃ€Ã€rÃ€Ã€, samoin kuin esitettÃ€vien hakutulosten mÃ€Ã€rÃ€Ã€.}
+
+_texttanumbrowseoptions_ [l=fi] {Tietoja tÃ€stÃ€ kokoelmasta voi hakea viidellÃ€ eri tavalla:}
+
+_textsimplehelpheading_ [l=fi] {Miten voit etsiÃ€ tietoja _collectionname_-kokoelmasta}
+
+_texthelpscopetitle_ [l=fi] {Haun laajuus}
+_texthelpscope_ [l=fi] {
+<p>Useimmissa kokoelmissa voit valita erilaisia hakuindeksejÃ€, esimerkiksi
+tekijÃ€nindeksin tai nimekeindeksin. Joissain tapauksissa myÃ¶s osa- ja
+kappaleindeksit tulevat kysymykseen. YleensÃ€ koko dokumentti palautetaan
+haun tuloksena, oli kÃ€ytetty indeksi mikÃ€ tahansa.
+<p>Jos dokumentit ovat kirjan muodossa, ne avataan sopivasta paikasta. 
+}
Index: /gsdl/stable/macros/french.dm
===================================================================
--- /gsdl/stable/macros/french.dm	(revision 20131)
+++ /gsdl/stable/macros/french.dm	(revision 20131)
@@ -0,0 +1,829 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# French Language text and icon macros 
+# Translated by UNESCO for the UNESCO CD-ROMs
+# Contributions made by Vincent Dubuc, Georges Braoudakis and John Rose
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=fr] {PÃ©riodiques}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=fr] {source: }
+_textdate_ [l=fr] {date de publication: }
+_textnumpages_ [l=fr] {nombre de pages: }
+
+_textsignin_ [l=fr] {se connecter}
+
+_textdefaultcontent_ [l=fr] {La page demandÃ©e n'a pu Ãªtre trouvÃ©e.
+Utilisez s'il-vous-plaÃ®t le bouton Â«PrÃ©cÃ©dentÂ» de votre navigateur, ou le
+bouton Â«AccueilÂ» pour retourner Ã  la BibliothÃšque NumÃ©rique Greenstone.}  
+
+_textdefaulttitle_ [l=fr] {Erreur GSDL}
+
+_textbadcollection_ [l=fr] {Cette collection (appelÃ©e "_cvariable_") n'est pas installÃ©e sur ce systÃšme de bibliothÃšque numÃ©rique Greenstone}
+
+_textselectpage_ [l=fr] {-- SÃ©lectionner Page --}
+
+_collectionextra_ [l=fr] {Cette collection contient _about:numdocs_
+documents. Sa derniÃšre mise a jour a Ã©tÃ© faite il y a _about:builddate_
+jours.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=fr] {<p>Cette collection comprend _numdocs_ _If_("_numdocs_" eq
+"1",document,documents), pour un total de _numbytes_.
+<p><a href="_httppagex_(bsummary)">Cliquer ici</a> pour visualiser le
+rapport de construction de cette collection. 
+}  
+
+_textdescrcollection_ [l=fr] {}
+_textdescrabout_ [l=fr] {Page Ã  propos}
+_textdescrhome_ [l=fr] {Page d'accueil}
+_textdescrhelp_ [l=fr] {Page d'aide}
+_textdescrpref_ [l=fr] {Page de prÃ©fÃ©rences}
+_textdescrgreenstone_ [l=fr] {Logiciel de BibliothÃšque NumÃ©rique Greenstone}
+_textdescrusab_ [l=fr] {Qu'avez vous trouvÃ© difficile Ã  utiliser?}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=fr] {Recherche}  
+_labelSearch_ [l=fr] {Rechercher}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=fr] {Titre}  
+_labelTitle_ [l=fr] {Titres}  
+_textCreator_ [l=fr] {CrÃ©ateur}  
+_labelCreator_ [l=fr] {CrÃ©ateurs}  
+_textSubject_ [l=fr] {Sujet}  
+_labelSubject_ [l=fr] {Sujets}  
+_textDescription_ [l=fr] {Description}  
+_labelDescription_ [l=fr] {Descriptions}
+_textPublisher_ [l=fr] {Editeur}  
+_labelPublisher_ [l=fr] {Editeurs}
+_textContributor_ [l=fr] {Contributeur}  
+_labelContributor_ [l=fr] {Collaborateurs}
+_textDate_ [l=fr] {Date}  
+_labelDate_ [l=fr] {Dates}
+_textType_ [l=fr] {Type}  
+_labelType_ [l=fr] {Genres}
+_textFormat_ [l=fr] {Format}  
+_labelFormat_ [l=fr] {Formats}
+_textIdentifier_ [l=fr] {Identifiant}  
+_labelIdentifier_ [l=fr] {Identifiants}
+_textSource_ [l=fr] {Nom de fichier}  
+_labelSource_ [l=fr] {Noms de fichiers}
+_textLanguage_ [l=fr] {Langue }  
+_labelLanguage_ [l=fr] {Langues}  
+_textRelation_ [l=fr] {Relation}  
+_labelRelation_ [l=fr] {RÃ©fÃ©rences}
+_textCoverage_ [l=fr] {Couverture}  
+_labelCoverage_ [l=fr] {Couvertures}
+_textRights_ [l=fr] {Droits}  
+_labelRights_ [l=fr] {Droits}
+
+# DLS metadata set
+_textOrganization_ [l=fr] {Organisation}  
+_labelOrganization_ [l=fr] {Organisations}
+_textKeyword_ [l=fr] {Mot-clÃ©}  
+_labelKeyword_ [l=fr] {Mots-clefs}
+_textHowto_ [l=fr] {Comment }  
+_labelHowto_ [l=fr] {Comment}
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=fr] {Phrase}  
+_labelPhrase_ [l=fr] {Phrases}  
+_textCollage_ [l=fr] {Collage}  
+_labelCollage_ [l=fr] {Collage}  
+_textBrowse_ [l=fr] {Parcourir}  
+_labelBrowse_ [l=fr] {Parcourir}
+_textTo_ [l=fr] {Pour}  
+_labelTo_ [l=fr] {Ã}
+_textFrom_ [l=fr] {De}  
+_labelFrom_ [l=fr] {De}
+_textAcronym_ [l=fr] {Sigle}  
+_labelAcronym_ [l=fr] {Acronymes}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=fr] {Parcourir par_1_}  
+
+_textdescrSearch_ [l=fr] {Recherche de termes spÃ©cifiques}
+_textdescrType_ [l=fr] {Recherche par type de ressource}  
+_textdescrIdentifier_ [l=fr] {Recherche par identifiant de ressource}  
+_textdescrSource_ [l=fr] {Naviguer par noms de fichiers originaux}  
+_textdescrTo_ [l=fr] {Naviguer par champ Â«ÃÂ»}  
+_textdescrFrom_ [l=fr] {Naviguer par champ Â«DeÂ»}  
+_textdescrCollage_ [l=fr] {Naviguer par collage d'images}  
+_textdescrAcronym_ [l=fr] {Naviguer par sigles}  
+_textdescrPhrase_ [l=fr] {Naviguer par groupes de mots}  
+_textdescrHowto_ [l=fr] {Naviguer en utilisant les rubriques Â«Comment faireÂ»}  
+_textdescrBrowse_ [l=fr] {Naviguer parmi les documents}  
+_texticontext_ [l=fr] {Afficher le document}
+_texticonclosedbook_ [l=fr] {ouvrir ce document et afficher son contenu}
+_texticonnext_ [l=fr] {vers la section suivante}
+_texticonprev_ [l=fr] {vers la section prÃ©cÃ©dente}
+
+_texticonworld_ [l=fr] {Voir le document Web}
+
+_texticonmidi_ [l=fr] {Voir le document au format MIDI}
+_texticonmsword_ [l=fr] {Voir le document au format Microsoft Word}
+_texticonmp3_ [l=fr] {Voir le document au format MP3}
+_texticonpdf_ [l=fr] {Voir le document au format PDF}  
+_texticonps_ [l=fr] {Voir le document au format PostScript}  
+_texticonppt_ [l=fr] {Voir le document au format PowerPoint}  
+_texticonrtf_ [l=fr] {Voir le document au format RTF}  
+_texticonxls_ [l=fr] {Voir le document au format Microsoft Excel}  
+
+_page_ [l=fr] {page }
+_pages_ [l=fr] {pages}
+_of_ [l=fr] {sur }
+_vol_ [l=fr] {Volume }  
+_num_ [l=fr] {numÃ©ro }
+
+_textmonth00_ [l=fr] {}
+_textmonth01_ [l=fr] {janvier}
+_textmonth02_ [l=fr] {fÃ©vrier}
+_textmonth03_ [l=fr] {mars}
+_textmonth04_ [l=fr] {avril}
+_textmonth05_ [l=fr] {mai}
+_textmonth06_ [l=fr] {juin}
+_textmonth07_ [l=fr] {juillet}
+_textmonth08_ [l=fr] {aoÃ»t}
+_textmonth09_ [l=fr] {septembre}
+_textmonth10_ [l=fr] {octobre}
+_textmonth11_ [l=fr] {novembre}
+_textmonth12_ [l=fr] {dÃ©cembre}
+
+_texttext_ [l=fr] {Texte}  
+_labeltext_ [l=fr] {_texttext_}  
+_textdocument_ [l=fr] {Document}
+_textsection_ [l=fr] {Section}
+_textparagraph_ [l=fr] {Paragraphe}
+_textchapter_ [l=fr] {Chapitre}  
+_textbook_ [l=fr] {Livre}  
+
+_magazines_ [l=fr] {Magazines}
+
+_nzdlpagefooter_ [l=fr] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">Projet de bibliothÃšque numÃ©rique de
+Nouvelle-ZÃ©lande</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">DÃ©partement d'informatique</a>, 
+<a href="http://www.waikato.ac.nz">UniversitÃ© de Waikato</a>, 
+Nouvelle-ZÃ©lande}
+
+_linktextHOME_ [l=fr] {ACCUEIL}
+_linktextHELP_ [l=fr] {AIDE}
+_linktextPREFERENCES_ [l=fr] {PRÃFÃRENCES}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=fr] {BibliothÃšque NumÃ©rique Greenstone}
+
+_textnocollections_ [l=fr] {Pas de collection valide disponible (c'est-Ã -dire construite et publique)}  
+
+_textadmin_ [l=fr] {Page d'Administration}
+_textabgs_ [l=fr] {Ã Propos de Greenstone}
+_textgsdocs_ [l=fr] {Documentation de Greenstone}  
+
+_textdescradmin_ [l=fr] {Vous permet d'ajouter de nouveaux utilisateurs, de connaÃ®tre les
+collections qui se trouvent sur le systÃšme, et de connaÃ®tre les
+informations techniques concernant l'installation de Greenstone
+
+}
+
+_textdescrgogreenstone_ [l=fr] {Vous informe sur le logiciel Greenstone et le projet de BibliothÃšque
+NumÃ©rique de Nouvelle-ZÃ©lande, d'oÃ¹ il provient
+
+}
+
+_textdescrgodocs_ [l=fr] {Manuels de Greenstone}
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=fr] {l'Interface BibliothÃ©caire}  
+_textdescrgli_ [l=fr] {Vous aide Ã  crÃ©er de nouvelles collections, Ã  modifier ou supprimer des
+collections, ou bien encore Ã  ajouter des documents Ã  une collection existante
+}  
+
+package collector
+
+_textcollector_ [l=fr] {Le Collector}
+_textdescrcollector_ [l=fr] {Dans la plupart des cas, l'Interface BibliothÃ©caire, plus recente, devrait Ãªtre utilisÃ© en lieu et place du Collector.}  
+
+package depositor
+
+_textdepositor_ [l=fr] {Le DÃ©posant}
+_textdescrdepositor_ [l=fr] {Vous aide Ã  ajouter des documents Ã  des collections existantes}
+
+package gti
+
+_textgti_ [l=fr] {Interface de traduction Greenstone }  
+_textdescrtranslator_ [l=fr] {Vous aide Ã  mettre Ã  jour les versions multilingues de Greenstone}
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=fr] {Ã propos de cette collection}
+
+_textsubcols1_ [l=fr] {<p>La collection comprend _1_ sous-collections au total:
+<blockquote>}
+
+_textsubcols2_ [l=fr] {</blockquote>
+Vous pouvez vÃ©rifier (et modifier) la collection que vous
+utilisez couramment en utilisant la page des prÃ©fÃ©rences.}
+
+_titleabout_ [l=fr] {Ã propos}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=fr] {fermer cette partie de la bibliothÃšque}
+_texticonclosedbookshelf_ [l=fr] {ouvrir cette partie de la bibliothÃšque et afficher son contenu}
+_texticonopenbook_ [l=fr] {fermer ce livre}
+_texticonclosedfolder_ [l=fr] {ouvrir ce rÃ©pertoire et afficher son contenu}
+_texticonclosedfolder2_ [l=fr] {ouvrir la sous-section : }  
+_texticonopenfolder_ [l=fr] {fermer ce rÃ©pertoire}
+_texticonopenfolder2_ [l=fr] {fermer la sous-section : }  
+_texticonsmalltext_ [l=fr] {Afficher cette portion de texte}  
+_texticonsmalltext2_ [l=fr] {afficher le texte: }
+_texticonpointer_ [l=fr] {section active}  
+_texticondetach_ [l=fr] {Ouvrir cette page dans une nouvelle fenÃªtre}
+_texticonhighlight_ [l=fr] {Mettre en Ã©vidence les termes de recherche}
+_texticonnohighlight_ [l=fr] {Supprimer la mise en Ã©vidence des termes de recherche}
+_texticoncontracttoc_ [l=fr] {RÃ©duire la table des matiÃšres}
+_texticonexpandtoc_ [l=fr] {DÃ©velopper la table des matiÃšres}
+_texticonexpandtext_ [l=fr] {Afficher tout le texte}
+_texticoncontracttext_ [l=fr] {Afficher le texte uniquement pour la section sÃ©lectionnÃ©e}  
+_texticonwarning_ [l=fr] {<b>Attention: </b>}
+_texticoncont_ [l=fr] {Souhaitez-vous continuer?}
+
+_textltwarning_ [l=fr] {<div class="buttons">_imagecont_</div>
+_iconwarning_ DÃ©velopper le texte 
+Ã  ce niveau gÃ©nÃ©rera une importante quantitÃ© d'informations 
+Ã  traiter par votre navigateur
+}
+
+_textgoto_ [l=fr] {aller Ã  la page}
+_textintro_ [l=fr] {<i>(texte d'introduction)</i>}
+
+_textCONTINUE_ [l=fr] {CONTINUER ??}
+
+_textEXPANDTEXT_ [l=fr] {DÃVELOPPER LE TEXTE}  
+
+_textCONTRACTCONTENTS_ [l=fr] {RÃDUIRE LE CONTENU}  
+
+_textDETACH_ [l=fr] {DÃTACHER}
+
+_textEXPANDCONTENTS_ [l=fr] {DÃVELOPPER LE CONTENU}  
+
+_textCONTRACT_ [l=fr] {RÃDUIRE LE TEXTE}  
+
+_textHIGHLIGHT_ [l=fr] {METTRE EN ÃVIDENCE}  
+
+_textNOHIGHLIGHT_ [l=fr] {SUPPRIMER LA MISE EN ÃVIDENCE}  
+
+_textPRINT_ [l=fr] {IMPRIMER}
+
+_textnextsearchresult_ [l=fr] {prochain rÃ©sultat de la recherche}
+_textprevsearchresult_ [l=fr] {resultat de la recherche antÃ©rieure}  
+
+# macros for printing page
+_textreturnoriginal_ [l=fr] {Retour Ã  la page d'origine}
+_textprintpage_ [l=fr] {Imprimer cette page}
+_textshowcontents_ [l=fr] {Montrez la table des matiÃšres}  
+_texthidecontents_ [l=fr] {Masquer la table des matiÃšres}
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=fr] {_If_(_thislast_,resultats _thisfirst_ - _thislast_ pour la recherche: _cgiargq_,Pas de documents contenant: _cgiargq_)}
+_textnoquerytitle_ [l=fr] {Page de recherche}
+
+_textsome_ [l=fr] {quelques-uns des}  
+_textall_ [l=fr] {tous les}
+_textboolean_ [l=fr] {boolÃ©enne}  
+_textranked_ [l=fr] {classÃ©e
+}  
+_textnatural_ [l=fr] {naturelle}  
+_textsortbyrank_ [l=fr] {rang de pertinence}
+_texticonsearchhistorybar_ [l=fr] {historique de recherche}  
+
+_textifeellucky_ [l=fr] {Je me sent chanceux!}
+
+#alt text for query buttons
+_textusequery_ [l=fr] {utiliser cette requÃªte}
+_textfreqmsg1_ [l=fr] {Nombre de mots: }
+_textpostprocess_ [l=fr] {_If_(_quotedquery_,<br><i>post-traitÃ©s Ã  retrouver _quotedquery_</i>
+)}
+_textinvalidquery_ [l=fr] {Syntaxe de requÃªte invalide}
+_textstopwordsmsg_ [l=fr] {Les termes suivants Ã©tant trop frÃ©quents et ont Ã©tÃ© ignorÃ©s:}
+_textlucenetoomanyclauses_ [l=fr] {Votre requÃªte contenait un trop grand nombre de termes de recherche; veuillez essayer une requÃªte plus prÃ©cise. }  
+
+_textmorethan_ [l=fr] {Plus de }
+_textapprox_ [l=fr] {Ã propos }
+_textnodocs_ [l=fr] {Aucun document ne satisfait la requÃªte.}
+_text1doc_ [l=fr] {1 document satisfait la requÃªte.}
+_textlotsdocs_ [l=fr] {documents satisfont la requÃªte.}
+_textmatches_ [l=fr] {RÃ©sultats }
+_textbeginsearch_ [l=fr] {DÃ©marrer la recherche}
+_textrunquery_ [l=fr] {ExÃ©cuter la requÃªte}  
+_textclearform_ [l=fr] {Effacer le formulaire}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=fr] {Mots}  
+_textinfield_ [l=fr] {... dans le champ}  
+_textfoldstem_ [l=fr] {(casse, fin des mots)}  
+
+_textadvquery_ [l=fr] {Ou tapez une requÃªte directement:}  
+_textallfields_ [l=fr] {Tous les champs}  
+_texttextonly_ [l=fr] {texte seulement
+}
+_textand_ [l=fr] {et}  
+_textor_ [l=fr] {ou}  
+_textandnot_ [l=fr] {et pas}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+# the space after "level" (before the right bracket) is required, otherwise no space between "Search" and "in"
+
+_textsimplesearch_ [l=fr] {Rechercher dans _indexselection__If_(_jselection_,associÃ©(e) Ã  _jselection_)_If_(_gselection_, au niveau de _gselection_)_If_(_nselection_,en langue _nselection_)_If_(_sfselection_,\,_allowformbreak_ en triant les rÃ©sultats par _sfselection_\,) _querytypeselection_ mots :}  
+
+_textadvancedsearch_ [l=fr] {Rechercher dans _indexselection__If_(_jselection_, associÃ©(e) Ã  _jselection_)_If_(_gselection_, au niveau de _gselection_)_If_(_nselection_, en langue _nselection_) par requÃªte _querytypeselection_ :}  
+
+_textadvancedmgppsearch_ [l=fr] {Rechercher dans _indexselection__If_(_jselection_, associÃ©(e) Ã  _jselection_)_If_(_gselection_, au niveau de _gselection_)_If_(_nselection_, en langue _nselection_) et afficher les rÃ©sultats en disposition _formquerytypeadvancedselection_ :}  
+
+_textadvancedlucenesearch_ [l=fr] {Rechercher dans _indexselection__If_(_jselection_, associÃ©(e) Ã  _jselection_)_If_(_gselection_, au niveau de _gselection_)_If_(_nselection_, en langue _nselection_)_If_(_sfselection_,_allowformbreak_ en triant les rÃ©sultats par _sfselection_) : }  
+
+# the space after "Search" is required, otherwise no space between "Search" and "in"
+
+_textformsimplesearch_ [l=fr] {Rechercher _If_(_jselection_, _jselection_) _If_(_gformselection_, au niveau de _gformselection_ ) _If_(_nselection_, en langue _nselection_)_If_(_sfselection_,\, en triant les rÃ©sultats par _sfselection_\,) selon _formquerytypesimpleselection_ critÃšres suivants : }  
+
+_textformadvancedsearchmgpp_ [l=fr] {Rechercher _If_(_jselection_,_jselection_ )_If_(_gformselection_,au niveau de _gformselection_)_If_(_nselection_,en langue _nselection_ ) et afficher les rÃ©sultats en disposition  _formquerytypeadvancedselection_ :}  
+
+_textformadvancedsearchlucene_ [l=fr] {Rechercher _If_(_jselection_, _jselection_)_If_(_gformselection_,  au niveau de _gformselection_)_If_(_nselection_, en langue _nselection_)_If_(_sfselection_,\, en triant les rÃ©sultats par _sfselection_\,) selon les critÃšres suivants : }  
+
+_textnojsformwarning_ [l=fr] {Attention: Javascript est dÃ©sactivÃ© dans votre navigateur web. <br> Pour utiliser la recherche par formulaire, veuillez l'activer.}
+_textdatesearch_ [l=fr] {On peut effectuer des recherches de documents compris
+dans un certain intervalle de dates, ou des documents comprenant une
+date particuliÃšre. C'est une fonctionnalitÃ© facultative de la
+recherche.}
+_textstartdate_ [l=fr] {Date de dÃ©but (ou unique):}
+_textenddate_ [l=fr] {Date de fin:}
+_textbc_ [l=fr] {avant notre Ãšre}
+_textad_ [l=fr] {de notre Ãšre}
+_textexplaineras_ [l=fr] {Â«av. N.E.Â» et Â«de N.E.Â» sont une autre faÃ§on d'exprimer respectivement, Â«av. J.-C.Â» et Â«ap. J.-C.Â». Ces termes sont considÃ©rÃ©s comme Ã©tant moins marquÃ©s culturellement et signifient Â«avant notre ÃšreÂ» et Â«de notre ÃšreÂ».}  
+
+_textstemon_ [l=fr] {(ignorer la fin des mots)}  
+
+_textsearchhistory_ [l=fr] {L'historique de recherche:}  
+
+#text macros for search history
+_textnohistory_ [l=fr] {L'historique de recherches est vide}  
+_texthresult_ [l=fr] {rÃ©sultat}
+_texthresults_ [l=fr] {rÃ©sultats}
+_texthallwords_ [l=fr] {tous les mots}
+_texthsomewords_ [l=fr] {quelques mots}
+_texthboolean_ [l=fr] {boolÃ©enne}  
+_texthranked_ [l=fr] {avec score}
+_texthcaseon_ [l=fr] {la casse doit correspondre}
+_texthcaseoff_ [l=fr] {sans tenir compte de la casse}  
+_texthstemon_ [l=fr] {racines des mots}
+_texthstemoff_ [l=fr] {les mots en entier}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=fr] {Les prÃ©fÃ©rences ont Ã©tÃ© appliquÃ©es comme suit. N'utilisez pas le bouton
+'PrÃ©cÃ©dent' de votre navigateur, sinon elles seront annulÃ©es. Utilisez plutÃŽt l'un des boutons
+de la barre d'accÃšs ci-dessus.}
+_textsetprefs_ [l=fr] {Appliquer}
+_textsearchprefs_ [l=fr] {PrÃ©fÃ©rences de recherche}
+_textcollectionprefs_ [l=fr] {PrÃ©fÃ©rences de collection}
+_textpresentationprefs_ [l=fr] {PrÃ©fÃ©rences de prÃ©sentation}
+_textpreferences_ [l=fr] {PrÃ©fÃ©rences}
+_textcasediffs_ [l=fr] {Respect de la casse:}  
+_textignorecase_ [l=fr] {ignorer la casse}  
+_textmatchcase_ [l=fr] {les majuscules et les minuscules doivent correspondre}  
+_textwordends_ [l=fr] {Terminaison des mots :}  
+_textstem_ [l=fr] {ignorer la terminaison des mots}  
+_textnostem_ [l=fr] {le mot entier doit correspondre}  
+_textaccentdiffs_ [l=fr] {diffÃ©rence d'accent:}  
+_textignoreaccents_ [l=fr] {ignorer les accents}  
+_textmatchaccents_ [l=fr] {Les accents doivent correspondre}  
+
+_textprefop_ [l=fr] {Afficher jusqu'Ã  _maxdocoption_ rÃ©sultats avec _hitsperpageoption_ rÃ©sultats par page.}
+_textextlink_ [l=fr] {AccÃšs aux pages web externes: }
+_textintlink_ [l=fr] {Documents source rÃ©cupÃ©rÃ©s de:}
+_textlanguage_ [l=fr] {Langue de l'interface: }
+_textencoding_ [l=fr] {Encodage: }
+_textformat_ [l=fr] {Format de l'interface: }
+_textall_ [l=fr] {tous}
+_textquerymode_ [l=fr] {Mode de recherche:}  
+_textsimplemode_ [l=fr] {mode de recherche simple}  
+_textadvancedmode_ [l=fr] {mode de recherche avancÃ©e (autoriser les recherches boolÃ©ennes utilisant !, &amp;, |, et les parenthÃšses)}
+_textlinkinterm_ [l=fr] {Ã  travers les pages intermÃ©diaires}
+_textlinkdirect_ [l=fr] {aller directement lÃ -bas}
+_textdigitlib_ [l=fr] {la bibliothÃšque numÃ©rique}
+_textweb_ [l=fr] {le web}
+_textgraphical_ [l=fr] {Graphique}
+_texttextual_ [l=fr] {Texte}  
+_textcollectionoption_ [l=fr] {<p>
+Sous-collections Ã  inclure:
+<br>}
+
+_textsearchtype_ [l=fr] {Style de requÃªte:}  
+_textformsearchtype_ [l=fr] {cadre de _formnumfieldoption_ champs}  
+_textplainsearchtype_ [l=fr] {normal avec la boÃ®te de recherche _boxsizeoption_ }  
+_textregularbox_ [l=fr] {ligne unique}  
+_textlargebox_ [l=fr] {grande 
+}  
+
+_textrelateddocdisplay_ [l=fr] {afficher les documents proches}  
+_textsearchhistory_ [l=fr] {Historique de recherche :}  
+_textnohistory_ [l=fr] {L'historique de recherche n'est pas disponible}  
+_texthistorydisplay_ [l=fr] {afficher les _historynumrecords_ derniÃšres requÃªtes}  
+_textnohistorydisplay_ [l=fr] {ne pas afficher l'historique de recherche}  
+
+_textbookoption_ [l=fr] {Mode lecteur de livre :}  
+_textbookvieweron_ [l=fr] {actif}  
+_textbookvieweroff_ [l=fr] {inactif}  
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=fr] {Trier les documents par}
+_textalsoshowing_ [l=fr] {comprenant Ã©galement}
+_textwith_ [l=fr] {comprenant au plus}
+_textdocsperpage_ [l=fr] {documents par page}
+
+_textfilterby_ [l=fr] {Obtenir les documents contenant}
+_textall_ [l=fr] {tous les}
+_textany_ [l=fr] {certains des}
+_textwords_ [l=fr] {mots}
+_textleaveblank_ [l=fr] {laisser cette boÃ®te vide pour obtenir tous les documents}  
+
+_browsebuttontext_ [l=fr] {"Trier les documents"}
+
+_nodata_ [l=fr] {<i>pas de donnÃ©es</i>}
+_docs_ [l=fr] {documents}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=fr] {Aide}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=fr] {parcourir les documents par _1_ en cliquant sur le bouton _2_}  
+
+_textSearchhelp_ [l=fr] {rechercher des mots particuliers qui figurent dans le texte en cliquant sur le bouton _labelSearch_ }  
+_textTohelp_ [l=fr] {parcourir les documents par le champ Â«ÃÂ» en cliquant sur le bouton _labelTo_ }  
+_textFromhelp_ [l=fr] {parcourir les documents par le champ Â«DeÂ» en cliquant sur le bouton _labelFrom_ }  
+_textBrowsehelp_ [l=fr] {parcourir les documents}  
+_textAcronymhelp_ [l=fr] {parcourir les documents en fonction de l'occurrence d'un sigle, en cliquant sur le bouton _labelAcronym_}  
+_textPhrasehelp_ [l=fr] {parcourir les phrases dans les documents en cliquant sur le bouton  _labelPhrase_ . Cela utilise le navigateur de pharses phind.}  
+
+_texthelptopicstitle_ [l=fr] {ThÃšmes}
+
+_textreadingdocs_ [l=fr] {Comment lire les documents}
+
+_texthelpreadingdocs_ [l=fr] {<p>Lorsqu'un document est affichÃ©, titre ou image de la page de couverture apparaÃ®t en haut et Ã  gauche. Dans certaines collections, une table des matiÃšres s'affiche, tandis que dans d'autres (si l'option image paginÃ©e est utilisÃ©e), vous ne trouverez que le numÃ©ro de la page sÃ©lectionnÃ©e et une boÃ®te qui vous permet soit de sÃ©lectionner une nouvelle page, soit de passer Ã  la page suivante ou prÃ©cÃ©dente. Dans la table des matiÃšres, le titre de la section sÃ©lectionnÃ©e est affichÃ© en gras, et la table peut Ãªtre dÃ©veloppÃ©e -- cliquez sur les dossiers pour les ouvrir ou les fermer ; cliquez sur le livre ouvert en haut de la page si vous souhaitez le fermer.</p>
+
+<p>Au-dessous, on trouve le texte de la section sÃ©lectionnÃ©e. A la fin de votre lecture, vous pouvez utiliser l'une des deux flÃšches en bas de page, soit pour passer Ã  la section suivante, soit pour revenir Ã  la section prÃ©cÃ©dente.</p>
+
+<p>Sous le titre ou l'image de la page de couverture se trouvent plusieurs boutons. Cliquez sur <i>_document:textEXPANDTEXT_</i> pour afficher le texte entier de la section ou du document sÃ©lectionnÃ©. Si le document est volumineux, le chargement peut Ãªtre long et peut nÃ©cessiter beaucoup de mÃ©moire ! Cliquez sur 
+<i>_document:textEXPANDCONTENTS_</i> pour dÃ©velopper la table de matiÃšres en entiÃšre pour que vous puissiez voir les titres de tous les chapitres et 
+sous-sections. Cliquez sur <i>_document:textDETACH_</i> pour crÃ©er une nouvelle fenÃªtre pour ce document. (Cela peut Ãªtre utile si vous voulez comparer 
+des documents, ou lire deux documents Ã  la fois). Finalement, lorsque vous faites une recherche, les mots-clefs utilisÃ©s dans la recherche sont mis en 
+Ã©vidence dans le texte du document affichÃ©. Cliquez sur <i>_document:textNOHIGHLIGHT_</i> pour dÃ©sactiver la mise en Ã©vidence.</p>
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=fr] {Ouvrir cette Ã©tagÃšre}  
+_texthelpopenbook_ [l=fr] {Ouvrir/Fermer ce livre}  
+_texthelpviewtextsection_ [l=fr] {Voir cette section du texte}  
+_texthelpexpandtext_ [l=fr] {Afficher tout le texte, ou pas}
+_texthelpexpandcontents_ [l=fr] {Ãtendre la table des matiÃšres, oÃ¹ pas}  
+_texthelpdetachpage_ [l=fr] {Ouvrir cette page dans une nouvelle fenÃªtre}
+_texthelphighlight_ [l=fr] {Mettre en Ã©vidence les mots recherchÃ©s, ou pas}
+_texthelpsectionarrows_ [l=fr] {Aller a la section suivante/prÃ©cÃ©dente}  
+
+
+_texthelpsearchingtitle_ [l=fr] {Comment faire une requÃªte pour certains mots en particulier}
+
+_texthelpsearching_ [l=fr] {"<p>
+ Ã partir de la page de recherche, vous pouvez formuler votre recherche
+ en suivant le mode d'emploi suivant:<p>
+
+   <ol>
+       <li>SpÃ©cifiez les Ã©lÃ©ments dans lesquels vous souhaitez faire la recherche
+       <li>Indiquez si vous voulez rechercher tous les mots ou seulement 
+           certains mots
+       <li>Entrez les mots pour lesquels vous souhaitez faire une recherche
+       <li>Cliquez sur le bouton <i>DÃ©marrer la recherche</i>
+   </ol>
+
+ <p>Lorsque vous faites une recherche, les titres des vingt premiers
+ documents qui correspondent Ã  la requÃªte sont affichÃ©s. Le bouton en fin de liste vous permet d'avoir accÃšs aux vingt documents
+ suivants. Ã partir de lÃ  vous pourrez Ã  nouveau avoir accÃšs aux
+ vingt documents suivants, et ainsi de suite. Cliquez sur le titre d'un
+ document, ou sur le petit bouton situÃ© Ã  sa gauche, pour l'afficher.
+
+ <p>Le nombre de documents restituÃ©s est limitÃ© Ã  100 par dÃ©faut.
+ Vous pouvez modifier ce nombre en cliquant sur le bouton
+ <i>_Global:linktextPREFERENCES_</i> en haut de la page.<p>"}  
+
+_texthelpquerytermstitle_ [l=fr] {Chercher des termes}  
+_texthelpqueryterms_ [l=fr] {<p>Tout ce que vous entrez dans la boÃ®te de recherche est interprÃ©tÃ©
+comme une liste de mots appelÃ©e Â«termes de la rechercheÂ». Chaque terme
+doit Ãªtre alphanumÃ©rique (ne peut contenir que des lettres ou des
+chiffres), ou bien Ãªtre une sÃ©quence de mots entourÃ©e de guillemets doubles ("..."). 
+Les termes de la recherche sont supposÃ©s Ãªtre sÃ©parÃ©s par des
+espaces: si des caractÃšres de ponctuation sont prÃ©sents, ils sont
+considÃ©rÃ©s comme Ã©tant des espaces servant Ã  sÃ©parer les termes et sont
+ignorÃ©s lors de la recherche. Il n'est pas possible d'effectuer une
+recherche sur des mots contenant des caractÃšres de ponctuation.
+
+<p>Par exemple, la recherche<p>
+
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>est Ã©quivalente Ã <p>
+      <ul><kbd>Agro forestry in the Pacific Islands Systems for Sustainability 1993 </kbd></ul><p>
+}  
+
+_texthelpmgppsearching_ [l=fr] {Pour les collections construites avec MGPP quelques autres options sont disponibles.
+ <ul>
+ <li>Un <b>*</b> en fin d'un terme de requÃªte correspond Ã  tous les mots <b>commenÃ§ant par</b> ce terme, par exemple, <b>ordinateur*</b> correspond Ã  tous les mots commenÃ§ant par  <b>ordinateur</b>.
+ <li><b>/x</b> peut Ãªtre utilisÃ© pour donner un poids supÃ©rieur Ã  l'un ou plusieurs des termes recherchÃ©s, par exemple <b>computer/10 sciences</b> donne Ã  ordinateur 10 fois plus de poids que sciences lors du classement des documents.
+ </ul>}  
+
+_texthelplucenesearching_ [l=fr] {Pour les collections construites avec Lucene quelques autres options sont disponibles.
+
+ <ul>
+ <li><b>?</b> peut Ãªtre utilisÃ© comme joker Ã  la place d'une seule lettre. Par exemple, <b>b?t</b> va correspondre Ã  <b>bet</b> <b>bit</b> et <b>bat</b> etc.
+ <li> <b>*</b> peut Ãªtre utilisÃ© comme joker Ã  la place de plusieurs lettres. Par exemple, <b> ordinateur*</b> correspond Ã  tous les mots commenÃ§ant par <b>ordinateur</b>.
+ </ul>
+ Ces deux jokers peuvent Ãªtre utilisÃ©s au milieu d'un terme, ou Ã  la fin. Ils ne peuvent pas Ãªtre utilisÃ©s au dÃ©but d'un terme de recherche.}  
+
+_texthelpquerytypetitle_ [l=fr] {Type de recherche}
+_texthelpquerytype_ [l=fr] {<p>Il y a deux types de recherche.
+
+<ul>
+
+<li>Recherches pour <b>tous</b> les mots. Ce type de recherche restitue les documents qui contiennent tous les mots spÃ©cifiÃ©s. Les documents qui correspondent Ã  la recherche sont affichÃ©s dans l'ordre alphabÃ©tique.<p>
+
+<li>Recherches pour <b>quelques-uns</b> des mots. Vous pouvez entrer une liste de mots qui sont susceptibles d'apparaÃ®tre dans les documents que vous recherchez. Les documents sont alors affichÃ©s dans un ordre qui reflÃšte leur pertinence. Lors de la dÃ©termination du degrÃ© de pertinence d'un document, il est tenu compte des critÃšres suivants:
+
+<p><ul>
+
+<li>Plus il y a de termes de la recherche dans le document, plus le
+document est pertinent;
+
+<li>les termes rares sont considÃ©rÃ©s comme plus importants que ceux qui
+sont courants;
+
+<li>les petits documents sont considÃ©rÃ©s comme Ã©tant plus pertinents que
+les documents plus volumineux.
+
+</ul>
+
+</ul>
+
+<p>Vous pouvez utiliser autant de termes de recherche que vous le souhaitez -- une phrase entiÃšre, oÃ¹ mÃªme un paragraphe entier. Si vous spÃ©cifiez un seul terme, alors les documents qui satisfont Ã  la requÃªte seront classÃ©s en fonction du nombre d'occurrences du terme dans chaque document.
+
+<p>
+}  
+
+_texthelpadvancedsearchtitle_ [l=fr] {Recherche avancÃ©e en utilisant le moteur de recherche _1_}
+
+_texthelpadvancedsearch_ [l=fr] {<p>Si vous avez sÃ©lectionnÃ© le mode de recherche avancÃ©e (dans prÃ©fÃ©rences), les options de recherche sont lÃ©gÃšrement diffÃ©rentes. }  
+
+_texthelpadvsearchmg_ [l=fr] {La fonction recherche avancÃ©e dans les collections MG permet deux options, classÃ©e et boolÃ©ene. Une recherche <b>classÃ©e</b> est exactement la mÃªme que la recherche <b>quelques-uns</b> dÃ©crite dans <a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_}  
+
+_texthelpbooleansearch_ [l=fr] {La recherche <b>boolÃ©enne</b> offre la possibilitÃ© de combiner des termes en utilisant & (pour Â«andÂ»), | (pour Â«ouÂ»),  et ! (pour Â«nonÂ»), en se servant des parenthÃšses pour regroupement si vous le dÃ©sirez. LâopÃ©rateur par dÃ©faut est | (pour Â«ouÂ»). 
+
+<p> Par exemple, <b>escargot & Ã©levage</b> restituera les documents qui contiennent le mot <b>escargot</b> ET le mot  <b>Ã©levage</b>, tandis que <b>escargot | Ã©levage</b> restituera les documents qui contiennent le mot <b>escargot</b>  OU le mot <b>Ã©levage</b>. <b>escargot ! Ã©levage</b> restituera les documents qui contiennent le mot <b>escargot</b> et qui NE CONTIENNENT PAS le mot <b>Ã©levage</b>. 
+
+<p> Des requÃªtes plus prÃ©cises peuvent Ãªtre formulÃ©es en utilisant des combinaisons dâopÃ©rateurs et de parenthÃšses. Par  exemple, <b>(mouton | bÅuf) & (ferme | institut)</b>, or <b>mouton | bÅuf | chÃšvre ! cochon</b>. }  
+
+_texthelpadvsearchmgpp_ [l=fr] {Les recherches avancÃ©es dans les collections MGPP utilisent les opÃ©rateurs boolÃ©ens. _texthelpbooleansearch_
+ <p> Les rÃ©sultats peuvent Ãªtre affichÃ©s en ordre <b>classÃ©</b>, comme dÃ©crit pour la recherche <b>quelques-uns</b> des mots dans <a href="\#query-type">_texthelpquerytypetitle_</a>, ou en ordre "naturel" (sÃ©quentiel). Ce dernier ordre est celui dans lequel les documents ont Ã©tÃ© traitÃ©s lors de la crÃ©ation de la collection.
+ <p> 
+Parmi les autres opÃ©rateurs il y a <b>NEARx</b> et <b>WITHINx</b>.
+NEARx est utilisÃ© pour indiquer la distance maximale en mots (x mots) qui sÃ©pare deux termes de la requÃªte, pour que le document soit sÃ©lectionnÃ©.
+WITHINx prÃ©cise que le second terme doit se trouver dans les x mots <i>aprÃšs</ i> le premier terme. Ceci est similaire Ã  NEARx, mais l'ordre est important. La valeur par dÃ©faut de la distance est de 20.}  
+
+_texthelpadvancedsearchextra_ [l=fr] {NOTE: Ces opÃ©rateurs sont tous ignorÃ©s si vous faites votre recherche en mode de recherche simple.}
+
+_texthelpadvsearchlucene_ [l=fr] {Les recherches avancÃ©es dans les collections de type Lucene utilisent des opÃ©rateurs boolÃ©ens. _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=fr] {Recherche par champ}  
+
+_texthelpformsearch_ [l=fr] {<p>La recherche par champ offre la possibilitÃ© de combiner les recherches sur plusieurs champs. Par exemple, on peut rechercher le mot "Smith" dans le titre ET "Ã©levage d'escargots" dans le champ Sujet. En mode de recherche simple, chaque ligne de la grille se comporte comme une ligne de recherche normale. Les diffÃ©rentes lignes de la grille sont combinÃ©es avec ET (pour une recherche "tous" ) ou OU (pour une recherche "quelques-uns"). Les termes Ã  l'intÃ©rieur d'un champ sont Ã©galement combinÃ©es de la mÃªme faÃ§on. En mode avancÃ©, vous pouvez spÃ©cifier diffÃ©rentes combinaisons de "et"/"ou"/"et pas" entre les champs en utilisant les listes dÃ©roulantes, et de l'intÃ©rieur d'un champ donnÃ©, vous pouvez Ã©galement utiliser des opÃ©rateurs boolÃ©ens.}  
+
+_texthelpformstemming_ [l=fr] {Les cases Â«Respect de la casseÂ» et Â«Terminaison des motsÂ» vous permettent de chosir si les termes Ã  l'intÃ©rieur d'un champ sont Â«casefoldedÂ» (ignorer la casse) ou Â«stemmedÂ» (ignorer la terminaison des mots). Elles sont toutes deux dÃ©sactivÃ©es par dÃ©faut pour la recherche avancÃ©e avec grille.}  
+
+_textdatesearch_ [l=fr] {Rechercher par dates}  
+
+_texthelpdatesearch_ [l=fr] {La recherche par date vous permet de trouver des documents qui non
+seulement remplissent vos critÃšres de recherche, mais traitent aussi
+d'Ã©vÃ©nements situÃ©s dans un intervale temporel particulier. Vous pouvez
+rechercher des documents d'une annÃ©e particuliÃšre d'un intervalle particulier d'annÃ©es. Remarquez qu'il n'est pas nÃ©cessaire de
+fournir des critÃšres de recherche: on peut se contenter d'une recherche
+par date. De mÃªme, il n'est pas nÃ©cessaire d'utiliser des dates dans la
+recherche: si vous ne prÃ©cisez aucune date tout se dÃ©roule comme si la
+recherche par date n'existait pas.<p>
+}
+
+_texthelpdatehowtotitle_ [l=fr] {Comment utiliser cette fonctionnalitÃ©:}
+_texthelpdatehowto_ [l=fr] {<ul>
+   <li>Pour rechercher des documents traitant d'une annÃ©e prÃ©cise:<p>
+   <ul>
+       <li>Tapez les critÃšres de recherche comme vous le faites habituellement.
+       <li>Tapez l'annÃ©e souhaitÃ©e dans la boÃ®te "Date de dÃ©but (ou unique)".
+       <li>Si votre date est antÃ©rieure Ã  notre Ãšre (avant
+           JÃ©sus-Christ), choisissez l'option "avant notre Ãšre" dans le menu dÃ©roulant
+           situÃ© prÃšs de cette boÃ®te.
+       <li>DÃ©marrez la recherche comme vous le faites habituellement.
+   </ul>
+<p><li>Pour rechercher des documents couvrant une pÃ©riode ou un intervalle d'annÃ©es:<p>
+   <ul>
+       <li>Tapez les critÃšres de recherche comme vous le faites habituellement.
+       <li>Tapez l'annÃ©e de dÃ©but dans la boÃ®te "Date de dÃ©but (ou unique)".
+       <li>Tapez l'annÃ©e de fin dans la boÃ®te "Date de fin".
+       <li>SÃ©lectionez l'option "avant notre Ãšre" dans le menu dÃ©roulant situÃ©
+           prÃšs de la boÃ®te de saisie pour toute date antÃ©rieure Ã  notre Ãšre (avant
+           JÃ©sus-Christ).
+       <li>DÃ©marrez la recherche comme vous le faites habituellement.
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=fr] {Fonctionnement de cette recherche}
+_texthelpdateresults_ [l=fr] {De maniÃšre gÃ©nÃ©rale, une recherche de documents traitant de l'an 1903 ne
+renverra pas des documents qui rÃ©fÃ©rencent des livres Ã©crits en 1903,
+mais uniquement des documents traitant de l'an 1903. Cependant, Ã©tant
+donnÃ©e la maniÃšre dont les dates des documents sont recherchÃ©es, cela
+renverra les documents dans un intervalle d'annÃ©es (comme par exemple
+1899-1911) incluant 1903, ainsi que les documents citant dans leur texte
+le siÃšcle auquel l'annÃ©e 1903 appartient (par exemple, le XXÃšme siÃšcle,
+ou le vingtiÃšme siÃšcle). Cela signifie que pour certains documents, les
+dates spÃ©cifiÃ©es dans la recherche n'apparaÃ®tront pas effectivement dans
+le texte du document. Pour une recherche par intervalles, tout ce qui
+prÃ©cÃšde s'applique Ã  toutes les dates de l'intervalle.<p>
+}
+
+_textchangeprefs_ [l=fr] {Modification des prÃ©fÃ©rences}  
+
+_texthelppreferences_ [l=fr] {<p>Si vous cliquez sur le bouton <i>PrÃ©fÃ©rences</i> en haut de la page,
+vous pourrez alors modifier certaines fonctionnalitÃ©s de l'interface
+utilisateur afin que celles-ci conviennent Ã  vos propres besoins.
+
+}  
+
+_texthelpcollectionprefstitle_ [l=fr] {PrÃ©fÃ©rences de cette collection}  
+_texthelpcollectionprefs_ [l=fr] {<p>Certaines collections sont constituÃ©es de plusieurs sous-collections,
+dans lesquelles on peut faire des recherches individuellement ou globalement. Si vous le souhaitez, vous pouvez spÃ©cifier dans la page Â«PrÃ©fÃ©rencesÂ» les
+sous-collections dans lesquelles vous voulez faire vos recherches.
+}  
+
+_texthelplanguageprefstitle_ [l=fr] {PrÃ©fÃ©rences de langue}
+_texthelplanguageprefs_ [l=fr] {<p>Une langue de prÃ©sentation est associÃ©e Ã  chaque collection par dÃ©faut, mais vous pouvez la modifier si vous le souhaitez. Vous pouvez aussi modifier la codification de caractÃšres utilisÃ©e par Greenstone pour lâaffichage dans le navigateur â le logiciel utilise des options de bon sens par dÃ©faut, mais avec certains navigateurs, on peut obtenir de meilleurs rÃ©sultats visuels en modifiant la codification de caractÃšres. Quelle que soit la collection, vous pouvez choisir une prÃ©sentation qui utilise une interface texte Ã  la place de l'interface graphique standard. Cela peut Ãªtre particuliÃšrement utile pour les utilisateurs qui ont des problÃšmes de vue et qui utilisent des grandes polices ou bien des synthÃ©tiseurs vocaux.
+}  
+
+_texthelppresentationprefstitle_ [l=fr] {PrÃ©fÃ©rences de prÃ©sentation}
+_texthelppresentationprefs_ [l=fr] {Pour chaque collection, vous pouvez spÃ©cifier plusieurs options
+qui contrÃŽlent la prÃ©sentation.
+
+<p>Â«Collection de pages webÂ» permet de masquer la barre de navigation
+Greenstone qui apparaÃ®t en haut de chaque page d'un document, de telle
+faÃ§on que lorsque vous avez fait une recherche, la page qui satisfait Ã 
+la requÃªte est affichÃ©e directement sans l'en-tÃªte Greenstone. Pour
+effectuer une autre recherche, vous devrez alors utiliser le bouton
+Â«PrÃ©cÃ©denteÂ» de votre navigateur. Ce type de collection vous permet
+aussi de supprimer le message d'avertissement affichÃ© par Greenstone
+lorsqu'un lien hypertexte vous renvoie en dehors de la collection de la
+bibliothÃšque numÃ©rique, quelque part ailleurs sur la toile (web). Pour
+certaines collections vous pouvez aussi contrÃŽler les liens qui
+apparaissent sur la page des rÃ©sultats de la recherche de telle faÃ§on que
+ces liens vous renvoient directement sur l'URL en question, plutÃŽt que
+sur la copie qui se trouve dans la bibliothÃšque numÃ©rique.
+}  
+
+_texthelpsearchprefstitle_ [l=fr] {PrÃ©fÃ©rences de recherche}
+_texthelpsearchprefs_ [l=fr] {<p>Vous pouvez choisir le mode recherche Â«avancÃ©eÂ» qui offre la possibilitÃ© de combiner des termes 
+en utilisant & (pour Â«etÂ»), | (pour Â«ouÂ»), et ! (pour Â«nonÂ»), en se servant des parenthÃšses pour regroupement 
+si vous le dÃ©sirez. Ceci vous permet de formuler des requÃªtes plus prÃ©cises.
+ <p>_selectsearchtypeprefs_
+ <p>_selectwordmodificationprefs_
+ <p>Vous pouvez activer le dispositif dâhistorique de recherche. Ceci facilite la formulation de requÃªtes de recherche 
+qui sont modifiÃ©es lÃ©gÃšrement par rapport aux requÃªtes antÃ©rieures.
+ <p>Finalement, vous pouvez contrÃŽler le nombre de documents pertinents restituÃ©s ainsi que le nombre de documents 
+prÃ©sentÃ©s sur chaque page.
+}  
+
+_textcasefoldprefs_ [l=fr] {Une paire de boutons gÃšre la fonction de prise en compte de majuscules et minuscules lors de la recherche. Par exemple, si "_preferences:textignorecase_" est sÃ©lectionnÃ©, <i>Elevage d'escargots</ i>, seront traitÃ©s de la mÃªme faÃ§on que <i>Elevage d'Escargots</ i> et <i>ELEVAGE D'ESCARGOTS</ i>.}  
+_textstemprefs_ [l=fr] {Une paire de boutons gÃšre si, lors de la recherche, on doit ignorer la terminaison des mots ou non. Par exemple, si "_preferences:textstem_" est sÃ©lectionnÃ©, <i>escargots d'Ã©levage</ i>, sera traitÃ© de la mÃªme faÃ§on que <i>escargots d'Ã©lÃ©vages</ i> et <i>escargot d'Ã©lÃ©vage</ i>. Actuellement, cela ne fonctionne correctement que pour des textes de langue anglaise. _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=fr] {Une paire de boutons gÃšre la fonction de prise en compte des accents lors de la recherche. Par exemple, si  "_preferences:textignoreaccents_" est sÃ©lÃ©ctionnÃ©, 	
+<i>fÃ©dÃ©ration</ i>sera traitÃ© de la mÃªme faÃ§on que <i> fedÃ©ration </ i> et <i> federation</ I>. }  
+ 
+_textstemoptionsprefs_ [l=fr] {Il peut Ãªtre plus pratique et plus prÃ©cis d'utiliser la fonction de recherche par troncature de termes dÃ©crite ci-dessus dans "_texthelpquerytermstitle_".}  
+
+_textsearchtypeprefsplain_ [l=fr] {Il est possible d'accÃ©der Ã  une grande boÃ®te de recherche, pour pouvoir facilement faire une recherche par termes aussi longs qu'un paragraphe. Il est Ã©tonnamment rapide de rechercher de grandes quantitÃ©s de texte.}  
+
+_textsearchtypeprefsform_ [l=fr] {Vous pouvez modifier le nombre de champs indiquÃ©s dans la grille de recherche.}  
+
+_textsearchtypeprefsboth_ [l=fr] {Vous pouvez choisir le type de recherche de la collection, recherche "normale", ou recherche "par champ" .
+ <ul>
+ <li>La recherche normale propose une seule boÃ®te de recherche. _textsearchtypeprefsplain_ </li>
+ <li>La recherche par champ propose un certain nombre de boÃ®tes de recherche, chacune interrogeant un champ diffÃ©rent de l'index. Cela permet la recherche de diffÃ©rents champs Ã  la fois. _textsearchtypeprefsform_ </ li>
+ </ul>}  
+
+
+
+_texttanumbrowseoptions_ [l=fr] {Il y a _numbrowseoptions_ faÃ§ons de
+trouver des informations dans cette collection:}
+
+_textsimplehelpheading_ [l=fr] {Comment trouver les informations qui vous intÃ©ressent dans la collection _collectionname_}  
+
+_texthelpscopetitle_ [l=fr] {Domaine d'application des recherches}
+_texthelpscope_ [l=fr] {<p>
+Dans la plupart des collections, vous pouvez choisir diffÃ©rents index
+pour la recherche. Par exemple, il y aura peut-Ãªtre un index pour les
+auteurs et un autre pour les titres, ou bien mÃªme un index pour les
+chapitres ou paragraphes. GÃ©nÃ©ralement, le document entier est
+prÃ©sentÃ© quel que soit l'index utilisÃ©.
+
+<p>
+Si le document est un livre, il sera ouvert Ã  l'endroit
+appropriÃ©.
+
+}  
Index: /gsdl/stable/macros/french2.dm
===================================================================
--- /gsdl/stable/macros/french2.dm	(revision 20131)
+++ /gsdl/stable/macros/french2.dm	(revision 20131)
@@ -0,0 +1,1181 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# French Language text and icon macros 
+# -- this file contains text that is of less importance
+#
+# Translated by UNESCO for the UNESCO CD-ROMs
+# Contributions made by Georges Braoudakis and John Rose
+#
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=fr] {documents. }
+_lastupdate_ [l=fr] {DerniÃšre mise Ã  jour}
+_ago_ [l=fr] {jours.}
+_colnotbuilt_ [l=fr] {Collection non construite.}
+
+### taken from here
+
+_textpoem_ [l=fr] {<br><h2>Kia papapounamu te moana</h2>
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>puisse la paix et le calme vous entourer,
+<br>puissiez vous Ãªtre dans la chaleur d'une brume d'Ã©tÃ©,
+<br>puisse l'ocÃ©an de vos voyages Ãªtre aussi lisse que la pierre verte polie.
+}
+
+_textgreenstone_ [l=fr] {<p>Greenstone est une pierre semi-prÃ©cieuse qui (tout comme ce logiciel) a
+pris naissance en Nouvelle-ZÃ©lande. Dans la sociÃ©tÃ© traditionnelle
+Maori, c'Ã©tait le matÃ©riau le plus recherchÃ© et celui auquel on attachait le
+plus d'importance. Cette pierre a le pouvoir d'emmagasiner et retenir
+<i>wairua</i>, qui est l'esprit de la force de vie, elle est aussi dotÃ©e
+de vertus traditionnelles qui en font un excellent emblÃšme pour un
+projet de bibliothÃšque numÃ©rique du domaine public. Son Ã©clat symbolise
+la charitÃ©; sa transluciditÃ©, l'honnÃªtetÃ©; sa duretÃ©, le courage; et le
+cÃŽtÃ© tranchant qu'elle peut prendre, la justice. L'objet sculptÃ© et
+utilisÃ© comme logo du logiciel est appelÃ© <i>patu</i>, c'est une sorte
+de matraque utilisÃ©e pour combattre. Un des participants au projet
+Greenstone a hÃ©ritÃ© cet objet de sa famille. Lors des combats main Ã  main, son
+lancer Ã©tait d'une rapiditÃ© et d'une prÃ©cision phÃ©nomÃ©nale ce qui en
+faisait une arme redoutable et complÃšte. Nous souhaiterions que ces
+qualitÃ©s soient aussi celles de ce logiciel, le cÃŽtÃ© du <i>patu</i> tranchant comme un
+rasoir symbolisant la technologie de point. 
+}  
+
+_textaboutgreenstone_ [l=fr] {<p>Greenstone est un ensemble de logiciels dont le but est de construire et de donner accÃšs Ã  des collections d'informations constituant des bibliothÃšques numÃ©riques. Greenstone permet d'organiser les informations d'une faÃ§on innovante et de les publier soit sur Internet soit sur un CD-ROM. Greenstone est produit par le <b>Projet de BibliothÃšque NumÃ©rique de Nouvelle-ZÃ©lande</b> Ã  <b>l'UniversitÃ© de Waikato</b>, et est dÃ©veloppÃ© et distribuÃ© en coopÃ©ration avec <b>l'UNESCO</b> et le Projet de <b>BibliothÃšques Humanitaires et de DÃ©veloppement</b>. C'est un logiciel libre (open source) qui est disponible par tÃ©lÃ©chargement du site web <a href="http://greenstone.org">http://greenstone.org</a>, la licence d'utilisation est la licence publique gÃ©nÃ©rale de GNU (GPL).</p>
+
+<p>Le but de ce progiciel est de permettre aux utilisateurs, appartenant en particulier aux universitÃ©s, bibliothÃšques, et autres institutions du service public, de construire leurs propres bibliothÃšques numÃ©riques. Les bibliothÃšques numÃ©riques sont en train de rÃ©volutionner la mÃ©thode de distribution et d'acquisition des connaissances dans les communautÃ©s et institutions partenaires de l'UNESCO autour du monde dans les domaines de l'Ã©ducation, de la science et de la culture, et en particulier dans celles dans les pays en voie de dÃ©veloppement. Nous espÃ©rons que ce progiciel servira Ã  encourager la construction et la diffusion de bibliothÃšques numÃ©riques afin de partager des connaissances et de les placer dans le domaine public.</p>
+
+<p>Ce progiciel est dÃ©veloppÃ© et distribuÃ© grÃ¢ce Ã  un effort de collaboration internationale de trois acteurs, effort qui prit naissance en aoÃ»t 2000.</p>
+
+<p><a href="http://nzdl.org"><b>Le projet de BibliothÃšque NumÃ©rique de Nouvelle-ZÃ©lande Ã  l'UniversitÃ© de Waikato</b></a><br>Le progiciel Greenstone s'est dÃ©veloppÃ© Ã  partir de ce projet, cette initiative a ensuite Ã©tÃ© soutenue par la Sous-Commision pour la Communication de la Commission Nationale de Nouvelle-ZÃ©lande auprÃšs de l'UNESCO en tant que contribution de la Nouvelle-ZÃ©lande au programme de l'UNESCO.</p>
+
+<p><a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif" class="logo"></a><a href="http://www.unesco.org"><b>Organisation des Nations Unies pour
+l'Ã©ducation, la science et la culture</b></a><br>La diffusion mondiale de l'information dans les domaines de l'Ã©ducation, de la science et de la culture, et en particulier dans les pays en voie de dÃ©veloppement, est une des missions centrales du programme intergouvernemental de l'UNESCO Â«Information pour tousÂ». D'autre part, une technologie de l'information et de la communication accessible est considÃ©rÃ©e comme un outil essentiel dans ce contexte.</p>
+
+<p><a href=""http://humaninfo.org""><img alt=""Human Info logo"" src="_httpimg_/ghproj2.jpg" class="logo"></a><a href="http://humaninfo.org"><b>L'ONG Â«Human InfoÂ» situÃ©e Ã  Anvers, en Belgique</b></a><br>Ce projet travaillant avec des agences des Nations Unies et d'autres ONG s'est forgÃ© une solide rÃ©putation mondiale en ce qui concerne la numÃ©risation de documents relatifs au dÃ©veloppement humanitaire et aussi pour leur large diffusion, gratuite pour les pays en voie de dÃ©veloppement et Ã  prix coÃ»tant pour les autres.</p>
+}  
+
+
+_textdescrselcol_ [l=fr] {sÃ©lectionnez une collection}
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=fr] {Il y a quatre autres boutons sur la page d'accueil}
+
+_textnocollections_ [l=fr] {<p>Aucune collection n'est disponible pour cette installation de
+Greenstone. Pour ajouter des collections, vous pouvez:
+
+<ul>
+<li>soit utiliser <a href="_httppagecollector_">Le Collector</a> pour
+construire de nouvelles collections
+
+<li>soit installer des collections Ã  partir du CD-ROM si vous avez le
+CD-ROM de Greenstone
+
+</ul>
+}
+
+_text1coll_ [l=fr] {Cette installation de Greenstone contient 1 collection}
+
+_textmorecolls_ [l=fr] {Cette installation de Greenstone contient _1_
+collections}
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=fr] {Lien externe}
+_textlinknotfound_ [l=fr] {Lien Interne Introuvable}  
+
+_textextlinkcontent_ [l=fr] {Le lien sÃ©lectionnÃ© est extÃ©rieur Ã  toutes
+vos collections sÃ©lectionnÃ©es actuellement, Si vous souhaitez quand mÃªme
+afficher ce lien et si vous avez accÃšs au web, vous pouvez <a
+href="_nexturl_">vous dÃ©placer</a> sur cette page; dans le cas
+contraire, utilisez le bouton Â«PrÃ©cÃ©dentÂ» du navigateur pour revenir au
+document prÃ©cÃ©dent.
+
+}
+
+_textlinknotfoundcontent_ [l=fr] {Le lien interne sÃ©lectionnÃ©  n'existe
+pas. C'est certainement dÃ» Ã  une erreur dans collection source de base.
+Utilisez le bouton Â«PrÃ©cÃ©dentÂ» du navigateur pour revenir au document
+prÃ©cÃ©dent. 
+
+}
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=fr] {<h3>Lien sur la collection "_2_"</h3>
+ 
+ <p> Le lien sÃ©lectionnÃ© est externe Ã  la collection Â«_collectionname_Â»
+ (il renvoie sur la collection Â«_2_Â»). Si vous souhaitez afficher le
+ contenu de ce lien dans la collection Â«_2_Â», vous pouvez
+ <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">aller</a> Ã  cette
+ page; dans le cas contraire, utilisez le bouton Â«PrÃ©cÃ©dentÂ» du
+ navigateur pour revenir au document prÃ©cÃ©dent. 
+ 
+}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=fr] {BibliothÃšque NumÃ©rique Greenstone}
+
+_textusername_ [l=fr] {nom d'utilisateur}
+_textpassword_ [l=fr] {mot de passe}
+
+_textmustbelongtogroup_ [l=fr] {Remarquez qu'il vous faut appartenir au groupe "_cgiargug_" pour accÃ©der Ã  cette page}
+
+_textmessageinvalid_ [l=fr] {La page que vous avez demandÃ©e nÃ©cessite
+que vous vous enregistriez.<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>) Veuillez saisir
+votre identifiant Greenstone et votre mot de passe.}
+
+_textmessagefailed_ [l=fr] {Votre nom d'utilisateur ou votre mot de passe est incorrect.}
+
+_textmessagedisabled_ [l=fr] {DÃ©solÃ©, votre compte a Ã©tÃ© mis
+hors service. Veuillez contacter l'administrateur de ce site.}
+
+_textmessagepermissiondenied_ [l=fr] {DÃ©solÃ©, vous n'avez pas la
+permission d'accÃ©der Ã  cette page.}  
+
+_textmessagestalekey_ [l=fr] {Le lien que vous avez choisi est
+maintenant pÃ©rimÃ©. Veuillez entrer votre mot de passe pour accÃ©der Ã 
+cette page.
+
+}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=fr] {<p>Cette installation de Greenstone ne contient pas de documentation.
+Ceci est peut-Ãªtre dÃ» au fait que:
+
+<ol>
+
+<li>vous avez installÃ© Greenstone Ã  partir du CD-ROM en utilisant
+une option compacte.
+
+<li>vous avez installÃ© Greenstone Ã  partir d'une distribution
+tÃ©lÃ©chargÃ©e sur un site Internet.
+
+</ol>
+
+Dans les deux cas, vous pouvez obtenir la documentation Ã  partir du
+rÃ©pertoire <i>docs</i> de Greenstone sur le CD-ROM, ou en visitant le
+site web <a href="http://www.greenstone.org">http://www.greenstone.org</a>.
+
+}
+
+_textuserguide_ [l=fr] {Guide de l'utilisateur}
+_textinstallerguide_ [l=fr] {Guide d'installation}
+_textdeveloperguide_ [l=fr] {Guide du dÃ©veloppeur}
+_textpaperguide_ [l=fr] {Du papier Ã  la collection}  
+_textorganizerguide_ [l=fr] {Utilisation de L'organizer}
+
+_textgsdocstitle_ [l=fr] {documentation de greenstone}
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=fr] {Construire la collection}  
+_textbildsuc_ [l=fr] {La collection a Ã©tÃ© construite avec succÃšs.}  
+_textviewbildsummary_ [l=fr] {Vous pouvez <a href="_httppagex_(bsummary)" target=_top> voir le sommaire de la construction</a> de cette collection pour plus de dÃ©tails.}  
+_textview_ [l=fr] {Voir la collection}  
+
+_textbild1_ [l=fr] {La collection est en cours de construction: cela peut prendre quelque temps. La ligne d'Ã©tat de la construction ci-dessous donne des informations sur le dÃ©roulement de l'opÃ©ration.}  
+
+_textbild2_ [l=fr] {Pour arrÃªter le processus de construction, Ã  tout moment, cliquez ici.
+ <Br> La collection sur laquelle vous travaillez restera inchangÃ©e.}  
+
+_textstopbuild_ [l=fr] {arrÃªter la construction}  
+
+_textbild3_ [l=fr] {Si vous quittez cette page (sans annuler le processus de construction avec le bouton
+ "ArrÃªter la construction"), la collection continuera Ã  se construire et sera
+ installÃ©e en cas de rÃ©ussite du processus.}  
+
+_textbuildcancelled_ [l=fr] {Construction annulÃ©e}  
+
+_textbildcancel1_ [l=fr] {Le processus de construction de la collection a Ã©tÃ© annulÃ©. Utilisez le bouton jaune ci-dessous pour apporter des modifications Ã  votre collection ou redÃ©marrer le processus de construction.}  
+
+_textbsupdate1_ [l=fr] {Etat de la construction mise Ã  jour dans 1 seconde}  
+_textbsupdate2_ [l=fr] {Mise Ã  jour de l'Ã©tat de la construction dans}  
+_textseconds_ [l=fr] {secondes}  
+
+_textfailmsg11_ [l=fr] {La collection n'a pas pu Ãªtre construite car elle ne contient pas de donnÃ©es. Assurez-vous que au moins l'un des rÃ©pertoires ou des fichiers que vous avez indiquÃ© sur la page <i> donnÃ©es source</i> existe et est d'un type ou (dans le cas d'un rÃ©pertoire) contient des fichiers d'un type, que Greenstone peut traiter.}  
+
+_textfailmsg21_ [l=fr] {La collection n'a pas pu Ãªtre construite (import.pl a Ã©chouÃ©). }  
+_textfailmsg31_ [l=fr] {La collection n'a pas pu Ãªtre construite (buildcol.pl a Ã©chouÃ©). }  
+_textfailmsg41_ [l=fr] {La collection a Ã©tÃ© construite avec succÃšs, mais n'a pas pu Ãªtre installÃ©e.}  
+_textfailmsg71_ [l=fr] {Une erreur inattendue s'est produite lors de la tentative de construire votre collection}  
+
+
+_textblcont_ [l=fr] {Le journal de la construction contient les informations suivantes:}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=fr] {structure par dÃ©faut}
+_textmore_ [l=fr] {plus}
+_textinfo_ [l=fr] {Informations sur la collection}
+_textsrce_ [l=fr] {DonnÃ©es source}
+_textconf_ [l=fr] {Configuration de la collection}
+_textdel_ [l=fr] {Supprimer la collection}
+_textexpt_ [l=fr] {Exporter la collection}
+
+_textdownloadingfiles_ [l=fr] {TÃ©lÃ©chargement de fichiers âŠ}
+_textimportingcollection_ [l=fr] {Importation de la collection âŠ}
+_textbuildingcollection_ [l=fr] {Construction de la collection âŠ}
+_textcreatingcollection_ [l=fr] {CrÃ©ation de la collection âŠ}
+
+_textcollectorblurb_ [l=fr] {<i>Le crayon et la plume ont plus de pouvoir que l'Ã©pÃ©e!
+
+<br>La construction et la distribution de collections d'information
+comportent certaines responsabilitÃ©s qu'il est prÃ©fÃ©rable d'Ã©tudier
+avant de commencer.
+
+Il y a des aspects juridiques concernant le droit d'auteur: le fait
+que l'on puisse avoir accÃšs librement Ã  certains documents ne signifie
+pas forcÃ©ment que l'on peut les distribuer aux autres. Il y a des
+aspects sociaux: les collections doivent respecter la culture et les
+coutumes de la communautÃ© dont les documents proviennent. Et il y a des
+aspects Ã©thiques: tout simplement, certaines informations ne doivent pas
+Ãªtre divulguÃ©es aux autres.
+
+<br>Soyez sensibilisÃ© au pouvoir de l'information et utilisez-le avec
+prudence.
+
+</i>
+
+}  
+
+_textcb1_ [l=fr] {Le Collector vous aide Ã  crÃ©er de nouvelles collections, Ã  modifier ou
+supprimer des collections, et Ã  ajouter des documents. Pour cela, vous
+serez guidÃ© par une sÃ©quence de pages web qui vous demanderont les
+informations nÃ©cessaires.
+
+}
+
+_textcb2_ [l=fr] {PremiÃšrement, vous devez dÃ©cider si vous voulez}
+_textcnc_ [l=fr] {crÃ©er une nouvelle collection}
+_textwec_ [l=fr] {travailler avec une collection dÃ©jÃ  existante, pour ajouter des donnÃ©es ou la supprimer.}
+
+_textcb3_ [l=fr] {Le systÃšme doit d'abord vÃ©rifier votre signature pour pouvoir construire
+ou modifier des collections de la bibliothÃšque numÃ©rique. Cela permet de
+protÃ©ger les informations contenues dans votre bibliothÃšque numÃ©rique en
+empÃªchant les autres de se connecter sur votre ordinateur et de modifier
+les informations. Note: pour des raisons de sÃ©curitÃ©, vous serez
+automatiquement dÃ©connectÃ© aprÃšs une pÃ©riode d'inactivitÃ© de 30 minutes.
+Si cela vous arrive, ne vous en faites pas ! -- vous pouvez Ã  nouveau
+entrer votre signature et continuer Ã  partir de l'endroit oÃ¹ vous Ã©tiez
+lors de la dÃ©connexion. 
+
+}  
+
+_textcb4_ [l=fr] {Veuillez entrer votre nom d'utilisateur et votre mot de passe, puis
+cliquer sur le bouton pour vÃ©rifier votre signature.
+
+}
+
+_textfsc_ [l=fr] {Tout d'abord, sÃ©lectionnez la collection sur laquelle vous souhaitez
+travailler (les collections protÃ©gÃ©es en Ã©criture n'apparaissent pas
+dans cette liste).
+
+}
+
+_textwtc_ [l=fr] {Avec la collection sÃ©lectionnÃ©e, vous pouvez}
+_textamd_ [l=fr] {Ajouter plus de donnÃ©es et reconstruire la collection}
+_textetc_ [l=fr] {Ãditer le fichier de configuration de la collection et reconstruire la collection}
+_textdtc_ [l=fr] {Supprimer entiÃšrement la collection}
+_textetcfcd_ [l=fr] {Exporter la collection pour l'enregistrer sur un CD-ROM auto-installable sous Windows}
+_textcaec_ [l=fr] {Modifier une collection existante}  
+_textnwec_ [l=fr] {Aucune collection permettant l'Ã©criture n'est disponible pour modification}
+_textcianc_ [l=fr] {CrÃ©ation d'une nouvelle collection}
+_texttsosn_ [l=fr] {La suite logique des Ã©tapes Ã  suivre pour crÃ©er une nouvelle bibliothÃšque numÃ©rique est la suivante:}
+_textsin_ [l=fr] {SpÃ©cifier son nom (et autres informations associÃ©es)}
+_textswts_ [l=fr] {SpÃ©cifier l'origine des donnÃ©es source}
+_textatco_ [l=fr] {Ajuster les options pour la configuration (uniquement pour les utilisateurs avancÃ©s)}
+_textbtc_ [l=fr] {Â«ConstructionÂ» de la collection (voir ci-dessous)}
+_textpvyh_ [l=fr] {Consulter avec fiertÃ© votre Åuvre d'art.}
+
+_texttfsiw_ [l=fr] {C'est dans la quatriÃšme Ã©tape que Greenstone effectue tout le travail.
+Au cours du processus de Â«ConstructionÂ», Greenstone construit tous les
+fichiers d'index et rassemble toutes les informations nÃ©cessaires pour
+que la bibliothÃšque numÃ©rique puisse fonctionner. Mais vous devez en
+premier lieu prÃ©ciser les informations.
+
+}
+
+_textadab_ [l=fr] {Le diagramme ci-dessous vous aidera Ã  vous situer dans la
+sÃ©quence. Le bouton vert est celui sur lequel vous devez cliquer pour
+continuer la sÃ©quence. Lorsque vous allez vous dÃ©placer dans la
+sÃ©quence, la couleur du bouton va changer et devenir jaune. Vous pouvez
+vous dÃ©placer sur une page prÃ©cÃ©dente en cliquant sur le bouton jaune
+correspondant dans le diagramme.
+
+
+}  
+
+_textwyar_ [l=fr] {Lorsque vous Ãªtes prÃªts, cliquez sur le bouton vert Â«informations sur
+la collectionÂ» pour commencer Ã  crÃ©er la nouvelle collection de la
+bibliothÃšque numÃ©rique.
+
+}
+
+_textcnmbs_ [l=fr] {Le nom de la collection est obligatoire}
+_texteambs_ [l=fr] {L'adresse Ã©lectronique est obligatoire}
+_textpsea_ [l=fr] {Veuillez spÃ©cifier l'adresse Ã©lectronique sous la forme : nomutilisateur@domaine}
+_textdocmbs_ [l=fr] {Une description de la collection est obligatoire}
+
+_textwcanc_ [l=fr] {Lorsque vous crÃ©ez une nouvelle collection, il est nÃ©cessaire de saisir
+certaines informations prÃ©liminaires concernant les donnÃ©es sources. Ce
+processus est structurÃ© sous la forme d'une sÃ©rie de pages web,
+contrÃŽlÃ©es par le Collector. La barre en bas de page affiche la sÃ©quence
+des pages qui doivent Ãªtre complÃ©tÃ©es.
+
+}
+
+_texttfc_ [l=fr] {Titre pour la collection:}
+
+_texttctiasp_ [l=fr] {Le titre de la collection est une phrase courte qui est utilisÃ©e dans
+la bibliothÃšque numÃ©rique pour identifier le contenu de la collection.
+Par exemple: Â«Rapports techniques en informatiqueÂ» ou
+Â«BibliothÃšque du DÃ©veloppement HumanitaireÂ».
+
+}  
+
+_textcea_ [l=fr] {Contact, adresse Ã©lectronique:}
+
+_textteas_ [l=fr] {Cette adresse Ã©lectronique donne le point de contact principal pour la
+collection. Si le logiciel Greenstone rencontre un problÃšme, un rapport
+sur le problÃšme est envoyÃ© Ã  cette adresse. Veuillez taper cette adresse
+en entier, au format suivant: <tt>nom@domaine</tt>
+
+}
+
+_textatc_ [l=fr] {Ã propos de cette collection:}
+
+_texttiasd_ [l=fr] {C'est une dÃ©claration dÃ©crivant les principes qui rÃ©gissent les donnÃ©es
+faisant partie de cette collection. Elle sera affichÃ©e sur la premiÃšre
+page lorsque la collection sera prÃ©sentÃ©e.
+
+}
+
+_textypits_ [l=fr] {La position dans la sÃ©quence est indiquÃ©e par une flÃšche en
+dessous--dans ce cas, l'Ã©tape Â«informations de collectionÂ». Pour
+continuer, cliquez sur le bouton Â«donnÃ©es sourceÂ».
+
+}
+
+_srcebadsources_ [l=fr] {<p>Une ou plusieurs donnÃ©es source spÃ©cifiÃ©es en entrÃ©e ne sont pas
+disponibles (marquÃ©e(s) _iconcross_ ci-dessous).
+
+<p>La cause peut Ãªtre:
+<ul>
+<li>le fichier, le site FTP ou bien l'URL n'existe pas.
+<li>vous n'Ãªtes pas connectÃ© Ã  l'Internet (vous devez d'abord vous connecter chez votre fournisseur).
+<li>vous essayez d'accÃ©der Ã  une URL alors que vous Ãªtes derriÃšre un pare-feu 
+(C'est en gÃ©nÃ©ral le cas si vous devez donner un nom d'utilisateur et un
+mot de passe pour accÃ©der Ã  l'Internet).
+</ul>
+
+<p>Si vous pouvez afficher l'URL dans votre navigateur, le problÃšme peut
+venir d'une copie qui se trouve dans la mÃ©moire tampon (cache) locale.
+Malheureusement, de telles copies ne sont pas visibles par le processus
+de miroir de Greenstone. Dans ce cas, il est recommandÃ© de commencer par
+tÃ©lÃ©charger les pages Ã  l'aide du navigateur.
+}  
+
+_textymbyco_ [l=fr] {<p>Vous pouvez dÃ©finir votre collection soit Ã  partir:
+<ul>
+<li>de la structure par dÃ©faut
+<dl><dd>La nouvelle collection peut contenir des documents dans les formats suivants :
+HTML, texte simple, courrier Ã©lectronique "m-box", PDF, RTF, MS WORD, PostScript, PowerPoint, 
+Excel, images, CDS/ISIS.</dd></dl>
+<li>d'une collection dÃ©jÃ  existante
+<dl><dd>Dans ce cas, les fichiers dans la nouvelle collection
+doivent Ãªtre exactement du mÃªme type que ceux qui ont Ã©tÃ© utilisÃ©s pour
+construire la collection existante.</dd></dl>
+</ul>
+}  
+
+_textbtco_ [l=fr] {DÃ©finir la collection Ã  partir de}
+_textand_ [l=fr] {Ãjouter de nouvelles donnÃ©es}
+_textad_ [l=fr] {Ãjout de donnÃ©es:}
+
+_texttftysb_ [l=fr] {Les fichiers que vous allez spÃ©cifier ci-dessous seront ajoutÃ©s Ã  la
+collection. Faites attention Ã  ne pas spÃ©cifier de nouveau des fichiers
+qui se trouvent dÃ©jÃ  dans la collection, sinon la collection comportera
+deux copies de ces fichiers. Les fichiers sont spÃ©cifiÃ©s en indiquant le
+nom du fichier prÃ©cÃ©dÃ© du chemin complet, et les pages web par leur
+adresse web absolue. 
+
+}
+
+_textis_ [l=fr] {DonnÃ©es en entrÃ©e:}
+
+_textddd1_ [l=fr] {<p>Si vous utilisez file:// ou ftp:// pour spÃ©cifier un fichier, ce
+fichier sera tÃ©lÃ©chargÃ©.
+
+<p>Si vous utilisez http:// le rÃ©sultat dÃ©pendra de l'URL et sera
+diffÃ©rent si celle-ci affiche une page web ou bien une liste de
+fichiers dans votre navigateur. Si l'URL affiche une page web, alors
+cette page et toutes les autres pages sur lesquelles elle pointe par
+l'intermÃ©diaire de liens hypertexte seront tÃ©lÃ©chargÃ©es -- il en sera
+de mÃªme pour ces pages et ainsi de suite, etc.. -- tant que ces pages
+rÃ©sident sur le mÃªme site web, sous l'URL initiale.
+
+
+<p>Si vous utilisez file:// ou ftp:// pour spÃ©cifier un dossier ou un
+rÃ©pertoire, ou bien http:// et que cette URL affiche une liste de
+fichiers, tous les fichiers qui se trouvent dans ce dossier et ses
+sous-dossiers seront inclus dans la collection.
+
+<p>Cliquez sur le bouton Â«Plus de donnÃ©esÂ» pour obtenir davantage de
+champs de saisie.
+
+}  
+
+_textddd2_ [l=fr] {<p>Cliquez sur l'un des boutons verts. Si vous Ãªtes un utilisateur
+avancÃ©, vous pouvez affiner la configuration de la collection.
+Autrement, passez directement Ã  l'Ã©tape de construction. N'oubliez pas
+que vous pouvez toujours avoir accÃšs Ã  une Ã©tape prÃ©cÃ©dente en cliquant
+sur le bouton jaune correspondant.
+
+}
+
+_textconf1_ [l=fr] {<p>La construction et la prÃ©sentation d'une collection sont contrÃŽlÃ©es
+par des spÃ©cifications enregistrÃ©es dans un Â«fichier de configurationÂ»
+spÃ©cial. Les utilisateurs avancÃ©s peuvent modifier les paramÃštres de
+configuration contenus dans ce fichier.
+
+<center><p><b>Si vous n'Ãªtes pas un utilisateur avancÃ©, allez
+directement en bas de la page.</b></center> 
+
+<p>Pour modifier les paramÃštres de configuration, Ã©ditez les paramÃštres
+qui apparaissent ci-dessous. Si vous faites une erreur, vous pouvez
+toujours cliquer sur le bouton Â«RÃ©initialiserÂ» pour revenir aux
+paramÃštres de configuration initiaux.
+
+}  
+
+_textreset_ [l=fr] {RÃ©initialiser}
+
+
+_texttryagain_ [l=fr] {Veuillez svp <a href="_httppagecollector_" target=_top>redÃ©marrer le
+Collector</a> et essayer Ã  nouveau.
+
+}
+
+
+_textretcoll_ [l=fr] {Retour au Collector}
+
+_textdelperm_ [l=fr] {Certains Ã©lÃ©ments ou toute la collection _cgiargbc1dirname_ n'ont pu
+Ãªtre supprimÃ©s. Les causes possibles sont:
+
+<ul>
+<li> Greenstone n'a pas la permission de supprimer le rÃ©pertoire _gsdlhome_/collect/_cgiargbc1dirname_
+.<br>
+
+Vous pouvez avoir Ã  supprimer manuellement le rÃ©pertoire pour achever la
+suppression de la collection _cgiargbc1dirname_ de cet ordinateur.
+<li>Greenstone ne peut pas lancer le programme  _gsdlhome_/bin/script/delcol.pl. Assurez vous que ce fichier est lisible et exÃ©cutable.</li>
+
+</ul>
+
+}
+
+_textdelinv_ [l=fr] {La collection _cgiargbc1dirname_ est protÃ©gÃ©e ou invalide. La
+suppression a Ã©tÃ© annulÃ©e.
+
+}
+
+_textdelsuc_ [l=fr] {La collection _cgiargbc1dirname_ a Ã©tÃ© supprimÃ©e.}
+
+_textclonefail_ [l=fr] {La collection _cgiargclonecol_ n'a pu Ãªtre clonÃ©e. Les causes possibles sont:
+
+<ul>
+
+<li> La collection _cgiargclonecol_ n'existe pas
+
+<li> La collection _cgiargclonecol_ ne possÃšde pas de fichier de
+configuration collect.cfg
+
+<li> Greenstone n'a pas la permission de lire le fichier de
+configuration collect.cfg
+
+</ul>
+
+}
+
+_textcolerr_ [l=fr] {Erreur du Collector.}
+
+_texttmpfail_ [l=fr] {Le Collector a Ã©chouÃ© lors de la lecture ou de l'Ã©criture sur un fichier
+temporaire ou dans un rÃ©pertoire temporaire. Les causes possibles sont:
+
+<ul>
+
+<li> Greenstone n'a pas la permission de lire/Ã©crire dans le rÃ©pertoire _gsdlhome_/tmp
+     
+</ul>
+
+}
+
+_textmkcolfail_ [l=fr] {Le Collector a Ã©chouÃ© lors de la crÃ©ation de la structure hiÃ©rarchique
+des rÃ©pertoires qui est nÃ©cessaire Ã  la crÃ©ation d'une nouvelle
+collection (mkcol.pl a Ã©chouÃ©). Les causes possibles sont:
+
+<ul>
+
+<li> Greenstone n'a pas la permission de lire/Ã©crire dans le rÃ©pertoire
+_gsdlhome_/tmp
+
+<li> Erreurs dans le script Perl mkcol.pl
+
+</ul>
+
+}
+
+_textnocontent_ [l=fr] {Erreur Collector: aucune collection n'a Ã©tÃ© saisie pour la nouvelle
+collection. Essayez de redÃ©marrer le Collector Ã  partir du dÃ©but.
+
+}
+
+_textrestart_ [l=fr] {RedÃ©marrer le Collector}
+
+_textreloaderror_ [l=fr] {Une erreur s'est produite lors de la crÃ©ation de la nouvelle collection.
+Il se peut que Greenstone ait Ã©tÃ© perturbÃ© par l'utilisation des boutons
+Â«RechargerÂ» ou Â«PrÃ©cÃ©dentÂ» du navigateur (veuillez essayer d'Ã©viter
+l'utilisation de ces boutons au moment de la crÃ©ation d'une collection
+avec le Collector). Il est recommandÃ© de redÃ©marrer le Collector Ã 
+partir du dÃ©but.
+
+}
+
+_textexptsuc_ [l=fr] {La collection _cgiargbc1dirname_ a Ã©tÃ© exportÃ©e dans le rÃ©pertoire
+_gsdlhome_/tmp/exported\__cgiargbc1dirname_ .
+
+}
+
+_textexptfail_ [l=fr] {<p>L'exportation de la collection _cgiargbc1dirname_ a Ã©chouÃ©.
+
+<p>Il est probable que ce problÃšme provient du fait que Greenstone a Ã©tÃ©
+installÃ© sans les composants qui permettent la fonction Â«Exporter ver CD-RomÂ».
+ <ul>
+
+ <li>
+ Si vous avez installÃ© Ã  partir du CD-Rom une version de Greenstone plus ancienne que 2.70w, ces composants
+ n'ont pas Ã©tÃ© installÃ©s Ã  moins que vous ne les ayez sÃ©lectionnÃ©s dans
+ le cadre d'une installation Â«PersonnalisÃ©eÂ». Vous pouvez les ajouter Ã 
+ votre installation en redÃ©marrant la procÃ©dure d'installation.
+
+ <li>Si vous avez installÃ© Greenstone Ã  partir d'une distribution tÃ©lÃ©chargÃ©e
+ sur le web, il vous faudra alors tÃ©lÃ©charger les composants 
+ dont vous avez besoin pour permettre cette fonctionnalitÃ©. Vous pouvez visiter
+ <a href="http://www.greenstone.org">http://www.greenstone.org</a> ou bien
+ envoyer un courrier Ã©lectronique Ã  
+ <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">la liste de discussion</a> pour plus de dÃ©tails. 
+ </ul> 
+
+}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=fr] {<p>spÃ©cifiez l'information de fichier suivante et cliquez sur _textintro_ ci-dessous.</p>}  
+
+_textcaec_ [l=fr] {Ajout Ã  une collection existante}  
+_textbild_ [l=fr] {Article de dÃ©pÃŽt}  
+_textintro_ [l=fr] {SÃ©lectionner un fichier }  
+_textconfirm_ [l=fr] {Confirmation}  
+_textselect_ [l=fr] {SÃ©lectionnez une collection}  
+_textmeta_ [l=fr] {PrÃ©cisez les mÃ©tadonnÃ©es}  
+_textselectoption_ [l=fr] {sÃ©lectionnez une collection...}  
+
+_texttryagain_ [l=fr] {<a href="_httppagedepositor_" target=_top> RedÃ©marrez le dÃ©posant</a>
+ et rÃ©essayez.}  
+
+_textselectcol_ [l=fr] {SÃ©lectionnez la collection Ã  laquelle vous souhaitez ajouter un nouveau document. }  
+_textfilename_ [l=fr] {Nom de fichier}  
+_textfilesize_ [l=fr] {Taille de fichier}  
+
+_textretcoll_ [l=fr] {Retour au dÃ©posant}  
+
+
+_texttmpfail_ [l=fr] {Le dÃ©posant ne peut pas lire ou Ã©crire sur un fichier temporaire ou un
+ rÃ©pertoire. Les causes possibles sont les suivantes:
+ <ul>
+ <li> Greenstone ne dispose pas d'accÃšs en lecture / Ã©criture au rÃ©pertoire _gsdlhome_ / tmp.     
+ </ ul> }  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=fr] {Greenstone est un ensemble de logiciels dont le but est de fournir un
+accÃšs Ã  des collections d'informations constituant une bibliothÃšque
+numÃ©rique et de construire de nouvelles collections. Greenstone permet
+d'organiser les informations d'une faÃ§on innovante et de les publier
+soit sur l'Internet soit sur un CD-ROM. Greenstone fait partie du Projet
+de BibliothÃšque NumÃ©rique de Nouvelle-ZÃ©lande Ã  l'UniversitÃ© de Waikato,
+il est distribuÃ© en coopÃ©ration avec l'UNESCO et le Projet de
+BibliothÃšques sur le DÃ©veloppement Humanitaire. C'est un logiciel libre
+(Open Source), disponible pour tÃ©lÃ©chargement Ã  d'adresse web suivante:
+<i>http://greenstone.org</i>, sous les termes de la licence publique
+gÃ©nÃ©rale de GNU (GPL). 
+
+}
+
+_textgreenstone2_ [l=fr] {Le site web de la bibliothÃšque numÃ©rique de Nouvelle-ZÃ©lande (<a
+href="http://nzdl.org">http://nzdl.org</a>) contient de nombreux
+exemples de collections, qui ont toutes Ã©tÃ© crÃ©Ã©es avec le logiciel
+Greenstone et que vous pouvez parcourir Ã  votre grÃ© car elles sont dans
+le domaine public. Elles montrent les diffÃ©rentes options de recherche
+et de parcours. Certaines collections sont en arabe, chinois, franÃ§ais,
+maori, espagnol et anglais. Il y a aussi quelques collections de
+morceaux de musique.
+
+}
+
+_textplatformtitle_ [l=fr] {plate-forme}
+_textgreenstone3_ [l=fr] {Greenstone s'exÃ©cute sous Windows, Unix ou Mac OS X. La distribution contient des
+versions exÃ©cutables pour toutes les versions de Windows, ainsi que pour
+Linux. Elle contient aussi l'ensemble du code source pour le systÃšme qui
+peut Ãªtre compilÃ© avec MS VC++ ou Gnu GCC. Greenstone fonctionne avec
+d'autres logiciels qui eux aussi sont des logiciels libres et
+tÃ©lÃ©chargables: le serveur web Apache et PERL. L'interface utilisateur
+utilise un navigateur web: gÃ©nÃ©ralement Netscape Navigator ou Internet
+Explorer.
+
+}
+
+_textgreenstone4_ [l=fr] {Bon nombre de collections sont distribuÃ©es sur CD-ROM avec le logiciel
+Greenstone. Par exemple, la <i>BibliothÃšque du DÃ©velopement Humanitaire</i> contient 1230 publications qui couvrent des
+sujets allant de la comptabilitÃ© jusqu'aux conditions d'hygiÃšne liÃ©es Ã 
+l'eau. L'accÃšs Ã  cette collection peut se faire Ã  partir d'un ordinateur
+aux capacitÃ©s modestes tels que ceux que l'on trouve dans les pays en
+dÃ©veloppement. On peut accÃ©der aux informations en recherchant
+des mots ou une phrase en particulier, en parcourant les publications
+par sujet, en parcourant les publications par titre, en parcourant les
+publications par organisation, en parcourant une liste de Â«Comment
+faireÂ», ou et en affichant au hasard des pages de couverture de
+publications.}  
+
+_textcustomisationtitle_ [l=fr] {Personnalisation}
+_textgreenstone5_ [l=fr] {Greenstone est spÃ©cialement conÃ§u pour Ãªtre Ã©largi et adaptÃ© Ã  des
+besoins particuliers. De nouveaux formats de documents et de
+mÃ©ta-donnÃ©es peuvent Ãªtre facilement traitÃ©s par Greenstone en Ã©crivant
+des Â«plugicielsÂ» (plug-ins), en Perl. De la mÃªme faÃ§on, de nouvelles
+structures de parcours des mÃ©ta-donnÃ©es peuvent Ãªtre mises en Åuvre en Ã©crivant des Â«classificateursÂ». L'interface utilisateur
+et la prÃ©sentation peuvent Ãªtre facilement modifiÃ©es car elles sont
+dÃ©finies par l'intermÃ©diaire d'un langage de macros simple. Le protocole
+CORBA permet aux agents (Ã©crits en Java, par exemple) d'utiliser toutes
+les fonctionnalitÃ©s disponibles dans les collections de documents.
+Finalement, le code source en C++ et Perl, est disponible et accessible
+pour modification.
+}  
+
+_textdocumentationtitle_ [l=fr] {documentation}
+_textdocuments_ [l=fr] {Une large documentation pour le logiciel Greenstone est disponible.}
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=fr] {liste de diffusion}
+_textmailinglist_ [l=fr] {Il existe une liste de diffusion dÃ©diÃ©e au logiciel Greenstone de
+bibliothÃšque numÃ©rique. Il serait bon que les utilisateurs actifs de
+Greenstone se joignent Ã  cette liste et contribuent aux discussions.
+Pour souscrire, cliquez <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+Pour envoyer un message Ã  cette liste, adressez-le Ã  <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz">greenstone-users@list.scms.waikato.ac.nz</a>.
+}
+
+_textbugstitle_ [l=fr] {bugs}
+_textreport_ [l=fr] {Nous voulons nous assurer que ce logiciel fonctionne correctement et qu'il 
+convient Ã  vos besoins. Veuillez nous faire part des bogues Ã  
+<a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">la liste de discussion</a>.
+}  
+
+_textgs3title_ [l=fr] {dans les ouvrages}
+_textgs3_ [l=fr] {Greenstone 3 est une refonte complÃšte et une rÃ©-implÃ©mentation qui conserve les avantages de  
+Greenstone 2 (la version actuelle)--par exemple, il est multilingue, 
+multi-plateforme, et hautement configurable. il incorpore toutes les fonctionalitÃ©s du systÃšme existent et il est compatible avec les versions antÃ©rieures: c'est-Ã -dire qu'il peut construire et lancer des collections existentes sans aucune modification. Ecrit en Java, il est structure en rÃ©seau de modules indÃ©pendants qui communique en utilisant XML : ainsi, il s'exÃ©cute d'une maniÃšre distribuÃ©e et peut Ãªtre rÃ©parti sur diffÃ©rents serveurs si nÃ©cessaire. Cette conception modulaire augmente la flexibilitÃ© et l'extensibilitÃ© de de Greenstone. La nouvelle version devrait Ãªtre disponible d'ici le 23 DÃ©cembre 2003 pour un usage expÃ©rimental. Une conception initiatiale du systÃšme est dÃ©crite dans "The design of Greenstone 3: An agent based 
+dynamic digital library" (tÃ©lÃ©chargement 
+<a href="http://www.greenstone.org/manuals/gs3design.pdf">PDF</a>).
+}
+
+_textcreditstitle_ [l=fr] {crÃ©dits}
+
+_textwhoswho_ [l=fr] {Le logiciel Greenstone a vu le jour grÃ¢ce Ã  un effort de collaboration
+entre de nombreuses personnes. Rodger McNab et Stefan Boddie en sont les
+principaux architectes et dÃ©veloppeurs. Des contributions ont Ã©tÃ© faites
+par David Bainbridge, George Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl
+Gutwin, Geoff Holmes, Dana McKay, John McPherson, Craig Nevill-Manning, Dynal Patel, Gordon
+Paynter, Bernhard Pfahringer, Todd Reed, Bill Rogers, John Thompson, et Stuart Yeates. 
+D'autres membres du Projet de bibliothÃšque numÃ©rique de Nouvelle-ZÃ©lande
+ont Ã©galement donnÃ© des conseils et inspirÃ© les concepteurs du systÃšme:
+Mark Apperley, Sally Jo Cunningham, Steve Jones, Te Taka Keegan, Michel
+Loots, Malika Mahoui, et Lloyd Smith. Nous remercions aussi tous ceux
+qui ont contribuÃ© au dÃ©veloppement des modules sous licence
+GNU GPL qui font partie de cette distribution: MG, GDBM, PDFTOHTML, PERL, WGET,
+WVWARE, XLHTML.
+
+}
+
+_textaboutgslong_ [l=fr] {Ã  propos du logiciel Greenstone}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=fr] {Liste des utilisateurs actifs}
+_textuser_ [l=fr] {Utilisateur}
+_textas_ [l=fr] {Ãtat du compte}
+_textgroups_ [l=fr] {Groupes}
+_textcomment_ [l=fr] {Commentaires}
+_textadduser_ [l=fr] {Ajouter un nouvel utilisateur}
+_textedituser_ [l=fr] {Ãditer}
+_textdeleteuser_ [l=fr] {Supprimer}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=fr] {Ãditer les informations utilisateur}
+_textadduser_ [l=fr] {Ajouter un nouvel utilisateur}
+
+_textaboutusername_ [l=fr] {Les noms d'utilisateur doivent comporter entre 2 et 30 caractÃšres. Ils
+peuvent aussi contenir les caractÃšres alphanumÃ©riques Â«.Â» et Â«_Â».
+
+}
+
+_textaboutpassword_ [l=fr] {Les mots de passe doivent comporter entre 3 et 128 caractÃšres. Ils peuvent
+contenir n'importe quel caractÃšre ASCII imprimable.
+
+}
+
+_textoldpass_ [l=fr] {Si ce champ est blanc, l'ancien mot de place sera
+conservÃ©.}
+_textenabled_ [l=fr] {activÃ©}
+_textdisabled_ [l=fr] {dÃ©sactivÃ©}
+
+_textaboutgroups_ [l=fr] {Les groupes sont des listes dont les Ã©lÃ©ments sont sÃ©parÃ©s par des virgules,
+ne mettez pas de blancs aprÃšs les virgules.
+
+}
+_textavailablegroups_ [l=fr] {Les groupes prÃ©dÃ©finis sont le groupe des administrateurs et d'autres groupes 
+qui autorisent la construction des collections Ã  distance avec l'Interface BibliothÃšcaire ou le DÃ©posant :
+<ul>
+<li><b>administrator</b> : donne l'autorisation d'accÃ©der Ã  la configuration du site et aux comptes 
+d'utilisateurs, ainsi que de modifier ceux-ci.
+<li><b>personal-collections-editor</b> : donne l'autorisation de crÃ©er des nouvelles collections personnelles.
+<li><b>&lt;nom de collection&gt;-collection-editor</b> : donne l'autorisation de crÃ©er et de modifier la collection 
+"nom de collection", par exemple rapports-collection-editor.
+<li><b>all-collections-editor</b> : donne l'autorisation de crÃ©er de nouvelles collections personnelles ou globales 
+et de modifier <b>toutes</b> les collections.
+</ul>
+}  
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=fr] {Supprimer un utilisateur}
+_textremwarn_ [l=fr] {Ãtes vous sÃ»r de vouloir supprimer
+l'utilisateur <b>_cgiargumun_</b>?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=fr] {Modifier le mot de passe}  
+_textoldpw_ [l=fr] {Ancien mot de passe}
+_textnewpw_ [l=fr] {Nouveau mot de passe}
+_textretype_ [l=fr] {Veuillez retaper le nouveau mot de passe}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=fr] {Votre mot de passe a Ã©tÃ© changÃ©.}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=fr] {Le nom d'utilisateur est incorrect.}
+_textinvalidpassword_ [l=fr] {Le mot de passe est incorrect.}
+_textemptypassword_ [l=fr] {Veuillez saisir un mot de passe initial pour cet utilisateur.}
+_textuserexists_ [l=fr] {Cet utilisateur existe dÃ©jÃ , veuillez saisir un autre nom d'utilisateur.}
+
+_textusernameempty_ [l=fr] {Veuillez saisir votre nom d'utilisateur.}
+_textpasswordempty_ [l=fr] {Vous devez saisir votre ancien mot de passe.}
+_textnewpass1empty_ [l=fr] {Entrez votre nouveau mot de passe, puis retapez-le.}
+_textnewpassmismatch_ [l=fr] {Les deux versions de votre nouveau mot de passe ne correspondent pas.}
+_textnewinvalidpassword_ [l=fr] {Vous avez entrÃ© un mot de passe incorrect.}
+_textfailed_ [l=fr] {Le nom d'utilisateur, le mot de passe, ou les deux sont incorrects.}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=fr] {NumÃ©ro de version de Greenstone}
+_textframebrowser_ [l=fr] {Vous devez avoir un navigateur acceptant les cadres (frames) pour l'affichage.}
+_textusermanage_ [l=fr] {Gestion des utilisateurs}
+_textlistusers_ [l=fr] {Liste des utilisateurs}
+_textaddusers_ [l=fr] {Ajouter un nouvel utilisateur}
+_textchangepasswd_ [l=fr] {modifier le mot de passe}  
+_textinfo_ [l=fr] {Informations techniques}
+_textgeneral_ [l=fr] {GÃ©nÃ©ral}
+_textarguments_ [l=fr] {Arguments}
+_textactions_ [l=fr] {Actions}
+_textbrowsers_ [l=fr] {Navigateurs}
+_textprotocols_ [l=fr] {Protocoles}
+_textconfigfiles_ [l=fr] {Fichiers de configuration}
+_textlogs_ [l=fr] {Journaux}
+_textusagelog_ [l=fr] {historique de l'utilisation}  
+_textinitlog_ [l=fr] {Journal d'initialisation}
+_texterrorlog_ [l=fr] {Journal des erreurs}
+_textadminhome_ [l=fr] {Page d'accueil de l'administration}
+_textreturnhome_ [l=fr] {Page d'accueil de Greenstone}
+_titlewelcome_ [l=fr] {Administration }
+_textmaas_ [l=fr] {Les services de maintenance et d'administration sont:}
+_textvol_ [l=fr] {Afficher les journaux en ligne}
+_textcmuc_ [l=fr] {CrÃ©ation, maintenance et mise Ã  jour des collections}
+_textati_ [l=fr] {accÃšs aux informations techniques telles que les arguments CGI}  
+
+_texttsaa_ [l=fr] {L'accÃšs Ã  ces services peut se faire en utilisant la barre de navigation
+sur le cÃŽtÃ© gauche de la page.
+
+}
+
+_textcolstat_ [l=fr] {Situation de la collection}
+
+_textcwoa_ [l=fr] {Les collections ne sont considÃ©rÃ©es comme "actives" que si leurs fichiers build.cfg
+existent, s'ils sont lisibles, et s'ils contiennent une date de construction valide
+(c-Ã -d >  0), et s'ils se trouvent dans le rÃ©pertoire index de
+la collection (c-Ã -d PAS dans le rÃ©pertoire
+build).
+
+}
+
+_textcafi_ [l=fr] {Cliquez sur <i>abrÃ©gÃ©</i> pour obtenir des informations sur la collection}
+_textcctv_ [l=fr] {Cliquez sur <i>collection</i> pour afficher une collection}
+_textsubc_ [l=fr] {Soumettre les changements}
+_texteom_ [l=fr] {Erreur lors de l'ouverture du fichier main.cfg}
+_textftum_ [l=fr] {La mise Ã  jour du fichier main.cfg a Ã©chouÃ©}
+_textmus_ [l=fr] {La mise Ã  jour du fichier main.cfg est faite}
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=fr] {RÃ©sumÃ© de la construction pour la collection Â«_collectionname_Â»}  
+_textflog_ [l=fr] {Journal des opÃ©rations qui ont Ã©chouÃ© pour la collection _collectionname_}  
+_textilog_ [l=fr] {Journal d'importation pour la collection "_collectionname_" }  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=fr] {ENVOYER DES REMARQUES}  
+
+_greenstoneusabilitytext_ [l=fr] {EfficacitÃ© de Greenstone}
+
+_textwhy_ [l=fr] {<p>L'envoi de ce rapport est une maniÃšre d'indiquer que vous avez trouvÃ© la page web que vous Ã©tiez en train de visionner difficile ou frustrante.}  
+_textextraforform_ [l=fr] {Vous n'avez pas Ã  remplir le formulaire -- toute information sera utile}
+_textprivacybasic_ [l=fr] {<p> Le rapport contiendra uniquement des informations concernant la page web Greenstone que vous Ãªtes en train de consulter, ainsi que la technologie que vous aviez utilisÃ©e pour la visionner (plus toute autre information facultative que vous donniez)}  
+_textstillsend_ [l=fr] {Voulez vous toujours envoyer ce rapport?}  
+
+_texterror_ [l=fr] {erreur}
+_textyes_ [l=fr] {Oui}  
+_textno_ [l=fr] {Non}  
+_textclosewindow_ [l=fr] {Fermer la fenÃªtre}  
+_textabout_ [l=fr] {A propos}
+_textprivacy_ [l=fr] {IntimitÃ©}
+_textsend_ [l=fr] {Envoyer}
+_textdontsend_ [l=fr] {Ne pas envoyer}  
+_textoptionally_ [l=fr] {Optionnellement}  
+
+_textunderdev_ [l=fr] {Un aperÃ§u des dÃ©tails sera disponible dans la version finale.}  
+
+_textviewdetails_ [l=fr] {Consulter les dÃ©tails du rapport}  
+_textmoredetails_ [l=fr] {Plus de dÃ©tails}  
+_texttrackreport_ [l=fr] {Suivre ce rapport}  
+_textcharacterise_ [l=fr] {Quel genre de problÃšme est-ce}  
+_textseverity_ [l=fr] {Quelle est la gravitÃ© du problÃšme}  
+ 
+_textbadrender_ [l=fr] {La page semble Ã©trange}  
+_textcontenterror_ [l=fr] {Erreur de contenu}  
+_textstrangebehaviour_ [l=fr] {Comportement Ã©trange}  
+_textunexpected_ [l=fr] {Quelque chose d'inattendu est arrivÃ©e}  
+_textfunctionality_ [l=fr] {Difficile Ã  utiliser}  
+_textother_ [l=fr] {Autre}  
+
+_textcritical_ [l=fr] {Critique}  
+_textmajor_ [l=fr] {SÃ©rieux}  
+_textmedium_ [l=fr] {Moyen}  
+_textminor_ [l=fr] {Secondaire}  
+_texttrivial_ [l=fr] {Trivial}  
+
+_textwhatdoing_ [l=fr] {Qu'essayiez-vous de faire?}  
+_textwhatexpected_ [l=fr] {A quoi vous attendiez vous?}  
+_textwhathappened_ [l=fr] {Que s'est-il rÃ©ellement passÃ©?}  
+
+_cannotfindcgierror_ [l=fr] {<h2>DÃ©solÃ©!</h2>Impossible de trouver les programmes du serveur pour le bouton "_linktextusab_".}  
+
+_textusabbanner_ [l=fr] {la banniÃšre koru-style de Greenstone}
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=fr] {Une erreur c'est produite}  
+
+_textgtihome_ [l=fr] {Ces pages vous aident Ã  amÃ©liorer l'interface multilingue de Greenstone. En les utilisant, vous pouvez,
+<ul>
+   <li>traduire des parties de Greenstone en une nouvelle langue
+   <li>mettre Ã  jour une interface existante d'une langue pour y intÃ©grer de nouvelles fonctionnalitÃ©s de Greenstone
+   <li>corriger les erreurs dans les traductions existantes
+</ul>
+
+On vous prÃ©sentera une sÃ©rie de pages web, chacune contenant plusieurs phrases Ã  traduire.
+Vous vous mettez Ã  traduire l'interface dans la langue choisie phrase par phrase.
+Plusieurs phrases contiennent des commandes de formatage HTML: vous ne devrez pas traduire celles-ci, prÃ©servez les intactes dans la version traduite. Les mots encadrÃ©s par des tirets bas (comme _ceci_) ne devraient pas non plus Ãªtre traduits (ce sont les noms de "macro" de Greenstone).
+<p>
+Si vous Ãªtes en train de mettre Ã  jour une traduction existante, on ne vous prÃ©sentera pas les phrases dÃ©jÃ  traduites. Quelques fois une traduction existe dÃ©jÃ  mais le texte en anglais a changÃ© entre-temps. Dans ce cas, la traduction actuelle vous sera prÃ©sentÃ©e et vous devrez la contrÃŽler et la corriger si nÃ©cessaire.
+<p>
+Chaque page termine avec un bouton "_textgtsubmit_". Quand vous cliquez dessus, les modifications sont enregistrÃ©es immÃ©diatement dans l'implantation spÃ©cifique de Greenstone Ã  nzdl.org. Un bouton est prÃ©sentÃ© sur chaque page pour accÃ©der Ã  ce site.}  
+
+_textgtiselecttlc_ [l=fr] {Selectionner votre langue}  
+
+#for status page
+_textgtiviewstatus_ [l=fr] {Cliquez pour voir l'Ã©tat actuel de traduction pour toutes les langues}  
+_textgtiviewstatusbutton_ [l=fr] {TABLEAU DE BORD}  
+_textgtistatustable_ [l=fr] {Liste de l'Ã©tat actuel de traduction pour toutes les langues}  
+_textgtilanguage_ [l=fr] {Langue}  
+_textgtitotalnumberoftranslations_ [l=fr] {Le nombre total de traductions}  
+
+_textgtiselecttfk_ [l=fr] {Selectionner un fichier pour travailler}  
+
+_textgticoredm_ [l=fr] {Interface Greenstone (NuclÃ©ique)}  
+_textgtiauxdm_ [l=fr] {Interface Greenstone (Auxiliaire)}  
+_textgtiglidict_ [l=fr] {Dictionnaire GLI}  
+_textgtiglihelp_ [l=fr] {GLI Aide}  
+_textgtiperlmodules_ [l=fr] {Modules Perl}  
+_textgtitutorials_ [l=fr] {Exercices de travaux pratiques}  
+_textgtigreenorg_ [l=fr] {Greenstone.org}  
+_textgtigs3interface_ [l=fr] {L'interface pour Greenstone 3}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=fr] {Guide du dÃ©veloppeur de Greenstone}  
+_textgtiinstallmanual_ [l=fr] {Guide dâinstallation de Greenstone}  
+_textgtipapermanual_ [l=fr] {Guide Greenstone : du Papier Ã  la Collection}  
+_textgtiusermanual_ [l=fr] {Guide de lâutilisateur de Greenstone }  
+
+_textgtienter_ [l=fr] {INSERER}  
+
+_textgticorrectexistingtranslations_ [l=fr] {Correction de traductions existantes}  
+_textgtidownloadtargetfile_ [l=fr] {Telecharger le fichier}  
+_textgtiviewtargetfileinaction_ [l=fr] {Voir ce fichier en action}  
+_textgtitranslatefileoffline_ [l=fr] {Traduire ce fichier hors connexion}  
+
+_textgtinumchunksmatchingquery_ [l=fr] {Nombre de fragments de textes qui correspondont Ã  la recherche}  
+
+_textgtinumchunkstranslated_ [l=fr] {traducitions achevees}  
+_textgtinumchunksrequiringupdating_ [l=fr] {De celle-ci, _1_ doi(ven)t etre actualisee(s)}  
+_textgtinumchunksrequiringtranslation_ [l=fr] {traductions demeurantes}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=fr] {nombre de traductions achevÃ©es}  
+_textgtinumchunksrequiringupdating2_ [l=fr] {nombre de traductions nÃ©cessitant une mise Ã  jour}  
+_textgtinumchunksrequiringtranslation2_ [l=fr] {nombre de traductions Ã  faire}  
+
+_textgtienterquery_ [l=fr] {Entrez le mot ou la phrase du texte que vous desirer traduire}  
+_textgtifind_ [l=fr] {RECHERCHE}  
+
+_textgtitranslatingchunk_ [l=fr] {Partie du texte en traduction <i>_1_</i>
+}  
+_textgtiupdatingchunk_ [l=fr] {Actualisant la partie du texte <i>_1_</i>}  
+_textgtisubmit_ [l=fr] {SOUMETTRE}  
+
+_textgtilastupdated_ [l=fr] {DerniÃšre actualisation}  
+
+_textgtitranslationfilecomplete_ [l=fr] {Merci d'actualiser ce fichier--il est maintenant complet!<p>Vouz pouvez telecharger ce fichier en utilisant le lien ci-dessus, et celui-ci sera aussi inclu dans des versions futures de Greenstone.}  
+
+_textgtiofflinetranslation_ [l=fr] {Vous pouvez traduire cette partie de Greenstone hors connexion Ã  l'aide d'un fichier du tableur Microsoft Excel :
+
+ <ol>
+ <li> TÃ©lÃ©charger <a href="_gwcgi_?a=gti&p=&tct=work&e=_compressedoptions_">ce fichier </a>pour tout le travail qui rest Ã  faire, ou <a href="_gwcgi_?a=gti&p=excel&tct=all&e=_compressedoptions_">ce fichier</a> pour tous les textes faisant partie de ce module.
+ <li> Ouvrez le fichier tÃ©lÃ©chargÃ© dans Microsoft Excel (la version Office 2003/XP ou une version plus rÃ©cente est requise) et enregistrez en format Microsoft Excel (.xls).
+ <li> Entrez les traductions dans les cadres prÃ©vus.
+ <li> Lorsque vous avez fini de traduire toutes les chaÃ®nes de caractÃšres, envoyez ce fichier .xls par courrier Ã©lectronique Ã  <a href="mailto:_gtiadministratoremail_"> _gtiadministratoremail_</a>.
+ </ol>
+}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=fr] {l'Interface BibliothÃ©caire de Greenstone}
+_textglihelp_ [l=fr] {L'Interface du BibliothÃ©caire de Greenstone (GLI) vous donne accÃšs aux fonctions de Greenstone Ã  
+ partir d'une interface 'pointer et cliquer' facile Ã  utiliser.
+ Cela vous permet de rassembler une sÃ©rie de documents, d'importer ou 
+ assigner des mÃ©ta-donnÃ©es, et d'intÃ©grer les deux dans une 
+ collection Greenstone.
+ <p>
+ Remarquez que GLI tourne conjointement avec Greenstone et normalement est 
+ installÃ© dans un sous-rÃ©pertoire de votre installation 
+ Greenstone. Si vous avez tÃ©lÃ©chargÃ© une des 
+ distributions de Greenstone ou si vous l'avez installÃ© Ã  
+ partir d'un CD-ROM, ceci sera le cas.
+ 
+ <h4>ExÃ©cuter GLI sous Windows</h4>
+ 
+ Lancer l'Interface BibliothÃ©caire sous 
+ Windows en sÃ©lectionnant <i>Greenstone Digital Library</i>
+ (BibliothÃšque numÃ©rique de Greenstone) dans la section 
+ Programmes du menu <i>DÃ©marrer</i> et en choisissant <i>Librarian 
+ Interface</i>.
+ 
+ <h4>ExÃ©cuter GLI sous Unix</h4>
+ 
+ Pour exÃ©cuter GLI sous Unix, aller au rÃ©pertoire <i>gli</i> de votre installation Greenstone et lancer le script <i>gli.sh</i>.
+}  
Index: /gsdl/stable/macros/gaelic.dm
===================================================================
--- /gsdl/stable/macros/gaelic.dm	(revision 20131)
+++ /gsdl/stable/macros/gaelic.dm	(revision 20131)
@@ -0,0 +1,705 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Gaelic (Scottish) Language text and icon macros 
+# Many thanks to Rita Campbell and Laurinda Matheson
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=gd] {RÃ itheachanan}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=gd] {PrÃ¬omhachd:}  
+_textdate_ [l=gd] {ceann-latha foillseachaidh}  
+_textnumpages_ [l=gd] {Ã ir. dhuilleagan}  
+
+_textsignin_ [l=gd] {SgrÃ¬obh d' ainm}  
+
+_textdefaultcontent_ [l=gd] {Cha rachadh an duileag thaghte lorg. Cleachd putan "Back" air do shealladar no am putan dachaigh gu h-Ã rd a thilleadh do 'n Leabharlann Digiteach Greenstone.}  
+
+_textdefaulttitle_ [l=gd] {Mearachd GSDL }  
+
+_textbadcollection_ [l=gd] {Chan eil an co-chruinneachadh seo (ris an cante "_cvariable_") air a chur air an t-siostam digiteach leabharlann Greenstone seo.}  
+
+_textselectpage_ [l=gd] {-- Tagh Duilleag --}  
+
+_collectionextra_ [l=gd] {Tha _about:numdocs_ sgrÃ¬obhainnean anns a' cho-chruinneachadh seo. Chaidh a thogail mu dheireadh  _about:builddate_ laithean seo chaidh.}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=gd] {<p>Tha an co-chruinneachadh seo aâ toirt a-steach _numdocs_ _If_("_numdocs_" eq "1",sgrÃ¬obhainn,sgrÃ¬obhainnean),  _numbytes_gu lÃšir.
+<p><a href="_httppagex_(bsummary)">Put an seo</a>airson cunntas den
+cho-chruinneachadh seo fhaicinn.
+}  
+
+_textdescrcollection_ [l=gd] {}
+_textdescrabout_ [l=gd] {Mu dhÃšidhinn duilleig }  
+_textdescrhome_ [l=gd] {Duilleag dhachaidh}  
+_textdescrhelp_ [l=gd] {Duilleag chobhrach}  
+_textdescrpref_ [l=gd] {Duilleag roghainnean}  
+_textdescrgreenstone_ [l=gd] {Bathar-bog Digiteach Leabharlann Greenstone}  
+_textdescrusab_ [l=gd] {DÃ© bha doirbh dhut a chleachdadh?}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=gd] {Lorg}  
+_labelSearch_ [l=gd] {Lorg}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=gd] {Tiotal }  
+_labelTitle_ [l=gd] {Tiotalan}  
+_textCreator_ [l=gd] {Ughdaran }  
+_labelCreator_ [l=gd] {Ughdaran}  
+_textSubject_ [l=gd] {Cuspair}  
+_labelSubject_ [l=gd] {Cuspairean}  
+_textDescription_ [l=gd] {Tuairisgeul}  
+_labelDescription_ [l=gd] {Tuairisgeulan}  
+_textPublisher_ [l=gd] {Foillsichear }  
+_labelPublisher_ [l=gd] {Foillsichearan}  
+_textContributor_ [l=gd] {Neachd-cuideachaidh }  
+_labelContributor_ [l=gd] {Luchd-chuideachaidh}  
+_textDate_ [l=gd] {Ceann-latha }  
+_labelDate_ [l=gd] {Cinn-latha}  
+_textType_ [l=gd] {SeÃ²rsa}  
+_labelType_ [l=gd] {SeÃ²rsachan}  
+_textFormat_ [l=gd] {Cruth}  
+_labelFormat_ [l=gd] {Cruthan}  
+_textIdentifier_ [l=gd] {Aithnichear }  
+_labelIdentifier_ [l=gd] {Aithnichearan}  
+_textSource_ [l=gd] {Ainm-faidhle }  
+_labelSource_ [l=gd] {Ainmean-faidhle}  
+_textLanguage_ [l=gd] {CÃ nain }  
+_labelLanguage_ [l=gd] {CÃ nainean}  
+_textRelation_ [l=gd] {Co-cheangal }  
+_labelRelation_ [l=gd] {Co-cheangail}  
+_textCoverage_ [l=gd] {Farsaigneachd }  
+_labelCoverage_ [l=gd] {Farsaigneachd}  
+_textRights_ [l=gd] {CÃ²irichean}  
+_labelRights_ [l=gd] {CÃ²irichean}  
+
+# DLS metadata set
+_textOrganization_ [l=gd] {Buidheann}  
+_labelOrganization_ [l=gd] {Buidhnean}  
+_textKeyword_ [l=gd] {Facal-luirg }  
+_labelKeyword_ [l=gd] {Faclan-luirg}  
+_textHowto_ [l=gd] {Ciamar a dheanamh}  
+_labelHowto_ [l=gd] {Ciamar a dhÃšanamh }  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=gd] {Abairt}  
+_labelPhrase_ [l=gd] {Abairtean}  
+_textCollage_ [l=gd] {Co-chruinneachadh dhealbhan }  
+_labelCollage_ [l=gd] {Co-chruinneachadh dhealbhan}  
+_textBrowse_ [l=gd] {SgrÃ¹daich}  
+_labelBrowse_ [l=gd] {SgrÃ¹daich}  
+_textTo_ [l=gd] {Gu}  
+_labelTo_ [l=gd] {Gu}  
+_textFrom_ [l=gd] {Bho}  
+_labelFrom_ [l=gd] {Bho}  
+_textAcronym_ [l=gd] {GeÃ rr-ainm }  
+_labelAcronym_ [l=gd] {GeÃ rr-ainmean}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=gd] {SgrÃ¹daich le _1_}  
+
+_textdescrSearch_ [l=gd] {Lorg teirmean Ã raid}  
+_textdescrType_ [l=gd] {Thoir ruith le seÃ²rsa ghoireis}  
+_textdescrIdentifier_ [l=gd] {Thoir ruith le aithnichear ghoireis}  
+_textdescrSource_ [l=gd] {Thoir ruith le ainm-faidhle tÃ¹sail}  
+_textdescrTo_ [l=gd] {Thoir ruith le raon Gu}  
+_textdescrFrom_ [l=gd] {Thoir ruith le raon Bho}  
+_textdescrCollage_ [l=gd] {Thoir ruith le co-chruinneachadh dhealbhan}  
+_textdescrAcronym_ [l=gd] {Thoir ruith air geÃ rr-ainmean}  
+_textdescrPhrase_ [l=gd] {Thoir ruith air abairtean}  
+_textdescrHowto_ [l=gd] {Thoir ruith air gnÃ© Ciamar a nÃ¬ thu . . . }  
+_textdescrBrowse_ [l=gd] {Thoir ruith air}  
+_texticontext_ [l=gd] {Faic an sgrÃ¬obhainn}  
+_texticonclosedbook_ [l=gd] {Fosgail an sgrÃ¬obhainn seo agus faic na th' ann}  
+_texticonnext_ [l=gd] {gus an ath roinn}  
+_texticonprev_ [l=gd] {gus an roinn seo chaidh}  
+
+_texticonworld_ [l=gd] {Faic sgrÃ¬obhainn an eadar-lÃ¬n}  
+
+_texticonmidi_ [l=gd] {Faic an sgrÃ¬obhainn MIDI }  
+_texticonmsword_ [l=gd] {Faic an sgrÃ¬obhainn Microsoft Word }  
+_texticonmp3_ [l=gd] {Faic an sgrÃ¬obhainn MP3 }  
+_texticonpdf_ [l=gd] {Faic an sgrÃ¬obhainn PDF }  
+_texticonps_ [l=gd] {Faic an sgrÃ¬obhainn PostScript }  
+_texticonppt_ [l=gd] {Faic an sgrÃ¬obhainn PowerPoint }  
+_texticonrtf_ [l=gd] {Faic an sgrÃ¬obhainn RTF }  
+_texticonxls_ [l=gd] {Faic an sgrÃ¬obhainn Microsoft Excel}  
+
+_page_ [l=gd] {duilleag}  
+_pages_ [l=gd] {duilleagan}  
+_of_ [l=gd] {de}  
+_vol_ [l=gd] {Lom-leabh.}  
+_num_ [l=gd] {Air.}  
+
+_textmonth00_ [l=gd] {}
+_textmonth01_ [l=gd] {Am Faoilteach}  
+_textmonth02_ [l=gd] {An Gearran}  
+_textmonth03_ [l=gd] {Am MÃ rt}  
+_textmonth04_ [l=gd] {An Giblean}  
+_textmonth05_ [l=gd] {An CÃšitean}  
+_textmonth06_ [l=gd] {An t-Og MhÃ¬os}  
+_textmonth07_ [l=gd] {An t-Iuchar}  
+_textmonth08_ [l=gd] {LÃ¹nasdal}  
+_textmonth09_ [l=gd] {An t-Sultain}  
+_textmonth10_ [l=gd] {An DÃ mhair}  
+_textmonth11_ [l=gd] {An t-Samhainn}  
+_textmonth12_ [l=gd] {An DÃ¹bhlachd}  
+
+_textdocument_ [l=gd] {SgrÃ¬obhainn}  
+_textsection_ [l=gd] {Roinn}  
+_textparagraph_ [l=gd] {Earrann}  
+
+_magazines_ [l=gd] {Irisean}  
+
+_nzdlpagefooter_ [l=gd] {<div class="divbar">Â </div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}  
+
+_linktextHOME_ [l=gd] {DACHAIGH}  
+_linktextHELP_ [l=gd] {COBHAIR}  
+_linktextPREFERENCES_ [l=gd] {ROGHAINNEAN}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=gd] {Bathar-bog Digiteach Leabharlainn Greenstone}  
+
+
+
+
+_textabgs_ [l=gd] {Mu Greenstone }  
+
+
+
+
+
+
+
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+
+
+
+package collector
+
+
+_textdescrcollector_ [l=gd] {Bha seo ann ro eadar-aghaidh an leabharlannaiche, agus sa mhÃ²r-chuid de shuidheachaidhean  âs e eadar-aghaidh an leabharlannaiche bu chÃ²ir a chleachdadh}  
+
+package depositor
+
+
+
+
+package gti
+
+
+_textdescrtranslator_ [l=gd] {Gad chuideachadh aâ cumail dreachan iom-chÃ nanach eadar-aghaidh Greenstone Ã¹raichte}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=gd] {Mu dhÃšidhinn a'cho-chruinneachaidh seo}  
+
+_textsubcols1_ [l=gd] {<p>Tha an cho-chruinneachadh gu lÃšir a' toirt a-steach  _1_ fo-chruinneachaidhean. Tha na feadhainn ri fhaotainn a nis mar a leanas:
+<blockquote>}  
+
+_textsubcols2_ [l=gd] {</blockquote>
+'S urrainn dhut na fo-chruinneachaidhean a tha thu a' cleachdadh  
+ gu gnÃ thach air an Duilleag Roghainnean fhaicinn (agus atharrachadh).}  
+
+_titleabout_ [l=gd] {mu dhÃšidhinn}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=gd] {dÃ¹in earrann seo an leabharlainn}  
+_texticonclosedbookshelf_ [l=gd] {fosgail an roinn seo den leabharlann agus faic na th' innte}  
+_texticonopenbook_ [l=gd] {dÃ¹in an leabhar seo}  
+_texticonclosedfolder_ [l=gd] {Fosgail am pasgan seo agus faic na th' ann}  
+_texticonclosedfolder2_ [l=gd] {fosgail fo-roinn:}  
+_texticonopenfolder_ [l=gd] {dÃ¹in am pasgan seo}  
+_texticonopenfolder2_ [l=gd] {dÃ¹in fo-earrann:}  
+_texticonsmalltext_ [l=gd] {Faic an roinn seo de 'n teacs}  
+_texticonsmalltext2_ [l=gd] {faic teacs:}  
+_texticonpointer_ [l=gd] {fo-earrann gnÃ thach}  
+_texticondetach_ [l=gd] {Fosgail an duilleag seo ann an uinneag Ã¹r}  
+_texticonhighlight_ [l=gd] {Comharraich teirmean-luirg}  
+_texticonnohighlight_ [l=gd] {Na comharraich facail-luirg}  
+_texticoncontracttoc_ [l=gd] {Leag clÃ r-Ã¬nnsidh}  
+_texticonexpandtoc_ [l=gd] {Leudaich clÃ r-Ã¬nnsidh}  
+_texticonexpandtext_ [l=gd] {taisbein an teacs gu lÃšir}  
+_texticoncontracttext_ [l=gd] {taisbein teacs a-mhain airson fo-earrann taghte}  
+_texticonwarning_ [l=gd] {<b>Rabhadh: </b>}  
+_texticoncont_ [l=gd] {lean ort?}  
+
+_textltwarning_ [l=gd] {<div class="buttons">_imagecont_</div>
+_iconwarning_Ma leudachas tu an teacs a seo bidh mÃ³ran data ann do 'n shealladair agad a shealltainn}  
+
+_textgoto_ [l=gd] {rach gu duilleig}  
+_textintro_ [l=gd] {<i>(teacs toisich)</i>}  
+
+_textCONTINUE_ [l=gd] {LEAN ORT?}  
+
+_textEXPANDTEXT_ [l=gd] {LEUDAICH TEACS}  
+
+_textCONTRACTCONTENTS_ [l=gd] {TEANNAICH CLAR-INNSIDH}  
+
+_textDETACH_ [l=gd] {SGAR}  
+
+_textEXPANDCONTENTS_ [l=gd] {LEUDAICH CLAR-INNSIDH}  
+
+_textCONTRACT_ [l=gd] {TEANNAICH TEACS}  
+
+_textHIGHLIGHT_ [l=gd] {COMHARRACHADH}  
+
+_textNOHIGHLIGHT_ [l=gd] {GUN CHOMHARRACHADH}  
+
+
+
+
+
+
+# macros for printing page
+
+
+
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=gd] {_If_(_thislast_,builean _thisfirst_ - _thislast_ do cheist: _cgiargq_,Chan eil seisean ann do cheist: _cgiargq_)}  
+_textnoquerytitle_ [l=gd] {Duillleag luirg}  
+
+_textsome_ [l=gd] {cuid}  
+_textall_ [l=gd] {uile}  
+_textboolean_ [l=gd] {boolean}  
+_textranked_ [l=gd] {Ã²rdaichte}  
+_textnatural_ [l=gd] {nÃ durra}  
+
+_texticonsearchhistorybar_ [l=gd] {eachdraidh luirg}  
+
+_textifeellucky_ [l=gd] {Tha mi a' faireachdain fortanach}  
+
+#alt text for query buttons
+_textusequery_ [l=gd] {cleachd a' cheist seo}  
+_textfreqmsg1_ [l=gd] {Cunntas fhaclan:}  
+_textpostprocess_ [l=gd] {_If_(_quotedquery_,<br><i>air a dhÃšanamh mu dheireadh a lorg _quotedquery_</i>
+)}  
+_textinvalidquery_ [l=gd] {CÃ²-rÃšir ceist chÃšarr}  
+
+
+
+_textmorethan_ [l=gd] {Barrachd air}  
+_textapprox_ [l=gd] {Mu dhÃšidhinn}  
+_textnodocs_ [l=gd] {Cha do sheisich sgrÃ¬obhainn na ceiste}  
+_text1doc_ [l=gd] {Sheisich 1 sgrÃ¬obhainn a' cheist}  
+_textlotsdocs_ [l=gd] {sheisich sgrÃ¬obhainnean a' cheist}  
+_textmatches_ [l=gd] {Samhailean}  
+_textbeginsearch_ [l=gd] {TÃ²isich Lorg}  
+_textrunquery_ [l=gd] {Ruith ceist}  
+_textclearform_ [l=gd] {Reitich Foirm}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=gd] {Faclan}  
+_textinfield_ [l=gd] {... Ann an raon}  
+_textfoldstem_ [l=gd] {(dÃšan co-ionnan, geÃ rr)}  
+
+_textadvquery_ [l=gd] {No cuir ceist gu dÃ¬reach:}  
+_textallfields_ [l=gd] {a h-uile raon}  
+_texttextonly_ [l=gd] {teacs a-mhÃ in}  
+_textand_ [l=gd] {agus}  
+_textor_ [l=gd] {no}  
+_textandnot_ [l=gd] {agus leig a-mach}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=gd] {Lorg  _indexselection_ _If_(_jselection_,de _jselection_ )_If_(_gselection_, aig _gselection_ Ã¬re )_If_(_nselection_,ann _nselection_ cÃ nain )anns a bheil _querytypeselection_ de na faclan}  
+
+_textadvancedsearch_ [l=gd] {Lorg _indexselection_ _If_(_jselection_,de _jselection_ )_If_(_gselection_,aig_gselection_ Ã¬re )_If_(_nselection_,ann _nselection_ cÃ nain )a' cleachdadh _querytypeselection_ ceist}  
+
+_textadvancedmgppsearch_ [l=gd] {Lorg _indexselection_ _If_(_jselection_,de _jselection_ )_If_(_gselection_,aig _gselection_ Ã¬re )_If_(_nselection_, ann _nselection_ cÃ nain ) agus seall builean ann _formquerytypeadvancedselection_ ordugh }  
+
+_textadvancedlucenesearch_ [l=gd] {Lorg _indexselection__If_(_jselection_, de _jselection_)_If_(_gselection_, aig _gselection_ Ã¬re)_If_(_nselection_, ann _nselection_ cÃ nain)_If_(_sfselection_,\,_allowformbreak_ sorting results by _sfselection_\,) air  }  
+
+_textformsimplesearch_ [l=gd] {Lorg _If_(_jselection_,_jselection_ )_If_(_gformselection_,aig _gformselection_ Ã¬re )_If_(_nselection_,ann _nselection_ cÃ nain )airson _formquerytypesimpleselection_ de}  
+
+_textformadvancedsearchmgpp_ [l=gd] {Lorg _If_(_jselection_,_jselection_ )_If_(_gformselection_,aig _gformselection_ Ã¬re )_If_(_nselection_,ann _nselection_ cÃ nain )agus seall builean ann _formquerytypeadvancedselection_ ordugh }  
+
+_textformadvancedsearchlucene_ [l=gd] {Lorg _If_(_jselection_, _jselection_)_If_(_gformselection_,  aig _gformselection_ Ã¬re)_If_(_nselection_, ann _nselection_ cÃ nain)_If_(_sfselection_,\, sorting results by _sfselection_\,) air  }  
+
+_textnojsformwarning_ [l=gd] {Rabhadh: cha tugadh comas do Javascript anns do shealladair. <br>Ma tha thu airson lorg chrutha a chleachdadh, thoir comas dha.}  
+_textdatesearch_ [l=gd] {Gabhaidh an co-chruinneachadh seo lorg airson sgrÃ¬obhainnean a-staigh sreath cinn-latha no airson sgrÃ¬obhainnean anns a bheil ceann-latha sÃ²nraichte. 'S e goireas roghainneil an luirg a th' ann.}  
+_textstartdate_ [l=gd] {Ceann-latha tÃ²iseachaidh (no a-mhÃ in)}  
+_textenddate_ [l=gd] {Ceann-latha crÃ¬che:}  
+_textbc_ [l=gd] {B.C.E.}  
+_textad_ [l=gd] {C.E.}  
+_textexplaineras_ [l=gd] {Tha C.E. agus B.C.E. faclan eile airson  A.D. and B.C. Chan eil na faclan seo ceangailte ri cultur sam bith, agus tha iad a' ciallachadh "Common Era" agus "Before the Common Era"}  
+
+_textstemon_ [l=gd] {(a' leigeil seachad deiridhean facail)}  
+
+_textsearchhistory_ [l=gd] {Eachdraidh Luirg}  
+
+#text macros for search history
+_textnohistory_ [l=gd] {Chan eil clÃ rachaidhean anns an eachdraidh luirg}  
+_texthresult_ [l=gd] {buil}  
+_texthresults_ [l=gd] {builean}  
+_texthallwords_ [l=gd] {a h-uile facal}  
+_texthsomewords_ [l=gd] {cuid fhaclan}  
+_texthboolean_ [l=gd] {boolean}  
+_texthranked_ [l=gd] {Ã²rdaichte}  
+_texthcaseon_ [l=gd] {feumaidh tuislean a bhith co-ionnan}  
+_texthcaseoff_ [l=gd] {deante co-ionnan}  
+_texthstemon_ [l=gd] {air geÃ rradh}  
+_texthstemoff_ [l=gd] {slÃ n}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=gd] {StÃšidhich roghainnean mar a leanas. Na cleachd putan "Back" air do shealladar - theid an call! An Ã ite sin, put air fear de na putannan air an "Access Bar" gu h-Ã rd.}  
+_textsetprefs_ [l=gd] {StÃšidhich na roghainnean}  
+_textsearchprefs_ [l=gd] {Roghainnean luirg}  
+_textcollectionprefs_ [l=gd] {Roghainnean co-chruinneachaidh}  
+_textpresentationprefs_ [l=gd] {Roghainnean taisbeanaidh}  
+_textpreferences_ [l=gd] {Roghainnean}  
+_textcasediffs_ [l=gd] {Eadar-dhealachaidhean tuiseil:}  
+_textignorecase_ [l=gd] {Leig seachad eadar-dhealachaidhean tuiseil}  
+_textmatchcase_ [l=gd] {feumaidh tuislean uachrach agus iochrach a bhith co-ionnan}  
+_textwordends_ [l=gd] {Deireadh fhaclan:}  
+_textstem_ [l=gd] {Leig seachad deiridhean facal}  
+_textnostem_ [l=gd] {feumaidh am facal slÃ n a bhith co-ionnan}  
+
+
+
+
+_textprefop_ [l=gd] {Thoir dhomh gu ruige  _maxdocoption_ buillean le _hitsperpageoption_ buillean air gach duilleig.}  
+_textextlink_ [l=gd] {Slighe gu lÃ raich-lÃ¬n a-muigh}  
+_textintlink_ [l=gd] {SgrÃ¬bohainnean prÃ¬omhach air fhaighinn bho:}  
+_textlanguage_ [l=gd] {CÃ nan eadar-aghaidh:}  
+_textencoding_ [l=gd] {Cuir ann an cÃ²d:}  
+_textformat_ [l=gd] {Cruth eadar-aghaidh:}  
+_textall_ [l=gd] {uile}  
+_textquerymode_ [l=gd] {Modh ceiste :}  
+_textsimplemode_ [l=gd] {Modh ceiste shÃ¬mplidh}  
+_textadvancedmode_ [l=gd] {Modh ceiste adhartaich (a' ceadachadh lorg boolean a' cleachdadh !, &, |, agus bracaidean)}  
+_textlinkinterm_ [l=gd] {troimh dhuilleag mheadhonach}  
+_textlinkdirect_ [l=gd] {rach dÃ¬reach an sin}  
+_textdigitlib_ [l=gd] {an leabharlann digiteach}  
+_textweb_ [l=gd] {an eadar-lÃ¬on}  
+_textgraphical_ [l=gd] {Dealbhach}  
+_texttextual_ [l=gd] {teacsail}  
+_textcollectionoption_ [l=gd] {<p>
+Fo-chruinneachaidhean a ghabhail a-steach:
+<br>}  
+
+
+
+
+
+_textlargebox_ [l=gd] {mÃ³r}  
+
+_textrelateddocdisplay_ [l=gd] {taisbein sgrÃ¬obhainnean co-cheangailte}  
+_textsearchhistory_ [l=gd] {Eachdraidh luirg:}  
+_textnohistory_ [l=gd] {Chan eil eachdraidh luirg ann}  
+_texthistorydisplay_ [l=gd] {taisbein _historynumrecords_ clÃ ran eachdraidh luirg}  
+_textnohistorydisplay_ [l=gd] {na taisbein eachdraidh luirg}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=gd] {Cuir sgrÃ¬obhainnean ann an Ã²rdugh le}  
+_textalsoshowing_ [l=gd] {a'sealltainn air bharrachd}  
+_textwith_ [l=gd] {leis a' char as motha}  
+_textdocsperpage_ [l=gd] {sgrÃ¬obhainnean air gach duilleig}  
+
+_textfilterby_ [l=gd] {Faigh sgrÃ¬obhainnean anns a bheil}  
+_textall_ [l=gd] {uile}  
+_textany_ [l=gd] {gin}  
+_textwords_ [l=gd] {nam faclan}  
+_textleaveblank_ [l=gd] {fÃ g am bocsa seo falamh airson a h-uile sgrÃ¬obhainn fhaotainn}  
+
+_browsebuttontext_ [l=gd] {"Cuir sgrÃ¬obhainnean ann an Ã²rdugh"}  
+
+_nodata_ [l=gd] {<i>chan eil data ann</i>}  
+_docs_ [l=gd] {sgrÃ¬obhainnean}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=gd] {Cobhair}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+
+
+
+
+
+_textBrowsehelp_ [l=gd] {SgrÃ¹daich sgrÃ¬obhainnean }  
+
+
+
+_texthelptopicstitle_ [l=gd] {CÃ¹isean}
+
+_textreadingdocs_ [l=gd] {Ciamar a leughas tu na sgrÃ¬obhainnean}  
+
+_texthelpreadingdocs_ [l=gd] {<p>Bidh fios agad nuair a ruigeas tu leahbar no sgrÃ¬obhainn, oir nochdaidh a thiotal no dealbh a' chomhdaich aig ceann na duilleige, air an taobh clÃ¬. Ann an cuid co-chruinneachaidhean, nochaidh cuideachd clÃ r-innsidh; ann an cuid eile, nochdaidh aireamh na duilleige far a bheil thu, cÃ²mhla ri bocsa a leigeas leat duilleag Ã¹r thaghadh, no leigeas leat dol air adhart no air ais.  Anns a' clÃ r-innsidh, bidh an roinn gnÃ thach air comharrachadh, agus 's urrainn dhut an clÃ r leudachadh -- put air na pasgannan 'gan fhosgladh no 'gan dhuineadh; put air an leabhar fostgailte shuas 'ga dhuineadh.</p>
+
+<p>Fo sin gheibhear teacs an roinn gnÃ thach. Nuair a bhios thu air a leughadh, bidh saighdean aig a' bhun a bheireas tu gu an ath roinn no air ais do 'n roinn mu dheireadh.</p>
+
+<p>Fo an tiotal no an dealbh gheibhear putannan. Put air <i>leudaich teacs</i> an teacs gu lÃ©ir de 'n roinn seo no de 'n leabhar seo a leudachadh. Ma bhios an sgrÃ¬obhainn mÃ³r, 's docha gum beir sin Ã¹ine fada agus mÃ³ran cuimhne cleachdadh! Put air <i>leudaich clÃ r-innsidh</i> an clÃ r-innsidh gu lÃšir leudachadh airson tiotalan na chabidilean agus fo-roinnean uile fhaicinn. Put air  <i>dealaich</i> uinneag shealladar Ã¹r a dheanamh do 'n sgrÃ¬obhainn seo. (Tha seo feumail, ma bhios thu airson coimeas a dheanamh eadar sgrÃ¬obhainnean, no airson dÃ  sgrÃ¬obhainn a leughadh aig an aon Ã m.) Mu dheireadh, nuair a nÃ¬ thu lorg, chomharraicheadh na faclan a lorg thu. Put air  <i>na comharraich</i> sin a thoirt air falbh.</p>
+}  
+
+# help about the icons
+
+
+_texthelpviewtextsection_ [l=gd] {Faic an roinn seo de 'n teacs }  
+_texthelpexpandtext_ [l=gd] {Seall an teacs gu lÃšir, no na dÃšan e }  
+_texthelpexpandcontents_ [l=gd] {Leudaich clÃ r-Ã¬nnsidh, no na dÃšan e}  
+_texthelpdetachpage_ [l=gd] {Fosgail an duilleag seo ann an uinneag Ã¹r}  
+_texthelphighlight_ [l=gd] {Comharraich teirmean-luirg, no na dÃšan e }  
+
+
+
+_texthelpsearchingtitle_ [l=gd] {Ciamar a lorg faclan Ã raid}
+
+_texthelpsearching_ [l=gd] {<p>
+  Bho 'n duilleag luirg, gabhaidh ceist a dheanamh mar a leanas:<p>
+  
+  <ol><li>Cuir ann dÃ© na goireasan a tha thu airson lorg
+      <li>Innis a bheil thu airson a h-uile facal no cuid dhiubh lorg
+      <li>Cuir ann na faclan a tha thu airson lorg
+      <li>Put air a phutan <i>Toisich Lorg</i> 
+  </ol>
+
+<p>Nuair a nÃ¬ thu ceist, nochdadh tiotalan de fichead sgrÃ¬obhainnean co-ionnan.
+Tha putan aig a' chrÃ¬ch a bheireas tu gu an ath fichead sgrÃ¬obhainnean. Bho sin, gheibh thu putannan a bheireas tu gu an treas fichead no air ais gu a' cheud fichead, agus mar sin air adhart. Put air tiotal sgrÃ¬obhainn sam bith, no air a' phutan beag ri taobh, an sgrÃ¬obhainn fhaicinn.
+
+<p>Gheibhear gus 100 sgrÃ¬obhainnean. 'S urrainn dhut an aireamh seo atharrachadh le putadh air a' phutan <i>roghainnean</i> aig ceann na duilleige.<p>
+}  
+
+_texthelpquerytermstitle_ [l=gd] {Teirmean luirg}
+_texthelpqueryterms_ [l=gd] {<p>Chithear rud sam bith a chuireas tu anns a' bocsa ceiste sreath fhaclan ris an cante "teirmean luirg."  Chan eil anns gach teirm ach litrichean agus meuran-aireamh. Bidh teirmean air an dealachadh le Ã ite geal. Ma nochdas caractaran eile, mar puingeachadh, dealachaidh iad teirmean dÃ¬reach mar Ã itean geala. As deidh sin, leigear iad seachad. Chan urrainn dhut faclan lorg anns a' bheil puingeachadh.
+
+<p>Mar eisimpleir, bidh a' cheist<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>a' laimhseachadh mar<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}  
+
+
+
+
+
+_texthelpquerytypetitle_ [l=gd] {SeÃ²rsa ceiste}
+_texthelpquerytype_ [l=gd] {<p>Tha dÃ  sheÃ²rsa ceist ann.
+
+<ul>
+  <li>Ceistean airson na faclan <b>uile</b>.  Bidh na ceistean sin a lorg sgrÃ¬obhainnean (no cabidilean, no tiotalan) anns a nochdadh a h-uile facal a chuir thu sios. Seallar na sgrÃ¬obhainnean a sheisich a' cheist ann an ordugh abidealach.<p>
+
+  <li>Ceistean airson <b>cuid</b> de na faclan. Cuir sios dÃ¬reach cuid de na faclan a tha thu a' smaoineachadh gu bhith anns na sgrÃ¬obhiannean a tha thu a' lorg. Seallar grÃ¬obhainnean ann an ordugh a rÃ©ir cho dlÃ¹th a sheisich iad a' cheist. A' coimhead air dÃ© cho dlÃ¹th agus a tha iad, 
+
+      <p><ul>
+        <li> nuair a nochdadh barrachd teirmean luirg ann an sgrÃ¬obhainn, seisichidh e nas dlÃ¹ithe;
+        <li> tha teirmean tearca nas cudtromaiche na teirmean cumanta;
+        <li> seisichidh sgrÃ¬obhainnean goirid nas fheÃ rr na sgrÃ¬obhainnean fada.
+      </ul>
+</ul>
+
+<p>Cleachd an aireamh de teirmen lorg a thogras tu -- rosg-rann gu lÃšir, no fiu 's earrann gu lÃšir.  Mura chuireas tu ann ach aon theirm, chuireadh sgrÃ¬obhainnean ann an ordugh le dÃ© cho tric a nochdas an teirm sin.<p>
+}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textdatesearch_ [l=gd] {A' lorg le cinn-latha}  
+
+_texthelpdatesearch_ [l=gd] {Bheir lorg cinn-latha cothrom dhut sgrÃ¬obhainnean fhaighinn, a tha, a thuilleadh air a bhith aâ maidseadh do lorg, mu thachartasan bho Ã m sÃ²nraichte. Gheibh thu air lorg airson sgrÃ¬obhainnean bho bhliadhna shÃ²nraichte no bho sreath bhliadhnaichean. Bi mothachail nach leig thu a leas teirmean luirg a chleachdadh â faodaidh tu lorg le ceann-latha a-mhÃ in; mothaich cuideachd nach leig thu a leas cinn-latha a chleachdadh na do lorg, mura cuir thu cinn-latha a-steach tha e mar nach biodh an lorg cinn-latha ann idir.<p>}  
+
+_texthelpdatehowtotitle_ [l=gd] {Ciamar a chleachdadh an goireas seo:}
+_texthelpdatehowto_ [l=gd] {<ul>
+   <li>A lorg sgrÃ¬obhainnean mu aon bhliadhna :<p>
+   <ul>
+       <li>Cuir ann teirmean luirg sam bith mar as Ã bhaist.
+       <li>Cuir am bliadhna taghte anns a' bocsa "Ceann-latha toiseach (no a-mhain)".
+       <li>Ma bhios an ceann-latha sin roimh an lÃ¬nn cumanta (cante cuideachd mar roimh Criosda), tagh an roghainn "B.C.E" bho 'n clÃ r ri taobh a' bhocsa sin.
+       <li>Toisich do lorg mar as Ã bhaist.
+   </ul>
+<p><li>A lorg sgrÃ¬obhainnean mu Ã m Ã raid no sreath bhliadhnaichean:<p>
+   <ul>
+       <li>Cuir ann teirmean luirg sam bith mar as Ã bhaist.
+       <li>Cuir an ceann-latha nas trÃ ithe anns a' bocsa "Ceann-latha toiseach (no a-mhain)".
+       <li>Cuir an ceann-latha air deireadh anns a' bocsa "Ceann-latha crÃ¬che".        <li>Tagh an roghainn "B.C.E" bho 'n clÃ r ri taobh ceann-latha sam bith a tha roimh an lÃ¬nn cumanta (cante cuideachd mar roimh Criosda).
+           
+       <li>Toisich do lorg mar as Ã bhaist.    </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=gd] {Ciamar a dh' obraicheas toradh do luirg}
+_texthelpdateresults_ [l=gd] {Chan fhaigh lorg airson sgrÃ¬obhainnean mu bhliadhna 1903 sgrÃ¬obhainnean anns a bheil iomradh air leabhraichean sgrÃ¬obhte ann an 1903, can, ach dÃ¬reach sgrÃ¬obhainnean mu 1903. Ach, leis mar a tha cinn-latha na sgrÃ¬obhainnean air an lorg, gheibhear sgrÃ¬obhainnean aig a bheil sreath cinn-latha (mar eisimpleir 1899-1911) anns a nochdadh 1903, agus cuideachd na sgrÃ¬obhainnean aig a bheil ainm teacsa leis ainm an lÃ¬nn anns a bheil 1903 (mar eisimpleir 20mh lÃ¬nn no ficheadamh lÃ¬nn). Tha sin a' ciallachadh gu bheil ann an cuid de na sgrÃ¬obhainnean, cha nochd cinn-latha do luirg ann an teacs an sgrÃ¬obhainn fhÃšin. Tha sin fÃ¬or airson gach ceann-latha ann an lorg sreath cinn-latha.<p>
+}  
+
+_textchangeprefs_ [l=gd] {Ag atharrachadh do roghainnean}  
+
+_texthelppreferences_ [l=gd] {<p>Nuair a phutas tu am putan <i>roghainnean</i> aig ceann na duileige, 's urrainn dhut cuid de goireasan eadar-aghaidh atharrachadh a rÃ©ir do riatasan.
+}  
+
+_texthelpcollectionprefstitle_ [l=gd] {Roghainnean cho-chruinneachaidh}
+_texthelpcollectionprefs_ [l=gd] {Tha cuid de cho-chruinneachaidhean anns a bheil grunn fo-chruinneachaidhean, agus dhâfhaodar lorg air an son air leth no cÃ²mhla, mar ionad. Ma bhios tu airson sin a dhÃšanamh, faodaidh tu na fo-chruinneachaidhean a tha thu airson a lorg a thaghadh air an duilleig Roghainnean.}  
+
+_texthelplanguageprefstitle_ [l=gd] {Roghainnean cÃ nain}  
+_texthelplanguageprefs_ [l=gd] {Tha cÃ nan tÃ²iseachadh taisbeanaidh aig gach co-chruinneachadh, ach faodadh tu atharrachadh gu cÃ nan eile ma thogras tu. Faodaidh tu an innleachd-chÃ²d a tha Greenstone aâ cleachdadh airson toradh a chur gun t-sealladair atharrachadh cuideachd. Taghaidh am bathar-bog ro-shuidheachaidhean freagarrach, ach le cuid a shealladairean gheibhear builean fradharcach nas fheÃ rr le atharrachadh gu innleachd-chÃ²d eile. Tha gach co-chruinneachadh aâ toirt cothrom dhut atharrachadh bhon eadar-aghaidh ghrafail chumanta gu eadar-aghaidh theacsail.  Tha sin feumail gu h-Ã raidh do luchd-cleachdaidh le ciorram fradharcach a bhios aâ cleachdadh clÃ²-sgrion mÃ²r no siontasaiseirean cainnte airson toradh. }  
+
+_texthelppresentationprefstitle_ [l=gd] {Roghainnean taisbeanaidh}
+_texthelppresentationprefs_ [l=gd] {A rÃšir aâ cho-chruinneachaidh, dhâfhaodadh gum bi grunn roghainnean ann airson smachd a chur air an taisbeanadh.
+
+<p>Bheir co-chruinneachaidhean de dhuilleagan-lÃ¬n cothrom dhut crann-stiÃ¹iridh Greenstone aig mullach gach duilleig sgrÃ¬obhainn a chumail fodha, âs mar sin nuair a tha thu air lorg a dhÃšanamh ruigidh tu air an dearbh dhuilleig lÃ¬n a tha aâ maidseadh, gun ceann-sgrÃ¬obhaidh Greenstone sam bith. Feumaidh tu am putan âair aisâ a chleachdadh airson lorg eile a dhÃšanamh. Bheir na co-chruinneachaidhean seo cuideachd cothrom dhut teachdaireachd rabhaidh Greenstone a chumail fodha nuair a phutas tu air ceangal a bheir thu a-mach Ã s aâ cho-chruinneachadh leabharlainn didseataich agus a-steach don eadarlÃ¬on fhÃšin. Agus, ann an cuid de cho-chruinneachaidhean-lÃ¬n, faodaidh smachd a bhith agad mu an toir na ceangail air an duilleig âToraidhean-luirgâ thu dÃ¬reach don URL-fhÃšin, an Ã ite gu lethbreac na duilleige aig an leabharlann didseatach.
+}  
+
+_texthelpsearchprefstitle_ [l=gd] {Roghainnean luirg}
+_texthelpsearchprefs_ [l=gd] {<p>Bidh dÃ  phaidhir phutain a' riaghladh an seÃ²rsa seiseachadh-teacs anns na lorgan a nÃ¬ thu. Tha a' cheud bhuidheann ("eadar-dhealachaidhean tuiseil") a' riaghladh gun fheum no nach fheum tuiseil uachrach agus iochrach a bhith co-ionnan. Tha an darna bhuidheann ("deiridhean facail") a' riaghladh an leigeadh seachad deiridhean facail. Gabhaidh bocsa ceiste mÃ³r fhaighinn; mar sin, 's urrainn dhut earranan teacsa lorg. Gabhaidh meud mÃ³r de teacs a lorg gu luath. 
+<p>Mar eisimpleir, ma bhios na putannan <i>Leig seachad eadar-dhealachaidhean tuiseil</i> agus
+<i>leig seachad deireidhran-facail</i> taghte, bidh a' cheist<p>
+    <ul><kbd>African building</kbd></ul>
+      <p>a' lÃ imhseachadh dÃ¬reach mar<p>
+      <ul><kbd>africa builds</kbd></ul><p>
+      oir bidh an litir tuiseal uachrach ann "African" ag atharrachad gu tuiseal iochrach, agus bidh "n" agus "ing" air an toirt a-mach bho       "African" agus "building" (biodh "s" air an toirt a-mach bho "builds", cuideachd).
+
+<p>'S urrainn dhut atharrachadh gu modh ceiste "adhartach" a leigeas leat faclan a chur ri chÃšile le  AND (&), OR (|), agus NOT (!). Leigidh sin leat ceistean nas pongaile a dheanamh.  'S urrainn dhut an goireas eachraidh luirg a chleachdadh, a sheallas dhut do cheistean mu dheireadh. Mar sin, tha e furasda ceistean air an atharrachadh a dheanamh a rithist. Mu dheireadh, 's urrainn dhut aireamh builean agus aireamh builean air gach duilleag a riaghladh.}  
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+_texttanumbrowseoptions_ [l=gd] {Tha _numbrowseoptions_ doighean ann airson fiosrachadh fhaighinn anns a' chruinneachadh seo:}  
+
+_textsimplehelpheading_ [l=gd] {Ciamar a gheibh thu fiosrachadh anns a' cho-chruinneachadh _collectionname_ 
+ }  
+
+_texthelpscopetitle_ [l=gd] {Meud cheistean}
+_texthelpscope_ [l=gd] {<p>
+Anns a' chuid as motha de na co-chruinneachaidhean, 's urrainn dhut taghadh eadar clÃ ran-amais eadar-dhealaichte a lorg. Mar eisempleir, 's docha gum biodh clÃ ran-amais Ã¹dhdair no thiotal ann, no clÃ ran-amais chabidil no earrann. Mar as Ã bhaist, gheibhear an sgrÃ¬obhainn co-ionnan gu lÃšir, ge bith dÃ© an clÃ r-amais a chleachd thu.
+<p>Ma 's e leabhraichean a th'ann an sgrÃ¬obhainnean, fhosgladh iad aig an Ã ite freagarrach.
+}  
Index: /gsdl/stable/macros/galician.dm
===================================================================
--- /gsdl/stable/macros/galician.dm	(revision 20131)
+++ /gsdl/stable/macros/galician.dm	(revision 20131)
@@ -0,0 +1,946 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Galician Language text and icon macros
+# TraducciÃ³n Ã³ galego feita por XaquÃ­n Lores xaquin@udc.es
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=gl] {PublicaciÃ³ns periÃ«dicas}
+_textsource_ [l=gl] {fonte: }
+_textdate_ [l=gl] {data de publicaciÃ³n: }
+_textnumpages_ [l=gl] {nÃºmero de pÃ¡xinas: }
+
+_textsignin_ [l=gl] {conectar}
+
+_textdefaultcontent_ [l=gl] {Non se atopa a pÃ¡xina solicitada. Por favor prema o
+botÃ³n "AtrÃ¡s" do seu navegador ou o botÃ³n "Principal" para regresar Ã¡ Biblioteca Dixital Greenstone}
+
+_textdefaulttitle_ [l=gl] {Erro en GSDL}
+
+# -- Missing translation: _textbadcollection_
+
+# -- Missing translation: _textselectpage_
+
+_collectionextra_ [l=gl] {Esta coleciÃ³n contÃ©n _about:numdocs_ documentos, e foi creada hai _about:builddate_ dÃ­as.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=gl] {<p>Esta colecciÃ³n contÃ©n _numdocs_ _If_("_numdocs_" eq
+"1",documento,documentos) e un total de _numbytes_.
+<p><a href="_httppagex_(bsummary)">Prema aquÃ­</a> para visualizar o
+informe de creaciÃ³n desta colecciÃ³n.
+}
+
+_textdescrcollection_ [l=gl] {}
+_textdescrabout_ [l=gl] {PÃ¡xina Acerca de}
+_textdescrhome_ [l=gl] {PÃ¡xina Principal}
+_textdescrhelp_ [l=gl] {PÃ¡xina de axuda}
+_textdescrpref_ [l=gl] {PÃ¡xina de Preferencias}
+_textdescrgreenstone_ [l=gl] {Programa da Biblioteca Dixital Greenstone}
+# -- Missing translation: _textdescrusab_
+
+_textdescrSearch_ [l=gl] {Buscar termos especÃ­ficos}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=gl] {Lista alfabÃ©tica de tÃ­tulos}
+_textdescrCreator_ [l=gl] {Lista de autores por orde alfabÃ©tica}
+_textdescrSubject_ [l=gl] {Lista por materias}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=gl] {Lista por data}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+_textdescrSource_ [l=gl] {Lista por nome de ficheiro orixinal}
+_textdescrLanguage_ [l=gl] {Lista por lingua}
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=gl] {Lista por organizaciÃ³n}
+_textdescrKeyword_ [l=gl] {Lista por palabra clave}
+_textdescrHowto_ [l=gl] {Lista por "Como..."}
+_textdescrList_ [l=gl] {Lista de documentos}
+_textdescrSeries_ [l=gl] {Lista por nÃºmero de publicaciÃ³n}
+_textdescrTo_ [l=gl] {Lista por campo "Para:"}
+_textdescrFrom_ [l=gl] {Lista por campo "De:"}
+_textdescrTopic_ [l=gl] {Lista por temas especiais}
+_textdescrBrowse_ [l=gl] {Navegar}
+# -- Missing translation: _textdescrCollage_
+_textdescrPeople_ [l=gl] {Lista de persoas por orde alfabÃ©tica}
+_textdescrAcronym_ [l=gl] {Lista de siglas}
+_textdescrPhrase_ [l=gl] {Lista de frases}
+_textdescrArtist_ [l=gl] {Lista de artistas}
+_textdescrVolume_ [l=gl] {Lista por volume}
+# -- Missing translation: _textdescrCountries_
+# -- Missing translation: _textdescrCaptions_
+
+
+_labelSearch_ [l=gl] {Buscar}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=gl] {TÃ­tulos A-Z}
+_labelCreator_ [l=gl] {Autores A-Z}
+_labelSubject_ [l=gl] {Materias}
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=gl] {Datas}
+# -- Missing translation: _labelType_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+_labelSource_ [l=gl] {Nomes de ficheiros}
+_labelLanguage_ [l=gl] {Lingua}
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=gl] {OrganizaciÃ³n}
+_labelKeyword_ [l=gl] {Palabras clave}
+_labelHow_ [l=gl] {CÃ³mo...}
+_labelSeries_ [l=gl] {Series}
+_labelList_ [l=gl] {Listas}
+_labelTo_ [l=gl] {Para}
+_labelFrom_ [l=gl] {De}
+_labelTopic_ [l=gl] {Temas}
+_labelBrwse_ [l=gl] {Navegar}
+# -- Missing translation: _labelCollage_
+_labelBrows_ [l=gl] {Navegar}
+_labelPeople_ [l=gl] {Persoas A-Z}
+_labelAcronym_ [l=gl] {Siglas}
+_labelPhrase_ [l=gl] {Frases}
+_labelArtist_ [l=gl] {Artistas}
+_labelVolume_ [l=gl] {Volumes}
+# -- Missing translation: _labelCaptions_
+# -- Missing translation: _labelCountries_
+
+_texticontext_ [l=gl] {Ver o documento}
+_texticonclosedbook_ [l=gl] {Abrir este documento e ver o seu Ã­ndice de contido}
+_texticonnext_ [l=gl] {Ir Ã¡ seguinte secciÃ³n}
+_texticonprev_ [l=gl] {Ir Ã¡ secciÃ³n anterior}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=gl] {Ver o documento no formato MIDI}
+_texticonmsword_ [l=gl] {Ver o documento no formato Microsoft Word}
+_texticonmp3_ [l=gl] {Ver o documento no formato MP3}
+_texticonpdf_ [l=gl] {Ver o documento no formato PDF}
+_texticonps_ [l=gl] {Ver o documento no formato PostScript}
+_texticonppt_ [l=gl] {Ver o documento no formato PowerPoint}
+_texticonrtf_ [l=gl] {Ver o documento no formato RTF}
+_texticonxls_ [l=gl] {Ver o documento no formato Microsoft Excel}
+
+_page_ [l=gl] {pÃ¡xina }
+_pages_ [l=gl] {pÃ¡xinas}
+_of_ [l=gl] {de }
+_vol_ [l=gl] {Vol.}
+_num_ [l=gl] {NÂº}
+
+_textmonth00_ [l=gl] {}
+_textmonth01_ [l=gl] {xaneiro}
+_textmonth02_ [l=gl] {febreiro}
+_textmonth03_ [l=gl] {marzo}
+_textmonth04_ [l=gl] {abril}
+_textmonth05_ [l=gl] {maio}
+_textmonth06_ [l=gl] {xuÃ±o}
+_textmonth07_ [l=gl] {xullo}
+_textmonth08_ [l=gl] {agosto}
+_textmonth09_ [l=gl] {setembro}
+_textmonth10_ [l=gl] {outubro}
+_textmonth11_ [l=gl] {novembro}
+_textmonth12_ [l=gl] {decembro}
+
+_textdocument_ [l=gl] {Documento}
+_textsection_ [l=gl] {SecciÃ³n}
+_textparagraph_ [l=gl] {Paragrafo}
+
+_magazines_ [l=gl] {Revistas}
+
+_nzdlpagefooter_ [l=gl] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">Proxecto de Biblioteca Dixital de Nova
+Celandia</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Departamento de informÃ¡tica</a>,
+<a href="http://www.waikato.ac.nz">Universidade de Waikato</a>,
+Nova Celandia}
+
+_linktextHOME_ [l=gl] {PRINCIPAL}
+_linktextHELP_ [l=gl] {AXUDA}
+_linktextPREFERENCES_ [l=gl] {PREFERENCIAS}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=gl] {Biblioteca Dixital Greenstone}
+_textadmin_ [l=gl] {PÃ¡xina de administraciÃ³n}
+_textabgs_ [l=gl] {Acerca de Greenstone}
+_textgsdocs_ [l=gl] {DocumentaciÃ³n de Greenstone}
+
+_textdescradmin_ [l=gl] {PermÃ­telle engadir novos usuarios, dÃ¡ un resume das colecciÃ³ns que hai no
+sistema e proporciona informaciÃ³ns tÃ©cnicas sobre a instalaciÃ³n de Greenstone.
+}
+
+_textdescrgogreenstone_ [l=gl] {ProporciÃ³nalle informaciÃ³n sobre o programa Greenstone e o proxecto de biblioteca
+Dixital de Nova Celandia, de onde provÃ©n
+}
+
+_textdescrgodocs_ [l=gl] {Manuais de Greenstone}
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textdescrgli_ [l=gl] {AxÃºdalle a crear novas colecciÃ³ns, modificar ou suprimir colecciÃ³ns existentes,
+ou engadir documentos nunha colecciÃ³n.
+}
+
+package collector
+
+_textcollector_ [l=gl] {O Coleccionista}
+
+package depositor
+
+
+package gti
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=gl] {Acerca desta colecciÃ³n}
+
+_textsubcols1_ [l=gl] {<p>A colecciÃ³n completa comprende _1_ subcolecciÃ³ns. As dispoÃ±ibles actualmente son:
+<blockquote>}
+
+_textsubcols2_ [l=gl] {</blockquote>
+Na pÃ¡xina de Preferencias pode vostede seleccionar (e cambiar) as
+subcolecciÃ³ns en uso.}
+
+
+_titleabout_ [l=gl] {acerca de}
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+# -- Missing translation: _texticonhcoll_
+# -- Missing translation: _texticonhcapt_
+# -- Missing translation: _texticonhcount_
+
+_texticonopenbookshelf_ [l=gl] {pechar esta secciÃ³n da biblioteca}
+_texticonclosedbookshelf_ [l=gl] {abrir esta secciÃ³n da biblioteca e ver o seu contido}
+_texticonopenbook_ [l=gl] {pechar este libro}
+_texticonclosedfolder_ [l=gl] {Abrir esta carpeta e ver o seu contido}
+_texticonclosedfolder2_ [l=gl] {abrir subsecciÃ³n: }
+_texticonopenfolder_ [l=gl] {pechar esta carpeta}
+_texticonopenfolder2_ [l=gl] {pechar subsecciÃ³n: }
+_texticonsmalltext_ [l=gl] {Ver esta secciÃ³n do texto}
+_texticonsmalltext2_ [l=gl] {ver texto: }
+_texticonpointer_ [l=gl] {secciÃ³n en curso}
+_texticondetach_ [l=gl] {Abrir esta PÃ¡xina nunha nova ventÃ¡}
+_texticonhighlight_ [l=gl] {Resaltar os termos da busca}
+_texticonnohighlight_ [l=gl] {Non resaltar os termos da busca}
+_texticoncontracttoc_ [l=gl] {Contraer o Ã­ndice de contido}
+_texticonexpandtoc_ [l=gl] {Expandir o Ã­ndice de contido}
+_texticonexpandtext_ [l=gl] {Mostrar o texto completo}
+_texticoncontracttext_ [l=gl] {Mostrar unicamente o texto da secciÃ³n seleccionada}
+_texticonwarning_ [l=gl] {<b>Advertencia: </b>}
+_texticoncont_ [l=gl] {Â¿desexa continuar?}
+
+_textltwarning_ [l=gl] {<div class="buttons">_imagecont_</div>
+_iconwarning_Expandir o texto aquÃ­ xerarÃ¡ unha gran
+cantidade de datos que o seu navegador terÃ¡ que procesar
+}
+
+_textgoto_ [l=gl] {ir Ã¡ pÃ¡xina}
+_textintro_ [l=gl] {<i>(texto introductorio)</i>}
+
+_textCONTINUE_ [l=gl] {Â¿DESEXA CONTINUAR?}
+
+_textEXPANDTEXT_ [l=gl] {TEXTO\nCOMPLETO}
+
+_textCONTRACTCONTENTS_ [l=gl] {CONTRAER\nÃ­NDICE}
+
+_textDETACH_ [l=gl] {SEPARAR}
+
+_textEXPANDCONTENTS_ [l=gl] {EXPANDIR\nÃ­NDICE}
+
+_textCONTRACT_ [l=gl] {CONTRAER\nTEXTO}
+
+_textHIGHLIGHT_ [l=gl] {RESALTAR}
+
+_textNOHIGHLIGHT_ [l=gl] {NON\nRESALTAR}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=gl] {_If_(_thislast_,resultados _thisfirst_ - _thislast_ para a consulta:_cgiargq_,Non se atoparon resultados correspondentes Ã¡ consulta: _cgiargq_)}
+_textnoquerytitle_ [l=gl] {PÃ¡xina de busca}
+
+_textsome_ [l=gl] {algunhas das}
+_textall_ [l=gl] {todas as}
+_textboolean_ [l=gl] {boolean0}
+_textranked_ [l=gl] {ordenado}
+_textnatural_ [l=gl] {natural}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=gl] {historial de buscas}
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+_textusequery_ [l=gl] {utilizar esta consulta}
+_textfreqmsg1_ [l=gl] {Palabras contadas: }
+_textpostprocess_ [l=gl] {_If_(_quotedquery_,<br><i>postprocesado para encontrar _quotedquery_</i>
+)}
+# -- Missing translation: _textinvalidquery_
+
+_textmorethan_ [l=gl] {MÃ¡is de }
+_textapprox_ [l=gl] {Acerca de }
+_textnodocs_ [l=gl] {Non hai documentos que correspondan Ã¡ consulta.}
+_text1doc_ [l=gl] {1 documento corresponde Ã¡ consulta.}
+_textlotsdocs_ [l=gl] {documentos corresponden Ã¡ consulta.}
+_textmatches_ [l=gl] {Resultados }
+_textbeginsearch_ [l=gl] {Iniciar a busca}
+_textrunquery_ [l=gl] {Executar a busca}
+_textclearform_ [l=gl] {Borrar o formulario}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=gl] {Palabra ou frase}
+_textinfield_ [l=gl] {... no campo}
+_textfoldstem_ [l=gl] {(maiÃºsculas e minÃºsculas, terminaciÃ³ns de palabras)}
+
+_textadvquery_ [l=gl] {Ou teclee directamente unha consulta:}
+_textallfields_ [l=gl] {Todos os campos}
+# -- Missing translation: _texttextonly_
+_textand_ [l=gl] {e}
+_textor_ [l=gl] {ou}
+_textandnot_ [l=gl] {e non}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=gl] {Buscar _indexselection__If_(_jselection_, de _jselection_)_If_(_nselection_, en idioma _nselection_) que conteÃ±an _querytypeselection_  palabras}
+
+_textadvancedsearch_ [l=gl] {Buscar _indexselection__If_(_jselection_, de _jselection_)_If_(_nselection_, en idioma _nselection_) utilizando a consulta _querytypeselection_}
+
+_textformsimplesearch_ [l=gl] {Buscar _If_(_jselection_, _jselection_) _If_(_gformselection_, at _gformselection_
+level) _If_(_nselection_, in _nselection_ language) que conteÃ±an
+_formquerytypesimpleselection_ de}
+
+_textformadvancedsearch_ [l=gl] {Buscar _If_(_jselection_,_jselection_) _If_(_gformselection_,
+at _gformselection_ level)_If_(_nselection_, in _nselection_ language) e
+ presentar os resultados por orde _formquerytypeadvancedselection_ }
+
+
+# -- Missing translation: _textnojsformwarning_
+_textdatesearch_ [l=gl] {<p>Podense buscar nesta colecciÃ³n
+documentos comprendidos nun intervalo de datas, ou documentos que
+conteÃ±an unha data en particular. Esta Ã© unha caracterÃ­stica
+facultativa da busca.}
+_textstartdate_ [l=gl] {Data inicial (ou Ãºnica):}
+_textenddate_ [l=gl] {Data final:}
+_textbc_ [l=gl] {Antes da nosa era}
+_textad_ [l=gl] {Da nosa era}
+_textexplaineras_ [l=gl] {"Da nosa era" e "Antes da nosa era" son formas alternativas de expresar "despois de Cristo" e "antes de Cristo", respectivamente. Son expresiÃ³ns con menos connotaciÃ³ns culturais}
+
+_textstemon_ [l=gl] {(ignorar as terminaciÃ³ns das palabras)}
+
+_textsearchhistory_ [l=gl] {Historial de buscas}
+
+#text macros for search history
+_textnohistory_ [l=gl] {Non estÃ¡ disponible o historial de buscas}
+_texthresult_ [l=gl] {resultado}
+_texthresults_ [l=gl] {resultados}
+_texthallwords_ [l=gl] {todas as palabras}
+_texthsomewords_ [l=gl] {algunhas palabras}
+_texthboolean_ [l=gl] {booleano}
+_texthranked_ [l=gl] {ordenado}
+_texthcaseon_ [l=gl] {ter en conta maiÃºsculas e minÃºsculas}
+_texthcaseoff_ [l=gl] {non ter en conta maiÃºsculas e minÃºsculas}
+_texthstemon_ [l=gl] {non ter en conta as terminaciÃ³ns das palabras}
+_texthstemoff_ [l=gl] {ter en conta as terminaciÃ³ns das palabras}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=gl] {As preferencias fixÃ¡ronse da seguinte maneira. Non prema o botÃ³n "AtrÃ¡s" do seu navegador, porque non quedarÃ­an gravadas.
+Utilice mellor un dos botÃ³ns da barra de acceso superior.
+}
+_textsetprefs_ [l=gl] {fixar preferencias}
+_textsearchprefs_ [l=gl] {Preferencias de busca}
+_textcollectionprefs_ [l=gl] {Preferencias de colecciÃ³n}
+_textpresentationprefs_ [l=gl] {Preferencias de presentaciÃ³n}
+_textpreferences_ [l=gl] {Preferencias}
+_textcasediffs_ [l=gl] {RecoÃ±ecemento de maiÃºsculas e minÃºsculas:}
+_textignorecase_ [l=gl] {ignorar diferencias entre maiÃºsculas e minÃºsculas}
+_textmatchcase_ [l=gl] {deben corresponder maiÃºsculas e minÃºsculas}
+_textwordends_ [l=gl] {TerminaciÃ³ns das palabras:}
+_textstem_ [l=gl] {ignorar as terminaciÃ³ns das palabras}
+_textnostem_ [l=gl] {debe corresponder a palabra completa}
+_textprefop_ [l=gl] {Presentar ata _maxdocoption_ resultados con _hitsperpageoption_ resultados por pÃ¡xina.}
+_textextlink_ [l=gl] {Acceder a PÃ¡xinas Web externas: }
+_textintlink_ [l=gl] {Documentos fonte recuperados de:}
+_textlanguage_ [l=gl] {Idioma da interface: }
+_textencoding_ [l=gl] {CodificaciÃ³n: }
+_textformat_ [l=gl] {Formato da interface: }
+_textall_ [l=gl] {todos}
+_textquerymode_ [l=gl] {Tipo de busca:}
+_textsimplemode_ [l=gl] {busca simple}
+_textadvancedmode_ [l=gl] {busca avanzada (permite efectuar buscas booleanas utilizando os caracteres !, &, | e os parÃ©nteses)}
+_textlinkinterm_ [l=gl] {a travÃ©s dunha pÃ¡xina intermedia}
+_textlinkdirect_ [l=gl] {ir directamente aÃ­}
+_textdigitlib_ [l=gl] {a biblioteca dixital}
+_textweb_ [l=gl] {o Web}
+_textgraphical_ [l=gl] {GrÃ¡fico}
+_texttextual_ [l=gl] {Textual}
+_textcollectionoption_ [l=gl] {<p>
+SubcolecciÃ³ns para incluÃ­r:
+<br>}
+
+_textrelateddocdisplay_ [l=gl] {mostrar documentos relacionados }
+_textsearchhistory_ [l=gl] {Historial de buscas:}
+_textnohistory_ [l=gl] {O historial de buscas non estÃ¡ dispoÃ±ible }
+_texthistorydisplay_ [l=gl] {mostrar as _historynumrecords_ Ãºltimas buscas}
+_textnohistorydisplay_ [l=gl] {non mostrar o historial de buscas }
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=gl] {busca con formulario}
+# -- Missing translation: _textplainsearch_
+_textqueryboxsize_ [l=gl] {TamaÃ±o do cadro de busca:}
+_textregbox_ [l=gl] {cadro de busca normal}
+_textbigbox_ [l=gl] {cadro de busca grande}
+_textformtype_ [l=gl] {Tipo de formulario:}
+_textsimple_ [l=gl] {simple}
+_textadvanced_ [l=gl] {avanzado}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=gl] {con}
+_textfields_ [l=gl] {campos}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=gl] {Ordenar os documentos por}
+_textalsoshowing_ [l=gl] {mostra tamÃ©n}
+_textwith_ [l=gl] {cun mÃ¡ximo de}
+_textdocsperpage_ [l=gl] {documentos por pÃ¡xina}
+
+_textfilterby_ [l=gl] {Buscar documentos que conteÃ±an}
+_textall_ [l=gl] {todas as}
+_textany_ [l=gl] {algunhas das}
+_textwords_ [l=gl] {as palabras}
+_textleaveblank_ [l=gl] {deixar este cadro baleiro para obter todos os documentos}
+
+_browsebuttontext_ [l=gl] {"Ordenar os documentos"}
+
+_nodata_ [l=gl] {<i>sen datos</i>}
+_docs_ [l=gl] {documentos}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=gl] {Axuda}
+_textSearchshort_ [l=gl] {buscar determinadas palabras}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por tÃ­tulo}
+_textCreatorshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por autor}
+_textSubjectshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por materia}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por data}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por nome de ficheiro}
+_textLanguageshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por lingua}
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por series}
+_textToshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por campo "para:"}
+_textFromshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por campo "de:"}
+_textBrowseshort_ [l=gl] {Lista das publicaciÃ³ns}
+_textOrganizationshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por OrganizaciÃ³n}
+_textHowtoshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por lista de "Como..."}
+_textTopicshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por tema}
+_textPeopleshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por persoas}
+_textAcronymshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por apariciÃ³n de siglas}
+_textPhraseshort_ [l=gl] {Lista das frases que aparecen nas publicaciÃ³ns}
+_textArtistshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por artista}
+_textKeywordshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por palabra clave}
+_textVolumeshort_ [l=gl] {Acceder Ã¡s publicaciÃ³ns por volume}
+# -- Missing translation: _textCountriesshort_
+_textdefaultshorttext_ [l=gl] {ClasificaciÃ³n non definida}
+
+_textSearchlong_ [l=gl] {<p>PÃ³dese <i>buscar determinadas
+palabras</i> que aparecen no texto desde a pÃ¡xina de "busca". Esta
+Ã© a primeira pÃ¡xina que aparece Ã³ principio e Ã¡ que se pode
+acceder desde outras pÃ¡xinas pulsando o botÃ³n <i>buscar</i>. }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns por
+tÃ­tulo</i> pulsando o botÃ³n <i>tÃ­tulos a-z</i>. O resultado serÃ¡ unha
+lista de libros por orde alfabÃ©tica. }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=gl] {<p>PÃ³dese <i>acceder as publicaciÃ³ns por
+autor</i> pulsando o botÃ³n <i>autores a-z</i>. O resultado serÃ¡ unha
+lista de libros ordenados por nome do autor. }
+
+_textSubjectlong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns
+por materia</i> presionando o botÃ³n de <i>materias</i>. O resultado serÃ¡ unha
+lista de materias, representadas por librerÃ­as. }
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns por
+data</i> pulsando o botÃ³n <i>datas</i>. O resultado serÃ¡ unha lista
+de todas las publicaciÃ³ns, ordenadas cronoloxicamente. }
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns por
+nome de ficheiro</i> pulsando o botÃ³n <i>nomes de ficheiros</i>. O
+resultado serÃ¡ unha lista ordenada por nome de ficheiro orixinal. }
+
+_textLanguagelong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns por
+lingua</i> presionando o botÃ³n <i>linguas</i>. O resultado serÃ¡ una
+lista ordenada por lingua. }
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns
+por organizaciÃ³n</i> pulsando o botÃ³n <i>organizaciÃ³n</i>. O resultado
+serÃ¡ unha lista de organizaciÃ³ns. }
+
+_textHowtolong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns por unha
+lista de "como..."</i> pulsando o botÃ³n <i>como</i>.
+O resultado serÃ¡ unha lista de categorÃ­as "como...". }
+
+_textTopiclong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns por
+tema</i> pulsando o botÃ³n <i>tema</i>. O resultado serÃ¡ unha lista de
+temas. }
+
+_textTolong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns polo
+campo "Para:"</i> pulsando o botÃ³n <i>para</i>. O resultado serÃ¡ unha lista de
+destinatarios. }
+
+_textFromlong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns polo
+campo "De:"</i> pulsando o botÃ³n <i>de</i>. O resultado serÃ¡ unha lista
+de remitentes. }
+
+_textSerieslong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns por
+series</i> pulsando o botÃ³n <i>series</i>. O resultado serÃ¡ unha lista
+das series que se atopen na colecciÃ³n. }
+
+_textBrowselong_ [l=gl] {<p>PÃ³dese <i>navegar nas publicaciÃ³ns</i>
+pulsando o botÃ³n <i>navegar</i>. }
+
+_textPeoplelong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns por
+persoas</i> pulsando o botÃ³n <i>persoas a-z</i>. O resultado serÃ¡ una
+lista ordenada por apelido. }
+
+_textAcronymlong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns por
+apariciÃ³n de siglas</i> pulsando o botÃ³n <i>siglas</i>. O resultado
+serÃ¡ unha lista de siglas e os lugares onde aparecen. }
+
+_textPhraselong_ [l=gl] {<p>PÃ³dese <i>navegar nas frases que aparecen
+nas publicaciÃ³ns</i> pulsando o botÃ³n <i>frases</i>. UtilizÃ¡ndose o navegador "phind phrase". }
+
+_textArtistlong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns por
+artista</i> pulsando o botÃ³n <i>artistas</i>. O resultado serÃ¡ unha
+lista ordenada por nome do artista. }
+
+_textKeywordlong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns por
+palabra clave</i> pulsando o botÃ³n <i>palabras clave</i>. O resultado
+serÃ¡ unha lista de palabras clave. }
+
+_textVolumelong_ [l=gl] {<p>PÃ³dese <i>acceder Ã¡s publicaciÃ³ns por
+volume</i> pulsando o botÃ³n <i>volumes</i>. O resultado
+serÃ¡ unha lista de volumes. }
+
+# -- Missing translation: _textCaptionslong_
+
+# -- Missing translation: _textCountrieslong_
+
+
+_textdefaultlongtext_ [l=gl] {<p>Prema o botÃ³n <i>descoÃ±ecido</i> para
+consultar as publicaciÃ³ns (a lista ordÃ©nase segundo un campo
+descoÃ±ecido). }
+
+_texthelptopicstitle_ [l=gl] {Temas}
+
+_textreadingdocs_ [l=gl] {Â¿Como ler os documentos?}
+
+_texthelpreadingdocs_ [l=gl] {
+<p> Cando aparece en pantalla un documento individual, o seu tÃ­tulo e o seu
+autor pÃ³dense ver na parte superior esquerda da pÃ¡xina. Ã³ lado
+destes pÃ³dese ver
+o nÃºmero da pÃ¡xina en curso, un cadro que permite seleccionar unha nova pÃ¡xina e
+as frechas que permiten pasar Ã¡ pÃ¡xina seguinte ou Ã¡ anterior.
+
+<p>Abaixo aparece o texto da secciÃ³n en curso. Ã³ final da lectura, pÃ³dense
+empregar as frechas que estÃ¡n na parte inferior para pasar Ã¡ secciÃ³n seguinte ou
+Ã¡ anterior.
+
+<p>Debaixo do tÃ­tulo e autor hai tres botÃ³ns. Prema <i>texto completo</i> para
+ver todo o texto do documento en curso. Â¡Se o documento Ã© grande, pode levar
+moito tempo e facer uso de moita memoria! Prema <i>separar</i> para crear unha
+nova ventÃ¡ no seu navegador para este documento (esto Ã© Ãºtil se desexa comparar
+documentos ou ler dous Ã¡ vez.) Por Ãºltimo, cando se fai unha busca, as palabras
+buscadas aparecen resaltadas. Prema <i>sen resaltar</i> para eliminar esto.
+}
+
+
+# help about the icons
+_texthelpexpandtext_ [l=gl] {Abrir ou non o texto completo}
+_texthelpdetachpage_ [l=gl] {Abrir esta pÃ¡xina nunha nova ventÃ¡}
+_texthelphighlight_ [l=gl] {Resaltar ou non os termos buscados}
+
+_texthelpsearchingtitle_ [l=gl] {Â¿CÃ³mo buscar determinadas palabras?}
+
+_texthelpsearching_ [l=gl] {
+<p>Desde a pÃ¡xina de busca, pÃ³dese facer unha consulta seguindo
+estes pasos:
+
+<ol>
+
+<li>Especificar quÃ© documentos quere buscar
+
+<li>Indicar se quere buscar todas as palabras o sÃ³ algunhas
+
+<li>Escribir as palabras que quere buscar
+
+<li>Pulsar o botÃ³n <i>Iniciar a busca</i>
+
+</ol>
+
+<p> Cando se fai unha consulta, aparecen os tÃ­tulos dos vinte primeiros
+documentos correspondentes. Ã³ final da lista hai un botÃ³n que permite acceder Ã³s
+vinte seguintes, e asÃ­ sucesivamente. Prema o tÃ­tulo de calquer documento ou no
+botonciÃ±o que aparece Ã³ lado.
+
+<p>O nÃºmero mÃ¡ximo de documentos obtidos Ã© 100. Pode cambiar este nÃºmero
+pulsando o botÃ³n <i>preferencias</i> na parte superior da pÃ¡xina.
+}
+
+_texthelpquerytermstitle_ [l=gl] {Termos da busca}
+_texthelpqueryterms_ [l=gl] {
+<p> O que se dixita no cadro de consulta interprÃ©tase como unha lista de
+palabras chamadas "termos da busca". Cada termo debe conter somente letras e
+dÃ­xitos. Os termos sepÃ¡ranse por un espacio en branco. Se aparecen outros
+caracteres, coma os de puntuaciÃ³n, interprÃ©tanse como espacios e a busca non os
+ten en conta. Non se poden efectuar buscas con palabras que inclÃºan puntuaciÃ³n.
+
+
+<p>Por exemplo, a consulta:<p>
+
+<ul><kbd>Agro-forestry in the Pacific Islands: Systems for
+Sustainability (1993)</kbd></ul>
+
+<p>tratarÃ¡se de igual xeito que:<p>
+
+<ul><kbd>Agro forestry in the Pacific Islands Systems for Sustainability
+1993</kbd></ul><p>
+}
+
+_texthelpquerytypetitle_ [l=gl] {Tipo de consulta}
+_texthelpquerytype_ [l=gl] {
+<p>Existen dous tipos de consulta.
+
+<ul>
+
+<li>busca de <b>todas</b> as palabras. BÃºscanse os documentos que
+conteÃ±en todas as palabras especificadas. Os documentos que respondan
+Ã¡ consulta presÃ©ntanse por orde alfabÃ©tica.
+
+<li>busca de <b>algunha(s)</b> palabra(s). Basta con enumerar os termos que
+poden aparecer nos documentos buscados. os documentos aparecerÃ¡n nunha orde que
+corresponde Ã³ seu grao de pertinencia con respecto Ã¡ consulta. Para determinar o
+grao de pertinencia aplÃ­canse os criterios seguintes:
+
+<ul>
+
+<li>cantos mÃ¡is termos buscados conteÃ±a o documento, maior serÃ¡ a sÃºa
+pertinencia;
+
+<li>os termos pouco usuais consideraranse mÃ¡is importantes cÃ³s
+comÃºns;
+
+<li>os documentos mÃ¡is curtos consideraranse mÃ¡is pertinentes cÃ³s
+documentos mÃ¡is voluminosos.
+
+</ul>
+
+</ul>
+
+<p>Pode utilizar tantos termos de busca como desexe: unha oraciÃ³n
+completa, ou incluso un parÃ¡grafo enteiro.  Se sÃ³ se especifica un
+termo, os documentos ordenaranse por frecuencia de apariciÃ³n do
+termo buscado.
+
+<p>
+
+}
+
+_textdatesearch_ [l=gl] {Buscar con datas}
+
+_texthelpdatesearch_ [l=gl] {
+<p>A busca por data permite atopar documentos que, ademais de corresponder Ã³s
+criterios de busca, fan referencia a acontecementos situados nun intervalo de
+tempo determinado. PÃ³dense buscar documentos relativos a un ano en particular ou
+comprendidos nun intervalo particular de anos. ObsÃ©rvese que non Ã© necesario
+proporcionar termos de busca, pÃ³dese buscar unicamente por data. Tampouco Ã©
+preciso indicar datas na busca: se non se indica ningunha data Ã© como se non
+existise a busca por data.
+}
+
+
+_texthelpdatehowtotitle_ [l=gl] { CÃ³mo utilizar esta funciÃ³n:}
+_texthelpdatehowto_ [l=gl] {
+<ul>
+
+<li>Para buscar documentos referentes a un ano en particular:
+
+<ul>
+
+<li>Teclear os termos da busca coma sempre.
+
+<li>Indicar o ano desexado no  cadro "Data inicial (ou Ãºnica)".
+
+<li> Se a data Ã© anterior Ã¡ nosa era (antes de Cristo), hai que
+escoller a opciÃ³n "
+antes da nosa era" no menÃº situado cerca dese cadro.
+
+<li>Iniciar a busca coma sempre.
+
+</ul>
+
+<li>Para buscar documentos referentes a un perÃ­odo ou a un intervalo de
+anos:
+
+<ul>
+
+<li>Teclear os termos da busca coma sempre.
+
+<li>Indicar o ano inicial no cadro "Data inicial (ou Ãºnica)".
+
+<li>Indicar o ano final no cadro "Data final".
+
+<li>Seleccionar a opciÃ³n "antes da nosa era" no menÃº situado
+cerca do cadro onde se teclea a data anterior Ã¡ nosa era (antes
+de Cristo).
+
+<li>Iniciar a busca como sempre.
+
+</ul>
+
+</ul>
+}
+
+_texthelpdateresultstitle_ [l=gl] {Como interpretar os resultados das buscas}
+_texthelpdateresults_ [l=gl] {
+<p> Xeralmente, unha  busca de documentos referentes Ã³ ano 1903 non permitirÃ¡
+obter documentos que, por exemplo, tratan de libros escritos no 1903, senÃ³n sÃ³
+documentos referentes Ã³ ano 1903. Sen embargo, dado o xeito no que se buscan as
+datas dos documentos, obteranse documentos referentes a un intervalo de anos (por
+exemplo 1899-1911) que  comprende o ano 1903 (por exemplo o sÃ©culo XX, ou o
+sÃ©culo vinte). Esto significa que, para algÃºns documentos, as datas indicadas na
+busca non aparecerÃ¡n realmente no texto do documento. Para unha busca por
+intervalo de tempo, todo o anterior aplÃ­case a todas as datas do intervalo.
+
+}
+
+_textchangeprefs_ [l=gl] {Cambio de preferencias}
+
+_texthelppreferences_ [l=gl] {
+
+<p> Se desexa cambiar algunhas caracterÃ­sticas da interface para adaptala Ã¡s sÃºas
+propias necesidades, prema o botÃ³n <i>preferencias</i> situado na parte superior
+da pÃ¡xina.
+}
+
+_texthelpcollectionprefstitle_ [l=gl] {Preferencias da colecciÃ³n}
+_texthelpcollectionprefs_ [l=gl] {
+<p>
+Algunhas colecciÃ³ns compÃ³Ã±ense de varias subcolecciÃ³ns, nas cales se poden
+efectuar operaciÃ³ns de busca de forma individual ou no seu conxunto, coma un
+todo. Se o desexa, pode vostede seleccionar na pÃ¡xina de <i>preferencias</i> quÃ©
+subcolecciÃ³ns incluÃ­r nas sÃºas buscas.
+}
+
+_texthelplanguageprefstitle_ [l=gl] {Preferencias de lingua}
+_texthelplanguageprefs_ [l=gl] {
+<p> Cada colecciÃ³n ten unha lingua de presentaciÃ³n por defecto, pero se o desexa
+pode vostede cambiar de idioma. Pode modificar tamÃ©n o sistema de codificaciÃ³n
+que utiliza Greenstone: o programa Greenstone soe escoller os parÃ¡metros
+por defecto, pero con algÃºns navegadores pÃ³dense conseguir mellores resultados
+grÃ¡ficos cambiando de sistema de codificaciÃ³n. En todas as colecciÃ³ns pÃ³dese
+escoller entre unha interface grÃ¡fica normalizada e unha interface textual. Ã©sta
+resulta especialmente Ãºtil para os usuarios con problemas de vista que utilizan
+tipos de letra grandes ou para a saÃ­da a sintetizadores de voz.
+}
+
+_texthelppresentationprefstitle_ [l=gl] {Preferencias de presentaciÃ³n}
+_texthelppresentationprefs_ [l=gl] {
+<p>SegÃºn a colecciÃ³n, pÃ³dense especificar varias opciÃ³ns que controlan
+a presentaciÃ³n.
+
+<p> As colecciÃ³ns de pÃ¡xinas Web permiten eliminar a barra de navegaciÃ³n de
+Greenstone que aparece na parte superior de cada pÃ¡xina dun documento, de tal
+modo que unha vez terminada a busca visualÃ­zase directamente a pÃ¡xina
+correspondente sen os encabezados de Greenstone. Para efectuar outra busca terÃ¡
+que utilizar o botÃ³n "AtrÃ¡s" do seu navegador. Estas colecciÃ³ns permÃ­tenlle
+tamÃ©n eliminar a mensaxe de advertencia de Greenstone que aparece cando un
+hipervinculo apunta fora da colecciÃ³n da biblioteca dixital. Nalgunhas
+colecciÃ³ns de pÃ¡xinas Web pÃ³dese determinar tamÃ©n se os enlaces que aparecen na
+pÃ¡xina de "Resultados da busca" remitirÃ¡n directamente Ã³ URL en cuestiÃ³n ou Ã¡
+copia da pÃ¡xina que estÃ¡ na biblioteca dixital.
+}
+
+_texthelpsearchprefstitle_ [l=gl] {Preferencias de busca}
+_texthelpsearchprefs_ [l=gl] {
+Dous pares de botÃ³ns controlan a diferencia entre maiÃºsculas e minÃºsculas e as
+raÃ­ces das buscas que fai. O primeiro conxunto de botÃ³ns controlan se deben
+coincidir maiÃºsculas ou minÃºsculas. O segundo conxunto controla se se ignoran ou
+non as terminaciÃ³ns das palabras na busca.
+
+<p> Por exemplo, se se activan os botÃ³ns <i>ignorar diferencias entre
+maiÃºsculas e minÃºsculas</i> e <i>ignorar terminaciÃ³ns de palabras</i>, a busca:
+
+<p><ul><kbd>African building</kbd></ul>
+
+<p>tratarase do mesmo modo que:
+
+<p><ul><kbd>africa builds</kbd></ul>
+
+<p>porque a letra maiÃºscula de "African" transformarase en minÃºscula e
+os sufixos "n" e "ing" eliminaranse de "African" e "building",
+respectivamente (suprimirase tamÃ©n a "s" de "builds").
+
+<p>PÃ³dese tamÃ©n optar polo modo de busca "avanzado" que permite combinar termos
+utilizando os operadores booleanos AND (&), OR (|), y NOT (!). Esto
+permitiralle efectuar buscas mÃ¡is precisas. PÃ³dese activar o historial de buscas,
+no que aparecen as Ãºltimas buscas efectuadas. Esto facilita a repeticiÃ³n de
+versiÃ³ns levemente modificadas de buscas anteriores.
+
+<p>Por Ãºltimo, pÃ³dese controlar o nÃºmero de acertos obtidos e a sÃºa
+presentaciÃ³n en pantalla.
+
+}
+
+_texttanumbrowseoptions_ [l=gl] {Existen _numbrowseoptions_ maneira(s) de atopar informaciÃ³n
+nesta colecciÃ³n:}
+
+_textsimplehelpheading_ [l=gl] {Â¿CÃ³mo encontrar informaciÃ³n?}
+
+_texthelpscopetitle_ [l=gl] {Campo de acciÃ³n das buscas}
+
+_texthelpscope_ [l=gl] {
+<p>Na maiorÃ­a das colecciÃ³ns pode vostede escoller diferentes Ã­ndices para a
+busca. Por exemplo, pode haber Ã­ndices por autor ou por tÃ­tulo. TamÃ©n pode haber
+Ã­ndices por capÃ­tulo ou por parÃ¡grafo. Normalmente obtense o documento
+correspondente sexa o que for o Ã­ndice utilizado.
+
+<p>Se os documentos son libros, estos abriranse no lugar
+adecuado.
+
+}
Index: /gsdl/stable/macros/galician2.dm
===================================================================
--- /gsdl/stable/macros/galician2.dm	(revision 20131)
+++ /gsdl/stable/macros/galician2.dm	(revision 20131)
@@ -0,0 +1,1138 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# English Language text and icon macros
+# -- this file contains english text that is of less importance
+# -- to translate when creating a new interface language
+#
+#   TraducciÃ³n Ã³ galego feita for XaquÃ­n Lores xaquin@udc.es
+#
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=gl] {documentos. }
+_lastupdate_ [l=gl] {Ãºltima actualizaciÃ³n }
+_ago_ [l=gl] {dÃ­as.}
+_colnotbuilt_ [l=gl] {ColecciÃ³n non creada.}
+
+_textpoem_ [l=gl] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>que a paz e a tranquilidade te rodeen,
+<br>que vivas no calor dunha calixe estival,
+<br>que o ocÃ©ano das tÃºas viaxes sexa liso como a pedra verde pulida.
+
+}
+
+_textgreenstone_ [l=gl] {<p>Greenstone (pedra verde) Ã© unha pedra semipreciosa que, como este programa
+provÃ©n de Nova Celandia. Na sociedade maorÃ­ tradicional era a materia mÃ¡is
+prezada e buscada. Este pedra ten o poder de absorber e encerrar o <i>wairua</i>
+que Ã© o espÃ­rito da forza da vida e estÃ¡ dotada de virtudes tradicionais que
+fan dela un emblema moi axeitado para un proxecto de biblioteca dixital de
+dominio pÃºblico. o seu lustre simboliza a caridade; a sÃºa transparencia, a
+honradez; a sÃºa dureza, o coraxe e o gume que pode coller, a xustiza.
+O obxecto tallado utilizado como emblema do programa Greenstone Ã© un <i>patu</i>,
+unha maza de combate. Esta arma de combate Ã© unha reliquia da familia dun dos
+membros do noso proxecto. No combate corpo a corpo, o seu lanzamento Ã©
+moi rÃ¡pido, preciso e definitivo. GÃºstanos pensar que esas calidades tamÃ©n se
+aplican Ã³ noso programa e que o afiado gume do <i>patu</i> simboliza a punta de
+lanza da tecnoloxÃ­a
+
+}
+
+_textaboutgreenstone_ [l=gl] {<p>Greenstone Ã© un conxunto de programas informÃ¡ticos destinado Ã¡ creaciÃ³n e
+difusiÃ³n de colecciÃ³ns documentais electrÃ³nicas que fornece unha nova forma de
+organizar a informaciÃ³n e publicala en Internet ou en CD-ROM. Greenstone Ã©
+producido polo <b> Proxecto de Biblioteca Dixital de Nova Celandia</b> da <b>
+Universidade de Waikato</b>, este producto distribÃºese en colaboraciÃ³n coa <b>
+UNESCO</b> e a <b>ONG Human Info</b>. Ã© un programa de cÃ³digo fonte aberto, que
+pode descarregarse no enderezo <a href="http://greenstone.org">http://greenstone.
+org</a> segundo as condiciÃ³ns estipuladas na Licencia PÃºblica Xeral de GNU.
+
+<p>A finalidade deste programa Ã© que os usuarios, en particular nas universidades,
+bibliotecas e outros establecementos pÃºblicos, poidan crear as sÃºas propias
+bibliotecas dixitais. As bibliotecas dixitais estÃ¡n transformando radicalmente
+o mÃ©todo de distribuciÃ³n e adquisiciÃ³n de coÃ±ecementos utilizado pola UNESCO
+cos seus interlocutores nas esferas da educaciÃ³n, a ciencia, e a cultura  en
+todo o mundo, a particularmente nos paÃ­ses en desenvolvemento. Agardamos que
+este programa contribÃºa a fomentar a creaciÃ³n e difusiÃ³n de bibliotecas
+dixitais co fin de compartir a informaciÃ³n e poÃ±ela a disposiciÃ³n do pÃºblico en
+xeral.
+
+<p>Este programa elabÃ³rase e distribÃºese gracias Ã³ esforzo de colaboraciÃ³n
+internacional iniciado en Agosto de 2000 por tres participantes:
+
+<table border="0">
+<tr valign="top">
+<td>
+O proxecto <a href="http://nzdl.org"><b>Biblioteca Dixital de
+Nova Celandia na Universidade de Waikato</b></a>
+<br>
+
+O programa Greenstone naceu deste proxecto e a iniciativa recibiu o respaldo da
+SubcomisiÃ³n de ComunicaciÃ³n da ComisiÃ³n Nacional Neocelandesa para a UNESCO,
+como parte da contribuciÃ³n de Nova Celandia Ã³ programa da UNESCO.
+</td>
+<td></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://www.unesco.org"><b>OrganizaciÃ³n das NaciÃ³ns Unidas
+para a ComunicaciÃ³n, a Ciencia e a Cultura</b></a>
+<br>
+
+A difusiÃ³n mundial de informaciÃ³n en materia de educaciÃ³n, ciencia e cultura, en
+particular nos paÃ­ses en desenvolvemento, Ã© un dos cometidos principais  do
+programa intergubernamental da UNESCO "InformaciÃ³n para todos". Por outra parte,
+considÃ©rase que unha tecnoloxÃ­a da informaciÃ³n e a comunicaciÃ³n apropiada e
+accesible constitÃºe un instrumento esencial a este proxecto.
+
+</td>
+<td><a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+border="0"></a></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://humaninfo.org"><b>A ONG Human Info, con sede en Amberes,
+BÃ©lxica</b></a>
+<br>
+
+Este proxecto, que traballa con Axencias de NaciÃ³ns Unidas e outras ONG, fÃ­xose
+unha reputaciÃ³n a nivel mundial na dixitalizaciÃ³n de documentos relativos o
+desenvolvemento humano, e a sÃºa difusiÃ³n, gratuÃ­ta nos paises en desenvolvemento
+e a prezo de custo nos demais paÃ­ses.
+
+</td>
+<td><a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" border="0"></a></td>
+</tr>
+</table>
+
+}
+
+_textdescrselcol_ [l=gl] {seleccionar unha colecciÃ³n}
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=gl] {Hai outros catro botÃ³ns na pÃ¡xina principal }
+
+_textnocollections_ [l=gl] {<p>Non hai actualmente ningunha colecciÃ³n dispoÃ±ible para esta instalaciÃ³n de
+Greenstone. Para engadir colecciÃ³ns, vostede pode:
+
+<ul>
+
+<li>utilizar o Coleccionista para crear novas colecciÃ³ns
+
+<li>ou ben instalar colecciÃ³ns a partir do CD-ROM de Greenstone, se dispÃ³n dun
+
+</ul>
+
+}
+
+_text1coll_ [l=gl] {Esta instalaciÃ³n de Greenstone contÃ©n 1 colecciÃ³n }
+
+_textmorecolls_ [l=gl] {Esta instalaciÃ³n de Greenstone contÃ©n _1_ colecciÃ³ns }
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=gl] {Enlace externo }
+_textlinknotfound_ [l=gl] {Non se atopou o enlace interno }
+
+_textextlinkcontent_ [l=gl] {O enlace que vostede seleccionou Ã© externo a todas as colecciÃ³ns actualmente
+seleccionadas. Se desexa de todos os xeitos activas este enlace e se o seu
+navegador estÃ¡ conectado a internet, pode vostede  <a
+href="_nexturl_">acceder</a> a esta pÃ¡xina; en caso contrario, prema o botÃ³n "
+AtrÃ¡s" do seu navegador para volver Ã³ documento anterior.
+
+}
+
+_textlinknotfoundcontent_ [l=gl] {O enlace interno que vostede seleccionou non existe. Esto dÃ©bese probablemente a
+un erro na colecciÃ³n fonte. Prema o botÃ³n "AtrÃ¡s" do seu navegador para volver Ã³
+documento anterior.
+
+}
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=gl] {<h3>Enlace coa colecciÃ³n "_2_"</h3>
+
+<p>O enlace que vostede seleccionou Ã© externo Ã¡ colecciÃ³n "_collectionname_" (
+remite Ã¡ colecciÃ³n "_2_"). Se desexa ver o documento que corresponde a este
+enlace na colecciÃ³n "_2_",pode <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">
+acceder</a> a esa pÃ¡xina; en caso contrario, prema o botÃ³n "AtrÃ¡s" do seu
+navegador para volver Ã³ documento anterior.
+
+}
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=gl] {Biblioteca Dixital Greenstone }
+
+_textusername_ [l=gl] {nome de usuario}
+_textpassword_ [l=gl] {contrasinal}
+
+_textmustbelongtogroup_ [l=gl] {AdvÃ­rtese que para acceder a esta pÃ¡xina vostede debe pertenecer Ã³ grupo "_cgiargug_"}
+
+_textmessageinvalid_ [l=gl] {Para acceder Ã¡ pÃ¡xina que vostede solicitou Ã© necesario conectarse.<br>
+_If_(_cgiargug_, [_textmustbelongtogroup_]<br>) Teclee por favor o seu nome de usuario de
+Greenstone e o seu contrasinal.
+
+}
+
+_textmessagefailed_ [l=gl] {Erro no nome de usuario ou no contrasinal}
+
+_textmessagedisabled_ [l=gl] {SentÃ­molo, pero a sÃºa conta foi invalidada. Por favor contacte co administrador
+deste sitio.
+
+}
+
+_textmessagepermissiondenied_ [l=gl] {SentÃ­molo, pero vostede non ten permiso para acceder a esta pÃ¡xina.
+
+}
+
+_textmessagestalekey_ [l=gl] {O enlace que vostede seleccionou xa non Ã© vÃ¡lido. Teclee por favor o seu
+contrasinal para ter acceso a esta pÃ¡xina.
+
+}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=gl] {<p<Esta instalaciÃ³n de Greenstone non inclÃºe ningunha documentaciÃ³n. Esto pode
+ser porque:
+
+<ol>
+
+<li>Greenstone instalouse a partir dun CD-ROM nunha versiÃ³n compacta.
+
+<li>Greenstone instalouse a partir dunha distribuciÃ³n descargada de Internet.
+
+</ol>
+
+<p>En ambos casos pode vostede obter a documentaciÃ³n no directorio<i>docs</i>
+dun CD-ROM de Greenstone ou visitando <a href="http://www.greenstone.org">
+http://www.greenstone.org</a>.
+
+}
+
+_textuserguide_ [l=gl] {GuÃ­a do usuario }
+_textinstallerguide_ [l=gl] {GuÃ­a de instalaciÃ³n }
+_textdeveloperguide_ [l=gl] {GuÃ­a do programador }
+_textpaperguide_ [l=gl] {Do papel Ã¡ colecciÃ³n }
+# -- Missing translation: _textorganizerguide_
+
+_textgsdocstitle_ [l=gl] {documentaciÃ³n de greenstone}
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=gl] {Estructura por defecto}
+_textmore_ [l=gl] {mÃ¡is}
+_textinfo_ [l=gl] {InformaciÃ³ns sobre a colecciÃ³n}
+_textsrce_ [l=gl] {Datos fonte}
+_textconf_ [l=gl] {Configurar a colecciÃ³n}
+_textbild_ [l=gl] {Crear a colecciÃ³n}
+_textview_ [l=gl] {Visualizar a colecciÃ³n}
+_textdel_ [l=gl] {Suprimir a colecciÃ³n}
+_textexpt_ [l=gl] {Exportar a colecciÃ³n}
+
+# -- Missing translation: _textdownloadingfiles_
+# -- Missing translation: _textimportingcollection_
+# -- Missing translation: _textbuildingcollection_
+# -- Missing translation: _textcreatingcollection_
+
+_textcollectorblurb_ [l=gl] {<i>Â¡A pluma Ã© mÃ¡is poderosa que a espada!
+
+<br>
+Crear e distribuÃ­r colecciÃ³ns de informaciÃ³n, implica responsabilidades nas que
+poida que vostede queira reflexionar antes de seguir adiante.
+Hai cuestiÃ³ns xurÃ­dicas sobre o dereito de autor: ter acceso a documentos non
+quere dicir que se poida comunicalos a terceiros. Hai tamÃ©n cuestiÃ³ns sociais:
+no manexo dos documentos dÃ©bense respectar os usos e costumes da comunidade da
+que proceden os documentos. E hai tamÃ©n cuestiÃ³ns Ã©ticas: algÃºns documentos non
+se deben poÃ±er a disposiciÃ³n de ninguÃ©n.
+
+<br>Sexa consciente do poder da informaciÃ³n e utilÃ­ceo con prudencia.
+
+</i>
+
+}
+
+_textcb1_ [l=gl] {O Coleccionista axÃºdalle a crear novas colecciÃ³ns e a modificar, engadir ou
+suprimir colecciÃ³ns existentes. Para facelo, serÃ¡ guiado por unha secuencia de
+pÃ¡xinas Web na que se lle pedirÃ¡ a informaciÃ³n necesaria.
+
+}
+
+_textcb2_ [l=gl] {Primeiro, debe decidir se}
+_textcnc_ [l=gl] {Crear unha nova colecciÃ³n }
+_textwec_ [l=gl] {Traballar cunha colecciÃ³n existente, engadÃ­ndolle datos o
+suprimindoa }
+
+_textcb3_ [l=gl] {Para crear ou modificar colecciÃ³ns Ã© necesario rexistrarse. Esto permite evitar
+que outras persoas entren no seu ordenador e alteren a informaciÃ³n. Nota: por
+razÃ³ns de seguridade terÃ¡ que conectarse de novo cada media hora. Se esto sucede,
+ Â¡Non se preocupe! -convidarÃ¡selle a abrir unha nova sesiÃ³n e poderÃ¡ vostede
+ continuar a partires de onde estaba no momento da desconexiÃ³n.
+
+}
+
+_textcb4_ [l=gl] {Dixite o seu nome de usuario de Greenstone e o seu contrasinal, e prema o botÃ³n
+para conectarse.
+
+}
+
+_textfsc_ [l=gl] {Primeiro seleccione a colecciÃ³n coa cal desexa vostede traballar (as colecciÃ³ns
+protexidas contra escritura non aparecerÃ¡n nesta lista).
+
+}
+
+_textwtc_ [l=gl] {coa colecciÃ³n seleccionada, vostede pode
+
+}
+_textamd_ [l=gl] {Engadir mÃ¡is datos e recrear a colecciÃ³n
+
+}
+_textetc_ [l=gl] {Modificar o ficheiro de configuraciÃ³n da colecciÃ³n e recrear a colecciÃ³n
+
+}
+_textdtc_ [l=gl] {Suprimir a colecciÃ³n definitivamente
+
+}
+_textetcfcd_ [l=gl] {Exportar a colecciÃ³n para gravala nun CD-ROM que se instala automaticamente en
+Windows
+
+}
+_textcaec_ [l=gl] {Cambiar unha colecciÃ³n existente
+
+}
+_textnwec_ [l=gl] {Non estÃ¡ dispoÃ±ible para a sÃºa modificaciÃ³n ningunha colecciÃ³n que permita a
+escritura
+
+}
+_textcianc_ [l=gl] {Crear unha nova colecciÃ³n
+
+}
+_texttsosn_ [l=gl] {A secuencia das fases necesarias para crear unha nova colecciÃ³n de biblioteca
+dixital Ã© a seguinte:
+
+}
+_textsin_ [l=gl] {Especificar o seu nome (e outras informaciÃ³ns asociadas)
+
+}
+_textswts_ [l=gl] {Especificar de onde proveÃ±en os datos fonte
+
+}
+_textatco_ [l=gl] {Axustar as opciÃ³ns de configuraciÃ³n (sÃ³ para usuarios experimentados)
+
+}
+_textbtc_ [l=gl] {"Crear" a colecciÃ³n (vÃ©xase mÃ¡is abaixo)
+
+}
+_textpvyh_ [l=gl] {Â¡Admire a sÃºa obra!
+
+}
+
+_texttfsiw_ [l=gl] {A cuarta fase Ã© cando o ordenador fai todo o traballo. No proceso de "creaciÃ³n"
+o ordenador elabora todos os Ã­ndices e recompila todas as informaciÃ³ns necesarias
+para o bo funcionamento da biblioteca dixital. Pero primeiro ten vostede que
+especificar as informaciÃ³ns.
+
+}
+
+_textadab_ [l=gl] {Abaixo aparece un diagrama que lle axudarÃ¡ a controlar onde estÃ¡. O botÃ³n verde
+Ã© o que vostede pulsarÃ¡ para continuar a secuencia. Despois de cada paso na
+secuencia, os botÃ³ns cambiarÃ¡n Ã³ amarelo. PÃ³dese volver a unha pÃ¡xina anterior
+premendo o botÃ³n amarelo correspondente no diagrama.
+
+}
+
+_textwyar_ [l=gl] {Cando estea listo, prema o botÃ³n verde "informaciÃ³ns sobre a colecciÃ³n" para
+comezar a crear a sÃºa nova colecciÃ³n.
+
+}
+
+_textcnmbs_ [l=gl] {DÃ©bese especificar o nome da colecciÃ³n}
+_texteambs_ [l=gl] {DÃ©bese especificar o enderezo de correo electrÃ³nico}
+_textpsea_ [l=gl] {Comprobe que o enderezo de correo electrÃ³nico corresponde Ã³ formato usuario@dominio}
+_textdocmbs_ [l=gl] {DÃ©bese especificar a descriciÃ³n da colecciÃ³n}
+
+_textwcanc_ [l=gl] {Ã³ crear unha nova colecciÃ³n, Ã© necesario incorporar algunhas informaciÃ³ns
+preliminares sobre os datos fonte. Este proceso estructÃºrase en forma dunha
+serie de pÃ¡xinas Web, supervisadas polo Coleccionista. A barra na parte inferior
+da pÃ¡xina mostra a secuencia de pÃ¡xinas que quedan.
+
+}
+
+_texttfc_ [l=gl] {TÃ­tulo da colecciÃ³n:
+
+}
+
+_texttctiasp_ [l=gl] {O tÃ­tulo da colecciÃ³n Ã© unha frase corta que se utiliza na biblioteca dixital
+para identificar o contido da colecciÃ³n.
+Por exemplo:  "Informes tÃ©cnicos de informÃ¡tica" ou "Humanity Development Library".
+
+}
+
+_textcea_ [l=gl] {Enderezo de correo electrÃ³nico de contacto:
+
+}
+
+_textteas_ [l=gl] {Este enderezo electrÃ³nico constitÃºe o primeiro punto de contacto para a
+colecciÃ³n. Se o programa Greenstone detecta un problema, enviase un informe de
+diagnostico a ese enderezo. Teclee un enderezo electrÃ³nico na sÃºa forma completa:
+<tt>nome@dominio</tt>.
+
+}
+
+_textatc_ [l=gl] {Acerca desta colecciÃ³n:
+
+}
+
+_texttiasd_ [l=gl] {Esta Ã© unha declaraciÃ³n na que se enuncian os principios que definen que elementos
+que son incluÃ­dos nesta colecciÃ³n. AparecerÃ¡ na primeira pÃ¡xina de presentaciÃ³n
+da colecciÃ³n.
+
+}
+
+_textypits_ [l=gl] {A sÃºa posiciÃ³n na secuencia indÃ­case cunha frecha por debaixo--neste caso, a
+etapa das "informaciÃ³ns de colecciÃ³n". Para continuar, prema o botÃ³n verde "
+datos fonte".
+
+}
+
+_srcebadsources_ [l=gl] {<p> Un ou mÃ¡is dos ficheiros fonte que vostede especificou non estÃ¡ dispoÃ±ible (
+marcados _iconcross_ abaixo).
+
+<p>Esto pode ser porque:
+
+<ul>
+
+<li>Non existe o ficheiro, o sitio FTP ou o URL.
+
+<li>Hai que conectarse primeiro a Internet.
+
+<li>Vostede estÃ¡ intentando acceder a un URL que estÃ¡ detrÃ¡s dun cortalume (esto
+ocorre normalmente cando vostede ten que proporcionar un nome de usuario e un
+contrasinal para acceder a Internet).
+
+</ul>
+
+<p>Se este Ã© un URL que vostede pode ver no seu navegador, o problema pode vir
+dunha copia que se atopa na memoria cache local. Desafortunadamente, estas
+copias son invisibles para o noso proceso de copiado. Neste caso recomendamos
+que descargue as pÃ¡xinas mediante o seu navegador.
+
+}
+
+_textymbyco_ [l=gl] {Vostede pode basear a sÃºa colecciÃ³n en:
+
+<ul>
+
+<li>A estructura por defecto
+
+</ul>
+
+<dl><dd> A nova colecciÃ³n pode conter documentos HTML (.htm,.html), documentos
+de texto (.txt,.text), documentos MS-Word (.doc), documentos PDF (.pdf), ou
+documentos de correo electrÃ³nico no formato "m-box" (.mbx).</dd></dl>
+
+<li>Unha colecciÃ³n existente
+
+<dl><dd>Os ficheiros da sÃºa nova colecciÃ³n deben ser exactamente do mesmo tipo
+que os utilizados para crear a colecciÃ³n existente. </dd></dl>
+
+</ul>
+
+}
+
+_textbtco_ [l=gl] {Basear a colecciÃ³n en:}
+_textand_ [l=gl] {Engadir novos datos}
+_textad_ [l=gl] {Engadir datos:}
+
+_texttftysb_ [l=gl] {os ficheiros que vostede especifique mais abaixo engadiranse Ã¡ colecciÃ³n.
+AsegÃºrese de non volver a especificar ficheiros que xa estÃ¡n na colecciÃ³n, pois
+de facelo haberÃ¡ dÃºas copias. Os ficheiros especifÃ­canse indicando o seu nome
+completo e o directorio no que estÃ¡n almacenados, as pÃ¡xinas Web identifÃ­canse
+polo seu enderezo Internet absoluto.
+
+}
+
+_textis_ [l=gl] {Datos de entrada: }
+
+_textddd1_ [l=gl] {<p>Se vostede utiliza file:// ou ftp:// para especificar un ficheiro, este
+descargarase.
+
+<p>Se vostede utiliza http://, o resultado dependerÃ¡ do URL e serÃ¡ diferente
+se
+este abre no seu navegador unha pÃ¡xina WEb ou unha lista de ficheiros. Se se
+trata dunha pÃ¡xina, descargarase estÃ¡, e tamÃ©n todas as pÃ¡xinas coas que este
+vinculada mediante enlaces, sempre que pertenzan Ã³ mesmo sitio inicial.
+
+<p>Se vostede utiliza file:// ou ftp:// para especificar un directorio, ou se
+indica un URL http:// que conduce a unha lista de ficheiros, todos os ficheiros
+que se encontren nesa carpeta e nas sÃºas subcarpetas serÃ¡n incluÃ­
+dos na colecciÃ³n.
+
+<p>Prema o botÃ³n "mais datos" para obter mais cadros de introducciÃ³n de datos.
+
+}
+
+_textddd2_ [l=gl] {<p>Prema un dos botÃ³ns verdes. Se Ã© vostede un usuario experimentado, pode
+desexar axustar a configuraciÃ³n da colecciÃ³n. outra posibilidade Ã© ir
+directamente Ã¡ etapa de creaciÃ³n. Lembre, pode volver Ã¡ etapa anterior premendo
+o botÃ³n amarelo correspondente.
+
+}
+
+_textconf1_ [l=gl] {<p>A creaciÃ³n e a presentaciÃ³n da sÃºa colecciÃ³n son controladas por
+especificaciÃ³ns nun "ficheiro de configuraciÃ³n" especial. Os usuarios
+experimentados que o desexen poden modificar os parÃ¡metros da configuraciÃ³n.
+
+<center><p><b>Se vostede non Ã© un usuario experimentado, vaia Ã¡ parte inferior
+da pÃ¡xina.</b></center>
+
+<p>Para modificar os parÃ¡metros de configuraciÃ³n, corrixa os datos que aparecen
+mais abaixo. Se se equivoca, prema o botÃ³n "Reiniciar" para restablecer os
+parÃ¡metros orixinais de configuraciÃ³n.
+
+}
+
+_textreset_ [l=gl] {Reiniciar}
+
+_textbild1_ [l=gl] {A colecciÃ³n estase creando: esta operaciÃ³n pode ser longa. A liÃ±a de estado que
+aparece mais abaixo indica como estÃ¡ progresando a operaciÃ³n.
+}
+
+_textbild2_ [l=gl] {Para interromper o proceso de creaciÃ³n en calquera momento, prema aquÃ­. <br> A
+colecciÃ³n coa que estÃ¡ traballando quedarÃ¡ intacta.
+
+}
+
+_textstopbuild_ [l=gl] {Interromper a creaciÃ³n }
+
+_textbild3_ [l=gl] {Se vostede sae desta pÃ¡xina (e non cancelou o proceso de creaciÃ³n co botÃ³n "
+interromper a creaciÃ³n"), a colecciÃ³n continuarÃ¡ creÃ¡ndose e instalarase cando o
+proceso teÃ±a rematado.
+
+}
+
+_textbuildcancelled_ [l=gl] {CreaciÃ³n cancelada
+
+}
+
+_textbildcancel1_ [l=gl] {Cancelouse o proceso de creaciÃ³n da colecciÃ³n. Utilice os botÃ³ns amarelos para
+efectuar cambios na sÃºa colecciÃ³n ou para reiniciar o proceso de creaciÃ³n.
+
+}
+
+_textbsupdate1_ [l=gl] {ActualizaciÃ³n do estado da creaciÃ³n dentro de 1 segundo}
+_textbsupdate2_ [l=gl] {ActualizaciÃ³n do estado da creaciÃ³n dentro de}
+_textseconds_ [l=gl] {segundos}
+_textbildsuc_ [l=gl] {ColecciÃ³n creada satisfactoriamente.}
+
+_textviewbildsummary_ [l=gl] {Para obter mais detalles, vostede pode  <a
+href="_httppagex_(bsummary)&c=_cgiargbc1dirname_" target=_top>visualizar o
+resume da creaciÃ³n </a> desta colecciÃ³n.
+
+}
+
+_textfailmsg11_ [l=gl] {A colecciÃ³n non se puido crear porque non conten ningÃºn dato. Comprobe que existe
+polo menos un dos directorios ou ficheiros que vostede especificou na pÃ¡xina <i>
+datos fonte</i> e de que Ã© dun tipo ou, no caso de directorios, de que contÃ©n
+ficheiros dun tipo que Greenstone pode procesar.
+
+}
+
+_textfailmsg21_ [l=gl] {Non se puido crear a colecciÃ³n (fallou o script import.pl).
+
+}
+_textblcont_ [l=gl] {O rexistro de creaciÃ³n contÃ©n as informaciÃ³ns seguintes:
+}
+
+_texttryagain_ [l=gl] {Por favor <a href="_httppagecollector_" target=_top>volva a arrancar o
+Coleccionista</a> e intenteo de novo.
+}
+
+_textfailmsg31_ [l=gl] {Non se puido crear a colecciÃ³n (fallou o script buildcol.pl).
+
+}
+_textfailmsg41_ [l=gl] {Creouse a colecciÃ³n pero non se puido instalar.
+
+}
+_textfailmsg71_ [l=gl] {Produciuse un erro inesperado cando se intentaba crear a colecciÃ³n
+
+}
+_textretcoll_ [l=gl] {Volver Ã³ Coleccionista
+
+}
+
+_textdelperm_ [l=gl] {<p>Non se puido suprimir parte da colecciÃ³n  _cgiargbc1dirname_ ou toda ela. As
+causas posibles son:
+
+<ul>
+
+<li>Greenstone non ten permiso para suprimir o directorio _gsdlhome_/collect/_cgiargbc1dirname_. <
+br> Para suprimir definitivamente a colecciÃ³n _cgiargbc1dirname_ neste ordenador,
+ pode ser necesario suprimir manualmente este directorio.
+
+</ul>
+
+}
+
+_textdelinv_ [l=gl] {A colecciÃ³n  _cgiargbc1dirname_ estÃ¡ protexida ou non Ã© vÃ¡lida. A supresiÃ³n
+cancelouse.
+
+}
+
+_textdelsuc_ [l=gl] {suprimiuse a colecciÃ³n _cgiargbc1dirname_.
+
+}
+
+_textclonefail_ [l=gl] {Non se puido clonar a colecciÃ³n  _cgiargbc1dirname_. As causas posibles son:
+
+<ul>
+
+<li>A colecciÃ³n _cgiargclonecol_ non existe
+
+<li>A colecciÃ³n _cgiargclonecol_ non ten ningÃºn ficheiro collect.cfg
+
+<li>Greenstone non ten permiso para ler o ficheiro de configuraciÃ³n
+collect.cfg
+
+</ul>
+
+}
+
+_textcolerr_ [l=gl] {Erro no Coleccionista. }
+
+_texttmpfail_ [l=gl] {O Coleccionista non puido efectuar ningunha operaciÃ³n de lectura ou de escritura
+no ficheiro temporal. As causas posibles son:
+<ul>
+
+<li>Greenstone non ten acceso de lectura/escritura Ã³ directorio _gsdlhome_/tmp.
+
+</ul>
+
+}
+
+_textmkcolfail_ [l=gl] {O Coleccionista non puido crear a estructura de directorios que require a nova
+colecciÃ³n (fallou o script mkcol.pl). As causas posibles son:
+
+<ul>
+
+<li>Greenstone non ten permiso para escribir no directorio _gsdlhome_/tmp.
+
+<li>Erros no guiÃ³n Perl mkcol.pl.
+
+</ul>
+
+}
+
+_textnocontent_ [l=gl] {Erros do Coleccionista: non se proporcionou ningÃºn nome para a nova colecciÃ³n.
+Intente volver a arrancar o Coleccionista.
+
+}
+
+_textrestart_ [l=gl] {Volver a arrancar o Coleccionista
+
+}
+
+_textreloaderror_ [l=gl] {Produciuse un erro cando se creaba a nova colecciÃ³n. Ã© posible que o uso dos
+botÃ³ns "Actualizar" ou "AtrÃ¡s" do seu navegador perturbara a Greenstone (trate
+de evitar o uso deses botÃ³ns durante a creaciÃ³n dunha colecciÃ³n co Coleccionista).
+ RecomÃ©ndase volver a arrincar o Coleccionista.
+
+}
+
+_textexptsuc_ [l=gl] {A colecciÃ³n de _cgiargbc1dirname_ exportouse Ã³ directorio _gsdlhome_/tmp/exported\__cgiargbc1dirname_.
+
+}
+
+_textexptfail_ [l=gl] {<p>Non se puido exportar a colecciÃ³n _cgiargbc1dirname_.
+
+>p>Ã© probable  que esto se deba a que Greenstone instalouse sen os compoÃ±entes
+necesarios para posibilitar a funciÃ³n "Exportar a colecciÃ³n".
+
+<ul>
+
+<li>Se vostede instalou Greenstone a partires dun CD-ROM, estos compoÃ±entes non
+se terÃ¡n instalado a menos que vostede os seleccionara durante unha instalaciÃ³n
+"personalizada". Pode engadilos Ã¡ sÃºa instalaciÃ³n volvendo a efectuar o
+procedemento de instalaciÃ³n.
+
+<li>Se vostede instalou Greenstone a partires dun programa distribuÃ­do por
+Internet, serÃ¡ necesario descargar e instalar un paquete adicional para activar
+esta funciÃ³n. Visite por favor <a href="http://www.greenstone.org">http://www.greenstone.org</a>
+ou envÃ­e un correo electrÃ³nico a  <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>
+para obter mais detalles.
+
+</ul>
+
+}
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=gl] {<P>Greenstone Ã© un conxunto de programas que posibilitan fornecer e construÃ­r
+bibliotecas dixitais. Ofrece un novo xeito de organizar a informaciÃ³n e
+publicala en Internet ou en CD-ROM. Elaborado dentro do proxecto de Biblioteca
+Dixital de Nova Celandia da Universidade de Waikato, este producto distribÃºese en
+colaboraciÃ³n coa UNESCO e a ONG Human Info. Ã© un programa informÃ¡tico de cÃ³digo
+fonte aberto, que pode descargarse no enderezo <a href="http://greenstone.org">http://greenstone.org</a>,
+segundo as condiciÃ³ns estipuladas na Licencia PÃºblica Xeral de GNU.
+
+}
+
+_textgreenstone2_ [l=gl] {O sitio web da Biblioteca Dixital de Nova Celandia (<a href="http://nzdl.org">http://nzdl.org</a>)
+contÃ©n numerosos exemplos de colecciÃ³ns, creados con Greenstone, que se poden
+consultar libremente. Mostran varias opciÃ³ns de busca e navegaciÃ³n, e inclÃºen
+colecciÃ³ns en Ã¡rabe, chinÃ©s, francÃ©s, maorÃ­ e espaÃ±ol, asÃ­ como en inglÃ©s. Hai
+tamÃ©n algunhas colecciÃ³ns de mÃºsica.
+
+}
+
+# -- Missing translation: _textplatformtitle_
+_textgreenstone3_ [l=gl] {Greenstone funciona con Windows e Unix. A distribuciÃ³n inclÃºe binarios listos
+para o seu uso en todas as versiÃ³ns de Windows e Linux. InclÃºe tamÃ©n o cÃ³digo
+fonte completo para o sistema, que se pode compilar usando Microsoft C++ ou GCC.
+Greenstone funciona con outros programas libres que se poden descargar de
+Internet: o servidor web Apache e Perl. A interfaz utiliza un navegador web,
+como Netscape Navigator ou Internet Explorer.
+
+}
+
+_textgreenstone4_ [l=gl] {Moitas colecciÃ³ns de documentos distribÃºense en CD-ROM con Greenstone.Por
+exemplo, o proxecto de <i>Bibliotecas para o Desenvolvemento da Humanidade</i>
+conten 1.230 publicaciÃ³ns con temÃ¡tica moi variada (dende a contabilidade ata a
+depuraciÃ³n de auga). PÃ³dese acceder a esta colecciÃ³n con ordenadores de escas
+potencia, como as que se soen ver en paÃ­ses en desenvolvemento. A informaciÃ³n
+pode obterse mediante buscas ou consultas por tema, por tÃ­tulos de publicaciÃ³ns,
+por organizaciÃ³n, consultando unha lista de "como..." ou visualizando de forma
+aleatoria as portadas dos libros.
+
+}
+
+# -- Missing translation: _textcustomisationtitle_
+_textgreenstone5_ [l=gl] {Greenstone estÃ¡ especialmente concibido para poder ampliarse e personalizarse a
+vontade. Greenstone pode tratar novos formatos de documentos e de metadatos
+escribindo "conectores" (<i>plugins</i>), na linguaxe Perl. TamÃ©n se poden
+implementar novas estructuras de navegaciÃ³n nos metadatos escribindo "
+clasificadores". a interfaz de usuario e a presentaciÃ³n poden modificarse
+utilizando as "macros" escritas nunha linguaxe de macros simple. O protocolo
+CORBA permite que os axentes (por exemplo en linguaxe Java) utilicen todas as
+funciÃ³ns dispoÃ±ibles nas colecciÃ³ns de documentos. Por Ãºltimo, pÃ³dese modificar o
+cÃ³digo fonte en C++ e Perl.
+
+}
+
+# -- Missing translation: _textdocumentationtitle_
+# -- Missing translation: _textdocuments_
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+# -- Missing translation: _textmailinglisttitle_
+_textmailinglist_ [l=gl] {Existe unha lista de correo electrÃ³nico para os debates sobre Greenstone. Ã©
+desexable que os usuarios activos de Greenstone participen nela.
+Para subscribirse, envÃ­e un correo
+electrÃ³nico a <a href="mailto:greenstone-users-request@list.scms.waikato.ac.nz?subject=subscribe">greenstone-users-request@list.scms.waikato.ac.nz?subject=subscribe</a>.
+Para enviar unha mensaxe a lista, utilice o enderezo <a href="mailto:greenstone-users@list.scms.waikato.ac.nz">greenstone-users@list.scms.waikato.ac.nz</a>.
+
+}
+
+# -- Missing translation: _textbugstitle_
+_textreport_ [l=gl] {O noso desexo Ã© garantir o correcto funcionamento deste programa, polo
+que animamos Ã³s seus usuarios a notificar calquera problema que detecten a: <a
+href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>.
+
+}
+
+# -- Missing translation: _textgs3title_
+# -- Missing translation: _textgs3_
+
+# -- Missing translation: _textcreditstitle_
+
+_textwhoswho_ [l=gl] {O programa Greenstone Ã© froito da colaboraciÃ³n de moitas persoas. Rodger McNab e
+Stefan bodie son os principais arquitectos e programadores. Aportaron
+contribuciÃ³ns David Bainbridge, George Buchanan, Hong Chen, Elke Duncker, Carl Gutwin, Geoff Holmes, John
+McPherson, Craig Nevill-Manning, Gordon Paynter, Bernhard Pfahringer,
+Todd Reed, Bill Rogers e Stuart Yeates. Outros membros do proxecto de Biblioteca
+Dixital de Nova Celandia, que contribuÃ­ron co seu asesoramento e as sÃºas
+inspiradas ideas Ã¡ concepciÃ³n do sistema son: Mark Apperley, Sally Jo Cunningham, Steve Jones, Te Taka Keegan, Michel
+Loots, Malika Mahoui e Lloyd Smith. Damos tamÃ©n as gracias a quen contribuÃ­u Ã³s
+paquetes de programas incluÃ­dos nesta distribuciÃ³n: MG, GDBM, PDFTOHTML, WVWARE
+e XLHTML.
+
+}
+
+_textaboutgslong_ [l=gl] {acerca do programa greenstone}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=gl] {Lista dos usuarios actuais}
+_textuser_ [l=gl] {usuario}
+_textas_ [l=gl] {estado da conta}
+_textgroups_ [l=gl] {grupos}
+_textcomment_ [l=gl] {comentario}
+_textadduser_ [l=gl] {engadir un novo usuario }
+_textedituser_ [l=gl] {modificar}
+_textdeleteuser_ [l=gl] {suprimir}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=gl] {Modificar as informaciÃ³ns relativas Ã³s usuarios}
+_textadduser_ [l=gl] {Engadir un novo usuario}
+
+_textaboutusername_ [l=gl] {Os nomes de usuario deben ter entre 2 e 30 caracteres. Poden estar compostos de
+caracteres alfanumÃ©ricos, '.', e '_'.
+}
+
+_textaboutpassword_ [l=gl] {Os contrasinais deben ser de entre 3 e 128 caracteres, e poden comprender todos os
+caracteres ASCII imprimibles.
+}
+
+_textoldpass_ [l=gl] {Se este campo se deixa baleiro, utilizarase o antigo
+contrasinal }
+_textenabled_ [l=gl] {activado }
+_textdisabled_ [l=gl] {desactivado }
+
+_textaboutgroups_ [l=gl] {Os grupos son listas cuxos elementos estÃ¡n separados por comas, non teclee
+espacios despois das comas.}
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=gl] {Suprimir un usuario}
+_textremwarn_ [l=gl] {Â¿Confirma vostede que desexa suprimir definitivamente o usuario <b>_cgiargumun_</b>?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=gl] {Cambiar o contrasinal}
+_textoldpw_ [l=gl] {antigo contrasinal}
+_textnewpw_ [l=gl] {novo contrasinal}
+_textretype_ [l=gl] {volva a teclear o seu novo contrasinal}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=gl] {Rexistrouse o seu novo contrasinal}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=gl] {O nome de usuario non Ã© vÃ¡lido.}
+_textinvalidpassword_ [l=gl] {O contrasinal non Ã© vÃ¡lido.}
+_textemptypassword_ [l=gl] {Teclee un contrasinal inicial para este usuario.}
+_textuserexists_ [l=gl] {Este usuario xa existe, teclee por favor outro
+nome de usuario.}
+
+_textusernameempty_ [l=gl] {Teclee por favor o seu nome de usuario.}
+_textpasswordempty_ [l=gl] {Ten que teclear o seu antigo contrasinal.}
+_textnewpass1empty_ [l=gl] {Teclee o seu novo contrasinal e volva a teclealo.}
+_textnewpassmismatch_ [l=gl] {As dÃºas versiÃ³ns do seu novo contrasinal son distintas.}
+_textnewinvalidpassword_ [l=gl] {O contrasinal Ã© incorrecto.}
+_textfailed_ [l=gl] {Ã© incorrecto o nome de usuario ou o contrasinal.}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=gl] {NÃºmero de versiÃ³n de Greenstone}
+_textframebrowser_ [l=gl] {Para visualizar esto requÃ­rese un navegador que acepte os marcos ("frames").}
+_textusermanage_ [l=gl] {XestiÃ³n dos usuarios}
+_textlistusers_ [l=gl] {lista dos usuarios}
+_textaddusers_ [l=gl] {engadir un novo usuario}
+_textchangepasswd_ [l=gl] {cambiar de contrasinal}
+_textinfo_ [l=gl] {InformaciÃ³ns tÃ©cnicas}
+_textgeneral_ [l=gl] {xeral}
+_textarguments_ [l=gl] {argumentos}
+_textactions_ [l=gl] {acciÃ³ns}
+_textbrowsers_ [l=gl] {navegadores}
+_textprotocols_ [l=gl] {protocolos}
+_textconfigfiles_ [l=gl] {Ficheiros de configuraciÃ³n}
+_textlogs_ [l=gl] {Rexistros}
+_textusagelog_ [l=gl] {rexistro de uso}
+_textinitlog_ [l=gl] {rexistro de inicializaciÃ³n}
+_texterrorlog_ [l=gl] {rexistro de erros}
+_textadminhome_ [l=gl] {pÃ¡xina principal da administraciÃ³n}
+_textreturnhome_ [l=gl] {pÃ¡xina principal de Greenstone}
+_titlewelcome_ [l=gl] {AdministraciÃ³n }
+_textmaas_ [l=gl] {Os servicios de mantemento e de administraciÃ³n son os seguintes:}
+_textvol_ [l=gl] {mostrar os rexistros en liÃ±a}
+_textcmuc_ [l=gl] {crear, manter e actualizar colecciÃ³ns}
+_textati_ [l=gl] {acceder a informaciÃ³ns tÃ©cnicas tales como os argumentos CGI}
+
+_texttsaa_ [l=gl] {PÃ³dese acceder a estes servicios mediante a barra de navegaciÃ³n situada na parte
+esquerda da pÃ¡xina.
+}
+
+_textcolstat_ [l=gl] {Estado da colecciÃ³n}
+
+_textcwoa_ [l=gl] {Unha colecciÃ³n sÃ³ aparecerÃ¡ como "running" (funcionando) se o ficheiro build.cfg
+existe, se Ã© lexible, se conten un campo vÃ¡lido "builddate" (data de creaciÃ³n),
+Ã© dicir > 0, e se estÃ¡ no directorio "index" da colecciÃ³n (Ã© dicir NON no
+directorio "build").
+
+}
+
+_textcafi_ [l=gl] {Prema <i>abbrev.</i> para obter informaciÃ³ns sobre unha colecciÃ³n}
+_textcctv_ [l=gl] {Prema <i>collection</i> para visualizar unha colecciÃ³n}
+_textsubc_ [l=gl] {Someter cambios }
+_texteom_ [l=gl] {Erro de lectura do ficheiro main.cfg}
+_textftum_ [l=gl] {Non se puido actualizar o ficheiro main.cfg }
+_textmus_ [l=gl] {Logrouse actualizar o ficheiro main.cfg }
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=gl] {Resumo da creaciÃ³n da colecciÃ³n _collectionname_
+
+}
+_textflog_ [l=gl] {Erros no rexistro da colecciÃ³n _collectionname_
+
+}
+
+
+############################################################################
+#
+# This stuff is only used by the usability (I'd like to Complain) stuff
+#
+############################################################################
+package Global
+
+# -- Missing translation: _greenstoneusabilitytext_
+
+# -- Missing translation: _textwhy_
+# -- Missing translation: _textextraforform_
+# -- Missing translation: _textprivacybasic_
+# -- Missing translation: _textstillsend_
+
+# -- Missing translation: _texterror_
+# -- Missing translation: _textyes_
+# -- Missing translation: _textno_
+# -- Missing translation: _textclosewindow_
+# -- Missing translation: _textabout_
+# -- Missing translation: _textprivacy_
+# -- Missing translation: _textsend_
+# -- Missing translation: _textdontsend_
+# -- Missing translation: _textoptionally_
+
+# -- Missing translation: _textunderdev_
+
+# -- Missing translation: _textviewdetails_
+# -- Missing translation: _textmoredetails_
+# -- Missing translation: _texttrackreport_
+# -- Missing translation: _textcharacterise_
+# -- Missing translation: _textseverity_
+ 
+# -- Missing translation: _textbadrender_
+# -- Missing translation: _textcontenterror_
+# -- Missing translation: _textstrangebehaviour_
+# -- Missing translation: _textunexpected_
+# -- Missing translation: _textfunctionality_
+# -- Missing translation: _textother_
+
+# -- Missing translation: _textcritical_
+# -- Missing translation: _textmajor_
+# -- Missing translation: _textmedium_
+# -- Missing translation: _textminor_
+# -- Missing translation: _texttrivial_
+
+# -- Missing translation: _textwhatdoing_
+# -- Missing translation: _textwhatexpected_
+# -- Missing translation: _textwhathappened_
+
+# -- Missing translation: _cannotfindcgierror_
+
+# -- Missing translation: _textusabbanner_
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+# -- Missing translation: _textgti_
+
+# -- Missing translation: _textgtierror_
+
+# -- Missing translation: _textgtihome_
+
+# -- Missing translation: _textgtiselecttlc_
+
+# -- Missing translation: _textgtiselecttfk_
+
+# -- Missing translation: _textgticoredm_
+# -- Missing translation: _textgtiauxdm_
+# -- Missing translation: _textgtiglidict_
+# -- Missing translation: _textgtiperlmodules_
+# -- Missing translation: _textgtigreenorg_
+
+# -- Missing translation: _textgtienter_
+
+# -- Missing translation: _textgticorrectexistingtranslations_
+# -- Missing translation: _textgtidownloadtargetfile_
+# -- Missing translation: _textgtiviewtargetfileinaction_
+
+# -- Missing translation: _textgtinumchunksmatchingquery_
+
+# -- Missing translation: _textgtinumchunkstranslated_
+# -- Missing translation: _textgtinumchunksrequiringupdating_
+# -- Missing translation: _textgtinumchunksrequiringtranslation_
+
+# -- Missing translation: _textgtienterquery_
+# -- Missing translation: _textgtifind_
+
+# -- Missing translation: _textgtitranslatingchunk_
+# -- Missing translation: _textgtiupdatingchunk_
+# -- Missing translation: _textgtisubmit_
+
+# -- Missing translation: _textgtilastupdated_
+
+# -- Missing translation: _textgtitranslationfilecomplete_
+
+
+############
+# gli page
+############
+package gli
+
+# -- Missing translation: _textgli_
+# -- Missing translation: _textglilong_
+# -- Missing translation: _textglihelp_
Index: /gsdl/stable/macros/georgian.dm
===================================================================
--- /gsdl/stable/macros/georgian.dm	(revision 20131)
+++ /gsdl/stable/macros/georgian.dm	(revision 20131)
@@ -0,0 +1,752 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Georgian Language text and icon macros 
+# Many thanks to George Varamishvili (translated June 2004)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=ka] {ááá áááááá}
+_textsource_ [l=ka] {á¬á§áá á:}
+_textdate_ [l=ka] {áááááªáááá¡ ááá ááŠá}
+_textnumpages_ [l=ka] {áááá ááááá¡ á áááááááá: }
+
+_textsignin_ [l=ka] {ášáá¡ááá}
+
+_textdefaultcontent_ [l=ka] {áááá®áááááá áááá áá áá  áááá«áááá áááá á£áááá <a href="javascript:history.back()">á£ááá</a>}
+
+_textdefaulttitle_ [l=ka] {ášááªáááá}
+
+_textbadcollection_ [l=ka] {ááááá¥áªáá  ("_cvariable_") áá  áá áá¡ ááááá¡á¢áááá ááá£áá áá ááá¡á¢áá£ááá¡ áªáá€á á£áá ááááááááááá¡ á¡áá¡á¢áááášá}
+
+_textselectpage_ [l=ka] {-- ááá á©ááá áááá áá  --}
+
+_collectionextra_ [l=ka] {ááááá¥áªáá ášáááªááá¡ _about:numdocs_ áááá£áááá¢á¡. 
+ááá  _about:builddate_ ááŠáá¡ á¬áá áááá.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=ka] {<p>ááááá¥áªáá ášáááªááá¡_numdocs_ _If_("_numdocs_" eq "1",áááá£áááá¢á¡,áááá£áááá¢á¡), á¡ááá áá áááªá£ááááá : _numbytes_.
+<p><a href="_httppagex_(bsummary)">áááá­áá áá </a>Â  ááááá¥áªááá¡ ášáá¥áááá¡ á ááá£ááá¡ á¡áááá®áááá.
+}
+
+_textdescrcollection_ [l=ka] {}
+_textdescrabout_ [l=ka] {áá ááá¥á¢áá¡ ášáá¡áá®áá}
+_textdescrhome_ [l=ka] {áááááá á áááá áá}
+_textdescrhelp_ [l=ka] {ááá®ááá áááá¡ áááá áá}
+_textdescrpref_ [l=ka] {ááá áááá¢á ááá}
+_textdescrgreenstone_ [l=ka] {áá ááá¡á¢áá£ááá¡ áªáá€á á£áá ááááááááááá¡ áá ááá ááá£áá á£áá á£ááááá§áá€á}
+_textdescrusab_ [l=ka] {á£áá£áááášáá á: á áá¡á ááááá§ááááá ááááá­áá ááá?}
+
+_textdescrSearch_ [l=ka] {á«áááá á¢áá ááááááá}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=ka] {á¡áááá£á áááá¡ á¡ááá¡ ááááááááá ááá ááááááá¡ ááá®ááááá}
+_textdescrCreator_ [l=ka] {ááá¢áá áááá¡ ááááááá¡ ááá®ááááá ááááááááá ááá}
+_textdescrSubject_ [l=ka] {ááááááááá ááá á¡áááááá ááá á á£áá áááááá}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=ka] {ááá ááŠáá¡ ááá®ááááá ááááááááá ááá }
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+_textdescrSource_ [l=ka] {ááááááááá ááá á€ááááááá¡ á¡áá®áááááá}
+_textdescrLanguage_ [l=ka] {ááááááááá ááá áááááá¡ ááá®ááááá}
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=ka] {ááááááááá ááá áá áááááááªááááá¡ ááá®ááááá}
+_textdescrKeyword_ [l=ka] {ááááááááá ááá á¡áááááá«á á¡áá¢á§ááá¡ ááá®ááááá}
+_textdescrHowto_ [l=ka] {ááááááááá ááá  á¡áášá£áááááááá¡ ááá¢áááá ááááá¡ ááá®ááááá}
+_textdescrList_ [l=ka] {áááá£áááá¢áááá¡ á¡ááá¡ ááááááááá ááá }
+_textdescrSeries_ [l=ka] {áááááªáááááá¡ ááááááááá ááá}
+_textdescrTo_ [l=ka] {ááááááááá áááâááá¡â ááááá}
+_textdescrFrom_ [l=ka] {ááááááááá ááá  âááá¡áááâ ááááá}
+_textdescrTopic_ [l=ka] {ááááááááá ááá á¡áááªáááá£á á ááááááá¡ ááá®ááááá}
+_textdescrBrowse_ [l=ka] {ááááááááá ááá}
+_textdescrCollage_ [l=ka] {á¡á£á áááááá¡ ááááááá¡ ááá®ááááá ááááááááá ááá}
+_textdescrPeople_ [l=ka] {ááá á¡ááááááá¡ á¡ááá¡ ááááááááá ááá }
+_textdescrAcronym_ [l=ka] {ááá áááááááá¡ ááááááááá ááá}
+_textdescrPhrase_ [l=ka] {ááááááááá ááá á€á áááááá¡ ááá®ááááá}
+_textdescrArtist_ [l=ka] {á®áááááááá á¡ááá¡ ááááááááá ááá}
+_textdescrVolume_ [l=ka] {ááááááááá ááá á¢áááááá¡ ááá®ááááá}
+_textdescrCountries_ [l=ka] {á¥ááá§ááááá¡ ááá®ááááá ááááááááá ááá}
+_textdescrCaptions_ [l=ka] {á€áá¢ááááá¡ ááááááááá ááá á¬áá á¬áá áááá}
+
+
+_labelSearch_ [l=ka] {á«áááá}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=ka] {á¡áááá£á ááá ááááááá¡ ááá®ááááá}
+_labelCreator_ [l=ka] {ááá¢áá ááá ááááááá¡ ááá®ááááá}
+_labelSubject_ [l=ka] {á¡áááááá ááá á á£áá ááááá }
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=ka] {ááá ááŠá}
+# -- Missing translation: _labelType_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+_labelSource_ [l=ka] {á€ááááááá¡ á¡áá®ááááá}
+_labelLanguage_ [l=ka] {ááá}
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=ka] {áá áááááááªáá}
+_labelKeyword_ [l=ka] {á¡áááááá«á á¡áá¢á§áááá}
+_labelHow_ [l=ka] {á¡áášá£ááááááá}
+_labelSeries_ [l=ka] {á¡áá áááá}
+_labelList_ [l=ka] {á©áááááááááá}
+_labelTo_ [l=ka] {âááá¡â}
+_labelFrom_ [l=ka] {âááá¡áááâ}
+_labelTopic_ [l=ka] {áááááá}
+_labelBrwse_ [l=ka] {ááááááááá ááá}
+_labelCollage_ [l=ka] {áááááá}
+_labelBrows_ [l=ka] {ááááááááá ááá}
+_labelPeople_ [l=ka] {ááá á¡áááááá ááááááá¡ ááá®ááááá}
+_labelAcronym_ [l=ka] {ááá ááááááá}
+_labelPhrase_ [l=ka] {á€á ááááá}
+_labelArtist_ [l=ka] {á®ááááááá}
+_labelVolume_ [l=ka] {á¢ááááá}
+_labelCaptions_ [l=ka] {á¬áá á¬áá ááá}
+_labelCountries_ [l=ka] {á¥ááá§áááá}
+
+_texticontext_ [l=ka] {áááá£áááá¢áá¡ ááá®áá}
+_texticonclosedbook_ [l=ka] {áááá£áááá¢áá¡ ášááááá á¡áá¡ ááá®áá}
+_texticonnext_ [l=ka] {ášáááááá áááá§áá€ááááá}
+_texticonprev_ [l=ka] {á¬ááá áááá§áá€ááááá}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=ka] {MIDI áááá£áááá¢áá¡ ááá®áá}
+_texticonmsword_ [l=ka] {Microsoft Word  áááá£áááá¢áá¡ ááá®áá}
+_texticonmp3_ [l=ka] {MP3 áááá£áááá¢áá¡ ááá®áá}
+_texticonpdf_ [l=ka] {PDF áááá£áááá¢áá¡ ááá®áá}
+_texticonps_ [l=ka] {PostScript  áááá£áááá¢áá¡ ááá®áá}
+_texticonppt_ [l=ka] {PowerPoint-áá¡  áááá£áááá¢áá¡ ááá®áá}
+_texticonrtf_ [l=ka] {RTF áááá£áááá¢áá¡ ááá®áá}
+_texticonxls_ [l=ka] {Microsoft Excel áááá£áááá¢áá¡ ááá®áá}
+
+_page_ [l=ka] {áááá áá}
+_pages_ [l=ka] {áááá áááá}
+_of_ [l=ka] {ááá}
+_vol_ [l=ka] {á¢ááá}
+_num_ [l=ka] {áá á}
+
+_textmonth00_ [l=ka] {}
+_textmonth01_ [l=ka] {áááááá á}
+_textmonth02_ [l=ka] {ááááá áááá}
+_textmonth03_ [l=ka] {ááá á¢á}
+_textmonth04_ [l=ka] {ááá ááá}
+_textmonth05_ [l=ka] {áááá¡á}
+_textmonth06_ [l=ka] {ááááá¡á}
+_textmonth07_ [l=ka] {ááááá¡á}
+_textmonth08_ [l=ka] {ááááá¡á¢á}
+_textmonth09_ [l=ka] {á¡áá¥á¢ááááá á}
+_textmonth10_ [l=ka] {áá¥á¢ááááá á}
+_textmonth11_ [l=ka] {ááááááá á}
+_textmonth12_ [l=ka] {áááááááá á}
+
+_textdocument_ [l=ka] {áááá£áááá¢á}
+_textsection_ [l=ka] {áááá§áá€ááááá}
+_textparagraph_ [l=ka] {ááá ááá áá€á}
+
+_magazines_ [l=ka] {áá£á áááááá}
+
+_nzdlpagefooter_ [l=ka] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">áá®ááá ááááááááá¡ áªáá€á á£áá ááááááááááá¡ áá ááá¥á¢á</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">áááááá£á¢áá á£á áááªáááá ááááá áááááá á</a>, 
+<a href="http://www.waikato.ac.nz">áááááá¢áá¡ á£ááááá á¡á¢áá¢á</a>, 
+áá®ááá áááááááá}
+
+_linktextHOME_ [l=ka] {áááááá á áááá áá}
+_linktextHELP_ [l=ka] {ááá®ááá ááá}
+_linktextPREFERENCES_ [l=ka] {ááá áááá¢á ááá}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=ka] {áá ááá¡á¢áá£ááá¡ áªáá€á á£áá áááááááááá}
+_textadmin_ [l=ka] {ááááááá¡á¢á ááªáá£áá áááá áá}
+_textabgs_ [l=ka] {áá ááá¡á¢áá£ááá¡ ášáá¡áá®áá}
+_textgsdocs_ [l=ka] {áá ááá¡á¢áá£ááá¡ áááá£áááá¢ááªáá}
+
+_textdescradmin_ [l=ka] {ááá«áááá áá®ááá  áááá®ááá ááááááá¡ ááááá¢áááá¡ á¡áášá£áááááá¡, áááá¡ á£á§á áá¡ ááááá¥áªáááá¡ á¡áá¡á¢áááášá, áá«áááá áá ááá¡á¢áá£ááá¡ ááá¡á¢ááááªáá¡áááá¡ á¡áá­áá á á¢áá¥áááá£á  ááá€áá áááªááá¡.
+}
+
+_textdescrgogreenstone_ [l=ka] {ááááááá®á ááá¡ áá ááá¡á¢áá£ááá¡ áá ááá ááá£á á£áá á£ááááá§áá€ááá áá áá®ááá ááááááááá¡ áªáá€á á£á áááááááááááá,  á¡ááááª áá¡ áá ááá¥á¢á ášááá¥ááá.}
+
+_textdescrgodocs_ [l=ka] {áá ááá¡á¢áá£ááá¡ á¡áá®áááá«áŠááááááááá.}
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=ka] {á¡ááááááááááá ááá¢áá á€ááá¡á}
+_textdescrgli_ [l=ka] {ááá®ááá áááá áá®ááá ááááá¥áªááá¡ ášáá¥áááášá, ááááá€ááªáá áááášá, á£ááá áá á¡ááá£á ááááá¥áªááá¡ááá áááá áááááááášá áá ááááá¥áªááá¡ á¬áášááášá}
+
+package collector
+
+_textcollector_ [l=ka] {ááááá¥á¢áá á}
+_textdescrcollector_ [l=ka] {ááá ááááááááááá áá¡ ááá¢áá á€ááá¡áá á£á€á á ááá á áá§á ášáá¥ááááá áá á£ááá¢áá¡á áá áá¥á¢ááá£áá áááááááá¡áááá¡ ááá¡ áááááá áá á£ááá áá§áá¡ ááááá§ááááá£áá ááááááááááá áá¡ ááá¢áá á€ááá¡á.  }
+
+
+package depositor
+
+
+package gti
+
+_textdescrtranslator_ [l=ka] {áá ááá¡á¢áá£ááá¡ ááá¢áá á€ááá¡áá¡ áá®ááá áá áááááááááá ááá á¡áááá.
+}
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=ka] {ááááá¥áªááá¡ ášáá¡áá®áá}
+
+_textsubcols1_ [l=ka] {<p>ááááá¥áªáá ášáááªááá¡_1_  á¥ááááááá¥áªáááá¡:
+<blockquote>}
+
+_textsubcols2_ [l=ka] {</blockquote>
+áá¥ááá ášáááá«áááá ášááááá¬ááá (ášááá¡á¬áá áá) á¥ááááááá¥áªáááá ááá áááá¢á áááá¡ áááá ááá¡ ááá®ááá áááá.}
+
+
+_titleabout_ [l=ka] {ášáá¡áá®áá}
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+
+_texticonopenbookshelf_ [l=ka] {áááá§áá€áááááá¡ ááá®á£á áá}
+_texticonclosedbookshelf_ [l=ka] {áááá§áá€áááááá¡ ááá®á¡áá áá ášáá¥áááá¡áá¡ ááá®áá}
+_texticonopenbook_ [l=ka] {á¬ááááá¡ ááá®á£á áá}
+_texticonclosedfolder_ [l=ka] {á€ááááá áá¡ ááá®áá áá á¡áá á©áááá¡ ááá®áá}
+_texticonclosedfolder2_ [l=ka] {á¥áááááá§áá€áááááá¡ ááá®á¡áá: }
+_texticonopenfolder_ [l=ka] {á€ááááá áá¡ ááá®á£á áá}
+_texticonopenfolder2_ [l=ka] {á¥áááááá§áá€áááááá¡ ááá®á£á áá: }
+_texticonsmalltext_ [l=ka] {á¢áá¥á¡á¢áá¡ áááá§áá€áááááá¡ ááá®áá}
+_texticonsmalltext2_ [l=ka] {á¢áá¥á¡á¢áá¡ ááá®áá: }
+_texticonpointer_ [l=ka] {áááááááá á áááá§áá€ááááá}
+_texticondetach_ [l=ka] {áááá ááá¡ ááá®á¡áá áá®áá á€ááá¯áá áášá}
+_texticonhighlight_ [l=ka] {á¡áá«áááá á¡áá¢á§ááááá¡ ááááá§áá€á}
+_texticonnohighlight_ [l=ka] {áá  ááááá§áá¡ á¡áá«áááá á¡áá¢á§áááá}
+_texticoncontracttoc_ [l=ka] {á¡áá á©áááá¡ ááááªáá}
+_texticonexpandtoc_ [l=ka] {á¡áá á©áááá¡ ááá€áá ááááá}
+_texticonexpandtext_ [l=ka] {ááááá á¢áá¥á¡á¢áá¡ ááááá¢ááá}
+_texticoncontracttext_ [l=ka] {á¢áá¥á¡á¢áá¡ ááááá¢ááá áá®áááá áá®ááá áá á©áá£áá áááá§áá€áááááááá}
+_texticonwarning_ [l=ka] {<b>ááá€á áá®ááááá: </b>}
+_texticoncont_ [l=ka] {áááá á«ááááá?}
+
+_textltwarning_ [l=ka] {<div class="buttons">_imagecont_</div>
+_iconwarning_ááášáááá á¢áá¥á¡á¢á áááá áááªá£ááááá¡áá áá¥áááá áá áá£áááá¡áááá¡
+}
+
+_textgoto_ [l=ka] {ááááá¡ááá áááá ááá}
+_textintro_ [l=ka] {<i>(ášáá¡ááááá á¢áá¥á¡á¢á)</i>}
+
+_textCONTINUE_ [l=ka] {áááá á«ááááá?}
+
+_textEXPANDTEXT_ [l=ka] {á¢áá¥á¡á¢áá¡\nááášáá}
+
+_textCONTRACTCONTENTS_ [l=ka] {á®ááášááá á£ááááá¡\nášááááá á¡á}
+
+_textDETACH_ [l=ka] {áá®ááá\ná€ááá¯áá á}
+
+_textEXPANDCONTENTS_ [l=ka] {á¡áá á©áááá¡\nááášáá}
+
+_textCONTRACT_ [l=ka] {á®ááášááá á£ááááá¡\ná¢áá¥á¡á¢á}
+
+_textHIGHLIGHT_ [l=ka] {ááááášááá}
+
+_textNOHIGHLIGHT_ [l=ka] {ááááášáááá¡\ná£áá á§áá€á}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=ka] {_If_(_thislast_,results _thisfirst_ - _thislast_ for query: _cgiargq_,No matches for query: _cgiargq_)}
+_textnoquerytitle_ [l=ka] {á«ááááá¡ áááá áá}
+
+_textsome_ [l=ka] {á ááááááááá}
+_textall_ [l=ka] {á§áááá}
+_textboolean_ [l=ka] {áá£ááá¡}
+_textranked_ [l=ka] {á ááááá ááá£áá}
+_textnatural_ [l=ka] {á©ááá£áááá ááá}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=ka] {á«áááá áá á¥ááášá}
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+_textusequery_ [l=ka] {ášááááá®ááá¡ ááááá§ááááá}
+_textfreqmsg1_ [l=ka] {á¡áá¢á§ááááá¡ á áááááááá: }
+_textpostprocess_ [l=ka] {áá£_(_áá á­á§ááááášá á©áá¡áá£áá ášááááá®ááá_,<br><i>ášááááááá áááá£ášááááá áá á­á§ááááášá á©áá¡áá£áá ášááááá®ááá¡ á¡áááá®áááá_</i>
+)
+}
+_textinvalidquery_ [l=ka] {ášááááá®ááá¡ áá áá¡á¬áá á á€áá áá !!!!}
+
+_textmorethan_ [l=ka] {ááá¢á áááá á}
+_textapprox_ [l=ka] {ášáá¡áá®áá}
+_textnodocs_ [l=ka] {ášááááá®ááá¡ ášáá¡áááááá¡á áááá£áááá¢ááá áá  áá á¡ááááá¡}
+_text1doc_ [l=ka] {ášááááá®ááá¡  ášááá¡áááááááá1 áááá£áááá¢á.}
+_textlotsdocs_ [l=ka] {ášááááá®ááá¡ ášáá¡áááááá¡á áááá£áááá¢ááá.}
+_textmatches_ [l=ka] {ášáá¡áááááá¡á áááá£áááá¢ááá}
+_textbeginsearch_ [l=ka] {á«ááááá¡ ááá¬á§ááá}
+_textrunquery_ [l=ka] {ášááááá®ááá¡ ááášáááá}
+_textclearform_ [l=ka] {ášááááá®ááá¡ ááášáááá}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=ka] {á¡áá¢á§áá áá á€á ááá}
+_textinfield_ [l=ka] {... áááášá}
+_textfoldstem_ [l=ka] {(áááááªá, á€á£á«á)}
+
+_textadvquery_ [l=ka] {ášááááá®ááá¡ ášáá¢ááá}
+_textallfields_ [l=ka] {á§áááá áááá}
+_texttextonly_ [l=ka] {áá®áááá á¢áá¥á¡á¢á}
+_textand_ [l=ka] {áá}
+_textor_ [l=ka] {áá}
+_textandnot_ [l=ka] {áá áá á}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=ka] {á«áááá _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_, at _gselection_ level )_If_(_nselection_,in _nselection_ language )á ááááááª ášáááªááá¡ _querytypeselection_ á¡áá«áááá á€á áááá¡}
+
+_textadvancedsearch_ [l=ka] {ááá«ááááá¡ _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language ) _querytypeselection_  ášááááá®ááá¡ ááááá§áááááá}
+
+_textformsimplesearch_ [l=ka] {á«áááá  _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language ) -ášá _formquerytypesimpleselection_ }
+
+_textformadvancedsearch_ [l=ka] {á«áááá _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )ášá áá áááááªáááááá¡_formquerytypeadvancedselection_ order ááá®ááááá ááááá¢ááá}
+
+
+_textnojsformwarning_ [l=ka] {ááá€á áá®ááááá: áá¥ááá áá áá£ááá ášá ááááá áá£ááá JavaScript. <br> áááá¡áááá¡ á áá áááá®áá áªáááááá¡ á«áááá á©áá ááá JavaScript.}
+_textdatesearch_ [l=ka] {áá ááááá¥áªááášá áááá£áááá¢áááá¡ á«áááá  ášáá¡áá«ááááááá ááá ááŠáááá¡  ášá£ááááášá  áá áááá£áááá¢áááá¡ á«áááá ááááá áá¢á£áá ááá ááŠáá.}
+_textstartdate_ [l=ka] {á¡áá¬á§áá¡á ( áá áá®áááá) ááá ááŠá:}
+_textenddate_ [l=ka] {áááá ááá ááŠá:}
+_textbc_ [l=ka] {B.C.E.}
+_textad_ [l=ka] {C.E.}
+_textexplaineras_ [l=ka] {C.E. áá  B.C.E áá áá¡ ááá¢áá ááá¢áá£áá A.D. áá B.C. á¡áááá¡. á©ááá á¬áááááŠá ááªá®ááááá áá á©áááá á¬áááááŠá ááªá®ááá}
+
+_textstemon_ [l=ka] {(á¡áá¢á§ááááá¡ ááááááááááá ááááá áá ááá)}
+
+_textsearchhistory_ [l=ka] {á«ááááá¡ áá á¥ááá}
+
+#text macros for search history
+_textnohistory_ [l=ka] {áá á¥ááášá á«áááá áá áá ášáá¡áá«áááááá}
+_texthresult_ [l=ka] {ášááááá}
+_texthresults_ [l=ka] {ášááááá  (ááá£ááá¡á®áááá Found Results:)}
+_texthallwords_ [l=ka] {á§áááá á¡áá¢á§áá}
+_texthsomewords_ [l=ka] {á áááááááá á¡áá¢á§áá}
+_texthboolean_ [l=ka] {áá£ááá¡}
+_texthranked_ [l=ka] {á ááááá ááá£áá}
+_texthcaseon_ [l=ka] {á áááá¡á¢á áá¡ ááááá®áááá}
+_texthcaseoff_ [l=ka] {áááááá¡ ááááªáá}
+_texthstemon_ [l=ka] {á¬áááááááá }
+_texthstemoff_ [l=ka] {á¬áá£ááááááá}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=ka] {ááá áááá¢á ááá ááá§ááááá£ááá. áá£ áááááá§ááááá áá áá£ááá áá¡ âá£áááâ áŠááááá¡ áá¡ ááááá£áááá¡ ááá áááá¢á ááá¡.áááá­áá áá áá á-áá á áŠááááá¡ ááááá ááááááááá£á áááááášá.}
+_textsetprefs_ [l=ka] {ááá áááá¢á áááá¡ ááá§ááááá}
+_textsearchprefs_ [l=ka] {ááá áááá¢á áááá¡ á«áááá}
+_textcollectionprefs_ [l=ka] {ááááá¥áªááá¡ ááá áááá¢á ááá}
+_textpresentationprefs_ [l=ka] {áá ááááá¢ááªááá¡ ááá áááá¢á ááá}
+_textpreferences_ [l=ka] {ááá áááá¢á ááá}
+_textcasediffs_ [l=ka] {áááá¡á®áááááá£áá á áááá¡á¢á á:}
+_textignorecase_ [l=ka] {á áááá¡á¢á áá¡ áááá¡á®ááááááááá¡ ááááá áá ááá}
+_textmatchcase_ [l=ka] {á áááá¡á¢á áá¡ ááááá®áááá}
+_textwordends_ [l=ka] {á¡áá¢á§ááá¡ ááááááááá:}
+_textstem_ [l=ka] {á¡áá¢á§ááá¡ áááááááááá¡ ááááá áá ááá}
+_textnostem_ [l=ka] {ááááááá á¡áá¢á§ááá¡ ááááá®áááá}
+_textprefop_ [l=ka] {ááááá á£áááá¡ _maxdocoption_ á ááá£áá¢áá¢á¡ _hitsperpageoption_ á«ááááá¡ áááááá£á áááá ááá.}
+_textextlink_ [l=ka] {ááá á ááá áááá ááááá ááááá ááá:}
+_textintlink_ [l=ka] {áááá£áááá¢áááá¡ á¬á§áá á:}
+_textlanguage_ [l=ka] {ááá¢áá á€ááá¡áá¡ ááá:}
+_textencoding_ [l=ka] {ááááá ááá:}
+_textformat_ [l=ka] {ááá¢áá á€ááá¡áá¡ á€áá ááá¢á:}
+_textall_ [l=ka] {á§áááá}
+_textquerymode_ [l=ka] {ášááááá®ááá¡  á ááááá:}
+_textsimplemode_ [l=ka] {ááá á¢ááá á«áááá}
+_textadvancedmode_ [l=ka] {áááááááá ááá£áá á«áááá (ášáá¡áá«ááááááá áááááá£á á á«áááá !,&, |, áá áá á­á§áááááá¡ ááááá§áááááá)}
+_textlinkinterm_ [l=ka] {ášá£ááááá£á á áá áááááá áááá áá}
+_textlinkdirect_ [l=ka] {ááááá¡ááá}
+_textdigitlib_ [l=ka] {áªáá€á á£áá áááááááááá}
+_textweb_ [l=ka] {www}
+_textgraphical_ [l=ka] {áá áá€ááá£áá}
+_texttextual_ [l=ka] {á¢áá¥á¡á¢á£á á}
+_textcollectionoption_ [l=ka] {<p>
+ á¥ááááááá¥áªáá ášáááªááá¡:
+<br>}
+
+_textrelateddocdisplay_ [l=ka] {áá¡áááá¡á áááá£áááá¢áááá¡ ááááá¢ááá}
+_textsearchhistory_ [l=ka] {á«ááááá¡ áá á¥ááá:}
+_textnohistory_ [l=ka] {á«ááááá¡ áá á¥ááá áá  áá á¡ááááá¡}
+_texthistorydisplay_ [l=ka] {á«áááá¡ áá á¥áááááá _historynumrecords_ á©áááá¬áá áá¡ ááááá¢ááá}
+_textnohistorydisplay_ [l=ka] {á«ááááá¡ áá á¥áááá¡ ááá£á¥áááá}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=ka] {á«ááááá¡ á€áá áá:}
+_textplainsearch_ [l=ka] {ááá á¢ááá á«áááá:}
+_textqueryboxsize_ [l=ka] {á«ááááá¡ á£á¯á áá¡ áááá:}
+_textregbox_ [l=ka] {ááá áááá£á á á«ááááá¡ á£á¯á á}
+_textbigbox_ [l=ka] {áááá á«ááááá¡ á£á¯á á}
+_textformtype_ [l=ka] {á€áá ááá¡ á¢ááá:}
+_textsimple_ [l=ka] {ááá á¢ááá}
+_textadvanced_ [l=ka] {áááááááá ááá£áá}
+
+# used in "with 4 fields" in the form search box
+# -- Missing translation: _textwith_
+_textfields_ [l=ka] {áááááá}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=ka] {áááá£áááá¢áááá¡ áááááááá}
+_textalsoshowing_ [l=ka] {áá¡ááá}
+_textwith_ [l=ka] {ááá¥á¡ááá£á}
+_textdocsperpage_ [l=ka] {áááá£áááá¢á áááá ááá}
+
+_textfilterby_ [l=ka] {áá áááá£áááá¢áááá¡ áááŠááá, á áááááááª ášáááªááá¡}
+_textall_ [l=ka] {á§áááá}
+_textany_ [l=ka] {ááááá¡áááá á}
+_textwords_ [l=ka] {á¡áá¢á§ááááá}
+_textleaveblank_ [l=ka] {áááá¡áááá¡ á áá ááá®áá á§áááá áááá£ááááá¢á, ááá¢áááá áá¡ á£á¯á á áªáá áááá}
+
+_browsebuttontext_ [l=ka] {"áááá£áááá¢áááá¡ ááá®áá áá¡á®ááá"}
+
+_nodata_ [l=ka] {<i>áááááªááááá áá  áá á¡ááááá¡</i>}
+_docs_ [l=ka] {áááá£áááá¢ááá}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=ka] {ááá®ááá ááá}
+_textSearchshort_ [l=ka] {áªááááá£áá á¡áá¢á§ááááá á«áááá}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=ka] {áááááªáááááá¡ ááá®áá á¡áááá£á áá}
+_textCreatorshort_ [l=ka] {áááááªáááááá¡ ááá®áá ááá¢áá áááá¡ ááá®ááááá}
+_textSubjectshort_ [l=ka] {áááááªáááááá¡ ááá®áá á¡áááááá ááá á á£áá áááá}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=ka] {áááááªáááááá¡ ááá®áá ááá ááŠáááá¡ ááá®ááááá}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=ka] {áááááªáááááá¡ ááá®áá  á€ááááá¡ á¡áá®áááá¡ ááá®ááááá}
+_textLanguageshort_ [l=ka] {áááááªáááááá¡ ááá®áá áááááá¡ ááá®ááááá}
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=ka] {áááááªáááááá¡ ááá®áá á¡áá ááá¡ ááá®ááááá}
+_textToshort_ [l=ka] {áááááªáááááá¡ ááá®áá âááá¡â  ááááááá¡  ááá®ááááá}
+_textFromshort_ [l=ka] {áááááªáááááá¡ ááá®áá ááááááá¡ âááá¡áááâ  ááá®ááááá}
+_textBrowseshort_ [l=ka] {áááááªáááááá¡ ááááááááá ááá}
+_textOrganizationshort_ [l=ka] {áááááªáááááá¡ ááá®áá áá áááááááªááááá¡ ááá®ááááá}
+_textHowtoshort_ [l=ka] {áááááªáááááá¡ ááá®áá âá¡áášá£áááááááá¡â ááá®ááááá}
+_textTopicshort_ [l=ka] {áááááªáááááá¡ ááá®áá ááááááá¡ ááá®ááááá }
+_textPeopleshort_ [l=ka] {áááááªáááááá¡ ááá®áá ááá á¡ááááááá¡ ááá®ááááá}
+_textAcronymshort_ [l=ka] {áááááªáááááá¡ ááá®áá áááášá ááá áááááááá¡ áá á¡áááááá¡ ááá®ááááá}
+_textPhraseshort_ [l=ka] {áááááªáááááá¡ ááá®áá  á€á áááááá¡ ááá®ááááá}
+_textArtistshort_ [l=ka] {áááááªáááááá¡ ááá®áá á®áááááááá¡ ááá®ááááá}
+_textKeywordshort_ [l=ka] {áááááªáááááá¡ ááá®áá  á¡áááááá«á á¡áá¢á§ááá¡ ááá®ááááá}
+_textVolumeshort_ [l=ka] {áááááªáááááá¡ ááá®áá  á¢áááááá¡ ááá®ááááá}
+_textCountriesshort_ [l=ka] {áááááªáááááá¡ á¥ááá§ááááá¡ ááá®ááááá ááá®áá}
+_textdefaultshorttext_ [l=ka] {áááá£á¡ááá áá ááá áááá¡áá€ááááªáá}
+
+_textSearchlong_ [l=ka] {<p>ášáááá«áááá <i>á«áááá áªááááá£áá á¡áá¢á§ááááá</i>. áááá¢áá¥á¡á¢áááá á¡áá¢á§ááá¡ ááá«áááá âá«ááááá¡âáááá ááá¡ ááááá§áááááá. ááá á©ááááá ááá ááá áááá ááá. ášáááá«áááá á¡á®áá áááá ááááááá ááááá®ááááá áá áááá ááá  <i>á«ááááá¡</i> áŠáááááá¡ ááááá§áááááá. 
+ }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=ka] {<p>ášáááá«áááá<i>áááááªáááááá¡ ááá®áá á¡áááá£á áá</i>. <i>á¡áááá£á ááá</i> áŠáááááá ááá­áá á áááááá¢ááá¡ á¬ááááááá¡ á¡áááá£á áááá¡ á¡ááá¡ áááááááá£áá¡ ááááááá¡ ááá®ááááá }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=ka] {áááááªáááááá¡ ááá®áá ááá¢áá áááá¡ ááá®ááááá. <i>ááá¢áá ááá</i> áŠáááááá ááá­áá á áááááá¢ááá¡ á¬ááááááá¡ á¡ááá¡ áááááááá£áá¡ ááá¢áá áá áááá áááá¡ ááá®ááááá
+}
+
+_textSubjectlong_ [l=ka] {<i>áááááªáááááá¡ ááá®áá á¡áááááá ááá á á£áá áááá</i>. <i>á¡áááááá ááá á á£áá ááááá</i> áŠáááááá ááá­áá á áááááá¢ááá¡ áá á¡áááááá ááá á á£áá áááááá¡ á¡ááá¡, á áááááááááª á¬áááááá áááááááá£ááá ááá ááááá.  }
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=ka] {<i>áááááªáááááá¡ ááá®áá ááá ááŠáááá¡ ááá®ááááá</i> <i>ááá ááŠááá</i> áŠáááááá ááá­áá á áááááá¢ááá¡ á¥á áááááááá£á áá áááááááá£á áááááªáááááá¡ á¡ááá¡ }
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=ka] {<i>á€ááááá¡ á¡áá®ááá </i> áŠááááá. áááááá¢ááá¡ áááááááá£á á¡ááá¡ á€ááááá¡ áááááááá á¡áá®áááááá¡ ááá®ááááá.  }
+
+_textLanguagelong_ [l=ka] {<i>ááá</i> áŠááááá. áááááá¢ááá¡ áááááªáááááá¡ á¡ááá¡ áááááááá£áá¡ áááááá¡ ááá®ááááá.  }
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=ka] {<i>áá áááááááªáááá </i> áŠááááá. (áááááá¢ááá¡  áá áááááááªááááá¡ á¡ááá¡)}
+
+_textHowtolong_ [l=ka] {<i> á¡áášá£ááááááá</i> áŠááááá.  áááááá á¡áášá£áááááááá¡ á¡áá}
+
+_textTopiclong_ [l=ka] {<i>áááá</i> áŠááááá. áááááá¢ááá¡ ááááááá¡ á¡ááá¡
+ }
+
+_textTolong_ [l=ka] {<i>ááá¡</i> áŠááááá. áááááá¢ááá¡ ááá¡áááá ááááá¡ á¡ááá¡.  }
+
+_textFromlong_ [l=ka] {<i>. ááá¡ááá áŠááááá </i> áŠááááá. áááááá¢ááá¡ ááááááááááá¡ ááá®ááááá.  }
+
+_textSerieslong_ [l=ka] {<i>áááááªáááááá¡ ááá®áá á¡áá ááá¡ ááá®ááááá</i>.  <i>á¡áá ááá¡ </i> áŠáááááá ááá­áá á ááááá¢ááá¡ áá á¡áá áá£áá áááááªáááááá¡ á¡ááá¡, á áááááááª ááááááá ášáá¡á£ááá  ááááá¥áªááášá. }
+
+_textBrowselong_ [l=ka] {<i>ááááááááá ááá </i> áŠááááá.  }
+
+_textPeoplelong_ [l=ka] {<i>áááááªáááááá¡ ááá®áá ááá á¡ááááááá¡ ááá®ááááá</i>. <i>ááá á¡áááááá</i> áŠáááááá ááá­áá á áááááá¢ááá¡ ááá á¡ááááááá¡ á¡ááá¡ áááááá£á áá áááááááá£áá¡ áááá áááá¡ ááá®ááááá.  }
+
+_textAcronymlong_ [l=ka] {<i>áááááªáááááá¡ ááá®áá áááášá ááá áááááááá¡ áá á¡áááááá¡ ááá®ááááá</i> áŠááááá.  áá£ áááá­áá á áŠááááá¡ <i>ááá ááááááá</i> ááááŠááá ááá áááááááá¡ á¡ááá¡ áá á¢áá¥á¡á¢ášá áááá áááááááááá¡ áááááááá¡.  }
+
+_textPhraselong_ [l=ka] {<i>á€á ááááá </i> áŠááááá. áááááá§ááááá á€á áááááá¡ ááááááááá áááá¡áááá¡.  }
+
+_textArtistlong_ [l=ka] {<i>á®ááááááá </i> áŠááááá. áááááá¢ááá¡ ááááááá¡ ááá®ááááá á®áááááááá á¡ááá¡. }
+
+_textKeywordlong_ [l=ka] {<i>.á¡áááááá«á á¡áá¢á§áá </i> áŠááááá. áááááá¢ááá¡ á¡áááááá«á á¡áá¢á§ááááá¡ á¡ááá¡. }
+
+_textVolumelong_ [l=ka] {<i>á¢ááááá</i> áŠááááá. áááááá¢ááá¡ á¢áááááá¡ á¡ááá¡. }
+
+_textCaptionslong_ [l=ka] {<p>ášáááá«áááá <i>áááááªáááááá¡ á¬áá á¬áá áááá¡ ááá®ááááá ááá®áá</i> <i>á¬áá á¬á áá ááá</i> áŠáááááá ááá­áá áá. áááááá  á¬áá á¬áá ááá á¡áá. }
+
+_textCountrieslong_ [l=ka] {<p>ášáááá«áááá <i>áááááªáááááá¡ á¥ááá§ááááá¡ ááá®ááááá ááá®áá</i> 
+<i>á¥ááá§áááá</i> áŠáááááá ááá­áá áá. áááááá á¥ááá§ááááá¡ á¡áá}
+
+
+_textdefaultlongtext_ [l=ka] {<p>áááá¬áá¥áá <i>"á£áªáááá"</i> áŠááááá¡ á ááá áááááááááá áá
+áááááªááááá (á¡áá áááááááá£ááá "á£áªáááá" ááááá¡ ááá®ááááá).  }
+
+
+_textreadingdocs_ [l=ka] {á áááá  á¬ááááááá®áá áááá£áááá¢á}
+
+_texthelpreadingdocs_ [l=ka] {
+<p>.áá¥ááá ášáááá«áááá  áá¥ááá  á áááá¡ ááááŠá¬ááá áááááááá£ááá£á  á¬ááááááá áá áááá£áááá¢áááá á ááááá, áááá á¡áááá£á á áá  á€áá¢áá¡á£á ááá ááááá©ááááá áááá ááá¡  ááááá ááá áªá®ááá .
+ááá ááááá¥áªááá¡ ááá áá®áááá¡ á¡áá á©ááá,á áááá¡ááª ááááá á©ááááá ášáááªáááá áááááááá á áááá ááááá¡ á ááááááááá¡ ááááááá  áá ááá, á¡ááááª áá¥ááá ááá«ááááá á¡áášá£ááááá ááááášááá áá®ááá áááá áá áá ááááá®ááááá á¬áá áá á£ááá. 
+á¡áá á©ááášá áááááááá á áááá§áá€áááááá¡ á¡áááá£á á ááááá§áá€áááá .</p>
+
+<p>á¥áááááá ááááááá¡ááá£ááá áááááááá á áááá§áá€áááááá¡ á¢áá¥á¡á¢á.
+á ááááá¡  ášááááá ááááááá¡ááá£ááá  áŠááááá á áááááááª ááááá¡áá®á£ááá áá¡á ááá, 
+áááá ááááá§áááááá áá¥ááá ááá«ááááá á¡áášá£ááááá  ááááá®ááááá ášááááá áá  á¬ááá áááá§áá€áááááášá.</p>
+
+<p>á¥áááááá ááááááá¡ááá£ááá á¡áááá£á á áá á€áá¢áá¡á£á ááááá.  ááááááááá£ááá á ááááááááá áŠááááá .
+ááá­áá áá <i>á¢áá¥á¡á¢áá¡ ááá€áá ááááááá</i> áááá¡áááá¡ ,á áá ,áááá€áá áááá¡ ááááááá á¢áá¥á¡á¢á áááááááá á áááá§áá€áááááášá áá á¬áááášá. 
+áá ášáááá®ááááášá ,áá£, áááá£áááá¢á áááá áááªá£ááááá¡ áá¥áááá, ááááááá á¢áá¥á¡á¢áá¡ ááá¡áá®á¡ááááá ááá¡ ááá¡á­áá áááá áááá áá á áááá¡ááá ááááááááá¡ ááá®á¡ááá áááá¡ ááá ááá¬ááá¡!
+ áááá­áá áá <i>á¡áá á©áááá¡ ááá€áá ááááááá</i>  , áááá¡áááá¡ á áá ááá®á¡ááá áááááááá á¡áá á©ááá.</p>
+}
+
+_texthelpsearchingtitle_ [l=ka] {á áááá  ááááááá áªááááá£áá á¡áá¢á§áááá}
+
+_texthelpsearching_ [l=ka] {
+<p>
+  á«ááááá¡ áááá ááááá áá¥ááá ááááááááá áááá®ááááá¡ ááá á¢ááá á¡á¢áá¢ááááá¡ ááá®ááááá:<p>
+  
+  <ol><li>áá£á¡á¢áá ááááááááá á ááááá ááá ááá áá€áá¡ ááá«áááá áá¡á£á á
+      <li>áááá¡áááŠáá áá á áá¡á ááá«áááá áá¡á£á á, áááááááá ááá ááá áá€áá¡  áá á ááááááááá á¡áá¢á§ááá¡ 
+      <li>ášááá¢áááá á«ááááá¡áááá¡ á¡áá¡á£á áááá á¡áá¢á§áá 
+      <li>áááá­áá áá <i>á«ááááá¡ ááá¬á§ááá</i> áŠááááá¡
+ </ol>
+
+<p>ášááááá®ááá¡ ášáá¡á á£ááááá¡ ášááááá áááááá ášááááá®ááá¡  ášáá¡áááááá¡á ááªá áááá£áááá¢áá¡ á¡áááá£á ááá.
+ ááááášá ááááááá¡ááá£ááá áŠááááá, á ááááááª ááááááá§áááá ášááááá ááª ášáá¡áááááá¡ áááá£áááá¢áá .
+
+<p>ááá¥á¡ááááá£á á á áááááááá áááá á£áááá£áá áááá£áááá¢áááá¡á 100-áá¡  á¢áááá.  áá¥ááá ášáááá«áááá ášááªááááá 
+áá¡ á áááááááá <i>ááá áááá¢á ááá</i>-áá ááá­áá áá á áááááª ááááááááá£ááá áááá ááá¡ ááááá.<p>
+}
+
+_texthelpquerytypetitle_ [l=ka] {ášááááá®ááá¡ á¢ááá}
+_texthelpquerytype_ [l=ka] {
+<p>áá á¡ááááá¡ áá á áááá¡á®áááááá£áá á¢áááá¡ ášááááá®áá.
+
+<ul>
+  <li>ášááááá®áá <b>á§áááá</b> á¡áá¢á§ááá¡áááá¡. áá«ááá¡ áááá£áááá¢ááá¡ (áááááá¡ áá á¡áááá£á ááá¡),
+     á áááááááª ášáááªáááá á¢á¥áááá¡ áááá  áááááááá£á á§áááá á¡áá¢á§ááá¡.
+      ášáá¡áááááá¡á áááá£áááá¢ááá ááááááá¡ ááá®ááááá ááááááá¡ ááá áááá.<p>
+
+  <li>ášááááá®áá <b> á áááááááá</b>á¡áá¢á§ááá¡áááá¡. 
+      áááááá¢ááá¡ ááááá á á¢áá áááá¡ áááá£áááá¢ááášá á áááááá¡ááª áá¥ááá áá«ááá.  
+      <p><ul>
+        <li>  áááá£áááá¢áá¡ ášááááá á¡áá¡ á«áááá , á ááááááª ááá£áá®ááááááá  á¡ááá¡;
+        <li> áášááááá ááá ááá á ááááááª, á£á€á á áááášáááááááááá áááá á á¡ááá áá ááá ááá;
+        <li> ááááá áááá£áááá¢áááá¡ ášáá¡áááááá¡ááá  á£á€á á ááá á¢áááá áá á«áá áááá£áááá¢áááá¡ááá áááá¡á®ááááááá.  
+      </ul>
+</ul>
+
+<p>ášáááá«áááá áááááá§áááá á ááááá áááá á  á¡áá«áááá á¢áá áááá--ááááááá á¬ááááááááá áá ááááá ááá ááá áá€á. áá ášáááá®ááááášá  áá£,
+ áá¥ááá ášááá¢áááá áá®áááá áá áá á¡áá«áááá á¢áá áááá, ááášáá áááá£áááá¢ááá ááááááááá áá á¢áá ááááá¡  ášáá®áááá áá¡ á¡áá®ášáá áá¡ áááááá¡ ááá®ááááá.<p>
+}
+
+_textdatesearch_ [l=ka] {á«áááá ááá ááŠáááá¡ ááá®ááááá}
+
+_texthelpdatesearch_ [l=ka] {
+ááá ááŠáá¡ á«áááá ááá«áááá á¡áášá£áááááá¡  áááá«ááá áá¡ááá áááá£áááá¢ááá , á áááááááª ááááá§áá€áááááá áá¥áááá¡ ášááááá®ááá¡ á áááá áª á¡áá«áááá á¢áá ááááááá¡ ááá®ááááá
+ ááá áááá áááášá ááŠá¬áá ááá áááááááááá¡ áá ááá¡ áááá¡áá«áŠáá á£áá ááá¢áá ááááá¡ ááá®ááááá. áá¥ááá ášáááá«áááá ááá«ááááá áááá£áááá¢ááá ááá áááá£áá á¬ááááá á¬áááá ášá£ááááášá. ášááááášááá, á áá ášááááá®ááášá áá  áá áá¡ áá£áªááááááá á¡áá«áááá á¢áá ááááááá¡ ášáá¢ááá, á ááááá áá¥ááá ášáááá«áááá á«ááááá¡ á©áá¢áá ááá áá®áááá ááá ááŠáá¡ ááá®ááááá.
+ áá¡ááá ááá áá¥áá, áá  áá áá¡ áá£áªááááááá ášááááá®ááášá ááá ááŠáá¡ ášáá¢ááá, áá ášáááá®ááááášá, á£áá áááá, ááá ááŠáá á«áááá áá  á©áá¢áá áááá.<p>
+}
+
+_texthelpdatehowtotitle_ [l=ka] {á áááá  ááááááá§ááá áá¡ á¡áášá£ááááá:}
+_texthelpdatehowto_ [l=ka] {
+<ul>
+   <li>áááá£áááá¢áááá¡ á«áááá áá®áááá áá áá á¬ááá¡ ááááááááá:<p>
+   <ul>
+       <li>á£áá áááá  ášááá¢áááá  á¡áá«áááá á¢áá áááááá á áááá áª áá¥ááá á©ááá£áááá áá ááááááá. 
+       <li>ášááá¢áááá  á¡áá¡á£á áááá á¬ááá  âá¡áá¬á§áá¡á (áá áá®áááá) ááá ááŠáâ-á¡ á£á¯á áášá.
+       <li>áá ášáááá®ááááášá áá£ áááááá áá£áá ááá ááŠá á©áááá¡ á¬ááá ááŠááªá®áááááá,
+           ááášáá ááá á©ááá âá©áááá¡ á¬ááá ááŠááªá®áááááâ áá á£á¯á áá¡ áááá á«á áá§áá€á áááá£áá ááááá£ááá.
+       <li>áááá¬á§áá á«áááá á áááá áª áá¥ááá áááá¡ á©ááá£áááá áá ááááááá.
+   </ul>
+<p><li>áááá£áááá¢áá¡ á«áááá áªáááááá áá áá¡ ááá ááááá¡ áá á¬ááááá¡ ášá£áááááááá¡ ááá®ááááá:<p>
+   <ul>
+       <li>á£áá áááá ášááá¢áááá á¡áá«áááá á¢áá áááá á áááá áª áá¥ááá á©ááá£áááá áá ááááááá.
+       <li>ááá áááááá ááá ááŠá â á¡á¬á§áá¡á (áá áá®áááá )ááá ááŠáâ á£á¯á áášá.
+       <li>ášááá¢áááá áááá ááá ááŠá âá¡áááááá ááá ááŠáâ á£á¯á áášá.
+       <li>ááá á©ááá ááá ááŠá âá©áááá¡ á¬ááá ááŠá ááªá®áááááâ áááá£áá ááááá£ááá 
+      <li>áááá¬á§áá á«áááá á áááá áª áá¥ááá áááá¡ á©ááá£áááá áá ááááááá.
+   </ul>    
+</ul><p>
+}
+
+
+_textchangeprefs_ [l=ka] {ááá áááá¢á áááá¡ ášááªááá}
+
+_texthelppreferences_ [l=ka] {
+
+<p><i>ááá áááá¢á áááá¡</i> áŠáááááá ááá­áá áá ášáááá«áááá áááá§áááá áá ááá¡á¢áá£ááá¡ ááá¢áá á€ááá¡á , áá¥áááá ášáá®ááá£ááááááá¡áá¡áááá 
+
+}
+
+
+_texthelplanguageprefstitle_ [l=ka] {áááá¡ ááá áááá¢á ááá}
+_texthelplanguageprefs_ [l=ka] {
+á§áááá  ááááá¥áªááášá ááá§ááááá£ááá á¡áá¡á¢ááá£á áá áááá¡áááŠáá á£áá ááá, áááá áá  ášáááá«áááá ááááá®ááááá á¡áá¡á£á ááá ááááá.
+ááá áááá á¢áááá¡ áááá ááá¡ ááá®ááá áááá.
+}
+
+_texthelppresentationprefstitle_ [l=ka] {ááá¢áá á€ááá¡áá¡ ááá áááá¢á ááá}
+_texthelppresentationprefs_ [l=ka] {
+ááááá áá¢á£á ááááá¥áªáááá ášááá«áááá áá§áá¡ áááááááááá£áá ááá¢áá á€ááá¡áá¡ áááá¢á áááá¡ á áááááááá áá á©ááááá  á áááááá ááá§ááááá 
+ááá áááá ááááá¡  ááááá¥áªáá ááá«áááá á¡áášá£áááááá¡  áááášáá áá áá ááá¡á¢áá£ááá¡ áááááááªááá¡ áááááá , á ááááááª ááááááááá£ááá á§ááááá áááá£áááá¢áá¡ ááááá áá ášáá¡áááááá¡á  ááá áááá áá  áááááá áá ááá¡á¢áá£ááá¡ áááá¡áá ááá¡ ááá áášá. 
+áááá¡ááááá¡ á áá ááááá®áá áªááááá áá®ááá á«áááá áá¥ááá ááááá¬ááá áá áá£ááá áá¡ âá£áááâ áŠáááááá¡  ááááá§ááááá. 
+<p>ááá áááá ááááá¡  ááááá¥áªáááá ááá áááá áá«áááá á¡áášá£áááááá¡ áááá®ášáá áá ááá¡á¢áá£ááá¡ ááá€á áá®ááááá,
+ á ááááááª á©ááááá ááášáá  á áááá¡ááª  áá¥ááá áááá­áá á ááá£áá¡, á ááááááª ááááááá¡ ááááá¥áªáá¡á¡ ááá áá, áááášá.
+ ááášáá¡ááááá, áááá ááá ááááá¥áªááá¡ ášáááá®ááááášá áá¥ááá ášáááá«ááá á©áá ááá á«ááááá¡ ášáááááááá¡ áááá áá, á ááááášááª 
+ ááá§áááááá ááá£áááá áá¥áááá áááááááá URL - á , áá£ ááááá¥áªááá¡.
+
+
+_texthelpsearchprefstitle_ [l=ka] {á«ááááá¡ ááá áááá¢á ááá}
+_texthelpsearchprefs_ [l=ka] {
+<p>áá á á¬á§áááá áŠááááá ááááá¢á ááááá¡  ášáá¡áááááá¡á á¢áá¥á¡á¢áá¡ á¢ááá¡ . ááá áááá áá§ááááá¡ á áááá¡á¢á áá¡ áááá¢á ááá¡ 
+(áá®áááá áááá, áá®áááá á¥áááá, áááášááááááá áá  áá¥áá¡ ).  áááá á ááááá¢á ááááá¡ á¡áá¢á§ááááá¡ áááááááááá¡
+(áááááááááá¡ ááááá áá ááá) ášááááá®ááá¡ á£á¯á áá¡ ááááááááá¡ ášáá¡áá«ááááááá, áá á¡ááááá¡, áááá¢áá áá¥áááá ášááááá®áá ááááááá ááá ááá áá€ááª ášááá«áááá áá§áá¡. 
+ááá á¡áááááá á¡á¬á áá€áá áááá áááªá£ááááá¡ á¢áá¥á¡á¢áá¡ ááá¡áá«ááááá
+
+
+
+<p>áá¥ááá ášáááá«áááá ááááá®ááááá âáááááááá ááá£áá ášááááá®ááá¡â á ááááášá,á ááááááª  ááá«áááá á¡áášá£áááááá¡ ááááááášáá áá á¢áá áááááá áááá áá¢áá áááá 
+ áá(&) , áá (|)  áá á (!) . áá¡ ááá«áááá á¡áášá£áááááá¡ á£á€á á áá£á¡á¢áá á©ááááá§áááááá ášááááá®áá. ášáááá«áááá á©áá ááá á«ááááá¡ áá á¥ááá,
+ á ááááááª áááááá¢ááá¡ áá¥áááá¡ áááá  ášááááá®áááá¡ . áá ááááá¡,áá¥ááá ášáááá«áááá ááááááá¢á áááá  ášáááááááá¡ áá ááá áááá ááááá¢ááááá
+ áááá£áááá¢áááá¡ á áááááááá. 
+}
+
+_texttanumbrowseoptions_ [l=ka] {ááááá¥áªááášá ááá€áá áááªáá¡á¡ ááá«ááááá¡ _numbrowseoptions_  ááá áá á¡áááá¡áá¡:}
+
+_textsimplehelpheading_ [l=ka] {á áááá  áááá«ááááá ááá€áá áááªáá  -  ááááá¥áªááášá}
+
+_texthelpscope_ [l=ka] {<p> ášááááá®ááá¡ ááá¥ááááááá¡ áá á  á£ááá¢áá¡ ááááá¥áªáááášá á«ááááá¡ á©áá¡áá¢áá ááááá áá¥ááá ášáááá«áááá á¡á®áááá¡á®áá ááááá¥á¡áááá¡ áá á©ááá. ááááááááá ášááá«áááá áá§áá¡ ááá¢áá áááá¡ áá á¡áááá£á áááá¡ áááá¥á¡ááá. áá ášááá«áááá áá§áá¡ ááááááá¡ áá ááá ááá áá€áááá¡ ááááá¥á¡ááá. á¡ááá ááá áá ááá£á®áááááá áá á©áá£áá ááááá¥á¡áá¡á áááá«áááááá áá¡ááá áááá£áááá¢ááá, á áááááááª ášááá¡ááááááá ášááááá®ááá¡. <p>áá£ ááá«áááá£áá áááá£áááá¢á á¬ááááá, ááášáá ááá áááááášáááá ášáá¡áááááá¡ ááááááá. }
Index: /gsdl/stable/macros/georgian2.dm
===================================================================
--- /gsdl/stable/macros/georgian2.dm	(revision 20131)
+++ /gsdl/stable/macros/georgian2.dm	(revision 20131)
@@ -0,0 +1,819 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Georgian Language text and icon macros 
+# -- this file contains text that is of less importance
+# -- to translate when creating a new interface language
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=ka] {áááá£áááá¢ááá }
+_lastupdate_ [l=ka] {ááááá¡ ááááá®ááá}
+_ago_ [l=ka] {ááŠáá¡ á¬áá.}
+_colnotbuilt_ [l=ka] {ááááá¥áªáá áá  áá áá¡ ášáááááááá.}
+
+_textpoem_ [l=ka] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>may peace and calmness surround you,
+<br>may you reside in the warmth of a summer's haze,
+<br>may the ocean of your travels be as smooth as the polished greenstone.
+}
+
+_textgreenstone_ [l=ka] {<p>áá ááá¡á¢áá£áá áá áá¡ ááá®ááá áá á«ááá á€áá¡á á¥áá, á áááááá¡ (áá áá ááá ááá£áá á£áá á£ááááá§áá€áá¡ áá¡áááá¡áá) ááááááááá áá®áá ááááááááášá. áááá áá¡ á¢á ááááªáá£á á¡ááááááááááášá ááá á§áááááá á£á€á á á«ááá áá áŠáá ááá£áá áá á¡áá¡á£á áááá á¡á£áá¡á¢áááªáá áá áá¡. ááá¡ ášáá£á«ááá ááá¡áá ááá ááá áá áááááá ááá  <i>wairua</i>, ááá áá áá¡ á¡á£ááá¡á áá á¡ááªááªá®ááá¡ á«ááá áá ááá¯ááááááá£ááá á¢á ááááªáá£áá á¡áááááááá áá áááááášáááááááá. áááá¢áá ááá ááá®áá á¡áááááááááá ááá áªáá€á á£áá ááááááááááá¡ áá ááá¥á¢áá¡ ááááááá. ááá¡á áá á¬á§áááááááá áá€á á¥áááá¡ ááá¬á§áááááá¡, ááá¡á áááá­ááá áááááá - ááá¢ááá¡ááááá¡, ááá¡á á¡ááá¢áááªá - á¡ááááááªáá¡ áá ááá¡á ááá¡á á ááá á, á ááááááª ááá¡ ášáá£á«ááá ááááŠáá¡ - á¡áááá ááááááááá¡. ááá¡á áááá­á ááá ááá­áá¢á á, á ááááááª ááááá§ááááá£ááá á áááá áª áá ááá¡áá£ááá¡ áªáá€á á£áá ááááááááááá¡ áááá áá áá¡ <i>patu</i> áá á¡ááá á«ááá á®ááááá¢á áá á¬áá áááááááá¡ á©áááá áá ááá¥á¢áá¡ áá á-áá áá á¬ááá áá¡ áá¯áá®á£á  áááá«á¡. á®ááá©áá áá£á áá á«áááášá ááá¡á ááááá§ááááá áá«áááá á«ááááá á¡á¬á áá€, áá£á¡á¢ áá á¡áááááá ášááááá¡. á©ááá ááá¡á£á á¡ ááá€áá¥á áá á áá áá¡ áááá¡ááááá áááá¡ááááááá á©áááá¡ áá ááá ááá£á á£áá á£ááááá§áá€áá¡, á®ááá ááá¡á ááá¡á á ááá á <i>patu</i> ááá£áááááá¡ áááááááá ááá á¢áá¥áááááááááá¡ á¬ááá§ááá á áááá.
+}
+
+_textaboutgreenstone_ [l=ka] {<p>áá ááá¡á¢áá£áá á¬áá áááááááá¡ áá ááá áááááá¡ ááááááá¥á¢á¡ á ááááááª ááááá£ááááááá áªáá€á á£áá ááááááááááá¡ ááááá¥áªááááá¡ ášáá¥áááá¡á áá áááá áªáááááá¡ááááá¡. ááá áá«áááá ááá€áá áááªááá¡ áá ááááááááá¡á áá ááá¢áá ááá¢áá áá CD-ROM-áá ááááá¥ááá§ááááá¡ áá®áá áááá¡. áá ááá¡á¢áá£áá  ášáá¥áááááá   
+<b>New Zealand Digital Library Project</b> at the <b>University of
+Waikato</b> áááá , áá ááá¡á áááááááá ááá áá áááá áªááááá á®áááá áá  áá áááááááªááá¡ááá áááááášá ááááááá: 
+<b>UNESCO</b> áá <b>Human Info NGO</b>.  ááá áá áá¡ áŠáá áá ááá ááá£áá á£áá á£ááááá§áá€á áá á®ááááá¡áá¬áááááá ášááááá ááá¡áááá ááá:  <a href="http://greenstone.org">http://greenstone.org</a> 
+the GNU General Public License ááá áááááá¡ áááªááá.
+
+<p>áá áá ááá ááá£áá á£áá á£ááááá§áá€áá¡ ááááááá ášáá¡áá«ááááááá ááá¡áªáá¡ áááá®ááá áááááá¡, ááá á«áá á£ááááá á¡áá¢áá¢ááá¡, áááááááááááá¡ áá á¡á®áá á¡áá¯áá á áááá¡áá®á£á áááá¡ ááá¬áá¡ááá£áááááá¡ ášáá¥áááá á¡ááá£ááá á áªáá€á á£áá áááááááááááá. áªáá€á á£áá áááááááááááá á ááááááá£á áá áªááááá áªááááá ááá€áá áááªááá¡ áááá áªáááááá¡á áá áááŠáááá¡ áááááááá¡  UNESCO-á¡ ááá á¢áááá  á¡áááááááááááá¡á áá ááá¬áá¡ááá£áááááášá áááááááááá¡, áááªáááá áááá¡á áá áá£áá¢á£á áá¡ á¡á€áá áááášá ááááá¡ áá¡áá€áááášá áá ááá á«áá, áááááááá áááá á¥ááá§áááášá. á©ááá ááááá áááá¥áá¡, á áá áá¡ áá ááá ááá£áá á£áá á£ááááá§áá€á á®ááá¡ ášáá£á¬á§ááá¡ áªáá€á á£áá ááááááááááááá¡ áá€áá¥á¢á£á  ááááá áááá¡ ááááá¡ áá¡áá€áááášá áá á©ááá§ááááá¡ ááá€áá áááªááá¡ á®ááá®áá¡ á¡ááá¡áá®á£á ášá. 
+
+
+<p>áá áá ááá ááá£áá á£áá á£ááááá§áá€áá¡ ášáá¥ááá áá áááá áªááááá áá áá¡ á¡ááá ááášáá áá¡á áááááášá ááááááá¡ ášááááá á¡áá áá®áá áá¡ ášáá áá¡ 2000 á¬ááá¡ ááááá¡á¢áášá.  
+
+<table border="0">
+<tr valign="top">
+<td>
+<a href="http://nzdl.org"><b>New Zealand Digital Library Project at the University of Waikato</b></a>
+<br>
+áá ááá¡á¢áá£ááá¡ áá ááá ááá£áá á£áá á£ááááá§áá€á áá áá ááá¥á¢áá¡ ááá§áá€áá, á ááááááª áá¥áá áá®áá ááá­áá ááá áá®ááá ááááááááá¡ UNESCO-á¡ ááááá¡ááá¡ áááá£áááááªááááá¡ á¥ááááááá¡ááá¡ áááá , á áááá áª áá®ááá ááááááááá¡ á¬ááááá UNESCO-á¡ áá ááá áááášá. 
+</td>
+<td></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://www.unesco.org"><b>United Nations Educational, Scientific and Cultural Organization</b></a>
+<br>
+ááá€áá áááªááá¡ áááá áªááááá áááááááááá¡, áááªáááá áááá¡á áá áá£áá¢á£á áá¡ á¡á€áá áááášá ááááá¡ áá¡áá€áááášá áá ááá á«áá, áá ááá€áá áááªááá¡ á®ááááá¡áá¬ááááááá áááááááá áááá á¥ááá§áááášá á¬áá áááááááá¡ UNESCO-á¡ áááááá  áááááá¡, á ááááá¡ááª ááá áá®áá áªáááááá¡ á§áááá ááááá¡ áá ááá áááášá áá áááá¢áá, ášáá¡áááááá¡á áá á§ááááá¡ááááá¡ á®ááááá¡áá¬ááááá á¡áááá€áá áááªáá áá á¡ááááá£áááááªáá á¢áá¥ááááááá á¬áá áááááááá¡  áááášáááááááá ááá ááŠá¡ áááªááá£á áááá¢áá¥á¡á¢ášá. 
+</td>
+<td><a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+border="0"></a></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://humaninfo.org"><b>The Human Info NGO, based in Antwerp, Belgium</b></a>
+<br>
+áá¡ áá ááá¥á¢á áá£ášáááá¡ áááá áá¡ á¡ááááááá¢áááá¡á áá á¡á®áá áá áá¡áááááá ááá áá áááááááªáááášá áá ááááá¡ áá¡áá€áááášá ááááááá ááŠááá ááá áá á¡áááááááááá ááá ááá¢áá áá¡á áááá£áááá¢áááá¡ áááªáá€á áááá¡ááááá¡. ááá á£á€áá¡áá áááááááá áááá á¥ááá§ááááá¡ááááá¡, á®ááá á¡á®ááááá¡ááá ááááá®ááá¡ ááááá®áá á¯áááá¡ áááááŠáá£á áááá¡.  
+</td>
+<td><a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" border="0"></a></td>
+</tr>
+</table>
+}
+
+_textdescrselcol_ [l=ka] {ááá á©ááá ááááá¥áªáá}
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=ka] {áááááá  áááá ááá ááááááááá£ááá ááá®á ááááá¢ááááá áŠááááá}
+
+_textnocollections_ [l=ka] {<p> áá ááá¡áá£ááá¡ á¡áááá¡á¢ááááªáá ááááá¢á áá  ášáááªáááá ááááá¥áªáááá¡<ul><li>áááááá§áááá<a href="_httppagecollector_">ááááá¥á¢áá á</a> áá®ááá ááááá¥áªááááá¡ ášáá¡ááááááá    </ul>
+}
+
+_text1coll_ [l=ka] {áá ááá¡á¢áá£ááá¡ á¡áááá¡á¢áááááªáá ááááá¢á ášáááªááá¡ 1 ááááá¥áªááá¡}
+
+_textmorecolls_ [l=ka] {áá ááá¡á¢áá£ááá¡ á¡áááá¡á¢áááááªáá ááááá¢á ášáááªááá¡  _1_ ááááá¥áªááá¡}
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=ka] {ááá á ááá£áá }
+_textlinknotfound_ [l=ka] {ášááá ááá£áá  áá  áááááá®á }
+
+_textextlinkcontent_ [l=ka] {áá á©áá£áá ááá£áá  áá áá¡ ááá á  ááááá¡áááá á áá á©áá£áá  ááááá¥áªááááá¡áááá¡.
+ áá£ ááááááá áá®áááá ááá£áá , ášáááá«áááá <a href="_nexturl_">ááááá¡ááá</a> á áááá ááá; 
+áá áááááá§áááá áá áá£ááá áá¡   âá£áááâ áŠááááá, áááá¡áááá¡ ,á áá áááá á£áááá á¬ááá áááá£áááá¢áá.}
+
+_textlinknotfoundcontent_ [l=ka] {ášááá ááá£áá áá  áááááá§áááá. ášáá¡áá«ááááááá áá§áá¡ ášááªáááá ááááá¥áªááášá.
+<a href="javascript:history.back()">âá£áááâ</a> áááá á£áááá 
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=ka] {
+
+<h3>ááá£áá "_2_" ááááá¥áªáááá</h3>
+
+<p> áá¥áááá¡ áááá  áá á©áá£áá ááá£áá áá áá¡ ááá á  "_collectionname_" ááááá¥áªááá¡áááá¡
+   (áá¡ ááá£áááááá¡ "_2_" ááááá¥áªáááá).
+    áá£ ááááá áá¡á£á á áá®áááá ááá£áá "_2_" ááááá¥áªáááá, 
+    <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">áá¥ áááá­áá áá </a>áá áááááá§áááá áá¥áááá áá áá£ááá áá¡ 
+<a href=javascript:history.back()> "back" </a> áŠááááá á£ááá ááá¡ááá á£áááááá. }
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=ka] {<h3>ááá£áá "_2_" ááááá¥áªáááá</h3>
+
+<p> ááá£áá, á ááááááª ááá á©ááá, áá áá¡ ááá á "_collectionname_"
+    ááááá¥ááá¡áááá¡  (áá¡ ááá£áááááá¡ "_2_" ááááá¥áªáááá).
+   áá£ áá¡á£á á áá ááá£ááá¡  "_2_" ááááá¥áªááášá ááá®áá 
+    <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">ááááááá</a> áá áááá ááá; 
+    áá áááá á£áááá "á£ááá" á¬ááá áááá£áááá¢áá áá¥áááá áá áá£ááá áá¡ "Back" áŠáááááá¡ ááááá§áááááá
+}
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=ka] {áá ááá¡á¢áá£ááá¡ áªáá€á á£áá áááááááááá}
+
+_textusername_ [l=ka] {áááá®ááá ááááá}
+_textpassword_ [l=ka] {ááá ááá}
+
+_textmustbelongtogroup_ [l=ka] {áá¥ááá á£ááá ááááá£ááááááááá áááá®ááá áááááá "_cgiargug_" á¯áá£á€á¡ áááá ááá¡ á¡áááá®áááá.}
+
+_textmessageinvalid_ [l=ka] {áááá ááá¡ á¡áááá®áááá á£ááá ááááá áá ááá¢áá ááááªáá <br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)ášááá¢áááá  áááá®ááá ááááá¡ á¡áá®ááá áá ááá ááá.}
+
+_textmessagefailed_ [l=ka] {áááá®ááá ááááá¡ á¡áá®ááá  áá ááá ááá áá áá¡á¬áá áá .}
+
+_textmessagedisabled_ [l=ka] {áá¥áááá áááá®ááá ááááá¡ á¡áá®ááá ááááášá£ááá. ááá£áááášáá ááá áá áááá ááá¡ ááá ááá¡á¢áá á¡.}
+
+_textmessagepermissiondenied_ [l=ka] {áá¥ááá áá  ááááá©áááá áá áááá ááá¡ ááá®ááá¡ á£á€áááá.}
+
+_textmessagestalekey_ [l=ka] {ášááá¢áááá ááá ááá áááá ááá¡ á¡áááá®áááá.}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=ka] {<p>áá ááá¡á¢áá£ááá¡ á¡áááá¡á¢áááááªáá ááááá¢á áá  ášáááªááá¡ áááá£áááá¢ááªááá¡.
+ášááªááááá¡ áááááá ášááá«áááá áá§áá¡:
+ <ol><li> áá ááá¡á¢áá£ááá¡ á¡áááá¡á¢áááááªáá ááááá¢á   ááááá¡á¢áááá ááá£ááá  cd-rom  áááááá¥á¢ ááá¡ááááá áááááááá£á á á áá¡á£á á¡áááá.
+ <li>áá ááá¡á¢áá£ááá¡ á¡áááá¡á¢ááááªáá ááááá¢á ááááá¡á¢áááá ááá£ááá ááá¢áá ááá¢áááá 
+</ol>
+  áááá£áááá¢ááªááá¡ ááááá¢ááá  ášáá¡áá«ááááááá áá <i>docs</i> ááá áá¥á¢áá ááááá, á ááááááª áááááá¡ááá£ááá áá ááá¡á¢áá£ááá¡  cd rom  áá, áá ááá áááá ááááá <a href="http://www.greenstone.org" target="_blank">http://www.greenstone.org</a>
+}
+
+_textuserguide_ [l=ka] {áááá®ááá ááááá¡ á¡áá®áááá«áŠáááááá }
+_textinstallerguide_ [l=ka] {ááá¡á¢ááááªááá¡  á¡áá®áááá«áŠáááááá }
+_textdeveloperguide_ [l=ka] {ááááááá¡á¢á áá¢áá áá¡ á¡áá®áááá«áŠáááááá }
+_textpaperguide_ [l=ka] {âá¥ááŠááááááá ááááá¥áªááááâ á¡áá®áááá«áŠáááááá }
+_textorganizerguide_ [l=ka] {áá áááááááá áá¡ ááááá§ááááá}
+
+_textgsdocstitle_ [l=ka] {áá ááá¡á¢áá£ááá¡ áááá£áááá¢ááªáá}
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=ka] {á«áá ááááá (á¡áá¡á¢ááá£á áá áááá£ááá¡á®áááá) á¡á¢á á£á¥á¢á£á á}
+_textmore_ [l=ka] {ááá¢á}
+
+_textinfo_ [l=ka] {ááá€áá áááªáá ááááá¥áªááá¡ ášá¬á¡áá®áá}
+_textsrce_ [l=ka] {áááááªáááááá¡ á¬á§áá á}
+_textconf_ [l=ka] {ááááá¥áªááá¡ áááá€ááá£á ááªáá}
+_textbild_ [l=ka] {ááááá¥áªááá¡ ááááá}
+_textview_ [l=ka] {ááááá¥áªááá¡ ááá®áá}
+_textdel_ [l=ka] {ááááá¥áªááá¡ á¬áášáá}
+_textexpt_ [l=ka] {ááááá¥áªáá¡á¡ áá¥ááá á¢áá ááá}
+
+
+_textdownloadingfiles_ [l=ka] {á€ááááááá¡ á©áá¢ááá ááá...}
+_textimportingcollection_ [l=ka] {ááááá¥áªááá¡ ááááá á¢áá áááá...}
+_textbuildingcollection_ [l=ka] {ááááá¥áªáá ááááá...}
+_textcreatingcollection_ [l=ka] {ááááá¥áªáá áá¥ááááá...}
+
+_textcollectorblurb_ [l=ka] {<i>áááááá¡ á£á€á á ááá¢á ášáá£á«ááá áááá á á®áááá¡!
+<br>ááááá¥áªááá¡ ášáá¡áá®áá ááá€áá áááªááá¡ ášáááááá áá áááá áªááááá áá¡áá®ááá¡ áá ááá¡á£á®áá¡ááááááááá¡ á ááááááª áá¥ááá áááá¡á£á ááá ááá¬á§áááááá.
+áá á¡ááááá¡ áá£á áááá£áá á¡ááááá®á á¡áááá¢áá á á£á€ááááá¡ ášáá¡áá®áá: áááá£áááá¢áá¡ á®ááááá¡áá¬ááááááá áá  ááášáááá¡, á áá áá¥ááá ášáááá«áááá ááá¡á áááááªááá á¡á®ááá¡áááá¡.
+áá á¡ááááá¡ á¡ááªáááá£á á á¡ááááá®ááááª:  ááááá¥áªáááá á£ááá ášááá¡áááááááááá¡ áá á¡ááááááááááá¡ áááá-á©áááááá¡, á¡ááááª á¬áá áááášáá áá¡ áááá£áááá¢ááá.
+ááá áá áááá¡á áá á¡ááááá¡ ááááá£á á á¡ááááá®ááá: áááá á áá á£áá áááá áá  á£ááá áá¥ááá¡ á®ááááá¡áá¬ááááá á¡á®ááááá¡áááá¡.  
+<br>ááá®á¡ááááá ááá€áá áááªááá¡ á«ááá áá áááááá§áááá áá¡ áááááá á£ááá. 
+</i> }
+
+_textcb1_ [l=ka] {ááááá¥á¢áá á ááááá®ááá áááá ášáá¥áááá áá®áá ááááá¥áªáá, áááááááááá áá á¡ááá£áá ááááá¥áªáá ,áááááá¢áá  áá á¬áášáááá ááááá¥áªáááá. áááá¡ áááá¡áá®áá áªáááááá áá¥ááá ááááá¬ááá áá®áááá«áŠááááááá ááá  áááá ááááá á áááááááª ááááá®áááá á¡áá­áá á ááá€áá áááªááá¡.}
+
+_textcb2_ [l=ka] {ááá á©ááá á áá¡á áááááááá áá¡á£á á}
+_textcnc_ [l=ka] {áá®ááá ááááá¥áªááá¡ ášáá¥ááá }
+_textwec_ [l=ka] {áá á¡ááá£á ááááá¥áªááá¡ááá áá£ášáááá, ááááá¥áªááášá áááááªáááááá¡ áááááá¢ááá áá á¬áášááá.}
+
+_textcb3_ [l=ka] {áááá¡ááá¡ á áá ášáá¥áááá áá áááááááááá ááááá¥áªáááá áªáá€á á£á ááááááááááášá áá¥ááá á£ááá ááááá áá ááá¢áá ááááªáá. áá¡ áááááªááá áá¥áááá¡ áááááá£á¢áá áá  á¡á®áá áááá®ááá ááááááá¡ ášáá¡áááá¡ááá  áá ááá¡ášá ááá€áá áááªááá¡ ášááªáááá¡ááá.
+<br>
+<i><b>ášáááášááá:</b></i>  ááá¢áá ááááªááá¡ áááááááá áá¥ááá 30 á¬á£ááá¡ ááááááááááášá, áá¥ááá ááá¢áááá¢áá£á áá ááááá®áááá .áá ášáááá®ááááášá, áá¥ááá ášáá«áááá  ááááá áá ááá¢áá ááááªáá ááááááá áá ááááá á«áááá áá¡ áá ááááááááá á¡ááááª ášáá©áá ááá. 
+}
+
+_textcb4_ [l=ka] {ášááá¢áááá áá ááá¡á¢áá£ááá¡ áááá®ááá ááááá¡ á¡áá®ááá áá ááá ááá áá áááá­áá áá áŠááááá¡ âášáá¡áááâ.
+}
+
+_textfsc_ [l=ka] {ááá á©ááá ááááá¥áªáá á ááááááá áá£ášááááá¡ááª áááá ááá.
+}
+
+_textwtc_ [l=ka] {áá á©áá£á  ááááá¥áªááá¡ááá áá£ášáááá.}
+_textamd_ [l=ka] {áááááªáááááá¡ ááááá¢ááá áá ááááá¥áªááá¡ ááááááá ášáááááá.}
+_textetc_ [l=ka] {ááááá¥áªááá¡  áááá€ááá£á ááªááá¡ á€ááááá¡  á áááá¥á¢áá ááá áá ááááá¥áªááá¡ ááááááá ášáááááá.}
+_textdtc_ [l=ka] {ááááááá ááááá¥áªááá¡ á¬áášáá}
+_textetcfcd_ [l=ka] {Windows-á¡áááá¡ áááá ááá¡á¢áááá ááááá áááááá¥á¢ ááá¡ááá¡ ášáá¥ááá}
+_textcaec_ [l=ka] {áá á¡ááá£áá ááááá¥áªááá¡ ášááªááá}
+_textnwec_ [l=ka] {ááááá¥áªááá¡ á©áá¡á¬áá ááá ášáá£á«ááááááá.}
+_textcianc_ [l=ka] {áá®ááá ááááá¥áªááá¡ ášáá¥ááá.}
+_texttsosn_ [l=ka] {áªáá€á á£áá ááááááááááá¡ áá®ááá ááááá¥áªááá¡ ášáá¥ááá á¡áá­áá áááá¡ ášááááá ááááá¯ááá¡.}
+_textsin_ [l=ka] {ááá£ááááá á¡áá®ááá (áá áááááášáá ááá£áá ááá€áá áááªáá)}
+_textswts_ [l=ka] {ááá£ááááá áááááªáááá á¬á§áá áá¡ á¬áá ááášááá.}
+_textatco_ [l=ka] {áááá€ááá£á ááªááá¡ ááá áááá¢á áááá¡ ášáá¡á¬áá ááá (áá®áááá ááªáááá áááá®ááá ááááááá¡áááá¡)}
+_textbtc_ [l=ka] {ááááá¥áªááá¡ âáááááâ}
+_textpvyh_ [l=ka] {á¡ááááá§áá ášáá®áááá áá¥áááá¡ á¥áááááááá¡.}
+
+_texttfsiw_ [l=ka] {áááá ááááá¯á  - âááááá¥áªááá¡ áááááâ , ááááááá¡ ááááá¥á¡ááá¡, áá ááá ááá ááááá¡ ááááá¥áªááá¡ ášáá¡áá®áá ááá€áá áááªááá¡.
+ááááááá, ááá®ááá ááá£ááááá ááá€áá áááªáá}
+
+_textadab_ [l=ka] {ááááá©ááááá ááááá ááá ááá®ááá áááá áááá¡ áááá¡áááŠáá áášá áá£ á¡áá ááá§áá€áááá. áá¬áááá áŠáááááá ááá­áá á ááááááá§áááá ááááááááááá áááá¡ ášááááá ááááá¯áá. áááááááá ááááá¯áá ááááá¡áááá¡ ášááááá áŠáááááá¡ á€áá á ášáááªááááá áá áá¥áááá á§áááááá. á¬ááá áááá ááá ááá¡ááá á£áááááá á¡áá­áá áá á§ááááá áŠáááááá ááá­áá á.  }
+
+_textwyar_ [l=ka] {áááá­áá áá âááá€áá áááªááá¡ ášáá¢áááâ áŠááááá¡, áá®ááá áªáá€á á£áá ááááááááááá¡ ášáá¥áááá¡ áá ááªáá¡áá¡ ááá¡áá¬á§áááá}
+
+_textcnmbs_ [l=ka] {áááááááá£áá á£ááá áá§áá¡ ááááá¥áªááá¡ á¡áá®ááá}
+_texteambs_ [l=ka] {áááááááá£áá á£ááá áá§áá¡ áá-á€áá¡á¢áá¡ ááá¡áááá áá }
+_textpsea_ [l=ka] {ááá£ááááá áá á€áá¡á¢áá¡ ááá¡áááá áá ášáááááá á€áá ááá¢áá: username@domain}
+_textdocmbs_ [l=ka] {áááááááá£áá á£ááá áá§áá¡ ááááá¥áªááá¡ ááŠá¬áá á}
+
+_textwcanc_ [l=ka] {áá®ááá ááááá¥áªááá¡ ášáá¥áááá¡áá¡, á¬áááá¡á¬áá  á£ááá ááá£ááááá  ááá€áá áááªáá áááááªáááá á¬á§áá áá¡ ášáá¡áá®áá. 
+}
+
+_texttfc_ [l=ka] {ááááá¥áªááá¡ á¡áááá£á á:}
+
+_texttctiasp_ [l=ka] {ááááá¥áªááá¡ á¡áááá£á á á£ááá áá§áá¡ ááááá á€á ááá, áááááášáá ááá£áá ááááá¥áªááá¡ ášááááá á¡ááá.}
+
+_textcea_ [l=ka] {á¡ááááá¢áá¥á¢á áá-á€áá¡á¢áá¡ ááá¡áááá áá:}
+
+_textteas_ [l=ka] {áá¡ áá-á€áá¡á¢áá¡ ááá¡áááá áá áá áá¡ ááá áááááá á¡ááááá¢áá¥á¢á ááá¡áááá áá :ááŠááášáá£á ááááá¥áªááá¡ááá áááááášáá áááá ááááá¡áááá á ášáááášáááááá¡á áá£ á¬áááááááááááá¡ ááá¡áááááááá. ášáááá¡áá á€áá áá ášáááááá á€áá ááá¢áá:
+<tt>name@domain</tt>.
+}
+
+_textatc_ [l=ka] {ááá€áá áááªáá ááááá¥áªááá¡ ášáá¡áá®áá:}
+
+_texttiasd_ [l=ka] {áá ááá¡á¢á á£á¥áªááášá ááŠá¬áá áááá áá áááªááááá á áááááá ááááá§ááááááááª  áá§á ášáá¢ááááá áááááªááááá ááááá¥áªááášá.
+ áá¡ ááá€áá áááªáá ááááááá¡áááá ááááá¥áªááá¡ ááá ááá áááá ááá.
+}
+
+_textypits_ [l=ka] {áá¥áááá áááá®ááááá¡ áááááªáá áááááááá£ááá áá¡á áá âááá€áá áááªááâ á áááá¡á¢á ášá.
+  ááá¡ááá«ááááááá áááá­áá áá âáááááªáááá á¬á§áá áâ áá¬áááá áŠááááá¡ 
+  }
+
+_srcebadsources_ [l=ka] {<p>áá¥áááá¡ áááá   áááááááá£áá  á¬á§áá áááá ááá£á¬áááááááá.(ááááášáá£ááá 
+_iconcross_ á¯áá áá).
+
+
+<p>áá¡ ášáá¡áá«ááááááá ášáááááá ááááááá¡ áááá.
+ <ul><li> ftp ááááá«á áá url ááá£á¬áááááááá
+<li>ášááááá¬ááá áá¥áááá ášááá áááá ááá¢áá ááá¢ááá ( á£ááá ááá£ááá¥áášáá ááá  ááá¢áá ááá¢ á¡áá ááá¡ áá ááááááá á¡ ISP).
+<li> áá¥ááá á£ááá á¡áªáááá ááá£áááášáá ááá url á ááááááª FIREWALL  áá áá áá¡ áááªá£áá ( áá£ ááá áááá£á áá á¬áá á£ááááá áááá®ááá ááááá¡ á¡áá®ááá¡ áá ááá ááá¡ ááá£áááášáá ááááá ááá¢áá ááá¢á¡ áá á áááá¡á¢á áá.)
+
+<p> url á ááááá¡ááª áá¥ááá á®ááááá áá áá£ááá ášá ášáá¡áá«ááááááá áááááá£á á áááš á©áááá¬áá áááá áááááááá¡.á¡ááá¬á£á®áá áá áááááá£á á áááš á©áááá¬áá á á©ááá áá ááªáá¡ášá á£á®áááááá. áá á áááá¡á¢á ášá á áááááááááá£ááá á¯áá  á©áá¢ááá ááá ááááá§ááááá£áá áááá áááá áá¥áááá¡ áá áá£ááá ášá.
+
+}
+
+_textymbyco_ [l=ka] {<p>ášáá¡áá«ááááááá ášáááááá á¡á¢á á£á¥á¢á£á áá¡ ááááá¥áªááááá¡ ááááá.
+<ul>
+   <li>á«áá ááááá á¡á¢á á£á¥á¢á£á á
+         <dl><dd> áá®ááá ááááá¥áªáá ášááá«áááá ášáááªááááá¡ html áááá£áááá¢ááá¡(.htm. html), á©ááá£áááá ááá á¢áá¥á¡á¢á£á á   áááá£áááá¢ááá (.txt,.text), ms word áááá£áááá¢ááá (.doc),pdf áááá£áááá¢ááá(.pdf)âm-boxâ áá-á€áá¡á¢áá¡ á€áá ááá¢áá áááá¡ áááá£áááá¢ááá(.mbx) </dd></dl>
+    <li> áá á¡áá¡áá£áá ááááá¥áªáá
+           <dd>áá®ááá ááááá¥áªááá¡ á€áááááá á£ááá áá£á¡á¢áá ášááá¡ááááááááááá á¢ááá¡ á áááááááª ááááá§ááááá£áá áá§á áá á¡ááá£áá ááááá¥áªááá¡ ášáá¥áááá¡áá¡.
+   </dd></dl>
+</ul> }
+
+_textbtco_ [l=ka] {ááááá¥áªááá¡  áááá}
+_textand_ [l=ka] {áá®ááá áááááªáááááá¡ ááááá¢ááá}
+_textad_ [l=ka] {áááááªáááááá¡ ááááá¢ááá:}
+
+_texttftysb_ [l=ka] {áá¥áááá¡ áááá  áááá¡áááŠáá á£áá á€áááá áááááá¢ááá ááááá¥áªááá¡. ááá á¬áá£áááá áááášá, á áá  á®áááá®áá áá  ášáááá¥áá á£ááá ááááá¢ááá£áá á€áááá ááááá¥áªááášá: á¬áááááŠáááá ášáááá®ááááášá ááááá¥áªááášá áááááá¡ááá£ááá áá¥áááá áá á áá¡áá . }
+
+_textis_ [l=ka] {á¬á§áá á:}
+
+_textddd1_ [l=ka] {<p> áá£ áá§ááááá file:// áá ftp:// ááášáá ááá£ááááá á©áá¡áá¢ááá áá á€ááá.
+      <p> áá£ áá§ááááá http://  ááášáá á€ááááááá¡ á©áá¢ááá ááá áááááááááá£ááá ááááá áá£ á áááá áá á¬áá ááááááááá áááªááá£áá URL - áá©áááááá¡ áá á áááá áá¡, áá£ ááá áá¥á¢áá ááášá á€ááááááá¡ á¡ááá¡. 
+
+áááá­áá áá More Sources áŠááááá¡, áá£ áá¡á£á á ááá¢á á¬á§áá áá¡ áááááááá}
+
+_textddd2_ [l=ka] {áá£ áááááªáááá áááá®ááá ááááá á®áá á, áá¬áááá áŠáááááá áááá­áá áá,  ášáááá«áááá ášááá¡á¬áá áá áááá€ááá£á ááªáá. ááá¢áá ááá¢áá£áá ááá áááá¢á áá£ ááááá®áááá ááááá¥áªááá¡ ášáá¥ááá¡ á¡áá€áá®á£á áá. ááá®á¡ááááá, áá¥ááá ášáááá«áááá  ááá£áá á£áááá ááá ááááá á¡áá€áá®á£á áá á§áááááá áŠáááááá¡ ááá­áá áá.}
+
+_textconf1_ [l=ka] {ááááá¥áªááá¡ ášáá¥ááá áá á¬áá ááááááá áááá¢á áááááá á¡áááªáááá£á  âáááá€ááá£á ááªááá¡ á€áááášáâ. 
+ áááááªááá áááá®ááá ááááá¡ ášáá£á«ááá áááá€ááá£á ááªááá¡ ášááªááá.   
+ <center><p><b>áá£ áá  á®áá á áááááªáááá áááá®ááá ááááá, ááááááá áááá ááá</b></center>
+<p>áááá€ááá£á ááªááá¡ ášááªáááá¡áááá¡  áááá§áááá áááááªáááááá¡ á áááá¥á¢áá ááááá. áá ášáááá®ááááášá áá£ ááášáááá£áá ášááªáááá áááá­áá áá áŠááááá¡ âáááááááâ áááá¡áááá¡, á áá, áá®áááááá ášáá«ááá áááá€ááá£á ááªááá¡ ááá§ááááá.
+}
+
+_textreset_ [l=ka] {ááááááá}
+
+_textbild1_ [l=ka] {ááááá¥áªáá ááááá: áá ááªáá¡á á¡áá­áá áááá¡ ááá áááá£á áá áá¡. 
+}
+
+_textbild2_ [l=ka] {áááá¡áááá¡ á áá, ášááá©áá áá ášáá¥áááá¡ áá ááªáá¡á áá¥ áááá­áá áá.
+<br>ááááá¥áªáá á áááááááª áá¥ááá áá£ášáááááá á®ááášáá£á®ááááá ááá á©ááá
+}
+
+_textstopbuild_ [l=ka] {ááááá¥áªááá¡ ášáá¥áááá¡ ášáá©áá ááá.}
+
+_textbild3_ [l=ka] {áá£ áá¥ááá ááááá®ááááá áááá ááááá (áá áá  á£áá á§ááá áá ááªáá¡á¡ âáááááá¡ ášáá©áá áááâ áŠáááááá¡ á¡áášá£áááááá) ááááá¥áªáá ááááá á«ááááá¡ ášáá¥áááá¡ áá ááªáá¡á¡ áá áááááá¡á¢áááá ááá¡ ááá¡ .
+}
+
+_textbuildcancelled_ [l=ka] {ááááá¥áªááá¡ ááááá ášáá¬á§áá}
+
+_textbildcancel1_ [l=ka] {ááááá¥áªááá¡ áááááá¡ áá ááªáá¡á ášáá©áá ááá£ááá . 
+áááááá§áááá á§áááááá áŠááááá áááá¡áááá¡, á áá ášááªááááá ááááá¥áªáá áá  ááááááá ááá£ášááá áááááá¡ áá ááªáá¡á.}
+
+_textbsupdate1_ [l=ka] {áááááá¡ á¡á¢áá¢á£á¡áá¡ ááááá®áááá á®áááá 1 á¬ááášá}
+_textbsupdate2_ [l=ka] {áááááá¡ á¡á¢áá¢á£á¡áá¡ ááááá®áááá }
+_textseconds_ [l=ka] {á¬ááááá}
+_textbildsuc_ [l=ka] {ááááá¥áªáá á¬áá ááá¢áááá ášááá¥ááá.}
+
+_textviewbildsummary_ [l=ka] {ááááá¥áªááá¡ áááááá¡ ááááá¢ááááá ááá¢ááááá ášáááá«áááá ááá®áá ááááá¥áªááá¡ 
+<a href="_httppagex_(bsummary)&c=_cgiargbc1dirname_" target=_top>ášáá¥áááá¡ á áááá£ááášá 
+</a> .
+}
+
+_textfailmsg11_ [l=ka] {ááááá¥áªááá¡ ášáá¥ááá ášáá£á«ááááááá á ááááá áá¡ áá  ášáááªááá¡ áááááªááááá¡. ááá á¬áá£áááá á áá, <i> áááááªáááá á¬á§áá áá¡</i>áááá áášá áááá¡áááŠáá á£áá ááá áá¥á¢áá ááááááá áá á€ááááááááá  áá áá áááááª áá á¡ááááá¡ áá á áááá á€áááášá áá¡ááá á¢áááá¡áá á áááááááª áá ááá¡á¢áá£áá  ááá£ášáááá¡. }
+
+_textfailmsg21_ [l=ka] {ááááá¥áªáá ááá  ášááá¥ááááá(import.pl ášááªáááá).}
+_textblcont_ [l=ka] {ášáá¥áááá¡ áááá ášáááªááá¡ ášááááá ááá€áá áááªááá¡:}
+
+_texttryagain_ [l=ka] {<a href="_httppagecollector_" target=_top>ááááá¢ááá ááá ááááá¥á¢áá á </a> áá 
+á¡áªáááá ááááááá.
+}
+
+_textfailmsg31_ [l=ka] {ááááá¥áªáá ááá  ášááá¥ááááá (buildcol.pl ášááªáááá)}
+_textfailmsg41_ [l=ka] {ááááá¥áªáá á¬áá ááá¢ááá£ááá ášááá¥ááá, ááá áá ááá  ááááá¡á¢áááá áá.}
+_textfailmsg71_ [l=ka] {ááááá¥áªááá¡ ášáá¥áááá¡ ááªááááááá¡ áá áá¡  á¬áá áááášáá ááá£ááááááá ášááªáááá.}
+_textretcoll_ [l=ka] {ááááá¥á¢áá áá áááá á£áááá }
+
+_textdelperm_ [l=ka] {á§áááá áá á ááááááááá  _cgiargbc1dirname_ ááááá¥áªáá ááá  á¬ááášáááá. . áá¡ ášáá¡áá«ááááááá ášáááááá ááááááááá¡ áááá.:
+<ul>
+<li> áá ááá¡á¢áá£áá¡ áá  áááá©ááá  _gsdlhome_/collect/_cgiargbc1dirname_
+ááá áá¥á¢áá ááá¡ á¬áášááá¡ á£á€áááá.<br>
+ášáááá«áááá áááááá¢áááá áá ááá áá¥á¢áá ááá¡ ááá¡á¢á á£á¥áªáá áááá¡áááá¡ ,á áá _cgiargbc1dirname_
+ááááá¥áªáá áááášáá áá áá áááááá£á¢áá áááá .<li>
+<li>áá ááá¡á¢áá£áá¡ áá  ášáá£á«ááá áá ááá áááá¡ ááášáááá _gsdlhome_/bin/script/delcol.pl. ááá á¬áá£áááá áááášá á áá á€áááá ááááá®ááá áá ášáá¡áá«ááááááá ááá¡á ááášáááá.</li>
+</ul>
+}
+
+_textdelinv_ [l=ka] {ááááá¥áªáá _cgiargbc1dirname_ áááªá£ááá áá áá áá¡á¬áá áá. á¬áášáá á£áá á§áá€áááá.
+}
+
+_textdelsuc_ [l=ka] {ááááá¥áªáá _cgiargbc1dirname_ á¬áá ááá¢ááá£ááá á¬ááášááá.}
+
+_textclonefail_ [l=ka] {ááááá¥áªááá  _cgiargclonecol_ ááá  á£áá á£ááááá§á ááá¡ááá£á¢á£á á  ášááááá¡ááá. <br> áá¡ ášáá¡áá«ááááááá ášáááááá ááááááááá¡ áááá:<ul>
+<li> ááááá¥áªáá _cgiargclonecol_ áá  áá á¡ááááá¡
+<li> ááááá¥áªáá _cgiargclonecol_ áá  áááá©ááá collect.cfg áááá€ááá£á ááªááá¡ á€áááá
+<li> áá ááá¡á¢áá£áá¡ áá  áááá©ááá  collect.cfg áááá€ááá£á ááªááá¡ á€ááááá¡ á¬ááááá®ááá¡   á£á€áááá.
+</ul>
+}
+
+_textcolerr_ [l=ka] {ááááá¥á¢áá áá¡ ášááªáááá.}
+
+_texttmpfail_ [l=ka] {ááááá¥á¢áá áá¡ á¬ááááá®ááá¡ áá á©áá¬áá áá¡ ášááªáááá ášá£ááááá£á  á€áááášá áá ááá áá¥á¢áá ááášá. 
+áá¡ ášáá¡áá«ááááááá ášáááááá ááááááááá¡ áááá: 
+<ul>
+<li> áá ááá¡á¢áá£áá¡ áá  áááá©ááá á¬ááááá®ááá¡ /á©áá¬áá áá¡ á£á€áááá gsdlhome_/tmp ááá áá¥á¢áá ááášá.</ul>
+}
+
+_textmkcolfail_ [l=ka] {áá®ááá   ááááá¥áªááá¡áááá¡ ááá áá¥á¢áá ááá¡ ášáá¥áááá¡áá¡  (mkcol.pl failed) ááááá¥á¢áá áá¡ ášááªáááá. áá¡ ášáá¡áá«ááááááá ášáááááá ááááááááá¡ áááá.
+       
+ <ul><li>áá ááá¡á¢áá£áá¡ áá  áááá©ááá ááá áá¥á¢áá ááášá _gsdlhome_/tmp á©áá¬áá áá¡ á£á€áááá 
+  <li> mkcol.pl -á¡ ášááªáááá ášááªáááá.</ul>
+ 
+
+}
+
+_textnocontent_ [l=ka] {ááááá¥á¢áá áá¡ ášááªáááá : áá®ááá áááá¥áªááá¡áááá¡ á¡áá®ááá  áá  áááááááá£áá. ááááá¢ááá ááá ááááá¥á¢áá á.
+}
+
+_textrestart_ [l=ka] {ááááá¥á¢áá áá¡ ááááá¢ááá ááá}
+
+_textreloaderror_ [l=ka] {áá®ááá ááááá¥áªááá¡ ášáá¥áááá¡ áá áá¡ á¬áá áááášáá ášááªáááá.  áááááá§áááá  áá áá£ááá áá¡ âááááá®ááááâ  áá âá£áááâ (ááªáááá áá  áááááá§áááá áá¡ áŠááááááá á áááá¡ááª á¥áááá ááááá¥áªááá¡ áááá¥á¢áá áá¡ ááááá§áááááá). á áááááááááá£ááá ááááá¢ááá ááá ááááá¥á¢áá á .}
+
+_textexptsuc_ [l=ka] {ááááá¥áªáá_cgiargbc1dirname_ á¬áá ááá¢ááá£ááá ááááááááááá  
+_gsdlhome_/tmp/exported__cgiargbc1dirname_ ááá áá¥á¢áá ááášá.
+}
+
+_textexptfail_ [l=ka] {<p> ááááá¥áªááá¡_cgiargbc1dirname_ áááá á¥á¢áá ááášá áá®á¡ááá á¢áá¡ áá áááááá.
+
+<p>áá¡ ášáá¡áá«ááááááá ááá®áá áááá¡ áááá, á áá áá ááá¡á¢áá£áá áá§á ááááá¡á¢áááá ááá£áá
+ â ááááá¥áªááá¡ áá¥á¡ááá á¢áá¡â á€á£áá¥áªááá¡ áá£áªááááááá ááááááááá¢áááá¡ á£áá á£ááááá§áá€áá¡ ááá áášá.<ul>
+
+ <li>áá£ áá ááá¡á¢áá£áá ááááá¡á¢áááá áá ááááááá¢ ááá¡ááááá áá¡ ááááááááá¢ááá áá  ááááá¡á¢áááá áááá á¡áááá áá¥ááá áá  ááááá á©ááá  áááâCustomâ-áá¡  ááá¡á¢ááááªááá¡ áá áá¡. ášáááá«áááá áááááá¢áá áá¡ááá ááá¡á¢ááááªááášá, ááá¡á¢ááááªááá¡  áá ááªááá£á áá¡ ááááááá ááášááááá.
+
+ <li>áá£ áá ááá¡á¢áá£ááá¡ á¡áááá¡á¢ááááªáá ááááá¢á ááááá¡á¢áááá ááá£ááá ááá¢áá ááá¢áááá ,ááááá¬ááá á©áá¢ááá ááá áá áááááá¡á¢áááá áá   á€á£áá¥áªááá¡ ááááá¢á. ááááá ááá
+<a href="http://www.greenstone.org">http://www.greenstone.org</a>
+ áá áá ááá¡áááá áá¡ <a
+ href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>
+ ááááá¢ááááá ááá¢áááááá¡áááá¡.
+</ul>
+}
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=ka] {132. áá ááá¡á¢áá£áá ášááá¡ááááááá áá ááá ááá£á á£áá á£ááááá§áá€áá¡ á ááááááª ááá¡áá®á£á ááá áªáá€á á£á ááááááááááá¡ ááááá¥áªáááá¡ áá áá®áá ááááá¥áªááááá¡ ášáá¥áááá¡. áá¡ á£áá á£ááááá§áá€á¡ áá®áá ááááá¡ ááá€áá áááªááá¡ áá áááááááªááá¡áááá¡ áá ááááá¥á§ááááááá¡áááá¡ ááá¢áá ááá¢ášá áá ááááááá¢ ááá¡ááá. áá ááá¡á¢áá£áá ááááášáááá£ááá áááááá¢áá¡ á£ááááá á¡áá¢áá¢áá¡ áááá  áá®áá ááááááááá¡ áªáá€á á£áá ááááááááááá¡ áá ááá¥á¢áá¡áááá¡ áá  ááá áªáááááá  áááá ááá ááªááášá UNESCO-á¡á áá HUMAN INFO NGO-ááá áá ááá. áá ááá¡á¢áá£ááá¡ áá ááá ááá£áá á£áá á£ááááá§áá€áá¡ á¬á§áá áá¡  <i> http:// greenstone. org </i>  GNU General Public License ááá áááááá¡ ááááá§áááááá.
+}
+
+_textgreenstone2_ [l=ka] {áá®ááá ááááááááá¡   áªáá€á á£áá ááááááááááá¡ ááá á¡ááá¢á(<a
+href="http://nzdl.org">http://nzdl.org</a>) ášáááªááá¡ á£ááá ááá ááááá¥áªááá¡ áááááááá¡ ,á áááááááª ášáá¥áááááá áá ááá¡á¢áá£ááá¡ áá ááá ááá£áá á£áá á£ááááá§áá€áá¡ ááááá§áááááá áá ááááá¥ááá§áááá£ááá áááá¡áááá¡ á áá  á§á£á áááŠáááá ááááªááá ááá.  ááááá¥ááá§áááá£ááá  á¡á®ááááá¡á®áá á«ááááá¡ áá ááá¢áá ááá¢áá£áá ááááááááá áááá¡ áááááááááá, áá áá¡ááá ášáááªáááá ááááá¥áªáááá¡ áá ááá£á ,á©ááá£á , á€á áááá£á, áááá áá£á, áá¡áááá£á   áááááá  áá¡ááá á áááá áª áááááá¡á£á áá. áá¡ááá áááá©áááá á áááááááá áá£á¡ááááá£á á ááááá¥áªáá.}
+
+_textplatformtitle_ [l=ka] {ááááá€áá áá}
+_textgreenstone3_ [l=ka] {134. áá ááá¡á¢áá£áá áá£ášáááá¡ Windows-ášá áá Unix-ášá. ááá¡ááá áªááááááá ááá á¡áá ášáááªááá¡ ááááá§áááááá¡  áá áááá áááá¡ Windows á§áááá ááá á¡ááá¡áááá¡ áá linux- á¡áá¡áááá¡. áá¡ááá ášáááªááá¡ ááááááá¡ á¬á§áá áá¡ á§áááá á¡áá¡á¢áááá¡áááá¡ á ááááááª ááááááááá£ááá Microsoft C++ áá gcc  ááááá§áááááá¡áááá¡. áá ááá¡á¢áá£áá áá£ášáááá¡ áááá ááááááá£á áá ááá ááá£á á£áá á£ááááá§áá€áá¡ááá, á ááááááª áá¡ááá á®ááááá¡áá¬áááááá : Apache Webserver áá PERL -á¡ááááá¡. áá¡ ááááá§ááááááá ááá¢áá á€ááá¡á áá§ááááá¡ ááá áá áá£ááá á¡; á¢áááá£á áá Netscape Navigator áá Internet Explorer.  }
+
+_textgreenstone4_ [l=ka] {ááááá¥áªááááá¡  áááá£áááá¢áááá¡ á£áá ááááá¡ááá áááá áªááááá£ááá ááááááá¢ ááá¡ááá áá ááá¡á¢áá£ááá¡ áá ááá ááá£áá á£áá á£ááááá§áá€áá¡ ááááá§áááááá. ááááááááá¡áááá¡ <i> Humanity Development Library</i>ášáááªááá¡ 1,230 áá£ááááááªáááá¡. áá¡ áá£ášáááá¡ áááááááá£á  áááá áá¢á£á á£á áááá®áááááááá á ááª á¢áááá£á áá áááááááá áááá á¥ááá§áááášá. ááá€áá áááªááá¡ ááá¡ááŠáááá ášááá«áááá áááááá§áááá á«áááá , ááááááá¡, á¡áááá£á áááá¡ áá áááááááªááááá¡ ááááááááá ááá ,á¡ááá¡ ááááááááá ááá áá á¬ááááááá¡ á§ááááá¡ ášáááá®áááááá ááááááááá ááá.}
+
+_textcustomisationtitle_ [l=ka] {áááááá€ááá£á áá ááá}
+_textgreenstone5_ [l=ka] {áá ááá¡á¢áá£áá áá¡áá ášááá£ášááááá£áá á áá ááá«áááá á¡áášá£áááááá¡ ááá¥á¡ááááá£á áá áááá€áá ááááá áá ááááááá€ááá£á áá áá ááá. áá®ááá áááá£áááá¢ááá áá ááá¢áááá¢áá¡ á€áá ááá¢ááá ááá¬áá áááá  âáá ááá áááá¡ ááááá¢ááááâ (perl ááááá) . áááááááá£á áá  áá®ááá ááá¢áááá¢áá¡ ááááááááá áááá¡ á¡á¢á á£á¥á¢á£á ááá ááá¬áá áááá âáááá¡áá€áááá¢áá áááá¡â á¡áášá£áááááá.  áááá®ááá ááááá¡ ááááá§ááááááá ááá¢áá á€ááá¡á ášááá«áááá ášáááªááááá¡ âáááá áá¡áááá¡â á¡áášá£áááááá ,á ááááááª ááá¬áá áááá áááá áá¡ ááá á¢ááá ááááá. Cobra áá áá¢ááááá ááááá¢ááá¡ áá«áááá¡ á¡áášá£áááááá¡  áááááá§áááá á§áááá á¡áášá£ááááááá á áááááááª áááááášáá ááá£ááá ááááá¥áªááááá¡ áááá£áááá¢ááá (áá.Java-ášá).  á¡ááááááá  ááááá¡ááááá áá ááá ááá C++-ášá áá Perl-ášá ááááá€ááªáá áááá.
+}
+
+_textdocumentationtitle_ [l=ka] {áááá£áááá¢ááªáá}
+_textdocuments_ [l=ka] {á®ááááá¡áá¬áááááá áá ááá¡á¢áá£ááá¡ ááá¬áá ááááááá áááá£áááá¢ááªáá}
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=ka] {ááááááá ááá¡á¢á}
+_textmailinglist_ [l=ka] {áá á¡ááááá¡ á¡áááá¡áá£á¡áá ááááááááá¡ áá£á¡á®á (mail list)  , á ááááááª ááááá£ááááááá  áá ááá¡á¢áá£ááá¡ áªáá€á á£áá ááááááááááá¡ áá ááá ááá£á á£áá á£ááááá§áá€áá¡ ášáá¡áá®áá  áá¡á¯áááááá¡áááá¡. áá ááá¡á¢áá£ááá¡ áá¥á¢áá£á á  áááá®ááá ááááááá á£ááá ááááá®áááá ááááááááá¡ áá£á¡á®áá¡ááá áááá áááá áá ášááááááá ááá¡áá£á¡ááášá.
+ááá¬ááá ááááááá¡áááá¡ ááááááá <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+
+á¡ááá¡áááá¡ ášáá¢á§ááááááá ááááááááá ášááááá ááá¡áááá ááá <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>.
+}
+
+_textbugstitle_ [l=ka] {ášááªáááááá}
+_textreport_ [l=ka] {ááá¡á£á á¡ áááá á¬áá£áááá áááášá , á áá , áá¡ áá ááá ááá£áá á£áá á£ááááá§áá€á áá¥ááááááá¡ ááááá¡áá§áááááááá. áááááááááááááá ááááá¡áááá á ášááªáááááá áá ááá¡áááá ááá
+<a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>
+}
+
+_textgs3title_ [l=ka] {ááášá ááááášá}
+# -- Missing translation: _textgs3_
+
+_textcreditstitle_ [l=ka] {áá ááá¡á¢áá£ááá¡ ášááá¥áááááá á¡áá }
+
+_textwhoswho_ [l=ka] {áá ááá¡á¢áá£ááá¡ áá ááá ááá£áá á£áá á£ááááá§áá€á á¬áá áááááááá¡ áááá á ááááááááá¡ ááááá¥á¢áá£á  ááášá ááá¡. á áá¯áá  ááááááá áá á¡á¢áá€áá áááá áá ááá áááááá á áá á¥áá¢áá¥á¢áá ááá áá ášáááá¥áááááá. ááááá¬áááááá ááááŠáá¡ ááá áááá ááááá áááááá áá¯áá, á¯áá á¯ áá£á®áááááá, á°ááá á©áááá, ááááá ááá£á¡ááááá, ááá¢áá áá ááááá, áááá áááááá áá, ááá á áá£á¢ááááá, á¯áá€ á°áááá¡áá, áááá áááá€áá á¡áááá, áá ááá ááááá-áááááááá, ááááá ááá¢áááá, ááá ááá ááááá¢áá áá, ááá áá°áá á áá€áá ááááá áá, á¢áá á áááá, ááá á áá¯áá á¡áá, á¯áá á¢ááá¡áááá áá á¡á¢áá£áá á¢ áááá¢á¡áá. áá®ááá ááááááááá¡ áªáá€á á£áá ááááááááááá¡ áá ááá¥á¢áá¡ á¡á®áá á¬ááá áááá: ááá á áááá ááá, á¡ááá á¯á áááááááááá, ááá¢ á¯áá£áá¡áá, á¡á¢áá á¯áá£áá¡áá, á¢á á¢ááá ááááááá, ááááá áá£á¢á¡áá, áááááá ááá°áá£áá, ááá á ááá á¡ááááá, áááá áááááá¡áá áá áááá á¡ááááá ááááá¬áááááá ááááŠáá¡ áááááááá á á©áááááá á¡áá¡á¢áááá¡ ášáá¥áááá¡ áá áá¡. á©ááá ááá áááá ááááááááá ááá á á§ááááá¡á ááááª ááááá¬áááááá ááááŠá MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE áá XLHTML ááááá¢áááá¡ áááªááááá áááášá áá áááá áªáááááášá. }
+
+_textaboutgslong_ [l=ka] {áá ááá¡á¢áá£ááá¡ ášáá¡áá®áá}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=ka] {áááá®ááá áááááá á¡áá }
+_textuser_ [l=ka] {áááá®ááá ááááá
+
+}
+_textas_ [l=ka] {ááááá áášáá¡ á¡á¢áá¢á£á¡á}
+_textgroups_ [l=ka] {á¯áá£á€ááá}
+_textcomment_ [l=ka] {áááááá¢áá á}
+_textadduser_ [l=ka] {áá®ááá áááá®ááá ááááá¡  ááááá¢ááá}
+_textedituser_ [l=ka] {ášáá¡á¬áá ááá}
+_textdeleteuser_ [l=ka] {á¬áášáá}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=ka] {áááá®ááá ááááá¡ ášáá¡áá®áá ááá€áá áááªááá¡ á áááá¥á¢áá ááá}
+_textadduser_ [l=ka] {áá®ááá áááá®ááá ááááá¡ ááááá¢ááá}
+
+_textaboutusername_ [l=ka] {áááá®ááá ááááá¡ á¡áá®áááá¡ á¡ááá á«á á£ááá áá§áá¡ 2-30 á¡ááááááááá. ááá ášááá«áááá ášáááªááááá¡ á áááá áª ááááááá¡ áá¡ááá áªáá€á áááá¡ áá â.âáá â_â á¡ááááááááá¡.
+}
+
+_textaboutpassword_ [l=ka] {ááá áááá¡ á¡ááá á«á á£ááá áá§áá¡ 3-128 á¡áááááá. ááá ášááá«áááá ášáááªááááá¡ á©ááá£áááá áá ASCII  á¡ááááááááá¡.
+}
+
+_textoldpass_ [l=ka] {áá£ áááªááá£áá áááá áªáá ááááá , áá ášáááá®ááááášá á«áááá ááá ááá áááááá§ááááá.}
+_textenabled_ [l=ka] {ááášáááá£áá}
+_textdisabled_ [l=ka] {ááá£ášáááááá}
+
+_textaboutgroups_ [l=ka] {á¯áá£á€ááá ááááá§áá€áááá áá«ááááááá áá ááá ášááááá áá  áá¡áááá âášá£áááááâ.
+}
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=ka] {áááá®ááá ááááá¡ á¬áášáá}
+_textremwarn_ [l=ka] {ááááááááá áá¡á£á á á¡ááááááá áááá®ááá áááááá¡ á¬áášáá <b>_cgiargumun_</b>?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=ka] {ááá áááá¡ ášááªááá}
+_textoldpw_ [l=ka] {á«áááá ááá ááá}
+_textnewpw_ [l=ka] {áá®ááá ááá áááá¡ }
+_textretype_ [l=ka] {áá®ááá ááá áááá¡  á®áááá®áá ášáá¢ááá}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=ka] {ááá ááá á¬áá ááá¢ááá£ááá ášáááªáááá.}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=ka] {áááá®ááá ááááá¡ á¡áá®ááá áá áá¡á¬áá áá.}
+_textinvalidpassword_ [l=ka] {ááá ááá áá áá¡á¬áá áá.}
+_textemptypassword_ [l=ka] {ááá®ááá ášááá¢áááá áááá®ááá ááááá¡ áááááááá áááá ááá ááá.}
+_textuserexists_ [l=ka] {áááá®ááá ááááá¡ á¡áá®ááá áááááááá£ááá, ááá®ááá , ášááá¢áááá á¡á®áá á¡áá®ááá.}
+
+_textusernameempty_ [l=ka] {ášááá¢áááá áááá®ááá ááááá¡ á¡áá®ááá.}
+_textpasswordempty_ [l=ka] {á£ááá ášááá¢áááá á«áááá ááá ááá.}
+_textnewpass1empty_ [l=ka] {ášááá¢áááá áá®ááá ááá ááá áá ááááááá áá ááá.}
+_textnewpassmismatch_ [l=ka] {áá¥áááá ááá ááá áá áá¡á¬áá áááá áááááá ááá£áá.}
+_textnewinvalidpassword_ [l=ka] {ášáá¢ááááá ááá ááá áá áá¡á¬áá áá.}
+_textfailed_ [l=ka] {áááá®ááá ááááá¡ á¡áá®ááá áá ááá ááá áá áá¡á¬áá áá.}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=ka] {áá áá¡áá¢áá£ááá¡ ááá á¡áá #}
+_textframebrowser_ [l=ka] {áááá¡áááá¡ á áá áá¡ áááá áá ááá®áá, áá¥ááá áá áá£ááá á¡ á£ááá á°á¥ááááá¡ âá€á ááááááá¡â áá®áá ááá­áá á.}
+# -- Missing translation: _textframebrowser_
+_textusermanage_ [l=ka] {áááá®ááá áááááá ááá ááá}
+_textlistusers_ [l=ka] {áááá®ááá áááááá á¡áá}
+_textaddusers_ [l=ka] {áá®ááá áááá®ááá ááááá¡ ááááá¢ááá}
+_textchangepasswd_ [l=ka] {ááá áááá¡ ášááªááá}
+_textinfo_ [l=ka] {á¢áá¥áááá£á á ááá€áá áááªáá}
+_textgeneral_ [l=ka] {áááááá áá ááá€áá áááªáá }
+_textarguments_ [l=ka] {áá áá£áááá¢ááá}
+_textactions_ [l=ka] {áááá ááªáááá }
+_textbrowsers_ [l=ka] {áá áá£ááá ááá}
+_textprotocols_ [l=ka] {áá áá¢ááááááá }
+_textconfigfiles_ [l=ka] {á¡ááááá€ááá£á ááªáá á€áááááá}
+_textlogs_ [l=ka] {áááááá}
+_textusagelog_ [l=ka] {ááááá§áááááá¡ áááá}
+_textinitlog_ [l=ka] {ááááªáááááááªááá¡ áááá }
+_texterrorlog_ [l=ka] {ášááªááááááá¡ áááá}
+_textadminhome_ [l=ka] {ááááááá¡á¢á ááªáá£áá ááá¬áááá¡ áááááá á áááá áá}
+_textreturnhome_ [l=ka] {áááááá á áááá áá}
+_titlewelcome_ [l=ka] {ááááááá¡á¢á ááªáá£áá ááá¬ááá }
+_textmaas_ [l=ka] {á®ááááá¡áá¬áááááá áááá¡áá®á£á áááá¡ áá ááááááá¡á¢á ááªááá¡ ášáááááá á¡áá ááá¡ááá: }
+_textvol_ [l=ka] {âááááááâ ááááááá¡ ááááááááá ááá }
+_textcmuc_ [l=ka] {ááááá¥áªááááá¡ ášáá¥ááá, ááááá®áááá áá áááá¡áá®á£á ááá}
+_textati_ [l=ka] {áá¡ááá á¢áá¥áááá£á á ááá€áá áááªááá¡ ááá®áá, á áááá ááªáá CGI áá áá£áááá¢ááá}
+
+_texttsaa_ [l=ka] {á¡áá ááá¡áááá¡ ááá®áá ášááá«áááá áááááááªááá¡ ááááááá¡ á¡áášá£áááááá, á ááááááª ááááááááá£ááá  áááá ááá¡ ááá áªá®ááá áá®áá áá¡.
+}
+
+_textcolstat_ [l=ka] {ááááá¥áªááá¡ á¡á¢áá¢á£á¡á}
+
+_textcwoa_ [l=ka] {ááááá¥áªáááá áá®áááá áá ášáááá®ááááášá áá¥áááá âáá£ášá ááááááá ááááášáâ, áá£ áááá ášáá¡áááááá¡á á¡ááááá€ááá£á ááªáá á€áááááá build.cfg áá á¡ááááá¡, áááá á¬ááááá®áá ášáá¡áá«ááááááá, áá ášáááªáááá á¡á¬áá  builddate áááá¡ áá ááááááá¡ááá£ááá áá ááá ááááá¥áªááá¡ áááááá  ááá áá¥á¢áá ááášá (áá áá á ášáá¥áááá¡ ááá áá¥á¢áá ááášá). 
+}
+
+_textcafi_ [l=ka] {áááá­áá áá  <i>abbrev.</i> áŠááááá¡,  ááááá¥áªááá¡ ášáá¡áá®áá ááá€áá áááªááá¡ á¡áááá®áááá.}
+_textcctv_ [l=ka] {áááá­áá áá <i>collection</i> ááááá¥áªááá¡ á¡áááá®áááá.}
+_textsubc_ [l=ka] {áªáááááááááá¡ ášáááá®áá}
+_texteom_ [l=ka] {main.cfg-á¡ ááá®á¡áá ášáá£á«ááááááá}
+_textftum_ [l=ka] {main.cfg-á¡  ááááá®áááá ášáá£á«ááááááá}
+_textmus_ [l=ka] {main.cfg á¬áá ááá¢áááá ááááá®ááá}
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=ka] {ááááá¥áªááá¡ _collectionname_ ášáá¥áááá¡ á ááá£áá}
+_textflog_ [l=ka] {ááááá¥áªááá¡ _collectionname_ ášááªááááááá¡ áááá}
+
+
+############################################################################
+#
+# This stuff is only used by the usability (I'd like to Complain) stuff
+#
+############################################################################
+package Global
+
+_greenstoneusabilitytext_ [l=ka] {á áááá  áááá«ááááá ááá€áá áááªáá- ááááá¥áªááášá}
+
+_textwhy_ [l=ka] {<p>áá ááá€áá áááªááá¡ ááááááááá áá¥ááá ááŠááášáááá, á áá ááá®áá á«ááááá ááá¡áááááááá ááááá áá á£á¡ááááááá ááá áááá áá.}
+_textextraforform_ [l=ka] {áá¥ááá áá  áááá­áá ááááá á€áá ááá¡ ášááá¡ááá -- ááááá¡áááá á ááá€áá áááªáá ááááá®ááá áááá.}
+_textprivacybasic_ [l=ka] {<p>áá¡ ášáá¢á§ááááááá  ášáááªááá¡ áá®áááá ááá€áá áááªááá¡ -- áááá ááá¡ ášáá¡áá®áá á ááááá¡ááª áá¥ááá áááááááá ááá  
+áá áá¥áááá¡ áááá  ááááá§ááááá£áá á¢áá¥áááááááá¡ ášáá¡áá®áá, á áááááááª  áá áááá ááá¡  ááá®á£áááá.}
+_textstillsend_ [l=ka] {ááááááá ááááááááá ášáá¢á§ááááááá?}
+
+_texterror_ [l=ka] {ášááªáááá}
+_textyes_ [l=ka] {áá}
+_textno_ [l=ka] {áá á}
+_textclosewindow_ [l=ka] {á€ááá¯á áá¡ ááá®á£á áá}
+_textabout_ [l=ka] {ášáá¡áá®áá
+}
+_textprivacy_ [l=ka] {áááá€áááááªáááá£á ááá}
+_textsend_ [l=ka] {áááááááá}
+_textdontsend_ [l=ka] {ááááááááá¡ ášáá¬á§ááá¢á}
+_textoptionally_ [l=ka] {áá ááá£áªááááááá}
+
+_textunderdev_ [l=ka] {ááá¢áááááá¡ ááááááááá ááá ášáá¡áá«áááááá áá¥áááá á€ááááá£á  ááá á¡ááášá.}
+
+_textviewdetails_ [l=ka] {ášáá¢á§áááááááá¡ ááá¢áááááá¡ ááááááááá ááá}
+_textmoredetails_ [l=ka] {á¡á®áá ááá¢ááááá}
+_texttrackreport_ [l=ka] {ášáá¢á§áááááááá¡ááá áááášáá á}
+_textcharacterise_ [l=ka] {áá ááááááá¡ á¢ááá}
+_textseverity_ [l=ka] {áá ááááááá¡ á¡ááá«ááá}
+ 
+_textbadrender_ [l=ka] {áááá áá á£áªááá£á áá áááááá§á£á ááá}
+_textcontenterror_ [l=ka] {ášáááªááá¡ ášááªááááá¡}
+_textstrangebehaviour_ [l=ka] {á£áªááá£á á ááá¥áªááá}
+_textunexpected_ [l=ka] {ááá£áááááá¡á¬ááááááá ášááªáááá}
+_textfunctionality_ [l=ka] {ááááá§áááááá¡áááá¡ á áá£áá}
+_textother_ [l=ka] {á¡á®áá}
+
+_textcritical_ [l=ka] {áá áá¢ááá£áá}
+_textmajor_ [l=ka] {á¡áá áááá£áá}
+_textmedium_ [l=ka] {á¡áášá£ááá áááášáááááááá¡}
+_textminor_ [l=ka] {á£áááášááááá}
+_texttrivial_ [l=ka] {á¢á áááááá£á á}
+
+_textwhatdoing_ [l=ka] {á áá¡ ááááááááá¡ áªáááááá?}
+_textwhatexpected_ [l=ka] {á áá¡ áááááááá ?}
+_textwhathappened_ [l=ka] {á á ááá®áá á¡áááááááááášá?}
+
+_cannotfindcgierror_ [l=ka] {<h2>Sorry!</h2>Can't find the server programs for the "I'd Like to Complain" button.}
+
+_textusabbanner_ [l=ka] {áá ááá¡á¢áá£ááá¡ ááááá á}
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+# -- Missing translation: _textgti_
+
+# -- Missing translation: _textgtierror_
+
+# -- Missing translation: _textgtihome_
+
+# -- Missing translation: _textgtiselecttlc_
+
+# -- Missing translation: _textgtiselecttfk_
+
+# -- Missing translation: _textgticoredm_
+# -- Missing translation: _textgtiauxdm_
+# -- Missing translation: _textgtiglidict_
+# -- Missing translation: _textgtiperlmodules_
+# -- Missing translation: _textgtigreenorg_
+
+# -- Missing translation: _textgtienter_
+
+# -- Missing translation: _textgticorrectexistingtranslations_
+# -- Missing translation: _textgtidownloadtargetfile_
+# -- Missing translation: _textgtiviewtargetfileinaction_
+
+# -- Missing translation: _textgtinumchunksmatchingquery_
+
+# -- Missing translation: _textgtinumchunkstranslated_
+# -- Missing translation: _textgtinumchunksrequiringupdating_
+# -- Missing translation: _textgtinumchunksrequiringtranslation_
+
+# -- Missing translation: _textgtienterquery_
+# -- Missing translation: _textgtifind_
+
+# -- Missing translation: _textgtitranslatingchunk_
+# -- Missing translation: _textgtiupdatingchunk_
+# -- Missing translation: _textgtisubmit_
+
+# -- Missing translation: _textgtilastupdated_
+
+# -- Missing translation: _textgtitranslationfilecomplete_
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=ka] {áá ááá¡á¢áá£ááá¡ á¡ááááááááááá ááá¢áá á€ááá¡á}
+_textglihelp_ [l=ka] {áá ááá¡á¢áá£ááá¡ ááááááááááá áá¡ ááá¢áá á€ááá¡á (GLI) á®ááááá¡áá¬ááááá¡ á®ááá¡ áá ááá¡á¢áá£ááá¡ á€á£áá¥áªááááá¡ ááááááá ááááá§áááááá¡ ááááá¡á ááá á¢ááá ááá¢áá á€ááá¡áá¡ á¬á§áááááá. ááá áá«áááá áááá£áááá¢áááá¡ ášááá áááááá¡, ááááá á¢áá¡, ááááááá¡ ááá¢ááááááªáááááá¡ ááá¬áá áá¡á áá ášááááá áá ááá¡á¢áá£ááá¡ ááááá¥áªááá¡ ášáá¥áááá¡ á¡áášá£áááááá¡. 
+ <p>
+ášááááášááá, á áá GLI á£ááá áá§áá¡ ááášáááá£áá áá ááá¡á¢áá£ááá¡ á«áá áááá áá ááá áááá¡ááá áá ááá áá áá£ááá¡á®áááá¡, á áá ááá á£ááá áá§áá¡ ááá¡á¢áááá ááá£áá áá ááá¡á¢áá£ááá¡ áá¥áááá ááá¡á¢ááááªááá¡ á¥ááááá áá¥á¢áá ááášá. áááá¡ááááá¡ á¡áá­áá áá áá ááá¡á¢áá£ááá¡ á ááááááá ááá¡á¢á ááá£áªááá¡ áááááá¢ááá ááá áá ááá§ááááá áá ááá¡á¢áá£ááá¡ CD-ROM-ááá.
+ 
+ 
+<h4>GLI-áá¡ ááášáááá Windows-áá</h4>
+ 
+áááá¡ááááá¡ á áá á©áá ááá ááááááááááá áá¡ ááá¢áá á€ááá¡á Windows-áá ááá á©ááá <i>Greenstone Digital Library</i> á¡áá¥áªááááá <i>Programs</i>, á ááááááª áááááá¡ááá£ááá i>Start</i> ááááá£ášá áá ášááááá ááá á©ááá <i>Librarian Interface</i>. 
+
+ 
+<h4>GLI-áá¡ ááášáááá Unix-áá</h4>
+ 
+áááá¡ááááá¡ á áá á©áá ááá ááááááááááá áá¡ ááá¢áá á€ááá¡á Unix-áá, ááááááá <i>gli</i> ááá áá¥á¢áá ááášá áá ááá¡á¢áá£ááá¡ áá¥áááá¡ ááá¡á¢ááááªááášá áá ášááááá ááá£ášááá <i>gli.sh</i> á¡áá ááá¢á. 
+ 
+<h4>GLI-áá¡ ááášáááá Mac OS X-áá</h4>
+
+ááááá®áá <i>Applications</i> ášááááá <i>Greenstone</i>
+(áá ášáááá®ááááášá áá£ áá ááá¡á¢áá£áá ááááá¡á¢áááá ááá£áá ááá¥áá á¡áá¡á¢ááá£á áá áááá£ááá¡á®ááá ááááááá), áá ášááááá ááá£ášááá  <i>GLI</i> áá ááá ááá.}
Index: /gsdl/stable/macros/german.dm
===================================================================
--- /gsdl/stable/macros/german.dm	(revision 20131)
+++ /gsdl/stable/macros/german.dm	(revision 20131)
@@ -0,0 +1,806 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# German Language text and icon macros (translated from english.dm
+# 9 March 2000)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=de] {die Zeitschrift}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=de] {Referenz der Quelle:}  
+_textdate_ [l=de] {Publikation Datum:}  
+_textnumpages_ [l=de] {Zahl  von den Seiten:}  
+
+_textsignin_ [l=de] {sign in}  
+
+_textdefaultcontent_ [l=de] {Die angegebene Seite konnte nicht gefunden
+werden. Bitte benutzen Sie den "ZurÃŒck" Knopf ihres Browsers oder
+den obigen "Home" Knopf um zur Hauptseite der elektronischen
+Bibliothek zurÃŒckzukehren.}  
+
+_textdefaulttitle_ [l=de] {GSDL Fehler}
+
+_textbadcollection_ [l=de] {Die Sammlung (genannt "_cvariable_") ist auf diesem Greenstone-System nicht installiert.}  
+
+_textselectpage_ [l=de] {-- AuserwÃ€hlte Seite --}  
+
+_collectionextra_ [l=de] {Diese Sammlung enthÃ€lt _about:numdocs_
+Dokumente. Sie wurde vor _about:builddate_ Tagen erstellt.}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=de] {<p>This collection contains _numdocs_ _If_("_numdocs_" eq "1",document,documents), a total of _numbytes_ of indexed text and metadata.
+<p><a href="_httppagex_(bsummary)">Click here</a> to view the build summary for this collection.
+}  
+
+_textdescrcollection_ [l=de] {}
+_textdescrabout_ [l=de] {Info}
+_textdescrhome_ [l=de] {Hauptseite}
+_textdescrhelp_ [l=de] {Hilfe}
+_textdescrpref_ [l=de] {Einstellungen}  
+_textdescrgreenstone_ [l=de] {Greenstone Digital Library Software}
+_textdescrusab_ [l=de] {Was fanden Sie stark, um zu verwenden?}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=de] {die Suche}  
+_labelSearch_ [l=de] {Suche}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=de] {Titel}  
+_labelTitle_ [l=de] {Titel}  
+_textCreator_ [l=de] {Urheber/in}  
+_labelCreator_ [l=de] {Autoren}  
+_textSubject_ [l=de] {Thema}  
+_labelSubject_ [l=de] {Themenbereiche}  
+_textDescription_ [l=de] {Beschreibung}  
+_labelDescription_ [l=de] {Beschreibungen}  
+_textPublisher_ [l=de] {Verlag}  
+_labelPublisher_ [l=de] {Verleger/in}  
+_textContributor_ [l=de] {der Mitwirkende }  
+_labelContributor_ [l=de] {Mitwirkende}  
+_textDate_ [l=de] {Jahr}  
+_labelDate_ [l=de] {Daten}
+_textType_ [l=de] {Typ}  
+_labelType_ [l=de] {Typen}  
+_textFormat_ [l=de] {Format}  
+_labelFormat_ [l=de] {Formate}  
+_textIdentifier_ [l=de] {Identifikator}  
+_labelIdentifier_ [l=de] {Identifikatoren}  
+_textSource_ [l=de] {der Dateiname}  
+_labelSource_ [l=de] {Dateinamen}  
+_textLanguage_ [l=de] {Sprache}  
+_labelLanguage_ [l=de] {Sprachen}  
+_textRelation_ [l=de] {Relation}  
+_labelRelation_ [l=de] {Verbindungen}  
+_textCoverage_ [l=de] {Umfang}  
+_labelCoverage_ [l=de] {Umfang}  
+_textRights_ [l=de] {Rechte}  
+_labelRights_ [l=de] {Rechte}  
+
+# DLS metadata set
+_textOrganization_ [l=de] {Organisation}  
+_labelOrganization_ [l=de] {Organisationen}  
+_textKeyword_ [l=de] {SchlÃŒsselwort}  
+_labelKeyword_ [l=de] {StichwÃ¶rter}  
+_textHowto_ [l=de] {Wie ...}  
+_labelHowto_ [l=de] {Wie ...}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=de] {Phrase}  
+_labelPhrase_ [l=de] {Phrasen}  
+_textCollage_ [l=de] {Collage}  
+_labelCollage_ [l=de] {Collage}  
+_textBrowse_ [l=de] {DurchstÃ¶bern}  
+_labelBrowse_ [l=de] {DurchstÃ¶bern}  
+_textTo_ [l=de] {Zu}  
+_labelTo_ [l=de] {Zu}  
+_textFrom_ [l=de] {Von}  
+_labelFrom_ [l=de] {Von}  
+_textAcronym_ [l=de] {Akronym}  
+_labelAcronym_ [l=de] {das Akronym  }  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=de] {StÃ¶bern nach _1_}  
+
+_textdescrSearch_ [l=de] {Suche nach einem bestimmten Begriff}
+_textdescrType_ [l=de] {StÃ¶bern nach Quellentyp}  
+_textdescrIdentifier_ [l=de] {StÃ¶bern nach Quellen-Identifikator}  
+_textdescrSource_ [l=de] {Grasen Sie durch ursprÃŒnglichen Dateinamen}  
+_textdescrTo_ [l=de] {Grasen Sie vorbei, um aufzufangen}  
+_textdescrFrom_ [l=de] {Von-Feld durchstÃ¶bern}  
+_textdescrCollage_ [l=de] {Bildercollage durchstÃ¶bern}  
+_textdescrAcronym_ [l=de] {Akronyme durchstÃ¶bern}  
+_textdescrPhrase_ [l=de] {Grasen Sie Phrasen}  
+_textdescrHowto_ [l=de] {"Wie geht das?"-Kategorien}
+_textdescrBrowse_ [l=de] {StÃ¶bern}
+_texticontext_ [l=de] {Sichten des Dokuments}
+_texticonclosedbook_ [l=de] {Ã¶ffnen dieses Dokuments und Sichten des Inhalts}
+_texticonnext_ [l=de] {zur nÃ€chsten Sektion}
+_texticonprev_ [l=de] {zur vorhergehenden Sektion}
+
+_texticonworld_ [l=de] {Sehen Sie das Netzdokument an}  
+
+_texticonmidi_ [l=de] {Sehen Sie das MIDI Dokument an}  
+_texticonmsword_ [l=de] {Das Microsoft Word-Dokument ansehen}  
+_texticonmp3_ [l=de] {Das Dokument MP3 ansehen }  
+_texticonpdf_ [l=de] {Sehen Sie das pdf Dokument an}  
+_texticonps_ [l=de] {Das PostScript-Dokument ansehen}  
+_texticonppt_ [l=de] {PowerPoint-Dokument ansehen}  
+_texticonrtf_ [l=de] {Sehen Sie das rtf Dokument an}  
+_texticonxls_ [l=de] {Microsoft Excel Dokument anzeigen}  
+
+_page_ [l=de] {Seite }
+_pages_ [l=de] {Seiten}
+_of_ [l=de] {of }
+_vol_ [l=de] {Band}  
+_num_ [l=de] {Nummer}  
+
+_textmonth00_ [l=de] {}
+_textmonth01_ [l=de] {Januar}
+_textmonth02_ [l=de] {Februar}
+_textmonth03_ [l=de] {MÃ€rz}
+_textmonth04_ [l=de] {April}
+_textmonth05_ [l=de] {Mai}
+_textmonth06_ [l=de] {Juni}
+_textmonth07_ [l=de] {Juli}
+_textmonth08_ [l=de] {August}
+_textmonth09_ [l=de] {September}
+_textmonth10_ [l=de] {Oktober}  
+_textmonth11_ [l=de] {November}
+_textmonth12_ [l=de] {Dezember}
+
+_textdocument_ [l=de] {Dokument}  
+_textsection_ [l=de] {Abschnitt (Section)}  
+_textparagraph_ [l=de] {Abschnitt}  
+
+_magazines_ [l=de] {Magazine}
+
+_nzdlpagefooter_ [l=de] {Temporarily added}  
+
+_linktextHOME_ [l=de] {HAUPTSEITE}
+_linktextHELP_ [l=de] {HILFE}
+_linktextPREFERENCES_ [l=de] {EINSTELLUNGEN}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=de] {Greenstone Digitale Bibliothek}  
+
+_textnocollections_ [l=de] {Keine gÃŒltigen (d.h. erstellte und Ã¶ffentliche) Sammlungen verfÃŒgbar}  
+
+_textadmin_ [l=de] {Die Administrations- Seite}  
+_textabgs_ [l=de] {Ãber Greenstone}  
+_textgsdocs_ [l=de] {Greenstone-
+Dokumentation}  
+
+_textdescradmin_ [l=de] {Erlaubt es neue Nutzer hinzuzufÃŒgen, zeigt den Sammlungsbestand an, informiert ÃŒber technische Aspekte der Greenstone-Installation}  
+
+_textdescrgogreenstone_ [l=de] {Berichtet von der Greenstone-Software und dem New Zealand Digital Library Project, wo die Software entstanden ist}  
+
+_textdescrgodocs_ [l=de] {Greenstone-HandbÃŒcher}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=de] {Die Bibliothekars- BenutzeroberflÃ€che}  
+_textdescrgli_ [l=de] {Hilft Ihnen, neue Sammlungen anzulegen, und bestehende Sammlungen zu verÃ€ndern, zu erweitern oder zu lÃ¶schen}  
+
+package collector
+
+_textcollector_ [l=de] {Der Sammler}  
+_textdescrcollector_ [l=de] {Dies ist der VorgÃ€nger der Bibliothekars-BenutzeroberflÃ€che. In den meisten FÃ€llen sollte  die Bibliothekars-BenutzeroberflÃ€che genutzt werden.}  
+
+package depositor
+
+_textdepositor_ [l=de] {Der Hinterleger}  
+_textdescrdepositor_ [l=de] {Hilft Ihnen Dokumente zu bereits erstellten Sammlungen hinzuzufÃŒgen}  
+
+package gti
+
+_textgti_ [l=de] {Das Greenstone Ãbersetzer Interface}  
+_textdescrtranslator_ [l=de] {Hilft Ihnen, die multilingualen Versionen der Greenstone-BenutzeroberflÃ€che aktuell zu halten}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=de] {Ãber diese Sammlung}  
+
+_textsubcols1_ [l=de] {<p>Die komplette Sammlung umfasst _1_ individuelle
+Sammlungen:
+<blockquote>}  
+
+_textsubcols2_ [l=de] {</blockquote>
+Auf der Seite mit den Einstellungen kÃ¶nnen Sie prÃŒfen (und
+ Ã€ndern) welche individuellen Sammlungen Sie momentan benutzen.}  
+
+_titleabout_ [l=de] {info}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=de] {SchlieÃen dieser Sektion der Bibliothek}  
+_texticonclosedbookshelf_ [l=de] {Ã¶ffnen dieser Sektion der Bibliothek und Sichten des Inhalts}
+_texticonopenbook_ [l=de] {SchlieÃen dieses Buches}  
+_texticonclosedfolder_ [l=de] {Ã¶ffnen dieses Ordners und Sichten des Inhalts}
+_texticonclosedfolder2_ [l=de] {Ãffnen der individuellen Sammlung: }  
+_texticonopenfolder_ [l=de] {SchlieÃen dieses Ordners}  
+_texticonopenfolder2_ [l=de] {SchlieÃen der individuellen Sammlung: }  
+_texticonsmalltext_ [l=de] {Sichten des Textabschnittes}
+_texticonsmalltext2_ [l=de] {Sichten des Texts: }
+_texticonpointer_ [l=de] {Augenblickliche Sektion}
+_texticondetach_ [l=de] {Ã¶ffnen dieser Seite in einem neuen Fenster}
+_texticonhighlight_ [l=de] {Suchbegriffe werden hervorgehoben}
+_texticonnohighlight_ [l=de] {Suchbegriffe werden nicht hervorgehoben}
+_texticoncontracttoc_ [l=de] {Verkleinerte Version des Inhaltsverzeichnisses}
+_texticonexpandtoc_ [l=de] {Expandierte Version des Inhaltsverzeichnisses}
+_texticonexpandtext_ [l=de] {Anzeigen des gesamten Texts}
+_texticoncontracttext_ [l=de] {Anzeigen des Textes nur fÃŒr die augenblicklich ausgewÃ€hlte Sektion}
+_texticonwarning_ [l=de] {<b>Warnung: </b>}
+_texticoncont_ [l=de] {Weitermachen?}
+
+_textltwarning_ [l=de] {<div class="buttons">_imagecont_</div>
+_iconwarning_Wenn der Text hier expandiert wird, wird eine sehr groÃe Menge an Daten dargestellt werden mÃŒssen
+}  
+
+_textgoto_ [l=de] {Gehe zur Seite}
+_textintro_ [l=de] {<i>(EinfÃŒhrender Text)</i>}
+
+_textCONTINUE_ [l=de] {WEITERMACHEN?}
+
+_textEXPANDTEXT_ [l=de] {TEXT AUSKLAPPEN}  
+
+_textCONTRACTCONTENTS_ [l=de] {INHALTSVERZEICHNIS EINKLAPPEN}  
+
+_textDETACH_ [l=de] {SEPARATES\nFENSTER}
+
+_textEXPANDCONTENTS_ [l=de] {INHALTSVERZEICHNIS\nAUFKLAPPEN}  
+
+_textCONTRACT_ [l=de] {TEXT EINKLAPPEN}  
+
+_textHIGHLIGHT_ [l=de] {HERVORHEBUNG}  
+
+_textNOHIGHLIGHT_ [l=de] {KEINE HERVORHEBUNG}  
+
+_textPRINT_ [l=de] {DRUCKEN}  
+
+_textnextsearchresult_ [l=de] {nÃ€chstes Suchergebnis}  
+_textprevsearchresult_ [l=de] {vorheriges Suchergebnis}  
+
+# macros for printing page
+_textreturnoriginal_ [l=de] {ZurÃŒck zur Ursprungsseite}  
+_textprintpage_ [l=de] {Diese Seite drucken}  
+_textshowcontents_ [l=de] {Inhaltsverzeichnis anzeigen}  
+_texthidecontents_ [l=de] {Inhaltsverzeichnis ausblenden}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=de] {_If_(_thislast_,Treffer _thisfirst_ - _thislast_ zur Anfrage: _cgiargq_,Keine Treffer fÃŒr die Anfrage: _cgiargq_)}
+_textnoquerytitle_ [l=de] {Suchseite}
+
+_textsome_ [l=de] {einige}
+_textall_ [l=de] {alle}
+_textboolean_ [l=de] {boolsch}
+_textranked_ [l=de] {gestaffelt}
+_textnatural_ [l=de] {natÃŒrlich}  
+_textsortbyrank_ [l=de] {Sortierung nach Relevanz}  
+_texticonsearchhistorybar_ [l=de] {Suchgeschichte}  
+
+_textifeellucky_ [l=de] {Ich bin glÃŒcklich!}  
+
+#alt text for query buttons
+_textusequery_ [l=de] {diese Suche benutzen}  
+_textfreqmsg1_ [l=de] {Zahl der WÃ¶rter: }
+_textpostprocess_ [l=de] {_If_(_quotedquery_,<br><i>weiterverarbeitet um _quotedquery_ zu finden</i>
+)}
+_textinvalidquery_ [l=de] {UngÃŒltige Abfragesyntax}  
+_textstopwordsmsg_ [l=de] {Die folgenden WÃ¶rter gibt es zu hÃ€ufig, sie wurden daher ignoriert:}  
+_textlucenetoomanyclauses_ [l=de] {Ihre Suche enthielt zu viele Suchbegriffe; bitte formulieren Sie eine prÃ€zisere Anfrage.}  
+
+_textmorethan_ [l=de] {Mehr als }
+_textapprox_ [l=de] {ÃŒber }
+_textnodocs_ [l=de] {Keine zur Anfrage passenden Dokumente gefunden.}  
+_text1doc_ [l=de] {Eins zur Anfrage passendes Dokument gefunden.}
+_textlotsdocs_ [l=de] {Zur Anfrage passende Dokumente gefunden.}  
+_textmatches_ [l=de] {Passende Dokumente }
+_textbeginsearch_ [l=de] {Suche beginnen}
+_textrunquery_ [l=de] {Run Query}  
+_textclearform_ [l=de] {Eingaben lÃ¶schen}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=de] {Wort oder phrase}  
+_textinfield_ [l=de] {... in Arbeit}  
+_textfoldstem_ [l=de] {(ignoriere GroÃ-/Kleinschreibung, ignoriere Wortendungen)}  
+
+_textadvquery_ [l=de] {Oder tragen Sie eine Frage direkt ein:}  
+_textallfields_ [l=de] {alles fÃ€ngt auf}  
+_texttextonly_ [l=de] {nur Text}  
+_textand_ [l=de] {und}  
+_textor_ [l=de] {oder}  
+_textandnot_ [l=de] {und nicht}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=de] {Suche nach _indexselection_ _If_(_jselection_, aus _jselection_)_If_(_gselection_, im Level _gselection_ ) _If_(_nselection_, in der Sprache _nselection_ ), die _querytypeselection_ der WÃ¶rter enthalten _If_(_sfselection_,\,_allowformbreak_ Ergebnisse sortiert nach _sfselection_)}  
+
+_textadvancedsearch_ [l=de] {Suche nach _indexselection_ _If_(_jselection_, aus _jselection_) _If_(_gselection_, at _gselection_ level)_If_(_nselection_, in der _nselection_ Sprache) mit einer _querytypeselection_ Anfrage}
+
+_textadvancedmgppsearch_ [l=de] {Search _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language ) and display results in _formquerytypeadvancedselection_ order}  
+
+_textadvancedlucenesearch_ [l=de] {Search _indexselection__If_(_jselection_, of _jselection_)_If_(_gselection_, at _gselection_ level)_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ sorting results by _sfselection_\,) for}  
+
+_textformsimplesearch_ [l=de] {Suche  _If_(_jselection_, _jselection_)_If_(_gformselection_, at _gformselection_ level)_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\, sortiere Ergebnisse nach _sfselection_\,) fÃŒr _formquerytypesimpleselection_ von }  
+
+_textformadvancedsearchmgpp_ [l=de] {Suche _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language ) und zeige die Ergebnisse in Reihenfolge _formquerytypeadvancedselection_ an}  
+
+_textformadvancedsearchlucene_ [l=de] {Suche _If_(_jselection_, _jselection_)_If_(_gformselection_,  at _gformselection_ level)_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\, Ergebnisse geordnet nach _sfselection_\,) fÃŒr}  
+
+_textnojsformwarning_ [l=de] {Warnung: Javascript wird in Ihrem Webbrowser gesperrt. <br>Um die Suchfunktion zu benutzen, lassen Sie bitte Javascript zu.}  
+_textdatesearch_ [l=de] {Diese Sammlung kann nach Dokumenten innerhalb eines Datumbereiches oder nach Dokumenten durchsucht werden, die ein bestimmtes Datum enthalten. Dieses ist eine Zusatzeinrichtung der Suche.}  
+_textstartdate_ [l=de] {Start- (oder nur) Datum:}  
+_textenddate_ [l=de] {End-Datum:}  
+_textbc_ [l=de] {B.C.E.}  
+_textad_ [l=de] {C.E.}  
+_textexplaineras_ [l=de] {C.E. und B.C.E sind Alternativen fÃŒr A.D. und B.C. beziehungsweise. Diese Bezeichnungen gelten, Kultur zu sein als unterschiedslos und stehen fÃŒr "allgemeine Ãra" und "vor der allgemeinen Ãra"}  
+
+_textstemon_ [l=de] {(Wortendungen werden ignoriert)}
+
+_textsearchhistory_ [l=de] {Alte Suchresultate}
+
+#text macros for search history
+_textnohistory_ [l=de] {Alte Suchresultate nicht verfÃŒgbar}
+_texthresult_ [l=de] {das Arbeitsergebnis}  
+_texthresults_ [l=de] {Ergebnisse}  
+_texthallwords_ [l=de] {alle WÃ¶rter}  
+_texthsomewords_ [l=de] {einige WÃ¶rter}  
+_texthboolean_ [l=de] {mit booleschen Operatoren}  
+_texthranked_ [l=de] {geordnet}  
+_texthcaseon_ [l=de] {GroÃ-/Kleinschreibung beachten}  
+_texthcaseoff_ [l=de] {GroÃ-/Kleinschreibung ignoriert}  
+_texthstemon_ [l=de] {eingeschrÃ€nkt}  
+_texthstemoff_ [l=de] {unbeschrÃ€nkt}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=de] {Die Einstellungen wurden wie folgt gewÃ€hlt. Benutzen Sie nicht den "ZurÃŒck"-Knopf Ihres Browsers - das wird die Einstellungen zurÃŒcksetzen! Stattdessen benutzen Sie bitte die KnÃ¶pfe am obigen Steuerungsbalken.}  
+_textsetprefs_ [l=de] {Einstellungen ÃŒbernehmen}  
+_textsearchprefs_ [l=de] {Sucheinstellungen}  
+_textcollectionprefs_ [l=de] {Voreinstellungen zu Sammlungen}  
+_textpresentationprefs_ [l=de] {DarstellungsprÃ€ferenzen}  
+_textpreferences_ [l=de] {Einstellungen}  
+_textcasediffs_ [l=de] {GroÃ-/Kleinschreibung:}  
+_textignorecase_ [l=de] {ignoriere GroÃ-/Kleinschreibung}  
+_textmatchcase_ [l=de] {GroÃ-/Kleinschreibung muss passen}  
+_textwordends_ [l=de] {Wortendungen}  
+_textstem_ [l=de] {ignoriere Wortendungen}  
+_textnostem_ [l=de] {das vollstÃ€ndige Wort muss passen}  
+_textaccentdiffs_ [l=de] {Akzent-Unterschiede:}  
+_textignoreaccents_ [l=de] {Akzente ignorieren}  
+_textmatchaccents_ [l=de] {Akzente beachten}  
+
+_textprefop_ [l=de] {Zeige maximal _maxdocoption_ Treffer an, mit _hitsperpageoption_ Treffern pro Seite.}  
+_textextlink_ [l=de] {Zugang zu externen Seiten: }  
+_textintlink_ [l=de] {Quelldokumente aufgefunden in:}
+_textlanguage_ [l=de] {Sprache der BenutzeroberflÃ€che: }  
+_textencoding_ [l=de] {Kodierung: }  
+_textformat_ [l=de] {Format der BenutzeroberflÃ€che: }  
+_textall_ [l=de] {alle}
+_textquerymode_ [l=de] {Suchmodus:}  
+_textsimplemode_ [l=de] {einfache Suche}  
+_textadvancedmode_ [l=de] {erweiterte Suche (ermÃ¶glicht boolesche Suche mit !, &, |, und Klammern)}  
+_textlinkinterm_ [l=de] {via einer dazwischenliegenden Seite}
+_textlinkdirect_ [l=de] {gehe direkt dorthin}
+_textdigitlib_ [l=de] {die elektronische Bibliothek}
+_textweb_ [l=de] {das Web}
+_textgraphical_ [l=de] {Graphisch}
+_texttextual_ [l=de] {Textuell}
+_textcollectionoption_ [l=de] {<p>
+Individuelle Sammlungen die eingebunden werden sollen:
+<br>}
+
+_textsearchtype_ [l=de] {Suchmodus:}  
+_textformsearchtype_ [l=de] {fielded with _formnumfieldoption_ fields}  
+_textplainsearchtype_ [l=de] {normal mit _boxsizeoption_ Suchanfragefeld}  
+_textregularbox_ [l=de] {eine Zeile}  
+_textlargebox_ [l=de] {groÃ}  
+
+_textrelateddocdisplay_ [l=de] {verwandte Dokumente anzeigen}  
+_textsearchhistory_ [l=de] {Suchgeschichte:}  
+_textnohistory_ [l=de] {Keine Suchgeschichte}  
+_texthistorydisplay_ [l=de] {_historynumrecords_ EintrÃ€ge der Suchgeschichte anzeigen}  
+_textnohistorydisplay_ [l=de] {Suchgeschichte nicht anzeigen}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=de] {Sortiere Dokumente nach}  
+_textalsoshowing_ [l=de] {ebenfalls anzeigen}  
+_textwith_ [l=de] {mit hÃ¶chstens}  
+_textdocsperpage_ [l=de] {Dokumente pro Seite }  
+
+_textfilterby_ [l=de] {Erhalten Sie das Dokumententhalten}  
+_textall_ [l=de] {alle}  
+_textany_ [l=de] {irgendwelche}  
+_textwords_ [l=de] {WÃ¶rter}  
+_textleaveblank_ [l=de] {Lassen Sie diesen kastenfreien Raum, um alle Dokumente zu erhalten}  
+
+_browsebuttontext_ [l=de] {"Dokumente sortieren"}  
+
+_nodata_ [l=de] {<i>keine Daten</i>}  
+_docs_ [l=de] {Dokumente}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=de] {Help}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=de] {Um die Dokumente nach _1_ zu durchstÃ¶bern, klicken Sie den _2_ -Knopf}  
+
+_textSearchhelp_ [l=de] {Um nach bestimmten WÃ¶rtern im Text zu suchen, klicken Sie den _labelSearch_ -Knopf}  
+_textTohelp_ [l=de] {browse documents by To field by clicking the _labelTo_ button}  
+_textFromhelp_ [l=de] {DurchstÃ¶bern Sie Publikationen mittels Von-Feld, indem Sie den _labelFrom_ -Knopf klicken}  
+_textBrowsehelp_ [l=de] {In Dokumenten stÃ¶bern}  
+_textAcronymhelp_ [l=de] {DurchstÃ¶bern Sie Dokumente nach Akronymen, indem Sie den _labelAcronym_ -Knopf klicken}  
+_textPhrasehelp_ [l=de] {DurchstÃ¶bern Sie AbsÃ€tze, die in den Dokumenten auftauchen, indem Sie den _labelPhrase_  -Knopf klicken. Dieser benutzt den phind phrase browser.}  
+
+_texthelptopicstitle_ [l=de] {Themen}
+
+_textreadingdocs_ [l=de] {Wie kÃ¶nnen die Dokumente gelesen werden?}  
+
+_texthelpreadingdocs_ [l=de] {<p> Sie erkennen, dass Sie bei einem einzelnen
+Dokument angekommen sind, wenn dessen Titel und Autor links oben auf
+der Seite angezeigt werden. Daneben ist die aktuelle Seitennummer, ein
+KÃ€stchen, welches Ihnen die Auswahl einer neuen Seite erlaubt, und
+VorwÃ€rts- und RÃŒckwÃ€rts-Pfeile.
+
+<p>Darunter ist der Text des aktuellen Abschnitts. Ganz unten befinden
+sich Pfeile, die Sie zum nÃ€chsten oder zum vorherigen Abschnitt bringen.
+
+<p>Unter dem Titel und dem Namen des Autors befinden sich drei KnÃ¶pfe.
+DrÃŒcken sie auf <i>Text ausklappen</i>, um den gesamten Text des
+aktuellen Dokuments anzuzeigen. Ist 
+das Dokument umfangreich, so kann der Ladevorgang einige Zeit in
+Anspruch nehmen, und es wird viel Arbeitsspeicher bennÃ¶tigt!
+DrÃŒcken Sie auf <i>separates Fenster</i>, um das Dokument in einem neuen
+Browserfenster zu Ã¶ffnen. (Dies is sinnvoll, wenn Sie Dokumente
+vergleichen oder zwei auf einmal lesen wollen.) Wenn Sie das Dokument
+aufgrund einer Suche erhalten haben, sind die Suchbegriffe
+hervorgehoben. DrÃŒcken Sie auf <i>keine Hervorhebung</i>, um die
+Suchbegriffe normal darzustellen.
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=de] {Diese Sammlung ansehen}  
+_texthelpopenbook_ [l=de] {Dieses Buch Ã¶ffnen / schlieÃen}  
+_texthelpviewtextsection_ [l=de] {Diesen Abschnitt des Textes ansehen}  
+_texthelpexpandtext_ [l=de] {Gesamten Text
+darstellen, oder nicht}
+_texthelpexpandcontents_ [l=de] {Inhaltsverzeichnis komplett darstellen, oder nicht}  
+_texthelpdetachpage_ [l=de] {Dieses Dokument in einem neuen Fenster Ã¶ffnen}  
+_texthelphighlight_ [l=de] {Suchbegriffe hervorheben, oder nicht}
+_texthelpsectionarrows_ [l=de] {Zum vorherigen / nÃ€chsten Abschnitt gehen}  
+
+
+_texthelpsearchingtitle_ [l=de] {Wie kann ich nach bestimmten WÃ¶rtern suchen?}  
+
+_texthelpsearching_ [l=de] {<p>
+  Ausgehend von der Suchseite starten Sie eine Suchanfrage in den folgenden
+  einfachen Schritten:<p>
+  
+  <ol><li>Spezifizieren Sie, welche Dokumente Sie durchsuchen wollen
+      <li>Sagen Sie, ob Sie nach allen oder lediglich einigen der
+      Suchbegriffe suchen wollen
+      <li>Geben Sie die Suchbegriffe ein
+      <li>DrÃŒcken Sie den Knopf <i>Suche beginnen</i>
+  </ol>
+
+<p> Wenn Sie eine Anfrage durchfÃŒhren, werden die Titel von zwanzig
+dazu gefundenen Dokumenten angezeigt. Am Ende der Seite befindet sich ein
+Knopf, mit dem Sie die nÃ€chsten zwanzig Suchergebnisse dargestellt
+bekommen. Dort finden Sie einen Knopf, der Sie zu den nÃ€chsten zwanzig,
+und einen der Sie zu den ersten zwanzig bringt, und so fort. Um ein
+beliebiges Dokument zu sehen, drÃŒcken Sie auf seinen Titel oder den
+kleinen Knopf daneben. 
+
+<p> GemÃ€Ã der Voreinstellungen werden maximal bis zu 100 Dokumente zu
+einer Anfrage zurÃŒckgegeben. Sie kÃ¶nnen diese Anzahl Ã€ndern,
+indem Sie auf den Knopf <i>Einstellungen</i> am Kopf der Seite
+drÃŒcken.<p> 
+}  
+
+_texthelpquerytermstitle_ [l=de] {Suchbegriffe}
+_texthelpqueryterms_ [l=de] {<p> Was immer Sie in das Suchfeld eingeben, wird als Liste von WÃ¶rtern
+interpretiert, die "Suchbegriffe" genannt werden. Jeder Begriff darf
+ausschlieÃlich Buchstaben und Zahlen enthalten. Begriffe werden
+durch Leerzeichen getrennt. Falls Interpunktionszeichen wie Punkte oder Kommata
+auftauchen, dienen diese dazu, genau wie Leerzeichen, Begriffe zu
+trennen. Sie werden nicht weiter beachtet. Sie kÃ¶nnen
+nicht nach WÃ¶rtern suchen, die Interpunktionszeichen enthalten!
+
+<p>Beispiel: die Anfrage<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>wird genauso interpretiert wie<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}  
+
+_texthelpmgppsearching_ [l=de] {FÃŒr Sammlungen, die mit MGPP erstellt wurden, sind einige weitere Optionen verfÃŒgbar.
+
+<ul>
+<li>A <b>*</b> am Ende eines Suchbegriffes stimmt mit allen WÃ¶rtern ÃŒberein, die mit mit diesem Wort beginnen, z.B. <b>comput*</b> entspricht allen WÃ¶rtern, die mit <b>comput</b> beginnen.
+<li><b>/x</b> kann benutzt werden um ein oder mehrere Suchbegriffe hÃ¶her zu gewichten. Z.B. <b>computer/10 science</b> gewichtet Computer 10mal hÃ¶her als science bei der Auflistung der Dokumente.
+</ul>}  
+
+_texthelplucenesearching_ [l=de] {FÃŒr Sammlungen, die mit Lucene erstellt wurden, sind einige andere Optionen verfÃŒgbar.
+
+<ul>
+<li><b>?</b> kann als Platzhalter fÃŒr einen einzelnen Buchstaben verwendet werden. Zum Beispiel stimmt <b>b?t</b> mit <b>bet</b>, <b>bit</b> und <b>bat</b> ÃŒberein, etc.
+<li><b>*</b> kann als Platzhalter fÃŒr mehrere Buchstaben verwendet werden. Zum Beispiel entspricht <b>comput*</b> allen WÃ¶rtern, die mit <b>comput</b> beginnen.
+</ul>
+Diese beiden Platzhalter kÃ¶nnen in der Mitte oder am Ende eines Wortes benutzt werden, jedoch nicht am Anfang eines Suchbegriffes.}  
+
+_texthelpquerytypetitle_ [l=de] {Anfragearten}
+_texthelpquerytype_ [l=de] {<p>Es gibt zwei unterschiedliche Arten von Anfragen:
+
+<ul>
+  <li>Anfragen nach <b>allen</b> eingegebenen Suchbegriffen. Anfragen
+  dieser Art suchen nach Dokumenten, die alle eingegebenen Suchbegriffe
+  beinhalten. Dokumente, die der Anfrage genÃŒgen, werden in
+  alphabetischer Reihenfolge dargestellt.<p>
+
+  <li>Anfragen nach <b>einigen</b> der eingegebenen Suchbegriffe. Geben
+      Sie einfach mehrere Begriffe an, die mÃ¶glicherweise in den
+      Dokumenten enthalten sind, nach denen Sie suchen. Die Darstellung der Dokumente 
+      ist danach geordnet, wie gut sie die
+      Suchanfrage erfÃŒllen. Der Grad des ErfÃŒllens der
+      Suchanfrage wird folgendermassen bestimmt:
+      <p><ul>
+        <li> Je mehr Suchbegriffe ein Dokument enthÃ€lt, desto besser
+      erfÃŒllt es die Anfrage.
+        <li> Seltene Begriffe sind wichtiger als sehr oft vorkommende.
+        <li> Kurze Dokumente erfÃŒllen Anfragen besser als lange.
+      </ul>
+</ul>
+
+<p> Benutzen Sie so viele Suchbegriffe wie Sie wollen - einen ganzen Satz
+oder gar einen ganzen Absatz. Falls sie nur einen einzigen Suchbegriff
+angeben, werden die Dokumente nach der HÃ€ufigkeit dessen Auftretens
+sortiert.<p>
+}  
+
+_texthelpadvancedsearchtitle_ [l=de] {Erweiterte Suche mit der Suchmaschine _1_}  
+
+_texthelpadvancedsearch_ [l=de] {<p>Wenn Sie den erweiterten Suchmodus (bei Einstellungen) gewÃ€hlt haben, haben Sie etwas andere Suchoptionen. _selectadvancedsearch_}  
+
+_texthelpadvsearchmg_ [l=de] {Die erweiterte Suche in den MG-Sammlungen bietet Ihnen zwei Optionen: Die geordnete Suche und Benutzung der booleschen Operatoren.
+Eine <b>geordnete</b> Suche ist genau das gleiche wie die Suche nach <b>einigen</b> WÃ¶rtern, welche in <a href="\#query-type">_texthelpquerytypetitle_</a> beschrieben wird.
+<p>_texthelpbooleansearch_
+}  
+
+_texthelpbooleansearch_ [l=de] {Eine <b>boolesche</b> Suche erlaubt die Kombination verschiedener Suchterme mittels der logischen Operatoren & ("und"), | ("oder") und ! ("nicht").
+<p>
+Die Anfrage <b>snail & farming</b> beispielsweise sucht Dokumente, die <b>snail</b> UND <b>farming</b> enthalten, wÃ€hrend <b>snail | farming</b> Dokumente sucht, die entweder <b>snail</b> ODER <b>farming</b> (oder beides) enthalten.
+<p>
+PrÃ€zisere Anfragen kÃ¶nnen gemacht werden, indem man Operatoren kombiniert und Klammern verwendet. Zum Beispiel: <b>(sheep | cattle) & (farm | station)</b> oder <b>sheep | cattle | goat !pig</b>.}  
+
+_texthelpadvsearchmgpp_ [l=de] {Die erweiterte Suche in MGPP-Sammlungen benutzt Boole'sche Operatoren. _texthelpbooleansearch_
+<p>Die Ergebnisse kÃ¶nnen in <b>geordneter</b> Reihenfolge angezeigt werden, wie beschrieben fÃŒr die <b>some</b> Suche in <a href="\#query-type">_texthelpquerytypetitle_</a> oder in "natÃŒrlicher" Reihenfolge. Das ist die Reihenfolge, in der die Dokumente wÃ€hrend der Herstellung dieser Sammlung bearbeitet wurden.
+<p>
+Weitere Operatoren sind <b>NEARx</b> und <b>WITHINx</b>.
+NEARx wird benutzt um den maximalen Abstand (x WÃ¶rter) festzulegen, den zwei Suchbegriffe voneinander haben dÃŒrfen um ein passendes Suchergebnis darzustellen.
+WITHINx legt fest, dass der zweite Suchbegriff innerhalb der nÃ€chsten x WÃ¶rter <i>after</i> des ersten Suchbegriffs auftauchen muss. Das ist dem Operator NEAR Ã€hnlich, aber die Reihenfolge ist von Bedeutung. Der vorgebene Abstand betrÃ€gt 20.}  
+
+_texthelpadvancedsearchextra_ [l=de] {HINWEIS: Diese Operatoren werden ignoriert, wenn Sie im einfachen Suchmodus suchen.}  
+
+_texthelpadvsearchlucene_ [l=de] {Die erweiterte Suche in den Lucene-Sammlungen benutzt die Boole'schen-Operatoren. _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=de] {Feldsuche}  
+
+_texthelpformsearch_ [l=de] {kÃ¶nnen die einzelnen Suchanfragen pro Feld mit UND kombiniert werden (bei einer "alle WÃ¶rter" - Suche) oder mit ODER (bei einer "einige WÃ¶rter - Suche). Suchbegriffe innerhalb der Felder werden in gleicher Weise kombiniert. Im erweiterten Modus kÃ¶nnen Sie mittels Drop-Down-MenÃŒs die Kombination zwischen den Feldern bestimmen (UND/ODER/NICHT). Innerhalb der Felder kÃ¶nnen Sie boolesche Operatoren verwenden.}  
+
+_texthelpformstemming_ [l=de] {Die Optionen "ignoriere GroÃ-/Kleinschreibung" und "ignoriere Wortendungen" sind in der erweiterten Suche zunÃ€chst nicht aktiviert.}  
+
+_textdatesearch_ [l=de] {Anhand von Daten suchen}  
+
+_texthelpdatesearch_ [l=de] {Die Datumssuche ermÃ¶glicht die Suche nach Dokumenten ÃŒber Ereignisse innerhalb einer gewissen Zeitspanne. Sie kÃ¶nnen nach Dokumenten ÃŒber ein bestimmtes Jahr oder ÃŒber eine Folge von Jahren suchen. Beachten Sie, dass Sie die Datumssuche mit anderen Suchbegriffen kombinieren kÃ¶nnen, aber nicht mÃŒssen. Sie kÃ¶nnen auch das Datumsfeld freilassen, dann wird die Datumssuche nicht berÃŒcksichtigt.}  
+
+_texthelpdatehowtotitle_ [l=de] {Wie dieses Angebot zu benutzen ist:}  
+_texthelpdatehowto_ [l=de] {<ul>
+   <li>Suche nach Dokumenten ÃŒber ein einzelnes Jahr:<p>
+   <ul>
+       <li>Geben Sie normale Suchbegriffe wie ÃŒblich ein.
+       <li>Geben Sie das gewÃŒnschte Jahr im Feld "Start- (oder nur) Jahr" ein. 
+       <li>Wenn das gesuchte Jahr vor unserer Zeitrechnung liegt (auch bekannt als vor Christus), wÃ€hlen Sie bitte die "V.U.Z."-Option im Pulldown-MenÃŒ neben dem Feld.
+       <li>Starten Sie Ihre Suche wie ÃŒblich.
+   </ul>
+<p><li>Suche nach Dokumenten ÃŒber einen Zeitraum von mehreren Jahren:<p>
+   <ul>
+       <li>Geben Sie normale Suchbegriffe wie ÃŒblich ein.
+       <li>Geben Sie das frÃŒhere Jahr im Feld "Start- (oder nur) Jahr" ein.
+       <li>Geben Sie das spÃ€tere Jahr im Feld "End-Jahr" ein.
+       <li>WÃ€hlen Sie im nebenstehenden Pulldown-MenÃŒ "V.U.Z." aus, wenn das Jahr vor unserer Zeitrechnung liegt (auch bekannt als vor Christus). 
+       <li>Starten Sie Ihre Suche wie ÃŒblich.
+   </ul>    
+</ul><p>
+}  
+
+_texthelpdateresultstitle_ [l=de] {Die Weise Resultate Ihrer Sucharbeit}  
+_texthelpdateresults_ [l=de] {Die Datumssuche sucht nicht nach Dokumenten, die zu einer bestimmten Zeit verÃ¶ffentlicht wurden oder entstanden sind, sondern nach Dokumenten, die eine bestimmte Zeit zum Thema haben. Eine Suche nach dem Jahr 1903 liefert jedoch auch Dokumente, die einen Zeitraum behandeln, zu dem 1903 gehÃ¶rt (zum Beispiel 1899-1911 oder zwanzigstes Jahrhundert). Das bedeutet, dass in einigen Dokumenten die gesuchten Daten nicht konkret im Text des Dokumentes auftauchen. Bei der Suche nach einem Zeitraum gilt dies fÃŒr alle Jahreszahlen innerhalb des Zeitraums.<p>}  
+
+_textchangeprefs_ [l=de] {Wie kann ich die Einstellungen Ã€ndern?}  
+
+_texthelppreferences_ [l=de] {<p>Wenn Sie den Knopf <i>Einstellungen</i> am Kopf der Seite
+drÃŒcken, kÃ¶nnen Sie einige Eigenschaften der
+BenutzeroberflÃ€che so verÃ€ndern, dass sie Ihren Anforderungen
+entspricht. 
+}  
+
+_texthelpcollectionprefstitle_ [l=de] {Sammlungseinstellungen}  
+_texthelpcollectionprefs_ [l=de] {Einige Sammlungen enthalten mehrere Untersammlungen, welche entweder
+unabhÃ€ngig oder gemeinsam als eine Einheit durchsucht werden
+kÃ¶nnen. Falls dem so ist, kÃ¶nnen Sie auf der Voreinstellungsseite
+festlegen, welche der Untersammlungen im Rahmen Ihrer Anfragen
+berÃŒcksichtigt werden sollen.
+
+}  
+
+_texthelplanguageprefstitle_ [l=de] {SprachprÃ€ferenzen}  
+_texthelplanguageprefs_ [l=de] {<p>Jede Sammlung wird zunÃ€chst in einer Sprache prÃ€sentiert, aber man kann zu anderen Sprachen wechseln. Man kann auch die Kodierung verÃ€ndern, die Greenstone fÃŒr die Anzeige im Browser verwendet -- Greenstone hat eine Vorauswahl getroffen, aber einige Browser erfordern mÃ¶glicherweise eine andere Kodierungseinstellung um alle Zeichen korrekt anzuzeigen.
+Alle Sammlungen ermÃ¶glichen Ihnen von der grafischen Standarddarstellung zur Textanzeige zu wechseln. Das ist besonders nÃŒtzlich fÃŒr Personen mit eingeschrÃ€nkter SehfÃ€higkeit, die die Seite in groÃer Schrift betrachten wollen oder eine Sprachausgabe benutzen.}  
+
+_texthelppresentationprefstitle_ [l=de] {DarstellungsprÃ€ferenzen}  
+_texthelppresentationprefs_ [l=de] {Je nach vorliegender Sammlung kÃ¶nnen verschiedene Optionen
+eingestellt werden, die die Art der Darstellung beeinflussen.<br/>
+
+Bei Sammlungen von Webseiten ist es mÃ¶glich, die Darstellung der 
+Greenstone-Navigationsleiste, die sich am Kopf jeder Dokumentseite befindet,
+zu unterdrÃŒcken. Auf diese Weise endet ihre Anfrage direkt auf der
+Webseite, die ihre Anfrage erfÃŒllt, ohne dass der Greenstoneseitenkopf
+dargestellt wird. Um in diesem Falle eine weitere Suche durchfÃŒhren zu
+kÃ¶nnen, mÃŒssen sie den "ZurÃŒck" Knopf ihres Browsers
+betÃ€tigen. Diese Art der Sammlungen erlaubt es Ihnen auch, die
+Greenstone-Warnmeldungen zu unterdrÃŒcken, die gezeigt werden, wenn Sie
+einen Link verfolgen, der aus der Greenstonesammlung in das World-Wide-Web fÃŒhrt. Weiterhin kÃ¶nnen Sie in manchen Websammlungen
+einstellen, ob die Links auf der Ergebnisseite direkt zur Originalwebseite anstatt zur lokal in der Sammlung gespeicherten Kopie fÃŒhren sollen.<br/>
+
+Sammlungen, die in verschiedenen Sprachen dargestellt werden kÃ¶nnen,
+erlauben ihnen die Wahl der in der BenutzeroberflÃ€che zu verwendenden
+Sprache. Ist die gewÃ€hlte Sprache Chinesisch, so kÃ¶nnen sie
+auÃerdem feststellen, welche der Standardkodierungen fÃŒr Chinesisch
+Ihr Browser verwendet.<br/>
+
+SchlieÃlich erlauben Ihnen alle Sammlungen, anstatt der graphischen
+Standarddarstellung eine Textdarstellung zu verwenden. Dies ist
+besonders fÃŒr sehbehinderte Benutzer sinnvoll, die auf die Verwendung groÃer
+ZeichensÃ€tze oder von GerÃ€ten zur Sprachausgabe angewiesen sind.
+}  
+
+_texthelpsearchprefstitle_ [l=de] {Sucheinstellungen}  
+_texthelpsearchprefs_ [l=de] {Zwei Knopfpaare steuern, ob bei Ihren Anfragen GroÃ- und Kleinschreibung
+beachtet wird, und ob WortstÃ€mme Verwendung finden. Die ersten beiden
+KnÃ¶pfe steuern, ob GroÃ- und Kleinbuchstaben zwischen Ihrer Anfrage
+und den Dokumenttexten ÃŒbereinstimmen mÃŒssen. Die zweiten
+beiden KnÃ¶pfe bestimmen, ob Wortendungen bei der Suche ignoriert werden
+oder nicht. 
+
+<p>Beispiel: wenn die KnÃ¶pfe <i>ignoriere GroÃ-/Kleinschreibung</i> und
+<i>ignoriere Wortendungen</i> angewÃ€hlt sind, wird die Anfrage<p>
+    <ul><kbd>African buildings</kbd></ul>
+      <p>genauso behandelt wie die Anfrage<p>
+      <ul><kbd>africa build</kbd>,</ul><p>
+      da der GroÃbuchstabe in "African" zu einem Kleinbuchstaben
+      transformiert wird und die Endungen "n" and "ing" von
+      "African" und "building" entfernt werden (ausserdem wird "s" von
+      "builds" entfernt).
+
+<p>Sie kÃ¶nnen auch auf einen komplexeren Anfragemodus umschalten,
+welcher es Ihnen gestattet Begriffe zu kombinieren indem Sie sie mittels
+der Operatoren AND (&), OR (|), und NOT (!) verknÃŒpfen. Dies erlaubt
+es Ihnen prÃ€zisere Anfragen zu spezifizieren.
+
+<p>SchlieÃlich kÃ¶nnen Sie die Anzahl der als Antwort zurÃŒckgegebenen Dokumente und der auf einer Seite dargestellten Dokumente einstellen.
+
+}  
+
+_textcasefoldprefs_ [l=de] {Ein Knopfpaar bestimmt, ob groÃe und kleine Buchstaben bei der Suche gleich behandelt werden. Wenn "_preferences:textignorecase_" ausgewÃ€hlt ist, wird beispielsweise zwischen <i>schneckenzucht</i>, <i>Schneckenzucht</i> and <i>SCHNECKENZUCHT</i> nicht unterschieden.}  
+_textstemprefs_ [l=de] {Ein Knopfpaar bestimmt, ob Wortendungen bei der Suche beachtet oder ignoriert werden sollen. Wenn "_preferences:textstem_" ausgewÃ€hlt wurde, wird beispielsweise zwischen <i>snail farming</i>, <i>snails farm</i> und <i>snail farmer</i> nicht unterschieden. Diese Option funktioniert zur Zeit nur bei englischen Texten. _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=de] {Ein Knopfpaar bestimmt, ob Buchstaben mit Akzent und ohne Akzent bei der Suche gleich behandelt werden. Wenn "_preferences:textignoreaccents_" gewÃ€hlt wurde, wird beispielsweise zwischen <i>fÃ©dÃ©ration</i>, <i>fedÃ©ration</i> und <i>federation</i> nicht unterschieden.}  
+ 
+_textstemoptionsprefs_ [l=de] {MÃ¶glicherweise ist die Suche mit Trunkierung einfacher und genauer. ErklÃ€rung siehe "_texthelpquerytermstitle_".}  
+
+_textsearchtypeprefsplain_ [l=de] {Es ist mÃ¶glich ein groÃes Suchfeld zu benutzen, so dass Sie einfach nach ganzen AbsÃ€tzen suchen kÃ¶nnen. Die Suche nach groÃen Textmengen geht ÃŒberraschend schnell.}  
+
+_textsearchtypeprefsform_ [l=de] {Sie kÃ¶nnen die Zahl der Felder verÃ€ndern, die im Suchformular angezeigt werden.}  
+
+_textsearchtypeprefsboth_ [l=de] {Es kann zwischen "einfacher Suche" und "erweiterter Suche" gewechselt werden. 
+<ul>
+<li>Die einfache Suche bietet ein einzelnes Suchfeld. _textsearchtypeprefsplain_</li>
+<li>Die erweiterte Suche bietet mehrere Suchfelder zur Suche in verschiedenen Feldern des Index. So kann in mehreren Feldern gleichzeitig gesucht werden. _textsearchtypeprefsform_ </li>
+</ul>
+}  
+
+
+
+_texttanumbrowseoptions_ [l=de] {Es gibt _numbrowseoptions_ Arten Informationen in
+dieser Sammlung zu finden:}  
+
+_textsimplehelpheading_ [l=de] {Wie finde ich Informationen in der Sammlung "_collectionname_"?}  
+
+_texthelpscopetitle_ [l=de] {Reichweite der Anfragen}
+_texthelpscope_ [l=de] {<p> In den meisten Sammlungen kÃ¶nnen Sie in verschiedenen Indexen
+suchen. Es kann zum Beispiel einen Autoren- und einen Titelindex
+geben. Oder es gibt einen Kapitel- und einen Paragraphenindex. In jedem
+Fall wird ein zu Ihrer Anfrage passendes Dokument immer vollstÃ€ndig
+zurÃŒckgegeben - egal, welchen Index Sie zur Suche verwendet haben.
+<p>Sollte es sich bei den gefundenen Dokumenten um BÃŒcher handeln, so werden sie immer an der passenden Stelle (in der Sammlung) geÃ¶ffnet.
+}  
Index: /gsdl/stable/macros/german2.dm
===================================================================
--- /gsdl/stable/macros/german2.dm	(revision 20131)
+++ /gsdl/stable/macros/german2.dm	(revision 20131)
@@ -0,0 +1,284 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Language text and icon macros 
+# -- this file contains text that is of less importance
+######################################################################
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+### taken from here
+
+_textdescrselcol_ [l=de] {eine Sammlung auswÃ€hlen}  
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text1coll_ [l=de] {Diese Greenstone-Installation enthÃ€lt 1 Sammlung}  
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# should have arguments of collection, collectionname and link
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textmessagedisabled_ [l=de] {Verzeihung, Ihr Account wurde deaktiviert. Bitte kontaktieren Sie den Webmaster dieser Seite.}  
+
+_textmessagepermissiondenied_ [l=de] {Verzeihung, Sie haben keine Zugangserlaubnis zu dieser Seite.}  
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textpaperguide_ [l=de] {Von Papier zur Sammlung}  
+_textorganizerguide_ [l=de] {Benutzung des Organizers}  
+
+######################################################################
+# collectoraction
+package wizard
+
+_textseconds_ [l=de] {"seconds"}  
+
+_textfailmsg21_ [l=de] {Die Sammlung konnte nicht erstellt werden (import.pl scheiterte).}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbuildingcollection_ [l=de] {Sammlung aufbauen ...}  
+
+_textswts_ [l=de] {Angeben, woher die Quelldaten kommen}  
+
+_texttfsiw_ [l=de] {Im vierten Schritt erledigt der Computer die ganze Arbeit. Im "Aufbau"-Prozess erzeugt er alle Indexe und sammelt alle ÃŒbrigen Informationen, die benÃ¶tigt werden, damit alles funktioniert. Aber zuerst mÃŒssen Sie die Informationen spezifizieren.}  
+
+_textadab_ [l=de] {Unten wird ein Diagramm angezeigt, auf dem Sie verfolgen kÃ¶nnen, wo Sie sind. Klicken Sie den grÃŒnen Knopf an, um in der Sequenz fortzufahren. Wenn Sie einen Teil der Sequenz durchlaufen haben, erscheinen die entsprechenden KnÃ¶pfe in gelb. Sie kÃ¶nnen zu einer vorhergehenden Seite zurÃŒckkehren, indem Sie den entsprechenden gelben Knopf anklicken.}  
+
+_textcnmbs_ [l=de] {Der Name der Sammlung muss angegeben werden}  
+_texteambs_ [l=de] {Emailadresse muss angegeben werden}  
+
+_textwcanc_ [l=de] {Um eine neue Sammlung anzulegen, mÃŒssen zuerst einige Informationen ÃŒber die Quelldaten eingegeben werden. Dieser Prozess ist als eine Folge von Webseiten angelegt, die von "Dem Sammler" ÃŒberwacht wird. Der Balken am unteren Ende der Seite zeigt Ihnen an, welche Webseiten noch zu durchlaufen sind.}  
+
+_texttctiasp_ [l=de] {Der Titel der Sammlung ist eine kurze Phrase, die in der gesamten Digitalen Bibliothek benutzt wird um den Inhalt der Sammlung zu identifizieren. Beispieltitel sind "Computer Science Technical Reports" und "Humanity Development Library".}  
+
+_textatc_ [l=de] {Ãber diese Sammlung:}  
+
+_textbtco_ [l=de] {Die Sammlung basieren auf}  
+
+_textdelsuc_ [l=de] {Die Sammlung _cgiargbc1dirname_ wurde erfolgreich gelÃ¶scht.}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+_textcaec_ [l=de] {Vorhandene Sammlung ergÃ€nzen}  
+
+_textselect_ [l=de] {Sammlung auswÃ€hlen}  
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textgreenstone3_ [l=de] {Greenstone lÃ€uft auf Windows, Unix und Mac OS X. Die Distribution enthÃ€lt betriebsfertige BinÃ€rdateien fÃŒr alle Versionen von Windows und fÃŒr Linux und Mac OS X. Sie enthÃ€lt auch den vollstÃ€ndigen Quellcode des Systems, welcher mit Microsoft C++ oder gcc kompiliert werden kann. Greenstone arbeitet mit assoziierter Software, die ebenfalls frei erhÃ€ltlich ist: der Apache-Webserver und PERL. Die BenutzeroberflÃ€che nutzt einen Webbrowser: normalerweise Netscape Navigator oder Internet Explorer.}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglist_ [l=de] {Es gibt eine Mailingliste, die der Diskussion ÃŒber die Digitale-Bibliotheks-Software von Greenstone dienen soll. Aktiven Nutzern von Greenstone wird vorgeschlagen, der Mailingliste beizutreten und an den Diskussionen teilzunehmen. Hier kÃ¶nnen Sie sich anmelden: <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textadduser_ [l=de] {neuen Benutzer hinzufÃŒgen}  
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlistusers_ [l=de] {Benutzer auflisten}  
+
+_textbrowsers_ [l=de] {Browser}  
+_textprotocols_ [l=de] {Protokolle}  
+
+_textusagelog_ [l=de] {Benutzungs-Protokoll}  
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textilog_ [l=de] {Log importieren fÃŒr die Sammlung "_collectionname_" }  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+
+_greenstoneusabilitytext_ [l=de] {Greenstone BenutzerfÃŒhrung}  
+
+_textsend_ [l=de] {Absenden}  
+
+_texttrackreport_ [l=de] {Diesen Report verfolgen}  
+
+ 
+
+_textcritical_ [l=de] {Bedenklich}  
+_textmajor_ [l=de] {Gravierend}  
+
+_textusabbanner_ [l=de] {das Greenstone-Banner im Koru-Stil}  
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+
+_textgtihome_ [l=de] {Diese Seiten helfen Ihnen, die mehrsprachige SprachunterstÃŒtzung von Greenstone zu verbessern. Sie kÃ¶nnen
+<ul>
+  <li>Teile von Greenstone in eine neue Sprache ÃŒbersetzen
+  <li>eine existierende SprachoberflÃ€che aktualisieren, wenn sich die englische SprachoberflÃ€che Ã€ndert (z.B. fÃŒr neue Greenstone-Facilities)
+  <li>Fehler in existierenden Ãbersetzungen korrigieren
+</ul>
+
+Sie bekommen eine Reihe von Webseiten zu sehen. Jede Webseite enthÃ€lt eine Phrase, die Sie ÃŒbersetzen. Das heiÃt, Sie ÃŒbersetzen das Sprachinterface Phrase fÃŒr Phrase.
+Viele Phrasen enthalten Kommandos im HTML-Format: Diese sollen nicht ÃŒbersetzt, sondern vollstÃ€ndig ÃŒbernommen werden. WÃ¶rter, die mit Unterstrichen versehen sind (wie _dieses_) sollen auch nicht ÃŒbersetzt werden (es sind Greenstone "Macro"-Namen).
+<p>
+Wenn Sie eine existierende SprachoberflÃ€che aktualisieren, werden Ihnen keine Phrasen gezeigt, fÃŒr die es schon eine Ãbersetzung gibt. Manchmal existiert eine Ãbersetzung, aber der englische Text wurde geÃ€ndert. In diesem Fall wird die derzeitige Ãbersetzung gezeigt, und Sie sollten prÃŒfen, ob eine Aktualisierung notwendig ist.
+<p>
+Um eine Ãbersetzung zu korrigieren, die schon aktualisiert wurde, verwenden Sie die Einrichtung "Vorhandene Ãbersetzungen korrigieren", die es fÃŒr jeden Teil von Greenstone gibt.
+<p>
+Jede Seite endet mit einem "_textgtisubmit_" Knopf. Wenn Sie den Knopf betÃ€tigen, werden die Ãnderungen sofort in einer separaten Greenstone-Installation auf nzdl.org durchgefÃŒhrt. Auf jeder Seite ist ein Knopf vorhanden, um diese Webseite anzusehen.
+}  
+
+_textgtiselecttlc_ [l=de] {Bitte wÃ€hlen Sie Ihre Sprache}  
+
+#for status page
+
+_textgtigs3core_ [l=de] {Greenstone3 BenutzeroberflÃ€che (Default)}  
+
+#for greenstone manuals
+
+_textgtipapermanual_ [l=de] {Greenstone Anleitung fÃŒr Papier zur Sammlung}  
+
+#for status page
+
+_textgtilastupdated_ [l=de] {Zuletzt aktualisiert}  
+
+############
+# gli page
+############
+package gli
+
Index: /gsdl/stable/macros/gli.dm
===================================================================
--- /gsdl/stable/macros/gli.dm	(revision 20131)
+++ /gsdl/stable/macros/gli.dm	(revision 20131)
@@ -0,0 +1,101 @@
+# this file must be UTF-8 encoded
+
+package gli
+
+#######################################################################
+# global navigation links
+#######################################################################
+
+_globallinks_ {_homelink_}
+
+#######################################################################
+# page content
+#######################################################################
+
+
+_pagetitle_ {_textgli_}
+
+_content_ {
+<div id="content">
+
+<div class="divbar">
+<p class="navbar">
+_textglilong_
+</p>
+</div>
+
+_If_(_gliapplet_,<p>_gliapplet_</p>)
+
+_textglihelp_
+
+_nzdlpagefooter_
+
+</div>
+}
+
+
+
+_gliapplet_ {
+
+<!--
+ <applet CODEBASE="_httpprefix_/bin/java" 
+    ARCHIVE="SignedGatherer.jar"
+    CODE = "org.greenstone.gatherer.GathererApplet"
+    name = "gatherer"
+    type="application/x-java-applet;version=1.4"
+    pluginspage="http://java.sun.com/products/plugin/1.4/plugin-install.html"
+    width = "380"
+    height = "50" >
+
+        <param name="httpprefix" value="_httpprefix_">
+        <param name="gwcgi" value="_gwcgi_">
+        <param name="collection" value="_cgiargc_">
+ </applet>
+
+-->
+
+
+<object 
+  classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
+
+  width="380" height="50"  name ="gatherer"
+
+  codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_4-windows-i586.cab#Version=1,4,0,0"
+>
+    <param name="type"   value="application/x-java-applet;version=1.4">
+    <param name="scriptable" value="false">
+
+    <param name=code     value="org.greenstone.gatherer.GathererApplet" >
+    <param name=archive  value="_httpprefix_/bin/java/SignedGatherer.jar" >
+    <param name=name     value="gatherer" >
+
+    <param name="httpprefix" value="_httpprefix_">
+    <param name="gwcgi"      value="_gwcgi_">
+    <param name="collection" value="_cgiargc_">
+
+    <comment>
+
+      <embed
+        pluginspage="http://java.sun.com/products/plugin/index.html#download"
+        type="application/x-java-applet;version=1.4"
+        scriptable="false"
+
+        archive  = "_httpprefix_/bin/java/SignedGatherer.jar"
+        code     = "org.greenstone.gatherer.GathererApplet"
+        name     = "gatherer"
+        width    = "380"
+        height   = "50" 
+
+        httpprefix = "_httpprefix_"
+        gwcgi      = "_gwcgi_"
+        collection = "_cgiargc_"
+      >
+
+
+      </embed>
+      <noembed></noembed>
+
+    </comment>
+</object>
+
+}
Index: /gsdl/stable/macros/greek.dm
===================================================================
--- /gsdl/stable/macros/greek.dm	(revision 20131)
+++ /gsdl/stable/macros/greek.dm	(revision 20131)
@@ -0,0 +1,1133 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Greek Language text and icon macros 
+# Many thanks to Dimitris Gavrilis (translated November 2003)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=el] {Î ÎµÏÎ¹Î¿ÎŽÎ¹ÎºÎ­Ï ÎµÎºÎŽÏÏÎµÎ¹Ï /Periodicals}
+_textsource_ [l=el] {Î±ÎœÎ±ÏÎ¿ÏÎ¬ ÏÎ·Î³Î®Ï/ ÏÎ·Î³Î®}
+_textdate_ [l=el] {Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î± Î­ÎºÎŽÎ¿ÏÎ·Ï: }
+_textnumpages_ [l=el] {Î±ÏÎ¹ÎžÎŒÏÏ ÏÎµÎ»Î¯ÎŽÏÎœ:}
+
+_textsignin_ [l=el] {ÎÎ³Î³ÏÎ±ÏÎ®}
+
+_textdefaultcontent_ [l=el] {ÎÎµÎœ ÎºÎ±ÏÎ­ÏÏÎ· ÎŽÏ
+ÎœÎ±ÏÎ¿Îœ ÎœÎ± Î²ÏÎµÎžÎµÎ¯ Î· ÏÎµÎ»Î¯ÎŽÎ± ÏÎ¿Ï
+ Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎ±ÏÎµ. Î Î±ÏÎ±ÎºÎ±Î»Î¿ÏÎŒÎµ ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÎµÎ¯ÏÏÎµ ÏÎ·Îœ ÎµÏÎ¹Î»Î¿Î³Î® "ÏÎ¯ÏÏ" Î® ÏÎ·Îœ ÎµÏÎ¹Î»Î¿Î³Î® "Î±ÏÏÎ¹ÎºÎ® ÏÎµÎ»Î¯ÎŽÎ±" Î³Î¹Î± ÎœÎ± Î³Ï
+ÏÎ¯ÏÎµÏÎµ ÏÏÎ·Îœ ÏÎ·ÏÎ¹Î±ÎºÎ® Î²Î¹Î²Î»Î¹Î¿ÎžÎ®ÎºÎ· ÏÎ¿Ï
+ Greenstone.}
+
+_textdefaulttitle_ [l=el] {GSDL Error}
+
+# -- Missing translation: _textbadcollection_
+
+_textselectpage_ [l=el] {-- ÎÏÎ¹Î»Î¿Î³Î® Î£ÎµÎ»Î¯ÎŽÎ±Ï --}
+
+_collectionextra_ [l=el] {ÎÏ
+ÏÎ® Î· ÏÏ
+Î»Î»Î¿Î³Î® ÏÎµÏÎ¹Î­ÏÎµÎ¹ _about:numdocs_ Î­Î³Î³ÏÎ±ÏÎ±. 
+Î€ÏÎ¿ÏÎ¿ÏÎ¿Î¹Î®ÎžÎ·ÎºÎµ ÏÎµÎ»ÎµÏ
+ÏÎ±Î¯Î± ÏÎ¿ÏÎ¬ ÏÏÎ¹Ï _ .}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=el] {<p>ÎÏ
+ÏÎ® Î· ÏÏ
+Î»Î»Î¿Î³Î® ÏÎµÏÎ¹Î»Î±ÎŒÎ²Î¬ÎœÎµÎ¹ _numdocs_ _If_("_numdocs_" eq "1",document,documents), ÏÏÎœÎ¿Î»Î¿ _numbytes_.
+<p><a href="_httppagex_(bsummary)">Î Î±ÏÎ®ÏÏÎµ ÎµÎŽÏ</a> Î³Î¹Î± ÎœÎ± ÎŽÎµÎ¯ÏÎµ Î­ÎœÎ±Îœ  ÏÎµÏÎ¹Î»Î·ÏÏÎ¹ÎºÏ ÏÎ¯ÎœÎ±ÎºÎ± Î±Ï
+ÏÎ®Ï ÏÎ·Ï ÏÏ
+Î»Î»Î¿Î³Î®Ï.
+}
+
+_textdescrcollection_ [l=el] {}
+_textdescrabout_ [l=el] {Î Î»Î·ÏÎ¿ÏÎ¿ÏÎ¯ÎµÏ (Î³Î¹Î±)}
+_textdescrhome_ [l=el] {ÎÏÏÎ¹ÎºÎ® ÏÎµÎ»Î¯ÎŽÎ±}
+_textdescrhelp_ [l=el] {ÎÎ¿Î®ÎžÎµÎ¹Î±}
+_textdescrpref_ [l=el] {ÎÏÎ¹Î»Î¿Î³Î­Ï}
+_textdescrgreenstone_ [l=el] {(ÏÎ¿) Software ÏÎ·Ï ÎšÎ·ÏÎ¹Î±ÎºÎ®Ï ÎÎ¹Î²Î»Î¹Î¿ÎžÎ®ÎºÎ·Ï ÏÎ¿Ï
+ Greenstone}
+_textdescrusab_ [l=el] {Î€Î¹ ÏÎ±Ï ÏÎ¬ÎœÎ·ÎºÎµ ÎŽÏÏÎºÎ¿Î»Î¿ ÎœÎ± ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹Î®ÏÎµÏÎµ;}
+
+_textdescrSearch_ [l=el] {ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ· Î³Î¹Î± ÎµÎ¹ÎŽÎ¹ÎºÎ¿ÏÏ ÏÏÎ¿Ï
+Ï}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=el] {ÎÎ»ÏÎ±Î²Î·ÏÎ¹ÎºÏ ÎµÏ
+ÏÎµÏÎ®ÏÎ¹Î¿ ÏÎ¯ÏÎ»ÏÎœ.}
+_textdescrCreator_ [l=el] {ÎÎ»ÏÎ±Î²Î·ÏÎ¹ÎºÏ ÎµÏ
+ÏÎµÏÎ®ÏÎ¹Î¿ ÏÏ
+Î³Î³ÏÎ±ÏÎ­ÏÎœ}
+_textdescrSubject_ [l=el] {Î£Î¬ÏÏÏÎ· Î±ÎœÎ¬ ÎžÎµÎŒÎ±ÏÎ¹ÎºÎ® ÎºÎ±ÏÎ·Î³Î¿ÏÎ¯Î±}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=el] {ÎÏ
+ÏÎµÏÎ®ÏÎ¹Î¿ Î±ÎœÎ¬ Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î±}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+_textdescrSource_ [l=el] {Î£Î¬ÏÏÏÎ· Î±ÎœÎ¬ Î±ÏÏÎ¹ÎºÏ ÏÎœÎ¿ÎŒÎ± Î±ÏÏÎµÎ¯Î¿Ï
+}
+_textdescrLanguage_ [l=el] {Î£Î¬ÏÏÏÎ· Î±ÎœÎ¬ Î³Î»ÏÏÏÎ±}
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=el] {Î£Î¬ÏÏÏÎ· Î±ÎœÎ¬ Î¿ÏÎ³Î±ÎœÎ¹ÏÎŒÏ}
+_textdescrKeyword_ [l=el] {Î£Î¬ÏÏÏÎ· ÎŒÎµ Î»Î­ÎŸÎ· ÎºÎ»ÎµÎ¹ÎŽÎ¯}
+_textdescrHowto_ [l=el] {ÎÏ
+ÏÎµÏÎ®ÏÎ¹Î¿ ÎºÎ±ÏÎ·Î³Î¿ÏÎ¹ÏÎœ Î ÏÏ ÎœÎ±}
+_textdescrList_ [l=el] {ÎÎ±ÏÎ¬Î»Î¿Î³Î¿Ï ÎÎ³Î³ÏÎ¬ÏÏÎœ}
+_textdescrSeries_ [l=el] {Î£Î¬ÏÏÏÎ· Î±ÎœÎ¬ ÏÎµÏÏÎ¿Ï}
+_textdescrTo_ [l=el] {Î£Î¬ÏÏÏÎ· Î±ÎœÎ¬ Î Î­ÏÎ±ÏÎŒÎ± ÏÎµ ÏÎµÎŽÎ¯Î¿}
+_textdescrFrom_ [l=el] {Î£Î¬ÏÏÏÎ· Î±ÎœÎ¬ ÏÎ¿ÎŒÎ­Î±}
+_textdescrTopic_ [l=el] {ÎÏ
+ÏÎµÏÎ®ÏÎ¹Î¿ ÏÎµÏ
+ÏÏÎœ Î³Î¹Î± ÎµÎ¹ÎŽÎ¹ÎºÎ¬ ÎžÎ­ÎŒÎ±ÏÎ±.}
+_textdescrBrowse_ [l=el] {ÎÏ
+ÏÎµÏÎ®ÏÎ¹Î¿}
+# -- Missing translation: _textdescrCollage_
+_textdescrPeople_ [l=el] {ÎÎ»ÏÎ±Î²Î·ÏÎ¹ÎºÏ ÎµÏ
+ÏÎµÏÎ®ÏÎ¹Î¿ Î±ÎœÎžÏÏÏÏÎœ}
+_textdescrAcronym_ [l=el] {ÎÏ
+ÏÎµÏÎ®ÏÎ¹Î¿ Î±ÎºÏÎ¿ÎœÏ
+ÎŒÎ¯ÏÎœ}
+_textdescrPhrase_ [l=el] {Î£Î¬ÏÏÏÎ· ÏÏÎ¬ÏÎµÏÎœ}
+_textdescrArtist_ [l=el] {ÎÏ
+ÏÎµÏÎ®ÏÎ¹Î¿  ÎºÎ±Î»Î»Î¹ÏÎµÏÎœÏÎœ}
+_textdescrVolume_ [l=el] {Î£Î¬ÏÏÏÎ· Î±ÎœÎ¬ ÏÏÎŒÎ¿}
+# -- Missing translation: _textdescrCountries_
+_textdescrCaptions_ [l=el] {ÎÏ
+ÏÎµÏÎ®ÏÎ¹Î¿ ÏÏÏÎ¿Î³ÏÎ±ÏÎ¹ÏÎœ}
+
+
+_labelSearch_ [l=el] {ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ·}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=el] {Î€Î¯ÏÎ»Î¿Î¹ (Î-Î©)}
+_labelCreator_ [l=el] {Î£Ï
+Î³Î³ÏÎ±ÏÎµÎ¯Ï (Î-Î©)}
+_labelSubject_ [l=el] {ÎÎµÎŒÎ±ÏÎ¹ÎºÎ­Ï ÎµÎœÏÏÎ·ÏÎµÏ}
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=el] {ÎÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯ÎµÏ}
+# -- Missing translation: _labelType_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+_labelSource_ [l=el] {ÎÎœÏÎŒÎ±ÏÎ± Î±ÏÏÎµÎ¯ÏÎœ}
+_labelLanguage_ [l=el] {ÎÎ»ÏÏÏÎ±}
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=el] {ÎÏÎ³Î±ÎœÎ¹ÏÎŒÏÏ}
+_labelKeyword_ [l=el] {ÎÎ­ÎŸÎµÎ¹Ï - ÎºÎ»ÎµÎ¹ÎŽÎ¹Î¬}
+_labelHow_ [l=el] {Î ÏÏ ÎœÎ±}
+_labelSeries_ [l=el] {Î£ÎµÎ¹ÏÎ­Ï}
+_labelList_ [l=el] {Î€Î±ÎŸÎ¹ÎœÏÎŒÎ¹ÏÎ·}
+_labelTo_ [l=el] {ÏÎ­ÏÎ±ÏÎŒÎ± ÏÎµ}
+_labelFrom_ [l=el] {Î±ÏÏ}
+_labelTopic_ [l=el] {ÎÎ­ÎŒÎ±ÏÎ±}
+_labelBrwse_ [l=el] {Î£Î¬ÏÏÏÎ·}
+# -- Missing translation: _labelCollage_
+_labelBrows_ [l=el] {Î£Î¬ÏÏÏÎ·}
+_labelPeople_ [l=el] {ÎÎœÎžÏÏÏÎ¿Î¹ (Î-Î©)}
+_labelAcronym_ [l=el] {ÎÎºÏÎ¿ÎœÏÎŒÎ¹Î±}
+_labelPhrase_ [l=el] {ÎŠÏÎ¬ÏÎµÎ¹Ï}
+_labelArtist_ [l=el] {ÎÎ±Î»Î»Î¹ÏÎ­ÏÎœÎµÏ}
+_labelVolume_ [l=el] {Î€ÏÎŒÎ¿Î¹}
+# -- Missing translation: _labelCaptions_
+# -- Missing translation: _labelCountries_
+
+_texticontext_ [l=el] {ÎÎœÎ¿Î¹Î³ÎŒÎ± ÏÎ¿Ï
+ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+}
+_texticonclosedbook_ [l=el] {Î¬ÎœÎ¿Î¹Î³ÎŒÎ± Î±Ï
+ÏÎ¿Ï ÏÎ¿Ï
+ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+ ÎºÎ±Î¹ ÎµÏÎ¹ÏÎºÏÏÎ¹ÏÎ· ÏÏÎœ ÏÎµÏÎ¹ÎµÏÎ¿ÎŒÎ­ÎœÏÎœ.}
+_texticonnext_ [l=el] {ÏÎ­ÏÎ±ÏÎŒÎ± ÏÏÎ·Îœ ÎµÏÏÎŒÎµÎœÎ· ÎµÎœÏÏÎ·ÏÎ±}
+_texticonprev_ [l=el] {ÏÎ­ÏÎ±ÏÎŒÎ± ÏÏÎ·Îœ ÏÏÎ¿Î·Î³Î¿ÏÎŒÎµÎœÎ· ÎµÎœÏÏÎ·ÏÎ±}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=el] {ÎÎœÎ¿Î¹Î³ÎŒÎ± ÏÎ¿Ï
+ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+ ÏÎµ ÎŒÎ¿ÏÏÎ® MIDI }
+_texticonmsword_ [l=el] {ÎÎœÎ¿Î¹Î³ÎŒÎ± ÏÎ¿Ï
+ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+ ÏÎµ ÎŒÎ¿ÏÏÎ® Microsoft Word }
+_texticonmp3_ [l=el] {ÎÎœÎ¿Î¹Î³ÎŒÎ± ÏÎ¿Ï
+ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+ ÏÎµ ÎŒÎ¿ÏÏÎ® MP3 }
+_texticonpdf_ [l=el] {ÎÎœÎ¿Î¹Î³ÎŒÎ± ÏÎ¿Ï
+ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+ ÏÎµ ÎŒÎ¿ÏÏÎ® PDF}
+_texticonps_ [l=el] {ÎÎœÎ¿Î¹Î³ÎŒÎ± ÏÎ¿Ï
+ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+ ÏÎµ ÎŒÎ¿ÏÏÎ® PostScript }
+_texticonppt_ [l=el] {ÎÎœÎ¿Î¹Î³ÎŒÎ± ÏÎ¿Ï
+ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+ ÏÎµ ÎŒÎ¿ÏÏÎ® PowerPoint }
+_texticonrtf_ [l=el] {ÎÎœÎ¿Î¹Î³ÎŒÎ± ÏÎ¿Ï
+ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+ ÏÎµ ÎŒÎ¿ÏÏÎ® RTF }
+_texticonxls_ [l=el] {ÎÎœÎ¿Î¹Î³ÎŒÎ± ÏÎ¿Ï
+ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+ ÏÎµ ÎŒÎ¿ÏÏÎ® Microsoft Excel }
+
+_page_ [l=el] {ÏÎµÎ»Î¯ÎŽÎ±}
+_pages_ [l=el] {ÏÎµÎ»Î¯ÎŽÎµÏ}
+_of_ [l=el] {Î±ÏÏ}
+_vol_ [l=el] {ÏÏÎŒÎ¿Ï}
+_num_ [l=el] {ÎÏ.}
+
+_textmonth00_ [l=el] {}
+_textmonth01_ [l=el] {ÎÎ±ÎœÎ¿Ï
+Î¬ÏÎ¹Î¿Ï}
+_textmonth02_ [l=el] {ÎŠÎµÎ²ÏÎ¿Ï
+Î¬ÏÎ¹Î¿Ï}
+_textmonth03_ [l=el] {ÎÎ¬ÏÏÎ¹Î¿Ï}
+_textmonth04_ [l=el] {ÎÏÏÎ¯Î»Î¹Î¿Ï}
+_textmonth05_ [l=el] {ÎÎ¬Î¹Î¿Ï}
+_textmonth06_ [l=el] {ÎÎ¿ÏÎœÎ¹Î¿Ï}
+_textmonth07_ [l=el] {ÎÎ¿ÏÎ»Î¹Î¿Ï}
+_textmonth08_ [l=el] {ÎÏÎ³Î¿Ï
+ÏÏÎ¿Ï}
+_textmonth09_ [l=el] {Î£ÎµÏÏÎ­ÎŒÎ²ÏÎ¹Î¿Ï}
+_textmonth10_ [l=el] {ÎÎºÏÏÎ²ÏÎ¹Î¿Ï}
+_textmonth11_ [l=el] {ÎÎ¿Î­ÎŒÎ²ÏÎ¹Î¿Ï}
+_textmonth12_ [l=el] {ÎÎµÎºÎ­ÎŒÎ²ÏÎ¹Î¿Ï}
+
+_textdocument_ [l=el] {ÎÎ³ÏÎ±ÏÎ¿}
+_textsection_ [l=el] {ÎÎœÏÏÎ·ÏÎ±}
+_textparagraph_ [l=el] {Î Î±ÏÎ¬Î³ÏÎ±ÏÎ¿Ï}
+
+_magazines_ [l=el] {Î ÎµÏÎ¹Î¿ÎŽÎ¹ÎºÎ¬}
+
+_nzdlpagefooter_ [l=el] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}
+
+_linktextHOME_ [l=el] {ÎÎ¡Î§ÎÎÎ Î£ÎÎÎÎÎ}
+_linktextHELP_ [l=el] {ÎÎÎÎÎÎÎ}
+_linktextPREFERENCES_ [l=el] {ÎÎ ÎÎÎÎÎÎ£}
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=el] {ÏÏÎµÏÎ¹ÎºÎ¬ ÎŒÎµ Î±Ï
+ÏÎ®Îœ ÏÎ· ÏÏ
+Î»Î»Î¿Î³Î®}
+
+_textsubcols1_ [l=el] {<p>Î ÏÏ
+Î»Î»Î¿Î³Î® ÏÎµÏÎ¹Î­ÏÎµÎ¹ ÏÏ
+ÎœÎ¿Î»Î¹ÎºÎ¬ _1_ Ï
+ÏÎ¿ÏÏ
+Î»Î»Î¿Î³Î­Ï. 
+ÎÏ
+ÏÎ® ÏÎ· ÏÏÎ¹Î³ÎŒÎ® ÎµÎ¯ÎœÎ±Î¹ ÎŽÎ¹Î±ÎžÎ­ÏÎ¹ÎŒÎµÏ:
+<blockquote>}
+
+_textsubcols2_ [l=el] {</blockquote>
+ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± ÎµÎ»Î­Î³ÎŸÎµÏÎµ ÏÎ¿Î¹ÎµÏ ÏÏ
+Î»Î»Î¿Î³Î­Ï ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÎµÎ¯ÏÎµ Î±Ï
+ÏÎ® ÏÎ· ÏÏÎ¹Î³ÎŒÎ® (Î® ÎœÎ± ÏÎ¹Ï Î±Î»Î»Î¬ÎŸÎµÏÎµ) ÏÏÎ· ÏÎµÎ»Î¯ÎŽÎ± ÏÏÎœ ÎÏÎ¹Î»Î¿Î³ÏÎœ.}
+
+
+_titleabout_ [l=el] {ÏÎ»Î·ÏÎ¿ÏÎ¿ÏÎ¯ÎµÏ}
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+# -- Missing translation: _texticonhcoll_
+# -- Missing translation: _texticonhcapt_
+# -- Missing translation: _texticonhcount_
+
+_texticonopenbookshelf_ [l=el] {ÎºÎ»ÎµÎ¯ÏÎµ Î±Ï
+ÏÎ® ÏÎ·Îœ ÎµÎœÏÏÎ·ÏÎ± ÏÎ·Ï Î²Î¹Î²Î»Î¹Î¿ÎžÎ®ÎºÎ·Ï}
+_texticonclosedbookshelf_ [l=el] {Î¬ÎœÎ¿Î¹ÎŸÎµ Î±Ï
+ÏÎ® ÏÎ·Îœ ÎµÎœÏÏÎ·ÏÎ± ÏÎ·Ï Î²Î¹Î²Î»Î¹Î¿ÎžÎ®ÎºÎ·Ï ÎºÎ±Î¹ ÎŽÎµÏ ÏÎ± ÏÎµÏÎ¹ÎµÏÏÎŒÎµÎœÎ±}
+_texticonopenbook_ [l=el] {ÎºÎ»ÎµÎ¯ÏÎµ Î±Ï
+ÏÏ ÏÎ¿ Î²Î¹Î²Î»Î¯Î¿}
+_texticonclosedfolder_ [l=el] {ÎÎœÎ¿Î¹ÎŸÎµ Î±Ï
+ÏÏÎœ ÏÎ¿ ÏÎ¬ÎºÎµÎ»Î¿ ÎºÎ±Î¹ ÎŽÎµÏ ÏÎ± ÏÎµÏÎ¹ÎµÏÏÎŒÎµÎœÎ±.}
+_texticonclosedfolder2_ [l=el] {Î¬ÎœÎ¿Î¹ÎŸÎµ ÏÎ·Îœ Ï
+ÏÎ¿ÎµÎœÏÏÎ·ÏÎ±:}
+_texticonopenfolder_ [l=el] {ÎºÎ»ÎµÎ¯ÏÎµ Î±Ï
+ÏÏÎœ ÏÎ¿ ÏÎ¬ÎºÎµÎ»Î¿}
+_texticonopenfolder2_ [l=el] {ÎºÎ»ÎµÎ¯ÏÎµ ÏÎ·Îœ Ï
+ÏÎ¿ÎµÎœÏÏÎ·ÏÎ±:}
+_texticonsmalltext_ [l=el] {ÏÏÎ¿Î²Î¿Î»Î® Î±Ï
+ÏÎ¿Ï ÏÎ¿Ï
+ ÏÎŒÎ®ÎŒÎ±ÏÎ¿Ï ÏÎ¿Ï
+ ÎºÎµÎ¹ÎŒÎ­ÎœÎ¿Ï
+}
+_texticonsmalltext2_ [l=el] {ÏÏÎ¿Î²Î¿Î»Î® ÎºÎµÎ¹ÎŒÎ­ÎœÎ¿Ï
+}
+_texticonpointer_ [l=el] {ÏÏÎ­ÏÎ¿Ï
+ÏÎ± ÎµÎœÏÏÎ·ÏÎ± }
+_texticondetach_ [l=el] {ÎÎœÎ¿Î¹ÎŸÎµ Î±Ï
+ÏÎ® ÏÎ· ÏÎµÎ»Î¯ÎŽÎ± ÏÎµ ÎœÎ­Î¿ ÏÎ±ÏÎ¬ÎžÏ
+ÏÎ¿}
+_texticonhighlight_ [l=el] {Î¥ÏÎ¿Î³ÏÎ¬ÎŒÎŒÎ¹ÏÎ· ÏÏÏÎœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+_texticonnohighlight_ [l=el] {ÎÎ· ÎµÏÎ¹ÏÎ®ÎŒÎ±ÎœÏÎ· ÏÏÏÎœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+_texticoncontracttoc_ [l=el] {Î£ÏÎŒÏÏÎ·ÎŸÎ· ÏÎ¿Ï
+ ÏÎ¯ÎœÎ±ÎºÎ± ÏÎµÏÎ¹ÎµÏÎ¿ÎŒÎ­ÎœÏÎœ}
+_texticonexpandtoc_ [l=el] {ÎÎœÎ¬ÏÏÏ
+ÎŸÎ· ÏÎ¿Ï
+ ÏÎ¯ÎœÎ±ÎºÎ± ÏÎµÏÎ¹ÎµÏÎ¿ÎŒÎ­ÎœÏÎœ}
+_texticonexpandtext_ [l=el] {ÎÎŒÏÎ¬ÎœÎ¹ÏÎµ Î¿Î»ÏÎºÎ»Î·ÏÎ¿ ÏÎ¿ ÎºÎµÎ¯ÎŒÎµÎœÎ¿}
+_texticoncontracttext_ [l=el] {ÎÎŒÏÎ¬ÎœÎ¹ÏÎ· ÎºÎµÎ¹ÎŒÎ­ÎœÎ¿Ï
+ ÎŒÏÎœÎ¿ Î³Î¹Î± ÏÎ·Îœ ÏÏÎ¿ÎµÏÎ¹Î»ÎµÎ³ÎŒÎ­ÎœÎ· ÎµÎœÏÏÎ·ÏÎ±}
+_texticonwarning_ [l=el] {<b>Î ÏÎ¿ÎµÎ¹ÎŽÎ¿ÏÎ¿Î¯Î·ÏÎ·: </b>}
+_texticoncont_ [l=el] {ÎžÎ­Î»ÎµÏÎµ ÎœÎ± ÏÏ
+ÎœÎµÏÎ¯ÏÎµÏÎµ;}
+
+_textltwarning_ [l=el] {<div class="buttons">_imagecont_</div>
+_iconwarning_ÎÎµÎ³Î­ÎœÎžÏ
+ÏÎ· ÏÎ¿Ï
+ ÎºÎµÎ¹ÎŒÎ­ÎœÎ¿Ï
+ ÎµÎŽÏ ÎžÎ± ÏÏÎ¿ÎºÎ±Î»Î­ÏÎµÎ¹ ÏÎ·Îœ ÎµÎŒÏÎ¬ÎœÎ¹ÏÎ· Ï
+ÏÎµÏÎ²Î¿Î»Î¹ÎºÎ¬ ÎŒÎµÎ³Î¬Î»Î¿Ï
+ Î±ÏÎ¹ÎžÎŒÎ¿Ï ÎŽÎµÎŽÎ¿ÎŒÎ­ÎœÏÎœ
+}
+
+_textgoto_ [l=el] {ÏÎ®Î³Î±Î¹ÎœÎµ ÏÏÎ· ÏÎµÎ»Î¯ÎŽÎ±}
+_textintro_ [l=el] {<i>(ÎµÎ¹ÏÎ±Î³ÏÎ³Î¹ÎºÏ ÎºÎµÎ¯ÎŒÎµÎœÎ¿)</i>}
+
+_textCONTINUE_ [l=el] {ÎÎ­Î»ÎµÏÎµ ÎœÎ± ÏÏ
+ÎœÎµÏÎ¯ÏÎµÏÎµ;?}
+
+_textEXPANDTEXT_ [l=el] {ÎÎÎÎÎÎÎ¥Î£Î\nÎÎÎÎÎÎÎÎ¥}
+
+_textCONTRACTCONTENTS_ [l=el] {Î ÎÎ¡ÎÎÎ§ÎÎÎÎÎ\nÎ£Î¥ÎÎÎÎÎÎÎÎ¥}
+
+_textDETACH_ [l=el] {ÎÎ ÎÎ£Î ÎÎ£Î}
+
+_textEXPANDCONTENTS_ [l=el] {ÎÎÎÎÎÎÎ¥Î£Î Î€Î©Î\nÎ ÎÎ¡ÎÎÎ§ÎÎÎÎÎ©Î}
+
+_textCONTRACT_ [l=el] {ÎÎÎÎÎÎÎ\nÎ£Î¥ÎÎÎÎÎÎÎÎ¥}
+
+_textHIGHLIGHT_ [l=el] {Î¥Î ÎÎÎ¡ÎÎÎÎÎ£Î}
+
+_textNOHIGHLIGHT_ [l=el] {Î§Î©Î¡ÎÎ£\nÎ¥Î ÎÎÎ¡ÎÎÎÎÎ£Î}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=el] {_If_(_thislast_,results _thisfirst_ - _thislast_ for query: _cgiargq_,No matches for query: _cgiargq_)}
+_textnoquerytitle_ [l=el] {Î£ÎµÎ»Î¯ÎŽÎ± Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+
+_textsome_ [l=el] {ÎŒÎµÏÎ¹ÎºÎ­Ï}
+_textall_ [l=el] {ÏÎ»Î± /all}
+_textboolean_ [l=el] {ÏÎµÎ»ÎµÏÏÎ­Ï boolean}
+_textranked_ [l=el] {ÏÎ±ÎŸÎ¹ÎœÏÎŒÎ·ÏÎ·}
+_textnatural_ [l=el] {ÏÏ
+ÏÎ¹ÎºÏ}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=el] {ÎÏÏÎ¿ÏÎ¹ÎºÏ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+_textusequery_ [l=el] {ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¯Î·ÏÎµ Î±Ï
+ÏÎ® ÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·}
+_textfreqmsg1_ [l=el] {ÎÎ­ÏÏÎ·ÏÎ· ÎÎ­ÎŸÎµÏÎœ: }
+_textpostprocess_ [l=el] {_If_(_quotedquery_,<br><i>post-processed to find _quotedquery_</i>
+)}
+_textinvalidquery_ [l=el] {Î ÏÏÎœÏÎ±ÎŸÎ· ÏÎ·Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ®Ï ÏÎ±Ï ÎŽÎµÎœ ÎµÎ¯ÎœÎ±Î¹ Î­Î³ÎºÏ
+ÏÎ·}
+
+_textmorethan_ [l=el] {Î ÎµÏÎ¹ÏÏÏÏÎµÏÎ± Î±ÏÏ}
+_textapprox_ [l=el] {Î£ÏÎµÏÎ¹ÎºÎ¬ ÎŒÎµ /About }
+_textnodocs_ [l=el] {ÎÎµÎœ Î²ÏÎ­ÎžÎ·ÎºÎµ ÎºÎ±ÎœÎ­ÎœÎ± Î­Î³Î³ÏÎ±ÏÎ¿ ÏÎ¿Ï
+ ÎœÎ± ÏÎ±Î¹ÏÎ¹Î¬Î¶ÎµÎ¹ ÏÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ® ÏÎ±Ï.}
+_text1doc_ [l=el] {1 Î­Î³Î³ÏÎ±ÏÎ¿ ÏÎ±Î¹ÏÎ¹Î¬Î¶ÎµÎ¹ ÏÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·.}
+_textlotsdocs_ [l=el] {Î±ÏÎ¿ÏÎµÎ»Î­ÏÎŒÎ±ÏÎ± ÏÎ¿Ï
+ ÏÎ±Î¹ÏÎ¹Î¬Î¶Î¿Ï
+Îœ ÏÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ® ÏÎ±Ï.}
+_textmatches_ [l=el] {ÎÏÎ¿ÏÎµÎ»Î­ÏÎŒÎ±ÏÎ±}
+_textbeginsearch_ [l=el] {ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ· ÏÏÏÎ±}
+_textrunquery_ [l=el] {ÎÎºÏÎ­Î»ÎµÏÎ· ÎÏÏÏÎ®ÎŒÎ±ÏÎ¿Ï}
+_textclearform_ [l=el] {ÎÎ¹Î±Î³ÏÎ±ÏÎ® ÏÎ·Ï ÏÏÏÎŒÎ±Ï}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=el] {Î»Î­ÎŸÎ· Î® ÏÏÎ¬ÏÎ·}
+_textinfield_ [l=el] {... ÏÎµ ÏÎµÎŽÎ¯Î¿ }
+_textfoldstem_ [l=el] {(fold, stem)}
+
+_textadvquery_ [l=el] {Î ÎµÎ¹ÏÎ¬Î³ÎµÏÎµ ÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· ÎºÎ±ÏÎµÏ
+ÎžÎµÎ¯Î±Îœ:}
+_textallfields_ [l=el] {ÏÎ»Î± ÏÎ± ÏÎµÎŽÎ¯Î± / all fields}
+_texttextonly_ [l=el] {ÎŒÏÎœÎ¿ ÎºÎµÎ¯ÎŒÎµÎœÎ¿}
+_textand_ [l=el] {ÎºÎ±Î¹ /and}
+_textor_ [l=el] {Î®}
+_textandnot_ [l=el] {ÎºÎ±Î¹ ÏÏÎ¹ / and not}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=el] {ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ· Î³Î¹Î± _indexselection_ _If_(_jselection_, of _jselection_) _If_(_gselection_, at _gselection_ level) _If_(_nselection_, in _nselection_ language) ÏÎ¿Ï
+ ÏÎµÏÎ¹Î»Î±ÎŒÎ²Î¬ÎœÎµÎ¹ _querytypeselection_ (Î±ÏÏ ÏÎ¹Ï) Î»Î­ÎŸÎµÎ¹Ï}
+
+_textadvancedsearch_ [l=el] {ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ· _indexselection_ _If_(_jselection_, of _jselection_) _If_(_gselection_, at _gselection_ level)_If_(_nselection_, in _nselection_ language) using _querytypeselection_ query}
+
+_textformsimplesearch_ [l=el] {ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ· _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )for _formquerytypesimpleselection_ of}
+
+_textformadvancedsearch_ [l=el] {ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ· _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )ÎºÎ±Î¹ ÎµÏÎ¯ÎŽÎµÎ¹ÎŸÎ· Î±ÏÎ¿ÏÎµÎ»ÎµÏÎŒÎ¬ÏÏÎœ ÏÎ±ÎŸÎ¹ÎœÎ¿ÎŒÎ·ÎŒÎ­ÎœÎ± Î±ÎœÎ¬ _formquerytypeadvancedselection_ }
+
+
+_textnojsformwarning_ [l=el] {Î ÏÎ¿ÎµÎ¹ÎŽÎ¿ÏÎ¿Î¯Î·ÏÎ·: ÏÏÎ¿Îœ web browser ÏÎ±Ï ÎµÎŒÏÎ±ÎœÎ¯Î¶ÎµÏÎ±Î¹ ÎºÎµÎ¯ÎŒÎµÎœÎ¿ Java. <br>ÎÎ¹Î± ÎœÎ± ÏÎ¿ ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹Î®ÏÎµÏÎµ Î±ÏÏ ÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· , ÏÎ±ÏÎ±ÎºÎ±Î»Î¿ÏÎŒÎµ ÎµÎœÎµÏÎ³Î¿ÏÎ¿Î¹Î®ÏÏÎµ ÏÎ·Îœ.}
+_textdatesearch_ [l=el] {Î£Îµ Î±Ï
+ÏÎ®Îœ ÏÎ· ÏÏ
+Î»Î»Î¿Î³Î® ÎŒÏÎ¿ÏÎµÎ¯ ÎœÎ± Î³Î¯ÎœÎµÎ¹ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· Î³Î¹Î± Î­Î³Î³ÏÎ±ÏÎ± ÎŒÎ¹Î±Ï ÏÏÎ¿ÎœÎ¹ÎºÎ®Ï ÏÎµÏÎ¹ÏÎŽÎ¿Ï
+, Î® Î³Î¹Î± Î­Î³Î³ÏÎ±ÏÎ± ÏÎ¿Ï
+ ÏÎµÏÎ¹Î»Î±ÎŒÎ²Î¬ÎœÎ¿Ï
+Îœ ÎºÎ¬ÏÎ¿Î¹Î± ÏÏ
+Î³ÎºÎµÎºÏÎ¹ÎŒÎ­ÎœÎ· Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î±. ÎÏ
+ÏÎ® ÎµÎ¯ÎœÎ±Î¹ ÎŒÎ¹Î± ÏÏÎ¿Î±Î¹ÏÎµÏÎ¹ÎºÎ® ÎµÏÎ¹Î»Î¿Î³Î® Î±Ï
+ÏÎ®Ï ÏÎ·Ï ÏÏ
+Î»Î»Î¿Î³Î®Ï.}
+_textstartdate_ [l=el] {ÎÏÏÎ¹ÎºÎ® (Î® ÎŒÎ¿ÎœÎ±ÎŽÎ¹ÎºÎ®) Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î±:}
+_textenddate_ [l=el] {Î€ÎµÎ»Î¹ÎºÎ® Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î±:}
+_textbc_ [l=el] {Ï.Î§.}
+_textad_ [l=el] {C.E.}
+_textexplaineras_ [l=el] {Î€Î± Î±ÏÏÎ¹ÎºÎ¬ Î.Î. ( C.E.) ÎºÎ±Î¹ Î .Î.Î.(B.C.E.) ÎµÎ¯ÎœÎ±Î¹ ÎµÎœÎ±Î»Î»Î±ÎºÏÎ¹ÎºÎ¬ ÏÏÎœ ÎŒ.Î§.(ÎŒÎµÏÎ¬ Î§ÏÎ¹ÏÏÎ¿Ï) ÎºÎ±Î¹ Ï.Î§. (ÏÏÎ¿ Î§ÏÎ¹ÏÏÎ¿Ï) ÎÏ
+ÏÎ® Î¿Î¹ ÏÏÎ¿Î¹ ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹Î¿ÏÎœÏÎ±Î¹ Î¿ÏÏÏÏ ÏÏÏÎµ ÎœÎ± ÎŒÎ·Îœ Î³Î¯ÎœÎ¿ÎœÏÎ±Î¹ ÎŽÎ¹Î±ÎºÎÏÎ¹ÏÎµÎ¹Ï ÎŒÎµÏÎ±ÎŸÏ ÎŽÎ¹Î±ÏÎ¿ÏÎµÏÎ¹ÎºÏÎœ ÏÎ¿Î»Î¹ÏÎ¹ÏÎŒÏÎœ/ ÎžÏÎ·ÏÎºÎ¹ÏÎœ ÎºÎ±Î¹ Î±ÎœÏÎ¹ÏÏÎ¿ÏÏÏÎµÏÎ¿Ï
+Îœ ÏÎ¹Ï ÏÏÎ¬ÏÎµÎ¹Ï "ÎÎ¿Î¹ÎœÎ® ÎÏÎ¿ÏÎ®" ÎºÎ±Î¹ "Î ÏÎ¹Îœ ÏÎ·Îœ ÎÎ¿Î¹ÎœÎ® ÎÏÎ¿ÏÎ®". }
+
+_textstemon_ [l=el] {(Î±Î³ÏÎ·ÏÎµ ÏÎ¹Ï ÎºÎ±ÏÎ±Î»Î®ÎŸÎµÎ¹Ï ÏÏÎœ Î»Î­ÎŸÎµÏÎœ)}
+
+_textsearchhistory_ [l=el] {ÎÏÏÎ¿ÏÎ¹ÎºÏ ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+
+#text macros for search history
+_textnohistory_ [l=el] {Î€Î¿ Î¹ÏÏÎ¿ÏÎ¹ÎºÏ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï ÎŽÎµÎœ ÎµÎ¯ÎœÎ±Î¹ ÎŽÎ¹Î±ÎžÎ­ÏÎ¹ÎŒÎ¿.}
+_texthresult_ [l=el] {Î±ÏÎ¿ÏÎ­Î»ÎµÏÎŒÎ±}
+_texthresults_ [l=el] {Î±ÏÎ¿ÏÎµÎ»Î­ÏÎŒÎ±ÏÎ±}
+_texthallwords_ [l=el] {ÏÎ»ÎµÏ Î¿Î¹ Î»Î­ÎŸÎµÎ¹Ï}
+_texthsomewords_ [l=el] {ÎŒÎµÏÎ¹ÎºÎ­Ï Î»Î­ÎŸÎµÎ¹Ï}
+_texthboolean_ [l=el] {Î§Î±ÏÎ±ÎºÏÎ®ÏÎµÏ boolean}
+_texthranked_ [l=el] {ÏÎ±ÎŸÎ¹ÎœÏÎŒÎ·ÏÎ·}
+_texthcaseon_ [l=el] {ÏÎ±Î¯ÏÎ¹Î±ÏÎŒÎ± ÏÎµÎ¶ÏÎœ- ÎºÎµÏÎ±Î»Î±Î¯ÏÎœ}
+_texthcaseoff_ [l=el] {casefolded}
+_texthstemon_ [l=el] {ÎŒÏÎœÎ¿ ÏÎ¯Î¶Î± Î»Î­ÎŸÎ·Ï}
+_texthstemoff_ [l=el] {unstemmed}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=el] {ÎÎ¹ ÎµÏÎ¹Î»Î¿Î³Î­Ï Î­ÏÎ¿Ï
+Îœ ÏÏ
+ÎžÎŒÎ¹ÏÏÎµÎ¯ ÏÏ ÎµÎŸÎ®Ï. ÎÎ·Îœ ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÎµÎ¯ÏÎµ ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ "ÏÎ¯ÏÏ"- ÎžÎ± ÏÎ¹Ï Î±ÏÎ¿ÏÏÏ
+ÎžÎŒÎ¯ÏÎµÎ¹! ÎÎœÏ' Î±Ï
+ÏÎ¿Ï ÏÎ±ÏÎ®ÏÏÎµ Î­ÎœÎ± Î±ÏÏ ÏÎ± ÎºÎ¿Ï
+ÎŒÏÎ¹Î¬ ÏÎ·Ï ÎŒÏÎ¬ÏÎ±Ï ÏÏÏÏÎ²Î±ÏÎ·Ï Î±ÏÏ ÏÎ¬ÎœÏ.
+}
+_textsetprefs_ [l=el] {Î¡ÏÎžÎŒÎ¹ÏÎ· ÎµÏÎ¹Î»Î¿Î³ÏÎœ}
+_textsearchprefs_ [l=el] {ÂšÎÏÎ¹Î»Î¿Î³Î­Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+_textcollectionprefs_ [l=el] {ÎÏÎ¹Î»Î¿Î³Î­Ï Î£Ï
+Î»Î»Î¿Î³Î®Ï}
+_textpresentationprefs_ [l=el] {ÎÏÎ¹Î»Î¿Î³Î­Ï ÏÎ±ÏÎ¿Ï
+ÏÎ¯Î±ÏÎ·Ï}
+_textpreferences_ [l=el] {ÎÏÎ¹Î»Î¿Î³Î­Ï}
+_textcasediffs_ [l=el] {ÎÎ¹Î±ÏÎ¿ÏÎ¬ ÏÎµÎ¶ÏÎœ - ÎºÎµÏÎ±Î»Î±Î¯ÏÎœ:}
+_textignorecase_ [l=el] {Î±Î³ÎœÏÎ·ÏÎµ ÏÎ· ÎŽÎ¹Î±ÏÎ¿ÏÎ¬ ÏÎµÎ¶ÏÎœ -ÎºÎµÏÎ±Î»Î±Î¯ÏÎœ}
+_textmatchcase_ [l=el] {Î ÎµÎ¶Î¬- ÎºÎµÏÎ±Î»Î±Î¯Î± Î³ÏÎ¬ÎŒÎŒÎ±ÏÎ± ÏÏÎ­ÏÎµÎ¹ ÎœÎ± ÏÎ±Î¹ÏÎ¹Î¬Î¶Î¿Ï
+Îœ}
+_textwordends_ [l=el] {ÎºÎ±ÏÎ±Î»Î®ÎŸÎµÎ¹Ï Î»Î­ÎŸÎµÏÎœ:}
+_textstem_ [l=el] {Î±Î³ÎœÏÎ·ÏÎµ ÏÎ¹Ï ÎºÎ±ÏÎ±Î»Î®ÎŸÎµÎ¹Ï ÏÏÎœ Î»Î­ÎŸÎµÏÎœ}
+_textnostem_ [l=el] {ÏÎ±Î¯ÏÎ¹Î±ÏÎŒÎ± Î¿Î»ÏÎºÎ»Î·ÏÎ·Ï ÏÎ·Ï Î»Î­ÎŸÎ·Ï}
+_textprefop_ [l=el] {_maxdocoption_ hits with _hitsperpageoption_ Î±ÏÎ¿ÏÎµÎ»Î­ÏÎŒÎ±ÏÎ± Î±ÎœÎ¬ ÏÎµÎ»Î¯ÎŽÎ±.}
+_textextlink_ [l=el] {Î ÏÏÏÎ²Î±ÏÎ· ÏÎµ ÎµÎŸÏÏÎµÏÎ¹ÎºÎ­Ï ÏÎµÎ»Î¯ÎŽÎµÏ ÏÏÎ¿ Web:}
+_textintlink_ [l=el] {Î ÏÎ·Î³Î® ÏÎ¿Ï
+ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+ Î­ÏÎµÎ¹ Î±ÎœÎ±ÎºÏÎ·ÎžÎµÎ¯ Î±ÏÏ:}
+_textlanguage_ [l=el] {Î³Î»ÏÏÏÎ± ÎµÏÎ¹ÏÎ¬ÎœÎµÎ¹Î±Ï ÎµÏÎ³Î±ÏÎ¯Î±Ï:}
+_textencoding_ [l=el] {ÎÏÎŽÎ¹ÎºÎ¿ÏÎ¿Î¯Î·ÏÎ·:}
+_textformat_ [l=el] {ÎŠÏÏÎŒÎ± ÎµÏÎ¹ÏÎ¬ÎœÎµÎ¹Î±Ï ÎµÏÎ³Î±ÏÎ¯Î±Ï:}
+_textall_ [l=el] {ÏÎ»Î±}
+_textquerymode_ [l=el] {Î€ÏÏÏÎ¿Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï:}
+_textsimplemode_ [l=el] {Î±ÏÎ»Î® Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·}
+_textadvancedmode_ [l=el] {ÏÏÎœÎžÎµÏÎ¿Ï ÏÏÏÏÎ¿Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï (ÏÎ±Ï ÎµÏÎ¹ÏÏÎ­ÏÎµÎ¹ ÎœÎ± ÎºÎ¬ÎœÎµÏÎµ Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÎ¹Ï ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÏÎœÏÎ±Ï Î»Î¿Î³Î¹ÎºÎ¿ÏÏ ÏÎµÎ»ÎµÏÏÎ­Ï: !, &, |, ÎºÎ±Î¹ ÏÎ±ÏÎ­ÎœÎžÎµÏÎ·)}
+_textlinkinterm_ [l=el] {ÎŒÎ­ÏÏ ÎµÎœÎŽÎ¹Î¬ÎŒÎµÏÎ·Ï ÏÎµÎ»Î¯ÎŽÎ±Ï}
+_textlinkdirect_ [l=el] {ÏÎ®Î³Î±Î¹ÎœÎµ ÎºÎ±ÏÎµÏ
+ÎžÎµÎ¯Î±Îœ ÎµÎºÎµÎ¯}
+_textdigitlib_ [l=el] {Î ÎšÎ·ÏÎ¹Î±ÎºÎ® ÎÎ¹Î²Î»Î¹Î¿ÎžÎ®ÎºÎ·}
+_textweb_ [l=el] {Î ÏÎ¿Ï ÎÏÏÎ¿ÏÎµÎ»Î¯ÎŽÎ±}
+_textgraphical_ [l=el] {ÎÏÎ±ÏÎ¹ÎºÎ¬ }
+_texttextual_ [l=el] {ÎÎ¿ÏÏÎ® ÎºÎµÎ¹ÎŒÎ­ÎœÎ¿Ï
+}
+_textcollectionoption_ [l=el] {<p>
+ÎÎ¹ Ï
+ÏÎ¿ÏÏ
+Î»Î»Î¿Î³Î­Ï ÎœÎ± ÏÎµÏÎ¹Î»Î±ÎŒÎ²Î¬ÎœÎ¿Ï
+Îœ: 
+<br>}
+
+_textrelateddocdisplay_ [l=el] {ÎÏÎ¯ÎŽÎµÎ¹ÎŸÎ· ÏÏ
+ÎœÎ±ÏÏÎœ ÎµÎ³Î³ÏÎ¬ÏÏÎœ}
+_textsearchhistory_ [l=el] {ÎÏÏÎ¿ÏÎ¹ÎºÏ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï:}
+_textnohistory_ [l=el] {ÎÎµÎœ Ï
+ÏÎ¬ÏÏÎµÎ¹ Î¹ÏÏÎ¿ÏÎ¹ÎºÏ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+_texthistorydisplay_ [l=el] {ÎÏÎ¯ÎŽÎµÎ¹ÎŸÎ· _historynumrecords_ ÏÏÎœ Î±ÏÏÎµÎ¯ÏÎœ Î¹ÏÏÎ¿ÏÎ¹ÎºÎ¿Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+_textnohistorydisplay_ [l=el] {ÎÎ± ÎŒÎ·Îœ ÏÎ±ÏÎ¿Ï
+ÏÎ¹Î¬Î¶ÎµÏÎ±Î¹ ÏÎ¿ Î¹ÏÏÎ¿ÏÎ¹ÎºÏ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=el] {ÎŠÏÏÎŒÎ± Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï:}
+_textplainsearch_ [l=el] {ÎÏÎ»Î® Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·}
+_textqueryboxsize_ [l=el] {ÎÎ­Î³ÎµÎžÎ¿Ï ÎºÎ¿Ï
+ÏÎ¹Î¿Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï:}
+_textregbox_ [l=el] {ÎºÎ±ÎœÎ¿ÎœÎ¹ÎºÏ ÎºÎ¿Ï
+ÏÎ¯ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+_textbigbox_ [l=el] {ÎŒÎµÎ³Î¬Î»Î¿ ÎºÎ¿Ï
+ÏÎ¯ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+_textformtype_ [l=el] {ÎÏÏ ÏÏÏÎ¿:}
+_textsimple_ [l=el] {Î±ÏÎ»Î®}
+_textadvanced_ [l=el] {ÏÏÎœÎžÎµÏÎ¿Ï}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=el] {ÎŒÎµ}
+_textfields_ [l=el] {ÏÎµÎŽÎ¯Î±}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=el] {Î€Î±ÎŸÎ¹ÎœÏÎŒÎ·ÏÎ· ÎµÎ³Î³ÏÎ¬ÏÏÎœ Î±ÎœÎ¬}
+_textalsoshowing_ [l=el] {ÎµÎŒÏÎ¬ÎœÎ¹ÏÎ·}
+_textwith_ [l=el] {ÎŒÎµ ÏÎ¹Ï ÏÎµÏÎ¹ÏÏÏÏÎµÏÎµÏ}
+_textdocsperpage_ [l=el] {Î­Î³Î³ÏÎ±ÏÎ± Î±ÎœÎ¬ ÏÎµÎ»Î¯ÎŽÎ±}
+
+_textfilterby_ [l=el] {ÎÏ
+ÏÎµÏÎ· ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+ ÏÎ¿Ï
+ ÎœÎ± ÏÎµÏÎ¹Î­ÏÎµÎ¹}
+_textall_ [l=el] {ÏÎ»Î±}
+_textany_ [l=el] {ÎŒÎµÏÎ¹ÎºÎ¬}
+_textwords_ [l=el] {Î±ÏÏ ÏÎ¹Ï Î»Î­ÎŸÎµÎ¹Ï}
+_textleaveblank_ [l=el] {Î±ÏÎ®ÏÏÎµ Î±Ï
+ÏÏ ÏÎ¿ ÎºÎ¿Ï
+ÏÎ¯ ÎºÎµÎœÏ Î³Î¹Î± ÎœÎ± Î±ÎœÎ±ÎºÏÎ®ÏÎµÏÎµ ÏÎ»Î± ÏÎ± Î­Î³Î³ÏÎ±ÏÎ±}
+
+_browsebuttontext_ [l=el] {"Î€Î±ÎŸÎ¹ÎœÏÎŒÎ·ÏÎ· ÎÎ³Î³ÏÎ¬ÏÏÎœ" }
+
+_nodata_ [l=el] {<i>no data</i>}
+_docs_ [l=el] {Î­Î³Î³ÏÎ±ÏÎ±}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=el] {ÎÎ¿Î®ÎžÎµÎ¹Î±}
+_textSearchshort_ [l=el] {Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· ÎŒÎµ ÏÏ
+Î³ÎºÎµÎºÏÎ¹ÎŒÎ­ÎœÎµÏ Î»Î­ÎŸÎµÎ¹Ï}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÏÎ¯ÏÎ»Î¿}
+_textCreatorshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÏÏ
+Î³Î³ÏÎ±ÏÎ­Î±}
+_textSubjectshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÎžÎ­ÎŒÎ±}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î±}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± ÎŒÎµ ÏÎœÎ¿ÎŒÎ± Î±ÏÏÎµÎ¯Î¿Ï
+}
+_textLanguageshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ Î³Î»ÏÏÏÎ±}
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÏÎµÎ¹ÏÎ¬}
+_textToshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± by To field}
+_textFromshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ Î±ÏÎ¿ÏÏÎ¿Î»Î­Î±/ access publications by From field}
+_textBrowseshort_ [l=el] {ÏÎ¬ÏÏÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î±}
+_textOrganizationshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ Î¿ÏÎ³Î±ÎœÎ¹ÏÎŒÏ}
+_textHowtoshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÏÏ ÏÎ¿Îœ ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿ "ÏÏÏ ÎœÎ±"// by "how to" listing}
+_textTopicshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÎžÎµÎŒÎ±ÏÎ¹ÎºÎ® ÎµÎœÏÏÎ·ÏÎ±}
+_textPeopleshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± ÎŒÎµ Î¿ÎœÏÎŒÎ±ÏÎ± Î±ÎœÎžÏÏÏÏÎœ/ access publications by people}
+_textAcronymshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ Î±ÎºÏÎ¿ÎœÏÎŒÎ¹Î¿}
+_textPhraseshort_ [l=el] {ÏÎ¬ÏÏÏÎ· ÏÏÎ¬ÏÎµÏÎœ ÏÎ¿Ï
+ Ï
+ÏÎ¬ÏÏÎ¿Ï
+Îœ ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î±}
+_textArtistshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÎºÎ±Î»Î»Î¹ÏÎ­ÏÎœÎ·}
+_textKeywordshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± ÎŒÎµ Î»Î­ÎŸÎµÎ¯Ï-ÎºÎ»ÎµÎ¹ÎŽÎ¹Î¬}
+_textVolumeshort_ [l=el] {ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÏÏÎŒÎ¿}
+# -- Missing translation: _textCountriesshort_
+_textdefaultshorttext_ [l=el] {ÎŒÎ· Î¿ÏÎ¹ÏÎŒÎ­ÎœÎ· ÏÎ±ÎŸÎ¹ÎœÏÎŒÎ·ÏÎ·}
+
+_textSearchlong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ <i>ÎœÎ± Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÏÎµ ÎŒÎµÎŒÎ¿ÎœÏÎŒÎ­ÎœÎµÏ Î»Î­ÎŸÎµÎ¹Ï</i> ÏÎ¿Ï
+ ÎµÎŒÏÎ±ÎœÎ¯Î¶Î¿ÎœÏÎ±Î¹ ÏÏÎ¿ ÎºÎµÎ¯ÎŒÎµÎœÎ¿ Î±ÏÏ ÏÎ· ÏÎµÎ»Î¯ÎŽÎ± 'Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï'. ÎÏ
+ÏÎ® ÎµÎ¯ÎœÎ±Î¹ Î· ÏÏÏÏÎ· ÏÎµÎ»Î¯ÎŽÎ± ÏÎ¿Ï
+ ÎµÎŒÏÎ±ÎœÎ¯Î¶ÎµÏÎ±Î¹ Î±Î»Î»Î¬ ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÎµ Î±Ï
+ÏÎ®Îœ ÎºÎ±Î¹ Î±ÏÏ ÏÎ¹Ï Ï
+ÏÏÎ»Î¿Î¹ÏÎµÏ ÏÎµÎ»Î¯ÎŽÎµÏ ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·</i> .  }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=el] {<p>ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± <i>Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÏÎ¯ÏÎ»Î¿</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯
+<i>ÏÎ¯ÏÎ»Î¿Î¹ Î±-Ï</i>.  ÎÎ± ÎµÎŒÏÎ±ÎœÎ¹ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï Î²Î¹Î²Î»Î¯ÏÎœ ÎŒÎµ Î±Î»ÏÎ±Î²Î·ÏÎ¹ÎºÎ® ÏÎµÎ¹ÏÎ¬.}
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=el] {<p>ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ <i>ÎœÎ± Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÏÏ
+Î³Î³ÏÎ±ÏÎ­Î± </i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>ÏÏ
+Î³Î³ÏÎ±ÏÎµÎ¹Ï Î±-Ï</i> ÎÎ± ÏÎ±ÏÎ¿Ï
+ÏÎ¹Î±ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï Î²Î¹Î²Î»Î¯ÏÎœ ÏÎ±ÎŸÎ¹ÎœÎ¿ÎŒÎ·ÎŒÎ­ÎœÎ¿Ï Î²Î¬ÏÎµÎ¹ ÏÎ¿Ï
+ Î¿ÎœÏÎŒÎ±ÏÎ¿Ï ÏÎ¿Ï
+ ÏÏ
+Î³Î³ÏÎ±ÏÎ­Î±.}
+
+_textSubjectlong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± <i>Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÎžÎ­ÎŒÎ±</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>ÎžÎ­ÎŒÎ±ÏÎ±</i> .  ÎÎ± ÎµÎŒÏÎ±ÎœÎ¹ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï ÎžÎµÎŒÎ¬ÏÏÎœ ÎŒÎµ ÏÎ· ÎŒÎ¿ÏÏÎ® ÏÎ±ÏÎ¹ÏÎœ Î²Î¹Î²Î»Î¹Î¿ÎžÎ®ÎºÎ·Ï.  }
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=el] {<p>ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ <i>ÎœÎ± Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î±</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯ÎµÏ</i> .  ÎÎ± ÏÎ±ÏÎ¿Ï
+ÏÎ¹Î±ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï ÏÎµÏ
+ÏÏÎœ ÏÎ±ÎŸÎ¹ÎœÎ¿ÎŒÎ·ÎŒÎ­ÎœÏÎœ ÏÏÎ¿ÎœÎ¿Î»Î¿Î³Î¹ÎºÎ¬.}
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± <i>Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÏÎœÏÎ±Ï Î¿ÎœÏÎŒÎ±ÏÎ± Î±ÏÏÎµÎ¯ÏÎœ</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>Î¿ÎœÏÎŒÎ±ÏÎ± Î±ÏÏÎµÎ¯ÏÎœ</i> .  ÎÎ± ÎµÎŒÏÎ±ÎœÎ¹ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï ÎµÎ³Î³ÏÎ±ÏÏÎœ ÏÎ±ÎŸÎ¹ÎœÎ¿ÎŒÎ·ÎŒÎ­ÎœÎ¿Ï Î±ÎœÎ¬ Î±ÏÏÎ¹ÎºÏ (original) ÏÎœÎ¿ÎŒÎ± Î±ÏÏÎµÎ¯Î¿Ï
+.}
+
+_textLanguagelong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ <i>ÎœÎ± Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ Î³Î»ÏÏÏÎ±</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>Î³Î»ÏÏÏÎµÏ</i> .  ÎÎ± ÏÎ±ÏÎ¿Ï
+ÏÎ¹Î±ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï ÎµÎ¹ÏÎ±Î³ÏÎ³ÏÎœ ÏÎ±ÎŸÎ¹ÎœÎ¿ÎŒÎ·ÎŒÎ­ÎœÏÎœ Î±ÎœÎ¬ Î³Î»ÏÏÏÎ±.}
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ <i>ÎœÎ± Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ Î¿ÏÎ³Î±ÎœÎ¹ÏÎŒÏ</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>Î¿ÏÎ³Î±ÎœÎ¹ÏÎŒÎ¿Î¯</i> .  ÎÎ± ÏÎ±ÏÎ¿Ï
+ÏÎ¹Î±ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï Î¿ÏÎ³Î±ÎœÎ¹ÏÎŒÏÎœ}
+
+_textHowtolong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± <i>Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÏÏ ÏÎ¿Îœ ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿ "ÏÏÏ ÎœÎ±"/ by "how to" listing</i>
+ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>ÏÏÏ ÎœÎ±</i> .  ÎÎ± ÏÎ±ÏÎ¿Ï
+ÏÎ¹Î±ÏÏÎµÎ¯ ÎŒÎ¹Î± Î»Î¯ÏÏÎ± Î±ÏÏ.../ a list of how to
+strings.  }
+
+_textTopiclong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ±  <i>Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÎžÎµÎŒÎ±ÏÎ¹ÎºÎ® ÎµÎœÏÏÎ·ÏÎ±/ by topic</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>ÎžÎµÎŒÎ±ÏÎ¹ÎºÎ® ÎµÎœÏÏÎ·ÏÎ±</i> .  ÎÎ± ÎµÎŒÏÎ±ÎœÎ¹ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï ÎžÎµÎŒÎ±ÏÎ¹ÎºÏÎœ ÎµÎœÎ¿ÏÎ®ÏÏÎœ ÏÏÎ¹Ï Î¿ÏÎ¿Î¯ÎµÏ ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± ÎºÎ¬ÎœÎµÏÎµ ÏÎ¬ÏÏÏÎ·.}
+
+_textTolong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± <i>Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± by To field</i> ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>to</i> .ÎÎ± ÎµÎŒÏÎ±ÎœÎ¹ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï Î±ÏÏÎµÎ¯ÏÎœ.  }
+
+_textFromlong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± <i>Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ Î±ÏÎ¿ÏÏÎ¿Î»Î­Î±</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>Î±ÏÏ</i> .  ÎÎ± ÏÎ±ÏÎ¿Ï
+ÏÎ¹Î±ÏÏÎµÎ¯ Î¿ ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï ÏÏÎœ Î±ÏÎ¿ÏÏÎ¿Î»Î­ÏÎœ.  }
+
+_textSerieslong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± <i>Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÏÎµÎ¹ÏÎ¬/ by series</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>ÏÎµÎ¹ÏÎ­Ï</i> .  ÎÎ± ÎµÎŒÏÎ±ÎœÎ¹ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï ÏÏÎœ ÏÎµÎ¹ÏÏÎœ ÏÎ¿Ï
+ Ï
+ÏÎ¬ÏÏÎ¿Ï
+Îœ Î±Ï
+ÏÎ® ÏÎ· ÏÏÎ¹Î³ÎŒÎ® ÏÏÎ· ÏÏ
+Î»Î»Î¿Î³Î®.}
+
+_textBrowselong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ <i>ÎœÎ± ÎºÎ¬ÎœÎµÏÎµ ÏÎ¬ÏÏÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î±</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯
+<i>ÏÎ¬ÏÏÏÎ·</i>.}
+
+_textPeoplelong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ <i>ÎœÎ± Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÏÎœÏÎ±Ï Î¿ÎœÏÎŒÎ±ÏÎ± Î±ÎœÎžÏÏÏÏÎœ</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>Î¬ÎœÎžÏÏÏÎ¿Î¹</i> .  ÎÎ± ÏÎ±ÏÎ¿Ï
+ÏÎ¹Î±ÏÏÎµÎ¯ Î­ÎœÎ±Ï Î±Î»ÏÎ±Î²Î·ÏÎ¹ÎºÏÏ ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï ÎŒÎµ Î¿ÎœÏÎŒÎ±ÏÎ± Î±ÎœÎžÏÏÏÏÎœ.}
+
+_textAcronymlong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ <i>ÎœÎ± Î­ÏÎµÏÎµ ÏÏÎ¿ÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ Î±ÎºÏÎ¿ÎœÏÎŒÎ¹Î¿</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>Î±ÎºÏÎ¿ÎœÏÎŒÎ¹Î±</i>.  ÎÎ± ÏÎ±ÏÎ¿Ï
+ÏÎ¹Î±ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï Î±ÎºÏÎ¿ÎœÏÎŒÎ¹ÏÎœ ÎºÎ±Î¹ ÏÎ¿ ÏÎ·ÎŒÎµÎ¯Î¿ ÏÎ¿Ï
+ Î±Ï
+ÏÎ¬ ÎµÎŒÏÎ±ÎœÎ¯Î¶Î¿ÎœÏÎ±Î¹.  }
+
+_textPhraselong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± <i>ÎºÎ¬ÎœÎµÏÎµ ÏÎ¬ÏÏÏÎ· ÏÎµ ÏÏÎ¬ÏÎµÎ¹Ï ÏÎ¿Ï
+ ÎµÎŒÏÎ±ÎœÎ¯Î¶Î¿ÎœÏÎ±Î¹ ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î±</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>ÏÏÎ¬ÏÎµÎ¹Ï</i> . ÎÏÏÎ¹ ÎžÎ­ÏÎµÏÎµ ÏÎµ Î»ÎµÎ¹ÏÎ¿Ï
+ÏÎ³Î¯Î± ÏÎ¿Îœ phind phrase browser.  }
+
+_textArtistlong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ <i>ÎœÎ± Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÎºÎ±Î»Î»Î¹ÏÎ­ÏÎœÎ·</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>ÎºÎ±Î»Î»Î¹ÏÎ­ÏÎœÎµÏ</i> ÎÎ± ÏÎ±ÏÎ¿Ï
+ÏÎ¹Î±ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï ÎµÎ³Î³ÏÎ±ÏÏÎœ ÏÎ±ÎŸÎ¹ÎœÎ¿ÎŒÎ·ÎŒÎ­ÎœÎ¿Ï Î²Î¬ÏÎµÎ¹ ÏÎ¿Ï
+ Î¿ÎœÏÎŒÎ±ÏÎ¿Ï ÏÎ¿Ï
+ ÎºÎ±Î»Î»Î¹ÏÎ­ÏÎœÎ·.  }
+
+_textKeywordlong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ <i>ÎœÎ± Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÏÎœÏÎ±Ï Î»Î­ÎŸÎµÎ¹Ï ÎºÎ»ÎµÎ¹ÎŽÎ¹Î¬</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>Î»Î­ÎŸÎµÎ¹Ï ÎºÎ»ÎµÎ¹ÎŽÎ¹Î¬</i> . ÎÎ± ÏÎ±ÏÎ¿Ï
+ÏÎ¹Î±ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï ÎŒÎµ Î»Î­ÎŸÎµÎ¹Ï ÎºÎ»ÎµÎ¹ÎŽÎ¹Î¬. }
+
+_textVolumelong_ [l=el] {<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± <i>Î­ÏÎµÏÎµ ÏÏÏÏÎ²Î±ÏÎ· ÏÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î±ÎœÎ¬ ÏÏÎŒÎ¿</i> ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>ÏÏÎŒÎ¿Î¹</i> . ÎÎ± ÎµÎŒÏÎ±ÎœÎ¹ÏÏÎµÎ¯ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï ÏÏÎŒÏÎœ.}
+
+# -- Missing translation: _textCaptionslong_
+
+# -- Missing translation: _textCountrieslong_
+
+
+_textdefaultlongtext_ [l=el] {<p>Î Î±ÏÎ®ÏÏÎµ ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>Î¬Î³ÎœÏÏÏÎ¿</i> Î³Î¹Î± ÎœÎ± ÎºÎ¬ÎœÎµÏÎµ ÏÎ¬ÏÏÏÎ· ÏÎµ ÎŽÎ·ÎŒÎ¿ÏÎ¹ÎµÏÏÎµÎ¹Ï (Î· ÏÎ±ÎŸÎ¹ÎœÏÎŒÎ·ÏÎ· ÎµÎ¯ÎœÎ±Î¹ Î²Î¬ÏÎµÎ¹ Î¬Î³ÎœÏÏÏÎ¿Ï
+ ÏÎµÎŽÎ¯Î¿Ï
+.}
+
+_texthelptopicstitle_ [l=el] {Topics}
+
+
+_textreadingdocs_ [l=el] {Î ÏÏ ÎœÎ± ÎŽÎ¹Î±Î²Î¬ÏÎµÏÎµ ÏÎ± Î­Î³Î³ÏÎ±ÏÎ±}
+
+_texthelpreadingdocs_ [l=el] {
+<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± ÎºÎ±ÏÎ±Î»Î¬Î²ÎµÏÎµ ÏÏÏÎµ ÎµÎœÏÎ¿ÏÎ¯ÏÎ±ÏÎµ Î­ÎœÎ± ÏÏ
+Î³ÎºÎµÎºÏÎ¹ÎŒÎ­ÎœÎ¿ Î²Î¹Î²Î»Î¯Î¿ Î® Î­Î³Î³ÏÎ±ÏÎ¿ ÏÏÎ±Îœ ÎŽÎµÎ¯ÏÎµ ÏÎ¿Îœ ÏÎ¯ÏÎ»Î¿ Î® ÏÎ·Îœ ÏÏÏÎ¿Î³ÏÎ±ÏÎ¯Î± ÎµÎŸÏÏÏÎ»Î»Î¿Ï
+ ÏÏÎ¿ ÏÎ¬ÎœÏ Î±ÏÎ¹ÏÏÎµÏÎ¬ ÎŒÎ­ÏÎ¿Ï ÏÎ·Ï ÏÎµÎ»Î¯ÎŽÎ±Ï. Î£Îµ Î¿ÏÎ¹ÏÎŒÎ­ÎœÎµÏ ÏÏ
+Î»Î»Î¿Î³Î­Ï Î±Ï
+ÏÏ ÏÏ
+ÎœÎ¿ÎŽÎµÏÎµÏÎ±Î¹ ÎºÎ±Î¹ Î±ÏÏ Î­ÎœÎ±Îœ ÏÎ¯ÎœÎ±ÎºÎ± ÏÎµÏÎ¹ÎµÏÎ¿ÎŒÎ­ÎœÏÎœ, ÎµÎœÏ Î¬Î»Î»ÎµÏ ÏÎµÏÎ¹Î­ÏÎ¿Ï
+Îœ Î±ÏÎ»ÏÏ ÏÎ¿Îœ Î±ÏÎ¹ÎžÎŒÏ ÏÎ·Ï ÏÏÎ­ÏÎ¿Ï
+ÏÎ±Ï ÏÎµÎ»Î¯ÎŽÎ±Ï ÎŒÎ±Î¶Î¯ ÎŒÎµ Î­ÎœÎ± ÎºÎ¿Ï
+ÏÎ¯ ÏÎ¿Ï
+ ÏÎ±Ï ÎµÏÎ¹ÏÏÎ­ÏÎµÎ¹ ÎœÎ± ÎµÏÎ¹Î»Î­ÎŸÎµÏÎµ ÎœÎ­Î± ÏÎµÎ»Î¯ÎŽÎ± ÎºÎ±Î¹ ÎœÎ± ÏÎ¬ÏÎµ ÎŒÏÏÎ¿ÏÏÎ¬ Î® ÏÎ¯ÏÏ. Î£ÏÎ¿Îœ ÏÎ¯ÎœÎ±ÎºÎ± ÏÎµÏÎ¹ÎµÏÎ¿ÎŒÎ­ÎœÏÎœ, Î· ÎµÎœÏÏÎ·ÏÎ± ÏÏÎ·Îœ Î¿ÏÎ¿Î¯Î± Î²ÏÎ¯ÏÎºÎµÏÏÎµ Ï
+ÏÎ¿ÎŽÎµÎ¹ÎºÎœÏÎµÏÎ±Î¹ ÎŒÎµ Î­ÎœÏÎ¿ÎœÎ± Î³ÏÎ¬ÎŒÎŒÎ±ÏÎ± ÎºÎ±Î¹ Î¿ ÏÎ¯ÎœÎ±ÎºÎ±Ï ÎŒÏÎ¿ÏÎµÎ¯ ÎœÎ± ÎµÏÎµÎºÏÎ±ÎžÎµÎ¯- Î±ÏÎ»ÏÏ ÏÎ±ÏÎ®ÏÏÎµ ÏÎ¬ÎœÏ ÏÏÎ¿Ï
+Ï ÏÎ±ÎºÎ­Î»Î¿Ï
+Ï Î³Î¹Î± ÎœÎ± ÏÎ¿Ï
+Ï Î±ÎœÎ¿Î¯ÎŸÎµÏÎµ Î® ÎœÎ± ÏÎ¿Ï
+Ï ÎºÎ»ÎµÎ¯ÏÎµÏÎµ. Î Î±ÏÎ®ÏÏÎµ ÏÎ¬ÎœÏ ÏÏÎ¿ Î±ÎœÎ¿Î¹ÏÏÏ Î²Î¹Î²Î»Î¯Î¿ ÏÏÎ¿ ÏÎ¬ÎœÏ ÎŒÎ­ÏÎ¿Ï ÏÎ·Ï ÏÎµÎ»Î¯ÎŽÎ±Ï Î³Î¹Î± ÎœÎ± ÏÎ¿ ÎºÎ»ÎµÎ¯ÏÎµÏÎµ.</p>
+
+<p>ÎÏÏ ÎºÎ¬ÏÏ ÎµÎ¯ÎœÎ±Î¹ ÏÎ¿ ÎºÎµÎ¯ÎŒÎµÎœÎ¿ ÏÎ·Ï ÎµÎœÏÏÎ·ÏÎ±Ï ÏÏÎ·Îœ Î¿ÏÎ¿Î¯Î± Î²ÏÎ¯ÏÎºÎµÏÏÎµ. Î£ÏÎ¿ ÏÎ­Î»Î¿Ï ÏÎ¿Ï
+ Ï
+ÏÎ¬ÏÏÎ¿Ï
+Îœ ÎºÎ¿Ï
+ÎŒÏÎ¹Î¬ ÏÎ¿Ï
+ ÎžÎ± ÏÎ±Ï ÏÎ¬ÎœÎµ ÏÏÎ·Îœ ÎµÏÏÎŒÎµÎœÎ· ÎµÎœÏÏÎ·ÏÎ± Î® ÏÎ¯ÏÏ ÏÏÎ·Îœ ÏÏÎ¿Î·Î³Î¿ÏÎŒÎµÎœÎ·.</p>
+
+<p>ÎÎ¬ÏÏ Î±ÏÏ ÏÎ¿Îœ ÏÎ¯ÏÎ»Î¿ Î® ÏÎ¿ ÎµÎŸÏÏÏ
+Î»Î¿ Ï
+ÏÎ¬ÏÏÎ¿Ï
+Îœ ÎŒÎµÏÎ¹ÎºÎ¬ ÎºÎ¿Ï
+ÎŒÏÎ¹Î¬. Î Î±ÏÎ®ÏÏÎµ ÏÎ¬ÎœÏ ÏÏÎ¿
+<i>Î±ÎœÎ¬ÏÏÏ
+ÎŸÎµ ÎºÎµÎ¯ÎŒÎµÎœÎ¿</i> ÏÏÎ¿ÎºÎµÎ¹ÎŒÎ­ÎœÎ¿Ï
+ ÎœÎ± Î±ÎœÎ±ÏÏÏÎŸÎµÏÎµ ÏÎ»Î¿ ÏÎ¿ ÎºÎµÎ¯ÎŒÎµÎœÎ¿ ÏÎ·Ï ÏÏÎ­ÏÎ¿Ï
+ÏÎ±Ï ÎµÎœÏÏÎ·ÏÎ±Ï Î® ÏÎ¿Ï
+ Î²Î¹Î²Î»Î¯Î¿Ï
+. ÎÎœ ÏÎ¿ Î­Î³Î³ÏÎ±ÏÎ¿ ÎµÎ¯ÎœÎ±Î¹ ÎŒÎµÎ³Î¬Î»Î¿, Î±Ï
+ÏÏ ÎžÎ± ÏÎ¬ÏÎµÎ¹ ÏÎ¿Î»Ï ÏÏÎ± ÎºÎ±Î¹ ÎœÎ± ÏÏÎµÎ¹Î±ÏÏÎµÎ¯ ÏÎ¿Î»Ï ÎŒÎœÎ®ÎŒÎ·! Î Î±ÏÎ®ÏÏÎµ ÏÎ¬ÎœÏ ÏÏÎ¿ <i>Î±ÎœÎ¬ÏÏÏ
+ÎŸÎµ ÏÎµÏÎ¹ÎµÏÏÎŒÎµÎœÎ±</i> Î³Î¹Î± ÎœÎ± Î±ÎœÎ±ÏÏÏÎŸÎµÏÎµ ÏÎ»Î¿Îœ ÏÎ¿Îœ ÏÎ¯ÎœÎ±ÎºÎ± ÏÎµÏÎ¹ÎµÏÎ¿ÎŒÎ­ÎœÏÎœ Î­ÏÏÎ¹ ÏÏÏÎµ ÎœÎ± ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± ÎŽÎµÎ¯ÏÎµ ÏÎ»Î¿Ï
+Ï ÏÎ¿Ï
+Ï ÏÎ¯ÏÎ»Î¿Ï
+Ï ÏÏÎœ ÎºÎµÏÎ±Î»Î±Î¯ÏÎœ ÎºÎ±Î¹ Ï
+ÏÎ¿ÎºÎµÏÎ±Î»Î±Î¯ÏÎœ. Î Î±ÏÎ®ÏÏÎµ ÏÎ¬ÎœÏ ÏÏÎ¿ <i>Î±ÏÏÏÏÎ±ÏÎµ</i> Î³Î¹Î± ÎœÎ± Î±ÎœÎ¿Î¯ÎŸÎµÏÎµ Î­ÎœÎ± ÎœÎ­Î¿ ÏÎ±ÏÎ¬ÎžÏ
+ÏÎ¿ Î³Î¹Î± ÏÎ¿ Î­Î³Î³ÏÎ±ÏÎ¿. (ÎÏ
+ÏÏ ÎµÎ¯ÎœÎ±Î¹ Î¹ÎŽÎ¹Î±Î¹ÏÎ­ÏÏÏ ÏÏÎ®ÏÎ¹ÎŒÎ¿ ÏÏÎ±Îœ ÎžÎ­Î»ÎµÏÎµ ÎœÎ± ÏÏ
+Î³ÎºÏÎ¯ÎœÎµÏÎµ Î­Î³Î³ÏÎ±ÏÎ±, Î® ÎœÎ± ÎŽÎ¹Î±Î²Î¬ÏÎµÏÎµ ÎŽÏÎ¿ ÎŒÎ±Î¶Î¯). Î€Î­Î»Î¿Ï, ÏÏÎ±Îœ ÎºÎ¬ÎœÎµÏÎµ ÎŒÎ¹Î± Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·, Î¿Î¹ ÏÏÎ¿Î¹ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ®Ï ÏÎ±Ï ÎµÏÎ¹ÏÎ·ÎŒÎ±Î¯ÎœÎ¿ÎœÏÎ±Î¹ ÎŒÎµ Î­ÎœÏÎ¿ÎœÎ· Î³ÏÎ±ÏÎ®. Î Î±ÏÎ®ÏÏÎµ ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>ÏÏÏÎ¯Ï ÎµÏÎ¹ÏÎ®ÎŒÎ±ÎœÏÎ·</i> Î³Î¹Î± ÎœÎ± Î±ÏÎµÏÎµÎžÎµÎ¯ Î· ÎµÏÎ¹ÏÎ®ÎŒÎ±ÎœÏÎ·.</p>
+}
+
+_texthelpsearchingtitle_ [l=el] {Î ÏÏ ÎœÎ± Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÏÎµ ÏÏ
+Î³ÎºÎµÎºÏÎ¹ÎŒÎ­ÎœÎµÏ Î»Î­ÎŸÎµÎ¹Ï}
+
+_texthelpsearching_ [l=el] {
+<p>
+  ÎÏÏ ÏÎ· ÏÎµÎ»Î¯ÎŽÎ± Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï, ÎºÎ¬ÎœÎµÏÎµ ÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· ÎŒÎµ ÏÎ± ÎµÎŸÎ®Ï Î±ÏÎ»Î¬ Î²Î®ÎŒÎ±ÏÎ±:<p>
+  
+  <ol><li>ÎÎ±ÎžÎ¿ÏÎ¯ÏÏÎµ ÏÎ± ÏÎµÎºÎŒÎ®ÏÎ¹Î± ÏÎ¿Ï
+ ÎžÎ­Î»ÎµÏÎµ ÎœÎ± Î±ÎœÎ±Î¶Î·ÏÎ·ÎžÎ¿ÏÎœ
+      <li>ÎÏÎ¹Î»Î­ÎŸÏÎµ Î±Îœ ÎžÎ­Î»ÎµÏÎµ ÎœÎ± Î±ÎœÎ±Î¶Î·ÏÎ·ÎžÎ¿ÏÎœ ÏÎ»ÎµÏ Î® ÎŒÎµÏÎ¹ÎºÎ­Ï Î±ÏÏ ÏÎ¹Ï Î»Î­ÎŸÎµÎ¹Ï ÏÎ¿Ï
+ ÎžÎ± Î¿ÏÎ¯ÏÎµÏÎµ
+      <li>Î Î»Î·ÎºÏÎ¿Î»Î¿Î³Î®ÏÏÎµ ÏÎ¹Ï Î»Î­ÎŸÎµÎ¹Ï ÏÎ¿Ï
+ ÎžÎ­Î»ÎµÏÎµ ÎœÎ± Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÏÎµ
+      <li>Î Î±ÏÎ®ÏÏÎµ ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ·</i> 
+  </ol>
+
+<p>ÎÏÎ±Îœ ÎºÎ¬ÎœÎµÏÎµ ÎŒÎ¹Î± Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·, ÎžÎ± ÎµÎŒÏÎ±ÎœÎ¹ÏÏÎ¿ÏÎœ ÎµÎ¯ÎºÎ¿ÏÎ¹ ÏÎ¯ÏÎ»Î¿Î¹ ÎµÎ³Î³ÏÎ¬ÏÏÎœ ÏÎ¿Ï
+ ÏÎ±Î¹ÏÎ¹Î¬Î¶Î¿Ï
+Îœ ÏÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·. Î¥ÏÎ¬ÏÏÎµÎ¹ Î­ÎœÎ± ÎºÎ¿Ï
+ÎŒÏÎ¯ ÏÏÎ¿ ÏÎ­Î»Î¿Ï ÏÎ¿Ï
+ ÎºÎ±ÏÎ±Î»ÏÎ³Î¿Ï
+ ÏÎ¿Ï
+ ÎžÎ± ÏÎ±Ï ÏÎ¬ÎµÎ¹ ÏÏÎ± ÎµÏÏÎŒÎµÎœÎ± ÎµÎ¯ÎºÎ¿ÏÎ¹ Î­Î³Î³ÏÎ±ÏÎ±. ÎÏÏ ÎµÎºÎµÎ¯ ÎžÎ± Î²ÏÎµÎ¯ÏÎµ ÎºÎ¿Ï
+ÎŒÏÎ¹Î¬ ÏÎ¿Ï
+ ÎžÎ± ÏÎ±Ï ÏÎ¬ÎœÎµ ÎºÎ±Î¹ ÏÏÎ± ÎµÏÏÎŒÎµÎœÎ± Î® ÏÎ± ÏÏÎ¿Î·Î³Î¿ÏÎŒÎµÎœÎ± ÎµÎ¯ÎºÎ¿ÏÎ¹. Î Î±ÏÎ®ÏÏÎµ ÏÎ¬ÎœÏ ÏÏÎ¿Îœ ÏÎ¯ÏÎ»Î¿ Î¿ÏÎ¿Î¹Î¿Ï
+ÎŽÎ®ÏÎ¿ÏÎµ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+, Î® ÏÏÎ¿ ÎŒÎ¹ÎºÏÏ ÎºÎ¿Ï
+ÏÎ¬ÎºÎ¹ ÎŽÎ¯ÏÎ»Î± ÏÎ¿Ï
+, Î³Î¹Î± ÎœÎ± ÏÎ¿ Î±ÎœÎ¿Î¯ÎŸÎµÏÎµ.
+
+<p>Î ÎŒÎ­Î³Î¹ÏÏÎ¿Ï Î±ÏÎ¹ÎžÎŒÏÏ ÎµÎ³Î³ÏÎ¬ÏÏÎœ ÏÎ¿Ï
+ ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± ÏÎ¬ÏÎµÏÎµ ÏÏ Î±ÏÎ¿ÏÎ­Î»ÎµÏÎŒÎ± ÎµÎ¯ÎœÎ±Î¹, ÏÏÎŒÏÏÎœÎ± ÎŒÎµ ÏÎ¹Ï ÏÏÎ¿ÎµÏÎ¹Î»Î¿Î³Î­Ï, 100. ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± Î±Î»Î»Î¬ÎŸÎµÏÎµ Î±Ï
+ÏÏÎœ ÏÎ¿Îœ Î±ÏÎ¹ÎžÎŒÏ ÏÎ±ÏÏÎœÏÎ±Ï ÏÎ¬ÎœÏ ÏÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>ÎµÏÎ¹Î»Î¿Î³Î­Ï</i> ÏÏÎ¿ ÏÎ¬ÎœÏ ÎŒÎ­ÏÎ¿Ï ÏÎ·Ï ÏÎµÎ»Î¯ÎŽÎ±Ï.<p>
+}
+
+_texthelpquerytermstitle_ [l=el] {ÏÏÎ¿Î¹ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+_texthelpqueryterms_ [l=el] {
+<p>ÎÏÎ¹ÎŽÎ®ÏÎ¿ÏÎµ ÏÎ»Î·ÎºÏÏÎ¿Î»Î¿Î³ÎµÎ¯ÏÎ±Î¹ ÎŒÎ­ÏÎ± ÏÏÎ¿ ÎºÎ¿Ï
+ÏÎ¯ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï ÎµÎºÎ»Î±ÎŒÎ²Î¬ÎœÎµÏÎ±Î¹ ÏÏ Î­ÎœÎ±Ï ÎºÎ±ÏÎ¬Î»Î¿Î³Î¿Ï Î»Î­ÎŸÎµÏÎœ ÏÎ¿Ï
+ Î¿ÎœÎ¿ÎŒÎ¬Î¶ÎµÏÎ±Î¹ "ÏÏÎ¿Î¹ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï". ÎÎ¬ÎžÎµ ÏÎµÎºÎŒÎ®ÏÎ¹Î¿ ÏÎµÏÎ¹Î»Î±ÎŒÎ²Î¬ÎœÎµÎ¹ ÎŒÏÎœÎ¿ Î±Î»ÏÎ±Î²Î·ÏÎ¹ÎºÎ¿ÏÏ ÏÎ±ÏÎ±ÎºÏÎ®ÏÎµÏ ÎºÎ±Î¹ ÏÎ·ÏÎ¯Î±. ÎÎ¹ ÏÏÎ¿Î¹ ÎŽÎ¹Î±ÏÏÏÎ¯Î¶Î¿ÎœÏÎ±Î¹ ÎŒÎµÏÎ±ÎŸÏ ÏÎ¿Ï
+Ï Î±ÏÏ Î»ÎµÏ
+ÎºÏ ÎºÎµÎœÏ. ÎÏÎ¿Î¹Î¿ÏÎŽÎ®ÏÎ¿ÏÎµ Î¬Î»Î»Î¿Ï ÏÎ±ÏÎ±ÎºÏÎ®ÏÎ±Ï ÎµÎŒÏÎ±ÎœÎ¹ÏÏÎµÎ¯, Ï.Ï., ÏÎ·ÎŒÎµÎ¯Î± ÏÏÎ¯ÎŸÎ·Ï, ÎµÎŸÏ
+ÏÎ·ÏÎµÏÎ¿ÏÎœ Î±ÏÎ»ÏÏ ÏÎ¿Îœ ÎŽÎ¹Î±ÏÏÏÎ¹ÏÎŒÏ ÏÏÎœ Î»Î­ÎŸÎµÏÎœ, Î±ÎºÏÎ¹Î²ÏÏ ÏÎ± ÎœÎ± Î®ÏÎ±Îœ ÎºÎµÎœÎ¬. ÎÎ±Î¹ ÎŒÎµÏÎ¬ Î±Î³ÎœÎ¿Î¿ÏÎœÏÎ±Î¹. ÎÎµÎœ ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÏÎµ ÏÏÎ¿Ï
+Ï ÏÎ¿Ï
+ ÏÎµÏÎ¹Î»Î±ÎŒÎ²Î¬ÎœÎ¿Ï
+Îœ ÏÎ·ÎŒÎµÎ¯Î± ÏÏÎ¯ÎŸÎ·Ï.
+
+<p>ÎÎ¹Î± ÏÎ±ÏÎ¬ÎŽÎµÎ¹Î³ÎŒÎ±, Î· Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·<p>
+      <ul><kbd>Î¡Î®Î³Î±Ï ÎÎµÎ»ÎµÏÏÎ¹ÎœÎ»Î®Ï: Î ÎÎ¿ÏÏÎ¹Î¿Ï (1821)</kbd></ul>
+      <p>ÎžÎ± Î±ÎœÏÎ¹ÎŒÎµÏÏÏÎ¹ÏÏÎµÎ¯ ÏÎ¿ Î¯ÎŽÎ¹Î¿, ÏÎ±Îœ ÎœÎ± Î­Î»ÎµÎ³Îµ<p>
+      <ul><kbd>Î¡Î®Î³Î±Ï ÎÎµÎ»ÎµÏÏÎ¹ÎœÎ»Î®Ï Î ÎÎ¿ÏÏÎ¹Î¿Ï 1821</kbd></ul><p>
+}
+
+_texthelpquerytypetitle_ [l=el] {ÎÎ¯ÎŽÎ¿Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+_texthelpquerytype_ [l=el] {
+<p>Î¥ÏÎ¬ÏÏÎ¿Ï
+Îœ ÎŽÏÎ¿ ÎŽÎ¹Î±ÏÎ¿ÏÎµÏÎ¹ÎºÎ¬ ÎµÎ¯ÎŽÎ· Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï.
+
+<ul>
+  <li>ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ· Î³Î¹Î± <b>ÏÎ»ÎµÏ</b> ÏÎ¹Ï Î»Î­ÎŸÎµÎ¹Ï.  ÎÏ
+ÏÎ® ÎžÎ± Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÎ¹ ÏÎµÎºÎŒÎ®ÏÎ¹Î± (Î® ÎºÎµÏÎ¬Î»Î±Î¹Î± Î® ÏÎ¯ÏÎ»Î¿Ï
+Ï) ÏÎ¿Ï
+ ÏÎµÏÎ¹Î»Î±ÎŒÎ²Î¬ÎœÎ¿Ï
+Îœ ÎÎÎÎ£ ÏÎ¹Ï Î»Î­ÎŸÎµÎ¹Ï ÏÎ¿Ï
+ Î­ÏÎµÏÎµ Î¿ÏÎ¯ÏÎµÎ¹. Î€Î± ÏÎµÎºÎŒÎ®ÏÎ¹Î± ÏÎ¿Ï
+ Î¹ÎºÎ±ÎœÎ¿ÏÎ¿Î¹Î¿ÏÎœ ÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· ÎµÎŒÏÎ±ÎœÎ¯Î¶Î¿ÎœÏÎ±Î¹ ÏÎµ Î±Î»ÏÎ±Î²Î·ÏÎ¹ÎºÎ® ÏÎµÎ¹ÏÎ¬.<p>
+
+  <li>ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ· Î³Î¹Î± <b>ÎŒÎµÏÎ¹ÎºÎ­Ï</b> Î±ÏÏ ÏÎ¹Ï Î»Î­ÎŸÎµÎ¹Ï.  ÎÏÎ»ÏÏ ÏÎ±ÏÎ±ÎžÎ­ÏÏÎµ ÎŒÎµÏÎ¹ÎºÎ¿ÏÏ ÏÏÎ¿Ï
+Ï ÏÎ¿Ï
+ ÎµÎ¯ÎœÎ±Î¹ ÏÎ¹ÎžÎ±ÎœÏ ÎœÎ± ÎµÎŒÏÎ±ÎœÎ¯Î¶Î¿ÎœÏÎ±Î¹ ÏÏÎ± Î­Î³Î³ÏÎ±ÏÎ± ÏÎ¿Ï
+ Î±ÎœÎ±Î¶Î·ÏÎ¬ÏÎµ. Î€Î± Î­Î³Î³ÏÎ±ÏÎ± ÎžÎ± ÎµÎŒÏÎ±ÎœÎ¹ÏÏÎ¿ÏÎœ ÏÎ±ÎŸÎ¹ÎœÎ¿ÎŒÎ·ÎŒÎ­ÎœÎ± Î±ÎœÎ¬Î»Î¿Î³Î± ÎŒÎµ ÏÎ¿ ÏÏÏÎ¿ Î¹ÎºÎ±ÎœÎ¿ÏÎ¿Î¹Î¿ÏÎœ ÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·. Î€Î¿ ÎºÎ±ÏÎ¬ ÏÏÏÎ¿ Î­ÎœÎ± Î­Î³Î³ÏÎ±ÏÎ¿ ÏÎ±Î¹ÏÎ¹Î¬Î¶ÎµÎ¹ ÏÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ® ÏÎ±Ï Î¿ÏÎ¯Î¶ÎµÏÎ±Î¹ ÎŒÎµ Î²Î¬ÏÎµÎ¹ ÏÎ± ÏÎ±ÏÎ±ÎºÎ¬ÏÏ ÎºÏÎ¹ÏÎ®ÏÎ¹Î±:
+
+      <p><ul>
+        <li> ÏÏÎ¿ ÏÎµÏÎ¹ÏÏÏÏÎµÏÎ¿Î¹ Î±ÏÏ ÏÎ¿Ï
+Ï ÏÏÎ¿Ï
+Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï ÏÎµÏÎ¹Î»Î±ÎŒÎ²Î¬ÎœÎ¿ÎœÏÎ±Î¹ ÏÎµ Î­ÎœÎ± Î­Î³Î³ÏÎ±ÏÎ¿, ÏÏÏÎ¿ ÏÎµÏÎ¹ÏÏÏÏÎµÏÎ¿ Î±Ï
+ÏÏ ÏÎ±Î¹ÏÎ¹Î¬Î¶ÎµÎ¹.
+        <li> Î¿Î¹ ÏÏÎ±ÎœÎ¹ÏÏÎµÏÎ¿Î¹ ÏÏÎ¿Î¹ ÎµÎ¯ÎœÎ±Î¹ ÏÎ¹Î¿ ÏÎ·ÎŒÎ±ÎœÏÎ¹ÎºÎ¿Î¯ Î±ÏÏ ÏÎ¿Ï
+Ï ÎºÎ¿Î¹ÎœÎ¿ÏÏ.
+        <li> ÏÎ± ÎŒÎ¹ÎºÏÎ¬ Î­Î³Î³ÏÎ±ÏÎ± ÎžÎµÏÏÎµÎ¯ÏÎ±Î¹ ÏÏÎ¹ ÏÎ±Î¹ÏÎ¹Î¬Î¶Î¿Ï
+Îœ ÎºÎ±Î»ÏÏÎµÏÎ± Î±ÏÏ ÏÎ± ÎŒÎµÎ³Î¬Î»Î±.
+      </ul>
+</ul>
+
+<p>Î§ÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÎµÎ¯ÏÏÎµ ÏÏÎ¿ ÏÎµÏÎ¹ÏÏÏÏÎµÏÎ¿Ï
+Ï ÏÏÎ¿Ï
+Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï ÎžÎ­Î»ÎµÏÎµ, ÎŒÎ¹Î± Î¿Î»ÏÎºÎ»Î·ÏÎ· ÏÏÏÏÎ±ÏÎ·, Î±ÎºÏÎŒÎ± ÎºÎ±Î¹ ÏÎ±ÏÎ¬Î³ÏÎ±ÏÎ¿. ÎÎœ Î¿ÏÎ¯ÏÎµÏÎµ ÎŒÏÎœÎ¿ Î­ÎœÎ±Îœ ÏÏÎ¿ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï, ÏÎ± Î­Î³Î³ÏÎ±ÏÎ± ÎžÎ± ÏÎ±ÎŸÎ¹ÎœÎ¿ÎŒÎ·ÎžÎ¿ÏÎœ Î±ÎœÎ¬Î»Î¿Î³Î± ÎŒÎµ ÏÎ¿ ÏÏÏÎ¿ ÏÏ
+ÏÎœÎ¬ Î±Ï
+ÏÏÏ Î¿ ÏÏÎ¿Ï ÎµÎŒÏÎ±ÎœÎ¯Î¶ÎµÏÎ±Î¹.<p>
+}
+
+_textdatesearch_ [l=el] {ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ· ÎŒÎµ ÎÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯ÎµÏ}
+
+_texthelpdatesearch_ [l=el] {
+Î Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· Î²Î¬ÏÎµÎ¹ Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î±Ï, ÏÎ±Ï ÎµÏÎ¹ÏÏÎ­ÏÎµÎ¹ ÎœÎ± Î²ÏÎµÎ¯ÏÎµ ÏÎµÎºÎŒÎ®ÏÎ¹Î± ÏÎ¿Ï
+ ÏÎ±Î¹ÏÎ¹Î¬Î¶Î¿Ï
+Îœ ÎŒÎµ ÏÎ¿Ï
+Ï ÏÏÎ¿Ï
+Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï ÏÎ¿Ï
+ ÎžÎ­ÏÎ±ÏÎµ ÎºÎ±Î¹ ÏÎ±ÏÎ¬Î»Î»Î·Î»Î±, Î±ÏÎ¿ÏÎ¿ÏÎœ Î³ÎµÎ³Î¿ÎœÏÏÎ± ÏÎ¿Ï
+ Î­Î»Î±Î²Î±Îœ ÏÏÏÎ± ÏÎµ ÏÏ
+Î³ÎºÎµÎºÏÎ¹ÎŒÎ­ÎœÎ¿ ÏÏÎ¿ÎœÎ¹ÎºÏ ÎŽÎ¹Î¬ÏÏÎ·ÎŒÎ±. ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÏÎµ ÏÎµÎºÎŒÎ®ÏÎ¹Î± ÎµÎ¯ÏÎµ Î³Î¹Î± Î­ÎœÎ± ÏÏ
+Î³ÎºÎµÎºÏÎ¹ÎŒÎ­ÎœÎ¿ Î­ÏÎ¿Ï ÎµÎ¯ÏÎµ Î³Î¹Î± ÎŒÎ¹Î± ÏÏÎ¿ÎœÎ¹ÎºÎ® ÏÎµÏÎ¯Î¿ÎŽÎ¿. ÎÎ± ÏÎ·ÎŒÎµÎ¹ÏÏÎ¿Ï
+ÎŒÎµ ÏÏÎ¹ ÎŽÎµÎœ ÏÏÎµÎ¹Î¬Î¶ÎµÏÎ±Î¹ ÎœÎ± Î­ÏÎµÏÎµ ÎžÎ­ÏÎµÎ¹ Î¬Î»Î»Î¿Ï
+Ï ÏÏÎ¿Ï
+Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï -- ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± ÏÎ¬ÎŸÎµÏÎµ ÎŒÏÎœÎ¿ ÎŒÎµ Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î±. ÎÏÎ¯ÏÎ·Ï, ÏÏÎ¹ ÎŽÎµÎœ ÏÏÎµÎ¹Î¬Î¶ÎµÏÎ±Î¹ ÎœÎ± ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÎµÎ¯ÏÎµÏÎµ Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯ÎµÏ ÏÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ® ÏÎ±Ï - Î±Îœ ÎŽÎµÎœ ÏÎ»Î·ÎºÏÏÎ¿Î»Î¿Î³Î®ÏÎµÏÎµ ÎºÎ±ÎžÏÎ»Î¿Ï
+ Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î± ÎµÎ¯ÎœÎ±Î¹ ÏÎ¿ Î¯ÎŽÎ¹Î¿ ÏÎ±Îœ ÎœÎ± ÎŒÎ·Îœ Ï
+ÏÎ®ÏÏÎµ Î· Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· Î²Î¬ÏÎµÎ¹ Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î±Ï.<p>
+}
+
+_texthelpdatehowtotitle_ [l=el] {Î ÏÏ ÎœÎ± ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÎµÎ¯ÏÎµÏÎµ Î±Ï
+ÏÎ® ÏÎ·Îœ ÎµÏÎ¹Î»Î¿Î³Î®:}
+_texthelpdatehowto_ [l=el] {
+<ul>
+   <li>ÎÎ¹Î± ÎœÎ± Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÏÎµ ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î³Î¹Î± Î­ÎœÎ± ÏÏ
+Î³ÎºÎµÎºÏÎ¹ÎŒÎ­ÎœÎ¿ Î­ÏÎ¿Ï:<p>
+   <ul>
+       <li>Î Î»Î·ÎºÏÏÎ¿Î»Î¿Î³Î®ÏÏÎµ Î¿ÏÎ¿Î¹Î¿ÎœÎŽÎ®ÏÎ¿ÏÎµ ÏÏÎ¿ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï ÎžÎ­Î»ÎµÏÎµ ÎœÎ± ÎžÎ­ÏÎµÏÎµ. 
+       <li>Î Î»Î·ÎºÏÏÎ¿Î»Î¿Î³Î®ÏÏÎµ ÏÎ¿ Î­ÏÎ¿Ï ÏÎ¿Ï
+ ÎžÎ­Î»ÎµÏÎµ ÎŒÎ­ÏÎ± ÏÏÎ¿ ÎºÎ¿Ï
+ÏÎ¯ "ÎÏÏÎ¹ÎºÎ® Î® ÎŒÎ¿ÎœÎ±ÎŽÎ¹ÎºÎ® Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î±".
+       <li>ÎÎœ Î· Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î± ÏÎ¿Ï
+ Î±ÎœÎ±Î¶Î·ÏÎ¬ÏÎµ ÎµÎ¯ÎœÎ±Î¹ ÏÏÎ¿ Î§ÏÎ¹ÏÏÎ¿Ï, ÎµÏÎ¹Î»Î­ÎŸÏÎµ ÏÎ·Îœ ÎµÏÎ¹Î»Î¿Î³Î® "Ï.Î§."Î±ÏÏ ÏÎ¿ ÎŒÎµÎœÎ¿Ï ÎµÏÎ¹Î»Î¿Î³ÏÎœ ÎŽÎ¯ÏÎ»Î± ÏÏÎ¿ ÎºÎ¿Ï
+ÏÎ¯.        <li>ÎÎµÎºÎ¹ÎœÎ®ÏÏÎµ ÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ® ÏÎ±Ï ÏÏÏÏ ÎžÎ± ÎºÎ¬ÎœÎ±ÏÎµ ÎºÎ±ÎœÎ¿ÎœÎ¹ÎºÎ¬.
+   </ul>
+<p><li>ÎÎ¹Î± ÎœÎ± Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÏÎµ Î­Î³ÏÎ±ÏÎ± Î³Î¹Î± ÎŒÎ¹Î± ÏÎµÏÎ¯Î¿ÎŽÎ¿ Î® ÎŒÎ¹Î± Î±ÎºÏÎ¯ÎœÎ± ÎµÏÏÎœ:<p>
+   <ul>
+       <li>Î Î»Î·ÎºÏÏÎ¿Î»Î¿Î³Î®ÏÏÎµ Î¿ÏÎ¿Î¹Î¿ÎœÎŽÎ®ÏÎ¿ÏÎµ ÏÏÎ¿ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï ÎžÎ­Î»ÎµÏÎµ ÎœÎ± ÎžÎ­ÏÎµÏÎµ.
+       <li>Î Î»Î·ÎºÏÏÎ¿Î»Î¿Î³Î®ÏÏÎµ ÏÎ·Îœ ÏÎ±Î»Î±Î¹ÏÏÎµÏÎ· Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î± ÏÏÎ¿ ÎºÎ¿Ï
+ÏÎ¯ "ÎÏÏÎ¹ÎºÎ® (Î® ÎŒÎ¿ÎœÎ±ÎŽÎ¹ÎºÎ®) ÎÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î±" /"ÎÎœÎ±ÏÎŸÎ· Î ÎµÏÎ¹ÏÎŽÎ¿Ï
+ Î® Î£Ï
+Î³ÎºÎµÎºÏÎ¹ÎŒÎ­ÎœÎ¿ ÎÏÎ¿Ï"/ "Start (or only) date".
+       <li>Î Î»Î·ÎºÏÏÎ¿Î»Î¿Î³Î®ÏÏÎµ ÏÎ·Îœ ÏÎ¹Î¿ ÏÏÏÏÏÎ±ÏÎ· Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î± ÏÏÎ¿ ÎºÎ¿Ï
+ÏÎ¯ "Î€ÎµÎ»Î¹ÎºÎ® Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î±".
+       <li>ÎÏÎ¹Î»Î­ÎŸÏÎµ ÏÎ·Îœ ÎµÏÎ¹Î»Î¿Î³Î® "Ï.Î§." Î³Î¹Î± Î¿ÏÎ¿Î¹Î±ÎŽÎ®ÏÎ¿ÏÎµ Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯Î± ÎµÎ¯ÎœÎ±Î¹ ÏÏÎ¿ Î§ÏÎ¹ÏÏÎ¿Ï Î±ÏÏ ÏÎ¿ ÎŒÎµÎœÎ¿Ï ÎµÏÎ¹Î»Î¿Î³ÏÎœ ÎŽÎ¯ÏÎ»Î± Î±ÏÏ ÏÎ¿ ÎºÎ¿Ï
+ÏÎ¯ (ÎÎœÎ±Î»Î»Î±ÎºÏÎ¹ÎºÎ¬ ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÎµÎ¯ÏÎµÏÎ±Î¹ ÏÎ·Îœ ÎµÏÎ¹Î»Î¿Î³Î® "Î.Î."(ÎÎ¿Î¹ÎœÎ® ÎÏÎ¿ÏÎ®), Î±ÎœÏÎ¯ ÏÎ¿Ï
+ ÎŒ.Î§. ÎºÎ±Î¹ Î .Î.Î. Î³Î¹Î± ÏÎ·Îœ ÎµÏÎ¹Î»Î¿Î³Î® Ï.Î§.).
+       <li>ÎÎµÎºÎ¹ÎœÎ®ÏÏÎµ ÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ® ÏÎ±Ï ÏÏÏÏ ÎžÎ± ÎºÎ¬ÎœÎ±ÏÎµ ÎºÎ±ÎœÎ¿ÎœÎ¹ÎºÎ¬.
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=el] {Î ÏÏ ÎµÎŒÏÎ±ÎœÎ¯Î¶Î¿ÎœÏÎ±Î¹ ÏÎ± Î±ÏÎ¿ÏÎµÎ»Î­ÏÎŒÎ±ÏÎ± ÏÎ·Ï Î­ÏÎµÏ
+ÎœÎ¬Ï ÏÎ±Ï}
+_texthelpdateresults_ [l=el] {
+ÎÎµÎœÎ¹ÎºÎ¬, Î· Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· Î³Î¹Î± ÏÎµÎºÎŒÎ®ÏÎ¹Î± Î²Î¬ÏÎµÎ¹ Î­ÏÎ¿Ï
+Ï Ï.Ï. 1903, ÎŽÎµÎœ ÎžÎ± ÏÎ±Ï ÎµÎŒÏÎ±ÎœÎ¯ÏÎµÎ¹ ÏÎµÎºÎŒÎ®ÏÎ¹Î± ÏÎ¿Ï
+ Î±ÏÎ¿ÏÎ¿ÏÎœ, Î³Î¹Î± ÏÎ±ÏÎ¬ÎŽÎµÎ¹Î³ÎŒÎ±, Î²Î¹Î²Î»Î¯Î± Î±ÎœÎ±ÏÎ¿ÏÏÎœ ÏÎ¿Ï
+ Î³ÏÎ¬ÏÏÎ·ÎºÎ±Îœ ÏÎ¿1903, Î±Î»Î»Î¬ Î­Î³Î³ÏÎ±ÏÎ± ÏÏÎµÏÎ¹ÎºÎ¬ ÎŒÎµ ÏÎ¿ 1903. ÎÏÎ¹ÏÎ»Î­Î¿Îœ, ÎžÎ± ÏÎ±Ï ÎµÎŒÏÎ±ÎœÎ¹ÏÏÎ¿ÏÎœ Î­Î³Î³ÏÎ±ÏÎ± ÏÎ¿Ï
+ Î±ÏÎ¿ÏÎ¿ÏÎœ ÎŒÎ¹Î± ÏÏÎ¿ÎœÎ¹ÎºÎ® ÏÎµÏÎ¯Î¿ÎŽÎ¿ (Ï.Ï. 1899-1911) ÏÎ¿Ï
+ ÏÎµÏÎ¹Î»Î±ÎŒÎ²Î¬ÎœÎµÎ¹ ÏÎ¿ Î­ÏÎ¿Ï 1903, ÎºÎ±Î¹ ÎµÏÎ¯ÏÎ·Ï Î­Î³Î³ÏÎ±ÏÎ± ÏÎ¿Ï
+ ÎŒÎ­ÏÎ± ÏÏÎ¿ ÎºÎµÎ¯ÎŒÎµÎœÎ¿ ÏÎ¿Ï
+Ï Î¿ÎœÎ¿ÎŒÎ±ÏÎ¯Î¶Î¿Ï
+Îœ ÏÎ¿Îœ Î±Î¹ÏÎœÎ± ÏÏÎ¿Îœ Î¿ÏÎ¿Î¯Î¿ ÏÎ¿ 1903 Î±ÎœÎ®ÎºÎµÎ¹ (Î³ÏÎ¬ÏÎ¿Ï
+Îœ, Î³Î¹Î± ÏÎ±ÏÎ¬ÎŽÎµÎ¹Î³ÎŒÎ±, "ÏÎ¿Îœ 20Î¿ Î±Î¹ÏÎœÎ±" Î® "ÏÎ¿Îœ ÎµÎ¹ÎºÎ¿ÏÏÏ Î±Î¹ÏÎœÎ±"). ÎÏ
+ÏÏ ÏÎ·ÎŒÎ±Î¯ÎœÎµÎ¹ ÏÏÎ¹, ÏÎµ ÎŒÎµÏÎ¹ÎºÎ¬ Î­Î³Î³ÏÎ±ÏÎ±, Î¿Î¹ ÏÏ
+Î³ÎºÎµÎºÏÎ¹ÎŒÎ­ÎœÎµÏ Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯ÎµÏ ÏÎ·Ï ÏÏÏÎŒÎ±Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï ÎŽÎµÎœ ÎžÎ± ÎµÎŒÏÎ±ÎœÎ¯Î¶Î¿ÎœÏÎ±Î¹ ÏÏÎ¿ ÎºÎµÎ¯ÎŒÎµÎœÎ¿. ÎÎ¹Î± Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· ÏÏÎµÏÎ¹ÎºÎ¬ ÎŒÎµ ÎŒÎ¹Î± ÏÏÎ¿ÎœÎ¹ÎºÎ® ÏÎµÏÎ¯Î¿ÎŽÎ¿, ÏÎ»Î± ÏÎ± ÏÎ±ÏÎ±ÏÎ¬ÎœÏ Î±ÏÎ¿ÏÎ¿ÏÎœ ÎºÎ¬ÎžÎµ Î­ÏÎ¿Ï ÏÎ·Ï ÏÏÎ¿ÎœÎ¹ÎºÎ®Ï ÏÎµÏÎ¹ÏÎŽÎ¿Ï
+.<p>
+}
+
+_textchangeprefs_ [l=el] {ÎÎ»Î»Î¬Î¶Î¿ÎœÏÎ±Ï ÏÎ¹Ï ÎÏÎ¹Î»Î¿Î³Î­Ï ÏÎ±Ï/ preferences}
+
+_texthelppreferences_ [l=el] {
+<p>Î Î±ÏÏÎœÏÎ±Ï ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ <i>ÎµÏÎ¹Î»Î¿Î³Î­Ï</i> ÏÏÎ¿ ÏÎ¬ÎœÏ ÎŒÎ­ÏÎ¿Ï ÏÎ·Ï ÏÎµÎ»Î¯ÎŽÎ±Ï ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± Î±Î»Î»Î¬ÎŸÎµÏÎµ Î¿ÏÎ¹ÏÎŒÎ­ÎœÎ± ÏÎ±ÏÎ±ÎºÏÎ·ÏÎ¹ÏÏÎ¹ÎºÎ¬ ÏÎ·Ï ÎµÏÎ¹ÏÎ¬ÎœÎµÎ¹Î±Ï ÎµÏÎ³Î±ÏÎ¯Î±Ï, ÏÏÏÎµ ÎœÎ± ÎµÎŸÏ
+ÏÎ·ÏÎµÏÎ¿ÏÎœ ÎºÎ±Î»ÏÏÎµÏÎ± ÏÎ¹Ï Î±ÏÎ±Î¹ÏÎ®ÏÎµÎ¹Ï ÏÎ±Ï 
+}
+_texthelpcollectionprefstitle_ [l=el] {ÎÏÎ¹Î»Î¿Î³Î­Ï ÏÎ·Ï Î£Ï
+Î»Î»Î¿Î³Î®Ï}
+_texthelpcollectionprefs_ [l=el] {
+ÎÎµÏÎ¹ÎºÎ­Ï ÏÏ
+Î»Î»Î¿Î³Î­Ï ÏÎµÏÎ¹Î»Î±ÎŒÎ²Î¬ÎœÎ¿Ï
+Îœ Ï
+ÏÎ¿-ÏÏ
+Î»Î»Î¿Î³Î­Ï ÏÏÎ¹Ï Î¿ÏÎ¿Î¯ÎµÏ ÎŒÏÎ¿ÏÎµÎ¯ ÎœÎ± Î³Î¯ÎœÎµÎ¹ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·, ÎµÎ¯ÏÎµ ÎŒÎµÎŒÎ¿ÎœÏÎŒÎ­ÎœÎ±, Î® ÏÎ¿Î»Î»Î­Ï ÎŒÎ±Î¶Î¯ ÏÏ ÎŒÎ¹Î± ÎµÎœÏÏÎ·ÏÎ±. ÎÏÎ¿ÏÎµÎ¯ÏÎµ, ÎµÏÎ¿ÎŒÎ­ÎœÏÏ, ÎœÎ± ÎµÏÎ¹Î»Î­ÎŸÎµÏÎµ ÏÎ¿Î¹Î­Ï Ï
+ÏÎ¿ÏÏ
+Î»Î»Î¿Î³Î­Ï ÎžÎ­Î»ÎµÏÎµ ÎœÎ± ÏÎµÏÎ¹Î»Î±ÎŒÎ²Î¬ÎœÎ¿Ï
+Îœ Î¿Î¹ Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÎ¹Ï ÏÎ±Ï ÎŒÎ­ÏÏ ÏÎ·Ï ÏÎµÎ»Î¯ÎŽÎ±Ï ÎµÏÎ¹Î»Î¿Î³ÏÎœ. 
+}
+
+ _texthelplanguageprefstitle_ [l=el] {ÎÏÎ¹Î»Î¿Î³Î® ÎÎ»ÏÏÏÎ±Ï}
+_texthelplanguageprefs_ [l=el] {
+ÎÎ¬ÎžÎµ ÏÏ
+Î»Î»Î¿Î³Î® Î­ÏÎµÎ¹ ÎŒÎ¹Î± ÏÏÎ¿ÎµÏÎ¹Î»ÎµÎ³ÎŒÎ­ÎœÎ· Î³Î»ÏÏÏÎ± ÏÎ±ÏÎ¿Ï
+ÏÎ¯Î±ÏÎ·Ï, Î±Î»Î»Î¬ ÎµÏÎµÎ¯Ï ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± Î±Î»Î»Î¬ÎŸÎµÏÎµ ÏÎ·Îœ Î³Î»ÏÏÏÎ± Î±Ï
+ÏÎ®. ÎÏÎ¿ÏÎµÎ¯ÏÎµ Î±ÎºÏÎŒÎ± ÎœÎ± Î±Î»Î»Î¬ÎŸÎµÏÎµ ÏÎ¿ ÏÏÎ®ÎŒÎ± ÎºÏÎŽÎ¹ÎºÎ¿ÏÎ¿Î¯Î·ÏÎ·Ï ÏÎ¿Ï
+ ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÎµÎ¯ Î· Greenstone for output to the browser -- ÏÎ¿ Î»ÎµÎ¹ÏÎ¿Ï
+ÏÎ³Î¹ÎºÏ ÏÏÏÏÎ·ÎŒÎ± / the software ÎµÏÎ¹Î»Î­Î³ÎµÎ¹
+sensible defaults, Î±Î»Î»Î¬ ÎŒÎµ Î¿ÏÎ¹ÏÎŒÎ­ÎœÎ¿Ï
+Ï browsers ÎºÎ±Î»ÏÏÎµÏÎ± Î¿ÏÏÎ¹ÎºÎ¬ Î±ÏÎ¿ÏÎµÎ»Î­ÏÎŒÎ±ÏÎ± ÎŒÏÎ¿ÏÎ¿ÏÎœ ÎœÎ± ÎµÏÎ¹ÏÎµÏ
+ÏÎžÎ¿ÏÎœ ÎŒÎµ ÎŽÎ¹Î±ÏÎ¿ÏÎµÏÎ¹ÎºÏ ÏÏÎ®ÎŒÎ± ÎºÏÎŽÎ¹ÎºÎ¿ÏÎ¿Î¯Î·ÏÎ·Ï. ÎÎ»ÎµÏ Î¿Î¹ ÏÏ
+Î»Î»Î¿Î³Î­Ï ÏÎ±Ï ÎµÏÎ¹ÏÏÎ­ÏÎ¿Ï
+Îœ ÎœÎ± Î±Î»Î»Î¬ÎŸÎµÏÎµ ÏÎ± ÏÏÎ¿ÎµÏÎ¹Î»ÎµÎ³ÎŒÎ­ÎœÎ± Î³ÏÎ±ÏÎ¹ÎºÎ¬ ÏÎ·Ï ÎµÏÎ¹ÏÎ¬ÎœÎµÎ¹Î±Ï ÎµÏÎ³Î±ÏÎ¯Î±Ï ÏÎµ ÏÏÏÎŒÎ± ÎºÎµÎ¹ÎŒÎ­ÎœÎ¿Ï
+. ÎÏ
+ÏÏ ÎµÎ¯ÎœÎ±Î¹ Î¹ÎŽÎ¹Î±Î¹ÏÎ­ÏÏÏ ÏÏÎ®ÏÎ¹ÎŒÎ¿ Î³Î¹Î± ÏÏÎ®ÏÏÎµÏ ÎŒÎµ ÏÏÎ¿Î²Î»Î®ÎŒÎ±ÏÎ± ÏÏÎ±ÏÎ·Ï ÏÎ¿Ï
+ ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹Î¿ÏÎœ ÎµÎ¯ÏÎµ ÎŒÎµÎ³Î¬Î»Î¿Ï
+Ï ÏÎ±ÏÎ±ÎºÏÎ®ÏÎµÏ ÏÏÎ·Îœ Î¿ÎžÏÎœÎ·, Î® ÏÏ
+ÎœÎžÎ­ÏÎµÏ ÏÏÎœÎ®Ï 
+}
+
+_texthelppresentationprefstitle_ [l=el] {ÎÏÎ¹Î»Î¿Î³Î­Ï Î Î±ÏÎ¿Ï
+ÏÎ¯Î±ÏÎ·Ï}
+_texthelppresentationprefs_ [l=el] {
+ÎÎœÎ¬Î»Î¿Î³Î± ÎŒÎµ ÏÎ·Îœ ÏÏ
+Î»Î»Î¿Î³Î® ÏÎ¿Ï
+ ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÎµÎ¯ÏÎ±Î¹, ÎŒÏÎ¿ÏÎµÎ¯ ÎœÎ± Ï
+ÏÎ¬ÏÏÎ¿Ï
+Îœ ÎµÎœÎ±Î»Î»Î±ÎºÏÎ¹ÎºÎ­Ï ÎµÎºÎŽÎ¿ÏÎ­Ï ÏÏÎ·ÏÎ¯ÎŒÎ±ÏÎ¿Ï Î³Î¹Î± ÏÎ¿Îœ Î­Î»ÎµÎ³ÏÎ¿ ÏÎ·Ï ÏÎ±ÏÎ¿Ï
+ÏÎ¯Î±ÏÎ·Ï/several options you can
+set that control the presentation.
+
+<p>ÎÎ¹ ÏÏ
+Î»Î»Î¿Î³Î­Ï ÏÎµÎ»Î¯ÎŽÏÎœ Web ÏÎ±Ï ÎµÏÎ¹ÏÏÎ­ÏÎ¿Ï
+Îœ ÎœÎ± ÏÏ
+ÎŒÏÎ¹Î­ÏÎµÏÎµ ÏÎ·Îœ ÎŒÏÎ¬ÏÎ± ÏÎ»Î¿Î®Î³Î·ÏÎ·Ï ÏÎ¿Ï
+ Greenstone/ suppress the Greenstone navigation bar ÏÏÎ¿ ÏÎ¬ÎœÏ ÎŒÎ­ÏÎ¿Ï ÎºÎ¬ÎžÎµ ÏÎµÎ»Î¯ÎŽÎ±Ï ÏÎ¿Ï
+ ÎµÎ³Î³ÏÎ¬ÏÎ¿Ï
+, Î­ÏÏÎ¹ ÏÏÏÎµ, ÎŒÎµÏÎ¬ Î±ÏÏ ÎºÎ¬ÎžÎµ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·, ÎœÎ± ÏÎ·Î³Î±Î¯ÎœÎµÏÎ±Î¹ Î±Ï
+ÏÎ¿ÎŒÎ¬ÏÏÏ ÏÏÎ·Îœ ÏÎµÎ»Î¯ÎŽÎ± ÏÎ¿Ï
+ ÏÎ±Î¹ÏÎ¹Î¬Î¶ÎµÎ¹ ÏÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ® ÏÎ±Ï ÏÏÏÎ¯Ï ÎœÎ± ÎµÎŒÏÎ±ÎœÎ¯Î¶Î¿ÎœÏÎ±Î¹ Î¿Î¹ ÎµÏÎ¹ÎºÎµÏÎ±Î»Î¯ÎŽÎµÏ ÏÎ·Ï Greenstone / without any Greenstone header. ÎÎ¹Î± ÎœÎ± ÎŸÎµÎºÎ¹ÎœÎ®ÏÎµÏÎµ ÎºÎ±Î¹ÎœÎ¿ÏÏÎ³Î¹Î± Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· ÎžÎ± ÏÏÎ­ÏÎµÎ¹ ÎœÎ± ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÎµÎ¯ÏÎµÏÎµ ÏÎ¿ ÎºÎ¿Ï
+ÎŒÏÎ¯ "ÏÎ¯ÏÏ" Î±ÏÏ ÏÎ¿Îœ browser ÏÎ±Ï. ÎÏ
+ÏÎ­Ï Î¿Î¹ ÏÏ
+Î»Î»Î¿Î³Î­Ï ÏÎ±Ï ÎµÏÎ¹ÏÏÎ­ÏÎ¿Ï
+Îœ Î±ÎºÏÎŒÎ± ÎœÎ± ÏÏ
+ÎŒÏÎ¹Î­ÏÎµÏÎµ ÏÎ¿ ÏÏÎ¿ÎµÎ¹ÎŽÎ¿ÏÎ¿Î¹Î·ÏÎ¹ÎºÏ ÎŒÎ®ÎœÏ
+ÎŒÎ± ÏÎ·Ï Greenstone ÏÏÎ±Îœ ÎµÏÎ¹Î»Î­Î³ÎµÏÎµ Î­ÎœÎ± ÏÏÎœÎŽÎµÏÎŒÎ¿ ÏÎ¿Ï
+ ÏÎ±Ï Î²Î³Î¬Î¶ÎµÎ¹ ÎµÎºÏÏÏ ÏÎ·Ï ÏÎ·ÏÎ¹Î±ÎºÎ®Ï Î²Î¹Î²Î»Î¹Î¿ÎžÎ®ÎºÎ·Ï, ÏÏÎ¿ Web. ÎÏÎ¯ÏÎ·Ï, ÏÎµ ÎŒÎµÏÎ¹ÎºÎ­Ï ÏÏ
+Î»Î»Î¿Î³Î­Ï, ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± ÎµÏÎ¹Î»Î­ÎŸÎµÏÎµ ÎµÎ¬Îœ Î¿ ÏÏÎœÎŽÎµÏÎŒÎ¿Ï ÏÏÎ± "Î±ÏÎ¿ÏÎµÎ»Î­ÏÎŒÎ±ÏÎ± Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï" ÎžÎ± ÏÎ±Ï ÏÎ·Î³Î±Î¯ÎœÎµÎ¹ ÎºÎ±ÏÎµÏ
+ÎžÎµÎ¯Î±Îœ ÏÏÎ¿ ÏÏÎ±Î³ÎŒÎ±ÏÎ¹ÎºÏ URL ÏÎ¿Ï
+ Î±ÎœÎ±Î¶Î·ÏÎ¬ÏÎµ, Î±ÎœÏÎ¯ Î³Î¹Î± ÏÎ¿ Î±ÎœÏÎ¯Î³ÏÎ±ÏÎ¿ ÏÎ·Ï Î²Î¹Î²Î»Î¹Î¿ÎžÎ®ÎºÎ·Ï.
+}
+
+_texthelpsearchprefstitle_ [l=el] {ÎÏÎ¹Î»Î¿Î³Î­Ï ÎÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï}
+_texthelpsearchprefs_ [l=el] {
+<p>ÎÏÎ¿ Î¶ÎµÏ
+Î³Î¬ÏÎ¹Î± ÎºÎ¿Ï
+ÎŒÏÎ¹ÏÎœ ÎµÎ»Î­Î³ÏÎ¿Ï
+Îœ ÏÎ¿ ÎµÎ¯ÎŽÎ¿Ï ÏÎ¿Ï
+ ÎºÎµÎ¹ÎŒÎ­ÎœÎ¿Ï
+ ÏÎ¿Ï
+ ÏÎ±Î¹ÏÎ¹Î¬Î¶ÎµÎ¹ ÏÏÎ¹Ï Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÎ¹Ï ÏÎ¿Ï
+ ÎºÎ¬ÎœÎµÏÎµ. Î€Î¿ ÏÏÏÏÎ¿ ÏÎµÏ (ÎŒÎµ ÏÎ¿ ÏÎœÎ¿ÎŒÎ± "ÎŽÎ¹Î±ÏÎ¿ÏÎ¬ ÏÎµÎ¶ÏÎœ - ÎºÎµÏÎ±Î»Î±Î¯ÏÎœ"/ "case differences") ÎµÎ»Î­Î³ÏÎµÎ¹ ÎµÎ¬Îœ ÏÎ± ÏÎµÎ¶Î¬ ÎºÎ±Î¹ ÏÎ± ÎºÎµÏÎ±Î»Î±Î¯Î± Î³ÏÎ¬ÎŒÎŒÎ±ÏÎ± ÏÎ±Î¹ÏÎ¹Î¬Î¶Î¿Ï
+Îœ/ whether upper and
+lower case must match.  Î€Î¿ ÎŽÎµÏÏÎµÏÎ¿ ("ÎºÎ±ÏÎ±Î»Î®ÎŸÎµÎ¹Ï Î»Î­ÎŸÎµÏÎœ") ÎµÎ»Î­Î³ÏÎµÎ¹ Î±Îœ ÎžÎ± ÏÏÎ­ÏÎµÎ¹ ÎœÎ± Î±Î³ÎœÎ¿Î®ÏÎµÎ¹ ÏÎ¹Ï ÎºÎ±ÏÎ±Î»Î®ÎŸÎµÎ¹Ï ÏÏÎœ ÏÏÏÎœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï Î® ÏÏÎ¹. ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎµÏÎ¯ÏÎ·Ï ÎœÎ± ÎµÏÎ¹Î»Î­ÎŸÎµÏÎµ Î­ÎœÎ± ÎŒÎµÎ³Î¬Î»Î¿Ï
+ ÎŒÎµÎ³Î­ÎžÎ¿Ï
+Ï ÎºÎ¿Ï
+ÏÎ¯ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï ÏÏÏÎµ ÎœÎ± Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÏÎµ ÎµÏ
+ÎºÎ¿Î»ÏÏÎµÏÎ± ÎºÎµÎ¯ÎŒÎµÎœÎ¿ ÏÎµ ÎŒÎ­Î³ÎµÎžÎ¿Ï ÏÎ±ÏÎ±Î³ÏÎ¬ÏÎ¿Ï
+. Î Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· ÎŒÎµÎ³Î¬Î»ÏÎœ ÎºÎµÎ¹ÎŒÎ­ÎœÏÎœ ÎµÎ¯ÎœÎ±Î¹ ÎµÎœÏÏ
+ÏÏÏÎ¹Î±ÎºÎ¬ Î³ÏÎ®Î³Î¿ÏÎ·.                                                                                                                                     
+<p>ÎÎ¹Î± ÏÎ±ÏÎ¬ÎŽÎµÎ¹Î³ÎŒÎ±, Î±Îœ ÎµÏÎ¹Î»ÎµÎ³Î¿ÏÎœ ÏÎ± ÎºÎ¿Ï
+ÎŒÏÎ¹Î¬ <i>Î±Î³ÎœÏÎ·ÏÎµ ÏÎ¹Ï ÎŽÎ¹Î±ÏÎ¿ÏÎ­Ï ÏÎµÎ¶ÏÎœ -ÎºÎµÏÎ±Î»Î±Î¯ÏÎœ/ignore case differences</i> ÎºÎ±Î¹
+<i>Î±Î³ÎœÏÎ·ÏÎµ ÏÎ¹Ï ÎºÎ±ÏÎ±Î»Î®ÎŸÎµÎ¹Ï Î»Î­ÎŸÎµÏÎœ</i>, Î· Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·<p>
+    <ul><kbd>ÎÏÏÎ¹ÎºÎ±ÎœÎ¹ÎºÏ KÏÎ¯ÏÎ¹Î¿</kbd></ul>
+      <p>ÎžÎ± Î±ÎœÏÎ¹ÎŒÎµÏÏÏÎ¹ÏÏÎµÎ¯ ÎŒÎµ ÏÎ¿Îœ Î¯ÎŽÎ¹Î¿ ÏÏÏÏÎ¿ ÏÏÏÏ Î· Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· Î³Î¹Î±<p>
+      <ul><kbd>Î±ÏÏÎ¹ÎºÎ® ÎºÏÎ¯ÏÎŒÎ±</kbd></ul><p>
+      ÎµÏÎµÎ¹ÎŽÎ® ÏÎ± ÎºÎµÏÎ±Î»Î±Î¯Î± Î³ÏÎ¬ÎŒÎŒÎ±ÏÎ± ÎžÎ± Î±Î»Î»Î¬ÎŸÎ¿Ï
+Îœ ÏÎµ ÏÎµÎ¶Î¬ ÎºÎ±Î¹ Î¿Î¹ ÎºÎ±ÏÎ±Î»Î®ÎŸÎµÎ¹Ï "-ÎœÎ¹ÎºÏ" ÎºÎ±Î¹ "-ÏÎ¹Î¿" ÎžÎ± ÏÏÎ³Î¿Ï
+Îœ Î±ÏÏ ÏÎ¹Ï Î»Î­ÎŸÎµÎ¹Ï "ÎÏÏÎ¹ÎºÎ±ÎœÎ¹ÎºÏ" ÎºÎ±Î¹ "ÎºÏÎ¯ÏÎ¹Î¿" Î±ÎœÏÎ¯ÏÏÎ¿Î¹ÏÎ±. 
+
+<p>ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± ÎµÏÎ¹Î»Î­ÎŸÎµÏÎµ ÏÎ·Îœ "ÏÏÎœÎžÎµÏÎ·" Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ· ÏÎ¿Ï
+ ÎžÎ± ÏÎ±Ï ÎµÏÎ¹ÏÏÎ­ÏÎµÎ¹ ÎœÎ± ÏÏ
+ÎœÎŽÏ
+Î¬ÏÎµÏÎµ ÏÏÎ¿Ï
+Ï ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÏÎœÏÎ±Ï ÏÎ¿Ï
+Ï ÏÏ
+ÎœÎŽÎ­ÏÎŒÎ¿Ï
+Ï AND (&), OR (|), ÎºÎ±Î¹ ÏÎ¿ NOT (!). ÎÏ
+ÏÏ ÎžÎ± ÏÎ±Ï ÎµÏÎ¹ÏÏÎ­ÏÎµÎ¹ ÎœÎ± ÎµÎŸÎµÎ¹ÎŽÎ¹ÎºÎµÏÏÎµÏÎµ ÏÎµÏÎ¹ÏÏÏÏÎµÏÎ¿ ÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ® ÏÎ±Ï. ÎÏÎ¿ÏÎµÎ¯ÏÎµ ÎµÏÎ¯ÏÎ·Ï ÎœÎ± ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹ÎµÎ¯ÏÎ±Î¹ ÏÎ·Îœ ÎµÏÎ¹Î»Î¿Î³Î® ÏÎ¿Ï
+ Î¹ÏÏÎ¿ÏÎ¹ÎºÎ¿Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï, Î³Î¹Î± ÎœÎ± ÎŽÎµÎ¯ÏÎµ ÏÎ¹Ï ÏÎµÎ»ÎµÏ
+ÏÎ±Î¯ÎµÏ ÏÎ±Ï Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÎ¹Ï. ÎÏ
+ÏÏ ÎŽÎ¹ÎµÏ
+ÎºÎ¿Î»ÏÎœÎµÎ¹ ÏÎ·Îœ ÎµÏÎ±ÎœÎ¬Î»Î·ÏÎ· ÎµÎ»Î±ÏÏÏÏ ÏÏÎ¿ÏÎ¿ÏÎ¿Î¹Î·ÎŒÎ­ÎœÏÎœ Î±ÎœÎ±Î¶Î·ÏÎ®ÏÎµÏÎœ. Î€Î­Î»Î¿Ï ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± ÎµÎ»Î­Î³ÎŸÎµÏÎµ ÏÎ¿Îœ Î±ÏÎ¹ÎžÎŒÏ ÏÏÎœ Î±ÏÎ¿ÏÎµÎ»ÎµÏÎŒÎ¬ÏÏÎœ ÏÎ¿Ï
+ ÎžÎ­Î»ÎµÏÎµ ÎœÎ± Î±ÎœÎ±ÎºÏÎ®ÏÎµÏÎµ ÎºÎ±Î¹ ÏÎ¿Îœ Î±ÏÎ¹ÎžÎŒÏ ÏÏÎœ Î±ÏÎ¿ÏÎµÎ»ÎµÏÎŒÎ¬ÏÏÎœ ÏÎ¿Ï
+ ÎžÎ­Î»ÎµÏÎµ ÎœÎ± Î²Î»Î­ÏÎµÏÎµ Î±ÎœÎ¬ Î¿ÎžÏÎœÎ·.
+}
+
+_texttanumbrowseoptions_ [l=el] {Î¥ÏÎ¬ÏÏÎ¿Ï
+Îœ _numbrowseoptions_ ÏÏÏÏÎ¿Î¹ ÎœÎ± Î²ÎµÎ¹ ÎºÎ±ÎœÎµÎ¯Ï ÏÎ»Î·ÏÎ¿ÏÎ¿ÏÎ¯ÎµÏ Î³Î¹' Î±Ï
+ÏÎ®Îœ ÏÎ· ÏÏ
+Î»Î»Î¿Î³Î®:}
+
+_textsimplehelpheading_ [l=el] {Î ÏÏ ÎœÎ± Î²ÏÎµÎ¯ÏÎµ ÏÎ»Î·ÏÎ¿ÏÎ¿ÏÎ¯ÎµÏ Î³Î¹Î± ÏÎ· ÏÏ
+Î»Î»Î¿Î³Î® _collectionname_ }
+
+_texthelpscopeheading_ [l=el] {ÎÏÏÎ¿Ï Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·Ï/ Scope of queries}
+_texthelpscope_ [l=el] {
+<p>
+Î£ÏÎ¹Ï ÏÎµÏÎ¹ÏÏÏÏÎµÏÎµÏ ÏÏ
+Î»Î»Î¿Î³Î­Ï ÎŒÏÎ¿ÏÎµÎ¯ÏÎµ ÎœÎ± ÎµÏÎ¹Î»Î­ÎŸÎµÏÎµ ÎŽÎ¹Î±ÏÎ¿ÏÎµÏÎ¹ÎºÎ¬ ÎµÏ
+ÏÎµÏÎ®ÏÎ¹Î± Î³Î¹Î± ÏÎ·Îœ Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ® ÏÎ±Ï. ÎÎ¹Î± ÏÎ±ÏÎ¬ÎŽÎµÎ¹Î³ÎŒÎ±, ÎŒÏÎ¿ÏÎµÎ¯ ÎœÎ± Ï
+ÏÎ¬ÏÏÎ¿Ï
+Îœ ÎµÏ
+ÏÎµÏÎ®ÏÎ¹Î± Î³Î¹Î± ÏÏ
+Î³Î³ÏÎ±ÏÎµÎ¯Ï Î® Î³Î¹Î± ÏÎ¯ÏÎ»Î¿Ï
+Ï. Î ÎµÏ
+ÏÎµÏÎ®ÏÎ¹Î± Î³Î¹Î± ÎºÎµÏÎ±Î»Î±Î¯Î± Î® ÏÎ±ÏÎ±Î³ÏÎ¬ÏÎ¿Ï
+Ï. ÎÎµÎœÎ¹ÎºÎ¬ ÏÎ¿ Î­Î³Î³ÏÎ±ÏÎ¿ ÏÎ¿Ï
+ ÏÎ±Î¹ÏÎ¹Î¬Î¶ÎµÎ¹ Î±ÏÎ¿Î»ÏÏÏÏ ÎžÎ± Î²ÏÎµÎžÎµÎ¯, Î±ÎœÎµÎŸÎ¬ÏÏÎ·ÏÎ± Î±ÏÏ ÏÎ¿ ÎµÏ
+ÏÎµÏÎ®ÏÎ¹Î¿ ÏÎ¿Ï
+ ÎžÎ± ÏÏÎ·ÏÎ¹ÎŒÎ¿ÏÎ¿Î¹Î®ÏÎµÏÎµ.
+<p>ÎÎœ ÏÎ± Î­Î³Î³ÏÎ±ÏÎ± ÏÎ¿Ï
+ Î±ÎœÎ±Î¶Î·ÏÎ¬ÏÎµ ÎµÎ¯ÎœÎ±Î¹ Î²Î¹Î²Î»Î¯Î±, ÎžÎ± ÎµÎ¯ÎœÎ±Î¹ Î±ÎœÎ¿Î¹Î³ÎŒÎ­ÎœÎ± ÏÏÎ·Îœ ÎºÎ±ÏÎ¬Î»Î»Î·Î»Î· ÏÎµÎ»Î¯ÎŽÎ±.
+}
Index: /gsdl/stable/macros/gsdl.dm
===================================================================
--- /gsdl/stable/macros/gsdl.dm	(revision 20131)
+++ /gsdl/stable/macros/gsdl.dm	(revision 20131)
@@ -0,0 +1,88 @@
+# this file must be UTF-8 encoded
+
+package gsdl
+
+
+#######################################################################
+# global navigation links
+#######################################################################
+
+_globallinks_ {_homelink_}
+
+#######################################################################
+# page content
+#######################################################################
+
+_pagetitle_ {_textdescrgreenstone_}
+
+_content_ {
+<div id="content">
+
+<div class="divbar">
+<p class="navbar">
+_textaboutgslong_
+</p>
+</div>
+
+
+<table border="0">
+ <tr>
+  <td valign="middle" align="center">_imagegreenstone_</td>
+  <td valign="middle"><p>_textgreenstone1_</p></td>
+ </tr>
+ <tr>
+  <td valign="middle" align="center"><h2><a href="http://nzdl.org">nzdl.org</a></h2></td>
+  <td valign="middle"><p>_textgreenstone2_</p></td>
+ </tr>
+ <tr>
+  <td valign="middle" align="center"><h2>_textplatformtitle_</h2></td>
+  <td valign="middle"><p>_textgreenstone3_</p></td>
+ </tr>
+ <tr>
+  <td valign="middle" align="center">
+    <a href="http://nzdl.org/hdl"><img class="icon" width="101" height="100" src="_httpimg_/hdlimg.jpg" alt="HDL Collection"></a>
+  </td>
+  <td valign="middle"><p>_textgreenstone4_</p></td>
+ </tr>
+ <tr>
+  <td valign="middle" align="center"><h2>_textcustomisationtitle_</h2></td>
+  <td valign="middle"><p>_textgreenstone5_</p></td>
+ </tr>
+ <tr>
+  <td valign="middle" align="center">
+  <h2><a href="http://wiki.greenstone.org/wiki/index.php/GreenstoneWiki">_textdocumentationtitle_</a></h2>
+  </td>
+  <td valign="middle"><p>_textdocuments_</p></td>
+</tr>
+ <tr>
+  <td valign="middle" align="center"><h2>_textmailinglisttitle_</h2></td>
+  <td valign="middle"><p>_textmailinglist_</p></td>
+ </tr>
+ <tr>
+  <td valign="middle" align="center"><h2>_textbugstitle_</h2></td>
+  <td valign="middle"><p>_textreport_</p></td>
+ </tr>
+ <tr>
+  <td valign="middle" align="center"><h2>_textgs3title_</h2></td>
+  <td valign="middle"><p>_textgs3_</p></td>
+ </tr>
+ <tr>
+  <td valign="middle" align="center"><h2>_textcreditstitle_</h2></td>
+  <td valign="middle"><p>_textwhoswho_</p></td>
+ </tr>
+</table>
+
+<div class="divbar">&nbsp;</div>
+
+<table>
+<tr valign="top">
+<td>_home:textpoem_</td>
+<td>_imagegreenstone_</td>
+</tr></table>
+
+_home:textgreenstone_
+
+_nzdlpagefooter_
+
+</div>
+}
Index: /gsdl/stable/macros/gti.dm
===================================================================
--- /gsdl/stable/macros/gti.dm	(revision 20131)
+++ /gsdl/stable/macros/gti.dm	(revision 20131)
@@ -0,0 +1,285 @@
+# this file must be UTF-8 encoded
+
+package gti
+
+_gtiadministratoremail_ {lh92@cs.waikato.ac.nz}
+
+#######################################################################
+# page head
+#######################################################################
+_cssheader_ {
+_style:cssheader_
+
+<style type="text/css">
+div.todo\{float: left; width: 23px; white-space: pre; text-align: right; color: red;\}
+div.update\{float: left; width: 23px; white-space: pre; text-align: right; color: orange;\}
+div.done\{float: left; width: 23px; white-space: pre; text-align: right; color: green;\}
+div.plus\{float: left; width: 11px; white-space: pre; text-align: center; padding-left: 2px; padding-right: 2px;\}
+div.nowrap\{table-layout: fixed; width: 100px; padding-left:3px; padding-right:3px;\}
+table.status\{border-collapse: collapse;border-style: none; font-size: 12pt;\}
+td.first\{border:solid; border-width:1px; border-color:grey; border-collapse: collapse; vertical-align: middle;\}
+td.status\{table-layout: fixed; border:solid; border-width:1px; border-color:grey; border-collapse: collapse; vertical-align: middle; text-align: center;\}
+th.status\{border:solid; border-width:1px; border-color:white; border-collapse: collapse; background-color: #d0d0d0; text-align: center;\}
+</style>
+}
+
+#######################################################################
+# page content
+#######################################################################
+
+_pagewidth_ {700}
+
+_pagetitle_ {_textgti_}
+
+_imagecollection_ {<a href="_gwcgi_?a=gti&amp;p=home&amp;e=_compressedoptions_"><img alt="_textgti_" src="_httpimg_/gti.gif" /></a>}
+
+# The preferences button must go to the "homepref" page, since we are not in a collection
+
+_preflink_ {_navtaborig_(_home:httppagehomepref_,_linktextPREFERENCES_,_textdescrpref_)}
+
+_gtidownloadglihelp_ {_gwcgi_?a=gti&amp;p=glihelp&amp;e=_compressedoptions_}
+
+_content_ {
+<div class="divbar">&nbsp;</div>
+
+<form method="post" action="_gwcgi_">
+  <input type="hidden" name="a" value="gti"/>
+  <input type="hidden" name="e" value="_compressedoptions_">
+  _gtiformcontent_
+</form>
+
+<div class="divbar">&nbsp;</div>
+}
+
+# Content of the GTI "error" page
+_gtierror_ {
+<strong>_textgtierror_:</strong>
+<p>
+<tt>_gtierrormessage_</tt>
+}
+
+# Content of the GTI "home" page
+_gtihome_ {
+<p>_textgtihome_</p>
+
+<table border="0" width="100%">
+  <tr><td>_textgtiselecttlc_:</td><td align="right">_gtitlcselection_</td></tr>
+</table>
+
+<center>
+  <input type="hidden" name="p" value="lang"/><input type="submit" value="_textgtienter_"/>
+</center>
+}
+
+# Content of the GTI "language status" page
+_gtilang_ {
+<h2>_gtitargetlanguagename_</h2>
+
+<p>_textgtiselecttfk_:</p>
+
+_gtitfkselection_
+
+<center>
+  <input type="hidden" name="p" value="core"/><input type="submit" value="_textgtienter_"/>
+</center>
+}
+
+# Content of the GTI "view status" page
+_gtistatus_ {
+<h2>_textgtistatustable_</h2>
+<table>
+<tr><td><font color="green">green</font>:</td><td>_textgtinumchunkstranslated2_</td></tr>
+<tr><td><font color="orange">orange</font>:</td><td>_textgtinumchunksrequiringupdating2_</td></tr>
+<tr><td><font color="red">red</font>:</td><td>_textgtinumchunksrequiringtranslation2_</td></tr>
+</table>
+_gtistatustable_
+}
+
+# Content of the GTI "find text fragments" page
+_gtifind_ {
+<h2><a href="_gwcgi_?a=gti&amp;p=lang&amp;e=_compressedoptions_">_gtitargetlanguagename_</a> -- <a href="_gwcgi_?a=gti&amp;p=core&amp;e=_compressedoptions_">_gtitranslationfiledesc_</a></h2>
+<p>
+_textgtienterquery_:
+<p>
+<nobr>
+<input type="text" name="q" value="_cgiargq_" size="_gtitextareawidth_"/>
+<input type="hidden" name="p" value="find"/><input type="submit" value="_textgtifind_"/>
+</nobr>
+_gtifindformcontent_
+}
+
+# Content of the GTI "offline" page
+_gtioffline_ {
+<h2><a href="_gwcgi_?a=gti&amp;p=lang&amp;e=_compressedoptions_">_gtitargetlanguagename_</a> -- _gtitranslationfiledesc_</h2>
+<p>
+_textgtiofflinetranslation_
+}
+
+# Content of the GTI "core" page (with text areas for entering and updating translations)
+_gticore_ {
+<h2><a href="_gwcgi_?a=gti&amp;p=lang&amp;e=_compressedoptions_">_gtitargetlanguagename_</a> -- _gtitranslationfiledesc_</h2>
+<p>
+<center>
+  _gtitranslationfilestatus_(_gtinumchunkstranslated_, _gtinumchunksrequiringtranslation_, _gtinumchunksrequiringupdating_, _gtitargetfilepath_)
+</center>
+<p>
+_gticoreformcontent_
+<p>
+<center>
+  <input type="hidden" name="p" value="submit"/><input type="submit" value="_textgtisubmit_"/>
+</center>
+}
+
+# Content of the GTI "done" page, thanking the translator for completing the file
+_gtidone_ {
+<h2><a href="_gwcgi_?a=gti&amp;p=lang&amp;e=_compressedoptions_">_gtitargetlanguagename_</a> -- _gtitranslationfiledesc_</h2>
+<p>
+<center>
+  _gtitranslationfilestatus_(_gtinumchunkstranslated_, _gtinumchunksrequiringtranslation_, _gtinumchunksrequiringupdating_, _gtitargetfilepath_)
+</center>
+<p>
+<hr>
+<p>
+_textgtitranslationfilecomplete_
+}
+
+_gtifindformheader_ {
+<hr><p>_textgtinumchunksmatchingquery_: _gtinumchunksmatchingquery_
+}
+
+_gtifindformfooter_ {
+<p>
+<center>
+  <input type="submit" name="sp" value="_textgtisubmit_"/>
+</center>
+}
+
+_gtitextareawidth_ {85}
+_gtitextareaheight_ {6}
+
+# --------------------------------------------------------------------------------
+#   Displays the status of a translation file
+#
+#   Used on the GTI "lang" and "core" pages
+#
+#   Parameters: 1 -- Number of chunks translated
+#               2 -- Number of chunks requiring translation
+#               3 -- Number of chunks requiring updating
+#		4 -- Relative URL of target file
+# --------------------------------------------------------------------------------
+
+# _If_(_gtiglihelpzipfilepath_ ne "", <a href="_httpprefix_/_gtiglihelpzipfilepath_">_textgtiglihelpzipfile_</a>,)<br>
+# <a href="_gwcgi_?a=gti&amp;p=glihelp&amp;e=_compressedoptions_">_textgtiglihelpzipfile_</a>
+
+_gtitranslationfilestatus_ {
+<table border="0">
+  <tr><td align="right">_1_</td><td>_textgtinumchunkstranslated_ (_textgtinumchunksrequiringupdating_(_3_))</td></tr>
+  <tr><td align="right">_2_</td><td>_textgtinumchunksrequiringtranslation_</td></tr>
+  _If_(_4_,<tr><td align="right">&nbsp;</td><td>
+     <a href="_gwcgi_?a=gti&amp;p=find&amp;e=_compressedoptions_">_textgticorrectexistingtranslations_</a><br>
+     _If_(_4_ eq _gtidownloadglihelp, <a href="_4_">, <a href="_httpprefix_/_4_">)_textgtidownloadtargetfile_</a>
+
+     _If_(_gtiglihelpzipfilepath_, <a href="_httpprefix_/_gtiglihelpzipfilepath_">_textgtiglihelpzipfile_</a>,)<br>
+
+     <a href="_gwcgi_?a=gti&amp;p=offline&amp;e=_compressedoptions_">_textgtitranslatefileoffline_</a><br>
+     _gtiviewtranslationfileinaction_
+  </td></tr>)
+</table>
+}
+
+_gtiglihelpzipfilepath_ {}
+
+_textgtiglihelpzipfile_ {Clicke here to download the operational files for GLI Help}
+
+# --------------------------------------------------------------------------------
+#   Displays the status of a translation file
+#
+#   Used on the GTI "view status" page
+#
+#   Parameters: 1 -- Number of chunks translated
+#               2 -- Number of chunks requiring translation
+#               3 -- Number of chunks requiring updating
+# --------------------------------------------------------------------------------
+_gtitranslationfilestatus2_ {
+_If_("_1_" eq "0", , <font color="green">_1_</font>+<font color="orange">_3_</font>+<font color="red">_2_</font>)
+}
+
+# --------------------------------------------------------------------------------
+#   Displays text area for correcting a chunk
+#
+#   Used on the GTI "find" page
+#
+#   Parameters: 1 -- Chunk key
+#               2 -- Target file chunk text
+# --------------------------------------------------------------------------------
+_gtichunkmatchingquery_ {
+<p>
+<center>
+  <table dir="_gtitextdirection_">
+    <tr><td><strong>_1_</strong></td></tr>
+    <tr><td><textarea name="_cgiargtlc_::_1_" rows="_gtitextareaheight_" cols="_gtitextareawidth_">_2_</textarea></td></tr>
+  </table>
+</center>
+}
+
+# --------------------------------------------------------------------------------
+#   Displays text areas for translating a chunk
+#
+#   Used on the GTI "core" page
+#
+#   Parameters: 1 -- Chunk key
+#               2 -- Source file chunk text
+#               3 -- Source file chunk date
+# --------------------------------------------------------------------------------
+_gtichunkrequiringtranslation_ {
+<hr>
+_textgtitranslatingchunk_(_1_)
+<p>
+<center>
+  <table dir="_gtitextdirection_">
+    <tr><td><strong>English</strong></td><td align="right"><font size="-1"><i>_textgtilastupdated_ _3_</i></font></td></tr>
+    <tr><td colspan="2"><textarea name="en::_1_" rows="_gtitextareaheight_" cols="_gtitextareawidth_" readonly="1">_2_</textarea></td></tr>
+  </table>
+  <table dir="_gtitextdirection_">
+    <tr><td><strong>_gtitargetlanguagename_</strong></td><td align="right">&nbsp;</td></tr>
+    <tr><td colspan="2"><textarea name="_cgiargtlc_::_1_" rows="_gtitextareaheight_" cols="_gtitextareawidth_"></textarea></td></tr>
+  </table>
+</center>
+}
+
+# --------------------------------------------------------------------------------
+#   Displays text areas for updating a chunk
+#
+#   Used on the GTI "core" page
+#
+#   Parameters: 1 -- Chunk key
+#               2 -- Source file chunk text
+#               3 -- Source file chunk date
+#               4 -- Target file chunk text
+#               5 -- Target file chunk date
+# --------------------------------------------------------------------------------
+_gtichunkrequiringupdating_ {
+<hr>
+_textgtiupdatingchunk_(_1_)
+<p>
+<center>
+  <table dir="_gtitextdirection_">
+    <tr><td><strong>English</strong></td><td align="right"><font size="-1"><i>_textgtilastupdated_ _3_</i></font></td></tr>
+    <tr><td colspan="2"><textarea name="en::_1_" rows="_gtitextareaheight_" cols="_gtitextareawidth_" readonly="1">_2_</textarea></td></tr>
+  </table>
+  <p>
+  <table dir="_gtitextdirection_">
+    <tr><td><strong>_gtitargetlanguagename_</strong></td><td align="right"><font size="-1"><i>_textgtilastupdated_ _5_</i></font></td></tr>
+    <tr><td colspan="2"><textarea name="_cgiargtlc_::_1_" rows="_gtitextareaheight_" cols="_gtitextareawidth_">_4_</textarea></td></tr>
+  </table>
+</center>
+}
+
+# Links to see the translation files in action
+_gtiviewcoredminaction_ {<a href="_gwcgi_?a=p&amp;p=about&amp;c=demo&amp;l=_cgiargtlc_&amp;e=_compressedoptions_">_textgtiviewtargetfileinaction_</a>}
+_gtiviewauxdminaction_ {<a href="_gwcgi_?a=p&amp;p=about&amp;c=demo&amp;l=_cgiargtlc_&amp;e=_compressedoptions_">_textgtiviewtargetfileinaction_</a>}
+
+_gtiviewperlmodulesinaction_ {}
+_gtiviewglihelpinaction_{}
+_gtiviewglidictinaction_ {}
+_gtiviewgreenorginaction_ {}
Index: /gsdl/stable/macros/gujarati.dm
===================================================================
--- /gsdl/stable/macros/gujarati.dm	(revision 20131)
+++ /gsdl/stable/macros/gujarati.dm	(revision 20131)
@@ -0,0 +1,849 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# English Language text and icon macros 
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=gu] {àªžàªŸàª®àªŸàª¯àª¿àªà«}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=gu] {àªžà«àª€à«àª°à«àª€ àªžàªàªŠàª°à«àª­}  
+_textdate_ [l=gu] {àªªà«àª°àªàªŸàª¶àªš àª€àªŸàª°à«àª}  
+_textnumpages_ [l=gu] {àªªàªŸàªšàªŸ àªšà« àªžàªàªà«àª¯àªŸ}  
+
+_textsignin_ [l=gu] {àª
+àª§àª¿àªà«àª€ àªàª°à«}  
+
+_textdefaultcontent_ [l=gu] {àª
+àªšà«àª°à«àª§ àªàª°à«àª²àªŸ àªªàªŸàªšàªŸ àª®àª³à« àª¶àªà«àª¯àªŸ àªšàª¥à«. àªà«àª°à«àªšàªžà«àªà«àªš àª¡àª¿àªàª¿àªàª² àª²àªŸàª¯àª¬à«àª°à«àª°à« àªªàª° àªªàª°àª€ àªàªµàªŸ àª®àªŸàªà« àª€àª®àªŸàª°à« àª¬à«àª°àªŸàªàªàª°àªšà«àª àªªàªŸàªàª³àªšà« àª¬àªàªš àª
+àª¥àªµàªŸ àªàªªàª° àªŠàª°à«àª¶àªŸàªµà«àª² 'àªàª°' àª¬àªàªš àªšà« àªàªªàª¯à«àª àªàª°à«.}  
+
+_textdefaulttitle_ [l=gu] {àªà«.àªàªž.àª¡à«.àªàª² àªàªžà«àª°}  
+
+_textbadcollection_ [l=gu] {àª àªžàªàªà«àª°àª¹ (àªà« "_cvariable_"àªšàªŸàª® àª¥à« àªàª³àªàªŸàª¯ àªà«) àª àªà«àª°à«àªšàªžà«àªà«àªš àª¡àª¿àªàª¿àªàª² àª²àªŸàª¯àª¬à«àª°à«àª°à« àªžàª¿àªžà«àªàª®àª®àªŸàª àªžàª®àªŸàªµà«àª¶ (àªàªšà«àªžà«àªà«àª²) àªàª°à«àª² àªšàª¥à«.}  
+
+_textselectpage_ [l=gu] {àªªàªŸàªšà«àª àªªàªžàªàªŠ àªàª°à«}  
+
+_collectionextra_ [l=gu] {àª àªžàªàªà«àª°àª¹àª®àªŸàª _about:numdocs_ àªªà«àª°àª²à«àªà« àªžàª®àªŸàª¯à«àª² àªà«. àª€à« àªà«àª²à«àª²àªŸ _about:builddate_ àªŠàª¿àªµàªžà« àªªàª¹à«àª²àªŸ àª¬àª¿àª²à«àª¡/àªšàª¿àª°à«àª®àª¿àª€ àª¥àª¯à« àª¹àª€à«.}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=gu] {<p>àª àªžàªàªà«àª°àª¹àª®àªŸàª _numdocs_ _If_("_numdocs_" eq "1",document,documents) àªžàª®àªŸàª¯à«àª² àªà«, àªšàª¿àª°à«àªŠà«àª¶àª¿àª€ àªà«àªàªžàª àª
+àªšà« àª®à«àªàªŸàª¡à«àªàªŸàªšàªŸ àªà«àª² _numbytes_ àªà«. <p>àª àªžàªàªà«àª°àª¹àªšà« àª¬àª¿àª²à«àª¡ àªžàª®àª°àª¿ (àªà«àªàªà« àª
+àª¹à«àªµàªŸàª²) àªà«àªµàªŸ àª®àªŸàªà« àª
+àª¹à«àª àªàª¿àª²àª àªàª°à«.<a href="_httppagex_(bsummary)"></a>}  
+
+_textdescrcollection_ [l=gu] {}
+_textdescrabout_ [l=gu] {àªªàªŸàªšàªŸ àªµàª¿àª¶à«}  
+_textdescrhome_ [l=gu] {àª¹à«àª® àªªà«àª}  
+_textdescrhelp_ [l=gu] {àª®àªŠàªŠ àªªàªŸàªšà«àª}  
+_textdescrpref_ [l=gu] {àªªàªžàªàªŠàªà«àª àªªàªŸàªšà«}  
+_textdescrgreenstone_ [l=gu] {àªà«àª°à«àªšàªžà«àªà«àªš àª¡àª¿àªàª¿àªàª² àª²àªŸàª¯àª¬à«àª°à«àª°à« àªžà«àª«à«àªàªµà«àª°}  
+_textdescrusab_ [l=gu] {àªàªªàª¯à«àª àªàª°àª€à« àªµàªàª€à« àª€àª®àªšà« àªàª¯àªŸàª àª®à«àª¶à«àªà«àª²à« àªªàª¡à«?}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=gu] {àª¶à«àª§}  
+_labelSearch_ [l=gu] {àª¶à«àª§}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=gu] {àª¶àª¿àª°à«àª·àª}  
+_labelTitle_ [l=gu] {àª¶àª¿àª°à«àª·àªà«}  
+_textCreator_ [l=gu] {àªšàª¿àª°à«àª®àªŸàª€àªŸ.}  
+_labelCreator_ [l=gu] {àªšàª¿àª°à«àª®àªŸàª€àªŸàª}  
+_textSubject_ [l=gu] {àªµàª¿àª·àª¯}  
+_labelSubject_ [l=gu] {àªµàª¿àª·àª¯à«}  
+_textDescription_ [l=gu] {àªµàª¿àªµàª°àª£}  
+_labelDescription_ [l=gu] {àªµàª¿àªµàª°àª£à«}  
+_textPublisher_ [l=gu] {àªªà«àª°àªàªŸàª¶àª}  
+_labelPublisher_ [l=gu] {àªªà«àª°àªàªŸàª¶àªà«}  
+_textContributor_ [l=gu] {àª«àªŸàª³à« àªàªªàªšàªŸàª°}  
+_labelContributor_ [l=gu] {àª«àªŸàª³à« àªàªªàªšàªŸàª°}  
+_textDate_ [l=gu] {àª€àªŸàª°à«àª}  
+_labelDate_ [l=gu] {àª€àªŸàª°à«àª}  
+_textType_ [l=gu] {àªªà«àª°àªàªŸàª°}  
+_labelType_ [l=gu] {àªªà«àª°àªàªŸàª°à«}  
+_textFormat_ [l=gu] {àªžà«àªµàª°à«àªª}  
+_labelFormat_ [l=gu] {àªžà«àªµàª°à«àªªà«}  
+_textIdentifier_ [l=gu] {àªàªàª¡à«àªšà«àªà«àª«àªŸàª¯àª°}  
+_labelIdentifier_ [l=gu] {àªàªàª¡à«àªšà«àªà«àª«àªŸàª¯àª°à«àªž}  
+_textSource_ [l=gu] {àª«àªŸàªàª²àªšàªŸàª®}  
+_labelSource_ [l=gu] {àª«àªŸàªàª² àªšàªŸàª®}  
+_textLanguage_ [l=gu] {àª­àªŸàª·àªŸ}  
+_labelLanguage_ [l=gu] {àª­àªŸàª·àªŸàª}  
+_textRelation_ [l=gu] {àªžàªàª¬àªàª§}  
+_labelRelation_ [l=gu] {àªžàªàª¬àªàª§à«}  
+_textCoverage_ [l=gu] {àªµàª¿àªžà«àª€àªŸàª°}  
+_labelCoverage_ [l=gu] {àªµàª¿àªžà«àª€àªŸàª°}  
+_textRights_ [l=gu] {àª¹àªà«}  
+_labelRights_ [l=gu] {àª¹àªà«}  
+
+# DLS metadata set
+_textOrganization_ [l=gu] {àªžàªàªžà«àª¥àªŸ}  
+_labelOrganization_ [l=gu] {àªžàªàªžà«àª¥àªŸàª}  
+_textKeyword_ [l=gu] {àªàªŸàªµà«àª°à«àªª àª¶àª¬à«àªŠ}  
+_labelKeyword_ [l=gu] {àªàªŸàªµà«àª°à«àªª àª¶àª¬à«àªŠà«}  
+_textHowto_ [l=gu] {àªà«àªµà« àª°à«àª€à«}  
+_labelHowto_ [l=gu] {àªà«àªµà« àª°à«àª€à«}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=gu] {àª¶àª¬à«àªŠàªžàª®à«àª¹}  
+_labelPhrase_ [l=gu] {àª¶àª¬à«àªŠàªžàª®à«àª¹à«}  
+_textCollage_ [l=gu] {àªàª³àªŸ}  
+_labelCollage_ [l=gu] {àªàª³àªŸ}  
+_textBrowse_ [l=gu] {àª¬à«àª°àªŸàªàª}  
+_labelBrowse_ [l=gu] {àª¬à«àª°àªŸàªàª}  
+_textTo_ [l=gu] {àª¥à«}  
+_labelTo_ [l=gu] {àª¥à«}  
+_textFrom_ [l=gu] {àª®àªŸàªàª¥à«}  
+_labelFrom_ [l=gu] {àª®àªŸàªàª¥à«}  
+_textAcronym_ [l=gu] {àªà«àªàªàªŸàªà«àª·àª°}  
+_labelAcronym_ [l=gu] {àªà«àªàªàªŸàªà«àª·àª°à«}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=gu] {_1_  àª§à«àªµàªŸàª°àªŸ àª¬à«àª°àªŸàªàª àªàª°à«}  
+
+_textdescrSearch_ [l=gu] {àªà«àªà«àªàªž àªªàªŠà« àª®àªŸàªà« àª¶à«àª§}  
+_textdescrType_ [l=gu] {àªµàªŸàªàªàªš àªžàªŸàª®àªà«àª°à«àªšàªŸ àªªà«àª°àªàªŸàª° àª§à«àªµàªŸàª°àªŸ àª¬à«àª°àªŸàªàª àªàª°à«}  
+_textdescrIdentifier_ [l=gu] {àªµàªŸàªàªàªš àªžàªŸàª®àªà«àª°à« àªàªàª¡à«àªšà«àªà«àª«àªŸàª¯àª° àª§à«àªµàªŸàª°àªŸ àª¬à«àª°àªŸàªàª àªàª°à«}  
+_textdescrSource_ [l=gu] {àª®à«àª³ àª«àªŸàªàª²àªšàªŸàª® àª§à«àªµàªŸàª°àªŸ àª¬à«àª°àªŸàªàª àªàª°à«}  
+_textdescrTo_ [l=gu] {àª¥à« àª«àª¿àª²à«àª¡ àª§à«àªµàªŸàª°àªŸ àª¬à«àª°àªŸàªàª àªàª°à«}  
+_textdescrFrom_ [l=gu] {àª®àªŸàªàª¥à« àª«àª¿àª²à«àª¡ àª§à«àªµàªŸàª°àªŸ àª¬à«àª°àªŸàªàª àªàª°à«}  
+_textdescrCollage_ [l=gu] {àªàª®à«àª àªàª³àªŸ àª§à«àªµàªŸàª°àªŸ àª¬à«àª°àªŸàªàª}  
+_textdescrAcronym_ [l=gu] {àªà«àªàªàªŸàªà«àª·àª°à« àª¬à«àª°àªŸàªàª àªàª°à«}  
+_textdescrPhrase_ [l=gu] {àª¶àª¬à«àªŠàªžàª®à«àª¹à« àª¬à«àª°àªŸàªàª àªàª°à«}  
+_textdescrHowto_ [l=gu] {àªà«àªµà« àª°à«àª€à« àªµàª°à«àªà«àªà«àª€ àªàª°àªµà«àª àª€à« àª¬à«àª°àªŸàªàª àªàª°à«}  
+_textdescrBrowse_ [l=gu] {àªªà«àª°àª²à«àªà« àª¬à«àª°àªŸàªàª àªàª°à«}  
+_texticontext_ [l=gu] {àªªà«àª°àª²à«àª àªà«àª}  
+_texticonclosedbook_ [l=gu] {àª àªªà«àª°àª²à«àª àªà«àª²à« àª
+àªšà« àªµàª¿àª·àª¯àªµàªžà«àª€à«àª àªà«àª}  
+_texticonnext_ [l=gu] {àªªàªà«àªšàªŸ àªµàª¿àª­àªŸàª àª€àª°àª«}  
+_texticonprev_ [l=gu] {àªàªàª³àªšàªŸ àªµàª¿àª­àªŸàª àª€àª°àª«}  
+
+_texticonworld_ [l=gu] {àªµà«àª¬ àª¡à«àªà«àª¯à«àª®à«àªšà«àª àªà«àª}  
+
+_texticonmidi_ [l=gu] {MIDI àªªà«àª°àª²à«àª àªà«àª}  
+_texticonmsword_ [l=gu] {àª®àªŸàªàªà«àª°à«àªžà«àª«à«àª àªµàª°à«àª¡ àªªà«àª°àª²à«àª àªà«àª}  
+_texticonmp3_ [l=gu] {MP3 àªªà«àª°àª²à«àª àªà«àª}  
+_texticonpdf_ [l=gu] {PDF àªªà«àª°àª²à«àª àªà«àª}  
+_texticonps_ [l=gu] {àªªà«àªžà«àªà«àª°àªžà«àªàª¿àªàª° àªªà«àª°àª²à«àª àªà«àª}  
+_texticonppt_ [l=gu] {àªªàªŸàªµàª°àªªà«àªàªšà«àª àªªà«àª°àª²à«àª àªà«àª}  
+_texticonrtf_ [l=gu] {RTF àªªà«àª°àª²à«àª àªà«àª}  
+_texticonxls_ [l=gu] {àª®àªŸàªàªà«àª°à«àªžà«àª«àª àªàªàªžà«àª² àªªà«àª°àª²à«àª àªà«àª}  
+
+_page_ [l=gu] {àªªàªŸàªšà«àª}  
+_pages_ [l=gu] {àªªàªŸàªšàªŸ}  
+_of_ [l=gu] {àªšà«àª}  
+_vol_ [l=gu] {àªàª¥à«àª¥à«}  
+_num_ [l=gu] {àªšàªàª¬àª°}  
+
+_textmonth00_ [l=gu] {}
+_textmonth01_ [l=gu] {àªàªŸàªšà«àª¯à«àªàª°à«}  
+_textmonth02_ [l=gu] {àª«à«àª¬à«àª°à«àªàª°à«}  
+_textmonth03_ [l=gu] {àª®àªŸàª°à«àª}  
+_textmonth04_ [l=gu] {àªàªªà«àª°àª¿àª²}  
+_textmonth05_ [l=gu] {àª®à«}  
+_textmonth06_ [l=gu] {àªà«àªš}  
+_textmonth07_ [l=gu] {àªà«àª²àªŸàª}  
+_textmonth08_ [l=gu] {àªàªàª·à«àª}  
+_textmonth09_ [l=gu] {àªžàªªà«àªà«àª®à«àª¬àª°}  
+_textmonth10_ [l=gu] {àªàªà«àªà«àª¬àª°}  
+_textmonth11_ [l=gu] {àªšàªµà«àªàª¬àª°}  
+_textmonth12_ [l=gu] {àª¡àª¿àªžà«àª®à«àª¬àª°}  
+
+_texttext_ [l=gu] {àªà«àªàªžà«àª}  
+_labeltext_ [l=gu] {_texttext_}  
+_textdocument_ [l=gu] {àªªà«àª°àª²à«àªà«}  
+_textsection_ [l=gu] {àªµàª¿àª­àªŸàª}  
+_textparagraph_ [l=gu] {àª«àªàª°à«}  
+_textchapter_ [l=gu] {àªªà«àª°àªàª°àª£}  
+_textbook_ [l=gu] {àªªà«àªžà«àª€àª}  
+
+_magazines_ [l=gu] {àªžàªŸàª®àªŸàª¯àª¿àªà«}  
+
+_nzdlpagefooter_ [l=gu] {<div class="divbar">&nbsp;</div><p><a href="http://www.nzdl.org">àªšà«àª¯à«àªàª¿àª²à«àªšà«àª¡ àª¡àª¿àªàª¿àªàª² àª²àªŸàª¯àª¬à«àª°à«àª°à« àªªà«àª°à«àªà«àªà«àª</a><br><a href="http://www.cs.waikato.ac.nz"> àª¡àª¿àªªàªŸàª°à«àªàª®à«àªšà«àª àªàª« àªà«àª®à«àªªà«àª¯à«àªàª° àªžàªŸàª¯àªšà«àªž</a>,<a href="http://www.waikato.ac.nz"> àª¯à«àªšàª¿àªµàª°à«àªžàª¿àªà« àªàª« àªµà«àªà«àªà«</a>, àªšà«àª¯à«àªàª¿àª²à«àªšà«àª¡}  
+
+_linktextHOME_ [l=gu] {àªàª°}  
+_linktextHELP_ [l=gu] {àª®àªŠàªŠ}  
+_linktextPREFERENCES_ [l=gu] {àªªàªžàªàªŠàªà«àª}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=gu] {àªà«àª°à«àªšàªžà«àªà«àªš àª¡à«àªà«àªàª² àª²àªŸàª¯àª¬à«àª°à«àª°à«}  
+
+_textnocollections_ [l=gu] {àªªà«àª°àª®àªŸàª£àª­à«àª€ àªà«àª àªžàªàªà«àª°àª¹à« (àªŠàªŸ.àª€. àª¬àª¿àª²à«àª àª
+àªšà« àªªàª¬à«àª²àª¿àª) àªàªªàª²àª¬à«àª§ àªšàª¥à«}  
+
+_textadmin_ [l=gu] {àªµàª¹àª¿àªµàªà« àªªàªŸàªšà«àª}  
+_textabgs_ [l=gu] {àªà«àª°à«àªšàªžà«àªà«àªš àªµàª¿àª¶à«}  
+_textgsdocs_ [l=gu] {àªà«àª°à«àªšàªžà«àªà«àªš àªªà«àª°àª²à«àªà«àªàª°àª£}  
+
+_textdescradmin_ [l=gu] {àªšàªµàªŸ àªàªªàª­à«àªàª€àªŸ àªàª®à«àª°àªµàªŸ, àªžàª¿àªžà«àªàª®àª®àªŸàª àªžàªàªà«àª°àª¹àªšà« àªžàªàªà«àª·àª¿àªªà«àª€ àªàª°àªµàªŸàªšà« àªà«àªàªµàªŸàª àªàª°à« àªà«, àªà«àª°à«àªšàªžà«àªà«àªš àªàªšà«àªžà«àªà«àª²à«àª¶àªš àª®àªŸàªà« àªà«àªà«àªšà«àªàª² àª®àªŸàª¹àª¿àª€à« àªàªªà« àªà«.}  
+
+_textdescrgogreenstone_ [l=gu] {àªà«àª°à«àªšàªžà«àªà«àªš àªžà«àª«à«àªàªµà«àª° àª
+àªšà« àªšà«àª¯à«àªàª¿àª²à«àªšà«àª¡ àª¡à«àªà«àªàª² àª²àªŸàª¯àª¬à«àª°à«àª°à« àªªà«àª°à«àªà«àªà«àªàªšà« àªà«àª¯àªŸàªàª¥à« àªàª€à«àªªàª€à«àª€àª¿ àª¥àª àª¹à«àª¯ àª€à«àªšàªŸ àªµàª¿àª¶à« àªàªŸàª£àªàªŸàª°à« àªàªªà« àªà«}  
+
+_textdescrgodocs_ [l=gu] {àªà«àª°à«àªšàªžà«àªà«àªš àª®àªŸàª°à«àªàªŠàª°à«àª¶àª¿àªàªŸàª}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=gu] {àªà«àª°àªàª¥àªªàªŸàª² àªàªšà«àªàª°àª«à«àª¶}  
+_textdescrgli_ [l=gu] {àªšàªµà« àªžàªàªà«àª°àª¹ àªšàª¿àª°à«àª®àªŸàª£ àªàª°àªµàªŸ, àªžà«àª§àªŸàª°à« àªàª°àªµàªŸ àª
+àª¥àªµàªŸ àªªà«àª°àªµàª°à«àª€àª®àªŸàªš àªžàªàªà«àª°àª¹ àª®àªŸàª àªàª®à«àª°à« àªàª°àªµàªŸ, àª
+àª¥àªµàªŸ àª€à«àªšà« àª°àªŠ àªàª°àªµàªŸ àª€àª®àªšà« àª®àªŠàªŠ àªàª°à« àªà«}  
+
+package collector
+
+_textcollector_ [l=gu] {àªžàªàªà«àª°àª¹àªàªŸàª°}  
+_textdescrcollector_ [l=gu] {àª àªà«àª°àªàª¥àªªàªŸàª² àªàªšà«àªàª°àª«à«àª¶ àª
+àªàªŸàªàªšà« àª€àªŸàª°à«àª àª¬àª€àªŸàªµà« àªà«, àª
+àªšà« àª®à«àªàªŸ àª­àªŸàªà« àªµà«àª¯àªµàª¹àªŸàª°à«àª àª¹à«àª€à« àª®àªŸàªà« àª€à«àªšàªŸ àª¬àªŠàª²à« àªà«àª°àªàª¥àªªàªŸàª² àªàªšà«àªàª°àª«à«àª¶àªšà« àªàªªàª¯à«àª àªàª°àªµà« àªà«àªàª.}  
+
+package depositor
+
+_textdepositor_ [l=gu] {àª¡àª¿àªªà«àªàª¿àªàª°}  
+_textdescrdepositor_ [l=gu] {àªªà«àª°àªµàª°à«àª€àª®àªŸàªš àªžàªàªà«àª°àª¹àª®àªŸàª àªàª®à«àª°àªµàªŸ àª®àªŸàªà« àª®àªŠàªŠ àªàª°à« àªà«}  
+
+package gti
+
+_textgti_ [l=gu] {àªà«àª°à«àªšàªžà«àªà«àªš àªà«àª°à«àªšà«àªžà«àª²à«àªàª° àªàªšà«àªàª°àª«à«àªž}  
+_textdescrtranslator_ [l=gu] {àªà«àª°à«àªšàªžà«àªà«àªš àªàªšà«àªàª°àª«à«àªž àªšàªŸ àª¬àª¹à«àª­àªŸàª·à« àªµàª°à«àªàªš àª
+àªª àªà« àª¡à«àª àª°àªŸàªàªµàªŸ àª®àªŸàªà« àª®àªŠàªŠ àªàª°à« àªà«}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=gu] {àª àªžàªàªà«àª°àª¹ àªµàª¿àª¶à«}  
+
+_textsubcols1_ [l=gu] {<p> àª àªžàªàªªà«àª°à«àª£ àªžàªàªà«àª°àª¹_1_ àªªà«àªàªŸ àªžàªàªà«àª°àª¹àªšà«àª àª¬àªšà«àª²à«àª àªà«. àªà« àª¹àªŸàª²àª®àªŸàª àªàªªàª²àª¬à«àª§ àªà« àª€à« <blockquote> }  
+
+_textsubcols2_ [l=gu] {àªªàªžàªàªŠàªà« àªªàªŸàªšàªŸ àªªàª° àª¹àªŸàª²àª®àªŸàª àªàªª àªàª¯àªŸ àªªà«àªàªŸ àªžàªàªà«àª°àª¹àªšà« àªàªªàª¯à«àª àªàª°à« àª°àª¹à«àª¯àªŸ àªà« àª€à« àªàªª àªàªàªŸàªžà« àª€àª¥àªŸ àª€à«àª®àªŸ àª«à«àª°àª«àªŸàª°  àªàª°à« àª¶àªà« àªà«.}  
+
+_titleabout_ [l=gu] {àªšàªŸ àªµàª¿àª¶à«}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=gu] {àªà«àª°àªàª¥àªŸàª²àª¯àªšà« àª àªµàª¿àª­àªŸàª àª¬àªàª§ àªàª°à«}  
+_texticonclosedbookshelf_ [l=gu] {àªà«àª°àªàª¥àªŸàª²àª¯àªšà« àª àªµàª¿àª­àªŸàª àªà«àª²à« àª
+àªšà« àªµàª¿àª·àª¯àªµàªžà«àª€à« àªà«àª}  
+_texticonopenbook_ [l=gu] {àª àªªà«àªžà«àª€àª àª¬àªàª§ àªàª°à«}  
+_texticonclosedfolder_ [l=gu] {àª àª«à«àª²à«àª¡àª° àªà«àª²à« àª
+àªšà« àªµàª¿àª·àª¯àªµàªžà«àª€à« àªà«àª}  
+_texticonclosedfolder2_ [l=gu] {àªªà«àªàªŸ-àªµàª¿àª­àªŸàª àªà«àª²à«:}  
+_texticonopenfolder_ [l=gu] {àª àª«à«àª²à«àª¡àª° àª¬àªàª§ àªàª°à«}  
+_texticonopenfolder2_ [l=gu] {àªªà«àªàªŸ àªµàª¿àª­àªŸàª àª¬àªàª§ àªàª°à«}  
+_texticonsmalltext_ [l=gu] {àªà«àªàªžà«àªàªšà« àª àªµàª¿àª­àªŸàª àªà«àª}  
+_texticonsmalltext2_ [l=gu] {àªà«àªàªžà«àª àªà«àª:}  
+_texticonpointer_ [l=gu] {àªµàª°à«àª€àª®àªŸàªš àªµàª¿àª­àªŸàª àª¬àªàª§ àªàª°à«}  
+_texticondetach_ [l=gu] {àª àªªàªŸàªšà«àª àªšàªµà« àªµàª¿àªšà«àª¡à«àª®àªŸ àªà«àª²à«}  
+_texticonhighlight_ [l=gu] {àª¶à«àª§ àªªàªŠà«àªšà« àª¹àªŸàªàª²àªŸàªàª àªàª°à«}  
+_texticonnohighlight_ [l=gu] {àª¶à«àª§ àªªàªŠà«àªšà« àª¹àªŸàªàª²àªŸàªàª àªš àªàª°à«}  
+_texticoncontracttoc_ [l=gu] {àªµàª¿àª·àª¯àªµàªžà«àª€à« àª¯àªŸàªŠà« àªšà« àªšàªŸàª¶ àªàª°à«}  
+_texticonexpandtoc_ [l=gu] {àªµàª¿àª·àª¯àªµàªžà«àª€à« àª¯àªŸàªŠà«àªšà« àªµàª¿àªžà«àª€àªŸàª° àªàª°à«}  
+_texticonexpandtext_ [l=gu] {àª¬àª§à« àª àªà«àªàªžà«àª àªªà«àª°àªŠàª°à«àª¶àª¿àª€ àªàª°à«}  
+_texticoncontracttext_ [l=gu] {àª€àªŸàªà«àª€àª°àª®àªŸàª àªªàªžàªàªŠ àªàª°à«àª² àªµàª¿àª­àªŸàª àª®àªŸàªà« àª àªà«àªàªžà«àª àªªà«àª°àªŠàª°à«àª¶àª¿àª€ àªàª°à«}  
+_texticonwarning_ [l=gu] {<b>àªà«àª€àªµàª£à«:<b>}  
+_texticoncont_ [l=gu] {àª
+àªµàª¿àª°àª€ ?}  
+
+_textltwarning_ [l=gu] {<div class="buttons">_imagecont_</div>_iconwarning_àª
+àª¹àª¿ àªà«àªàªžà«àª àªµàª¿àªžà«àª€àªŸàª°à«àªšà« àª€àª®àªŸàª°àªŸ àª¬à«àª°àªŸàªàªàª° àª®àªŸàªà« àªªà«àª°àªŠàª°à«àª¶àª¿àª€ àªàª°àªµàªŸ àªµàª¿àª¶àªŸàª³ àª®àªŸàª€à«àª°àªŸàª®àªŸàª àª¡à«àªàªŸàªšà«àª àªšàª¿àª°à«àª®àªŸàª£ àª¥àª¶à«}  
+
+_textgoto_ [l=gu] {àªªàªŸàªšàªŸ àªªàª° àªàªŸàªµ}  
+_textintro_ [l=gu] {<i>(àªªà«àª°àªžà«àª€àªŸàªµàª¿àª àªà«àªàªžà«àª)</i>}  
+
+_textCONTINUE_ [l=gu] {àª
+àªµàª¿àª°àª€?}  
+
+_textEXPANDTEXT_ [l=gu] {àªà«àªà«àªžà«àªàªšà« àªµàª¿àªžà«àª€àªŸàª° àªàª°à«}  
+
+_textCONTRACTCONTENTS_ [l=gu] {àªžàªàªà«àª·àª¿àªªà«àª€ àªµàª¿àª·àª¯àªµàªžà«àª€à«}  
+
+_textDETACH_ [l=gu] {àª
+àª²àª}  
+
+_textEXPANDCONTENTS_ [l=gu] {àªµàª¿àª·àª¯àªµàªžà«àª€à«àªšà« àªµàª¿àªžà«àª€àªŸàª° àªàª°à«}  
+
+_textCONTRACT_ [l=gu] {àªžàªàªà«àª·àª¿àªªà«àª€ àªà«àªà«àªžà«àª}  
+
+_textHIGHLIGHT_ [l=gu] {àª¹àªŸàªàª²àªŸàªàª àªàª°à« àªšà«}  
+
+_textNOHIGHLIGHT_ [l=gu] {àª¹àªŸàªàª²àªŸàªàª àªš àªàª°à« àªšà«}  
+
+_textPRINT_ [l=gu] {àªªà«àª°àª¿àªšà«àª}  
+
+_textnextsearchresult_ [l=gu] {àª€àª°àª€ àªªàªà«àªšà«àª àª¶à«àª§ àªªàª°àª¿àª£àªŸàª®}  
+_textprevsearchresult_ [l=gu] {àªªàª¹à«àª²àªŸàªšà«àª àª¶à«àª§ àªªàª°àª¿àª£àªŸàª®}  
+
+# macros for printing page
+_textreturnoriginal_ [l=gu] {àª®à«àª³ àªªàªŸàªšàªŸ àªªàª° àªªàªŸàªàªŸ àªàªŸàªµ}  
+_textprintpage_ [l=gu] {àª àªªàªŸàªšà« àªªà«àª°àª¿àªšà«àª àªàª°à«}  
+_textshowcontents_ [l=gu] {àªµàª¿àª·àª¯àªµàªžà«àª€à« àª¯àªŸàªŠà« àª¬àª€àªŸàªµà«}  
+_texthidecontents_ [l=gu] {àªµàª¿àª·àª¯àªµàªžà«àª€à« àª¯àªŸàªŠà«  àªà«àªªà«àª€ àª°àªŸàªà«}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=gu] {_If_(_thislast_,results _thisfirst_ - _thislast_ àªà«àªµà«àª°à« àª®àªŸàªà«: _cgiargq_,àªà«àªµà«àª°à« àª®àªŸàªà« àª®à«àª àª¥àª€à« àªšàª¥à«.: _cgiargq_)}  
+_textnoquerytitle_ [l=gu] {àªªàªŸàªšà« àª¶à«àª§à«}  
+
+_textsome_ [l=gu] {àª
+àª®à«àª}  
+_textall_ [l=gu] {àª€àª®àªŸàª®}  
+_textboolean_ [l=gu] {àª¬à«àª²àª¿àª
+àªš}  
+_textranked_ [l=gu] {àª°à«àªšà«àªàª¡}  
+_textnatural_ [l=gu] {àªà«àªŠàª°àª€à«}  
+_textsortbyrank_ [l=gu] {àªžà«àªžàªàªàª€ àª°à«àªšà«àª}  
+_texticonsearchhistorybar_ [l=gu] {àª¶à«àª§ àªàª€àª¿àª¹àªŸàªž}  
+
+_textifeellucky_ [l=gu] {àª¹à«àª àª­àªŸàªà«àª¯àª¶àªŸàª³à« àªà« àª€à«àªµà« àª
+àªšà«àª­àªµà« àª°àª¹à«àª¯à« àªà«!}  
+
+#alt text for query buttons
+_textusequery_ [l=gu] {àª àªà«àªµà«àª°à«àªšà« àªàªªàª¯à«àª àªàª°à«}  
+_textfreqmsg1_ [l=gu] {àª¶àª¬à«àªŠ àªàª£àª€àª°à«}  
+_textpostprocess_ [l=gu] {_If_(_quotedquery_,<br><i>àªªà«àª°àªàª¿àª¯àªŸ àª¥àª¯àªŸ àªªàªà« àªšà« àª¶à«àª§ àªàª°àªµà« _quotedquery_</i> )}  
+_textinvalidquery_ [l=gu] {àª
+àª¯à«àªà«àª¯ àªà«àªµà«àª°à« àªµàªŸàªà«àª¯àª°àªàªšàªŸ (àªžàª¿àªšà«àªà«
+àªàªž)}  
+_textstopwordsmsg_ [l=gu] {àªšà«àªà«àªšàªŸ àª¶àª¬à«àªŠà« àªà«àª¬àª àªžàªŸàª®àªŸàªšà«àª¯ àªà« àª
+àªšà« àª
+àªµàªàª£à«àª²àªŸ àª¹àª€àªŸ:}  
+_textlucenetoomanyclauses_ [l=gu] {àª€àª®àªŸàª°à« àªà«àªµà«àª°à«àª®àªŸàª àªàª£àªŸ àª¬àª§àªŸ àª¶à«àª§ àªªàªŠà« àªžàª®àªŸàªµàª¿àª·à«àª àª¹àª€àªŸ; àªàª àªµàª§àªŸàª°à« àªµàª¿àª¶àª¿àª·à«àª àªà«àªµà«àª°à«àª¥à« àªªà«àª°àª¯àª€à«àªš àªàª°à«.}  
+
+_textmorethan_ [l=gu] {àª¥à« àªµàª§àªŸàª°à«}  
+_textapprox_ [l=gu] {àªšàªŸ àªµàª¿àª¶à«}  
+_textnodocs_ [l=gu] {àªà«àªµà«àª°à« àªªà«àª°àª®àªŸàª£à« àªà«àª àªªà«àª°àª²à«àªà« àª®à«àª àª¥àª€àªŸ àªšàª¥à«.}  
+_text1doc_ [l=gu] {àªà«àªµà«àª°à« àªªà«àª°àª®àªŸàª£à« 1 àªªà«àª°àª²à«àª àª®à«àª àª¥àªŸàª¯ àªà«.}  
+_textlotsdocs_ [l=gu] {àªà«àªµà«àª°à« àªªà«àª°àª®àªŸàª£à« àª®àª³àª€àªŸ àªàªµàª€àªŸ àªªà«àª°àª²à«àªà«.}  
+_textmatches_ [l=gu] {àª
+àªšà«àª°à«àªª}  
+_textbeginsearch_ [l=gu] {àª¶à«àª§ àª¶àª°à« àªàª°à«}  
+_textrunquery_ [l=gu] {àªà«àªµà«àª°à« àª¶àª°à« àªàª°à«}  
+_textclearform_ [l=gu] {àª«à«àª°à«àª® àª­à«àªàªžà«}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=gu] {àª¶àª¬à«àªŠà«
+
+}  
+_textinfield_ [l=gu] {...àª«àª¿àª²à«àª¡àªšà« àª
+àªàªŠàª°}  
+_textfoldstem_ [l=gu] {(àªµàªŸàª³à«, àªªà«àª°àª€àª¿àª¬àªàª§)}  
+
+_textadvquery_ [l=gu] {àª
+àª¥àªµàªŸ àªà«àªµà«àª°à« àªžà«àª§à« àªžà«àª§à« àªàªšà«àªàª° àªàª°à«}  
+_textallfields_ [l=gu] {àª€àª®àªŸàª® àª«àª¿àª²à«àª¡}  
+_texttextonly_ [l=gu] {àª®àªŸàª€à«àª° àªà«àªà«àªžà«àª}  
+_textand_ [l=gu] {àª
+àªšà«}  
+_textor_ [l=gu] {àª
+àª¥àªµàªŸ}  
+_textandnot_ [l=gu] {àª
+àªšà« àªšàª¹àª¿}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+# the space after "level" (before the right bracket) is required, otherwise no space between "Search" and "in"
+
+_textsimplesearch_ [l=gu] {Search in _indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ sorting results by _sfselection_) for _querytypeselection_ of the words}  
+
+_textadvancedsearch_ [l=gu] {Search in_indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level)_If_(_nselection_, in _nselection_ language) using _querytypeselection_ query}  
+
+_textadvancedmgppsearch_ [l=gu] {Search in_indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level)_If_(_nselection_, in _nselection_ language), and display results in _formquerytypeadvancedselection_ order, for}  
+
+_textadvancedlucenesearch_ [l=gu] {Search in_indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ sorting results by _sfselection_\,) for }  
+
+# the space after "Search" is required, otherwise no space between "Search" and "in"
+
+_textformsimplesearch_ [l=gu] {Search _If_(_jselection_, in _jselection_)_If_(_gformselection_, at _gformselection_ level)_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\, sorting results by _sfselection_\,) for _formquerytypesimpleselection_ of}  
+
+_textformadvancedsearchmgpp_ [l=gu] {Search _If_(_jselection_, in _jselection_)_If_(_gformselection_, at _gformselection_ level)_If_(_nselection_, in _nselection_ language),  àª®àªŸàªà«, àª
+àªšà« _formquerytypeadvancedselection_ àªà«àª°àª® àª®àªŸ àªªàª°àª¿àª£àªŸàª® àª¬àª€àªŸàªµà« àªà«}  
+
+_textformadvancedsearchlucene_ [l=gu] {Search _If_(_jselection_, in _jselection_)_If_(_gformselection_, at _gformselection_ level)_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\, sorting results by _sfselection_\,) for}  
+
+_textnojsformwarning_ [l=gu] {àªà«àª€àªµàª£à«àª àªàªŸàªµàªŸàªžà«àªà«àª°àª¿àªªà«àª àª€àª®àªŸàª°àªŸ àªµà«àª¬ àª¬à«àª°àªŸàªàªàª°àª®àªŸàª àªžàªà«àª·àª® àªà«.<br>àª«à«àª°à«àª® àª¶à«àª§àªšà« àªàªªàª¯à«àª àªàª°àªµàªŸ, àª€à«àªšà« àªžàªà«àª·àª® àª¬àªšàªŸàªµà«.}  
+_textdatesearch_ [l=gu] {àªà«àª àª€àªŸàª°à«àª àª®àª°à«àª¯àªŸàªŠàªŸàª®àªŸàª àªàªµàª€àªŸ àªªà«àª°àª²à«àªà«àªšà«, àª
+àª¥àªµàªŸ àªà«àªà«àªàªž àª€àªŸàª°à«àª àªšà« àª²àªàª€àªŸ àªªà«àª°àª²à«àªà«àªšà« àª àªžàªàªà«àª°àª¹ àª§à«àªµàªŸàª°àªŸ àª¶à«àª§ àªàª°à« àª¶àªàªŸàª¯ àªà«. àª¶à«àª§ àª®àªŸàªà« àª  àªµà«àªàª²à«àªªàª¿àª àª²àªŸàªà«àª·àª£àª¿àªàª€àªŸ àªà«.}  
+_textstartdate_ [l=gu] {àª¶àª°à«àªàª€àªšà« (àª
+àª¥àªµàªŸ, àª«àªà«àª€) àª€àªŸàª°à«àªàª }  
+_textenddate_ [l=gu] {àª
+àªàª€àª¿àª® àª€àªŸàª°à«àª}  
+_textbc_ [l=gu] {àª¬à«.àªžà«.àª.}  
+_textad_ [l=gu] {C.E.}  
+_textexplaineras_ [l=gu] {C.E àª
+àªšà« B.C.E àª A.D. àª
+àªšà« B.C.àªšàªŸ àª
+àªšà«àªà«àª°àª®à« àªàªªàªŸàª¯à« àªà«. àª àªªàªŠà«àªšà« àªžàªàªžà«àªà«àª€àª¿àªšàªŸ àª­à«àªŠàª­àªŸàªµ àª€àª°à«àªà«àªšà« àªàª£àªšàªŸ àª¥àªŸàª¯ àªà«, àª
+àªšà« àª€à«àªšà« "àªà«àª®àªš àªàª°àªŸ" àª
+àªšà« "àª.àªž. àªªà«àª°à«àªµà«" àª€àª°à«àªà« àªàª³àªàªµàªŸàª®àªŸ àªàªµà« àªà«.}  
+
+_textstemon_ [l=gu] {àª¶àª¬à«àªŠàªšà« àª
+àªàª€à« àªàªµàª€àªŸ àª
+àªà«àª·àª°à« àªšà« àª
+àªµàªàª£à«àªšà«}  
+
+_textsearchhistory_ [l=gu] {àª¶à«àª§ àªàª€àª¿àª¹àªŸàªž}  
+
+#text macros for search history
+_textnohistory_ [l=gu] {àª¶à«àª§ àªàª€àª¿àª¹àªŸàªžàª®àªŸàª àªà«àª àªàªšà«àªà«àª°à« àªšàª¥à«}  
+_texthresult_ [l=gu] {àªªàª°àª¿àª£àªŸàª®}  
+_texthresults_ [l=gu] {àªªàª°àª¿àª£àªŸàª®à«}  
+_texthallwords_ [l=gu] {àª€àª®àªŸàª® àª¶àª¬à«àªŠà«}  
+_texthsomewords_ [l=gu] {àª
+àª®à«àª àª¶àª¬à«àªŠà«}  
+_texthboolean_ [l=gu] {àª¬à«àª²àª¿àª
+àªš}  
+_texthranked_ [l=gu] {àª°à«àªšà«àªàª¡}  
+_texthcaseon_ [l=gu] {àªà«àªž àª®à«àª àª¥àªµà« àªà«àªàª}  
+_texthcaseoff_ [l=gu] {àªà«àªžàª«à«àª²à«àª¡à«àª¡}  
+_texthstemon_ [l=gu] {àªªà«àª°àª€àª¿àª¬àªàª§àª¿àª€}  
+_texthstemoff_ [l=gu] {àª
+àªªà«àª°àª€àª¿àª¬àªàª§àª¿àª€}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=gu] {àªªàªžàªàªŠàªà«àª àªšà«àªà« àªªà«àª°àª®àªŸàª£à« àªà«àª àªµàªµàªŸàª®àªŸàª àªàªµà« àªà«. àª€àª®àªŸàª°àªŸ àª¬à«àª°àªŸàªàªàª°àªšà«àª "àªªàªŸàªàª³" àª¬àªàªšàªšà« àªàªªàª¯à«àª àªš àªàª°à«. àªšàª¹àª¿àª€àª° àª€à« àª€à«àªšà« àª
+àªžà«àª€-àªµà«àª¯àªžà«àª€ àªàª°àª¶à« àª€à«àªšàªŸ àª¬àªŠàª²à«, àªàªà«àªžà«àªž àªªàªà« àªªàª°àªšàªŸ àªà«àªàªªàª£ àª¬àªàªšà« àªŠàª¬àªŸàªµà«. }  
+_textsetprefs_ [l=gu] {àªªàªžàªàªŠàªà«àª àªšàªà«àªà« àªàª°à«}  
+_textsearchprefs_ [l=gu] {àª¶à«àª§ àªªàªžàªàªŠàªà«àª}  
+_textcollectionprefs_ [l=gu] {àªžàªàªà«àª°àª¹ àªªàªžàªàªŠàªà«àª}  
+_textpresentationprefs_ [l=gu] {àªªà«àª°àªžà«àª€à«àª€àª¿ àªªàªžàªàªŠàªà«àª}  
+_textpreferences_ [l=gu] {àªªàªžàªàªŠàªà«àª}  
+_textcasediffs_ [l=gu] {àªà«àªž àª­àª¿àªšà«àªšàª€àªŸ:}  
+_textignorecase_ [l=gu] {àªà«àªž àª­àª¿àªšà«àªšàª€àªŸàªšà« àª
+àªµàªàª£à«}  
+_textmatchcase_ [l=gu] {àª
+àªªàª°àªà«àª¶/àª²à«àª
+àª°àªà«àª¶ àª
+àªà«àª·àª°à« àª®à«àª àª¥àªµàªŸ àª àªà«àªàª}  
+_textwordends_ [l=gu] {àª¶àª¬à«àªŠàªšà« àª
+àªàª€à« àªàªµàª€àªŸ àª
+àªà«àª·àª°à«:}  
+_textstem_ [l=gu] {àª¶àª¬à«àªŠàªšà« àª
+àªàª€àªšàªŸ àª
+àªà«àª·àª°à« àª
+àªµàªàª£à«}  
+_textnostem_ [l=gu] {àªàªà« àª¶àª¬à«àªŠ àª®à«àª àª¥àªµà« àªà«àªàª}  
+_textaccentdiffs_ [l=gu] {àªàªà«àªàªŸàª°àª£ àª­àª¿àªšà«àªšàª€àªŸ:}  
+_textignoreaccents_ [l=gu] {àªàªà«àªàªŸàª°àª£àªšà« àª
+àªµàªàª£à«}  
+_textmatchaccents_ [l=gu] {àªàªà«àªàªŸàª°àª£ àª®à«àª àª¥àªµà«àª àªà«àªàª}  
+
+_textprefop_ [l=gu] {àªà«àª² _maxdocoption_ àªªàª°àª¿àª£àªŸàª®à« àª®àªŸàªàª¥à« _hitsperpageoption_ àªªàª°àª¿àª£àªŸàª®à« àªªàªŸàªšàªŸ àªŠàª¿àª  àªŠàª°à«àª¶àªŸàªµà«. }  
+_textextlink_ [l=gu] {àª¬àª¹àªŸàª°àªšàªŸ àªµà«àª¬ àªªà«àªàªšà« àªàªàªžà«àªž:}  
+_textintlink_ [l=gu] {àª®àªŸàªàª¥à« àª®à«àª³ àªªà«àª°àª²à«àªà«àªšà« àªªà«àªšàª àªªà«àª°àªŸàªªà«àª€àª¿:}  
+_textlanguage_ [l=gu] {àªàªšà«àªàª°àª«à«àª¶ àª­àªŸàª·àªŸ:}  
+_textencoding_ [l=gu] {àªàªšàªà«àª¡à«àªàª:}  
+_textformat_ [l=gu] {àªàªšà«àªàª°àª«à«àª¶ àªžà«àªµàª°à«àªª:}  
+_textall_ [l=gu] {àª€àª®àªŸàª®}  
+_textquerymode_ [l=gu] {àªà«àªµà«àª°à« àª°à«àª€:}  
+_textsimplemode_ [l=gu] {àªžàª¿àª®à«àªªàª² àªà«àªµà«àª°à« àª®à«àª¡}  
+_textadvancedmode_ [l=gu] {àªàª¡àªµàªŸàªšà«àªž àªà«àªµà«àª°à« àª°à«àª€ (!, &, |, àª
+àªšà« àªà«àª·àªšà« àªàªªàª¯à«àª àªàª°à«àªšà« àª¬à«àª²àª¿àª
+àªš àª¶à«àª§àªšà« àªžà«àªµàª¿àª§àªŸ àªªà«àª°à« àªªàªŸàª¡à« àªà«)}  
+_textlinkinterm_ [l=gu] {àªàªàª€àª° àª®àª§à«àª¯àªžà«àª¥à« àªªà«àªàªšàªŸ àª®àªŸàª§à«àª¯àª® àª§à«àªµàªŸàª°àªŸ}  
+_textlinkdirect_ [l=gu] {àªžà«àª§àªŸ àª€à«àª¯àªŸàª àªàªŸàªµ}  
+_textdigitlib_ [l=gu] {àª¡àª¿àªà«àªàª² àª²àªŸàª¯àª¬à«àª°à«àª°à«}  
+_textweb_ [l=gu] {àªµà«àª¬}  
+_textgraphical_ [l=gu] {àªà«àª°àªŸàª«àª¿àªàª²}  
+_texttextual_ [l=gu] {àª¶àªŸàª¬à«àªŠàª¿àª}  
+_textcollectionoption_ [l=gu] {<p>àªªà«àªàªŸ àªžàªàªà«àª°àª¹àªšà« àªžàª®àªŸàªµà«àª¶ àªàª°àªµàªŸ àª®àªŸàªà«: <br>}  
+
+_textsearchtype_ [l=gu] {àªà«àªµà«àª°à« àª¶à«àª²à«:}  
+_textformsearchtype_ [l=gu] {_formnumfieldoption_ àª«àª¿àª²à«àª¡ àª§à«àªµàªŸàª°àªŸ àªªàª°àª¿àªªà«àª°à«àª£}  
+_textplainsearchtype_ [l=gu] {àªžàªŸàª®àªŸàªšà«àª¯ àª°à«àª€à« _boxsizeoption_ àªà«àªµà«àª°à« àª¬à«àªà«àªžàª¥à« }  
+_textregularbox_ [l=gu] {àªàª àªªàªàªà«àª€àª¿}  
+_textlargebox_ [l=gu] {àª®à«àªà«}  
+
+_textrelateddocdisplay_ [l=gu] {àªàªšà«àªžàªàªàª¿àª àªªà«àª°àª²à«àªà« àªŠàª°à«àª¶àªŸàªµà«}  
+_textsearchhistory_ [l=gu] {àª¶à«àª§ àªàª€àª¿àª¹àªŸàªž:}  
+_textnohistory_ [l=gu] {àªà«àª àª¶à«àª§ àªàª€àª¿àª¹àªŸàªž àªšàª¹àª¿}  
+_texthistorydisplay_ [l=gu] {àª¶à«àª§ àªàª€àª¿àª¹àªŸàªžàªšàªŸ _historynumrecords_  àª°à«àªà«àª°à«àª¡àªž àªªà«àª°àªŠàª°à«àª¶àª¿àª€ àªàª°à«.}  
+_textnohistorydisplay_ [l=gu] {àª¶à«àª§ àªàª€àª¿àª¹àªŸàªž àªŠàª°à«àª¶àªŸàªµà« àªšàª¹àª¿}  
+
+_textbookoption_ [l=gu] {àªªà«àªžà«àª€àª àªàª¿àª€à«àª°àªªàª àª°à«àª€:}  
+_textbookvieweron_ [l=gu] {àªàªŸàª²à«}  
+_textbookvieweroff_ [l=gu] {àª¬àªàª§}  
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=gu] {àª¥à« àªªà«àª°àª²à«àªà« àª
+àª²àª àª€àªŸàª°àªµà«}  
+_textalsoshowing_ [l=gu] {àªªàª£ àª¬àª€àªŸàªµà« àªà«}  
+_textwith_ [l=gu] {àªµàª§à«àª®àªŸàª àªµàª§à« àªžàªŸàª¥à«}  
+_textdocsperpage_ [l=gu] {àªŠàª°à«àª àªªàªŸàªšàªŸ àªŠàª¿àª  àªªà«àª°àª²à«àªà«}  
+
+_textfilterby_ [l=gu] {àªšà« àªžàªŸàª¥à« àªªà«àª°àª²à«àªà« àª®à«àª³àªµà«}  
+_textall_ [l=gu] {àª€àª®àªŸàª®}  
+_textany_ [l=gu] {àªà«àªàªªàª£}  
+_textwords_ [l=gu] {àª¶àª¬à«àªŠà«àªšà«àª}  
+_textleaveblank_ [l=gu] {àª¬àª§àªŸàª àªªà«àª°àª²à«àªà« àª®à«àª³àªµàªµàªŸ àª®àªŸàªà« àª àª¬à«àªàªž àªà«àª°à« àªà«àª¡à«}  
+
+_browsebuttontext_ [l=gu] {"àªªà«àª°àª²à«àªà« àª
+àª²àª àª€àªŸàª°àªµà«"}  
+
+_nodata_ [l=gu] {<i>àª¡à«àªàªŸ àªšàª¥à«</i>}  
+_docs_ [l=gu] {àªªà«àª°àª²à«àªà«}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=gu] {àª®àªŠàªŠ}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=gu] {_2_ àª¬àªàªš àªàª¿àª²àª àªàª°à« _1_  àª§à«àªµàªŸàª°àªŸ àªªà«àª°àª²à«àªà« àª¬à«àª°àªŸàªàª àªàª°à«}  
+
+_textSearchhelp_ [l=gu] {àªà«àªà«àªžà«àªàªšà« àª
+àªàªŠàª°àªšàªŸ àªà«àªà«àªàªž àª¶àª¬à«àªŠà« àª¶à«àª§àªµàªŸ àª®àªŸàªà« _labelSearch_ àª¬àªàªš àªà«àª²àª¿àª àªàª°à«}  
+_textTohelp_ [l=gu] {_labelTo_ àª¬àªàªš àªà«àª²àª¿àª àªàª°à«àªšà« àª¥à« àª«àª¿àª²à«àª¡ àª§à«àªµàªŸàª°àªŸ àªªà«àª°àª²à«àªà« àª¬à«àª°àªŸàªàª àªàª°à«}  
+_textFromhelp_ [l=gu] {_labelFrom_ àª¬àªàªš àªàª¿àª²àª àªàª°à«àªšà« àª®àªŸàª àª¥à« àª«àª¿àª²à«àª¡ àª§à«àªµàªŸàª°àªŸ àªªà«àª°àª²à«àªà« àª¬à«àª°àªŸàªàª àªàª°à«}  
+_textBrowsehelp_ [l=gu] {àªªà«àª°àª²à«àªà« àª¬à«àª°àªŸàªàª àªàª°à«}  
+_textAcronymhelp_ [l=gu] {_labelAcronym_ àª¬àªàªš àªªàª° àªàª¿àª²àª àªàª°à« àªà«àªàªàªŸàªà«àª·àª° àªàªàªšàªŸ àª§à«àªµàªŸàª°àªŸ àªªà«àª°àª²à«àªà« àª¬à«àª°àªŸàªàª àªàª°à«}  
+_textPhrasehelp_ [l=gu] {_labelPhrase_ àª¬àªàªš àªà«àª²àª¿àª àªàª°à«àªšà« àªªà«àª°àª²à«àªà«àª®àªŸàª àªžàª®àªŸàªµàª¿àª·à«àª àª¶àª¬à«àªŠ àªžàª®à«àª¹à«àªšà« àª¬à«àª°àªŸàªàª àªàª°à«. àª phind àª¶àª¬à«àªŠ àªžàª®à«àª¹àªšà« àªàªªàª¯à«àª àªàª°à« àªà«}  
+
+_texthelptopicstitle_ [l=gu] {àªµàª¿àª·àª¯à«}  
+
+_textreadingdocs_ [l=gu] {àªªà«àª°àª²à«àªà«àªšà« àªà«àªµà« àª°à«àª€à« àªµàªŸàªàªàªµàªŸ}  
+
+_texthelpreadingdocs_ [l=gu] {<p>àªªà«àªàªšà« àªà«àªàªšàªŸ àª­àªŸàªà« àª¡àªŸàª¬à« àª¬àªŸàªà« àªà« àª€à« àªªà«àªžà«àª€àª àª
+àª¥àªµàªŸ àªªà«àª°àª²à«àªàªšàªŸ àª¶àª¿àª°à«àª·àª, àª
+àª¥àªµàªŸ àª®à«àª àªàªµàª° àªŠà«àªàªŸàª€à« àª¹à«àªµàªŸàªšà« àªàªŸàª°àª£à« àªà«-àª€à« àªªà«àªžà«àª€àª àª
+àª¥àªµàªŸ àªªà«àª°àª²à«àª àªžà«àª§à« àª€àª®à« àªªà«àª¹àªàªà« àªàª¯àªŸ àªà« àª€à«àªµà«àª àª€àª®à« àªàª¹à« àª¶àªà«. àª
+àª®à«àª àªžàªàªà«àª°àª¹à«àª®àªŸàª àªµàª¿àª·àª¯àªµàªžà«àª€à« àª¯àªŸàªŠà« àªŠà«àªàªŸàª¯ àªà«, àªà«àª¯àªŸàª°à« àª
+àª®à«àª àªžàªàªà«àª°àª¹à«àª®àªŸàª (àªŠàªŸ.àª€. àªà«àª¯àªŸàª àªªà«àª àªàª®à«àª àªµàª¿àªà«àª²à«àªª àªšà« àªàªªàª¯à«àª àªàª°àªµàªŸàª®àªŸàª àªàªµà« àª€à«àª¯àªŸàª) àª®àªŸàª€à«àª° àªªàªŸàªšàªŸ àªšàªàª¬àª° àªŠà«àªàªŸàª¯ àªà«, àª¬à«àªà«àªž àªžàªŸàª¥à« àªà« àªªàªŸàªšàªŸ àªšàªàª¬àª° àªŠà«àªàªŸàª¯ àªà« àª€à« àªšàªµà« àªªàªŸàªšà«àª àªªàªžàªàªŠ àªàª°àªµàªŸ àª
+àªšà« àªà«-àª€à« àªªàªŸàªšàªŸàªšà« àªàªàª³ àª
+àªšà« àªªàªŸàªàª³ àªàªµàªŸ àª®àªŸàªà« àªàªªàª¯à«àªà« àª¬àªšà« àªà«. àªµàª¿àª·àª¯àªµàªžà«àª€à« àª¯àªŸàªŠà«àª®àªŸàª àªµàª°à«àª€àª®àªŸàªš àªžà«àªà«àª¶àªš àª¹à«àª¡àª¿àªàª àª àªàªŸàªàªŸ àª
+àªà«àª·àª°à«àª®àªŸàª àª¹à«àª¯ àªà«, àª
+àªšà« àªà«àª¬àª² àªµàª¿àªžà«àª€à«àª€à«àª€ àª¹à«àª¯ àªà«-àª«à«àª²à«àª¡àª°à«àªž àªšà« àªà«àª²àªµàªŸ àªà« àª¬àªàª§ àªàª°àªµàªŸ àª€à«àªšàªŸ àªªàª° àªà«àª²àª¿àª àªàª°à«, àªà« àª€à« àªªà«àªžà«àª€àª àªà«àª²à«àª²à« àªà« àª€à«àªšà« àª¬àªàª§ àªàª°àªµàªŸ àªà«àª²à«àª²àªŸ àªªà«àªžà«àª€àª àªàªàªà«àªš àªªàª° àªà«àª²àª¿àª àªàª°à«.<p>àª
+àªšà«àª¡àª°àªšà«àª¥ àª àªµàª°à«àª€àª®àªŸàªš àªžà«àªà«àª¶àªšàªšà« àªà«àªà«àªžà«àª àªà« àªà«àª¯àªŸàª°à« àª€àª®à« àªà«àªàªªàª£ àªà«àªà«àªžà«àª àªà«-àª€à« àªžà«àªà«àª¶àªšàª®àªŸàªàª¥à« àªµàªàªàªŸàª¯ àªàª àª¹à«àª¯ àª€à«àª¯àªŸàª°à« àªªàªŸàªšàªŸàªšà« àªšà«àªà«àªšàªŸ àª­àªŸàªàªšàªŸ àªàª°à« àª¬àªàªš àª€àª®à« àªªàªà«àªšàªŸ àªžà«àªà«àª¶àªš àª
+àª¥àªµàªŸ àªàªàª³àªšàªŸ àªžà«àªà«àª¶àªš àª€àª°àª« àª²àª àªàªŸàª¯ àªà«.</p><p>àª¶àª¿àª°à«àª·àª àª
+àª¥àªµàªŸ àª®à«àª-àªàªµàª° àªàª®à«àªàªšà« àªšà«àªà« àªà«àªàª²àªŸàª àª¬àªàªš àªà«. àªµàª°à«àª€àª®àªŸàªš àªžà«àªà«àª¶àªš àª
+àª¥àªµàªŸ àªªà«àªžà«àª€àªàªšà« àª€àª®àªŸàª® àªà«àªà«àªžà«àªàªšà« àªµàª¿àªžà«àª€à«àª€à«àª€ àªàª°àªµàªŸ àª®àªŸàªà« <i>_document:textEXPANDTEXT_</i> àªªàª° àªà«àª²àª¿àª àªàª°à«. àªà« àªªà«àª°àª²à«àª àª®à«àªà« àª¹àª¶à« àª€à« àª€à« àªµàª¿àªžà«àª€à«àª€ àª¥àª€àªŸ àªµàª§àªŸàª°à« àªžàª®àª¯ àª
+àªšà« àª®à«àª®àª°à«àªšà« àªàª°à«àª° àªªàª¡àª¶à«. àªàªà« àªµàª¿àª·àª¯àªµàªžà«àª€à« àª¯àªŸàªŠà«àªšà« àªµàª¿àªžà«àª€à«àª€ àªàª°àªµàªŸ <i>_document:textEXPANDCONTENTS_</i> àªªàª° àªà«àª²àª¿àª àªàª°à« àªà«àª¥à« àª€àª®à« àª¬àª§àªŸ àªªà«àª°àªàª°àª£à«àªšàªŸ àª¶àª¿àª°à«àª·àªà« àª
+àªšà« àªªàªàªŸ àªžà«àªà«àª¶àªš àªà«àª àª¶àªà«. àª àªªà«àª°àª²à«àª àª®àªŸàªà« àªšàªµà« àª¬à«àª°àªŸàªàªàª° àªµàª¿àªšà«àª¡à« àª¬àªšàªŸàªµàªµàªŸ àª®àªŸàªà« <i>_document:textDETACH_</i> àªªàª° àªà«àª²àª¿àª àªàª°à«. ( àªà« àª€àª®à« àª¬à« àªªà«àª°àª²à«àªà«àªšà« àªžàª°àªàªŸàª®àª£à« àªàª°àªµàªŸ àª®àªŸàªàªàª€àªŸ àª¹à«àª¯ àª
+àª¥àªµàªŸ àªµàªŸàªàªàªµàªŸ àªàªà«àªàª€àªŸ àª¹à«àª¯ àª€à«àª¯àªŸàª°à« àª àªàªªàª¯à«àªà« àª¬àªšà« àªà«). àª
+àªàª€àª®àªŸàª, àª€àª®à« àªà« àª¶àª¬à«àªŠà«àªšàªŸ àªàªªàª¯à«àªàª¥à« àª¶à«àª§ àªàª°à« àªà« àª€à« àª¹àªŸàªàª²àªŸàªàª àª¥àª¯à«àª²àªŸ àª¹à«àªµàªŸ àªà«àªàª. àª¹àªŸàªàª²àªŸàªàªàªšà« àªŠà«àª° àªàª°àªµàªŸ àª®àªŸàªà« <i>_document:textNOHIGHLIGHT_</i> àªªàª° àªà«àª²àª¿àª àªàª°à«.</p>}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=gu] {àª àª¬à«àªàªžà«àª²à«àª« àªà«àª²à«}  
+_texthelpopenbook_ [l=gu] {àª àªªà«àªžà«àª€àª àªà«àª²à«/àª¬àªàª§ àªàª°à«}  
+_texthelpviewtextsection_ [l=gu] {àªà«àªà«àªžà«àªàªšà« àª àªµàª¿àª­àªŸàª àªà«àª}  
+_texthelpexpandtext_ [l=gu] {àª¬àª§à«àª àªà«àªà«àªžà«àª àªŠàª°à«àª¶àªŸàªµà«, àª
+àª¥àªµàªŸ àªš àªŠàª°à«àª¶àªŸàªµà«}  
+_texthelpexpandcontents_ [l=gu] {àªµàª¿àª·àª¯àªµàªžà«àª€à« àª¯àªŸàªŠà«àªšà« àªµàª¿àªžà«àª€àªŸàª° àªàª°à«, àª
+àª¥àªµàªŸ àªš àªàª°à«}  
+_texthelpdetachpage_ [l=gu] {àª àªªàªŸàªšà« àªšàªµà« àªµàª¿àªšà«àª¡à«àª®àªŸàª àªà«àª²à«}  
+_texthelphighlight_ [l=gu] {àª¶à«àª§ àªªàªŠà« àª¹àªŸàªàª²àªŸàªàª àªàª°à«, àª
+àª¥àªµàªŸ àªš àªàª°à«}  
+_texthelpsectionarrows_ [l=gu] {àªàªàª³àªšàªŸ/àªªàªŸàªàª³àªšàªŸ àªµàª¿àª­àªŸàª àª€àª°àª« àªàªŸàªµ}  
+
+
+_texthelpsearchingtitle_ [l=gu] {àªà«àª àªà«àªà«àªàªž àª¶àª¬à«àªŠà« àª®àªŸàªà« àªà«àªµà« àª°à«àª€à« àª¶à«àª§ àªàª°àªµà«}  
+
+_texthelpsearching_ [l=gu] {<p>àª¶à«àª§ àªªàªŸàªšàªŸ àªªàª°àª¥à« àª€àª®à« àªàªµàªŸ àªžàªŸàªŠàªŸ àªªàªàª²àªŸàª¥à« àªà«àªµà«àª°à« àªàª°à« àª¶àªà« àªà«àª<p><ol><li>àªàª àªµàª¿àªàª€àªšà« àª¶à«àª§ àªàª°àªµàªŸ àªàªà«àªà« àªà« àª€à« àªšàªà«àªàª¿ àªàª°à«.<li>àªà« àª€àª®à« àª¬àª§àªŸàª àª¶àª¬à«àªŠà« àª
+àª¥àªµàªŸ àª
+àª®à«àª àª¶àª¬à«àªŠà« àª¶à«àª§ àªàª°àªµàªŸ àª®àªŸàªàªà« àªà« àª€à« àªšàªà«àªàª¿ àªàª°à«<li>àª€àª®à« àªà«àªšàªŸ àª®àªŸàªà« àª¶à«àª§ àªàª°àªµàªŸ àª®àªŸàªàªà« àªà« àª€à« àª¶àª¬à«àªŠà« àªàªŸàªàªª àªàª°à« <li><i>àª¶à«àª§ àª¶àª°à« àªàª°à«</i> àª¬àªàªš àªªàª° àªà«àª²àª¿àª àªàª°à«</ol><p>àªà«àª¯àªŸàª°à« àª€àª®à« àªà«àªµà«àª°à« àªàª°à« àªà« àª€à«àª¯àªŸàª°à« àªµà«àªž àª®à«àªà«àªàª àªªà«àª°àª²à«àªà«àªšàªŸ àª¶àª¿àª°à«àª·àªà« àª¬àª€àªŸàªµàª¶à«. àªªàªŸàªšàªŸàªšà« àª
+àªàª€àª®àªŸàª àªàª àª¬àªàªš àªà« àªà« àª€àª®àªšà« àªªàªà«àªšàªŸ àªµà«àªž àªªà«àª°àª²à«àªà«àª®àªŸàª àª²àª àªàªŸàª¯ àªà«, àª€à«àª¯àªŸàª àª€àª®àªšà« àª€à«àª°à«àªàªŸ àªµà«àªž àªªà«àª°àª²à«àªà«àª®àªŸàª àª²àª àªàªµàªŸ àª
+àª¥àªµàªŸ àªªà«àª°àª¥àª® àªµà«àªž àªªà«àª°àª²à«àªà«àª®àªŸàª àªªàªŸàªàªŸ àªàªµàªµàªŸ àª®àªŸàªà«àªšàªŸ, àª
+àªšà« àª€à«àªšà« àª²àªàª€à« àªªà«àª°àªµà«àª€à«àª€àª¿ àªàª°àªµàªŸ àª®àªŸàªà«àªšàªŸ àª¬àªàªšà« àªà«àªµàªŸ àª®àª³àª¶à«. àªªà«àª°àª²à«àªà«àªšà« àªà«àªµàªŸ àª®àªŸàªà« àªà«àª àªªàª£ àªªà«àª°àª²à«àªàªšàªŸ àª¶àª¿àª°à«àª·àª àª
+àª¥àªµàªŸ àª¶àª¿àª°à«àª·àª àª¬àªàªš àªªàª° àªà«àª²àª¿àª àªàª°à«<p>àªµàª§à«àª®àªŸàª àªµàª§à« 50 àªªà«àª°àª²à«àªà« àªàªàª àªªàªŸàªšàªŸ àªªàª° àªà«àªµàªŸ àª®àª³à« àªà«. àªªàªŸàªšàªŸàªšà« àªà«àªàªšàªŸ àª­àªŸàªàª®àªŸàª àª°àª¹à«àª² <i>_Global:linktextPREFERENCES_</i> àª¬àªàªš àªªàª° àªàª¿àª²àª àªàª°à«àªšà« àª€àª®à« àª àªšàªàª¬àª°àª®àªŸàª àª«à«àª°àª«àªŸàª° àªàª°à« àª¶àªà« àªà«.<p>}  
+
+_texthelpquerytermstitle_ [l=gu] {àª¶à«àª§ àªªàªŠà« }  
+_texthelpqueryterms_ [l=gu] {<p>àªà«àªµà«àª°à« àª¬à«àªà«àªžàª®àªŸàª àª€àª®à« àªà« àªªàª£ àªàªŸàªàªª àªàª°à« àªà« àª€à«àªšà« àª¶àª¬à«àªŠà« àª
+àª¥àªµàªŸ àª¶àª¬à«àªŠàªžàª®à«àª¹àªšà« àª¯àªŸàªŠà« àª€àª°à«àªà« àª
+àª°à«àª¥àªàªàªš àªàª°àªµàªŸàª®àªŸ àªàªµà« àªà« àªà«àªšà« "àª¶à«àª§àªªàªŠà«" àªàª¹à«àªµàªŸàª¯ àªà«. àªªàªŠ àª àªàª àª¶àª¬à«àªŠ àªà« àªà«àª®àªŸàª àª®àªŸàª€à«àª° àª
+àªà«àª·àª°à« àª
+àªšà« àª
+àªàªà« àªšà« àªžàª®àªŸàªµà«àª¶ àª¥àªŸàª¯ àªà«, àª
+àª¥àªµàªŸ àªàª àª¶àª¬à«àªŠàªžàª®à«àª¹ àªà« àªà«àª®àªŸàª àª¹àªŸàª°àª¬àªàª§ àª¶àª¬à«àªŠà« àª¬à«àªµàª¡àªŸ àª
+àªµàª€àª°àª£ àªàª¿àª¹à«àªšà« ("...") àªžàª®àªŸàª¯à«àª² àª¹à«àª¯ àªà«. àªªàªŠà« àªµà«àª¹àªŸàªàª àªžà«àªªà«àª¶ àª¥à« àª
+àª²àª àªªàª¡à« àªà«. àªà« àªà«àª àªªàª£ àªà«àª°à«àªà«àªàª° àªà«àª® àªà« àªµàª¿àª°àªŸàª® àªàª¿àª¹à«àªš àªŠà«àªàªŸàª¯, àª€à« àª€à« àªªàªŠà« àªšà« àªàª àª¬à«àªàªŸàª¥à« àª
+àª²àª àªªàªŸàª¡à« àªà« àªà«àª® àªà« àªªàªŠà« àªµàªà«àªà« àªàªà«àª¯àªŸ àª¹àª€à«. àª
+àªšà« àªªàªà« àª€à«àªšà« àª
+àªµàªàª£àªšàªŸ àªàª°àªµàªŸàª®àªŸàª àªàªµà« àªà« àª€àª®à« àªà« àª€à« àª¶àª¬à«àªŠà«àª®àªŸàª àªµàª¿àª°àªŸàª® àªàª¿àª¹à«àªš àªžàª®àªŸàªµàª¿àª·à«àª àª¹à«àª¯ àª€à«àªšà« àª¶à«àª§ àªàª°à« àª¶àªà« àªšàª¹àª¿.<p>àªàªŠàªŸàª¹àª°àª£ àª€àª°à«àªà«, àªàª àªªàªŠ <p><ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>àªšà« àª
+àª°à«àª¥àªàªàªš  <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul>àª¥àª¶à«.<p>}  
+
+_texthelpmgppsearching_ [l=gu] {MGPP àª§à«àªµàªŸàª°àªŸ àªžàªàªà«àª°àª¹ àª€à«àª¯àªŸàª° àªàª°àªµàªŸ àª¥à«àª¡àªŸ àª
+àªšà«àª¯ àªàªªàªŸàª¯à« àªàªªàª²àª¬à«àª§ àªà«.<ul> <li> <b>*</b>àª àª¶àª¬à«àªŠàª¥à« àª¶àª°à« àª¥àª€àªŸ àªà«àªµà«àª°à« àªªàªŠàªšàªŸ àª
+àªàª€à« àª¬àª§àªŸ àª¶àª¬à«àªŠà«àªšà« àª®à«àª àªàª°à« àªà«.àªŠàªŸ.àª€ <b>comput*</b>àªàªµàªŸ àª¶àª¬à«àªŠà«àªšà« àª®à«àª àªàª°àª¶à« àªà« <b>comput</b>àª¥à« àª¶àª°à« àª¥àª€àªŸ àª¹à«àª¯.<li><b>/x</b> àªà«àªµà«àª°à« àªªàªŠà«àªšàªŸ àªàª àª
+àª¥àªµàªŸ àªµàª§àªŸàª°à« àªªàªŠà«àªšà« àªµàª§à« àª®àª¹àª€à«àªµ àªàªªàªµàªŸ àª®àªŸàªà« àªàªªàª¯à«àª àªàª°à« àª¶àªàªŸàª¯ àªà«. àªŠàªŸ.àª€. àªªà«àª°àª²à«àªà«àªšà« àª°à«àªàªšà«àª àªàªªàª€à« àªµàªàª€à«<b>computer/10 science</b>àª®àªŸàª science àªàª°àª€àªŸ computer àªšà« 10àªàª£à« àªµàª§àªŸàª°à« àª®àª¹àª€à«àªµ àªàªªàª¶à«. </ul>}  
+
+_texthelplucenesearching_ [l=gu] {Lucene àª§à«àªµàªŸàª°àªŸ àªžàªàªà«àª°àª¹ àª€à«àª¯àªŸàª° àªàª°àªµàªŸ àª¥à«àª¡àªŸ àª
+àªšà«àª¯ àªàªªàªŸàª¯à« àªàªªàª²àª¬à«àª§ àªà«. <ul><li><b>?</b> àªµàªŸàªàª²à«àª¡àªàªŸàª°à«àª¡ àª€àª°à«àªà« àªàª àª
+àªà«àª·àª°àªšà« àªàªà«àª¯àªŸàª àªàªªàª¯à«àª àªàª°à« àª¶àªàªŸàª¯ àªà«. àªàªŠàªŸàª¹àª°àª£ àª€àª°à«àªà«, <b>b?t</b> àª <b>bet</b>, <b>bit</b> àª
+àªšà« <b>bat</b> àªµàªà«àª°à«àªšà« àª®à«àª àªàª°àª¶à«.<li><b>*</b> àªšà« àªàª àªàª°àª€àªŸ àªµàª§àªŸàª°à« àª
+àªà«àª·àª°à«àªšà« àªàªà«àª¯àªŸàª àªµàªŸàªàª²à«àª¡àªàªŸàª°à«àª¡ àª€àª°à«àªà« àªàªªàª¯à«àª àªàª°à« àª¶àªàªŸàª¯ àªà«. àªàªŠàªŸàª¹àª°àª£ àª€àª°à«àªà« <b>comput*</b> àª <b>comput</b> àª¥à« àª¶àª°à« àª¥àª€àªŸ àª¬àª§àªŸàª àª¶àª¬à«àªŠà« àª®à«àª àªàª°à« àªà«.</ul> àª àª¬àªšà«àªšà« àªµàªŸàªàª²à«àª¡àªàªŸàª°à«àª¡àªžàªšà« àªàªªàª¯à«àª àªªàªŠàªšà« àª®àª§à«àª¯àª®àªŸàª, àª
+àª¥àªµàªŸ àªªàªŠàªšà« àª
+àªàª€à« àªàª°à« àª¶àªàªŸàª¯ àªà«. àª€à«àªšà« àªàªªàª¯à«àª àª¶à«àª§ àªªàªŠàªšà« àª¶àª°à«àªàª€àª®àªŸàª àªàª°à« àª¶àªàªŸàª€à« àªšàª¥à«.}  
+
+_texthelpquerytypetitle_ [l=gu] {àªà«àªµà«àª°à«àªšà« àªªà«àª°àªàªŸàª°}  
+_texthelpquerytype_ [l=gu] {<p>àªà«àªµà«àª°à«àªšàªŸ àª¬à« àªªà«àª°àªàªŸàª° àªà«.<ul><li><b>àª€àª®àªŸàª®</b> àª¶àª¬à«àªŠà« àª®àªŸàªà«àªšà« àªà«àªµà«àª°à«. àª àª€àª®à« àªšàªà«àªàª¿ àªàª°à«àª²àªŸ àª€àª®àªŸàª® àª¶àª¬à«àªŠà« àªà« àªªà«àª°àª²à«àªà«àª®àªŸàª àªžàª®àªŸàªµàª¿àª·à«àª àª¹à«àª¯ àª€à«àªµàªŸ àªªà«àª°àª²à«àªà« (àª
+àª¥àªµàªŸ àªªà«àª°àªàª°àª£à«, àª
+àª¥àªµàªŸ àª¶àª¿àª°à«àª·àªà«) àªšà« àª¶à«àª§à« àªà«. àªà«àªµà«àª°à« àªªà«àª°àª®àªŸàª£à«àªšàªŸ àªªà«àª°àª²à«àªà« àªµàª°à«àª£àªŸàªà«àª·àª° àª®à«àªàª¬ àªŠà«àªàªŸàª¯ àªà«.<p><li><b>àª
+àª®à«àª</b> àª¶àª¬à«àªŠà« àª®àªŸàªà«àªšà« àªà«àªµà«àª°à«. àªà« àªªàªŠà« àª€àª®à« àª¶à«àª§à« àª°àª¹à«àª¯àªŸ àªà« àªà« àªà« àªªà«àª°àª²à«àªà«àª®àªŸàª àª¹à«àª àª¶àªà« àª€à«àªµàªŸ àªªàªŠà«àªšà« àª¯àªŸàªŠà« àª¬àªšàªŸàªµà« àªà«.  àªàªµàªŸ àªªà«àª°àª²à«àªà« àªà«àª°àª® àªªà«àª°àª®àªŸàª£à« àªªà«àª°àªŠàª°à«àª¶àª¿àª€ àª¥àªŸàª¯ àªà« àªà« àªà« àªà«àªµà«àª°à« àªªà«àª°àª®àªŸàª£à« àªà«àª¬ àª àªšàªà«àª àª®à«
+àª àª¥àª€àªŸ àª¹à«àª¯ . àªà«àª¯àªŸàª°à« àªªà«àª°àª²à«àªà« àªà«àªàª²àªŸ àªšàªà«àª àª®à«
+àª àª¥àªŸàª¯ àªà« àª€à« àª®àªŸàª€à«àª°àªŸ àªšàªà«àªàª¿ àªàª°àª€à« àªµàªàª€à«,<p><ul><li> àªà« àªªà«àª°àª²à«àªàªšà« àª¶à«àª§àªµàªŸ àª®àªŸàªà« àªàª àªàª°àª€àªŸ àªµàª§àªŸàª°à« àª¶à«àª§ àªªàªŠàªšà« àªàªªàª¯à«àª àªàª°àªµàªŸàª®àªŸàª àªàªµà« àª€à« àªà« àª€à« àª¶à«àª§ àªªàª°àª¿àª£àªŸàª® àª€à« àªªà«àª°àª²à«àªàªšà« àªàªàªŠàª® àªšàªà«àª àª²àª àªàªŸàª¯ àªà«;<li> àªžàªŸàª®àªŸàªšà«àª¯ àªªàªŠ àªàª°àª€àªŸ àª
+àªžàªŸàª§àªŸàª°àª£ àªªàªŠàªšà«àª àª®àª¹à«àª€à«àªµ àªµàª§àªŸàª°à« àª¹à«àª¯ àªà«;<li>àªµàª§àªŸàª°à« àªªàªŸàªšàªŸ àªµàªŸàª³àªŸ àªªà«àª°àª²à«àªà« àªàª°àª€àªŸ àªàªàªŸ àªªàªŸàªšàªŸ àªµàªŸàª³àªŸ àªªà«àª°àª²à«àªà« àª¶à«àª§ àªªàª°àª¿àª£àªŸàª®àª¥à« àªàªàªŠàª® àªšàªà«àª àª¹à«àª¯ àªà«.</ul></ul><p>àªàª àªàª°àª€àªŸ àªµàª§àªŸàª°à« àª¶à«àª§ àªªàªŠà«, àªàªà« àªµàªŸàªà«àª¯, àª
+àª¥àªµàªŸ àªàªà« àª«àªàª°à« àªµàªà«àª°à« àª€àª®àªŸàª°à« àªàªà«àªàªŸ àªªà«àª°àª®àªŸàª£à« àª¶à«àª§ àªàª°à« àª¶àªà« àªà«. àªà« àª€àª®à« àª®àªŸàª€à«àª° àªàª àª àª¶à«àª§ àªªàªŠ àªšàªà«àªàª¿ àªàª°à«àª¯à« àª¹à«àª¯ àª€à« àªªà«àª°àª²à«àªà« àª¶à«àª§ àªªàª°àª¿àª£àªŸàª®à«àªšà« àª«àª¿àªàªµàªšà«àªžà« àªªà«àª°àª®àªŸàª£à« àªà«àª àªµàªŸàª àªàª¶à«.<p>}  
+
+_texthelpadvancedsearchtitle_ [l=gu] {_1_ àªžàª°à«àª àªàªšà«àªàª¿àªšàªšà« àªàªªàª¯à«àª àªàª°à«àªšà« àªàª¡àªµàªŸàªšà«àªž àª¶à«àª§ àªàª°à«}  
+
+_texthelpadvancedsearch_ [l=gu] {<p> àªà« àª€àª®à« àªàª¡àªµàªŸàªšà«àªž àªàªµà«àª°à« àª°à«àª€ (àªªàªžàªàªŠàªà«àª àª®àªŸàª) àªªàªžàªàªŠ àªàª°à«àª² àª¹àª¶à« àª€à« àª€àª®àªŸàª°à« àªªàªŸàªžà« àª¶à«àª§ àªµàª¿àªàª²à«àªªà« àª¥à«àª¡àªŸ àª
+àª²àª àª¹àª¶à«.}  
+
+_texthelpadvsearchmg_ [l=gu] {MG àªžàªàªà«àª°àª¹à«àª®àªŸàª àªàª¡àªµàªŸàªšà«àªž àª¶à«àª§ àª€àª®àªšà« àª¬à« àªµàª¿àªàª²à«àªªà« àªàªªà« àªà«. àª°à«
+àªšà«àªàª¡ àª
+àªšà« àª¬à«àª²àª¿àª
+àªš. <a href="\#query-type">_texthelpquerytypetitle_</a>àª®àªŸ àªàª£àªŸàªµà«àª¯àªŸ àªªà«àª°àª®àªŸàª£à« <b>àª°à«
+àªšà«àªàª¡</b>àª¶à«àª§ àª <b>àª
+àª®à«àª</b> àªà«àªµà« àª àªà«.<p>_texthelpbooleansearch_}  
+
+_texthelpbooleansearch_ [l=gu] {<b>àª¬à«àª²àª¿àª
+àªš</b> àª¶à«àª§  & ("àª
+àªšà«" àª®àªŸàªà«), | ("àª
+àª¥àªµàªŸ"àª®àªŸàªà«), àª
+àªšà« ("àªšàª¹à«"àª®àªŸàªà«) àªšà« àªàªªàª¯à«àª àªàª°à«àªšà«, àªà« àªàª°à«àª° àª¹à«àª¯ àª€à« àªà«àª¥ àª®àªŸàªà« àªà«àªàªž (àªªà«àª°à«àªšà«àª¥àªžàª¿àªž) àªšà« àªàªªàª¯à«àª àªàª°àªµàªŸàªšà« àªà«àªàªµàªŸàª àªªà«àª°à« àªªàªŸàª¡à« àªà«. | àª ("àª
+àª¥àªµàªŸ"àª®àªŸàªà«) àª¡à«àª«à«àª²à«àª àªàªªàª°à«àªàª° àªà«.   
+<p> àªàªŠàªŸàª¹àª°àª£ àª€àª°à«àªà« <b>snail & farming</b> àªàªµàªŸ àªªà«àª°àª²à«àªà«àªšà« àª®à«àª àªàª°àª¶à« àªà«àª®àªŸàª àª¬àªšà«àªšà« àª¶àª¬à«àªŠà« àªžàª®àªŸàªµà«àª·à«àª àª¹à«àª¯ àªà«àª® àªà« <b>snail</b> àª
+àªšà« <b>farming</b>, àªàª¯àªŸàª°à«<b>snail | farming</b> àªàªµàªŸ àªªà«àª°àª²à«àªà«àªšà« àª®à«àª àªàª°àª¶à« àªà«àª®àªŸàª àª¬àªàªšà«àªšà«  àª®àªŸàª¥à« àªà«àª àªªàª£ àªàª àª àª¶àª¬à«àªŠ àª¹à«àª¯ àªà«àª® àªà« <b>snail</b> àª
+àª¥àªµàªŸ. <b>farming</b>. <b>snail !farming</b> àªàªµàªŸ àªªà«àª°àª²à«àªà« àª®à«àª àªàª°àª¶à« àªà«àª®àªŸ àª®àªŸàª€à«àª° <b>snail</b> àª¹à«àª¯ àªªàª£ <b>farming</b> àªš àª¹à«àª¯.}  
+
+_texthelpadvsearchmgpp_ [l=gu] {MGPP àªžàªàªà«àª°àª¹à«àª®àªŸàª àªàª¡àªµàªŸàªšà«àªž àª¶à«àª§ àªàª°àªµàªŸ àª®àªŸàªà« àª¬à«àª²àª¿àª
+àªš àªàªªàª°à«àªàª°à«àªž àªšà« àªàªªàª¯à«àª àªàª°à«. _texthelpbooleansearch_ <p> <a href="\#query-type">_texthelpquerytypetitle_</a> àª®àªŸàª <b>àª
+àª®à«àª</b> àª¶à«àª§ àª®àªŸàªà«, "àªà«àªŠàª°àª€à«" (àª
+àª¥àªµàªŸ "àªšàª¿àª°à«àª®àªŸàª£") àªàª°à«àª¡àª°àª®àªŸàª àªàª£àªŸàªµà«àª¯àªŸ àªªà«àª°àª®àªŸàª£à« <b>àªà«àª°àª®àªŸàªšà«àªžàªŸàª°</b> àªàª°à«àª¡àª°àª®àªŸàª àªªàª°àª¿àª£àªŸàª® àªà«àª àª¶àªàªŸàª¯ àªà«, àª€à«àª¯àªŸàª° àªªàªà«àªšà« àªà«àª°àª® àª àªžàªàªà«àª°àª¹ àªšàª¿àª°à«àª®àªŸàª£ àªžàª®àª¯à« àªªà«àª°àª²à«àªà« àªªàª° àªà« àªªà«àª°àªà«àª°àª¿àª¯àªŸ àª¥àª àª€à« àªà«. <p> àª¬à«àªàªŸ àªàªªàª°à«àªàª°à«àªžàª®àªŸàª <b>àªšàªà«àªx</b> àª
+àªšà« <b>àª
+àªàªŠàª°x</b> àªà«. àªšàªà«àªxàªšà« àªàªªàª¯à«àª àª®àª¹àª€à«àª€à«àª® àª
+àªàª€àª° àªšàªà«àªà« àªàª°àªµàªŸ àª®àªŸàªà« àª¥àªŸàª¯ àªà« ( x àª¶àª¬à«àªŠà« ) àªà« àªªà«àª°àª²à«àªà«àªšà« àª®à«àª àª¥àªµàªŸ àª®àªŸàªà« àª¬à« àªà«àªµà«àª°à« àªªàªŠà«àªšà« àª
+àª²àª àªàª°à« àªà« àªªà«àª°àª¥àª® àªªàªŠ  <i>àªªàªà«</i> àª¬à«àªà« àªªàªŠ  x àª¶àª¬à«àªŠà«àªšà« àª
+àªàªŠàª° àª àª¹à«àª¯ àª€à«àªµà«àª àª
+àªàªŠàª°x àªšàªà«àªà« àªàª°à« àªà«. àª àªšàªà«àª àªà«àªµà« àª àªà« àªªàª°àªàª€à« àªà«àª°àª® àª®àª¹àª€à«àªµàªšà« àªà«. àª¡àª¿àª«à«àª²à«àª àª
+àªàª€àª° 20 àªà«.}  
+
+_texthelpadvancedsearchextra_ [l=gu] {àªšà«àª§àª àªà« àª€àª®à« àªžàª°àª³ (àªžàª¿àª®à«àªªàª²) àªàªµà«àª°à« àª®à«àª¡ àªµàª¿àªàª²à«àªªàª®àªŸàª àª¶à«àª§ àªàª°àª€àªŸ àª¹à«àª¯ àª€à« àª àªàªªàª°à«àªàª°à«àªžàªšà« àª
+àªµàªàª£àªšàªŸ àªàª°àªµà«.}  
+
+_texthelpadvsearchlucene_ [l=gu] {Lucene àªžàªàªà«àª°àª¹àª®àªŸàª àªàª¡àªµàªŸàªšà«àªž àª¶à«àª§ àªàª°àªµàªŸ àª®àªŸàªà« àª¬à«àª²àª¿àª
+àªš àªàªªàª°à«àªàª°à«àªž àªšà« àªàªªàª¯à«àª àªàª°à«. _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=gu] {àª«àª¿àª²à«àª¡àªšà« àªàªªàª¯à«àª àªàª°à«àªšà« àªàª°àªµàªŸàª®àªŸàª àªàªµàª€à« àª¶à«àª§}  
+
+_texthelpformsearch_ [l=gu] {<p>àª«àª¿àª²à«àª¡àªšà« àªàªªàª¯à«àª àªàª°à«àªšà« àªàª°àªµàªŸàª®àªŸàª àªàªµàª€à« àª¶à«àª§ àªµàª¿àªµàª¿àª§ àª«àª¿àª²à«àª¡àª®àªŸàª àªžàªàª¯à«àªà«àª€ àª¶à«àª§àªšà« àª€àª àªªà«àª°à« àªªàªŸàª¡à« àªà«. àªŠàªŸ.àª€. àªà«àªàªªàª£ àªµà«àª¯àªà«àª€àª¿ "Smith" àªªàªŠàªšà« àª¶àª¿àª°à«àª·àª àª
+àªšà« "snail farming" àªªàªŠàªšà« àªµàª¿àª·àª¯ àª«àª¿àª²à«àª¡àª®àªŸàª àª¶à«àª§ àªàª°à« àª¶àªà« àªà«. àªžàª¿àª®à«àªªàª² àªà«àªµà«àª°à« àª®à«àª¡àª®àªŸàª àª«à«àª°à«àª®àªšà« àªŠàª°à«àª àª²àªŸàªàªš àªàª àª àª²àªŸàªàªšàª®àªŸàª àªžàªŸàª®àªŸàªšà«àª¯ àª¶à«àª§ àªªà«àª°àªà«àª°àª¿àª¯àªŸ àª
+àªšà«àªžàª°à« àªà«. àª«à«àª°à«àª®àªšà« àªµà«àª¯àªà«àª€àª¿àªàª€ àª²àªŸàªàªš àª
+àªšà« ("àª€àª®àªŸàª®" àª¶à«àª§ àª®àªŸàªà«) àª
+àª¥àªµàªŸ àª
+àª¥àªµàªŸ ("àª
+àª®à«àª" àª¶à«àª§ àª®àªŸàªà«) àªšà« àªžàªàª¯à«àªà«àª€ àªàªªàª¯à«àª àªàª°à« àªà«. àª«àª¿àª²à«àª¡àªšà« àª
+àªàªŠàª° àªžàª®àªŸàªµàª¿àª·à«àª àªªàªŠà«àªšà« àªªàª£ àªžàªàª¯à«àªà«àª€ àª¶à«àª§ àªàª°à« àª¶àªàªŸàª¯ àªà«. àªàª¡àªµàªŸàªšà«àªž àª®à«àª¡àª®àªŸàª àª€àª®à« àª¡à«àª°à«àªª àª¡àªŸàªàªš àª¯àªŸàªŠà«àª®àªŸàª àª«àª¿àª²à«àª¡ àªµàªà«àªà« àª
+àªšà«/àª
+àª¥àªµàªŸ/àªšàª¹àª¿ àªšà« àªžàª°àªàªŸàª®àª£à« àªšàªà«àªàª¿ àªàª°à« àª¶àªà« àªà« àª
+àªšà« àª«àª¿àª²à«àª¡àªšà« àª
+àªàªŠàª° àª€àª®à« àª¬à«àª²àª¿àª
+àªš àªàªªàª°à«àªàª°à«àªžàªšà« àªàªªàª¯à«àª àªàª°à« àª¶àªà« àªà«.}  
+
+_texthelpformstemming_ [l=gu] {àªà« àª€à« àª«àª¿àª²à«àª¡ àª
+àªàªŠàª°àªšàªŸ àªªàªŠà« àªà«àªžàª«à«àª²à«àª¡à«àª¡ àª
+àª¥àªµàªŸ àªžà«àªà«àª®à«àª¡ àªà« àªà« àªšàª¹àª¿ àª€à« "àªµàªŸàª³à«" àª
+àªšà« "àª°à«àªà«" àª¬à«àªà«àªž àª§à«àªµàªŸàª°àªŸ àªšàªà«àªàª¿ àªàª°à« àª¶àªàªŸàª¯ àªà«. àª
+àª¡àªµàªŸàªšà«àªž àªªà«àª°àªàªŸàª°à« àª¶à«àª§ àªàª°àª€à« àªµàªàª€à« àª àª¬àªàªšà« àª¡àª¿àª«à«àª²à«àª àª¥à« àª¬àªàª§ (àªžà«àªµàª¿àªà«àª¡ àªàª«) àª¹à«àª¯ àªà«.}  
+
+_textdatesearch_ [l=gu] {àª€àªŸàª°à«àª àªªà«àª°àª®àªŸàª£à« àª¶à«àª§ àªàª°à«àªšà« }  
+
+_texthelpdatesearch_ [l=gu] {àª€àªŸàª°à«àª àªàª§àªŸàª°àª¿àª€ àª¶à«àª§, àªà«àªà«àªàªž àªžàª®àª¯ àª®àª°à«àª¯àªŸàªŠàªŸàªšàªŸ àªªà«àª°àª²à«àªà«àªšà« àª
+àªšà« àª¬àªšàªŸàªµà«àªšà« àª¶à«àª§ àªàª°à« àªà«. àª€àª®à« àªà«àªà«àªàªž àªµàª°à«àª· àª
+àª¥àªµàªŸ àªžàª®àª¯ àª®àª°à«àª¯àªŸàªŠàªŸàªšà« àª²àªàª€àªŸ àªªà«àª°àª²à«àªà«àªšà« àª¶à«àª§ àªàª°à« àª¶àªà« àªà«. àª¯àªŸàªŠ àª°àªŸàªà«, àªà« àª€àª®àªŸàª°à« àªªàªŸàªžà« àªà«àª àª¶à«àª§ àªªàªŠà« àªš àª¹à«àª¯ àª€à« àª€àª®à« àª®àªŸàª€à«àª° àª€àªŸàª°à«àª àªªà«àª°àª®àªŸàª£à« àª¶à«àª§ àªàª°à« àª¶àªà« àªà«, àªà« àª€àª®à« àªà«àªàªªàª£ àª€àªŸàª°à«àª àªàªŸàªàªª àªš àªàª°à« àª¹à«àª¯ àª€à« àª€àª®àªŸàª°à« àª¶à«àª§ àªªà«àª°àªà«àª°à«àª¯àªŸàª®àªŸàª àª€àªŸàª°à«àªàªšà« àªàªªàª¯à«àª àªš àªàª°àªµà« àªà«àªàª àªàªàª²à« àªà« àª€àªŸàª°à«àª àª¶à«àª§ àª
+àªžà«àª€àª¿àª€à«àªµàª®àªŸàª àªš àª¹àª€à« àª€à«àªµà« àª
+àª°à«àª¥ àª¥àªŸàª¯.<p>}  
+
+_texthelpdatehowtotitle_ [l=gu] {àª àªžà«àªµàª¿àª§àªŸàªšà« àªà«àªµà« àª°à«àª€à« àªàªªàª¯à«àª àªàª°àªµà«àª}  
+_texthelpdatehowto_ [l=gu] {<ul><li>àª®àªŸàª€à«àª° àªàªàª àªµàª°à«àª·àªšàªŸ àªªà«àª°àª²à«àªà« àª¶à«àª§àªµàªŸ àª®àªŸàªà«:<p><ul><li>àª€àª®àªšà« àªªàªžàªàªŠ àª¹à«àª¯ àª€à« àªžàªŸàª®àªŸàªšà«àª¯ àª¶à«àª§ àªªàªŠà«àªšà« "àª¶àª°à«àªàª€ (àª
+àª¥àªµàªŸ àª«àªà«àª€) àª€àªŸàª°à«àª" àª¬à«àªà«àªžàª®àªŸàª àªµàª°à«àª· àªàªŸàªàªª àªàª°à« .<li>àªà« àª€àª®àªŸàª°à« àª€àªŸàª°à«àª àªà«àª®àªš àªàª°àªŸ àªªàª¹à«àª²àªŸ (àªà«àªšà« àª.àªž. àªªà«àª°à«àªµà« àª€àª°à«àªà« àªªàª£ àªàª³àªàªµàªŸàª®àªŸ àªàªµà« àªà«) àªšà« àª¹à«àª¯ àª€à« àª€à« àª¬à«àªà«àªžàª®àªŸàª àªªà«àª²àª¡àªŸàªàªš àª®à«àªšà«àª®àªŸàªàª¥à« "B.C.E" àªµàª¿àªàª²à«àªª àªªàªžàªàªŠ àªàª°à«. <li>àª€àª®àªšà« àªªàªžàªàªŠ àªªàª¡à« àª€à«àªµà« àª°à«àª€à« àª¶à«àª§ àª¶àª°à« àªàª°à«..</ul><p><li>àªà«àª àªžàª®àª¯àªàªŸàª³à« àª
+àª¥àªµàªŸ àªµàª°à«àª· àª
+àªµàª§àª¿àªšà« àª²àªàª€àªŸ àªªà«àª°àª²à«àªà« àª¶à«àª§àªµàªŸ àª®àªŸàªà«:<p><ul><li>àª€àª®àªšà« àªà« àªªàªžàªàªŠ àªªàª¡à« àª€à« àª¶à«àª§ àªªàªŠà« àªàªŸàªàªª àªàª°à«.<li>"àª¶àª°à«àªàª€ (àª
+àª¥àªµàªŸ àª«àªà«àª€) àª€àªŸàª°à«àª" àª¬à«àªà«àªžàª®àªŸàª àª
+àªàªŸàªàªšà« àª€àªŸàª°à«àª àªàªŸàªàªª àªàª°à«.<li>"àª
+àªàª€àª¿àª® àª€àªŸàª°à«àª" àªàªŸàªšàªŸàª®àªŸàª àªªàªà«àªšà« àª€àªŸàª°à«àª àªàªŸàªàªª àªàª°à«. <li> àªà« àªà«àª àªªàª£ àª€àªŸàª°à«àª àªà«àª®àªš àªàª°àªŸ (àªà«àªšà« àª.àªž. àªªà«àª°à«àªµà« àª€àª°à«àªà« àªªàª£ àªàª³àªàªµàªŸàª®àªŸàª àªàªµà« àªà«) àªªàª¹à«àª²àªŸàªšà« àª¹à«àª¯ àª€à« àªªà«àª²àª¡àªŸàªàªš àª®à«àªšà«àªàª®àªŸàªàª¥à« "B.C.E" àªµàª¿àªàª²à«àªª àªªàªžàªàªŠ àªàª°à«. <li>àª€àª®àªšà« àªªàªžàªàªŠ àªªàª¡à« àª€à«àªµà« àª°à«àª€à« àª¶à«àª§ àª¶àª°à« àªàª°à«.</ul></ul><p>}  
+
+_texthelpdateresultstitle_ [l=gu] {àª€àª®àªŸàª°à« àª¶à«àª§ àªàªŸàª® àªªà«àª°àª®àªŸàª£à«àªšà«àª àªªàª°àª¿àª£àªŸàª®}  
+_texthelpdateresults_ [l=gu] {àª.àªž.1903àªšàªŸ àªªà«àª°àª²à«àªà« àª®àªŸàªà« àª¶à«àªŠ àªàª°àªµàªŸàª®àªŸàª àªàªµà« àª€à« àªžàªŸàª®àªŸàªšà«àª¯ àª°à«àª€à« àªàªµà«àª àªàª¹à«àªµàªŸàª¯ àªà« 1903àª®àªŸàª àª²àªàªŸàª¯à«àª²àªŸ àªžàªàªŠàª°à«àª­ àªªà«àªžà«àª€àªà« àª¬àª€àªŸàªµàª¶à« àªšàª¹àª¿ àªªàª°àªàª€à« 1903 àªšàªŸ àªªà«àª°àª²à«àªà« àª¬àª€àªŸàªµàª¶à«. àªàª® àªàª€àªŸ, àªà« àªªà«àª°àª²à«àªà«àªšà« àª€àªŸàª°à«àª àª®àª³à« àª€à« àªàª àªªà«àª°àª²à«àªà« àªµàª€àªŸàªµàª¶à« àªà« àªà«àªà«àªàªž àª€àªŸàª°à«àª àª®àª°à«àª¯àªŸàªŠàªŸàªšàªŸ àª¹à«àª¯ ( àªà«àª® àªà« 1899-1911) àªà«àª®àªŸàª 1903 àªšà« àªžàª®àªŸàªµà«àª¶ àª¥àªŸàª¯ àªà«, àª
+àªšà« àªàªµàªŸ àªªà«àª°àª²à«àªà« àªà« àªà« àªà«-àª€à« àªžàªŠà«àªšà« àª­àªŸàª àª¹à«àª¯. àªà«àª® àªà« 1903 àª (20àª®à« àªžàªŠà« àª
+àª¥àªµàªŸ àªµà«àªžàª®à« àªžàªŠà«) àªšà« àª­àªŸàª àªà«.}  
+
+_textchangeprefs_ [l=gu] {àª€àª®àªŸàª°à« àªªàªžàªàªŠàªà«àª àª¬àªŠàª²à«àªšà«}  
+
+_texthelppreferences_ [l=gu] {<p>àªà«àª¯àªŸàª°à« àª€àª®à« àªªà«àªàªšà« àªà«àªàªšàªŸ àª­àªŸàªàª®àªŸàª <i>_Global:linktextPREFERENCES_</i> àª¬àªàªš àªà«àª²àª¿àª àªàª°à« àª€à« àª€àª®àªŸàª°à« àªàª°à«àª°àª¿àª¯àªŸàª€ àª®à«àªàª¬ àªàªšà«àªàª°àª«à«àª¶àª®àªŸàª àªà«àªàª²à«àª àª²àªŸàªà«àª·àª£àª¿àªà«àª€àªŸ (àª«à«àªàª°àª°à«àªž)àª®àªŸàª àªªàª°àª¿àªµàª°à«àª€ àªàª°à« àª¶àªàª¶à«.}  
+
+_texthelpcollectionprefstitle_ [l=gu] {àªžàªàªà«àª°àª¹ àªªàªžàªàªŠàªà«àª }  
+_texthelpcollectionprefs_ [l=gu] {<p> àª
+àª®à«àª àªžàªàªà«àª°àª¹à«àª®àªŸàª àªàª£àªŸ àªªà«àªàªŸàªžàªàªà«àª°àª¹à« àªžàª®àªŸàª¯à«àª² àª¹à«àª¯ àªà«, àªà«àªšà« àªàª àª¯à«àªšàª¿àª àª€àª°à«àªà« àªµà«àª¯àªàª¿àª€àªàª€ àª
+àª¥àªµàªŸ àªàª àªžàªŸàª¥à« àª¶à«àª§à« àª¶àªàªŸàª¯ àªà«. àªà« àªàª® àªàª°àªµà«àª àª¹à«àª¯ àª€à«, àªªàªžàªàªŠàªà«àª àªªàªŸàªšàªŸ àªªàª° àª€àª®àªŸàª°à« àª¶à«àª§ àªªàªžàªàªŠàªà«àª®àªŸàª àªà« àªªà«àªàªŸàªžàªàªà«àª°àª¹àªšà« àªžàª®àªŸàªµàªŸàªšà«àª àªà« àª€à« àª€àª®à« àªªàªžàªàªŠ àªàª°à« àª¶àªà« àªà«.}  
+
+_texthelplanguageprefstitle_ [l=gu] {àª­àªŸàª·àªŸ àªªàªžàªàªŠàªà«àª}  
+_texthelplanguageprefs_ [l=gu] {<p>àªŠàª°à«àª àªžàªàªà«àª°àª¹àª®àªŸàª àª¡àª¿àª«à«àª²à«àª àªªà«àª°àªžà«àª€à«àª€àª¿ àª­àªŸàª·àªŸ àª¹à«àª¯ àªà«, àªªàª°àªàª€à« àªàªª àª€àª®àªŸàª°à« àªªàªžàªàªŠàªà«àªšà« àª­àªŸàª·àªŸ àªªàªžàªàªŠ àªàª°à« àª¶àªà« àªà«. àª¬à«àª°àªŸàªàªàª° àª§à«àªµàªŸàª°àªŸ àª®àªŸàª¹àª¿àª€à« àªàªàªàªªà«àª àª®àªŸàªà« àªà«àª°à«àªšàªžà«àªà«àªš àª§à«àªµàªŸàª°àªŸ àªàªªàª¯à«àªàª®àªŸàª àª²à«àª§à«àª² àªžàªàªà«àª€àª²à«àªàªš (àªàªšà«àªà«àª¡à«àªàª) àªžà«àªà«àª® àªªàª£ àª€àª®à« àª¬àªŠàª²à« (àªàª²à«àªàª°) àª¶àªà« àªà«. àªžà«àª«à«àªàªµà«àª° àªµàª¿àªµà«àªà« (àªžà«àªšà«àªžàª¿àª¬àª²) àª¡àª¿àª«à«àª²à«àª àªªàªžàªàªŠ àªàª°à« àªà«, àªªàª°àªàª€à« àªàª£àªŸ àª¬à«àª°àªŸàªàªàª°àª®àªŸàª àªªà«àª°àª®àªŸàª£àª­à«àª€ àªà«àª°à«àªà«àªàª° àªªà«àª°àªŠàª°à«àª¶àª¿àª€ àªàª°àªµàªŸ àªà«àªŠà« àª àªžàªàªà«àª€ àª²à«àªàªš (àªàªšà«àªà«àª¡à«àªàª) àª¯à«àªàªšàªŸ àªªàªžàªàªŠ àªàª°àªµà« àªàªµàª¶à«àª¯àª àªà«. àª¬àª§àªŸ àª àªžàªàªà«àª°àª¹à«àª®àªŸàª àªªà«àª°àª®àªŸàª£àª­à«àª€ àªà«àª°àªŸàª«àª¿àªàª² àªàªšà«àªàª°àª«à«àª¶ àª«à«àª°à«àª®à«àªàª®àªŸàªàª¥à« àªà«àªà«àªžà«àªà«àª¯à«àª
+àª² àª«à«àª°à«àª®à«àªàª®àªŸàª àªàªµàªŸàªšà« àªà«àªàªµàªŸàª àª¹à«àª¯ àªà«. àª àª®àªŸàª€à«àª° àªàªà«àª·à«àªµàª¿àª¹àª¿àªš àªàªªàª­à«àªà«àª€àªŸàª àª®àªŸàªà« àª àªàªªàª¯à«àªà« àªà« àªà« àªà«àª àªàªàªàªªà«àª àª®à«àª³àªµàªµàªŸ àª®à«àªàªŸ àª
+àªà«àª·àª°à« (àª«à«àªšà«àª) àª
+àª¥àªµàªŸ àªžà«àªªà«àª àªžàª¿àªšà«àª¥àª¿àªžàªŸàªàªàª°àªšà« àªàªªàª¯à«àª àªàª°à« àªà«.}  
+
+_texthelppresentationprefstitle_ [l=gu] {àªªà«àª°àªžà«àª€à«àª€àª¿ àªªàªžàªàªŠàªà«àª}  
+_texthelppresentationprefs_ [l=gu] {àªµàª¿àª¶à«àª· àªžàªàªà«àª°àª¹ àªªàª° àªàª§àªŸàª°àª¿àª€ àª€àª®à« àªàª£àªŸ àª¬àª§àªŸ àªµàª¿àªàª²à«àªªà« àªªàªžàªàªŠ àªàª°à« àª¶àªà« àªà« àªà« àªà« àªªà«àª°àªžà«àª€à«àª€àª¿ (àªªà«àª°à«àªàªšà«àªà«àª¶àªš) àªšà« àª
+àªàªà«àª¶ àªàª°àª€àªŸ àª¹à«àª¯.<p>àªŠàª°à«àª àªªàªŸàªšàªŸàªšà« àªà«àªàªšàªŸ àª­àªŸàªàªšà«àª àªà«àª°à«àªšàªžà«àªà«àªš àªšà«àªµà«àªà«àª¶àªš àª¬àªŸàª°àªšà« àªžàªàªà«àª°àª¹à«àªšàªŸ àªµà«àª¬ àªªà«àª àªà«àªªà«àª€ àª°àªŸàªà« àªà«, àªà«àª¥à« àªàª°à«àªšà« àª€àª®à« àªà«àª¯àªŸàª°à« àª¶à«àª§ àªàª°à« àªà« àª€à«àª¯àªŸàª°à« àª€àª®à« àªà«àª àªà«àªà«àªàªž àªµà«àª¬ àªªà«àª àªªàª° àªàªŸàªµ àªà« àªà«àª¯àªŸàª àª€àª®àªšà« àªà«àª°à«àªšàªžà«àªà«àªšàªšà« àª¹à«àª¡àª° àªŠà«àªàªŸàª€à« àªšàª¥à«. àª¬à«àªà« àª¶à«àª§ àªàª°àªµàªŸ àª®àªŸàªà« àª€àª®àªŸàª°à« àª¬à«àª°àªŸàªàªàª°àªšà« "àªªàªŸàªàª³" àª¬àªàªšàªšà« àªàªªàª¯à«àª àªàª°àªµà« àªªàª¡àª¶à«. àªà«àª¯àªŸàª°à« àª€àª®à« àª¡àª¿àªà«àªàª² àª²àªŸàªàª¬à«àª°à«àª°à« àªžàªàªà«àª°àª¹ àª
+àªšà« àªµà«àª¬àª®àªŸàª àª²àª àªàª€à« àª²à«àªàª àªªàª° àªà«àª²àª¿àª àªàª°à« àª€à«àª¯àªŸàª°à« àª àªžàªàªà«àª°àª¹ àªà«àª°à«àªšàªžà«àªà«àªšàªšà« àªà«àª€àªµàª£à« àªžàªàªŠà«àª¶àªšà« àªà«àªªà«àª€ (àªžàªªà«àª°à«àªž) àª°àªŸàªà« àªà«. àª
+àªšà« àª
+àª®à«àª àªµà«àª¬ àªžàªàªà«àª°àª¹à«àª®àªŸàª àª¶à«àª§ àªªàª°àª¿àª£àªŸàª® àªªà«àª·à«àª àªšà« àª²à«àªàª àª¡àª¿àªà«àªàª² àª²àªŸàªàª¬à«àª°à«àª°à«àªšà« àªªà«àª°àª€àª¿àª²àª¿àªªàª¿ àªªà«àª·à«àª àª®àªŸàª àª²àª àªàªµàªŸàªšà« àª¬àªŠàª²à« àªžà«àª§à« àªžà«àª§à« àªµàªŸàªžà«àª€àªµà«àª àª¯à«àªàª°àªàª² àª®àªŸàª àª²àª àªàªŸàª¯ àª€à«àªµà« àª
+àªàªà«àª¶ àª€àª®à« àªàª°à« àª¶àªà« àªà«.}  
+
+_texthelpsearchprefstitle_ [l=gu] {àªªàªžàªàªŠàªà«àª àª¶à«àª§à«}  
+_texthelpsearchprefs_ [l=gu] {<p>"àªàª¡àªµàªŸàªšà«àªž" àªà«àªµà«àª°à« àª°à«àª€ àª€àª®àªšà« & ("àª
+àªšà«"àª®àªŸàªà«), | ("àª
+àª¥àªµàªŸ"àª®àªŸàªà«), àª
+àªšà« ! ("àªšàª¹àª¿"àª®àªŸàªà«) àªšàªŸ àªàªªàª¯à«àª àª§à«àªµàªŸàª°àªŸ àªžàªàª¯à«àªà«àª€ àªªàªŠà«, àªà«àª¥àª®àªŸàª àª¶à«àª§ àªàª°àªµàªŸ àª®àªŸàªà« àªà«àªž (àªªà«àª°à«àªšà«àª¥àª¿àªžàª¿àªž) àªšà« àªàªªàª¯à«àª àªàª°àªµàªŸàªšà« àªžàªµàª²àª€ àªªà«àª°à« àªªàªŸàª¡à« àªà«. àªàªšàªŸ àª§à«àªµàªŸàª°àªŸ àª€àª®à« àªàªàªŠàª® àªà«àªà«àªàªž àªà«àªµà«àª°à« àªšàªà«àªàª¿ àªàª°à« àª¶àªà« àªà«. <p>_selectsearchtypeprefs_<p>_selectwordmodificationprefs_<p> àª€àª®à« àª¶à«àª§ àªàª€àª¿àª¹àªŸàªž àª²àªà«àª·àª£ (àª«à«àªàª°) àªªàª° àªàªŸàªµ àª€à«, àª
+àªàªŸàª àªàª°à«àª²à« àªà«àªµà«àª°à«àª®àªŸàªàª¥à« àª
+àª®à«àª àªà«àªµà«àª°à« àª€àª®àªšà« àª¬àª€àªŸàªµà« àªà«. àª àªžà«àªµàª¿àª§àªŸàª¥à« àª
+àªàªŸàªàªšà« àªà«àªµà«àª°à«àª®àªŸàª àª¥à«àª¡à« àª«à«àª°àª«àªŸàª° àªàª°à« àª¶à«àª§ àªàª°àªµàªŸàª®àªŸàª àªžàª°àª³ àªªàª¡à« àªà«.<p>àª
+àªàª€àª®àªŸàª àªà«àªàª²à« àªžàªàªà«àª¯àªŸàª®àªŸàª àªªàª°àª¿àª£àªŸàª®à« ( àª¹àª¿àª) àª®àª³à«àª¯àªŸ àª¹à«àª¯, àª
+àªšà« àªŠàª°à«àª àªžà«àªà«àª°à«àªš àªªàª° àªà«àªàª²àªŸ àªšàªàª¬àª° àªŠà«àªàªŸàª€àªŸ àª¹à«àª¯ àª€à«àªšà« àª€àª®à« àª
+àªàªà«àª¶àª¿àª€ àªàª°à« àª¶àªà« àªà«. }  
+
+_textcasefoldprefs_ [l=gu] {àª¶à«àª§ àªàª°àª€à« àªµàªàª€à« àª®à«àªàªŸ àª®à«àª³àªŸàªà«àª·àª°à« (àª
+àªªàª° àªà«àªž) àª
+àªšà« àªšàªŸàªšàªŸ àª®à«àª³àªŸàªà«àª·àª°à« (àª²à«àª
+àª° àªà«àªž) àª®à«àª àª¥àªŸàª¯ àª€à« àª
+àªàªà« àª¬àªàªšàªšà« àªàª àªà«àª¡à« àª€à«àªšà«àª àªšàª¿àª¯àªàª€à«àª°àª£ àªàª°à« àªà«. àªŠàªŸ.àª€. àªà« "_preferences:textignorecase_" àªªàªžàªàªŠ àªàª°àªµàªŸàª®àªŸàª àªàªµà«, àª€à«  <i>snail farming</i> àªšà« <i>SNAIL FARMING</i> àª€àª°à«àªà« àª
+àª°à«àª¥àªàªàªš àªàª°àªµàªŸàª®àªŸ àªàªµàª¶à«.}  
+_textstemprefs_ [l=gu] {àª¶à«àª§ àªàª°àª€à« àªµàªàª€à« àª¶àª¬à«àªŠàªšàªŸ àª
+àªàª€à«àªšàªŸ àª
+àªà«àª·àª°à«àªšà« àª
+àªµàªàª£àªšàªŸ àªàª°àªµà« àªà« àªšàª¹àª¿ àª€à«àªšà« àªžàªàªàªŸàª²àªš àª¬àªàªšàªšà« àªà«àª¡àªà«àª àªàª°à« àªà«. àªàªŠàªŸàª¹àª°àª£ àª€àª°à«àªà«, àªà« "_preferences:textstem_" àªªàªžàªàªŠ àªàª°àªµàªŸàª®àªŸàª àªàªµà« àª€à« <i>snail farming</i> àªšà« àª
+àª°à«àª¥àªàªàªš <i>snails farm</i> àª
+àªšà« <i>snail farmer</i> àª€àª°à«àªà« àª àª¥àª¶à«. àª¹àªŸàª²àª®àªŸàª àª àª®àªŸàª€à«àª° àª
+àªàªà«àª°à«àªà« àª­àªŸàª·àªŸàª®àªŸàª àª àªµà«àª¯àªµàªžà«àª¥àª¿àª€ àªàªŸàª® àªàª°à« àªà«. _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=gu] {àª¶à«àª§ àªàª°àª€à« àªµàªàª€à« àªàªà«àªàªŸàª° (àªàªžàªšà«àªà«àª¡) àª
+àªšà« àª
+àªšà«àªà«àªàªŸàª° (àª
+àªšàªàªžà«àªšà«àªà«àª¡) àªµàªŸàª³àªŸ àª
+àªà«àª·àª°à« àª®à«àª àª¥àªµàªŸ àªà«àªàª àª€à« àª
+àªàªà« àª¬àªàªšà«àªšà« àªàª àªà«àª¡à« àª€à«àªšà«àª àªšàª¿àª¯àªàª€à«àª°àª£ àªàª°à« àªà«. àªŠàªŸ.àª€. àªà« <i>fÃ©dÃ©ration</i> àªªàªžàªàªŠ àªàª°àªŸàª¯ àª€à« àª€à« <i>fedÃ©ration</i> àªšà« <i>federation</i>àª€àª°à«àªà« àª
+àª°à«àª¥àªàªàªš àªàª°àªµàªŸàª®àªŸ àªàªµàª¶à«.}  
+ 
+_textstemoptionsprefs_ [l=gu] {"_texthelpquerytermstitle_" àªàªªàª° àªŠàª°à«àª¶àªŸàªµà«àª² àª®à«àªàª¬ àª¶à«àª§ àªªàªŠ àªà«àª°à«àªà«àª¶àªš àªžàªµàª²àª€àªšà« àªàªªàª¯à«àª àªàª°àªµà« àªµàª§à«  àª
+àªšà«àªà«àª³ àª
+àªšà« àªà«àªà«àªàªž àª¹àª¶à«.}  
+
+_textsearchtypeprefsplain_ [l=gu] {àª®à«àªà« àªà«àªµà«àª°à« àª¬à«àªà«àªž àª¶àªà«àª¯ àªà«, àªà«àª¥à« àª€àª®à« àªàªà« àª«àªàª°à« àªà«àªµà«àª°à« àª¬à«àªà«àªžàª®àªŸàª àªàªŸàªàªª àªàª°à«àªšà« àªžàª°àª³ àª°à«àª€à« àª¶à«àª§ àªàª°à« àª¶àªà« àªà«. àª®à«àªàªŸ àªªà«àª°àª®àªŸàª£àª®àªŸàª àªà«àªà«àªžà«àª àª¶à«àª§àªµà« àª€à« àªµàª¿àªžà«àª®àª¯àªàªšàª àª°à«àª€à« àªàª¡àªªà« àªà«.}  
+
+_textsearchtypeprefsform_ [l=gu] {àª¶à«àª§ àª«à«àª°à«àª®àªšà« àª
+àªàªŠàª° àª¬àª€àªŸàªµà«àª²àªŸ àª«àª¿àª²à«àª¡àªšà« àªžàªàªà«àª¯àªŸàª®àªŸàª àª€àª®à« àª«à«àª°àª«àªŸàª° àªàª°à« àª¶àªà« àªà«.}  
+
+_textsearchtypeprefsboth_ [l=gu] {àª€àª®à« àªžàªàªà«àª°àª¹àªšàªŸ àª¶à«àª§ àªªà«àª°àªàªŸàª° àª®àªŸàªà« "àªžàªŸàª®àªŸàªšà«àª¯" àª¶à«àª§ àª
+àªšà« "àª«àª¿àª²à«àª¡ àªµàªŸàª³à«" àª¶à«àª§ àª¬àªàªšà« àª®àªŸàªàª¥à« àªªàªžàªàªŠàªà« àªàª°à« àª¶àªà« àªà«.<ul><li>àªšàª¿àª¯àª®àª¿àª€ (àªšà«àª°à«àª®àª²) àª¶à«àª§ àª«àªà«àª€ àªàª àªà«àªµà«àª°à« àª¬à«àªà«àªž àªªà«àª°à« àªªàªŸàª¡à« àªà«._textsearchtypeprefsplain_</li><li>àª°à«àª«àª¿àª²à«àª¡àªµàªŸàª³à« àª¶à«àª§ àªàª àªàª°àª€àªŸ àªµàª§àªŸàª°à« àªà«àªµà«àª°à« àª¬à«àªà«àªž àªªà«àª°àªŸ àªªàªŸàª¡à« àªà«, àª àªà«àªµà«àª°à« àª¬à«àªà«àªž àªšàª¿àª°à«àªŠàª¿àª¶àª¿àªàªŸàªšàªŸ àª
+àª²àª àª«àª¿àª²à«àª¡àª®àªŸàª àªŠàª°à«àª àªà«àªµà«àª°à« àªžàªàª€à«àª·à« àªà«, àªàªšàªŸ àª²à«àª§à« àªàª àªžàªŸàª¥à« àªà«àªŠàªŸ àªà«àªŠàªŸ àª«àª¿àª²à«àª¡àªšàªŸ àªàªªàª¯à«àªàª¥à« àª¶à«àª§ àªàª°à« àª¶àªàªŸàª¯ àªà«. _textsearchtypeprefsform_ </li></ul>}  
+
+
+
+_texttanumbrowseoptions_ [l=gu] {àª àªžàªàªà«àª°àª¹àª®àªŸàª àª®àªŸàª¹àª¿àª€à« àª¶à«àª§àªµàªŸ àª®àªŸàªà« _numbrowseoptions_ àªµàª¿àªàª²à«àªªà« àªà«:}  
+
+_textsimplehelpheading_ [l=gu] {_collectionname_ àªžàªàªà«àª°àª¹àª®àªŸàªàª¥à« àª®àªŸàª¹àª¿àª€à« àªà«àªµà« àª°à«àª€à« àª®à«àª³àªµàªµà«}  
+
+_texthelpscopetitle_ [l=gu] {àªà«àªµà«àª°à«àªšà« àª
+àªµàªàªŸàª¶ }  
+_texthelpscope_ [l=gu] {<p>àª®à«àªàªŸ àª­àªŸàªàªšàªŸ àªžàªàªà«àª°àª¹à«àª®àªŸàª àª¶à«àª§ àªàª°àªµàªŸ àªà«àªŠàªŸ àªà«àªŠàªŸ àªªà«àª°àªàªŸàª°àªšà« àªšàª¿àª°à«àªŠà«àª¶àª¿àªàªŸàªàªšà« àªªàªžàªàªŠàªà«àªšà« àª
+àªµàªàªŸàª¶ àª€àª®àªšà« àªàªªàªµàªŸàª®àªŸàª àªàªµà« àªà«. àªàªŠàªŸàª¹àª°àª£ àª€àª°à«àªà«, àª€à«àª®àªŸàª àªà«àª°àª°à«àª€àªŸ àªšàª¿àª°à«àªŠà«àª¶àª¿àªàªŸ àª
+àª¥àªµàªŸ àª¶àª¿àª°à«àª·àª àªšàª¿àª°à«àªŠà«àª¶àª¿àªàªŸ àª¹à«àª àª¶àªà«. àª
+àª¥àªµàªŸ àª€à«àª®àªŸàª àªªà«àª°àªàª°àª£ àªšàª¿àª°à«àªŠà«àª¶àª¿àªàªŸ àª
+àª¥àªµàªŸ àª«àªàª°àªŸàªšà« àªšàª¿àª°à«àªŠà«àª¶àª¿àªàªŸ àª¹à«àª àª¶àªà«. àªžàªŸàª®àªŸàªšà«àª¯ àª°à«àª€à«, àª€àª®à« àª¶à«àª§ àª®àªŸàªà« àªàª àªšàª¿àª°à«àªŠà«àª¶àª¿àªàªŸàªšà« àªàªªàª¯à«àª àªàª°à«àª¯à« àªà« àª€à«àªšà« àªªàª°àªµàªŸ àªàª°à«àª¯àªŸ àªµàª¿àªšàªŸ àªžàªàªªà«àª°à«àª£ àª®à«àªàª¿àªàª àªªà«àª°àª²à«àª àª€àª®àªšà« àªà«àªµàªŸ àª®àª³àª¶à«.<p>àªà« àªªà«àª°àª²à«àªà« àªªà«àªžà«àª€àªà«àªšàªŸ àªžà«àªµàª°à«àªªàª®àªŸàª àª¹à«àª¯ àª€à«, àª€à« àªªà«àª°àª²à«àªà« àª¯à«àªà«àª¯ àªàªà«àª¯àªŸàª àª àªà«àª²àª¶à«.}  
Index: /gsdl/stable/macros/hebrew.dm
===================================================================
--- /gsdl/stable/macros/hebrew.dm	(revision 20131)
+++ /gsdl/stable/macros/hebrew.dm	(revision 20131)
@@ -0,0 +1,721 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Hebrew Language text and icon macros 
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textperiodicals_
+
+# these three used by the default format statement of the demo and dls collections.
+# -- Missing translation: _textsource_
+# -- Missing translation: _textdate_
+# -- Missing translation: _textnumpages_
+
+# -- Missing translation: _textsignin_
+
+_textdefaultcontent_ [l=he] {Greenstone Digital Library  ×××¡×× ×××××§×© ×× × ××Š×. × × ×××××¥ ×¢× ××€×ª××š "××××š×" ×××€××€× ×× ××€×ª××š ×"×××ª" ××× ×××××š × }
+
+_textdefaulttitle_ [l=he] {GSDL ××¢××ª }
+
+# -- Missing translation: _textbadcollection_
+
+# -- Missing translation: _textselectpage_
+
+_collectionextra_ [l=he] {×××× _about:builddate_ ××××¡×£ × ×× × ××€× × 
+ ××¡×××× _about:numdocs_ ××××¡×£ ××××  }
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=he] {<p> ××ª×× _numbytes_ ×¡×"×    _If_("_numdocs_" eq "1",××¡××,××¡××××),_numdocs_ ××××¡×£ ×××× ××××¢ ××××× }
+
+_textdescrcollection_ [l=he] {}
+_textdescrabout_ [l=he] {×¢× ×××ª×š}
+_textdescrhome_ [l=he] {×¢××× ××××ª}
+_textdescrhelp_ [l=he] {××£ ×¢××š}
+_textdescrpref_ [l=he] {××£ ××××š××ª}
+_textdescrgreenstone_ [l=he] {Greenstone  ×¡×€×š×××ª }
+# -- Missing translation: _textdescrusab_
+
+
+# Metadata names and navigation bar labels
+
+# -- Missing translation: _textSearch_
+_labelSearch_ [l=he] {××€×©}
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _textTitle_
+_labelTitle_ [l=he] {×××ª×š××ª ×-×ª}
+# -- Missing translation: _textCreator_
+_labelCreator_ [l=he] {××××š×× ×-×ª}
+# -- Missing translation: _textSubject_
+_labelSubject_ [l=he] {× ××©×××}
+# -- Missing translation: _textDescription_
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _textPublisher_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _textContributor_
+# -- Missing translation: _labelContributor_
+# -- Missing translation: _textDate_
+_labelDate_ [l=he] {×ª××š××××}
+# -- Missing translation: _textType_
+# -- Missing translation: _labelType_
+# -- Missing translation: _textFormat_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _textIdentifier_
+# -- Missing translation: _labelIdentifier_
+# -- Missing translation: _textSource_
+# -- Missing translation: _labelSource_
+# -- Missing translation: _textLanguage_
+_labelLanguage_ [l=he] {×©×€×}
+# -- Missing translation: _textRelation_
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _textCoverage_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _textRights_
+# -- Missing translation: _labelRights_
+
+# DLS metadata set
+# -- Missing translation: _textOrganization_
+# -- Missing translation: _labelOrganization_
+# -- Missing translation: _textKeyword_
+# -- Missing translation: _labelKeyword_
+# -- Missing translation: _textHowto_
+# -- Missing translation: _labelHowto_
+
+# Miscellaneous Greenstone metadata
+# -- Missing translation: _textPhrase_
+_labelPhrase_ [l=he] {×××××××}
+# -- Missing translation: _textCollage_
+# -- Missing translation: _labelCollage_
+# -- Missing translation: _textBrowse_
+# -- Missing translation: _labelBrowse_
+# -- Missing translation: _textTo_
+_labelTo_ [l=he] {××¢×}
+# -- Missing translation: _textFrom_
+_labelFrom_ [l=he] {××§××š}
+# -- Missing translation: _textAcronym_
+_labelAcronym_ [l=he] {×š××©× ×ª××××ª}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+# -- Missing translation: _textdescrdefault_
+
+_textdescrSearch_ [l=he] {××€×© ××× ××× ××××××§××}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrIdentifier_
+# -- Missing translation: _textdescrSource_
+_textdescrTo_ [l=he] {××€××£ ××€× ×¡××š ×××¢×}
+_textdescrFrom_ [l=he] {××€××£ ××€× ×¡××š ××§××š××ª}
+# -- Missing translation: _textdescrCollage_
+_textdescrAcronym_ [l=he] {××€××£ ×š××©× ×ª××××ª}
+_textdescrPhrase_ [l=he] {××€××£ ××××××××}
+_textdescrHowto_ [l=he] {××€××£ ××€× ×¡××š ×××Š×}
+_textdescrBrowse_ [l=he] {××€××£}
+_texticontext_ [l=he] {××Š× ××ª ×××¡××}
+_texticonclosedbook_ [l=he] {×€×ª× ××ª ×××¡×× ×××Š× ××ª ×ª××× ×}
+_texticonnext_ [l=he] {××××§ ×××}
+_texticonprev_ [l=he] {××××§ ××§×××}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=he] {MIDI - ××Š× ××ª ××¡×× ×}
+_texticonmsword_ [l=he] {Word - ××Š× ××ª ××¡×× ×}
+_texticonmp3_ [l=he] {MP3 - ××Š× ××ª ××¡×× ×}
+_texticonpdf_ [l=he] {PDF - ××Š× ××ª ××¡×× × }
+_texticonps_ [l=he] {PS - ××Š× ××ª ××¡×× ×}
+_texticonppt_ [l=he] {PPT - ××Š× ××ª ××¡×× ×}
+_texticonrtf_ [l=he] {RTF - ××Š× ××ª ××¡×× ×}
+_texticonxls_ [l=he] {XLS - ××Š× ××ª ××¡×× ×}
+
+_page_ [l=he] {×¢×××}
+_pages_ [l=he] {×¢×××××}
+_of_ [l=he] {×××§××š ×××}
+_vol_ [l=he] {××š×}
+_num_ [l=he] {××¡×€×š}
+
+_textmonth00_ [l=he] {}
+_textmonth01_ [l=he] {×× ×××š}
+_textmonth02_ [l=he] {×€××š×××š}
+_textmonth03_ [l=he] {××š×¥}
+_textmonth04_ [l=he] {××€×š××}
+_textmonth05_ [l=he] {×××}
+_textmonth06_ [l=he] {××× ×}
+_textmonth07_ [l=he] {××××}
+_textmonth08_ [l=he] {×××××¡×}
+_textmonth09_ [l=he] {×¡×€××××š}
+_textmonth10_ [l=he] {×××§××××š}
+_textmonth11_ [l=he] {× ×××××š}
+_textmonth12_ [l=he] {××Š×××š}
+
+_textdocument_ [l=he] {××¡××}
+_textsection_ [l=he] {×××§}
+_textparagraph_ [l=he] {×€××¡×§×}
+
+_magazines_ [l=he] {××š×××}
+
+_nzdlpagefooter_ [l=he] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}
+
+_linktextHOME_ [l=he] {××××¢ ×ª×××}
+_linktextHELP_ [l=he] {××š××¢}
+_linktextPREFERENCES_ [l=he] {×ª××××€×××¢}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+# -- Missing translation: _textpagetitle_
+# -- Missing translation: _textadmin_
+# -- Missing translation: _textabgs_
+# -- Missing translation: _textgsdocs_
+
+# -- Missing translation: _textdescradmin_
+
+# -- Missing translation: _textdescrgogreenstone_
+
+# -- Missing translation: _textdescrgodocs_
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+# -- Missing translation: _textgli_
+# -- Missing translation: _textdescrgli_
+
+package collector
+
+# -- Missing translation: _textcollector_
+# -- Missing translation: _textdescrcollector_
+
+package depositor
+
+# -- Missing translation: _textdepositor_
+# -- Missing translation: _textdescrdepositor_
+
+package gti
+
+# -- Missing translation: _textgti_
+# -- Missing translation: _textdescrtranslator_
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textabcol_
+
+# -- Missing translation: _textsubcols1_
+
+# -- Missing translation: _textsubcols2_
+
+_titleabout_ [l=he] {××¢}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=he] {×¡×××š ××ª ××××§ ××× ×©× ××¡×€×š×××}
+_texticonclosedbookshelf_ [l=he] {×€×ª× ××ª ××××§ ××× ×©× ××¡×€×š××× ×××Š× ××ª ×ª××× ×}
+_texticonopenbook_ [l=he] {×¡×××š ××ª ××¡×€×š}
+_texticonclosedfolder_ [l=he] {×€×ª× ××ª ××ª××§××× ×××Š× ××ª ×ª××× ×}
+_texticonclosedfolder2_ [l=he] {×€×ª× ××ª ××ª×ª-×××§}
+_texticonopenfolder_ [l=he] {×¡×××š ××ª ××ª××§×××}
+_texticonopenfolder2_ [l=he] {×¡×××š ××ª ××ª×ª-×××§}
+_texticonsmalltext_ [l=he] {××Š× ××ª ××××§ ××× ×©× ×××§×¡×}
+_texticonsmalltext2_ [l=he] {××Š× ××§×¡×}
+_texticonpointer_ [l=he] {×××§ × ××××}
+_texticondetach_ [l=he] {×€×ª× ××ª ××¢××× ××××× ×××©}
+_texticonhighlight_ [l=he] {××××© ××× ×× ×××€××©}
+_texticonnohighlight_ [l=he] {×× ×ª××××© ××× ×× ×××€××©}
+_texticoncontracttoc_ [l=he] {×Š××Š× ×ª××× ×¢×× ××× ××}
+_texticonexpandtoc_ [l=he] {××Š× ×ª××× ×¢×× ××× ××}
+_texticonexpandtext_ [l=he] {××Š× ××ª ×× ×××§×¡×}
+_texticoncontracttext_ [l=he] {××Š× ××§×¡× ×š×§ ×¢×××š ××××§ ×××¡×××}
+_texticonwarning_ [l=he] {<b> ××××š× : /<b>}
+_texticoncont_ [l=he] {?××××©××}
+
+_textltwarning_ [l=he] {<div class="buttons">_imagecont_</div>
+_iconwarning_  ××Š××ª ×××§×¡× ××× ×××Š××š ××××ª ××××× 
+×©× × ×ª×× ×× ×××Š×× ×××€××€×
+}
+
+_textgoto_ [l=he] {×× ××¢×××}
+_textintro_ [l=he] {<i>  (××××) </i> }
+
+_textCONTINUE_ [l=he] {" ×××©×××}
+
+_textEXPANDTEXT_ [l=he] {××××š××\n××¡×§×}
+
+_textCONTRACTCONTENTS_ [l=he] {×¥××××\n×ª× ××××ª×}
+
+_textDETACH_ [l=he] {×§×ª× ×}
+
+_textEXPANDCONTENTS_ [l=he] {××××š××\n×ª× ××××ª×}
+
+_textCONTRACT_ [l=he] {×¥××××\n×ª× ××¡×§××}
+
+_textHIGHLIGHT_ [l=he] {××©×××}
+
+_textNOHIGHLIGHT_ [l=he] {×××\n××©×××}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=he] {_If_(thislast_,×ª××Š×××ª _thisfirst_ - _thislast_ ××©××××ª× : _cgiargq_, ×××  ××¡×××× ×××× ××©××××ª×: _cgiargq_)}
+_textnoquerytitle_ [l=he] {×××€××© ××£}
+
+_textsome_ [l=he] {×××××}
+_textall_ [l=he] {××××× ×}
+_textboolean_ [l=he] {×××}
+_textranked_ [l=he] {×××§}
+_textnatural_ [l=he] {×××}
+# -- Missing translation: _textsortbyrank_
+_texticonsearchhistorybar_ [l=he] {××¡×××š×××ª ×××€××©}
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+_textusequery_ [l=he] {×©×ª××© ××©××××ª× ××××ª}
+_textfreqmsg1_ [l=he] {:×¡×€××š×ª ×××××}
+_textpostprocess_ [l=he] {_If_(_quotedquery_,<br><i>××××š ×××××_quotedquery_</i>)}
+# -- Missing translation: _textinvalidquery_
+# -- Missing translation: _textstopwordsmsg_
+# -- Missing translation: _textlucenetoomanyclauses_
+
+_textmorethan_ [l=he] {-  ×××ª×š × }
+_textapprox_ [l=he] {××}
+_textnodocs_ [l=he] {××©××××ª× ××× ×ª×©××××ª}
+_text1doc_ [l=he] {×ª×©××× ×××ª ××× ××©××××ª×}
+_textlotsdocs_ [l=he] {×ª×©××××ª ××ª×××××ª ××©××××ª×}
+_textmatches_ [l=he] {× ××Š×× ××ª××××ª}
+_textbeginsearch_ [l=he] {××ª×× ×××€××©}
+_textrunquery_ [l=he] {××š×¥ ×©××××ª×}
+_textclearform_ [l=he] {× ×§× ×××€×¡}
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=he] {×××× ×× ×××××}
+_textinfield_ [l=he] {...××©××}
+_textfoldstem_ [l=he] {××××©×× ××××€××©, ××¢×Š××š }
+
+_textadvquery_ [l=he] {×× ××× ×¡ ××ª ××©××××ª× ××©××š××ª:}
+_textallfields_ [l=he] {×× × ×©×××ª}
+# -- Missing translation: _texttextonly_
+_textand_ [l=he] {×××}
+_textor_ [l=he] {××}
+_textandnot_ [l=he] {×××}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=he] {××€×© ××ª _indexselection_ _If_(_jselection_, ×©× _jselection_) _If_(_gselection_, _gselection_ ××š××) _If_(_nselection_, _nselection_ ××©×€×) _querytypeselection_ ××©×š ×××××ª ×××××}
+
+_textadvancedsearch_ [l=he] {××€×© ××ª _indexselection_ _If_(_jselection_, ×©×) _jselection_) _If_(_gselection_, _gselection_ ××š××)_If_(_nselection_, _nselection_ ××©×€×)  _querytypeselection_ ××©××××© ×©× ×©×××××}
+
+# -- Missing translation: _textadvancedmgppsearch_
+
+# -- Missing translation: _textadvancedlucenesearch_
+
+_textformsimplesearch_ [l=he] {××€×© ××ª _If_(_jselection_, _jselection_) _If_(_gformselection_, _gformselection_ ××š××) _If_(_nselection_, _nselection_ ××©×€×)
+_formquerytypesimpleselection_ ××©×š ×××××ª ××ª}
+
+# -- Missing translation: _textformadvancedsearchmgpp_
+
+# -- Missing translation: _textformadvancedsearchlucene_
+
+# -- Missing translation: _textnojsformwarning_
+_textdatesearch_ [l=he] {××××€×¡ ××× × ××ª× ×××€×© ×××š ××¡×××× ××ª×§××€× ××¡×××××ª ×× ×××× ××××××× ×ª××š×× ××¡××××. ×× ×××§ ×××€×Š××× ×× ×××××€××©}
+_textstartdate_ [l=he] {×ª××š×× (×× ×š×§ ) ××ª×××}
+_textenddate_ [l=he] {×ª××š××  ×¡×××:}
+_textbc_ [l=he] {××€× × ××¡×€××š×}
+_textad_ [l=he] {××¡×€××š×}
+_textexplaineras_ [l=he] {×××ª××.C.E. -× B.C.E -×   A.D. -×  B.C. ××××¡×§×, ××©××× ×××× ××ª ××××××× ××ª×š×××ª× ×××¡×× ××ª ××€× × ××××š× ××¡×€××š× 
+ ××× ××©××©×× × -  "××¡×€××š×" ×-"××€× × ××¡×€××š×" ×××ª×××}
+
+_textstemon_ [l=he] {(××ª×¢××  ××¡××××ª ×©× ××××× )}
+
+_textsearchhistory_ [l=he] {××¡×××š×××ª ×××€××©}
+
+#text macros for search history
+_textnohistory_ [l=he] {×××¡×××š×××ª ×××€××© ×× ×××× ×}
+_texthresult_ [l=he] {×ª××Š××}
+_texthresults_ [l=he] {×ª××Š×××ª}
+_texthallwords_ [l=he] {×× ××××××}
+_texthsomewords_ [l=he] {××§ ×©× ××××××}
+_texthboolean_ [l=he] {××××× ×}
+_texthranked_ [l=he] {×××××}
+_texthcaseon_ [l=he] {×××× ×××ª×××  ×××× ××××ª×××ª}
+_texthcaseoff_ [l=he] {×©×××š ×¢× ×××× ×××××}
+_texthstemon_ [l=he] {× ×¢×Š×š}
+_texthstemoff_ [l=he] {×××©×× ××× ×¢×Š××š×}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=he] {××¢×××€××××ª ×××××š× ××¡××š ××× :
+ ×©× ××€××€× "back" ×× ×ª×©×ª××© ×××€×××š 
+×× ×××× ×××ª× !  ×××§×× ×××ª ×ª×××Š× ×¢× ××€×ª××š×× ××¡×š×× ×××©× ×××¢××}
+_textsetprefs_ [l=he] {××××š×ª ×¢×××€××××ª}
+_textsearchprefs_ [l=he] {×××€××© ×¢×××€××××ª}
+_textcollectionprefs_ [l=he] {×××¡×£ ×¢×××€××××ª}
+_textpresentationprefs_ [l=he] {×ª×Š×××ª ×¢×××€××××ª}
+_textpreferences_ [l=he] {×¢×××€××××ª}
+_textcasediffs_ [l=he] {××××× ×××ª×××ª ×§×× ××ª/××××××ª}
+_textignorecase_ [l=he] {××ª×¢×× ×××××× ×××ª×××ª ×§×× ××ª/××××××ª}
+_textmatchcase_ [l=he] {×××× ×××ª×××ª ×Š×š×× ×××××ª ××ª×××}
+_textwordends_ [l=he] {×¡×××××ª ×××××}
+_textstem_ [l=he] {×××ª×¢×× ××¡××××ª ×××××}
+_textnostem_ [l=he] {×××× ×©××× ×Š×š××× ×××ª×××}
+# -- Missing translation: _textaccentdiffs_
+# -- Missing translation: _textignoreaccents_
+# -- Missing translation: _textmatchaccents_
+
+_textprefop_ [l=he] {×§××©××š×× _maxdocoption_ ××××š ×¢× }
+_textextlink_ [l=he] {××××Š×× ××× Web ×××©× ×××€×× }
+_textintlink_ [l=he] {××§××š××ª ×××€×¡×× ×××××š× ×  }
+_textlanguage_ [l=he] {:×©×€×ª ×××©×§}
+_textencoding_ [l=he] {:×§××××}
+_textformat_ [l=he] {:×€××š×× ××××©×§}
+_textall_ [l=he] {×××}
+_textquerymode_ [l=he] {×¡×× ××©××××ª×}
+_textsimplemode_ [l=he] {×¡×× ×€×©×× ×©× ××©××××ª×}
+_textadvancedmode_ [l=he] {×¡×× ××ª×§×× ×©× ××©××××ª× ×××©×š ×©××××© ××××€××© ××××× × ×¢× ×©××××© ×- !,&,| ××¡×××š×××}
+_textlinkinterm_ [l=he] {××š× ××£ ×××ª×××}
+_textlinkdirect_ [l=he] {×¢×××š ××©×š ××©×}
+_textdigitlib_ [l=he] {×¡×€×š××× ××××××××ª}
+_textweb_ [l=he] {××š×©×ª}
+_textgraphical_ [l=he] {××š×€×}
+_texttextual_ [l=he] {×××××}
+_textcollectionoption_ [l=he] {<p>
+×ª×ª ××××¡×€××  ××××<br>}
+
+# -- Missing translation: _textsearchtype_
+# -- Missing translation: _textformsearchtype_
+# -- Missing translation: _textplainsearchtype_
+# -- Missing translation: _textregularbox_
+# -- Missing translation: _textlargebox_
+
+_textrelateddocdisplay_ [l=he] {××Š× ××€×¡×× ×§×©××š××}
+_textsearchhistory_ [l=he] {:××¡×××š×××ª ×××€××©}
+# -- Missing translation: _textnohistory_
+_texthistorydisplay_ [l=he] {×××Š×× ××¡×××š×××ª ×××€××©}
+_textnohistorydisplay_ [l=he] {×× ×××Š×× ××¡×××š×××ª ×××€××©}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+# -- Missing translation: _textsortby_
+# -- Missing translation: _textalsoshowing_
+# -- Missing translation: _textwith_
+_textdocsperpage_ [l=he] {××€×¡×× ××£ ×××š× ××£}
+
+_textfilterby_ [l=he] {××€××£ ×š×§ ××ª ×××¡×××× ×××××××}
+_textall_ [l=he] {××ª ×××}
+_textany_ [l=he] {×××§}
+_textwords_ [l=he] {××××××}
+# -- Missing translation: _textleaveblank_
+
+_browsebuttontext_ [l=he] {××€××£}
+
+# -- Missing translation: _nodata_
+# -- Missing translation: _docs_
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=he] {×¢××š×}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=he] {××§×××ª ×××× ××××§×©×ª ××××§×¡× ××©××š×ª ××××€××© ×××××Š× ×¢× ××€×ª××š _labelSearch_ }
+
+_textSearchhelp_ [l=he] {××Š××ª ××¡×××× ××€× ×¡××× ×¢× ××× _1_ ××××Š× ×¢× ××€×ª××š _2_ }
+# -- Missing translation: _textTohelp_
+# -- Missing translation: _textFromhelp_
+# -- Missing translation: _textBrowsehelp_
+# -- Missing translation: _textAcronymhelp_
+# -- Missing translation: _textPhrasehelp_
+
+_texthelptopicstitle_ [l=he] {× ××©×××}
+
+_textreadingdocs_ [l=he] {××× ××§×š×× ××¡××××}
+
+_texthelpreadingdocs_ [l=he] {<p>××€×©×š ×××¢×ª ×× ×××¢×ª ×××¡×× ×××× ××××× ×©××××ª×š×ª ××××××š
+×××€××¢×× ××€×× × ×©×××××ª ×¢×××× × ×©× ××¢×××. ×××¥ ××× ××© ××ª ××¡×€×š  ××¢×××
+×× ××××, ×ª××× ××××€×©×š×ª ××××š×ª ×¢××× ×××© ×××Š×× ×§×××× ×××××š×
+
+<p> ××ª××ª ××© ××ª ×××§×¡× ×©× ××§××¢ ×× ××××. ××××š ×©×§×š××ª ×××ª×
+××ª××ª××ª ××¢××× ××©× × ××€×ª××š×× ×©××§×× ×××ª× ××¢××× ××× ×× ××¢××× ××§×××
+
+<p>××ª××ª ××××ª×š×ª ××××××š ××©× × ×©×××©× ××€×ª××š××. ×××¥ ×¢×
+ ××× ××€×ª×× ××ª ×× ×××§×¡× ×©×××¡××.<i> ××š×× ××§×¡× </i> 
+×× ×××¡×× ××××, ××××š ×××× ××§××ª ××š×× ××× ×××××š××!
+××× ××€×ª×× ×××× ×××© ×¢× ×××¡××..<i>××€×š×  </i> ×××¥ ×¢× 
+××××š ×©××××©× ×××©××××ª ××¡×××× ×× ×§×š××× ×©× ××× ×××§×××
+<i> ××× ××××©× </i> ×× ××¡×£ ×××××ª ××××€××© ×××××©××ª. ×××¥ ×¢×
+××× ×××€×¡××§ ××ª ×××××©×
+}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=he] {×€×ª× ××ª ×××£ ××¡×€×š××}
+_texthelpopenbook_ [l=he] {×€×ª×/×¡×××š ××ª ××¡×€×š}
+_texthelpviewtextsection_ [l=he] {×Š×€× ××××§ ××× ×©× ×××¡××}
+_texthelpexpandtext_ [l=he] {××Š×/×× ×ª×Š×× ××ª ×××§×¡× ××××}
+_texthelpexpandcontents_ [l=he] {×× ×¡ ××ª×××}
+_texthelpdetachpage_ [l=he] {×€×ª× ×¢××× ×× ××××× ×××©}
+_texthelphighlight_ [l=he] {××× ×× ×××€××© ×××××©××/×× ×××××©××}
+_texthelpsectionarrows_ [l=he] {×¢×××š ××€×š×§ ×××/××§×××}
+
+
+_texthelpsearchingtitle_ [l=he] {××× ×××Š×× ××××× ××¡××××××ª }
+
+_texthelpsearching_ [l=he] {<p>
+ :××¢××× ××©××××ª× , ×××××š×× ××ª ××©××××ª× ×××¡×€×š ×Š×¢××× ×€×©××××<p>
+  
+<ol><li>××××š ×××× ×¡××× ×€×š×××× ××© ×××€×©
+<li>×¡×× ×× ××ª× ×š××Š× ×××€×© ××ª ×× ×××××× ×× ×š×§ ×××§ ×××
+      <li>××§×× ××ª ×××××ª ××××€××©
+      <li> <i> ××ª×× ×××€××© </i> ×××¥ ×¢× ××€×ª××š
+</ol>
+
+
+<p>××©××ª× ××€×¢×× ××ª ××©××××ª× , ××××ª×š××ª ×©× ×¢×©×š×× ××€×š×××× ××ª××××× ×××Š××.
+××©× ×××× 2 ××€×ª××š×× ×××× ××¢×©×š×× ××€×š×××× ××××× ×××©× × ××¢×©×š×× ××€×š×××× ××§××××× ××¡××£ ××¢××× ××©× × ××€×ª××š ×©××§× ×××ª× ××¢×©×š×× ××€×š×××× ×××××
+
+
+<p>×××§×¡×××× ×©× ×€×š×××× ×©×××××š× ××× 100
+<i> ×¢×××€××××ª</i> ××€×©×š ××©× ××ª ××ª ×××¡×€×š ×¢"× ××××Š× ×¢× ××€×ª××š
+××ª××××ª  ××¢×××<p>
+}
+
+# -- Missing translation: _texthelpquerytermstitle_
+_texthelpqueryterms_ [l=he] {<p>×× ×©×××× ×¡ ×××§×¡× ××©××××ª× ×××¢×× ××š×©××× ×©× ××××× 
+×× ×§×š×××ª "××× ×× ×××€××©". ×× ××× × ×××× ×š×§ ×××ª×××ª ×××¡×€×š××. 
+×××× ××× ×××€×š××× ×¢"× ×š×××. ×× ×¡××× × ×€××¡××§ ×××€××¢××ª ××ª×× ××××××, ××
+××©××©××ª ××š×××, ×××××š ××× ××ª×¢×××× ×××. ×× ××€×©×š ×××€×© ××××× 
+×××××××ª ×¡××× × ×××€××© 
+
+
+<p>×××××× ××©××××ª×<p>
+<ul><kbd>××§××××ª ×××× ××××§×× ××¡ ××©×§×: ××¢×š×××ª × ×ª××××ª (1993)</kbd></ul>
+<p>×ª×¢××× ×××××§ ×××<p>
+<ul><kbd> ××§××××ª ×××× ××××§×× ××¡ ××©×§× ××¢×š×××ª × ×ª××××ª 1993</kbd></ul><p>
+}
+
+# -- Missing translation: _texthelpmgppsearching_
+
+# -- Missing translation: _texthelplucenesearching_
+
+_texthelpquerytypetitle_ [l=he] {×¡××× ×©××××ª××ª}
+_texthelpquerytype_ [l=he] {<p>××©× × ×©× × ×¡××× ×©××××ª××ª
+
+<ul>
+  <li> ××××××. ××©××××ª××ª <b> ××</b> ×©××××ª××ª ×¢×××š
+	×××× ×××€×©××ª ×××š ××€×š×××× ××××××× ××ª ×× ××××××
+	××€×š×××× ×××Š××× ××¡××š ×"×
+<p>
+
+<li> ×××××××. ××©××××ª××ª <b> ×××§</b> ×©××××ª××ª ×¢×××š
+	×××× ×××€×©××ª ×××š ××€×š×××× ××××××× ××ª ×× ××××××
+	××€×š×××× ×××Š××× ××¡××š ×××ª××× ××©××××ª×
+      <p><ul>
+<li> ×€×š×××× ××××××× ×××ª×š ××× ×× ×××€××© ×× ×××ª××××× ×××ª×š 
+<li> ××× ××× × ×××š×× ××©×××× ×××ª×§ ×××©×š ×š××××× 
+<li> ××¡×××× ×§×Š×š×× ××ª××××× ×××ª×š ×××©×š ××š××××
+</ul>
+</ul>
+
+<p>××©×ª××© ×××× ××× ×× ×××€××© ×©× ×× ××- ××©×€× ×× ××€××× ×€××¡×§×
+×× ×××× ×š×§ ××× × ×××€××© ××××, ×××¡×××× ××¡×××š× ××€× ××¡×€×š ××××€×¢×× ×©× ××× × ××××€××©
+<p>
+}
+
+# -- Missing translation: _texthelpadvancedsearchtitle_
+
+# -- Missing translation: _texthelpadvancedsearch_
+
+# -- Missing translation: _texthelpadvsearchmg_
+
+# -- Missing translation: _texthelpbooleansearch_
+
+# -- Missing translation: _texthelpadvsearchmgpp_
+
+# -- Missing translation: _texthelpadvancedsearchextra_
+
+# -- Missing translation: _texthelpadvsearchlucene_
+
+# -- Missing translation: _texthelpformsearchtitle_
+
+# -- Missing translation: _texthelpformsearch_
+
+# -- Missing translation: _texthelpformstemming_
+
+_textdatesearch_ [l=he] {×××€××© ×¢× ×ª××š××××}
+
+_texthelpdatesearch_ [l=he] {×××€××© ×¢× ×ª××š×××× × ××ª× ××€×©×š××ª ××§×× ×€×š×××× ××©×š ×××¥ ××× ×©××ª×××××
+×××× ×× ×××€××© ×× ××©×ª××××× ×××× ××¡××××. ××€×©×š ×××€×© ××€× ×©× × ××¡×××××ª ×× ×š×Š×£ ×©× ×©× ××
+××€×©×š ×××ª×©××© ××××€××© ××€× ×ª××š×× ×× ××× ××× ×× ×××€××©: ××€×š×××× ×©×××××š× ××©×ª×××× ××š×Š×£ ×××× ××××××š
+×× ××©×ª××©×× ××××€××© ×š××× ××× ×××€××© ××€× ×ª××š×× ××€×š×××× ×©×××××š× ×××××š× ××× ×ª×××ª ××ª××š××
+<p>
+}
+
+_texthelpdatehowtotitle_ [l=he] {××× ×××©×ª××© ××××€××©}
+_texthelpdatehowto_ [l=he] {<ul>
+<p><li>×××€×© ×××š ××¡×× ××©× × ××¡×××××ª
+<ul>
+<li>××× ×¡ ××× ×× ×××€××© ××š×××     
+<li>××× ×¡ ×©× × ×š×Š×××× × ×××× "××ª×××"
+<li>×× ××©× × ××× ××€× ×"×¡ , ×¡×× ××€× ×"×¡ ××š×©×××ª ×××××× 
+<li>××ª×× ××××€××© ××š×××
+</ul>
+<p><li>:×××€×© ××¡×× ××©× ××<p>
+   <ul>
+       <li> ××× ×¡ ××× ×× ×××€××© ××š×××
+<li> "××× ×¡ ×©× ×ª ××ª××× ×š×Š×××× × ×××× "××ª×××
+<li> ××× ×¡ ×©× ×ª ×¡××× ×š×Š×××× × ×××× "×¡××£"
+<li> ×× ××©× × ××× ××€× ×"×¡ , ×¡×× ××€× ×"×¡ ××š×©×××ª ××××××
+<li> ××ª×× ××××€××© ××š××× 
+</ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=he] {××š× ×©×× ××××€××© ×€××¢×}
+_texthelpdateresults_ [l=he] {<p> ×××€×©×× ××¡×××× ×©× ××ª×× × - 1903, ××š×× × ×§×× ××¡×××× ×¢× ××©× × ××× ××× ××©×š × ××ª×× ××©× × ×× "×
+}
+
+_textchangeprefs_ [l=he] {×©×× ×× ×¢×××€××××ª}
+
+_texthelppreferences_ [l=he] {<p>×× ×ª×××¥ ×¢× ××€×ª××š "×¢×××€××××ª" ××ª××××ª ×××£ , ×ª××× ×× ××€×©×š××ª ××©× ××ª
+××ª ×€×¢××××ª ×× ××××©×§ ×× ×©××ª××× ××Š×š×××
+}
+
+_texthelpcollectionprefstitle_ [l=he] {×¢×××€××××ª ××××¡×£}
+_texthelpcollectionprefs_ [l=he] {××©× × ×××¡×€×× ××××š×××× ×××× ×ª×ª-×××¡×€×× , ××©×š × ××ª× ×× ××¢××× ×××××€××© 
+×× ×€×š× ×× ××××, ×××××× ×××ª. ×× ×× ××××š , ××¢××× ××¢×××€××××ª × ××ª×
+ ××¡×× ×××× ×××ª×ª-×××¡×€×× ××© ×××××× ××××€××©
+}
+
+_texthelplanguageprefstitle_ [l=he] {×©×€× ×¢×××€××××ª }
+_texthelplanguageprefs_ [l=he] {×× ×××¡×£ × ×× × ×¢×××š ×©×€× ××¡×××××ª , ×× × ××ª× ××©× ××ª ×××ª
+××× ×× ××€×©×š ××©× ××ª ××× ×××Š×× ××š×€× ××××Š×× ××§×¡× ××š×××
+}
+
+_texthelppresentationprefstitle_ [l=he] {×¢×××€××××ª ×ª×Š×××}
+_texthelppresentationprefs_ [l=he] {×××ª×× ××××¡×£ ×× ×ª×× ××©× × ××× ××š××× ××©× ××ª ××ª ×ª×Š×××ª×
+
+
+
+<p>  Greenstone×××¡×€×× ×©× ××€× ×š×©×ª ×××€×©×š×× ×× ×××× ××ª ××€×ª××š× ×× ×××× ×©×    
+××ª××××ª ××¢××× , ××  ×©××××š ××©××××ª× ××ª× ×ª×××¢ ××©××š××ª ××¢××× ××š×©×ª ×©×××ª× ×××€×©×ª ××× ××€×ª××š× ××××€××©. ×××× ×××Š×¢ 
+×××€××© ×××© ××© ×××©××© ×××€×ª××š "××××š×" . ××××¡×€×× ×× ×××€×©×š×× ×× ×××× ××ª ×××××š×  ×××××š ××××Š× ×¢× ×××××š ××××Š× ×××××¡×£ ××š×©×ª ×¢×Š××.
+××× ×× ×××× ×××¡×€×× ××€×©×š ××©××× ××× ××××××š×× ×××××× ×××€× ××š×©×ª ××š×©×ª ×× ××¢××ª×§×× ×©××× ×©× ××Š××× ××¡×€×š××
+}
+
+_texthelpsearchprefstitle_ [l=he] {×¢×××€××××ª ×××€××©}
+_texthelpsearchprefs_ [l=he] {<p>×©× × ×××××ª ××€×ª××š×× ×©××××× ×¢× ×¢×××€××××ª ××××€××©:
+×××× ××š××©×× ××× × ×š×××× ×× ××©×€× ××¢××š××ª ( ×××ª×××ª ××××××ª ××§×× ××ª)
+×××× ××©× × ×©××× ××× ×¡×××××ª ×××××× ×××××× ××××€××©.
+ ××× ×× ××© ××€×©×š××ª ××§×× ×©×× ××× × ×××× ×××ª×š. ×××€××© ×¢× ××š××
+ ××× ××× ××× ×××€××© ××××š ××××
+
+
+<p>×××××× ×× ××€×ª××š "××ª×¢×× ××¡×××××ª ××××××" ×××× ××××§ ××××€××©
+<ul><kbd>××× ×× ××€×š××§×××× </kbd></ul>
+      <p>××ª×§×× ×××
+     <ul><kbd>××× × ××€×š××§×</kbd></ul><p>
+
+<p>××€×©×š ×××€×¢×× ×××€××© ××ª×§×× ×©× ××ª× ×××€×¢××××× ××× ×××××× ××× ×××
+××× & , ×× | , ××× !.
+××š××š×ª ×××××  ( ×š××× ) ××× ×××
+××××š ×××€×©×š ×××€××© ××××××§ ×××ª×š
+××€×©×š ×××€×¢×× ××ª ×××€×Š×××ª ×××××š××: ××××š ×××€×©×š ×××€×¢×× ×××€××©×× ×××©××
+×× ××š×¡×××ª ×©×× ××ª ×××§×Š×ª ×©× ×××€××©×× ×§×××××
+}
+
+# -- Missing translation: _textcasefoldprefs_
+# -- Missing translation: _textstemprefs_
+# -- Missing translation: _textaccentfoldprefs_
+ 
+# -- Missing translation: _textstemoptionsprefs_
+
+# -- Missing translation: _textsearchtypeprefsplain_
+
+# -- Missing translation: _textsearchtypeprefsform_
+
+# -- Missing translation: _textsearchtypeprefsboth_
+
+
+
+_texttanumbrowseoptions_ [l=he] {××š××× ×××Š×× ××ª ×××××¢ ××××¡×£ ×× "×  _numbrowseoptions_ ××©
+}
+
+_textsimplehelpheading_ [l=he] {××× ×××Š×× ××××¢}
+
+_texthelpscopetitle_ [l=he] {×¡×××š×ª ×©××××ª××ª}
+_texthelpscope_ [l=he] {<p>
+××š×× ××××¡×€×× × ××ª× ×××××š ××× ××¡×€×š ××× ××§×¡×× ××××€××©. ×××××× ×××× ×××××ª ××× ××§×¡ ×©× ××××š××
+ ×× ×××ª×š××ª, ×× ×××× ×××××ª ××× ××§×¡ ×©× ×€×š×§××, ×× ×©× ×€×¡×§×××ª. ×××××ª, ×××××š× ×××¡×××× ××××××
+××× ×ª×××ª ×××š× ××××€××©. ×× ×××¡×× ××× ×¡×€×š, ××× ×××€×ª× ×××§×× ××ª××
+<p>   
+}
Index: /gsdl/stable/macros/help.dm
===================================================================
--- /gsdl/stable/macros/help.dm	(revision 20131)
+++ /gsdl/stable/macros/help.dm	(revision 20131)
@@ -0,0 +1,201 @@
+# this file must be UTF-8 encoded
+
+package help
+
+# preflink may change depending on whether a collection is set or not
+_globallinks_ {_homelink_ _choosepreflink_}
+_choosepreflink_ {_If_(_cgiargc_,_preflink_,_home:preflink_)}
+
+_imagethispage_ {_textHelp_}
+
+_textnumbrowseoptions_ {_If_("_numbrowseoptions_" != "1",<p>_texttanumbrowseoptions_)}
+
+_simplehelp_ {
+_textnumbrowseoptions_
+_textbrowseoptions_
+}
+
+_content_ {
+_optnavigationbar_
+
+_texthelptopics_
+_If_(_cgiargc_,
+<div class="divbar">&nbsp;</div>
+<a name="finding-information"></a>
+<h2>_textsimplehelpheading_</h2>
+_simplehelp_)
+<div class="divbar">&nbsp;</div>
+<a name="reading-docs"></a>
+<h2>_textreadingdocs_</h2>
+_texthelpreadingdocs_
+<p>_texthelpiconsexplained_</p>
+<div class="divbar">&nbsp;</div>
+<a name="searching"></a>
+<h2>_texthelpsearchingtitle_</h2>
+_texthelpsearching_
+<div class="divbar">&nbsp;</div>
+<a name="query-terms"></a>
+<h3>_texthelpquerytermstitle_</h3>
+_texthelpqueryterms_
+_selectextrahelpsearching_
+<div class="divbar">&nbsp;</div>
+<a name="query-type"></a>
+<h3>_texthelpquerytypetitle_</h3>
+_texthelpquerytype_
+<div class="divbar">&nbsp;</div>
+<a name="scope-of-queries"></a>
+<h3 align=left>_texthelpscopetitle_</h3>
+_texthelpscope_
+_If_(_cgiargc_,
+<div class="divbar">&nbsp;</div>
+<a name="advanced-search"></a>
+<h3 align=left>_texthelpadvancedsearchtitle_(_selectindexer_)</h3>
+_texthelpadvancedsearch_
+<p>_texthelpadvancedsearchextra_
+_optionalformsearchhelp_
+_optdatesearchhelp_)
+<div class="divbar">&nbsp;</div>
+<a name="preferences"></a>
+<h2>_textchangeprefs_</h2>
+_texthelppreferences_
+<div class="divbar">&nbsp;</div>
+<a name="col-prefs"></a>
+<h3 align=left>_texthelpcollectionprefstitle_</h3>
+_texthelpcollectionprefs_
+<div class="divbar">&nbsp;</div>
+<a name="lang-prefs"></a>
+<h3 align=left>_texthelplanguageprefstitle_</h3>
+_texthelplanguageprefs_
+<div class="divbar">&nbsp;</div>
+<a name="pres-prefs"></a>
+<h3 align=left>_texthelppresentationprefstitle_</h3>
+_texthelppresentationprefs_
+<div class="divbar">&nbsp;</div>
+<a name="search-prefs"></a>
+<h3 align=left>_texthelpsearchprefstitle_</h3>
+_texthelpsearchprefs_
+<div class="divbar">&nbsp;</div>
+}
+
+
+_texthelptopics_ {
+<h2 align=left>_texthelptopicstitle_</h2>
+<ul>
+  _If_(_cgiargc_,<li><a href="\#finding-information">_textsimplehelpheading_</a>)
+  <li><a href="\#reading-docs">_textreadingdocs_</a>
+  <li><a href="\#searching">_texthelpsearchingtitle_</a>
+<ul>
+  <li><a href="\#query-terms">_texthelpquerytermstitle_</a>
+  <li><a href="\#query-type">_texthelpquerytypetitle_</a>
+  <li><a href="\#scope-of-queries">_texthelpscopetitle_</a>
+  _If_(_cgiargc_,<li><a href="\#advanced-search">_texthelpadvancedsearchtitle_(_selectindexer_)</a>
+  _optionalformsearchhelpcontents_
+  _optdatesearchhelpcontents_)
+</ul>
+  <li><a href="\#preferences">_textchangeprefs_</a>
+<ul>
+  <li><a href="\#col-prefs">_texthelpcollectionprefstitle_</a>
+  <li><a href="\#lang-prefs">_texthelplanguageprefstitle_</a>
+  <li><a href="\#pres-prefs">_texthelppresentationprefstitle_</a>
+  <li><a href="\#search-prefs">_texthelpsearchprefstitle_</a>
+</ul>
+</ul>
+}
+
+_texthelpiconsexplained_ {
+<table cellspacing="0" cellpadding="2" border="0">
+<tr><td colspan=2><img src="_httpiconbshelf_" border="0" alt="_document:texticonclosedbookshelf_" title="_document:texticonclosedbookshelf_"></td><td>_texthelpopenbookshelf_</td></tr>
+<tr><td><img src="_httpiconbook_" border="0" alt="_texticonclosedbook_" title="_texticonclosedbook_"></td><td><img src="_httpiconopenbook_" border="0" alt="_document:texticonopenbook_" title="_document:texticonopenbook_"></td><td>_texthelpopenbook_</td></tr>
+<tr><td colspan=2><img src="_httpiconitext_" border="0" alt="_texticontext_" title="_texticontext_"></td><td>_texthelpviewtextsection_</td></tr>
+<tr><td><img src="_httpiconless_" border="0" alt="_texticonprev_" title="_texticonprev_"></td><td><img src="_httpiconmore_" border="0" alt="_texticonnext_" title="_texticonnext_"></td><td>_texthelpsectionarrows_</td></tr>
+<tr><td>_document:imageexpandtext_</td><td>_document:imagecontracttext_</td><td>_texthelpexpandtext_</td></tr>
+<tr><td>_document:imageexpandtoc_</td><td>_document:imagecontracttoc_</td><td>_texthelpexpandcontents_</td></tr>
+<tr><td>_document:imagedetach_</td><td></td><td>_texthelpdetachpage_</td></tr>
+<tr><td>_document:imagehighlight_</td><td>_document:imagenohighlight_</td><td>_texthelphighlight_</td></tr>
+</table>
+}
+
+# this gets set to _datesearchhelp_ by the receptionist if datesearch is enabled in the collection
+_optdatesearchhelp_{}
+_optdatesearchhelpcontents_ {}
+_datesearchhelpcontents_ {
+  <li><a href="\#datesearch">_textdatesearch_</a>
+  <ul>
+    <li><a href="\#datesearch-howto">_texthelpdatehowtotitle_</a>
+    <li><a href="\#datesearch-results">_texthelpdateresultstitle_</a>
+  </ul>
+}
+
+_datesearchhelp_{
+<div class="divbar">&nbsp;</div>
+<a name="datesearch"></a>
+<h2>_textdatesearch_</h2>
+_texthelpdatesearch_
+<div class="divbar">&nbsp;</div>
+<a name="datesearch-howto"></a>
+<h3>_texthelpdatehowtotitle_</h3>
+_texthelpdatehowto_
+<div class="divbar">&nbsp;</div>
+<a name="datesearch-results"></a>
+<h3>_texthelpdateresultstitle_</h3>
+_texthelpdateresults_
+}
+
+_selectindexer_ {
+_If_("_cgiargct_" eq "0",MG)
+_If_("_cgiargct_" eq "1",MGPP)
+_If_("_cgiargct_" eq "2",Lucene)
+}
+
+_selectextrahelpsearching_ {
+_If_("_cgiargct_" eq "1",_texthelpmgppsearching_)
+_If_("_cgiargct_" eq "2",_texthelplucenesearching_)
+
+}
+
+_selectadvancedsearch_ {
+_If_("_cgiargct_" eq "0",_texthelpadvsearchmg_)
+_If_("_cgiargct_" eq "1",_texthelpadvsearchmgpp_)
+_If_("_cgiargct_" eq "2",_texthelpadvsearchlucene_)
+}
+
+_selectsearchtypeprefs_ {
+_If_("_cgiargct_" eq "0", _textsearchtypeprefsplain_,_mgppsearchtypeoptions_)
+}
+
+_mgppsearchtypeoptions_ {
+_If_("_cgiargqto_" eq "1", _textsearchtypeprefsplain_)
+_If_("_cgiargqto_" eq "2", _textsearchtypeprefsform_)
+_If_("_cgiargqto_" eq "3", _textsearchtypeprefsboth_)
+}
+_optionalformsearchhelp_{
+_If_("_cgiargqto_" eq "2", _formsearchhelp_)
+_If_("_cgiargqto_" eq "3", _formsearchhelp_)
+}
+
+_formsearchhelp_{
+<div class="divbar">&nbsp;</div>
+<a name="form-search"></a>
+<h3 align=left>_texthelpformsearchtitle_</h3>
+_texthelpformsearch_
+}
+
+_optionalformsearchhelpcontents_ {
+_If_("_cgiargqto_" eq "2", _formsearchhelpcontents_)
+_If_("_cgiargqto_" eq "3", _formsearchhelpcontents_)
+}
+
+_formsearchhelpcontents_ {
+<li><a href="\#form-search">_texthelpformsearchtitle_</a>
+}
+
+_selectwordmodificationprefs_ {
+_If_("_cgiargks_" eq "1", <p>_textcasefoldprefs_)
+_If_("_cgiargss_" eq "1", <p>_textstemprefs_)
+_If_("_cgiargafs_" eq "1", <p>_textaccentfoldprefs_)
+}
+
+_selectstemoptionsprefs_ {
+_If_("_cgiargct_" eq "1",_textstemoptionsprefs_)
+}
+
Index: /gsdl/stable/macros/hindi.dm
===================================================================
--- /gsdl/stable/macros/hindi.dm	(revision 20131)
+++ /gsdl/stable/macros/hindi.dm	(revision 20131)
@@ -0,0 +1,970 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Hindi Language text and icon macros (translated from english.dm
+# 2 July 2002 by Mr.Shivaram.B.S., Information and Knowledge Management Course 
+# Trainee (2001-2002), National Centre for Science Information, Indian Institute of 
+# Science, Bangalore 560 012, Karnataka, India.)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textperiodicals_
+# -- Missing translation: _textsource_
+# -- Missing translation: _textdate_
+# -- Missing translation: _textnumpages_
+
+# -- Missing translation: _textsignin_
+
+# -- Missing translation: _textdefaultcontent_
+
+_textdefaulttitle_ [l=hi] {à€à€¿. à€à€žà¥. à€¡à€¿.
+à€à€²à¥. à€ à€Šà¥à€·}
+
+# -- Missing translation: _textbadcollection_
+
+# -- Missing translation: _textselectpage_
+
+# -- Missing translation: _collectionextra_
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+# -- Missing translation: _collectorextra_
+
+_textdescrcollection_ [l=hi] {}
+# -- Missing translation: _textdescrabout_
+_textdescrhome_ [l=hi] {à€®à¥à€ à€ªà¥à€·à¥à€ }
+_textdescrhelp_ [l=hi] {à€žà€¹à€Ÿà€¯à€ à€ªà¥à€·à¥à€ }
+_textdescrpref_ [l=hi] {à€à¥à€šà€Ÿà€µ à€ªà¥à€·à¥à€ }
+_textdescrgreenstone_ [l=hi] {à€à¥à€°à¥à€šà¥ à€žà¥à€à¥à€šà¥
+à€¡à€¿à€à€¿à€à€²à¥ à€²à¥à€¬à¥à€°à€°à€¿ 
+à€žà€«à¥à€à€µà¥à€°à¥}
+# -- Missing translation: _textdescrusab_
+
+_textdescrsearch_ [l=hi] {à€šà€¿à€¶à¥à€à€¿à€€
+à€¶à€µà¥à€Šà¥à€à€à¥ à€à¥à€à€¿à€ à¥€}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=hi] {à€¶à¥à€°à¥à€·à€à€šà€Ÿ à€à¥ à€µà€°à¥à€£à€®à€Ÿà€²à€Ÿ
+à€à€¿ à€žà¥à€à¥ à€à¥ à€
+à€šà¥à€žà€Ÿà€° à€à€°à€šà€Ÿ
+à€à¥à€à€¿à€}
+_textdescrCreator_ [l=hi] {à€²à¥à€à€à¥ à€à¥ à€µà€°à¥à€£à€®à€Ÿà€²à€Ÿ
+à€à€¿ à€žà¥à€à¥ à€à¥ à€
+à€šà¥à€žà€Ÿà€° à€à€°à€šà€Ÿ
+à€à¥à€à€¿à€ à¥€}
+_textdescrSubject_ [l=hi] {à€µà€¿à€·à€¯ à€à¥ à€
+à€šà¥à€žà€Ÿà€° à€à€°à€šà€Ÿ
+à€à¥à€à€¿à€ à¥€}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=hi] {à€€à€Ÿà€°à¥à€ à€à¥ à€
+à€šà¥à€žà€Ÿà€° à€à€°à€šà€Ÿ
+à€à¥à€à€¿à€ à¥€}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+# -- Missing translation: _textdescrSource_
+# -- Missing translation: _textdescrLanguage_
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=hi] {à€žà€à€à€ à€š à€à¥ à€
+à€šà¥à€žà€Ÿà€° à€à€°à€šà€Ÿ
+à€à¥à€à€¿à€ à¥€}
+# -- Missing translation: _textdescrKeyword_
+_textdescrHowto_ [l=hi] {à€à¥à€žà¥ à€µà€°à¥à€à¥ à€à¥ à€à€°à€šà€Ÿ
+à€à¥à€à€¿à€ à¥€}
+_textdescrList_ [l=hi] {à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€žà¥à€à¥ à€à¥
+à€
+à€šà¥à€žà€Ÿà€° à€à€°à€šà€Ÿ à€à¥à€à€¿à€ à¥€}
+_textdescrSeries_ [l=hi] {à€¶à¥à€°à¥à€£à¥ à€à¥ à€
+à€šà¥à€žà€Ÿà€° 
+à€à€°à€šà€Ÿ à€à¥à€à€¿à€ à¥€}
+# -- Missing translation: _textdescrTo_
+# -- Missing translation: _textdescrFrom_
+_textdescrTopic_ [l=hi] {à€ªà¥à€°à€žà€à€ à€à¥ à€
+à€šà¥à€žà€Ÿà€° à€à€°à€šà€Ÿ
+à€à¥à€à€¿à€ à¥€}
+_textdescrBrowse_ [l=hi] {à€à€°à€šà€Ÿ à€à¥à€à€¿à€ à¥€}
+# -- Missing translation: _textdescrCollage_
+_textdescrPeople_ [l=hi] {à€²à¥à€ à€à¥
+à€µà€°à¥à€£à€®à€Ÿà€²à€Ÿ à€à€¿ à€žà¥à€à¥
+à€à¥ à€
+à€šà¥à€žà€Ÿà€° à€à€°à€šà€Ÿ
+à€à¥à€à€¿à€ à¥€}
+# -- Missing translation: _textdescrAcronym_
+# -- Missing translation: _textdescrPhrase_
+# -- Missing translation: _textdescrArtist_
+# -- Missing translation: _textdescrVolume_
+# -- Missing translation: _textdescrCountries_
+# -- Missing translation: _textdescrCaptions_
+
+
+_labelSearch_ [l=hi] {à€à¥à€}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=hi] {à€¶à¥à€°à¥à€·à€à€šà€Ÿ A-Z}
+_labelCreator_ [l=hi] {à€²à¥à€à€ A-Z}
+_labelSubject_ [l=hi] {à€µà€¿à€·à€¯à¥}
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=hi] {à€€à€Ÿà€°à¥à€}
+# -- Missing translation: _labelTypes_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+# -- Missing translation: _labelSource_
+# -- Missing translation: _labelLanguage_
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=hi] {à€žà€à€à€ à€š}
+# -- Missing translation: _labelKeyword_
+_labelHow_ [l=hi] {à€à¥à€žà¥?}
+_labelSeries_ [l=hi] {à€¶à¥à€°à¥à€£à¥}
+_labelList_ [l=hi] {à€žà¥à€à¥}
+# -- Missing translation: _labelTo_
+# -- Missing translation: _labelFrom_
+_labelTopic_ [l=hi] {à€ªà¥à€°à€žà€à€}
+_labelBrwse_ [l=hi] {à€à€°à€šà€Ÿ}
+# -- Missing translation: _labelCollage_
+# -- Missing translation: _labelBrows_
+_labelPeople_ [l=hi] {à€²à¥à€ A-Z}
+# -- Missing translation: _labelAcronym_
+# -- Missing translation: _labelPhrase_
+# -- Missing translation: _labelArtist_
+# -- Missing translation: _labelVolume_
+# -- Missing translation: _labelCaptions_
+# -- Missing translation: _labelCountries_
+
+_texticontext_ [l=hi] {à€Šà€žà¥à€€à€Ÿà€µà¥à€
+à€à¥ à€Šà¥à€à€¿à€}
+_texticonclosedbook_ [l=hi] {à€Šà€žà¥à€€à€Ÿà€µà¥à€
+à€à¥ à€à¥à€² à€à¥ à€Šà¥à€à€¿à€}
+_texticonnext_ [l=hi] {à€
+à€à€²à€Ÿ à€­à€Ÿà€à€šà€Ÿ à€à¥ à€²à€¿à€}
+_texticonprev_ [l=hi] {à€ªà€¹à€²à€Ÿ à€­à€Ÿà€à€šà€Ÿ à€à¥ à€²à€¿à€}
+
+# -- Missing translation: _texticonworld_
+
+# -- Missing translation: _texticonmidi_
+# -- Missing translation: _texticonmsword_
+# -- Missing translation: _texticonmp3_
+# -- Missing translation: _texticonpdf_
+# -- Missing translation: _texticonps_
+# -- Missing translation: _texticonppt_
+# -- Missing translation: _texticonrtf_
+# -- Missing translation: _texticonxls_
+
+_page_ [l=hi] {à€ªà¥à€·à¥à€  }
+_pages_ [l=hi] {à€ªà¥à€·à¥à€ }
+_of_ [l=hi] {à€®à¥à€}
+_vol_ [l=hi] {à€ªà¥à€¥à¥}
+_num_ [l=hi] {à€žà€à€à¥à€¯à€Ÿ}
+
+_textmonth00_ [l=hi] {}
+_textmonth01_ [l=hi] {à€à€šà€µà€°à€¿}
+_textmonth02_ [l=hi] {à€«à¥à€¬à¥à€°à€µà€°à€¿}
+_textmonth03_ [l=hi] {à€®à€Ÿà€°à¥à€}
+_textmonth04_ [l=hi] {à€
+à€ªà¥à€°à¥à€²à¥}
+_textmonth05_ [l=hi] {à€®à¥}
+_textmonth06_ [l=hi] {à€à¥à€šà¥}
+_textmonth07_ [l=hi] {à€à¥à€²à¥}
+_textmonth08_ [l=hi] {à€à€à€žà¥à€}
+_textmonth09_ [l=hi] {à€žà¥à€ªà¥à€à€à€¬à€°à¥}
+_textmonth10_ [l=hi] {à€
+à€à¥à€à¥à€¬à€°à¥}
+_textmonth11_ [l=hi] {à€šà€µà€à€¬à€°à¥}
+_textmonth12_ [l=hi] {à€Šà€¿à€žà€à€¬à€°à¥}
+
+# -- Missing translation: _textdocument_
+# -- Missing translation: _textsection_
+# -- Missing translation: _textparagraph_
+
+# -- Missing translation: _magazines_
+
+# -- Missing translation: _nzdlpagefooter_
+
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=hi] {à€¯à€¹ à€žà€à€à¥à€°à€¹
+à€à¥ à€žà€à€¬à€à€§ à€®à¥à€}
+
+_textsubcols1_ [l=hi] {<p>à€žà€®à¥à€ªà¥à€°à¥à€£
+à€žà€à€à¥à€°à€¹ _1_ à€à€ª à€žà€à€à¥à€°à€¹à¥à€
+à€žà¥ à€­à€šà€Ÿ à€¹à¥ à¥€:
+<blockquote>}
+
+_textsubcols2_ [l=hi] {</blockquote>
+à€
+à€ª à€à€¹à€¿à€ à€€à¥ à€à¥à€šà€Ÿà€µ
+à€ªà¥à€·à¥à€  à€®à¥à€ à€à¥à€
+à€à€ªà€žà€à€à¥à€°à€¹ à€à¥ à€ªà€°à¥à€à¥à€·
+à€à€° à€žà€à¥à€€à¥ à€¹à¥ à¥€}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhsrc_
+# -- Missing translation: _texticonhlang_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+# -- Missing translation: _texticonhcoll_
+# -- Missing translation: _texticonhto_
+# -- Missing translation: _texticonhfrom_
+# -- Missing translation: _texticonhbrows_
+# -- Missing translation: _texticonhacronym_
+# -- Missing translation: _texticonhphrases_
+# -- Missing translation: _texticonhartist_
+# -- Missing translation: _texticonhkw_
+# -- Missing translation: _texticonhvol_
+# -- Missing translation: _texticonhcapt_
+# -- Missing translation: _texticonhcount_
+
+_texticonopenbookshelf_ [l=hi] {à€à¥ à€à€ž à€­à€Ÿà€ 
+à€à¥ à€¬à€šà¥à€Š à€à¥à€à€¿à€ à¥€}
+_texticonclosedbookshelf_ [l=hi] {à€à¥ à€à€ž à€­à€Ÿà€ 
+à€à¥ à€à¥à€² à€à¥ à€Šà¥à€à€¿à€ à¥€}
+_texticonopenbook_ [l=hi] {à€à€ž à€à€¿à€€à€Ÿà€¬
+à€à¥ à€¬à€šà¥à€Š à€à¥à€à€¿à€ à¥€}
+_texticonclosedfolder_ [l=hi] {à€à€ž à€ªà¥à€²à¥à€¡à€°à¥ à€à¥ 
+à€à¥à€² à€à¥ à€Šà¥à€à€¿à€ à¥€}
+_texticonclosedfolder2_ [l=hi] {à€à€ª-à€žà€à€à¥à€°à€¹
+à€à¥ à€à¥à€²à€¿à€ à¥€}
+_texticonopenfolder_ [l=hi] {à€à€ž à€ªà¥à€²à¥à€¡à€°à¥ à€à¥ 
+à€¬à€šà¥à€Š à€à¥à€à€¿à€ à¥€}
+_texticonopenfolder2_ [l=hi] {à€à€ª-à€žà€à€à¥à€°à€¹
+à€à¥ à€¬à€šà¥à€Š à€à¥à€à€¿à€ à¥€ }
+_texticonsmalltext_ [l=hi] {à€à€ž à€­à€Ÿà€ à€à¥ 
+à€®à¥à€²à€¶à€¬à¥à€Šà¥à€
+à€à¥ à€Šà¥à€à€¿à€ à¥€}
+_texticonsmalltext2_ [l=hi] {à€®à¥à€²à€¶à€¬à¥à€Šà¥à€
+à€à¥ à€Šà¥à€à€¿à€ à¥€ }
+_texticonpointer_ [l=hi] {à€ªà¥à€°à€à€²à€¿à€€ à€­à€Ÿà€ à¥€}
+_texticondetach_ [l=hi] {à€à€ž à€ªà¥à€·à¥à€ 
+à€à¥ à€šà€¯à€Ÿ à€à€¿à€¡à€à¥
+à€®à¥à€ à€à¥à€²à€¿à€ à¥€}
+_texticonhighlight_ [l=hi] {à€à¥à€ à€à¥à€¯à€Ÿ à€ªà€Šà¥à€ à€à¥
+à€¹à¥à€²à¥à€ à€à¥à€à€¿à€ à¥€}
+# -- Missing translation: _texticonnohighlight_
+# -- Missing translation: _texticoncontracttoc_
+# -- Missing translation: _texticonexpandtoc_
+# -- Missing translation: _texticonexpandtext_
+# -- Missing translation: _texticoncontracttext_
+_texticonwarning_ [l=hi] {<b> </b>}
+# -- Missing translation: _texticoncont_
+
+_textltwarning_ [l=hi] {<div class="buttons">_imagecont_</div>
+_iconwarning_
+}
+
+# -- Missing translation: _textgoto_
+_textintro_ [l=hi] {<i></i>}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=hi] {_If_(_thislast_,à€ªà€°à€¿à€£à€Ÿà€® _thisfirst_ - _thislast_ à€à€ž
+à€ªà¥à€°à€¶à¥à€š à€à¥: _cgiargq_,à€à€ž à€ªà¥à€°à€¶à¥à€š
+à€à€Ÿ à€à¥à€ à€®à¥à€² à€šà€¹à¥à€ à€¹à¥: _cgiargq_)}
+_textnoquerytitle_ [l=hi] {à€à¥à€ à€à€Ÿ à€ªà¥à€·à¥à€  à¥€}
+
+_textsome_ [l=hi] {_If_(_cgiargb_,à€ªà€à€à¥à€€à€¿, à€à¥à€)}
+_textall_ [l=hi] {_If_(_cgiargb_,à€¬à¥à€²à€¿à€¯à€šà¥, à€žà€¬)}
+# -- Missing translation: _textboolean_
+# -- Missing translation: _textranked_
+# -- Missing translation: _textnatural_
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+# -- Missing translation: _texticonsearchhistorybar_
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+# -- Missing translation: _textusequery_
+_textfreqmsg1_ [l=hi] {à€ªà€Š à€à€£à€šà€Ÿ: }
+_textpostprocess_ [l=hi] {_If_(_quotedquery_,<br><i>à€ªà€¿à€à€²à€¿
+à€ªà¥à€°à€à¥à€°à¥à€¯à€Ÿ à€à¥
+à€à¥à€à€šà¥ à€à¥ à€²à€¿à€¯à¥ _quotedquery_ </i>)}
+# -- Missing translation: _textinvalidquery_
+
+_textmorethan_ [l=hi] {à€
+à€§à€¿à€ à€žà¥ }
+# -- Missing translation: _textapprox_
+_textnodocs_ [l=hi] {à€à€ž
+à€ªà¥à€°à€¶à¥à€š à€à¥ à€à¥à€
+à€®à¥à€² à€šà€¹à¥à€ à€¹à¥ à¥€}
+_text1doc_ [l=hi] {à€à€ž à€ªà¥à€°à€¶à¥à€š à€à¥ 
+1 à€Šà€žà¥à€€à€Ÿà€µà¥à€
+à€®à¥à€² à€¹à¥à€ à€¹à¥ à¥€}
+_textlotsdocs_ [l=hi] {à€à€ž à€ªà¥à€°à€¶à¥à€š à€à¥ à€Šà€žà¥à€€à€Ÿà€µà¥à€
+à€®à¥à€² à€¹à¥à€ à€¹à¥ à¥€}
+_textmatches_ [l=hi] {à€®à¥à€² }
+_textbeginsearch_ [l=hi] {à€à¥à€à€šà€Ÿ à€¶à¥à€°à¥ à€à€°à¥}
+# -- Missing translation: _textrunquery_
+# -- Missing translation: _textclearform_
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+# -- Missing translation: _textwordphrase_
+# -- Missing translation: _textinfield_
+# -- Missing translation: _textfoldstem_
+
+# -- Missing translation: _textadvquery_
+# -- Missing translation: _textallfields_
+# -- Missing translation: _texttextonly_
+# -- Missing translation: _textand_
+# -- Missing translation: _textor_
+# -- Missing translation: _textandnot_
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=hi] {à€à¥à€à€¿à€¯à¥ _indexselection__If_(_jselection_, à€žà¥ _jselection_)_If_(_nselection_, _nselection_) à€à€¿à€žà€®à¥ _querytypeselection_ à€¶à€¬à¥à€Š à€¹à¥à€ à¥€}
+
+_textadvancedsearch_ [l=hi] {à€à¥à€à€¿à€¯à¥ _indexselection_ _If_(_jselection_, à€žà¥ _jselection_)_If_(_nselection_, _nselection_ à€­à€Ÿà€·à€Ÿ) à€à€¿à€žà€®à¥ _querytypeselection_ à€¶à€¬à¥à€Š à€¹à¥à€ à¥€}
+
+# -- Missing translation: _textformsimplesearch_
+
+# -- Missing translation: _textformadvancedsearch_
+
+
+# -- Missing translation: _textnojsformwarning_
+# -- Missing translation: _textdatesearch_
+# -- Missing translation: _textstartdate_
+# -- Missing translation: _textenddate_
+# -- Missing translation: _textbc_
+# -- Missing translation: _textad_
+# -- Missing translation: _textexplaineras_
+
+_textstemon_ [l=hi] {(à€¶à€µà¥à€Šà€Ÿà€šà¥à€€à¥à€
+à€à¥ à€
+à€šà€Šà¥à€à€Ÿ à€à€°à¥ à¥€)}
+
+_textsearchhistory_ [l=hi] {à€à¥à€ à€à€Ÿ à€à€€à€¿à€¹à€Ÿà€ž à¥€}
+
+#text macros for search history
+_textnohistory_ [l=hi] {à€à¥à€ à€à€Ÿ à€à€€à€¿à€¹à€Ÿà€ž 
+à€®à€€ à€Šà€¿à€à€Ÿà€ à¥€}
+# -- Missing translation: _texthresult_
+# -- Missing translation: _texthresults_
+# -- Missing translation: _texthallwords_
+# -- Missing translation: _texthsomewords_
+# -- Missing translation: _texthboolean_
+# -- Missing translation: _texthranked_
+# -- Missing translation: _texthcaseon_
+# -- Missing translation: _texthcaseoff_
+# -- Missing translation: _texthstemon_
+# -- Missing translation: _texthstemoff_
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textprefschanged_
+_textsetprefs_ [l=hi] {à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿà€¯à¥à€
+à€à¥à€šà€¿à€¯à¥}
+_textsearchprefs_ [l=hi] {à€à¥à€ à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿà€¯à¥à€}
+_textcollectionprefs_ [l=hi] {à€žà€à€à¥à€°à€¹
+à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿà€¯à¥à€}
+_textpresentationprefs_ [l=hi] {à€ªà¥à€°à€Šà€°à¥à€¶à€šà¥à€¯
+à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿà€¯à¥à€}
+_textpreferences_ [l=hi] {à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿà€¯à¥à€}
+# -- Missing translation: _textcasediffs_
+# -- Missing translation: _textignorecase_
+# -- Missing translation: _textmatchcase_
+_textwordends_ [l=hi] {à€¶à€µà¥à€Šà€Ÿà€šà¥à€€:}
+_textstem_ [l=hi] {à€¶à€µà¥à€Šà€Ÿà€šà¥à€€à¥à€
+à€à¥ à€
+à€šà€Šà¥à€à€Ÿ à€à€°à¥ à¥€}
+_textnostem_ [l=hi] {à€ªà¥à€°à¥à€£ à€¶à€¬à¥à€Š à€à€°à¥à€°
+à€®à€¿à€²à€Ÿà€ à¥€}
+_textprefop_ [l=hi] {à€à¥à€²_maxdocoption_ à€ªà€°à€¿à€£à€Ÿà€®à¥à€
+à€®à¥à€ à€žà¥ _hitsperpageoption_ à€ªà€°à€¿à€£à€Ÿà€®
+à€ªà¥à€°à€€à€¿ à€ªà¥à€·à¥à€  à€Šà€¿à€à€Ÿà€à¥€}
+_textextlink_ [l=hi] {à€¬à€¹à€°à¥
+à€µà¥à€¬ à€ªà¥à€·à¥à€ à¥à€
+à€à¥ à€ªà¥à€°à€Ÿà€ªà¥à€€
+à€à¥à€à€¿à€¯à¥ }
+_textintlink_ [l=hi] {à€®à¥à€² à€Šà€žà¥à€€à€Ÿà€µà¥à€
+à€à€ž à€žà¥ à€ªà€¯à€Ÿ à€¹à¥:}
+_textlanguage_ [l=hi] {à€à€šà¥à€à€°à€«à¥à€ž
+à€à¥ à€­à€Ÿà€·à€Ÿ: }
+_textencoding_ [l=hi] {à€à€šà¥à€à¥à€¡à€¿à€à€: }
+_textformat_ [l=hi] {à€à€šà¥à€à€°à€«à¥à€ž
+à€à¥ à€°à€à€šà€Ÿ: }
+_textall_ [l=hi] {à€žà€¬}
+_textquerymode_ [l=hi] {à€à¥à€
+à€à¥ à€ªà¥à€°à€à€Ÿà€°:}
+_textsimplemode_ [l=hi] {à€žà€°à€³ à€à¥à€ à¥€}
+_textadvancedmode_ [l=hi] {à€à€šà¥à€šà€€
+à€à¥à€ à€¬à¥à€²à€¿à€¯à€šà¥ à€à¥à€
+à€à€° à€žà€à€€à¥ à€¹à¥à€) à¥€}
+# -- Missing translation: _textlinkinterm_
+_textlinkdirect_ [l=hi] {à€žà€¿à€Š à€à€Šà€° à€à€Ÿà€¯à€¿à€¯à¥}
+_textdigitlib_ [l=hi] {à€¡à€¿à€à€¿à€à€² à€ªà¥à€žà¥à€€à€à€²à€¯}
+_textweb_ [l=hi] {à€µà¥à€¬}
+_textgraphical_ [l=hi] {à€žà¥à€à€¿à€€à¥à€°}
+_texttextual_ [l=hi] {à€®à¥à€²à€¿à€}
+_textcollectionoption_ [l=hi] {<p>
+à€à€ªà€žà€à€à¥à€°à€¹à¥à€
+à€à¥ à€žà€®à¥à€®à€¿à€²à€š
+à€à€°à¥:
+<br>}
+
+_textrelateddocdisplay_ [l=hi] {à€žà€®à¥à€¬à€šà¥à€§à€¿à€€
+à€Šà€žà¥à€€à€Ÿà€µà¥à€à¥à€
+à€à¥ à€Šà€¿à€à€Ÿà€ à¥€}
+_textsearchhistory_ [l=hi] {à€à¥à€
+à€à€Ÿ à€à€€à€¿à€¹à€Ÿà€ž}
+# -- Missing translation: _textnohistory_
+_texthistorydisplay_ [l=hi] {à€à¥à€ à€à¥ _historynumrecords_ à€à€€à€¿à€¹à€Ÿà€ž
+à€Šà€¿à€à€Ÿà€ à¥€}
+_textnohistorydisplay_ [l=hi] {à€à¥à€
+à€à€Ÿ à€à€€à€¿à€¹à€Ÿà€ž à€®à€€ à€Šà€¿à€à€Ÿà€ à¥€}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+# -- Missing translation: _textformsearch_
+# -- Missing translation: _textplainsearch_
+_textqueryboxsize_ [l=hi] {à€à¥à€ à€žà€šà¥à€Šà¥à€ 
+à€à¥ à€à€à€Ÿà€°:}
+_textregbox_ [l=hi] {à€šà€¿à€¯à€€ à€à¥à€ à€žà€šà¥à€Šà¥à€ à¥€}
+_textbigbox_ [l=hi] {à€¬à€¡à€Ÿ à€à¥à€ à€žà€šà¥à€Šà¥à€ à¥€}
+# -- Missing translation: _textformtype_
+_textsimple_ [l=hi] {à€žà€°à€³}
+_textadvanced_ [l=hi] {à€à€šà¥à€šà€€}
+
+# used in "with 4 fields" in the form search box
+# -- Missing translation: _textwith_
+# -- Missing translation: _textfields_
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+# -- Missing translation: _textsortby_
+# -- Missing translation: _textalsoshowing_
+# -- Missing translation: _textwith_
+# -- Missing translation: _textdocsperpage_
+
+# -- Missing translation: _textfilterby_
+# -- Missing translation: _textall_
+# -- Missing translation: _textany_
+# -- Missing translation: _textwords_
+# -- Missing translation: _textleaveblank_
+
+# -- Missing translation: _browsebuttontext_
+
+# -- Missing translation: _nodata_
+# -- Missing translation: _docs_
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textHelp_
+_textSearchshort_ [l=hi] {à€šà€¿à€¶à¥à€à€¿à€€
+à€ªà€Š à€à¥ à€à¥à€à€¿à€¯à¥ à¥€}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=hi] {à€¶à¥à€°à¥à€·à€
+à€à¥ à€
+à€šà¥à€žà€Ÿà€° à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€
+à€®à¥ à€ªà¥à€°à€µà¥à€¶ à€à¥à€à€¿à€¯à¥ à¥€}
+_textCreatorshort_ [l=hi] {à€à¥ à€
+à€šà¥à€žà€Ÿà€°
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€ à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à¥à€à€¿à€¯à¥ à¥€}
+_textSubjectshort_ [l=hi] {à€µà€¿à€·à€¯ à€à¥ à€
+à€šà¥à€žà€Ÿà€°
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€ à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à¥à€à€¿à€¯à¥ à¥€}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=hi] {à€€à€Ÿà€°à¥à€ à€à¥ à€
+à€šà¥à€žà€Ÿà€°
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€ à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à¥à€à€¿à€¯à¥ à¥€}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=hi] {à€²à¥à€à€ªà€€à¥à€° à€à¥
+à€
+à€šà¥à€žà€Ÿà€° à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€
+à€®à¥ à€ªà¥à€°à€µà¥à€¶ à€à¥à€à€¿à€¯à¥ à¥€}
+# -- Missing translation: _textLanguageshort_
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=hi] {à€¶à¥à€°à¥à€£à¥ à€à¥
+à€
+à€šà¥à€žà€Ÿà€° à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€
+à€®à¥ à€ªà¥à€°à€µà¥à€¶ à€à¥à€à€¿à€¯à¥ à¥€}
+# -- Missing translation: _textToshort_
+# -- Missing translation: _textFromshort_
+_textBrowseshort_ [l=hi] {à€ªà¥à€°à€à€Ÿà€¶à€šà¥
+à€à¥ à€à€°à€šà€Ÿ à€à¥à€à€¿à€¯à¥ à¥€}
+_textOrganizationshort_ [l=hi] {à€žà€à€à€ à€šà¥ à€à¥
+à€
+à€šà¥à€žà€Ÿà€° à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€
+à€®à¥ à€ªà¥à€°à€µà¥à€¶ à€à¥à€à€¿à€¯à¥ à¥€}
+_textHowtoshort_ [l=hi] {à€à¥à€žà¥ à€žà¥à€à€¿
+à€à¥ à€
+à€šà¥à€žà€Ÿà€° à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€
+à€®à¥ à€ªà¥à€°à€µà¥à€¶ à€à¥à€à€¿à€¯à¥ à¥€}
+_textTopicshort_ [l=hi] {à€ªà¥à€°à€žà€à€ à€à¥
+à€
+à€šà¥à€žà€Ÿà€° à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€
+à€®à¥ à€ªà¥à€°à€µà¥à€¶ à€à¥à€à€¿à€¯à¥ à¥€}
+_textPeopleshort_ [l=hi] {à€à€šà€€à€Ÿ à€à¥ à€
+à€šà¥à€žà€Ÿà€°
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€ à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à¥à€à€¿à€¯à¥ à¥€}
+# -- Missing translation: _textAcronymshort_
+# -- Missing translation: _textPhraseshort_
+_textArtistshort_ [l=hi] {à€à€²à€Ÿà€à€Ÿà€° à€à¥
+à€
+à€šà¥à€žà€Ÿà€° à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€
+à€®à¥ à€ªà¥à€°à€µà¥à€¶ à€à¥à€à€¿à€¯à¥ à¥€}
+# -- Missing translation: _textKeywordshort_
+# -- Missing translation: _textVolumeshort_
+# -- Missing translation: _textCountriesshort_
+# -- Missing translation: _textdefaultshorttext_
+
+_textSearchlong_ [l=hi] {<p>à€à€ª à€®à¥à€²à€à¥à€°à€šà¥à€¥
+à€žà¥ à€šà€¿à€¶à¥à€à€¿à€€ à€ªà€Š
+à€à¥ à€à¥à€ "à€à¥à€" à€ªà¥à€·à¥à€ 
+à€žà¥ à€à€° à€žà€à€€à¥ à€¹à¥
+à¥€ à€¯à€¹ à€µà¥ à€ªà€¹à€²à€Ÿ à€ªà¥à€·à¥à€ 
+à€¹à¥ à€à€¹à€Ÿà€žà¥ à€à€ª <b>à€à¥à€</b>, 
+à€¬à€à€š à€à€Ÿ
+à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€Šà¥à€žà€°à¥ à€ªà¥à€·à¥à€  à€à¥ à€à€° à€¬à€Œà€¢à€€à¥
+à€¹à¥ à¥€  }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=hi] {<p>à€à€ª <b> à€¶à¥à€°à¥à€·à€</b>
+ à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€
+à€à€°à€à¥ à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥ à€ªà¥à€°à€µà¥à€¶
+à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ à€¯à¥
+à€µà€°à¥à€£à€®à€Ÿà€²à€Ÿ à€žà€à€¬à€šà¥à€§à€¿ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à€€à¥ à€¹à¥ à¥€  }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=hi] {<p>à€à€ª <b> à€²à¥à€à€</b> 
+à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+ à€¯à¥ à€µà€°à¥à€£à€®à€Ÿà€²à€Ÿ
+à€žà€à€¬à€šà¥à€§à€¿ à€²à¥à€à€
+à€žà¥à€à€¿ à€à¥ à€ªà¥à€¶
+à€à€°à€€à¥ à€¹à¥ à¥€  }
+
+_textSubjectlong_ [l=hi] {<p>à€à€ª <b> à€µà€¿à€·à€¯</b>
+ à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€
+à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥ à€ªà¥à€°à€µà¥à€¶
+à€à€° à€žà€à€€à¥
+à€¹à¥ à¥€ à€¯à¥ à€µà¥ à€µà€¿à€·à€¯ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à¥à€à€Ÿ à€à¥ à€à€¿à€€à€Ÿà€¬à¥ à€à¥
+à€€à€Ÿà€ à€à€Ÿ à€ªà¥à€°à€€à€¿à€šà€¿à€§à€¿à€€à¥à€µ
+à€à€°à€€à¥ à€¹à¥ à¥€ }
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=hi] {<p>à€à€ª <b> à€€à€Ÿà€°à¥à€</b> 
+à€¬à€à€šà€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥ à€ªà¥à€°à€µà¥à€¶
+à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ à€¯à¥à€à€µà¥à€€à¥à€€à€¿à€à¥
+à€žà¥à€à€¿à€à¥à€ªà¥à€¶à€à€°à€€à¥à€¹à¥ à¥€  }
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=hi] {<p>à€à€ª <i>à€²à¥à€à€ªà€€à¥à€°</i> à€¬à€à€š à€à€Ÿ
+à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ 
+à€¯à¥ à€®à¥à€² à€²à¥à€à€ªà€€à¥à€° à€à¥ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à€€à¥ à€¹à¥ à¥€ }
+
+# -- Missing translation: _textLanguagelong_
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=hi] {<p>à€à€ª <b> à€žà€à€à€ à€šà¥</b> 
+à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥ à€ªà¥à€°à€µà¥à€¶
+à€à€° à€žà€à€€à¥ 
+à€¹à¥ à¥€ à€¯à¥ à€žà€à€à€ à€šà¥à€à¥
+à€žà¥à€à€¿ à€à¥ à€ªà¥à€¶ à€à€°à€€à¥ à€¹à¥ à¥€ }
+
+_textHowtolong_ [l=hi] {<p>à€à€ª <b> à€à¥à€žà¥</b> à€¬à€à€š à€à€Ÿ
+à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+ à€¯à¥ à€à¥à€žà¥ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à€€à¥ 
+à€¹à¥ à¥€  }
+
+_textTopiclong_ [l=hi] {<p>à€à€ª <b> à€ªà¥à€°à€žà€à€</b> 
+à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+ à€¯à¥ à€ªà¥à€°à€žà€à€
+à€žà¥à€à€¿ à€à¥ à€à€°à€š à€à¥ à€²à€¿à€
+à€ªà¥à€¶ à€à€°à€€à¥ à€¹à¥ à¥€ }
+
+_textTolong_ [l=hi] {<p>à€à€ª <b>à€ªà€€à€Ÿ</b> à€¬à€à€š à€à€Ÿ
+à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+à€¯à¥ à€
+à€²à€-à€
+à€²à€ à€ªà€€à¥à€ à€à¥ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à€€à¥ à€¹à¥ à¥€  }
+
+_textFromlong_ [l=hi] {<p>à€à€ª<b>à€žà¥</b> à€¬à€à€š à€à€Ÿ
+à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+à€¯à¥ à€ªà¥à€°à¥à€·à€ à€à¥ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à€€à¥
+à€¹à¥ à¥€  }
+
+_textSerieslong_ [l=hi] {<p>à€à€ª <b> à€¶à¥à€°à¥à€£à¥</b> 
+à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+à€¯à¥ à€¶à¥à€°à¥à€£à¥à€à€
+ à€à¥ à€žà¥à€à€¿ à€à¥ à€ªà¥à€¶ à€à€°à€€à¥
+à€¹à¥ à¥€ }
+
+_textBrowselong_ [l=hi] {<p>à€à€ª <b>à€à€°à€šà€Ÿ</b> 
+à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€ à€à€Ÿ
+à€à€°à€š à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ }
+
+_textPeoplelong_ [l=hi] {<p>à€à€ª <b> à€à€šà€€à€Ÿ</b> 
+à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+à€¯à¥ à€à¥à€²à€šà€Ÿà€® à€à¥ à€žà¥à€à€¿ à€à¥ à€ªà¥à€¶
+à€à€°à€€à¥ à€¹à¥ à¥€  }
+
+# -- Missing translation: _textAcronymlong_
+
+# -- Missing translation: _textPhraselong_
+
+_textArtistlong_ [l=hi] {<p>à€à€ª <b>à€à€²à€Ÿà€à€Ÿà€°</b> à€¬à€à€š à€à€Ÿ
+à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ 
+à€¯à¥ à€à€²à€Ÿà€à€Ÿà€° à€à¥ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à€€à¥ à€¹à¥ à¥€  }
+
+# -- Missing translation: _textKeywordlong_
+
+# -- Missing translation: _textVolumelong_
+
+# -- Missing translation: _textCaptionslong_
+
+# -- Missing translation: _textCountrieslong_
+
+
+# -- Missing translation: _textdefaultlongtext_
+
+
+_textreadingdocs_ [l=hi] {à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€à¥
+à€à¥à€žà¥ à€ªà€¢à¥à€ à¥€}
+
+_texthelpreadingdocs_ [l=hi] {
+<p> à€à€ª à€à¥ à€ªà¥à€·à¥à€
+à€ªà¥ à€¶à¥à€°à¥à€·à€, à€²à¥à€à€ à€à€Ÿ à€šà€Ÿà€®
+à€¬à€Ÿà€¯à¥à€ à€€à€°à€« à€®à¥à€²à¥à€à€Ÿ à¥€ 
+à€€à€Šà¥à€ªà€°à€Ÿà€à€€ à€à€ª
+à€à¥ à€µà€°à¥à€€à€®à€Ÿà€š à€ªà¥à€·à¥à€
+à€žà¥ à€à€à¥ à€²à¥ à€à€Ÿà€šà¥à€µà€Ÿà€²à¥
+à€ªà¥à€·à¥à€, à€à€à¥ à€à€° à€ªà¥à€à¥ à€²à¥
+à€à€Ÿà€šà¥à€µà€Ÿà€²à¥ à€€à¥à€° à€®à¥à€²à¥à€à€à¥ à¥€
+
+<p>à€šà¥à€à¥
+à€µà€°à¥à€€à€®à€Ÿà€š à€µà€¿à€­à€Ÿà€
+à€à€Ÿ à€®à¥à€² à€®à¥à€²à¥à€à€Ÿ
+à¥€ à€à€žà¥ à€ªà€¢à€šà¥ à€à¥
+à€¬à€Ÿà€Š à€žà€¬à€žà¥ à€šà¥à€à¥
+à€à€à¥ à€à€° à€ªà¥à€à¥ à€²à¥
+à€à€Ÿà€šà¥à€µà€Ÿà€²à¥ à€€à¥à€° à€®à¥à€²à¥à€à€à¥ à¥€
+
+<p>à€¶à¥à€°à¥à€·à€ à€à€°
+à€²à¥à€à€ à€à¥ à€šà€Ÿà€®
+à€à¥ à€šà¥à€à¥ à€€à¥à€š
+à€¬à€à€š à€®à¥à€²à¥à€à€à¥ à¥€
+à€µà€°à¥à€€à€®à€Ÿà€š à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€à€Ÿ
+à€ªà¥à€°à¥à€£ à€®à¥à€²
+à€«à¥à€²à€Ÿà€šà¥ à€à¥ à€²à€¿à€ <i>à€«à¥à€²à€Ÿà€šà€Ÿ à€à¥</i>, 
+à€à€¿à€ à€à€¿à€ à€à€°à¥à€ à¥€ 
+à€šà€¯à¥ à€à€¿à€¡à€à¥
+à€à¥à€²à€šà¥ à€à¥ à€²à€¿à€ <i>à€
+à€²à€</i>,
+ à€ªà€° à€à€¿à€ à€à€¿à€
+à€à€°à¥à€ à¥€ (à€Šà¥ à€Šà€žà¥à€€à€Ÿà€µà¥à€à¥à€
+à€à¥ à€€à¥à€²à€šà€Ÿ à€à€°à€šà¥
+à€à¥ à€²à€¿à€ à€šà€¯à¥ à€à€¿à€¡à€à¥
+à€žà€¹à€Ÿà€¯à€ à€¹à¥ à¥€) à€
+à€à€€ à€®à¥, à€à¥à€ à€à€¿à€¯à€Ÿ
+à€¹à¥à€ à€¶à€¬à¥à€Š à€ªà¥à€°à€à€Ÿà€¶à€¿à€€
+à€¹à¥à€à€Ÿ à¥€ à€
+à€ªà¥à€°à€à€Ÿà€¶à€¿à€€
+à€à€°à€šà¥ à€à¥ à€²à€¿à€ <i>à€
+à€ªà¥à€°à€à€Ÿà€¶à€¿à€€</i>, 
+à€¬à€à€š à€à¥ à€à€¿à€ à€à€¿à€ à€à€°à¥à€ à¥€
+}
+
+# help about the icons
+_texthelpexpandtext_ [l=hi] {à€ªà¥à€°à¥à€£ à€®à¥à€² à€à¥
+à€ªà¥à€°à€°à¥à€Šà€·à€¿à€€
+à€à€°à¥à€, à€š à€à€°à¥à€ à¥€}
+_texthelpdetachpage_ [l=hi] {à€à€ž à€ªà¥à€·à¥à€ à€à¥
+à€šà€¯à¥ à€à€¿à€¡à€à¥ à€®à¥
+à€à¥à€²à¥ à¥€}
+_texthelphighlight_ [l=hi] {à€à¥à€à¥ à€¹à¥à€
+à€¶à€¬à¥à€Š à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€¿à€€ à€à€°à¥à€,
+à€š à€à€°à¥à€ à¥€}
+
+_texthelpsearchingtitle_ [l=hi] {à€šà€¿à€¶à¥à€à€¿à€€
+à€ªà€Šà¥à€ à€à¥ à€à¥à€žà¥
+à€à¥à€à¥}
+
+_texthelpsearching_ [l=hi] {
+<p>
+  à€à¥à€ à€ªà¥à€·à¥à€ à€žà¥, à€à€ª
+à€à€ž à€ªà¥à€°à€à€Ÿà€° à€žà€°à€³
+à€µà€¿à€§à€Ÿà€š à€¬à€šà€Ÿà€¯à¥à€ :<p>
+  
+  <ol><li>à€à¥à€ à€à¥ à€šà€¿à€¶à¥à€à€¿à€€
+à€à€°à¥ à¥€
+      <li>à€à€ª à€žà€¬ à€
+à€¥à€µà€Ÿ
+à€à¥à€ à€ªà€Šà¥à€ à€à¥
+à€à¥à€ à€à¥ à€²à€¿à€ à€šà€¿à€¶à¥à€à€¿à€€
+à€à€°à¥ à¥€
+      <li>à€à¥à€ à€šà¥ à€µà€Ÿà€²à¥ à€ªà€Šà¥à€
+à€à¥ à€à€Ÿà€à€ª à€à€°à¥ à¥€
+      <li><i>à€à¥à€à€šà€Ÿ à€¶à¥à€°à¥
+à€à€°à¥</i> à€¬à€à€š à€ªà€° à€à€¿à€
+à€à€¿à€ à€à€°à¥ à¥€
+  </ol>
+
+<p> à€à€ª à€à¥ à€à¥à€ à€à¥
+à€¬à€Ÿà€Š, à€¬à¥à€ž à€žà€¹à¥
+à€®à¥à€² à€à¥ à€Šà€žà¥à€€à€Ÿà€µà¥à€
+à€à¥ à€¶à¥à€°à¥à€·à€
+à€Šà¥à€à¥à€à€à¥ à¥€ à€
+à€à€€
+
+à€®à¥ à€
+à€à€²à¥ à€¬à¥à€ž à€Šà€žà¥à€€à€Ÿà€µà¥à€
+à€®à¥ à€à€Ÿà€šà¥ à€à¥ à€²à€¿à€ à€¬à€à€š
+à€®à¥à€²à¥à€à€Ÿ à¥€ à€à€¹à€Ÿà€žà¥
+à€
+à€à€²à¥ à€¬à¥à€ž à€Šà€žà¥à€€à€Ÿà€µà¥à€
+à€®à¥ à€à€Ÿà€šà¥ à€à¥ à€²à€¿à€ à€à€° à€ªà¥à€à¥
+à€à€šà¥ à€à¥ à€²à€¿à€ à€­à¥ à€¬à€à€š
+à€®à¥à€²à¥à€à€Ÿ à¥€ à€à€ª à€¶à¥à€°à¥à€·à€
+à€
+à€¥à€µà€Ÿ à€¶à¥à€°à¥à€·à€ à€à¥ à€ªà€Ÿà€ž à€µà€Ÿà€²à€Ÿ
+à€¬à€à€š à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€à€ž à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€à¥ à€Šà¥à€ à€žà€à€€à¥
+à€¹à¥ à¥€ 
+
+<p> à€à€ª à€à€°à¥à€°à€€ à€à¥ 
+à€
+à€šà¥à€žà€Ÿà€° à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿà€¯à¥à€
+à€¬à€Šà€² à€žà€à€€à¥ à€¹à¥ à¥€<p> 
+}
+
+_texthelpquerytermstitle_ [l=hi] {à€à¥à€ à€ªà€Š}
+_texthelpqueryterms_ [l=hi] {
+<p> à€à€ª à€à¥ à€ªà€Šà¥à€ à€à¥
+à€à¥à€ à€žà€šà¥à€Šà¥à€
+à€®à¥à€ à€à€Ÿà€à€ª
+à€à€°à¥à€à€à¥ à€à€žà€à€Ÿ
+à€
+à€°à¥à€¥à€à€à€š "à€à¥à€ à€ªà€Š" 
+à€¹à¥à€à€Ÿ à¥€ à€¹à€° à€à€ à€ªà€Š à€µà€°à¥à€£à€®à€Ÿà€²à€Ÿ
+à€à¥ à€à€¿à€šà¥à€¹ à€à€° à€
+à€à€à¥ à€žà¥ à€¬à€šà€€à€Ÿ
+à€¹à¥ à¥€ à€Šà¥ à€ªà€Šà¥à€ à€à¥ à€à€Ÿà€²à¥ à€à€à€¹
+à€žà¥ à€
+à€²à€ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ à€µà€¿à€°à€Ÿà€®
+à€à€¿à€šà¥à€¹ à€à€Ÿ à€à€ªà€¯à¥à€ à€­à¥ à€Šà¥
+à€ªà€Šà¥à€ à€à¥ à€
+à€²à€ à€à€°à¥à€à€Ÿ à¥€ à€à€ž
+à€€à€°à€¹ à€µà€¿à€°à€Ÿà€® à€à€¿à€šà¥à€¹à¥à€ à€à¥
+à€à¥à€¡ à€Šà€¿à€¯à€Ÿ à€à€Ÿà€¯à¥à€à€Ÿ à¥€
+à€à€žà€²à€¿à€ à€à€ª à€µà€¿à€°à€Ÿà€® à€à€¿à€šà¥à€¹
+à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€à¥à€ à€šà€¹à¥ à€à€° à€žà€à€€à¥ à¥€
+
+<p>à€à€Šà€Ÿà€¹à€°à€£: à€šà€¿à€®à¥à€šà€²à€¿à€à€¿à€€
+à€à¥à€<p>
+    <ul><kbd>à€
+à€¬à¥à€Šà¥à€² à€à€²à€Ÿà€®-
+à€à€ à€žà€à€€ à€µà¥à€à¥à€à€Ÿà€šà€¿à€
+(2002)</kbd></ul>
+      <p>à€à€Ÿ à€
+à€°à¥à€¥à€à€à€š<p>
+      <ul><kbd>à€
+à€¬à¥à€Šà¥à€² à€à€²à€Ÿà€®
+à€à€ à€žà€à€€ à€µà¥à€à¥à€à€Ÿà€šà€¿à€
+2002 </kbd></ul><p>
+<p>à€¹à¥à€à€Ÿ à¥€
+}
+
+_texthelpquerytypetitle_ [l=hi] {à€à¥à€ à€à€Ÿ à€ªà¥à€°à€à€Ÿà€°}
+_texthelpquerytype_ [l=hi] {
+<p>à€à¥à€ à€à¥ à€Šà¥
+à€ªà¥à€°à€à€Ÿà€° à€¹à¥ à¥€
+
+<ul>
+  <li>à€žà€¬ à€ªà€Šà¥à€ à€à¥ à€²à€¿à€
+à€à¥à€ à€à€°à€šà€Ÿ à¥€ à€à€ž
+à€®à¥à€ à€à€ª à€Šà¥à€¬à€Ÿà€°à€Ÿ
+à€µà€°à¥à€£à€¿à€€ à€ªà€Šà¥à€ à€à¥
+à€Šà€žà¥à€€à€Ÿà€µà¥à€, à€ªà¥à€°à€à€°à€£ à€à€°
+à€¶à¥à€°à¥à€·à€à¥à€ à€®à¥à€ à€¢à¥à€à€¢à¥à€à€Ÿ à¥€
+à€à€à€¿à€€ à€Šà€žà¥à€€à€Ÿà€µà¥à€à¥à€
+à€à¥ à€µà€°à¥à€£à€®à€Ÿà€²à€Ÿ à€žà€®à¥à€¬à€šà¥à€§à€¿
+à€à¥à€°à€® à€®à¥ à€Šà€°à¥à€¶à€Ÿà€¯à¥à€à€Ÿ à¥€<p>
+
+  <li>à€à¥à€ à€ªà€Šà¥à€ à€à¥ à€²à€¿à€
+à€à¥à€ à€à€°à€šà€Ÿ à¥€ à€à€ª à€¯à€¹à¥ à€à¥à€
+à€à¥à€¯à€Ÿà€Šà€Ÿ à€®à€¹à€€à¥à€€à¥à€µ
+à€à¥ à€ªà€Šà¥à€ à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€à¥à€ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ à€à¥à€ à€ªà€Š à€à¥
+à€šà€¿à€à€ à€µà€Ÿà€²à¥ à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€à€Ÿ
+à€ªà¥à€°à€Šà€°à¥à€¶à€š à€žà€¬à€žà¥
+à€ªà€¹à€²à¥ à€¹à¥à€à€Ÿ à¥€ à€à€ªà€¯à¥à€à¥à€€à€¿
+à€à€Ÿ à€šà€¿à€°à¥à€£à€¯ à€šà€¿à€®à¥à€šà€²à€¿à€à€¿à€€
+à€¬à€Ÿà€€à¥à€ à€ªà¥ à€šà€¿à€°à¥à€­à€° à€¹à¥
+      <p>
+        
+</ul>
+
+}
+
+# -- Missing translation: _textdatesearch_
+
+# -- Missing translation: _texthelpdatesearch_
+
+# -- Missing translation: _textchangeprefs_
+
+# -- Missing translation: _texthelppreferences_
+
+_texttanumbrowseoptions_ [l=hi] {à€žà€à€à¥à€°à€¹ à€žà¥
+à€à€šà€à€Ÿà€°à¥ à€ªà¥à€°à€Ÿà€ªà¥à€€
+à€à€°à€šà¥ à€à¥ à€²à¥à€¯à¥
+à€šà€¿à€®à¥à€š _numbrowseoptions_ à€€à€°à¥à€à¥
+à€ªà¥à€°à€¯à¥à€ à€à€°à¥à€
+}
+
+_textsimplehelpheading_ [l=hi] {_collectionname_ à€žà€à€à¥à€°à€¹ à€žà¥ à€à€šà€à€Ÿà€°à¥ à€à¥à€žà¥
+à€ªà¥à€°à€Ÿà€ªà¥à€€ à€à¥ à€à€Ÿ
+à€žà€à€€à¥ à€¹à¥à€à¥€
+}
+
+# -- Missing translation: _texthelpscope_
+
Index: /gsdl/stable/macros/home.dm
===================================================================
--- /gsdl/stable/macros/home.dm	(revision 20131)
+++ /gsdl/stable/macros/home.dm	(revision 20131)
@@ -0,0 +1,194 @@
+# this file must be UTF-8 encoded
+
+package home
+
+# set the title of the home page to be "greenstone digital library"
+# in the currently chosen language
+
+_pagetitle_ {_textdescrgreenstone_}
+
+#######################################################################
+# global navigation links
+#######################################################################
+
+# overridden here as we don't want 'home' links on this page
+
+# home:helplink and home:preflink set in nav_css/ns4 macro files
+_globallinks_ {_helplink_ _preflink_}
+
+#######################################################################
+# icons
+#######################################################################
+
+_iconmusiclibrary_ {<img src="_httpicontmusic_" border="1" alt="meldex music library" title="meldex music library">}
+
+_imagecollection_ {<img src="_httpimg_/gsdlhead.gif" alt="_textdescrgreenstone_">}
+
+#######################################################################
+# http macros 
+#
+# These contain the url without any quotes
+#######################################################################
+
+_httppagegsdl_ {_httppagex_(gsdl)}
+_httppagehomepref_ {_httppagex_(homepref)}
+
+#######################################################################
+# images
+#######################################################################
+
+# Buttons for the pane after the collections and before the text
+
+_button_ {<div class="homebutton"><span class="button"><a href="_1_">_2_</a></span></div>
+}
+
+_imagegli_ {_button_(_httppagegli_,_gli:textgli_)}
+
+_imagecollector_ {_button_(_httppagecollector_,_collector:textcollector_)}
+
+_imagedepositor_ {_button_(_httppagedepositor_,_depositor:textdepositor_)}
+
+_imagetranslator_ {_button_(_httppagetranslator_,_gti:textgti_)}
+
+_imageadmin_ {_button_(_httppagestatus_,_home:textadmin_)}
+
+_imagegogreenstone_ {_button_(_home:httppagegsdl_,_home:textabgs_)}
+
+_imagegodocs_ {_button_(_home:httppagedocs_,_home:textgsdocs_)}
+
+
+#######################################################################
+# page content                     
+#######################################################################
+
+# _homeextra_ is the automatically generated list of collections (in a table)
+_content_ {
+<div id="content">
+<div class="divbar">
+<p class="navbar">
+_textdescrselcol_
+</p>
+</div>
+
+<p>
+
+<div class="section">
+_homeextra_
+</div>
+
+<div class="divbar">&nbsp;</div>
+
+<div class="section">
+<table>
+_textgogli_
+_textgocollector_
+_textgodepositor_
+_textgotranslator_
+_textgoadmin_
+_textgogreenstone_
+_textgodocs_
+</table>
+</div>
+
+<div class="divbar">&nbsp;</div>
+
+<div class="section">
+_textaboutgreenstone_
+</div>
+
+<div class="divbar">&nbsp;</div>
+
+</div>
+}
+
+# the _textgocollector_, _textgotranslator_, and _textgoadmin_ macros 
+# may be overridden to be empty from within the receptionist if the 
+# collector, translator, or admin facilities are disabled
+
+_textgogli_ {
+<tr valign=top>
+<td valign=top>_imagegli_</td>
+<td>_gli:textdescrgli_</td>
+</tr>
+}
+
+_textgocollector_ {
+<tr valign=top>
+<td valign=top>_imagecollector_</td>
+<td>_collector:textdescrcollector_</td>
+</tr>
+}
+
+_textgodepositor_ {
+<tr valign=top>
+<td valign=top>_imagedepositor_</td>
+<td>_depositor:textdescrdepositor_</td>
+</tr>
+}
+
+_textgotranslator_ {
+<tr valign=top>
+<td valign=top>_imagetranslator_</td>
+<td>_gti:textdescrtranslator_</td>
+</tr>
+}
+
+_textgoadmin_ {
+<tr valign=top>
+<td valign=top>_imageadmin_</td>
+<td>_textdescradmin_</td>
+</tr>
+}
+
+_textgogreenstone_ {
+<tr valign=top>
+<td valign=top>_imagegogreenstone_</td>
+<td>_textdescrgogreenstone_</td>
+</tr>
+}
+
+_textgodocs_ {
+<tr valign=top>
+<td valign=top>_imagegodocs_</td>
+<td>_textdescrgodocs_</td>
+</tr>
+}
+
+
+package homepref
+_pagetitle_ {_preferences:textpreferences_ - _textdescrgreenstone_}
+
+_imagecollection_ {<a href="_httppagehome_"><img src="_httpimg_/gsdlhead.gif" alt="_textdescrgreenstone_" border="0"></a>}
+
+_globallinks_ {_homelink_ _helplink_}
+
+_pagescriptextra_ {_preferences:pagescriptextra_}
+
+_content_ {
+<div id="content">
+
+<div class="divbar">&nbsp;</div>
+
+<div class="section">
+<form name="PrefForm" method="get" action="_gwcgi_">
+<h3>_preferences:textpresentationprefs_</h3>
+
+<table border="0">
+<tr valign="top">
+<td>_preferences:textlanguage_</td>
+<td>_languageoption_</td>
+</tr>
+<tr valign="top">
+<td>_preferences:textencoding_</td>
+<td>_encodingoption_</td>
+</tr>
+<tr valign="top">
+_preferences:formatoption_
+</tr>
+</table>
+</div>
+
+<div class="divbar">&nbsp;</div>
+
+</div> <!-- \_homepref:content\_ -->
+}
Index: /gsdl/stable/macros/html.dm
===================================================================
--- /gsdl/stable/macros/html.dm	(revision 20131)
+++ /gsdl/stable/macros/html.dm	(revision 20131)
@@ -0,0 +1,66 @@
+# this file must be UTF-8 encoded
+
+package html
+
+_header_ {<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
+<html>
+<head></head>
+}
+
+_footer_ {</html>}
+
+_pagetitle_ {_collectionname_}
+
+_content_ {
+<frameset rows="90,*" noresize frameborder=0>
+  <frame frameborder=0 src="_gwcgi_?e=_compressedoptions_&a=p&p=nav">
+  <frame frameborder=0 src="_cgiarghp_">
+  <noframes>
+  <p>_textframebrowser_</p>
+  </noframes>
+</frameset>
+}
+
+
+package nav
+
+_header_ {_cgihead_
+_htmlhead_
+
+<div id="banner">
+<div class="pageinfo"> 
+<p class="bannerlinks">_globallinks_</p>
+</div>
+</div>
+<div class="bannerextra">_pagebannerextra_</div>
+
+}
+
+_faoheader_ [v=1] {_cgihead_
+_htmlhead_
+_globallinks_
+}
+
+# need transitional for target=""
+_htmlhead_ {
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+<title>_pagetitle_</title>
+<base target="_top">
+_globalscripts_
+
+_Style:cssheader_
+</head>
+
+<body>
+}
+
+_footer_ {</body>
+</html>
+}
+
+_content_ {
+_optnavigationbar_
+}
Index: /gsdl/stable/macros/hungarian.dm
===================================================================
--- /gsdl/stable/macros/hungarian.dm	(revision 20131)
+++ /gsdl/stable/macros/hungarian.dm	(revision 20131)
@@ -0,0 +1,694 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Hungarian Language text and icon macros 
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=hu] {KiadvÃ¡nyok}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=hu] {ForrÃ¡s referencia:}  
+_textdate_ [l=hu] {KiadÃ¡s dÃ¡tuma:}  
+_textnumpages_ [l=hu] {Oldalak szÃ¡ma:}  
+
+_textsignin_ [l=hu] {bejelentkezÃ©s}  
+
+_textdefaultcontent_ [l=hu] {A kÃ©rt oldalt nem lehetett megtalÃ¡lni. KÃ©rem hasznÃ¡lja a bÃ¶ngÃ©szÅje âvisszaâ gombjÃ¡t vagy a fenti âelsÅ oldalâ gombot, hogy visszatÃ©rhessen a Greenstone DigitÃ¡lis KÃ¶nyvtÃ¡rba}  
+
+_textdefaulttitle_ [l=hu] {GSDL hiba}  
+
+_textbadcollection_ [l=hu] {Ez a gyÅ±jtemÃ©ny (called "_cvariable_") nincs betÃ¶ltve a Greenstone digitÃ¡lis kÃ¶nyvtÃ¡rÃ¡ba. }  
+
+_textselectpage_ [l=hu] {OldalvÃ¡lasztÃ¡s}  
+
+_collectionextra_ [l=hu] {Ez a gyÅ±jtemÃ©ny _about:numdocs_ dokumentumot tartalmaz. _about:builddate_ nappal ezelÅtt kÃ©szÃŒlt.}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=hu] {<p>Ez a gyÅ±jtemÃ©ny tartalmaz _numdocs_ _If_("_numdocs_" eq "1",document,documents), Ã¶sszesen _numbytes_  indexelt szÃ¶veg Ã©s metaadat.
+<p><a href="_httppagex_(bsummary)">klikkeljen ide</a> hogy megjelenÃ­tse a gyÅ±jtemÃ©ny Ã¶sszefoglalÃ³jÃ¡t.}  
+
+_textdescrcollection_ [l=hu] {}
+_textdescrabout_ [l=hu] {ErrÅl az oldalrÃ³l}  
+_textdescrhome_ [l=hu] {honlap}  
+_textdescrhelp_ [l=hu] {SegÃ­tsÃ©g oldal}  
+_textdescrpref_ [l=hu] {Preferencia oldal}  
+_textdescrgreenstone_ [l=hu] {Greenstone DigitÃ¡lis KÃ¶nyvtÃ¡r AlkalmazÃ¡s}  
+_textdescrusab_ [l=hu] {Amit talÃ¡ltÃ¡l nehÃ©z hasznÃ¡lni?}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=hu] {KeresÃ©s}  
+_labelSearch_ [l=hu] {KeresÃ©s}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=hu] {CÃ­m}  
+_labelTitle_ [l=hu] {CÃ­mek}  
+_textCreator_ [l=hu] {KÃ©szÃ­tÅ}  
+_labelCreator_ [l=hu] {KÃ©szÃ­tÅk}  
+_textSubject_ [l=hu] {TÃ¡rgy}  
+_labelSubject_ [l=hu] {TÃ¡rgyak}  
+_textDescription_ [l=hu] {LeÃ­rÃ¡s}  
+_labelDescription_ [l=hu] {LeÃ­rÃ¡s}  
+_textPublisher_ [l=hu] {KiadÃ³}  
+_labelPublisher_ [l=hu] {KiadÃ³k}  
+_textContributor_ [l=hu] {KÃ¶zremÅ±kÃ¶dÅ}  
+_labelContributor_ [l=hu] {HozzÃ¡jÃ¡rulÃ¡s}  
+_textDate_ [l=hu] {Datum}  
+_labelDate_ [l=hu] {DÃ¡tumok}  
+_textType_ [l=hu] {TÃ­pus}  
+_labelType_ [l=hu] {TÃ­pusok}  
+_textFormat_ [l=hu] {FormÃ¡tum}  
+_labelFormat_ [l=hu] {FormÃ¡tum}  
+_textIdentifier_ [l=hu] {AzonosÃ­tÃ³}  
+_labelIdentifier_ [l=hu] {AzonosÃ­tÃ³k}  
+_textSource_ [l=hu] {FÃ¡jlnÃ©v}  
+_labelSource_ [l=hu] {FÃ¡jlnevek}  
+_textLanguage_ [l=hu] {Nyelv}  
+_labelLanguage_ [l=hu] {Nyelvek}  
+_textRelation_ [l=hu] {Kapcsolat}  
+_labelRelation_ [l=hu] {Kapcsolatok}  
+_textCoverage_ [l=hu] {LefedÃ©s}  
+_labelCoverage_ [l=hu] {LefedÃ©s}  
+_textRights_ [l=hu] {Jogok}  
+_labelRights_ [l=hu] {Jogok}  
+
+# DLS metadata set
+_textOrganization_ [l=hu] {Szervezet}  
+_labelOrganization_ [l=hu] {Szervezetek}  
+_textKeyword_ [l=hu] {KulcsszÃ³}  
+_labelKeyword_ [l=hu] {Kulcsszavak}  
+_textHowto_ [l=hu] {Hogyan kell}  
+_labelHowto_ [l=hu] {Hogyan kell}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=hu] {KifejezÃ©s}  
+_labelPhrase_ [l=hu] {KifejezÃ©sek}  
+_textCollage_ [l=hu] {KollÃ¡zs}  
+_labelCollage_ [l=hu] {KollÃ¡zs}  
+_textBrowse_ [l=hu] {BÃ¶ngÃ©szÃ©s}  
+_labelBrowse_ [l=hu] {BÃ¶ngÃ©szÃ©s}  
+_textTo_ [l=hu] {-hoz}  
+_labelTo_ [l=hu] {-hoz}  
+_textFrom_ [l=hu] {Forma}  
+_labelFrom_ [l=hu] {Forma}  
+_textAcronym_ [l=hu] {BetÅ±szÃ³}  
+_labelAcronym_ [l=hu] {MozaikszÃ³}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=hu] {BÃ¶ngÃ©ssz _1_ szerint}  
+
+_textdescrSearch_ [l=hu] {Keress kÃŒlÃ¶nleges feltÃ©teleket}  
+_textdescrType_ [l=hu] {BÃ¶ngÃ©ssz erÅforrÃ¡s-tÃ­pus szerint}  
+_textdescrIdentifier_ [l=hu] {BÃ¶ngÃ©ssz erÅforrÃ¡s azonosÃ­tÃ³k szerint}  
+_textdescrSource_ [l=hu] {BÃ¶ngÃ©ssz eredeti fÃ¡jlnÃ©v szerint}  
+_textdescrTo_ [l=hu] {BÃ¶ngÃ©ssz âmezÅhÃ¶zâ szerint}  
+_textdescrFrom_ [l=hu] {BÃ¶ngÃ©sszâmezÅtÅlâ szerint}  
+_textdescrCollage_ [l=hu] {BÃ¶ngÃ©ssz kÃ©pkollÃ¡zs szerint}  
+_textdescrAcronym_ [l=hu] {BÃ¶ngÃ©szd a betÅ±szavakat}  
+_textdescrPhrase_ [l=hu] {BÃ¶ngÃ©sszÅ kifejezÃ©sek}  
+_textdescrHowto_ [l=hu] {BÃ¶ngÃ©ssz âhogyan kellâ kategÃ³riÃ¡kat}  
+_textdescrBrowse_ [l=hu] {BÃ¶ngÃ©szd a dokumetumot}  
+_texticontext_ [l=hu] {A dokumentum megtekintÃ©se}  
+_texticonclosedbook_ [l=hu] {A dokumentum kinyitÃ¡sa Ã©s megtekintÃ©se}  
+_texticonnext_ [l=hu] {A kÃ¶vetkezÅ rÃ©szhez}  
+_texticonprev_ [l=hu] {Az elÅzÅ rÃ©szhez}  
+
+_texticonworld_ [l=hu] {A web dokumentum megtekintÃ©se}  
+
+_texticonmidi_ [l=hu] {Az MIDI dokumentum megtekintÃ©se}  
+_texticonmsword_ [l=hu] {A Microsoft Word dokumentum megtekintÃ©se}  
+_texticonmp3_ [l=hu] {Az MP3 dokumentum megtekintÃ©se}  
+_texticonpdf_ [l=hu] {A PDF dokumentum megtekintÃ©se}  
+_texticonps_ [l=hu] {A PostScript dokumentum megtekintÃ©se}  
+_texticonppt_ [l=hu] {A PowerPoint dokumentum megtekintÃ©se}  
+_texticonrtf_ [l=hu] {A RTF dokumentum megtekintÃ©se}  
+_texticonxls_ [l=hu] {A Microsoft Excel dokumentum megtekintÃ©se}  
+
+_page_ [l=hu] {Oldal}  
+_pages_ [l=hu] {Oldalak}  
+_of_ [l=hu] {-nek}  
+_vol_ [l=hu] {KÃ¶tet}  
+_num_ [l=hu] {Sz.}  
+
+_textmonth00_ [l=hu] {}
+_textmonth01_ [l=hu] {JanuÃ¡r}  
+_textmonth02_ [l=hu] {FebruÃ¡r}  
+_textmonth03_ [l=hu] {MÃ¡rcius}  
+_textmonth04_ [l=hu] {Ãprilis}  
+_textmonth05_ [l=hu] {MÃ¡jus}  
+_textmonth06_ [l=hu] {JÃºnius}  
+_textmonth07_ [l=hu] {JÃºlius}  
+_textmonth08_ [l=hu] {Augusztus}  
+_textmonth09_ [l=hu] {Szeptember}  
+_textmonth10_ [l=hu] {OktÃ³ber}  
+_textmonth11_ [l=hu] {November}  
+_textmonth12_ [l=hu] {December}  
+
+_textdocument_ [l=hu] {Dokumentum}  
+_textsection_ [l=hu] {RÃ©sz}  
+_textparagraph_ [l=hu] {Paragrafus}  
+
+_magazines_ [l=hu] {Magazinok}  
+
+_nzdlpagefooter_ [l=hu] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}  
+
+_linktextHOME_ [l=hu] {ElsÅ oldal}  
+_linktextHELP_ [l=hu] {SEGÃTSÃG}  
+_linktextPREFERENCES_ [l=hu] {PREFERENCIÃK}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=hu] {Greenstone digitÃ¡lis kÃ¶nyvtÃ¡r}  
+_textadmin_ [l=hu] {AdminisztrÃ¡ciÃ³s oldal}  
+_textabgs_ [l=hu] {GreenstonrÃ³l}  
+_textgsdocs_ [l=hu] {Greenstone dokumentÃ¡ciÃ³}  
+
+_textdescradmin_ [l=hu] {"Ãj felhasznÃ¡lÃ³ adhatÃ³ meg, valamint Ã¶sszefoglalja a rendszerben talÃ¡lhatÃ³ gyÅ±jtemÃ©nyeket Ã©s technikai informÃ¡ciÃ³kat ad a Greenstone telepÃ­tÃ©sÃ©hez  gives technical information on the Greenstone installation"	 }  
+
+_textdescrgogreenstone_ [l=hu] {LeÃ­rja a Greenstone softvert Ã©s az ÃjzÃ©landi DigitÃ¡lis KÃ¶nyvtÃ¡r Projektet ahonnan elkezdÅdÃ¶tt }  
+
+_textdescrgodocs_ [l=hu] {Greenstone kÃ©zikÃ¶nyv}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=hu] {A KÃ¶nyvtÃ¡ros illesztÅje}  
+_textdescrgli_ [l=hu] {SegÃ­tsÃ©gÃ©vel Ãºj gyÅ±jtemÃ©nyek kÃ©szÃ­thetÅk, mÃ³dosÃ­thatÃ³k vagy tÃ¶rÃ¶lhetÅk}  
+
+package collector
+
+_textcollector_ [l=hu] {A GyÅ±jtÅ}  
+_textdescrcollector_ [l=hu] {Ez visszadÃ¡tumozza kÃ¶nyvtÃ¡ros illesztÅ egysÃ©gÃ©t, Ã©s a a legtÃ¶bb gyakorlati alkalmazÃ¡sban a kÃ¶nyvtÃ¡ros illesztÅ egysÃ©gÃ©t kellene hasznÃ¡ni helyette??}  
+
+package depositor
+
+_textdepositor_ [l=hu] {A feltÃ¶ltÅ}  
+_textdescrdepositor_ [l=hu] {SegÃ­tsÃ©gÃ©vel lÃ©tezÅ gyÅ±jtemÃ©nyhez dokumentumokat adhat}  
+
+package gti
+
+_textgti_ [l=hu] {A Greenstone fordÃ­tÃ³ egysÃ©ge}  
+_textdescrtranslator_ [l=hu] {SegÃ­t hogy a Greenstone tÃ¶bbnyelvÅ± interfÃ©sze naprakÃ©sz legyen}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=hu] {ErrÅl a gyÅ±jtemÃ©nyrÅl}  
+
+_textsubcols1_ [l=hu] {A teljes gyÅ±jtemÃ©ny _1_ algyÅ±jtemÃ©nybÅl Ã¡ll. Ezek jelenleg elÃ©rhetÅk:}  
+
+_textsubcols2_ [l=hu] {EllenÅrizheti (Ã©s megvÃ¡ltoztathatja) mely algyÅ±jtemÃ©nyt hasznÃ¡lja Ã©ppen a Preferencia oldalon.}  
+
+_titleabout_ [l=hu] {-rÃ³l(rÅl)}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=hu] {ZÃ¡rd be a kÃ¶nyvtÃ¡r ezen rÃ©szÃ©t}  
+_texticonclosedbookshelf_ [l=hu] {Nyisd ki a kÃ¶nytÃ¡r ezen rÃ©szÃ©t Ã©s nÃ©zd meg a tartalmat}  
+_texticonopenbook_ [l=hu] {ZÃ¡rd be ezt a kÃ¶nyvet}  
+_texticonclosedfolder_ [l=hu] {Nyisd ki ezt a mappÃ¡t Ã©s nÃ©zd meg a tartalmat}  
+_texticonclosedfolder2_ [l=hu] {Nysid ki az alfejezetet:}  
+_texticonopenfolder_ [l=hu] {ZÃ¡rd be ezt a mappÃ¡t}  
+_texticonopenfolder2_ [l=hu] {ZÃ¡rd be az alrÃ©szt:}  
+_texticonsmalltext_ [l=hu] {NÃ©zd meg a szÃ¶veg ezen rÃ©szÃ©t}  
+_texticonsmalltext2_ [l=hu] {NÃ©zd meg a szÃ¶veget:}  
+_texticonpointer_ [l=hu] {A jelenlegi rÃ©sz}  
+_texticondetach_ [l=hu] {Nyisdk ki ezt az oldalt egy Ãºj ablakban}  
+_texticonhighlight_ [l=hu] {Emeld ki a keresÃ©si feltÃ©teleket}  
+_texticonnohighlight_ [l=hu] {Ne emeld ki a keresÃ©si feltÃ©teleket}  
+_texticoncontracttoc_ [l=hu] {KisebbÃ­tsd a tartalomjegyzÃ©ket}  
+_texticonexpandtoc_ [l=hu] {Nyisd ki a tartalomjegyzÃ©ket}  
+_texticonexpandtext_ [l=hu] {Mutasd meg az egÃ©sz szÃ¶veget}  
+_texticoncontracttext_ [l=hu] {Csak a jelenleg kivÃ¡lasztott rÃ©szre mutasd a szÃ¶veget}  
+_texticonwarning_ [l=hu] {<b>FigyelmeztetÃ©s: </b>}  
+_texticoncont_ [l=hu] {Folytatja?}  
+
+_textltwarning_ [l=hu] {<div class="buttons">_imagecont_</div> _iconwarning_ a szÃ¶veg nÃ¶velÃ©se nagy mennyisÃ©gÅ± adatot fog generÃ¡lni a bÅngÃ©szÅje szÃ¡mÃ¡ra}  
+
+_textgoto_ [l=hu] {Menj az ... oldalra}  
+_textintro_ [l=hu] {<i>(BevezetÅ szÃ¶veg)</i>}  
+
+_textCONTINUE_ [l=hu] {FOLYTATJA?}  
+
+_textEXPANDTEXT_ [l=hu] {NYISD KI A SZÃVEGET}  
+
+_textCONTRACTCONTENTS_ [l=hu] {VÃGD LE A TARTALMAT}  
+
+_textDETACH_ [l=hu] {ERESZD EL}  
+
+_textEXPANDCONTENTS_ [l=hu] {NYISD KI A TARTALMAT}  
+
+_textCONTRACT_ [l=hu] {VÃGD LE A SZÃVEGET}  
+
+_textHIGHLIGHT_ [l=hu] {KIEMELÃS}  
+
+_textNOHIGHLIGHT_ [l=hu] {NINCS SZÃKSÃG KIEMELÃSRE}  
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=hu] {_If_(_thislast_,results _thisfirst_ - _thislast_ a lekerdezesre: _cgiargq_,nincs talalat a lekerdezesre: _cgiargq_)}  
+_textnoquerytitle_ [l=hu] {KeresÅ oldal}  
+
+_textsome_ [l=hu] {NÃ©hÃ¡ny}  
+_textall_ [l=hu] {Minden}  
+_textboolean_ [l=hu] {Logikai}  
+_textranked_ [l=hu] {Besorolt}  
+_textnatural_ [l=hu] {TermÃ©szetes}  
+_textsortbyrank_ [l=hu] {Relevancia besorolÃ¡s}  
+_texticonsearchhistorybar_ [l=hu] {KeresÃ©si elÅzmÃ©nyek}  
+
+_textifeellucky_ [l=hu] {SzerencsÃ©snek Ã©rzem magam!}  
+
+#alt text for query buttons
+_textusequery_ [l=hu] {HasznÃ¡ld ezt a lekÃ©rdezÃ©st}  
+_textfreqmsg1_ [l=hu] {Szavak szÃ¡ma:}  
+_textpostprocess_ [l=hu] {_If_(_quotedquery_,<br><i>utokezelt hogy megtalalhato legyen _quotedquery_</i>
+)}  
+_textinvalidquery_ [l=hu] {ÃrvÃ©nytelen lekÃ©rdezÃ©si szintaxis}  
+_textstopwordsmsg_ [l=hu] {A kÃ¶vetkezÅ szavak tÃºl elterjedtek Ã©s nincsenek a listÃ¡n}  
+_textlucenetoomanyclauses_ [l=hu] {A lekÃ©rdezÃ©se tÃºl sok keresÃ©si rÃ©szt tartalmaz; kÃ©rem prÃ³bÃ¡lkozzon egy specifikusabb lekÃ©rdezÃ©ssel}  
+
+_textmorethan_ [l=hu] {TÃ¶bb mint}  
+_textapprox_ [l=hu] {#NAME?}  
+_textnodocs_ [l=hu] {Nincs dokumentum ami megfelelne a lekÃ©rdezÃ©snek.}  
+_text1doc_ [l=hu] {1 dokumentum megfelel a lekÃ©rdezÃ©snek}  
+_textlotsdocs_ [l=hu] {Dokumentumok megfelelnek a lekÃ©rdezÃ©snek}  
+_textmatches_ [l=hu] {MegfeleltetÃ©sek}  
+_textbeginsearch_ [l=hu] {Kezd el a keresÃ©st}  
+_textrunquery_ [l=hu] {Futtasd a lekÃ©rdezÃ©st}  
+_textclearform_ [l=hu] {ÃresÃ­tsd a formanyomtatvÃ¡nyt}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=hu] {Szavak
+}  
+_textinfield_ [l=hu] {âŠ a mezÅben}  
+_textfoldstem_ [l=hu] {(kis/nagybetu, to)}  
+
+_textadvquery_ [l=hu] {Vagy kÃ©rdezzen le kÃ¶zvetlenÃŒl:}  
+_textallfields_ [l=hu] {Minden mezÅ}  
+_texttextonly_ [l=hu] {Cask szÃ¶veg}  
+_textand_ [l=hu] {Ãs}  
+_textor_ [l=hu] {Vagy}  
+_textandnot_ [l=hu] {Ãs nem}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=hu] {Keress a _indexselection_ _If_(_jselection_,_jselection_-bol )_If_(_gselection_, _gselection_ levo szinten )_If_(_nselection_, _nselection_ -beli nyelvben ) ami tartalmazza _querytypeselection_ a szavait _If_(_sfselection_,\,_allowformbreak_ rendezve az eredmenyt _sfselection_ szerint)}  
+
+_textadvancedsearch_ [l=hu] {Keress _indexselection_ _If_(_jselection_, _jselection_-bol )_If_(_gselection_, _gselection_ levo szinten )_If_(_nselection_, _nselection_ -beli nyelvben) felhasznalva a _querytypeselection_ lekerdezest}  
+
+_textadvancedmgppsearch_ [l=hu] {keress _indexselection_ _If_(_jselection_,_jselection_-bol )_If_(_gselection_, _gselection_ levo szinten)_If_(_nselection_,_nselection_ beli nyelvben ) es mutasd az erdmenyt in _formquerytypeadvancedselection_-beli sorrendben}  
+
+_textadvancedlucenesearch_ [l=hu] {Keress _indexselection__If_(_jselection_, _jselection_-bol)_If_(_gselection_, _gselection_ levo szinten)_If_(_nselection_, _nselection_-ban language)_If_(_sfselection_,\,_allowformbreak_ rendezd az eredmenyt _sfselection_\ szerint,) -nek }  
+
+_textformsimplesearch_ [l=hu] {Keress _If_(_jselection_, _jselection_)_If_(_gformselection_,  _gformselection_ levo szinten)_If_(_nselection_, _nselection_ -beli nyelvben)_If_(_sfselection_,\, rendezve az eredmenyeket _sfselection_\ szerint,) for _formquerytypesimpleselection_ of }  
+
+_textformadvancedsearchmgpp_ [l=hu] {Keress _If_(_jselection_,_jselection_ )_If_(_gformselection_, _gformselection_ levo szinten)_If_(_nselection_, _nselection_ -beli nyelvben ) es mutasd az eredmenyt a _formquerytypeadvancedselection_ lekerdezes sorendjeben}  
+
+_textformadvancedsearchlucene_ [l=hu] {Keress _If_(_jselection_, _jselection_)_If_(_gformselection_,  _gformselection_ levo szinten)_If_(_nselection_, _nselection_ -beli nyelvben)_If_(_sfselection_,\, rendezve az eredmenyeket _sfselection_\ szerint,)  }  
+
+_textnojsformwarning_ [l=hu] {FigyelmeztetÃ©s: Javascript hasznÃ¡lata nem engedÃ©lyezett a web bÃ¶ngÃ©szÅben. <br> âformâ keresÃ©shez kÃ©rem engedÃ©lyezze.}  
+_textdatesearch_ [l=hu] {Ebben a gyÅ±jtemÃ©nyben a megadott dÃ¡tumon belÃŒli dokumentumokra lehet keresni, vagy olyan dokumentumokra amik egy adott dÃ¡tumot tartalmaznak.}  
+_textstartdate_ [l=hu] {KezdÅ (vagy csak) dÃ¡tum}  
+_textenddate_ [l=hu] {BefejezÃ©si datum:}  
+_textbc_ [l=hu] {KÃE - KeresztÃ©ny Ãra ElÅtt}  
+_textad_ [l=hu] {K.Ã. â KeresztÃ©ny Ãra}  
+_textexplaineras_ [l=hu] {A C.E. Ã©s a B.C.E. alternatÃ­vÃ¡k a K.u. Ã©s K.e. jelÃ¶lÃ©sekre. Ezeket a jelÃ¶lÃ©seket kultÃºrafÃŒggetlennek lehet tekinteni Ã©s azt jelentik, hogy âKeresztÃ©ny Ãraâ Ã©s  âKeresztÃ©ny Ãra ElÅttâ}  
+
+_textstemon_ [l=hu] {Elhagyott szÃ³vÃ©gek}  
+
+_textsearchhistory_ [l=hu] {KeresÃ©si elÅzmÃ©nyek}  
+
+#text macros for search history
+_textnohistory_ [l=hu] {Nincs keresÃ©si elÅzmÃ©ny}  
+_texthresult_ [l=hu] {EredmÃ©ny}  
+_texthresults_ [l=hu] {EredmÃ©nyek}  
+_texthallwords_ [l=hu] {Minden szÃ³}  
+_texthsomewords_ [l=hu] {NÃ©hÃ¡ny szÃ³}  
+_texthboolean_ [l=hu] {Logikai Ã©rtÃ©k}  
+_texthranked_ [l=hu] {Rangsorolt}  
+_texthcaseon_ [l=hu] {KisbetÅ±-nagybetÅ±nek egyeznie kell}  
+_texthcaseoff_ [l=hu] {KisbetÅ±-nagybetÅ± felcserÃ©lhetÅ}  
+_texthstemon_ [l=hu] {Ered}  
+_texthstemoff_ [l=hu] {Nem ered}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=hu] {A preferenciÃ¡k a kÃ¶vetkezÅk szerint lettek beÃ¡llÃ­tva. Ne hasznÃ¡lja a bÃ¶ngÃ©szÅ âvisszaâ gombjÃ¡t, mert ez semmissÃ© teszi a beÃ¡llÃ­tÃ¡sokat. Ehelyett klikkeljen a felsÅ elÃ©rÃ©si szalag egyik gombjÃ¡ra.}  
+_textsetprefs_ [l=hu] {ÃllÃ­tsa be a preferenciÃ¡kat}  
+_textsearchprefs_ [l=hu] {LekÃ©rdeÃ©si preferenciÃ¡k}  
+_textcollectionprefs_ [l=hu] {GyÅ±jtemÃ©ny preferenciÃ¡i}  
+_textpresentationprefs_ [l=hu] {ElÅadÃ¡si preferenciÃ¡k}  
+_textpreferences_ [l=hu] {PreferenciÃ¡k}  
+_textcasediffs_ [l=hu] {NagybetÅ±/kisbetÅ± kÃŒlÃ¶nbsÃ©gek}  
+_textignorecase_ [l=hu] {Hagyja figyelmen kÃ­vÅ±l a nagybetÅ±/kisbetÅ± kÃŒlÃ¶nbsÃ©geket}  
+_textmatchcase_ [l=hu] {NagybetÅ±/kisbetÅ±-nek meg kell felelnie}  
+_textwordends_ [l=hu] {SzÃ³vÃ©gek:}  
+_textstem_ [l=hu] {Hagyja el a szÃ³vÃ©geket}  
+_textnostem_ [l=hu] {Az egÃ©sz szÃ³nak meg kell felelnie}  
+_textaccentdiffs_ [l=hu] {Ãkezet kÃŒlÃ¶nbsÃ©gek:}  
+_textignoreaccents_ [l=hu] {Hagyja figyelmen kÃ­vÅ±l az Ã©kezeteket}  
+_textmatchaccents_ [l=hu] {Az Ã©kezetnek meg kell felelnie}  
+
+_textprefop_ [l=hu] {_maxdocoption_ talÃ¡lat, oldalankÃ©nt _hitsperpageoption_ talÃ¡lattal.}  
+_textextlink_ [l=hu] {ElÃ©rÃ©s kÃŒlsÅ web oldalakhoz:}  
+_textintlink_ [l=hu] {A forrÃ¡sdokumentum innen szÃ¡rmazik:}  
+_textlanguage_ [l=hu] {illesztÅ nyelv:}  
+_textencoding_ [l=hu] {KÃ³dolÃ¡s:}  
+_textformat_ [l=hu] {IllesztÅ formÃ¡tum:}  
+_textall_ [l=hu] {Minden}  
+_textquerymode_ [l=hu] {LekÃ©rdeÃ©si mÃ³d:}  
+_textsimplemode_ [l=hu] {EgyszerÅ± lekÃ©rdezÃ©si mÃ³d}  
+_textadvancedmode_ [l=hu] {RÃ©szletes lekÃ©rdezÃ©si mÃ³d (megenged logikai keresÃ©st, Ãºgy mint !, &, |, Ã©s zÃ¡rÃ³jelek)}  
+_textlinkinterm_ [l=hu] {KÃ¶zbÃŒlsÅ oldalakon keresztÃŒl}  
+_textlinkdirect_ [l=hu] {Menjen kÃ¶zvetlenÃŒl ide}  
+_textdigitlib_ [l=hu] {A digitÃ¡lis kÃ¶nyvtÃ¡r}  
+_textweb_ [l=hu] {A web}  
+_textgraphical_ [l=hu] {Grafikus}  
+_texttextual_ [l=hu] {SzÃ¶veges}  
+_textcollectionoption_ [l=hu] {<p>
+mellÃ©kgyÅ±jtemÃ©ny hozzÃ¡adÃ¡sa:
+<br>}  
+
+_textsearchtype_ [l=hu] {LekÃ©rdeÃ©si stÃ­lus:}  
+_textformsearchtype_ [l=hu] {A _formnumfieldoption_ mezÅket tartalmazza}  
+_textplainsearchtype_ [l=hu] {Normal a _boxsizeoptionïŒ¿ lekÃ©rdeÃ©si cellÃ¡val}  
+_textregularbox_ [l=hu] {Egyetlen sor}  
+_textlargebox_ [l=hu] {Nagy}  
+
+_textrelateddocdisplay_ [l=hu] {Mutasd meg a kapcsolÃ³dÃ³ dokumentumokat}  
+_textsearchhistory_ [l=hu] {LekÃ©rdezÃ©si elÅzmÃ©nyek:}  
+_textnohistory_ [l=hu] {Nincs lekÃ©rdezÃ©si elÅzmÃ©ny}  
+_texthistorydisplay_ [l=hu] {Mutasd meg a _historynumrecords_ keresÃ©si elÅzmÃ©nyeket}  
+_textnohistorydisplay_ [l=hu] {Ne mutass lekÃ©rdezÃ©si elÅzmÃ©nyt}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=hu] {A kÃ¶vetkezÅk alapjÃ¡n rendezd a dokumentumokat }  
+_textalsoshowing_ [l=hu] {MÃ©g megmutatott}  
+_textwith_ [l=hu] {Legfeljebb}  
+_textdocsperpage_ [l=hu] {OldalankÃ©nti dokumentum}  
+
+_textfilterby_ [l=hu] {Keress dokumentumokat amelyek tartalmaznak}  
+_textall_ [l=hu] {Minden}  
+_textany_ [l=hu] {Valamely}  
+_textwords_ [l=hu] {A szavaknak}  
+_textleaveblank_ [l=hu] {Hagyja ezt a cellÃ¡t ÃŒresen hogy az Ã¶sszes dokumentumot megkaphassa}  
+
+_browsebuttontext_ [l=hu] {Rendezd a dokumentumokat}  
+
+_nodata_ [l=hu] {<i>Nincs adapt</i>}  
+_docs_ [l=hu] {Dokumentumok}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=hu] {segÃ­tsÃ©g}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=hu] {BÃ¶ngÃ©szd a dokumentumokat _1_ szerint a _2_ gombra klikkelve}  
+
+_textSearchhelp_ [l=hu] {Keress rÃ¡ a szÃ¶veg kÃŒlÃ¶nbÃ¶zÅ szavaira a _labelSearch_ gombra klikkelve  }  
+_textTohelp_ [l=hu] {BÃ¶ngÃ©sz dokumentumokat mezÅnkÃ©nt a _labelTo_ gombra klikkelve}  
+_textFromhelp_ [l=hu] {BÃ¶ngÃ©szd a kiadvÃ¡nyokat âmezÅktÅlâ szerint a _labelFrom_ gombra klikkelve}  
+_textBrowsehelp_ [l=hu] {BÃ¶ngÃ©ssz dokumentumokat}  
+_textAcronymhelp_ [l=hu] {BÃ¶ngÃ©ssz a dokumentumokban betÅ±szÃ³ szerint a _labelAcronym_ gombra klikkelve}  
+_textPhrasehelp_ [l=hu] {bongessza dokumentumban elofordulo kifejezeseket _labelPhrase_ gombra klikkelve. Ez a phind kifejezeskeresot hasznalja.}  
+
+_texthelptopicstitle_ [l=hu] {TÃ©mÃ¡k}  
+
+_textreadingdocs_ [l=hu] {Hogyan kell a dokumentumokat olvasni}  
+
+_texthelpreadingdocs_ [l=hu] {<p>Meg fogja tudni mondani, amikor egy kÃ¶nyvhÃ¶z vagy dokumentumhoz Ã©r, mert a cÃ­m vagy a fedÅlap fÃ©nykÃ©pe megjelenik a az oldal bal felsÅ rÃ©szÃ©ben. NÃ©hÃ¡ny gyÅ±jtemÃ©nyben ez egyÃŒtt jelenik meg a tartalomjegyzÃ©kkel, mÃ­g nÃ©hÃ¡nyban csak az Ã©ppen aktuÃ¡lis oldal szÃ¡ma jelenik meg egy cellÃ¡val ami lehetÅsÃ©get nyÃºjt hogy egy Ãºj oldalt vÃ¡lasszon Ã©s elÅre vagy hÃ¡tra mozogjon. A tartalomjegyzÃ©kben az Ã©ppen aktuÃ¡lis rÃ©sz feje vastagon van kiemelve, Ã©s a tablet ki lehet nyitni â klikkeljen a mappÃ¡ra hogy kinyissa Ã©s becsukja;klikkeljen a nyitott kÃ¶nyvere hogy becsukja.</p>
+
+<p>Alatta a az Ã©ppen aktuÃ¡lis rÃ©sz szÃ¶vege van. Amikor elolvasta, az oldal aljÃ¡n lÃ©vÅ nyilakkal a kÃ¶vetkezÅ rÃ©szhez vagy az elÅzÅ rÃ©szhez ugorhat.</p>
+
+<p>A cÃ­m vagy a feÅlap fÃ©nykÃ©pe alatt vannak gombok. Klikkeljen a
+<i>_document:textEXPANDTEXT_</i> gombra hogy ha ki akarja nyitni az aktuÃ¡lis rÃ©sz vagy kÃ¶nyv teljes szÃ¶vegÃ©t. Ha a dokumentum nagy, ez egy csomO idÅt vehet igÃ©nybe, Ã©s egy csomÃ³ memÃ³riÃ¡t fog hasznÃ¡ni! Klikkeljen a  <i>_document:textEXPANDCONTENTS_</i> gombra hogy kinyithassa a teljes tartalomjegyzÃ©ket, ahol az Ã¶sszes fejezet Ã©s alfejezetcÃ­met lÃ¡thatja. Klikkeljen a <i>_document:textDETACH_</i> gombra hogy ha egy Ãºj ablakot akar nyitni a dokumentumnak (Ez hasznos amikor dokumentumokat akar Ã¶sszehasonlÃ­tani, vagy amikor egyszerre kettÅt akar olvasni.) VÃ©gezetÃŒl, amikor egy keresÃ©st hajt verge szavakra, a szavak ki lesznek emelve. Klikkeljen a <i>_document:textNOHIGHLIGHT_</i> gombra hogy megszÃŒntesse a kiemelÃ©st.</p>
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=hu] {Nyisk ki ezt a kÃ¶nyvespolcot}  
+_texthelpopenbook_ [l=hu] {Nyisd ki/ zÃ¡rd be ezt a kÃ¶nyvet}  
+_texthelpviewtextsection_ [l=hu] {NÃ©zze a szÃ¶veg ezen rÃ©szÃ©t}  
+_texthelpexpandtext_ [l=hu] {Mutasd meg az egÃ©sz szÃ¶veget, vagy sem}  
+_texthelpexpandcontents_ [l=hu] {Terjeszd ki a tartalomjegyzÃ©ket, vagy sem}  
+_texthelpdetachpage_ [l=hu] {Nyisd ki ezt az oldalt egy Ãºj oldalon}  
+_texthelphighlight_ [l=hu] {KeresÃ©si feltÃ©telek kiemelÃ©se, vagy sem}  
+_texthelpsectionarrows_ [l=hu] {Menjen az elÅzÅ/kÃ¶vetkezÅ rÃ©szhez}  
+
+
+_texthelpsearchingtitle_ [l=hu] {Hogyan kell egyes szavakra keresni}  
+
+_texthelpsearching_ [l=hu] {<p>
+  A lekÃ©rdezÃ©si oldalon a kÃ¶vetkezÅ egyszerÅ± lÃ©pÃ©seket kell tenni a lekÃ©rdezÃ©shez:<p>
+  
+  <ol><li>JelÃ¶lje meg mit akar keresni
+      <li>JelÃ¶lje meg hogy minden vagy csak nÃ©mely szÃ³ra akar e keresni
+      <li>Ãrja be a szavakat amiket keresni akar
+      <li>Klikkeljen a <i>keresÃ©s kezdÃ©se</i> gombra
+  </ol>
+
+<p>Amikor egy kekÃ©rdezÃ©st kÃ©szÃ­t, 20 megfeleltett cÃ­m fog megjelenni. A vÃ©gÃ©n van egy gomb hogy a kÃ¶vetkezÅ 20-hoz ugorhasson. Onnan pedig talÃ¡lni fog a harmadik 20-hoz vagy az elsÅ 20-hoz ugrÃ³ gombokat, Ã©s Ã­gy tovÃ¡bb. Klikkeljen bÃ¡rmely dokumentum cÃ­mÃ©re vagy a kis gombra mellette, hogy megnÃ©zhesse.
+
+<p>MaximÃ¡lisan 100 a dokumentumok szÃ¡mÃ¡ra az alapÃ©rtelmezett Ã©rtÃ©k az egyszeri megjelenÃ­tÃ©skor. Ezt meg lehet vÃ¡ltoztani az oldal tetejÃ©n lÃ©vÅ 
+  <i>_Global:linktextPREFERENCES_</i> gombra valÃ³ klikkelÃ©ssel.<p>
+}  
+
+_texthelpquerytermstitle_ [l=hu] {KeresÃ©si feltÃ©telek}  
+_texthelpqueryterms_ [l=hu] {<p> BÃ¡rmit is kerÃŒl a lekÃ©rdezÃ©si cellÃ¡ba, ez Ãºgy Ã©rtelmezÅdik mint szavak Ã©s kifejezÃ©sek listÃ¡ja, az Ãºgynevezett âkeresÃ©si feltÃ©telekâ. Egy feltÃ©tel egyetlen szÃ³, ami csak betÅ±ket Ã©s szÃ¡mokat tartalmaz, vagy egy kifejezÃ©s ami szavak sorozatÃ¡t tartalmazza idÃ©zÅjelek kÃ¶zÃ¶tt. A feltÃ©telek betÅ±kÃ¶zÃ¶kkel vannak elvÃ¡lasztva. Ha bÃ¡rmely mÃ¡s karakter, mint pl. pont is szerepel, akkor ezek mint elvÃ¡lasztÃ³k szerepelnek ugyanÃºgy mint a betÅ±kÃ¶zÃ¶k. Ãs akkor ezek a kÃ¶zÃ¶k elhagyhatÃ³k. Nem lehet olyan szavakra keresni, amik pontot tartalmaznak.
+
+<p>Pl.  lekÃ©rdezÃ©s<p>
+    <ul><kbd>HÃ¡rom a kislÃ¡ny. Verses drÃ¡ma 2 rÃ©szben (1931)</kbd></ul>
+      <p>ugyanolyan lekÃ©rdezÃ©si feltÃ©tel mint a<p>
+      <ul><kbd>HÃ¡rom a kislÃ¡ny Verses drÃ¡ma 2 rÃ©szben 1931</kbd></ul><p>
+}  
+
+_texthelpmgppsearching_ [l=hu] {Az MGPP-vel kÃ©szÃŒlt gyÅ±jtemÃ©nyekre nÃ©hÃ¡ny mÃ¡s opciÃ³ beÃ¡llÃ­tÃ¡sÃ¡ra is lehetÅsÃ©g van.
+<ul>
+<li>Egy <b>*</b> a feltÃ©tel vÃ©gÃ©n meg fog felelni minden szÃ³nak ami azzal a szÃ³val <b>kezdÅdik</b>, pl.  <b>szÃ¡mt*</b> meg fog felelni minden <b>szÃ¡m</b>-mal kezdÅdÅ szÃ³.
+<li><b>/x</b> hasznÃ¡lhatÃ³ arra, hogy nagyobb sÃºlya legyen bizonyos lekÃ©rdezÃ©si feltÃ©telnek, pl. <b>szÃ¡mÃ­tÃ³gÃ©p/10 tudomÃ¡ny</b> -ban a âszÃ¡mÃ­tÃ³gÃ©pâ-nek 10-szer akkora sÃºlya van mint a âtudomÃ¡nyâ-nak amikor a megtalÃ¡lt dokumentumokat rangsoroljÃ¡k.
+</ul>
+}  
+
+_texthelplucenesearching_ [l=hu] {"A Lucene-nel kÃ©szÃŒlt gyÅ±jtemÃ©nyekre nÃ©hÃ¡ny mÃ¡s opciÃ³ beÃ¡llÃ­tÃ¡sÃ¡ra is lehetÅsÃ©g van.
+
+<ul>
+<li><b>?</b> hasznÃ¡lhatÃ³ mint joker bÃ¡rmely betÅ± helyÃ©n. Pl.  <b>b?t</b>keresÃ©sre a <b>lÃ©p</b>, <b>lop,</b> and <b>lap</b> stb. szavak fognak megfelelni.
+<li><b>*</b> hasznÃ¡lhatÃ³ jokerkÃ©nt tÃ¶bb mint egy betÅ± esetÃ©n. Pl. <b>comput*</b> keresÃ©s esetÃ©n minde szÃ³ meg fog felelni ami a <b>szÃ¡m</b>â-mal kezdÅdik..
+</ul>
+MindekÃ©t joker hasznÃ¡lhatÃ³ akÃ¡r a feltÃ©tel kÃ¶zepÃ©n vagy vÃ©gÃ©n. Nem lehet hasznÃ¡lni Åket a feltÃ©tel elejÃ©n.
+"	 }  
+
+_texthelpquerytypetitle_ [l=hu] {LekÃ©rdezÃ©si tÃ­pus	 }  
+_texthelpquerytype_ [l=hu] {<p>KÃ©tfÃ©le lekÃ©rdezÃ©s lehetsÃ©ges
+
+<ul>
+  <li>LekÃ©dezÃ©s <b>minden</b> szÃ³ra.. Ez olyan dokumentumra (vagy fejezetre, vegy cÃ­mre) keres, ami tartalmazza mindzokat a aszavakat amiket megadtak a keresÃ©sben. Azon dokumentumok amik megfelelnek a lekÃ©rdezÃ©snek meg lesznek jelenitve a felÃ©pÃ­tÃ©s sorrendjÃ©ben.
+<p>
+
+  <li>LekÃ©rdezÃ©sek<b>valamely</b>szÃ³ra.  EgyszerÅ±en listÃ¡zzon feltÃ©teleket, amik valÃ³szÃ­nÅ±en megtalÃ¡lhatÃ³k a dokumentumban amit keres. A dokumentumok meg lesznek jelenÃ­tve abban a sorrendben hogy mennyire kÃ¶zelien felelnek meg a lekÃ©rdezÃ©s feltÃ©teleinek. A kÃ¶zelsÃ©g meghatÃ¡rozÃ¡sa azt jelenti, hogy,
+
+      <p><ul>
+        <li> KÃ¶zelebbi dokumentum az, amelyik tÃ¶bb szÃ³t tartalmaz;
+        <li> Azon feltÃ©telek-szavak, melyek ritkÃ¡bbak a gyÅ±jtemÃ©nyben Ã¡ltalÃ¡ban fontosabbak, mint az elterjedtebbek;
+        <li> Roved dokumentumok jobban megfelelnek mint a hosszabbak.
+      </ul>
+</ul>
+
+<p>HasznÃ¡ljon olyan sok keresÃ©si feltÃ©telt, szÃ³t amenniyit csak akar â egy egÃ©sz mondat vagy egy egÃ©sz paragrafus. Ha csak 1 feltÃ©telt-szÃ³t ad meg, akkor a dokumentumok a szÃ³ megjelenÃ©sÃ©nek sÅ±rÅ±sÃ©gÃ©nek sorrendjÃ©ben fognak megjelenni..<p>
+}  
+
+_texthelpadvancedsearchtitle_ [l=hu] {Az _1_ keresÅ motor van beÃ¡llÃ­tva a rÃ©szletes keresÃ©sben}  
+
+_texthelpadvancedsearch_ [l=hu] {<p>Ha a rÃ©szletes lekÃ©rdezÃ©s van kivÃ¡lasztva (a preferenciÃ¡k kÃ¶zÃ¶tt), akkor egy kicsit kÃŒlÃ¶nbÃ¶zÅ keresÃ©si opciÃ³ Ã¡ll rendelkezÃ©sre. _selectadvancedsearch_}  
+
+_texthelpadvsearchmg_ [l=hu] {A rÃ©szletes keresÃ©s az MG gyÅ±jtemÃ©nyben a rangsorolt Ã©s a logokai opciÃ³kat engedi meg. Egy A <b>rangsorolt</b> keresÃ©s pontosan ugyan az mint <b>egy</b> keresÃ©s ami a <a href="\#query-type">_texthelpquerytypetitle_</a> -ben van leÃ­rva.  <p>_texthelpbooleansearch_}  
+
+_texthelpbooleansearch_ [l=hu] {Egy <b>logikai</b> keresÃ©s megengedi, hogy kombinÃ¡lni lehessen olyan feltÃ©teleket melyek hasznÃ¡lnak & ("Ã©s"-re), | ("vagy"-ra), Ã©s ! ("nem"-re), valamint zÃ¡rÃ³jeleket, ha szÃŒksÃ©g van csoportosÃ­tÃ¡sra. Az alapÃ©rtelmezett operator | ("vagy"). <p>  PÃ©ldÃ¡ul, <b>csiga & gazdÃ¡lkodÃ¡s</b> meg fog talÃ¡lni dokumentumokat amelyek tartalmazzÃ¡k mind a <b> csiga-t </b> ÃS <b> gazdÃ¡lkodÃ¡s-t </b>, de a <b> csiga | gazdÃ¡lkodÃ¡s </b> meg fogja talÃ¡lni mindazokat a dokumentumokat, amelyek tartalmazzÃ¡k vagy <b> csiga-t </b> VAGY <b> gazdÃ¡lkodÃ¡s-t </b>.  <b> csiga! gazdÃ¡lkodÃ¡s </b> meg fogja talÃ¡lni mindazokat a dokumentumokat amelyek tartalmazzÃ¡k <b> csiga-t </b> ÃS NEM tartalmazzÃ¡k <b> gazdÃ¡lkodÃ¡s-t </b>. <p>  Pontosabb lekÃ©rdezÃ©seket lehet kÃ©szÃ­teni operÃ¡torok Ã©s zÃ¡rÃ³jelek segÃ­tsÃ©gÃ©vel. PÃ©ldaul, <b>(birka | marha) & (gazdasÃ¡g | Ã¡llomÃ¡s)</b>, vagy <b>birka | marha | kecske !sertÃ©s</b>}  
+
+_texthelpadvsearchmgpp_ [l=hu] {Az MGPP gyÅ±jtemÃ©nyben a rÃ©szletes keresÃ©s logikai operÃ¡torokat hasznÃ¡l. _texthelpbooleansearch_  <p>az eredmÃ©ny megtekinthetÅ <b>ragsorolva</b>, ahogy az le van Ã­rva a href="\#query-type">_texthelpquerytypetitle_</a> keresÃ©sben, vagy âtermÃ©szetesâ (vagy âfelÃ©pÃ­tettâ) sorrendben. Ez az a sorrend amelyben a dokumentumok feldolgozÃ¡sra kerÃŒlnek a gyÅ±jtemÃ©ny lÃ©trehozÃ¡sakor. <p> tovÃ¡bbi operÃ¡torok mÃ©g <b>NEARx</b> Ã©s <b>WITHINx</b>.  NEARx jelenti a maximÃ¡lis tÃ¡volsÃ¡got (x szÃ³) amelyeknek szerepelniÃŒk kell 2 lekÃ©rdezÃ©s feltÃ©teleiben  WITHINx megadja, hogy a mÃ¡sodik feltÃ©telbeli elemnek szerepelnie kell x szÃ³n belÃŒl az elsÅ <i>utÃ¡n</i>. Ez hasonlÃ­t a NEAR-hez, de a sorrend fontos. Az alapÃ©rtrelmezett tÃ¡volsÃ¡g 20.}  
+
+_texthelpadvancedsearchextra_ [l=hu] {MEGJEGYZÃS: ezek az operÃ¡torok egyike sem hasznÃ¡lhatÃ³ ha a keresÃ©s az egyszerÅ± lekÃ©rdezÃ©sre van Ã¡llÃ­tva}  
+
+_texthelpadvsearchlucene_ [l=hu] {A rÃ©szletes keresÃ©s a Lucene gyÅ±jtemÃ©nyben logokai operÃ¡torokat hasznÃ¡lnak. _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=hu] {MezÅ keresÃ©s}  
+
+_texthelpformsearch_ [l=hu] {<p> MezÅkeresÃ©s lehetÅvÃ© teszi a keresÃ©sek kombinÃ¡ciÃ³jÃ¡t mezÅk kÃ¶zÃ¶tt. Pl. keresni lehet âKovÃ¡csâ-ra a cÃ­mben ÃS âcsiga gazdÃ¡lkodÃ¡sâ-ra a tÃ¡rgyban. Az egyszerÅ lekÃ©rdezÃ©sben minden sor mint egy normÃ¡lis egysoros keresÃ©s mÅ±kÃ¶dik. Az egyes sorok ÃS-sel vannak Ã¶sszekapcsolva (egy âmindenâ keresÃ©sre) vagy VAGY-gyal (a nÃ©hÃ¡ny keresÃ©sre). MezÅn belÃŒli feltÃ©telek ugyanilyen mÃ³don vannak Ã¶szekapcsolva. RÃ©szletes keresÃ©s esetÃ©n az ÃS/VAGY/NEM mezÅk kÃ¶zÃ¶tti tetszÅleges kombinÃ¡ciÃ³it lehet vÃ¡lasztani, valamint a mezÅkÃ¶n belÃŒl logokai oprÃ¡torokat lehet hasznÃ¡lni.}  
+
+_texthelpformstemming_ [l=hu] {A âkis/nagybetÅ±â Ã©s a âtÅâ cellÃ¡k lehetÅvÃ© teszik mezÅn belÃŒli feltÃ©telek esetÃ©n a kis/nagybetÅ± Ã©s szÃ³tÅ jelÃ¶lÃ©sÃ©t.}  
+
+_textdatesearch_ [l=hu] {KeresÃ©s dÃ¡tumokkal}  
+
+_texthelpdatesearch_ [l=hu] {DÃ¡tumkeresÃ©s nem csak olyan dokumentumokat talÃ¡l meg ami megfelelnek a keresÃ©si feltÃ©teleknek, hanem olyan esemÃ©nyeket is amik az adott idÅintervallumban vannak. Keresni lehet dokumentumokat egy bizonyos Ã©vtÅl, vagy idÅ(dÃ¡tum)intervallumtÃ³l. MegjegyzendÅ, hogy nem szÃŒksÃ©ges kÃŒlÃ¶n keresÃ©si feltÃ©tel a dÃ¡tumra, csak dÃ¡tumra is lehet keresni; illetve nem kell egyÃ¡talÃ¡n dÃ¡tumnak szerepelnie a keresÃ©si feltÃ©telek kÃ¶zÃ¶tt.}  
+
+_texthelpdatehowtotitle_ [l=hu] {Hogyan kell hasznÃ¡lni ezt a lehetÅsÃ©get:}  
+_texthelpdatehowto_ [l=hu] {<ul>
+   <li>egyetlen Ã©vhez kapcsolÃ³dÃ³ dokumentumok keresÃ©se:<p>
+   <ul>
+       <li>Ãrj be bÃ¡rmilyen kÅzÅnsÃ©ges keresÃ©si feltÃ©telt.
+       <li>Ãrd be az Ã©vet a "kezdÅ (vagy csak) dÃ¡tum"  cellÃ¡ba.
+       <li>Ha a dÃ¡tum a K.E.Ã.-rÅl valÃ³ (Krisztus elÅtt), vÃ¡lassza a K.E.Ã opciÃ³t a lehÃºzhatÃ³ menÃŒbÅl
+       <li>Kezdje a keresÃ©st ahogy szokta.
+   </ul>
+<p><li>idÅintervallulmhoz kapcsolÃ³dÃ³ dokumentumok keresÃ©se:<p>
+   <ul>
+       <li>Ãrjon be egy szokÃ¡sos keresÃ©si feltÃ©telt.
+       <li>Ãrja be a kezdÅ dÃ¡tumot a "KezdÅ (vagy âcsakâ) dÃ¡tum" cellÃ¡ba.
+       <li>Ãrja be a vÃ©gdÃ¡tumot a "VÃ©ge dÃ¡tum" cellÃ¡ba
+       <li>VÃ¡lassza a "K.Ã.E" opciÃ³t a lehÃºzhatÃ³ menÃŒbÅl bÃ¡rmely dÃ¡tumra a Krisztus Ãra ElÅttrÅl (ismertebben Krisztus ElÅtt).
+       <li>Kesdje el a keresest.
+   </ul>    
+</ul><p>
+}  
+
+_texthelpdateresultstitle_ [l=hu] {A keresÃ©s eredmÃ©nye}  
+_texthelpdateresults_ [l=hu] {ÃltalÃ¡ban vÃ©ve egy dokumentum keresÃ©se az 1903. Ã©vben nem fog megtalÃ¡lni olyan dokumentumokat amik 1903-ban Ã­rÃ³dtak, hanem amik 1903-rÃ³l âszÃ³lnakâ. Azonban, ahogy a dokumentumok dÃ¡tumaira keresÃŒnk, az idÅintervallumokra tÃ¶rtÃ©nÅ keresÃ©s esetÃ©n (p.l. 1899-1911), meg fogja talÃ¡lni azon dokumentumokat amelyek nevÃŒkben magukban foglaljÃ¡k a szÃ¡zad nevÃ©t, aminek 1903 a rÃ©sze (pl. 20.szÃ¡zad vagy huszadik szÃ¡zad). Ez azt jelenti, hogy namely dokumentumra, a keresÃ©sbeli dÃ¡tum nem fog megjelenni a dokumentum szÃ¶vegÃ©ben. Egy idÅintervallum keresÃ©s esetÃ©n, az elÅbbiek igazak az intervallum minden dÃ¡tumÃ¡ra..<p>}  
+
+_textchangeprefs_ [l=hu] {PreferenciÃ¡k megvÃ¡ltoztatÃ¡sa}  
+
+_texthelppreferences_ [l=hu] {<p> Amikor az oldal legtetejÃ©n a <i> _Global:linktextPREFERENCES_ </i>gombra klikkelÃŒnk a csatolÃ³egysÃ©g nÃ©hÃ¡ny beÃ¡llÃ­tÃ¡sa lehetsÃ©ges ami a sajÃ¡t preferenciÃ¡kat fejezi ki.}  
+
+_texthelpcollectionprefstitle_ [l=hu] {GyÅ±jtemÃ©ny preferenciÃ¡i}  
+_texthelpcollectionprefs_ [l=hu] {<p>NÃ©hÃ¡ny gyÅ±jtemÃ©ny tÃ¶bb algyÅ±jtemÃ©nybÅl Ã¡ll, amelyeken keresni lehet.  fÃŒggetlenÃŒl, vagy egyÃŒtt, mint egyetlen egysÃ©g.  Ha ez utÃ³bbi a helyzet, akkor vÃ¡lasztani lehet a PreferenciÃ¡k oldalon, hogy mely algyÃŒjtemÃ©nyekre folyjon a keresÃ©s.}  
+
+_texthelplanguageprefstitle_ [l=hu] {Nyelvi preferencia}  
+_texthelplanguageprefs_ [l=hu] {<p> Minde gyÅ±jtemÃ©nybek van egy alapÃ©rtelmezett elÅadÃ³i nyelve, de ezt Ã¡t lehet vÃ¡ltoztani mÃ¡s neylvre is. Azon kÃ³dolÃ¡st is meg lehet vÃ¡ltoztatni, amit Greenstone a bÃ¶ngÃ©szÅben hasznÃ¡l â a softver egy Ã©rtelmes alapÃ©rtrelmezÃ©st vÃ¡laszt, de nÃ©hÃ¡ny bÃ¶ngÃ©szÅvel szÃŒksÃ©gessÃ© vÃ¡lhat a vÃ¡ltoztatÃ¡s a karakterek helyes megjelenÃ­tÃ©se Ã©rdekÃ©ben. Minde gyÅ±jtemÃ©ny lehetÅvÃ© teszi a grafikus kÃ©pernyÅrÅl a szÃ¶veges kÃ©pernyÅre valÃ³ vÃ¡ltÃ¡st. Ez kÃŒlÃ¶nÃ¶sen akkor hasznos azon lÃ¡tÃ¡ssÃ©rÃŒlt felhasznÃ¡lÃ³knak akik nagy betÅ±beÃ¡llÃ­tÃ¡st vagy beszÃ©d szintetizÃ¡tort hasznÃ¡lnak.}  
+
+_texthelppresentationprefstitle_ [l=hu] {Eloadas preferenciaja}  
+_texthelppresentationprefs_ [l=hu] {NÃ©hÃ¡ny gyÅ±jtemÃ©nyben lehetÅsÃ©g van mÃ¡s opciÃ³k beÃ¡llÃ­tÃ¡sÃ¡ra is, amik az elÅadÃ¡s kontrolljÃ¡t teszik lehetÅvÃ©. <p> Web oldalak gyÅ±jtemÃ©nye esetÃ©n lehetÅsÃ©g van a Greenstone navigÃ¡ciÃ³s sÃ¡v elhagyÃ¡sÃ¡ra Ãºgy, hogy amikor vÃ©ge a keresÃ©snek nem egy Greenstone fejlÃ©ces oldal jelenik meg hanem a megtalÃ¡lt web oldal maga. Egy mÃ¡sik keresÃ©st lehet indÃ­tani a bÃ¶ngÃ©szÅ âvisszaâ gonbjÃ¡nak hasznÃ¡latÃ¡val. Ezek a gÅ±jtemÃ©nyek lehetÅvÃ© teszik a Greenstone figyelmeztetÅ ÃŒzeneteitÅl valÃ³ megszabadulÃ¡st, amikor egy linker klikkelÃŒnk ami a kivisz a digitalis kÃ¶nyvtÃ¡rbÃ³l Ã©s elvisz a Web-re magÃ¡ra. NÃ©hÃ¡ny web gyÅ±jtemÃ©ny esetÃ©n lehetÅsÃ©g van annak beÃ¡llÃ­tÃ¡sÃ¡ra, hogy a âkeresÃ©s eredmÃ©nyeâ egyenesen a megtalÃ¡lt fogja adni, vagy csak az oldal digitalis kÃ¶nyvtÃ¡rban lÃ©vÅ mÃ¡solatÃ¡t.}  
+
+_texthelpsearchprefstitle_ [l=hu] {KeresÃ©si preferenciÃ¡k}  
+_texthelpsearchprefs_ [l=hu] {<p>ÃtvÃ¡lthat âhaladÃ³â lekÃ©rdezÃ©sre, amely lehetÅvÃ© teszi hogy hasznÃ¡lhassa a & (az âÃ©sâ-re), | (a âvagyâ-ra), Ã©s ! (a ânemâ-re), illetve zÃ¡rÃ³jeleket csoportosÃ­tÃ¡sra, ha szÃŒksÃ©ges. Ez lehetÅvÃ© teszi pontosabb lekÃ©rdezÃ©seket.
+<p>_selectsearchtypeprefs_
+<p>_selectwordmodificationprefs_
+ <p>Be tudja kapcsolni a keresÃ©s elÅzmÃ©nyei funkciÃ³t, amely Ã­gy megmutatja az utolÃ³ nÃ©hÃ¡ny lekÃ©rdezÃ©sÃ©t.  Ez megkÃ¶nnyÃ­tti hogy csak kevÃ©sbÃ© eltÃ©rÅ lekÃ©rdezÃ©seket lehesen ismÃ©telni.
+<p>VÃ©gÃŒl beÃ¡llÃ­thatÃ³ a talÃ¡latok szÃ¡ma, Ã©s a szÃ¡m lÃ¡thatÃ³ minden kÃ©pernyÅn.}  
+
+_textcasefoldprefs_ [l=hu] {2 gombbal vezÃ©relhetÅ, hogy kis vagy nagybetÅ± kÃŒlÃ¶nbÃ¶zÅnek szÃ¡mÃ­t e a keresÃ©sben. PÃ©ldÃ¡ul, ha "_preferences:textignorecase_" ki van vÃ¡lasztva, <i>snail farming</i> ugyanolyan kifejezÃ©snek szÃ¡mÃ­t, mint <i>Snail Farming</i> vagy <i>SNAIL FARMING</i>.}  
+_textstemprefs_ [l=hu] {2 gombbal lehet irÃ¡nyÃ­tani, hogy szÃ³vÃ©gek figyelembe vannak e vÃ©ve. Pl. ha "_preferences:textstem_"  van kivÃ¡lasztva, <i>csiga gazdasÃ¡g</i> ugyanÃºgy lesz figyelembe vÃ©ve mint <i>csiga gazda</i> Ã©s <i>csiga gazdÃ¡k</i>. Ez jelenleg csak az angol nyelvÅ± szÃ¶vegekre mÅ±kÃ¶dik megfelelÅen _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=hu] {2 gombbal vezÃ©relhetÅ, hogy Ã©kezetes vagy Ã©kezet nÃ©lkÃŒli betÅ± kÃŒlÃ¶nbÃ¶zÅnek szÃ¡mit e a keresÃ©sben. PÃ©ldÃ¡ul, ha "_preferences:textignoreaccents_" ki van vÃ¡lsztva, <i>fÃ©dÃ©ration</i> ugyanolyan szÃ³nak szÃ¡mÃ­t, mint <i>fedÃ©ration</i> vagy <i>federation</i>.}  
+ 
+_textstemoptionsprefs_ [l=hu] {Lehet hogy kÃ©nyelmesebb Ã©s pontosabb ha a âkeresÃ©sek levÃ¡gÃ¡saâ funkciÃ³t hasznÃ¡lja ami a fenti "_texthelpquerytermstitle_"-ben van leÃ­rva.}  
+
+_textsearchtypeprefsplain_ [l=hu] {LehetsÃ©ges egy nagy lekÃ©rdezÃ©si cellÃ¡t kapni, Ãºgy hogy paragrafus mÃ©retÅ± keresÃ©s is lehetsÃ©ges. MeglepÅen gyorsan lehet keresni nagy tÃ¶megÅ± szÃ¶vegben}  
+
+_textsearchtypeprefsform_ [l=hu] {MegvÃ¡ltoztathatja a mezÅk szÃ¡mÃ¡t a lekÃ©rdezÃ©sben}  
+
+_textsearchtypeprefsboth_ [l=hu] {VÃ¡lthat a gyÅ±jtemÃ©ny keresÃ©si tÃ­pusÃ¡ban a "normÃ¡l" Ã©s a âmezÅâ keresÃ©s kÃ¶zÃ¶tt.
+<ul>
+<li>NormÃ¡l keresÃ©s egyetlen lekÃ©rdezÃ©si cellÃ¡t ad. _textsearchtypeprefsplain_</li>
+ <li>MezÅkeresÃ©s tÃ¶bb lekÃ©rdezÃ©si cellÃ¡t ad, mindegyik lekÃ©rdezi az index kÃŒlÃ¶nbÃ¶zÅ mezÅit. Ez lehetÅvÃ© tesz kÃŒlÃ¶nbÃ¶zÅ mezÅkÃ¶n egyszerre tÃ¶rtÃ©nÅ keresÃ©st. _textsearchtypeprefsform_ </li>
+</ul>
+}  
+
+
+
+_texttanumbrowseoptions_ [l=hu] {_numbrowseoptions_ szÃ¡mos mÃ³d van hogy informÃ¡ciÃ³t lehessen talÃ¡lni ebben a gyÅ±jtemÃ©nyben:}  
+
+_textsimplehelpheading_ [l=hu] {Hogyan lehet informÃ¡ciÃ³t talÃ¡lni a _collectionname_ gyÅ±jtemÃ©nyben}  
+
+_texthelpscopetitle_ [l=hu] {A lekÃ©rdezÃ©s Ã©rvÃ©nyessÃ©ge}  
+_texthelpscope_ [l=hu] {<p>
+A legtÃ¶bb gyÅ±jtemÃ©nyben a keresÃ©shez lehetÅsÃ©g van kÃŒlÃ¶nbÃ¶zÅ indexek vÃ¡lasztÃ¡sÃ¡ra. Pl. lehetnek szerzÅ vagy cÃ­m indexek. Vagy lehetnek fejezet vagy paragrafus indexek. ÃltalÃ¡ban a teljesen dokumentum jelenÃ­tÅdik meg fÃŒggetlenÃŒl attÃ³l, hogy mely indexet hasznÃ¡lta fel. <p> Ha a dokumentumok kÃ¶nyvek, akkor ki lesznek nyitva a megfelelÅ rÃ©sznÃ©l.}  
Index: /gsdl/stable/macros/hungarian2.dm
===================================================================
--- /gsdl/stable/macros/hungarian2.dm	(revision 20131)
+++ /gsdl/stable/macros/hungarian2.dm	(revision 20131)
@@ -0,0 +1,712 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Language text and icon macros 
+# -- this file contains text that is of less importance
+######################################################################
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_lastupdate_ [l=hu] {UtoljÃ¡ra frissÃ­tve}  
+
+
+
+### taken from here
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+# should have arguments of collection, collectionname and link
+
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# collectoraction
+package wizard
+
+
+
+
+
+
+
+
+
+
+_textstopbuild_ [l=hu] {Fejezd be a lÃ©trehozÃ¡st}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textfailmsg21_ [l=hu] {A gyÅ±jtemÃ©nyt nem lehetett lÃ©trehozni (import.pl problÃ©ma).}  
+
+
+
+
+
+
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+_textinfo_ [l=hu] {GyÅ±jtemÃ©ny informÃ¡ciÃ³}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textypits_ [l=hu] {A sorozatban elfoglalt helye egy nyÃ­llal van jelezve alul â ebben az esetben, ez a âgyÅ±jtemÃ©ny informÃ¡ciÃ³â szint. Hogy folytathassa, klikkeljen a zÃ¶ld âforrÃ¡s adatâ gombra}  
+
+_srcebadsources_ [l=hu] {<p>Egy vagy tÃ¶bb input forrÃ¡s amit megjelÃ¶lt nem Ã¡ll rendelkezÃ©sre (meg van jelÃ¶lve _iconcross_ alul).
+
+<p>Ez talÃ¡n azÃ©rt lehet, mert
+<ul>
+<li>A file, FTP site vagy URL nem lÃ©tezik.
+<li>SzÃŒksÃ©ges hogy elÅszÃ¶r az ISP-jÃ©t hÃ­vja fel.
+<li>Olyan URL-t prÃ³bÃ¡l elÃ©rni ami egy tÅ±zfal mÃ¶gÃ¶tt van (Ã¡ltalÃ¡ban ez a helyzet ha felhasznÃ¡lÃ³i nevet Ã©s jelszÃ³t kell megadni, hogy el lehessen Ã©rni az internetet).
+</ul>
+
+<p>Ha ez egy olyan URL amit lÃ¡tni lehet a bÃ¶ngÃ©szÅjÃ©ben, akkor lehet hogy ez egy helyileg tÃ¡rolt mÃ¡solatbol jÃ¶n. Sajnos, helyileg tÃ¡rolt mÃ¡solatok lÃ¡thatatlanok a tÃŒkrÃ¶zÃ©si folyamatainknak. Ebben az esetben az javasoljuk hogy elÅszÃ¶r tÃ¶ltse le az oldalakat a bÃ¶ngÃ©szÅjÃ©vel.
+}  
+
+
+
+
+
+_textad_ [l=hu] {Adat hozzÃ¡adÃ¡sa}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textbsupdate2_ [l=hu] {_wizard:textbsupdate2_}  
+
+
+
+
+
+
+
+_texttryagain_ [l=hu] {KÃ©rem <a href="_httppagecollector_" target=_top> indÃ­tsa Ãºjra a gyÅ±jtemÃ©nyt</a>
+Ã©s prÃ³bÃ¡lja Ãºjra.}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textmkcolfail_ [l=hu] {A gyÅ±jtemÃ©nynek nem sikerÃŒlt lÃ©trehozni a kÃ¶nyvtÃ¡r szerkezetet amit az Ãºj gyÅjtemÃ©ny megkÃ­vÃ¡n (mkcol.pl problÃ©ma). A lehetsÃ©ges okok:
+<ul>
+<li> A Greenstone-nak nincs Ã­rÃ¡si engedÃ©lye a _gsdlhome_/tmp kÃ¶nyvtÃ¡rhoz.
+<li> mkcol.pl perl script hiba.
+</ul>
+}  
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textbuildcancelled_ [l=hu] {_wizard:textbuildcancelled_}  
+
+
+
+
+
+
+
+
+
+
+_textfailmsg41_ [l=hu] {_wizard:textfailmsg41_}  
+
+
+
+
+
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+_textplatformtitle_ [l=hu] {platform}  
+
+
+
+
+
+
+
+
+
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+
+_textmailinglist_ [l=hu] {LÃ©tezik egy levelezÃ©si lista, mely elsÅdlegesen fÃ³rumkÃ©nt szolgÃ¡l a Greenstone digitÃ¡lis kÃ¶nyvtÃ¡r szoftverÃ©rÅl tÃ¶rtÃ©nÅ megbeszÃ©lÃ©shez. Greenstone aktÃ­v felhasznÃ¡lÃ³inak a listÃ¡n kellene lenniÃŒk Ã©s a megbeszÃ©lÃ©s tÃ©mÃ¡ihoz hozzÃ¡ kellene szÃ³lniuk. A belÃ©pÃ©shez menjen a <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>. }  
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+_textretype_ [l=hu] {GÃ©pelje be Ãºjra a jelszÃ³t}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=hu] {A felhasznÃ¡lÃ³i nÃ©v nem Ã©rvÃ©nyes.}  
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textcwoa_ [l=hu] {A gyÅ±jtemÃ©nyek csak akkor fognak megjelenni mint âfutÃ³kâ, ha a build.cfg-jÃŒk lÃ©tezik, olvashatÃ³, tartalmaz egy lÃ©trehozÃ¡si dÃ¡tumot (>0), Ã©s benne vannak a gyÅ±jtemÃ©ny index kÃ¶nyvtÃ¡rÃ¡ban (NEM a lÃ©trehozÃ¡si kÃ¶nyvtÃ¡rban!).}  
+
+
+
+_textsubc_ [l=hu] {KÃŒldje el a vÃ¡ltozÃ¡sokat}  
+
+
+
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textoptionally_ [l=hu] {OpcionÃ¡lis}  
+
+
+
+
+
+
+
+
+ 
+
+
+_textstrangebehaviour_ [l=hu] {Ne megfelelÅ viselkedÃ©s}  
+
+
+
+
+
+
+
+
+_texttrivial_ [l=hu] {NYILVÃNVALÃ}  
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+
+
+
+
+
+
+
+
+
+
+
+_textgtiglihelp_ [l=hu] {GLI segÃ­tsÃ©g}  
+
+
+_textgtigreenorg_ [l=hu] {Greenstone.org}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textgtifind_ [l=hu] {TALÃLD MEG}  
+
+
+
+
+
+
+
+
+
+
+############
+# gli page
+############
+package gli
+
+
+
Index: /gsdl/stable/macros/indo.dm
===================================================================
--- /gsdl/stable/macros/indo.dm	(revision 20131)
+++ /gsdl/stable/macros/indo.dm	(revision 20131)
@@ -0,0 +1,665 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Indonesian Language text and icon macros 
+# Many thanks to Paul Mundy (updated November 2004)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=id] {Terbitan berkala}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=id] {sumber:}
+_textdate_ [l=id] {tanggal terbitan:}
+_textnumpages_ [l=id] {jumlah halaman:}
+
+_textsignin_ [l=id] {login}
+
+_textdefaultcontent_ [l=id] {Halaman yang diminta tidak dapat ditemukan. Mohon gunakan tombol 'Back' (balik) di browser anda atau tombol Induk di atas untuk kembali ke Perpustakaan Digital Greenstone.}
+
+_textdefaulttitle_ [l=id] {Kesalahan GSDL }
+
+_textbadcollection_ [l=id] {Koleksi ini (namanya "_cvariable") belum diinstalasi pada sistem perpustakaan digital Greenstone ini.}
+
+_textselectpage_ [l=id] {-- Pilih Halaman --}
+
+_collectionextra_ [l=id] {Koleksi ini mengandung _about:numdocs_ dokumen. 
+Koleksi terbentuk _about:builddate_ hari yang lalu.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=id] {<p>Koleksi ini mengandung _numdocs_ _If_("_numdocs_" eq "1",dokumen,dokumen), dengan jumlah _numbytes_.
+<p><a href="_httppagex_(bsummary)">Klik di sini</a> untuk melihat ringkasan pembentukan koleksi ini.}
+
+_textdescrcollection_ [l=id] {}
+_textdescrabout_ [l=id] {Halaman Perihal}
+_textdescrhome_ [l=id] {Halaman Induk}
+_textdescrhelp_ [l=id] {Halaman Bantuan}
+_textdescrpref_ [l=id] {Halaman Preferensi}
+_textdescrgreenstone_ [l=id] {Perangkat Lunak Perpustakaan Digital Greenstone}
+_textdescrusab_ [l=id] {Apa yang menurut anda sulit digunakan?}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=id] {Pencarian}  
+_labelSearch_ [l=id] {Mencari}
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_labelTitle_ [l=id] {Judul A-Z}
+
+_labelCreator_ [l=id] {Pengarang A-Z}
+
+_labelSubject_ [l=id] {Subyek}
+
+_labelDescription_ [l=id] {Deskripsi}
+
+_labelPublisher_ [l=id] {Penerbit}
+_textContributor_ [l=id] {Kontributor}  
+_labelContributor_ [l=id] {Penyumbang}
+
+_labelDate_ [l=id] {Tanggal}
+
+_labelType_ [l=id] {Tipe}
+
+_labelFormat_ [l=id] {Format}
+
+_labelIdentifier_ [l=id] {Pengenal}
+_textSource_ [l=id] {Nama File}  
+_labelSource_ [l=id] {Nama file}
+
+_labelLanguage_ [l=id] {Bahasa}
+_textRelation_ [l=id] {Hubungan}  
+_labelRelation_ [l=id] {Hubungan}
+
+_labelCoverage_ [l=id] {Pencakupan}
+
+_labelRights_ [l=id] {Hak-hak}
+
+# DLS metadata set
+_textOrganization_ [l=id] {Organisasi}  
+
+
+_labelKeyword_ [l=id] {Kata kunci}
+
+
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=id] {Frase}  
+_labelPhrase_ [l=id] {Ungkapan}
+
+_labelCollage_ [l=id] {Susunan gambar}
+
+
+
+_labelTo_ [l=id] {Kepada}
+_textFrom_ [l=id] {Dari
+}  
+_labelFrom_ [l=id] {Dari}
+
+_labelAcronym_ [l=id] {Singkatan}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+
+
+_textdescrSearch_ [l=id] {Mencari istilah tertentu}
+_textdescrType_ [l=id] {Browse tipe sumberdaya}
+_textdescrIdentifier_ [l=id] {Browse pengenal sumberdaya}
+_textdescrSource_ [l=id] {Browse name file asli}
+_textdescrTo_ [l=id] {Melihat menurut bidang Kepada}
+_textdescrFrom_ [l=id] {Melihat menurut bidang Dari}
+_textdescrCollage_ [l=id] {Browse susunan gambar}
+_textdescrAcronym_ [l=id] {Melihat singkatan lembaga}
+_textdescrPhrase_ [l=id] {Melihat ungkapan}
+_textdescrHowto_ [l=id] {Melihat kategori Bagaimana}
+_textdescrBrowse_ [l=id] {Browse}
+_texticontext_ [l=id] {Menampilkan dokumen}
+_texticonclosedbook_ [l=id] {Membuka dokumen ini dan melihat isinya}
+_texticonnext_ [l=id] {ke bagian berikut}
+_texticonprev_ [l=id] {ke bagian sebelumnya}
+
+_texticonworld_ [l=id] {Lihat dokumen internet}  
+
+_texticonmidi_ [l=id] {Melihat dokumen MIDI}
+_texticonmsword_ [l=id] {Melihat dokumen Microsoft Word}
+_texticonmp3_ [l=id] {Melihat dokumen MP3}
+_texticonpdf_ [l=id] {Melihat dokumen PDF}  
+_texticonps_ [l=id] {Melihat dokumen PostScript}  
+_texticonppt_ [l=id] {Melihat dokumen PowerPoint}  
+_texticonrtf_ [l=id] {Melihat dokumen RTF}  
+_texticonxls_ [l=id] {Melihat dokumen Microsoft Excel}  
+
+_page_ [l=id] {halaman }
+_pages_ [l=id] {halaman}
+_of_ [l=id] {dari }
+_vol_ [l=id] {Vol.}
+_num_ [l=id] {Nomor}
+
+_textmonth00_ [l=id] {}
+_textmonth01_ [l=id] {Januari}
+_textmonth02_ [l=id] {Pebruari}
+_textmonth03_ [l=id] {Maret}
+_textmonth04_ [l=id] {April}
+_textmonth05_ [l=id] {Mei}
+_textmonth06_ [l=id] {Juni}
+_textmonth07_ [l=id] {Juli}
+_textmonth08_ [l=id] {Agustus}
+_textmonth09_ [l=id] {September}
+_textmonth10_ [l=id] {Oktober}
+_textmonth11_ [l=id] {Nopember}
+_textmonth12_ [l=id] {Desember}
+
+_textdocument_ [l=id] {Dokumen}
+_textsection_ [l=id] {Bagian}
+_textparagraph_ [l=id] {Alinea}
+
+_magazines_ [l=id] {Majalah}
+
+_nzdlpagefooter_ [l=id] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}
+
+_linktextHOME_ [l=id] {INDUK}
+_linktextHELP_ [l=id] {BANTUAN}
+_linktextPREFERENCES_ [l=id] {PREFERENSI}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+
+package collector
+
+_textcollector_ [l=id] {Kolektor}  
+
+package depositor
+
+
+package gti
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=id] {Mengenai koleksi ini}
+
+_textsubcols1_ [l=id] {<p>Koleksi lengkap mengandung _1_ subkoleksi. 
+Koleksi yang sedang tersedia adalah:
+<blockquote>}
+
+_textsubcols2_ [l=id] {</blockquote>
+Anda dapat mengecek (dan mengubah) subkoleksi yang sedang digunakan 
+pada halaman Preferensi.}
+
+_titleabout_ [l=id] {about}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=id] {tutup bagian perpustakaan ini}
+_texticonclosedbookshelf_ [l=id] {buka bagian perpustakaan ini dan melihat isinya}
+_texticonopenbook_ [l=id] {tutup buku ini}
+_texticonclosedfolder_ [l=id] {Buka map ini dan melihat isinya}
+_texticonclosedfolder2_ [l=id] {buka sub-bagian: }
+_texticonopenfolder_ [l=id] {tutup map ini}
+_texticonopenfolder2_ [l=id] {tutup sub-bagian: }
+_texticonsmalltext_ [l=id] {Melihat bagian ini dari teks}
+_texticonsmalltext2_ [l=id] {melihat teks: }
+_texticonpointer_ [l=id] {bagian terpilih}
+_texticondetach_ [l=id] {Bukan halaman ini pada jendela baru}
+_texticonhighlight_ [l=id] {Menyoroti istilah yang dicari}
+_texticonnohighlight_ [l=id] {Jangan menyoroti istilah yang dicari}
+_texticoncontracttoc_ [l=id] {Tutup daftar isi}
+_texticonexpandtoc_ [l=id] {Buka daftar isi}
+_texticonexpandtext_ [l=id] {Tampilkan semua teks}
+_texticoncontracttext_ [l=id] {Tampilkan teks hanya di bagian yang terpilih}
+_texticonwarning_ [l=id] {<b>Perhatian: </b>}
+_texticoncont_ [l=id] {teruskan?}
+
+_textltwarning_ [l=id] {<div class="buttons">_imagecont_</div>
+_iconwarning_Membuka teks di sini akan menghasilkan sejumlah data besar untuk ditampilkan oleh browser anda
+}
+
+_textgoto_ [l=id] {ke halaman}
+_textintro_ [l=id] {<i>(teks pengantar)</i>}
+
+_textCONTINUE_ [l=id] {TERUSKAN??}
+
+_textEXPANDTEXT_ [l=id] {BUKA TEKS}
+
+_textCONTRACTCONTENTS_ [l=id] {TUTUP ISI}
+
+_textDETACH_ [l=id] {PISAHKAN}
+
+_textEXPANDCONTENTS_ [l=id] {BUKA ISI}
+
+_textCONTRACT_ [l=id] {TUTUP TEKS}
+
+_textHIGHLIGHT_ [l=id] {PENYOROTAN}
+
+_textNOHIGHLIGHT_ [l=id] {TANPA\nPENYOROTAN}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=id] {_If_(_thislast_,hasil _thisfirst_ - _thislast_ untuk pertanyaan: _cgiargq_,Tidak ada yang memenuhi syarat: _cgiargq_)}
+_textnoquerytitle_ [l=id] {Halaman Pencarian}
+
+_textsome_ [l=id] {beberapa}
+_textall_ [l=id] {semua}
+_textboolean_ [l=id] {logika}
+_textranked_ [l=id] {terurut}
+_textnatural_ [l=id] {alami}
+
+_texticonsearchhistorybar_ [l=id] {riwayat pencarian}
+
+_textifeellucky_ [l=id] {Saya lagi beruntung!}
+
+#alt text for query buttons
+_textusequery_ [l=id] {gunakan pertanyaan ini}
+_textfreqmsg1_ [l=id] {Jumlah kata: }
+_textpostprocess_ [l=id] {_If_(_quotedquery_,<br><i>diproses ulang untuk menemukan _quotedquery_</i>
+)}
+_textinvalidquery_ [l=id] {Susunan <i>query</i> (permintaan informasi) tidak laku}
+
+
+
+_textmorethan_ [l=id] {Lebih dari }
+_textapprox_ [l=id] {Sekitar }
+_textnodocs_ [l=id] {Tidak ada dokumen yang memenuhi syarat.}
+_text1doc_ [l=id] {1 dokumen memenuhi syarat.}
+_textlotsdocs_ [l=id] {dokumen memenuhi syarat.}
+_textmatches_ [l=id] {Penemuan }
+_textbeginsearch_ [l=id] {Mulai mencari}
+_textrunquery_ [l=id] {Menjalankan pertanyaan}  
+_textclearform_ [l=id] {Menghapuskan formulir}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=id] {Kata atau ungkapan}  
+_textinfield_ [l=id] {... dalam bidang}  
+_textfoldstem_ [l=id] {(lipatan, kata dasar)}  
+
+_textadvquery_ [l=id] {Atau masukkan pertanyaan secara langsung:}  
+_textallfields_ [l=id] {semua bidang}  
+_texttextonly_ [l=id] {hanya teks
+}
+_textand_ [l=id] {dan}  
+_textor_ [l=id] {atau}  
+_textandnot_ [l=id] {dan tidak}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=id] {Mencari _indexselection_ _If_(_jselection_, dari _jselection_) _If_(_gselection_, pada tingkat _gselection_) _If_(_nselection_, dalam bahasa _nselection_) yang mengandung _querytypeselection_ dari kata}  
+
+_textadvancedsearch_ [l=id] {Mencari _indexselection_ _If_(_jselection_, dari _jselection_) _If_(_gselection_, pada tigkat _gselection_)_If_(_nselection_, dalam bahasa _nselection_) dengan menggunakan pertanyaan _querytypeselection_}
+
+
+
+
+
+_textformsimplesearch_ [l=id] {Mencari _If_(_jselection_, _jselection_) _If_(_gformselection_, pada tingkat _gformselection_) _If_(_nselection_, dalam bahasa _nselection_)
+yang mengandung _formquerytypesimpleselection_ dari}
+
+_textformadvancedsearchmgpp_ [l=id] {Pencarian () dan tampilkan hasil di}  
+
+_textformadvancedsearchlucene_ [l=id] {pencarian( )untuk}  
+
+_textnojsformwarning_ [l=id] {Perhatian: Javascript dilumpuhkan di browser anda. <br>Untuk menggunakan pencarian dengan formulir, mohon diizinkan.}
+_textdatesearch_ [l=id] {Koleksi ini dapat diselidiki untuk dokumen yang mengandung tahun atau kisaran tahun tertentu. Kemungkinan ini merupakan pilihan tambahan.}
+_textstartdate_ [l=id] {Tahun mulai (atau tunggal):}
+_textenddate_ [l=id] {Tahun akhir:}
+_textbc_ [l=id] {SM}
+_textad_ [l=id] {TM}
+_textexplaineras_ [l=id] {C.E. (Common Era) = TM = Tarich (sesudah) Masehi. B.C.E. (Before Common Era) = SM = sebelum Masehi. }  
+
+_textstemon_ [l=id] {(mengabaikan akhiran kata)}
+
+_textsearchhistory_ [l=id] {Riwayat pencarian}
+
+#text macros for search history
+_textnohistory_ [l=id] {Riwayat pencarian tidak tersedia}  
+_texthresult_ [l=id] {hasil}
+_texthresults_ [l=id] {hasil}
+_texthallwords_ [l=id] {semua kata}
+_texthsomewords_ [l=id] {beberapa kata}
+_texthboolean_ [l=id] {pencarian logika}
+_texthranked_ [l=id] {terurut}
+_texthcaseon_ [l=id] {Huruf besar/kecil harus sama}
+_texthcaseoff_ [l=id] {Abaikan huruf besar/kecil}
+_texthstemon_ [l=id] {Abaikan awalan dan akhiran}
+_texthstemoff_ [l=id] {Dengan awalan dan akhiran}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=id] {Preferensi ditetapkan seperti berikut. Jangan menggunakan tombol "back" di browser anda - preferensi tersebut akan terhapus! Daripada itu, klik di salah satu tombol di atas.}
+_textsetprefs_ [l=id] {tetapkan preferensi}
+_textsearchprefs_ [l=id] {Preferensi pencarian}
+_textcollectionprefs_ [l=id] {Preferensi koleksi}
+_textpresentationprefs_ [l=id] {Preferensi penampilan}
+_textpreferences_ [l=id] {Preferensi}
+_textcasediffs_ [l=id] {Pembedaan huruf besar/kecil:}
+_textignorecase_ [l=id] {abaikan perbedaan}
+_textmatchcase_ [l=id] {huruf besar/kecil harus tepat sama}
+_textwordends_ [l=id] {Akhiran kata:}  
+_textstem_ [l=id] {abaikan akhiran}
+_textnostem_ [l=id] {kata harus tepat sama}
+
+
+
+
+_textprefop_ [l=id] {Sediakan sampai dengan _maxdocoption_ penemuan dengan _hitsperpageoption_ penemuan per halaman.}
+_textextlink_ [l=id] {Akses ke halaman web di luar:}
+_textintlink_ [l=id] {Dokumen asli diperoleh dari:}
+_textlanguage_ [l=id] {Bahasa tampilan:}
+_textencoding_ [l=id] {Pengekodean:}
+_textformat_ [l=id] {Format tampilan:}
+_textall_ [l=id] {semua}
+_textquerymode_ [l=id] {Cara pertanyaan:}  
+_textsimplemode_ [l=id] {sederhana}
+_textadvancedmode_ [l=id] {cara pertanyaan lanjutan (memungkinkan pencarian yang menggunakan !, &, |, dan tanda kurung) }
+_textlinkinterm_ [l=id] {melalui halaman pengantara}
+_textlinkdirect_ [l=id] {langsung tersedia}
+_textdigitlib_ [l=id] {perpustakaan digital}
+_textweb_ [l=id] {web}
+_textgraphical_ [l=id] {grafis}
+_texttextual_ [l=id] {teks}
+_textcollectionoption_ [l=id] {<p>
+Sub-koleksi yang tercantum:
+<br>}
+
+
+_textformsearchtype_ [l=id] {Isi dengan}  
+
+
+
+
+_textrelateddocdisplay_ [l=id] {tampilkan dokumen terkait}
+_textsearchhistory_ [l=id] {Riwayat pencarian:}  
+_textnohistory_ [l=id] {Tidak ada pencarian sebelumnya}  
+_texthistorydisplay_ [l=id] {tampilkan _historynumrecords_ butir riwayat pencarian}
+_textnohistorydisplay_ [l=id] {jangan tampilkan riwayat pencarian}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=id] {Susunkan dokumen menurut}
+_textalsoshowing_ [l=id] {juga menunjukkan}
+_textwith_ [l=id] {dengan paling banyak}
+_textdocsperpage_ [l=id] {dokumen per halaman}
+
+_textfilterby_ [l=id] {Melihat hanya dokumen yang mengandung}
+_textall_ [l=id] {semua}
+_textany_ [l=id] {apa saja}
+_textwords_ [l=id] {dari kata}
+_textleaveblank_ [l=id] {biarkan kotak ini kosong untuk memperoleh semua dokumen }  
+
+_browsebuttontext_ [l=id] {Melihat}
+
+_nodata_ [l=id] {<i>tidak ada data</i>}
+_docs_ [l=id] {dokumen}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=id] {Bantuan}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+
+
+
+
+
+
+
+
+
+_texthelptopicstitle_ [l=id] {Topik}
+
+_textreadingdocs_ [l=id] {Bagaimana membaca dokumen}
+
+_texthelpreadingdocs_ [l=id] {<p>Anda dapat mengetahui bahwa anda telah tiba di dokumen tertentu karena judul dan pengarangnya terlihat pada atas kiri halaman. Di sebelahnya ada nomor halaman yang ditampilkan, kotak yang memungkinkan anda untuk memilih halaman baru, dan panah maju dan mundur.
+
+<p>Di bawahnya ada teks dari bagian yang terpilih. Bila anda sudah selesai membaca teks itu, panah di bawah dapat digunakan untuk maju ke bagian berikut atau mundur ke yang sebelumnya. 
+
+<p>Di bawah judul dan pengarang terdapat tiga tombol. Klik pada <i>buka teks</i> untuk membuka semua teks dari dokumen terpilih. Bila dokumen besar, mungkin perlu menunggu lama dan banyak memori terpakai! Klik pada tombol <i>pisahkan</i> untuk membuka jendela baru untuk dokumen ini. (Hal ini dapat berguna bila anda ingin memperbandingkan dokumen, atau membaca dua dokumen sekaligus.)  Akhirnya, bila anda mencari kata tertentu, kata tersebut disoroti.  Klik pada tombol <i>tanpa penyorotan</i> untuk menghilangkan penyorotan.
+}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=id] {Buka Katalog buku ini}  
+
+_texthelpviewtextsection_ [l=id] {Lihat teks pada bagian ini}  
+_texthelpexpandtext_ [l=id] {Tampilkan semua teks, atau tidak}
+
+_texthelpdetachpage_ [l=id] {Buka halaman ini dalam jendela baru}
+_texthelphighlight_ [l=id] {Menyoroti istilah yang dicari, atau tidak}
+
+
+
+_texthelpsearchingtitle_ [l=id] {Bagaimana mencari istilah tertentu}
+
+_texthelpsearching_ [l=id] {<p>
+  Dari halaman Pencarian, anda dapat mengajukan pertanyaan dengan langkah berikut:<p>
+  
+  <ol><li>Memilih bahan yang ingin diselidiki 
+      <li>Menentukan apakah anda ingin mencari semua atau hanya beberapa dari istilah 
+      <li>Mengetik istilah yang dicari 
+      <li>Klik pada tombol <i>Mulai mencari</i> 
+  </ol>
+
+<p>Bila pertanyaan diajukan, judul dari 20 dokumen yang sesuai akan ditampilkan. Tombol di ujung daftar tersebut dapat ditekan untuk menampilkan 20 dokumen berikutnya, kemudian 20 dokumen lagi, dst. Untuk melihat isi dokumen, klik pada judul dokumen itu, atau pada lambang di sisiknya. 
+
+<p>Maksimal 100 dokumen dapat ditemukan. Jumlah ini dapat diganti dengan mengeklik pada tombol <i>preferensi</i> di atas halaman.<p>
+}
+
+_texthelpquerytermstitle_ [l=id] {Istilah pencarian}
+_texthelpqueryterms_ [l=id] {<p>Apa saja yang diketik dalam kotak pertanyaan dianggap sebagai daftar kata atau "istilah pencarian". Suatu istilah dapat mengandung hanya huruf A-Z dan angka 0-9. Istilah dipisahkan dengan spasi. Semua tanda lain (seperti tanda baca) dianggap sebagai spasi dan diabaikan. Kata yang mengandung tanda baca tidak dapat dicari.
+
+<p>Misalnya, pertanyaan<p>
+    <ul><kbd>Lada di Bangka-Belitung: Peluang untuk Agribisnis (1993)</kbd></ul>
+      <p>dianggap sebagai<p>
+      <ul><kbd> Lada di Bangka Belitung Peluang untuk Agribisnis 1993</kbd></ul><p>
+}
+
+
+
+
+
+_texthelpquerytypetitle_ [l=id] {Macam pertanyaan}
+_texthelpquerytype_ [l=id] {<p>Ada dua macam pertanyaan.
+
+<ul>
+  <li>Mencari <b>semua</b> kata. Pertanyaan ini mencari dokumen (atau bab atau 
+      judul) yang mengandung semua kata yang diketik dalam kotak pertanyaan.
+      Dokumen yang mengisi syarat itu ditampilkan dalan urutan abjad.<p>
+
+  <li>Mencari <b>beberapa</b> dari kata. Ketikkan saja daftar istilah yang
+      barangkali dimuat dalam dokumen yang dicari. Dokumen ditampilkan menurut
+      kesesuaiannya pada pertanyaan itu. Dalam menentukan dekatnya kesesuaian,
+
+      <p><ul>
+        <li> makin banyak istilah yang dikandung dokumen, makin dekat kesesuaiannya;
+        <li> istilah yang jarang dianggap lebih penting daripada istilah biasa;
+        <li> dokumen pendek dianggap lebih dekat kesesuaiannya daripada dokumen panjang.
+      </ul>
+</ul>
+
+<p>Anda dapat menggunakan sehendaknya banyak istilah pencarian--suatu kalimat penuh, atau bahkan alinea lengkap. Bila hanya satu istilah yang diketik, dokumen diurutkan menurut keseringan munculnya istilah itu.<p>
+}
+
+
+
+
+
+
+
+
+
+
+
+_texthelpadvancedsearchextra_ [l=id] {CATATAN: operator akan mengabaikan jika anda melakukan pencarian dengan modul simple query }  
+
+
+
+
+
+
+
+
+
+_textdatesearch_ [l=id] {Mencari menurut tanggal}  
+
+_texthelpdatesearch_ [l=id] {Pencarian menurut tanggal memungkinkan pencarian dokumen yang sesuai dengan istilah yang dipilih dan juga mengenai peristiwa dalam kurung waktu tertentu. Dokumen dapat dicari dari tahun tertentu atau dari kisaran tahun. Istilah pencarian tidak perlu: dokumen juga dapat dicari menurut tanggal saja. Tidak perlu menggunakan tanggal dalam pencarian: bila tanggal tidak diketik, maka tanggal diabaikan.<p>
+}
+
+_texthelpdatehowtotitle_ [l=id] {Bagaimana menggunakan fasilitas ini:}
+_texthelpdatehowto_ [l=id] {<ul>
+   <li>Untuk mencari dokumen mengenai tahun tertentu:<p>
+   <ul>
+       <li>Masukkan istilah pencarian seperti biasa. 
+       <li>Ketikkan tahun yang dimaksud pada kotak "Tahun mulai (atau tunggal)". 
+       <li>Bila tahun yang dimaksud sebelum Masehi, pilihlah SM dari menu di sebelah. 
+       <li>Mulailah pencarian seperti biasa.
+   </ul>
+<p><li>Untuk mencari dokumen mengenai kisaran tahun:<p>
+   <ul>
+       <li>Masukkan istilah pencarian seperti biasa.
+       <li>Ketikkan tahun pertama pada kotak "Tahun mulai (atau tunggal)". 
+       <li>Ketikkan tahun terakhir pada kotak "Tahun akhir".
+       <li> Bila tahun yang dimaksud sebelum Masehi, pilihlah SM dari menu di sebelah. 
+       <li> Mulailah pencarian seperti biasa.
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=id] {Cara kerja pencarian}
+_texthelpdateresults_ [l=id] {Pada umumnya, pencarian dokumen mengenai tahun 1903 tidak akan menemukan dokumen yang mengutip buku yang tertulis pada tahun 1903, hanya dokumen mengenai 1903. Akan tetapi, dokumen ditemukan yang mengandung kisaran tahun (seperti 1899-1911) yang mencakupi 1903. Juga ditemukan dokumen yang menyebut abad itu (misalnya abad ke-20 atau abad keduapuluh). Hal ini berarti bahwa tahun yang dicari tidak muncul di teks. Cara kerja ini juga berlaku untuk setiap tahun dalam pencarian kisaran.<p>
+}
+
+_textchangeprefs_ [l=id] {Mengubah preferensi}
+
+_texthelppreferences_ [l=id] {<p>Dengan mengeklik pada tombol <i>preferensi</i> di atas halaman, anda dapat mengubah beberapa fasilitas dari penampilan supaya cocok dengan kebutuhan anda.
+}
+
+_texthelpcollectionprefstitle_ [l=id] {Preferensi koleksi}
+_texthelpcollectionprefs_ [l=id] {Koleksi dapat terdiri dari beberapa sub-koleksi, yang dapat dicari secara tersendiri atau bersamaan. Pada koleksi macam itu, anda dapat memilih sub-koleksi yang mana untuk diselidiki pada halaman Preferensi.
+}
+
+_texthelplanguageprefstitle_ [l=id] {Preferensi bahasa}
+_texthelplanguageprefs_ [l=id] {Setiap koleksi ada bahasa penampilan yang standar, tetapi bahasa lain juga dapat dipilih. Anda juga dapat mengubah cara pengekodeaan yang digunakan oleh Greenstone untuk penyampaian hasil ke browser. Perangkat lunak memilih cara pengekodeaan secara otomatis, tetapi penampilan masih dapat diperbaiki di beberapa browser dengan memilih cara pengekodean yang lain. Semua koleksi memungkinkan pengantian penampilan grafis yang standar menjadi penampilan teks saja. Hal ini berguna untuk pengguna yang cacat mata yang memerlukan gaya huruf besar atau alat bicara untuk memperoleh keluaran.
+}
+
+_texthelppresentationprefstitle_ [l=id] {Preferensi presentasi}
+_texthelppresentationprefs_ [l=id] {Dalam koleksi tertentu, beberapa pilihan dapat disetel yang mengendalikan presentasi. 
+
+<p>Di koleksi halaman web, mungkin menghilangkan menu navigasi Greenstone di atas setiap halaman, sehingga setelah menemukan halaman yang dicari, tidak ada kop Greenstone di atasnya. Untuk mencari lagi, harus menggunakan tombol "Back" (balik) di browser. Pada koleksi seperti itu juga mungkin menghilangkan pesan peringatan dari Greenstone yang ditampilkan bila anda klik pada link yang keluar dari koleksi dan masuk ke internet. Pada beberapa koleksi, mungkin mengendalikan apakah link di halaman "Hasil pencarian" meneruskan anda ke URL di internet, atau ke jiplakan halaman itu yang ada di koleksi. 
+}
+
+_texthelpsearchprefstitle_ [l=id] {Preferensi pencarian}
+_texthelpsearchprefs_ [l=id] {<p>Dua pasangan tombol mengendalikan macam penyesuaian teks yang dilakukan dalam pencarian. Pasangan pertama ("Pembedaan huruf besar/kecil") mengatur apakah huruf besar dan kecil harus persis sama dengan apa yang diketik. Pasangan kedua ("Akhiran kata") mengatur apakah akhiran kata diabaikan atau tidak. Mungkin menampilkan kotak pertanyaan besar untuk mencari kalimat atau alinea. Pencarian alinea cukup cepat. 
+
+<p>Misalnya, bila tombol <i>abaikan perbedaan</i> dan 
+<i>abaikan akhiran</i> dipilih, pertanyaan<p>
+    <ul><kbd>African building</kbd></ul>
+      <p>akan dianggap sama dengan<p>
+      <ul><kbd>africa builds</kbd></ul><p>karena huruf besar di "African" akan
+      dijadikan huruf kecil, dan akhiran "n" dan "ing" dihapus dari "African"
+      dan "building" ("s" juga dihapus dari "builds").
+
+<p>Anda dapat pindah ke cara pencarian "lanjutan" yang memungkinkan penggunaan AND (&) [dan], OR (|) [atau], dan NOT (!) [tidak]. Hal ini memungkinkan pertanyaan lebih spesifik. Anda juga dapat menggunakan fasilitas riwayat pencarian, yang menampilkan beberapa pertanyaan yang terakhir ditampilkan. Fasilitas ini memungkinkan pengulangan dari pertanyaan dulu dengan nada sedikit berbeda. Anda juga dapat mengendalikan jumlah dokumen yang ditemukan, serta jumlah yang ditampilkan pada setiap layar. 
+}
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+_texttanumbrowseoptions_ [l=id] {Ada _numbrowseoptions_ cara untuk menemukan informasi dalam koleksi ini:}
+
+_textsimplehelpheading_ [l=id] {Bagaimana mencari informasi}
+
+_texthelpscopetitle_ [l=id] {Jangkauan pertanyaan}
+_texthelpscope_ [l=id] {<p>
+Dalam sebagian besar dari koleksi, anda dapat memilih di antara beberapa indeks. Misalnya, mungkin ada indeks pengarang atau judul. Atau indeks bab atau alinea. Pada umumnya, dokumen penuh ditampilkan, tanpa memperhatikan indeks yang digunakan.
+<p>Bila dokumen adalah buku, buku tsb dibuka pada tempat yang layak.
+}
Index: /gsdl/stable/macros/indo2.dm
===================================================================
--- /gsdl/stable/macros/indo2.dm	(revision 20131)
+++ /gsdl/stable/macros/indo2.dm	(revision 20131)
@@ -0,0 +1,725 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# English Language text and icon macros 
+# -- this file contains text that is of less importance
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_lastupdate_ [l=id] {Pembaharuan terakhir}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#------------------------------------------------------------
+# icons
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+# should have arguments of collection, collectionname and link
+
+
+
+#------------------------------------------------------------
+# icons
+#------------------------------------------------------------
+
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+_textinfo_ [l=id] {Informasi koleksi}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textypits_ [l=id] {Posisi anda dalam uraian ditunjukkan oleh panah di bawah--dalam hal ini, tahap "informasi koleksi".  Untuk melanjutkan, klik pada tombol "data sumber" (source data).}  
+
+
+
+
+
+
+
+_textad_ [l=id] {Menambah data:}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textbsupdate2_ [l=id] {Status pembangunan ("building") dalam}  
+
+
+
+
+
+
+
+
+
+
+_texttryagain_ [l=id] {Mohon <a href="_httppagecollector_" target=_top>memulai collector lagi</a>
+dan coba ulang.}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#------------------------------------------------------------
+# icons
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+
+_textmailinglist_ [l=id] {Terdapat suatu milis (kelompok email) terutama untuk diskusi mengenai perangkat lunak perpustakaan digital Greenstone.  Pengguna Greenstone aktif dipersilahkan bergabung dengan milis ini dan ikut serta dalam diskusi.
+Untuk bergabung, kunjungilah <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+
+Untuk mengirim pesan ke milis, gunakan alamat <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>.}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+_textretype_ [l=id] {masukkan ulang password baru}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=id] {Nama pengguna salah.}  
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textcwoa_ [l=id] {Koleksi hanya tampak "sedang jalan" bila file "build.cfg" tersedia, dapat dibaca, mengandung medan "builddate" (tanggal pembentukan) yang sah (yaitu > 0),
+dan terdapat dalam direktori indeks dari koleksi (bukan di direktori "building").
+}  
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+############################################################################
+#
+# This stuff is only used by the usability (I'd like to Complain) stuff
+#
+############################################################################
+package Global
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textoptionally_ [l=id] {Sebagai alternatif}  
+
+
+
+
+
+
+
+
+ 
+
+
+_textstrangebehaviour_ [l=id] {Tindak laku aneh}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textgtiglihelp_ [l=id] {Bantuan GLI}  
+
+_textgtigreenorg_ [l=id] {Greenstone.org}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+############
+# gli page
+############
+package gli
+
+
+
+
Index: /gsdl/stable/macros/italian.dm
===================================================================
--- /gsdl/stable/macros/italian.dm	(revision 20131)
+++ /gsdl/stable/macros/italian.dm	(revision 20131)
@@ -0,0 +1,859 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Italian Language text and icon macros 
+# Many thanks to Marco Michelino (translated August 2001)
+#            and Massimo Pesenti (updated March 2004) 
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=it] {Periodici}
+_textsource_ [l=it] {Rif. fonte}
+_textdate_ [l=it] {data di pubblicazione:}
+_textnumpages_ [l=it] {n. di pagine}
+
+_textsignin_ [l=it] {Entra}
+
+_textdefaultcontent_ [l=it] {La pagina richiesta non Ãš disponibile.
+Usa il pulsante 'indietro' del tuo browser o il pulsante
+'Pagina principale' per tornare alla Greenstone Digital Library.}
+
+_textdefaulttitle_ [l=it] {Errore GSDL}
+
+_textbadcollection_ [l=it] {Questa collezione (denominata "_cvariable_") non Ãš installata in questa Greenstone Digital Library.}
+
+_textselectpage_ [l=it] {-- Seleziona la pagina --}
+
+_collectionextra_ [l=it] {Questa raccolta contiene _about:numdocs_ documenti.
+E' stata creata _about:builddate_ giorni fa.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=it] {<p>Questa raccolta contiene _numdocs_ _If_("_numdocs_" eq "1",documento,documenti), per un totale di _numbytes_.
+<p><a href="_httppagex_(bsummary)">Clicca qui</a> per visualizzare il sommario di questa collezione.}
+
+_textdescrcollection_ [l=it] {}
+_textdescrabout_ [l=it] {Informazioni su}
+_textdescrhome_ [l=it] {Pagina principale}
+_textdescrhelp_ [l=it] {Aiuto}
+_textdescrpref_ [l=it] {Impostazioni}
+_textdescrgreenstone_ [l=it] {Greenstone Digital Library Software}
+_textdescrusab_ [l=it] {Cosa hai trovato difficile da usare?}
+
+_textdescrSearch_ [l=it] {Cerca termini specifici}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=it] {Elenco alfabetico per titolo}
+_textdescrCreator_ [l=it] {Elenco per autore}
+_textdescrSubject_ [l=it] {Elenco per soggetto}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=it] {Elenco per data}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+_textdescrSource_ [l=it] {Elenco per nome originale del file}
+_textdescrLanguage_ [l=it] {Elenco per lingua}
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=it] {Elenco per organizzazione}
+_textdescrKeyword_ [l=it] {Elenco per parola chiave}
+_textdescrHowto_ [l=it] {Elenco per categorie di guide pratiche}
+_textdescrList_ [l=it] {Elenco documenti}
+_textdescrSeries_ [l=it] {Elenco per argomento}
+_textdescrTo_ [l=it] {Elenco per destinatario}
+_textdescrFrom_ [l=it] {Elenco per mittente}
+_textdescrTopic_ [l=it] {Elenco argomenti particolari}
+_textdescrBrowse_ [l=it] {Elenco}
+_textdescrCollage_ [l=it] {Elenco per collage immagine}
+_textdescrPeople_ [l=it] {Elenco per persone}
+_textdescrAcronym_ [l=it] {Elenco acronimi}
+_textdescrPhrase_ [l=it] {Elenco frasi}
+_textdescrArtist_ [l=it] {Elenco artisti}
+_textdescrVolume_ [l=it] {Elenco per volume}
+_textdescrCountries_ [l=it] {Elenco per paese}
+_textdescrCaptions_ [l=it] {Elenco per didascalia della foto}
+
+
+_labelSearch_ [l=it] {Cerca}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=it] {Titoli A-Z}
+_labelCreator_ [l=it] {Autori A-Z}
+_labelSubject_ [l=it] {Soggetti}
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=it] {Date}
+# -- Missing translation: _labelType_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+_labelSource_ [l=it] {Nomi dei file}
+_labelLanguage_ [l=it] {Lingua}
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=it] {Organizzazione}
+_labelKeyword_ [l=it] {Parole chiave}
+_labelHow_ [l=it] {Guide pratiche}
+_labelSeries_ [l=it] {Serie}
+_labelList_ [l=it] {Lista}
+_labelTo_ [l=it] {Destinatario}
+_labelFrom_ [l=it] {Mittente}
+_labelTopic_ [l=it] {Argomento}
+_labelBrwse_ [l=it] {Elenco}
+_labelCollage_ [l=it] {Collage}
+_labelBrows_ [l=it] {Elenco}
+_labelPeople_ [l=it] {Persone A-Z}
+_labelAcronym_ [l=it] {Acronimi}
+_labelPhrase_ [l=it] {Frasi}
+_labelArtist_ [l=it] {Artisti}
+_labelVolume_ [l=it] {Volumi}
+_labelCaptions_ [l=it] {Didascalie}
+_labelCountries_ [l=it] {Paesi}
+
+_texticontext_ [l=it] {Visualizza il documento}
+_texticonclosedbook_ [l=it] {Apri questo documento e visualizza il contenuto}
+_texticonnext_ [l=it] {Prossima sezione}
+_texticonprev_ [l=it] {Sezione precedente}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=it] {Visualizza il documento MIDI}
+_texticonmsword_ [l=it] {Visualizza il documento Microsoft Word}
+_texticonmp3_ [l=it] {Visualizza il documento MP3}
+_texticonpdf_ [l=it] {Visualizza il documento PDF}
+_texticonps_ [l=it] {Visualizza il documento PS}
+_texticonppt_ [l=it] {Visualizza il documento PowerPoint}
+_texticonrtf_ [l=it] {Visualizza il documento RTF}
+_texticonxls_ [l=it] {Visualizza il documento Excel}
+
+_page_ [l=it] {pagina }
+_pages_ [l=it] {pagine}
+_of_ [l=it] {di }
+_vol_ [l=it] {Vol.}
+_num_ [l=it] {N.}
+
+_textmonth00_ [l=it] {}
+_textmonth01_ [l=it] {Gennaio}
+_textmonth02_ [l=it] {Febbraio}
+_textmonth03_ [l=it] {Marzo}
+_textmonth04_ [l=it] {Aprile}
+_textmonth05_ [l=it] {Maggio}
+_textmonth06_ [l=it] {Giugno}
+_textmonth07_ [l=it] {Luglio}
+_textmonth08_ [l=it] {Agosto}
+_textmonth09_ [l=it] {Settembre}
+_textmonth10_ [l=it] {Ottobre}
+_textmonth11_ [l=it] {Novembre}
+_textmonth12_ [l=it] {Dicembre}
+
+_textdocument_ [l=it] {Documento}
+_textsection_ [l=it] {Sezione}
+_textparagraph_ [l=it] {Paragrafo}
+
+_magazines_ [l=it] {Riviste}
+
+_nzdlpagefooter_ [l=it] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">Progetto New Zealand Digital Library</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Dipartimento di Informatica</a>,
+<a href="http://www.waikato.ac.nz">UniversitÃ  di Waikato</a>,
+Nuova Zelanda.}
+
+_linktextHOME_ [l=it] {PAGINA PRINCIPALE}
+_linktextHELP_ [l=it] {AIUTO}
+_linktextPREFERENCES_ [l=it] {IMPOSTAZIONI}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=it] {Greenstone Digital Library}
+_textadmin_ [l=it] {Pagina di amministrazione}
+_textabgs_ [l=it] {Informazioni su Greenstone}
+_textgsdocs_ [l=it] {Documentazione Greenstone}
+
+_textdescradmin_ [l=it] {Ti permette di aggiungere nuovi utenti, raggruppare le collezioni nel sistema, dare informazioni tecniche sulla installazione di Greenstone.}
+
+_textdescrgogreenstone_ [l=it] {Ti dÃ  informazioni a proposito del software Greenstone e del New Zealand Digital Library Project all'interno del quale Ãš stato creato}
+
+_textdescrgodocs_ [l=it] {Manuali di Greenstone}
+
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=it] {Interfaccia bibliotecario}
+_textdescrgli_ [l=it] {Ti aiuta a creare nuove collezioni, modificarle o aggiungerne alle esistenti, oppure cancellarle.}
+
+package collector
+
+_textcollector_ [l=it] {Il Collector}
+_textdescrcollector_ [l=it] {Questo precede l'interfaccia bibliotecario, e per la maggior parte degli scopi pratici dovrebbe essere usata preferibilmente}
+
+package depositor
+
+
+package gti
+
+_textdescrtranslator_ [l=it] {Ti aiuta a mantenere aggiornate le versioni multilingua dell'interfaccia Greenstone}
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=it] {Informazioni su questa raccolta}
+
+_textsubcols1_ [l=it] {<p>La raccolta completa comprende _1_ sottoraccolte.
+Quelle attualmente disponibili sono:
+<blockquote>}
+
+_textsubcols2_ [l=it] {</blockquote>
+Puoi controllare (e modificare) le sottoraccolte che stai
+correntemente utilizzando nella pagina Impostazioni.}
+
+
+_titleabout_ [l=it] {informazioni su}
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+
+_texticonopenbookshelf_ [l=it] {Chiudi questa sezione della biblioteca}
+_texticonclosedbookshelf_ [l=it] {apri questa sezione della biblioteca e mostra il contenuto}
+_texticonopenbook_ [l=it] {Chiudi questo libro}
+_texticonclosedfolder_ [l=it] {Apri questa cartella e mostra il contenuto}
+_texticonclosedfolder2_ [l=it] {apri la sottosezione: }
+_texticonopenfolder_ [l=it] {Chiudi questa cartella}
+_texticonopenfolder2_ [l=it] {Chiudi la sottosezione: }
+_texticonsmalltext_ [l=it] {Mostra questa sezione del testo}
+_texticonsmalltext2_ [l=it] {Mostra testo: }
+_texticonpointer_ [l=it] {Sezione corrente}
+_texticondetach_ [l=it] {Apri questa pagina in una nuova finestra}
+_texticonhighlight_ [l=it] {Evidenzia le parole cercate}
+_texticonnohighlight_ [l=it] {Non evidenziare le parole cercate}
+_texticoncontracttoc_ [l=it] {Nascondi indice}
+_texticonexpandtoc_ [l=it] {Mostra indice}
+_texticonexpandtext_ [l=it] {Mostra tutto il testo}
+_texticoncontracttext_ [l=it] {Mostra il testo solo per la sezione correntemente selezionata}
+_texticonwarning_ [l=it] {<b>Attenzione: </b>}
+_texticoncont_ [l=it] {continuare?}
+
+_textltwarning_ [l=it] {<div class="buttons">_imagecont_</div>
+_iconwarning_ mostrare il testo qui significa una
+grande quantitÃ  di dati
+}
+
+_textgoto_ [l=it] {vai a pagina}
+_textintro_ [l=it] {<i>(introduzione)</i>}
+
+_textCONTINUE_ [l=it] {CONTINUA??}
+
+_textEXPANDTEXT_ [l=it] {ESPANDI\nTESTO}
+
+_textCONTRACTCONTENTS_ [l=it] {NASCONDI\nINDICE}
+
+_textDETACH_ [l=it] {NUOVA\nFINESTRA}
+
+_textEXPANDCONTENTS_ [l=it] {MOSTRA\nINDICE}
+
+_textCONTRACT_ [l=it] {NASCONDI\nTESTO}
+
+_textHIGHLIGHT_ [l=it] {EVIDENZIA}
+
+_textNOHIGHLIGHT_ [l=it] {NON\nEVIDENZIARE}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=it] {_If_(_thislast_,risultati _thisfirst_ - _thislast_ della ricerca: _cgiargq_,Nessun risultato della ricerca: _cgiargq_)}
+_textnoquerytitle_ [l=it] {Pagina di ricerca}
+
+_textsome_ [l=it] {almeno una delle}
+_textall_ [l=it] {tutte le}
+_textboolean_ [l=it] {booleano}
+_textranked_ [l=it] {posizione}
+_textnatural_ [l=it] {naturale}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=it] {storico ricerca}
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+_textusequery_ [l=it] {Cerca}
+_textfreqmsg1_ [l=it] {Conteggio parole: }
+_textpostprocess_ [l=it] {_If_(_quotedquery_,<br><i>trasformata in _quotedquery_</i>
+)}
+_textinvalidquery_ [l=it] {Invalida sintassi di ricerca}
+
+_textmorethan_ [l=it] {PiÃ¹ di }
+_textapprox_ [l=it] {Circa }
+_textnodocs_ [l=it] {Nessun documento soddisfa le condizioni.}
+_text1doc_ [l=it] {1 documento soddisfa le condizioni.}
+_textlotsdocs_ [l=it] {documenti soddisfano le condizioni.}
+_textmatches_ [l=it] {Trovati }
+_textbeginsearch_ [l=it] {Inizia ricerca}
+_textrunquery_ [l=it] {Esegui ricerca}
+_textclearform_ [l=it] {Pulisci maschera}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=it] {Parola o frase}
+_textinfield_ [l=it] {... nel campo}
+_textfoldstem_ [l=it] {(desinenza, radice)}
+
+_textadvquery_ [l=it] {O inserisci direttamente una query:}
+_textallfields_ [l=it] {Tutti i campi}
+_texttextonly_ [l=it] {solo testo}
+_textand_ [l=it] {e}
+_textor_ [l=it] {o}
+_textandnot_ [l=it] {e non}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=it] {Cerca _indexselection_ _If_(_jselection_,di _jselection_ )_If_(_gselection_, a livello _gselection_ )_If_(_nselection_,in lingua _nselection_ )contenenti _querytypeselection_ parole specificate}
+
+_textadvancedsearch_ [l=it] {Cerca _indexselection_ _If_(_jselection_,di _jselection_ )_If_(_gselection_, a livello _gselection_ )_If_(_nselection_,in lingua _nselection_ )secondo _querytypeselection_}
+
+_textformsimplesearch_ [l=it] {Cerca _If_(_jselection_,_jselection_ )_If_(_gformselection_,a livello _gformselection_ ) _If_(_nselection_,in lingua _nselection_ )contenenti _formquerytypesimpleselection_ di}
+
+_textformadvancedsearch_ [l=it] {Cerca _If_(_jselection_,_jselection_ )_If_(_gformselection_,a livello di _gformselection_ )_If_(_nselection_,in lingua _nselection_ )e mostra i risultati in ordine _formquerytypeadvancedselection_}
+
+
+_textnojsformwarning_ [l=it] {Attenzione: Javascript Ãš disabilitato sul tuo browser. <br> Abilitalo per vuoi utilizzare il campo ricerca}
+_textdatesearch_ [l=it] {In questa raccolta si possono anche cercare documenti compresi in un intervallo di date o contenenti una particolare data. }
+_textstartdate_ [l=it] {Data iniziale (o  data):}
+_textenddate_ [l=it] {Data finale:}
+_textbc_ [l=it] {A.C.}
+_textad_ [l=it] {D.C.}
+_textexplaineras_ [l=it] {C.E. e B.C.E. sono alternativi rispettivamente a D.C. e A.C. Questi termini vengono impiegati per evitare discriminazioni culturali e stanno per "Common Era" e "Before Common Era"}
+
+_textstemon_ [l=it] {(ignora la declinazione delle parole)}
+
+_textsearchhistory_ [l=it] {Storico ricerca}
+
+#text macros for search history
+_textnohistory_ [l=it] {Storico ricerca non disponibile}
+_texthresult_ [l=it] {risultato}
+_texthresults_ [l=it] {risultati}
+_texthallwords_ [l=it] {tutte le parole}
+_texthsomewords_ [l=it] {almeno una parola}
+_texthboolean_ [l=it] {booleana}
+_texthranked_ [l=it] {classifica}
+_texthcaseon_ [l=it] {maiuscole e minuscole devono coincidere}
+_texthcaseoff_ [l=it] {maiuscole e minuscole non devono coincidere}
+_texthstemon_ [l=it] {radice}
+_texthstemoff_ [l=it] {parola intera}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=it] {Le impostazioni sono state fissate come riportato di seguito.
+Non usare il pulsante "indietro" del tuo browser - le cancellerebbe!
+Fai click invece su uno dei pulsanti della barra soprastante.
+}
+_textsetprefs_ [l=it] {modifica impostazioni}
+_textsearchprefs_ [l=it] {impostazioni di ricerca}
+_textcollectionprefs_ [l=it] {impostazioni della raccolta}
+_textpresentationprefs_ [l=it] {impostazioni di visualizzazione}
+_textpreferences_ [l=it] {Impostazioni}
+_textcasediffs_ [l=it] {Maiuscole:}
+_textignorecase_ [l=it] {ignora maiuscole}
+_textmatchcase_ [l=it] {maiuscole e minuscole devono corrispondere}
+_textwordends_ [l=it] {Parole:}
+_textstem_ [l=it] {ignora la declinazione delle parole}
+_textnostem_ [l=it] {la parola completa deve corrispondere}
+_textprefop_ [l=it] {Cerca fino a _maxdocoption_ risultati, _hitsperpageoption_ per pagina.}
+_textextlink_ [l=it] {Accesso a pagine web esterne:}
+_textintlink_ [l=it] {Documenti originali presi da:}
+_textlanguage_ [l=it] {Lingua dell'interfaccia:}
+_textencoding_ [l=it] {Codifica:}
+_textformat_ [l=it] {Formato dell'interfaccia:}
+_textall_ [l=it] {tutte}
+_textquerymode_ [l=it] {ModalitÃ  ricerca:}
+_textsimplemode_ [l=it] {ricerca semplice}
+_textadvancedmode_ [l=it] {ricerca avanzata (permette espressioni booleane che contengono !, &, |, e parentesi)}
+_textlinkinterm_ [l=it] {attraverso pagina intermedia}
+_textlinkdirect_ [l=it] {vai direttamente}
+_textdigitlib_ [l=it] {la biblioteca digitale}
+_textweb_ [l=it] {il web}
+_textgraphical_ [l=it] {Grafica}
+_texttextual_ [l=it] {Testuale}
+_textcollectionoption_ [l=it] {<p>
+Sottoraccolte da includere:
+<br>}
+
+_textrelateddocdisplay_ [l=it] {mostra documenti correlati}
+_textsearchhistory_ [l=it] {Storico della ricerca:}
+_textnohistory_ [l=it] {Storico ricerca non presente}
+_texthistorydisplay_ [l=it] {mostra _historynumrecords_ elementi dello storico}
+_textnohistorydisplay_ [l=it] {non mostrare lo storico della ricerca}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=it] {ricerca attraverso modulo:}
+_textplainsearch_ [l=it] {Ricerca base:}
+_textqueryboxsize_ [l=it] {Dimensioni della casella di ricerca:}
+_textregbox_ [l=it] {casella normale}
+_textbigbox_ [l=it] {casella grande}
+_textformtype_ [l=it] {Tipo di modulo:}
+_textsimple_ [l=it] {semplice}
+_textadvanced_ [l=it] {avanzato}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=it] {con}
+_textfields_ [l=it] {campi}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=it] {Elenca documenti per}
+_textalsoshowing_ [l=it] {mostrare anche}
+_textwith_ [l=it] {con al massimo}
+_textdocsperpage_ [l=it] {documenti per pagina}
+
+_textfilterby_ [l=it] {Elenca i documenti contenenti}
+_textall_ [l=it] {tutte le parole}
+_textany_ [l=it] {almeno una parola}
+_textwords_ [l=it] {delle parole}
+_textleaveblank_ [l=it] {lascia vuota questa casella per vedere tutti i documenti}
+
+_browsebuttontext_ [l=it] {Elenco}
+
+_nodata_ [l=it] {<i>nessun dato</i>}
+_docs_ [l=it] {documenti}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=it] {Aiuto}
+_textSearchshort_ [l=it] {ricerca per parole}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=it] {elenco per titolo}
+_textCreatorshort_ [l=it] {elenco per autore}
+_textSubjectshort_ [l=it] {elenco per soggetti}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=it] {elenco per data di pubblicazione}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=it] {elenco per nome del file}
+_textLanguageshort_ [l=it] {elenco per lingua}
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=it] {elenco per serie}
+_textToshort_ [l=it] {elenco per destinatario}
+_textFromshort_ [l=it] {elenco per mittente}
+_textBrowseshort_ [l=it] {elenco pubblicazioni}
+_textOrganizationshort_ [l=it] {elenco per organizzazione}
+_textHowtoshort_ [l=it] {elenco per categorie di guide pratiche}
+_textTopicshort_ [l=it] {elenco per argomento}
+_textPeopleshort_ [l=it] {elenco per persone}
+_textAcronymshort_ [l=it] {elenco per acronimi utilizzati}
+_textPhraseshort_ [l=it] {elenco per occorrenza di frasi}
+_textArtistshort_ [l=it] {elenco per artisti}
+_textKeywordshort_ [l=it] {elenco per parole chiave}
+_textVolumeshort_ [l=it] {elenco per volume}
+_textCountriesshort_ [l=it] {elenco per paesi}
+_textdefaultshorttext_ [l=it] {classificatione non definita}
+
+_textSearchlong_ [l=it] {<p>Puoi effettuare la <i>ricerca per parole</i> nella pagina "ricerca".
+Questa Ãš la prima pagina che ti appare e puÃ² essere raggiunta premendo il
+pulsante <i>cerca</i>.  }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=it] {<p>Puoi <i>accedere alle publicazioni per titolo</i>
+premendo il pulsante <i>titoli a-z</i>. Questo ti mostra un elenco di
+ libri in ordine alfabetico. }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=it] {<p>Puoi <i>accedere alle pubblicazioni per autore</i>
+premendo il pulsante <i>autori a-z</i>. Questo mostra l'elenco di libri
+ ordinati per autore. }
+
+_textSubjectlong_ [l=it] {<p>Puoi <i>accedere alle pubblicazioni per soggetto</i> premendo il pulsante
+<i>soggetti</i>. Questo mostra la lista dei soggetti. }
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=it] {<p>Puoi <i>accedere alle pubblicazioni per data</i>
+premendo il pulsante <i>date</i>. Questo mostrerÃ  l'elenco di tutti
+i documenti ordinati cronologicamente. }
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=it] {<p>Puoi <i>accedere alle pubblicazioni in base al nome del file</i>
+premendo il pulsante <i>nomi del file</i>. Questo mostrerÃ  la lista dei documenti ordinati in base
+al nome originale del file.}
+
+_textLanguagelong_ [l=it] {<p>Puoi <i>accedere alle pubblicazioni in base alla lingua</i>
+premendo il pulsante <i>lingue</i>. Questo mostrerÃ  la lista dei documenti ordinati in base
+alla lingua. }
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=it] {<p>Puoi <i>accedere alle pubblicazioni
+per organizzazione</i> premendo il pulsante <i>organizzazioni</i>.
+Questo mostrerÃ  l'elenco delle organizzazioni.  }
+
+_textHowtolong_ [l=it] {<p>Puoi <i>accedere alle pubblicazioni per categorie di guide pratiche</i>
+premendo il pulsante <i>guide pratiche</i>.
+Questo ti mostra una lista di di categorie di guide pratiche. }
+
+_textTopiclong_ [l=it] {<p>Puoi <i>accedere alle pubblicazioni per argomento</i>
+premendo il pulsante <i>argomento</i>.
+Questo mostra l'elenco di argomenti da scegliere. }
+
+_textTolong_ [l=it] {<p>Puoi <i>accedere alle email per destinatario</i> premendo il pulsante
+<i>destinatario</i>Questo mostrerÃ  un elenco di indirizzi.  }
+
+_textFromlong_ [l=it] {<p>Puoi <i>accedere alle email per mittente</i>
+premendo il pulsante <i>mittente</i>. Questo mostrerÃ  l'elenco dei mittenti. }
+
+_textSerieslong_ [l=it] {<p>Puoi <i>accedere alle pubblicazioni per serie</i>
+premendo il pulsante <i>serie</i>. Questo mostrerÃ  l'elenco delle serie
+presenti nella raccolta.  }
+
+_textBrowselong_ [l=it] {<p>Puoi <i>visualizzare l'elenco delle pubblicazioni</i>
+premendo il pulsante <i>elenco</i>.  }
+
+_textPeoplelong_ [l=it] {<p>Puoi <i>accedere alle publicazioni in base alle persone</i>
+premendo il pulsante <i>persone a-z</i>. Questo mostrerÃ  l'elenco delle persone
+ordinato per cognome.  }
+
+_textAcronymlong_ [l=it] {<p>Puoi <i>accedere alle pubblicazioni tramite gli acronimi che vi compaiono</i>
+premendo il pulsante <i>acronimi</i>. Questo mostrerÃ  un elenco di acronimi e dei punti nei quale essi compaiono.  }
+
+_textPhraselong_ [l=it] {<p>Puoi <i>accedere alle pubblicazioni tramite le frasi che vi occorrono</i>
+premendo il pulsante <i>frasi</i>.  }
+
+_textArtistlong_ [l=it] {<p>Puoi <i> accedere alle pubblicazioni tramite gli artisti</i> premendo il pulsante <i>artisti</i>. Questo mostrerÃ  un elenco di voci ordinate per nome di artista.}
+
+_textKeywordlong_ [l=it] {<p>Puoi <i> accedere alle pubblicazioni per parola chiave</i> premendo il pulsante <i>parole chiave</i>. Questo mostrerÃ  un elenco di parole chiave.}
+
+_textVolumelong_ [l=it] {<p>Puoi <i>accedere alle pubblicazioni per volume</i> premendo il pulsante <i>volumi</i>. Verra` presentata una lista per volume.}
+
+_textCaptionslong_ [l=it] {<p>Puoi <i> accedere alle pubblicazioni tramite didascalia</i> premendo il pulsante <i>didascalie</i>. Questo mostrerÃ  un elenco di didascalie.}
+
+_textCountrieslong_ [l=it] {<p>Puoi <i> accedere alle pubblicazioni tramite il paese</i> premendo il pulsante <i>paesi</i>. Questo mostrerÃ  un elenco di paesi.}
+
+
+_textdefaultlongtext_ [l=it] {<p>Premi il pulsante <i>sconosciuto</i> per navigare tra pubblicazioni
+ordinate in base ad un campo sconosciuto.  }
+
+_texthelptopicstitle_ [l=it] {Argomenti}
+
+_textreadingdocs_ [l=it] {Come leggere i documenti}
+
+_texthelpreadingdocs_ [l=it] {
+<p>Puoi sapere quando sei arrivato ad uno specifico documento in quanto
+il titolo e l'autore appaiono in alto a sinistra nella pagina. Inoltre
+appare il numero della pagina corrente, una casella che ti permette
+di scegliere la pagina da visualizzare e delle frecce per andare avanti ed indietro.
+
+<p>Sotto c'Ãš il testo della sezione corrente. Sotto di esso ci sono delle
+frecce per tornare alla sezione precedente o per spostarsi alla successiva.
+
+<p>Sotto il titolo e l'autore ci sono tre pulsanti. Clicka su <i>espandi
+testo</i> per visualizzare tutto il testo del documento corrente. Se il
+documento Ãš molto grande questo richiederÃ  molto tempo e molta memoria!
+Clicka su <i>nuova finestra</i> per aprire una nuova finestra del browser contenente
+il documento. (Questo puÃ² essere utile se desideri confrontare due documenti o
+leggere piÃ¹ di un documento alla volta.) Infine quando effettui una ricerca
+le parole cercate appaiono evidenziate, clicka su <i>non evidenziaziare</i> per rimuovere la sottolineatura.
+}
+
+# help about the icons
+_texthelpexpandtext_ [l=it] {Mostra (o no) tutto il testo}
+_texthelpdetachpage_ [l=it] {Mostra questa pagina in una nuova finestra}
+_texthelphighlight_ [l=it] {Evidenzia (o no) le parole cercate}
+
+_texthelpsearchingtitle_ [l=it] {Come cercare parole particolari}
+_texthelpsearching_ [l=it] {
+<p>
+  Dalla pagina di ricerca, puoi cercare tramite questi semplici passi:<p>
+
+  <ol><li>Specifica in che ambito effettuare la ricerca
+      <li>Specifica se vuoi cercare tutte o alcune delle parole
+      <li>Scrivi le parole che vuoi cercare
+      <li>Clicka il pulsante <i>Ricerca</i>
+  </ol>
+
+<p>Quando effettui una ricerca, appaiono i titoli di venti documenti.
+Il pulsante in basso ti permette di visualizzare i successivi venti.
+Una volta premuto appariranno i pulsanti che ti permettono di visualizzare i
+venti documenti successivi o quelli precedenti.
+Clicka sul titolo di un documento, o sul piccolo pulsante affianco ad esso,
+per visualizzarne il contenuto.
+
+<p>Il numero massimo di documenti elencati Ãš fissato a 100.
+Puoi modificare questo numero clickando sul pulsante <i>impostazioni</i>
+nella parte alta della pagina.<p>
+}
+
+_texthelpquerytermstitle_ [l=it] {Parole da cercare}
+_texthelpqueryterms_ [l=it] {
+<p>Qualsiasi cosa scrivi nella casella di ricerca viene interpretato come
+"parole da cercare". Ogni parola non contiene nient'altro che caratteri
+alfabetici e cifre numeriche. Le parole sono separate da spazi.
+Se altri caratteri (come i segni di punteggiatura) appaiono, questi verranno
+utilizzati per separare le parole come se fossero spazi. Non Ãš possibile
+ricercare parole che includono segni di punteggiatura.
+
+<p>Per esempio la ricerca:<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>verrÃ  trattata come se fosse:<p>
+      <ul><kbd>Agro forestry in the Pacific Islands Systems for Sustainability 1993 </kbd></ul><p>
+}
+
+_texthelpquerytypetitle_ [l=it] {Tipi di ricerca}
+_texthelpquerytype_ [l=it] {
+<p>Ci sono due differenti tipi di ricerca:
+
+<ul>
+  <li>Ricerca di <b>tutte</b> le parole. In questo caso si cercano documenti
+  (o capitoli o titoli) che contengano tutte le parole specificate.
+  I documenti che soddisfano questa condizine sono elencati in ordine alfabetico.<p>
+
+  <li>Ricerca di <b>alcune</b> delle parole. Scrivi alcune delle parole che
+  probabilmente compariranno nei documenti che stai cercando. I documenti verranno
+  elencati in base al grado di corrispondenza alla ricerca effettuata. Nella
+  determinazione del grado di corrispondenza,
+
+      <p><ul>
+        <li> piÃ¹ parole da cercare il documento contiene, piÃ¹ elevato Ãš il grado;
+        <li> le parole rare sono piÃ¹ importanti delle parole comuni;
+        <li> i documenti corti corrispondono meglio di quelli lunghi.
+      </ul>
+</ul>
+
+<p>Usa quante parole da cercare desideri - una intera frase o anche
+un intero paragrafo. Se specifichi una sola parola i documenti saranno ordinati
+in base al numero di volte in cui occorre quella parola in ognuno.<p>
+}
+
+_textdatesearch_ [l=it] {Ricerca per data}
+
+_texthelpdatesearch_ [l=it] {
+La ricerca per data permette di trovare documenti che, oltre a contenere parole da cercare,
+riguardano eventi avvenuti in un certo intervallo temporale.
+Puoi cercare documenti di un certo anno o in una serie di anni.
+Nota che non Ãš indispensabile inserire parole da cercare, puoi effettuare
+ricerche anche solo sulle date, cosÃ¬ come non Ãš necessario inserire delle date;
+se non scrivi alcuna data Ãš come se si effettuasse una ricerca non per data.<p>
+}
+
+_texthelpdatehowtotitle_ [l=it] {Come utilizzare questa funzionalitÃ :}
+_texthelpdatehowto_ [l=it] {
+<ul>
+   <li>Come cercare documenti riguardanti un singolo anno:<p>
+   <ul>
+       <li>Scrivi le parole da cercare come faresti normalmente.
+       <li>Scrivi l'anno nella casella "Data iniziale (o data)".
+       <li>Se la data Ãš Avanti Cristo,
+       scegli l'opzione A.C. dal menu a tendina a fianco.
+       <li>Avvia la ricerca come faresti normalmente.
+   </ul>
+<p><li>Per cercare documenti riguardanti un periodo di tempo o un intervallo di anni:<p>
+   <ul>
+       <li>Scrivi le parole da cercare come faresti normalmente.
+       <li>Scrivi la data di partenza nella casella "Data iniziale (o data)".
+       <li>Scrivi la data finale nella casella "Data finale".
+       <li>Seleziona A.C. dal menu a tendina per ogni data Avanti Cristo.
+       <li>Avvia la ricerca come faresti normalmente.
+   </ul>
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=it] {Come funziona la ricerca}
+_texthelpdateresults_ [l=it] {
+Generalmente una ricerca di documenti riguardanti l'anno 1903 non mostrerÃ  quelli che, ad esempio,
+sono stati scritti nel 1903, solo i documenti che riguardano il 1903. In ogni modo, verranno trovati i documenti
+che hanno nel testo un'intervallo di date (ad esempio 1899-1911) in cui rientra il 1903, e tutti i documenti
+che hanno nel testo il nome del secolo di cui Ãš parte il 1903 (ad esempio 20th century o twentieth century).
+Questo significa che per alcuni documenti la data ricercata potrebbe non apparire nel testo. Se si effettua la ricerca
+su di un intervallo di date, questo si applica a tutte la date nell'intervallo.<p>
+}
+
+_textchangeprefs_ [l=it] {Modifica le impostazioni}
+
+_texthelppreferences_ [l=it] {
+<p>Premendo il pulsante <i>impostazioni</i> in alto nella pagina puoi modificare
+alcune caratteristiche dell'interfaccia per adattarla alle tue esigenze.
+}
+
+_texthelpcollectionprefstitle_ [l=it] {Impostazioni relative alle raccolte}
+_texthelpcollectionprefs_ [l=it] {
+Alcune raccolte comprendono diverse sottoraccolte, su cui Ãš possibile
+effettuare ricerche singolarmente o come un tutt'uno. In questi casi, nella pagina Impostazioni puoi
+scegliere quali sottoraccolte prendere in considerazione nelle ricerche.
+}
+
+_texthelplanguageprefstitle_ [l=it] {Impostazioni della lingua}
+_texthelplanguageprefs_ [l=it] {
+Ogni raccolta ha una lingua di presentazione predefinita, ma puoi cambiare lingua se lo desideri.
+Puoi anche cambiare il set di caratteri utilizzato da Greenstone per l'output verso il tuo browser
+-- il software ha delle opportune impostazioni predefinite ma con alcuni browser puoi ottenere una
+visualizzazione migliore cambiando il set di caratteri. Tutte le raccolte permettono di passare dall'interfaccia
+grafica standard ad una testuale. Questa Ãš particolarmente utile per gli ipovedenti che utilizzano
+delle interfacce testuali con tipi di caratteri molto grandi oppure dei sintetizzatori vocali.
+}
+
+_texthelppresentationprefstitle_ [l=it] {Impostazioni relative all'interfaccia}
+_texthelppresentationprefs_ [l=it] {
+A seconda della raccolta possono esserci numerose opzioni modificabili riguardanti l'interfaccia.
+
+<p>Le raccolte di pagine web ti permettono di eliminare la barra di navigazione di Greenstone che altrimenti
+appare sulla sommitÃ  di ogni pagina, in questo modo quando effettui una ricerca trovi esattamente la pagina
+cercata senza alcuna intestazione aggiuntiva. In questo caso, per effettuare una nuova ricerca
+dovrai utilizzare il pulsante "indietro" del browser.
+Queste raccolte ti permettono anche di eliminare il messaggio di avvertimento che appare quando fai click su
+di un collegamento che ti porta direttamente sul web, fuori dalla raccolta.
+Inoltre in alcune raccolte di pagine web puoi stabilire se i link presentati nella pagina "Risultati della ricerca"
+ti portano direttamente all'URL in questione piuttosto che alla copia della pagina web presente nella
+biblioteca digitale.
+}
+
+_texthelpsearchprefstitle_ [l=it] {Impostazioni relative alla ricerca}
+_texthelpsearchprefs_ [l=it] {
+<p>Due coppie di pulsanti controlano il tipo di confronto tra parole nelle ricerche che effettui.
+La prima coppia ("sensibilitÃ  alle maiuscole") stabilisce se le maiuscole e le minuscole devono essere
+considerate differenti nel confronto tra le parole.
+La seconda coppia ("finali delle parole") stabilisce se ignorare la declinazione delle parole nelle operazioni
+di confronto.
+E' inoltre possibile ingrandire la casella in cui inserire le parole da cercare, in modo da rendere piÃ¹
+semplice cercare frasi lunghe. La ricerca di grandi porzioni di testo Ãš incredibilmente veloce.
+
+<p>Ad esempio, se i pulsanti <i>ignora maiuscole</i> ed
+<i>ignora la declinazione delle parole</i> sono selezionati, la ricerca<p>
+    <ul><kbd>Edifici africani</kbd></ul>
+      <p>sarÃ  trattata allo stesso modo di<p>
+      <ul><kbd>africa edificio</kbd></ul><p>
+      in quanto la maiuscola in "Edifici" sarÃ  trasformata in minuscola e le desinenze saranno rimosse
+      (NOTA DEL TRADUTTORE: quest'ultima funzionalitÃ  potrebbe non funzionare correttamente quando
+      applicata a parole non in lingua inglese).
+
+<p>Puoi passare ad una modalitÃ  di ricerca "avanzata" che ti permette di unire piÃ¹ condizioni
+usando AND (&), OR (|), e NOT (!).
+Questo permette di creare ricerche piÃ¹ precise.
+Puoi abilitare o disabilitare lo storico delle ricerche, questo ti mostrerÃ  le ultime
+ricerche effettuate rendendo piÃ¹ semplice la ripetizione di ricerche simili tra loro.
+Infine puoi stabilire il numero massimo di documenti da trovare ed il numero massimo di documenti
+da mostrare in una schermata.
+}
+
+_texttanumbrowseoptions_ [l=it] {Ci sono _numbrowseoptions_ modi per cercare le informazioni nell'ambito di questa raccolta:}
+
+_textsimplehelpheading_ [l=it] {Come cercare le informazioni}
+
+_texthelpscopetitle_ [l=it] {Ambito delle ricerche}
+_texthelpscope_ [l=it] {
+<p>In alcune raccolte puoi scegliere tra diversi indici per effettuare le ricerche. Ad esempio, ci possono essere
+indici sugli autori e sui titoli, oppure ci possono essere indici sui nomi dei capitoli e dei paragrafi.
+Generalmente, viene ritornato comunque l'intero documento a prescindere dall'indice su cui si Ãš effettuata
+la ricerca.
+
+<p>Se il documento Ãš un libro, questo verrÃ  aperto in un punto specifico.
+}
Index: /gsdl/stable/macros/italian2.dm
===================================================================
--- /gsdl/stable/macros/italian2.dm	(revision 20131)
+++ /gsdl/stable/macros/italian2.dm	(revision 20131)
@@ -0,0 +1,787 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Italian Language text and icon macros 
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=it] {documenti. }
+_lastupdate_ [l=it] {Ultima modifica}
+_ago_ [l=it] {giorni fa.}
+_colnotbuilt_ [l=it] {Raccolta non costruita.}
+
+_textpoem_ [l=it] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>possano la pace e la calma circondarti,
+<br>possa tu vivere nel calore della foschia estiva,
+<br>possa l'oceano in cui tu viaggi essere levigato come la nefrite.
+}
+
+_textgreenstone_ [l=it] {<p>La nefrite (greenstone) Ãš una pietra semi-preziosa che (come questo software) viene dalla Nuova Zelanda.
+Nella societÃ  tradizionale dei Maori era la piÃ¹ costosa ed ambita di tutte le sostanze. Essa puÃ²
+assorbire e conservare lo <i>wairua</i>, lo spirito della forza vitale, ed Ãš dotata di virtÃ¹ tradizionali
+che la rendono un emblema appropriato per una biblioteca digitale di pubblico dominio.
+Il suo splendore Ãš simbolo di caritÃ ; la sua trasparenza, di onestÃ ; la sua durezza, di coraggio;
+ed i bordi taglienti che puÃ² avere, di giustizia.
+La pietra lavorata utilizzata come logo del software Greenstone Digital Library Ãš un <i>patu</i>
+o mazza da guerra, ed Ãš un cimelio di famiglia di uno dei membri del progetto.
+Nel combattimento corpo a corpo il suo colpo Ãš molto veloce e preciso. A noi piace pensare
+che queste qualitÃ  si applicano anche al nostro software, il bordo del <i>patu</i> tagliente come un rasoio
+simboleggia il vertice della tecnologia.
+}
+
+_textaboutgreenstone_ [l=it] {<p>Greenstone Ãš una suite di software adatti a gestire collezioni di biblioteche digitali ed a creare nuove collezioni. Fornisce un nuovo modo di organizzare informazioni e di pubblicarle su Internet o su CD-ROM.  Greenstone Ãš prodotto dal <b>New Zealand Digital Library Project</b> presso l'<b>UniversitÃ  di Waikato</b>, ed Ãš distribuito in cooperazione con l'<b>UNESCO</b> e lo <b>Human Info NGO</b>. E' un software open-source, disponibile da  <i>http://greenstone.org</i> sotto i termini della GNU General Public
+License.                                                                                                                                                                                                     <p>Lo scopo del sofware Ãš quello di dare la possibilitÃ  agli utenti, particolarmente in universitÃ , biblioteche ed altre istituzioni pubbliche, di creare proprie biblioteche digitali. Le biblioteche digitali stanno modificando radicalmente il modo in cui l'informazione viene disseminata ed acquisita nelle comunitÃ  e nelle istituzioni partner dell'UNESCO nei campi dell'educazione, della scienza e della cultura in tutto il mondo, e particolarmente nei paesi in via di sviluppo. Speriamo che questo software possa incoraggiare la diffusione effettiva delle biblioteche digitali al fine di condividere l'informazione e di porla nel pubblico dominio.  
+
+<p>Questo software Ãš sviluppato e distribuito come un'opera collaborativa internazionale avviata nell'agosto 2000 fra tre istituzioni.
+
+<table border="0">
+<tr valign="top">
+<td>
+<a href="http://nzdl.org"><b>New Zealand Digital Library Project presso l'UniversitÃ  di Waikato</b></a>
+<br>
+Il software Greenstone Ãš scaturito da questo progetto e l'iniziativa Ãš stata appoggiata dalla sub-commissione Comunicazione della Commissione della Nuova Zelanda per l'UNESCO, come parte del contributo della Nuova Zelanda al programma dell'UNESCO.
+</td>
+<td></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://www.unesco.org"><b>United Nations Educational, Scientific and Cultural Organization</b></a>
+<br>
+La disseminazione dell'informazione educativa, scientifica e culturale nel mondo, e particolarmente la sua disponibilitÃ  nei paesi in via di sviluppo,            Ãš centrale negli obiettivi dell'UNESCO, che la persegue all'interno del programma intergovernativo Infomation for All, ed una tecnologia dell'informazione e comunicazione appropriata ed accessibile Ãš vista come un importante strumento in questo contesto. 
+</td>
+<td><a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+border="0"></a></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://humaninfo.org"><b>Lo Human Info NGO, fondato ad Anversa, Belgio</b></a>
+<br>
+Questo progetto collabora con agenzie ONU ed altre organizzazione non governative, ed ha conquistato una reputazione internazionale per la digitalizzazione di documentazione d'interesse per lo sviluppo umano e per averla resa ampiamente accessibile, gratuitamente per i paesi in via di sviluppo, a copertura dei costi per gli altri.
+</td>
+<td><a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" border="0"></a></td>
+</tr>
+</table>
+
+}
+
+_textdescrselcol_ [l=it] {scegli una collezione}
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=it] {Ci sono quattro pulsanti ulteriori sulla home page}
+
+_textnocollections_ [l=it] {<p>Non vi sono attualmente collezioni disponibili in questa installazione Greenstone. 
+Per aggiungerne alcune puoi 
+<ul><li>usare <a href="_httppagecollector_">Il Collector</a> per costruire nuove collezioni
+    <li>Se hai un cd-rom Greenstone cd-rom puoi installare collezioni dal cd-rom
+</ul>
+}
+
+_text1coll_ [l=it] {Questa installazione di Greenstone contiene 1 collezione}
+
+_textmorecolls_ [l=it] {Questa installazione Greenstone contiene _1_ collezioni}
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=it] {Collegamento esterno}
+_textlinknotfound_ [l=it] {Collegamento interno non trovato}
+
+_textextlinkcontent_ [l=it] {Il collegamento che hai selezionato Ãš esterno alle raccolte correntemente selezionate da te.
+Se desideri ugualmente seguire questo collegamento ed il tuo browser ha accesso al web, puoi
+<a href="_nexturl_">proseguire</a> altrimenti usa il pulsante "indietro" del browser per tornare al documento
+precedente.}
+
+_textlinknotfoundcontent_ [l=it] {Per ragioni aldilÃ  del nostro controllo, il link interno che hai selezionato
+non esiste. Questo probabilmente Ãš dovuto ad un errore nel documento originale. Usa il pulsante "indietro" del
+browser per tornare al documento preccedente.}
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=it] {<h3>Collegamento alla raccolta "_2_"</h3>
+
+<p> Il collegamento che hai selezionato Ãš esterno alla raccolta "_collectionname_" (esso porta alla raccolta
+"_2_"). Se desideri seguire questo collegamento verso la raccolta "_2_" puoi
+<a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">proseguire</a> verso questa pagina; altrimenti usa il pulsante "indietro"
+del browser per tornare al documento precedente.
+}
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=it] {Greenstone Digital Library}
+
+_textusername_ [l=it] {nome utente}
+_textpassword_ [l=it] {password}
+
+_textmustbelongtogroup_ [l=it] {Nota che devi appartenere al gruppo "_cgiargug_" per accedere a questa pagina}
+
+_textmessageinvalid_ [l=it] {La pagina che hai richiesto necessita di autenticazione.<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)
+Inserisci nome e password.}
+
+_textmessagefailed_ [l=it] {Il tuo nome o la tua password sono errati.}
+
+_textmessagedisabled_ [l=it] {Spiacente, il tuo account Ãš stato disabilitato. Contatta il webmaster di questo sito.}
+
+_textmessagepermissiondenied_ [l=it] {Spiacente, non hai il permesso di accedere a questa pagina.}
+
+_textmessagestalekey_ [l=it] {La pagina Ãš scaduta. Inserisci la password per accedere a questa pagina.}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=it] {<p>Questa installazione di Greenstone non include alcuna documentazione. CiÃ² puÃ² 
+essere perchÃ©:
+<ol>
+ <li>Greenstone Ãš stato installato da CD-ROM usando una installazione compatta.
+ <li>Greenstone Ãš stato installato da una distribuzione scaricata da internet.
+</ol>
+In entrambi i casi puoi ottenere la documentazione dalla directory <i>docs</i>
+di un CD-ROM Greenstone oppure visitando <a
+href="http://www.greenstone.org">http://www.greenstone.org</a>.
+}
+
+_textuserguide_ [l=it] {Guida utente}
+_textinstallerguide_ [l=it] {Guida dell'installatore}
+_textdeveloperguide_ [l=it] {Guida dello sviluppatore}
+_textpaperguide_ [l=it] {Guida dalla carta alla collezione}
+_textorganizerguide_ [l=it] {Usare l'Organizer}
+
+_textgsdocstitle_ [l=it] {documentazione Greenstone}
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=it] {struttura di default}
+_textmore_ [l=it] {altro}
+_textinfo_ [l=it] {Informazioni sulla collezione}
+_textsrce_ [l=it] {Origine dati}
+_textconf_ [l=it] {Configura la collezione}
+_textbild_ [l=it] {Crea la collezione}
+_textview_ [l=it] {Vedi la collezione}
+_textdel_ [l=it] {Cancella la collezione}
+_textexpt_ [l=it] {Esporta la collezione}
+
+_textdownloadingfiles_ [l=it] {Scaricamento file in corsoâŠ}
+_textimportingcollection_ [l=it] {Importazione della collezione in corsoâŠ}
+_textbuildingcollection_ [l=it] {Creazione della collezione in corsoâŠ}
+_textcreatingcollection_ [l=it] {creazione della collezioneâŠ}
+
+_textcollectorblurb_ [l=it] {<i>La penna Ãš piÃ¹ potente della spada! <br>Creare e distribuire collezioni di informazioni comporta delle responsabilitÃ  sulle quali Ãš bene riflettere prima di iniziare. Esistono questioni legali connesse al copyright: la possibilitÃ  di accedere ai documenti non significa necessariamente che li puoi scambiare con altre persone. Vi sono questioni di natura sociale: le collezioni dovrebbero rispettare i costumi della comunitÃ  al di fuori della quale i documenti sono nati. E vi sono motivi etici: alcune cose semplicemente non dovrebbero essere rese disponibili ad altri. <br>Sii sensibile al potere dell'informazione ed usalo con saggezza. </i>}
+
+_textcb1_ [l=it] {Il Collector consente di creare nuove collezioni, di modificarle, aggiungerle o cancellarle. Per fare questo, sarai guidato attraverso una serie di pagine web che raccolgono le informazioni necessarie.}
+
+_textcb2_ [l=it] {Innanzitutto, devi decidere se}
+_textcnc_ [l=it] {crea una nuova collezione}
+_textwec_ [l=it] {lavorare con una esistente, aggiungervi dati o cancellarla.}
+
+_textcb3_ [l=it] {Per poter costruire o modificare le collezioni della biblioteca digitale devi identificarti. Questo al fine di proteggere da accessi non autorizzati al tuo computer e da alterazioni dei dati contenuti. }
+
+_textcb4_ [l=it] {Inserisci, per favore, il tuo nome utente Greenstone e la password, poi clicca sul pulsante per entrare.}
+
+_textfsc_ [l=it] {Per prima cosa seleziona la collezione su cui vuoi lavorare (le collezioni protette in scrittura non appariranno in questo elenco).}
+
+_textwtc_ [l=it] {Con la collezione che hai selezionato, puoi}
+_textamd_ [l=it] {Aggiungi altri dati e ricostruisci la collezione}
+_textetc_ [l=it] {Modifica il file di configurazione della collezione e ricostruisci la collezione}
+_textdtc_ [l=it] {Cancella la collezione interamente}
+_textetcfcd_ [l=it] {Esporta la collezione per la copia su un CD-ROM Windows autoinstallante.}
+_textcaec_ [l=it] {Modifica una collezione esistente}
+_textnwec_ [l=it] {Non Ãš disponibile nessuna collezione abilitata in scrittura per modifiche}
+_textcianc_ [l=it] {Crea una nuova collezione}
+_texttsosn_ [l=it] {La sequenza di passi necessari a creare una nuova collezione digitale Ãš:}
+_textsin_ [l=it] {Specifica il suo nome (e le informazioni connesse)}
+_textswts_ [l=it] {Specifica da dove provengono i dati di origine}
+_textatco_ [l=it] {Modifica le opzioni di configurazione (solo utenti avanzati)}
+_textbtc_ [l=it] {"Crea" la collezione (vedi sotto)}
+_textpvyh_ [l=it] {Vedi il lavoro fatto}
+
+_texttfsiw_ [l=it] {Il quarto passo Ãš la fase in cui il computer esegue tutto il lavoro. Nel processo di costruzione il computer crea tutti gli indici e combina ogni altra informazione necessaria al funzionamento. Ma prima di tutto devi specificare le informazioni.}
+
+_textadab_ [l=it] {Sotto appare un diagramma che consentirÃ  di mantenere la traccia del punto in cui ci si trova. Il pulsante verde Ãš quello che puoi cliccare per proseguire lungo la sequenza. I pulsanti cambieranno in giallo man mano che ci si sposta nella sequenza. E' possibile ritornare ad una pagina precedente cliccando sul pulsante giallo corrispondente nel diagramma.}
+
+_textwyar_ [l=it] {Quando sei pronto, clicca il bottone verde "informazioni sulla collezione" per avviare la creazione della nuova collezione digitale!}
+
+_textcnmbs_ [l=it] {Il nome della collezione deve essere specificato}
+_texteambs_ [l=it] {L'indirizzo email deve essere specificato}
+_textpsea_ [l=it] {Specifica l'indirizzo email nel campo: username@domain}
+_textdocmbs_ [l=it] {La descrizione della collezione deve essere specificata}
+
+_textwcanc_ [l=it] {Durante la creazione di una nuova collezione devi inserire alcune informazioni preliminari relative alla fonte dei dati. Questo processo Ãš strutturato come una serie di pagine web controllate dal Collector. La barra a piÃš di pagina mostra la sequenza di pagine che deve essere completata.}
+
+_texttfc_ [l=it] {Titolo della collezione:}
+
+_texttctiasp_ [l=it] {Il titolo della collezione Ãš una breve frase usata all'interno della biblioteca digitale per 
+identificare il contenuto della collezione. Titoli di esempio possono essere
+"Rapporti tecnici ed informatici" e "Biblioteca dello sviluppo dell'umanitÃ "
+}
+
+_textcea_ [l=it] {Contatta l'indirizzo mail.}
+
+_textteas_ [l=it] {Questo indirizzo email specifica il principale punto di contatto per la collezione.
+Se il software Greenstone individua un problema, invierÃ  un rapporto diagnostico a questo indirizzo.
+Inserisci un indirizzo email nella sua forma completa: <tt>name@domain</tt>.
+}
+
+_textatc_ [l=it] {Informazioni su questa collezione:}
+
+_texttiasd_ [l=it] {Questa Ãš una dichiarazione che illustra i principi che regolano ciÃ² che viene inserito nella collezione. Appare sulla prima pagina quando la collezione viene presentata.}
+
+_textypits_ [l=it] {La tua posizione nella sequenza Ãš indicata sotto da una freccia - in questo caso, la fase "informazioni sulla collezione". Per proseguire, clicca il bottone verde "origine dati".}
+
+_srcebadsources_ [l=it] {<p>Una o piÃ¹ delle fonti che hai specificato non Ãš disponibile (contrassegnata
+_iconcross_ sotto).
+
+<p>Questo puÃ² essere perchÃš
+<ul>
+<li>Il file, il sito FTP o l'URL non esiste.
+<li>Devi connetterti prima al tuo ISP.
+<li>Stai cercando di accedere ad un URL protetto da firewall (Ãš questo il caso se normalmente devi fornire username e password per accedere a Internet).
+</ul>
+
+<p>Se questo Ãš un URL che puoi visualizzare sul tuo browser, potrebbe provenire da una copia nella cache locale. Purtroppo le copie memorizzate nella cahe locale non sono visibili al nostro processo di mirroring. In questo caso, ti raccomandiamo di scaricare le pagine utilizzando direttamente il tuo browser.
+}
+
+_textymbyco_ [l=it] {<p>Puoi basare la tua collezione sia su
+<ul>
+<li>La struttura di default
+<dl><dd>La nuova collezione puÃ² contenere documenti html (.htm, .html), documenti solo testo
+(.txt, .text), documenti MS Word (.doc), documenti PDF (.pdf) oppure
+documenti email formato "m-box" (.mbx).</dd></dl>
+<li>Una collezione esistente
+<dl><dd>I file nella tua nuova collezione devono essere esattamente dello stesso tipo di quelli usati per creare quella esistente.</dd></dl>
+</ul>
+}
+
+_textbtco_ [l=it] {Basa la collezione su}
+_textand_ [l=it] {Aggiungi nuovi dati}
+_textad_ [l=it] {Aggiungere dati:}
+
+_texttftysb_ [l=it] {I file che hai indicato sotto saranno aggiunti alla collezione. Assicurati di non aver indicato file giÃ  presenti nella collezione, altrimenti verranno inserite due copie. I file sono identificati col loro percorso completo, le pagine web dal loro indirizzo web assoluto.}
+
+_textis_ [l=it] {Origine dati:}
+
+_textddd1_ [l=it] {<p>Se usi file:// o ftp:// per specificare un file, quel file verrÃ  scaricato. <p>Se usi http://, varia a seconda che l'URL indichi una normale pagina web nel tuo browser, oppure una lista di file. Se si tratta di una pagina, questa pagina verrÃ  scaricata - e cosÃ¬ avverrÃ  per tutte le pagine alle quali fa un link e dalle quali Ãš collegata etc. - ammesso che risiedano sullo stesso sito, secondo l'URL. <p>Se usi file:// o ftp:// per specificare una cartella o directory, oppure se fornisci un URL http:// che conduce ad una lista di file, ogni cosa contenuta nella cartella ed in tutte le sottocartelle verrÃ  inclusa nella collezione. <p>Clicca il pulsante "altri dettagli" per avere altre caselle di input.}
+
+_textddd2_ [l=it] {<p>Clicca uno dei pulsanti verdi. Se sei un utente avanzato, potresti avere la necessitÃ  di modificare la configurazione della collezione. Diversamente, vai direttamente alla fase di creazione. Ricorda che puoi sempre rivedere una fase precedente cliccando sul pulsante giallo.}
+
+_textconf1_ [l=it] {<p>La creazione e la presentazione della tua collezione sono controllate attraverso delle specifiche contenute in uno speciale "file di configurazione". Gli utenti avanzati potrebbero aver bisogno di modificare le impostazioni di configurazione. <center><p><b>Se non sei un utente avanzato, vai alla fine della pagina.</b></center> <p>Per cambiare le impostazione di configurazione, modifica i dati che appaiono sotto. Se fai un errore, clicca su "Reset" per ripristinare le impostazioni di configurazione originali.}
+
+_textreset_ [l=it] {Reset}
+
+_textbild1_ [l=it] {La collezione Ãš ora in fase di creazione: questa operazione potrebbe richiedere tempo. La linea di stato di avanzamento che appare sotto dÃ  informazioni su come sta procedendo l'operazione.}
+
+_textbild2_ [l=it] {Per bloccare il processo di costruzione in ogni momento, clicca qui. <br>La collezione sulla quale stai lavorando rimarrÃ  intatta.}
+
+_textstopbuild_ [l=it] {Arresta la creazione}
+
+_textbild3_ [l=it] {Se abbandoni questa pagina (senza aver annullato il processo di costruzione col pulsante "arresta costruzione") la collezione continuerÃ  ad essere costruita e verrÃ  installata dopo il completamento positivo dell'operazione.}
+
+_textbuildcancelled_ [l=it] {Costruzione annullata}
+
+_textbildcancel1_ [l=it] {Il processo di cotruzione della collezione Ãš stato annullato. Usa i pulsanti gialli sottostanti per fare delle modifiche alla collezione oppure riattiva il processo di costruzone.}
+
+_textbsupdate1_ [l=it] {Lo stato di costruzione viene aggiornato in 1 secondo}
+_textbsupdate2_ [l=it] {Lo stato di costruzione viene aggiornato in}
+_textseconds_ [l=it] {secondi}
+_textbildsuc_ [l=it] {La collezzione Ãš stata creata con successo.}
+
+_textviewbildsummary_ [l=it] {Puoi <a href="_httppagex_(bsummary)&c=_cgiargbc1dirname_" target=_top>vedere il sommario creato
+</a> per questa collezione per ulteriori dettagli.
+}
+
+_textfailmsg11_ [l=it] {La collezione non puÃ² essere creata perchÃš non contiene dati. Assicurati che almeno una delle directory o dei file 
+che hai specificato nella pagina <i>origine dati</i> esista e che sia del tipo (nel caso di una directory) o che contenga il tipo di file che 
+Greenstone puÃ² processare.
+}
+
+_textfailmsg21_ [l=it] {La collezione non puÃ² essere creata (import.pl fallito).}
+_textblcont_ [l=it] {Il log di costruzione contiene le seguenti informazioni:}
+
+_texttryagain_ [l=it] {Per favore<a href="_httppagecollector_" target=_top>riavvia il collector</a>
+e prova di nuovo.
+}
+
+_textfailmsg31_ [l=it] {La collezione non puÃ² essere creata (buildcol.pl fallito).}
+_textfailmsg41_ [l=it] {La collezione Ãš stata creata con successo ma non puÃ² essere installata.}
+_textfailmsg71_ [l=it] {Si Ãš verificato un errore imprevisto durante la creazione della collezione}
+_textretcoll_ [l=it] {Ritorna al Collector}
+
+_textdelperm_ [l=it] {Alcune o tutte le collezioni _cgiargbc1dirname_non possono essere cancellate. La cause possibili sono: <ul> <li> Greenstone non ha il permesso di cancellare la directory _gsdlhome_/collect/_cgiargbc1dirname_
+<br> Potrebbe essere necessario rimuovere manualmente questa directory per completare la cancellazione della collezione _gsdlhome_/collect/_cgiargbc1dirname_ da questo computer.</li> <li>Greenstone non puÃ² eseguire il programma _gsdlhome_/bin/script/delcol.pl. Assicurati che questo file sia leggibile ed eseguibile.</li></ul>}
+
+_textdelinv_ [l=it] {La collezione _cgiargbc1dirname_ Ãš protetta o invalida. La cancellazione Ãš stata annullata.}
+
+_textdelsuc_ [l=it] {La collezione _cgiargbc1dirname_ Ãš stata cancellata con successo.}
+
+_textclonefail_ [l=it] {La collezione _cgiargclonecol_ non puÃ² essere clonata.}
+
+_textcolerr_ [l=it] {Errore del Collector.}
+
+_texttmpfail_ [l=it] {Il collector non Ãš riuscito a leggere o scrivere su un file o directory temporanea.
+Cause possibili sono:
+<ul>
+<li> Greenstone non ha accesso in lettura/scrittura alla directory _gsdlhome_/tmp
+</ul>
+}
+
+_textmkcolfail_ [l=it] {Il collector ha fallito nel tentativo di creare la struttura della directory richiesta dalla nuova 
+collezione (mkcol.pl fallito). Possibili cause sono:
+<ul>
+<li> Greenstone non ha il permesso di scrittura nella directory _gsdlhome_/tmp
+     
+<li> errori nello script perl mkcol.pl 
+</ul>
+}
+
+_textnocontent_ [l=it] {Errore nel collector: non Ãš stato fornito alcun nome per la nuova collezione. Prova a riavviare il Collector dall'inizio.}
+
+_textrestart_ [l=it] {Riavvia il Collector}
+
+_textreloaderror_ [l=it] {Si Ãš verificato un errore durante la creazione della nuova collezione. CiÃ² puÃ² essere dovuto al fatto
+che Greenstone Ãš stato confuso dall'uso dei pulsanti "ricarica" e "indietro" del tuo browser  
+(cerca di evitare l'utilizzo di questi pulsanti mentre crei una collezione con il Collector). 
+Si consiglia di riavviare il Collector dall'inizio.
+}
+
+_textexptsuc_ [l=it] {La collezione _cgiargbc1dirname_ Ãš stata esportata con successo 
+nella direcoty _gsdlhome_/tmp/exported\__cgiargbc1dirname_ 
+}
+
+_textexptfail_ [l=it] {<p>L'esportazione della collezione _cgiargbc1dirname_ Ãš fallita.
+
+<p>Probabilmente questo dipende dal fatto che Greenstone Ãš stato installato senza le componenti
+necessarie a supportare la funzione "Esporta collezione".
+<ul>
+
+ <li>Se hai installato Greenstone da un CD-ROM, queste componenti non sono state installate a meno che 
+ non le abbia selezionate durante l'installazione "Personalizzata".
+ Puoi aggiungerle alla tua installazione ripetendo la procedura di installazione.
+
+ <li>Se hai installato Greenstone da una distribuzion web, devi scaricare ed installare i pacchetti addizionali 
+ necessari ad abilitare questa funzione. Consulta <a href="http://www.greenstone.org">http://www.greenstone.org</a> 
+ oppure spedisci un'e-mail a <a
+ href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>
+ per ulteriori informazioni.
+
+</ul>
+
+}
+
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=it] {Greenstone Ãš una suite di software adatti a gestire collezioni di biblioteche digitali ed a creare nuove collezioni. Fornisce un nuovo modo di organizzare informazioni e di pubblicarle su Internet o su CD-ROM.  Greenstone Ãš prodotto dal New Zealand Digital Library Project presso l'UniversitÃ  di Waikato, ed Ãš distribuito in cooperazione con l'UNESCO e lo Human Info NGO. E' un software open-source, disponibile da  <i>http://greenstone.org</i> sotto i termini della GNU General Public
+License.
+}
+
+_textgreenstone2_ [l=it] {Il sito della New Zealand Digital Library (<a
+href="http://nzdl.org">http://nzdl.org</a>) contiene numerose collezioni esempio, tutte create col software Greenstone, che sono disponibili pubblicamente per essere esaminate. Esemplificano diverse opzioni di ricerca e di consultazione ed includono collezioni in arabo, cinese, francese, maori e spagnolo, cosÃ¬ come in inglese. Vi sono anche alcune collezioni musicali. }
+
+_textplatformtitle_ [l=it] {piattaforma}
+_textgreenstone3_ [l=it] {Greenstone funziona sotto Windows, Unix e Mac OS X. La distribuzione include file binari pronti all'uso per ogni versione di Windows, per Linux e per Mac OSX. Contiene anche il codice sorgente completo del sistema che puÃ² essere compilato usando Microsoft C++ o gcc. Greenstone lavora con software associato che Ãš pure disponibile liberamente: il webserver Apache e PERL. L'interfaccia utente utilizza un browser web, tipicamente Netscape Navigator o Internet Explorer.}
+
+_textgreenstone4_ [l=it] {Molte collezioni di documenti sono distribuite su CD-ROM usando il software Greenstone. Ad esempio, la <i>Humanity Development Library</i>contiene 1.230 pubblicazioni che spaziano dalla contabilitÃ  alla bonifica delle acque. Funziona con minime configurazioni di computer, come quelli che di solito sono presenti nei paesi in via di sviluppo. Le informazioni possono essere consultate attraverso la ricerca, l'elenco per soggetti, per titolo, per organizzazione, con un elenco di guide e visualizzando casualmente le copertine del libro.}
+
+_textcustomisationtitle_ [l=it] {personalizzazione}
+_textgreenstone5_ [l=it] {Greenstone Ãš progettato in modo particolare per essere altamente estensibile e personalizzabile. Nuovi formati di documenti e di metadati vengono adottati scrivendo "plugins" (in Perl). Analogamente, nuove strutture di presentazione di metadati possono essere implementate scrivendo "classificatori". L'interfaccia utente puÃ² essere modifcata utilizzando "macro" scritte con un semplice linguaggio macro. Un protocollo Corba consente ad agenti (ad es. Java) di usare tutti i servizi associati alle collezioni di documenti. Infine, il codice sorgente, in C++ e Perl, Ãš disponibile ed accessibile per modifiche.}
+
+_textdocumentationtitle_ [l=it] {documentazione}
+_textdocuments_ [l=it] {E' disponibile una documentazione estesa per il software Greenstone.}
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=it] {mailing list }
+_textmailinglist_ [l=it] {Vi Ãš una mailing list orientata primariamente alle discussioni sul software Greenstone digital library. Gli utenti attivi di Greenstone dovrebbero valutare di aggregarsi alla lista e di contribuire alle discussioni. Per iscriversi, vai a <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+
+Per spedire un messaggio alla lista, indirizzalo a  <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>.}
+
+_textbugstitle_ [l=it] {errori di programma}
+_textreport_ [l=it] {Vogliamo garantire che questo software funziona bene per te. Invia ogni errore di programma a <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>}
+
+_textgs3title_ [l=it] {nelle opere}
+_textgs3_ [l=it] {Greenstone 3 Ãš un progetto completamente riformulato ed implementato che mantiene tutti i vantaggi di Greenstone 2 (la versione corrente) - ad esempio, Ãš multilingua, multipiattaforma ed ampiamente configurabile. Incorpora tutte le caratteristiche del sistema esistente ed Ãš retrocompatibile, ossia puÃ² costruire e gestire collezioni esistente senza modifiche. Scritto in Java, Ãš strutturato come una rete di moduli indipendenti che comunicano usando XML: cosÃ¬ esso funziona in modo distribuito e puÃ² essere dislocato su diversi server se necessario. Questa struttura modulare aumenta la flessibilitÃ  e l'estensibilitÃ  di Greenstone. La nuova versione dovrebbe essere disponibile per uso sperimentale entro il 23 dicembre 2003. Una descrizione di base del sistema Ãš contenuta in "The design of Greenstone 3: An agent based 
+dynamic digital library" (scarica il PDF 
+<a href="http://www.greenstone.org/manuals/gs3design.pdf"> </a>).}
+
+_textcreditstitle_ [l=it] {credits}
+
+_textwhoswho_ [l=it] {Il software Greenstone Ãš un'opera collaborativa tra numerose persone. Rodger McNab e Stefan Boddie sono i principali architetti ed implementatori. Contributi sono stati dati da David Bainbridge, George
+Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John
+McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd
+Reed, Bill Rogers, John Thompson e Stuart Yeates. Altri membri del New Zealand
+Digital Library project hanno fornito consigli ed ispirazione per il progetto del sistema: Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka
+Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols e Lloyd Smith. Desideriamo anche manifestare la nostra riconoscenza a tutti coloro i quali hanno contribuito ai pacchetti sotto licenza GNU inclusi in questa distribuzione: MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE e XLHTML.
+}
+
+_textaboutgslong_ [l=it] {informazioni sul software greenstone}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=it] {Lista degli utenti correnti}
+_textuser_ [l=it] {utente
+}
+_textas_ [l=it] {stato dell'account}
+_textgroups_ [l=it] {gruppi}
+_textcomment_ [l=it] {commento}
+_textadduser_ [l=it] {aggiungi un nuovo utente}
+_textedituser_ [l=it] {modifica}
+_textdeleteuser_ [l=it] {cancella}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=it] {Modifica le informazioni utente}
+_textadduser_ [l=it] {Aggiungi un nuovo utente}
+
+_textaboutusername_ [l=it] {Gli username devono essere lunghi tra 2 e 30 caratteri. Essi possono contenere caratteri alfanumerici,  '.', e '_'.}
+
+_textaboutpassword_ [l=it] {La password deve essere lunga fra 3 e 128 caratteri. Essi possono contenere qualsiasi normale carattere ASCII stampabile.}
+
+_textoldpass_ [l=it] {Se questo campo Ãš vuoto la vecchia password sarÃ  mantenuta.}
+_textenabled_ [l=it] {abilitato}
+_textdisabled_ [l=it] {disabilitato}
+
+_textaboutgroups_ [l=it] {Gruppi Ãš una lista separata da virgola, non mettere spazi dopo la virgola}
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=it] {Cancella un utente}
+_textremwarn_ [l=it] {Vuoi davvero rimuovere definitivamente l'utente <b>_cgiargumun_</b>?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=it] {Cambia la password}
+_textoldpw_ [l=it] {vecchia password}
+_textnewpw_ [l=it] {nuova password}
+_textretype_ [l=it] {riscrivi la nuova password}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=it] {La tua password Ãš stata modificata con successo.}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=it] {Lo username Ãš invalido:}
+_textinvalidpassword_ [l=it] {La password non Ãš valida.}
+_textemptypassword_ [l=it] {Inserisci, per favore, una password per questo utente.}
+_textuserexists_ [l=it] {Questo utente esiste giÃ , inserisci un altro username.}
+
+_textusernameempty_ [l=it] {Inserisci il tuo username.}
+_textpasswordempty_ [l=it] {Devi inserire la tua vecchia password.}
+_textnewpass1empty_ [l=it] {Inserisci la tua nuova password e quindi riscrivila.}
+_textnewpassmismatch_ [l=it] {Le due versioni della tua nuova pasword non coincidono.}
+_textnewinvalidpassword_ [l=it] {Hai inserito una passvord non valida}
+_textfailed_ [l=it] {Il tuo username o password sono errati.}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=it] {Numero di versione Greenstone}
+_textframebrowser_ [l=it] {Devi avere un browser con frame abilitato per vedere questo.}
+_textusermanage_ [l=it] {Gestione utente}
+_textlistusers_ [l=it] {elenco utenti}
+_textaddusers_ [l=it] {aggiungi un nuovo utente}
+_textchangepasswd_ [l=it] {cambia password}
+_textinfo_ [l=it] {Informazioni tecniche}
+_textgeneral_ [l=it] {generale}
+_textarguments_ [l=it] {argomenti}
+_textactions_ [l=it] {azioni}
+_textbrowsers_ [l=it] {browsers}
+_textprotocols_ [l=it] {protocolli}
+_textconfigfiles_ [l=it] {Files di configurazione}
+_textlogs_ [l=it] {Logs}
+_textusagelog_ [l=it] {log di utilizzo}
+_textinitlog_ [l=it] {init log}
+_texterrorlog_ [l=it] {errore di log}
+_textadminhome_ [l=it] {admin home}
+_textreturnhome_ [l=it] {Home di Greenstone}
+_titlewelcome_ [l=it] {Amministrazione}
+_textmaas_ [l=it] {I servizi di manutenzione e amministrazione disponibili includono:}
+_textvol_ [l=it] {vedi logs on-line}
+_textcmuc_ [l=it] {crea, mantieni e aggiorna le collezioni}
+_textati_ [l=it] {accedi a informazioni tecniche come argomenti CGI}
+
+_texttsaa_ [l=it] {Questi servizi sono accessibili usando la barra di navigazione laterale sul margine sinistro della pagina.}
+
+_textcolstat_ [l=it] {Stato della collezione}
+
+_textcwoa_ [l=it] {Le collezioni appariranno come "running" solo se i loro file build.cfg esistono, sono leggibili, contengono un campo builddate valido (ad es. < 0), e sono nella directory dell'indice della collezione (ad es. NON la directory di creazione).}
+
+_textcafi_ [l=it] {clicca <i>abbrev.</i> per informazioni su una collezione}
+_textcctv_ [l=it] {clicca <i>collezione</i> per vedere una collezione}
+_textsubc_ [l=it] {Inserisci modifiche}
+_texteom_ [l=it] {Errore in apertura di main.cfg}
+_textftum_ [l=it] {Aggiornamento di main.cfg fallito}
+_textmus_ [l=it] {main.cfg aggiornato con successo}
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=it] {Visualizza il sommario della collezione _collectionname_ }
+_textflog_ [l=it] {Accesso fallito alla collezione _collectionname_}
+
+
+############################################################################
+#
+# This stuff is only used by the usability (I'd like to Complain) stuff
+#
+############################################################################
+package Global
+
+_greenstoneusabilitytext_ [l=it] {UsabilitÃ  di Greenstone}
+
+_textwhy_ [l=it] {<p>L'invio del rapporto Ãš un modo per segnalare che hai trovato difficile o deludente la pagina web che stavi visualizzando.}
+_textextraforform_ [l=it] {Non devi riempire il modulo -- ogni informazione sarÃ  di aiuto.}
+_textprivacybasic_ [l=it] {<p>Il rapporto conterrÃ  solamente informazioni sulle pagine web di Greenstone che stavi visualizzando, nonchÃ© sulla tecnologia che stavi utilizzando per vederle (oltre ad ogni altra informazione facoltativa che fornisci).}
+_textstillsend_ [l=it] {Vuoi inviare ancora questo rapporto?}
+
+_texterror_ [l=it] {errore}
+_textyes_ [l=it] {SÃ¬}
+_textno_ [l=it] {No}
+_textclosewindow_ [l=it] {Chiudi la finestra}
+_textabout_ [l=it] {Informazioni}
+_textprivacy_ [l=it] {Riservatezza}
+_textsend_ [l=it] {Spedisci}
+_textdontsend_ [l=it] {Non spedire}
+_textoptionally_ [l=it] {Facoltativamente}
+
+_textunderdev_ [l=it] {L'anteprima dei dettagli sarÃ  disponibile nella versione finale.}
+
+_textviewdetails_ [l=it] {Visualizza i dettagli del rapporto}
+_textmoredetails_ [l=it] {Maggiori dettagli}
+_texttrackreport_ [l=it] {Tieniti informato su questo rapporto}
+_textcharacterise_ [l=it] {Di quale tipo di problema si tratta}
+_textseverity_ [l=it] {Quanto Ãš grave il problema}
+ 
+_textbadrender_ [l=it] {La pagina appare strana}
+_textcontenterror_ [l=it] {Errore di contenuto}
+_textstrangebehaviour_ [l=it] {Comportamento strano}
+_textunexpected_ [l=it] {E' accaduto qualcosa di inaspettato}
+_textfunctionality_ [l=it] {Difficile da usare}
+_textother_ [l=it] {Altro}
+
+_textcritical_ [l=it] {Critico}
+_textmajor_ [l=it] {Serio}
+_textmedium_ [l=it] {Medio}
+_textminor_ [l=it] {Minore}
+_texttrivial_ [l=it] {Insignificante}
+
+_textwhatdoing_ [l=it] {Cosa stavi cercando di fare?}
+_textwhatexpected_ [l=it] {Cosa ti aspettavi che accadesse?}
+_textwhathappened_ [l=it] {Cosa Ãš accaduto effettivamente?}
+
+_cannotfindcgierror_ [l=it] {<h2>Spiacente!</h2>Non Ãš possibile localizzare il server dei programmi per il pulsante "Segnalazioni".}
+
+_textusabbanner_ [l=it] {il banner stile koru di Greenstone}
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+# -- Missing translation: _textgti_
+
+# -- Missing translation: _textgtierror_
+
+# -- Missing translation: _textgtihome_
+
+# -- Missing translation: _textgtiselecttlc_
+
+# -- Missing translation: _textgtiselecttfk_
+
+# -- Missing translation: _textgticoredm_
+# -- Missing translation: _textgtiauxdm_
+# -- Missing translation: _textgtiglidict_
+# -- Missing translation: _textgtiperlmodules_
+# -- Missing translation: _textgtigreenorg_
+
+# -- Missing translation: _textgtienter_
+
+# -- Missing translation: _textgticorrectexistingtranslations_
+# -- Missing translation: _textgtidownloadtargetfile_
+# -- Missing translation: _textgtiviewtargetfileinaction_
+
+# -- Missing translation: _textgtinumchunksmatchingquery_
+
+# -- Missing translation: _textgtinumchunkstranslated_
+# -- Missing translation: _textgtinumchunksrequiringupdating_
+# -- Missing translation: _textgtinumchunksrequiringtranslation_
+
+# -- Missing translation: _textgtienterquery_
+# -- Missing translation: _textgtifind_
+
+# -- Missing translation: _textgtitranslatingchunk_
+# -- Missing translation: _textgtiupdatingchunk_
+# -- Missing translation: _textgtisubmit_
+
+# -- Missing translation: _textgtilastupdated_
+
+# -- Missing translation: _textgtitranslationfilecomplete_
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=it] {Interfaccia bibliotecario Greenstone}
+_textglihelp_ [l=it] {L'interfaccia bibliotecario (GLI) ti dÃ  accesso alle funzionalitÃ  di Greenstone attraverso un'interfaccia facile da usare ed immediata. Ti permette di raccogliere serie di documenti, importare o assegnare metadati e di crearli all'interno di una collezione Greenstone.
+  <p>
+Nota che la GLI funziona congiuntamente a Greenstone, ammeso che sia installata in una sottodirectory della tua installazione Greenstone. Questo avviene se hai scaricato una delle distribuzioni Greenstone, oppure  installato da un CD-ROM Greenstone.
+
+ <h4>Funzionamento della GLI sotto Windows</h4>
+
+Lancia l'interfaccia bibliotecario sotto Windows selezionando <i>Greenstone Digital Library</i> dalla sezione <i>Programmi</i> del menu <i>Start</i> e scegliendo <i>Interfaccia bibliotecario</i>.
+
+ <h4>Funzionamento della GLI sotto Unix</h4>
+
+Per attivare la GLI sotto Unix, vai alla directory <i>gli</i> nella tua installazione Greenstone, quindi esegui lo script <i>gli.sh</i>.
+
+ <h4>Usare GLI sotto Mac OS X</h4>
+
+Nel Finder, visualizza <i>Applicazioni</i> quindi <i>Greenstone</i> (se hai installato Greenstone nella localizzazione di default), poi lancia l'applicazione <i>GLI</i>.}
Index: /gsdl/stable/macros/japanese.dm
===================================================================
--- /gsdl/stable/macros/japanese.dm	(revision 20131)
+++ /gsdl/stable/macros/japanese.dm	(revision 20131)
@@ -0,0 +1,735 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Japanese Language text and icon macros 
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=ja] {å®æåè¡}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=ja] {åæåç
+§}
+_textdate_ [l=ja] {çºè¡æ¥}
+_textnumpages_ [l=ja] {ææ°}
+
+_textsignin_ [l=ja] {ãµã€ã³ã€ã³}
+
+_textdefaultcontent_ [l=ja] {èŠæ±ãããããŒãžãèŠã€ããããªãã£ããã°ãªãŒã³ã¹ããŒã³é»å­å³æžé€šãžæ»ãæã¯ãã©ãŠã¶ã®âBackâãã¿ã³ããŸãã¯äžã®âããŒã âãã¿ã³ãã¯ãªãã¯ããŠäžããã}
+
+_textdefaulttitle_ [l=ja] {GSDL ãšã©ãŒ}
+
+
+
+
+
+_collectionextra_ [l=ja] {ãã®ã³ã¬ã¯ã·ã§ã³ã«ã¯ã_about:numdocs_ããã­ã¥ã¡ã³ããããŸãã
+ããã¯ã_about:builddate_ãæ¥éåã«äœããã}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=ja] {<p>ãã®åéã«ã¯ _numdocs_ _If_("_numdocs_" eq "1",ãã­ã¥ã¡ã³ã,ãã­ã¥ã¡ã³ã),  _numbytes_ããã€ãã®åèšããããŸãã
+<p><a href="_httppagex_(bsummary)">ãããž</a>ã¯ãªãã¯ãããšããã®åéã®æŠèŠãè¡šç€ºããããšãã§ããŸãã
+}
+
+_textdescrcollection_ [l=ja] {}
+_textdescrabout_ [l=ja] {ããŒãžã«é¢ããŠ}
+_textdescrhome_ [l=ja] {ããŒã ããŒãž}
+_textdescrhelp_ [l=ja] {ãã«ãããŒãž}
+_textdescrpref_ [l=ja] {ããªãã¡ã¬ã³ã¹ããŒãž}
+_textdescrgreenstone_ [l=ja] {ã°ãªãŒã³ã¹ããŒã³é»å­å³æžé€šãœãããŠãšã¢}
+_textdescrusab_ [l=ja] {äœãäœ¿ãé£ãã§ããïŒ}
+
+
+# Metadata names and navigation bar labels
+
+
+_labelSearch_ [l=ja] {æ€çŽ¢}
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_labelTitle_ [l=ja] {ã¿ã€ãã«ïŒèŸæžé ïŒ}
+
+_labelCreator_ [l=ja] {äœå®¶ïŒèŸæžé ïŒ}
+
+
+
+
+
+
+_textContributor_ [l=ja] {è²¢ç®è
+}  
+
+
+_labelDate_ [l=ja] {æ¥ä»}
+
+
+
+
+
+
+
+_labelSource_ [l=ja] {ãã¡ã€ã«å}
+
+_labelLanguage_ [l=ja] {èšèª}
+
+
+
+
+
+
+
+# DLS metadata set
+
+
+
+_labelKeyword_ [l=ja] {ã­ãŒã¯ãŒã}
+
+
+
+# Miscellaneous Greenstone metadata
+
+_labelPhrase_ [l=ja] {ãã¬ãŒãº}
+
+
+
+
+
+
+
+
+
+_labelAcronym_ [l=ja] {é ­å­èª}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+
+
+_textdescrSearch_ [l=ja] {ç¹å®ã®ã­ãŒã¯ãŒãã®æ€çŽ¢}
+
+
+_textdescrSource_ [l=ja] {å
+ã®ãã¡ã€ã«åã«ãŠãã©ãŠãºãã}
+_textdescrTo_ [l=ja] {Toããã£ãŒã«ãã«ãŠãã©ãŠãºãã}
+_textdescrFrom_ [l=ja] {Fromããã£ãŒã«ãã«ãŠãã£ãšãã©ãŠãºãã}
+
+_textdescrAcronym_ [l=ja] {é ­å­èªããã©ãŠãºãã}
+_textdescrPhrase_ [l=ja] {ãã¬ãŒãºããã©ãŠãºãã}
+_textdescrHowto_ [l=ja] {HowãToãã«ããŽãªãŒã«ãŠãã£ãšãã©ãŠãºãã}
+_textdescrBrowse_ [l=ja] {ãã©ãŠãº}
+_texticontext_ [l=ja] {ãã­ã¥ã¡ã³ããèŠã}
+_texticonclosedbook_ [l=ja] {ãã­ã¥ã¡ã³ããéã}
+_texticonnext_ [l=ja] {æ¬¡ã®ã»ã¯ã·ã§ã³ãž}
+_texticonprev_ [l=ja] {åã»ã¯ã·ã§ã³ãž}
+
+
+
+_texticonmidi_ [l=ja] {MIDIããã­ã¥ã¡ã³ããèŠã}
+_texticonmsword_ [l=ja] {MicrosoftãWordãã­ã¥ã¡ã³ããèŠã}
+_texticonmp3_ [l=ja] {MP3ããã­ã¥ã¡ã³ããèŠã}
+_texticonpdf_ [l=ja] {PDFããã­ã¥ã¡ã³ããèŠã}
+_texticonps_ [l=ja] {PostScriptããã­ã¥ã¡ã³ããèŠã}
+_texticonppt_ [l=ja] {PowerPointããã­ã¥ã¡ã³ããèŠã}
+_texticonrtf_ [l=ja] {RTFããã­ã¥ã¡ã³ããèŠã}
+_texticonxls_ [l=ja] {MicrosoftãExcelããã­ã¥ã¡ã³ããèŠã}
+
+_page_ [l=ja] {ããŒãž}
+_pages_ [l=ja] {ããŒãž}
+_of_ [l=ja] {ã®}
+_vol_ [l=ja] {Vol.}
+_num_ [l=ja] {ãã³ããŒ}
+
+_textmonth00_ [l=ja] {}
+_textmonth01_ [l=ja] {äžæ}
+_textmonth02_ [l=ja] {äºæ}
+_textmonth03_ [l=ja] {äžæ}
+_textmonth04_ [l=ja] {åæ}
+_textmonth05_ [l=ja] {äºæ}
+_textmonth06_ [l=ja] {å
+­æ}
+_textmonth07_ [l=ja] {äžæ}
+_textmonth08_ [l=ja] {å
+«æ}
+_textmonth09_ [l=ja] {ä¹æ}
+_textmonth10_ [l=ja] {åæ}
+_textmonth11_ [l=ja] {åäžæ}
+_textmonth12_ [l=ja] {åäºæ}
+
+_textdocument_ [l=ja] {ãã­ã¥ã¡ã³ã}
+_textsection_ [l=ja] {ã»ã¯ã·ã§ã³}
+_textparagraph_ [l=ja] {ãã©ã°ã©ã}
+
+_magazines_ [l=ja] {éèª}
+
+_nzdlpagefooter_ [l=ja] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}
+
+_linktextHOME_ [l=ja] {ããŒã }
+_linktextHELP_ [l=ja] {ãã«ã}
+_linktextPREFERENCES_ [l=ja] {ããªãã¡ã¬ã³ã¹}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+
+
+
+package collector
+
+_textcollector_ [l=ja] {åéè
+}  
+
+
+package depositor
+
+
+
+
+package gti
+
+
+
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=ja] {ãã®ã³ã¬ã¯ã·ã§ã³ã«ã€ããŠ}
+
+_textsubcols1_ [l=ja] {<p>ãã®å®å
+šãªã³ã¬ã¯ã·ã§ã³ã¯éšåã³ã¬ã¯ã·ã§ã³ _1_ ãå«ã¿ãŸãããããã¯æ¬¡ã«å©çšå¯èœã§ãïŒ  <blockquote>}
+
+_textsubcols2_ [l=ja] {</blockquote>
+ããªãã¡ã¬ã³ã¹ããŒãžã§çŸåšããªããä»æ§ããŠãããµãã³ã¬ã¯ã·ã§ã³ãã©ããªã®ããæ žã«ããããšãã§ããŸãã}
+
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=ja] {ãã®ã©ã€ãã©ãªã®ã»ã¯ã·ã§ã³ãéãã}
+_texticonclosedbookshelf_ [l=ja] {ãã®ã»ã¯ã·ã§ã³ãéããã³ã³ãã³ããèŠã}
+_texticonopenbook_ [l=ja] {ãã®æ¬ãéãã}
+_texticonclosedfolder_ [l=ja] {ãã©ã«ããŒãéããã³ã³ãã³ããèŠã}
+_texticonclosedfolder2_ [l=ja] {ãµãã»ã¯ã·ã§ã³ãéã}
+_texticonopenfolder_ [l=ja] {ãã©ã«ããéãã}
+_texticonopenfolder2_ [l=ja] {ãµãã»ã¯ã·ã§ã³ãéããïŒ}
+_texticonsmalltext_ [l=ja] {ãã®ã»ã¯ã·ã§ã³ã®ãã­ã¹ããèŠãïŒ}
+_texticonsmalltext2_ [l=ja] {ãã­ã¹ããèŠãïŒ}
+_texticonpointer_ [l=ja] {çŸåšã®ã»ã¯ã·ã§ã³}
+_texticondetach_ [l=ja] {ãã®ããŒãžãæ°ãããŠã£ã³ããŠã§éã}
+_texticonhighlight_ [l=ja] {æ€çŽ¢èªããã€ã©ã€ã}
+_texticonnohighlight_ [l=ja] {æ€çŽ¢èªããã€ã©ã€ããããªã}
+_texticoncontracttoc_ [l=ja] {ã³ã³ãã³ãã®ããŒãã«ãçµãããã}
+_texticonexpandtoc_ [l=ja] {ã³ã³ãã³ãã®ããŒãã«ãæ¡åŒµãã}
+_texticonexpandtext_ [l=ja] {ãã¹ãŠã®ãã­ã¹ããè¡šç€ºãã}
+_texticoncontracttext_ [l=ja] {çŸåšéžæããã»ã¯ã·ã§ã³ã®ãã­ã¹ãã ããèŠã}
+_texticonwarning_ [l=ja] {<b>è­Šå: </b>}
+_texticoncont_ [l=ja] {ç¶ããŸããïŒ}
+
+_textltwarning_ [l=ja] {<div class="buttons">_imagecont_</div>
+_iconwarning_Expanding ãã®ãã­ã¹ãã¯ãããªãã®ãã©ãŠã¶ã§è¡šç€ºãããããã«ã¯ãéåžžã«å€§ããªããŒã¿ãšãªã£ãŠããŸããŸãã
+}
+
+_textgoto_ [l=ja] {ããŒãžã«è¡ã}
+_textintro_ [l=ja] {<i>(introductory text)</i>}
+
+_textCONTINUE_ [l=ja] {ç¶ããŸããïŒ?}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=ja] {_If_(_thislast_,results _thisfirst_ - _thislast_ for query: _cgiargq_,No matches for query: _cgiargq_)}
+_textnoquerytitle_ [l=ja] {æ€çŽ¢ããŒãž}
+
+
+
+
+
+
+
+_texticonsearchhistorybar_ [l=ja] {æ€çŽ¢å±¥æ­Ž}
+
+
+
+#alt text for query buttons
+_textusequery_ [l=ja] {ãã®åãåãããäœ¿ã}
+_textfreqmsg1_ [l=ja] {Word count: }
+_textpostprocess_ [l=ja] {_If_(_quotedquery_,<br><i>post-processed to find _quotedquery_</i>
+)}
+
+
+
+
+_textmorethan_ [l=ja] {More than }
+_textapprox_ [l=ja] {About }
+_textnodocs_ [l=ja] {åãåããã«åèŽããæç« ããããŸãã}
+_text1doc_ [l=ja] {1 document matched the query.}
+_textlotsdocs_ [l=ja] {documents matched the query.}
+_textmatches_ [l=ja] {åèŽæ°}
+_textbeginsearch_ [l=ja] {Begin Search}
+_textrunquery_ [l=ja] {åãåããå®è¡}
+_textclearform_ [l=ja] {Clear Form}
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=ja] {èªãŸãã¯ãã¬ãŒãº}
+_textinfield_ [l=ja] {... in field}
+_textfoldstem_ [l=ja] {(fold, stem)}
+
+_textadvquery_ [l=ja] {Or enter a query directly:}
+
+
+_textand_ [l=ja] {and}
+_textor_ [l=ja] {or}
+_textandnot_ [l=ja] {and not}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textdatesearch_ [l=ja] {This collection can be searched for documents within a date range, or documents that contain a particular date. This is an optional feature of the search.}
+_textstartdate_ [l=ja] {æ¥ä»ïŒæéã®å Žåã¯éå§å¹Žææ¥ïŒïŒ}
+_textenddate_ [l=ja] {End date:}
+_textbc_ [l=ja] {B.C.E.}
+_textad_ [l=ja] {C.E.}
+_textexplaineras_ [l=ja] {C.E. and B.C.E are alternatives for A.D. and B.C. respectively.  These terms are considered to be culture indiscriminate, and stand for "Common Era" and "Before the Common Era"}
+
+_textstemon_ [l=ja] {(èªæ«åœ¢åŒãç¡èŠããŠããŸã)}
+
+_textsearchhistory_ [l=ja] {æ€çŽ¢å±¥æ­Ž}
+
+#text macros for search history
+_textnohistory_ [l=ja] {æ€çŽ¢å±¥æ­ŽããããŸãã}
+_texthresult_ [l=ja] {result}
+_texthresults_ [l=ja] {results}
+_texthallwords_ [l=ja] {all words}
+_texthsomewords_ [l=ja] {some words}
+_texthboolean_ [l=ja] {boolean}
+_texthranked_ [l=ja] {ranked}
+_texthcaseon_ [l=ja] {case must match}
+_texthcaseoff_ [l=ja] {casefolded}
+_texthstemon_ [l=ja] {stemmed}
+_texthstemoff_ [l=ja] {unstemmed}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=ja] {ããªãã¡ã¬ã³ã¹ã®èš­å®ã¯ä»¥äžã®éãã§ãããã©ãŠã¶ã®ããã¯ãã¿ã³ã¯æŒããªãã§ãã ããã}
+_textsetprefs_ [l=ja] {set preferences}
+_textsearchprefs_ [l=ja] {æ€çŽ¢ããªãã¡ã¬ã³ã¹}
+_textcollectionprefs_ [l=ja] {ã³ã¬ã¯ã·ã§ã³ããªãã¡ã¬ã³ã¹}
+_textpresentationprefs_ [l=ja] {Presentation ããªãã¡ã¬ã³ã¹}
+_textpreferences_ [l=ja] {ããªãã¡ã¬ã³ã¹}
+_textcasediffs_ [l=ja] {Case differences:}
+_textignorecase_ [l=ja] {å€§æå­ã»å°æå­ãåºå¥ããªã}
+_textmatchcase_ [l=ja] {å€§æå­ã»å°æå­ãåºå¥ãã}
+_textwordends_ [l=ja] {Word endings:}
+_textstem_ [l=ja] {ignore word endings}
+_textnostem_ [l=ja] {å®å
+šèªäžèŽ}
+
+
+
+
+_textprefop_ [l=ja] {Return up to _maxdocoption_ hits with _hitsperpageoption_ hits per page.}
+_textextlink_ [l=ja] {Access to external Web pages:}
+_textintlink_ [l=ja] {Source documents retrieved from:}
+_textlanguage_ [l=ja] {ã€ã³ã¿ãŒãã§ãŒã¹èšèªïŒ}
+_textencoding_ [l=ja] {æå­ã³ãŒãïŒ}
+_textformat_ [l=ja] {ã€ã³ã¿ãŒãã§ãŒã¹ format:}
+_textall_ [l=ja] {all}
+_textquerymode_ [l=ja] {åãåããã¢ãŒãïŒ}
+_textsimplemode_ [l=ja] {simple query mode}
+_textadvancedmode_ [l=ja] {advancedåãåããã¢ãŒã (æŒç®å­ !, &, |,ãäœ¿ããŸã)}
+_textlinkinterm_ [l=ja] {through intermediate page}
+_textlinkdirect_ [l=ja] {go directly there}
+_textdigitlib_ [l=ja] {é»å­å³æžé€š}
+_textweb_ [l=ja] {the web}
+_textgraphical_ [l=ja] {ã°ã©ãã£ãã¯}
+_texttextual_ [l=ja] {Textual}
+_textcollectionoption_ [l=ja] {<p>
+ãµãã³ã¬ã¯ã·ã§ã³ãå«ãã:
+<br>}
+
+
+
+
+
+
+
+_textrelateddocdisplay_ [l=ja] {é¢é£ããæç« ãè¡šç€ºãã}
+_textsearchhistory_ [l=ja] {æ€çŽ¢å±¥æ­ŽïŒ}
+_textnohistory_ [l=ja] {æ€çŽ¢å±¥æ­Žã¯ãããŸãã}
+_texthistorydisplay_ [l=ja] {display _historynumrecords_ search history records}
+_textnohistorydisplay_ [l=ja] {æ€çŽ¢å±¥æ­ŽãèŠããªã}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=ja] {äžŠã¹æ¿ãã®æ¹æ³}
+_textalsoshowing_ [l=ja] {also showing}
+_textwith_ [l=ja] {æå€§ã§ã}
+_textdocsperpage_ [l=ja] {ãã­ã¥ã¡ã³ãïŒïŒããŒãžæ¯ïŒ}
+
+_textfilterby_ [l=ja] {å«ãã§ãããã­ã¥ã¡ã³ããååŸ}
+_textall_ [l=ja] {ãã¹ãŠ}
+_textany_ [l=ja] {any}
+_textwords_ [l=ja] {èªæ°}
+_textleaveblank_ [l=ja] {ãã¹ãŠã®ãã­ã¥ã¡ã³ããååŸããããã«ã¯ããã®ããã¯ã¹ãç©ºã®ãŸãŸã«ããŠãã ãã}
+
+_browsebuttontext_ [l=ja] {"äžŠã¹æ¿ã"}
+
+_nodata_ [l=ja] {<i>ããŒã¿ããããŸãã</i>}
+_docs_ [l=ja] {ãã­ã¥ã¡ã³ã}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=ja] {Help}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+
+
+
+
+
+
+
+
+
+
+
+_textreadingdocs_ [l=ja] {ã©ã®ããã«æç« ãèª­ãã}
+
+_texthelpreadingdocs_ [l=ja] {<p>åã
+ã®ææžã®ã¿ã€ãã«ãšèè
+ã¯ãããŒãžã®äžéšå·Šã«ç€ºãããã
+ãããã®æšªã«ããæ°å­ã¯ãçŸåšã®ããŒãžã§ãç®±ã¯ãæ°ããéžæã§ããããŒãžããããŠãå·Šå³ã®ç¢å°ã¯åã®ããŒãžãåŸãã®ããŒãžãç€ºãã
+
+<p>ç»é¢äžéšã¯ãçŸåšã®ã»ã¯ã·ã§ã³ã®ãã­ã¹ãã§ããã
+ãã­ã¹ããæåŸãŸã§èª­ããšããã®äžã«åã®ããŒãžãåŸãã®ããŒãžãžã®ç¢å°ãããã
+
+<p>ã¿ã€ãã«ãšèè
+ã®äžã«ã¯ïŒã€ã®ãã¿ã³ãããã
+<i>expand text</i>ãæŒããšãçŸåšã®æç« ã®ãã­ã¹ãå
+šäœãæ¡å€§ããã
+ãããæç« ãå€§ãããªãããã®åŠçã«ã¯é·ãæéãšå€ãã®ã¡ã¢ãªãå¿
+èŠãšãªãã®ã§æ³šæããŠãã ããã
+<i>detach</i> ãæŒããšããã®æç« ã®ããã«æ°ãããã©ãŠã¶ãŠã£ã³ããŠãéããŸãã
+ããã¯ãæç« åå£«ãæ¯ã¹ãæã«äŸ¿å©ã§ãããã
+<i>no highlighting</i>ã¯ãæ€çŽ¢èªã®ãã€ã©ã€ãããããããšãã§ããŸãã
+}
+
+# help about the icons
+
+
+
+
+
+_texthelpdetachpage_ [l=ja] {æ°ãããŠã£ã³ããŠã§ãã®ããŒãžãéããŠãã ããã}  
+
+
+
+
+_texthelpsearchingtitle_ [l=ja] {ããã«ãç¹å®ã®èªãæ€çŽ¢ããã}
+
+_texthelpsearching_ [l=ja] {<p>
+æ€çŽ¢ããŒãžãããæ¬¡ã®ãããªã¹ãããã§è³ªåããã :<p>
+<ol><li>ã©ã®ãããªã¢ã€ãã ãæãããæå®ããã
+   <li>ãã¹ãŠã®èªãå«ãã®ããããã€ãã®èªã ãã§ããã®ããæ±ºããã
+   <li>æ€çŽ¢ãããèªãå
+¥åããã
+   <li><i>Begin Search</i>ãã¿ã³ãã¯ãªãã¯ããã
+</ol>
+
+<p>
+è³ªåããããšãè©²åœãã20ã®ææžã®ã¿ã€ãã«ãè¡šç€ºãããã§ãããã
+ãã®äžçªäžã«ã¯ãæ¬¡ã®20ã®ææžãååŸãããã¿ã³ããããŸãã
+æ¬¡ã®ç»é¢ã§ãåæ§ã«ã3çªç®ã®20ææžããŸãã¯ãæåã®20ææžã«æ»ããã¿ã³ããããŸãã
+ã©ã®ææžã®ãã¿ã³ãããã®æšªã«ããå°ããªãã¿ã³ãæŒããŠãããã®æç« ãã¿ãããšãã§ããŸãã
+
+<p>
+æ€çŽ¢ã®æå€§æ°ã¯100ã§äž­æ­ãããŸãã
+ãã®æ°å­ãå€ããããã«ã¯ã
+æåã®ããŒãžã®<i>preferences</i>ãã¿ã³ãæŒããŠãã ããã
+}
+
+_texthelpquerytermstitle_ [l=ja] {æ€çŽ¢èª}
+_texthelpqueryterms_ [l=ja] {<p>
+æ€çŽ¢ããã¯ã¹ã®å
+¥åãã¹ãŠã¯ãæ€çŽ¢èªãšåŒã°ããèªã®ãªã¹ããšè§£éãããŸãã
+ããããã®æ€çŽ¢èªã¯è±å­ãšæ°å­ã§ãããç©ºçœã§åºåãããã
+å¥èª­ç¹ã¯ãç©ºçœãšåæ§ã«æ€çŽ¢èªãåºåããšèŠãªãããç¡èŠãããã
+ãã®ãããå¥èª­ç¹ãå«ãèªãæ€çŽ¢ããããšã¯ã§ããªãã
+
+<p>åãåããã®äŸ<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>ã¯æ¬¡ãšåæ§ã«èŠãªããã<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}
+
+
+
+
+
+_texthelpquerytypetitle_ [l=ja] {åãåããã®ã¿ã€ã}
+_texthelpquerytype_ [l=ja] {<p>åãåããã«ã¯ïŒã€ã®ã¿ã€ããããã
+
+<ul>
+  <li>æ€çŽ¢èª<b>ãã¹ãŠãšã®</b>äžèŽïŒæ€çŽ¢èªã®ãã¹ãŠãå«ãæç« ïŒæã«ã¯ç« ãã¿ã€ãã«ïŒãæ¢ããæ¡ä»¶ã«åèŽããæç« ã¯èŸæžé ã«è¡šç€ºãããã<p>
+
+  <li>æ€çŽ¢èªã®<b>äžéšãšã®</b>äžèŽïŒæ€çŽ¢èªã®äžéšãšã®äžèŽã«ããæ€çŽ¢ããããçµæã¯æ€çŽ¢èªãšäžèŽåºŠãé«ããã®ããé ã«è¡šç€ºãããã
+      <p><ul>
+        <li>æ°å€ãã®æ€çŽ¢èªãšäžèŽããã»ã©ãããåèŽãããšã¿ãªã
+        <li>åžã«åºçŸããèªãåºçŸããã»ã©ããåèŽãããšã¿ãªãã
+        <li>é·ãæç« ãããç­ãæç« ã®æ¹ãããåèŽãããšããã
+      </ul>
+</ul>
+
+<p>æ€çŽ¢èªã¯å¥œããªã ãå€ãå«ããŠããããäŸãã°æãããã©ã°ã©ãã§ãã£ãŠãããã
+ïŒåèªã ããæå®ãããšãçµæã¯æç« äž­ã®ãã®åèªã®åºçŸé »åºŠãå€ãé ã«äžŠã¹ãããŠåºåãããã<p>
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textdatesearch_ [l=ja] {æ¥ä»ã«ããæ€çŽ¢}
+
+_texthelpdatesearch_ [l=ja] {æ¥ä»æ€çŽ¢ã¯ãèªã«ããæ€çŽ¢ãšåæ§ã«æéé 
+ç®ãæ€çŽ¢ããŸãã
+ãã®å Žåãããå¹Žããããããã¯ãæ°å¹Žã®ç¯å²ããã®ææžãæ¢ããšãã£ãããšãã§ããŸãã
+æ¥ä»ã«ããæ€çŽ¢ãªã®ã§ãæ¥ä»é 
+ç®ã«å­åšããªããããªèªãå
+¥åããŠãé©åœãªæ€çŽ¢ãè¡ãªããªãããšã«æ³šæããŠãã ããã
+<p>
+}
+
+_texthelpdatehowtotitle_ [l=ja] {ãã®æ©èœã®äœ¿ãæ¹:}
+_texthelpdatehowto_ [l=ja] {<ul>
+   <li>åå¹Žã«å¯ŸããŠã®æ€çŽ¢:<p>
+   <ul>
+       <li>å
+¥åã¯æ®éã«è¡ããŸãã 
+       <li>æ€çŽ¢å¹Žã""Start (or only) date""ã«å
+¥åããã
+       <li>æ¥ä»ã«çŽå
+åãæå®ããããšãã¯ããã«ããŠã³ã¡ãã¥ãŒãã ""B.C.E""ãéžãã§ãã ããã.
+   </ul>
+<p><li>æéãæå®ããŠã®æ€çŽ¢ïŒ<p>
+   <ul>
+       <li>å
+¥åã¯æ®éã«è¡ããŸãã
+       <li>æéã®å§ãã ""Start (or only) date"" ã«å
+¥åããã
+       <li>æéã®çµããã ""End date"" ã«å
+¥åããã
+       <li>çŽå
+åã®å Žåã¯ã""B.C.E"" ããã«ããŠã³ã¡ãã¥ãŒããéžæããŠãã ããã
+   </ul>
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=ja] {æ€çŽ¢ã®çµæ}
+_texthelpdateresults_ [l=ja] {æ¥ä»ã«é¢ããç¯å²ã®æå®ã¯ãäŸãã°1899-1911ãšããå Žåã«ããã®æéã®éã®ãããã®æ¥ä»ãã«ãé©åãããŸã<p>
+}
+
+_textchangeprefs_ [l=ja] {ããªãã¡ã¬ã³ã¹ãå€æŽãã}
+
+_texthelppreferences_ [l=ja] {<p>ããŒãžã®å
+é ­ã«ãã<i>preferences</i>ãã¿ã³ãæŒããšãã€ã³ã¿ãŒãã§ãŒã¹ã®æ©èœãå€æŽããããšãã§ããŸãã
+}
+
+
+_texthelpcollectionprefs_ [l=ja] {ãµãã³ã¬ã¯ã·ã§ã³ãç¬ç«ããŠæ€çŽ¢ããããäžã€ã®éåã§ããããã«æ€çŽ¢ããããéžæããããšãã§ããŸãã
+}
+
+
+_texthelplanguageprefs_ [l=ja] {ã©ã®ã³ã¬ã¯ã·ã§ã³ãæšæºã®è¡šç€ºèšèªããã£ãŠããŸãããèªåã®èŠããç°ãªãèšèªã«å€æŽããããšãå¯èœã§ãã
+ãã®å ŽåãGreenstoreã®ã¢ãŠããããã«çšããŠãããã©ãŠã¶ã®èšèªã³ãŒãäœç³»ã®èš­å®ãå€æŽããããšã«æ³šæããŠãã ããã
+}
+
+
+_texthelppresentationprefs_ [l=ja] {ã³ã¬ã¯ã·ã§ã³ã«ãã£ãŠã¯ãæšæºçãªè¡šç€ºæ¹æ³ã®å€æŽãã§ããŸãã
+<p>WebããŒãžã®ã³ã¬ã¯ã·ã§ã³ã«ã€ããŠã¯ãGreenstoneã®ããã²ãŒã·ã§ã³ããŒãé ãããšãã§ããŸãã
+ãã®å Žåãä»ã®æ€çŽ¢ãããããã«ã¯ããã©ãŠã¶ã®ããã¯ãã¿ã³ãäœ¿çšããŠãã ããã
+ãã®ãããªã³ã¬ã¯ã·ã§ã³ãäœ¿ãå Žåã¯ãé»å­å³æžé€šã®ã³ã¬ã¯ã·ã§ã³ãWebãã®ãã®ã®ãªã³ã¯ãã¯ãªãã¯ãããšãã«ãGreenstoneã®è­Šåãåºããªãããã«ããããšãã§ããŸãã
+ãŸããé»å­å³æžé€šã®ã³ããŒã§ã¯ãªããå®éã®URLã«çŽæ¥ãç§»åãããã©ãããæç€ºããããšãã§ããŸãã
+}
+
+
+_texthelpsearchprefs_ [l=ja] {<p>
+Two pairs of buttons control the kind of text matching in the searches that you make.
+æ€çŽ¢ããªãã¡ã¬ã³ã¹ã®ãã¿ã³ã¯ãæ€çŽ¢ãšããããããã­ã¹ãã®çš®é¡ãã³ã³ãã­ãŒã«ããããšãã§ããŸãã
+""case differences""ã¯å€§æå­ã»å°æå­ã®åèŽæ¡ä»¶ãèš­å®ã§ããŸãã
+""word endings""ã¯èªæ«åœ¢åŒãç¡èŠãããã©ãããèš­å®ã§ããŸãã
+ãã©ã°ã©ãåäœã®æ€çŽ¢ããããããªãå€§ããªæ€çŽ¢æ¡ä»¶å
+¥åããã¯ã¹ãæå®ããããšãã§ããŸããé·ãæ€çŽ¢æ¡ä»¶ãæå®ãããšãæ©ãå€ãã®æã®ãã­ã¹ããæ€çŽ¢ããããšãã§ããŸãã
+<p>
+äŸãã°ã<i>ignore case differences</i> ãš <i>ignore word endings</i>ã®ãã¿ã³ãéžæãããŠããã°ã<p>
+<ul><kbd>African building</kbd></ul>
+ãšããæå­åã¯ã
+<ul><kbd>africa builds</kbd></ul><p>
+ãšåæ§ã«æ±ãããŸãã
+ãªããªãã""African""ã®""A""ã¯""a""ã«ã
+æ«å°Ÿã® ""n"" ãš ""ing"" ã¯åãããããããã§ãã
+
+<p>ãŸãã""advanced"" æ€çŽ¢ã¢ãŒããæå®ã§ããŸãã
+""advanced"æ€çŽ¢ã¢ãŒãã§ã¯ãè«çæŒç®ãAND (&), OR (|), and NOT (!)ãçšããŠè€éãªæ€çŽ¢ãè¡ãªãããšãã§ããŸãã
+æ€çŽ¢å±¥æ­Žæ©èœãå€ããããšãã§ããŸãã
+ããã«ããããããåã®è³ªåãå°ãä¿®æ­£ããŠãŸãè¡ãªãããšãç¹°ãè¿ãæããªããŸãã
+æ€æ»çµæãšããŠæå€§æ°ãç»é¢äžã«è¡šç€ºã§ããæå€§çµææ°ãå€æŽããããšãã§ããŸãã
+}
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+_texttanumbrowseoptions_ [l=ja] {ãã®ã³ã¬ã¯ã·ã§ã³ããæ
+å ±ãæ¢ãããã®_numbrowseoptions_ ã ãã®æ¹æ³ããããŸãïŒ}
+
+_textsimplehelpheading_ [l=ja] {ã³ã¬ã¯ã·ã§ã³ _collectionname_ ã«ããæ
+å ±ãã©ã®ããã«èŠã€ããã}
+
+
+_texthelpscope_ [l=ja] {<p>
+å€§éšåã³ã¬ã¯ã·ã§ã³ã«ãããŠæ€çŽ¢ã®ããã®ã€ã³ããã¯ã¹ãå©çšã§ããŸãã
+äŸãã°ãèè
+ãã¿ã€ãã«ã®ã€ã³ããã¯ã¹ãæãã¯ãç« ããã©ã°ã©ãã®ã€ã³ããã¯ã¹ããããŸãã
+ããã«å¯Ÿããæç« å
+šäœãžã®æ€çŽ¢ã¯ãã©ã®ã€ã³ããã¯ã¹ãå©çšãããã«é¢ä¿ãªãå®è¡ãããŸãã<p>
+}
Index: /gsdl/stable/macros/japanese2.dm
===================================================================
--- /gsdl/stable/macros/japanese2.dm	(revision 20131)
+++ /gsdl/stable/macros/japanese2.dm	(revision 20131)
@@ -0,0 +1,694 @@
+# this file must be UTF-8 encoded
+
+############################################################################
+#
+# This stuff is only used by the usability (I'd like to Complain) stuff
+#
+############################################################################
+package Global
+
+
+
+
+
+
+### taken from here
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+# should have arguments of collection, collectionname and link
+
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# collectoraction
+package wizard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textypits_ [l=ja] {Your position in the sequence is indicated by an arrow underneath--in this
+case, the "collection information" stage.  To proceed, click the green
+"source data" button.
+}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_texttryagain_ [l=ja] {æ¬¡ã®ãã¿ã³ãæŒããŠ<a href="_httppagecollector_" target=_top>restart the collector</a>
+ãããäžåºŠè©ŠããŠãã ããã
+}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+
+
+_greenstoneusabilitytext_ [l=ja] {ã°ãªãŒã³ã¹ããŒã³ã®å©çšæ§}
+
+_textwhy_ [l=ja] {è²Žæ¹ãèŠãŠããWeb PageãèŠã€ãããšããããšãç¥ãããããããã®ã¬ããŒãããéããã ãã}
+_textextraforform_ [l=ja] {Formãã«ã¯èšå
+¥ããªããŠãçµæ§ã§ã}
+_textprivacybasic_ [l=ja] {<p>ãã®ã¬ããŒãã¯ the Greenstone web pageãšããã«é¢é£ããæè¡ã«ã€ããŠè¿°ã¹ãŠãããŸãã}
+_textstillsend_ [l=ja] {ã¬ããŒãããéãã«ãªãããã§ãã}
+
+_texterror_ [l=ja] {ãšã©ãŒ}
+_textyes_ [l=ja] {ã¯ã}
+_textno_ [l=ja] {ããã}
+_textclosewindow_ [l=ja] {Windowããéãã}
+_textabout_ [l=ja] {ã«ã€ããŠ}
+_textprivacy_ [l=ja] {èªè²»åºç}
+_textsend_ [l=ja] {éã}
+_textdontsend_ [l=ja] {éããªã}
+_textoptionally_ [l=ja] {ãªãã·ã§ã³}
+
+_textunderdev_ [l=ja] {è©³çŽ°ãªãã¬ãã¥ãŒã¯æçµããŒãžã§ã³ã«ãã£ãŠæäŸãããŸã}
+
+_textviewdetails_ [l=ja] {ã¬ããŒããè©³çŽ°ã«èŠãŠãã ãã}
+_textmoredetails_ [l=ja] {çŽ°ããè©³çŽ°}
+_texttrackreport_ [l=ja] {ãã®ã¬ããŒããè¿œè·¡ãã}
+_textcharacterise_ [l=ja] {ã©ããªåé¡ã§ãã}
+_textseverity_ [l=ja] {åé¡ã®çšåºŠ}
+ 
+_textbadrender_ [l=ja] {ããŒãžããããã}
+_textcontenterror_ [l=ja] {ã³ã³ãã³ããšã©ãŒ}
+_textstrangebehaviour_ [l=ja] {ããããªæåã§ã}
+_textunexpected_ [l=ja] {äºæããªãäœããèµ·ãããŸãã}
+_textfunctionality_ [l=ja] {äœ¿çšãé£ãã}
+_textother_ [l=ja] {ãã®ä»}
+
+_textcritical_ [l=ja] {éå€§}
+_textmajor_ [l=ja] {å³ãã}
+_textmedium_ [l=ja] {ããã€ãŒã¢ã }
+_textminor_ [l=ja] {ãã€ããŒ}
+_texttrivial_ [l=ja] {ããããªåé¡}
+
+_textwhatdoing_ [l=ja] {ãªã«ããªãããããšããŸãããïŒ}
+_textwhatexpected_ [l=ja] {ã©ã®ãããªããšãããããšæãããŸãããïŒ}
+_textwhathappened_ [l=ja] {å®éã«ã¯äœãããããŸãããïŒ}
+
+_cannotfindcgierror_ [l=ja] {<h2>ãã¿ãŸããã!</h2>ãâComplainâãã¿ã³ã®ããã®ãµãŒããŒãã­ã°ã©ãã¯èŠã€ããããŸãã}
+
+_textusabbanner_ [l=ja] {Greenstoneã®koru-stykeã®ãããŒ}
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+############
+# gli page
+############
+package gli
+
+
+
Index: /gsdl/stable/macros/kannada.dm
===================================================================
--- /gsdl/stable/macros/kannada.dm	(revision 20131)
+++ /gsdl/stable/macros/kannada.dm	(revision 20131)
@@ -0,0 +1,809 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Kannada Language text and icon macros, translated from english.dm
+# on 2 July 2002 by Mr.Shivaram.B.S. and updated on 8 January 2007 By Mr.Pradeep Kumar,U.M.
+# Information and Knowledge Management Course Trainee ,
+# National Centre for Science Information, Indian Institute of Science,
+# Bangalore 560 012, Karnataka, India.) under the guidance of Ms.Anuradha.K.T.,
+# Senior Technical Officer, National Centre for Science Information,
+# Indian Institute of Science, Bangalore 560 012, Karnataka, India.
+#
+# Updated in July 2009 by S.K. Lalitha  and K.S. Raghavan of 
+# the Sarada Ranganathan Endowment for Library Science, Bangalore
+#
+######################################################################
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=kn] {à²šà²¿à²¯à²€à²à²Ÿà²²à²¿à²à²à²³à³}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=kn] {à²®à³à²² ref:}  
+_textdate_ [l=kn] {à²ªà³à²°à²à²Ÿà²¶à²¿à²€ à²Šà²¿à²šà²Ÿà²à²}  
+_textnumpages_ [l=kn] {à²à²à³à²à³ à²ªà³à²à²à²³à³}  
+
+_textsignin_ [l=kn] {à²°à³à²à³à²®à²Ÿà²¡à²¿ à²à²³ à²¬à²šà³à²šà²¿}  
+
+_textdefaultcontent_ [l=kn] {à²šà³à²µà³ à²ªà³à²°à²¯à²€à³à²šà²¿à²žà²¿à²Š à²ªà³à² à²žà²¿à²à²²à²¿à²²à³à²². à²à²¿.à²à²žà³.à²¡à²¿.à²à²²à³.à²à³ à²¹à²¿à²à²€à²¿à²°à³à²à²²à³ à²šà²¿à²®à³à²® à²¬à³à²°à³à²žà²°à³ à²š 'à²¹à²¿à²à²Šà³' à²à³à²à²¡à²¿à²¯à²šà³à²šà²Ÿà²à²²à²¿ à²
+à²¥à²µà²Ÿ à²®à³à²²à²¿à²š à²®à³à²à²ªà³à² à²à³à²à²¡à²¿à²¯à²šà³à²šà²Ÿà²à²²à²¿ à²¬à²³à²žà²¿.}  
+
+_textdefaulttitle_ [l=kn] {à²à²¿.à²à²žà³.à²¡à²¿.à²à²²à³ à²€à²ªà³à²ªà³}  
+
+_textbadcollection_ [l=kn] {à² à²žà²à²à³à²°à²¹ (called "_cvariable_") à² à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²¡à²¿à²à²¿à²à²²à³â à²à³à²°à²à²¥à²Ÿà²²à²¯à²Šà²²à³à²²à²¿ à²žà³à²¥à²Ÿà²ªà²¿à²žà²²à³à²ªà²à³à²à²¿à²²à³à²².}  
+
+_textselectpage_ [l=kn] {-- à²ªà³à²à²µà²šà³à²šà³ à²à²°à²¿à²žà³--}  
+
+_collectionextra_ [l=kn] {à²à²žà²à²à³à²°à²¹à²£à³à²¯à²²à³à²²à²¿ _about:numdocs_ à²Šà²Ÿà²à²²à³à²à²³à²¿à²µà³. à²à²Šà²°à²žà²à²à³à²°à²¹à²£à³ à²®à²Ÿà²¡à²¿à²Šà³à²Šà³ _about:builddate_ à²Šà²¿à²šà²à²³ à²¹à²¿à²à²Šà³.}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=kn] {<p> à² à²žà²à²à³à²°à²¹à²£à³à²¯à²²à³à²²à²¿ à²à²°à³à²µ _numdocs_ _If_("_numdocs_" eq "1",document,documents), à²à²à³à²à³ _numbytes_à²žà³à²à³à²à²°à²¿à²žà²¿à²Š à²ªà² à³à²¯ à²®à²€à³à²€à³ à²®à³à²à²¡à³à². <p><a href="_httppagex_(bsummary)"> à² à²žà²à²à³à²°à²¹à²Š à²žà²à²à³à²·à²¿à²ªà³à²€à²µà²¿à²µà²°à²à²³à²šà³à²šà³ à²šà³à²¡à²²à³ à²à²²à³à²²à²¿ à²à³à²²à²¿à²à³à²à²¿à²žà²¿</a>}  
+
+_textdescrcollection_ [l=kn] {}  
+_textdescrabout_ [l=kn] {'à²¬à²à³à²à³' à²ªà³à²}  
+_textdescrhome_ [l=kn] {à²®à³à² à²ªà³à²}  
+_textdescrhelp_ [l=kn] {à²žà²¹à²Ÿà²¯ à²ªà³à²}  
+_textdescrpref_ [l=kn] {à²ªà³à²°à²Ÿà²§à²Ÿà²šà³à²¯à²€à³à²à²³ à²ªà³à²}  
+_textdescrgreenstone_ [l=kn] {à²à³à²°à³à²šà³à²žà³à²à³à²šà³ à²¡à²¿à²à²¿à²à²²à³ à²à³à²°à²à²¥à²Ÿà²²à²¯ à²€à²à²€à³à²°à²Ÿà²à²¶}  
+_textdescrusab_ [l=kn] {à²à²ªà²¯à³à²à²¿à²žà³à²µà³à²Šà²°à²²à³à²²à²¿ à²¯à²Ÿà²µà³à²Šà³ à²à²·à³à²à²µà²Ÿà²¯à²¿à²€à³}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=kn] {à²¶à³à²§à²šà³}  
+_labelSearch_ [l=kn] {à²¶à³à²§à²šà³}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=kn] {à²¶à³à²°à³à²·à²¿à²à³}  
+_labelTitle_ [l=kn] {à²¶à³à²°à³à²·à²¿à²à³ A-Z}
+_textCreator_ [l=kn] {à²žà³à²·à³à²à²¿à²à²°à³à²€}  
+_labelCreator_ [l=kn] {à²²à³à²à²à²°à³ A-Z}
+_textSubject_ [l=kn] {à²µà²¿à²·à²¯}  
+_labelSubject_ [l=kn] {à²µà²¿à²·à²¯}
+_textDescription_ [l=kn] {à²µà²¿à²µà²°à²£à³}  
+_labelDescription_ [l=kn] {à²µà²¿à²µà²°à²£à³}  
+_textPublisher_ [l=kn] {à²ªà³à²°à²à²Ÿà²¶à²}  
+_labelPublisher_ [l=kn] {à²ªà³à²°à²à²Ÿà²¶à²à²°à³}  
+_textContributor_ [l=kn] {à²à³à²¡à³à²à³à²Šà²Ÿà²°à²°à³}  
+_labelContributor_ [l=kn] {à²à³à²¡à³à²à³à²Šà²Ÿà²°à²°à³}  
+_textDate_ [l=kn] {à²Šà²¿à²šà²Ÿà²à²}  
+_labelDate_ [l=kn] {à²Šà²¿à²šà²Ÿà²à²}
+_textType_ [l=kn] {à²¬à²à³}  
+_labelType_ [l=kn] {à²¬à²à³à²à²³à³}  
+_textFormat_ [l=kn] {à²žà²à²µà²¿à²­à²Ÿà²}  
+_labelFormat_ [l=kn] {à²žà²à²µà²¿à²­à²Ÿà²}  
+_textIdentifier_ [l=kn] {à²à³à²°à³à²€à³à²à²³à³}  
+_labelIdentifier_ [l=kn] {à²à³à²°à³à²€à³à²à²³à³}  
+_textSource_ [l=kn] {à²à²¡à²€à²Š à²¹à³à²žà²°à³}  
+_labelSource_ [l=kn] {à²à²¡à²€à²Š à²¹à³à²žà²°à³}  
+_textLanguage_ [l=kn] {à²­à²Ÿà²·à³}  
+_labelLanguage_ [l=kn] {à²­à²Ÿà²·à³à²à²³à³}  
+_textRelation_ [l=kn] {à²žà²à²¬à²à²§}  
+_labelRelation_ [l=kn] {à²žà²à²¬à²à²§à²à²³à³}  
+_textCoverage_ [l=kn] {à²µà³à²¯à²Ÿà²ªà³à²€à²¿}  
+_labelCoverage_ [l=kn] {à²µà³à²¯à²Ÿà²ªà³à²€à²¿}  
+_textRights_ [l=kn] {à²¹à²à³à²à³à²à²³à³}  
+_labelRights_ [l=kn] {à²¹à²à³à²à³à²à²³à³}  
+
+# DLS metadata set
+_textOrganization_ [l=kn] {à²žà²à²žà³à²¥à³}  
+_labelOrganization_ [l=kn] {à²žà²à²žà³à²¥à³à²à²³à³}  
+_textKeyword_ [l=kn] {à²®à³à²à³à²¯ à²ªà²Š}  
+_labelKeyword_ [l=kn] {à²®à³à²à³à²¯ à²ªà²Šà²à²³à³}  
+_textHowto_ [l=kn] {à²¹à³à²à³}  
+_labelHowto_ [l=kn] {à²¹à³à²à³}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=kn] {à²ªà²Šà²à³à²à³à²}  
+_labelPhrase_ [l=kn] {à²ªà²Šà²à³à²à³à²}  
+_textCollage_ [l=kn] {à²à²²à²Ÿà²à³}  
+_labelCollage_ [l=kn] {à²à²²à²Ÿà²à³}  
+_textBrowse_ [l=kn] {à²µà³à²à³à²·à²¿à²žà³}  
+_labelBrowse_ [l=kn] {à²µà³à²à³à²·à²£à³}  
+_textTo_ [l=kn] {à²à³}  
+_labelTo_ [l=kn] {à²à³}  
+_textFrom_ [l=kn] {à²à²à²Š}  
+_labelFrom_ [l=kn] {à²à²à²Š}  
+_textAcronym_ [l=kn] {à²žà²à²à³à²·à²¿à²ªà³à²€à²°à³à²ª}  
+_labelAcronym_ [l=kn] {à²žà²à²à³à²·à²¿à²ªà³à²€ à²°à³à²ª}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=kn] {_1_ à²°à²¿à²à²Š à²µà³à²à³à²·à²¿à²žà³}  
+
+_textdescrSearch_ [l=kn] {à²šà²®à³à²Šà²¿à²žà²¿à²Š à²ªà²Šà²à²³à²šà³à²šà³ à²¶à³à²§à²¿à²žà³}  
+_textdescrType_ [l=kn] {à²žà²à²ªà²šà³à²®à³à²² à²¬à²à³à²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}  
+_textdescrIdentifier_ [l=kn] {à²žà²à²ªà²šà³à²®à³à²² à²à³à²°à³à²€à³ à²®à³à²²à² à²µà³à²à³à²·à²¿à²žà²¿}  
+_textdescrSource_ [l=kn] {à²®à³à²² à²à²¡à²€ à²¹à³à²žà²°à³à²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}  
+_textdescrTo_ [l=kn] {à²à³' à²à³à²·à³à²€à³à²°à²Š à²®à³à²²à² à²µà³à²à³à²·à²¿à²žà²¿}  
+_textdescrFrom_ [l=kn] {à²à³à²·à³à²€à³à²°à²Š à²®à³à²²à² à²µà³à²à³à²·à²¿à²žà²¿ }  
+_textdescrCollage_ [l=kn] {à²à²Ÿà²¯à³à²à²³à²šà³à²šà³ à²à²²à²Ÿà²à³ à²®à³à²à²Ÿà²à²€à²° à²µà³à²à³à²·à²¿à²žà²¿}  
+_textdescrAcronym_ [l=kn] {à²žà²à²à³à²·à²¿à²ªà³à²€ à²°à³à²ªà²µà²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}  
+_textdescrPhrase_ [l=kn] {à²ªà²Šà²à³à²à³à²à²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}  
+_textdescrHowto_ [l=kn] {à²¹à³à²à³ à²µà²°à³à²à³à²à²°à²¿à²žà²¬à²¹à³à²Šà³' à²µà³à²à³à²·à²¿à²žà²¿}  
+_textdescrBrowse_ [l=kn] {à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}  
+_texticontext_ [l=kn] {à²Šà²žà³à²€à²Ÿà²µà³à²à²šà³à²šà³ à²šà³à²¡à²¿}  
+_texticonclosedbook_ [l=kn] {à²Šà²žà³à²€à²Ÿà²µà³à²à³ à²€à³à²à³à²Šà³ à²ªà²°à²¿à²µà²¿à²¡à²¿à²¯à²šà³à²šà³ à²šà³à²¡à²¿}  
+_texticonnext_ [l=kn] {à²®à³à²à²Šà²¿à²š à²­à²Ÿà²à²à³à²à³}  
+_texticonprev_ [l=kn] {à²¹à²¿à²à²Šà²¿à²š à²­à²Ÿà²à²à³à²à³}
+
+_texticonworld_ [l=kn] {à²µà³à²¬à³â à²Šà²žà³à²€à²Ÿà²µà³à²à²šà³à²šà³ à²šà³à²¡à²¿}  
+
+_texticonmidi_ [l=kn] {à²®à²¿à²¡à²¿ à²®à²Ÿà²Šà²°à²¿ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²šà³à²¡à²¿}  
+_texticonmsword_ [l=kn] {à²à².à²à²žà³. à²µà²°à³à²¡ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²šà³à²¡à²¿}  
+_texticonmp3_ [l=kn] {MP3 à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²šà³à²¡à²¿}  
+_texticonpdf_ [l=kn] {PDF à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²šà³à²¡à²¿}  
+_texticonps_ [l=kn] {à²ªà³à²žà³à²à³âà²žà³à²à³à²°à²¿à²ªà³à²à³â à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²šà³à²¡à²¿}  
+_texticonppt_ [l=kn] {à²ªà²µà²°à³âà²ªà²Ÿà²¯à²¿à²à²à³â à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²šà³à²¡à²¿}  
+_texticonrtf_ [l=kn] {RTF à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²šà³à²¡à²¿}  
+_texticonxls_ [l=kn] {à²®à³à²à³à²°à³à²žà²Ÿà²«à³à²à³â à²à²à³à²žà³à²²à³â à²Šà²žà³à²€à²Ÿà²µà³à²à²šà³à²šà³ à²šà³à²¡à²¿}  
+
+_page_ [l=kn] {à²ªà³à²}
+_pages_ [l=kn] {à²ªà³à²à²à²³à³}
+_of_ [l=kn] {à²à²¡à³à²à³ }
+_vol_ [l=kn] {à²žà²à²ªà³à²}
+_num_ [l=kn] {à²žà²à²à³à²¯à³}  
+
+_textmonth00_ [l=kn] {}  
+_textmonth01_ [l=kn] {à²à²šà²µà²°à²¿}
+_textmonth02_ [l=kn] {à²«à³à²¬à³à²°à²µà²°à²¿}
+_textmonth03_ [l=kn] {à²®à²Ÿà²°à³à²}
+_textmonth04_ [l=kn] {à²à²ªà³à²°à²¿à²²à³}
+_textmonth05_ [l=kn] {à²®à³}
+_textmonth06_ [l=kn] {à²à³à²šà³}
+_textmonth07_ [l=kn] {à²à³à²²à³}
+_textmonth08_ [l=kn] {à²à²à²žà³à²à³}
+_textmonth09_ [l=kn] {à²žà³à²ªà³à²à²à²¬à²°à³}
+_textmonth10_ [l=kn] {à²
+à²à³à²à³à²¬à²°à³}
+_textmonth11_ [l=kn] {à²šà²µà²à²¬à²°à³}
+_textmonth12_ [l=kn] {à²¡à²¿à²žà³à²à²¬à²°à³}
+
+_texttext_ [l=kn] {à²ªà² à³à²¯}  
+_labeltext_ [l=kn] {_texttext_}  
+_textdocument_ [l=kn] {à²Šà²žà³à²€à²Ÿà²µà³à²à³}  
+_textsection_ [l=kn] {à²µà²¿à²­à²Ÿà²}  
+_textparagraph_ [l=kn] {à²µà²Ÿà²à³à²¯à²µà³à²à²Š}  
+_textchapter_ [l=kn] {à²
+à²§à³à²¯à²Ÿà²¯}  
+_textbook_ [l=kn] {à²ªà³à²žà³à²€à²}  
+
+_magazines_ [l=kn] {à²šà²¿à²¯à²€à²à²Ÿà²²à²¿à²à²à²³à³}  
+
+_nzdlpagefooter_ [l=kn] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">à²šà³à²¯à³à²à²¿ à²²à³à²¯à²Ÿà²à²¡à³â à²¡à²¿à²à²¿à²à²²à³â à²²à³à²¬à³à²°à²°à²¿ à²ªà³à²°à²Ÿà²à³à²à³à²à³â</a>
+ <br><a href="http://www.cs.waikato.ac.nz">à²à²à²ªà³à²¯à³à²à²°à³â à²µà²¿à²à³à²à²Ÿà²š à²µà²¿à²­à²Ÿà²</a>, 
+ <a href="http://www.waikato.ac.nz">à²µà³à²à²Ÿà²à³ à²µà²¿à²¶à³à²µà²µà²¿à²Šà³à²¯à²Ÿà²šà²¿à²²à²¯</a>, 
+ à²šà³à²¯à³à²à²¿ à²²à³à²¯à²Ÿà²à²¡à³â 
+}  
+
+_linktextHOME_ [l=kn] {à²¹à³à²®à³â}  
+_linktextHELP_ [l=kn] {à²žà²¹à²Ÿà²¯}  
+_linktextPREFERENCES_ [l=kn] {à²ªà³à²°à²Ÿà²§à²Ÿà²šà³à²¯à²€à³à²à²³à³}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²¡à²¿à²à²¿à²à²²à³â à²²à³à²¬à³à²°à²°à²¿}  
+
+_textnocollections_ [l=kn] {à²žà²°à²¿à²¯à²Ÿà²Š  (à²šà²¿à²°à³à²®à²Ÿà²£ à²®à²Ÿà²¡à²¿à²Š à²®à²€à³à²€à³ à²žà²Ÿà²°à³à²µà²à²šà²¿à²à²µà²Ÿà²à²¿ à²²à²­à³à²¯à²µà²Ÿà²à³à²µ) à²žà²à²à³à²°à²¹à²à²³à³ à²žà²¿à²à³à²€à³à²€à²¿à²²à³à²²}  
+
+_textadmin_ [l=kn] {à²à²¡à²³à²¿à²€ à²ªà³à²}  
+_textabgs_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà²¿à²š à²¬à²à³à²à³}  
+_textgsdocs_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²°à²£}  
+
+_textdescradmin_ [l=kn] {à²šà²¿à²®à²à³ à²¹à³à²ž à²¬à²³à²à³à²Šà²Ÿà²°à²°à²šà³à²šà³ à²žà³à²°à²¿à²žà²²à³ à²
+à²µà²à²Ÿà²¶ à²®à²Ÿà²¡à²¿à²à³à²¡à³à²€à³à²€à²Šà³; à²šà²¿à²®à³à²® à²žà²à²à³à²°à²¹à²à²³ à²žà²Ÿà²°à²Ÿà²à²¶à²µà²šà³à²šà³à²Šà²à²¿à²žà³à²€à³à²€à²Šà³ à²®à²€à³à²€à³ à²à³à²šà³âà²žà³à²à³à²šà³â à²žà³à²¥à²Ÿà²ªà²¿à²žà³à²µ à²¬à²à³à²à³ à²€à²Ÿà²à²€à³à²°à²¿à² à²®à²Ÿà²¹à²¿à²€à²¿à²¯à²šà³à²šà³ à²šà³à²¡à³à²€à³à²€à²Šà³}  
+
+_textdescrgogreenstone_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²€à²à²€à³à²°à²Ÿà²à²¶à²Š à²¬à²à³à²à³ à²®à²€à³à²€à³ à²šà³à²¯à³à²à²¿à²²à³à²¯à²Ÿà²à²¡à³â à²¡à²¿à²à²¿à²à²²à³â à²²à³à²¬à³à²°à²°à²¿à²¯à³ à²¬à²à³à²à³ à²šà²¿à²®à²à³ à²€à²¿à²³à²¿à²žà²¿à²à³à²¡à³à²€à³à²€à²Šà³}  
+
+_textdescrgodocs_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà²¿à²š à²à³à²ªà²¿à²¡à²¿}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=kn] {à²²à³à²¬à³à²°à²°à²¿à²¯à²šà³ à²à²à²à²°à³âà²«à³à²žà³â}  
+_textdescrgli_ [l=kn] {à²¹à³à²ž à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà²²à³ à²®à²€à³à²€à³ à²à²°à³à²µ à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ à²šà²µà³à²à²°à²¿à²žà²²à³ à²¹à²Ÿà²à³ à²€à³à²à³à²¯à²²à³ à²žà²¹à²Ÿà²¯ à²®à²Ÿà²¡à³à²€à³à²€à²Šà³}  
+
+package collector
+
+_textcollector_ [l=kn] {à²à²²à³à²à³à²à²°à³â}  
+_textdescrcollector_ [l=kn] {à²à²Šà³ à²²à³à²¬à³à²°à²°à²¿à²¯à²šà³ à²à²à²à²°à³ à²«à³à²žà³âà²à²¿à²à²€ à²¹à²³à³à²¯à²Šà³. à²à²²à³à²²à²Ÿ à²à²ªà²¯à³à²à²à²³à²¿à²à³ à²²à³à²¬à³à²°à²°à²¿à²¯à²šà³ à²à²à²à²°à³ à²«à³à²žà³â à²¬à²³à²žà²¿}  
+
+package depositor
+
+_textdepositor_ [l=kn] {à² à³à²µà²£à²¿à²Šà²Ÿà²°}  
+_textdescrdepositor_ [l=kn] {à²à²°à³à²µ à²žà²à²à³à²°à²¹à²à²³à²¿à²à³ à²¹à³à²ž à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²žà³à²°à²¿à²žà²²à³ à²žà²¹à²Ÿà²¯à²®à²Ÿà²¡à³à²€à³à²€à²Šà³}  
+
+package gti
+
+_textgti_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²­à²Ÿà²·à²Ÿà²à²€à²° à²à²à²à²°à³âà²«à³à²žà³â}  
+_textdescrtranslator_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²à²à²à²°à³âà²«à³à²žà³âà²š à²¬à²¹à³ à²­à²Ÿà²·à²Ÿ à²à²µà³à²€à³à²€à²¿à²à²³à²šà³à²šà³ à²šà²µà³à²à²°à²¿à²žà²²à³ à²žà²¹à²Ÿà²¯à²®à²Ÿà²¡à³à²€à³à²€à²Šà³}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=kn] {à² à²žà²à²à³à²°à²¹à²£à³à²¯ à²¬à²à³à²à³}
+
+_textsubcols1_ [l=kn] {<p>à²žà²à²ªà³à²°à³à²£ à²žà²à²à³à²°à²¹à²£à³à²¯ _1_ à²à²ª à²žà²à²à³à²°à²¹à²£à³à²à²³à²šà³à²šà³à²¹à³à²à²Šà²¿à²Šà³<blockquote>}  
+
+_textsubcols2_ [l=kn] {</blockquote>à²šà³à²µà³ à²žà²Šà³à²¯ à²à²ªà²¯à³à²à²¿à²žà³à²€à³à²€à²¿à²°à³à²µ à²à²ªà²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²ªà³à²°à²Ÿà²§à²Ÿà²šà³à²¯à²€à³à²¯ à²ªà³à²à²Šà²²à³à²²à²¿ à²šà³à²¡à²¬à²¹à³à²Šà³ à²®à²€à³à²€à³ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²¬à²¹à³à²Šà³}  
+
+_titleabout_ [l=kn] {à²žà²à²¬à²à²§à²¿à²žà²¿à²Š}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=kn] {à²à³à²°à²à²¥à²Ÿà²²à²¯à²Š à² à²­à²Ÿà²à²µà²šà³à²šà³ à²®à³à²à³à²à²¿}  
+_texticonclosedbookshelf_ [l=kn] {à²à³à²°à²à²¥à²Ÿà²²à²¯à²Š à² à²­à²Ÿà²à²µà²šà³à²šà³à²€à³à²°à³à²Šà³ à²ªà²°à²¿à²µà²¿à²¡à²¿à²¯à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}
+_texticonopenbook_ [l=kn] {à² à²ªà³à²žà³à²€à²à²µà²šà³à²šà³ à²®à³à²à³à²à²¿}
+_texticonclosedfolder_ [l=kn] {à² à²à²¡à²€à²à²à³à²à²šà³à²šà³ à²€à³à²à³à²Šà³ à²
+à²Šà²° à²ªà²°à²¿à²µà²¿à²¡à²¿à²¯à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}  
+_texticonclosedfolder2_ [l=kn] {à²à²ªà²µà²¿à²­à²Ÿà²à²µà²šà³à²šà³ à²€à³à²à³à²¯à²¿à²°à²¿: }  
+_texticonopenfolder_ [l=kn] {à² à²à²¡à²€à²à²à³à²à²šà³à²šà³ à²®à³à²à³à²à²¿}  
+_texticonopenfolder2_ [l=kn] {à²à²ªà²µà²¿à²­à²Ÿà²à²µà²šà³à²šà³ à²®à³à²à³à²à²¿: }  
+_texticonsmalltext_ [l=kn] {à² à²­à²Ÿà²à²Š à²ªà² à³à²¯à²µà²šà³à²šà³ à²šà³à²¡à²¿}  
+_texticonsmalltext2_ [l=kn] {à²ªà² à³à²¯à²µà²šà³à²šà³ à²šà³à²¡à²¿: }  
+_texticonpointer_ [l=kn] {à²ªà³à²°à²à²²à²¿à²€ à²­à²Ÿà²}
+_texticondetach_ [l=kn] {à² à²ªà³à²à²µà²šà³à²šà³à²¹à³à²ž à²à²¿à²à²à²¿à²¯à²²à³à²²à²¿ à²€à³à²à³à²¯à²¿à²°à²¿}
+_texticonhighlight_ [l=kn] {à²¶à³à²§à²¿à²žà²¿à²Š à²ªà²Šà²à²³à²šà³à²šà³ à²à²€à³à²€à²¿à²€à³à²°à²¿à²žà³}  
+_texticonnohighlight_ [l=kn] {à²¶à³à²§à²¿à²žà²¿à²Š à²ªà²Šà²à²³à²¿à²à³ à²à²€à³à²€à²¿à²€à³à²°à²¿à²ž à²¬à³à²¡}  
+_texticoncontracttoc_ [l=kn] {à²ªà²°à²¿à²µà²¿à²¡à²¿à²¯à²šà³à²šà³ à²žà²à²à³à²à²¿à²€à²à³à²³à²¿à²žà³}  
+_texticonexpandtoc_ [l=kn] {à²ªà²°à²¿à²µà²¿à²¡à²¿à²¯à²šà³à²šà³ à²µà²¿à²žà³à²€à²°à²¿à²žà³}
+_texticonexpandtext_ [l=kn] {à²ªà² à³à²¯à²µà²šà³à²šà³ à²ªà³à²°à²Šà²°à³à²¶à²¿à²žà³}  
+_texticoncontracttext_ [l=kn] {à²ªà² à³à²¯à²µà²šà³à²šà³ à²ªà³à²°à²à²²à²¿à²€à²µà²Ÿà²à²¿ à²à²¯à³à²à³ à²®à²Ÿà²¡à²¿à²à³à²à²¡ à²­à²Ÿà²à²à³à²à³ à²®à²Ÿà²€à³à²° à²€à³à²°à²¿à²žà³}  
+_texticonwarning_ [l=kn] {<b>à²à²à³à²à²°à²¿à²à³: </b>}  
+_texticoncont_ [l=kn] {à²®à³à²à²Šà³à²µà²°à³à²žà²¬à²¹à³à²Šà²Ÿ?}  
+
+_textltwarning_ [l=kn] {<div class="buttons">_imagecont_</div>
+_iconwarning_à²à²²à³à²²à²¿à²š à²ªà² à³à²¯à²µà²šà³à²šà³ à²µà²¿à²žà³à²€à²°à²¿à²žà³à²µà³à²Šà²°à²¿à²à²Š à²šà²¿à²®à³à²® à²¬à³à²°à³à²žà²°à³â à²¬à²¹à²³à²·à³à²à³ à²¹à³à²à³à²à²¿à²š à²Šà²€à³à²€à²µà²šà³à²šà³ à²ªà³à²°à²Šà²°à³à²¶à²¿à²žà²¬à³à²à²Ÿà²à³à²€à³à²€à²Šà³}  
+
+_textgoto_ [l=kn] {à² à²ªà³à²à²à³à²à³ à²¹à³à²à²¿}
+_textintro_ [l=kn] {<i>(à²ªà²°à²¿à²à²¯à²Ÿà²€à³à²®à² à²ªà² à³à²¯)</i>}
+
+_textCONTINUE_ [l=kn] {à²®à³à²à²Šà³à²µà²°à²¿à²žà²²à³?}  
+
+_textEXPANDTEXT_ [l=kn] {à²ªà² à³à²¯à²µà²šà³à²šà³ à²µà²¿à²žà³à²€à²Ÿà²°à²à³à²³à²¿à²žà³}  
+
+_textCONTRACTCONTENTS_ [l=kn] {à²ªà²°à²¿à²µà²¿à²¡à²¿à²à²³à²šà³à²šà³ à²žà²à²à³à²à²¿à²€à²à³à²³à²¿à²žà³}  
+
+_textDETACH_ [l=kn] {à²¬à³à²°à³à²ªà²¡à²¿à²žà³}  
+
+_textEXPANDCONTENTS_ [l=kn] {à²ªà²°à²¿à²µà²¿à²¡à²¿à²à²³à²šà³à²šà³ à²µà²¿à²žà³à²€à²Ÿà²°à²à³à²³à²¿à²žà³}  
+
+_textCONTRACT_ [l=kn] {à²ªà² à³à²¯à²µà²šà³à²šà³ à²žà²à²à³à²à²¿à²€à²à³à²³à²¿à²žà³}  
+
+_textHIGHLIGHT_ [l=kn] {à²à²€à³à²€à²¿ à²€à³à²°à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à²¿à²Šà³}  
+
+_textNOHIGHLIGHT_ [l=kn] {à²à²€à³à²€à²¿ à²€à³à²°à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à²¿à²²à³à²²}  
+
+_textPRINT_ [l=kn] {à²®à³à²Šà³à²°à²¿à²žà³}  
+
+_textnextsearchresult_ [l=kn] {à²®à³à²à²Šà²¿à²š à²¹à³à²¡à³à²à³à²µà²¿à²à³ à²«à²²à²¿à²€à²Ÿà²à²¶}  
+_textprevsearchresult_ [l=kn] {à²¹à²¿à²à²Šà²¿à²š à²¶à³à²§à²šà³à²¯ à²«à²²à²¿à²€à²Ÿà²à²¶}  
+
+# macros for printing page
+_textreturnoriginal_ [l=kn] {à²®à³à²² à²ªà³à²à³à²à²à³à²à³ à²¹à²¿à²à²€à²¿à²°à³à²à²¿}  
+_textprintpage_ [l=kn] {à² à²ªà³à²à²µà²šà³à²šà³ à²®à³à²Šà³à²°à²¿à²žà²¿}  
+_textshowcontents_ [l=kn] {à²µà²¿à²·à²¯ à²ªà²°à²¿à²µà²¿à²¡à²¿à²¯à²šà³à²šà³ à²€à³à²°à²¿à²žà³}  
+_texthidecontents_ [l=kn] {à²µà²¿à²·à²¯ à²ªà²à³à²à²¿à²¯à²šà³à²šà³ à²®à²°à³à²®à²Ÿà²¡à³}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=kn] {_If_(_thislast_,à²«à²²à²¿à²€à²Ÿà²à²¶à²à²³à³ _thisfirst_ - _thislast_ 
+à² à²ªà³à²°à²¶à³à²šà³à²à³: _cgiargq_,à² à²ªà³à²°à²¶à³à²šà³à²à³ à²žà²°à²¿à²¯à²Ÿà²Š à²¹à³à²à²Šà²Ÿà²£à²¿à²à³à²à²³à²¿à²²à³à²²: _cgiargq_)}  
+_textnoquerytitle_ [l=kn] {à²¶à³à²§à²šà³à²¯ à²ªà³à²}  
+
+_textsome_ [l=kn] {à²à³à²²à²µà³}  
+_textall_ [l=kn] {à²à²²à³à²²à²Ÿ}  
+_textboolean_ [l=kn] {à²¬à³à²²à²¿à²¯à²šà³}  
+_textranked_ [l=kn] {à²¶à³à²°à³à²£à³à²à³à²€}  
+_textnatural_ [l=kn] {à²žà²¹à²à²µà²Ÿà²Š}  
+_textsortbyrank_ [l=kn] {à²žà³à²žà²à²à²€à³ à²¶à³à²°à³à²£à²¿}  
+_texticonsearchhistorybar_ [l=kn] {à²¶à³à²§à²šà³à²¯ à²à²°à²¿à²€à³à²°à³}  
+
+_textifeellucky_ [l=kn] {à²šà²Ÿà²šà³ à²
+à²Šà³à²·à³à²à²µà²à²€!}  
+
+#alt text for query buttons
+_textusequery_ [l=kn] {à² à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿à²¯à²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¿}  
+_textfreqmsg1_ [l=kn] {à²ªà²Šà²à²³ à²à²£à²¿à²à³: }
+_textpostprocess_ [l=kn] {_If_(_quotedquery_,<br><i>à²¹à³à²¡à³à²à²²à³ à²¹à²¿à²à²Šà²¿à²š à²à²Ÿà²°à³à²¯ à²µà²¿à²§à²Ÿà²š à²¬à²³à²žà²¿_quotedquery_</i>
+)}  
+_textinvalidquery_ [l=kn] {à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿à²¯ à²ªà²Šà²µà²¿à²šà³à²¯à²Ÿà²ž à²€à²ªà³à²ªà³}  
+_textstopwordsmsg_ [l=kn] {à² à²ªà²Šà²à²³à³ à²¬à²¹à²³ à²žà²Ÿà²®à²Ÿà²šà³à²¯ à²®à²€à³à²€à³ à²à²µà²šà³à²šà³ à²à²¡à³à²à²£à²¿à²žà²²à²Ÿà²à²¿à²Šà³}  
+_textlucenetoomanyclauses_ [l=kn] {à²šà²¿à²®à³à²® à²ªà³à²°à²¶à³à²šà³à²¯à²²à³à²²à²¿ à²¬à²¹à²³ à²¶à³à²§à²šà²Ÿ à²ªà²Šà²à²³à²¿à²µà³; à²Šà²¯à²µà²¿à²à³à²à³ à²¹à³à²à³à²à³ à²žà³à²ªà²·à³à²à²€à³à²¯à²šà³à²šà³ à²¹à³à²à²Šà²¿à²°à³à²µ à²ªà³à²°à²¶à³à²šà³à²¯à²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¿.}  
+
+_textmorethan_ [l=kn] {à²à²Šà²à³à²à²¿à²à²€ à²¹à³à²à³à²à²¿à²š}  
+_textapprox_ [l=kn] {à²¬à²à³à²à³}
+_textnodocs_ [l=kn] {à²šà²¿à²®à³à²® à²ªà³à²°à²¶à³à²šà³à²à³ à²¯à²Ÿà²µ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³ à²žà²°à²¿ à²¹à³à²à²Šà²²à²¿à²²à³à²².}  
+_text1doc_ [l=kn] {à²šà²¿à²®à³à²® à²ªà³à²°à²¶à³à²šà³à²à³ 1 à²Šà²Ÿà²à²²à³ à²žà²°à²¿à²¹à³à²à²Šà²¿à²Šà³.}  
+_textlotsdocs_ [l=kn] {à²šà²¿à²®à³à²® à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿à²à³ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³ à²žà²°à²¿à²¹à³à²à²Šà²¿à²µà³.}  
+_textmatches_ [l=kn] {à²¹à³à²à²Šà²Ÿà²£à²¿à²à³ }
+_textbeginsearch_ [l=kn] {à²¶à³à²§à²šà³ à²ªà³à²°à²Ÿà²°à²à²­à²¿à²žà²¿}  
+_textrunquery_ [l=kn] {à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿à²¯à²šà³à²šà³ à²®à³à²à²Šà³à²µà²°à³à²žà³}  
+_textclearform_ [l=kn] {à²šà²®à³à²šà³à²¯à²šà³à²šà³ à²®à³à²à³à²€à²à³à²³à²¿à²žà³}
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=kn] {à²ªà²Šà²à²³à³}  
+_textinfield_ [l=kn] {âŠ à²à³à²·à³à²€à³à²°à²Šà³à²³à²à³}  
+_textfoldstem_ [l=kn] {(à²®à²¡à²¿à²žà³, à²à²Ÿà²à²¡à²µà²Ÿà²à²¿à²žà³)}  
+
+_textadvquery_ [l=kn] {à²
+à²¥à²µ à²šà³à²°à²µà²Ÿà²à²¿ à²ªà³à²°à²¶à³à²šà³à²¯à²šà³à²šà³  à²¬à²°à³à²¯à²¿à²°à²¿}  
+_textallfields_ [l=kn] {à²à²²à³à²²à²Ÿ à²à³à²·à³à²€à³à²°à²à²³à³}  
+_texttextonly_ [l=kn] {à²ªà² à³à²¯ à²®à²Ÿà²€à³à²°}  
+_textand_ [l=kn] {à²®à²€à³à²€à³}  
+_textor_ [l=kn] {à²
+à²¥à²µ}  
+_textandnot_ [l=kn] {à²®à²€à³à²€à³ à²
+à²²à³à²²}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+# the space after "level" (before the right bracket) is required, otherwise no space between "Search" and "in"
+
+_textsimplesearch_ [l=kn] {à²à²²à³à²²à²¿ à²¶à³à²§à²¿à²žà²¿ _indexselection_ _If_( _jselection_à²° à²à³à²€à³ à²žà²à²ªà²°à³à²à²µà²¿à²°à³à²µ _jselection_)_If_(_gselection_,  _gselection_ à²®à²à³à²à²Š )_If_(_nselection_, _nselection_ à²­à²Ÿà²·à³ à²¯à²²à³à²²à²¿ )à²à²Šà²šà³à²šà³ à²à²³à²à³à²à²¡à²¿à²°à³à²µ _querytypeselection_ à² à²ªà²Šà²à²³_If_(_sfselection_,\,_allowformbreak_ à²«à²²à²¿à²€à²Ÿà²à²¶à²à²³à²šà³à²šà³ à² à²ªà³à²°à²à²Ÿà²° à²µà²¿à²à²à²¡à²¿à²žà²¿   _sfselection_)}  
+
+_textadvancedsearch_ [l=kn] {à²à²²à³à²²à²¿  à²¶à³à²§à²¿à²žà²¿  _indexselection_ _If_(_jselection_, _jselection_ )à²š_If_(_gselection_, _gselection_ level )à²šà²²à³à²²à²¿_If_(_nselection_, _nselection_ à²­à²Ÿà²·à³à²¯à²²à³à²²à²¿ ) _querytypeselection_ à²à²ªà²¯à³à²à²¿à²žà²¿ à²ªà³à²°à²¶à³à²šà²¿à²žà²¿}  
+
+_textadvancedmgppsearch_ [l=kn] {à²à²²à³à²²à²¿ à²¶à³à²§à²¿à²žà²¿ _indexselection_ _If_(_jselection_,associated with _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language ), à²®à²€à³à²€à³ à²«à²²à²¿à²€à²Ÿà²à²¶à²à²³à²šà³à²šà³  _formquerytypeadvancedselection_ à² à²ªà³à²°à²à²Ÿà²° à²ªà³à²°à²Šà²°à³à²¶à²¿à²žà²¿}  
+
+_textadvancedlucenesearch_ [l=kn] {à²à²²à³à²²à²¿ à²¶à³à²§à²¿à²žà²¿ _indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ à²«à²²à²¿à²€à²Ÿà²à²¶à²à²³à²šà³à²šà³ _sfselection_\,) à²µà²¿à²à²à²¡à²¿à²žà²¿ }  
+
+# the space after "Search" is required, otherwise no space between "Search" and "in"
+
+_textformsimplesearch_ [l=kn] {à²à²²à³à²²à²¿  à²¶à³à²§à²¿à²žà²¿ _If_(_jselection_, _jselection_)_If_(_gformselection_,  _gformselection_ à²šà²²à³à²²à²¿ à²®à²à³à² )_If_(_nselection_,  _nselection_ à²­à²Ÿà²·à³à²¯à²²à³à²²à²¿)_If_(_sfselection_,\, à²«à²²à²¿à²€à²Ÿà²à²¶à²à²³à²šà³à²šà³ _sfselection_\,) for _formquerytypesimpleselection_ à² à²ªà³à²°à²à²Ÿà²° à²µà²¿à²à²à²¡à²¿à²žà²¿}  
+
+_textformadvancedsearchmgpp_ [l=kn] {à²à²²à³à²²à²¿  à²¶à³à²§à²¿à²žà²¿ _If_(_jselection_,_jselection_ )_If_(_gformselection_, _gformselection_ level )à²šà²²à³à²²à²¿_If_(_nselection_, _nselection_ à²­à²Ÿà²·à³à²¯à²²à³à²²à²¿ )à²®à²€à³à²€à³ à²«à²²à²¿à²€à²Ÿà²à²¶à²à²³à²šà³à²šà³  _formquerytypeadvancedselection_ à² à²ªà³à²°à²à²Ÿà²° à²µà²¿à²à²à²¡à²¿à²žà²¿:}  
+
+_textformadvancedsearchlucene_ [l=kn] {à²à²²à³à²²à²¿  à²¶à³à²§à²¿à²žà²¿ _If_(_jselection_, _jselection_)_If_(_gformselection_,  _gformselection_ level )à²šà²²à³à²²à²¿_If_(_nselection_,  _nselection_ à²®à²€à³à²€à³ à²­à²Ÿà²·à³)_If_(_sfselection_,\, à²«à²²à²¿à²€à²Ÿà²à²¶à²à²³à²šà³à²šà³  _sfselection_\,) à² à²ªà³à²°à²à²Ÿà²° à²µà²¿à²à²à²¡à²¿à²žà²¿ }  
+
+_textnojsformwarning_ [l=kn] {à²à²à³à²à²°à²¿à²à³: à²šà²¿à²®à³à²® à²µà³à²¬à³âà²¬à³à²°à³à²žà²°à³âà²šà²²à³à²²à²¿ à²à²Ÿà²µà²žà³à²à³à²°à²¿à²ªà³à²à³â à²šà²¿à²·à³à²à³à²°à²¿à²¯à²µà²Ÿà²à²¿à²Šà³.<br>à²¶à³à²§à²šà³ à²šà²®à³à²šà³à²¯à²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²²à³ à²Šà²¯à²µà²¿à²à³à²à³ à²à²Ÿà²µà²žà³à²à³à²°à²¿à²ªà³à²à³âà²šà³à²šà³ à²žà²à³à²°à²¿à²¯à²à³à²³à²¿à²žà²¿}  
+_textdatesearch_ [l=kn] {à² à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²à²à²Šà³ à²Šà²¿à²šà²Ÿà²à²à²Š à²¶à³à²°à³à²£à²¿à²¯à³à²³à²à³ à²à²°à³à²µ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²¿à²à²Ÿà²à²¿ à²
+à²¥à²µà²Ÿ à²šà²®à³à²Šà²¿à²žà²¿à²Š à²Šà²¿à²šà²Ÿà²à²à²µà²šà³à²šà³ à²¹à³à²à²Šà²¿à²°à³à²µ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²¿à²à²Ÿà²à²¿ à²¶à³à²§à²¿à²žà²¬à²¹à³à²Šà³. à²à²Šà³ à²¶à³à²§à²šà³à²¯à²²à³à²²à³à²Šà²à³à²µ à²à²à³à²à²¿à² à²žà³à²²à²­à³à²¯}  
+_textstartdate_ [l=kn] {à²Šà²¿à²šà²Ÿà²à²à²Šà²¿à²à²Š (à²
+à²¥à²µ à²®à²Ÿà²€à³à²°)à²ªà³à²°à²Ÿà²°à²à²¬à²¿à²žà³:}  
+_textenddate_ [l=kn] {à²à³à²šà³à²¯ à²Šà²¿à²šà²Ÿà²à²:}  
+_textbc_ [l=kn] {B.C.E.}  
+_textad_ [l=kn] {C.E.}  
+_textexplaineras_ [l=kn] {C.E. à²®à²€à³à²€à³ B.C.E à²¯à³ à²
+à²šà³à²à³à²°à²®à²µà²Ÿà²à²¿ A.D. à²®à²€à³à²€à³ B.C à²¯ à²¬à²Šà²²à²¿à²à³ à²à²ªà²¯à³à²à²µà²Ÿà²à³à²€à³à²€à²¿à²µà³. à² à²ªà²Šà²à²³à³ à²¯à²Ÿà²µà³à²Šà³ à²à²à²Šà³ à²žà²à²žà³à²à³à²€à²¿à²à³ à²žà³à²®à²¿à²€à²µà²Ÿà²à²Šà³, "à²žà²Ÿà²®à²Ÿà²šà³à²¯ à²à²Ÿà²²à²®à²Ÿà²š" à²®à²€à³à²€à³ "à²žà²Ÿà²®à²Ÿà²šà³à²¯ à²à²Ÿà²²à²®à²Ÿà²šà²Š à²¹à²¿à²à²Šà²¿à²š à²à²Ÿà²²à²®à²Ÿà²š" à²à²³à²šà³à²šà³ à²šà²®à³à²Šà²¿à²žà³à²€à³à²€à²µà³}  
+
+_textstemon_ [l=kn] {(à²ªà²Šà²à²³ à²à³à²šà³à²¯à²šà³à²šà³ à²à²¡à³à²à²£à²¿à²žà²¿)}
+
+_textsearchhistory_ [l=kn] {à²¶à³à²§à²šà³à²¯ à²à²°à²¿à²€à³à²°à³}  
+
+#text macros for search history
+_textnohistory_ [l=kn] {à²¶à³à²§à²šà³à²¯ à²à²°à²¿à²€à³à²°à³à²¯à²²à³à²²à²¿ à²¯à²Ÿà²µà³à²Šà³ à²Šà²Ÿà²à²²à³à²à²³à²¿à²²à³à²²}  
+_texthresult_ [l=kn] {à²«à²²à²¿à²€à²Ÿà²à²¶}  
+_texthresults_ [l=kn] {à²«à²²à²¿à²€à²Ÿà²à²¶à²à²³à³}  
+_texthallwords_ [l=kn] {à²à²²à³à²²à²Ÿ à²ªà²Šà²à²³à³}  
+_texthsomewords_ [l=kn] {à²à³à²²à²µà³ à²ªà²Šà²à²³à³}  
+_texthboolean_ [l=kn] {à²¬à³à²²à²¿à²¯à²šà³}  
+_texthranked_ [l=kn] {à²¶à³à²°à³à²£à³à²à³à²€}  
+_texthcaseon_ [l=kn] {à²Šà³à²¡à³à²¡ à²®à²€à³à²€à³ à²žà²£à³à²£ à²
+à²à³à²·à²°à²à²³à³ à²¹à³à²à²Šà²Ÿà²£à²¿à²à³à²¯à²Ÿà²à²¬à³à²à³}  
+_texthcaseoff_ [l=kn] {à²
+à²à³à²·à²°à²à²³ à²®à²¡à²¿à²à³}  
+_texthstemon_ [l=kn] {à²®à³à²à²à³à²à³à²³à²¿à²žà²¿à²Š}  
+_texthstemoff_ [l=kn] {à²®à³à²à²à³à²à³à²³à²¿à²žà²Š}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=kn] {à²à²Šà³à²¯à²€à³à²à²³à²šà³à²šà³ à² à²°à³à²€à²¿à²¯à²²à³à²²à²¿ à²šà²¿à²à²Šà²¿à²žà²²à²Ÿà²à²¿à²Šà³: à²šà²¿à²®à³à²® à²¬à³à²°à³à²žà²°à³âà²š à²¹à²¿à²à²Šà²¿à²š ( "back")à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¬à³à²¡à²¿ - à²¹à²Ÿà²à³ à²®à²Ÿà²¡à³à²µà³à²Šà²°à²¿à²à²Š à²šà²¿à²à²Šà²¿à²€ à²à²Šà³à²¯à²€à³à²à²³à³ à²¬à²Šà²²à²Ÿà²à³à²€à³à²€à²µà³; à²
+à²Šà²° à²¬à²Šà²²à³ à²
+à²à³à²žà³à²žà³ââà²¬à²Ÿà²°à³âà²š à²®à³à²²à²¿à²°à³à²µ à²à³à²à²¡à²¿à²à²³à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿}  
+_textsetprefs_ [l=kn] {à²à²§à³à²¯à²€à³à²¯à²šà³à²šà³ à²šà²¿à²¶à³à²à²¯à²¿à²žà²¿}
+_textsearchprefs_ [l=kn] {à²à²§à³à²¯à²€à³à²¯ à²¶à³à²§à²šà³à²à²³à³}  
+_textcollectionprefs_ [l=kn] {à²žà²à²à³à²°à²¹à²Š à²à²Šà³à²¯à²€à³à²à²³à³}  
+_textpresentationprefs_ [l=kn] {à²à²Šà³à²¯à²€à³à²à²³à²šà³à²šà³ à²šà²¿à²à²Šà²¿à²žà²¿}  
+_textpreferences_ [l=kn] {à²à²Šà³à²¯à²€à³à²à²³à³}  
+_textcasediffs_ [l=kn] {à²Šà³à²¡à³à²¡ à²®à²€à³à²€à³ à²žà²£à³à²£ à²
+à²à³à²·à²°à²à²³ à²µà³à²¯à²€à³à²¯à²Ÿà²žà²à²³à³:}  
+_textignorecase_ [l=kn] {à²Šà³à²¡à³à²¡ à²®à²€à³à²€à³ à²žà²£à³à²£ à²
+à²à³à²·à²°à²à²³ à²µà³à²¯à²€à³à²¯à²Ÿà²žà²à²³à²šà³à²šà³ à²à²¡à³à²à²£à²¿à²žà³}  
+_textmatchcase_ [l=kn] {à²Šà³à²¡à³à²¡/à²žà²£à³à²£ à²
+à²à³à²·à²°à²à²³à³ à²¹à³à²à²Šà²Ÿà²£à²¿à²à³à²¯à²Ÿà²à²¬à³à²à³}  
+_textwordends_ [l=kn] {à²ªà²Šà²à²³ à²à³à²šà³:}
+_textstem_ [l=kn] {à²ªà²Šà²à²³ à²à³à²šà³à²¯à²šà³à²šà³ à²à²¡à³à²à²£à²¿à²žà³}
+_textnostem_ [l=kn] {à²žà²®à²žà³à²€ à²ªà²Šà²à²³à³ à²¹à³à²à²Šà²¿à²à³à²¯à²Ÿà²à²¬à³à²à³}  
+_textaccentdiffs_ [l=kn] {à²à²€à³à²€à²à³à²·à²° à²µà³à²¯à²€à³à²¯à²Ÿà²ž:}  
+_textignoreaccents_ [l=kn] {à²à²€à³à²€à²à³à²·à²°à²à²³à²šà³à²šà³ à²à²¡à³à²à²£à²¿à²žà³}  
+_textmatchaccents_ [l=kn] {à²ªà³à²°à³à²£ à²ªà²Š à²¹à³à²à²Šà²¿à²à³à²¯à²Ÿà²à²¬à³à²à³}  
+
+_textprefop_ [l=kn] {à²ªà³à²°à²€à²¿ à²ªà³à²à²à³à²à³ _maxdocoption_ à²«à²²à²¿à²€à²Ÿà²à²¶à²à²³à²à²€à³_hitsperpageoption_ à²¹à²¿à²à²€à²¿à²°à³à²à²¿à²žà³.}
+_textextlink_ [l=kn] {à²¹à³à²°à²à²¿à²š à²µà³à²¬à³â à²ªà³à²à²à²³à²¿à²à³ à²žà²à²ªà²°à³à²: }  
+_textintlink_ [l=kn] {à²à²Šà²°à²¿à²à²Š à²®à³à²²à²ªà³à²°à²€à²¿à²à²³à²šà³à²šà³ à²ªà²¡à³à²¯à²²à²Ÿà²à²¿à²Šà³:}
+_textlanguage_ [l=kn] {à²žà²à²ªà²°à³à² à²­à²Ÿà²·à³: }  
+_textencoding_ [l=kn] {à²à²šà³ à²à³à²¡à²¿à²à²à³: }
+_textformat_ [l=kn] {à²žà²à²ªà²°à³à² à²®à²Ÿà²§à³à²¯à²®: }  
+_textall_ [l=kn] {à²à²²à³à²²à²Ÿ}
+_textquerymode_ [l=kn] {à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿ à²°à³à²€à²¿:}
+_textsimplemode_ [l=kn] {à²žà²°à²³ à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿ à²°à³à²€à²¿}
+_textadvancedmode_ [l=kn] {à²ªà²°à²¿à²£à²¿à²€ à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿ à²°à³à²€à²¿ (à²¬à³à²²à²¿à²¯à²šà³â à²¶à³à²§à²šà³à²¯à²šà³à²šà³ à²à²³à²à³à²à²¡à²à²€à³)}  
+_textlinkinterm_ [l=kn] {à²®à²§à³à²¯à²à²€à²° à²ªà³à²à²Š à²®à³à²à²Ÿà²à²€à²°}  
+_textlinkdirect_ [l=kn] {à²
+à²²à³à²²à²¿à²à³ à²šà³à²°à²µà²Ÿà²à²¿ à²¹à³à²à³}
+_textdigitlib_ [l=kn] {à²¡à²¿à²à²¿à²à²²à³ à²à³à²°à²à²¥à²Ÿà²²à²¯}
+_textweb_ [l=kn] {à²µà³à²¬à³}
+_textgraphical_ [l=kn] {à²žà²à²¿à²€à³à²°à²µà²Ÿà²à²¿}
+_texttextual_ [l=kn] {à²®à³à²² à²ªà² à³à²¯}  
+_textcollectionoption_ [l=kn] {<p>à²à²ªà²žà²à²à³à²°à²¹à²£à³à²à²³à³ à²à²µà²šà³à²šà³ à²à²³à²à³à²à²¡à²¿à²µà³: <br>}  
+
+_textsearchtype_ [l=kn] {à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿ à²ªà²Šà³à²§à²€à²¿}  
+_textformsearchtype_ [l=kn] {à²à³à²·à³à²€à³à²°à²Šà²¿à²à²Š  _formnumfieldoption_ à²à³à²·à³à²€à³à²°à²à²³à³}  
+_textplainsearchtype_ [l=kn] {à²žà²Ÿà²§à²Ÿà²°à²£à²Šà²¿à²à²Š _boxsizeoption_ à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿à²¯ à²ªà³à²à³à²à²¿à²à³}  
+_textregularbox_ [l=kn] {à²à²à²Šà³ à²žà²Ÿà²²à³}  
+_textlargebox_ [l=kn] {à²Šà³à²¡à³à²¡à²Šà³}  
+
+_textrelateddocdisplay_ [l=kn] {à²žà²à²¬à²à²§à²¿à²žà²¿à²Š à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²ªà³à²°à²Šà²°à³à²¶à²¿à²žà³}  
+_textsearchhistory_ [l=kn] {à²¶à³à²§à²šà³à²¯ à²à²°à²¿à²€à³à²°à³:}  
+_textnohistory_ [l=kn] {à²¶à³à²§à²šà³à²¯ à²à²°à²¿à²€à³à²°à³ à²à²²à³à²²}  
+_texthistorydisplay_ [l=kn] {à²¶à³à²§à²šà³à²¯ à²à²°à²¿à²€à³à²°à³à²¯ à²Šà²Ÿà²à²²à³à²à²³à²šà³à²šà³ _historynumrecords_à²ªà³à²°à²Šà²°à³à²¶à²¿à²žà³}  
+_textnohistorydisplay_ [l=kn] {à²¶à³à²§à²šà³à²¯ à²à²°à²¿à²€à³à²°à³à²¯à²šà³à²šà³ à²ªà³à²°à²Šà²°à³à²¶à²¿à²žà²¬à³à²¡}  
+
+_textbookoption_ [l=kn] {à²ªà³à²žà³à²€à² à²µà³à²à³à²·à²¿à²žà³à²µà²° à²ªà²Šà³à²§à²€à²¿:}  
+_textbookvieweron_ [l=kn] {à²€à³à²à³}  
+_textbookvieweroff_ [l=kn] {à²à²°à²¿à²žà³}  
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=kn] {à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²¯à²¿à²à²Š à²µà²¿à²à²à²¡à²¿à²žà²¿}  
+_textalsoshowing_ [l=kn] {à²žà²¹ à²€à³à²°à²¿à²žà³à²€à³à²€à²¿à²Šà³}  
+_textwith_ [l=kn] {à²à²°à²¿à²·à³à² }  
+_textdocsperpage_ [l=kn] {à²ªà³à²°à²€à²¿ à²ªà³à²à²à³à²à³ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³}  
+
+_textfilterby_ [l=kn] {à²à²³à²à³à²à²¡à²¿à²°à³à²µ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²ªà²¡à³}  
+_textall_ [l=kn] {à²à²²à³à²²à²Ÿ}  
+_textany_ [l=kn] {à²¯à²Ÿà²µà³à²Šà²Ÿà²Šà²°à³}  
+_textwords_ [l=kn] {à² à²ªà²Šà²à²³}  
+_textleaveblank_ [l=kn] {à²à²²à³à²²à²Ÿ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²ªà²¡à³à²¯à²²à³ à² à²ªà³à²à³à²à²¿à²à³à²¯à²šà³à²šà³ à²à²Ÿà²²à²¿ à²¬à²¿à²¡à²¿}  
+
+_browsebuttontext_ [l=kn] {"à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²µà²¿à²à²à²¡à²¿à²žà²¿"}  
+
+_nodata_ [l=kn] {<i>à²Šà²€à³à²€ à²à²²à³à²²</i>}  
+_docs_ [l=kn] {à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=kn] {à²žà²¹à²Ÿà²¯}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=kn] {_1_à²°à²¿à²à²Š à²Šà²žà³à²€à²Ÿà²µà³à²à³à²µà²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿  _2_ à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà³à²µà³à²Šà²° à²®à³à²²à² }  
+
+_textSearchhelp_ [l=kn] {_labelSearch_à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²²à³à²²à²¿à²°à³à²µ à²ªà²Šà²à²³à²šà³à²šà³ à²¶à³à²§à²¿à²žà²¿}  
+_textTohelp_ [l=kn] {_labelTo_ à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿ 'à²à³' à²à³à²·à³à²€à³à²°à²Š à²ªà³à²°à²à²Ÿà²° à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}  
+_textFromhelp_ [l=kn] {_labelFrom_à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿ 'à²¯à²¿à²à²Š' à²à³à²·à³à²€à³à²°à²Š à²ªà³à²°à²à²Ÿà²° à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}  
+_textBrowsehelp_ [l=kn] {à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}  
+_textAcronymhelp_ [l=kn] {_labelAcronym_ à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿ à²žà²à²à³à²·à²¿à²ªà³à²€à²°à³à²ª à²¹à³à²à²Šà²¿à²°à³à²µ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}  
+_textPhrasehelp_ [l=kn] {_labelPhrase_ à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²²à³à²²à²¿à²°à³à²µ à²ªà²Šà²à³à²à³à²à²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}  
+
+_texthelptopicstitle_ [l=kn] {à²žà²¹à²Ÿà²¯à²Š à²µà²¿à²·à²¯à²à²³à³}
+
+_textreadingdocs_ [l=kn] {à²Šà²Ÿà²à²²à³à²à²³à²šà³à²šà³ à²¹à³à²à³ à²à²Šà³à²µà³à²Šà³}
+
+_texthelpreadingdocs_ [l=kn] {<p> à²šà²¿à²®à³à²® à²¶à³à²§à²šà³ à²šà²¿à²®à³à²®à²šà³à²šà³ à²à²à²Šà³ à²ªà³à²°à²€à³à²¯à³à² à²Šà²žà³à²€à²Ÿà²µà³à²à²¿à²à³ à²®à³à²à³à²à²¿à²žà²¿à²Šà²°à³ à²
+à²Šà²šà³à²šà³ à²šà³à²µà³ à²€à²à³à²·à²£ à²à³à²°à³à²€à²¿à²žà²¬à²¹à³à²Šà³. à²¹à³à²à³à²à²Šà²°à³ à²
+à²Šà²° à²¶à³à²°à³à²·à²¿à²à³ à²
+à²¥à²µà²Ÿ à²ªà³à²žà³à²€à²à²Š à²¹à³à²°à²à²µà²à²Š à²žà³à²à³à²·à³à²® à²à²¿à²€à³à²° à²ªà³à²à²Š à²®à³à²²à³ à²à²¡à²Š à²­à²Ÿà²à²Šà²²à³à²²à²¿à²°à³à²€à³à²€à²Šà³. à²à³à²²à²µà³ à²žà²à²à³à²°à²¹à²à²³à²²à³à²²à²¿ à²µà²¿à²·à²¯ à²žà³à²à²¿ à²ªà³à²°à²Šà²°à³à²¶à²¿à²€à²µà²Ÿà²à³à²€à³à²€à²Šà³; à²®à²€à³à²€à³ à²à³à²²à²µà³ à²žà²à²à³à²°à²¹à²à²³à²²à³à²²à²¿ à²ªà³à²à²Š à²žà²à²à³à²¯à³ à²à²°à³à²€à³à²€à²Šà³;   à²ªà³à²°à²à²²à²¿à²€ à²
+à²¥à²µà²Ÿ à²¬à³à²°à³ à²¯à²Ÿà²µà³à²Šà³ à²ªà³à²à²à³à²à³ à²¹à³à²à²²à³ à²žà²Ÿà²§à³à²¯à²µà²Ÿà²à³à²€à³à²€à²Šà³. à²µà²¿à²·à²¯ à²žà³à²à²¿ à²ªà³à²°à²Šà²°à³à²¶à²¿à²€à²µà²Ÿà²à²¿à²°à³à²µà²Ÿà² à²ªà³à²°à²à²²à²¿à²€ à²µà²¿à²­à²Ÿà² à²¶à³à²°à³à²·à²¿à²à³à²¯à³ à²à²€à³à²€à²¿à²€à³à²°à²¿à²µà²à²€à³ à²à²°à³à²€à³à²€à²Šà³ à²¹à²Ÿà²à³ à²µà²¿à²·à²¯ à²žà³à²à²¿à²¯à²šà³à²šà³ à²à²¡à²€à²à²à³à²à³à²à²³à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà³à²µà³à²Šà²° à²®à³à²²à² à²µà²¿à²žà³à²€à²Ÿà²°à²à³à²³à²¿à²žà²¬à²¹à³à²Šà³. à²®à³à²²à³ à²€à³à²à³à²Šà²¿à²°à³à²µ à²ªà³à²žà³à²€à²à²µà²šà³à²šà³ à²
+à²Šà²° à²®à³à²²à³ à²à³à²²à²¿à²à³à²à²¿à²žà³à²µà³à²Šà²° à²®à³à²²à² à²®à³à²à³à²à²¬à²¹à³à²Šà³</p>
+
+<p> à²à³à²³à²à³ à²ªà³à²°à²à²²à²¿à²€ à²­à²Ÿà²à²Š à²ªà² à³à²¯à²µà²¿à²°à³à²€à³à²€à²Šà³.à²šà³à²µà³ à²
+à²Šà²šà³à²šà³ à²à²Šà²¿à²Šà²šà²à²€à²° à²
+à²²à³à²²à²¿à²°à³à²µ à²¬à²Ÿà²£à²Š à²à³à²°à³à²€à²¿à²š à²à²¿à²¹à³à²šà³à²à²³à²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¿ à²®à³à²à²Šà²¿à²š à²
+à²¥à²µà²Ÿ à²¹à²¿à²à²Šà²¿à²š à²­à²Ÿà²à²à³à²à³ à²¹à³à²à²¬à²¹à³à²Šà³.</p>
+
+<p> à²¶à³à²°à³à²·à²¿à²à³ à²
+à²¥à²µà²Ÿ à²ªà³à²žà³à²€à²à²Š à²¹à³à²°à²à²µà²à²Š à²žà³à²à³à²·à³à²® à²à²¿à²€à³à²°à²Š à²à³à²³à²à³ à²à³à²²à²µà³ à²à³à²à²¡à²¿à²à²³à²¿à²µà³.  <i>_document:textEXPANDTEXT_</i> à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³ à²®à²Ÿà²¡à²¿ à²ªà³à²°à²à²²à²¿à²€ à²­à²Ÿà²à²Š à²
+à²¥à²µà²Ÿ à²ªà³à²žà³à²€à²à²Š à²ªà³à²°à³à²£ à²ªà²Ÿà² à²µà²šà³à²šà³ à²šà³à²¡à²¬à²¹à³à²Šà³. à²à²à²Šà³ à²µà³à²³à³ à²Šà²žà³à²€à²Ÿà²µà³à²à³ à²€à³à²à²¬ à²Šà³à²¡à³à²¡à²Šà²¿à²Šà³à²Šà²²à³à²²à²¿ à²
+à²Šà³ à²¬à²¹à²³ à²žà²®à²¯ à²€à³à²à³à²Šà³à²à³à²³à³à²³à²¬à²¹à³à²Šà³. <i>_document:textEXPANDCONTENTS_</i> à²
+à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿ à²µà²¿à²·à²¯ à²žà³à²à²¿à²¯à²šà³à²šà³ à²µà²¿à²žà³à²€à²Ÿà²°à²à³à²³à²¿à²žà²¬à²¹à³à²Šà³ à²®à²€à³à²€à³ à²à²²à³à²² à²
+à²§à³à²¯à²Ÿà²¯ à²®à²€à³à²€à³ à²à²ªà²µà²¿à²­à²Ÿà²à²à²³ à²¶à³à²°à³à²·à²¿à²à³à²à²³à²šà³à²šà³ à²šà³à²µà³ à²šà³à²¡à²¬à²¹à³à²Šà³. <i>_document:textDETACH_</i> à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³â à²®à²Ÿà²¡à²¿à²Šà²°à³ à²ªà³à²°à²à²²à²¿à²€ à²ªà³à²žà³à²€à² à²¹à³à²ž à²à²¿à²à²à²¿à²¯à²²à³à²²à²¿ à²€à³à²°à³à²Šà³à²à³à²³à³à²³à³à²€à³à²€à²Šà³(à²à²Šà³ à²à²°à²¡à³ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²¹à³à²²à²¿à²žà²¿, à²à²°à²¡à²šà³à²šà³ à²à²à³à²à²¿à²à³ à²à²Šà²²à³ à²žà²¹à²Ÿà²¯à²µà²Ÿà²à³à²€à³à²€à²Šà³.)à²
+à²à²€à²¿à²®à²µà²Ÿà²à²¿ à²šà³à²µà³ à²à²ªà²¯à³à²à²¿à²žà²¿à²Š à²¶à³à²§à²šà²Ÿ à²ªà²Šà²à²³à³ à²šà²¿à²®à³à²® à²¶à³à²§à²šà³à²¯à²²à³à²²à²¿ à²¹à³à²²à³à²à³ à²à²à²¿à²°à³à²€à³à²€à²Šà³. à²šà²¿à²®à²à³ à²¹à³à²²à³à²à³ à²¬à³à²¡à²Šà²¿à²Šà³à²Šà²²à³à²²à²¿<i> _document:textNOHIGHLIGHT_ </i> à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³ à²®à²Ÿà²¡à²¿.</p>}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=kn] {à²ªà³à²žà³à²€à²à²Š à²à²ªà²Ÿà²à²šà³à²šà³ à²€à³à²à³}
+_texthelpopenbook_ [l=kn] {à²ªà³à²žà³à²€à²à²µà²šà³à²šà³ à²®à³à²à³à²à³ à²
+à²¥à²µà²Ÿ à²€à³à²°à³}  
+_texthelpviewtextsection_ [l=kn] {à²ªà² à³à²¯à²Š à² à²­à²Ÿà²à²µà²šà³à²šà³ à²šà³à²¡à²¿}
+_texthelpexpandtext_ [l=kn] {à²à²²à³à²²à²Ÿ à²ªà² à³à²¯à²µà²šà³à²šà³ à²ªà³à²°à²Šà²°à³à²¶à²¿à²žà³,à²
+à²¥à²µà²Ÿ à²¬à³à²¡}
+_texthelpexpandcontents_ [l=kn] {à²ªà²°à²¿à²µà²¿à²¡à²¿à²¯à²šà³à²šà³ à²µà²¿à²žà³à²€à²Ÿà²°à²µà²Ÿà²à²¿à²žà³ à²
+à²¥à²µà²Ÿ à²µà²¿à²žà³à²€à²°à²¿à²žà²Šà²¿à²°à³}
+_texthelpdetachpage_ [l=kn] {à² à²ªà³à²à²µà²šà³à²šà³ à²à²à²Šà³ à²šà²µà³à²š à²µà²¿à²à²¡à³à²µà²¿à²šà²²à³à²²à²¿ à²€à³à²à³}  
+_texthelphighlight_ [l=kn] {à²¶à³à²§à²¿à²žà²¿à²Š à²ªà²Šà²à²³à²šà³à²šà³ à²à²€à³à²€à²¿ à²€à³à²°à²¿à²žà²¬à³à²à³ à²à²²à³à²²à²µà³}  
+_texthelpsectionarrows_ [l=kn] {à²¹à²¿à²à²Šà²¿à²š à²
+à²¥à²µà²Ÿ à²®à³à²à²Šà²¿à²š à²­à²Ÿà²à²à³à²à³ à²¹à³à²à³}
+
+
+_texthelpsearchingtitle_ [l=kn] {à²šà²¿à²°à³à²Šà²¿à²·à³à² à²ªà²Šà²à²³à²šà³à²šà³ à²¹à³à²à³ à²¶à³à²§à²¿à²žà³à²µà³à²Šà³}  
+
+_texthelpsearching_ [l=kn] {<p> à²¶à³à²§à²šà³à²¯ à²ªà³à²à²Šà²²à³à²²à²¿ à²šà²¿à²®à³à²® à²ªà³à²°à²¶à³à²šà³à²¯à²šà³à²šà³ à²žà²°à²³à²µà²Ÿà²à²¿ à² à²¹à²à²€à²à²³à²²à³à²²à²¿ à²žà³à²·à³à²à²¿à²žà²¿:<p>
+  <ol><li>à²¯à²Ÿà²µ à²¬à²à³à²¯ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²¶à³à²§à²¿à²žà²¬à³à²à³à²à²Šà³ à²šà²®à³à²Šà²¿à²žà²¿
+      <li>à²šà²¿à²®à³à²® à²ªà³à²°à²¶à³à²šà³à²¯ à²à²²à³à²²à²Ÿ à²
+à²¥à²µà²Ÿ à²à³à²²à²µà³ à²ªà²Šà²à²³à²šà³à²šà³ à²®à²Ÿà²€à³à²°à²µà³ à²¶à³à²§à²¿à²žà²¬à³à²à³ à²à²à²Šà³ à²€à²¿à²³à²¿à²žà²¿
+      <li>à²¶à³à²§à²¿à²žà²¬à³à²à²Ÿà²Š à²ªà²Šà²à²³à²šà³à²šà³ à²à³à²ªà³ à²®à²Ÿà²¡à²¿
+      <li>à²¶à³à²§à²šà³ à²à²°à²à²­à²¿à²žà³<i>à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³ à²®à²Ÿà²¡à²¿</i>
+  </ol>
+
+  <p>à²šà²¿à²®à³à²® à²ªà³à²°à²¶à³à²šà³à²à³ à²žà²à²¬à²à²§à²¿à²žà²¿à²Š à²®à³à²Šà²² à²à²ªà³à²ªà²€à³à²€à³ à²Šà²Ÿà²à²²à³à²à²³à²šà³à²šà³ à²€à³à²°à²¿à²žà²²à²Ÿà²à³à²€à³à²€à²Šà³. à²®à³à²à²Šà²¿à²š à²à²ªà³à²ªà²€à³à²€à³ à²Šà²Ÿà²à²²à³à²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²²à³ à²ªà³à²à²Š à²à³à²šà³à²¯à²²à³à²²à²¿à²°à³à²µ à²à³à²à²¡à²¿à²à²³à³ à²žà²¹à²Ÿà²¯ à²®à²Ÿà²¡à³à²€à³à²€à²µà³.à² à²à³à²à²¡à²¿à²à²³à²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¿ à²®à²€à³à²€à³ à²®à³à²à²Šà²¿à²°à³à²µ
+à²
+à²¥à²µà²Ÿ à²¹à²¿à²à²Šà²¿à²š à²Šà²Ÿà²à²²à³à²à²³à²šà³à²šà²Ÿà²à²²à²¿ à²µà³à²à³à²·à²¿à²žà²¬à²¹à³à²Šà³. à²šà³à²µà³ à²ªà³à²°à³à²£à²Šà²Ÿà²à²²à³à²¯à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²²à³ à²¶à³à²°à³à²·à²¿à²à³ à²®à³à²²à²Ÿà²à²²à²¿
+à²
+à²¥à²µà²Ÿ à²
+à²Šà²° à²®à³à²à²Šà²¿à²°à³à²µ à²à²¿à²¹à³à²šà³à²¯à²šà³à²šà²Ÿà²à²²à²¿ à²à³à²²à²¿à²à³â à²®à²Ÿà²¡à²¿.
+
+<p>à²¹à³à²à³à²à³à²à²Šà²°à³ 50 à²«à²²à²¿à²€à²Ÿà²à²¶à²à²³à²šà³à²šà³ à²¹à²¿à²à²€à²¿à²°à³à²à²¿à²žà²²à²Ÿà²à³à²€à³à²€à²Šà³, à² à²®à²¿à²€à²¿à²¯à²šà³à²šà³ à²šà³à²µà³  _Global:linktextPREFERENCES_ à²à³à²²à²¿à²à³à²à²¿à²žà³à²µà³à²Šà²°à²®à³à²²à² à²à²¯à³à²à³à²à²³ à²ªà³à²à²Šà²²à³à²²à²¿ à²¬à²Šà²²à²¿à²žà²¬à²¹à³à²Šà³.<p>
+}  
+
+_texthelpquerytermstitle_ [l=kn] {à²¶à³à²§à²šà³à²¯ à²ªà²Šà²à²³à³}  
+_texthelpqueryterms_ [l=kn] {<p>à²šà³à²µà³ à²ªà³à²°à²¶à³à²šà³ à²ªà³à²à³à²à²¿à²à³à²¯à²²à³à²²à²¿ à²à²šà²Ÿà²Šà²°à³ à²¬à²°à³à²Šà²°à³ à²
+à²Šà³ "à²¶à³à²§à²šà²Ÿ à²ªà²Š"à²à²³à³à²à²Šà³  à²ªà²°à²¿à²à²£à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à²µà³. à²à²à²Šà³ "à²¶à³à²§à²šà²Ÿ à²ªà²Š" à²
+à²à³à²·à²°à²à²³à²¿à²à²Š à²
+à²¥à²µà²Ÿ à²
+à²à²à²¿à²à²³à²¿à²à²Š à²à³à²¡à²¿à²°à³à²€à³à²€à²Šà³. à² à²ªà²Šà²à²³à²šà³à²šà³ à²à²Ÿà²²à²¿ à²à²Ÿà²à²Šà²¿à²à²Š à²¬à³à²°à³à²ªà²¡à²¿à²žà²²à²Ÿà²à²¿à²°à³à²€à³à²€à²Šà³. à²à²µà²²à³à²²à²Šà³ à²¬à³à²°à³ à²¯à²Ÿà²µ à²µà²¿à²·à³à²¶ à²
+à²à³à²·à²°à²à²³à³ (à².à²Šà²Ÿ. à²µà²¿à²°à²Ÿà²® à²à²¿à²¹à³à²šà³à²à²³à³) à²¬à²à²Šà²²à³à²²à²¿ à²
+à²µà³à²à²³à²šà³à²šà³ à²à²Ÿà²²à²¿ à²à²Ÿà²à²µà³à²à²Šà³ à²ªà²°à²¿à²à²£à²¿à²žà²¿ à²
+à²µà²šà³à²šà³ à²à²¡à³à²à²£à²¿à²žà²²à²Ÿà²à³à²€à³à²€à²Šà³. à²šà³à²µà³ à²µà²¿à²°à²Ÿà²® à²à²¿à²¹à³à²šà³à²à²³à²šà³à²šà³ à²¹à³à²à²Šà²¿à²°à³à²µ "à²¶à³à²§à²šà²Ÿ à²ªà²Š"à²à²³à²šà³à²šà³ à²¶à³à²§à²¿à²žà²²à³ à²à²à³à²µà³à²Šà²¿à²²à³à²²!
+
+<p> à²à²Šà²Ÿà²¹à²°à²£à³à²à³: à²  à²ªà³à²°à²¶à³à²šà³<p>
+<ul><kbd> à²«à³à²žà²¿à²«à²¿à²à³ à²Šà³à²µà³à²ªà²à²³à²²à³à²²à²¿ à²à²à³à²°à³-à²«à²Ÿà²°à³à²žà³à²à³à²°à²¿: à²žà²à²°à²à³à²·à²£à³ à²®à²Ÿà²¡à³à²µ à²ªà²Šà³à²Šà²€à²¿(1993)</kbd></ul>
+<p>à²à²Šà²šà³à²šà³<p>
+<ul><kbd> à²«à³à²žà²¿à²«à²¿à²à³ à²Šà³à²µà³à²ªà²à²³à²²à³à²²à²¿ à²à²à³à²°à³ à²«à²Ÿà²°à³à²žà³à²à³à²°à²¿ à²žà²à²°à²à³à²·à²£à³ à²®à²Ÿà²¡à³à²µ à²ªà²Šà³à²Šà²€à²¿ 1993</kbd></ul><p>
+à²à²à²Šà³ à²ªà²°à²¿à²à²£à²¿à²žà²²à²Ÿà²à³à²€à³à²€à²Šà³}  
+
+_texthelpmgppsearching_ [l=kn] {à²à²à²à²¿à²ªà²¿à²ªà²¿ à²à²ªà²¯à³à²à²¿à²žà²¿ à²šà²¿à²°à³à²®à²¿à²žà²¿à²Š à²žà²à²à³à²°à²¹à²à²³à²²à³à²²à²¿ à²¬à³à²°à³ à²à³à²²à²µà³ à²žà³à²²à²­à³à²¯à²à²³à³ à²à²µà³.
+<ul> 
+<li>à²à²à²Šà³ à²ªà³à²°à²¶à³à²šà³à²¯/à²
+à²à³à²·à²° à²žà²®à³à²¹à²Š à²à³à²šà³à²¯à²²à³à²²à²¿ <b>*</b> à²¬à²³à²žà²¿ à² à²
+à²à³à²·à²° à²žà²®à³à²¹à²Šà²¿à²à²Š à²à²°à²à²­à²¿à²žà³à²µ à²à²²à³à²² à²ªà²Šà²à²³à²šà³à²šà³ à²¶à³à²§à²¿à²žà²¬à²¹à³à²Šà³. à².à²Šà²Ÿ. <b>comput*</b> <b>comput</b> à²à²à²Š à²¶à³à²°à³à²µà²Ÿà²à³à²µ à²à²²à³à²²à²Ÿ à²ªà²Šà²à²³à²šà³à²šà³à²¹à³à²²à³à²€à³à²€à²Šà³. 
+<li><b>/x</b> à²à²ªà²¯à³à²à²¿à²žà²¿ à²à²à²Šà³ à²
+à²¥à²µà²Ÿ à²¹à³à²à³à²à³ à²ªà³à²°à²¶à³à²šà³ à²ªà²Šà²à²³à²¿à²à³ à²à²à²Šà³ à²¶à³à²§à²šà³à²¯à²²à³à²²à²¿ à²¹à³à²à³à²à³ à²®à³à²²à³à²¯à²µà²šà³à²šà³ à²šà³à²¡à²¬à²¹à³à²Šà³. à².à²Šà²Ÿ. <b>computer/10 science</b> à²¶à³à²§à²šà³à²¯à²²à³à²²à²¿ computer à²ªà²Šà²à³à²à³ science à²ªà²Šà²à³à²à²¿à²à²€ à²¹à²€à³à²€à³à²ªà²à³à²à³ à²¹à³à²à³à²à³ à²®à³à²²à³à²¯ à²à³à²à³à²à³ à² à²ªà³à²°à²à²Ÿà²° à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²¶à³à²°à³à²£à³à²à²°à²¿à²žà³à²€à³à²€à²Šà³.
+</ul>
+}  
+
+_texthelplucenesearching_ [l=kn] {à²²à³à²žà³à²šà³â à²à²ªà²¯à³à²à²¿à²žà²¿ à²šà²¿à²°à³à²®à²¿à²€à²µà²Ÿà²Š à²žà²à²à³à²°à²¹à²à²³à²²à³à²²à²¿ à²¬à³à²°à³ à²à³à²²à²µà³ à²žà³à²²à²­à³à²¯à²à²³à³ à²à²µà³.  <ul>
+<li><b>?</b> à²µà²šà³à²šà³ à²à²à²Šà³ à²
+à²à³à²·à²°à²Š à²¬à²Šà²²à²¿à²à³ à²µà³à²²à³à²¡à³â à²à²Ÿà²°à³à²¡à³â à²à²à²¿ à²à²ªà²¯à³à²à²¿à²žà²¬à²¹à²Šà³. à².à²Šà²Ÿ. <b>b?t</b> <b>bet</b>, <b>bit</b> and <b>bat</b> à²à²€à³à²¯à²Ÿà²Šà²¿ à²à²²à³à²²à²µà²šà³à²šà³ à²¹à³à²²à³à²€à³à²€à²Šà³. 
+<li><b>*</b> à²µà²šà³à²šà³ à²¬à²¹à³ à²
+à²à³à²·à²°à²à²³ à²¬à²Šà²²à²¿à²à³ à²µà³à²²à³à²¡à³â à²à²Ÿà²°à³à²¡à³â à²à²à²¿ à²à²ªà²¯à³à²à²¿à²žà²¬à²¹à²Šà³. à².à²Šà²Ÿ. <b>comput*</b> <b>comput</b> à²à²à²Š à²¶à³à²°à³à²µà²Ÿà²à³à²µ à²à²²à³à²²à²Ÿ à²ªà²Šà²à²³à²šà³à²šà³à²¹à³à²²à³à²€à³à²€à²Šà³ 
+</ul>.
+à² à²à²°à²¡à³ à²µà³à²²à³à²¡à³âà²à²Ÿà²°à³à²¡à³à²à²³à²šà³à²šà³ à²à²à²Šà³ à²ªà²Šà²Š à²šà²¡à³à²µà³ à²
+à²¥à²µà²Ÿ à²à³à²šà³à²¯à²²à³à²²à²¿ à²à²ªà²¯à³à²à²¿à²žà²¬à²¹à³à²Šà³. à²
+à²µà²šà³à²šà³ à²ªà²Šà²Š à²ªà³à²°à²Ÿà²°à²à²­à²Šà²²à³à²²à²¿ à²à²ªà²¯à³à²à²¿à²žà²²à²Ÿà²à²Šà³.}  
+
+_texthelpquerytypetitle_ [l=kn] {à²ªà³à²°à²¶à³à²šà³à²¯ à²®à²Ÿà²Šà²°à²¿}
+_texthelpquerytype_ [l=kn] {<p>à²à²°à²¡à³ à²¬à²à³à²¯ à²ªà³à²°à²¶à³à²šà³à²à²³à²¿à²µà³. 
+
+<ul>
+  <li>à²ªà³à²°à²¶à³à²šà³à²à²³à²²à³à²²à²¿ <b>à²à²²à³à²²à²Ÿ </b>  à²ªà²Šà²à²³à³. 
+  <li>à²à²µà³ à²šà³à²µà³ à²µà²¿à²¶à³à²²à³à²·à²¿à²žà²¿à²Š à²à²²à³à²²à²Ÿ à²ªà²Šà²à²³à²šà³à²šà³  à²¹à³à²à²Šà²¿à²°à³à²µ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²®à²Ÿà²€à³à²° (à²
+à²¥à²µà²Ÿ à²
+à²§à³à²¯à²Ÿà²¯à²à²³à³ à²
+à²¥à²µà²Ÿ à²¶à³à²°à³à²·à²¿à²à³à²à²³à³)   
+
+<p> 
+  <li>à²¹à³à²¡à³à²à³à²€à³à²€à²µà³. à²žà²°à²¿ à²¹à³à²à²Šà³à²µ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²
+à²µà³ à²žà²à²à³à²°à²¹à²à³à²à³ à²Šà²Ÿà²à²²à²Ÿà²Š à²à³à²°à²®à²Šà²²à³à²²à³ à²ªà³à²°à²Šà²°à³à²¶à²¿à²žà³à²€à³à²€à²Šà³. 
+  <li>à²ªà³à²°à²¶à³à²šà³à²à²³à²²à³à²²à²¿* à²à³à²²à²µà³ * à²ªà²Šà²à²³à³. à² à²€à²°à²¹à²Š à²ªà³à²°à²¶à³à²šà³à²à²³à²²à³à²²à²¿ à²šà³à²µà³ à²¹à³à²¡à³à²à³à²€à³à²€à²¿à²°à³à²µ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²²à³à²²à²¿ à²à²°à²¬à²¹à³à²Šà²Ÿà²Š à²à³à²²à²µà³ à²ªà²Šà²à²³à²³à²šà³à²šà³ à²ªà²à³à²à²¿à²®à²Ÿà²¡à²¬à²¹à³à²Šà³. à²žà²à²¬à²à²§à²ªà²à³à² à²Šà²Ÿà²à²²à³à²à²³à²šà³à²šà³ à²¶à³à²§à²¿à²žà²¿  
+  <li> à²žà²°à²¿à²¹à³à²à²Šà²¿à²Š à²Šà²Ÿà²à²²à³à²à²³à²šà³à²šà³ à²
+à²µà³ à²šà²¿à²®à³à²® à²ªà³à²°à²¶à³à²šà³à²à³ à²à²·à³à²à³ à²žà²®à³à²ªà²µà³ à² à²ªà³à²°à²à²Ÿà²° à²ªà³à²°à²Šà²°à³à²¶à²¿à²žà³à²€à³à²€à²Šà³.  à²à²à²Šà³ à²Šà²žà³à²€à²Ÿà²µà³à²à³ à²šà²¿à²®à³à²® à²ªà³à²°à²¶à³à²šà³à²à³ à²à²·à³à²à³ à²žà²Ÿà²®à³à²ªà³à²¯ à²à²à²Šà³ à²šà²¿à²°à³à²§à²°à²¿à²žà³à²µ à²à³à²°à²® à²¹à³à²à²¿à²Šà³  
+
+  <p><ul>
+    <li>à²Šà²žà³à²€à²Ÿà²µà³à²à²¿à²šà²²à³à²²à²¿ à²ªà³à²°à²¶à³à²šà³à²¯à²²à³à²²à²¿à²°à³à²µ à²à²²à³à²²à²Ÿ à²ªà²Šà²à²³à³ à²à²Šà³à²Šà²°à³ à²
+à²Šà³ à²¹à²€à³à²€à²¿à²°à²Š à²žà²°à²¿à²¹à³à²à²Šà²Ÿà²£à²¿à²à³.
+    <li>à²žà²Ÿà²®à²šà³à²¯ à²ªà²Šà²à²³à²¿à²à²¿à²à²€ à²µà²¿à²°à²³à²µà²Ÿà²Š à²ªà²Šà²à²³à³ à²®à³à²à³à²¯à²µà²Ÿà²Šà²µà³.
+    <li>à²Šà³à²¡à³à²¡ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²¿à²à²¿à²à²€ à²à²¿à²à³à²à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³ à²¹à³à²à³à²à³ à²žà²®à³à²ª.
+   </ul>
+</ul> 
+
+<p>à²šà³à²µà³ à²à²·à³à²à³ à²¶à³à²§à²šà³ à²ªà²Šà²à²³à²šà³à²šà²Ÿà²Šà²°à³ à²à²ªà²¯à³à²à²¿à²žà²¬à²¹à³à²Šà³; à²à²Šà²Ÿà²¹à²°à²£à³à²à³ à²à²à²Šà³ à²ªà³à²°à³à²€à²¿à²µà²Ÿà²à³à²¯ ,à²à²à²Šà³ à²ªà³à²°à³à²€à²¿ à²µà²Ÿà²à³à²¯à²µà³à²à²Š, à²à²€à³à²¯à²Ÿà²Šà²¿. à²ªà³à²°à²¶à³à²šà³à²¯à²²à³à²²à²¿ à²à²à²Šà³ à²ªà²Šà²µà²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¿à²Šà²°à³ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à² à²ªà²Šà²Š à²žà²à²­à²µà²¿à²šà³à²¯à²€à³ (à²
+à²à²Šà²°à³ à² à²ªà²Š à²à²·à³à²à³ à²¬à²Ÿà²°à²¿ à² à²Šà²žà³à²€à²Ÿà²µà³à²à²¿à²šà²²à³à²²à²¿ à²¬à²°à³à²€à³à²€à²Šà³) à²¯à²à²€à³ à²ªà²à³à²à²¿ à²®à²Ÿà²¡à³à²€à³à²€à²Šà³.<p>}  
+
+_texthelpadvancedsearchtitle_ [l=kn] {_1_ à²¶à³à²§ à²¯à²à²€à³à²° à²à²ªà²¯à³à²à²¿à²žà²¿à²à³à²à²¡à³  à²ªà²°à²¿à²£à²¿à²€ à²¶à³à²§à²šà³ }  
+
+_texthelpadvancedsearch_ [l=kn] {<p>à²à²à²Šà³ à²µà³à²³à³ à²šà³à²µà³ à²à²šà³à²šà²€ à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿ à²°à³à²€à²¿à²¯à²šà³à²šà³ à²à²°à²¿à²žà²¿à²Šà³à²Šà²²à³à²²à²¿(à²ªà³à²°à²Ÿà²§à²Ÿà²šà³à²¯à²€à³à²¯à²²à³à²²à²¿)à²
+à²µà²Ÿà² à²šà²¿à²®à²à³ à²žà³à²µà²²à³à²ª à²¬à³à²°à³ à²°à³à²€à²¿à²¯à²²à³à²²à²¿ à²¶à³à²§à² à²à²à³à²à²¿à²à²à²³à³ à²žà²¿à²à³à²µà³à²Šà³.}  
+
+_texthelpadvsearchmg_ [l=kn] {à²à²à²à²¿ à²žà²à²à³à²°à²¹à²à²³à²²à³à²²à²¿ à²ªà²°à²¿à²£à²¿à²€ à²¶à³à²§à²šà³à²¯à²²à³à²²à²¿ à²à²°à²¡à³ à²à²à³à²à²¿à²à²à²³à³ à²Šà³à²°à²à³à²€à³à²€à²µà³ - à²¶à³à²°à³à²£à²¿ à²®à²€à³à²€à³ à²¬à³à²²à²¿à²¯à²šà³â. à²à²à²Šà³ <b>à²¶à³à²°à³à²£à²¿</b>à²¶à³à²§à²šà³ <a href="\#query-type">_texthelpquerytypetitle_</a> à²¯à²²à³à²²à²¿ à²µà²¿à²µà²°à²¿à²žà²¿à²°à³à²µ <b>à²à³à²²à²µà³</b>à²¶à³à²§à²šà³à²¯à²à²€à³à²¯à³ à²à²°à³à²€à³à²€à²Šà³.<p>_texthelpbooleansearch_}  
+
+_texthelpbooleansearch_ [l=kn] {<b>à²¬à³à²²à²¿à²¯à²šà³â</b>  à²¶à³à²§à²šà³à²¯ à²®à³à²²à² à²šà³à²µà³ à²à²°à²¡à³ à²
+à²¥à²µà²Ÿ à²¹à³à²à³à²à³ à²ªà²Šà²à²³à²šà³à²šà³ à²à³à²¡à²¿à²žà²¿ à²¶à³à²§à²¿à²žà²¬à²¹à³à²Šà³ &  ("à²®à²€à³à²€à³"), | ("à²
+à²¥à²µà²Ÿ"), à²¹à²Ÿà²à³ ! ("à²à²²à³à²²à²Šà³"), à²¹à²Ÿà²à³ à²ªà²Šà²à²³à²šà³à²šà³ à²à²à³à²à³à²à³à²¡à²¿à²žà²²à³ à²à²µà²°à²£à²à²³à²šà³à²šà³ à²¬à²³à²žà²¬à²¹à³à²Šà³.
+<p>
+à².à²Šà²Ÿ., <b>à²­à²Ÿà²°à²€ & à²à²°à³à²¥à²¿à² à²ªà²°à²¿à²žà³à²¥à²¿à²€à²¿</b> à² à²à²°à²¡à³ à²ªà²Šà²à²³à²šà³à²šà³à²³à²à³à²à²Š à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²®à²Ÿà²€à³à²° à²à²Šà²à²¿à²žà³à²€à³à²€à²Šà³. <b>à²­à²Ÿà²°à²€ | à²à³à²šà²Ÿ</b> à² à²à²°à²¡à²°à²²à³à²²à²¿ à²¯à²Ÿà²µà³à²Šà²Ÿà²Šà²°à³ à²à²à²Šà³ à²ªà²Šà²µà²¿à²°à³à²µ à²à²²à³à²²à²Ÿ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²à²Šà²à²¿à²žà³à²€à³à²€à²Šà³.
+<b>à²­à²Ÿà²°à²€ ! à²à³à²šà²Ÿ</b> 'à²­à²Ÿà²°à²€' à²ªà²Šà²µà²¿à²°à³à²µ à²®à²€à³à²€à³ à²à³à²šà²Ÿ à²ªà²Šà²µà²¿à²²à³à²²à²Šà²¿à²°à³à²µ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²®à²Ÿà²€à³à²° à²à²Šà²à²¿à²žà³à²€à³à²€à²Šà³. 
+<p>
+à²à²µà²°à²£à²à²³ à²®à²€à³à²€à³ à²¬à³à²²à²¿à²¯à²šà³â à²à²à³à²à²¿à²à²à²³à³à²°à²¡à²šà³à²šà³ à²¬à²³à²žà²¿ à²à²šà³à²šà³ à²¹à³à²à³à²à²¿à²š à²à²à²¿à²€ à²¶à³à²§à²šà³à²à²³à²šà³à²šà³ à²°à³à²ªà²¿à²žà²¬à²¹à³à²Šà³.}  
+
+_texthelpadvsearchmgpp_ [l=kn] {à²¬à³à²²à²¿à²¯à²šà³ à²à²à³à²à²¿à²à²à²³à²šà³à²šà³ à²à²à²à²¿à²ªà²¿à²ªà²¿ à²žà²à²à³à²°à²¹à²Š à²à²šà³à²šà²€ à²¶à³à²§à²Šà²²à³à²²à²¿ à²à²ªà²¯à³à²à²¿à²žà²¿.  
+_texthelpbooleansearch_
+<p>à²«à²²à²¿à²€à²Ÿà²à²¶à²à²³à²šà³à²šà³ <b>à²¶à³à²°à³à²£à²¿</b>à²
+à²šà³à²žà²Ÿà²°à²µà²Ÿà²à²¿ <a href=""\#query-type"">_texthelpquerytypetitle_</a>à²šà²²à³à²²à²¿ à²¹à³à²³à²¿à²°à³à²µà²à²€à³ à²€à³à²°à²¿à²žà²¬à²¹à³à²Šà³, à²
+à²¥à²µà²Ÿ ""à²ªà³à²°à²Ÿà²à³à²€à²¿à²"" (à²
+à²¥à²µà²Ÿ ""à²šà²¿à²°à³à²®à²¿à²žà³"")à²
+à²šà³à²žà²Ÿà²°à²µà²Ÿà²à²¿ à²€à³à²°à²¿à²žà²¬à²¹à³à²Šà³. à²à²Šà³ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³ à²à³à²°à²à²¥à²Ÿà²²à²¯à²Š à²à²³à²à³ à²¬à²à²Š à²žà²Ÿà²²à²¿à²šà²²à³à²²à³ à²€à³à²°à²¿à²žà³à²€à³à²€à²Šà³.
+à²à²Šà²²à³à²²à²Šà³  <b>NEARx</b> à²®à²€à³à²€à³ <b>WITHINx</b> à²à²ªà²°à³à²à²°à³âà²à²³à³ à²à²µà³. NEARx à²à²ªà²¯à³à²à²¿à²žà²¿ à²à²°à²¡à³ à²¶à³à²§à² à²ªà²Šà²à²³ à²šà²¡à³à²µà²¿à²š à²à²°à²¿à²·à³à²  à²Šà³à²°à²µà²šà³à²šà³  (x à²ªà²Šà²à²³à³)à²¹à³à²³à²¬à²¹à³à²Šà³. WITHINx  à²à²ªà²¯à³à²à²¿à²žà²¿ à²à²°à²¡à²šà³ à²¶à³à²§à² à²ªà²Š à²®à³à²Šà²²à²šà³ à²¶à³à²§à² à²ªà²Šà²Šà²¿à²à²Š à²à²·à³à²à³ à²ªà²Šà²à²³ (x à²ªà²Šà²à²³à³)<i>à²
+à²à²€à²°à²Šà²²à³à²²à²¿</i> à²à²°à²¬à³à²à³ à²à²à²Šà³ à²šà²®à³à²Šà²¿à²žà²¬à²¹à³à²Šà³. à²à²Šà³  NEAR à²šà²à²€à³à²¯à³ à²à²Šà²°à³ à²à²²à³à²²à²¿ à²ªà²Šà²à²³ à²à³à²°à²®à²Ÿà²šà³à²à²€à²¿ à²®à³à²à³à²¯à²µà²Ÿà²à³à²€à³à²€à²Šà³. à²ªà³à²°à³à²µà²šà²¿à²¯à³à²à²¿à²€ à²
+à²à²€à²° 20."}  
+
+_texthelpadvancedsearchextra_ [l=kn] {à²žà³à²à²šà³: à²à²à²Šà³à²µà³à²³à³ à²šà³à²µà³ à²žà²Ÿà²Šà²Ÿà²°à²£ query mode à²®à³à²²à² à²¶à³à²§à²¿à²žà²¿à²Šà²°à³ à²
+ à²à²²à³à²²à²Ÿ à²à²Ÿà²°à³à²¯à²à²³à²šà³à²šà³  à²
+à²²à²à³à²·à²¿à²žà²²à²Ÿà²à³à²µà³à²Šà³}  
+
+_texthelpadvsearchlucene_ [l=kn] {à²¬à³à²²à²¿à²¯à²šà³â à²à²ªà²°à³à²à²°à³à²žà³âà²šà³à²šà³ à²à²šà³à²šà²€ à²¶à³à²§à²¿à²žà³à²µà²¿à²à³ à²²à³à²žà³à²žà³â à²žà²à²à³à²°à²¹à²à²³à²²à³à²²à²¿ à²à²ªà²¯à³à²à²¿à²žà²¿. _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=kn] {à²à³à²·à³à²€à³à²°à²Ÿà²µà²Ÿà²°à³ à²¶à³à²§}  
+
+_texthelpformsearch_ [l=kn] {<p>à²à³à²·à³à²€à³à²°à²Ÿà²µà²Ÿà²°à³ à²¶à³à²§à²¿à²žà³à²µà²¿à²à³ à²µà²¿à²µà²¿à²§ à²à³à²·à³à²€à³à²°à²à²³à²šà³à²šà³ à²à²à³à²à²¿à²à³ à²¶à³à²§à²¿à²žà²žà²²à³ à²
+à²šà³à²µà³ à²®à²Ÿà²¡à²¿à²à³à²¡à³à²€à³à²€à²Šà³. à².à²Šà²Ÿ. "à²žà³à²®à²¿à²€à³â" à²à²šà³à²šà³à²µ à²¹à³à²žà²°à²šà³à²šà³ à²¶à³à²°à³à²·à²¿à²à³à²¯à²²à³à²²à²¿ à²®à²€à³à²€à³ "à²žà³à²šà³à²²à³â à²«à²Ÿà²°à³à²®à²¿à²à²à³â" à²à²à²¬ à²ªà²Šà²à³à²à³à²à²µà²šà³à²šà³ à²µà²¿à²·à²¯à²Š à²
+à²¡à²¿à²¯à²²à³à²²à²¿ à²¶à³à²§à²¿à²žà²¬à²¹à³à²Šà³. à²žà²Ÿà²§à²Ÿà²°à²£ à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿ à²ªà²Šà³à²§à²€à²¿à²¯à²²à³à²²à²¿ à²ªà³à²°à²€à²¿à²¯à³à²à²Šà³ à²žà²Ÿà²²à³ à²žà²¹ à²žà²¹à²à²µà²Ÿà²Š à²à²à²Šà³ à²žà²Ÿà²²à²¿à²š à²¶à³à²§à²¿à²žà³à²µà²¿à²à³à²¯à²à²€à³ à²µà²°à³à²€à²¿à²žà³à²€à³à²€à²Šà³. à²à²°à²¡à³ à²žà²Ÿà²²à³à²à²³à²šà³à²šà³ 'à²®à²€à³à²€à³' (à²à²²à³à²²à²Ÿ à²¶à³à²§à²šà³à²à³)à²
+à²¥à²µà²Ÿ 'à²
+à²¥à²µà²Ÿ' à²ªà²Šà²µà²šà³à²šà³ (à²à³à²²à²µà³ à²¶à³à²§à²¿à²žà³à²µà²¿à²à³à²à³)à²à²ªà²¯à³à²à²¿à²žà²¿ à²žà³à²°à²¿à²žà²¬à²¹à³à²Šà³. à²à²Šà³ à²°à³à²€à²¿à²¯à²²à³à²²à²¿ à²à³à²·à³à²€à³à²°à²Šà³à²³à²à²¿à²°à³à²µ à²ªà²Šà²à³à²à³à²à²µà²šà³à²šà³ à²žà²¹ à²žà³à²°à²¿à²žà²¬à²¹à³à²Šà³. à²ªà²°à²¿à²£à²¿à²€ à²ªà²Šà³à²§à²€à²¿à²¯à²²à³à²²à²¿, à²šà³à²µà³ à²¡à³à²°à²Ÿà²ªà³â-à²¡à³à²šà³â à²ªà²à³à²à²¿à²¯à²¿à²à²Š à²à²°à²¡à³ à²à³à²·à³à²€à³à²°à²à²³ à²šà²¡à³à²µà³ à²¬à³à²°à³ à²¬à³à²°à³ à²°à³à²€à²¿à²¯ AND/OR/NOT à²žà³à²°à²¿à²žà³à²µà²¿à²à³à²à²³à²šà³à²šà³ à²µà²¿à²µà²°à²¿à²žà²¬à²¹à³à²Šà³, à²®à²€à³à²€à³ à²šà³à²µà³ à²à³à²·à³à²€à³à²°à²Šà³à²³à²à³ à²¬à³à²²à²¿à²¯à²šà³â à²à²ªà²°à³à²à²°à³à²žà³ââà²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¬à²¹à³à²Šà³.}  
+
+_texthelpformstemming_ [l=kn] {"à²®à²¡à²à³" à²®à²€à³à²€à³ "à²à²Ÿà²à²¡" à²ªà³à²à³à²à²¿à²à³à²à²³à²šà³à²šà³ à²¬à²³à²žà²¿ à²à³à²·à³à²€à³à²°à²Šà³à²³à²à²¿à²°à³à²µ à²ªà²Šà²à²³à³ à²à³à²žà³âà²ªà³à²²à³à²¡à³à²¡à³â à²
+à²¥à²µ à²žà³à²à³à²®à³â à²à²à²¿à²Šà³à²¯à³ à²à²à²Šà³ à²šà³à²µà³ à²žà³à²à²¿à²žà²¬à²¹à³à²Šà³. à²ªà²°à²¿à²£à²¿à²€ à²¶à³à²§à²šà³à²¯à²²à³à²²à²¿ à² à²à²°à²¡à³ à²ªà³à²°à³à²µà²šà²¿à²¯à³à²à²¿à²€à²µà²Ÿà²à²¿ à²€à³à²°à³à²Šà²¿à²°à³à²µà³à²Šà²¿à²²à³à²²}  
+
+_textdatesearch_ [l=kn] {à²Šà²¿à²šà²Ÿà²à²à²à²³à²¿à²à²Š à²¶à³à²§à²¿à²žà³à²µà²¿à²à³}  
+
+_texthelpdatesearch_ [l=kn] {à²Šà²¿à²šà²Ÿà²à²à²Š à²ªà³à²°à²à²Ÿà²°à²Š à²¶à³à²§à²šà³ à²šà²¿à²®à³à²®  à²ªà³à²°à²¶à³à²£à²Ÿà²µà²³à²¿à²à³ à²¹à³à²²à³à²µ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²·à³à²à³ à²
+à²²à³à²²à²Šà³, à² à²žà²®à²¯à²à²à³à²à²¿à²šà²²à³à²²à²¿ à²šà³à²¡à³à²Š à²à²à²šà³à²à²³à²¿à²à³ à²žà²à²¬à²à²§à²¿à²žà²¿à²Š à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²€à³à²°à²¿à²žà³à²€à³à²€à²Šà³. à²šà³à²µà³ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²šà²¿à²à²Šà²¿à²€ à²µà²°à³à²· à²
+à²¥à²µà²Ÿ à²µà²°à³à²·à²à²³ à²µà³à²¯à²Ÿà²ªà³à²€à²¿à²¯à²šà³à²šà³ à²šà³à²¡à²¿ à²¶à³à²§à²¿à²žà²¬à²¹à³à²Šà²Ÿà²à²¿à²Šà³. à²à²à²Šà²šà³à²šà³ à²à²®à²šà²¿à²žà²¿, à²šà³à²µà³ à²šà²¿à²®à³à²® à²¶à³à²§à²¿à²šà³à²¯à²²à³à²²à²¿ à²šà²¿à²¯à²®à²à²³à²šà³à²šà³ à²¹à²Ÿà²à²¿ à²¶à³à²§à²¿à²žà²¬à³à²à²Ÿà²à²¿à²²à³à²² - à²¬à²°à³ à²Šà²¿à²šà²Ÿà²à²à²µà²šà³à²šà³ à²šà³à²¡à²¿ à²¶à³à²§à²¿à²žà²¬à²¹à³à²Šà³;  à²¹à²Ÿà²à³à²¯à³ à²Šà²¿à²šà²Ÿà²à²à²à²³à²šà³à²šà³ à²šà³à²µà³ à²¹à²Ÿà²à²²à³à²¬à³à²à³à²à²Šà²¿à²²à³à²², à²à²à²Šà³ à²µà³à²³à³ à²šà³à²µà³ à²¯à²Ÿà²µ à²Šà²¿à²šà²Ÿà²à²à²µà²šà³à²šà³ à²šà²®à³à²Šà²¿à²žà²Šà²¿à²Šà³à²Šà²°à³,  à² à²šà²¿à²¯à²®à²à²³à²¿à²à³ à² à²Šà²¿à²šà²Ÿà²à²à²Šà²²à³à²²à²¿ à²¯à²Ÿà²µ à²¶à³à²§à²¿à²à³à²¯à³ à²à²²à³à²² à²à²à²Šà³ à²
+à²°à³à²¥. <p>}  
+
+_texthelpdatehowtotitle_ [l=kn] {à² à²²à²à³à²·à²£à²µà²šà³à²šà³ à²¹à³à²à³ à²à²ªà²¯à³à²à²¿à²žà³à²µà³à²Šà³:}  
+_texthelpdatehowto_ [l=kn] {<ul>
+   <li>à²à²à²Šà³ à²µà²°à³à²·à²Š à²¬à²à³à²à³ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³ à²¶à³à²§à²šà³:<p>
+   <ul>
+       <li>à²žà²Ÿà²®à²Ÿà²šà³à²¯à²µà²Ÿà²à²¿ à²šà³à²µà³ à²®à²Ÿà²¡à³à²µà²à²€à³ à²¯à²µà³à²Šà²Ÿà²Šà²°à³ à²žà²Ÿà²®à²Ÿà²šà³à²¯ à²¶à³à²§à²¿à²žà³ à²ªà²Šà²µà²šà³à²šà³ à²¬à²°à³à²¯à²¿à²°à²¿.
+       <li>"Start (or only) date" à²ªà³à²à³à²à²¿à²à³à²¯à²²à³à²²à²¿ à²šà²¿à²®à²à³ à²¬à³à²à²Ÿà²Š à²µà²°à³à²·à²µà²šà³à²šà³ à²¬à²°à³à²¯à²¿à²°à²¿.
+       <li>à²à²à²Šà³à²µà³à²³à³ à²à³à²°à²¿.à²¶. à²à³à²à²¿à²à²€ à²®à³à²Šà²²à²¿à²š à²Šà²¿à²šà²Ÿà²à²à²µà²Ÿà²Šà²°à³ à²ªà³à²à³à²à²¿à²à³à²¯ à²šà²à²€à²° à²à²°à³à²µ à²ªà³à²²à³âà²¡à³à²šà³â à²®à³à²šà³à²¯à³à²š "B.C.E" à²à²à³à²à²¿à²à²µà²šà³à²šà³ à²à²°à²¿à²žà²¿.
+       <li>à²žà²Ÿà²®à²Ÿà²šà³à²¯à²µà²Ÿà²à²¿ à²šà³à²µà³ à²®à²Ÿà²¡à³à²µà²à²€à³ à²šà²¿à²®à³à²® à²¶à³à²§à²à²µà²šà³à²šà³ à²¶à³à²°à³à²®à²Ÿà²¡à²¿.
+   </ul>
+<p><li>à²à²à²Šà³ à²à²Ÿà²² à²žà²®à²¯à²à³à²à³ à²
+à²¥à²µà²Ÿ à²šà²¿à²à²Šà²¿à²žà²¿à²Š à²µà²°à³à²· à²¶à³à²°à³à²£à²¿à²à³ à²žà²à²¬à²à²§à²¿à²žà²¿à²Š à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²¹à³à²¡à³à²à²²à³:<p>
+   <ul>
+       <li>à²šà³à²µà³ à²žà²Ÿà²®à²Ÿà²šà³à²¯à²µà²Ÿà²à²¿ à²®à²Ÿà²¡à³à²µà²à²€à³  à²¯à²Ÿà²µà³à²Šà²Ÿà²Šà²°à³ à²¶à³à²§à² à²ªà²Šà²µà²šà³à²šà³ à²¬à²°à³à²¯à²¿à²°à²¿.
+       <li>"Start (or only) date"  à²ªà³à²à³à²à²¿à²à³à²¯à²²à³à²²à²¿ à²®à³à²Šà²²à²¿à²š à²Šà²¿à²šà²Ÿà²à²à²µà²šà³à²šà³ à²¬à²°à³à²¯à²¿à²°à²¿.
+       <li>"End date"  à²ªà³à²à³à²à²¿à²à³à²¯à²²à³à²²à²¿ à²®à³à²à²Šà²¿à²š à²Šà²¿à²šà²Ÿà²à²à²µà²šà³à²šà³ à²¬à²°à³à²¯à²¿à²°à²¿.
+       <li>à²à³à²°à²¿.à²¶. à²à³à²à²¿à²à²€ à²®à³à²Šà²²à²¿à²š à²¯à²Ÿà²µà³à²Šà²Ÿà²Šà²°à³ à²Šà²¿à²šà²Ÿà²à²à²Š à²®à³à²à²à³ "B.C.E"  à²à²à³à²à²¿à²à²µà²šà³à²šà³ à²ªà³à²²à³âà²¡à³à²šà³â à²®à³à²šà³à²¯à³à²µà²¿à²à²Š à²à²°à²¿à²žà²¿.
+       <li>à²žà²Ÿà²®à²Ÿà²šà³à²¯à²µà²Ÿà²à²¿ à²®à²Ÿà²¡à³à²µà²à²€à³  à²¯à²Ÿà²µà³à²Šà²Ÿà²Šà²°à³ à²¶à³à²§à² à²ªà²Šà²µà²šà³à²šà³ à²¶à³à²°à³à²®à²Ÿà²¡à²¿.
+   </ul>    
+</ul><p>   }  
+
+_texthelpdateresultstitle_ [l=kn] {à²šà²¿à²®à³à²® à²¶à³à²§à²šà³à²¯ à²«à²²à²¿à²€à²Ÿà²à²¶ à² à²°à³à²€à²¿à²¯à²²à³à²²à²¿ à²à³à²²à²žà²®à²Ÿà²¡à³à²µà³à²Šà³}  
+_texthelpdateresults_ [l=kn] {à²žà²Ÿà²®à²Ÿà²šà³à²¯à²µà²Ÿà²à²¿ à²¹à³à²³à³à²µà³à²Šà²Ÿà²Šà²°à³, 1903 à²šà³ à²µà²°à³à²·à²à³à²à³ à²žà²à²­à²à²Šà²¿à²žà²¿à²Š à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²¶à³à²§à²¿à²žà²²à³ à²¹à³à²°à²à²Ÿà² 1903 à²šà³ à²µà²°à³à²·à²Šà²²à³à²²à²¿ à²¬à²°à³à²Šà²¿à²°à³à²µ à²ªà³à²žà³à²€à²à²à²³à²šà³à²šà³à²²à³à²²à²Ÿ à²
+à²Šà³ à²€à³à²°à²¿à²žà³à²µà³à²Šà²¿à²²à³à²²; 1903 à²° à²¬à²à³à²à³ à²à²°à³à²µ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²®à²Ÿà²€à³à²° à²€à³à²°à²¿à²žà³à²€à³à²€à²Šà³. à²à²Šà²°à³ à²à²Šà³ 1903 à²šà³ à²à²žà²µà²¿à²¯à²šà³à²šà³ à²à²³à²à³à²à²¡à³ à²¬à²°à³à²µ à²Šà²¿à²šà²Ÿà²à²à²à²³ à²µà³à²¯à²Ÿà²ªà³à²€à²¿à²¯à²²à³à²²à²¿ (à².à²Šà²Ÿ. 1899-1911) à²¬à²°à³à²µ à²à²²à³à²²à²Ÿ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²€à³à²°à²¿à²žà³à²µà³à²Šà²²à³à²²à²Šà³, à² à²¶à²€à²®à²Ÿà²šà²Š à²¹à³à²žà²°à³ à²ªà² à³à²¯à²Šà²²à³à²²à²¿à²°à³à²µ, à²
+à²à²Šà²°à³ 1903 à²¬à²°à³à²µ à²¶à²€à²®à²Ÿà²š(à².à²Šà²Ÿ. 20 à²šà³ à²¶à²€à²®à²Ÿà²š à²
+à²¥à²µà²Ÿ à²à²ªà³à²ªà²€à³à²€à²šà³ à²¶à²€à²®à²Ÿà²š)à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²€à³à²°à²¿à²žà³à²€à³à²€à²Šà³. à²
+à²à²Šà²°à³, à²šà³à²µà³ à²¶à³à²§à²šà³à²¯à²²à³à²²à²¿ à²šà²®à³à²Šà²¿à²žà²¿à²Š à²Šà²¿à²šà²Ÿà²à²à²à²³à³ à² à²Šà²žà³à²€à²Ÿà²µà³à²à²¿à²š à²ªà² à³à²¯à²Šà²²à³à²²à²¿ à²ªà³à²°à²€à³à²¯à³à²à²µà²Ÿà²à²¿ à²à²Ÿà²£à³à²µà³à²Šà²¿à²²à³à²². à²à²Šà²°à³ à²µà³à²¯à²Ÿà²ªà³à²€à²¿à²¯ à²¶à³à²§à²¿à²žà³à²µà²¿à²à³à²¯à²²à³à²²à²¿ à² à²µà³à²¯à²Ÿà²ªà³à²€à²¿à²¯à²²à³à²²à²¿à²°à³à²µ à²à²²à³à²²à²Ÿ à²Šà²¿à²šà²Ÿà²à²à²à²³à³ à²µà³à²¯à²Ÿà²ªà³à²€à²¿à²¯à²²à³à²²à²¿à²°à³à²€à³à²€à²Šà³.<p>}  
+
+_textchangeprefs_ [l=kn] {à²šà²¿à²®à³à²® à²ªà³à²°à²Ÿà²§à²Ÿà²šà³à²¯à²€à³à²à²³à³ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à²¿à²Šà³}  
+
+_texthelppreferences_ [l=kn] {<p> à²ªà³à²à²Š à²®à³à²²à²¿à²°à³à²µ<i>_Global:linktextPREFERENCES_</i> à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³â à²®à²Ÿà²¡à²¿ à²à²à²à²°à³âà²«à³à²žà³âà²š à²žà³à²µà²°à³à²ªà²µà²šà³à²šà³ à²šà²¿à²®à²à³ à²
+à²šà³à²à³à²²à²µà²Ÿà²à³à²µ à²°à³à²€à²¿à²¯à²²à³à²²à²¿ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²¿à²à³à²³à³à²³à²¬à²¹à³à²Šà³.}  
+
+_texthelpcollectionprefstitle_ [l=kn] {à²žà²à²à³à²°à²¹à²£à³à²¯ à²ªà³à²°à²Ÿà²§à²Ÿà²šà³à²¯à²€à³à²à²³à³}  
+_texthelpcollectionprefs_ [l=kn] {<p>à²à³à²²à²µà³ à²žà²à²à³à²°à²¹à²£à³à²à²³à³ à²à²ªà²žà²à²à³à²°à²¹à²£à³à²à²³à²¿à²à²Š à²à³à²¡à²¿à²°à³à²€à³à²€à²µà³.à²
+à²µà²šà³à²šà³ à²žà³à²µà²€à²à²€à³à²°à²µà²Ÿà²à²¿ à²
+à²¥à²µà²Ÿ à²à³à²€à³à²¯à²Ÿà²à²¿
+à²¶à³à²§à²¿à²žà²¬à²¹à³à²Šà³.à²šà²¿à²®à³à²® à²à²ªà²žà²à²à³à²°à²¹à²£à³à²¯à²šà³à²šà³ à²ªà³à²°à²Ÿà²§à²Ÿà²šà³à²¯à²€à³à²à²³ à²ªà³à²à²Šà²²à³à²²à²¿ à²žà³à²°à²¿à²žà²¬à²¹à³à²Šà³.}  
+
+_texthelplanguageprefstitle_ [l=kn] {à²­à²Ÿà²·à³à²¯ à²ªà³à²°à²Ÿà²§à²Ÿà²šà³à²¯à²€à³à²à²³à³}  
+_texthelplanguageprefs_ [l=kn] {<p> à²ªà³à²°à²€à²¿à²¯à³à²à²Šà³ à²žà²à²à³à²°à²¹à²à³à²à³ à²
+à²Šà²°à²Šà³à²Šà³ à²à²Š à²­à²Ÿà²·à³ à²à²°à³à²€à³à²€à²Šà³à²¯à²Ÿà²Šà²°à³, à²šà³à²µà³ à²¬à³à²°à³ à²­à²Ÿà²·à³à²à³ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²¿à²à³à²³à³à²³à²¬à²¹à³à²Šà³; à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²à²ªà²¯à³à²à²¿à²žà³à²µ à²à²šà³âà²à³à²¡à²¿à²à²à³ à²µà²¿à²§à²Ÿà²šà²µà²šà³à²šà³ à²žà²¹ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²¬à²¹à³à²Šà³. à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²€à²à²€à³à²°à²Ÿà²à²¶ à²¡à²¿à²«à²Ÿà²²à³à²à³ à²à²šà³âà²à³à²¡à²¿à²à²à³â à²µà²¿à²§à²Ÿà²šà²µà²šà³à²šà³ à²à²¯à³à²Šà³à²à³à²³à³à²³à³à²€à³à²€à²Šà³à²¯à²Ÿà²Šà²°à³, à²à³à²²à²µà³à²à²Šà³ à²¬à³à²°à³à²žà²°à³âà²à²³à²²à³à²²à²¿ à²žà²°à²¿à²¯à²Ÿà²à²¿ à²ªà³à²°à²Šà²°à³à²¶à²¿à²žà²²à³ à²¬à³à²°à³ à²à²šà³âà²à³à²¡à²¿à²à²à³â à²µà²¿à²§à²Ÿà²šà²µà²šà³à²šà³ à²¬à²³à²žà²¬à³à²à²Ÿà²à²¬à²¹à³à²Šà³. à²à²²à³à²² à²à³à²°à²à²¥ à²žà²à²à³à²°à²¹à²à²³à²²à³à²²à³ à²šà³à²µà³ à²¬à³à²à²¿à²Šà³à²Šà²²à³à²²à²¿, à²à³à²°à³à²¯à²Ÿà²«à²¿à²à³â à²®à²Ÿà²§à³à²¯à²®à²Šà²¿à²à²Š à²ªà² à³à²¯ à²®à²Ÿà²§à³à²¯à²®à²à³à²à³ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²¿à²à³à²³à³à²³à²¬à²¹à³à²Šà³; à² à²žà³à²²à²­à³à²¯ à²µà²¿à²¶à³à²·à²µà²Ÿà²à²¿ à²Šà³à²·à³à²à²¿ à²®à²Ÿà²à²Šà³à²¯à²°à²¿à²à³ à²à²ªà²¯à³à²à²µà²Ÿà²à³à²€à³à²€à²Šà³.}  
+
+_texthelppresentationprefstitle_ [l=kn] {à²ªà³à²°à²Šà²°à³à²¶à²šà³à²¯ à²ªà³à²°à²Ÿà²§à²Ÿà²šà³à²¯à²€à³à²à²³à³}  
+_texthelppresentationprefs_ [l=kn] {à²žà²à²à³à²°à²¹à²£à³à²¯à²šà³à²šà³ à²à²§à²°à²¿à²žà²¿, à²ªà³à²°à²Šà²°à³à²¶à²šà³à²¯ à²à²¯à³à²à³à²à²³à²šà³à²šà³ à²¹à²€à³à²à²¿à²¯à²²à³à²²à²¿à²¡à²¬à²¹à³à²Šà³.
+
+<p>à²µà³à²¬à³â à²ªà³à²à²à²³ à²žà²à²à³à²°à²¹à²£à³à²à²³à²²à³à²²à²¿, à²ªà³à²à²Š à²®à³à²²à²¿à²°à³à²µ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â  à²šà³à²¯à²Ÿà²µà²¿à²à³à²¶à²šà³â à²¬à²Ÿà²°à³âà²šà³à²šà³ à²®à³à²à³à²à²¿à²¡à²¬à²¹à³à²Šà³, à²à²Šà³à²Šà²°à²¿à²à²Š à²šà³à²µà³ à²à²à²Šà³ à²¶à³à²§à²šà³à²¯à²šà³à²šà³ à²®à²Ÿà²¡à²¿à²Š à²šà²à²€à²° à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²¹à³à²¡à³à²¡à²°à³â à²à²²à³à²²à²Šà³à²¯à³ à²šà³à²°à²µà²Ÿà²à²¿ à² à²µà³à²¬à³â à²ªà³à²à²à³à²à³ à²¹à³à²à²¬à²¹à³à²Šà³. à²šà³à²µà³ à²®à²€à³à²€à³  à²¶à³à²§à²¿à²žà²²à³ à²¬à³à²°à³à²žà²°à³âà²š à²¹à²¿à²à²Šà²¿à²š à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²¬à²³à²žà²¬à³à²à³. à² à²žà²à²à³à²°à²¹à²£à³à²à²³à³, à²šà³à²µà³ à²à²à²Šà³ à²µà³à²¬à³âà²²à²¿à²à²à³â à²
+à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿  à²¡à²¿à²à²¿à²à²²à³â à²à³à²°à²à²¥à²Ÿà²²à²¯à²Šà²¿à²à²Š à²¹à³à²°à²à³ à²¬à²à²Šà²Ÿà² à²žà²Ÿà²®à²Ÿà²šà³à²¯à²µà²Ÿà²à²¿ à²šà³à²¡à³à²µ à²à²à³à²à²°à²¿à²à³à²¯à²šà³à²šà³ à²®à³à²à³à²à²¿à²¡à³à²€à³à²€à²µà³. 
+à²à³à²²à²µà³à²à²Šà³ à²µà³à²¬à³â à²žà²à²à³à²°à²¹à²à²³à²²à³à²²à²¿ à²à²à²Šà³ à²²à²¿à²à²à³â à²šà²¿à²®à³à²®à²šà³à²šà³ à²šà³à²°à²µà²Ÿà²à²¿ à² à²¯à³ à²à²°à³ à²à²²à³ à²à³ à²à²°à³à²Šà³à²¯à³à²¯à²¬à³à²à³ à²
+à²¥à²µà²Ÿ à²šà²¿à²®à³à²® à²¡à²¿à²à²¿à²à²²à³â à²à³à²°à²à²¥à²Ÿà²²à²¯à²Šà²²à³à²²à²¿à²°à³à²µ à² à²µà³à²¬à³â à²ªà³à²à²Š à²ªà³à²°à²€à²¿à²à³ à²à²°à³à²Šà³à²¯à³à²¯à²¬à³à²à³ à²à²à²¬à³à²Šà²šà³à²šà³ à²šà²¿à²¯à²à²€à³à²°à²¿à²žà²¬à²¹à³à²Šà³}  
+
+_texthelpsearchprefstitle_ [l=kn] {à²¶à³à²§à²šà³à²¯ à²ªà³à²°à²Ÿà²§à²Ÿà²šà³à²¯à²€à³à²à²³à³}  
+_texthelpsearchprefs_ [l=kn] {<p>à²¬à³à²à²¿à²Šà³à²Šà²²à³à²²à²¿ à²šà³à²µà³ à²ªà²°à²¿à²£à²¿à²€ à²¶à³à²§à²šà²Ÿ à²µà³à²¯à²µà²žà³à²¥à³à²¯à²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¿ à²¹à²²à²µà³ à²¶à³à²§à²šà²Ÿ à²ªà²Šà²à²³à²šà³à²šà³ à²¬à³à²²à²¿à²¯à²šà³â à²à²ªà²°à³à²à²°à³à²žà³â - & (à²®à²€à³à²€à³) | (à²
+à²¥à²µà²Ÿ) à²®à²€à³à²€à³ ! (à²à²²à³à²²à²Šà³) - à²à²ªà²¯à³à²à²¿à²žà²¿ à²à³à²¡à²¿à²žà²¬à²¹à³à²Šà³ à²®à²€à³à²€à³ à²¶à³à²§à²šà²Ÿ à²ªà²Šà²à²³à²šà³à²šà³ à²à²à³à²à³à²à³à²¡à²¿à²žà²²à³ à²à²µà²°à²£à²à²³à²šà³à²šà³ à²¬à²³à²žà²¬à²¹à³à²Šà³. à² à²®à³à²²à² à²šà²¿à²®à³à²® à²ªà³à²°à²¶à³à²šà³à²¯à²šà³à²šà³ à²à²šà³à²šà³ à²šà²¿à²à²° à²®à²Ÿà²¡à²¬à²¹à³à²Šà³. 
+<p>_selectsearchtypeprefs_
+<p>_selectwordmodificationprefs_
+<p>à²¶à³à²§à²šà²Ÿ à²à²€à²¿à²¹à²Ÿà²ž à²žà³à²²à²­à³à²¯à²µà²šà³à²šà³ à²à²Ÿà²à³à²€à²¿à²à³à²³à²¿à²žà²¿ à²šà²¿à²®à³à²® à²¹à²¿à²à²Šà²¿à²š à²¹à²²à²µà³ à²ªà³à²°à²¶à³à²šà³à²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¬à²¹à³à²Šà³. à²à²Šà²°à²¿à²à²Š à²šà²¿à²®à³à²® à²¹à²¿à²à²Šà²¿à²š à²ªà³à²°à²¶à³à²šà³à²à²³à²šà³à²šà³ à²¬à²Šà²²à²Ÿà²µà²£à³ à²®à²Ÿà²¡à³à²µà³à²Šà³ à²žà³à²²à³à²­à²µà²Ÿà²à³à²€à³à²€à²Šà³.
+<p>à²à³à²šà³à²¯à²Šà²Ÿà²à²¿, à²šà²¿à²®à³à²® à²ªà³à²°à²¶à³à²šà³à²à³ à²à²°à²¿à²·à³à²  à²®à²¿à²€à²¿à²¯à²šà³à²šà³ à²¹à²Ÿà²à³ à²à²à²Šà³ à²¬à²Ÿà²°à²¿à²à³ à²€à³à²°à³à²¯ à²®à³à²²à³ à²à²·à³à²à³ à²Šà²Ÿà²à²²à³à²à²³à²šà³à²šà³ à²ªà³à²°à²Šà²°à³à²¶à²¿à²žà²¬à³à²à³à²à²¬à³à²Šà²šà³à²šà³ à²šà³à²µà³ à²šà²¿à²°à³à²§à²°à²¿à²žà²¬à²¹à³à²Šà³ à²®à²€à³à²€à³ à²¹à²€à³à²à²¿à²¯à²²à³à²²à²¿à²à³à²à³à²à³à²³à³à²³à²¬à³à²Šà³}  
+
+_textcasefoldprefs_ [l=kn] {à²à²à²Šà³ à²à³à²€à³ à²à³à²à²¡à²¿à²à²³à³ à²Šà³à²¡à³à²¡ à²®à²€à³à²€à³ à²žà²£à³à²£ à²
+à²à³à²·à²° à²¶à³à²§à²¿à²žà²¬à³à²à³ à²à²²à³à²²à²µà³ à²à²à²¬à³à²Šà²šà³à²šà³ à²šà²¿à²¯à²à²€à³à²°à²¿à²žà³à²€à³à²€à²µà³. à²à²Šà²Ÿà²¹à²°à²£à³à²à³, "_preferences:textignoreaccents_" à²à²¯à³à²à³à²®à²Ÿà²¡à²¿à²Šà²°à³, <i>snail farming</i>à²šà³à²šà³ <i>Snail Farming</i> à²®à²€à³à²€à³ <i>SNAIL FARMING</i> à²à²à²Šà³ à²ªà²°à²¿à²à²£à²¿à²žà²²à²Ÿà²à³à²€à³à²€à²Šà³.}  
+_textstemprefs_ [l=kn] {à²¶à³à²§à²šà³ à²®à²Ÿà²¡à³à²µà²Ÿà² à²ªà²Šà²à²³ à²à³à²šà³à²¯à²šà³à²šà³ à²à²¡à³à²à²£à²¿à²žà²¬à³à²à³ à²à²²à³à²²à²µà³ à²à²à²¬à³à²Šà²šà³à²šà³ à²à²à²Šà³ à²à³à²¡à²¿ à²à³à²à²¡à²¿à²à²³à³ à²šà²¿à²¯à²à²€à³à²°à²¿à²žà³à²€à³à²€à²µà³. à².à²Šà²Ÿ. à²à²à²Šà³ à²µà³à²³à³ "_preferences:textstem_" à²à²°à²¿à²žà²¿à²Šà³à²Šà²²à³à²²à²¿,<i>snail farming</i>à²šà³à²šà³< i>snails farm</i> à²®à²€à³à²€à³ <i>snail farmer</i>à²à²à²Šà³ à²à²Ÿà²£à³à²²à²Ÿà²à³à²€à³à²€à²Šà³. à² à²žà³à²²à²­à³à²¯ à²žà²§à³à²¯à²à³à²à³ à²à²à²à³à²²à³à²·à³â à²¬à²Ÿà²·à³à²¯à²²à³à²²à²¿ à²®à²Ÿà²€à³à²° à²žà²°à²¿à²¯à²Ÿà²à²¿ à²à³à²²à²žà²®à²Ÿà²¡à³à²€à³à²€à²Šà³. _selectstemoptionsprefs_ }  
+_textaccentfoldprefs_ [l=kn] {à²à²à²Šà³ à²à³à²€à³ à²à³à²à²¡à²¿à²à²³à³ à²à²€à³à²€à²à³à²·à²° à²¶à³à²§à²¿à²žà²¬à³à²à³ à²à²²à³à²²à²µà³ à²à²à²¬à³à²Šà²šà³à²šà³ à²šà²¿à²¯à²à²€à³à²°à²¿à²žà³à²€à³à²€à²µà³. à²à²Šà²Ÿà²¹à²°à²£à³à²à³, "_preferences:textignoreaccents_" à²à²¯à³à²à³à²®à²Ÿà²¡à²¿à²Šà²°à³, <i>fÃ©dÃ©ration</i> à²šà³à²šà³ <i>fedÃ©ration</i> à²®à²€à³à²€à³ <i>federation</i> à²à²à²Šà³ à²ªà²°à²¿à²à²£à²¿à²žà²²à²Ÿà²à³à²€à³à²€à²Šà³.}  
+ 
+_textstemoptionsprefs_ [l=kn] {à²®à³à²²à³ "_texthelpquerytermstitle_"à²šà²²à³à²²à²¿ à²µà²¿à²µà²°à²¿à²žà²¿à²°à³à²µà²à²€à³  à²¶à³à²§à² à²ªà²Šà²à³à²à³à²à²µà²šà³à²šà³ à²®à³à²à²à³à²à³à²³à²¿à²žà³à²µ à²žà³à²²à²­à³à²¯à²µà²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà³à²µà³à²Šà³ à²¹à³à²à³à²à³ à²à²ªà²¯à³à²à²à²° à²®à²€à³à²€à³ à²šà²¿à²à²° à²µà²Ÿà²Š à²¶à³à²§à²šà³à²¯à²Ÿà²à²¬à²¹à³à²Šà³.}  
+
+_textsearchtypeprefsplain_ [l=kn] {à²žà²°à²Ÿà²à²µà²Ÿà²à²¿ à²Šà³à²¡à³à²¡ à²µà²Ÿà²à³à²¯à²µà³à²à²Šà²µà²šà³à²šà³ à²¶à³à²§à²¿à²žà²¬à²¹à³à²Šà³; à²à²¶à³à²à²°à³à²¯à²µà²Ÿà²à³à²µà²·à³à²à³ à²µà³à²à²µà²Ÿà²à²¿ à²Šà³à²¡à³à²¡ à²µà²Ÿà²à³à²¯à²µà³à²à²Šà²à²³à²šà³à²šà³ à²¶à³à²§à²¿à²žà²¬à²¹à³à²Šà³}  
+
+_textsearchtypeprefsform_ [l=kn] {à²¶à³à²§à²šà³ à²
+à²°à³à²à²¿à²¯à²²à³à²²à²¿ à²šà²®à³à²Šà²¿à²žà²¿à²°à³à²µ à²à³à²·à³à²€à³à²° à²žà²à²à³à²¯à³à²¯à²šà³à²šà³ à²šà³à²µà³ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²¬à²¹à³à²Šà³}  
+
+_textsearchtypeprefsboth_ [l=kn] {à²šà³à²µà³ à²¶à³à²§à²š à²¬à²à³à²¯à²šà³à²šà³ "à²žà²Ÿà²®à²Ÿà²šà³à²¯  à²¶à³à²§à²šà³"  à²®à²€à³à²€à³ "à²à³à²·à³à²€à³à²° à²¶à³à²§à²šà³" à²à²³ à²®à²§à³à²¯à³ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²¿à²à³à²³à³à²³à²¬à²¹à³à²Šà³. 
+<ul>
+<li> à²žà²Ÿà²®à²Ÿà²šà³à²¯ à²¶à³à²§à²šà³ à²à²à²Šà³ à²à²à²Šà³ à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿ à²ªà³à²à³à²à²¿à²à³à²¯à²šà³à²šà³ à²à²Šà²à²¿à²žà³à²€à³à²€à²Šà³. _textsearchtypeprefsplain_</li>
+<li> à²à³à²·à³à²€à³à²° à²¶à³à²§à²šà³ à²¹à²²à²µà²Ÿà²°à³ à²ªà³à²°à²¶à³à²šà²Ÿà²µà²³à²¿ à²ªà³à²à³à²à²¿à²à³à²à²³à²šà³à²šà³ à²à²Šà²à²¿à²žà³à²€à³à²€à²Šà³, à²ªà³à²°à²€à²¿à²¯à³à²à²Šà³ à²¬à³à²°à³ à²¬à³à²°à³ à²à³à²·à³à²€à³à²°à²Š à²žà³à²à²¿à²¯à²šà³à²šà³ à²¶à³à²§à²¿à²žà³à²€à³à²€à²Šà³. à²à²Šà³ à²à²à²Šà³ à²¬à²Ÿà²°à²¿ à²¬à³à²°à³ à²¬à³à²°à³ à²à³à²·à³à²€à³à²°à²Š à²žà³à²à³ à²¶à³à²§à²šà³à²¯à²šà³à²šà³ à²žà²à³à²°à²¿à²¯à²à³à²³à²¿à²žà³à²€à³à²€à²Šà³. _textsearchtypeprefsform_ </li>
+</ul>}  
+
+
+
+_texttanumbrowseoptions_ [l=kn] {à² à²žà²à²à³à²°à²¹à²£à³à²¯à²²à³à²²à²¿ _numbrowseoptions_ à²®à²Ÿà²¹à²¿à²€à²¿ à²ªà²¡à³à²¯à³à²µ à²¬à²à³à²à²³à²¿à²µà³ :}  
+
+_textsimplehelpheading_ [l=kn] {à²žà²à²à³à²°à²¹à²£à³à²¯à²²à³à²²à²¿ _collectionname_ à²®à²Ÿà²¹à²¿à²€à²¿ à²¹à³à²à³ à²ªà²¡à³à²¯à³à²µà³à²Šà³}  
+
+_texthelpscopetitle_ [l=kn] {à²ªà³à²°à²¶à³à²šà³à²à²³ à²µà³à²¯à²Ÿà²ªà³à²€à²¿}  
+_texthelpscope_ [l=kn] {<p>
+à²¬à²¹à³à²€à³à² à²žà²à²à³à²°à²¹à²à²³à³ à²¶à³à²§à²šà³ à²®à²Ÿà²¡à²²à³ à²¹à²²à²µà³ à²¬à²à³à²¯ à²žà³à²à²¿à²à²³à²šà³à²šà³ à²à²Šà²à²¿à²žà³à²€à³à²€à²µà³. à².à²Šà²Ÿ. à²²à³à²à²à²° à²®à²€à³à²€à³ à²¶à³à²°à³à²·à²¿à²à³ à²žà³à²à²¿à²à²³à²¿à²°à²¬à²¹à³à²Šà³ à²
+à²¥à²µà²Ÿ à²
+à²§à³à²¯à²Ÿà²¯ à²
+à²¥à²µà²Ÿ à²ªà³à²¯à²Ÿà²° à²®à²à³à²à²Š à²žà³à²à²¿à²à²³à²¿à²°à²¬à²¹à³à²Šà³. à²šà³à²µà³ à²¯à²Ÿà²µà³à²Šà³ à²žà³à²à²¿à²¯à²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¿ à²¶à³à²§à²¿à²žà²¿à²Šà²°à³ à²¹à³à²²à³à²µ à²ªà³à²°à³à²£ à²Šà²žà³à²€à²Ÿà²µà³à²à³ à²²à²­à³à²¯à²µà²Ÿà²à³à²€à³à²€à²Šà³.
+<p>à²²à²­à³à²¯à²µà²Ÿà²Š à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³ à²ªà³à²žà³à²€à²à²à²³à²²à³à²²à²¿à²Šà³à²Šà²°à³ à²
+à²µà³ à²à²à²¿à²€à²žà³à²¥à²³à²Šà²²à³à²²à²¿ à²€à³à²°à³à²¯à²²à³à²ªà²¡à³à²€à³à²€à²µà³}  
Index: /gsdl/stable/macros/kannada2.dm
===================================================================
--- /gsdl/stable/macros/kannada2.dm	(revision 20131)
+++ /gsdl/stable/macros/kannada2.dm	(revision 20131)
@@ -0,0 +1,1079 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Language text and icon macros , translated from english.dm
+# in July 2009 by S.K. Lalitha  and K.S. Raghavan of 
+# the Sarada Ranganathan Endowment for Library Science, Bangalore
+# -- this file contains text that is of less importance
+######################################################################
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=kn] {à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³}  
+_lastupdate_ [l=kn] {à²à²¡à³à²¯ à²à²§à³à²šà³à²à²°à²£}  
+_ago_ [l=kn] {à²Šà²¿à²šà²à²³ à²¹à²¿à²à²Šà³}  
+_colnotbuilt_ [l=kn] {à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²¿à²žà²¿à²²à³à²²}  
+
+### taken from here
+
+_textpoem_ [l=kn] {<br><h2>à²à²¿à²¯ à²ªà²ªà²ªà³à²šà²®à³ à²€à³ à²®à³à²µà²Ÿà²š</h2>
+
+<p>à²à²¿à²¯ à²¹à³à²° à²€à³ à²®à²°à²¿à²šà³,
+<br>à²à²¿à²¯ à²€à³à²°à³ à²€à³ à²à²°à³à²¹à²¿à²°à³à²¹à²¿,
+<br>à²à²¿à²¯ à²ªà²ªà²ªà³à²šà²®à³ à²€à³ à²®à³à²µà²Ÿà²š
+
+<p>à²¶à²Ÿà²à²€à²¿ à²®à²€à³à²€à³ à²žà³à²¥à²¬à³à²Šà²€à³ à²šà²¿à²®à³à²®à²šà³à²šà³ à²à²µà²°à²¿à²žà²²à²¿
+<br>à²µà²žà²à²€à²Š à²žà³à²à³à²·à³à²£à²Šà²²à³à²²à²¿ à²šà³à²µà³ à²à²°à³à²µà²à²€à²Ÿà²à²²à²¿
+<br>à²šà³à²µà³ à²ªà³à²°à²¯à²Ÿà²£ à²®à²Ÿà²¡à³à²µ à²žà²Ÿà²à²°à²µà³ à²šà²¯à²à³à²³à²¿à²žà²¿à²Š à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²šà²à²€à³ à²žà³à²à²®à²µà²Ÿà²à²¿à²°à²²à²¿}  
+
+_textgreenstone_ [l=kn] {<p> à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â (à²¹à²žà²¿à²°à³ à²®à²£à²¿) à²šà³à²¯à³à²à²¿à²²à³à²à²¡à³ à²Šà³à²¶à²Šà²²à³à²²à²¿ à²Šà³à²°à²à³à²µ à²à²à²Šà³ à²®à²£à²¿. à²
+à²²à³à²²à²¿à²š à²®à²Ÿà²à²°à²¿ à²žà²®à³à²Šà²Ÿà²¯ 
+à² à²®à²£à²¿à²à³ à²¬à²¹à²³ à²ªà³à²°à²Ÿà²¶à²žà³à²€à³à²¯ à²šà³à²¡à²¿à²€à³à²€à³. à² à²®à²£à²¿ à²ªà³à²°à²Ÿà²£ à²à³à²€à²šà²µà³à²à²Šà³ à²ªà²°à²¿à²à²£à²¿à²žà²²à²Ÿà²Š <i>à²µà³à²°à³à²µ</i>à²µà²šà³à²šà³ à²¹à³à²°à²¿ à²¹à²¿à²¡à²¿à²Šà²¿à²à³à²à³à²à³à²³à³à²³à³à²€à³à²€à²Šà³.
+à² à²à²Ÿà²°à²£à²Šà²¿à²à²Šà²Ÿà²à²¿ à²à²Šà³ à² à²€à²à²€à³à²°à²Ÿà²à²¶à²à³à²à³ à²¹à²Ÿà²à³ à² à²ªà³à²°à²Ÿà²¯à³à²à²šà³à²à³ à²à²à²Šà³ à²žà³à²à³à²€ à²žà²à²à³à²€ à²²à²Ÿà²à²à²š.  à²à²Šà²° à²à²Ÿà²à²€à²¿, à²ªà²Ÿà²°à²Šà²°à³à²¶à²¿à²à²€à³, à²à² à²¿à²£à²€à³, à²®à²€à³à²€à³ à²à²Šà²°
+à²¹à²°à²¿à²€à²µà²Ÿà²Š à²
+à²à²à³à²à²³à³ à²à³à²°à²®à²µà²Ÿà²à²¿ à²à²Šà²° à²à²Šà²Ÿà²°à³à²¯, à²ªà³à²°à²Ÿà²®à²Ÿà²£à²¿à²à²€à³, à²žà³à²¥à³à²°à³à²¯ à²¹à²Ÿà²à³ à²šà³à²¯à²Ÿà²¯à²µà²šà³à²šà³ à²¬à²¿à²à²¬à²¿à²žà³à²€à³à²€à²µà³. à² à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²€à²à²€à³à²°à²Ÿà²à²¶à²Š 
+à²²à²Ÿà²à²à²š à²à²¿à²¹à³à²šà³à²¯à²Ÿà²à²¿ à²¬à²³à²žà²²à²Ÿà²à²¿à²°à³à²µ <i>à²ªà²à³</i>à²
+à²¥à²µà²Ÿ à²²à²Ÿà² à²¿, à² à²®à²£à²¿à²¯ à²à³à²€à³à²€à²¿à²Š à²à³à²°à³. à²
+à²Šà³ à² à²ªà³à²°à²Ÿà²¯à³à²à²šà³à²¯à²²à³à²²à²¿ à²à³à²²à²žà²®à²Ÿà²¡à³à²€à³à²€à²¿à²°à³à²µ à²šà²®à³à²® 
+à²à²¬à³à²¬ à²žà²¹à³à²Šà³à²¯à³à²à²¿à²¯ à²µà²à²¶ à²ªà²Ÿà²°à²à²ªà²°à³à²¯ à²žà³à²µà²€à³à²€à³. à²šà³à²° à²žà³à²«à²°à³à²§à³à²à²³à²²à³à²²à²¿ à²à²Šà²° à²¬à²³à²à³ à²à³à²·à²¿à²ªà³à²°, à²à²à²¿à²€ à²®à²€à³à²€à³ à²žà²à²ªà³à²°à³à²£. à² à²à²²à³à²² à²à³à²£à²à²³à³ 
+à²šà²®à³à²® à²€à²à²€à³à²°à²Ÿà²à²¶à²à³à²à³ à²
+à²šà³à²µà²¯à²¿à²žà³à²€à³à²€à²Šà³,  <i>à²ªà²à³</i>à²µà²¿à²š à²¹à²°à²¿à²€à²µà²Ÿà²Š à²®à³à²šà³ à²€à²à²€à³à²°à²Ÿà²à²¶à²Š à²
+à²à³à²°à²€à³à²¯à²šà³à²šà³ à²¬à²¿à²à²¬à²¿à²žà³à²€à³à²€à²Šà³ à²à²à²Šà³ à²šà²®à³à²® à²šà²à²¬à²¿à²à³.</p>}  
+
+_textaboutgreenstone_ [l=kn] {<p>à²¬à²³à²à³à²Šà²Ÿà²°à²°à²¿à²à³ - à²µà²¿à²¶à³à²·à²µà²Ÿà²à²¿ à²µà²¿à²¶à³à²µà²µà²¿à²Šà³à²¯à²Ÿà²šà²¿à²²à²¯à²à²³à³, à²à³à²°à²à²¥à²Ÿà²²à²¯à²à²³à³ à²®à²€à³à²€à³ à²à²€à²° à²žà²Ÿà²°à³à²µà²à²šà²¿à²
+à²žà³à²µà²Ÿ à²žà²à²žà³à²¥à³à²à²³à²¿à²à³ - à²€à²®à³à²®à²Šà³ à²à²Š à²¡à²¿à²à²¿à²à²²à³â à²à³à²°à²à²¥à²Ÿà²²à²¯à²à²³à²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà²²à³ à²
+à²§à²¿à²à²Ÿà²° à²šà³à²¡à³à²µà³à²Šà³ 
+à² à²€à²à²€à³à²°à²Ÿà²à²¶à²Š  à²à²Šà³à²Šà³à²¶. à²µà²¿à²à³à²šà²Ÿà²š, à²¶à²¿à²à³à²·à²£ à²®à²€à³à²€à³ à²žà²à²žà³à²à³à²€à²¿ à²à³à²·à³à²€à³à²°à²à²³à²²à³à²²à²¿ à²¯à³à²šà³à²žà³à²à³à²Š à²žà²¹à²­à²Ÿà²à²¿ 
+à²žà²à²žà³à²¥à³à²à²³à²²à³à²²à²¿, à²µà²¿à²¶à³à²·à²µà²Ÿà²à²¿ à²
+à²­à²¿à²µà³à²Šà³à²§à²¿à²¶à³à²² à²°à²Ÿà²·à³à²à³à²°à²à²³à²²à³à²²à²¿, à²®à²Ÿà²¹à²¿à²€à²¿ à²à³à²°à²¹à²£ à²®à²€à³à²€à³ à²µà²¿à²€à²°à²£à²Ÿ à²µà²¿à²§à²Ÿà²šà²à²³à²šà³à²šà³ 
+à²¡à²¿à²à²¿à²à²²à³ à²à³à²°à²à²¥à²Ÿà²²à²¯à²à²³à³ à²
+à²®à³à²²à²Ÿà²à³à²°à²µà²Ÿà²à²¿ à²žà³à²§à²Ÿà²°à²¿à²žà²¿à²µà³. à² à²€à²à²€à³à²°à²Ÿà²à²¶à²µà²šà³à²šà³ à²«à²²à²à²Ÿà²°à²¿à²¯à²Ÿà²à²¿ à²¬à²³à²žà²¿à²à³à²à²¡à³ 
+à²¡à²¿à²à²¿à²à²²à³ à²à³à²°à²à²¥à²Ÿà²²à²¯à²à²³à²šà³à²šà³ à²¹à²Ÿà²à³ à²
+à²µà³à²à²³ à²®à³à²²à² à²à²²à³à²² à²®à²Ÿà²¹à²¿à²€à²¿à²¯à³ à²žà²Ÿà²°à³à²µà²à²šà²¿à² à²žà³à²µà²Ÿà²®à³à²¯à²Šà²²à³à²²à²¿ 
+à²à²²à³à²²à²°à²¿à²à³ à²Šà³à²°à²à³à²µà²à²€à²Ÿà²à²¬à³à²à³à²à²¬à³à²Šà³ à²šà²®à³à²® à²à²¶à²¯.
+</p>}  
+
+
+_textdescrselcol_ [l=kn] {à²à²à²Šà³ à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²à²°à²¿à²žà²¿}  
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=kn] {à²®à³à² à²ªà³à²à²Šà²²à³à²²à²¿ à²®à²€à³à²€à³ à²šà²Ÿà²²à³à²à³ à²à³à²à²¡à²¿à²à²³à²¿à²µà³}  
+
+_textnocollections_ [l=kn] {<p>à² à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà³à²¥à²Ÿà²ªà²¿à²€à²Šà²²à³à²²à²¿ à²ªà³à²°à²žà³à²€à³à²€ à²¯à²Ÿà²µà³à²Šà³ à²žà²à²à³à²°à²¹à²à²³à²¿à²²à³à²². 
+à²à³à²²à²µà³ à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ à²žà³à²°à²¿à²žà²²à³ à²šà³à²µà³ à²®à²Ÿà²¡à²¬à³à²à²Ÿà²à²¿à²°à³à²µà³à²Šà³à²šà³à²à²Šà²°à³
+<ul><li><a href="_httppagecollector_">The Collector</a> à²à²ªà²¯à³à²à²¿à²žà²¿ à²¹à³à²ž à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà²¿ à²
+à²¥à²µà²Ÿ 
+    <li>à²à²à²Šà³à²µà³à²³à³ à²šà²¿à²®à³à²®à²²à³à²²à²¿ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà²¿à²¡à²¿ à²°à³à²®à³ à²à²Šà³à²Šà²²à³à²²à²¿ à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²žà²¿à²¡à²¿ à²°à³âà²®à³âà²šà²¿à²à²Š à²žà³à²¥à²Ÿà²ªà²¿à²žà²¬à²¹à³à²Šà³
+</ul>}  
+
+_text1coll_ [l=kn] {à² à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà³à²¥à²Ÿà²ªà²¿à²€à²µà³ 1 à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²¹à³à²à²Šà²¿à²Šà³}  
+
+_textmorecolls_ [l=kn] {_1_à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ à² à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà³à²¥à²Ÿà²ªà²¿à²€à²µà³ à²¹à³à²à²Šà²¿à²Šà³}  
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=kn] {à²¬à²Ÿà²¹à³à²¯ à²à³à²à²¡à²¿}  
+_textlinknotfound_ [l=kn] {à²à²à²€à²°à²¿à² à²à³à²à²¡à²¿ à²à²Ÿà²£à³à²€à³à²€à²¿à²²à³à²²}  
+
+_textextlinkcontent_ [l=kn] {à²šà³à²µà³ à²à²¯à³à²à³ à²®à²Ÿà²¡à²¿à²°à³à²µ à²à³à²à²¡à²¿ à²šà³à²µà³ à²ªà³à²°à²žà³à²€à³à²€ à²à²¯à³à²à³ à²®à²Ÿà²¡à²¿à²à³à²à²¡à²¿à²°à³à²µ à²¯à²Ÿà²µà³à²Šà³ à²žà²à²à³à²°à²¹à²à³à²à³ à²¬à²Ÿà²¹à³à²¯. à²à²Šà²Ÿà²à³à²¯à³ à²šà³à²µà³ à² à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²šà³à²¡à²¬à²¯à²žà²¿à²Šà²°à³ à²®à²€à³à²€à³ à²šà²¿à²®à³à²® à²¬à³à²°à³à²žà²°à³âà²à³ à²µà³à²¬à³ à²ªà³à²°à²µà³à²¶à²¿à²žà²²à³ à²žà²Ÿà²§à³à²¯à²µà²Ÿà²Šà²°à³, à²šà³à²µà³ à² à²ªà³à²à²à³à²à³ <a href="_nexturl_">go forward</a> à²®à²Ÿà²¡à²¿.  à²
+à²¥à²µà²Ÿ à²šà²¿à²®à³à²® à²¬à³à²°à³à²žà²°à³âà²š "back" à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à²€à³à²€à²¿ à² à²¹à²¿à²à²Šà²¿à²š à²Šà²žà³à²€à²Ÿà²µà³à²à²¿à²à³ à²¹à²¿à²à²Šà²¿à²°à³à²à²¿.}  
+
+_textlinknotfoundcontent_ [l=kn] {à²šà²®à³à²® à²¹à²€à³à²à²¿à²à³ à²®à³à²°à²¿à²Š à²à³à²²à²µà³ à²à²Ÿà²°à²£à²à²³à²¿à²à²Šà²Ÿà²à²¿ à²šà³à²µà³ à²à²¯à³à²à³ à²®à²Ÿà²¡à²¿à²Š à²à²à²€à²°à²¿à² à²à³à²à²¡à²¿ à²
+à²žà³à²€à²¿à²€à³à²µà²Šà²²à³à²²à²¿à²²à³à²². 
+à²®à³à²² à²žà²à²à³à²°à²¹à²Šà²²à³à²²à²¿à²š à²¯à²Ÿà²µà³à²Šà²Ÿà²Šà²°à³ à²šà³à²¯à³à²šà²€à³à²¯à²¿à²à²Šà²Ÿà²à²¿ à²¹à³à²à²Ÿà²à²¿à²°à²¬à²¹à³à²Šà³. à²šà²¿à²®à³à²® à²¬à³à²°à³à²žà²°à³âà²š "back" 
+à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à²€à³à²€à²¿ à² à²¹à²¿à²à²Šà²¿à²š à²Šà²žà³à²€à²Ÿà²µà³à²à²¿à²à³ à²¹à²¿à²à²Šà²¿à²°à³à²à²¿. }  
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=kn] {<h3>"_2_" à²žà²à²à³à²°à²¹à²à³à²à³ à²à²à²à²¿à²žà³</h3>
+
+<p> à²šà³à²µà³ à²à²¯à³à²à³ à²®à²Ÿà²¡à²¿à²°à³à²µ à²à³à²à²¡à²¿ "_collectionname_" à²žà²à²à³à²°à²¹à²à³à²à³ à²¬à²Ÿà²¹à³à²¯ (à²
+à²Šà³ "_2_" à²žà²à²à³à²°à²¹à²à³à²à³ à²à²à²à²¿à²žà³à²€à³à²€à²Šà³).
+à²šà³à²µà³ à² à²à³à²à²¡à²¿à²¯à²šà³à²šà³ "_2_" à²žà²à²à³à²°à²¹à²Šà²²à³à²²à²¿ à²šà³à²¡à²¬à²¯à²žà²¿à²Šà²°à³ à² à²ªà³à²à²à³à²à³ 
+<a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">go forward</a> à²®à²Ÿà²¡à²¿; 
+à²
+à²¥à²µà²Ÿ à²šà²¿à²®à³à²® à²¬à³à²°à³à²žà²°à³ à²šà³ "back" à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à²€à³à²€à²¿ à² à²¹à²¿à²à²Šà²¿à²š à²Šà²žà³à²€à²Ÿà²µà³à²à²¿à²à³ à²¹à²¿à²à²Šà²¿à²°à³à²à²¿.}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²¡à²¿à²à²¿à²à²²à³â  à²²à³à²¬à³à²°à²°à²¿}  
+
+_textusername_ [l=kn] {à²¬à²³à²à³à²Šà²Ÿà²°à²° à²¹à³à²žà²°à³}  
+_textpassword_ [l=kn] {à²žà²à²à³à²€ à²ªà²Š}  
+
+_textmustbelongtogroup_ [l=kn] {à² à²ªà³à²à²µà²šà³à²šà³ à²šà³à²¡à²²à³ à²šà³à²µà³ "_cgiargug_" à²à³à²à²ªà²¿à²à³ à²žà³à²°à²¿à²Šà²µà²°à²Ÿà²à²¿à²°à²¬à³à²à³}  
+
+_textmessageinvalid_ [l=kn] {à²šà²¿à²®à²à³ à²¬à³à²à²Ÿà²à²¿à²°à³à²µ à²ªà³à²à²à³à²à³ à²šà³à²µà³ à²°à³à²à³à²®à²Ÿà²¡à²¿ à²à²³ à²¬à²°à²¬à³à²à³.<br> _If_(_cgiargug_,[_textmustbelongtogroup_]<br>)à²Šà²¯à²µà²¿à²à³à²à³ à²šà²¿à²®à³à²® à²¬à²³à²à³à²Šà²Ÿà²°à²° à²¹à³à²žà²°à³ à²®à²€à³à²€à³ à²žà²à²à³à²€à²ªà²Šà²µà²šà³à²šà³ à²¬à²°à³à²¯à²¿à²°à²¿}  
+
+_textmessagefailed_ [l=kn] {à²šà²¿à²®à³à²® à²¬à²³à²à³à²Šà²Ÿà²°à²° à²¹à³à²žà²°à³ à²
+à²¥à²µà²Ÿ à²žà²à²à³à²€à²ªà²Š à²€à²ªà³à²ªà²Ÿà²à²¿à²Šà³}  
+
+_textmessagedisabled_ [l=kn] {à²à³à²·à²®à²¿à²žà²¿. à²šà²¿à²®à³à²® à²à²Ÿà²€à³à²¯à²šà³à²šà³ à²šà²¿à²·à³à²à³à²°à²¿à²¯à²à³à²³à²¿à²žà²²à²Ÿà²à²¿à²Šà³. à²µà³à²¬à³ à²®à²Ÿà²žà³à²€à²°à²šà³à²šà³ à²žà²à²ªà²°à³à²à²¿à²žà²¿}  
+
+_textmessagepermissiondenied_ [l=kn] {à²à³à²·à²®à²¿à²žà²¿, à² à²ªà³à² à²ªà³à²°à²µà³à²¶à²¿à²žà²²à³ à²šà²¿à²®à²à³ à²
+à²šà³à²®à²€à²¿à²¯à²¿à²²à³à²²}  
+
+_textmessagestalekey_ [l=kn] {à²šà³à²µà³ à²à²ªà²¯à³à²à²¿à²žà²¿à²Š à²à³à²à²¡à²¿ à²à² à²à²Ÿà²²à³à²€à²¿à²¯à²²à³à²²à²¿à²²à³à²². 
+à² à²ªà³à² à²ªà³à²°à²µà³à²¶à²¿à²žà²²à³ à²šà²¿à²®à³à²® à²žà²à²à³à²€ à²ªà²Šà²µà²šà³à²šà³ à²à²Šà²à²¿à²žà²¿.}  
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=kn] {<p>à² à²žà³à²¥à²Ÿà²ªà²šà³à²¯à²²à³à²²à²¿ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà²à²¬à²à²§à²¿à²€ à²¯à²Ÿà²µà³à²Šà³ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³ à²à²²à³à²². 
+à²à²Šà²à³à²à³ à² à²à²Ÿà²°à²£à²à²³à²¿à²°à²¬à²¹à³à²Šà³:
+<ol>
+<li>à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²à²à²Šà³ à²žà²¿ à²¡à²¿ à²°à³à²®à³ à²šà²¿à²à²Š à²žà²à²à³à²·à²¿à²ªà³à²€à²µà²Ÿà²à²¿ à²žà³à²¥à²Ÿà²ªà²¿à²žà²²à³à²ªà²à³à²à²¿à²€à³.
+<li>à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²
+à²à²€à²°à³à²à²Ÿà²² à²®à³à²²à² à²µà²¿à²€à²°à²¿à²žà²²à³à²ªà²à³à² à²à²à²Šà³ à²®à³à²²à²Šà²¿à²à²Š à²žà³à²¥à²Ÿà²ªà²¿à²žà²²à³à²ªà²à³à²à²¿à²€à³.
+</ol>
+à²¯à²Ÿà²µà³à²Šà³ à²à²Ÿà²°à²£à²µà²¿à²Šà³à²Šà²°à³ à²šà³à²µà³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà²à²¬à²à²§à²¿à²€ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà²¿ à²¡à²¿ à²°à³à²®à³âà²š
+<i>docs</i> à²¡à³à²°à²à³à²à²°à²¿à²¯à²¿à²à²Š à²
+à²¥à²µà²Ÿ <a href="http://www.greenstone.org">http://www.greenstone.org</a>
+à²šà³à²šà³ à²žà²à²Šà²°à³à²¶à²¿à²žà³à²µà³à²Šà²° à²®à³à²²à² à²ªà²¡à³à²Šà³à²à³à²³à³à²³à²¬à²¹à³à²Šà³.}  
+
+_textuserguide_ [l=kn] {à²¬à²³à²à³à²Šà²Ÿà²°à²š à²®à²Ÿà²°à³à²à²Šà²°à³à²¶à²¿}  
+_textinstallerguide_ [l=kn] {à²žà³à²¥à²Ÿà²ªà²šà³à²Šà²Ÿà²°à²š à²®à²Ÿà²°à³à²à²Šà²°à³à²¶à²¿}  
+_textdeveloperguide_ [l=kn] {à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²Ÿà²ªà²à²° à²®à²Ÿà²°à³à²à²Šà²°à³à²¶à²¿}  
+_textpaperguide_ [l=kn] {à²à²Ÿà²à²Šà²Šà²¿à²à²Š à²žà²à²à³à²°à²¹à²à³à²à³}  
+_textorganizerguide_ [l=kn] {à²à²°à³à²à²šà³à²à²°à³ à²à²ªà²¯à³à²}  
+
+_textgsdocstitle_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà²à²¬à²à²§à²¿à²€ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³}  
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=kn] {à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà²¿}  
+_textbildsuc_ [l=kn] {à²žà²à²à³à²°à²¹ à²žà²«à²²à²µà²Ÿà²à²¿ à²šà²¿à²°à³à²®à²¿à²žà²²à²Ÿà²¯à²¿à²€à³}  
+_textviewbildsummary_ [l=kn] {à²šà³à²µà³ à² à²žà²à²à³à²°à²¹à²Š <a href="_httppagex_(bsummary)" target=_top>view the build
+summary</a> à²šà²²à³à²²à²¿ à²¹à³à²à³à²à²¿à²š à²µà²¿à²µà²°à²à²³à²šà³à²šà³ à²šà³à²¡à²¬à²¹à³à²Šà³ 
+}  
+_textview_ [l=kn] {à²žà²à²à³à²°à²¹ à²µà³à²à³à²·à²¿à²žà²¿}  
+
+_textbild1_ [l=kn] {à²à² à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²Ÿà²£ à²ªà³à²°à²Ÿà²°à²à²­à²µà²Ÿà²à²¿à²Šà³; à²à²Šà³ à²žà³à²µà²²à³à²ª à²žà²®à²¯ à²€à³à²à³à²Šà³ à²à³à²³à³à²³à²¬à²¹à³à²Šà³. à²à²Ÿà²°à³à²¯à²à²€à²¿ à²¹à³à²à³  
+à²šà²¡à³à²¯à³à²€à³à²€à²¿à²Šà³ à²à²à²¬à³à²Šà²° à²µà²¿à²µà²°à²à²³à²šà³à²šà³ à²à³à²³à²à²¿à²š à²žà²à²à³à²°à²¹ à²žà³à²¥à²¿à²€à²¿à²¯ à²žà²Ÿà²²à³ à²šà³à²¡à³à²€à³à²€à²Šà³.}  
+
+_textbild2_ [l=kn] {à²¯à²µà³à²Šà³ à²žà²®à²¯à²Šà²²à³à²²à²¿ à²šà²¿à²°à³à²®à²¿à²žà³à²µ à²à²Ÿà²°à³à²¯à²à³à²°à²®à²µà²šà³à²šà³ à²šà²¿à²²à³à²²à²¿à²žà²²à³ à²à²²à³à²²à²¿ à²à³à²²à²¿à²à³à²à²¿à²žà²¿.
+<br>à²šà³à²µà³ à²à³à²²à²žà²®à²Ÿà²¡à³à²€à³à²€à²¿à²°à³à²µ à²žà²à²à³à²°à²¹ à²¬à²Šà²²à²Ÿà²à²Šà³ à²à²³à²¿à²¯à³à²€à³à²€à²Šà³.}  
+
+_textstopbuild_ [l=kn] {à²šà²¿à²°à³à²®à²¿à²žà³à²µà³à²Šà²šà³à²šà³ à²šà²¿à²²à³à²²à²¿à²žà³}  
+
+_textbild3_ [l=kn] {à²šà³à²µà³ "à²šà²¿à²°à³à²®à²¿à²žà³à²µà³à²Šà²šà³à²šà³ à²šà²¿à²²à³à²²à²¿à²žà³" à²à³à²à²¡à²¿à²¯ à²®à³à²²à² à²à²Ÿà²°à³à²¯à²µà²šà³à²šà³ à²°à²Šà³à²Šà³à²à³à²³à²¿à²žà²Šà³ à² à²ªà³à²à²µà²šà³à²šà³ 
+à²€à³à²¯à²à²¿à²žà²¿à²Šà²°à³ à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²Ÿà²£ à²®à³à²à²Šà³à²µà²°à²¿à²¯à³à²€à³à²€à²Šà³ à²®à²€à³à²€à³ à²¯à²¶à²žà³à²µà²¿à²¯à²Ÿà²à²¿ à²®à³à²à²¿à²Šà²šà²à²€à²° 
+à²¹à³à²ž à²žà²à²à³à²°à²¹ à²žà³à²¥à²Ÿà²ªà²šà³à²¯à²Ÿà²à³à²€à³à²€à²Šà³. }  
+
+_textbuildcancelled_ [l=kn] {à²šà²¿à²°à³à²®à²Ÿà²£à²µà²šà³à²šà³ à²°à²Šà³à²Šà³à²à³à²³à²¿à²žà²¿à²Šà³}  
+
+_textbildcancel1_ [l=kn] {à²žà²à²à³à²°à²¹à²Š à²šà²¿à²°à³à²®à²Ÿà²£ à²à²Ÿà²°à³à²¯à²µà²šà³à²šà³ à²°à²Šà³à²Šà³à²à³à²³à²¿à²žà²²à²Ÿà²¯à²¿à²€à³. à²šà²¿à²®à³à²® à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²²à³ à²
+à²¥à²µà²Ÿ
+à²šà²¿à²°à³à²®à²Ÿà²£ à²à²Ÿà²°à³à²¯à²µà²šà³à²šà³ à²®à²€à³à²€à³ à²ªà³à²°à²Ÿà²°à²à²­à²¿à²žà²²à³ à²à³à²³à²à²¿à²°à³à²µ à²¹à²³à²Šà²¿ à²¬à²£à³à²£à²Š à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿.}  
+
+_textbsupdate1_ [l=kn] {à²à²à²Šà³ à²žà³à²à³à²à²¡à³âà²šà²²à³à²²à²¿ à²šà²¿à²°à³à²®à²Ÿà²£ à²žà³à²¥à²¿à²€à²¿ à²šà²µà³à²à²°à²£à²à³à²³à³à²³à³à²€à³à²€à²Šà³ }  
+_textbsupdate2_ [l=kn] {à²šà²¿à²°à³à²®à²Ÿà²£ à²žà³à²¥à²¿à²€à²¿ à²šà²µà³à²à²°à²£}  
+_textseconds_ [l=kn] {à²à³à²·à²£à²à²³à³}  
+
+_textfailmsg11_ [l=kn] {à²¯à²Ÿà²µà³à²Šà³ à²Šà²€à³à²€à²Ÿà²à²¶ à²à²²à³à²²à²Š à²à²Ÿà²°à²£ à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà²²à²Ÿà²à²²à²¿à²²à³à²². à²šà³à²µà³ <i>à²®à³à²² à²Šà²€à³à²€à²Ÿà²à²¶</i> 
+à²ªà³à²à²Šà²²à³à²²à²¿ à²šà²®à³à²Šà²¿à²žà²¿à²Š à²¯à²Ÿà²µà³à²Šà²Ÿà²Šà²°à³à²à²Šà³ à²à²¡à²€ à²à²à³à²à³ à²
+à²¥à²µà²Ÿ à²à²¡à²€ à²à²Šà³ à²®à²€à³à²€à³ à²
+à²Šà³ 
+à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà²à²žà³à²à²°à²¿à²žà²¬à²²à³à²² à²¬à²à³à²¯ à²à²¡à²€ à²
+à²¥à²µà²Ÿ à²
+à²Šà³ à²à²à²Šà³ à²à²¡à²€ à²à²à³à²à²Ÿà²à²¿à²Šà³à²Šà²²à³à²²à²¿ à²
+à²Šà²°à²²à³à²²à²¿ 
+à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà²à²žà³à²à²°à²¿à²žà²¬à²²à³à²² à²¬à²à³à²¯ à²à²¡à²€à²à²³à²¿à²µà³ à²à²à²¬à³à²Šà²šà³à²šà³ à²à²à²¿à²€à²ªà²¡à²¿à²žà²¿à²à³à²³à³à²³à²¿. }  
+
+_textfailmsg21_ [l=kn] {à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà²²à³ à²žà²Ÿà²§à³à²¯à²µà²Ÿà²à²²à²¿à²²à³à²² (import.pl à²µà²¿à²«à²²à²¹à³à²à²Šà²¿à²Šà³).}  
+_textfailmsg31_ [l=kn] {à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà²²à³ à²žà²Ÿà²§à³à²¯à²µà²Ÿà²à²²à²¿à²²à³à²² (buildcol.pl à²µà²¿à²«à²²à²¹à³à²à²Šà²¿à²Šà³).}  
+_textfailmsg41_ [l=kn] {à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²žà²«à²²à²µà²Ÿà²à²¿ à²šà²¿à²°à³à²®à²¿à²žà²²à²Ÿà²¯à²¿à²€à³ à²à²Šà²°à³ à²žà³à²¥à²Ÿà²ªà²¿à²žà²²à³ à²žà²Ÿà²§à³à²¯à²µà²Ÿà²à²²à²¿à²²à³à²²}  
+_textfailmsg71_ [l=kn] {à²šà²¿à²®à³à²® à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà³à²µ à²ªà³à²°à²¯à²€à³à²šà²Šà²²à³à²²à²¿à²Šà³à²Šà²Ÿà² à²
+à²šà²¿à²°à³à²à³à²·à²¿à²€ à²€à²ªà³à²ªà³ à²žà²à²­à²µà²¿à²žà²¿à²Šà³}  
+
+
+_textblcont_ [l=kn] {à²šà²¿à²°à³à²®à²Ÿà²£ à²²à²Ÿà²à³â à² à²°à³à²€à²¿à²¯à²Ÿà²Š à²®à²Ÿà²¹à²¿à²€à²¿à²¯à²šà³à²šà³ à²¹à³à²à²Šà²¿à²Šà³:}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=kn] {à²ªà³à²°à³à²µà²šà²¿à²¯à³à²à²¿à²€ à²µà³à²¯à²µà²žà³à²¥à³}  
+_textmore_ [l=kn] {à²
+à²§à²¿à²}  
+_textinfo_ [l=kn] {à²žà²à²à³à²°à²¹à²à³à²à³ à²žà²à²¬à²à²§à²¿à²žà²¿à²Š à²®à²Ÿà²¹à²¿à²€à²¿}  
+_textsrce_ [l=kn] {à²®à³à²² à²Šà²€à³à²€à²Ÿà²à²¶}  
+_textconf_ [l=kn] {à²žà²à²à³à²°à²¹à²Š à²žà²®à²à³à²°à²Ÿà²à³à²€à²¿à²à³à²³à²¿à²žà³}  
+_textdel_ [l=kn] {à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²€à³à²à³à²¯à²¿à²°à²¿}  
+_textexpt_ [l=kn] {à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²°à²«à³à²€à³ à²®à²Ÿà²¡à²¿}  
+
+_textdownloadingfiles_ [l=kn] {à²à²¡à²€à²à²³à³ à²à³à²³à²à²¿à²³à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à²¿à²µà³ .....}  
+_textimportingcollection_ [l=kn] {à²žà²à²à³à²°à²¹ à²à²®à²Šà²Ÿà²à³à²€à³à²€à²¿à²Šà³...}
+_textbuildingcollection_ [l=kn] {à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²Ÿà²£à²µà²Ÿà²à³à²€à³à²€à²¿à²Šà³âŠ}  
+_textcreatingcollection_ [l=kn] {à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à²¿à²Šà³ ....}  
+
+_textcollectorblurb_ [l=kn] {<i>à²²à³à²à²šà²¿ à²à²€à³à²€à²¿à²à²¿à²à²€ à²¶à²à³à²€à²¿à²¯à³à²€!
+<br>à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà²¿ à²
+à²µà²šà³à²šà³ à²à²²à³à²²à²°à²¿à²à³ à²à²Šà²à²¿à²žà³à²µ à²®à³à²šà³à²š à²šà³à²µà³ à²šà²¿à²®à³à²® à²à²µà²Ÿà²¬à³à²Šà²Ÿà²°à²¿à²à²³ à²¬à²à³à²à³ à²¯à³à²à²¿à²žà²¬à³à²à²Ÿà²à³à²€à³à²€à²Šà³. 
+à²à²Ÿà²ªà²¿à²°à³à²à³ à²žà²à²¬à²à²§ à²à²Ÿà²šà³à²šà³à²à²³à³ à²
+à²šà³à²µà²¯à²¿à²žà²¬à²¹à³à²Šà³. à²à²à²Šà³ à²Šà²žà³à²€à²Ÿà²µà³à²à²šà³à²šà³ à²šà³à²µà³ à²šà³à²¡à²²à³ à²žà²Ÿà²§à³à²¯à²µà²Ÿà²Šà²°à³ 
+à²
+à²Šà²šà³à²šà³ à²à²²à³à²²à²°à²¿à²à³ à²à²Šà²à²¿à²žà²¬à²¹à³à²Šà³ à²à²à²Šà³ à²
+à²°à³à²¥à²µà²²à³à²². à²¹à²Ÿà²à³à²¯à³ à² à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³ à²¹à³à²°à²¬à²à²Š à²žà²®à²Ÿà²à²Š 
+à²°à³à²¢à²¿à²à²³à²šà³à²šà³ à²à³à²°à²µà²¿à²žà²¬à³à²à²Ÿà²à³à²€à³à²€à²Šà³. à²
+à²Šà²²à³à²²à²Šà³ à²šà³à²€à²¿à² à²¹à²Ÿà²à³ à²®à³à²²à³à²¯à²Ÿà²§à²Ÿà²°à²¿à²€ à²µà²¿à²·à²¯à²à²³à²šà³à²šà³ à²à²®à²šà²¿à²žà²¬à³à²à³; 
+à²à³à²²à²µà³ à²¬à²à³à²¯ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³ à²®à²€à³à²€à³ à²®à²Ÿà²¹à²¿à²€à²¿à²¯à²šà³à²šà³ à²à²²à³à²²à²°à²¿à²à³ à²à²Šà²à²¿à²žà³à²µà³à²Šà³ à²žà²Ÿà²§à³à²µà²²à³à²².
+<br> à²®à²Ÿà²¹à²¿à²€à²¿ à²¬à²¹à²³ à²ªà³à²°à²­à²Ÿà²µà²à²Ÿà²°à²¿à²¯à²Ÿà²Šà²Šà³à²Šà³. à²
+à²Šà²šà³à²šà³ à²µà²¿à²µà³à²à²šà³à²¯à²¿à²à²Š à²à²ªà²¯à³à²à²¿à²žà³à²µà³à²Šà³ à²
+à²µà²¶à³à²¯.
+</i> }  
+
+_textcb1_ [l=kn] {à²¹à³à²ž à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà²²à³, à²à²°à³à²µ à²žà²à²à³à²°à²¹à²à²³à²²à³à²²à²¿ à²¬à²Šà²²à²Ÿà²µà²£à³ à²®à²Ÿà²¡à²²à³ à²
+à²¥à²µà²Ÿ à²
+à²µà²šà³à²šà³ à²€à³à²à³à²¯à²²à³ 'à²žà²à²à³à²°à²Ÿà²¹à²' 
+à²žà²¹à²Ÿà²¯à²®à²Ÿà²¡à³à²€à³à²€à²Šà³. à²¹à³à²à³ à²®à²Ÿà²¡à²²à³ à²¹à²²à²µà²Ÿà²°à³ à²µà³à²¬à³ à²ªà³à²à²à²³ à²®à³à²²à² à²šà²¿à²®à³à²®à²šà³à²šà³ à²à²°à³à²Šà³à²¯à³à²Šà³ à²¬à³à²à²Ÿà²Š à²®à²Ÿà²¹à²¿à²€à²¿
+à²à²Šà²à²¿à²žà³à²µà²à²€à³ à²à³à²³à²²à²Ÿà²à³à²€à³à²€à²Šà³.}  
+
+_textcb2_ [l=kn] {à²®à³à²Šà²²à³ à²šà³à²µà³ à²šà²¿à²°à³à²£à²¯à²¿à²žà²¬à³à²à³, à²à²šà³à²à²Šà²°à³}  
+_textcnc_ [l=kn] {à²¹à³à²ž à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà²¿}
+_textwec_ [l=kn] {à²à²à²Ÿà²à²²à³ à²à²°à³à²µ à²žà²à²à³à²°à²¹à²à³à²à³ à²Šà²€à³à²€ à²žà³à²°à²¿à²žà²¿à²¯à³ à²
+à²¥à²µà²Ÿ à²
+à²Šà²°à²¿à²à²Š à²Šà²€à³à²€ à²€à³à²à³à²Šà³ à²à²Ÿà²°à³à²¯ à²šà²¿à²°à³à²µà²¹à²¿à²žà²¿.}  
+
+_textcb3_ [l=kn] {à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²¿à²žà²²à³ à²
+à²¥à²µà²Ÿ à²žà²à²à³à²°à²¹à²Šà²²à³à²²à²¿ à²¬à²Šà²²à²Ÿà²µà²£à³à²à²³à²šà³à²šà³ à²®à²Ÿà²¡à²²à³ à²šà³à²µà³ à²¹à²žà³à²€à²Ÿà²à³à²·à²°à²®à²Ÿà²¡à²¿ à²à²³à²à³ à²¬à²°à²¬à³à²à³.
+à²à²Šà³ à²šà²¿à²®à³à²® à²žà³à²°à²à³à²·à³à²à²Ÿà²à²¿; à²¬à³à²°à³à²¯à²µà²°à³ à²šà²¿à²®à³à²® à²žà²à²à³à²°à²¹à²Šà²²à³à²²à²¿ à²¬à²Šà²²à²Ÿà²µà²£à³à²à²³à²šà³à²šà³ à²®à²Ÿà²¡à³à²µà³à²Šà²šà³à²šà³ à²€à²¡à³à²¯à²²à³ à²à²Šà²°à²¿à²à²Š 
+à²žà²Ÿà²§à³à²¯à²µà²Ÿà²à³à²€à³à²€à²Šà³. à²žà³à²à²šà³: à²šà³à²µà³ à²à²³à²¬à²à²Šà³ à³©à³Š à²šà²¿à²®à²¿à²·à²à²³à²Ÿà²Šà²šà²à²€à²°  à²®à²€à³à²€à³ à²¹à²žà³à²€à²Ÿà²à³à²·à²°à²®à²Ÿà²¡à²¿ à²à²³à²à³ à²¬à²°à²¬à³à²à²Ÿà²à²¬à²¹à³à²Šà³; 
+à²¹à³à²à³à²šà²Ÿà²Šà²°à³ à²à²Šà²°à³ à²à²Ÿà²¬à²°à²¿à²à³à²³à³à²³à²¬à³à²¡à²¿; à²šà³à²µà³ à²¬à²¿à²à³à² à²žà³à²¥à²³à²Šà²¿à²à²Šà²²à³ à²šà²¿à²®à³à²® à²à³à²²à²ž à²®à³à²à²Šà³à²µà²°à²¿à²žà²¬à²¹à³à²Šà³.}  
+
+_textcb4_ [l=kn] {à²šà²¿à²®à³à²® à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²¬à²³à²à³à²Šà²Ÿà²°à²° à²¹à³à²žà²°à³ à²®à²€à³à²€à³ à²žà²à²à³à²€à²ªà²Š à²à²Šà²à²¿à²žà²¿ à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿ à²à²³à²¬à²šà³à²šà²¿}  
+
+_textfsc_ [l=kn] {à²®à³à²Šà²²à³ à²šà³à²µà³ à²à³à²²à²žà²®à²Ÿà²¡à²¬à³à²à²Ÿà²Š à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²à²¯à³à²Šà³à²à³à²³à³à²³à²¿ (à²¬à²°à³à²¯à²²à³ à²€à²¡à³ à²à²°à³à²µ à²žà²à²à³à²°à²¹à²à²³à³ à² à²ªà²à³à²à²¿à²¯à²²à³à²²à²¿ à²¬à²°à³à²µà³à²Šà²¿à²²à³à²²).}  
+
+_textwtc_ [l=kn] {à²à²¯à³à²à³ à²®à²Ÿà²¡à²¿à²°à³à²µ à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²šà³à²µà³}  
+_textamd_ [l=kn] {à²à²šà³à²šà³ à²¹à³à²à³à²à³ à²Šà²€à³à²€à²Ÿà²à²¶ à²ªà³à²°à³à²žà²¿ à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²®à²€à³à²€à³ à²šà²¿à²°à³à²®à²¿à²žà²¿}  
+_textetc_ [l=kn] {à²žà²à²à³à²°à²¹à²Š à²žà²®à²à³à²°à²Ÿà²à³à²€à²¿ à²à²¡à²€à²µà²šà³à²šà³ à²€à²¿à²Šà³à²Šà²¿ à²šà²à²€à²° à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²®à²€à³à²€à³ à²šà²¿à²°à³à²®à²¿à²žà²¿}  
+_textdtc_ [l=kn] {à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²žà²à²ªà³à²°à³à²£à²µà²Ÿà²à²¿ à²€à³à²à³à²¯à²¿à²°à²¿}  
+_textetcfcd_ [l=kn] {à²žà²à²à³à²°à²µà²šà³à²šà³ à²à²à²Šà³ à²žà³à²µà²¯à² à²žà³à²¥à²Ÿà²ªà²¿à²žà²¬à²²à³à²² à²µà²¿à²à²¡à³à²žà³ à²žà²¿à²¡à²¿ à²°à³à²®à³ à²à³ à²¬à²°à³à²¯à²²à³ à²°à²«à³à²€à³ à²®à²Ÿà²¡à²¿}  
+_textcaec_ [l=kn] {à²à²à²Ÿà²à²²à³ à²à²°à³à²µ à²à²à²Šà³ à²žà²à²à³à²°à²¹à²µà³ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à²¿à²Šà³}  
+_textnwec_ [l=kn] {à²¬à²Šà²²à²Ÿà²µà²£à³ à²®à²Ÿà²¡à²²à³, à²¬à²°à³à²¯à²²à³ à²€à²¡à³à²¯à²¿à²²à³à²²à²Š à²¯à²Ÿà²µà³à²Šà³ à²žà²à²à³à²°à²¹ à²à²²à³à²².}  
+_textcianc_ [l=kn] {à²¹à³à²ž à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à²¿à²Šà³}  
+_texttsosn_ [l=kn] {à²à²à²Šà³ à²¹à³à²ž à²¡à²¿à²à²¿à²à²²à³ à²à³à²°à²à²¥à²Ÿà²²à²¯ à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²Ÿà²£à²Šà²²à³à²²à²¿ à²à²°à³à²µ à²¹à²à²€à²à²³à³: }  
+_textsin_ [l=kn] {à²
+à²Šà²° à²¹à³à²žà²°à³ (à²®à²€à³à²€à³ à²žà²à²¬à²à²§à²¿à²žà²¿à²Š à²®à²Ÿà²¹à²¿à²€à²¿à²¯à²šà³à²šà³) à²à²Šà²à²¿à²žà²¿}  
+_textswts_ [l=kn] {à²®à³à²² à²Šà²€à³à²€ à²à²²à³à²²à²¿à²à²Š à²¬à²à²€à³à²à²Šà³ à²€à²¿à²³à²¿à²žà²¿}  
+_textatco_ [l=kn] {à²žà²®à²à³à²°à²Ÿà²à³à²€à²¿à²¯ à²à²à³à²à²¿à²à²à²³à²šà³à²šà³ à²žà²°à²¿à²ªà²¡à²¿à²žà³(à²€à²à³à² à²¬à²³à²à³à²Šà²Ÿà²°à²°à²¿à²à³ à²®à²Ÿà²€à³à²°)}  
+_textbtc_ [l=kn] {à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà²¿ (à² à²à³à²³à²à³ à²šà³à²¡à²¿)}  
+_textpvyh_ [l=kn] {à²šà²¿à²®à³à²® à²à³à²à³à²²à²žà²µà²šà³à²šà³ à²¹à³à²®à³à²®à³à²¯à²¿à²à²Š à²µà³à²à³à²·à²¿à²žà²¿}  
+
+_texttfsiw_ [l=kn] {à²à²à²ªà³à²¯à³à²à²°à³ à²à²²à³à²²à²Ÿ à²à³à²²à²žà²à²³à²šà³à²šà³ à²šà²¿à²°à³à²µà²¹à²¿à²žà³à²µà³à²Šà³ à² à²šà²Ÿà²²à³à²à²šà³ à²¹à²à²€à²Šà²²à³à²²à³. à² "à²šà²¿à²°à³à²®à²Ÿà²£" à²¹à²à²€à²Šà²²à³à²²à²¿,
+à²žà³à²à²¿à²à²³à²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà³à²µà³à²Šà²·à³à²à³ à²
+à²²à³à²²à²Šà³ à²à²Ÿà²°à³à²¯ à²šà²¿à²°à³à²µà²¹à²¿à²žà²²à³ à²¬à³à²à²Ÿà²Š à²à²€à²° à²®à²Ÿà²¹à²¿à²€à²¿à²à²³à²šà³à²šà³ à²à³à²°à²¹à²¿à²žà³à²€à³à²€à²Šà³. 
+à²à²Šà²°à³ à²®à³à²Šà²²à³ à²šà³à²µà³ à²¬à³à²à²Ÿà²Š à²®à²Ÿà²¹à²¿à²€à²¿à²¯à²šà³à²šà³ à²à²Šà²à²¿à²žà²¬à³à²à²Ÿà²à³à²€à³à²€à²Šà³.}  
+
+_textadab_ [l=kn] {à²à³à²³à²à³ à²à²Ÿà²£à³à²µ à² à²°à³à²à²Ÿà²à²¿à²€à³à²°à²µà³ à²šà³à²µà³ à²à²²à³à²²à²¿à²°à³à²µà²¿à²°à³à²à²¬ à²à²Ÿà²¡à³ à²à²à²¡à³ à²¹à²¿à²¡à²¿à²¯à²²à³ à²žà²¹à²Ÿà²¯à²®à²Ÿà²¡à³à²€à³à²€à²Šà³.
+à²
+à²šà³à²à³à²°à²®à²µà²Ÿà²à²¿ à²¹à²žà²¿à²°à³ à²¬à²£à³à²£à²Š à²à³à²à²¡à²¿à²à²³à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿ à²šà³à²µà³ à²®à³à²à²Šà³à²µà²°à²¿à²Šà²Ÿà², à²à³à²à²¡à²¿à²à²³à³ à²¹à²³à²Šà²¿ à²¬à²£à³à²£à²à³à²à³ 
+à²¬à²Šà²²à²Ÿà²à³à²€à³à²€à²µà³. à²¹à²³à²Šà²¿ à²¬à²£à³à²£à²Š à²à³à²à²¡à²¿à²à²³à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà³à²µà³à²Šà²° à²®à³à²²à² à²šà³à²µà³ à²¹à²¿à²à²Šà²¿à²š à²ªà³à²à²à³à²à³ à²µà²Ÿà²ªà²žà³à²žà³à²¬à²°à²¬à²¹à³à²Šà³.}  
+
+_textwyar_ [l=kn] {à²šà³à²µà³ à²€à²¯à²Ÿà²°à²¿à²Šà³à²Šà²°à³, à²¹à²žà²¿à²°à³ à²¬à²£à³à²£à²Š "à²žà²à²à³à²°à²¹ à²®à²Ÿà²¹à²¿à²€à²¿" à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿ 
+à²šà²¿à²®à³à²® à²¹à³à²ž à²¡à²¿à²à²¿à²à²²à³ à²à³à²°à²à²¥à²Ÿà²²à²¯ à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²Ÿà²£à²µà²šà³à²šà³ à²ªà³à²°à²Ÿà²°à²à²­à²¿à²žà²¿. }  
+
+_textcnmbs_ [l=kn] {à²žà²à²à³à²°à²¹à²Š à²¹à³à²žà²°à²šà³à²šà³ à²šà²®à³à²Šà²¿à²žà²²à³ à²¬à³à²à³}  
+_texteambs_ [l=kn] {à²µà²¿à²Šà³à²¯à³à²šà³à²®à²Ÿà²š à²
+à²à²à³à²¯à²šà³à²šà³ à²šà²®à³à²Šà²¿à²žà²¬à³à²à³}  
+_textpsea_ [l=kn] {à²Šà²¯à²µà²¿à²à³à²à³ à²µà²¿à²Šà³à²¯à³à²šà³à²®à²Ÿà²š à²
+à²à²à³à²¯à²šà³à²šà³ username@domain à²°à³à²ªà²Šà²²à³à²²à²¿ à²à²Šà²à²¿à²žà²¿.}  
+_textdocmbs_ [l=kn] {à²žà²à²à³à²°à²¹à²Š à²µà²¿à²µà²°à²à²³à²šà³à²šà³ à²žà³à²à²¿à²žà²²à³à²¬à³à²à³}  
+
+_textwcanc_ [l=kn] {à²à²à²Šà³ à²¹à³à²ž à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà³à²µà²Ÿà², à²Šà²€à³à²€ à²®à³à²²à²à²³ à²¬à²à³à²à³ à²à²°à²à²­ à²®à²Ÿà²¹à²¿à²€à²¿à²¯à²šà³à²šà³ 
+à²šà³à²¡à²¬à³à²à²Ÿà²à³à²€à³à²€à²Šà³. à² à²à³à²²à²ž "à²žà²à²à³à²°à²Ÿà²¹à²à²Š" à²®à³à²²à³à²šà³à²à²Šà²²à³à²²à²¿ à²¹à²²à²µà³ à²µà³à²¬à³ à²ªà³à²à²à²³ à²žà²°à²£à²¿à²¯à²Ÿà²à²¿ 
+à²°à³à²ªà²¿à²žà²²à³à²ªà²à³à²à²¿à²Šà³. à²ªà³à²à²Š à²à³à²³à²­à²Ÿà²à²Šà²²à³à²²à²¿ à²à²Ÿà²£à³à²µ à²ªà²à³à²à²¿ à²ªà³à²°à³à²£à²à³à²³à²¿à²žà²¬à³à²à²Ÿà²à²¿à²°à³à²µ à²µà³à²¬à³â à²ªà³à²à²à²³ 
+à²à³à²°à²®à²µà²šà³à²šà³ à²€à³à²°à²¿à²žà³à²€à³à²€à²Šà³.}  
+
+_texttfc_ [l=kn] {à²žà²à²à³à²°à²¹à²Š à²¶à³à²°à³à²·à²¿à²à³ }  
+
+_texttctiasp_ [l=kn] {à²žà²à²à³à²°à²¹ à²¶à³à²°à³à²·à²¿à²à³ à²à²à²Šà³ à²žà²£à³à²£ à²ªà²Šà²ªà³à²à². à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²à³à²°à³à²€à²¿à²žà²²à³ à² à²ªà²Šà²ªà³à²à²à²µà²šà³à²šà³ à²¬à²³à²žà²²à²Ÿà²à³à²€à³à²€à²Šà³. 
+à². à²Šà²Ÿ.  "Computer Science Technical Reports" à²®à²€à³à²€à³ "Humanity Development Library."}  
+
+_textcea_ [l=kn] {à²žà²à²ªà²°à³à²à²¿à²žà²²à³ à²µà²¿à²Šà³à²¯à³à²šà³à²®à²Ÿà²š à²
+à²à²à³:}  
+
+_textteas_ [l=kn] {à² à²µà²¿à²Šà³à²¯à³à²šà³à²®à²Ÿà²š à²
+à²à²à³ à² à²žà²à²à³à²°à²¹à²à³à²à³ à²®à³à²Šà²² à²žà²à²ªà²°à³à² à²¬à²¿à²à²Šà³. à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²€à²à²€à³à²°à²Ÿà²à²¶ à²¯à²Ÿà²µà³à²Šà²Ÿà²Šà²°à³ à²€à²ªà³à²ªà²šà³à²šà³ 
+à²à³à²°à³à²€à²¿à²žà²¿à²Šà²°à³ à² à²µà²¿à²³à²Ÿà²žà²à³à²à³ à²à²à²Šà³ à²µà²°à²Šà²¿à²¯à²šà³à²šà³ à²à²³à³à²¹à²¿à²žà³à²€à³à²€à²Šà³. à²µà²¿à²Šà³à²¯à³à²šà³à²®à²Ÿà²š à²
+à²à²à³à²¯à²šà³à²šà³ à²ªà³à²°à³à²£à²°à³à²ªà²Šà²²à³à²²à²¿ à²¬à²°à³à²¯à²¿à²°à²¿: 
+<tt>name@domain</tt> .}  
+
+_textatc_ [l=kn] {à² à²žà²à²à³à²°à²¹à²Š à²¬à²à³à²à³}  
+
+_texttiasd_ [l=kn] {à² à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²Ÿà²£à²Šà²²à³à²²à²¿ à²¬à²³à²žà²²à²Ÿà²à²¿à²°à³à²µ à²à²§à²Ÿà²° à²€à²€à³à²µà²à²³à²šà³à²šà³ à² à²¹à³à²³à²¿à²à³à²¯à²²à³à²²à²¿ à²µà²¿à²µà²°à²¿à²žà²²à²Ÿà²à²¿à²Šà³. 
+à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²€à³à²à³à²Šà²Ÿà² à²®à³à²Šà²² à²ªà³à²à²Šà²²à³à²²à²¿ à² à²¹à³à²³à²¿à²à³ à²à²Ÿà²£à²¬à²°à³à²€à³à²€à²Šà³.}  
+
+_textypits_ [l=kn] {à²žà²°à²£à²¿à²¯à²²à³à²²à²¿ à²šà²¿à²®à³à²® à²žà³à²¥à²³ à²à²à²Šà³ à²¬à²Ÿà²£à²Šà²¿à²à²Š à²à³à²°à³à²€à²¿à²žà²²à³à²ªà²à³à²à²¿à²Šà³--à²à²²à³à²²à²¿"à²žà²à²à³à²°à²¹ à²®à²Ÿà²¹à²¿à²€à²¿" à²à²à³à². 
+à²®à³à²à²Šà³à²µà²°à³à²¯à²²à³ à²¹à²žà²¿à²°à³ à²¬à²£à³à²£à²Š "à²®à³à²² à²Šà²€à³à²€" à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à²€à³à²€à²¿.}
+
+_srcebadsources_ [l=kn] {<p>à²šà³à²µà³ à²žà³à²à²¿à²žà²¿à²Š à²à²à²Šà³ à²
+à²¥à²µà²Ÿ à²¹à³à²à³à²à³ à²à²³à²¬à²°à²¬à³à²à²Ÿà²Š à²®à³à²²à²à²³à³ à²²à²­à³à²¯à²µà²¿à²²à³à²².  (_iconcross_  à²à³à²³à²à³ à²à³à²°à³à²€à²¿à²žà²²à²Ÿà²à²¿à²Šà³).
+ <p>à²à²à³à²à²Šà²°à³ à²ªà³à²°à²Ÿà²¯à²¶à²
+ <ul>
+ <li>à²šà²®à³à²Šà²¿à²žà²¿à²Š à²à²¡à²€, à²à²«à³ à²à²¿ à²ªà²¿ à²
+à²¥à²µà²Ÿ à²¯à³ à²à²°à³ à²à²²à³ à²à²²à³à²²à²Šà²¿à²°à²¬à²¹à³à²Šà³
+<li>à²®à³à²Šà²²à³ à²šà³à²µà³ à²à²à²žà³âà²ªà²¿à²¯à²šà³à²šà³ à²¡à²¯à²²à³ à²®à²Ÿà²¡à²¬à³à²à³ 
+<li>à²šà³à²µà³ à²¯à³ à²à²°à³âà²à²²à³âà²šà³à²šà³ à²à²à²Šà³ à²«à³à²°à³âà²µà²Ÿà²²à³â à²žà³à²°à²à³à²·à²¿à²€ à²žà³à²¥à²³à²Šà²¿à²à²Š à²žà²à²ªà²°à³à²à²¿à²žà²²à³ à²ªà³à²°à²¯à²€à³à²šà²¿à²žà³à²€à³à²€à²¿à²Šà³à²Šà³à²°à²¿ (à²šà³à²µà³ à²
+à²à²€à²°à³à²à²Ÿà²² à²žà²à²ªà²°à³à²à²¿à²žà²²à³ à²¬à²³à²à³à²Šà²Ÿà²°à²° à²¹à³à²žà²°à³ à²®à²€à³à²€à³ à²žà²à²à³à²€à²ªà²Š à²à²Šà²à²¿à²žà²¬à³à²à²Ÿà²à²¿à²Šà³à²Šà²°à³, à²¹à³à²à²¿à²°à³à²µà³à²Šà³ à²žà²¹à²).</ul>
+<p>à² à²¯à³ à²à²°à³ à²à²²à³ à²šà²¿à²®à³à²® à²¬à³à²°à³à²žà²°à³âà²šà²²à³à²²à²¿ à²šà³à²¡à²¬à²¹à³à²Šà²Ÿà²à²¿à²Šà³à²Šà²°à³ à²
+à²Šà³ à²žà³à²¥à²³à³à²¯ à²à³à²¯à²Ÿà²¶à³ à²ªà³à²°à²€à²¿à²¯à²¿à²°à²¬à²¹à³à²Šà³; à² à²ªà³à²°à²€à²¿à²à²³à³ à²šà²®à³à²® à²à²Ÿà²°à³à²¯à²Ÿà²à²°à²£à³à²¯à²²à³à²²à²¿ à²à³à²à²°à²µà²Ÿà²à³à²µà³à²Šà²¿à²²à³à²². à²®à³à²Šà²²à³ à²šà²¿à²®à³à²® à²¬à³à²°à³à²žà²°à³ à²à²ªà²¯à³à²à²¿à²žà²¿ à²¬à³à²à²Ÿà²Š à²ªà³à²à²à²³à²šà³à²šà³  à²à³à²³à²à²¿à²³à²¿à²žà²¿à²à³à²³à³à²³à²¿.}  
+
+_textymbyco_ [l=kn] {à²šà²¿à²®à³à²® à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à² à²à³à²³à²à²à²¡à²µà³à²à²³ à²®à³à²²à³  à²à²§à²Ÿà²°à²¿à²žà²¬à²¹à³à²Šà³.
+<ul>
+<li>à²ªà³à²°à³à²µà²šà²¿à²¯à³à²à²¿à²€ à²µà³à²¯à²µà²žà³à²¥à³
+<dl><dd>à²¹à³à²ž à²žà²à²à³à²°à²¹à²µà³ à² à²à³à²³à²à²à²¡ à²žà²à²µà²¿à²­à²Ÿà²à²à²³à²²à³à²²à²¿ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²¹à³à²à²Šà²¿à²°à²¬à²¹à³à²Šà³:
+à²¹à³à²à³âà²à²¿à²à²à²à²²à³â, à²žà²Ÿà²§à²Ÿà²°à²£ à²ªà² à³à²¯, "m-box" à²-à²®à³à²²à³â, à²ªà²¿à²¡à²¿à²à²«à³â, à²à²°à³âà²à²¿à²à²ªà³â, à²à²à²à²žà³â à²µà²°à³à²¡à³â, 
+à²ªà³à²žà³à²à³âà²žà³à²à³à²°à²¿à²ªà³à²à³â, à²ªà²µà²°à³âà²ªà²Ÿà²¯à²¿à²à²à³â, à²à²à³à²žà³âà²à²²à³â, à²à²®à³à²à²žà³â, à²žà²¿à²¡à²¿à²à²žà³â/à²à²à²žà³âà²à²à²žà³â. </dd></dl>
+<li>à²à²à²Ÿà²à²²à³ à²à²°à³à²µ à²à²à²Šà³ à²žà²à²à³à²°à²¹ 
+<dl><dd>à²¹à³à²ž à²žà²à²à³à²°à²¹à²Š à²à²¡à²€à²à²³à³ à²à²à²Ÿà²à²²à³ à²à²°à³à²µ à²žà²à²à³à²°à²¹à²Šà²²à³à²²à²¿à²°à³à²µ à²à²¡à²€à²à²³ 
+à²¬à²à³à²à²³à²¿à²à³ à²žà³à²°à²¿à²Šà²à²€à²¹ à²à²¡à²€à²à²³à²Ÿà²à²¿à²°à²¬à³à²à³.</dd></dl>
+</ul>}  
+
+_textbtco_ [l=kn] {à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²à²Šà²° à²®à³à²²à³ à²à²§à²Ÿà²°à²¿à²žà²¿}  
+_textand_ [l=kn] {à²¹à³à²ž à²Šà²€à³à²€à²Ÿà²à²¶ à²ªà³à²°à³à²žà²¿ }  
+_textad_ [l=kn] {à²Šà²€à³à²€à²Ÿà²à²¶à²µà²šà³à²šà³ à²žà³à²°à²¿à²žà³à²€à³à²€à²¿à²Šà³:}  
+
+_texttftysb_ [l=kn] {à² à²à³à²³à²à³ à²šà³à²µà³ à²šà²®à³à²Šà²¿à²žà³à²µ à²à²²à³à²² à²à²¡à²€à²à²³à³ à²žà²à²à³à²°à²¹à²à³à²à³ à²žà³à²°à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à²µà³. à²žà²à²à³à²°à²¹à²Šà²²à³à²²à²¿ à²à²à²Ÿà²à²²à³ à²
+à²°à³à²µ à²¯à²Ÿà²µà³à²Šà³ à²à²¡à²€à²à²³à³ à²®à²€à³à²€à³ à²šà²®à³à²Šà²¿à²žà²²à³à²ªà²à³à²à²¿à²²à³à²²à²µà³à²à²Šà³ à²à²à²¿à²€ à²ªà²¡à²¿à²žà²¿à²à³à²³à³à²³à²¿. à²à²à²Šà³ à²µà³à²³à³ à²¹à²Ÿà²à²Ÿà²Šà²²à³à²²à²¿
+à² à²à²¡à²€à²à²³ à²à²°à²¡à³ à²ªà³à²°à²€à²¿à²à²³à³ à²žà²à²à³à²°à²¹à²Šà²²à³à²²à²¿ à²žà³à²°à³à²€à³à²€à²µà³. à²à²¡à²€à²à²³à²šà³à²šà³ à²
+à²µà³à²à²³ à²ªà³à²°à³à²£ à²ªà²¥ à²®à²€à³à²€à³ à²µà³à²¬à³ à²ªà³à²à²à²³à²šà³à²šà³ 
+à²
+à²µà³à²à²³ à²žà²à²ªà³à²°à³à²£ à²µà³à²¬à³ à²µà²¿à²³à²Ÿà²žà²µà²šà³à²šà³ à²¬à²³à²žà²¿ à²šà²®à³à²Šà²¿à²žà²¬à³à²à³.}  
+
+_textis_ [l=kn] {à²Šà²žà³à²€à²Ÿà²µà³à²à³ à²à²³à²¬à²°à³à²µ à²®à³à²²à²à²³à³}  
+
+_textddd1_ [l=kn] {<p>à²šà³à²µà³ file:// à²
+à²¥à²µà²Ÿ ftp:// à²¬à²³à²žà²¿ à²à²à²Šà³ à²à²¡à²€à²µà²šà³à²šà³ à²šà²®à³à²Šà²¿à²žà²¿à²Šà²°à³, à² à²à²¡à²€ à²à³à²³à²à²¿à²³à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à²Šà³.
+<p>à²šà³à²µà³ http:// à²¬à²³à²žà²¿à²Šà²°à³ à²
+à²Šà³ à²à²à²Šà³ à²µà³à²¬à³ à²ªà³à²à²µà²šà³à²šà³ à²šà²®à³à²Šà²¿à²žà³à²€à³à²€à²Šà³à²¯à³ à²
+à²¥à²µà²Ÿ à²¹à²²à²µà³ à²à²¡à²€à²à²³ à²ªà²à³à²à²¿à²¯à²šà³à²šà³ à²à²šà³à²šà³à²µà³à²Šà³ à²®à³à²à³à²¯à²µà²Ÿà²à³à²€à³à²€à²Šà³. à²
+à²Šà³ à²à²à²Šà³ à²µà³à²¬à³ à²ªà³à²à²µà²Ÿà²à²¿à²Šà³à²Šà²°à³ à² à²ªà³à² à²¹à²Ÿà²à³ à²
+à²Šà³ à²¯à³ à²à²°à³ à²à²²à³ à²à²³à²à³ à²¬à²°à³à²µ à² à²ªà³à²à²Šà²¿à²à²Š à²à³à²à²¡à²¿ à²à²°à³à²µ à²à²²à³à²²à²Ÿ à²ªà³à²à²à²³à³ à²à³à²³à²à²¿à²³à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à²µà³.
+<p>à²šà³à²µà³ file:// à²
+à²¥à²µà²Ÿ ftp:// à²¬à²³à²žà²¿ à²à²à²Šà³ à²à²¡à²€ à²à²à³à²à²šà³à²šà³ à²šà²®à³à²Šà²¿à²žà²¿à²Šà²°à³ à²
+à²¥à²µà²Ÿ http:// à²¬à²³à²žà²¿ à²à²à²Šà³ à²¯à³ à²à²°à³ à²à²²à³ à²šà³à²šà³ à²šà²®à³à²Šà²¿à²žà²¿à²Šà²°à³ à² à²à²à³à²à³ à²®à²€à³à²€à³ à²
+à²Šà²° à²à²ª à²à²à³à²à³à²à²³à²²à³à²²à²¿à²°à³à²µ à²à²²à³à²²à²Ÿ à²Šà²žà³à²€à²Ÿà²µà³à²à³/ à²à²¡à²€à²à²³à³ à²šà²¿à²®à³à²® à²žà²à²à³à²°à²¹à²à³à²à³ à²¬à²°à³à²€à³à²€à²µà³.
+<p> "à²à²šà³à²šà³ à²¹à³à²à³à²à³ à²®à³à²²à²à²³à³" à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿ à²à²šà³à²šà³ à²¹à²²à²µà³ à²Šà²€à³à²€ à²®à²Ÿà²¹à²¿à²€à²¿ à²ªà³à²à³à²à²¿à²à³à²à²³à²šà³à²šà³ à²ªà²¡à³à²Šà³à²à³à²³à³à²³à²¿.}  
+
+_textddd2_ [l=kn] {<p>à²à²à²Šà³ à²¹à²žà²¿à²°à³ à²¬à²£à³à²£à²Š à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿. à²šà³à²µà³ à²€à²à³à² à²¬à²³à²à³à²Šà²Ÿà²°à²°à²Ÿà²à²¿à²Šà³à²Šà²°à³ à²žà²à²à³à²°à²¹à²Š à²žà²®à²à³à²°à²Ÿà²à³à²€à²¿à²¯à²šà³à²šà³ à²žà²°à²¿à²ªà²¡à²¿à²žà²¬à²¹à³à²Šà³. à²
+à²¥à²µ à²šà³à²°à²µà²Ÿà²à²¿ à²šà²¿à²°à³à²®à²Ÿà²£ à²à²à³à²à²à³à²à³ à²¹à³à²à²¿.  à²šà³à²µà³ à²¯à²Ÿà²µà²Ÿà² à²¬à³à²à²Ÿà²Šà²°à³ à²¹à²³à²Šà²¿ à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿ à²¹à²¿à²à²Šà²¿à²š à²à²à³à²à²à³à²à³ à²¹à²¿à²à²€à²¿à²°à³à²à²¬à²¹à³à²Šà³.}
+
+
+
+_textreset_ [l=kn] {à²ªà³à²šà² à²à³à²¡à²¿à²žà²¿}  
+
+
+_texttryagain_ [l=kn] {à²Šà²¯à²µà²¿à²à³à²à³<a href="_httppagecollector_" target=_top>restart the collector</a>
+à²®à²€à³à²€à³ à²ªà³à²šà² à²ªà³à²°à²¯à²€à³à²šà²¿à²žà²¿.}
+
+
+_textretcoll_ [l=kn] {"à²žà²à²à³à²°à²Ÿà²¹à²" à²à³à²à³ à²¹à²¿à²à²€à²¿à²°à³à²à²¿}  
+
+_textdelperm_ [l=kn] {_cgiargbc1dirname_ à²š à²¹à²²à²µà³ à²
+à²¥à²µà²Ÿ à²à²²à³à²²à²Ÿ à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ à²€à³à²à³à²¯à²²à²Ÿà²à²²à²¿à²²à³à²². à²à²Šà²à³à²à³ à²à²Ÿà²°à²£à²à²³à³ à²¹à³à²à²¿à²°à²¬à²¹à³à²Šà³:
+<ul> 
+<li> à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²à³  _gsdlhome_/collect/_cgiargbc1dirname_  à²¡à³à²°à²à³à²à²°à²¿à²¯à²šà³à²šà³ à²€à³à²à³à²¯à²²à³ à²
+à²šà³à²®à²€à²¿à²¯à²¿à²²à³à²²<br>
+à²šà³à²µà³ à²šà³à²°à²µà²Ÿà²à²¿ à² à²¡à³à²°à²à³à²à²°à²¿à²¯à²šà³à²šà³ à²€à³à²à³à²Šà³,  _cgiargbc1dirname_ à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²€à³à²à³à²¯à³à²µà²à²Ÿà²°à³à²¯à²µà²šà³à²šà³ à²ªà³à²°à³à²£à²à³à²³à²¿à²žà²¿. </li>
+<li>à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²à³ _gsdlhome_/bin/script/delcol à²ªà³à²°à³à²à³à²°à²Ÿà²à²šà³à²šà³ à²à²Ÿà²°à³à²¯à²à²€à²à³à²³à²¿à²žà²²à³ à²žà²Ÿà²§à³à²¯à²µà²¿à²²à³à²². à²à²Šà³ à²à²Šà²¬à²¹à³à²Šà²Ÿà²Š à²®à²€à³à²€à³ à²à²Ÿà²°à³à²¯à²Ÿà²à²°à²£à³à²¯à²Ÿà²à²¬à²²à³à²² à²ªà³à²°à³à²à³à²°à²Ÿà² à²à²à²Šà³ à²à²à²¿à²€ à²ªà²¡à²¿à²žà²¿à²à³à²³à³à²³à²¿</li>
+</ul>}  
+
+_textdelinv_ [l=kn] {_cgiargbc1dirname_ à²žà²à²à³à²°à²¹ à²°à²à³à²·à²¿à²žà²²à³à²ªà²à³à²à²¿à²Šà³ à²
+à²¥à²µà²Ÿ à²
+à²Šà³ à²žà²°à²¿à²¯à²¿à²²à³à²².  à²¹à³à²à²Ÿà²à²¿ à²žà²à²à³à²°à²¹ à²€à³à²à³à²¯à³à²µ à²à²Ÿà²°à³à²¯ à²°à²Šà³à²Šà²Ÿà²à²¿à²Šà³.}  
+
+_textdelsuc_ [l=kn] {_cgiargbc1dirname_ à²žà²à²à³à²°à²¹à²µà³ à²žà²«à²²à²µà²Ÿà²à²¿ à²€à³à²à³à²¯à²²à³à²ªà²à³à²à²¿à²€à³}  
+
+_textclonefail_ [l=kn] {à² à²ªà³à² à²ªà³à²°à²µà³à²¶à²¿à²žà²²à³ à²¡à²¯à²²à³
+_cgiargclonecol_ à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²à³à²²à³à²šà³ à²®à²Ÿà²¡à²²à²Ÿà²à²²à²¿à²²à³à²². à² à²à³à²³à²à²à²¡ à²à²Ÿà²°à²£à²à²³à²¿à²°à²¬à²¹à³à²Šà³:
+<ul>
+<li>  _cgiargclonecol_ à²žà²à²à³à²°à²¹ à²
+à²žà³à²€à²¿à²€à³à²µà²Šà²²à³à²²à²¿à²²à³à²² 
+<li> _cgiargclonecol_ à²žà²à²à³à²°à²¹à²à³à²à³ à²¬à³à²à²Ÿà²Š collect.cfg à²žà²®à²à³à²°à²Ÿà²à³à²€à²¿ à²à²¡à²€à²µà²¿à²²à³à²²
+<li> à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²à³ collect.cfg à²žà²®à²à³à²°à²Ÿà²à³à²€à²¿ à²à²¡à²€à²µà²šà³à²šà³ à²à²Šà²²à³ à²
+à²šà³à²®à²€à²¿à²¯à²¿à²²à³à²² 
+</ul>}  
+
+_textcolerr_ [l=kn] {à²žà²à²à³à²°à²Ÿà²¹à² à²šà³à²¯à³à²šà²€à³.}  
+
+_texttmpfail_ [l=kn] {à²à²à²Šà³ à²€à²Ÿà²€à³à²à²Ÿà²²à²¿à² à²à²¡à²€à²à³à²à³ à²¬à²°à³à²¯à²²à³ / à²¡à³à²°à²à³à²à²°à²¿à²¯à²šà³à²šà³ à²à²Šà²²à³ "à²žà²à²à³à²°à²Ÿà²¹à²" à²µà²¿à²«à²²à²µà²Ÿà²¯à²¿à²€à³. à²à²Šà²à³à²à³ à²à²Ÿà²°à²£:
+<ul>
+<li> à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²à³ _gsdlhome_/tmp à²¡à³à²°à²à³à²à²°à²¿à²à³ à²¬à²°à³à²¯à²²à³ à²
+à²¥à²µà²Ÿ à²
+à²Šà²šà³à²šà³ à²à²Šà²²à³ à²
+à²šà³à²®à²€à²¿à²¯à²¿à²²à³à²².
+</ul>}  
+
+_textmkcolfail_ [l=kn] {à²¹à³à²ž à²žà²à²à³à²°à²¹à²à³à²à³ à²¬à³à²à²Ÿà²Š à²¡à³à²°à²à³à²à²°à²¿à²¯à²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà³à²µà²²à³à²²à²¿ "à²žà²à²à³à²°à²Ÿà²¹à²" à²µà²¿à²«à²²à²µà²Ÿà²¯à²¿à²€à³ (mkcol.pl à²µà²¿à²«à²²). à²à²Šà²à³à²à³ à²à²Ÿà²°à²£:
+<ul> 
+<li> à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²à³  _gsdlhome_/tmp à²¡à³à²°à²à³à²à²°à²¿à²à³ à²¬à²°à³à²¯à²²à³ à²
+à²šà³à²®à²€à²¿ à²à²²à³à²².
+<li> mkcol.pl à²šà²²à³à²²à²¿ à²à²°à²¬à²¹à³à²Šà²Ÿà²Š à²ªà²°à³à²²à³ à²žà³à²à³à²°à²¿à²ªà³à²à³â à²šà³à²¯à³à²šà²€à³à²à²³à³ 
+</ul>}  
+
+_textnocontent_ [l=kn] {à²žà²à²à³à²°à²Ÿà²¹à² à²šà³à²¯à³à²šà²€à³. à²¹à³à²ž à²žà²à²à³à²°à²¹à²à³à²à³ à²¯à²Ÿà²µà³à²Šà³ à²¹à³à²žà²°à³ à²šà²®à³à²Šà²¿à²žà²¿à²²à³à²². "à²žà²à²à³à²°à²Ÿà²¹à²" à²µà²šà³à²šà³ à²®à³à²Šà²²à²¿à²à²Š à²ªà³à²°à²Ÿà²°à²à²­à²¿à²žà²¿ à²®à²€à³à²€à³ à²ªà³à²°à²¯à²€à³à²šà²¿à²žà²¿.}  
+
+_textrestart_ [l=kn] {à²žà²à²à³à²°à²Ÿà²¹à²à²µà²šà³à²šà³ à²®à²€à³à²€à³  à²ªà³à²°à²Ÿà²°à²à²­à²¿à²žà²¿. }  
+
+_textreloaderror_ [l=kn] {à²¹à³à²ž à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²Ÿà²£à²Šà²²à³à²²à²¿ à²à²à²Šà³ à²€à²ªà³à²ªà²Ÿà²¯à²¿à²€à³. à²šà²¿à²®à³à²® à²¬à³à²°à³à²žà²°à³âà²š "reload" à²
+à²¥à²µà²Ÿ "back" à²à³à²à²¡à²¿à²à²³ à²à²ªà²¯à³à²à²Šà²¿à²à²Š 
+à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²à³ à²à³à²à²Šà²² à²à²à²à²Ÿà²à²¿à²°à²¬à²¹à³à²Šà³. (à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²Ÿà²£ à²šà³à²¡à³à²¯à³à²€à³à²€à²¿à²°à³à²µà²Ÿà² à² à²à³à²à²¡à²¿à²à²³à²šà³à²šà³ à²¬à²³à²žà²¬à³à²¡à²¿).  
+"à²žà²à²à³à²°à²Ÿà²¹à²" à²µà²šà³à²šà³ à²®à²€à³à²€à³ à²®à³à²Šà²²à²¿à²à²Š à²ªà³à²°à²Ÿà²°à²à²­à²¿à²žà²¿.}  
+
+_textexptsuc_ [l=kn] {_cgiargbc1dirname_ à²žà²à²à³à²°à²¹à²µà³ à²žà²«à²²à²µà²Ÿà²à²¿  _gsdlhome_/tmp/exported\__cgiargbc1dirname_ à²¡à³à²°à²à³à²à²°à²¿à²à³ à²°à²«à³à²€à²Ÿà²¯à²¿à²€à³}
+
+_textexptfail_ [l=kn] {<p>_cgiargbc1dirname_ à²žà²à²à³à²°à²¹à²Š à²°à²«à³à²€à³ à²à²Ÿà²°à³à²¯ à²µà²¿à²«à²²à²µà²Ÿà²¯à²¿à²€à³.
+
+<p> à²ªà³à²°à²Ÿà²¯à²·à² à²°à²«à³à²€à³à²®à²Ÿà²¡à²²à³ à²
+à²µà²¶à³à²¯à²µà²Ÿà²Š à²à²²à³à²² à²à²ªà²à²°à²£à²à²³à³ à²à²²à³à²²à²Šà³à²¯à³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà³à²¥à²Ÿà²ªà²¿à²€à²µà²Ÿà²à²¿à²Šà³.<ul>
+ <ul>
+<li> à²šà³à²µà³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²š 2.70w à²à²¿à²à²€ à²¹à²³à³à²¯ à²µà²°à³à²·à²šà³âà²šà²šà³à²šà³ à²žà²¿à²¡à²¿à²°à³à²®à³âà²šà²¿à²à²Š à²žà³à²¥à²Ÿà²ªà²¿à²žà²¿à²Šà³à²Šà²°à³, à²šà³à²µà²Ÿà²à²¿à²¯à³ 
+à²¬à³à²à²Ÿà²Š à²à²²à³à²²à²µà²šà³à²šà³ à²à²¯à³à²à³ à²®à²Ÿà²¡à²Šà²¿à²Šà³à²Šà²²à³à²²à²¿ à² à²à²ªà²à²°à²£à²à²³à³ à²žà³à²¥à²Ÿà²ªà²¿à²€à²µà²Ÿà²à²¿à²°à³à²µà³à²Šà²¿à²²à³à²². à²šà³à²µà³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²šà²šà³à²šà³ 
+à²®à²€à³à²€à³ à²žà³à²¥à²Ÿà²ªà²¿à²žà²¿ à² à²à²²à³à²² à²žà³à²²à²­à³à²¯ à²à²³à²šà³à²šà³ à²žà³à²¥à²Ÿà²ªà²¿à²žà²¬à²¹à³à²Šà³.
+
+<li>à²šà³à²µà³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²šà²šà³à²šà³ à²µà³à²¬à³ à²šà²¿à²à²Š à²žà³à²¥à²Ÿà²ªà²¿à²žà²¿à²Šà³à²Šà²°à³, à²à²šà³à²šà³ à²à²à²Šà³ à²ªà³à²°à³à²à³à²°à²Ÿà² à²
+à²šà³à²šà³ à²žà³à²¥à²Ÿà²ªà²¿à²žà²¿ à² à²à²²à³à²² 
+à²žà³à²²à²­à³à²¯à²à²³à²šà³à²šà³ à²žà³à²¥à²Ÿà²ªà²¿à²žà²¬à²¹à³à²Šà³. à²Šà²¯à²µà²¿à²à³à²à³ <a href="http://www.greenstone.org">http://www.greenstone.org</a> 
+à²
+à²¥à²µà²Ÿ <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">the mailing list</a> 
+à²¯à²šà³à²šà³ à²žà²à²Šà²°à³à²¶à²¿à²žà²¿ à² à²¬à²à³à²à³ à²ªà³à²°à³à²£ à²®à²Ÿà²¹à²¿à²€à²¿ à²ªà²¡à³à²¯à²¿à²°à²¿.
+</ul>}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=kn] {<p>à² à²à³à²³à²à³ à²¹à³à²³à²¿à²Š à²®à²Ÿà²¹à²¿à²€à²¿à²à²³à²šà³à²šà³ à²šà²®à³à²Šà²¿à²žà²¿ à²à³à²³à²à²¿à²°à³à²µ _textintro_  à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿. </p>}  
+
+_textcaec_ [l=kn] {à²à²à²Ÿà²à²²à³ à²à²°à³à²µ à²žà²à²à³à²°à²¹à²à³à²à³ à²žà³à²°à³à²ªà²¡à³}  
+_textbild_ [l=kn] {à² à³à²µà²£à²¿ à²µà²žà³à²€à³}  
+_textintro_ [l=kn] {à²à²¡à²€à²µà²šà³à²šà³ à²à²¯à³à²Šà³à²à³à²³à³à²³à²¿}  
+_textconfirm_ [l=kn] {à²žà²®à²°à³à²¥à²šà³}  
+_textselect_ [l=kn] {à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²à²¯à³à²Šà³à²à³à²³à³à²³à²¿}  
+_textmeta_ [l=kn] {à²®à³à²à²¡à³à²à²Ÿ à²šà²®à³à²Šà²¿à²žà²¿}  
+_textselectoption_ [l=kn] {à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²à²¯à³à²Šà³à²à³à²³à³à²³à²¿ âŠ}  
+
+_texttryagain_ [l=kn] {à²Šà²¯à²µà²¿à²à³à²à³<a href="_httppagedepositor_" target=_top>restart the depositor</a>à²®à²€à³à²€à³ à²ªà³à²šà² à²ªà³à²°à²¯à²€à³à²šà²¿à²žà²¿}
+
+_textselectcol_ [l=kn] {à²šà³à²µà³ à²¯à²Ÿà²µ à²žà²à²à³à²°à²¹à²à³à²à³ à²Šà²žà³à²€à²Ÿà²µà³à²à²šà³à²šà³ à²žà³à²°à²¿à²žà²¬à³à²à³ à² à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²à²¯à³à²Šà³à²à³à²³à³à²³à²¿.}  
+_textfilename_ [l=kn] {à²à²¡à²€à²Š à²¹à³à²žà²°à³ }  
+_textfilesize_ [l=kn] {à²à²¡à²€à²Š à²à²Ÿà²€à³à²°}  
+
+_textretcoll_ [l=kn] {"à²¡à²¿à²ªà²Ÿà²žà²¿à²à²°à³"à²à³ à²¹à²¿à²à²Šà²¿à²°à³à²à²¿}  
+
+
+_texttmpfail_ [l=kn] {à²à²à²Šà³ à²€à²Ÿà²€à³à²à²Ÿà²²à²¿à² à²à²¡à²€à²µà²šà³à²šà³ à²à²Šà²²à³ à²
+à²¥à²µà²Ÿ à²
+à²Šà²à³à²à³ à²¬à²°à³à²¯à²²à³ "à²¡à²¿à²ªà²Ÿà²žà²¿à²à²°à³" à²
+à²žà²®à²°à³à²¥à²µà²Ÿà²¯à²¿à²€à³. 
+à²à²Šà²à³à²à³ à² à²à²Ÿà²°à²£à²à²³à²¿à²°à²¬à²¹à³à²Šà³: 
+<ul>
+<li> à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²à³  _gsdlhome_/tmp à²¡à³à²°à²à³à²à²°à²¿à²¯à²šà³à²šà³ à²à²Šà³à²²à³ / à²
+à²Šà²à³à²à³ à²¬à²°à³à²¯à³à²²à³ à²ªà³à²°à²µà³à²¶à²Ÿà²§à²¿à²à²Ÿà²°à²µà²¿à²²à³à²².
+</ul>}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²¡à²¿à²à²¿à²à²²à³ à²à³à²°à²à²¥à²Ÿà²²à²¯à²à²³à²šà³à²šà³ à²à²Šà²à²¿à²žà³à²µ à²¹à²Ÿà²à³ à²¹à³à²ž à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ 
+à²šà²¿à²°à³à²®à²¿à²žà²²à³ à²à²ªà²¯à³à²à²à²°à²µà²Ÿà²Š à²€à²à²€à³à²°à²Ÿà²à²¶à²à²³ à²à²à²Šà³ à²žà²à²à³à²°à³à²£. à²
+à²Šà³ à²®à²Ÿà²¹à²¿à²€à²¿à²¯à²šà³à²šà³ 
+à²à²à²Šà³ à²šà²µà³à²š à²®à²Ÿà²Šà²°à²¿à²¯à²²à³à²²à²¿ à²žà²à²à²à²¿à²žà²¿ à²
+à²à²€à²°à³à²à²Ÿà²²à²Šà²²à³à²²à³ à²
+à²¥à²µà²Ÿ à²žà²¿ à²¡à²¿ à²°à³à²®à³âà²šà²²à³à²²à³ 
+à²ªà³à²°à²à²à²¿à²žà³à²µ à²¹à³à²ž à²µà²¿à²§à²Ÿà²š. à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²€à²à²€à³à²°à²Ÿà²à²¶ à²šà²¿à²°à³à²®à²¿à²žà²¿à²Šà²µà²°à³ à²šà³à²¯à³à²à²¿à²²à³à²à²¡à³âà²š à²µà³à²à²Ÿà²à³ 
+à²µà²¿à²¶à³à²µà²µà²¿à²Šà³à²¯à²Ÿà²šà²¿à²²à²¯à²Š à²šà³à²¯à³à²à²¿à²²à³à²à²¡à³â à²¡à²¿à²à²¿à²à²²à³ à²à³à²°à²à²¥à²Ÿà²²à²¯ à²ªà³à²°à²Ÿà²¯à³à²à²šà³. à² à²€à²à²€à³à²°à²Ÿà²à²¶ à²¯à³à²šà³à²žà³à²à³ 
+à²®à²€à³à²€à³ à²¹à³à²¯à³à²®à²šà³ à²à²šà³à²«à³ à²à²šà³ à²à²¿ à² à²
+à²µà²°à³à²à²³ à²žà²¹à²à²Ÿà²°à²Šà³à²à²Šà²¿à²à³ à²µà²¿à²€à²°à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à³à²€à²¿à²Šà³. à²à²Šà³ 
+à²à²¿ à²à²šà³ à²¯à³ à²žà²Ÿà²®à²Ÿà²šà³à²¯ à²žà²Ÿà²°à³à²µà²à²šà²¿à² à²²à³à²žà³à²šà³à²žà³ à²
+à²¡à²¿à²¯à²²à³à²²à²¿ <i>http://greenstone.org</i> à²¯à²²à³à²²à²¿ 
+à²Šà³à²°à²à³à²µ à²à²à²Šà³ à²®à³à²à³à²€ à²€à²à²€à³à²°à²Ÿà²à²¶. }  
+
+_textgreenstone2_ [l=kn] {à² à²€à²à²€à³à²°à²Ÿà²à²¶ à²à²ªà²¯à³à²à²¿à²žà²¿ à²šà²¿à²°à³à²®à²¿à²žà²¿à²Š à²
+à²šà³à² à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ à²šà³à²µà³ à²šà³à²¯à³à²à²¿à²²à³à²à²¡à³â à²¡à²¿à²à²¿à²à²²à³ à²à³à²°à²à²¥à²Ÿà²²à²¯à²Š à²µà³à²¬à³ à²žà³à²à³ 
+(<a href="http://nzdl.org">http://nzdl.org</a>)  à²šà²²à³à²²à²¿ à²ªà²°à²¿à²¶à³à²²à²¿à²žà²¬à²¹à³à²Šà³. 
+à²
+à²°à²Ÿà²¬à²¿à²à³, à²«à³à²°à³à²à²à³, à²žà³à²ªà³à²¯à²Ÿà²šà²¿à²¶à³, à²à²à²à³à²²à²¿à²·à³ à²®à³à²à²€à²Ÿà²Š à²µà²¿à²µà²¿à²§ à²­à²Ÿà²·à²Ÿ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²à²³à²à³à²à²¡ 
+à² à²žà²à²à³à²°à²¹à²à²³à³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²€à²à²€à³à²°à²Ÿà²à²¶à²Š à²µà²¿à²µà²¿à²§ à²¶à³à²§à²šà²Ÿ à²¹à²Ÿà²à³ à²à²€à²° à²žà³à²²à²­à³à²¯à²à²³à²šà³à²šà³ à²šà²¿à²Šà²°à³à²¶à²¿à²žà³à²€à³à²€à²µà³. à²à²µà³ à²
+à²²à³à²²à²Šà³ à²žà²à²à³à²€à²à³à²à³ à²žà²à²¬à²à²§à²¿à²žà²¿à²Š 
+à²à³à²²à²µà³ à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ à²à²²à³à²²à²¿ à²à²Ÿà²£à²¬à²¹à³à²Šà³.}  
+
+_textplatformtitle_ [l=kn] {à²µà³à²Šà²¿à²à³}  
+_textgreenstone3_ [l=kn] {à²µà²¿à²à²¡à³à²žà³, à²¯à³à²šà²¿à²à³à²žà³ à²¹à²Ÿà²à³ à²®à³à²¯à²Ÿà²à³ à² à²à²žà³  à²µà³à²Šà²¿à²à³à²à²³à²²à³à²²à²¿ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²
+à²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¬à²¹à³à²Šà³. à² à²µà²¿à²€à²°à²£à²¿à²à³à²¯à²²à³à²²à²¿ 
+à² à²à²²à³à²² à²µà³à²Šà²¿à²à³à²à²³à²¿à²à³ à²¬à³à²à²Ÿà²Š à²®à²€à³à²€à³ à²à²ªà²¯à³à²à²¿à²žà²²à³ à²€à²¯à²Ÿà²°à²Ÿà²Š à²žà³à²¥à²¿à²€à²¿à²¯ à²¬à³à²šà²°à²¿à²à²³à³ à²žà³à²°à²¿à²žà²²à³à²ªà²à³à²à²¿à²µà³. à² à²µà²¿à²€à²°à²£à²¿à²à³ 
+à²®à³à²à³à²°à³à²žà²Ÿà²«à³à²à³  C++ à²
+à²¥à²µà²Ÿ gcc à²à²ªà²¯à³à²à²¿à²žà²¿ à²žà²à²à²²à²¿à²žà²¬à²²à³à²² à²žà²à²ªà³à²°à³à²£ à²à²à²° à²žà²à²à³à²€à²µà²šà³à²šà³ à²à²³à²à³à²à²¡à²¿à²Šà³.  à²à²à²¿à²€
+à²µà²Ÿà²à²¿ à²Šà³à²°à³à²¯à³à²µ à²
+à²ªà²Ÿà²à³ à²µà³à²¬à³ à²žà²°à³à²µà²°à³ à²®à²€à³à²€à³ à²ªà²°à³à²²à³ à²à³à²€à³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²à³à²²à²žà²®à²Ÿà²¡à³à²€à³à²€à²Šà³. à²
+à²Šà²° à²à²à²à²°à³âà²«à³à²žà³ 
+à²à²à²à²°à³à²šà³à²à³ à²à²à³à²žà³âà²ªà³à²²à³à²°à²°à³â, à²šà³à²à³à²žà³à²à³à²ªà³ à²šà³à²¯à²Ÿà²µà²¿à²à³à²à²°à³ à²®à³à²à²€à²Ÿà²Š à²¬à³à²°à³à²žà²°à³âà²à²³à²šà³à²šà³ à²¬à²³à²žà³à²€à³à²€à²Šà³.  }  
+
+_textgreenstone4_ [l=kn] {à²
+à²šà³à² à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²žà²à²à³à²°à²¹à²à²³à³ à²žà²¿ à²¡à²¿ à²°à³à²®à³âà²°à³à²ªà²Šà²²à³à²²à²¿ à²µà²¿à²€à²°à²£à³à²¯à²Ÿà²à³à²€à³à²€à²µà³. 
+à².à²Šà²Ÿ. <i>Humanity Development Library</i> à²¯à²²à³à²²à²¿ à²¹à²£à²à²Ÿà²žà²¿à²š à²²à³à²à³à², à²šà³à²°à³à²®à²²à³à²¯ à²¶à²Ÿà²žà³à²€à³à²° 
+à²à²µà³ à²®à³à²à²€à²Ÿà²Š à²µà²¿à²·à²¯à²à²³à²¿à²à³ à²žà²à²¬à²à²§à²¿à²žà²¿à²Š 1,230 à²ªà³à²°à²à²à²£à³à²à²³à³à²³à²à³à²à²¡à²¿à²µà³. à²à²šà²¿à²·à³à²  à²à²à²ªà³à²à²°à³ à²žà³à²²à²­à³à²¯à²à²³à³ à²à²°à³à²µ 
+à²
+à²­à²¿à²µà³à²Šà³à²§à²¿ à²¹à³à²à²Šà³à²€à³à²€à²¿à²°à³à²µ à²Šà³à²¶à²à²³à²²à³à²²à³ à²à²ªà²¯à³à²à²¿à²žà²¬à²¹à³à²Šà³. à²®à²Ÿà²¹à²¿à²€à²¿à²¯à²šà³à²šà³ à²µà²¿à²·à²¯, à²¶à³à²°à³à²·à²¿à²à³, à²žà²à²žà³à²¥à³ à²¯ à²¹à³à²žà²°à³, 
+à²®à²€à³à²€à³ à²¹à²²à²µà³ à²Šà²€à³à²€à²Ÿà²à²¶à²à²³à²šà³à²šà³ à²¬à²³à²žà²¿ à²¶à³à²§à²¿à²žà²¬à²¹à³à²Šà³.}  
+
+_textcustomisationtitle_ [l=kn] {à²à³à²°à²Ÿà²¹à²à³à²¯à²à³à²³à²¿à²žà³à²µà²¿à²à³}  
+_textgreenstone5_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³  à²
+à²šà³à²šà³ à²µà²¿à²žà³à²€à²°à²¿à²žà²²à³ à²®à²€à³à²€à³ à²¬à²³à²à³à²Šà²Ÿà²°à²° à²
+à²šà³à²à³à²²à²à³à²à³ à²
+à²³à²µà²¡à²¿à²žà²²à³ à²žà²Ÿà²§à³à²¯à²µà²Ÿà²à³à²µà²à²€à³ à²µà²¿à²šà³à²¯à²Ÿà²žà²à³à²³à²¿à²žà²²à²Ÿà²à²¿à²Šà³. 
+à²¹à³à²ž à²Šà²žà³à²€à²Ÿà²µà³à²à³ à²®à²€à³à²€à³ à²®à³à²à²Ÿà²¡à³à²à²Ÿ à²žà²à²µà²¿à²­à²Ÿà²à²à²³à²¿à²à³ à²ªà²°à³à²²à³âà²šà²²à³à²²à²¿ à²ªà³à²²à²à³âà²à²šà³ à²¬à²°à³à²Šà³  à²
+à²µà²à²Ÿà²¶ à²®à²Ÿà²¡à²¬à²¹à³à²Šà³. à²¹à²Ÿà²à³à²¯à³  
+à²¹à³à²ž à²®à³à²à²Ÿà²¡à³à²à²Ÿ à²žà³à²¥à³à²² à²à²£à³à²£à³à² à²µà³à²¯à²µà²žà³à²¥à³à²à²³à²šà³à²šà³ "à²à³à²²à²Ÿà²žà²¿à²«à³à²¯à²°à³à²žà³" à²¬à²°à³à²Šà³ à²à²Ÿà²°à³à²¯à²à²€à²à³à²³à²¿à²žà²¬à²¹à³à²Šà³. à²à²à²à²°à³âà²«à³à²žà³âà²š 
+à²šà³à²à²µà²šà³à²šà³ "à²®à³à²¯à²Ÿà²à³à²°à³à²žà³" à²®à³à²²à² à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²¿à²à³à²³à³à²³à²¬à²¹à³à²Šà³. à²à²à²Šà³ âà²à³à²°à³à²¬à²Ÿâ à²à³à²°à²®à²µà²¿à²¹à²¿à²€ à²®à²§à³à²¯à²µà²°à³à²€à²¿
+(à²à²Ÿà²µà²Ÿ à²®à³à²à²€à²Ÿà²Š) à²žà²à²à³à²°à²¹à²à²³ à²à²²à³à²²à²Ÿ à²žà³à²²à²­à³à²¯à²à²³ à²à²ªà²¯à³à² à²ªà²¡à³à²¯à²²à³ à²
+à²šà³à²µà³ à²®à²Ÿà²¡à²¿à²à³à²¡à³à²€à³à²€à²Šà³. à²®à³à²à³à²¯à²µà²Ÿà²à²¿ C++ à²®à²€à³à²€à³ Perlà²šà²²à³à²²à²¿
+à²žà²à²ªà³à²°à³à²£ à²à²à²° à²žà²à²à³à²€à²µà³ à²²à²­à³à²¯à²µà²Ÿà²à²¿à²°à³à²µà³à²Šà²°à²¿à²à²Š à²
+à²µà²¶à³à²¯à²µà²Ÿà²Š à²¬à²Šà²²à²Ÿà²µà²£à³à²à²³à²šà³à²šà³ à²®à²Ÿà²¡à²¿à²à³à²³à³à²³à²¬à²¹à³à²Šà³.}  
+
+_textdocumentationtitle_ [l=kn] {à²žà²à²¬à²à²§à²ªà²à³à² à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³}  
+_textdocuments_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²€à²à²€à³à²°à²Ÿà²à²¶à²à³à²à³ à²žà²à²¬à²à²§à²ªà²à³à²à²à²€à³ à²µà²¿à²µà²°à²µà²Ÿà²Š à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³ à²à²µà³.}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=kn] {à²
+à²à²à³ à²µà²¿à²³à²Ÿà²ž à²ªà²à³à²à²¿}  
+_textmailinglist_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²à³ à²žà²à²¬à²à²§à²¿à²žà²¿à²Š à²µà²¿à²à²Ÿà²° à²µà²¿à²šà²¿à²®à²¯ à²®à²€à³à²€à³ à²à²°à³à²à³à²à³ à²
+à²šà³à²à³à²²à²µà²Ÿà²à³à²µà²à²€à³ à²à²à²€à²°à³à²à²Ÿà²²à²Šà²²à³à²²à²¿ 
+à²à²à²Šà³ à²µà³à²Šà²¿à²à³à²¯à²¿à²Šà³. à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²à²ªà²¯à³à²à²¿à²žà³à²µà²µà²°à³ à² à²µà³à²Šà²¿à²à³à²¯ à²žà²Šà²žà³à²¯à²°à²Ÿà²à³à²µà³à²Šà³ 
+à²à²ªà²¯à³à²à³à²€. à² à²µà³à²Šà²¿à²à³à²¯ à²žà²Šà²žà³à²¯à²°à²Ÿà²à²²à³ <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a> à²
+à²šà³à²šà³ à²žà²à²Šà²°à³à²¶à²¿à²žà²¿. 
+à² à²µà³à²Šà²¿à²à³à²¯ à²à²²à³à²² à²žà²Šà²žà³à²¯à²°à²¿à²à³ à²µà²¿à²Šà³à²¯à³à²šà³à²®à²Ÿà²š à²
+à²à²à³ à²à²³à²¿à²žà²²à³ <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a> à²µà²¿à²³à²Ÿà²žà²à³à²à³ à²¬à²°à²¿à²¯à²¿à²°à²¿}  
+
+_textbugstitle_ [l=kn] {à²€à³à²à²Šà²°à³à²à²³à³}  
+_textreport_ [l=kn] {à²šà²¿à²®à²à³ à² à²žà²Ÿà²«à³à²à³âà²µà³à²°à³â à²žà²°à²¿à²¯à²Ÿà²à²¿ à²à³à²²à²ž à²®à²Ÿà²¡à³à²€à³à²€à²Ÿ à²à²²à³à²²à²µà²Ÿ à²à²à²Šà³ à²šà³à²µà³ à²à²Ÿà²€à³à²°à²¿à²®à²Ÿà²¡à²¿à²à³à²³à³à²³à²¬à³à²à³.<a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">the mailing list</a>à²à²²à³à²²à²¿à²à³ à²Šà²¯à²µà²¿à²à³à²à³ à²¯à²Ÿà²µà³à²Šà²Ÿà²Šà²°à³ à²¬à²à³à²žà³â à²à²Šà³à²Šà²²à³à²²à²¿ à²€à²¿à²³à²¿à²žà²¿.}  
+
+_textgs3title_ [l=kn] {à²à³à²²à²žà²à²³à²²à³à²²à²¿}  
+_textgs3_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ 3 à²žà²à²ªà³à²°à³à²£à²µà²Ÿà²à²¿ à²ªà³à²šà²°à³à²µà²¿à²šà³à²¯à²Ÿà²žà²à³à²³à²¿à²žà²²à³à²ªà²à³à²à²¿à²Šà³. à²
+à²Šà³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ 2à²šà³ à²à²µà³à²€à³à²€à²¿à²¯ 
+à²à²²à³à²² à²žà³à²²à²­à³à²¯à²à²³à²šà³à²šà³ à²¹à³à²à²Šà²¿à²Šà³- à².à²Šà²Ÿ. à²¬à²¹à³à²­à²Ÿà²·à²Ÿ, à²¬à²¹à³ à²µà³à²Šà²¿à²à³, à²®à²€à³à²€à³ à²žà²®à²à³à²°à²Ÿà²à³à²€à²¿à²à³, à²à²€à³à²¯à²Ÿà²Šà²¿. 
+à²
+à²Šà³ à²¹à²¿à²à²Šà²¿à²š à²à²µà³à²€à³à²€à²¿à²à²³à³à²¡à²šà³ à²žà²¹à²µà²°à³à²€à²šà³ à²¹à³à²à²Šà²¿à²Šà³.   à²à²Ÿà²µà²Ÿà²Šà²²à³à²²à²¿ à²¬à²°à³à²¯à²²à³à²ªà²à³à² à²à²Šà³ à²¹à²²à²µà³ 
+à²žà³à²µà²€à²à²€à³à²° à²à²à²à²à²³ à²à²à³à²à³à²; à² à²à²à²à²à²³à³ à²à²à³à²žà³ à²à²®à³ à²à²²à³ à²®à³à²à²Ÿà²à²€à²° à²µà²¿à²·à²¯ à²®à²€à³à²€à³ à²žà²à²Šà³à²¶à²à²³à²šà³à²šà³
+à²µà²¿à²šà²¿à²®à²¯ à²®à²Ÿà²¡à²¿à²à³à²³à³à²³à³à²€à³à²€à²µà³. à²¹à³à²à³ à²
+à²Šà³ âà²¹à²°à²¡à³â à²®à²Ÿà²Šà²°à²¿à²¯à²²à³à²²à²¿ à²à³à²²à²ž à²®à²Ÿà²¡à³à²µà³à²Šà²°à²¿à²à²Š à²
+à²Šà²° à²à²Ÿà²°à³à²¯ 
+à²µà²¿à²µà²¿à²§ à²žà²°à³à²µà²°à³âà²à²³à²²à³à²²à²¿ à²¹à²à²à²¿à²à³à²³à³à²³à²²à³ à²žà²Ÿà²§à³à²¯. à² à²žà²Ÿà²§à³à²¯à²€à³à²¯à²¿à²à²Šà²Ÿà²à²¿ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ââà²
+à²šà³à²šà³ à²šà²¿à²®à³à²® 
+à²
+à²µà²¶à³à²¯à²à²€à³à²à²³à²¿à²à²šà³à²à³à²£à²µà²Ÿà²à²¿ à²¹à³à²à²Šà²¿à²žà²¬à²¹à³à²Šà³ à²¹à²Ÿà²à³ à²µà²¿à²žà³à²€à²°à²¿à²žà²¬à²¹à³à²Šà³. à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ 3 à²à³à²à³ 
+à²žà²à²¬à²à²§à²¿à²žà²¿à²Š à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à³ à²®à²€à³à²€à³ à²ªà²°à³à²à³à²·à²Ÿ à²¬à²¿à²¡à³à²à²¡à³à²à²³à²šà³à²šà³ 
+<a href="http://www.greenstone.org/greenstone3.html">Greenstone 3 home page</a>
+à²šà²¿à²à²Š à²à²³à²¿à²žà²¿à²à³à²³à³à²³à²¬à²¹à³à²Šà³.}  
+
+_textcreditstitle_ [l=kn] {à²®à²šà³à²šà²£à³}  
+
+_textwhoswho_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²€à²à²€à³à²°à²Ÿà²à²¶ à²¹à²²à²µà²Ÿà²°à³ à²à²šà²° à²žà²¹à²à²Ÿà²°à²Š à²«à²². à²°à²Ÿà²¡à³à²à²°à³ à²®à³à²à³à²šà²Ÿà²¬à³ à²®à²€à³à²€à³ à²žà³à²à³à²«à²šà³ à²¬à²Ÿà²¡à²¿ à²à²Šà²° à²®à³à²à³à²¯ à²¶à²¿à²²à³à²ªà²¿à²à²³à³.  
+à²¡à³à²µà²¿à²¡à³â à²¬à³à²šà³âà²¬à³à²°à²¿à²¡à³à²à³â, à²à²¿à²¯à³à²°à³âà²à³â à²¬à³à²à²Ÿà²šà²šà³â, à²¹à³à²à²à³ à²à³à²šà³, à²®à³à²à³à²²à³  à²¡à³à²¯à³à²žà³à²šà²¿à²ªà³, à²à³à²¥à²°à²¿à²šà³ à²¡à²Ÿà²šà³, à²à²²à³à²à³ à²¡à²à²à²°à³, à²à²Ÿà²°à³à²²à³ à²à³à²à³à²µà²¿à²šà³, à²à³à²«à³ à²¹à³à²®à³à²žà³, 
+à²¡à²Ÿà²š à²®à³à²à³, à²à²Ÿà²šà³ à²®à³à²à³à²«à²°à³à²žà²šà³, à²à³à²°à³à²à³ à²šà³à²µà²¿à²²à³-à²®à²Ÿà²šà²¿à²à²à³, à²¡à³à²šà²²à³ à²ªà²à³à²²à³, à²à²Ÿà²°à³à²¡à²šà³ à²ªà³à²šà³à²à²°à³, à²¬à²°à³à²šà²Ÿà²°à³à²¡à³ à²«à²Ÿà²°à²¿à²à²à²°à³, 
+à²à²Ÿà²¡à³ à²°à³à²¡à³, à²¬à²¿à²²à³ à²°à³à²à²°à³à²žà³, à²à²Ÿà²šà³ à²¥à²Ÿà²®à³à²žà²šà³ à²®à²€à³à²€à³ à²žà³à²à³à²µà²°à³à²à³ à²¯à³à²à³à²žà³ à²à²µà²°à³à²²à³à²² à² à²€à²à²€à³à²°à²Ÿà²à²¶à²à³à²à³ à²à³à²¡à³à²à³ à²šà³à²¡à²¿à²Šà³à²Šà²Ÿà²°à³. 
+à²šà³à²¯à³à²à²¿à²²à³à²à²¡à³ à²¡à²¿à²à²¿à²à²²à³â à²²à³à²¬à³à²°à²°à²¿à²¯ à²à²€à²° à²žà²Šà²žà³à²¯à²°à²Ÿà²Š à²®à²Ÿà²°à³à²à³ à²
+à²ªà³à²ªà²°à³à²²à²¿, à²žà³à²¯à²Ÿà²²à³à²²à²¿ à²à³ à²à²šà³à²šà²¿à²à²à³âà²¹à²Ÿà²®à³, à²®à³à²¯à²Ÿà²à³à²à³ à²à³à²šà³à²žà³, 
+à²žà³à²à³à²µà³ à²à³à²šà³à²žà³, à²à³ à²à²à²Ÿ à²à³à²à²šà³, à²®à³à²à³à²²à³ à²²à³à²à³à²žà³, à²®à²²à²¿à²à²Ÿ à²®à³à²°à²¿, à²à³à²¯à²Ÿà²°à²¿ à²®à²Ÿà²°à³à²žà³à²¡à³à²šà³, à²¡à³à²µà³ à²šà²¿à²à³à²²à³à²žà³ à²
+à²šà³à²Šà³ à²²à²Ÿà²¯à³à²¡à³ à²žà³à²®à²¿à²€à³ 
+à²à²µà²°à³à²à²³à³ à²žà²²à²¹à³ à²®à²€à³à²€à³ à²à²€à³à²€à³à²à²š à²šà³à²¡à²¿à²Šà³à²Šà²Ÿà²°à³. à² à²µà²¿à²€à²°à²£à³à²¯à³à²à²Šà²¿à²à³ à²à²°à³à²µ à²à²¿à²à²šà³âà²¯à³ à²
+à²šà³à²®à²€à²¿ à²ªà²¡à³à²Š MG, GDBM, 
+PDFTOHTML, PERL, WGET, WVWARE and XLHTML à² à²à²²à³à²²à²Ÿ à²€à²à²€à³à²°à²Ÿà²à²¶à²à²³à²¿à²à³ à²à³à²¡à³à²à³ à²šà³à²¡à²¿à²Šà²µà²°à²šà³à²šà³ à²à²²à³à²²à²¿ à²µà²à²Šà²¿à²žà³à²€à³à²€à³à²µà³.}  
+
+_textaboutgslong_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²€à²à²€à³à²°à²Ÿà²à²¶à²Š à²¬à²à³à²à³}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=kn] {à²ªà³à²°à²žà³à²€à³à²€ à²à²ªà²¯à³à²à²¿à²žà³à²µà²µà²° à²ªà²à³à²à²¿}  
+_textuser_ [l=kn] {à²à²ªà²¯à³à²à²¿à²žà³à²µà²µà²°à³}  
+_textas_ [l=kn] {à² à³à²µà²£à²¿ à²žà³à²¥à²¿à²€à²¿}  
+_textgroups_ [l=kn] {à²à³à²à²ªà³à²à²³à³}  
+_textcomment_ [l=kn] {à²
+à²­à²¿à²ªà³à²°à²Ÿà²¯}  
+_textadduser_ [l=kn] {à²¹à³à²ž à²à²ªà²¯à³à²à²¿à²žà³à²µà²µà²°à²šà³à²šà³ à²žà³à²°à²¿à²žà³}  
+_textedituser_ [l=kn] {à²€à²¿à²Šà³à²Šà³}  
+_textdeleteuser_ [l=kn] {à²€à³à²à³}  
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=kn] {à²à²ªà²¯à³à²à²¿à²žà³à²µà²µà²° à²®à²Ÿà²¹à²¿à²€à²¿à²¯à²šà³à²šà³ à²€à²¿à²Šà³à²Šà³}  
+_textadduser_ [l=kn] {à²¹à³à²ž à²à²ªà²¯à³à²à²¿à²žà³à²µà²µà²°à²šà³à²šà³ à²žà³à²°à²¿à²žà³}  
+
+_textaboutusername_ [l=kn] {à²¬à²³à²à³à²Šà²Ÿà²°à²° à²¹à³à²žà²°à²¿à²š à²à²Šà³à²Š  2 à²°à²¿à²à²Š 30 à²
+à²à³à²·à²°à²à²³ à²à²³à²à²¿à²°à²¬à³à²à³. à²
+à²Šà³ à²µà²°à³à²£à²®à²Ÿà²²à³ à²
+à²à³à²·à²°à²à²³à³ à²®à²€à³à²€à³ à²
+à²à²à²¿à²à²³à²šà³à²šà³ à²¹à³à²à²Šà²¿à²°à²¬à²¹à³à²Šà³. }  
+
+_textaboutpassword_ [l=kn] {à²žà²à²à³à²€à²ªà²Šà²à²³ à²à²Šà³à²Š 3à²°à²¿à²à²Š 128 à²
+à²à³à²·à²°à²à²³ à²à²³à²à²¿à²°à²¬à³à²à³. 
+à²
+à²Šà³  à²žà²Ÿà²§à²Ÿà²°à²£à²µà²Ÿà²à²¿ à²®à³à²Šà³à²°à²¿à²žà²¬à²²à³à²² à²¯à²Ÿà²µà³à²Šà³à²à²žà³à²à³ à²
+à²à³à²·à²°à²à²³à²šà³à²šà³ à²¹à³à²à²Šà²¿à²°à²¬à²¹à³à²Šà³.}  
+
+_textoldpass_ [l=kn] {à²à²à²Šà³à²µà³à²³à³ à² à²à³à²·à³à²€à³à²° à²à²Ÿà²²à²¿ à²à²Šà³à²Šà²²à³à²²à²¿ à²¹à²³à³ à²žà²à²à³à²€à²ªà²Šà²µà³ à²à²°à³à²€à³à²€à²Šà³. }  
+_textenabled_ [l=kn] {à²žà²à³à²°à²¿à²¯à²à³à²³à²¿à²žà²²à²Ÿà²à²¿à²Šà³}  
+_textdisabled_ [l=kn] {à²šà²¿à²·à³à²à³à²°à²¿à²¯à²à³à²³à²¿à²žà²²à²Ÿà²à²¿à²Šà³}  
+
+_textaboutgroups_ [l=kn] {`à²à³à²à²ªà³à²à²³à³' 'à²
+à²°à³à²§ à²µà²¿à²°à²Ÿà²®' à²à²¿à²¹à³à²šà³à²¯à²¿à²à²Š à²¬à³à²°à³à²ªà²à³à² à²ªà²à³à²à²¿. 'à²
+à²°à³à²§ à²µà²¿à²°à²Ÿà²®' à²à²¿à²¹à³à²šà³à²¯ à²šà²à²€à²° à²à²Ÿà²à²µà²šà³à²šà³ à²¬à²¿à²¡à²¬à³à²¡à²¿.}  
+_textavailablegroups_ [l=kn] {à²ªà³à²°à³à²µà²­à²Ÿà²µà²¿à²¯à²Ÿà²à²¿ à²šà²¿à²°à³à²§à²°à²¿à²€à²µà²Ÿà²Š à²à³à²à²ªà³à²à²³à²²à³à²²à²¿à²°à³à²µ à²à²¡à²³à²¿à²€à²à²Ÿà²° à²®à²€à³à²€à³ à²à²€à²°à²°à³  
+à²²à³à²¬à³à²°à³à²°à²¿à²¯à²šà³ à²à²à²à²°à³âà²«à³à²žà³ à²
+à²¥à²µ à²¡à²¿à²ªà²Ÿà²žà²¿à²à²°à³ à²¬à²³à²žà²¿ à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà³à²µ à²¹à²à³à²à³à²à²³à²šà³à²šà³ à²šà³à²°à²žà²à²ªà²°à³à²à²µà²¿à²²à³à²²à²Š 
+à²¬à²³à²à³à²Šà²Ÿà²°à²°à²¿à²à³ à²šà³à²¡à³à²€à³à²€à²Ÿà²°à³.  
+<ul>
+<li><b>à²à²¡à²³à²¿à²€à²à²Ÿà²°</b>: à²žà³à²à³âà²š à²žà²®à²à³à²°à²Ÿà²à³à²€à²¿à²¯à²šà³à²šà³ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà³à²µ à²®à²€à³à²€à³ à²¬à²³à²à³à²Šà²Ÿà²°à²° à²à²Ÿà²€à³à²à²³à²šà³à²šà³ à²ªà³à²°à²µà³à²¶à²¿à²žà³à²µ à²
+à²§à²¿à²à²Ÿà²°à²µà²šà³à²šà³ à²à³à²¡à²¬à²¹à³à²Šà³.
+<li><b>à²à²Ÿà²žà²à²¿ à²žà²à²à³à²°à²¹à²à²³ à²žà²à²ªà²Ÿà²Šà²</b>: à²¹à³à²ž à²à²Ÿà²žà²à²¿ à²žà²à²à³à²°à²¹à²à²³ à²šà²¿à²°à³à²®à²Ÿà²£ à²
+à²§à²¿à²à²Ÿà²°à²µà²šà³à²šà³ à²à³à²¡à²¬à²¹à³à²Šà³.
+<li><b><&collection-name>-à²žà²à²à³à²°à²¹ à²žà²à²ªà²Ÿà²Šà²</b>: à²¹à³à²ž à²à²Ÿà²žà²à²¿ à²®à²€à³à²€à³ à²à²Ÿà²à²€à²¿à² à²žà²à²à³à²°à²¹à²à²³ à²šà²¿à²°à³à²®à²Ÿà²£ à²®à²€à³à²€à³ à²
+à²µà³à²à²³à²šà³à²šà³ à²€à²¿à²Šà³à²Šà³à²µ à²
+à²§à²¿à²à²Ÿà²°à²à²³à²šà³à²šà³ à²à³à²¡à²¬à²¹à³à²Šà³.
+</ul>}  
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=kn] {à² à²à²ªà²¯à³à²à²¿à²žà³à²µà²µà²°à²šà³à²šà³ à²€à³à²à³}  
+_textremwarn_ [l=kn] {<b>_cgiargumun_</b> à²¬à²³à²à³à²Šà²Ÿà²°à²°à²šà³à²šà³ à²šà³à²µà³ à²šà²¿à²à²µà²Ÿà²à²¿ à²¶à²Ÿà²¶à³à²µà²€à²µà²Ÿà²à²¿ à²€à³à²à³à²¯à²²à³ à²à²à³à²à²¿à²žà³à²€à³à²€à³à²°à²Ÿ?}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=kn] {à²žà²à²à³à²€à²ªà²Šà²µà²šà³à²šà³ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà³}  
+_textoldpw_ [l=kn] {à²¹à²³à³à²¯ à²žà²à²à³à²€à²ªà²Š}  
+_textnewpw_ [l=kn] {à²¹à³à²ž à²žà²à²à³à²€à²ªà²Š}  
+_textretype_ [l=kn] {à²¹à³à²ž à²žà²à²à³à²€à²ªà²Šà²µà²šà³à²šà³ à²®à²€à³à²€à³ à²¬à²°à³}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=kn] {à²šà²¿à²®à³à²® à²žà²à²à³à²€à²ªà²Šà²µà²šà³à²šà³ à²žà²«à²²à²µà²Ÿà²à²¿ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²¿à²€à³.}  
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=kn] {à²à²ªà²¯à³à²à²¿à²žà³à²µà²µà²° à²¹à³à²žà²°à³ à²
+à²žà²®à²à²à²ž}  
+_textinvalidpassword_ [l=kn] {à²žà²à²à³à²€à²ªà²Š à²
+à²žà²®à²à²à²ž}  
+_textemptypassword_ [l=kn] {à²Šà²¯à²µà²¿à²à³à²à³ à² à²¬à²³à²à³à²Šà²Ÿà²°à²° à²à²°à²à²­ à²žà²à²à³à²€à²ªà²Šà²µà²šà³à²šà³ à²¬à²°à³à²¯à²¿à²°à²¿}  
+_textuserexists_ [l=kn] {à² à²¹à³à²žà²°à²¿à²š à²¬à²³à²à³à²Šà²Ÿà²°à²°à³ à²à²à²Ÿà²à²²à³ à²à²Šà³à²Šà²Ÿà²°à³; à²Šà²¯à²µà²¿à²à³à²à³ à²¬à³à²°à³à²à²Šà³ à²¹à³à²žà²°à²šà³à²šà³ à²žà³à²à²¿à²žà²¿}  
+
+_textusernameempty_ [l=kn] {à²Šà²¯à²µà²¿à²à³à²à³ à²šà²¿à²®à³à²® à²à²ªà²¯à³à²à²¿à²žà³à²µà²µà²° à²¹à³à²žà²°à²šà³à²šà³ à²¬à²°à³à²¯à²¿à²°à²¿}  
+_textpasswordempty_ [l=kn] {à²šà³à²µà³ à²šà²¿à²®à³à²® à²¹à²³à³à²¯ à²žà²à²à³à²€à²ªà²Šà²µà²šà³à²šà³ à²¬à²°à³à²¯à²²à³à²¬à³à²à³}  
+_textnewpass1empty_ [l=kn] {à²šà²¿à²®à³à²® à²¹à³à²ž à²žà²à²à³à²€à²ªà²Šà²µà²šà³à²šà³ à²¬à²°à³à²¯à²¿à²°à²¿ à²®à²€à³à²€à³ à²šà²à²€à²° à²
+à²Šà²šà³à²šà³ à²ªà³à²šà² à²¬à²°à³à²¯à²¿à²°à²¿}  
+_textnewpassmismatch_ [l=kn] {à²šà²¿à²®à³à²® à²žà²à²à³à²€à²ªà²Šà²Š à²à²°à²¡à³ à²à²µà³à²€à³à²€à²¿à²à²³à³ à²¹à³à²à²Šà³à²€à³à²€à²¿à²²à³à²². }  
+_textnewinvalidpassword_ [l=kn] {à²šà³à²µà³ à²¬à²°à³à²Š à²žà²à²à³à²€à²ªà²Š à²
+à²žà²®à²à²à²žà²µà²Ÿà²Šà³à²Šà³}  
+_textfailed_ [l=kn] {à²šà²¿à²®à³à²® à²à²ªà²¯à³à²à²¿à²žà³à²µà²µà²° à²¹à³à²žà²°à³ à²
+à²¥à²µ à²žà²à²à³à²€à²ªà²Š à²žà²°à²¿à²¯à²Ÿà²à²¿à²²à³à²²}  
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²à²µà³à²€à³à²€à²¿ à²žà²à²à³à²¯à³}  
+_textframebrowser_ [l=kn] {à²à²Šà²šà³à²šà³ à²šà³à²¡à²²à³ à²«à³à²°à³à²®à³â à²žà²à³à²°à²¿à²¯à²à³à²³à²¿à²žà²¿à²Š  à²¬à³à²°à³à²žà²°à³â à²šà²¿à²®à³à²®à²²à³à²²à²¿à²°à²¬à³à²à³. }  
+_textusermanage_ [l=kn] {à²¬à²³à²à³à²Šà²Ÿà²°à²° à²šà²¿à²¯à²à²€à³à²°à²£}  
+_textlistusers_ [l=kn] {à²à²ªà²¯à³à²à²¿à²à²³ à²ªà²à³à²à²¿à²®à²Ÿà²¡à³}  
+_textaddusers_ [l=kn] {à²¹à³à²ž à²¬à²³à²à³à²Šà²Ÿà²°à²°à²šà³à²šà³ à²žà³à²°à²¿à²žà²¿}  
+_textchangepasswd_ [l=kn] {à²žà²à²à³à²€à²ªà²Šà²µà²šà³à²šà³ à²¬à²Šà²²à²¿à²žà³}  
+_textinfo_ [l=kn] {à²€à²Ÿà²à²€à³à²°à²¿à² à²®à²Ÿà²¹à²¿à²€à²¿}  
+_textgeneral_ [l=kn] {à²žà²Ÿà²§à²Ÿà²°à²£}  
+_textarguments_ [l=kn] {à²à²°à³âà²à³à²¯à³à²®à³à²à²à³âà²à²³à³}  
+_textactions_ [l=kn] {à²à³à²°à²¿à²¯à³à²à²³à³}  
+_textbrowsers_ [l=kn] {à²¬à³à²°à³à²žà²°à³âà²à²³à³}  
+_textprotocols_ [l=kn] {à²à³à²°à²®à²µà²¿à²¹à²¿à²€à²à²³à³}  
+_textconfigfiles_ [l=kn] {à²
+à²³à²µà²¡à²¿à²žà³à²µà²¿à²à³à²¯ à²à²¡à²€à²à²³à³}  
+_textlogs_ [l=kn] {à²²à²Ÿà²à³âà²à²³à³}  
+_textusagelog_ [l=kn] {à²¬à²³à²à³à²¯à²Ÿà²Š à²¬à²à³à²à³ à²²à²Ÿà²à³}  
+_textinitlog_ [l=kn] {à²à²šà²¿à²à³ à²²à²Ÿà²à³â}  
+_texterrorlog_ [l=kn] {à²€à²ªà³à²ªà³ à²²à²Ÿà²à³â}  
+_textadminhome_ [l=kn] {à²
+à²¡à³âà²®à²¿à²šà³â à²¹à³à²®à³â}  
+_textreturnhome_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²¹à³à²®à³â}  
+_titlewelcome_ [l=kn] {à²à²¡à²³à²¿à²€}  
+_textmaas_ [l=kn] {à²à²Šà²à³à²µ à²žà²à²°à²à³à²·à²£à³ à²®à²€à³à²€à³ à²à²¡à²³à²¿à²€ à²žà³à²µà³à²à²³ à²²à²­à³à²¯à²à²³à²Ÿà²µà³à²Šà³à²à²Šà²°à³:}  
+_textvol_ [l=kn] {à²à²šà³âà²²à³à²šà³â à²²à²Ÿà²à³âà²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà³}  
+_textcmuc_ [l=kn] {à²žà²à²à³à²°à²¹à²à²³à²šà³à²šà³ à²šà²¿à²°à³à²®à²¿à²žà³, à²žà²à²°à²à³à²·à²£à³ à²®à²€à³à²€à³ à²à²§à³à²šà³à²à²°à²¿à²žà³ }  
+_textati_ [l=kn] {à²žà²¿à²à²¿à² à²à²°à³âà²à³à²¯à³à²®à³à²à²à³âà²šà²à²€à²¹ à²€à²Ÿà²à²€à³à²°à²¿à² à²®à²Ÿà²¹à²¿à²€à²¿à²¯à²šà³à²šà³ à²ªà²¡à³à²¯à²¿à²°à²¿}  
+
+_texttsaa_ [l=kn] {à² à²žà³à²µà³à²¯à²šà³à²šà³ à²ªà³à²°à²µà³à²¶à²¿à²žà²²à³ à² à²ªà³à²à²Š à²à²¡à²­à²Ÿà²à²Šà²²à³à²²à²¿à²°à³à²µ à²šà³à²¯à²Ÿà²µà²¿à²à³à²·à²šà³â à²¬à²Ÿà²°à²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¿}  
+
+_textcolstat_ [l=kn] {à²žà²à²à³à²°à²¹ à²žà³à²¥à²¿à²€à²¿}  
+
+_textcwoa_ [l=kn] {à²à²à²Šà³ à²žà²à²à³à²°à²¹à²µà³ à²à²Ÿà²²à³à²€à²¿à²¯à²²à³à²²à²¿à²Šà³ à²à²à²Šà³ à²à²Ÿà²£à²¬à³à²à²Ÿà²Šà²°à³, à²
+à²Šà²à³à²à³ à²žà²à²¬à²à²§à²¿à²žà²¿à²Š build.cfg 
+à²à²¡à²€à²µà²¿à²°à²¬à³à²à³, à² à²à²¡à²€à²µà²šà³à²šà³ à²à²Šà²²à³ à²žà²Ÿà²§à³à²¯à²µà²Ÿà²à²¬à³à²à³,  à² à²à²¡à²€ à²à²à²Šà³ à²žà²®à²à²à²žà²µà²Ÿà²Š à²šà²¿à²°à³à²®à²Ÿà²£ 
+à²Šà²¿à²šà²Ÿà²à²à²µà²šà³à²šà³  (i.e. > 0) à²¹à³à²à²Šà²¿à²°à²¬à³à²à³ à²®à²€à³à²€à³ à²à²¡à²€ à²žà²à²à³à²°à²¹à²Š à²žà³à²à³ à²¡à³à²°à³à²à³à²à²°à²¿à²¯à²²à³à²²à²¿à²°à²¬à³à²à³.}  
+
+_textcafi_ [l=kn] {à²à²à²Šà³ à²žà²à²à³à²°à²¹à²Š à²¬à²à³à²à³ à²®à²Ÿà²¹à²¿à²€à²¿à²à³ <i>abbrev.</i> à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿}  
+_textcctv_ [l=kn] {à²žà²à²à³à²°à²¹à²µà²šà³à²šà³ à²šà³à²¡à²²à³ <i>à²žà²à²à³à²°à²¹</i> à²µà²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà³}  
+_textsubc_ [l=kn] {à²¬à²Šà²²à²Ÿà²µà²£à³à²à²³à²šà³à²šà³ à²®à²à²¡à²¿à²žà³}  
+_texteom_ [l=kn] {main.cfg à²šà³à²šà³ à²€à³à²°à³à²¯à³à²µà²²à³à²²à²¿ à²€à²ªà³à²ªà³}  
+_textftum_ [l=kn] {main.cfg à²šà³à²šà³ à²à²§à³à²šà³à²à²°à²¿à²žà³à²µà²²à³à²²à²¿ à²µà²¿à²«à²²à²µà²Ÿà²à²¿à²Šà³}  
+_textmus_ [l=kn] {main.cfg à²žà²«à²²à²µà²Ÿà²à²¿ à²à²§à³à²šà³à²à²°à²£à²à³à²à²¡à²¿à²Šà³}  
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=kn] {_collectionname_ à²žà²à²à³à²°à²¹à²à³à²à³ à²žà²Ÿà²°à²Ÿà²à²¶ à²šà²¿à²°à³à²®à²¿à²žà²¿}  
+_textflog_ [l=kn] {_collectionname_ à²žà²à²à³à²°à²¹à²à³à²à³ à²²à²Ÿà²à³ à²µà²¿à²«à²²}  
+_textilog_ [l=kn] {_collectionname_ à²žà²à²à³à²°à²¹à²à³à²à³ à²²à²Ÿà²à³âà²šà³à²šà³ à²à²®à²Šà³ à²®à²Ÿà²¡à²¿à²à³à²³à³à²³à²¿}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=kn] {à²žà²²à²¹à³ / à²ªà³à²°à²€à²¿à²à³à²°à²¿à²¯à³à²à²³à²šà³à²šà³ à²à²³à²¿à²žà²¿}  
+
+_greenstoneusabilitytext_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²à²ªà²¯à³à² à²ªà²à³à²€à³à²µ}  
+
+_textwhy_ [l=kn] {<p>à² à²µà²°à²Šà²¿à²¯à²šà³à²šà³ à²à²³à³à²¹à²¿à²žà³à²µà³à²Šà²° à²®à³à²²à² à²šà³à²µà³ à²µà³à²à³à²·à²¿à²žà³à²€à³à²€à²¿à²Šà³à²Š à²µà³à²¬à³âà²ªà³à² à²à³à²²à²¿à²·à³à² à²®à²€à³à²€à³ à²šà²¿à²°à²Ÿà²¶à²Ÿà²Šà²Ÿà²¯à²à²µà²Ÿà²à²¿à²€à³à²€à³ à²à²à²Šà³ à²žà³à²à²¿à²žà³à²€à³à²€à³à²°à²¿}  
+_textextraforform_ [l=kn] {à²šà³à²µà³ à²
+à²°à³à²à²¿à²¯à²šà³à²šà³ à²ªà³à²°à³à²£à²µà²Ÿà²à²¿ à²€à³à²à²¬à²¬à³à²à²¿à²²à³à²² -- à²¯à²Ÿà²µà³à²Šà³ à²®à²Ÿà²¹à²¿à²€à²¿ à²à²Šà²à²¿à²žà²¿à²Šà²°à³ à²žà²¹à²Ÿà²¯à²µà²Ÿà²à³à²€à³à²€à²Šà³}  
+_textprivacybasic_ [l=kn] {<p>à² à²µà²°à²Šà²¿à²¯à²²à³à²²à²¿ à²šà³à²µà³ à²€à²€à³à²žà²®à²¯ à²µà³à²à³à²·à²¿à²žà²¿à²€à³à²€à²¿à²°à³à²µ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²µà³à²¬à³ à²ªà³à² à²®à²€à³à²€à³ à²
+à²Šà²šà³à²šà³ à²šà³à²¡à²²à³ à²šà³à²µà³ à²à²ªà²¯à³à²à²¿à²žà³à²€à³à²€à²¿à²Šà³à²Š à²€à²à²€à³à²°à²à³à²šà²Ÿà²šà²à³à²à³ à²žà²à²¬à²à²§à²¿à²žà²¿à²Š (à²®à²€à³à²€à³ à²®à³à²²à³ à²šà³à²µà³ à²à²Šà²à²¿à²žà²¿à²Š à²à²à³à²à²¿à² à²®à²Ÿà²¹à²¿à²€à²¿) à²®à²Ÿà²¹à²¿à²€à²¿à²à²³à²·à³à²à³ à²à²°à³à²€à³à²€à²Šà³.}  
+_textstillsend_ [l=kn] {à²šà³à²µà³ à² à²µà²°à²Šà²¿à²¯à²šà³à²šà³ à²à²³à³à²¹à²¿à²ž à²¬à²¯à²žà³à²€à³à²€à³à²°à²Ÿ}  
+
+_texterror_ [l=kn] {à²šà³à²¯à³à²šà²€à³}  
+_textyes_ [l=kn] {à²¹à³à²Šà³}  
+_textno_ [l=kn] {à²à²²à³à²²}  
+_textclosewindow_ [l=kn] {à²à²¿à²à²à²¿à²¯à²šà³à²šà³ à²®à³à²à³à²à²¿}  
+_textabout_ [l=kn] {à²¬à²à³à²à³}  
+_textprivacy_ [l=kn] {à²à³à²ªà³à²¯à²€à³}  
+_textsend_ [l=kn] {à²à²³à³à²¹à²¿à²žà²¿}  
+_textdontsend_ [l=kn] {à²à²³à²¿à²ž à²¬à³à²¡à²¿}  
+_textoptionally_ [l=kn] {à²à²à³à²à²¿à²à²µà²Ÿà²à²¿}  
+
+_textunderdev_ [l=kn] {à²µà²¿à²µà²°à²à²³ à²®à³à²šà³à²šà³à² à²
+à²à²€à²¿à²® à²à²µà³à²€à³à²€à²¿à²¯à²²à³à²²à²¿ à²Šà³à²°à²à³à²µà³à²Šà³}  
+
+_textviewdetails_ [l=kn] {à²µà²°à²Šà²¿à²¯ à²µà²¿à²µà²°à²à²³à²šà³à²šà³ à²µà³à²à³à²·à²¿à²žà²¿}  
+_textmoredetails_ [l=kn] {à²¹à³à²à³à²à²¿à²š à²µà²¿à²µà²°à²à²³à³}  
+_texttrackreport_ [l=kn] {à² à²µà²°à²Šà²¿à²¯ à²à²Ÿà²¡à²šà³à²šà³ à²à²®à²šà²¿à²žà³à²€à³à²€à²¿à²°à³}  
+_textcharacterise_ [l=kn] {à²à²Šà³ à²¯à²Ÿà²µ à²¬à²à³à²¯ à²žà²®à²žà³à²¯à³}  
+_textseverity_ [l=kn] {à²žà²®à²žà³à²¯à³ à²à²·à³à²à³ à²à²à²­à³à²°à²µà²Ÿà²Šà²Šà³à²Šà³}  
+ 
+_textbadrender_ [l=kn] {à²ªà³à² à²µà²¿à²²à²à³à²·à²£à²µà²Ÿà²à²¿ à²à²Ÿà²£à³à²€à³à²€à²Šà³}  
+_textcontenterror_ [l=kn] {à²µà²žà³à²€à³ à²µà²¿à²·à²¯ à²šà³à²¯à³à²šà²€à³}  
+_textstrangebehaviour_ [l=kn] {à²µà²¿à²²à²à³à²·à²£ à²µà²°à³à²€à²šà³}  
+_textunexpected_ [l=kn] {à²
+à²šà²¿à²°à³à²à³à²·à²¿à²€à²µà²Ÿà²Šà²Šà³à²Šà³ à²žà²à²­à²µà²¿à²žà²¿à²Šà³}  
+_textfunctionality_ [l=kn] {à²à²ªà²¯à³à²à²¿à²žà²²à³ à²à²·à³à²}  
+_textother_ [l=kn] {à²à²€à²°}  
+
+_textcritical_ [l=kn] {à²à²à²­à³à²°}  
+_textmajor_ [l=kn] {à²µà²¿à²·à²®}  
+_textmedium_ [l=kn] {à²®à²Ÿà²§à³à²¯à²®}  
+_textminor_ [l=kn] {à²
+à²ªà³à²°à²§à²Ÿà²š}  
+_texttrivial_ [l=kn] {à²
+à²ªà³à²°à²¯à³à²à²}  
+
+_textwhatdoing_ [l=kn] {à²šà³à²µà³ à²à²šà³ à²®à²Ÿà²¡à²²à³ à²ªà³à²°à²¯à²€à³à²šà²¿à²žà³à²€à³à²€à²¿à²Šà³à²Šà²¿à²°à²¿?}  
+_textwhatexpected_ [l=kn] {à²šà³à²µà³ à²à²šà³ à²žà²à²­à²µà²¿à²žà²¬à³à²à³à²à²Šà³ à²šà²¿à²°à³à²à³à²·à²¿à²žà³à²€à³à²€à²¿à²Šà³à²Šà²¿à²°à²¿? }  
+_textwhathappened_ [l=kn] {à²µà²Ÿà²žà³à²€à²µà²µà²Ÿà²à²¿ à²à²šà²Ÿà²¯à²¿à²€à³?}  
+
+_cannotfindcgierror_ [l=kn] {<h2>à²à³à²·à²®à²¿à²žà²¿!</h2>"_linktextusab_" à²à³à²à²¡à²¿à²à³ à²žà²à²¬à²à²§à²¿à²žà²¿à²Š à²žà²°à³à²µà²°à³ à²ªà³à²°à³à²à³à²°à²Ÿà²à²à²³à³ à²à²Ÿà²£à²¿à²žà³à²€à³à²€à²¿à²²à³à²².}  
+
+_textusabbanner_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²à³à²°à³ à²¶à³à²²à²¿à²¯ à²§à³à²µà²}  
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=kn] {à²à²à²Šà³ à²€à²ªà³à²ªà³ à²žà²à²­à²µà²¿à²žà²¿à²Šà³}  
+
+_textgtihome_ [l=kn] {à² à²ªà³à²à²à²³à³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²š à²¬à²¹à³à²­à²Ÿà²·à²Ÿ à²žà³à²²à²­à³à²¯à²à²³à²šà³à²šà³ à²à²€à³à²€à²® à²ªà²¡à²¿à²žà²²à³ à²žà²¹à²Ÿà²¯ à²®à²Ÿà²¡à³à²€à³à²€à²µà³. à²à²µà²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¿ à²šà³à²µà³
+<ul>
+<li>à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²š à²à³à²²à²µà³ à²­à²Ÿà²à²à²³à²šà³à²šà³ à²¹à³à²ž à²­à²Ÿà²·à³à²à²³à²¿à²à³ à²­à²Ÿà²·à²Ÿà²à²€à²°à²¿à²žà²¬à²¹à³à²Šà³
+<li>à²à²à²à³à²²à²¿à²·à³ à²à²à²à²°à³âà²«à³à²žà³âà²šà²²à³à²²à²¿ à²¬à²Šà²²à²Ÿà²µà²£à³à²à²³à²Šà²Ÿà² à²à²à²Ÿà²à²²à³ à²à²°à³à²µ à²à²à²Šà³ à²­à²Ÿà²·à²Ÿà²à²€à²°à²µà²šà³à²šà³ à²šà²µà³à²à²°à²¿à²žà²¬à²¹à³à²Šà³ (à².à²Šà²Ÿ. à²¹à³à²ž à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà³à²²à²­à³à²¯à²à²³à³)
+<li>à²à²à²Ÿà²à²²à³ à²à²°à³à²µ à²­à²Ÿà²·à²Ÿà²à²€à²°à²à²³à²šà³à²šà³ à²€à²¿à²Šà³à²Šà²¬à²¹à³à²Šà³
+</ul>
+à²šà³à²µà³ à²à²à²Šà³à²à²Šà³ à²ªà³à²à²Šà²²à³à²²à³ à²­à²Ÿà²·à²Ÿà²à²€à²°à²®à²Ÿà²¡à²¬à³à²à²Ÿà²Š à²à²à²Šà³ à²ªà²Šà²à³à²à³à²à²µà³à²³à³à²³ à²µà³à²¬à³ à²ªà³à²à²à²³ à²à²à²Šà³ à²žà²°à²£à²¿à²¯à²šà³à²šà³ à²à²Ÿà²£à³à²µà²¿à²°à²¿.
+à²à²à²Šà³à²à²Šà³ à²ªà²Šà²à³à²à³à²à²µà²šà³à²šà³ à²­à²Ÿà²·à²Ÿà²à²€à²°à²à³à²³à²¿à²žà³à²€à³à²€ à²®à³à²à²Šà³ à²žà²Ÿà²à²¿. 
+à²¹à²²à²µà³ à²ªà²Šà²à³à²à³à²à²à²³à³ à²à²à³âà²à²¿à²à²®à³âà²à²²à³ à²žà²à²µà²¿à²­à²Ÿà² à²à²Šà³à²¶à²à²³à²šà³à²šà³à²³à²à³à²à²¡à²¿à²°à³à²€à³à²€à²µà³. à²à²µà²šà³à²šà³ à²­à²Ÿà²·à²Ÿà²à²€à²°à²¿à²žà²²à³ à²ªà³à²°à²¯à²€à³à²šà²¿à²žà²Šà³ à²¹à²Ÿà²à³à²¯à³ à²à²³à²¿à²žà²¿à²à³à²³à³à²³à²¿.
+à²à²à²Šà³ à²ªà²Šà²Š à²¹à²¿à²à²Šà³ à²¹à²Ÿà²à³ à²®à³à²à²Šà³ à²
+à²¡à²¿à²®à²à³à²à²Š à²à²à²Šà³ à²à³à²°à³à²¯à²¿à²Šà³à²Šà²²à³à²²à²¿ (à².à²Šà²Ÿ._textgtisubmit_) à²
+à²Šà²šà³à²šà³ à²­à²Ÿà²·à²Ÿà²à²€à²°à²¿à²žà²à³à²¡à²Šà³ (à²à²µà³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²šà²²à³à²²à²¿à²š
+"à²®à³à²¯à²Ÿà²à³à²°à³" à²¹à³à²žà²°à³à²à²³à²Ÿà²à²¿à²°à³à²€à³à²€à²µà³).
+<p>
+à²šà³à²µà³ à²à²à²Ÿà²à²²à³ à²à²°à³à²µ à²à²à²Šà³ à²­à²Ÿà²·à²Ÿà²à²€à²°à²µà²šà³à²šà³ à²šà²µà³à²à²°à²¿à²žà³à²€à³à²€à²¿à²Šà³à²Šà²°à³ à²à²à²à³à²²à²¿à²·à³ à²à²à²à²°à³âà²«à³à²žà³âà²šà²²à³à²²à²¿ à²¬à²Šà²²à²Ÿà²µà²£à³à²à²³à²Ÿà²Š à²­à²Ÿà²à²à²³à²šà³à²šà²·à³à²à³ 
+à²šà³à²¡à³à²€à³à²€à³à²°à²¿. à²­à²Ÿà²·à²Ÿà²à²€à²°à²Šà²²à³à²²à²¿ à²
+à²µà²¶à³à²¯à²µà²Ÿà²Š à²¬à²Šà²²à²Ÿà²µà²£à³à²à²³à²šà³à²šà³ à²®à²Ÿà²¡à²¿.
+<p>
+à²à²à²Ÿà²à²²à³ à²à²°à³à²µ à²à²à²Šà³ à²­à²Ÿà²·à²Ÿà²à²€à²°à²µà²šà³à²šà³ à²€à²¿à²Šà³à²Šà²²à³ "Correct existing translations" à²žà³à²²à²­à³à²¯à²µà²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¿.
+<p>
+à²ªà³à²°à²€à²¿ à²ªà³à²à²µà³ "_textgtisubmit_" à²à³à²à²¡à²¿à²¯à³à²à²Šà²¿à²à³ à²à³à²šà³à²à³à²³à³à²³à³à²€à³à²€à²Šà³. à²à²Šà²šà³à²šà³ à²à²€à³à²€à²¿à²Šà²Ÿà² nzdl.orgà²Šà²²à³à²²à²¿à²°à³à²µ à²à²à²Šà³ à²ªà³à²°à²€à³à²¯à³à²
+à²žà³à²¥à²Ÿà²ªà²šà³à²¯à²²à³à²²à²¿ à²¬à²Šà²²à²Ÿà²µà²£à³à²à²³à³ à²®à²Ÿà²¡à²²à³à²ªà²¡à³à²€à³à²€à²µà³. à² à²µà³à²¬à³ à²žà³à²à³âà²šà³à²šà³ à²ªà³à²°à²µà³à²¶à²¿à²žà²²à³à²à²Šà³ à²ªà³à²°à²€à²¿ à²ªà³à²à²Šà²²à³à²²à³ à² à²à³à²à²¡à²¿ à²à²Šà²à²¿à²žà²²à²Ÿà²à²¿à²Šà³.}  
+
+_textgtiselecttlc_ [l=kn] {à²Šà²¯à²µà²¿à²à³à²à³ à²šà²¿à²®à³à²® à²­à²Ÿà²·à³à²¯à²šà³à²šà³ à²à²°à²¿à²žà²¿}  
+
+#for status page
+_textgtiviewstatus_ [l=kn] {à²à²²à³à²²à²Ÿ à²­à²Ÿà²·à³à²à²³ à²ªà³à²°à²žà³à²€à³à²€ à²­à²Ÿà²·à²Ÿà²à²€à²° à²žà³à²¥à²¿à²€à²¿à²¯à²šà³à²šà³ à²šà³à²¡à²²à³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿}  
+_textgtiviewstatusbutton_ [l=kn] {à²ªà³à²°à²žà³à²€à³à²€ à²žà³à²¥à²¿à²€à²¿à²¯à²šà³à²šà³ à²šà³à²¡à²¿}  
+_textgtistatustable_ [l=kn] {à²à²²à³à²²à²Ÿ à²­à²Ÿà²·à³à²à²³ à²ªà³à²°à²žà³à²€à³à²€ à²­à²Ÿà²·à²Ÿà²à²€à²° à²žà³à²¥à²¿à²€à²¿à²¯ à²ªà²à³à²à²¿}  
+_textgtilanguage_ [l=kn] {à²­à²Ÿà²·à³}  
+_textgtitotalnumberoftranslations_ [l=kn] {à²­à²Ÿà²·à²Ÿà²à²€à²°à²Š à²®à³à²€à³à²€à²Ÿ à²žà²à²à³à²¯à³}  
+
+_textgtiselecttfk_ [l=kn] {à²Šà²¯à²µà²¿à²à³à²à³ à²à³à²²à²žà²®à²Ÿà²¡à²¬à³à²à³à²à²Šà²¿à²°à³à²µ à²à²¡à²€à²µà²šà³à²šà³ à²à²°à²¿à²žà²¿}  
+
+_textgticoredm_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²à²à²à²°à³âà²«à³à²žà³â (à²à³à²°à³â)}  
+_textgtiauxdm_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²à²à²à²°à³âà²«à³à²žà³â (à²à²à³à²žà²¿à²²à²°à²¿â)}  
+_textgtiglidict_ [l=kn] {à²à²¿à²à²²à³âà² à²šà²¿à²à²à²à³}  
+_textgtiglihelp_ [l=kn] {à²à²¿à²à²²à³âà² à²žà²¹à²Ÿà²¯}  
+_textgtiperlmodules_ [l=kn] {à²ªà²°à³à²²à³â à²à²à²à²à²³à³}  
+_textgtitutorials_ [l=kn] {à²
+à²­à³à²¯à²Ÿà²ž à²ªà²Ÿà² à²à²³à³}  
+_textgtigreenorg_ [l=kn] {Greenstone.org}  
+_textgtigs3interface_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â 3 à²à²à²à²°à³âà²«à³à²žà³â}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà²à²à³à²°à²¹ à²šà²¿à²°à³à²®à²Ÿà²ªà²à²° à²à³à²ªà²¿à²¡à²¿}  
+_textgtiinstallmanual_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà³à²¥à²Ÿà²ªà²¿à²žà³à²µà²µà²° à²à³à²ªà²¿à²¡à²¿}  
+_textgtipapermanual_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²à³à²ªà²¿à²¡à²¿ à²à²Ÿà²à²Šà²Šà²¿à²à²Š à²žà²à²à³à²°à²¹à²à³à²à³ }  
+_textgtiusermanual_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²¬à²³à²à³à²à²Ÿà²°à²° à²à³à²ªà²¿à²¡à²¿}  
+
+_textgtienter_ [l=kn] {à²¬à²°à³à²¯à²¿à²°à²¿}  
+
+_textgticorrectexistingtranslations_ [l=kn] {à²à²à²Ÿà²à²²à³ à²à²°à³à²µ à²­à²Ÿà²·à²Ÿà²à²€à²°à²à²³à²šà³à²šà³ à²žà²°à²¿à²à³à²³à²¿à²žà²¿}  
+_textgtidownloadtargetfile_ [l=kn] {à²à²¡à²€à²µà²šà³à²šà³ à²à³à²³à²à²¿à²³à²¿à²žà³}  
+_textgtiviewtargetfileinaction_ [l=kn] {à² à²à²¡à²€à²µà²šà³à²šà³ à²à²Ÿà²°à³à²¯à²°à³à²ªà²Šà²²à³à²²à²¿ à²šà³à²¡à²¿}  
+_textgtitranslatefileoffline_ [l=kn] {à² à²à²¡à²€à²µà²šà³à²šà³ à²à²«à³âà²²à³à²šà³âà²šà²²à³à²²à²¿ à²­à²Ÿà²·à²Ÿà²à²€à²°à²¿à²žà²¿}  
+
+_textgtinumchunksmatchingquery_ [l=kn] {à²
+à²šà³à² à²ªà² à³à²¯à²­à²Ÿà²à²à²³à³ à²ªà³à²°à²¶à³à²šà³à²¯à²šà³à²šà³ à²¹à³à²à²Šà³à²€à³à²€à²µà³}  
+
+_textgtinumchunkstranslated_ [l=kn] {à²­à²Ÿà²·à²Ÿà²à²€à²°à²à²³à³ à²®à³à²à²¿à²Šà³à²Šà³}  
+_textgtinumchunksrequiringupdating_ [l=kn] {à²à²µà³à²à²³à²²à³à²²à²¿,  _1_ à²à²§à³à²šà³à²à²°à²£ à²¬à³à²à²Ÿà²à²¿à²Šà³}  
+_textgtinumchunksrequiringtranslation_ [l=kn] {à²­à²Ÿà²·à²Ÿà²à²€à²° à²®à²Ÿà²¡à³à²µà³à²Šà³ à²à²³à²¿à²Šà²¿à²Šà³}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=kn] {à²
+à²šà³à² à²­à²Ÿà²·à²Ÿà²à²€à²°à²à²³à³ à²®à³à²à²¿à²Šà³à²Šà³}  
+_textgtinumchunksrequiringupdating2_ [l=kn] {à²
+à²šà³à² à²­à²Ÿà²·à²Ÿà²à²€à²°à²à²³ à²à²§à³à²šà³à²à²°à²£ à²¬à³à²à²Ÿà²à²¿à²Šà³}  
+_textgtinumchunksrequiringtranslation2_ [l=kn] {à²
+à²šà³à² à²­à²Ÿà²·à²Ÿà²à²€à²° à²®à²Ÿà²¡à³à²µà³à²Šà³ à²à²³à²¿à²Šà²¿à²Šà³}  
+
+_textgtienterquery_ [l=kn] {à²šà³à²µà³ à²€à²¿à²Šà³à²Šà³à²ªà²¡à²¿à²žà²¬à³à²à³à²à²Šà²¿à²°à³à²µ à²ªà² à³à²¯ à²­à²Ÿà²à²Šà²¿à²à²Š à²à²à²Šà³ à²ªà²Š à²
+à²¥à²µà²Ÿ à²ªà²Šà²à³à²à³à²à²µà²šà³à²šà³ à²¬à²°à³à²¯à²¿à²°à²¿}  
+_textgtifind_ [l=kn] {à²¹à³à²¡à³à²à³}  
+
+_textgtitranslatingchunk_ [l=kn] {<i>_1_</i> à²ªà² à³à²¯à²­à²Ÿà²à²µà²šà³à²šà³ à²­à²Ÿà²·à²Ÿà²à²€à²°à²¿à²žà²²à²Ÿà²à³à²€à³à²€à²¿à²Šà³ }  
+_textgtiupdatingchunk_ [l=kn] {<i>_1_</i>à²ªà² à³à²¯ à²€à³à²£à³à²à³à²à²³ à²šà²µà³à²à²°à²£}  
+_textgtisubmit_ [l=kn] {à²à²³à²ªà²¡à²¿à²žà³}  
+
+_textgtilastupdated_ [l=kn] {à²à²¡à³à²¯ à²à²§à³à²šà³à²à²°à²£}  
+
+_textgtitranslationfilecomplete_ [l=kn] {à² à²à²¡à²€à²µà²šà³à²šà³ à²šà²µà³à²à²°à²£ à²®à²Ÿà²¡à²¿à²Šà³à²Šà²à³à²à²Ÿà²à²¿ à²šà²¿à²®à²à³ à²µà²à²Šà²šà³à²à²³à³ -- à²à² à²à²Šà³ à²žà²à²ªà³à²°à³à²£à²µà²Ÿà²à²¿à²Šà³!
+<p>à²®à³à²²à²¿à²š à²à³à²à²¡à²¿à²¯à²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¿ à²šà³à²µà³ à² à²à²¡à²€à²Š à²šà²à²²à²šà³à²šà³ à²¡à³à²šà³âà²²à³à²¡à³â à²®à²Ÿà²¡à²¿à²à³à²³à³à²³à²¬à²¹à³à²Šà³, à²®à²€à³à²€à³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà²¿à²š à²®à³à²à²Šà²¿à²š à²¬à²¿à²¡à³à²à²¡à³à²¯à²²à³à²²à²¿ à²à²Šà²šà³à²šà³ à²žà³à²°à²¿à²žà²²à²Ÿà²à³à²€à³à²€à²Šà³}  
+
+_textgtiofflinetranslation_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²šà²¿à²š à²à²«à³âà²²à³à²šà³âà²šà²²à³à²²à²¿ à²®à³à²à³à²°à³à²žà²Ÿà²«à³à²à³â à²à²à³à²žà³à²²à³â à²žà³à²ªà³à²°à³à²¡à³âà²¶à³à²à³â à²à²¡à²€à²µà²šà³à²šà³ à²à²ªà²¯à³à²à²¿à²žà²¿à²à³à²à²¡à³ à²šà³à²µà³ à² à²­à²Ÿà²à²µà²šà³à²šà³ à²­à²Ÿà²·à²Ÿà²à²€à²°à²¿à²žà²¬à²¹à³à²Šà³:
+
+<ol>
+<li>à²à³à²³à²à²¿à²³à²¿à²žà²¿ <a href="_gwcgi_?a=gti&p=excel&tct=work&e=_compressedoptions_">à² à²à²¡à²€à²Š</a> à²®à²¿à²à³à² à²à²²à³à²²à²Ÿ à²à³à²²à²žà²à²³à²¿à²à³, à²
+à²¥à²µà²Ÿ <a href="_gwcgi_?a=gti&p=excel&tct=all&e=_compressedoptions_">à² à²à²¡à²€à²Š</a>à² à²à²à³à²à²Š à²à²²à³à²²à²žà³à²à³à²°à²¿à²à²à³â .
+<li>à²®à³à²à³à²°à³à²žà²Ÿà²«à³à²à³â à²à²à³à²žà³à²²à³âà²šà²²à³à²²à²¿ à²à³à²³à²à²¿à²³à²¿à²žà²²à³à²ªà²à³à² à²à²¡à²€à²µà²šà³à²šà³ à²€à³à²°à³à²¯à²¿à²°à²¿(à²à²«à³à²žà³â 2003/à²à²à³à²žà³âà²ªà²¿ à²
+à²¥à²µà²Ÿ à²à² à²ªà³à²°à²žà³à²€à³à²€à²Šà²²à³à²²à²¿à²°à³à²µ à²µà²°à³à²·à²šà³â à²¬à³à²à²Ÿà²à³à²€à³à²€à²Šà³) à²®à²€à³à²€à³ à²®à³à²à³à²°à³à²žà²Ÿà²«à³à²à³â à²à²à³à²žà³à²²à³â à²µà²°à³à²à²¬à³à²à³â(.xls)à²žà²à²µà²¿à²­à²Ÿà²à²µà²Ÿà²à²¿ à²à²³à²¿à²žà²¿.
+<li>à²à²Šà²à²¿à²žà²¿à²°à³à²µ à²ªà³à²à³à²à²¿à²à³à²¯à²²à³à²²à²¿ à²­à²Ÿà²·à²Ÿà²à²€à²°à²µà²šà³à²šà³ à²¬à²°à³à²¯à²¿à²°à²¿.
+<li>à²šà³à²µà³ à²­à²Ÿà²·à²Ÿà²à²€à²°à²Š à²à²²à³à²²à²Ÿ à²žà³à²à³à²°à²¿à²à²à²šà³à²šà³ à²®à³à²à²¿à²žà²¿à²Š à²®à³à²²à³ <a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_à²à³à²à³ .xls à²à²¡à²€à²µà²šà³à²šà³ à²-à²®à³à²²à³â à²®à²Ÿà²¡à²¿</a>.
+</ol>}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=kn] {à²à³à²°à³à²šà³âà²žà³à²à³à²šà³ à²²à³à²¬à³à²°à³à²°à²¿à²¯à²šà³ à²à²à²à²°à³âà²«à³à²žà³â }  
+_textglihelp_ [l=kn] {<p>à²à²¿ à²à²²à³ à² à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²š à²à²²à³à²² à²à²Ÿà²°à³à²¯ à²žà³à²²à²­à³à²¯à²à²³à²¿à²à³ à²žà³à²²à²­à²µà²Ÿà²Š "à²€à³à²°à³ à²®à²€à³à²€à³ à²à³à²²à²¿à²à³à²à²¿à²žà³" 
+à²à²à²à²°à³âà²«à³à²žà³ à²®à³à²à²Ÿà²à²€à²° à²ªà³à²°à²µà³à²¶ à²à²Šà²à²¿à²žà³à²€à³à²€à²Šà³. à² à²®à³à²²à² à²šà³à²µà³ à²Šà²žà³à²€à²Ÿà²µà³à²à³à²à²³à²šà³à²šà³ à²žà²à²à³à²°à²¹à²¿à²žà²¬à²¹à³à²Šà³, 
+à²®à³à²à²Ÿà²¡à³à²à²Ÿ à²šà²®à³à²Šà²¿à²žà²¬à²¹à³à²Šà³ à²
+à²¥à²µà²Ÿ à²à²®à²Šà³ à²®à²Ÿà²¡à²¿à²à³à²³à³à²³à²¬à²¹à³à²Šà³, à²®à²€à³à²€à³ à²à²µà³à²²à³à²²à²µà²šà³à²šà³ 
+à²à²à²Šà³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â à²žà²à²à³à²°à²¹à²µà²šà³à²šà²Ÿà²à²¿ à²šà²¿à²°à³à²®à²¿à²žà²¬à²¹à³à²Šà³.</p>
+
+<p>à²à²¿ à²à²²à³ à² à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²š à²à³à²€à³à²¯à²²à³à²²à²¿ à²à²ªà²¯à³à²à²¿à²žà²²à³à²ªà²¡à³à²€à³à²€à²Šà³ à²®à²€à³à²€à³ à²
+à²Šà³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³â 
+à²žà³à²¥à²Ÿà²ªà²¿à²€à²µà²Ÿà²à²¿à²°à³à²µ à²¡à³à²°à³à²à³à²à³à²°à²¿à²¯ à²à²à²Šà³ à²à²ª à²¡à³à²°à²à³à²à²°à²¿à²¯à²²à³à²²à²¿ à²žà³à²¥à²Ÿà²ªà²¿à²€à²µà²Ÿà²à²¿à²°à³à²€à³à²€à²Šà³ à²à²à²¬à³à²Šà²šà³à²šà³ à²à²®à²šà²¿à²žà²¿. 
+à²šà³à²µà³ à²à³à²°à³à²šà³âà²žà³à²à³à²šà³âà²šà³à²šà³  à²žà²¿ à²¡à²¿ à²°à³à²®à³âà²šà²¿à²à²Šà²²à³ à²
+à²¥à²µà²Ÿ à²
+à²à²€à²°à³à²à²Ÿà²² à²®à³à²²à² à²µà²¿à²€à²°à²¿à²žà²²à³à²ªà²à³à² à²à²à²Šà³ 
+à²®à³à²²à²Šà²¿à²à²Šà²²à³ à²žà³à²¥à²Ÿà²ªà²¿à²žà²¿à²Šà³à²Šà²°à³ à²¹à³à²à²Ÿà²à²¿à²°à²²à³ à²žà²Ÿà²§à³à²¯</p>
+
+<h4>à²à²¿ à²à²²à³ à²  à²µà²¿à²à²¡à³à²žà³ à²
+à²¡à²¿à²¯à²²à³à²²à²¿ à²à²¡à³à²€à³à²€à²¿à²Šà³</h4>
+
+à²²à³à²¬à³à²°à³à²°à²¿à²¯à²šà³ à²à²à²à²°à³âà²«à³à²žà³â à²
+à²šà³à²šà³ à²µà²¿à²à²¡à³à²žà³ à²
+à²¡à²¿à²¯à²²à³à²²à²¿ à²ªà³à²°à²Ÿà²°à²à²­à²¿à²žà²²à³ <i>Greenstone Digital Library</i> 
+à²¯à²šà³à²šà³ <i>Start</i> à²®à³à²šà³à²µà²¿à²š <i>Programs</i> à²ªà²à³à²à²¿à²¯à²¿à²à²Š à²à²¯à³à²Šà³à²à³à²³à³à²³à²¿ à²®à²€à³à²€à³ 
+<i>Librarian Interface</i>à²šà³à²šà³ à²à³à²²à²¿à²à³à²à²¿à²žà²¿
+<h4>à²à²¿ à²à²²à³ à²  à²¯à³à²šà²¿à²à³à²žà³ à²
+à²¡à²¿à²¯à²²à³à²²à²¿ à²à²¡à³à²€à³à²€à²¿à²Šà³</h4>
+
+à²à²¿ à²à²²à³ à² à²
+à²šà³à²šà³ à²¯à³à²šà²¿à²à³à²žà³ à²
+à²¡à²¿à²¯à²²à³à²²à²¿ à²šà³à²¡à³à²žà²²à³, <i>gli</i> à²¡à³à²°à²à³à²à²°à²¿à²à³ à²¬à²Šà²²à²Ÿà²¯à²¿à²žà²¿ 
+à²®à²€à³à²€à³ <i>gli.sh</i> à²žà³à²à³à²°à²¿à²ªà³à²à³â à²
+à²šà³à²šà³ à²šà³à²¡à³à²žà²¿
+
+<h4>à²à²¿ à²à²²à³ à²  à²®à³à²¯à²Ÿà²à³ à² à²à²žà³ à²
+à²¡à²¿à²¯à²²à³à²²à²¿ à²à²¡à³à²€à³à²€à²¿à²Šà³</h4>
+
+à²®à³à²Šà²²à³ <i>Applications</i> à²®à³à²à²Ÿà²à²€à²° <i>Greenstone</i> à²à³ à²¹à³à²à²¿, à²šà²à²€à²°  
+<i>GLI</i> à²
+à²šà³à²šà³ à²ªà³à²°à²Ÿà²°à²à²­à²¿à²žà²¿}
Index: /gsdl/stable/macros/kazakh.dm
===================================================================
--- /gsdl/stable/macros/kazakh.dm	(revision 20131)
+++ /gsdl/stable/macros/kazakh.dm	(revision 20131)
@@ -0,0 +1,697 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Kazakh Language text and icon macros 
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=kk] {ÐÐ°ÑÐ¿Ð°ÑÓ©Ð·}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=kk] {ÐÐµÑÐµÐº ÐºÓ©Ð·Ñ:}
+_textdate_ [l=kk] {ÐÐ°ÑÐžÑÐ»Ð°ÐœÒÐ°Ðœ ÐŒÐµÑÐ·ÑÐŒÑ:}
+_textnumpages_ [l=kk] {Ð¿Ð°ÑÐ°ÒÑÑÒ£ ÑÐµÑ ÑÐ°ÐœÑ}
+
+_textsignin_ [l=kk] {ÐÐ²ÑÐŸÑÐ»Ð°ÐœÐŽÑÑÑ}
+
+_textdefaultcontent_ [l=kk] {ÐÐµÑÐµÐºÑÑ Ð¿Ð°ÑÐ°Ò ÑÐ°Ð±ÑÐ»ÒÐ°Ðœ Ð¶ÐŸÒ. ÓšÐ·ÑÒ£ÑÐ·ÐŽÑÒ£ Ð±ÑÐ°ÑÐ·ÐµÑÑÐœÑÐ·ÐŽÐµÐ³Ñ "ÐÐµÐ¹ÑÐœ" Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ· ÐœÐµÐŒÐµÑÐµ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÐœÑÐ·ÐŽÑÒ£ Ð±Ð°ÑÑÐ°Ð¿ÒÑ Ð¿Ð°ÑÐ°ÒÑÐœÐ° ÐŸÑÐ°Ð»ÑÒ£ÑÐ·.}
+
+_textdefaulttitle_ [l=kk] {ÐÑÐžÐœÑÑÐŸÑÐœ ÒÐ°ÑÐµÑÑ}
+
+_textbadcollection_ [l=kk] {ÐÒ±Ð» ÐÐžÐœÐ°Ò ("_cvariable _" ÑÐ°ÒÑÑÑÐ±ÑÐœÐŽÐ°ÒÑ)  ÐÑÐžÐœÑÑÐŸÑÐœ ÑÐ°ÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÑÑÐœÐ° ÐŸÑÐœÐ°ÑÑÐ»ÐŒÐ°ÒÐ°Ðœ.}
+
+_textselectpage_ [l=kk] {ÒÐ°Ð¶ÐµÑ Ð¿Ð°ÑÐ°ÒÑÑ ÑÐ°Ò£ÐŽÐ°Ñ'}
+
+_collectionextra_ [l=kk] {ÐÒ±Ð» ÐÐžÐœÐ°Ò _about:numdocs_ ÒÒ±Ð¶Ð°Ñ/ÑÐ°ÑÑÐœ ÒÐ°ÐŒÑÐžÐŽÑ. 
+Ð¡ÐŸÒ£ÒÑ Ó©Ð·Ð³ÐµÑÑÑÑÐµÑ _about:builddate_ ÐºÒ¯Ðœ Ð±Ò±ÑÑÐœ ÐµÐœÐ³ÑÐ·ÑÐ»Ð³ÐµÐœ}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=kk] {<p>ÐÒ±Ð» ÐÐžÐœÐ°Ò _numdocs_ If_("_numdocs_" eq "1", ÒÒ±Ð¶Ð°Ñ, ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÐ°Ðœ) ÑÒ±ÑÐ°ÐŽÑ, Ð±Ð°ÑÐ»ÑÒÑ _numbytes_. 
+<p> ÐÐžÐœÐ°ÒÑÑÒ£ ÒÐ°Ð»ÑÐ¿ÑÐ°ÑÑ Ð¿ÑÐŸÑÐµÑÑÐœÐµÐœ ÐŒÐ°ÒÐ»Ò±ÐŒÐ°Ñ Ð°Ð»Ñ Ò¯ÑÑÐœ <a href="_httppagex_(bsummary)">ÐŒÒ±ÐœÐŽÐ° Ð±Ð°ÑÑÒ£ÑÐ· <\a>.}
+
+_textdescrcollection_ [l=kk] {}
+_textdescrabout_ [l=kk] {ÐÐ°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° ÑÑÑÐ°Ð»Ñ}
+_textdescrhome_ [l=kk] {ÐÐ°ÑÑÐ°Ð¿ÒÑ Ð¿Ð°ÑÐ°Ò}
+_textdescrhelp_ [l=kk] {ÐÓ©ÐŒÐµÐº Ð¿Ð°ÑÐ°ÒÑ}
+_textdescrpref_ [l=kk] {ÐÐºÐµÐŒÐŽÐµÑ}
+_textdescrgreenstone_ [l=kk] {Greenstone ÑÐ»ÐµÐºÑÑÐŸÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÑÑ}
+_textdescrusab_ [l=kk] {ÐÐ°Ð¹ÐŽÐ°Ð»Ð°ÐœÑ Ð±Ð°ÑÑÑÑÐœÐŽÐ° Ð¡ÑÐ·Ð³Ðµ ÐœÐµ ÒÐžÑÐœÐŽÑÒ ÑÑÒÑÐ·ÐŽÑ?}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=kk] {ÐÐŸÐžÑÐº}  
+_labelSearch_ [l=kk] {ÐÐ·ÐŽÐµÑ}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=kk] {ÐÐ°ÐžÐŒÐµÐœÐŸÐ²Ð°ÐœÐžÐµ}  
+_labelTitle_ [l=kk] {ÐÑÐ°ÑÐ»Ð°Ñ Ð-Ð¯}
+_textCreator_ [l=kk] {Ð¡ÐŸÐ·ÐŽÐ°ÑÐµÐ»Ñ}  
+_labelCreator_ [l=kk] {ÐÐ²ÑÐŸÑÐ»Ð°Ñ Ð-Ð¯}
+_textSubject_ [l=kk] {Ð¢ÐµÐŒÐ°}  
+_labelSubject_ [l=kk] {ÐÓ©ÑÑÐµÑÐºÑÑÑÐµÑ}
+_textDescription_ [l=kk] {ÐÐ¿ÐžÑÐ°ÐœÐžÐµ}  
+_labelDescription_ [l=kk] {Ð¡ÐžÐ¿Ð°ÑÑÐ°ÐŒÐ°Ð»Ð°Ñ}
+_textPublisher_ [l=kk] {ÐÐ·ÐŽÐ°ÑÐµÐ»Ñ}  
+_labelPublisher_ [l=kk] {ÐÐ°ÑÐ¿Ð°Ð»Ð°Ñ}
+_textContributor_ [l=kk] {ÐÐºÐ»Ð°ÐŽÑÐžÐº}  
+_labelContributor_ [l=kk] {Ò®Ð»ÐµÑ ÒÐŸÑÒÐ°ÐœÐŽÐ°Ñ}
+_textDate_ [l=kk] {ÐÐ°ÑÐ°}  
+_labelDate_ [l=kk] {ÐÐµÑÐ·ÑÐŒÐŽÐµÑÑ}
+_textType_ [l=kk] {Ð¢ÐžÐ¿}  
+_labelType_ [l=kk] {Ð¢Ò¯ÑÐ»ÐµÑÑ}
+_textFormat_ [l=kk] {Ð€ÐŸÑÐŒÐ°Ñ}  
+_labelFormat_ [l=kk] {Ð€ÐŸÑÐŒÐ°ÑÑÐ°Ñ}
+_textIdentifier_ [l=kk] {ÐÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑ}  
+_labelIdentifier_ [l=kk] {ÐÑÐµÐºÑÐµ Ð±ÐµÐ»Ð³ÑÐ»ÐµÑÑ}
+_textSource_ [l=kk] {ÐÐŒÑ ÑÐ°Ð¹Ð»Ð°}  
+_labelSource_ [l=kk] {Ð€Ð°Ð¹Ð» Ð°ÑÑÐ°ÑÑ}
+_textLanguage_ [l=kk] {Ð¯Ð·ÑÐº}  
+_labelLanguage_ [l=kk] {Ð¢ÑÐ»ÐŽÐµÑ}
+_textRelation_ [l=kk] {ÐÑÐœÐŸÑÐµÐœÐžÐµ}  
+_labelRelation_ [l=kk] {ÐÐ°Ð¹Ð»Ð°ÐœÑÑÑÐ°Ñ}
+_textCoverage_ [l=kk] {ÐÐŸÐºÑÑÑÐžÐµ}  
+_labelCoverage_ [l=kk] {ÒÐ°ÐŒÑÑÐ»Ñ Ð°ÑÑÑ}
+_textRights_ [l=kk] {ÐÑÐ°Ð²Ð°}  
+_labelRights_ [l=kk] {ÒÒ±ÒÑÒÑÐ°Ñ}
+
+# DLS metadata set
+_textOrganization_ [l=kk] {Ò°Ð¹ÑÐŒÐŽÐ°Ñ}  
+_labelOrganization_ [l=kk] {Ò°Ð¹ÑÐŒÐŽÐ°Ñ}  
+_textKeyword_ [l=kk] {ÐÐ»ÑÑÐµÐ²ÐŸÐµ ÑÐ»ÐŸÐ²ÐŸ}  
+_labelKeyword_ [l=kk] {Ð¢Ò¯Ð¹ÑÐœ ÑÓ©Ð·ÐŽÐµÑ}
+_textHowto_ [l=kk] {ÒÐ°Ð»Ð°Ð¹}  
+_labelHowto_ [l=kk] {ÒÐ°Ð»Ð°Ð¹}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=kk] {Ð€ÑÐ°Ð·Ð°}  
+_labelPhrase_ [l=kk] {Ð€ÑÐ°Ð·Ð°Ð»Ð°Ñ}
+_textCollage_ [l=kk] {ÐÐŸÐ»Ð»Ð°Ð¶}  
+_labelCollage_ [l=kk] {ÐÐŸÐ»Ð»Ð°Ð¶}
+_textBrowse_ [l=kk] {ÐÑÐŸÑÐŒÐŸÑÑ}  
+_labelBrowse_ [l=kk] {ÐÑÐŸÑÐŒÐŸÑÑ}  
+_textTo_ [l=kk] {ÐÐŸÐŒÑ}  
+_labelTo_ [l=kk] {ÐÑÐŒÐ³Ðµ}
+_textFrom_ [l=kk] {ÐÑ}  
+_labelFrom_ [l=kk] {ÐÑÐŒÐœÐµÐœ}
+_textAcronym_ [l=kk] {Ð¡ÐŸÐºÑÐ°ÑÐµÐœÐžÐµ}  
+_labelAcronym_ [l=kk] {ÐÐºÑÐŸÐœÐžÐŒÐŽÐµÑ}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=kk] {ÐÑÐŸÑÐŒÐŸÑÑ Ð¿ÐŸ _1_}  
+
+_textdescrSearch_ [l=kk] {ÐÐ·ÐŽÐµÑ}
+_textdescrType_ [l=kk] {Ð ÐµÑÑÑÑ ÑÒ¯ÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÒÐ°ÑÐ°Ñ}
+_textdescrIdentifier_ [l=kk] {Ð ÐµÑÑÑÑ ÐµÑÐµÐºÑÐµ Ð±ÐµÐ»Ð³ÑÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÒÐ°ÑÐ°Ñ}
+_textdescrSource_ [l=kk] {Ð€Ð°Ð¹Ð»ÐŽÑÒ£ ÑÒ¯Ð¿ÐœÒ±ÑÒÐ° Ð°ÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÒÐ°ÑÐ°Ñ}
+_textdescrTo_ [l=kk] {ÐÐµÐºÐµÐœÐ¶Ð°Ð¹Ð»Ð°Ñ Ð±ÐŸÐ¹ÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÒ±ÐœÑ}
+_textdescrFrom_ [l=kk] {ÐÑÐ±ÐµÑÑÑÑÐ»ÐµÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÒ±ÐœÑ}
+_textdescrCollage_ [l=kk] {ÐÐµÐ¹ÐœÐµÐ»ÐµÑ ÐºÐŸÐ»Ð»Ð°Ð¶ÐŽÐ°ÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÒÐ°ÑÐ°Ñ}
+_textdescrAcronym_ [l=kk] {ÐÐºÑÐŸÐœÐžÐŒÐŽÐµÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÒ±ÐœÑ}
+_textdescrPhrase_ [l=kk] {Ð€ÑÐ°Ð·Ð°Ð»Ð°Ñ Ð±ÐŸÐ¹ÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÒ±ÐœÑ}
+_textdescrHowto_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÐ»Ñ ÑÓÑÑÐ»Ñ Ð±ÐŸÐ¹ÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÒ±ÐœÑ}
+_textdescrBrowse_ [l=kk] {ÒÐ°ÑÐ°Ñ}
+_texticontext_ [l=kk] {ÒÒ±Ð¶Ð°ÑÑÑ ÒÐ°ÑÐ°Ñ}
+_texticonclosedbook_ [l=kk] {ÒÒ±Ð¶Ð°ÑÑÑ Ð°ÑÑÐ¿ ÐŒÐ°Ð·ÐŒÒ±ÐœÑÐœ ÒÐ°ÑÐ°Ñ}
+_texticonnext_ [l=kk] {ÐÐµÐ»ÐµÑÑ}
+_texticonprev_ [l=kk] {ÐÐ»ÐŽÑÒ£ÒÑÑÑ}
+
+_texticonworld_ [l=kk] {ÐÐŸÐºÐ°Ð· Ð²ÐµÐ± ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°}  
+
+_texticonmidi_ [l=kk] {MIDI ÒÒ±Ð¶Ð°ÑÑÐœ ÒÐ°ÑÐ°Ñ}
+_texticonmsword_ [l=kk] {Microsoft Word ÒÒ±Ð¶Ð°ÑÑÐœ ÒÐ°ÑÐ°Ñ}
+_texticonmp3_ [l=kk] {MP3 ÒÒ±Ð¶Ð°ÑÑÐœ ÒÐ°ÑÐ°Ñ}
+_texticonpdf_ [l=kk] {PDF ÒÒ±Ð¶Ð°ÑÑÐœ ÒÐ°ÑÐ°Ñ}
+_texticonps_ [l=kk] {PS ÒÒ±Ð¶Ð°ÑÑÐœ ÒÐ°ÑÐ°Ñ}
+_texticonppt_ [l=kk] {PPT  ÒÒ±Ð¶Ð°ÑÑÐœ ÒÐ°ÑÐ°Ñ}
+_texticonrtf_ [l=kk] {RTF ÒÒ±Ð¶Ð°ÑÑÐœ ÒÐ°ÑÐ°Ñ}
+_texticonxls_ [l=kk] {XLS ÒÒ±Ð¶Ð°ÑÑÐœ ÒÐ°ÑÐ°Ñ}
+
+_page_ [l=kk] {ÐÐ°ÑÐ°Ò}
+_pages_ [l=kk] {ÐÐ°ÑÐ°ÒÑÐ°Ñ}
+_of_ [l=kk] {ÐÑÐ°ÑÑÐœÐ°Ðœ}
+_vol_ [l=kk] {Ð¢ÐŸÐŒ}
+_num_ [l=kk] {ÐÓ©ÐŒÑÑÑ}
+
+_textmonth00_ [l=kk] {}
+_textmonth01_ [l=kk] {ÒÐ°Ò£ÑÐ°Ñ}
+_textmonth02_ [l=kk] {ÐÒÐ¿Ð°Ðœ}
+_textmonth03_ [l=kk] {ÐÐ°ÑÑÑÐ·}
+_textmonth04_ [l=kk] {Ð¡ÓÑÑÑ}
+_textmonth05_ [l=kk] {ÐÐ°ÐŒÑÑ}
+_textmonth06_ [l=kk] {ÐÐ°ÑÑÑÐŒ}
+_textmonth07_ [l=kk] {ÐšÑÐ»ÐŽÐµ}
+_textmonth08_ [l=kk] {Ð¢Ð°ÐŒÑÐ·}
+_textmonth09_ [l=kk] {ÒÑÑÐºÒ¯Ð¹ÐµÐº}
+_textmonth10_ [l=kk] {ÒÐ°Ð·Ð°Ðœ}
+_textmonth11_ [l=kk] {ÒÐ°ÑÐ°ÑÐ°}
+_textmonth12_ [l=kk] {ÐÐµÐ»ÑÐŸÒÑÐ°Ðœ}
+
+_textdocument_ [l=kk] {ÒÒ±Ð¶Ð°Ñ}
+_textsection_ [l=kk] {Ð¡ÐµÐºÑÐžÑ}
+_textparagraph_ [l=kk] {ÐÐ±Ð·Ð°Ñ}
+
+_magazines_ [l=kk] {ÐÑÑÐœÐ°Ð»ÐŽÐ°Ñ}
+
+_nzdlpagefooter_ [l=kk] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">Ð¡Ð°ÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÐœÑÒ£ ÐÐ°Ò£Ð°Ð·ÐµÐ»Ð°ÐœÐŽÐžÑÐ»ÑÒ Ð¶ÐŸÐ±Ð°ÑÑ</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">ÐÐŸÐŒÐ¿ÑÑÑÐµÑÐ»ÑÐº ÒÑÐ»ÑÐŒÐŽÐ°ÑÐŽÑÒ£ Ð±Ó©Ð»ÑÐŒÑ</a>, 
+<a href="http://www.waikato.ac.nz">ÐÐ°Ð¹ÐºÐ°ÑÐŸ Ð£ÐœÐžÐ²ÐµÑÑÐžÑÐµÑÑ</a>, 
+ÐÐ°Ò£Ð° ÐÐµÐ»Ð°ÐœÐŽÐžÑ}
+
+_linktextHOME_ [l=kk] {ÐÐÐ¡Ð«}
+_linktextHELP_ [l=kk] {ÐÓšÐÐÐ}
+_linktextPREFERENCES_ [l=kk] {ÐÐÐÐÐÐÐ£}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=kk] {Greenstone ÑÐ°ÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÑÑ}
+
+
+
+_textadmin_ [l=kk] {ÐÐŽÐŒÐžÐœÐžÑÑÑÐ°ÑÐžÐ²ÑÑÐº Ð¿Ð°ÑÐ°Ò}
+_textabgs_ [l=kk] {Greenstone ÑÑÑÐ°Ð»Ñ}
+_textgsdocs_ [l=kk] {Greenstone ÒÒ±Ð¶Ð°ÑÑÐ°ÐŒÐ°ÑÑ}
+
+_textdescradmin_ [l=kk] {ÐÐ°Ò£Ð° ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ»Ð°ÑÐŽÑ ÒÐ°ÑÐ°ÑÒÐ° ÒÐŸÑÑÒÐ°, ÐÐžÐœÐ°ÒÑÐ°ÑÐŽÑ Ð¶Ò¯Ð¹ÐµÐ³Ðµ Ð±ÑÑÑÐºÑÐµÑÐ³Ðµ, Greenstone-ÐœÑÒ£ ÐŸÑÐœÐ°ÑÑÐ»ÑÑÐœÐ° ÒÐ°ÑÑÑÑÑ ÑÐµÑ
+ÐœÐžÐºÐ°Ð»ÑÒ Ð°ÒÐ¿Ð°ÑÐ°ÑÑÑ Ð°Ð»ÑÒÐ° ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐº Ð±ÐµÑÐµÐŽÑ.}
+
+_textdescrgogreenstone_ [l=kk] {Greenstone Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° Ð¶Ð°Ð±ÐŽÑÒÑ Ð¶ÓÐœÐµ  ÐÐ°Ò£Ð°Ð·ÐµÐ»Ð°ÐœÐŽÐžÑ Ð¡Ð°ÐœÐŽÑÒ ÐÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ° Ð¶ÐŸÐ±Ð°ÑÑ ÑÑÑÐ°Ð»Ñ ÓÒ£Ð³ÑÐŒÐµÐ»ÐµÐ¹ÐŽÑ.}
+
+_textdescrgodocs_ [l=kk] {Greenstone ÐœÒ±ÑÒÐ°ÑÑ}
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=kk] {ÐÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°Ð»ÑÒ ÐžÐœÑÐµÑÑÐµÐ¹Ñ}
+_textdescrgli_ [l=kk] {ÐÐ°Ò£Ð° ÐÐžÐœÐ°ÒÑÑ Ð¶Ð°ÑÐ°Ñ, Ó©Ð·Ð³ÐµÑÑÑ, ÑÐŸÐ»ÑÒÑÑÑÑ ÐœÐµÐŒÐµÑÐµ Ð¶ÐŸÑÑÐœÐ° ÐºÓ©ÐŒÐµÐº}
+
+package collector
+
+_textcollector_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ}
+_textdescrcollector_ [l=kk] {ÐÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°Ð»ÑÒ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑÐµÐœ Ð±Ò±ÑÑÐœ ÒÒ±ÑÑÐ»ÒÐ°ÐœÐŽÑÒÑÐ°Ðœ, ÐºÓ©Ð¿ÑÐµÐ³ÐµÐœ Ð°ÒÑÐŒÐŽÐ°ÒÑ ÐŒÐ°ÒÑÐ°ÑÑÐ°Ñ Ò¯ÑÑÐœ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°Ð»ÑÒ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑÑ ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ ÐŸÑÐœÑÐœÐ° Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑ Ð¶Ó©Ðœ.}
+
+package depositor
+
+_textdepositor_ [l=kk] {ÐÐµÐ¿ÐŸÐ·ÐžÑÐŸÑ}  
+_textdescrdepositor_ [l=kk] {ÐÐŸÐŒÐŸÐ³Ð°ÐµÑ ÐÐ°ÐŒ ÐŽÐŸÐ±Ð°Ð²ÐžÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ðº ÑÑÑÐµÑÑÐ²ÑÑÑÐžÐŒ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŒ}  
+
+package gti
+
+_textgti_ [l=kk] {ÐÐœÑÐµÑÑÐµÐ¹Ñ ÐÐµÑÐµÐ²ÐŸÐŽÑÐžÐºÐ° ÐÑÐžÐœÑÑÐŸÑÐœ}  
+_textdescrtranslator_ [l=kk] {Greenstone ÐžÐœÑÐµÑÑÐµÐ¹ÑÑÐœÑÒ£ ÒÐ°Ð·ÑÑÐ³Ñ  ÐºÓ©Ð¿ÑÑÐ»ÐŽÑ ÐœÒ±ÑÒÐ°Ð»Ð°ÑÑÐœ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÒÐ° ÐºÓ©ÐŒÐµÐºÑÐµÑÐµÐŽÑ}
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=kk] {ÐÐžÐœÐ°Ò ÑÑÑÐ°Ð»Ñ ÐŒÓÐ»ÑÐŒÐµÑ}
+
+_textsubcols1_ [l=kk] {<p>ÐÒ±Ð» ÐÐžÐœÐ°Ò _1_ ÑÑÐºÑ Ð¶ÐžÐœÐ°ÒÑÐ°ÑÐŽÑ ÑÐŸÐ¿ÑÐ°ÑÑÑÑÒÐ°Ðœ <blockquote>}
+
+_textsubcols2_ [l=kk] {</blockquote>
+Ð¡ÑÐ· "ÐÐºÐµÐŒÐŽÐµÑ" Ð¿Ð°ÑÐ°ÒÑÐœÐŽÐ° ÒÐ°Ð·ÑÑ ÒÐŸÐ»ÐŽÐ°ÐœÑÐ»ÑÐ¿ ÐŸÑÑÑÒÐ°Ðœ ÑÑÐºÑ Ð¶ÐžÐœÐ°ÒÑÐ°ÑÐŽÑÐœ ÑÑÐ·ÑÐŒÑÐœ ÒÐ°ÑÐ°Ð¿/Ó©Ð·Ð³ÐµÑÑÐµ Ð°Ð»Ð°ÑÑÐ·.}
+
+_titleabout_ [l=kk] {ÑÐžÐ¿Ð°ÑÑÐ°ÐŒÐ°}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=kk] {ÐÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ° Ð±Ó©Ð»ÑÐŒÑÐœ Ð¶Ð°Ð±Ñ.}
+_texticonclosedbookshelf_ [l=kk] {ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ° ÑÐµÐºÑÐžÑÑÑÐœ Ð°ÑÑ Ð¶ÓÐœÐµ ÐŒÐ°Ð·ÐŒÒ±ÐœÑÐœ ÒÐ°ÑÐ°Ñ}
+_texticonopenbook_ [l=kk] {ÐÑÑÐ°Ð¿ÑÑ Ð¶Ð°Ð±Ñ}
+_texticonclosedfolder_ [l=kk] {ÐÐ°Ð¿ÐºÐ°ÐœÑ Ð°ÑÑ Ð¶ÓÐœÐµ ÐŒÐ°Ð·ÐŒÒ±ÐœÑÐœ ÒÐ°ÑÐ°Ñ}
+_texticonclosedfolder2_ [l=kk] {Ð±Ó©Ð»ÑÐŒÑÐµÐœÑ Ð°ÑÑ}
+_texticonopenfolder_ [l=kk] {ÐÐ°Ð¿ÐºÐ°ÐœÑ Ð¶Ð°Ð±Ñ}
+_texticonopenfolder2_ [l=kk] {Ð±Ó©Ð»ÑÐŒÑÐµÐœÑ Ð¶Ð°Ð±Ñ.}
+_texticonsmalltext_ [l=kk] {ÐŒÓÑÑÐœ Ð±Ó©Ð»ÑÐŒÑÐœ ÒÐ°ÑÐ°Ñ}
+_texticonsmalltext2_ [l=kk] {ÐŒÓÑÑÐœÐŽÑ ÒÐ°ÑÐ°Ñ}
+_texticonpointer_ [l=kk] {ÐÒÑÐŒÐŽÐ°ÒÑ Ð±Ó©Ð»ÑÐŒ}
+_texticondetach_ [l=kk] {ÐÐ°Ò£Ð° ÑÐµÑÐµÐ·ÐµÐŽÐµ Ð¿Ð°ÑÐ°Ò Ð°ÑÑ}
+_texticonhighlight_ [l=kk] {ÑÐ·ÐŽÐµÐ³ÐµÐœ ÑÐµÑÐŒÐžÐœÐŽÐµÑÐŽÑ Ð±Ð°ÑÐ° ÐºÓ©ÑÑÐµÑÑ}
+_texticonnohighlight_ [l=kk] {ÑÐ·ÐŽÐµÐ³ÐµÐœ ÑÐµÑÐŒÐžÐœÐŽÑ Ð±Ð°ÑÐ° ÐºÓ©ÑÑÐµÑÐ¿ÐµÑ}
+_texticoncontracttoc_ [l=kk] {ÐÐ°Ð·ÐŒÒ±ÐœÑÐœ Ð¶ÐžÑÑÑ}
+_texticonexpandtoc_ [l=kk] {ÐÐ°Ð·ÐŒÒ±ÐœÑÐœ ÐºÐµÒ£ÑÐœÐµÐœ ÐºÓ©ÑÑÐµÑÑ}
+_texticonexpandtext_ [l=kk] {ÐÐ°ÑÐ»ÑÒ ÐŒÓÑÑÐœÐŽÑ ÐºÓ©ÑÑÐµÑÑ}
+_texticoncontracttext_ [l=kk] {ÑÐµÐº Ð±Ð°ÑÐ° Ð°Ð¹ÒÑÐœÐŽÐ°Ð»ÒÐ°Ðœ ÑÐµÐºÑÐžÑÐ»Ð°ÑÒÐ° ÐŒÓÑÑÐœÐŽÑ ÐºÓ©ÑÑÐµÑÑ}
+_texticonwarning_ [l=kk] {<b>ÐÐ°Ð·Ð°Ñ Ð°ÑÐŽÐ°ÑÑÒ£ÑÐ·: </b>}
+_texticoncont_ [l=kk] {Ð¶Ð°Ð»ÒÐ°ÑÑÑÑÐ°Ð¹ÑÐœ Ð±Ð°?}
+
+_textltwarning_ [l=kk] {<div class="buttons">_imagecont_</div>
+_iconwarning_ ÐÐ°ÑÐ»ÑÒ ÐŒÓÑÑÐœÐŽÑ Ð±ÐµÐ¹ÐœÐµÐ»ÐµÑ Ð±ÑÐ°ÑÐ·ÐµÑÑÐœÐŽÐµ Ð±ÐµÐ¹ÐœÐµÐ»ÐµÐœÐµÑÑÐœ Ð°ÒÐ¿Ð°ÑÐ°ÑÑÐ°ÑÐŽÑÒ£ ÐºÓ©Ð±ÐµÑÑÐœÐµ ÓÐºÐµÐ»ÑÐ¿ ÑÐŸÒÐ°ÐŽÑ.}
+
+_textgoto_ [l=kk] {Ð¿Ð°ÑÐ°ÒÒÐ° ÐºÓ©ÑÑ}
+_textintro_ [l=kk] {<i>(ÐºÑÑÑÑÐ¿Ðµ)</i>}
+
+_textCONTINUE_ [l=kk] {ÐÐÐÒÐÐ¡Ð¢Ð«Ð ÐÐÐ«Ð ÐÐ?}
+
+_textEXPANDTEXT_ [l=kk] {ÐÐÐ ÐÐ«Ò\nÐÓÐ¢ÐÐ}
+
+_textCONTRACTCONTENTS_ [l=kk] {ÐÐÐÐÒ°ÐÐÐ«\nÐÐÐ«Ð Ð£}
+
+_textDETACH_ [l=kk] {ÐÐÒ¢Ð\nÐ¢ÐÐ ÐÐÐ}
+
+_textEXPANDCONTENTS_ [l=kk] {ÐÐÐÐÒ°ÐÐÐ«\nÐ¶Ð°Ñ}
+
+_textCONTRACT_ [l=kk] {ÐÓÐ¢ÐÐÐÐ\nÐÐÐ«Ð Ð£}
+
+_textHIGHLIGHT_ [l=kk] {ÐÐÐ¡Ð\nÐÓšÐ Ð¡ÐÐ¢Ð£}
+
+_textNOHIGHLIGHT_ [l=kk] {ÐÐÐ¡Ð ÐÓšÐ Ð¡ÐÐ¢Ð£ÐÐ\nÐÐÐ«Ð Ð¢ÐÐ¡Ð¢ÐÐ£}
+
+_textPRINT_ [l=kk] {ÐÐÐ§ÐÐ¢Ð¬}  
+
+_textnextsearchresult_ [l=kk] {Ð¡Ð»ÐµÐŽÑÑÑÐžÐ¹ Ð¿ÐŸÑÐžÐºÐŸÐ²ÑÐ¹ ÑÐµÐ·ÑÐ»ÑÑÐ°Ñ}  
+_textprevsearchresult_ [l=kk] {ÐÑÐµÐŽÑÐŽÑÑÐžÐ¹ Ð¿ÐŸÐžÑÐºÐŸÐ²ÑÐ¹ ÑÐµÐ·ÑÐ»ÑÑÐ°Ñ}  
+
+# macros for printing page
+_textreturnoriginal_ [l=kk] {ÐÐµÑÐœÑÑÑÑÑ ÐœÐ° ÑÑÑÐ°ÐœÐžÑÑ}  
+_textprintpage_ [l=kk] {ÐÐµÑÐ°ÑÐ°ÑÑ ÐŽÐ°ÐœÐœÑÑ ÑÑÑÐ°ÐœÐžÑÑ}  
+_textshowcontents_ [l=kk] {ÐÐŸÐºÐ°Ð·Ð°ÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ}  
+_texthidecontents_ [l=kk] {Ð¡ÐºÑÑÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=kk] {_If_(_thislast_, _cgiargq_ ÑÒ±ÑÐ°ÐœÑÐŒ Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÐ·ÐŽÐµÑÐŽÑÒ£ ÐœÓÑÐžÐ¶ÐµÐ»ÐµÑÑ: _thisfirst_ - _thislast_ , ÑÒ±ÑÐ°ÐœÑÐŒ Ð±ÐŸÐ¹ÑÐœÑÐ°: _cgiargq_ ÐµÑÑÐµÒ£Ðµ ÑÐ°Ð±ÑÐ»ÒÐ°Ðœ Ð¶ÐŸÒ)}
+_textnoquerytitle_ [l=kk] {ÐÐ·ÐŽÐµÑ Ð¿Ð°ÑÐ°ÒÑ}
+
+_textsome_ [l=kk] {ÐºÐµÐ¹Ð±ÑÑ}
+_textall_ [l=kk] {Ð±Ð°ÑÐ»ÑÒÑ}
+_textboolean_ [l=kk] {Ð»ÐŸÐ³ÐžÐºÐ°Ð»ÑÒ}
+_textranked_ [l=kk] {Ð ÐµÑÑÐµÐ»Ð³ÐµÐœ}
+_textnatural_ [l=kk] {ÐºÓÐŽÑÐŒÐ³Ñ}
+
+_texticonsearchhistorybar_ [l=kk] {ÐÐ·ÐŽÐµÑ ÑÐ°ÑÐžÑ
+Ñ}
+
+_textifeellucky_ [l=kk] {ÐÐµÐœ Ð¶ÐµÒ£ÑÑÑÑ ÑÐµÐ·ÑÐŽÐµÐŒÑÐœ!}
+
+#alt text for query buttons
+_textusequery_ [l=kk] {ÐÑÑ ÑÒ±ÑÐ°ÐœÑÐŒÐŽÑ ÒÐŸÐ»ÐŽÐ°ÐœÑ}
+_textfreqmsg1_ [l=kk] {ÐÐµÐ·ÐŽÐµÑÑ ÑÐ°ÐœÑ:}
+_textpostprocess_ [l=kk] {_If_(_quotedquery_,<br><i> _quotedquery_ ÑÐ·ÐŽÐµÑ Ò¯ÑÑÐœ Ó©Ò£ÐŽÐµÐ»ÐŽÑ</i>)}
+_textinvalidquery_ [l=kk] {Ð¡Ò±ÑÐ°Ò ÑÐžÐœÑÐ°ÐºÑÐžÑÑ ÒÐ°ÑÐµ}
+
+
+
+_textmorethan_ [l=kk] {ÐºÓ©Ð±ÑÑÐµÐº, ÐœÐµÒÒ±ÑÐ»ÑÐŒ}
+_textapprox_ [l=kk] {Ð¢Ó©Ò£ÑÑÐµÐ³ÑÐœÐŽÐµ}
+_textnodocs_ [l=kk] {Ð¡Ò±ÑÐ°ÐœÑÐŒÐŽÑ ÒÐ°ÐœÐ°ÒÐ°ÑÑÐ°ÐœÐŽÑÑÐ°ÑÑÐœ ÒÒ±Ð¶Ð°ÑÑÐ°Ñ ÑÐ°Ð±ÑÐ»ÐŒÐ°ÐŽÑ}
+_text1doc_ [l=kk] {1 ÒÒ±Ð¶Ð°Ñ ÑÒ±ÑÐ°ÐœÑÐŒÐŽÑ ÒÐ°ÐœÐ°ÒÐ°ÑÑÐ°ÐœÐŽÑÑÐ°ÐŽÑ.}
+_textlotsdocs_ [l=kk] {ÒÒ±Ð¶Ð°ÑÑÐ°Ñ, ÑÒ±ÑÐ°ÐœÑÐŒÐŽÑ ÒÐ°ÐœÐ°ÒÐ°ÑÑÐ°ÐœÐŽÑÑÐ°ÑÑÐœ.}
+_textmatches_ [l=kk] {ÐÓÑÐžÐ¶ÐµÐ»ÐµÑ}
+_textbeginsearch_ [l=kk] {ÐÐ·ÐŽÐµÑÐŽÑ Ð±Ð°ÑÑÐ°Ñ}
+_textrunquery_ [l=kk] {Ð¡Ò±ÑÐ°ÐœÑÐŒÐŽÑ ÐŸÑÑÐœÐŽÐ°Ñ}
+_textclearform_ [l=kk] {Ð€ÐŸÑÐŒÐ°ÐœÑ Ð±ÐŸÑÐ°ÑÑ}
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=kk] {Ð¡Ó©Ð· ÐœÐµÐŒÐµÑÐµ ÑÑÐ°Ð·Ð°}
+_textinfield_ [l=kk] {... Ð°Ð»Ð°Ò£ÑÐ°ÐŽÐ°}
+_textfoldstem_ [l=kk] {(ÑÓ©Ð·, ÑÑÐ°Ð·Ð°)}
+
+_textadvquery_ [l=kk] {ÐœÐµÐŒÐµÑÐµ ÑÒ±ÑÐ°ÐœÑÐŒ ÐŒÓÑÑÐœÑÐœ ÐµÐœÐ³ÑÐ·ÑÒ£ÑÐ·:}
+_textallfields_ [l=kk] {Ð±Ð°ÑÐ»ÑÒ Ð°Ð»Ð°Ò£ÑÐ°ÑÑ}
+_texttextonly_ [l=kk] {ÑÐµÐº ÐŒÓÑÑÐœ}
+_textand_ [l=kk] {Ð¶ÓÐœÐµ}
+_textor_ [l=kk] {ÐœÐµÐŒÐµÑÐµ}
+_textandnot_ [l=kk] {Ð¶ÓÐœÐµ ÐµÐŒÐµÑ}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=kk] {_indexselection_ _If_(_jselection_, of _jselection_) _If_(_gselection_, _gselection_ ÐŽÐµÒ£Ð³ÐµÐ¹ÑÐœÐŽÐµ) _If_(_nselection_, _nselection_ ÑÑÐ»ÑÐœÐŽÐµ) Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÐ·ÐŽÐµÑ, _querytypeselection_ ÑÓ©Ð·ÐŽÐµÑÐŽÐµÐœ ÑÒ±ÑÐ°ÑÑÐœ}
+
+_textadvancedsearch_ [l=kk] {_indexselection_ _If_(_jselection_, of _jselection_) _If_(_gselection_, _gselection_ ÐŽÐµÒ£Ð³ÐµÐ¹ÐŽÐµ)_If_(_nselection_, _nselection_ ÑÑÐ»ÑÐœÐŽÐµ) ÑÐ·ÐŽÐµÑ, _querytypeselection_ ÑÒ±ÑÐ°ÐœÑÐŒÐŽÑ ÒÐŸÐ»ÐŽÐ°ÐœÑÐ¿}
+
+
+
+
+
+_textformsimplesearch_ [l=kk] {_If_(_jselection_, _jselection_) _If_(_gformselection_,  _gformselection_ ÐŽÐµÒ£Ð³ÐµÐ¹ÐŽÐµ) _If_(_nselection_, _nselection_ ÑÑÐ»ÑÐœÐŽÐµ) Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÐ·ÐŽÐµÑ, _formquerytypesimpleselection_ Ð±Ð°Ñ Ð¶ÐµÑÑÐœÐŽÐµ}
+
+
+
+
+
+_textnojsformwarning_ [l=kk] {ÐÑÐºÐµÑÑÑ: Ð¡ÑÐ·ÐŽÑÒ£ Ð²ÐµÐ±-Ð±ÑÐ°ÑÐ·ÐµÑÑÒ£ÑÐ·ÐŽÐµ Javascript Ð·Ð°ÒÑÐŒÐŽÐ°ÐœÒÐ°Ðœ. <br>ÐÐ·ÐŽÐµÑ ÑÐŸÑÐŒÐ°ÑÑÐœ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑ Ò¯ÑÑÐœ Ð±Ò±ÒÐ°Ðœ ÑÒ±ÒÑÐ°Ñ ÒÐ°Ð¶ÐµÑ.}
+_textdatesearch_ [l=kk] {ÐÒ±Ð» ÐÐžÐœÐ°ÒÑÐ° ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ Ð°ÐœÑÒÑÐ°Ð»ÒÐ°Ðœ ÐŒÐµÑÐ·ÑÐŒÑ ÑÐµÒ£Ð±ÐµÑÑ Ð¶ÓÐœÐµ ÐœÐ°ÒÑÑ ÐºÓ©ÑÑÐµÑÐºÐµÐœ ÑÐ°ÒÑÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÐ·ÐŽÐµÑÑÑÑÑÐ³ÐµÑ Ð±ÐŸÐ»Ð°ÐŽÑ.}
+_textstartdate_ [l=kk] {ÐÐ°ÑÑÐ°Ð¿ÒÑ (ÐœÐµÐŒÐµÑÐµ ÐœÐ°ÒÑÑ) ÐŒÐµÑÐ·ÑÐŒ:}
+_textenddate_ [l=kk] {Ð¡ÐŸÒ£ÒÑ ÐŒÐµÑÐ·ÑÐŒÑ}
+_textbc_ [l=kk] {Ð±.Ñ.ÐŽ.}
+_textad_ [l=kk] {Ð±.Ñ.}
+_textexplaineras_ [l=kk] {Ð.Ñ. Ð¶ÓÐœÐµ Ð±.Ñ.ÐŽ. Ð¢ÐµÑÐŒÐžÐœÐŽÐµÑÑ "Ð±ÑÐ·ÐŽÑÒ£ ÑÑÐ°ÐŒÑÐ·" Ð¶ÓÐœÐµ "Ð±ÑÐ·ÐŽÑÒ£ ÑÑÐ°ÐŒÑÐ·ÒÐ° ÐŽÐµÐ¹ÑÐœ"-ÐŽÑ Ð±ÑÐ»ÐŽÑÑÐµÐŽÑ}
+
+_textstemon_ [l=kk] {(ÑÓ©Ð· Ð¶Ð°Ð»ÒÐ°ÑÐ»Ð°ÑÑÐœ ÐµÐ»ÐµÐŒÐµÑ)}
+
+_textsearchhistory_ [l=kk] {ÐÐ·ÐŽÐµÑ ÑÐ°ÑÐžÑ
+Ñ}
+
+#text macros for search history
+_textnohistory_ [l=kk] {ÓÐ·ÑÑÑÐµ ÑÒ±ÑÐ°ÐœÑÐŒ ÑÐ°ÑÐžÑ
+Ñ ÒÐ°Ð»ÑÐ¿ÑÐ°ÑÒÐ°Ðœ Ð¶ÐŸÒ}
+_texthresult_ [l=kk] {ÐºÐµÐ·ÐŽÐµÑÑÑ}
+_texthresults_ [l=kk] {ÐºÐµÐ·ÐŽÐµÑÑÐ»ÐµÑ}
+_texthallwords_ [l=kk] {ÑÓ©Ð·ÐŽÐµÑÐŽÑÒ£ Ð±Ð°ÑÐ»ÑÒÑ}
+_texthsomewords_ [l=kk] {ÐºÐµÐ¹Ð±ÑÑ ÑÓ©Ð·ÐŽÐµÑ}
+_texthboolean_ [l=kk] {Ð»ÐŸÐ³ÐžÐºÐ°Ð»ÑÒ}
+_texthranked_ [l=kk] {ÑÐµÑÑÐµÐ»Ð³ÐµÐœ}
+_texthcaseon_ [l=kk] {ÑÐµÐ³ÐžÑÑÑÐŽÑ ÐµÑÐºÐµÑÐµ ÐŸÑÑÑÑÐ¿}
+_texthcaseoff_ [l=kk] {ÑÐµÐ³ÐžÑÑÑÐŽÑ ÐµÑÐºÐµÑÐŒÐµÐ¹}
+_texthstemon_ [l=kk] {Ð¶Ð°Ð»ÒÐ°ÑÐŒÐµÐœ}
+_texthstemoff_ [l=kk] {Ð¶Ð°Ð»ÒÐ°ÑÑÑÐ·}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=kk] {ÐÑÑÑÒÑÑÐ»ÑÒÑ Ð±ÑÐ»Ð°Ð¹ÑÐ° Ð±ÐµÑÑÐ»ÐŽÑ. Ð¡ÑÐ·ÐŽÑÒ£ Ð±ÑÐ°ÑÐ·ÐµÑÑÒ£ÑÐ·ÐŽÐµÐ³Ñ "back" Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÐ±Ð°Ò£ÑÐ· - Ð±Ò±Ð» ÐŸÐœÑ Ð¶ÐŸÐ¹ÑÐ¿ Ð¶ÑÐ±ÐµÑÐµÐŽÑ! ÐÑÐœÑÐœÐ° ÐµÐœÑ ÑÑÐ·ÑÒÑÐœÑÒ£ Ò¯ÑÑÑÐœÐŽÐµÐ³Ñ Ð±Ð°ÑÑÑÐŒÐ°ÐœÑÒ£ ÐºÐµÐ·-ÐºÐµÐ»Ð³ÐµÐœÑÐœ Ð±Ð°ÑÑÒ£ÑÐ·.}
+_textsetprefs_ [l=kk] {Ð°ÑÑÑÒÑÑÐ»ÑÒÑÐœ Ð±ÐµÐ»Ð³ÑÐ»ÐµÑ}
+_textsearchprefs_ [l=kk] {ÐÐ·ÐŽÐµÑ ÑÐ°ÑÑÑÐ°ÑÑ}
+_textcollectionprefs_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ ÐžÐºÐµÐŒÐŽÐµÑ}
+_textpresentationprefs_ [l=kk] {ÐÐœÑÐµÑÑÐµÐ¹Ñ ÐžÐºÐµÐŒÐŽÐµÑ}
+_textpreferences_ [l=kk] {ÐÐºÐµÐŒÐŽÐµÑ}
+_textcasediffs_ [l=kk] {Ð ÐµÐ³ÐžÑÑÑÐ»ÐµÑ:}
+_textignorecase_ [l=kk] {ÑÐµÐ³ÐžÑÑÑÐ»ÐµÑÐŽÑ ÐµÑÐºÐµÑÐŒÐµÑ}
+_textmatchcase_ [l=kk] {Ð¶ÐŸÒÐ°ÑÒÑ Ð¶ÓÐœÐµ ÑÓ©ÐŒÐµÐœÐ³Ñ ÑÐµÐ³ÐžÑÑÑÐ»ÐµÑÐŽÑ ÒÐŸÐ»ÐŽÐ°ÐœÑ}
+_textwordends_ [l=kk] {Ð¡Ó©Ð·ÐŽÐµÑÐŽÑÒ£ Ð¶Ð°Ð»ÒÐ°ÑÐ»Ð°ÑÑ:}
+_textstem_ [l=kk] {ÑÓ©Ð·ÐŽÐµÑÐŽÑÒ£ Ð¶Ð°Ð»ÒÐ°ÑÐ»Ð°ÑÑÐœ ÐµÑÐºÐµÑÐŒÐµÑ}
+_textnostem_ [l=kk] {Ð¶Ð°Ð»ÒÐ°ÑÑ Ð±Ð°Ñ ÑÓ©Ð·ÐŽÐµÑÐŽÑ ÒÐŸÐ»ÐŽÐ°ÐœÑ}
+
+
+
+
+_textprefop_ [l=kk] {_maxdocoption_ ÒÒ±Ð¶Ð°ÑÑÐ°ÑÑÐœ â ÑÐ·ÐŽÐµÑ ÐœÓÑÐžÐ¶ÐµÐ»ÐµÑÑÐœ ÐºÓ©ÑÑÐµÑÑ,   _hitsperpageoption_ ÒÒ±Ð¶Ð°ÑÑÐ°Ðœ Ð±ÑÑ Ð¿Ð°ÑÐ°ÒÑÐ°.}
+_textextlink_ [l=kk] {Ð¡ÑÑÑÒÑ Web-ÑÐŸÑÐ°Ð±ÑÐœÐ° ÐµÐœÑ:}
+_textintlink_ [l=kk] {ÐÒ±Ð» ÒÒ±Ð¶Ð°Ñ Ð°Ð»ÑÐœÒÐ°Ðœ ÐŸÑÐœÑ:}
+_textlanguage_ [l=kk] {ÐÐœÑÐµÑÑÐµÐ¹Ñ ÑÑÐ»Ñ:}
+_textencoding_ [l=kk] {ÐÐŸÐŽÑÐ°ÐŒÐ°ÑÑ:}
+_textformat_ [l=kk] {ÐÐœÑÐµÑÑÐµÐ¹Ñ ÑÐŸÑÐŒÐ°ÑÑ:}
+_textall_ [l=kk] {Ð±Ð°ÑÐ»ÑÒÑ}
+_textquerymode_ [l=kk] {Ð¡Ò±ÑÐ°ÐœÑÐŒ ÑÒ¯ÑÑ:}
+_textsimplemode_ [l=kk] {Ð¡Ò±ÑÐ°ÐœÑÐŒÐœÑÒ£ ÒÐ°ÑÐ°Ð¿Ð°Ð¹ÑÐŒ ÑÒ¯ÑÑ}
+_textadvancedmode_ [l=kk] {Ð¡Ò±ÑÐ°ÐœÑÐŒÐœÑÒ£ ÐºÐµÒ£ÐµÐ¹ÑÑÐ»Ð³ÐµÐœ ÑÒ¯ÑÑ (! (ÐÐÐÐ¡) , & (ÐÓÐÐ), | (ÐÐÐÐÐ¡Ð) Ð¶ÓÐœÐµ Ð¶Ð°ÒÑÐ°Ð»Ð°Ñ Ð°ÐŒÐ°Ð»ÐŽÐ°ÑÑÐŒÐµÐœ Ð»ÐŸÐ³ÐžÐºÐ°Ð»ÑÒ ÑÐ·ÐŽÐµÑ ÑÒ±ÒÑÐ°Ñ ÐµÑÑÐ»Ð³ÐµÐœ}
+_textlinkinterm_ [l=kk] {Ð°ÑÐ°Ð»ÑÒ Ð¿Ð°ÑÐ°Ò Ð°ÑÒÑÐ»Ñ}
+_textlinkdirect_ [l=kk] {ÑÑÐºÐµÐ»ÐµÐ¹ Ó©ÑÑ}
+_textdigitlib_ [l=kk] {ÑÐ»ÐµÐºÑÑÐŸÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°}
+_textweb_ [l=kk] {Web}
+_textgraphical_ [l=kk] {ÐÑÐ°ÑÐžÐºÐ°Ð»ÑÒ}
+_texttextual_ [l=kk] {ÐÓÑÑÐœÐŽÑÐº}
+_textcollectionoption_ [l=kk] {<p> ÒÐŸÐ»ÐŽÐ°ÐœÑÒÐ° Ð°ÑÐœÐ°Ð»ÒÐ°Ðœ ÑÑÐºÑ Ð¶ÐžÐœÐ°ÒÑÐ°Ñ: <br>}
+
+
+
+
+
+
+
+_textrelateddocdisplay_ [l=kk] {Ò±ÒÑÐ°Ñ ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ ÐºÓ©ÑÑÐµÑÑ}
+_textsearchhistory_ [l=kk] {Ð¡Ò±ÑÐ°ÐœÑÐŒ ÑÐ°ÑÐžÑ
+Ñ:}
+_textnohistory_ [l=kk] {Ð¡Ò±ÑÐ°ÐœÑÐŒ ÑÐ°ÑÐžÑ
+ÑÐœÑÒ£ Ð¶ÐŸÒÑÑÒÑ}
+_texthistorydisplay_ [l=kk] {_historynumrecords_ ÑÒ±ÑÐ°ÐœÑÐŒ ÑÐ°ÑÐžÑ
+ÑÐœ ÐºÓ©ÑÑÐµÑÑ}
+_textnohistorydisplay_ [l=kk] {ÑÒ±ÑÐ°ÐœÑÐŒ ÑÐ°ÑÐžÑ
+ÑÐœ ÐºÓ©ÑÑÐµÑÐ¿ÐµÑ}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=kk] {Ð±ÐŸÐ¹ÑÐœÑÐ° ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ ÑÒ±ÑÑÐ¿ÑÐ°Ñ}
+_textalsoshowing_ [l=kk] {ÒÐŸÑÑÐŒÑÐ° ÐºÓ©ÑÑÐµÑÑ}
+_textwith_ [l=kk] {ÐµÒ£ Ò¯Ð»ÐºÐµÐœÑÐŒÐµÐœ}
+_textdocsperpage_ [l=kk] {Ð¿Ð°ÑÐ°ÒÑÐ°ÒÑ ÒÒ±Ð¶Ð°ÑÑÐ°Ñ}
+
+_textfilterby_ [l=kk] {ÐŒÐ°Ð·ÐŒÒ±ÐœÐŽÐ°ÒÑ ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ Ð°Ð»Ñ}
+_textall_ [l=kk] {Ð±Ð°ÑÐ»ÑÒÑ}
+_textany_ [l=kk] {ÐºÐµÐ·-ÐºÐµÐ»Ð³ÐµÐœÑ}
+_textwords_ [l=kk] {ÑÓ©Ð·ÐŽÐµÑÐŽÐµÐœ}
+_textleaveblank_ [l=kk] {ÐÐ°ÑÐ»ÑÒ ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ Ð°Ð»Ñ Ò¯ÑÑÐœ, ÐŸÑÑ Ð¶ÓÑÑÐºÑÑ Ð±ÐŸÑ ÒÐ°Ð»ÐŽÑÑÑ}
+
+_browsebuttontext_ [l=kk] {"ÒÒ±Ð¶Ð°Ñ ÑÒ¯ÑÑ"}
+
+_nodata_ [l=kk] {<i>ÐŒÓÐ»ÑÐŒÐµÑ Ð¶ÐŸÒ</i>}
+_docs_ [l=kk] {ÒÒ±Ð¶Ð°ÑÑÐ°Ñ}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=kk] {ÐÓ©ÐŒÐµÐº}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=kk] {Ð¿ÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ð¿ÐŸ _1_ ÐœÐ°Ð¶Ð°Ð² ÐºÐœÐŸÐ¿ÐºÑ _2_}  
+
+
+_textTohelp_ [l=kk] {Ð¿ÑÐŸÑÐŒÐŸÑÑÐµÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð¿ÐŸ Ð¿ÐŸÐ»Ñ ÐºÐŸÐŒÑ ÐœÐ°Ð¶Ð°Ð² ÐºÐœÐŸÐ¿ÐºÑ _labelTo_ button}  
+_textFromhelp_ [l=kk] {Ð¿ÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ð¿ÐŸ Ð¿ÐŸÐ»Ñ ÐÑ ÐœÐ°Ð¶Ð°Ð² _labelFrom_ button}  
+_textBrowsehelp_ [l=kk] {Ð¿ÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ²}  
+_textAcronymhelp_ [l=kk] {Ð¿ÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ð¿ÐŸ ÑÐŸÐºÑÐ°ÑÐµÐœÐžÑÐŒ Ð¿ÐŸÑÐ²Ð»ÑÐµÑÑÑ ÐœÐ°Ð¶Ð°Ð² ÐºÐœÐŸÐ¿ÐºÑ _labelAcronym_ button}  
+
+
+_texthelptopicstitle_ [l=kk] {Ð¢Ð°ÑÐ°ÑÐ»Ð°ÑÑ}
+
+_textreadingdocs_ [l=kk] {ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŒÐµÐœ ÒÐ°Ð»Ð°Ð¹ Ð¶Ò±ÐŒÑÑ ÑÑÑÐµÑ ÐºÐµÑÐµÐº}
+
+_texthelpreadingdocs_ [l=kk] {<p>Ð¡ÑÐ· ÐºÐµÐ·-ÐºÐµÐ»Ð³ÐµÐœ ÒÐ°ÐœÐŽÐ°Ð¹ ÐŽÐ° Ð±ÑÑ ÒÒ±Ð¶Ð°ÑÑÑ Ð°ÑÒÐ°ÐœÐŽÐ° ÐŸÐœÑÒ£ Ð°ÑÑÐœ Ð¶ÓÐœÐµ Ð¿Ð°ÑÐ°ÒÑÑÒ£ ÑÐŸÐ» Ð¶Ð°Ò Ð¶ÐŸÒÐ°ÑÒÑ Ð±Ò±ÑÑÑÑÐœÐŽÐ° Ð°Ð²ÑÐŸÑÑÐœ ÐºÓ©ÑÐµÑÑÐ·. Ð¡ÐŸÐ» ÑÐžÑÒÑÑ Ð¡ÑÐ· Ð¿Ð°ÑÐ°Ò ÐœÓ©ÐŒÐµÑÑÐœ, Ð°Ð»ÒÐ° Ð¶ÓÐœÐµ Ð°ÑÑÒÐ° ÐºÓ©ÑÑ ÑÑÑÐµÐ»ÐºÐ°Ð»Ð°ÑÑÐœ, Ð¶Ð°Ò£Ð° Ð¿Ð°ÑÐ°ÒÑÑ ÑÐ°Ò£ÐŽÐ°Ñ Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ ÑÐ°Ð±Ð° Ð°Ð»Ð°ÑÑÐ·. 
+
+<p>Ð¢Ó©ÐŒÐµÐœÐŽÐµ Ð°ÒÑÐŒÐŽÐ°ÒÑ Ð±Ó©Ð»ÑÐŒÐœÑÒ£ ÐŒÓÑÑÐœÑ Ð±ÐµÑÑÐ»Ð³ÐµÐœ. ÐÐœÑ ÐŸÒÑÒÐ°ÐœÐœÐ°Ðœ ÐºÐµÐ¹ÑÐœ, ÑÓ©ÐŒÐµÐœ Ð¶Ð°ÒÑÐœÐŽÐ° ÐºÐµÐ»ÐµÑÑ ÐœÐµÐŒÐµÑÐµ Ð°Ð»ÐŽÑÒ£ÒÑ Ð±Ó©Ð»ÑÐŒÐ³Ðµ ÐºÓ©ÑÑ ÑÑÑÐµÐ»ÐºÐ°Ð»Ð°ÑÑÐœ ÐºÓ©ÑÐµÑÑÐ·. 
+
+
+<p>ÒÒ±Ð¶Ð°Ñ Ð°ÑÑ Ð¶ÓÐœÐµ ÐŸÐœÑÒ£ Ð°Ð²ÑÐŸÑÑ Ð±ÐµÐ»Ð³ÑÐ»ÐµÐœÐ³ÐµÐœ Ð¶Ð°Ð·Ñ Ð°ÑÑÑÐœÐŽÐ° Ò¯Ñ Ð±Ð°ÑÑÑÐŒÐ° Ð±Ð°Ñ. <i>ÐÐ°ÑÐ»ÑÒ ÐŒÓÑÑÐœ</i> Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÑÑÐ°Ò£ÑÐ· ÒÒ±Ð¶Ð°ÑÑÑÒ£ Ð±Ð°ÑÐ»ÑÒ ÐŒÓÑÑÐœÑÐœ ÑÐºÑÐ°ÐœÒÐ° ÑÑÒÐ°ÑÐ° Ð°Ð»Ð°ÑÑÐ·. ÐÐ³ÐµÑ ÒÒ±Ð¶Ð°Ñ Ð¶ÐµÑÐºÑÐ»ÑÐºÑÑ ÐºÓ©Ð»ÐµÐŒÐŽÑ Ð±ÐŸÐ»ÑÐ°, ÐŸÐœÐŽÐ° ÐŸÐ» Ð±ÑÑÐ°Ð· ÑÐ°ÒÑÑ Ð¿ÐµÐœ ÐºÓ©Ð¿ Ð¶Ð°ÐŽÑÐœÑ ÒÐ°Ð¶ÐµÑ ÐµÑÐµÐŽÑ! </i> 
+ÐÐµÑÑÐ»Ð³ÐµÐœ ÒÒ±Ð¶Ð°ÑÑÑ Ð¶Ð°Ò£Ð° ÑÐµÑÐµÐ·ÐµÐ³Ðµ ÑÑÒÐ°ÑÑ Ò¯ÑÑÐœ (Ð±Ò±Ð» Ð±ÑÑÐŽÐµÐœ Ð±ÑÑÐœÐµÑÐµ ÒÒ±Ð¶Ð°ÑÑÑ ÑÐ°Ð»ÑÑÑÑÑÒÑÒ£ÑÐ· ÐºÐµÐ»ÑÐµ ÐœÐµÐŒÐµÑÐµ ÐµÐºÐµÑÑÐœ Ð±ÑÑÐŽÐµÐœ ÐŸÒÑÒÑÒ£ÑÐ· ÐºÐµÐ»ÑÐµ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ñ) <i>ÐÐ°Ò£Ð° ÑÐµÑÐµÐ·ÐµÐŽÐµ</i> Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ·. ÐÐ³ÐµÑ Ð¡ÑÐ· Ð±Ò±Ð» ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ Ð±ÐµÐ»Ð³ÑÐ»Ñ ÑÓ©Ð·ÐŽÐµÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÐ°Ð¿ÒÐ°Ðœ Ð±ÐŸÐ»ÑÐ°Ò£ÑÐ·, ÐŸÐœÐŽÐ° ÐŸÐ»Ð°Ñ ÒÒ±Ð¶Ð°Ñ ÐŒÓÑÑÐœÑÐœÐŽÐµ Ð±Ð°ÑÐ° ÐºÓ©ÑÑÐµÑÑÐ»ÑÐ¿ ÑÒ±ÑÐ°ÐŽÑ. ÐÐ·ÐŽÐµÐ³ÐµÐœ ÑÓ©Ð·ÐŽÐµÑ ÒÒ±Ð¶Ð°Ñ ÐŒÓÑÑÐœÑÐœÐŽÐµ Ð±Ð°ÑÐ° ÐºÓ©ÑÑÐµÑÑÐ»ÑÐ¿ ÑÒ±ÑÐŒÐ°ÑÑ Ò¯ÑÑÐœ <i>Ð±Ð°ÑÐ° ÐºÓ©ÑÑÐµÑÑÐŽÑ Ð¶ÐŸÑ</i> Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ·.}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=kk] {ÐÑÐºÑÑÑÑ ÐºÐœÐžÐ¶ÐœÑÐ¹ ÑÐºÐ°Ñ}  
+_texthelpopenbook_ [l=kk] {Ð Ð°ÑÐºÑÑÑÑ/Ð·Ð°ÐºÑÑÑÑ ÑÑÑ ÐºÐœÐžÐ³Ñ}  
+_texthelpviewtextsection_ [l=kk] {ÐÑÐŸÑÐŒÐŸÑÑÐµÑÑ ÐŽÐ°ÐœÐœÑÐ¹ ÑÐ°Ð·ÐŽÐµÐ» ÐºÐ°Ðº ÑÐµÐºÑÑ}  
+_texthelpexpandtext_ [l=kk] {ÐÐ°ÑÐ»ÑÒ ÐŒÓÑÑÐœÐŽÑ ÑÑÒÐ°ÑÐ°Ð¹ÑÐœÐ±Ð°, Ð¶ÐŸÒÐ¿Ð°}
+_texthelpexpandcontents_ [l=kk] {Ð Ð°ÑÐºÑÑÑÑ ÑÐ°Ð±Ð»ÐžÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÑ, ÐžÐ»Ðž ÐœÐµÑ}  
+_texthelpdetachpage_ [l=kk] {ÐÒ±Ð» Ð¿Ð°ÑÐ°ÒÑÑ Ð¶Ð°Ò£Ð° ÑÐµÑÐµÐ·ÐµÐŽÐµ Ð°ÑÐ°Ð¹ÑÐœ Ð±Ð°}
+_texthelphighlight_ [l=kk] {ÐÐ·ÐŽÐµÑÑÑÑÐµÑÑÐœ ÑÓ©Ð·ÐŽÐµÑÐŽÑ Ð±Ð°ÑÐ° ÐºÓ©ÑÑÐµÑÐµÐ¹ÑÐœ Ð±Ðµ, Ð¶ÐŸÒ Ð¿Ð°}
+_texthelpsectionarrows_ [l=kk] {Ð ÑÐ»ÐµÐŽÑÑÑÐµÐŒÑ/Ð¿ÑÐµÐŽÑÐŽÑÑÐµÐŒÑ ÑÐ°Ð·ÐŽÐµÐ»Ñ}  
+
+
+_texthelpsearchingtitle_ [l=kk] {ÐÑÐœÐ°Ð¹Ñ ÑÐµÑÐŒÐžÐœÐŽÐµÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÐ·ÐŽÐµÑ ÐµÑÐµÐºÑÐµÐ»ÑÐºÑÐµÑÑ}
+
+_texthelpsearching_ [l=kk] {<p>
+  Ð¡ÑÐ· ÑÐ·ÐŽÐµÑ Ð¿Ð°ÑÐ°ÒÑÐœÐ°Ðœ, ÐºÐµÐ»ÐµÑÑ ÒÐ°ÐŽÐ°ÐŒÐŽÐ°ÑÒÐ° ÑÓÐ¹ÐºÐµÑ ÒÐ°ÑÐ°Ð¿Ð°Ð¹ÑÐŒ ÑÒ±ÑÐ°ÐœÑÐŒ Ð¶Ð°ÑÐ°Ð¹ Ð°Ð»Ð°ÑÑÐ·. <p>
+  
+  <ol><li>ÐÐ·ÐŽÐµÐ¹ÑÑÐœÑÒ£ÑÐ·ÐŽÑ Ð°ÐœÑÒÑÐ°Ò£ÑÐ·
+      <li>ÐÐœÑÒ£ Ð¶ÐŸÐ»ÐŽÐ°ÑÑÐœ: ÑÑÐ°Ð·Ð° ÐœÐµÐŒÐµÑÐµ Ð¶ÐµÐºÐµ ÑÓ©Ð·ÐŽÐµÑ Ð°ÑÒÑÐ»Ñ 
+      <li>Ð¡Ò±ÑÐ°ÐœÑÐŒ ÐŒÓÑÑÐœÑÐœ ÑÐ·ÐŽÐµÑ Ð¶ÐŸÐ»ÑÐœÐ° ÑÐµÑÑÒ£ÑÐ·
+      <li><i>ÐÐ·ÐŽÐµÑÐŽÑ Ð±Ð°ÑÑÐ°Ñ</i> Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ· 
+  </ol>
+
+<p>Ð¡Ò±ÑÐ°ÐœÑÐŒ ÐŸÑÑÐœÐŽÐ°Ð»ÒÐ°ÐœÐœÐ°Ðœ ÐºÐµÐ¹ÑÐœ ÑÐºÑÐ°ÐœÐŽÐ° 20 ÒÒ±Ð¶Ð°ÑÑÑÒ£ Ð°ÑÐ°ÑÑ ÑÑÒÐ°ÐŽÑ. Ð¢ÑÐ·ÑÐŒÐœÑÒ£ ÑÐŸÒ£ÑÐœÐŽÐ°, ÐºÐµÐ»ÐµÑÑ 20 ÒÒ±Ð¶Ð°ÑÒÐ° ÐºÓ©ÑÐµÑÑÐœ Ð±Ð°ÑÑÑÐŒÐ°ÑÑ Ð±Ð°Ñ. Ð¡ÑÐ· ÐºÐµÐ· ÐºÐµÐ»Ð³ÐµÐœ ÒÒ±Ð¶Ð°ÑÑÑÒ£ Ð°ÑÑÐœÐ° ÐœÐµÐŒÐµÑÐµ ÒÐ°ÑÑÐœÐŽÐ°ÒÑ Ð±ÐµÐ»Ð³ÑÑÑÐœ Ð±Ð°ÑÑÐ¿, ÐŸÐœÑ ÒÐ°ÑÐ°Ð¹ Ð°Ð»Ð°ÑÑÐ·. 
+
+<p>ÐÐ·ÐŽÐµÑ ÐœÓÑÐžÐ¶ÐµÑÑ ÐµÒ£ ÐºÓ©Ð¿ ÐŽÐµÐ³ÐµÐœÐŽÐµ 100 ÒÒ±Ð¶Ð°Ñ ÑÐ°ÐœÑÐœ ÑÐ°Ð±Ð°ÐŽÑ. ÐÒ±Ð» ÑÐ°ÐœÐŽÑ ÐÐºÐµÐŒÐŽÐµÑ Ð¿Ð°ÑÐ°ÒÑÐœÐ°Ðœ Ó©Ð·Ð³ÐµÑÑÐµ Ð°Ð»Ð°ÑÑÐ· (ÐÐ°ÑÐ°ÒÑÑÒ£ Ð¶ÐŸÒÐ°ÑÑ Ð¶Ð°ÒÑÐœÐŽÐ° ÐŸÑÐœÐ°Ð»Ð°ÑÒÐ°Ðœ <i> ÐÐºÐµÐŒÐŽÐµÑ </i> Ð±Ð°ÑÑÑÐŒÐ°ÑÑ) <p>}
+
+_texthelpquerytermstitle_ [l=kk] {ÐÐ·ÐŽÐµÑÑÑÑÑ ÑÓ©Ð·ÐŽÐµÑÑ}
+_texthelpqueryterms_ [l=kk] {<p>Ð¡ÑÐ·ÐŽÑÒ£ ÑÒ±ÑÐ°ÐœÑÐŒ Ð¶ÐŸÐ»ÑÐœÐ° ÐµÐœÐ³ÑÐ·ÐµÑÑÐœÑÒ£ÑÐ·ÐŽÑÒ£ Ð±ÓÑÑ, "ÑÐ·ÐŽÐµÑÑÑÑÑ ÑÓ©Ð·ÐŽÐµÑÑ" ÐŽÐµÐ¿ Ð°ÑÐ°Ð»Ð°ÐŽÑ. ÓÑ ÑÓ©Ð·ÐŽÑ ÓÑÑÐ¿ÑÐµÑ Ð¶ÓÐœÐµ ÑÐ°ÐœÐŽÐ°Ñ ÒÒ±ÑÐ°Ð¹ÐŽÑ. Ð¡Ó©Ð·ÐŽÐµÑ Ð°ÑÐ°Ð»ÑÒÑÐŒÐµÐœ Ð±Ó©Ð»ÑÐœÐ³ÐµÐœ. ÐÑÐœÐºÑÑÐ°ÑÐžÑ Ð±ÐµÐ»Ð³ÑÐ»ÐµÑÑ (ÐŒÑÑÐ°Ð»Ñ, Ò¯ÑÑÑ, ÐœÒ¯ÐºÑÐµ Ñ.Ñ.Ñ.), Ð°ÑÐ°Ð»ÑÒ (ÐžÐœÑÐµÑÐ²Ð°Ð») ÑÐžÑÒÑÑ ÑÐµÐº ÑÓ©Ð· Ð±Ó©Ð»Ð³ÑÑ ÒÑÐ·ÐŒÐµÑÑÐœ Ð°ÑÒÐ°ÑÐ°ÐŽÑ. ÐÑÐœÐºÑÑÐ°ÑÐžÑ Ð±ÐµÐ»Ð³ÑÐ»ÐµÑÑ Ð±Ð°Ñ ÑÓ©Ð·ÐŽÐµÑÐŒÐµÐœ ÑÐ·ÐŽÐµÑ Ð¶Ò¯ÑÐ³ÑÐ·Ðµ Ð°Ð»ÐŒÐ°Ð¹ÑÑÐ·. 
+
+<p>ÐÑÑÐ°Ð»Ñ, <p>
+    <ul><kbd>Ð¢ÑÐœÑÒ ÐŒÒ±Ñ
+ÐžÑÑ Ð°ÑÐ°Ð»ÐŽÐ°ÑÑÐœÐŽÐ°ÒÑ ÐÑÑÐ»-ÐŸÑÐŒÐ°Ðœ ÑÐ°ÑÑÐ°ÑÑÐ»ÑÒÑ: ÒÐŸÐ»ÐŽÐ°Ñ Ð¶Ò¯Ð¹ÐµÑÑ (1993)</kbd></ul>
+      <p>Ð±Ò±Ð» ÑÒ±ÑÐ°ÐœÑÐŒ ÑÓ©ÐŒÐµÐœÐŽÐµÐ³ÑÐŒÐµÐœ Ð¿Ð°ÑÐ°-Ð¿Ð°Ñ<p>
+      <ul><kbd>Ð¢ÑÐœÑÒ ÐŒÒ±Ñ
+ÐžÑÑ Ð°ÑÐ°Ð»ÐŽÐ°ÑÑÐœÐŽÐ°ÒÑ ÐÑÑÐ»-ÐŸÑÐŒÐ°Ðœ ÑÐ°ÑÑÐ°ÑÑÐ»ÑÒÑ ÒÐŸÐ»ÐŽÐ°Ñ Ð¶Ò¯Ð¹ÐµÑÑ 1993</kbd></ul><p>
+}  
+
+
+
+
+
+_texthelpquerytypetitle_ [l=kk] {Ð¡Ò±ÑÐ°ÐœÑÐŒÐŽÐ°Ñ ÑÒ¯ÑÑ}
+_texthelpquerytype_ [l=kk] {<p>ÓšÐ·Ð³ÐµÑÐµ ÐµÐºÑ ÑÒ±ÑÐ°ÐœÑÐŒ ÑÒ¯ÑÑ Ð±Ð°Ñ.
+
+<ul>
+  <li><b>ÐÐ°ÑÐ»ÑÒ</b> ÑÓ©Ð·ÐŽÐµÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÒ±ÑÐ°ÐœÑÐŒÐŽÐ°Ñ. ÐÒ±Ð» ÑÐ·ÐŽÐµÑ Ð¶ÐŸÐ»ÑÐœÐ° ÐµÐœÐ³ÑÐ·Ð³ÑÒ£ÑÐ· ÐºÐµÐ»Ð³ÐµÐœ ÑÓ©Ð·ÐŽÐµÑÐŽÑÒ£ Ð±Ð°ÑÐ»ÑÒÑ ÐºÐµÐ·ÐŽÐµÑÐµÑÑÐœ ÒÒ±Ð¶Ð°ÑÑÐ°Ñ Ò¯ÑÑÐœ. Ð¡Ò±ÑÐ°ÐœÑÐŒÐŽÑ ÒÐ°ÐœÐ°ÒÐ°ÑÑÐ°ÐœÐŽÑÑÐ°ÑÑÐœ ÒÒ±Ð¶Ð°ÑÑÐ°Ñ ÐÐ»ÑÐ°Ð²ÐžÑÑÑÐº ÑÓÑÑÑÐ¿Ð¿ÐµÐœ ÑÑÒÐ°ÑÑÐ»Ð°ÐŽÑ. <p>
+
+  <li><b>ÐÐµÐ¹Ð±ÑÑ</b> ÑÓ©Ð·ÐŽÐµÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÒ±ÑÐ°ÐœÑÐŒÐŽÐ°Ñ. Ð¢ÐµÐº ÒÒ±Ð¶Ð°Ñ ÐŒÓÑÑÐœÑÐœÐŽÐµ ÐºÐµÐ·ÐŽÐµÑÑÑ ÐŒÒ¯ÐŒÐºÑÐœ Ð±ÑÑÐœÐµÑÐµ ÑÓ©Ð·ÐŽÑ Ð¶Ð°Ð·Ñ Ð¶ÐµÑÐºÑÐ»ÑÐºÑÑ. ÒÒ±Ð¶Ð°ÑÑÐ°Ñ ÑÒ±ÑÐ°ÐœÑÐŒÒÐ° ÑÓÐ¹ÐºÐµÑ ÐºÐµÐ»ÑÑÐœ ÑÓ©ÐŒÐµÐœÐŽÐµÑ ÑÐµÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÑÒÐ°ÑÑÐ»Ð°ÐŽÑ. Ð¡Ò±ÑÐ°ÐœÑÐŒÒÐ° ÑÓÐ¹ÐºÐµÑÑÑÐº Ð±ÑÐ»Ð°Ð¹ Ð°ÐœÑÒÑÐ°Ð»Ð°ÐŽÑ:  
+      <p><ul>
+        <li> ÒÒ±Ð¶Ð°ÑÑÐ° ÑÐ·ÐŽÐµÐ»ÑÐœÐµÑÑÐœ ÑÐµÑÐŒÐžÐœÐŽÐµÑ ÐºÓ©Ð±ÑÑÐµÐº ÐºÐµÐ·ÐŽÐµÑÐºÐµÐœ ÑÐ°Ð¹ÑÐœ, ÐŸÐ» ÐºÓ©Ð±ÑÑÐµÐº ÑÓÐ¹ÐºÐµÑ ÐºÐµÐ»ÐµÐŽÑ;
+        <li> Ð¶Ð°Ð»Ð¿Ñ ÑÓ©Ð·ÐŽÐµÑÐ³Ðµ ÒÐ°ÑÐ°ÒÐ°ÐœÐŽÐ°, ÑÐžÑÐµÐº ÑÓ©Ð·ÐŽÐµÑ ÐŒÐ°Ò£ÑÐ·ÐŽÑÑÐ°Ò;
+        <li> ÐºÓ©Ð»ÐµÐŒÐŽÑ ÒÒ±Ð¶Ð°ÑÑÐ°ÑÒÐ° ÒÐ°ÑÐ°ÒÐ°ÐœÐŽÐ° ÑÒÑÐ°ÐŒÐŽÑÐ»Ð°ÑÑ Ð¶Ð°ÒÑÑ ÑÓÐ¹ÐºÐµÑ.
+      </ul>
+</ul>
+
+<p>ÐÐ·ÐŽÐµÑÐ³Ðµ ÒÐ°ÐœÑÐ° ÑÓ©Ð· ÒÐ°Ð¶ÐµÑ Ð±ÐŸÐ»ÑÐ° ÑÐŸÐœÑÐ° ÑÓ©Ð·ÐŽÑ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÒ£ÑÐ· â Ð±Ò±Ð» Ð±Ò¯ÑÑÐœ ÑÓ©Ð¹Ð»ÐµÐŒ ÐœÐµÐŒÐµÑÐµ Ð¿Ð°ÑÐ°Ð³ÑÐ°Ñ Ð±ÐŸÐ»ÑÑ ÐŒÒ¯ÐŒÐºÑÐœ. ÐÐ³ÐµÑ Ð¡ÑÐ· ÑÐµÐº Ð±ÑÑ ÑÓ©Ð· ÐµÐœÐ³ÑÐ·ÑÐµÒ£ÑÐ·, ÐŸÐœÐŽÐ° ÒÒ±Ð¶Ð°ÑÑÐ°Ñ ÐŸÐœÑÒ£ Ð¿Ð°Ð¹ÐŽÐ° Ð±ÐŸÐ»Ñ Ð¶ÐžÑÐ»ÑÐ³ÑÐœÑÒ£ ÐºÐµÐŒÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÐŸÑÐœÐ°Ð»Ð°ÑÐ°ÐŽÑ. <p>}
+
+_texthelpadvancedsearchtitle_ [l=kk] {Ð Ð°ÑÑÐžÑÐµÐœÐœÑÐ¹ Ð¿ÐŸÐžÑÐº Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµÐŒ _1_ Ð¿ÐŸÐžÑÐºÐŸÐ²ÐŸÐ¹ ÐŒÐ°ÑÐžÐœÑ}  
+
+
+
+
+
+
+
+
+
+_texthelpadvancedsearchextra_ [l=kk] {ÐÐ ÐÐÐÐ§ÐÐÐÐ: Ð­ÑÐž ÐŸÐ¿ÐµÑÐ°ÑÐŸÑÑ Ð±ÑÐŽÑÑ Ð²ÑÐµ Ð¿ÑÐŸÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÐœÐœÑ ÐµÑÐ»Ðž Ð²Ñ ÐžÑÐµÑÐµ Ð² ÑÐµÐ¶ÐžÐŒÐµ Ð¿ÑÐŸÑÑÐŸÐ³ÐŸ Ð¿ÐŸÐžÑÐºÐ°.}  
+
+_texthelpadvsearchlucene_ [l=kk] {Ð Ð°ÑÑÐžÑÐµÐœÐœÑÐ¹ Ð¿ÐŸÐžÑÐº Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Lucene Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµÐŒ  Ð±ÑÐ»ÐµÐ²ÑÑ
+ ÐŸÐ¿ÐµÑÐ°ÑÐŸÑÐŸÐ². _texthelpbooleansearch_
+}  
+
+_texthelpformsearchtitle_ [l=kk] {ÐÐŸÐžÑÐº Ð¿ÐŸ Ð¿ÐŸÐ»ÑÐŒ}  
+
+
+
+
+
+_textdatesearch_ [l=kk] {ÐÐµÑÐ·ÑÐŒÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÐ·ÐŽÐµÑ}
+
+_texthelpdatesearch_ [l=kk] {ÐÐµÑÐ·ÑÐŒÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÐÐ·ÐŽÐµÑ Ð¡ÑÐ·Ð³Ðµ Ð±ÐµÐ»Ð³ÑÐ»Ñ Ð±ÑÑ ÑÐ°ÒÑÑ Ð°ÑÐ°Ð»ÑÒÑÐœÐŽÐ° Ð±ÐŸÐ»ÒÐ°Ðœ ÐŸÒÐžÒÐ°Ð»Ð°ÑÒÐ° ÒÐ°ÑÑÑÑÑ ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ, Ð±ÐµÐ»Ð³ÑÐ»Ñ Ð±ÑÑ ÑÐ·ÐŽÐµÑ ÑÐµÑÐŒÐžÐœÑÐŒÐµÐœ ÑÐ°Ð±ÑÐ»Ð°ÑÑÐœ ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ ÑÐ°Ð±Ñ Ñ.Ð±. ÑÐ·ÐŽÐµÑÑÑÑÑÐ³Ðµ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐº Ð±ÐµÑÐµÐŽÑ. Ð¡ÑÐ· ÑÐ·ÐŽÐµÑÐŽÑ Ð±ÐµÐ»Ð³ÑÐ»Ñ Ð±ÑÑ Ð¶ÑÐ»ÒÐ° ÒÐ°ÑÑÑÑÑ ÒÒ±Ð¶Ð°ÑÑÐ°Ñ Ð±ÐŸÐ¹ÑÐœÑÐ° Ð¶ÓÐœÐµ Ð¶ÑÐ»ÐŽÐ°Ñ ÐºÐµÐ·ÐµÒ£ÑÐœÐµ Ð±Ð°Ð¹Ð»Ð°ÐœÑÑÑÑÑÐ° Ð¶Ò¯ÑÐ³ÑÐ·Ðµ Ð°Ð»Ð°ÑÑÐ·.<p>}
+
+_texthelpdatehowtotitle_ [l=kk] {ÐÒ±ÐœÑ ÒÐ°Ð»Ð°Ð¹ ÒÐŸÐ»ÐŽÐ°ÐœÑ ÐºÐµÑÐµÐº:}
+_texthelpdatehowto_ [l=kk] {<ul>
+   <li>ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ ÐœÐ°ÒÑÑ ÐŒÐµÑÐ·ÑÐŒÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÐ·ÐŽÐµÑ:<p>
+   <ul>
+       <li>ÐÐ·ÐŽÐµÑÑÑÑÑ Ò¯ÑÑÐœ ÐºÓÐŽÑÐŒÐ³Ñ ÑÓ©Ð·ÐŽÐµÑÐŽÑ ÐµÐœÐ³ÑÐ·ÑÒ£ÑÐ·. 
+       <li>ÒÐ°Ð¶ÐµÑÑÑ Ð¶ÑÐ»ÐŽÑ "ÐÐ°ÑÑÐ°Ð¿ÒÑ (ÐœÐµÐŒÐµÑÐµ ÐœÐ°ÒÑÑ) ÐŒÐµÑÐ·ÑÐŒ" ÑÐŸÑÐŒÐ°ÑÑÐœÐ° ÐµÐœÐ³ÑÐ·ÑÒ£ÑÐ·.
+       <li>ÐÐ³ÐµÑ Ð¡ÑÐ·ÐŽÑÒ£ Ð¶ÑÐ»ÑÒ£ÑÐ· Ð±ÑÐ·ÐŽÑÒ£ ÑÑÐ°ÐŒÑÐ·ÒÐ° ÐŽÐµÐ¹ÑÐœÐ³Ñ (Ð¥ÑÐžÑÑÐŸÑ ÑÑÑÐ»ÒÐ°ÐœÒÐ° ÐŽÐµÐ¹ÑÐœÐ³Ñ) Ð°ÑÐ°Ð»ÑÒÑÐ° Ð¶Ð°ÑÑÐ°, ÐŸÐœÐŽÐ° Ð±Ò±ÐŽÐ°Ðœ Ð±ÑÐ»Ð°Ð¹ Ð¿Ð°Ð¹ÐŽÐ° Ð±ÐŸÐ»Ð°ÑÑÐœ ÐŒÓÐ·ÑÑÐŽÐµÐœ "Ð.Ñ.ÐŽ." ÑÐ°Ò£ÐŽÐ°Ò£ÑÐ·.
+       <li>ÐÐ·ÐŽÐµÑÐŽÑ Ð±Ð°ÑÑÐ°Ò£ÑÐ·.
+   </ul>
+<p><li>ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ ÑÐ°ÒÑÑ Ð°ÑÐ°Ð»ÑÒÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÐ·ÐŽÐµÑ:<p>
+   <ul>
+       <li>ÐÐ·ÐŽÐµÑÑÑÑÑ Ò¯ÑÑÐœ ÐºÓÐŽÑÐŒÐ³Ñ ÑÓ©Ð·ÐŽÐµÑÐŽÑ ÐµÐœÐ³ÑÐ·ÑÒ£ÑÐ·.
+
+
+       <li>ÐÐ°ÑÑÐ°Ð¿ÒÑ Ð¶ÑÐ»ÐŽÑ "ÐÐ°ÑÑÐ°Ð¿ÒÑ (ÐœÐµÐŒÐµÑÐµ ÐœÐ°ÒÑÑ) ÐŒÐµÑÐ·ÑÐŒ" ÑÐŸÑÐŒÐ°ÑÑÐœÐ° ÐµÐœÐ³ÑÐ·ÑÒ£ÑÐ·. 
+       <li>Ð¡ÐŸÒ£ÒÑ Ð¶ÑÐ»ÐŽÑ "Ð¡ÐŸÒ£ÒÑ ÐŒÐµÑÐ·ÑÐŒÑ" ÑÐŸÑÐŒÐ°ÑÑÐœÐ° ÐµÐœÐ³ÑÐ·ÑÒ£ÑÐ·.
+       <li>ÐÐ°Ð¹ÐŽÐ° Ð±ÐŸÐ»Ð°ÑÑÐœ ÐŒÓÐ·ÑÑÐŽÐµÐœ "Ð.Ñ.ÐŽ." ÐŸÑÑ ÐºÐµÐ·ÐµÒ£ÐœÑÒ£ ÐºÐµÐ· ÐºÐµÐ»Ð³ÐµÐœ ÐŒÐµÑÐ·ÑÐŒÑ Ò¯ÑÑÐœ (Ð¥ÑÐžÑÑÐŸÑ ÑÑÑÐ»ÒÐ°ÐœÒÐ° ÐŽÐµÐ¹ÑÐœÐ³Ñ ÐºÐµÐ·ÐµÒ£ ÐŽÐµÐ¿ ÑÐµ Ð°ÑÐ°Ð»Ð°ÐŽÑ) ÑÐ°Ò£ÐŽÐ°Ò£ÑÐ·. 
+       <li>ÐÐ·ÐŽÐµÑÐŽÑ Ð±Ð°ÑÑÐ°Ò£ÑÐ·.
+   </ul>    
+</ul><p>}
+
+_texthelpdateresultstitle_ [l=kk] {ÐÐµÑÐ·ÑÐŒ Ð±ÐŸÐ¹ÑÐœÑÐ° ÑÐ·ÐŽÐµÑ ÒÐ°Ð»Ð°Ð¹ Ð¶Ò¯ÑÐ³ÑÐ·ÑÐ»ÐµÐŽÑ}
+_texthelpdateresults_ [l=kk] {Ð¡Ò±ÑÐ°ÐœÑÐŒÐœÑÒ£ ÑÐŸÐ»ÑÒÑÑÐ°Ò ÐœÓÑÐžÐ¶ÐµÑÑÐœ Ð°Ð»Ñ Ò¯ÑÑÐœ ÐžÐœÑÐµÑÐ²Ð°Ð»ÐŽÑÒ ÑÒ±ÑÐ°ÐœÑÐŒÐŽÑ ÒÐŸÐ»ÐŽÐ°ÐœÑ Ò±ÑÑÐœÑÐ»Ð°ÐŽÑ, ÑÐµÐ±ÐµÐ±Ñ ÐºÐµÐ¹Ð±ÑÑ ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÐ° ÐŒÐµÑÐ·ÑÐŒÐŽÐµÑÑ ÐœÐ°ÒÑÑ ÐºÓ©ÑÑÐµÑÑÐ»ÐŒÐµÐ³ÐµÐœ (ÐŒÑÑÐ°Ð»Ñ Ð¶ÑÐ» ÐµÐŒÐµÑ, ÒÐ°ÑÑÑ ÐºÓ©ÑÑÐµÑÑÐ»ÑÑ ÐŒÒ¯ÐŒÐºÑÐœ). 
+<p>}
+
+_textchangeprefs_ [l=kk] {ÐÐºÐµÐŒÐŽÐµÑÐŽÑ Ó©Ð·Ð³ÐµÑÑÑ}
+
+_texthelppreferences_ [l=kk] {<p> <i>ÐÐºÐµÐŒÐŽÐµÑ</i> Ð¿Ð°ÑÐ°ÒÑÐœÐŽÐ° (Ð¿Ð°ÑÐ°ÒÑÑÒ£ Ð¶ÐŸÒÐ°ÑÒÑ Ð±Ó©Ð»ÑÐ³ÑÐœÐŽÐµÐ³Ñ Ð±Ð°ÑÑÑÐŒÐ°) Ð¡ÑÐ· ÐžÐœÑÐµÑÑÐµÐ¹ÑÑÑÒ£ ÐºÐµÐ¹Ð±ÑÑ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÐ»ÐµÑÑÐœ Ó©Ð·Ð³ÐµÑÑÐµ Ð°Ð»Ð°ÑÑÐ·.}
+
+_texthelpcollectionprefstitle_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ ÐÐºÐµÐŒÐŽÐµÑ}
+_texthelpcollectionprefs_ [l=kk] {ÐÐµÐ¹Ð±ÑÑ ÐÐžÐœÐ°ÒÑÐ°ÑÐŽÐ° Ð±ÑÑÐœÐµÑÐµ ÑÑÐºÑ Ð¶ÐžÐœÐ°ÒÑÐ°Ñ Ð±ÐŸÐ»Ð°ÐŽÑ. ÐÐ·ÐŽÐµÑ ÓÑÒÐ°Ð¹ÑÑÑÑÐœÐŽÐ° Ð¶ÐµÐºÐµ Ð¶ÓÐœÐµ Ð±Ð°ÑÐ»ÑÒÑÐœÐŽÐ° Ð±ÑÑ ÒÐ°ÑÐ°Ñ Ð¶Ò¯ÑÐ³ÑÐ·ÑÐ»ÑÑ ÐŒÒ¯ÐŒÐºÑÐœ. ÐÐºÐµÐŒÐŽÐµÑ Ð¿Ð°ÑÐ°ÒÑÐœÐŽÐ° Ð¡ÑÐ· ÑÐ·ÐŽÐµÑÐ³Ðµ ÒÐŸÑÒÑÒ£ÑÐ· ÐºÐµÐ»Ð³ÐµÐœ ÑÑÐºÑ Ð¶ÐžÐœÐ°ÒÑÐ°ÑÐŽÑ ÑÐ°Ò£ÐŽÐ°Ð¹ Ð°Ð»Ð°ÑÑÐ·.}
+
+_texthelplanguageprefstitle_ [l=kk] {Ð¢ÑÐ»ÐŽÑ ÐžÐºÐµÐŒÐŽÐµÑ}
+_texthelplanguageprefs_ [l=kk] {ÓÑ ÐÐžÐœÐ°ÒÑÐ° ÑÑÐ°ÐœÐŽÐ°ÑÑÑÑ ÐžÐœÑÐµÑÑÐµÐ¹Ñ ÑÑÐ»Ñ Ð±Ð°Ñ, Ð±ÑÑÐ°Ò Ð¡ÑÐ· ÐºÐµÐ· ÐºÐµÐ»Ð³ÐµÐœ Ð±Ð°ÑÒÐ° ÑÑÐ»ÐŽÑ ÑÐ°Ò£ÐŽÐ°Ð¹ Ð°Ð»Ð°ÑÑÐ·. Ð¡ÐŸÐœÐŽÐ°Ð¹-Ð°Ò Ð¡ÑÐ· ÐŸÑÑ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°ÐŽÐ° ÒÐŸÐ»ÐŽÐ°ÐœÑÐ»Ð°ÑÑÐœ Ð±Ð°ÑÒÐ° ÐºÐŸÐŽÑÐ°ÐŒÐ°ÐœÑ ÑÐ°Ò£ÐŽÐ°Ð¹ Ð°Ð»Ð°ÑÑÐ·, Ð¡ÑÐ·ÐŽÑÒ£ Ð±ÑÐ°ÑÐ·ÐµÑÐ³Ðµ ÑÑÑÐ° ÐºÐµÐ»ÐµÑÑÐœÑ Ð°Ð²ÑÐŸÐŒÐ°ÑÑÑ ÑÒ¯ÑÐŽÐµ ÑÑÐ°ÐœÐŽÐ°ÑÑÑÑ Ð±ÐŸÐ»Ð°ÐŽÑ, ÐµÒ£ ÐŽÒ±ÑÑÑÑ ÐºÐŸÐŽÑÐ°ÐŒÐ°ÐœÑ ÒÐŸÐ»ÑÐŒÐµÐœ ÑÐ°Ò£ÐŽÐ°ÒÐ°Ðœ. ÐÐžÐœÐ°ÒÑÐ°ÑÐŽÑÒ£ Ð±Ð°ÑÐ»ÑÒÑÐœÐŽÐ° Ð±ÐµÐ¹ÐœÐµÐ»ÑÐŽÑÒ£ Ð³ÑÐ°ÑÐžÐºÐ°Ð»ÑÒ ÑÐµÐ¶ÐžÐŒÑÐœÐµÐœ ÐŒÓÑÑÐœÐŽÑÐºÐºÐµ Ð¶ÓÐœÐµ ÐºÐµÑÑÑÑÐœÑÐµ ÐºÓ©ÑÑÐ³Ðµ Ð±ÐŸÐ»Ð°ÐŽÑ.}
+
+_texthelppresentationprefstitle_ [l=kk] {ÐÐœÑÐµÑÑÐµÐ¹ÑÑÑ ÐžÐºÐµÐŒÐŽÐµÑ}
+_texthelppresentationprefs_ [l=kk] {ÐÐžÐœÐ°ÒÑÐ°ÑÒÐ° Ð±Ð°Ð¹Ð»Ð°ÐœÑÑÑÑ ÐŸÐ»Ð°ÑÐŽÐ° ÓÑÑÒ¯ÑÐ»Ñ Ð±ÑÑÐœÐµÑÐµ ÐÐºÐµÐŒÐŽÐµÑ Ð±ÐŸÐ»Ð°ÐŽÑ. 
+
+<p>Web-Ð¿Ð°ÑÐ°ÒÑÐ°Ñ  ÐÐžÐœÐ°ÒÑ  ÓÑ ÒÒ±Ð¶Ð°ÑÑÑÒ£ Ð¶ÐŸÒÐ°ÑÒÑ Ð¶Ð°ÒÑÐœÐŽÐ° ÐŸÑÐœÐ°Ð»Ð°ÑÒÐ°Ðœ Ð±Ð°ÑÒÐ°ÑÑ Ð¿Ð°ÐœÐµÐ»ÑÐœ ÒÐŸÐ»ÐŽÐ°ÐœÑÒÐ° ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐº Ð±ÐµÑÐµÐŽÑ, ÑÐŸÐ» Ð°ÑÒÑÐ»Ñ ÐÐ·ÐŽÐµÑÐŽÐµÐœ ÐºÐµÐ¹ÑÐœ Ð±ÑÑ-Ð¶ÐŸÐ»Ð°ÑÐ° Web-Ð¿Ð°ÑÐ°ÒÑÒ£ÑÐ·ÒÐ° ÐºÓ©ÑÐµ Ð°Ð»Ð°ÑÑÐ·. ÐÐ°Ò£Ð° ÑÒ±ÑÐ°ÐœÑÐŒ Ð¶Ð°ÑÐ°Ñ Ò¯ÑÑÐœ Ó©Ð·ÑÒ£ÑÐ·ÐŽÑÒ£ Ð±ÑÐ°ÑÐ·ÐµÑÑÒ£ÑÐ·ÐŽÐµÐ³Ñ "back" Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÑÑÐ°Ò£ÑÐ· Ð±ÐŸÐ»ÒÐ°ÐœÑ. ÐÒ±ÐœÐŽÐ°Ð¹ ÐÐžÐœÐ°ÒÑÐ°Ñ  WWW-ÐŽÐ°ÒÑ ÑÐ»ÐµÐºÑÑÐŸÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ° Ð°ÑÒÑÐŒÑÐœÐ°Ðœ ÑÑÒÐ°ÑÐ°ÑÑÐœ ÑÑÐ»ÑÐµÐŒÐµÐ»ÐµÑÐŽÑ Ð±Ð°ÑÒÐ°ÐœÐŽÐ° Ð¿Ð°Ð¹ÐŽÐ° Ð±ÐŸÐ»Ð°ÑÑÐœ Ð¶Ò¯Ð¹ÐµÐ»ÑÐº ÒÐ°ÑÐµÐ»ÐµÑÐ³Ðµ ÑÑÐ¹ÑÐŒ ÑÐ°Ð»Ñ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐ³ÑÐœ Ð±ÐµÑÐµÐŽÑ.}
+
+_texthelpsearchprefstitle_ [l=kk] {ÐÐ·ÐŽÐµÑÑÑÑÑÐŽÑ ÐÐºÐµÐŒÐŽÐµÑ}
+_texthelpsearchprefs_ [l=kk] {<p>ÐÐºÑ Ð°ÑÑÑÑÑÑÑÐ¿-ÒÐŸÑÒÑÑ ÐŒÓÑÑÐœÐŽÑ ÑÐ·ÐŽÐµÑ ÐŽÓÐ»ÐŽÑÐ³ÑÐœ Ð±Ð°ÑÒÐ°ÑÐ°ÐŽÑ. "Ð ÐµÐ³ÐžÑÑÑÐ»ÐµÑ" ÒÐ°Ð¹ÑÐ° ÒÐŸÑÒÑÑÑ ÑÐµÐ³ÐžÑÑÑÐŽÑ ÐµÑÐºÐµÑÑÐŽÑ Ó©ÑÑÑÐµÐŽÑ\ÑÑÐºÐµ ÒÐŸÑÐ°ÐŽÑ. "Ð¡Ó©Ð· Ð¶Ð°Ð»ÒÐ°ÑÐ»Ð°ÑÑ" ÒÐ°Ð¹ÑÐ° ÒÐŸÑÒÑÑÑÐ°ÑÑ ÑÓ©Ð·ÐŽÑÒ£ Ð¶Ð°Ð»ÒÐ°ÑÐ»Ð°ÑÑÐœ ÒÐŸÐ»ÐŽÐ°ÐœÑÐŽÑ ÐœÐµÐŒÐµÑÐµ ÐµÑÐºÐµÑÐŒÐµÑÐŽÑ ÒÐŸÐ»ÐŽÐ°ÐœÑ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐ³ÑÐœ Ð±ÐµÑÐµÐŽÑ. "ÐÐ·ÐŽÐµÑ ÑÐµÑÐµÐ·ÐµÑÑÐœÑÒ£ Ó©Ð»ÑÐµÐŒÑ" ÒÐ°Ð¹ÑÐ° ÒÐŸÑÒÑÑÑ ÑÒ±ÑÐ°ÐœÑÐŒ ÐŒÓÑÑÐœÑ ÑÐµÑÑÐœÐŽÐµ Ð±Ò¯ÑÑÐœÐŽÐµÐ¹ Ð±ÑÑ Ð°Ð±Ð·Ð°ÑÑÑ ÐµÐœÐ³ÑÐ·Ñ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐ³ÑÐœ Ð±ÐµÑÐµÐŽÑ.  
+<p>ÐÑÑÐ°Ð»Ñ, ÐµÐ³ÐµÑ <i>ÑÐµÐ³ÐžÑÑÑÐ»ÐµÑÐŽÑ ÐµÑÐºÐµÑÐŒÐµÑ</i> Ð¶ÓÐœÐµ
+<i>ÑÓ©Ð· Ð¶Ð°Ð»ÒÐ°ÑÐ»Ð°ÑÑÐœ ÐµÑÐºÐµÑÐŒÐµÑ</i> ÑÐ°Ò£ÐŽÐ°Ð»ÑÐ°, ÐŸÐœÐŽÐ° ÑÒ±ÑÐ°ÐœÑÐŒ<p>
+    <ul><kbd>African building</kbd></ul>
+      <p>ÐºÐµÐ»ÐµÑÑ ÑÒ¯ÑÐŽÐµ ÑÒ¯ÑÑÐœÑÐ»ÐµÐŽÑ<p>
+      <ul><kbd>africa builds</kbd></ul><p>
+      Ð¡ÐµÐ±ÐµÐ±Ñ "African" ÑÓ©Ð·ÑÐœÐŽÐµÐ³Ñ Ð¶ÐŸÒÐ°ÑÒÑ ÑÐµÐ³ÐžÑÑÑ ÓÑÐ¿Ñ ÑÓ©ÐŒÐµÐœÐ³Ñ ÑÐµÐ³ÐžÑÑÑ ÓÑÐ¿ÑÐœÐµ Ó©Ð·Ð³ÐµÑÑÑÐ»ÑÐ¿, "n" Ð¶ÓÐœÐµ "ing" Ð¶Ð°Ð»ÒÐ°ÑÐ»Ð°ÑÑ ÑÓ©Ð·ÐŽÐµÐœ Ð°Ð»ÑÐ¿ ÑÐ°ÑÑÐ°Ð»ÑÐœÐ°ÐŽÑ. "African" Ð¶ÓÐœÐµ "building" (ÑÐŸÐœÐŽÐ°Ð¹-Ð°Ò, "s" "builds" ÑÓ©Ð·ÑÐœÐµÐœ Ð°Ð»ÑÐ¿ ÑÐ°ÑÑÐ°Ð»ÑÐœÐ°ÐŽÑ).
+
+<p>Ð¡ÑÐ· ÐÓÐÐ (&), ÐÐÐÐÐ¡Ð (|), ÐÓÐÐ ÐÐÐÐ¡ Ð°ÐŒÐ°Ð»ÐŽÐ°ÑÑÐœ ÒÐŸÐ»ÐŽÐ°ÐœÑÐ¿ ÑÒ±ÑÐ°ÐœÑÐŒÐœÑÒ£ ÐºÐµÒ£ÐµÐ¹ÑÑÐ»Ð³ÐµÐœ ÑÐŸÑÐŒÐ°ÑÑÐœÐ° ÐºÓ©ÑÐµ Ð°Ð»Ð°ÑÑÐ·. ÐÒ±Ð» ÐŽÓÐ» ÑÒ±ÑÐ°ÐœÑÐŒÐŽÐ°Ñ ÒÒ±ÑÑ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐ³ÑÐœ Ð±ÐµÑÐµÐŽÑ. ÐÐ»ÐŽÑÒ£ÒÑ ÑÐ·ÐŽÐµÑ ÐœÓÑÐžÐ¶ÐµÐ»ÐµÑÑ ÐºÓ©ÑÑÐµÑÑÐ»Ð³ÐµÐœ ÐºÐµÐ·ÐŽÐµ ÑÒ±ÑÐ°ÐœÑÐŒ ÑÐ°ÑÐžÑ
+ÑÐœ ÐºÓ©ÑÑÐµÑÑÐŽÑ ÑÑÐºÐµ ÒÐŸÑÐ° Ð°Ð»Ð°ÑÑÐ·. ÐÒ±Ð» Ð°Ð·ÐŽÐ°Ð¿ Ó©Ð·Ð³ÐµÑÑÑÐ»Ð³ÐµÐœ ÑÒ±ÑÐ°ÐœÑÐŒÐŽÐ°Ñ ÑÒ¯ÑÑÐœ Ð¶Ð°ÑÐ°ÑÒÐ° ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐº Ð±ÐµÑÐµÐŽÑ. Ð¡ÑÐ· Ð±ÑÑ Ð±ÐµÑÑÐµÐ³Ñ ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑÒ£ Ð¶Ð°Ð»Ð¿Ñ ÑÐ°ÐœÑ ÐŒÐµÐœ ÑÐ·ÐŽÐµÑ ÐœÓÑÐžÐ¶ÐµÑÑÐœÑÒ£ Ð¶Ð°Ð»Ð¿Ñ ÑÐ°ÐœÑÐœ ÑÐµÑÑÐµÐ¹ Ð°Ð»Ð°ÑÑÐ·.}
+
+_textcasefoldprefs_ [l=kk] {ÐÐ°ÑÐ° ÐºÐœÐŸÐ¿ÐŸÐº ÐºÐŸÐœÑÑÐŸÐ»ÐžÑÑÐµÑ Ð²ÐµÑÑ
+ÐœÐžÐ¹ Ðž ÐœÐžÐ¶ÐœÐžÐ¹ ÑÐµÐ³ÐžÑÑÑ Ð² ÐœÐ°Ð¹ÐŽÐµÐœÐœÐŸÐŒ. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, ÐµÑÐ»Ðž Ð²ÑÐ±ÑÐ°ÐœÐŸ "_preferences:textignorecase_", <i>Ð°ÐºÐžÐŒÐ°Ñ Ð³ÐŸÑÐŸÐŽÐ°</i> Ð±ÑÐŽÐµÑ Ð¿ÑÐµÐŽÑÑÐ°Ð²Ð»ÐµÐœ ÐºÐ°Ðº <i>ÐÐºÐžÐŒÐ°Ñ ÐÐŸÑÐŸÐŽÐ°</i> Ðž <i>ÐÐÐÐÐÐ¢ ÐÐÐ ÐÐÐ</i>.}  
+
+_textaccentfoldprefs_ [l=kk] {ÐÐ°ÑÐ° ÐºÐœÐŸÐ¿ÐŸÐº ÐºÐŸÐœÑÑÐŸÐ»ÐžÑÑÐµÑ Ð°ÐºÑÐµÐœÑÐžÑÐŸÐ²Ð°ÐœÐœÑÐµ Ðž ÐœÐµÐ°ÐºÑÐµÐœÑÐžÑÐŸÐ²Ð°ÐœÐœÑÐµ ÑÐžÐŒÐ²ÐŸÐ»Ñ ÐºÐŸÑÐŸÑÑÐµ ÐŽÐŸÐ»Ð¶ÐœÑ ÑÐŸÐŸÑÐ²ÐµÑÑÐ²ÐŸÐ²Ð°ÑÑ ÐœÐ°Ð¹ÐŽÐµÐœÐœÐŸÐŒÑ. ÐÐ°Ð¿ÐžÐŒÐµÑ , ÐµÑÐ»Ðž Ð²ÑÐ±ÑÐ°ÐœÐŸ "_preferences:textignoreaccents_", <i>fÃ©dÃ©ration</i> Ð±ÑÐŽÐµÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑÑÑ ÐºÐ°Ðº <i>fedÃ©ration</i> Ðž <i>federation</i>.}  
+ 
+_textstemoptionsprefs_ [l=kk] {ÐÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÑÑÐŸ Ð±ÐŸÐ»ÐµÐµ ÑÐŸÑÐœÐŸ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ° ÑÐ°Ð·Ð±ÐžÑÑÐµ ÑÐµÑÐŒÐžÐœÑ ÐºÐ°Ðº ÐŸÐ¿ÐžÑÐ°ÐœÐŸ Ð²ÑÑÐµ Ð² "_texthelpquerytermstitle_".}  
+
+_textsearchtypeprefsplain_ [l=kk] {ÐÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ Ð¿ÐŸÐ»ÑÑÐžÑÑ Ð±ÐŸÐ»ÑÑÑÑ ÑÐŸÑÐŒÑ Ð·Ð°Ð¿ÑÐŸÑÐ°, ÑÐ°Ðº ÑÑÐŸÐ±Ñ Ð¿ÐŸÑÐ²ÐžÐ»Ð°ÑÑ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÑ ÐŽÐŸÐ±Ð°Ð²Ð»ÑÑÑ Ð¿ÐŸÐžÑÐºÐŸÑÐµ Ð·Ð°Ð¿ÑÐŸÑÑ ÑÐ°Ð·ÐŒÐµÑÐŸÐŒ Ð² Ð¿Ð°ÑÐ°Ð³ÑÐ°Ñ. Ð ÐœÐ°ÑÐµÐŒÑ ÑÐŽÐžÐ²Ð»ÐµÐœÐžÑ ÑÑÐŸ ÐŸÑÐµÐœÑ Ð±ÑÑÑÑÑÐ¹ Ð¿ÐŸÐžÑÐº.}  
+
+_textsearchtypeprefsform_ [l=kk] {ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ ÐžÐ·ÐŒÐµÐœÐžÑÑ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ Ð¿ÐŸÐ»ÐµÐ¹ Ð² Ð¿ÐŸÐžÑÐºÐŸÐ²ÐŸÐ¹ ÑÐŸÑÐŒÐµ.}  
+
+
+
+
+
+_texttanumbrowseoptions_ [l=kk] {ÐÒ±Ð» ÐÐžÐœÐ°ÒÑÐ° ÑÐ·ÐŽÐµÑÐŽÑÒ£ ÓÑ ÑÒ¯ÑÐ»Ñ ÑÓÑÑÐ»ÐŽÐµÑÑ Ð±Ð°Ñ (_numbrowseoptions_):}
+
+_textsimplehelpheading_ [l=kk] {ÐÒÐ¿Ð°ÑÐ°ÑÑÑ ÒÐ°Ð»Ð°Ð¹ ÑÐ·ÐŽÐµÑ ÐºÐµÑÐµÐº}
+
+_texthelpscopetitle_ [l=kk] {ÐÐ·ÐŽÐµÑ ÐŽÐžÐ°Ð¿Ð°Ð·ÐŸÐœÑ}
+_texthelpscope_ [l=kk] {<p>
+ÐÐžÐœÐ°ÒÑÐ°ÑÐŽÑÒ£ ÐºÓ©Ð¿ÑÑÐ»ÑÐ³ÑÐœÐŽÐµ Ð¡ÑÐ· ÓÑÑÒ¯ÑÐ»Ñ ÑÐ·ÐŽÐµÑ ÐžÐœÐŽÐµÐºÑÑÐµÑÑÐœ ÒÐŸÐ»ÐŽÐ°ÐœÐ° Ð°Ð»Ð°ÑÑÐ·. ÐÑÑÐ°Ð»Ñ, ÐºÑÑÐ°Ð¿ Ð°ÑÐ°ÑÐ»Ð°ÑÑÐœÑÒ£, Ð°Ð²ÑÐŸÑÐ»Ð°Ñ Ð°ÑÑ-Ð¶Ó©ÐœÑ ÐžÐœÐŽÐµÐºÑÑÐµÑÑÐœ. ÐÐ» ÑÐ°ÑÐ°Ñ ÐœÐµÐŒÐµÑÐµ Ð±Ó©Ð»ÑÐŒ Ð°ÑÐ°ÑÐ»Ð°ÑÑÐœÑÒ£ ÐžÐœÐŽÐµÐºÑÑÐµÑÑ ÐŽÐµ Ð±ÐŸÐ»ÑÑ ÐŒÒ¯ÐŒÐºÑÐœ. ÐÐ³ÐµÑ Ð¡ÑÐ· ÒÐ°Ð¶ÐµÑÑÑ ÐžÐœÐŽÐµÐºÑÑÑ (ÑÐ°ÑÐ°Ñ ÐœÐµÐŒÐµÑÐµ Ð±Ó©Ð»ÑÐŒÑ Ð±ÐŸÐ¹ÑÐœÑÐ°) ÐºÓ©ÑÑÐµÑÐ¿ÐµÑÐµÒ£ÑÐ· ÐŸÐœÐŽÐ° ÑÐºÑÐ°ÐœÒÐ° Ð±Ò¯ÐºÑÐ» ÒÒ±Ð¶Ð°Ñ ÑÑÒÐ°ÑÑÐ»Ð°ÐŽÑ. ÐÐ³ÐµÑ ÒÒ±Ð¶Ð°Ñ Ð±Ò¯ÑÑÐœÐŽÐµÐ¹ Ð±ÑÑ ÐºÑÑÐ°Ð¿ Ð±ÐŸÐ»ÑÐ° ÐŸÐœÐŽÐ° ÐŸÐ» Ð±ÐµÐ»Ð³ÑÐ»ÐµÐœÐ³ÐµÐœ ÑÒ±ÑÑÐœÐ°Ðœ Ð°ÑÑÐ»Ð°ÐŽÑ.}
Index: /gsdl/stable/macros/kazakh2.dm
===================================================================
--- /gsdl/stable/macros/kazakh2.dm	(revision 20131)
+++ /gsdl/stable/macros/kazakh2.dm	(revision 20131)
@@ -0,0 +1,877 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Kazakh Language text and icon macros 
+# -- this file contains text that is of less importance
+#     Updated by Zhanat Kulenov and Kalima Tuenbaeva in May 2009.
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=kk] {ÒÒ±Ð¶Ð°ÑÑÐ°Ñ}
+_lastupdate_ [l=kk] {Ð¡ÐŸÒ£ÒÑ Ð¶Ð°Ò£Ð°ÑÑÑ}
+_ago_ [l=kk] {ÐºÒ¯ÐœÑ Ð±Ò±ÑÑÐœ.}
+_colnotbuilt_ [l=kk] {ÐÐžÐœÐ°Ò ÒÒ±ÑÑÐ»ÐŒÐ°ÐŽÑ.}
+
+### taken from here
+
+_textpoem_ [l=kk] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+<p>Ð¡ÑÐ·ÐŽÑ Ð±ÐµÐ¹Ð±ÑÑÑÑÐ»ÑÐº Ð¿ÐµÐœ ÑÑÐœÑÑÑÑÒ ÒÐŸÑÑÐ°ÑÑÐœ, 
+<p>Ð¡ÑÐ· ÓÑÒÐ°ÑÐ°Ðœ Ð¶Ð°Ð·ÐŽÑÒ£ Ð¶ÑÐ»Ñ ÒÒ±ÑÐ°ÒÑÐœÐŽÐ° Ð±ÐŸÐ»ÑÒ£ÑÐ·, 
+<br>Ð¡ÑÐ·ÐŽÑÒ£ ÐŒÒ±Ñ
+ÐžÑÑÐ°ÒÑ ÑÐ°ÑÑ
+Ð°ÑÑÒ£ÑÐ·ÐŽÑÒ£ ÑÑÐ»Ð°ÑÑ, Greenstone-ÐœÑÒ£ ÑÒ¯ÑÐ³ÑÐ»ÐµÐœÐ³ÐµÐœ ÒÑÑÑÐœÐŽÐ°Ð¹ ÑÐµÐ³ÑÑ Ð±ÐŸÐ»ÑÑÐœ.}
+
+_textgreenstone_ [l=kk] {<p>ÐÑÐžÐœÑÑÐŸÑÐœ - ÐÐ°Ò£Ð°Ð·ÐµÐ»Ð°ÐœÐŽÐžÑÐŽÐ° ÑÐ°Ð±ÑÐ»ÒÐ°Ðœ (ÐŸÑÑ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° Ð¶Ð°Ð±ÐŽÑÒÑÐœÐ° Ò±ÒÑÐ°Ñ) 
+Ð¶Ð°ÑÑÑÐ»Ð°Ð¹ Ð±Ð°ÒÐ°Ð»Ñ ÑÐ°Ñ. ÐÐ°ÐŸÑÐžÐ»ÐµÑÐŽÑÒ£ ÐŽÓÑÑÒ¯ÑÐ»Ñ ÒÐŸÒÐ°ÐŒÑÐœÐŽÐ° ÐŸÐ» ÐµÒ£ ÒÑÐŒÐ±Ð°ÑÑÑ. 
+ÐÐ» ÑÑÑ
+ ÐœÐµÐŒÐµÑÐµ Ó©ÐŒÑÑ ÐºÒ¯ÑÑ Ð±ÐŸÐ»ÑÐ¿ ÑÐ°Ð±ÑÐ»Ð°ÑÑÐœ <i> wairua</i>-ÐœÑ Ð¶Ò±ÑÑÐ¿ Ð¶ÓÐœÐµ Ò±ÑÑÐ°Ð¹ Ð°Ð»Ð°ÐŽÑ. 
+ÐÓÑÑÒ¯ÑÐ»ÑÐº ÐœÐ°ÐŒÑÑÑÑ ÐºÓ©ÑÑÐµÑÐµÑÑÐœ, Ð±Ò±Ð» ÐŸÐœÑ Ð¶Ð°Ð»Ð¿Ñ ÒÐŸÐ»ÐŽÐ°ÐœÑÒÐ° Ð°ÑÐœÐ°Ð»ÒÐ°Ðœ ÑÐ°ÐœÐŽÑÒ 
+ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ° Ð¶ÐŸÐ±Ð°ÑÑ Ó©ÐœÑÐŒÑÐœÐµ ÑÐŸÐ»ÑÒ ÑÐ°Ð¹ ÐºÐµÐ»ÐµÑÑÐœ ÑÐŒÐ±Ð»ÐµÐŒÐ°. ÐÐœÑÒ£ Ð¶ÑÐ»ÑÑÑÐ»ÑÒÑ ÒÐ°Ð¹ÑÑÑÐŒÐŽÑÐ»ÑÒÑÑ, 
+ÑÒ±ÐœÑÒÑÑÒÑ â Ð°ÐŽÐ°Ð»ÐŽÑÒÑÑ, ÒÒ±Ð»Ð°ÐŒÐ°ÑÑ â Ð±Ð°ÑÑÑÐ»ÑÒÑÑ, Ð°Ð» Ó©ÑÐºÑÑ ÒÑÑÑ 
+- ÓÐŽÑÐ» ÑÓ©ÑÐµÐ»ÑÐºÑÑ Ð±ÑÐ»ÐŽÑÑÐµÐŽÑ. ÐÑÐžÐœÑÑÐŸÑÐœ ÑÐ°ÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ° Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° Ð¶Ð°Ð±ÐŽÑÒÑ 
+ÑÐŒÐ±Ð»ÐµÐŒÐ°ÑÑ ÑÐµÑÑÐœÐŽÐµ ÒÐŸÐ»ÐŽÐ°ÐœÑÐ»Ð°ÐŽÑ. ÐÐµÑÐµÑÑÐœ Ð±Ó©Ð»ÑÐ³Ñ â ÐŸÐ» <i>patu</i> 
+ÐœÐµÐŒÐµÑÐµ Ð°ÑÐ¿Ð°Ð»ÑÑÑÐ°ÒÑ ÑÑÐŒÐ°Ò ÑÐµÐºÑÐ»ÐŽÑ, Ð±ÑÐ·ÐŽÑÒ£ ÐÐŸÐ±Ð° Ð¶Ð°ÑÐ°ÑÑÑÐ»Ð°Ñ 
+Ð±ÑÑÐµÑÑÐœÑÒ£ Ð¶Ð°ÐœÒ±ÑÑÑÐœÐŽÐ° ÐµÑÐµÐºÑÐµ ÒÐ°ÑÑÐµÑ ÑÒ±ÑÐ°ÑÑÐœ ÐœÓÑÑÐµÑÑ. 
+ÐÐµÐºÐ¿Ðµ-Ð¶ÐµÐºÑÐµ ÐŸÐœÑÒ£ ÑÐµÐ°ÐºÑÐžÑÑÑ Ó©ÑÐµ Ð¶ÑÐ»ÐŽÐ°ÐŒ, Ó©ÑÐµ ÐŽÓÐ» Ð¶ÓÐœÐµ ÐœÐ°ÒÑÑ. 
+ÐÐŸÒÐ°ÑÑÐŽÐ° Ð°Ð¹ÑÑÐ»ÒÐ°Ðœ ÒÐ°ÑÐžÐµÑÑÐµÑÐŽÑÒ£ Ð±Ð°ÑÐ»ÑÒÑ Ð±ÑÐ·ÐŽÑÒ£ Ð±Ð°ÒÐŽÐ°ÑÐŒÐ° Ð¶Ð°Ð±ÐŽÑÒÑÐœÐ° ÒÐ°ÑÑÑÑÑ, 
+Ð°Ð» Ò±ÑÑÐ°ÑÐ°ÐœÑÒ£ Ó©ÑÐºÑÑ Ð¶Ð°ÒÑ  - <i>patu</i>, 
+ÑÐµÑ
+ÐœÐŸÐ»ÐŸÐ³ÐžÑÐ»Ð°ÑÑÐŒÑÐ·ÐŽÑÒ£ ÐŸÐ·ÑÒ ÑÐžÐŒÐ²ÐŸÐ»Ñ ÐŽÐµÐ¿ Ó©Ð·ÑÐŒÑÐ· ÑÒ¯ÑÑÐœÐµÐŒÑÐ·. </p>
+}  
+
+_textaboutgreenstone_ [l=kk] {<p>Greenstone - Ð±Ò±Ð» ÑÐ»ÐµÐºÑÑÐŸÐœÐŽÑÒ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ°Ð»ÑÒ Ð¶ÐžÐœÐ°ÒÑÐ°ÑÐŽÑ ÓÐ·ÑÑÐ»ÐµÑ ÐŒÐµÐœ ÑÐ°ÑÐ°ÑÑÒÐ° Ð°ÑÐœÐ°Ð»ÒÐ°Ðœ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°Ð»ÑÒ ÒÐ°ÐŒÑÐ°ÐŒÐ°ÑÑÐ· ÐµÑÑÐŽÑÒ£ Ð¶ÐžÑÐœÑÑÒÑ. ÐÒ±Ð» Ð¶Ò¯Ð¹Ðµ Ð°ÒÐ¿Ð°ÑÐ°ÑÑÑ ÑÐ°ÒÑÐœ ÐŽÐžÑÐºÑÐ³Ðµ, Ð¶ÐµÑÐ³ÑÐ»ÑÐºÑÑ Ð¶ÐµÐ»ÑÐ»ÐµÑ ÐŒÐµÐœ ÐÐœÑÐµÑÐœÐµÑÑÐµ Ð¶Ð°ÑÐžÑÐ»Ð°ÑÐŽÑ Ò±Ð¹ÑÐŒÐŽÐ°ÑÑÑÑÑÐŽÑÒ£ Ð¶Ð°Ò£Ð° ÑÓÑÑÐ»ÑÐœ ÒÐ°ÐŒÑÐ°ÐŒÐ°ÑÑÐ· ÐµÑÐµÐŽÑ. Greenstone  <b>ÐÐ°ÐžÐºÐ°ÑÐŸ Ð£ÐœÐžÐ²ÐµÑÑÐžÑÐµÑÑÐœÑÒ£ ÐÐ°Ò£Ð°Ð·ÐµÐ»Ð°ÐœÐŽÐžÑÐ»ÑÒ Ð­Ð»ÐµÐºÑÑÐŸÐœÐŽÑÒ ÐÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÑÑ</b> Ð¶ÐŸÐ±Ð°ÑÑ ÑÐµÒ£Ð±ÐµÑÑÐœÐŽÐµ, <b>Ð®ÐÐ­Ð¡ÐÐ</b>  Ð¶ÓÐœÐµ <b>ÐÐÐ ÐÐŽÐ°ÐŒÐ·Ð°Ñ ÐÒÐ¿Ð°ÑÐ°ÑÑ</b> (Human Info) ÑÐœÑÑÐŒÐ°ÒÑÐ°ÑÑÑÒÑÐŒÐµÐœ ÓÐ·ÑÑÐ»ÐµÐœÐŽÑ. ÐÒ±Ð» Ð°ÑÑÒ ÐœÐµÐ³ÑÐ·Ð³Ñ ÐºÐŸÐŽÑÐŒÐµÐœ Ð±ÐµÑÑÐ»Ð³ÐµÐœ Ð¶ÓÐœÐµ ÐŒÑÐœÐ° ÐŒÐµÐºÐµÐœÐ¶Ð°Ð¹ Ð±ÐŸÐ¹ÑÐœÑÐ° <a href="http://greenstone.org"> http://greenstone.org</a>, ÑÑÐ°ÐœÐŽÐ°ÑÑÑÑ ÒÐŸÒÐ°ÐŒÐŽÐ°Ò Ð»ÐžÑÐµÐœÐ·ÐžÑ ÑÐ°ÑÑÑÐ°ÑÑ Ð°ÑÒÑÐ»Ñ (GNU)</p> Ð°Ð»ÑÒÐ° Ð±ÐŸÐ»Ð°ÑÑÐœ ÐµÑÐºÑÐœ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°Ð»ÑÒ ÒÐ°ÐŒÑÐ°ÐŒÐ°ÑÑÐ· ÐµÑÑ.  
+
+<br>ÐÐ°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°Ð»ÑÒ ÒÐ°ÐŒÑÐ°ÐŒÐ°ÑÑÐ· ÐµÑÑÐŽÑÒ£ ÐŒÐ°ÒÑÐ°ÑÑ Ó©Ð· ÑÐ»ÐµÐºÑÑÐŸÐœÐŽÑÒ Ð¶ÐžÐœÐ°ÒÑÐ°ÑÑÐœ ÒÒ±ÑÐ° Ð±ÑÐ»Ñ Ò¯ÑÑÐœ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÑÑÐœÑÒ£ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐ³ÑÐœ ÐºÐµÒ£ÐµÐ¹ÑÑ, ÐŸÐ» ÑÐœÐžÐ²ÐµÑÑÐžÑÐµÑÑÐµÑ, ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°Ð»Ð°Ñ Ð¶ÓÐœÐµ Ð±Ð°ÑÒÐ° ÐŽÐ° ÒÐŸÒÐ°ÐŒÐŽÑÒ ÒÑÐ·ÐŒÐµÑ ÐµÑÑ Ò±Ð¹ÑÐŒÐŽÐ°ÑÑ Ð±ÐŸÐ»ÑÑ ÐŒÒ¯ÐŒÐºÑÐœ. Ð­Ð»ÐµÐºÑÑÐŸÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°Ð»Ð°Ñ Ð®ÐÐÐ¡ÐÐ ÑÐµÑÑÐºÑÐµÑÑÑÐ³Ñ  Ð¶ÓÐœÐµ Ð±Ò¯ÐºÑÐ» ÓÐ»ÐµÐŒÐŽÐµÐ³Ñ, ÓÑÑÑÐµÑÐµ ÐŽÐ°ÐŒÑÒÐ°Ðœ ÐŒÐµÐŒÐ»ÐµÐºÐµÑÑÐµÑÐŽÐµÐ³Ñ Ð±ÑÐ»ÑÐŒ Ð±ÐµÑÑ, ÒÑÐ»ÑÐŒ Ð¶ÓÐœÐµ ÐŒÓÐŽÐµÐœÐžÐµÑ ÑÐ°Ð»Ð°ÑÑÐœÐŽÐ°ÒÑ ÑÒ¯ÑÐ»Ñ Ò±Ð¹ÑÐŒÐŽÐ°Ñ ÑÐµÒ£Ð±ÐµÑÑÐœÐŽÐµ Ð°ÒÐ¿Ð°ÑÐ°ÑÑÑ ÑÐ°ÑÐ°ÑÑ ÐŒÐµÐœ ÐŸÐœÑ Ð°Ð»Ñ ÑÓÑÑÐ»ÐŽÐµÑÑÐœ ÑÒ¯Ð±ÐµÐ³ÐµÐ¹Ð»Ñ ÒÐ°Ð¹ÑÐ° Ó©Ð·Ð³ÐµÑÑÐµÐŽÑ. ÐÒ±Ð» Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°Ð»ÑÒ ÒÐ°ÐŒÑÐ°ÐŒÐ°ÑÑÐ· ÐµÑÑ Ð°ÒÐ¿Ð°ÑÐ°ÑÑÑ ÐºÒ¯ÐœÐŽÐµÐ»ÑÐºÑÑ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑ Ð¶ÓÐœÐµ ÒÐŸÒÐ°ÐŒÐœÑÒ£ ÒÐ°Ð»ÑÒ£ Ð±Ò±ÒÐ°ÑÐ° ÑÐŸÐ¿ÑÐ°ÑÑÐœÐ° ÒÐŸÐ»Ð°Ð¹Ð»Ñ Ð±ÐŸÐ»Ñ Ò¯ÑÑÐœ ÑÐžÑÐŒÐŽÑ ÑÐ°ÑÐ°ÑÑÐ»ÑÑÐœÐ° ÒÐ°Ð·ÒÐ°Ð»ÑÑ ÑÐ°Ð»Ð°ÐŽÑ ÐŽÐµÐ¿ ÑÐµÐœÐµÐŒÑÐ·. 
+</p>
+
+<p>ÐÒ±Ð» Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°Ð»ÑÒ ÒÐ°ÐŒÑÐ°ÐŒÐ°ÑÑÐ· ÐµÑÑ, 2000 Ð¶ÑÐ»ÐŽÑÒ£ ÑÐ°ÐŒÑÐ·ÑÐœÐ°Ðœ Ð±Ð°ÑÑÐ°Ð¿ Ò¯Ñ Ð¶Ð°ÒÑÑÒ£ Ñ
+Ð°Ð»ÑÒÐ°ÑÐ°Ð»ÑÒ ÑÐœÑÑÐŒÐ°ÒÑÐ°ÑÑÑÒÑÐœÑÒ£ Ó©ÐœÑÐŒÑ ÑÐµÑÑÐœÐŽÐµ ÓÐ·ÑÑÐ»ÐµÐœÑÐ¿ ÑÐ°ÑÐ°ÑÑÐ»ÐŽÑ. 
+
+</p>
+
+<p>
+<a href="http://nzdl.org"><b>ÐÐ°ÐžÐºÐ°ÑÐŸ Ð£ÐœÐžÐ²ÐµÑÑÐžÑÐµÑÑÐœÑÒ£ ÐÐ°Ò£Ð°Ð·ÐµÐ»Ð°ÐœÐŽÐžÑÐ»ÑÒ Ð­Ð»ÐµÐºÑÑÐŸÐœÐŽÑÒ ÐÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÑÑÐœÑÒ£ ÐÐŸÐ±Ð°ÑÑ </b></a>
+<br>
+Greenstone Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°Ð»ÑÒ ÒÐ°ÐŒÑÐ°ÐŒÐ°ÑÑÐ· ÐµÑÑ ÐŸÑÑ Ð¶ÐŸÐ±Ð° ÑÑÑÐœÐµÐœ ÑÑÒÑÑ Ð¶ÓÐœÐµ Ð±Ò±Ð» ÐžÐœÐžÑÐžÐ°ÑÐžÐ²Ð° Ð®ÐÐÐ¡ÐÐ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°ÑÑÐœÐ° ÐÐ°Ò£Ð° ÐÐµÐ»Ð°ÐœÐŽÐžÑÐœÑÒ£ ÒÐŸÑÒÐ°Ðœ Ò¯Ð»ÐµÑÑ ÑÐµÑÑÐœÐŽÐµ Ð®ÐÐÐ¡ÐÐ ÑÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÐÐ°Ò£Ð°Ð·ÐµÐ»Ð°ÐœÐŽÐžÑÐ»ÑÒ Ò°Ð»ÑÑÑÒ ÐÐŸÐŒÐžÑÑÐžÑÑÑÐœÑÒ£ ÐÐ°Ð¹Ð»Ð°ÐœÑÑÑÐ°ÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÐºÐŸÐŒÐžÑÐµÑÑÐµÑÑÐŒÐµÐœ ÒÒ±Ð¿ÑÐ°Ð»ÒÐ°Ðœ. 
+</p>
+
+<p>
+<a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+class="logo"></a>
+<a href="http://www.unesco.org"><b>ÐÑÐ»ÑÐŒ Ð±ÐµÑÑ, ÒÑÐ»ÑÐŒ Ð¶ÓÐœÐµ ÐÓÐŽÐµÐœÐžÐµÑ ÐŒÓÑÐµÐ»ÐµÐ»ÐµÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÐÑÑÑÐºÐºÐµÐœ Ò°Ð»ÑÑÐ°Ñ Ò°Ð¹ÑÐŒÑ (Ð®ÐÐÐ¡ÐÐ)</b></a>
+<br> Ð±Ò¯ÐºÑÐ» ÓÐ»ÐµÐŒÐŽÐµÐ³Ñ, ÓÑÑÑÐµÑÐµ ÐŽÐ°ÐŒÑÒÐ°Ðœ ÐŒÐµÐŒÐ»ÐµÐºÐµÑÑÐµÑÐŽÐµÐ³Ñ Ð±ÑÐ»ÑÐŒ Ð±ÐµÑÑ, ÒÑÐ»ÑÐŒ Ð¶ÓÐœÐµ ÐŒÓÐŽÐµÐœÐžÐµÑÑÐµÐ³Ñ Ð°ÒÐ¿Ð°ÑÐ°ÑÑÑ ÑÐ°ÑÐ°ÑÑ ÐŒÐµÐœ ÐŸÐœÑ Ð°Ð»Ñ "ÐÐ°ÑÐ»ÑÒÑÐœÐ° Ð°ÑÐœÐ°Ð»ÒÐ°Ðœ ÐÒÐ¿Ð°ÑÐ°Ñ" Ò¯ÐºÑÐŒÐµÑÐ°ÑÐ°Ð»ÑÒ ÐÐ°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° ÑÐµÒ£Ð±ÐµÑÑÐœÐŽÐµ Ð¶ÐµÑÐµÑÑÐœ Ð®ÐÐÐ¡ÐÐ-ÐœÑÒ£ Ð±Ð°ÑÑÑ ÐŒÐ°ÒÑÐ°ÑÑ Ð±ÐŸÐ»ÑÐ¿ ÑÐ°Ð±ÑÐ»Ð°ÐŽÑ. ÐÒÐ¿Ð°ÑÐ°ÑÑÑÒ-ÒÐ°ÑÑÐœÐ°ÑÑÑÒ Ð¢ÐµÑ
+ÐœÐŸÐ»ÐŸÐ³ÐžÑÐ»Ð°Ñ ÒÒ±ÑÐ°Ð»ÐŽÐ°ÑÑÐœÐ° ÑÓÐ¹ÐºÐµÑ Ð°ÒÐ¿Ð°ÑÐ°Ñ Ð¿ÐµÐœ ÐŸÒÐ°Ðœ ÐºÑÑÑ, Ð±ÐµÑÑÐ»Ð³ÐµÐœ ÐŒÓÑÑÐœÐŽÐµ ÐŒÐ°Ò£ÑÐ·ÐŽÑ ÒÒ±ÑÐ°Ð»ÐŽÐ°Ñ Ð±ÐŸÐ»ÑÐ¿ ÑÐ°Ð±ÑÐ»Ð°ÐŽÑ. 
+</p>
+
+<p>
+<a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b> ÐÐœÑÐ²ÐµÑÐ¿ÐµÐœÐµ, ÐÐµÐ»ÑÐ³ÐžÑÐŽÐ°ÒÑ ÐÐÐ ÐÐŽÐ°ÐŒÐ·Ð°Ñ ÐÒÐ¿Ð°ÑÐ°ÑÑ</b></a>
+<br>
+ÐÒ±Ð» Ð¶ÐŸÐ±Ð° ÐÒ°Ò° Ð°Ð³ÐµÐœÑÑÑÐºÑÐµÑÑÐŒÐµÐœ Ð¶ÓÐœÐµ Ð±Ð°ÑÒÐ° ÐŽÐ° Ò¯ÐºÑÐŒÐµÑÑÑÐº ÐµÐŒÐµÑ Ò±Ð¹ÑÐŒÐŽÐ°ÑÐŒÐµÐœ Ð¶Ò±ÐŒÑÑ ÑÑÑÐµÐ¹ÐŽÑ, Ð°ÐŽÐ°ÐŒÐ·Ð°Ñ ÐŽÐ°ÐŒÑÑÐœÐ° ÑÒÐ¿Ð°Ð» ÐµÑÐµÑÑÐœ ÑÐ°ÐœÐŽÑÒ ÒÒ±Ð¶Ð°ÑÑÐ°Ñ ÑÐ°Ð»Ð°ÑÑÐœÐŽÐ° Ð¶ÐŸÒÐ°ÑÑ ÓÐ»ÐµÐŒÐŽÑÐº Ð°ÑÐ°ÒÒÐ° ÑÐ»ÑÐºÐºÐµÐœ Ð¶ÓÐœÐµ  ÐŸÐ» Ð±ÓÑÑÐœÐµ ÒÐŸÐ»Ð°Ð¹Ð»Ñ, Ð±Ð°ÑÒÐ°Ð»Ð°ÑÐŽÑÒ£ ÑÑÒÑÐœÑÐœ ÑÓ©Ð»ÐµÑ ÓÐŽÑÑÑÐŒÐµÐœ ÐŽÐ°ÐŒÑÐ¿ ÐºÐµÐ»Ðµ Ð¶Ð°ÑÒÐ°Ðœ ÐŒÐµÐŒÐ»ÐµÐºÐµÑÑÐµÑÐ³Ðµ ÑÐµÐ³ÑÐœ Ð±ÐŸÐ»Ð°ÐŽÑ. </p>}  
+
+
+_textdescrselcol_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ ÑÐ°Ò£ÐŽÐ°Ò£ÑÐ·}
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=kk] {ÐÑÑÐœÐŽÐ° Ð¶ÓÐœÐµ Ð±Ò±ÐŽÐ°Ðœ Ð±ÑÐ»Ð°Ð¹ Ð±Ð°ÑÑÐ°Ð¿ÒÑ Ð¿Ð°ÑÐ°ÒÑÐ° 4 Ð±Ð°ÑÑÑÐŒÐ° ÒÐŸÐ»ÐŽÐ°ÐœÑÐ»Ð°ÐŽÑ}
+
+_textnocollections_ [l=kk] {<p> ÒÐ°Ð·ÑÑÐ³Ñ ÑÐ°ÒÑÑÑÐ° Ð±Ò±Ð» Greenstone ÐŸÑÐœÐ°ÑÑÐ»ÑÐŒÑÐœÐŽÐ° ÒÐŸÐ»ÐŽÐ°ÐœÑÐ»Ð°ÑÑÐœ ÐµÑÐ±ÑÑ ÐÐžÐœÐ°Ò Ð¶ÐŸÒ. ÐÐµÐ¹Ð±ÑÑ ÐÐžÐœÐ°ÒÑÐ°ÑÐŽÑ ÒÐŸÑÑ Ò¯ÑÑÐœ Ð¡ÑÐ· - <ul><li> Ð¶Ð°Ò£Ð° ÐÐžÐœÐ°Ò ÒÒ±ÑÑ Ò¯ÑÑÐœ <href = "_httppagecollector _ ">ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑÐŽÑ</a> Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÒ£ÑÐ· <li> Greenstone CD-ROM-Ñ Ð±ÐŸÐ»ÑÐ°, CD-ROM-ÐœÐ°Ðœ ÐÐžÐœÐ°Ò ÐŸÑÐœÐ°ÑÐ° Ð°Ð»Ð°ÑÑÐ·
+</ul>}
+
+_text1coll_ [l=kk] {Greenstone ÐŸÑÐœÐ°ÑÑÐ»ÑÐŒÑÐœÐŽÐ° 1 ÐÐžÐœÐ°Ò Ð±Ð°Ñ}
+
+_textmorecolls_ [l=kk] {Greenstone ÐŸÑÐœÐ°ÑÑÐ»ÑÐŒÑÐœÐŽÐ°  _1_ ÐÐžÐœÐ°Ò Ð±Ð°Ñ}
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=kk] {Ð¡ÑÑÑÒÑ ÑÑÐ»ÑÐµÐŒÐµ}
+_textlinknotfound_ [l=kk] {ÐÑÐºÑ ÑÑÐ»ÑÐµÐŒÐµ ÑÐ°Ð±ÑÐ»ÒÐ°Ðœ Ð¶ÐŸÒ}
+
+_textextlinkcontent_ [l=kk] {<p>Ð¢Ð°Ò£ÐŽÐ°ÒÐ°Ðœ ÑÑÐ»ÑÐµÐŒÐµÒ£ÑÐ· ÐºÐµÐ· ÐºÐµÐ»Ð³ÐµÐœ ÒÐ°Ð·ÑÑ ÑÐ°Ò£ÐŽÐ°Ð»ÒÐ°Ðœ ÐÐžÐœÐ°Ò Ò¯ÑÑÐœ ÑÑÑÑÒÑ. ÐÐ³ÐµÑ Ð¡ÑÐ· Ð±Ò±Ð» ÑÑÐ»ÑÐµÐŒÐµ Ð±ÐŸÐ¹ÑÐœÑÐ° Ð°ÑÑÑÒÑÒ£ÑÐ· ÐºÐµÐ»ÑÐµ Ð¶ÓÐœÐµ ÐŽÐµ Ð±ÑÐ°ÑÐ·ÐµÑÑÒ£ÑÐ·ÐŽÑÒ£ ÐÐœÑÐµÑÐœÐµÑ Ð¶Ò¯Ð¹ÐµÑÑÐœÐµ ÒÐŸÑÑÐ»Ñ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐ³Ñ Ð±ÐŸÐ»ÑÐ°, ÐŸÐ¹ÐŽÐ°ÒÑÐŽÐ°Ð¹ <a href="_nexturl_">  Ð¿Ð°ÑÐ°ÒÑÐœÐ° Ð°ÑÑÑÐ° Ð±ÐµÑÑÒ£ÑÐ· </a>; ÐœÐµÐŒÐµÑÐµ Ð°Ð»ÐŽÑÒ£ÒÑ ÒÒ±Ð¶Ð°ÑÒÐ° ÒÐ°Ð¹ÑÐ° ÐŸÑÐ°Ð»Ñ Ò¯ÑÑÐœ, "back/Ð°ÑÑÒÐ°" Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ·.}
+
+_textlinknotfoundcontent_ [l=kk] {ÐÑÐ·ÐŽÑÒ£ Ð±Ð°ÒÑÐ»Ð°ÑÑÐŒÑÐ·ÐŽÐ°Ðœ ÑÑÑ ÑÐµÐ±ÐµÐ¿ÑÐµÑÐŽÐµÐœ, Ð¡ÑÐ· ÑÐ°Ò£ÐŽÐ°ÒÐ°Ðœ ÑÑÐºÑ ÑÑÐ»ÑÐµÐŒÐµ Ð¶ÐŸÒ. ÐÒ¯ÐŒÐºÑÐœ Ð±Ò±Ð» Ð±Ð°ÑÑÐ°Ð¿ÒÑ ÐÐžÐœÐ°ÒÑÑÒ£ ÒÐ°ÑÐµÑÑÐœÐµ Ð±Ð°Ð¹Ð»Ð°ÐœÑÑÑÑ ÑÑÒÐ°Ñ. ÐÐ»ÐŽÑÒ£ÒÑ ÒÒ±Ð¶Ð°ÑÒÐ° ÒÐ°Ð¹ÑÐ° ÐŸÑÐ°Ð»Ñ Ò¯ÑÑÐœ "back" Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ ÒÐŸÐ»ÐŽÐ°ÐœÑÒ£ÑÐ·.}
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=kk] {" _2 _ " Ð¶ÐžÐœÐ°ÒÑÐœÐ° ÑÑÐ»ÑÐµÐŒÐµ
+Ð¡ÑÐ· ÑÐ°Ò£ÐŽÐ°ÒÐ°Ðœ ÑÑÐ»ÑÐµÐŒÐµ " _collectionname _ " Ð¶ÐžÐœÐ°ÒÒÐ° ÑÑÑÑÒÑ Ð±ÐŸÐ»ÑÐ¿ ÑÐ°Ð±ÑÐ»Ð°ÐŽÑ (ÐŸÐ» " _2 _ " Ð¶ÐžÐœÐ°ÒÑÐŒÐµÐœ Ð±Ð°Ð¹Ð»Ð°ÐœÑÑÑÑ). ÐÐ³ÐµÑ ÑÑÐ· ÐŸÑÑ ÑÑÐ»ÑÐµÐŒÐµ Ð°ÑÒÑÐ»Ñ  " _2 _ " Ð¶ÐžÐœÐ°ÒÑÐœÐ° Ó©ÑÐºÑÒ£ÑÐ· ÐºÐµÐ»ÑÐµ, ÐŸÐœÐŽÐ° ÑÑÐ· <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_"> Ð°ÑÑ ÒÐ°ÑÐ°Ð¹ ÐŒÑÐœÐ° Ð±ÐµÑÐºÐµ Ó©ÑÑÑÒ£ÑÐ·Ð³Ðµ Ð±ÐŸÐ»Ð°ÐŽÑ </a>; Ð±Ð°ÑÒÐ°ÑÐ° Ð°Ð»ÐŽÑÐœÒÑ ÒÒ±Ð¶Ð°ÑÒÐ° ÐŸÑÐ°Ð»Ñ Ò¯ÑÑÐœ ÑÑÐ·ÐŽÑÒ£ Ð±ÑÐ°ÑÐ·ÐµÑÑÒ£ÑÐ·ÐŽÐµÐ³Ñ "back/Ð°ÑÑÒÐ°" Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ ÒÐŸÐ»ÐŽÐ°ÐœÑÒ£ÑÐ·. }  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=kk] {Greenstone Ð¡Ð°ÐœÐŽÑÒ ÐÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÑÑ}
+
+_textusername_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ Ð°ÑÑ}
+_textpassword_ [l=kk] {ÐÐ°ÑÐŸÐ»Ñ}
+
+_textmustbelongtogroup_ [l=kk] {ÐÐ°Ð·Ð°Ñ Ð°ÑÐŽÐ°ÑÑÒ£ÑÐ·, Ð±Ò±Ð» Ð¿Ð°ÑÐ°ÒÒÐ° ÐºÑÑÑ Ò¯ÑÑÐœ Ð¡ÑÐ· "_cgiargug_" ÑÐŸÐ±ÑÐœÐ° Ð¶Ð°ÑÑÑÒ£ÑÐ· ÒÐ°Ð¶ÐµÑ.}
+
+_textmessageinvalid_ [l=kk] {Ð¡ÑÐ· ÑÒ±ÑÐ°ÒÐ°Ðœ Ð¿Ð°ÑÐ°Ò Ð°Ð²ÑÐŸÑÐžÐ·Ð°ÑÐžÑÐ»Ð°ÑÐŽÑ ÑÐ°Ð»Ð°Ð¿ ÐµÑÐµÐŽÑ.
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>) Greenstone-ÒÐ° ÐºÑÑÑ Ò¯ÑÑÐœ Ó©Ð·ÑÒ£ÑÐ·ÐŽÑÒ£ ÒÐŸÐ»ÐŽÐ°ÐœÐ°ÑÑÐœ Ð°ÑÑÒ£ÑÐ·ÐŽÑ Ð¶ÓÐœÐµ Ð¿Ð°ÑÐŸÐ»ÑÒ£ÑÐ·ÐŽÑ ÑÐµÑÑÒ£ÑÐ·. }
+
+_textmessagefailed_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ Ð°ÑÑ ÐœÐµÐŒÐµÑÐµ Ð¿Ð°ÑÐŸÐ»Ñ ÐŽÒ±ÑÑÑ ÑÐµÑÑÐ»ÐŒÐµÐ³ÐµÐœ.}
+
+_textmessagedisabled_ [l=kk] {ÐÐµÑÑÑÑÒ£ÑÐ·, Ð¡ÑÐ·ÐŽÑÒ£ ÐŒÓÐ»ÑÐŒÐµÑ Ð¶Ð°Ð·Ð±Ð°Ò£ÑÐ·ÒÐ°  ÑÐžÑÐŒ ÑÐ°Ð»ÑÐ»Ñ. ÐÑÑ ÑÐ°Ð¹ÑÑÑÒ£ Web-ÑÐµÐ±ÐµÑÑÐŒÐµÐœ Ð±Ð°Ð¹Ð»Ð°ÐœÑÑÑÒ£ÑÐ·.}
+
+_textmessagepermissiondenied_ [l=kk] {ÐÐµÑÑÑÑÒ£ÑÐ·, Ð¡ÑÐ· ÑÒ±ÑÐ°ÒÐ°Ðœ Ð¿Ð°ÑÐ°ÒÒÐ° ÐºÑÑÑ Ò¯ÑÑÐœ ÒÐ°Ð¶ÐµÑÑÑ Ó©ÐºÑÐ»ÐµÑÑÑÐ»ÑÐ³ÑÒ£ÑÐ· Ð¶ÐŸÒ.}
+
+_textmessagestalekey_ [l=kk] {Ð¡ÑÐ· Ð±Ð°ÑÑÐ¿ ÑÑÒÒÐ°Ðœ ÑÑÐ»ÑÐµÐŒÐµ Ð¶Ð°Ò£Ð°ÑÑÑÐ»ÐŽÑ. Ð¡Ò±ÑÐ°ÒÐ°Ðœ Ð¿Ð°ÑÐ°ÒÑÒ£ÑÐ·ÒÐ° ÐºÑÑÑ Ò¯ÑÑÐœ Ð¿Ð°ÑÐŸÐ»ÑÐŽÑ ÐµÐœÐ³ÑÐ·ÑÒ£ÑÐ·.}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=kk] {<br>
+ÐÒ±Ð» Greenstone ÐŸÑÐœÐ°ÑÑÐ»ÑÐŒÑÐœÐŽÐ° ÐµÑÒÐ°ÐœÐŽÐ°Ð¹ ÒÒ±Ð¶Ð°Ñ Ð±ÐµÑÑÐ»Ð³ÐµÐœ ÐµÐŒÐµÑ. ÐÒ¯ÐŒÐºÑÐœ ÑÐµÐ±ÐµÐ¿ÑÐµÑÑ:
+1. Greenstone ÑÒÑÐ°ÐŒÐŽÑ ÐŸÑÐœÐ°ÑÑ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÑÐœ ÒÐŸÐ»ÐŽÐ°ÐœÑÐ¿ CD-ROM-ÐœÐ°Ðœ ÐŸÑÐœÐ°ÑÑÐ»ÒÐ°Ðœ.
+2. Greenstone ÐÐœÑÐµÑÐœÐµÑ Ð¶Ò¯Ð¹ÐµÑÑ Ð°ÑÒÑÐ»Ñ Ð¶Ò¯ÐºÑÐµÐ»Ð³ÐµÐœ ÐŽÐžÑÑÑÐžÐ±ÑÑÐžÐ²ÑÐµÑÐŽÑ ÒÐŸÐ»ÐŽÐ°ÐœÑÐ¿ ÐŸÑÐœÐ°ÑÑÐ»ÒÐ°Ðœ. 
+ÐÐµÐ³ÐµÐœÐŒÐµÐœ ÐŽÐµ, Ð¡ÑÐ· ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ CD-ROM-ÐœÑÒ£ docs ÐŽÐžÑÐµÐºÑÐŸÑÐžÐ¹ÑÐœÐµÐœ ÐœÐµÐŒÐµÑÐµ <a href=" http://www.greenstone.org "> http://www.greenstone.org </a> ÑÐ°Ð¹ÑÑÐœÐ°Ðœ ÑÐ°Ð±Ð° Ð°Ð»Ð°ÑÑÐ·.}
+
+_textuserguide_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÒÐ° Ð°ÑÐœÐ°Ð»ÒÐ°Ðœ ÐœÒ±ÑÒÐ°Ñ}
+_textinstallerguide_ [l=kk] {ÐÐœÑÑÐ°Ð»Ð»ÑÑÐžÑÐ»Ð°ÑÒÐ° Ð°ÑÐœÐ°Ð»ÒÐ°Ðœ ÐœÒ±ÑÒÐ°Ñ}
+_textdeveloperguide_ [l=kk] {ÐÐ°ÑÐ°ÑÑÑÒÐ° Ð°ÑÐœÐ°Ð»ÒÐ°Ðœ ÐœÒ±ÑÒÐ°Ñ}
+_textpaperguide_ [l=kk] {"ÒÐ°ÒÐ°Ð·ÐŽÐ°Ðœ ÐÐžÐœÐ°ÒÒÐ°" ÐœÒ±ÑÒÐ°ÑÑ}
+_textorganizerguide_ [l=kk] {ÐÑÐ³Ð°ÐœÐ°Ð¹Ð·ÐµÑÐŽÑ ÒÐŸÐ»ÐŽÐ°ÐœÑ}
+
+_textgsdocstitle_ [l=kk] {greenstone ÒÒ±Ð¶Ð°ÑÑ}
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐœÑ ÒÒ±ÑÑ}  
+_textbildsuc_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐœÓÑÐžÐ¶ÐµÐ»Ñ ÒÒ±ÑÑÐ»ÐŽÑ.}  
+_textviewbildsummary_ [l=kk] {ÐÒ¯ÐŒÐºÑÐœ ÑÑÐ· <a href="_httppagex_(bsummary)" target=_top> ÐŸÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐœÑÒ£ ÒÒ±ÑÑÐ»ÑÑÐœÑÒ£ ÐŒÒ±ÒÐžÑÑ ÐŒÓÐ»ÑÐŒÐµÑÑÐœ </a>ÐºÓ©ÑÐ³ÑÒ£ÑÐ· ÐºÐµÐ»ÐµÐŽÑ.
+}  
+_textview_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐœÑ ÒÐ°ÑÐ°Ñ}  
+
+_textbild1_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÒÐ°Ð·ÑÑ ÒÒ±ÑÑÐ»ÑÐŽÐ°: ÐŸÐ» Ð±ÑÑÐ°Ð· ÑÐ°ÒÑÑÑÑ Ð°Ð»Ð°ÐŽÑ.
+Ð¡ÑÐ°ÑÑÑ Ð¶ÐŸÐ»Ñ ÒÒ±ÑÑÐ»Ñ Ð¿ÑÐŸÐ³ÑÐµÑÑÐœ ÐºÓ©ÑÑÐµÑÑÐŽÐµ
+}  
+
+_textbild2_ [l=kk] {ÒÒ±ÑÑÐ»ÑÐŒÐŽÑ ÐºÐµÐ· ÐºÐµÐ»Ð³ÐµÐœ ÑÐ°ÒÑÑÑÐ° ÑÐŸÒÑÐ°ÑÒÑÒ£ÑÐ· ÐºÐµÐ»ÑÐµ, ÐŒÑÐœÐ° Ð¶ÐµÑÐ³Ðµ Ð±Ð°ÑÑÒ£ÑÐ·. <br> Ð¡ÑÐ· Ð¶Ò±ÐŒÑÑ Ð¶Ð°ÑÐ°Ð¿ Ð¶Ð°ÑÒÐ°Ðœ Ð¶ÐžÐœÐ°Ò Ð±Ò±Ð·ÑÐ»ÐŒÐ°Ð¹ÐŽÑ. 
+}  
+
+_textstopbuild_ [l=kk] {ÒÒ±ÑÑÐŽÑ ÑÐŸÒÑÐ°ÑÑ}  
+
+_textbild3_ [l=kk] {ÐÐ³ÐµÑ ÑÑÐ· Ð±Ò±Ð» Ð±ÐµÑÑÑ ÑÐ°ÑÑÐ°Ð¿ ÐºÐµÑÑÐµÒ£ÑÐ· (ÒÒ±ÑÑÐ»ÑÐŽÑ ÑÐŸÒÑÐ°ÑÑ ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÐ¿Ð°Ð¹) ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐœÑ ÒÒ±ÑÑ Ò¯ÑÐŽÑÑÑ Ð¶Ð°Ð»ÒÐ°ÑÐ°ÐŽÑ Ð¶ÓÐœÐµ ÐœÓÑÐžÐ¶ÐµÐ»Ñ Ð°ÑÒÑÐ°Ð»ÒÐ°Ðœ Ð¶Ð°ÒÐŽÐ°Ð¹ÐŽÐ°, ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÐŽÐ° ÐŸÑÐœÐ°Ð»Ð°ÑÑÑÑÑÐ»Ð°ÐŽÑ.}  
+
+_textbuildcancelled_ [l=kk] {ÒÒ±ÑÑ Ð¶ÐŸÒÒÐ° ÑÑÒÐ°ÑÑÐ»ÐŽÑ}  
+
+_textbildcancel1_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐœÑ ÒÒ±ÑÑ Ò¯ÑÐŽÑÑÑ Ò¯Ð·ÑÐ»ÐŽÑ. ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÒÒ±ÑÑÐŽÑ ÒÐ°Ð¹ÑÐ° Ð¶Ò¯ÑÐ³ÐµÐ·Ñ Ð¶ÓÐœÐµ Ó©Ð·Ð³ÐµÑÑÑÑÐµÑ ÐµÐœÐ³ÑÐ·Ñ Ò¯ÑÑÐœ, ÑÓ©ÐŒÐµÐœÐŽÐµ ÐŸÑÐœÐ°Ð»ÑÑÒÐ°Ðœ ÑÐ°ÑÑ ÐºÐœÐŸÐ¿ÐºÐ°ÐœÑ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÒ£ÑÐ·.}  
+
+_textbsupdate1_ [l=kk] {ÒÒ±ÑÑ ÑÑÐ°ÑÑÑÑ 1 ÑÐµÐºÑÐœÐŽ ÑÑÑÐœÐŽÐµ Ð¶Ð°Ò£Ð°ÑÐ°ÐŽÑ}  
+_textbsupdate2_ [l=kk] {ÐÑÑÐœÐŽÐµ ÒÒ±ÑÑ ÑÑÐ°ÑÑÑÑ Ð¶Ð°Ò£Ð°ÑÐ°ÐŽÑ}  
+_textseconds_ [l=kk] {ÑÐµÐºÑÐœÐŽÑÐ°Ñ}  
+
+_textfailmsg11_ [l=kk] {ÐÐµÑÑÐ»Ð³ÐµÐœÐŽÐµÑ Ð¶ÐŸÒ Ð±ÐŸÐ»ÒÐ°ÐœÐŽÑÒÑÐ°Ðœ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÒÒ±ÑÑÐ»Ð° Ð°Ð»ÐŒÐ°Ð¹ÐŽÑ. ÐÓ©ÑÑÐµÑÑÐ»Ð³ÐµÐœ ÐŽÐžÑÐµÐºÑÐŸÑÐžÑÐ»Ð°Ñ ÐœÐµÐŒÐµÑÐµ ÑÐ°Ð¹Ð»ÐŽÐ°ÑÐŽÑÒ£ ÐºÐµÐŒ ÐŽÐµÐ³ÐµÐœÐŽÐµ Ð±ÑÑÐµÑÑÐœÑÒ£ <i> Ð±ÐµÑÑÐ»Ð³ÐµÐœ ÐºÓ©Ð·ÐŽÐµÑÐŽÐµ </i>Ð±Ð°ÑÐµÐºÐµÐœÑÐœÐµ Ð¶ÓÐœÐµ ÐÑÐžÐœÑÑÐŸÑÐœ Ó©Ò£ÐŽÐµÐ¹ Ð°Ð»Ð°ÑÑÐœ Ð±ÐµÑÑÐ»Ð³ÐµÐœÐŽÐµÑ ÑÐžÐ¿Ñ Ð±Ð°Ñ ÐµÐºÐµÐœÑÐœÐµ ÐºÓ©Ð· Ð¶ÐµÑÐºÑÐ·ÑÒ£ÑÐ·.
+}  
+
+_textfailmsg21_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÒÒ±ÑÑÐ»Ð° Ð°Ð»ÐŒÐ°Ð¹ÐŽÑ Ó©Ð¹ÑÐºÐµÐœÑ import.pl
+ÒÐ°ÑÐµÐœÑ Ð±ÐµÑÐŽÑ.
+}  
+_textfailmsg31_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÒÒ±ÑÑÐ»Ð° Ð°Ð»ÐŒÐ°Ð¹ÐŽÑ (builtcol.pl ÒÐ°ÑÐµÐœÑ Ð±ÐµÑÐŽÑ)}  
+_textfailmsg41_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐœÓÑÐžÐ¶ÐµÐ»Ñ ÒÒ±ÑÐ°Ð»ÐŽÑ, Ð±ÑÑÐ°Ò ÒÐŸÐœÐŽÑÑÑÐ»ÐŒÐ°ÐŽÑ.}  
+_textfailmsg71_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐœÑ ÒÒ±ÑÑ ÐºÐµÐ·ÑÐœÐŽÐµ ÐŸÐ¹Ð»Ð°ÐŒÐ°ÒÐ°Ðœ ÒÐ°ÑÐµÐ»ÑÐº ÑÑÑÐœÐŽÐ°ÐŽÑ.}  
+
+
+_textblcont_ [l=kk] {ÒÒ±ÑÑ Ð¶ÑÑÐœÐ°Ð»ÑÐœÐŽÐ° ÐºÐµÐ»ÐµÑÑ Ð°ÒÐ¿Ð°ÑÐ°Ñ Ð±Ð°Ñ:}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=kk] {Ò®ÐœÑÑÐ· ÒÒ±ÑÑÐ»ÑÐŒ}
+_textmore_ [l=kk] {Ð¢ÐŸÐ»ÑÒÑÑÐ°Ò}
+_textinfo_ [l=kk] {ÐÐžÐœÐ°Ò ÐŒÓÐ»ÑÐŒÐµÑÑÐµÑÑ}
+_textsrce_ [l=kk] {ÐÐ°ÑÑÐ°Ð¿ÒÑ ÐŒÓÐ»ÑÐŒÐµÑÐµÑ}
+_textconf_ [l=kk] {ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÑÑÑ}
+_textdel_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐœÑ Ð¶ÐŸÑ}  
+_textexpt_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ ÑÐºÑÐ¿ÐŸÑÑÑÐ°Ñ}
+
+_textdownloadingfiles_ [l=kk] {Ð€Ð°Ð¹Ð»ÐŽÐ°ÑÐŽÑ ÒÐ°Ð±ÑÐ»ÐŽÐ°Ñ...}
+_textimportingcollection_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ ÐžÐŒÐ¿ÐŸÑÑÑÐ°Ñ...}
+_textbuildingcollection_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ ÒÒ±ÑÑ...}
+_textcreatingcollection_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ ÒÒ±ÑÑ...}
+
+_textcollectorblurb_ [l=kk] {<i>ÒÐ°Ð»Ð°ÐŒ ÒÑÐ»ÑÑÑÐ°Ðœ ÐŒÑÒÑÑÑÐ°Ò!
+<br> ÐÒÐ¿Ð°ÑÐ°ÑÑÑÒ ÐÐžÐœÐ°ÒÑÐ°ÑÐŽÑ ÒÒ±ÑÑ Ð¶ÓÐœÐµ ÑÐ°ÑÐ°ÑÑ Ð¶Ð°ÑÐ°Ð¿ÐºÐµÑÑÑÐ»ÑÐºÑÑ ÑÐ°Ð»Ð°Ð¿ ÐµÑÐµÐŽÑ. Ð¡ÑÐ· ÐŒÒ±ÐœÑ Ð±Ð°ÑÑÐ°ÐŒÐ°ÑÑÐ°Ðœ Ð±Ò±ÑÑÐœ ÑÒ¯ÑÑÐœÑÑÒ£ÑÐ· ÐºÐµÑÐµÐº. 
+Ð ÐµÑÐŒÐž Ð±Ð°ÑÑÐ»ÑÐŒÐŽÐ°ÑÒÐ° Ð°Ð²ÑÐŸÑÐ»ÑÒ ÒÒ±ÒÑÒÑÐ°Ñ: Ð¡ÑÐ·Ð³Ðµ Ð±ÐµÑÑÐ»Ð³ÐµÐœ ÑÒ±ÒÑÐ°Ñ Ð±Ò±Ð» ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ Ð±Ð°ÑÒÐ° Ð±ÑÑÐµÑÐ³Ðµ Ð±ÐµÑÑÐ³Ðµ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐ³ÑÐœ ÑÐµÐºÑÐµÐ¹ÐŽÑ.
+ÓÐ»ÐµÑÐŒÐµÑÑÑÐº ÐœÐŸÑÐŒÐ°Ð»Ð°ÑÑ: ÐÐžÐœÐ°ÒÑÐ°Ñ ÒÒ±Ð¶Ð°ÑÑÑ Ò±ÑÑÐœÒÐ°Ðœ ÒÐŸÒÐ°ÐŒ ÑÒ±ÑÐ°ÐœÑÑÑÐœÐ° ÑÐ°Ð¹ Ð±ÐŸÐ»Ñ ÐºÐµÑÐµÐº.
+Ð­ÑÐžÐºÐ°Ð»ÑÒ ÐœÐŸÑÐŒÐ°Ð»Ð°ÑÑ: ÐºÐµÐ¹Ð±ÑÑ ÐœÓÑÑÐµÐ»ÐµÑÐŒÐµÐœ Ð±Ð°ÑÒÐ°Ð»Ð°ÑÐŽÑÒ£ ÒÐŸÐ»ÐŽÐ°ÐœÑÑÐœÐ° ÑÒ±ÒÑÐ°Ñ Ð±ÐµÑÑÐ»ÐŒÐµÐ¹ÐŽÑ.
+<br> ÐÒÐ¿Ð°ÑÐ°Ñ ÐºÒ¯ÑÑÐœÐµ ÑÐ°Ò Ð±ÐŸÐ»ÑÒ£ÑÐ·, ÐŸÐ¹Ð»Ð°ÐœÑÐ¿ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÒ£ÑÐ·.
+</i>
+}
+
+_textcb1_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ Ð¡ÑÐ·Ð³Ðµ Ð¶Ð°Ò£Ð° ÐÐžÐœÐ°ÒÑÐ°ÑÐŽÑ Ð¶Ð°ÑÐ°ÑÒÐ°, Ð±Ð°ÑÐ»Ð°ÑÑÐœ ÒÐŸÑÑÐ¿ Ð¶ÐµÑÑÐ»ÐŽÑÑÑÐ³Ðµ, Ó©Ð·Ð³ÐµÑÑÑÐ³Ðµ ÐœÐµÐŒÐµÑÐµ ÐŸÐ»Ð°ÑÐŽÑ ÐŒÒ¯Ð»ÐŽÐµ Ð¶ÐŸÑÒÐ° ÐºÓ©ÐŒÐµÐºÑÐµÑÐµÐŽÑ. ÐÒ±Ð» ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐºÑÐµÑÐŽÑ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑ Ò¯ÑÑÐœ, Ð¡ÑÐ· Ð±ÑÑÒÐ°ÑÐ°Ñ Web-Ð¿Ð°ÑÐ°ÒÑÐ°ÑÐŽÑÒ£ ÑÒ±ÑÐ°ÐœÑÑÑÐœ ÒÐ°ÐœÐ°ÒÐ°ÑÑÐ°ÑÐŽÑÑÑ ÐŒÐ°ÒÑÐ°ÑÑÐœÐŽÐ° ÒÐ°Ð¶ÐµÑÑÑ Ð°ÒÐ¿Ð°ÑÐ°Ñ Ð±ÐµÑÑÑÒ£ÑÐ· ÐºÐµÑÐµÐº.}
+
+_textcb2_ [l=kk] {ÐÒ£ Ð°Ð»ÐŽÑÐŒÐµÐœ ÐœÐµ ÑÑÑÐµÐ¹ÑÑÒ£ÑÐ·ÐŽÑ ÑÐµÑÑÑÒ£ÑÐ· ÐºÐµÑÐµÐº:}
+_textcnc_ [l=kk] {Ð¶Ð°Ò£Ð° ÐÐžÐœÐ°ÒÑÑ ÒÒ±ÑÑ}
+_textwec_ [l=kk] {ÐÐžÐœÐ°ÒÐ¿ÐµÐœ Ð¶Ò±ÐŒÑÑ Ð±Ð°ÑÑÐ°Ñ, ÐŒÓÐ»ÑÐŒÐµÑ ÒÐŸÑÑ ÐœÐµÐŒÐµÑÐµ Ð¶ÐŸÑ.}
+
+_textcb3_ [l=kk] {ÐÐ°Ò£Ð°ÐœÑ ÒÒ±ÑÑ ÐœÐµÐŒÐµÑÐµ Ð±Ð°ÑÑÐœ ÐŒÐŸÐŽÐžÑÐžÐºÐ°ÑÐžÑÐ»Ð°Ñ Ò¯ÑÑÐœ, Ð¡ÑÐ· Ð°Ð²ÑÐŸÑÐžÐ·Ð°ÑÐžÑÐ»Ð°Ñ Ð¿ÑÐŸÑÐµÐŽÑÑÐ°ÑÑÐœÐ°Ðœ Ó©ÑÑ ÐºÐµÑÐµÐºÑÑÐ·. ÐÒ±Ð» ÐºÐŸÐŒÐ¿ÑÑÑÐµÑÑÒ£ÑÐ·Ð³Ðµ Ð±Ð°ÑÒÐ°Ð»Ð°ÑÐŽÑÒ£ ÐºÑÑÑÐ¿, Ð¡ÑÐ·ÐŽÑÒ£ Ð°ÒÐ¿Ð°ÑÐ°ÑÑÐ°ÑÑÒ£ÑÐ·ÐŽÑ Ó©Ð·Ð³ÐµÑÑÑÐŽÐµÐœ ÐœÐµÐŒÐµÑÐµ Ð¶ÐŸÑÐŽÐ°Ðœ ÑÐ°ÒÑÐ°Ð¹ÐŽÑ. ÐÐ°Ð·Ð°Ñ Ð°ÑÐŽÐ°ÑÑÒ£ÑÐ·: ÒÐ°ÑÑÐ¿ÑÑÐ·ÐŽÑÐºÑÑ ÑÐ°ÒÑÐ°Ñ ÐŒÐ°ÒÑÐ°ÑÑÐœÐŽÐ° Ð¡ÑÐ· Ð°Ð²ÑÐŸÐŒÐ°ÑÑÑ ÑÒ¯ÑÐŽÐµ ÑÑÑÐºÐµÐ»ÐµÑÑÐ·, Ð°Ð» 30 ÐŒÐžÐœÑÑ Ð°ÑÒÐ°ÐœÐœÐ°Ðœ ÐºÐµÐ¹ÑÐœ Ð¡ÑÐ· Ð°Ð²ÑÐŸÑÐžÐ·Ð°ÑÐžÑÐ»Ð°Ñ Ð¿ÑÐŸÑÐµÐŽÑÑÐ°ÑÑÐœÐ°Ðœ ÒÐ°Ð¹ÑÐ°ÐŽÐ°Ðœ  Ó©ÑÑÑÒ£ÑÐ· ÒÐ°Ð¶ÐµÑ. ÐÑÑ Ð¶Ð°ÒÐŽÐ°Ð¹ÒÐ° Ò±ÑÑÑÐ°ÑÐ°Ò£ÑÐ· - ÑÐ°Ð±ÑÑÐ»ÑÒ ÑÐ°ÒÑÐ°Ò£ÑÐ·! â Ð¡ÑÐ·ÐŽÑ ÐºÑÑÑÐ³Ðµ ÒÐ°Ð¹ÑÐ°ÐŽÐ°Ðœ ÑÐ°ÒÑÑÐ°ÐŽÑ â Ð¡ÑÐ· ÑÐŸÐ» ÑÐŸÒÑÐ°ÒÐ°Ðœ Ð¶ÐµÑÑÒ£ÑÐ·ÐŽÐµÐœ Ð¶Ò±ÐŒÑÑÑÒ£ÑÐ·ÐŽÑ Ð¶Ð°Ð»ÒÐ°ÑÑÑÑÐ° Ð°Ð»Ð°ÑÑÐ·. }
+
+_textcb4_ [l=kk] {ÓšÐ·ÑÒ£ÑÐ·ÐŽÑÒ£ Greenstone ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ»ÑÒ Ð°ÑÑÒ£ÑÐ·ÐŽÑ Ð¶ÓÐœÐµ Ð¿Ð°ÑÐŸÐ»ÑÒ£ÑÐ·ÐŽÑ ÑÐµÑÑÐ¿, ÑÐ°ÑÑÐ°Ñ Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ·.}
+
+_textfsc_ [l=kk] {ÐÐ»ÐŽÑÐŒÐµÐœ Ð¡ÑÐ· Ð¶Ò±ÐŒÑÑ ÑÑÑÐµÐ³ÑÒ£ÑÐ· ÐºÐµÐ»ÐµÑÑÐœ ÐÐžÐœÐ°ÒÑÐ°ÑÐŽÑ Ð±ÐµÐ»Ð³ÑÐ»ÐµÒ£ÑÐ· (Ð¶Ð°Ð·ÑÐŽÐ°Ðœ ÒÐŸÑÒÐ°Ð»ÒÐ°Ðœ ÐÐžÐœÐ°ÒÑÐ°Ñ Ð±Ò±Ð» ÑÑÐ·ÑÐŒÐŽÐµ Ð¿Ð°Ð¹ÐŽÐ° Ð±ÐŸÐ»ÐŒÐ°Ð¹ÐŽÑ).}
+
+_textwtc_ [l=kk] {Ð¢Ð°Ò£ÐŽÐ°Ð»ÒÐ°Ðœ ÐÐžÐœÐ°ÒÐ¿ÐµÐœ Ð¡ÑÐ· ÐºÐµÐ»ÐµÑÑ Ð°ÐŒÐ°Ð»ÐŽÐ°Ñ Ð¶Ð°ÑÐ°Ð¹ Ð°Ð»Ð°ÑÑÐ·:}
+_textamd_ [l=kk] {ÒÐŸÑÑÐŒÑÐ° ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ ÒÐŸÑÑ Ð¶ÓÐœÐµ ÐÐžÐœÐ°ÒÑÑ ÒÐ°Ð¹ÑÐ° ÒÐ°Ð»ÑÐ¿ÑÐ°ÑÑÑÑÑ}
+_textetc_ [l=kk] {ÐÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÑÐ»ÑÒ ÑÐ°Ð¹Ð»ÐŽÐ°ÑÐŽÑ ÑÒ¯Ð·ÐµÑÑÐ¿,  ÐÐžÐœÐ°ÒÑÑ ÒÐ°Ð¹ÑÐ° ÒÐ°Ð»ÑÐ¿ÑÐ°ÑÑÑÑÑ}
+_textdtc_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ ÑÐŸÐ»ÑÒ  Ð¶ÐŸÑ}
+_textetcfcd_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ Ó©Ð·Ñ ÐŸÑÐœÐ°ÑÑÐ»Ð°ÑÑÐœ Windows CD-ROM-ÒÐ° Ð¶Ð°Ð·Ñ Ò¯ÑÑÐœ ÑÐºÑÐ¿ÐŸÑÑÑÐ°Ñ}
+_textcaec_ [l=kk] {ÐÒ±ÑÑÐœÐœÐ°Ðœ ÒÒ±ÑÑÐ»ÒÐ°Ðœ ÐÐžÐœÐ°ÒÑÑ Ó©Ð·Ð³ÐµÑÑÑ.}
+_textnwec_ [l=kk] {ÐÐ°Ð·Ñ ÑÒ±ÒÑÐ°ÑÑ Ð±ÐµÑÑÐ»Ð³ÐµÐœ ÐµÑÐ±ÑÑ ÐÐžÐœÐ°ÒÒÐ° ÒÐŸÐ» Ð¶ÐµÑÐºÑÐ·Ñ ÐŒÒ¯ÐŒÐºÑÐœ ÐµÐŒÐµÑ}
+_textcianc_ [l=kk] {ÐÐ°Ò£Ð° ÐÐžÐœÐ°ÒÑÑ ÒÒ±ÑÑ.}
+_texttsosn_ [l=kk] {ÐÐ°Ò£Ð° ÑÐ°ÐœÐŽÑÒ ÐÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ° ÐÐžÐœÐ°ÒÑÐœ Ð¶Ð°ÑÐ°ÑÒÐ° ÒÐ°Ð¶ÐµÑ ÒÐ°ÐŽÐ°ÐŒÐŽÐ°Ñ ÑÑÐ·Ð±ÐµÐ³Ñ:}
+_textsin_ [l=kk] {ÐÑÑÒ£ÑÐ·ÐŽÑ (Ð¶ÓÐœÐµ ÒÐŸÑÑÐŒÑÐ° ÐŒÓÐ»ÑÐŒÐµÑÑÑ) ÐºÓ©ÑÑÐµÑÑÒ£ÑÐ· }
+_textswts_ [l=kk] {ÐÐžÐœÐ°Ò ÒÒ±ÑÐ°Ð¹ÑÑÐœ ÐŽÐµÑÐµÐºÑÐµÑ ÐºÓ©Ð·ÑÐœ ÐºÓ©ÑÑÐµÑÑÒ£ÑÐ·}
+_textatco_ [l=kk] {ÐÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÑ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐºÑÐµÑÑÐœ Ó©Ð·Ð³ÐµÑÑÑ (ÑÐµÐº ÑÓÐ¶ÑÑÐžÐ±ÐµÐ»Ñ ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ»Ð°Ñ Ò¯ÑÑÐœ)}
+_textbtc_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ "ÒÐ°Ð»ÑÐ¿ÑÐ°ÑÑÑÑÑ" (ÑÓ©ÐŒÐµÐœÐœÐµÐœ ÒÐ°ÑÐ°)}
+_textpvyh_ [l=kk] {Ð¡ÑÐ·ÐŽÑÒ£ ÒÐŸÐ»ÐŒÐµÐœ Ð¶Ð°ÑÐ°ÒÐ°Ðœ ÐµÐœÐ±ÐµÐ³ÑÒ£ÑÐ·ÐŽÑ ÐŒÐ°ÒÑÐ°ÐœÑÑÐ¿ÐµÐœ ÒÐ°ÑÐ°Ò£ÑÐ·.}
+
+_texttfsiw_ [l=kk] {Ð¢Ó©ÑÑÑÐœÑÑ ÒÐ°ÐŽÐ°ÐŒ â ÐºÐŸÐŒÐ¿ÑÑÑÐµÑÑÒ£ÑÐ·ÐŽÑÒ£ Ð¶Ò±ÐŒÑÑÑ. "ÒÐ°Ð»ÑÐ¿ÑÐ°ÑÑÑÑÑ" Ò¯ÑÐŽÑÑÑ Ð±Ð°ÑÑÑÑÐœÐŽÐ° ÐºÐŸÐŒÐ¿ÑÑÑÐµÑ Ð±Ð°ÑÐ»ÑÒ ÐžÐœÐŽÐµÐºÑÑÐµÑÐŽÑ Ð¶Ð°ÑÐ°ÒÑÐ°Ð¿, ÑÐŸÐœÑÐŒÐµÐœ ÒÐ°ÑÐ°Ñ ÐºÐµÐ·ÐŽÐµÑÐµÑÑÐœ Ð±Ð°ÑÒÐ° ÐŽÐ° Ð°ÒÐ¿Ð°ÑÐ°ÑÑÐ°ÑÐŽÑ Ð¶ÐžÐœÐ°ÒÑÐ°Ð¹ÐŽÑ. Ð¡ÑÐ· ÑÐµÐº ÐºÐµÑÐµÐ³ÑÐœ  Ð°ÐœÑÒÑÐ°ÑÑÒ£ÑÐ· ÒÐ°Ð¶ÐµÑ.}
+
+_textadab_ [l=kk] {Ð¢Ó©ÐŒÐµÐœÐŽÐµ Ð¡ÑÐ·ÐŽÑÒ£ ÒÐ°Ð¹ ÐºÐµÐ·ÐµÒ£ÐŽÐµ Ð¶Ò¯ÑÐ³ÐµÐœÑÒ£ÑÐ·ÐŽÑ Ð°ÐœÑÒÑÐ°Ð¹ÑÑÐœ ÐŽÐžÐ°Ð³ÑÐ°ÐŒÐŒÐ° Ð¿Ð°Ð¹ÐŽÐ° Ð±ÐŸÐ»Ð°ÐŽÑ. ÐÐ°ÑÑÐ» Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°ÐœÑÒ£ ÐŸÑÑÐœÐŽÐ°Ð»Ñ ÑÑÐ·Ð±ÐµÐ³ÑÐœ Ð¶Ð°Ð»ÒÐ°ÑÑÑÑÑ Ò¯ÑÑÐœ Ð±Ð°ÑÐ°ÑÑÐ·. Ò®ÑÐŽÑÑÑÑÒ£ Ð¶Ò¯ÑÑÑÐœÐµ Ð±Ð°Ð¹Ð»Ð°ÐœÑÑÑÑ Ð±Ð°ÑÑÑÐŒÐ°ÐœÑÒ£ ÑÒ¯ÑÑ ÑÐ°ÑÑÒÐ° Ó©Ð·Ð³ÐµÑÐµÐŽÑ. ÐÐ»ÐŽÑÒ£ÒÑ Ð¿Ð°ÑÐ°ÒÒÐ° ÐŸÑÐ°Ð»Ñ Ò¯ÑÑÐœ ÐŽÐžÐ°Ð³ÑÐ°ÐŒÐŒÐ°ÐŽÐ°ÒÑ ÑÓÐ¹ÐºÐµÑ ÑÐ°ÑÑ Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÑÐ° Ð°Ð»Ð°ÑÑÐ·. }
+
+_textwyar_ [l=kk] {Ð¡Ð°ÐœÐŽÑÒ ÐÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ° ÐÐžÐœÐ°ÒÑÐœ Ð¶Ð°ÑÐ°ÑÐŽÑ Ð±Ð°ÑÑÐ°Ñ Ò¯ÑÑÐœ "ÐÐžÐœÐ°Ò ÐŒÓÐ»ÑÐŒÐµÑÑÐµÑÑ" Ð°ÑÑÑ Ð¶Ð°ÑÑÐ» Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ·!}
+
+_textcnmbs_ [l=kk] {ÐÐžÐœÐ°ÒÑÑÒ£ Ð°ÑÑ Ð°ÐœÑÒÑÐ°Ð»ÑÑ ÑÐžÑÑ}
+_texteambs_ [l=kk] {E-mail ÐŒÐµÐºÐµÐœ-Ð¶Ð°Ð¹ÑÐœÑÒ£ ÐºÓ©ÑÑÐµÑÑÐ»ÑÑ ÑÐžÑÑ}
+_textpsea_ [l=kk] {Ð-mail ÐŒÐµÐºÐµÐœ-Ð¶Ð°Ð¹ÑÐœ usename@domain Ò¯Ð»Ð³ÑÑÑ ÑÐžÑÒÑÑ ÐºÓ©ÑÑÐµÑÑÒ£ÑÐ·}
+_textdocmbs_ [l=kk] {ÐÐžÐœÐ°Ò ÑÐžÐ¿Ð°ÑÑÐ°ÐŒÐ°ÑÑÐœ Ð±ÐµÑÑÒ£ÑÐ·}
+
+_textwcanc_ [l=kk] {ÐÐ°Ò£Ð°ÐŽÐ°Ðœ ÐÐžÐœÐ°Ò ÒÒ±ÑÐ°ÑÑÑÑÒÐ°ÐœÐŽÐ°, Ð¡ÑÐ· Ð°Ð»ÐŽÑÐŒÐµÐœ Ð±Ð°ÑÑÐ°Ð¿ÒÑ ÐŒÓÐ»ÑÐŒÐµÑÑÐµÑ Ð¶Ð°Ð¹Ð»Ñ Ð°Ð·ÐŽÐ°ÒÐ°Ðœ Ð°ÒÐ¿Ð°ÑÐ°Ñ ÐµÒ£Ð³ÑÐ·ÑÑÒ£ÑÐ·  ÒÐ°Ð¶ÐµÑ. ÐÒ±Ð» ÑÑÐ°Ð¿ ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ Ð±Ð°ÒÑÐ»Ð°Ð¹ÑÑÐœ Web-Ð¿Ð°ÑÐ°ÒÑÐ°Ñ ÒÐ°ÑÐ°ÑÑ ÒÒ±ÑÑÐ»ÑÐŒÑÐœ Ð¶Ð°ÑÐ°ÒÑÐ°Ñ Ò¯ÑÑÐœ ÐºÐµÑÐµÐº. ÐÐ°ÑÐ°ÒÑÑÒ£ ÑÓ©ÐŒÐµÐœÐ³Ñ Ð¶Ð°ÒÑÐœÐŽÐ° Ð¡ÑÐ· Ð¿Ð°ÑÐ°ÒÑÐ°Ñ ÒÐ°ÑÐ°ÑÑÐœ Ò¯ÑÐŽÑÑ Ð°ÑÒÑÐ°Ð»ÒÐ°ÐœÑÐœÐ° ÐŽÐµÐ¹ÑÐœ ÐºÓ©ÑÐµ Ð°Ð»Ð°ÑÑÐ·.}
+
+_texttfc_ [l=kk] {ÐÐžÐœÐ°Ò Ð°ÑÐ°ÑÑ}
+
+_texttctiasp_ [l=kk] {ÐÐžÐœÐ°Ò ÑÐ°ÒÑÑÑÐ±Ñ â ÐŒÐ°Ð·ÐŒÒ±ÐœÑÐœ ÐžÐœÐŽÐµÐºÑÐ°ÑÐžÑÐ»Ð°Ñ Ò¯ÑÑÐœ ÑÐ°ÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÐœÑÒ£ Ð±Ð°ÑÐ»ÑÒ Ð¶ÐµÑÑÐœÐŽÐµ ÒÐŸÐ»ÐŽÐ°ÐœÑÐ»Ð°ÑÑÐœ ÑÒ¯Ð¹ÑÐœ ÑÑÐ°Ð·Ð°. ÐÑÑÐ°Ð»Ñ ÑÐ°ÒÑÑÑÐ¿: "Computer Science Technical Reports"  Ð¶ÓÐœÐµ  "Humanity Development Library"}
+
+_textcea_ [l=kk] {ÐÐ°Ð¹Ð»Ð°ÐœÑÑ e-mail:}
+
+_textteas_ [l=kk] {ÐÒ±Ð» ÑÐ»ÐµÐºÑÑÐŸÐœÐŽÑÒ ÐŒÐµÐºÐµÐœ-Ð¶Ð°Ð¹  ÐÐžÐœÐ°ÒÐ¿ÐµÐœ Ð±Ð°Ð¹Ð»Ð°ÐœÑÑ ÐŸÑÐœÐ°ÑÑÐŽÐ°ÒÑ Ð°Ð»ÒÐ°ÑÒÑ ÐœÒ¯ÐºÑÐµÑÑÐœ Ð°ÐœÑÒÑÐ°Ð¹ÐŽÑ. ÐÐ³ÐµÑ Greenstone Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°Ð»ÑÒ Ð¶Ð°Ð±ÐŽÑÒÑ Ð¿ÑÐŸÐ±Ð»ÐµÐŒÐ°ÐœÑ Ð°ÐœÑÒÑÐ°ÑÐ°, ÐŽÐžÐ°Ð³ÐœÐŸÑÑÐžÐºÐ°Ð»ÑÒ Ñ
+Ð°Ð±Ð°ÑÐ»Ð°ÐŒÐ° ÐºÓ©ÑÑÐµÑÑÐ»Ð³ÐµÐœ ÐŒÐµÐºÐµÐœ-Ð¶Ð°Ð¹ÒÐ° Ð¶ÑÐ±ÐµÑÑÐ»ÐµÐŽÑ. Ð­Ð»ÐµÐºÑÑÐŸÐœÐŽÑÒ ÐŒÐµÐºÐµÐœ-Ð¶Ð°Ð¹ÐŽÑ name@domain Ò¯Ð»Ð³ÑÑÑÐœÐµ ÑÐ°Ð¹ ÐºÓ©ÑÑÐµÑÑÒ£ÑÐ·.}
+
+_textatc_ [l=kk] {ÐÐžÐœÐ°Ò ÑÑÑÐ°Ð»Ñ:}
+
+_texttiasd_ [l=kk] {ÐÒ±Ð» ÐœÒ±ÑÒÐ°Ñ ÐŒÓÐ»ÑÐŒÐµÑÑÐµÑÐŽÑÒ£ ÐÐžÐœÐ°ÒÒÐ° ÐµÐœÐ³ÑÐ·ÑÐ»Ñ Ð¿ÑÐžÐœÑÐžÐ¿ÑÐœ ÑÐžÐ¿Ð°ÑÑÐ°Ð¹ÐŽÑ. ÐÒ±ÐœÑ ÐÐžÐœÐ°ÒÑÑ Ò±ÑÑÐœÒÐ°Ðœ ÐºÐµÐ·ÐŽÐµ Ð±ÑÑÑÐœÑÑ Ð¿Ð°ÑÐ°ÒÑÐ°Ðœ ÐºÓ©ÑÐµ Ð°Ð»Ð°ÑÑÐ·.}
+
+_textypits_ [l=kk] {ÐÑÐŸÑÐµÑÑ Ð±Ð°ÑÑÑÑÐœÐŽÐ°ÒÑ Ð¡ÑÐ·ÐŽÑÒ£ ÐŸÑÐœÑÒ£ÑÐ· ÑÓ©ÐŒÐµÐœÐŽÐµ ÑÑÑÐµÐ»ÐºÐ°ÐŒÐµÐœ Ð±ÐµÐ¹ÐœÐµÐ»ÐµÐœÐ³ÐµÐœ â ÐÐžÐœÐ°Ò ÐŒÓÐ»ÑÐŒÐµÑÑÐµÑÑ "ÐºÐµÐ·ÐµÒ£ÐŽÐµÑÑÐœ" Ð±ÑÐ»ÐŽÑÑÐ³ÐµÐœÑ. ÐÐ°ÑÑÐ» "Source data/Ð±Ð°ÑÑÐ°Ð¿ÒÑ ÐŒÓÐ»ÑÐŒÐµÑÑÐµÑ" Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð¶Ð°Ð»ÒÐ°ÑÑÑÑÑ Ò¯ÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ·.}
+
+_srcebadsources_ [l=kk] {Ð¡ÑÐ· ÐºÓ©ÑÑÐµÑÐºÐµÐœ ÐŽÐµÑÐµÐº ÐºÓ©Ð·ÐŽÐµÑÐŽÑÒ£ Ð±ÑÑÐµÑÑÐœÐµ ÐœÐµÐŒÐµÑÐµ ÐŸÐŽÐ°Ðœ ÐŽÐ° Ð±Ð°ÑÒÐ°Ð»Ð°ÑÑÐœÐ° ÒÐŸÐ» Ð¶ÐµÑÐºÑÐ·ÑÐ³Ðµ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐº Ð¶ÐŸÐº  (ÑÓ©ÐŒÐµÐœÐŽÐµ Ð±ÐµÐ»Ð³ÑÐ»ÐµÐœÐ³ÐµÐœ _iconcross_).
+<p>ÐÒ±Ð» ÐºÐµÐ»ÐµÑÑ ÑÐµÐ±ÐµÐ¿ÑÐµÑÐ³Ðµ Ð±Ð°Ð¹Ð»Ð°ÐœÑÑÑÑ:
+<ul>
+<li>FTP ÑÐ°Ð¹Ð»ÐŽÑÒ£, ÑÐ°Ð¹ÑÑÑÒ£ ÐœÐµÐŒÐµÑÐµ URL-ÐŽÑÒ£ Ð¶ÐŸÒÑÑÒÑ.
+<li>ÐÒ£ Ð°Ð»ÐŽÑÐŒÐµÐœ Ð¡ÑÐ· Ó©Ð·ÑÒ£ÑÐ·ÐŽÑÒ£ ÐÐœÑÐµÑÐœÐµÑ-ÒÑÐ·ÐŒÐµÑ Ð¿ÑÐŸÐ²Ð°Ð¹ÐŽÐµÑÑÒ£ÑÐ·Ð±ÐµÐœ dial-up Ð±Ð°Ð¹Ð»Ð°ÐœÑÑ ÐŸÑÐœÐ°ÑÑÑÒ£ÑÐ· ÐºÐµÑÐµÐº.
+<li>Ð¡ÑÐ· Ð¶ÐµÐ»ÑÐ»ÑÐº ÒÐŸÑÒÐ°ÐœÑÑ Ð¶Ò¯Ð¹ÐµÑÑ â firewall Ð°ÑÒÑÐ»Ñ URL-ÒÐ° ÒÐ°ÑÑÐœÐ°Ñ Ð¶Ð°ÑÐ°Ð¿ ÐºÓ©ÑÐµÑÑÐ· (ÑÑÑÑÒ£ ÐŒÓÐœÑ ÐÐœÑÐµÑÐœÐµÑÐºÐµ ÐºÑÑÐ³ÐµÐœÐŽÐµÐ³Ñ ÑÐžÑÒÑÑ ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ Ð°ÑÑÐœ Ð¶ÓÐœÐµ Ð¿Ð°ÑÐŸÐ»ÑÐŽÑ ÐµÐœÐ³ÑÐ·Ñ).
+</ul>
+<p>ÐÐ³ÐµÑ Ð±Ò±Ð» Ð¡ÑÐ· Ó©Ð· Ð±ÑÐ°ÑÐ·ÐµÑÑÒ£ÑÐ·ÐŽÐµÐœ ÐºÓ©ÑÐµ Ð°Ð»Ð°ÑÑÐœ URL Ð±ÐŸÐ»ÑÐ°, ÐŸÐœÐŽÐ° ÐŸÐ» Ð¶ÐµÑÐ³ÑÐ»ÑÐºÑÑ ÐºÑÑ-ÐºÓ©ÑÑÑÐŒÐµÐŽÐµÐœ ÑÑÒÑÑ ÐŒÒ¯ÐŒÐºÑÐœ. ÓšÐºÑÐœÑÑÐºÐµ ÐŸÑÐ°Ð¹, Ð±ÑÐ·ÐŽÑÒ£ Ð°Ð¹ÐœÐ°Ð»Ð°Ñ Ò¯ÑÐŽÑÑÑ Ò¯ÑÑÐœ Ð¶ÐµÑÐ³ÑÐ»ÑÐºÑÑ ÐºÑÑ-ÐºÓ©ÑÑÑÐŒÐµÐ»ÐµÑ ÐºÓ©ÑÑÐœÐ±ÐµÐ¹ÐŽÑ. ÐÒ±Ð» Ð¶Ð°ÒÐŽÐ°Ð¹ÐŽÐ° Ð±ÑÐ·, ÐµÒ£ Ð°Ð»ÐŽÑÐŒÐµÐœ Ð¡ÑÐ·ÐŽÐµÐœ Ð²ÐµÐ±-Ð¿Ð°ÑÐ°ÒÑÐ°ÑÐŽÑ Ð±ÑÐ°ÑÐ·ÐµÑÑÒ£ÑÐ·ÐŽÑ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÐ¿ Ð¶Ò¯ÐºÑÐµÑÐŽÑ ÑÒ±ÑÐ°Ð¹ÐŒÑÐ·.}
+
+_textymbyco_ [l=kk] {<p> Ð¡ÑÐ· Ð¶ÐžÐœÐ°ÒÑÒ£ÑÐ·ÐŽÑ ÐœÐµÐ³ÑÐ·ÐŽÐµÑÑÒ£ÑÐ·Ð³Ðµ Ð±ÐŸÐ»Ð°ÐŽÑ ÐœÐµÐŒÐµÑÐµ .... <ul>
+<li> ÐÐ°ÑÑÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÒÒ±ÑÑÐ»ÑÐŒ <dl><dd>  HTML ÒÒ±Ð¶Ð°ÑÑÐ° Ð¶Ð°Ò£Ð° Ð¶ÐžÐœÐ°Ò Ð±ÐŸÐ»ÑÑ ÐŒÒ¯ÐŒÐºÑÐœ(.htm.html),  Ð¶Ð°Ð¹ ÐŒÓÑÑÐœÐœÑÒ£ ÒÒ±Ð¶Ð°ÑÑ (.txt.text),  MS Word ÒÒ±Ð¶Ð°ÑÑÐ°ÑÑ(.doc), PDF ÒÒ±Ð¶Ð°ÑÑÐ°ÑÑ (.pdf) ÐœÐµÐŒÐµÑÐµ ÑÐ»ÐµÐºÑÑÐŸÐœÐŽÑ Ð¿ÐŸÑÑÐ° ÑÐŸÑÐŒÐ°ÑÑÐœÐŽÐ°ÒÑ ÒÒ±Ð¶Ð°ÑÑÐ°Ñ "m-box" (.mbx). </dd></dl>
+<li> ÐÐ°Ñ Ð¶ÐžÐœÐ°ÒÐ»Ð°Ñ 
+<dl><dd> Ð¡ÑÐ·ÐŽÑÒ£ Ð¶Ð°Ò£Ð° Ð¶ÐžÐœÐ°ÒÑÐ°ÑÑÒ£ÑÐ·ÐŽÐ°ÒÑ ÑÐ°Ð¹Ð»ÐŽÐ°Ñ Ð±Ð°Ñ Ð¶ÐžÐœÐ°ÒÑÑÒ£ ÒÒ±ÑÑÐ»ÑÐŒÑÐœÐ° Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÐ»ÒÐ°Ðœ ÑÐ°Ð¹Ð»ÐŽÐ°Ñ ÑÐžÐ¿ÑÐœÐµ Ò±ÒÑÐ°Ñ Ð±ÐŸÐ»ÑÑ ÐºÐµÑÐµÐº. </dd> </dl>
+</ul>}  
+
+_textbtco_ [l=kk] {ÐÐžÐœÐ°Ò ÒÒ±ÑÑÐ»ÐŽÑ}
+_textand_ [l=kk] {ÐÐ°Ò£Ð° ÐŒÓÐ»ÑÐŒÐµÑÑÐµÑÐŽÑ ÒÐŸÑÑ}
+_textad_ [l=kk] {ÒÐŸÑÑÐŒÑÐ° ÐŒÓÐ»ÑÐŒÐµÑÑÐµÑ:}
+
+_texttftysb_ [l=kk] {<p> Ð¢Ó©ÐŒÐµÐœÐŽÐµ Ð±ÐµÐ»Ð³ÑÐ»ÐµÐœÐµÑÑÐœ ÑÐ°Ð¹Ð»ÐŽÐ°ÑÑÒ£ÑÐ· ÐÐžÐœÐ°ÒÒÐ° ÒÐŸÑÑÐ»Ð°ÐŽÑ. ÐÐžÐœÐ°ÒÑÐ° ÐºÐµÐ·ÐŽÐµÑÐµÑÑÐœ ÑÐ°Ð¹Ð»ÐŽÐ°ÑÐŒÐµÐœ ÑÐ°ÑÐ°ÑÑÑÑÑÐ¿ Ð°Ð»ÐŒÐ°ÑÑÑÑÐŒÐ°Ñ Ò¯ÑÑÐœ, ÑÐµÐºÑÐµÑÐ³ÐµÐœÑÒ£ÑÐ· Ð¶Ó©Ðœ. ÓÐ¹ÑÐ¿ÐµÑÐµ ÐµÐºÑ Ð±ÑÑÐŽÐµÐ¹ ÐºÓ©ÑÑÑÐŒÐµ ÐÐžÐœÐ°ÒÒÐ° ÒÐŸÑÑÐ»ÑÑ ÐŒÒ¯ÐŒÐºÑÐœ. Ð€Ð°Ð¹Ð»ÐŽÐ°Ñ ÑÐŸÐ»ÑÒ Ð°ÑÑÐŒÐµÐœ Ð¶ÓÐœÐµ ÐŸÑÐœÐ°Ð»Ð°ÑÒÐ°Ðœ ÐŸÑÐœÑÐŒÐµÐœ, Web-Ð¿Ð°ÑÐ°ÒÑÐ°Ñ Ð°Ð±ÑÐŸÐ»ÑÑÑÑÐº Web-ÐŒÐµÐºÐµÐœ Ð¶Ð°Ð¹ÑÐŒÐµÐœ ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐžÑÐ»Ð°ÐœÑÑ ÐºÐµÑÐµÐº.}
+
+_textis_ [l=kk] {ÐÑÑÑ ÐŽÐµÑÐµÐº ÐºÓ©Ð·ÐŽÐµÑÑ:}
+
+_textddd1_ [l=kk] {<p> ÐÐ³ÐµÑ Ð¡ÑÐ· file:// ÐœÐµÐŒÐµÑÐµ ftp:// ÑÐ°Ð¹Ð»ÐŽÑ Ð°ÐœÑÒÑÐ°Ñ Ò¯ÑÑÐœ ÒÐŸÐ»ÐŽÐ°ÐœÑÐ°Ò£ÑÐ·, Ð±Ò±Ð» ÑÐ°Ð¹Ð» ÒÐ°Ð±ÑÐ»ÐŽÐ°ÐœÐ°ÐŽÑ.
+
+<p> http:// ÒÐŸÐ»ÐŽÐ°ÐœÑ Ð±ÑÐ°ÑÐ·ÐµÑÐŽÑ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÐŽÐ°ÒÑ Ð²ÐµÐ±-Ð¿Ð°ÑÐ°ÒÑÐ°ÑÐŽÑÒ£ ÐœÐµÐŒÐµÑÐµ ÑÐ°Ð¹Ð»ÐŽÐ°Ñ ÑÑÐ·ÑÐŒÑÐœÑÒ£ ÐºÓÐŽÑÐŒÐ³Ñ Ð±ÐµÐ¹ÐœÐµÐ»ÐµÑÑÐœ Ð±ÐµÑÐµÑÑÐœ URL-ÒÐ° Ð±Ð°Ð¹Ð»Ð°ÐœÑÑÑÑ Ð±ÐŸÐ»Ð°ÐŽÑ. ÐÐ³ÐµÑ Ð¿Ð°ÑÐ°Ò Ð±ÐŸÐ»ÑÐ° - ÐŸÐ» ÒÐ°Ð±ÑÐ»ÐŽÐ°ÐœÐ°ÐŽÑ, ÐŽÓÐ» ÑÐŸÐ»Ð°Ð¹ Ð±Ð°Ð¹Ð»Ð°ÐœÑÑ ÑÑÐ»ÑÐµÐŒÐµÐ»ÐµÑÑ Ð±Ð°Ñ ÒÐ°Ð»ÒÐ°Ðœ Ð¿Ð°ÑÐ°ÒÑÐ°ÑÐŒÐµÐœ ÐŽÐµ Ð¶Ò±ÐŒÑÑ ÑÑÑÐµÐ¹ÐŽÑ. 
+
+<p> ÐÐ³ÐµÑ Ð¡ÑÐ· file:// ÐœÐµÐŒÐµÑÐµ ftp:// Ð¿Ð°Ð¿ÐºÐ°ÐœÑ Ñ ÐŽÐžÑÐµÐºÑÐŸÑÐžÑÐœÑ Ð°ÐœÑÒÑÐ°Ñ Ò¯ÑÑÐœ ÒÐŸÐ»ÐŽÐ°ÐœÑÐ°Ò£ÑÐ· ÐœÐµÐŒÐµÑÐµ ÑÐ°Ð¹Ð»ÐŽÐ°Ñ ÑÑÐ·ÑÐŒÑÐœ Ð±ÐµÑÐµÑÑÐœ http:// URL-ÐŽÑ ÐµÐœÐ³ÑÐ·ÑÐµÒ£ÑÐ·, Ð¿Ð°Ð¿ÐºÐ°Ð»Ð°ÑÐŽÐ° Ð¶ÓÐœÐµ ÑÑÐºÑ Ð¿Ð°Ð¿ÐºÐ°Ð»Ð°ÑÐŽÐ° ÐŸÑÐœÐ°Ð»Ð°ÑÒÐ°ÐœÐŽÐ°ÑÐŽÑÒ£ Ð±Ð°ÑÐ»ÑÒÑ ÐÐžÐœÐ°ÒÒÐ° ÒÐŸÑÑÐ»Ð°ÐŽÑ.
+
+<p> ÒÐŸÑÑÐŒÑÐ° ÐºÑÑÑ Ð°Ð»Ð°Ò£ÐŽÐ°ÑÑÐœ Ð°Ð»Ñ Ò¯ÑÑÐœ, "more sources" Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ·.}
+
+_textddd2_ [l=kk] {<p> ÐÐ°ÑÑÐ» Ð±Ð°ÑÑÑÐŒÐ°Ð»Ð°ÑÑÐœÑÒ£ Ð±ÑÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ·. ÐÐ³ÐµÑ Ð¡ÑÐ· â ÑÓÐ¶ÑÑÐžÐ±ÐµÐ»Ñ ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ Ð±ÐŸÐ»ÑÐ°Ò£ÑÐ·, ÐŸÐœÐŽÐ° Ð¡ÑÐ· ÐÐžÐœÐ°Ò Ð¿Ð°ÑÐ°ÐŒÐµÑÑÐ»ÐµÑÑÐœ ÑÒ¯Ð·ÐµÑÐºÑÒ£ÑÐ· ÐºÐµÐ»ÑÑ ÐŒÒ¯ÐŒÐºÑÐœ. Ð¡ÑÐ·Ð³Ðµ Ð±Ð°Ð»Ð°ÐŒÐ° ÑÐµÑÑÐœÐŽÐµ Ð±ÑÑÐŽÐµÐœ ÒÐ°Ð»ÑÐ¿ÑÐ°ÑÑÑÑÑ ÐºÐµÐ·ÐµÒ£ÑÐœÐµ ÐºÓ©ÑÑ Ò±ÑÑÐœÑÐ»Ð°ÐŽÑ. ÐÑÑÒ£ÑÐ·ÐŽÐµ Ð±ÐŸÐ»ÑÑÐœ, Ð¡ÑÐ· ÒÐ°Ð¹ÑÐ°ÐŽÐ°Ðœ ÐµÑÑÐµÑÐµÐºÑÐµÐ³Ñ ÐºÐµÐ·ÐµÒ£Ð³Ðµ ÐŸÑÐ°Ð»Ð° Ð°Ð»Ð°ÑÑÐ·, ÐŸÐ» Ò¯ÑÑÐœ ÑÓÐ¹ÐºÐµÑ ÑÐ°ÑÑ Ð±Ð°ÑÑÑÐŒÐ°ÐœÑ Ð±Ð°ÑÑÑÒ£ÑÐ· ÒÐ°Ð¶ÐµÑ.}
+
+_textconf1_ [l=kk] {<p> ÐÐžÐœÐ°ÒÑÒ£ÑÐ·ÐŽÑ ÒÐ°Ð»ÑÐ¿ÑÐ°ÑÑÑÑÑ ÐŒÐµÐœ Ò±ÑÑÐœÑ Ð°ÑÐœÐ°Ð¹Ñ "ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÑÐ»Ð°Ñ ÑÐ°Ð¹Ð»ÑÐœÐŽÐ°ÒÑ" ÑÐžÐ¿Ð°ÑÑÐ°ÐŒÐ°Ð»Ð°ÑÐŒÐµÐœ Ð±Ð°ÑÒÐ°ÑÑÐ»Ð°ÐŽÑ. Ð¢ÓÐ¶ÑÑÐžÐ±ÐµÐ»Ñ ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ»Ð°Ñ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÑÐ»Ð°ÑÐŽÑÒ£ ÐÐºÐµÐŒÐŽÐµÑ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÐ»ÐµÑÑÐœ Ó©Ð·Ð³ÐµÑÑÐºÑÑÑ ÐºÐµÐ»ÑÑ ÐŒÒ¯ÐŒÐºÑÐœ.
+<center><p><b> ÐÐ³ÐµÑ Ð¡ÑÐ· Ð¶Ð°Ò£Ð°ÐŽÐ°Ðœ Ò¯Ð¹ÑÐµÐœÑÐ¿ ÐºÐµÐ»Ðµ Ð¶Ð°ÑÒÐ°Ðœ ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ Ð±ÐŸÐ»ÑÐ°Ò£ÑÐ·, Ð¿Ð°ÑÐ°ÒÑÑÒ£ ÑÓ©ÐŒÐµÐœÐ³Ñ Ð¶Ð°ÒÑÐœÐ° ÑÒ¯ÑÑÒ£ÑÐ·.</b></center>
+<p> ÐÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÑÐ»Ð°ÑÐŽÑÒ£ ÐÐºÐµÐŒÐŽÐµÑ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÐ»ÐµÑÑÐœ Ó©Ð·Ð³ÐµÑÑÑ Ò¯ÑÑÐœ, ÑÓ©ÐŒÐµÐœÐŽÐµ Ð¿Ð°Ð¹ÐŽÐ° Ð±ÐŸÐ»Ð°ÑÑÐœ ÐŒÓÐ»ÑÐŒÐµÑÑÐµÑÐŽÑ ÑÒ¯Ð·ÐµÑÑÒ£ÑÐ·. ÐÐ³ÐµÑ ÒÐ°ÑÐµ Ð¶ÑÐ±ÐµÑÑÐµÒ£ÑÐ·, Ð±Ð°ÑÑÐ°Ð¿ÒÑ ÐÐºÐµÐŒÐŽÐµÑ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÑÐ»ÑÒ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÐ»ÐµÑÑÐœ  ÒÐ°Ð»Ð¿ÑÐœÐ° ÐºÐµÐ»ÑÑÑÑ Ò¯ÑÑÐœ, "Ð¢Ð°Ð·Ð°Ð»Ð°Ñ" Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ·.}
+
+_textreset_ [l=kk] {ÒÐ°Ð¹ÑÐ°ÐŽÐ°Ðœ ÐŸÑÐœÐ°ÑÑ}
+
+
+_texttryagain_ [l=kk] {<a href="_httppagecollector_" target=_top> ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑÑÐœ ÒÐ°Ð¹ÑÐ°ÐŽÐ°Ðœ Ð¶ÑÐ±ÐµÑÑÐ¿ </a> Ð¶Ð°Ò£Ð°ÐŽÐ°Ðœ ÓÑÐµÐºÐµÑ Ð¶Ð°ÑÐ°Ð¿ ÐºÓ©ÑÑÒ£ÑÐ·.}
+
+
+_textretcoll_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑÒÐ° ÐŸÑÐ°Ð»Ñ}
+
+_textdelperm_ [l=kk] {<p> ÐÐµÐ¹Ð±ÑÑ Ð±Ó©Ð»ÑÐºÑÐµÑ ÐœÐµÐŒÐµÑÐµ Ð±Ð°ÑÐ»ÑÒ _cgiargbc1dirname_ ÐÐžÐœÐ°ÒÑ Ð¶ÐŸÐ¹ÑÐ»Ð° Ð°Ð»ÐŒÐ°ÐŽÑ. ÐÒ¯ÐŒÐºÑÐœ ÑÐµÐ±ÐµÐ¿ÑÐµÑÑ:
+<ul>
+<li> Greenstone-ÐœÑÒ£ gsdlhome_/collect/_cgiargbc1dirname_ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐ¹ÑÐœ Ð¶ÐŸÑÒÐ° ÑÒ±ÒÑÐ°Ñ Ð¶ÐŸÒ.
+<br> ÐÒ±Ð» ÐºÐ°ÑÐ°Ð»ÐŸÐ³ÑÑ Ó©Ð·ÑÒ£ÑÐ·ÐŽÑÒ£ ÐºÐŸÐŒÐ¿ÑÑÑÐµÑÑÒ£ÑÐ·ÐŽÐµÐœ ÒÐŸÐ»ÐŒÐµÐœ Ð¶Ð°ÑÐ°Ñ ÑÐµÐ¶ÐžÐŒÑÐœÐŽÐµ Ð¶ÐŸÐ¹ÑÐ¿ ÐºÓ©ÑÑÒ£ÑÐ·. }
+
+_textdelinv_ [l=kk] {_cgiargbc1dirname_  ÐÐžÐœÐ°ÒÑ ÒÐŸÑÒÐ°Ð»ÒÐ°Ðœ ÐœÐµÐŒÐµÑÐµ Ð·Ð°ÒÑÐŒÐŽÐ°ÐœÒÐ°Ðœ. ÐÐŸÑ Ò¯ÑÐŽÑÑÑÐœÐµÐœ Ð±Ð°Ñ ÑÐ°ÑÑÑÐ»ÐŽÑ.}
+
+_textdelsuc_ [l=kk] {_cgiargbc1dirname_  ÐÐžÐœÐ°ÒÑ ÑÓÑÑÑ Ð¶ÐŸÐ¹ÑÐ»ÐŽÑ.}
+
+_textclonefail_ [l=kk] {_cgiargclonecol_  ÐÐžÐœÐ°Ò ÐŽÑÐ±Ð»ÐžÐºÐ°ÑÑÐœ Ð¶Ð°ÑÐ°Ñ ÐŒÒ¯ÐŒÐºÑÐœ ÐµÐŒÐµÑ. ÐÒ±ÐœÑÒ£ ÐŒÒ¯ÐŒÐºÑÐœ ÑÐµÐ±ÐµÐ¿ÑÐµÑÑ:
+<ul>
+<li> _cgiargclonecol_  Ð¶ÐžÐœÐ°ÒÑÑÒ£ Ð¶ÐŸÒÑÑÒÑ
+<li> _cgiargclonecol_ Ð¶ÐžÐœÐ°ÒÑÑÒ£ collect.cfg ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÑÐ»ÑÒ ÑÐ°Ð¹Ð»ÐŽÑÒ£ Ð¶ÐŸÒÑÑÒÑ
+<li> Greenstone-ÐœÑÒ£ collect.cfg ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÑÐ»ÑÒ ÑÐ°Ð¹Ð»ÐŽÑ ÐŸÒÑ ÑÒ±ÒÑÐ°ÑÑÐœÑÒ£ Ð¶ÐŸÒÑÑÒÑ</ul>}
+
+_textcolerr_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ ÒÐ°ÑÐµÑÑ.}
+
+_texttmpfail_ [l=kk] {Ð£Ð°ÒÑÑÑÐ° ÑÐ°Ð¹Ð» ÐœÐµÐŒÐµÑÐµ ÐºÐ°ÑÐ°Ð»ÐŸÐ³ ÑÑÑÐœÐµ Ð¶Ð°Ð·Ñ/ÐŸÒÑ Ð±Ð°ÑÑÑÑÐœÐŽÐ° ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ Ð¶Ð°Ò£ÑÐ»ÑÑÒÐ° Ò±ÑÑÑÐ°ÐŽÑ. ÐÒ¯ÐŒÐºÑÐœ ÑÐµÐ±ÐµÐ¿ÑÐµÑÑ:
+<ul>
+<li> _gsdlhome_/tmp ÐŽÐžÑÐµÐºÑÐŸÑÐžÐ¹ÑÐœÐµ Greenstone-ÐœÑÒ£ Ð¶Ð°Ð·Ñ/ÐŸÒÑÒÐ° ÒÒ±ÒÑÑÑ Ð±ÐµÑÑÐ»Ð³ÐµÐœ ÐµÐŒÐµÑ. </ul>}
+
+_textmkcolfail_ [l=kk] {ÐÐ°Ò£Ð° ÐÐžÐœÐ°ÒÒÐ° ÒÐ°Ð¶ÐµÑ ÐŽÐžÑÐµÐºÑÐžÐ²Ð°Ð»ÑÒ ÒÒ±ÑÑÐ»ÑÐŒ Ð¶Ð°ÑÐ°Ñ ÐºÐµÐ·ÑÐœÐŽÐµ ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ Ð¶Ð°Ò£ÑÐ»ÑÑÒÐ° Ò±ÑÑÑÐ°ÐŽÑ (mkcol.pl Ð¶Ð°Ò£ÑÐ»ÑÑÑ). ÐÒ¯ÐŒÐºÑÐœ ÑÐµÐ±ÐµÐ¿ÑÐµÑÑ:
+<ul>
+<li> Greenstone-ÐœÑÒ£ _gsdlhome_/tmp ÐŽÐžÑÐµÐºÑÐŸÑÐžÐ¹ÑÐœÐµ Ð¶Ð°Ð·Ñ ÒÒ±ÒÑÒÑ Ð±ÐµÑÑÐ»Ð³ÐµÐœ ÐµÐŒÐµÑ.
+<li> mkcol.pl perl-ÑÐºÑÐžÐ¿ÑÑÒ£ ÒÐ°ÑÐµÑÑ.
+</ul>}
+
+_textnocontent_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ ÒÐ°ÑÐµÑÑ: Ð¶Ð°Ò£Ð° ÐÐžÐœÐ°ÒÒÐ° ÐµÑÒÐ°ÐœÐŽÐ°Ð¹ Ð°ÑÐ°Ñ Ð±ÐµÑÑÐ»ÐŒÐµÐ³ÐµÐœ. ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑÐŽÑ ÒÐ°Ð¹ÑÐ° Ð¶ÑÐ±ÐµÑÑÐ¿ ÐºÓ©ÑÑÒ£ÑÐ·.}
+
+_textrestart_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑÐŽÑ ÒÐ°Ð¹ÑÐ°ÐŽÐ°Ðœ ÒÐŸÑÑ}
+
+_textreloaderror_ [l=kk] {ÐÐ°Ò£Ð° ÐÐžÐœÐ°ÒÑÑ Ð¶Ð°ÑÐ°Ñ Ð±Ð°ÑÑÑÑÐœÐŽÐ° ÒÐ°ÑÐµ Ð¿Ð°Ð¹ÐŽÐ° Ð±ÐŸÐ»ÐŽÑ. ÐÒ±Ð» Ð±ÑÐ°ÑÐ·ÐµÑÑÒ£ÑÐ·ÐŽÑÒ£ "reload/ÒÐ°Ð¹ÑÐ°Ð¶Ò¯ÐºÑÐµÑ" Ð¶ÓÐœÐµ "back/Ð°ÑÑÒÐ°" Ð±Ð°ÑÑÑÐŒÐ°Ð»Ð°ÑÑÐœ ÒÐ°ÑÐµ Ð±Ð°ÑÑÐŽÐ°Ðœ Ð±ÐŸÐ»ÑÑ ÐŒÒ¯ÐŒÐºÑÐœ (ÐÑÑ Ð±Ð°ÑÑÑÐŒÐ°Ð»Ð°ÑÐŽÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐŸÑ ÐºÓ©ÐŒÐµÐ³ÑÐŒÐµÐœ ÐÐžÐœÐ°ÒÑÐ°Ñ Ð¶Ð°ÑÐ°ÒÐ°ÐœÐŽÐ° Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÐ±Ð°ÑÒÐ° ÑÑÑÑÑÑÒ£ÑÐ·). ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ ÒÐ°Ð¹ÑÐ° Ð¶ÑÐ±ÐµÑÑÐ»ÑÑ Ð¶Ó©Ðœ.}
+
+_textexptsuc_ [l=kk] {_cgiargbc1dirname_ ÐÐžÐœÐ°ÒÑ _gsdlhome_/tmp/exported\__cgiargbc1dirname_ ÐŽÐžÑÐµÐºÑÐŸÑÐžÑÑÑÐœÐ° ÑÓÑÑÑ ÐµÐœÐ³ÑÐ·ÑÐ»ÐŽÑ.}
+
+_textexptfail_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ ÑÐºÑÐ¿ÐŸÑÑÑÐ°ÑÐŽÐ° Ð¶Ð°Ò£ÑÐ»Ñ_cgiargbc1dirname_. 
+ÐÒ±Ð»  "ÐÐžÐœÐ°ÒÑÑ ÑÐºÑÐ¿ÐŸÑÑÑÐ°Ñ" ÑÑÐœÐºÑÐžÑÑÑÐœ ÒÐŸÐ»ÐŽÐ°ÑÐŽÑÒ£ ÒÐ°Ð¶ÐµÑÑÑ ÐºÐŸÐŒÐ¿ÐŸÐœÐµÐœÑÑÐµÑÑÑÑÐ· Greenstone ÐŸÑÐœÐ°ÑÑÐ»ÒÐ°ÐœÐŽÑÒÑÐ°Ðœ Ð±ÐŸÐ»ÑÑ ÐŒÒ¯ÐŒÐºÑÐœ. 
+<ul>
+<li> ÐÐ³ÐµÑ ÑÑÐ· Greenstone-ÐŽÑ  CD-ROM-ÐŒÐµÐœ Ð±ÑÑÐ³Ðµ ÐŸÑÐœÐ°ÑÑÐ°Ò£ÑÐ·, ÐµÐ³ÐµÑ ÑÑÐ· ÐŸÐ»Ð°ÑÐŽÑ ÑÑÑÐœÐ°ÑÐ° ÐŸÑÐœÐ°ÑÑ ÐºÐµÐ·ÑÐœÐŽÐµ ÑÐ°Ò£ÐŽÐ°ÐŒÐ°ÑÐ°Ò£ÑÐ·, Ð±Ò±Ð» ÐºÐŸÐŒÐ¿ÐŸÐœÐµÐœÑÑÐµÑ ÐŸÑÐœÐ°ÑÑÐ»ÐŒÐ°Ð¹ÐŽÑ. Ð¡ÑÐ· ÒÐ°Ð¹ÑÐ° ÐŸÑÐœÐ°ÑÑ ÐºÐµÐ·ÑÐœÐŽÐµ ÒÐŸÑÑÑÒ£ÑÐ·ÒÐ° Ð±ÐŸÐ»Ð°ÐŽÑ.  
+<li> ÐÐ³ÐµÑ ÑÑÐ· Greenstone-ÐŽÑ  Ð²ÐµÐ±-ÐŽÐžÑÑÑÐžÐ±ÑÑÐžÐ²-Ð¿ÐµÐœ Ð±ÑÑÐ³Ðµ ÐŸÑÐœÐ°ÑÑÐ°Ò£ÑÐ·, ÐŸÐœÐŽÐ° ÑÐºÑÐ¿ÐŸÑÑ ÑÑÐœÐºÑÐžÑÑÑÐœÑÒ£ ÒÑÐ·ÐŒÐµÑÑÐœ ÒÐ°ÐŒÑÐ°ÐŒÐ°ÑÑÐ· ÐµÑÐµÑÑÐœ ÒÐŸÑÑÐŒÑÐ° Ð±ÑÐŒÐ°ÐœÑ ÒÐŸÑÐ°ÑÑÐ¿ ÐŸÑÐœÐ°ÑÑÑÒ£ÑÐ· ÒÐ°Ð¶ÐµÑ.  <a href="http://www.greenstone.org"> http://www.greenstone.org </a> ÑÐ°Ð¹ÑÑÐœÐ° ÐºÑÑÑÒ£ÑÐ· ÐœÐµÐŒÐµÑÐµ  <a href="mailto:greenstone@cs.waikato.ac.nz"> ÑÐ»ÐµÐºÑÑÐŸÐœÐŽÑÒ Ð¿ÐŸÑÑÐ° Ð°ÑÒÑÐ»Ñ ÑÒ±ÑÐ°Ñ ÑÐ°Ð»ÑÒ£ÑÐ·
+greenstone@cs.waikato.ac.nz </a>  Ð°ÑÑÒÐ°ÑÐ°Ð¹ ÐœÒ±ÑÒÐ°Ñ Ð°Ð»Ñ Ò¯ÑÑÐœ}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=kk] {<p>Ð€Ð°Ð¹Ð» ÑÑÑÐ°Ð»Ñ ÐºÐµÐ»ÐµÑÑ Ð°ÒÐ¿Ð°ÑÐ°ÑÑÑ Ð°ÐœÑÒÑÐ°Ð¿, _textintro_ below. </p> - ÐŽÑ Ð±Ð°ÑÑÒ£ÑÐ·}  
+
+_textcaec_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ° Ð±Ð°Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÒÐ° ÒÐŸÑÑ}  
+_textbild_ [l=kk] {ÐÐµÐ¿ÐŸÐ·ÐžÑÐŸÑ ÑÐ»ÐµÐŒÐµÐœÑÑ}  
+_textintro_ [l=kk] {Ð€Ð°Ð¹Ð»ÐŽÑ ÑÐ°Ò£ÐŽÐ°Ò£ÑÐ·}  
+_textconfirm_ [l=kk] {ÒÒ±Ð¿ÑÐ°Ñ}  
+_textselect_ [l=kk] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐœÑ ÑÐ°Ò£ÐŽÐ°Ñ}  
+_textmeta_ [l=kk] {ÐÐµÑÐ°Ð±ÐµÑÑÐ»Ð³ÐµÐœÐŽÐµÑÐŽÑ Ð°ÐœÑÒÑÐ°Ò£ÑÐ·}  
+_textselectoption_ [l=kk] {Ð¶ÐžÐœÐ°ÒÑÑ ÑÐ°Ò£ÐŽÐ°Ò£ÑÐ·}  
+
+_texttryagain_ [l=kk] {ÐÐµÐ¿ÐŸÐ·ÐžÑÐŸÑÐŽÑ</a> ÒÐ°Ð¹ÑÐ° ÒÐŸÑÑÒ£ÑÐ· <a href="_httppagedepositor_" target=_top> Ð¶ÓÐœÐµ ÑÐ°ÒÑ ÒÐ°Ð¹ÑÐ°Ð»Ð°Ò£ÑÐ·.
+}  
+
+_textselectcol_ [l=kk] {Ð¡ÑÐ· Ð¶Ð°Ò£Ð° ÒÒ±Ð¶Ð°ÑÒÐ° ÒÐŸÑÐ°ÑÑÐœ Ð¶ÐžÐœÐ°ÒÑÑ ÑÐ°Ò£ÐŽÐ°Ò£ÑÐ· }  
+_textfilename_ [l=kk] {Ð€Ð°Ð¹Ð» Ð°ÑÐ°ÑÑ}  
+_textfilesize_ [l=kk] {Ð€Ð°Ð¹Ð»ÐŽÑÒ£ ÐŒÓ©Ð»ÑÐµÑÑ}  
+
+_textretcoll_ [l=kk] {ÐÐµÐ¿ÐŸÐ·ÐžÑÐŸÑÒÐ° ÐŸÑÐ°Ð»Ñ}  
+
+
+_texttmpfail_ [l=kk] {ÐÐµÐ¿ÐŸÐ·ÐžÑÐŸÑ ÐŽÐžÑÐµÐºÑÐŸÑÐžÑÒÐ° ÐœÐµÐŒÐµÑÐµ ÑÐ°ÒÑÑÑÐ° ÑÐ°Ð¹Ð»ÒÐ° 
+Ð¶Ð°Ð·Ð° Ð°Ð»ÐŒÐ°Ð¹ÐŽÑ ÐœÐµÐŒÐµÑÐµ ÐŸÒÐž Ð°Ð»ÐŒÐ°Ð¹ÐŽÑ. ÐÒ¯ÐŒÐºÑÐœ ÑÐµÐ±ÐµÐ¿ÑÐµÑ:
+<ul>
+<li> ÐÑÐžÐœÑÑÐŸÑÐœÐœÑÒ£ _gsdlhome_/tmp .
+</ul> ÐŽÐžÑÐµÐºÑÐŸÑÐžÑÑÑÐœÐŽÐ° ÐŸÒÑÒÐ°/ Ð¶Ð°Ð·ÑÒÐ° ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐ³Ñ Ð¶ÐŸÒ.
+}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=kk] {Greenstone â ÑÐ°ÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ° ÐÐžÐœÐ°ÒÑÐ°ÑÒÐ° ÒÑÐ·ÐŒÐµÑ ÐºÓ©ÑÑÐµÑÑÐ³Ðµ Ð¶ÓÐœÐµ Ð¶Ð°Ò£Ð° ÐÐžÐœÐ°ÒÑÐ°ÑÐŽÑ ÒÒ±ÑÑÒÐ° Ð°ÑÐœÐ°Ð»ÒÐ°Ðœ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° Ð¶Ð°Ð±ÐŽÑÒÑ. ÐÒ±Ð» ÐÐœÑÐµÑÐœÐµÑ Ð¶ÓÐœÐµ CD-ROM-ÐŽÐ°ÑÐŽÐ° Ð°ÒÐ¿Ð°ÑÐ°ÑÑÐ°ÑÐŽÑ Ò±Ð¹ÑÐŒÐŽÐ°ÑÑÑÑÑ ÐŒÐµÐœ Ð¶Ð°ÑÐžÑÐ»Ð°ÑÐŽÑÒ£ Ð¶Ð°Ò£Ð° ÑÓÑÑÐ»Ñ. Greenstone ÐÐ°Ð¹ÐºÐ°ÑÐŸ ÑÐœÐžÐ²ÐµÑÑÐžÑÐµÑÑ Ð¶Ð°ÐœÑÐœÐŽÐ° New Zealand Digital Library Project Ð¶ÐŸÐ±Ð°ÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÐŽÐ°ÑÑÐ»Ð°ÐœÑÐ¿ Ð®ÐÐÐ¡ÐÐ Ð¶ÓÐœÐµ Human info Ò¯ÐºÑÐŒÐµÑÑÑÐº ÐµÐŒÐµÑ Ò±Ð¹ÑÐŒÑ ÒÐŸÐ»ÐŽÐ°ÑÑÐŒÐµÐœ ÑÐ°ÑÐ°ÑÑÐ»Ð°ÐŽÑ. ÐÒ±Ð» Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° Ð¶Ð°Ð±ÐŽÑÒÑ <i><a href="http://greenstone.org"> http://greenstone.org </a></i> ÐŒÐµÐºÐµÐœ-Ð¶Ð°Ð¹Ñ Ð°ÑÒÑÐ»Ñ GNU ÑÐ°ÑÑÑÐœÐ° ÑÐ°Ð¹, ÑÐµÐ³ÑÐœ ÑÐ°ÑÐ°ÑÑÐ»Ð°ÐŽÑ.}
+
+_textgreenstone2_ [l=kk] {ÐÐ°Ò£Ð°ÐÐµÐ»Ð°ÐœÐŽÐžÑ ÑÐ°ÐœÐŽÑÒ ÐÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÑÑÐœÑÒ£ ÐÐµÐ±-ÑÐ°Ð¹ÑÑÐœÐ° (<a href="http://nzdl.org">http://nzdl.org</a>) ÐºÑÑÐ³ÐµÐœ ÐºÐµÐ· ÐºÐµÐ»Ð³ÐµÐœ ÐÐœÑÐµÑÐœÐµÑ-ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ Greenstone Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°ÑÑÐŒÐµÐœ Ð¶Ð°ÑÐ°ÒÑÐ°Ð»ÒÐ°Ðœ ÐÐžÐœÐ°ÒÑÐ°ÑÐŽÑÒ£ ÐºÓ©Ð¿ÑÐµÐ³ÐµÐœ ÐŒÑÑÐ°Ð»ÐŽÐ°ÑÑÐŒÐµÐœ ÑÐ°ÐœÑÑÐ° Ð°Ð»Ð°ÐŽÑ. ÐÑÐ°Ð±, ÒÑÑÐ°Ð¹, ÑÑÐ°ÐœÑÑÐ·, ÐžÑÐ¿Ð°Ðœ, Ð°ÒÑÐ»ÑÑÐœ, ÐŒÐ°ÐŸÑÐž ÑÑÐ»ÐŽÐµÑÑÐœÐŽÐµ ÐŽÐ°ÑÑÐ»Ð°ÐœÒÐ°Ðœ ÐÐžÐœÐ°ÒÑÐ°Ñ ÐÐ·ÐŽÐµÑÐŽÑÒ£ Ð¶ÓÐœÐµ ÒÐ°ÑÐ°ÑÐŽÑÒ£ ÑÒ¯ÑÐ»Ñ ÐœÒ±ÑÒÐ°Ð»Ð°ÑÑÐœ Ð±ÐµÐ¹ÐœÐµÐ»ÐµÐ¹ÐŽÑ. Ð¡ÐŸÐœÑÐŒÐµÐœ ÒÐ°ÑÐ°Ñ ÐŒÑÐ·ÑÐºÐ°Ð»ÑÒ ÐÐžÐœÐ°ÒÑÐ°Ñ ÐŽÐ° Ð±ÐµÑÑÐ»Ð³ÐµÐœ.}
+
+_textplatformtitle_ [l=kk] {ÐÐ»Ð°ÑÑÐŸÑÐŒÐ°}
+_textgreenstone3_ [l=kk] {Greenstone Windows Ð¶ÓÐœÐµ Unix Ð¶Ò¯Ð¹ÐµÐ»ÐµÑÑÐœÐŽÐµ ÐŸÑÐœÐ°ÑÑÐ»Ð°ÐŽÑ. Greenstone ÐŽÐžÑÑÑÐžÐ±ÑÑÐžÐ²Ñ Windows, Linux Ð¶ÓÐœÐµ Mac OS X ÑÒ¯ÑÐ»Ñ ÐœÒ±ÑÒÐ°Ð»Ð°ÑÑÐœ ÒÐŸÐ»ÐŽÐ°ÐœÑÒÐ° ÐŽÐ°Ð¹ÑÐœ ÑÐŸÐ¿ÑÐ°ÐŒÐ°Ð»Ð°ÑÐŽÑ ÒÐ°ÐŒÑÐžÐŽÑ. Ð¡ÐŸÐœÑÐŒÐµÐœ ÒÐ°ÑÐ°Ñ, Microsoft C++ Ð¶ÓÐœÐµ GCC ÐºÓ©ÐŒÐµÐ³ÑÐŒÐµÐœ ÒÒ±ÑÑÐ»Ð°ÑÑÐœ ÐŽÐ°Ð¹ÑÐœ Ð±Ð°ÑÑÐ°Ð¿ÒÑ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°ÐœÑ ÐŽÐ° ÒÐ°ÐŒÑÐžÐŽÑ. Greenstone ÐµÑÐºÑÐœ ÑÐ°ÑÐ°ÑÑÐ»Ð°ÑÑÐœ: Apache Webserver Ð¶ÓÐœÐµ PERL Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°Ð»Ð°ÑÐŒÐµÐœ Ð¶Ò±ÐŒÑÑ ÑÑÑÐµÐ¹ Ð°Ð»Ð°ÐŽÑ. ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑ Web-Ð±ÑÐ°ÑÐ·ÐµÑÐŽÑ: ÓÐŽÐµÑÑÐµ Netscape Navigator ÐœÐµÐŒÐµÑÐµ Internet Explorer-ÐŽÑ ÒÐŸÐ»ÐŽÐ°ÐœÐ°ÐŽÑ.}
+
+_textgreenstone4_ [l=kk] {Ð­Ð»ÐµÐºÑÑÐŸÐœÐŽÑÒ ÒÒ±Ð¶Ð°ÑÑÐ°Ñ ÑÐŸÐ¿ÑÐ°ÐŒÐ°ÑÑÐœÑÒ£ ÐºÓ©Ð¿ÑÑÐ»ÑÐ³Ñ Greenstone Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°ÑÑÐœ ÒÐŸÐ»ÐŽÐ°ÐœÑ Ð°ÑÒÑÐ»Ñ CD-ROM-ÐŒÐµÐœ ÑÐ°ÑÐ°ÑÑÐ»Ð°ÐŽÑ. ÐÑÑÐ°Ð»Ñ, <i> Humanity Development Library</i> 1230 Ð¶Ð°ÑÐžÑÐ»Ð°ÑÐŽÑ ÒÐ°ÐŒÑÐžÐŽÑ. ÐÐ» ÐŒÐžÐœÐžÐŒÐ°Ð»ÐŽÑ Ð°Ð¿Ð¿Ð°ÑÐ°ÑÑÑÒ ÑÐ°Ð»Ð°Ð¿ÑÐ°ÑÑÐœ ÑÐ°Ð»Ð°Ð¿ ÐµÑÐµÑÑÐœ Ð¶Ð°ÒÐŽÐ°Ð¹ÑÐœÐŽÐ° Ð¶Ò±ÐŒÑÑ ÑÑÑÐµÐ¹ Ð°Ð»Ð°ÐŽÑ, Ð±Ò±Ð» ÐŽÐ°ÐŒÑÑÑ ÐµÐ»ÐŽÐµÑ Ò¯ÑÑÐœ ÒÐ°Ð»ÑÐ¿ÑÑ Ð¶Ð°ÒÐŽÐ°Ð¹. ÐÐ·ÐŽÐµÑ Ð¿ÑÐŸÑÐµÐŽÑÑÐ°Ð»Ð°ÑÑÐœ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÐ° ÐŸÑÑÑÑÐ¿, ÑÐ°ÒÑÑÑÐ¿ÑÐ°Ñ, Ò±Ð¹ÑÐŒÐŽÐ°Ñ Ð±ÐŸÐ¹ÑÐœÑÐ°, Ð¶Ð°Ðœ-Ð¶Ð°ÒÑÑ ÑÐµÑÑÐµÐ»Ð³ÐµÐœ ÑÑÐ·ÑÐŒÐŽÐµÑÑ ÐŒÐµÐœ ÐºÑÑÐ°Ð¿ÑÐ°Ñ Ð±ÐµÐ¹ÐœÐµÐ»ÐµÑÑÐœ ÒÐ°ÑÐ°ÑÒÐ° Ð±ÐŸÐ»Ð°ÐŽÑ.}
+
+_textcustomisationtitle_ [l=kk] {ÐÐºÐµÐŒÐŽÐµÑ}
+_textgreenstone5_ [l=kk] {Greenstone Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°ÑÑ ÓÑ ÑÒ¯ÑÐ»Ñ ÐžÐºÐµÐŒÐŽÐµÑÐ»ÑÐºÑÐµÑÐ³Ðµ Ð±Ð°ÒÑÑÑÐ°Ð»ÒÐ°Ðœ. ÐÐµÑÐ°ÐŒÓÐ»ÑÐŒÐµÑÑÐµÑÐŽÑÒ£ ÑÐŸÑÐŒÐ°ÑÑÐ°ÑÑ ÐŒÐµÐœ Ð¶Ð°Ò£Ð° ÒÒ±Ð¶Ð°ÑÑÐ°Ñ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°ÒÐ° "plugins/ÒÐŸÑÑÐŒÑÐ°Ð»Ð°Ñ" Ð¶Ð°Ð·Ñ Ð°ÑÒÑÐ»Ñ Ð±ÐµÑÑÐ»ÐµÐŽÑ (Perl Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° ÑÑÐ»ÑÐœÐŽÐµ). Ð¡ÐŸÐ» ÑÐžÑÒÑÑ, ÑÑÐºÑ ÒÒ±ÑÑÐ»ÑÐŒÑÐœ Ð±Ð°ÒÑÐ»Ð°Ð¹ÑÑÐœ Ð¶Ð°Ò£Ð° ÐŒÐµÑÐ°ÐŒÓÐ»ÑÐŒÐµÑÑÐµÑ "classifiers/ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ»Ð°Ñ" Ð¶Ð°Ð·Ñ Ð°ÑÒÑÐ»Ñ Ð¶Ð°ÑÐ°Ð»ÑÐœÐ°ÐŽÑ. ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ ÐžÐœÑÐµÑÑÐµÐ¹Ñ Ð±ÐµÐ¹ÐœÐµÑÑÐœ ÒÐ°ÑÐ°Ð¿Ð°Ð¹ÑÐŒ ÐŒÐ°ÐºÑÐŸÑÑÐ»ÐŽÐµ Ð¶Ð°Ð·ÑÐ»ÒÐ°Ðœ "ÐŒÐ°ÐºÑÐŸÑÑÐ°Ñ" Ð°ÑÒÑÐ»Ñ Ó©Ð·Ð³ÐµÑÑÑÐ³Ðµ Ð±ÐŸÐ»Ð°ÐŽÑ. Corba Ð¿ÑÐŸÑÐŸÐºÐŸÐ»Ñ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°Ð»ÑÒ Ð°Ð³ÐµÐœÑÑÐµÑÐ³Ðµ (ÐŒÑÑÐ°Ð»Ñ Java-ÐŽÐ°) ÒÒ±Ð¶Ð°ÑÑÐ°Ñ ÐÐžÐœÐ°ÒÑÐŒÐµÐœ Ð±Ð°Ð¹Ð»Ð°ÐœÑÑÒÐ°Ðœ Ð±Ð°ÑÐ»ÑÒ ÒÒ±ÑÐ°Ð»ÐŽÐ°ÑÐŽÑ ÒÐŸÐ»ÐŽÐ°ÐœÑ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐ³ÑÐœ Ð±ÐµÑÐµÐŽÑ. C++ Ð¶ÓÐœÐµ Perl ÑÑÐ»ÑÐœÐŽÐµ Ð¶Ð°Ð·ÑÐ»ÒÐ°Ðœ Ð±Ð°ÑÑÐ°Ð¿ÒÑ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° ÐŽÐ° ÐŒÐŸÐŽÐžÑÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÒÐ° Ð±Ð°ÒÑÑÑÐ°Ð»ÒÐ°Ðœ.}
+
+_textdocumentationtitle_ [l=kk] {ÒÒ±Ð¶Ð°ÑÑÐ°ÐŒÐ°}
+_textdocuments_ [l=kk] {Greenstone Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° Ð¶Ð°Ð±ÐŽÑÒÑ Ð±ÐŸÐ¹ÑÐœÑÐ° ÐºÐµÒ£ÐµÐ¹ÑÑÐ»Ð³ÐµÐœ ÒÒ±Ð¶Ð°ÑÑÐ°ÐŒÐ°ÒÐ° ÑÒ±ÒÑÐ°Ñ}
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=kk] {Ð¶ÑÐ±ÐµÑÑ ÑÑÐ·ÑÐŒÑ }
+_textmailinglist_ [l=kk] {Greenstone ÑÐ°ÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ° Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° Ð¶Ð°Ð±ÐŽÑÒÑÐœ ÑÐ°Ð»ÒÑÐ»Ð°Ñ Ò¯ÑÑÐœ Ð¶ÑÐ±ÐµÑÑ ÑÑÐ·ÑÐŒÑ ÒÐ°ÑÐ°ÑÑÑÑÑÐ»ÒÐ°Ðœ. Greenstone-ÐœÑÒ£ Ð±ÐµÐ»ÑÐµÐœÐŽÑ ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ»Ð°ÑÑ ÐŸÑÑ ÑÑÐ·ÑÐŒÐ³Ðµ ÒÐŸÑÑÐ»ÑÐ¿, ÑÐ°Ð»ÒÑÐ»Ð°ÑÒÐ° Ð°ÑÐ°Ð»Ð°ÑÐ° Ð°Ð»Ð°ÐŽÑ. ÐÒ±Ð» ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐº Pathfinder Library System Ð°ÑÐœÐ°Ð¹Ñ Ð±ÐµÑÑÐ»Ð³ÐµÐœ Ñ
+ÐŸÑÑ Ð°ÑÒÑÐ»Ñ Ð¿Ð°Ð¹ÐŽÐ° Ð±ÐŸÐ»ÐŽÑ (ÐÐŸÐ»ÐŸÑÐ°ÐŽÐŸ ÑÑÐ°ÑÑÐœÐŽÐ°ÒÑ Grand Junction ÒÐ°Ð»Ð°ÑÑ (ÐÐ¶ÐŸÐœ ÐÐ°ÐŒÐ¿Ð±ÐµÐ»Ð», <a href="john@colosys.net">john@colosys.net</a>). Ð¢ÑÐ·ÑÐŒÐ³Ðµ ÒÐŸÑÑÐ»Ñ Ò¯ÑÑÐœ <ul>subscribe greenstone </ul> (ÑÐ°ÒÑÑÑÐ¿ÑÑ ÐŽÐ°, Ð°ÑÑÒ£ÑÐ·ÐŽÑ ÐŽÐ°, ÐµÑÐœÓÑÑÐµÐœÑ ÐºÓ©ÑÑÐµÑÐ¿ÐµÐ¹) ÑÐ»ÐµÐºÑÑÐŸÐœÐŽÑÒ Ñ
+Ð°Ð±Ð°ÑÐ»Ð°ÐŒÐ° <a href="mailto:majordomo@colosys.net"> majordomo@colosys.net </a> ÐŒÐµÐºÐµÐœ-Ð¶Ð°Ð¹ÑÐœÐ° Ð¶ÑÐ±ÐµÑÑÒ£ÑÐ·. Ð¥Ð°Ð±Ð°ÑÐ»Ð°ÑÐ°Ò£ÑÐ·ÐŽÑ <a href="mailto: greenstone@colosys.net"> greenstone@colosys.net.</a> ÐŒÐµÐºÐµÐœ-Ð¶Ð°Ð¹ÑÐœÐ° ÒÐŸÑÐ° Ð¶ÑÐ±ÐµÑÑÒ£ÑÐ·}
+
+_textbugstitle_ [l=kk] {ÒÐ°ÑÐµÐ»ÐµÑ}
+_textreport_ [l=kk] {ÐÑÐ·ÐŽÑÒ£ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°Ð»ÑÒ Ð¶Ð°ÑÐ°ÒÑÐ°ÐŒÐ°Ð»Ð°ÑÑÐŒÑÐ·Ð±ÐµÐœ Ð¶Ò±ÐŒÑÑ Ð¶Ð°ÑÐ°Ñ ÑÑÐ·ÐŽÐµÑÐ³Ðµ Ð¶Ð°ÒÑÐŒÑÑÐ· Ð¶Ð°ÒÐŽÐ°Ð¹ ÑÒ±ÒÑÐ·Ð±Ð°Ð¹ÑÑÐœÐŽÑÒÑÐœÐ° Ð±ÑÐ· ÑÐµÐœÑÐŒÐŽÑ Ð±ÐŸÐ»ÑÑÐŒÑÐ· ÐºÐµÑÐµÐº. ÐÑÐœÐ° ÐŒÐµÐºÐµÐœÐ¶Ð°Ð¹ Ð±ÐŸÐ¹ÑÐœÑÐ° <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a> Ð¶Ò±ÐŒÑÑ Ò¯ÑÐŽÑÑÑÐœÐŽÐµ ÑÐ°Ð±ÑÐ»ÒÐ°Ðœ Ð±Ð°ÑÐ»ÑÒ ÒÐ°ÑÐµÐ»ÐµÑ Ð¶Ð°Ð¹Ð»Ñ Ð±ÑÐ·Ð³Ðµ Ñ
+Ð°Ð±Ð°ÑÐ»Ð°Ò£ÑÐ·.}  
+
+_textgs3title_ [l=kk] {Ð¶Ò±ÐŒÑÑ Ð±Ð°ÑÑÑÑÐœÐŽÐ°}
+_textgs3_ [l=kk] {Greenstone 3   ÐŽÐžÐ·Ð°Ð¹ÐœÑ ÐŒÐµÐœ ÒÒ±ÑÐ°Ð»-Ð¶Ð°Ð±ÐŽÑÒÑÐ°ÑÑÑÑÑ ÑÐŸÐ»ÑÒÑÐŒÐµÐœ Ó©Ð·Ð³ÐµÑÑÑÐ»Ð³ÐµÐœ, ÐŽÐµÐ³ÐµÐœÐŒÐµÐœ ÐŽÐµ ÐŸÐ» Greenstone  2 (ÐŸÑÑ Ð²ÐµÑÑÐžÑÑÑ) Ð±Ð°ÑÐ»ÑÒ Ð°ÑÑÑÒÑÑÐ»ÑÒÑÐ°ÑÑÐœ ÑÐ°ÒÑÐ°ÒÐ°Ðœ. ÐÓ©Ð¿ÑÑÐ»ÐŽÑ, ÐºÓ©Ð¿Ð¿Ð»Ð°ÑÑÐŸÑÐŒÐ°Ð»Ñ Ð¶ÓÐœÐµ Ð¶ÐŸÒÐ°ÑÑ Ò¯Ð¹Ð»ÐµÑÑÐŒÐŽÑÐ»ÑÐ³ÑÐŒÐµÐœ  ÐµÑÐµÐºÑÐµÐ»ÐµÐœÐµÐŽÑ. ÐÐ» Ð±Ð°Ñ Ð¶Ò¯Ð¹ÐµÐœÑÒ£ ÒÒ±ÑÐ°Ð»ÐŽÐ°ÑÑÐœ ÒÐŸÑÑÐ¿, ÐºÐµÑÑ ÑÑÑÐºÐµÑÑÑÐ»ÑÐºÑÑ ÒÐ°ÐŒÑÐžÐŽÑ. Ð¯ÒÐœÐž, ÐµÑ ÐŒÐŸÐŽÐžÑÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÑÑÐ· ÐÐžÐœÐ°ÒÑÐ°ÑÐŽÑ ÒÒ±ÑÐ°ÑÑÑÑÐ° ÐŸÑÑÑÑÐ¿, ÐµÒ£Ð³ÑÐ·Ðµ Ð°Ð»Ð°ÐŽÑ. Java-ÐŽÐ° Ð¶Ð°Ð·ÑÐ»ÑÐ¿, XML-ÐŽÑ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÐ¿ ÓÑÐµÑÐ»ÐµÑÐµÑÑÐœ ÑÓÑÐµÐ»ÑÑÐ· ÐŒÐŸÐŽÑÐ»ÑÐŽÐµÑ ÑÒ±Ð»Ð±Ð°ÑÑ ÑÐžÑÒÑÑ ÒÒ±ÑÑÐ»ÑÐŒÐŽÐ°Ð»ÒÐ°Ðœ.  Ð¡Ó©Ð¹ÑÑÐ¿, ÐŽÐžÑÑÑÐžÐ±ÑÑÐžÐ² ÑÒ¯ÑÑÐœÐŽÐµ ÐŸÑÑÐœÐŽÐ°Ð»ÑÐ¿, Ð±ÐµÑÑÐ»Ð³ÐµÐœ ÑÐ°Ð»Ð°Ð¿ Ð±ÐŸÐ¹ÑÐœÑÐ° ÓÑÑÒ¯ÑÐ»Ñ ÑÐµÑÐ²ÐµÑ Ð°ÑÒÑÐ»Ñ ÑÐ°ÑÐ°Ð»Ð° Ð°Ð»Ð°ÐŽÑ. ÐÒ±Ð» ÐŒÐŸÐŽÑÐ»ÑÐŽÑÐº ÑÐµÑÑÐŒ  Greenstone-ÐœÑÒ£ ÐžÐºÐµÐŒÐŽÑÐ»ÑÐ³Ñ ÐŒÐµÐœ ÐºÐµÒ£ÐµÐ¹ÑÑÐ»ÐµÐœÑÑÐœ Ð°ÑÑÑÑÑÐ°ÐŽÑ. Ð¢ÓÐ¶ÑÑÐžÐ±ÐµÐ»ÑÐº ÒÐŸÐ»ÐŽÐ°ÐœÑÒÐ° Ð±Ò±Ð» Ð¶Ð°Ò£Ð° Ð²ÐµÑÑÐžÑ 2003 Ð¶ÑÐ»ÐŽÑÒ£ 23 Ð¶ÐµÐ»ÑÐŸÒÑÐ°ÐœÑÐœÐŽÐ° Ò±ÑÑÐœÑÐ»Ð°ÐŽÑ ÐŽÐµÐ¿ Ò±Ð¹ÒÐ°ÑÑÐ»ÒÐ°Ðœ. ÐÒ¯Ð¹ÐµÐœÑÒ£ Ð±Ð°ÑÑÐ°Ð¿ÒÑ ÐŽÐžÐ·Ð°Ð¹ÐœÑ "The design of Greenstone 3: An agent based dynamic digital library"-ÐŽÐµ ÑÐžÐ¿Ð°ÑÑÐ°Ð»ÒÐ°Ðœ. (ÐµÐœÐ³ÑÐ·Ñ Ò¯ÑÑÐœ - <a href="http://www.greenstone.org/manuals/gs3design.pdf">PDF</a>).
+}
+
+_textcreditstitle_ [l=kk] {ÐÑÐµÐŽÐžÑÑÐµÑ}
+
+_textwhoswho_ [l=kk] {Greenstone Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°ÑÑ - ÐºÓ©Ð¿ÑÐµÐ³ÐµÐœ Ð°ÐŽÐ°ÐŒÐŽÐ°ÑÐŽÑÒ£ Ð±ÑÑÐ»ÐµÑÐºÐµÐœ ÐµÒ£Ð±ÐµÐ³ÑÐœÑÒ£ Ð¶ÐµÐŒÑÑÑ. Ð ÐŸÐŽÐ¶ÐµÑ ÐÐ°ÐºÐÐ°Ð± Ð¿ÐµÐœ Ð¡ÑÑÑÐ°Ðœ ÐÐŸÐŽÐŽÐž ÐœÐµÐ³ÑÐ·Ð³Ñ Ð¶Ð°ÑÐ°ÑÑÑÐ»Ð°Ñ. ÐÑÐ²ÐžÐŽ ÐÑÐ¹ÐœÐ±ÑÐžÐŽÐ¶, ÐÐ¶ÐŸÑÐŽÐ¶ ÐÑÑÐ°ÐœÐ°Ðœ, Ð¥ÐŸÐœÐ³ Ð§ÐµÐœ,Ð­Ð»ÑÐºÐµ ÐÐ°ÐœÐºÐµÑ, ÐÐ°ÑÐ» ÐÑÑÐ²ÐžÐœ, ÐÐ¶ÐµÑ Ð¥ÐŸÐ»ÐŒÑ, ÐÐ¶ÐŸÐœ ÐÐ°ÐºÐ€ÐµÑÑÐŸÐœ, ÐÑÐµÐ¹Ð³ ÐÑÐ²ÐžÐ»Ð»-ÐÑÐ¹ÐœÐžÐœÐ³, ÐÐŸÑÐŽÐŸÐœ ÐÐ°Ð¹ÐœÑÐµÑ, ÐÐµÑÐœÑ
+Ð°ÑÐŽ Ð€Ð°ÑÐžÐœÐ³ÐµÑ, Ð¢ÐŸÐŽÐŽ Ð ÐžÐŽ, ÐÐžÐ»Ð» Ð ÐŸÐŽÐ¶ÐµÑÑ Ðž Ð¡ÑÑÐ°ÑÑ ÐÐ°ÑÑ - ÐŽÐ°ÑÑÐ»Ð°ÑÒÐ° Ò¯Ð»ÐºÐµÐœ Ò¯Ð»ÐµÑ ÒÐŸÑÒÐ°Ðœ Ð°Ð·Ð°ÐŒÐ°ÑÑÐ°Ñ. ÐÐ°Ò£Ð°Ð·ÐµÐ»Ð°ÐœÐŽÐžÑÐ»ÑÒ ÑÐ°ÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ° Ð¶ÐŸÐ±Ð°ÑÑ Ð¶Ð°ÑÐ°ÑÑÑÐ»Ð°ÑÐŽÑÒ£ ÑÐ°ÒÑ Ð±ÑÑ ÑÐŸÐ±Ñ: ÐÐ°ÑÐº ÐÐ¿Ð¿ÐµÑÐ»ÐµÐ¹, Ð¡Ð°Ð»Ð»Ðž ÐÐ¶ÐŸ ÐÐ°ÐœÐœÐžÐœÐ³ÐµÐŒ, Ð¡ÑÐžÐ² ÐÐ¶ÐŸÐœÑ, Ð¢Ñ Ð¢Ð°ÐºÐ° ÐÐžÐ³Ð°Ðœ, ÐÐ°Ð¹ÐºÐ» ÐÑÑÑ, ÐÐ°Ð»ÐžÐºÐ° ÐÐ°Ñ
+ÐŸÑÐž Ðž ÐÐ»ÐŸÐ¹ÐŽ Ð¡ÐŒÐžÑ - Ð±Ò¯ÐºÑÐ» Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° Ð¶Ò¯Ð¹ÐµÐœÑÒ£ ÐŽÐžÐ·Ð°Ð¹ÐœÑÐœ Ð¶Ð°ÑÐ°ÐŽÑ.
+ÐÑÐ· ÑÐŸÐœÐŽÐ°Ð¹-Ð°Ò GNU Ð»ÐžÑÐµÐœÐ·ÐžÑÑÑ ÒÐ°ÐŒÑÐžÑÑÒ£ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° Ð¿Ð°ÐºÐµÑÑÐµÑÐŽÑ: MG, GDBM, PDFTOHTML, WGET, WVWARE Ðž XLHTML - Ð¶Ð°ÑÐ°ÑÑÑÐ»Ð°ÑÒÐ° Ó©Ð· Ð°Ð»ÒÑÑÑÐŒÑÐ·ÐŽÑ Ð±ÑÐ»ÐŽÑÑÐµÐŒÑÐ·.}
+
+_textaboutgslong_ [l=kk] {Greenstone Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ° Ð¶Ð°Ð±ÐŽÑÒÑ ÑÑÑÐ°Ð»Ñ}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=kk] {ÐÒÑÐŒÐŽÐ°ÒÑ ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ»Ð°ÑÐŽÑÒ£ ÑÑÐ·ÑÐŒÑ}
+_textuser_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ
+}
+_textas_ [l=kk] {ÐÓÐ»ÑÐŒÐµÑ Ð¶Ð°Ð·Ð±Ð°ÑÑÐœÑÒ£ Ð¶Ð°Ð¹-ÐºÒ¯Ð¹Ñ}
+_textgroups_ [l=kk] {ÑÐŸÐ¿ÑÐ°Ñ}
+_textcomment_ [l=kk] {ÐºÐŸÐŒÐŒÐµÐœÑÐ°ÑÐžÐ¹}
+_textadduser_ [l=kk] {ÐÐ°Ò£Ð° ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐœÑ ÒÐŸÑÑ}
+_textedituser_ [l=kk] {ÑÐµÐŽÐ°ÐºÑÐžÑÐ»Ð°Ñ}
+_textdeleteuser_ [l=kk] {Ð¶ÐŸÑ}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ Ð¶Ð°Ð¹Ð»Ñ Ð°ÒÐ¿Ð°ÑÐ°ÑÑÑ ÑÒ¯Ð·ÐµÑÑ}
+_textadduser_ [l=kk] {ÐÐ°Ò£Ð° ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐœÑ ÒÐŸÑÑ}
+
+_textaboutusername_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ Ð°ÑÑÐœÑÒ£ Ò±Ð·ÑÐœÐŽÑÒÑ 2-30 ÑÐžÐŒÐ²ÐŸÐ» Ð°ÑÐ°Ð»ÑÒÑÐœÐŽÐ° Ð±ÐŸÐ»ÑÑ ÒÐ°Ð¶ÐµÑ. ÐÐ» ÓÑÑÐ¿ÑÑÐº-ÑÐžÑÑÐ»Ñ ÑÐžÐŒÐ²ÐŸÐ»ÐŽÐ°Ñ, '.', Ð¶ÓÐœÐµ '_' Ð±ÐµÐ»Ð³ÑÐ»ÐµÑÑÐœÐµÐœ ÑÒ±ÑÐ°ÐŽÑ. }
+
+_textaboutpassword_ [l=kk] {ÐÐ°ÑÐŸÐ»Ñ 3 ÑÐµÐœ 128 ÑÐžÐŒÐ²ÐŸÐ»ÐŸÐ²ÒÐ° ÐŽÐµÐ¹ÑÐœ. ÐÐ°ÑÐŸÐ»Ñ ÑÐµÑÑÐœÐŽÐµ ÓÐŽÐµÑÑÐµÐ³Ñ Ð±Ð°ÑÑÐ»Ð°ÑÑÐœ  ASCII ÑÐžÐŒÐ²ÐŸÐ»ÐŽÐ°Ñ ÒÐŸÐ»ÐŽÐ°ÐœÑÐ»Ð° Ð°Ð»Ð°ÐŽÑ. }
+
+_textoldpass_ [l=kk] {ÐÐ³ÐµÑ Ð±ÐµÑÑÐ»Ð³ÐµÐœ Ð°Ð»Ð°Ò£ Ð±ÐŸÑ Ð±ÐŸÐ»ÑÐ° ÐŸÐœÐŽÐ° ÐµÑÐºÑ Ð¿Ð°ÑÐŸÐ»Ñ ÒÐŸÐ»ÐŽÐ°ÐœÑÐ»Ð°ÐŽÑ.}
+_textenabled_ [l=kk] {ÑÒ±ÒÑÐ°Ñ ÐµÑÑÐ»Ð³ÐµÐœ }
+_textdisabled_ [l=kk] {ÑÑÐ¹ÑÐŒ ÑÐ°Ð»ÑÐœÒÐ°Ðœ}
+
+_textaboutgroups_ [l=kk] {Ð¢ÐŸÐ¿ÑÐ°Ñ â Ò¯ÑÑÑ Ð°ÑÒÑÐ»Ñ Ð±Ó©Ð»ÑÐœÐ³ÐµÐœ ÑÑÐ·ÑÐŒ, Ò¯ÑÑÑÐŽÐµÐœ ÐºÐµÐ¹ÑÐœ Ð¿ÑÐŸÐ±ÐµÐ» ÒÐŸÐ¹ÑÐ»ÐŒÐ°Ð¹ÐŽÑ! }
+_textavailablegroups_ [l=kk] {ÐÐ»ÐŽÑÐœ Ð°Ð»Ð° Ð°ÐœÑÒÑÐ°Ð»ÒÐ°Ðœ ÑÐŸÐ¿ÑÐ°Ñ Ð±Ð°ÑÒÐ°ÑÑÑÑ ÐŒÐµÐœ ÐÐµÐ¿ÐŸÐ·ÐžÑÐŸÑ ÐœÐµÐŒÐµÑÐµ ÐÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°Ð»ÑÒ ÐÐœÑÐµÑÑÐµÐ¹ÑÑÑ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÑÐŒÐµÐœ Ð¶ÐžÐœÐ°ÒÑÑÒ£ Ð¶ÐŸÐ¹ÑÐ»ÒÐ°Ðœ ÒÒ±ÑÑÐ»ÑÐŒÑ Ò¯ÑÑÐœ ÒÒ±ÒÑÒÑÑ ÑÐ°ÒÐ°Ð¹ÑÐœÐŽÐ°ÑÑÑÐ»Ð°ÑÐŽÑ ÐµÐœÐ³ÑÐ·ÐµÐŽÑ. 
+<ul>
+<li><b>Ð±Ð°ÑÒÐ°ÑÑÑÑ</b>: ÐÑÑÑÐ³Ðµ Ð¶ÓÐœÐµ ÑÐ°Ð¹Ñ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÑÑÑÐœÑÒ£ Ó©Ð·Ð³ÐµÑÑÑÐœÐµ Ð¶ÓÐœÐµ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÑÑÐ»Ð°ÑÐŽÑÒ£ ÐºÑÑÑÑÐœÐµ ÒÒ±ÒÑ Ð±ÐµÑÐµÐŽÑ. 
+<li><b>ÐŽÐµÑÐ±ÐµÑ-ÑÐµÐŽÐ°ÐºÑÐŸÑ-Ð¶ÐžÐœÐ°ÒÑ</b>: ÐÐ°Ò£Ð° ÐŽÐµÑÐ±ÐµÑ Ð¶ÐžÐœÐ°ÒÑÐ°ÑÐŽÑ Ð¶Ð°ÑÐ°ÑÒÐ° ÒÒ±ÒÑ Ð±ÐµÑÐµÐŽÑ.  
+<li><b><collection-name>-ÑÐµÐŽÐ°ÐºÑÐŸÑ-Ð¶ÐžÐœÐ°ÒÑ</b>: ÐÐžÐœÐ°ÒÑÑ ÑÐµÐŽÐ°ÐºÑÐžÑÐ»Ð°Ñ ÐŒÐµÐœ Ð¶Ð°ÑÐ°Ñ Ò¯ÑÑÐœ ÒÒ±ÒÑ Ð±ÐµÑÐµÐŽÑ collection-name", ÐŒÑÑÐ°Ð»Ñ, Ð¶ÐžÐœÐ°ÒÑÑÒ£-ÐµÑÐµÐ¿ Ð±ÐµÑÑ-ÑÐµÐŽÐ°ÐºÑÐŸÑÑ.
+<li><b>Ð±Ð°ÑÐ»ÑÒ-Ð¶ÐžÐœÐ°ÒÑÐ°ÑÐŽÑÒ£-ÑÐµÐŽÐ°ÐºÑÐŸÑÑ</b>: ÓÐ·ÑÑÐ»ÐµÐ¹ ÐŒÐµÐœ Ó©Ò£ÐŽÐµÑÐ³Ðµ ÒÒ±ÒÑ Ð±ÐµÑÐµÐŽÑ<b>Ð²ÑÐµÑ
+</b> Ð¶Ð°Ò£Ð° ÐŽÐµÑÐ±ÐµÑ Ð¶ÓÐœÐµ ÒÐ°Ð»Ð°ÐŒÐŽÑÒ Ð¶ÐžÐœÐ°ÒÑÐ°ÑÒÐ°.
+</ul>
+}  
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐœÑ Ð°Ð»ÑÐ¿ ÑÐ°ÑÑÐ°Ñ}
+_textremwarn_ [l=kk] {Ð¡ÑÐ· ÑÑÐœÑÐŒÐµÐœÐµÐœ ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ _cgiargumun_ ÐŽÑ ÑÒ¯Ð¿ÐºÑÐ»ÑÐºÑÑ Ð°Ð»ÑÐ¿ ÑÐ°ÑÑÐ°Ð¹ÑÑÐ· Ð±Ð°?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=kk] {ÐÐ°ÑÐŸÐ»ÑÐŽÑ Ó©Ð·Ð³ÐµÑÑÑ}
+_textoldpw_ [l=kk] {ÐÑÐºÑ Ð¿Ð°ÑÐŸÐ»Ñ}
+_textnewpw_ [l=kk] {ÐÐ°Ò£Ð° Ð¿Ð°ÑÐŸÐ»Ñ}
+_textretype_ [l=kk] {ÐÐ°Ò£Ð° Ð¿Ð°ÑÐŸÐ»ÑÐŽÑ ÒÐ°Ð¹ÑÐ°Ð»Ð°Ð¿ ÐµÐœÐ³ÑÐ·ÑÒ£ÑÐ·}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=kk] {Ð¡ÑÐ·ÐŽÑÒ£ Ð¿Ð°ÑÐŸÐ»ÑÒ£ÑÐ· ÑÓÑÑÑ Ó©Ð·Ð³ÐµÑÑÑÐ»ÐŽÑ.}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ Ð°ÑÑ - ÒÐ°ÑÐµ}
+_textinvalidpassword_ [l=kk] {ÒÐ°ÑÐµ Ð¿Ð°ÑÐŸÐ»Ñ.}
+_textemptypassword_ [l=kk] {ÐÑÑ ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÒÐ° Ð°ÑÐœÐ°Ð»ÒÐ°Ðœ Ð±Ð°ÑÑÐ°Ð¿ÒÑ Ð¿Ð°ÑÐŸÐ»ÑÐŽÑ ÐµÐœÐ³ÑÐ·ÑÒ£ÑÐ·}
+_textuserexists_ [l=kk] {ÐÒ±ÐœÐŽÐ°Ð¹ Ð°ÑÑÑ ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ Ð±Ò±ÑÑÐœÐœÐ°Ðœ Ð±Ð°Ñ, Ð±Ð°ÑÒÐ°ÒÐ° Ó©Ð·Ð³ÐµÑÑÑÒ£ÑÐ·}
+
+_textusernameempty_ [l=kk] {ÐÐ°Ò£Ð° Ð¿Ð°ÑÐŸÐ»ÑÒ£ÑÐ·ÐŽÑ ÐµÐœÐ³ÑÐ·ÑÐ¿, ÐŸÐœÑ ÑÐ°ÑÑÐ°Ò£ÑÐ·}
+_textpasswordempty_ [l=kk] {ÐÑÐºÑ Ð¿Ð°ÑÐŸÐ»ÑÒ£ÑÐ·ÐŽÑ ÐµÐœÐ³ÑÐ·ÑÑÒ£ÑÐ· ÐºÐµÑÐµÐº}
+_textnewpass1empty_ [l=kk] {ÐÐ°Ò£Ð° Ð¿Ð°ÑÐŸÐ»ÑÒ£ÑÐ·ÐŽÑ ÐµÐœÐ³ÑÐ·ÑÒ£ÑÐ·, ÐŸÐŽÐ°Ðœ ÐºÐµÐ¹ÑÐœ ÐŸÐœÑ ÒÐ°Ð¹ÑÐ°Ð»Ð°Ð¿ Ð±Ð°ÑÑÒ£ÑÐ·}
+_textnewpassmismatch_ [l=kk] {Ð¡ÑÐ·ÐŽÑÒ£ Ð¶Ð°Ò£Ð° Ð¿Ð°ÑÐŸÐ»ÑÒ£ÑÐ·ÐŽÑÒ£ ÑÒ¯ÑÐ»Ñ ÐœÒ±ÑÒÐ°Ð»Ð°ÑÑ ÐµÐœÐ³ÑÐ·ÑÐ»ÐŽÑ}
+_textnewinvalidpassword_ [l=kk] {Ð¡ÑÐ·ÐŽÑÒ£ ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ Ð°ÑÑÒ£ÑÐ· ÐœÐµÐŒÐµÑÐµ Ð¿Ð°ÑÐŸÐ»ÑÒ£ÑÐ· ÐŽÒ±ÑÑÑ ÐµÐœÐ³ÑÐ·ÑÐ»ÐŒÐµÐ³ÐµÐœ.}
+_textfailed_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ Ð°ÑÑ ÐœÐµÐŒÐµÑÐµ Ð¿Ð°ÑÐŸÐ»Ñ ÐŽÒ±ÑÑÑ ÑÐµÑÑÐ»ÐŒÐµÐ³ÐµÐœ.}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=kk] {Greenstone ÐœÒ±ÑÒÐ°ÑÑ}
+_textframebrowser_ [l=kk] {ÐÒ±ÐœÑÒ£ ÑÑÑÐœÐŽÐµÐ³ÑÐœÑ ÒÐ°ÑÐ°Ñ Ò¯ÑÑÐœ Ð±ÑÐ°ÑÐ·ÐµÑÑÒ£ÑÐ·Ð³Ðµ ÑÑÐµÐ¹ÐŒÐŽÐµÑÐŽÑ ÒÐŸÐ»ÐŽÐ°ÐœÑ ÑÒ±ÒÑÐ°ÑÑÐœ ÐŸÑÐœÐ°ÑÑÑÒ£ÑÐ· ÒÐ°Ð¶ÐµÑ.}
+_textusermanage_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ»Ð°ÑÐŽÑ Ð±Ð°ÑÒÐ°ÑÑ}
+_textlistusers_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ»Ð°Ñ ÑÑÐ·ÑÐŒÑ}
+_textaddusers_ [l=kk] {ÐÐ°Ò£Ð° ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐœÑ ÒÐŸÑÑ}
+_textchangepasswd_ [l=kk] {ÐÐ°ÑÐŸÐ»ÑÐŽÑ Ó©Ð·Ð³ÐµÑÑÑ}
+_textinfo_ [l=kk] {Ð¢ÐµÑ
+ÐœÐžÐºÐ°Ð»ÑÒ Ð°ÒÐ¿Ð°ÑÐ°Ñ}
+_textgeneral_ [l=kk] {ÐÐ°Ð»Ð¿Ñ}
+_textarguments_ [l=kk] {Ð°ÑÐ³ÑÐŒÐµÐœÑÑÐµÑ}
+_textactions_ [l=kk] {ÓÑÐµÐºÐµÑÑÐµÑ}
+_textbrowsers_ [l=kk] {ÒÐ°ÑÐ°ÑÐ»Ð°Ñ}
+_textprotocols_ [l=kk] {Ð¿ÑÐŸÑÐŸÐºÐŸÐ»ÐŽÐ°ÑÑ}
+_textconfigfiles_ [l=kk] {ÐÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÑ ÑÐ°Ð¹Ð»Ñ}
+_textlogs_ [l=kk] {Ð¢ÑÑÐºÐµÐ»Ñ}
+_textusagelog_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑ ÑÑÑÐºÐµÑÑ}
+_textinitlog_ [l=kk] {Ð¢ÑÑÐºÐµÐ»Ñ Ð±Ð°ÑÑ}
+_texterrorlog_ [l=kk] {ÑÑÑÐºÐµÑ ÒÐ°ÑÐµÑÑ}
+_textadminhome_ [l=kk] {Ð°ÐŽÐŒÐžÐœÐžÑÑÑÐ°ÑÐŸÑÐŽÑÒ£ Ð±Ð°ÑÑÐ°Ð¿ÒÑ Ð¿Ð°ÑÐ°ÒÑ}
+_textreturnhome_ [l=kk] {Greenstone-ÐœÑÒ£ Ð²ÐµÐ±-Ð¿Ð°ÑÐ°ÒÑ}
+_titlewelcome_ [l=kk] {ÐÐŽÐŒÐžÐœÐžÑÑÑÐ°ÑÐžÑÐ»Ð°Ñ}
+_textmaas_ [l=kk] {ÐÐŽÐŒÐžÐœÐžÑÑÑÐ°ÑÐŸÑ ÐŒÐµÐœ ÐÐžÐœÐ°Ò Ò±ÑÑÐ°ÑÑÑÐœÑÒ£ ÒÑÐ·ÐŒÐµÑ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐ³ÑÐœÐµ Ð¶Ð°ÑÐ°ÐŽÑ:}
+_textvol_ [l=kk] {on-line ÑÑÑÐºÐµÑÑÐœ ÒÐ°ÑÐ°Ñ}
+_textcmuc_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ Ð¶Ð°ÑÐ°Ñ, ÒÐŸÐ»ÐŽÐ°Ñ Ð¶ÓÐœÐµ Ð¶Ð°Ò£Ð°ÑÑÑ}
+_textati_ [l=kk] {CGI Ð¿Ð°ÑÐ°ÐŒÐµÑÑÐ»Ñ ÑÐµÑ
+ÐœÐžÐºÐ°Ð»ÑÒ Ð°ÒÐ¿Ð°ÑÐ°ÑÒÐ° ÑÒ±ÒÑÐ°Ñ}
+
+_texttsaa_ [l=kk] {ÐÒ±Ð» ÒÑÐ·ÐŒÐµÑÑÐµÑÐ³Ðµ Ð¿Ð°ÑÐ°ÒÑÑÒ£ ÑÐŸÐ» Ð¶Ð°ÒÑÐœÐŽÐ°ÒÑ ÐœÐ°Ð²ÐžÐ³Ð°ÑÐžÑÐ»ÑÒ ÐŒÐµÐœÑ Ð°ÑÒÑÐ»Ñ ÒÐŸÐ» Ð¶ÐµÑÐºÑÐ·ÑÐ³Ðµ Ð±ÐŸÐ»Ð°ÐŽÑ.}
+
+_textcolstat_ [l=kk] {ÐÐžÐœÐ°Ò ÑÑÐ°ÑÑÑÑ}
+
+_textcwoa_ [l=kk] {ÐÐžÐœÐ°ÒÑÐ°Ñ, ÐµÐ³ÐµÑ ÐŸÐ»Ð°ÑÐŽÑÒ£ build.cfg ÑÐ°Ð¹Ð»Ñ Ð±ÐŸÐ»ÑÐ°, builddate Ð°Ð»Ð°Ò£ÑÐ°ÑÑ ÒÐ°Ð¶ÐµÑÑÑ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐ³ÑÐœ ÒÐ°ÐŒÑÑÐ¿ (ÑÒÐœÐž > 0) ÐžÐœÐŽÐµÐºÑÑÑÐº ÐºÐ°ÑÐ°Ð»ÐŸÐ³ÑÐœÐŽÐµ ÑÐ°Ð±ÑÐ»ÑÐ° (ÑÒÐœÐž ÒÐ°Ð»ÑÐ¿ÑÐ°ÑÑÑÑÑ ÐºÐ°ÑÐ°Ð»ÐŸÐ³Ñ ÐÐÐÐ¡),  ÐÐžÐœÐ°ÒÑÐ°Ñ "ÐŸÑÑÐœÐŽÐ°Ð»Ð°ÑÑÐœ" Ð±ÐŸÐ»ÑÐ¿ Ð¿Ð°Ð¹ÐŽÐ° Ð±ÐŸÐ»Ð°ÐŽÑ.}
+
+_textcafi_ [l=kk] {ÐÐžÐœÐ°Ò ÑÑÑÐ°Ð»Ñ ÐŒÓÐ»ÑÐŒÐµÑ Ð°Ð»Ñ Ò¯ÑÑÐœ <i> abbrev. </i>  Ð±Ð°ÑÑÒ£ÑÐ·}
+_textcctv_ [l=kk] {ÐÐžÐœÐ°ÒÑÑ ÒÐ°ÑÐ°Ñ Ò¯ÑÑÐœ <i> collection </i> Ð±Ð°ÑÑÒ£ÑÐ·}
+_textsubc_ [l=kk] {ÓšÐ·Ð³ÐµÑÑÑÐ»ÐµÑÐŽÑ ÑÐ°ÑÑÐ°Ò£ÑÐ·}
+_texteom_ [l=kk] {main.cfg-ÐŽÑ Ð°ÑÑ ÒÐ°ÑÐµÑÑ}
+_textftum_ [l=kk] {main.cfg Ð¶Ð°Ò£Ð°ÑÑÑ Ð±Ð°ÑÑÑÑÐœÐŽÐ°ÒÑ Ð¶Ð°Ò£ÑÐ»ÑÑ}
+_textmus_ [l=kk] {main.cfg Ð¶Ð°Ò£Ð°ÑÑÑÐ»ÑÑ ÑÓÑÑÑ Ð°ÑÒÑÐ°Ð»ÐŽÑ}
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=kk] {ÐÐžÐœÐ°ÒÑÑÒ£ ÒÐ°Ð»ÑÐ¿ÑÐ°ÑÑÑÑÑ Ò¯ÑÐŽÑÑÑÐœÑÒ£ ÑÐµÐ·ÑÐŒÐµÑÑ _collectionname_ }  
+_textflog_ [l=kk] {_collectionname_ ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐ»Ð°ÑÒÐ° Ð°ÑÐœÐ°Ð»ÒÐ°Ðœ Ð¶Ð°Ò£ÑÐ»ÑÑÑÐ°Ñ ÑÑÑÐºÐµÑ ÑÐ°Ð¹Ð»Ñ}  
+_textilog_ [l=kk] {"_collectionname_" ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ Ð¶ÑÑÐœÐ°Ð»ÑÐœÑÒ£ ÐžÐŒÐ¿ÐŸÑÑÑ}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=kk] {ÐÐÐ£ÐÐ ÐÐÐÐÐ ÐÒ¢ÐÐ}  
+
+_greenstoneusabilitytext_ [l=kk] {Greenstone ÒÐŸÐ»ÐŽÐ°ÐœÑÐ»ÑÑ}
+
+_textwhy_ [l=kk] {<p> ÐÒ±Ð» Ñ
+Ð°Ð±Ð°ÑÐ»Ð°ÐŒÐ°ÐœÑ Ð¶ÑÐ±ÐµÑÑ - ÒÐ°ÑÐ°ÑÑ ÒÐžÑÐœ Ð²ÐµÐ±-Ð¿Ð°ÑÐ°ÒÑÑ ÑÐ°Ð¿ÒÐ°ÐœÑÒ£ÑÐ·ÐŽÑ ÐºÓ©ÑÑÐµÑÐµÑÑÐœ Ð±ÐµÐ»Ð³Ñ.}
+_textextraforform_ [l=kk] {Ð¡ÑÐ· Ð±Ò±Ð» ÑÐŸÑÐŒÐ°ÐœÑ ÑÐŸÐ»ÑÑÑÐŒÐ°ÑÑÒ£ÑÐ· ÐºÐµÑÐµÐº  - ÐºÐµÐ·-ÐºÐµÐ»Ð³ÐµÐœ Ð°ÒÐ¿Ð°ÑÐ°Ñ ÐºÓ©ÐŒÐµÐºÑÐµÑÐµÐŽÑ.}
+_textprivacybasic_ [l=kk] {<p>The report will contain only information about the Greenstone web page you were viewing, and the technology you were using to view it (plus any optional information you provide).; <p> ÐÒ±Ð» Ñ
+Ð°Ð±Ð°ÑÐ»Ð°ÐŒÐ° ÑÐµÐº ÒÐ°ÐœÐ° Greenstone Ð²ÐµÐ±-Ð¿Ð°ÑÐ°ÒÑ ÑÑÑÐ°Ð»Ñ, ÑÒÐœÐž Ð¡ÑÐ· ÒÐ°ÑÐ°ÑÑÑÑÒÐ°Ðœ, Ð¶ÓÐœÐµ ÐŸÐœÑ ÒÐ°ÑÐ°Ñ Ò¯ÑÑÐœ Ð¡ÑÐ· ÒÐŸÐ»ÐŽÐ°ÐœÒÐ°Ðœ ÑÐµÑ
+ÐœÐŸÐ»ÐŸÐ³ÐžÑ ÑÑÑÐ°Ð»Ñ (ÑÐŸÐœÑÐŒÐµÐœ Ð±ÑÑÐ³Ðµ Ð¡ÑÐ· Ò±ÑÑÐœÐ°ÑÑÐœ ÐºÐµÐ·-ÐºÐµÐ»Ð³ÐµÐœ ÒÐŸÑÑÐŒÑÐ° ÐŒÓÐ»ÑÐŒÐµÑ),  Ð°ÒÐ¿Ð°ÑÐ°Ñ Ð±ÐµÑÐŒÐµÐº. }
+_textstillsend_ [l=kk] {Ð¡ÑÐ· Ð±Ò±Ð» Ñ
+Ð°Ð±Ð°ÑÐ»Ð°ÐŒÐ°ÐœÑ ÓÐ»Ñ ÐŽÐµ Ð¶ÑÐ±ÐµÑÐ³ÑÒ£ÑÐ· ÐºÐµÐ»Ðµ ÐŒÐµ?}
+
+_texterror_ [l=kk] {ÒÐ°ÑÐµ}
+_textyes_ [l=kk] {ÐÓ}
+_textno_ [l=kk] {ÐÐŸÒ}
+_textclosewindow_ [l=kk] {Ð¢ÐµÑÐµÐ·ÐµÐœÑ Ð¶Ð°Ð±Ñ}
+_textabout_ [l=kk] {ÑÑÑÐ°Ð»Ñ}
+_textprivacy_ [l=kk] {ÒÒ±Ð¿ÐžÑ}
+_textsend_ [l=kk] {ÐÑÐ±ÐµÑÑ}
+_textdontsend_ [l=kk] {ÐÑÐ±ÐµÑÐŒÐµÑ}
+_textoptionally_ [l=kk] {ÐÑÑÐºÑÑ}
+
+_textunderdev_ [l=kk] {ÐÐ»ÐŽÑÐœ Ð°Ð»Ð° ÑÐŸÐ»ÑÒ ÒÐ°ÑÐ°Ñ ÒÐŸÑÑÑÑÐœÐŽÑ Ð¶ÐŸÐ±Ð°ÐŽÐ° ÐŒÒ¯ÐŒÐºÑÐœ Ð±ÐŸÐ»Ð°ÐŽÑ}
+
+_textviewdetails_ [l=kk] {ÒÐ°ÑÐ°Ñ ÑÑÑÐ°Ð»Ñ ÑÐŸÐ»ÑÒ Ñ
+Ð°Ð±Ð°ÑÐ»Ð°ÐŒÐ°}
+_textmoredetails_ [l=kk] {ÐÐ°ÑÑÐœÑÐ° Ð°ÐœÑÒÑÑÒ}
+_texttrackreport_ [l=kk] {ÐÒ±Ð» Ñ
+Ð°Ð±Ð°ÑÐ»Ð°ÐŒÐ°ÐœÑ ÒÐ°ÐŽÐ°ÒÐ°Ð»Ð°Ñ}
+_textcharacterise_ [l=kk] {ÐÒ±Ð» ÒÐ°ÐœÐŽÐ°Ð¹ Ð¿ÑÐŸÐ±Ð»ÐµÐŒÐ° }
+_textseverity_ [l=kk] {ÐÑÐŸÐ±Ð»ÐµÐŒÐ° ÒÐ°ÐœÑÐ°Ð»ÑÒÑÑ ÐºÒ¯ÑÐŽÐµÐ»Ñ}
+ 
+_textbadrender_ [l=kk] {ÐÐ°ÑÐ°Ò ÑÒ¯ÑÑÐœÑÐºÑÑÐ·}
+_textcontenterror_ [l=kk] {ÐÐ°Ð·ÐŒÒ±Ðœ ÒÐ°ÑÐµÑÑ}
+_textstrangebehaviour_ [l=kk] {Ð¢Ð°Ò£ÒÐ°Ð»Ð°ÑÐ»ÑÒ Ð¶Ð°Ð¹Ñ}
+_textunexpected_ [l=kk] {ÐÒ¯ÑÐ¿ÐµÐ³ÐµÐœ Ð¶Ð°Ð¹Ñ}
+_textfunctionality_ [l=kk] {ÐÐ°Ð¹ÐŽÐ°Ð»Ð°ÐœÑ ÒÐžÑÐœ}
+_textother_ [l=kk] {ÐÐ°ÑÒÐ°}
+
+_textcritical_ [l=kk] {ÒÐ°ÑÑÐ¿ÑÑ ÑÓÑ}
+_textmajor_ [l=kk] {ÐÐ°Ð¹ÑÐ¿ÑÑ}
+_textmedium_ [l=kk] {ÐÑÑÐ°ÑÐ°}
+_textminor_ [l=kk] {Ð«ÒÑÐ°ÐŒ}
+_texttrivial_ [l=kk] {Ð¢ÑÐžÐ²ÐžÐ°Ð»ÐŽÑÒ}
+
+_textwhatdoing_ [l=kk] {Ð¡ÑÐ· ÐœÐµ ÑÑÑÐµÐ¿ ÐºÓ©ÑÐŽÑÒ£ÑÐ·?}
+_textwhatexpected_ [l=kk] {Ð¡ÑÐ· ÐºÒ¯ÑÐºÐµÐœÐŽÐµÐ¹ Ð±ÐŸÐ»ÐŽÑ ÐŒÐ°?}
+_textwhathappened_ [l=kk] {ÐšÑÐœ ÐŒÓÐœÑÐœÐŽÐµ ÐœÐµ Ð±ÐŸÐ»ÐŽÑ?}
+
+_cannotfindcgierror_ [l=kk] {<h2>ÓšÐºÑÐœÑÑÐºÐµ ÐŸÑÐ°Ð¹</h2>"ÐŒÐµÐœ Ñ
+Ð°Ð±Ð°ÑÐ»Ð°ÒÑÐŒ ÐºÐµÐ»ÐŽÑ" Ð±Ð°ÑÑÑÐŒÐ°ÑÑÐœÐ° ÑÐµÑÐ²ÐµÑÐŽÐµÐ³Ñ Ð±Ð°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°Ð»Ð°ÑÐŽÑ ÑÐ°Ð±Ñ ÐŒÒ¯ÐŒÐºÑÐœ ÐµÐŒÐµÑ }  
+
+_textusabbanner_ [l=kk] {Greenstone koru-ÑÑÐžÐ»ÑÐœÐŽÐµÐ³Ñ Ð±Ð°ÐœÐœÐµÑ }
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=kk] {ÒÐ°ÑÐµÐ»ÑÐº ÑÑÑÐœÐŽÐ°ÐŽÑ}  
+
+_textgtihome_ [l=kk] {ÐÒ±Ð» Ð±ÐµÑÑÐµÑ ÑÑÐ·Ð³Ðµ Ð³ÑÐžÐœÑÑÐŸÑÐœÐœÑÒ£ ÐºÓ©Ð¿ ÑÑÐ»ÐŽÑ ÒÐŸÐ»ÐŽÐ°ÑÑÐœ Ð¶Ð°ÒÑÐ°ÑÑÑÒÐ° ÐºÓ©ÐŒÐµÐºÑÐµÑÐµÐŽÑ.
+ÐÐµÑÑÐµÑÐŽÑ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÐ¿, <ul> ÑÑÐ· <li>ÐÑÐžÐœÑÑÐŸÑÐœÐœÑÒ£ ÐžÐœÑÐµÑÑÐµÐ¹Ñ Ð±Ó©Ð»ÑÐºÑÐµÑÑÐœ Ð¶Ð°Ò£Ð° ÑÑÐ»ÐŽÐµÑÐ³Ðµ Ð°ÑÐŽÐ°ÑÐ° Ð°Ð»Ð°ÑÑÐ·.
+<li> ÐÐ³ÐµÑ Ð°ÒÑÐ»ÑÑÐœ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑ Ó©Ð·Ð³ÐµÑÑÐµ  (ÐŒÑÑÐ°Ð»Ñ
+ÐÑÐžÐœÑÑÐŸÑÐœÐœÑÒ£ Ð¶Ð°Ò£Ð° ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐºÑÐµÑÑ Ò¯ÑÑÐœ), ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ°ÒÑ ÐžÐœÑÐµÑÑÐµÐ¹Ñ ÑÑÐ»ÐŽÐµÑÑÐœ Ð¶Ð°Ò£Ð°ÑÑÑ
+<li> ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ°ÒÑ Ð°ÑÐŽÐ°ÑÐŒÐ°ÐŽÐ°ÒÑ ÒÐ°ÑÐµÐ»ÑÐºÑÐµÑÐŽÑ Ð¶Ó©ÐœÐŽÐµÑ. </ul>
+Ð¡ÑÐ·Ð³Ðµ ÓÑÒÐ°Ð¹ÑÑÑÑÐœÐŽÐ° Ð°ÑÐŽÐ°ÑÐŒÐ° ÑÑÐ°Ð·Ð°ÑÑ Ð±Ð°Ñ Ð²ÐµÐ± Ð±ÐµÑÑÐµÑ ÑÐµÑÐžÑÐ»Ð°ÑÑ Ò±ÑÑÐœÑÐ»Ð°ÐŽÑ. 
+Ð¡ÑÐ· ÐžÐœÑÐµÑÑÐµÐ¹ÑÑÑ ÑÐµÑÑÐŒÐµÐœ Ð±ÑÑ-Ð±ÑÑ ÑÑÐ°Ð·Ð°ÐŽÐ°Ðœ Ð°ÑÐŽÐ°ÑÐ° Ð°Ð»Ð°ÑÑÐ·. 
+Ð€ÐŸÑÐŒÐ°ÑÑÐ°Ñ ÐºÐŸÐŒÐ°ÐœÐŽÐ°ÑÑ HTML ÐºÓ©Ð¿ ÑÑÐ°Ð·Ð°ÐŽÐ°Ðœ ÑÒ±ÑÐ°ÐŽÑ:
+ÐÐ»Ð°ÑÐŽÑ Ð°ÑÐŽÐ°ÑÑÒÐ° ÑÑÑÑÑÐ¿Ð°Ò£ÑÐ·, Ð±ÑÑÐ°Ò ÐŸÐ»Ð°ÑÐŽÑ ÒÐŸÑÒÐ°Ò£ÑÐ·.
+Ð¢Ó©ÐŒÐµÐœÐ³Ñ ÑÑÐ·ÑÒÑ Ð±Ð°Ñ ÑÓ©Ð·ÐŽÐµÑ (tipa_etogo_) Ð°ÑÐŽÐ°ÑÑÐ»ÐŒÐ°ÑÑ ÑÐžÑÑ  (Ð±Ò¯Ð» ÐÑÐžÐœÑÑÐŸÑÐœÐœÑÒ£ "ÐŒÐ°ÐºÑÐŸ" Ð°ÑÐ°ÑÑ).
+<p>
+ÐÐ³ÐµÑ ÑÑÐ· ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ°ÒÑ ÑÑÐ» ÐžÐœÑÐµÑÑÐµÐ¹ÑÑÐœ Ð¶Ð°Ò£Ð°ÑÑÑÐ°Ò£ÑÐ· Ð¶ÓÐœÐµ ÑÑÐ·Ð³Ðµ Ð°ÑÐŽÐ°ÑÑÐ»ÒÐ°Ðœ ÑÑÐ°Ð·Ð°Ð»Ð°Ñ ÐºÓ©ÑÑÐµÑÑÐ»ÐŒÐµÑÐµ. 
+ÐÐµÐ¹ÐŽÐµ Ð°ÑÐŽÐ°ÑÐŒÐ°Ð±ÐŸÐ»ÒÐ°ÐœÑÐŒÐµÐœ, Ð°ÒÑÐ»ÑÑÐœ ÑÑÐ»ÑÐœÐŽÐµÐ³Ñ ÐŒÓÑÑÐœ Ó©Ð·Ð³ÐµÑÑÑÐ»Ð³ÐµÐœ. ÐÒ±Ð» Ð¶Ð°ÒÐŽÐ°Ð¹ÐŽÐ° Ð°ÒÑÐŒÐŽÐ°ÒÑ Ð°ÑÐŽÐ°ÑÑÐŒ, ÑÐµÐºÑÐµÑÑÐ¿ Ð¶ÓÐœÐµ ÒÐ°Ð¶ÐµÑ Ð±ÐŸÐ»ÒÐ°Ðœ Ð¶Ð°ÒÐŽÐ°Ð¹ÐŽÐ° Ð¶Ð°Ò£Ð°ÑÑÑ Ò¯ÑÑÐœ ÑÑÐ·Ð³Ðµ ÒÐ°Ð¹ÑÐ°Ò±ÑÑÐœÑÐ»Ð°ÐŽÑ.
+<p>
+ÐÐ°Ò£Ð°ÑÑÑÐ»ÒÐ°Ðœ Ð°ÑÐŽÐ°ÑÑÐŒÐŽÑ ÐºÐŸÑÑÐµÐºÑÐžÑÐ»Ð°Ñ Ò¯ÑÑÐœ 
+"ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ°ÒÑ Ð°ÑÐŽÐ°ÑÑÐŒÐŽÑ ÐºÐŸÑÑÐµÐºÑÐžÑÐ»Ð°ÑÐŽÑ" Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÒ£ÑÐ· ÐÑÐžÐœÑÑÐŸÑÐœÐœÑÒ£ ÓÑ Ð±Ó©Ð»ÑÐ³Ñ Ò¯ÑÑÐœ ÒÐŸÐ» Ð¶ÐµÑÐµÑÐ»ÑÐº ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐº.
+<p>
+ÓÑÐ±ÑÑ Ð±ÐµÑ "_textgtisubmit_" ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐŒÐµÐœ Ð°ÑÒÑÐ°Ð»Ð°ÐŽÑ.
+ÐÐ³ÐµÑ ÑÑÐ· ÐŸÐœÑ Ð±Ð°ÑÑÐ°Ò£ÑÐ·, Ó©Ð·Ð³ÐµÑÑÑÑÐµÑ Ð±ÑÑÐŽÐµÐœ ÐºÒ¯ÑÑÐœÐµ ÐµÐœÐµÐŽÑ Ð¶ÓÐœÐµ ÐÑÐžÐœÑÑÐŸÑÐœÐœÑÒ£ nzdl.org. Ð¶ÐµÐºÐµ ÒÒ±ÑÑÐ»ÒÑ Ð¿Ð°ÐºÐµÑÑÐœÐŽÐµ  Ð¿Ð°Ð¹ÐŽÐ° Ð±ÐŸÐ»Ð°ÐŽÑ. ÐÑÑ ÑÐ°Ð¹ÑÒÐ° ÐºÑÑÑ Ò¯ÑÑÐœ
+ÓÑÐ±ÑÑ Ð±ÐµÑÑÐµ ÐºÐœÐŸÐ¿ÐºÐ° Ð±ÐµÑÑÐ»Ð³ÐµÐœ.
+}  
+
+_textgtiselecttlc_ [l=kk] {Ð¢ÑÐ» ÑÐ°Ò£ÐŽÐ°Ò£ÑÐ·}  
+
+#for status page
+_textgtiviewstatus_ [l=kk] {ÐÑÐŽÐ°ÑÑÐŒÐœÑÒ£ Ð±Ð°ÑÐ»ÑÒ ÑÑÐ»ÐŽÐµÑÑÐœÑÒ£ Ð°ÒÑÐŒÐŽÐ°ÒÑ ÑÑÐ°ÑÑÑÑÐœ ÑÐµÐºÑÐµÑÑ Ò¯ÑÑÐœ ÐŒÑÑÐºÐ°ÐœÑ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°Ò£ÑÐ·}  
+_textgtiviewstatusbutton_ [l=kk] {ÒÐÐ ÐÐ£ Ð¡Ð¢ÐÐ¢Ð£Ð¡Ð«}  
+_textgtistatustable_ [l=kk] {ÐÒÑÐŒÐŽÐ°ÒÑ Ð°ÑÐŽÐ°ÑÑÐŒÐŽÐ°ÑÐŽÑÒ£ Ð±Ð°ÑÐ»ÑÒ ÑÑÐ»ÐŽÐµÑ Ò¯ÑÑÐœ ÑÑÐ°ÑÑÑÑ}  
+_textgtilanguage_ [l=kk] {Ð¢ÑÐ»}  
+_textgtitotalnumberoftranslations_ [l=kk] {ÐÑÐŽÐ°ÑÑÐŒÐŽÐ°ÑÐŽÑÒ£ Ð¶Ð°Ð»Ð¿Ñ ÐŒÓ©Ð»ÑÐµÑÑ}  
+
+_textgtiselecttfk_ [l=kk] {ÐÒ±ÐŒÑÑ ÑÑÑÐµÑ Ò¯ÑÑÐœ ÑÐ°Ð¹Ð»ÐŽÑ ÑÐ°Ò£ÐŽÐ°Ò£ÑÐ·}  
+
+_textgticoredm_ [l=kk] {ÐÑÐžÐœÑÑÐŸÑÐœ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑ (Core)}  
+_textgtiauxdm_ [l=kk] {ÐÑÐžÐœÑÑÐŸÑÐœ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑ (Auxiliary)}  
+_textgtiglidict_ [l=kk] {ÐÐœÑÐµÑÑÐµÐ¹Ñ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÑÑÑÑÐœÑÒ£ ÑÓ©Ð·ÐŽÑÐ³Ñ (GLI)}  
+_textgtiglihelp_ [l=kk] {ÐÐœÑÐµÑÑÐµÐ¹Ñ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÑÑÑÑÐœÑÒ£ ÐºÓ©ÐŒÐµÐ³Ñ (GLI)}  
+_textgtiperlmodules_ [l=kk] {Perl ÐŒÐŸÐŽÑÐ»ÑÐŽÐµÑÑ}  
+_textgtitutorials_ [l=kk] {ÐÒÑ Ð¶Ð°ÑÑÑÒÑÐ»Ð°ÑÑ}  
+_textgtigreenorg_ [l=kk] {ÐÑÐžÐœÑÑÐŸÑÐœ.ÐŸÑÐ³}  
+_textgtigs3interface_ [l=kk] {ÐÑÐžÐœÑÑÐŸÑÐœ 3 ÐžÐœÑÐµÑÑÐµÐ¹ÑÑ}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=kk] {ÐÑÐžÐœÑÑÐŸÑÐœ ÒÒ±ÑÑÑÑÐ»Ð°ÑÑÐœÑÒ£ Ð±Ð°ÑÑÑÐ»ÑÒÑ}  
+_textgtiinstallmanual_ [l=kk] {ÐÑÐžÐœÑÑÐŸÑÐœÐŽÑ ÒÒ±ÑÑÒÐ° Ð°ÑÐœÐ°Ð»ÒÐ°Ðœ Ð±Ð°ÑÑÑÐ»ÑÒ}  
+_textgtipapermanual_ [l=kk] {ÒÐ°ÒÐ°Ð·ÐŽÐ°Ðœ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÒÐ° ÐŽÐµÐ¹ÑÐœÐ³Ñ ÐÑÐžÐœÑÑÐŸÑÐœ Ð±Ð°ÑÑÑÐ»ÑÒÑ}  
+_textgtiusermanual_ [l=kk] {ÐÑÐžÐœÑÑÐŸÑÐœ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÑÑÑÑÐœÑÒ£ Ð±Ð°ÑÑÑÐ»ÑÒÑ}  
+
+_textgtienter_ [l=kk] {ÐÐÐÐÐÐ£}  
+
+_textgticorrectexistingtranslations_ [l=kk] {ÒÐŸÐ»ÐŽÐ°ÐœÑÑÑÐ° Ð±Ð°Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐœÑ ÐºÐŸÑÑÐµÐºÑÐžÑÐ»Ð°Ò£ÑÐ·}  
+_textgtidownloadtargetfile_ [l=kk] {Ð€Ð°Ð¹Ð»ÐŽÑ Ð¶Ò¯ÐºÑÐµÑ}  
+_textgtiviewtargetfileinaction_ [l=kk] {ÐÒ±Ð» ÑÐ°Ð¹Ð»ÐŽÑ ÑÑ- ÒÐžÐŒÐ°Ð»ÐŽÐ° ÒÐ°ÑÐ°Ñ}  
+_textgtitranslatefileoffline_ [l=kk] {ÐÐµÑÑÐ»Ð³ÐµÐœ  ÑÐ°Ð¹Ð»ÐŽÑ ÐŸÑÑÐ»Ð°Ð¹Ðœ ÑÐµÐ¶ÐžÐŒÑÐœÐŽÐµ Ð°ÑÐŽÐ°ÑÑ}  
+
+_textgtinumchunksmatchingquery_ [l=kk] {ÐÐµÐ¹Ð±ÑÑ ÐŒÓÑÑÐœ ÑÑÐ°Ð³ÐŒÐµÐœÑÑÐµÑÑ ÑÒ±ÑÐ°ÐœÑÑÒÐ° ÑÓÐ¹ÐºÐµÑ}  
+
+_textgtinumchunkstranslated_ [l=kk] {Ð°ÑÐŽÐ°ÑÑ Ð°ÑÒÑÐ°Ð»ÐŽÑ}  
+_textgtinumchunksrequiringupdating_ [l=kk] {_1_ ÐŸÑÑÐŽÐ°Ðœ Ð°ÑÐŽÐ°ÑÑÐŽÑ ÑÐ°Ð»Ð°Ð¿ ÐµÑÐµÐŽÑ}  
+_textgtinumchunksrequiringtranslation_ [l=kk] {Ð°ÑÐŽÐ°ÑÑÒÐ° ÒÐ°Ð»ÐŽÑ}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=kk] {Ð°ÑÐŽÐ°ÑÑÐ»ÒÐ°ÐœÐœÑÒ£ ÐŒÓ©Ð»ÑÐµÑÑ}  
+_textgtinumchunksrequiringupdating2_ [l=kk] {Ð¶Ð°Ò£Ð°Ð»Ð°ÑÐŽÑ ÑÐ°Ð»Ð°Ð¿ ÐµÑÐµÑÑÐœ Ð°ÑÐŽÐ°ÑÐŒÐ°Ð»Ð°Ñ ÑÐ°ÐœÑ }  
+_textgtinumchunksrequiringtranslation2_ [l=kk] {Ð°ÑÐŽÐ°ÑÑÒÐ° ÒÐ°Ð»ÒÐ°ÐœÐœÑÒ£ ÐŒÓ©Ð»ÑÐµÑÑ}  
+
+_textgtienterquery_ [l=kk] {Ð ÐµÐŽÐ°ÐºÑÐžÑÐ»Ð°ÐœÐ°ÑÑÐœ ÐŒÓÑÑÐœÐŽÑÐº ÑÑÐ°Ð³ÐŒÐµÐœÑÑÐµÐœ ÑÓ©Ð·ÐŽÑ ÐœÐµÐŒÐµÑÐµ ÑÑÐ°Ð·Ð°ÐœÑ ÐµÐœÐ³ÑÐ·ÑÒ£ÑÐ·}  
+_textgtifind_ [l=kk] {ÐÐÐÐÐ£}  
+
+_textgtitranslatingchunk_ [l=kk] {<i>_1_</i> ÐŒÓÑÑÐœ ÑÑÐ°Ð³ÐŒÐµÐœÑÑ Ð°ÑÐŽÐ°ÑÑÐ»Ð°ÐŽÑ}  
+_textgtiupdatingchunk_ [l=kk] {<i>_1_</i>  ÐŒÓÑÑÐœÐŽÑÐº ÑÑÐ°Ð³ÐŒÐµÐœÑÑÒ£ Ð¶Ð°Ò£Ð°ÑÑÑÐ»ÑÑ}  
+_textgtisubmit_ [l=kk] {ÐÐÐÐÐ Ð£}  
+
+_textgtilastupdated_ [l=kk] {Ð¡ÐŸÒ£ÒÑ Ð¶Ð°Ò£Ð°ÑÑÑ}  
+
+_textgtitranslationfilecomplete_ [l=kk] {ÐÑÑ ÑÐ°Ð¹Ð»ÐŽÑ Ð°ÑÐŽÐ°ÑÒÐ°ÐœÑÒ£ÑÐ·ÒÐ° ÑÐ°Ñ
+ÐŒÐµÑ-- ÒÐ°Ð·ÑÑ ÐŸÐ» Ð°ÑÒÑÐ°Ð»ÐŽÑ! <p>ÐÐŸÒÐ°ÑÑÐŽÐ°ÒÑ ÐºÓ©ÑÑÐµÑÑÐ»ÑÐŒÐŽÑ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÐ¿, ÑÑÐ· ÑÐ°Ð¹Ð»ÐŽÑÒ£ ÐºÓ©ÑÑÑÐŒÐµÑÑÐœ Ð¶Ò¯ÐºÑÐµÐ¹ Ð°Ð»Ð°ÑÑÐ·. ÐÐ» ÐÑÐžÐœÑÑÐŸÑÐœÐœÑÒ£ Ð±ÐŸÐ»Ð°ÑÐ°Ò Ð²ÐµÑÑÐžÑÐ»Ð°ÑÑÐœÐŽÐ°
+Ð±ÐµÐ¹ÐœÐµÐ»ÐµÐœÐµÐŽÑ
+}  
+
+_textgtiofflinetranslation_ [l=kk] {Ð¡ÑÐ· Microsoft Excel ÑÐ°Ð¹Ð»ÑÐœ ÒÐŸÐ»ÐŽÐ°ÐœÐ° ÐŸÑÑÑÑÐ¿ ÐÑÐžÐœÑÑÐŸÑÐœ ÐŸÑÑÐ»Ð°Ð¹Ðœ-ÐœÑÒ£  ÐŸÑÑ Ð±Ó©Ð»ÑÐŒÑÐœ Ð°ÑÐŽÐ°ÑÑÑÒ£ÑÐ·ÒÐ° Ð±ÐŸÐ»Ð°ÐŽÑ: 
+<ol>
+<li>ÐÐ°Ð·ÑÐ¿ Ð°Ð»Ñ <a href="_gwcgi_?a=gti&p=excel&e=_compressedoptions_">Ð±Ò±Ð» ÑÐ°Ð¹Ð»ÐŽÑ</a>.
+<li>Microsoft ExcelÐŽÐµ Ð¶Ð°Ð·ÑÐ¿ Ð°Ð»ÑÐœÒÐ°Ðœ ÑÐ°Ð¹Ð»ÐŽÑ Ð°ÑÑÐ¿ Ð¶ÓÐœÐµ Microsoft Excel workbook (.xls) ÑÐŸÑÐŒÐ°ÑÑÐœÐŽÐ° ÑÐ°ÒÑÐ°Ñ.
+<li>Ò°ÑÑÐœÑÐ»ÒÐ°Ðœ ÑÐŸÑÐ»Ð°ÑÒÐ° Ð°ÑÐŽÐ°ÑÐŒÐ°Ð»Ð°Ñ ÐµÐœÐ³ÑÐ·ÑÒ£ÑÐ·.
+<li>ÐÐ°ÑÐ»ÑÒ ÑÑÑÐžÐœÐ³ÑÐµÑÐŽÑÒ£ Ð°ÑÐŽÐ°ÑÐŒÐ°ÑÑÐœ Ð°ÑÒÑÐ°ÒÐ°Ðœ ÑÐŸÒ£, xls ÑÐ°Ð¹Ð»ÐŽÑ <a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a> ÐµÐŒÐ°Ð¹ÑÐ»ÑÐœÐ° Ð¶ÑÐ±ÐµÑÑÒ£ÑÐ·.
+</ol>}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=kk] {Greenstone ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°Ð»ÑÒ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑ}
+_textglihelp_ [l=kk] {ÐÑÐžÐœÑÑÐŸÑÐœ (GLI) ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°Ð»ÑÒ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑ Ð¡ÑÐ·Ð³Ðµ ÐÑÐžÐœÑÑÐŸÑÐœ-ÐœÑÒ£ ÑÑÐœÐºÑÐžÐŸÐœÐ°Ð»ÐŽÑÒ ÐŒÒ¯ÐŒÐºÑÐœÐŽÑÐºÑÐµÑÑÐœ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÒÐ° ÐºÐµÒ£ Ð¶ÐŸÐ» Ð°ÑÐ°ÐŽÑ - ÐºÓ©ÑÑÐµÑÑÒ£ÑÐ· ÐŽÐµ ÑÐµÑÑÑÒ£ÑÐ·. ÐÒ±Ð» Ð¡ÑÐ·Ð³Ðµ ÒÒ±Ð¶Ð°ÑÑÐ°ÑÐŽÑ ÑÑÑÐºÑÐµÐ¿ Ð¶ÐžÐœÐ°ÒÑÐ°ÑÒÐ°, ÐžÐŒÐ¿ÐŸÑÑÑÐ°ÑÒÐ° ÐœÐµÐŒÐµÑÐµ ÐŒÐµÑÐ°ÐŒÓÐ»ÑÐŒÐµÑÑÐµÑÐ³Ðµ Ð±Ð°ÒÑÑ Ð±ÐµÑÑ Ð°ÑÒÑÐ»Ñ ÑÑÑÐºÑÐµÐ¿ ÐŸÐ»Ð°ÑÐŽÑ ÐÑÐžÐœÑÑÐŸÑÐœ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÑÑÐœÐ° ÐŸÑÐœÐ°Ð»Ð°ÑÑÑÑÑÒÐ° ÐºÓ©ÐŒÐµÐºÑÐµÑÐµÐŽÑ.
+ÐÐ°Ð·Ð°Ñ Ð°ÑÐŽÐ°ÑÑÒ£ÑÐ·, GLI ÐÑÐžÐœÑÑÐŸÑÐœ-ÐŒÐµÐœ Ð±Ð°Ð¹Ð»Ð°ÐœÑÑÑÑ. ÐÐ» ÐÑÐžÐœÑÑÐŸÑÐœÐŽÑ ÐŸÑÐœÐ°ÑÒÐ°Ðœ ÐºÐµÐ·ÐŽÐµ, ÑÑÐºÑ ÐŽÐžÑÐµÐºÑÐŸÑÐžÑÐŽÐ° ÐŸÑÐœÐ°Ð»Ð°ÑÒÐ°Ðœ ÐŽÐµÐ¿ Ò±Ð¹ÒÐ°ÑÑÐ»ÒÐ°Ðœ. ÐÐ³ÐµÑ Ð¡ÑÐ· ÐÑÐžÐœÑÑÐŸÑÐœ-ÐŽÑ ÐŽÐžÑÑÑÐžÐ±ÑÑÑÐµÑÑÐœÑÒ£  Ð±ÑÑÐµÑÑÐœÐµÐœ ÐœÐµÐŒÐµÑÐµ CD-ROM-ÐœÐ°Ðœ Ð°Ð»ÑÐ¿ ÐŸÑÐœÐ°ÑÑÐ°Ò£ÑÐ·, ÐŸÐœÑÒ£ ÐŒÓÐœÑÑÑ Ð±Ð°Ñ.
+
+<h4>GLI-ÐŽÑ Windows-ÐŽÐ° Ð¶ÑÐ±ÐµÑÑ</h4>
+Windows-ÑÐ°Ðœ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°Ð»ÑÒ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑÑ Ð¡ÑÐ°ÑÑ ÐŒÐµÐœÑÑÐœÑÒ£ ÐÐ°ÒÐŽÐ°ÑÐ»Ð°ÐŒÐ°Ð»Ð°Ñ Ð±Ó©Ð»ÑÐŒÑÐœÐµÐœ ÐÑÐžÐœÑÑÐŸÑÐœÐœÑÒ£ ÑÐ°ÐœÐŽÑÒ ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°ÑÑÐœ ÑÐ°Ò£ÐŽÐ°Ð¿, ÐºÑÑÐ°Ð¿Ñ
+Ð°ÐœÐ°Ð»ÑÒ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑÑ ÐºÓ©ÑÑÐµÑÑ Ð°ÑÒÑÐ»Ñ Ð¶ÑÐ±ÐµÑÑÒ£ÑÐ·.     
+
+<h4>GLI-ÐŽÑ Unix-ÑÐµ Ð¶ÑÐ±ÐµÑÑ</h4>
+Unix ÑÑÑÐœÐµÐœ GLI-ÐŽÑ Ð¶ÑÐ±ÐµÑÑ Ò¯ÑÑÐœ ÐŸÑÐœÐ°ÑÒÐ°Ðœ ÐÑÐžÐœÑÑÐŸÑÐœÑÒ£ÑÐ·ÐŽÐ°Ðœ gli ÐŽÐžÑÐµÐºÑÐŸÑÐžÑÑÑÐœ Ó©Ð·Ð³ÐµÑÑÑÒ£ÑÐ·, ÐŸÐŽÐ°Ðœ ÐºÐµÐ¹ÑÐœ gli.sh ÑÐºÑÐžÐ¿ÑÑÐœÐµ Ð±Ð°ÑÑÒ£ÑÐ·.}  
Index: /gsdl/stable/macros/kirghiz.dm
===================================================================
--- /gsdl/stable/macros/kirghiz.dm	(revision 20131)
+++ /gsdl/stable/macros/kirghiz.dm	(revision 20131)
@@ -0,0 +1,722 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Kirghiz Language text and icon macros 
+# Many thanks to Fedor Bakalov (translated February 2005)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=ky] {ÐÐµÑÐžÐŸÐŽÐžÐºÐ°}
+_textsource_ [l=ky] {Ð±ÑÐ»Ð°Ðº:}
+_textdate_ [l=ky] {Ð¶Ð°ÑÑÑÐ»Ð°ÐœÐ³Ð°Ðœ ÐºÒ¯ÐœÒ¯:}
+_textnumpages_ [l=ky] {ÐÐµÑÑÐžÐœ ÐœÐŸÐŒÐµÑÐž:}
+
+_textsignin_ [l=ky] {Ð°Ð²ÑÐŸÑÐžÐ·Ð°ÑÐžÑ}
+
+_textdefaultcontent_ [l=ky] {ÐÑÐ» Ð±ÐµÑ ÑÐ°Ð±ÑÐ»Ð³Ð°Ðœ Ð¶ÐŸÐº. ÐÑÐ°ÑÐ·ÐµÑÐŽÐžÐœ 'ÐºÐ°Ð¹ÑÑÑ' Ð¶Ðµ Ð±ÐŸÐ»ÑÐŸ  (home)  ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ  Ð±Ð°ÑÑÐ°Ò£ÑÐ· ÐºÐ°Ð¹ÑÐ°ÐŽÐ°Ðœ Ð±Ð°ÑÐºÑ Ð±ÐµÑÑÐµ Ð±ÐŸÐ»ÐŸÑÑÐ·.}
+
+_textdefaulttitle_ [l=ky] {GSDL ÐÐ°ÑÐ°}
+
+_textbadcollection_ [l=ky] {ÐÑÐ» ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ("_cvariable_") Greenstone ÑÐžÑÑÐµÐŒÐ°ÑÑÐœÐŽÐ° ÐŸÑÐœÐŸÑÑÐ»Ð³Ð°Ðœ ÑÐŒÐµÑ.}
+
+_textselectpage_ [l=ky] {-- Ð¢Ð°ÐœÐŽÐŸÐŸ Ð±Ð°ÑÐ°Ð³Ñ --}
+
+_collectionextra_ [l=ky] {ÐÑÐ» ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ°  _about:numdocs_ ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð±Ð°Ñ. 
+ÐÐºÑÑÐºÑ Ó©Ð·Ð³Ó©ÑÑÒ¯Ò¯Ð»Ó©Ñ _about:builddate_ ÐºÒ¯Ðœ ÐŒÑÑÑÐœ Ð¶Ð°ÑÐ°Ð»Ð³Ð°Ðœ.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=ky] {<p>ÐÒ±Ð»  ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ° _numdocs_ If_(â_numdocs_â eq â1â, ÐŽÐŸÐºÑÐŒÐµÐœÑ, ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑ), Ð±Ð°ÑÐŽÑÐ³Ñ _numbytes_.
+ <p><a href=â_httppagex_(bsummary)â>ÐÑÐœÑ Ð±Ð°ÑÑÒ£ÑÐ·</a> ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐœÑ Ð°ÐºÑÑÐºÑ Ð¶ÑÐ¹ÑÐœÑÑÐºÑÐŸÐŸÑÑ ÑÒ¯Ð·Ò¯Ð»Ò¯ÑÒ¯Ðœ ÐºÑÑÑÑ Ò¯ÑÒ¯Ðœ.
+}
+
+_textdescrcollection_ [l=ky] {}
+_textdescrabout_ [l=ky] {ÐÑÐŸÐ³ÑÐ°ÐŒÐŒÐ° Ð¶Ó©ÐœÒ¯ÐœÐŽÓ©}
+_textdescrhome_ [l=ky] {Ò®Ð¹ Ð±ÐµÑÐž}
+_textdescrhelp_ [l=ky] {ÐÐ°ÑÐŽÐ°ÐŒ Ð±ÐµÑÐž}
+_textdescrpref_ [l=ky] {Ð¢Ò¯Ð·Ó©ÑÒ¯Ò¯ Ð±ÐµÑÐž}
+_textdescrgreenstone_ [l=ky] {Greenstone ÑÐ»ÐµÐºÑÑÐŸÐœÐŽÑÐº ÐºÐžÑÐµÐ¿ÐºÐ°ÐœÐ°ÑÑ}
+_textdescrusab_ [l=ky] {ÐÐ·ÐŽÓ©Ó©ÐŽÓ© ÐºÐ°ÐœÐŽÐ°Ð¹ ÐºÑÐ¹ÑÐœÑÑÐ»ÑÐºÑÐ°ÑÐŽÑ ÐºÓ©ÑÐŽÒ¯Ò£Ò¯Ð·? }
+
+_textdescrSearch_ [l=ky] {ÐÐœÑÐºÑÐŸÐŸÑÑ ÑÐµÑÐŒÐžÐœÐŽÐµÑÐŽÑ ÐžÐ·ÐŽÓ©Ó©}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=ky] {ÐÑÑÐœ Ð°Ð»ÑÐ°Ð²ÐžÑ ÑÐžÐ·ÐŒÐµÑÐž Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrCreator_ [l=ky] {ÐÐ²ÑÐŸÑÐ»ÐŸÑÐŽÑ Ð°Ð»ÑÐ°Ð²ÐžÑ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrSubject_ [l=ky] {ÐÐžÑÑÐžÐ¿Ð»ÐžÐœÐ°ÑÑ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrDescription_ [l=ky] {ÐÐ°ÑÐœÐŽÐ°ÐŒÐ°  Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrPublisher_ [l=ky] {ÐÐ°ÑÐŒÐ°ÐºÐ°ÐœÐ°Ð»Ð°Ñ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrContributor_ [l=ky] {Ð­ÐŒÐ³ÐµÐºÑÐµÑÑÐµÑ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrDate_ [l=ky] {ÐÐ°ÑÐ° Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrType_ [l=ky] {Ð¢ÐžÐ¿ÑÐµÑÐŽÐžÐœ ÑÐµÑÑÑÑÑ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrFormat_ [l=ky] {Ð€ÐŸÑÐŒÐ°Ñ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrIdentifier_ [l=ky] {ÐÐµÐ»Ð³Ðž ÑÐµÑÑÑÑÑÐ°ÑÑ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrSource_ [l=ky] {Ð€Ð°Ð¹Ð»ÐŽÑÐœ Ð°ÑÑ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrLanguage_ [l=ky] {Ð¢ÐžÐ»ÐŽÐµÑ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrRelation_ [l=ky] {ÐÐ°ÐŒÐžÐ»ÐµÐ»ÐµÑ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrCoverage_ [l=ky] {ÐÑÐ»ÐŽÐ°Ñ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrRights_ [l=ky] {Ð£ÐºÑÐºÑÐ°Ñ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+
+_textdescrOrganization_ [l=ky] {Ð£ÑÐŒ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrKeyword_ [l=ky] {ÐÐ°Ò£ÑÐ· ÑÓ©Ð·ÐŽÓ©Ñ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrHowto_ [l=ky] {ÐÐŸÐ»ÐŽÐŸÐœÑÑÑÑÐ»Ð°Ñ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrList_ [l=ky] {ÐÐŸÐºÑÐŒÐµÐœÑÑÐžÐœ ÑÐžÐ·ÐŒÐµÑÐžÐœ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrSeries_ [l=ky] {ÐÐ°ÑÑÑÐ»Ð°ÐœÑÑ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÑÑ}
+_textdescrTo_ [l=ky] {ÐÐŽÑÐµÑÐ°ÑÑÐ°Ñ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrFrom_ [l=ky] {ÐÐžÐ±ÐµÑÒ¯Ò¯ÑÒ¯Ð»Ó©Ñ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrTopic_ [l=ky] {Ð¢ÐµÐŒÐ°Ð»Ð°Ñ  Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrBrowse_ [l=ky] {ÐÓ©ÑÒ¯Ò¯}
+_textdescrCollage_ [l=ky] {Ð¡Ò¯ÑÓ©ÑÑÓ©ÑÐŽÒ¯Ðœ ÐºÐŸÐ»Ð»Ð°Ð¶Ñ Ð°ÑÐºÑÐ»ÑÑ  ÐºÓ©ÑÒ¯Ò¯}
+_textdescrPeople_ [l=ky] {ÐÐµÑÑÐŸÐœÐ°Ð»ÐžÐ¹Ð»ÐµÑÐŽÐž Ð°Ð»ÑÐ°Ð²ÐžÑ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrAcronym_ [l=ky] {ÐÑÑÐºÐ°ÑÑÑÑÐ»Ð°ÑÐŽÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrPhrase_ [l=ky] {Ð€ÑÐ°Ð·Ð°Ð»Ð°Ñ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrArtist_ [l=ky] {Ð¡Ò¯ÑÓ©ÑÑÒ¯Ð»Ó©ÑÐŽÒ¯ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrVolume_ [l=ky] {Ð¢ÐŸÐŒÐŽÐŸÑÑ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+_textdescrCountries_ [l=ky] {ÓšÐ»ÐºÓ©Ð»Ó©Ñ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯ }
+_textdescrCaptions_ [l=ky] {Ð€ÐŸÑÐŸ ÑÒ¯ÑÓ©ÑÑÓ©ÑÐŽÒ¯Ðœ Ð¶Ð°Ð·ÑÑÐ»Ð°ÑÑ Ð°ÑÐºÑÐ»ÑÑ ÐºÓ©ÑÒ¯Ò¯}
+
+
+_labelSearch_ [l=ky] {ÐÐ·ÐŽÓ©Ó©}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=ky] {ÐÐ°Ñ Ð°ÑÑ Ð-Ð¯ }
+_labelCreator_ [l=ky] {ÐÐ²ÑÐŸÑÐ»ÐŸÑÑ Ð-Ð¯ }
+_labelSubject_ [l=ky] {ÐÐžÑÑÐžÐ¿Ð»ÐžÐœÐ°ÑÑ }
+_labelDescription_ [l=ky] {ÐÐ°ÑÐœÐŽÐŸÐŸÐ»ÐŸÑ}
+_labelPublisher_ [l=ky] {ÐÐ°ÑÑÐ¿ ÑÑÐ³Ð°ÑÑÑÑÑÐ»Ð°Ñ}
+_labelContributor_ [l=ky] {Ð­ÐŒÐ³ÐµÐºÑÐµÑÑÐµÑ}
+_labelDate_ [l=ky] {ÐÐ°ÑÐ°Ð»Ð°Ñ}
+_labelType_ [l=ky] {Ð¢ÐžÐ¿ÑÐµÑÐž}
+_labelFormat_ [l=ky] {Ð€ÐŸÑÐŒÐ°ÑÑÐ°Ñ}
+_labelIdentifier_ [l=ky] {ÐÐµÐ»Ð³ÐžÐ»ÐµÑ}
+_labelSource_ [l=ky] {Ð€Ð°Ð¹Ð»ÐŽÑÐœ Ð°ÑÑ}
+_labelLanguage_ [l=ky] {Ð¢ÐžÐ»ÐŽÐµÑ}
+_labelRelation_ [l=ky] {ÐÐ°ÐŒÐžÐ»ÐµÐ»ÐµÑ}
+_labelCoverage_ [l=ky] {ÐÑÐ»ÐŽÐ°Ñ}
+_labelRights_ [l=ky] {Ð£ÐºÑÐºÑÐ°ÑÑ}
+
+_labelOrg_ [l=ky] {Ð£ÑÐŒ }
+_labelKeyword_ [l=ky] {ÐÐ°Ò£ÑÐ·ÐŽÑÑ ÑÓ©Ð·ÐŽÓ©Ñ}
+_labelHow_ [l=ky] {ÐÑÐ°ÐºÐµÑÑÐµÑ}
+_labelSeries_ [l=ky] {Ð¡ÐµÑÐžÑÐ»Ð°Ñ}
+_labelList_ [l=ky] {Ð¢ÐžÐ·ÐŒÐµ }
+_labelTo_ [l=ky] {ÐÐžÐŒÐ³Ðµ}
+_labelFrom_ [l=ky] {ÐÐžÐŒÐŽÐµÐœ}
+_labelTopic_ [l=ky] {Ð¢ÐµÐŒÐ°Ð»Ð°Ñ}
+_labelBrwse_ [l=ky] {ÐÓ©ÑÑÓ©ÑÒ¯Ò¯}
+_labelCollage_ [l=ky] {ÐÐŸÐ»Ð»Ð°Ð¶}
+_labelBrows_ [l=ky] {ÐÓ©ÑÑÓ©ÑÒ¯Ò¯}
+_labelPeople_ [l=ky] {ÐÐµÑÑÐŸÐœÐ°Ð»ÐžÐ¹Ð»ÐµÑ Ð-Ð¯}
+_labelAcronym_ [l=ky] {ÐÑÑÐºÐ°ÑÑÑÑÐ»Ð°Ñ}
+_labelPhrase_ [l=ky] {Ð€ÑÐ°Ð·Ð°Ð»Ð°Ñ}
+_labelArtist_ [l=ky] {Ð¡Ò¯ÑÓ©ÑÑÒ¯Ð»Ó©Ñ }
+_labelVolume_ [l=ky] {Ð¢ÐŸÐŒÐŽÐŸÑÑ}
+_labelCaptions_ [l=ky] {ÐÐ°Ð·ÑÑÐ»Ð°Ñ}
+_labelCountries_ [l=ky] {ÓšÐ»ÐºÓ©Ð»Ó©Ñ}
+
+_texticontext_ [l=ky] {ÐÐŸÐºÑÐŒÐµÐœÑÑÐž ÐºÓ©ÑÒ¯Ò¯}
+_texticonclosedbook_ [l=ky] {ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐž Ð°ÑÑÑ Ð¶Ð°ÐœÐ° ÐŒÐ°Ð·ÐŒÑÐœÑÐœ ÐºÓ©ÑÒ¯Ò¯}
+_texticonnext_ [l=ky] {ÐºÐžÐ¹ÐžÐœÐºÐž Ð±Ó©Ð»Ò¯ÐŒÐ³Ó© Ó©ÑÒ¯Ò¯}
+_texticonprev_ [l=ky] {Ð°Ð»ÐŽÑÒ£ÐºÑ Ð±Ó©Ð»Ò¯ÐºÐºÓ© Ó©ÑÒ¯Ò¯}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=ky] {MIDI ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐž ÐºÓ©ÑÒ¯Ò¯}
+_texticonmsword_ [l=ky] {Microsoft Word ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐž ÐºÓ©ÑÒ¯Ò¯}
+# -- Missing translation: _texticonmp3_
+_texticonpdf_ [l=ky] {PDF ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐž ÐºÓ©ÑÒ¯Ò¯}
+_texticonps_ [l=ky] {PostScrip ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐž ÐºÓ©ÑÒ¯Ò¯}
+_texticonppt_ [l=ky] {PowerPoint ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐž ÐºÓ©ÑÒ¯Ò¯ }
+_texticonrtf_ [l=ky] {RTF ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐž ÐºÓ©ÑÒ¯Ò¯}
+_texticonxls_ [l=ky] {Microsoft Excel ÐŽÐŸÐºÑÐŒÐµÐœÑÐžÐœ ÐºÓ©ÑÒ¯Ò¯}
+
+_page_ [l=ky] {Ð±ÐµÑ}
+_pages_ [l=ky] {Ð±ÐµÑÑÐµÑ}
+_of_ [l=ky] {ÑÐµÐœ}
+_vol_ [l=ky] {Ð¢ÐŸÐŒ}
+_num_ [l=ky] {ÐÐŸÐŒÐµÑÐž}
+
+_textmonth00_ [l=ky] {}
+_textmonth01_ [l=ky] {ÐÐžÑÐŽÐžÐœ Ð°Ð¹Ñ}
+_textmonth02_ [l=ky] {ÐÐ°Ð»Ð³Ð°Ðœ ÐºÑÑÐ°Ðœ}
+_textmonth03_ [l=ky] {Ð§ÑÐœ ÐºÑÑÐ°Ðœ}
+_textmonth04_ [l=ky] {ÐÑÐ³Ñ}
+_textmonth05_ [l=ky] {ÐÑÐ»Ð¶Ð°}
+_textmonth06_ [l=ky] {Ð¢ÐµÐºÐµ}
+_textmonth07_ [l=ky] {ÐÐ°Ñ ÐŸÐŸÐœÐ°}
+_textmonth08_ [l=ky] {ÐÑÐº ÐŸÐŸÐœÐ°}
+_textmonth09_ [l=ky] {Ð¢ÐŸÐ³ÑÐ·ÐŽÑÐœ Ð°Ð¹Ñ}
+_textmonth10_ [l=ky] {ÐÐµÑÐžÐœÐžÐœ Ð°Ð¹Ñ}
+_textmonth11_ [l=ky] {ÐÐµÑÑÐžÐœ Ð°Ð¹Ñ}
+_textmonth12_ [l=ky] {Ò®ÑÑÒ¯Ðœ Ð°Ð¹Ñ}
+
+_textdocument_ [l=ky] {ÐÐŸÐºÑÐŒÐµÐœÑ}
+_textsection_ [l=ky] {ÐÓ©Ð»Ò¯ÐŒ}
+_textparagraph_ [l=ky] {ÐÐ°ÑÐ°Ð³ÑÐ°Ñ}
+
+_magazines_ [l=ky] {ÐÑÑÐœÐ°Ð»ÐŽÐ°Ñ}
+
+_nzdlpagefooter_ [l=ky] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">ÐÐ°Ò£Ñ ÐÐµÐ»Ð°ÐœÐŽÐžÑ Ð­Ð»ÐµÐºÑÑÐŸÐœÐŽÑÐº ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ° ÐÑÐŸÐµÐºÑÐž</a>
+<br><a href="http://www.cs.waikato.ac.nz">ÐÐœÑÐŸÑÐŒÐ°ÑÐžÐºÐ° Ð±Ó©Ð»Ò¯ÐŒÒ¯</a>, 
+<a href="http://www.waikato.ac.nz">ÐÐ°Ð¹ÐºÐ°ÑÐŸ Ð£ÐœÐžÐ²ÐµÑÑÐžÑÐµÑÐž</a>, 
+ÐÐ°Ò£Ñ ÐÐµÐ»Ð°ÐœÐŽÐžÑ}
+
+_linktextHOME_ [l=ky] {Ò®Ð}
+_linktextHELP_ [l=ky] {ÐÐÐ ÐÐÐ}
+_linktextPREFERENCES_ [l=ky] {Ð¢Ò®ÐÓšÐ¢Ò®Ò®ÐÓšÐ }
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=ky] {ÐÑÐ» ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ Ð¶Ó©ÐœÒ¯ÐœÐŽÓ©}
+
+_textsubcols1_ [l=ky] {<p>ÐÑÐ» ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ° _1_ ÐžÑÐºÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ Ð±Ð°Ñ. 
+ <blockquote>}
+
+_textsubcols2_ [l=ky] {</blockquote>
+Ð¡ÐžÐ·  ÑÒ¯Ð·Ó©ÑÒ¯Ò¯Ð»Ó©Ñ Ð±ÐµÑÐžÐœÐŽÐµ Ð°Ð·ÑÑ ÐºÐŸÐ»ÐŽÐŸÐœÑÐ¿ Ð¶Ð°ÑÐºÐ°Ðœ ÐžÑÐºÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐœÑÐœ ÑÐžÐ·ÐŒÐµÑÐžÐœ ÐºÓ©ÑÒ¯Ð¿ Ð¶Ðµ Ð±ÐŸÐ»ÑÐŸ Ó©Ð·Ð³Ó©ÑÑÓ© Ð°Ð»Ð°ÑÑÐ·.
+}
+
+_titleabout_ [l=ky] {Ð¶Ó©ÐœÒ¯ÐœÐŽÓ©}
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+
+_texticonopenbookshelf_ [l=ky] {ÐºÐžÑÐµÐ¿ÐºÐ°ÐœÐ° Ð±Ó©Ð»Ò¯ÐŒÒ¯Ðœ Ð¶Ð°Ð±ÑÑ}
+_texticonclosedbookshelf_ [l=ky] {ÐºÐžÑÐµÐ¿ÐºÐ°ÐœÐ° Ð±Ó©Ð»Ò¯ÐŒÒ¯Ðœ Ð°ÑÑÑ Ð¶Ð°ÐœÐ° ÐŒÐ°Ð·ÐŒÑÐœÑÐœ ÐºÓ©ÑÒ¯Ò¯ }
+_texticonopenbook_ [l=ky] {ÐºÐžÑÐµÐ¿ÑÐž Ð¶Ð°Ð±ÑÑ}
+_texticonclosedfolder_ [l=ky] {ÐÐ°Ð¿ÐºÐ°ÐœÑ Ð°ÑÑÑ Ð¶Ð°ÐœÐ° ÐŒÐ°Ð·ÐŒÑÐœÑÐœ ÐºÓ©ÑÒ¯Ò¯ }
+_texticonclosedfolder2_ [l=ky] {ÐžÑÐºÐž Ð±Ó©Ð»Ò¯ÐŒÐŽÒ¯ Ð°ÑÑÑ}
+_texticonopenfolder_ [l=ky] {Ð¿Ð°Ð¿ÐºÐ°ÐœÑ Ð¶Ð°Ð±ÑÑ}
+_texticonopenfolder2_ [l=ky] {ÐžÑÐºÐž Ð±Ó©Ð»Ò¯ÐŒÐŽÒ¯ Ð¶Ð°Ð±ÑÑ}
+_texticonsmalltext_ [l=ky] {Ð¢ÐµÐºÑÑÑÐžÐœ Ð±Ó©Ð»Ò¯ÐŒÒ¯Ðœ ÐºÓ©ÑÒ¯Ò¯}
+_texticonsmalltext2_ [l=ky] {ÑÐµÐºÑÑÑÐž ÐºÓ©ÑÒ¯Ò¯}
+_texticonpointer_ [l=ky] {ÐºÐµÐ·ÐµÐºÑÐµÐ³Ðž Ð±Ó©Ð»Ò¯ÐŒ}
+_texticondetach_ [l=ky] {ÐÐ°Ò£Ñ ÑÐµÑÐµÐ·ÐµÐŽÐµÐœ Ð±ÑÐ» Ð±ÐµÑÑÐž Ð°ÑÑÑ}
+_texticonhighlight_ [l=ky] {ÐÐ·ÐŽÐµÐ»Ò¯Ò¯ÑÒ¯ ÑÐµÑÐŒÐžÐœÐŽÐµÑÐŽÐž Ð±Ó©Ð»Ò¯Ð¿ ÐºÓ©ÑÑÓ©ÑÒ¯Ò¯}
+_texticonnohighlight_ [l=ky] {ÐÐ·ÐŽÐµÐ»Ò¯Ò¯ÑÒ¯ ÑÐµÑÐŒÐžÐœÐŽÐµÑÐŽÐž ÐºÓ©ÑÑÓ©ÑÐ¿Ó©Ó©}
+_texticoncontracttoc_ [l=ky] {ÐÐ°Ð·ÐŒÑÐœÐŽÑÑ ÑÒ¯ÑÒ¯Ò¯}
+_texticonexpandtoc_ [l=ky] {ÐÐ°Ð°ÑÐŽÑÐº ÐŒÐ°Ð·ÐŒÑÐœÐŽÑ Ð°ÑÑÐ¿ ÐºÓ©ÑÑÓ©ÑÒ¯Ò¯ }
+_texticonexpandtext_ [l=ky] {ÐÐ°Ð°ÑÐŽÑÐº ÑÐµÐºÑÑÑÐž ÐºÓ©ÑÑÓ©ÑÒ¯Ò¯}
+_texticoncontracttext_ [l=ky] {ÓšÐ·Ò¯ÐœÑÓ© Ð°Ð»ÑÐœÐ³Ð°Ðœ Ð±Ó©Ð»Ò¯ÐŒÐŽÓ©Ñ Ò¯ÑÒ¯Ðœ ÑÐµÐºÑÑÑÐž ÐºÓ©ÑÑÓ©ÑÒ¯Ò¯ }
+_texticonwarning_ [l=ky] {<b>ÐÐ°ÑÐ°: </b>}
+_texticoncont_ [l=ky] {ÑÐ»Ð°ÐœÑÑÐ»ÑÑÐœÐ±Ñ?}
+
+_textltwarning_ [l=ky] {<div class="buttons">_imagecont_</div>
+_iconwarning_ ÐÑÐ» ÑÐµÐºÑÑÑÐžÐœ ÐºÓ©Ð»Ó©ÐŒÒ¯ÐœÓ© Ð±Ð°Ð¹Ð»Ð°ÐœÑÑÑÑÑ Ð±ÑÐ°ÑÐ·ÐµÑÐŽÐµÐœ ÐºÓ©ÑÒ¯Ò¯Ð³Ó© ÐŒÒ¯ÐŒÐºÒ¯Ðœ ÑÐŒÐµÑ.
+}
+
+_textgoto_ [l=ky] {Ð±ÐµÑÐºÐµ Ó©ÑÒ¯Ò¯}
+_textintro_ [l=ky] {<i>(ÐºÐžÑÐžÑÒ¯Ò¯)</i>}
+
+_textCONTINUE_ [l=ky] {Ð£ÐÐÐÐ¢Ð«ÐÐ¡Ð«ÐÐÐ«??}
+
+_textEXPANDTEXT_ [l=ky] {ÐÐÐÐ ÐÐ«Ð\nÐ¢ÐÐÐ¡Ð¢}
+
+_textCONTRACTCONTENTS_ [l=ky] {ÐÐÐÐ£Ð£}
+
+_textDETACH_ [l=ky] {ÐÐÒ¢Ð«\nÐ¢ÐÐ ÐÐÐ}
+
+_textEXPANDCONTENTS_ [l=ky] {ÐÐ§Ð£Ð£}
+
+_textCONTRACT_ [l=ky] {ÐÐÐÐ£Ð£}
+
+_textHIGHLIGHT_ [l=ky] {ÐÓšÐÒ®Ò®}
+
+_textNOHIGHLIGHT_ [l=ky] {ÐÓšÐÐÓšÓš}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=ky] {_If_(_thislast_, ÐœÐ°ÑÑÐ¹Ð¶Ð°Ð»Ð°ÑÑ _thisfirst_ - _thislast_ ÑÑÑÐŸÐŸ Ð±ÐŸÑÐœÑÐ° ÐžÐ·ÐŽÓ©Ó©: _cgiargq_,ÑÑÑÐŸÐŸ Ð±ÐŸÑÐœÑÐ° ÑÐ»Ð³ÐŸÐŸÐ»ÐŸÑ Ð¶ÐŸÐº _cgiargq_)}
+_textnoquerytitle_ [l=ky] {ÐÐµÑÑÐž ÐžÐ·ÐŽÓ©Ó©}
+
+_textsome_ [l=ky] {ÐºÐ°Ð¹ÑÑ Ð±ÐžÑ}
+_textall_ [l=ky] {Ð±Ð°Ð°ÑÐŽÑÐ³Ñ}
+_textboolean_ [l=ky] {Ð»ÐŸÐ³ÐžÐºÐ°Ð»ÑÐº}
+_textranked_ [l=ky] {ÐžÑÐµÑÑÐµÐ»Ð³ÐµÐœ}
+_textnatural_ [l=ky] {ÐºÐ°ÐŽÐžÐŒÐºÐž}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=ky] {ÑÐ°ÑÑÑ
+ÑÑ ÐžÐ·ÐŽÓ©Ó©}
+
+_textifeellucky_ [l=ky] {ÐÐŸÐ»ÑÐŒ Ð±ÐŸÐ»ÐŽÑ!}
+
+#alt text for query buttons
+_textusequery_ [l=ky] {ÑÑÑÐŸÐŸ Ð±ÐµÑÒ¯Ò¯}
+_textfreqmsg1_ [l=ky] {ÐÐµÐ·ÐŽÐµÑÒ¯Ò¯ ÑÐ°ÐœÑ:}
+_textpostprocess_ [l=ky] {_If_(_quotedquery_,<br><i>ÐžÐ·ÐŽÓ©Ó©ÐœÒ¯Ðœ ÐºÐžÐ¹ÐžÐœÐºÐž ÐžÑÑÐµÐ¿ ÑÑÐ³Ð°ÑÑÐ»ÑÑÑÑ _quotedquery_</i>
+)}
+_textinvalidquery_ [l=ky] {Ð¡ÑÑÐŸÐŸÐœÑÐœ ÑÐžÐœÑÐ°ÐºÑÐžÑÐž ÑÑÑÑÐ° ÑÐŒÐµÑ}
+
+_textmorethan_ [l=ky] {ÐÑÐœÐŽÐ°Ðœ Ð°ÑÑÑÐº}
+_textapprox_ [l=ky] {ÐÓ©ÐœÒ¯ÐœÐŽÓ©}
+_textnodocs_ [l=ky] {Ð¡ÑÑÐŸÐŸ Ð±ÐŸÑÐœÑÐ° ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑ ÑÐ°Ð±ÑÐ»Ð³Ð°Ðœ Ð¶ÐŸÐº}
+_text1doc_ [l=ky] {1 ÐŽÐŸÐºÑÐŒÐµÐœÑ ÑÑÑÐŸÐŸÐ³ÐŸ ÑÑÑÑÐ° ÐºÐµÐ»ÐŽÐž.}
+_textlotsdocs_ [l=ky] {ÑÑÑÐŸÐŸÐ³ÐŸ ÑÑÑÑÐ° ÐºÐµÐ»Ð³ÐµÐœ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑ }
+_textmatches_ [l=ky] {ÐÐ°ÑÑÐ¹Ð¶Ð°Ð»Ð°Ñ}
+_textbeginsearch_ [l=ky] {ÐÐ·ÐŽÐµÐ¿ Ð±Ð°ÑÑÐŸÐŸ}
+_textrunquery_ [l=ky] {Ð¡ÑÑÐ°ÐœÑÐŒÐŽÑ Ð°ÑÐºÐ°ÑÑÑ}
+_textclearform_ [l=ky] {Ð€ÐŸÑÐŒÐ°ÐœÑ ÑÐ°Ð·Ð°Ð»ÐŸÐŸ}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=ky] {Ð¡Ó©Ð·ÐŽÓ©Ñ Ð¶Ðµ ÑÑÐ°Ð·Ð°Ð»Ð°Ñ}
+_textinfield_ [l=ky] {... Ð°ÑÐœÑÐ°}
+_textfoldstem_ [l=ky] {(ÑÓ©Ð·, ÑÑÐ°Ð·Ð°)}
+
+_textadvquery_ [l=ky] {ÐÐµ Ð±ÐŸÐ»ÑÐŸ ÑÑÑÐŸÐŸ ÐŽÐŸÐºÑÐŒÐµÑÑÐµÑÐžÐœ ÐºÐžÑÐ³ÐžÐ·ÐžÒ£ÐžÐ·:}
+_textallfields_ [l=ky] {Ð±Ð°Ð°ÑÐŽÑÐº Ð°ÑÐœÑÑÐ°Ñ}
+_texttextonly_ [l=ky] {ÑÐµÑÐºÑ Ð³Ð°ÐœÐ°}
+_textand_ [l=ky] {Ð¶Ð°ÐœÐ°}
+_textor_ [l=ky] {Ð¶Ðµ}
+_textandnot_ [l=ky] {Ð¶Ð°ÐœÐ° ÑÐŒÐµÑ}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=ky] {ÐÐ·ÐŽÓ©Ó©  _indexselection_ _If_(_jselection_, of _jselection_) _If_(_gselection_, ÐŽÐµÒ£Ð³ÐµÐ¹ _gselection_ Ð±ÐŸÑÐœÑÐ°) _If_(_nselection_, ÑÐžÐ»ÐžÐœÐŽÐµ  _nselection_  ),ÑÓ©Ð·ÐŽÓ©ÑÐŽÓ©Ðœ _querytypeselection_ ÑÑÑÐ³Ð°Ðœ}
+
+_textadvancedsearch_ [l=ky] {ÐÐ·ÐŽÓ©Ó© _indexselection_ _If_(_jselection_, of _jselection_) _If_(_gselection_, ÐŽÐµÒ£Ð³ÐµÐ¹ _gselection_ Ð±ÐŸÑÐœÑÐ°)_If_(_nselection_, ÑÐžÐ»ÐžÐœÐŽÐµ_nselection_ )  ÑÑÑÐŸÐŸÐœÑ  _querytypeselection_ ÐºÐŸÐ»ÐŽÐŸÐœÑÐ¿}
+
+_textformsimplesearch_ [l=ky] {ÐÐŸÑÐœÑÐ° ÐžÐ·ÐŽÓ©Ó© _If_(_jselection_, _jselection_) _If_(_gformselection_, ÐŽÐµÒ£Ð³ÐµÐ¹ _gformselection_ Ð±ÐŸÑÐœÑÐ°)_If_(_nselection_, ÑÐžÐ»ÐžÐœÐŽÐµ _nselection_ ), Ð±Ð°Ñ Ð¶ÐµÑÐž _formquerytypesimpleselection_}
+
+_textformadvancedsearch_ [l=ky] {ÐÐ·ÐŽÓ©Ó© _If_(_jselection_,_jselection_) _If_(_gformselection_, ÐŽÐµÒ£Ð³ÐµÐ¹ _gformselection_ Ð±ÐŸÑÐœÑÐ°)_If_(_nselection_, ÑÐžÐ»ÐžÐœÐŽÐµ _nselection_ ) 
+Ð¶Ð°ÐœÐ° ÐžÑÐµÑÐž Ð±ÐŸÑÐœÑÐ° ÑÐžÐ·Ò¯Ò¯ _formquerytypeadvancedselection_}
+
+
+_textnojsformwarning_ [l=ky] {ÐÐ°ÑÐ°: Javascript ÑÐžÐ·ÐŽÐžÐœ Ð±ÑÐ°ÑÐ·ÐµÑÐŽÐµ Ó©ÑÒ¯ÑÒ¯Ð»Ð³Ó©Ðœ . <br>ÐÐ·ÐŽÓ©Ó© ÑÐŸÑÐŒÐ°ÑÑÐœ ÐºÐŸÐ»ÐŽÐŸÐœÑÑ Ò¯ÑÒ¯Ðœ Ð°ÐœÑ Ð°ÑÑÑ ÐºÐµÑÐµÐº. }
+_textdatesearch_ [l=ky] {ÐÑÐ» ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ° ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑ Ð±ÐµÐ»Ð³ÐžÐ»Ò¯Ò¯ Ð±ÐžÑ ÑÐ±Ð°ÐºÑÑ Ð°ÑÐ°Ð»ÑÐ³Ñ Ð±ÐŸÑÐœÑÐ° ÐžÐ·ÐŽÓ©Ó© ÐºÐ°ÑÐ°ÑÑ ÐœÐ°ÐºÑÑ ÐŽÐ°ÑÐ° Ð±ÐŸÑÐœÑÐ° ÐžÐ·ÐŽÐµÐ¿ ÑÐ°Ð±Ð° Ð°Ð»Ð°ÑÑÐ·.}
+_textstartdate_ [l=ky] {ÐÐ°ÑÐºÑ (Ð¶Ðµ ÐœÐ°ÐºÑÐ°) ÐŽÐ°ÑÐ°}
+_textenddate_ [l=ky] {ÐÐºÑÑÐºÑ ÐŽÐ°ÑÐ°:}
+_textbc_ [l=ky] {Ð±.Ñ.Ñ.}
+_textad_ [l=ky] {Ð±.Ñ.}
+_textexplaineras_ [l=ky] {Ð.Ñ. Ð¶Ð°ÐœÐ° Ð±.Ñ. ÑÐµÐ¹ÐžÐœ ÑÐµÑÐŒÐžÐœÐŽÐµÑÐž âÐ±ÐžÐ·ÐŽÐžÐœ ÑÑÐ°Ð±ÑÐ·â Ð¶Ð°ÐœÐ° âÐ±ÐžÐ·ÐŽÐžÐœ ÑÑÐ°Ð±ÑÐ·Ð³Ð° ÑÐµÐ¹ÐžÐœâ ÐŽÐµÐ³ÐµÐœÐŽÐž Ð±ÐžÐ»ÐŽÐžÑÐµÑ}
+
+_textstemon_ [l=ky] {Ð¶Ó©ÐœÐŽÓ©ÐŒÓ©Ð»Ó©ÑÐŽÒ¯Ðœ Ð¶Ð°Ð»Ð³ÐŸÐŸÐ»ÐŸÑÑÑÑÐ·}
+
+_textsearchhistory_ [l=ky] {Ð¡ÑÑÐ°Ð»Ð³Ð°Ðœ ÑÐ°ÑÑÑ
+}
+
+#text macros for search history
+_textnohistory_ [l=ky] {ÐÐ·ÑÑ ÐžÐ·ÐŽÓ©Ó© ÑÐ°ÑÑÑ
+Ñ Ð¶ÐŸÐº}
+_texthresult_ [l=ky] {ÐºÐµÐ·ÐŽÐµÑÒ¯Ò¯}
+_texthresults_ [l=ky] {ÐºÐµÐ·ÐŽÐµÑÒ¯Ò¯Ð»Ó©Ñ}
+_texthallwords_ [l=ky] {Ð±Ð°Ð°ÑÐŽÑÐº ÑÓ©Ð·ÐŽÓ©Ñ}
+_texthsomewords_ [l=ky] {ÐºÑÑ Ð±ÐžÑ ÑÓ©Ð·ÐŽÓ©Ñ}
+_texthboolean_ [l=ky] {Ð»ÐŸÐ³ÐžÐºÐ°Ð»ÑÐº}
+_texthranked_ [l=ky] {ÐžÑÐµÑÑÐµÐ»Ð³ÐµÐœ}
+_texthcaseon_ [l=ky] {ÑÐµÐ³ÐžÑÑÑÐŽÐž ÑÑÐµÐ¿ÐºÐµ Ð°Ð»ÑÐ¿}
+_texthcaseoff_ [l=ky] {ÑÐµÐ³ÐžÑÑÑÐŽÐž ÑÑÐµÐ¿ÑÐµÐ±ÐµÐ¹}
+_texthstemon_ [l=ky] {ÐÓ©ÐœÐŽÓ©ÐŒÓ©Ð»Ó©ÑÐŽÒ¯Ðœ Ð¶Ð°Ð»Ð³ÐŸÐŸÐ»ÐŸÑÑ ÐŒÐµÐœÐµÐœ}
+_texthstemoff_ [l=ky] {Ð¶Ó©ÐœÐŽÓ©ÐŒÓ©Ð»Ó©ÑÐŽÒ¯Ðœ Ð¶Ð°Ð»Ð³ÐŸÐŸÐ»ÐŸÑÑÑÑÐ·}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=ky] {Ð¢Ò¯Ð·Ó©ÑÒ¯Ò¯ÐœÒ¯ ÑÓ©ÐŒÓ©ÐœÐºÒ¯ÐŽÓ©Ð¹ ÐºÐ°Ð»ÑÐ¿ÑÐ°ÑÑÑÑÑÐ»Ð³Ð°Ðœ. ÐÑÐ°ÑÐ·ÐµÑÐŽÐžÐœ "ÐºÐ°Ð¹ÑÑÑ" ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ ÐºÐŸÐ»ÐŽÐŸÐœÐ±ÐŸÐ³ÑÐ»Ð°, Ð°ÐœÑÐœ ÐŸÑÐŽÑÐœÐ° Ò¯ÑÑÒ¯Ò£ÐºÒ¯ ÐºÐœÐŸÐ¿ÐºÐ°Ð»Ð°ÑÐŽÑÐœ Ð±ÐžÑÐžÐœ Ð±Ð°ÑÐºÑÐ»Ð°.}
+_textsetprefs_ [l=ky] {ÑÒ¯Ð·Ó©ÑÒ¯Ð¿ ÐºÐŸÑÑ }
+_textsearchprefs_ [l=ky] {ÐÐ·ÐŽÓ©Ó©ÐœÒ¯Ò¯ ÑÒ¯Ð·Ó©ÑÒ¯Ò¯  }
+_textcollectionprefs_ [l=ky] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐœÑ ÑÒ¯Ð·Ó©ÑÒ¯Ò¯Ð»Ó©Ñ}
+_textpresentationprefs_ [l=ky] {ÐÐœÑÐµÑÑÐµÐ¹ÑÑÐž ÑÒ¯Ð·Ó©ÑÒ¯Ò¯Ð»Ó©ÑÒ¯}
+_textpreferences_ [l=ky] {Ð¢Ò¯Ð·Ó©ÑÒ¯Ò¯Ð»Ó©Ñ}
+_textcasediffs_ [l=ky] {Ð ÐµÐ³ÐžÑÑÑÐ»ÐµÑ:}
+_textignorecase_ [l=ky] {ÑÐµÐ³ÐžÑÑÑÐŽÐž ÑÑÐµÐ¿ÑÐµÐ±ÐµÐ¹}
+_textmatchcase_ [l=ky] {Ð¶ÐŸÐ³ÐŸÑÐºÑ Ð¶Ð°ÐœÐ° ÑÓ©ÐŒÓ©ÐœÐºÒ¯ ÑÐµÐ³ÐžÑÑÑÐ»ÐµÑÐŽÐž ÐºÐŸÐ»ÐŽÐŸÐœÑÑ}
+_textwordends_ [l=ky] {Ð¡Ó©Ð·ÐŽÓ©ÑÐŽÒ¯Ðœ Ð¶Ð°Ð»Ð³ÐŸÐŸÐ»ÐŸÑÑ:}
+_textstem_ [l=ky] {ÑÓ©Ð·ÐŽÓ©ÑÐŽÒ¯Ðœ Ð¶Ð°Ð»Ð³ÐŸÐŸÐ»ÐŸÑÑÑÑÐ·}
+_textnostem_ [l=ky] {ÑÓ©Ð·ÐŽÓ©Ñ ÑÐŸÐ»ÑÐ³Ñ ÐŒÐµÐœÐµÐœ ÑÑÑÐ°Ð° ÐºÐµÐ»Ò¯Ò¯}
+_textprefop_ [l=ky] {Return up to _maxdocoption_ hits with _hitsperpageoption_ hits per page.}
+_textextlink_ [l=ky] {Web-ÑÐžÐœ ÑÑÑÑÐºÑ Ð±ÐµÑÑÐµÑÐžÐœÐµ ÑÑÐ³ÑÑ}
+_textintlink_ [l=ky] {ÐÑÐ» ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð°Ð»ÑÐœÐ³Ð°Ðœ Ð¶ÐµÑ:}
+_textlanguage_ [l=ky] {ÐÐœÑÐµÑÑÐµÐ¹Ñ ÑÐžÐ»Ðž}
+_textencoding_ [l=ky] {ÐÐŸÐŽÐžÑÐŸÐ²ÐºÐ°:}
+_textformat_ [l=ky] {ÐÐœÑÐµÑÑÐµÐ¹ÑÑÐžÐœ ÑÐŸÑÐŒÐ°ÑÑ:}
+_textall_ [l=ky] {Ð±Ð°Ð°ÑÐŽÑÐ³Ñ}
+_textquerymode_ [l=ky] {Ð¡ÑÑÐŸÐŸÐœÑÐœ ÑÐžÐ±Ðž: }
+_textsimplemode_ [l=ky] {ÑÑÑÐŸÐŸÐœÑÐœ Ð¶Ó©ÐœÓ©ÐºÓ©Ð¹ ÑÒ¯ÑÒ¯}
+_textadvancedmode_ [l=ky] {ÑÑÑÐŸÐŸÐœÑÐœ ÑÐŸÒ£ÐŸÐ¹ÑÑÐ»Ð³Ð°Ðœ ÑÒ¯ÑÒ¯ (! (Ð­ÐÐÐ¡) , & (ÐÐÐÐ), | (ÐÐ) Ð¶Ð°ÐœÐ° ÐºÐ°ÑÐ°Ð°Ð»Ð°Ñ) ÑÑÑÐ»Ó©ÑÒ¯ ÐŒÐµÐœÐµÐœ Ð»ÐŸÐ³ÐžÐºÐ°Ð»ÑÐº ÐžÐ·ÐŽÓ©Ó©Ð³Ó© ÑÑÑÐºÑÐ°Ñ Ð±ÐµÑÐžÐ»Ð³ÐµÐœ}
+_textlinkinterm_ [l=ky] {Ð°ÑÐ°ÐŽÐ°Ð³Ñ Ð±ÐµÑ Ð°ÑÐºÑÐ»ÑÑ}
+_textlinkdirect_ [l=ky] {ÑÐžÑÐºÐµÐ»ÐžÐ¿ Ó©ÑÒ¯Ò¯}
+_textdigitlib_ [l=ky] {ÑÐ»ÐµÐºÑÑÐŸÐœÐŽÑÐº ÐºÐžÑÐµÐ¿ÐºÐ°ÐœÐ°}
+_textweb_ [l=ky] {Web}
+_textgraphical_ [l=ky] {ÐÑÐ°ÑÐžÐºÐ°Ð»ÑÐº}
+_texttextual_ [l=ky] {Ð¢ÐµÐºÑÑÑÐžÐº}
+_textcollectionoption_ [l=ky] {<p>
+ÐÑÐºÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐ»Ð°Ñ:
+<br>}
+
+_textrelateddocdisplay_ [l=ky] {ÐŸÐºÑÐŸÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐž ÐºÓ©ÑÑÓ©ÑÒ¯Ò¯}
+_textsearchhistory_ [l=ky] {ÐÐ·ÐŽÓ©Ó© ÑÐ°ÑÑÑ
+Ñ: }
+_textnohistory_ [l=ky] {Ð¢Ð°ÑÑÑ
+ÑÑ ÐžÐ·ÐŽÐµÐ±Ó©Ó©}
+_texthistorydisplay_ [l=ky] {ÑÑÑÐŸÐŸ ÑÐ°ÑÑÑ
+ÑÐœ _historynumrecords_ ÐºÓ©ÑÑÓ©ÑÒ¯Ò¯}
+_textnohistorydisplay_ [l=ky] {ÑÑÑÐŸÐŸ ÑÐ°ÑÑÑ
+ÑÐœ ÐºÓ©ÑÑÓ©ÑÐ¿Ó©Ó©}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=ky] {Ð€ÐŸÑÐŒÐ°ÐœÑ ÐžÐ·ÐŽÓ©Ó©:}
+_textplainsearch_ [l=ky] {ÐÓ©ÐœÓ©ÐºÓ©Ð¹ ÐžÐ·ÐŽÓ©Ó©:}
+_textqueryboxsize_ [l=ky] {ÐÐ·ÐŽÓ©Ó©Ð³Ó© Ð°ÑÐœÐ°Ð»Ð³Ð°Ðœ ÑÐµÑÐµÐ·Ðµ Ó©Ð»ÑÓ©ÐŒÒ¯:}
+_textregbox_ [l=ky] {ÐžÐ·ÐŽÓ©Ó©Ð³Ó© Ð°ÑÐœÐ°Ð»Ð³Ð°Ðœ ÐºÓ©ÐœÒ¯ÐºÐºÓ©Ðœ ÑÐµÑÐµÐ·Ðµ}
+_textbigbox_ [l=ky] {ÐžÐ·ÐŽÓ©Ó©Ð³Ó© Ð°ÑÐœÐ°Ð»Ð³Ð°Ðœ ÑÐŸÒ£ ÑÐµÑÐµÐ·Ðµ}
+_textformtype_ [l=ky] {Ð€ÐŸÑÐŒÐ°ÐœÑÐœ ÑÐžÐ±Ðž:}
+_textsimple_ [l=ky] {Ð¶Ó©ÐœÓ©ÐºÓ©Ð¹}
+_textadvanced_ [l=ky] {ÑÐŸÒ£ÐŸÐ¹ÑÑÐ»Ð³Ð°Ðœ}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=ky] {ÐŒÐµÐœÐµÐœ}
+_textfields_ [l=ky] {Ð°ÑÐœÑ}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=ky] {ÐÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐž  ÑÐŸÑÑÑÐŸÐŸ}
+_textalsoshowing_ [l=ky] {ÐŽÐ°Ð³Ñ ÐºÐ°ÑÐŸÐŸ}
+_textwith_ [l=ky] {ÑÒ£ ÑÐŸÒ£Ñ ÐŒÐµÐœÐµÐœ}
+_textdocsperpage_ [l=ky] {Ð±ÐµÑÑÐµÐ³Ðž ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐžÐœ ÑÐ°ÐœÑ}
+
+_textfilterby_ [l=ky] {ÐÐŸÐºÑÐŒÐµÐœÑÑÐžÐœ ÐŒÐ°Ð·ÐŒÑÐœÑÐœ Ð°Ð»ÑÑ}
+_textall_ [l=ky] {Ð±Ð°Ð°ÑÐŽÑÐ³Ñ}
+_textany_ [l=ky] {Ð°ÐœÐŽÐ°Ðœ Ð±Ð°ÑÐºÐ°}
+_textwords_ [l=ky] {ÑÓ©Ð·ÐŽÓ©Ñ Ð°ÑÐºÑÐ»ÑÑ }
+_textleaveblank_ [l=ky] {Ð±Ð°Ð°ÑÐŽÑÐº ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐž Ð°Ð»ÑÑ Ò¯ÑÒ¯Ðœ Ð±ÑÐ» ÑÐµÑÑÐž ÐºÐ°Ð»ÑÑÑÑÒ£ÑÐ·}
+
+_browsebuttontext_ [l=ky] {"ÐÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐž ÑÐŸÑÑÑÐŸÐŸ"}
+
+_nodata_ [l=ky] {<i>ÐŽÐ°ÑÐ°ÑÑ Ð¶ÐŸÐº</i>}
+_docs_ [l=ky] {ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑ}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=ky] {ÐÐ°ÑÐŽÐ°ÐŒ}
+_textSearchshort_ [l=ky] {Ð°ÑÐ°Ð¹ÑÐœ Ð°ÑÐœÐ°Ð»Ð³Ð°Ðœ ÑÐµÑÐŒÐžÐœÐŽÐµÑ Ð±ÐŸÑÐœÑÐ° ÐžÐ·ÐŽÓ©Ó©}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=ky] {ÑÐžÐ·ÐŒÐµÐ»ÐµÑ (Ð-Ð¯)  Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textCreatorshort_ [l=ky] {Ð°Ð²ÑÐŸÑÐ»ÐŸÑ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textSubjectshort_ [l=ky] {ÐÐžÑÑÐžÐ¿Ð»ÐžÐœÐ°Ð»Ð°Ñ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textDescriptionshort_ [l=ky] {Ð±Ð°ÑÐœÐŽÐ°ÐŒÐŸÐŸ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textPublishershort_ [l=ky] {Ð±Ð°ÑÑÐ¿ ÑÑÐ³Ð°ÑÑÑÑÑÐ»Ð°Ñ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textContributorshort_ [l=ky] {ÑÐŒÐ³ÐµÐºÑÐµÑÑÐµÑ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textDateshort_ [l=ky] {ÐŽÐ°ÑÐ°Ð»Ð°Ñ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textTypeshort_ [l=ky] {ÑÐžÐ¿ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textFormatshort_ [l=ky] {ÑÐŸÑÐŒÐ°Ñ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textIdentifiershort_ [l=ky] {Ð±ÐµÐ»Ð³ÐžÐ»ÐµÑ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textSourceshort_ [l=ky] {ÑÐ°Ð¹Ð»ÐŽÑÐœ Ð°ÑÑ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textLanguageshort_ [l=ky] {ÑÐžÐ»ÐŽÐµÑ  Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textRelationshort_ [l=ky] {ÐŒÐ°ÐŒÐžÐ»ÐµÐ»ÐµÑ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textCoverageshort_ [l=ky] {ÐŽÐ°ÑÐ°Ð»Ð°Ñ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textRightsshort_ [l=ky] {ÑÐºÑÐºÑÐ°Ñ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+
+_textSeriesshort_ [l=ky] {cÐµÑÐžÑÐ»Ð°Ñ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textToshort_ [l=ky] {ÐºÐžÐŒÐ³Ðµ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textFromshort_ [l=ky] {"ÐºÐžÐŒÐŽÐµÐœ"  Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textBrowseshort_ [l=ky] {Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐŽÑ ÐºÓ©ÑÒ¯Ò¯}
+_textOrganizationshort_ [l=ky] {ÑÑÐŒÐŽÐ°Ñ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textHowtoshort_ [l=ky] {Ð°ÑÐ°ÐºÐµÑÑÐžÐ»ÐµÑ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textTopicshort_ [l=ky] {ÑÐµÐŒÐ°Ð»Ð°Ñ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textPeopleshort_ [l=ky] {Ð¿ÐµÑÑÐŸÐœÐ°Ð»ÐžÐ¹Ð»ÐµÑ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textAcronymshort_ [l=ky] {ÐºÑÑÐºÐ°ÑÑÑÑÐ»Ð°Ñ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ}
+_textPhraseshort_ [l=ky] {ÑÑÐ°Ð·Ð°Ð»Ð°Ñ  Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textArtistshort_ [l=ky] {ÑÒ¯ÑÓ©ÑÑÒ¯Ð»Ó©Ñ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ}
+_textKeywordshort_ [l=ky] {ÐŒÐ°Ò£ÑÐ· ÑÓ©Ð·ÐŽÓ©Ñ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textVolumeshort_ [l=ky] {ÑÐŸÐŒ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textCountriesshort_ [l=ky] {Ó©Ð»ÐºÓ©Ð»Ó©Ñ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÒ¯Ò¯}
+_textdefaultshorttext_ [l=ky] {Ð±ÐµÐ»Ð³ÐžÑÐžÐ· ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÑ}
+
+_textSearchlong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÐžÐ·ÐŽÓ©Ó©ÐœÒ¯ Ð°ÑÐ°Ð¹ÑÐœ Ð°ÑÐœÐ°Ð»Ð³Ð°Ðœ ÑÐµÑÐŒÐžÐœÐŽÐµÑ Ð±ÐŸÑÐœÑÐ°</i> ÐžÐ·ÐŽÓ©Ó© Ð±ÐµÑÐžÐœÐµÐœ Ð¶Ò¯ÑÐ³Ò¯Ð·Ó© Ð°Ð»Ð°ÑÑÐ·. ÐÑÐ» Ð±ÐµÑ ÑÐžÐ· ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐŒÐµÐœÐµÐœ ÐžÐ·ÐŽÓ©Ó©ÐœÒ¯ Ð±Ð°ÑÑÐ°Ð³Ð°ÐœÐŽÐ° ÑÒ¯Ð¹Ò¯Ð»Ò¯Ò¯ Ð±ÐŸÐ»ÐŸÑ Ð¶Ð°ÐœÐ° Ð°Ð³Ð° Ð°Ñ ÐºÐ°Ð¹ÑÑ Ð±ÐµÑÑÐµÑÐŽÐµÐœ <i>ÐžÐ·ÐŽÓ©Ó© ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÐ¿ ÐºÐ°Ð¹ÑÑÐ¿ ÐºÐµÐ»Ò¯Ò¯Ð³Ó© Ð±ÐŸÐ»ÐŸÑ</i>.}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÑÐžÐ·ÐŒÐµÐ»ÐµÑ (Ð-Ð¯)</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÐ¿ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐžÐœ Ð±Ð°Ñ-Ð°ÑÑÐ°ÑÑ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœÐŽÑ <i>Ð°Ð»Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÑÐžÐ· Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐŽÑÐœ Ð°ÑÑÐ°ÑÑÐœ Ð°Ð»ÑÐ°Ð²ÐžÑ Ð±ÐŸÑÐœÑÐ° ÐºÐžÑÐµÐ¿ÑÐµÑ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·. }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=ky] {<p>Ð¡ÐžÐ· Ð°Ð²ÑÐŸÑÐ»ÐŸÑ Ð-Ð¯ <i>ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ</i> Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>Ð°Ð²ÑÐŸÑÐ»ÐŸÑ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœÐŽÑ Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÑÐžÐ· Ð°Ð²ÑÐŸÑÐ»ÐŸÑ ÑÐ°ÐŒÐžÐ»ÐžÑÐ»Ð°ÑÑ Ð±ÐŸÑÐœÑÐ° ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐžÐœ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·. }
+
+_textSubjectlong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÐŽÐžÑÑÐžÐ¿Ð»ÐžÐœÐ°</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÓ© Ð°Ð»Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ° ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐžÐœ ÐŽÐžÑÑÐžÐ¿Ð»ÐžÐœÐ°Ð»Ð°ÑÑ Ð¶Ó©ÐœÒ¯ÐœÐŽÓ© ÐŒÐ°Ð°Ð»ÑÐŒÐ°Ñ Ð°Ð»Ð°Ð»Ð°ÑÑÐ·.}
+
+_textDescriptionlong_ [l=ky] {<p>Ð¡ÐžÐ· <i>Ð±Ð°ÑÐœÐŽÐ°ÐŒÐŸÐŸ ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ</i> Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐŽÑÐœ Ð±Ð°ÑÐœÐŽÐ°ÐŒÐ°ÑÑ</i> Ð¶Ó©ÐœÒ¯ÐœÐŽÓ© ÐŒÐ°Ð°Ð»ÑÐŒÐ°Ñ Ð°Ð»Ð°Ð»Ð°ÑÑÐ·.   }
+
+_textPublisherlong_ [l=ky] {<p>Ð¡ÐžÐ· <i>Ð±Ð°ÑÑÐ¿ ÑÑÐ³Ð°ÑÑÑÑÑÐ»Ð°Ñ</i>ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>Ð±Ð°ÑÑÐ¿ ÑÑÐ³Ð°ÑÑÑÑÑÐ»Ð°Ñ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ°Ð³Ñ Ð±Ð°ÑÑÐ¿ ÑÑÐ³Ð°ÑÑÑÑÑÐ»Ð°Ñ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·.  }
+
+_textContributorlong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÑÐŒÐ³ÐµÐºÑÐµÑÑÐµÑÐž</i>ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÐ¿.
+ <i>Ð­ÐŒÐ³ÐµÐºÑÐµÑÑÐµÑ</i> Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð°Ð»ÑÐŒÐ°Ñ Ð°Ð»Ð°Ð»Ð°ÑÑÐ·ÐŽÐ°Ñ.  }
+
+_textDatelong_ [l=ky] {<p>Ð¡ÐžÐ· ÐŽÐ°ÑÐ° <i>ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ </i>Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐŽÑÐœ Ð±Ð°ÑÑÐ»ÑÐ¿ ÑÑÐºÐºÐ°Ðœ <i>ÐŽÐ°ÑÐ°Ð»Ð°ÑÑ</i> Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð°Ð»ÑÐŒÐ°Ñ Ð°Ð»Ð°Ð»Ð°ÑÑÐ·ÐŽÐ°Ñ. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ° ÑÐžÐ· Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐŽÑ Ñ
+ÑÐŸÐœÐŸÐ»ÐŸÐ³ÐžÑÐ»ÑÐº ÑÐ°ÑÑÐžÐ¿ÐºÐµ Ð°Ð»ÑÐ¿ ÐºÐµÐ»ÐµÐ»Ð°ÑÑÐ·.  }
+
+_textTypelong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÑÐžÐ¿</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ<i>ÑÐžÐ¿ÑÐµÑ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœÐŽÑ Ð°Ð»Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÑÐžÐ· ÑÐžÐ¿ÑÐµÑ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·. }
+
+_textFormatlong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÑÐŸÑÐŒÐ°Ñ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐŽÑÐœ ÑÐŸÑÐŒÐ°ÑÑ</i> Ð¶Ó©ÐœÒ¯ÐœÐŽÓ© ÐŒÐ°Ð°Ð»ÑÐŒÐ°Ñ Ð°Ð»Ð°Ð»Ð°ÑÑÐ·.   }
+
+_textIdentifierlong_ [l=ky] {<p>Ð¡ÐžÐ· <i>Ð±ÐµÐ»Ð³ÐžÐ»ÐµÑ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>Ð±ÐµÐ»Ð³ÐžÐ»ÐµÑ (ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑÐ»ÐŸÑ) Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ°Ð³Ñ Ð±ÐµÐ»Ð³ÐžÐ»ÐµÑ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·.  }
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÑÐ°Ð¹Ð»ÐŽÑÐœ Ð°ÑÑ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐ³Ð° Ó©ÑÓ© Ð°Ð»Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÑÐ°Ð¹Ð»ÐŽÑÐœ Ð°ÑÑÐ°ÑÑÐœ ÐžÑÐµÑÑÐµÐ¹ Ð°Ð»Ð°ÑÑÐ·. }
+
+_textLanguagelong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÑÐžÐ»ÐŽÐµÑ</i>ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>ÑÐžÐ»ÐŽÐµÑÐž Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ°Ð³Ñ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐŽÑÐœ ÑÐžÐ»ÐŽÐµÑÐž Ð±ÐŸÑÐœÑÐ° ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð· Ð¶Ð°ÐœÐ° ÑÐŸÑÑÑÐŸÐ¹ Ð°Ð»Ð°ÑÑÐ·.  }
+
+_textRelationlong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÐŒÐ°ÐŒÐžÐ»ÐµÐ»ÐµÑ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>ÐŒÐ°ÐŒÐžÐ»ÐµÐ»ÐµÑ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ°Ð³Ñ  ÐŒÐ°ÐŒÐžÐ»Ðµ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·.  }
+
+_textCoveragelong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÐŽÐ°ÑÐ°Ð»Ð°Ñ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑ Ð°ÑÐºÑÐ»ÑÑ </i>ÐÐ°ÑÐ°Ð»Ð°Ñ</i> Ð¶Ó©ÐœÒ¯ÐœÐŽÓ© ÐŒÐ°Ð°Ð»ÑÐŒÐ°Ñ ÐºÓ©ÑÓ© Ð°Ð»Ð°ÑÑÐ·.  }
+
+_textRightslong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÑÐºÑÐºÑÐ°Ñ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>ÑÐºÑÐºÑÐ°Ñ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°ÑÑÐ·</i>.   }
+
+
+
+_textOrganizationlong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÑÑÐŒÐŽÐ°Ñ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>ÑÑÐŒÐŽÐ°Ñ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ°Ð³Ñ ÑÑÐŒÐŽÐ°Ñ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·.  }
+
+_textHowtolong_ [l=ky] {<p> Ð¡ÐžÐ· <i>Ð°ÑÐ°ÐºÐµÑÑÐµÑ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>Ð°ÑÐ°ÐºÐµÑÑÐžÐ»ÐµÑ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ°Ð³Ñ Ð°ÑÐ°ÐºÐµÑÑÐžÐ»ÐµÑ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·.  }
+
+_textTopiclong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÑÐµÐŒÐ°Ð»Ð°Ñ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ<i>ÑÐµÐŒÐ°Ð»Ð°Ñ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœÐŽÑ Ð°Ð»Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÑÐžÐ· ÑÐµÐŒÐ°Ð»Ð°Ñ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·. }
+
+_textTolong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÐºÐžÐŒÐ³Ðµ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>Ð°Ð»ÑÑÑÑÐ»Ð°Ñ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÑÐžÐ· Ð°Ð»ÑÑÑÑÐ»Ð°Ñ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·.  }
+
+_textFromlong_ [l=ky] {<p> Ð¡ÐžÐ· <i>ÐºÐžÐŒÐŽÐµÐœ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>Ð¶ÐžÐ±ÐµÑÒ¯Ò¯Ð»Ó©Ñ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ°Ð³Ñ ÑÐµÑÐžÑÐ»Ð°Ñ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·.  }
+
+_textSerieslong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÑÐµÑÐžÑÐ»Ð°Ñ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ<i>Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐŽÑÐœ ÑÐµÑÐžÑÐ»Ð°ÑÑ Ð±ÐŸÑÐœÑÐ°  ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÐŒÐ°ÑÐµÑÐžÐ°Ð»ÐŽÐ°Ñ ÑÐµÑÐžÑÐ»Ð°ÑÑÐœ Ñ
+ÑÐŸÐœÐŸÐ»ÐŸÐ³ÐžÑÐ»ÑÐº ÐžÑÐµÑÐžÐœÐŽÐµ ÐºÓ©ÑÓ©ÑÒ¯Ð·. }
+
+_textBrowselong_ [l=ky] {<p>Ð¡ÐžÐ·<i>Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐŽÑ ÐºÓ©ÑÒ¯Ò¯</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÐ¿
+<i>ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐž ÐºÐ°ÑÐ°Ð¹ Ð°Ð»Ð°ÑÑÐ·</i>. }
+
+_textPeoplelong_ [l=ky] {<p>Ð¡ÐžÐ· <i>Ð¿ÐµÑÑÐŸÐœÐ°Ð»ÐžÐ¹Ð»ÐµÑ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>Ð°Ð»Ð°Ñ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ°Ð³Ñ Ð¿ÐµÑÑÐŸÐœÐ°Ð»ÐžÐ¹Ð»ÐµÑ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·.  }
+
+_textAcronymlong_ [l=ky] {<p> Ð¡ÐžÐ· ÐºÑÑÐºÐ°ÑÑÑÑÐ»Ð°Ñ<i>ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ</i> Ð±Ð°ÑÑÐ¿ ÐºÑÑÐºÐ°ÑÑÑÑÐ»Ð°Ñ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÑÐžÐ· ÐºÑÑÐºÐ°ÑÑÑÑÐ»Ð°Ñ ÐºÐµÐ·ÐŽÐµÑÐºÐµÐœ Ð¶ÐµÑÐ»ÐµÑÐŽÐž ÐºÓ©ÑÓ© Ð°Ð»Ð°ÑÑÐ·.}
+
+_textPhraselong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÑÑÐ°Ð·Ð°Ð»Ð°Ñ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÐ¿ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐŽÐ°Ð³Ñ <i>ÑÑÐ°Ð·Ð°Ð»Ð°Ñ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœÑÐœ Ð°Ð»Ð°ÑÑÐ·</i>.    }
+
+_textArtistlong_ [l=ky] {<p> Ð¡ÐžÐ· ÑÒ¯ÑÓ©ÑÑÒ¯Ð»Ó©Ñ<i>ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ</i> Ð±Ð°ÑÑÐ¿ ÑÒ¯ÑÓ©ÑÑÒ¯Ð»Ó©Ñ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÑÐžÐ· ÑÒ¯ÑÓ©ÑÑÒ¯Ð»Ó©ÑÐŽÒ¯ Ð°ÑÑ ÐŒÐµÐœÐµÐœ ÑÐŸÑÑÑÐŸÐ¹ Ð°Ð»Ð°ÑÑÐ·.}
+
+_textKeywordlong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÐŒÐ°Ò£ÑÐ· ÑÓ©Ð·ÐŽÓ©Ñ</i>ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>ÐŒÐ°Ò£ÑÐ· ÑÓ©Ð·ÐŽÓ©ÑÒ¯  Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœ Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ°Ð³Ñ ÐŒÐ°Ò£ÑÐ· ÑÓ©Ð·ÐŽÓ©ÑÒ¯ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·.  }
+
+_textVolumelong_ [l=ky] {<p>Ð¡ÐžÐ· <i>ÑÐŸÐŒ </i>  ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ </i> Ð±Ð°ÑÑÑ Ð°ÑÐºÑÐ»ÑÑ <i> ÑÐŸÐŒÐŽÐŸÑ Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð·ÐŒÑÐœÐŽÑ Ð°Ð»Ð°Ð»Ð°ÑÑÐ·</i>. ÐÑÐ» ÐŒÐ°Ð·ÐŒÑÐœÐŽÐ°Ðœ ÑÐžÐ· ÐºÐžÑÐµÐ¿ÑÐžÐœ ÑÐŸÐŒÐŽÐŸÑÑ ÑÐžÐ·ÐžÐŒÐžÐœ ÐºÓ©ÑÓ©ÑÒ¯Ð·. }
+
+_textCaptionslong_ [l=ky] {<p>Ð¡ÐžÐ· <i>Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐŽÑÐœ Ð¶Ð°Ð·ÑÑÐ»Ð°ÑÑ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÐ¿
+ <i>ÐÑÐ±Ð»ÐžÐºÐ°ÑÐžÑÐ»Ð°ÑÐŽÑÐœ Ð¶Ð°Ð·ÑÑÑÑ</i> Ð±ÐŸÑÐœÑÐ° ÐŒÐ°Ð°Ð»ÑÐŒÐ°Ñ Ð°Ð»Ð°Ð»Ð°ÑÑÐ·ÐŽÐ°Ñ. }
+
+_textCountrieslong_ [l=ky] {<p>Ð¡ÐžÐ· <i>Ó©Ð»ÐºÓ©Ð»Ó©Ñ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑ Ð°ÑÐºÑÐ»ÑÑ <i>ÓšÐ»ÐºÓ©Ð»Ó©Ñ</i> Ð¶Ó©ÐœÒ¯ÐœÐŽÓ© ÐŒÐ°Ð°Ð»ÑÐŒÐ°Ñ ÐºÓ©ÑÓ© Ð°Ð»Ð°ÑÑÐ·.  }
+
+
+_textdefaultlongtext_ [l=ky] {<p>ÐÐµÐ»Ð³ÐžÑÐžÐ· ÑÐµÑ Ð±ÐŸÑÐœÑÐ° ÑÑÑÐ°Ð»Ð³Ð°Ðœ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐž ÐºÐ°ÑÐŸÐŸ Ò¯ÑÒ¯Ðœ <i>Ð±ÐµÐ»Ð³ÐžÑÐžÐ· ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÑ</i> ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ·. }
+
+_texthelptopicstitle_ [l=ky] {ÐÓ©Ð»Ò¯ÐŒÐŽÓ©Ñ}
+
+_textreadingdocs_ [l=ky] {ÐÐŸÐºÑÐŒÐµÐœÑÑÐž ÐºÐ°ÐœÐŽÐ°Ð¹ ÐžÐ·ÐŽÓ©Ó© ÐºÐµÑÐµÐº}
+
+_texthelpreadingdocs_ [l=ky] {
+<p>You can tell when you have arrived at an individual book or document
+because its title, or a photograph of the front cover, appears at the top
+left of the page. In some collections this is accompanied by a table of
+contents, while others contain just the number of the current page along
+with a box that allows you to select a new page and go forward and
+backward. In the table of contents, the current section heading is in bold
+face, and the table is expandable -- click on the folders to open or close
+them; click on the open book at the top to close it.</p>
+
+<p>Underneath is the text of the current section. When you have read
+through it, there are arrows at the bottom to take you on to the next
+section or back to the previous one.</p>
+
+<p>Below the title or front-cover photograph are some buttons. Click on
+<i>expand text</i> to expand out the whole text of the current section, or
+book. If the document is large, this could take a long time and use a lot
+of memory! Click on <i>expand contents</i> to expand out the whole table of
+contents so that you can see the titles of all chapters and
+subsections. Click on <i>detach</i> to make a new browser window for this
+document. (This is useful if you want to compare documents, or read two at
+once.) Finally, when you do a search the words you search for are
+highlighted. Click on <i>no highlighting</i> to remove highlighting.</p>
+}
+
+_texthelpsearchingtitle_ [l=ky] {ÐÑÐ°Ð¹ÑÐœ Ð°ÑÐœÐ°Ð»Ð³Ð°Ðœ ÑÐµÑÐŒÐžÐœÐŽÐµÑ Ð±ÐŸÑÐœÑÐ° ÐžÐ·ÐŽÓ©Ó©ÐœÒ¯ ÐºÐ°ÐœÐŽÐ°Ð¹ Ð¶Ò¯ÑÐ³Ò¯Ð·Ò¯Ò¯ ÐºÐµÑÐµÐº}
+_texthelpsearching_ [l=ky] {
+<p>
+  Ð¡ÐžÐ· ÐžÐ·ÐŽÓ©Ó© Ð±ÐµÑÐžÐœÐµÐœ, Ð¶Ó©ÐœÓ©ÐºÓ©Ð¹ ÑÑÑÐŸÐŸ Ð¶Ð°ÑÐ°Ð¹ Ð°Ð»Ð°ÑÑÐ·. <p>
+  
+  <ol><li>Ð­ÐŒÐœÐµÐœÐž ÐžÐ·ÐŽÐµÐ¹ÑÐžÐ· Ð°ÐœÑÐºÑÐ°Ò£ÑÐ·
+      <li>ÐÐœÑ ÐºÐ°ÐœÐŽÐ°Ð¹ ÐžÐ·ÐŽÓ©Ó©ÐœÒ¯ Ð°ÐœÑÐºÑÐ°Ò£ÑÐ·: ÑÑÐ°Ð·Ð°ÐœÑ  Ð¶Ðµ Ð¶ÐµÐºÐµ ÑÓ©Ð·ÐŽÓ©ÑÐŽÒ¯ ÐºÐŸÐ»ÐŽÐŸÐœÑÑ ÐŒÐµÐœÐµÐœ 
+      <li>Ð¡ÑÑÐŸÐŸÒ£ÑÐ·ÐŽÑ  ÐžÐ·ÐŽÓ©Ó© Ð¶ÐŸÐ»ÑÐœÐ° ÑÐµÑÐžÐ¿ ÐºÐžÑÐ³ÐžÐ·ÐžÒ£ÐžÐ·
+      <li>ÐÐ·ÐŽÓ©Ó©ÐœÒ¯ Ð±Ð°ÑÑÐŸÐŸ <i>ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÒ£ÑÐ·</i> 
+  </ol>
+
+<p>Ð¡ÑÑÐŸÐŸÐœÑÐœ Ð¶ÑÐ¹ÑÐœÑÑÐ³Ñ ÑÑÐºÐºÐ°ÐœÐŽÐ°Ðœ ÐºÐžÐ¹ÐžÐœ ÑÐºÑÐ°ÐœÐŽÐ°  20 ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐžÐœ Ð°ÑÐ°Ð»ÑÑÑ Ð¿Ð°Ð¹ÐŽÐ° Ð±ÐŸÐ»ÐŸÑ. Ð¢ÐžÐ·ÐžÐŒÐŽÐžÐœ Ð°ÑÐ³ÑÐœÐŽÐ°, ÐºÐžÐ¹ÐžÐœÐºÐž 20 ÐŽÐŸÐºÑÐŒÐµÐœÑÐºÐµ Ó©ÑÒ¯Ò¯ ÐºÐœÐŸÐ¿ÐºÐ°ÑÑ Ð±Ð°Ñ. ÐÐ°ÑÑÐ¹Ð¶Ð°Ð»Ð°ÑÐŽÑÐœ ÐºÐžÐ¹ÐžÐœÐºÐž Ð±ÐµÑÑÐµÑÐžÐœÐŽÐµ ÐŽÐ°Ð³Ñ 20 ÐŽÐŸÐºÑÐŒÐµÐœÑÐºÐµ Ð¶Ðµ Ð°Ð»ÐŽÑÒ£ÐºÑ 20 ÐŽÐŸÐºÑÐŒÐµÐœÑÐºÐµ ÐºÓ©ÑÒ¯Ò¯Ð³Ó© Ð°ÑÐœÐ°Ð»Ð³Ð°Ðœ ÐºÐœÐŸÐ¿ÐºÐ°ÐœÑ ÐºÓ©ÑÓ©ÑÒ¯Ð·. ÐÐŸÐºÑÐŒÐµÐœÑÑÐžÐœ Ð°ÑÑÐœÐ° Ð¶Ðµ Ð°ÐœÑÐœ Ð°Ð»ÐŽÑÐœÐŽÐ°Ð³Ñ Ð±ÐµÐ»Ð³ÐžÐœÐž Ð±Ð°ÑÑÐ¿, Ð°ÐœÑ ÐºÐ°ÑÐ°Ð¹ Ð°Ð»Ð°ÑÑÐ·. 
+
+<p>ÐÐ·ÐŽÓ©Ó©ÐœÒ¯Ðœ ÐœÐ°ÑÑÐ¹Ð¶Ð°ÑÑÐœÐŽÐ° ÑÒ£ ÐºÓ©Ð¿ ÐŽÐµÐ³ÐµÐœÐŽÐµ -100 ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð±ÐŸÐ»ÐŸÑ. Ð¡ÐžÐ· Ð±ÑÐ» ÑÐ°ÐœÐŽÑ ÑÒ¯Ð·Ó©ÑÒ¯Ò¯ Ð±ÐµÑÐžÐœÐµÐœ Ó©Ð·Ð³Ó©ÑÑÓ© Ð°Ð»Ð°ÑÑÐ· (ÐÐµÑÑÐžÐœ Ð±Ð°Ñ Ð¶Ð°Ð³ÑÐœÐŽÐ°Ð³Ñ <i> ÑÒ¯Ð·Ó©ÑÒ¯Ò¯Ð»Ó©Ñ</i>ÐºÐœÐŸÐ¿ÐºÐ°ÑÑ). <p>
+}
+
+_texthelpquerytermstitle_ [l=ky] {ÐÐ·ÐŽÓ©Ó©Ð³Ó© Ð°ÑÐœÐ°Ð»Ð³Ð°Ðœ ÑÓ©Ð·ÐŽÓ©Ñ}
+_texthelpqueryterms_ [l=ky] {
+<p>Ð¡ÐžÐ·ÐŽÐžÐœ ÑÑÑÐŸÐŸ Ð¶ÐŸÐ»ÑÐœÐŽÐ° ÐºÐžÑÐ³ÐžÐ·Ð³ÐµÐœÐžÒ£ÐžÐ·ÐŽÐžÐœ Ð±Ð°Ð°ÑÑ, â ÐžÐ·ÐŽÓ©Ð³Ó©Ó© Ð°ÑÐœÐ°Ð»Ð³Ð°Ðœ ÑÓ©Ð·ÐŽÓ©Ñâ ÐŽÐµÐ¿ Ð°ÑÐ°Ð»Ð°Ñ. ÐÑ Ð±ÐžÑ ÑÓ©Ð· ÑÐ°ÐŒÐ³Ð°Ð»Ð°Ñ ÐŒÐµÐœÐµÐœ ÑÐžÑÑÐ°Ð»Ð°ÑÐŽÐ°Ðœ ÑÑÑÐ°Ñ. Ð¡Ó©Ð·ÐŽÓ©Ñ Ð±ÐŸÑ ÐŸÑÑÐœ ÐŒÐµÐœÐµÐœ Ð±Ó©Ð»Ò¯ÐœÐ³Ó©Ðœ. Ð­Ð³ÐµÑ Ð±Ð°ÑÐºÐ° Ð±ÐžÑ Ð±ÐµÐ»Ð³Ðž Ð±ÐŸÐ»ÑÐŸ, ÐŒÐžÑÐ°Ð»Ñ Ð¿ÑÐœÐºÑÑÐ°ÑÐžÑ Ð±ÐµÐ»Ð³ÐžÐ»ÐµÑÐž, Ð°ÐœÐŽÐ° Ð°Ð»Ð°Ñ ÐŽÐ° Ð±ÐŸÑ Ð±ÐµÐ»Ð³Ðž ÑÑÑÐºÑÑÑ ÑÓ©Ð· Ð±Ó©Ð»Ð³Ò¯Ñ ÐºÑÐ·ÐŒÐ°ÑÑÐœ Ð°ÑÐºÐ°ÑÐ°Ñ. Ð¡ÐžÐ· Ð¿ÑÐœÐºÑÑÐ°ÑÐžÑ Ð±ÐµÐ»Ð³ÐžÐ»ÐµÑÐž Ð±Ð°Ñ ÑÓ©Ð·ÐŽÓ©Ñ Ð±ÐŸÑÐœÑÐ° ÐžÐ·ÐŽÓ©Ó© Ð¶Ò¯ÑÐ³Ò¯Ð·Ó© Ð°Ð»Ð°ÑÑÐ·. 
+
+
+<p>ÐÐžÑÐ°Ð»Ñ, <p>
+    <ul><kbd>Ð§ÑÐœ Ð°ÑÐ°Ð»ÐŽÐ°ÑÑÐœÐŽÐ°Ð³Ñ ÐÐ¹ÑÐ»-ÑÐ°ÑÐ±Ð°ÑÑÐ»ÑÐ³Ñ: ÐÐŸÐ»ÐŽÐŸÐŸ ÑÐ°ÑÐŒÐ°Ð³Ñ (1993)</kbd></ul>
+      <p>ÑÑÑÐŸÐŸÐœÑ ÐºÐ°ÑÐ°ÑÑÑÑÑÐ°Ðº Ð°Ð» Ð°Ð»ÐŽÑÒ£ÐºÑ ÐŒÐµÐœÐµÐœ Ð±Ð°ÑÐ°Ð±Ð°Ñ<p>
+      <ul><kbd> Ð§ÑÐœ Ð°ÑÐ°Ð»ÐŽÐ°ÑÑÐœÐŽÐ°Ð³Ñ Ð°Ð¹ÑÐ»-ÑÐ°ÑÐ±Ð°ÑÑÐ»ÑÐ³Ñ ÐºÐŸÐ»ÐŽÐŸÐŸ ÑÐ°ÑÐŒÐ°Ð³Ñ 1993</kbd></ul><p>
+}
+
+_texthelpquerytypetitle_ [l=ky] {Ð¡ÑÑÐŸÐŸ ÑÐžÐ¿ÑÐµÑÐž}
+_texthelpquerytype_ [l=ky] {
+<p>ÓšÐ·Ð³Ó©ÑÓ© ÑÐºÐž ÑÑÑÐŸÐŸ ÑÐžÐ±Ðž Ð±Ð°Ñ.
+
+<ul>
+  <li>ÐÐ°ÑÐŽÑÐº <b>ÑÓ©Ð·ÐŽÓ©Ñ</b> Ð±ÐŸÑÐœÑÐ° ÑÑÑÐŸÐŸÐ»ÐŸÑ. ÐÑÐ» ÑÐžÐ· ÐžÐ·ÐŽÓ©Ó© Ð¶ÐŸÐ»ÑÐœÐ° ÐºÐžÑÐ³ÐžÐ·Ð³ÐžÒ£ÐžÐ· ÐºÐµÐ»Ð³ÐµÐœ ÑÓ©Ð·ÐŽÓ©ÑÐŽÒ¯Ðœ Ð±Ð°Ð°ÑÑ Ð±Ð°ÑÐŽÑÐº ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑ Ò¯ÑÒ¯Ðœ Ð±ÐŸÐ»ÐŸÑ. Ð¢ÑÑÑÐ° ÐºÐµÐ»Ð³ÐµÐœ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑ Ð°Ð»ÑÐ°Ð²ÐžÑÑÐžÐº ÑÐ°ÑÑÐžÐ¿ÑÐµ ÑÑÐ³Ð°ÑÑÐ»Ð°Ñ. <p>
+
+  <li>ÐÑÑ Ð±ÐžÑ <b>ÑÓ©Ð·ÐŽÓ©Ñ</b> Ð±ÐŸÑÐœÑÐ° ÑÑÑÐŸÐŸÐ»ÐŸÑ. ÐÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐžÐœ ÑÐµÐŒÐ°ÑÑÐœÐŽÐ°  ÐºÐµÐ·ÐŽÐµÑÒ¯Ò¯ ÐŒÒ¯ÐŒÐºÒ¯Ðœ Ð±ÐžÑ ÐœÐµÑÐµ ÑÓ©Ð·ÐŽÒ¯ Ð¶Ð°Ð·ÑÑ Ð¶ÐµÑÐºÐžÐ»ÐžÐºÑÒ¯Ò¯.  Ð¡ÑÑÐŸÐŸÐ³ÐŸ ÑÑÑÑÐ° ÐºÐµÐ»Ð³ÐµÐœÐž ÐŒÑÐœÐŽÐ°Ð¹ Ð°ÐœÑÐºÑÐ°Ð»Ð°Ñ:  
+      <p><ul>
+        <li> ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµ ÐžÐ·ÐŽÐµÐ»Ò¯Ò¯ÑÒ¯ ÑÐµÑÐŒÐžÐœÐŽÐµÑ ÐºÓ©Ð±Ò¯ÑÓ©Ó©Ðº ÐºÐµÐ·ÐŽÐµÑÐºÐµÐœ ÑÐ°Ð¹ÑÐœ, Ð°Ð» ÐºÓ©Ð±Ò¯ÑÓ©Ó©Ðº ÑÑÑÑÐ° ÐºÐµÐ»ÐµÑ;   <li> Ð¶Ð°Ð»Ð¿Ñ ÑÓ©Ð·ÐŽÓ©ÑÐ³Ó© ÐºÐ°ÑÐ°Ð³Ð°ÐœÐŽÐ°, ÑÐµÐ¹ÑÐµÐº ÑÓ©Ð·ÐŽÓ©Ñ ÐŒÐ°Ò£ÑÐ·ÐŽÑÑÑÐ°Ðº;
+        <li> ÑÐŸÒ£ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐ³Ðµ ÐºÐ°ÑÐ°Ð³Ð°ÐœÐŽÐ° ÐºÐžÑÐžÐœÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐ³Ðµ ÐºÓ©Ð±Ò¯ÑÓ©Ó©Ðº ÑÑÑÑÐ° ÐºÐµÐ»ÐµÑ.
+      </ul>
+</ul>
+
+<p>ÐÐ·ÐŽÓ©Ó©Ð³Ó© ÐºÐ°ÐœÑÐ° ÑÓ©Ð· ÐºÐµÑÐµÐº Ð±ÐŸÐ»ÑÐŸ ÐŸÑÐŸÐœÑÐŸ ÑÓ©Ð·ÐŽÒ¯ Ð¿Ð°Ð¹ÐŽÐ°Ð»Ð°ÐœÑÒ£ÑÐ· â ÐÐžÑ ÑÒ¯Ð¹Ð»Ó©ÐŒ Ð¶Ðµ Ð¿Ð°ÑÐ°Ð³ÑÐ°Ñ Ð±ÐŸÐ»ÑÑÑ ÐŒÒ¯ÐŒÐºÒ¯Ðœ.  <p>
+}
+
+_textdatesearch_ [l=ky] {ÐÐ°ÑÐ° Ð±ÐŸÑÐœÑÐ° ÐžÐ·ÐŽÓ©Ó©}
+
+_texthelpdatesearch_ [l=ky] {
+ÐÐ°ÑÐ° Ð±ÐŸÑÐœÑÐ° ÐžÐ·ÐŽÓ©Ó©, Ð±ÐµÐ»Ð³ÐžÐ»Ò¯Ò¯ Ð±ÐžÑ ÑÐ±Ð°ÐºÑÑ Ð°ÑÐ°Ð»ÑÐ³ÑÐœÐŽÐ° Ð±ÐŸÐ»Ð³ÐŸÐœ ÐŸÐºÑÑÐ»Ð°ÑÐ³Ð° ÐºÐ°ÑÑÑÑÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐž ÑÐ°Ð±ÑÑÐ³Ð° ÐŒÒ¯ÐŒÒ¯ÐœÑÒ¯Ð»Ò¯Ðº
+Ð±ÐµÑÐµÑ. Ð¡ÐžÐ· ÐžÐ·ÐŽÓ©Ó©ÐœÒ¯ Ð±ÐµÐ»Ð³ÐžÐ»Ò¯Ò¯ Ð±ÐžÑ Ð¶ÑÐ»Ð³Ð° ÐºÐ°ÑÑÑÑÑ Ð±Ð°Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑ Ð±ÐŸÐ¹ÑÐœÑÐ° Ð¶Ð°ÐœÐ° Ð¶ÑÐ»ÐŽÐ°Ñ ÐŽÐžÐ°Ð¿Ð°Ð·ÐŸÐœÐŽÐŸÑÑ Ð±ÐŸÐ¹ÑÐœÑÐ° Ð¶Ò¯ÑÐ³Ò¯Ð·Ó© Ð°Ð»Ð°ÑÑÐ·.<p>
+}
+
+_texthelpdatehowtotitle_ [l=ky] {ÐÑÐ» ÑÑÐœÐºÑÐžÑÐœÑ ÐºÐ°ÐœÐŽÐ°Ð¹ ÐºÐŸÐ»ÐŽÐŸÐœÑÑ ÐºÐµÑÐµÐº:}
+_texthelpdatehowto_ [l=ky] {
+<ul>
+   <li>ÐÐžÑ Ð±ÐµÑÐžÐ»Ð³ÐµÐœ Ð¶ÑÐ»ÐŽÐ°Ðœ ÐžÐ·ÐŽÓ©Ó©:<p>
+   <ul>
+       <li>ÐÓ©ÐœÒ¯ÐºÐºÓ©Ðœ ÑÓ©Ð·ÐŽÓ©ÑÐŽÒ¯ ÐºÐžÑÐ³ÐžÐ·ÐžÒ£ÐžÐ·.
+       <li>Ð¡ÐžÐ·Ð³Ðµ ÐºÐµÑÐµÐºÑÒ¯Ò¯ Ð¶ÑÐ»ÐŽÑ "ÐÐ°ÑÐºÑ (Ð¶Ðµ ÐœÐ°ÐºÑÑ) ÐŽÐ°ÑÐ°" ÑÒ¯ÑÒ¯ÐœÐŽÓ© ÐºÐžÑÐ³ÐžÐ·ÐžÒ£ÐžÐ·.
+       <li>Ð¡ÐžÐ·ÐŽÐžÐœ ÐŽÐ°ÑÐ°Ò£ÑÐ· Ð±ÐžÐ·ÐŽÐžÐœ ÑÑÐ°Ð³Ð° ÑÐµÐžÐ¹Ðœ ÐŽÐµÐ¿ ÑÑÐµÐ¿ÑÐµÐ»ÑÐµ ÑÐžÐ· âÐ±.Ñ.Ñ.â ÐŽÐµÐ³ÐµÐœ ÐŸÐ¿ÑÐžÑÐœÑ ÑÐ°ÐœÐŽÐ°Ð¿ Ð°Ð»ÑÒ£ÑÐ·.
+       <li>ÐÐ·ÐŽÓ©Ó©ÐœÒ¯ Ð±Ð°ÑÑÐŸÐŸ.
+   </ul>
+<p><li>ÐÐµÑÐžÐ»Ð³ÐµÐœ ÐŽÐžÐ°Ð¿Ð°Ð·ÐŸÐœÐŽÐŸÐœ ÐžÐ·ÐŽÓ©Ó©:<p>
+   <ul>
+       <li>ÐÓ©ÐœÒ¯ÐºÐºÓ©Ðœ ÑÓ©Ð·ÐŽÓ©ÑÐŽÒ¯ ÐºÐžÑÐ³ÐžÐ·ÐžÒ£ÐžÐ·.
+       <li>ÐÐ°ÑÐºÑ ÐŽÐ°ÑÐ°ÑÑ "ÐÐ°ÑÐºÑ (Ð¶Ðµ ÐœÐ°ÐºÑÑ) ÐŽÐ°ÑÐ°" ÑÒ¯ÑÒ¯ÐœÐŽÓ© ÐºÐžÑÐ³ÐžÐ·ÐžÒ£ÐžÐ·.
+       <li>ÐÐºÑÑÐºÑ ÐŽÐ°ÑÐ°ÑÑ "ÐÐºÑÑÐºÑ ÐŽÐ°ÑÐ°ÑÑ" ÑÒ¯ÑÒ¯ÐœÐŽÓ© ÐºÐžÑÐ³ÐžÐ·ÐžÒ£ÐžÐ·.
+       <li>Ð¡ÐžÐ·ÐŽÐžÐœ ÐŽÐ°ÑÐ°Ò£ÑÐ· Ð±ÐžÐ·ÐŽÐžÐœ ÑÑÐ°Ð³Ð° ÑÐµÐžÐ¹Ðœ ÐŽÐµÐ¿ ÑÑÐµÐ¿ÑÐµÐ»ÑÐµ ÑÐžÐ· âÐ±.Ñ.Ñ.â ÐŽÐµÐ³ÐµÐœ ÐŸÐ¿ÑÐžÑÐœÑ ÑÐ°ÐœÐŽÐ°Ð¿ Ð°Ð»ÑÒ£ÑÐ·.
+       <li>ÐÐ·ÐŽÓ©Ó©ÐœÒ¯ Ð±Ð°ÑÑÐŸÐŸ.
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresults_ [l=ky] {
+ÐÐ°Ð»Ð¿Ñ Ð°Ð¹ÑÐºÐ°ÐœÐŽÐ°, Ð±ÑÐ» ÐžÐ·ÐŽÓ©Ó©ÐŽÓ© 1903 Ð¶ÑÐ» Ð¶Ó©ÐœÒ¯ÐœÐŽÓ© ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐž ÐžÐ·ÐŽÐµÑÐµÒ£ÐžÐ· ÑÐžÐ·Ð³Ðµ 1903 Ð¶ÑÐ»Ñ Ð¶Ð°Ð·ÑÐ»Ð³Ð°Ðœ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑ ÑÑÐ³Ð°ÑÑÐ»Ð±Ð°Ð¹Ñ, Ð°ÐœÐŽÐ° 1903 Ð¶ÑÐ» Ð¶Ó©ÐœÒ¯ÐœÐŽÓ© Ð³Ð°ÐœÐ° ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑ ÑÐ°Ð±ÑÐ»Ð°Ñ.ÐÐžÑÐŸÐº,ÐŽÐžÐ°Ð¿ÐŸÐ·ÐŸÐœÐŽÐŸÑ Ð±ÐŸÑÐœÑÐ° ÐžÐ·ÐŽÐµÑÐµÒ£ÐžÐ· (ÐŒÐžÑÐ°Ð»Ñ 1899-1911) ÑÐžÐ·Ð³Ðµ 1903 Ð¶ÑÐ»Ð³Ð° ÑÐžÐµÑÐµÑÐž Ð±Ð°Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐžÐœ Ð±Ð°Ð°ÑÐŽÑÐ³Ñ ÐŽÐ°Ð³Ñ ÐºÓ©ÑÑÓ©ÑÒ¯Ð»Ó©Ñ. ÐÑÐŸÐœÐŽÑÐºÑÐ°Ðœ ÑÐžÐ·Ð³Ðµ ÐºÓ©ÑÑÓ©Ò¯Ð»Ð³Ó©Ðœ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐžÐœ Ð°ÑÐ°ÑÑÐœÐŽÐ° ÐŽÐ°ÑÐ°ÑÑ ÑÐ°Ðº Ð¶Ð°Ð·ÑÐ»Ð±Ð°Ð³Ð°ÐœÑ ÐŽÐ° ÐŒÒ¯ÐŒÐºÒ¯Ðœ. ÐÐžÐ°Ð¿ÐŸÐ·ÐŸÐœÐŽÐŸÐ³Ñ Ð±Ð°Ð°ÑÐŽÑÐº ÐŽÐ°ÑÐ°Ð»Ð°ÑÐ³Ð° ÐºÐ°ÑÑÑÑ Ð±Ð°Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑ ÐºÓ©ÑÑÓ©ÑÒ¯Ð»Ó©Ñ.<p>
+}
+
+_textchangeprefs_ [l=ky] {Ð¢Ò¯Ð·Ó©ÑÒ¯Ò¯Ð»Ó©ÑÐŽÒ¯ Ó©Ð·Ð³Ó©ÑÑÒ¯Ò¯}
+
+_texthelppreferences_ [l=ky] {
+  <p>Ð¢Ò¯Ð·Ó©ÑÒ¯Ò¯Ð»Ó©Ñ <i> Ð±ÐµÑÐžÐœÐŽÐµ</i> (Ð±ÐµÑÑÐžÐœ Ð¶ÐŸÐ³ÐŸÑÑ Ð±Ó©Ð»Ò¯Ð³Ò¯ÐœÐŽÓ©Ð³Ò¯ ÐºÐœÐŸÐ¿ÐºÐ°) ÑÐžÐ·ÐŽÐµÑ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑÐžÐœ ÐºÑÑ Ð±ÐžÑ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÐ»ÐµÑÐžÐœ Ó©Ð·Ð³Ó©ÑÑÓ© Ð°Ð»Ð°ÑÑÐ·. 
+ }
+
+_texthelpcollectionprefstitle_ [l=ky] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐ»Ð°ÑÐŽÑ ÑÒ¯Ð·Ó©ÑÒ¯Ò¯}
+_texthelpcollectionprefs_ [l=ky] {
+ ÐÑÑ Ð±ÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐ»Ð°ÑÐŽÐ° ÐºÓ©Ð¿ÑÓ©Ð³Ó©Ðœ ÐžÑÐºÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐ»Ð°Ñ Ð±ÐŸÐ»ÐŸÑ, Ð°Ð»Ð°ÑÐŽÐ° ÐžÐ·ÐŽÓ©Ó© Ð°ÑÐºÐ°Ð¹ÑÑÐœÑÑÑÐœÐŽÐ° Ð¶ÐµÐºÐµ Ð¶Ð°ÐœÐ° Ð±Ð°ÑÐŽÑÐ³ÑÐœ Ð±ÐžÑÐ³Ðµ Ð¶Ò¯ÑÐ³Ò¯Ð·Ó© Ð°Ð»Ð°ÑÑÐ·. Ò¯Ð¹Ò¯ÐœÓ© ÐºÐµÐ»ÑÐžÑÒ¯Ò¯ Ð±ÐµÑÐžÐœÐŽÐµ ÑÐžÐ· ÐžÐ·ÐŽÓ©Ó©Ð³Ó©  ÐºÐŸÑÐºÑÒ£ÑÐ· ÐºÐµÐ»Ð³ÐµÐœ ÐžÑÐºÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐ»Ð°ÑÐŽÑ ÑÐ°ÐœÐŽÐ°Ð¿ Ð°Ð»ÑÐ°Ò£ÑÐ· Ð±ÐŸÐ»ÐŸÑ.
+ }
+
+_texthelplanguageprefstitle_ [l=ky] {Ð¢ÐžÐ»ÐŽÐž ÑÒ¯Ð·Ó©ÑÒ¯Ò¯}
+_texthelplanguageprefs_ [l=ky] {
+ ÐÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ° ÑÑÐ°ÐœÐŽÐ°ÑÑÑÑÑ ÐžÐœÑÐµÑÑÐµÐ¹Ñ ÑÐžÐ»Ðž Ð±Ð°Ñ, Ð±ÐžÑÐŸÐº ÑÐžÐ· Ð±Ð°ÑÐºÐ° ÑÐžÐ»ÐŽÐž ÑÐ°ÐœÐŽÐ°Ð¿ Ð°Ð»ÑÐ°Ò£ÑÐ· Ð±ÐŸÐ»ÐŸÑ. ÐÑÐŸÐœÐŽÐŸÐ¹ ÑÐ»Ðµ ÑÐžÐ· Ð±ÑÐ» Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐ°ÐŽÐ° Ð±Ð°Ñ Ð±Ð°ÑÐºÐ° ÐºÐŸÐŽÐžÑÐŸÐ²ÐºÐ°ÐœÑ ÑÐ°ÐœÐŽÐ°Ð¿ Ð°Ð»ÑÐ°Ò£ÑÐ· Ð±ÐŸÐ»ÐŸÑ, ÑÐžÐ·ÐŽÐžÐœ Ð±ÑÐ°ÑÐ·ÐµÑÐ³Ðµ ÑÑÑÑÐ° ÐºÐµÐ»Ð³ÐµÐœ Ð°Ð²ÑÐŸÐŒÐ°Ñ ÑÒ¯ÑÐŽÓ© ÑÑÐ°ÐœÐŽÐ°ÑÑÑ Ð±ÐŸÐ»ÐŸÑ, ÑÑÑÑÐ° ÐºÐŸÐŽÐžÑÐŸÐ²ÐºÐ°ÐœÑ Ó©Ð·Ò¯Ò£Ò¯Ð· ÑÐ°ÐœÐŽÐ°Ð³Ð°Ðœ ÐŸÒ£. ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐ»Ð°ÑÐŽÑÐœ Ð±Ð°Ð°ÑÐŽÑÐ³ÑÐœÐŽÐ° ÐºÐ°ÑÐŸÐŸÐœÑÐœ Ð³ÑÐ°ÑÐžÐºÐ°Ð»ÑÐº ÑÐµÐ¶ÐžÐŒÐžÐœÐµÐœ ÑÐµÐºÑÑ ÑÐµÐ¶ÐžÐŒÐžÐœÐµ Ó©ÑÒ¯Ò¯Ð³Ó© Ð¶Ð°ÐœÐ° ÑÐµÑÐºÐµÑÐžÐœÑÐµ ÐºÓ©ÑÒ¯Ò¯Ð³Ó© ÐŽÐ° Ð±ÐŸÐ»ÐŸÑ.
+}
+
+ _texthelppresentationprefstitle_ [l=ky] {ÐÐœÑÐµÑÑÐµÐ¹ÑÑÐž ÑÒ¯Ð·Ó©ÑÒ¯Ò¯ }
+_texthelppresentationprefs_ [l=ky] {
+ ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐ»Ð°ÑÐ³Ð° Ð±Ð°Ð¹Ð»Ð°ÐœÑÑÑÑÑ Ð°Ñ-ÑÒ¯ÑÐŽÒ¯Ò¯ ÑÒ¯Ð·Ó©ÑÒ¯Ò¯Ð»Ó©Ñ Ð±Ð°Ñ. 
+ 
+ <p>Web Ð±ÐµÑÑÐµÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÑÑ Ð°Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐžÐœ Ò¯ÑÑÒ¯ÐœÐŽÓ©Ð³Ò¯ Ð±Ð°ÑÐºÐ°ÑÑÑ Ð¿Ð°ÐœÐµÐ»ÐžÐœ ÐºÐŸÐ»ÐŽÐŸÐœÑÑÐ³Ð° ÐŒÒ¯ÐŒÐºÒ¯ÐœÐŽÒ¯Ðº Ð±ÐµÑÐµÑ, Ð°ÐœÑ ÐŒÐµÐœÐµÐœ ÐžÐ·ÐŽÓ©Ó©ÐŽÓ©Ðœ ÐºÐžÐ¹ÐžÐœ Greenstone ÑÐµÐŒÐ°Ò£ÑÐ·  Web Ð±ÐµÑÐºÐµ ÑÒ¯ÑÓ©Ñ.  ÐÐ°Ò£Ñ ÑÑÑÐŸÐŸ ÐºÐŸÐ¹ÑÑ Ò¯ÑÒ¯Ðœ Ó©Ð·Ò¯Ò£Ò¯Ð·ÐŽÒ¯Ðœ Ð±ÑÐ°ÑÐ·ÐµÑÐžÒ£ÐžÐ·ÐŽÐµÐ³Ðž "back" ÐºÐœÐŸÐ¿ÐºÐ°ÑÑÐœ Ð±Ð°ÑÑÐ°Ò£ÑÐ· Ð±ÐŸÐ»ÐŸÑ. ÐÑÐ» ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐ»Ð°Ñ WWW ÐŽÐµÐ³Ðž ÑÐ»ÐµÐºÑÑÐŸÐœÐŽÑÐº ÐºÐžÑÐµÐ¿ÐºÐ°ÐœÐ° ÑÐžÑÑÐµÐŒÐ°ÑÑÐœÑÐœ ÐºÐ°ÑÐ°Ð»Ð°ÑÑÐœÐ° ÑÑÐ¹ÑÐŒ ÑÐ°Ð»ÑÑ ÐŒÒ¯ÐŒÐºÒ¯ÐœÐŽÒ¯ÐºÑÓ©ÑÒ¯Ðœ Ð±ÐµÑÐµÑ. 
+}
+
+_texthelpsearchprefstitle_ [l=ky] {ÐÐ·ÐŽÓ©Ó©ÐœÒ¯ ÑÒ¯Ð·Ó©ÑÒ¯Ò¯ }
+_texthelpsearchprefs_ [l=ky] {
+ <p>Ð­ÐºÐž Ð°Ð»ÐŒÐ°ÑÑÑÑÑÐ¿  ÐºÐŸÑÐºÑÑ ÐºÐœÐŸÐ¿ÐºÐ°Ð»Ð°ÑÑ ÐžÐ·ÐŽÓ©Ó©  ÐºÐ°ÑÐžÐµÑÑÐµÑÐžÐœ Ð±Ð°ÑÐºÐ°ÑÐ°Ñ. âÐ ÐµÐ³ÐžÑÑÑÐ»ÐµÑâ ÑÐ°ÐŒÐ³Ð°Ð»Ð°ÑÐŽÑÐœ ÑÐµÐ³ÐžÑÑÐžÑÐ»ÐµÑÐžÐœ ÑÑÐµÐ¿ÑÓ©Ó© Ð¶Ðµ Ó©ÑÒ¯ÑÒ¯Ò¯ ÐŒÒ¯ÐŒÐºÒ¯ÐœÑÒ¯Ð»Ò¯ÑÒ¯Ðœ Ð±ÐµÑÐµÑ. âÐ¡Ó©Ð·ÐŽÓ©ÑÐŽÒ¯Ðœ Ð¶Ð°Ð»Ð³ÐŸÐŸÐ»ÐŸÑÑâ  ÑÓ©Ð·ÐŽÒ¯Ðœ Ð¶Ð°Ð»Ð³ÐŸÐŸÐ»ÐŸÑÑÐœ ÑÑÐµÐ¿ÑÓ©Ó© Ð¶Ðµ ÑÑÐµÐ¿ÑÐµÐ±Ó©Ó© ÐŒÒ¯ÐŒÐºÒ¯ÐœÑÒ¯Ð»Ò¯ÐºÑÓ©ÑÒ¯Ðœ Ð±ÐµÑÐµÑ. âÐÐ·ÐŽÓ©Ó© ÑÐµÑÐµÐ·ÐµÑÐžÐœÐžÐœ Ó©Ð»ÑÓ©ÐŒÒ¯â  Ð±Ò¯ÑÒ¯Ðœ Ð±ÐžÑ Ð°Ð±Ð·Ð°ÑÑÑ ÐºÐžÑÐ³ÐžÐ·Ò¯Ò¯ ÐŒÒ¯ÐŒÐºÒ¯ÐœÐŽÒ¯Ð³Ò¯Ðœ Ð±ÐµÑÐµÑ.  
+ <p>ÐÐžÑÐ°Ð»Ñ, ÑÐ³ÐµÑ <i>ÑÐµÐ³ÐžÑÑÑÐ»ÐµÑÐŽÐž ÑÑÐµÐ¿ÑÐµÐ±Ó©Ó©</i> Ð¶Ð°ÐœÐ°
+ <i>ÑÓ©Ð·ÐŽÓ©ÑÐŽÒ¯Ðœ Ð¶Ð°Ð»Ð³ÐŸÐŸÐ»ÐŸÑÑÐœ ÑÑÐµÐ¿ÑÐµÐ±Ó©Ó© ÑÐ°ÐœÐŽÐ°Ð»ÑÐ°</i>,Ð°ÐœÐŽÐ° ÑÑÑÐŸÐŸ<p>
+     <ul><kbd>African building</kbd></ul>
+       <p>Ð±ÑÐ» ÑÒ¯ÑÐŽÓ© ÐžÐ·ÐŽÐµÐ»ÐµÑ<p>
+       <ul><kbd>africa builds</kbd></ul><p>
+       Ð¡ÐµÐ±ÐµÐ±Ðž âAfricanâ ÑÓ©Ð·Ò¯ÐœÐŽÓ©Ð³Ò¯ Ð¶ÐŸÐ³ÐŸÑÐºÑ ÑÐµÐ³ÐžÑÑÑ ÑÐ°ÐŒÐ³Ð°ÑÑ ÑÓ©ÐŒÓ©ÐœÐºÒ¯ ÑÐµÐ³ÐžÑÑÑ ÑÐ°ÐŒÐ³Ð°ÑÑÐœÐ° Ó©Ð·Ð³Ó©ÑÑÒ¯Ð»Ò¯Ð¿, ânâ Ð¶Ð°ÐœÐ° âingâ Ð¶Ð°Ð»Ð³ÐŸÐŸÐ»ÐŸÑÑ ÑÓ©Ð·ÐŽÓ©Ðœ Ð°Ð»ÑÐœÐ°Ñ.      "African" Ð¶Ð°ÐœÐ° "building" ("s" "builds" ÑÓ©Ð·Ò¯ÐœÓ©Ðœ Ð°Ð»ÑÐœÐ°Ñ).
+ 
+ <p>Ð¡ÐžÐ· ÐÐÐÐ (&), ÐÐ(|), ÐÐÐÐ Ð­ÐÐÐ¡ ÐŒÐžÐ»ÐŽÐµÑÑÐµÑÐžÐœ ÐºÐŸÐ»ÐŽÐŸÐœÑÐ¿ ÑÑÑÐŸÐŸÐœÑÐœ ÑÐŸÒ£ÐŸÐ¹ÑÑÐ»Ð³Ð°Ðœ ÑÐŸÑÐŒÐ°ÑÑÐœÐ° Ó©ÑÓ© Ð°Ð»Ð°Ð»Ð°ÑÑÐ·. ÐÑÐ» ÑÐ°Ðº ÑÑÑÐŸÐŸÐ»ÐŸÑÐŽÑ ÐºÑÑÑÑ ÐŒÒ¯ÐŒÐºÒ¯ÐœÑÒ¯Ð»Ò¯Ð³Ò¯Ðœ Ð±ÐµÑÐµÑ. ÐÑÐ» ÐžÐ·ÐŽÓ©Ó© ÐœÐ°ÑÑÐ¹Ð¶Ð°Ð»Ð°ÑÑ ÐºÓ©ÑÑÓ©ÑÒ¯Ð»Ð³Ó©Ðœ  ÐºÐµÐ·ÐŽÐµ ÑÑÑÐŸÐŸ ÑÐ°ÑÑÑ
+ÑÐœ ÐºÓ©ÑÑÓ©ÑÒ¯Ò¯ÐœÒ¯ ÐžÑÐºÐµ ÐºÐŸÑÐŸ Ð°Ð»Ð°ÑÑÐ·. ÐÑÐ» Ó©Ð·Ð³Ó©ÑÑÒ¯Ð»Ð³Ó©Ðœ ÑÑÑÐŸÐŸ ÑÒ¯ÑÒ¯Ðœ Ð¶Ð°ÑÐŸÐŸÐ³ÐŸ ÐŒÒ¯ÐŒÐºÒ¯ÐœÐŽÒ¯Ðº Ð±ÐµÑÐµÑ. Ð¡ÐžÐ· Ð±ÐžÑ Ð±ÐµÑÑÐµÐ³Ðž ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐžÐœ Ð¶Ð°Ð»Ð¿Ñ ÑÐ°ÐœÑ ÐŒÐµÐœÐµÐœ ÐžÐ·ÐŽÓ©Ó© ÐœÐ°ÑÑÐ¹Ð¶Ð°ÑÑÐœÑÐœ Ð¶Ð°Ð»Ð¿Ñ ÑÐ°ÐœÑÐœ ÐžÑÐµÑÑÐµÐ¹ Ð°Ð»Ð°ÑÑÐ·. 
+}
+
+_texttanumbrowseoptions_ [l=ky] {ÐÑÐ» ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŽÐ° ÐžÐ·ÐŽÓ©Ó©Ð»Ó©ÑÐŽÒ¯Ðœ Ð°Ñ ÑÒ¯ÑÐŽÒ¯Ò¯ Ð¶ÐŸÐ»ÐŽÐŸÑÑ Ð±Ð°Ñ (_numbrowseoptions_):}
+
+_textsimplehelpheading_ [l=ky] {ÐÐœÑÐŸÑÐŒÐ°ÑÐžÑÐœÑ ÐºÐ°ÐœÐŽÐ°Ð¹ ÐžÐ·ÐŽÓ©Ó© ÐºÐµÑÐµÐº}
+
+_texthelpscopetitle_ [l=ky] {ÐÐ·ÐŽÓ©Ó© ÐŽÐžÐ°Ð¿Ð°Ð·ÐŸÐœÑ }
+_texthelpscope_ [l=ky] {
+<p>ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐ»Ð°ÑÐŽÑÐœ ÐºÓ©Ð¿ÑÒ¯Ð»Ò¯Ð³Ò¯ÐœÐŽÓ© ÑÐžÐ· Ð°Ñ ÑÒ¯ÑÐŽÒ¯Ò¯ ÐžÐ·ÐŽÓ©Ó© ÐžÐœÐŽÐµÐºÑÑÐµÑÐžÐœ ÐºÐŸÐ»ÐŽÐŸÐœÐŸ Ð°Ð»Ð°ÑÑÐ·. ÐÐžÑÐ°Ð»Ñ, ÐºÐžÑÐµÐ¿ Ð°ÑÐ°Ð»ÑÑÑ, Ð°Ð²ÑÐŸÑÐ»ÐŸÑ ÑÐ°ÐŒÐžÐ»ÐžÑÐ»Ð°ÑÑ ÐžÐœÐŽÐµÐºÑÑÐµÑÐž. ÐÐ» ÑÑÑÑÐ°Ð»ÑÑ Ð¶Ðµ Ð¿Ð°ÑÐ°Ð³ÑÐ°Ñ ÐžÐœÐŽÐµÐºÑÑÐµÑÐž ÐŽÐ° Ð±ÐŸÐ»ÑÑÑ ÐŒÒ¯ÐŒÐºÒ¯Ðœ. Ð­Ð³ÐµÑ ÑÐžÐ· ÐºÐµÑÐµÐºÑÒ¯Ò¯ ÐžÐœÐŽÐµÐºÑÑÐž ÐºÓ©ÑÑÓ©ÑÐ¿Ó©ÑÓ©Ò£Ò¯Ð· Ð°ÐœÐŽÐ° ÑÐºÑÐ°ÐœÐ³Ð° ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐµÑÐŽÐžÐœ Ð±Ð°Ð°ÑÐŽÑÐ³Ñ ÑÑÐ³Ð°ÑÑÐ»Ð°Ñ. Ð­Ð³ÐµÑ ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð±ÐžÑ ÐºÐžÑÐµÐ¿ Ð±ÐŸÐ»ÑÐŸ Ð°ÐœÐŽÐ° Ð°Ð» ÐŸÑÐŸÐ» ÐŸÑÑÐœÐŽÐ°Ðœ Ð°ÑÑÐ»Ð°Ñ.     }
Index: /gsdl/stable/macros/languages.dm
===================================================================
--- /gsdl/stable/macros/languages.dm	(revision 20131)
+++ /gsdl/stable/macros/languages.dm	(revision 20131)
@@ -0,0 +1,163 @@
+package iso639
+
+_iso639aa_ {Afar}
+_iso639ab_ {Abkhazian}
+_iso639af_ {Afrikaans}
+_iso639am_ {Amharic}
+_iso639ar_ {Arabic}
+_iso639as_ {Assamese}
+_iso639ay_ {Aymara}
+_iso639az_ {Azerbaijani}
+  
+_iso639ba_ {Bashkir}
+_iso639be_ {Byelorussian}
+_iso639bg_ {Bulgarian}
+_iso639bh_ {Bihari}
+_iso639bi_ {Bislama}
+_iso639bn_ {Bengali; Bangla}
+_iso639bo_ {Tibetan}
+_iso639br_ {Breton}
+  
+_iso639ca_ {Catalan}
+_iso639co_ {Corsican}
+_iso639cs_ {Czech}
+_iso639cy_ {Welsh}
+  
+_iso639da_ {Danish}
+_iso639de_ {German}
+_iso639dz_ {Bhutani}
+  
+_iso639el_ {Greek}
+_iso639en_ {English}
+_iso639eo_ {Esperanto}
+_iso639es_ {Spanish}
+_iso639et_ {Estonian}
+_iso639eu_ {Basque}
+  
+_iso639fa_ {Persian}
+_iso639fi_ {Finnish}
+_iso639fj_ {Fiji}
+_iso639fo_ {Faroese}
+_iso639fr_ {French}
+_iso639fy_ {Frisian}
+  
+_iso639ga_ {Irish}
+_iso639gd_ {Scots Gaelic}
+_iso639gl_ {Galician}
+_iso639gn_ {Guarani}
+_iso639gu_ {Gujarati}
+  
+_iso639ha_ {Hausa}
+_iso639hi_ {Hindi}
+_iso639hr_ {Croatian}
+_iso639hu_ {Hungarian}
+_iso639hy_ {Armenian}
+  
+_iso639ia_ {Interlingua}
+_iso639ie_ {Interlingue}
+_iso639ik_ {Inupiak}
+_iso639in_ {Indonesian}
+_iso639is_ {Icelandic}
+_iso639it_ {Italian}
+_iso639iw_ {Hebrew}
+  
+_iso639ja_ {Japanese}
+_iso639ji_ {Yiddish}
+_iso639jw_ {Javanese}
+  
+_iso639ka_ {Georgian}
+_iso639kk_ {Kazakh}
+_iso639kl_ {Greenlandic}
+_iso639km_ {Cambodian}
+_iso639kn_ {Kannada}
+_iso639ko_ {Korean}
+_iso639ks_ {Kashmiri}
+_iso639ku_ {Kurdish}
+_iso639ky_ {Kirghiz}
+  
+_iso639la_ {Latin}
+_iso639ln_ {Lingala}
+_iso639lo_ {Laothian}
+_iso639lt_ {Lithuanian}
+_iso639lv_ {Latvian, Lettish}
+  
+_iso639mg_ {Malagasy}
+_iso639mi_ {Maori}
+_iso639mk_ {Macedonian}
+_iso639ml_ {Malayalam}
+_iso639mn_ {Mongolian}
+_iso639mo_ {Moldavian}
+_iso639mr_ {Marathi}
+_iso639ms_ {Malay}
+_iso639mt_ {Maltese}
+_iso639my_ {Burmese}
+  
+_iso639na_ {Nauru}
+_iso639ne_ {Nepali}
+_iso639nl_ {Dutch}
+_iso639no_ {Norwegian}
+  
+_iso639oc_ {Occitan}
+_iso639om_ {(Afan) Oromo}
+_iso639or_ {Oriya}
+  
+_iso639pa_ {Punjabi}
+_iso639pl_ {Polish}
+_iso639ps_ {Pashto, Pushto}
+_iso639prs_ {Dari}
+_iso639pt_ {Portuguese}
+  
+_iso639qu_ {Quechua}
+_iso639rm_ {Rhaeto-Romance}
+_iso639rn_ {Kirundi}
+_iso639ro_ {Romanian}
+_iso639ru_ {Russian}
+_iso639rw_ {Kinyarwanda}
+  
+_iso639sa_ {Sanskrit}
+_iso639sd_ {Sindhi}
+_iso639sg_ {Sangro}
+_iso639sh_ {Serbo-Croatian}
+_iso639si_ {Singhalese}
+_iso639sk_ {Slovak}
+_iso639sl_ {Slovenian}
+_iso639sm_ {Samoan}
+_iso639sn_ {Shona}
+_iso639so_ {Somali}
+_iso639sq_ {Albanian}
+_iso639sr_ {Serbian}
+_iso639ss_ {Siswati}
+_iso639st_ {Sesotho}
+_iso639su_ {Sudanese}
+_iso639sv_ {Swedish}
+_iso639sw_ {Swahili}
+  
+_iso639ta_ {Tamil}
+_iso639te_ {Tegulu}
+_iso639tg_ {Tajik}
+_iso639th_ {Thai}
+_iso639ti_ {Tigrinya}
+_iso639tk_ {Turkmen}
+_iso639tl_ {Tagalog}
+_iso639tn_ {Setswana}
+_iso639to_ {Tonga}
+_iso639tr_ {Turkish}
+_iso639ts_ {Tsonga}
+_iso639tt_ {Tatar}
+_iso639tw_ {Twi}
+  
+_iso639uk_ {Ukrainian}
+_iso639ur_ {Urdu}
+_iso639uz_ {Uzbek}
+  
+_iso639vi_ {Vietnamese}
+_iso639vo_ {Volapuk}
+  
+_iso639wo_ {Wolof}
+  
+_iso639xh_ {Xhosa}
+  
+_iso639yo_ {Yoruba}
+  
+_iso639zh_ {Chinese}
+_iso639zu_ {Zulu}
Index: /gsdl/stable/macros/latvian.dm
===================================================================
--- /gsdl/stable/macros/latvian.dm	(revision 20131)
+++ /gsdl/stable/macros/latvian.dm	(revision 20131)
@@ -0,0 +1,882 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Latvian Language text and icon macros 
+# Many thanks to Raitis Brodezhonok (updated April 2005)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=lv] {Periodika}
+_textsource_ [l=lv] {avota norÄde:}
+_textdate_ [l=lv] {publicÄÅ¡anas datums:}
+_textnumpages_ [l=lv] {lapu skaits:}
+
+_textsignin_ [l=lv] {autorizÄcija}
+
+_textdefaultcontent_ [l=lv] {PieprasÄ«tÄ lapa nav atrasta. LÅ«dzu izmantojiet
+jÅ«su pÄrlÅ«kprogrammas 'atpakaÄŒ' pogu vai augÅ¡Äjo 'mÄja' pogu, lai
+atgrieztos uz Greenstone DigitÄlo BibliotÄku.}
+
+_textdefaulttitle_ [l=lv] {GSDL KÄŒÅ«da}
+
+_textbadcollection_ [l=lv] {Kolekcija (nosaukta "_cvariable_") nav uzstÄdÄ«ta Å¡ajÄ Greenstone digitÄlÄs bibliotÄkas sistÄmÄ.}
+
+_textselectpage_ [l=lv] {-- IzvÄlieties Lapu --}
+
+_collectionextra_ [l=lv] {Kolekcija satur _about:numdocs_ dokumentus. 
+TÄ pÄdÄjo reizi tika veidota _about:builddate_ dienas atpakaÄŒ.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=lv] {<p>Kolekcija satur _numdocs_ _If_("_numdocs_" eq "1",dokumentu,dokumentus), summÄri _numbytes_.
+<p><a href="_httppagex_(bsummary)">NoklikÅ¡Ä·iniet Å¡eit</a> lai redzÄtu Å¡Ä«s kolekcijas veidoÅ¡anas kopsavilkumu.
+}
+
+_textdescrcollection_ [l=lv] {}
+_textdescrabout_ [l=lv] {Par lapa}
+_textdescrhome_ [l=lv] {MÄjas lapa}
+_textdescrhelp_ [l=lv] {PalÄ«gs lapa}
+_textdescrpref_ [l=lv] {IestatÄ«jumu lapa}
+_textdescrgreenstone_ [l=lv] {Greenstone DigitÄlÄs BibliotÄkas ProgrammatÅ«ra}
+_textdescrusab_ [l=lv] {Ko jÅ«s atradÄt grÅ«ti izmantojamu?}
+
+_textdescrSearch_ [l=lv] {MeklÄt specifiskus nosacÄ«jumus}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=lv] {PÄrlÅ«kot virsrakstu alfabÄtisku sarakstu}
+_textdescrCreator_ [l=lv] {PÄrlÅ«kot autoru alfabÄtisko sarakstu}
+_textdescrSubject_ [l=lv] {PÄrlÅ«kot pÄc priekÅ¡metu kategorijas}
+_textdescrDescription_ [l=lv] {PÄrlÅ«kot pÄc aprakstiem}
+_textdescrPublisher_ [l=lv] {PÄrlÅ«kot pÄc izdevÄjiem}
+_textdescrContributor_ [l=lv] {PÄrlÅ«kot pÄc lÄ«dzautoriem}
+_textdescrDate_ [l=lv] {PÄrlÅ«kot pÄc datÄjuma}
+_textdescrType_ [l=lv] {PÄrlÅ«kot pÄc resursu tipiem}
+_textdescrFormat_ [l=lv] {PÄrlÅ«kot pÄc formÄta}
+_textdescrIdentifier_ [l=lv] {PÄrlÅ«kot pÄc resursa identifikatora}
+_textdescrSource_ [l=lv] {PÄrlÅ«kot pÄc originÄlÄ datnesvÄrda}
+_textdescrLanguage_ [l=lv] {PÄrlÅ«kot pÄc valodas}
+_textdescrRelation_ [l=lv] {PÄrlÅ«kot pÄc saistÄ«bÄm}
+_textdescrCoverage_ [l=lv] {PÄrlÅ«kot pÄc aptvÄruma}
+_textdescrRights_ [l=lv] {PÄrlÅ«kot pÄc tiesÄ«bÄm}
+
+_textdescrOrganization_ [l=lv] {PÄrÅ«kot pÄc organizÄcijÄm}
+_textdescrKeyword_ [l=lv] {PÄrlÅ«kot pÄc atslÄgvÄrda}
+_textdescrHowto_ [l=lv] {PÄrlÅ«kot kÄdÄ veidÄ kategorijas}
+_textdescrList_ [l=lv] {PÄrlÅ«kot dokumentu sarakstu}
+_textdescrSeries_ [l=lv] {PÄrlÅ«kot pÄc izdevumiem}
+_textdescrTo_ [l=lv] {PÄrlÅ«kot pÄc Kam lauka}
+_textdescrFrom_ [l=lv] {PÄrlÅ«kot pÄc No lauka}
+_textdescrTopic_ [l=lv] {PÄrlÅ«kot speciÄlus tematikskus izdevumus}
+_textdescrBrowse_ [l=lv] {PÄrlÅ«kot}
+_textdescrCollage_ [l=lv] {PÄrlÅ«kot pÄc attÄlu kolÄÅŸÄm}
+_textdescrPeople_ [l=lv] {PÄrlÅ«kot cilvÄku alfabÄtisko sarakstu}
+_textdescrAcronym_ [l=lv] {PÄrlÅ«kot akronÄ«mus}
+_textdescrPhrase_ [l=lv] {PÄrlÅ«kot frÄzes}
+_textdescrArtist_ [l=lv] {PÄrlÅ«kot mÄksliniekus}
+_textdescrVolume_ [l=lv] {PÄrlÅ«kot pÄc sÄjuma}
+_textdescrCountries_ [l=lv] {PÄrlÅ«kot pÄc valstÄ«m}
+_textdescrCaptions_ [l=lv] {PÄrlÅ«kot pÄc foto virsrakstiem}
+
+_labelSearch_ [l=lv] {MeklÄt}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=lv] {Nosaukumi A-Z}
+_labelCreator_ [l=lv] {Autori A-Z}
+_labelSubject_ [l=lv] {PriekÅ¡meti}
+
+_labelDescription_ [l=lv] {Apraksti}
+_labelPublisher_ [l=lv] {IzdevÄji}
+_labelContributor_ [l=lv] {LÄ«dzautori}
+_labelDate_ [l=lv] {DatÄjums}
+_labelType_ [l=lv] {Tipi}
+_labelFormat_ [l=lv] {FormÄti}
+_labelIdentifier_ [l=lv] {Identifikatori}
+_labelSource_ [l=lv] {DatnesvÄrdi}
+_labelLanguage_ [l=lv] {Valodas}
+_labelRelation_ [l=lv] {SaistÄ«bas}
+_labelCoverage_ [l=lv] {AptvÄrums}
+_labelRights_ [l=lv] {TiesÄ«bas}
+
+_labelOrg_ [l=lv] {OrganizÄcija}
+_labelKeyword_ [l=lv] {AtslÄgvÄrds}
+_labelHow_ [l=lv] {KÄdÄ veidÄ}
+_labelSeries_ [l=lv] {Izdevumi}  
+_labelList_ [l=lv] {Saraksts}
+_labelTo_ [l=lv] {Kam}  
+_labelFrom_ [l=lv] {No}  
+_labelTopic_ [l=lv] {Temati}  
+_labelBrwse_ [l=lv] {PÄrlÅ«kot}  
+_labelCollage_ [l=lv] {KolÄÅŸa}  
+_labelbrows_ [l=lv] {PÄrlÅ«kot}  
+_labelPeople_ [l=lv] {CilvÄki A-Z}  
+_labelAcronym_ [l=lv] {AkronÄ«mi}
+_labelPhrase_ [l=lv] {FrÄzes}  
+_labelArtist_ [l=lv] {MÄkslinieki}  
+_labelVolume_ [l=lv] {SÄjumi}  
+_labelCaptions_ [l=lv] {Virsraksti}
+_labelCountries_ [l=lv] {Valstis}  
+
+
+_texticontext_ [l=lv] {SkatÄ«t dokumentu}
+_texticonclosedbook_ [l=lv] {atvÄrt Å¡o dokumentu un skatÄ«t saturu}
+_texticonnext_ [l=lv] {uz nÄkoÅ¡o nodaÄŒu}
+_texticonprev_ [l=lv] {uz iepriekÅ¡Äjo nodaÄŒu}
+
+_texticonworld_ [l=lv] {SkatÄ«t web dokumentu}
+
+_texticonmidi_ [l=lv] {SkatÄ«t MIDI dokumentu}
+_texticonmsword_ [l=lv] {SkatÄ«t Microsoft Word dokumentu}
+_texticonmp3_ [l=lv] {SkatÄ«t MP3 dokumentu}
+_texticonpdf_ [l=lv] {SkatÄ«t PDF dokumentu}  
+_texticonps_ [l=lv] {SkatÄ«t PostScript dokumentu}  
+_texticonppt_ [l=lv] {SkatÄ«t PowerPoint dokumentu}  
+_texticonrtf_ [l=lv] {SkatÄ«t RTF dokumentu}  
+_texticonxls_ [l=lv] {SkatÄ«t Microsoft Excel dokumentu}  
+
+_page_ [l=lv] {lapa}
+_pages_ [l=lv] {lapas}
+_of_ [l=lv] {no}
+_vol_ [l=lv] {SÄj.}
+_num_ [l=lv] {Nr.}
+
+_textmonth00_ [l=lv] {}
+_textmonth01_ [l=lv] {JanvÄris}
+_textmonth02_ [l=lv] {FebruÄris}
+_textmonth03_ [l=lv] {Marts}
+_textmonth04_ [l=lv] {AprÄ«lis}
+_textmonth05_ [l=lv] {Maijs}
+_textmonth06_ [l=lv] {JÅ«nijs}
+_textmonth07_ [l=lv] {JÅ«lijs}
+_textmonth08_ [l=lv] {Augusts}
+_textmonth09_ [l=lv] {Septembris}
+_textmonth10_ [l=lv] {Oktobris}
+_textmonth11_ [l=lv] {Novembris}
+_textmonth12_ [l=lv] {Decembris}
+
+_textdocument_ [l=lv] {Dokuments}
+_textsection_ [l=lv] {Sekcija}
+_textparagraph_ [l=lv] {ParagrÄfs}
+
+_magazines_ [l=lv] {ÅœurnÄli}
+
+_nzdlpagefooter_ [l=lv] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">JaunzÄlandes DigitÄlÄs BibliotÄkas Projekts</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">DatorzinÄtÅu FakultÄte</a>, 
+<a href="http://www.waikato.ac.nz">Waikato UniversitÄte</a>, 
+JaunzÄlande}  
+
+_linktextHOME_ [l=lv] {MÄJA}
+_linktextHELP_ [l=lv] {PALÄªGS}
+_linktextPREFERENCES_ [l=lv] {IESTATÄªJUMI}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=lv] {Greenstone DigitÄlÄ BibliotÄka}
+_textadmin_ [l=lv] {AdministrÄcijas Lapa}
+_textabgs_ [l=lv] {Par Greenstone}
+_textgsdocs_ [l=lv] {Greenstone DokumentÄcija}
+
+_textdescradmin_ [l=lv] {AtÄŒauj jums pievienot jaunus lietotÄjus, apkopo kolekcijas sistÄmÄ, dot
+tehnisko informÄciju uz Greenstone instalÄciju
+}
+
+_textdescrgogreenstone_ [l=lv] {StÄsta jums par Greenstone programmatÅ«ru un JaunzÄlandes DigitÄlÄs BibliotÄkas
+Projektu, no kurienes tas nÄk
+}
+
+_textdescrgodocs_ [l=lv] {Greenstone rokasgrÄmatas}
+
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=lv] {BibliotekÄra Interfeiss}
+_textdescrgli_ [l=lv] {PalÄ«dzÄs jums radÄ«t jaunas kolekcijas, modificÄt vai papildinÄt jau esoÅ¡Äs, vai izdzÄst 
+kolekcijas
+}
+
+package collector
+
+_textcollector_ [l=lv] {Kolektors}
+_textdescrcollector_ [l=lv] {Kolektors tika izveidots pirms bibliotekÄra interfeisa, un vispraktiskÄko apsvÄrumu dÄÄŒ, tiek rekomendÄts izmantot bibliotekÄra interfeisu}
+
+
+package depositor
+
+
+package gti
+
+_textgti_ [l=lv] {Greenstone TulkoÅ¡anas Interfeiss}  
+_textdescrtranslator_ [l=lv] {PalÄ«dz jums uzturÄt daudzvalodu Greenstone interfeisa versijas 
+aktuÄlas
+}
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=lv] {Par Å¡o kolekciju}
+
+_textsubcols1_ [l=lv] {<p>Pilna kolekcija satur _1_ apakÅ¡kolekcijas. 
+PaÅ¡reiz pieejamÄs ir:
+<blockquote>}
+
+_textsubcols2_ [l=lv] {</blockquote>
+JÅ«s varat kontrolÄt (un mainÄ«t) kuras apakÅ¡kolekcijas 
+jÅ«s paÅ¡laik izmantojiet IestatÄ«jumu lapÄ.}
+
+_titleabout_ [l=lv] {par}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+
+_texticonopenbookshelf_ [l=lv] {azvÄrt Å¡o bibliotÄkas sekciju}
+_texticonclosedbookshelf_ [l=lv] {atvÄrt Å¡o bibliotÄkas sekciju un apskatiet saturu}
+_texticonopenbook_ [l=lv] {aizvÄrt Å¡o grÄmatu}
+_texticonclosedfolder_ [l=lv] {AtvÄrt Å¡o mapi un apskatÄ«t saturu}
+_texticonclosedfolder2_ [l=lv] {atvÄrt apakÅ¡sekciju:}
+_texticonopenfolder_ [l=lv] {aizvÄrt Å¡o mapi}
+_texticonopenfolder2_ [l=lv] {aizvÄrt apakÅ¡sekciju:}
+_texticonsmalltext_ [l=lv] {SkatÄ«t Å¡o teksta sekciju}
+_texticonsmalltext2_ [l=lv] {skatÄ«t tekstu:}
+_texticonpointer_ [l=lv] {tekoÅ¡Ä sekcija}
+_texticondetach_ [l=lv] {AtvÄrt Å¡o lapu jaunÄ logÄ}
+_texticonhighlight_ [l=lv] {Izcelt meklÄÅ¡anas nosacÄ«jumus}
+_texticonnohighlight_ [l=lv] {Neizcelt meklÄÅ¡anas nosacÄ«jumus}
+_texticoncontracttoc_ [l=lv] {AizvÄrt satura tabulu}
+_texticonexpandtoc_ [l=lv] {AtvÄrt satura tabulu}
+_texticonexpandtext_ [l=lv] {ParÄdÄ«t visu tekstu}
+_texticoncontracttext_ [l=lv] {ParÄdÄ«t tekstu tikai paÅ¡laikt atlasÄ«tai sekcijai}
+_texticonwarning_ [l=lv] {<b>BrÄ«dinÄjums: </b>}
+_texticoncont_ [l=lv] {turpinÄt?}
+
+_textltwarning_ [l=lv] {<div class="buttons">_imagecont_</div>
+_iconwarning_IzvÄrÅ¡ot tekstu Å¡eit, izraisÄ«s liela apjoma
+datu Ä£enerÄÅ¡anu jÅ«su pÄrlÅ«kprogrammai
+}
+
+_textgoto_ [l=lv] {aiziet uz lapu}
+_textintro_ [l=lv] {<i>(ievada teksts)</i>}
+
+_textCONTINUE_ [l=lv] {TURPINÄT???}
+
+_textEXPANDTEXT_ [l=lv] {IZVÄRST\nTEKSTU}
+
+_textCONTRACTCONTENTS_ [l=lv] {SAÄªSINÄT\nSATURU}
+
+_textDETACH_ [l=lv] {ATDALÄªT}
+
+_textEXPANDCONTENTS_ [l=lv] {IZVÄRST\nSATURU}
+
+_textCONTRACT_ [l=lv] {SAÄªSINÄT\nTEKSTU}
+
+_textHIGHLIGHT_ [l=lv] {IZCELÅ ANA}
+
+_textNOHIGHLIGHT_ [l=lv] {NE\nIZCELÅ ANA}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=lv] {_If_(_thislast_,rezultÄti _thisfirst_ - _thislast_ priekÅ¡ pieprasÄ«juma: _cgiargq_,Nav rezultÄtu priekÅ¡ pieprasÄ«juma: _cgiargq_)}
+_textnoquerytitle_ [l=lv] {MeklÄÅ¡anas lapa}
+
+_textsome_ [l=lv] {daÅŸus}
+_textall_ [l=lv] {visus}
+_textboolean_ [l=lv] {loÄ£isks}
+_textranked_ [l=lv] {sarindots}
+_textnatural_ [l=lv] {dabisks}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=lv] {meklÄÅ¡anas vÄsture}
+
+_textifeellucky_ [l=lv] {Es jÅ«tos veiksmÄ«gs!}
+
+#alt text for query buttons
+_textusequery_ [l=lv] {izmantotjiet Å¡o pieprasÄ«jumu}
+_textfreqmsg1_ [l=lv] {VÄrdu skaits:}
+_textpostprocess_ [l=lv] {_If_(_quotedquery_,<br><i>apstrÄdÄti,lai meklÄtu  _quotedquery_</i>
+)}
+_textinvalidquery_ [l=lv] {Nepareiza pieprasÄ«juma sintakse}
+
+_textmorethan_ [l=lv] {VairÄk nekÄ}
+_textapprox_ [l=lv] {Par}
+_textnodocs_ [l=lv] {Nav dokumenta, kas atbilst pieprasÄ«jumam.}
+_text1doc_ [l=lv] {1 dukuments sakrÄ«t ar pieprasÄ«jumu.}
+_textlotsdocs_ [l=lv] {dokumenti atbilst pieprasÄ«jumam.}
+_textmatches_ [l=lv] {SakritÄ«bas}
+_textbeginsearch_ [l=lv] {SÄk MeklÄt}
+_textrunquery_ [l=lv] {PieprasÄ«jums IzpildÄs}  
+_textclearform_ [l=lv] {NotÄ«rÄ«t Formu}  
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=lv] {VÄrds vai frÄze}  
+_textinfield_ [l=lv] {... lauciÅÄ}  
+_textfoldstem_ [l=lv] {(locÄ«jums,celms)}  
+
+_textadvquery_ [l=lv] {Vai ievadiet pieprasÄ«jumu tieÅ¡i:}  
+_textallfields_ [l=lv] {visi lauki}  
+_texttextonly_ [l=lv] {tikai teksts}
+_textand_ [l=lv] {un}  
+_textor_ [l=lv] {vai}  
+_textandnot_ [l=lv] {un ne}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=lv] {MeklÄÅ¡ana pÄc _indexselection_ _If_(_jselection_,no _jselection_ )_If_(_gselection_, uz _gselection_ lÄ«meÅa )_If_(_nselection_, _nselection_ valodÄ ) kas satur _querytypeselection_ vÄrdus}  
+
+_textadvancedsearch_ [l=lv] {MeklÄt _indexselection_ _If_(_jselection_,no _jselection_ )_If_(_gselection_,uz _gselection_ lÄ«meÅa )_If_(_nselection_, _nselection_ valodÄ )izmantojot _querytypeselection_ pieprasÄ«jumu}
+
+_textformsimplesearch_ [l=lv] {MeklÄt _If_(_jselection_,_jselection_ )_If_(_gformselection_,uz _gformselection_ lÄ«meÅa )_If_(_nselection_, _nselection_ valodÄ )pÄc _formquerytypesimpleselection_ no}
+
+_textformadvancedsearch_ [l=lv] {MeklÄt _If_(_jselection_,_jselection_ )_If_(_gformselection_,uz _gformselection_ lÄ«meÅa )_If_(_nselection_, _nselection_ valodÄ )un rezultÄtus parÄdÄ«t _formquerytypeadvancedselection_ secÄ«bÄ}
+
+
+_textnojsformwarning_ [l=lv] {BrÄ«dinÄjums: JavaScripts ir aizliegts jÅ«su tÄ«mekÄŒa pÄrlÅ«kprogrammÄ. <br>Lai izmantotu formas meklÄÅ¡anu, lÅ«dzu atÄŒaujiet to.}
+_textdatesearch_ [l=lv] {SajÄ kolekcijÄ dokumenti var tikt meklÄti pÄc datumu diapazona, vai pÄc noteikta datuma.Å Ä« ir neobligÄta meklÄÅ¡anas iespÄja. }
+_textstartdate_ [l=lv] {Starta (vai tikai) datums:}
+_textenddate_ [l=lv] {Beigu datums:}
+_textbc_ [l=lv] {B.C.E.}
+_textad_ [l=lv] {C.E.}
+_textexplaineras_ [l=lv] {C.E. un B.C.E ir alternatÄ«vas A.D. un B.C. respektÄ«vi. Å ie termi nozÄ«mÄ C.E. = "MÅ«su Ära" un B.C.E.= "Pirms MÅ«su Äras".}  
+
+_textstemon_ [l=lv] {(ignorÄjot vÄrdu galotnes)}
+
+_textsearchhistory_ [l=lv] {MeklÄÅ¡anas VÄsture}
+
+#text macros for search history
+_textnohistory_ [l=lv] {MeklÄÅ¡anas vÄsture nav pieejama}
+_texthresult_ [l=lv] {iznÄkums}
+_texthresults_ [l=lv] {iznÄkumi}
+_texthallwords_ [l=lv] {visi vÄrdi}
+_texthsomewords_ [l=lv] {daÅŸi vÄrdi}
+_texthboolean_ [l=lv] {loÄ£iskais}
+_texthranked_ [l=lv] {sarindots}
+_texthcaseon_ [l=lv] {rÄgistram jÄsakrÄ«t}
+_texthcaseoff_ [l=lv] {neievÄrojot reÄ£istru}
+_texthstemon_ [l=lv] {ar galotnÄm}
+_texthstemoff_ [l=lv] {bez galotnÄm}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=lv] {IestatÄ«jumi tika uzstÄdÄ«ti sekojoÅ¡i. Nelietojiet jÅ«su pÄrlÅ«kprogrammas
+"atpakaÄŒ" pugu - tas nesaglabÄs iestatÄ«jumus! TÄ vietÄ, noklikÅ¡Ä·iniet
+jebkuru pogu no piekÄŒuves joslas augÅ¡pusÄ.
+}
+_textsetprefs_ [l=lv] {uzstÄdÄ«t iestatÄ«jumus}
+_textsearchprefs_ [l=lv] {MeklÄÅ¡anas iestatÄ«jumi}
+_textcollectionprefs_ [l=lv] {Kolekcijas iestatÄ«jumi}
+_textpresentationprefs_ [l=lv] {PrezentÄcijas iestatÄ«jumi}
+_textpreferences_ [l=lv] {IestatÄ«jumi}
+_textcasediffs_ [l=lv] {ReÄ£istru atÅ¡Ä·irÄ«bas:}
+_textignorecase_ [l=lv] {ignorÄt reÄ£istru atÅ¡Ä·irÄ«bas}
+_textmatchcase_ [l=lv] {lieliem/maziem burtiem jÄsakrÄ«t}
+_textwordends_ [l=lv] {VÄrdu galotnes:}  
+_textstem_ [l=lv] {ignorÄt vÄrdu galotnes}
+_textnostem_ [l=lv] {veseliem vÄrdiem jÄsakrÄ«t}
+_textprefop_ [l=lv] {Atgriezt lÄ«dz _maxdocoption_ trÄpÄ«jumiem _hitsperpageoption_ trÄpÄ«jumi uz lapas.}
+_textextlink_ [l=lv] {PiekÄŒuve ÄrÄjÄm TÄ«mekÄŒa lapÄm:}
+_textintlink_ [l=lv] {Avota dokumenti saÅemti no:}
+_textlanguage_ [l=lv] {Interfeisa valoda:}
+_textencoding_ [l=lv] {KodÄÅ¡ana:}
+_textformat_ [l=lv] {Interfeisa formÄts:}
+_textall_ [l=lv] {visi}
+_textquerymode_ [l=lv] {PieprasÄ«juma reÅŸÄ«ms:}  
+_textsimplemode_ [l=lv] {vienkÄrÅ¡s pieprasÄ«juma reÅŸÄ«ms}
+_textadvancedmode_ [l=lv] {paplaÅ¡inÄtais pieprasÄ«jumu reÅŸÄ«ms (ÄŒauj logisku meklÄÅ¡anu izmantojot !, &, |, un iekavas)}
+_textlinkinterm_ [l=lv] {caur starpnieklapu}
+_textlinkdirect_ [l=lv] {doties tieÅ¡i tur}
+_textdigitlib_ [l=lv] {digitÄlÄ bibliotÄka}
+_textweb_ [l=lv] {tÄ«meklis}
+_textgraphical_ [l=lv] {Grafiskais}
+_texttextual_ [l=lv] {TekstuÄls}
+_textcollectionoption_ [l=lv] {<p>
+IekÄŒaujamas apakÅ¡kolekcijas:
+<br>}
+
+_textrelateddocdisplay_ [l=lv] {parÄdÄ«t abilstoÅ¡os dokumentus}
+_textsearchhistory_ [l=lv] {MeklÄÅ¡anas vÄsture:}  
+_textnohistory_ [l=lv] {Nav meklÄÅ¡anas vÄstures}  
+_texthistorydisplay_ [l=lv] {parÄdÄ«t _historynumrecords_ meklÄÅ¡anas vÄstures ierakstus}
+_textnohistorydisplay_ [l=lv] {nerÄdÄ«t meklÄÅ¡anas vÄsturi}  
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=lv] {Formas meklÄÅ¡ana:}
+_textplainsearch_ [l=lv] {Parasta meklÄÅ¡ana:}
+_textqueryboxsize_ [l=lv] {PieprasÄ«juma lauciÅa izmÄrs:}
+_textregbox_ [l=lv] {regulÄrs pieprasÄ«juma lodziÅÅ¡}  
+_textbigbox_ [l=lv] {lielais pieprasÄ«juma lodziÅÅ¡}  
+_textformtype_ [l=lv] {Formas tips:}
+_textsimple_ [l=lv] {vinkÄrÅ¡s}  
+_textadvanced_ [l=lv] {paplaÅ¡inÄtais}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=lv] {ar}  
+_textfields_ [l=lv] {lauki}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=lv] {Å Ä·irot dokumentus pÄc}
+_textalsoshowing_ [l=lv] {arÄ« parÄdot}
+_textwith_ [l=lv] {ar lielÄko }
+_textdocsperpage_ [l=lv] {dokumenti uz lapu}
+
+_textfilterby_ [l=lv] {SaÅemt dokumentus saturoÅ¡i}
+_textall_ [l=lv] {viss}
+_textany_ [l=lv] {ikviens}
+_textwords_ [l=lv] {no vÄrdiem}
+_textleaveblank_ [l=lv] {atstÄt Å¡o aili tukÅ¡u, lai saÅemtu visus dokumentus}  
+
+_browsebuttontext_ [l=lv] {"Å Ä·irot Dokumentus"}
+
+_nodata_ [l=lv] {<i>nav datu</i>}
+_docs_ [l=lv] {dokumenti}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=lv] {PalÄ«gs}
+_textSearchshort_ [l=lv] {meklÄt atseviÅ¡Ä·us vÄrdus}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc nosaukuma}
+_textCreatorshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc autoriem}
+_textSubjectshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc priekÅ¡meta (tÄmas)}
+_textDescriptionshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc aprakstiem}
+_textPublishershort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc izdevÄjiem}
+_textContributorshort_ [l=lv] {piekÄŒuve publikÄcijÄm pÄc lÄ«dzautoriem}
+_textDateshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc datuma}
+_textTypeshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc tipiem}
+_textFormatshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc formÄta}
+_textIdentifiershort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc indentifikatora}
+_textSourceshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc datnesvÄrda}
+_textLanguageshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc valodas}
+_textRelationshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc saistÄ«bas}
+_textCoverageshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc aptvÄruma}
+_textRightsshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc tiesÄ«bÄm}
+
+_textSeriesshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc izdevumiem}
+_textToshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc Kam lauka}
+_textFromshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc No lauka}
+_textBrowseshort_ [l=lv] {pÄrlÅ«kot publikÄcijas}
+_textOrganizationshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc organizÄcijas}
+_textHowtoshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc "kÄdÄ veidÄ" saraksta}
+_textTopicshort_ [l=lv] {piekÄŒÅ«t publiÄcijÄm pÄc temata}
+_textPeopleshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc cilvÄkiem}
+_textAcronymshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc akronÄ«mu sastopamÄ«bas}
+_textPhraseshort_ [l=lv] {pÄrlÅ«kot frÄzes sastopamas publikÄcijÄs}
+_textArtistshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc mÄksliniekiem}
+_textKeywordshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc atslÄgvÄrda}
+_textVolumeshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc sÄjuma}
+_textCountriesshort_ [l=lv] {piekÄŒÅ«t publikÄcijÄm pÄc valstÄ«m}
+_textdefaultshorttext_ [l=lv] {nenoteikta klasifikÄcija}
+
+_textSearchlong_ [l=lv] {<p>JÅ«s varat <i>meklÄt atseviÅ¡Ä·us vÄrdus</i> ,kuri
+ sastopami tekstÄ, no "meklÄt" lapas. Å Ä« ir pirmÄ lapa, kas
+pÄrÄdÄs kad jÅ«s sÄkat, un var bÅ«t pieejama no citÄm lapÄm 
+nospieÅŸot <i>meklÄt</i> pogu.  }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc nosaukuma</i> 
+nospieÅŸot <i>nosaukumi a-z</i> pogu.  Tas parÄdÄ«s grÄmatu sarakstu
+pÄc nosaukumiem alfabÄtiskÄ secÄ«bÄ.  }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijas pÄc autoriem</i>
+nospieÅŸot <i>autori a-z</i> pogu.  Tas parÄdÄ«s grÄmatu sarakstu,
+kas atlasÄ«ta pÄc autoru vÄrdiem.  }
+
+_textSubjectlong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc priekÅ¡meta (tÄmas)</i> 
+nospieÅŸot <i>priekÅ¡meti</i> pogu.  Tas parÄdÄ«s priekÅ¡metu (tÄmu) sarakstu,
+kas pieejami grÄmatu plauktos.  }
+
+_textDescriptionlong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc to aprakstiem</i> 
+nospieÅŸot <i>apraksti</i> pogu. Tas parÄdÄ«s aprakstu sarakstu, ko 
+aplÅ«kot.}
+
+_textPublisherlong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc to izdevÄjiem</i>
+nospieÅŸot <i>izdevÄji</i> pogu. Tas parÄdÄ«s izdevÄju sarakstu.}
+
+_textContributorlong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc lÄ«dzautoriem</i> nospieÅŸot
+<i>lÄ«dzautori</i> pogu. Tas parÄdÄ«s lÄ«dzautoru sarakstu.}
+
+_textDatelong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc datuma</i> nospieÅŸot
+<i>datÄjums</i> pogu.  Tas parÄdÄ«s visu izdevumu sarakstu, kas atlasÄ«ti
+hronoloÄ£iski.  }
+
+_textTypelong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc resursu tipiem</i>
+nospieÅŸot <i>tipi</i> pogu. Tas parÄdÄ«s tipu sarakstu.}
+
+_textFormatlong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc formÄta</i>
+nospieÅŸot <i>formÄti</i> pogu. Tas parÄdÄ«s formÄtu sarakstu.}
+
+_textIdentifierlong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc identifikatora</i>
+nospieÅŸot <i>identifikatori</i> pogu. Tas parÄdÄ«s identifikatoru sarakstu.}
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc datnesvÄrda</i> 
+nospieÅŸot <i>datnesvÄrdi</i> pogu.  Tas parÄdÄ«s ierakstu sarakstu,
+kas atlasÄ«ts pÄc oriÄ£inÄliem datnesvÄrdiem.  }
+
+_textLanguagelong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc valodas</i> 
+nospieÅŸot <i>valodas</i> pogu.  Tas parÄdÄ«s ierakstu sarakstu,
+kas atlasÄ«ts pÄc valodÄm.  }
+
+_textRelationlong_ [l=lv] {<p> JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc saistÄ«bas (norÄde uz saistÄ«to resursu)</i>
+nospieÅŸot <i>saistÄ«bas</i> pogu. Tas parÄdÄ«s saistÄ«to resursu sarakstu.}
+
+_textCoveragelong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc aptvÄruma</i> 
+nospieÅŸot <i>aptvÄrums</i> pogu.}
+
+_textRightslong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc tiesÄ«bÄm</i>
+nospieÅŸot <i>tiesÄ«bas</i> pogu.}
+
+
+
+_textOrganizationlong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc
+organizÄcijas</i> nospieÅŸot <i>organizÄcijas</i> pogu.  Tas parÄdÄ«s
+sarakstu pÄc organizÄcijÄm.  }
+
+_textHowtolong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc "kÄdÄ veidÄ" saraksta</i>
+nospieÅŸot <i>kÄdÄ veidÄ</i> pogu.  Tas parÄdÄ«s rindu "kÄdÄ veidÄ"
+sarakstu.  }
+
+_textTopiclong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publiÄcijÄm pÄc temata</i>
+nospieÅŸot <i>temats</i> pogu.  Tas parÄdÄ«s tematu sarakstu
+pÄrlÅ«koÅ¡anai.  }
+
+_textTolong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc Kam lauka</i> 
+nospieÅŸot <i>Kam</i> pogu.  Tas parÄdÄ«s adreÅ¡u sarakstu.  }
+
+_textFromlong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc No lauka</i>
+nospieÅŸot <i>no</i> pogu.  Tas parÄdÄ«s sÅ«tÄ«tÄju sarakstu.  }
+
+_textSerieslong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc izdevumiem</i> 
+nospieÅŸot <i>izdevumi</i> pogu.  Tas parÄdÄ«s to izdevumu sarakstu,
+kuri ir dotajÄ kolekcijÄ.  }
+
+_textBrowselong_ [l=lv] {<p>JÅ«s varat <i>pÄrlÅ«kot publikÄcijas</i> nospieÅŸot
+<i>pÄrlÅ«kot</i> pogu.  }
+
+_textPeoplelong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc cilvÄkiem</i> 
+nospieÅŸot <i>cilvÄki a-z</i> pogu.  Tas parÄdÄ«s ierakstu sarakstu,
+kas atlasÄ«ts pÄc uzvÄrdiem.  }
+
+_textAcronymlong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc akronÄ«mu sastopamÄ«bas</i> 
+nospieÅŸot <i>akronÄ«mi</i> pogu.  Tas parÄdÄ«s akronÄ«mu sarakstu
+un vietas, kur tie sastopami.  }
+
+_textPhraselong_ [l=lv] {<p>JÅ«s varat <i>pÄrlÅ«kot frÄzes sastopamas publikÄcijÄs</i> 
+nospieÅŸot <i>frÄzes</i> pogu.  Tas izmanto phind frÄÅŸu pÄrlÅ«kprogrÄmmu.  }
+
+_textArtistlong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc mÄksliniekiem</i> 
+nospieÅŸot <i>mÄkslinieki</i> pogu.  Tas parÄdÄ«s ierakstu sarakstu,
+kuri atlasÄ«ti pÄc mÄkslinieku vÄrdiem.  }
+
+_textKeywordlong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc atslÄgvÄrda</i> 
+nospieÅŸot <i>atslÄgvÄrdi</i> pogu.  Tas parÄdÄ«s atslÄgvÄrdu sarakstu. }
+
+_textVolumelong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc sÄjuma</i>
+nospieÅŸot <i>sÄjumi</i> pogu. Tas parÄdÄ«s sÄjumu sarakstu. }
+
+_textCaptionslong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc virsrakstiem</i>
+nospieÅŸot <i>virsraksti</i> pogu. Tas parÄdÄ«s virsrakstu sarakstu. }
+
+_textCountrieslong_ [l=lv] {<p>JÅ«s varat <i>piekÄŒÅ«t publikÄcijÄm pÄc valstÄ«m</i>
+nospieÅŸot <i>valstis</i> pogu. Tas parÄdÄ«s valstu sarakstu. }
+
+
+_textdefaultlongtext_ [l=lv] {<p>NoklikÅ¡Ä·inÄt uz <i>nezinÄms</i> pogu, lai pÄrlÅ«kotu 
+publikÄcijas (saraksts ir atlasÄ«ts pÄc nezinÄms lauka).  }
+
+
+_texthelptopicstitle_ [l=lv] {TÄmas}
+
+_textreadingdocs_ [l=lv] {KÄ lasÄ«t dokumentus}
+
+_texthelpreadingdocs_ [l=lv] {<p>JÅ«s varat pateikt, kad jÅ«s esat nonÄcis uz individuÄlu grÄmatu vai
+dokumentu, pÄc tÄ, ka tÄ virsraksts, vai priekÅ¡vÄka fotogrÄfija, parÄdÄs
+lapas augÅ¡pusÄ pa kreisi. DaÅŸÄs kolekcijÄs tas tiek pavadÄ«ts ar satura 
+tabulu, kamÄr citi satur tikai tekoÅ¡as lappuses numuru un lodziÅu, kas
+ÄŒauj jums izvÄlÄties jaunu lapu un iet uz priekÅ¡u vai atpakaÄŒ.
+Satura tabulÄ tekoÅ¡as sekcijas virsraksts ir treknrakstÄ un pati tabula
+ir paplaÅ¡inÄma â nokliÅ¡Ä·iniet uz mapi, lai to atvÄrtu vai aizvÄrtu;
+noklikÅ¡Ä·iniet uz atvÄrtu grÄmatu augÅ¡pusÄ, lai to aizvÄrtu.</p>
+
+<p>ApakÅ¡daÄŒÄ ir tekoÅ¡Äs sekcijas teksts. Kad jÅ«s to esat izlasÄ«jis,
+jÅ«s varat pÄriet uz nÄkoÅ¡o sekciju vai iepriekÅ¡Äjo, izmantojot apakÅ¡ÄjÄ
+daÄŒÄ esoÅ¡as bultiÅas.</p>
+
+<p>Zem virsraksta vai priekÅ¡vÄka fotogrÄfijas ir daÅŸas pogas. NoklikÅ¡Ä·iniet
+uz <i>izvÄrst tekstu</i> , lai izvÄrstu visu tekoÅ¡Äs sekcijas vai grÄmatas tekstu.
+Ja dokuments ir liels, tas var aizÅemt daudz laika un patÄrÄs daudz atmiÅas!
+NoklikÅ¡Ä·iniet uz <i>izvÄrst saturu</i> , lai izvÄrstu visu satura tabulu, tÄdÄ veidÄ
+jÅ«s varat redzÄt visu nodaÄŒu un apakÅ¡sekciju virsrakstus. NoklikÅ¡Ä·iniet uz
+<i>atdalÄ«t</i> , lai atvÄrtu Å¡o dokumentu jaunajÄ pÄrlÅ«kprogrammas logÄ.
+(Tas ir Ärti, ja jÅ«s vÄlÄties salÄ«dizinÄt dokumentus, vai lasÄ«t divus vienlaicÄ«gi.)
+Beidzot, kad jÅ«s veicat meklÄÅ¡anu, vÄrdi , kurus meklÄjat, tiek izcelti (izgaismoti).
+NoklikÅ¡Ä·iniet uz <i>ne izcelÅ¡ana</i> , lai atrastie vÄrdi netiktu izcelti (izgaismoti).</p>
+}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=lv] {AtvÄrt Å¡o  grÄmatplauktu}
+_texthelpopenbook_ [l=lv] {AtvÄrt/AizvÄrt Å¡o grÄmatu}
+_texthelpviewtextsection_ [l=lv] {SkatÄ«t Å¡o teksta sekciju}
+_texthelpexpandtext_ [l=lv] {ParÄdÄ«t visu tekstu, vai ne}
+_texthelpexpandcontents_ [l=lv] {IzvÄrst satura tabulu, vai ne}
+_texthelpdetachpage_ [l=lv] {AtvÄrt Å¡o lapu jaunÄ logÄ }
+_texthelphighlight_ [l=lv] {Izcelt meklÄÅ¡anas nosacÄ«jumus, vai ne}
+_texthelpsectionarrows_ [l=lv] {Doties uz iepriekÅ¡Äjo/nÄkamo sekciju}  
+
+
+_texthelpsearchingtitle_ [l=lv] {KÄ meklÄt atseviÅ¡Ä·us vÄrdus}
+
+_texthelpsearching_ [l=lv] {<p>
+  No meklÄÅ¡anas lapas veiciet pieprasÄ«jumu sekojoÅ¡Ä secÄ«bÄ:<p>
+  
+  <ol><li>NorÄdiet, kÄdas izvÄlnes jÅ«s gribÄt meklÄt
+      <li>NorÄdiet, vai jÅ«s gribat meklÄt visus vÄrdus, vai atseviÅ¡Ä·us vÄrdus
+      <li>Ievadiet vÄrdus, kurus jÅ«s gribat meklÄt
+      <li>NoklikÅ¡Ä·iniet <i>SÄkt MeklÄt</i> pogu
+  </ol>
+
+<p>Kad jÅ«s veicat pieprasÄ«jumu, divdesmit atrastie dokumenti tiks parÄdÄ«ti.
+Izmantojiet navigÄcijas pogas, lai apskatÄ«tu nÄkoÅ¡os divdesmit dokumentus (ja tÄdi ir),
+vai, lai atgriestos uz iepriekÅ¡Äjiem atrastiem divdesmit dokumentiem, un tÄ tÄlÄk.
+NoklikÅ¡Ä·iniet uz jebkura dokumenta virsraksta, vai virsraksta pogas blakus tam, 
+lai to aplÅ«kotu.
+
+<p>Dokumentu skaits, kuri tiek atgriezti meklÄÅ¡anas rezultÄtÄ ir iepriekÅ¡ noteikts.
+JÅ«s varat izmainÄ«t Å¡o skaitu noklikÅ¡Ä·inot <i>iestatÄ«jumi</i> 
+pogu lapas augÅ¡daÄŒÄ.<p>
+}
+
+_texthelpquerytermstitle_ [l=lv] {MeklÄÅ¡anas nosacÄ«jumi<}
+_texthelpqueryterms_ [l=lv] {<p>Viss, kas tiek ievadÄ«ts pieprasÄ«juma lodziÅÄ, tiek interpretÄts kÄ vÄrdu
+saraksts un tiek saukts par âmeklÄÅ¡anas nosacÄ«jumiemâ. Katrs nosacÄ«jums
+satur neko citu, kÄ alfabÄtisku vai ciparu rakstuzÄ«mi. NosacÄ«jumi atdalÄs ar 
+atstarpÄm. Jebkura cita rakstuzÄ«me, tÄda kÄ punktuÄcijas, tiek ignorÄta.
+JÅ«s nevarat meklÄt vÄrdus, kuri satur punktuÄcijas zÄ«mes.
+
+<p>PiemÄram, pieprasÄ«jums<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>tiks apstrÄdÄtas tÄdÄ paÅ¡Ä veidÄ, kÄ<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}
+
+_texthelpquerytypetitle_ [l=lv] {PieprasÄ«juma tipi}
+_texthelpquerytype_ [l=lv] {<p>EksistÄ divu veidu atÅ¡Ä·irÄ«gi pieprasÄ«jumi.
+
+<ul>
+  <li>PieprasÄ«jums <b>visus</b> vÄrdi.  Tiek meklÄti dokumenti (vai
+      nodaÄŒas, vai virsraksti), kuri satur visus vÄrdus, kurus esat norÄdÄ«juÅ¡i.
+Dokumenti, kuri apmierina pieprasÄ«jumu, tiek parÄdÄ«ti alfabÄtiskÄ secÄ«bÄ.<p>
+
+  <li>PieprasÄ«jums <b>daÅŸus</b> vÄrdus. Tiek meklÄti dokumenti, kuri
+satur daÅŸus nosacÄ«jumus (vÄrdus) no uzdotÄ saraksta. Dokumenti tiek
+parÄdÄ«ti secÄ«bÄ atkarÄ«bÄ no tÄ, cik tuvu viÅi atbilst sakritÄ«bas nosacÄ«jumiem.
+
+SakritÄ«bas pakÄpe
+
+    tiek noteikta sekojoÅ¡i,
+
+      <p><ul>
+        <li> jo vairÄk meklÄÅ¡anas nosacÄ«jumus dokuments satur, jo lielÄka sakritÄ«ba;
+        <li> reti nosacÄ«jumi ir svarÄ«gÄki nekÄ izplatÄ«tie;
+        <li> Ä«si dokumenti sakrÄ«t labÄk nekÄ gari dokumenti.
+      </ul>
+</ul>
+
+<p>Lietojiet tik daudz meklÄÅ¡anas nosacÄ«jumus, cik jums patÄ«k--veselu  teikumu,
+ vai pat veselu paragrÄfu. Ja jÅ«s norÄdiet tikai vienu nosacÄ«jumu (vÄrdu),
+tad dokumenti tiks sarindoti atkarÄ«bÄ no nosacÄ«juma sastopamÄ«bas bieÅŸuma dokumentos.<p>
+}
+
+_textdatesearch_ [l=lv] {MeklÄÅ¡ana pÄc DatÄjuma}
+
+_texthelpdatesearch_ [l=lv] {MeklÄÅ¡ana pÄc datuma ÄŒauj jums atrast dukumentus, kuri atbilst ievadÄ«tiem meklÄÅ¡anas
+nosacÄ«jumiem un papildus vÄl ievÄrojot uzdotos laika perioda  nosacÄ«jumus.
+JÅ«s meklÄÅ¡anu varat veikt, gan pÄc noteikta gada skaitÄŒa, kÄ arÄ« pÄc norÄdÄ«tÄ 
+gadu perioda robeÅŸÄs. JÄpiezÄ«mÄ, ka jums nav obligÄti jÄuzdot meklÄÅ¡anas nosacÄ«jumus
+(piem. vÄrdus), jÅ«s varat meklÄt tikai pÄc datumiem, un otrÄdi, jÅ«s varat uzdot meklÄÅ¡anas 
+nosacÄ«jumus bez datumiem. Å ajÄ gadÄ«juÄ meklÄÅ¡ana notiks tÄ, it kÄ, meklÄÅ¡ana pÄc datumiem
+neeksistÄ. <p>
+}
+
+_texthelpdatehowtotitle_ [l=lv] {KÄ izmantot Å¡o iespÄju:}
+_texthelpdatehowto_ [l=lv] {<ul>
+   <li>Lai atrastu dokumentus uz doto gadu:<p>
+   <ul>
+       <li>Ievadiet meklÄÅ¡anas nosacÄ«jumus, kÄ parasti.
+       <li>Ievadiet vÄlamo gadu "Starta (vai tikai) datums" lauciÅÄ.
+       <li>Ja jÅ«su gads ir pirms mÅ«su Äras (pirms 
+           Kristus), izvÄlieties "B.C.E" opciju no nolaiÅŸamas izvÄlnes 
+           tulÄ«t aiz lauciÅa.
+       <li>UzsÄciet meklÄÅ¡anu kÄ parasti.
+   </ul>
+<p><li>Lai atrastu dokumentus uz laika periodu vai gadu periodu:<p>
+   <ul>
+       <li>Ievadiet meklÄÅ¡anas nosacÄ«jumus, kÄ parasti.
+       <li>Ievadiet vÄlamo gadu "Starta (vai tikai) datums" lauciÅÄ. 
+       <li>Ievadiet nÄkamo gadu "Beigu datums" lauciÅÄ.
+       <li>IzvÄlÄties "B.C.E" opciju no nolaiÅŸamas izvÄlnes aiz lauciÅa , ja
+           datums ir pirms mÅ«su Äras (pirms Kristus).
+       <li>UzsÄciet meklÄÅ¡anu kÄ parasti.
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=lv] {SagaidÄmais rezultÄts meklÄÅ¡anai pÄc datumiem}
+_texthelpdateresults_ [l=lv] {Stingri runÄjot, lai meklÄÅ¡anas rezultÄts bÅ«tu pilnÄ«gÄks, rekomendÄjas izmantot meklÄÅ¡anu pÄc
+datumu intervÄla, jo daÅŸos dokumentos datums (gads)  var nebÅ«t tieÅ¡i norÄdÄ«ts (piemÄram, var
+bÅ«t norÄdÄ«ts gadsimts, bet ne gads). <p>
+}  
+
+_textchangeprefs_ [l=lv] {JÅ«su iestatÄ«jumu maiÅa}
+
+_texthelppreferences_ [l=lv] {<p> Kad jÅ«s noklikÅ¡Ä·iniet uz <i>iestatÄ«jumi</i> pogas lapas augÅ¡pusÄ jÅ«s varat izmainÄ«t daÅŸas
+interfeisa iezÄ«mes, lai tÄs atbilstu jÅ«su vajadzÄ«bÄm.
+}
+
+_texthelpcollectionprefstitle_ [l=lv] {Kolekciju iestatÄ«jumi}
+_texthelpcollectionprefs_ [l=lv] {DaÅŸas kolekcijas satur daÅŸÄdas apakÅ¡kolekcijas, kuras var tikt meklÄtas
+neatkarÄ«gi vai kopÄ, kÄ viens vesels. TÄdÄ veidÄ IestatÄ«jumu lapÄ, 
+jÅ«s varat izvÄlÄties, kuras apakÅ¡kolekcijas iekÄŒaut jÅ«su meklÄjumos. 
+}
+
+_texthelplanguageprefstitle_ [l=lv] {Valodas iestatÄ«jumi}
+_texthelplanguageprefs_ [l=lv] {Katrai kolekcijai ir sava prezentÄcijas valoda pÄc noklusÄÅ¡anas, bet jÅ«s
+varat  pÄrslÄgties uz citu valodu, ja vÄlaties. JÅ«s arÄ« varat izmainÄ«t kodÄÅ¡anas
+shÄmu, ko Greenstone izmantos izvadam uz jÅ«su pÄrlÅ«kprogrammu -- programma
+izvÄlÄs to labÄko, bet ar dÄÅŸÄm pÄrlÅ«kprogrammÄm labÄku vizuÄlu rezultÄtu
+var iegÅ«t, pÄrslÄdzoties uz citu kodÄÅ¡anas shÄmu. Visas kolekcijas ÄŒauj jums
+pÄrslÄgties no standarta grafiskÄ interfeisa formÄta uz tekstuÄlu. Tas Ä«paÅ¡i
+izmantojams lietotÄjiem ar vÄju redzi, kuri izmanto lielus ekrÄna Å¡riftus vai
+runas sintezÄtorus izvadam.
+}
+
+_texthelppresentationprefstitle_ [l=lv] {PrezentÄcijas iestatÄ«jumi}
+_texthelppresentationprefs_ [l=lv] {AtkarÄ«bÄ no katras kolekcijas, jÅ«s varat uzstÄdÄ«t daÅŸÄdas opcijas, kuras
+kontrolÄs prezentÄciju. 
+
+
+<p>TÄ«mekÄŒu lapu kolekcijas ÄŒauj jums aizliegt parÄdÄ«ties Greenstone navigÄcijas
+joslai katra dokumeta lapas augÅ¡pusÄ, tÄdÄ veidÄ, pÄc katras meklÄÅ¡anas beigÄm
+jÅ«s nonÄkat meklÄjamÄ lapÄ bez jebkÄdas Greenstone datnes galvenes. Lai veiktu
+nÄkoÅ¡o meklÄÅ¡anu, jums vajadzÄs lietot jÅ«su pÄrlÅ«kprogrammas âatpakaÄŒâ pogu.
+Kolekcijas arÄ« atÄŒauj jums aizliegt Greenstone brÄ«dinÄjuma paziÅojumu, kad jÅ«s
+noklikÅ¡Ä·iniet uz saiti, kura pÄradresÄs jÅ«s uz Äru no digitÄlÄs bibliotÄkas kolekcijas
+un uz paÅ¡u TÄ«mekli. DaÅŸÄs TÄ«mekÄŒa kolekcijÄs jÅ«s varat kontrolÄt, vai saites 
+âMeklÄÅ¡anas RezultÄtuâ lapÄ pÄradresÄs jÅ«s uz aktuÄlÄm URL, vai uz digitÄlÄs 
+bibliotÄkas lapÄm-kopijÄm.
+}
+
+_texthelpsearchprefstitle_ [l=lv] {MeklÄÅ¡anas iestatÄ«jumi}
+_texthelpsearchprefs_ [l=lv] {<p>Divu pÄru pogas kontrolÄ meklÄÅ¡anas veidu, kas tiks veikts.
+Pirmais pÄris (âreÄ£istru atÅ¡Ä·irÄ«basâ) kontrolÄ vai jÄsakrÄ«t ar maziem, vai lielajiem
+burtiem.  Otrais pÄris (âvÄrdu galotnesâ) kontrolÄ vai ignorÄt vÄrdu galotnes, vai
+nÄ. Ir iespÄjams izmantot lielu meklÄÅ¡anas pieprasÄ«juma lodziÅu, tÄdÄ veidÄ,
+jÅ«s varat viegli veikt paragrÄfa-izmÄra meklÄÅ¡anu. Tas ir pÄrsteidzoÅ¡i, Ätri veikt
+liela apjoma tekstu meklÄÅ¡anu.
+
+<p>PiemÄram, ja pogas <i> ignorÄt reÄ£istru atÅ¡Ä·irÄ«bas </i> un
+<i>ignorÄt vÄrdu galotnes</i> ir izvÄlÄtas, tad pieprasÄ«jums<p>
+    <ul><kbd>African building</kbd></ul>
+      <p>tiks apstrÄdÄts tÄpatÄs, kÄ<p>
+      <ul><kbd>africa builds</kbd></ul><p>
+      tÄpÄc , ka lielais burts vÄrdÄ "African" transformÄsies uz mazo
+      un galotnes "n" un "ing" tiks novÄktas no
+      "African" un "building" vÄrdiem attiecÄ«gi (arÄ«, "s" tiks novÄkts no "builds").
+
+<p>JÅ«s varat pÄrslÄgties uz âuzlabotaisâ pieprasÄ«juma reÅŸÄ«mu, kurÅ¡ ÄŒaus jums
+kombinÄt nosacÄ«jumus izmantojot AND(&), OR (|) un NOT (!). Tas ÄŒauj veidot
+daudz precÄ«zÄkus pieprasÄ«jumus. JÅ«s varat izmantot meklÄÅ¡anas vÄstures
+iepÄju, kurÅ¡ parÄdÄ«s daÅŸus jÅ«su pÄdÄjos pieprasÄ«jumus. Tas dot iespÄju atkÄrtoti 
+izmantot viegli izmainÄ«tus iepriekÅ¡Äjos pieprasÄ«jumus. Beidzot, jÅ«s varat kontrolÄt
+atgriezto meklÄÅ¡anas trÄpÄ«jumu skaitu un to prezentÄcijas daudzumu uz katra ekrÄna.
+}
+
+_texttanumbrowseoptions_ [l=lv] {Pieejami _numbrowseoptions_ veidi, kÄ atrast informÄciju Å¡ajÄ kolekcijÄ:}
+
+_textsimplehelpheading_ [l=lv] {KÄ meklÄt informÄciju _collectionname_ kolekcijÄ}
+
+_texthelpscopetitle_ [l=lv] {PieprasÄ«jumu darbÄ«bas sfÄra}
+_texthelpscope_ [l=lv] {<p>
+VairumÄ kolekcijÄs jÅ«s varat izvÄlÄties daÅŸÄdus meklÄÅ¡anas indeksus. PiemÄram, tie
+var bÅ«t autoru vai virsraksu indeksi. Vai tie var bÅ«t nodaÄŒu vai paragrÄfu indeksi. VispÄr,
+pilnÄ mÄrÄ meklÄjamais dokuments tiek atgriezsts neatkarÄ«gi no uzdotÄ meklÄÅ¡anas indeksa.
+<p>Ja dokumenti ir grÄmatas, tÄs tiks atvÄrtas atbilstoÅ¡Äs vietÄs.
+}
Index: /gsdl/stable/macros/latvian2.dm
===================================================================
--- /gsdl/stable/macros/latvian2.dm	(revision 20131)
+++ /gsdl/stable/macros/latvian2.dm	(revision 20131)
@@ -0,0 +1,1015 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Latvian Language text and icon macros (many thanks to Raitis Brodezhonok)
+# -- this file contains text that is of less importance
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=lv] {dokumenti.}
+_lastupdate_ [l=lv] {PÄdejoreiz atjaunota }
+_ago_ [l=lv] {dienas atpakaÄŒ.}
+_colnotbuilt_ [l=lv] {Kolekcija nav izveidota}
+
+_textpoem_ [l=lv] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>lai miers un klusums apÅem jÅ«s,
+<br>lai jÅ«s atrastos vasaras siltuma plÄ«vurÄ,
+<br>lai jÅ«su ceÄŒojumu okeÄns bÅ«tu tik gluds, kÄ nopulÄts greenstone.
+}
+
+_textgreenstone_ [l=lv] {<p>Greenstone ir pusdÄrgakmenis, kas (lÄ«dzigi ka programmatÅ«ra) tiek iegÅ«ts
+JaunzÄlandÄ. TradicionÄlÄ Maori sabiedrÄ«bÄ tas bija visdÄrgÄkais un vispieprasÄ«tÄkais.
+Tas var absorbÄt un noturÄt <i>wairua</i>, kas ir gars vai dzÄ«vÄ«bas spÄks, un ir
+nodroÅ¡inÄts ar tradicionÄlÄm vÄrtÄ«bÄm, kas padara to par piemÄrotu emblÄmu
+tÄdam publiski  pieejamam projektam, kÄ digitÄlÄ bibliotÄka. TÄ spoÅŸums norÄda uz
+ÅŸÄlsirdÄ«bu; tÄ caurspÄ«dÄ«ba - godÄ«gums; tÄ stingrÄ«ba - droÅ¡sirdÄ«ba; un asie gali, kas tam
+var bÅ«t - taisnÄ«gums. IzgravÄts akmens gabals, kas tiek izmantots kÄ Greenstone DigitÄlÄs
+BibliotÄkas ProgrammatÅ«ras logo, ir  <i>patu</i> vai cÄ«Åas klubs, un ir viena no
+projekta dalÄ«bnieka Ä£imenes relikvijÄm. Tas simbolizÄ:  ÄŒoti Ätru reakciju, precizitÄti 
+un pabeigtÄ«bu roku cÄ«ÅÄ. MÄs vÄlÄtos, lai Å¡Ä«s kvalitÄtes piemistu arÄ« mÅ«su programmatÅ«rai,
+un  akmens ÅŸiletes asuma <i>patu</i> gals zimbolizÄ tehnoloÄ£ijas vadoÅ¡Äs pozÄ«cijas. 
+}
+
+_textaboutgreenstone_ [l=lv] {<p>Greenstone ir programmatÅ«ras komplekts, lai veidotu un izplatÄ«tu
+digitÄlÄs bibliotÄkas kolekcijas. Tas nodroÅ¡ina jaunu informÄcijas 
+organizÄÅ¡anas un publicÄÅ¡anas veidu uz Interneta vai uz CD-ROM.
+Greenstone ir producÄts <b>JaunzÄlandes DigitÄlÄs BibliotÄkas Projekta</b>
+ietvaros <b>Waikato UniversitÄtÄ</b>, attÄ«stÄ«ts un izplatÄ«ts kooperÄcijÄ ar
+<b>UNESCO</b> un <b>Human Info NGO</b>. TÄ ir atvÄrto-kodu
+programmatÅ«ra un pieejama no <a
+href="http://greenstone.org">http://greenstone.org</a> pie 
+GNU General Public License nosacÄ«jumiem.
+</p>
+
+<p>ProgrammatÅ«ras mÄrÄ·is ir dot iespÄju lietotÄjiem universitÄtÄs,
+bibliotÄkÄs un citÄs publisko pakalpojumu institÅ«cijÄs veidot viÅu
+paÅ¡u digitÄlÄs bibliotÄkas. DigitÄlÄs bibliotÄkas radikÄli reformÄ veidu,
+kÄ informÄcija tiek izplatÄ«ta un iegÅ«ta UNESCO partneru savienÄ«bÄs
+un institÅ«cijÄs: izglÄ«tÄ«bas, zinÄtnes un kultÅ«ras jomÄs visÄ pasaulÄ un
+Ä«paÅ¡i attÄ«stÄ«bas valstÄ«s. MÄs ceram, ka Å¡Ä« programmatÅ«ra veicinÄs 
+efektÄ«vu digitÄlo bibliotÄku izvÄrÅ¡anos, lai dalÄ«tos ar informÄciju un
+izvietotu to publiskÄ vietÄ.
+</p>
+
+
+<p>Å Ä« programmatÅ«ra ir attÄ«stÄ«ta un izplatÄ«ta kÄ starptautisku pÅ«liÅu
+rezultÄts, kurÅ¡ nodibinÄjies augustÄ 2000. g. starp trim pusÄm.  
+</p>
+
+<p>
+<a href="http://nzdl.org"><b>JaunzÄlandes DigitÄlÄs BibliotÄkas Projekts Waikato UniversitÄtÄ</b></a>
+<br>
+Greestone programmatÅ«ra izauga no Å¡Ä projekta, un Å¡Ä« iniciatÄ«va
+tika apstiprinÄta ar KomunikÄciju ApakÅ¡komisiju JaunzÄlandes
+NacionÄlajÄ KomisijÄ, kÄ daÄŒa no JaunzÄlandes ieguldÄ«juma UNESCO 
+programmÄ.
+</p>
+
+<p>
+<a href="http://www.unesco.org"><img src="_httpimg_/unesco.gif"
+class="logo"></a>
+<a href="http://www.unesco.org"><b>ANO IzglÄ«tÄ«bas, ZinÄtnes un KultÅ«ras OrganizÄcija</b></a>
+<br>
+IzglÄ«tÄ«bas, zinÄtniskÄs un kultÅ«ras informÄcijas izplatÄ«Å¡anÄs pa visu
+pasauli un Ä«paÅ¡i tÄs pieejamÄ«ba attÄ«stÄ«bas valstÄ«s ir centrÄlais
+UNESCO mÄrÄ·is, kÄ norÄdÄ«ts tÄs starpvaldÄ«bu InformÄcijÄ VisÄm
+ProgrammÄm, un attiecÄ«gÄs informÄciju un komunikÄciju 
+tehnoloÄ£ijas ir uzskatÄmas, kÄ svarÄ«gi rÄ«ki Å¡ajÄ kontekstÄ.
+</p>
+
+<p>
+<a href="http://humaninfo.org"><img src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>The Human Info NGO, bÄzÄjas AntverpenÄ, BelÄ£ijÄ</b></a>
+<br>
+Å is projekts darbojas ar ANO aÄ£entÅ«rÄm un citÄm NVO (NGO), un ir nodibinÄjis vispasaules reputÄciju
+dokumentu diÄ£itÄlizÄcijÄ humÄnÄs attÄ«stÄ«bas interesÄs, un veicot to plaÅ¡i pieejamu,
+par brÄ«vu attÄ«stot nÄcijas.
+</p>
+}  
+
+
+_textdescrselcol_ [l=lv] {piedÄvÄtÄs kolekcijas}
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=lv] {Pieejamas sekojoÅ¡as Äetras pogas uz mÄjas lapas}
+
+_textnocollections_ [l=lv] {<p>DotajÄ Greenstone instalÄcijÄ nav pieejamas kolekcijas
+Lai pievienotu daÅŸas kolekcijas jÅ«s varat
+<ul><li>Izmantot <a href="_httppagecollector_">Kolektoru</a> lai izveidotu jaunas kolekcijas
+    <li>Ja jums ir Greenstone cd-rom, jÅ«s varat instalÄt kolekcijas no cd-rom
+</ul>
+}
+
+_text1coll_ [l=lv] {DotÄ Greenstone instalÄcija satur 1 kolekciju }
+
+_textmorecolls_ [l=lv] {DotÄ Greenstone instalÄcija satur _1_ kolekcijas }
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=lv] {ÄrÄja Saite}
+_textlinknotfound_ [l=lv] {IekÅ¡ÄjÄ Saite nav Atrasta}  
+
+_textextlinkcontent_ [l=lv] {Saite, kuru jÅ«s esat izvÄlÄjuÅ¡ies, ir ÄrÄja attiecÄ«bÄ pret jebkuru paÅ¡reiz izvÄlÄto kolekciju.
+    Ja jÅ«s joprojÄm gribat skatÄ«t Å¡o saiti un jÅ«su pÄrlÅ«kam ir pieejams TÄ«meklis,
+    jÅ«s varat <a href="_nexturl_">tikt tÄlÄk</a> uz Å¡o lapu; pretÄjÄ gadÄ«jumÄ
+    izmantojiet jÅ«su pÄrlÅ«ka "atpakaÄŒ" pogu, lai atgrieztos uz iepriekÅ¡Äjo dokumentu.}
+
+_textlinknotfoundcontent_ [l=lv] {Iemeslu dÄÄŒ Ärpus mÅ«su kontroles, iekÅ¡ÄjÄ saite, kuru jÅ«s esat izvÄlÄjuÅ¡ies
+    neeksistÄ.  Tas iespÄjams ir dÄÄŒ kÄŒÅ«das pirmkolekcijÄ (avota kolekcijÄ).
+    Izmantojiet pÄrlÅ«ka "atpakaÄŒ" pogu, lai atgrieztos uz iepriekÅ¡Äjo dokumentu.}
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=lv] {<h3>Saite uz "_2_" kolekciju</h3>
+
+<p> JÅ«su izvÄlÄtÄ saite ir ÄrÄja uz "_collectionname_"
+    kolekciju (tÄ saista uz "_2_" kolekciju).
+    Ja jÅ«s vÄlÄties skatÄ«t Å¡o saiti  "_2_" kolekcijÄ, jÅ«s varat 
+    <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">tikt tÄlÄk</a> uz Å¡o lapu; 
+    pretÄjÄ gadÄ«jumÄ izmantojiet jÅ«su pÄrlÅ«ka "atpakaÄŒ" pogu, lai atgrieztos uz iepriekÅ¡Äjo dokumentu.
+}
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=lv] {Greenstone DiÄ£itÄlÄ BibliotÄka}
+
+_textusername_ [l=lv] {lietotÄjvÄrds}
+_textpassword_ [l=lv] {parole}
+
+_textmustbelongtogroup_ [l=lv] {IevÄrojiet, ka jums jÄpieder "_cgiargug_" grupai, lai piekÄŒÅ«tu Å¡ai lapai}
+
+_textmessageinvalid_ [l=lv] {JÅ«su prasÄ«tÄ lapa pieprasa jÅ«su pierakstÄ«Å¡anos.<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)
+LÅ«dzu ievadiet jÅ«su lietotÄja vÄrdu un paroli.}
+
+_textmessagefailed_ [l=lv] {JÅ«su lietotÄja vÄrds vai parole bija nepareizi.}
+
+_textmessagedisabled_ [l=lv] {Atvainojiet, jÅ«su lietotÄja konts ticis aizliegts. LÅ«dzu sazinieties
+ar Å¡Ä«s vietnes tÄ«mekÄŒa pÄrzini.}
+
+_textmessagepermissiondenied_ [l=lv] {Atvainojiet, bet piekÄŒÅ«t Å¡ai lapai jums nav atÄŒaujas.}
+
+_textmessagestalekey_ [l=lv] {Saite, pa kuru jÅ«s sekojat ir tikusi atjaunota.
+LÅ«dzu ievadiet jÅ«su paroli, lai piekÄŒÅ«tu Å¡ai lapai.}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=lv] {<p>Å Ä« Greenstone instalÄcija neiekÄŒauj nevienu dokumentu. Tas
+varÄtu bÅ«t ja:
+<ol>
+ <li>Greenstone bija instalÄts no CD-ROM izmantojot kompakto instalÄciju.
+ <li>Greenstone bija instalÄts no interneta lejupielÄdÄtÄs 
+ distribÅ«cijas.
+</ol>
+Abos gadÄ«jumos jÅ«s varat dabÅ«t dokumentÄciju vai nu no <i>docs</i>
+direktorijas uz Greenstone CD-ROM vai apmeklÄjot <a
+href="http://www.greenstone.org">http://www.greenstone.org</a>.
+}
+
+_textuserguide_ [l=lv] {User's Guide}
+_textinstallerguide_ [l=lv] {Installer's Guide}
+_textdeveloperguide_ [l=lv] {Developer's Guide}
+_textpaperguide_ [l=lv] {From Paper to Collection}
+_textorganizerguide_ [l=lv] {Using the Organizer}
+
+_textgsdocstitle_ [l=lv] {greenstone dokumentÄcija}
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=lv] {noklusÄjuma struktÅ«ra}
+_textmore_ [l=lv] {vairÄk}
+_textinfo_ [l=lv] {Kolekcijas informÄcija}
+_textsrce_ [l=lv] {Pirmdati}
+_textconf_ [l=lv] {KonfigurÄt kolekciju}
+_textbild_ [l=lv] {Veidot kolekciju}
+_textview_ [l=lv] {SkatÄ«t kolekciju}
+_textdel_ [l=lv] {IzdzÄst kolekciju}
+_textexpt_ [l=lv] {EksportÄt kolekciju}
+
+_textdownloadingfiles_ [l=lv] {DatÅu lejupielÄdÄÅ¡ana âŠ}
+_textimportingcollection_ [l=lv] {kolekcijas importÄÅ¡ana âŠ}
+_textbuildingcollection_ [l=lv] {Kolekcijas veidoÅ¡ana âŠ}
+_textcreatingcollection_ [l=lv] {kolekcijas radÄ«Å¡ana âŠ}
+
+_textcollectorblurb_ [l=lv] {<i>Spalva ir spÄcÄ«gÄka nekÄ zobens!
+<br>InformÄcijas kolekciju veidoÅ¡ana un izplatÄ«Å¡ana prasa atbildÄ«bu,
+kuru jÅ«s vÄlÄtos atspoguÄŒot pirms jÅ«s sÄkat.
+Ir autortiesÄ«bas uz legÄliem izdevumiem: iespÄja piekÄŒÅ«t dokumentiem
+nebÅ«t nenozÄ«mÄ, ka jÅ«s varat nodot tos citiem.
+Ir sociÄlie izdevumi: kolekcijÄm jÄrespektÄ sabiedrÄ«bas prasÄ«bas, kura
+piegÄdÄja dokumentus.
+Un ir vÄl Ätiskie jautÄjumi: daÅŸÄm lietÄm nevajadzÄtu bÅ«t vienkÄrÅ¡i 
+pieejamÄm citiem.
+<br>Esiet uzmanÄ«gi ar informÄcijas spÄku un izmantojiet to prÄtÄ«gi.
+</i>  
+}
+
+_textcb1_ [l=lv] {Kolektors palÄ«dzÄs jums izveidot jaunas kolekcijas, modificÄt vai papildinÄt
+jau eksistÄjoÅ¡as, vai izdzÄst kolekcijas.  Lai to veiktu, jÅ«s tiksiet vadÄ«ti caur
+TÄ«mekÄŒu lapu secÄ«bu, kur tiks pieprasÄ«ta nepiecieÅ¡ama informÄcija.
+}
+
+_textcb2_ [l=lv] {Vispirms, jums vajag izlemt vai}
+_textcnc_ [l=lv] {radÄ«t jaunu kolekciju}
+_textwec_ [l=lv] {darbs ar eksistÄjoÅ¡u kolekciju, datu pievienoÅ¡ana tai vai izdzÄÅ¡ana no tÄs.}
+
+_textcb3_ [l=lv] {Lai veidotu vai modificÄtu digitÄlÄs bibliotÄkas kolekciju jums vajag pierakstÄ«ties.
+Tas ir, lai aizsargÄtu jÅ«s no citiem pieteikumiem (logging) uz  jÅ«su datoru un 
+aisargÄtu no informacijas izmaiÅas uz tÄ. IevÄrojiet: droÅ¡Ä«bas dÄÄŒ jÅ«s tiksiet
+automÄtiski atteikti (logged out), pÄc 30 minÅ«Å¡u ilga perioda, kopÅ¡ jÅ«su pieteikuma
+(logged in). Ja tas notiek, neuztraucieties! -- jÅ«s tiksiet uzaicinÄti pieteikties no 
+jauna un varÄsiet turpinÄt no tÄs vietas, kur bijÄt.
+}
+
+_textcb4_ [l=lv] {LÅ«dzu ievadiet jÅ«su Greenstone lietotÄjvÄrdu un paroli, un noklikÅ¡Ä·iniet pogu lai
+apstiprinÄtu.
+}
+
+_textfsc_ [l=lv] {Vispirms izvÄlieties kolekciju ar kuru jÅ«s gribat strÄdÄt ( aizsargÄtas no ieraksta
+kolekcijas neparÄdÄ«sies Å¡ajÄ sarakstÄ).
+}
+
+_textwtc_ [l=lv] {Ar jÅ«su izvÄlÄto kolekciju jÅ«s varat}
+_textamd_ [l=lv] {Pievienot papildus datus un pÄrbÅ«vÄt kolekciju}
+_textetc_ [l=lv] {RediÄ£Ät kolekcijas konfigurÄcijas datni un rekonstruÄt kolekciju}
+_textdtc_ [l=lv] {IzdzÄst kolekciju pilnÄ«gi}
+_textetcfcd_ [l=lv] {EksportÄt kolekciju, lai rakstÄ«tu uz paÅ¡uzstÄdÄmo Windows CD-ROM }
+_textcaec_ [l=lv] {EksistÄjoÅ¡as kolekcijas izmaiÅa}
+_textnwec_ [l=lv] {ModificÄÅ¡anai nav pieejamas uz ierakstu atÄŒautas kolekcijas   }
+_textcianc_ [l=lv] {JaunÄs kolekcijas veidoÅ¡ana}
+_texttsosn_ [l=lv] {SoÄŒu secÄ«ba, kura nepiecieÅ¡ama, lai radÄ«tu jaunu digitÄlÄs bibliotÄkas kolekciju:}
+_textsin_ [l=lv] {NorÄdiet tÄs vÄrdu (un saistÄ«to informÄciju)}
+_textswts_ [l=lv] {NorÄdiet no kurienes pirmdati nÄk}
+_textatco_ [l=lv] {PielÄgot konfigurÄcijas opcijas (tikai pieredzÄjuÅ¡iem lietotÄjiem)}
+_textbtc_ [l=lv] {"Veidot" kolekciju (skatÄ«t zemÄk)}
+_textpvyh_ [l=lv] {Ar lepnumu apskatiet jÅ«su rokudarbu.}
+
+_texttfsiw_ [l=lv] {Ceturtais solis ir tas, kur dators veic visu nepiecieÅ¡amo darbu. "VeidoÅ¡anas"
+procesÄ dators veido visus indeksus un savÄc kopÄ visu pÄrÄjo informÄciju,
+kura nepiecieÅ¡ama, lai viss darbotos. Bet vispirms jums vajag specificÄt
+informÄciju.
+}
+
+_textadab_ [l=lv] {ApakÅ¡Ä parÄdÄs diagramma, kura palÄ«dzÄs jums izsekot jÅ«su atraÅ¡anas pozÄ«ciju.
+ZaÄŒÄ poga ir tÄ, kuru jÅ«s noklikÅ¡Ä·iniet secÄ«gÄ izpildÄ«jumÄ. JÅ«su darbÄ«bas secÄ«bÄ,
+pogas mainÄ«s nokrÄsu no zaÄŒÄs uz dzeltenu. JÅ«s varat atgriezties iepriekÅ¡ÄjÄ
+lapÄ noklikÅ¡Ä·inot uz atbilstoÅ¡Äs dzeltenÄs pogas uz diagrammas. 
+}
+
+_textwyar_ [l=lv] {Kad jÅ«s esat gatavi, nokliÅ¡Ä·iniet zaÄŒo "kolekcijas informÄcija" pogu, lai
+sÄktu radÄ«t jÅ«su jauno digitÄlÄs bibliotÄkas kolekciju!
+}
+
+_textcnmbs_ [l=lv] {Kolekcijas vÄrdam jÄbÅ«t norÄdÄ«tam}
+_texteambs_ [l=lv] {Epasta adresei jÄbÅ«t ievadÄ«tai}
+_textpsea_ [l=lv] {LÅ«dzu norÄdiet epasta adresi formÄ: username@domain}
+_textdocmbs_ [l=lv] {Kolekcijas aprakstam jÄbÅ«t ievadÄ«tam.}
+
+_textwcanc_ [l=lv] {Kad tiek radÄ«ta jauna kolekcija, jums nepiecieÅ¡ams ievadÄ«t sagatavoÅ¡anas
+informÄciju par datu avotu. Å is process ir strukturÄts kÄ TÄ«mekÄŒu lapu 
+sÄrija, pÄrskatÄma no Kolektora. Abgabals lapas apakÅ¡Ä parÄda jums
+Å¡o lapu secÄ«bu, kurÄm ir jÄiziet cauri.
+}
+
+_texttfc_ [l=lv] {Kolekcijas nosaukums:}
+
+_texttctiasp_ [l=lv] {Kolekcijas nosaukums ir Ä«sa frÄze, kura tiek izmantota viscaur digitÄlajÄ bibliotÄkÄ,
+lai identificÄtu kolekcijas saturu. PiemÄram, 
+"Computer Science Technical Reports" un "Humanity Development Library."
+}
+
+_textcea_ [l=lv] {Kontakta epasta adrese:}
+
+_textteas_ [l=lv] {Å Ä« epasta adrese norÄda pirmo kontakta punktu dotai kolekcijai.
+Ja Greenstone programmatÅ«ra sastopas ar problÄmu, tad diagnozes ziÅojums
+tiek sÅ«tÄ«ts uz Å¡o adresi. Ievadiet epasta adresi tÄs pilnÄ formÄ:
+<tt>name@domain</tt>.
+}
+
+_textatc_ [l=lv] {Par Å¡o kolekciju:}
+
+_texttiasd_ [l=lv] {Å eit tiek veikts apraksts, pÄc kÄdiem principiem kolekcija tika veidota.
+TÄ parÄdÄs uz kolekcijas prezentÄcijas pirmÄs lapas.
+}
+
+_textypits_ [l=lv] {JÅ«su pozÄ«cija secÄ«bÄ tiek indicÄta ar bultiÅu apakÅ¡daÄŒÄ--Å¡ajÄ
+gadÄ«jumÄ, kÄ "kolekcijas informÄcija" stadija. Lai turpinÄtu, nospiediet zaÄŒo
+"pirmdati" pogu.
+}
+
+_srcebadsources_ [l=lv] {<p>Viens vai vairÄki jÅ«su norÄdÄ«tie ievada avoti ir nepieejami (izcelti
+_iconcross_ zemÄk).
+
+<p>Tam cÄlonis varÄtu bÅ«t
+<ul>
+<li>Datne, FTP vietne vai URL neeksistÄ.
+<li>Jums vispirms nepiecieÅ¡ams iezvanÄ«t uz ISP.
+<li>JÅ«s mÄÄ£inÄt piekÄŒÅ«t URL atrodoties aiz ugunsmÅ«ra (tas ir gadÄ«jums
+kad jums normÄli vajag norÄdÄ«t lietotajvÄrdu un paroli, lai piekÄŒÅ«tu
+internetam).
+</ul>
+
+<p>Ja tas ir URL, kuru jÅ«s varat redzÄt jÅ«su pÄrlÅ«kprogrammÄ, tad tas varÄtu
+nÄkt no lokÄlÄs keÅ¡-kopijas.DiemÅŸÄl, lokÄlas keÅ¡-kopijas ir neredzamas
+mÅ«su spoguÄŒprocesam. Å ajÄ gadÄ«jumÄ mÄs rekomendÄjam, lai jÅ«s vispirms
+lejupielÄdÄjat lapas, izmantojot jÅ«su pÄrlÅ«kprogrammu. 
+}
+
+_textymbyco_ [l=lv] {<p>JÅ«s varat bÄzÄt jÅ«su kolekciju uz
+<ul>
+<li>NoklusÄjuma struktÅ«ra
+<dl><dd>Jauna kolekcija var saturÄt html dokumentus (.htm, .html), teksta
+dokumentus (.txt, .text), MS Word dokumentus (.doc), PDF dokumentus (.pdf) vai
+"m-box" formÄta epasta dokumentus (.mbx).</dd><dl>
+<li>EksistÄjoÅ¡a kolekcija
+<dl><dd>JÅ«su jaunÄs kolekcijas datÅu tipam jÄbÅ«t pilnÄ«gi tÄdam paÅ¡am, kÄ
+jau eksistÄjoÅ¡Äs kolekcijas datÅu tipam.</dd></dl>
+</ul>
+}
+
+_textbtco_ [l=lv] {Kolekcija pamatojas uz}
+_textand_ [l=lv] {Pievienot jaunus datus}
+_textad_ [l=lv] {Papildus dati:}
+
+_texttftysb_ [l=lv] {Datnes, kuras norÄdÄ«tas apakÅ¡Ä, tiks pievienotas kolekcijai. PÄrliecinieties,
+ka jÅ«s neesat norÄdijuÅ¡i datnes, kuras jau ir kolekcijÄ:
+pretÄjÄ gadÄ«jumÄ, divas kopijas tiks iekÄŒautas. Datnes tiek identificÄtas
+pÄc to pilnajiem ceÄŒavÄrdiem, TÄ«mekÄŒa lapas pÄc to absolÅ«tÄm TÄ«mekÄŒa
+adresÄm.
+}
+
+_textis_ [l=lv] {Ievadavoti:}
+
+_textddd1_ [l=lv] {<p>Ja jÅ«s lietojat file:// vai ftp:// ,lai norÄdÄ«tu datni, tad datne
+tiks lejupielÄdÄta.
+
+<p>Ja jÅ«s lietojat http:// , tad tas atkarÄ«gs, vai URL norÄda uz normÄlu tÄ«mekÄŒa
+lapu jÅ«su pÄrlÅ«kprogrammÄ, vai datÅu sarakstu. Ja uz lapu, tad lapa tiks lejupielÄdÄta
+-- un arÄ« visas lapas uz kurÄm ir saites no tÄs, un pÄrÄjÄs lapas uz kurÄm ir savukÄrt 
+saites, utt. --  piÅemot, ja tÄs visas ir uz tÄs paÅ¡as vietnes, kuru norÄda URL.
+
+<p>Ja jÅ«s lietojat file:// vai ftp:// norÄdot mapi  vai direktoriju, vai uzdodat
+http:// URL kas norÄda uz datÅu sarakstu, viss esoÅ¡ais mapÄ un tÄs
+apakÅ¡-mapÄs tiks iekÄŒauts kolekcijÄ.
+
+<p>NoklikÅ¡Ä·iniet "vairÄk avoti" pogu, lai dabÅ«tu vairÄk ievada lodziÅus. 
+}
+
+_textddd2_ [l=lv] {<p>NokliÅ¡Ä·iniet vienu no zaÄŒÄm pogÄm. Ja jÅ«s esat pieredzÄjis lietotÄjs, jÅ«s
+iespÄjams gribÄsiet koriÄ£Ät kolekcijas konfigurÄciju. AlternatÄ«vi, jÅ«s varat doties
+taisni uz veidoÅ¡anas stadiju. Atcerieties, jÅ«s vienmÄr varat atgriezties iepriekÅ¡ÄjÄ
+stadijÄ noklikÅ¡Ä·inot tÄs dzelteno pogu.
+}
+
+_textconf1_ [l=lv] {<p>JÅ«su kolekcijas veidoÅ¡ana un prezentÄcija tiek kontrolÄta ar
+specifikÄcijÄm speciÄlÄ "konfigurÄciju datnÄ". PieredzÄjuÅ¡i lietotÄji
+var mainÄ«t konfigurÄcijas uzstatÄ«jumus.
+
+<center><p><b>Ja jÅ«s nÄesat pieredzÄjis lietotÄjs, vienkÄrÅ¡i dodieties
+uz lapas apakÅ¡u.</b></center>
+
+<p>Lai izmainÄ«tu konfigurÄcijas uzstatÄ«jumus, rediÄ£Äjiet datus, kuri redzami zemÄk.
+ Ja jÅ«s kÄŒÅ«dÄties, noklikÅ¡Ä·iniet uz "Atiestate", lai atjaunotu oriÄ£inÄlos konfigurÄcijas
+uzstatÄ«jumus.
+}
+
+_textreset_ [l=lv] {Atiestate}
+
+_textbild1_ [l=lv] {Kolekcija patreiz tiek veidota: tas var aizÅemt zinÄmu laiku. VeidoÅ¡anas
+stÄvokÄŒa lÄ«nija apakÅ¡Ä uzrÄda operÄcijas progresu.
+}
+
+_textbild2_ [l=lv] {Lai apturÄtu veidoÅ¡anas procesu jebkurÄ laikÄ, noklikÅ¡Ä·iniet Å¡eit.
+<br>Kolekcija ar kuru jÅ«s strÄdajat paliks neskarta.
+}
+
+_textstopbuild_ [l=lv] {stop veidot}
+
+_textbild3_ [l=lv] {Ja jÅ«s aiziesiet no Å¡Ä«s lapas (un nebÅ«siet atcÄluÅ¡i veidoÅ¡anas procesu ar
+"stop veidot" pogu) kolekcija turpinÄsies veidoties un tiks uzstÄdÄ«ta pie 
+sekmÄ«ga nobeiguma.
+}
+
+_textbuildcancelled_ [l=lv] {VeidoÅ¡ana atcelta}
+
+_textbildcancel1_ [l=lv] {Kolekcijas veidoÅ¡anas process bija atcelts. Izmantojiet dzeltenas pogas apakÅ¡Ä,
+lai veiktu izmaiÅas jÅ«su kolekcijÄ vai restÄrtÄtu veidoÅ¡anas procesu.
+}
+
+_textbsupdate1_ [l=lv] {VeidoÅ¡anas stÄvokÄŒa aktualizÄcija 1 sekundÄ}
+_textbsupdate2_ [l=lv] {VeidoÅ¡anas stÄvokÄŒa aktualizÄcija }
+_textseconds_ [l=lv] {sekundes}
+_textbildsuc_ [l=lv] {Kolekcija izveidota sekmÄ«gi.}
+
+_textviewbildsummary_ [l=lv] {JÅ«s varat <a href="_httppagex_(bsummary)&c=_cgiargbc1dirname_" target=_top>skatÄ«t kolekcijas veidoÅ¡anas
+pÄrskatu</a> papildus informÄcijai.
+}
+
+_textfailmsg11_ [l=lv] {Kolekcija nevarÄja tikt izveidota, jo nesatur datus. PÄrliecinieties, ka vismaz
+viena no direktorijÄm vai datnÄm, kuras jÅ«s norÄdÄ«jÄt <i>pirmdati</i>
+lapÄ eksistÄ un ir tÄda tipa, ko Greenstone var apstrÄdÄt.   
+}
+
+_textfailmsg21_ [l=lv] {Kolekcija nevarÄja bÅ«t izveidota (import.pl nojuka).}
+_textblcont_ [l=lv] {VeidoÅ¡anas ieraksts satur sekojoÅ¡u informÄciju:}
+
+_texttryagain_ [l=lv] {LÅ«dzu <a href="_httppagecollector_" target=_top>restartÄjiet kolektoru</a>
+un mÄÄ£iniet vÄlreiz.
+}
+
+_textfailmsg31_ [l=lv] {Kolekcija nevarÄja bÅ«t izveidota (buildcol.pl nojuka).}
+_textfailmsg41_ [l=lv] {Kolekcija tika izveidota sekmÄ«gi, bet nevarÄja tikt uzstÄdÄ«ta.}
+_textfailmsg71_ [l=lv] {NeparedzÄta kÄŒÅ«da gadÄ«jÄs, kamÄr mÄÄ£inÄju veidot jÅ«su kolekciju }
+_textretcoll_ [l=lv] {Atgriezties uz kolektoru}
+
+_textdelperm_ [l=lv] {DaÄŒa vai visa _cgiargbc1dirname_ kolekcija nevar tikt izdzÄsta.
+IespÄjami cÄloÅi ir:
+<ul>
+<li> Greenstone nav atÄŒaujas izdzÄst _gsdlhome_/collect/_cgiargbc1dirname_
+direktoriju.<br>
+JÅ«s varat mÄÄ£inÄt izdzÄst Å¡o direktoriju manuÄli, lai pabeigtu kolekcijas _cgiargbc1dirname_
+izdzÄÅ¡anu no jÅ«su datora.</li>
+<li>Greenstone nevar palaist programmu _gsdlhome_/bin/script/delcol.pl . PÄrliecinieties,
+ka Å¡Ä« datne ir lasÄma (readable) un izpildÄma (executable).</li>
+</ul>
+}
+
+_textdelinv_ [l=lv] {_cgiargbc1dirname_ kolekcija ir aizsargÄta vai bojÄta. IzdzÄÅ¡ana bija atcelta.
+}
+
+_textdelsuc_ [l=lv] {_cgiargbc1dirname_ kolekcija bija sekmÄ«gi izdzÄsta.}
+
+_textclonefail_ [l=lv] {_cgiargclonecol_ kolekcija nevar tikt klonÄta. IespÄjamie cÄloÅi:
+<ul>
+<li> _cgiargclonecol_ kolekcija neeksistÄ
+<li> _cgiargclonecol_ kolekcijai nav collect.cfg konfigurÄcijas datnes
+<li> Greenstone nav atÄŒaujas lasÄ«t collect.cnf konfigurÄcijas datni.
+</ul>
+}
+
+_textcolerr_ [l=lv] {Kolektora kÄŒÅ«da.}
+
+_texttmpfail_ [l=lv] {Kolektors nojuka nolasot no vai ierakstot uz pagaidu datni vai
+direktoriju. IespÄjamie cÄloÅi ir:
+<ul>
+<li> Greenstone nav lasÄ«t/rakstÄ«t pieejas uz _gsdlhome_/tmp
+     direktoriju.
+</ul>
+}
+
+_textmkcolfail_ [l=lv] {Kolektors nojuka radot direktorijas struktÅ«ru, kura nepiecieÅ¡ama jaunai
+kolekcijai (mkcol.pl nojuka). IespÄjamie cÄloÅi ir:
+<ul>
+<li> Greenstone nav atÄŒaujas ierakstÄ«t _gsdlhome_/tmp direktorijÄ.
+<li> mkcol.pl perl skripta kÄŒÅ«das.
+</ul>
+}
+
+_textnocontent_ [l=lv] {Kolektora kÄŒÅ«da: netika nodroÅ¡inÄts nosaukums jaunai kolekcijai. MÄÄ£iniet
+restartÄjot Kolektoru no sÄkuma.}
+
+_textrestart_ [l=lv] {RestartÄt Kolektoru}
+
+_textreloaderror_ [l=lv] {KÄŒÅ«da gadÄ«jÄs jaunas kolekcijas radÄ«Å¡anÄ. Tam par cÄloni varÄja bÅ«t
+Greenstone maldinÄÅ¡ana ar jÅ«su parlÅ«kprogrammas "reload" vai 
+"back" pogu izmantoÅ¡anu (lÅ«dzu izvairieties izmantot Å¡Ä«s pogas, kamÄr
+radÄt kolekciju ar Kolektoru). Tiek rekomendÄts restartÄt Kolektoru
+no sÄkuma. 
+}
+
+_textexptsuc_ [l=lv] {_cgiargbc1dirname_ kolekcija tika sekmÄ«gi eksportÄta uz
+_gsdlhome_/tmp/exported\__cgiargbc1dirname_ direktoriju.
+}
+
+_textexptfail_ [l=lv] {<p>Neizdodas eksportÄt _cgiargbc1dirname_ kolekciju.
+
+<p>Tas varÄtu bÅ«t, ja Greenstone bija uzstÄdÄ«ts bez nepiecieÅ¡amiem
+komponentiem, kuri atbalsta "EksportÄt Kolekciju" funkciju.
+<ul>
+
+<li>Ja jÅ«s uzstÄdÄ«jÄt Greenstone no CD-ROM, Å¡ie komponenti netika uzstÄdÄ«ti
+bez to izvÄles "Custom" uzstÄdÄ«Å¡anas laikÄ.
+JÅ«s varat pievienot tos  no jauna palaiÅŸot uzstÄdÄ«Å¡anas 
+procedÅ«ru. 
+
+<li>Ja jÅ«s uzstÄdÄ«jÄt Greenstone no tÄ«mekÄŒa distribÅ«cijas, jums nepiecieÅ¡ams
+lejupielÄdÄt un uzstÄdÄ«t papildus paketi, lai atÄŒautu Å¡o funkciju. LÅ«dzu
+apmeklÄjiet <a href="http://www.greenstone.org">http://www.greenstone.org</a> vai
+sÅ«tiet uz epastu <a
+ href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>
+, lai saÅemtu vairÄk informÄcijas.
+
+</ul>
+}
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=lv] {Greenstone ir programmatÅ«ras komplekts,  kurÅ¡ domÄts, lai apkalpotu digitÄlÄs 
+bibliotÄkas kolekcijas un veidotu jaunas kolekcijas. Tas nodroÅ¡ina jaunu veidu
+informÄcijas organizÄÅ¡anai un tÄs publiskoÅ¡anai uz Interneta vai uz CD-ROM.
+Greenstone ir producÄts Waikato universitÄtÄ pÄc JaunzÄlandes DigitÄlÄs
+BibliotÄkas Projekta, un izplatÄ«ts kooperÄjoties ar UNESCO un Human Info NGO.
+TÄ ir atvÄrta-koda programmatÅ«ra un  ir pieejama uz <i>http://greenstone.org</i>
+pÄc Licences GNU General Public nosacÄ«jumiem.
+}
+
+_textgreenstone2_ [l=lv] {JunzÄlandes DigitÄlÄs BibliotÄkas webvieta (<a
+href="http://nzdl.org">http://nzdl.org</a>) satur daudzus kolekciju
+piemÄrus, visas radÄ«tas ar Greenstone programmatÅ«ru, un kuras publiski
+pieejamas jÅ«su izpÄtei. Å ie piemÄri parÄda daÅŸÄdus meklÄÅ¡anas un pÄrlÅ«koÅ¡anas
+variantus, un ietver kolekcijas arÄbu, Ä·Ä«nas, franÄu, maori, spÄÅu, kÄ arÄ«
+angÄŒu valodÄs.Tur ir arÄ« daÅŸas mÅ«zikas kolekcijas.
+}
+
+_textplatformtitle_ [l=lv] {platforma}
+_textgreenstone3_ [l=lv] {Greenstone darbojas uz Windows, Unix un Max OS X. DistribÅ«cija ietver sevÄ« gatavus
+lietoÅ¡anai binÄros kodus visÄm Windows versijÄm, kÄ arÄ« Linux un Mac OS X sistÄmÄm.
+Tas sevÄ« ietver arÄ« pilnus pirmkodus, kuri var tikt nokompilÄti izmantojot Microsoft
+C++ vai gcc. Greenstone darbojas kooperÄcijÄ ar programmatÅ«ru, kura arÄ« ir brÄ«vi
+pieejama: ar Apache Webserveri un PERL. LietotÄja interfeiss izmanto Web pÄrlÅ«kus:
+parasti Netscape vai Internet Explorer.
+}
+
+_textgreenstone4_ [l=lv] {Daudzas dokumentu kolekcijas tiek izplatÄ«tas uz CD-ROM, izmantojot Greenstone
+programmatÅ«ru. PiemÄram, <i>Humanity Development Library</i>, satur
+1 230 publikÄcijas diapazonÄ no grÄmatvedÄ«bas lÄ«dz Å«dens sanitÄrijai. Tie
+darbojas uz minimÄlas jaudas datoriem, tÄdiem , kuri parasti pieejami 
+attÄ«stÄ«bas valstÄ«s. InformÄcija var bÅ«t pieejama caur meklÄÅ¡anu, pÄrlÅ«kojot
+pÄc satura priekÅ¡meta, pÄc virsrakstiem, pÄc organizÄcijÄm, pÄrlÅ«kojot 
+pÄc 'kÄdÄ veidÄ', vai arÄ« brÄ«vi pÄrlÅ«kojot grÄmatu vÄkus.
+}
+
+_textcustomisationtitle_ [l=lv] {pieskaÅoÅ¡ana}
+_textgreenstone5_ [l=lv] {Greenstone ir speciÄli veidots, lai bÅ«tu pÄc iespÄjas paplaÅ¡inÄms un 
+pielÄgojams. Jauni dokumentu un metadatu formÄti var tikt apgÅ«ti uzrakstot
+jaunus "plugins" (PerlÄ). AnaloÄ£iski, jaunas metadatu pÄrlÅ«koÅ¡anas struktÅ«ras
+var tikt ieviestas uzrakstot "klasifikÄtorus". LietotÄja izskata-un-sajÅ«tas interfeiss var
+bÅ«t izmainÄ«ts izmantojot "macros", kuri uzrakstÄ«ti viekÄrÅ¡Ä makro valodÄ. Corba 
+protokols ÄŒauj aÄ£entiem (piem. uz Java) izmantot visas iespÄjas, kuras saistÄ«tas
+ar dokumentu kolekcijÄm. Visbeidzot, pirmkodi uz C++ un Perl ir pieejami 
+modificÄÅ¡anai.
+ }
+
+_textdocumentationtitle_ [l=lv] {dokumentÄcija}
+_textdocuments_ [l=lv] {Ir pieejama plaÅ¡a dokumentÄcija par Greenstone programmatÅ«ru.}
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=lv] {adresÄtu saraksts}
+_textmailinglist_ [l=lv] {Pieejams adresÄtu saraksts galvenokÄrt domÄts diskusijÄm
+par Greenstone digitÄlÄs bibliotÄkas programmatÅ«ru.
+AktÄ«viem Greenstone lietotÄjiem ir iespÄja pievienoties Å¡ai
+pasta sarakstei un piedalÄ«ties diskusijÄs.
+Lai pierakstÄ«tos, dodieties uz  <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+
+Lai nosÅ«tÄ«tu ziÅu uz adresÄtu sarakstu, adresÄjiet to uz  <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>.
+}
+
+_textbugstitle_ [l=lv] {defekti}
+_textreport_ [l=lv] {MÄs vÄlÄmies zinÄt, kÄ Å¡Ä« programmatÅ«ra jums darbojas. LÅ«dzu ziÅojiet par
+jebkuru kÄŒÅ«mi uz  <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>
+}
+
+_textgs3title_ [l=lv] {izstrÄde}
+_textgs3_ [l=lv] {Greenstone 3 ir pilnÄ«bÄ pÄrstrÄdÄta versija, kura ietver visas priekÅ¡rocÄ«bas no Greenstone 2 (tekoÅ¡Ä versija)--piemÄram, tÄ ir daudzvalodu, daudzplatformu,
+un stipri konfigurÄjama vide. TÄ ietver visas Ä«paÅ¡Ä«bas no eksistÄjoÅ¡as sistÄmas un
+ir atpakaÄŒ savietojama: tas ir, tÄ var veidot un uzturÄt jau  eksistÄjoÅ¡as kolekcijas bez
+to modificÄÅ¡anas. UzrakstÄ«ta uz Java, tÄ ir strukturÄta kÄ no tÄ«kla neatkarÄ«gi moduÄŒi,
+kuri komunicÄ izmantojot XML: tas ir, tÄ darbojas distributÄ«vÄ manierÄ un var bÅ«t
+izplatÄ«ta uz daÅŸÄdiem serveriem pÄc vajadzÄ«bas. ModulÄrais dizains palielina
+Greenstone elastÄ«gumu un  tÄ paplaÅ¡inÄÅ¡anas iespÄjas. DokumentÄciju un  
+Greenstone 3 izlaidumus var lejupielÄdÄt no <a href="http://www.greenstone.org/greenstone3.html">Greenstone 3 home page</a>. }  
+
+_textcreditstitle_ [l=lv] {kredÄ«ti}
+
+_textwhoswho_ [l=lv] {Greenstone programmatÅ«ra ir daudzu cilvÄku kopÄ«gu pÅ«liÅu
+rezultÄts. Rodger McNab un Stefan Boddie ir galvenie arhitekti un
+Ä«stenotÄji. Savu ieguldÄ«jumu ir devuÅ¡i David Bainbridge, George
+Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John
+McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd
+Reed, Bill Rogers, John Thompson, un Stuart Yeates. Citi JaunzÄlandes DigitÄlÄs BibliotÄkas
+projekta locekÄŒi, kuri deva padomus un iedvesmoja sistÄmas dizainÄ ir: Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te
+Taka Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols un Lloyd Smith. MÄs vÄlÄmies
+arÄ« izteikt atzinÄ«bu tiem, kuri deva ieguldÄ«jumu GNU-licences pakotnÄs, kuras iekÄŒautas Å¡ajÄ distribÅ«cijÄ:
+ MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE un XLHTML.
+}
+
+_textaboutgslong_ [l=lv] {par greenstone programmatÅ«ru}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=lv] {EsoÅ¡o lietotÄju saraksts}
+_textuser_ [l=lv] {lietotÄjs
+
+
+}
+_textas_ [l=lv] {uzskaites stÄvoklis}
+_textgroups_ [l=lv] {grupas}
+_textcomment_ [l=lv] {komentÄt}
+_textadduser_ [l=lv] {pievienot jaunu lietotÄju}
+_textedituser_ [l=lv] {labot}
+_textdeleteuser_ [l=lv] {izdzÄst}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=lv] {Labot lietotÄja informÄciju}
+_textadduser_ [l=lv] {Pievienot jaunu lietotÄju}
+
+_textaboutusername_ [l=lv] {LietotÄjvÄrdiem jÄbÅ«t no 2 lÄ«dz 30 simbolus gariem. Tie var saturÄt
+burtu un ciparu simbolus, '.', un '_' .
+}
+
+_textaboutpassword_ [l=lv] {ParolÄm jÄbÅ«t no 3 lÄ«dz 128 simbolus garÄm. TÄs var saturÄt jebkuru normÄli
+drukÄjamu ASCII rakstu simbolu.
+}
+
+_textoldpass_ [l=lv] {Ja Å¡is lauks ir tukÅ¡s, tad vecÄ parole tiks saglabÄta.}
+_textenabled_ [l=lv] {atÄŒauts}
+_textdisabled_ [l=lv] {aizliegts}
+
+_textaboutgroups_ [l=lv] {Grupas ir ar komatu nodalÄ«ti saraksti, nelieciet atstarpes (tukÅ¡umus) pÄc komatiem.
+}
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=lv] {IzdzÄst lietotÄju}
+_textremwarn_ [l=lv] {Vai jÅ«s patiesi vÄlaties pavisam izdzÄst lietotÄju <b>_cgiargumun_</b>?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=lv] {IzmainÄ«t paroli}
+_textoldpw_ [l=lv] {vecÄ parole}
+_textnewpw_ [l=lv] {jauna parole}
+_textretype_ [l=lv] {ievadiet vÄlreiz jauno paroli}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=lv] {JÅ«su parole bija sekmÄ«gi izmainÄ«ta.}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=lv] {LietotÄjvÄrds ir nepareizs.}
+_textinvalidpassword_ [l=lv] {Parole ir nepareiza.}
+_textemptypassword_ [l=lv] {LÅ«dzu ievadiet Å¡im lietotÄjam sÄkuma paroli.}
+_textuserexists_ [l=lv] {LietotÄjs jau eksistÄ, lÅ«dzu ievadiet citu lietotajvÄrdu.}
+
+_textusernameempty_ [l=lv] {LÅ«dzu ievadiet jÅ«su lietotÄjvÄrdu.}
+_textpasswordempty_ [l=lv] {Jums jÄievada jÅ«su vecÄ parole.}
+_textnewpass1empty_ [l=lv] {Ievadiet jÅ«su jauno paroli un tad atkÄrtojiet to.}
+_textnewpassmismatch_ [l=lv] {JÅ«su jaunÄs paroles abas versijas nesakrita.}
+_textnewinvalidpassword_ [l=lv] {JÅ«s ievadÄ«jÄt nepareizu paroli.}
+_textfailed_ [l=lv] {JÅ«su lietotÄjvÄrds vai parole bija nepareizi.}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=lv] {Greenstone versijas numurs }
+_textframebrowser_ [l=lv] {Lai to apskatÄ«tu, jums vajag 'frame' atÄŒautu pÄrlÅ«ku.}
+_textusermanage_ [l=lv] {LietotÄju administrÄÅ¡ana}
+_textlistusers_ [l=lv] {lietotÄju saraksts}
+_textaddusers_ [l=lv] {pievienot jaunu lietotÄju}
+_textchangepasswd_ [l=lv] {izmainÄ«t paroli}
+_textinfo_ [l=lv] {TehniskÄ informÄcija}
+_textgeneral_ [l=lv] {vispÄrÄ«ga}
+_textarguments_ [l=lv] {argumenti}
+_textactions_ [l=lv] {darbÄ«bas}
+_textbrowsers_ [l=lv] {pÄrlÅ«ki}
+_textprotocols_ [l=lv] {protokoli}
+_textconfigfiles_ [l=lv] {KonfigurÄcijas datnes}
+_textlogs_ [l=lv] {LogDatnes}
+_textusagelog_ [l=lv] {izmantoÅ¡anas log}
+_textinitlog_ [l=lv] {init log}
+_texterrorlog_ [l=lv] {kÄŒÅ«du log}
+_textadminhome_ [l=lv] {admin mÄjas lapa}
+_textreturnhome_ [l=lv] {Greenstone mÄjas lapa}
+_titlewelcome_ [l=lv] {AdministrÄÅ¡ana}
+_textmaas_ [l=lv] {Pieejamie apkalpoÅ¡anas un administrÄÅ¡anas servisi iekÄŒauj:}
+_textvol_ [l=lv] {skatÄ«t tieÅ¡saites (on-line) log datni}
+_textcmuc_ [l=lv] {radÄ«t, apkalpot un atjaunot kolekcijas}
+_textati_ [l=lv] {piekÄŒuve tehniskai informÄcijai tÄdai kÄ CGI argumenti}
+
+_texttsaa_ [l=lv] {Servisi ir pieejami izmantojot navigÄcijas joslu lapas kreisajÄ pusÄ
+}
+
+_textcolstat_ [l=lv] {Kolekcijas Statuss}
+
+_textcwoa_ [l=lv] {Kolekcijas parÄdÄ«sies tikai kÄ "izpildÄmas" (running), ja viÅu build.cfg
+datnes eksistÄ, ir lasÄmas, satur pareizu izveidoÅ¡anas datuma lauku (piem. >0),
+un ir kolekciju indeksu direktorijÄ (piem. NE veidoÅ¡anas 
+vai 'building' direktorijÄ).
+}
+
+_textcafi_ [l=lv] {noklikÅ¡Ä·iniet <i>abbrev.</i> informÄcijai par kolekciju}
+_textcctv_ [l=lv] {noklikÅ¡Ä·iniet <i>collection</i>, lai apskatÄ«tu kolekciju}
+_textsubc_ [l=lv] {ApstiprinÄt IzmaiÅas}
+_texteom_ [l=lv] {KÄŒÅ«da atverot main.cng}
+_textftum_ [l=lv] {Nojuka aktualizÄjot main.cfg}
+_textmus_ [l=lv] {main.cfg sekmÄ«gi aktualizÄta}
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=lv] {Veidot kopsavilkumu par _collectionname_ kolekciju}
+_textflog_ [l=lv] {KÄŒÅ«du reÄ£istrÄcijas datne _collectionname_ kolekcijai}
+
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=lv] {SÅªTÄªT ATSAUKSMI}  
+
+_greenstoneusabilitytext_ [l=lv] {Greenstone PielietojamÄ«ba}
+
+_textwhy_ [l=lv] {<p>NosÅ«tot Å¡o ziÅojumu ir indikÄcijas ceÄŒÅ¡, ka jÅ«s esat atraduÅ¡i tÄ«mekÄŒa lapu, kurÄ jÅ«s bijÄt novÄrojuÅ¡i kÄdas problÄmas.}  
+_textextraforform_ [l=lv] {Jums nav jÄaizpilda Å¡Ä« forma -- jebkura informÄcija palÄ«dzÄs.}
+_textprivacybasic_ [l=lv] {<p>Å is ziÅojums tikai saturÄs informÄciju par Greenstone tÄ«mekÄŒa lapu, kuru jÅ«s bijÄt skatÄ«juÅ¡i, un tehnoloÄ£iju, kuru jÅ«s bijÄt izmantojuÅ¡i to apskatot (plus jebkuru jÅ«su norÄdÄ«to papildus informÄciju).}  
+_textstillsend_ [l=lv] {Vai jÅ«s joprojÄm vÄlaties nosÅ«tÄ«t Å¡o ziÅojumu?}  
+
+_texterror_ [l=lv] {kÄŒÅ«da}
+_textyes_ [l=lv] {JÄ}  
+_textno_ [l=lv] {NÄ}  
+_textclosewindow_ [l=lv] {AizvÄrt Logu}  
+_textabout_ [l=lv] {Par}
+_textprivacy_ [l=lv] {PrivÄti}
+_textsend_ [l=lv] {NosÅ«tÄ«t}
+_textdontsend_ [l=lv] {NesÅ«tÄ«t}  
+_textoptionally_ [l=lv] {NeobligÄti}  
+
+_textunderdev_ [l=lv] {DetaÄŒu priekÅ¡skatÄ«jums bÅ«s pieejams gala versijÄ.}  
+
+_textviewdetails_ [l=lv] {SkatÄ«t ziÅojuma detaÄŒas}  
+_textmoredetails_ [l=lv] {DetalizÄtÄk}  
+_texttrackreport_ [l=lv] {Izsekot Å¡o ziÅojumu}  
+_textcharacterise_ [l=lv] {KÄda veida problÄma tÄ ir}  
+_textseverity_ [l=lv] {Cik smaga ir Å¡Ä« problÄma}  
+ 
+_textbadrender_ [l=lv] {Lapa izskatÄs dÄ«vaina}  
+_textcontenterror_ [l=lv] {Satura kÄŒÅ«da}  
+_textstrangebehaviour_ [l=lv] {DÄ«vaina uzvedÄ«ba}  
+_textunexpected_ [l=lv] {Notika kaut kas neparedzÄts}  
+_textfunctionality_ [l=lv] {GrÅ«ti izmantot}  
+_textother_ [l=lv] {Citi}  
+
+_textcritical_ [l=lv] {Kritisks}  
+_textmajor_ [l=lv] {Nopietna}  
+_textmedium_ [l=lv] {VidÄja}  
+_textminor_ [l=lv] {MazsvarÄ«ga}  
+_texttrivial_ [l=lv] {TriviÄli}  
+
+_textwhatdoing_ [l=lv] {Ko jÅ«s bijÄt mÄÄ£inÄjuÅ¡i darÄ«t?}  
+_textwhatexpected_ [l=lv] {Ko jÅ«s sagaidÄ«jÄt lai notiktu?}  
+_textwhathappened_ [l=lv] {Kas patiesÄ«bÄ notika?}  
+
+_cannotfindcgierror_ [l=lv] {<h2>Atvainojiet!</h2>Nevaru atrast servera  programmas "Es vÄlÄtos sÅ«dzÄties" pogai.}  
+
+_textusabbanner_ [l=lv] {Greenstone koru-stila baneris}
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+
+_textgtierror_ [l=lv] {AtgadÄ«jusies kÄŒÅ«da}  
+
+_textgtihome_ [l=lv] {Å Ä«s lapas palÄ«dz jums uzlabot Greenstone sveÅ¡valodu atbalstu. Izmantojot tÄs,
+JÅ«s varat
+<ul> 
+ <li>tulkot Greenstone daÄŒas citÄ valodÄ
+ <li>atjauninÄt esoÅ¡o valodas interfeisu, parÄdoties jaunÄm Greenstone iespÄjÄm
+ <li>labot kÄŒÅ«das eksistÄjoÅ¡Ä tulkojumÄ
+</ul>
+
+Jums tiks uzrÄdÄ«tas virkne web lapu, kur katra saturÄs tulkojamÄs frÄzes.
+Jums jÄveic valodas interfeisa tulkoÅ¡ana frÄze pÄc frÄzes.
+Daudzas frÄzes satur HTML formatÄÅ¡anas komandas: jums tÄs nav jÄtulko,
+bet jÄatstÄj bez izmaiÅÄm iztulkotÄ teksta versijÄ. VÄrdi ieskauti ar pasvÄ«trojuma simbolu (kÄ piemÄram, _this_) arÄ« nav jÄtulko, jo tie ir Greenstone makro vÄrdi.
+<p>
+Ja jÅ«s atjauninÄt eksistÄjoÅ¡o tulkojumu, tad jums netiks atrÄdÄ«tas frÄzes, kurÄm jau eksistÄ tulkojums. DaÅŸreiz, ja tulkojums eksistÄ, bet angÄŒu valodas teksts ticis mainÄ«ts, tad tulkotÄs frÄzes tiks parÄdÄ«tas un jums tÄs ir jÄpÄrbauda un jÄkoriÄ£Ä, ja 
+ir nepiecieÅ¡ams.
+<p>
+Katra lapa beidzas ar "_textgtisubmit_" pogu.  Kad jÅ«s to nospieÅŸat, tad izmaiÅas tiek saglabÄtas atseviÅ¡Ä·Ä Greenstone instalÄcijas vietÄ uz nzdl.org. 
+}  
+
+_textgtiselecttlc_ [l=lv] {LÅ«dzu izvÄlieties jÅ«su valodu}  
+
+_textgtiselecttfk_ [l=lv] {LÅ«dzu izvÄlieties datni ar kuru strÄdÄt}  
+
+_textgticoredm_ [l=lv] {Greenstone Interfeiss (Pamatmakrodatne)}  
+_textgtiauxdm_ [l=lv] {Greenstone Interfeiss (PalÄ«gmakrodatne)}  
+_textgtiglidict_ [l=lv] {GBI VÄrdnÄ«ca}  
+_textgtiglihelp_ [l=lv] {GBI PalÄ«gs}  
+_textgtiperlmodules_ [l=lv] {Perl ModuÄŒi}  
+_textgtitutorials_ [l=lv] {MÄcÄ«bu VingrinÄjumi}  
+_textgtigreenorg_ [l=lv] {Greenstone.org}  
+
+_textgtienter_ [l=lv] {IEIET}  
+
+_textgticorrectexistingtranslations_ [l=lv] {KoriÄ£Ät esoÅ¡os tulkojumus}  
+_textgtidownloadtargetfile_ [l=lv] {LejupielÄdÄt datni}  
+_textgtiviewtargetfileinaction_ [l=lv] {SkatÄ«t Å¡o datni darbÄ«bÄ}  
+
+_textgtinumchunksmatchingquery_ [l=lv] {Teksta fragmentu skaits, kuri atbilst pieprasÄ«jumam}  
+
+_textgtinumchunkstranslated_ [l=lv] {tulkojumi veikti}  
+_textgtinumchunksrequiringupdating_ [l=lv] {No tiem, _1_ prasa atjauninÄÅ¡anu}  
+_textgtinumchunksrequiringtranslation_ [l=lv] {tukojumi atlikuÅ¡i}  
+
+_textgtienterquery_ [l=lv] {Ievadiet vÄrdu vai frÄzi no teksta fragmenta, kuru jÅ«s gribat labot}  
+_textgtifind_ [l=lv] {MEKLÄT}  
+
+_textgtitranslatingchunk_ [l=lv] {TulkojamÄ teksta fragments <i>_1_</i>}  
+_textgtiupdatingchunk_ [l=lv] {Teksta fragmenta <i>_1_</i> atjauninÄÅ¡ana}  
+_textgtisubmit_ [l=lv] {IESNIEGT}  
+
+_textgtilastupdated_ [l=lv] {PÄdÄjo reizi atjaunots}  
+
+_textgtitranslationfilecomplete_ [l=lv] {Pateicamies par datnes atjauninÄÅ¡anu -- tÄ nu ir pabeigta!<p>JÅ«s varat lejupielÄdÄt Å¡Ä«s datnes kopiju izmantojot saiti augÅ¡Ä, un tÄ arÄ« tiks iekÄŒauta nÄkmajos Greenstone izlaidumos.}  
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=lv] {greenstone bibliotekÄra interfeiss}
+_textglihelp_ [l=lv] {Greenstone BibliotekÄra Interfeiss (Greenstone Librarian Interface) jeb GLI dot iespÄju
+izmantot vienkÄrÅ¡i lietojamu Greenstone interfeisu. Ar to jÅ«s varat veidot dokumentu kolekciju, importÄt vai pieÅ¡Ä·irt metadatus kolekcijai.
+<p>
+JÄuzsver, ka GLI darbojas kopÄ ar Greenstone, un tam jÄbÅ«t uzinstalÄtam  Greenstone istalÄcijas apakÅ¡direktorijÄ.
+Ja jÅ«s esat uzinstalÄjuÅ¡i kÄdu no lejupielÄdÄtÄm Greenstone distribÅ«cijÄm, vai uzinstalÄjÄt to no Greenstone CD-ROM, tad Å¡is 
+nosacÄ«jums tiks izpildÄ«ts.
+
+
+<h4>GLI palaiÅ¡ana zem Windows</h4>
+
+Palaist GLI zem Windows var secÄ«gi izvÄloties no izvÄlnes <i>Start</i> , <i>Programs</i> , <i>Greenstone Digital Library</i> un
+beidzot izvÄlni  <i>Greenstone Librarian Interface</i>.
+
+
+<h4>GLI palaiÅ¡ana zem Unix</h4>
+
+Lai palaistu GLI zem Unix sistÄmas, ieejiet Greenstone instalÄcijas direktorijÄ, un ieejiet apakÅ¡direktorijÄ <i>gli</i>.
+Tad palaidiet <i>gli.sh</i> skriptu.
+
+<h4>GLI  palaiÅ¡ana zem Mac OS</h4>
+
+MeklÄtÄjÄ pÄrlÅ«kojiet <i>Applications</i>, tad <i>Greenstone</i>
+(ja jÅ«s uzinstalÄjÄt Greenstone vietÄ pÄc noklusÄÅ¡anas), un tad
+palaidiet <i>GLI</i> aplikÄciju.
+}
Index: /gsdl/stable/macros/malayalam.dm
===================================================================
--- /gsdl/stable/macros/malayalam.dm	(revision 20131)
+++ /gsdl/stable/macros/malayalam.dm	(revision 20131)
@@ -0,0 +1,818 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Malayalam Language text and icon macros, translated from English.dm on
+# 31st of January, 2007 by Mr. Sanjo Jose, Information and Knowledge Management 
+# Course  Trainee (2007-2008), National Centre for Science Information, Indian Institute of 
+# Science, Bangalore 560 012, Karnataka, India.) under the guidance of 
+# Ms.Anuradha.K.T., Senior Technical Officer, National Centre for Science Information, 
+# Indian Institute of Science, Bangalore 560 012, Karnataka, India.
+# àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽžàµàŽ«àµàŽ±àµàŽ±àµàŽµàµàŽ±àŽ¿àŽšàµâàŽ±àµàŽ àŽ€àŽ°àµâàŽàµàŽàŽ® 
+# àŽšàŽ¿àŽ°àµâàŽµàŽ¹àŽ¿àŽàµàŽàŽ¿àŽ°àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµ 
+# àŽžàŽŸàŽšàµâàŽàµ àŽàµàŽžàµ.2006-àŽ²àµâ àŽàµàŽ°àŽ³ àŽžàŽ°àµâàŽµàµàŽµàŽàŽ²àŽŸàŽ¶àŽŸàŽ²àŽ¯àŽ¿àŽ²àµâàŽšàŽ¿àŽšàµàŽšàµ  àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ 
+# àŽàŽšàµâàŽ±àµ  
+#
+#######################################################################
+
+#######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=ml] {àŽàŽšàµàŽàŽŸàŽ²àŽ¿àŽàŽàµàŽàŽ³àµâ}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=ml] {àŽàŽ§àŽŸàŽ°àŽžàµàŽàŽàŽ}  
+_textdate_ [l=ml] {àŽªàµàŽ°àŽžàŽŸàŽ§àŽš àŽµàŽ°àµâàŽ·àŽ}  
+_textnumpages_ [l=ml] {àŽªàµàŽàµàŽàŽ³àµàŽàµ àŽàŽ£àµàŽ£àŽ}  
+
+_textsignin_ [l=ml] {àŽ
+àŽàŽ¯àŽŸàŽ³àŽ àŽšàŽ²àµàŽàµàŽ}  
+
+_textdefaultcontent_ [l=ml] {àŽàŽµàŽ¶àµàŽ¯àŽ®àŽŸàŽ¯ àŽªàµàŽàµ àŽàŽŸàŽ£àŽŸàŽšàŽ¿àŽ²àµàŽ². àŽŠàŽ¯àŽµàŽŸàŽ¯àŽ¿ àŽ¬àµàŽ°àµàŽžàŽ±àŽ¿àŽ²àµ àŽªàŽ¿àŽšàµàŽšàµàŽàµàŽàµàŽªàµàŽµàŽŸàŽšàµàŽ³àµàŽ³ 'back' àŽ¬àŽàµàŽàŽ£àµ  àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽàŽ¯àµ àŽ®àµàŽàŽ³àŽ¿àŽ²àµ àŽšàŽ²àµàŽàŽ¿àŽ¯àŽ¿àŽàµàŽàµàŽ³àµàŽ³ àŽ¹àµàŽ àŽ¬àŽàµàŽàŽ£àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿àŽ¯àŽ¿àŽ²àµàŽàµàŽàµ àŽªàµàŽµàµàŽ}  
+
+_textdefaulttitle_ [l=ml] {àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àµâ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽžàµàŽ«àµâàŽ±àµàŽ±àµâ àŽµàµàŽ¯àŽ±àŽ¿àŽ²àµ àŽ€àµàŽ±àµàŽ±àµâ}  
+
+_textbadcollection_ [l=ml] {"_cvariable_' àŽàŽšàµàŽš àŽ¶àµàŽàŽ°àŽ àŽ àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽžàŽàŽµàŽ¿àŽ§àŽŸàŽšàŽ€àµàŽ€àŽ¿àŽ²àµ àŽàŽ²àµàŽ²}  
+
+_textselectpage_ [l=ml] {àŽªàµàŽàµâ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽàµàŽàµàŽ}  
+
+_collectionextra_ [l=ml] {àŽ àŽ¶àµàŽàŽ°àŽ............. àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµâ àŽàŽ³àµâàŽàµàŽàµàŽ³àµàŽ³àµàŽšàµàŽšàµ. àŽ
+àŽ€àµâ àŽ
+àŽµàŽžàŽŸàŽšàŽ®àŽŸàŽ¯àŽ¿........... àŽŠàŽ¿àŽµàŽžàŽàµàŽàŽ³àµâàŽàµàŽàµ àŽ®àµàŽšàµâàŽªàµ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàŽ€àŽŸàŽ£àµâ }  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=ml] {<p>àŽ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµâ_numdocs_ _If_("_numdocs_" eq "1",document,documents), a total of _numbytes_ of indexed text and metadata.
+<p><a href="_httppagex_(bsummary)">àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽžàŽàŽàµàŽ·àŽ¿àŽªàµâàŽ€ àŽµàŽ¿àŽµàŽ°àŽ£àŽ àŽàŽŸàŽ£àŽŸàŽšàŽŸàŽ¯àŽ¿ àŽàŽµàŽ¿àŽàµ àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµàŽ¯àµàŽ</a>}  
+
+_textdescrcollection_ [l=ml] {}  
+_textdescrabout_ [l=ml] {àŽªàµàŽàµàŽžàŽàŽ¬àŽšàµàŽ§àŽ¿àŽàµàŽ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµ}  
+_textdescrhome_ [l=ml] {àŽ¹àµàŽàŽªàµàŽàµ}  
+_textdescrhelp_ [l=ml] {àŽžàŽ¹àŽŸàŽ¯àŽ}  
+_textdescrpref_ [l=ml] {àŽ®àµàŽšàµâàŽàŽ£àŽšàŽŸàŽªàµàŽàµâ}  
+_textdescrgreenstone_ [l=ml] {àŽàµàŽ°àµàµ»àŽžàµàŽ±àµàŽ±àµàŽ£àµâ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽžàµàŽ«àµâàŽ±àµàŽ±àµâ àŽµàµàŽ¯àŽ°àµâ}  
+_textdescrusab_ [l=ml] {àŽàŽšàµàŽ€àŽŸàŽ£àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽ²àµâ àŽªàµàŽ°àŽ¯àŽŸàŽžàŽ®àµàŽ³àŽµàŽŸàŽàµàŽàµàŽšàµàŽšàŽ€àµâ}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµâ}  
+_labelSearch_ [l=ml] {àŽ€àŽ¿àŽ°àŽ¯àµàŽ}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=ml] {àŽ€àŽ²àŽµàŽŸàŽàŽàŽ}  
+_labelTitle_ [l=ml] {àŽ¶àµàŽ°àµàŽ·àŽàŽ}  
+_textCreator_ [l=ml] {àŽ°àŽàŽ¯àŽ¿àŽ€àŽŸàŽµàµ}  
+_labelCreator_ [l=ml] {àŽàµàŽ°àŽšàµàŽ¥àŽàŽ°àµàŽ€àµàŽ€àŽŸàŽµàµ}  
+_textSubject_ [l=ml] {àŽµàŽ¿àŽ·àŽ¯àŽ}  
+_labelSubject_ [l=ml] {àŽµàŽ¿àŽ·àŽ¯àŽàµàŽàŽ³àµ}  
+_textDescription_ [l=ml] {àŽµàŽ¿àŽµàŽ°àŽ£àŽ}  
+_labelDescription_ [l=ml] {àŽµàŽ¿àŽµàŽ°àŽ£àŽ}  
+_textPublisher_ [l=ml] {àŽªàµàŽ°àŽžàŽŸàŽ§àŽàŽšàµ}  
+_labelPublisher_ [l=ml] {àŽªàµàŽ°àŽžàŽŸàŽ§àŽàŽšàµâ}  
+_textContributor_ [l=ml] {àŽžàŽàŽ­àŽŸàŽµàŽšàŽàµàŽ¯àµàŽ€àŽ¯àŽŸàŽ³àµ}  
+_labelContributor_ [l=ml] {àŽžàŽ¹àŽŸàŽ¯àŽ¿àŽàŽ³àµ}  
+_textDate_ [l=ml] {àŽ€àµàŽ¯àµàŽ¯àŽ€àŽ¿}  
+_labelDate_ [l=ml] {àŽ€àµàŽ¯àŽ€àŽ¿}  
+_textType_ [l=ml] {àŽ°àµàŽªàŽ}  
+_labelType_ [l=ml] {àŽ°àµàŽªàŽàµàŽàŽ³àµ}  
+_textFormat_ [l=ml] {àŽ°àµàŽªàŽàŽàŽš}  
+_labelFormat_ [l=ml] {àŽ°àµàŽªàŽàŽàŽšàŽàŽ³àµ}  
+_textIdentifier_ [l=ml] {àŽ€àŽ¿àŽ°àŽ¿àŽàµàŽàŽ±àŽ¿àŽ¯àŽ²àŽ¿àŽšàµàŽ³àµàŽ³àŽ€àµâ}  
+_labelIdentifier_ [l=ml] {àŽµàµàŽ°àµàŽ€àŽ¿àŽ°àŽ¿àŽàµàŽàŽŸàŽšàµàŽ³àµàŽ³àŽµ}  
+_textSource_ [l=ml] {àŽ«àŽ¯àŽ²àŽ¿àŽšàµàŽ±àµ àŽªàµàŽ°àµâ}  
+_labelSource_ [l=ml] {àŽ«àŽ¯àŽ²àµàŽšàŽŸàŽ®àŽàµàŽàŽ³àµ}  
+_textLanguage_ [l=ml] {àŽ­àŽŸàŽ·àŽàŽ³àµ}  
+_labelLanguage_ [l=ml] {àŽ­àŽŸàŽ·àŽàŽ³àµ}  
+_textRelation_ [l=ml] {àŽ¬àŽšàµàŽ§àŽ}  
+_labelRelation_ [l=ml] {àŽ¬àŽšàµàŽ§àŽàµàŽàŽ³àµ}  
+_textCoverage_ [l=ml] {àŽµàµàŽ¯àŽŸàŽªàµâàŽ€àŽ¿}  
+_labelCoverage_ [l=ml] {àŽµàµàŽ¯àŽŸàŽªàµàŽ€àŽ¿}  
+_textRights_ [l=ml] {àŽ
+àŽµàŽàŽŸàŽ¶àŽàµàŽàŽ³àµ}  
+_labelRights_ [l=ml] {àŽ
+àŽµàŽàŽŸàŽ¶àŽàµàŽàŽ³àµâ}  
+
+# DLS metadata set
+_textOrganization_ [l=ml] {àŽžàµàŽ¥àŽŸàŽªàŽšàŽ}  
+_labelOrganization_ [l=ml] {àŽžàµàŽ¥àŽŸàŽªàŽšàŽàµàŽàŽ³àµâ}  
+_textKeyword_ [l=ml] {àŽµàŽ¿àŽ·àŽ¯àŽžàµàŽàŽ àŽªàŽŠàŽàµàŽàŽ³àµâ}  
+_labelKeyword_ [l=ml] {àŽžàµàŽàŽàŽªàŽŠàŽàµàŽàŽ³àµ}  
+_textHowto_ [l=ml] {àŽàŽàµàŽàŽ¿àŽšàµ}  
+_labelHowto_ [l=ml] {àŽàŽàµàŽàŽ¿àŽšàµ}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=ml] {àŽªàŽŠàŽŸàŽµàŽ²àŽ¿}  
+_labelPhrase_ [l=ml] {àŽªàŽŠàŽžàŽ®àµàŽàµàŽàŽ¯àŽ}  
+_textCollage_ [l=ml] {àŽàµàŽ³àŽŸàŽ·àµ}  
+_labelCollage_ [l=ml] {àŽàµàŽ³àŽŸàŽ·àµâ}  
+_textBrowse_ [l=ml] {àŽ¬àµàŽ°àµàŽžàµ àŽàµàŽ¯àµàŽ¯àµàŽ}  
+_labelBrowse_ [l=ml] {àŽ¬àµàŽ°àµàŽžàµâ àŽàµàŽ¯àµàŽ¯àµàŽ}  
+_textTo_ [l=ml] {àŽ®àŽ±àµàŽ±àµàŽšàµàŽšàŽ¿àŽ²àµàŽàµàŽàµ}  
+_labelTo_ [l=ml] {àŽ²àµàŽ¯àµàŽàµàŽàµ}  
+
+_labelFrom_ [l=ml] {àŽ€àµàŽàŽàµàŽàŽ}  
+_textAcronym_ [l=ml] {àŽàµàŽ°àµàŽàµàŽàµàŽŽàµàŽ€àµàŽ€àµ}  
+_labelAcronym_ [l=ml] {àŽàµàŽ°àµàŽàµàŽàµàŽŽàµàŽ€àµàŽ€àµâ}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=ml] {_1_ àŽµàŽàµàŽàµ àŽ€àŽ¿àŽ°àŽ¯àµàŽ}  
+
+_textdescrSearch_ [l=ml] {àŽªàµàŽ°àŽ€àµàŽ¯àµàŽàŽªàŽŠàŽàµàŽàŽ³àµàŽàµàŽàŽŸàŽ¯àŽ¿ àŽ€àŽ¿àŽ°àŽ¯àµàŽ}  
+_textdescrType_ [l=ml] {àŽµàŽ¿àŽ­àŽµàŽŸàŽšàµàŽžàµàŽ€ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ}  
+_textdescrIdentifier_ [l=ml] {àŽµàŽ¿àŽ·àŽ¯àŽ àŽ€àŽ¿àŽ°àŽ¿àŽàµàŽàŽ±àŽ¿àŽ¯àŽŸàŽšàµâàŽªàŽ±àµàŽ±àµàŽšàµàŽšàŽ€àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ³àµàŽ³ àŽ¬àµàŽ°àµàŽžàŽ¿àŽàµàŽàµâ}  
+_textdescrSource_ [l=ml] {àŽ¶àŽ°àŽ¿àŽ¯àŽŸàŽ¯ àŽ«àŽ¯àŽ²àµàŽšàŽŸàŽ®àŽ àŽàµàŽ£àµàŽàµ àŽªàŽ°àŽ¿àŽ¶àµàŽ§àŽ¿àŽàµàŽàµàŽ}  
+_textdescrTo_ [l=ml] {àŽ«àµàŽ²àµàŽ¡àµàŽªàµàŽ°àŽàŽŸàŽ°àŽ àŽ¬àµàŽ°àµàŽžàµàŽàµàŽ¯àµàŽ¯àµàŽ}  
+
+_textdescrCollage_ [l=ml] {àŽàµàŽ³àŽŸàŽ·àµ àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽšàŽ®àŽŸàŽàµàŽàŽ¿àŽ¯àµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ}  
+_textdescrAcronym_ [l=ml] {àŽàµàŽ°àµàŽàµàŽàŽªàµàŽªàµàŽ°àµàŽšàµàŽàµàŽàµàŽ}  
+_textdescrPhrase_ [l=ml] {àŽµàŽŸàŽàµàŽ¯àŽàµàŽàŽ³àµâ àŽµàŽàµàŽàµâ àŽ€àŽ¿àŽ°àŽ¯àµàŽ}  
+_textdescrHowto_ [l=ml] {àŽàŽàµàŽàŽšàµ àŽ  àŽ¶àµàŽàŽ°àŽ àŽ¬àµàŽ°àµàŽžàµ àŽàµàŽ¯àµàŽ¯àŽŸàŽ}  
+_textdescrBrowse_ [l=ml] {àŽ¬àµàŽ°àµàŽžàµâ àŽàµàŽ¯àµàŽ¯àµàŽ}  
+_texticontext_ [l=ml] {àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ àŽàŽŸàŽ£àµàŽ}  
+_texticonclosedbook_ [l=ml] {àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ àŽ€àµàŽ±àŽšàµàŽšàµâ àŽàŽ³àµàŽ³àŽàŽàµàŽàŽ àŽàŽŸàŽ£àµàŽ}  
+_texticonnext_ [l=ml] {àŽ
+àŽàµàŽ€àµàŽ€àŽ€àŽ¿àŽ²àµàŽ¯àµàŽàµàŽàµ}  
+_texticonprev_ [l=ml] {àŽ®àµàŽ®àµàŽªàŽ¿àŽ²àŽ€àµàŽ€àµàŽ€àµâ}  
+
+_texticonworld_ [l=ml] {àŽµàµàŽ¬àµ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ àŽàŽŸàŽ£àµàŽ}  
+
+_texticonmidi_ [l=ml] {àŽàŽ.àŽ.àŽ¡àŽ¿.àŽ àŽ°àµàŽ àŽàŽŸàŽ£àµàŽ}  
+_texticonmsword_ [l=ml] {àŽ®àµàŽàµàŽ°àµàŽŸàŽžàµàŽ«àµâàŽ±àµàŽ±àµâ àŽµàµàŽ°àµâàŽ¡àŽ¿àŽ²àµàŽ³àµàŽ³ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ àŽàŽŸàŽ£àµàŽ}  
+_texticonmp3_ [l=ml] {àŽàŽ.àŽªàŽ¿.3 àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ àŽàŽŸàŽ£àµàŽ}  
+_texticonpdf_ [l=ml] {àŽªàµàŽ¡àŽ¿àŽ¯àµàŽ«àµ àŽàµàŽ°àŽšàµàŽ¥àŽ àŽàŽŸàŽ£àµàŽ}  
+_texticonps_ [l=ml] {àŽªàµàŽšàŽ°àµâàŽ²àŽ¿àŽàŽ¿àŽ€ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ àŽàŽŸàŽ£àµàŽ}  
+_texticonppt_ [l=ml] {àŽªàŽµ àŽªàµàŽ¯àŽ¿àŽšàµàŽ±àµ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµ àŽàŽŸàŽ£àµàŽ}  
+_texticonrtf_ [l=ml] {àŽàŽ°àµâàŽàŽ¿àŽàŽ«àµâ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ}  
+_texticonxls_ [l=ml] {àŽ®àµàŽàµàŽ°àµàŽŸàŽžàµàŽ«àµàŽ±àµàŽ±àµ àŽàŽàµàŽžàŽ²àµ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ àŽàŽŸàŽ£àµàŽ}  
+
+_page_ [l=ml] {àŽªàµàŽàµ}
+_pages_ [l=ml] {àŽªàµàŽàµàŽàŽ³àµ}  
+_of_ [l=ml] {àŽšàµâàŽ±àµ}
+_vol_ [l=ml] {àŽµàŽŸàŽ²àµàŽ¯àŽ}  
+_num_ [l=ml] {àŽ²àŽàµàŽàŽ}  
+
+_textmonth00_ [l=ml] {}
+_textmonth01_ [l=ml] {àŽàŽšàµàŽµàŽ°àŽ¿}  
+_textmonth02_ [l=ml] {àŽ«àµàŽ¬àµàŽ°àµàŽµàŽ°àŽ¿}
+_textmonth03_ [l=ml] {àŽ®àŽŸàŽ°àµâàŽàµàŽàµâ}  
+_textmonth04_ [l=ml] {àŽàŽªàµàŽ°àŽ¿àŽ²àµâ}
+_textmonth05_ [l=ml] {àŽ®àµàŽ¯àµ}  
+_textmonth06_ [l=ml] {àŽàµàŽ£àµâ}
+_textmonth07_ [l=ml] {àŽàµàŽ²àµ}  
+_textmonth08_ [l=ml] {àŽàŽàŽžàµàŽ±àµàŽ±àµ}
+_textmonth09_ [l=ml] {àŽžàŽªàµàŽ±àµàŽ±àŽàŽ¬àŽ°àµ}  
+_textmonth10_ [l=ml] {àŽàŽàµàŽàµàŽ¬àŽ°àµâ}  
+_textmonth11_ [l=ml] {àŽšàŽµàŽàŽ¬àŽ°àµâ}  
+_textmonth12_ [l=ml] {àŽ¡àŽ¿àŽžàŽàŽ¬àŽ°àµâ}  
+
+
+_labeltext_ [l=ml] {_texttext_}  
+_textdocument_ [l=ml] {àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ}  
+_textsection_ [l=ml] {àŽ­àŽŸàŽàŽ}  
+_textparagraph_ [l=ml] {àŽàŽ£àµàŽ¡àŽ¿àŽ}  
+
+
+
+_magazines_ [l=ml] {àŽ®àŽŸàŽàŽžàµàŽšàµàŽàŽ³àµ}  
+
+_nzdlpagefooter_ [l=ml] {<div class="divbar"> </div> 
+<p><a href="http://www.nzdl.org">àŽšàµàŽ¯àµàŽžàµàŽ²àŽŸàŽšàµàŽ±àµ  àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽªàµàŽ°àµàŽàŽàµàŽ±àµàŽ±àµ</a> 
+<br><a href="http://www.cs.waikato.ac.nz"> àŽ¡àŽ¿àŽªàµàŽªàŽŸàŽ°àµàŽàµàŽàµàŽ®àµàŽšàµàŽ±àµ  àŽàŽ«àµ  àŽàŽ®àµàŽªàµàµàŽàµàŽàŽ°àµ àŽžàŽ¯àŽšàµàŽžàµ 
+</a>, <a href="http://www.waikato.ac.nz"> àŽ¯àµàŽ£àŽ¿àŽµàµàŽŽàµàŽžàŽ¿àŽ±àµàŽ±àŽ¿ àŽàŽ«àµ  àŽµàµàŽàŽŸàŽ±àµàŽ±àµ 
+</a>, àŽšàµàŽ¯àµàŽžàµàŽ²àŽŸàŽšàµàŽ±àµ}  
+
+_linktextHOME_ [l=ml] {àŽ¹àµàŽ àŽªàµàŽàµ}  
+_linktextHELP_ [l=ml] {àŽžàŽ¹àŽŸàŽ¯àŽ}  
+_linktextPREFERENCES_ [l=ml] {àŽ®àµàŽšàµàŽàŽ£àŽš}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿}  
+
+_textnocollections_ [l=ml] {àŽàŽ°àµ àŽ¶àµàŽàŽ°àŽµàµàŽ àŽ²àŽ­àµàŽ¯àŽ®àŽ²àµàŽ²}  
+
+_textadmin_ [l=ml] {àŽšàŽ¿àŽ¯àŽšàµàŽ€àµàŽ°àŽ£ àŽªàµàŽàµâ}  
+_textabgs_ [l=ml] {àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµàŽªàŽ±àµàŽ±àŽ¿}  
+_textgsdocs_ [l=ml] {àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àµâ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµâ}  
+
+_textdescradmin_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽµàŽ¿àŽšàµ àŽàŽ³àµàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽŸàŽšàµ àŽ
+àŽšàµàŽµàŽŠàŽ¿àŽàµàŽàµàŽšàµàŽšàµ, àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµàŽàµ àŽžàŽàŽàµàŽ·àŽ¿àŽªàµàŽ€àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµàŽ àŽšàŽ²àµàŽàµàŽšàµàŽšàµ. àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽàŽšàµàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµàŽ·àŽšàµàŽ±àµ àŽžàŽŸàŽàµàŽàµàŽ€àŽ¿àŽ àŽàŽŸàŽ°àµàŽ¯àŽàµàŽàŽ³àµàŽ àŽšàŽ²àµàŽàµàŽšàµàŽšàµ.}  
+
+_textdescrgogreenstone_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽªàµàŽ°àŽàŽàµàŽàµàŽ àŽšàµàŽ¯àµàŽžàŽ¿àŽ²àŽŸàŽšàµàŽ±àµ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽªàµàŽ°àµàŽŸàŽàŽàµàŽàµàŽ àŽàŽµàŽ¿àŽàµ àŽšàŽ¿àŽšàµàŽšàµ àŽ€àµàŽàŽàµàŽàŽ àŽàµàŽ±àŽ¿àŽàµàŽàµàŽµàµàŽšàµàŽšàµ àŽªàŽ±àŽ¯àµàŽšàµàŽš}  
+
+_textdescrgodocs_ [l=ml] {àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽàµàŽªàµàŽªàµàŽžàµàŽ€àŽàŽàµàŽàŽ³àµ}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=ml] {àŽ²àµàŽ¬àµàŽ°àµàŽ±àŽ¿àŽ¯àŽšàµâ àŽàŽšàµàŽ±àŽ°àµâàŽ«àµàŽ¯àµâàŽžàµâ}  
+_textdescrgli_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ àŽ¶àµàŽàŽ°àŽ àŽàŽ£àµàŽàŽŸàŽàµàŽàŽŸàŽšàµ àŽ®àŽŸàŽ±àµàŽ±àŽ àŽµàŽ°àµàŽ€àµàŽ€àŽŸàŽšàµ, àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³àŽ€àŽ¿àŽšàµàŽàµâ àŽàµàŽàµàŽàŽ¿àŽàµàŽàµàŽ°àµâàŽàµàŽàŽŸàŽšàµ, àŽšàµàŽàµàŽàŽàŽàµàŽ¯àµàŽ¯àŽŸàŽšàµ àŽžàŽ¹àŽŸàŽ¯àŽ¿àŽàµàŽàµàŽ}  
+
+package collector
+
+_textcollector_ [l=ml] {àŽàŽ³àŽàµàŽàŽ°àµ}  
+_textdescrcollector_ [l=ml] {àŽàŽ€àµ àŽ²àµàŽ¬àµàŽ°àµàŽ±àŽ¿àŽ¯àŽšàµ àŽàŽšàµàŽ±àŽ°àµàŽ«àµàŽ¯àŽ¿àŽžàŽ¿àŽšàµàŽ®àµàŽšàµàŽªàµàŽ³àµàŽ³àŽ€àŽŸàŽ£àµ. àŽªàŽàŽ°àŽ®àŽŸàŽ¯àŽ¿ àŽ²àµàŽ¬àµàŽ°àµàŽ±àŽ¿àŽ¯àŽšàµ àŽàŽšàµàŽ±àŽ°àµàŽ«àµàŽ¯àµàŽžàµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ}  
+
+package depositor
+
+_textdepositor_ [l=ml] {àŽ¡àŽ¿àŽªàµàŽªàµàŽžàŽ¿àŽ±àµàŽ±àŽ°àµ}  
+_textdescrdepositor_ [l=ml] {àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽàµàŽ°àŽšàµàŽ¥àŽàµàŽàŽ³àµ àŽàµàŽ°àµàŽàµàŽàŽŸàŽšàµ àŽžàŽ¹àŽŸàŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽšàµ}  
+
+package gti
+
+_textgti_ [l=ml] {àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àµâ àŽ­àŽŸàŽ·àŽŸ àŽªàŽ°àŽ¿àŽµàŽ°àµâàŽ€àµàŽ€àŽš àŽžàŽ¹àŽŸàŽ¯àŽ¿}  
+_textdescrtranslator_ [l=ml] {àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµàŽ±àµ àŽ¬àŽ¹àµàŽ­àŽŸàŽ·àŽŸàŽ°àµàŽªàŽàµàŽàŽ³àµâ àŽàµàŽ€àµàŽ¯àŽ®àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽŸàŽšàµâ àŽžàŽ¹àŽŸàŽ¯àŽ¿àŽàµàŽàµàŽ}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=ml] {àŽ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àµàŽàµàŽàµàŽ±àŽ¿àŽàµàŽàµâ}  
+
+_textsubcols1_ [l=ml] {<p>àŽ  àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿ àŽ²àµâ
+ _1_ àŽàŽªàŽ¶àµàŽàŽ°àŽ àŽàŽ³àµâ
+àŽàµàŽàµàŽ³àµàŽ³àµàŽšàµàŽšàµ:
+<blockquote>}  
+
+_textsubcols2_ [l=ml] {</blockquote>àŽ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµ àŽàŽ€àµ àŽàŽªàŽ¶àµàŽàŽ°àŽ àŽµàµàŽ£àŽ®àµàŽšàµàŽšàµ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ
+ àŽ€àŽŸàŽ²àµâàŽªàŽ°àµàŽ¯àŽ®àŽšàµàŽžàŽ°àŽ¿àŽàµàŽàµ
+ àŽ€àµàŽ°àŽàµàŽàµàŽàµàŽàµàŽàŽŸàŽ}
+
+_titleabout_ [l=ml] {àŽàµàŽ±àŽ¿àŽªàµàŽªàµ}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=ml] {àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿àŽ¯àµàŽàµ àŽ àŽµàŽ¿àŽ­àŽŸàŽàŽ àŽ
+àŽàŽ¯àµâàŽàµàŽàµàŽ}  
+_texticonclosedbookshelf_ [l=ml] {àŽ àŽ­àŽŸàŽàŽ àŽ€àµàŽ±àŽšàµàŽšàµàŽàŽŸàŽ£àµàŽ}  
+_texticonopenbook_ [l=ml] {àŽ àŽªàµàŽžàµàŽ€àŽàŽ àŽ
+àŽàŽ¯àµàŽàµàŽàµàŽ}  
+_texticonclosedfolder_ [l=ml] {àŽ àŽ«àµàŽ³àµàŽ¡àŽ°àµ àŽ€àµàŽ±àŽ¯àµàŽàµàŽàµàŽ}  
+_texticonclosedfolder2_ [l=ml] {àŽàŽªàŽ­àŽŸàŽàŽ àŽ€àµàŽ±àŽ¯àµàŽàµàŽàµàŽ}  
+_texticonopenfolder_ [l=ml] {àŽ àŽ«àµàŽ³àµàŽ¡àŽ°àµ àŽ
+àŽàŽ¯àµàŽàµàŽàµàŽ}  
+_texticonopenfolder2_ [l=ml] {àŽàŽªàŽ­àŽŸàŽàŽ àŽ
+àŽàŽ¯àµàŽàµàŽàµàŽ}  
+_texticonsmalltext_ [l=ml] {àŽ àŽ­àŽŸàŽàŽ àŽ€àµàŽ±àŽšàµàŽšàµàŽàŽŸàŽ£àµàŽ}  
+_texticonsmalltext2_ [l=ml] {àŽ àŽ­àŽŸàŽàŽ àŽ€àµàŽ±àŽšàµàŽšàµ àŽàŽŸàŽ£àµàŽ}  
+_texticonpointer_ [l=ml] {àŽàŽªàµàŽªàµàŽ³àµ àŽàŽŸàŽ£àµàŽšàµàŽš àŽ­àŽŸàŽàŽ}  
+_texticondetach_ [l=ml] {àŽ àŽªàµàŽàµâ àŽªàµàŽ€àŽ¿àŽ¯ àŽàŽŸàŽ²àŽàŽ€àµàŽ€àŽ¿àŽ²àµâ àŽ€àµàŽ±àŽàµàŽàµàŽ}  
+_texticonhighlight_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµâ àŽªàŽŠàŽàµàŽàŽ³àµâ àŽµàµàŽ¯àŽàµàŽ€àŽ®àŽŸàŽàµàŽàµàŽ}  
+_texticonnohighlight_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽªàŽŠàŽàµàŽàŽ³àµ àŽàŽàµàŽ€àµàŽ€àµàŽàŽŸàŽ£àŽ¿àŽàµàŽàµàŽ£àµàŽàŽ€àŽ¿àŽ²àµàŽ²}  
+_texticoncontracttoc_ [l=ml] {àŽàŽ³àµàŽ³àŽàŽàµàŽàŽ àŽ
+àŽªàµàŽ°àŽ€àµàŽ¯àŽàµàŽ·àŽ®àŽŸàŽµàµàŽ}  
+_texticonexpandtoc_ [l=ml] {àŽàŽ³àµàŽ³àŽàŽàµàŽàŽ àŽµàŽ¿àŽªàµàŽ²àµàŽàŽ°àŽ¿àŽàµàŽàµàŽ}  
+_texticonexpandtext_ [l=ml] {àŽàŽ²àµàŽ²àŽŸ àŽàµàŽàµàŽžàµàŽ±àµàŽ±àµàŽ àŽªàµàŽ°àŽŠàŽ°àµàŽ¶àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽ}  
+_texticoncontracttext_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽ€àµàŽ€ àŽ­àŽŸàŽàŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽàµàŽàµàŽžàµàŽ±àµàŽ±àµ àŽ®àŽŸàŽ€àµàŽ°àŽ àŽªàµàŽ°àŽŠàŽ°àµàŽ¶àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽ}  
+_texticonwarning_ [l=ml] {<b>àŽ®àµàŽšàµàŽšàŽ±àŽ¿àŽ¯àŽ¿àŽªàµàŽªàµ: </b>}  
+_texticoncont_ [l=ml] {àŽ€àµàŽàŽ°àŽ£àŽ®àµ?}  
+
+_textltwarning_ [l=ml] {<div class="buttons">_imagecont_</div>
+_iconwarning_àŽàµàŽàµâàŽžàµâàŽ±àµàŽ±àµâ àŽµàŽ¿àŽàŽžàŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµàŽµàŽŽàŽ¿àŽ¯àŽŸàŽ¯àŽ¿ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽ¬àµàŽ°àµàŽžàŽ±àŽ¿àŽ²àµàŽ¯àµâàŽàµàŽàµâàµâ àŽàµàŽàµàŽ€àŽ²àµâ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽªàµàŽ°àŽŠàŽ°àµâàŽ¶àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽ}  
+
+_textgoto_ [l=ml] {àŽªàµàŽàŽ¿àŽ²àµàŽàµàŽàµ àŽªàµàŽµàµàŽ}  
+_textintro_ [l=ml] {àŽàŽ®àµàŽàŽ}  
+
+_textCONTINUE_ [l=ml] {àŽ€àµàŽàŽ°àŽ£àŽ®àµ?}  
+
+_textEXPANDTEXT_ [l=ml] {àŽàµàŽàµàŽžàµàŽ±àµàŽ±àµ àŽµàŽ¿àŽàŽžàŽ¿àŽ€àŽ®àŽŸàŽàµàŽàµàŽ}  
+
+
+
+_textDETACH_ [l=ml] {àŽµàµàŽ°àµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ}  
+
+_textEXPANDCONTENTS_ [l=ml] {àŽàŽ³àµàŽ³àŽàŽàµàŽàŽ àŽµàŽ¿àŽªàµàŽ²àµàŽàŽ°àŽ¿àŽàµàŽàµàŽ}  
+
+_textCONTRACT_ [l=ml] {àŽàµàŽàµâàŽžàµàŽ±àµàŽ±àµâ àŽàµàŽ°àµàŽàµàŽàµàŽ}  
+
+_textHIGHLIGHT_ [l=ml] {àŽàŽàµàŽ€àµàŽ€àµàŽàŽŸàŽàµàŽàŽ²àµâ}  
+
+_textNOHIGHLIGHT_ [l=ml] {àŽàŽàµàŽ€àµàŽ€àµàŽàŽŸàŽàµàŽàµàŽ£àµàŽàŽ€àŽ¿àŽ²àµàŽ²}  
+
+_textPRINT_ [l=ml] {àŽ
+àŽàµàŽàŽàŽ¿àŽàµàŽàµàŽ}  
+
+_textnextsearchresult_ [l=ml] {àŽ
+àŽàµàŽ€àµàŽ€ àŽ«àŽ²àŽàµàŽàŽ³àµ}  
+_textprevsearchresult_ [l=ml] {àŽ®àµàŽšàµâàŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµâ àŽ«àŽ²àŽ}  
+
+# macros for printing page
+_textreturnoriginal_ [l=ml] {àŽ€àµàŽàŽàµàŽ àŽªàµàŽàŽ¿àŽ²àµàŽ¯àµàŽàµàŽàµ àŽ®àŽàŽàµàŽàŽ¿àŽªàµàŽµàµàŽ}  
+_textprintpage_ [l=ml] {àŽ àŽªàµàŽàµâ àŽªàµàŽ°àŽ¿àŽšàµàŽ±àµàŽàµàŽ¯àµàŽ¯àµàŽ}  
+_textshowcontents_ [l=ml] {àŽàŽ³àµàŽ³àŽàŽàµàŽàŽªàµàŽªàµàŽàµ àŽàŽŸàŽ£àµàŽ}  
+_texthidecontents_ [l=ml] {àŽàŽ³àµàŽ³àŽàŽàµàŽàŽ àŽ®àŽ±àŽàµàŽàµàŽªàŽ¿àŽàŽ¿àŽàµàŽàµàŽ}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=ml] {_If_(_thislast_,results _thisfirst_ - _thislast_ for query: _cgiargq_,No matches for query: _cgiargq_)}  
+_textnoquerytitle_ [l=ml] {àŽ€àµàŽ°àŽ¯àµàŽ }
+
+_textsome_ [l=ml] {àŽàŽ¿àŽ²}
+_textall_ [l=ml] {àŽàŽ²àµàŽ²àŽŸàŽ}
+_textboolean_ [l=ml] {àŽ¬àµàŽ³àŽ¿àŽ¯àŽšàµ}  
+_textranked_ [l=ml] {àŽ±àŽŸàŽàµàŽàµâ àŽàµàŽ¯àµâàŽ€àŽ€àµâ}  
+_textnatural_ [l=ml] {àŽžàµàŽµàŽŸàŽ­àŽŸàŽµàŽ¿àŽàŽ}
+_textsortbyrank_ [l=ml] {àŽªàµàŽ°àŽŸàŽ§àŽŸàŽšàµàŽ¯àŽŸàŽ§àŽ¿àŽ·àµâàŽ àŽ¿àŽ€ àŽ±àŽŸàŽàµàŽàµâ}  
+_texticonsearchhistorybar_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàµàŽ±àµ àŽàŽ°àŽ¿àŽ€àµàŽ°àŽ}  
+
+_textifeellucky_ [l=ml] {àŽàŽ¿àŽàµàŽàŽ¿àŽ¯àµàŽšàµàŽšàµ àŽ€àµàŽšàµàŽšàµàŽšàµàŽšàµ}  
+
+#alt text for query buttons
+_textusequery_ [l=ml] {àŽàµàŽµàŽ±àŽ¿ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ}  
+_textfreqmsg1_ [l=ml] {àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽàµ àŽàŽ£àµàŽ£àŽ}  
+
+_textinvalidquery_ [l=ml] {àŽ
+àŽàŽàµàŽàŽ°àŽ¿àŽàµàŽàŽªàµàŽªàµàŽàŽŸàŽ€àµàŽ€ àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽ}  
+_textstopwordsmsg_ [l=ml] {àŽ€àŽŸàŽŽàµ àŽšàŽ²àµàŽàŽ¿àŽ¯ àŽµàŽŸàŽàµàŽàµàŽàŽ³àµ àŽžàŽ°àµàŽµàµàŽµàŽžàŽŸàŽ§àŽŸàŽ°àŽ£àŽ®àŽŸàŽàŽ¯àŽŸàŽ²àµ àŽ
+àŽµàŽàŽ£àŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽàŽ¿àŽ°àŽ¿àŽàµàŽàµàŽšàµàŽšàµ}  
+_textlucenetoomanyclauses_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽ€àµàŽ€àŽ¿àŽ²àµ àŽ
+àŽšàŽµàŽ§àŽ¿ àŽªàŽŠàŽàµàŽàŽ³àµ àŽàŽ£àµàŽàµ. àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽªàŽŠàŽàµàŽàŽ³àµ àŽàµàŽ±àµàŽàµàŽàµàŽàŽ¿ àŽàµàŽ€àµàŽ¯àŽ®àŽŸàŽàµàŽàµàŽ}  
+
+_textmorethan_ [l=ml] {àŽàµàŽàŽŸàŽ€àµ}  
+_textapprox_ [l=ml] {àŽžàŽàŽ¬àŽšàµàŽ§àŽ¿àŽàµàŽ}  
+_textnodocs_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽàŽ°àµ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽµàµàŽ®àŽŸàŽ¯àµàŽ àŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ¿àŽ²àµàŽ²}  
+_text1doc_ [l=ml] {àŽàŽ°àµ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽžàŽàŽ¶àŽ¯àŽµàµàŽ®àŽŸàŽ¯àŽ¿ àŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽšàµ}  
+_textlotsdocs_ [l=ml] {àŽ°àµàŽàŽàŽ³àµ  àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽžàŽàŽ¶àŽ¯àŽµàµàŽ®àŽŸàŽ¯àŽ¿ àŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽšàµ}  
+_textmatches_ [l=ml] {àŽàµàŽ°àµàŽšàµàŽšàŽµ}  
+_textbeginsearch_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàµ àŽ€àµàŽàŽàµàŽàµàŽ}  
+_textrunquery_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽšàŽàŽ€àµàŽ€àµàŽ}  
+_textclearform_ [l=ml] {àŽ«àµàŽ àŽàŽ²àµàŽ²àŽŸàŽ€àŽŸàŽàµàŽàµàŽ}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=ml] {àŽµàŽŸàŽàµàŽàµàŽàŽ³àµ}  
+_textinfield_ [l=ml] {àŽ«àµàŽ²àµàŽ¡àŽ¿àŽ²àµ}  
+_textfoldstem_ [l=ml] {àŽ«àµàŽ³àµàŽ¡àµ, àŽžàµàµàŽ±àµàŽ±àµàŽ}  
+
+_textadvquery_ [l=ml] {àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿àŽ²àµ àŽàµàŽŠàµàŽ¯àŽ àŽšàµàŽ°àŽ¿àŽàµàŽàµ àŽšàŽ²àµàŽàµàŽ}  
+_textallfields_ [l=ml] {àŽàŽ²àµàŽ²àŽŸ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽšàŽ®àŽ£àµàŽ¡àŽ²àŽàµàŽàŽ³àµàŽ}  
+_texttextonly_ [l=ml] {àŽàµàŽàµàŽžàµàŽ±àµàŽ±àµ àŽ®àŽŸàŽ€àµàŽ°àŽ}  
+_textand_ [l=ml] {àŽàŽ}  
+_textor_ [l=ml] {àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿àŽ²àµ}  
+_textandnot_ [l=ml] {àŽàŽ²àµàŽ²àŽŸàŽ€àµàŽ¯àµàŽ}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=ml] {àŽàµàŽ£àµàŽàµàŽªàŽ²àŽàŽ¯àŽ¿àŽ²àµ àŽ€àŽ¿àŽ°àŽ¯àµàŽ__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level)_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ sorting results by _sfselection_) for _querytypeselection_ of the àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽ³àµàŽ³}  
+
+
+
+_textadvancedmgppsearch_ [l=ml] {àŽ€àŽ¿àŽ°àŽ¯àµàŽ _indexselection_ _If_(_jselection_,associated with _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language ), and display results in _formquerytypeadvancedselection_ order, for}  
+
+
+
+
+
+
+
+
+
+_textnojsformwarning_ [l=ml] {àŽ®àµàŽšàµàŽšàŽ±àŽ¿àŽ¯àŽ¿àŽªàµàŽªàµ: àŽàŽŸàŽµ àŽžàµàŽàµàŽ°àŽ¿àŽªàµàŽ±àµàŽ±àµ àŽšàŽ¿àŽàµàŽàŽ³àµàŽàµ àŽ¬àµàŽ°àµàŽžàŽ±àŽ¿àŽ²àµ àŽšàŽ¿àŽàµàŽµàŽ®àŽŸàŽàµàŽàŽ¿ <br>  àŽ«àµàŽ  àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽ¶àŽàµàŽ€àŽ®àŽŸàŽàµàŽàµàŽ}  
+_textdatesearch_ [l=ml] {àŽ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµ àŽ€àµàŽ¯àµàŽ¯àŽ€àŽ¿àŽµàŽàµàŽàµ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽ. àŽàŽ€àµ àŽàŽ·àµàŽàŽ®àµàŽ£àµàŽàµàŽàµàŽàŽ¿àŽ²àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽµàµàŽšàµàŽš àŽžàŽµàŽ¿àŽ¶àµàŽ·àŽ€àŽ¯àŽŸàŽ£àµ}  
+_textstartdate_ [l=ml] {àŽ€àµàŽàŽàµàŽàµàŽšàµàŽš àŽ€àµàŽ¯àµàŽ¯àŽ€àŽ¿}  
+_textenddate_ [l=ml] {àŽ
+àŽµàŽžàŽŸàŽš àŽ€àµàŽ¯àµàŽ¯àŽ€àŽ¿}  
+_textbc_ [l=ml] {àŽ¬àŽ¿.àŽžàŽ¿.àŽ}  
+
+_textexplaineras_ [l=ml] {àŽµàŽ°àµàŽ·àŽàµàŽàŽ³àµ àŽàŽŸàŽ£àŽ¿àŽàµàŽàŽŸàŽšàµ àŽ.àŽ¡àŽ¿ àŽ¯àµàŽàµàŽàµ àŽªàŽàŽ°àŽ àŽžàŽ¿.àŽ àŽ¯àµàŽ àŽ¬àŽ¿àŽžàŽ¿ àŽ¯àµàŽàµàŽàµ àŽªàŽàŽ°àŽ àŽ¬àŽ¿àŽžàŽ¿àŽ àŽ¯àµàŽ àŽàŽ£àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽ¿àŽ°àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµ. àŽ
+àŽµ àŽàµàŽ®àŽ£àµ àŽàŽ±, àŽ¬àŽ¿àŽ«àµàŽ°àµ àŽŠ àŽàµàŽ®àŽ£àµ àŽàŽ± àŽàŽšàµàŽšàŽ¿àŽµ àŽžàµàŽàŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽšàµàŽšàµ}  
+
+_textstemon_ [l=ml] {àŽµàŽŸàŽàµàŽ¯àŽµàŽžàŽŸàŽšàŽ àŽ
+àŽµàŽàŽ£àŽ¿àŽàµàŽàµàŽ}  
+
+_textsearchhistory_ [l=ml] {àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽàŽ°àŽ¿àŽ€àµàŽ°àŽ}  
+
+#text macros for search history
+_textnohistory_ [l=ml] {àŽªàµàŽ°àµàŽµàµàŽµàŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽ°àµàŽàŽàŽ³àµ àŽ²àŽ­àµàŽ¯àŽ®àŽ²àµàŽ²}  
+_texthresult_ [l=ml] {àŽ«àŽ²àŽ}  
+_texthresults_ [l=ml] {àŽ«àŽ²àŽàµàŽàŽ³àµâ}  
+_texthallwords_ [l=ml] {àŽàŽ²àµàŽ²àŽŸ àŽªàŽŠàŽàµàŽàŽ³àµàŽ}  
+_texthsomewords_ [l=ml] {àŽàŽ¿àŽ² àŽªàŽŠàŽàµàŽàŽ³àµ}  
+_texthboolean_ [l=ml] {àŽ¬àµàŽ³àŽ¿àŽ¯àŽšàµ}  
+_texthranked_ [l=ml] {àŽ±àŽŸàŽàµàŽàµ àŽàµàŽ¯àµàŽ€àŽ€àµ}  
+_texthcaseon_ [l=ml] {àŽ²àŽ¿àŽªàŽ¿àŽàŽ³àµâ àŽ¯àµàŽàŽ¿àŽàµàŽàŽ£àŽ}  
+
+
+
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=ml] {àŽ€àŽŸàŽŽàµàŽªàŽ±àŽ¯àµàŽ àŽµàŽ¿àŽ§àŽ àŽ®àµàŽšàµâàŽàŽ£àŽšàŽàŽ³àµâ àŽšàŽ¿àŽ¶àµàŽàŽ¯àŽ¿àŽàµàŽàŽ¿àŽàµàŽàµàŽ£àµàŽàµâ. àŽ¬àµàŽ°àµàŽžàŽ±àŽ¿àŽ²àµ àŽªàŽ¿àŽšàµàŽšàµàŽàµàŽàµàŽ³àµàŽ³  "back"àŽ¬àŽàµàŽàŽ£àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽ°àµàŽ€àµâ. àŽ®àµàŽàŽ³àŽ¿àŽ²àµàŽ¯àµâàŽàµàŽàµàŽ³àµàŽ³ àŽ¬àŽàµàŽàŽ£àµàŽàŽ³àµâ àŽ®àŽŸàŽ€àµàŽ°àŽ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ}  
+_textsetprefs_ [l=ml] {àŽ®àµàŽšàµâàŽàŽ£àŽš àŽšàŽ¿àŽ¶àµàŽàŽ¯àŽ¿àŽàµàŽàµàŽ}  
+_textsearchprefs_ [l=ml] {àŽ®àµàŽšàµâàŽàŽ£àŽšàŽŸàŽàµàŽ°àŽ®àŽ€àµàŽ€àŽ¿àŽ²àµâ àŽ€àŽ¿àŽ°àŽ¯àµàŽ}  
+_textcollectionprefs_ [l=ml] {àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ³àµàŽ³ àŽ®àµàŽšàµàŽàŽ£àŽšàŽàŽ³àµ}  
+_textpresentationprefs_ [l=ml] {àŽªàµàŽ°àŽŠàŽ°àµâàŽ¶àŽš àŽ®àµàŽšàµâàŽàŽ£àŽšàŽàŽ³àµâ}  
+_textpreferences_ [l=ml] {àŽ®àµàŽšàµâàŽàŽ£àŽšàŽàŽ³àµâ}  
+_textcasediffs_ [l=ml] {àŽ²àŽ¿àŽªàŽ¿ àŽµàµàŽ¯àŽ€àµàŽ¯àŽŸàŽžàŽàµàŽàŽ³àµ}  
+_textignorecase_ [l=ml] {àŽ²àŽ¿àŽªàŽ¿ àŽµàµàŽ¯àŽ€àµàŽ¯àŽŸàŽžàŽàµàŽàŽ³àµâ àŽ
+àŽµàŽàŽ£àŽ¿àŽàµàŽàµàŽ}  
+_textmatchcase_ [l=ml] {àŽàµàŽ€àµàŽ¯àŽ®àŽŸàŽ¯àŽ¿ àŽ¯àµàŽàŽ¿àŽàµàŽàŽ£àŽ}  
+_textwordends_ [l=ml] {àŽµàŽŸàŽàµàŽ¯àŽµàŽžàŽŸàŽšàŽ}  
+_textstem_ [l=ml] {àŽµàŽŸàŽàµàŽ¯àŽµàŽžàŽŸàŽšàŽ àŽ
+àŽµàŽàŽ£àŽ¿àŽàµàŽàµàŽ}  
+_textnostem_ [l=ml] {àŽ®àµàŽŽàµàŽµàŽšàµâ àŽªàŽŠàŽµàµàŽ àŽ
+àŽšàµàŽ¯àµàŽàµàŽ¯àŽ®àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽ£àŽ}  
+_textaccentdiffs_ [l=ml] {àŽàŽàµàŽàŽŸàŽ°àŽ£ àŽµàµàŽ¯àŽ€àµàŽ¯àŽŸàŽžàŽàµàŽàŽ³àµ}  
+_textignoreaccents_ [l=ml] {àŽàŽšàµàŽšàŽ²àµ àŽ
+àŽµàŽàŽ£àŽ¿àŽàµàŽàµàŽ}  
+_textmatchaccents_ [l=ml] {àŽàŽàµàŽàŽŸàŽ°àŽ£ àŽàŽ¿àŽ¹àµàŽšàŽàµàŽàŽ³àµâ àŽ¯àµàŽàŽ¿àŽàµàŽàŽ£àŽ}  
+
+_textprefop_ [l=ml] {àŽàŽ°àµ àŽªàµàŽàŽ¿àŽ²àµàŽ _hitsperpageoption_   àŽµàµàŽ€àŽ àŽªàŽ°àŽ®àŽŸàŽµàŽ§àŽ¿  _maxdocoption_ àŽ±àŽ¿àŽžàŽ³àµàŽàµàŽàµàŽàŽ³àµ àŽµàŽ°àµ àŽàŽŸàŽ£àŽ¿àŽàµàŽàµàŽ.}  
+_textextlink_ [l=ml] {àŽªàµàŽ±àŽ®àµàŽ¯àµàŽ³àµàŽ³ àŽµàµàŽ¬àµàŽªàµàŽàµàŽàŽ³àµàŽàµ àŽ²àŽ­àµàŽ¯àŽ€}  
+_textintlink_ [l=ml] {àŽàŽ£àµàŽàµàŽ€àµàŽ€àŽ¿àŽ¯ àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽš àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµ}  
+_textlanguage_ [l=ml] {àŽ­àŽŸàŽ·àŽàŽ³àµ}  
+_textencoding_ [l=ml] {àŽàŽšàµàŽàµàŽ¡àŽ¿àŽàŽàµ:}  
+_textformat_ [l=ml] {àŽàŽšàµàŽ±àŽ°àµâàŽ«àµàŽ¯àµâàŽžàµâ àŽ«àµàŽ°àµâàŽ®àŽŸàŽ±àµàŽ±àµâ}  
+_textall_ [l=ml] {àŽàŽ²àµàŽ²àŽŸàŽ}  
+_textquerymode_ [l=ml] {àŽàµàŽŠàµàŽ¯ àŽ°àµàŽªàŽ}  
+_textsimplemode_ [l=ml] {àŽžàŽŸàŽ§àŽŸàŽ°àŽ£ àŽàµàŽµàµàŽ±àŽ¿ àŽ®àµàŽ¡àµ}  
+_textadvancedmode_ [l=ml] {àŽ
+àŽ¡àµàŽµàŽŸàŽšàµàŽžàµàŽ¡àµ àŽàµàŽµàŽ±àŽ¿ àŽ®àµàŽ¡àµ (àŽàŽµàŽ¿àŽàµ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàµ !, &, I, àŽªàŽŸàŽ°àŽšàµàŽ€àµàŽžàŽ¿àŽžàµ àŽàŽšàµàŽšàŽ¿àŽµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽ¬àµàŽ³àŽ¿àŽ¯àŽšàµ àŽžàµàŽ°àµàŽàµàŽàµ àŽšàŽàŽ€àµàŽ€àŽŸàŽ}  
+_textlinkinterm_ [l=ml] {àŽàŽàŽ¯àŽ¿àŽ²àµàŽ³àµàŽ³ àŽªàµàŽàŽ¿àŽ²àµàŽàµ}  
+_textlinkdirect_ [l=ml] {àŽšàµàŽ°àŽ¿àŽàµàŽàµ àŽ
+àŽµàŽ¿àŽàµàŽ¯àµàŽàµàŽàµ àŽªàµàŽµàµàŽ}  
+_textdigitlib_ [l=ml] {àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿}  
+_textweb_ [l=ml] {àŽµàµàŽ¬àµâ}  
+_textgraphical_ [l=ml] {àŽ°àµàŽàŽŸàŽàŽ¿àŽ€àµàŽ°àŽ°àµàŽªàŽ®àµàŽ³àµàŽ³}  
+_texttextual_ [l=ml] {àŽàµàŽàµàŽàµàŽµàŽ²àµ}  
+_textcollectionoption_ [l=ml] {<p>àŽàŽªàŽ¶àµàŽàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽàŽ³àµàŽªàµàŽªàµàŽàµàŽšàµàŽšàŽ€àµ<br>}  
+
+_textsearchtype_ [l=ml] {àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽ°àµàŽªàŽ}  
+_textformsearchtype_ [l=ml] {àŽ«àµàŽ²àµâàŽ¡àµàŽàŽ³àµàŽàµàŽàµàŽàŽ¿àŽ¯àŽ€àµâ}  
+_textplainsearchtype_ [l=ml] {_boxsizeoption_ àŽžàŽŸàŽ§àŽŸàŽ°àŽ£ àŽàµàŽŠàµàŽ¯ àŽàŽ³àµàŽ³àŽ¿}  
+_textregularbox_ [l=ml] {àŽàŽ±àµàŽ±àŽµàŽ°àŽ¿}
+_textlargebox_ [l=ml] {àŽµàŽ²àŽ¿àŽ¯}  
+
+_textrelateddocdisplay_ [l=ml] {àŽ¬àŽšàµàŽ§àŽªàµàŽªàµàŽàµàŽ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµ àŽàŽŸàŽ£àŽ¿àŽàµàŽàµàŽ}  
+_textsearchhistory_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàµàŽ±àµ àŽàŽ°àŽ¿àŽ€àµàŽ°àŽ}  
+_textnohistory_ [l=ml] {àŽªàµàŽ°àµàŽµàµàŽµàŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽ°àµàŽàŽàŽ³àµ àŽ²àŽ­àµàŽ¯àŽ®àŽ²àµàŽ²}  
+_texthistorydisplay_ [l=ml] {àŽžàµàŽ°àµàŽàµàŽàµ àŽ¹àŽ¿àŽžàµàŽ±àµàŽ±àŽ±àŽ¿ àŽ±àŽ¿àŽàµàŽàµàŽ°àµàŽ¡àµàŽàŽ²àµ _historynumrecords_ àŽàŽŸàŽ£àŽ¿àŽàµàŽàµàŽ}  
+_textnohistorydisplay_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàµàŽ±àµ àŽàŽ°àŽ¿àŽ€àµàŽ°àŽ àŽàŽŸàŽ£àŽ¿àŽàµàŽàµàŽ£àµàŽàŽ€àŽ¿àŽ²àµàŽ²}  
+
+
+
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=ml] {àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµàŽàµ àŽ€àŽ°àŽàŽ€àŽ¿àŽ°àŽ¿àŽµàŽ¿àŽšàµ àŽàŽ§àŽŸàŽ°àŽ}  
+_textalsoshowing_ [l=ml] {àŽàµàŽàŽŸàŽ€àµ àŽàŽŸàŽ£àŽ¿àŽàµàŽàµàŽšàµàŽš}  
+_textwith_ [l=ml] {àŽ®àŽ¿àŽàµàŽàŽµàŽŸàŽ±àµàŽ}  
+_textdocsperpage_ [l=ml] {àŽàŽ°àµ àŽªàµàŽàŽ¿àŽ²àµàŽ®àµàŽ³àµàŽ³ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµ}  
+
+_textfilterby_ [l=ml] {àŽàŽšàµàŽš àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽàŽ³àµàŽ³ àŽªàµàŽ°àŽ®àŽŸàŽ£àµâàŽàµàŽàŽ³àµâ àŽ²àŽ­àŽ¿àŽàµàŽàŽ£àŽ}  
+_textall_ [l=ml] {àŽàŽ²àµàŽ²àŽŸàŽ}  
+_textany_ [l=ml] {àŽàŽ€àµàŽàµàŽàŽ¿àŽ²àµàŽ}  
+_textwords_ [l=ml] {àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽàµ}  
+_textleaveblank_ [l=ml] {àŽàŽ²àµàŽ²àŽŸ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµàŽ àŽ²àŽ­àŽ¿àŽàµàŽàµàŽµàŽŸàŽšàµâ àŽ àŽàŽ³àµàŽ³àŽ¿ àŽ
+àŽµàŽàŽ£àŽ¿àŽàµàŽàµàŽ}  
+
+_browsebuttontext_ [l=ml] {àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµâ àŽ€àŽ°àŽàŽ€àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ}  
+
+_nodata_ [l=ml] {<i>àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµ àŽàŽ²àµàŽ²</i>}  
+_docs_ [l=ml] {àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµâ}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=ml] {àŽžàŽ¹àŽŸàŽ¯àŽ}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=ml] {_2_ àŽ¬àŽàµàŽàŽ£àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµâàµâ _1_ àŽµàŽŽàŽ¿ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµâ àŽ¬àµàŽ°àµàŽžàµâ àŽàµàŽ¯àµàŽ¯àµàŽ}  
+
+_textSearchhelp_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµàŽŠàµàŽŠàµàŽ¶àŽ¿àŽàµàŽàµàŽšàµàŽš àŽµàŽŸàŽàµàŽàµàŽàŽ³àµâ àŽªàŽŸàŽ àŽ€àµàŽ€àŽ¿àŽ²àµàŽ£àµàŽàµàŽ¯àµàŽšàµàŽšàŽ±àŽ¿àŽ¯àŽŸàŽšàµâ _labelSearch_ àŽ¬àŽàµàŽàŽ£àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµâ àŽ€àŽ¿àŽ°àŽ¯àµàŽ}  
+_textTohelp_ [l=ml] {àŽ¬àŽàµàŽàŽ£àµ àŽàµàŽ²àŽ¿àŽàµ àŽàµàŽ¯àµàŽ€àµ àŽàµàŽ°àŽšàµàŽ¥àŽàµàŽàŽ³àµ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽ}  
+_textFromhelp_ [l=ml] {àŽ²àµàŽ¬àŽ²àµâàŽ«àµàŽ_labelFrom_  àŽ¬àŽàµàŽàŽ£àµâàŽµàŽŽàŽ¿ àŽ«àµàŽ²àµâàŽ¡àŽ¿àŽ²àµâ àŽšàŽ¿àŽšàµàŽšàµàŽ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµâ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµâ}  
+_textBrowsehelp_ [l=ml] {àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµâ}  
+_textAcronymhelp_ [l=ml] {àŽ²àµàŽ¬àŽ²àµ àŽ
+àŽàµàŽ°àµàŽŸàŽ£àŽ¿àŽ _labelAcronym_ àŽ¬àŽàµàŽàŽ£àµ àŽµàŽŽàŽ¿ àŽžàŽàŽàµàŽ·àµàŽªàŽªàŽŠàŽàµàŽàŽ³àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽàµàŽ£àµàŽàµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ}  
+_textPhrasehelp_ [l=ml] {àŽ²àŽŸàŽ¬àŽ²àµàŽ«àµàŽ°àµàŽžàµ àŽ¬àŽàµàŽàŽ£àŽ¿àŽ²àµ _labelPhrase_ àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµàŽ€àµàµ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ€àµàŽ€àŽ¿àŽ²àµ àŽµàŽ°àµàŽšàµàŽš àŽªàŽŠàŽžàŽ®àµàŽàµàŽàŽ¯àŽ àŽµàŽàµàŽàµ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽšàŽàŽ€àµàŽ€àŽŸàŽ. àŽ«àŽ¿àŽšàµàŽ±àµ àŽ«àµàŽ°àµàŽžàµ àŽ¬àµàŽ°àµàŽžàŽ±àŽŸàŽ£àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽšàµàŽšàŽ€àµ}  
+
+_texthelptopicstitle_ [l=ml] {àŽµàŽ¿àŽ·àŽ¯àŽàµàŽàŽ³àµ}  
+
+_textreadingdocs_ [l=ml] {àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµ àŽàŽàµàŽàŽ¿àŽšàµ àŽµàŽŸàŽ¯àŽ¿àŽàµàŽàŽŸàŽ}  
+
+_texthelpreadingdocs_ [l=ml] {<p>àŽàŽ¿àŽ²àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµâ àŽªàµàŽžàµâàŽ€àŽàŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽàŽ³àµàŽ³àŽàµàŽàŽ àŽàŽŸàŽ£àŽŸàŽ. àŽ®àŽ±àµàŽ±àµàŽàŽ¿àŽ²àŽ€àŽ¿àŽ²àµâ àŽªàµàŽàµâ àŽšàŽ®àµàŽªàŽ±àµàŽàŽ³àµàŽ àŽ
+àŽ€àµàŽàµàŽªàµàŽªàŽ àŽàŽ°àµ àŽªàµàŽ€àŽ¿àŽ¯ àŽªàµàŽàµâ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽàµàŽàŽŸàŽšàµàŽ³àµàŽ³ àŽàŽ°àµ àŽàŽ³àµàŽ³àŽ¿àŽ¯àµàŽ àŽàŽŸàŽ£àŽŸàŽ. àŽ
+àŽµàŽ¿àŽàµàŽšàŽ¿àŽšàµàŽšàµàŽ àŽ®àµàŽ®àµàŽªàµàŽàµàŽàµàŽ àŽªàŽ¿àŽšàµàŽšàµàŽàµàŽàµàŽ®àµàŽ³àµàŽ³ àŽªàµàŽàµàŽàŽ³àŽ¿àŽ²àµàŽ¯àµâàŽàµàŽàµâ àŽªàµàŽàŽŸàŽ. àŽàµàŽ°àŽšàµàŽ¥àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽàŽ³àµàŽ³àŽàŽàµàŽàŽ àŽàŽ£àµàŽàµàŽàµàŽàŽ¿àŽ²àµâ, àŽªàµàŽ°àŽŠàŽ°àµâàŽ¶àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽšàµàŽš àŽ­àŽŸàŽàŽ àŽàµàŽàµàŽ€àŽ²àµâ àŽàŽ±àµàŽªàµàŽªàµàŽšàŽ¿àŽ±àŽ€àµàŽ€àŽ¿àŽ²àµâ àŽàŽŸàŽ£àŽŸàŽ. àŽ
+àŽ€àµ àŽµàŽ¿àŽàŽžàŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽŸàŽšàµàŽ àŽàµàŽ°àµàŽàµàŽàŽŸàŽšàµàŽ àŽàŽŽàŽ¿àŽ¯àµàŽ. àŽ«àµàŽ³àµâàŽ¡àŽ±àµàŽàŽ³àŽ¿àŽ²àµâ àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµâàŽ€àŽŸàŽ²àµâ àŽ
+àŽ€àµ àŽµàŽ¿àŽàŽžàŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽµàŽŸàŽšàµàŽ àŽžàŽàµàŽàµàŽàŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽµàŽŸàŽšàµàŽ àŽàŽŽàŽ¿àŽ¯àµàŽ.
+
+<p>àŽàŽªàµàŽªàµàŽ³àµâ àŽàŽŸàŽ£àµàŽšàµàŽš àŽàµàŽ°àŽšàµàŽ¥àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽ­àŽŸàŽàŽ àŽàŽ³àµàŽ³àŽàŽàµàŽàŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽ€àŽŸàŽŽàµ àŽàŽŸàŽ£àŽŸàŽ. àŽ
+àŽ€àµ àŽµàŽŸàŽ¯àŽ¿àŽàµàŽàµàŽàŽŽàŽ¿àŽàµàŽàŽŸàŽ²àµâ àŽ®àµàŽšàµâàŽªàµàŽàµàŽàµàŽ àŽªàŽ¿àŽšàµàŽšàµàŽàµàŽàµàŽ àŽªàµàŽàµàŽšàµàŽš àŽžàµàŽàŽàŽàµàŽàŽ³àµâ àŽ
+àŽàµàŽ€àµàŽ€ àŽ­àŽŸàŽàŽàµàŽàŽ³àŽ¿àŽ²àµàŽ¯àµâàŽàµàŽàµâ àŽšàŽ¯àŽ¿àŽàµàŽàµàŽ</p>
+<p>àŽàŽµàŽ°àµâ àŽàŽ¿àŽ€àµàŽ°àŽ€àµàŽ€àŽ¿àŽšàµ àŽ€àŽŸàŽŽàµ àŽàŽ¿àŽ² àŽ¬àŽàµàŽàŽ£àµàŽàŽ³àµâ àŽàŽŸàŽ£àŽŸàŽ<i>_document:textEXPANDTEXT_</i> àŽ
+àŽ®àŽ°àµâàŽ€àµàŽ€àŽ¿àŽ¯àŽŸàŽ²àµâ àŽàµàŽ°àŽšàµàŽ¥àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽàµàŽàµâàŽžàµâàŽ±àµàŽ±àµâ àŽªàµàŽ°àµâàŽ£àŽ®àŽŸàŽ¯àŽ¿ àŽàŽŸàŽ£àŽŸàŽ. àŽàµàŽ°àŽšàµàŽ¥àŽ àŽµàŽ³àŽ°àµ àŽµàŽ²àµàŽ€àŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµâ àŽ
+àŽ€àµ àŽ€àµàŽ±àŽšàµàŽšàµàŽµàŽ°àŽŸàŽšàµâ àŽàµàŽàµàŽ€àŽ²àµâ àŽžàŽ®àŽ¯àŽ àŽàŽàµàŽàµàŽàµàŽ. àŽàµàŽàµàŽ€àŽ²àµâ àŽàŽàŽªàµàŽ¯àµàŽàµàŽàŽ°àµâ àŽ®àµàŽ®àµàŽ®àŽ±àŽ¿àŽ¯àµàŽ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽ.  <i>_document:textEXPANDCONTENTS_</i> àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµâàŽ€àŽŸàŽ²àµâ àŽàŽ²àµàŽ²àŽŸ àŽ
+àŽŠàµàŽ§àµàŽ¯àŽŸàŽ¯àŽàµàŽàŽ³àµàŽàµàŽ¯àµàŽ àŽ€àŽ²àŽàµàŽàµàŽàµàŽàµàŽàŽ³àµâ àŽàŽŸàŽ£àµàŽàŽµàŽ¿àŽ§àŽ àŽàŽ³àµàŽ³àŽàŽàµàŽàŽ àŽµàŽ¿àŽàŽžàŽ¿àŽ€àŽ®àŽŸàŽàµàŽ.
+
+àŽ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ€àµàŽ€àŽ¿àŽšàµâ àŽàŽ°àµ àŽªàµàŽ€àŽ¿àŽ¯ àŽ¬àµàŽ°àµàŽžàŽ°àµâ àŽµàŽ¿àŽšàµâàŽ¡àµ àŽ²àŽ­àŽ¿àŽàµàŽàµàŽµàŽŸàŽšàµâ  <i>_document:textDETACH_</i>  àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµàŽ¯àµàŽ. (àŽ€àŽŸàŽ°àŽ€àŽ®àµàŽ¯àŽ àŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàŽ€àŽ¿àŽšàµàŽ àŽàŽ°àµàŽžàŽ®àŽ¯àŽ àŽ°àŽ£àµàŽàµàŽ£àµàŽ£àŽ àŽµàŽŸàŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽšàµàŽ àŽ®àŽ±àµàŽ±àµàŽ àŽàŽ€àµâ àŽàŽªàŽàŽŸàŽ°àŽªàµàŽªàµàŽàµàŽšàµàŽšàŽ€àŽŸàŽ£àµâ). àŽàŽàµàŽµàŽ¿àŽ²àŽŸàŽ¯àŽ¿, àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽ€àŽ¿àŽ°àŽ¯àµàŽšàµàŽš àŽªàŽŠàŽàµàŽàŽ³àµâ àŽ¹àµàŽ²àµàŽ±àµàŽ±àµàŽàµàŽ¯àµâàŽ€àµâ àŽàŽŸàŽ£àŽ¿àŽàµàŽàŽªàµàŽªàµàŽàŽŸ àŽžàŽ¹àŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽšàµ. àŽàµàŽ²àŽ¿àŽàµàŽàµàŽ. àŽ¹àµàŽ²àµàŽ±àµàŽ±àµàŽàµàŽ¯àµâàŽ€àŽ€àµ àŽàŽŽàŽ¿àŽµàŽŸàŽàµàŽàµàŽµàŽŸàŽšàŽŸàŽ¯àŽ¿ àŽàŽµàŽ¿àŽàµ <i>_document:textNOHIGHLIGHT_</i> àŽàµàŽ²àŽ¿àŽàµàŽàµàµàŽàµàŽž</p>
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=ml] {àŽ àŽàµàŽ°àŽšàµàŽ¥àŽžàŽ®àµàŽàµàŽàŽ¯àŽ àŽ€àµàŽ±àŽàµàŽàµàŽ}  
+_texthelpopenbook_ [l=ml] {àŽ àŽàµàŽ°àŽšàµàŽ¥àŽ àŽ€àµàŽ±àŽàµàŽàµàŽ / àŽ
+àŽàŽàµàŽàµàŽ}  
+_texthelpviewtextsection_ [l=ml] {àŽàµàŽàµâàŽžàµàŽ±àµàŽ±àŽ¿àŽšàµàŽ±àµ àŽ àŽ­àŽŸàŽàŽ àŽàŽŸàŽ£àµàŽ}  
+_texthelpexpandtext_ [l=ml] {àŽàµàŽàµàŽžàµàŽ±àµàŽ±àµ àŽªàµàŽ°àµàŽ£àŽ®àŽŸàŽ¯àŽ¿ àŽàŽŸàŽ£àŽ¿àŽàµàŽàŽ£àŽ / àŽàŽŸàŽ£àŽ¿àŽàµàŽàµàŽ£àµàŽ}  
+_texthelpexpandcontents_ [l=ml] {àŽàŽ³àµàŽ³àŽàŽàµàŽàŽ àŽµàŽ¿àŽàŽžàŽ¿àŽ€àŽ®àŽŸàŽàµàŽàŽ£àµ àŽµàµàŽ£àµàŽàŽ¯àµ àŽàŽšàµàŽšàµ}  
+_texthelpdetachpage_ [l=ml] {àŽ àŽªàµàŽàµ àŽàŽ°àµ àŽªàµàŽ€àŽ¿àŽ¯ àŽàŽŸàŽ²àŽàŽ€àµàŽ€àŽ¿àŽ²àµ àŽàŽŸàŽ£àµàŽ}  
+_texthelphighlight_ [l=ml] {àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽªàŽŠàŽàµàŽàŽ³àµâ àŽàŽàµàŽ€àµàŽ€àµàŽàŽŸàŽ£àŽ¿àŽàµàŽàµàŽ}  
+_texthelpsectionarrows_ [l=ml] {àŽ®àµàŽšàµàŽªàµ àŽ¶àµàŽ·àŽ®àµ àŽàŽ³àµàŽ³ àŽµàŽ¿àŽ­àŽŸàŽàŽ€àµàŽ€àŽ¿àŽ²àµàŽàµàŽàµ àŽªàµàŽµàµàŽ}  
+
+
+_texthelpsearchingtitle_ [l=ml] {àŽªàµàŽ°àŽ€àµàŽ¯àµàŽ àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽàµàŽàµ àŽàŽàµàŽàŽ¿àŽšàµ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽ}  
+
+_texthelpsearching_ [l=ml] {<p>àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽªàµàŽàŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàµàŽ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàµ àŽ€àŽŸàŽŽàµàŽªàŽ±àŽ¯àµàŽšàµàŽš àŽªàµàŽ°àŽàŽŸàŽ°àŽ àŽ²àŽ³àŽ¿àŽ€àŽ®àŽŸàŽ¯ àŽàŽ°àµ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽšàŽàŽ€àµàŽ€àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ 
+ 
+<p>     
+   <ol><li>àŽàŽšàŽàµàŽàŽ³àŽŸàŽ£àµ àŽ€àŽ¿àŽ°àŽ¯àµàŽ£àµàŽàµàŽšàµàŽšàŽ€àµàŽšàµàŽšàµ àŽµàµàŽ¯àŽàµàŽ€àŽ®àŽŸàŽàµàŽàµàŽ  
+<li>àŽàŽ²àµàŽ²àŽŸ àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽàµàŽàµàŽ àŽµàµàŽ£àµàŽàŽ¿àŽ¯àµ àŽ
+àŽ€àµ àŽàŽ¿àŽ² àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽàµàŽàµàŽµàµàŽ£àµàŽàŽ¿àŽ¯àµ àŽàŽšàµàŽšàµ àŽšàŽ¿àŽ¶àµàŽàŽ¯àŽ¿àŽàµàŽàµàŽ  
+      <li>àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàµ àŽ€àŽ¿àŽ°àŽ¯àµàŽ£àµàŽ àŽµàŽŸàŽàµàŽàµàŽàŽ³àµ àŽàµàŽªàµàŽªàµàŽàµàŽ¯àµàŽ¯àµàŽ  
+</ol>  
+<p>àŽàŽ°àµ àŽàµàŽŠàµàŽ¯àŽ àŽšàŽ²àµàŽàµàŽ®àµàŽªàµàŽ³àµ àŽ€àŽšàµàŽšàµ àŽ
+àŽ€àµàŽ®àŽŸàŽ¯àŽ¿ àŽ¬àŽšàµàŽ§àŽªàµàŽªàµàŽàµàŽ àŽ
+àŽšàµàŽ¯àµàŽàµàŽ¯àŽ®àŽŸàŽ¯ àŽàŽ°àµàŽªàŽ€àµ àŽàµàŽ±àµàŽ±àŽ¿àŽ²àµàŽàŽ³àµ àŽ€àµàŽ³àŽ¿àŽ¯àµàŽšàµàŽšàŽ€àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ. àŽ€àŽŸàŽŽàµàŽ¯àµàŽ³àµàŽ³ àŽ¬àŽàµàŽàŽ£àŽ¿àŽ²àµ àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµàŽ€àŽŸàŽ²àµ àŽ
+àŽàµàŽ€àµàŽ€ àŽàŽ°àµàŽªàŽ€àŽ¿àŽ²àµàŽ¯àµàŽàµàŽàµ àŽªàµàŽàŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ. àŽ
+àŽ€àŽ€àµ àŽàµàŽ±àµàŽ±àŽ¿àŽ²àµàŽàŽ³àŽ¿àŽ²àµ àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµàŽ€àŽŸàŽ²àµ, àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿àŽ²àµ àŽžàŽ®àµàŽªàŽ€àµàŽ€àµàŽ³àµàŽ³ àŽàµàŽ±àŽ¿àŽ¯ àŽ¬àŽàµàŽàŽ£àŽ¿àŽ²àµ àŽ
+àŽ®àŽ°àµàŽ€àµàŽ€àŽ¿àŽ¯àŽŸàŽ²àµ àŽ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ àŽ€àµàŽ±àŽ¯àµàŽàµàŽàŽªàµàŽªàµàŽàµàŽàŽ¯àµàŽ àŽàµàŽ¯àµàŽ¯àµàŽ.  
+<p>àŽ€àŽ¿àŽ°àŽ¿àŽàµàŽàŽ¯àŽàµàŽàŽªàµàŽªàµàŽàµàŽšàµàŽš àŽ®àŽŸàŽàµàŽžàŽ¿àŽ®àŽ àŽàŽ£àµàŽ£àŽ 50 àŽàŽšàµàŽšàµàŽ³àµàŽ³àŽ€àµ àŽ®àŽŸàŽ±àµàŽ±àµàŽµàŽŸàŽšàŽŸàŽ¯àŽ¿ <i>_Global:linktextPREFERENCES_</i> àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµàŽ¯àµàŽ <p> 
+}  
+
+_texthelpquerytermstitle_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµâ àŽªàŽŠàŽàµàŽàŽ³àµâ}  
+_texthelpqueryterms_ [l=ml] {<p>àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàµàŽ³àµàŽ³ àŽàŽ³àµàŽ³àŽ¿àŽ¯àŽ¿àŽ²àµ àŽšàŽ¿àŽàµàŽàŽ³àµ àŽàµàŽªàµàŽªàµàŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàŽ€àµ àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽàµ àŽàµàŽàµàŽàŽ®àµ àŽ¶àµàŽ²àŽ¿àŽ¯àµ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽšàµàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽš àŽªàŽŠàŽàµàŽàŽ³àŽŸàŽ¯àŽ¿ àŽàŽ£àŽàµàŽàŽŸàŽàµàŽàµàŽ. àŽ
+àŽàµàŽ·àŽ°àŽàµàŽàŽ³àµàŽ àŽ
+àŽàµàŽàŽàµàŽàŽ³àµàŽ àŽàŽ³àµàŽªàµàŽªàµàŽàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽšàµàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽš àŽªàŽŠàŽàµàŽàŽ³àµ. àŽàŽŠàµàŽ§àŽ°àŽ£àŽ¿àŽàŽ³àµàŽàµàŽàµàŽ³àµàŽ³àŽ¿àŽ²àµ ("...")àŽµàŽ°àµàŽšàµàŽš àŽªàŽŠàŽàµàŽàŽ³àµàŽàµ àŽàµàŽàµàŽàŽàµàŽàŽ³àµàŽ àŽàŽàŽŸàŽ. àŽªàŽŠàŽàµàŽàŽ³àµ àŽ¶àµàŽšàµàŽ¯àŽžàµàŽ¥àŽ²àŽ àŽàµàŽ£àµàŽàµ àŽµàµàŽ°àµàŽ€àŽ¿àŽ°àŽ¿àŽ¯àµàŽàµàŽàµàŽ. àŽàµàŽ®àŽ¯àµ àŽ¶àµàŽšàµàŽ¯àŽžàµàŽ¥àŽ²àŽ®àŽŸàŽ¯àŽ¿ àŽàŽ£àŽàµàŽàŽŸàŽàµàŽàµàŽ.. àŽ
+àŽ€àŽ¿àŽšàµ àŽ
+àŽµàŽàŽ£àŽ¿àŽàµàŽàµàŽàŽ¯àµàŽ àŽàµàŽ¯àµàŽ¯àµàŽ. àŽµàŽ¿àŽ°àŽŸàŽ®àŽàŽ¿àŽ¹àµàŽšàŽàµàŽàŽ³àµ àŽàŽ³àµàŽ³ àŽµàŽŸàŽàµàŽ¯àŽàµàŽàŽ³àµàŽàµàŽ£àµàŽàµ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ®àŽ²àµàŽ².  
+ 
+<p>àŽàŽŠàŽŸàŽ¹àŽ°àŽ£àŽ€àµàŽ€àŽ¿àŽšàµ àŽàŽ°àµ àŽàµàŽŠàµàŽ¯àŽ<p> 
+<ul><kbd>àŽªàŽžàŽ«àŽ¿àŽàµ àŽàŽ²àŽšàµàŽ±àµàŽàŽ³àŽ¿àŽ²àµ àŽàŽŸàŽ°àµàŽ·àŽ¿àŽàŽµàŽšàŽµàŽ²àµàŽàµàŽàŽ°àŽ£àŽ: àŽšàŽ¿àŽ²àŽšàŽ¿àŽ²àµàŽªàŽ¿àŽšàµ àŽžàŽ¹àŽŸàŽ¯àŽàŽ®àŽŸàŽ¯ àŽàŽàŽš (1993) </kbd></ul> 
+       <p>àŽàŽšàµàŽšàŽ€àµ àŽªàŽ°àŽ¿àŽàŽ£àŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽ  
+<p>àŽªàŽžàŽ«àŽ¿àŽàµ àŽàŽ²àŽšàµàŽ±àµàŽàŽ³àŽ¿àŽ²àµ àŽàŽŸàŽ°àµàŽ·àŽ¿àŽàŽµàŽšàŽµàŽ²àµàŽàµàŽàŽ°àŽ£àŽ àŽšàŽ¿àŽ²àŽšàŽ¿àŽ²àµàŽªàŽ¿àŽšàµ àŽžàŽ¹àŽŸàŽ¯àŽàŽ®àŽŸàŽ¯ àŽàŽàŽš </kbd></ul><p> àŽàŽšàµàŽšàŽŸàŽ¯àŽ¿àŽàµàŽàŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ 
+}  
+
+_texthelpmgppsearching_ [l=ml] {àŽàŽàŽàŽ¿àŽªàŽ¿àŽªàŽ¿ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽ¿àŽàµàŽ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽ®àŽ±àµàŽ±àµàŽàŽ¿àŽ² àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ€àŽàŽ³àµ àŽàŽ£àµàŽàµàµ.  <ul> 
+<li>A <b>*</b> àŽžàŽàŽ¶àŽ¯àŽªàŽŠàŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽàŽàµàŽµàŽ¿àŽ²àµ àŽ àŽ
+àŽàµàŽ·àŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽ€àµàŽàŽàµàŽàµàŽšàµàŽš àŽ®àµàŽŽàµàŽµàŽšàµ <b>starting with</b> àŽªàŽŠàŽàµàŽàŽ³àµàŽ àŽªàµàŽ°àŽ€àµàŽ¯àŽàµàŽ·àŽ®àŽŸàŽµàµàŽšàµàŽšàµ 
+<li><b>/x</b> àŽžàŽàŽ¶àŽ¯àŽªàŽŠàŽàµàŽàŽ³àŽ¿àŽ²àµ àŽàŽ€àµàŽàµàŽàŽ¿àŽ²àµàŽ àŽàŽšàµàŽšàŽ¿àŽšàµ àŽàµàŽàµàŽ€àŽ²àŽ¿àŽšàµ àŽ
+àŽ§àŽ¿àŽàŽªàµàŽ°àŽŸàŽ§àŽŸàŽšàµàŽ¯àŽ àŽàµàŽàµàŽàµàŽàŽŸàŽµàµàŽšàµàŽšàŽ€àµàŽ®àŽŸàŽ£àµ. àŽàŽŠàŽŸàŽ¹àŽ°àŽ£àŽ®àŽŸàŽ¯àŽ¿ <b>computer/10 science</b>àŽàŽšàµàŽšàµ àŽàµàŽàµàŽ€àµàŽ€àŽŸàŽ²àµ àŽžàŽ¯àŽšàµàŽžàŽ¿àŽšàµàŽàµàŽàŽŸàŽ³àµàŽ 10 àŽàŽ°àŽàµàŽàŽ¿ àŽªàµàŽ°àŽŸàŽ§àŽŸàŽšàµàŽ¯àŽ àŽàŽàŽªàµàŽ¯àµàŽàµàŽàŽ±àŽ¿àŽšàµ àŽ²àŽ­àŽ¿àŽàµàŽàµàŽšàµàŽšàµ</ul>}  
+
+_texthelplucenesearching_ [l=ml] {àŽ²àµàŽžàŽ¿àŽšàµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµâ àŽàŽ¿àŽ² àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ€àŽàŽ³àµâ àŽàŽ£àµàŽàµâ
+
+<li><b>?</b> àŽàŽ°àµ àŽ
+àŽàµàŽ·àŽ°àŽ€àµàŽ€àŽ¿àŽšàµâ àŽªàŽàŽ°àŽ®àŽŸàŽ¯àŽ¿ àŽ€àµàŽ°àµàŽªàµàŽªàŽ¿àŽ±àŽàµàŽàŽ¿ àŽšàµàŽàµàŽàŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµâ. àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽ. àŽàŽŠàŽŸàŽ¹àŽ°àŽ£àŽ€àµàŽ€àŽ¿àŽšàµâ  <b>b?t</b> àŽ®àŽŸàŽàµàŽàŽ¿àŽàµ  <b>bet</b>, <b>bit</b> and <b>bat</b> àŽšàµàŽàµàŽàµàŽ.
+<li><b>*</b> àŽàŽšàµàŽšàŽ€àµâ <b>comput*</b> àŽàŽ®àµàŽªàµàŽ¯àµàŽàµàŽàŽ¿àŽàµàŽ®àŽŸàŽ¯àŽ¿ àŽ®àŽŸàŽàµàŽàµàŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàµ <b>comput</b>.
+</ul>. àŽàŽšàµàŽšàŽ¿àŽ²àŽ§àŽ¿àŽàŽ àŽ
+àŽàµàŽ·àŽ°àŽàµàŽàŽ³àµâàŽàµàŽàµâ àŽªàŽàŽ°àŽ®àŽŸàŽ¯àµàŽ àŽàŽ€àµ àŽšàŽ®àµàŽªàŽ°àŽ¿àŽ±àŽàµàŽàŽŸàŽ. àŽàŽŠàŽŸàŽ¹àŽ°àŽ£àŽ€àµàŽ€àŽ¿àŽšàµâ 'àŽàŽàŽªàµàŽ¯àµ' àŽàŽšàµàŽšàµàŽàµàŽàµàŽ€àµàŽ€àŽŸàŽ²àµâ 'àŽàŽàŽªàµàŽ¯àµ' àŽµàŽ¿àŽ²àµâ àŽ€àµàŽàŽàµàŽàŽ¿ àŽžàŽàŽ²àŽªàŽŠàŽàµàŽàŽ³àµàŽ àŽµàµàŽ¯àŽàµàŽ€àŽ®àŽŸàŽµàµàŽ. àŽàŽ¯àµàŽ°àµ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµâ àŽ°àµàŽ€àŽ¿ àŽµàŽŸàŽàµàŽàŽ¿àŽšàŽ¿àŽàŽ¯àŽ¿àŽ²àµàŽ àŽ¶àµàŽ·àŽµàµàŽ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽ. àŽªàŽàµàŽ·àµ àŽµàŽŸàŽàµàŽàŽ¿àŽšàµàŽ®àµàŽ®àµàŽªàŽ¿àŽ²àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽšàŽŸàŽµàŽ¿àŽ²àµàŽ².}  
+
+_texthelpquerytypetitle_ [l=ml] {àŽàµàŽŠàµàŽ¯àŽ°àµàŽªàŽ}  
+_texthelpquerytype_ [l=ml] {<p>àŽ°àŽ£àµàŽàµàŽ€àŽ°àŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµàŽàŽ³àµ àŽàŽ£àµàŽàµ. <ul> 
+ 
+<li>àŽàŽ²àµàŽ²àŽŸ àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽàµàŽàµàŽ àŽµàµàŽ£àµàŽàŽ¿àŽ¯àµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµàŽàŽ³àµ<b>all</b> . àŽ
+àŽµ àŽ
+àŽ€àŽ¿àŽ²àµàŽ³àµàŽ³ àŽàŽ²àµàŽ²àŽŸ àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽ àŽàŽ³àµàŽ³ àŽ°àµàŽàŽàŽ³àµ, àŽ
+àŽŠàµàŽ§àµàŽ¯àŽŸàŽ¯àŽàµàŽàŽ³àµ, àŽ¶àµàŽ°àµàŽ·àŽàŽàµàŽàŽ³àµ àŽàŽšàµàŽšàŽ¿àŽ² àŽšàµàŽàµàŽàŽ¿ àŽ
+àŽšàµàŽ¯àµàŽàµàŽ¯àŽ®àŽŸàŽ¯ àŽàµàŽ°àŽšàµàŽ¥àŽàµàŽàŽ³àµ àŽªàµàŽ°àŽŠàŽ°àµàŽ¶àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽ. àŽ
+àŽ€àµ àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽ¿àŽàµàŽ àŽàµàŽ°àŽ®àŽ€àµàŽ€àŽ¿àŽ²àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽàµàŽàµàŽµàµàŽ£àµàŽàŽ¿àŽ¯àµàŽ³àµàŽ³ àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽ.  
+<p> 
+ 
+<li>àŽšàŽ¿àŽàµàŽàŽ³àµ àŽ€àµàŽàµàŽšàµàŽš àŽ°àµàŽàŽàŽ³àŽ¿àŽ²àµàŽ³àµàŽ³ àŽàµàŽ°àŽšàµàŽ¥àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽàŽ£àµàŽàŽŸàŽàŽŸàŽµàµàŽšàµàŽš àŽàŽ¿àŽ² àŽµàŽŸàŽàµàŽàµàŽàŽ³àµ <b>some</b> àŽšàŽ²àµàŽàµàŽ. àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽšàµàŽ³àµàŽ³ àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽ àŽàµàŽ°àŽšàµàŽ¥àŽàµàŽàŽ³àŽ¿àŽ²àµàŽ³àµàŽ³àŽµàŽ¯àµàŽ àŽ€àŽ®àµàŽ®àŽ¿àŽ²àµ àŽàŽ€àµàŽ° àŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽšàµ àŽàŽšàµàŽšàŽ€àŽ¿àŽšàµàŽ±àµ àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽšàŽ€àµàŽ€àŽ¿àŽ²àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ àŽ°àµàŽàŽàŽ³àµ àŽªàµàŽ°àŽŠàŽ°àµàŽ¶àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽ 
+ 
+<p><ul> 
+         <li> àŽàµàŽàµàŽ€àŽ²àµ àŽªàŽŠàŽàµàŽàŽ³àµ àŽàŽ³àµàŽàµàŽàµàŽ³àµàŽ³àµàŽšàµàŽš àŽ°àµàŽàŽàŽ³àµ àŽàµàŽàµàŽ€àŽ²àµ àŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽŸàŽ¯àŽ¿ àŽàŽŸàŽ£àŽŸàŽ. 
+ 
+  <li> àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽµàŽ³àŽ°àµ àŽ
+àŽªàµàŽ°àµàŽµàµàŽµàŽ®àŽŸàŽ¯àŽ¿ àŽàŽŸàŽ£àµàŽšàµàŽš àŽªàŽŠàŽ¹àµàŽàŽ³àµ àŽžàŽ°àµàŽµàµàŽµàŽžàŽŸàŽ§àŽŸàŽ°àŽ£ àŽàŽŸàŽ£àµàŽšàµàŽš àŽªàŽŠàŽàµàŽàŽ³àµàŽàµàŽàŽŸàŽ³àµ àŽªàµàŽ°àŽ§àŽŸàŽšàŽ®àŽŸàŽ£àµ 
+ 
+<li> àŽ¹àµàŽžàµàŽµàŽ°àµàŽàŽàŽ³àŽŸàŽ£àµ àŽ¬àµàŽ¹àŽ€àµàŽ€àŽŸàŽ¯ àŽ°àµàŽàŽàŽ³àµàŽàµàŽàŽŸàŽ³àµ àŽàµàŽàµàŽ€àŽ²àµ àŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ 
+       </ul> 
+</ul> 
+àŽàµàŽ±àµ àŽµàŽŸàŽàµàŽàµàŽàŽ³àµ àŽàŽ°àµ àŽµàŽŸàŽàŽàŽ àŽ€àŽšàµàŽšàµàŽ¯àµ àŽµàµàŽ£àŽ®àµàŽàµàŽàŽ¿àŽ²àµ àŽàŽ°àµ àŽàŽ£àµàŽ¡àŽ¿àŽàŽ€àŽšàµàŽšàµàŽ¯àµ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽ<p> }  
+
+_texthelpadvancedsearchtitle_ [l=ml] {_1_ àŽžàŽ°àµàŽàµàŽàµ àŽàŽšàµàŽàŽ¿àŽšàµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ³àµàŽ³ àŽàµàŽàµàŽ€àŽ²àµ àŽšàŽ¿àŽ²àŽµàŽŸàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ}  
+
+_texthelpadvancedsearch_ [l=ml] {<p> àŽ€àŽŸàŽàµàŽ àŽµàŽ¿àŽàŽžàŽ¿àŽ€ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàµ àŽ®àµ àŽàŽ£àŽš àŽšàŽàµàŽšàµàŽšàµàŽµàµàŽàµàŽàŽ¿, àŽ
+àŽ²àµàŽªàŽ àŽµàµàŽ¯àŽ€àµàŽ¯àŽžàµàŽ€àŽ®àŽŸàŽ¯ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿ àŽ°àµàŽ€àŽ¿àŽàŽ³àµàŽ£àµàŽàµ.}  
+
+_texthelpadvsearchmg_ [l=ml] {àŽàŽ.àŽàŽ¿ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽàŽ¯àŽ°àµàŽšàµàŽš àŽšàŽ¿àŽ²àŽµàŽŸàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽ°àŽ£àµàŽàµàŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ€àŽàŽ³àµ àŽšàŽ²àŽàµàŽšàµàŽšàµ. àŽàµàŽ°àŽ®àŽŸàŽšàµàŽžàµàŽ€àŽµàµàŽ àŽ¬àµàŽ²àŽ¿àŽ¯àŽšàµàŽ 
+A <b>ranked</b> search is exactly the same as the <b>some</b> search descibed in <a href="\#query-type">_texthelpquerytypetitle_</a>. 
+<p>_texthelpbooleansearch}  
+
+_texthelpbooleansearch_ [l=ml] {àŽàŽ°àµ <b>àŽ¬àµàŽ²àŽ¿àŽ¯àŽšàµ</b>àŽ¬àµàŽ²àŽ¿àŽ¯àŽšàµ àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàµ àŽªàŽŠàŽàµàŽàŽ³àµ àŽ€àŽ®àµàŽ®àŽ¿àŽ²àµ & (for "and"), | (for "or"), and ! (for "not") àŽàŽšàµàŽšàŽ¿àŽµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ àŽ¬àµàŽ°àŽŸàŽàµàŽàŽ±àµàŽ±àŽ¿àŽšàµàŽ³àµàŽ³àŽ¿àŽ²àµ àŽàŽ³àµàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽ¿àŽ¯àµàŽ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽšàµ àŽžàŽ¹àŽŸàŽ¯àŽ¿àŽàµàŽàµàŽ.   
+<p>àŽàŽŠàŽŸàŽ¹àŽ°àŽ£àŽ€àµàŽ€àŽ¿àŽšàµ <b>snail & farming</b> àŽàŽšàµàŽšàŽ€àŽŸàŽ£àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµàŽàµàŽàŽ¿ àŽ°àŽ£àµàŽàµ àŽªàŽŠàŽàµàŽàŽ³àµàŽ àŽžàŽàŽ¬àŽšàµàŽ§àŽ¿àŽàµàŽ<b>snail</b> AND <b>farming</b> àŽ°àµàŽàŽàŽ³àµàŽ <b>snail | farming</b> àŽàŽšàµàŽšàŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµ àŽ
+àŽµàŽ¯àŽ¿àŽ²àµ àŽàŽ€àµàŽàµàŽàŽ¿àŽ²àµàŽ àŽàŽšàµàŽšàŽ¿àŽšàµ either <b>snail</b> OR <b>farming</b> àŽžàŽàŽ¬àŽšàµàŽ§àŽ¿àŽàµàŽàŽµàŽ¯àµàŽ <b>snail !farming</b> àŽàŽ£àµàŽàµàŽàŽ¿àŽ²àµ àŽàŽšàµàŽšàŽŸàŽ®àŽ€àµàŽ€àµàŽ€àµ àŽàŽ³àµàŽ³àŽ€àµàŽ àŽ°àŽ£àµàŽàŽŸàŽ®àŽ€àµàŽ€àµàŽ€àµ àŽàŽ²àµàŽ²àŽŸàŽ€àµàŽ€àŽ€àµàŽ®àŽŸàŽ¯ àŽ°àµàŽàŽàŽ³àµàŽ®àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ àŽ²àŽ­àŽ¿àŽàµàŽàµàŽ.   
+<p>àŽ àŽ¬àµàŽ²àŽ¿àŽ¯àŽšàµ àŽàŽªàµàŽªàŽ±àµàŽ±àµàŽ±àµàŽŽàµàŽžàŽ¿àŽšàµàŽ±àµ àŽàµàŽàµàŽàŽŸàŽ¯ àŽàŽªàŽ¯àµàŽàŽ àŽ®àµàŽ²àŽ àŽàµàŽàµàŽ€àŽ²àµ àŽ«àŽ²àŽµàŽ€àµàŽ€àŽŸàŽ¯ àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽ àŽšàŽàŽ€àµàŽ€àŽŸàŽšàµ àŽàŽŽàŽ¿àŽ¯àµàŽ}  
+
+_texthelpadvsearchmgpp_ [l=ml] {àŽàŽàŽàŽ¿àŽªàŽ¿àŽªàŽ¿ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽàŽ¯àŽ°àµàŽšàµàŽš àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàµ àŽ¬àµàŽ²àŽ¿àŽ¯àŽšàµ àŽàŽªàµàŽªàŽ±àµàŽ±àµàŽ±àµàŽŽàµàŽžàµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ _texthelpbooleansearch_   
+<p>àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàµàŽ±àµ àŽàµàŽ°àŽ®àŽªàµàŽ°àŽàŽŸàŽ°àŽ®àµ àŽžàŽŸàŽ§àŽŸàŽ°àŽ£ àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽŸàŽ£àŽàµàŽ°àŽ®àŽ àŽ
+àŽšàµàŽžàŽ°àŽ¿àŽàµàŽàµ àŽàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ àŽ°àµàŽàŽàŽ³àµ àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽŸàŽ£àŽ€àµàŽ€àŽ¿àŽšàµàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽ€àŽ¿àŽšàµàŽ±àµ àŽàµàŽ°àŽ®àŽ. 
+àŽ°àŽ£àµàŽàŽŸàŽ®àŽ€àµàŽ€àµàŽ€àµ àŽ¶àµàŽàŽ°àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽŸàŽ£àŽµàµàŽ³àŽ¯àŽ¿àŽ²àµ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµ àŽªàµàŽ°àµàŽŸàŽžàŽžàµ àŽàµàŽ¯àŽ€àµ àŽàµàŽ°àŽ®àŽ€àµàŽ€àŽ¿àŽ²àŽŸàŽ£àµ 
+NEARx and WITHINx. NEARx àŽ°àŽ£àµàŽàµ àŽžàŽàŽ¶àŽ¯àŽªàŽŠàŽàµàŽàŽ³àµàŽàµàŽàŽ¿àŽàŽ¯àŽ¿àŽ²àµ àŽªàŽ°àŽ®àŽŸàŽµàŽ§àŽ¿ àŽŠàµàŽ°àŽ àŽàµàŽ°àŽ®àµàŽàŽ°àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽšàŽŸàŽ¯àŽ¿ (10 àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽàµàŽ€àµ) , àŽàŽ°àµ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ€àµàŽ€àŽ¿àŽšàµàŽµàµàŽ£àµàŽàŽ¿àŽ¯àµàŽ³àµàŽ³ àŽ°àŽ£àµàŽàµ àŽžàŽàŽ¶àŽ¯àŽªàŽŠàŽàµàŽàŽ³àµ àŽµàµàŽ°àµàŽ€àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽšàŽŸàŽ¯àµàŽ àŽàŽ€àµ àŽžàŽ¹àŽŸàŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽšàµ 
+WITHINx àŽ°àŽ£àµàŽàŽŸàŽ®àŽ€àµàŽ€àµ àŽžàŽàŽ¶àŽ¯àŽªàŽŠàŽ àŽ
+àŽàµàŽ€àµàŽ€ x àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽàµàŽàµàŽ³àµàŽ³àŽ¿àŽ²àµ after àŽµàŽ°àµàŽ£àµàŽàŽ€àŽŸàŽ£àµàŽšàµàŽšàµ àŽ
+àŽ°àµàŽ€àµàŽ¥àŽ®àŽŸàŽàµàŽàµàŽšàµàŽšàµ. àŽàŽ€àŽŸàŽ£àµàŽàµ NEAR àŽšàµàŽàµ àŽžàŽŸàŽ®àµàŽ¯àŽ®àµàŽ£àµàŽàµàŽàµàŽàŽ¿àŽ²àµàŽ àŽàŽ°àµàŽ¡àŽ°àµ àŽ
+àŽ€àµàŽ¯àŽŸàŽµàŽ¶àµàŽ¯àŽ®àŽŸàŽ£àµ. àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµ àŽàµàŽàµàŽ€àµàŽ€àµàŽµàµàŽ¯àµàŽàµàŽàŽªàµàŽªàµàŽàµàŽ àŽ
+àŽàŽ²àŽ 20 àŽàŽ£àµ}  
+
+_texthelpadvancedsearchextra_ [l=ml] {àŽ¶àµàŽ°àŽŠàµàŽ§àŽ¿àŽàµàŽàµàŽ: àŽ àŽàŽªàµàŽªàŽ±àµàŽ±àµàŽ±àµàŽŽàµâàŽžàµâ àŽ²àŽ³àŽ¿àŽ€àŽ®àŽŸàŽ¯ àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽ°àµàŽ€àŽ¿àŽ¯àµ àŽ
+àŽµàŽàŽ£àŽ¿àŽàµàŽàµàŽàµàŽàŽŸàŽ}  
+
+_texthelpadvsearchlucene_ [l=ml] {àŽ²àµàŽžàŽ¿àŽšàµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽš àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽàŽšàµàŽšàŽ€àŽšàŽ¿àŽ²àŽµàŽŸàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàŽŸàŽ¯àŽ¿ àŽ¬àµàŽ²àŽ¿àŽ¯àŽšàµ àŽàŽªàµàŽªàŽ±àµàŽ±àµàŽ±àµàŽŽàµàŽžàµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ_texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=ml] {àŽ«àµàŽ²àµàŽ¡àµ àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽšàŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ}  
+
+_texthelpformsearch_ [l=ml] {<p>àŽ°àŽ£àµàŽàµàŽ«àµàŽ²àµâàŽ¡àµàŽàŽ³àµâ àŽàµàŽàµàŽàŽ¿àŽàµàŽàµàŽ°àµâàŽ€àµàŽ€àµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµâ àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ®àŽŸàŽ£àµâ. àŽàŽŠàŽŸàŽ¹àŽ°àŽ£àŽ€àµàŽ€àŽ¿àŽšàµâ àŽ¶àµàŽ°àµâàŽ·àŽàŽ€àµàŽ€àŽ¿àŽ²àµâ 'àŽžàµâàµâàŽ®àŽ¿àŽ€àµàŽ€àµàŽ' àŽµàŽ¿àŽ·àŽ¯àŽ€àµàŽ€àŽ¿àŽ²àµâ 'àŽàµàŽàµàŽàµàŽàµàŽ·àŽ¿àŽ¯àµàŽ' àŽàµàŽàµàŽàŽ¿ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµâ àŽšàŽàŽ€àµàŽ€àŽŸàŽ. àŽ¶àµàŽ°àµâàŽ·àŽàŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµàŽ¯àµàŽ àŽµàŽ¿àŽ·àŽ¯àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµàŽ¯àµàŽ àŽàŽàŽ¯àŽ¿àŽ²àµâ àŽšàŽ²àµâàŽàŽ¿àŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽšàµàŽš àŽ¬àŽàµàŽàŽ£àµàŽàŽ³àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽ£àµâ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµâ àŽžàŽàŽ¯àµàŽàŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµâ. 
+àŽàŽ°àµ àŽ«àµàŽ²àµâàŽ¡àŽ¿àŽ²àµàŽ³àµàŽ³ àŽàŽšàµàŽšàŽ¿àŽ²àŽ§àŽ¿àŽàŽ àŽªàŽŠàŽàµàŽàŽ³àµàŽ àŽàµàŽàµàŽàŽ¿àŽàµàŽàµàŽ°àµâàŽàµàŽàŽŸàŽ. àŽµàŽ³àŽ°àµ àŽžàŽàµàŽàµàŽ°àµâàŽ£àŽ®àŽŸàŽ¯ àŽ°àµàŽ€àŽ¿àŽ¯àŽ¿àŽ²àµâ àŽàŽ¯àŽ°àµâàŽšàµàŽš àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽàµàŽàŽ³àŽ¿àŽ²àµâ and/of/not àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽ.}  
+
+_texthelpformstemming_ [l=ml] {àŽ«àµàŽ³àµàŽ¡àµ, àŽžàµàŽ±àµàŽ±àµàŽ "fold" and "stem"àŽàŽšàµàŽšàµ àŽ¬àµàŽàµàŽžàµàŽàŽ³àµ àŽ«àµàŽ²àµàŽ¡àŽ¿àŽ²àµàŽ³àµàŽ³ àŽ¡àŽŸàŽ±àµàŽ± àŽàµàŽ¯àµàŽžàµàŽ«àµàŽ³àµàŽ¡àŽ¡àµ àŽžàµàŽ±àµàŽ±àµàŽàŽ¡àµ àŽàŽ£àµàŽšàµàŽšàµ àŽªàµàŽ°àŽ€àŽ¿àŽªàŽŸàŽŠàŽ¿àŽàµàŽàŽŸàŽšàµàŽ³àµàŽ³àŽ€àŽŸàŽ£àµ. }  
+
+
+
+_texthelpdatesearch_ [l=ml] {àŽ€àµàŽ¯àµàŽ¯àŽ€àŽ¿ àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽšàŽ®àŽŸàŽàµàŽàŽ¿àŽ¯àµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽ²àµâ àŽ²àŽ­àŽ¿àŽàµàŽàµàŽ àŽ àŽ€àµàŽ¯àµàŽ¯àŽ€àŽ¿ àŽàŽ³àµâàŽªàµàŽªàµàŽàµàŽšàµàŽš àŽàŽŸàŽ²àŽ¯àŽ³àŽµàµàŽžàµàŽàŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµàŽ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàµâ àŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµàŽ®àŽŸàŽ¯ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ. àŽàŽ°àµ àŽªàµàŽ°àŽ€àµàŽ¯àµàŽ àŽµàŽ°àµâàŽ·àŽ€àµàŽ€àµàŽ€àµ àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿àŽ²àµâ àŽšàŽ¿àŽ¶àµàŽàŽ¿àŽ€ àŽµàŽ°àµâàŽ·àŽàµàŽàŽ³àŽ¿àŽ²àµàŽ€àµ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµâàŽàµàŽàŽŸàŽ¯àµàŽ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµâ. 
+
+àŽ€àŽŸàŽàµàŽàŽ³àµâàŽàµàŽàµâ àŽàŽ°àµ àŽ€àµàŽ¯àµàŽ¯àŽ€àŽ¿àŽ¯àµ àŽàŽ°àµ àŽàŽŸàŽ²àŽ¯àŽ³àŽµàµ àŽµàŽàµàŽàµâ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµâ àŽšàŽàŽ€àµàŽ€àŽŸàŽ. 
+}  
+
+_texthelpdatehowtotitle_ [l=ml] {àŽ àŽµàŽ¿àŽ¶àµàŽ·àŽàµàŽ£àŽ àŽàŽàµàŽàŽ¿àŽšàµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽ}  
+_texthelpdatehowto_ [l=ml] {<ul> 
+  <li>àŽàŽ°àµ àŽµàŽ°àµàŽ·àŽ€àµàŽ€àµ àŽžàŽàŽ¬àŽšàµàŽ§àŽ¿àŽàµàŽ àŽàŽ²àµàŽ²àŽŸ àŽ°àµàŽàŽàŽ³àµàŽ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽšàµ 
+<li>àŽžàŽŸàŽ§àŽŸàŽ°àŽ£àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽšàµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽš àŽªàŽŠàŽàµàŽàŽ³àµ àŽàµàŽªàµàŽªàµàŽàµàŽ¯àµàŽ¯àµàŽ 
+<li>àŽàŽµàŽ¶àµàŽ¯àŽ®àµàŽ³àµàŽ³ àŽµàŽ°àµàŽ·àŽ "àŽ€àµàŽàŽàµàŽ àŽ€àµàŽ¯àŽ€àŽ¿" àŽàŽšàµàŽš àŽàŽ³àµàŽ³àŽ¿àŽ¯àŽ¿àŽ²àµ àŽàµàŽªàµàŽªàµàŽàµàŽ¯àµàŽ¯àµàŽ 
+<li>àŽšàŽ¿àŽàµàŽàŽ³àµàŽàµ àŽ€àµàŽ¯àŽ€àŽ¿ àŽªàµàŽ€àµàŽµàŽ°àµàŽ·àŽàµàŽàŽ³àµàŽàµàŽàµ àŽ®àµàŽ®àµàŽªàŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµ àŽ
+àŽ€àµ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽàµàŽàµàŽ 
+<li>àŽžàŽŸàŽ§àŽŸàŽ°àŽ£àŽªàµàŽ²àµ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽ€àµàŽàŽ°àµàŽ 
+</ul> 
+<p><li>àŽàµàŽ±àµ àŽµàŽ°àµàŽ·àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽšàµ 
+<p> 
+    <ul> 
+        <li>àŽžàŽŸàŽ§àŽŸàŽ°àŽ£àŽªàµàŽ²àµ àŽàŽ€àµàŽàµàŽàŽ¿àŽ²àµàŽ àŽàŽ°àµ àŽªàŽŠàŽ àŽàµàŽªàµàŽªàµàŽàµàŽ¯àµàŽ¯àµàŽ 
+     <li>àŽ
+àŽ€àŽ¿àŽ²àµ àŽàŽŠàµàŽ¯àŽµàŽ°àµàŽ·àŽ "àŽ€àµàŽàŽàµàŽ àŽ€àµàŽ¯àµàŽ¯àŽ€àŽ¿" àŽàŽšàµàŽš àŽàŽ³àµàŽ³àŽ¿àŽ¯àŽ¿àŽ²àµ àŽàµàŽªàµàŽªàµ àŽàµàŽ¯àµàŽ¯àµàŽ 
+<li>àŽ
+àŽµàŽžàŽŸàŽšàŽµàŽ°àµàŽ·àŽ àŽ
+àŽ€àŽ¿àŽšàµàŽ³àµàŽ³ àŽàŽ³àµàŽ³àŽ¿àŽ¯àŽ¿àŽ²àµàŽ àŽàµàŽªàµàŽªàµ àŽàµàŽ¯àµàŽ¯àµàŽ 
+<li>àŽªàµàŽ€àµàŽµàŽ°àµàŽ·àŽàµàŽàŽ³àµàŽàµàŽàµàŽ®àµàŽ®àµàŽªàµàŽ³àµàŽ³àŽ€àŽŸàŽ£àµ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽ€àµàŽ¯àµàŽ¯àŽ€àŽ¿àŽ¯àµàŽàµàŽàŽ¿àŽ²àµ àŽ¬àŽ¿àŽžàŽ¿àŽ "B.C.E" àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽàµàŽàµàŽ 
+<li>àŽžàŽŸàŽ§àŽŸàŽ°àŽ£àŽªàµàŽ²àµ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽšàŽàŽ€àµàŽ€àµàŽ}  
+
+_texthelpdateresultstitle_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàµàŽ±àµ àŽ«àŽ²àŽ}  
+_texthelpdateresults_ [l=ml] {1903 àŽšàµàŽàµàŽàµàŽ±àŽ¿àŽàµàŽàµàŽ³àµàŽ³ àŽàµàŽ°àŽšàµàŽ¥àŽàµàŽàŽ³àµ àŽ€àŽ¿àŽ°àŽàµàŽàŽŸàŽ²àµ 1903àŽ²àµ àŽªàµàŽ°àŽžàŽ¿àŽŠàµàŽ§àµàŽàŽ°àŽ¿àŽàµàŽ àŽàµàŽ°àŽšàµàŽ¥àŽàµàŽàŽ³àµ àŽàŽ£àµàŽàµàŽ€àµàŽ€àŽŸàŽšàŽŸàŽ¯àµàŽšàµàŽšàµàŽµàŽ°àŽ¿àŽ²àµàŽ². àŽªàŽàŽ°àŽ 1903 àŽšàµàŽàµàŽàµàŽ±àŽ¿àŽàµàŽàµàŽ³àµàŽ³ àŽàµàŽ°àŽšàµàŽ¥àŽàµàŽàŽ³àŽŸàŽàµàŽ àŽ²àŽªàŽ¿àŽàµàŽàµàŽ. àŽªàŽàµàŽ·àµ àŽàŽ°àµ àŽàŽŸàŽ²àŽ¯àŽ³àŽµàŽ¿àŽšàµàŽ³àµàŽ³àŽ¿àŽ²àµ (àŽ
+àŽ€àŽŸàŽ¯àŽ€àµ 1899 àŽšàµàŽ 1911àŽšàµàŽ®àŽ¿àŽàŽ¯àŽ¿àŽ²àµ) 1903 àŽàŽ³àµàŽªàµàŽªàµàŽàµàŽ®àµàŽšàµàŽšàŽ€àŽ¿àŽšàŽŸàŽ²àµ àŽ
+àŽ€àµàŽ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽàµàŽ. àŽàµàŽ°àŽšàµàŽ¥àŽ€àµàŽ€àŽ¿àŽ²àµ àŽàŽ°àµàŽªàŽ€àŽŸàŽ àŽšàµàŽ±àµàŽ±àŽŸàŽ£àµàŽàµ àŽàŽšàµàŽšàµàŽ£àµàŽàµàŽàµàŽàŽ¿àŽ²àµàŽ àŽ
+àŽ€àŽ¿àŽ²àµ 1903 àŽàŽ³àµàŽªàµàŽªàµàŽàµàŽ®àµàŽšàµàŽšàŽ€àŽ¿àŽšàŽŸàŽ²àµ àŽ
+àŽ€àµàŽ àŽ²àŽ­àŽ¿àŽàµàŽàµàŽ. àŽ
+àŽ€àŽŸàŽ¯àŽ€àµ àŽàŽ¿àŽ² àŽ€àŽ¿àŽ°àŽ¯àŽ²àµàŽàŽ³àŽ¿àŽ²àµ àŽ²àŽ­àŽ¿àŽàµàŽàµàŽšàµàŽšàŽµàŽ¯àµàŽ àŽàµàŽ°àŽšàµàŽ¥àŽàµàŽàŽ³àŽ¿àŽ²àµàŽ³àµàŽ³ àŽµàŽ°àµàŽ·àŽàµàŽàŽ³àµàŽ àŽàŽ€àµàŽ€àµàŽªàµàŽàŽ¿àŽ²àµàŽ². àŽàŽ°àµ àŽàŽŸàŽ²àŽ¯àŽ³àŽµàŽ¿àŽšàµ àŽžàŽàŽ¬àŽšàµàŽ§àŽ¿àŽàµàŽ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàµàŽ àŽàŽ€àµàŽ²àµàŽ²àŽŸàŽ àŽ¬àŽŸàŽ§àŽàŽ®àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ.}  
+
+_textchangeprefs_ [l=ml] {àŽ®àµàŽšàµâàŽàŽ£àŽšàŽàŽ³àµâ àŽ®àŽŸàŽ±àµàŽ±àµàŽ}  
+
+_texthelppreferences_ [l=ml] {<p> àŽ€àŽŸàŽàµàŽ àŽªàµàŽàŽ¿àŽšàµàŽ±àµ àŽ®àµàŽàŽ³àŽ¿àŽ²àµàŽ³àµàŽ³ <i>_Global:linktextPREFERENCES_</i> àŽ¬àŽàµàŽ àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµàŽ€àŽŸ, àŽàŽµàŽ¶àµàŽ¯àŽŸàŽšàµàŽžàµàŽ°àµàŽ€àŽ àŽàŽšàµàŽ±àµàŽ«àµàŽ¯àµàŽžàŽ¿àŽ²àµ àŽžàµàŽàŽ°àµàŽ¯àŽàµàŽàŽ³àŽ¿ àŽ®àŽŸàŽ±àµàŽ±àŽ àŽµàŽ°àµàŽ€àµàŽ€àŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ.}  
+
+_texthelpcollectionprefstitle_ [l=ml] {àŽ¶àµàŽàŽ°àŽžàŽàŽ¬àŽšàµàŽ§ àŽ®àµàŽšàµàŽàŽ£àŽšàŽàŽ³àµ}  
+_texthelpcollectionprefs_ [l=ml] {<p>àŽàŽ¿àŽ² àŽàŽ²àŽàµàŽ·àŽšàµàŽàŽ³àµàŽàµàŽàµ àŽàŽ°àµàŽªàŽŸàŽàµ àŽžàŽ¬àµàŽàŽ²àŽàµàŽ·àŽšàµàŽžàµ àŽàŽ£àµàŽàµ. àŽ
+àŽµàŽ¯àµàŽàµàŽàŽŸàŽ¯àŽ¿ àŽàŽšàµàŽšàµàŽšàµàŽšàŽŸàŽ¯àµ àŽàµàŽàµàŽàŽ®àŽŸàŽ¯àµ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ. àŽàŽ€àµàŽàµàŽàµ àŽžàŽ¬àµàŽàŽ²àŽàµàŽ·àŽšàµàŽžàŽŸàŽ£àµ àŽžàŽ¿àŽ²àŽàµàŽàµ àŽàµàŽ¯àµàŽ¯àµàŽ£àµàŽàŽ€àµàŽšàµàŽšàµ àŽšàŽ¿àŽàµàŽàŽ³àµàŽàµàŽàµ àŽªàµàŽ°àŽ¿àŽ«àŽ±àŽšàµàŽžàµ àŽªàµàŽàŽ¿àŽ²àµ àŽ€àŽšàµàŽšàµ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ. }  
+
+_texthelplanguageprefstitle_ [l=ml] {àŽ­àŽŸàŽ·àŽŸàŽ®àµàŽšàµàŽàŽ£àŽš}  
+_texthelplanguageprefs_ [l=ml] {<p>àŽàŽ°àµ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ àŽàŽ°àµ àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽš àŽªàµàŽ°àŽŠàŽ°àµàŽ¶àŽšàŽ­àŽŸàŽ·àŽ¯àµàŽ£àµàŽàŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ. àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàµ àŽµàµàŽ£àŽ®àµàŽàµàŽàŽ¿àŽ²àµ àŽ®àŽ±àµàŽ±àµàŽ°àµ àŽ­àŽŸàŽ·àŽ¯àŽ¿àŽ²àµàŽàµàŽàµ àŽ®àŽŸàŽ±àŽŸàŽ. àŽ¬àµàŽ°àµàŽžàŽ±àŽ¿àŽ²àµ àŽàŽŸàŽ£àŽ¿àŽàµàŽàµàŽšàµàŽš àŽàŽšàµàŽàµàŽ¡àŽ¿àŽàŽàµàŽ àŽàµàŽàŽ¿ àŽ®àŽŸàŽ±àµàŽ±àŽ¿àŽ¯àŽŸàŽ²àµ àŽ­àŽŸàŽ· àŽ¶àŽ°àŽ¿àŽ¯àŽŸàŽ¯àŽ¿ àŽàŽŸàŽ£àµàŽàŽ¯àµàŽ³àµàŽ³àµ. àŽ°àµàŽàŽŸàŽ°àµàŽªàŽ€àµàŽ€àŽ¿àŽ²àµàŽ àŽàµàŽàµàŽžàµàŽ±àµàŽ±àµ àŽ°àµàŽªàŽ€àµàŽ€àŽ¿àŽ²àµàŽ®àµàŽ³àµàŽ³ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµàŽàµ àŽªàµàŽ°àŽŠàŽ°àµàŽ¶àŽšàŽ€àµàŽ€àŽ¿àŽ²àµàŽàµàŽàµ àŽšàŽ¿àŽàµàŽàŽ³àµàŽàµàŽàµ àŽ®àŽŸàŽ±àŽŸàŽ. àŽàŽŸàŽ£àŽŸàŽšàµ àŽ¬àµàŽŠàµàŽ§àŽ¿àŽ®àµàŽàµàŽàµàŽ³àµàŽ³àŽµàŽ°àµàŽàµàŽàµ àŽµàŽ²àŽ¿àŽ¯ àŽžàµàµàŽàµàŽ°àµàŽšàµ àŽžàŽ¹àŽŸàŽ¯àŽàŽ°àŽ®àŽŸàŽ£àµ}  
+
+_texthelppresentationprefstitle_ [l=ml] {àŽªàµàŽ°àŽŠàŽ°àµàŽ¶àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽ²àµ àŽ®àµàŽšàµàŽàŽ£àŽš}  
+_texthelppresentationprefs_ [l=ml] {àŽàŽ°àµ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ®àŽšàµàŽžàµàŽ€àŽ®àŽŸàŽ¯àŽ¿ àŽªàµàŽ°àŽŠàŽ°àµâàŽ¶àŽšàŽ°àµàŽ€àŽ¿ àŽšàŽ¿àŽ¯àŽšàµàŽ€àµàŽ°àŽ¿àŽàµàŽàµàŽµàŽŸàŽšàµàŽ³àµàŽ³ àŽªàŽ² àŽµàŽŽàŽ¿àŽàŽ³àµàŽ£àµàŽàµâ.
+<p>àŽšàŽ¿àŽàµàŽàŽ³àµâàŽàµàŽàµ àŽ®àµàŽàŽ³àŽ¿àŽ²àµàŽ³àµàŽ³ àŽšàŽŸàŽµàŽ¿àŽàµàŽ·àŽšàµâ àŽ¬àŽŸàŽ°àµâ àŽàŽŸàŽ£àŽŸàŽ€àµàŽ€àŽµàŽ¿àŽ§àŽ àŽàµàŽ°àŽ®àµàŽàŽ°àŽ¿àŽàµàŽàŽŸàŽ. àŽ
+àŽªàµàŽªàµàŽ³àµâ àŽšàŽ¿àŽàµàŽàŽ³àµâ àŽµàµàŽ¬àµâàŽªàµàŽàŽ¿àŽ²àµàŽ¯àµâàŽàµàŽàµâ àŽšàµàŽ°àŽ¿àŽàµàŽàµàŽªàµàŽàµàŽ. àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àµâ àŽ¹àµàŽ¡àµàŽ¡àŽ°àµâ àŽàŽ£àµàŽàŽŸàŽµàµàŽàŽ¯àµàŽ®àŽ¿àŽ²àµàŽ². àŽ®àŽ±àµàŽ±àµàŽ°àµ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµâ àŽšàŽàŽ€àµàŽ€àŽŸàŽšàµâ àŽ¬àµàŽ°àµàŽžàŽ±àŽ¿àŽšàµàŽ±àµ àŽªàµàŽ±àŽàµàŽàµàŽàµàŽªàµàŽàµàŽšàµàŽš àŽ¬àŽàµàŽàŽ£àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽ. àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽµàµàŽ³àŽ¿àŽ²àµàŽ¯àµâàŽàµàŽàµ àŽµàµàŽ¬àµâàµâàŽžàµàŽ±àµàŽ±àŽ¿àŽ²àµàŽàµàŽàµ àŽšàŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽš àŽ²àŽ¿àŽàµàŽàŽ¿àŽ²àµâ àŽ
+àŽ®àŽ°àµâàŽ€àµàŽ€àµàŽ®àµàŽªàµàŽ³àµâ àŽµàŽ°àµàŽšàµàŽš àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµàŽ±àµ àŽ®àµàŽšàµàŽšàŽ±àŽ¿àŽ¯àŽ¿àŽªàµàŽªàµàŽàŽ³àµâ àŽàŽŽàŽ¿àŽµàŽŸàŽàµàŽàŽ¿àŽàµàŽàŽ¿àŽàµàŽàµàŽàŽ¯àµàŽ àŽàµàŽ¯àµàŽ¯àµàŽ. àŽàŽ¿àŽ²àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµâ àŽ€àŽ¿àŽ°àŽ¯àŽ²àŽ¿àŽšàµàŽ¶àµàŽ·àŽ àŽ²àŽ­àŽ¿àŽàµàŽàµàŽšàµàŽš àŽ²àŽ¿àŽàµàŽàµàŽàŽ³àµâ àŽàµàŽ€àµàŽ¯àŽ®àŽŸàŽ¯àŽ¿ àŽšàŽ¿àŽàµàŽàŽ³àµâàŽàµàŽàµ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿àŽ¯àµàŽàµ àŽªàµàŽàŽ¿àŽ²àµâ àŽªàµàŽàŽŸàŽ€àµ, àŽµàµàŽ£àµàŽ àŽµàµàŽ¬àµâàŽªàµàŽàŽ¿àŽ²àµàŽàµàŽàµ àŽªàµàŽàµàŽàŽµàŽ¿àŽ§àŽµàµàŽ àŽàµàŽ°àŽ®àµàŽàŽ°àŽ¿àŽàµàŽàŽŸàŽ. }  
+
+_texthelpsearchprefstitle_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽ®àµàŽšàµàŽàŽ£àŽš}  
+_texthelpsearchprefs_ [l=ml] {àŽàµàŽàµàŽ€àŽ²àµ àŽšàŽ¿àŽ²àŽµàŽŸàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³ àŽ°àµàŽ€àŽ¿àŽ¯àŽ¿àŽ²àµ àŽàŽšàµàŽšàŽ¿àŽ²àŽ§àŽ¿àŽàŽ àŽµàŽŸàŽàµàŽàµàŽàŽ³àµ & (and) I (or), ! (not) àŽàŽ¿àŽ¹àµàŽšàŽàµàŽàŽ³àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽàµàŽ°àµàŽ€àµàŽ€àµ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàµ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ.  
+<p>_selectsearchtypeprefs_ 
+<p>_selectwordmodificationprefs_ 
+ 
+<p>àŽ
+àŽµàŽžàŽŸàŽšàŽ€àµàŽ€àµ àŽàµàŽ±àµ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµàŽàŽ³àµàŽàµ àŽàŽ°àŽ¿àŽ€àµàŽ°àŽ àŽàŽŸàŽ£àŽ¿àŽàµàŽàµàŽàŽµàŽ¿àŽ§àŽ àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽžàŽµàŽ¿àŽ¶àµàŽ·àŽ€àŽàŽ³àµ àŽàµàŽ°àŽ®àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽŸàŽ 
+ 
+<p>àŽ
+àŽµàŽžàŽŸàŽšàŽ®àŽŸàŽ¯àŽ¿ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽ²àµ àŽ²àŽ­àŽ¿àŽàµàŽàµàŽ£àµàŽ àŽ°àµàŽàŽàŽ³àµàŽàµ àŽàŽ£àµàŽ£àŽµàµàŽ àŽàŽ°àµ àŽªàµàŽàŽ¿àŽ²àµ àŽ
+àŽµ àŽàŽ€àµàŽ° àŽ²àŽ­àŽ¿àŽàµàŽàŽ£àŽ®àµàŽšàµàŽšàµàŽ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàµ àŽàµàŽ°àŽ®àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽŸàŽ }  
+
+_textcasefoldprefs_ [l=ml] {àŽ€àŽ¿àŽ°àŽ¯àµàŽ®àµàŽªàµàŽ³àµ àŽàµàŽ±àŽ¿àŽ¯ àŽ
+àŽàµàŽ·àŽ°àŽàµàŽàŽ³àµàŽ àŽµàŽ²àŽ¿àŽ¯ àŽ
+àŽàµàŽ·àŽ°àŽàµàŽàŽ³àµàŽ àŽ¯àµàŽàŽ¿àŽàµàŽàŽ£àŽ®àµ àŽàŽšàµàŽšàµ àŽàŽ°àµ àŽàµàŽàŽ¿ àŽ¬àŽàµàŽàŽ£àµàŽàŽ³àµ àŽàµàŽ£àµàŽàµ àŽšàŽ¿àŽ¯àŽšàµàŽ€àµàŽ°àŽ¿àŽàµàŽàŽŸàŽ. (àŽ®àŽ²àŽ¯àŽŸàŽ³àŽ€àµàŽ€àŽ¿àŽšàµ àŽ¬àŽŸàŽ§àŽàŽ®àŽŸàŽµàµàŽšàµàŽšàŽ¿àŽ²àµàŽ²) àŽàŽŠàŽŸàŽ¹àŽ°àŽ£àŽ®àŽŸàŽ¯àŽ¿  if "_preferences:textignorecase_" is selected, <i>snail farming</i> will be treated the same as <i>Snail Farming</i> and <i>SNAIL FARMING</i>.}  
+_textstemprefs_ [l=ml] {àŽ€àŽ¿àŽ°àŽ¯àµàŽ®àµàŽªàµàŽ³àµâ àŽµàŽŸàŽàµàŽàµàŽàŽ³àµàŽàµ àŽ
+àŽµàŽžàŽŸàŽšàŽ­àŽŸàŽàŽàµàŽ àŽµàµàŽ£àµ àŽ
+àŽ€àµ àŽµàŽ¿àŽàµàŽàµàŽàŽ³àŽ¯àŽ£àµ àŽàŽšàµàŽšàµâ àŽàŽ°àµ àŽàµàŽàŽ¿ àŽ¬àŽàµàŽàŽ£àµàŽàŽ³àµâ àŽšàŽ¿àŽ¶àµàŽàŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽšàµ. àŽàŽŠàŽŸàŽ¹àŽ°àŽ£àŽ®àŽŸàŽ¯àŽ¿ if "_preferences:textstem_" is selected, <i>snail farming</i> will be treated the same as <i>snails farm</i> and <i>snail farmer</i>. àŽàŽ€àµâ àŽàŽªàµàŽªàµàŽ³àµâ àŽ®àŽ²àŽ¯àŽŸàŽ³àŽ€àµàŽ€àŽ¿àŽšàµâ àŽ¬àŽŸàŽ§àŽàŽ®àŽ²àµàŽ²_selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=ml] {àŽ€àŽ¿àŽ°àŽ¯àµàŽ®àµàŽªàµàŽ³àµ àŽàŽàµàŽàŽŸàŽ°àŽ£àŽàŽ¿àŽ¹àµàŽšàŽ àŽàŽ³àµàŽ³àŽ€àµàŽ àŽàŽ²àµàŽ²àŽŸàŽ€àµàŽ€àŽ€àµàŽ àŽ€àŽ®àµàŽ®àŽ¿àŽ²àµ àŽ¯àµàŽàŽ¿àŽàµàŽàŽ£àŽ®àµ àŽàŽšàµàŽšàµ àŽšàŽ¿àŽ°àµàŽ£àŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµ "_preferences:textignoreaccents_" is selected, <i>fÃ©dÃ©ration</i> will be treated the same as <i>fedÃ©ration</i> and <i>federation</i>àŽàŽ£àµ. àŽ°àŽ£àµàŽàµàŽ àŽ¯àµàŽàŽ¿àŽàµàŽàŽ£àŽ®àµàŽàµàŽàŽ¿àŽ²àµ àŽ
+àŽ€àµ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽàµàŽàµàŽ}  
+ 
+_textstemoptionsprefs_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽªàŽŠàŽàµàŽàŽ³àµàŽàµ àŽšàµàŽ³àŽ àŽàµàŽ°àµàŽàµàŽàŽŸàŽšàµàŽ³àµàŽ³ àŽžàŽ®àµàŽªàµàŽ°àŽŠàŽŸàŽ¯àŽ àŽàµàŽàµàŽ€àŽ²àµ àŽžàµàŽàŽ°àµàŽ¯àŽªàµàŽ°àŽŠàŽ®àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ "_texthelpquerytermstitle_".}  
+
+_textsearchtypeprefsplain_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽšàµ àŽàµàŽàµàŽ€àŽ²àµ àŽªàŽŠàŽ®àµ àŽàŽ£àµàŽ¡àŽ¿àŽàŽàŽ³àµ àŽ€àŽšàµàŽšàµàŽ¯àµ àŽàŽ³àµàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽŸàŽšàŽŸàŽµàµàŽ àŽµàŽ¿àŽ§àŽ àŽàŽ³àµàŽ³àŽ¿àŽàŽ³àµàŽàµ àŽµàŽ²àµàŽªàµàŽªàŽ àŽµàŽ°àµàŽŠàµàŽ§àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽŸàŽ. àŽ«àŽ²àŽ àŽ
+àŽ€àŽ¿àŽµàµàŽàŽ àŽ²àŽ­àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµàŽ®àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ}  
+
+_textsearchtypeprefsform_ [l=ml] {àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽ«àµàŽ®àŽ¿àŽ²àµ àŽàŽàŽàŽàµàŽàŽ³àŽ¿àŽ²àµ àŽ®àŽŸàŽ±àµàŽ±àŽ àŽµàŽ°àµàŽ€àµàŽ€àŽŸàŽ}  
+
+_textsearchtypeprefsboth_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàµ àŽžàŽŸàŽ§àŽŸàŽ°àŽ£ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽ«àµàŽ²àµàŽ¡àµ àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽšàŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àµ àŽšàŽàŽ€àµàŽ€àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ<ul> 
+ 
+<li>àŽžàŽŸàŽ§àŽŸàŽ°àŽ£ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽ²àµ àŽàŽ°àµ àŽàŽ³àµàŽ³àŽ¿àŽ¯àµ àŽàŽ£àµàŽàŽŸàŽàµ_textsearchtypeprefsplain_</li>  
+<li>àŽ«àµàŽ²àµàŽ¡àµ àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽšàŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽ¿àŽàµàŽàŽ¿àŽ²àŽ¿àŽ²àµ àŽàµàŽ±àµ àŽàŽ³àµàŽ³àŽ¿àŽàŽ³àµ àŽàŽŸàŽ£àµàŽ. àŽàŽ°àµ àŽàŽ³àµàŽ³àŽ¿àŽ¯àµàŽ àŽàŽ°àµ àŽªàµàŽ°àŽ€àµàŽ¯àµàŽ àŽ«àµàŽ²àµàŽ¡àŽ¿àŽšàµ àŽžàµàŽàŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽšàµàŽšàµ. àŽàŽ°àµ àŽµàµàŽ¯àŽ€àµàŽ¯àŽžàµàŽ€ àŽ«àµàŽ²àµàŽ¡àµàŽàŽ³àµ àŽàŽ±àµàŽ±àŽ¯àŽàŽ¿àŽàµàŽàµ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽšàµ àŽžàŽ¹àŽŸàŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽšàµ_textsearchtypeprefsform_ </li> 
+</ul>}  
+
+
+
+_texttanumbrowseoptions_ [l=ml] {_numbrowseoptions_ àŽµàŽŽàŽ¿àŽàŽ³àŽ¿àŽ²àµàŽàµ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàµàŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµ àŽàŽ£àµàŽàµàŽ€àµàŽ€àŽŸàŽ}  
+
+_textsimplehelpheading_ [l=ml] {_collectionname_ àŽàŽšàµàŽšàŽªàµàŽ°àµàŽ³àµàŽ³ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàµàŽ àŽàŽàµàŽàŽ¿àŽšàµ àŽµàŽ¿àŽµàŽ°àŽ àŽàŽ£àµàŽàµàŽ€àµàŽ€àŽŸàŽ}  
+
+_texthelpscopetitle_ [l=ml] {àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽµàµàŽ¯àŽŸàŽªàµâàŽ€àŽ¿}  
+_texthelpscope_ [l=ml] {<p>àŽ®àŽ¿àŽàµàŽàŽ¶àµàŽàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽšàµàŽ³àµàŽ³ àŽµàµàŽ¯àŽ€àµàŽ¯àŽžàµàŽ€ àŽžàµàŽàŽ¿àŽàŽàŽ³àµ àŽàŽ£àµàŽàŽŸàŽàµàŽ. àŽàŽŠàŽŸàŽ¹àŽ°àŽ£àŽ€àµàŽ€àŽ¿àŽšàµ àŽàµàŽ°àŽšàµàŽ¥àŽàŽ°àµàŽ€àµàŽ€àŽŸàŽµàµ, àŽ¶àŽ¿àŽ°àµàŽ·àŽàŽ àŽàŽšàµàŽšàŽ¿àŽµàŽ¯àµàŽàµ àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽšàŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³àŽµ àŽàŽ£àµàŽàŽŸàŽàµàŽ. àŽ
+àŽŠàµàŽ§àµàŽ¯àŽŸàŽ¯àŽàµàŽàŽ³àµàŽ àŽàŽ£àµàŽ¡àŽ¿àŽàŽàŽ³àµàŽ àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽšàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽ¿àŽ¯àŽµ àŽàŽ£àµàŽàŽŸàŽàµàŽ. àŽàŽ€àµ àŽžàµàŽàŽ¿àŽ àŽ€àŽ¿àŽ°àŽàµàŽàŽŸàŽ²àµàŽ àŽàµàŽ€àµàŽ¯àŽ®àŽŸàŽ¯àŽ¿ àŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽš àŽ°àµàŽàŽàŽ³àµ àŽàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ àŽ€àŽ¿àŽ°àŽàµàŽàŽ¿àŽ²àŽ¿àŽ²àµ àŽ²àŽ­àŽ¿àŽàµàŽàµàŽ 
+ 
+<p>àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµ àŽªàµàŽžàµàŽ€àŽàŽàµàŽàŽ³àŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµ àŽ
+àŽµ àŽàŽàŽ¿àŽ€àŽžàµàŽ¥àŽŸàŽšàŽ€àµàŽ€àµ àŽ€àµàŽ±àŽàµàŽàµàŽàŽ¯àµàŽ àŽàµàŽ¯àµàŽ¯àµàŽ. }  
Index: /gsdl/stable/macros/malayalam2.dm
===================================================================
--- /gsdl/stable/macros/malayalam2.dm	(revision 20131)
+++ /gsdl/stable/macros/malayalam2.dm	(revision 20131)
@@ -0,0 +1,956 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Language text and icon macros 
+# -- this file contains text that is of less importance
+######################################################################
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=ml] {àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµâ}  
+_lastupdate_ [l=ml] {àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµâ}  
+_ago_ [l=ml] {àŽŠàŽ¿àŽµàŽžàŽàµàŽàŽ³àµâàŽàµàŽàµ àŽ®àµàŽ®àµàŽªàµâ}  
+_colnotbuilt_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽàŽ¿àŽàµàŽàŽ¿àŽ²àµàŽ²}  
+
+### taken from here
+
+_textpoem_ [l=ml] {
+<p>àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàµ àŽªàµàŽ°àŽ¶àŽŸàŽšàµàŽ€àŽ€àŽ¯àµàŽ àŽžàŽ®àŽŸàŽ§àŽŸàŽšàŽµàµàŽ àŽàŽ£àµàŽàŽŸàŽµàŽàµàŽàµ 
+<br>àŽàµàŽ°àµàŽ·àµàŽ®àŽàŽŸàŽ²àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽžàµàŽàŽŸàŽšàµàŽ­àµàŽ€àŽ¿àŽ¯àŽ¿àŽ²àµ àŽàŽŽàŽ¿àŽ¯àŽŸàŽšàµ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàŽ¿àŽàŽµàŽ°àŽàµàŽàµ 
+<br>àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽ²àŽàµàŽ·àµàŽ¯àŽàµàŽàŽ³àµ àŽàŽ°àŽàµàŽàµàŽ®àŽ¿àŽšàµàŽàµàŽàŽ¿àŽ¯ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽªàµàŽ²àµ àŽàŽàŽ°àµàŽ·àŽ£àµàŽ¯àŽµàµàŽ àŽµàŽ¶àµàŽ¯àŽµàµàŽ®àŽŸàŽµàŽàµàŽàµ
+}  
+
+_textgreenstone_ [l=ml] {àŽšàµàŽ¯àµàŽžàŽ¿àŽ²àŽŸàŽšàµàŽ±àŽ¿àŽ²àµâ àŽàŽšàµàŽ®àŽàŽàµàŽ£àµàŽ àŽ
+àŽ®àµàŽ²àµàŽ¯àŽ®àŽŸàŽ¯ àŽ°àŽ€àµâàŽšàŽžàŽ®àŽŸàŽš àŽ¶àŽ¿àŽ²àŽ¯àŽŸàŽ£àµâ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ (àŽ àŽžàµàŽ«àµâàŽ±àµàŽ±àµâ àŽµàµàŽ¯àŽ°àµâ àŽªàµàŽ²àµàŽ€àŽšàµàŽšàµ). àŽªàŽ°àŽ®àµàŽªàŽ°àŽŸàŽàŽ€ àŽ®àŽŸàŽµàµàŽ±àŽ¿ àŽžàŽ®àµàŽ¹àŽ€àµàŽ€àŽ¿àŽ²àµâ àŽ
+àŽ€àµâ àŽµàŽ³àŽ°àµ àŽµàŽ¿àŽ²àŽªàŽ¿àŽàŽ¿àŽàµàŽàŽ€àµàŽ àŽ®àŽ±àµàŽ±àµàŽšàµàŽ€àŽ¿àŽšàµàŽ àŽ®àµàŽ€àµàŽ¯àŽŸàŽ¯àŽ¿ àŽàŽ³àµàŽàŽ³àµâ àŽ€àµàŽàŽ¿àŽªàµàŽªàµàŽµàµàŽšàµàŽšàŽ€àµàŽ®àŽŸàŽ¯ àŽàŽ°àµ àŽ
+àŽ®àµàŽ²àµàŽ¯àŽµàŽžàµâàŽ€àµ àŽàŽšàµàŽšàµàŽªàŽ±àŽ¯àŽŸàŽ. àŽàŽ€àµàŽ®àŽŸàŽµàŽ¿àŽšàµ àµâàŽ
+àŽ¥àŽµàŽŸ àŽàµàŽµàŽ¶àµàŽ¶àŽàµàŽ€àŽ¿àŽ¯àµ àŽàŽµàŽŸàŽ¹àŽ¿àŽàµàŽàŽŸàŽšàµàŽ àŽžàµàŽàµàŽ·àŽ¿àŽàµàŽàŽŸàŽšàµàŽ àŽàŽŽàŽ¿àŽµàµàŽ³àµàŽ³àŽ€àµàŽ àŽªàŽ°àŽ®àµàŽªàŽ°àŽŸàŽàŽ€àŽ®àŽŸàŽ¯àŽ¿ àŽàŽ°àµâàŽàŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽ àŽžàŽàŽ² àŽ®àµàŽ²àµàŽ¯àŽàµàŽàŽ³àµàŽàµàŽ¯àµàŽ àŽªàµàŽ°àŽ€àµàŽàŽµàµàŽ®àŽŸàŽ¯àŽ¿ àŽàŽšàŽàµàŽàŽ³àµâ àŽµàŽ¿àŽ¶àµàŽµàŽžàŽ¿àŽàµàŽàµàŽµàŽ°àµàŽšàµàŽšàŽ€àµàŽ®àŽŸàŽ¯àŽ€àµàŽàµàŽ£àµàŽàŽŸàŽ£àµâ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿àŽ¯àµàŽàµ àŽàŽàŽ¬àµàŽ²àŽ®àŽŸàŽ¯àŽ¿ <i>patu</i> àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽ€àŽšàµàŽšàµ àŽžàµàŽµàµàŽàŽ°àŽ¿àŽàµàŽàŽ¿àŽàµàŽàµàŽ³àµàŽ³àŽ€àµâ. àŽ
+àŽ€àŽ¿àŽšàµàŽ±àµ àŽ€àŽ¿àŽ³àŽàµàŽàŽ àŽžàŽŸàŽ°àµâàŽµàµàŽµàŽ€àµàŽ°àµàŽàŽžàµâàŽšàµàŽ¹àŽ€àµàŽ€àµàŽ¯àµàŽ àŽžàµàŽ€àŽŸàŽ°àµàŽ¯àŽ€ àŽžàŽ€àµàŽ¯àŽžàŽšàµàŽ§àŽ€àŽ¯àµàŽ¯àµàŽ àŽàŽŸàŽ àŽ¿àŽšàµàŽ¯àŽ àŽ§àµàŽ°àŽ€àŽ¯àµàŽ¯àµàŽ àŽ®àµàŽ°àµâàŽàµàŽàŽ¯àµàŽ±àŽ¿àŽ¯ àŽ
+àŽ°àŽ¿àŽàµàŽàŽ³àµâ <i>patu</i>àŽšàµàŽ€àŽ¿àŽ¬àµàŽ§àŽ€àµàŽ€àµàŽ¯àµàŽ àŽªàµàŽ°àŽ€àµàŽàŽµàŽ²àµâàŽàµàŽàŽ°àŽ¿àŽàµàŽàµàŽšàµàŽšàµ. àŽ¯àµàŽŠàµàŽ§àŽ€àµàŽ€àŽ¿àŽ²àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽš àŽàŽàŽàµàŽàµàŽàµàŽ€àµàŽ€ àŽàŽŠàŽ¯àŽŸàŽ£àµâ àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àµâ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽžàµàŽ«àµâàŽ±àµàŽ±àµâ àŽµàµàŽ¯àŽ°àµâ àŽ²àµàŽàµ. àŽŠàµàŽµàŽšàµàŽŠàµàŽµàŽ¯àµàŽŠàµàŽ§àŽàµàŽàŽ³àŽ¿àŽ²àµâ àŽàŽŠ àŽàŽ²àµâàŽªàŽ¿àŽàµàŽàµàŽšàµàŽš àŽàŽàŽŸàŽ€àŽ àŽàŽšàŽ€àµàŽ€àŽ€àµàŽ àŽžàµàŽàµàŽ·àµâàŽ®àŽµàµàŽ àŽªàµàŽ°àµâàŽ£àŽµàµàŽ®àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ. àŽ àŽàµàŽ£àŽàµàŽàŽ³àµâ àŽšàŽ®àµàŽ®àµàŽàµ àŽžàµàŽ«àµâàŽ±àµàŽ±àµâ àŽµàµàŽ¯àŽ±àŽ¿àŽšàµàŽ àŽ
+àŽšàŽ¿àŽµàŽŸàŽ°àµàŽ¯àŽ®àŽŸàŽ£àµàŽšàµàŽš àŽ€àµàŽšàµàŽšàŽ²àŽ¿àŽ²àµâ àŽšàŽ¿àŽšàµàŽšàµàŽ®àŽŸàŽ£àµâ àŽàŽŠ àŽàŽàŽ¬àµàŽ²àŽ®àŽŸàŽ¯àŽ¿ àŽµàŽ°àµàŽšàµàŽšàŽ€àµâ. </p>}  
+
+_textaboutgreenstone_ [l=ml] {
+<p>àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿àŽàŽ³àµâàŽàµàŽàµâ àŽµàŽ³àŽ°àµ àŽžàŽ¹àŽŸàŽ¯àŽàŽ®àŽŸàŽ¯ àŽžàµàŽµàŽšàŽàµàŽàŽ³àµâ àŽšàŽ²àµâàŽàµàŽšàµàŽš àŽàŽ°àµ àŽžàµàŽ«àµâàŽ±àµàŽ± àŽµàµàŽ¯àŽ°àµâ àŽžàŽ®àµàŽàµàŽàŽ¯àŽ®àŽŸàŽ£àµâ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµâ. àŽµàŽ¿àŽµàŽ°àŽ¶àµàŽàŽ°àŽ£àŽ€àµàŽ€àŽ¿àŽšàµàŽ àŽàŽšàµàŽ±àŽ°àµâàŽšàµàŽ±àµàŽ±àŽ¿àŽ²àµàŽ àŽžàŽ¿àŽ¡àŽ¿ àŽ±àµàŽ®àŽ¿àŽ²àµàŽ®àŽŸàŽ¯àŽ¿ àŽ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽàµàŽ°àŽ®àµàŽàŽ°àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽšàµàŽ®àŽŸàŽ¯àŽ¿ àŽàŽ°àµ àŽšàµàŽ€àŽšàŽ®àŽŸàŽ°àµâàŽàŽ®àŽŸàŽ£àµâ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ. <b>àŽšàµàŽ¯àµàŽžàŽ¿àŽ²àŽŸàŽšàµàŽ±àŽ¿àŽ²àµ àŽµàµàŽàµàŽàŽŸàŽàµàŽàµ àŽžàŽ°àµâàŽµàµàŽµàŽàŽ²àŽŸàŽ¶àŽŸàŽ²àŽ¯àŽ¿àŽ²àµ </b> at the <b>àŽšàµàŽ¯àµàŽžàŽ¿àŽ²àŽŸàŽšàµàŽ±àµâ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽªàµàŽ°àµàŽŸàŽàŽàµàŽàµâ àŽàŽ£àµâ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽàŽªàŽàµàŽàŽŸàŽ€àŽŸàŽµàµâ. àŽ¹àµàŽ¯àµàŽ®àŽšàµâ àŽàŽšàµàŽ±àŽ«àµ àŽàŽšàµâ.àŽàŽ¿.àŽàŽ¯àµàŽ àŽ¯àµàŽšàŽžàµâàŽàµàŽ¯àµàŽ àŽàµàŽ°àµâàŽšàµàŽšàŽŸàŽ£àµâ àŽàŽ€àŽ¿àŽšàµàŽ±àµ àŽµàŽ¿àŽ€àŽ°àŽ£àŽ àŽšàŽàŽ€àµàŽ€àµàŽšàµàŽšàŽ€àµâ<b>UNESCO</b> and the <b>Human Info NGO</b>. àŽàŽšàŽ±àŽ²àµâ àŽªàŽ¬àµàŽ²àŽ¿àŽàµâ àŽ²àµàŽžàŽšàµâàŽžàµâ àŽšàŽ¿àŽ¬àŽšàµàŽ§àŽšàŽàŽ³àµâàŽàµàŽàµâ àŽµàŽ¿àŽ§àµàŽ¯àŽ®àŽŸàŽ¯àŽ¿ <a
+href="http://greenstone.org">http://greenstone.org</a> àŽ²àµâ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽ¯ àŽàŽªàµàŽªàŽ£àµâ àŽžàµàŽŽàµâàŽžàµâ àŽžàµàŽ«àµâàŽ±àµàŽ±àµâ àŽµàµàŽ¯àŽ±àŽŸàŽ£àµâ àŽàŽ€àµâ.
+
+<p>àŽžàŽ°àµâàŽµàµàŽµàŽàŽ²àŽŸàŽ¶àŽŸàŽ²àŽàŽ³àŽ¿àŽ²àµàŽ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿àŽàŽ³àŽ¿àŽ²àµàŽ àŽªàµàŽ€àµàŽžàµàŽ¥àŽŸàŽªàŽšàŽàµàŽàŽ³àŽ¿àŽ²àµàŽ àŽàŽ³àµàŽ³ àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽàµàŽàŽ³àµ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàŽŸàŽšàµâ àŽªàµàŽ°àŽŸàŽªàµâàŽ€àŽ®àŽŸàŽàµàŽàµàŽàŽ¯àŽŸàŽ£àµâ àŽ àŽžàµàŽ«àµâàŽ±àµàŽ± àŽµàµàŽ¯àŽ±àŽ¿àŽšàµàŽ±àµ àŽàŽŠàµàŽŠàµàŽ¶àµàŽ¯àŽ. àŽ¯àµàŽšàŽžàµâàŽàµàŽ¯àµàŽàµ àŽªàŽàµàŽàŽŸàŽ³àŽ¿àŽ€àµàŽ€àŽžàµàŽ¥àŽŸàŽªàŽšàŽàµàŽàŽ³àŽ¿àŽ²àµàŽ àŽ®àŽ±àµàŽ±àµâ àŽµàŽ¿àŽŠàµàŽ¯àŽŸàŽ­àµàŽ¯àŽŸàŽžàŽ®àµàŽàŽ²àŽàŽ³àŽ¿àŽ²àµàŽ®àŽàŽàµàŽàŽ àŽµàŽ¿àŽµàŽ°àŽ¶àµàŽàŽ°àŽ£àŽ€àµàŽ€àŽ¿àŽ²àµàŽ àŽµàŽ¿àŽ€àŽ°àŽ£àŽ€àµàŽ€àŽ¿àŽ²àµàŽ àŽžàŽ®àŽàµàŽ°àŽ®àŽŸàŽ¯ àŽ®àŽŸàŽ±àµàŽ±àŽàµàŽàŽ³àµâàŽàµàŽàŽŸàŽ£àµâàµâ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿àŽàŽ³àµâ àŽàŽŸàŽ°àŽ£àŽ®àŽŸàŽ¯àŽ¿àŽàµàŽàµàŽ³àµàŽ³àŽ€àµâ.  </p>
+
+<p>
+<a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>The Human Info NGO, based in Antwerp, Belgium</b></a>
+<br>
+<p>àŽàŽàŽžàµâàŽ€àµâ 2000àŽ²àµâ àŽ®àµàŽšàµàŽšàµ àŽàµàŽ®àµàŽàŽ³àµâ àŽžàŽ¹àŽàŽ°àŽ¿àŽàµàŽàµàŽšàŽàŽ€àµàŽ€àŽ¿àŽ¯ àŽªàŽ°àŽ¿àŽ¶àµàŽ°àŽ®àŽ«àŽ²àŽ®àŽŸàŽ¯àŽŸàŽ£àµâ àŽ àŽžàµàŽ«àµâàŽ±àµàŽ± àŽµàµàŽ¯àŽ°àµâ àŽµàŽ¿àŽàŽžàŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽàŽ€àµàŽ àŽµàŽ¿àŽ€àŽ°àŽ£àŽ€àµàŽ€àŽ¿àŽšàµàŽ€àµàŽ€àŽ¿àŽ¯àŽ€àµàŽ </p>
+<p>
+<a href="http://nzdl.org"><b>New Zealand Digital Library Project at the University of Waikato</b></a>
+<br>
+àŽàŽµàŽ¿àŽàµàŽšàŽ¿àŽšàµàŽšàµàŽ àŽàµàŽ°àµàŽšàµâàŽžàµàŽ±àµàŽ±àµàŽ£àµâ àŽµàµàŽ£àµàŽàµàŽ àŽµàŽ³àŽ°àµâàŽšàµàŽšàµ. àŽ¯àµàŽ£àŽžàµâàŽàµ àŽªàŽŠàµàŽ§àŽ€àŽ¿àŽàŽ³àµâàŽàµàŽàŽŸàŽ¯àµàŽ³àµàŽ³ àŽšàµàŽ¯àµàŽžàµàŽ²àŽŸàŽšàµàŽ±àŽ¿àŽšàµàŽ±àµ àŽžàŽàŽ­àŽŸàŽµàŽš; àŽšàµàŽ¯àµàŽžàµàŽ²àŽŸàŽšàµàŽ±àµâ àŽšàŽŸàŽ·àŽ£àŽ²àµâ àŽàŽ®àµàŽ®àµàŽ·àŽšàµâ àŽ«àµàŽ°àµâ àŽ¯àµàŽ£àŽžàµâàŽàµàŽ¯àµàŽàµ àŽªàŽ°àŽ¿àŽ¶àµàŽ°àŽ®àŽ®àŽŸàŽ£àµâ àŽ àŽµàŽ¿àŽàŽ¯àŽ€àµàŽ€àŽ¿àŽšàµ àŽªàŽ¿àŽšàµàŽšàŽ¿àŽ²àµâ. 
+<p>
+<a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+class="logo"></a>
+<a href="http://www.unesco.org"><b>United Nations Educational, Scientific and Cultural Organization</b></a>
+<br>
+</p>àŽ
+àŽšàµàŽ¯àµàŽàµàŽ¯àŽ®àŽŸàŽ¯ àŽàŽ®àµàŽ®àµàŽ¯àµàŽ£àŽ¿àŽàµàŽàµàŽ·àŽšàµâ àŽàµàŽàµâàŽšàµàŽ³àŽàŽ¿àŽ¯àµ àŽªàŽŠàµàŽ§àŽ€àŽ¿ àŽàŽªàŽàŽ°àŽ£àŽ®àŽŸàŽàµàŽàŽ¿ àŽµàŽ¿àŽàµàŽàŽŸàŽšàŽ, àŽ¶àŽŸàŽžàµâàŽ€àµàŽ°àµàŽ¯àŽµàµàŽ àŽžàŽŸàŽàŽžàµâàŽàŽŸàŽ°àŽ¿àŽàŽµàµàŽ®àŽŸàŽ¯ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽ²àµàŽàŽ®àµàŽ®àµàŽªàŽŸàŽàµàŽ®àµàŽ€àµàŽ€àŽ¿àŽàµàŽàŽŸàŽšàµâ àŽµàŽ¿àŽ¶àŽ¿àŽ·àµàŽ¯àŽŸ àŽµàŽ¿àŽàŽžàµàŽµàŽ° àŽ°àŽŸàŽàµàŽ¯àŽàµàŽàŽ³àŽ¿àŽ²àµàŽ¯àµâàŽàµàŽàµàŽàµàŽàŽ¿ àŽàŽ€àµàŽ€àŽ¿àŽàµàŽàµàŽ¯àŽŸàŽ£àµâ àŽ¯àµàŽ£àŽžàµâàŽàµàŽªàŽŠàµàŽ§àŽ€àŽ¿àŽ¯àµàŽàµ àŽ²àŽàµàŽ·àµàŽ¯àŽ. 
+
+<p>
+<a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>The Human Info NGO, based in Antwerp, Belgium</b></a>
+<br>
+
+àŽ¯àµ.àŽàŽšàµâ.àŽàŽàŽšàµâàŽžàŽ¿àŽàŽ³àµàŽ àŽ®àŽ±àµàŽ±àµ àŽàŽšàµâ.àŽàŽ¿.àŽàŽàŽ³àµàŽ®àŽŸàŽ¯àŽ¿ àŽªàŽŠàµàŽ§àŽ€àŽ¿ àŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽªàµàŽ°àŽµàŽ°àµâàŽ€àµàŽ€àŽ¿àŽàµàŽàµàŽšàµàŽšàµ. àŽ®àŽšàµàŽ·àµàŽ¯àŽµàŽàŽ¶àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽµàŽ¿àŽàŽŸàŽžàŽªàŽ°àŽ¿àŽ£àŽŸàŽ® àŽàŽàµàŽàŽàµàŽàŽ³àµàŽàµàŽàµàŽ±àŽ¿àŽàµàŽàµàŽ³àµàŽ³ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àµàŽžàµâ àŽàµàŽ¯àµâàŽ€àµâ àŽžàµàŽàŽšàµàŽ¯àŽ®àŽŸàŽ¯àŽ¿ àŽµàŽ¿àŽàŽžàµàŽµàŽ° àŽ°àŽŸàŽàµàŽ¯àŽàµàŽàŽ³àµâàŽàµàŽàµàŽ, àŽàŽ¿àŽ²àŽµàµàŽ®àŽŸàŽ€àµàŽ°àŽ àŽàŽàŽŸàŽàµàŽàŽ¿ àŽ¬àŽŸàŽàµàŽàŽ¿ àŽ°àŽŸàŽàµàŽ¯àŽàµàŽàŽ³àµâàŽàµàŽàµàŽ àŽàŽ€àµàŽ€àŽ¿àŽàµàŽàµàŽàµàŽàµàŽ€àµàŽ€àµâ àŽªàŽŠàµàŽ§àŽ€àŽ¿ àŽàŽ€àŽ¿àŽšàŽàŽ àŽàŽàµàŽ³àŽªàµàŽ°àŽ¶àŽžàµâàŽ€àŽ¿ àŽšàµàŽàŽ¿àŽ¯àŽ¿àŽàµàŽàµàŽ£àµàŽàµâ. 
+</p>
+}  
+
+
+_textdescrselcol_ [l=ml] {àŽàŽ°àµ àŽàŽ²àŽàµàŽ·àŽšàµâ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽàµàŽàµàŽ}  
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=ml] {àŽ¹àµàŽ àŽªàµàŽàŽ¿àŽ²àµâ àŽšàŽŸàŽ²àµâ àŽ¬àŽàµàŽàŽ£àµàŽ£àµàŽàµâ.}  
+
+_textnocollections_ [l=ml] {<p>àŽ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽàŽšàµàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµàŽ·àŽšàŽ¿àŽ²àµ àŽàŽ°àµ àŽ¶àµàŽàŽ°àŽµàµàŽ àŽ²àŽ­àµàŽ¯àŽ®àŽ²àµàŽ² 
+àŽàŽ¿àŽ² àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµ àŽàŽ³àµàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽŸàŽšàµ àŽàŽšàµàŽšàµàŽàŽ¿àŽ²àµ<ul><li>Use <a href="_httppagecollector_">The Collector</a>àŽàŽ²àŽàµàŽàŽ°àµ àŽàŽªàŽ¯àµàŽàµàŽ¿àŽàµàŽàµàŽ 
+<li>àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿àŽ²àµ àŽžàŽ¿àŽ¡àŽ¿ àŽ±àµàŽ àŽàŽ£àµàŽàµàŽàµàŽàŽ¿àŽ²àµ àŽ
+àŽ€àŽ¿àŽ²àµ àŽšàŽ¿àµàŽšàµàŽšàµàŽ àŽàŽšàµàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµ àŽàµàŽ¯àµàŽ¯àµàŽ </ul>}  
+
+_text1coll_ [l=ml] {àŽ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽàŽšàµâàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµàŽ·àŽšàŽ¿àŽ²àµâ 1 àŽ¶àµàŽàŽ°àŽ®àµàŽ£àµàŽàµâ.}  
+
+_textmorecolls_ [l=ml] {àŽ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽàŽšàµâàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµàŽ·àŽšàŽ¿àŽ²àµâ 1 àŽ¶àµàŽàŽ°àŽ®àµàŽ£àµàŽàµâ.}  
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=ml] {àŽªàµàŽ±àŽ€àµàŽ€àµàŽàµàŽàµàŽ³àµàŽ³ àŽ²àŽ¿àŽàµàŽàµâ}  
+_textlinknotfound_ [l=ml] {àŽàŽšàµàŽ€àŽ°àµàŽ àŽ¶àµàŽàŽàŽ²àŽàŽ³àµâ àŽàŽŸàŽ£àŽªàµàŽªàµàŽàµàŽšàµàŽšàŽ¿àŽ²àµàŽ²}  
+
+_textextlinkcontent_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµâàŽàµàŽàµâ àŽµàµàŽ³àŽ¿àŽ¯àŽ¿àŽ²àµàŽ³àµàŽ³ àŽ²àŽ¿àŽàµàŽàŽŸàŽ£àµâ àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽ€àµàŽ€àŽ¿àŽàµàŽàµàŽ³àµàŽ³àŽ€àµâ. àŽ àŽ²àŽ¿àŽàµàŽàµâ àŽàŽŸàŽ£àŽ£àŽ®àµàŽàµàŽàŽ¿àŽ²àµâ <a href="_nexturl_">go forward</a>  àŽžàµàŽ±àµàŽ±àµâ àŽžàŽšàµàŽŠàŽ°àµâàŽ¶àŽ¿àŽàµàŽàµàŽ. àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿àŽ²àµâ àŽ¬àŽŸàŽàµàŽàµâ àŽ¬àŽàµàŽàŽ£àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµâ àŽªàŽŽàŽ¯àŽ€àŽ¿àŽ²àµàŽàµàŽàµâ àŽ€àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽªàµàŽµàµàŽ}  
+
+_textlinknotfoundcontent_ [l=ml] {àŽšàŽ¿àŽ¯àŽšàµàŽ€àµàŽ°àŽ£àŽŸàŽ€àµàŽ€àŽ®àŽŸàŽ¯ àŽàŽ¿àŽ² àŽàŽŸàŽ°àŽ£àŽàµàŽàŽ³àŽŸàŽ²àµâ àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽ€àµàŽ€ àŽàŽšàµàŽ€àŽ°àµàŽ àŽ¶àµàŽàŽàŽ²àŽàŽ³àµâ àŽšàŽ¿àŽ²àŽšàŽ¿àŽ²àµâàŽàµàŽàµàŽšàµàŽšàŽ¿àŽ²àµàŽ². àŽµàŽ¿àŽµàŽ°àŽžàµàŽ°àµàŽŸàŽ€àŽžàµàŽžàµàŽàŽ³àŽ¿àŽ²àµ àŽªàŽ¿àŽ¶àŽàµàŽàŽ³àŽŸàŽµàŽŸàŽšàŽŸàŽ£àµâ àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ€. àŽ¬àŽŸàŽàµàŽàµâ àŽ¬àŽàµàŽàŽ£àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµâ àŽªàŽŽàŽ¯àŽ€àŽ¿àŽ²àµàŽàµàŽàµâ àŽ€àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽªàµàŽµàµàŽ}  
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=ml] {<h3> "_2_" àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµàŽ¯àµàŽàµàŽàµ </h3> àŽ²àŽ¿àŽàµàŽàµ àŽàµàŽ¯àµàŽ¯àµàŽ 
+<p> àŽ€àŽŸàŽàµàŽ àŽžàµàŽ²àŽàµàŽ±àµàŽ±àµ àŽàµàŽ¯àµàŽ€ àŽ²àŽ¿àŽàµàŽàµ  "_collectionname_" 
+     collection (it links to the "_2_" collection). 
+    àŽàŽ€àµ àŽàŽŸàŽ£àŽ£àŽ®àµàŽàµàŽàŽ¿ e "_2_" collection àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ  
+     <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">àŽ®àµàŽšàµàŽšàµàŽàµàŽàµ àŽªàµàŽµàµàŽàµ</a>   
+     àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿  "back" àŽ¬àŽàµàŽ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽªàŽŽàŽ¯àŽ€àŽ¿àŽ²àµàŽàµàŽàµ àŽ®àŽàŽàµàŽàµàŽàµ}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=ml] {àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àµâ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿}  
+
+_textusername_ [l=ml] {àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽµàµàŽ}  
+_textpassword_ [l=ml] {àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ}  
+
+_textmustbelongtogroup_ [l=ml] {àŽ àŽªàµàŽàŽ¿àŽ²àµàŽàµàŽàµàŽ³àµàŽ³ àŽžàŽšàµàŽŠàŽ°àµàŽ¶àŽŸàŽšàµàŽ®àŽ€àŽ¿ '-cgiargug-' àŽàµàŽàµàŽàŽ€àµàŽ€àŽ¿àŽ²àµ àŽªàµàŽàµàŽàŽµàŽ°àµàŽàµàŽàµàŽ®àŽŸàŽ€àµàŽ°àŽ}  
+
+_textmessageinvalid_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµ  àŽàŽµàŽ¶àµàŽ¯àŽªàµàŽªàµàŽàµàŽ àŽªàµàŽàµàŽ²àŽ­àŽ¿àŽàµàŽàµàŽµàŽŸàŽšàµ àŽžàµàŽšàµ àŽàŽ£àµ àŽàµàŽ¯àµàŽ¯àµàŽ 
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>) 
+àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽµàµàŽ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽµàµàŽ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽªàµàŽàŽ¿àŽ²àµàŽàµàŽàµ àŽªàµàŽ°àŽµàµàŽ¶àŽ¿àŽàµàŽàµàŽ}  
+
+_textmessagefailed_ [l=ml] {àŽšàŽ¿àŽàµàŽàŽ³àµàŽàµ àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽ®àµ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ®àµ àŽàµàŽ€àµàŽ¯àŽ®àŽ²àµàŽ²}  
+
+_textmessagedisabled_ [l=ml] {àŽàµàŽ·àŽ®àŽ¿àŽàµàŽàµàŽ, àŽšàŽ¿àŽàµàŽàŽ³àµàŽàµ àŽ
+àŽàµàŽàµàŽ£àµàŽàµâ àŽªàµàŽ°àŽµàŽ°àµâàŽ€àµàŽ€àŽšàŽàµàŽ·àŽ®àŽ®àŽ²àµàŽ²àŽŸàŽ€àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽšàµàŽšàµ. àŽµàµàŽ¬àµâ àŽ®àŽŸàŽžàµàŽ±àµàŽ±àŽ±àµàŽ®àŽŸàŽ¯àŽ¿ àŽ¬àŽšàµàŽ§àŽªàµàŽªàµàŽàµàŽ}  
+
+_textmessagepermissiondenied_ [l=ml] {àŽàµàŽ·àŽ®àŽ¿àŽàµàŽàŽ£àŽ, àŽ àŽªàµàŽàµ àŽžàŽšàµàŽŠàŽ°àµàŽ¶àŽ¿àŽàµàŽàµàŽµàŽŸàŽšàµ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàµ àŽ
+àŽšàµàŽµàŽŸàŽŠàŽ®àŽ¿àŽ²àµàŽ².}  
+
+_textmessagestalekey_ [l=ml] {àŽšàŽ¿àŽàµàŽàŽ³àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽ àŽ²àŽ¿àŽàµàŽàµ àŽàŽªàŽ¯àµàŽàŽ°àŽ¹àŽ¿àŽ€àŽ®àŽŸàŽ¯àŽ¿. àŽ àŽªàµàŽàµ àŽžàŽšàµàŽŠàŽ°àµàŽ¶àŽ¿àŽàµàŽàµàŽµàŽŸàŽšàµ àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽµàµàŽ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽµàµàŽ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ.}  
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=ml] {<p>àŽ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽ²àµ àŽàŽ§àŽŸàŽ°àŽàµàŽ°àŽšàµàŽ¥àŽàµàŽàŽ³àµ àŽàŽ²àµàŽ². àŽ
+àŽ€àŽ¿àŽšàµàŽ³àµàŽ³ àŽàŽŸàŽ°àŽ£àŽàµàŽàŽ³àµ: <ol> 
+  <li>àŽªàŽ°àŽ¿àŽ®àŽ¿àŽ€àŽžàµàŽàŽ°àµàŽ¯àŽàµàŽàŽ³àµ àŽ®àŽŸàŽ€àµàŽ°àŽ®àµàŽ³àµàŽ³ àŽžàŽ¿àŽ¡àŽ¿ àŽ±àµàŽ®àŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàµàŽ àŽªàŽàŽ°àµàŽ€àµàŽ€àŽ¿àŽ¯àŽ€àµàŽàµàŽ£àµàŽàµ 
+  <li>àŽàŽšàµàŽ±àŽ°àµàŽšàµàŽ±àµàŽ±àŽ¿àŽ²àµ àŽšàŽ¿àµàŽšàµàŽšàµàŽ àŽ¡àµàŽ£àµàŽ²àµàŽ¡àµ àŽàµàŽ¯àµàŽ€àµ àŽžàµàŽ¥àŽŸàŽªàŽ¿àŽàµàŽàŽ€àµàŽàµàŽ£àµàŽàµ </ol> 
+àŽàŽàµàŽàŽ¿àŽšàµàŽ¯àŽŸàŽ¯àŽ¿àŽ°àµàŽšàµàŽšàŽŸàŽ²àµàŽ àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽžàŽ¿àŽ¡àŽ¿ àŽ±àµàŽ®àŽ¿àŽšàµàŽ±àµ .<i>docs</i>  àŽ¡àŽ¯àŽ±àŽàµàŽàŽ±àŽ¿àŽ¯àŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàµ href="http://www.greenstone.org">http://www.greenstone.org</a>  àŽžàµàŽ±àµàŽ±àŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàµ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽ£àµ.}  
+
+_textuserguide_ [l=ml] {àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽµàŽŽàŽ¿àŽàŽŸàŽàµàŽàŽ¿}  
+_textinstallerguide_ [l=ml] {àŽàŽšàµàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµàŽ·àŽšàµ àŽàµàŽ¡àµ}  
+_textdeveloperguide_ [l=ml] {àŽ¶àµàŽàŽ°àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽŸàŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàŽŸàŽ¯àµàŽ³àµàŽ³ àŽµàŽŽàŽ¿àŽàŽŸàŽàµàŽàŽ¿}  
+_textpaperguide_ [l=ml] {àŽªàµàŽªàµàŽªàŽ±àŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàµàŽ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµàŽ¯àµàŽàµàŽàµ}  
+_textorganizerguide_ [l=ml] {àŽàŽ°àµàŽàŽšàµàŽžàŽ°àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ}  
+
+_textgsdocstitle_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµ}  
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàµàŽ}  
+_textbildsuc_ [l=ml] {àŽµàŽ¿àŽàŽ¯àŽàŽ°àŽ®àŽŸàŽ¯àŽ¿ àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàµ}  
+_textviewbildsummary_ [l=ml] {"àŽ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àµàŽªàµàŽªàŽ±àµàŽ±àŽ¿àŽ¯àµàŽ³àµàŽ³ àŽàµàŽàµàŽ€àŽ²àµâ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâàŽàµàŽàŽŸàŽ¯àŽ¿ <a href="_httppagex_(bsummary)" target=_top>àŽ¬àŽ¿àŽ²àµâàŽ¡àµâ àŽžàŽ®àµàŽ®àŽ±àŽ¿ </a> àŽàŽŸàŽ£àµàŽ"}  
+_textview_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽàŽŸàŽ£àµàŽ}  
+
+_textbild1_ [l=ml] {àŽ àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽàŽ¯àŽŸàŽ£àµâ. àŽ
+àŽ€àµâ àŽ
+àŽ²àµâàŽªàŽžàŽ®àŽ¯àŽ àŽàŽàµàŽàµàŽàµàŽ. àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£ àŽªàµàŽ°àµàŽàŽ€àŽ¿ àŽ€àŽŸàŽŽàµàŽ¯àµàŽ³àµàŽ³ àŽµàŽ°àŽ¿àŽ¯àŽ¿àŽ²àµâ àŽàŽŸàŽ£àŽŸàŽ.}  
+
+_textbild2_ [l=ml] {àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£àŽ àŽšàŽ¿àŽ°àµâàŽ€àµàŽ€àŽ¿àŽµàµàŽ¯àµâàŽàµàŽàŽŸàŽšàµâ àŽàŽµàŽ¿àŽàµ àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµàŽ¯àµàŽ.  <br>àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽªàµàŽ°àŽµàŽ°àµâàŽ€àµàŽ€àŽ¿àŽàµàŽàµàŽšàµàŽš àŽ¶àµàŽàŽ°àŽ àŽ®àŽŸàŽ±àµàŽ±àŽ®àŽ¿àŽ²àµàŽ²àŽŸàŽ€àµ àŽ€àµàŽàŽ°àµàŽ. }  
+
+_textstopbuild_ [l=ml] {àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£àŽ àŽšàŽ¿àŽ°àµâàŽ€àµàŽ€àµàŽ}  
+
+_textbild3_ [l=ml] {àŽšàŽ¿àŽ°àµâàŽ€àµàŽ€àŽ¿àŽµàµàŽ¯àµâàŽàµàŽàŽŸàŽ€àµ àŽ àŽ¶àµàŽàŽ°àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽ€àŽ¿ àŽ€àµàŽàŽ°àµàŽµàŽŸàŽšàµâ àŽ
+àŽšàµàŽµàŽŠàŽ¿àŽàµàŽàŽŸàŽ²àµâ àŽªàµàŽ°àŽµàŽ°àµâàŽ€àµàŽ€àŽšàŽ àŽ€àµàŽàŽ°àµàŽàŽ¯àµàŽ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽµàŽ¿àŽàŽ¯àŽàŽ°àŽ®àŽŸàŽ¯ àŽàŽšàµâàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµàŽ·àŽšàµâ àŽªàµàŽ°àµâàŽ€àµàŽ€àŽ¿àŽ¯àŽŸàŽµàµàŽàŽ¯àµàŽ àŽàµàŽ¯àµàŽ¯àµàŽ}  
+
+_textbuildcancelled_ [l=ml] {àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£àŽ àŽšàŽ¿àŽ°àµâàŽ€àµàŽ€àŽ¿àŽµàµàŽàµàŽàµ}  
+
+_textbildcancel1_ [l=ml] {àŽ àŽ¶àµàŽàŽ°àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£àŽ àŽ±àŽŠàµàŽŠàµàŽàµàŽ¯àµâàŽ€àµ. àŽ€àŽŸàŽŽàŽ€àµàŽ€àµ àŽ®àŽàµàŽ àŽ¬àŽàµàŽàŽ£àŽ¿àŽ²àµâ àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµâàŽ€àµâ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµâ àŽ®àŽŸàŽ±àµàŽ±àŽ àŽµàŽ°àµàŽ€àµàŽ€àµàŽàŽ¯àµàŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£àŽ àŽªàµàŽšàŽ°àŽŸàŽ°àŽàŽ­àŽ¿àŽàµàŽàµàŽàŽ¯àµàŽ àŽàµàŽ¯àµàŽ¯àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµâ }  
+
+_textbsupdate1_ [l=ml] {àŽàŽ°àµ àŽžàµàŽàµàŽàŽšàµàŽ±àŽ¿àŽšàµàŽ³àµàŽ³àŽ¿àŽ²àµâ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽàŽŸàŽ£àŽŸàŽ}  
+_textbsupdate2_ [l=ml] {àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽªàµàŽ€àµàŽàµàŽàŽªàµàŽªàµàŽàµàŽàŽ€àµâàµâ}  
+_textseconds_ [l=ml] {àŽžàµàŽàµàŽàŽšàµàŽ±àµàŽàŽ³àµâ}  
+
+_textfailmsg11_ [l=ml] {àŽàŽ°àµ àŽ¡àµàŽ±àµàŽ±àŽ¯àµàŽ àŽàŽ²àµàŽ²àŽŸàŽ€àµàŽ€àŽ€àµàŽàŽŸàŽ°àŽ£àŽ àŽ àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàŽŸàŽšàµâ àŽàŽŽàŽ¿àŽàµàŽàŽ¿àŽ²àµàŽ². àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽžàµàŽàŽ¿àŽªàµàŽªàŽ¿àŽàµàŽ àŽªàµàŽ°àŽ®àŽŸàŽ£ àŽžàµàŽ°àµàŽŸàŽ€àŽžàµàŽžàŽ¿àŽ²àµ àŽàŽ€àµàŽàµàŽàŽ¿àŽ²àµàŽ àŽ¡àŽ¯àŽ±àŽàµàŽàŽ±àŽ¿àŽàŽ³àŽ¿àŽ²àµâ <i>source
+data</i> àŽàŽµàŽ¶àµàŽ¯àŽ®àŽŸàŽ¯ àŽ«àŽ¯àŽ²àµàŽàŽ³àµâ àŽàŽ£àµàŽàŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ®àµàŽšàµàŽšàµàŽ àŽ
+àŽ€àµâ àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àµâ àŽªàŽŠàµàŽ§àŽ€àŽ¿àŽàµàŽàµâ àŽ
+àŽšàµàŽ¯àµàŽàµàŽ¯àŽ®àŽŸàŽ£àµàŽšàµàŽšàµàŽ àŽàŽ±àŽªàµàŽªàŽ¿àŽàµàŽàµàŽ}  
+
+_textfailmsg21_ [l=ml] {àŽ àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàŽŸàŽšàµâ àŽàŽŽàŽ¿àŽàµàŽàŽ¿àŽ²àµàŽ² (import.pl failed).}  
+_textfailmsg31_ [l=ml] {àŽ àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàŽŸàŽšàµâ àŽàŽŽàŽ¿àŽàµàŽàŽ¿àŽ²àµàŽ²}  
+_textfailmsg41_ [l=ml] {àŽµàŽ¿àŽàŽ¯àŽàŽ°àŽ®àŽŸàŽ¯àŽ¿ àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàµ, àŽªàŽàµàŽ·àµ àŽàŽšàµâàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµàŽ·àŽšàµâ àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ®àŽŸàŽ¯àŽ¿àŽ²àµàŽ²}  
+_textfailmsg71_ [l=ml] {àŽ àŽ¶àµàŽàŽ°àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽ€àŽ¿àŽ¯àµâàŽàµàŽàŽ¿àŽàŽ¯àŽ¿àŽ²àµâ àŽàŽ°àµ àŽ
+àŽªàµàŽ°àŽ€àµàŽàµàŽ·àŽ¿àŽ€ àŽªàŽ¿àŽŽàŽµàµ àŽžàŽàŽ­àŽµàŽ¿àŽàµàŽàµ}  
+
+
+_textblcont_ [l=ml] {àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£ àŽªàŽàµàŽàŽ¿àŽ àŽ€àŽŸàŽŽàµàŽªàŽ±àŽ¯àµàŽšàµàŽš àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽàŽ³àµâàŽàµàŽàµàŽ³àµàŽ³àµàŽšàµàŽš}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=ml] {àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽšàŽàŽàŽš}  
+_textmore_ [l=ml] {àŽàµàŽàµàŽ€àŽ²àµâ}  
+_textinfo_ [l=ml] {àŽ¶àµàŽàŽ°àŽ€àµàŽ€àµàŽàµàŽàµàŽ±àŽ¿àŽàµàŽàµàŽ³àµàŽ³ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµ}  
+_textsrce_ [l=ml] {àŽµàŽ¿àŽµàŽ°àŽžàµàŽ°àµàŽŸàŽ€àŽžàµàŽžàµàŽàŽ³àµâ}  
+_textconf_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽàµàŽ°àŽ®àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ}  
+_textdel_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽšàµàŽàµàŽàŽ àŽàµàŽ¯àµàŽ¯àµàŽ}  
+_textexpt_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽàŽàµâàŽžàµâàŽªàµàŽ°àµâàŽàµàŽàµâ àŽàµàŽ¯àµàŽ¯àµàŽ}  
+
+_textdownloadingfiles_ [l=ml] {àŽ«àŽ¯àŽ²àµàŽàŽ³àµâ àŽ¡àµàŽ£àµâàŽ²àµàŽ¡àµâ àŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàµ}  
+_textimportingcollection_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽàŽàŽªàµàŽ°àµàŽàµàŽàµ àŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàµ}  
+_textbuildingcollection_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàµàŽ (àŽ€àŽŸàŽŽàµ àŽàŽŸàŽ£àµàŽ)}  
+_textcreatingcollection_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽšàµàŽšàµ}  
+
+_textcollectorblurb_ [l=ml] {<i>àŽ€àµàŽàµàŽàŽ¿àŽšàµàŽàµàŽàŽŸàŽ³àµ àŽ¶àŽàµàŽ€àŽ®àŽŸàŽ£àµ àŽªàµàŽš 
+<br>àŽµàŽ¿àŽàµàŽàŽŸàŽšàŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµàŽàµ àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽŸàŽ£àŽµàµàŽ àŽµàŽ¿àŽ€àŽ°àŽ£àŽµàµàŽ àŽàŽ€àµàŽ€àŽ°àŽµàŽŸàŽŠàŽ¿àŽ€àµàŽµàŽ¬àµàŽ§àŽªàµàŽ°àµàŽµàµàŽµàŽ àŽšàŽ¿àŽ°àµàŽµàµàŽµàŽ¹àŽ¿àŽàµàŽàµàŽ£àµàŽàŽ€àŽŸàŽàŽ¯àŽŸàŽ²àµ àŽ€àµàŽàŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽšàµ àŽ®àµàŽšàµàŽªàµ àŽšàŽšàµàŽšàŽŸàŽ¯àŽ¿ àŽàŽ²àµàŽàŽ¿àŽàµàŽàµàŽ£àµàŽàŽ€àµàŽ£àµàŽàµ 
+àŽªàŽàŽ°àµàŽªàµàŽªàŽµàŽàŽŸàŽ¶àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽšàŽ¿àŽ¯àŽ®àŽªàµàŽ°àŽ¶àµàŽšàŽàµàŽàŽ³àµ àŽàŽ£àµàŽàµ; àŽªàŽ°àŽ¿àŽ¶àµàŽ§àŽ¿àŽàµàŽàŽŸàŽšàµàŽ àŽµàŽŸàŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽàµàŽàŽŸàŽšàµàŽ®àµàŽ³àµàŽ³ àŽ
+àŽšàµàŽ®àŽ€àŽ¿ àŽ
+àŽ€àµ àŽ®àŽ±àµàŽ±àµàŽ³àµàŽ³àŽµàŽ°àµàŽàµàŽàµ àŽàµàŽ®àŽŸàŽ±àŽŸàŽšàµàŽ³àµàŽ³ àŽ
+àŽµàŽàŽŸàŽ¶àŽ®àŽŸàŽµàµàŽšàµàŽšàŽ¿àŽ²àµàŽ² 
+àŽžàŽŸàŽ®àµàŽ¹àŽ¿àŽ àŽªàµàŽ°àŽ¶àµàŽšàŽàµàŽàŽ³àµàŽ àŽàŽ£àµàŽàµ. àŽžàŽŸàŽ®àµàŽ¹àŽ¿àŽàŽžàŽŠàŽŸàŽàŽŸàŽ°àŽàµàŽàŽ³àµàŽàµàŽàµ àŽšàŽ¿àŽ°àŽàµàŽàµàŽšàµàŽšàŽ€àµàŽ àŽ
+àŽµàŽ¯àµ àŽ®àŽŸàŽšàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµàŽ®àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽ£àŽ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµ àŽªàµàŽàµàŽšàµàŽš àŽµàŽžàµàŽ€àµàŽ€àŽàŽ³àµ 
+àŽàµàŽàŽŸàŽ€àµ àŽšàµàŽ€àµàŽàŽµàŽ¿àŽ·àŽ¯àŽàµàŽàŽ³àµàŽ®àµàŽ£àµàŽàµ. àŽàŽ²àµàŽ²àŽŸàŽµàŽ°àµàŽàµàŽàµàŽ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽàµàŽàŽŸàŽšàµ àŽªàŽ±àµàŽ±àŽŸàŽ€àµàŽ€ àŽàŽ¿àŽ²àŽ€àµàŽ£àµàŽàµ.  
+<br>àŽ
+àŽ±àŽ¿àŽµàŽ¿àŽšàµàŽ±àµ àŽàŽ°àµàŽ€àµàŽ€àŽ¿àŽšàµàŽªàŽ±àµàŽ±àŽ¿àŽ¯àµàŽ³àµàŽ³ àŽ€àŽ¿àŽ°àŽ¿àŽàµàŽàŽ±àŽ¿àŽµàµàŽ àŽ¶àŽ°àŽ¿àŽ¯àŽŸàŽ¯ àŽµàŽ¿àŽ§àŽ€àµàŽ€àŽ¿àŽ²àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽšàµàŽ³àµàŽ³ àŽµàŽ¿àŽµàµàŽàŽµàµàŽ àŽ
+àŽšàŽ¿àŽµàŽŸàŽ°àµàŽ¯àŽ</i>
+}  
+
+_textcb1_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàµàŽµàŽŸàŽšàµàŽ àŽàµàŽàµàŽàŽ¿àŽàµàŽàµàŽ°àµâàŽàµàŽàµàŽµàŽŸàŽšàµàŽ àŽ®àŽŸàŽ±àµàŽ±àŽ àŽµàŽ°àµàŽ€àµàŽ€àµàŽµàŽŸàŽšàµàŽ àŽàŽ³àŽàµàŽàŽ°àµâ àŽžàŽ¹àŽŸàŽ¯àŽ¿àŽàµàŽàµàŽ. àŽ
+àŽ€àŽ¿àŽšàŽŸàŽ¯àŽ¿ àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽ²àµàŽ¡àµàŽàµàŽ¯àµàŽ¯àŽªàµàŽªàµàŽàµàŽšàµàŽš  àŽµàµàŽ¬àµâàŽªàµàŽàµàŽàŽ³àŽ¿àŽ²àµâ àŽàŽµàŽ¶àµàŽ¯àŽ®àŽŸàŽ¯ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽšàŽ²àµâàŽàµàŽ}  
+
+_textcb2_ [l=ml] {àŽàŽŠàµàŽ¯àŽ®àµ àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽ€àµàŽ°àµàŽ®àŽŸàŽšàŽ¿àŽàµàŽàµàŽ£àµàŽàµàŽ€àµàŽšàµàŽ€àµàŽšàµàŽšàŽŸàŽ²àµâ }  
+_textcnc_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ àŽ¶àµàŽàŽ°àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽ€àŽ¿}  
+_textwec_ [l=ml] {àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµâ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽàŽ³àµâàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽàŽ¯àµ àŽšàµàŽàµàŽàŽ àŽàµàŽ¯àµàŽ¯àµàŽàŽ¯àµ àŽàµàŽ¯àµàŽ¯àµàŽ}  
+
+_textcb3_ [l=ml] {àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽ¿àŽàµàŽàµàŽµàŽŸàŽšàµàŽ àŽ®àµàŽàŽ¿àŽàµàŽàµàŽàµàŽµàŽŸàŽšàµàŽ®àŽŸàŽ¯àŽ¿ àŽ€àŽŸàŽàµàŽàŽ³àµ àŽ
+àŽàŽàµàŽàµàŽ€ àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽµàµàŽ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽµàµàŽ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽàµàŽ£àµàŽàµ àŽžàµàŽ±àµàŽ±àŽ¿àŽ²àµàŽàµàŽàµ àŽàŽàŽàµàŽàµàŽ£àµàŽàŽ€àŽŸàŽ£àµ. àŽ
+àŽšàŽ§àŽ¿àŽàµàŽ€àŽ®àŽŸàŽ¯àŽ¿ àŽ®àŽ±àµàŽ±àµàŽ³àµàŽ³àŽµàŽ°àµ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽžàµàŽ±àµàŽ±àŽ¿àŽ²àµàŽàµàŽàµ àŽªàµàŽ°àŽµàµàŽ¶àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽšàµàŽ àŽžàµàŽ±àµàŽ±àŽ¿àŽ²àµ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµàŽàµàŽàµ àŽàµàŽàµàŽªàŽŸàŽàµàŽ£àµàŽàŽŸàŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽšàµàŽ àŽ€àŽàŽ¯àŽ¿àŽàµàŽµàŽŸàŽšàµ àŽµàµàŽ£àµàŽàŽ¿àŽ¯àŽŸàŽ£àµ àŽ àŽ°àµàŽ€àŽ¿ àŽàµàŽàµàŽàµàŽ³àµàŽ³àµàŽšàµàŽšàŽ€àµ. àŽžàµàŽ°àŽàµàŽ·àŽŸ àŽàŽŸàŽ°àŽ£àŽàµàŽàŽ³àŽŸàŽ²àµ àŽàŽ°àµ 30 àŽ®àŽ¿àŽšàŽ¿àŽ±àµàŽ±àµàŽàŽ³àµàŽàµ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽšàŽ°àŽ¹àŽ¿àŽ€àŽ®àŽŸàŽ¯ àŽàŽàŽµàµàŽ³àŽàŽ³àŽ¿àŽ²àµàŽ àŽ¯àŽŸàŽšàµàŽ€àµàŽ°àŽ¿àŽàŽ®àŽŸàŽ¯àŽ¿ àŽ€àŽŸàŽàµàŽàŽ³àµ àŽžàµàŽšàµ àŽàŽàµàŽàµ àŽàµàŽ¯àµàŽ¯àŽªàµàŽªàµàŽàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ. àŽàŽšàµàŽšàŽŸàŽ²àµ àŽµàµàŽ£àµàŽàµàŽ àŽžàµàŽšàµ àŽàŽ£àµ àŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàŽ€àµàŽàµàŽàµàŽàŽ¿ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽšàŽ àŽžàµàŽàŽ®àŽ®àŽŸàŽ¯àŽ¿ àŽšàŽàŽ€àµàŽ€àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ.}  
+
+_textcb4_ [l=ml] {àŽŠàŽ¯àŽµàŽŸàŽ¯àŽ¿ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽµàµàŽ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽµàµàŽ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽàµàŽ£àµàŽàµâ àŽžàµàŽ±àµàŽ±àŽ¿àŽ²àµàŽàµàŽàµâ àŽàŽàŽàµàŽàµàŽ.}  
+
+_textfsc_ [l=ml] {àŽàŽŠàµàŽ¯àŽ®àŽŸàŽ¯àŽ¿ àŽ€àŽŸàŽàµàŽàŽ³àµ àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽ¿àŽàµàŽàŽŸàŽšàµ àŽàŽàµàŽ°àŽ¹àŽ¿àŽàµàŽàµàŽšàµàŽš àŽ¶àµàŽàŽ°àŽ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽàµàŽàµàŽ}  
+
+_textwtc_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽ€àµàŽ€ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àµ àŽµàŽàµàŽàµâ àŽ€àŽŸàŽàµàŽàŽ³àµâàŽàµàŽàµâ}  
+_textamd_ [l=ml] {àŽàµàŽàµàŽ€àŽ²àµâ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽàŽ³àµâàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽ¿ àŽ¶àµàŽàŽ°àŽ àŽªàµàŽšàŽ°àµâàŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàµàŽ}  
+_textetc_ [l=ml] {àŽ°àµàŽªàŽàŽ²àµâàŽªàŽšàŽŸ àŽ«àŽ¯àŽ²àµàŽàŽ³àµâ àŽàŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽ¿ àŽ¶àµàŽàŽ°àŽ àŽªàµàŽšàŽ°àµâàŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàµàŽ}  
+_textdtc_ [l=ml] {àŽ àŽ¶àµàŽàŽ°àŽ àŽªàµàŽ°àµâàŽ£àŽ®àŽŸàŽ¯àµàŽ àŽšàµàŽàµàŽàŽ àŽàµàŽ¯àµâàŽ€àµ}  
+_textetcfcd_ [l=ml] {àŽžàµàŽµàŽ¯àŽ àŽžàµàŽ¥àŽŸàŽªàŽ¿àŽ€ àŽµàŽ¿àŽšàµâàŽ¡àµ àŽžàµàŽ¡àŽ¿àŽ¯àŽ¿àŽ²àµàŽàµàŽàµâ àŽ¶àµàŽàŽ°àŽ àŽªàŽàŽ°àµâàŽ€àµàŽ€àµàŽ}  
+_textcaec_ [l=ml] {àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµâ àŽ®àŽŸàŽ±àµàŽ±àŽ àŽµàŽ°àµàŽ€àµàŽ€àµàŽšàµàŽšàµ}  
+_textnwec_ [l=ml] {àŽ®àŽŸàŽ±àµàŽ±àŽ àŽµàŽ°àµàŽ€àµàŽ€àŽŸàŽšàµâ àŽ
+àŽšàµàŽµàŽŸàŽŠàŽ®àµàŽ³àµàŽ³ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµâ àŽ²àŽ­àµàŽ¯àŽ®àŽ²àµàŽ²}  
+_textcianc_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ àŽ¶àµàŽàŽ°àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽ€àŽ¿}  
+_texttsosn_ [l=ml] {àŽàŽ°àµ àŽªàµàŽ€àŽ¿àŽ¯ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽ¶àµàŽàŽ°àŽ àŽàŽ£àµàŽàŽŸàŽàµàŽàŽŸàŽšàµàŽ³àµàŽ³ àŽàŽàµàŽàŽàµàŽàŽ³àµâ}  
+_textsin_ [l=ml] {àŽ
+àŽ€àŽ€àŽ¿àŽšàµàŽ±àµ àŽªàµàŽ°àŽ àŽ
+àŽšàµàŽ¬àŽšàµàŽ§àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµàŽ àŽšàŽ²àµâàŽàµàŽ}  
+_textswts_ [l=ml] {àŽµàŽ¿àŽµàŽ°àŽžàµàŽ°àµàŽŸàŽ€àŽžàµàŽžàµàŽàŽ³àµâ àŽàŽµàŽ¿àŽàµàŽšàŽ¿àŽšàµàŽšàµâ àŽµàŽ°àµàŽšàµàŽšàµàŽµàµàŽšàµàŽšàµâ àŽµàµàŽ¯àŽàµàŽ€àŽ®àŽŸàŽàµàŽàµàŽ}  
+_textatco_ [l=ml] {àŽ¹àŽ¿àŽ€àŽŸàŽšàµàŽžàŽ°àŽ£àŽ àŽàŽàŽšàŽ®àŽŸàŽ±àµàŽ±àµàŽ (àŽµàŽ¿àŽàŽžàŽ¿àŽ€ àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽàµàŽàŽ³àµâàŽàµàŽàµàŽ®àŽŸàŽ€àµàŽ°àŽ)}  
+_textbtc_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàµàŽ (àŽ€àŽŸàŽŽàµ àŽàŽŸàŽ£àµàŽ)}  
+_textpvyh_ [l=ml] {àŽ
+àŽ­àŽ¿àŽ®àŽŸàŽšàŽªàµàŽ°àŽžàµàŽžàŽ°àŽ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽžàµàŽ·àµàŽàŽ¿ àŽàŽŸàŽ£àµàŽ}  
+
+_texttfsiw_ [l=ml] {àŽàŽàŽªàµàŽ¯àµàŽàµàŽàŽ°àµâ àŽžàµàŽµàŽšàµàŽ€àŽ®àŽŸàŽ¯àŽ¿ àŽàŽ²àµàŽ²àŽŸàŽ àŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàŽ€àŽŸàŽ£àµâ àŽšàŽŸàŽ²àŽŸàŽ®àŽ€àµàŽ€àµ àŽàŽàµàŽàŽ. àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£àŽªàµàŽ°àŽàµàŽ¯àŽ¯àŽ¿àŽ²àµâ àŽàŽ°àµâàŽªàµàŽªàµàŽàµàŽàŽ¿àŽ°àŽ¿àŽàµàŽàµàŽšàµàŽš àŽàŽàµàŽàŽ€àµàŽ€àŽ¿àŽ²àµâ àŽàŽàŽªàµàŽ¯àµàŽàµàŽàŽ°àµâ àŽžàµàŽµàŽ¯àŽ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£àŽ€àµàŽ€àŽ¿àŽšàŽŸàŽµàŽ¶àµàŽ¯àŽ®àŽŸàŽ¯ àŽàŽ²àµàŽ²àŽŸ àŽžàµàŽàŽ¿àŽàŽàŽ³àµàŽ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµàŽ àŽ¶àµàŽàŽ°àŽ¿àŽàµàŽàµàŽàŽ¯àŽŸàŽ£àµâ àŽ àŽàŽàµàŽàŽ€àµàŽ€àŽ¿àŽ²àµâ àŽàµàŽ¯àµàŽ¯àµàŽ. àŽàŽšàµàŽšàŽŸàŽ²àµâ àŽàŽŠàµàŽ¯àŽ®àµ àŽàŽµàŽ¶àµàŽ¯àŽ®àŽŸàŽ¯ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àŽ€àµàŽ°àŽ¯àµàŽ àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽšàŽ²àµâàŽàŽ¿àŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽ£àŽ. }  
+
+_textadab_ [l=ml] {àŽ€àŽŸàŽŽàµ àŽàŽŸàŽ£àµàŽšàµàŽš àŽ°àµàŽàŽŸàŽàŽ¿àŽ€àµàŽ°àŽ àŽ€àŽŸàŽàµàŽàŽ³àµ àŽàŽµàŽ¿àŽàµàŽ¯àŽŸàŽ£àµàŽšàµàŽšàµ àŽàŽŸàŽàµàŽàŽ¿àŽ€àµàŽ€àŽ°àµàŽ. àŽ¬àµàŽ°àµàŽžàŽ¿àŽàµ àŽ€àµàŽàŽ°àµàŽµàŽŸàŽšàµ àŽªàŽàµàŽ àŽ¬àŽàµàŽàŽ£àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ. àŽ¬àµàŽ°àµàŽžàŽ¿àŽàµ àŽ€àµàŽàŽ°àµàŽ®àµàŽªàµàŽ³àµ àŽ¬àŽàµàŽàŽ£àµ àŽ®àŽàµàŽàŽ¯àŽŸàŽ¯àŽ¿ àŽ®àŽŸàŽ±àµàŽ. àŽàŽ€àŽ¿àŽ°àµàŽµàŽ¶àŽ€àµàŽ€àµàŽ³àµàŽ³ àŽ®àŽàµàŽàŽ¬àŽàµàŽàŽ£àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽªàŽŽàŽ¯ àŽªàµàŽàŽ¿àŽ²àµàŽàµàŽàµ àŽ€àŽ¿àŽ°àŽ¿àŽàµàŽàµàµàŽªàµàŽàŽŸàŽµàµàŽšàµàŽšàŽ€àµàŽ®àŽŸàŽ£àµ.}  
+
+_textwyar_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽ€àŽ¯àµàŽ¯àŽŸàŽ±àŽŸàŽ¯àŽŸàŽ²àµâ àŽªàŽàµàŽ "collection information" (àŽàŽ²àŽàµàŽ·àŽšàµâ àŽàŽšàµâàŽ«àµàŽ°àµâàŽ®àµàŽ·àŽšàµâ) àŽ¬àŽàµàŽàŽ£àµâ àŽ
+àŽ®àŽ°àµâàŽ€àµàŽ€àµàŽ. àŽªàµàŽ€àŽ¿àŽ¯ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽ¶àµàŽàŽ°àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£àŽ àŽàŽ°àŽàŽ­àŽ¿àŽàµàŽàµàŽàŽ¯àŽŸàŽµàŽŸàŽ!}  
+
+_textcnmbs_ [l=ml] {àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽªàµàŽ°àµâ àŽµàµàŽ¯àŽàµàŽ€àŽ®àŽŸàŽàµàŽàµàŽ}  
+_texteambs_ [l=ml] {àŽàŽ®àµàŽ¯àŽ¿àŽ²àµâ àŽµàŽ¿àŽ²àŽŸàŽžàŽ àŽšàŽ²àµâàŽàŽ£àŽ}  
+_textpsea_ [l=ml] {àŽŠàŽ¯àŽµàŽŸàŽ¯àŽ¿ username@domain àŽàŽšàµàŽš àŽ°àµàŽ€àŽ¿àŽ¯àŽ¿àŽ²àµâ àŽàŽ®àµàŽ¯àŽ¿àŽ²àµâ àŽµàŽ¿àŽ²àŽŸàŽžàŽ àŽšàŽ²àµâàŽàµàŽ}  
+_textdocmbs_ [l=ml] {àŽ¶àµàŽàŽ°àŽ€àµàŽ€àµàŽªàŽ±àµàŽ±àŽ¿àŽ¯àµàŽ³àµàŽ³ àŽµàŽ¿àŽµàŽ°àŽ£àŽ àŽšàŽ²àµâàŽàµàŽ}  
+
+_textwcanc_ [l=ml] {àŽàŽ°àµ àŽªàµàŽ€àŽ¿àŽ¯ àŽ¶àµàŽàŽ°àŽ àŽàŽ£àµàŽàŽŸàŽàµàŽàµàŽ®àµàŽªàµàŽ³àµâ àŽµàŽ¿àŽµàŽ°àŽžàµàŽ°àµàŽŸàŽ€àŽžàµàŽžàµàŽàŽ³àµàŽªàµàŽªàŽ±àµàŽ±àŽ¿ àŽ
+àŽ€àµàŽ¯àŽŸàŽµàŽ¶àµàŽ¯àŽ àŽµàŽ°àµàŽšàµàŽš àŽµàŽžàµâàŽ€àµàŽ€àŽàŽ³àµâ àŽ°àµàŽàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ£àµàŽàŽ€àµàŽ£àµàŽàµâ. àŽàŽ²àŽàµàŽàŽ°àµâ àŽšàµàŽ°àµàŽàµàŽ·àŽ£àŽµàŽ¿àŽ§àµàŽ¯àŽ®àŽŸàŽàµàŽàµàŽšàµàŽš àŽµàµàŽ¬àµâàŽªàµàŽàµàŽàŽ³àµàŽàµ àŽàŽ°àµ àŽ¶àµàŽ°àµàŽ£àŽ¿àŽ¯àŽŸàŽ¯àŽ¿ àŽàŽ€àŽ¿àŽšàµ àŽàµàŽ°àŽ®àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽšàµàŽšàµ. àŽªàµàŽàŽ¿àŽšàµàŽ±àµ àŽàŽàµàŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽ¬àŽŸàŽ°àµâ àŽ¶àµàŽàŽàŽ²àŽ¯àµàŽàµ àŽ
+àŽµàŽžàŽŸàŽšàŽ¿àŽàµàŽàŽ€àŽŸàŽ¯àŽ¿ àŽžàµàŽàŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽšàµàŽšàµ. }  
+
+_texttfc_ [l=ml] {àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽ¶àµàŽ°àµâàŽ·àŽàŽ}  
+
+_texttctiasp_ [l=ml] {àŽàŽ³àµàŽ³àŽàŽàµàŽàŽ€àµàŽ€àµàŽªàµàŽªàŽ±àµàŽ±àŽ¿àŽ¯àµàŽ³àµàŽ³ àŽàŽ°àµ àŽ°àµàŽªàŽ°àµàŽ àŽšàŽ²àµâàŽàµàŽšàµàŽš àŽàŽ°àµ àŽàµàŽ±àŽ¿àŽ¯ àŽµàŽŸàŽàµàŽ¯àŽ®àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽ£àŽ àŽ¶àµàŽàŽ°àŽ¶àµàŽ°àµâàŽ·àŽ. àŽàŽŠàŽŸàŽ¹àŽ°àŽ£àŽ®àŽŸàŽ¯àŽ¿ 'àŽàŽàŽªàµàŽ¯àµàŽàµàŽàŽ°àµâ àŽžàŽ¯àŽšàµâàŽžàµâ àŽàµàŽàµâàŽšàŽ¿àŽàµàŽàŽ²àµâ àŽ±àŽ¿àŽªàµàŽªàµàŽ°àµâàŽàµàŽàµàŽàŽ³àµâ', àŽ¹àµàŽ¯àµàŽ®àŽŸàŽšàŽ¿àŽ±àµàŽ±àŽ¿ àŽ¡àŽµàŽ²àŽªàµàŽªàµâàŽ®àµàŽšàµàŽ±àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿' àŽàŽšàµàŽšàŽ¿àŽµ}  
+
+_textcea_ [l=ml] {àŽ¬àŽšàµàŽ§àŽªàµàŽªàµàŽàµàŽ£àµàŽ àŽàŽ®àµàŽ¯àŽ¿àŽ²àµâ}  
+
+_textteas_ [l=ml] {àŽ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽàŽŸàŽ°àµàŽ¯àŽ€àµàŽ€àŽ¿àŽ²àµâ àŽàŽŠàµàŽ¯àŽ®àŽŸàŽ¯àŽ¿ àŽ¬àŽšàµàŽ§àŽªàµàŽªàµàŽàµàŽµàŽŸàŽšàµàŽ³àµàŽ³ àŽ®àŽŸàŽ°àµâàŽàŽ àŽàŽ®àµàŽ¯àŽ¿àŽ²àµâ àŽµàŽ¿àŽ²àŽŸàŽžàŽ®àŽŸàŽ£àµâ. àŽàŽšàµàŽ€àµàŽàµàŽàŽ¿àŽ²àµàŽ àŽªàµàŽ°àŽ¶àµâàŽšàµâàŽàµàŽàŽ³àµâ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµâ àŽžàµàŽ«àµâàŽ±àµàŽ±àµâ àŽµàµàŽ¯àŽ±àŽ¿àŽšàµàŽ±àµ àŽ¶àµàŽ°àŽŠàµàŽ§àŽ¯àŽ¿àŽ²àµâ àŽªàµàŽàµàŽšàµàŽš àŽªàŽàµàŽ·àŽ àŽàŽ°àµ àŽµàŽ¿àŽ¶àŽàŽ²àŽš àŽ±àŽ¿àŽªàµàŽªàµàŽ°àµâàŽàµàŽàµâ àŽ àŽàŽ®àµàŽ¯àŽ¿àŽ²àŽ¿àŽ²àµàŽàµàŽàµâ àŽ
+àŽ¯àŽàµàŽàŽªàµàŽªàµàŽàµàŽšàµàŽšàŽ€àŽŸàŽ£àµâ. àŽªàµàŽ°àµâàŽ£àŽ®àŽŸàŽ¯ àŽàŽ°àµ àŽàŽ®àµàŽ¯àŽ¿àŽ²àµâ àŽµàŽ¿àŽ²àŽŸàŽžàŽ àŽšàŽ²àµâàŽàµàŽ.<tt>name@domain</tt>.}  
+
+_textatc_ [l=ml] {àŽ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àµàŽàµàŽàµàŽ±àŽ¿àŽàµàŽàµâ}  
+
+_texttiasd_ [l=ml] {àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµâ àŽàŽ³àµâàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽ¿àŽ¯ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâàŽàµàŽàµâ àŽàŽ§àŽŸàŽ°àŽ®àŽŸàŽ¯ àŽµàŽžàµâàµâàŽ€àµàŽ€àŽàŽ³àµàŽ àŽ€àŽ€àµàŽµàŽàµàŽàŽ³àµàŽ àŽµàŽ¿àŽ¶àŽŠàŽ®àŽŸàŽàµàŽàµàŽšàµàŽš àŽµàŽ¿àŽµàŽ°àŽ£àŽ®àŽŸàŽ£àµâ àŽàŽ€àµâ. àŽàµâàŽ€àµâ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽàŽŠàµàŽ¯àŽªàµàŽàŽ¿àŽ²àµâàŽ€àŽšàµàŽšàµ àŽšàŽ²àµâàŽàŽªàµàŽªàµàŽàµàŽšàµàŽšàµ. }  
+
+_textypits_ [l=ml] {àŽ "collection information"àŽàŽ²àŽàµàŽ·àŽšàµ àŽàŽšàµàŽ«àµàŽ°àµàŽ®àµàŽ·àŽšàµ àŽàŽàµàŽàŽ€àµàŽ€àŽ¿àŽ²àµ àŽ€àŽŸàŽŽàµ àŽšàŽ²àµàŽàŽ¿àŽ¯àŽ¿àŽàµàŽàµàŽ³àµàŽ³ àŽªàŽàµàŽ "source data" àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽžàµàŽ¥àŽŸàŽšàŽ àŽšàŽ¿àŽ¶àµàŽàŽ¯àŽ¿àŽàµàŽàµàŽ. àŽ®àµàŽšàµàŽšàµàŽàµàŽàµàŽªàµàŽàµàŽµàŽŸàŽšàµ àŽªàŽàµàŽ àŽ¬àŽàµàŽàŽ£àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ.}  
+
+_srcebadsources_ [l=ml] {<p>àŽšàŽ¿àŽàµàŽàŽ³àµ àŽàµàŽ£àµàŽàŽ¿àŽàµàŽàŽŸàŽ£àŽ¿àŽàµàŽ àŽàŽ°àµ àŽžàµàŽ°àµàŽŸàŽ€àŽžàµ (àŽ€àŽŸàŽŽàµ àŽµàµàŽ¯àŽàµàŽ€àŽ®àŽŸàŽàµàŽàŽ¿àŽ¯ _iconcross_ ) 
+ 
+<p>àŽàŽ€àŽ¿àŽšàµàŽàŽŸàŽ°àŽ£àŽ 
+ 
+<li> àŽ àŽ«àŽ¯àŽ²àµ àŽžàµàŽ±àµàŽ±àµ àŽšàŽ¿àŽ²àŽšàŽ¿àŽ²àµàŽàµàŽàµàŽšàµàŽšàµàŽ£àµàŽàŽŸàŽµàŽ¿àŽ²àµàŽ² 
+ 
+<li> àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàµ àŽàŽšàµàŽ±àŽ°àµàŽšàµàŽ±àµàŽ±àµ àŽžàµàŽµàŽšàŽ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽàµàŽàŽ¿àŽ¯ àŽàŽ³àµàŽ®àŽŸàŽ¯àŽ¿ àŽ¬àŽšàµàŽ§àŽªàµàŽªàµàŽàµàŽ 
+<li> àŽ€àŽŸàŽàµàŽàŽ³àµ àŽžàµàŽ±àµàŽ±àŽ¿àŽ²àµàŽàµàŽàµ àŽªàµàŽ°àŽµàµàŽ¶àŽ¿àŽàµàŽàŽŸàŽšàµ àŽ¶àµàŽ°àŽ®àŽ¿àŽàµàŽàŽ€àµ àŽàŽ°àµ àŽ«àŽ¯àŽ°àµàŽµàŽŸàŽ³àŽ¿àŽšàµàŽ±àµ àŽ®àŽ±àŽµàŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàµàŽ®àŽŸàŽ£àµ. àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽµàµàŽ àŽ
+àŽàŽ¯àŽŸàŽ³àŽµàŽŸàŽàµàŽàµàŽ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽ¯àŽŸàŽ²àµàŽ àŽàŽ€àµàŽ€àŽšàµàŽšàµàŽ¯àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ àŽ«àŽ²àŽ. </ul> 
+ 
+<p> àŽàŽ€àµ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽ¬àµàŽ°àµàŽžàŽ±àŽ¿àŽ²àµ àŽàŽ°àµ àŽµàµàŽ¬àµàŽžàµàŽ±àµàŽ±àµ àŽµàŽ¿àŽ²àŽŸàŽžàŽ®àŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµ àµàŽ
+àŽ€àµ àŽ
+àŽµàŽ¿àŽàµ àŽªàŽ€àŽ¿àŽàµàŽàµàŽµàµàŽàµàŽàŽªàµàŽªàµàŽàµàŽàŽ€àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽŸàŽ. àŽŠàµàŽ°àµàŽ­àŽŸàŽàµàŽ¯àŽµàŽ¶àŽŸàŽ²àµ àŽšàŽ®àµàŽ®àµàŽàµ àŽàŽ£àµàŽ£àŽŸàŽàŽ¿àŽ¯àŽ¿àŽ²àµ àŽ àŽªàŽ€àŽ¿àŽªàµàŽªàµàŽàŽ³àµàŽàµ àŽªàµàŽ°àŽ€àŽ¿àŽ«àŽ²àŽšàŽ àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ®àŽ²àµàŽ². àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽ¬àµàŽ°àµàŽžàŽ°àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽ àŽªàµàŽàµ àŽ¡àµàŽ£àµàŽ²àµàŽ¡àµ àŽàµàŽ¯àµàŽ¯àµàŽµàŽŸàŽšàµ àŽ¶àµàŽªàŽŸàŽ°àµàŽ¶àŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàµ. 
+àŽµàŽžàµàŽ€àµàŽ€àŽàŽ³àµ àŽàµàŽ°àµàŽàµàŽàµàŽšàµàŽšàµ}  
+
+_textymbyco_ [l=ml] {<p>àŽšàŽ¿àŽàµàŽàŽ³àµ àŽ àŽ¶àµàŽàŽ°àŽ àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽšàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ£àµàŽàŽ€àµ  
+<ul> 
+<li>àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽš àŽàŽàŽšàŽ¯àŽ¿àŽ²àµ 
+<dl><dd>àŽªàµàŽ€àŽ¿àŽ¯ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµ html àŽ°àµàŽàŽàŽ³àµàŽ àŽªàµàŽ²àµàŽ¯àŽ¿àŽšàµ (.htm, .html)àŽàµàŽàµàŽžàµàŽ±àµàŽ±àµ àŽ°àµàŽàŽàŽ³àµàŽ (.txt, .text),àŽµàµàŽ°àµàŽ¡àµ àŽ¡àµàŽàµàŽ¯àµàŽ®àµàŽšàµàŽ±àµàŽàŽ³àµàŽ àŽªàµàŽ¡àŽ¿àŽ¯àµàŽ«àµ àŽ¡àµàŽàµàŽ¯àµàŽ®àµàŽšàµàŽ±àµàŽàŽ³àµàŽ (.pdf),  "m-box" àŽ°àµàŽªàŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àŽ³ àŽàŽ®àµàŽ¯àŽ¿àŽ²àµ àŽ¡àµàŽàµàŽ¯àµàŽ®àµàŽšàµàŽ±àµàŽàŽ³àµàŽ (.mbx).</dd></dl> 
+<li>  àŽàŽ²àµàŽ²àŽŸàŽ àŽžàµàŽàµàŽ·àŽ¿àŽàµàŽàµàŽ àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ®àŽŸàŽ£àµ. <li> 
+<li>àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽàŽ°àµ àŽ¶àµàŽàŽ°àŽ 
+<dl><dd>àŽªàµàŽ€àŽ¿àŽ¯ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµ àŽ«àŽ¯àŽ²àµàŽàŽ³àµ àŽ®àµàŽšàµàµàŽªàµ àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽ àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµ àŽ«àŽ¯àŽ²àµàŽàŽ³àµàŽàµàŽàµ àŽžàŽ®àŽŸàŽšàŽ®àŽŸàŽ¯ àŽ€àŽ°àŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³àŽ€àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽ£àŽ.</dd></dl> 
+</ul>}  
+
+_textbtco_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽàŽšàµàŽšàŽ€àŽ¿àŽšàµ àŽ
+àŽàŽ¿àŽžàµàŽ¥àŽŸàŽšàŽ®àŽŸàŽàµàŽàµàŽšàµàŽšàµ}  
+_textand_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽàŽ³àµâàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ}  
+_textad_ [l=ml] {àŽµàŽžàµâàŽ€àµàŽ€àŽàŽ³àµâ àŽàµàŽ°àµâàŽàµàŽàµàŽšàµàŽš}  
+
+_texttftysb_ [l=ml] {àŽ€àŽŸàŽŽàµ àŽšàŽ²àµâàŽàŽ¿àŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽšàµàŽš àŽ«àŽ¯àŽ²àµàŽàŽ³àµâ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµàŽàµàŽàµâ àŽàµàŽ°àµâàŽàµàŽàŽªàµàŽªàµàŽàµàŽ. àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµâ àŽàŽªàµàŽªàµàŽ³àµâàŽ€àŽšàµàŽšàµàŽ¯àµàŽ³àµàŽ³ àŽ«àŽ¯àŽ²àµàŽàŽ³àµâ àŽµàµàŽ£àµàŽàµàŽ àŽàŽ³àµâàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽŸàŽ€àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽšàµ àŽ¶àµàŽ°àŽŠàµàŽ§àŽ¿àŽ¯àµâàŽàµàŽàµàŽ£àµàŽàŽ€àµàŽ£àµàŽàµâ. àŽ
+àŽàµàŽàŽ¿àŽšàµàŽµàŽšàµàŽšàŽŸàŽ²àµâ àŽàŽ°àµàŽ«àŽ¯àŽ²àŽ¿àŽšàµàŽ±àµ àŽ°àŽ£àµàŽàµàŽàµàŽªàµàŽªàŽ¿àŽàŽ³àµâ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽšàµàŽšàŽ€àŽŸàŽ£àµâ. àŽ«àŽ¯àŽ²àµàŽàŽ³àµâ àŽ
+àŽµàŽ¯àµàŽàµ àŽªàŽŸàŽ€àµàŽ€àµâ àŽšàµàŽ¯àŽ¿àŽ àŽ
+àŽšàµàŽžàŽ°àŽ¿àŽàµàŽàµàŽ àŽµàµàŽ¬àµâàŽªàµàŽàµàŽàŽ³àµâ àŽàŽšàµàŽ±àµàŽ°àµâàŽšàµàŽ±àµàŽ±àµâ àŽµàŽ¿àŽ²àŽŸàŽžàŽ àŽ
+àŽšàµàŽžàŽ°àŽ¿àŽàµàŽàµàŽ®àŽŸàŽ£àµâ àŽ€àŽ¿àŽ°àŽàµàŽàŽ±àŽ¿àŽ¯àŽªàµàŽªàµàŽàµàŽ.}  
+
+_textis_ [l=ml] {àŽµàŽ¿àŽµàŽ°àŽžàµàŽ°àµàŽŸàŽ€àŽžàµàŽžàµàŽàŽ³àµ}  
+
+_textddd1_ [l=ml] {<p>àŽ€àŽŸàŽàµàŽàŽ³àµ  file:// àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿àŽ²àµ  ftp://:// ftp:// àŽàŽšàµàŽš àŽ«àŽ¯àŽ²àµ àŽàŽšàµàŽšàµàŽàµàŽ€àµàŽ€àµàŽªàŽ±àŽàµàŽàŽŸàŽ²àµ àŽ àŽ«àŽ¯àŽ²àµ àŽ¡àµàŽ£àµàŽ²àµàŽ¡àµ àŽàµàŽ¯àµàŽ¯àŽªàµàŽªàµàŽàµàŽ 
+<p>àŽ€àŽŸàŽàµàŽ http://àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽ²àµ àŽµàµàŽ¬àµàŽªàµàŽàµ àŽàŽŸàŽ£àŽ¿àŽàµàŽàµàŽàŽ¯àµ àŽ«àŽ¯àŽ²àµàŽàŽ³àµàŽàµ àŽàŽ°àµ àŽ²àŽ¿àŽžàµàŽ±àµàŽ±àµ àŽàŽŸàŽ£àŽ¿àŽàµàŽàµàŽàŽ¯àµ àŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàŽ€àŽ¿àŽšàµ àŽàŽ¶àµàŽ°àŽ¯àŽ¿àŽàµàŽàŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ àŽ«àŽ²àŽ àŽ¬àµàŽ°àµàŽžàŽ±àŽ¿àŽ²àµ. àŽàŽ°àµ àŽªàµàŽàµ àŽ®àŽŸàŽ€àµàŽ°àŽ®àŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµ àŽ àŽªàµàŽàµàŽ àŽàŽšàŽ¿ àŽàŽ°àµ àŽ²àŽ¿àŽžàµàŽ±àµàŽ±àµ àŽàŽ£àµàŽàµàŽàŽ¿àŽ²àµ, àŽ
+àŽ€àµ àŽžàµàŽ±àµàŽ±àŽ¿àŽ²àµ àŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµàŽ€ àŽàŽ²àµàŽ²àŽŸ àŽ«àŽ¯àŽ²àµàŽàŽ³àµàŽ àŽ¡àµàŽ£àµàŽ²àµàŽ¡àµ àŽàµàŽ¯àµàŽ¯àŽªàµàŽªàµàŽàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ. 
+<p>àŽàŽ°àµ àŽ«àµàŽ³àµàŽ¡àŽ±àŽ¿àŽšàµàŽ±àµ àŽªàµàŽ°àµàŽàµàŽ€àµàŽ€àµàŽªàŽ±àŽàµàŽàµ àŽ€àŽŸàŽàµàŽàŽ³àµ  file:// àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿àŽ²àµ  ftp:// àŽžàŽàŽµàŽ¿àŽ§àŽŸàŽšàŽ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽàŽ¯àŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµ àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿àŽ²àµ http:// url àŽžàŽàŽµàŽ¿àŽ§àŽŸàŽšàŽ€àµàŽ€àµ àŽàŽ¶àµàŽ°àŽ¯àŽ¿àŽàµàŽàŽŸàŽ²àµ àŽ«àµàŽ³àµàŽ¡àŽ±àŽ¿àŽ²àµàŽ àŽžàŽ¬àµàŽ«àµàŽ³àµàŽ¡àŽ±àŽ¿àŽ²àµàŽ àŽ²àŽ¿àŽžàµàŽ±àµàŽ±àµàŽàµàŽ¯àµàŽ€ àŽ®àµàŽŽàµàŽµàŽšàµ àŽ«àŽ¯àŽ²àµàŽàŽ³àµàŽ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽ£àµ.  
+<p>"more sources" (àŽàµàŽàµàŽ€àŽ²àµ àŽžàµàŽ°àµàŽŸàŽ€àŽžàµàŽžàµàŽàŽ³àµ) àŽàŽšàµàŽš àŽ¬àŽàµàŽàŽ£àŽ¿àŽ²àµ àŽ
+àŽ®àŽ°àµàŽ€àµàŽ€àŽ¿àŽ¯àŽŸàŽ²àµ àŽàµàŽàµàŽ€àŽ²àµ àŽµàŽ¿àŽµàŽ°àŽšàŽ¿àŽàµàŽ·àµàŽª àŽªàµàŽàŽàŽàµàŽàŽ³àµ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ
+}  
+
+_textddd2_ [l=ml] {<p>àŽàŽ€àµàŽàµàŽàŽ¿àŽ²àµàŽ àŽàŽ°àµ àŽªàŽàµàŽ àŽ¬àŽàµàŽàŽ£àŽ¿àŽ²àµ àŽ
+àŽ®àŽ°àµàŽ€àµàŽ€àµàŽ. 
+àŽàŽ°àµ àŽµàŽ¿àŽàŽžàŽ¿àŽ€àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽµàŽŸàŽ£àµ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàŽ¿àŽ²àµ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽàµàŽ£àµàŽ«àŽ¿àŽàŽ±àµàŽ·àŽšàµ àŽàµàŽ°àŽ®àµàŽàŽ°àŽ¿àŽàµàŽàŽŸàŽšàŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ àŽ¶àµàŽ°àŽ®àŽ¿àŽàµàŽàµàŽ.  
+àŽ®àŽ±àµàŽ±àµàŽ°àµ àŽµàŽ¿àŽ§àŽ€àµàŽ€àŽ¿àŽ²àµ, àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽŸàŽ£àŽàŽàµàŽàŽ€àµàŽ€àŽ¿àŽ²àµàŽàµàŽàµ àŽ€àŽšàµàŽšàµ àŽªàµàŽµàµàŽàŽ¯àµàŽ®àŽŸàŽµàŽŸàŽ. àŽ®àŽàµàŽàŽ¬àŽàµàŽàŽ£àŽ¿àŽ²àµàŽàµ àŽªàµàŽ°àµàŽµàµàŽµàŽžàµàŽ¥àŽ¿àŽ€àŽ¿ àŽªàµàŽ°àŽŸàŽªàŽ¿àŽàµàŽàµàŽàŽ¯àµàŽ®àŽŸàŽµàŽŸàŽ.}  
+
+_textconf1_ [l=ml] {<p>àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£àŽµàµàŽ àŽªàµàŽ°àŽŠàŽ°àµâàŽ¶àŽšàŽµàµàŽ àŽšàŽ¿àŽ¯àŽšàµàŽ€àµàŽ°àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµâ àŽªàµàŽ°àŽ€àµàŽ¯àµàŽ "configuration file" àŽ«àŽ¯àŽ²àµàŽàŽ³àŽŸàŽ£àµâ. àŽµàŽ¿àŽàŽžàŽ¿àŽ€ àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽàµàŽàŽ³àµâ àŽàŽ¿àŽ²àŽªàµàŽªàµàŽ³àµâ àŽ àŽžàµàŽ±àµàŽ±àŽ¿àŽàŽàµâàŽžàµâ àŽ€àŽšàµàŽšàµ àŽ®àŽŸàŽ±àµàŽ±àŽŸàŽšàµâ àŽšàµàŽàµàŽàŽ¿àŽ¯àµàŽàµàŽàŽŸàŽ.
+<center><p><b>àŽ
+àŽàµàŽàŽ¿àŽšàµàŽ¯àµàŽ³àµàŽ³ àŽµàŽ¿àŽàŽžàŽ¿àŽ€ àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽµàŽ²àµàŽ² àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàŽ¿àŽ²àµâ àŽªàµàŽàŽ¿àŽšàµàŽ±àµ àŽ
+àŽàŽ¿àŽ­àŽŸàŽàŽ€àµàŽ€àµàŽàµàŽàµâ àŽšàµàŽàµàŽàµàŽ</b></center>
+<p>àŽàµàŽ£àµâàŽ«àŽ¿àŽàŽ±àµàŽ·àŽšàµâ àŽ®àŽŸàŽ±àµàŽ±àµàŽšàµàŽšàŽ€àŽ¿àŽšàŽŸàŽ¯àŽ¿ àŽ€àŽŸàŽŽàµ àŽªàµàŽ°àŽ€àµàŽ¯àŽàµàŽ·àŽªàµàŽªàµàŽàµàŽšàµàŽš àŽ¡àŽŸàŽ±àµàŽ± àŽàŽ¡àŽ¿àŽ±àµàŽ±àµàŽàµàŽ¯àµàŽ¯àµàŽ. àŽ€àµàŽ±àµàŽ±àµàŽªàŽ±àµàŽ±àµàŽàŽ¯àŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµâ "Reset" àŽ¬àŽàµàŽàŽ£àµâ àŽ
+àŽ®àŽ°àµâàŽ€àµàŽ€àŽ¿ àŽªàŽŽàŽ¯ àŽàµàŽ£àµâàŽ«àŽ¿àŽàŽ±àµàŽ·àŽšàµâ àŽªàµàŽšàŽžàµàŽ¥àŽŸàŽªàŽ¿àŽàµàŽàµàŽ}  
+
+_textreset_ [l=ml] {àŽªàµàŽš:àŽàµàŽ°àŽ®àµàŽàŽ°àŽ¿àŽàµàŽàµàŽ}  
+
+
+_texttryagain_ [l=ml] {<a href="_httppagecollector_" target=_top>àŽàŽ²àŽàµàŽàŽ°àµâ àŽªàµàŽšàŽ°àŽŸàŽ°àŽàŽ­àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµâ </a>àŽµàµàŽ£àµàŽàµàŽ àŽ¶àµàŽ°àŽ®àŽ¿àŽàµàŽàŽ}  
+
+
+_textretcoll_ [l=ml] {àŽàŽ³àŽàµàŽàŽ±àŽ¿àŽ²àµàŽàµàŽàµ àŽ®àŽàŽàµàŽàŽ¿àŽµàŽ°àŽ¿àŽ}  
+
+_textdelperm_ [l=ml] {_cgiargbc1dirname_ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽàŽ¿àŽ²àŽ€àµ àŽàŽ²àµàŽ²àŽŸàŽ®àµ àŽšàµàŽàµàŽàŽ àŽàµàŽ¯àµàŽ¯àŽŸàŽšàµ àŽàŽŽàŽ¿àŽ¯àµàŽšàµàŽšàŽ¿àŽ²àµàŽ². àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ®àŽŸàŽ¯ àŽàŽŸàŽ°àŽ£àŽàµàŽàŽ³àµ <ul> 
+<li> _gsdlhome_/collect/_cgiargbc1dirname_àŽ¡àŽ¯àŽ±àŽàµàŽàŽ±àŽ¿ àŽšàµàŽàµàŽàŽ àŽàµàŽ¯àµàŽ¯àŽŸàŽšàµ àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµ àŽ
+àŽšàµàŽ®àŽ€àŽ¿àŽ¯àŽ¿àŽ²àµàŽ²<br> 
+àŽ¡àŽ¯àŽ±àŽàµàŽàŽ±àŽ¿ àŽàŽšàµàŽšàµàŽšàµàŽšàŽŸàŽ¯àŽ¿ àŽšàµàŽàµàŽàŽàŽàµàŽ¯àµàŽ€àŽŸàŽ²àµ àŽ®àŽŸàŽ€àµàŽ°àŽ®àµ àŽžàŽ®àµàŽªàµàŽ°àµàŽ£àŽ®àŽŸàŽ¯ _cgiargbc1dirname_àŽšàµàŽàµàŽàŽàŽàµàŽ¯àµàŽ¯àŽ²àµ àŽµàŽ¿àŽàŽ¯àŽ¿àŽàµàŽàµàŽàŽ¯àµàŽ³àµàŽ³àµ 
+àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµ _gsdlhome_/bin/script/delcol.pl.àŽªàµàŽ°àµàŽŸàŽàµàŽ°àŽŸàŽ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽŸàŽšàµ àŽàŽŽàŽ¿àŽ¯àµàŽàŽ¯àŽ¿àŽ²àµàŽ². àŽ àŽ«àŽ¯àŽ²àµ àŽµàŽŸàŽ¯àŽ¿àŽàµàŽàŽŸàŽµàµàŽšàµàŽšàŽ€àµàŽ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽšàŽ¯àµàŽàµàŽ¯àŽ®àŽŸàŽàµàŽàŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ àŽàŽšàµàŽšàµàŽ àŽªàŽ°àŽ¿àŽ¶àµàŽ§àŽ¿àŽàµàŽàµàŽ</li> 
+</ul>}  
+
+_textdelinv_ [l=ml] {_cgiargbc1dirname_àŽ¶àµàŽàŽ°àŽ àŽžàŽàŽ°àŽàµàŽ·àŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽàŽ€àµ àŽŠàµàŽ°àµàŽ¬àŽ²àŽ®àŽŸàŽàµàŽàŽªàµàŽªàµàŽàµàŽàŽ€àµ àŽàŽ£àµ. àŽšàµàŽàµàŽàŽàŽàµàŽ¯àµàŽ¯àŽ²àµ àŽ±àŽŠàµàŽŠàµàŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàµ}  
+
+_textdelsuc_ [l=ml] {_cgiargbc1dirname_àŽ¶àµàŽàŽ°àŽ àŽµàŽ¿àŽàŽ¯àŽàŽ°àŽ®àŽŸàŽ¯àŽ¿ àŽšàµàŽàµàŽàŽ àŽàµàŽ¯àµâàŽ€àµ}  
+
+_textclonefail_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ _cgiargclonecol_ àŽ¶àµàŽàŽ°àŽ àŽàµàŽ²àµàŽ£àµ àŽàµàŽ¯àµàŽ¯àŽŸàŽšàµ àŽàŽŽàŽ¿àŽàµàŽàŽ¿àŽ²àµàŽ².  
+àŽ
+àŽ€àŽ¿àŽšàµàŽ³àµàŽ³ àŽàŽŸàŽ°àŽ£àŽàµàŽàŽ³àµ  <ul> 
+<li> _cgiargclonecol_àŽ¶àµàŽàŽ°àŽ àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àŽ¿àŽ²àµàŽ² 
+<li>_cgiargclonecol_ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµ collect.cfg àŽàŽ²àŽàµàŽ·àµàŽšàµ àŽàµàŽ£àµàŽ«àŽ¿àŽàŽ±àµàŽ·àŽšàµ àŽ«àŽ¯àŽ²àµ àŽàŽ£àµàŽàŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽ¿àŽ²àµàŽ² 
+<li> àŽªàµàŽ°àŽžàµàŽ€àµàŽ€ collect.cfg àŽ«àŽ¯àŽ²àµ àŽµàŽŸàŽ¯àŽ¿àŽàµàŽàŽŸ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµ àŽ
+àŽšàµàŽ®àŽ€àŽ¿àŽ¯àµàŽ£àµàŽàŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽ¿àŽ²àµàŽ²</ul>}  
+
+_textcolerr_ [l=ml] {àŽ¶àµàŽàŽ°àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£ àŽªàŽ¿àŽ¶àŽàµàŽàŽ³àµâ}  
+
+_texttmpfail_ [l=ml] {àŽ€àŽŸàŽ²àµâàŽàµàŽàŽŸàŽ²àŽ¿àŽ àŽ«àŽ¯àŽ²àµ àŽ¡àŽ¯àŽ±àŽàµàŽàŽ±àŽ¿àŽ¯àµ àŽµàŽŸàŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽ²àµàŽ àŽàŽŽàµàŽ€àµàŽšàµàŽšàŽ€àŽ¿àŽ²àµàŽ àŽàŽ²àŽàµàŽàŽ°àµâ àŽªàŽ°àŽŸàŽàŽ¯àŽªàµàŽªàµàŽàµàŽàµ. àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ®àŽŸàŽ¯ àŽàŽŸàŽ°àŽ£àŽàµàŽàŽ³àµâ <ul>
+<li> àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµâ  _gsdlhome_/tmp àŽµàŽŸàŽ¯àŽ¿àŽàµàŽàµàŽµàŽŸàŽšàµ àŽàŽŽàµàŽ€àŽŸàŽšàµ àŽªàµàŽ°àŽµàµàŽ¶àŽ¿àŽàµàŽàŽŸàŽšàµ àŽàŽ³àµàŽ³ àŽ
+àŽšàµàŽ®àŽ€àŽ¿ àŽàŽ£àµàŽàŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽ¿àŽ²àµàŽ²</ul>}  
+
+_textmkcolfail_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ (mkcol.pl failed) àŽ¡àŽ¯àŽ±àŽàµàŽàŽ±àŽ¿àŽ¯àµàŽàµ àŽàŽàŽšàŽŸ àŽ°àµàŽªàµàŽàŽ°àŽ£ àŽžàŽ®àŽŸàŽ¹àŽ°àŽ£àŽ àŽªàŽ°àŽŸàŽàŽ¯àŽªàµàŽªàµàŽàµàŽàµ. àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ®àŽŸàŽ¯ àŽàŽŸàŽ°àŽ£àŽàµàŽàŽ³àµ<ul> 
+<li>_gsdlhome_/tmp àŽ¡àŽ¯àŽ±àŽàµàŽàŽ±àŽ¿àŽàµàŽàµ àŽàŽŽàµàŽ€àŽŸàŽšàµàŽ³àµàŽ³ àŽ
+àŽšàµàŽµàŽŸàŽŠàŽ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµ àŽàŽ£àµàŽàŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽ¿àŽ²àµàŽ² 
+<li> mkcol.pl perl àŽžàµàŽàµàŽ°àŽ¿àŽªàµàŽ±àµàŽ±àŽ¿àŽ²àµ àŽªàŽ¿àŽŽàŽµàµàŽàŽ³àµ 
+</ul>}  
+
+_textnocontent_ [l=ml] {àŽžàŽ®àŽŸàŽ¹àŽ°àŽ£ àŽªàŽ¿àŽ¶àŽàµâ. àŽªàµàŽ€àŽ¿àŽ¯ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµâ àŽšàŽŸàŽ®àŽàŽ°àŽ£àŽ àŽàµàŽ¯àµâàŽ€àŽ¿àŽ²àµàŽ². àŽàŽŠàµàŽ¯àŽ®àµ àŽµàµàŽ£àµàŽàµàŽ àŽ€àµàŽàŽàµàŽàµàŽ}  
+
+_textrestart_ [l=ml] {àŽàŽ³àŽàµàŽàŽ°àµâ àŽªàµàŽšàŽ°àŽŸàŽ°àŽàŽ­àŽ¿àŽàµàŽàµàŽ}  
+
+_textreloaderror_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ àŽ¶àµàŽàŽ°àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£àŽ€àµàŽ€àŽ¿àŽšàŽ¿àŽàŽ¯àŽ¿àŽ²àµâ àŽàŽ°àµ àŽªàŽ¿àŽŽàŽµàµ àŽªàŽ±àµàŽ±àŽ¿. àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽ¬àµàŽ°àµàŽžàŽ±àŽ¿àŽ²àµ "reload", "back" àŽ¬àŽàµàŽàŽ£àµàŽàŽ³àµàŽàµ àŽàŽªàŽ¯àµàŽàŽ€àµàŽ€àµàŽªàµàŽªàŽ±àµàŽ±àŽ¿ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµ àŽžàŽàŽ­àŽµàŽ¿àŽàµàŽ àŽ§àŽŸàŽ°àŽ£àŽŸàŽªàŽ¿àŽ¶àŽàµ àŽ®àµàŽ²àŽ®àŽŸàŽµàŽŸàŽ àŽàŽ€àµâ. (àŽ¶àµàŽàŽ°àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽŸàŽ£ àŽµàµàŽ³àŽ¯àŽ¿àŽ²àµâ àŽ àŽ¬àŽàµàŽàŽ£àµàŽàŽ³àµàŽàµ àŽàŽªàŽ¯àµàŽàŽ àŽàŽŽàŽ¿àŽµàŽŸàŽàµàŽàŽŸàŽšàµâ àŽ¶àµàŽ°àŽŠàµàŽ§àŽ¿àŽàµàŽàµàŽ). àŽàŽ²àŽàµàŽàŽ°àµâ àŽàŽŠàµàŽ¯àŽ®àµ àŽàŽ°àŽàŽ­àŽ¿àŽàµàŽàµàŽµàŽŸàŽšàµâ àŽ¶àµàŽªàŽŸàŽ°àµâàŽ¶àŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàµ. }  
+
+_textexptsuc_ [l=ml] {_cgiargbc1dirname_ àŽ¶àµàŽàŽ°àŽ àŽµàŽ¿àŽàŽ¯àŽàŽ°àŽ®àŽŸàŽ¯àŽ¿  _gsdlhome_/tmp/exported\__cgiargbc1dirname_  àŽ¡àŽ¯àŽ±àŽàµàŽàŽ±àŽ¿àŽ¯àŽ¿àŽ²àµàŽàµàŽàµ àŽàŽàµàŽžàµàŽªàµàŽ°àµàŽàµàŽàµàŽàµàŽ¯àµàŽ€àµ.}  
+
+_textexptfail_ [l=ml] {<p>àŽ¶àµàŽàŽ°àŽ àŽàŽàµàŽžàµàŽªàµàŽ°àµàŽàµàŽàµàŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàŽ€àŽ¿àŽ²àµ àŽªàŽ°àŽŸàŽàŽ¯àŽ 
+<p>àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿ àŽàŽàµàŽžàµàŽªàµàŽ°àµàŽàµàŽàµ àŽ«àŽàµàŽ·àŽšàµ àŽàŽµàŽ¶àµàŽ¯àŽ®àŽŸàŽ¯ àŽàŽàŽàŽàµàŽàŽ³àµ àŽàŽšàµàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµ àŽàµàŽ¯àµàŽ€àŽ¿àŽàµàŽàµàŽ£àµàŽàŽŸàŽµàŽŸàŽšàµ àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ€àŽ¯àŽ¿àŽ²àµàŽ²àŽŸàŽ€àµàŽ€àŽ€àµàŽàµàŽ£àµàŽàŽŸàŽµàŽŸàŽ àŽàŽàµàŽàŽ¿àŽšàµ àŽžàŽàŽ­àŽµàŽ¿àŽàµàŽàŽ€àµ. <ul> 
+<li>àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽàŽšàµàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµ àŽàµàŽ¯àµàŽ€àŽ€àµ àŽžàŽ¿.àŽ¡àŽ¿àŽ¯àŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµ àŽ àŽàŽàŽàŽàµàŽàŽ³àµ àŽàŽšàµàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµ àŽàµàŽ¯àµàŽ¯àŽªàµàŽªàµàŽàµàŽàµàŽàŽŸàŽ£àµàŽàŽ¯àŽ¿àŽ²àµàŽ². àŽàŽžàµàŽ±àµàŽ±àŽ àŽàŽšàµàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµàŽ·àŽšàµ àŽ°àµàŽ€àŽ¿ àŽ
+àŽšàµàŽžàŽ°àŽ¿àŽàµàŽàµ àŽàŽµàŽ¶àµàŽ¯àŽ®àŽŸàŽ¯ àŽàŽàŽàŽàµàŽàŽ³àµ àŽ€àŽ¿àŽ°àŽàµàŽàŽàµàŽ€àµàŽ€àµàµ àŽªàµàŽšàŽžàµàŽ¥àŽŸàŽªàŽ¿àŽàµàŽàµàŽàŽ¯àŽŸàŽ£àµ àŽµàµàŽ£àµàŽàŽ€àµ. 
+<li>àŽµàµàŽ¬àµàµàŽžàµàŽ±àµàŽ±àŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàµàŽ®àŽŸàŽ£àµ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽžàµàŽ¥àŽŸàŽªàŽ¿àŽàµàŽàŽ€àµàŽàµàŽàŽ¿àŽ²àµ, àŽàŽ°àµ àŽ
+àŽ¡àµàŽ·àŽ£àŽšàµ àŽªàŽŸàŽàµàŽàµàŽàµ àŽ¡àµàŽ£àµàŽ²àµàŽ¡àµ àŽàµàŽ¯àµàŽ€àµ àŽàŽšàµàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµ àŽàµàŽ¯àµàŽ¯àµàŽ£àµàŽàŽ€àµàŽ£àµàŽàµ. àŽŠàŽ¯àŽµàŽŸàŽ¯àŽ¿ <a href="http://www.greenstone.org">http://www.greenstone.org</a>àŽžàµàŽ±àµàŽ±àµ àŽžàŽšàµàŽŠàŽ°àµàŽ¶àŽ¿àŽàµàŽàµàŽ àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿àŽ²àµ  
+  àŽàŽ®àµàŽ¯àŽ¿àŽ²àµ <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a> . àŽ
+àŽ¯àŽàµàŽàµàŽ</ul>}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=ml] {<p> àŽŠàŽ¯àŽµàŽŸàŽ¯àŽ¿ àŽ€àŽŸàŽŽàµàŽªàŽ±àŽ¯àµàŽšàµàŽš àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµ àŽšàŽ²àµàŽàŽ¿ _textintro_ below. </p>àŽ
+àŽ®àŽ°àµàŽ€àµàŽ€àµàŽ}  
+
+_textcaec_ [l=ml] {àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽ²àµàŽàµàŽàµ àŽàµàŽàµàŽàŽ¿àŽàµàŽàµàŽ°àµàŽàµàŽàŽ²àµ}  
+_textbild_ [l=ml] {àŽ¡àŽ¿àŽªàµàŽªàµàŽžàŽ¿àŽ±àµàŽ±àµ àŽàŽšàŽ}  
+_textintro_ [l=ml] {àŽ«àŽ¯àŽ²àµ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽàµàŽàµàŽ}  
+_textconfirm_ [l=ml] {àŽžàµàŽ¥àŽ¿àŽ°àµàŽàŽ°àŽ£àŽ}  
+_textselect_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽàµàŽàµàŽ}  
+_textmeta_ [l=ml] {àŽ®àµàŽ±àµàŽ±àŽ¡àµàŽ±àµàŽ± àŽµàµàŽ¯àŽàµàŽ€àŽ®àŽŸàŽàµàŽàµàŽ}  
+
+
+_texttryagain_ [l=ml] {àŽŠàŽ¯àŽµàŽŸàŽ¯àŽ¿ <a href="_httppagedepositor_" target=_top>àŽ¡àŽ¿àŽªàµàŽªàµàŽžàŽ¿àŽ±àµàŽ±àŽ°àµ àŽªàµàŽš:àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµ àŽµàµàŽ£àµàŽàµàŽ àŽ¶àµàŽ°àŽ®àŽ¿àŽàµàŽàµàŽ</a>}  
+
+_textselectcol_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯àŽ€àµ àŽàµàŽàµàŽàŽ¿àŽàµàŽ°àµàŽàµàŽàŽŸàŽšàµàŽ³àµàŽ³ àŽ¶àµàŽàŽ°àŽ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽàµàŽàµàŽ}  
+_textfilename_ [l=ml] {àŽ«àŽ¯àŽ²àŽ¿àŽšàµàŽ±àµ àŽªàµàŽ°àµ}  
+_textfilesize_ [l=ml] {àŽ«àŽ¯àŽ²àŽ¿àŽšàµàŽ±àµ àŽµàŽ²àµàŽªàµàŽªàŽ}  
+
+_textretcoll_ [l=ml] {àŽ¡àŽ¿àŽªàµàŽªàµàŽžàŽ¿àŽ±àµàŽ±àŽ±àŽ¿àŽ²àµàŽàµàŽàµ àŽ®àŽàŽàµàŽàµàŽ}  
+
+
+_texttmpfail_ [l=ml] {àŽ¡àŽ¿àŽªàµàŽªàµàŽžàŽ¿àŽ±àµàŽ±àŽ°àµ àŽ€àŽŸàŽ€àµàŽàŽŸàŽ²àŽ¿àŽ àŽ«àŽ¯àŽ²àµ àŽ®àŽšàŽžàµàŽžàŽ¿àŽ²àŽŸàŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽ²àµ àŽµàŽŸàŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽ²àµ àŽªàŽ°àŽŸàŽàŽ¯àŽªàµàŽªàµàŽàµàŽàµ. àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ®àŽŸàŽ¯ àŽàŽŸàŽ°àŽ£àŽàµàŽàŽ³àµ<ul><li>àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµ _gsdlhome_/tmp 
+      directory àŽàŽªàŽ¯àµàŽàŽŸàŽšàµàŽ®àŽ€àŽ¿ àŽàŽ²àµàŽ²àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽŸàŽ </ul>}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=ml] {àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿àŽàŽ³àµàŽàµàŽàµ àŽµàŽ³àŽ°àµ àŽžàŽ¹àŽŸàŽ¯àŽàŽ®àŽŸàŽ¯ àŽžàµàŽµàŽšàŽàµàŽàŽ³àµ àŽšàŽ²àµàŽàµàŽšàµàŽš àŽàŽ°àµ àŽžàµàŽ«àµàŽ±àµàŽ± àŽµàµàŽ¯àŽ°àµ àŽžàŽ®àµàŽàµàŽàŽ¯àŽ®àŽŸàŽ£àµ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµ. àŽµàŽ¿àŽµàŽ°àŽ¶àµàŽàŽ°àŽ£àŽ€àµàŽ€àŽ¿àŽšàµàŽ àŽàŽšàµàŽ±àŽ°àµàŽšàµàŽ±àµàŽ±àŽ¿àŽ²àµàŽ àŽžàŽ¿àŽ¡àŽ¿ àŽ±àµàŽ®àŽ¿àŽ²àµàŽ®àŽŸàŽ¯àŽ¿ àŽ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµ àŽàµàŽ°àŽ®àµàŽàŽ°àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽšàµàŽ®àŽŸàŽ¯àŽ¿ àŽàŽ°àµ àŽšàµàŽ€àŽšàŽ®àŽŸàŽ°àµàŽàŽ®àŽŸàŽ£àµ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµ. àŽšàµàŽ¯àµàŽžàŽ¿àŽ²àŽŸàŽšàµàŽ±àŽ¿àŽ²àµ àŽµàµàŽàµàŽàŽŸàŽàµàŽàµ àŽžàŽ°àµàŽµàµàŽµàŽàŽ²àŽŸàŽ¶àŽŸàŽ²àŽ¯àŽ¿àŽ²àµ àŽšàµàŽ¯àµàŽžàŽ¿àŽ²àŽŸàŽšàµàŽ±àµ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽªàµàŽ°àµàŽŸàŽàŽàµàŽàµ àŽàŽ£àµ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµàŽ±àµ àŽàŽªàŽàµàŽàŽŸàŽ€àŽŸàŽµàµ. àŽ¹àµàŽ¯àµàŽ®àŽšàµ àŽàŽšàµàŽ±àŽ«àµ àŽàŽšàµ.àŽàŽ¿.àŽàŽ¯àµàŽ àŽ¯àµàŽšàŽžàµàŽàµàŽ¯àµàŽ àŽàµàŽ°àµàŽšàµàŽšàŽŸàŽ£àµ àŽàŽ€àŽ¿àŽšàµàŽ±àµ àŽµàŽ¿àŽ€àŽ°àŽ£àŽ àŽšàŽàŽ€àµàŽ€àµàŽšàµàŽšàŽ€àµ. àŽàŽšàŽ±àŽ²àµ àŽªàŽ¬àµàŽ²àŽ¿àŽàµ àŽ²àµàŽžàŽšàµàŽžàµ àŽšàŽ¿àŽ¬àŽšàµàŽ§àŽšàŽàŽ³àµàŽàµàŽàµ àŽµàŽ¿àŽ§àµàŽ¯àŽ®àŽŸàŽ¯àŽ¿  <i>http://greenstone.org</i>  àŽ²àµ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽ¯ àŽàŽªàµàŽªàŽ£àµ àŽžàµàŽŽàµàŽžàµ àŽžàµàŽ«àµàŽ±àµàŽ±àµ àŽµàµàŽ¯àŽ±àŽŸàŽ£àµ àŽàŽ€àµ. }  
+
+_textgreenstone2_ [l=ml] {àŽšàµàŽ¯àµàŽžàŽ¿àŽ²àŽŸàŽšàµàŽ±àµâ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿àŽ¯àŽ¿àŽ²àµâ  (<a
+href="http://nzdl.org">http://nzdl.org</a>)  àŽªàµàŽ€àµàŽµàŽŸàŽ¯àŽ¿ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽ¯ àŽ
+àŽšàµàŽàŽ àŽ®àŽŸàŽ€àµàŽàŽŸ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµàŽ£àµàŽàµâ. àŽ
+àŽµàŽ¯àµàŽ²àµàŽ²àŽŸàŽ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàŽµàŽ¯àŽŸàŽ£àµâ. àŽ
+àŽµàŽ¯àŽ¿àŽ²àµâ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽšàµàŽ àŽ¬àµàŽ°àµàŽžàµâ àŽàµàŽ¯àµàŽ¯àŽŸàŽšàµàŽ®àµàŽ³àµàŽ³ àŽšàŽ¿àŽ°àŽµàŽ§àŽ¿ àŽ°àµàŽ€àŽ¿àŽàŽ³àµâ àŽàŽŸàŽ£àŽ¿àŽàµàŽàŽ¿àŽàµàŽàµàŽ£àµàŽàµâ. àŽ
+àŽ±àŽ¬àŽ¿àŽàµâ, àŽàµàŽšàµàŽžàµâ, àŽ«àµàŽ°àŽàµàŽàµâ, àŽ®àŽŸàŽµàµàŽ±àŽ¿, àŽžàµâàŽªàŽŸàŽšàŽ¿àŽ·àµâ, àŽàŽàŽàµàŽ²àµàŽ·àµâ àŽàŽšàµàŽšàµ àŽ­àŽŸàŽ·àŽàŽ³àŽ¿àŽ²àµàŽ³àµàŽ³ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµâ àŽàŽ€àŽ¿àŽ²àµàŽ£àµàŽàµâ. }  
+
+_textplatformtitle_ [l=ml] {àŽªàµàŽ²àŽŸàŽ±àµàŽ±àµâ àŽ«àµàŽ}  
+_textgreenstone3_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽµàŽ¿àŽšàµàŽ¡àµàŽžàµ, àŽ¯àµàŽ£àŽ¿àŽàµàŽžàµ, àŽ®àŽŸàŽàµ àŽàŽšàµàŽšàŽ¿àŽµàŽ¯àŽ¿àŽ²àµ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ. àŽàµàŽàŽŸàŽ€àµ àŽµàŽ¿àŽšàµàŽ¡àµàŽžàŽ¿àŽšàµàŽ±àµ àŽàŽ²àµàŽ²àŽŸàŽªàŽ€àŽ¿àŽªàµàŽªàŽ¿àŽ²àµàŽ àŽ²àŽ¿àŽšàŽàµàŽžàŽ¿àŽ²àµàŽ àŽ®àŽŸàŽàµ, àŽ.àŽàŽžàµ àŽàŽàµàŽžàµ àŽàŽšàµàŽšàŽ¿àŽµàŽ¯àŽ¿àŽ²àµàŽ àŽàŽàŽšàµàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽµàµàŽšàµàŽš àŽ¬àµàŽšàŽ±àŽ¿ àŽžàµàŽ«àµàŽ±àµàŽ± àŽµàµàŽ¯àŽ°àµ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽ£àµ. àŽžàµàŽŽàµàŽžàµàŽàµàŽ¡àµ àŽ
+àŽàŽàµàŽàŽ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽàµàŽšàµàŽšàŽ€àŽŸàŽàŽ¯àŽŸàŽ²àµ àŽàŽ€àµ àŽžàŽ¿++ àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿àŽ²àµ àŽàŽ¿.àŽžàŽ¿.àŽžàŽ¿ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽ¿àŽšàŽšàŽ¿àŽ°àŽ€àŽ®àŽŸàŽàµàŽàŽŸàŽšàµ àŽàŽŽàŽ¿àŽ¯àµàŽšàµàŽšàŽ€àµàŽ®àŽŸàŽ£àµ. àŽ
+àŽªàµàŽªàŽŸàŽ·àµ àŽµàµàŽ¬àµàŽžàµàŽ°àµàŽµàŽ°àµ àŽàŽšàµàŽ±àµ àŽªàµàŽ³àµ àŽàŽšàµàŽš àŽ
+àŽšàµàŽ¬àŽšàµàŽ§ àŽžàµàŽ«àµàŽ±àµàŽ±àµ àŽµàµàŽ¯àŽ±àµàŽ®àŽŸàŽ¯àŽ¿ àŽ¬àŽšàµàŽ§àŽªàµàŽªàµàŽàµàŽàµ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµ. àŽàŽšàµàŽ±àŽ°àµàŽšàµàŽ±àµàŽ±àµ àŽàŽàµàŽžàµàŽªàµàŽ²àµàŽ±àŽ±àµ àŽšàµàŽ±àµàŽ±àµàŽžàµàŽàµàŽ¯àŽ¿àŽªàµ àŽ¬àµàŽ°àµàŽžàŽ±àŽŸàŽ¯àŽ¿ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ àŽšàŽšàµàŽšàŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ. }  
+
+_textgreenstone4_ [l=ml] {àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµâ àŽªàŽ² àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµàŽ àŽžàŽ¿àŽ¡àŽ¿ àŽ±àµàŽ®àŽ¿àŽ²àµàŽàµ àŽµàŽ¿àŽ€àŽ°àŽ£àŽ àŽàµàŽ¯àµàŽ¯àŽªàµàŽªàµàŽàµàŽàŽ¿àŽàµàŽàµàŽ£àµàŽàµâ. àŽàŽŠàŽŸàŽ¹àŽ°àŽ£àŽ€àµàŽ€àŽ¿àŽšàµâ àŽ¹àµàŽ¯àµàŽ®àŽŸàŽšàŽ¿àŽ±àµàŽ±àŽ¿ àŽ¡àŽ¿àŽµàŽ²àŽªàµàŽªàµâàŽ®àµàŽšàµàŽ±àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ <i>Humanity Development Library</i> àŽ
+àŽàµàŽàµàŽ£àµàŽàŽ¿àŽàµâ àŽ®àµàŽ€àŽ²àµâ àŽàŽ²àŽ¶àµàŽàŽ¿àŽ€àµàŽµàŽ àŽµàŽ°àµàŽ¯àµàŽ³àµàŽ³ àŽµàŽ¿àŽ·àŽ¯àŽàµàŽàŽ³àŽ¿àŽ²àµàŽ³àµàŽ³ 1230 àŽªàµàŽ°àŽžàŽ¿àŽŠàµàŽ§àµàŽàŽ°àŽ£àŽàµàŽàŽ³àµàŽ£àµàŽàµâ. àŽµàŽ¿àŽàŽžàµàŽµàŽ°àŽ°àŽŸàŽ·àµàŽàµàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽàŽ¯àŽ°àµâàŽšàµàŽš àŽšàŽ¿àŽ²àŽµàŽŸàŽ°àŽ®àŽ¿àŽ²àµàŽ²àŽŸàŽ€àµàŽ€ àŽžàŽŸàŽ§àŽŸàŽ°àŽ£ àŽàŽàŽªàµàŽ¯àµàŽàµàŽàŽ±àµàŽàŽ³àŽ¿àŽ²àµâ àŽªàµàŽ²àµàŽ àŽàŽµ àŽªàµàŽ°àŽµàŽ°àµâàŽ€àµàŽ€àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽŸàŽ. àŽ
+àŽµàŽ¯àŽ¿àŽ²àµâ àŽ€àŽ¿àŽ°àŽ¯àŽŸàŽšàµàŽ àŽµàŽ¿àŽ·àŽ¯àŽàµàŽàŽ³àµàŽ àŽ¶àµàŽ°àµâàŽ·àŽàŽàµàŽàŽ³àµàŽ àŽªàµàŽ°àŽžàŽ¿àŽŠàµàŽ§àµàŽàŽ°àŽ¿àŽàµàŽ àŽžàµàŽ¥àŽŸàŽªàŽšàŽàµàŽàŽ³àµâ àŽµàŽàµàŽàµàŽ àŽ¬àµàŽ°àµàŽžàµâ àŽàµàŽ¯àµàŽ¯àµàŽµàŽŸàŽšàµàŽ àŽžàµàŽàŽ°àµàŽ¯àŽ®àµàŽ£àµàŽàµâ. àŽªàµàŽ°àŽžàŽ¿àŽŠàµàŽ§àµàŽàŽ°àŽ£àŽàµàŽàŽ³àµàŽàµ àŽªàµàŽ±àŽàŽàŽàµàŽ àŽšàµàŽàµàŽàŽ¿àŽªàµàŽ²àµàŽ àŽªàµàŽµàŽŸàŽšàµàŽ³àµàŽ³ àŽžàµàŽàŽ°àµàŽ¯àŽµàµàŽ®àµàŽ£àµàŽàµâ.}  
+
+_textcustomisationtitle_ [l=ml] {àŽ
+àŽšàµàŽ¯àµàŽàµàŽ¯àŽ®àŽŸàŽàµàŽàŽ²àµâ}  
+_textgreenstone5_ [l=ml] {àŽµàŽ¿àŽªàµàŽ²àµàŽàŽ°àŽ¿àŽàµàŽàŽŸàŽšàµàŽ àŽ°àµàŽªàŽ®àŽŸàŽ±àµàŽ±àŽ àŽµàŽ°àµàŽ€àµàŽ€àŽŸàŽšàµàŽ àŽªàŽ±àµàŽ±àµàŽ àŽµàŽ¿àŽ§àŽ®àŽŸàŽ£àµ àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽ°àµàŽªàŽàŽ²àµàŽªàŽšàŽàµàŽ¯àµàŽ¯àŽªàµàŽªàµàŽàµàŽàŽ¿àŽàµàŽàµàŽ³àµàŽ³àŽ€àµ. àŽªàµàŽ°àŽžàŽ¿àŽŠàµàŽ§àµàŽàŽ°àŽ£àŽàµàŽàŽ³àµàŽ àŽ®àµàŽ±àµàŽ±àŽŸàŽ¡àµàŽ±àµàŽ±àŽàŽ³àµàŽ àŽàŽ³àµàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽšàµàŽšàŽ€àµ àŽªàµàŽ²àŽàŽ¿àŽšàµàŽàŽ³àµ  "plugins" (in Perl) àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽàµàŽ£àµàŽàŽŸàŽ£àµ. àŽàµàŽ²àŽŸàŽžàŽ¿àŽ«àµàŽ¯àŽ±àµàŽàŽ³àµàŽàµàŽàµ àŽ°àµàŽªàŽàŽàµàŽàµàŽ€àµàŽ€àµ àŽ®àµàŽ±àµàŽ±àŽŸàŽ¡àŽŸàŽ±àµàŽ±àŽŸ àŽ¬àµàŽ°àµàŽžàŽ¿àŽàµàŽàµ àŽàŽàŽš àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽ¿àŽàµàŽàŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ. àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽ¬àµàŽ°àµàŽžàµ àŽàµàŽ¯àµàŽ¯àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ. àŽ²àŽ³àŽ¿àŽ€àŽ®àŽŸàŽ¯ àŽ®àŽŸàŽàµàŽ°àµàŽŸ àŽ­àŽŸàŽ· àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµàŽ±àµ àŽŠàŽ°àµàŽ¶àŽšàŽ°àµàŽªàŽ€àµàŽ€àŽ¿àŽ²àµ àŽ®àŽŸàŽ±àµàŽ±àŽàŽµàŽ°àµàŽ€àµàŽ€àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ. àŽªàµàŽ°àŽ®àŽŸàŽ£ àŽ¶àµàŽàŽ°àŽµàµàŽ®àŽŸàŽ¯àŽ¿ àŽ¬àŽšàµàŽ§àŽªàµàŽªàµàŽàµàŽàµàŽàŽ¿àŽàŽàµàŽàµàŽšàµàŽš àŽžàŽàŽ² àŽžàµàŽàŽ°àµàŽ¯àŽàµàŽàŽ³àµàŽ àŽàŽªàŽ¯àµàŽàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽŸàŽšàµ àŽàµàŽ°àµàŽ¬àŽŸ àŽªàµàŽ°àµàŽŸàŽàµàŽàµàŽàµàŽ³àµ àŽžàŽ¹àŽŸàŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽšàµ. àŽ
+àŽµàŽžàŽŸàŽšàŽ®àŽŸàŽ¯àŽ¿ àŽžàŽ¿++ àŽ²àµàŽ àŽªàµàŽ³àŽ¿àŽ²àµàŽ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽµàµàŽšàµàŽš àŽžàµàŽ°àµàŽžàµ àŽàµàŽ¡àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽàŽšàµàŽ€àµàŽ®àŽŸàŽ±àµàŽ±àŽ àŽµàµàŽ£àŽ®àµàŽàµàŽàŽ¿àŽ²àµàŽ àŽµàŽ°àµàŽ€àµàŽ€àµàŽàŽ¯àµàŽ®àŽŸàŽµàŽŸàŽ.}  
+
+_textdocumentationtitle_ [l=ml] {àŽªàµàŽ°àŽ®àŽŸàŽ£àŽàµàŽàŽ³àµâ}  
+_textdocuments_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµâ àŽžàµàŽ«àµâàŽ±àµàŽ±àµâ àŽµàµàŽ¯àŽ±àŽ¿àŽšàµ àŽžàŽàŽ¬àŽšàµàŽ§àŽ¿àŽàµàŽàµâ àŽµàŽ¿àŽ¶àŽŠàŽ®àŽŸàŽ¯ àŽ°àµàŽàŽàŽ³àµâ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽ£àµâ}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=ml] {àŽ®àµàŽ¯àŽ¿àŽ²àŽ¿àŽàµâ àŽ²àŽ¿àŽžàµàŽ±àµàŽ±àµâ}  
+_textmailinglist_ [l=ml] {àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àµâ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµâ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽžàµàŽ«àµâàŽ±àµàŽ±àµâ àŽµàµàŽ¯àŽ±àŽ¿àŽšàµàŽ±àµ àŽàŽŸàŽ°àµàŽ¯àŽàµàŽàŽ³àµâ àŽàŽ°àµâàŽàµàŽ àŽàµàŽ¯àµàŽ¯àŽŸàŽšàŽŸàŽ¯àŽ¿ àŽàŽ°àµ àŽ®àµàŽ¯àŽ¿àŽ²àŽ¿àŽàµàŽàµâ àŽ²àŽ¿àŽžàµàŽ±àµàŽ±àµâ àŽàŽ£àµàŽàµâ <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>. àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµàŽ±àµ àŽžàŽàµàŽµ àŽàŽªàŽ­àµàŽàµàŽ€àŽŸàŽàµàŽàŽ³àµâ àŽ
+àŽ€àŽ¿àŽ²àµâ àŽàµàŽ°àµàŽàŽ¯àµàŽ àŽàŽ°àµâàŽàµàŽàŽàŽ³àŽ¿àŽ²àµâ àŽªàŽ°àŽ®àŽŸàŽµàŽ§àŽ¿ àŽžàŽàŽ­àŽŸàŽµàŽšàŽàµàŽ¯àµàŽ¯àµàŽàŽ¯àµàŽ àŽµàµàŽ£àŽ.
+
+àŽàŽ°àµ àŽžàŽšàµàŽŠàµàŽ¶àŽ àŽ
+àŽ€àŽ¿àŽ²àµàŽ¯àµàŽàµàŽàµ àŽ
+àŽ¯àŽàµàŽàµàŽµàŽŸ <a href="mailto:greenstone-users@list.scms.waikato.ac.nz">greenstone-users@list.scms.waikato.ac.nz</a>.}  
+
+_textbugstitle_ [l=ml] {àŽµàµàŽ±àŽžàµâ àŽ€àŽàŽ°àŽŸàŽ±àµàŽàŽ³àµâ}  
+_textreport_ [l=ml] {àŽ àŽžàµàŽ«àµàŽ±àµàŽ±àµ àŽµàµàŽ¯àŽ°àµ àŽšàŽšàµàŽšàŽŸàŽ¯àŽ¿ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽ¿àŽàµàŽàµàŽàŽŸàŽ£àµàŽµàŽŸàŽšàµ àŽàŽàµàŽàŽ³àµ àŽ
+àŽ€àŽ¿àŽ¯àŽŸàŽ¯àŽ¿ àŽàŽàµàŽ°àŽ¹àŽ¿àŽàµàŽàµàŽšàµàŽšàµ. àŽàŽšàµàŽ€àµàŽàµàŽàŽ¿àŽ²àµàŽ àŽ€àŽàŽ°àŽŸàŽ±àµàŽàŽ³àµ àŽ¶àµàŽ°àŽŠàµàŽ§àŽ¯àŽ¿àŽ²àµ àŽªàµàŽàµàŽàŽ¯àŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµ <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a> àŽ²àµàŽàµàŽàµ àŽ
+àŽ¯àŽàµàŽàµàŽµàŽŸàŽšàµ àŽ¶àµàŽªàŽŸàŽ°àµàŽ¶ àŽàµàŽ¯àµàŽ¯àµàŽšàµàŽšàµ.}  
+
+_textgs3title_ [l=ml] {àŽàµàŽ²àŽ¿àŽ¯àŽ¿àŽ²àµâ}  
+_textgs3_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµâ2 àŽšàµàŽ±àµ àŽªàµàŽ°àµâàŽ£àŽ®àŽŸàŽ¯ àŽªàµàŽš:àŽàµàŽ°àŽ®àµàŽàŽ°àŽ£àŽµàµàŽ àŽ°àµàŽªàµàŽàŽ°àŽ£àŽµàµàŽ®àŽŸàŽ£àµâ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµâ 3. àŽµàŽ¿àŽµàŽ¿àŽ§ àŽ­àŽŸàŽ·àŽàŽ³àŽ¿àŽ²àµàŽ àŽªàµàŽ²àŽŸàŽ±àµàŽ±àµàŽ«àµàŽ®àµàŽàŽ³àŽ¿àŽ²àµàŽ àŽªàµàŽ°àŽµàŽ°àµâàŽ€àµàŽ€àŽ¿àŽàµàŽàµàŽšàµàŽš àŽàµàŽ£àµâàŽ«àŽ¿àŽàŽ±àµàŽ·àŽšàµâ, àŽ®àŽŸàŽ±àµàŽ±àŽ àŽµàŽ°àµàŽ€àµàŽ€àŽŸàŽšàµàŽ€àŽàµàŽšàµàŽš àŽ€àŽ°àŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³àŽ€àµâ àŽ€àµàŽàŽàµàŽàŽ¿àŽ¯ àŽžàŽµàŽ¿àŽ¶àµàŽ·àŽ€àŽàŽ³àµâ àŽšàŽ¿àŽ²àŽšàŽ¿àŽ°àµâàŽ€àµàŽ€àµàŽšàµàŽšàµ. àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽžàŽàŽ² àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµàŽ àŽ
+àŽ€àµàŽªàŽàŽ¿ àŽàŽ€àŽ¿àŽ²àµâ àŽªàµàŽ°àŽµàŽ°àµâàŽ€àµàŽ€àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµâ. àŽàŽŸàŽµàŽ¯àŽ¿àŽ²àµâ àŽàŽŽàµàŽ€àŽ¿àŽ¯ àŽàŽàµâàŽžàµâ.àŽàŽ.àŽàŽ²àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµâ àŽªàµàŽ°àŽµàŽ°àµâàŽ€àµàŽ€àŽ¿àŽàµàŽàµàŽšàµàŽš àŽµàŽ¿àŽµàŽ¿àŽ§ àŽžàµàŽµàŽ€àŽšàµàŽ€àµàŽ° àŽ®àµàŽ¡àµàŽ¯àµàŽ³àµàŽàŽ³àµàŽàµ àŽ¶àµàŽàŽàŽ²àŽ¯àŽŸàŽ¯àŽŸàŽ£àµâ àŽàŽ€àµâ àŽ°àµàŽªàŽàŽ²àµâàŽªàŽšàŽàµàŽ¯àµàŽ¯àŽªàµàŽªàµàŽàµàŽàŽ¿àŽàµàŽàµàŽ³àµàŽ³àŽ€àµâ. àŽ
+àŽ€àµâ àŽµàŽ¿àŽµàŽ¿àŽ§ àŽµàµàŽ¬àµâàŽžàŽ°àµâàŽµàµàŽµàŽ±àµàŽàŽ³àŽ¿àŽ²àµâ àŽµàŽ¿àŽàµàŽšàµàŽŠàµàŽ°àµàŽàŽ°àŽ¿àŽàµàŽàµâ àŽµàŽ¿àŽšàµàŽ¯àŽžàŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽàŽ¿àŽàŽ€àµàŽ€àµàŽšàŽ¿àŽšàµàŽšàŽŸàŽ£àµâ àŽ
+àŽ€àŽ¿àŽšàµàŽ±àµ àŽªàµàŽ°àŽµàŽ°àµâàŽ€àµàŽ€àŽšàŽ. àŽµàŽ³àŽ°àµ àŽµàŽ°àµâàŽŠàµàŽ§àŽ¿àŽàµàŽàµâ àŽµàŽ¿àŽªàµàŽ²àµàŽàŽ°àŽ£-àŽšàŽµàµàŽàŽ°àŽ£ àŽžàŽŸàŽŠàµàŽ§àµàŽ¯àŽ€àŽàŽ³àŽŸàŽ£àµâ àŽàŽ€àŽ¿àŽšàµàŽ³àµàŽ³àµàŽ€àµâ. àŽªàŽŽàŽ¯àŽªàŽ€àŽ¿àŽªàµàŽªàµàŽàŽ³àµâ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµâ àŽžàµàŽ±àµàŽ±àŽ¿àŽ²àµâ àŽšàŽ¿àŽšàµàŽšàµàŽ àŽ²àŽ­àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽŸàŽ£àµâ. }  
+
+_textcreditstitle_ [l=ml] {àŽ¬àŽ¹àµàŽ®àŽ€àŽ¿}  
+
+_textwhoswho_ [l=ml] {àŽàŽ°àµàŽªàŽŸàŽàµ àŽàŽ³àµàŽàŽ³àµàŽàµ àŽàµàŽàµàŽàŽŸàŽ¯ àŽ¶àµàŽ°àŽ®àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽàŽ²àµàŽªàŽšàµàŽšàŽ®àŽŸàŽ£àµ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµ. àŽ±àµàŽàŽ°àµ àŽ®àŽàµàŽšàŽŸàŽ¬àµ, àŽžàµàŽ±àµàŽ±àµàŽ«àŽŸàŽšàµ àŽ¬àµàŽ¡àŽ¿ àŽàŽšàµàŽšàŽ¿àŽµàŽ°àŽŸàŽ£àµ àŽªàµàŽ°àŽ§àŽŸàŽš àŽ¶àŽ¿àŽ²àµàŽªàŽ¿àŽàŽ³àµ. 
+àŽ¡àµàŽµàŽ¿àŽ¡àµ àŽ¬àµàŽ°àµàŽ¯àŽ¿àŽšàµàŽ¬àµàŽ°àŽ¿àŽ¡àµàŽàµ, àŽàµàŽ°àµàŽàµ àŽ®àŽàµàŽàµàŽ¯àµ, àŽàµàŽ£àµ àŽ®àŽàµàŽ«àµàŽ°àµàŽžàŽšàµ, àŽàµàŽ°àµàŽ¯àŽ¿àŽàµ àŽšàµàŽµàŽ¿àŽ²àµàŽ®àŽŸàŽšàŽ¿àŽàµ, àŽ¡àµàŽšàŽŸàŽ³àµ àŽªàŽàµàŽàµàŽ²àµ, àŽàµàŽ°àµàŽ¡àŽšàµ àŽªàµàŽ¯àµàŽšàµàŽ±àŽ°àµ, àŽ¬àµàŽ£àµàŽ¹àŽŸàŽ°àµàŽ¡àµ àŽ«àŽŸàŽ±àŽ¿àŽàµàŽàŽ°àµ, àŽàµàŽ¡àµàŽ±àµàŽ¡àµ, àŽ¬àŽ¿àŽ²àµ àŽ±àµàŽàµàŽŽàµàŽžàµ, àŽàµàŽ£àµ àŽ€àµàŽàŽžàŽ£àµ, àŽžàµàŽ±àµàŽ±àŽ¿àŽ¯àµàŽµàŽŸàŽàµàŽàµ àŽ¯àµàŽ±àµàŽ±àµàŽžàµ àŽàŽšàµàŽšàŽ¿àŽµàŽ°àµàŽ àŽ àŽàŽŠàµàŽ¯àŽ®àŽ€àµàŽ€àŽ¿àŽšàŽŸàŽ¯àŽ¿ àŽžàŽàŽ­àŽŸàŽµàŽšàŽàµàŽ¯àµàŽ€àŽ¿àŽàµàŽàµàŽ£àµàŽàµ. 
+ 
+àŽ àŽàŽŠàµàŽ¯àŽ®àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽµàŽ¿àŽàŽ¯àŽ€àµàŽ€àŽ¿àŽšàŽŸàŽ¯àŽ¿ àŽàŽªàŽŠàµàŽ¶àŽàŽ°àŽŸàŽ¯àµàŽ àŽªàµàŽ°àŽàµàŽŠàŽàŽ°àŽŸàŽ¯àµàŽ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽ¿àŽàµàŽ àŽšàµàŽ¯àµàŽžàŽ¿àŽ²àŽŸàŽšàµàŽ±àµ àŽ¡àŽ¿àŽàŽ¿àŽ±àµàŽ±àŽ²àµ àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽªàµàŽ°àµàŽŸàŽàŽàµàŽàŽ¿àŽ²àµ àŽ®àŽ±àµàŽ±àµ àŽ®àµàŽ®àµàŽªàŽ°àµàŽ®àŽŸàŽ°àŽŸàŽ¯ àŽ®àŽŸàŽ°àµàŽàµ àŽ
+àŽªàµàŽªàŽ°àµàŽ²àŽ¿, àŽžàŽŸàŽ²àŽ¿ àŽàµ àŽàŽ£àµàŽ£àŽ¿àŽàµàŽ¹àŽŸàŽ, àŽ®àŽŸàŽ±àµàŽ±àµ àŽàµàŽ£àµàŽžàµ, àŽžàµàŽ±àµàŽ±àµàŽµàµ àŽàµàŽ£àµàŽžàµ, àŽàµ àŽàŽŸàŽàŽŸ àŽàµàŽàŽšàµ, àŽ®àµàŽàµàŽàµàŽ²àµ àŽ²àµàŽàµàŽžàµ, àŽ®àŽŸàŽ²àŽ¿àŽàŽŸ àŽ®àŽ¹àµàŽ¯àŽ¿, àŽàŽŸàŽ°àŽ¿ àŽ®àŽŸàŽ°àµàŽžàµàŽ¡àŽšàµ, àŽŠàŽŸàŽµàµ àŽšàŽ¿àŽàµàŽàµàŽ³àŽžàµ, àŽ²àµàŽ¯àµàŽ¡àµ àŽžàµàŽ®àŽ¿àŽ€àµàŽ€àµ àŽàŽšàµàŽšàŽ¿àŽµàŽ°àµàŽàµ àŽžàŽàŽ­àŽŸàŽµàŽšàŽàŽ³àµàŽ àŽžàµàŽ®àŽ°àŽ£àµàŽ¯àŽàµàŽàŽ³àŽŸàŽ£àµ. 
+ 
+àŽàŽ¿.àŽàŽšàµ.àŽ¯àµ àŽ²àµàŽžàŽšàµàŽžàµàŽ¡àµ àŽªàŽŸàŽàµàŽàµàŽàŽ¿àŽšàŽŸàŽ¯àŽ¿ àŽžàŽàŽ­àŽŸàŽµàŽšàŽàµàŽ¯àµàŽ€ àŽàŽ²àµàŽ²àŽŸàŽµàŽ°àµàŽàµàŽ àŽàŽàµàŽàŽ³àµàŽàµàŽàµàŽ³àµàŽ³ àŽàµàŽ€àŽàµàŽàŽ€ àŽ°àµàŽàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽšàµàŽšàµ.
+}  
+
+_textaboutgslong_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµâ àŽžàµàŽ«àµâàŽ±àµàŽ±àµâ àŽµàµàŽ¯àŽ±àŽ¿àŽšàµ àŽžàŽàŽ¬àŽšàµàŽ§àŽ¿àŽàµàŽàµâ}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=ml] {àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽªàŽàµàŽàŽ¿àŽ}  
+_textuser_ [l=ml] {àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽµàµâ}  
+_textas_ [l=ml] {àŽ
+àŽàµàŽàµàŽ£àµàŽàŽ¿àŽšàµàŽ±àµ àŽšàŽ¿àŽ²àŽµàŽŸàŽ°àŽ}  
+_textgroups_ [l=ml] {àŽàµàŽ°àµàŽªàµàŽªàµàŽàŽ³àµâ}  
+_textcomment_ [l=ml] {àŽµàŽ¿àŽ²àŽ¯àŽ¿àŽ°àµàŽ€àµàŽ€àŽ²àµâ}  
+_textadduser_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽµàŽ¿àŽšàµ àŽàµàŽ°àµâàŽàµàŽàµàŽ}  
+_textedituser_ [l=ml] {àŽàŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽ²àµâ}  
+_textdeleteuser_ [l=ml] {àŽàŽŽàŽ¿àŽµàŽŸàŽàµàŽàµàŽ}  
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=ml] {àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽµàŽ¿àŽšàµàŽ±àµ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽàŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ}  
+_textadduser_ [l=ml] {àŽàŽ°àµ àŽªàµàŽ€àŽ¿àŽ¯ àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽµàŽ¿àŽšàµ àŽàµàŽ°àµâàŽàµàŽàµàŽ}  
+
+_textaboutusername_ [l=ml] {àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽ 2 àŽ®àµàŽ€àŽ²àµâ 30 àŽ
+àŽàµàŽ·àŽ°àŽàµàŽàŽ³àµâàŽµàŽ°àµàŽ¯àµàŽ³àµàŽ³àŽ€àŽŸàŽµàŽŸàŽ. àŽ
+àŽàµàŽ·àŽ°àŽàµàŽàŽ³àµ àŽ
+àŽàµàŽàŽàµàŽàŽ³àµ àŽàŽ¿àŽ¹àµàŽšàŽàµàŽàŽ³àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ³àµàŽ³àŽ€àŽŸàŽµàŽŸàŽ àŽàŽ€àµâ  
+'.', and '_'.}  
+
+_textaboutpassword_ [l=ml] {àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽàµàŽ 3 àŽ®àµàŽ€àŽ²àµâ 128 àŽµàŽ°àµ àŽ
+àŽàµàŽ·àŽ°àŽàµàŽàŽ³àµâ àŽàŽ³àµàŽ³àŽ€àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽ£àŽ. àŽ
+àŽµàŽ¯àŽ¿àŽ²àµâ ASCII àŽ
+àŽàµàŽ·àŽ°àŽàµàŽàŽ³àµâ àŽ®àŽŸàŽ€àµàŽ°àŽ®àµ àŽàŽ£àµàŽàŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàŽŸàŽµàµ}  
+
+_textoldpass_ [l=ml] {àŽ àŽàµàŽ³àŽ àŽ¶àµàŽšàµàŽ¯àŽ®àŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµâ àŽªàŽŽàŽ¯ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ àŽ€àŽšàµàŽšàµ àŽšàŽ¿àŽ²àŽšàŽ¿àŽ²àµâàŽàµàŽàµàŽ}  
+_textenabled_ [l=ml] {àŽžàŽàµàŽµàŽ®àŽŸàŽàµàŽàŽ¿}  
+_textdisabled_ [l=ml] {àŽŠàµàŽ°àµâàŽ¬àŽ²àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽ¿}  
+
+_textaboutgroups_ [l=ml] {àŽàµàŽ® àŽàµàŽ£àµàŽàŽŸàŽ£àµâ àŽàµàŽ°àµàŽªàµàŽªàµàŽàŽ³àµ àŽµàŽ¿àŽ­àŽàŽ¿àŽàµàŽàŽ¿àŽàµàŽàµàŽ³àµàŽ³àŽ€àµâ. àŽàµàŽ® àŽàŽŽàŽ¿àŽàµàŽàµâ àŽ¶àµàŽšàµàŽ¯àŽžàµàŽ¥àŽ²àŽ àŽàŽàŽŸàŽšàµâ àŽªàŽŸàŽàŽ¿àŽ²àµàŽ².}  
+
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=ml] {àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽµàŽ¿àŽšàµ àŽàŽŽàŽ¿àŽµàŽŸàŽàµàŽàµàŽ}  
+_textremwarn_ [l=ml] {àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽµàŽ¿àŽšàµ àŽàŽšàµàŽšàµàŽšàµàŽšàµàŽàµàŽàµàŽ®àŽŸàŽ¯àŽ¿ àŽàŽŽàŽ¿àŽµàŽŸàŽàµàŽàµàŽ£àµàŽàŽ€àµàŽ£àµàŽàµ?}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=ml] {àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ àŽ®àŽŸàŽ±àµàŽ±àµàŽ}  
+_textoldpw_ [l=ml] {àŽªàŽŽàŽ¯ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ}  
+_textnewpw_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ àŽšàŽ²àµâàŽàµàŽ}  
+_textretype_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ àŽµàµàŽ£àµàŽàµàŽ àŽšàŽ²àµâàŽàµàŽ}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽ àŽµàŽ¿àŽàŽ¯àŽàŽ°àŽ®àŽŸàŽ¯ àŽ®àŽŸàŽ±àµàŽ±àŽ¿}  
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=ml] {àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽ àŽàŽªàŽ¯àµàŽàŽ€àµàŽ€àŽ¿àŽ²àŽ¿àŽ²àµàŽ²}  
+_textinvalidpassword_ [l=ml] {àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ àŽàŽªàŽ¯àµàŽàŽ€àµàŽ€àŽ¿àŽ²àŽ¿àŽ²àµàŽ²}  
+_textemptypassword_ [l=ml] {àŽŠàŽ¯àŽµàŽŸàŽ¯àŽ¿ àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽµàŽ¿àŽšàµàŽ±àµ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ àŽšàŽ²àµâàŽàµàŽ}  
+_textuserexists_ [l=ml] {àŽ àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽµàµâ àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ£àµàŽàµâ, àŽµàµàŽ±àµàŽ°àµ àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽ àŽšàŽ²àµâàŽàµàŽ}  
+
+_textusernameempty_ [l=ml] {àŽšàŽ¿àŽàµàŽàŽ³àµàŽàµ àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽ àŽšàŽ²àµâàŽàµàŽ}  
+_textpasswordempty_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽªàŽŽàŽ¯ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ àŽšàŽ²àµâàŽàµàŽ}  
+_textnewpass1empty_ [l=ml] {àŽªàµàŽ€àŽ¿àŽ¯ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ àŽµàµàŽ£àµàŽàµàŽ àŽšàŽ²àµâàŽàµàŽ}  
+_textnewpassmismatch_ [l=ml] {àŽ°àŽ£àµàŽàŽ¿àŽàŽ€àµàŽ€àµàŽ àŽšàŽ²àµâàŽàŽ¿àŽ¯ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ àŽ¯àµàŽàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ¿àŽ²àµàŽ²}  
+_textnewinvalidpassword_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽšàŽ²àµâàŽàŽ¿àŽ¯ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àŽ¿àŽ²àµàŽ²àŽŸàŽ€àµàŽ€àŽ€àŽŸàŽ£àµâ}  
+_textfailed_ [l=ml] {àŽàŽšàµàŽšàµàŽàŽ¿ àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽšàŽŸàŽ®àŽ àŽ
+àŽ²àµàŽ²àµàŽàµàŽàŽ¿ àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ àŽ€àµàŽ±àµàŽ±àŽŸàŽ£àµ}  
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽªàŽ€àŽ¿àŽªàµàŽªàµâ àŽšàŽ®àµàŽªàŽ°àµâ}  
+_textframebrowser_ [l=ml] {àŽàŽ€àµàŽàŽŸàŽ£àŽŸàŽšàµâ àŽ€àŽŸàŽàµàŽàŽ³àµâàŽàµàŽàµâ àŽàŽ°àµ àŽ«àµàŽ°àµàŽ¯àŽ¿àŽàŽžàŽ¹àŽŸàŽ¯àŽ®àµàŽ³àµàŽ³ àŽ¬àµàŽ°àµàŽžàŽ°àµâ àŽàŽµàŽ¶àµàŽ¯àŽ®àŽŸàŽ£àµâ}  
+_textusermanage_ [l=ml] {àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽªàŽ°àŽ¿àŽªàŽŸàŽ²àŽšàŽ}  
+_textlistusers_ [l=ml] {àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽªàŽàµàŽàŽ¿àŽ}  
+_textaddusers_ [l=ml] {àŽàŽ°àµ àŽªàµàŽ€àŽ¿àŽ¯ àŽàŽªàŽ¯àµàŽàµàŽ€àŽŸàŽµàŽ¿àŽšàµ àŽàŽ³àµâàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ}  
+_textchangepasswd_ [l=ml] {àŽ
+àŽàŽ¯àŽŸàŽ³àŽªàŽŠàŽ àŽ®àŽŸàŽ±àµàŽ±àµàŽ}  
+_textinfo_ [l=ml] {àŽžàŽŸàŽàµàŽàµàŽ€àŽ¿àŽ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ}  
+_textgeneral_ [l=ml] {àŽªàµàŽ€àµàŽµàŽŸàŽ¯àŽ¿}  
+_textarguments_ [l=ml] {àŽµàŽŸàŽŠàŽàµàŽàŽ³àµâ}  
+_textactions_ [l=ml] {àŽªàµàŽ°àŽµàµàŽ€àµàŽ€àŽ¿àŽàŽ³àµâ}  
+_textbrowsers_ [l=ml] {àŽ¬àµàŽ°àµàŽžàŽ±àµàŽàŽ³àµâ}  
+_textprotocols_ [l=ml] {àŽªàµàŽ°àµàŽŸàŽàµàŽàµàŽàµàŽàµàŽ³àµàŽàŽ³àµâ}  
+_textconfigfiles_ [l=ml] {àŽàµàŽ£àµâàŽ«àŽ¿àŽàŽ±àµàŽ·àŽšàµâ àŽ«àŽ¯àŽ²àµàŽàŽ³àµâ}  
+_textlogs_ [l=ml] {àŽªàŽàµàŽàŽ¿àŽàŽàŽ³àµâ}  
+_textusagelog_ [l=ml] {àŽàŽªàŽ¯àµàŽ àŽªàŽàµàŽàŽ¿àŽ}  
+_textinitlog_ [l=ml] {àŽªàŽàµàŽàŽ¿àŽ}  
+_texterrorlog_ [l=ml] {àŽªàŽ¿àŽŽàŽµàµàŽàŽ³àµàŽàµ àŽªàŽàµàŽàŽ¿àŽ}  
+_textadminhome_ [l=ml] {àŽ
+àŽ¡àµâàŽ®àŽ¿àŽšàµâ àŽ¹àµàŽ}  
+_textreturnhome_ [l=ml] {àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àµâ àŽ¹àµàŽ}  
+_titlewelcome_ [l=ml] {àŽ­àŽ°àŽ£àŽšàŽ¿àŽ°àµâàŽµàµàŽµàŽ¹àŽ£àŽ}  
+_textmaas_ [l=ml] {àŽªàŽ°àŽ¿àŽªàŽŸàŽ²àŽš - àŽ­àŽ°àŽ£àŽšàŽ¿àŽ°àµâàŽµàµàŽµàŽ¹àŽ£ àŽžàµàŽµàŽšàŽàµàŽàŽ³àŽ¿àŽ²àµâ àŽªàµàŽàµàŽšàµàŽšàŽ€àµâ:}  
+_textvol_ [l=ml] {àŽàŽ£àµâàŽ²àµàŽšàµâ àŽªàŽàµàŽàŽ¿àŽàŽàŽ³àµâ àŽàŽŸàŽ£àµàŽ}  
+_textcmuc_ [l=ml] {àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµâ àŽšàŽ¿àŽ°àµâàŽ®àµàŽ®àŽ¿àŽàµàŽàµàŽ, àŽšàŽ¿àŽ²àŽšàŽ¿àŽ°àµâàŽ€àµàŽ€àµàŽ, àŽªàµàŽ€àµàŽàµàŽàµàŽ}  
+_textati_ [l=ml] {àŽžàŽ¿.àŽàŽ¿.àŽ àŽµàŽŸàŽŠàŽàµàŽàŽ³àµâ àŽªàµàŽ²àµàŽ³àµàŽ³ àŽžàŽŸàŽàµàŽàµàŽ€àŽ¿àŽàŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àŽ¿àŽ²àµàŽàµàŽàµâ àŽªàµàŽ°àŽµàµàŽ¶àŽ¿àŽàµàŽàŽŸàŽ}  
+
+_texttsaa_ [l=ml] {àŽ àŽžàµàŽµàŽšàŽàµàŽàŽ³àµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàŽŸàŽšàµâ àŽµàŽ¶àŽàµàŽàŽ³àŽ¿àŽ²àµ àŽªàŽŸàŽ³àŽ¿àŽàŽ³àŽ¿àŽ²àµâ àŽàŽŸàŽ£àµàŽšàµàŽš àŽàŽ¿àŽ¹àµàŽšàŽàµàŽàŽ³àµâ àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµàŽ¯àµàŽ}  
+
+_textcolstat_ [l=ml] {àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽžàµàŽ¥àŽ¿àŽ€àŽ¿}  
+
+_textcwoa_ [l=ml] {àŽ¬àŽ¿àŽ²àµâàŽ¡àµâ àŽžàŽ¿.àŽàŽ«àµâ.àŽàŽ¿ àŽ«àŽ¯àŽ²àµàŽàŽ³àµâ àŽžàŽŸàŽ§àµàŽµàŽŸàŽ¯ àŽ«àµàŽ²àµâàŽ¡àµàŽàµàŽàµàŽàŽ¿ (i.e. > 0),àŽªàŽŸàŽ°àŽŸàŽ¯àŽ£àŽ¯àµàŽàµàŽ¯àŽ®àŽŸàŽ¯àŽ¿ àŽšàŽ¿àŽ²àµâàŽàµàŽàµàŽàŽ¯àŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµâ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµâ 'àŽ±àŽ£àµàŽ£àŽ¿àŽàŽàµâ' àŽàŽšàµàŽšàµ àŽàŽŸàŽ£àµàŽàŽ¯àµ àŽàŽ³àµàŽ³àµ. àŽàŽ€àŽ¿àŽšàµàŽ±àµ àŽžàµàŽ¥àŽŸàŽšàŽ àŽ¶àµàŽàŽ°àŽàµàŽàŽ³àµàŽàµ àŽàŽšàµâàŽ¡àŽàµâàŽžàµâ àŽ¡àŽ¯àŽ±àŽàµàŽàŽ±àŽ¿àŽ¯àŽ¿àŽ²àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽ (àŽ¬àŽ¿àŽ²àµâàŽ¡àŽ¿àŽàŽàµâ àŽ¡àŽ¯àŽ±àŽàµàŽàŽ±àŽ¿àŽ¯àŽ¿àŽ²àŽŸàŽ¯àŽ¿àŽ°àŽ¿àŽàµàŽàµàŽàŽ¯àŽ¿àŽ²àµàŽ²)}  
+
+_textcafi_ [l=ml] {àŽàŽ°àµ àŽ¶àµàŽàŽ°àŽ€àµàŽ€àµàŽªàµàŽªàŽ±àµàŽ±àŽ¿àŽ¯àµàŽ³àµàŽ³ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâàŽàµàŽàµâ <i>abbrev.</i> àŽàµàŽ²àŽ¿àŽàµàŽàµàŽàµàŽ¯àµàŽ¯àµàŽ}  
+_textcctv_ [l=ml] {àŽ¶àµàŽàŽ°àŽ àŽàŽŸàŽ£àŽŸàŽšàµâ <i>collection</i>}  
+_textsubc_ [l=ml] {àŽ®àŽŸàŽ±àµàŽ±àŽàµàŽàŽ³àµâ àŽžàŽ®àŽ°àµâàŽªàµàŽªàŽ¿àŽàµàŽàµàŽ}  
+_texteom_ [l=ml] {àŽªàµàŽ°àŽ§àŽŸàŽš àŽžàŽ¿.àŽàŽ«àµâ.àŽàŽ¿ àŽ€àµàŽ±àŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽ²àµâ àŽ€àŽàŽ°àŽŸàŽ±àµâ}  
+_textftum_ [l=ml] {àŽªàµàŽ°àŽ§àŽŸàŽš àŽžàŽ¿.àŽàŽ«àµâ.àŽàŽ¿ àŽªàµàŽ€àµàŽàµàŽàµàŽšàµàŽšàŽ€àŽ¿àŽ²àµâ àŽªàŽ°àŽŸàŽàŽ¯àŽªàµàŽªàµàŽàµàŽàµ}  
+_textmus_ [l=ml] {àŽªàµàŽ°àŽ§àŽŸàŽš àŽžàŽ¿.àŽàŽ«àµâ.àŽàŽ¿ àŽµàŽ¿àŽàŽ¯àŽàŽ°àŽ®àŽŸàŽ¯àŽ¿ àŽªàµàŽ€àµàŽàµàŽàŽ¿}  
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=ml] {"_collectionname_" àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµ àŽ¹àµàŽ°àŽžàµàŽµàŽµàŽ¿àŽµàŽ°àŽ àŽ°àµàŽªàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ}  
+_textflog_ [l=ml] {"_collectionname_" àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽªàŽ°àŽŸàŽàŽ¿àŽ€àŽ¶àµàŽ°àŽ®àŽàµàŽàŽ³àµàŽàµ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµ}  
+_textilog_ [l=ml] {"_collectionname_" àŽ¶àµàŽàŽ°àŽ€àµàŽ€àŽ¿àŽšàµàŽ±àµ àŽàŽ³àµàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽ²àµ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµ}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=ml] {àŽªàµàŽ°àŽ€àŽ¿àŽàŽ°àŽ£àŽ àŽ
+àŽ±àŽ¿àŽ¯àŽ¿àŽàµàŽàµàŽ}  
+
+_greenstoneusabilitytext_ [l=ml] {àŽàµàŽ°àµàŽšàµâàŽžàµâàŽ±àµàŽ±àµàŽ£àµâ àŽàŽªàŽ¯àµàŽàŽàµàŽ·àŽ®àŽ€}  
+
+_textwhy_ [l=ml] {<p>àŽ€àŽŸàŽàµàŽàŽ³àµâàŽàµàŽàµâ àŽªàµàŽ°àŽ¯àŽŸàŽžàŽ®àµàŽ³àŽµàŽŸàŽàµàŽàµàŽšàµàŽš àŽµàµàŽ¬àµâàŽªàµàŽàµâ àŽàŽ£àµàŽàµàŽ€àµàŽ€àŽ¿àŽ¯àµàŽšàµàŽšàŽŸàŽ£àµâ àŽ àŽ±àŽ¿àŽªàµàŽªàµàŽ°àµâàŽàµàŽàµâ àŽžàµàŽàŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµâ.}  
+_textextraforform_ [l=ml] {àŽšàŽ¿àŽàµàŽàŽ³àµâ àŽ«àµàŽ±àŽ àŽªàµàŽ°àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽ£àŽ®àµàŽšàµàŽšàŽ¿àŽ²àµàŽ²... àŽàŽ€àµ àŽµàŽ¿àŽµàŽ°àŽ®àŽŸàŽ¯àŽŸàŽ²àµàŽ àŽ®àŽ€àŽ¿}  
+_textprivacybasic_ [l=ml] {<p>àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽàŽ£àµàŽàµàŽàµàŽ£àµàŽàŽ¿àŽ°àŽ¿àŽàµàŽàµàŽšàµàŽš àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµâ àŽµàµàŽ¬àµâàŽªàµàŽàµàŽàŽ³àµàŽàµàŽàµàŽ±àŽ¿àŽàµàŽàµàŽ³àµàŽ³ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽ®àŽŸàŽ€àµàŽ°àŽ®àµ àŽ±àŽ¿àŽªàµàŽªàµàŽ°àµâàŽàµàŽàŽ¿àŽ²àµâ àŽàŽŸàŽ£àµàŽàŽ¯àµàŽ³àµàŽ³àµ}  
+_textstillsend_ [l=ml] {àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽàŽ€àµâ àŽ±àŽ¿àŽªàµàŽªàµàŽ°àµâàŽàµàŽàµâ àŽàµàŽ¯àµàŽ¯àµàŽµàŽŸàŽšàµâ àŽàŽàµàŽ°àŽ¹àŽ¿àŽàµàŽàµàŽšàµàŽšàµàŽ£àµàŽàµ?}  
+
+_texterror_ [l=ml] {àŽªàŽ¿àŽŽàŽµàµàŽàŽ³àµâ}  
+_textyes_ [l=ml] {àŽ
+àŽ€àµ}  
+_textno_ [l=ml] {àŽàŽ²àµàŽ²}  
+_textclosewindow_ [l=ml] {àŽàŽŸàŽ²àŽàŽ àŽ
+àŽàŽ¯àµâàŽàµàŽàµàŽ}  
+_textabout_ [l=ml] {àŽžàŽàŽ¬àŽšàµàŽ§àŽ¿àŽàµàŽàŽ€àµâ}  
+_textprivacy_ [l=ml] {àŽžàµàŽµàŽàŽŸàŽ°àµàŽ¯àŽ}  
+_textsend_ [l=ml] {àŽ
+àŽ¯àŽ¯àµâàŽàµàŽàµàŽ}  
+_textdontsend_ [l=ml] {àŽŠàŽ¯àŽµàŽŸàŽ¯àŽ¿ àŽ
+àŽ¯àŽ¯àµâàŽàµàŽàŽ°àµàŽ€àµâ}  
+_textoptionally_ [l=ml] {àŽ¹àŽ¿àŽ€àŽŸàŽšàµàŽžàŽ°àŽ£àŽ®àµàŽ³àµàŽ³}  
+
+_textunderdev_ [l=ml] {àŽµàŽ¿àŽ¶àŽŠàŽŸàŽàŽ¶àŽàµàŽàŽ³àµâ àŽ
+àŽšàµàŽ€àŽ¿àŽ®àŽ°àµàŽªàŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³ àŽªàŽ€àŽ¿àŽªàµàŽªàŽ¿àŽ²àµâ àŽàŽŸàŽ£àŽŸàŽ}  
+
+_textviewdetails_ [l=ml] {àŽ±àŽ¿àŽªàµàŽªàµàŽ°àµâàŽàµàŽàŽ¿àŽšàµàŽ±àµ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ àŽàŽŸàŽ£àµàŽ}  
+_textmoredetails_ [l=ml] {àŽàµàŽàµàŽ€àŽ²àµâ àŽµàŽ¿àŽµàŽ°àŽàµàŽàŽ³àµâ}  
+_texttrackreport_ [l=ml] {àŽ àŽ±àŽ¿àŽªàµàŽªàµàŽ°àµâàŽàµàŽàŽ¿àŽšàµ àŽªàŽ¿àŽšàµàŽ€àµàŽàŽ°àµàŽ}  
+_textcharacterise_ [l=ml] {àŽàŽ€àµàŽµàŽ¿àŽ§àŽ€àµàŽ€àŽ¿àŽ²àµàŽ³àµàŽ³àŽ€àŽŸàŽ£àµâ àŽàŽªàµàŽ°àŽ¶àµâàŽšàŽ?}  
+_textseverity_ [l=ml] {àŽàŽ€àµ àŽµàŽ³àŽ°àµ àŽ®àµàŽ¶àŽ®àŽŸàŽ¯ àŽªàµàŽ°àŽ¶àµâàŽšàŽ®àŽŸàŽ£àµ}  
+ 
+_textbadrender_ [l=ml] {àŽªàµàŽàµâ àŽµàŽ¿àŽàŽ¿àŽ€àµàŽ°àŽ®àŽŸàŽ¯àŽ¿ àŽ€àµàŽšàµàŽšàµàŽšàµàŽšàµ}  
+_textcontenterror_ [l=ml] {àŽàŽ³àµàŽ³àŽàŽàµàŽàŽ€àµàŽ€àŽ¿àŽ²àµ àŽªàŽ¿àŽ¶àŽàµâ}  
+_textstrangebehaviour_ [l=ml] {àŽµàŽ¿àŽàŽ¿àŽ€àµàŽ°àŽ®àŽŸàŽ¯ àŽªàµàŽ°àµàŽ®àŽŸàŽ±àµàŽ±àŽ}  
+_textunexpected_ [l=ml] {àŽàŽšàµàŽ€àµ àŽ
+àŽªàµàŽ°àŽ€àµàŽàµàŽ·àŽ¿àŽ€àŽ®àŽŸàŽ¯àŽ€àµâ àŽžàŽàŽ­àŽµàŽ¿àŽàµàŽàµ}  
+_textfunctionality_ [l=ml] {àŽàŽªàŽ¯àµàŽàŽ àŽµàŽ¿àŽ·àŽ®àŽàŽ°àŽ}  
+_textother_ [l=ml] {àŽ®àŽ±àµàŽ±àµàŽ³àµàŽ³àŽ€àµâ}  
+
+_textcritical_ [l=ml] {àŽšàŽ¿àŽ°àµâàŽ£àŽŸàŽ¯àŽàŽ®àŽŸàŽ¯}  
+_textmajor_ [l=ml] {àŽàµàŽ°àŽµàŽ®àŽŸàŽ¯ }  
+_textmedium_ [l=ml] {àŽ®àŽŸàŽ§àµàŽ¯àŽ®àŽ}  
+_textminor_ [l=ml] {àŽàµàŽ±àŽ¿àŽ¯}  
+_texttrivial_ [l=ml] {àŽšàŽ¿àŽžàµàŽžàŽŸàŽ°àŽ}  
+
+_textwhatdoing_ [l=ml] {àŽàŽšàµàŽ€àŽŸàŽ¯àŽ¿àŽ°àµàŽšàµàŽšàµ àŽ€àŽŸàŽàµàŽàŽ³àµâ àŽàµàŽ¯àµàŽ¯àŽŸàŽšàµâ àŽ¶àµàŽ°àŽ®àŽ¿àŽàµàŽàŽ€àµâ?}  
+_textwhatexpected_ [l=ml] {àŽàŽšàµàŽ€àµ àŽžàŽàŽ­àŽµàŽ¿àŽàµàŽàµàŽ®àµàŽšàµàŽšàŽŸàŽ¯àŽ¿àŽ°àµàŽšàµàŽšàµ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽªàµàŽ°àŽ€àµàŽàµàŽ·?}  
+_textwhathappened_ [l=ml] {àŽ¯àŽ¥àŽŸàŽ°àµâàŽ€àµàŽ¥àŽ€àµàŽ€àŽ¿àŽ²àµâ àŽàŽšàµàŽ€àŽŸàŽ£àµâ àŽžàŽàŽ­àŽµàŽ¿àŽàµàŽàŽ€àµâ?}  
+
+_cannotfindcgierror_ [l=ml] {<h2>Sorry!</h2>Can\\'t àŽ¬àŽàµàŽàŽ£àµàŽµàµàŽ£àµàŽàŽ¿àŽ¯àµàŽ³àµàŽ³ àŽžàµàŽ°àµâàŽµàŽ°àµâ _linktextusab_ àŽªàµàŽ°àµàŽŸàŽàµàŽ°àŽŸàŽ àŽàŽŸàŽ£àŽŸàŽšàŽ¿àŽ²àµàŽ²àµâ}  
+
+_textusabbanner_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµâ àŽ¬àŽŸàŽšàŽ°àµâ}  
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=ml] {àŽàŽ°àµ àŽ€àµàŽ±àµàŽ±àµàŽžàŽàŽ­àŽµàŽ¿àŽàµàŽàµ}  
+
+_textgtihome_ [l=ml] {<ul>àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµàŽ±àµ àŽ¬àŽ¹àµàŽ­àŽŸàŽ·àŽŸ àŽžàŽªàµàŽªàµàŽ°àµàŽàµàŽàµ àŽ®àµàŽàµàŽàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽŸàŽšàµ àŽ àŽªàµàŽàµàŽàŽ³àµ àŽž àŽ¹àŽŸàŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ.<ul> 
+  <li>àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµàŽ±àµ àŽ­àŽŸàŽàŽàµàŽàŽ³àµ àŽàŽ°àµ àŽªàµàŽ€àŽ¿àŽ¯ àŽ­àŽŸàŽ·àŽ¯àŽ¿àŽ²àµàŽàµàŽàµ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽŸàŽ 
+  <li>àŽàŽàŽàµàŽ²àµàŽ·àµ àŽ­àŽŸàŽ·àŽŸ àŽàŽšàµàŽ±àŽ°àµàŽ«àµàŽ¯àµàŽžàŽ¿àŽ²àµ àŽ®àŽŸàŽ±àµàŽ±àŽ àŽµàŽ°àµàŽ€àµàŽ€àµàŽ®àµàŽªàµàŽ³àµ àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽ­àŽŸàŽ·àµàŽŸ àŽàŽšàµàŽ±àŽ°àµàŽ«àµàŽ¯àµàŽžàµ àŽªàµàŽ€àµàŽàµàŽàŽŸàŽ 
+   <li>àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽàŽ³àŽ¿àŽ²àµ àŽ€àµàŽ±àµàŽ±àµàŽàŽ³àµ àŽ€àŽ¿àŽ°àµàŽ€àµàŽ€àŽŸàŽ </ul> 
+<p>àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ£àµàŽàµ àŽ¹àµàŽ°àŽžàµàŽµàŽµàŽŸàŽàŽàŽàµàŽàŽ³àµàŽ³àµàŽ³ àŽàŽ°àµ àŽàµàŽàµàŽàŽ àŽªàµàŽàµàŽàŽ³àµ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµ àŽ®àµàŽšàµàŽšàŽ¿àŽ²àµ àŽªàµàŽ°àŽŠàŽ°àµàŽ¶àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽ. àŽ
+àŽµ àŽàŽšàµàŽšàµàŽšàµàŽšàŽŸàŽ¯àŽ¿ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽ¿ àŽ®àµàŽšàµàŽšàµàŽàµàŽàµàŽªàµàŽµàµàŽ. àŽàŽ¿àŽ² àŽ¹àµàŽ°àŽžàµàŽµàŽµàŽŸàŽàŽàŽàµàŽàŽ³àŽ¿àŽ²àµ àŽàŽàµàŽàµ.àŽàŽ¿.àŽàŽ.àŽàŽ²àµ àŽ«àµàŽ°àµàŽ®àŽŸàŽ±àµàŽ±àŽ¿àŽàŽàµ àŽàŽ®àŽŸàŽšàµàŽ±àµàŽ àŽàŽ£àµàŽàŽŸàŽµàµàŽ. àŽ
+àŽµ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ£àµàŽàŽ€àŽ¿àŽ²àµàŽ². àŽªàŽàŽ°àŽ àŽ
+àŽµ àŽ
+àŽ€àµàŽªàŽàŽ¿ àŽšàŽ¿àŽ²àŽšàŽ¿àŽ°àµàŽ€àµàŽ€àµàŽ. àŽàŽàŽ€àµàŽ€àµàŽ àŽµàŽ²àŽ€àµàŽ€àµàŽ _ àŽ
+àŽàŽ¯àŽŸàŽ³àŽµàµàŽ®àŽŸàŽ¯àŽ¿ àŽšàŽ¿àŽ²àµàŽàµàŽàµàŽšàµàŽš àŽµàŽŸàŽàµàŽàµàŽàŽ³àµ àŽµàŽ¿àŽµàŽ°àµàŽ€àµàŽ€àŽšàŽ àŽàµàŽ¯àµàŽ¯àŽªàµàŽªàµàŽàŽŸàŽšàµàŽ³àµàŽ³àŽ€àŽ²àµàŽ². àŽ
+àŽµ àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµàŽ±àµ àŽ®àŽŸàŽàµàŽ°àµàŽŸ àŽ«àŽ¯àŽ²àµàŽàŽ³àŽŸàŽ£àµ. 
+<p>àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽàŽ°àµ àŽ­àŽŸàŽ·àŽŸ àŽàŽšàµàŽ±àŽ°àµàŽ«àµàŽ¯àµàŽžàŽŸàŽ£àµ àŽ€àŽŸàŽàµàŽàŽ³àµ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽšàµàŽšàŽ€àµàŽàµàŽàŽ¿àŽ²àµ àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽàŽ³àµ àŽ€àŽŸàŽàµàŽàŽ³àµàŽàµàŽàµàŽ®àµàŽšàµàŽšàŽ¿àŽ²àµ àŽªàµàŽ°àŽŠàŽ°àµàŽ¶àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽªàµàŽªàµàŽàµàŽàµàŽµàµàŽšàµàŽšàµàŽµàŽ°àŽ¿àŽ²àµàŽ². àŽ
+àŽªàµàŽªàµ àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµàŽ³àµàŽ³ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ· àŽ€àŽšàµàŽšàµ  àŽžàµàŽµàµàŽàŽ°àŽ¿àŽàµàŽàµàŽàŽ¯àŽŸàŽµàŽŸàŽ. 
+ 
+<p>àŽ®àµàŽªàµ àŽ
+àŽªàµàŽ¡àµàŽ¯àµàŽ±àµàŽ±àµ àŽàµàŽ¯àµàŽ€ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àµ àŽ€àŽ¿àŽ°àµàŽ€àµàŽ€àµàŽµàŽŸàŽšàŽŸàŽ£àµàŽàµàŽ¹àŽ¿ "Correct existing translations" àŽžàµàŽàŽ°àµàŽ¯àŽ àŽàŽªàµàŽ¯àµàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽ. 
+ 
+<p> àŽàŽ²àµàŽ²àŽŸ àŽªàµàŽàµàŽàŽ³àµàŽ àŽàŽµàŽžàŽŸàŽšàŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àµ "_textgtisubmit_" àŽ¬àŽàµàŽàŽ£àŽ¿àŽ²àŽŸàŽ£àµ.  
+"_textgtisubmit_" àŽ¬àŽàµàŽàŽ£àŽ¿àŽ²àŽŸàŽ£àµ àŽàŽ²àµàŽ²àŽŸ àŽªàµàŽàµàŽàŽ³àµàŽ àŽ
+àŽµàŽžàŽŸàŽšàŽ¿àŽàµàŽàµàŽ. àŽ
+àŽ€àµ àŽ
+àŽ®àŽ°àµàŽ€àµàŽ€àŽªàµàŽªàµàŽàµàŽ®àµàŽªàµàŽ³àµ nzdl.org àŽ²àµ àŽàµàŽ°àµàŽšàµàŽžàµàŽ±àµàŽ±àµàŽ£àµ àŽàŽšàµàŽžàµàŽ±àµàŽ±àŽŸàŽ³àµàŽ·àŽšàŽ¿àŽ²àµ àŽ®àŽŸàŽ±àµàŽ±àŽ àŽµàŽ°àµàŽ€àµàŽ€àŽªàµàŽªàµàŽàµàŽšàµàŽšàµ. àŽ àŽžàµàŽ±àµàŽ±àŽ¿àŽ²àµàŽ¯àµàŽàµàŽàµ àŽªàµàŽ°àŽµàµàŽ¶àŽ¿àŽàµàŽàŽŸàŽšàŽŸàŽ¯àŽ¿ àŽàŽ²àµàŽ²àŽŸ àŽªàµàŽàµàŽàŽ³àŽ¿àŽ²àµàŽ àŽàŽ°àµ àŽ¬àŽàµàŽàŽ£àµ àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽàµàŽàŽ¿àŽ¯àŽ¿àŽàµàŽàµàŽ£àµàŽàµ. }  
+
+_textgtiselecttlc_ [l=ml] {àŽ­àŽŸàŽ· àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽàµàŽàµàŽ}  
+
+#for status page
+_textgtiviewstatus_ [l=ml] {àŽàŽ²àµàŽ²àŽŸ àŽ­àŽŸàŽ·àŽàŽ³àŽ¿àŽ²àµàŽ¯àµàŽ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽàŽ³àµàŽàµ àŽšàŽ¿àŽàŽžàµàŽ¥àŽ¿àŽ€àŽ¿ àŽ
+àŽ±àŽ¿àŽ¯àµàŽµàŽŸàŽšàµâ àŽ
+àŽ®àŽ°àµâàŽ€àµàŽ€àµàŽ}  
+_textgtiviewstatusbutton_ [l=ml] {àŽžàµàŽ¥àŽ¿àŽ€àŽ¿ àŽ
+àŽ±àŽ¿àŽ¯àµàŽ}  
+_textgtistatustable_ [l=ml] {àŽàŽ²àµàŽ²àŽŸ àŽ­àŽŸàŽ·àŽàŽ³àŽ¿àŽ²àµàŽ¯àµàŽ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽàŽ³àµàŽàµ àŽµàŽ°àµâàŽ€àµàŽ€àŽ®àŽŸàŽš àŽžàµàŽ¥àŽ¿àŽ€àŽ¿}  
+_textgtilanguage_ [l=ml] {àŽ­àŽŸàŽ·}  
+_textgtitotalnumberoftranslations_ [l=ml] {àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽàŽ³àµàŽàµ àŽàŽ£àµàŽ£àŽ}  
+
+_textgtiselecttfk_ [l=ml] {àŽàµàŽ²àŽ¿àŽ€àµàŽàŽàµàŽàŽŸàŽšàŽŸàŽ¯àŽ¿ àŽàŽ°àµ àŽ«àŽ¯àŽ²àµâ àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽàµàŽàµàŽ}  
+
+_textgticoredm_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµâ àŽàŽšàµàŽ±àŽ°àµâàŽ«àµàŽ¯àµâàŽžàµâ (àŽ®àµàŽàµàŽ¯àŽ)}  
+_textgtiauxdm_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµâ àŽàŽšàµàŽ±àŽ°àµâàŽ«àµàŽ¯àµâàŽžàµâ (àŽ
+àŽšàµàŽ¬àŽšàµàŽ§àŽ)}  
+_textgtiglidict_ [l=ml] {àŽàŽ¿.àŽàŽ²àµâ.àŽ àŽ¡àŽ¿àŽàµàŽ·àµâàŽ£àŽ±àŽ¿}  
+_textgtiglihelp_ [l=ml] {àŽàŽ¿.àŽàŽ²àµâ.àŽ àŽžàŽ¹àŽŸàŽ¯àŽ}  
+_textgtiperlmodules_ [l=ml] {àŽªàµàŽ³àµâ àŽ®àµàŽ¡àµàŽ¯àµàŽ³àµàŽàŽ³àµâ}  
+_textgtitutorials_ [l=ml] {àŽàµàŽ¯àµàŽàµàŽàµàŽ±àŽ¿àŽ¯àŽ²àµâ àŽàŽàµâàŽžàŽ°àµâàŽžàµàŽžàŽžàµâ}  
+_textgtigreenorg_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµââ.àŽ.àŽàŽ°àµâ.àŽàŽ¿}  
+
+
+#for greenstone manuals
+_textgtidevmanual_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àµâ àŽµàŽ¿àŽàŽžàŽš àŽžàŽ¹àŽŸàŽ¯àŽ¿}  
+_textgtiinstallmanual_ [l=ml] {âàŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽžàµàŽ¥àŽŸàŽªàŽš àŽžàŽ¹àŽŸàŽ¯àŽ¿}  
+_textgtipapermanual_ [l=ml] {âàŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽ®àŽŸàŽšàµàŽµàŽ²àµâ àŽ«àµàŽ°àµâ àŽªàµàŽªàµàŽªàŽ°àµâ àŽ±àµàŽ±àµ àŽàŽ³àŽàµàŽ·àŽšàµâ}  
+_textgtiusermanual_ [l=ml] {âàŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽàŽªàŽ¯àµàŽàµàŽ€àµàŽžàŽ¹àŽŸàŽ¯àŽ¿}  
+
+_textgtienter_ [l=ml] {àŽªàµàŽ°àŽµàµàŽ¶àŽ¿àŽàµàŽàµàŽ}  
+
+_textgticorrectexistingtranslations_ [l=ml] {àŽšàŽ¿àŽ²àŽµàŽ¿àŽ²àµ àŽ®àµàŽŽàŽ¿àŽ®àŽŸàŽ±àµàŽ±àŽ àŽ€àŽ¿àŽ°àµàŽ€àµàŽ€àµàŽ}  
+_textgtidownloadtargetfile_ [l=ml] {àŽ«àŽ¯àŽ²àµâ àŽ¡àµàŽ£àµâàŽ²àµàŽ¡àµâ àŽàµàŽ¯àµàŽ¯àµàŽ}  
+_textgtiviewtargetfileinaction_ [l=ml] {àŽªàµàŽ°àŽµàŽ°àµâàŽ€àµàŽ€àŽšàŽšàŽ¿àŽ°àŽ€àŽ®àŽŸàŽµàµàŽšàµàŽš àŽ«àŽ¯àŽ²àµâ àŽàŽŸàŽ£àµàŽ}  
+_textgtitranslatefileoffline_ [l=ml] {àŽ àŽ«àŽ¯àŽ²àµâ àŽàŽ£àŽàµàŽ·àŽšàµâ àŽµàŽ¿àŽàµàŽàµàŽŠàŽ¿àŽàµàŽàŽ¶àµàŽ·àŽ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ}  
+
+_textgtinumchunksmatchingquery_ [l=ml] {àŽ
+àŽšàµàŽµàµàŽ·àŽ£àŽàµàŽàŽ³àµâàŽàµàŽàµâ àŽ
+àŽšàµàŽ¯àµàŽàµàŽ¯àŽ®àŽŸàŽ¯ àŽàµàŽàµâàŽžàµâàŽ±àµàŽ±àµâ àŽ­àŽŸàŽàŽàµàŽàŽ³àµàŽàµ àŽàŽ£àµàŽ£àŽ}  
+
+_textgtinumchunkstranslated_ [l=ml] {àŽàµàŽ¯àµâàŽ€ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽàŽ³àµâ}  
+_textgtinumchunksrequiringupdating_ [l=ml] {àŽàŽµàŽ¯àŽ¿àŽ²àµâ _1_ àŽšàµâ àŽªàµàŽ€àµàŽàµàŽàŽ²àµâ àŽàŽµàŽ¶àµàŽ¯àŽ®àŽŸàŽ£àµâ}  
+_textgtinumchunksrequiringtranslation_ [l=ml] {àŽ¶àµàŽ·àŽ¿àŽàµàŽàµàŽšàµàŽš àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽàŽ³àµâ}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=ml] {àŽàµàŽ¯àµâàŽ€ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽàŽ³àµàŽàµ àŽàŽ£àµàŽ£àŽ}  
+_textgtinumchunksrequiringupdating2_ [l=ml] {àŽªàµàŽ€àµàŽàµàŽàŽ²àµâ àŽàŽµàŽ¶àµàŽ¯àŽ®àŽŸàŽ¯ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽàŽ³àµàŽàµ àŽàŽ£àµàŽ£àŽ}  
+_textgtinumchunksrequiringtranslation2_ [l=ml] {àŽ¶àµàŽ·àŽ¿àŽàµàŽàµàŽšàµàŽš àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽàŽ³àµàŽàµ àŽàŽ£àµàŽ£àŽ}  
+
+_textgtienterquery_ [l=ml] {àŽ€àµàŽ±àµàŽ±àµàŽ€àŽ¿àŽ°àµàŽ€àµàŽ€àµàŽµàŽŸàŽšàŽŸàŽàµàŽ°àŽ¹àŽ¿àŽàµàŽàµàŽšàµàŽš àŽµàŽŸàŽàµàŽàµ àŽàµàŽàµâàŽžàµâàŽ±àµàŽ±àŽ¿àŽšàµàŽ±àµ àŽ®àŽ±àµàŽ±àµ àŽ­àŽŸàŽàŽàµàŽàŽ³àµ àŽàŽµàŽ¿àŽàµ àŽ°àµàŽàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ}  
+_textgtifind_ [l=ml] {àŽàŽ£àµàŽàµàŽ€àµàŽ€àµàŽ}  
+
+_textgtitranslatingchunk_ [l=ml] {àŽàµàŽàµâàŽžàµàŽ±àµàŽ±àŽ¿àŽšàµàŽ±àµ àŽ­àŽŸàŽàŽàµàŽàŽ³àµâ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ<i>_1_</i>}  
+_textgtiupdatingchunk_ [l=ml] {àŽàµàŽàµâàŽžàµâàŽ±àµàŽ±àŽ¿àŽšàµàŽ±àµ àŽ­àŽŸàŽàŽàµàŽàŽ³àµâ àŽªàµàŽ€àµàŽàµàŽàµàŽšàµàŽš <i>_1_</i>}  
+_textgtisubmit_ [l=ml] {àŽžàŽ®àŽ°àµâàŽªàµàŽªàŽ¿àŽàµàŽàµàŽ}  
+
+_textgtilastupdated_ [l=ml] {àŽ
+àŽµàŽžàŽŸàŽšàŽ àŽªàµàŽ€àµàŽàµàŽàŽ¿àŽ¯àŽ€àµâ}  
+
+_textgtitranslationfilecomplete_ [l=ml] {àŽ àŽ«àŽ¯àŽ²àµâ -- àŽªàµàŽ€àŽ¿àŽàµàŽàŽ¿àŽ¯àŽ€àŽ¿àŽšàµâ àŽšàŽšàµàŽŠàŽ¿. àŽàŽªàµàŽªàµàŽ³àµâ àŽàŽ€àµâ àŽªàµàŽ°àµâàŽ£àŽ®àŽŸàŽ£àµâ. <p>àŽ àŽ²àŽ¿àŽàµàŽàµâ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽàµàŽ£àµàŽàµâ àŽ«àŽ¯àŽ²àŽ¿àŽšàµàŽ±àµ àŽàŽ°àµ àŽàµàŽªàµàŽªàŽ¿ àŽ€àŽŸàŽàµàŽàŽ³àµâàŽàµàŽàµâ àŽ¡àµàŽ£àµâàŽ²àµàŽ¡àµâ àŽàµàŽ¯àµàŽ¯àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµâ}  
+
+_textgtiofflinetranslation_ [l=ml] {<ol>àŽ®àµàŽàµàŽ°àµàŽŸàŽžàµàŽ«àµàŽ±àµàŽ±àµ àŽàŽàµàŽžàŽ²àµ àŽžàµàŽªàµàŽ°àµàŽ¡àµàŽ·àµàŽ±àµàŽ±àµ àŽàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµàŽàµàŽ£àµàŽàµàµ àŽ àŽ­àŽŸàŽàŽ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽªàµàŽªàµàŽàµàŽ€àµàŽ€àŽŸàŽµàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ 
+<li>Download <a href="_gwcgi_?a=gti&p=excel&e=_compressedoptions_">this file</a>.àŽ àŽ«àŽ¯àŽ²àµ àŽ¡àµàŽ£àµàŽ²àµàŽ¡àµ àŽàµàŽ¯àµàŽ¯àµàŽ 
+<li>2003àŽ²àµàŽ¯àµ àŽ
+àŽ€àŽ¿àŽšàµàŽ¶àµàŽ·àŽ®àµàŽ³àµàŽ³àŽ€àµ àŽàŽ¯ àŽ®àµàŽàµàŽ°àµàŽŸàŽžàµàŽ«àµàŽ±àµàŽ±àµ àŽàŽàµàŽžàŽ²àµ àŽªàŽ€àŽ¿àŽªàµàŽªàµàŽàŽ³àµàŽªàŽ¯àµàŽàŽ¿àŽàµàŽàµ àŽµàŽ°àµàŽàµàŽ¬àµàŽàµ àŽ«àµàŽ°àµàŽ®àŽŸàŽ±àµàŽ±àŽ¿àŽ²àµ àŽ
+àŽ€àµ àŽžàŽàŽ°àŽàµàŽ·àŽ¿àŽàµàŽàµàŽ (àŽžàµàŽµàµ) 
+<li>àŽ²àŽ­àµàŽ¯àŽ®àŽŸàŽ¯ àŽàŽ³àµàŽ³àŽ¿àŽàŽ³àŽ¿àŽ²àµ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ· àŽ°àµàŽàŽªàµàŽªàµàŽàµàŽ€àµàŽ€àµàŽ 
+<li>àŽàŽ²àµàŽ²àŽŸ àŽªàŽ°àŽ¿àŽ­àŽŸàŽ·àŽàŽ³àµàŽ àŽªàµàŽ°àµàŽ€àµàŽ€àŽ¿àŽ¯àŽŸàŽàµàŽ®àµàŽªàµàŽ³àµ<a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>.àŽµàŽ¿àŽ²àŽŸàŽžàŽ€àµàŽ€àŽ¿àŽ²àµ àŽàŽ®àµàŽ¯àŽ¿àŽ²àŽŸàŽ¯àŽ¿ àŽ àŽ«àŽ¯àŽ²àµ àŽ
+àŽ¯àŽ¯àµàŽàµàŽàµàŽ 
+</ol>
+}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=ml] {àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµàŽ±àµ  àŽ²àµàŽ¬àµàŽ°àŽ±àŽ¿ àŽàŽšàµàŽ±àŽ°àµâàŽ«àµàŽ¯àµâàŽžàµâ}  
+_textglihelp_ [l=ml] {<p>àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµàŽ±àµ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽšàŽàµàŽàŽ³àµ àŽ
+àŽšàŽŸàŽ¯àŽŸàŽžàŽ àŽšàŽàŽ€àµàŽ€àŽŸàŽšàµ àŽžàŽ¹àŽŸàŽ¯àŽ¿àŽàµàŽàµàŽšàµàŽšàŽ€àŽŸàŽ£àµ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽ²àµàŽ¬àµàŽ°àµàŽ±àŽ¿àŽ¯àŽšàµ àŽàŽšàµàŽ±àŽ°àµàŽ«àµàŽ¯àµàŽžàµ. àŽªàµàŽ°àŽ®àŽŸàŽ£àŽ¶àµàŽàŽ°àŽ£àŽàµàŽàŽ³àµàŽàµàŽàµàŽ àŽ
+àŽµ àŽàŽ±àŽàµàŽàµàŽ®àŽ€àŽ¿ àŽàµàŽ¯àµàŽ¯àŽŸàŽšàµàŽ àŽ®àµàŽ±àµàŽ±àŽŸàŽ¡àµàŽ±àµàŽ± àŽšàŽ²àµàŽàŽŸàŽšàµàŽ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽ¶àµàŽàŽ°àŽšàŽ¿àŽ°àµàŽ®àµàŽ®àŽ¿àŽ€àŽ¿àŽàµàŽàµàŽ àŽàŽµàŽ¿àŽàµ àŽžàµàŽàŽ°àµàŽ¯àŽ®àµàŽ£àµàŽàµ. 
+ 
+<p>àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽžàµàŽ¥àŽŸàŽªàŽšàŽàŽàµàŽàŽ€àµàŽ€àŽ¿àŽ²àµ àŽ
+àŽ€àŽ¿àŽ²àµ àŽàŽ°àµ àŽžàŽ¬àµàŽ¡àŽ¯àŽ±àŽàµàŽàŽ±àŽ¿àŽ¯àŽŸàŽ¯àŽ¿ àŽšàŽ¿àŽ²àŽšàŽ¿àŽšàµàŽšàµ àŽàŽ¿.àŽàŽ²àµ.àŽ àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµàŽ£àŽ¿àŽšàµàŽªàµàŽªàŽ àŽªàµàŽ°àŽµàŽ€àµàŽ€àŽ¿àŽàµàŽàµàŽšàµàŽšàµàŽµàµàŽšàµàŽšàµ àŽ
+àŽ±àŽ¿àŽ¯àµàŽ. àŽàµàŽ°àµàŽžàµàŽ±àµàŽ±àµ àŽžàŽ¿àŽ¡àŽ¿ àŽ±àµàŽ®àŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàµàŽ àŽàŽàµàŽ€àµàŽ€àŽ€àŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµàŽ àŽžàµàŽ±àµàŽ±àŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàµàŽ àŽ¡àµàŽ£àµàŽ²àµàŽ¡àµ àŽàµàŽ¯àµàŽ€àŽ€àŽŸàŽ£àµàŽàµàŽàŽ¿àŽ²àµàŽ àŽàŽ€àµ àŽ¬àŽŸàŽ§àŽàŽ®àŽŸàŽ£àµ.</p> 
+ 
+<h4>àŽàŽ¿.àŽàŽ²àµ.àŽ àŽµàŽ¿àŽšàµàŽ¡àµàŽžàŽ¿àŽ²àµ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽŸàŽšàŽŸàŽ¯àŽ¿</h4> 
+ 
+<i>Programs</i> section of the <i>Start</i> àŽ®àŽ¿àŽ²àµ àŽšàŽ¿àŽšàµàŽšàµàŽ <i>Librarian Interface</i>àŽ€àŽ¿àŽ°àŽàµàŽàµàŽàµàŽ€àµàŽ€àµàŽàµàŽ£àµàŽàµàµ àŽàŽ¿.àŽàŽ²àµ.àŽ àŽµàŽ¿àŽšàµàŽ¡àµàŽžàŽ¿àŽ²àµ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽ 
+ 
+<h4>àŽàŽ¿.àŽàŽ²àµ.àŽ Unix</h4>àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽŸàŽšàŽŸàŽ¯àŽ¿.................. 
+ 
+àŽ¯àµàŽ£àŽ¿àŽàµàŽžàŽ¿àŽ²àµ àŽàŽ¿.àŽàŽ²àµ.àŽ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàŽŸàŽšàµ <i>gli</i> àŽ¡àŽ¯àŽ±àŽàµàŽàŽ±àŽ¿àŽ¯àŽ¿àŽ²àµàŽàµàŽàµ àŽ®àŽŸàŽ±àŽ¿àŽ¯àŽ¶àµàŽ·àŽ <i>gli.sh</i> àŽàŽšàµàŽ±àŽ°àµàŽ«àµàŽ¯àµàŽžàµ àŽªàµàŽ°àŽµàŽ°àµàŽ€àµàŽ€àŽ¿àŽªàµàŽªàŽ¿àŽàµàŽàµàŽ 
+ 
+<h4>àŽàŽ¿.àŽàŽ²àµ.àŽ  Mac OS X</h4> 
+  In the finder, browse to <i>Applications</i> then <i>Greenstone</i> (if you installed Greenstone into the default location), and then launch the <i>GLI</i> application.}  
Index: /gsdl/stable/macros/maori.dm
===================================================================
--- /gsdl/stable/macros/maori.dm	(revision 20131)
+++ /gsdl/stable/macros/maori.dm	(revision 20131)
@@ -0,0 +1,841 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Maori Language text and icon macros 
+# Many thanks to Te Taka Keegan (translated May 2004)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=mi] {TÄnga Pukapuka}
+_textsource_ [l=mi] {tohutoro pÅ«take:}
+_textdate_ [l=mi] {rÄ tÄnga: }
+_textnumpages_ [l=mi] {e hia ngÄ whÄrangi:}
+
+_textsignin_ [l=mi] {whakauru mai}
+
+_textdefaultcontent_ [l=mi] {KÄore tÅ whÄrangi tono i kitea. PÄwhiritia te pÄtene 'back' i tÅ pÅ«manawa tirotiro, pÄwhiritia rÄnei te pÄtene kÄinga o runga ake kia hoki atu ai ki te
+Greenstone Digital Library.}
+
+_textdefaulttitle_ [l=mi] {He hÄ GSDL}
+
+_textbadcollection_ [l=mi] {KÄore te kohikohinga (called "_cvariable_") e noho mai ana i tÄnei pÅ«naha o Greenstone.}
+
+_textselectpage_ [l=mi] {âKÅwhirihia he WhÄrangiâ}
+
+_collectionextra_ [l=mi] {E _about:numdocs_ ngÄ  tuhinga kei tÄnei kohikohinga.
+He mea hanga _about:builddate_ ngÄ rÄ i mua.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=mi] {<p>Kei tÄnei kohikohinga _numdocs_ _If_("_numdocs_" eq "1",te tuhinga,ngÄ tuhinga), Ä, ko te rahi  _numbytes_ ngÄ bytes.
+<p><a href="_httppagex_(bsummary)">PÄwhiritia tÄnei</a> kia panui ai te pÅ«rongo hanga o tÄnei kohikohinga.
+}
+
+_textdescrcollection_ [l=mi] {}
+_textdescrabout_ [l=mi] {WhÄrangi whakamÄrama}
+_textdescrhome_ [l=mi] {WhÄrangi kÄinga}
+_textdescrhelp_ [l=mi] {WhÄrangi Äwhina}
+_textdescrpref_ [l=mi] {Te whÄrangi o ngÄ kÅwhiringa}
+_textdescrgreenstone_ [l=mi] {Greenstone Digital Library Software}
+_textdescrusab_ [l=mi] {He aha ngÄ mea uaua hei whakamahi?}
+
+_textdescrSearch_ [l=mi] {rapua he kupu}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=mi] {Tirotiro pÅ«rÄrangi taitara}
+_textdescrCreator_ [l=mi] {Tirotiro pÅ«rÄrangi kaitito}
+_textdescrSubject_ [l=mi] {Tirotiro kaupapa}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=mi] {Tirotiro whakarÄrangi wÄtaka}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+_textdescrSource_ [l=mi] {Tirotiro ingoa kÅnae taketake}
+_textdescrLanguage_ [l=mi] {Tirotiro reo}
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=mi] {Tirotiro rÅpÅ«}
+_textdescrKeyword_ [l=mi] {Tirotiro kupu matua}
+_textdescrHowto_ [l=mi] {Tirotiro Äpure PÄwhea Te}
+_textdescrList_ [l=mi] {Tirotiro whakarÄrangi tuhinga}
+_textdescrSeries_ [l=mi] {Tirotiro tÄnga pukapuka}
+_textdescrTo_ [l=mi] {Tirotiro Äpure Ki a Wai}
+_textdescrFrom_ [l=mi] {Tirotiro Äpure NÄ Wai}
+_textdescrTopic_ [l=mi] {Tirotiro kaupapa motuhake}
+_textdescrBrowse_ [l=mi] {Tirotiro}
+_textdescrCollage_ [l=mi] {Tirotiro kÄpunupuni whakaahua}
+_textdescrPeople_ [l=mi] {Tirotiro pÅ«rÄrangi tÄngata}
+_textdescrAcronym_ [l=mi] {Tirotiro PÅ«tauÄkÄ«}
+_textdescrPhrase_ [l=mi] {Tirotiro kÄ«waha}
+_textdescrArtist_ [l=mi] {Tirotiro kaitito}
+_textdescrVolume_ [l=mi] {Tirotiro pukapuka}
+_textdescrCountries_ [l=mi] {Tirotiro whenua}
+_textdescrCaptions_ [l=mi] {Tirotiro whakaahua rerekÅrero}
+
+
+_labelSearch_ [l=mi] {Rapu}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=mi] {Taitara A-Z}
+_labelCreator_ [l=mi] {Kaitito A-Z}
+_labelSubject_ [l=mi] {Kaupapa}
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=mi] {NgÄ RÄ}
+# -- Missing translation: _labelType_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+_labelSource_ [l=mi] {Ingoa KÅnae}
+_labelLanguage_ [l=mi] {Reo}
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=mi] {RÅpÅ«}
+_labelKeyword_ [l=mi] {Kupu Matua}
+_labelHow_ [l=mi] {PÄwhea te}
+_labelSeries_ [l=mi] {TÄnga Pukapuka}
+_labelList_ [l=mi] {WhakarÄrangi}
+_labelTo_ [l=mi] {Ki a Wai}
+_labelFrom_ [l=mi] {NÄ Wai}
+_labelTopic_ [l=mi] {Kaupapa}
+_labelBrwse_ [l=mi] {Tirotiro}
+_labelCollage_ [l=mi] {KÄpunipuni Whakaahua}
+_labelBrows_ [l=mi] {Tirotiro}
+_labelPeople_ [l=mi] {TÄngata A-Z}
+_labelAcronym_ [l=mi] {PÅ«tauÄkÄ«}
+_labelPhrase_ [l=mi] {KÄ«waha}
+_labelArtist_ [l=mi] {Kaitito}
+_labelVolume_ [l=mi] {Pukapuka}
+_labelCaptions_ [l=mi] {RerekÅrero}
+_labelCountries_ [l=mi] {Whenua}
+
+_texticontext_ [l=mi] {Tirohia te tuhinga}
+_texticonclosedbook_ [l=mi] {whakatÅ«wheratia te tuhinga nei kia pÄnui ai ngÄ kÅrero}
+_texticonnext_ [l=mi] {titiro ki te whÄrangi o muri}
+_texticonprev_ [l=mi] {titiro ki te whÄrangi o mua}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=mi] {titiro ki te kÅnae MIDI}
+_texticonmsword_ [l=mi] {titiro ki te tuhinga Microsoft Word}
+_texticonmp3_ [l=mi] {titiro ki te kÅnae MP3}
+_texticonpdf_ [l=mi] {titiro ki te tuhinga PDF}
+_texticonps_ [l=mi] {titiro ki te tuhinga Postscript}
+_texticonppt_ [l=mi] {titiro ki te tuhinga PowerPoint}
+_texticonrtf_ [l=mi] {titiro ki te tuhinga RTF}
+_texticonxls_ [l=mi] {Tirohia te kÅnae Microsoft Excel}
+
+_page_ [l=mi] {whÄrangi }
+_pages_ [l=mi] {ngÄ whÄrangi}
+_of_ [l=mi] {i te }
+_vol_ [l=mi] {Pukapuka}
+_num_ [l=mi] {Nama}
+
+_textmonth00_ [l=mi] {}
+_textmonth01_ [l=mi] {Kohi-tÄtea}
+_textmonth02_ [l=mi] {Hui-tanguru}
+_textmonth03_ [l=mi] {PoutÅ«-te-rangi}
+_textmonth04_ [l=mi] {Paenga-whÄehÄ}
+_textmonth05_ [l=mi] {Haratua}
+_textmonth06_ [l=mi] {Pipiri}
+_textmonth07_ [l=mi] {HÅngongoi}
+_textmonth08_ [l=mi] {Here-turi-kÅkÄ}
+_textmonth09_ [l=mi] {Mahuru}
+_textmonth10_ [l=mi] {Whiringa-Ä-nuku}
+_textmonth11_ [l=mi] {Whiringa-Ä-rangi}
+_textmonth12_ [l=mi] {Hakihea}
+
+_textdocument_ [l=mi] {Tuhinga}
+_textsection_ [l=mi] {WÄhanga}
+_textparagraph_ [l=mi] {KÅwae}
+
+_magazines_ [l=mi] {Pukapuka}
+
+_nzdlpagefooter_ [l=mi] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Tari Rorohiko</a>, 
+<a href="http://www.waikato.ac.nz">Te Whare WÄnanga o Waikato</a>, 
+Aotearoa}
+
+_linktextHOME_ [l=mi] {KÄINGA}
+_linktextHELP_ [l=mi] {ÄWHINA}
+_linktextPREFERENCES_ [l=mi] {KÅWHIRINGA}
+
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=mi] {He kupu whakamÄrama i te kohikohinga nei}
+
+_textsubcols1_ [l=mi] {<p>Kei te kohinga-whÄnui nei e  _1_ ngÄ kohinga-whÄiti. 
+Ko ngÄ kohinga-whÄiti e wÄtea ana mÄu:
+<blockquote>}
+
+_textsubcols2_ [l=mi] {</blockquote>
+Kei te WhÄrangi Whiringa e taea ana e koe te whakarite ko Äwhea ngÄ kohinga-whÄiti mÄu.}
+
+
+_titleabout_ [l=mi] {e pÄ ana}
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+
+_texticonopenbookshelf_ [l=mi] {kÄtia tÄnei wÄhanga}
+_texticonclosedbookshelf_ [l=mi] {whakatÅ«whera mai tÄnei wÄhanga hei tirotiro ai}
+_texticonopenbook_ [l=mi] {kÄtia tÄnei pukapuka}
+_texticonclosedfolder_ [l=mi] {whakatÅ«whera mai tÄnei kÅpaki hei tirotiro ai}
+_texticonclosedfolder2_ [l=mi] {whakatÅ«whera mai te wÄhanga iti nei}
+_texticonopenfolder_ [l=mi] {katia tÄnei kÅpaki}
+_texticonopenfolder2_ [l=mi] {katia tÄnei wÄhanga-iti}
+_texticonsmalltext_ [l=mi] {Tirohia tÄnei wÄhanga o ngÄ kupu tuhituhi}
+_texticonsmalltext2_ [l=mi] {tirohia kupu tuhituhi}
+_texticonpointer_ [l=mi] {wÄhanga e tiro ana}
+_texticondetach_ [l=mi] {Huakina mai he matapihi hou kia noho motuhake ai tÄnei kÅrero}
+_texticonhighlight_ [l=mi] {Kia pÅ«kaha ngÄ kupu rapu}
+_texticonnohighlight_ [l=mi] {Kia kore-pÅ«kaha ngÄ kupu rapu}
+_texticoncontracttoc_ [l=mi] {Whakaitihia te whakarÄrangi kaupapa}
+_texticonexpandtoc_ [l=mi] {Whakanuia te whakarÄrangi kaupapa}
+_texticonexpandtext_ [l=mi] {Titiro ki ngÄ kupu katoa}
+_texticoncontracttext_ [l=mi] {Titiro ki ngÄ kupu anakÄ o te wÄhanga kua kÅwhiritia}
+_texticonwarning_ [l=mi] {<b>Kia TÅ«pato: </b>}
+_texticoncont_ [l=mi] {haere tonu?}
+
+_textltwarning_ [l=mi] {<div class="buttons">_imagecont_</div>
+_iconwarning_Ki te whakanui koe i ngÄ kupu tuhituhi i konei ka nui rawa ngÄ kÅrero hei whakaatu mai ki runga i te mata o te rorohiko
+}
+
+_textgoto_ [l=mi] {poka noa ki}
+_textintro_ [l=mi] {<i>(kÅrero whakataki)</i>}
+
+_textCONTINUE_ [l=mi] {HAERE TONU??}
+
+_textEXPANDTEXT_ [l=mi] {WHAKANUI\nKUPU TUHITUHI}
+
+_textCONTRACTCONTENTS_ [l=mi] {WHAKAITI\nWHAKARÄRANGI\nKAUPAPA}
+
+_textDETACH_ [l=mi] {WHAKAWEHE}
+
+_textEXPANDCONTENTS_ [l=mi] {WHAKANUI\nWHAKARÄRANGI\nKAUPAPA}
+
+_textCONTRACT_ [l=mi] {WHAKAITI\nKUPU TUHITUHI}
+
+_textHIGHLIGHT_ [l=mi] {PÅªKAHA}
+
+_textNOHIGHLIGHT_ [l=mi] {KORE-PÅªKAHA}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=mi] {_If_(_thislast_,kitenga _thisfirst_ - _thislast_ mÅ te rapu: _cgiargq_,kÄore he kitenga mÅ: _cgiargq_)}
+_textnoquerytitle_ [l=mi] {WhÄrangi rapu}
+
+_textsome_ [l=mi] {Ätehi}
+_textall_ [l=mi] {te katoa}
+_textboolean_ [l=mi] {te boolean}
+_textranked_ [l=mi] {ranked}
+_textnatural_ [l=mi] {aunoa}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=mi] {hÄ«tori rapu}
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+_textusequery_ [l=mi] {whakamahia tÄnei rapunga}
+_textfreqmsg1_ [l=mi] {Kia hia ngÄ kupu: }
+_textpostprocess_ [l=mi] {_If_(_quotedquery_,<br><i>kua rapu tuaruatia kia puta ko te _quotedquery_</i>
+)}
+_textinvalidquery_ [l=mi] {kua hÄ te tuhi rapu}
+
+_textmorethan_ [l=mi] {Neke atu i te }
+_textapprox_ [l=mi] {E pÄ ana}
+_textnodocs_ [l=mi] {kÄore he kitenga e pÄ ana ki Äu kupu rapu.}
+_text1doc_ [l=mi] {1 te pukapuka e pÄ ana ki Äu kupu rapu.}
+_textlotsdocs_ [l=mi] {ngÄ pukapuka e pÄ ana ki Äu kupu rapu.}
+_textmatches_ [l=mi] {Kitenga }
+_textbeginsearch_ [l=mi] {Rapua}
+_textrunquery_ [l=mi] {Tukua te Rapu}
+_textclearform_ [l=mi] {Åªkui ngÄ kupu}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=mi] {he kupu, he kÄ«waha rÄnei}
+_textinfield_ [l=mi] {âŠ i te Äpure}
+_textfoldstem_ [l=mi] {(pÅ«matua/pÅ«titi, kÅ«muri)}
+
+_textadvquery_ [l=mi] {Me tuhi kau noa rÄnei i ngÄ kupu rapu:}
+_textallfields_ [l=mi] {ngÄ Äpure katoa}
+_texttextonly_ [l=mi] {kore-whakaahua}
+_textand_ [l=mi] {me te}
+_textor_ [l=mi] {rÄnei}
+_textandnot_ [l=mi] {me te kore}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=mi] {Tirohia ki _indexselection_ _If_(_jselection_, of _jselection_) _If_(_gselection_, at _gselection_ level)_If_(_nselection_, in _nselection_ language) mÅ _querytypeselection_ o ngÄ kupu}
+
+_textadvancedsearch_ [l=mi] {"Rapu _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,ki te _gselection_ level )_If_(_nselection_,in _nselection_ language )ki te _querytypeselection_ query}
+
+_textformsimplesearch_ [l=mi] {Rapu _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )mÅ _formquerytypesimpleselection_ i te}
+
+_textformadvancedsearch_ [l=mi] {Rapu_If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language ) whakaatu mai ngÄ kitenga ki _formquerytypeadvancedselection_ order}
+
+
+_textnojsformwarning_ [l=mi] {Warning: Javascript is disabled in your web browser. <br>To use form searching, please enable it.}
+_textdatesearch_ [l=mi] {Kei tÄnei kohikohinga e taea ana te rapu i ngÄ tuhinga i puta mai ai i tÄtehi wÄ,i tÄtehi rÄ rÄnei. He Ähuatanga tÄnei e taea ana te whakaÅ« ki te mahi rapu.}
+_textstartdate_ [l=mi] {RÄ (tÄ«mata):}
+_textenddate_ [l=mi] {RÄ mutunga}
+_textbc_ [l=mi] {B.C.E.}
+_textad_ [l=mi] {C.E.}
+_textexplaineras_ [l=mi] {E Årite ana te C.E. me te B.C.E ki te A.D. me te B.C. arÄ i mua, i muri rÄnei i te whÄnau mai o Ihu Karaiti. He pÅ«tauÄkÄ« mÅ te "Common Era" me te "Before the Common Era", Ä, he mea kore whakararu i tÄtehi hÄhi o te ao.}
+
+_textstemon_ [l=mi] {(hei aha te kÅ«muri)}
+
+_textsearchhistory_ [l=mi] {HÄ«tori Rapu}
+
+#text macros for search history
+_textnohistory_ [l=mi] {kÄore he hÄ«tori rapu}
+_texthresult_ [l=mi] {kitenga}
+_texthresults_ [l=mi] {ngÄ kitenga}
+_texthallwords_ [l=mi] {kupu katoa}
+_texthsomewords_ [l=mi] {Ätehi kupu}
+_texthboolean_ [l=mi] {boolean}
+_texthranked_ [l=mi] {ranked}
+_texthcaseon_ [l=mi] {kia tika ngÄ pÅ« matua me ngÄ pÅ« iti}
+_texthcaseoff_ [l=mi] {hei aha te pÅ«matua me te pÅ«iti}
+_texthstemon_ [l=mi] {hei aha te kÅ«muri}
+_texthstemoff_ [l=mi] {kia tika te kÅ«muri}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=mi] {Kua whakaÅ« ngÄ kÅwhiringa engari kaua kÄ e whakamahia te pÄtene
+"back" i tÅ pÅ«tirotiro (browser) - i te mea ka ngaro aua kÅwhiringa! Me pÄwhiri kÄtia tÄtehi pÄtene o runga ake nei.
+}
+_textsetprefs_ [l=mi] {whakamaua kÅwhiringa}
+_textsearchprefs_ [l=mi] {KÅwhiringa Rapu}
+_textcollectionprefs_ [l=mi] {KÅwhiringa kohikohinga}
+_textpresentationprefs_ [l=mi] {KÅwhiringa Whakaaturanga}
+_textpreferences_ [l=mi] {KÅwhiringa}
+_textcasediffs_ [l=mi] {PÅ« matua me te pÅ« iti:}
+_textignorecase_ [l=mi] {hei aha te pÅ« matua me te pÅ« iti}
+_textmatchcase_ [l=mi] {me tika te pÅ« matua me te pÅ« iti}
+_textwordends_ [l=mi] {KÅ«muri:}
+_textstem_ [l=mi] {hei aha te kÅ«muri}
+_textnostem_ [l=mi] {me tika te kÅ«muri}
+_textprefop_ [l=mi] {Whakahokia mai te _maxdocoption_ kupu, Ä, kia _hitsperpageoption_ kupu ki ia whÄrangi.}
+_textextlink_ [l=mi] {WhakapÄ atu ki ngÄ whÄrangi WWW:}
+_textintlink_ [l=mi] {Kua tikina ngÄ tuhinga mai i te:}
+_textlanguage_ [l=mi] {reo tauwhiti }
+_textencoding_ [l=mi] {Whakatakotoranga pÅ«: }
+_textformat_ [l=mi] {Whakatakotoranga tauwhiti: }
+_textall_ [l=mi] {katoa}
+_textquerymode_ [l=mi] {TÅ«momo rapu:}
+_textsimplemode_ [l=mi] {te rapu ngÄwari}
+_textadvancedmode_ [l=mi] {te rapu matatau (ka taea te whakamahi i ngÄ pÅ« boolean, 
+pÄrÄ i te '!', '&', '|', me te '()' hoki)}
+_textlinkinterm_ [l=mi] {mÄ tÄtehi whÄrangi takawaenga}
+_textlinkdirect_ [l=mi] {haere tÅtika ki reira}
+_textdigitlib_ [l=mi] {te whare pukapuka hiko}
+_textweb_ [l=mi] {te web}
+_textgraphical_ [l=mi] {Whakaahua}
+_texttextual_ [l=mi] {kore-whakaahua}
+_textcollectionoption_ [l=mi] {<p>
+Kohikohinga-whÄiti hei rauika mai:
+<br>}
+
+_textrelateddocdisplay_ [l=mi] {whakaatu mai ngÄ tuhinga e hÄngai ana}
+_textsearchhistory_ [l=mi] {HÄ«tori rapu:}
+_textnohistory_ [l=mi] {KÄore he hÄ«tori rapu}
+_texthistorydisplay_ [l=mi] {whakaatu mai kia _historynumrecords_ ngÄ rapunga kua tukua}
+_textnohistorydisplay_ [l=mi] {kaua e whakaatu mai i te hÄ«tori rapu}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=mi] {Rapu me te Äta whakarite:}
+_textplainsearch_ [l=mi] {Rapu ngÄwari}
+_textqueryboxsize_ [l=mi] {Te rahi o te pouaka rapu:}
+_textregbox_ [l=mi] {pouaka rapu iti}
+_textbigbox_ [l=mi] {pouaka rapu nui}
+_textformtype_ [l=mi] {TÅ«momo Rapu:}
+_textsimple_ [l=mi] {ngÄwari}
+_textadvanced_ [l=mi] {matatau}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=mi] {me te}
+_textfields_ [l=mi] {ngÄ Äpure}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=mi] {KÅmaka tuhinga ki te}
+_textalsoshowing_ [l=mi] {whakaatu mai ana hoki }
+_textwith_ [l=mi] {kaua e rahi ake i te}
+_textdocsperpage_ [l=mi] {tuhinga ki ia whÄrangi}
+
+_textfilterby_ [l=mi] {Rapua he tuhinga e mau ana i te}
+_textall_ [l=mi] {katoa}
+_textany_ [l=mi] {Ätehi}
+_textwords_ [l=mi] {o ngÄ kupu}
+_textleaveblank_ [l=mi] {waiho tÄnei pouaka e wÄtea ana kia puta mai te katoa o ngÄ tuhinga}
+
+_browsebuttontext_ [l=mi] {KÅmaka Tuhinga}
+
+_nodata_ [l=mi] {<i>kÄore he kÅrero</i>}
+_docs_ [l=mi] {tuhinga}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=mi] {Äwhina}
+_textSearchshort_ [l=mi] {rapua he kupu}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=mi] {tirohia te whakarÄrangi taitara}
+_textCreatorshort_ [l=mi] {tirohia whakarÄrangi kaitito}
+_textSubjectshort_ [l=mi] {tirohia te whakarÄrangi kaupapa}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=mi] {tirohia te whakarÄrangi e pÄ ana ki ngÄ rÄ}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=mi] {tirohia te whakarÄrangi ingoa kÅnae}
+_textLanguageshort_ [l=mi] {tirohia te whakarÄrangi reo}
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=mi] {tirohia te whakarÄrangi tÄnga pukapuka}
+_textToshort_ [l=mi] {tirohia te whakarÄrangi Ki a Wai}
+_textFromshort_ [l=mi] {tirohia te whakarÄrangi NÄ Wai}
+_textBrowseshort_ [l=mi] {tirohia tÄnga pukapuka}
+_textOrganizationshort_ [l=mi] {tirohia te whakarÄrangi rÅpÅ«}
+_textHowtoshort_ [l=mi] {triohia te whakarÄrangi "pÄwhea te"}
+_textTopicshort_ [l=mi] {tirohia te whakarÄrangi kaupapa}
+_textPeopleshort_ [l=mi] {tirohia te whakarÄrangi tÄngata}
+_textAcronymshort_ [l=mi] {tirohia te whakarÄrangi pÅ«tauÄkÄ«}
+_textPhraseshort_ [l=mi] {tirotiro ngÄ kÄ«waha i ngÄ tuhinga}
+_textArtistshort_ [l=mi] {tirohia te whakarÄrangi kaitito}
+_textKeywordshort_ [l=mi] {tirohia te whakarÄrangi kupu matua}
+_textVolumeshort_ [l=mi] {tirohia te whakarÄrangi pukaupuka}
+_textCountriesshort_ [l=mi] {tirohia whakarÄrangi whenua}
+_textdefaultshorttext_ [l=mi] {tirohia te whakarÄrangi kore-mÅhio}
+
+_textSearchlong_ [l=mi] {<p>Ko te whÄrangi rapu te whÄrangi <i>e rapu atu ai ngÄ kupu</i> i roto i ngÄ tuhinga. Ka puta mai ai tÄnei whÄrangi i te tÄ«matanga, Ä, mehemea kua hipa te whÄrangi rapu pÄwhiritia te pÄtene <i>rapu</i> kia puta mai anÅ ai.
+}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi taitara</i> pÄwhiritia te pÄtene 
+<i>taitara a -z</i>. Ka puta mai te pÅ«rÄrangi o ngÄ
+tuhinga e pÄ ana ki ngÄ taitara.
+}
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=mi] {<p>Kia <i>tirohia ngÄ tuhinga e pÄ ana ki te kaitito</i> pÄwhiritia te
+pÄtene <i>kaitito</i>. Ka puta mai he whakarÄrangi e pÄ ana ki ngÄ ingoa kaitito.}
+
+_textSubjectlong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi kaupapa</i> pÄwhiritia te pÄtene 
+<i>kaupapa</i>. Ka puta mai te whakarÄrangi o ngÄ
+tuhinga e pÄ ana ki ngÄ kaupapa.
+}
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi e pÄ ana ki te wÄ</i> pÄwhiritia te
+pÄtene <i>wÄtaka</i>. Ka puta mai te whakarÄrangi o ngÄ tuhinga
+e pÄ ana ki te wÄ i puta mai ai aua tuhinga. }
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi ingoa kÅnae</i> pÄwhiritia te pÄtene <i>ingoa kÅnae</i>. Ka puta mai te whakarÄrangi o ngÄ tuhinga e pÄ ana ki ngÄ ingoa kÅnae.
+}
+
+_textLanguagelong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi reo</i> pÄwhiritia te pÄtene <i>Reo</i>.  Ka puta mai te whakarÄrangi tuhinga e pÄ ana ki ngÄ reo.  }
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi rÅpÅ«</i> pÄwhiritia te pÄtene <i>RÅpÅ«</i>.  Ka puta mai te whakarÄrangi tuhinga e pÄ ana ki ngÄ rÅpÅ«.  }
+
+_textHowtolong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi "pÄwhea te"</i> pÄwhiritia te pÄtene <i>PÄwhea te</i>.  Ka puta mai he whakarÄrangi e pÄ ana ki ngÄ whakamÄrama i ngÄ mahi.  }
+
+_textTopiclong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi kaupapa</i> pÄwhiritia te pÄtene 
+<i>kaupapa</i>. Ka puta mai te whakarÄrangi o ngÄ
+tuhinga e pÄ ana ki ngÄ kaupapa.
+}
+
+_textTolong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi Ki a Wai</i> pÄwhiritia te pÄtene 
+<i>Ki a Wai</i>. Ka puta mai te whakarÄrangi o ngÄ
+tuhinga e pÄ ana ki ngÄ kaiwhiwhi tuhinga.
+}
+
+_textFromlong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi kaituku</i> pÄwhiritia te pÄtene <i>NÄ wai</i>.  Ka puta mai te whakarÄrangi tuhinga e pÄ ana ki ngÄ kaituku.  }
+
+_textSerieslong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi tÄnga pukapuka</i> pÄwhiritia te pÄtene 
+<i>tÄnga pukapuka</i>. Ka puta mai te whakarÄrangi o ngÄ
+tuhinga e pÄ ana ki ngÄ tÄnga pukapuka.
+}
+
+_textBrowselong_ [l=mi] {<p>Kia <i>tirohia tÄnga pukapuka</i> pÄwhiritia te pÄtene
+<i>tirotiro</i>.  }
+
+_textPeoplelong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi tÄngata</i> pÄwhiritia te pÄtene <i>TÄngata</i>.  Ka puta mai te whakarÄrangi tuhinga e pÄ ana ki ngÄ ingoa whÄnau o ngÄ tÄngata.  }
+
+_textAcronymlong_ [l=mi] {<p>Kia <i>tirohia ngÄ tuhinga e pÄ ana ki te pÅ«tauÄkÄ«</i> pÄwhiritia te
+pÄtene <i>pÅ«tauÄkÄ«</i>. Ka puta mai te whakarÄrangi o ngÄ pÅ«tauÄkÄ«
+me te wÄhi e noho mai ai i te tuhinga nei.}
+
+_textPhraselong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi kÄ«waha</i> pÄwhiritia te pÄtene <i>KÄ«waha</i>.  Ka puta mai te whakarÄrangi tuhinga e pÄ ana ki ngÄ kÄ«waha.  }
+
+_textArtistlong_ [l=mi] {<p>Kia <i>tirohia ngÄ tuhinga e pÄ ana ki te kaitito</i> pÄwhiritia te
+pÄtene <i>kaitito</i>. Ka puta mai he whakarÄrangi e pÄ ana ki ngÄ ingoa kaitito.}
+
+_textKeywordlong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi kupu matua</i> pÄwhiritia te pÄtene <i>Kupu Matua</i>.  Ka puta mai te whakarÄrangi tuhinga e pÄ ana ki ngÄ kupu matua.  }
+
+_textVolumelong_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi pukapuka</i> pÄwhiritia te pÄtene 
+<i>pukapuka</i>. Ka puta mai te whakarÄrangi o ngÄ
+pukapuka.
+}
+
+_textCaptionslong_ [l=mi] {<p>Kia <i>tirohia ngÄ tuhinga e pÄ ana ki te rerekÅrero</i> pÄwhiritia te
+pÄtene <i>rerekÅrero</i>. Ka puta mai he whakarÄrangi e pÄ ana ki ngÄ rerekÅrero.}
+
+_textCountrieslong_ [l=mi] {<p>Kia <i>tirohia ngÄ tuhinga e pÄ ana ki te whenua</i> pÄwhiritia te
+pÄtene <i>whenua</i>. Ka puta mai he whakarÄrangi e pÄ ana ki ngÄ whenua.}
+
+
+_textdefaultlongtext_ [l=mi] {<p>Kia <i>tirohia te whakarÄrangi pukapuka</i> pÄwhiritia te pÄtene 
+<i>kore-mÅhio</i>. Ka puta mai te whakarÄrangi o ngÄ
+pukapuka.
+}
+_texthelptopicstitle_ [l=mi] {Kaupapa}
+
+_textreadingdocs_ [l=mi] {NgÄ huarahi hei pÄnui tuhinga}
+
+_texthelpreadingdocs_ [l=mi] {
+<p>Ka kite atu koe i tÄtehi taitara, i tÄtehi whakaahua iti rÄnei i 
+runga ake ki te taha mÄui ka mÅhio koe kei te pÄnui tuhinga. I 
+Ätehi kohikohinga ka kite atu hoki i te rÄrangi kaupapa, i Ätehi 
+atu kohinga ko ngÄ pÄtene haere whakamua (whakamuri) noa 
+iho rÄnei. I te rÄrangi kaupapa e pÅ«kaha ana te wÄhanga pÄnui, Ä, 
+e taea ana te whakatuwhera, te kÄti rÄnei i ngÄ kÅpaki. 
+PÄwhiritia te whakaahua pukapuka kia kÄti ai te tuhinga.</p>
+
+<p>Kei raro ko ngÄ kupu tuhituhi o taua wÄhanga o te tuhinga. 
+Kei raro rÄ anÅ ko te pÄtene haere whakamua i te tuhinga me 
+te pÄtene haere whakamuri i te tuhinga.</p>
+
+ <p>Kei runga ake Ätehi atu pÄtene whakahaere. PÄwhiritia te
+<i>WHAKANUI KUPU TUHITUHI</i> kia kite atu ai i ngÄ kupu 
+tuhituhi katoa. Kia tÅ«pato, i Ätehi wÄ he nui rawa Änei kupu! 
+PÄwhiritia te <i>WHAKANUI WHAKARÄRANGI KAUPAPA</i> 
+kia kite atu ai i ngÄ kaupapa me ngÄ taitara katoa o taua tuhinga. 
+PÄwhiritia te <i>WHAKAWEHE</i> kia puta mai ai ngÄ kÅrero nei
+ki tÄtehi matapihi hou. (He pai tÄnei mÅ te titiro ki ngÄ tuhinga e rua 
+i te wÄ kotahi.) Hei whakamutunga, mehemea ka rapu kupu, ka 
+noho pÅ«kaha aua kupu i roto i te tuhinga. PÄwhiritia te 
+<i>KORE PÅªKAHA</i> kia tango ai te pÅ«kaha o aua kupu.</p>
+}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=mi] {WhakatÅ«whera mai Änei pukapuka}
+_texthelpopenbook_ [l=mi] {WhakatÅ«whera/KÄti tÄnei pukapuka}
+_texthelpviewtextsection_ [l=mi] {Tirohia tÄnei wÄhanga tuhituhi}
+_texthelpexpandtext_ [l=mi] {Whakaatu mai ngÄ kupu tuhituhi katoa, kÄore rÄnei}
+_texthelpexpandcontents_ [l=mi] {Whakanuia WhakarÄrangi Kaupapa, kÄore rÄnei}
+_texthelpdetachpage_ [l=mi] {WhakatÅ«whera mai tÄnei whÄrangi ki te matapihi hou}
+_texthelphighlight_ [l=mi] {PÅ«kaha ngÄ kupu rapu, kÄore rÄnei}
+
+_texthelpsearchingtitle_ [l=mi] {He whakamÄrama i te mahi Rapu Kupu}
+_texthelpsearching_ [l=mi] {
+<p>
+     Ko te whÄrangi rapu te whÄrangi hei rapu kupu. Ka puta mai taua whÄrangi ka
+  whai mai Änei kÅkiri kia rapu ai i (t)Ätehi kupu:<p>
+  
+  <ol><li>Whakaritea kia rapua ngÄ kupu ki whea
+      <li>Whakaritea kia rapua ngÄ kupu katoa, kia rapua Ätehi kupu noa iho rÄnei
+      <li>Tuhia ngÄ kupu rapu
+      <li>PÄwhiritia te pÄtene <i>Rapua</i> 
+  </ol>
+
+<p>Ka tukua te rapu ka puta mai ngÄ kitenga rua tekau e pÄ ana ki Äu kupu 
+rapu. He pÄtene kei raro rÄ o te whÄrangi hei titiro ai ki ngÄ kitenga 21 ki te
+40.  Ka pÄwhiri anÅ i taua pÄtene ka titiro ki Ätehi atu kitenga rua tekau. 
+NÅ reira, he pÄtene kei raro rÄ hei haere whakamua i ngÄ kitenga, hei haere 
+whakamuri rÄnei. 
+PÄwhiritia te taitara o te kitenga, .pÄwhiritia te whakaahua iti rÄnei i te taha o 
+te kitenga kia whakatÅ«whera mai ai taua kitenga.
+
+<p> Ka kore e nuku atu i te 100 o ngÄ pukapuka ka kitea i tÄtehi rapunga. Heoi anÅ
+ka taea te whakarerekÄ tÄnei nama i te pÄtene  <i>kÅwhiringa</i> i runga ake rÄ.<p>
+}
+
+_texthelpquerytermstitle_ [l=mi] {NgÄ kupu rapu}
+_texthelpqueryterms_ [l=mi] {
+<p> Koia nei ngÄ kupu ka tuhia ki roto i te pouaka rapu. Me noho te 
+mokowÄ (wÄhi wÄtea) i waenganui i ngÄ kupu. Ko ngÄ reta me ngÄ 
+nama anakÄ ngÄ pÅ« ka rapua. Kaua e tuhi ngÄ tohutuhi (pÄrÄ i te "?" me 
+te "/"), ka tangohia aua tohu e te rorohiko nei, ka whakauru ko te mokowÄ.
+
+<p> tauira, ki te tuhi atu i Änei kupu rapu; <p>
+    <ul><kbd> huihuinga-a-motu / Whanganui (1860-1885) </kbd></ul>
+      <p>ka rapua kÄtia e te rorohiko Änei kupu;<p>
+      <ul><kbd> huihuinga a motu Whanganui 1860 1885 </kbd></ul><p>
+}
+
+_texthelpquerytypetitle_ [l=mi] {NgÄ tÅ«momo rapu}
+_texthelpquerytype_ [l=mi] {
+<p>E rua ngÄ tÅ«momo rapu.
+
+<ul>
+  <li> Ka rapua te <b>katoa</b> o Äu kupu rapu. Ka rapua ngÄ 
+pukapuka e mau ana i te katoa o ngÄ kupu rapu kua tuhia e koe.
+Ka whakarÄrangitia mai aua kitenga e pÄ ana ki te pÅ«rÄrangi. <p>
+
+  <li> Ka rapua <b>Ätehi</b> o Äu kupu rapu. NÅ reira, me tuhi noa he kupu e pÄ
+      ana ki te kaupapa e hiahia ana koe. Ka whakarÄrangitia ngÄ kitenga e pÄ ana
+      ki te ritenga ki Äu kupu rapu. ArÄ, ka puta tuatahitia mai ngÄ kitenga;  
+
+
+      <p><ul>
+        <li> e mau ana i te maha o Äu kupu rapu;
+        <li> e mau ana i ngÄ kupu uaua te kite o Äu kupu rapu;
+        <li> e iti ana, ka whai mai ko ngÄ pukapuka nui.
+      </ul>
+</ul>
+
+<p> Me tuhi i te maha o ngÄ kupu rapu kia arahina te rapu ki tÅ ake hiahia.<p>
+}
+
+_textdatesearch_ [l=mi] {Rapu RÄ}
+
+_texthelpdatesearch_ [l=mi] {
+Ko te rapu rÄ tÄtehi rapu e taea ana te mahi motuhake, e taea ana rÄnei te 
+whakaÅ« ki tÄtehi rapunga kupu. He huarahi hei rapu tuhinga i puta mai i 
+tÄtehi tau, i Ätehi tau rÄnei.<p>
+}
+
+_texthelpdatehowtotitle_ [l=mi] {NgÄ Huarahi hei Rapu RÄ:}
+_texthelpdatehowto_ [l=mi] {
+<ul>
+   <li>Kia rapu ngÄ tuhinga e pÄ ana ki tÄtehi tau:<p>
+   <ul>
+       <li>Tuhia ngÄ kupu rapu (pÄra i te rapu kupu).
+       <li>Tuhia te tau ki te pouaka "RÄ (tÄ«mata)".
+       <li>Mehemea i mua tÅ tau rapu i te whÄnau mai o 
+             Ihu Karaiti kÅwhiritia te "B.C.E" i te rÄrangi tono
+            e tata ana ki te pouaka.
+       <li>Tukua te rapu.
+   </ul>
+<p><li>Kia rapu ngÄ tuhinga e pÄ ana ki tÄtehi wÄ, arÄ ki Ätehi tau:<p>
+   <ul>
+       <li> Tuhia ngÄ kupu rapu (pÄra i te rapu kupu).
+       <li> Tuhia te tau tÄ«mata ki te pouaka "RÄ (tÄ«mata)".
+       <li> Tuhia te tau mutunga ki te pouaka "RÄ mutunga".
+       <li> Mehemea i mua tÄtehi tau rapu i te whÄnau mai o 
+             Ihu Karaiti kÅwhiritia te "B.C.E" i te rÄrangi tono
+            e tata ana ki te pouaka.
+       <li>Tukua te rapu.
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=mi] {He kÅrero mÅ te Rapu RÄ}
+_texthelpdateresults_ [l=mi] {
+Mehemea i rapua e koe te tau 1907 ko ngÄ kitenga he 
+pukapuka kua tuhi kÅrero e pÄ ana ki 1907, kÄore he 
+pukapuka i tÄ ai i te tau 1907. He Ähua koi hoki te rapu 
+i te mea ka kitea ngÄ pukapuka e kÅrero ana mÅ taua 
+wÄ hoki, hei tauira; ka kitea ngÄ pukapuka e pÄ ana ki 
+te wÄ 1899-1921 (kei roto te 1907 i taua wÄ), ka kitea 
+hoki ngÄ pukapuka e pÄ ana ki te 20th century (kei roto 
+te 1907 i taua wÄ), ahakoa kÄore te tau 1907 i tuhia ake 
+i aua pukapuka.<p>
+}
+
+_textchangeprefs_ [l=mi] {Te whakarerekÄ Å kÅwhiringa}
+
+_texthelppreferences_ [l=mi] {
+<p>Ko te pÄtene <i>kÅwhiringa</i> kei runga ake i te whÄrangi hei 
+whakarerekÄ ai ngÄ kÅwhiringa e pÄ ana ki Åu ake hiahia. 
+}
+
+_texthelpcollectionprefstitle_ [l=mi] {KÅwhiringa Kohikohinga}
+_texthelpcollectionprefs_ [l=mi] {
+Kei roto i Ätehi kohikohinga he kohikohinga anÅ, he kohikohinga-whÄiti.  
+E taea te whakarite i te whÄrangi kÅwhiringa, ko Äwhea ngÄ 
+kohikohinga-whÄiti ka tirohia i te mahi rapu kupu, ko Äwhea ngÄ 
+kohikohinga-whÄiti ka kore e tirohia i te mahi rapu.
+}
+
+_texthelplanguageprefstitle_ [l=mi] {KÅwhiringa Reo}
+_texthelplanguageprefs_ [l=mi] {
+Kei ngÄ kohikohinga he reo tauwhiti. E taea ana te whakarite 
+kÅ tÄwhea te reo tauwhiti tuatahi ka kite atu ai te kaipÄnui. 
+E taea ana te whakarerekÄ hoki i te encoding scheme mehemea 
+kÄore e pai ana, kÄore e tika ana te puta mai o ngÄ pÅ« i tÅ reo.
+E taea ana hoki te whakarite kia kore-whakaahua te puta mai 
+o ngÄ kÅrero, arÄ kia text anakÄ, hei Äwhina i ngÄ tÄngata e Ähua 
+kÄpÅ ana.
+}
+
+_texthelppresentationprefstitle_ [l=mi] {KÅwhiringa Whakaaturanga}
+_texthelppresentationprefs_ [l=mi] {
+
+Ka rerekÄ ngÄ kÅwhiringa whakaaturanga e taea ana te whakarite 
+i ia tÅ«momo kohikohinga.
+
+<p>Kei Ätehi kohikohinga e taea ana te whakangaro ngÄ pÄtene
+whakahaere o runga ake, Ä ka riro mÄ ngÄ pÄtene whakahaere ake 
+o te pÅ«manawa tirotiro e tohutoro. Kei Ätehi atu kohikohinga e taea 
+ana te rapu kitenga i te ipurangi whÄnui, me te haere tÅtika ki reira,
+}
+
+_texthelpsearchprefstitle_ [l=mi] {KÅwhiringa Rapu}
+_texthelpsearchprefs_ [l=mi] {
+<p>E rua ngÄ kÅwhiringa hei whakarite ai i te hÄngai pÅ« o te kupu
+rapu ki te kupu kite. Ko te kÅwhiringa tuatahi ko ngÄ pÅ« matua me 
+ngÄ pÅ« iti. Äe rÄnei, me tika te pÅ« matua me te pÅ« iti, kÄore rÄnei, 
+me rapu noa i te kupu hei aha te Äta titiro ki ngÄ pÅ« matua me ngÄ pÅ« iti. 
+Ko te kÅwhiringa tuarua ko te kÅ«muri. Äe rÄnei, me tino Årite 
+te kÅ«muri, kÄore rÄnei, hei aha te Äta titiro ki ngÄ kÅ«muri o ngÄ 
+kupu. MÅ ngÄ kupu rapu PÄkehÄ anakÄ te  kÅwhiringa kÅ«muri.
+
+<p>Hei tauira, mehemea ka kÅwhiritia te <i>hei aha te pÅ« matua me te pÅ«
+iti</i>, Ä, ka kÅwhiritia hoki te <i>hei aha te kÅ«muri o te kupu</i>
+kÄtahi ka tukua Änei kupu hei rapu;
+<p>
+  <ul><kbd>Aotearoa building</kbd></ul>
+    <p>ka Årite te whakahoki mai o ngÄ pukapuka ki Änei kupu rapu
+  <ul><kbd>aotearoa builds</kbd></ul>
+<p>ka pÄnei i te mea, kÄore te rapu i te Äta titiro mehemea he pÅ«
+matua, he pÅ« iti rÄnei, Ä, ka tangohia ngÄ kÅ«muri (pÄrÄ
+i te "ing", me te "s") i tÄnei kÅwhiringa.
+
+E taea ana te whakarite te pouaka rapu kia Ähua nui kia ngÄwari ai
+te tuhi i te maha o ngÄ kupu, kÅwae kÅrero rÄnei. He huarahi tere 
+tÄnei mÅ te rapu kÅrero.
+ 
+<p>E taea ana te whakarite i te tÅ«momo rapu kia matatau, arÄ 
+kia whakamahia ngÄ pÅ« Boolean pÄra i te  AND (&), OR (|), 
+me te NOT (!). Mehemea ka pÄna ka whakawhÄiti te nama o ngÄ 
+kitenga. E taea ana te whakarite i te hÄ«tori rapu kia maumahara ai 
+te rorohiko i ngÄ kupu kua rapua e koe. Ä, e taea ana hoki te 
+whakarite kia hia ngÄ kitenga ka puta mai ki runga i te mata 
+o tÅ rorohiko i te wÄ kotahi.
+"	}
+
+_texttanumbrowseoptions_ [l=mi] {E _numbrowseoptions_ ngÄ huarahi hei rapu kÅrero i te kohikohinga nei:}
+
+_textsimplehelpheading_ [l=mi] {NgÄ huarahi hei rapu kÅrero}
+
+_texthelpscopetitle_ [l=mi] {NgÄ TaupÅ« o te Rapu}
+_texthelpscope_ [l=mi] {
+<p>
+Kei te nuinga o ngÄ kohikohinga e taea ana te whiriwhiri ki 
+tÄwhea taupÅ« e rapu atu ai ngÄ kupu. Hei tauira, me rapu 
+ngÄ kupu i te taupÅ« Kaitito, i te taupÅ« Taitara rÄnei; me rapu 
+ngÄ kupu i te taupÅ« wÄhanga, i te taupÅ« kÅwae rÄnei. 
+Ahakoa ko tÄwhea taupÅ« ka puta mai te katoa o ngÄ kupu tuhituhi.
+
+<p>Mehemea he pukapuka te kitenga, ka whakatÅ«whera mai
+ki te wÄhi e noho mai ai Äu kupu rapu.
+}
Index: /gsdl/stable/macros/marathi.dm
===================================================================
--- /gsdl/stable/macros/marathi.dm	(revision 20131)
+++ /gsdl/stable/macros/marathi.dm	(revision 20131)
@@ -0,0 +1,810 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# English Language text and icon macros 
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=mr] {à€šà€¿à€¯à€€à€à€Ÿà€²à€¿à€à¥}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=mr] {à€¶à¥à€§à€²à¥à€²à¥ à€žà€à€°à¥à€Šà€­}  
+_textdate_ [l=mr] {à€ªà¥à€°à€à€Ÿà€¶à€šà€Ÿà€à¥ à€€à€Ÿà€°à¥à€}  
+_textnumpages_ [l=mr] {à€ªà¥à€·à€ à€žà€à€à¥à€¯à€Ÿ}  
+
+_textsignin_ [l=mr] {à€žà¥à€µà€Ÿà€à¥à€·à€°à¥ à€à€°à€Ÿ }  
+
+_textdefaultcontent_ [l=mr] {à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€¹à€µà¥ à€
+à€žà€²à¥à€²à¥ à€ªà€Ÿà€š à€žà€Ÿà€ªà€¡à€²à¥ à€šà€Ÿà€¹à¥.  à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€à¥à€¯à€Ÿ à€®à¥à€à¥à€¯à€ªà€Ÿà€šà€Ÿà€µà€° à€à€Ÿà€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€à¥à€ªà€¯à€Ÿ à€¬à¥à€°à€Ÿà€à€à€° à€µà€°à¥à€² à€®à€Ÿà€à¥ à€¹à¥ à€µà€à€£ à€Šà€Ÿà€¬à€Ÿ à€
+à€¥à€µà€Ÿ à€¹à¥à€® à€¬à€à€£ à€Šà€Ÿà€¬à€Ÿ.}  
+
+_textdefaulttitle_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€à¥ à€à¥à€}  
+
+_textbadcollection_ [l=mr] {à€¹à€Ÿ à€žà€à€à¥à€°à€¹  à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¡à€¿à€à¥à€à€² à€²à€Ÿà€¯à€¬à¥à€°à€°à¥ à€®à€§à¥à€¯à¥ à€šà€Ÿà€¹à¥.}  
+
+_textselectpage_ [l=mr] {à€ªà¥à€·à¥à€  à€šà€¿à€µà€¡à€Ÿ}  
+
+_collectionextra_ [l=mr] {à€¯à€Ÿ à€à¥à€°à€à€¥ à€žà€Ÿà€ à¥à€¯à€Ÿ à€®à€§à¥à€¯à¥---à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€à€¹à¥à€€.à€¯à€Ÿ à€à¥à€°à€à€¥ à€žà€Ÿà€ à¥à€¯à€Ÿà€à¥ à€€à€Ÿà€°à¥à€---}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=mr] {<p>à€¯à€Ÿ à€à¥à€°à€à€¥ à€žà€Ÿà€ à¥à€¯à€Ÿ à€®à€§à¥à€¯à¥---à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€à€¹à¥à€€.("_numdocs_" eq "1",document,documents),  <p><a href="_httppagex_(bsummary)"> </a> to view the build summary for this collection.
+}  
+
+_textdescrcollection_ [l=mr] {}
+_textdescrabout_ [l=mr] {à€ªà€Ÿà€šà€Ÿà€à€µà€¿à€·à€¯à¥ }  
+_textdescrhome_ [l=mr] {à€®à¥à€à¥à€¯ à€ªà€Ÿà€š}  
+_textdescrhelp_ [l=mr] {à€®à€Šà€€à¥à€à¥ à€ªà€Ÿà€š}  
+_textdescrpref_ [l=mr] {à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯ à€ªà€Ÿà€š}  
+_textdescrgreenstone_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¡à€¿à€à¥à€à€² à€²à€Ÿà€¯à€¬à¥à€°à€°à¥  à€žà¥
+à€Ÿà€«à¥à€à€µà¥à€
+à€°}  
+_textdescrusab_ [l=mr] {à€à€ à¥à€£ à€à€Ÿà€¯ à€µà€Ÿà€à€²à¥ }  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=mr] {à€¶à¥à€§à€Ÿ}  
+_labelSearch_ [l=mr] {à€¶à¥à€§}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=mr] {à€¶à€¿à€°à¥à€·à€}  
+_labelTitle_ [l=mr] {à€¶à€¿à€°à¥à€·à€à¥}  
+_textCreator_ [l=mr] {à€žà€à€à¥à€°à€¹à€}  
+_labelCreator_ [l=mr] {à€žà€à€à€²à€}  
+_textSubject_ [l=mr] {à€µà€¿à€·à€¯}  
+_labelSubject_ [l=mr] {à€µà€¿à€·à€¯}  
+_textDescription_ [l=mr] {à€žà€µà€¿à€žà¥à€€à€°}  
+_labelDescription_ [l=mr] {à€µà€°à¥à€£à€š}  
+_textPublisher_ [l=mr] {à€ªà¥à€°à€à€Ÿà€¶à€}  
+_labelPublisher_ [l=mr] {à€ªà¥à€°à€à€Ÿà€¶à€}  
+_textContributor_ [l=mr] {à€žà€¹à€Ÿà€¯à¥à€¯à€}  
+_labelContributor_ [l=mr] {à€žà€¹à€Ÿà€¯à¥à€¯à€}  
+_textDate_ [l=mr] {à€€à€Ÿà€°à¥à€}  
+_labelDate_ [l=mr] {à€Šà€¿à€šà€Ÿà€à€}  
+_textType_ [l=mr] {à€ªà¥à€°à€à€Ÿà€°}  
+_labelType_ [l=mr] {à€ªà¥à€°à€à€Ÿà€°}  
+_textFormat_ [l=mr] {à€ªà¥à€°à€à€Ÿà€°}  
+_labelFormat_ [l=mr] {à€ªà¥à€°à€à€Ÿà€°}  
+_textIdentifier_ [l=mr] {à€žà€¿à€§à¥à€Šà€à€°à€£à€Ÿà€°à€Ÿ à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à€£à€Ÿà€°à€Ÿ}  
+_labelIdentifier_ [l=mr] {à€à€³à€à€£à¥}  
+_textSource_ [l=mr] {à€«à€Ÿà€¯à€²à€¿à€à€à¥ à€šà€Ÿà€µà¥}  
+_labelSource_ [l=mr] {à€«à€Ÿà€à€² à€šà€Ÿà€µ}  
+_textLanguage_ [l=mr] {à€­à€Ÿà€·à€Ÿ}  
+_labelLanguage_ [l=mr] {à€­à€Ÿà€·à€Ÿ}  
+_textRelation_ [l=mr] {à€žà€à€¬à€à€§à€¿à€€}  
+_labelRelation_ [l=mr] {à€žà€à€¬à€à€§à€¿à€€}  
+_textCoverage_ [l=mr] {à€žà€®à€Ÿà€µà€¿à€·à¥à€}  
+_labelCoverage_ [l=mr] {à€à€µà¥à€¹à€°à¥à€}  
+_textRights_ [l=mr] {à€¯à¥à€à¥à€¯}  
+_labelRights_ [l=mr] {à€
+à€§à€¿à€à€Ÿà€°}  
+
+# DLS metadata set
+_textOrganization_ [l=mr] {à€žà€à€žà¥à€¥à€Ÿ}  
+_labelOrganization_ [l=mr] {à€žà€à€žà¥à€¥à€Ÿ}  
+_textKeyword_ [l=mr] {à€¶à¥à€§ à€¶à€¬à¥à€Š}  
+_labelKeyword_ [l=mr] {à€®à¥à€à¥à€¯à€¶à€¬à¥à€Š}  
+_textHowto_ [l=mr] {à€à€žà¥}  
+_labelHowto_ [l=mr] {à€à€žà¥}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=mr] {à€µà€Ÿà€à¥à€ªà¥à€°à€à€Ÿà€°}  
+_labelPhrase_ [l=mr] {à€µà€Ÿà€à¥à€ªà¥à€°à€à€Ÿà€°}  
+_textCollage_ [l=mr] {à€®à€¹à€Ÿà€µà€¿à€Šà¥à€¯à€Ÿà€²à€¯}  
+_labelCollage_ [l=mr] {à€®à€¹à€Ÿà€µà€¿à€Šà¥à€¯à€Ÿà€²à€¯}  
+_textBrowse_ [l=mr] {à€ªà€¹à€Ÿ}  
+_labelBrowse_ [l=mr] {à€à€Ÿà€³à€£à¥}  
+_textTo_ [l=mr] {à€ªà€°à¥à€¯à€à€€}  
+_labelTo_ [l=mr] {à€ªà¥à€°à€€à€¿}  
+_textFrom_ [l=mr] {à€ªà€Ÿà€žà¥à€š}  
+_labelFrom_ [l=mr] {à€ªà€Ÿà€žà¥à€š}  
+_textAcronym_ [l=mr] {à€žà€à€à¥à€·à€¿à€ªà¥à€€ à€°à¥à€ª}  
+_labelAcronym_ [l=mr] {à€žà€à€à¥à€·à€¿à€ªà¥à€€ à€°à¥à€ª}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=mr] {à€à€ à€Šà¥à€µà€Ÿà€°à¥ à€ªà€¹à€Ÿ}  
+
+_textdescrSearch_ [l=mr] {à€µà€¿à€¶à€¿à€·à¥à€ à€¶à€¬à¥à€Š à€¶à¥à€§à€Ÿ}  
+_textdescrType_ [l=mr] {à€°à€¿à€žà¥à€°à¥à€žà€Šà¥à€µà€Ÿà€°à¥ à€ªà€¹à€Ÿ}  
+_textdescrIdentifier_ [l=mr] {à€°à€¿à€žà¥à€°à¥à€ž à€à€¯à€¡à¥à€à€à¥à€«à€Ÿà€¯à€° à€šà¥à€žà€Ÿà€° à€ªà€¹à€Ÿ}  
+_textdescrSource_ [l=mr] {à€®à¥à€³ à€«à€Ÿà€à€² à€šà€Ÿà€µà€Ÿ à€ªà¥à€°à€®à€Ÿà€£à¥ à€ªà€¹à€Ÿ}  
+_textdescrTo_ [l=mr] {à€à€¶à€¯à€Ÿà€à¥à€¯à€Ÿ à€
+à€à€à€Ÿà€ªà¥à€°à€®à€Ÿà€£à¥ à€ªà€¹à€Ÿ}  
+_textdescrFrom_ [l=mr] {à€¯à€Ÿ à€µà€¿à€­à€Ÿà€à€Ÿà€€à¥à€š à€¶à¥à€§à€Ÿ.}  
+_textdescrCollage_ [l=mr] {à€à€¿à€€à¥à€° à€žà€à€à¥à€°à€¹ à€ªà€¹à€Ÿ}  
+_textdescrAcronym_ [l=mr] {à€žà€à€à¥à€·à€¿à€ªà¥à€€ à€°à¥à€ª  à€ªà€¹à€Ÿ}  
+_textdescrPhrase_ [l=mr] {à€µà€Ÿà€à¥à€ªà¥à€°à€à€Ÿà€° à€ªà€¹à€Ÿ}  
+_textdescrHowto_ [l=mr] {à€ªà¥à€°à€à€Ÿà€°à€Ÿà€à€šà¥à€žà€Ÿà€° à€ªà€¹à€Ÿ}  
+_textdescrBrowse_ [l=mr] {à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€ªà€¹à€Ÿ}  
+_texticontext_ [l=mr] {à€Šà€žà¥à€€à€à€µà€ à€Šà€Ÿà€à€µà€Ÿ}  
+_texticonclosedbook_ [l=mr] {à€¹à€Ÿ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€à€à€¡à€Ÿ à€à€£à€¿ à€
+à€šà¥à€à¥à€°à€®à€£à€¿à€à€Ÿ à€ªà€¹à€Ÿ.}  
+_texticonnext_ [l=mr] {à€ªà¥à€¢à€¿à€² à€µà€¿à€­à€Ÿà€ à€šà€Ÿà€¹à¥}  
+_texticonprev_ [l=mr] {à€ªà¥à€°à¥à€µà¥à€à¥à€¯à€Ÿ à€µà€¿à€­à€Ÿà€à€Ÿà€€}  
+
+_texticonworld_ [l=mr] {à€®à€Ÿà€¹à€¿à€€à¥à€à€Ÿà€³à¥à€¯à€Ÿà€µà€°à¥à€² à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€Šà€Ÿà€à€µà€Ÿ}  
+
+_texticonmidi_ [l=mr] {à€®à€¿à€¡à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€ªà€¹à€Ÿ.}  
+_texticonmsword_ [l=mr] {à€¹à€Ÿ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€®à€Ÿà€¯à€à¥à€à¥à€žà¥à€«à¥à€ à€µà€°à¥à€¡ à€®à€§à¥à€¯à¥ à€Šà€Ÿà€à€µà€Ÿ}  
+_texticonmp3_ [l=mr] {à€žà€Ÿà€¹à€¿à€€à¥à€¯  à€à€® à€ªà¥ à€¥à¥à€°à¥ à€ªà€¹à€Ÿ}  
+_texticonpdf_ [l=mr] {à€ªà¥à€¡à¥à€« à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€ªà€¹à€Ÿ.}  
+_texticonps_ [l=mr] {à€ªà¥à€žà¥à€à€žà¥à€°à€¿à€ªà€ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€Šà€Ÿà€à€µà€Ÿ}  
+_texticonppt_ [l=mr] {à€ªà¥à€µà€° à€ªà¥à€à€à€ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€ªà€¹à€Ÿ.}  
+_texticonrtf_ [l=mr] {à€à€°.à€à¥.à€« à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€ªà€¹à€Ÿ.}  
+_texticonxls_ [l=mr] {à€®à€Ÿà€¯à€à¥à€°à¥à€žà¥à€«à¥à€ à€à€à¥à€žà¥à€² à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€¬à€à€Ÿ}  
+
+_page_ [l=mr] {à€ªà€Ÿà€š}  
+_pages_ [l=mr] {à€ªà€Ÿà€šà¥}  
+_of_ [l=mr] {à€à¥}  
+_vol_ [l=mr] {à€
+à€à€}  
+_num_ [l=mr] {à€à¥à€°à€®à€Ÿà€à€.}  
+
+_textmonth00_ [l=mr] {}
+_textmonth01_ [l=mr] {à€à€Ÿà€šà¥à€µà€Ÿà€°à¥}  
+_textmonth02_ [l=mr] {à€«à¥à€¬à¥à€°à¥à€µà€Ÿà€°à¥}  
+_textmonth03_ [l=mr] {à€®à€Ÿà€°à¥à€}  
+_textmonth04_ [l=mr] {à€à€ªà¥à€°à€¿à€²}  
+_textmonth05_ [l=mr] {à€®à¥}  
+_textmonth06_ [l=mr] {à€à¥à€š}  
+_textmonth07_ [l=mr] {à€à¥à€²à¥}  
+_textmonth08_ [l=mr] {à€à€à€žà¥à€}  
+_textmonth09_ [l=mr] {à€žà€ªà¥à€à¥à€à€¬à€°}  
+_textmonth10_ [l=mr] {à€à€à¥à€à¥à€¬à€°}  
+_textmonth11_ [l=mr] {à€šà¥à€µà¥à€¹à¥à€à€¬à€°}  
+_textmonth12_ [l=mr] {à€¡à€¿à€žà¥à€à€¬à€°}  
+
+_texttext_ [l=mr] {à€
+à€à¥à€·à€°}  
+_labeltext_ [l=mr] {_texttext_}  
+_textdocument_ [l=mr] {à€žà€Ÿà€¹à€¿à€€à¥à€¯}  
+_textsection_ [l=mr] {à€µà€¿à€­à€Ÿà€}  
+_textparagraph_ [l=mr] {à€ªà€°à€¿à€à¥à€à¥à€Š}  
+_textchapter_ [l=mr] {à€ªà€Ÿà€ }  
+_textbook_ [l=mr] {à€ªà¥à€žà¥à€€à€}  
+
+_magazines_ [l=mr] {à€®à€Ÿà€žà€¿à€}  
+
+_nzdlpagefooter_ [l=mr] {à€šà¥à€¯à¥à€à€¿à€²à€à€¡ à€
+à€à€à¥à€à¥à€€ à€à€à€¥à€Ÿà€²à€¯ à€ªà¥à€°à€à€²à¥à€ª, à€žà€à€à€£à€ à€¶à€Ÿà€žà¥à€€à¥à€° à€µà€¿à€­à€Ÿà€, à€µà€Ÿà€¯à€à€€à¥ à€µà€¿à€Šà¥à€¯à€Ÿà€ªà¥à€ , à€šà¥à€¯à¥à€à¥à€²à€à€¡.}  
+
+_linktextHOME_ [l=mr] {à€®à¥à€à¥à€¯ à€ªà€Ÿà€š}  
+_linktextHELP_ [l=mr] {à€®à€Šà€€}  
+_linktextPREFERENCES_ [l=mr] {à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=mr] {à€à¥à€°à¥à€š à€žà¥à€à¥à€š à€¡à€¿à€à¥à€à€² à€²à€Ÿà€¯à€¬à¥à€°à€°à¥}  
+
+_textnocollections_ [l=mr] {à€¯à¥à€à¥à€¯ à€šà€Ÿà€¹à¥ (à€®à¥à€¹à€£à€à¥ à€€à€¯à€Ÿà€° à€µ à€žà€Ÿà€°à¥à€µà€à€šà€¿à€) à€žà€à€à¥à€°à€¹ à€à€ªà€²à€¬à¥à€§ à€à€¹à¥}  
+
+_textadmin_ [l=mr] {à€®à¥à€à¥à€¯ à€ªà€Ÿà€š}  
+_textabgs_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€µà€¿à€·à€¯à¥}  
+_textgsdocs_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯}  
+
+_textdescradmin_ [l=mr] {à€¯à€Ÿ à€Šà¥à€µà€Ÿà€°à¥ à€€à¥à€®à¥à€¹à¥ à€šà€µà€¿à€š à€à€ªà€¯à¥à€à€ à€à€Ÿà€²à¥à€š à€žà€à€à¥à€°à€¹ à€žà€à€à¥à€·à€¿à€ªà¥à€€ à€à€°à¥ à€¶à€à€€à€Ÿ, à€µ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€®à€§à¥à€¯à¥ à€à€à€šà¥à€žà¥à€à¥à€²à¥à€¶à€š à€µà€¿à€·à€¯à¥ à€€à€Ÿà€à€€à¥à€°à€¿à€ à€®à€Ÿà€¹à€¿à€€à¥ à€­à€°à¥ à€¶à€à€€à€Ÿ}  
+
+_textdescrgogreenstone_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€žà¥à€«à¥à€à€µà¥à€
+à€° à€µ à€šà¥à€¯à¥à€à¥à€²à€à€¡ à€
+à€à€à¥à€à¥à€€ à€à¥à€°à€à€¥à€Ÿà€²à€¯ à€ªà¥à€°à€à€²à¥à€ª à€¯à€Ÿ à€µà€¿à€·à€¯à¥ à€®à€Ÿà€¹à€¿à€€à¥}  
+
+_textdescrgodocs_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€à¥ à€®à€Ÿà€¹à€¿à€€à¥à€ªà¥à€žà¥à€€à€¿à€à€Ÿ}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=mr] {à€²à€Ÿà€¯à€¬à¥à€°à¥à€¯à€š à€à€à€à€°à€«à¥à€ž}  
+_textdescrgli_ [l=mr] {à€®à€Šà€€à¥à€Šà¥à€µà€Ÿà€°à¥ à€€à¥à€®à¥à€¹à¥ à€šà€µà€¿à€š à€Šà€žà¥à€€à€à€µà€ à€®à€¿à€³à€µà¥ à€¶à€à€€à€Ÿ,à€€à¥à€¯à€Ÿà€®à€§à¥à€¯à¥ à€¬à€Šà€² à€à€°à¥ à€¶à€à€€à€Ÿ,à€à€¿à€à€µà€Ÿ à€à€®à¥ à€à€°à¥ à€¶à€à€€à€Ÿ.}  
+
+package collector
+
+_textcollector_ [l=mr] {à€žà€à€à¥à€°à€¹à€}  
+_textdescrcollector_ [l=mr] {à€¹à¥ à€²à€Ÿà€¯à€¬à¥à€°à€°à¥à€¯à€š à€à€à€à€°à€«à¥à€ž à€à¥à€¯à€Ÿ à€à€§à¥ à€¯à¥à€€à¥ à€à€£à€¿ à€ªà¥à€°à€¯à¥à€à€Ÿà€žà€Ÿà€ à¥ à€²à€Ÿà€¯à€¬à¥à€°à€°à¥à€¯à€š à€à€Ÿ à€à€à€à€°à€«à¥à€ž à€µà€Ÿà€ªà€°à€Ÿà€µà€Ÿ.}  
+
+package depositor
+
+_textdepositor_ [l=mr] {à€ à¥à€µà¥à€Šà€Ÿà€°}  
+_textdescrdepositor_ [l=mr] {à€à€ªà€²à€¬à¥à€§ à€žà€Ÿà€¹à€¿à€€à¥à€¯à€Ÿà€®à€§à¥à€¯à¥ à€šà€µà¥à€š à€Šà€žà¥à€€à€à€µà€  à€à€Ÿà€²à€€à€Ÿ à€¯à¥à€€à€Ÿà€€.}  
+
+package gti
+
+_textgti_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€à€Ÿà¥à€°à€šà€žà€²à¥à€à€° à€à€à€à€°à€«à¥à€ž}  
+_textdescrtranslator_ [l=mr] {à€®à€Šà€€à¥à€µà¥à€Šà€Ÿà€°à¥ à€€à¥à¥à€®à¥à€¹à¥ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€à€à€à€°à€«à¥à€žà€à¥à€¯à€Ÿ à€
+à€Šà¥à€¯à€¯à€Ÿà€µà€€ à€à€µà¥à€€à¥à€€à¥ à€ªà€Ÿà€¹à¥ à€¶à€à€€à€Ÿ.}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=mr] {à€žà€à€à€²à€šà€Ÿ à€žà€à€°à¥à€Šà€­à€Ÿà€€}  
+
+_textsubcols1_ [l=mr] {à€žà€§à¥à€¯à€Ÿ à€à€ªà€²à€¬à¥à€§ à€à€¹à¥}  
+
+_textsubcols2_ [l=mr] {à€šà€¿à€µà€¡à€²à¥à€²à¥à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€€à¥à€² à€žà€§à¥à€¯à€Ÿ à€µà€Ÿà€ªà€°à€€ à€
+à€žà€²à¥à€²à¥ à€à€ªà€žà€à€à¥à€°à€¹ à€€à¥à€®à¥à€¹à¥ à€€à€ªà€Ÿà€žà¥ (à€à€£à€¿ à€¬à€Šà€²à¥) à€¶à€à€€à€Ÿ}  
+
+_titleabout_ [l=mr] {à€žà¥à€®à€Ÿà€°à¥}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=mr] {à€à¥à€°à€à€¥à€Ÿà€²à€¯à€Ÿà€à€Ÿ à€¹à€Ÿ à€µà€¿à€­à€Ÿà€ à€¬à€à€Š à€à€°à€Ÿ}  
+_texticonclosedbookshelf_ [l=mr] {à€à¥à€°à€à€¥à€Ÿà€²à€¯à€Ÿà€€à¥à€² à€¹à€Ÿ à€µà€¿à€­à€Ÿà€ à€à€à€¡à¥à€š à€€à¥à€¯à€Ÿà€€à¥à€² à€
+à€šà¥à€à¥à€°à€®à€£à€¿à€à€Ÿ à€¬à€à€Ÿ}  
+_texticonopenbook_ [l=mr] {à€¹à¥ à€ªà¥à€žà¥à€€à€ à€¬à€à€Š à€à€°à€Ÿ}  
+_texticonclosedfolder_ [l=mr] {à€¹à¥ à€«à¥à€²à¥à€¡à€° à€à€à€¡à€Ÿ à€à€£à€¿ à€€à¥à€¯à€Ÿà€€à¥à€² à€®à€Ÿà€¹à¥à€€à¥ à€ªà€¹à€Ÿ}  
+_texticonclosedfolder2_ [l=mr] {à€à€ªà€µà€¿à€­à€Ÿà€ à€à€à€¡à€Ÿ}  
+_texticonopenfolder_ [l=mr] {à€«à¥à€²à¥à€¡à€° à€¬à€à€Š à€à€°à€Ÿ}  
+_texticonopenfolder2_ [l=mr] {à€à€ªà€µà€¿à€­à€Ÿà€ à€¬à€à€Š à€à€°à€Ÿ}  
+_texticonsmalltext_ [l=mr] {à€®à€à€à¥à€°à€Ÿà€€à¥à€² à€¹à€Ÿ à€­à€Ÿà€ à€¬à€à€Ÿ}  
+_texticonsmalltext2_ [l=mr] {à€²à¥à€ à€Šà€Ÿà€à€µà€Ÿ.}  
+_texticonpointer_ [l=mr] {à€à€Ÿà€²à¥ à€µà€¿à€­à€Ÿà€}  
+_texticondetach_ [l=mr] {à€¹à¥ à€ªà€Ÿà€š à€šà€µà¥à€š à€à€¿à€¡à€à¥à€®à€§à¥à€¯à¥ à€à€à€¡à€Ÿ}  
+_texticonhighlight_ [l=mr] {à€¶à¥à€§à€Ÿà€µà€¯à€Ÿà€à¥ à€¶à€¬à¥à€Š à€ à€³à€ à€à€°à€Ÿ}  
+_texticonnohighlight_ [l=mr] {à€žà€à€à¥à€à€Ÿ à€ à€³à€ à€à€°à¥ à€šà€à€Ÿ}  
+_texticoncontracttoc_ [l=mr] {à€à¥à€°à€®à€µà€Ÿà€°à¥à€€ à€¯à¥à€€ à€šà€Ÿà€¹à¥.}  
+_texticonexpandtoc_ [l=mr] {à€
+à€šà¥à€à¥à€°à€®à€£à€¿à€à€Ÿ à€µà€¿à€žà¥à€€à€Ÿà€°à€Ÿà€šà¥ à€¬à€à€Ÿ}  
+_texticonexpandtext_ [l=mr] {à€žà€°à¥à€µ à€®à€Ÿà€¹à€¿à€€à¥ à€¬à€à€Ÿ}  
+_texticoncontracttext_ [l=mr] {à€žà€§à¥à€¯à€Ÿ à€šà€¿à€µà€¡ à€à¥à€²à¥à€²à€¯à€Ÿ à€µà€¿à€­à€Ÿà€à€Ÿà€€à¥à€² à€®à€Ÿà€¹à€¿à€€à¥ à€¬à€à€Ÿ}  
+_texticonwarning_ [l=mr] {à€žà¥à€à€šà€Ÿ}  
+_texticoncont_ [l=mr] {à€ªà¥à€¢à¥ à€à€Ÿà€¯à€à€¯?}  
+
+_textltwarning_ [l=mr] {<div class="buttons">_imagecont_</div>
+_iconwarning_à€¯à€Ÿ à€®à¥à€³à¥ à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€à€Ÿà€žà¥à€€à¥à€€ à€à€Ÿà€žà¥à€€ à€®à€Ÿà€¹à¥à€€à¥ à€ªà€Ÿà€¹à€€à€Ÿ à€¯à¥à€€à¥. 
+}  
+
+_textgoto_ [l=mr] {à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€° à€à€Ÿ}  
+_textintro_ [l=mr] {à€ªà¥à€°à€Ÿà€¥à€®à€¿à€ à€®à€à€à¥à€°}  
+
+_textCONTINUE_ [l=mr] {à€ªà¥à€¢à¥ à€à€Ÿà€¯à€à€¯?}  
+
+_textEXPANDTEXT_ [l=mr] {à€®à€à€à¥à€° à€µà€¿à€žà€°}  
+
+_textCONTRACTCONTENTS_ [l=mr] {à€
+à€šà¥à€à¥à€°à€®à€£à€¿à€à€Ÿ à€žà€à€à¥à€·à€¿à€€ à€à€°à€Ÿ}  
+
+_textDETACH_ [l=mr] {à€µà€¿à€¯à¥à€à¥à€€ à€à€°à€Ÿ}  
+
+_textEXPANDCONTENTS_ [l=mr] {à€
+à€šà¥à€à¥à€°à€®à€£à€¿à€à€Ÿ à€µà€¿à€žà¥à€€à€Ÿà€°à€Ÿà€šà¥ à€¬à€à€Ÿ}  
+
+_textCONTRACT_ [l=mr] {à€®à€à€à¥à€° à€žà€à€à¥à€·à€¿à€ªà¥à€€ à€à€Ÿ}  
+
+_textHIGHLIGHT_ [l=mr] {à€ à€³à€ à€à€°à€Ÿ}  
+
+_textNOHIGHLIGHT_ [l=mr] {à€ à€³à€ à€šà€à¥}  
+
+_textPRINT_ [l=mr] {à€ªà¥à€°à€€ }  
+
+_textnextsearchresult_ [l=mr] {à€ªà¥à€¢à¥à€² à€¶à¥à€§}  
+_textprevsearchresult_ [l=mr] {à€à€§à¥à€à¥ à€¶à¥à€§}  
+
+# macros for printing page
+_textreturnoriginal_ [l=mr] {à€®à¥à€³ à€ªà€Ÿà€šà€Ÿà€µà€° à€à€Ÿ}  
+_textprintpage_ [l=mr] {à€¹à¥ à€ªà€Ÿà€š à€ªà¥à€°à€¿à€à€ à€à€°à€Ÿ}  
+_textshowcontents_ [l=mr] {à€®à€à€à¥à€° à€Šà€Ÿà€à€µà€Ÿ}  
+_texthidecontents_ [l=mr] {à€
+à€šà¥à€à¥à€°à€®à€£à€¿à€à€Ÿ à€Šà€Ÿà€à€µà¥ à€šà€à€Ÿ}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=mr] {à€à€° (_thislast_,results _thisfirst_ - _thislast_ for query: _cgiargq_,No matches for query: _cgiargq_)}  
+_textnoquerytitle_ [l=mr] {à€¶à¥à€§ à€ªà€Ÿà€š }  
+
+_textsome_ [l=mr] {à€à€Ÿà€¹à¥}  
+_textall_ [l=mr] {à€žà€°à¥à€µ}  
+_textboolean_ [l=mr] {à€¬à¥à€²à€¿à€¯à€š}  
+_textranked_ [l=mr] {à€à€³à¥à€€}  
+_textnatural_ [l=mr] {à€šà¥à€žà€°à¥à€à€¿à€}  
+_textsortbyrank_ [l=mr] {à€žà€à€¬à€à€§à€¿à€€ à€à¥à€°à€®à€Ÿà€à€}  
+_texticonsearchhistorybar_ [l=mr] {à€¯à€Ÿ à€ªà¥à€°à¥à€µà¥à€à¥ à€¶à¥à€§}  
+
+_textifeellucky_ [l=mr] {à€®à¥ à€­à€Ÿà€à¥à€¯à€µà€Ÿà€š à€à€¹à¥.}  
+
+#alt text for query buttons
+_textusequery_ [l=mr] {à€¹à€Ÿ à€ªà¥à€°à€¶à¥à€š à€µà€Ÿà€ªà€°à€Ÿ.}  
+_textfreqmsg1_ [l=mr] {à€¶à€¬à¥à€Š à€žà€à€à¥à€¯à€Ÿ:}  
+_textpostprocess_ [l=mr] {à€à€° (_quotedquery_,<br><i>post-processed to find _quotedquery_</i>
+)}  
+_textinvalidquery_ [l=mr] {à€ªà¥à€°à€¶à¥à€°à€Ÿà€à¥ à€µà€Ÿà€à¥à€¯à€°à€à€šà€Ÿ à€šà€¿à€°à¥à€ªà€¯à¥à€à¥ à€à€¹à¥}  
+_textstopwordsmsg_ [l=mr] {à€¯à€Ÿ à€žà€à€à¥à€à€Ÿ à€žà€Ÿà€®à€Ÿà€šà¥à€¯ à€à€¹à¥à€€}  
+_textlucenetoomanyclauses_ [l=mr] {à€ à€°à€Ÿà€µà€¿à€ à€žà€à€à¥à€à¥à€à€Ÿ  à€µà€Ÿà€ªà€° à€à€°à¥à€š à€¶à¥à€§ à€à¥à€¯à€Ÿ}  
+
+_textmorethan_ [l=mr] {à€¯à€Ÿà€ªà¥à€à¥à€·à€Ÿ à€à€Ÿà€žà¥à€€}  
+_textapprox_ [l=mr] {à€à¥à€¯à€Ÿà€µà€¿à€·à€¯à¥}  
+_textnodocs_ [l=mr] {à€à¥à€£à€€à¥à€¹à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€ªà¥à€°à€¶à¥à€šà€Ÿà€¶à¥ à€à¥à€³à€²à¥ à€šà€Ÿà€¹à¥à€€}  
+_text1doc_ [l=mr] {à¥§ à€ªà¥à€°à€¶à¥à€°à€Ÿà€¶à¥ à€à¥à€³à€²à¥à€²à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯ }  
+_textlotsdocs_ [l=mr] {à€ªà¥à€°à€¶à¥à€°à€Ÿà€¶à¥ à€à¥à€³à€²à¥à€²à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯}  
+_textmatches_ [l=mr] {à€à¥à€³à€£à€Ÿà€°à€Ÿ}  
+_textbeginsearch_ [l=mr] {à€¶à¥à€§à€£à¥à€¯à€Ÿà€ž à€žà¥à€°à€µà€Ÿà€€ à€à€°à€Ÿ.}  
+_textrunquery_ [l=mr] {à€ªà¥à€°à€¶à¥à€šà€Ÿà€à¥ à€à€€à¥à€€à€° à€¶à¥à€§à€Ÿ}  
+_textclearform_ [l=mr] {à€ªà¥à€šà€°à¥à€²à¥à€à€š}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=mr] {à€¶à€¬à¥à€Š à€à€¿à€à€µà€Ÿ à€µà€Ÿà€à¥à€ªà¥à€°à€à€Ÿà€° / à€µà€Ÿà€à¥à€¯à€Ÿà€à€¶
+
+}  
+_textinfield_ [l=mr] {à€à¥à€·à¥à€€à¥à€°à¥}  
+_textfoldstem_ [l=mr] {à€¥à€Ÿà€à€¬à€µà€Ÿ}  
+
+_textadvquery_ [l=mr] {à€à€¿à€à€µà€Ÿ à€žà€°à€³ à€ªà¥à€°à€¶à¥à€š à€²à€¿à€¹à€Ÿ}  
+_textallfields_ [l=mr] {à€žà€°à¥à€µ à€à¥à€·à¥à€€à¥à€°à¥}  
+_texttextonly_ [l=mr] {à€«à€à¥à€€ à€®à€à€à¥à€°}  
+_textand_ [l=mr] {à€à€£à€¿}  
+_textor_ [l=mr] {à€à€¿à€à€µà€Ÿ}  
+_textandnot_ [l=mr] {à€à€£à€¿ à€šà€Ÿà€¹à¥}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+# the space after "level" (before the right bracket) is required, otherwise no space between "Search" and "in"
+
+_textsimplesearch_ [l=mr] {à€¶à¥à€§à€Ÿ in _indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ sorting results by _sfselection_) à€à¥ _querytypeselection_ of the words}  
+
+_textadvancedsearch_ [l=mr] {à€¶à¥à€§à€Ÿ in _indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level )_If_(_nselection_, in _nselection_ language) using _querytypeselection_ query}  
+
+_textadvancedmgppsearch_ [l=mr] {à€¶à¥à€§à€Ÿ in _indexselection__If_(_jselection_, associated with _jselection_)_If_(_gselection_, at _gselection_ level )_If_(_nselection_, in _nselection_ language), à€à€£à€¿ à€šà€¿à€à€Ÿà€² à€Šà€°à¥à€¶à€µà€Ÿ  _formquerytypeadvancedselection_ order, à€à¥à€°à€®à€Ÿà€£à¥}  
+
+_textadvancedlucenesearch_ [l=mr] {à€¶à¥à€§à€Ÿ _à€šà€¿à€°à¥à€Šà¥à€¶à€šà€¿à€µà€¡ _ _à€à€°__(_jselection_, of _jselection_)_If_(_gselection_, at _gselection_ level)_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ sorting results by _sfselection_\,) for }  
+
+# the space after "Search" is required, otherwise no space between "Search" and "in"
+
+_textformsimplesearch_ [l=mr] {à€¶à¥à€§à€Ÿ _If_(_jselection_, in _jselection_)_If_(_gformselection_, at _gformselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\, sorting results by _sfselection_\,) à€žà€Ÿà€ à¥ _formquerytypesimpleselection_ à€à¥}  
+
+_textformadvancedsearchmgpp_ [l=mr] {à€¶à¥à€§à€Ÿ _If_(_jselection_, in _jselection_)_If_(_gformselection_, at _gformselection_ level )_If_(_nselection_, in _nselection_ language), and display results in _formquerytypeadvancedselection_ order, for}  
+
+_textformadvancedsearchlucene_ [l=mr] {à€¶à¥à€§à€Ÿ _If_(_jselection_, in _jselection_)_If_(_gformselection_, at _gformselection_ level )_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\, sorting results by _sfselection_\,) à€žà€Ÿà€ à¥}  
+
+_textnojsformwarning_ [l=mr] {à€žà¥à€à€šà€Ÿà€à€à€Ÿà€µà€Ÿà€žà¥à€à¥à€°à€¿à€ªà¥à€ à€€à¥à€®à€à¥à€¯à€Ÿ à€¬à¥à€°à€Ÿà€à€à€° à€µà€° à€¬à€à€Š à€à€¹à¥. à€¶à¥à€§à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€«à¥à€°à¥à€® à€¹à€µà€Ÿ à€
+à€žà€²à¥à€¯à€Ÿà€ž à€à€Ÿà€µà€Ÿà€žà¥à€à¥à€°à€¿à€ªà¥à€ à€žà¥à€°à¥ à€à€°à€Ÿ.}  
+_textdatesearch_ [l=mr] {à€¹à€Ÿ à€®à€Ÿà€¹à€¿à€€à¥à€žà€Ÿà€ à€Ÿ à€µà€¿à€¶à€¿à€·à¥à€  à€€à€Ÿà€°à€à¥ à€ªà€Ÿà€žà¥à€š à€µà€¿à€¶à€¿à€·à¥à€  à€€à€Ÿà€°à€à¥ à€ªà€°à¥à€¯à€à€€ à€¶à¥à€§à€€à€Ÿ à€¯à¥à€€à¥.  à€¹à€Ÿ à€¶à¥à€§ à€à€à¥à€à€¿à€ à€à€¹à¥.}  
+_textstartdate_ [l=mr] {à€žà¥à€°à¥à€µà€Ÿà€€ (à€à€¿à€à€µà€Ÿ à€«à€à¥à€€) à€€à€Ÿà€°à¥à€}  
+_textenddate_ [l=mr] {à€¶à¥à€µà€à€à¥ à€€à€Ÿà€°à¥à€ / à€€à€Ÿà€°à€à¥ à€ªà€°à¥à€¯à€à€€ }  
+_textbc_ [l=mr] {à€¬à¥.à€žà¥.à€.}  
+_textad_ [l=mr] {à€à¥à€®à€š à€à€°à€Ÿ}  
+_textexplaineras_ [l=mr] {à€žà¥.à€ à€µ à€¬à¥.à€žà¥.à€ à€¯à€Ÿ à€žà€à€à¥à€à€Ÿ à€.à€¡à¥. à€µ à€¬à¥.à€žà¥. à€à€°à¥à€€à€Ÿ à€à€ªà€¯à¥à€à€²à¥à€¯à€Ÿ à€à€¹à¥à€€.à€¯à€Ÿà€à€Ÿ à€
+à€°à¥à€¥ "à€à¥à€®à€š à€à€°à€Ÿ" à€µ "à€à¥à€®à€š à€à€°à€Ÿà€à¥à€¯à€Ÿ à€à€§à¥"}  
+
+_textstemon_ [l=mr] {à€¶à€¬à¥à€Šà€Ÿà€à€à€Ÿ à€¶à¥à€µà€à€à€Ÿ à€­à€Ÿà€ à€Šà¥à€°à¥à€²à€à¥à€·à€¿à€€ à€à€°à¥à€š}  
+
+_textsearchhistory_ [l=mr] {à€¯à€Ÿ à€ªà¥à€°à¥à€µà¥à€à¥ à€¶à¥à€§}  
+
+#text macros for search history
+_textnohistory_ [l=mr] {à€®à€Ÿà€à€à¥ à€¶à¥à€§à€Ÿà€®à€§à¥à€¯à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€šà€Ÿà€¹à¥à€€}  
+_texthresult_ [l=mr] {à€šà€¿à€à€Ÿà€²}  
+_texthresults_ [l=mr] {à€šà€¿à€à€Ÿà€²}  
+_texthallwords_ [l=mr] {à€žà€°à¥à€µ à€žà€à€à¥à€à€Ÿ}  
+_texthsomewords_ [l=mr] {à€à€Ÿà€¹à¥ à€¶à€¬à¥à€Š}  
+_texthboolean_ [l=mr] {à€¬à¥à€²à€¿à€¯à€š}  
+_texthranked_ [l=mr] {à€à€³à¥à€€}  
+_texthcaseon_ [l=mr] {à€žà€à€à¥à€à€Ÿ à€à¥à€³à€²à¥à€¯à€Ÿ à€ªà€Ÿà€¹à€¿à€à¥à€€.}  
+_texthcaseoff_ [l=mr] {à€à¥à€žà€«à¥à€²à¥à€¡}  
+_texthstemon_ [l=mr] {à€¥à€Ÿà€à€¬à€µà€Ÿ}  
+_texthstemoff_ [l=mr] {à€¥à€Ÿà€à€¬à€µà¥ à€šà€à€Ÿ}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=mr] {à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯à€à¥à€°à€® à€šà€¿à€¶à¥à€à€¿à€€ à€à¥à€²à¥à€²à€Ÿ à€à€¹à¥.à€®à¥à€¹à€£à¥à€š à€¬à¥à€°à€Ÿà€à€à€° à€µà€°à¥à€² à€¬à¥
+à€ à€¹à¥à€¯à€Ÿ à€¬à€à€£à€Ÿà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à¥ à€à€à¥à€žà¥à€ž à€¬à€Ÿà€° à€µà€°à¥à€² à€¬à€à€š à€Šà€Ÿà€¬à€Ÿ}  
+_textsetprefs_ [l=mr] {à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯ à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à€Ÿ}  
+_textsearchprefs_ [l=mr] {à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯ à€šà€¿à€¶à¥à€à€¿à€€à¥}  
+_textcollectionprefs_ [l=mr] {à€žà€à€à¥à€°à€¹ à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯ }  
+_textpresentationprefs_ [l=mr] {à€žà€Ÿà€Šà€°à¥à€à€°à€£à€Ÿà€à€Ÿ à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯à€à¥à€°à€®}  
+_textpreferences_ [l=mr] {à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯}  
+_textcasediffs_ [l=mr] {(not applicable in marathi)}  
+_textignorecase_ [l=mr] {(not applicable in marathi)}  
+_textmatchcase_ [l=mr] {à€®à€°à€Ÿà€ à¥à€®à€§à¥à€¯à¥ à€¯à¥à€€ à€šà€Ÿà€¹à¥.}  
+_textwordends_ [l=mr] {à€
+à€à€€à¥à€¯à€Ÿà€à¥à€·à€° / à€¶à¥à€µà€à€à€Ÿ à€¶à€¬à¥à€Š}  
+_textstem_ [l=mr] {à€¶à€¬à¥à€Šà€Ÿà€à€à€Ÿ à€¶à¥à€µà€à€à€Ÿ à€­à€Ÿà€ à€Šà¥à€°à¥à€²à€à¥à€·à€¿à€€ à€à€°à€Ÿ}  
+_textnostem_ [l=mr] {à€žà€à€ªà¥à€°à¥à€£ à€¶à€¬à¥à€Š à€à¥à€³à€²à€Ÿ à€ªà€Ÿà€¹à€¿à€à¥}  
+_textaccentdiffs_ [l=mr] {à€à€à¥à€à€Ÿà€° à€µà¥à€à€³à¥}  
+_textignoreaccents_ [l=mr] {à€à€à¥à€à€Ÿà€° à€Šà¥à€°à¥à€²à€à¥à€·à€¿à€€ à€à€°à€Ÿ.}  
+_textmatchaccents_ [l=mr] {à€à€à¥à€à€Ÿà€° à€à¥à€³à€²à¥à€ à€ªà€Ÿà€¹à€¿à€à¥à€€.}  
+
+_textprefop_ [l=mr] {_maxdocoption_ hits with _hitsperpageoption_  à€¯à€Ÿà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à¥à€š à€à€¿à€€à€à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€à€ªà€£à€Ÿà€à€ž à€ªà€¹à€Ÿà€µà€¯à€Ÿà€à¥ à€à€¹à¥ à€€à€¿à€€à€à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€à€ªà€£ à€ªà€Ÿà€¹à¥ à€¶à€à€€à¥. }  
+_textextlink_ [l=mr] {à€¬à€Ÿà€¹à¥à€°à¥à€² à€®à€Ÿà€¹à€¿à€€à¥ à€à€Ÿà€³à¥à€¯à€Ÿà€à€¡à¥à€² à€ªà€Ÿà€šà€Ÿà€à€µà€° à€à€Ÿà€£à¥à€¯à€Ÿà€à€Ÿ à€®à€Ÿà€°à¥à€}  
+_textintlink_ [l=mr] {à€¶à¥à€§à€²à¥à€²à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯}  
+_textlanguage_ [l=mr] {à€Šà€°à¥à€¶à€šà¥ à€­à€Ÿà€·à€Ÿ:}  
+_textencoding_ [l=mr] {à€žà€à€à¥à€·à€¿à€ªà¥à€€ à€°à¥à€ªà¥à€à€°à€£}  
+_textformat_ [l=mr] {à€ªà¥à€°à€Šà€°à¥à€¶à€šà€Ÿà€à€Ÿ à€ªà¥à€°à€à€Ÿà€° à€šà€¿à€µà€¡}  
+_textall_ [l=mr] {à€žà€°à¥à€µ  }  
+_textquerymode_ [l=mr] {à€à¥à€à€¶à¥}  
+_textsimplemode_ [l=mr] {à€žà¥à€ªà¥à€¯à€Ÿ à€­à€Ÿà€·à¥à€€ à€¶à¥à€§}  
+_textadvancedmode_ [l=mr] {à€žà¥à€§à€Ÿà€°à¥à€€ à€¶à¥à€§ à€ªà€§à¥à€Šà€€à¥à€®à€§à¥à€¯à¥ à€¬à¥à€²à€¿à€¯à€šà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à€€à€Ÿ à€¯à¥à€€à¥.}  
+_textlinkinterm_ [l=mr] {à€®à€§à€²à¥à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€°à¥à€š }  
+_textlinkdirect_ [l=mr] {à€€à¥à€¯à€Ÿà€µà€° à€à€Ÿ}  
+_textdigitlib_ [l=mr] {à€¡à€¿à€à¥à€à€² à€²à€Ÿà€¯à€¬à¥à€°à€°à¥ / à€
+à€à€à¥à€à¥à€€ à€à¥à€°à€à€¥à€Ÿà€²à€¯  }  
+_textweb_ [l=mr] {à€à€Ÿà€³à¥}  
+_textgraphical_ [l=mr] {à€à€²à¥à€à¥à€¯}  
+_texttextual_ [l=mr] {à€à€¶à€¯ à€¶à¥à€§}  
+_textcollectionoption_ [l=mr] {<p>à€à€ªà€žà€à€à¥à€°à€¹à€Ÿà€žà€¹:<br>}  
+
+_textsearchtype_ [l=mr] {à€ªà¥à€°à€¶à¥à€šà€Ÿà€à¥ à€ªà€Šà¥à€Šà€€ }  
+_textformsearchtype_ [l=mr] {à€à¥à€·à¥à€€à¥à€°}  
+_textplainsearchtype_ [l=mr] {à€žà€Ÿà€§à€Ÿà€°à€£à€ªà€£à¥ à€ªà¥à€°à€¶à¥à€° à€µà€¿à€à€Ÿà€°à€£à¥à€¯à€Ÿà€à¥à€¯à€Ÿ à€ªà¥à€à¥à€à€Ÿ à€à€à€Ÿà€°}  
+_textregularbox_ [l=mr] {à€à€à€ à€°à¥à€·à€Ÿ}  
+_textlargebox_ [l=mr] {à€®à¥à€ à€Ÿ}  
+
+_textrelateddocdisplay_ [l=mr] {à€žà€à€¬à€à€§à€¿à€€ à€žà€Ÿà€¹à€¿à€€à¥à€¯à€Ÿà€à¥ à€ªà¥à€°à€Šà€°à¥à€¶à€š}  
+_textsearchhistory_ [l=mr] {à€¯à€Ÿ à€ªà¥à€°à¥à€µà¥à€à¥ à€¶à¥à€§}  
+_textnohistory_ [l=mr] {à€®à€Ÿà€à€à¥ à€¶à¥à€§ à€ªà€Ÿà€¹à€€à€Ÿ à€¯à¥à€£à€Ÿà€° à€šà€Ÿà€¹à¥à€€}  
+_texthistorydisplay_ [l=mr] {à€®à€Ÿà€à¥à€² à€¶à¥à€§à€Ÿà€à€à¥ à€ªà¥à€°à€Šà€°à¥à€¶à€š-à€®à€Ÿà€à¥à€² à€¶à¥à€§}  
+_textnohistorydisplay_ [l=mr] {à€®à€Ÿà€à€à¥ à€¶à¥à€§ à€ªà¥à€°à€Šà€°à¥à€¶à€¿à€€ à€à€°à¥ à€šà€à€Ÿ}  
+
+_textbookoption_ [l=mr] {à€ªà¥à€žà¥à€€à€ à€Šà€°à¥à€¶à€šà€¿à€¯ à€žà¥à€¥à€¿à€€à¥à€®à€§à¥à€¯à¥}  
+_textbookvieweron_ [l=mr] {à€žà¥à€°à¥}  
+_textbookvieweroff_ [l=mr] {à€¬à€à€Š}  
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=mr] {à€žà€Ÿà€¹à€¿à€€à¥à€¯à€Ÿà€à¥ à€µà€¿à€­à€Ÿà€à€£à¥ à€à€°à€Ÿ}  
+_textalsoshowing_ [l=mr] {à€Šà€°à¥à€¶à€šà€Ÿà€¥}  
+_textwith_ [l=mr] {à€žà€°à¥à€µ }  
+_textdocsperpage_ [l=mr] {à€ªà¥à€°à€€à¥à€¯à¥à€ à€ªà€Ÿà€šà€Ÿà€µà€°à¥à€² à€žà€Ÿà€¹à€¿à€€à¥à€¯ }  
+
+_textfilterby_ [l=mr] {à€žà€Ÿà€¹à€¿à€€à¥à€¯à€Ÿà€à€Ÿ à€žà€®à€Ÿà€µà¥à€¶}  
+_textall_ [l=mr] {à€žà€°à¥à€µ}  
+_textany_ [l=mr] {à€à¥à€£à€€à¥à€¹à¥}  
+_textwords_ [l=mr] {à€à¥ à€¶à€¬à¥à€Š}  
+_textleaveblank_ [l=mr] {à€žà€°à¥à€µ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€¬à€à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€¹à€Ÿ à€à¥à€à¥à€š à€°à€¿à€à€Ÿà€®à€Ÿ à€žà¥à€¡à€Ÿ}  
+
+_browsebuttontext_ [l=mr] {à€žà€Ÿà€¹à€¿à€€à¥à€¯à€Ÿà€à¥ à€µà€¿à€­à€Ÿà€à€£à¥ à€à€°à€Ÿ}  
+
+_nodata_ [l=mr] {à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€šà€Ÿà€¹à¥}  
+_docs_ [l=mr] {à€žà€Ÿà€¹à€¿à€€à¥à€¯}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=mr] {à€®à€Šà€€}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=mr] {à€Šà€žà¥à€€à€à€µà€ à€à€ à€à€ à€à€°à¥à€š à€ªà€¹à€Ÿ}  
+
+_textSearchhelp_ [l=mr] {à€žà€à€ªà¥à€°à¥à€£ à€à€¶à€¯à€Ÿà€€à¥à€² à€¶à€¬à¥à€Š à€¶à¥à€§à€Ÿà€¯à€à¥ à€
+à€žà€²à¥à€¯à€Ÿà€ž à€à€ªà€£ à€¶à¥à€§à¥ à€¶à€à€€à€Ÿ. à€¹à¥ à€žà¥à€°à€µà€Ÿà€€à¥à€à¥ à€ªà€Ÿà€š à€à€¹à¥. à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€° à€à€ªà€£ à€ªà€°à€€ à€¯à¥à€ à€¶à€à€€à€Ÿ. à€€à¥à€¯à€Ÿ à€žà€Ÿà€ à¥ ''à€¶à¥à€§à€Ÿ'' à€¹à¥ à€¬à€à€£ à€Šà€Ÿà€¬à€Ÿ.}  
+_textTohelp_ [l=mr] {à€²à¥à€¬à€² à€à¥ à€¹à¥ à€¬à€à€š à€Šà€Ÿà€¬à¥à€š à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€à¥à€·à¥à€€à¥à€°à€Ÿà€à€ªà¥à€°à€®à€Ÿà€£à¥ à€¶à¥à€§à€Ÿ}  
+_textFromhelp_ [l=mr] {_labelFrom_ button  à€¯à€Ÿ à€¬à€à€šà€Ÿà€µà¥à€Šà€Ÿà€°à¥ à€ªà¥à€°à€à€Ÿà€¶à€šà€ à€¶à¥à€§à€Ÿ}  
+_textBrowsehelp_ [l=mr] {à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€ªà€¹à€Ÿ}  
+_textAcronymhelp_ [l=mr] {à€žà€à€à¥à€·à€¿à€ªà¥à€€ à€°à¥à€ª à€¹à¥ à€¬à€à€š à€Šà€Ÿà€¬à€²à¥à€¯à€Ÿà€ž à€ªà¥à€°à€Ÿà€ªà¥à€€à€¹à¥à€£à€Ÿà€°à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€Šà€Ÿà€à€µà€Ÿ}  
+_textPhrasehelp_ [l=mr] {à€ªà¥à€°à€à€Ÿà€¶à€šà€Ÿà€€ à€
+à€žà€²à¥à€²à¥ à€µà€Ÿà€à¥à€ªà¥à€°à€à€Ÿà€° à€ªà€¹à€Ÿ}  
+
+_texthelptopicstitle_ [l=mr] {à€à€¶à€¯}  
+
+_textreadingdocs_ [l=mr] {à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€à€žà¥ à€µà€Ÿà€à€Ÿà€¯à€à¥}  
+
+_texthelpreadingdocs_ [l=mr] {<p> à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€à¥à€¯à€Ÿ  à€žà€°à¥à€µà€Ÿà€€ à€µà€° à€à€Ÿà€¹à¥ à€à€¿à€€à¥à€°à¥ à€à€¹à¥à€€. à€€à¥à€¯à€Ÿ à€µà€°à¥à€š à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€¹à€Ÿ à€²à¥à€ / à€ªà¥à€°à¥à€£ à€ªà¥à€žà¥à€€à€ / à€ªà€°à€¿à€à¥à€à¥à€Š à€
+à€¥à€µà€Ÿ à€ªà¥à€°à€¥à€® à€ªà€Ÿà€šà€Ÿà€à¥ à€à€Ÿà€¯à€Ÿà€à€¿à€€à¥à€° à€à€¹à¥ à€¹à¥ à€žà€®à€à¥à€².   à€à€Ÿà€¹à¥ à€ à€¿à€à€Ÿà€£à¥ à€
+à€šà¥à€à¥à€°à€®à€£à€¿à€à€Ÿ à€žà¥à€§à¥à€Šà€Ÿ à€à€¹à¥.  à€à€¿à€¥à¥ à€
+à€šà¥à€à¥à€°à€®à€£à€¿à€à€Ÿ à€šà€žà¥à€² à€€à¥à€¥à¥ à€à€ à€°à€¿à€à€Ÿà€®à€Ÿ à€à¥à€à¥à€š à€
+à€žà¥à€².  à€€à¥à€¯à€Ÿ à€Šà¥à€µà€Ÿà€°à¥ à€€à¥à€®à¥à€¹à¥ à€šà€µà¥à€š à€
+à€¥à€µà€Ÿ à€à€§à¥à€à¥à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€° à€à€Ÿà€ à€¶à€à€€à€Ÿ.  à€
+à€šà¥à€à¥à€°à€®à€£à€¿à€à¥à€®à€§à¥à€¯à¥ à€ à€³à€ à€
+à€à¥à€·à€°à€Ÿà€à€µà€°à¥à€š à€žà€à€ªà¥à€°à¥à€£ à€²à¥à€ à€µà€Ÿà€à€€à€Ÿ à€¯à¥à€€à¥ </p>
+
+<p>à€¯à€Ÿ à€­à€Ÿà€à€Ÿà€€à¥à€² à€²à¥à€ à€à€Ÿà€²à¥ à€à€¹à¥. à€ªà€Ÿà€šà€Ÿà€à¥à€¯à€Ÿ à€¶à¥à€µà€à¥ à€Šà€¿à€²à¥à€²à¥à€¯à€Ÿ à€¬à€£à€Ÿà€à€µà€°à¥à€š à€ªà¥à€¢à¥à€² à€
+à€¥à€µà€Ÿ à€®à€Ÿà€à¥à€² à€ªà€Ÿà€šà€Ÿà€µà€° à€à€Ÿà€€à€Ÿ à€¯à¥à€€à¥. </p>
+
+<p>à€à€Ÿà€²à¥ à€à€Ÿà€¹à¥ à€¬à€à€£à¥ à€à€¹à¥à€€. à€à€žà¥  <i>_document:textEXPANDTEXT_</i> à€¯à€Ÿ à€Šà¥à€µà€Ÿà€°à¥ à€žà€à€ªà¥à€°à¥à€£ à€²à¥à€ à€
+à€¥à€µà€Ÿ à€ªà¥à€žà¥à€€à€ à€ªà€Ÿà€¹à€€à€Ÿ à€¯à¥à€à€².  à€à€° à€ªà¥à€žà¥à€€à€ à€
+à€¥à€µà€Ÿ à€²à¥à€ à€®à¥à€  à€
+à€žà¥à€² à€€à€° à€žà€à€à€£à€à€Ÿà€²à€Ÿ à€€à¥ à€à€à€¡à€£à¥à€¯à€Ÿà€ž à€¬à€°à€Ÿà€ à€µà¥à€³ à€²à€Ÿà€à¥à€².  à€
+à€¶à€Ÿ à€µà¥à€³à¥ à€¯à€Ÿ <i>_document:textEXPANDCONTENTS_</i> à€¬à€à€£à€Ÿà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à€Ÿ.  à€žà€à€ªà¥à€°à¥à€£ à€
+à€šà¥à€à¥à€°à€®à€£à€¿à€à€Ÿ à€ªà€¹à€Ÿà€µà€¯à€Ÿà€à¥ à€
+à€žà¥à€² à€€à€° <i>_document:textDETACH_</i> à€¯à€Ÿ à€¬à€à€£à€Ÿà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à€Ÿ.  à€¯à€Ÿ à€®à¥à€³à¥ à€¬à¥à€°à€Ÿà€à€à€° à€à¥ à€šà€µà¥à€š à€µà€¿à€à€¡à¥ à€à€à€¡à€€à€Ÿ à€¯à¥à€€à¥. (à€¯à€Ÿà€à€Ÿ  à€à€ªà€¯à¥à€ à€Šà¥à€š à€²à¥à€à€Ÿà€à€®à€§à¥à€² à¥à€°à€ à€²à€à¥à€·à€Ÿà€€ à€¯à¥à€€à¥.) à€¶à¥à€µà€à¥ à€à¥à€¯à€Ÿ à€¶à€¬à¥à€Šà€Ÿà€à€µà€° à€€à¥à€®à¥à€¹à¥ à€²à¥à€à€Ÿà€à€Ÿ à€¶à¥à€§ à€à¥à€€à€²à€Ÿ à€à€¹à¥ à€€à¥ à€¶à€¬à¥à€Š à€ à€³à€ à€
+à€žà€€à¥à€².  à€€à¥ à€ à€³à€ à€žà¥à€µà€°à¥à€ªà€Ÿà€€ à€šà€à¥ à€
+à€žà€²à¥à€¯à€Ÿà€ž  <i>_document:textNOHIGHLIGHT_</i> à€¯à€Ÿ à€¬à€à€£à€Ÿà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à€Ÿ. </p
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=mr] {à€¹à€Ÿ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€à€à€¡à€Ÿ à€à€£à€¿ à€
+à€šà¥à€à¥à€°à€®à€£à€¿à€à€Ÿ à€ªà€¹à€Ÿ.}  
+_texthelpopenbook_ [l=mr] {à€¹à€Ÿ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€à€à€¡à€Ÿ/à€ªà¥à€žà¥à€€à€ à€¬à€à€Š à€à€°à€Ÿ}  
+_texthelpviewtextsection_ [l=mr] {à€®à€à€à¥à€°à€Ÿà€€à¥à€² à€¹à€Ÿ à€­à€Ÿà€ à€¬à€à€Ÿ}  
+_texthelpexpandtext_ [l=mr] {à€žà€°à¥à€µ à€®à€Ÿà€¹à€¿à€€à¥ à€¬à€à€Ÿ à€à€¿à€à€µà€Ÿ à€šà€Ÿà€¹à¥.}  
+_texthelpexpandcontents_ [l=mr] {à€
+à€šà¥à€à¥à€°à€®à€£à€¿à€à€Ÿ à€µà€¿à€žà¥à€€à€Ÿà€°à€Ÿà€šà¥ à€¬à€à€Ÿ,à€à€£à€¿ à€šà€Ÿà€¹à¥}  
+_texthelpdetachpage_ [l=mr] {à€¹à¥ à€ªà€Ÿà€š à€šà€µà€¿à€š à€à¥à€à€à¥à€€ à€à€à€¡à€Ÿ}  
+_texthelphighlight_ [l=mr] {à€¶à¥à€§à€Ÿà€µà€¯à€Ÿà€à¥ à€¶à€¬à¥à€Š à€ à€³à€ à€à€°à€Ÿ}  
+_texthelpsectionarrows_ [l=mr] {à€à€§à€¿à€à¥à€¯à€Ÿ à€à€¿à€à€µà€Ÿ à€ªà¥à€¢à¥à€² à€ªà€Ÿà€šà€Ÿà€µà€° à€à€Ÿ}  
+
+
+_texthelpsearchingtitle_ [l=mr] {à€à€µà€¶à¥à€¯à€ à€žà€à€à€Ÿ à€à€¶à€Ÿ à€¬à€à€Ÿà€µà¥à€¯à€Ÿà€€}  
+
+_texthelpsearching_ [l=mr] {<p>
+  à€¶à¥à€§à€ªà€§à¥à€Šà€€à¥ à€ªà€Ÿà€šà€Ÿ à€µà€°à¥à€š à€ªà¥à€¢à¥à€² à€ªà¥à€°à€à€Ÿà€°à¥ à€žà€Ÿà€§à¥à€¯à€Ÿ à€ªà€§à¥à€Šà€€à¥à€šà¥ à€à¥à€µà¥à€°à¥ à€€à€¯à€Ÿà€° à€à€°à€Ÿ:<p>
+
+  <ol><li>à€à€Ÿà€¯ à€¶à¥à€§à€Ÿà€¯à€Ÿà€à¥ à€€à¥ à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à€Ÿ
+      <li>à€«à€à¥à€€ à€¶à€¬à¥à€Š à€à€¿à€à€µà€Ÿ à€žà€à€ªà¥à€°à¥à€£ à€à¥à€µà¥à€°à¥
+      <li>à€à¥à€¶à¥à€§à€Ÿà€¯à€Ÿà€à¥ à€€à¥ à€à€Ÿà€à€ª à€à€°à€Ÿ
+      <li>à€à¥à€²à€¿à€ <i>à€¶à¥à€§</i> à€¬à€à€£
+  </ol>
+
+<p>à€€à¥à€®à¥à€¹à¥ à€à¥à€µà¥à€°à¥ à€€à€¯à€Ÿà€° à€à¥à€²à¥à€¯à€Ÿà€šà€à€€à€° à¥šà¥Š à€šà€Ÿà€µà¥ à€à¥à€³à€£à€Ÿà€°à¥ à€žà€Ÿà€ªà€¡à€€à¥à€².
+à€à€Ÿà€²à¥à€² à€¬à€à€šà€Ÿ à€µà¥à€Šà€Ÿà€°à¥ à€ªà¥à€¢à¥à€² à¥šà¥Š à€šà€Ÿà€µà¥ à€®à€¿à€³à€€à¥à€²  à€¯à€Ÿ à€ªà¥à€¢à¥ à€ªà¥à€¢à¥à€² à€ªà€Ÿà€šà€Ÿà€µà€° à€à€¿à€à€µà€Ÿ à€ªà¥à€°à€¥à€® à€ªà€Ÿà€šà€Ÿà€µà€° à€à€Ÿà€€à€Ÿ à€¯à¥à€à€².à€à¥à€£à€€à¥à€¯à€Ÿà€¹à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯à€Ÿà€à¥à€¯à€Ÿ à€šà€Ÿà€µà€Ÿà€µà€° à€à¥à€²à€¿à€² à€à€°à€Ÿ à€€à¥ à€Šà€¿à€žà¥à€²  
+
+<p>à€à€Ÿà€žà¥à€€à¥à€€ à€à€Ÿà€žà¥à€€ à¥«à¥Š à€²à¥à€ à€ªà€Ÿà€¹à¥  à€¶à€à€€à€Ÿ.  à€¹à€Ÿ à€šà€à€¬à€° à€€à¥à€®à¥à€¹à¥ <i>_Global:linktextPREFERENCES_</i> à€¯à€Ÿ  à€¬à€à€£à€Ÿà€Šà¥à€µà€Ÿà€°à¥ à€¬à€Šà€²à¥ à€¶à€à€€à€Ÿ. 
+}  
+
+_texthelpquerytermstitle_ [l=mr] {à€¶à€¬à¥à€Š à€¶à¥à€§à€Ÿ}  
+_texthelpqueryterms_ [l=mr] {à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€¶à¥à€§à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€à¥à€¯à€Ÿ à€žà€à€à¥à€à€Ÿà€à€à€Ÿ à€µà€Ÿà€ªà€° à€à¥à€²à€Ÿ à€à€Ÿà€€à¥ à€€à¥à€¯à€Ÿà€à€šà€Ÿ à€¶à¥à€§ à€žà€à€à¥à€à€Ÿ à€®à¥à€¹à€£à€€à€Ÿà€€.à€¯à€Ÿ à€žà€à€à¥à€à€Ÿ à€®à¥à€¹à€£à€à¥ à€µà€°à¥à€£à€Ÿà€šà¥à€à¥à€°à€® à€®à¥à€³à€Ÿà€à¥à€·à€°à¥ à€
+à€žà€€à€Ÿà€€.à€µà€¿à€°à€Ÿà€®à€à€¿à€šà¥à€¹à€Ÿà€à€à€Ÿ à€à€ªà€¯à¥à€ à€à¥à€²à¥à€¯à€Ÿà€ž à€žà€Ÿà€¹à€¿à€€à¥à€¯à€Ÿà€à€Ÿ à€¶à¥à€§ à€à¥à€€à€Ÿ à€¯à¥à€€ à€šà€Ÿà€¹à¥.  <p>à€à€Šà€Ÿà€¹à€°à€£à€Ÿà€°à¥à€¥, <p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>will be treated the same as<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>}  
+
+_texthelpmgppsearching_ [l=mr] {à€žà€à€à¥à€°à€¹ à€à€® à€à¥à€ªà¥à€ªà¥ à€šà¥ à€€à€¯à€Ÿà€° à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€ªà¥à€¢à¥à€² à€ªà€°à¥à€¯à€Ÿà€¯ à€ªà€¹à€Ÿ
+
+<ul>
+<li>A <b>*</b> à€žà€°à¥à€µ à€¶à€¬à¥à€Šà€Ÿà€à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€Ÿ <b>à€žà¥à€°à¥à€µà€Ÿà€€</b> à€€à¥ à€¶à€¬à¥à€Š, à€à€Šà€Ÿ <b>à€à¥à€®à¥à€ªà¥à€¯à¥à€*</b> à€šà¥ à€žà¥à€°à¥ à€¹à¥à€£à€Ÿà€°à¥ à€žà€°à¥à€µ à€¶à€¬à¥à€Š <b>à€à¥à€®à¥à€ªà¥à€¯à¥à€</b>.
+<li><b>/x</b> can be used to give higher weight to one or more of the query terms, eg <b>computer/10 science</b> gives computer 10 times more weight than science when ranking documents.
+</ul>
+}  
+
+_texthelplucenesearching_ [l=mr] {Lucene à€¯à€Ÿà€®à€§à¥à€¯à¥ à€žà€à€à¥à€°à€¹  à€€à€¯à€Ÿà€° à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€à€Ÿà€¹à¥ à€à€ªà¥à€¶à€šà€žà¥ à€à€¹à¥à€€.
+<ul>
+<li><b>?</b> à€à€à€Ÿ à€
+à€à¥à€·à€°à€Ÿà€à€µà€à¥ à€µà€Ÿà€à€²à¥à€¡à€à€Ÿà€°à¥à€¡ à€µà€Ÿà€ªà€°à€Ÿ. à€à€Šà€Ÿà€¹à€°à€£à€Ÿà€°à¥à€¥, <b>b?t</b> à€¯à€Ÿà€ž à€à¥à€³à¥à€² <b>bet</b>, <b>bit</b> and <b>bat</b> etc.
+<li><b>*</b> à€
+à€šà¥à€ à€
+à€à¥à€·à€°à€Ÿà€à€µà€à¥ à€µà€Ÿà€à€²à¥à€¡à€à€Ÿà€°à¥à€¡ à€µà€Ÿà€ªà€°à€Ÿ. à€à€Šà€Ÿà€¹à€°à€£à€Ÿà€°à¥à€¥ <b>comput*</b> <b>comput</b>.à€žà¥à€°à¥à€µà€Ÿà€€ à€
+à€žà€²à¥à€²à¥à€¯à€Ÿ à€žà€°à¥à€µ à€¶à€¬à¥à€Šà€Ÿà€à€šà€Ÿ à€à¥à€³à¥à€².
+</ul>
+à€¹à¥ à€Šà¥à€šà¥à€¹à¥ à€µà€Ÿà€à€²à¥à€¡à€à€Ÿà€°à¥à€¡ à€žà€à€à¥à€à¥à€à¥à€¯à€Ÿ à€®à€§à¥à€¯à€­à€Ÿà€à¥ à€µà€Ÿà€ªà€°à€Ÿ, à€à€¿à€à€µà€Ÿ à€¶à¥à€µà€à¥. à€ªà€£ à€žà€à€à¥à€à¥à€à¥à€¯à€Ÿ à€žà¥à€°à¥à€µà€Ÿà€€à¥à€²à€Ÿ à€¹à¥ à€µà€Ÿà€ªà€°à¥ à€šà€¯à¥à€€.}  
+
+_texthelpquerytypetitle_ [l=mr] {à€à¥à€à€¶à¥}  
+_texthelpquerytype_ [l=mr] {<p>à€¯à¥à€¥à¥ à€Šà¥à€š à€­à€¿à€šà¥à€š à€ªà¥à€°à€à€Ÿà€°à€à¥à€¯à€Ÿ à€¶à€à€à€Ÿ à€à€¹à¥à€€.
+
+<ul>
+  <li>à€¶à€à€à€Ÿ <b>à€žà€°à¥à€µ</b> à€à¥ à€¶à€¬à¥à€Šà€Ÿà€à€à€°à¥à€€à€Ÿ.  à€¹à¥ à€ªà¥à€°à€²à¥à€à€Ÿà€à¥ à€šà€Ÿà€µ,à€à€¿à€à€µà€Ÿ à€à¥
+à€ªà¥à€à€°à€à¥ à€šà€Ÿà€µ à€¯à€Ÿ à€®à€§à¥à€¯à¥ à€€à¥à€®à¥à€¹à¥ à€šà€¿à€¶à¥à€à€¿à€€ à€à¥à€²à¥à€²à¥ à€žà€°à¥à€µ à€¶à€¬à¥à€Š      à€¯à€Ÿ à€ªà¥à€°à€²à¥à€à€Ÿà€µà€°à¥à€² à€¶à€à€à€Ÿ à€Šà€¿à€žà€€à¥.
+<p>
+
+  <li>à€¶à€à€à€Ÿ <b>à€à€Ÿà€¹à¥</b> à€à¥ à€¶à€¬à¥à€Šà€Ÿà€à€à€°à¥à€€à€Ÿ.  à€€à¥à€®à¥à€¹à¥ à€ªà€¹à€Ÿà€€ à€
+à€žà€²à¥à€²à¥ à€à€Ÿà€¹à¥ à€¶à€¬à¥à€Š à€à¥ à€ªà¥à€°à€²à¥à€à€Ÿà€€ à€žà€®à€Ÿà€µà€¿à€·à¥à€ à€à€¹à¥à€€.  à€ªà¥à€°à€²à¥à€
+      à€žà€à¥à€à€Ÿ à€à€¶à€Ÿ à€à¥à€³à€²à¥à€¯à€Ÿ à€€à¥à€¯à€Ÿà€ªà¥à€°à€®à€Ÿà€£à¥ à€Šà€Ÿà€à€µà€€ à€à€¹à¥.  
+      <p><ul>
+        <li> the more search term occurrences a document contains, the closer it matches;
+        <li> terms which are rare in the collection as a whole are more important than common ones;
+        <li> short documents match better than long ones.
+      </ul>
+</ul>
+
+<p>Use as many search terms as you like--a whole sentence, or even a
+whole paragraph.  If you specify only
+one term, documents will be ordered by its frequency of occurrence.<p>
+}  
+
+_texthelpadvancedsearchtitle_ [l=mr] {_à¥§_ à€¯à€Ÿ à€¶à¥à€§ à€à€à€à€¿à€šà€Ÿà€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à¥à€š à€žà¥à€§à€Ÿà€°à¥à€€ à€¶à¥à€§ à€à¥à€¯à€Ÿ}  
+
+_texthelpadvancedsearch_ [l=mr] {à€à€° à€€à¥à€®à¥à€¹à¥ à€žà¥à€§à€Ÿà€°à¥à€€ à€ªà€§à¥à€Šà€€à¥à€à¥ à€šà€¿à€µà€¡ à€à¥à€²à¥ à€€à€° à€¶à¥à€§ à€ªà€§à¥à€Šà€€à¥à€€ à€¥à¥à€¡à€Ÿà€žà€Ÿ à€¬à€Šà€² à€Šà€¿à€žà¥à€š à€¯à¥à€€à¥.}  
+
+_texthelpadvsearchmg_ [l=mr] {à€à€® à€à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯à€Ÿà€à€®à€§à¥à€¯à¥ à€ªà¥à€°à€¶à¥à€šà€Ÿà€à¥ à€žà¥à€§à€Ÿà€°à¥à€€ à€ªà€§à¥à€Šà€€ à€Šà¥à€š à€ªà¥à€°à€à€Ÿà€°à¥ à€à€ªà€¯à¥à€à€Ÿà€€ à€à€£à€€à€Ÿ à€¯à¥à€€à¥.à€°à¥
+à€à€ à€µ à€¬à¥à€²à€¿à€¯à€š ....}  
+
+_texthelpbooleansearch_ [l=mr] {A <b>à€¬à¥à€²à€¿à€¯à€
+à€š</b>à€¶à¥à€§ à€ªà¥à€°à€à€Ÿà€°à€Ÿà€®à¥à€³à¥ à€à€ªà€
+à€²à¥à€¯à€Ÿà€²à€Ÿ "&" à€¯à€Ÿà€à€Ÿ à€à€ªà€£ "à€à€£à€¿" "and" à€
+à€žà€Ÿ à€µà€Ÿà€ªà€° à€à€°à¥ à€¶à€à€€à¥ à€€à€žà¥à€ "à¥€" à€¯à€Ÿ à€à€¿à€à€šà¥à€¹à€Ÿà€à€Ÿ à€à€ªà€¯à¥à€ "à€à€¿à€à€µà€Ÿ" "OR" à€®à¥à€¹à€£à¥à€š à€à€°à€€à€Ÿà€€. "!" à€¯à€Ÿà€à€Ÿ à€µà€Ÿà€ªà€° "not" à€®à¥à€¹à€£à€à¥à€ "à€šà€à¥" à€
+à€žà€Ÿ à€¹à¥à€€à¥. 
+ <p>
+à€à€Šà€Ÿ., <b>snail & farming</b>à€
+à€žà¥ à€¶à¥à€§à€²à¥ à€
+à€žà€€à€Ÿ à€à¥à€¯à€Ÿ à€²à¥à€à€Ÿà€à€®à€§à¥à€¯à¥<b> snail </> AND <b>farming</b>, à€¹à¥à€ à€¶à€¬à¥à€Š à€
+à€žà€€à¥à€² à€€à¥à€ à€²à¥à€ à€¶à¥à€§à€€à€Ÿ à€¯à¥à€€à¥à€². à€€à€žà¥à€ <b>snail | farming</b>  à€à€Ÿ à€à€ªà€¯à¥à€ à€à¥à€²à¥à€¯à€Ÿà€ž <b>snail</b> OR <b>farming</b> à€¯à€Ÿ à€Šà¥à€šà¥à€¹à¥à€®à€§à¥à€² à€à¥à€£à€€à€Ÿà€¹à¥ à€à€ à€¶à€¬à¥à€Š à€
+à€žà€²à¥à€²à¥ à€²à¥à€ à€®à€¿à€³à€€à¥à€²,  <b>snail !farming</b> à€à€Ÿ à€à€ªà€¯à¥à€ <b>snail</b> AND DO NOT contain <b>farming</b> à¥à€à¥à€€ snail à€¯à€Ÿ à€¶à€¬à¥à€Šà€Ÿà€à€Ÿ à€¶à¥à€§ 
+à€à¥à€€à€Ÿ à€¯à¥à€€à¥. <p> "AND" "OR" "NOT" à€¯à€Ÿ à€€à¥à€š à€¬à¥à€²à€¿à€¯à€š à€¶à¥à€§ à€ªà¥à€°à€à€Ÿà€°à€Ÿà€à€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à¥à€š à€¶à€¬à¥à€Šà€Ÿà€à€à¥ à€à¥à€³à€£à¥ à€à€°à¥à€š à€žà€à€à¥à€°à€¹à€Ÿà€€à¥à€² à€²à¥à€à€Ÿà€à€à€Ÿ à€¶à¥à€§ à€à¥à€€à€Ÿ à€¯à¥à€€à¥. 
+à€à€Šà€Ÿ. <b>(sheep | cattle) & (farm | station)</b>, or <b>sheep | cattle | goat !pig</b>.
+}  
+
+_texthelpadvsearchmgpp_ [l=mr] {MGPP à€žà€à€à¥à€°à€¹à€Ÿ à€®à€§à¥à€¯à¥ à€ªà¥à€°à€à€€ à€¶à¥à€§ à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€¬à¥à€²à€¿à€¯à€š à€¶à¥à€§ à€ªà¥à€°à€à€Ÿà€°à€Ÿà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à€€à€Ÿà€€.  _texthelpbooleansearch_
+<p>à€šà€¿à€à€Ÿà€² <b>ranked</b> à€
+à€¶à€Ÿ à€ªà€§à¥à€Šà€€à¥à€šà¥ à€¯à¥à€€à€Ÿà€€,  <b>some</b> search in <a href="\#query-type">_texthelpquerytypetitle_</a>, or in "natural" (or "build") order. à€žà€à€à¥à€°à€¹ à€¯à€Ÿ à€ªà¥à€°à€à€Ÿà€°à¥ à€€à€¯à€Ÿà€° à€¹à¥à€€à€Ÿà€€. 
+<p>
+à€
+à€à¥à€š <b>NEARx</b> and <b>WITHINx</b>.
+NEARx, WITHINx à€¯à€Ÿà€à€Ÿ à€µà€Ÿà€ªà€° à€Šà¥à€š à€¶à€¬à¥à€Šà€Ÿà€à€®à€§à¥à€² à€
+à€à€€à€°à€Ÿà€žà€Ÿà€ à¥ à€à€°à€€à€Ÿà€€.  (x words) 
+à¥šà¥Š à€¶à€¬à¥à€Šà€Ÿà€à€à€€à€à¥ à€
+à€à€€à€° à€
+à€žà€€à¥.  
+}  
+
+_texthelpadvancedsearchextra_ [l=mr] {à€žà¥à€à€šà€Ÿ à€žà¥à€ªà¥à€¯à€Ÿ à€­à€Ÿà€·à¥à€€ à€¶à¥à€§ à€à¥à€€à€²à€Ÿ à€€à€° à€¶à€¬à¥à€Šà€Ÿà€à€à€Ÿ à€¶à¥à€µà€à€à€Ÿ à€­à€Ÿà€ à€Šà¥à€°à¥à€²à€à¥à€·à€¿à€€ à€à€°à€Ÿ}  
+
+_texthelpadvsearchlucene_ [l=mr] {à€žà¥à€§à€Ÿà€°à¥à€€ à€ªà¥à€°à€¶à¥à€š à€ªà€§à¥à€Šà€€à¥à€€ à€¬à¥à€²à€¿à€¯à€šà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à€Ÿ}  
+
+_texthelpformsearchtitle_ [l=mr] {à€«à¥à€²à¥à€¡à¥à€¡ à€žà€°à¥à€ }  
+
+_texthelpformsearch_ [l=mr] {à€¯à€Ÿà€Šà¥à€µà€Ÿà€°à¥ à€¶à¥à€§ à€à€°à€€à€Ÿà€šà€Ÿ à€µà€¿à€µà€¿à€§ à€ªà€§à¥à€Šà€€à¥à€Šà¥à€µà€Ÿà€°à¥ à€¶à¥à€§ à€à€°à€€à€Ÿ à€¯à¥à€€à¥,à€à€Šà€Ÿà€¹à€°à€£à€Ÿà€°à¥à€¥ à€Šà€žà¥à€€à€à€µà€à€Ÿà€à¥à€¯à€Ÿ à€šà€Ÿà€µà€Ÿà€€ à€žà¥à€®à€¿à€¥  à€à€£à€¿ à€žà¥à€šà¥à€² à€«à€Ÿà€°à¥à€®à€¿à€à€ à€¹ à€€à¥à€¯à€Ÿ à€µà€¿à€·à€¯à€Ÿà€€ à€à€¹à¥.à€žà€Ÿà€§à¥à€¯à€Ÿ à€¶à¥à€§ à€ªà€§à¥à€Šà€€à¥à€®à€§à¥à€¯à¥ à€ªà¥à€°à€€à¥à€¯à¥à€ à€à€³à¥ à€¯à€Ÿ à€žà¥à€µà€€à€à€€à¥à€° à€žà€à€à¥à€à€Ÿ à€®à¥à€¹à€£à¥à€š à€¶à¥à€§ à€à¥à€²à€Ÿ à€à€Ÿà€à€²,à€¯à€Ÿ à€®à€§à¥à€¯à¥ à€à€£à€¿ à€¹à¥ à€žà€à€à¥à€à€Ÿ à€à€ªà€¯à¥à€à¥à€€ à€ à€°à¥à€².à€ªà€£ à€µà€¿à€·à¥à€¶ à€¶à¥à€§ à€ªà€§à¥à€Šà€€à¥à€®à€§à¥à€¯à¥ à€€à¥à€®à¥à€¹à€Ÿà€à€²à€Ÿ à€ à€°à€Ÿà€µà€¿à€ à€žà€à€à¥à€à€Ÿ à€¶à¥à€§à€€à€Ÿà€šà€Ÿ à€à€£à€¿ à€à€¿à€à€µà€Ÿ à€šà€Ÿà€¹à¥ à€¯à€Ÿ à€µà€¿à€¶à€¿à€·à¥à€ à€žà€à€à¥à€à€Ÿà€à€à€Ÿà€µà€Ÿà€ªà€° à€à€°à€Ÿà€µà€Ÿ à€²à€Ÿà€à¥à€².à€µà€¬à¥à€²à€¿à€¯à€šà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à€€à€Ÿ à€¯à¥à€à€².}  
+
+_texthelpformstemming_ [l=mr] {The "fold" and "stem" boxes allow you to specify whether the terms inside that field are casefolded or stemmed. These are both switched off by default for advanced form searching}  
+
+_textdatesearch_ [l=mr] {à€€à€Ÿà€°à€à€Ÿà€à€ªà¥à€°à€®à€Ÿà€£à¥ à€¶à¥à€§à€Ÿ}  
+
+_texthelpdatesearch_ [l=mr] {Date search lets you find documents that, as well as matching your search 
+terms, are about events within a certain timeframe.  You can search for 
+documents from a certain year or from a range of years.  Note that you do not 
+have to have any search terms -- you can search by date alone; and also that 
+you do not have to use dates in your search, if you do not type any dates in it
+ is just the same as if the date search didn't exist.<p>
+}  
+
+_texthelpdatehowtotitle_ [l=mr] {à€¯à€Ÿà€à€Ÿ à€à€ªà€¯à¥à€ à€à€žà€Ÿ à€à€°à€Ÿà€µà€Ÿ}  
+_texthelpdatehowto_ [l=mr] {<ul>
+   <li>à€à€ à€µà€°à¥à€·à€Ÿà€€à¥à€² à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€¶à¥à€§à€£à¥à€¯à€Ÿ à€à€°à¥à€€à€Ÿ:<p>
+   <ul>
+       <li>à€à€ à€žà€à€à¥à€à€Ÿ  à€à€Ÿà€à€ª à€à€°à€Ÿ.
+       <li>à€à€µà€¶à¥à€¯à€ à€€à¥ à€µà€°à¥à€·  "à€žà¥à€°à¥ (à€à€¿à€à€µà€Ÿ) à€Šà€¿à€šà€Ÿà€à€" à€¬à¥à€à¥à€ž.
+       <li>à€Šà€¿à€šà€Ÿà€à€ à€à€° à€à¥à€°à€¿à€žà¥à€€ à€ªà¥à€°à¥à€µ à€
+à€žà¥à€² à€€à€° à€¬à¥à€žà¥ à€ à€à€ªà¥à€¶à€š à€à¥ à€šà€¿à€µà€¡ à€à€°à€Ÿ, 
+
+   </ul>
+<p><li>à€®à€°à¥à€¯à€Ÿà€Šà€¿à€€ à€à€Ÿà€²à€Ÿà€µà€§à¥à€€à¥à€² à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€¶à¥à€§<p>
+   <ul>
+       <li>à€à€ à€žà€à€à¥à€à€Ÿ  à€à€Ÿà€à€ª à€à€°à€Ÿ
+       <li>à€à€µà€¶à¥à€¯à€ à€€à¥ à€µà€°à¥à€·  "à€žà¥à€°à¥à€µà€Ÿà€€à¥à€à¥ (à€à€¿à€à€µà€Ÿ) à€Šà€¿à€šà€Ÿà€à€" à€¬à¥à€à¥à€ž.
+       <li>à€à€µà€¶à¥à€¯à€ à€€à¥ à€µà€°à¥à€·  "à€¶à¥à€µà€à€à¥ (à€à€¿à€à€µà€Ÿ) à€Šà€¿à€šà€Ÿà€à€" à€¬à¥à€à¥à€ž.
+       <li>à€Šà€¿à€šà€Ÿà€à€ à€à€° à€à¥à€°à€¿à€žà¥à€€ à€ªà¥à€°à¥à€µ à€
+à€žà¥à€² à€€à€° à€¬à¥à€žà¥ à€ à€à€ªà¥à€¶à€š à€à¥ à€šà€¿à€µà€¡ à€à€°à€Ÿ
+
+   </ul>    
+</ul><p>
+}  
+
+_texthelpdateresultstitle_ [l=mr] {à€¯à€Ÿ à€µà€¿à€­à€Ÿà€à€Ÿà€€à¥à€² à€®à€Ÿà€¹à€¿à€€à¥ à€¶à¥à€§à€£à¥à€¯à€Ÿà€à¥ à€®à€Ÿà€°à¥à€}  
+_texthelpdateresults_ [l=mr] {<p> à¥§à¥¯à¥¯à¥© à€®à€§à¥à€² à€²à¥à€ à€
+à€¥à€µà€Ÿ à€žà€à€à¥à€°à€¹ à€¶à¥à€§à€Ÿà€¯à€à¥ à€
+à€žà€€à¥à€² à€€à€° à¥§à¥¯à¥®à¥¯ - à¥§à¥¯à¥§à¥§ à€
+à€¶à€Ÿ à€ªà¥à€°à€à€Ÿà€°à¥ à€€à€Ÿà€°à¥à€ à€¶à¥à€§ à€à¥à€à¥à€šà€Ÿà€€ à€Šà¥à€¯à€Ÿà€µà¥ à€²à€Ÿà€à€€à¥. 
+}  
+
+_textchangeprefs_ [l=mr] {à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯ à€¬à€Šà€²à€Ÿ}  
+
+_texthelppreferences_ [l=mr] {à€à¥à€µà¥à€¹à€Ÿ à€€à¥à€®à€à¥à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€°à¥à€² à€žà€°à¥à€µà€Ÿà€€ à€µà€°à€à¥ à€€à¥à€®à¥à€¹à¥ à€¹à¥ à€¬à€à€š <i>_Global:linktextPREFERENCES_</i> à€Šà€Ÿà€¬à€Ÿà€²,à€€à¥à€µà¥à€¹à€Ÿ à€€à¥à€®à¥à€¹à¥ à€€à¥à€®à€à¥à€¯à€Ÿ à€à€µà€¶à¥à€¯à€à¥à€€à¥à€šà¥à€žà€Ÿà€° à€à€à€à€°à€«à¥à€ž à€®à€§à¥à€² à€à€à€à€Ÿà€à€®à€§à¥à€¯à¥ à€¬à€Šà€² à€à€°à¥ à€¶à€à€Ÿà€².}  
+
+_texthelpcollectionprefstitle_ [l=mr] {à€žà€à€à¥à€°à€¹ à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯}  
+_texthelpcollectionprefs_ [l=mr] {à€à€à€Ÿ à€žà€à€à¥à€°à€¹à€Ÿà€®à€§à¥à€¯à¥ à€
+à€šà¥à€ à€à€ªà€žà€à€à¥à€°à€¹ à€à€¹à¥à€€,à€à¥ à€€à¥à€®à¥à€¹à¥ à€žà¥à€µà€€à€à€€à¥à€°à€ªà€£à¥ à€à€¿à€à€µà€Ÿ à€à€à€€à¥à€° à€ªà€Ÿà€¹à¥ à€¶à€à€€à€Ÿ.à€à€° à€€à€žà¥ à€ªà€¹à€Ÿà€µà€¯à€Ÿà€à¥ à€
+à€žà€€à¥à€² à€€à€° à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯ à€ªà€Ÿà€šà€Ÿà€µà€° à€à€ªà€žà€à€à¥à€°à€¹à€Ÿà€à¥ à€šà€¿à€µà€¡ à€à€°à€Ÿ}  
+
+_texthelplanguageprefstitle_ [l=mr] {à€­à€Ÿà€·à¥à€à€Ÿ à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯à€à¥à€°à€®}  
+_texthelplanguageprefs_ [l=mr] {à€ªà¥à€°à€€à¥à€¯à¥à€ à€žà€Ÿà€¹à€¿à€€à¥à€¯à€Ÿà€ž à€ à€°à€Ÿà€µà€¿à€ à€­à€Ÿà€·à€Ÿ à€à€¹à¥,à€ªà€£ à€€à¥à€®à¥à€¹à€Ÿà€à€ž à€¹à€µà¥à€¯à€Ÿ à€
+à€žà€²à¥à€²à¥à€¯à€Ÿ à€­à€Ÿà€·à¥à€®à€§à¥à€¯à¥ à€€à¥ à€€à¥à€®à¥à€¹à¥ à€ªà€Ÿà€¹à¥ à€¶à€à€€à€Ÿ,à€¯à€Ÿà€¬à€°à¥à€¬à€° à€€à¥à€®à¥à€¹à¥ à€€à¥ à€à€šà€à¥à€¡à¥à€à€ à€à€°à¥ à€¶à€à€€à€Ÿ.....}  
+
+_texthelppresentationprefstitle_ [l=mr] {à€žà€Ÿà€Šà€°à¥à€à€°à€£à€Ÿà€à¥ à€ªà¥à€°à€Ÿà€§à€Ÿà€šà¥à€¯}  
+_texthelppresentationprefs_ [l=mr] {à€ à€°à€Ÿà€µà€¿à€ à€žà€Ÿà€¹à€¿à€€à¥à€¯à€Ÿà€€à¥à€² à€žà€Ÿà€ à¥à€¯à€Ÿà€µà€° à€
+à€šà¥à€ à€ªà€§à¥à€Šà€€à¥à€µà¥à€Šà€Ÿà€°à¥ à€žà€Ÿà€Šà€°à¥à€à€°à€£à€Ÿà€µà€° à€šà€¿à€¯à€à€€à¥à€°à€£ à€®à€¿à€³à€µà€¿à€€à€Ÿ à€¯à¥à€€à¥.à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€¶à¥à€§à€š à€à€°à¥à€š à€šà€à€€à€° à€šà€µà€¿à€š à€¶à¥à€§à€Ÿ à€žà€Ÿà€ à¥ à€®à€Ÿà€à¥ à€¯à€Ÿ à€¬à€à€£à€Ÿà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à€Ÿà€µà€Ÿ}  
+
+_texthelpsearchprefstitle_ [l=mr] {à€ªà€Ÿà¥à€°à€§à€Ÿà€šà¥à€¯ à€¶à¥à€§à€Ÿ}  
+_texthelpsearchprefs_ [l=mr] {<p> à€€à¥à€®à¥à€¹à¥ âà€ªà¥à€°à€à€€ à€žà€à€à¥à€à€Ÿâ à€¶à¥à€§ à€µà€Ÿà€ªà€°à¥ à€¶à€à€€à€Ÿ.  à€€à¥à€¯à€Ÿà€Šà¥à€µà€Ÿà€°à¥ à€€à¥à€®à¥à€¹à¥ à€Šà¥à€š à€à€¿à€à€µà€Ÿ à€
+à€§à€¿à€ à€žà€à€à¥à€à€Ÿ à€à€Ÿà€²à¥à€² à€à€¿à€à€šà¥à€¹à€Ÿà€à€à¥à€¯à€Ÿ à€žà€¹à€Ÿà€¯à¥à€¯à€Ÿà€šà¥ à€à¥à€¡à¥ à€¶à€à€€à€Ÿ. à€à€¿à€šà¥à€¹à€Ÿà€à€à€Ÿ à€
+à€°à¥à€¥ à€
+à€žà€Ÿ : & - and (à€à€£à€¿) ; à¥€ - OR - (à€à€¿à€à€µà€Ÿ) ; ! - Not (à€šà€Ÿà€¹à¥). à€¯à€Ÿ à€®à¥à€³à¥ à€€à¥à€®à€à€Ÿ à€¶à¥à€§ à€
+à€§à€¿à€ à€ªà¥à€°à€­à€Ÿà€µà¥ à€¹à¥à€€à¥. <p> à€à€ªà€²à¥ à€¶à¥à€§ à€ªà€žà€à€€à¥ à€šà€¿à€µà€¡à€Ÿ <p> à€¶à€¬à¥à€Šà€¬à€Šà€²à€Ÿà€à¥ à€ªà€žà€à€€à¥ à€šà€¿à€µà€¡à€Ÿ <p>à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€à€€à¥à€€à€Ÿà€ªà€°à¥à€¯à€à€€ à€à¥à€²à¥à€²à¥à€¯à€Ÿ à€ªà¥à€°à€¶à€Ÿà€à€à¥à€¯à€Ÿ à€¶à¥à€§à€Ÿà€à€à¥ à€¯à€Ÿà€Šà¥ à€¹à€µà¥ à€
+à€žà€²à¥à€¯à€Ÿà€ž "Search History" "à€¶à¥à€§à€Ÿà€à€à€Ÿ à€à€€à€¿à€¹à€Ÿà€ž" à€¯à€Ÿ à€¬à€à€£à€Ÿà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à€€à€Ÿ à€¯à¥à€€à¥.  à€šà€µà¥à€š à€¶à¥à€§ à€à€°à€€à€Ÿà€šà€Ÿ à€¯à€Ÿà€à€Ÿ à€à€ªà€¯à¥à€ à€¹à¥à€€à¥.  à€€à¥à€®à€à¥à€¯à€Ÿ à€ªà¥à€°à€¶à€Ÿà€à€à¥à€¯à€Ÿ à€à€€à¥à€€à€°à€Ÿà€à€à¥à€¯à€Ÿ à€šà€à€¬à€°à€Ÿà€µà€°à€€à¥ à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€€à€Ÿà€¬à€Ÿ à€ à¥à€µà€€à€Ÿ à€¯à¥à€€à¥.      }  
+
+_textcasefoldprefs_ [l=mr] {"_preferences:textignorecase_" à€¹à¥ à€¬à€à€š à€¶à¥à€§à€žà€à€à¥à€à€Ÿ à€à€à€®à¥à€à€Ÿà€à€ž à€à¥à€³à€€à€Ÿà€€ à€à€¿à€à€µà€Ÿ à€šà€Ÿà€¹à¥à€¹à¥ à€ªà€Ÿà€¹à€€à¥.
+<i>snail farming</i> à€µ <i>SNAIL FARMING</i> à€
+à€¶à€Ÿ à€µà€¿à€­à€¿à€šà¥à€š à€ªà¥à€°à€à€Ÿà€°à¥ à€²à€¿à€¹à¥à€²à¥à€²à¥à€¯à€Ÿ à€Šà¥à€šà¥à€¹à¥ à€žà€à€à¥à€à€Ÿ à€¶à¥à€§ à€à¥à€€à€Ÿà€šà€Ÿ à€µà€¿à€à€Ÿà€°à€Ÿà€€ à€à¥à€€à€²à¥à€¯à€Ÿ à€à€Ÿà€€à€Ÿà€€.}  
+_textstemprefs_ [l=mr] {à€¯à€Ÿ à€Šà¥à€š à€¬à€à€šà€Ÿà€à€Šà¥à€µà€°à¥à€žà€à€à¥à€à€Ÿ à€¶à¥à€§à€Ÿà€µà€° à€šà€¿à€¯à€à€€à¥à€°à€£ à€®à€¿à€³à€µà€¿à€€à€Ÿ à€¯à¥à€€à¥.}  
+_textaccentfoldprefs_ [l=mr] {à€¯à€Ÿ à€¬à€à€šà€Ÿà€à€µà¥à€Šà€Ÿà€°à¥ à€¶à¥à€§ à€à¥à€€à€Ÿà€šà€Ÿ accented and unaccented à€¶à€¬à¥à€Š à€à¥à€³à€²à¥ à€à€¿à€à€µà€Ÿ à€šà€Ÿà€¹à¥ à€€à¥ à€žà€®à€à¥ à€¶à€à€€à¥.à€à€Šà€Ÿà€ if "_preferences:textignoreaccents_" is selected, <i>fÃ©dÃ©ration</i> will be treated the same as <i>fedÃ©ration</i> and <i>federation</i>.}  
+ 
+_textstemoptionsprefs_ [l=mr] {"_texthelpquerytermstitle_".à€¯à€Ÿ à€®à€§à¥à€¯à¥ à€žà€Ÿà€à€à€¿à€€à€²à¥à€²à¥ à€¶à¥à€§à€ªà€§à¥à€Šà€€à¥ à€¹à¥ à€¯à¥à€à¥à€¯ à€µ à€žà¥à€¯à¥à€žà¥à€à€° à€à€¹à¥.}  
+
+_textsearchtypeprefsplain_ [l=mr] {à€ªà¥à€°à€¶à¥à€° à€µà€¿à€à€Ÿà€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€®à¥à€ à€Ÿ à€à¥à€à¥à€š à€®à€¿à€³à¥ à€¶à€à€€à¥ à€à€Ÿ,à€€à¥à€¯à€Ÿà€®à¥à€³à¥ à€à€Ÿà€žà¥à€€ à€®à€Ÿà€¹à€¿à€€à¥à€à€Ÿ à€¶à¥à€§ à€²à€µà€à€° à€à¥à€€à€Ÿ à€¯à¥à€à€².à€¯à€Ÿà€®à¥à€³à¥ à€à€Ÿà€žà¥à€€ à€®à€Ÿà€¹à€¿à€€à¥à€žà€Ÿà€ à€Ÿ à€²à€µà€à€° à€ªà¥à€°à€Ÿà€ªà¥à€€ à€¹à¥à€ à€¶à€à¥à€².}  
+
+_textsearchtypeprefsform_ [l=mr] {à€€à¥à€®à¥à€¹à¥ à€¹à¥ à€à¥à€°à€®à€Ÿà€à€ à€¬à€Šà€²à¥ à€¶à€à€€à€Ÿ.}  
+
+_textsearchtypeprefsboth_ [l=mr] {à€€à¥à€®à¥à€¹à¥à€¶à¥à€§à€Šà¥à€š à€ªà¥à€°à€à€Ÿà€°à¥ à€à€°à¥ à€¶à€à€€à€Ÿ à€žà€Ÿà€§à¥à€¯à€Ÿ à€µ à€«à€¿à€²à¥à€¡ à€¶à¥à€§. 
+<ul>
+<li>à€žà€Ÿà€§à¥à€¯à€Ÿ à€¶à¥à€§ à€ªà€§à¥à€Šà€€à¥ à€®à€§à¥à€¯à¥ à€à€ à€à¥à€µà¥à€°à¥ à€¬à¥à€à¥à€ž à€à€¹à¥. _textsearchtypeprefsplain_</li>
+<li>à€«à¥à€²à€¿à€¡ à€¶à¥à€§ à€ªà€§à¥à€Šà€€à¥ à€®à€§à¥à€¯à¥ à€à€ à€ªà¥à€à¥à€·à€Ÿ à€à€Ÿà€žà¥à€€  à€à¥à€µà¥à€°à¥ à€¬à¥à€à¥à€ž à€à€¹à¥, à€ªà¥à€°à€€à¥à€¯à¥à€ à€à¥à€µà¥à€°à¥ à€žà€Ÿà€ à¥ à€µà¥à€à€³à€Ÿ à€¬à¥à€à¥à€ž.à€¯à€Ÿ à€®à¥à€³à¥ à€à€à€Ÿ à€µà¥à€³à¥ à€
+à€šà¥à€ à€«à¥à€²à€¿à€¡ à€®à€§à¥à€² à€žà€Ÿà€¹à€¿à€€à¥à€¯à€Ÿà€à€Ÿ à€¶à¥à€§à€à¥à€€à€Ÿ à€¯à¥à€€à¥  _textsearchtypeprefsform_ </li>
+</ul>
+}  
+
+
+
+_texttanumbrowseoptions_ [l=mr] {à€žà€à€à¥à€°à€¹à€Ÿà€€à¥à€² à€®à€Ÿà€¹à€¿à€€à¥ à€µà€¿à€µà€¿à€§ à€ªà€§à¥à€Šà€€à¥à€šà¥ à€¶à¥à€§à€€à€Ÿ à€¯à¥à€€à¥}  
+
+_textsimplehelpheading_ [l=mr] {à€žà€à€à¥à€°à€¹à€šà€Ÿà€µ à€žà€à€à¥à€°à€¹ à€à€žà€Ÿ à€¶à¥à€§à€Ÿà€µà€Ÿ}  
+
+_texthelpscopetitle_ [l=mr] {à€ªà¥à€°à€¶à¥à€šà€Ÿà€à€Ÿ à€à¥à€²à€Ÿà€žà€Ÿ}  
+_texthelpscope_ [l=mr] {à€žà€Ÿà€§à€Ÿà€°à€£à€ªà€£à¥ à€žà€à€à¥à€°à€¹à€Ÿà€®à€§à¥à€¯à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯à€Ÿà€à€Ÿ à€¶à¥à€§ à€à¥à€€à€Ÿà€šà€Ÿ à€µà€¿à€µà€¿à€§ à€šà€¿à€°à¥à€Šà¥à€¶à€Ÿà€à€à€Ÿ à€à€ªà€¯à¥à€ à€à¥à€²à€Ÿ à€à€Ÿà€€à¥ à€à€žà¥ à€à¥à€°à€à€¥à€šà€Ÿà€®,à€à¥à€°à€à€¥à€à€Ÿà€° ,à€à€€à¥à€¯à€Ÿà€Šà€¿.
+à€à¥à€£à€€à¥à€¯à€Ÿ à€šà€¿à€°à¥à€Šà¥à€¶à€Ÿà€à€à€Ÿ à€à€ªà€¯à¥à€ à€à¥à€²à€Ÿ,à€¯à€Ÿà€µà€° à€à¥à€³à€£à€Ÿà€°à¥ à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€®à€¿à€³à¥ à€¶à€à€€à€Ÿà€€.
+à€à€° à€žà€Ÿà€¹à€¿à€€à¥à€¯ à€¹à€Ÿ à€à€à€Ÿà€Šà€Ÿ à€à¥à€°à€à€¥ à€
+à€žà¥à€² à€€à€°,à€€à¥ à€¯à¥à€à¥à€¯ à€à€Ÿà€à¥ à€®à€¿à€³à€€à¥.}  
Index: /gsdl/stable/macros/marathi2.dm
===================================================================
--- /gsdl/stable/macros/marathi2.dm	(revision 20131)
+++ /gsdl/stable/macros/marathi2.dm	(revision 20131)
@@ -0,0 +1,1026 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Language text and icon macros 
+# -- this file contains text that is of less importance
+######################################################################
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=mr] {à€Šà€žà¥à€€à€à€µà€}  
+_lastupdate_ [l=mr] {à€¶à¥à€µà€à¥ à€
+à€Šà¥à€Šà€¯à€Ÿà€µà€€ à€à¥à€²à¥à€²à¥}  
+_ago_ [l=mr] {à€¯à€Ÿ à€à¥à€°à€à€¥ à€žà€Ÿà€ à¥à€¯à€Ÿà€à¥ à€€à€Ÿà€°à¥à€}  
+_colnotbuilt_ [l=mr] {à€žà€à€à¥à€°à€¹ à€šà€Ÿà€¹à¥}  
+
+### taken from here
+
+_textpoem_ [l=mr] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>may peace and calmness surround you,
+<br>may you reside in the warmth of a summer's haze,
+<br>may the ocean of your travels be as smooth as the polished greenstone.
+}  
+
+_textgreenstone_ [l=mr] {<p>à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¹à€Ÿ à€
+à€®à¥à€²à¥à€¯ à€
+à€žà€Ÿ à€¹à€¿à€°à€µà€Ÿ à€Šà€à€¡ à€
+à€žà¥à€š à€€à¥ à€šà¥à€¯à¥à€à¥à€²à€à€¡ à€®à€§à¥à€¯à¥ à€žà€Ÿà€ªà€¡à€€à¥. à€ªà€Ÿà€°à€à€ªà€Ÿà€°à€¿à€ à€®à€Ÿà€à€°à¥ à€à€®à€Ÿà€€à¥à€®à€§à¥à€¯à¥ à€€à¥ à€à¥à€ª à€à€¿à€®à€€à¥à€à€Ÿ à€à€¹à¥ à€€à€žà¥à€ à€à¥à€ª à€ªà¥à€°à€¯à€€à¥à€šà€Ÿà€šà¥ à€€à¥ à€žà€Ÿà€ªà€¡à€€à¥.  à€¯à€Ÿ à€Šà€à€¡à€Ÿà€®à€§à¥à€¯à¥ <i>à€µà¥à€¯à€Ÿà€°à¥à€ </i> 
+à€
+à€žà¥à€š à€€à¥ à€à€¯à¥à€·à¥à€¯ à€à¥à€€à€šà¥à€¯à€®à€¯ à€à€°à€€à¥. à€à€£à€¿ à€®à¥à€¹à€£à¥à€šà€ à€€à¥à€¯à€Ÿà€à¥ à€žà€Ÿà€°à¥à€µà€à€šà€¿à€ à€
+à€šà¥à€à¥à€à¥à€€ à€à¥à€°à€à€¥à€Ÿà€²à€¯à€Ÿà€à¥ à€¬à¥à€§ à€à€¿à€šà¥à€¹ à€à€°à€£à¥à€¯à€Ÿà€€ à€à€²à¥ à€à€¹à¥. 
+à€€à¥à€¯à€Ÿà€à¥ à€à€®à€ à€Šà€Ÿà€šà€¶à¥à€°à€€à€Ÿ à€Šà€°à¥à€¶à€µà€€à¥, à€ªà€Ÿà€°à€Šà€°à¥à€¶à€à€€à€Ÿ à€à€°à¥à€ªà€£à€Ÿ, à€à€£à€à€°à€€à€Ÿ à€§à¥à€à€ªà€£à€Ÿ à€€à€žà¥à€ à€€à¥à€¯à€Ÿà€à€Ÿ à€à¥à€à€Šà€Ÿà€°à€ªà€£à€Ÿ à€šà¥à€¯à€Ÿà€¯ à€Šà€°à¥à€¶à€µà€€à¥. 
+à€¯à€Ÿ à€ªà¥à€°à€à€²à¥à€ªà€Ÿà€€à¥à€² à€à€à€Ÿ à€žà€Šà€žà¥à€¯à€Ÿà€²à€Ÿ à€€à¥à€¯à€Ÿà€à¥à€¯à€Ÿ à€µà€à€¶à€à€Ÿà€à€à€¡à¥à€š à€®à€¿à€³à€Ÿà€²à¥à€²à€Ÿ à€à¥à€°à€²à¥à€²à€Ÿ à€¹à€¿à€°à€µà¥à€¯à€Ÿ à€Šà€à€¡à€Ÿà€à€Ÿ à€€à¥à€à€¡à€Ÿ "à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€
+à€šà¥à€à¥à€à¥à€€ à€žà€à€à€£à€ à€ªà¥à€°à€£à€Ÿà€²à¥ à€®à€§à¥à€¯à¥ à€µà€Ÿà€ªà€°à€²à€Ÿ à€à€¹à¥.  
+à€¯à€Ÿà€à€Ÿ à€¯à¥à€Šà¥à€§à€Ÿà€€ à€
+à€à¥à€ à€ªà€Šà¥à€§à€€à¥à€šà¥ à€µà€Ÿà€ªà€° à€à€°à€€à€Ÿà€€. à€€à¥à€¯à€Ÿà€ à€ªà¥à€°à€à€Ÿà€°à€à¥ à€žà¥à€à€Ÿà€à€Ÿà€€à¥à€®à€ à€à¥à€£ à€¯à€Ÿ à€žà€à€à€£à€ à€ªà¥à€°à€£à€Ÿà€²à¥ à€®à€§à¥à€¯à¥ à€à€®à¥à€¹à¥ à€µà€Ÿà€ªà€°à€²à¥ à€à€¹à¥à€€. à€€à¥ à€šà€µà¥à€š à€€à€Ÿà€à€€à¥à€°à€¿à€ à€ªà€§à¥à€Šà€€à¥à€à¥ à€žà¥à€à€ à€à€¹à¥. 
+.</p>
+}  
+
+_textaboutgreenstone_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¹à¥ à€žà¥à€«à¥à€à€µà¥à€
+à€°à€µà¥à€Šà€Ÿà€°à¥ à€à€¹à¥ à€à¥ à€à¥à€¯à€Ÿ à€®à€§à¥à€¯à¥ à€€à¥à€®à¥à€¹à¥ à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à¥à€š à€µà€¿à€€à€°à¥à€€ à€à€°à¥ à€¶à€à€€à€Ÿ.à€¯à€Ÿà€®à¥à€³à¥ à€®à€Ÿà€¹à€¿à€€à¥à€à¥ à€šà€µà¥à€š à€ªà¥à€°à€à€Ÿà€°à¥ à€®à€Ÿà€à€¡à€£à¥ à€à€°à¥à€š à€€à¥ à€à€à€à€°à€šà¥à€ à€à€¿à€à€µà€Ÿ à€žà¥à€¡à¥à€°à¥à€® à€µà¥à€Šà€Ÿà€°à¥ à€ªà¥à€°à€°à¥à€Šà€¶à€¿à€€ à€à€°à¥ à€¶à€à€€à€Ÿ.à€¯à¥à€šà€¿à€°à¥à€µà¥à€¹à€žà€¿à€à¥ à€à€« à€µà¥à€¯à€à€Ÿà€€à¥ à€¯à¥à€¥à¥à€² à€šà¥à€¯à¥à€à¥à€²à€à€¡ à€¡à€¿à€à¥à€à€² à€²à€Ÿà€¯à€¬à¥à€°à€°à¥ à€ªà¥à€°à¥à€à¥à€à¥à€ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¹à¥ à€µà¥à€Šà€Ÿà€°à¥ à€ªà¥à€°à€žà€Ÿà€°à¥à€€ à€à¥à€²à¥ à€à€¹à¥
+à€à€£à€¿ à€¯à¥à€šà¥à€žà¥à€à¥à€à¥à€¯à€Ÿ à€žà€¹à€Ÿà€¯à¥à€¯à€Ÿà€šà¥  à€€à¥ à€µà€¿à€€à€°à¥à€€ à€à¥à€²à¥ à€à€¹à¥
+<i>http://greenstone.org</i> à€à€šà€°à€² à€ªà€¬à¥à€²à€¿à€ à€²à€Ÿà€¯à€žà€šà¥à€žà€à¥à€¯à€Ÿ à€
+à€à¥à€à€à€Ÿà€²à¥ 
+à€¹à¥à€¯à¥à€®à€š à€à€šà¥à€«à¥ à€à€šà€à¥à€ à€¹à¥  à€à€ªà€š à€žà¥à€°à¥à€ž à€žà¥à€«à¥à€à€µà¥à€
+à€° à€à€ªà€²à€¬à¥à€§ à€à€¹à¥
+à€¯à€Ÿ à€žà¥à€«à¥à€à€µà¥à€
+à€°à€à€Ÿ à€¹à¥à€€à¥ à€
+à€žà€Ÿ à€à¥ à€µà€¿à€Šà¥à€Šà€Ÿà€ªà¥à€ à€Ÿà€€à¥à€² à€µ à€žà€Ÿà€°à¥à€µà€à€šà€¿à€ à€à¥à€°à€à€¥à€Ÿà€²à€¯à€Ÿà€à€šà¥ à€žà¥à€µà€€à€ à€
+à€à€à€¿à€à¥à€€ à€à¥à€°à€à€¥à€Ÿà€²à€¯à€Ÿà€à€Ÿ à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à€Ÿà€µà€Ÿ
+Digital libraries are radically
+reforming how information is disseminated and acquired in UNESCO's
+partner communities and institutions in the fields of education,
+science and culture around the world, and particularly in developing
+countries. We hope that this software will encourage the effective
+deployment of digital libraries to share information and place it in
+the public domain.
+</p>
+<p>This software is developed and distributed as an international
+cooperative effort established in August 2000 among three parties.
+</p>
+
+<p>
+<a href="http://nzdl.org"><b>New Zealand Digital Library Project at the University of Waikato</b></a>
+<br>
+Greenstone software grew out of this project, and this initiative
+has been endorsed by the Communication Sub-Commission of the New
+Zealand National Commission for UNESCO as part of New Zealand's
+contribution to UNESCO's programme.
+</p>
+
+<p>
+<a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+class="logo"></a>
+<a href="http://www.unesco.org"><b>United Nations Educational, Scientific and Cultural Organization</b></a>
+<br>
+The dissemination of educational, scientific and cultural information
+throughout the world, and particularly its availability in developing
+countries, is central to UNESCO's goals as pursued within its
+intergovernmental Information for All Programme, and appropriate,
+accessible information and communication technology is seen as an important
+tool in this context.
+</p>
+
+<p>
+<a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>The Human Info NGO, based in Antwerp, Belgium</b></a>
+<br>
+This project works with UN agencies and other NGOs, and has established
+a worldwide reputation for digitizing documentation of interest to
+human development and making it widely available, free of charge to
+developing nations and on a cost-recovery basis to others.
+</p>
+
+}  
+
+
+_textdescrselcol_ [l=mr] {à€žà€à€à¥à€°à€¹ à€šà€¿à€µà€¡à€Ÿ}  
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=mr] {à€¹à¥à€®à€ªà¥à€ à€µà€° à€à€€à€° à€à€Ÿà€° à€¬à€à€š à€à€¹à¥à€€}  
+
+_textnocollections_ [l=mr] {<p>à€¯à€Ÿ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€à€à€šà€žà¥à€à¥à€µà€° à€€à¥à€¥à¥ à€à€€à¥à€€à€Ÿ à€à¥à€£à€€à€Ÿà€¹à¥ à€žà€à€à¥à€°à€¹ à€šà€Ÿà€¹à¥
+à€¯à€Ÿ à€®à€§à¥à€¯à¥ à€žà€à€à¥à€°à€¹ à€­à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ 
+<ul><li>à€µà€Ÿà€ªà€°à€Ÿ <a href="_httppagecollector_">à€žà€à€à¥à€°à€¹à€à€Ÿà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à€Ÿ</a> à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥
+    <li>à€€à¥à€®à€à¥à€¯à€Ÿà€à€¡à¥ à€žà¥à€¡à¥-à€°à¥à€® à€
+à€žà€²à¥à€¯à€Ÿà€ž à€€à¥à€¯à€Ÿà€Šà¥à€µà€Ÿà€°à¥ à€à€°à€Ÿ
+</ul>}  
+
+_text1coll_ [l=mr] {à€¯à€Ÿ à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€µà€° à¥§ à€žà€à€à¥à€°à€¹ à€à€¹à¥}  
+
+_textmorecolls_ [l=mr] {à€¹à¥à€¯à€Ÿ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€à€žà¥à€à¥à€²à¥à€¶à€šà€µà€° _à¥§_ à€žà€à€à¥à€°à€¹ à€à€¹à¥.}  
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=mr] {à€¬à€Ÿà€¹à¥à€°à€à¥ à€²à€¿à€à€}  
+_textlinknotfound_ [l=mr] {à€
+à€à€€à€°à¥à€à€€ à€²à€¿à€à€ à€žà€Ÿà€ªà€¡à€€ à€šà€Ÿà€¹à¥.}  
+
+_textextlinkcontent_ [l=mr] {<h3>à€²à€¿à€à€ "_à¥š_" à€žà€à€à¥à€°à€¹</h3>
+
+ <p> à€€à¥à€®à¥à€¹à¥ à€šà€¿à€µà€¡à€²à¥à€²à¥ à€²à€¿à€à€ à€¹à¥  "_à€žà€à€à¥à€°à€¹ à€šà€Ÿà€µà€Ÿà€à¥à€¯à€Ÿ_"à€¬à€Ÿà€¹à¥à€°à¥à€² à€à€¹à¥
+     à€žà€à€à¥à€°à€¹ (à€¹à¥ à€²à€¿à€à€ "_à¥š_"  à€žà€à€à¥à€°à€¹).
+    à€à€° à€€à¥à€®à¥à€¹à€Ÿà€à€²à€Ÿ à€¹à¥ à€²à€¿à€à€  à€žà€à€à¥à€°à€¹ "_à¥š_" à€®à€§à¥à€¯à¥ à€Šà€Ÿà€à€µà€Ÿà€¯à€à¥ à€
+à€žà¥à€² 
+     <a href="_httpdoc_&c=_à¥§_&cl=_cgiargcl_&d=_à¥©_">à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€°à¥à€š</a> à€ªà¥à€¢à¥ à€à€Ÿ ; 
+    à€à€¿à€à€µà€Ÿ à€€à¥à€®à€à¥à€¯à€Ÿ à€¬à¥à€°à€Ÿà€à€à€°à€µà€°à¥à€² "à€®à€Ÿà€à¥" à€¹à€¯à€Ÿ à€¬à€à€šà€Ÿà€µà¥à€Šà€Ÿà€°à¥ à€à€§à¥à€à¥à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€° à€¯à€Ÿ
+ }  
+
+_textlinknotfoundcontent_ [l=mr] {à€à€®à€à¥à€¯à€Ÿ à€¬à€à€§à€šà€Ÿà€®à¥à€³à¥ à€€à¥à€®à¥à€¹à¥ à€šà€¿à€µà€¡à€²à¥à€²à¥ à€²à€¿à€à€ à€ªà€¹à€Ÿà€€à€Ÿ à€¯à¥à€£à€Ÿà€° à€šà€Ÿà€¹à¥,à€à€Ÿà€°à€£ à€žà¥à€°à¥à€ž à€žà€à€à¥à€°à€¹à€Ÿà€€ à€à¥à€ à€à€¹à¥
+ à€€à¥à€®à€à¥à€¯à€Ÿ à€¬à¥à€°à€Ÿà€à€à€°à€µà€°à¥à€² "à€®à€Ÿà€à¥" à€¹à€¯à€Ÿ à€¬à€à€šà€Ÿà€µà¥à€Šà€Ÿà€°à¥ à€à€§à¥à€à¥à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€° à€¯à€Ÿ.}  
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=mr] {<h3>à€²à€¿à€à€ "_à¥š_" à€žà€à€à¥à€°à€¹</h3>
+
+ <p> à€€à¥à€®à¥à€¹à¥ à€šà€¿à€µà€¡à€²à¥à€²à¥ à€²à€¿à€à€ à€¹à¥  "_à€žà€à€à¥à€°à€¹ à€šà€Ÿà€µà€Ÿà€à¥à€¯à€Ÿ_"à€¬à€Ÿà€¹à¥à€°à¥à€² à€à€¹à¥
+     à€žà€à€à¥à€°à€¹ (à€¹à¥ à€²à€¿à€à€ "_à¥š_"  à€žà€à€à¥à€°à€¹).
+    à€à€° à€€à¥à€®à¥à€¹à€Ÿà€à€²à€Ÿ à€¹à¥ à€²à€¿à€à€  à€žà€à€à¥à€°à€¹ "_à¥š_" à€®à€§à¥à€¯à¥ à€Šà€Ÿà€à€µà€Ÿà€¯à€à¥ à€
+à€žà¥à€² 
+     <a href="_httpdoc_&c=_à¥§_&cl=_cgiargcl_&d=_à¥©_">à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€°à¥à€š</a> à€ªà¥à€¢à¥ à€à€Ÿ ; 
+    à€à€¿à€à€µà€Ÿ à€€à¥à€®à€à¥à€¯à€Ÿ à€¬à¥à€°à€Ÿà€à€à€°à€µà€°à¥à€² à€®à€Ÿà€à¥ à€¹à€¯à€Ÿ à€¬à€à€šà€Ÿà€µà¥à€Šà€Ÿà€°à¥ à€à€§à¥à€à¥à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€° à€¯à€Ÿ
+ }  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¡à€¿à€à¥à€à€² à€²à€Ÿà€¯à€¬à¥à€°à€°à¥}  
+
+_textusername_ [l=mr] {à€¯à¥à€à€°à€à¥ à€šà€Ÿà€µ}  
+_textpassword_ [l=mr] {à€ªà€Ÿà€žà€µà€°à¥à€¡ (à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š) }  
+
+_textmustbelongtogroup_ [l=mr] {à€žà¥à€à€šà€Ÿ  "_cgiargug_" à€€à¥à€®à¥à€¹à¥ à€¯à€Ÿ à€à€à€Ÿà€à¥ à€
+à€žà€²à¥à€¯à€Ÿà€žà€ à€¹à¥ à€ªà€Ÿà€š à€ªà€Ÿà€¹à¥ à€¶à€à€€à€Ÿ}  
+
+_textmessageinvalid_ [l=mr] {à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€¹à€µà¥ à€
+à€žà€²à¥à€²à¥ à€ªà€Ÿà€š à€®à€¿à€³à€µà€¿à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€ªà¥à€°à€µà¥à€¶ à€à€°à€Ÿà€µà€Ÿ.
+à€à¥à€ªà€¯à€Ÿ à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€µà€°à¥à€² à€€à¥à€®à€à¥ à€¯à¥à€à€° à€šà€Ÿà€µ à€à€£à€¿ à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š (à€ªà€Ÿà€žà€µà€°à¥à€¡) à€Šà€¯à€Ÿ.}  
+
+_textmessagefailed_ [l=mr] {à€¯à¥à€à€°à€à¥ à€šà€Ÿà€µ à€µ à€ªà€Ÿà€žà€µà€°à¥à€¡ à€
+à€¯à¥à€à¥à€¯.}  
+
+_textmessagedisabled_ [l=mr] {à€®à€Ÿà€« à€à€°à€Ÿ à€€à¥à€®à€à¥ à€à€Ÿà€€à¥ à€¬à€à€Š à€à€Ÿà€²à¥ à€à€¹à¥.à€à¥à€ªà€¯à€Ÿ à€µà¥à€¬à€®à€Ÿà€žà¥à€à€°à€¶à¥ à€žà€à€°à¥à€ªà€ à€žà€Ÿà€§à€Ÿ}  
+
+_textmessagepermissiondenied_ [l=mr] {à€®à€Ÿà€« à€à€°à€Ÿ, à€€à¥à€®à¥à€¹à€Ÿà€à€²à€Ÿ à€¹à¥ à€ªà€Ÿà€š à€µà€Ÿà€ªà€°à€£à¥à€¯à€Ÿà€à¥ à€ªà€°à€µà€Ÿà€šà€à¥ à€šà€Ÿà€¹à¥}  
+
+_textmessagestalekey_ [l=mr] {à€€à¥à€®à¥à€¹à€Ÿà€à€²à€Ÿ à€¹à€µà¥ à€
+à€žà€²à¥à€²à¥ à€²à€¿à€à€ à€à€€à¥à€€à€Ÿ  à€à¥à€šà¥ à€à€Ÿà€²à¥ à€à€¹à¥.
+à€à¥à€ªà€¯à€Ÿ à€¹à¥ à€ªà€Ÿà€š à€ªà€Ÿà€¹à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€€à¥à€®à€à¥à€¯à€Ÿ à€à¥à€£à¥à€à¥à€¯à€Ÿ à€¶à€¬à¥à€Šà€Ÿà€šà¥ à€ªà¥à€°à€µà¥à€¶ à€à€°à€Ÿ.}  
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=mr] {à€¹à¥à€¯à€Ÿ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€à€à€¹à¥ à€Šà€žà¥à€€à€à€µà€ à€šà€Ÿà€¹à¥ à€à€Ÿà€°à€£, 
+à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¹à¥ à€žà¥à€¡à¥-à€°à¥à€® à€µà€°à¥à€š à€à€šà€žà¥à€à¥à€²  à€à¥à€²à¥,
+à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¹à¥  à€à€à€à€°à€šà¥à€ à€¡à€¿à€žà¥à€à¥à€°à¥à€¬à¥à€¯à¥à€¶à€š à€®à€§à¥à€š à€à€šà€žà¥à€à¥à€² à€à¥à€²à¥,
+à€¯à€Ÿ à€ªà¥à€°à€à€Ÿà€°à€Ÿà€®à€§à¥à€¯à¥ à€€à¥à€®à¥à€¹à¥ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¹à¥ à€žà¥à€¡à¥-à€°à¥à€® à€¡à€¿à€°à¥à€à¥à€à€°à¥à€€à¥à€š à€à€¿à€à€µà€Ÿ "http://www.greenstone.org" à€¯à¥à€¥à¥à€š à€®à€¿à€³à€µà¥ à€¶à€à€€à€Ÿ.}  
+
+_textuserguide_ [l=mr] {à€¯à¥à€à€° à€Šà€°à¥à€¶à€}  
+_textinstallerguide_ [l=mr] {à€à€šà€žà¥à€à¥à€²à€° à€Šà€°à¥à€¶à€}  
+_textdeveloperguide_ [l=mr] {à€µà€¿à€à€Ÿà€žà€Ÿà€€à¥à€®à€ à€Šà€°à¥à€¶à€}  
+_textpaperguide_ [l=mr] {à€à€Ÿà€à€Šà€Ÿà€ªà€Ÿà€žà¥à€š à€žà€à€à¥à€°à€¹}  
+_textorganizerguide_ [l=mr] {à€à€°à¥à€à€šà€Ÿà€¯à€à€°à€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à€Ÿ}  
+
+_textgsdocstitle_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€Šà€žà¥à€€à€à€µà€}  
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=mr] {à€žà€à€à¥à€°à€¹ à€à€°à€Ÿ}  
+_textbildsuc_ [l=mr] {à€žà€à€à¥à€°à€¹ à€¯à€¶à€žà¥à€µà¥à€°à€¿à€€à¥à€¯à€Ÿ à€€à€¯à€Ÿà€° à€à€Ÿà€²à€Ÿ}  
+_textviewbildsummary_ [l=mr] { à€€à¥à€®à¥à€¹à¥ <a href="_httppagex_(bsummary)" target=_top></a> à€€à€¯à€Ÿà€° à€à¥à€²à¥à€²à€Ÿ à€žà€à€à¥à€°à€¹ à€ªà€¹à€Ÿ
+
+}  
+_textview_ [l=mr] {à€žà€à€à¥à€°à€¹ à€ªà€¹à€Ÿ}  
+
+_textbild1_ [l=mr] {à€žà€à€à¥à€°à€¹ à€žà€à€à€²à€¿à€€ à€¹à¥à€€ à€à€¹à¥,à€¯à€Ÿà€à€°à¥à€€à€Ÿ à€¥à¥à€¡à€Ÿ à€µà¥à€³ à€²à€Ÿà€à¥à€².à€žà€à€à€²à€š à€à€Ÿà€°à¥à€¯à€Ÿà€à¥ à€®à€Ÿà€¹à€¿à€€à¥ à€¯à€Ÿ à€à€³à¥à€µà€°à¥à€š à€žà€®à€à€€à¥}  
+
+_textbild2_ [l=mr] {à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€¹à¥à€€à€Ÿà€šà€Ÿ à€¥à€Ÿà€à€¬à€µà€¿à€£à¥à€¯à€Ÿà€ž à€¯à¥à€¥à¥ à€Šà€Ÿà€¬à€Ÿ.
+à€€à¥à€®à€à€Ÿ à€žà€à€à¥à€°à€¹ à€€à€žà€Ÿà€ à€°à€Ÿà€¹à€¿à€².
+}  
+
+_textstopbuild_ [l=mr] {à€à€à€€à¥à€° à€à€°à€£à¥ à€¥à€Ÿà€à€¬à€µà€Ÿ}  
+
+_textbild3_ [l=mr] {à€¹à¥à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€° à€€à¥à€®à¥à€¹à¥ à€¥à€Ÿà€à€¬à€²à€Ÿà€€,à€µ "à€žà¥à€à¥à€ª à€¬à€¿à€²à¥à€¡à€¿à€à€" à€¹à¥ à€¬à€à€š à€Šà€Ÿà€¬à€²à¥à€€ à€€à€° à€žà€à€à¥à€°à€¹ à€€à€žà€Ÿà€ à€°à€Ÿà€¹à€¿à€².}  
+
+_textbuildcancelled_ [l=mr] {à€ªà¥à€°à€à¥à€°à€¿à€¯à€Ÿ à€¥à€Ÿà€à€¬à€µà€Ÿ.}  
+
+_textbildcancel1_ [l=mr] {à€žà€à€à¥à€°à€¹ à€°à€Šà¥à€Š à€à¥à€²à€Ÿ à€à€¹à¥, à€¬à€Šà€² à€à€°à¥à€š  à€ªà¥à€šà¥à€¹à€Ÿ à€€à€¯à€Ÿà€° à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€ªà€¿à€µà€³à¥ à€¬à€à€š à€Šà€Ÿà€¬à€Ÿ}  
+
+_textbsupdate1_ [l=mr] {à€ªà¥à€°à€à¥à€°à€¿à€¯à€Ÿ à¥§ à€žà¥à€à€à€Šà€Ÿà€€ à€žà¥à€§à€Ÿà€°à¥à€²}  
+_textbsupdate2_ [l=mr] {à€ªà¥à€°à€à¥à€°à€¿à€¯à€Ÿ à€žà¥à€°à¥  à€à€¹à¥}  
+_textseconds_ [l=mr] {à€žà¥à€à€à€Š }  
+
+_textfailmsg11_ [l=mr] {à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à€€à€Ÿ à€¯à¥à€£à€Ÿà€° à€šà€Ÿà€¹à¥.à€¯à€Ÿà€®à€§à¥à€¯à¥ à€®à€Ÿà€¹à€¿à€€à¥à€à€Ÿ à€žà€à€à¥à€°à€¹ à€šà€Ÿà€¹à¥.à€¯à€Ÿà€à¥ à€à€Ÿà€€à¥à€°à¥ à€à€°à€Ÿ à€à¥ à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€à€Ÿà€® à€à€°à¥à€² à€
+à€¶à¥ à€à€ à€€à€°à¥ à€°à¥à€ªà€°à¥à€Šà€¶à€¿à€à€Ÿ à€à€¿à€à€µà€Ÿ à€«à€Ÿà€à€² à€à€¿à€à€µà€Ÿ à€ªà€Ÿà€š à€¯à€Ÿ à€®à€§à¥à€¯à¥ à€à€¹à¥.}  
+
+_textfailmsg21_ [l=mr] {à€žà€à€à¥à€°à€¹ à€à€à€€à¥à€° à€à€°à€€à€Ÿ à€¯à¥à€£à€Ÿà€° à€šà€Ÿà€¹à¥}  
+_textfailmsg31_ [l=mr] {à€žà€à€à¥à€°à€¹ à€à€à€€à¥à€° à€à€Ÿà€²à€Ÿ à€šà€Ÿà€¹à¥}  
+_textfailmsg41_ [l=mr] {à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€Ÿà€²à€Ÿ à€à€¹à¥ à€ªà€£ à€à€šà€žà¥à€à¥à€² à€¹à¥à€ à€¶à€à€€ à€šà€Ÿà€¹à¥}  
+_textfailmsg71_ [l=mr] {à€€à¥à€®à€à€Ÿ à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à€€à€Ÿà€šà€Ÿ à€
+à€šà€ªà¥à€à¥à€·à€¿à€€ à€à¥à€ à€à€Ÿà€²à¥ à€à€¹à¥ }  
+
+
+_textblcont_ [l=mr] {à€¬à€¿à€²à¥à€¡ à€²à¥à€ à€®à€§à¥à€¯à¥ à€à€Ÿà€²à¥à€² à€®à€Ÿà€¹à¥à€€à¥ à€à€¹à¥:}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=mr] {à€š à€¬à€Šà€²à€£à€Ÿà€°à¥ à€°à€à€šà€Ÿ}  
+_textmore_ [l=mr] {à€
+à€à¥à€š}  
+_textinfo_ [l=mr] {à€žà€à€à¥à€°à€¹à€Ÿà€à¥ à€®à€Ÿà€¹à€¿à€€à¥}  
+_textsrce_ [l=mr] {à€žà¥à€°à¥à€ž à€¡à¥à€à€Ÿ.}  
+_textconf_ [l=mr] {à€žà€à€à¥à€°à€¹ à€à¥à€šà¥à€«à€¿à€à€° à€à€°à€Ÿ.}  
+_textdel_ [l=mr] {à€žà€à€à¥à€°à€¹ à€à¥à€¡à¥à€š à€à€Ÿà€à€Ÿ}  
+_textexpt_ [l=mr] {à€žà€à€à¥à€°à€¹ à€ªà€Ÿà€ à€µà€Ÿ.}  
+
+_textdownloadingfiles_ [l=mr] {à€«à€Ÿà€à€² à€¡à€Ÿà€à€šà€²à¥à€¡ à€¹à¥à€€ à€à€¹à¥à€€.}  
+_textimportingcollection_ [l=mr] {à€žà€à€à¥à€°à€¹ à€®à€¿à€³à€µà€Ÿ...}  
+_textbuildingcollection_ [l=mr] {à€žà€à€à¥à€°à€¹ à€¬à€Ÿà€à€§à€£à¥}  
+_textcreatingcollection_ [l=mr] {à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à€Ÿ}  
+
+_textcollectorblurb_ [l=mr] {<i>à€²à¥à€à€£à¥ à€¹à¥ à€€à€²à€µà€Ÿà€°à¥à€žà€Ÿà€°à€à¥ à€
+à€žà€€à¥!
+ <br>à€¯à€Ÿ à€žà€à€à¥à€°à€¹ à€¬à€Ÿà€à€§à€£à¥à€²à€Ÿ à€à€£à€¿à€µà€¿à€€à€°à€£à€Ÿà€²à€Ÿ à€€à¥à€®à¥à€¹à¥ à€à€¬à€Ÿà€¬à€Šà€Ÿà€° à€à€¹à€Ÿà€€
+à€ªà¥à€°à€€à¥à€®à¥à€Šà¥à€°à€£ à€à€Ÿà€¯à€Šà€Ÿ: à€¯à€Ÿ à€®à¥à€³à¥ à€€à¥à€®à¥à€¹à¥ à€€à¥ à€ªà€Ÿà€¹à¥à€¶à€à€²à€Ÿà€€ à€€à€°à¥ à€€à¥ à€à€€à€°à€Ÿà€à€šà€Ÿ à€Šà¥à€£à¥à€¯à€Ÿà€à¥ à€à€µà€¶à€à¥à€¯à€€à€Ÿ  à€šà€Ÿà€¹à¥
+ à€žà€Ÿà€®à€Ÿà€à€¿à€ à€¬à€Ÿà€à€§à€¿à€²à€à¥ :  à€ªà¥à€°à€²à¥à€à€à¥à€¯à€Ÿ à€žà€®à€Ÿà€à€Ÿà€€à¥à€š à€ªà¥à€°à€Ÿà€ªà¥à€€ à€à€Ÿà€²à¥ à€à€¹à¥à€€ à€€à¥à€¯ à€žà€®à€Ÿà€à€Ÿà€à€Ÿ à€à€Šà€° à€°à€Ÿà€à€£à€°à¥ à€
+à€žà€Ÿà€µà¥à€€.
+ à€šà€¿à€€à¥à€®à€€à¥à€€à€Ÿ:à€à€Ÿà€¹à¥ à€à¥à€·à¥à€à¥ à€¯à€Ÿ à€žà€à€³à¥à€¯à€Ÿà€à€à€°à¥à€€à€Ÿ à€à€ªà€²à€¬à¥à€§ à€¹à¥à€ à€¶à€à€€ à€šà€Ÿà€¹à¥à€€
+ <br>à€®à€Ÿà€¹à€¿à€€à¥à€à€Ÿ à€à€Ÿà€³à€à¥à€ªà¥à€°à€µà€ à€µ à€¯à¥à€à¥à€¯ à€µà€Ÿà€ªà€° à€à€°à€Ÿ
+ </i>}  
+
+_textcb1_ [l=mr] {à€žà€à€à¥à€°à€Ÿà€¹à€ à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€šà€µà¥à€š à€®à€Ÿà€¹à€¿à€€à¥ à€­à€°à€£à¥à€¯à€Ÿà€ž à€à€¿à€à€µà€Ÿ à€à€Ÿà€¢à¥à€š à€à€Ÿà€à€£à¥à€¯à€Ÿà€ž à€à€¿à€à€µà€Ÿ à€€à¥à€¯à€Ÿà€€ à€¬à€Šà€² à€à€°à€£à¥à€¯à€Ÿà€ž à€®à€Šà€€ à€à€°à¥à€²....}  
+
+_textcb2_ [l=mr] {à€à€§à¥ à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à€Ÿ,}  
+_textcnc_ [l=mr] {à€šà€µà¥à€š à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à€Ÿ.}  
+_textwec_ [l=mr] {à€
+à€žà¥à€€à€¿à€€à¥à€µà€Ÿà€€ à€
+à€žà€²à¥à¥à€¯à€Ÿ à€®à€Ÿà€¹à€¿à€€à¥à€®à€§à¥à€¯à¥ à€­à€° à€à€Ÿà€² à€à€¿à€à€µà€Ÿ à€€à¥ à€à€Ÿà€¢à¥à€š à€à€Ÿà€à€Ÿ.}  
+
+_textcb3_ [l=mr] {à€
+à€à€à€¿à€à¥à€€ à€žà€à€à¥à€°à€¹à€Ÿà€€ à€¬à€Šà€² à€à€°à€£à¥à€žà€Ÿà€ à¥ à€à€¿à€à€µà€Ÿ à€€à¥à€¯à€Ÿà€€ à€Šà€žà¥à€€à€à€µà€à€Ÿà€à€à¥ à€­à€° à€à€Ÿà€²à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€€à¥à€®à¥à€¹à¥ à€ªà¥à€°à€µà¥à€¶ à€à¥à€²à€Ÿ à€ªà€Ÿà€¹à€¿à€à¥.à€¯à€Ÿà€®à¥à€³à¥ à€à€€à€° à€à¥à€£à¥ à€ªà¥à€°à€µà¥à€¶ à€à¥à€²à€Ÿ à€€à€°à¥ à€€à¥à€®à€à¥ à€à€Ÿà€® à€µ à€žà€à€à€£à€à€Ÿà€µà€°à¥à€² à€à€€à€° à€®à€¹à€¿à€€à¥ à€žà¥à€°à€à¥à€·à€¿à€€ à€°à€Ÿà€¹à€€à¥.
+à€žà¥à€à€šà€Ÿ- à€žà€à€°à€à¥à€·à€£à€Ÿà€à¥à€¯à€Ÿà€Šà¥à€·à¥à€à¥à€šà¥ à€€à¥à€®à¥à€¹à¥ à€ªà¥à€°à€µà¥à€¶ à€à¥à€²à¥à€¯à€Ÿ à€šà€à€€à€° à¥©à¥Š à€®à€¿à€šà¥à€à€Ÿà€à€šà¥ à€€à¥à€®à¥à€¹à¥ à€€à¥à€¯à€Ÿà€€à¥à€š à€¬à€Ÿà€¹à¥à€° à€¯à¥à€€à€Ÿ.à€ªà€£ à€²à€à¥à€ à€ªà¥à€šà¥à€¹à€Ÿ à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€ªà¥à€°à€µà¥à€¶à€Ÿà€à¥ à€à€®à€à€€à¥à€°à€£ à€¯à¥à€€à¥, à€µ à€à¥à€¥ à€ªà€Ÿà€žà¥à€š à€¬à€Ÿà€¹à¥à€° à€ªà€¡à€²à€Ÿà€€ à€€à€¥à¥à€š à€ªà¥à€šà¥à€¹à€Ÿ à€à€Ÿà€® à€à€°à€€à€Ÿ à€¯à¥à€€à¥}  
+
+_textcb4_ [l=mr] {à€€à¥à€®à€à¥ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€µà€°à¥à€² à€¯à¥à€à€° à€šà€Ÿà€µ à€µ à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š à€Šà¥à€¯à€Ÿ,à€µ à€ªà¥à€°à€µà¥à€¶ à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€¬à€à€š à€Šà€Ÿà€¬à€Ÿ}  
+
+_textfsc_ [l=mr] {à€€à¥à€®à¥à€¹à€Ÿà€à€²à€Ÿ à€¹à€µà€Ÿ à€
+à€žà€£à€Ÿà€°à€Ÿ à€žà€à€à¥à€°à€¹ à€à€§à¥ à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à€Ÿ(à€žà€à€°à€à¥à€·à€¿à€€ à€žà€à€à¥à€°à€¹ à€¯à€Ÿ à€¯à€Ÿà€Šà¥à€€ à€¯à€Ÿà€µà€¯à€Ÿà€ž à€šà€à¥)}  
+
+_textwtc_ [l=mr] {à€€à¥à€®à¥à€¹à¥ à€šà€¿à€µà€¡à€²à¥à€²à¥à€¯à€Ÿ à€žà€à€à¥à€°à€¹à€Ÿ à€¬à€°à¥à€¬à€° à€€à¥à€®à¥à€¹à¥}  
+_textamd_ [l=mr] {à€žà€à€à¥à€°à€¹à€Ÿà€€ à€
+à€à¥à€š à€­à€° à€à€²à¥à€š à€žà€à€à¥à€°à€¹ à€ªà¥à€šà¥à€¹à€Ÿ à€¬à€Ÿà€à€§à€Ÿ}  
+_textetc_ [l=mr] {à€žà€à€à¥à€°à€¹ à€à¥à€šà¥à€«à€¿à€à€°à¥à€¶à€š à€«à€Ÿà€à€² à€à€¡à€¿à€ à€à€°à¥à€š à€ªà¥à€šà¥à€¹à€Ÿ à€¬à€Ÿà€à€§à€Ÿ.}  
+_textdtc_ [l=mr] {à€žà¥à€°à¥à€µà€Ÿà€€à¥à€ªà€Ÿà€žà¥à€šà€à€Ÿ à€žà€à€à¥à€°à€¹ à€à¥à€¡à€Ÿ}  
+_textetcfcd_ [l=mr] {à€µà€¿à€à€¡à¥ à€ªà¥à€°à€£à€Ÿà€²à¥à€µà€° à€à€Ÿà€²à€£à€Ÿà€°à¥ à€žà¥. à€¡à¥. à€€à€¯à€Ÿà€° à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€žà€à€à¥à€°à€¹ à€ªà€Ÿà€ à€µà€Ÿ. }  
+_textcaec_ [l=mr] {à€
+à€žà¥à€€à€¿à€€à¥à€µà€Ÿà€€à€
+à€žà€²à¥à€²à€Ÿ à€žà€à€à¥à€°à€¹ à€¬à€Šà€²à€Ÿ}  
+_textnwec_ [l=mr] {à€¬à€Šà€² à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€žà€à€à¥à€°à€¹ à€²à€¿à€¹à¥à€š à€ªà¥à¥à€°à¥à€£ à€à€Ÿà€²à¥à€²à€Ÿ à€à¥à€£à€€à€Ÿà€¹à¥ à€žà€à€à¥à€°à€¹ à€šà€Ÿà€¹à¥.}  
+_textcianc_ [l=mr] {à€šà€µà¥à€š à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à€Ÿ}  
+_texttsosn_ [l=mr] {à€šà€µà¥à€š à€
+à€à€à€¿à€à¥à€€ à€à¥à€°à€à€¥à€Ÿà€²à€¯ à€¯à€Ÿ à€à¥à€°à€®à€Ÿà€šà¥ à€µ à€ªà€§à¥à€Šà€€à¥à€šà¥  à€€à€¯à€Ÿà€° à€à€°à€Ÿ.}  
+_textsin_ [l=mr] {à€¯à€Ÿà€à¥ à€šà€Ÿà€µ à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à€Ÿ (à€žà€¹à€Ÿà€¯à¥à€¯à€ à€®à€Ÿà€¹à€¿à€€à¥à€à¥)}  
+_textswts_ [l=mr] {à€žà¥à€°à¥à€ž à€¡à¥à€à€Ÿ à€à¥à€ à¥à€š à€¯à¥à€€à¥ à€¹à¥ à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à€Ÿ.}  
+_textatco_ [l=mr] {à€à¥à€šà€šà¥à€«à€¿à€à€°à¥à€¶à€šà€à¥ à€µà€¿à€­à€Ÿà€ à€šà€¿à€ à€à€°à¥à€š à€à¥à€¯à€Ÿ.(à€à€¡à€µà¥à€¹à€Ÿà€šà¥à€ž à€¯à¥à€à€° à€«à€à¥à€€)}  
+_textbtc_ [l=mr] {à€žà€à€à¥à€°à€¹ " à€€à€¯à€Ÿà€° " à€¹à¥à€€ à€à€¹à¥,à€à€Ÿà€²à¥ à€ªà€¹à€Ÿ.}  
+_textpvyh_ [l=mr] {à€€à¥à€®à€à¥ à€žà¥à€µà€€à€à€à¥ à€à€Ÿà€® à€Šà€Ÿà€à€µà€Ÿ.}  
+
+_texttfsiw_ [l=mr] {à€à¥à€¥à¥ à€ªà€Ÿà€¯à€°à¥ à€žà€à€à€£à€ à€žà¥à€° à€à€Ÿà€® à€à€°à€€à¥ ..... à€ªà¥à€°à€¥à€® à€€à¥à€®à¥à€¹à¥ à€®à€Ÿà€¹à€¿à€€à¥ à€šà€¿à€¶à¥à€à€¿à€€ à€à¥à€²à¥ à€ªà€Ÿà€¹à€¿à€à¥,}  
+
+_textadab_ [l=mr] {à€à€Ÿà€²à¥à€² à€à€à¥à€€à¥à€µà¥à€Šà€Ÿà€°à¥ à€€à¥à€®à¥à€¹à¥ à€à¥à€ à¥ à€à€¹à€Ÿà€€ à€¹à¥ à€Šà€¿à€žà¥ à€¶à€à€€à¥.à€¹à€¿à€°à€µà¥ à€¬à€à€š à€Šà€Ÿà€¬à¥à€š à€€à¥à€®à¥à€¹à¥ à€à¥à€°à€® à€ à€°à€µà¥ à€¶à€à€€à€Ÿ.à€¯à€Ÿ à€à¥à€°à€®à€µà€Ÿà€°à¥ à€ªà¥à€¢à¥ à€à¥à€²à¥à€¯à€Ÿà€ž à€¹à€¿à€°à€µà¥ à€¬à€à€š à€ªà€¿à€µà€³à¥ à€¹à¥à€€à¥.à€ªà¥à€°à¥à€µà¥à€à¥à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€° à€¯à¥à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€ªà¥à€šà¥à€¹à€Ÿ à€ªà€¿à€µà€³à¥ à€¬à€à€š à€Šà€Ÿà€¬à€Ÿ}  
+
+_textwyar_ [l=mr] {à€šà€µà¥à€š à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€
+à€à€à€¿à€à¥à€€ à€à¥à€°à€¥à€Ÿà€²à€¯à€Ÿà€à¥ à€žà¥à€°à¥à€µà€Ÿà€€ à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€žà€à€à¥à€°à€¹ à€®à€Ÿà€¹à€¿à€€à¥ à€¹à¥ à€¬à€à€š à€Šà€Ÿà€¬à€Ÿ}  
+
+_textcnmbs_ [l=mr] {à€žà€à€à¥à€°à€¹à€Ÿà€à¥ à€šà€Ÿà€µ à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à€Ÿ}  
+_texteambs_ [l=mr] {à€-à€®à¥à€² à€à€Ÿ à€ªà€€à¥à€€à€Ÿ à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à€Ÿ}  
+_textpsea_ [l=mr] {à€à¥à€ªà€¯à€Ÿ à€-à€®à¥à€²à€à€Ÿ à€ªà€€à¥à€€à€Ÿ à€¬à€°à¥à€¬à€° à€Šà¥à€¯à€Ÿ.
+à€à€žà¥- à€¯à¥à€à€°à€Ÿà€à¥ à€šà€Ÿà€µ@à€à€Ÿà€°à¥à€¯à€à¥à€·à¥à€€à¥à€°}  
+_textdocmbs_ [l=mr] {à€žà€à€à¥à€°à€¹à€Ÿà€à¥ à€µà€°à¥à€£à€š à€¯à¥à€à¥à€¯ à€à€°à€Ÿà€µà¥}  
+
+_textwcanc_ [l=mr] {à€šà€µà¥à€šà€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à€€à€Ÿà€šà€Ÿ à€à€Ÿà€¹à¥ à€ªà¥à€°à€Ÿà€¥à€®à€¿à€ à€®à€Ÿà€¹à¥à€€à¥ à€Šà¥à€¯à€Ÿ....}  
+
+_texttfc_ [l=mr] {à€žà€à€à¥à€¹à€Ÿà€žà€Ÿà€ à¥ à€šà€Ÿà€µà€}  
+
+_texttctiasp_ [l=mr] {à€žà€à€à¥à€°à€¹à€Ÿà€à€°à¥à€€à€Ÿ à€
+à€žà€Ÿ  à€µà€Ÿà€à¥à€ªà¥à€°à€à€Ÿà€° à€µà€Ÿà€ªà€°à€Ÿ à€à¥à€¯à€®à¥à€³à¥ à€
+à€à€à€¿à€à¥à€€ à€à¥à€°à€à€¥à€Ÿà€²à€¯ à€žà€à€à¥à€°à€¹à€Ÿà€€à¥à€²  à€à€à€ à€à€³à€à¥ à€¶à€à¥à€².  à€à€Šà€Ÿà€¹à€°à€£
+ "à€à€®à¥à€ªà¥à€¯à¥à€à€° à€žà€Ÿà€¯à€à€šà¥à€ž à€à¥à€à¥à€šà€¿à€à€² à€°à€¿à€ªà¥à€°à¥à€" à€à€£à€¿ "à€¹à¥à€¯à¥à€®à¥
+à€šà€¿à€à¥ à€¡à¥à€µà¥à€¹à€²à€ªà€®à¥à€à€ à€²à€Ÿà€¯à€¬à¥à€°à€°à¥."}  
+
+_textcea_ [l=mr] {à€žà€à€°à¥à€ªà€à€ à€-à€®à¥à€² à€ªà€€à¥à€€à€Ÿ}  
+
+_textteas_ [l=mr] {à€žà€à€à¥à€°à€¹à€Ÿà€²à€Ÿ à€žà€à€°à¥à€ªà€ à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€¹à€Ÿ à€-à€®à¥à€² à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à€Ÿ.
+à€à€° à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€žà¥à€«à¥à€à€µà¥à€
+à€°à€²à€Ÿ à€¯à€Ÿ à€®à€§à¥à€¯à¥ à€à¥à€ à€à€¢à€³à€²à¥ à€€à€° 
+à€¯à€Ÿ à€-à€®à¥à€² à€µà€° à€žà€à€°à¥à€ªà€ à€à€°à€Ÿ.  à€-à€®à¥à€² à€à€Ÿ à€ªà€€à¥à€€à€Ÿ à€ªà¥à€°à¥à€£ à€²à€¿à€¹à€Ÿ:
+ <tt>à€šà€Ÿà€µ@à€¡à¥à€®à¥à€š</tt>.}  
+
+_textatc_ [l=mr] {à€¯à€Ÿ à€žà€à€à¥à€°à€¹à€Ÿà€µà€¿à€·à€¯à¥}  
+
+_texttiasd_ [l=mr] {à€žà€à€à¥à€°à€¹ à€à¥à€µà¥à€¹à€Ÿ à€ªà¥à€°à€°à¥à€Šà€¶à€¿à€€ à€à¥à€²à€Ÿ à€à€Ÿà€à€² à€€à¥à€µà¥à€¹à€Ÿ à€¹à¥ à€šà€¿à€µà¥à€Šà€š à€ªà¥à€°à€¥à€® à€Šà€¿à€žà¥à€².à€¯à€Ÿ à€šà€¿à€µà¥à€Šà€šà€Ÿà€µà¥à€Šà€Ÿà€°à¥ à€žà€à€à¥à€°à€¹à€Ÿà€€ à€
+à€žà€²à¥à€²à¥ à€€à€€à¥à€µà¥ à€ªà¥à€°à€°à¥à€Šà€¶à€¿à€€ à€¹à¥à€€à¥à€² }  
+
+_textypits_ [l=mr] {à€¯à€Ÿà€ªà€Ÿà€žà¥à€š à€ªà¥à€¢à¥ à€à€Ÿà€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ "à€®à€Ÿà€¹à€¿à€€à¥à€à€Ÿ à€à€à€®" à€¹à¥ à€¹à€¿à€°à€µà¥ à€¬à€à€£ à€Šà€Ÿà€¬à€Ÿ....}  
+
+_srcebadsources_ [l=mr] {à€Šà€¿à€²à¥à€²à¥ à€®à€Ÿà€¹à€¿à€€à¥ à€žà¥à€€à¥à€°à¥à€€ à€à€ªà€²à€¬à¥à€§ à€šà€Ÿà€¹à¥à€€, à€à€Ÿà€°à€£ à€Šà€¿à€²à¥à€²à¥ à€«à€Ÿà€à€² à€¯à€Ÿ à€à€«à€à¥à€ªà¥ à€žà€Ÿà€à€ à€µà€° à€šà€Ÿà€¹à¥,à€à€¿à€à€µà€Ÿ à€«à€Ÿà€¯à€°à€µà¥à€² à€®à¥à€³à¥ à€¯à¥à€à€°à€à€² à€à€ªà€²à€¬à¥à€§ à€šà€Ÿà€¹à¥. à€€à¥à€¯à€Ÿ à€à€°à¥à€€à€Ÿ à€ªà¥à€šà¥à€¹à€Ÿ à€à€¯à€ªà¥à€à€ž à€ªà€¹à€Ÿà€µà€Ÿ.?
+...}  
+
+_textymbyco_ [l=mr] {<p>à€€à¥à€®à¥à€¹à¥ à€€à¥à€®à€à€Ÿ à€žà€à€°à€¹ à€¯à¥à€¥à¥ à€ à¥à€µà€Ÿ 
+ <ul>
+ <li>à€
+à€à¥à€ à€°à€à€šà€Ÿ
+ <dl><dd>à€šà€µà¥à€š à€žà€à€à¥à€°à€¹à€Ÿà€€ à€à€à€à¥à€à€®à€à€² à€ªà¥à€°à€²à¥à€ (.htm, .html), à€žà€Ÿà€§à¥
+ à€ªà¥à€°à€²à¥à€ (.txt, .text), à€à€®à€à€ž à€µà¥à€°à€¡ à€ªà¥à€°à€²à¥à€ (.doc), à€ªà¥à€¡à¥à€à€« à€ªà¥à€°à€²à¥à€  (.pdf) or
+ "à€à€®-à€¬à¥à€à¥à€ž" à€«à¥à€°à€®à¥
+à€ à€-à€®à¥à€² à€ªà¥à€°à€²à¥à€  (.mbx).</dd></dl>
+ <li>à€
+à€žà¥à€€à€¿à€€à¥à€µà€Ÿà€€à¥à€² à€žà€à€à¥à€°à€¹
+ <dl><dd>à€žà€à€à¥à€°à€¹ à€à¥à€¯à€Ÿ à€ªà¥à€°à€à€Ÿà€°à¥ à€€à€¯à€Ÿà€° à€à€°à€Ÿà€µà€¯à€Ÿà€à€Ÿ à€à€¹à¥ à€€à¥à€¯à€Ÿà€ à€ªà¥à€°à€à€Ÿà€°à€à¥à€¯à€Ÿ à€šà€µà¥à€š à€«à€Ÿà€à€² à€
+à€žà€£à¥ à€à€µà€¶à¥à€¯à€ à€à€¹à¥.</dd></dl>
+ </ul>
+ }  
+
+_textbtco_ [l=mr] {à€žà€à€à¥à€°à€¹à€Ÿà€à€Ÿ à€ªà€Ÿà€¯à€Ÿ}  
+_textand_ [l=mr] {à€šà€µà¥à€š à€žà€à€à¥à€°à€¹ à€­à€°à€Ÿ}  
+_textad_ [l=mr] {à€®à€Ÿà€¹à€¿à€€à¥ à€®à€¿à€³à€µà€Ÿ}  
+
+_texttftysb_ [l=mr] {à€€à¥à€®à¥à€¹à¥ à€à€Ÿà€²à¥ à€šà€¿à€¶à¥à€à€¿à€€ à€à¥à€²à¥à€²à¥à€¯à€Ÿ à€«à€Ÿà€à€² à€žà€à€à¥à€°à€¹à€Ÿà€€ à€žà€®à€Ÿà€µà€¿à€·à¥à€ à€¹à¥à€€à¥à€²  à€à€§à¥ à€žà€®à€Ÿà€µà€¿à€·à¥à€ à€
+à€žà€²à¥à€²à¥à€¯à€Ÿ à€«à€Ÿà€à€² à€ªà¥à€šà¥à€¹à€Ÿ à€žà€®à€Ÿà€µà€¿à€·à¥à€ à€¹à¥à€£à€Ÿà€° à€šà€Ÿà€¹à¥à€€ à€¯à€Ÿà€à€¡à¥ à€²à€à¥à€· à€Šà¥à€¯à€Ÿ.à€šà€Ÿà€¹à¥à€€à€° à€Šà¥à€š à€žà€Ÿà€°à€à¥à€¯à€Ÿ à€«à€Ÿà€à€² à€ªà¥à€šà¥à€¹à€Ÿ à€žà€®à€Ÿà€µà€¿à€·à¥à€ à€¹à¥à€€à¥à€²,à€¯à€Ÿ à€€à¥à€¯à€Ÿà€à€à¥à€¯à€Ÿ à€ªà¥à€°à¥à€£ à€ªà€Ÿà€¥à€šà€Ÿà€µà€Ÿà€šà¥ à€à€³à€à€²à¥à€¯à€Ÿ à€à€Ÿà€€à€Ÿà€€âŠ?}  
+
+_textis_ [l=mr] {à€à€šà€ªà¥à€ à€žà¥à€žà¥à€°}  
+
+_textddd1_ [l=mr] {à€à€šà€ªà¥à€ à€¿à€à€¡à€à¥ à€¿à€®à€³à€¿à€µà€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ "à€à€£à€à¥ à€à€à€®" à€¹à¥ à€¬à€à€š à€Šà€Ÿà€¬à€Ÿ}  
+
+_textddd2_ [l=mr] {à€
+à¥
+à€¡à€µà¥à€¹à€Ÿà€šà¥à€ž à€à€ªà€¯à€à€ à€
+à€žà€Ÿà€²  à€µ à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€žà€à€à¥à€°à€¹à€Ÿà€à¥ à€à¥à€šà¥à€«à¥à€à€°à¥à€¶à€š à€à€°à€Ÿà€µà€¯à€Ÿà€à¥ à€
+à€žà¥à€²  à€€à€°  à€¹à€¿à€°à€µà¥ à€¬à€à€š à€Šà€Ÿà€¬à€Ÿ à€µ à€¬à€Ÿà€à€§à€£à¥à€à€¡à¥ à€à€Ÿ,à€€à¥à€®à¥à€¹à¥ à€ªà€¿à€µà€³à¥ à€¬à€à€š à€Šà€Ÿà€¬à¥à€š à€ªà¥à€šà¥à€¹à€Ÿ à€à€§à¥à€à¥ à€à¥à€€à¥ à€à€°à¥ à€¶à€à€€à€Ÿ.}  
+
+_textconf1_ [l=mr] {à€€à¥à€®à€à¥à€¯à€Ÿ à€žà€à€à¥à€°à€¹à€Ÿà€à¥ à€žà€Ÿà€Šà€°à¥à€à€°à€£ à€¹à¥ à€à€à€Ÿ à€µà€¿à€¶à€¿à€·à¥à€ à€à¥à€šà€«à€¿à€à€° à€«à€Ÿà€à€²à€µà¥à€Šà€Ÿà€°à¥ à€à¥à€²à¥à€²à¥ à€à€¹à¥.à€µà€¿à€¶à€¿à€·à¥à€ à€¯à¥à€à€°à€Ÿà€šà¥ à€¹à¥ à€à¥à€šà€«à€¿à€à€° à€«à€Ÿà€à€²à€à¥ à€žà¥à€à€¿à€à€ à€¬à€Šà€²à€Ÿà€µà€¯à€Ÿà€ž à€¹à€µà¥.
+à€à€° à€€à¥à€®à¥à€¹à¥ à€µà€¿à€¶à€¿à€·à¥à€ à€¯à¥à€à€° à€šà€žà€Ÿà€² à€€à€° à€ªà€Ÿà€šà€Ÿà€µà€°à¥à€² à€¬à€à€šà€Ÿà€à€¡à¥ à€à€Ÿ.
+à€à¥à€šà€«à€¿à€à€°à¥à€¶à€šà€à¥ à€žà¥à€à¥à€à€ à€¬à€Šà€²à€£à¥à€¯à€Ÿà€à€°à¥à€€à€Ÿ à€ªà¥à€¢à¥à€² à€®à€Ÿà€¹à€¿à€€à¥ à€à€¡à¥à€ à€à€°à€Ÿ,à€à€° à€€à¥à€®à€à¥à€¯à€Ÿà€à€¡à¥à€š à€à¥à€ à€à€Ÿà€²à¥à€ à€€à€° à€°à€¿à€žà¥à€ à€¹à¥ à€¬à€à€š à€Šà€Ÿà€¬à€Ÿ,à€µ à€ªà¥à€šà¥à€¹à€Ÿ à€à€§à¥à€à¥ à€à¥à€šà€«à€¿à€à€°à¥à€¶à€š à€®à€¿à€³à€µà€Ÿ}  
+
+_textreset_ [l=mr] {à€ªà¥à€šà¥à€¹à€Ÿ à€à€°à€Ÿ}  
+
+
+_texttryagain_ [l=mr] {à€à¥à€ªà€¯à€Ÿ à€žà€à€à¥à€°à€¹à€ à€ªà¥à€šà¥à€¹à€Ÿ à€à€Ÿà€²à¥ à€à€°à€Ÿ}  
+
+
+_textretcoll_ [l=mr] {à€žà€à€à¥à€°à€¹à€à€Ÿà€à€¡à¥ à€ªà€°à€€ à€¯à€Ÿ}  
+
+_textdelperm_ [l=mr] {à€žà€à€³à¥ à€à€¿à€à€µà€Ÿ à€à€Ÿà€¹à¥ à€žà€à€à¥à€°à€¹ à€à¥à€¡à€²à€Ÿ à€à¥à€²à€Ÿ à€šà€Ÿà€¹à¥ à€à€Ÿà€°à€£ à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€²à€Ÿ à€¹à¥ à€à€°à€£à¥à€¯à€Ÿà€à¥ à€ªà€°à€µà€Ÿà€šà€à¥ à€šà€Ÿà€¹à¥.à€€à¥à€®à¥à€¹à¥ à€žà€à€à€£à€à€Ÿà€µà€°à¥à€š à€¹à¥ à€«à€Ÿà€à€² à€à€Ÿà€¢à¥à€š à€à€Ÿà€à€Ÿ,à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¹à€Ÿ à€à€Ÿà€°à¥à€¯à€à¥à€°à€® à€à€Ÿà€²à€µà¥ à€¶à€à€€ à€šà€Ÿà€¹à¥}  
+
+_textdelinv_ [l=mr] {à€žà€à€à¥à€°à€¹ à€¹à€Ÿ à€žà€à€°à€à¥à€·à€¿à€€ à€à¥à€²à€Ÿ à€à€¹à¥ à€à€¿à€à€µà€Ÿ à€€à¥ à€šà€¿à€°à¥à€ªà€¯à¥à€à¥ à€à€¹à¥.à€à¥à€¡à€²à¥à€²à¥ à€°à€Šà¥à€Š à€à€Ÿà€²à¥}  
+
+_textdelsuc_ [l=mr] {à€žà€à€à¥à€°à€¹ à€à¥à€¡à€²à€Ÿ à€à¥à€²à€Ÿ à€à€¹à¥}  
+
+_textclonefail_ [l=mr] {à€žà€ à€à¥à€°à€¹ à€
+à€žà¥à€€à€¿à€€à¥à€µà€Ÿà€€ à€šà€Ÿà€¹à¥ à€žà€à€à¥à€°à€¹à€Ÿà€²à€Ÿ à€žà¥à€«à€à¥ à€à¥à€šà¥à€«à€¿à€à€°à¥à€¶à€š à€«à€Ÿà€à€² à€šà€Ÿà€¹à¥ à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€²à€Ÿ à€¹à€¿ à€žà€¿ à€à€« à€à¥ à€µà€Ÿà€à€£à¥à€¯à€Ÿà€à¥ à€ªà€°à€µà€Ÿà€šà€à¥ à€šà€Ÿà€¹à¥.?}  
+
+_textcolerr_ [l=mr] {à€žà€à€à¥à€°à€¹à€ à€à¥à€}  
+
+_texttmpfail_ [l=mr] {à€žà€à€à¥à€°à€¹à€ à€€à€Ÿà€€à¥à€ªà¥à€°à€€à¥à€¯à€Ÿ à€°à¥à€ªà€°à¥à€Šà€¶à€¿à€à¥à€€à¥à€² à€«à€Ÿà€à€² à€µà€Ÿà€à¥ à€¶à€à€€ à€šà€Ÿà€¹à¥ . 
+à€à€Ÿà€°à€£
+ <ul>
+ <li> à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€²à€Ÿ à€²à€¿à€¹à¥à€²à¥à€²à¥ _à€à¥à€à€žà€à€²à€¡à¥ à€¹à¥à€®_/à€€à€Ÿà€€à¥à€ªà¥à€°à€€à¥ 
+      à€°à¥à€ªà€Šà¥à€°à€¶à€¿à€à€Ÿ à€µà€Ÿà€à€£à¥à€¯à€Ÿà€à¥ à€ªà€°à€µà€Ÿà€šà€à¥ à€šà€Ÿà€¹à¥.
+ </ul>
+}  
+
+_textmkcolfail_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€²à€Ÿ à€¹à€¿ à€¡à€¿à€°à¥à€à¥à€à€°à¥ à€à€°à€€à€Ÿ à€¯à¥à€£à€Ÿà€° à€šà€Ÿà€¹à¥}  
+
+_textnocontent_ [l=mr] {à€žà€à€à¥à€°à€¹ à€à¥à€à€ à€šà€µà¥à€š à€žà€à€à¥à€°à€¹à€Ÿà€žà€Ÿà€ à¥ à€à¥à€£à€€à¥à€¹à¥ à€šà€Ÿà€µ à€Šà€¿à€²à¥à€²à¥ à€šà€Ÿà€¹à¥.à€žà€à€à¥à€°à€¹à€ à€žà¥à€°à¥à€µà€Ÿà€€à¥ à€ªà€Ÿà€žà¥à€š à€ªà¥à€šà¥à€¹à€Ÿ à€à€Ÿà€²à¥ à€à€°à€Ÿ.}  
+
+_textrestart_ [l=mr] {à€žà€à€à¥à€°à€¹à€ à€ªà¥à€šà¥à€¹à€Ÿ à€à€Ÿà€²à¥ à€à€°à€Ÿ.}  
+
+_textreloaderror_ [l=mr] {à€šà€µà¥à€š à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à€£à¥à€¯à€Ÿà€€ à€à¥à€ à€¹à¥à€€ à€à€¹à¥ ,à€
+à€žà¥ à€¹à¥à€€ à€à€¹à¥ à€à€Ÿà€°à€£
+à€€à¥à€®à€à¥à€¯à€Ÿ à€¬à¥à€°à€Ÿà€à€à€° à€µà€°à¥à€² à€€à¥à€®à¥à€¹à¥ à€µà€Ÿà€ªà€°à€€ à€
+à€žà€²à¥à€²à¥à€¯à€Ÿ à€°à€¿à€²à¥à€¡ à€µ à€¬à¥
+à€ à€¬à€à€šà€®à¥à€³à¥ (à€à¥à€ªà€¯à€Ÿ à€žà€à€à¥à€°à€¹à€ à€€à€¯à€Ÿà€° à€à€°à€€ à€
+à€žà€€à€Ÿà€šà€Ÿ à€¯à€Ÿ à€¬à€à€šà€Ÿà€à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à¥ à€šà€à€Ÿ).  à€¯à€Ÿà€®à¥à€³à¥ à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€žà€à€³à€Ÿ 
+ à€žà€à€à¥à€°à€¹à€ à€ªà¥à€šà¥à€¹à€Ÿ à€žà¥à€°à¥à€µà€Ÿà€€à¥à€ªà€Ÿà€žà¥à€š à€€à€¯à€Ÿà€° à€à€°à€Ÿà€µà€Ÿ à€²à€Ÿà€à¥à€²}  
+
+_textexptsuc_ [l=mr] {The _cgiargbc1dirname_ à€žà€à€à¥à€°à€¹ à€¯à€¶à€žà¥à€µà¥à€°à€¿à€€à¥à€¯à€Ÿ à€ªà€Ÿà€ à€µà€¿à€²à€Ÿ à€à€¹à¥
+ _à€à¥à€à€žà€à€²à€¡à¥ à€¹à¥à€®_/à€€à€Ÿà€€à¥à€ªà¥à€°à€€à¥/à€ªà€Ÿà€ à€µà€¿à€²à¥\__cgiargbcà¥§ à€Šà€°à¥à€¶à€¿à€à€Ÿ à€šà€Ÿà€µ_ à€Šà€°à¥à€¶à€¿à€à€Ÿ.
+ }  
+
+_textexptfail_ [l=mr] {<p>Failed to export the _cgiargbc1dirname_ collection.
+
+<p>This is likely to be because Greenstone was installed without the
+necessary components to support the "Export Collection" function.
+<ul>
+
+ <li>If you installed Greenstone from a CD-ROM these components won't have
+ been installed unless you selected them during a "Custom" install.
+ You may add them to your installation by re-running the installation 
+ procedure.
+
+ <li>If you installed Greenstone from a web distribution you will need to
+ download and install an additional package to enable this function. Please
+ visit <a href="http://www.greenstone.org">http://www.greenstone.org</a> or
+ email <a
+ href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>
+ for further details.
+
+</ul>
+}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=mr] {à€à¥à€ªà€¯à€Ÿ à€à€Ÿà€²à¥à€²à€«à€Ÿà€à€²à¥à€à¥ à€®à€Ÿà€¹à€¿à€€à¥ à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à¥à€š   _ à€à¥à€à¥à€žà€à€à€à¥à€°à¥ _à€Šà€Ÿà€¬à€Ÿ_à€à€Ÿà€²à¥.</p>}  
+
+_textcaec_ [l=mr] {à€à€¹à¥ à€€à¥à€¯à€Ÿ à€žà€à€à¥à€°à€¹à€Ÿà€€ à€­à€° à€à€Ÿà€²à€Ÿ}  
+_textbild_ [l=mr] {à€à€¯à€à€® à€ à¥à€µà€Ÿ}  
+_textintro_ [l=mr] {à€«à€Ÿà€à€² à€šà€¿à€µà€¡à€Ÿ}  
+_textconfirm_ [l=mr] {à€šà€¿à€¶à¥à€à€¿à€€à¥}  
+_textselect_ [l=mr] {à€žà€à€à¥à€°à€¹ à€šà€¿à€µà€¡à€Ÿ}  
+_textmeta_ [l=mr] {à€®à¥à€à€Ÿà€¡à¥à€à€Ÿ à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à€Ÿ}  
+_textselectoption_ [l=mr] {à€žà€à€à¥à€°à€¹ à€šà€¿à€µà€¡à€Ÿ}  
+
+_texttryagain_ [l=mr] {à€à¥à€ªà€¯à€Ÿ à€ªà¥à€šà¥à€¹à€Ÿ à€ªà¥à€°à€¯à€€à¥à€š à€à€°à€Ÿ}  
+
+_textselectcol_ [l=mr] {à€à¥à€¯à€Ÿ à€žà€à€à¥à€°à€¹à€Ÿà€®à€§à¥à€¯à¥ à€šà€µà¥à€š à€®à€Ÿà€¹à€¿à€€à¥ à€­à€°à€Ÿà€¯à€à¥ à€à€¹à¥ à€€à¥ à€žà€à€à¥à€°à€¹ à€šà€¿à€µà€¡à€Ÿ. }  
+_textfilename_ [l=mr] {à€«à€Ÿà€à€²à€à¥ à€šà€Ÿà€µ  }  
+_textfilesize_ [l=mr] {à€«à€Ÿà€à€²à€à€Ÿ à€à€à€Ÿà€° }  
+
+_textretcoll_ [l=mr] {à€¡à€¿à€ªà¥à€à€¿à€à€° à€à€¡à¥ à€ªà€°à€€ à€¯à€Ÿ.}  
+
+
+_texttmpfail_ [l=mr] {à€¡à€¿à€ªà¥à€à€¿à€à€° à€¹à¥ à€µà€Ÿà€à¥à€¶à€à€€ à€šà€Ÿà€¹à¥ à€à€¿à€à€µà€Ÿ à€²à€¿à€¹à¥ à€¶à€à€€ à€šà€Ÿà€¹à¥ à€à€¿à€à€µà€Ÿ à€¡à€¿à€°à¥à€à¥à€à€°à¥  à€à€°à¥ à€¶à€à€€ à€šà€Ÿà€¹à¥ à€à€Ÿà€°à€£ à€à€°à¥à€šà€žà¥à€à¥à€šà€²à€Ÿ à€¹à¥ à€à€°à€£à¥à€¯à€Ÿà€à¥ à€ªà€°à€µà€Ÿà€šà€à¥ à€šà€Ÿà€¹à¥.}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¹à¥ à€
+à€žà¥ à€žà¥à€«à¥à€à€µà¥à€
+à€° à€à€¹à¥ à€à¥, à€à¥à€¯à€Ÿ à€µà¥à€Šà€Ÿà€°à¥ à€
+à€à€à€¿à€à¥à€€ à€à¥à€°à€à€¥à€Ÿà€²à€¯à€Ÿà€à€Ÿ 
+ à€žà€à€à¥à€°à€¹ à€à€à€€à¥à€° à€à€°à¥à€š à€šà€µà¥à€šà€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€€à€Ÿ à€¯à¥à€€à¥.  à€¯à€Ÿ à€µà¥à€Šà€Ÿà€°à¥
+à€®à€Ÿà€¹à€¿à€€à¥à€à¥ à€ªà¥à€°à¥à€š à€µà¥à€¯à€µà€¥à¥à€žà€Ÿà€ªà€š à€à€°à¥à€š à€µà¥à€¬ à€ªà€Ÿà€šà€Ÿà€µà€° à€€à¥à€¯à€Ÿà€à¥ à€ªà¥à€°à€Šà¥à€°à€¶à€š à€à€°à€€à€Ÿ à€¯à¥à€€à¥
+à€¯à¥à€šà€¿à€µà¥à€¹à¥à€°à€žà€¿à€à¥ à€à€« à€µà¥à€¯à€à€Ÿà€€à¥ à€¯à¥à€¥à¥à€² à€šà¥à€¯à¥à€à¥à€²à€à€¡ à€¡à€¿à€à¥à€à€² à€²à€Ÿà€¯à€¬à¥à€°à€°à¥ à€ªà¥à€°à¥à€à¥à€à¥à€ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¹à¥ à€µà¥à€Šà€Ÿà€°à¥ à€ªà¥à€°à€žà€Ÿà€°à¥à€€ à€à¥à€²à¥ à€à€¹à¥
+à€à€£à€¿ à€¯à¥à€šà¥à€žà¥à€à¥à€à¥à€¯à€Ÿ à€žà€¹à€Ÿà€¯à¥à€¯à€Ÿà€šà¥  à€€à¥ à€µà€¿à€€à€°à¥à€€ à€à¥à€²à¥ à€à€¹à¥
+ <i>http://greenstone.org</i> à€à€šà€°à€² à€ªà€¬à¥à€²à€¿à€ à€²à€Ÿà€¯à€žà€šà¥à€žà€à€¯à€Ÿà€
+à€à¥à€à€à€Ÿà€²à¥ 
+.à€¹à¥à€¯à¥à€®à€š à€à€šà€«à¥ à€à€šà€à¥à€ à€¹à¥  à€à€ªà€š à€žà¥à€°à¥à€ž à€žà¥à€«à¥à€à€µà¥à€
+à€° à€à€ªà€²à€¬à¥à€§ à€à€¹à¥}  
+
+_textgreenstone2_ [l=mr] {à€šà¥à€¯à¥à€à¥à€²à€à€¡ à€
+à€à€à¥à€à¥à€€ à€à¥à€°à€à€¥à€Ÿà€²à€¯à€Ÿà€à¥ à€µà¥à€¬ à€žà€Ÿà€à€ 
+(<ahref="http://nzdl.org">http://nzdl.org</a>) à€¯à€Ÿà€®à€§à¥à€¯à¥ à€
+à€à€à€¿à€¯ à€žà€à€à¥à€°à€¹ à€à€¹à¥,
+  à€à¥ à€žà€à€°à¥à€ªà¥à€£ à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€µà¥à€Šà€Ÿà€°à¥ à€žà€°à¥à€µà€Ÿà€à€žà€Ÿà€ à¥ à€à€ªà€²à€¬à¥à€§ à€à¥à€²à€Ÿ à€à€¹à¥
+  à€¯à€Ÿà€®à€§à¥à€¯à¥  à€
+à€°à¥à€¬à€¿à€, à€à€Ÿà€¯à€šà¥à€, à€«à¥à€°à¥à€à€, à€®à¥à€°à¥ à€à€£à€¿ à€žà¥à€ªà¥à€šà€¿à€¶, à€€à¥à€¯à€Ÿà€ à€ªà¥à€°à€®à€Ÿà€£à¥ à€à€à€à¥à€°à€à¥,à€. à€­à€Ÿà€·à€Ÿà€à€®à€§à¥à€¯à¥ à€¶à¥à€§ à€à¥à€ à€¶à€à€€à€Ÿ 
+à€€à¥à€¯à€Ÿà€à€ªà¥à€°à€®à€Ÿà€£à¥ à€€à¥à€¥à¥ à€žà€à€à¥à€€ à€žà€à€à¥à€°à€¹ à€à€¹à¥
+ }  
+
+_textplatformtitle_ [l=mr] {à€ªà¥à€²à¥
+à€à€«à¥à€®}  
+_textgreenstone3_ [l=mr] {Greenstone runs on Windows, Unix and Mac OS X. The distribution includes ready-to-use
+binaries for all versions of Windows, and for Linux and Mac OS X. It also includes
+complete source code for the system, which can be compiled using Microsoft
+C++ or gcc.  Greenstone works with associated software that is also freely
+available: the Apache Webserver and PERL. The user interface uses a Web
+browser: typically Netscape Navigator or Internet Explorer.
+}  
+
+_textgreenstone4_ [l=mr] {à€
+à€šà¥à€ à€Šà€žà¥à€€à€à€µà€à€Ÿà€à€à€Ÿ à€žà€à€à¥à€°à€¹ à€¹à€Ÿ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€žà¥à€«à¥à€à€µà¥à€
+à€° à€µà€Ÿà€ªà€°à¥à€š  à€žà¥à€¡à¥-à€°à¥à€® à€Šà¥à€Ÿà€°à¥ à€µà€Ÿà€à€€à€Ÿà€¯à¥à€€à¥ à€à€Šà€Ÿà€ à€¹à¥à€¯à¥à€®à¥
+à€šà€¿à€à¥ à€¡à¥à€µà¥à€¹à€²à€ªà€®à¥à€à€ à€²à€Ÿà€¯à€¬à¥à€°à€°à¥  ....à¥§,à¥šà¥©à¥Š à€ªà¥à€°à€à€Ÿà€¶à€šà¥....}  
+
+_textcustomisationtitle_ [l=mr] {à€žà€°à€Ÿà€µ}  
+_textgreenstone5_ [l=mr] {Greenstone is specifically designed to be highly extensible and
+customisable. New document and metadata formats are accommodated by writing
+"plugins" (in Perl). Analogously, new metadata browsing structures can be
+implemented by writing "classifiers." The user interface look-and-feel can
+be altered using "macros" written in a simple macro language. A Corba
+protocol allows agents (e.g. in Java) to use all the facilities associated
+with document collections. Finally, the source code, in C++ and Perl, is
+available and accessible for modification.
+}  
+
+_textdocumentationtitle_ [l=mr] {à€Šà€žà¥à€€à€à€µà€}  
+_textdocuments_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€žà¥à€«à¥à€à€µà¥à€
+à€°à€à¥ à€žà€µà€¿à€žà¥à€€à€° à€Šà€žà¥à€€à€à€µà€}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=mr] {à€®à¥à€²à€¿à€à€ à€¯à€Ÿà€Šà¥.}  
+_textmailinglist_ [l=mr] {à€¯à¥à€¥à¥ à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€µà€¿à€·à€¯à¥ à€ªà¥à€°à€Ÿà€¥à€®à€¿à€     à€à€à¥à€°à€Ÿ à€à€°à€£à¥à€¯à€žà€Ÿà€ à¥ à€à€®à¥à€²à€à¥ à€¯à€Ÿà€Šà¥ à€à¥à€²à¥ à€à€¹à¥ à€€à€ªà¥à€€à€° à€¯à¥à€à€° à€¯à€Ÿà€®à€§à¥à€¯à¥ à€žà€®à€Ÿà€µà€¿à€·à¥à€ à€¹à¥à€à€¶à€à€€à¥......}  
+
+_textbugstitle_ [l=mr] {à€¬à€à¥à€à¥}  
+_textreport_ [l=mr] {à€¹à¥ à€žà¥à€«à¥à€à€µà¥à€
+à€° à€€à¥à€®à€à¥ à€à€Ÿà€°à¥à€¯ à€à€Ÿà€à€à€²à¥ à€à€°à€€à¥ à€¯à€Ÿà€à¥ à€à€®à¥à€¹à€Ÿà€à€²à€Ÿ à€à€Ÿà€€à¥à€°à¥ à€à€°à¥à€š à€à¥à€¯à€Ÿà€µà€¯à€Ÿà€à¥ à€à€¹à¥. à€à¥à€ªà€¯à€Ÿ à€
+à€¡à€à€£ à€à€²à¥à€¯à€Ÿà€ž à€à€³à€µà€Ÿ.}  
+
+_textgs3title_ [l=mr] {à€¯à€Ÿ à€à€Ÿà€®à€Ÿà€®à€§à¥à€¯à¥}  
+_textgs3_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à¥© à€¹à¥ à€ªà¥à€°à¥à€£ à€¬à€Šà€²à€²à¥ à€à€¹à¥
+à€žà€§à¥à€¯à€Ÿ à€µà€Ÿà€ªà€°à€€ à€
+à€žà€²à¥à€²à¥à€¯à€Ÿ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à¥š à€ªà¥à€à¥à€·à€Ÿ à€¹à¥ à€
+à€Šà¥à€¯à€¯à€Ÿà€µà€€ à€à¥à€²à¥à€²à¥ à€à€¹à¥  (à€žà€§à¥à€¯à€Ÿà€à¥ à€µà¥à€¹à€°à¥à€à€š)--à€à€Šà€Ÿà€¹à€°à€£, 
+à€¹à¥ à€¬à€¹à¥à€­à€Ÿà€·à€¿à€, à€®à€²à¥à€à¥à€ªà¥à€²à¥
+à€à€«à¥à€®, à€à€£à€¿ à€à¥à€šà¥à€«à€¿à€à€° à€à¥à€²à¥à€²à¥ à€à€¹à¥.à€žà€§à¥à€¯à€Ÿà€à¥ à€µà¥à€¹à€°à¥à€à€šà€®à€§à¥à€² à€žà€°à¥à€µ 
+à€à€à€ à€¯à€Ÿà€®à€§à¥à€¯à¥ à€à€¹à¥à€€, à€à€£à€¿ à€®à€Ÿà€à¥à€²   à€µà¥à€¹à€°à¥à€à€š à€¹à¥ à€ªà¥à€°à€ à€à€¹à¥
+:à€®à¥à€¹à€£à€à¥ à€¯à€Ÿà€®à€§à¥à€¯à¥ à€à€§à¥à€à€Ÿ à€žà€à€à¥à€°à€¹à€¬à€Šà€² à€š à€à€°à€€à€Ÿ à€€à€žà€Ÿà€ à€°à€Ÿà€¹à€€à¥ à€µ à€€à¥à€¯à€Ÿà€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€€à€Ÿ à€¯à¥à€€à¥
+ à€à€Ÿà€µà€Ÿ à€¯à€Ÿ  à€ªà¥à€°à¥à€à¥à€°à¥
+à€® à€®à€§à¥à€¯à¥ à€²à€¿à€¹à€¿à€²à¥à€¯à€Ÿà€šà¥ à€¯à€Ÿà€à¥ à€°à€à€šà€Ÿ à€šà¥à€à€µà¥à€°à€ à€žà€Ÿà€°à€à¥ à€
+à€žà€€à¥ 
+à€à€à¥à€ž à€à€®à€à€² à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à¥à€š à€¯à€Ÿ à€®à¥à€¡à¥à€¯à¥à€² à€¶à¥ à€žà€à€ªà¥à€°à€ à€à€°à€€à€Ÿ à€¯à¥à€€à¥: à€€à€žà¥à€
+ à€¹à¥ à€à€µà€¶à¥à€¯à€à¥à€€à¥à€šà¥à€žà€Ÿà€° à€µà€¿à€µà€¿à€§à€žà¥à€°à€µà¥à€¹à€° à€Šà€¿à€žà¥ à€¶à€à€€à¥
+à€à¥à€°à€šà€žà¥à€à¥ à¥© à€¹à¥ à€
+à€Šà¥à€¯à€¯à€Ÿà€µà€€ à€
+à€žà¥à€š à€€à¥ à€ªà¥à€°à€Ÿà€¯à¥à€à€¿à€ à€€à¥à€žà€Ÿà€ à¥ 
+ <a href="http://www.greenstone.org/greenstone3.html">Greenstone 3 home page</a>.à€¯à¥à€¥à¥à€à€ªà€²à€¬à¥à€§ à€à€¹à¥}  
+
+_textcreditstitle_ [l=mr] {à€à€®à€Ÿ}  
+
+_textwhoswho_ [l=mr] {The Greenstone software is a collaborative effort between many
+people. Rodger McNab and Stefan Boddie are the principal architects and
+implementors.  Contributions have been made by David Bainbridge, George
+Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John
+McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd
+Reed, Bill Rogers, John Thompson, and Stuart Yeates. Other members of the New Zealand
+Digital Library project provided advice and inspiration in the design of
+the system: Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka
+Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols and Lloyd Smith. We would also like to
+acknowledge all those who have contributed to the GNU-licensed packages
+included in this distribution: MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE and XLHTML.
+}  
+
+_textaboutgslong_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€
+à€à€à€¿à€à¥à€€ à€à¥à€°à€à€¥à€Ÿà€²à€¯ à€à€Ÿà€°à¥à€¯à€à¥à€°à€®à€Ÿ à€µà€¿à€·à€¯à¥}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=mr] {à€žà€§à¥à€¯à€Ÿà€à¥ à€¯à¥à€à€° }  
+_textuser_ [l=mr] {à€¯à¥à€à€°}  
+_textas_ [l=mr] {à€à€Ÿà€€à¥à€¯à€Ÿà€à¥ à€žà¥à€¥à€¿à€€à¥}  
+_textgroups_ [l=mr] {à€à€}  
+_textcomment_ [l=mr] {à€­à€Ÿà€·à¥à€¯ }  
+_textadduser_ [l=mr] {à€šà€µà¥à€š à€¯à¥à€à€° à€­à€°à€Ÿ}  
+_textedituser_ [l=mr] {à€€à€ªà€Ÿà€žà€Ÿ}  
+_textdeleteuser_ [l=mr] {à€à€Ÿà€¢à¥à€š à€à€Ÿà€à€Ÿ}  
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=mr] {à€¯à¥à€à€°à€à¥ à€®à€Ÿà€¹à€¿à€€à¥ à€žà€à€ªà€Ÿà€Šà€š à€à€°à€Ÿ}  
+_textadduser_ [l=mr] {à€šà€µà¥à€š à€¯à¥à€à€° à€€à€¯à€Ÿà€° à€à€°à€Ÿ }  
+
+_textaboutusername_ [l=mr] {à€¯à¥à€à€°à€Ÿà€à¥ à€šà€Ÿà€µ à€¹à¥ à¥š à€€à¥ à¥©à¥Š à€
+à€à¥à€·à€°à€Ÿà€à€ªà€°à¥à€¯à€à€€ à€
+à€žà€Ÿà€µà¥.à€€à¥à€¯à€Ÿà€®à€§à¥à€¯à¥ à€à€à€¡à¥, à€
+à€à¥à€·à€°, '.' à€à€¿à€à€µà€Ÿ '_' à€
+à€žà€Ÿà€µà¥.}  
+
+_textaboutpassword_ [l=mr] {à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š (à€ªà€Ÿà€žà€µà€°à¥à€¡) à¥© à€€à¥   à¥§à¥šà¥® à€à€€à€à€Ÿ à€
+à€žà€Ÿà€µà€Ÿ.  à€€à¥à€¯à€Ÿà€€ à€¶à€¬à¥à€Š, à€
+à€à€ à€
+à€¥à€µà€Ÿ à€à€€à€° à€à¥à€£à€Ÿ à€
+à€žà€Ÿà€µà¥à€¯à€Ÿà€€. }  
+
+_textoldpass_ [l=mr] {à€¹à€Ÿ à€µà€¿à€­à€Ÿà€ à€°à€¿à€à€Ÿà€®à€Ÿ à€
+à€žà€²à¥à€¯à€Ÿà€ž à€à¥à€šà€Ÿ à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š à€µà€Ÿà€ªà€°à€Ÿ.}  
+_textenabled_ [l=mr] {à€ªà€°à€µà€Ÿà€šà€à¥ à€Šà¥à€¯à€Ÿ}  
+_textdisabled_ [l=mr] {à€ªà€°à€µà€Ÿà€šà€à¥ à€šà€Ÿà€à€Ÿà€°à€Ÿ }  
+
+_textaboutgroups_ [l=mr] {à€žà¥à€µà€²à¥à€ªà€µà€¿à€°à€Ÿà€®à€Ÿà€šà¥ à€à€ à€€à€¯à€Ÿà€° à€¹à¥à€€à¥, à€žà¥à€µà€²à¥à€ªà€µà€¿à€°à€Ÿà€®à€Ÿà€šà€à€€à€° à€
+à€à€€à€° à€ à¥à€µà¥ à€šà€à€Ÿ}  
+_textavailablegroups_ [l=mr] {à€à€§à¥ à€ à€°à€µà€²à¥à€²à¥à€¯à€Ÿ à€à€à€Ÿà€à€®à€§à¥à€² à€ªà¥à€°à€¶à€Ÿà€žà€ à€à€£à€¿ à€à€€à€°à€Ÿà€à€šà€Ÿà€  à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€à€Ÿ à€²à€Ÿà€¯à€¬à¥à€°à€°à¥à€¯à€š à€à€à€à€°à€«à¥à€ž  à€à€¿à€à€µà€Ÿ à€¡à€¿à€ªà€Ÿà€à€à€¿à€à€° à€µà€Ÿà€ªà€°à¥à€š à€šà€µà¥à€š à€®à€Ÿà€¹à€¿à€€à¥ à€žà€Ÿà€ à€Ÿ à€€à€¯à€Ÿà€° à€à€°à€€à€Ÿ à€¯à¥à€à€². <ul>
+<li><b>à€ªà¥à€°à€¶à€Ÿà€žà€</b>: à€¯à¥à€à€° à€à€Ÿà€€à¥ à€à€£à€¿ à€žà€Ÿà€à€ à€à¥à€šà¥à€«à€¿à€à¥à€°à¥à€¶à€š à€žà€Ÿà€ à¥ à€ªà€°à€µà€Ÿà€šà€à¥
+<li><b>à€µà¥à€¯à€à¥à€€à€¿à€ à€žà€à€à¥à€°à€¹à€Ÿà€à€Ÿ à€žà€à€ªà€Ÿà€Šà€ </b>: à€µà¥à€¯à€à¥à€€à€¿à€ à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€ªà€°à€µà€Ÿà€šà€à¥ à€Šà¥à€¯à€Ÿ
+<li><b><à€žà€à€à¥à€°à€¹à€Ÿà€à¥ à€šà€Ÿà€µ >-à€žà€à€à¥à€°à€¹à€Ÿà€à€Ÿ à€žà€à€ªà€Ÿà€Šà€r</b>: à€šà€µà¥à€š à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à€£à¥à€¯à€Ÿà€ž à€µ à€šà€Ÿà€µ à€¬à€Šà€²à€£à¥à€¯à€Ÿà€ž à€ªà€°à€µà€Ÿà€šà€à¥ à€Šà¥à€¯à€Ÿ. à€.à€Šà€Ÿ.à€°à¥à€ªà¥à€°à¥à€-à€à€²à¥à€à¥à€¶à€š-à€à€¡à€¿à€à€°
+ <li><b>à€žà€°à¥à€µ-à€žà€à€à¥à€°à€¹à€Ÿà€à€à€Ÿ-à€žà€à€ªà€Ÿà€Šà€</b>: à€žà¥à€µà€€à€à€žà€Ÿà€ à¥ à€à€£à€¿ à€à€€à€°à€Ÿà€à€žà€Ÿà€ à¥ à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€µ à€žà€à€ªà€Ÿà€Šà€¿à€€ à€à€°à€£à¥à€¯à€Ÿà€ž à€ªà€°à€µà€Ÿà€šà€à¥ à€Šà¥à€€à¥ <b>à€žà€°à¥à€µ</b> collections.}  
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=mr] {à€¯à¥à€à€° à€à€Ÿà€¢à¥à€š à€à€Ÿà€à€Ÿ.}  
+_textremwarn_ [l=mr] {à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€à€°à¥à€ à€¯à¥à€à€° à€à€Ÿà€¢à€Ÿà€µà€¯à€Ÿà€à€Ÿ à€à€¹à¥?}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=mr] {à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š à€¬à€Šà€²à€Ÿ.}  
+_textoldpw_ [l=mr] {à€à¥à€šà€Ÿ à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š}  
+_textnewpw_ [l=mr] {à€šà€µà¥à€š à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š}  
+_textretype_ [l=mr] {à€šà€µà¥à€š à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š à€ªà¥à€šà¥à€¹à€Ÿ à€à€Ÿà€à€ª à€à€°à€Ÿ}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=mr] {à€€à¥à€®à€à€Ÿ à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š à€¯à€¶à€žà¥à€µà¥à€°à€¿à€€à¥à€¯à€Ÿ à€¬à€Šà€²à€²à€Ÿ à€à€¹à¥}  
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=mr] {à€¯à¥à€à€°à€Ÿà€à¥ à€šà€Ÿà€µ à€šà€¿à€°à¥à€ªà€¯à¥à€à¥}  
+_textinvalidpassword_ [l=mr] {à€
+à€¯à¥à€à¥à€¯ à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š}  
+_textemptypassword_ [l=mr] {à€à¥à€ªà€¯à€Ÿ à€¯à€Ÿ à€¯à¥à€à€°à€žà€Ÿà€ à¥ à€žà¥à€°à¥à€µà€Ÿà€€à¥à€à€Ÿ à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š à€Šà¥à€¯à€Ÿ}  
+_textuserexists_ [l=mr] {à€¹à¥ à€¯à¥à€à€° à€šà€Ÿà€µ à€à€ªà€²à€¬à¥à€§ à€šà€Ÿà€¹à¥ , à€à¥à€ªà€¯à€Ÿ à€Šà¥à€žà€°à¥ à€šà€¿à€µà€¡à€Ÿ.}  
+
+_textusernameempty_ [l=mr] {à€¯à¥à€à€° à€šà€Ÿà€µ à€²à€¿à€¹à€Ÿ
+}  
+_textpasswordempty_ [l=mr] {à€€à¥à€®à€à€Ÿ à€à¥à€šà€Ÿ à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š à€¯à¥à€¥à¥ à€²à€¿à€¹à€Ÿ}  
+_textnewpass1empty_ [l=mr] {à€€à¥à€®à€à€Ÿ à€šà€µà¥à€š à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š à€Šà¥à€à€š à€ªà¥à€šà¥à€¹à€Ÿ à€²à€¿à€¹à€Ÿ}  
+_textnewpassmismatch_ [l=mr] {à€€à¥à€®à€à¥à€¯à€Ÿ à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Šà€Ÿà€à¥ à€Šà¥à€š à€­à€Ÿà€·à€Ÿà€à€€à€°à¥ à€à¥à€³à€€ à€šà€Ÿà€¹à¥à€€}  
+_textnewinvalidpassword_ [l=mr] {à€€à¥à€®à¥à€¹à¥ à€à¥à€à¥à€à€Ÿ à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š à€²à€¿à€¹à€¿à€²à€Ÿ}  
+_textfailed_ [l=mr] {à€¯à¥à€à€° à€žà€à€à¥à€à€Ÿ à€à€¿à€à€µà€Ÿ à€à¥à€£à¥à€à¥ à€žà€à€à¥à€à€Ÿ à€¯à¥à€à¥à€¯ à€šà€Ÿà€¹à¥}  
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€à€µà¥à€€à¥à€€à¥ à€à¥à€°à€®à€Ÿà€à€}  
+_textframebrowser_ [l=mr] {à€¹à¥ à€Šà€Ÿà€à€µà€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€€à¥à€®à€à¥à€¯à€Ÿà€à€¡à¥ à€¯à¥à€à¥à€¯ à€¬à¥à€°à€Ÿà€à€à€° à€
+à€žà€Ÿà€µà€¯à€Ÿà€ž à€¹à€µà€Ÿ}  
+_textusermanage_ [l=mr] {à€¯à¥à€à€°à€Ÿà€à¥ à€µà¥à€¯à€µà€žà¥à€¥à€Ÿà€ªà€š}  
+_textlistusers_ [l=mr] {à€¯à¥à€à€° à€¯à€Ÿà€Šà¥}  
+_textaddusers_ [l=mr] {à€šà€µà¥à€š à€¯à¥à€à€° à€­à€°à€Ÿ}  
+_textchangepasswd_ [l=mr] {à€žà€Ÿà€à€à¥à€€à€¿à€ à€¶à€¬à¥à€Š à€¬à€Šà€²à€Ÿ}  
+_textinfo_ [l=mr] {à€€à€Ÿà€à€€à¥à€°à€¿à€ à€®à€Ÿà€¹à€¿à€€à¥}  
+_textgeneral_ [l=mr] {à€žà€Ÿà€§à€Ÿà€°à€£}  
+_textarguments_ [l=mr] {à€µà€¿à€·à€¯}  
+_textactions_ [l=mr] {à€à¥à€€à¥}  
+_textbrowsers_ [l=mr] {à€¬à¥à€°à€Ÿà€à€à€°}  
+_textprotocols_ [l=mr] {à€šà€¿à€¯à€®à€Ÿà€µà€²à¥}  
+_textconfigfiles_ [l=mr] {à€à¥à€šà€«à€¿à€à€°à¥à€¶à€š à€«à€Ÿà€à€²à¥à€ž}  
+_textlogs_ [l=mr] {à€²à¥à€à¥à€}  
+_textusagelog_ [l=mr] {à€¯à¥à€à€° à€²à¥à€}  
+_textinitlog_ [l=mr] {à€²à¥à€}  
+_texterrorlog_ [l=mr] {à€à¥à€à€Ÿ à€Šà€°à¥à€¶à€µà€£à€Ÿà€°à€Ÿ à€²à¥à€}  
+_textadminhome_ [l=mr] {à€ªà¥à€°à€¶à€Ÿà€žà€à€¿à€¯ à€ªà€Ÿà€š}  
+_textreturnhome_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¹à¥à€®}  
+_titlewelcome_ [l=mr] {à€ªà¥à€°à€¶à€Ÿà€žà€à€¿à€¯}  
+_textmaas_ [l=mr] {à€žà€à€°à€à¥à€·à€£ à€µà€ªà¥à€°à€¶à€Ÿà€žà€à¥à€¯  à€žà¥à€µà¥ à€žà€¹ à€à€ªà€²à€¬à¥à€§}  
+_textvol_ [l=mr] {à€à€š à€²à€Ÿà€à€š à€µà€°à¥à€² à€²à¥à€ à€Šà€Ÿà€à€µà€Ÿ}  
+_textcmuc_ [l=mr] {à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€°à€Ÿ,à€°à€Ÿà€à€Ÿ à€µ à€žà¥à€§à€Ÿà€°à¥à€€ à€à€°à€Ÿ}  
+_textati_ [l=mr] {à€žà¥à€à¥à€à€¯ à€ªà¥à€°à€®à€Ÿà€£à¥ à€€à€Ÿà€à€€à¥à€°à€¿à€ à€®à€Ÿà€¹à€¿à€€à¥ à€ªà€¹à€Ÿ}  
+
+_texttsaa_ [l=mr] {à€¯à€Ÿ à€ªà€Ÿà€šà€Ÿà€µà€°à¥à€² à€¡à€Ÿà€µà¥à€à€¡à¥à€² à€šà¥à€µà¥à€¹à¥à€à¥à€¶à€š à€¬à€Ÿà€° à€®à€§à¥à€š à€¹à¥ à€à€Ÿà€® à€à€°à¥ à€¶à€à€€à€Ÿ.}  
+
+_textcolstat_ [l=mr] {à€žà€à€à¥à€°à€¹à€Ÿà€à¥ à€žà¥à€¥à€¿à€€à¥ }  
+
+_textcwoa_ [l=mr] {build.cfg  à€«à€Ÿà€à€² à€à€° à€à€Ÿà€¯à€°à¥à€°à€€ à€
+à€žà¥à€² à€€à€° à€žà€à€à¥à€°à€¹ à€Šà€¿à€žà¥à€² à€€à€žà¥à€ à€€à¥ à€µà€Ÿà€à€€à€Ÿ à€¯à¥à€à€² à€µ à€€à¥à€¯à€Ÿà€à¥ à€à€ à€µà€¿à€¶à€¿à€·à¥à€  à€€à€Ÿà€°à¥à€ à€
+à€žà¥à€² (à€à€¶à¥ > à¥Š) à€žà€à€à¥à€°à€¹ à€à€²à¥à€à¥à€¶à€š à€¡à€¿à€°à¥à€à¥à€à€°à¥ à€®à€§à¥à€¯à¥ à€
+à€žà¥à€² ( building à€¡à€¿à€°à¥à€à¥à€à€°à¥ à€®à€§à¥à€¯à¥ à€šà€žà¥à€²)}  
+
+_textcafi_ [l=mr] {à€Šà€Ÿà€¬à€Ÿ <i>à€žà€à€à¥à€·à€¿à€ªà¥à€€. </i> à€žà€à€à¥à€°à€¹à€Ÿà€€à¥à€² à€®à€Ÿà€¹à€¿à€€à¥à€žà€Ÿà€ à¥ }  
+_textcctv_ [l=mr] {à€Šà€Ÿà€¬à€Ÿ <i>à€žà€à€à¥à€°à€¹</i> à€žà€à€à¥à€°à€¹ à€¬à€à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ }  
+_textsubc_ [l=mr] {à€¬à€Šà€² à€ à¥à€µà€Ÿ}  
+_texteom_ [l=mr] {à€®à¥à€à¥à€¯ à€žà¥à€à€«à€à¥ à€à€à€¡à€£à¥à€¯à€Ÿà€€ à€à¥à€}  
+_textftum_ [l=mr] {à€®à¥à€à¥à€¯ à€žà¥à€à€«à€à¥ à€«à€Ÿà€à€² à€žà¥à€§à€Ÿà€°à€£à¥à€¯à€Ÿà€ž à€
+à€ªà€¯à€¶}  
+_textmus_ [l=mr] {à€®à¥à€à¥à€¯ à€žà¥à€à€«à€à¥ à€¯à€¶à€žà¥à€µà¥à€ªà€£à¥ à€žà¥à€§à€Ÿà€°à¥à€€ à€à€Ÿà€²à¥}  
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=mr] {à€žà€à€à¥à€°à€¹ à€žà€Ÿà€°à€Ÿà€à€¶à€Ÿà€ž à€šà€Ÿà€µ à€Šà¥à€¯à€Ÿ}  
+_textflog_ [l=mr] {à€«à¥à€² à€²à¥à€ à€«à¥à€°"_ à€à€²à¥à€à¥à€¶à€š à€šà¥à€®_" à€à€²à¥à€à¥à€¶à€š}  
+_textilog_ [l=mr] {à€à€à€ªà¥à¥à€°à€  à€²à¥à€ à€«à¥à€°"_ à€à€²à¥à€à¥à€¶à€š à€šà¥à€®_" à€à€²à¥à€à¥à€¶à€š}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=mr] {à€«à€¿à€¡à€¬à¥
+à€ à€ªà€Ÿà€ à€µà€Ÿ}  
+
+_greenstoneusabilitytext_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€à¥ à€à€ªà€¯à¥à€à€¿à€€à€Ÿ}  
+
+_textwhy_ [l=mr] {à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€µà¥à€¬à€ªà¥à€ à€ªà€Ÿà€¹à€£à¥à€¯à€Ÿà€ž à€
+à€µà€à€¡ à€µà€Ÿà€à€€à¥ à€
+à€žà¥ à€¯à€Ÿ à€šà€¿à€µà¥à€Šà€šà€Ÿà€Šà¥à€µà€°à¥ à€žà¥à€à€¿à€€ à€¹à¥à€€à¥}  
+_textextraforform_ [l=mr] {à€«à¥à€°à¥à€® à€­à€°à€£à¥à€¯à€Ÿà€à¥ à€à€µà€¶à¥à€à€¯à€€à€Ÿ à€šà€Ÿà€¹à¥.  à€à¥à€£à€€à¥à€¹à¥ à€®à€Ÿà€¹à¥à€€à¥ à€à€ªà€¯à¥à€à¥ à€ªà€¡à¥à€². }  
+_textprivacybasic_ [l=mr] {à€¯à€Ÿ à€šà€¿à€µà¥à€Šà€šà€Ÿà€€ à€«à€à¥à€€ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€µà¥à€¬ à€ªà¥à€ à€¬à€Šà¥à€Šà€² à€µ à€€à¥à€®à¥à€¹à¥ à€µà€Ÿà€ªà€°à€€ à€
+à€žà€²à¥à€²à¥à€¯à€Ÿ à€€à€à€€à¥à€°à€Ÿà€šà€Ÿà€¬à€Šà¥à€Šà€²  à€®à€Ÿà€¹à€¿à€€à¥ à€à€¹à¥}  
+_textstillsend_ [l=mr] {à€€à¥à€®à¥à€¹à€Ÿà€²à€Ÿ à€
+à€à¥à€šà€¹à¥ à€¹à€Ÿ à€°à€¿à€ªà¥à€°à¥à€ à€ªà€Ÿà€ à€µà€Ÿà€¯à€²à€Ÿ à€à€µà€¡à¥à€²?}  
+
+_texterror_ [l=mr] {à€à¥à€}  
+_textyes_ [l=mr] {à€¹à¥à€¯}  
+_textno_ [l=mr] {à€šà€Ÿà€¹à¥}  
+_textclosewindow_ [l=mr] {à€à€¿à€¡à€à¥ à€¬à€à€Š à€à€°à€Ÿ}  
+_textabout_ [l=mr] {à€à¥à€¯à€Ÿ à€µà€¿à€·à€¯à¥.}  
+_textprivacy_ [l=mr] {à€à€Ÿà€à€à¥}  
+_textsend_ [l=mr] {à€ªà€Ÿà€ à€µà€Ÿ}  
+_textdontsend_ [l=mr] {à€ªà€Ÿà€ à€µà¥ à€šà€à€Ÿ}  
+_textoptionally_ [l=mr] {à€ªà€°à¥à€¯à€Ÿà€¯à¥}  
+
+_textunderdev_ [l=mr] {à€žà€µà€¿à€žà¥à€€à€°à€ªà€£à¥ à€®à¥à€à¥à€¯ à€à€µà¥à€€à¥à€€à¥ à€®à€§à¥à€¯à¥ à€à€ªà€²à€¬à¥à€§ à€¹à¥à€à€²}  
+
+_textviewdetails_ [l=mr] {à€šà€¿à€µà¥à€Šà€š à€žà€µà€¿à€žà¥à€€à€° à€Šà€Ÿà€à€µà€Ÿ.}  
+_textmoredetails_ [l=mr] {à€žà€µà€¿à€žà¥à€€à€°}  
+_texttrackreport_ [l=mr] {à€šà€¿à€µà¥à€Šà€š à€ªà€¹à€Ÿ}  
+_textcharacterise_ [l=mr] {à€à€Ÿà€¯ à€¶à€à€à€Ÿ à€à€¹à¥}  
+_textseverity_ [l=mr] {à€à¥à€ }  
+ 
+_textbadrender_ [l=mr] {à€
+à€ªà€°à€¿à€à€¿à€€ à€ªà€Ÿà€š}  
+_textcontenterror_ [l=mr] {à€žà¥à€à¥à€ªà€€à¥à€° à€à¥à€}  
+_textstrangebehaviour_ [l=mr] {à€µà€¿à€à€¿à€€à¥à€° à€µà€Ÿà€à€£à¥à€}  
+_textunexpected_ [l=mr] {à€à€Ÿà€¹à¥à€€à€°à¥ à€
+à€šà€ªà¥à€à¥à€·à€¿à€€ à€à€Ÿà€²à¥}  
+_textfunctionality_ [l=mr] {à€µà€Ÿà€ªà€°à€£à¥à€¯à€Ÿà€ž à€
+à€µà€à€¡}  
+_textother_ [l=mr] {à€à€€à€°}  
+
+_textcritical_ [l=mr] {à€
+à€µà€à€¡}  
+_textmajor_ [l=mr] {à€®à€¹à€€à¥à€µà€Ÿà€à€Ÿ}  
+_textmedium_ [l=mr] {à€®à€Ÿà€§à¥à€¯à€® }  
+_textminor_ [l=mr] {à€à¥à€·à¥à€²à¥à€²à€}  
+_texttrivial_ [l=mr] {à€à¥à€·à¥à€²à¥à€²à€}  
+
+_textwhatdoing_ [l=mr] {à€€à¥à€®à¥à€¹à¥ à€à€Ÿà€¯ à€à€°à€£à¥à€¯à€Ÿà€à€Ÿ à€ªà¥à€°à€¯à€€à¥à€š à€à€°à¥à€€ à€à€¹à€Ÿà€€?}  
+_textwhatexpected_ [l=mr] {à€€à¥à€®à€à¥à€¯à€Ÿ à€
+à€ªà¥à€à¥à€·à¥à€ªà¥à€°à€®à€Ÿà€£à¥ à€à€Ÿà€¯ à€µà¥à€¹à€Ÿà€µà€¯à€Ÿà€ž à€¹à€µà¥?}  
+_textwhathappened_ [l=mr] {à€ªà¥à€°à€€à¥à€¯à€à¥à€·à€Ÿà€€ à€à€Ÿà€¯ à€à€Ÿà€²à¥.}  
+
+_cannotfindcgierror_ [l=mr] {<h2>à€žà€Ÿà€à€°à¥!</h2> à€®à¥à€à¥à€¯ à€žà€à€à€£à€à€à€²à€Ÿ "_linktextusab_"  à€¹à¥ à€ªà¥à€°à€£à€Ÿà€²à¥ à€žà€Ÿà€ªà€¡à€€ à€šà€Ÿà€¹à¥.}  
+
+_textusabbanner_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š  koru-style banner}  
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=mr] {à€à¥à€à¥à€à¥ à€à€¹à¥.}  
+
+_textgtihome_ [l=mr] {à€¯à€Ÿà€ªà€Ÿà€šà€Ÿà€µà¥à€Šà€Ÿà€°à¥ à€€à¥à€®à¥à€¹à¥ à€¬à€¹à¥à€­à€Ÿà€·à€Ÿ à€¯à€Ÿ à€à€à€à€Ÿà€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à¥ à€¶à€à€€à€Ÿ,à€€à¥à€¯à€Ÿ à€µà¥à€Šà€Ÿà€°à¥
+ <ul>
+   <li>à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€à¥ à€šà€µà¥à€š à€­à€Ÿà€·à¥à€€ à€­à€Ÿà€·à€Ÿà€à€€à€° à€à€°à€£à¥
+   <li>à€žà€§à¥à€¯à€Ÿ à€à€ªà€¯à¥à€à€Ÿà€€ à€
+à€žà€²à¥à€²à¥ à€­à€Ÿà€·à€Ÿ à€
+à€Šà€¯à€¯à€Ÿà€µà€€ à€à€°à€Ÿ, à¥à€µà¥à€¹à€Ÿ à€à€à€à¥à€°à€à¥ à€­à€Ÿà€·à€Ÿ à€¬à€Šà€²à€£à€Ÿà€° à€à€¹à¥ (à€à€Šà€Ÿà€à€à¥à€°à¥à€šà€žà¥à¥à€š à€®à€§à¥à€² à€šà€µà¥à€š à€žà¥à€ à€žà€Ÿà€ à¥)
+   <li>à€žà€§à€¯à€Ÿ à€
+à€žà€²à¥à€²à¥à€¯à€Ÿ à€­à€Ÿà€·à€Ÿà€à€€à€°à€Ÿà€€à¥à€² à€à¥à€à€Ÿ à€Šà¥à€°à¥à€žà¥à€€ à€à€°à€Ÿ
+ </ul>
+
+ à€€à¥à€®à¥à€¹à€Ÿà€à€²à€Ÿ à€µà¥à€¬ à€ªà€Ÿà€šà¥ à€à¥à€°à€®à€µà€Ÿà€°à¥à€€ à€®à€¿à€³à€€à¥à€²,
+ à€à¥à€¯à€Ÿ à€®à€§à¥à€¯à¥ à€­à€Ÿà€·à€Ÿà€à€€à€°à¥à€€ à€µà€Ÿà€à¥à€ªà¥à€°à€à€Ÿà€° à€®à€¿à€³à€€à¥à€²
+à€­à€Ÿà€·à¥à€à¥à€¯à€Ÿ à€à€à€à€°à€«à¥à€ž à€®à€§à¥à€¯à¥ à€€à¥à€®à¥à€¹à¥ à€à€ à€à€  à€µà€Ÿà€à¥à€ªà¥à€°à€à€Ÿà€° à€­à€Ÿà€·à€Ÿà€à€€à€°à¥à€€ à€à€°à¥ à€¶à€à€€à€Ÿ.
+ à€
+à€šà¥à€ à€µà€Ÿà€à¥à€ªà¥à€°à€à€Ÿà€°à€Ÿà€à€®à€§à¥à€¯à¥ à€à€à€à€¿à€à€®à€à€² à€à€Ÿ à€µà€Ÿà€ªà€° à€à¥à€²à¥à€²à€Ÿ à€à€¹à¥: à€¯à€Ÿà€à¥ à€€à¥à€®à¥à€¹à€Ÿà€à€²à€Ÿ
+ à€­à€Ÿà€·à€Ÿà€à€€à€° à€à€°à€£à¥à€¯à€Ÿà€à¥ à€à€°à€ à€šà€Ÿà€¹à¥ à€ªà€£à€€à¥à€¯à€Ÿà€€ à€¬à€Šà€² à€à€°à¥ à€šà€¯à¥
+ (like _this_) à€
+à€žà¥ à€¶à€¬à¥à€§, à€à¥ à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€à¥ à€žà€à€à¥à€·à€¿à€ªà¥à€€ à€°à¥à€ª à€à€¹à¥à€€ 
+ <p>à€à€° à€€à¥à€®à¥à€¹à¥ à€žà€à€à¥à€à€Ÿ à€
+à€Šà¥à€¯à€¯à€Ÿà€µà€€ à€à€°à€€ à€
+à€žà€Ÿà€² à€€à€° à€€à¥à€®à¥à€¹à€Ÿà€à€²à€Ÿ à€à€§à¥à€à¥à€¯à€Ÿ à€žà€à€à¥à€à€Ÿ à€ªà€Ÿà€¹à€£à¥à€¯à€Ÿà€à¥ à€à€µà€¶à¥à€¯à€à¥à€€à€Ÿ à€šà€Ÿà€¹à¥.à€à€§à¥ à€à€§à¥ à€à¥à€²à¥à€²à¥ à€­à€Ÿà€·à€Ÿà€à€€à€° à€¹à¥ à€à€à€à¥à€°à€à¥ à€­à€Ÿà€·à¥à€®à¥à€³à¥ à€¬à€Šà€²à€²à¥ à€à€Ÿà€€à¥.à€
+à€¶à€Ÿà€µà¥à€³à¥ à€žà€§à¥à€¯à€Ÿ à€à¥à€²à¥à€²à¥à€¯à€Ÿ à€­à€Ÿà€·à€Ÿà€à€€à€°à€Ÿà€µà€°à¥à€š à€€à¥à€®à¥à€¹à¥ à€€à¥ à€€à€ªà€Ÿà€žà¥ à€¶à€à€€à€Ÿ.
+<P>
+à€à€§à¥ à€à¥à€²à¥à€²à¥ à€­à€Ÿà€·à€Ÿà€à€€à€° à€Šà¥à€°à¥à€žà¥à€€ à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ "à€à¥à€²à¥à€²à¥ à€­à€Ÿà€·à€Ÿà€à€€à€° à€Šà¥à€°à¥à€žà¥à€€ à€à€°à€Ÿ "à€¯à€Ÿ à€«à€Ÿà€à€²à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€Ÿ.
+<P>
+ nzdl.org à€žà€Ÿà€à€à€µà€° à€à€Ÿà€£à¥à€¯à€Ÿà€à€°à¥à€€à€Ÿ à€ªà¥à€°à€€à¥à€¯à¥à€ à€ªà€Ÿà€šà€Ÿà€µà€° "_textgtisubmit_" à€¹à¥ à€¬à€à€š à€Šà€¿à€²à¥à€²à¥ à€à€¹à¥.à€¹à¥ à€¬à€à€š à€Šà€Ÿà€¬à¥à€š à€¬à€Šà€² à€à€°à¥ à€¶à€à€€à€Ÿ
+ }  
+
+_textgtiselecttlc_ [l=mr] {à€à¥à€ªà€¯à€Ÿ à€€à¥à€®à€à¥à€¯à€Ÿ à€­à€Ÿà€·à¥à€à¥ à€šà€¿à€µà€¡ à€à€°à€Ÿ}  
+
+#for status page
+_textgtiviewstatus_ [l=mr] {Click to view the current translation status for all languages}  
+_textgtiviewstatusbutton_ [l=mr] {VIEW STATUS}  
+_textgtistatustable_ [l=mr] {List of current translation status for all languages}  
+_textgtilanguage_ [l=mr] {à€­à€Ÿà€·à€Ÿ}  
+_textgtitotalnumberoftranslations_ [l=mr] {Total number of translations}  
+
+_textgtiselecttfk_ [l=mr] {à€à€Ÿà€°à¥à€¯ à€à¥à€£à€€à¥à€¯à€Ÿ à€«à€Ÿà€à€² à€µà€° à€à€°à€Ÿà€µà€¯à€Ÿà€à¥ à€€à¥ à€šà€¿à€¶à¥à€à€¿à€€ à€à€°à€Ÿ}  
+
+_textgticoredm_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€à€à€à€°à€«à¥à€ž (à€®à€§à¥à€¯)}  
+_textgtiauxdm_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€à€Ÿ à€žà€¹à€Ÿà€¯à¥à€¯à€à€Ÿà€°à¥ à€à€à€°à€«à¥à€ž}  
+_textgtiglidict_ [l=mr] {à€à¥à€à€²à€à€¯ à€¡à€¿à€à¥à€¶à€šà€°à¥}  
+_textgtiglihelp_ [l=mr] {à€à¥à€à€²à€à€¯ à€®à€Šà€€}  
+_textgtiperlmodules_ [l=mr] {à€ªà€°à¥à€² à€®à¥à€¡à¥à€¯à¥à€²à€žà¥}  
+_textgtitutorials_ [l=mr] {à€à¥à€à¥à€°à€¿à€
+à€² à€à€à¥à€žà€žà€Ÿà€à€}  
+_textgtigreenorg_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š.à€à€°à€à¥}  
+_textgtigs3interface_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à¥© à€à€à€à€°à€«à¥à€ž}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=mr] {Greenstone Developer's Manual}  
+_textgtiinstallmanual_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¡à€Ÿà€à€šà€²à¥à€¡à€à¥ à€®à€Ÿà€¹à€¿à€€à¥ à€ªà€€à¥à€°à€}  
+_textgtipapermanual_ [l=mr] {Greenstone Manual for Paper to Collection}  
+_textgtiusermanual_ [l=mr] {Greenstone User's Manual}  
+
+_textgtienter_ [l=mr] {à€ªà¥à€°à€µà¥à€¶}  
+
+_textgticorrectexistingtranslations_ [l=mr] {à€­à€Ÿà€·à€Ÿà€à€€à€° à€Šà¥à€°à¥à€žà¥à€€ à€à€°à€Ÿ.}  
+_textgtidownloadtargetfile_ [l=mr] {à€¡à€Ÿà€à€šà€²à¥à€¡ à€«à€Ÿà€à€²}  
+_textgtiviewtargetfileinaction_ [l=mr] {à€¹à¥ à€«à€Ÿà€à€² à€à¥à€€à¥à€€ à€Šà€Ÿà€à€µà€Ÿ}  
+_textgtitranslatefileoffline_ [l=mr] {Translate this file offline}  
+
+_textgtinumchunksmatchingquery_ [l=mr] {à€
+à€šà¥à€ à€€à¥à€à€¡à¥à€¯à€Ÿà€à€¶à¥ à€®à€Ÿà€¹à€¿à€€à¥ à€à¥à€³à€€à¥}  
+
+_textgtinumchunkstranslated_ [l=mr] {à€­à€Ÿà€·à€Ÿà€à€€à€° à€à€Ÿà€²à¥}  
+_textgtinumchunksrequiringupdating_ [l=mr] {à€¯à€Ÿ à€ªà¥à€à¥ _à¥§_ à€žà¥à€§à€Ÿà€°à¥à€€ à€à€°à€£à¥ à€à€µà€¶à¥à€¯à€ à€à€¹à¥}  
+_textgtinumchunksrequiringtranslation_ [l=mr] {à€°à€Ÿà€¹à€¿à€²à¥à€²à¥ à€­à€Ÿà€·à€Ÿà€à€€à€°}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=mr] {à€­à€Ÿà€·à€Ÿà€à€€à€° à€à€Ÿà€²à¥}  
+_textgtinumchunksrequiringupdating2_ [l=mr] {à€­à€Ÿà€·à€Ÿà€à€€à€° à€ªà¥à€šà¥à€¹à€Ÿ à€ªà€Ÿà€¹à€£à¥à€¯à€Ÿà€à¥ à€à€°à€ à€à€¹à¥. }  
+_textgtinumchunksrequiringtranslation2_ [l=mr] {à€­à€Ÿà€·à€Ÿà€à€€à€° à€à€°à€Ÿà€µà€¯à€Ÿà€à¥ à€à€¹à¥}  
+
+_textgtienterquery_ [l=mr] {à€Šà¥à€°à¥à€žà¥à€€ à€à€°à€Ÿà€µà€¯à€Ÿà€à€Ÿ à€¶à€¬à¥à€Š à€²à€¿à€¹à€Ÿ}  
+_textgtifind_ [l=mr] {à€¶à¥à€§à€Ÿ}  
+
+_textgtitranslatingchunk_ [l=mr] {à€®à€à€à¥à€°à€Ÿà€€à¥à€² à€­à€Ÿà€·à€Ÿà€à€€à€° <i>_1_</i>}  
+_textgtiupdatingchunk_ [l=mr] {à€
+à€ªà€¡à¥à€à€¿à€à€ à€à¥à€à¥à€ž à€«à¥à€°à¥
+à€à€®à¥à€à€ <i>_1_</i>}  
+_textgtisubmit_ [l=mr] {à€ªà¥à€¢à¥ à€ªà€Ÿà€ à€µà€¿à€£à¥}  
+
+_textgtilastupdated_ [l=mr] {à€žà¥à€§à€Ÿà€°à¥à€€ }  
+
+_textgtitranslationfilecomplete_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€šà€à¥ à€¹à€¿ à€«à€Ÿà€à€² à€žà¥à€§à€Ÿà€°à¥à€€ à€à¥à€²à¥à€¯à€Ÿ à€¬à€Šà¥à€Šà€² à€§à€šà¥à€¯à€µà€Ÿà€Š,à€¹à€¿ à€à€€à€Ÿ à€ªà¥à€°à¥à€£ à€à€Ÿà€²à¥ à€à€¹à¥.
+à€€à¥à€®à¥à€¹à¥ à€¹à€¿ à€«à€Ÿà€à€² à€µà€°à¥à€² à€²à€¿à€à€à€µà¥à€Šà€Ÿà€°à¥ à€¡à€Ÿà€à€šà€²à¥à€¡ à€à€°à¥ à€¶à€à€€à€Ÿ,à€à€£à€¿ à€¹à€¿ à€«à€Ÿà€à€² à€à€€à€Ÿ à€­à€µà€¿à€·à¥à€¯à€Ÿà€€ à€¹à€¿ à€ªà€Ÿà€¹à¥}  
+
+_textgtiofflinetranslation_ [l=mr] {You can translate this part of Greenstone offline using a Microsoft Excel spreadsheet file:
+
+<ol>
+<li>Download <a href="_gwcgi_?a=gti&p=excel&e=_compressedoptions_">this file</a>.
+<li>Open the downloaded file in Microsoft Excel and save as Microsoft Excel workbook (.xls) format.
+<li>Enter the translations in the boxes provided.
+<li>When you have finished translating all the strings, e-mail the .xls file to <a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>.
+</ol>
+}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=mr] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€²à€Ÿà€¯à€¬à¥à€°à€°à¥ à€à€à€à€°à€«à¥à€ž}  
+_textglihelp_ [l=mr] {<p>The Greenstone Librarian Interface (GLI) gives you access to Greenstone's functionality from an easy-to-use, 'point and click' interface. This allows you to collect sets of documents, import or assign metadata, and build them into a Greenstone collection.</p>
+
+<p>Note that the GLI is run in conjunction with Greenstone, and assumes that it is installed in a subdirectory of your Greenstone installation. If you have downloaded one of the Greenstone distributions, or installed from a Greenstone CD-ROM, this will be the case.</p>
+
+<h4>Running the GLI under Windows</h4>
+ 
+Launch the librarian interface under Windows by selecting <i>Greenstone Digital Library</i> from the <i>Programs</i> section of the <i>Start</i> menu and choosing <i>Librarian Interface</i>. 
+
+<h4>Running the GLI under Unix</h4>
+
+To run the GLI under Unix, change to the <i>gli</i> directory in your Greenstone installation, then run the <i>gli.sh</i> script. 
+
+<h4>Running the GLI under Mac OS X</h4>
+
+In the finder, browse to <i>Applications</i> then <i>Greenstone</i> (if you installed Greenstone into the default location), and then launch the <i>GLI</i> application.
+}  
Index: /gsdl/stable/macros/mongolian.dm
===================================================================
--- /gsdl/stable/macros/mongolian.dm	(revision 20131)
+++ /gsdl/stable/macros/mongolian.dm	(revision 20131)
@@ -0,0 +1,1705 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Mongolian Language text and icon macros 
+# Many thanks to Mendbayar Ichinkhorlo (translated December 2004)
+#                B. Sukhbaatar and Ganchimeg (updated April 2008)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=mn] {Ð¢ÐŸÐ³ÑÐŒÐŸÐ» Ñ
+ÑÐ²Ð»ÑÐ»Ò¯Ò¯ÐŽ}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=mn] {Ð­Ñ
+ ÑÑÑÐ²Ð°Ð»Ð¶:}
+_textdate_ [l=mn] {ÐœÐžÐ¹ÑÐ»ÑÐ³ÐŽÑÑÐœ ÐŸÐ³ÐœÐŸÐŸ:}
+_textnumpages_ [l=mn] {Ñ
+ÑÑÐŽÐ°ÑÐœÑ ÐŽÑÐ³Ð°Ð°Ñ:}
+
+_textsignin_ [l=mn] {ÐœÑÐ²ÑÑÑÑ
+}
+
+_textdefaultcontent_ [l=mn] {Ð¥Ð°Ð¹ÑÐ°Ðœ Ñ
+ÑÑÐŽÐ°Ñ ÑÐ°ÐœÑ ÐŸÐ»ÐŽÐŸÐŸÐ³Ò¯Ð¹ ÑÑÐ» Ð±ÑÐ°ÑÐ·ÐµÑÑÐœÑ
+Ð°Ð° "Ð±ÑÑÐ°Ñ
+" ÑÐŸÐ²ÑÐžÐ¹Ð³ Ð±ÐŸÐ»ÐŸÐœ ÐŽÑÑÑ Ð±ÑÐ¹ Ò¯ÐœÐŽÑÑÐœ Ñ
+ÑÑÐŽÐ°Ñ Ð³ÑÑÑÐœ ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐ¶ Greenstone ÐÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÐžÐ¹Ðœ Ñ
+ÑÑÐŽÐ°Ñ ÑÑÑ ÐŸÑÐœÐŸ ÑÑ.}
+
+_textdefaulttitle_ [l=mn] {GSDL ÐÐ»ÐŽÐ°Ð°}
+
+_textbadcollection_ [l=mn] {Ð­ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ (called "_cvariable_") Greenstone ÐŽÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÐžÐ¹Ðœ ÑÐžÑÑÐµÐŒÐŽ ÑÑÑÐ»Ð³Ð°Ð°Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°.}
+
+_textselectpage_ [l=mn] {Ð¥ÑÑÐŽÐ°Ñ ÑÐŸÐœÐ³ÐŸÑ
+}
+
+_collectionextra_ [l=mn] {Ð­ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽ _about:numdocs_ Ð±Ð°ÑÐžÐŒÑ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±Ð° ÑÐŽÐ³ÑÑÑÐžÐ¹Ð³ _about:builddate_ Ó©ÐŽÑÐžÐ¹Ðœ Ó©ÐŒÐœÓ© Ò¯Ò¯ÑÐ³ÑÑÑÐœ.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=mn] {<p>Ð­ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽ ÐœÐžÐ¹Ñ _numbytes_ Ð±Ð°ÑÐžÐŒÑ Ð±Ð°Ð¹Ð³Ð°Ð°.
+<p><a href="_httppagex_(bsummary)">Ð­ÐœÐŽ ÐŽÐ°ÑÐ¶</a> ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÑÐŸÐ²ÑÐ»ÐŸÐ»ÑÐ³ Ñ
+Ð°ÑÐœÐ° ÑÑ.}
+
+_textdescrcollection_ [l=mn] {}
+_textdescrabout_ [l=mn] {Ð¥ÑÑÐŽÐ°ÑÐœÑ ÑÑÑ
+Ð°Ð¹}
+_textdescrhome_ [l=mn] {Ò®ÐœÐŽÑÑÐœ Ñ
+ÑÑÐŽÐ°Ñ}
+_textdescrhelp_ [l=mn] {Ð¢ÑÑÐ»Ð°ÐŒÐ¶ Ñ
+ÑÑÐŽÐ°Ñ}
+_textdescrpref_ [l=mn] {Ð¢ÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐœÑ Ñ
+ÑÑÐŽÐ°Ñ}
+_textdescrgreenstone_ [l=mn] {Greenstone Digital ÐÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÐžÐ¹Ðœ Ð¿ÑÐŸÐ³ÑÐ°ÐŒ Ñ
+Ð°ÐœÐ³Ð°ÐŒÐ¶}
+_textdescrusab_ [l=mn] {Ð¢Ð°ÐœÐŽ Ð°ÑÐžÐ³Ð»Ð°Ñ
+Ð°ÐŽ ÑÑÐžÑÑÐ°Ðœ Ñ
+Ò¯ÐœÐŽÑÑÐ» ÑÑ Ð±Ð°Ð¹Ð²?}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=mn] {Ð¥Ð°Ð¹Ð»Ñ}  
+_labelSearch_ [l=mn] {Ð¥Ð°Ð¹Ñ
+}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=mn] {Ð¡ÑÐŽÑÐ²}  
+_labelTitle_ [l=mn] {ÐÐ°ÑÑÐžÐ³ Ð-Ð¯}
+_textCreator_ [l=mn] {ÐÒ¯ÑÑÑÐ³Ñ}  
+_labelCreator_ [l=mn] {ÐÐŸÑ
+ÐžÐŸÐ³ÑÐžÐŽ Ð-Ð¯}
+_textSubject_ [l=mn] {Ð°ÐœÐ³ÐžÐ»Ð°Ð», ÑÐžÐ³Ð»ÑÐ»}  
+_labelSubject_ [l=mn] {ÐÐ°ÑÑÐžÐ³ÑÑÐŽ}
+_textDescription_ [l=mn] {Ð¢ÐŸÐŽÐŸÑÑ
+ÐŸÐ¹Ð»ÐŸÐ»Ñ}  
+_labelDescription_ [l=mn] {Ð¢Ð°Ð¹Ð»Ð±Ð°Ñ}
+_textPublisher_ [l=mn] {Ð¥ÑÐ²Ð»ÑÐ»ÐžÐ¹Ðœ Ð³Ð°Ð·Ð°Ñ}  
+_labelPublisher_ [l=mn] {ÐÐžÐ¹ÑÐ»ÑÐ³ÑÐžÐŽ}
+_textContributor_ [l=mn] {Ð¥Ð°ÐŒÑÑÐ°Ðœ Ð°Ð¶ÐžÐ»Ð»Ð°Ð³Ñ}  
+_labelContributor_ [l=mn] {Ð¥Ð°ÐœÐŽÐžÐ²Ð»Ð°Ð³ÑÐžÐŽ}
+_textDate_ [l=mn] {ÐÐ³ÐœÐŸÐŸ}  
+_labelDate_ [l=mn] {ÐÐ³ÐœÐŸÐŸ}
+_textType_ [l=mn] {Ð¢Ó©ÑÓ©Ð»}  
+_labelType_ [l=mn] {Ð¢Ó©ÑÐ»Ò¯Ò¯ÐŽ}
+_textFormat_ [l=mn] {Ð€ÐŸÑÐŒÐ°Ñ}  
+_labelFormat_ [l=mn] {Ð€ÐŸÑÐŒÐ°Ñ}
+_textIdentifier_ [l=mn] {Ð¢Ð°ÐœÐžÑ
+ ÑÑÐŒÐŽÑÐ³}  
+_labelIdentifier_ [l=mn] {Ð¢ÐŸÐŽÐŸÑÑ
+ÐŸÐ¹Ð»ÐŸÐ³Ñ}
+_textSource_ [l=mn] {Ð€Ð°Ð¹Ð»ÑÐœ ÐœÑÑ}  
+_labelSource_ [l=mn] {Ð€Ð°Ð¹Ð»ÑÐœ ÐœÑÑÑ}
+_textLanguage_ [l=mn] {Ð¥ÑÐ»}  
+_labelLanguage_ [l=mn] {Ð¥ÑÐ»}
+_textRelation_ [l=mn] {Ð¥Ð°ÐŒÐ°Ð°ÑÐ°Ð»}  
+_labelRelation_ [l=mn] {Ð¥Ð°ÐŒÐ°Ð°ÑÐ»ÑÑÐŽ}
+_textCoverage_ [l=mn] {Ð¥Ð°ÐŒÑÐ°Ñ
+ Ñ
+Ò¯ÑÑÑ}  
+_labelCoverage_ [l=mn] {Ð¥Ð°ÐŒÑÐ°Ñ
+ Ñ
+Ò¯ÑÑÑ}
+_textRights_ [l=mn] {Ð­ÑÑ
+}  
+_labelRights_ [l=mn] {Ð­ÑÑ
+}
+
+# DLS metadata set
+_textOrganization_ [l=mn] {ÐÐ°Ð¹Ð³ÑÑÐ»Ð»Ð°Ð³Ð°}  
+_labelOrganization_ [l=mn] {ÐÐ°Ð¹Ð³ÑÑÐ»Ð»Ð°Ð³ÑÑÐŽ}  
+_textKeyword_ [l=mn] {Ð¢Ò¯Ð»Ñ
+Ò¯Ò¯Ñ Ò¯Ð³}  
+_labelKeyword_ [l=mn] {Ð¢Ò¯Ð»Ñ
+Ò¯Ò¯Ñ Ò¯Ð³}
+_textHowto_ [l=mn] {Ð¥ÑÑÑ
+ÑÐœ}  
+_labelHowto_ [l=mn] {Ð¥ÑÑÑ
+ÑÐœ}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=mn] {Ð¥ÑÐ»Ñ Ò¯Ð³Ñ}  
+_labelPhrase_ [l=mn] {Ð¥ÑÐ»Ñ Ò¯Ð³Ò¯Ò¯ÐŽ}
+_textCollage_ [l=mn] {ÐÐ°Ð²Ñ
+ÑÐ°Ð°}  
+_labelCollage_ [l=mn] {ÐÑÑÐ°Ð³Ð¶ÑÑÐ»Ð°Ñ
+}
+_textBrowse_ [l=mn] {ÐÐ°Ð¹ÑÐ»Ð°Ð»ÑÐ³ Ð·Ð°Ð°Ñ
+, Ñ
+Ó©ÑÐ»Ó©Ñ
+}  
+_labelBrowse_ [l=mn] {ÐÐ°Ð¹ÑÐ»Ð°Ð»ÑÐ³ Ð·Ð°Ð°Ñ
+, Ñ
+Ó©ÑÐ»Ó©Ñ
+}  
+_textTo_ [l=mn] {ÐŽ,Ñ}  
+_labelTo_ [l=mn] {ÑÑÑ}
+_textFrom_ [l=mn] {-Ð°Ð°Ñ' OR Ñ
+Ð°Ð°ÐœÐ°Ð°Ñ(when we use from in question, it is translated Ñ
+Ð°Ð°ÐœÐ°Ð°Ñ)}  
+_labelFrom_ [l=mn] {Ð°Ð°Ñ}
+_textAcronym_ [l=mn] {Ð¢ÐŸÐ²ÑÐ»ÐŸÐ»}  
+_labelAcronym_ [l=mn] {Ð¢ÐŸÐ²ÑÐ»ÐŸÐ»}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=mn] {_1_-Ñ Ð³Ò¯Ð¹Ð»Ð³ÑÐ¶ Ñ
+Ð°ÑÐ°Ñ
+}  
+
+_textdescrSearch_ [l=mn] {Ð¢ÐŸÐŽÐŸÑÑ
+ÐŸÐ¹ ÐœÑÑ ÑÐŸÐŒÑÑÐŸ Ñ
+Ð°Ð¹Ñ
+}
+_textdescrType_ [l=mn] {ÐÓ©Ó©ÑÐžÐ¹Ðœ ÑÓ©ÑÐ»Ó©Ó©Ñ ÐœÑ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ò¯Ð·ÑÑ
+}
+_textdescrIdentifier_ [l=mn] {ÐÓ©Ó©ÑÐžÐ¹Ðœ ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹Ð»ÐŸÐ³ÑÐŸÐŸÑ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ñ
+Ð°ÑÐ°Ñ
+}
+_textdescrSource_ [l=mn] {ÐÐžÐœÑ
+ÑÐœÑ ÑÐ°Ð¹Ð»ÑÐœ ÐœÑÑÑÑÑ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ò¯Ð·ÑÑ
+}
+_textdescrTo_ [l=mn] {Ð¢Ð°Ð»Ð±Ð°ÑÑÑÐŽÑÐ³ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ò¯Ð·ÑÑ
+}
+_textdescrFrom_ [l=mn] {Ð¥ÑÐœÑÑÑ ÑÐ°Ð»Ð±Ð°ÑÐ°Ð°Ñ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ò¯Ð·ÑÑ
+}
+_textdescrCollage_ [l=mn] {ÐÒ¯ÑÑÑÑÑ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ò¯Ð·ÑÑ
+}
+_textdescrAcronym_ [l=mn] {Ò®Ð³ÐžÐ¹Ðœ ÑÐŸÐ²ÑÐ»ÐŸÐ»ÑÐ³ Ñ
+Ð°ÑÐ°Ñ
+}
+_textdescrPhrase_ [l=mn] {Ð¥ÑÐ»Ñ Ò¯Ð³ÑÑÑ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ò¯Ð·ÑÑ
+}
+_textdescrHowto_ [l=mn] {Ð¥ÑÑÑ
+ÑÐœ Ð°ÐœÐ³ÐžÐ»Ð»Ð°Ð°Ñ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ñ
+Ð°ÑÐ°Ñ
+}
+_textdescrBrowse_ [l=mn] {ÐÒ¯Ð¹Ð»Ð³ÑÐœ Ò¯Ð·ÑÑ
+}
+_texticontext_ [l=mn] {ÐÐ°ÑÐžÐŒÑÑÐ³ Ñ
+Ð°ÑÐ°Ñ
+}
+_texticonclosedbook_ [l=mn] {ÑÐœÑ Ð±Ð°ÑÐžÐŒÑÑÐ³ ÐœÑÑÐ¶ Ò¯Ð·ÑÑ
+}
+_texticonnext_ [l=mn] {ÐŽÐ°ÑÐ°Ð°Ð³ÐžÐ¹Ðœ Ð±Ò¯Ð»ÑÐ³ ÑÒ¯Ò¯}
+_texticonprev_ [l=mn] {Ó©ÐŒÐœÓ©Ñ
+ Ð±Ò¯Ð»ÑÐ³ ÑÒ¯Ò¯}
+
+_texticonworld_ [l=mn] {ÐÑÐ± ÑÐ°Ð¹Ð» Ò¯Ð·ÑÑ
+}  
+
+_texticonmidi_ [l=mn] {MIDI Ð±Ð°ÑÐžÐŒÑÑÐ³ Ò¯Ð·ÐœÑ Ò¯Ò¯}
+_texticonmsword_ [l=mn] {Microsoft Word ÐŽÑÑÑÑ
+ Ð±Ð°ÑÐžÐŒÑÑÐ³ Ò¯Ð·ÐœÑ Ò¯Ò¯}
+_texticonmp3_ [l=mn] {MP3 ÑÐ°Ð¹Ð» Ò¯Ð·ÑÑ
+}  
+_texticonpdf_ [l=mn] {PDF Ð±Ð°ÑÐžÐŒÑÑÐ³ Ñ
+Ð°ÑÐ°Ñ
+}  
+_texticonps_ [l=mn] {PostScript Ð±Ð°ÑÐžÐŒÑÑÐ³ Ñ
+Ð°ÑÐ°Ñ
+}  
+_texticonppt_ [l=mn] {PowerPoint Ð±Ð°ÑÐžÐŒÑÑÐ³ Ñ
+Ð°ÑÐ°Ñ
+}  
+_texticonrtf_ [l=mn] {RTF Ð±Ð°ÑÐžÐŒÑÑÐ³ Ñ
+Ð°ÑÐ°Ñ
+}  
+_texticonxls_ [l=mn] {Microsoft Excel Ð±Ð°ÑÐžÐŒÑÑÐ³ Ò¯Ð·ÑÑ
+}  
+
+_page_ [l=mn] {Ñ
+ÑÑÐŽÐ°Ñ}
+_pages_ [l=mn] {Ñ
+ÑÑÐŽÐ°Ñ}
+_of_ [l=mn] {of}  
+_vol_ [l=mn] {ÐÐŸÑÑ}
+_num_ [l=mn] {â}
+
+_textmonth00_ [l=mn] {}
+_textmonth01_ [l=mn] {ÐÑÐ³ÐŽÒ¯Ð³ÑÑÑ ÑÐ°Ñ}
+_textmonth02_ [l=mn] {Ð¥ÐŸÑÑÐŽÑÐ³Ð°Ð°Ñ ÑÐ°Ñ}
+_textmonth03_ [l=mn] {ÐÑÑÐ°Ð²ÐŽÑÐ³Ð°Ð°Ñ ÑÐ°Ñ}
+_textmonth04_ [l=mn] {ÐÓ©ÑÓ©Ð²ÐŽÒ¯Ð³ÑÑÑ ÑÐ°Ñ}
+_textmonth05_ [l=mn] {Ð¢Ð°Ð²ÐŽÑÐ³Ð°Ð°Ñ ÑÐ°Ñ}
+_textmonth06_ [l=mn] {ÐÑÑÐ³Ð°Ð°ÐŽÑÐ³Ð°Ð°Ñ ÑÐ°Ñ}
+_textmonth07_ [l=mn] {ÐÐŸÐ»ÐŽÑÐ³Ð°Ð°Ñ ÑÐ°Ñ}
+_textmonth08_ [l=mn] {ÐÐ°Ð¹ÐŒÐŽÑÐ³Ð°Ð°Ñ ÑÐ°Ñ}
+_textmonth09_ [l=mn] {ÐÑÐŽÒ¯Ð³ÑÑÑ ÑÐ°Ñ}
+_textmonth10_ [l=mn] {ÐÑÐ²Ð°ÐœÐŽÑÐ³Ð°Ð°Ñ ÑÐ°Ñ}
+_textmonth11_ [l=mn] {ÐÑÐ²Ð°ÐœÐœÑÐ³ÑÐœÐŽÒ¯Ð³ÑÑÑ ÑÐ°Ñ}
+_textmonth12_ [l=mn] {ÐÑÐ²Ð°ÐœÑ
+ÐŸÑÑÐŽÑÐ³Ð°Ð°Ñ ÑÐ°Ñ}
+
+_textdocument_ [l=mn] {ÐÐ°ÑÐžÐŒÑ}
+_textsection_ [l=mn] {Ð¥ÑÑÑÐ³}
+_textparagraph_ [l=mn] {ÐÐŸÐ³ÐŸÐ» ÐŒÓ©Ñ}
+
+_magazines_ [l=mn] {Ð¡ÑÑÐ³Ò¯Ò¯Ð»}
+
+_nzdlpagefooter_ [l=mn] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">ÐšÐžÐœÑ ÐÐµÐ»Ð°ÐœÐŽÑÐœ Ð­Ð»ÐµÐºÑÑÐŸÐœ ÐÐŸÐŒÑÐœ Ð¡Ð°Ðœ Ð¢Ó©ÑÓ©Ð»</a>
+<br><a href="http://www.cs.waikato.ac.nz">ÐÐŸÐŒÐ¿ÑÑÑÐµÑÐžÐ¹Ðœ ÐšÐžÐœÐ¶Ð»ÑÑ
+ Ð£Ñ
+Ð°Ð°ÐœÑ Ð¢ÑÐœÑ
+ÐžÐŒ</a>, 
+<a href="http://www.waikato.ac.nz">ÐÐ°Ð¹ÐºÐŸÑÐŸÐ³ÐžÐ¹Ðœ ÐÑ
+ Ð¡ÑÑÐ³ÑÑÐ»Ñ</a>, 
+ÐšÐžÐœÑ ÐÐµÐ»Ð°ÐœÐŽ}
+
+_linktextHOME_ [l=mn] {ÐÒ®Ò®Ð }
+_linktextHELP_ [l=mn] {Ð¢Ð£Ð¡ÐÐÐÐ}
+_linktextPREFERENCES_ [l=mn] {Ð¢ÐÐ¥ÐÐ ÐÐÐ}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=mn] {Greenstone-ÐžÐ¹ ÐŽÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°Ðœ}
+
+_textnocollections_ [l=mn] {ÐÑÐ»ÑÐœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð°Ð»Ð³Ð°.}  
+
+_textadmin_ [l=mn] {Ð£ÐŽÐžÑÐŽÐ»Ð°Ð³Ð° Ð·ÐŸÑ
+ÐžÐŸÐœ Ð±Ð°Ð¹Ð³ÑÑÐ»Ð°Ð»ÑÑÐœ Ñ
+ÑÑÐŽÐ°Ñ}
+_textabgs_ [l=mn] {Greenstone-ÐžÐ¹ ÑÑÑ
+Ð°Ð¹}
+_textgsdocs_ [l=mn] {Greenstone-ÐžÐ¹ Ð±ÐžÑÐžÐ³ Ñ
+ÑÑÐ³ÐžÐ¹Ðœ Ñ
+Ó©ÑÐ»Ó©Ð»Ñ}
+
+_textdescradmin_ [l=mn] {ÐšÐžÐœÑ Ñ
+ÑÑÑÐ³Ð»ÑÐ³Ñ ÐœÑÐŒÑÑ
+, ÑÐžÑÑÐµÐŒ ÐŽÑÑ
+ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ ÐœÑÐ³ÑÐ³ÑÐœ ÐŽÒ¯Ð³ÐœÑÑ
+,
+Greenstone-ÐžÐ¹Ð³ ÐžÐœÑÑÐ°Ð»Ð» Ñ
+ÐžÐ¹Ñ
+ ÑÐ°Ð»Ð°Ð°Ñ ÐŒÑÐŽÑÑÐ»ÑÐ» Ó©Ð³ÐŽÓ©Ð³.}
+
+_textdescrgogreenstone_ [l=mn] {Greenstone Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑÐœ ÑÑÑ
+Ð°Ð¹ Ð±ÐŸÐ»ÐŸÐœ ÐšÐžÐœÑ ÐÐµÐ°Ð»Ð°ÐœÐŽÑÐœ ÐÐžÐ¶ÐžÑÐ°Ð» ÐÐŸÐŒÑÐœ
+Ð¡Ð°ÐœÐ³ÐžÐ¹Ðœ Ð¢Ó©ÑÓ©Ð» Ñ
+Ð°Ð°ÐœÐ° ÑÑ
+ÑÐ»ÑÑÐœ ÑÑÑ
+Ð°Ð¹ ÑÐ°ÐœÐŽ Ó©Ð³Ò¯Ò¯Ð»ÐœÑ.}
+
+_textdescrgodocs_ [l=mn] {Greenstone-ÐžÐ¹ Ð³Ð°ÑÑÐœ Ð°Ð²Ð»Ð°Ð³ÑÑÐŽ}
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=mn] {ÐÐŸÐŒÑÐœ ÑÐ°ÐœÑÐžÐ¹Ðœ ÐžÐœÑÐµÑÑÐ°Ð¹Ñ}
+_textdescrgli_ [l=mn] {ÐšÐžÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ñ
+ÐžÐ¹Ñ
+, Ó©Ó©ÑÑÐ»Ó©Ñ
+ ÑÑÐ²ÑÐ» ÑÑÑÐŽ Ñ
+ÐžÐ¹ÑÐžÑ
+ÑÑÐœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÐŽÑÑÑ
+ÐœÑÐŒÑÑ
+ Ð±ÐŸÐ»ÐŸÐœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÑÑÑÐ³Ð°Ñ
+Ð°ÐŽ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÐŽÑÐœÑ.}
+
+package collector
+
+_textcollector_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð°Ð³Ñ}
+_textdescrcollector_ [l=mn] {Ð­ÐœÑ ÐœÑ ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÐžÐ¹Ðœ ÐžÐœÑÐµÑÑÑÐ¹ÑÐžÐ¹Ð³ Ñ
+Ð°ÑÑÑÐ»Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±Ó©Ð³Ó©Ó©ÐŽ Ñ
+Ð°ÐŒÐ³ÐžÐ¹Ðœ Ñ
+ÑÑÑÐ³ÑÑÑÑÑÐ¹ ÐœÑ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÐŽÑÑ
+ Ð±ÐŸÐ»ÐœÐŸ}
+
+package depositor
+
+_textdepositor_ [l=mn] {Depositor}  
+_textdescrdepositor_ [l=mn] {Ò®Ò¯ÑÐ³ÑÐ³ÐŽÑÑÐœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽ Ð±Ð°ÑÐžÐŒÑ ÐœÑÐŒÑÑ
+ÑÐŽ ÑÑÑÐ°Ð»ÐœÐ°}  
+
+package gti
+
+_textgti_ [l=mn] {The Greenstone Translator Interface}  
+_textdescrtranslator_ [l=mn] {Greenstone-ÐžÐ¹ ÐžÐœÑÐµÑÑÑÐ¹ÑÐžÐ¹Ðœ ÐŸÐ»ÐŸÐœ Ñ
+ÑÐ» ÐŽÑÑÑÑ
+Ðž Ñ
+ÑÐ²ÐžÐ»Ð±Ð°ÑÑÐ³ ÑÐžÐœÑÑÐžÐ»Ð¶
+Ð±Ð°Ð¹Ñ
+Ð°ÐŽ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÐŽÑÐœÑ.}
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=mn] {Ð­ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÑÑÑ
+Ð°Ð¹}
+
+_textsubcols1_ [l=mn] {<p> _1_ ÐŽÑÐŽ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð±Ò¯Ñ
+ÐžÐ¹ Ð±Ò¯ÑÑÐœ ÑÑ
+. 
+ÐÐ°ÐœÐ°Ð¹ÐŽ Ð±Ð°Ð¹Ð³Ð°Ð° ÐœÑ:
+<blockquote>}
+
+_textsubcols2_ [l=mn] {</blockquote>
+Ð¯ÐŒÐ°Ñ ÑÓ©ÑÐ»ÐžÐ¹Ðœ ÐŽÑÐŽ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð°ÑÐžÐ³Ð»Ð°Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð°Ð³Ð°Ð° 
+Ð¢ÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐœÑ Ñ
+ÑÑÐŽÐ°ÑÐœÐ°Ð° Ð·ÐŸÑÐ»ÐŸÐœ ÐŸÑÐ¶ Ñ
+Ð°ÑÐ°Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹.}
+
+_titleabout_ [l=mn] {ÑÑÑ
+Ð°Ð¹}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=mn] {ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÐžÐ¹Ðœ ÑÐœÑ Ñ
+ÑÑÐ³ÐžÐ¹Ð³ Ñ
+Ð°Ð°Ñ
+}
+_texticonclosedbookshelf_ [l=mn] {ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÐžÐ¹Ðœ ÑÐœÑ Ð±Ò¯Ð»Ð³ÐžÐ¹Ð³ ÐœÑÑÐ¶ Ð°Ð³ÑÑÐ»Ð³ÑÐ³ Ò¯Ð·ÑÑ
+}
+_texticonopenbook_ [l=mn] {ÑÐœÑ ÐœÐŸÐŒÑÐ³ Ñ
+Ð°Ð°Ñ
+}
+_texticonclosedfolder_ [l=mn] {Ð­ÐœÑ Ñ
+Ð°Ð²ÑÑÑÐ³ ÐœÑÑÐ¶ Ð°Ð³ÑÑÐ»Ð³ÑÐ³ Ñ
+Ð°ÑÐ°Ñ
+}
+_texticonclosedfolder2_ [l=mn] {ÐœÑÑÑ
+ ÐŽÑÐŽ Ñ
+ÑÑÐ³ÐžÐ¹Ðœ ÐŽÑÐ³Ð°Ð°Ñ:}
+_texticonopenfolder_ [l=mn] {ÑÐœÑ Ñ
+Ð°Ð²ÑÑÑÐ³ Ñ
+Ð°Ð°Ñ
+}
+_texticonopenfolder2_ [l=mn] {Ñ
+Ð°Ð°Ñ
+ ÐŽÑÐŽ Ñ
+ÑÑÑÐ³:}
+_texticonsmalltext_ [l=mn] {Ð¢ÐµÐºÑÑÐžÐ¹Ðœ ÑÐœÑ Ñ
+ÑÑÐ³ÐžÐ¹Ð³ Ñ
+Ð°ÑÐ°Ñ
+}
+_texticonsmalltext2_ [l=mn] {Ñ
+Ð°ÑÐ°Ñ
+ ÑÐµÐºÑÑ:}
+_texticonpointer_ [l=mn] {ÑÑÑ
+Ð°Ð¹Ðœ Ñ
+ÑÑÑÐ³}
+_texticondetach_ [l=mn] {Ð­ÐœÑ Ñ
+ÑÑÐŽÑÑÐ³ ÑÐžÐœÑ ÑÐŸÐœÑ
+ÐŸÐœÐŽ ÐœÑÑÑ
+}
+_texticonhighlight_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ ÐœÑÑ ÑÐŸÐŒÑÑÐŸÐ³ ÑÐŸÐŽÑÑÑÐ»Ð°Ñ
+}
+_texticonnohighlight_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ ÐœÑÑ ÑÐŸÐŒÑÑÐŸÐ³ ÑÐŸÐŽÑÑÑÐ»Ð°Ñ
+Ð³Ò¯Ð¹}
+_texticoncontracttoc_ [l=mn] {ÐÐ³ÑÑÐ»Ð³ÑÐœ Ñ
+Ò¯ÑÐœÑÐ³ÑÐžÐ¹Ð³ Ð·Ð°ÐŽÐ»Ð°Ñ
+}
+_texticonexpandtoc_ [l=mn] {ÐÐ³ÑÑÐ»Ð³ÑÐœ Ñ
+Ò¯ÑÐœÑÐ³ÑÐžÐ¹Ð³ Ó©ÑÐ³Ó©ÑÐ³Ó©Ñ
+}
+_texticonexpandtext_ [l=mn] {ÐÒ¯Ñ
+ ÑÐµÐºÑÑÐžÐ¹Ð³ Ñ
+Ð°ÑÑÑÐ»Ð°Ñ
+}
+_texticoncontracttext_ [l=mn] {ÐÓ©Ð²Ñ
+Ó©Ðœ ÐžÐŽÑÐ²Ñ
+ÐžÐ¶Ò¯Ò¯Ð»ÑÑÐœ Ð±Ð°Ð¹Ð³Ð°Ð° ÑÐµÐºÑÑÐžÐ¹Ð³ ÑÐŸÐœÐ³ÐŸÑ
+}
+_texticonwarning_ [l=mn] {<b>ÐÐœÑ
+Ð°Ð°Ñ: </b>}
+_texticoncont_ [l=mn] {Ò¯ÑÐ³ÑÐ»Ð¶Ð»Ò¯Ò¯Ð»ÑÑ
+ Ò¯Ò¯?}
+
+_textltwarning_ [l=mn] {<div class="buttons">_imagecont_</div>
+_iconwarning_Ð¢ÐµÐºÑÑÐžÐ¹Ð³ ÑÐœÐŽ Ð·Ð°ÐŽÐ°Ð»ÑÐœÐ°Ð°Ñ ÑÐ°ÐœÑ Ð±ÑÐ°ÑÐ·ÐµÑ ÐŽÑÑÑ Ò¯Ð·Ò¯Ò¯Ð»ÑÑ
+
+ÐžÑ
+ Ñ
+ÑÐŒÐ¶ÑÑÐœÐžÐ¹ Ó©Ð³Ó©Ð³ÐŽÐ»ÐžÐ¹Ð³ Ò¯Ò¯ÑÐ³ÑÑ
+ Ð±ÐŸÐ»ÐœÐŸ.}
+
+_textgoto_ [l=mn] {Ñ
+ÑÑÐŽÐ°Ñ ÑÑÑ ÑÐžÐ»Ð¶ÐžÑ
+}
+_textintro_ [l=mn] {<i>(ÐŸÑÑÐžÐ» ÑÐµÐºÑÑ)</i>}
+
+_textCONTINUE_ [l=mn] {Ò®Ð ÐÐ­ÐÐÐÒ®Ò®ÐÐ­Ð¥ Ò®Ò®??}
+
+_textEXPANDTEXT_ [l=mn] {Ð¢ÐÐÐ¡Ð¢ÐÐÐ ÐÐÐÐÐÐ¥}  
+
+_textCONTRACTCONTENTS_ [l=mn] {ÐÐ­Ð Ð­Ð­ÐÐÐ ÐÐÐ£Ð£ÐÐÐ}  
+
+_textDETACH_ [l=mn] {Ð¡ÐÐÐÐÐ¥}
+
+_textEXPANDCONTENTS_ [l=mn] {ÐÐÐ£Ð£ÐÐÐ«Ð ÐÐÐÐÐÐ¥}  
+
+_textCONTRACT_ [l=mn] {ÐÐ­Ð Ð­Ð­ÐÐÐ Ð¢ÐÐÐ¡Ð¢}  
+
+_textHIGHLIGHT_ [l=mn] {Ð¢ÐÐÐ Ð£Ð£ÐÐÐ¥}  
+
+_textNOHIGHLIGHT_ [l=mn] {Ð¢ÐÐÐ Ð£Ð£ÐÐÐ¥ÐÒ®Ð}  
+
+_textPRINT_ [l=mn] {Ð¥ÑÐ²Ð»ÑÑ
+}  
+
+_textnextsearchresult_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ ÐŽÐ°ÑÐ°Ð°Ð³ÐžÐ¹Ðœ Ò¯Ñ ÐŽÒ¯Ðœ}  
+_textprevsearchresult_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ Ó©ÐŒÐœÓ©Ñ
+ Ò¯Ñ ÐŽÒ¯Ðœ}  
+
+# macros for printing page
+_textreturnoriginal_ [l=mn] {Ð­Ñ
+ Ñ
+ÑÑÐŽÐ°Ñ ÑÑÑ Ð±ÑÑÐ°Ñ
+}  
+_textprintpage_ [l=mn] {Ð­ÐœÑ Ñ
+ÑÑÐŽÑÑÐ³ Ñ
+ÑÐ²Ð»ÑÑ
+}  
+_textshowcontents_ [l=mn] {ÐÐ°ÑÑÐžÐ³ÐžÐ¹Ð³ Ò¯Ð·Ò¯Ò¯Ð»ÑÑ
+}  
+_texthidecontents_ [l=mn] {ÐÐ°ÑÑÐžÐ³ÐžÐ¹Ð³ Ñ
+Ð°ÑÐ°Ð³ÐŽÐ°Ñ
+Ð³Ò¯Ð¹ Ð±ÐŸÐ»Ð³ÐŸÑ
+}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=mn] {_If_(_thislast_,results _thisfirst_ - _thislast_ for query: _cgiargq_,Ð¥Ð°Ð¹Ð»ÑÐ°ÐœÐŽ ÑÐŸÑ
+ÐžÑÐŸÑ
+ Ñ
+Ð°ÑÐžÑ ÐŸÐ»ÐŽÑÐŸÐœÐ³Ò¯Ð¹: _cgiargq_)}
+_textnoquerytitle_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ Ñ
+ÑÑÐŽÐ°Ñ}
+
+_textsome_ [l=mn] {Ð·Ð°ÑÐžÐŒ}
+_textall_ [l=mn] {Ð±Ò¯Ð³ÐŽ}
+_textboolean_ [l=mn] {boolean}
+_textranked_ [l=mn] {ÑÑÑÐŒÐ±ÑÐ»ÑÐ³ÐŽÑÑÐœ}
+_textnatural_ [l=mn] {ÑÑ
+}
+_textsortbyrank_ [l=mn] {Ð¥Ð°ÐŒÐ°Ð°ÑÐ»ÑÐœ Ð·ÑÑÑÐ³Ð»ÑÐ»}  
+_texticonsearchhistorybar_ [l=mn] {Ñ
+Ð°Ð¹Ð»ÑÑÐœ Ð°ÑÑ
+ÐžÐ²}
+
+_textifeellucky_ [l=mn] {ÐÐž Ð°Ð·ÑÐ°Ð¹ Ð±Ð°Ð¹ÐœÐ°!}
+
+#alt text for query buttons
+_textusequery_ [l=mn] {ÑÐœÑ Ñ
+Ð°Ð¹Ð»ÑÑÐ³ Ð°ÑÐžÐ³Ð»Ð°Ñ
+}
+_textfreqmsg1_ [l=mn] {Ò®Ð³ÐžÐ¹Ðœ ÑÐŸÐŸ:}
+_textpostprocess_ [l=mn] {_If_(_quotedquery_,<br><i>Ñ
+Ð°Ð¹Ñ
+Ð°Ð°Ñ Ð±ÐŸÐ»ÐŸÐ²ÑÑÑÑÐ»Ð°Ð³ÐŽÑÐ°Ðœ _quotedquery_</i>
+)}
+_textinvalidquery_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ Ð±Ò¯ÑÑÐžÐ¹Ðœ Ð°Ð»ÐŽÐ°Ð°}
+_textstopwordsmsg_ [l=mn] {ÐÐŸÐŸÑÑ
+ Ò¯Ð³ÐœÒ¯Ò¯ÐŽ Ñ
+ÑÑ ÐœÐžÐ¹ÑÐ»ÑÐ³ ÑÑÑÐ°Ð°Ñ Ð°Ð²Ñ Ò¯Ð·ÑÑÐœÐ³Ò¯Ð¹.}  
+_textlucenetoomanyclauses_ [l=mn] {Ð¢Ð°ÐœÑ Ñ
+Ò¯ÑÑÐ»Ñ Ñ
+ÑÑ ÐŸÐ»ÐŸÐœ Ñ
+Ð°Ð¹Ð»ÑÑÐœ ÐœÑÑ ÑÐŸÐŒÑÑÐŸ Ð°Ð³ÑÑÐ»ÑÐ°Ðœ Ð±Ð°Ð¹ÐœÐ°. ÐÐ»Ò¯Ò¯ ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹ Ð±ÐŸÐ»Ð³ÐŸÐœÐŸ ÑÑ.}  
+
+_textmorethan_ [l=mn] {ÐÐ»Ò¯Ò¯ ÐžÑ
+}
+_textapprox_ [l=mn] {Ð¢ÑÑ
+Ð°Ð¹}
+_textnodocs_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÐ°ÐŽ ÑÐŸÑ
+ÐžÑÐŸÑ
+ Ð±Ð°ÑÐžÐŒÑ Ð°Ð»Ð³Ð°.}
+_text1doc_ [l=mn] {1 Ð±Ð°ÑÐžÐŒÑ Ñ
+Ð°Ð¹Ð»ÑÐ°ÐŽ ÑÐŸÑ
+ÐžÑÑÐŸÐœ.}
+_textlotsdocs_ [l=mn] {Ñ
+Ð°Ð¹Ð»ÑÐ°ÐŽ ÑÐŸÑ
+ÐžÑÐŸÑ
+ Ð±Ð°ÑÐžÐŒÑ.}
+_textmatches_ [l=mn] {Ð¢ÐŸÑ
+ÐžÑÑÐŸÐœ}
+_textbeginsearch_ [l=mn] {Ð¥Ð°Ð¹Ð¶ Ð­Ñ
+Ð»ÑÑ
+}
+_textrunquery_ [l=mn] {Ð¥Ð°Ð¹Ð¶ ÑÑ
+Ð»ÑÑ
+}  
+_textclearform_ [l=mn] {ÐÐ°ÑÐ³ÑÑÐ³ ÑÑÐ²ÑÑÐ»ÑÑ
+}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=mn] {Ò®Ð³ ÑÑÐ²ÑÐ» Ñ
+ÑÐ»Ñ Ò¯Ð³}  
+_textinfield_ [l=mn] {... ÑÐ°Ð»Ð±Ð°ÑÑ}  
+_textfoldstem_ [l=mn] {(ÐœÑÐ³Ð°Ð»Ð°Ñ
+, Ò¯Ò¯ÑÑÑ
+)}  
+
+_textadvquery_ [l=mn] {Ð­ÑÐ²ÑÐ» Ñ
+Ð°Ð¹Ð»ÑÐ°Ð° ÑÑÑÐŽ ÐŸÑÑÑÐ»ÐœÐ° ÑÑ:}  
+_textallfields_ [l=mn] {Ð±Ò¯Ñ
+ ÑÐ°Ð»Ð±Ð°Ñ}  
+_texttextonly_ [l=mn] {Ð·Ó©Ð²Ñ
+Ó©Ðœ ÑÐµÐºÑÑ}
+_textand_ [l=mn] {Ð±Ð°}  
+_textor_ [l=mn] {ÑÑÐ²ÑÐ»}  
+_textandnot_ [l=mn] {Ð±Ð° Ò¯Ð³Ò¯Ð¹}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=mn] {Ò®Ð³ÐžÐ¹Ðœ _querytypeselection_ Ð°Ð³ÑÑÐ»ÑÐ°Ðœ _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_, at _gselection_ level )_If_(_nselection_,in _nselection_ language )Ð³ Ñ
+Ð°Ð¹Ñ
+}  
+
+_textadvancedsearch_ [l=mn] {_querytypeselection_ Ð°ÑÐžÐ³Ð»Ð°Ðœ _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language ) Ñ
+Ð°Ð¹Ñ
+}
+
+_textadvancedmgppsearch_ [l=mn] {_indexselection_ Ñ
+Ð°Ð¹Ñ
+ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language )  _formquerytypeadvancedselection_ ÐŽÐ°ÑÐ°Ð°Ð»Ð»Ð°Ð°Ñ Ò¯Ñ ÐŽÒ¯ÐœÐ³ Ñ
+Ð°ÑÑÑÐ»Ð°Ñ
+}  
+
+_textadvancedlucenesearch_ [l=mn] {Ð¥Ð°Ð¹Ð»Ñ _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language )}  
+
+_textformsimplesearch_ [l=mn] {Ð¥ÑÑÑÐ² _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )Ð±ÐŸÐ» _formquerytypesimpleselection_ Ñ
+Ð°Ð¹Ñ
+}  
+
+_textformadvancedsearchmgpp_ [l=mn] { _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )-ÐŽ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ð³ÑÑÐŽ, Ò¯Ñ ÐŽÒ¯ÐœÐ³ ÐœÑ _formquerytypeadvancedselection_ order-Ñ Ñ
+Ð°ÑÑÑÐ»ÐœÐ°.}  
+
+
+
+_textnojsformwarning_ [l=mn] {ÐÐ»ÐŽÐ°Ð°: Javascript ÑÐ°ÐœÑ Ð²ÑÐ± Ð±ÑÐ°ÑÐ·ÑÑÐŽ ÐžÐŽÑÐ²Ñ
+ÐžÐ³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°. <br> Ð¥Ð°Ð¹Ð»ÑÑÐœ ÑÓ©ÑÐ»ÐžÐ¹Ð³ Ð°ÑÐžÐ³Ð»Ð°Ñ
+ Ð±ÐŸÐ» ÐžÐŽÑÐ²Ñ
+ÐžÐ¶Ò¯Ò¯Ð»ÐœÑ Ò¯Ò¯.}
+_textdatesearch_ [l=mn] {Ð­ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹ Ñ
+ÑÐ³Ð°ÑÐ°Ð°ÐœÑ Ð·Ð°Ð²ÑÐ°Ñ ÐŽÐ°Ñ
+Ñ Ð±Ð°ÑÐžÐŒÑÑÐ³ ÑÐŒ ÑÑ ÑÑÐ²ÑÐ» ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹ ÐŸÐ³ÐœÐŸÐŸ Ð±Ò¯Ñ
+ÐžÐ¹ Ð±Ð°ÑÐžÐŒÑÑÑÐŽÑÐœ ÐŽÑÐœÐŽ Ñ
+Ð°Ð¹Ð³ÐŽÐ°Ð¶ Ð±ÐŸÐ»ÐœÐŸ. Ð­ÐœÑ Ð±ÐŸÐ» Ñ
+Ð°Ð¹Ð»ÑÑÐœ ÐœÑÐŒÑÐ³ÐŽÑÐ» ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ ÑÐŒ.}
+_textstartdate_ [l=mn] {Ð­Ñ
+Ð»ÑÑ
+ (ÑÑÐ²ÑÐ» Ð³Ð°ÐœÑ) ÐŸÐ³ÐœÐŸÐŸ:}
+_textenddate_ [l=mn] {ÐÑÑÑÐ°Ñ
+ ÐŸÐ³ÐœÐŸÐŸ:}
+_textbc_ [l=mn] {Ð.Ð.Ð¢.Óš}
+_textad_ [l=mn] {Ð.Ð.Ð¢}
+_textexplaineras_ [l=mn] {Ð.Ð.Ð¢ Ð±ÐŸÐ»ÐŸÐœ Ð.Ð.Ð¢.Óš Ð·ÑÑÐ³ÑÑÑ Ð.Ð­. Ð±ÐŸÐ»ÐŸÐœ Ð.Ð­.Óš Ñ
+ÐŸÑÑÑÐ³ ÑÑÐŒÐŽÑÐ³Ð»ÑÐŽÑÐ³. Ð­ÐŽÐ³ÑÑÑÑÑÑ ÑÐŸÑÐ»ÑÐœ ÑÐŸÐŸÐ»Ð»ÑÐ³ ÑÑÐŒÐŽÑÐ³Ð»ÑÑ
+ÑÐŽ Ñ
+ÑÑÑÐ³Ð»ÑÐŽÑÐ³ Ð±Ð° Ð·Ð°ÐŽÐ»Ð°Ð²Ð°Ð» "ÐÐžÐ¹ÑÐžÐ¹Ðœ ÐÐœ Ð¢ÐŸÐŸÐ»ÐŸÐ»" Ð±Ð° "ÐÐžÐ¹ÑÐžÐ¹Ðœ ÐÐœ Ð¢ÐŸÐŸÐ»Ð»ÐŸÐŸÑ ÓšÐŒÐœÓ©"}  
+
+_textstemon_ [l=mn] {(Ò®Ð³ÐžÐ¹Ðœ ÑÓ©Ð³ÑÐ³Ó©Ð»ÐžÐ¹Ð³ ÑÐŸÐŸÑÐŸÑ
+Ð³Ò¯Ð¹)}
+
+_textsearchhistory_ [l=mn] {ÐÑÑ
+ÐžÐ²ÑÐ³ Ð¥Ð°Ð¹Ñ
+}
+
+#text macros for search history
+_textnohistory_ [l=mn] {ÐÑÑ
+ÐžÐ²Ñ Ñ
+Ð°Ð¹Ð»Ñ Ð°Ð»Ð³Ð°}
+_texthresult_ [l=mn] {Ò¯Ñ ÐŽÒ¯Ðœ}
+_texthresults_ [l=mn] {Ò¯Ñ ÐŽÒ¯ÐœÐ³Ò¯Ò¯ÐŽ}
+_texthallwords_ [l=mn] {Ð±Ò¯Ñ
+ Ò¯Ð³}
+_texthsomewords_ [l=mn] {Ð·Ð°ÑÐžÐŒ Ò¯Ð³}
+_texthboolean_ [l=mn] {boolean}
+_texthranked_ [l=mn] {ÑÑÑÐŒÐ±ÑÐ»ÑÑÐœ}
+_texthcaseon_ [l=mn] {Ò¯ÑÐ³ÐžÐ¹Ðœ ÑÐŸÐŒ/Ð¶ÐžÐ¶ÐžÐ³ ÑÐŸÑ
+ÐžÑÐŸÑ
+ ÑÑÑÐŸÐ¹.}
+_texthcaseoff_ [l=mn] {Ò¯ÑÐ³ÐžÐ¹Ðœ ÑÐŸÐŒ/Ð¶ÐžÐ¶ÐžÐ³ ÑÐŸÑ
+ÐžÑÑÑÐ»Ð°Ñ
+Ð³Ò¯Ð¹}
+_texthstemon_ [l=mn] {ÐžÑÐ»ÑÑÑÐœ}
+_texthstemoff_ [l=mn] {ÐžÑÐ»ÑÑÐ³Ò¯Ð¹}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=mn] {Ð¢ÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐ³ ÐŽÐ°ÑÐ°Ð°Ñ
+ Ð±Ð°Ð¹ÐŽÐ»Ð°Ð°Ñ Ñ
+ÐžÐ¹ÑÑÐœ. ÐÑÐ°ÑÐ·ÐµÑÑÐœÑ
+Ð°Ð° "Ð±ÑÑÐ°Ñ
+"
+ÑÐŸÐ²ÑÐžÐ¹Ð³ Ð±Ò¯Ò¯ ÐŽÐ°Ñ - ÑÑÐ³Ð²ÑÐ» ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ ÐœÑ Ð°Ð»ÐŽÐ°Ð³ÐŽÐ°Ñ
+ ÑÑÐ» ÐŽÑÑÑ Ð±Ð°Ð¹Ð³Ð°Ð°
+ÐœÑÐ²ÑÑÑÑ
+ ÑÐ°Ð»Ð±Ð°ÑÑÐœ Ð°Ð»Ñ ÐœÑÐ³ ÑÐŸÐ²Ñ ÐŽÑÑÑ ÐŽÐ°ÑÐœÐ° ÑÑ.}
+_textsetprefs_ [l=mn] {ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ ÐŸÑÑÑÐ»Ð°Ñ
+}
+_textsearchprefs_ [l=mn] {Ð¢ÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐ³ Ñ
+Ð°Ð¹Ñ
+}
+_textcollectionprefs_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ}
+_textpresentationprefs_ [l=mn] {Ð¢Ð°ÐœÐžÐ»ÑÑÑÐ»Ð³ÑÐœ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ}
+_textpreferences_ [l=mn] {Ð¢ÐŸÑ
+ÐžÑÐ³ÐŸÐŸ}
+_textcasediffs_ [l=mn] {Ò®ÑÐ³ÐžÐ¹Ðœ ÑÐŸÐŒ, Ð¶ÐžÐ¶Ð³ÐžÐ¹Ðœ ÑÐ»Ð³Ð°Ð°:}
+_textignorecase_ [l=mn] {Ò¯ÑÐ³ÐžÐ¹Ðœ ÑÐŸÐŒ, Ð¶ÐžÐ¶Ð³ÐžÐ¹Ð³ Ò¯Ð» Ñ
+ÑÑÑÐ³ÑÑÑ
+}
+_textmatchcase_ [l=mn] {Ò¯ÑÐ³ÐžÐ¹Ðœ ÑÐŸÐŒ/Ð¶ÐžÐ¶ÐžÐ³ ÑÐ°Ð°ÑÑ Ð±Ð°Ð¹Ñ
+ ÑÑÑÐŸÐ¹}
+_textwordends_ [l=mn] {Ò®Ð³ÐžÐ¹Ðœ ÑÓ©Ð³ÑÐ³Ó©Ð»Ò¯Ò¯ÐŽ:}  
+_textstem_ [l=mn] {Ò¯Ð³ÐžÐ¹Ðœ ÑÓ©Ð³Ó©ÑÐ³Ó©Ð»ÐžÐ¹Ð³ ÑÐŸÐŸÑÐŸÑ
+Ð³Ò¯Ð¹}
+_textnostem_ [l=mn] {Ð±Ò¯ÑÑÐœ Ò¯Ð³ ÑÐŸÑ
+ÐžÑÐŸÑ
+ ÑÑÑÐŸÐ¹}
+_textaccentdiffs_ [l=mn] {ÓšÑÐ³Ó©Ð»ÑÐžÐ¹Ðœ ÑÑÐŒÐŽÑÐ³ÑÐžÐ¹Ðœ ÑÐ»Ð³Ð°Ð°}  
+_textignoreaccents_ [l=mn] {ÓšÑÐ³Ó©Ð»ÑÐžÐ¹Ðœ ÑÑÐŒÐŽÑÐ³ÑÐžÐ¹Ð³ Ò¯Ð» ÑÐŸÐŸÑÐŸÑ
+}  
+_textmatchaccents_ [l=mn] {ÓšÑÐ³Ó©Ð»ÑÐžÐ¹Ðœ ÑÑÐŒÐŽÑÐ³ÑÒ¯Ò¯ÐŽ ÑÐŸÑ
+ÐžÑÐŸÑ
+ ÑÑÑÐŸÐ¹}  
+
+_textprefop_ [l=mn] {ÐÑÑÐ°Ð°ÐŽ _maxdocoption_ ÑÑÑ ÐŸÑÐžÑ
+, ÐœÑÐ³ Ñ
+ÑÑÐŽÐ°Ñ _hitsperpageoption_ ÑÐŽÐ°Ð° ÐœÑÑÐ³ÐŽÑÑÐœ.}
+_textextlink_ [l=mn] {ÐÐ°ÐŽÐ°Ð°ÐŽ ÐÑÐ± Ñ
+ÑÑÐŽÐ°ÑÐœÐ°Ð° ÐŸÑÐŸÑ
+}
+_textintlink_ [l=mn] {Ð­Ñ
+ Ð±Ð°ÑÐžÐŒÑÑÐ³ Ð°Ð²ÑÐ°Ðœ:}
+_textlanguage_ [l=mn] {Interface Ñ
+ÑÐ»:}
+_textencoding_ [l=mn] {ÐÐŸÐŽÐ»ÐŸÐ»:}
+_textformat_ [l=mn] {ÐžÐœÑÐµÑÑÑÐ¹ÑÐžÐ¹Ðœ ÑÐŸÑÐŒÐ°Ñ}
+_textall_ [l=mn] {Ð±Ò¯Ð³ÐŽ}
+_textquerymode_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ:}  
+_textsimplemode_ [l=mn] {ÑÐœÐ³ÐžÐ¹Ðœ Ñ
+Ð°Ð¹Ð»Ñ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ}
+_textadvancedmode_ [l=mn] {ÐœÐ°ÑÐžÐ¹Ð²ÑÐžÐ»ÑÐ°Ðœ Ñ
+Ð°Ð¹Ð»ÑÑÐœ Ð³ÐŸÑÐžÐŒ ( !, &, |, Ð±ÐŸÐ»ÐŸÐœ Ñ
+Ð°Ð°Ð»Ñ Ð·ÑÑÑÐ³ ÑÑÐŒÐŽÐ³Ò¯Ò¯ÐŽÐžÐ¹Ð³ Ð°ÑÐžÐ³Ð»Ð°Ðœ Boolean Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹)}
+_textlinkinterm_ [l=mn] {ÐŽÑÐœÐŽÐ°Ð¶ Ñ
+ÑÑÐŽÑÑÐ³ ÐŽÐ°Ð¹ÑÑÑÐ»Ð°Ðœ}
+_textlinkdirect_ [l=mn] {ÑÑÑÐŽ ÐŸÑÐžÑ
+}
+_textdigitlib_ [l=mn] {ÐŽÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°Ðœ}
+_textweb_ [l=mn] {Ð²ÑÐ±}
+_textgraphical_ [l=mn] {ÐÑÐ°ÑÐžÐºÐ°Ðœ}
+_texttextual_ [l=mn] {Ð¢ÐµÐºÑÑÑÐœ}
+_textcollectionoption_ [l=mn] {<p>
+ÐÑÑÑÐ»Ð°Ñ
+ ÐŽÑÐŽ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÑÐŽ:
+<br>}
+
+_textsearchtype_ [l=mn] {Ð¥Ò¯ÑÑÐ»ÑÐžÐ¹Ðœ Ñ
+ÑÐ»Ð±ÑÑ:}  
+_textformsearchtype_ [l=mn] {_formnumfieldoption_ ÑÐ°Ð»Ð±Ð°ÑÑÑÐŽÐ°ÐŽ ÑÐ°Ð»Ð±Ð°ÑÑ Ñ
+ÑÐ²Ð°Ð°Ð³ÐŽÑÐ°Ðœ}  
+_textplainsearchtype_ [l=mn] {_boxsizeoption_  Ñ
+Ò¯ÑÑÐ»ÑÐžÐ¹Ðœ ÑÐ°Ð»Ð±Ð°ÑÑ Ñ
+ÑÐ²ÐžÐ¹Ðœ Ð±Ð°Ð¹ÐœÐ°}  
+_textregularbox_ [l=mn] {ÐŽÐ°Ðœ ÐŒÓ©Ñ}  
+_textlargebox_ [l=mn] {ÑÐŸÐŒ}  
+
+_textrelateddocdisplay_ [l=mn] {Ñ
+ÐŸÐ»Ð±ÐŸÐ³ÐŽÐŸÑ
+ Ð±Ð°ÑÐžÐŒÑÑÐ³ Ñ
+Ð°ÑÑÑÐ»Ð°Ñ
+}
+_textsearchhistory_ [l=mn] {ÐÑÑ
+ÐžÐ²ÑÐ³ Ñ
+Ð°Ð¹Ñ
+:}  
+_textnohistory_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ Ð°ÑÑ
+ÐžÐ² Ð°Ð»Ð³Ð°}  
+_texthistorydisplay_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ Ð°ÑÑ
+ÐžÐ²ÑÐœ Ò¯Ñ ÐŽÒ¯ÐœÐ³ _historynumrecords_ Ñ
+Ð°ÑÑÑÐ»Ð°Ñ
+}
+_textnohistorydisplay_ [l=mn] {Ñ
+Ð°Ð¹Ð»ÑÑÐœ Ð°ÑÑ
+ÐžÐ²ÑÐ³ Ð±Ò¯Ò¯ Ñ
+Ð°ÑÑÑÐ»}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=mn] {ÐÐ°ÑÐžÐŒÑÑÑÐŽÑÐ³ ÑÑÑÐŒÐ±ÑÐ»ÑÑ
+}
+_textalsoshowing_ [l=mn] {Ð±Ð°Ñ}
+_textwith_ [l=mn] {Ñ
+Ð°ÐŒÐ³ÐžÐ¹Ðœ ÐžÑ
+ Ó©ÑÐ³Ó©Ðœ}
+_textdocsperpage_ [l=mn] {ÐœÑÐ³ Ñ
+ÑÑÐŽÐ°Ñ ÐŽÐ°Ñ
+Ðž Ð±Ð°ÑÐžÐŒÑÑÑÐŽ}
+
+_textfilterby_ [l=mn] {ÐÐ°ÑÐ°Ð°Ñ
+ÑÐ³ Ð°Ð³ÑÑÐ»ÑÐ°Ðœ Ð±Ð°ÑÐžÐŒÑÑÑÐŽÑÐ³ ÐŸÐ»ÐŸÑ
+:}
+_textall_ [l=mn] {Ð±Ò¯Ð³ÐŽ}
+_textany_ [l=mn] {ÑÐŒÐ°Ñ ÐœÑÐ³ÑÐœ}
+_textwords_ [l=mn] {Ò¯Ð³ÐœÒ¯Ò¯ÐŽÐžÐ¹Ðœ}
+_textleaveblank_ [l=mn] {ÑÐœÑ ÐœÒ¯ÐŽÐžÐ¹Ð³ Ñ
+ÐŸÐŸÑÐŸÐœ ÐŸÑÑ
+ÐžÐ²ÐŸÐ» Ð±Ò¯Ñ
+ Ð±Ð°ÑÐžÐŒÑÑÐ³ Ð³Ð°ÑÐ³Ð°Ð¶ ÐžÑÐœÑ}  
+
+_browsebuttontext_ [l=mn] {"ÐÐ°ÑÐžÐŒÑÑÐ³ ÐÐœÐ³ÐžÐ»Ð°Ñ
+"}
+
+_nodata_ [l=mn] {<i>Ó©Ð³Ó©Ð³ÐŽÓ©Ð» Ð°Ð»Ð³Ð°</i>}
+_docs_ [l=mn] {Ð±Ð°ÑÐžÐŒÑÑÑÐŽ}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=mn] {Ð¢ÑÑÐ»Ð°ÐŒÐ¶}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=mn] {_2_  ÐŽÐ°ÑÐ¶, Ð±Ð°ÑÐžÐŒÑÑÑÐŽÑÐ³  _1_-ÑÑÑ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ñ
+Ð°ÑÐ°Ñ
+}  
+
+_textSearchhelp_ [l=mn] {_labelSearch_  ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐ°Ðœ ÑÐµÐºÑÑÑÐœ ÐŽÐŸÑÐŸÑÑ
+Ðž ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹ Ò¯Ð³ÑÑÑ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ð¶ Ð±ÐŸÐ»ÐœÐŸ.}  
+_textTohelp_ [l=mn] {_labelTo_ ÑÐŸÐ²Ñ ÐŽÐ°ÑÐ°Ðœ Ð¥Ò¯ÑÑÑÐ» ÑÐ°Ð»Ð±Ð°ÑÐ°Ð°Ñ Ð±Ð°ÑÐžÐŒÑÑÐ³ Ð³Ò¯Ð¹Ð»Ð³ÑÑ
+}  
+_textFromhelp_ [l=mn] {_labelFrom_ ÑÐŸÐ²Ñ ÐŽÐ°ÑÐ°Ðœ Ð±Ð°ÑÐžÐŒÑÑÑÐŽÑÐ³ From ÑÐ°Ð»Ð±Ð°ÑÐ°Ð°Ñ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ñ
+Ð°ÑÐ°Ñ
+}  
+_textBrowsehelp_ [l=mn] {Ð±Ð°ÑÐžÐŒÑÑÑÐŽÑÐ³ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ñ
+Ð°ÑÐ°Ñ
+}  
+_textAcronymhelp_ [l=mn] {_labelAcronym_ ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐ°Ðœ Ð±Ð°ÑÐžÐŒÑÑÑÐŽÑÐ³ ÑÐŸÐ²ÑÐžÐ»ÑÐ°Ðœ Ñ
+ÑÐ»Ð±ÑÑÑ ÐœÑ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ñ
+Ð°ÑÐ°Ñ
+}  
+_textPhrasehelp_ [l=mn] {_labelPhrase_ ÑÐŸÐ²Ñ ÐŽÐ°ÑÐ°Ðœ Ð±Ð°ÑÐžÐŒÑÐ°Ðœ ÐŽÐŸÑÐŸÑÑ
+ Ñ
+ÑÐ»Ð»ÑÐ³ÐžÐ¹Ð³ Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ñ
+Ð°ÑÐ°Ñ
+. Ð­ÐœÑ ÐœÑ phind phrase Ñ
+Ó©ÑÑÐžÐ¹Ð³ Ñ
+ÑÑÑÐ³Ð»ÑÐŽÑÐ³.}  
+
+_texthelptopicstitle_ [l=mn] {Ð¡ÑÐŽÐ²Ò¯Ò¯ÐŽ}
+
+_textreadingdocs_ [l=mn] {ÐÐ°ÑÐžÐŒÑÑÐ³ Ñ
+ÑÑÑ
+ÑÐœ ÑÐœÑÐžÑ
+ Ð²Ñ}
+
+_texthelpreadingdocs_ [l=mn] {<p>Ð¢Ð° ÑÑÑÐ³Ð°Ð°Ñ ÐœÐŸÐŒ ÑÐŒ ÑÑ Ð±Ð°ÑÐžÐŒÑ ÐŽÑÑÑ ÐžÑÑÑÐœ ÑÑÑÑ
+ÑÑ Ñ
+ÑÑÐŽÐ°ÑÐœÑ Ð·Ò¯Ò¯Ðœ 
+ÐŽÑÑÐŽ Ó©ÐœÑÓ©Ð³Ñ Ð³Ð°ÑÑ ÐžÑÑÑ
+ Ð³Ð°ÑÑÐžÐ³ÐœÐ°Ð°Ñ ÑÑÐ²ÑÐ» ÐœÒ¯Ò¯ÑÐœÐžÐ¹ Ð·ÑÑÐ³ÐžÐ¹Ð³ Ñ
+Ð°ÑÐ¶
+ÐŒÑÐŽÑÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹. ÐÐ°ÑÐžÐŒ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽ ÑÐŽÐ³ÑÑÑ ÐœÑ Ð°Ð³ÑÑÐ»Ð³ÑÐœ Ñ
+Ò¯ÑÐœÑÐ³ÑÑÑÐ¹
+Ð±Ð°Ð¹ÐŽÐ°Ð³ Ð±ÐŸÐ» Ð·Ð°ÑÐžÐŒ ÐœÑ Ð·Ò¯Ð³ÑÑÑ Ð» ÑÑÑ
+Ð°Ð¹Ðœ Ñ
+ÑÑÐŽÐ°ÑÐœÑ ÐŽÑÐ³Ð°Ð°ÑÑÐ³ Ñ
+Ð°ÑÑÑÐ»Ð°Ð°ÐŽ,
+Ó©ÐŒÐœÓ©Ñ
+ Ð±ÐŸÐ»ÐŸÐœ ÐŽÐ°ÑÐ°Ð°Ð³ÐžÐ¹Ðœ Ñ
+ÑÑÐŽÑÑÑÐŽ ÑÑÑ ÑÐžÐ³Ð»Ò¯Ò¯Ð»ÑÑ
+ ÑÐŸÐ²ÑÐœÑÑÐŽÑÐ°Ð¹ Ð±Ð°Ð¹ÐŽÐ°Ð³. 
+ÐÐ³ÑÑÐ»Ð³ÑÐœ Ñ
+Ò¯ÑÐœÑÐ³Ñ ÐŽÐŸÑÐŸÑ ÑÑÑ
+Ð°Ð¹Ðœ Ñ
+ÑÑÑÐ³ ÐœÑ ÑÐŸÐŽÐŸÑÑ Ñ
+Ð°ÑÐ°Ð³ÐŽÐ°Ñ
+ Ð±Ð° Ñ
+Ò¯ÑÐœÑÐ³Ñ
+ÐŽÐŸÑÐŸÑÑ
+ ÑÐŸÐ»ÐŽÐµÑÑÑÐŽ ÐŽÑÑÑ ÐŽÐ°ÑÐ¶ ÐœÑÑÐ³ÑÑÐŽ, ÐœÐŸÐŒÐœÑ ÐŽÑÑÐŽ Ñ
+ÑÑÑÐ³Ñ ÐŽÐ°ÑÐ¶ Ñ
+Ð°Ð°ÐœÐ°. </p>
+
+<p>ÐÐŸÐŸÑ ÑÐ°ÐœÑ ÐŸÐŽÐŸÐŸ Ñ
+Ð°ÑÐ¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ñ
+ÑÑÐ³ÐžÐ¹Ðœ(ÑÑÐŽÑÐ²) ÑÐµÐºÑÑ Ð±Ð°Ð¹Ð³Ð°Ð°. Ð¢Ò¯Ò¯ÐœÐžÐ¹Ð³ ÑÐœÑÐžÐ¶
+ÐŽÑÑÑÑÐ°ÐœÑ ÑÑÑÑÑ Ñ
+ÑÑÐŽÑÑÐœ ÐŽÐŸÐŸÐŽ Ñ
+ÑÑÑÐ³Ñ ÑÐ°ÐœÑÐ³ ÐŽÐ°ÑÐ°Ð°Ð³ÐžÐ¹Ðœ ÑÑÐ²ÑÐ» Ó©ÐŒÐœÓ©Ñ
+ Ñ
+ÑÑÑÐ³
+ÑÒ¯Ò¯ Ð°Ð²Ð°Ð°ÑÐžÑ
+ ÑÐŸÐ²ÑÐ»ÑÑÑ Ð±ÐžÐ¹.</p>
+
+<p>ÐÐŸÐŸÑÑ
+ Ð±ÐŸÐ» Ð·Ð°ÑÐžÐŒ Ð³Ð°ÑÑÐžÐ³ Ð±ÐŸÐ»ÐŸÐœ ÐœÒ¯Ò¯ÑÐœÐžÐ¹ Ð·ÑÑÐ³ÐžÐ¹Ðœ ÑÐŸÐ²ÑÐ»ÑÑÑÑÑÐŽ ÑÐŒ. Ð¢Ð°
+<i>_document:textEXPANDTEXT_</i> ÐŽÑÑÑ ÐŽÐ°ÑÐ¶ ÑÑÑ
+Ð°Ð¹Ðœ Ñ
+ÑÑÐ³ÐžÐ¹Ðœ Ð±Ò¯ÑÑÐœ ÑÐµÐºÑÑÐžÐ¹Ð³ Ñ
+Ð°ÑÐœÐ° ÑÑ.
+Ð¥ÑÑÑÐ² Ð±Ð°ÑÐžÐŒÑ Ñ
+ÑÑ ÑÐŸÐŒ Ð±Ð°Ð¹Ð²Ð°Ð» ÑÐŽÐ°Ñ
+ Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÐ°ÐœÐ°Ñ
+ ÐŸÐ¹Ð³ ÐžÑ
+ÑÑÑ ÑÐ·ÑÐ»ÐœÑ! 
+Ð¢Ð° <i>_document:textEXPANDCONTENTS_</i> ÐŽÑÑÑ ÐŽÐ°ÑÐ¶ Ð±Ò¯Ð»Ð³Ò¯Ò¯ÐŽ, ÐŽÑÐŽ Ñ
+ÑÑÐ³Ò¯Ò¯ÐŽÐžÐ¹Ðœ Ð°Ð³ÑÑÐ»Ð³ÑÐœ
+Ñ
+Ò¯ÑÐœÑÐ³ÑÐžÐ¹Ð³ Ð±Ò¯Ñ
+ÑÐ»ÐŽ ÐœÑ Ñ
+Ð°ÑÐ¶ Ð±ÐŸÐ»ÐœÐŸ. Ð¢Ð° <i>_document:textDETACH_</i> ÐŽÑÑÑ ÐŽÐ°ÑÐ¶ Ð±Ð°ÑÐžÐŒÑÑÐœ
+ÑÐžÐœÑ Ð±ÑÐ°ÑÐ·ÐµÑÑÐ³ ÐœÑÑÐœÑ Ò¯Ò¯. (ÐÐ°ÑÐžÐŒÑÑÐ³ Ñ
+Ð°ÑÑÑÑÑÐ»Ð°Ñ
+ ÑÐŒ ÑÑ Ñ
+ÐŸÑÑÑÐ³ ÐœÑÐ³ Ð·ÑÑÑÐ³
+ÑÐœÑÐžÑ
+ÑÐ³ Ñ
+Ò¯ÑÑÑÐœ Ð±ÐŸÐ» ÑÐœÑ ÐžÑ
+ Ñ
+ÑÑÑÐ³ Ð±ÐŸÐ»ÐœÐŸ.) Ð­ÑÑÑÑ ÐœÑ Ñ
+ÑÐ»ÑÑ
+ÑÐŽ ÑÐ° ÑÐŒÐ°Ñ ÐœÑÐ³ÑÐœ
+Ò¯Ð³ Ñ
+Ð°Ð¹Ð¶ Ð±Ð°Ð¹ÑÐ°Ðœ Ð±ÐŸÐ» ÑÑÐŽÐ³ÑÑÑ Ò¯Ð³Ñ ÑÐžÐœÑ ÑÐŸÐŽÐŸÑÑÐŸÐœ Ð±Ð°Ð¹ÐŽÐ»Ð°Ð°Ñ Ñ
+Ð°ÑÐ°Ð³ÐŽÐ°ÐœÐ°. Ð¢Ð° 
+<i>_document:textNOHIGHLIGHT_</i> Ð³ÑÐ¶ ÑÐŸÐŽÑÑÑÐ»ÑÐ°ÐœÑÐ³ ÐœÑ Ð°ÑÐžÐ»Ð³Ð°ÐœÐ° ÑÑ.</p>}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=mn] {ÐÐŸÐŒÑÐœ ÑÒ¯Ò¯Ð³ÑÑÐ³ ÐœÑÑÑ
+}
+_texthelpopenbook_ [l=mn] {Ð­ÐœÑ ÐœÐŸÐŒÑÐ³ ÐÑÑÑ
+/Ñ
+Ð°Ð°Ñ
+}  
+_texthelpviewtextsection_ [l=mn] {Ð¢ÐµÐºÑÑÐžÐ¹Ðœ ÑÐœÑ Ñ
+ÑÑÐ³ÐžÐ¹Ð³ Ñ
+Ð°ÑÐ°Ñ
+}
+_texthelpexpandtext_ [l=mn] {ÐÒ¯Ñ
+ ÑÐµÐºÑÑÐžÐ¹Ð³ Ñ
+Ð°ÑÑÑÐ»Ð°Ñ
+ ÑÑÐ²ÑÐ» Ò¯Ð³Ò¯Ð¹}
+_texthelpexpandcontents_ [l=mn] {ÐÐ³ÑÑÐ»Ð³ÑÐœ Ñ
+Ò¯ÑÐœÑÐ³ÑÐžÐ¹Ð³ Ð·Ð°ÐŽÐ»Ð°Ñ
+ ÑÑÐ²ÑÐ» Ò¯Ð³Ò¯Ð¹}
+_texthelpdetachpage_ [l=mn] {Ð¥ÑÑÐŽÑÑÐ³ ÑÐžÐœÑ ÑÐŸÐœÑ
+ÐœÐŸÐŸ ÐœÑÑÑ
+}
+_texthelphighlight_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐ³ ÑÐŸÐŽÑÑÑÐ»Ð°Ñ
+ ÑÑÐ²ÑÐ» Ò¯Ð³Ò¯Ð¹}
+_texthelpsectionarrows_ [l=mn] {Ó©ÐŒÐœÓ©Ñ
+/ÐŽÐ°ÑÐ°Ð°Ð³ÐžÐ¹Ðœ Ñ
+ÑÑÑÐ³ ÑÒ¯Ò¯ ÐŸÑÐžÑ
+}  
+
+
+_texthelpsearchingtitle_ [l=mn] {Ð¢ÐŸÐŽÐŸÑÑ
+ÐŸÐ¹ Ò¯Ð³ÐœÒ¯Ò¯ÐŽÐžÐ¹Ð³ Ñ
+ÑÑÑ
+ÑÐœ Ñ
+Ð°Ð¹Ñ
+ Ð²Ñ}
+
+_texthelpsearching_ [l=mn] {<p>
+  Ð¥Ð°Ð¹Ð»ÑÑÐœ Ñ
+ÑÑÐŽÐ°ÑÐœÐ°Ð°Ñ ÑÐ° ÐŽÐ°ÑÐ°Ð°Ñ
+ Ñ
+ÑÐŽÑÐœ ÑÐœÐ³ÐžÐ¹Ðœ Ð°Ð»Ñ
+Ð°ÐŒÑÑÐŽÑÐ³ Ñ
+ÐžÐ¹Ð¶ Ð±ÐŸÐ»ÐœÐŸ:<p>
+  
+  <ol><li>Ð¯ÐŒÐ°Ñ ÐœÑÑ ÑÐŸÐŒÑÑÐŸ Ñ
+Ð°Ð¹Ñ
+Ð°Ð° ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹Ð»Ð¶ Ó©Ð³ÐœÓ©
+      <li>Ò®Ð³ÐœÒ¯Ò¯ÐŽÑÑÑ Ð±Ò¯Ð³ÐŽÑÑÑÑÐœÐ³ÑÑÑ ÐœÑ Ñ
+Ð°Ð¹Ñ
+, Ð·Ð°ÑÐžÐŒÐ°Ð°Ñ ÐœÑ Ñ
+Ð°Ð¹Ñ
+ ÑÑÑÑ
+ÑÑ Ñ
+ÑÐ»ÐœÑ
+      <li>Ð¥Ð°Ð¹Ñ
+ÑÐ³ Ñ
+Ò¯ÑÑÑÐœ Ò¯Ð³ÑÑ Ð±ÐžÑÐžÐ¶ ÐŸÑÑÑÐ»ÐœÐ°
+      <li>Ð¢ÑÐ³ÑÑÐŽ <i>Ð¥Ð°Ð¹Ð»ÑÑÐ³ ÑÑ
+Ð»ÑÑ
+</i> ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐœÐ°
+  </ol>
+
+<p>Ð¥Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ÑÐŽ ÑÐžÐœÑ ÑÐŸÑ
+ÐžÑÑÐŸÐœ 20 ÑÐžÑÑ
+ÑÐ³ Ò¯Ñ ÐŽÒ¯ÐœÐ³ÐžÐ¹Ðœ Ð³Ð°ÑÑÐžÐ³ Ñ
+Ð°ÑÐ°Ð³ÐŽÐ°ÐœÐ°.
+Ð¢Ó©Ð³ÑÐ³Ó©Ð» Ñ
+ÑÑÑÐ³Ñ ÐœÑ ÐŽÐ°ÑÐ°Ð°Ð³ÐžÐ¹Ðœ 20 Ð±Ð°ÑÐžÐŒÑÑÐ³ Ñ
+Ð°ÑÑÑÐ»Ð°Ñ
+ ÑÐŸÐ²Ñ Ð±Ð°Ð¹Ð³Ð°Ð°. Ð¢ÑÐœÐŽÑÑÑ ÑÐ°
+Ð³ÑÑÐ°Ð² ÐŽÐ°Ñ
+Ñ 20 Ð±Ð°ÑÐžÐŒÑÑÐ³ Ò¯Ð·ÑÑ
+, ÑÑÐ²ÑÐ» ÑÑÐ³ÑÑÐŽ ÑÑ
+ÐœÐžÐ¹Ñ
+ ÑÒ¯Ò¯ Ð±ÑÑÐ°Ñ
+ Ð³ÑÑÑÐœ ÑÐŸÐ²ÑÐœÑÑÐŽÑÐ³ ÐŸÐ»Ð¶ Ñ
+Ð°ÑÐœÐ°.
+ÐÐ°ÑÐžÐŒÑÑÐœ ÐœÑÑ ÐŽÑÑÑ ÑÐŒ ÑÑ ÑÑÐ²ÑÐ» ÐŽÑÑÐ³ÑÐŽÑÑ
+ Ð¶ÐžÐ¶ÐžÐ³ ÑÐŸÐ²Ñ ÐŽÑÑÑ ÐŽÐ°ÑÐ¶ ÐœÑÑÐ¶ Ò¯Ð·ÐœÑ Ò¯Ò¯.
+
+<p>Ð¥Ð°ÐŒÐ³ÐžÐ¹Ðœ ÐžÑ
+ÐŽÑÑ 100 Ò¯Ñ ÐŽÒ¯Ðœ Ð³Ð°ÑÑ ÐžÑÑÑ
+ÑÑÑ ÑÐŸÑ
+ÐžÑÑÑÐ»ÑÐ°Ðœ Ð±Ó©Ð³Ó©Ó©ÐŽ
+  ÑÐ° ÑÑÑÐœÐžÐ¹Ð³ ÑÒ¯Ò¯Ð»ÐŽ Ñ
+ÑÑÐŽÐ°ÑÐœÑ ÐŽÑÑÐŽ ÑÐ°Ð»ÐŽ Ð±Ð°Ð¹ÑÐ»Ð°Ñ
+ <i>_Global:linktextPREFERENCES_</i> ÑÐŸÐ²Ñ ÐŽÑÑÑ ÐŽÐ°ÑÐ¶ Ó©Ó©ÑÑÐ»Ó©Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹.<p>}  
+
+_texthelpquerytermstitle_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ ÐœÑÑ ÑÐŸÐŒÑÑÐŸ}
+_texthelpqueryterms_ [l=mn] {<p>Ð¥Ð°Ð¹Ð»ÑÑÐœ ÑÐ°Ð»Ð±Ð°ÑÑ ÑÐ°ÐœÑ ÐŸÑÑÑÐ»ÑÐ°Ðœ ÑÐµÐºÑÑÐžÐ¹Ð³ âÑ
+Ð°Ð¹Ð»ÑÑÐœ ÐœÑÑ ÑÐŸÐŒÑÑÐŸâ Ð³ÑÐ¶ 
+ÐœÑÑÐ»ÑÐŽÑÐ³. ÐÑÑ ÑÐŸÐŒÑÑÐŸ Ð±Ò¯Ñ Ò¯ÑÑÐ³, ÑÐŸÐŸÐœÐŸÐŸÑ Ð±Ò¯ÑÐŽÑÐœÑ. ÐÑÑ ÑÐŸÐŒÑÑÐŸÐœÑÑÐŽ ÐŽÑÐœÐŽÐ°Ð°
+Ð·Ð°Ð¹ Ð°Ð²Ñ ÑÑÑÐ³Ð°Ð°ÑÐ»Ð°Ð³ÐŽÐ°ÐœÐ°. Ð¯ÐŒÐ°Ñ ÐœÑÐ³ÑÐœ ÑÑÐ³ Ð³ÑÑ
+ ÐŒÑÑ ÑÑÐŒÐŽÐ³Ò¯Ò¯ÐŽ Ð±Ð°Ð¹Ñ
+ ÑÐŒ Ð±ÐŸÐ»
+ÑÑÑÐœÐžÐ¹Ð³ Ð·Ð°Ð¹ Ð°Ð²ÑÐ°Ðœ Ñ
+ÑÐŒÑÑÐœ Ñ
+Ò¯Ð»ÑÑÐœ Ð°Ð²ÐœÐ°. ÐÑÐœÐŽÐ°Ð° ÑÑÐ³ÑÑÐ¹ Ò¯Ð³ Ñ
+Ð°Ð¹Ð¶ Ð±ÐŸÐ»ÐŸÑ
+Ð³Ò¯Ð¹.
+
+<p>ÐÐžÑÑÑÐ»Ð±ÑÐ», Ñ
+Ð°Ð¹Ð»Ñ<p>
+    <ul><kbd>ÐÐŸÐŒÑ
+ÐŸÐœ ÐŽÐ°Ð»Ð°Ð¹Ðœ Ð°ÑÐ»ÑÑÐŽ ÐŽÑÑÑÑ
+ Ð¥Ó©ÐŽÓ©Ó© ÐÐ¶ ÐÑ
+ÑÐ¹ â ÐÐ¹Ðœ ÐÐ¶ ÐÑ
+ÑÐ¹: Ð¢ÐŸÐ³ÑÐ²ÐŸÑÑÐŸÐ¹ Ð±Ð°Ð¹ÐŽÐ»ÑÐœ ÑÐžÑÑÐµÐŒ (1993)</kbd></ul>
+      <p>Ð³ÑÑÑÐœ Ñ
+Ð°Ð¹Ð»Ñ ÐŽÐ°ÑÐ°Ð°Ñ
+ Ð±Ð°Ð¹ÐŽÐ»Ð°Ð°Ñ ÑÐœÑÐžÐ³ÐŽÐ°ÐœÐ°<p>
+      <ul><kbd> ÐÐŸÐŒÑ
+ÐŸÐœ ÐŽÐ°Ð»Ð°Ð¹Ðœ Ð°ÑÐ»ÑÑÐŽ ÐŽÑÑÑÑ
+ Ð¥Ó©ÐŽÓ©Ó© ÐÐ¶ ÐÑ
+ÑÐ¹  ÐÐ¹Ðœ ÐÐ¶ ÐÑ
+ÑÐ¹: Ð¢ÐŸÐ³ÑÐ²ÐŸÑÑÐŸÐ¹ Ð±Ð°Ð¹ÐŽÐ»ÑÐœ ÑÐžÑÑÐµÐŒ </kbd></ul><p>}
+
+_texthelpmgppsearching_ [l=mn] {MGPP ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ Ñ
+ÑÐ²ÑÐŽ Ó©Ó©Ñ Ð±Ð°Ñ Ñ
+ÑÐŽÑÐœ ÑÐŸÐœÐ³ÐŸÐ»Ñ Ð±Ð°Ð¹ÐŽÐ°Ð³.
+
+<ul>
+<li><b>*</b> Ð³ÑÐ²ÑÐ» Ð±Ò¯Ñ
+ Ò¯Ð³, <b>ÐŒÑÐœÐŽ*</b> Ð³ÑÐ²ÑÐ» <b>ÐŒÑÐœÐŽ</b> Ð³ÑÐ¶ ÑÑ
+ÑÐ»ÑÑÐœ Ð±Ò¯Ñ
+ Ò¯Ð³ÐžÐ¹Ð³ Ñ
+Ð°Ð¹ÐœÐ°.
+<li><b>/x</b> Ð³ÑÐ²ÑÐ» Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° ÑÑÑ
+Ð°Ð¹Ðœ Ò¯Ð³ÑÐœÐŽÑÑ <>x</> ÐŽÐ°Ñ
+ÐžÐœ ÐžÐ»Ò¯Ò¯ Ð°Ñ Ñ
+ÐŸÐ»Ð±ÐŸÐ³ÐŽÐŸÐ» Ó©Ð³Ñ Ð±Ð°Ð¹ÐœÐ° Ð³ÑÑÑÐœ Ò¯Ð³. ÐÐžÑÑÑ ÐœÑ <b>ÐœÐŸÐŒ/10 ÑÐŸÐ³Ð»ÐŸÐŸÐŒ</b> Ð³ÑÑ
+ ÑÐŒ Ð±ÐŸÐ» ÑÐ°ÐœÑÐ°Ð° ÑÐŸÐ³ÑÐŸÐŸÑ
+ÐŽÐŸÐŸ ÐœÐŸÐŒÐŸÐœÐŽ ÑÐŸÐ³Ð»ÐŸÐŸÐŒÐœÐŸÐŸÑ 10 ÐŽÐ°Ñ
+ÐžÐœ ÐžÐ»Ò¯Ò¯ Ð°Ñ Ñ
+ÐŸÐ»Ð±ÐŸÐ³ÐŽÐŸÐ» Ó©Ð³ÐœÓ© Ð³ÑÑÑÐœ Ò¯Ð³.
+</ul>}  
+
+_texthelplucenesearching_ [l=mn] {Lucene Ð°ÑÐžÐ³Ð»Ð°Ð¶ Ñ
+ÐžÐ¹ÑÑÐœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐœÑÑÐŽÑÐœ Ñ
+ÑÐ²ÑÐŽ Ó©Ó©Ñ Ñ
+ÑÐŽÑÐœ ÐœÑÐŒÑÐ»Ñ Ð±ÐŸÐ»ÐŸÐŒÐ¶ Ð±Ð°Ð¹Ð³Ð°Ð°.
+
+<ul>
+<li><b>?</b> ÑÑÐŒÐŽÑÐ³Ñ ÐœÑ ÐŽÑÑÑÐœ ÐœÑÐ³ Ò¯ÑÑÐ³ ÐžÐ»ÑÑÑ
+ÐžÐ¹Ð»ÑÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹(wildcard). ÐÐžÑÑÑ ÐœÑ, <b>Ñ?Ñ</b> Ð³ÑÐ²ÑÐ» <b>ÑÐ°Ñ</b>, <b>ÑÑÑ</b>, <b>ÑÐŸÑ</b> Ð³.ÐŒ ÐžÐ»ÑÑÑ
+ÐžÐ¹Ð»Ð¶ ÑÐ°ÐŽÐœÐ°
+<li><b>*</b> ÑÑÐŒÐŽÑÐ³Ñ ÐœÑ Ñ
+ÑÐŽ Ñ
+ÑÐŽÑÐœ Ò¯ÑÑÐ³ ÐžÐ»ÑÑÑ
+ÐžÐ¹Ð»ÑÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹. ÐÐžÑÑÑ ÐœÑ,
+<b>ÐŒÑÐœÐŽ*</b> Ð³ÑÐ¶ Ð±Ð°Ð¹Ð²Ð°Ð» <b>ÐŒÑÐœÐŽ</b> Ð³ÑÐ¶ ÑÑ
+ÑÐ»ÑÑÐœ Ð±Ò¯Ñ
+ Ò¯Ð³ÐžÐ¹Ðœ ÐžÐ»ÑÑÑ
+ÐžÐ¹Ð»ÐœÑ .
+</ul>
+ÐÑÑÑÑ
+Ðž Ñ
+ÐŸÑÑ ÑÑÐŒÐŽÑÐ³Ñ ÐœÑ Ò¯Ð³ÐžÐ¹Ðœ ÐŽÑÐœÐŽ Ð±Ð°Ð¹ Ð°ÐŽÐ°Ð³Ñ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÐŽÑÐ¶ Ð±ÐŸÐ»ÐœÐŸ. Ð¥Ð°ÑÐžÐœ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ Ò¯Ð³ÐžÐ¹Ðœ ÑÑ
+ÑÐœÐŽ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÐŽÑÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶Ð³Ò¯Ð¹.
+Both of these wildcards can}  
+
+_texthelpquerytypetitle_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ ÑÓ©ÑÓ©Ð»}
+_texthelpquerytype_ [l=mn] {<p>Ð¥ÐŸÑÑ ÑÓ©ÑÐ»ÐžÐ¹Ðœ Ñ
+Ð°Ð¹Ð»Ñ Ð±Ð°Ð¹ÐŽÐ°Ð³.
+
+<ul>
+  <li><b>ÐÒ¯Ñ
+</b> Ò¯Ð³ÐœÐžÐ¹ Ñ
+Ð°Ð¹Ð»Ñ. Ð­ÐœÑ Ñ
+Ð°Ð¹Ð»ÑÐ°Ð°Ñ ÑÐ°ÐœÑ ÐŸÑÑÑÐ»ÑÐ°Ðœ Ð±Ò¯Ñ
+ Ò¯Ð³ÐžÐ¹Ð³ Ð°Ð³ÑÑÐ»ÑÐ°Ðœ 
+      Ð±Ð°ÑÐžÐŒÑÑÐ³ (ÑÑÐ²ÑÐ» Ð±Ò¯Ð»ÑÐ³, Ð³Ð°ÑÑÐžÐ³ Ð³ÑÑ
+ ÐŒÑÑ) Ñ
+Ð°Ð¹ÐœÐ°. Ð¥Ð°Ð¹Ð»ÑÐ°ÐŽ ÑÐŸÑ
+ÐžÑÐŸÑ
+ Ò¯Ñ ÐŽÒ¯ÐœÐ³Ò¯Ò¯ÐŽ 
+      Ò¯ÑÐ³ÐžÐ¹Ðœ ÐŽÐ°ÑÐ°Ð°Ð»Ð»Ð°Ð°Ñ Ð³Ð°ÑÑ ÐžÑÐœÑ.<p>
+
+  <li><b>ÐÐ°ÑÐžÐŒ</b> Ò¯Ð³ÐœÐžÐ¹ Ñ
+Ð°Ð¹Ð»Ñ. Ð¢Ð°ÐœÑ Ñ
+Ð°Ð¹Ð¶ Ð±ÑÐ¹ Ð±Ð°ÑÐžÐŒÑÐ°ÐŽ Ð±Ð°Ð¹Ð¶ Ð±ÐŸÐ»ÐŸÑ
+ Ð·Ð°ÑÐžÐŒ 
+      Ò¯Ð³ÐœÒ¯Ò¯ÐŽ. Ð¥Ð°Ð¹Ð»ÑÑÐœ Ò¯Ñ ÐŽÒ¯Ðœ ÐœÑ ÑÐ°ÐœÑ Ñ
+Ð°Ð¹ÑÐ°Ðœ ÐœÑÑ ÑÐŸÐŒÑÑÐŸÐœÐŽ Ñ
+ÑÑ ÐŽÓ©Ñ
+Ò¯Ò¯ Ð±Ð°Ð¹ÐŽÐ»Ð°Ð°ÑÐ°Ð° Ð¶Ð°Ð³ÑÐ°Ð°Ð³ÐŽÐ°Ðœ Ð³Ð°ÑÑ ÐžÑÐœÑ. Ð¥ÑÑ ÐŽÓ©Ñ
+Ò¯Ò¯ Ð±Ð°Ð¹Ð³Ð°Ð°Ð³ ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹Ð»ÐŸÑ
+ÐŽÐŸÐŸ,
+
+      <p><ul>
+        <li> Ñ
+Ð°Ð¹Ð»ÑÑÐœ ÐœÑÑ ÑÐŸÐŒÑÑÐŸÐœÐŸÐŸÑ Ð±Ð°ÑÐžÐŒÑÐ°ÐŽ Ð°Ð³ÑÑÐ»Ð°Ð³ÐŽÐ°Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ñ
+ÑÐŒÐ¶ÑÑÐ³ÑÑÑ;
+        <li> Ñ
+ÐŸÐ²ÐŸÑ ÐœÑÑ ÑÐŸÐŒÑÑÐŸ ÐœÑ ÐœÐžÐ¹ÑÐ»ÑÐ³ ÑÐŸÑ
+ÐžÐŸÐ»ÐŽÐŽÐŸÐ³ÐŸÐŸÑÐŸÐŸ ÐžÐ»Ò¯Ò¯ ÑÑÑ
+Ð°Ð»;
+        <li> Ð±ÐŸÐ³ÐžÐœÐŸ Ð±Ð°ÑÐžÐŒÑ ÑÑÑÐ°Ð°ÑÐ°Ð° ÐžÐ»Ò¯Ò¯ ÑÐŸÑ
+ÐžÑÐŽÐŸÐ³.
+      </ul>
+</ul>
+
+<p>ÐÒ¯ÑÑÐœ Ó©Ð³Ò¯Ò¯Ð»Ð±ÑÑ, ÑÐ»ÐŒÐ°Ð°Ñ Ñ
+ÑÑÑÐ³ Ó©Ð³Ò¯Ò¯Ð»Ð±ÑÑÒ¯Ò¯ÐŽ, ÐŽÐŸÐ³ÐŸÐ» ÐŒÓ©Ñ Ñ
+Ò¯ÑÑÑÐ» ÐŸÑÑÑÐ»Ð¶ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹ÑÑÐœ Ñ 
+Ð±ÐŸÐ»ÐœÐŸ. ÐÐ°ÐœÑ ÐœÑÑ ÑÐŸÐŒÑÑÐŸÐ³ ÐŸÑÑÑÐ»Ð¶ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ð²ÑÐ» Ò¯Ñ ÐŽÒ¯Ðœ ÐœÑ ÐœÑÑ ÑÐŸÐŒÑÑÐŸÐœÑ ÐžÐ»ÑÑÐ»ÐžÐ¹Ðœ ÐŽÐ°Ð²ÑÐ°ÐŒÐ¶Ð°Ð°Ñ ÑÑÑÐŒÐ±ÑÐ»ÑÐ³ÐŽÑÐœ Ð³Ð°ÑÑ ÐžÑÐœÑ.<p>}  
+
+_texthelpadvancedsearchtitle_ [l=mn] {ÐÐ°ÑÐžÐ¹Ð²ÑÐžÐ»ÑÐ°Ðœ Ñ
+Ð°Ð¹Ð»Ñ}  
+
+_texthelpadvancedsearch_ [l=mn] {<p>Ð¥ÑÑÑÐ² ÑÐ° ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐ³ÐŸÐŸ ÐœÐ°ÑÐžÐ¹Ð²ÑÐžÐ»ÑÐ°Ðœ Ñ
+Ð°Ð¹Ð»ÑÑÐœ Ð³ÐŸÑÐžÐŒ Ð³ÑÐ¶ Ñ
+ÐžÐ¹ÑÑÐœ Ð±ÐŸÐ» Ñ
+Ð°Ð¹Ð»Ñ Ð°ÑÐ°Ð¹ Ó©Ó©Ñ Ð±Ð°Ð¹ÐŽÐ»Ð°Ð°Ñ Ñ
+ÐžÐ¹Ð³ÐŽÑÐœÑ. _selectadvancedsearch_}  
+
+_texthelpadvsearchmg_ [l=mn] {MG ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÐœÐ°ÑÐžÐ¹Ð²ÑÐžÐ»ÑÐ°Ðœ Ñ
+Ð°Ð¹Ð»Ñ ÐœÑ ÑÐ°ÐœÑÐ°Ð°, ÐœÓ©Ñ
+ÑÓ©Ð» ÑÐ°Ð»Ð³Ð°Ñ
+ Ð³ÑÑÑÐœ Ñ
+ÐŸÑÑ ÑÐŸÐœÐ³ÐŸÐ»ÑÑÐŸÐ¹.
+<b>ÑÐ°ÐœÑÐ°Ð°</b> Ñ
+Ð°Ð¹Ð»Ñ ÐœÑ <a href="\#query-type">_texthelpquerytypetitle_</a>-ÐŽ ÑÐ°Ð¹Ð»Ð±Ð°ÑÐ»Ð°ÑÐ°Ðœ  <b>Ð·Ð°ÑÐžÐŒ</b> Ñ
+Ð°Ð¹Ð»ÑÑÐ°Ð¹ ÑÐ³ Ð°ÐŽÐžÐ».
+<p>_texthelpbooleansearch_}  
+
+_texthelpbooleansearch_ [l=mn] {<b>ÐœÓ©Ñ
+ÑÓ©Ð» ÑÐ°Ð»Ð³Ð°Ñ
+</b> Ñ
+Ð°Ð¹Ð»Ñ ÐœÑ & ("Ð±Ð°"), | ("ÑÑÐ²ÑÐ»"), ÐŒÓ©Ðœ ! ("Ð±Ð°Ð¹Ñ
+Ð³Ò¯Ð¹") Ð·ÑÑÑÐ³ Ñ
+Ð°Ð¹Ð»ÑÑÐœ  ÑÒ¯Ð»Ñ
+Ò¯Ò¯Ñ Ò¯Ð³ÐœÒ¯Ò¯ÐŽÐžÐ¹Ðœ Ñ
+ÐŸÑÐ»ÐŸÐ»ÑÐ³ Ñ
+ÑÑÑÐ³Ð»ÑÐœÑ. Ð¡ÑÐ°ÐœÐŽÐ°ÑÑ ÑÑÐ³Ð° ÐœÑ | ("Ð±ÑÑÑ") Ð±Ð°Ð¹ÐœÐ°.
+<p>
+ÐÐžÑÑÑ ÐœÑ, <b>ÑÐ¿ÐŸÑÑ & Ð°ÑÐ»Ð°Ð»</b> Ð³ÑÑ
+ ÑÐŒ Ð±ÐŸÐ» <b>ÑÐ¿ÐŸÑÑ</b> ÐÐ <b>Ð°ÑÐ»Ð°Ð»</b> Ð³ÑÑÑÐœ Ñ
+ÐŸÑÑ Ò¯Ð³ Ð·ÑÑÑÐ³ ÐŸÑÑÐŸÐœ Ð±Ð°ÑÐžÐŒÑÑÑÐŽÑÐ³ Ñ
+Ð°Ð¹ÐœÐ°, Ñ
+Ð°ÑÐžÐœ <b>ÑÐ¿ÐŸÑÑ | Ð°ÑÐ»Ð°Ð»</b> Ð³ÑÑ
+ ÑÐŒ Ð±ÐŸÐ» <b>ÑÐ¿ÐŸÑÑ</b> Ð­Ð¡ÐÐ­Ð <b>Ð°ÑÐ»Ð°Ð»</b> Ð³ÑÑÑÐœ Ò¯Ð³ ÐŸÑÑÐŸÐœ Ð±Ð°ÑÐžÐŒÑ Ñ
+Ð°Ð¹Ñ
+ Ð±ÐŸÐ»ÐœÐŸ.
+<b>ÑÐ¿ÐŸÑÑ !Ð°ÑÐ»Ð°Ð»</b> Ð³ÑÐ²ÑÐ» <b>ÑÐ¿ÐŸÑÑ</b> Ð³ÑÑÑÐœ Ò¯Ð³ ÐŸÑÑÐŸÐœ Ñ
+Ð°ÑÐžÐœ <b>Ð°ÑÐ»Ð°Ð»</b> Ð³ÑÑÑÐœ Ò¯Ð³ ÐŸÑÐŸÐŸÐ³Ò¯Ð¹ Ð±Ð°ÑÐžÐŒÑÐ°Ð°Ñ Ñ
+Ð°Ð¹ÐœÐ°.
+<p>
+Ð­ÐŽÐ³ÑÑÑ ÐŸÐ¿ÐµÑÐ°ÑÐŸÑ Ð±ÐŸÐ»ÐŸÐœ Ñ
+Ð°Ð°Ð»ÑÑÐ³ Ð°ÑÐžÐ³Ð»Ð°Ðœ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ð¶ Ð±ÐŸÐ»ÐœÐŸ. ÐÐžÑÑÑ ÐœÑ, <b>(Ñ
+ÐŸÐœÑ | ÑÐŒÐ°Ð°) & (Ó©Ð²Ó©Ð»Ð¶Ó©Ó© | Ñ
+Ð°Ð²Ð°ÑÐ¶Ð°Ð°)</b>, ÑÑÐ²ÑÐ» <b>Ñ
+ÐŸÐœÑ | ÑÑÐŒÑÑ | ÐŒÐŸÑÑ !Ð³Ð°Ñ
+Ð°Ð¹</b>.}  
+
+_texthelpadvsearchmgpp_ [l=mn] {MGPP ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÐœÐ°ÑÐžÐ¹Ð²ÑÐžÐ»ÑÐ°Ðœ Ñ
+Ð°Ð¹Ð»Ñ ÐœÑ ÐœÓ©Ñ
+ÑÓ©Ð» ÑÐ°Ð»Ð³Ð°Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹. _texthelpbooleansearch_ 
+<p>Ò®Ñ ÐŽÒ¯Ðœ ÐœÑ <a href="\#query-type">_texthelpquerytypetitle_</a> ÑÐ°Ð¹Ð»Ð±Ð°ÑÐ»Ð°ÑÐœÐ°Ð°Ñ <b>ÑÐ°ÐœÑÐ°Ð°Ð³Ð°Ð°Ñ</b>, ÑÑÐ²ÑÐ» "Ñ
+ÐžÐ¹Ð³ÐŽÑÑÐœ" ÐŽÐ°ÑÐ°Ð°Ð»Ð»Ð°Ð°Ñ Ñ
+Ð°ÑÐ°Ð³ÐŽÐ°ÐœÐ°. Ð¥ÐžÐ¹Ð³ÐŽÑÑÐœ ÐŽÐ°ÑÐ°Ð°Ð»Ð°Ð» Ð³ÑÐŽÑÐ³ ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÐ³ÑÑÑÐœ ÐŽÐ°ÑÐ°Ð°Ð»Ð°Ð» ÑÐŒ.
+<p>
+<b>NEARx</b>, <b>WITHINx</b> Ñ
+ÐŸÑÑ ÐºÐŸÐŒÐ°ÐœÐŽ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÐŽÐŽÑÐ³.
+NEARx  is used to specify the maximum distance apart (x words) two query
+terms must be for a document to match. 
+WITHINx specifies that the second term must occur within x words <i>after</i> the first term. This is similar to NEAR but the order is important. The default distance is 20.}  
+
+_texthelpadvancedsearchextra_ [l=mn] {ÐÐÐ¥ÐÐÐ : Ñ
+Ð°Ð¹Ð»Ñ ÑÐœÐ³ÐžÐ¹Ðœ Ñ
+Ò¯ÑÑÐ»ÑÐžÐ¹Ðœ Ð³ÐŸÑÐžÐŒÐŽ Ñ
+ÐžÐ¹Ð³ÐŽÑÐ¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±ÐŸÐ» ÑÐŽÐ³ÑÑÑ ÐŸÐ¿ÐµÑÐ°ÑÐŸÑÑÑÐŽ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÐŽÑÑ
+Ð³Ò¯Ð¹.}  
+
+_texthelpadvsearchlucene_ [l=mn] {Lucene ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÐœÐ°ÑÐžÐ¹Ð²ÑÐžÐ»ÑÐ°Ðœ Ñ
+Ð°Ð¹Ð»Ñ ÐœÑ ÐœÓ©Ñ
+ÑÓ©Ð» ÑÐ°Ð³Ð»Ð°Ñ
+ _texthelpbooleansearch_
+ÐŸÐ¿ÐµÑÐ°ÑÐŸÑ Ñ
+ÑÑÑÐ³Ð»ÑÐŽÑÐ³}  
+
+_texthelpformsearchtitle_ [l=mn] {Ð¢Ð°Ð»Ð±Ð°ÑÑ Ñ
+Ð°Ð¹Ð»Ñ}  
+
+_texthelpformsearch_ [l=mn] {<p>Ð¢Ð°Ð»Ð±Ð°ÑÑ Ñ
+Ð°Ð¹Ð»Ñ ÐœÑ Ñ
+Ð°Ð¹Ð»ÑÑÑÐŽÑÐ³ ÑÐ°Ð»Ð±Ð°ÑÐ°Ð°Ñ ÐœÑ ÐœÑÐ³ÑÐ³ÑÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ ÐŸÐ»Ð³ÐŸÐŽÐŸÐ³. ÐÐžÑÑÑ ÐœÑ, ÐœÑÐ³ Ñ
+Ò¯Ðœ ÐÐ°ÑÑÐžÐ³ Ð±ÐŸÐ»ÐŸÐœ Ð¡ÑÐŽÐ²ÑÑÑ ÐœÑ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ÐŽÑÑ Ð¡ÑÐŽÑÐ² ÐŽÑÑÑ "snail farming", ÐÐ°ÑÑÐžÐ³ ÐŽÑÑÑ "Smith" Ð³ÑÑÑÐœ Ð±ÐŸÐ» Ñ
+Ò¯ÑÑÐ»ÑÐžÐ¹Ðœ ÑÐœÐ³ÐžÐ¹Ðœ Ð³ÐŸÑÐžÐŒÐŸÐœÐŽ, ÑÐœÑ Ñ
+ÑÐ»Ð±ÑÑÐžÐ¹Ðœ ÐŒÓ©Ñ Ð±Ò¯Ñ ÐœÑ ÑÐœÐ³ÐžÐ¹Ðœ ÐœÑÐ³ ÐŒÓ©ÑÐžÐ¹Ðœ Ñ
+Ð°Ð¹Ð»Ñ ÐŒÐ°ÑÐ³Ð°Ð°Ñ Ð°Ð¶ÐžÐ»Ð»Ð°ÐœÐ°. Ð¥Ð°ÑÐžÐœ Ð±ÐžÐŽ ÑÐŽÐœÐžÐ¹ ÐŽÑÐœÐŽ AND (Ð±Ò¯Ñ
+ Ñ
+Ð°Ð¹Ð»ÑÑÐœ Ñ
+ÑÐ²ÑÐŽ) Ð±ÑÑÑ OR(Ð·Ð°ÑÐžÐŒ Ñ
+Ð°Ð¹Ð»ÑÑÐœ Ñ
+ÑÐ²ÑÐŽ) Ñ
+ÑÑÑÐ³Ð»ÑÐœ ÐœÑÐ³ÑÐ³ÑÐ¶ Ð±ÐŸÐ»ÐœÐŸ. Ð¢Ð°Ð»Ð±Ð°Ñ ÐŽÐŸÑÐŸÑÑ
+ ÐœÑÑÑÐžÐ¹Ð³ Ñ ÐŒÓ©Ðœ Ð°ÐŽÐžÐ» ÐœÑÐ³ÑÐ³ÑÐœ Ð°ÑÐžÐ³Ð»Ð°Ð¶ Ð±ÐŸÐ»ÐœÐŸ. ÐÑ
+ÐžÑÐ°Ðœ ÑÒ¯Ð²ÑÐœÐžÐ¹ Ð³ÐŸÑÐžÐŒÐŸÐœÐŽ, ÑÐ° ÑÐ°Ð»Ð±Ð°ÑÑÑÐŽÑÐœ Ñ
+ÐŸÐŸÑÐŸÐœÐŽ drop-down list ÐŽÐŸÑÐŸÑ AND/OR/NOT-ÑÐœ ÑÐœÐ· Ð±Ò¯ÑÐžÐ¹Ðœ Ñ
+ÐŸÑÐ»ÐŸÐ» Ñ
+ÑÑÑÐ³Ð»ÑÐ¶ Ð±ÐŸÐ»ÐŸÑ
+ Ð±Ð° ÐŒÓ©Ðœ ÑÐ°Ð»Ð±Ð°Ñ ÐŽÐŸÑÐŸÑ ÐÑÐ»ÐžÐ¹Ðœ ÐŸÐ¿ÐµÑÐ°ÑÐŸÑ Ð°ÑÐžÐ³Ð»Ð°Ð¶ Ð±ÐŸÐ»ÐœÐŸ.}  
+
+
+
+_textdatesearch_ [l=mn] {ÓšÐŽÑÒ¯Ò¯ÐŽÑÑÑ Ð¥Ð°Ð¹Ñ
+}  
+
+_texthelpdatesearch_ [l=mn] {ÐÐ³ÐœÐŸÐŸÐœÑ Ñ
+Ð°Ð¹Ð»Ñ Ð°ÑÐžÐ³Ð»Ð°ÑÐœÐ°Ð°Ñ ÑÐ° Ð±Ð°ÑÐžÐŒÑÑÑÐŽ ÐŽÐŸÑÐŸÑ ÑÐŸÑ
+ÐžÑÐŸÑ
+ Ò¯Ñ ÐŽÒ¯Ðœ Ñ
+Ð°Ð¹Ñ
+Ð°Ð°Ñ
+Ð³Ð°ÐŽÐœÐ° ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹ Ñ
+ÑÐ³Ð°ÑÐ°Ð°ÐœÑ Ð·Ð°Ð²ÑÐ°ÑÑ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÑÐŸÐ¹. ÐÐ°Ð°Ð²Ð°Ð» Ñ
+Ð°Ð¹Ð»ÑÑÐœ
+ÐœÑÑ ÑÐŸÐŒÑÑÐŸ ÐŸÑÑÑÐ»Ð°Ñ
+ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³Ð°Ð³Ò¯Ð¹ Ð·Ó©Ð²Ñ
+Ó©Ðœ ÐŸÐ³ÐœÐŸÐŸÐ³ÐŸÐŸ Ñ
+Ð°Ð¹Ñ
+Ð°ÐŽ Ð» Ð±ÐŸÐ»ÐœÐŸ
+Ð³ÑÐŽÐ³ÐžÐ¹Ð³ ÑÐ°ÐœÐ°ÐœÐ° ÑÑ. ÐÓ©Ðœ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ÐŽÑÑ Ñ
+ÑÐ³Ð°ÑÐ°Ð°Ð³ Ð³Ð°ÑÐœÐ°Ð°Ñ ÐŸÑÑÑÐ»Ð±Ð°Ð» ÐŸÐ³ÐœÐŸÐŸÐœÑ
+Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹ÑÑÐœ Ð±ÐŸÐ»ÐŸÑ
+Ð³Ò¯Ð¹.<p>}
+
+_texthelpdatehowtotitle_ [l=mn] {Ð¥ÑÑÑ
+ÑÐœ Ð°ÑÐžÐ³Ð»Ð°Ñ
+ Ð²Ñ:}
+_texthelpdatehowto_ [l=mn] {<ul>
+   <li>ÐÑÐ³ Ð¶ÐžÐ»ÐžÐ¹Ðœ ÐŽÐŸÑÐŸÑ Ð±Ð°ÑÐžÐŒÑÑÐ³ Ñ
+Ð°Ð¹Ñ
+:<p>
+   <ul>
+       <li>Ð­ÐœÐ³ÐžÐ¹Ðœ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° ÐŒÑÑÑÑÑ ÐœÑÑ ÑÐŸÐŒÑÑÐŸÐ³ÐŸÐŸ ÐŸÑÑÑÐ».
+       <li>"Ð­Ñ
+Ð»ÑÑ
+ (ÑÑÐ²ÑÐ» Ð·Ó©Ð²Ñ
+Ó©Ðœ) ÐŸÐ³ÐœÐŸÐŸ" ÑÐ°Ð»Ð±Ð°ÑÑ ÐŸÐ³ÐœÐŸÐŸÐ³ ÐŸÑÑÑÐ».
+       <li>Ð¥ÑÑÑÐ² ÑÐ°ÐœÑ ÐŸÑÑÑÐ»ÑÐ°Ðœ ÐŸÐ³ÐœÐŸÐŸ ÐœÐžÐ¹ÑÐžÐ¹Ðœ ÐŸÐœ ÑÐŸÐŸÐ»Ð»ÐŸÐŸÑ Ó©ÐŒÐœÓ©
+             (Ð±Ð°Ñ ÐŒÐ°ÐœÐ°Ð¹ ÑÑÐžÐœÐžÐ¹ Ó©ÐŒÐœÓ© Ð³ÑÐ³ÐŽÐŽÑÐ³) Ð±ÐŸÐ» ÐŽÑÑÐ³ÑÐŽÑÑ
+ Ð·Ð°ÐŽÑÐ°Ñ
+
+             ÑÑÑÐœÑÑÑ âÐ.Ð.Ð¢.Óšâ ÑÐŸÐœÐ³ÐŸÐ»ÑÑÐ³ ÑÐŸÐœÐ³ÐŸÐœÐŸ.
+       <li>Ð¥Ð°Ð¹Ð»ÑÐ°Ð° ÑÑ
+Ð»Ò¯Ò¯Ð»ÐœÑ.
+   </ul>
+<p><li>Ð¢ÐŸÐŽÐŸÑÑ
+ÐŸÐ¹ Ñ
+ÑÐ³Ð°ÑÐ°Ð°ÐœÑ Ð·Ð°Ð²ÑÐ°ÑÑ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+:<p>
+   <ul>
+       <li> Ð­ÐœÐ³ÐžÐ¹Ðœ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° ÐŒÑÑÑÑÑ ÐœÑÑ ÑÐŸÐŒÑÑÐŸÐ³ÐŸÐŸ ÐŸÑÑÑÐ».
+       <li>"Ð­Ñ
+Ð»ÑÑ
+ (ÑÑÐ²ÑÐ» Ð·Ó©Ð²Ñ
+Ó©Ðœ) ÐŸÐ³ÐœÐŸÐŸ" ÑÐ°Ð»Ð±Ð°ÑÑ ÑÑ
+Ð»ÑÑ
+ ÐŸÐ³ÐœÐŸÐŸÐ³ ÐŸÑÑÑÐ».
+       <li>âÐÑÑÑÐ°Ñ
+ ÐŸÐ³ÐœÐŸÐŸâ ÑÐ°Ð»Ð±Ð°ÑÑ ÑÒ¯Ò¯Ð»ÐžÐ¹Ðœ ÐŸÐ³ÐœÐŸÐŸÐ³ ÐŸÑÑÑÐ»ÐœÐ°.
+       <li> Ð¥ÑÑÑÐ² ÑÐ°ÐœÑ ÐŸÑÑÑÐ»ÑÐ°Ðœ ÐŸÐ³ÐœÐŸÐŸ ÐœÐžÐ¹ÑÐžÐ¹Ðœ ÐŸÐœ ÑÐŸÐŸÐ»Ð»ÐŸÐŸÑ Ó©ÐŒÐœÓ©
+             (Ð±Ð°Ñ ÐŒÐ°ÐœÐ°Ð¹ ÑÑÐžÐœÐžÐ¹ Ó©ÐŒÐœÓ© Ð³ÑÐ³ÐŽÐŽÑÐ³) Ð±ÐŸÐ» ÐŽÑÑÐ³ÑÐŽÑÑ
+ Ð·Ð°ÐŽÑÐ°Ñ
+
+             ÑÑÑÐœÑÑÑ âÐ.Ð.Ð¢.Óšâ ÑÐŸÐœÐ³ÐŸÐ»ÑÑÐ³ ÑÐŸÐœÐ³ÐŸÐœÐŸ.
+       <li>Ð¥Ð°Ð¹Ð»ÑÐ°Ð° ÑÑ
+Ð»Ò¯Ò¯Ð»ÐœÑ.
+   </ul>    
+</ul><p>}
+
+_texthelpdateresultstitle_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ ÑÐ°ÐœÑ Ò¯Ñ ÐŽÒ¯Ðœ Ñ
+ÑÑÑ
+ÑÐœ Ð°ÑÐžÐ»Ð»Ð°Ñ
+ Ð²Ñ}
+_texthelpdateresults_ [l=mn] {ÐÑÓ©ÐœÑ
+ÐžÐ¹ÐŽÓ©Ó© 1903 ÐŸÐœÑ ÑÑÑ
+Ð°Ð¹ Ð±Ð°ÑÐžÐŒÑ Ñ
+Ð°Ð¹Ð²Ð°Ð» 1903 ÐŸÐœÐŽ Ð±ÐžÑÐžÐ³ÐŽÑÑÐœ Ð»Ð°Ð²Ð»Ð°Ñ
+ ÐœÐŸÐŒ ÐŸÐ»ÐŽÐŸÑ
+Ð³Ò¯Ð¹ Ñ
+Ð°ÑÐžÐœ 1903 ÐŸÐœÑ ÑÑÑ
+Ð°Ð¹ Ð±Ð°ÑÐžÐŒÑÑÑÐŽ ÐŸÐ»ÐŽÐŸÐœÐŸ. ÐÑÐ²Ñ Ð±Ð°ÑÐžÐŒÑÑÐœ ÐŸÐ³ÐœÐŸÐŸÐœÑ ÐŸÐ»ÐŽÐŸÑ
+ Ð±Ð°Ð¹ÐŽÐ»Ð°Ð°Ñ ÑÐ°Ð»ÑÐ³Ð°Ð°Ð»Ð°Ðœ Ñ
+Ð°Ð¹Ð»ÑÑÐœ Ò¯Ñ ÐŽÒ¯ÐœÐŽ 1903 ÐŸÐœÑÐ³ Ð°Ð³ÑÑÐ»ÑÐ°Ðœ Ñ
+ÑÐ³Ð°ÑÐ°Ð°ÐœÑ Ð·Ð°Ð²ÑÑÑÐ³ (Ð¶ÐžÑÑÑ ÐœÑ 1899-1911 Ð³ÑÑ
+ ÐŒÑÑ) Ð³Ð°ÑÐ³Ð°Ñ
+ Ð±Ð° ÐŒÓ©Ðœ ÐœÑÑÐœÐžÐ¹Ñ
+ ÐœÑ Ñ
+ÑÑÑÐ³ ÐœÑ 1903 ÐŸÐœÑÐ³ Ð°Ð³ÑÑÐ»ÐŽÐ°Ð³ Ð·ÑÑÐœÑÐ³ Ð°Ð³ÑÑÐ»ÑÐ°Ðœ Ð±Ð°ÑÐžÐŒÑÑÑÐŽÑÐ³ Ð³Ð°ÑÐ³Ð°Ð¶ ÐžÑÐœÑ. Ð­ÐœÑ ÐœÑ Ð±Ð°Ñ Ð·Ð°ÑÐžÐŒ Ð±Ð°ÑÐžÐŒÑÑÑÐŽÑÐœ Ñ
+ÑÐ²ÑÐŽ Ñ
+Ð°Ð¹Ð»ÑÑÐœ ÑÐ°ÐœÑ ÐŸÐ³ÐœÐŸÐŸ Ð±Ð°ÑÐžÐŒÑÑÑÐŽÑÐœ ÑÐµÐºÑÑÑÐŽ Ñ
+Ð°ÑÐ°Ð³ÐŽÐ°Ñ
+Ð³Ò¯Ð¹ Ð³ÑÑÑÐœ Ò¯Ð³ ÑÐŒ. Ð¥ÑÐ³Ð°ÑÐ°Ð°ÐœÑ Ð·Ð°Ð²ÑÐ°ÑÑ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±ÐŸÐ» ÑÐœÑ Ð±Ò¯Ñ
+ÑÐœ ÑÑÑ
+Ð°Ð¹Ðœ Ð·Ð°Ð²ÑÐ°Ñ ÐŽÐ°Ñ
+Ñ Ð±Ò¯Ñ
+ ÐŸÐ³ÐœÐŸÐŸÐœÐŽ Ñ
+Ð°ÐŒÐ°Ð°ÑÐœÐ°. <p>}
+
+_textchangeprefs_ [l=mn] {ÓšÓ©ÑÐžÐ¹Ðœ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐ³ Ó©Ó©ÑÑÐ»Ó©Ñ
+}
+
+_texthelppreferences_ [l=mn] {<p>Ð¢Ð° <i>_Global:linktextPREFERENCES_</i> ÑÐŸÐ²Ñ ÐŽÑÑÑ ÐŽÐ°ÑÑÐœÐ°Ð°Ñ Ñ
+ÑÑÐŽÐ°ÑÐœÑ ÐŽÑÑÑ Ð³Ð°ÑÑ ÐžÑÑÑ
+
+Ð·Ð°ÑÐžÐŒ ÐœÑÐŒÑÐ»Ñ ÑÐŸÐœÐ³ÐŸÐ»ÑÑÑÐŽÑÐ³ Ð°ÑÐžÐ³Ð»Ð°Ðœ ÐžÐœÑÐµÑÑÑÐ¹ÑÑÑ Ó©Ó©ÑÑÓ©Ó© ÑÐŸÑ
+ÐžÑÑÑÐ»Ð°Ðœ
+Ð·Ð°ÑÑ Ð±ÐŸÐ»ÐœÐŸ.}  
+
+_texthelpcollectionprefstitle_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ}
+_texthelpcollectionprefs_ [l=mn] {ÐÐ°ÑÐžÐŒ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ñ
+ÑÐŽ Ñ
+ÑÐŽÑÐœ Ð¶ÐžÐ¶ÐžÐ³ ÐŽÑÐŽ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÑÐ°Ð¹ Ð±Ð°Ð¹ÐŽÐ°Ð³ Ð±Ð° ÑÑÐŽÐ³ÑÑÑ
+ÐœÑ ÑÑÑ ÑÑÑÐŽÐ°Ð° ÑÑÐ²ÑÐ» ÐœÑÐ³ÐŽÐŒÑÐ» Ð±Ð°Ð¹ÐŽÐ»Ð°Ð°Ñ Ñ
+Ð°Ð¹Ð»ÑÐ°ÐŽ Ñ
+Ð°ÐŒÑÐ°Ð³ÐŽÐ°Ð¶ Ð±ÐŸÐ»ÐŽÐŸÐ³. Ð­ÐœÑ
+ÑÐŸÑ
+ÐžÐŸÐ»ÐŽÐŸÐ»ÐŽ ÑÐ° Ð¢ÐŸÑ
+ÐžÑÐ³ÐŸÐŸ Ñ
+ÑÑÐŽÑÐ°ÐœÐŽ ÐŸÑÐžÑ
+ Ð°Ð»Ñ ÐŽÑÐŽ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ñ
+Ð°Ð¹Ð»ÑÐ°ÐŽ
+Ñ
+Ð°ÐŒÑÑÑÐ»Ð°Ñ
+Ð°Ð° ÑÐŸÐœÐ³ÐŸÐœÐŸ.}
+
+_texthelplanguageprefstitle_ [l=mn] {Ð¥ÑÐ»ÐœÐžÐ¹ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ}
+_texthelplanguageprefs_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð±Ò¯Ñ Ð°Ð²ÑÐŸÐŒÐ°Ñ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐ³ÐŸÐŸÑ ÑÐŒÐ°Ñ ÐœÑÐ³ÑÐœ Ñ
+ÑÐ»ÐœÑÑ ÑÐ°ÐœÐžÐ»ÑÑÑÐ»Ð°Ð³ÐŽÑÐ°Ðœ
+Ð±Ð°Ð¹Ñ
+ Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÐ° ÑÒ¯Ò¯ÐœÐžÐ¹Ð³ ÐŽÐ°ÑÐ°Ð° ÐœÑ ÑÐŸÐ»ÑÐ¶ Ð±ÐŸÐ»ÐœÐŸ. ÐÑÐ°ÑÐ·ÐµÑÑ Ð³Ð°ÑÐ³Ð°Ñ
+ÐŽÐ°Ð°
+Greenstone ÑÐžÑÑÐµÐŒÐžÐ¹Ðœ Ó©Ó©ÑÐžÐ¹ÐœÑ
+ ÐœÑ ÐºÐŸÐŽÐ»ÐŸÐ»ÑÐœ ÑÑ
+ÐµÐŒÐžÐ¹Ð³ Ð°ÑÐžÐ³Ð»Ð°Ð¶ Ð±ÐŸÐ»ÐŸÑ
+
+Ð±ÐŸÐ»ÐŸÐ²Ñ Ð·Ð°ÑÐžÐŒ Ð±ÑÐ°ÑÐ·ÐµÑÑÑÐŽÑÐœ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐœÐŸÐŸÑ ÑÐ°Ð»ÑÐ³Ð°Ð°Ð»Ð°Ðœ ÑÐœÐ· Ð±Ò¯ÑÐžÐ¹Ðœ
+ÐºÐŸÐŽÐ»ÐŸÐ»ÑÐœ ÑÑ
+ÐµÐŒÒ¯Ò¯ÐŽÐžÐ¹Ð³ Ð°ÑÐžÐ³Ð»Ð°Ð¶ Ð±ÐŸÐ»ÐœÐŸ. ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð±Ò¯Ñ ÑÐ°ÐœÐŽ ÑÑÐ°ÐœÐŽÐ°ÑÑÑÐœ
+Ð³ÑÐ°ÑÐžÐº ÐžÐœÑÐµÑÑÑÐ¹ÑÑÑÑ ÐŽÐ°Ðœ ÑÐµÐºÑÑÑÐœ ÐžÐœÑÐµÑÑÑÐ¹Ñ ÑÒ¯Ò¯ ÑÐžÐ»Ð¶ÐžÑ
+ ÐŽÐ°Ð²ÑÑ ÑÐ°Ð»ÑÐ³
+ÐŸÐ»Ð³ÐŸÐŽÐŸÐ³. Ð­ÐœÑ ÐœÑ Ñ
+Ð°ÑÐ°Ð°ÐœÑ ÑÐŸÐ³ÐŸÐ³ÑÐŸÐ¹ Ñ
+Ò¯ÐŒÒ¯Ò¯ÑÑ Ñ
+ÑÑÑÐ³Ð»ÑÑ
+ÑÐŽ ÐŒÐ°Ñ Ð°ÐŒÐ°Ñ Ð±ÐŸÐ»ÐŸÑ
+
+Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÑÐŽ ÑÐŸÐŒ Ñ
+ÑÐŒÐ¶ÑÑÐœÐžÐ¹ ÑÐŸÐœÑÐŸÐŸÑ Ñ
+Ð°ÑÐ°Ñ
+ Ð·ÑÑÐ³ÑÑÑ Ð°ÑÐžÐ³Ð»Ð°Ð¶ Ð±ÐŸÐ»ÐŸÑ
+ ÑÐŒ.}
+
+_texthelppresentationprefstitle_ [l=mn] {Ð¢Ð°ÐœÐžÐ»ÑÑÑÐ»Ð³ÑÐœ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ}
+_texthelppresentationprefs_ [l=mn] {Ð¢ÐŸÐŽÐŸÑÑ
+ÐŸÐ¹ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°Ð°Ñ Ñ
+Ð°ÐŒÐ°Ð°ÑÐ°Ðœ ÑÐ°ÐœÐžÐ»ÑÑÑÐ³ÑÐ³ Ñ
+ÑÐœÐ°Ñ
+ Ñ
+ÑÐŽ Ñ
+ÑÐŽÑÐœ ÑÓ©ÑÐ»ÐžÐ¹Ðœ
+ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐœÑ ÑÐŸÐœÐ³ÐŸÐ»Ñ Ð±Ð°Ð¹Ð¶ Ð±ÐŸÐ»ÐœÐŸ.
+
+<p>ÐÑÐ± Ñ
+ÑÑÐŽÑÑÑÐŽÑÐœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽ Greenstone ÑÐžÑÑÐµÐŒÐžÐ¹Ðœ ÐœÐ°Ð²ÐžÐ³Ð°ÑÐžÐ¹Ðœ ÑÐ°Ð»Ð±Ð°Ñ
+Ð±Ð°ÑÐžÐŒÑÑÐœ Ñ
+ÑÑÐŽÐ°Ñ Ð±Ò¯ÑÐžÐ¹Ðœ ÐŽÑÑÐŽ Ñ
+ÑÑÑÐ³Ñ Ð³Ð°ÑÑ ÐžÑÑÑ
+ Ð±Ð° Ñ
+Ð°Ð¹Ð»ÑÐ°Ð° Ñ
+ÐžÐ¹Ð¶ ÐŽÑÑÑÑÐ°ÐœÑ
+ÐŽÐ°ÑÐ°Ð° ÐŸÑÑÐŸÐœ Ñ
+ÑÑÐŽÐ°Ñ ÑÐ°ÐœÑ ÑÐžÐ¹ÐŒ ÑÐ°Ð»Ð±Ð°ÑÐ³Ò¯Ð¹Ð³ÑÑÑ Ð³Ð°ÑÑ ÐžÑÑÑ
+ Ð±ÐŸÐ»ÐœÐŸ. ÓšÓ©Ñ Ñ
+Ð°Ð¹Ð»Ñ
+Ñ
+ÐžÐ¹Ñ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ ÑÐ° Ð±ÑÐ°ÑÐ·ÐµÑÑÐœÑ
+Ð°Ð° Ð±ÑÑÐ°Ñ
+ ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐ°Ñ
+ Ñ
+ÑÑÑÐ³ÑÑÐ¹. ÐÓ©Ðœ ÑÐ°ÐœÑÐ³
+ÑÐ»ÐµÐºÑÑÐŸÐœ ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³Ð°Ð°Ñ Ð³Ð°ÑÐ°Ð°ÐŽ ÐžÐœÑÐµÑÐœÑÑ ÑÒ¯Ò¯ ÑÐžÐ³Ð»ÑÑÑÐœ Ð»ÐžÐœÐº ÐŽÐ°ÑÐ°Ñ
+Ð°ÐŽ
+Greenstone ÑÐžÑÑÐµÐŒÐžÐ¹Ðœ Ð°ÐœÑ
+Ð°Ð°ÑÑÑÐ»Ð°Ñ
+ Ð·ÑÑÐ²Ð°Ñ ÐžÐ»Ð³ÑÑÐŽÑÐ³. ÐÐ°ÑÐžÐŒ Ð²ÑÐ±
+ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÑÐŽÑÐœ âÐ¥Ð°Ð¹Ð»ÑÑÐœ Ò¯Ñ ÐŽÒ¯Ðœâ Ñ
+ÑÑÐŽÑÐ°ÐœÐŽ ÑÐ»ÐµÐºÑÑÐŸÐœ ÐœÐŸÐŒÑÐœ ÑÐ°Ðœ ÐŽÐ°Ñ
+Ñ
+Ð²ÑÐ±Ò¯Ò¯ÐŽÐžÐ¹Ðœ Ñ
+ÑÑÐ»Ð±Ð°Ñ Ñ
+ÑÑÐŽÐ°ÑÐœÑÑÐŽ ÑÑÑ Ð±ÐžÑ Ð¶ÐžÐœÑ
+ÑÐœÑ URL ÑÑÑ ÐœÑ ÑÐžÐ³Ð»Ò¯Ò¯Ð»ÑÑÐœ
+Ð»ÐžÐœÐº Ð³Ð°ÑÐ³Ð°Ñ
+ ÑÑÑÑ
+ÐžÐ¹Ð³ ÑÐŸÑ
+ÐžÑÑÑÐ»Ð¶ Ð±ÐŸÐ»ÐŽÐŸÐ³.}
+
+_texthelpsearchprefstitle_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ}
+_texthelpsearchprefs_ [l=mn] {<p>Ð¢Ð° ÐœÐ°ÑÐžÐ¹Ð²ÑÐžÐ»ÑÐ°Ðœ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ð²ÑÐ» & ("Ð±Ð°"), | (for "ÑÑÐ²ÑÐ»"), and ! ("Ò¯Ð³Ò¯Ð¹") Ð³ÑÑÑÐœ Ò¯Ð³ÐœÒ¯Ò¯ÐŽ Ð°ÑÐžÐ³Ð»Ð°Ð¶ ÐžÐ»Ò¯Ò¯ Ð»Ð°Ð² Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹.
+<p>Ð¥ÐŸÑÑ Ñ
+ÑÑÑÐ³ ÑÐŸÐ²ÑÐœÑÑÐŽÐ°Ð°Ñ ÑÐ°ÐœÑ Ñ
+Ð°Ð¹Ð»ÑÑÐœ ÑÐµÐºÑÑÐžÐ¹Ð³ Ñ
+ÑÐœÐ°ÐŽÐ°Ð³. ÐÑÐ³ÐŽÒ¯Ð³ÑÑÑÑ
+
+ÐœÑ (âÒ¯ÑÐ³ÐžÐ¹Ðœ ÑÐŸÐŒ, Ð¶ÐžÐ¶Ð³ÐžÐ¹Ðœ ÑÐ»Ð³Ð°Ð°â Ð³ÑÑÑÐœ) Ò¯ÑÐ³ÐžÐ¹Ðœ ÑÐŸÐŒ, Ð¶ÐžÐ¶ÐžÐ³ ÐœÑ ÑÐŸÑ
+ÐžÑÑ
+Ð±Ð°Ð¹Ð³Ð°Ð° ÑÑÑÑ
+ÐžÐ¹Ð³ ÑÐ°Ð»Ð³Ð°ÐŽÐ°Ð³. Ð¥ÐŸÑÑ ÐŽÐ°Ñ
+Ñ ÐœÑ (âÒ¯Ð³ÐžÐ¹Ðœ ÑÓ©Ð³ÑÐ³Ó©Ð»â Ð³ÑÑÑÐœ) Ò¯Ð³ÐžÐ¹Ðœ
+ÑÓ©Ð³ÑÐ³Ó©Ð» ÑÐŸÑ
+ÐžÑÑ Ð±Ð°Ð¹Ð³Ð°Ð° ÑÑÑÑ
+ÐžÐ¹Ð³ ÑÐ°Ð»Ð³Ð°ÐŽÐ°Ð³. Ð¢ÐŸÐŒ Ñ
+ÑÐŒÐ¶ÑÑÐœÐžÐ¹ Ñ
+Ð°Ð¹Ð»ÑÑÐœ
+ÑÐ°Ð»Ð±Ð°Ñ Ð³Ð°ÑÐ³Ð°Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹ ÑÑÐžÑ ÑÐ° Ð±Ò¯ÑÑÐœ ÐŽÐŸÐ³ÐŸÐ» ÐŒÓ©ÑÓ©Ó©Ñ ÐœÑ Ñ
+Ð°Ð¹Ð»ÑÑÐ³ ÑÐ²ÑÑÐ»Ð¶
+Ð±ÐŸÐ»ÐŸÑ
+ ÑÐŒ. Ð¢ÐžÐ¹ÐŒ ÑÐŸÐŒ Ñ
+ÑÐŒÐ¶ÑÑÐœÐžÐ¹ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð³ÑÑ
+ÑÐŽ ÑÑÐœ Ñ
+ÑÑÐŽÐ°Ðœ
+Ò¯Ñ ÐŽÒ¯Ðœ Ð³Ð°ÑÐœÐ°.
+
+<p>ÐÐžÑÑÑÐ»Ð±ÑÐ», Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ÐŽÑÑ <i>Ò¯ÑÐ³ÐžÐ¹Ðœ ÑÐŸÐŒ/ Ð¶ÐžÐ¶ÐžÐ³ Ñ
+Ð°ÐŒÐ°Ð°ÑÐ°Ñ
+Ð³Ò¯Ð¹</i> Ð±ÐŸÐ»ÐŸÐœ
+<i>Ò¯Ð³ÐžÐ¹Ðœ ÑÓ©Ð³ÑÐ³Ó©Ð» Ñ
+Ð°ÐŒÐ°Ð°ÑÐ°Ñ
+Ð³Ò¯Ð¹</i> Ð³ÑÐ¶ ÑÐŸÐœÐ³ÐŸÑÐŸÐœ Ð±Ð°Ð¹Ð²Ð°Ð», <p>
+    <ul><kbd>African building</kbd></ul>
+      <p>Ð³ÑÑÑÐœ Ñ
+Ð°Ð¹Ð»ÑÑÐ³ ÐŽÐ°ÑÐ°Ð°Ñ
+ ÐŒÐ°ÑÐ³Ð°Ð°Ñ Ð°Ð²Ñ Ð±ÐŸÐ»ÐœÐŸ:<p>
+      <ul><kbd>africa builds</kbd></ul><p>
+      "African" Ð³ÑÐŽÑÐ³ Ò¯Ð³ÐœÐžÐ¹ ÑÑ
+ÐœÐžÐ¹ ÑÐŸÐŒ Ò¯ÑÑÐ³ ÐœÑ Ð¶ÐžÐ¶ÐžÐ³ Ð±ÐŸÐ»ÐŸÐœ Ñ
+ÑÐ²ÐžÑÑ, "n" Ð±ÐŸÐ»ÐŸÐœ "ing"
+      ÑÓ©Ð³ÑÐ³Ó©Ð»Ò¯Ò¯ÐŽ ÐœÑ "African", "building" Ð·ÑÑÑÐ³ Ò¯Ð³ÐœÒ¯Ò¯ÐŽÑÑÑ  Ñ
+Ð°ÑÐ³Ð°Ð»Ð·Ð°Ðœ Ñ
+Ð°ÑÐ°Ð³ÐŽÐ°ÐœÐ°.
+      (ÐŒÓ©Ðœ "builds" Ð³ÑÐŽÑÐ³ Ò¯Ð³ÐœÑÑÑ "s" Ò¯ÑÑÐ³ Ñ
+Ð°ÑÐ°Ð³ÐŽÐ°ÐœÐ°).
+
+<p>Ð¢Ð° Ð±Ð°Ñ "ÐœÐ°ÑÐžÐ¹Ð²ÑÐžÐ»ÑÐ°Ðœ" Ñ
+Ð°Ð¹Ð»ÑÑÐœ Ð³ÐŸÑÐžÐŒÐŽ ÑÐžÐ»Ð¶ÐžÐ¶ AND (&), OR (|), NOT (!)
+Ð·ÑÑÑÐ³ ÐœÑÑ ÑÐŸÐŒÑÑÐŸÐœÑÑÐŽÑÐ³ Ð°ÑÐžÐ³Ð»Ð°Ðœ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ð¶ Ð±ÐŸÐ»ÐœÐŸ. ÐÐœÐ³ÑÑÐœÑÑÑ ÐžÐ»Ò¯Ò¯ ÑÐ°Ð¹Ðœ
+Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ Ð±Ò¯ÑÑÐ»ÐŽÑÐœÑ. ÐÑÑ
+ÐžÐ²Ñ Ñ
+Ð°Ð¹Ñ
+ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐ³ ÐžÐŽÑÐ²Ñ
+ÐžÐ¶Ò¯Ò¯Ð»Ð¶
+ÑÒ¯Ò¯Ð»ÐžÐ¹Ðœ Ñ
+ÑÐŽÑÐœ Ñ
+Ð°Ð¹Ð»ÑÑÐ³ Ñ
+Ð°ÑÐ¶ Ð±ÐŸÐ»ÐœÐŸ. Ð­ÐœÑ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐ³ Ð°ÑÐžÐ³Ð»Ð°ÑÐœÐ°Ð°Ñ Ó©ÐŒÐœÓ©Ñ
+
+Ñ
+Ð°Ð¹Ð»ÑÑÑÐŽÑÐ³ ÐžÐ»Ò¯Ò¯ ÑÐ°Ð¹Ð¶ÑÑÑÐ»Ð°Ðœ Ð³Ò¯Ð¹ÑÑÑÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹. Ð­ÑÑÐžÐ¹Ðœ ÐœÑÐ³ ÑÐŸÐœÐ³ÐŸÐ»Ñ ÐœÑ
+Ñ
+Ð°Ð¹Ð»ÑÑÐœ Ò¯Ñ ÐŽÒ¯Ðœ Ð±ÐŸÐ»ÐŸÐœ ÐŽÑÐ»Ð³ÑÑÐœÑÑ Ñ
+Ð°ÑÑÑÐ»Ð°Ñ
+ Ò¯Ñ ÐŽÒ¯ÐœÐ³ÐžÐ¹Ðœ ÑÐŸÐŸÐ³ Ñ
+ÑÐ·Ð³Ð°Ð°ÑÐ»Ð°Ñ
+
+Ð±ÐŸÐ»ÐŸÐŒÐ¶ ÑÐŒ.}  
+
+_textcasefoldprefs_ [l=mn] {Ð­ÐœÑ Ñ
+ÐŸÑ ÑÐŸÐ²Ñ ÐœÑ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ÑÐŽ ÑÐŸÐŒ, Ð¶ÐžÐ¶ÐžÐ³ Ò¯ÑÐ³Ò¯Ò¯ÐŽÐžÐ¹Ðœ ÑÐ»Ð³Ð°Ð°Ð³ ÑÐŸÑ
+ÐžÑÑÑÐ»ÐœÐ°. ÐÐžÑÑÑ ÐœÑ, "_preferences:textignorecase_" ÑÐŸÐœÐ³ÐŸÐ³ÐŽÑÐŸÐœ Ð±ÐŸÐ» <i>snail farming</i>, <i>Snail Farming</i> Ð±ÐŸÐ»ÐŸÐœ <i>SNAIL FARMING</i> Ð±Ò¯Ð³ÐŽ Ð°ÐŽÐžÐ»Ñ
+Ð°Ðœ Ð³ÑÐ¶ ÑÐŸÐŸÑÐŸÐ³ÐŽÐŸÐœ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹ÐœÑ.}  
+_textstemprefs_ [l=mn] {Ð­ÐœÑ Ñ
+ÐŸÑ ÑÐŸÐ²Ñ ÐœÑ Ñ
+Ð°Ð¹Ð»ÑÑÐœ ÑÐ²ÑÐ°ÐŽ Ò¯Ð³ÐžÐ¹Ðœ Ð·Ð°Ð»Ð³Ð°Ð²Ð°Ñ ÑÑÐ²ÑÐ» ÑÓ©Ð³ÑÐ³Ó©Ð» ÐŽÑÑÑ Ð·ÐŸÑ
+ÐžÑÑÑÐ»Ð°Ð»Ñ Ñ
+ÐžÐ¹ÐŽÑÐ³. ÐÐžÑÑÑ ÐœÑ, "_preferences:textstem_" ÑÐŸÐœÐ³ÐŸÐ³ÐŽÑÐŸÐœ Ð±ÐŸÐ» <i>snail farming</i>, <i>snails farm</i> Ð±ÐŸÐ»ÐŸÐœ <i>snail farmer</i> Ð±Ò¯Ð³ÐŽ Ð°ÐŽÐžÐ» Ð³ÑÐ¶ ÑÐŸÐŸÑÐŸÐ³ÐŽÐŸÐœÐŸ. Ð¥Ð°ÑÐ°ÐŒÑÐ°Ð»ÑÐ°Ð¹ ÐœÑ, ÑÐœÑ ÐœÑ Ð·Ó©Ð²Ñ
+Ó©Ðœ ÐÐœÐ³Ð»Ðž Ñ
+ÑÐ» ÐŽÑÑÑÑ
+ ÑÐµÐºÑÑÑÐœ ÐŽÑÑÑ Ð» Ð°Ð¶ÐžÐ»Ð»Ð°Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð°.}  
+_textaccentfoldprefs_ [l=mn] {ÑÐœÑ Ñ
+ÐŸÑ ÑÐŸÐ²Ñ ÐœÑ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ÑÐŽ Ó©ÑÐ³Ó©Ð»ÑÐžÐ¹Ðœ ÑÑÐŒÐŽÑÐ³ÑÒ¯Ò¯ÐŽÐžÐ¹Ðœ ÑÐ»Ð³Ð°Ð°Ð³ ÑÐŸÑ
+ÐžÑÑÑÐ»ÐœÐ°. ÐÐžÑÑÑ ÐœÑ,"_preferences:textignoreaccents_" ÑÐŸÐœÐ³ÐŸÐ³ÐŽÑÐŸÐœ Ò¯ÐµÐŽ <i>fÃ©dÃ©ration</i> ÐœÑ <i>fedÃ©ration</i> Ð±ÐŸÐ»ÐŸÐœ <i>federation</i>-Ñ Ð°Ð»Ñ Ð°Ð»ÐžÐœÑÐ°Ð¹ ÐœÑ Ð°ÐŽÐžÐ»Ñ
+Ð°Ðœ Ð³ÑÐ¶ ÑÐŸÐŸÑÐŸÐ³ÐŽÐŸÐœÐŸ.}  
+ 
+_textstemoptionsprefs_ [l=mn] {"_texthelpquerytermstitle_" ÐŽÑÑÑ ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹Ð»ÑÐŸÐœ Ñ
+Ð°Ð¹Ð»ÑÑÐœ Ò¯Ð³ÐžÐ¹Ð³ ÑÐŸÑ
+ÐžÑÑÑÐ»Ð°Ñ
+ Ñ
+ÑÑÑÐ³ÑÑÐ»ÐžÐ¹Ð³ Ð°ÑÐžÐ³Ð»Ð°Ñ
+ ÐœÑ ÐžÐ»Ò¯Ò¯ ÑÐŸÑ
+ÐžÑÐŸÐŒÐ¶ÑÐŸÐ¹.}  
+
+_textsearchtypeprefsplain_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ ÑÐŸÐœÑ
+ÑÐ³ ÑÐŸÐŒÐŸÐŸÑ ÑÐŸÐœÐ³ÐŸÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹ Ð±Ó©Ð³Ó©Ó©ÐŽ Ò¯Ò¯ÐœÐžÐ¹ Ò¯Ñ ÐŽÒ¯ÐœÐŽ Ð¿Ð°ÑÐ°Ð³ÑÐ°ÑÑÐœ Ñ
+ÑÐŒÐ¶ÑÑÐœÐžÐ¹ ÑÒ¯Ð»Ñ
+Ò¯Ò¯ÑÑÑÑ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹ Ð±ÐŸÐ»ÐœÐŸ. Ð­ÐœÑ ÐœÑ ÑÐŸÐŒ Ñ
+ÑÐŒÐ¶ÑÑÐœÐžÐ¹ ÑÐµÐºÑÑÐžÐ¹Ð³ Ñ
+Ð°Ð¹Ñ
+Ð°ÐŽ ÐžÑ
+ Ñ
+ÑÑÐŽÐ°Ðœ.}  
+
+_textsearchtypeprefsform_ [l=mn] {Ð¢Ð° Ñ
+Ð°Ð¹Ð»ÑÑÐœ ÑÐŸÑÐŒ ÐŽÐŸÑÐŸÑÑ
+Ðž ÑÐ°Ð»Ð±Ð°ÑÑÐœ ÑÐŸÐŸÐ³ Ó©Ó©ÑÑÐžÐ»Ð¶ Ð±ÐŸÐ»ÐœÐŸ.}  
+
+_textsearchtypeprefsboth_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ Ñ
+Ð°Ð¹Ð»ÑÑÐœ ÑÓ©ÑÐ»ÐžÐ¹Ð³ Ð±ÐžÐŽ "ÑÐœÐ³ÐžÐ¹Ðœ" Ð±ÐŸÐ»ÐŸÐœ "ÑÐ°Ð»Ð±Ð°ÑÑ" Ð³ÑÑÑÐœ ÑÓ©ÑÐ»Ó©Ó©Ñ ÑÐŸÐœÐ³ÐŸÐ¶ Ð±ÐŸÐ»ÐœÐŸ. <ul>
+<li>Ð­ÐœÐ³ÐžÐ¹Ðœ Ñ
+Ð°Ð¹Ð»Ñ ÐœÑ Ñ
+Ò¯ÑÑÐ»Ñ Ð°Ð²Ð°Ñ
+ Ð³Ð°ÐœÑ Ñ
+ÑÑÑÐ³ÑÑÐ¹. _textsearchtypeprefsplain_</li>
+<li>Ð¢Ð°Ð»Ð±Ð°ÑÑ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+Ò¯ÑÑÐ»Ñ Ñ
+Ò¯Ð»ÑÑÐœ Ð°Ð²Ð°Ñ
+ ÐŸÐ»ÐŸÐœ Ñ
+ÑÑÑÐ³ÑÑÐ¹ Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÐœÑ Ñ
+ÑÑÐ³Ò¯Ò¯ÐŽ ÑÑÑ Ð±Ò¯ÑÐŽÑÑ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÐžÐœÐŽÐµÐºÑÐžÐ¹Ðœ Ó©Ó©Ñ Ó©Ó©Ñ ÑÐ°Ð»Ð±Ð°ÑÑ ÐœÑÐ³ Ð·ÑÑÑÐ³ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹ÐŽÑÐ³. _textsearchtypeprefsform_ </li>
+</ul>}  
+
+
+
+_texttanumbrowseoptions_ [l=mn] {Ð­ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÐŽÐŸÑÐŸÑ _numbrowseoptions_ Ó©Ó©Ñ Ð°ÑÐ³Ð°Ð°Ñ Ð±Ð°ÑÐžÐŒÑ ÐŸÐ»ÐŸÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹:}
+
+_textsimplehelpheading_ [l=mn] {_collectionname_ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÐŽÐŸÑÐŸÑ Ð±Ð°ÑÐžÐŒÑÑÐ³ Ñ
+ÑÑÑ
+ÑÐœ ÐŸÐ»ÐŸÑ
+ Ð²Ñ}
+
+_texthelpscopetitle_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÑÐœ Ñ
+ÑÐŒÐ¶ÑÑ}
+_texthelpscope_ [l=mn] {<p>
+ÐÑ
+ÑÐœÑ
+ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽ Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ Ó©Ó©Ñ Ó©Ó©Ñ ÐžÐœÐŽÐµÐºÑ Ð°ÑÐžÐ³Ð»Ð°Ð¶ Ð±ÐŸÐ»ÐœÐŸ. ÐÐžÑÑÑ ÐœÑ, Ð·ÐŸÑ
+ÐžÐŸÐ³Ñ ÑÐŒ ÑÑ
+Ð³Ð°ÑÑÐ³ÐžÐ¹Ðœ ÐžÐœÐŽÐµÐºÑ Ð±Ð°Ð¹Ð¶ Ñ Ð±ÐŸÐ»ÐŸÑ
+ ÑÐŒ. Ð­ÑÐ²ÑÐ» Ð±Ò¯Ð»Ð³ÐžÐ¹Ðœ Ð±ÐŸÐ»ÐŸÐœ ÐŽÐŸÐ³ÐŸÐ» ÐŒÓ©ÑÐžÐ¹Ðœ ÐžÐœÐŽÐµÐºÑ Ð±Ð°Ð¹Ð¶ Ð±ÐŸÐ»ÐœÐŸ.
+ÐÑÓ©ÐœÑ
+ÐžÐ¹ÐŽÓ©Ó© ÑÐ°ÐœÑ ÑÐŒÐ°Ñ ÐžÐœÐŽÐµÐºÑÑÑÑ Ñ
+Ð°Ð¹Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð°Ð³Ð°Ð°Ñ Ò¯Ð» Ñ
+Ð°ÐŒÐ°Ð°ÑÐ°Ðœ Ð±Ò¯ÑÑÐœ ÑÐŸÑ
+ÐžÑÑÐŸÐœ Ñ
+Ð°Ð¹Ð»ÑÑÐœ Ò¯Ñ ÐŽÒ¯Ðœ Ð³Ð°ÑÑ ÐžÑÐŽÑÐ³.
+<p>Ð¥ÑÑÑÐ² Ð±Ð°ÑÐžÐŒÑ ÐœÑ ÐœÐŸÐŒ Ð±Ð°Ð¹Ð²Ð°Ð» Ð·ÐŸÑ
+ÐžÑ
+ Ð³Ð°Ð·ÑÐ°Ð° ÐœÑÑÐ³ÐŽÑÑ
+ Ð±ÐŸÐ»ÐœÐŸ.}
Index: /gsdl/stable/macros/mongolian2.dm
===================================================================
--- /gsdl/stable/macros/mongolian2.dm	(revision 20131)
+++ /gsdl/stable/macros/mongolian2.dm	(revision 20131)
@@ -0,0 +1,1979 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Mongolian Language text and icon macros 
+# -- this file contains text that is of less importance
+# -- to translate when creating a new interface language
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=mn] {ÐÐžÑÐžÐ³ Ð±Ð°ÑÐžÐŒÑÑÑÐŽ}
+_lastupdate_ [l=mn] {Ð¡Ò¯Ò¯Ð»ÐŽ ÑÐžÐœÑÑÐ»ÑÐ³ÐŽÑÑÐœ}
+_ago_ [l=mn] {Ó©ÐŽÑÐžÐ¹Ðœ Ó©ÐŒÐœÓ©.}
+_colnotbuilt_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ñ
+ÐžÐ¹Ð³ÐŽÑÑÐœÐ³Ò¯Ð¹.}
+
+### taken from here
+
+_textpoem_ [l=mn] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>ÑÐœÑ
+ ÑÐ°Ð¹Ð²Ð°Ðœ, Ð°ÐŒÐ°Ñ Ð°ÐŒÐ³Ð°Ð»Ð°Ðœ ÑÐ°ÐŒÐ°Ð¹Ð³ Ñ
+Ò¯ÑÑÑÐ»ÑÐ³, 
+<br>ÑÑÐ»ÑÑÐ¹ Ð·ÑÐœÑ ÑÑÐžÐœ ÐŽÑÐ»Ð°Ð°ÐœÐŽ ÑÐž Ð°ÐŒÑÐŽÑÐ°Ð³, 
+<br>ÑÑÑÑ ÑÓ©Ð³ÑÐ³Ó©Ð»Ð³Ò¯Ð¹ Ð³ÑÐŒÑÑÑ ÐŽÐ°Ð»Ð°Ð¹ÐŽ Ñ
+ÐžÐ¹Ñ
+ Ð°ÑÐ»Ð°Ð» ÑÐžÐœÑ Ó©Ó©Ð»Ð¶ Ð·Ð°ÑÑÐ°Ðœ ÑÑÐŽÑÐœÐžÐ¹Ðœ greenstone ÑÐžÐ³ ÑÐŸÐ»ÐžÐ³ÐŸÑ Ð±Ð°Ð¹Ð³.}
+
+_textgreenstone_ [l=mn] {<p>Greenstone Ð³ÑÐŽÑÐ³ ÐœÑ ÐšÐžÐœÑ ÐÐµÐ»Ð°ÐœÐŽÐ°ÐŽ Ð±Ð°Ð¹ÐŽÐ°Ð³ Ò¯ÐœÑÑ ÑÑÐ»ÑÑÐœÑ ÐœÑÑ ÑÐŒ.
+Ð¢ÑÐœÐŽÑ
+ÐžÐ¹Ðœ ÑÑÐ³ÑÑÐ» ÐÐ°ÐŸÑÐžÑÑÑÐŽÑÐœ Ñ
+ÑÐ²ÑÐŽ ÑÐœÑ ÑÑÐ»ÑÑ Ñ
+Ð°ÐŒÐ³ÐžÐ¹Ðœ Ò¯ÐœÑÑ ÑÑÐŽÑÐœÑ
+Ð±Ó©Ð³Ó©Ó©ÐŽ Ð±Ò¯Ñ
+ Ð±ÐŸÐŽÐžÑÐŸÐŸÑ ÐŽÑÑÑ Ò¯ÐœÑÐ»ÑÐ³ÐŽÐŽÑÐ³ Ð±Ð°Ð¹Ð¶ÑÑ. Ð£Ð³ ÑÑÐ»ÑÑ ÐœÑ Ð°ÐŒÑÐŽÑÐ°Ð»ÑÐœ
+Ñ
+Ò¯ÑÐœÐžÐ¹ ÑÒ¯ÐœÑ Ð±ÐŸÐ»ÑÐŸÐœ <i>Ð²Ð°Ð¹ÑÑÐ°</i> Ñ
+ÑÐŒÑÑÑ
+ Ð±ÐŸÐŽÐžÑÑÐ³ Ó©Ó©ÑÓ©Ó©ÑÓ©Ó© ÑÐ»Ð³Ð°ÑÑÑÐ»Ð°Ðœ,
+Ñ
+Ð°ÐŽÐ³Ð°Ð»Ð¶ Ð±Ð°Ð¹ÐŽÐ°Ð³ Ð³ÑÐ¶ Ò¯Ð·ÐŽÑÐ³ ÑÑÑÐ°Ð°Ñ ÑÐœÑÑ
+Ò¯Ò¯ ÐŸÐ»ÐŸÐœ ÐœÐžÐ¹ÑÐžÐ¹Ðœ ÑÐ»ÐµÐºÑÑÐŸÐœ ÐœÐŸÐŒÑÐœ
+ÑÐ°ÐœÐ³ÐžÐ¹Ðœ Ð±ÑÐ»ÑÐ³ ÑÑÐŒÐŽÑÐ³ Ð±ÐŸÐ»Ð³ÐŸÐœ Ñ
+ÑÑÑÐ³Ð»ÑÑÑÐœ Ð±ÐžÐ»ÑÑ. Ð¡Ð°Ð¹Ñ
+Ð°Ðœ Ñ
+ÑÐ»Ð±ÑÑ ÐœÑ
+Ó©Ð³Ó©Ó©ÐŒÓ©Ñ ÑÐ°ÐœÐ³, ÑÑÐœÐ³Ð°Ð»Ð°Ð³ Ð±Ð°Ð¹ÐŽÐ°Ð» ÐœÑ Ò¯ÐœÑÐœÑ Ð±Ð°Ð¹ÐŽÐ»ÑÐ³, Ð±Ó©Ñ
+ Ð±Ð°Ñ ÐœÑ ÑÑ Ð·ÐŸÑÐžÐ³ÐžÐ¹Ð³,
+Ñ
+ÑÑÑ Ó©ÐœÑÓ©Ð³ ÐœÑ ÑÑÐŽÐ°ÑÐ³Ð° ÑÑÑÐ³ Ð±ÑÐ»Ð³ÑÐŽÑÑÐœ. Greenstone ÐÐžÐ¶ÐžÑÐ°Ð» ÐÐŸÐŒÑÐœ
+Ð¡Ð°ÐœÐ³ÐžÐ¹Ðœ ÐÑÐŸÐ³ÑÐ°ÐŒÐŒÑÐœ ÐÐŸÐ³ÐŸÐœÐŽ ÐŸÑÑÐŸÐœ ÐŒÑÑÑÐ¹ Ñ
+ÑÑÑÐ³ ÐœÑ <i>patu</i> Ð±ÑÑÑ
+Ð·ÐŸÐŽÐŸÐŸÐœÑ Ð±ÐŸÑÐŸÐŸÑ
+ÐŸÐ¹ Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÓ©ÑÐ»ÐžÐ¹Ðœ ÐœÑÐ³ Ð³ÐžÑÒ¯Ò¯ÐœÐžÐ¹ ÐŒÐ°Ð°ÐœÑ Ð³ÑÑ Ð±Ò¯Ð»ÐžÐ¹Ðœ
+ÑÐ»Ð°ÐŒÐ¶Ð»Ð°Ð³ÐŽÐ°Ðœ ÐžÑÑÑÐœ Ó©Ð² ÑÐŒ. ÐÐ°ÑÐŽÐ°Ðœ ÑÑÐ»Ð°Ð°ÐœÑ Ò¯ÐµÐŽ ÑÐœÑ Ð±ÐŸÑÐŸÐŸÑ
+ÐŸÐ¹ÐœÑ
+ÑÐŸÑ
+ÐžÐ»Ñ ÐŒÐ°Ñ ÑÒ¯ÑÐ³ÑÐœ, ÐŸÐœÐŸÐ²ÑÑÐŸÐ¹ Ð±Ó©Ð³Ó©Ó©ÐŽ Ñ
+Ò¯ÑÑÑÐ¹ Ð±Ð°Ð¹ÐŽÐ°Ð³. Ð¯Ð³ Ð» ÑÐŽÐ³ÑÑÑ ÐœÑ
+Ð±ÐžÐŽÐœÐžÐ¹ Ð¿ÑÐŸÐ³ÑÐ°ÐŒ Ñ
+Ð°ÐœÐ³Ð°ÐŒÐ¶ÐžÐŽ Ð±Ð°Ð¹Ð²Ð°Ð» Ð·ÐŸÑ
+ÐžÑ
+ Ò¯Ð·Ò¯Ò¯Ð»ÑÐ»ÑÒ¯Ò¯ÐŽ Ð±Ð°Ð¹ÑÐ°Ðœ Ð±Ó©Ð³Ó©Ó©ÐŽ
+<i>Ð¿Ð°ÑÑ</i>ÐœÑ Ñ
+ÑÑÑ Ò¯Ð·Ò¯Ò¯Ñ ÐœÑ ÐŒÐ°ÐœÐ°Ð¹ ÐŽÑÐ²ÑÐžÐ»ÑÑÑ ÑÐµÑ
+ÐœÐŸÐ»ÐŸÐ³ÐžÐ¹Ð³ ÐžÐ»ÑÑÑ
+ÐžÐ¹Ð»Ð¶
+Ð±Ð°Ð¹Ð³Ð°Ð° ÑÐŒ.}
+
+_textaboutgreenstone_ [l=mn] {<p>Greenstone Ð±ÐŸÐ» ÐŽÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÐžÐ¹Ðœ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ñ
+ÐžÐ¹Ñ
+ ÑÒ¯Ò¯ÐœÐžÐ¹Ð³ ÑÒ¯Ð³ÑÑÑ
+ 
+Ð·ÐŸÑÐžÑÐ»Ð°Ð»Ñ Ð±Ò¯Ñ
+ÐžÐ¹ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ Ñ
+Ð°ÐœÐ³Ð°ÐŒÐ¶ ÑÐŒ. Ð­ÐœÑ ÐœÑ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ ÑÑÐ³ÑÐ»ÑÑ
+ ÑÒ¯Ò¯ÐœÐžÐ¹Ð³ 
+Internet ÑÑÐ²ÑÐ» CD-ROM Ð°ÑÐžÐ³Ð»Ð°Ðœ ÐœÐžÐ¹ÑÑÐŽ ÑÒ¯Ð³ÑÑÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÐžÐ¹Ð³ ÐŸÐ»Ð³ÐŸÐŽÐŸÐ³.  Greenstone ÐœÑ 
+<b>ÐšÐžÐœÑ ÐÐµÐ°Ð»Ð°ÐœÐŽÑÐœ ÐÐžÐ¶ÐžÑÐ°Ð» ÐÐŸÐŒÑÐœ Ð¡Ð°Ðœ</b>  ÑÓ©ÑÐ»Ó©Ó©Ñ <b>Waikato-Ð³ÑÐœ ÐÑ
+ Ð¡ÑÑÐ³ÑÑÐ»ÑÐŽ Ð±Ò¯ÑÑÑÐ³ÐŽÑÑÐœ</b>, Ð±Ð° <b>UNESCO</b> Ð±ÐŸÐ»ÐŸÐœ the <b>Human Info Ð¢ÐÐ</b>-ÑÐœ ÐŸÑÐŸÐ»ÑÐŸÐŸÑÐŸÐ¹Ð³ÐŸÐŸÑ ÐœÐžÐ¹ÑÐžÐ¹Ðœ Ñ
+Ò¯ÑÑÑÑÐ» Ð±ÐŸÐ»ÑÐŸÐœ.                                                                     Ð­ÐœÑ ÐœÑ ÐœÑÑÐ»ÑÑÑÐ¹ ÑÑ
+ Ð±Ò¯Ñ
+ÐžÐ¹ Ð¿ÑÐŸÐ³ÑÐ°ÐŒ Ð±Ð° ÐŽÐ°ÑÐ°Ð°Ñ
+ Ñ
+Ð°ÑÐ³ÐœÐ°Ð°Ñ GNU Ð±ÑÑÑ ÐÐžÐ¹ÑÐžÐ¹Ðœ ÐÑÓ©ÐœÑ
+ÐžÐ¹ ÐÐžÑÐµÐœÐ·ÐžÐ¹Ðœ ÐŽÐ°Ð³ÑÑ Ð°Ð²Ñ Ð±ÐŸÐ»ÐœÐŸ <a
+href="http://greenstone.org">http://greenstone.org</a>.
+
+<p>Ð­ÐœÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ ÐœÑ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐŽÐžÐ¹Ð³ ÑÐ»Ð°ÐœÐ³ÑÑÐ° ÐÑ
+, ÐÑÑÐŽ Ð¡ÑÑÐ³ÑÑÐ»ÐžÑÐŽ, 
+ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÑÑÐŽ Ð±ÐŸÐ»ÐŸÐœ Ð±ÑÑÐ°ÐŽ ÐœÐžÐ¹ÑÑÐŽ Ò¯Ð¹Ð»ÑÐžÐ»ÐŽÑÐ³ Ð±ÐŸÐ»ÐŸÐ²ÑÑÐŸÐ»ÑÐœ Ð±Ð°Ð¹Ð³ÑÑÐ»Ð»Ð°Ð³ÑÑÐŽÑÐ³ 
+ÑÐ°ÐŽÐ°Ð²Ñ
+ÐžÐ¶ÑÑÐ»Ð°Ñ
+, Ó©Ó©ÑÑÐŽÐžÐ¹Ðœ ÐŽÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ Ð±ÐžÐ¹ Ð±ÐŸÐ»Ð³ÐŸÑ
+ÐŸÐŽ ÐœÑ ÑÑÑÐ»Ð°Ð»ÑÐ°Ð°, ÐŽÑÐŒÐ¶Ð»ÑÐ³ Ð±ÐŸÐ»ÐŸÑ
+ Ð·ÐŸÑÐžÐ»Ð³ÐŸÐŸÑ Ð±Ò¯ÑÑÑÐ³ÐŽÑÑÐœ.                                                                  ÐÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÑÑÐŽ ÐœÑ ÐŽÑÐ»Ñ
+ÐžÐ¹Ðœ ÐŽÐ°Ñ
+ÐžÐœÑ Ñ
+ÑÐŒÐ¶ÑÑÐœÐŽ ÑÑÑ ÐŽÑÐœÐŽÐ°Ð° Ñ
+Ó©Ð³Ð¶ÐžÐ¶ Ð±ÑÐ¹ ÐŸÑÐœÑÑÐŽÐ°ÐŽ                                                                          UNESCO-Ð³ÐžÐ¹Ðœ Ò¯Ð¹Ð» Ð°Ð¶ÐžÐ»Ð»Ð°Ð³Ð°Ð°Ð³Ð°Ð° ÑÐ²ÑÑÐ»ÐŽÐ°Ð³ ÐŸÐ»ÐŸÐœ ÐœÐžÐ¹Ñ, Ñ
+Ð°ÐŒÑÑÐ°Ðœ Ð°Ð¶ÐžÐ»Ð»Ð°ÐŽÐ°Ð³ Ð±ÐŸÐ»ÐŸÐ²ÑÑÐŸÐ», ÑÐžÐœÐ¶Ð»ÑÑ
+ ÑÑ
+Ð°Ð°Ðœ,  
+ÑÐŸÑÐ»ÑÐœ Ð±Ð°Ð¹Ð³ÑÑÐ»Ð»Ð°Ð³ÑÑÐŽÐ°ÐŽ ÐŒÑÐŽÑÑÐ»ÑÐ» ÑÒ¯Ð³ÑÑÑ
+, ÐŒÑÐŽÑÑÐ»ÑÐ» ÐŸÐ»Ð¶ Ð°Ð²Ð°Ñ
+ ÑÐ°Ð» ÐŽÑÑÑ Ó©Ó©ÑÑÐ»Ó©Ð»Ñ ÑÐžÐœÑÑÐ»ÑÐ»Ñ Ñ
+ÐžÐ¹Ð¶ Ð±Ð°Ð¹ÐœÐ°. 
+Ð­ÐœÑÑ
+Ò¯Ò¯ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ ÐœÑ ÐŽÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÑÑÐŽÑÐ³ ÐŒÑÐŽÑÑÐ»ÑÐ» Ñ
+Ð°ÑÐžÐ»ÑÐ°Ðœ ÑÐŸÐ»ÐžÐ»ÑÐŸÑ
+ 
+ÐŸÐ»ÐŸÐœ ÐœÐžÐ¹ÑÑÐŽ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ Ñ
+Ò¯ÑÑÑÑÑ
+ Ð·ÑÑÑÐ³Ñ Ò¯Ñ ÐœÓ©Ð»Ó©Ó© Ð±Ò¯Ñ
+ÐžÐ¹ ÐŽÑÐŒÐ¶Ð»ÑÐ³ Ð±ÐŸÐ»ÐœÐŸ Ð³ÑÐŽÑÐ³Ñ Ð±ÐžÐŽ ÐžÑÐ³ÑÐ¶ Ð±Ð°Ð¹ÐœÐ°.
+
+<p>2000 ÐŸÐœÑ 8-Ñ ÑÐ°ÑÐŽ Ñ
+ÐŸÐ»Ð±ÐŸÐ³ÐŽÐŸÑ
+ Ð³ÑÑÐ²Ð°Ðœ ÑÐ°Ð»ÑÐœ Ñ
+Ð°ÐŒÑÑÐœ Ð°Ð¶ÐžÐ»Ð»Ð°Ð³Ð°Ð°ÐœÑ Ò¯Ñ ÐŽÒ¯ÐœÐŽ Ð±Ò¯ÑÑÑÐ³ÐŽÑÐ¶ ÐœÐžÐ¹ÑÐžÐ¹Ðœ Ñ
+Ò¯ÑÑÑÑÐ» Ð±ÐŸÐ»ÑÐŸÐœ.</p>
+
+<p>
+<a href="http://nzdl.org"><b>Waikato-ÑÐœ ÐžÑ
+ ÑÑÑÐ³ÑÑÐ»Ñ ÐŽÐ°Ñ
+Ñ ÐšÐžÐœÑ ÐÐµÐ°Ð»Ð°ÐœÐŽÑÐœ ÐÐžÐ¶ÐžÑÐ°Ð» ÐÐŸÐŒÑÐœ Ð¡Ð°ÐœÐ³ÐžÐ¹Ðœ Ð¢Ó©ÑÓ©Ð»</b></a>
+<br>
+Greenstone Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ ÐœÑ ÑÐœÑ ÑÓ©ÑÐ»Ó©Ó©Ñ Ð±Ò¯ÑÑÑÐ³ÐŽÑÑÐœ Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÐ»ÐŒÐ°Ð°Ñ ÐšÐžÐœÑ ÐÐµÐ°Ð»Ð°ÐœÐŽÑÐœ Ò®ÐœÐŽÑÑÐœÐžÐ¹ Ð¥ÐŸÑÐŸÐŸÐœÑ Ñ
+Ð°ÑÑÑÐ° Ð¥Ð°ÑÐžÐ»ÑÐ°Ð° Ð¥ÐŸÐ»Ð±ÐŸÐŸÐœÑ ÐÑÐŽ Ð¥ÐŸÑÐŸÐŸÐ³ÐŸÐŸÑ UNESCO-ÑÐœ Ñ
+Ó©ÑÓ©Ð»Ð±Ó©ÑÑ ÐšÐžÐœÑ ÐÐµÐ°Ð»Ð°ÐœÐŽÑÐœ ÑÐ°Ð»ÑÐœ ÐŸÑÑÑÐ»Ð¶ Ð±ÑÐ¹ Ñ
+ÑÐ²Ñ ÐœÑÐŒÑÑ Ð³ÑÐŽÑÐ³ ÑÑÐ³Ð°Ð°Ñ Ð±Ð°ÑÐ»Ð°Ð³ÐŽÑÐ°Ðœ Ð±ÐŸÐ»ÐœÐŸ.
+</p>
+<p>
+<a href="http://www.unesco.org"><b>ÐÒ®Ð-ÑÐœ ÐÐŸÐ»ÐŸÐ²ÑÑÐŸÐ», ÐšÐžÐœÐ¶Ð»ÑÑ
+ Ð£Ñ
+Ð°Ð°Ðœ, Ð¡ÐŸÑÐ»ÑÐœ ÐÐ°Ð¹Ð³ÑÑÐ»Ð»Ð°Ð³Ð°</b></a>
+<br>
+ÐÑÐ»Ñ
+ÐžÐ¹ ÐŽÐ°Ñ
+ÐžÐœÐŽ Ð±ÐŸÐ»ÐŸÐ²ÑÐŸÐ», ÑÐžÐœÐ¶Ð»ÑÑ
+ ÑÑ
+Ð°Ð°Ðœ Ð±ÐŸÐ»ÐŸÐœ ÑÐŸÑÐ»ÑÐœ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ ÑÒ¯Ð³ÑÑÐœ ÐŽÑÐ»Ð³ÑÑÒ¯Ò¯Ð»ÑÑ
+ÐžÐ¹Ðœ ÑÐ°ÑÑÑ ÑÐ»Ð°ÐœÐ³ÑÑÐ° ÑÒ¯Ò¯ÐœÐžÐ¹Ð³ Ñ
+Ó©Ð³Ð¶ÐžÐ¶ Ð±ÑÐ¹ ÑÐ»Ñ ÐŸÑÐœÑÑÐŽÐ°ÐŽ ÐžÐ»Ò¯Ò¯ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹ Ð±ÐŸÐ»Ð³ÐŸÑ
+ ÐœÑ 
+UNESCO-Ð³ÐžÐ¹Ðœ Ò¯ÐœÐŽÑÑÐœ Ð·ÐŸÑÐžÐ»Ð³ÑÐœ ÑÓ©Ð²ÐŽ Ð±Ð°Ð¹ÐŽÐ°Ð³ Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÐœÑ ÐœÑ Ð±Ò¯Ñ
+ÐžÐ¹ Ð» Ñ
+Ó©ÑÓ©Ð»Ð±Ó©ÑÒ¯Ò¯ÐŽÑÐœ Ð·Ð°ÑÐ³ÐžÐ¹Ðœ Ð³Ð°Ð·Ð°Ñ Ñ
+ÐŸÐŸÑÐŸÐœÐŽÑÐœ ÐŒÑÐŽÑÑÐ»ÑÐ»ÐŽ ÐŸÑÑÐœÐŸÐŸÑ ÑÑÑÐ³Ð°Ð»Ð°Ð° ÐŸÐ»ÐŽÐŸÐ³ Ð±Ð° Ò¯Ò¯ÐœÐžÐ¹ Ñ
+Ò¯ÑÑÑÐœÐŽ ÐŒÑÐŽÑÑÐ»ÑÐ» Ñ
+Ð°ÑÐžÐ»ÑÐ°Ð°ÐœÑ ÑÐžÐœÑÐ»ÑÐ³ ÑÐµÑ
+ÐœÐŸÐ»ÐŸÐ³Ðž ÐœÑ ÑÑÑ
+Ð°Ð» Ñ
+ÑÑÑÐ³ÑÑÐ» Ð±ÐŸÐ»ÐŸÑ
+ ÑÐŒ. 
+</p>
+
+<p>
+
+<a href="http://humaninfo.org"><img src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>The Human Info Ð¢ÐÐ, ÐÐµÐ»ÑÐ³Ðž ÑÐ»ÑÑÐœ ÐÐœÑÐ²ÑÑÑ Ñ
+ÐŸÑ</b></a>
+<br>
+Ð­ÐœÑ ÑÓ©ÑÓ©Ð» ÐœÑ ÐÒ®Ð-ÑÐœ Ð±Ð°Ð¹Ð³ÑÑÐ»Ð»Ð°Ð³ÑÑÐŽ Ð±ÐŸÐ»ÐŸÐœ Ð±ÑÑÐ°ÐŽ Ð¢Ó©ÑÐžÐ¹Ðœ ÐÑÑ ÐÐ°Ð¹Ð³ÑÑÐ»Ð»Ð°Ð³ÑÑÐŽÑÐ°Ð¹ Ñ
+Ð°ÐŒÑÑÐ°Ðœ Ð°Ð¶ÐžÐ»Ð»Ð°ÐŽÐ°Ð³ Ð±Ó©Ð³Ó©Ó©ÐŽ ÐŽÑÐ»Ñ
+ÐžÐ¹ ÐŽÐ°Ñ
+ÐžÐœÐŽ Ñ
+Ò¯ÐŒÒ¯Ò¯ÐœÐžÐ¹ Ñ
+Ó©Ð³Ð¶Ð»ÐžÐ¹Ðœ Ð°ÑÐžÐ³ ÑÐŸÐœÐžÑÑ
+ÐŸÐ»ÐŽ ÐœÐžÐ¹ÑÒ¯Ò¯Ð»ÑÐœ Ð±ÐžÑÐžÐ³ Ð±Ð°ÑÐžÐŒÑÑÐœ Ñ
+Ó©ÑÐ»Ó©Ð»ÑÐžÐ¹Ð³ ÐŽÐžÐ¶ÐžÑÐ°Ð» ÑÐµÑ
+ÐœÐŸÐ»ÐŸÐ³ÐžÐŽ Ð±ÑÑÐ»Ð³Ð°Ñ
+ ÐŒÓ©Ðœ Ò¯Ò¯ÐœÐžÐ¹Ð³ ÐŸÐ»ÐŸÐœ ÐœÐžÐ¹ÑÑÐŽ Ñ
+Ò¯ÑÑÑÑÐŒÐ¶ÑÑÐ¹ Ð±ÐŸÐ»Ð³ÐŸÑ
+, Ñ
+Ó©Ð³Ð¶ÐžÐ¶ Ð±ÑÐ¹ ÑÐ»Ñ Ò¯ÐœÐŽÑÑÑÐœÒ¯Ò¯ÐŽÑÐŽ Ò¯ÐœÑÐ³Ò¯Ð¹,                                                                                       Ñ
+Ð°ÑÐžÐœ Ð±ÑÑÐŽÐ°ÐŽ ÐœÑ Ð·Ð°ÑÐŽÐ»Ð°Ð° ÐœÓ©Ñ
+Ó©Ñ
+ Ð±ÐŸÐ»ÐŸÐ»ÑÐŸÐŸÑÐŸÐ¹Ð³ÐŸÐŸÑ ÑÐ°ÑÐ°Ð°Ñ
+. 
+</p>}  
+
+
+_textdescrselcol_ [l=mn] {ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ ÑÐŸÐœÐ³ÐŸÑ
+}
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=mn] {Ð­Ñ
+ Ñ
+ÑÑÐŽÑÐ°ÐœÐŽ ÐŽÐ°Ñ
+ÐžÐœ ÐŽÓ©ÑÐ²Ó©Ðœ ÑÐŸÐ²ÑÐ»ÑÑÑ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±ÐŸÐ»ÐœÐŸ}
+
+_textnocollections_ [l=mn] {<p>Greenstone-Ñ ÑÐœÑ ÐžÐœÑÑÐ°Ð»Ð»ÐŽ ÐŸÐŽÐŸÐŸÐ³ÐŸÐŸÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð±Ð°Ð¹Ñ
+Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°.  
+ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° ÐœÑÐŒÐ¶ ÐŸÑÑÑÐ»Ð°Ñ
+ÑÐ³ Ñ
+Ò¯ÑÐ²ÑÐ» 
+<ul><li>Use <a href="_httppagecollector_">ÐŠÑÐ³Ð»ÑÑÐ»Ð°Ð³Ñ</a> ÐšÐžÐœÑ ÑÑÐ³ÑÑÐ»Ð³Ð° Ñ
+ÐžÐ¹Ñ
+
+    <li>Ð¥ÑÑÐ²ÑÑ ÑÐ°ÐœÐŽ Greenstone cd-rom Ð±Ð°Ð¹Ð³Ð°Ð° Ð±ÐŸÐ» ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ cd-rom-ÐœÐŸÐŸÑ ÐžÐœÑÑÐ°Ð»Ð» Ñ
+ÐžÐ¹Ð¶ Ð±ÐŸÐ»ÐœÐŸ.
+</ul>}
+
+_text1coll_ [l=mn] {Greenstone-ÐžÐ¹ ÑÐœÑ ÐžÐœÑÑÐ°Ð»Ð»ÐŽ 1 ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð±Ð°Ð¹ÐœÐ°}
+
+_textmorecolls_ [l=mn] {Greenstone-ÐžÐ¹ ÐžÐœÑÑÐ°Ð»Ð» _1_ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð°Ð³ÑÑÐ»ÑÐ°Ðœ Ð±Ð°Ð¹ÐœÐ°}
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=mn] {ÐÐ°ÐŽÐ°Ð°ÐŽ Ñ
+ÐŸÐ»Ð±ÐŸÐŸÑ}
+_textlinknotfound_ [l=mn] {ÐÐŸÑÐŸÐŸÐŽ Ñ
+ÐŸÐ»Ð±ÐŸÐŸÑ ÐŸÐ»ÐŽÑÐŸÐœÐ³Ò¯Ð¹}  
+
+_textextlinkcontent_ [l=mn] {Ð¢Ð°ÐœÑ ÑÐŸÐœÐ³ÐŸÑÐŸÐœ Ñ
+ÐŸÐ»Ð±ÐŸÐŸÑ ÑÐ°ÐœÑ ÐŸÐŽÐŸÐŸ ÑÐŸÐœÐ³ÐŸÐŸÐŽ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±Ò¯Ñ
+ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÑÐŽÐ°Ð°Ñ Ð³Ð°ÐŽÐœÐ° Ð±Ð°Ð¹ÐœÐ°.
+Ñ
+ÑÑÑÐ² ÑÐ° ÐŸÐŽÐŸÐŸ Ñ Ð³ÑÑÑÐœ ÑÐœÑ Ñ
+ÐŸÐ»Ð±ÐŸÐŸÑÑÐ³ Ñ
+Ð°ÑÐ°Ñ
+ÑÐ³ Ñ
+Ò¯ÑÑÐ¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±ÐŸÐ»ÐŸÐœ ÑÐ°ÐœÑ Ð±ÑÐ°ÑÐ·ÐµÑ ÐÑÐ±ÐŽ 
+ÐœÑÐ²ÑÑÑÑ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±ÐŸÐ» , ÑÐ° <a href="_nexturl_">ÑÐ³ Ñ
+ÑÑÐŽÐ°Ñ</a> ÑÑÑ ÐŸÑÐœÐŸ ÑÑ; ÑÑÐ²ÑÐ» 
+Ð±ÑÐ°ÑÐ·ÐµÑ ÐŽÑÑÑÑ
+ "Ð±ÑÑÐ°Ñ
+" ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐ¶ Ó©ÐŒÐœÓ©Ñ
+ Ð±ÐžÑÐžÐ³ Ð±Ð°ÑÐžÐŒÑÑÐ³ Ñ
+Ð°ÑÐ¶ Ð±ÐŸÐ»ÐœÐŸ.}
+
+_textlinknotfoundcontent_ [l=mn] {Ð±ÐžÐŽÐœÐžÐ¹ Ñ
+ÑÐœÐ°Ð»ÑÐ°Ð°Ñ Ñ
+ÑÑÑÑÑÐœÐžÐ¹ ÑÐ»ÐŒÐ°Ð°Ñ, ÑÐ°ÐœÑ ÑÐŸÐœÐ³ÐŸÑÐŸÐœ ÐžÐœÑÐµÑÐœÑÑ Ñ
+ÐŸÐ»Ð±ÐŸÐŸÑ 
+Ð±Ð°Ð¹Ñ
+Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°. Ð­ÐœÑ ÐœÑ ÑÑ
+ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°Ðœ ÐŽÐ°Ñ
+Ñ Ð°Ð»ÐŽÐ°Ð°ÐœÐ°Ð°Ñ ÑÐ°Ð»ÑÐ³Ð°Ð°Ð»ÑÐ°Ðœ Ð±Ð°Ð¹Ð¶ Ð±ÐŸÐ»ÐœÐŸ.
+ÐÑÐ°ÑÐ·ÐµÑ ÐŽÐ°Ñ
+Ñ "Ð±ÑÑÐ°Ñ
+" ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐ¶ Ó©ÐŒÐœÓ©Ñ
+ Ð±ÐžÑÐžÐ³ Ð±Ð°ÑÐžÐŒÑÑÐ³ Ñ
+Ð°ÑÐœÐ° ÑÑ.}
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=mn] {<h3>"_2_" ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÑÑÑ Ñ
+ÐŸÐ»Ð±ÐŸÐ³ÐŽ</h3>
+
+<p> Ð¢Ð°ÐœÑ ÑÐŸÐœÐ³ÐŸÑÐŸÐœ Ñ
+ÐŸÐ»Ð±ÐŸÐŸÑ "_collectionname_" ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°Ð°Ñ
+Ð³Ð°ÐŽÐœÐ° Ð±Ð°Ð¹ÐœÐ°. (ÑÐœÑ ÐœÑ Ñ
+Ð°ÑÐžÐœ "_2_" ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽ Ñ
+ÐŸÐ»Ð±ÐŸÐ³ÐŽÐŸÐ¶ Ð±Ð°Ð¹ÐœÐ°.).
+Ñ
+ÑÑÑÐ² ÑÐ° "_2_" ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÐŽÐ°Ñ
+Ñ ÑÐœÑÑ
+Ò¯Ò¯ Ñ
+ÐŸÐ»Ð±ÐŸÐŸÑÑÐ³ Ñ
+Ð°ÑÐ°Ñ
+ÑÐ³ Ñ
+Ò¯ÑÐ²ÑÐ» ÑÐ° 
+<a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">ÑÐ³ Ñ
+ÑÑÐŽÐ°Ñ</a> ÑÑÑ ÐŸÑÐœÐŸ ÑÑ; 
+ÑÑÐ²ÑÐ» Ð±ÑÐ°ÑÐ·ÐµÑ ÐŽÑÑÑÑ
+  "Ð±ÑÑÐ°Ñ
+" ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐ¶ Ó©ÐŒÐœÓ©Ñ
+ Ð±ÐžÑÐžÐ³ Ð±Ð°ÑÐžÐŒÑÑÐ³ Ñ
+Ð°ÑÐ¶ Ð±ÐŸÐ»ÐœÐŸ.}
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=mn] {Greenstone ÐŽÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°Ðœ}
+
+_textusername_ [l=mn] {Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐœÑÑ}
+_textpassword_ [l=mn] {ÐœÑÑÑ Ò¯Ð³}
+
+_textmustbelongtogroup_ [l=mn] {Ð­ÐœÑ Ñ
+ÑÑÐŽÑÐ°ÐœÐŽ ÐœÑÐ²ÑÑÑÑ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ ÑÐ° "_cgiargug_" Ð±Ò¯Ð»Ð³ÐžÐ¹ÐœÑ
+ Ð±Ð°Ð¹Ñ
+ ÑÑÑÐŸÐ¹ Ð³ÑÐŽÐ³ÐžÐ¹Ð³ Ð°ÐœÑ
+Ð°Ð°ÑÐœÐ° ÑÑ.}
+
+_textmessageinvalid_ [l=mn] {Ð­ÐœÑ Ñ
+ÑÑÐŽÑÑÐ³ ÐœÑÑÑ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ ÑÐ° Ð±Ò¯ÑÑÐ³Ò¯Ò¯Ð»ÑÑ
+ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³Ð°ÑÐ°Ð¹.<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)  Greenstone
+ÐŽÑÑ
+ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐœÑÑ Ð±ÐŸÐ»ÐŸÐœ ÐœÑÑÑ Ò¯Ð³ÑÑ ÐŸÑÑÑÐ»ÐœÐ° ÑÑ.}
+
+_textmessagefailed_ [l=mn] {Ð¢Ð°ÐœÑ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐœÑÑ ÑÑÐ²ÑÐ» ÐœÑÑÑ Ò¯Ð³ Ð±ÑÑÑÑ Ð±Ð°Ð¹ÐœÐ°}
+
+_textmessagedisabled_ [l=mn] {Ð£ÑÑÐ»Ð°Ð°ÑÐ°Ð¹, ÑÐ°ÐœÑ Ñ
+Ð°ÑÐ³ Ñ
+Ò¯ÑÐžÐœÐ³Ò¯Ð¹ Ð±ÐŸÐ»ÑÐŸÐœ Ð±Ð°Ð¹ÐœÐ°. Ð­ÐœÑ ÑÐ°Ð¹ÑÑÐœ Ð²ÑÐ±ÐŒÐ°ÑÑÐµÑÑ Ñ
+Ð°ÐœÐŽÐ°ÐœÐ° ÑÑ.}
+
+_textmessagepermissiondenied_ [l=mn] {Ð£ÑÑÐ»Ð°Ð°ÑÐ°Ð¹, ÑÐ° ÑÐœÑ Ñ
+ÑÑÐŽÐ°ÑÑ ÐœÑÐ²ÑÑÑÑ
+ Ð·Ó©Ð²ÑÓ©Ó©ÑÓ©Ð» Ð°Ð²Ð°Ð°Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°.}
+
+_textmessagestalekey_ [l=mn] {Ð¢Ð°ÐœÑ Ñ
+ÑÑÑÐ³Ð»ÑÑÑÐœ Ð»ÐžÐœÐº Ñ
+Ð°ÐŒÐ³Ð°Ð°Ð»Ð°Ð³ÐŽÑÐ°Ðœ Ð±Ð°Ð¹ÐœÐ°.
+Ð­ÐœÑ Ñ
+ÑÑÐŽÑÐ°ÐœÐŽ ÐœÑÐ²ÑÑÑÑ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ ÐœÑÑÑ Ò¯Ð³ÑÑ ÐŸÑÑÑÐ»ÐœÐ° ÑÑ.}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=mn] {<p>Ð­ÐœÑÑ
+Ò¯Ò¯ Greenstone-Ðœ ÐžÐœÑÑÐ°Ð»Ð» ÐœÑ ÑÐŒÐ°Ñ ÐœÑÐ³ÑÐœ Ð±Ð°ÑÐžÐŒÑ Ð±ÐžÑÐžÐ³ Ð°Ð³ÑÑÐ»ÐŽÐ°Ð³Ð³Ò¯Ð¹.
+ÑÐ°Ð»ÑÐ³Ð°Ð°Ðœ ÐœÑ:
+<ol>
+ <li>Greenstone-Ð³ ÑÐ°Ñ
+ÑÐ°Ðœ ÐžÐœÑÑÐ°Ð»Ð» Ð°ÑÐžÐ³Ð»Ð°Ðœ CD-ROM-Ñ ÐžÐœÑÑÐ°Ð»Ð» Ñ
+ÐžÐ¹ÑÑÐœ.
+ <li>Greenstone ÐœÑ ÐžÐœÑÐµÑÐœÑÑÑÑÑ ÑÐ°ÑÐ°Ð¶ Ð°Ð²ÑÐ°Ðœ Ð³Ð°Ð·ÑÐ°Ð°Ñ ÐžÐœÑÑÐ°Ð»Ð»
+ Ñ
+ÐžÐ¹Ð³ÐŽÑÑÐœ.
+</ol>
+ÐÐ»Ñ Ñ ÑÐŸÑ
+ÐžÐŸÐ»ÐŽÐŸÐ»ÐŽ ÑÐ° <i>docs</i>Greenstone CD-ROM -ÑÐœ ÐŽÐžÑÐµÐºÑÐŸÑÐŸÐŸÑ
+ÑÐŒÑÑ <a href="http://www.greenstone.org">http://www.greenstone.org</a>.
+Ð²ÑÐ± Ñ
+ÑÑÐŽÐ°ÑÐœÐ°Ð°Ñ Ð±Ð°ÑÐžÐŒÑ Ð±ÐžÑÐ³ÐžÐ¹Ð³ Ð°Ð²Ñ Ð±ÐŸÐ»ÐœÐŸ.}
+
+_textuserguide_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ Ð³Ð°ÑÑÐœ Ð°Ð²Ð»Ð°Ð³Ð°}
+_textinstallerguide_ [l=mn] {ÐÐœÑÑÐ°Ð»Ð» Ñ
+ÐžÐ¹Ñ
+ Ð·Ð°Ð°Ð²Ð°ÑÑÐžÐ»Ð³Ð°Ð°}
+_textdeveloperguide_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ Ð³Ð°ÑÑÐœ Ð°Ð²Ð»Ð°Ð³Ð°}
+_textpaperguide_ [l=mn] {ÐŠÐ°Ð°ÑÐ°Ðœ Ð±ÐžÑÐžÐ³ Ð±Ð°ÑÐžÐŒÑÐœÐ°Ð°Ñ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÑÑÑ}
+_textorganizerguide_ [l=mn] {ÐÐŸÑ
+ÐžÐŸÐœ Ð±Ð°Ð¹Ð³ÑÑÐ»Ð°Ð³ÑÐžÐ¹Ð³ Ñ
+ÑÑÑÐ³Ð»ÑÑ
+ ÑÑÑ
+Ð°Ð¹}
+
+_textgsdocstitle_ [l=mn] {greenstone Ð±ÐžÑÐžÐ³ Ñ
+ÑÑÐ³ÐžÐ¹Ðœ Ñ
+Ó©ÑÐ»Ó©Ð»Ñ}
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÐ³ÑÑ
+}  
+_textbildsuc_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð°ÐŒÐ¶ÐžÐ»ÑÑÐ°Ð¹ Ò¯Ò¯ÑÐ»ÑÑ.}  
+_textviewbildsummary_ [l=mn] {Ð¢Ð° ÑÐœÑÑ
+Ò¯Ò¯ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ò¯Ò¯ÑÐ³ÑÑÑÐœ ÑÐ°Ð»Ð°Ð°ÑÑ
+ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³<a href="_httppagex_(bsummary)&c=_cgiargbc1dirname_" target=_top>Ò¯Ð·ÑÐ¶ Ð±ÐŸÐ»ÐœÐŸ</a>}  
+_textview_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ð·ÑÑ
+}  
+
+_textbild1_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÐ³ÑÐ¶ ÑÑ
+ÑÐ»Ð»ÑÑ: Ñ
+ÑÑÑÐ³ Ñ
+ÑÐ³Ð°ÑÐ°Ð° ÑÐ°Ð°ÑÐŽÐ°Ð³ÐŽÐ°ÐœÐ°. Ò®Ò¯ÑÐ³ÑÑ
+ ÑÐ²Ñ Ð°Ð»Ñ ÑÐ°ÑÐ°ÐœÐŽÐ°Ð° ÑÐ²Ð°Ð°Ð³ ÐŽÐŸÐŸÑÑ
+Ðž Ð·ÑÑÐ°Ð°ÑÐ°Ð°Ñ Ñ
+Ð°ÑÐœÐ° ÑÑ.}  
+
+_textbild2_ [l=mn] {Ò®Ò¯ÑÐ³ÑÑ
+ Ð°Ð¶ÐžÐ»Ð»Ð°Ð³Ð°Ð°Ð³ Ð·ÐŸÐ³ÑÐŸÐŸÑ Ð³ÑÐ²ÑÐ» ÑÐœÐŽ ÐŽÐ°ÑÐœÐ° ÑÑ.
+<br>ÐÐ¶ÐžÐ»Ð»Ð°Ð¶ Ð±ÑÐ¹ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÑÐ°ÐœÑ Ñ
+ÑÐ²ÑÑÑÑÑ Ð±Ð°Ð¹ÐœÐ°.}  
+
+_textstopbuild_ [l=mn] {Ò¯Ò¯ÑÐ³ÑÑ
+ Ð°Ð¶ÐžÐ»Ð»Ð°Ð³Ð°Ð°Ð³ Ð·ÐŸÐ³ÑÐŸÐŸÑ
+}  
+
+_textbild3_ [l=mn] {Ð¥ÑÑÑÐ² ÑÐ° ÑÐœÑÑ
+Ò¯Ò¯ Ñ
+ÑÑÐŽÑÑÐ³ ÐŸÑÑ
+ÐžÐœ Ð³Ð°ÑÐ²Ð°Ð» (ÐŒÓ©Ðœ "Ð·ÐŸÐ³ÑÐŸÐŸÑ
+" ÑÐŸÐ²ÑÐ»ÑÑÑÑÐ³ ÐŽÐ°ÑÐ°Ð°Ð³Ò¯Ð¹ Ð±ÐŸÐ») ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÐ³ÑÑ
+ Ð°Ð¶ÐžÐ»Ð»Ð°Ð³Ð°Ð° Ò¯ÑÐ³ÑÐ»Ð¶Ð»ÑÐœ ÑÐ²Ð°Ð³ÐŽÐ°Ñ
+ Ð±ÐŸÐ»ÐœÐŸ}  
+
+_textbuildcancelled_ [l=mn] {Ò®Ò¯ÑÐ³ÑÑ
+ Ð°Ð¶ÐžÐ»Ð»Ð°Ð³Ð°Ð° Ð·ÐŸÐ³ÑÐŸÐŸÐ³ÐŽÐ»ÐŸÐŸ}  
+
+_textbildcancel1_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÐ³ÑÑ
+ Ð°Ð¶ÐžÐ»Ð»Ð°Ð³Ð°Ð° Ð·ÐŸÐ³ÑÐŸÐŸÐ³Ð»ÐŸÐŸ. ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽÐ°Ð° Ð·Ð°ÑÐ²Ð°Ñ Ñ
+ÐžÐ¹Ñ
+ Ð±ÐŸÐ» ÑÐ°Ñ ÑÐŸÐ²ÑÐ»ÑÑÑÑÑÐŽÑÐ³ ÐŽÐ°ÑÐœÐ° ÑÑ ÑÑÐ²ÑÐ» Ò¯Ò¯ÑÐ³ÑÑ
+ Ð°Ð¶ÐžÐ»Ð»Ð°Ð³Ð°Ð°Ð³Ð°Ð° ÐŽÐ°Ñ
+ÐžÐœ ÑÑ
+Ð»Ò¯Ò¯Ð»ÐœÑ Ò¯Ò¯.}  
+
+_textbsupdate1_ [l=mn] {Ò®Ò¯ÑÐ³ÑÑ
+ Ð±Ð°Ð¹ÐŽÐ°Ð» 1 ÑÐµÐºÑÐœÐŽÑÐŽ ÑÐžÐœÑÑÐ»ÑÐ³ÐŽÑÐœÑ}  
+_textbsupdate2_ [l=mn] {ÑÐžÐœÑÑÐ»ÑÐ³ÐŽÑÑ
+ Ð±Ð°Ð¹ÐŽÐ°Ð»}  
+_textseconds_ [l=mn] {ÑÐµÐºÑÐœÐŽ}  
+
+_textfailmsg11_ [l=mn] {ÓšÐ³Ó©Ð³ÐŽÓ©Ð» Ð±Ð°Ð¹Ñ
+Ð³Ò¯Ð¹ ÑÑÑÐ°Ð°Ñ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÑ ÑÐ°ÐŽÐ°Ñ
+Ð³Ò¯Ð¹.}  
+
+_textfailmsg21_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÐ³ÑÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ° (import.pl Ð°Ð¶ÐžÐ»ÑÐ°ÐœÐ³Ò¯Ð¹)}  
+_textfailmsg31_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÐ³ÑÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ° (buildcol.pl Ð°Ð¶ÐžÐ»ÑÐ°ÐœÐ³Ò¯Ð¹).}  
+_textfailmsg41_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð°ÐŒÐ¶ÐžÐ»ÑÑÐ°Ð¹ Ò¯Ò¯ÑÑÑÐœ Ð±ÐŸÐ»ÐŸÐ²Ñ ÐžÐœÑÑÐŸÐ» Ñ
+ÐžÐ¹Ð¶ Ð±ÐŸÐ»ÐŸÑ
+Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°.}  
+_textfailmsg71_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÐ³ÑÑ
+ ÑÐ²ÑÐ°Ñ
+ Ò¯Ð» ÐŒÑÐŽÑÐ³ÐŽÑÑ
+ Ð°Ð»ÐŽÐ°Ð° Ð³Ð°ÑÐ»Ð°Ð°}  
+
+
+_textblcont_ [l=mn] {Ò®Ò¯ÑÐ³ÑÑÑÐœ Ð»ÐŸÐ³ ÑÐ°Ð¹Ð» ÐŽÐ°ÑÐ°Ð°Ñ
+ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ Ð°Ð³ÑÑÐ»Ð¶ Ð±Ð°Ð¹ÐœÐ°:}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=mn] {ÑÑÐ°ÐœÐŽÐ°ÑÑ Ð±Ò¯ÑÑÑ}
+_textmore_ [l=mn] {ÐžÐ»Ò¯Ò¯}
+_textinfo_ [l=mn] {ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÑÑÑ
+Ð°Ð¹ ÐŒÑÐŽÑÑÐ»ÑÐ»}
+_textsrce_ [l=mn] {ÑÑ
+ Ó©Ð³Ó©Ð³ÐŽÓ©Ð»}
+_textconf_ [l=mn] {ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ ÑÐŸÑ
+ÐžÑÑÑÐ»Ð°Ñ
+}
+_textdel_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° ÑÑÑÐ³Ð°Ñ
+}  
+_textexpt_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ð±ÑÐ»ÑÐœ Ð±ÐŸÐ»Ð³ÐŸÐ¶ Ð³Ð°ÑÐ³Ð°Ñ
+}
+
+_textdownloadingfiles_ [l=mn] {Ð€Ð°Ð¹Ð»ÑÑÐŽÑÐ³ ÑÐ°ÑÐ°Ð¶ Ð±Ð°Ð¹ÐœÐ°}
+_textimportingcollection_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ ÐŸÑÑÑÐ»Ð¶ Ð±Ð°Ð¹ÐœÐ°}
+_textbuildingcollection_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ò¯Ò¯ÑÐ³ÑÐ¶ Ð±Ð°Ð¹ÐœÐ° ...}
+_textcreatingcollection_ [l=mn] {ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ò¯Ò¯ÑÐ³ÑÐ¶ Ð±Ð°Ð¹ÐœÐ° ...}
+
+_textcollectorblurb_ [l=mn] {<i>Ò®Ð·ÑÐ³ ÑÑÐ»ÑÐŒÐœÑÑÑ Ñ ÐžÐ»Ò¯Ò¯ Ñ
+Ò¯ÑÑÑÐ¹!
+<br>Ð¢Ð° ÑÑ
+Ð»ÑÑ
+ÑÑÑÑÑ Ó©ÐŒÐœÓ© ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ðœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ñ
+ÐžÐ¹Ñ
+ Ð±ÐŸÐ»ÐŸÐœ ÑÒ¯Ð³ÑÑÑ
+ Ò¯Ò¯ÑÑÐ³
+Ñ
+Ð°ÑÐžÑÑÐ»Ð°Ð³ÑÐ³ Ó©Ó©ÑÑÓ©Ó© Ñ
+Ò¯Ð»ÑÑÑ
+ÐžÐ¹Ð³ Ñ
+Ò¯ÑÑÐ¶ Ð±ÐŸÐ»ÐŸÑ
+ ÑÐŒ. ÐÐŸÑ
+ÐžÐŸÐ³ÑÐžÐ¹Ðœ ÑÑÑ
+ÑÑÑ
+Ñ
+Ð°ÐŒÐ³Ð°Ð°Ð»Ð°Ð³ÐŽÑÐ°Ðœ Ñ
+ÑÑÐ»Ñ Ð·Ò¯Ð¹Ðœ Ð°ÑÑÑÐŽÐ»ÑÑÐŽ Ð±Ð°Ð¹ÐœÐ°: Ð±ÐžÑÐžÐ³ Ð±Ð°ÑÐžÐŒÑÐ°ÐœÐŽ ÐœÑÐ²ÑÑÑÑ
+Ò¯Ð·ÑÐ¶ ÑÐ°ÐŽÐ°Ð¶ Ð±Ð°Ð¹ÐœÐ° Ð³ÑÐŽÑÐ³ ÐœÑ ÑÑÐŽÐ³ÑÑÑÐžÐ¹Ð³ Ð±ÑÑÐŽÐ°ÐŽ ÐŽÐ°ÐŒÐ¶ÑÑÐ»Ð¶ Ð±ÐŸÐ»ÐœÐŸ Ð³ÑÑÑÐœ
+Ò¯Ð³ Ð±ÐžÑ ÑÐŒ. ÐÐžÐ¹Ð³ÐŒÐžÐ¹Ðœ Ð°ÑÑÑÐŽÐ»ÑÑÐŽ Ñ Ð±Ð°Ð¹ÐœÐ°:  ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÐœÑ ÑÑÑ
+Ð°Ð¹Ðœ Ð±ÐžÑÐžÐ³
+Ð±Ð°ÑÐžÐŒÑÑÐœ Ò¯ÐœÐŽÑÑ Ð±ÐŸÐ»ÑÐŸÐœ ÐœÐžÐ¹Ð³ÐŒÐžÐ¹Ðœ ÑÑ Ð·Ð°ÐœÑÐžÐ», ÑÐ»Ð°ÐŒÐ¶Ð»Ð°Ð»ÑÐ³ Ñ
+Ò¯ÐœÐŽÑÑÐ³ÑÑÑÐœ
+Ð±Ð°Ð¹Ñ
+ Ñ
+ÑÑÑÐ³ÑÑÐ¹. ÐÓ©Ðœ ÑÑ ÑÑÑÑÐ°Ñ
+ÑÑÐœÑ Ð°ÑÑÑÐŽÐ»ÑÑÐŽ Ñ Ð±Ð°Ð¹ÐœÐ°: Ð·Ð°ÑÐžÐŒ Ð·Ò¯Ð¹Ð»ÑÑÐŽ
+Ñ
+Ò¯Ðœ Ð±Ò¯Ñ
+ÑÐœ ÐœÑÐ²ÑÑÑÑ
+ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³Ð°Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐŽÐ°Ð³.
+<br>ÐÑÐŽÑÑÐ»Ð»ÐžÐ¹Ðœ Ñ
+Ò¯ÑÐžÐœ ÑÐ°ÐŽÐ»ÑÐ³ ÐŒÑÐŽÑÑÑ ÑÒ¯Ò¯ÐœÐžÐ¹Ð³ ÑÑ
+Ð°Ð°Ð»Ð°Ð³ Ñ
+ÑÑÑÐ³Ð»Ñ.
+</i>}
+
+_textcb1_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð°Ð³Ñ ÐœÑ ÑÐžÐœÑÑÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ñ
+ÐžÐ¹Ñ
+, ÐŸÐŽÐŸÐŸ Ð±Ð°Ð¹Ð³Ð°Ð° ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³
+Ó©Ó©ÑÑÐ»Ó©Ñ
+ Ð±ÑÑÑ ÐœÑÐŒÑÐ»Ñ ÐŸÑÑÑÐ»Ð°Ñ
+ Ð±ÐŸÐ»ÐŸÐœ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ ÑÑÑÐ³Ð°Ñ
+Ð°ÐŽ ÑÐ°ÐœÐŽ
+ÑÑÑÐ°Ð»ÐœÐ°. Ð­ÐŽÐ³ÑÑÑ Ò¯Ð¹Ð»ÐŽÐ»Ò¯Ò¯ÐŽÐžÐ¹Ð³ Ñ
+ÐžÐ¹Ñ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ ÑÐ° ÑÑÐ²ÑÐ°Ð» Ð²ÑÐ± Ñ
+ÑÑÐŽÑÑÑÐŽÑÐœ
+Ð·Ð°Ð°Ð²ÑÑÐ³ ÐŽÐ°Ð³Ð°Ðœ ÑÐ²Ð°Ñ
+ Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³Ð°ÑÐ°Ð¹ ÐŒÑÐŽÑÑÐ»Ð»Ò¯Ò¯ÐŽÐžÐ¹Ð³ ÑÐ°ÐœÐ°Ð°Ñ Ð°ÑÑÑÐœÐ°.}
+
+_textcb2_ [l=mn] {Ð­Ñ
+Ð»ÑÑÐŽ, ÑÐŒÐ°Ñ Ò¯Ð¹Ð»ÐŽÑÐ» Ñ
+ÐžÐ¹Ñ
+ÑÑ ÑÐžÐ¹ÐŽÐœÑ Ò¯Ò¯}
+_textcnc_ [l=mn] {ÑÐžÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð±Ò¯ÑÐŽÒ¯Ò¯Ð»ÑÑ
+}
+_textwec_ [l=mn] {ÐŸÐŽÐŸÐŸ Ð°Ð¶ÐžÐ»Ð»Ð°Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ñ
+ÑÑÑÐ³ÑÑÑ ÐŒÑÐŽÑÑÐ»ÑÐ» ÐœÑÐŒÐ¶ ÐŸÑÑÑÐ»Ð°Ñ
+ Ð±ÑÑÑ ÑÑÑÐ³Ð°Ñ
+}
+
+_textcb3_ [l=mn] {Ð­Ð»ÐµÐºÑÑÐŸÐœ ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÐžÐ¹Ðœ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ñ
+ÐžÐ¹Ñ
+ Ð±ÑÑÑ Ó©Ó©ÑÑÐ»Ó©Ñ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ ÑÐ°
+Ð±Ò¯ÑÑÐ³Ò¯Ò¯Ð»ÑÑ
+ ÑÑÑÐŸÐ¹. ÐÐœÐ³ÑÑÐœÑÑÑ Ð±ÑÑÐ°ÐŽ Ñ
+Ò¯ÐŒÒ¯Ò¯Ñ ÑÐ°ÐœÑ ÐºÐŸÐŒÐ¿ÑÑÑÐµÑÑ  ÐŸÑÐŸÑ
+
+Ð±ÐŸÐ»ÐŸÐŸÐŽ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ Ó©Ó©ÑÑÐ»Ó©Ñ
+Ó©Ó©Ñ Ñ
+Ð°ÐŒÐ³Ð°Ð°Ð»ÐœÐ°. ÐÐœÑ
+Ð°Ð°ÑÑÑÐ»Ð³Ð°: Ð°ÑÑÐ»Ð³Ò¯Ð¹
+Ð±Ð°Ð¹ÐŽÐ»ÑÐœ Ò¯Ò¯ÐŽÐœÑÑÑ ÐŸÑÑÐœÐŸÐŸÑ Ñ
+ÐŸÐ¹Ñ 30 ÐŒÐžÐœÑÑÑÐœ ÐŽÐ°ÑÐ°Ð° ÐœÑÐ³ ÑÐŽÐ°Ð° ÑÐ° Ð°Ð²ÑÐŸÐŒÐ°ÑÐ°Ð°Ñ
+Ð³Ð°ÑÐ°Ñ
+ Ð±ÐŸÐ»ÐœÐŸ. ÐÐœÐ³ÑÑÑÐœ ÑÐŸÑ
+ÐžÐŸÐ»ÐŽÐŸÐ»ÐŽ ÑÐ° ÑÐ°ÐœÐ°Ð° Ð·ÐŸÐ²ÐŸÑ
+ Ñ
+ÑÑÑÐ³Ð³Ò¯Ð¹!- ÑÐ° ÐŽÐ°Ñ
+ÐžÐœ ÐŸÑÐ¶
+Ð³Ð°ÑÑÐ°Ðœ Ñ
+ÑÑÐ³ÑÑÑÑÑ Ò¯ÑÐ³ÑÐ»Ð¶Ð»Ò¯Ò¯Ð»Ð¶ Ð±ÐŸÐ»ÐœÐŸ.}
+
+_textcb4_ [l=mn] {Greenstone-Ñ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐœÑÑ, ÐœÑÑÑ Ò¯Ð³ÑÑ ÐŸÑÑÑÐ»Ð°Ð°ÐŽ ÐŸÑÐŸÑ
+ Ð³ÑÑÑÐœ ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐœÐ° ÑÑ.}
+
+_textfsc_ [l=mn] {Ð­Ñ
+Ð»ÑÑÐŽ Ð°Ð¶ÐžÐ»Ð»Ð°Ñ
+ Ð³ÑÐ¶ Ð±Ð°Ð¹Ð³Ð°Ð° ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°Ð° ÑÐŸÐœÐ³ÐŸÐœÐŸ ÑÑ (Ð±ÐžÑÐ»ÑÐ³ÑÑÑ Ñ
+Ð°ÐŒÐ³Ð°Ð°Ð»Ð°Ð³ÐŽÑÐ°Ðœ
+ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÑÐŽ ÑÐœÑ Ð¶Ð°Ð³ÑÐ°Ð°Ð»ÑÐ°ÐŽ Ð³Ð°ÑÑ ÐžÑÑÑ
+Ð³Ò¯Ð¹).}
+
+_textwtc_ [l=mn] {Ð¡ÐŸÐœÐ³ÐŸÑÐŸÐœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°Ð°ÑÐ°Ð° ÑÐ°}
+_textamd_ [l=mn] {ÓšÐ³Ó©Ð³ÐŽÓ©Ð» ÐœÑÐŒÐ¶ ÐŸÑÑÑÐ»Ð°Ñ
+ Ð±ÐŸÐ»ÐŸÐœ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ ÐŽÐ°Ñ
+ÐžÐœ Ñ
+ÐžÐ¹Ñ
+}
+_textetc_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÑÐŸÑ
+ÐžÑÑÑÐ»Ð³ÑÐœ ÑÐ°Ð¹Ð»ÑÐ³ Ó©Ó©ÑÑÐ»Ó©Ñ
+, ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ ÐŽÐ°Ñ
+ÐžÐœ Ñ
+ÐžÐ¹Ñ
+}
+_textdtc_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ð±Ò¯Ñ
+ÑÐ»ÐŽ ÐœÑ Ð°ÑÐžÐ»Ð³Ð°Ñ
+}
+_textetcfcd_ [l=mn] {CD-ROM-ÐœÐŸÐŸÑ Windows-ÑÐœ ÐŸÑÑÐžÐœÐŽ Ó©Ó©ÑÐžÐ¹Ð³Ó©Ó© ÐžÐœÑÑÐ°Ð»Ð» Ñ
+ÐžÐ¹Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹Ð³ÐŸÐŸÑ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ ÑÐºÑÐ¿ÐŸÑÑÐ»ÐŸÑ
+}
+_textcaec_ [l=mn] {ÐÐŽÐŸÐŸ Ð±Ð°Ð¹Ð³Ð°Ð° ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ó©Ó©ÑÑÐ»Ó©Ð¶ Ð±Ð°Ð¹ÐœÐ°}
+_textnwec_ [l=mn] {ÐÐ°ÑÐ²Ð°Ñ Ñ
+ÐžÐ¹Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð±Ð°Ð¹Ñ
+Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°.}
+_textcianc_ [l=mn] {ÐšÐžÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÐ³ÑÑ
+}
+_texttsosn_ [l=mn] {ÐšÐžÐœÑ ÐŽÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÐžÐ¹Ðœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð±Ò¯ÑÐŽÒ¯Ò¯Ð»ÑÑ
+ÑÐŽ Ñ
+ÑÑÑÐ³ÑÑÐ¹ Ð°Ð»Ñ
+Ð°ÐŒÑÑÐŽÑÐœ ÐŽÐ°ÑÐ°Ð°Ð»Ð°Ð» ÐœÑ:}
+_textsin_ [l=mn] {ÐÑÑÐžÐ¹Ð³ ÐœÑ ÐŸÑÑÑÐ»ÐœÐ° ÑÑ (ÐŒÓ©Ðœ Ñ
+ÐŸÐ»Ð±ÐŸÐ³ÐŽÐŸÑ
+ ÐŒÑÐŽÑÑÐ»ÑÐ»)}
+_textswts_ [l=mn] {Ð­Ñ
+ ÐŒÑÐŽÑÑÐ»ÑÐ» Ñ
+Ð°Ð°ÐœÐ°Ð°Ñ ÐžÑÑÐœÐžÐ¹Ð³ ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹Ð»ÐœÐŸ ÑÑ}
+_textatco_ [l=mn] {ÓšÓ©ÑÑÐ»Ó©Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ ÑÐŸÐœÐ³ÐŸÐ»ÑÑÑÐŽÑÐ³ ÑÐŸÑ
+ÐžÑÑÑÐ»Ð°Ñ
+ (Ð·Ó©Ð²Ñ
+Ó©Ðœ ÑÑÑ
+ Ð±Ò¯Ñ
+ÐžÐ¹ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐŽÑÐŽ)}
+_textbtc_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÐ³ÑÐœÑ Ò¯Ò¯ (ÐŽÐŸÐŸÑÐŸÐŸÑ Ñ
+Ð°ÑÐœÐ° ÑÑ)}
+_textpvyh_ [l=mn] {ÓšÓ©ÑÐžÐ¹Ðœ Ð±Ò¯ÑÑÑÐ»ÐžÐ¹Ð³ Ñ
+Ð°ÑÐ°Ñ
+}
+
+_texttfsiw_ [l=mn] {ÐÓ©ÑÓ©Ð² ÐŽÑÑ
+ ÑÐ°ÑÐ°ÐœÐŽ ÐºÐŸÐŒÐ¿ÑÑÑÐµÑ Ð±Ò¯Ñ
+ Ò¯Ð¹Ð»ÐŽÐ»ÐžÐ¹Ð³ Ð³Ò¯Ð¹ÑÑÑÐ³ÑÐœÑ. ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ "Ñ
+ÐžÐ¹Ñ
+" 
+ÑÐ²ÑÐ°ÐŽ ÐºÐŸÐŒÐ¿ÑÑÑÐµÑ Ð±Ò¯Ñ
+ÐžÐ¹ Ð» ÐžÐœÐŽÐµÐºÑÐžÐ¹Ð³ Ð±ÐžÑÐžÐ¶ Ð±ÑÑÐ°ÐŽ Ñ
+ÑÑÑÐ³ÑÑÑÑ ÐŒÑÐŽÑÑÐ»ÑÐ»ÑÑÐ¹ Ñ
+Ð°ÐŒÑ ÑÑÐ³Ð»ÑÑÐ»ÐŽÐ°Ð³. 
+ÐÑÑ
+ÐŽÑÑ ÑÐ° ÑÑ
+ÑÐœÐŽ ÐœÑ ÐŒÑÐŽÑÑÐ»Ð»ÑÑ ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹ ÐŸÑÑÑÐ»Ð°Ñ
+ Ñ
+ÑÑÑÐ³ÑÑÐ¹.}
+
+_textadab_ [l=mn] {ÐÐŸÐŸÑÑ
+Ðž ÐŽÐžÐ°Ð³ÑÐ°ÐŒÑÑÐŽ ÐœÑ Ñ
+Ð°Ð°ÐœÐ° Ð±Ð°Ð¹Ð³Ð°Ð°Ð³Ð°Ð° ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹ ÐŒÑÐŽÑÑ
+ÑÐŽ ÑÐ°ÐœÑ ÑÑÑÐ°Ð»ÐœÐ°. ÐÐŸÐ³ÐŸÐŸÐœ ÑÐŸÐ²Ñ ÐœÑ ÑÐ°ÐœÑÐ³ Ð·Ó©Ð² ÐŽÐ°ÑÐ°Ð°Ð»Ð»Ð°Ð°Ñ Ò¯ÑÐ³ÑÐ»Ð¶Ð»Ò¯Ò¯Ð»ÑÑ
+ÑÐŽ Ð·ÐŸÑÐžÑÐ»Ð°Ð³ÐŽÑÐ°Ðœ. Ð¢Ð° ÐŽÐ°ÑÐ°Ð°Ð»Ð»ÑÐœ ÐŽÐ°Ð³ÑÑ ÑÐ²Ð°Ñ
+Ð°ÐŽ ÑÐŸÐ²ÑÐœÑ Ó©ÐœÐ³Ó© ÑÐ°Ñ Ð±ÐŸÐ»Ð¶ Ó©Ó©ÑÑÐ»Ó©Ð³ÐŽÓ©ÐœÓ©. Ð¢Ð° ÐŽÐžÐ°Ð³ÑÐ°ÐŒ ÐŽÐ°Ñ
+Ñ ÑÑÑ
+Ð°Ð¹Ðœ ÑÐ°Ñ ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐ¶ Ó©ÐŒÐœÓ©Ñ
+ Ñ
+ÑÑÐŽÐ°Ñ ÑÑÑÐ³Ð°Ð° ÐŸÑÐ¶ Ð±ÐŸÐ»ÐœÐŸ.}
+
+_textwyar_ [l=mn] {Ð¢Ð° Ð±ÑÐ»ÑÐœ Ð±ÐŸÐ»ÑÐœÑÑ
+ÐŸÐŸ ÐŽÐ°ÑÐ°Ð° ÑÐžÐœÑ ÐŽÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÐžÐ¹Ðœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°Ð°
+Ð±Ò¯ÑÐŽÒ¯Ò¯Ð»Ð¶ ÑÑ
+Ð»ÑÑ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ "ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÐŒÑÐŽÑÑÐ»ÑÐ»" Ð³ÑÑÑÐœ ÐœÐŸÐ³ÐŸÐŸÐœ ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐœÐ° ÑÑ!}
+
+_textcnmbs_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÐœÑÑÐžÐ¹Ð³ ÐŸÑÑÑÐ»ÑÐ°Ðœ Ð±Ð°Ð¹Ñ
+ ÑÑÑÐŸÐ¹}
+_texteambs_ [l=mn] {Ð-ÐŒÑÐ¹Ð» Ñ
+Ð°ÑÐ³ Ð·Ð°Ð°Ð³ÐŽÑÐ°Ðœ Ð±Ð°Ð¹Ñ
+ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³Ð°ÑÐ°Ð¹}
+_textpsea_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐœÑÑ@ÐŽÐŸÐŒÑÐ¹Ðœ Ñ
+ÑÐ»Ð±ÑÑÑÑÑ Ðž-ÐŒÑÐ¹Ð» Ñ
+Ð°ÑÐ³ÐžÐ¹Ð³ ÐŸÑÑÑÐ»ÐœÐ° ÑÑ}
+_textdocmbs_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÑÐ°Ð¹Ð»Ð±Ð°Ñ ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹Ð»ÐŸÐ³ÐŽÑÐŸÐœ Ð±Ð°Ð¹Ñ
+ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³Ð°ÑÐ°Ð¹.}
+
+_textwcanc_ [l=mn] {ÐšÐžÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð±Ò¯ÑÐŽÒ¯Ò¯Ð»ÑÑ
+ÑÑÑÑÑ Ó©ÐŒÐœÓ© ÑÐ° ÑÑ
+ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ðœ
+ÑÑÑ
+Ð°Ð¹ Ð·Ð°ÑÐžÐŒ ÐŒÑÐŽÑÑÐ»ÑÐ»ÑÑÐ¹ Ð±Ð°Ð¹Ñ
+ Ñ
+ÑÑÑÐ³ÑÑÐ¹. Ð­ÐœÑ Ò¯Ð¹Ð»ÐŽÑÐ» ÐœÑ ÐÑÐ±
+Ñ
+ÑÑÐŽÐ°ÑÐœÑÑÐŽÑÐœ ÑÑÐ²ÑÐ°Ð» Ñ
+ÑÐ»Ð±ÑÑÐžÐ¹Ðœ Ð±Ò¯ÑÑÑÑÑÐ¹ Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÑÐ³Ð»ÑÑÐ»Ð°Ð³ÑÐžÐ¹Ðœ
+Ñ
+ÑÐœÐ°Ð»ÑÐ°ÐŽ Ð±Ð°Ð¹ÐŽÐ°Ð³. Ð¥ÑÑÐŽÐ°ÑÐœÑ ÑÓ©Ð³ÑÐ³Ó©Ð»ÐŽ Ð±Ð°Ð¹Ð³Ð°Ð° ÑÐ°Ð»Ð±Ð°Ñ ÐœÑ Ð±Ó©Ð³Ð»Ó©Ñ
+ Ñ
+ÑÑÑÐ³ÑÑÐ¹
+Ñ
+ÑÑÐŽÐ°ÑÐœÑÑÐŽÑÐœ ÐŽÐ°ÑÐ°Ð°Ð»Ð»ÑÐ³ Ñ
+Ð°ÑÑÑÐ»ÐœÐ°.}
+
+_texttfc_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ Ð³Ð°ÑÑÐžÐ³:}
+
+_texttctiasp_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÐœÑÑ Ð³ÑÐŽÑÐ³ ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ Ð°Ð³ÑÑÐ»Ð°ÐŒÐ¶ÐžÐ¹Ð³ ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹Ð»ÐŸÑ
+ÑÐœ
+ÑÑÐ»ÐŽ ÐŽÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐŽ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÐŽÑÐ¶ Ð±ÑÐ¹ Ð±ÐŸÐ³ÐžÐœÐŸ Ó©Ð³Ò¯Ò¯Ð»Ð±ÑÑ ÑÐŒ.}
+
+_textcea_ [l=mn] {Ð¥Ð°ÑÐžÐ»ÑÐ°Ñ
+ Ðž-ÐŒÑÐ¹Ð» Ñ
+Ð°ÑÐ³:}
+
+_textteas_ [l=mn] {Ð­ÐœÑÑ
+Ò¯Ò¯ Ðž-ÐŒÑÐ¹Ð» Ñ
+Ð°ÑÐ³ ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ Ñ
+ÑÐ²ÑÐŽ Ñ
+ÐŸÐ»Ð±ÐŸÐ³ÐŽÐŸÑ
+ ÑÑ
+ÐœÐžÐ¹ ÑÑÐ³ÐžÐ¹Ð³ ÑÑÐŒÐŽÑÐ³Ð»ÑÐ¶ Ó©Ð³ÐŽÓ©Ð³.
+Ð¥ÑÑÑÐ² Greenstone Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ Ð°ÑÑÑÐŽÐ°Ð»ÑÐ°Ð¹ ÑÑÐ»Ð³Ð°ÑÐ²Ð°Ð», ÐŸÐœÐŸÑÐžÐ»Ð³ÐŸÐŸÐœÑ ÐŒÑÐŽÑÑÐ»ÑÐ» ÑÐœÑ Ñ
+Ð°ÑÐ³ ÑÑÑ ÐžÐ»Ð³ÑÑÐ³ÐŽÑÐœÑ.
+Ðž-ÐŒÑÐ¹Ð» Ñ
+Ð°ÑÐ³Ð°Ð° Ð±Ò¯ÑÐœÑÑÑ ÐœÑ ÐŸÑÑÑÐ»ÐœÐ° ÑÑ: 
+<tt>name@domain</tt>.}
+
+_textatc_ [l=mn] {Ð­ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÑÑÑ
+Ð°Ð¹}
+
+_texttiasd_ [l=mn] {Ð­ÐœÑ ÐŒÑÐŽÑÑÐ»ÑÐ» ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐœÐŽ ÑÑ Ð°Ð³ÑÑÐ»Ð°Ð³ÐŽÐ°Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð°Ð³ ÐµÑÓ©ÐœÑ
+ÐžÐ¹ÐŽ ÐœÑ ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹Ð»ÑÐŸÐœ Ð±ÐŸÐ»ÐœÐŸ.  
+Ð­ÐœÑ ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÑÑ
+ÐœÐžÐ¹ ÐœÒ¯Ò¯Ñ Ñ
+ÑÑÐŽÑÐ°ÐœÐŽ Ð±Ð°Ð¹ÑÐ»Ð°ÐŽÐ°Ð³.}
+
+_textypits_ [l=mn] {ÐÐ°ÑÐ°Ð°Ð»Ð°Ð» ÐŽÐ°Ñ
+Ñ ÑÐ°ÐœÑ Ð±Ð°Ð¹ÑÐ»Ð°Ð» ÐŽÐŸÐŸÑ Ð±Ð°Ð¹Ð³Ð°Ð° ÑÑÐŒÐ°Ð°Ñ ÐžÐ»ÑÑÑ
+ÐžÐ¹Ð»ÑÐ³ÐŽÑÑ
+
+Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÑÑ
+Ð°Ð¹Ðœ ÑÐŸÑ
+ÐžÐŸÐ»ÐŽÐŸÐ»ÐŽ "ÑÑÐ³Ð»ÑÑÐ³ÑÐœ ÐŒÑÐŽÑÑÐ»ÑÐ»" Ñ
+ÑÑÐŽÐ°ÑÐœÐ°Ð° Ð±Ð°Ð¹ÐœÐ°.
+ÐŠÐ°Ð°Ñ Ò¯ÑÐ³ÑÐ»Ð¶Ð»Ò¯Ò¯Ð»ÑÑ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ ÐœÐŸÐ³ÐŸÐŸÐœ Ó©ÐœÐ³Ó©ÑÑÐ¹ "ÑÑ
+ ÑÑÑÐ²Ð°Ð»Ð¶ÐžÐ¹Ðœ Ó©Ð³Ó©Ð³ÐŽÓ©Ð»"
+ÑÐŸÐ²Ñ ÐŽÑÑÑ ÐŽÐ°ÑÐœÐ° ÑÑ.}
+
+_srcebadsources_ [l=mn] {Ð¢Ð°ÐœÑ ÑÐŸÐœÐ³ÐŸÑÐŸÐœ ÐœÑÐ³ Ð±ÑÑÑ Ñ
+ÑÐŽ Ñ
+ÑÐŽÑÐœ ÐŸÑÐŸÐ»ÑÑÑÐŽÑÐœ ÑÑ
+ ÐŸÑÐŸÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°. (_iconcross_ Ð³ÑÐ¶ ÐŽÐŸÐŸÑ ÑÑÐŒÐŽÑÐ³Ð»ÑÐ³ÐŽÑÑÐœ)
+<p>ÐšÐ°Ð»ÑÐ³Ð°Ð°Ðœ ÐœÑ
+<ul>
+<li>Ð¢ÑÑ
+Ð°Ð¹Ðœ ÑÐ°Ð¹Ð», FTP ÑÐ°Ð¹Ñ ÑÑÐ²ÑÐ» URL Ð°Ð»Ð³Ð°.
+<li>Ð¢Ð° ÑÑ
+Ð»ÑÑÐŽ Ó©Ó©ÑÐžÐ¹Ðœ ISP-ÑÑÑ Ñ
+ÐŸÐ»Ð±ÐŸÐ³ÐŽÐŸÑ
+ Ñ
+ÑÑÑÐ³ÑÑÐ¹.
+<li>Ð¢Ð° firewall Ñ
+Ð°ÐŒÐ³Ð°Ð°Ð»Ð°Ð»ÑÑÐœ Ð°ÑÐŽÐ°Ð°Ñ URL-ÐŽ ÐœÑÐ²ÑÑÑÑ
+ÐžÐ¹Ð³ ÐŸÑÐŸÐ»ÐŽÐŸÐ¶ Ð±Ð°Ð¹ÐœÐ°. (Ð­ÐœÑ ÑÐŸÑ
+ÐžÐŸÐ»ÐŽÐŸÐ»ÐŽ ÑÐ° ÐžÐœÑÐµÑÐœÑÑÑÐŽ ÐœÑÐ²ÑÑÑÑ
+ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐœÑÑ Ð±ÐŸÐ»ÐŸÐœ ÐœÑÑÑ Ò¯Ð³ÑÑÐ¹ Ð±Ð°Ð¹Ñ
+ Ñ
+ÑÑÑÐ³ÑÑÐ¹).
+</ul>
+
+<p>Ð¥ÑÑÐ²ÑÑ ÑÐœÑ URL -Ð³ ÑÐ° Ó©Ó©ÑÐžÐ¹Ðœ Ð±ÑÐ°ÑÐ·ÐµÑÑ Ñ
+Ð°ÑÐ¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±ÐŸÐ» ÐŒÐ°Ð³Ð°ÐŽÐ³Ò¯Ð¹ ÑÐœÑ ÐœÑ ÑÐ°ÐœÑ ÐºÐŸÐŒÐ¿ÑÑÑÐµÑ ÐŽÑÑÑ Ñ
+Ð°ÐŽÐ³Ð°Ð»Ð°Ð³ÐŽÑÐžÑ
+ÑÐ°Ðœ Ñ
+ÑÑÐ»Ð±Ð°Ñ Ð±Ð°Ð¹Ð¶ Ð±ÐŸÐ»ÐŸÑ
+ ÑÐŒ.  Ð¥Ð°ÑÐ°ÐŒÑÐ°Ð»ÑÐ°Ð¹ ÐœÑ ÑÐœÑÑ
+Ò¯Ò¯ Ñ
+Ð°ÐŽÐ³Ð°Ð»Ð°Ð³ÐŽÑÐ°Ðœ Ñ
+ÑÑÐ»Ð±Ð°ÑÑÑÐŽ ÐœÑ Ð±ÐžÐŽÐœÐžÐ¹  Ñ
+ÑÐœÐ°Ð»ÑÐ°ÐŽ Ñ
+Ð°ÐŒÑÐ°Ð³ÐŽÐ°Ñ
+Ð³Ò¯Ð¹ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±ÐŸÐ»ÐœÐŸ. ÐÐ¹ÐŒÐŽ ÑÐ°ÐœÑÐ³ ÑÑÐœÑ ÑÒ¯ÑÒ¯Ò¯ÐœÐŽ Ó©Ó©ÑÐžÐ¹Ðœ Ð±ÑÐ°ÑÐ·ÐµÑÑÑ Ð°ÑÐžÐ³Ð»Ð°Ðœ Ñ
+ÑÑÐŽÑÑÑÐŽÐ°Ð° ÑÐ°ÑÐ°Ð¶ Ð°Ð²Ð°Ñ
+ÑÐ³ ÑÐ°ÐœÐ°Ð» Ð±ÐŸÐ»Ð³ÐŸÐ¶ Ð±Ð°Ð¹ÐœÐ°.}
+
+_textymbyco_ [l=mn] {<p>Ð¢Ð° Ó©Ó©ÑÐžÐ¹Ðœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°Ð° Ò¯Ò¯ÑÐ³ÑÑ
+ ÑÐŒ ÑÑ ÑÑÐ²ÑÐ»
+<ul>
+<li>Ð¡ÑÐ°ÐœÐŽÐ°ÑÑ Ð±Ò¯ÑÑÑ
+<dl><dd>ÐšÐžÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽ html Ð±Ð°ÑÐžÐŒÑ (.htm, .html), ÑÐœÐ³ÐžÐ¹Ðœ ÑÐµÐºÑÑ Ð±Ð°ÑÐžÐŒÑÑÑÐŽ
+(.txt, .text), MS Word Ð±Ð°ÑÐžÐŒÑÑÑÐŽ (.doc), PDF Ð±Ð°ÑÐžÐŒÑÑÑÐŽ (.pdf) ÑÑÐ²ÑÐ» "m-box"
+ÑÐŸÑÐŒÐ°ÑÑÐœ ÐžÐŒÑÐ¹Ð» Ð±Ð°ÑÐžÐŒÑÑÑÐŽ (.mbx) Ð±Ð°Ð¹Ð¶ Ð±ÐŸÐ»ÐœÐŸ.</dd></dl>
+<li>ÐÐŽÐŸÐŸ Ð±Ð°Ð¹Ð³Ð°Ð° ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°
+<dl><dd>Ò®Ò¯ÑÐ³ÑÐ¶ Ð±ÑÐ¹ ÑÐžÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÐŽÐ°Ñ
+Ñ ÑÐ°Ð¹Ð»ÑÑÐŽ ÐœÑ ÐŸÐŽÐŸÐŸ Ð±Ð°Ð¹Ð³Ð°Ð°Ð³ Ò¯Ò¯ÑÐ³ÑÑ
+ÑÐŽ
+Ñ
+ÑÑÑÐ³Ð»ÑÑÑÐœÑÑÐ¹ ÑÐ³ ÐžÐ¶ÐžÐ» ÑÓ©ÑÐ»ÐžÐ¹ÐœÑ
+ Ð±Ð°Ð¹ÐœÐ°.</dd></dl>
+</ul>}
+
+_textbtco_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ ÐŽÐŸÐŸÑÑ
+Ðž Ð¶ÐžÑÑÑÐœÐŽ ÑÑÐ»Ð³ÑÑÑÐ»Ð°Ðœ Ò¯Ò¯ÑÐ³Ñ}
+_textand_ [l=mn] {ÐšÐžÐœÑ Ó©Ð³Ó©Ð³ÐŽÓ©Ð» ÐŸÑÑÑÐ»Ð°Ñ
+}
+_textad_ [l=mn] {ÓšÐ³Ó©Ð³ÐŽÓ©Ð» ÐœÑÐŒÑÑ
+}
+
+_texttftysb_ [l=mn] {Ð¢Ð°ÐœÑ ÐŽÐŸÐŸÑ ÐŸÑÑÑÐ»Ð°Ñ
+ ÑÐ°Ð¹Ð»ÑÑÐŽ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐœÐŽ ÐœÑÐŒÑÐ³ÐŽÑÑ
+ Ð±ÐŸÐ»ÐœÐŸ. ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐœÐŽ
+ÐœÑÐ³ÑÐœÑ ÐŸÑÑÑÐ»ÑÐžÑ
+ÑÐ°Ðœ ÑÐ°Ð¹Ð»Ð°Ð° ÐŽÐ°Ñ
+ÐžÐœ ÐœÑÐŒÐ¶ ÐŸÑÑÑÐ»ÑÐ°Ðœ ÑÑÑÑ
+ÑÑ Ð°ÐœÑ
+Ð°Ð°ÑÐ°Ð°ÑÐ°Ð¹: ÑÑ Ð±Ó©Ð³Ó©Ó©Ñ 
+ÐœÑÐ³ ÑÐ°Ð¹Ð»ÑÐœ ÐžÐ¶ÐžÐ»Ñ
+ÑÐœ Ñ
+ÐŸÑÑ Ñ
+ÑÐ²ÐžÐ»Ð±Ð°Ñ ÐŸÑÐŸÑ
+ Ð±ÐŸÐ»ÐœÐŸ. Ð€Ð°Ð¹Ð»ÑÑÐŽ ÐœÑ Ñ
+Ð°ÐŽÐ³Ð°Ð»Ð°Ð³ÐŽÑÐ°Ðœ Ñ
+Ð°ÑÐ³, 
+Ð²ÑÐ± Ñ
+ÑÑÐŽÐ°ÑÐœÑÑÐŽÑÐœ Ð²ÑÐ± Ñ
+Ð°ÑÐ³ Ð·ÑÑÐ³ÑÑÑ ÑÐ°ÐœÐžÐ³ÐŽÐ°Ñ
+ Ð±ÐŸÐ»ÐœÐŸ.}
+
+_textis_ [l=mn] {Ð­Ñ
+ ÑÑÑÐ²Ð°Ð»Ð¶ÑÑÐŽ ÐŸÑÑÑÐ»Ð°Ñ
+:}
+
+_textddd1_ [l=mn] {<p>Ð€Ð°Ð¹Ð»ÑÐœ Ð·Ð°ÐŒÑÐ³ Ð·Ð°Ð°Ð¶ Ó©Ð³Ó©Ñ
+ÐŽÓ©Ó© file:// ÑÑÐ²ÑÐ» ftp:// Ð³ÑÐ¶ Ó©Ð³ÑÓ©Ðœ Ð±ÐŸÐ» ÑÑÑ
+ÑÐ°Ð¹Ð»ÑÐ³ ÑÐ°ÑÐ°Ð¶ Ð°Ð²Ð°Ñ
+ Ð±ÐŸÐ»ÐœÐŸ.
+
+<p>Ð¥ÑÑÐ²ÑÑ ÑÐ° http:// -ÐžÐ¹Ð³ Ñ
+ÑÑÑÐ³Ð»ÑÐ²ÑÐ», ÑÐœÑ ÐœÑ URL ÑÐ°ÐœÑ Ð±ÑÐ°ÑÐ·ÐµÑÑ
+ÑÐœÐ³ÐžÐ¹Ðœ Ð²ÑÐ± Ñ
+ÑÑÐŽÐ°Ñ ÑÑÐ²ÑÐ» ÑÐ°Ð¹Ð»ÑÐœ Ð¶Ð°Ð³ÑÐ°Ð°Ð»ÑÑÐœ Ð°Ð»ÐžÐ¹Ð³ ÐœÑ Ð³Ð°ÑÐ³Ð°Ð¶
+Ð±ÑÐ¹Ð³Ð°Ð°Ñ Ñ
+Ð°ÐŒÐ°Ð°ÑÐœÐ°. Ð¥ÑÑÑÐ² Ñ
+ÑÑÐŽÐ°Ñ Ð±ÐŸÐ» ÑÑÑÑ
+Ò¯Ò¯ Ñ
+ÑÑÐŽÑÑÐ³ ÑÐ°ÑÐ°Ð¶ Ð°Ð²Ð°Ñ
+
+Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÒ¯Ò¯ÐœÑÑÐ¹ Ñ
+ÐŸÐ»Ð±ÐŸÐ³ÐŽÐŸÑ
+ Ð±Ò¯Ñ
+ Ñ
+ÑÑÐŽÑÑÑÐŽ, ÑÑÐŽÐ³ÑÑÑ Ñ
+ÑÑÐŽÑÑÑÐŽÑÐ°Ð¹
+Ñ
+ÐŸÐ»Ð±ÐŸÐ³ÐŽÐŸÑ
+ Ð±Ò¯Ñ
+ Ñ
+ÑÑÐŽÑÑÑÐŽÑÐ³ Ñ ÐŒÓ©Ðœ Ð°ÐŽÐžÐ» ÑÐ°ÑÐ°Ð¶ Ð°Ð²Ñ Ð±ÐŸÐ»ÐœÐŸ. 
+
+<p>Ð¥ÑÑÑÐ² ÑÐ° ÑÐŸÐ»ÐŽÐµÑ ÑÐŒÑÑ ÐŽÐžÑÐµÐºÑÐŸÑÑÐ³ ÐŸÐœÑÐ³ÐŸÐ¹Ð»ÐŸÐœ Ð·Ð°Ð°Ñ
+ Ò¯Ò¯ÐŽÐœÑÑÑ
+file:// ÑÑÐ²ÑÐ» ftp:// Ð³ÑÐ¶ Ñ
+ÑÑÑÐ³Ð»ÑÐŽÑÐ³, ÑÑÐ²ÑÐ» ÑÐ°Ð¹Ð»ÑÑÐŽÑÐœ Ð¶Ð°Ð³ÑÐ°Ð°Ð»ÑÑÐ³
+Ñ
+Ó©ÑÐ»Ó©Ñ
+ http:// URL-Ð³ Ó©Ð³ÑÓ©Ðœ ÑÐŸÑ
+ÐžÐŸÐ»ÐŽÐŸÐ»ÐŽ ÑÐŸÐ»ÐŽÐµÑ ÐŽÑÑ
+Ðž Ð±Ò¯Ñ
+ Ð·Ò¯Ð¹Ð» Ð±ÐŸÐ»ÐŸÐœ
+ÑÒ¯Ò¯ÐœÐžÐ¹ ÐŽÑÐŽ ÑÐŸÐ»ÐŽÐµÑÒ¯Ò¯ÐŽ ÐœÑ Ð±Ò¯Ð³ÐŽ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽ Ð°Ð³ÑÑÐ»Ð°Ð³ÐŽÐ°Ñ
+ Ð±ÐŸÐ»ÐœÐŸ.
+
+<p>ÐÐ»Ò¯Ò¯ ÐŒÑÐŽÑÑÐ»ÑÐ» ÐŸÑÑÑÐ»Ð°Ñ
+ Ð±ÐŸÐ» "ÐžÐ»Ò¯Ò¯ ÑÑ
+ ÑÑÑÐ²Ð°Ð»Ð¶ÑÑÐŽ"
+Ð³ÑÑÑÐœ ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐœÐ° ÑÑ.}
+
+_textddd2_ [l=mn] {<p>ÐÐŸÐ³ÐŸÐŸÐœ ÑÐŸÐ²ÑÐœÑÑÐŽÑÐœ Ð°Ð»Ñ ÐœÑÐ³ÐžÐ¹Ð³ ÐœÑ ÐŽÐ°ÑÐœÐ° ÑÑ. Ð¥ÑÑÑÐ² ÑÐ° ÑÑÑ
+ Ð±Ò¯Ñ
+ÐžÐ¹
+Ñ
+ÑÑÑÐ³Ð»ÑÐ³Ñ Ð±ÐŸÐ» ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ Ñ
+ÑÐ»Ð±ÑÑÐžÐ¹Ð³ ÑÐŸÑ
+ÐžÑÑÑÐ»Ð¶ Ð±ÐŸÐ»ÐœÐŸ.
+Ð­ÑÐ²ÑÐ» ÑÑÑÐŽ Ñ
+ÐžÐ¹Ñ
+ Ò¯Ðµ ÑÐ°ÑÐ°ÐœÐŽ ÐœÑ ÐŸÑÐ¶ Ð±ÐŸÐ»ÐœÐŸ. ÐšÐ°Ñ ÑÐŸÐ²ÑÐžÐ¹Ð³
+ÐŽÐ°ÑÐ°Ð°ÐŽ Ó©ÐŒÐœÓ©Ñ
+ Ò¯Ðµ ÑÐ°ÑÑÑÐŽÐ°ÐŽ ÐŸÑÐžÐ¶ Ð±ÐŸÐ»ÐœÐŸ Ð³ÑÐŽÐ³ÐžÐ¹Ð³ ÑÐ°ÐœÐ°Ð°ÑÐ°Ð¹.}
+
+_textconf1_ [l=mn] {<p>Ð¢ÑÑÐ³Ð°Ð¹ "ÑÐŸÑ
+ÐžÑÑÑÐ»Ð³ÑÐœ ÑÐ°Ð¹Ð»" ÑÐœ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ ÐœÑ ÑÐ°ÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ñ
+ÐžÐ¹Ñ
+ Ð±ÐŸÐ»ÐŸÐœ  
+ÑÐ°ÐœÐžÐ»ÑÑÑÐ»Ð°Ñ
+ Ò¯Ð¹Ð»ÐŽÐ»ÐžÐ¹Ð³ Ð·ÐŸÑ
+ÐžÑÑÑÐ»Ð¶ Ð±Ð°Ð¹ÐŽÐ°Ð³. Ð­ÑÑ
+ Ð±Ò¯Ñ
+ÐžÐ¹ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐŽ  
+ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐœÑÑÐŽÑÐ³ Ó©Ó©ÑÑÐžÐ»Ð¶ Ð±ÐŸÐ»ÐœÐŸ.
+
+<center><p><b>Ñ
+ÑÑÑÐ² ÑÐ° ÑÑÑ
+ Ð±Ò¯Ñ
+ÐžÐ¹ Ñ
+ÑÑÑÐ³Ð»ÑÐ³Ñ Ð±ÐžÑ Ð±ÐŸÐ», Ñ
+ÑÑÐŽÐ°ÑÐœÑ ÐŽÐŸÐŸÐŽ ÑÐ°Ð» ÑÑÑ ÐŸÑÐœÐŸ ÑÑ. 
+</b></center> 
+
+<p>Ð¢ÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐ³ Ó©Ó©ÑÑÐ»Ó©Ñ
+Ó©ÐŽ, ÐŽÐŸÐŸÑ Ð±Ð°Ð¹Ð³Ð°Ð° Ó©Ð³Ó©Ð³ÐŽÐ»ÐžÐ¹Ð³ Ð·Ð°ÑÐ°Ð°ÑÐ°Ð¹.
+Ð¥ÑÑÐ²ÑÑ ÑÐ° Ð°Ð»ÐŽÐ°Ð° Ð³Ð°ÑÐ³Ð°Ñ
+ ÑÐŒ Ð±ÐŸÐ», "Ð­Ñ
+Ð»Ò¯Ò¯Ð»ÑÑ
+" ÑÐŸÐ²ÑÐžÐ¹Ð³ ÐŽÐ°ÑÐ¶ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐœÑ Ð°ÐœÑ
+ÐœÑ Ñ
+ÑÐ²ÐžÐ»Ð±Ð°ÑÑÐ³ ÐŽÐ°Ñ
+ÐžÐœ Ð³Ð°ÑÐ³Ð°Ð¶ Ð±ÐŸÐ»ÐœÐŸ.}
+
+_textreset_ [l=mn] {Ð­Ñ
+Ð»Ò¯Ò¯Ð»ÑÑ
+}
+
+
+_texttryagain_ [l=mn] {<a href="_httppagecollector_" target=_top>ÐŠÑÐ³Ð»ÑÑÐ»Ð°Ð³ÑÐžÐ¹Ð³ ÐŽÐ°Ñ
+ÐžÐœ ÑÑ
+Ð»Ò¯Ò¯Ð»ÑÑÐŽ</a>
+ÐŽÐ°Ñ
+ÐžÐœ ÐœÑÐ³ ÐŸÑÐŸÐ»ÐŽÐ»ÐŸÐ³ÐŸ Ñ
+ÐžÐ¹ÐœÑ Ò¯Ò¯.}
+
+
+_textretcoll_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð°Ð³Ñ ÑÑÑ Ð±ÑÑÐ°Ñ
+}
+
+_textdelperm_ [l=mn] {ÐÐ°ÑÐžÐŒ Ð±ÑÑÑ Ð±Ò¯Ñ
+ _cgiargbc1dirname_ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ð°ÑÐžÐ»Ð³Ð°Ñ
+ 
+Ð±ÐŸÐ»ÐŸÐŒÐ¶Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°. ÐšÐ°Ð»ÑÐ³Ð°Ð°Ðœ ÐœÑ:
+<ul>                                                                                                                                                                                                                                       <li> Greenstone ÐœÑ <li>Greenstone ÑÑÑ
+Ð°Ð¹Ðœ _gsdlhome_/collect/_cgiargbc1dirname_
+ÐŽÐžÑÐµÐºÑÐŸÑÑÐ³ ÑÑÑÐ³Ð°Ñ
+ ÑÑÑ
+Ð³Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°.<br>
+_cgiargbc1dirname_ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ ÑÐœÑ ÐºÐŸÐŒÐ¿ÑÑÑÐµÑÑÑÑ Ð°ÑÐžÐ»Ð³Ð°Ñ
+ Ò¯Ð¹Ð»ÐŽÐ»ÐžÐ¹Ð³ Ð±Ò¯ÑÑÐœ Ñ
+ÐžÐ¹Ñ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ
+ÑÐ° ÑÐœÑÑ
+Ò¯Ò¯ ÐŽÐžÑÐµÐºÑÐŸÑÑÐ³ Ð³Ð°Ñ Ð°Ð¶ÐžÐ»Ð»Ð°Ð³Ð°Ð°Ð³Ð°Ð°Ñ ÑÑÑÐ³Ð°ÐœÐ°. </li>
+<li>Greenstone _gsdlhome_/bin/script/delcol.pl. Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑÐ³ Ð°Ð¶ÐžÐ»Ð»ÑÑÐ»Ð°Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°.
+Ð­ÐœÑ ÑÐ°Ð¹Ð» ÐœÑ ÑÐœÑÐžÐ³ÐŽÐ°Ñ
+ÑÐ¹Ñ Ð±ÑÑÑ Ð³Ò¯Ð¹ÑÑÑÐ³ÑÐ³ÐŽÑÑ
+Ò¯Ð¹Ñ ÑÑÑÑ
+ÐžÐ¹Ð³ ÑÐ°Ð»Ð³Ð°ÐœÐ° ÑÑ. </li>
+</ul>}
+
+_textdelinv_ [l=mn] {_cgiargbc1dirname_ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÐœÑ Ñ
+Ð°ÐŒÐ³Ð°Ð°Ð»Ð°Ð³ÐŽÑÐ°Ðœ, ÑÑÐ²ÑÐ» Ñ
+Ò¯ÑÐžÐœÐ³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°. Ð£ÑÑÐ³Ð°ÑÐ°ÐœÐ³Ò¯Ð¹.}
+
+_textdelsuc_ [l=mn] {_cgiargbc1dirname_ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ð°ÐŒÐ¶ÐžÐ»ÑÑÐ°Ð¹ ÑÑÑÐ³Ð°Ð»Ð°Ð°.}
+
+_textclonefail_ [l=mn] {_cgiargclonecol_ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ñ
+ÑÐ²ÐžÐ»Ð°Ð³ÐŽÑÐ°ÐœÐ³Ò¯Ð¹. ÐšÐ°Ð»ÑÐ³Ð°Ð°Ðœ ÐœÑ:
+<ul>
+<li>_cgiargclonecol_ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ð±Ð°Ð¹Ñ
+Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°.
+<li>_cgiargclonecol_ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐœÐŽ collect.cfg Ð³ÑÐŽÑÐ³ Ó©Ó©ÑÑÐ»Ó©Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ ÑÐ°Ð¹Ð» Ð°Ð»Ð³Ð° Ð±Ð°Ð¹ÐœÐ°.
+<li> Greenstone collect.cfg ÑÐ°Ð¹Ð»ÑÐ³ ÑÐœÑÐžÑ
+ ÑÑÑ
+Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°. 
+</ul>}
+
+_textcolerr_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð°Ð³ÑÐžÐ¹Ðœ Ð°Ð»ÐŽÐ°Ð°.}
+
+_texttmpfail_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð°Ð³Ñ ÑÒ¯Ñ ÑÐ°Ð¹Ð» ÑÑÐ²ÑÐ» ÐŽÐžÑÐµÐºÑÐŸÑÐžÐ¹Ð³  ÑÐœÑÐžÑ
+ ÑÑÐ²ÑÐ» Ð±ÐžÑÐžÑ
+ Ò¯Ð¹Ð»ÐŽÐ»ÐžÐ¹Ð³ Ð³Ò¯Ð¹ÑÑÑÐ³ÑÐ¶ ÑÐ°ÐŽÑÐ°ÐœÐ³Ò¯Ð¹. 
+Ò®Ò¯ÐœÐžÐ¹ Ð±Ð°Ð¹Ð¶ Ð±ÐŸÐ»ÐŸÑ
+ ÑÐ°Ð»ÑÐ³Ð°Ð°Ðœ ÐœÑ :
+<ul>
+<li> Greenstone _gsdlhome_/tmp ÐŽÐžÑÐµÐºÑ Ð·ÐŸÑÐžÑÐ»ÑÐ°Ðœ ÑÐœÑÐžÑ
+/Ð±ÐžÑÐžÑ
+  
+     ÑÑÑ
+ Ð±Ð°Ð¹Ñ
+Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°.
+</ul>}
+
+_textmkcolfail_ [l=mn] {ÐšÐžÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³Ð°ÑÐ°Ð¹ ÐŽÐžÑÐµÐºÑÐŸÑÑÐœ Ð±Ò¯ÑÑÐžÐ¹Ð³ Ð±Ò¯ÑÐŽÒ¯Ò¯Ð»ÑÑ
+ Ð³ÑÑÑÐœ 
+ÑÑÐ³Ð»ÑÑÐ»Ð°Ð³Ñ Ð°ÐŒÐ¶ÐžÐ»ÑÐ³Ò¯Ð¹ Ð±ÐŸÐ»Ð»ÐŸÐŸ. (mkcol.pl Ð°ÐŒÐ¶ÐžÐ»ÑÐ³Ò¯Ð¹ Ð±ÐŸÐ»Ð»ÐŸÐŸ). ÐšÐ°Ð»ÑÐ³Ð°Ð°Ðœ ÐœÑ:
+<ul>
+<li> Greenstone _gsdlhome_/tmp ÐŽÐžÑÐµÐºÑÐŸÑ Ð»ÑÑ Ð±ÐžÑÐžÑ
+ ÑÑÑ
+Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°. 
+ <li> mkcol.pl perl script -Ðœ Ð°Ð»ÐŽÐ°Ð°.
+</ul>}
+
+_textnocontent_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð°Ð³ÑÐžÐ¹Ðœ Ð°Ð»ÐŽÐ°Ð°: ÑÐžÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽ ÐœÑÑ Ð±Ð°Ð¹Ñ
+Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°. ÐŠÑÐ³Ð»ÑÑÐ»Ð°Ð³ÑÐžÐ¹Ð³ ÑÑ
+ÐœÑÑÑ ÐœÑ ÐŽÐ°Ñ
+ÐžÐœ ÑÑ
+Ð»Ò¯Ò¯Ð»ÐœÑ Ò¯Ò¯.}
+
+_textrestart_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð°Ð³ÑÐžÐ¹Ð³ ÐŽÐ°Ñ
+ÐžÐœ ÑÑ
+Ð»Ò¯Ò¯Ð»ÑÑ
+}
+
+_textreloaderror_ [l=mn] {ÐšÐžÐœÑ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ð±Ò¯ÑÐŽÒ¯Ò¯Ð»ÑÑ
+ ÑÐ²ÑÐ°ÐŽ Ð°Ð»ÐŽÐ°Ð° Ð³Ð°ÑÐ»Ð°Ð°. Greenstone ÑÐ°ÐœÑ Ð±ÑÐ°ÑÐ·ÐµÑÑÐœ 
+"ÐŽÐ°Ñ
+ÐžÐœ Ð°ÑÐ°Ð°Ð»Ð°Ñ
+" Ð±ÑÑÑ "Ð±ÑÑÐ°Ñ
+"  (ÑÑÐ³Ð»ÑÑÐ»Ð°Ð³ÑÐ°Ð°Ñ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÐ³ÑÑ
+ ÑÐ²ÑÐ°ÐŽ ÑÐœÑ ÑÐŸÐ²ÑÐžÐ¹Ð³ 
+Ñ
+ÑÑÑÐ³Ð»ÑÑ
+ÑÑÑ Ð·Ð°Ð¹Ð»ÑÑ
+ÐžÐ¹ÐœÑ Ò¯Ò¯) ÑÐŸÐ²ÑÐ»ÑÑÑÑÑÐŽÑÐ³ Ð°ÐœÐŽÑÑÑÑÐœÐ°Ð°Ñ Ò¯Ò¯ÑÑÑÐœ Ð±Ð°Ð¹Ð¶ Ð±ÐŸÐ»ÐŸÑ
+ ÑÐŒ.
+ÐŠÑÐ³Ð»ÑÑÐ»Ð°Ð³ÑÐžÐ¹Ð³ ÑÑ
+ÐœÑÑÑ ÐœÑ ÐŽÐ°Ñ
+ÐžÐœ ÑÑ
+Ð»Ò¯Ò¯Ð»ÑÑ
+ÐžÐ¹Ð³ ÑÐ°ÐœÐŽ Ð·Ó©Ð²Ð»Ó©Ð¶ Ð±Ð°Ð¹ÐœÐ°.}
+
+_textexptsuc_ [l=mn] {_cgiargbc1dirname_ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ _gsdlhome_/tmp/exported\__cgiargbc1dirname_ ÐŽÐžÑÐµÐºÑÐŸÑ Ð»ÑÑ 
+Ð°ÐŒÐ¶ÐžÐ»ÑÑÐ°Ð¹ ÐŸÑÑÑÐ»Ð»Ð°Ð°.}
+
+_textexptfail_ [l=mn] {<p>_cgiargbc1dirname_ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ð±ÐžÑÐžÑ
+ÑÑÑ Ð±ÑÐ»ÐŽÑÑ
+ Ò¯Ð¹Ð» ÑÐ²Ñ Ð°ÐŒÐ¶ÐžÐ»ÑÐ³Ò¯Ð¹ Ð±ÐŸÐ»Ð»ÐŸÐŸ.
+
+<p>Ð­ÐœÑ ÐœÑ Greenstone-Ð³ "ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° ÑÐºÑÐ¿ÐŸÑÑÐ»ÐŸÑ
+" Ð³ÑÑÑÐœ Ò¯Ð¹Ð»ÐŽÐ»ÐžÐ¹Ð³  
+Ñ
+Ð°ÐœÐ³Ð°Ñ
+Ð°ÐŽ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³Ð°ÑÐ°Ð¹ Ð±Ò¯ÑÐŽÒ¯Ò¯Ð»ÑÐ»ÑÐ³Ò¯Ð¹Ð³ÑÑÑ ÐžÐœÑÑÐ°Ð»Ð» Ñ
+ÐžÐ¹ÑÑÐœÑÑÐ¹ Ñ
+ÐŸÐ»Ð±ÐŸÐŸÑÐŸÐ¹.
+<ul>
+
+<li>Ð¥ÑÑÑÐ² ÑÐ° Greenstone-Ð³ CD-ROM-ÐŸÐŸÑ ÐžÐœÑÑÐ°Ð»Ð» Ñ
+ÐžÐ¹ÑÑÐœ Ð±ÐŸÐ» "Custom" ÐžÐœÑÑÐ°Ð»Ð»ÑÐœ Ò¯ÐµÐŽ 
+Ñ
+ÑÑÑÐ² ÑÑÐŽÐœÐžÐ¹Ð³ ÑÐŸÐœÐ³ÐŸÐŸÐ³Ò¯Ð¹ Ð±ÐŸÐ» ÑÐŽÐ³ÑÑÑ Ð±Ò¯ÑÐŽÒ¯Ò¯Ð»ÑÐ»ÑÒ¯Ò¯ÐŽ ÐœÑ ÐžÐœÑÑÐ°Ð»Ð» Ñ
+ÐžÐ¹Ð³ÐŽÑÑ
+Ð³Ò¯Ð¹.
+ÐÐœÑÐ°Ð»Ð»ÑÐœ Ð¿ÑÐŸÑÐµÑÑÑÐ³ ÐŽÐ°Ñ
+ÐžÐœ ÑÑ
+Ð»Ò¯Ò¯Ð»ÑÑ
+ Ð·Ð°ÐŒÐ°Ð°Ñ ÑÑÐŽÐ³ÑÑÑÐžÐ¹Ð³ ÐžÐœÑÑÐ°Ð»Ð»ÐŽ ÐœÑÐŒÐ¶ ÐŸÑÑÑÐ»Ð¶  
+Ð±ÐŸÐ»ÐœÐŸ.
+<li>Ð¥ÑÑÑÐ² ÑÐ° Greenstone-Ð³ Ð²ÑÐ±ÑÑÑ  ÐžÐœÑÑÐ°Ð»Ð» Ñ
+ÐžÐ¹ÑÑÐœ Ð±ÐŸÐ» ÑÐœÑÑ
+Ò¯Ò¯ Ò¯Ð¹Ð»ÐŽÐ»ÐžÐ¹Ð³ 
+ÐžÐŽÑÐ²Ñ
+Ð¶Ò¯Ò¯Ð»ÑÑ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ ÐœÑÐŒÑÐ»Ñ Ð±Ð°Ð³ÑÑÑÐŽÑÐ³ ÑÐ°ÑÐ°Ð¶ Ð°Ð²Ñ, ÐžÐœÑÑÐ°Ð»Ð» Ñ
+ÐžÐ¹Ñ
+ Ñ
+ÑÑÑÐ³ÑÑÐ¹. 
+ÐÑÐŒÑÐ»Ñ ÐŒÑÐŽÑÑÐ»ÑÐ» Ð°Ð²Ð°Ñ
+ÑÐ³ Ñ
+Ò¯ÑÐ²ÑÐ» <a href="http://www.greenstone.org">http://www.greenstone.org</a> 
+Ð²ÑÐ± Ñ
+ÑÑÐŽÑÐ°ÐœÐŽ Ñ
+Ð°ÐœÐŽÐ°Ñ
+ Ð±ÑÑÑ <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>
+Ñ
+Ð°ÑÐ³Ð°Ð°Ñ Ðž-ÐŒÑÐ¹Ð» ÐžÐ»Ð³ÑÑÐœÑ Ò¯Ò¯.
+
+</ul>}
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=mn] {<p> ÐÐ°ÑÐ°Ð°Ñ
+ ÑÐ°Ð¹Ð»ÑÐœ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ ÐŸÑÑÑÐ»Ð°Ð°ÐŽ ÐŽÐŸÐŸÑÑ
+Ðž ÑÐ°Ð¹Ð»ÑÐ³ ÑÐŸÐœÐ³ÐŸÐœÐŸ ÑÑ.</p>}  
+
+_textcaec_ [l=mn] {Ò®Ò¯ÑÐ³ÑÐ³ÐŽÑÑÐœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° ÑÑÑ ÐœÑÐŒÐ¶ Ð±Ð°Ð¹ÐœÐ°}  
+_textbild_ [l=mn] {Ð¥Ð°ÐŽÐ³Ð°Ð»Ð°Ñ
+ Ð·Ò¯Ð¹Ð»}  
+_textintro_ [l=mn] {Ð€Ð°Ð¹Ð»Ð°Ð° ÑÐŸÐœÐ³ÐŸ}  
+_textconfirm_ [l=mn] {ÐÐ°ÑÐ°Ð»Ð³Ð°Ð°Ð¶ÑÑÐ»Ð°Ð»Ñ}  
+_textselect_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³Ð° ÑÐŸÐœÐ³ÐŸÑ
+}  
+_textmeta_ [l=mn] {Metadata ÐŸÑÑÑÐ»Ð°Ñ
+}  
+
+
+_texttryagain_ [l=mn] {Please <a href="_httppagedepositor_" target=_top>restart the depositor</a>
+and try again.}  
+
+_textselectcol_ [l=mn] {ÐšÐžÐœÑÑÑ Ð±Ð°ÑÐžÐŒÑ ÐŸÑÑÑÐ»Ð°Ñ
+ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°Ð° ÑÐŸÐœÐ³ÐŸÐœÐŸ ÑÑ.}  
+_textfilename_ [l=mn] {Ð€Ð°Ð¹Ð»ÑÐœ ÐœÑÑ}  
+_textfilesize_ [l=mn] {Ð€Ð°Ð¹Ð»ÑÐœ Ñ
+ÑÐŒÐ¶ÑÑ}  
+
+_textretcoll_ [l=mn] {ÐÑÑÐ°Ñ
+}  
+
+
+_texttmpfail_ [l=mn] {The depositor failed to read from or write to a temporary file or
+directory. Possible causes are:
+<ul>
+<li> Greenstone does not have read/write access to the _gsdlhome_/tmp
+     directory.
+</ul>}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=mn] {Greenstone ÐœÑ ÐŽÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÑÐœ Ð¿ÑÐŸÐ³ÑÐ°ÐŒ Ð±Ð° ÐŒÓ©Ðœ ÑÐžÐœÑÑÑ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ò¯Ò¯ÑÐ³ÑÑ
+ 
+Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ Ñ
+Ð°ÐœÐ³Ð°ÐŒÐ¶ ÑÐŒ.  Ð­ÐœÑ ÐœÑ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ ÑÐŒÑ
+Ð»ÑÐœ ÑÑÐ³ÑÑÐ»Ð¶ ÑÒ¯Ò¯ÐœÐžÐ¹Ð³ÑÑ 
+ÐžÐœÑÐµÑÐœÑÑÑÑÑ ÑÑÐ²ÑÐ» CD-ROM -ÐŸÐŸÑ ÐŽÐ°ÐŒÐ¶ÑÑÐ»Ð°Ðœ Ð±ÑÑÐŽÐ°ÐŽ Ñ
+Ò¯ÑÑÑÑÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÐžÐ¹Ð³ ÐŸÐ»Ð³ÐŸÐŽÐŸÐ³. 
+Greenstone ÐœÑ ÐšÐžÐœÑ ÐÐµÐ°Ð»Ð°ÐœÐŽÑÐœ ÐÐŸÐŒÑÐœ Ð¡Ð°ÐœÐ³ÐžÐ¹Ðœ ÑÓ©ÑÐ»Ó©Ó©Ñ Waikato-Ð³ÐžÐ¹Ðœ ÐžÑ
+ ÑÑÑÐ³ÑÑÐ»ÑÐŽ Ñ
+ÐžÐ¹Ð³ÐŽÑÑÐœ                                                                                                                                                           UNESCO Ð±ÐŸÐ»ÐŸÐœ Human Info Ð¢ÐÐ-ÑÐ°Ð¹ Ñ
+Ð°ÐŒÑÑÐ°Ðœ Ð°Ð¶ÐžÐ»Ð»Ð°ÑÐœÑ ÐŽÒ¯ÐœÐŽ ÐœÐžÐ¹ÑÐžÐ¹Ðœ Ñ
+Ò¯ÑÑÑÑÐ» Ð±ÐŸÐ»ÑÐŸÐœ. 
+Ð­ÐœÑ Ð±ÐŸÐ» ÐœÑÑÐ»ÑÑÑÐ¹-Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ Ð±Ó©Ð³Ó©Ó©ÐŽ ÐŽÐ°ÑÐ°Ð°Ñ
+ Ñ
+Ð°ÑÐ³Ð°Ð°Ñ <i>http://greenstone.org</i> Ñ
+Ð°ÐœÐŽÐ°Ðœ
+GNU ÐÐžÐ¹ÑÐžÐ¹Ðœ ÐÑÓ©ÐœÑ
+ÐžÐ¹ ÐÐžÑÐµÐœÐ·-ÐžÐ¹Ðœ ÐœÓ©Ñ
+ÑÐ»ÐžÐ¹Ðœ ÐŽÐŸÐŸÑ Ð°Ð²Ð°Ñ
+Ð°ÐŽ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹.}
+
+_textgreenstone2_ [l=mn] {ÐšÐžÐœÑ ÐÐµÐ°Ð»Ð°ÐœÐŽÑÐœ ÐÐžÐ¶ÐžÑÐ°Ð» ÐÐŸÐŒÑÐœ Ð¡Ð°ÐœÐ³ÐžÐ¹Ðœ Ð²ÑÐ± Ñ
+ÑÑÐŽÐ°Ñ ÐœÑ (<a
+href="http://nzdl.org">http://nzdl.org</a>) Ð±Ó©Ð³Ó©Ó©ÐŽ Greenstone -Ñ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐ°Ð°Ñ Ñ
+ÐžÐ¹Ð³ÐŽÑÑÐœ  
+ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÐŸÐ»ÐŸÐœ ÑÐœÐ·ÑÐœ Ð¶ÐžÑÑÑÐ³ Ð°Ð³ÑÑÐ»ÐŽÐ°Ð³ ÑÑÐ» ÑÐ° ÑÒ¯Ò¯ÐœÐžÐ¹Ð³ ÑÓ©Ð»Ó©Ó©ÑÑÐ¹ ÑÑÐŽÐ°Ð»Ð¶ Ð±ÐŸÐ»ÐŸÑ
+ ÑÐŒ. 
+Ð¢ÑÐŽÐ³ÑÑÑ Ð¶ÐžÑÑÑÐœÒ¯Ò¯ÐŽ ÐœÑ ÐÑÐ°Ð±, Ð¥ÑÑÐ°ÐŽ, Ð€ÑÐ°ÐœÑ, ÐÐ°ÑÑÐž Ð±ÐŸÐ»ÐŸÐœ ÐÑÐ¿Ð°ÐœÐž ÑÑÐ³ÑÑÐŽ ÐÐœÐ³Ð»Ðž Ð·ÑÑÑÐ³ 
+Ð·ÑÑÑÐ³ Ñ
+ÑÐ» ÐŽÑÑÑÑ
+Ðž ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ð°Ð³ÑÑÐ»ÐŽÐ°Ð³ Ð±Ð° Ñ
+ÑÐ²ÐžÐ»Ð±Ð°ÑÑÐ³ Ñ
+ÑÑÑ
+ÑÐœ Ò¯Ð·ÑÑ
+, ÑÐ°ÐœÐŽ Ñ
+ÑÑÑ
+ÑÐœ   
+Ñ
+Ð°Ð¹Ð»Ñ Ñ
+ÐžÐ¹Ñ
+ Ð·ÑÑÑÐ³ Ð·Ò¯Ð¹Ð»ÑÐžÐ¹Ðœ ÐŸÐ»ÐŸÐœ ÑÐœÐ·ÑÐœ Ñ
+ÑÐ²ÐžÐ»Ð±Ð°ÑÑÐ³ Ð°Ð³ÑÑÐ»ÐŽÐ°Ð³. ÐÓ©Ðœ Ð·Ð°ÑÐžÐŒ Ñ
+Ó©Ð³Ð¶ÐŒÐžÐ¹Ðœ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ñ ÑÐ° ÐŸÐ»Ð¶ Ð±ÐŸÐ»ÐœÐŸ.}
+
+_textplatformtitle_ [l=mn] {platform}
+_textgreenstone3_ [l=mn] {Greenstone ÐœÑ Windows, Unix Ð±ÐŸÐ»ÐŸÐœ Mac Ò¯Ð¹Ð»ÐŽÐ»ÐžÐ¹Ðœ ÑÐžÑÑÐµÐŒÒ¯Ò¯ÐŽ ÐŽÑÑÑ Ð°Ð¶ÐžÐ»Ð»Ð°ÐŽÐ°Ð³. ÐÐžÐ¹ÑÑÐŽ ÑÒ¯Ð³ÑÑÑÑÐœ Ñ
+ÑÐ²ÐžÐ»Ð±Ð°Ñ ÐœÑ 
+Windows, Ð±ÐŸÐ»ÐŸÐœ Linux ÐŒÓ©Ðœ Mac X Ò¯Ð¹Ð»ÐŽÐ»ÐžÐ¹Ðœ ÑÐžÑÑÐµÐŒÐžÐ¹Ðœ Ð±Ò¯Ñ
+ÐžÐ¹ Ð» Ñ
+ÑÐ²ÐžÐ»Ð±Ð°ÑÑ ÑÐŸÑ
+ÐžÑÑÐŸÐœ Ñ
+ÑÑÑÐ³Ð»ÑÑ
+ÑÐŽ Ñ
+ÑÐ»Ð±Ð°Ñ Ð±ÐžÐœÐ°ÑÑÑÐŽÑÐ³ Ð°Ð³ÑÑÐ»ÐŽÐ°Ð³. 
+ÐÓ©Ðœ ÐÐžÐºÑÐŸÑÐŸÑÑ C++ ÑÑÐ²ÑÐ» gcc Ñ
+ÑÑÑÐ³Ð»ÑÐœ ÐŽÑÑÑ ÐœÑ Ð°Ð¶ÐžÐ»Ð»Ð°Ð¶ Ð±ÐŸÐ»ÐŸÐœ Ð±Ò¯Ñ
+ÑÐ» Ð±Ò¯ÑÑÐœ source code Ð°Ð³ÑÑÐ»ÐŽÐ°Ð³.
+Greenstone ÐœÑ Apache Webserver Ð±ÐŸÐ»ÐŸÐœ PERL-ÑÑÐ¹ Ð·ÐŸÑ
+ÐžÑÐŸÐ¶ Ð°Ð¶ÐžÐ»Ð»Ð°ÐŽÐ°Ð³ 
+Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐžÐœÑÐµÑÑÑÐ¹Ñ ÐœÑ Ð³ÐŸÐ»ÑÐ»ÐŸÐœ Netscape Navigator ÑÑÐ²ÑÐ» Internet Explorer Ñ
+ÑÑÑÐ³Ð»ÑÐŽÑÐ³.}
+
+_textgreenstone4_ [l=mn] {ÐÐ»ÐŸÐœ Ð±ÐžÑÐžÐ³ Ð±Ð°ÑÐžÐŒÑÑÐœ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Greenstone-ÐžÐ¹ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑÐ³ Ð°ÑÐžÐ³Ð»Ð°Ð¶ Ñ
+ÐžÐ¹ÑÑÐœ 
+CD-ROM -ÐŸÐŸÑ ÐŸÐ»ÐŸÐœ ÐœÐžÐ¹ÑÑÐŽ Ñ
+Ò¯ÑÑÑÐœ. ÐÐžÑÑÑ ÐœÑ, <i>Ð¥Ò¯ÐŒÒ¯Ò¯ÐœÐ»ÐžÐ³ÐžÐ¹Ðœ Ð¥Ó©Ð³Ð¶Ð»ÐžÐ¹Ðœ ÐÐŸÐŒÑÐœ Ð¡Ð°Ðœ</i> ÐœÑ 
+ÐœÑÐ³ÑÐ»Ð°Ðœ Ð±ÐŸÐŽÐŸÑ
+ Ð±Ò¯ÑÑÐ³ÑÐ»ÑÑÑ Ð°Ð²Ð°Ñ
+ÑÑÐ»Ð°Ð°ÐŽ ÑÑÐœÑ Ð°ÑÐžÑÐœ ÑÑÐ²ÑÑ Ñ
+Ò¯ÑÑÑÐ» 1,230 Ñ
+ÑÐ²Ð»ÑÐ»ÐžÐ¹Ð³ Ð°Ð³ÑÑÐ»ÑÐ°Ðœ Ð±Ð°Ð¹ÐŽÐ°Ð³. 
+Ð­ÐœÑ ÐœÑ ÐžÑ
+ÑÐœÑ
+Ðž Ñ
+Ó©Ð³Ð¶ÐžÐ¶ Ð±ÑÐ¹ ÑÐ»Ñ ÐŸÑÐŸÐœÐŽ Ð±Ð°Ð¹ÐŽÐ°Ð³ Ñ
+Ò¯ÑÐžÐœ ÑÐ°ÐŽÐ°Ð» ÐŒÑÑÑÐ°Ð¹ ÐºÐŸÐŒÐ¿ÑÑÑÐµÑ ÐŽÑÑÑ Ñ Ð°Ð¶ÐžÐ»Ð»Ð°ÐŽÐ°Ð³.
+ÐÐ³ÑÑÐ»Ð°Ð³ÐŽÑÐ°Ðœ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ ÐœÑÑ, ÑÑÐŽÑÐ², Ð±Ð°Ð¹Ð³ÑÑÐ»Ð»Ð°Ð³Ð°, Ð°ÐœÐ³ÐžÐ»Ð°Ð³ÐŽÑÐ°Ðœ Ð¶Ð°Ð³ÑÐ°Ð°Ð»Ñ Ð·ÑÑÐ³ÑÑÑ ÐœÑ Ñ
+Ð°Ð¹Ñ
+, ÑÐ°ÑÐ°Ð¶ Ò¯Ð·ÑÑ
+ Ð±ÐŸÐ»ÐŸÐœ 
+ÐœÐŸÐŒÑÐœ ÐœÒ¯Ò¯ÑÐžÐ¹Ð³ ÐœÑ ÑÑÑÐŽ Ð¶Ð°Ð³ÑÐ°Ð°Ðœ Ñ
+Ð°ÑÐ°Ñ
+ Ð·ÑÑÐ³ÑÑÑ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ ÑÑÐ¶ Ò¯Ð·ÑÐ¶ Ð±ÐŸÐ»ÐœÐŸ.}
+
+_textcustomisationtitle_ [l=mn] {Ñ
+ÑÐ²ÐžÐ¹Ðœ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ}
+_textgreenstone5_ [l=mn] {Greenstone ÑÐžÑÑÐµÐŒÐžÐ¹Ð³ Ó©ÑÐ³Ó©ÑÐ³Ó©Ñ
+ Ð±ÐŸÐ»ÐŸÐœ Ñ
+ÑÐ²ÐžÐ¹Ðœ ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ Ñ
+ÐžÐ¹Ñ
+ ÐŒÐ°Ñ Ó©ÑÐ³Ó©Ðœ
+Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹Ð³ÐŸÐŸÑ Ñ
+ÐžÐ¹ÑÑÐœ Ð±Ð°Ð¹ÐœÐ°. ÐšÐžÐœÑ Ð±Ð°ÑÐžÐŒÑ Ð±ÐŸÐ»ÐŸÐœ ÐŒÐµÑÐ°-Ó©Ð³Ó©Ð³ÐŽÓ©Ð»Ò¯Ò¯ÐŽÐžÐ¹Ðœ
+ÑÐŸÑÐŒÐ°ÑÑÑÐŽÑÐ³ "plugin" Ð±ÐžÑÑÑÐŽ (Perl Ñ
+ÑÐ»ÑÑÑ) ÑÐŸÑ
+ÐžÑÑÑÐ»ÑÐ°Ðœ. ÐÓ©Ðœ ÑÐžÐœÑ
+ÐŒÐµÑÐ°-Ó©Ð³Ó©Ð³ÐŽÓ©Ð» Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ñ
+Ð°ÑÐ°Ñ
+ Ð±Ò¯ÑÑÒ¯Ò¯ÐŽÐžÐ¹Ð³ "Ð°ÐœÐ³ÐžÐ»Ð°Ð³Ñ" Ð±ÐžÑÑÑÐŽ Ð» Ñ
+ÑÑÑÐ³Ð»ÑÑ
+
+Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹. Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ Ñ
+Ð°ÑÑ ÐŒÑÐŽÑÑÑ
+ ÐžÐœÑÐµÑÑÑÐ¹ÑÐžÐ¹Ð³ ÑÐœÐ³ÐžÐ¹Ðœ ÐŒÐ°ÐºÑÐŸ
+Ñ
+ÑÐ» Ð°ÑÐžÐ³Ð»Ð°Ðœ Ð±ÐžÑÑÑÐœ "ÐŒÐ°ÐºÑÐŸ" Ð°ÑÐžÐ³Ð»Ð°Ðœ Ó©Ó©ÑÑÐ»Ó©Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹. ÐÐŸÑÐ±Ð°
+Ð¿ÑÐŸÑÐŸÐºÐŸÐ»ÑÐœ ÑÑÑÐ»Ð°ÐŒÐ¶ÑÐ°Ð¹Ð³Ð°Ð°Ñ Ð°Ð³ÐµÐœÑÑÑÐŽ (Java Ð³ÑÑ
+ ÐŒÑÑ) Ð±Ð°ÑÐžÐŒÑÑÐ°Ð¹
+Ñ
+ÐŸÐ»Ð±ÐŸÐŸÑÐŸÐ¹ Ð±Ò¯Ñ
+ Ð» ÑÓ©ÑÐ»ÐžÐ¹Ðœ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÑÐŽÑÐ³ Ð°ÑÐžÐ³Ð»Ð°Ð¶ Ð±ÐŸÐ»ÐœÐŸ. Ð­ÑÑÑÑ ÐœÑ,
+Ó©Ó©ÑÑÐ»Ó©Ð»Ñ ÐŸÑÑÑÐ»Ð°Ñ
+Ð°Ð°Ñ Ð±ÐŸÐ» C++ Ð±ÐŸÐ»ÐŸÐœ Perl Ñ
+ÑÐ»ÑÑÑ Ð±ÐžÑÑÑÐœ ÑÑ
+ ÐºÐŸÐŽ ÐœÑ
+Ð±Ð°Ð¹Ð³Ð°Ð°.}
+
+_textdocumentationtitle_ [l=mn] {Ð±ÐžÑÐžÐ³ Ñ
+ÑÑÐ³ÐžÐ¹Ðœ Ñ
+Ó©ÑÐ»Ó©Ð»Ñ}
+_textdocuments_ [l=mn] {Greenstone-ÐžÐ¹ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ Ñ
+Ð°ÐœÐ³Ð°ÐŒÐ¶ÐžÐœÐŽ ÐœÑÐŒÑÐ»Ñ Ð±ÐžÑÐžÐ³ Ñ
+ÑÑÐ³ÐžÐ¹Ðœ Ñ
+Ó©ÑÐ»Ó©Ð»Ñ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹.}
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=mn] {Ðž-ÐŒÑÐ¹Ð» Ñ
+Ð°ÑÐ³ÐžÐ¹Ðœ Ð¶Ð°Ð³ÑÐ°Ð°Ð»Ñ}
+_textmailinglist_ [l=mn] {Greenstone-ÐžÐ¹ ÐŽÐžÐ¶ÐžÑÐ°Ð» ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÐ³ÑÐœ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐŽ ÑÑÑ
+Ð°Ð¹ Ð°ÐœÑ
+ÐœÑ Ñ
+ÑÐ»ÑÐ»ÑÒ¯Ò¯Ð»ÑÐ³Ñ  
+Ð·ÐŸÑÐžÑÐ»ÑÐ°Ðœ Ðž-ÐŒÑÐ¹Ð»ÑÐœ Ð¶Ð°Ð³ÑÐ°Ð°Ð»Ñ Ð±Ð°Ð¹ÐŽÐ°Ð³. Greenstone-ÐžÐ¹ ÐžÐŽÑÐ²Ñ
+ÑÑÐœ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐŽ 
+Ðž-ÐŒÑÐ¹Ð»ÑÐœ Ð¶Ð°Ð³ÑÐ°Ð°Ð»ÑÐ°ÐœÐŽ Ð±Ò¯ÑÑÐ³Ò¯Ò¯Ð»ÑÐœ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑÐœ ÑÑÑ
+Ð°Ð¹ Ñ
+ÑÐ»ÑÐ»ÑÑÐœ Ó©Ó©ÑÐžÐ¹Ðœ ÑÐ°ÐœÐ°Ð» Ð±ÐŸÐŽÐŸÐ», Ñ
+ÑÐ²Ñ ÐœÑÐŒÑÐžÐ¹Ð³ ÐŸÑÑÑÐ»Ð¶ Ð±ÐŸÐ»ÐœÐŸ. 
+Ò®Ò¯ÐœÐŽ Ð±Ò¯ÑÑÐ³Ò¯Ò¯Ð»ÑÑ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ ÐŽÐ°ÑÐ°Ð°Ñ
+ Ñ
+Ð°ÑÐ³ ÑÑÑ Ñ
+Ð°ÐœÐŽÐ°Ñ
+ Ñ
+ÑÑÑÐ³ÑÑÐ¹, <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>. 
+
+ÐÐ°Ð³ÑÐ°Ð°Ð»ÑÐ°ÐœÐŽ Ð±Ò¯ÑÑÐ³Ò¯Ò¯Ð»ÑÑÐœ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐŽ ÑÒ¯Ò¯ Ð·Ð°Ñ
+ÐžÐ°, ÐŒÑÐŽÑÑ ÐžÐ»Ð³ÑÑÑ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ ÑÐœÑ Ñ
+Ð°ÑÐ³ ÑÑÑ Ð±ÐžÑÑÑÑÑÐ¹ <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>.}
+
+_textbugstitle_ [l=mn] {ÑÐžÑÑÐµÐŒÐžÐ¹Ðœ Ð³Ð°Ð¶ÐžÐ³}
+_textreport_ [l=mn] {Ð­ÐœÑÑ
+Ò¯Ò¯ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ Ñ
+ÑÐ²ÐžÐ¹Ðœ Ð°Ð¶ÐžÐ»Ð»Ð°Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° ÑÑÑÑ
+ ÑÑÑ
+Ð°Ð¹ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ Ð±ÐŸÐ»ÐŸÐœ Ð°Ð»ÐŽÐ°Ð° ÐŽÐŸÐ³ÐŸÐ»ÐŽÐ»ÑÐœ ÑÐ°Ð»Ð°Ð°Ñ Ð±ÐžÐŽÑÐœÐŽ 
+ÐŽÐ°ÑÐ°Ð°Ñ
+ Ñ
+Ð°ÑÐ³Ð°Ð°Ñ ÐŒÑÐŽÑÑÐ»ÐœÑ Ò¯Ò¯.  <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>}
+
+_textgs3title_ [l=mn] {Ð°Ð¶ÐžÐ»ÐŽ}
+_textgs3_ [l=mn] {Greenstone 3 Ð³ÑÐŽÑÐ³ ÐœÑ Greenstone 2 (ÐŸÐŽÐŸÐŸÐ³ÐžÐ¹Ðœ Ñ
+ÑÐ²ÐžÐ»Ð±Ð°Ñ) -ÑÐœ
+Ð±Ò¯Ñ
+ÐžÐ¹ Ð» ÐŽÐ°Ð²ÑÑ ÑÐ°Ð»ÑÑÐŽÑÐ³ ÑÐžÐœÐ³ÑÑÑÑÐœ ÐŽÐ°Ñ
+ÐžÐœ Ð±ÐŸÐ»ÐŸÐ²ÑÑÑÑÐ»Ð°Ð³ÐŽÐ°Ð¶,
+ÑÐ°Ð¹Ð¶ÑÑÑÐ»Ð°Ð³ÐŽÑÐ°Ðœ Ñ
+ÑÐ²ÐžÐ»Ð±Ð°Ñ-Ð¶ÐžÑÑÑ ÐœÑ: ÐŸÐ»ÐŸÐœ Ñ
+ÑÐ»ÐœÐžÐ¹ ÑÐŸÐœÐ³ÐŸÐ»ÑÑÐŸÐ¹,
+ÐŸÐ»ÐŸÐœ ÑÓ©ÑÐ»ÐžÐ¹Ðœ Ò¯Ð¹Ð»ÐŽÐ»ÐžÐ¹Ðœ ÑÐžÑÑÐµÐŒ, ÐŸÑÑÐžÐœÐŽ Ð°Ð¶ÐžÐ»Ð»Ð°ÐŽÐ°Ð³ Ð±ÐŸÐ»ÐŸÐœ Ó©Ó©ÑÑÐ»Ó©Ðœ
+Ð·ÐŸÑ
+ÐžÐŸÐœ Ð±Ð°Ð¹Ð³ÑÑÐ»Ð°Ñ
+Ð°ÐŽ ÑÑÐ¹Ð»ÑÐœ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹. ÐÓ©Ðœ ÑÒ¯Ò¯ÐœÑÐ»ÑÐœ ÑÑÑÐŽÐœÑ
+Ñ
+ÑÐ²ÐžÐ»Ð±Ð°ÑÑÑÐŽÑÐ°Ð¹ Ð·ÐŸÑ
+ÐžÑÐŸÐœ Ð°Ð¶ÐžÐ»Ð»Ð°ÐŽÐ°Ð³: ÑÐœÑ ÐœÑ ÑÑÑÐŽ Ñ
+ÐžÐ¹Ð³ÐŽÑÑÐœ
+Ð±Ð°Ð¹ÑÐ°Ðœ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ ÑÐŒÐ°Ñ ÐœÑÐ³ÑÐœ Ó©Ó©ÑÑÐ»Ó©Ð»ÑÐ³Ò¯Ð¹Ð³ÑÑÑ ÐŽÐ°Ñ
+ÐžÐœ Ñ
+ÐžÐ¹Ð¶
+Ð°Ð¶ÐžÐ»Ð»ÑÑÐ»Ð¶ Ð±ÐŸÐ»ÐœÐŸ Ð³ÑÑÑÐœ Ò¯Ð³ ÑÐŒ. Java Ñ
+ÑÐ»ÑÑÑ Ð±ÐžÑÐžÐ³ÐŽÑÑÐœ Ð±Ð° ÑÐœÑ
+ÐœÑ Ð±ÐžÐµ Ð±ÐžÐµÑ ÐŽÐ°Ð°ÑÐ°Ðœ Ñ
+ÐŸÐŸÑÐŸÐœÐŽÐŸÐŸ XML-ÑÑÑ Ñ
+Ð°ÑÑÑÐŽÐ°Ð³ ÐŒÐŸÐŽÑÐ»ÑÑÐŽÑÐœ
+ÑÒ¯Ð»Ð¶ÑÑ Ñ
+ÑÐ»Ð±ÑÑÑÑÑ Ð±Ò¯ÑÑÑÐ»ÑÐ³ÐŽÑÑÐœ: ÐÐ¹ÐŒÑÑÑ ÑÐœÑ ÐœÑ ÐœÐžÐ¹ÑÑÐŽ ÑÒ¯Ð³ÑÑÑÑÐœ
+Ñ
+ÑÐ²ÐžÐ»Ð±Ð°ÑÐ°Ð°ÑÐ°Ð° Ð°Ð¶ÐžÐ»Ð»Ð°Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð° Ð±Ó©Ð³Ó©Ó©ÐŽ Ñ
+ÑÑÑÐ³ÑÑÐ¹ ÑÐŸÑ
+ÐžÐŸÐ»ÐŽÐŸÐ»ÐŽ
+Ó©Ó©Ñ ÑÐµÑÐ²ÐµÑÒ¯Ò¯ÐŽÑÐŽ ÑÒ¯Ð³ÑÑÐ³ÐŽÑÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹. Ð­ÐœÑÑ
+Ò¯Ò¯ ÐœÑÐ³ ÑÑÐ°ÐœÐŽÐ°ÑÑÑÐ³
+Ð±Ð°ÑÐžÐŒÑÐ°Ð»ÑÐ°Ðœ Ð·Ð°Ð³Ð²Ð°Ñ ÐœÑ Greenstone-ÑÐ³ Ó©ÑÐ³Ó©Ðœ Ñ
+ÑÑÑÐ³Ð»ÑÑÑÑÐ¹ ÐžÐ»Ò¯Ò¯
+Ñ
+ÑÑÑÐ³Ð»ÑÑ
+ÑÐŽ ÐŽÓ©Ñ
+Ó©ÐŒ Ð±ÐŸÐ»Ð³ÐŸÐ¶ Ð±Ð°Ð¹ÐœÐ°. Greenstone 3-ÑÐœ Ð±ÐžÑÐžÐ³ Ñ
+ÑÑÑÐ³
+Ñ
+Ó©ÑÐ»Ó©Ð»ÑÐžÐ¹Ðœ Ð±ÐŸÐ»ÐŸÐœ ÑÑÑÑÐžÐ»ÑÑÐœ Ñ
+ÑÐ²ÐžÐ»Ð±Ð°ÑÑÑÐŽÑÐ³
+<a href="http://www.greenstone.org/greenstone3.html">Greenstone 3 home page</a> Ð³ÑÑÑÐœ Ñ
+Ð°ÑÐ³Ð°Ð°Ñ ÐŸÑÐ¶ ÑÐ°ÑÐ°Ð¶ Ð°Ð²Ñ Ð±ÐŸÐ»ÐœÐŸ.}
+
+_textcreditstitle_ [l=mn] {ÑÐžÑÑÐµÐŒÐžÐ¹Ðœ Ð±Ò¯ÑÑÑÐ³ÑÐžÐŽ}
+
+_textwhoswho_ [l=mn] {Greenstone-ÐžÐ¹ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ Ñ
+Ð°ÐœÐ³Ð°ÐŒÐ¶ ÐœÑ ÐŸÐ»ÐŸÐœ Ñ
+Ò¯ÐœÐžÐ¹ Ñ
+Ò¯ÑÐžÐœ ÑÐ°ÑÐŒÐ°Ð¹Ð»Ñ, Ñ
+Ð°ÐŒÑÑÐœ Ð°Ð¶ÐžÐ»Ð»Ð°Ð³Ð°Ð°ÐœÑ Ò¯Ñ ÐŽÒ¯ÐœÐŽ Ð±Ò¯ÑÑÑÐœ. 
+Rodger McNab Ð±ÐŸÐ»ÐŸÐœ Stefan Boddie ÐœÐ°Ñ ÐœÑ Ð³ÐŸÐ» Ò¯ÐœÐŽÑÑÐœ Ð±Ò¯ÑÑÐžÐ¹Ð³ Ñ
+ÐžÐ¹ÑÑÐœ ÑÐŒ. 
+ÓšÓ©ÑÑÐŽÐžÐ¹Ðœ Ñ
+ÑÐ²Ñ ÐœÑÐŒÑÐžÐ¹Ð³ ÐŸÑÑÑÐ»ÑÐ°Ðœ Ñ
+Ò¯ÐŒÒ¯Ò¯Ñ David Bainbridge, George
+Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John
+McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd
+Reed, Bill Rogers, John Thompson, and Stuart Yeates. ÐšÐžÐœÑ ÐÐµÐ°Ð»Ð°ÐœÐŽÑÐœ ÐÐžÐ¶ÐžÑÐ°Ð» ÐÐŸÐŒÑÐœ Ð¡Ð°ÐœÐ³ÐžÐ¹Ðœ ÐŽÐŸÐŸÑ ÐœÑÑ Ð±Ò¯Ñ
+ÐžÐ¹ Ð³ÐžÑÒ¯Ò¯ÐŽ 
+ÑÐžÑÑÐµÐŒÐžÐ¹Ðœ Ð±Ò¯ÑÑÐžÐ¹Ð³ ÑÐ°Ð¹Ð¶ÑÑÑÐ»Ð°Ñ
+Ð°Ð» Ó©Ó©ÑÑÐŽÐžÐ¹Ðœ ÑÑÑÐ³ÑÐ» Ð·Ò¯ÑÑ
+ÐžÐ¹Ð³ Ð³Ð°ÑÐ³Ð°Ðœ ÑÑÑÐ°Ð»ÑÐ°Ðœ: Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka
+Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols and Lloyd Smith. ÐÓ©Ðœ Ð±ÐžÐŽ ÐŽÐ°ÑÐ°Ð°Ñ
+ Ð±Ð°Ð³ÑÑÐ³ ÑÒ¯Ð³ÑÑÑ
+ÑÐŽ Ð³Ò¯Ðœ ÑÑÑÐ»Ð°Ð»ÑÐ°Ð° Ò¯Ð·Ò¯Ò¯Ð»ÑÑÐœ Ñ
+Ò¯ÐŒÒ¯Ò¯ÑÑ Ñ ÑÐ°Ð»Ð°ÑÑ
+Ð»Ð°Ð° ÐžÐ»ÑÑÑ
+ÐžÐ¹Ð»ÑÐµ. GNU-Ð»ÐžÑÐµÐœÐ·ÑÑÐ¹ Ð±Ð°Ð³Ñ:MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE Ð±ÐŸÐ»ÐŸÐœ XLHTML}
+
+_textaboutgslong_ [l=mn] {greenstone Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ Ñ
+Ð°ÐœÐ³Ð°ÐŒÐ¶ÐžÐ¹Ðœ ÑÑÑ
+Ð°Ð¹}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐŽÐžÐ¹Ðœ Ð¶Ð°Ð³ÑÐ°Ð°Ð»Ñ}
+_textuser_ [l=mn] {Ñ
+ÑÑÑÐ³Ð»ÑÐ³Ñ}
+_textas_ [l=mn] {Ñ
+Ð°ÑÐ³ÐžÐ¹Ðœ ÑÑÐ°ÑÑÑ}
+_textgroups_ [l=mn] {Ð±Ò¯Ð»Ð³Ò¯Ò¯ÐŽ}
+_textcomment_ [l=mn] {ÑÐ°Ð¹Ð»Ð±Ð°Ñ}
+_textadduser_ [l=mn] {ÑÐžÐœÑ Ñ
+ÑÑÑÐ³Ð»ÑÐ³Ñ ÐœÑÐŒÑÑ
+}
+_textedituser_ [l=mn] {Ó©Ó©ÑÑÐ»Ó©Ñ
+}
+_textdeleteuser_ [l=mn] {ÑÑÑÐ³Ð°Ñ
+}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ Ó©Ó©ÑÑÐ»Ó©Ñ
+}
+_textadduser_ [l=mn] {ÐšÐžÐœÑ Ñ
+ÑÑÑÐ³Ð»ÑÐ³Ñ ÐœÑÐŒÑÑ
+}
+
+_textaboutusername_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐœÑÑ 2-30 ÑÑÐŒÐŽÑÐ³ÑÑÑÑ Ð±Ò¯ÑÐŽÑÑÐœ Ð±Ð°Ð¹Ñ
+ ÑÑÑÐŸÐ¹ Ð±Ó©Ð³Ó©Ó©ÐŽ  Ò¯ÑÑÐ³
+ÑÐŸÐŸ Ð±ÐŸÐ»ÐŸÐœ '.', '_' Ð³ÑÑÑÐœ ÑÑÐŒÐŽÑÐ³ÑÒ¯Ò¯ÐŽÐžÐ¹Ð³ Ð°Ð³ÑÑÐ»ÑÐ°Ðœ Ð±Ð°Ð¹Ð¶ Ð±ÐŸÐ»ÐœÐŸ.}
+
+_textaboutpassword_ [l=mn] {ÐÑÑÑ Ò¯Ð³ 3-8 ÑÑÐŒÐŽÑÐ³ÑÑÑÑ Ð±Ò¯ÑÐŽÑÑÐœ Ð±Ð°Ð¹Ñ
+ ÑÑÑÐŸÐ¹ Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÐœÐ³ÐžÐ¹Ðœ Ñ
+ÑÐ²Ð»ÑÐ³ÐŽÑÑ
+
+Ð±ÐŸÐ»ÐŸÐŒÐ¶ Ð±Ò¯Ñ
+ÐžÐ¹ ASCII ÑÑÐŒÐŽÑÐ³ÑÒ¯Ò¯ÐŽÐžÐ¹Ð³ Ð°Ð³ÑÑÐ»ÑÐ°Ðœ Ð±Ð°Ð¹Ð¶ Ð±ÐŸÐ»ÐœÐŸ.}
+
+_textoldpass_ [l=mn] {Ð¥ÑÑÑÐ² ÑÐœÑ Ð·Ð°Ð¹Ð³ Ñ
+ÐŸÐŸÑÐŸÐœ Ò¯Ð»ÐŽÑÑÐ²ÑÐ» Ñ
+ÑÑÑÐžÐœ ÐœÑÑÑ Ò¯Ð³ ÑÐ°ÐœÑ Ñ
+ÑÐ²ÑÑÑÑÑ Ñ
+Ð°ÐŽÐ³Ð°Ð»Ð°Ð³ÐŽÐ°Ñ
+ Ð±ÐŸÐ»ÐœÐŸ.}
+_textenabled_ [l=mn] {ÐžÐŽÑÐ²Ñ
+ÐžÐ¶ÑÑÐœ}
+_textdisabled_ [l=mn] {Ñ
+Ò¯ÑÐžÐœÐ³Ò¯Ð¹ Ð±ÐŸÐ»Ð³ÐŸÑÐŸÐœ}
+
+_textaboutgroups_ [l=mn] {ÐÒ¯Ð»Ð³Ò¯Ò¯ÐŽ ÐœÑ ÑÐ°ÑÐ»Ð°Ð»Ð°Ð°Ñ ÑÑÑÐ³Ð°Ð°ÑÐ»Ð°Ð³ÐŽÑÐ°Ðœ Ð¶Ð°Ð³ÑÐ°Ð°Ð»Ñ Ð±Ó©Ð³Ó©Ó©ÐŽ ÑÐ°ÑÐ»Ð°Ð»ÑÑÐŽÑÐœ Ð°ÑÐŽ Ð·Ð°Ð¹ Ð°Ð²Ð°Ñ
+Ð³Ò¯Ð¹.}
+
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ð³ ÑÑÑÐ³Ð°Ñ
+}
+_textremwarn_ [l=mn] {Ð¢Ð° <b>_cgiargumun_</b> Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ð³ Ð°ÑÐžÐ»Ð³Ð°Ñ
+ÑÐ³ Ñ
+Ò¯ÑÑ Ð±Ð°Ð¹ÐœÐ° ÑÑ?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=mn] {ÐÑÑÑ Ò¯Ð³ÐžÐ¹Ð³ Ó©Ó©ÑÑÐ»Ó©Ñ
+}
+_textoldpw_ [l=mn] {Ñ
+ÑÑÑÐžÐœ ÐœÑÑÑ Ò¯Ð³}
+_textnewpw_ [l=mn] {ÐšÐžÐœÑ ÐœÑÑÑ Ò¯Ð³}
+_textretype_ [l=mn] {ÑÐžÐœÑ ÐœÑÑÑ Ò¯Ð³ÑÑ ÐŽÐ°Ñ
+ÐžÐœ Ð±ÐžÑÐœÑ Ò¯Ò¯}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=mn] {Ð¢Ð°ÐœÑ ÐœÑÑÑ Ò¯Ð³ÐžÐ¹Ð³ Ð°ÐŒÐ¶ÐžÐ»ÑÑÐ°Ð¹ Ó©Ó©ÑÑÐžÐ»Ð»Ó©Ó©.}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐœÑÑ Ð±ÑÑÑÑ Ð±Ð°Ð¹ÐœÐ°.}
+_textinvalidpassword_ [l=mn] {ÐÑÑÑ Ò¯Ð³ Ð±ÑÑÑÑ Ð±Ð°Ð¹ÐœÐ°.}
+_textemptypassword_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ Ð°ÐœÑ
+ÐœÑ ÐœÑÑÑ Ò¯Ð³ÑÑ ÐŸÑÑÑÐ»ÐœÐ° ÑÑ}
+_textuserexists_ [l=mn] {Ð­ÐœÑ ÐœÑÑ ÑÐŸÐœÐ³ÐŸÐ³ÐŽÑÐŸÐœ Ð±Ð°Ð¹Ð³Ð°Ð° ÑÑÐ» ÑÐ° Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ Ó©Ó©Ñ ÐœÑÑ ÐŸÑÑÑÐ»ÐœÐ° ÑÑ}
+
+_textusernameempty_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐœÑÑÑÑ Ð±ÐžÑÐœÑ Ò¯Ò¯}
+_textpasswordempty_ [l=mn] {Ð¢Ð° Ñ
+ÑÑÑÐžÐœ ÐœÑÑÑ Ò¯Ð³ÑÑ ÐŸÑÑÑÐ»Ð°Ñ
+ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³Ð°ÑÐ°Ð¹}
+_textnewpass1empty_ [l=mn] {ÐšÐžÐœÑ ÐœÑÑÑ Ò¯Ð³ÑÑ ÐŸÑÑÑÐ»Ð°Ð°ÐŽ ÐŽÐ°ÑÐ°Ð° ÐœÑ ÐŽÐ°Ñ
+ÐžÐœ Ð±ÐžÑÐœÑ Ò¯Ò¯}
+_textnewpassmismatch_ [l=mn] {ÐšÐžÐœÑ ÐœÑÑÑ Ò¯Ð³ÐžÐ¹Ðœ Ñ
+ÐŸÑÑ Ñ
+ÑÐ»Ð±ÑÑ Ñ
+ÐŸÐŸÑÐŸÐœÐŽÐŸÐŸ ÑÐŸÑ
+ÐžÑÐŸÑ
+Ð³Ò¯Ð¹ Ð±Ð°Ð¹ÐœÐ°}
+_textnewinvalidpassword_ [l=mn] {Ð¢Ð° ÑÐŸÑ
+ÐžÑÐŸÑ
+Ð³Ò¯Ð¹ ÐœÑÑÑ Ò¯Ð³ ÐŸÑÑÑÐ»ÑÐ°Ðœ Ð±Ð°Ð¹ÐœÐ°}
+_textfailed_ [l=mn] {Ð¢Ð°ÐœÑ Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐœÑÑ ÑÐŒÑÑ ÐœÑÑÑ Ò¯Ð³ ÑÐ°ÐœÑ Ð±ÑÑÑÑ Ð±Ð°Ð¹ÐœÐ°}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=mn] {Greenstone Ñ
+ÑÐ²ÐžÐ»Ð±Ð°ÑÑÐœ ÐŽÑÐ³Ð°Ð°Ñ}
+_textframebrowser_ [l=mn] {Ð¢Ð° Ò¯Ò¯ÐœÐžÐ¹Ð³ Ñ
+Ð°ÑÐ°Ñ
+ÑÐœ ÑÑÐ»ÐŽ frame Ð±ÑÐ°ÑÐ·ÐµÑÑÐ°Ð¹ Ð±Ð°Ð¹Ñ
+ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³Ð°ÑÐ°Ð¹}
+_textusermanage_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐŒÐµÐœÐµÐ¶ÐŒÐµÐœÑ}
+_textlistusers_ [l=mn] {Ñ
+ÑÑÑÐ³Ð»ÑÐ³ÑÐŽÐžÐ¹Ð³ Ð¶Ð°Ð³ÑÐ°Ð°Ð»Ñ}
+_textaddusers_ [l=mn] {ÑÐžÐœÑ Ñ
+ÑÑÑÐ³Ð»ÑÐ³Ñ ÐœÑÐŒÑÑ
+}
+_textchangepasswd_ [l=mn] {ÐœÑÑÑ Ò¯Ð³ÑÑ ÑÐŸÐ»ÐžÑ
+}
+_textinfo_ [l=mn] {Ð¢ÐµÑ
+ÐœÐžÐºÐžÐ¹Ðœ ÐŒÑÐŽÑÑÐ»ÑÐ»}
+_textgeneral_ [l=mn] {ÐµÑÓ©ÐœÑ
+ÐžÐ¹}
+_textarguments_ [l=mn] {Ð°ÑÐ³ÑÐŒÐµÐœÑ}
+_textactions_ [l=mn] {Ò¯Ð¹Ð»ÐŽÐ»Ò¯Ò¯ÐŽ}
+_textbrowsers_ [l=mn] {Ð±ÑÐ°ÑÐ·ÐµÑÑÑÐŽ}
+_textprotocols_ [l=mn] {Ð¿ÑÐŸÑÐŸÐºÐŸÐ»ÑÑÐŽ}
+_textconfigfiles_ [l=mn] {Ð¢ÐŸÑ
+ÐžÑÐ³ÐŸÐŸÐœÑ ÑÐ°Ð¹Ð»ÑÑÐŽ}
+_textlogs_ [l=mn] {Ð¢ÑÐŒÐŽÑÐ³Ð»ÑÐ»Ò¯Ò¯ÐŽ}
+_textusagelog_ [l=mn] {Ñ
+ÑÑÑÐ³Ð»ÑÑÑÐœ ÑÑÐŒÐŽÑÐ³Ð»ÑÐ»}
+_textinitlog_ [l=mn] {Ð°ÐœÑ
+ÐœÑ ÑÑÐŒÐŽÑÐ³Ð»ÑÐ»}
+_texterrorlog_ [l=mn] {Ð°Ð»ÐŽÐ°Ð°ÐœÑ ÑÑÐŒÐŽÑÐ³Ð»ÑÐ»}
+_textadminhome_ [l=mn] {Ð°ÐŽÐŒÐžÐœÑ Ñ
+ÑÑÐŽÐ°Ñ}
+_textreturnhome_ [l=mn] {Greenstone ÑÑ
+Ð»ÑÐ» Ñ
+ÑÑÐŽÐ°Ñ}
+_titlewelcome_ [l=mn] {Ð£ÐŽÐžÑÐŽÐ»Ð°Ð³Ð°}
+_textmaas_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÐ¶ Ð±ÐŸÐ»ÐŸÑ
+ Ð·Ð°ÑÐ²Ð°Ñ Ð±ÐŸÐ»ÐŸÐœ Ð·ÐŸÑ
+ÐžÐŸÐœ Ð±Ð°Ð¹Ð³ÑÑÐ»Ð°Ð»ÑÑÐœ Ò¯Ð¹Ð»ÑÐžÐ»Ð³ÑÑÐœÒ¯Ò¯ÐŽ ÐœÑ}
+_textvol_ [l=mn] {ÐŸÐœÐ»Ð°Ð¹Ðœ ÑÑÐŒÐŽÑÐ³Ð»ÑÐ»ÐžÐ¹Ð³ Ñ
+Ð°ÑÐ°Ñ
+}
+_textcmuc_ [l=mn] {ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³ Ò¯Ò¯ÑÐ³ÑÑ
+, Ð°Ð²Ð°Ñ
+ Ð±ÐŸÐ»ÐŸÐœ ÑÐžÐœÑÑÐ»ÑÑ
+}
+_textati_ [l=mn] {CGI Ð°ÑÐ³ÑÐŒÐµÐœÑ Ð³ÑÑ
+ ÐŒÑÑ ÑÐµÑ
+ÐœÐžÐºÐžÐ¹Ðœ ÐŒÑÐŽÑÑÐ»ÑÐ»ÐŽ Ñ
+Ð°ÐœÐŽÐ°Ñ
+}
+
+_texttsaa_ [l=mn] {Ð­ÐŽÐ³ÑÑÑ Ò¯Ð¹Ð»ÑÐžÐ»Ð³ÑÑÐœÒ¯Ò¯ÐŽÑÐŽ ÐœÑÐ²ÑÑÑÑ
+ÐžÐ¹Ðœ ÑÑÐ»ÐŽ Ñ
+ÑÑÐŽÐ°ÑÐœÑ Ð·Ò¯Ò¯Ðœ Ð³Ð°Ñ ÑÐ°Ð»ÐŽ Ð±Ð°Ð¹Ð³Ð°Ð° ÑÐŸÐ²ÑÐœÑÑÐŽÑÐ³ Ð°ÑÐžÐ³Ð»Ð°ÐœÐ°.}
+
+_textcolstat_ [l=mn] {ÐŠÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÑÑÐ°ÑÑÑ}
+
+_textcwoa_ [l=mn] {build.cfg ÑÐ°Ð¹Ð» ÐœÑ Ð±Ð°Ð¹Ð³Ð°Ð°, ÑÐœÑÐžÑ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÑÐŸÐ¹, Ò¯Ò¯ÑÐ³ÑÑÑÐœ ÐŸÐ³ÐœÐŸÐŸÐœÑ
+ÑÐ°Ð»Ð±Ð°Ñ ÐœÑ Ñ
+Ò¯ÑÐžÐœÑÑÐ¹ (Ó©,Ñ
+. >0), ÐŒÓ©Ðœ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÑÑ
+Ð»ÑÐ»ÐžÐ¹Ðœ ÐºÐ°ÑÐ°Ð»ÐŸÐ³Ñ
+Ð±Ð°Ð¹Ð³Ð°Ð° Ð·ÑÑÑÐ³ ÑÐŸÑ
+ÐžÐŸÐ»ÐŽÐ»ÑÑÐŽÐ°ÐŽ Ð» "Ð°Ð¶ÐžÐ»Ð»Ð°Ð¶ Ð±Ð°Ð¹Ð³Ð°Ð°" Ñ
+ÑÐŒÑÑÐœ
+Ñ
+Ð°ÑÐ°Ð³ÐŽÐ°ÐœÐ°.}
+
+_textcafi_ [l=mn] {<i>ÑÐŸÐ²ÑÐ»ÐŸÐ»</i> ÐŽÑÑÑ ÐŽÐ°ÑÐ¶ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ Ñ
+Ð°ÑÐœÐ° ÑÑ}
+_textcctv_ [l=mn] {<i>ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°</i> ÐŽÑÑÑ ÐŽÐ°ÑÐ¶ ÑÑÐ³Ð»ÑÑÐ³ÑÐ³ Ñ
+Ð°ÑÐœÐ° ÑÑ}
+_textsubc_ [l=mn] {ÓšÓ©ÑÑÐ»Ó©Ð»ÑÒ¯Ò¯ÐŽÐžÐ¹Ð³ Ð±Ò¯ÑÑÐ³ÑÑ
+}
+_texteom_ [l=mn] {main.cfg ÑÐ°Ð¹Ð»ÑÐ³ ÐœÑÑÑ
+ÑÐŽ Ð°Ð»ÐŽÐ°Ð° Ð³Ð°ÑÐ»Ð°Ð°}
+_textftum_ [l=mn] {main.cfg ÑÐ°Ð¹Ð»ÑÐœ ÑÐžÐœÑÑÐ»ÑÐ»Ñ Ð°ÐŒÐ¶ÐžÐ»ÑÐ³Ò¯Ð¹ Ð±ÐŸÐ»Ð»ÐŸÐŸ}
+_textmus_ [l=mn] {main.cfg ÑÐ°Ð¹Ð»ÑÐ³ Ð°ÐŒÐ¶ÐžÐ»ÑÑÐ°Ð¹ ÑÐžÐœÑÑÐžÐ»Ð»ÑÑ}
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=mn] {_collectionname_ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð°ÐŽ Ð·ÐŸÑÐžÑÐ»Ð°Ðœ ÑÐŸÐ²ÑÐ»ÐŸÐ» Ò¯Ò¯ÑÐ³ÑÐœÑ Ò¯Ò¯}
+_textflog_ [l=mn] {_collectionname_ ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ Ð°Ð»ÐŽÐ°Ð°ÐœÑ ÑÑÐŒÐŽÑÐ³Ð»ÑÐ»}
+_textilog_ [l=mn] {"_collectionname_ " ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ Ñ
+ÑÐ²ÑÐŽ ÑÑÐŒÐŽÑÐ³Ð»ÑÐ» ÐŸÑÑÑÐ»Ð°Ñ
+ }  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=mn] {Ð¡Ð°ÐœÐ°Ð»Ð°Ð° ÑÐ²ÑÑÐ»Ð°Ñ
+}  
+
+_greenstoneusabilitytext_ [l=mn] {Greenstone ÑÐžÑÑÐµÐŒÐžÐ¹Ðœ Ñ
+ÑÑÑÐ³Ð»ÑÑ}
+
+_textwhy_ [l=mn] {<p>Ð¢Ð° ÑÐœÑ Ð²ÑÐ± Ñ
+ÑÑÐŽÑÑÐ³ Ò¯Ð·ÑÑ
+ÑÐŽ Ñ
+ÑÑÒ¯Ò¯ ÑÑÐ²ÑÐ» Ñ
+Ò¯ÐœÐŽÑÑÐ»ÑÑÐ¹ Ð±Ð°Ð¹ÑÐ°Ðœ ÑÑÐ» ÑÐœÑ ÐŒÑÐŽÑÑÐ³ ÐžÐ»Ð³ÑÑÐ¶ Ð±Ð°Ð¹ÐœÐ° Ð³ÑÑÑÐœ Ò¯Ð³ ÑÐŒ.}  
+_textextraforform_ [l=mn] {Ð¢Ð° ÐŒÐ°ÑÐ³Ñ Ð±Ó©Ð³Ð»Ó©Ñ
+ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³Ð°Ð³Ò¯Ð¹ - ÑÐŒÐ°Ñ Ñ ÐŒÑÐŽÑÑÐ»ÑÐ» Ñ
+ÑÑÑÐ³ÑÑÑÑÑÐ¹.}
+_textprivacybasic_ [l=mn] {Ð­ÐœÑ ÑÐ°Ð¹Ð»Ð°ÐœÐŽ ÑÐ°ÐœÑ Ò¯Ð·ÑÐ¶ Ð±Ð°Ð¹ÑÐ°Ðœ Greenstone Ð²ÑÐ± Ñ
+ÑÑÐŽÐ°Ñ Ð±ÐŸÐ»ÐŸÐœ ÑÒ¯Ò¯ÐœÐžÐ¹Ð³ Ò¯Ð·ÑÑ
+ÑÐŽ Ñ
+ÑÑÑÐ³Ð»ÑÑÑÐœ ÑÐµÑ
+ÐœÐŸÐ»ÐŸÐ³ÐžÐ¹Ðœ ÑÑÑ
+Ð°Ð¹ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ Ñ
+Ð°ÐŽÐ³Ð°Ð»ÐœÐ°. (ÑÐ°ÐœÑ ÐŸÑÑÑÐ»ÑÐ°Ðœ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ Ð±Ð°Ñ Ñ
+Ð°ÐŽÐ³Ð°Ð»ÐœÐ°)}  
+_textstillsend_ [l=mn] {Ð¢Ð° ÑÐœÑ ÑÐ°Ð¹Ð»Ð°ÐœÐ³ ÐžÐ»Ð³ÑÑÑ
+ÐžÐ¹Ð³ Ñ
+Ò¯ÑÑÐ¶ Ð±Ð°Ð¹ÐœÐ° ÑÑ?}  
+
+_texterror_ [l=mn] {Ð°Ð»ÐŽÐ°Ð°}
+_textyes_ [l=mn] {Ð¢ÐžÐ¹ÐŒ}  
+_textno_ [l=mn] {Ò®Ð³Ò¯Ð¹}  
+_textclosewindow_ [l=mn] {ÐŠÐŸÐœÑ
+ÑÐ³ Ñ
+Ð°Ð°Ñ
+}  
+_textabout_ [l=mn] {Ð¢ÑÑ
+Ð°Ð¹}
+_textprivacy_ [l=mn] {ÐÑÑÑ}
+_textsend_ [l=mn] {ÐÐ»Ð³ÑÑÑ
+}
+_textdontsend_ [l=mn] {ÐÒ¯Ò¯ ÐžÐ»Ð³ÑÑ}  
+_textoptionally_ [l=mn] {ÐÐ»Ð±Ð°Ð³Ò¯Ð¹}  
+
+_textunderdev_ [l=mn] {Ð¡Ò¯Ò¯Ð»ÐžÐ¹Ðœ Ñ
+ÑÐ²ÐžÐ»Ð±Ð°Ñ ÐŽÑÑÑ ÐœÐ°ÑÐžÐ¹Ð²ÑÐžÐ»ÑÐ°Ðœ ÐŒÑÐŽÑÑÐ»Ð»Ò¯Ò¯ÐŽÐžÐ¹Ð³ ÑÑÑÐŽÑÐžÐ»ÑÐ°Ðœ Ð±Ð°Ð¹ÐŽÐ»Ð°Ð°Ñ ÐœÑ Ñ
+Ð°ÑÐ¶ Ð±ÐŸÐ»ÐœÐŸ}  
+
+_textviewdetails_ [l=mn] {ÐÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ ÐŽÑÐ»Ð³ÑÑÑÐœÐ³Ò¯Ð¹Ð³ÑÑÑ Ñ
+Ð°ÑÐ°Ñ
+}  
+_textmoredetails_ [l=mn] {ÐÑÐ»Ð³ÑÑÑÐœÐ³Ò¯Ð¹}  
+_texttrackreport_ [l=mn] {Ð­ÐœÑ ÐŒÑÐŽÑÑÐ»Ð»ÐžÐ¹Ð³ ÑÐ°Ð»Ð³Ð°Ñ
+}  
+_textcharacterise_ [l=mn] {Ð­ÐœÑ ÑÐŒÐ°Ñ ÑÓ©ÑÐ»ÐžÐ¹Ðœ Ð°ÑÑÑÐŽÐ°Ð» Ð²Ñ}  
+_textseverity_ [l=mn] {ÐÑÑÑÐŽÐ°Ð» Ñ
+ÑÑ ÐœÐŸÑÑÐŸÐ¹ Ð²Ñ}  
+ 
+_textbadrender_ [l=mn] {Ð¥ÑÑÐŽÐ°Ñ Ñ
+ÑÐ²ÐžÐ¹Ðœ Ð±ÑÑ Ñ
+Ð°ÑÐ°Ð³ÐŽÐ°Ð¶ Ð±Ð°Ð¹ÐœÐ°}  
+_textcontenterror_ [l=mn] {ÐÐ³ÑÑÐ»Ð³ÑÐœ Ð°Ð»ÐŽÐ°Ð°}  
+_textstrangebehaviour_ [l=mn] {Ò®Ð» ÐŒÑÐŽÑÐ³ÐŽÑÑ
+ ÑÐžÐœÐ¶ ÑÑÐŒÐŽÑÐ³}  
+_textunexpected_ [l=mn] {Ð¯ÐŒÐ°Ñ ÐœÑÐ³ÑÐœ Ð³ÑÐœÑÑÐžÐ¹Ðœ Ð·Ò¯Ð¹Ð» ÑÐŸÑ
+ÐžÐŸÐ»ÐŽÐ»ÐŸÐŸ}  
+_textfunctionality_ [l=mn] {Ð¥ÑÑÑÐ³Ð»ÑÑ
+ÑÐŽ ÑÓ©Ð²Ó©Ð³ÑÑÐ¹}  
+_textother_ [l=mn] {ÐÑÑÐ°ÐŽ}  
+
+_textcritical_ [l=mn] {ÐÐŸÑÑÐŸÐ¹}  
+_textmajor_ [l=mn] {ÐÐŸÑÑÐŸÐ¹}  
+_textmedium_ [l=mn] {ÐÑÐœÐŽ Ð·ÑÑÑÐ³}  
+_textminor_ [l=mn] {ÐÐ°Ð³Ð°}  
+_texttrivial_ [l=mn] {Ð¯Ð»ÐžÐŒÐ³Ò¯Ð¹}  
+
+_textwhatdoing_ [l=mn] {Ð¢Ð° ÑÑ Ñ
+ÐžÐ¹Ñ
+ÑÑÑ ÐŸÑÐŸÐ»ÐŽÐŸÐ¶ Ð±Ð°Ð¹ÑÐ°Ðœ Ð±Ñ?}  
+_textwhatexpected_ [l=mn] {Ð¢Ð° ÑÑ ÑÐŸÑ
+ÐžÐŸÐ»ÐŽÐŸÐœÐŸ Ð³ÑÐ¶ Ñ
+Ò¯Ð»ÑÑÐ¶ Ð±Ð°Ð¹ÑÐ°Ðœ Ð±Ñ?}  
+_textwhathappened_ [l=mn] {Ð¯Ð³ ÑÑ Ð±ÐŸÐ»ÑÐŸÐœ Ð±Ñ?}  
+
+_cannotfindcgierror_ [l=mn] {<h2>Ð£ÑÑÐ»Ð°Ð°ÑÐ°Ð¹!</h2> "_linktextusab_" ÑÐŸÐ²ÑÐžÐœÐŽ Ñ
+Ð°ÑÐ³Ð°Ð»Ð·Ð°Ñ
+ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑÐ³ ÐŸÐ»ÑÐŸÐœÐ³Ò¯Ð¹.}  
+
+_textusabbanner_ [l=mn] {Greenstone-Ñ koru Ñ
+ÑÐ»Ð±ÑÑÐžÐ¹Ðœ Ð±Ð°ÐœÐœÐµÑ}
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=mn] {ÐÐ»ÐŽÐ°Ð° Ð³Ð°ÑÐ»Ð°Ð°}  
+
+_textgtihome_ [l=mn] {Ð­ÐŽÐ³ÑÑÑ Ñ
+ÑÑÐŽÐ°Ñ ÐœÑ ÑÐ°ÐœÑÐŽ Greenstone ÐŸÐ»ÐŸÐœ Ñ
+ÑÐ»ÑÑÐ¹ Ð°Ð¶ÐžÐ»Ð»Ð°Ñ
+ Ð°Ð¶ÐžÐ»Ð»Ð°Ð³Ð°Ð°Ð³ ÑÐ°Ð¹Ð¶ÑÑÑÐ»Ð°Ñ
+Ð°ÐŽ ÑÑÑÐ°Ð»ÐœÐ°. Ð­ÐŽÐ³ÑÑÑÐžÐ¹Ð³ Ð°ÑÐžÐ³Ð»Ð°ÑÐœÐ°Ð°Ñ ÑÐ°
+<ul>
+   <li>Greenstone Ñ
+ÑÑÐ³Ò¯Ò¯ÐŽÐžÐ¹Ð³ ÑÐžÐœÑ Ñ
+ÑÐ» ÑÒ¯Ò¯ Ñ
+Ó©ÑÐ²Ò¯Ò¯Ð»ÑÑ
+
+   <li>ÐÐœÐ³Ð»Ðž Ñ
+ÑÐ»ÑÐœÐŽ Ó©Ó©ÑÑÐ»Ó©Ð»Ñ Ð³Ð°ÑÐ°Ñ
+Ð°ÐŽ ÑÑÑ
+Ð°Ð¹Ðœ ÐŸÑÑÑÑÐ»Ð°Ð³ÐŽÑÐ°Ðœ Ñ
+ÑÐ»ÑÐœÐŽ Ð·Ð°ÑÐ²Ð°Ñ Ñ
+ÐžÐ¹Ñ
+
+   <li>ÐŸÑÑÑÑÐ»Ð°Ð³ÐŽÑÐ°Ðœ Ñ
+ÑÑÑÐ³Ñ Ð·Ð°ÑÐ²Ð°Ñ Ñ
+ÐžÐ¹Ñ
+
+</ul>
+You will be presented with a series of web pages, each containing
+a phrase to translate.
+You proceed by translating the language interface phrase by phrase.
+Many phrases contain HTML formatting commands: you should not
+attempt to translate these but preserve them intact in the translated
+version. Words flanked by underscores (like _this_) should not be
+translated either (they're Greenstone "macro" names).
+<p>
+If you are updating an existing language interface you will not be presented
+with phrases for which a translation already exists. Sometimes a translation
+exists but the English text has since been changed. In this case the current
+translation will be provided and you should check and update this if necessary.
+<p>
+To correct a translation that has already been updated, use the "Correct existing translations" facility available for each part of Greenstone.
+<p>
+Each page ends with a "_textgtisubmit_" button. When you press it, changes are
+made immediately to a separate Greenstone installation at nzdl.org. A button
+is provided on each page to access this site.}  
+
+_textgtiselecttlc_ [l=mn] {Ð¥ÑÐ»ÑÑ ÑÐŸÐœÐ³ÐŸÐœÐŸ ÑÑ}  
+
+#for status page
+_textgtiviewstatus_ [l=mn] {ÐÒ¯Ñ
+ Ñ
+ÑÐ»ÐœÐžÐ¹ Ñ
+ÑÐ²ÑÐŽ ÐŸÑÑÑÑÐ»Ð³ÑÐœ ÑÐ²ÑÑÐ³ Ñ
+Ð°ÑÐ°Ñ
+ÑÐœ ÑÑÐ»ÐŽ ÑÐœÐŽ ÐŽÐ°Ñ.}  
+_textgtiviewstatusbutton_ [l=mn] {Ð¢ÓšÐÐÐÐÐ Ð¥ÐÐ ÐÐ¥}  
+_textgtistatustable_ [l=mn] {ÐÒ¯Ñ
+ Ñ
+ÑÐ»ÐœÐžÐ¹ ÐŸÑÑÑÑÐ»Ð³ÑÐœ ÑÐ²ÑÑÐœ Ð¶Ð°Ð³ÑÐ°Ð°Ð»Ñ.}  
+_textgtilanguage_ [l=mn] {Ð¥ÑÐ»}  
+_textgtitotalnumberoftranslations_ [l=mn] {ÐÐžÐ¹Ñ ÐŸÑÑÑÑÐ»Ð³ÑÐœ ÑÐŸÐŸ.}  
+
+_textgtiselecttfk_ [l=mn] {ÐÐ¶ÐžÐ»Ð»Ð°Ñ
+ ÑÐ°Ð¹Ð»Ð°Ð° ÑÐŸÐœÐ³ÐŸÐœÐŸ ÑÑ}  
+
+_textgticoredm_ [l=mn] {Greenstone Interface (Core)}  
+_textgtiauxdm_ [l=mn] {Greenstone Interface (Auxiliary)}  
+_textgtiglidict_ [l=mn] {GLI Ò¯Ð³ÑÐžÐ¹Ðœ ÑÐ°Ðœ}  
+_textgtiglihelp_ [l=mn] {GLI ÑÑÑÐ»Ð°ÐŒÐ¶}  
+_textgtiperlmodules_ [l=mn] {Perl Modules}  
+_textgtitutorials_ [l=mn] {ÐÐžÑÑÑ ÐŽÐ°ÑÐ³Ð°Ð»ÑÑÐŽ}  
+_textgtigreenorg_ [l=mn] {Greenstone.org}  
+_textgtigs3core_ [l=mn] {Greenstone3 ÐÐœÑÐµÑÑÑÐ¹Ñ(Default)}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=mn] {Greenstone Ð¥Ó©Ð³Ð¶Ò¯Ò¯Ð»ÑÐ³ÑÐŽÐžÐ¹Ðœ ÐÐ°ÑÑÐœ ÐÐ²Ð»Ð°Ð³Ð°}  
+_textgtiinstallmanual_ [l=mn] {Greenstone Ð¡ÑÑÐ»Ð³Ð°Ñ
+ ÐÐ°ÑÑÐœ Ð°Ð²Ð»Ð°Ð³Ð°}  
+
+_textgtiusermanual_ [l=mn] {Greenstone Ð¥ÑÑÑÐ³Ð»ÑÐ³ÑÐžÐ¹Ðœ ÐÐ°ÑÑÐœ ÐÐ²Ð»Ð°Ð³Ð°}  
+
+_textgtienter_ [l=mn] {ÐÐ Ð£Ð£Ð}  
+
+_textgticorrectexistingtranslations_ [l=mn] {ÐÑÑÑÑÐ»Ð³Ð° Ð·Ð°ÑÐ°Ñ
+}  
+_textgtidownloadtargetfile_ [l=mn] {Ð€Ð°Ð¹Ð» ÑÐ°ÑÐ°Ð¶ Ð°Ð²Ð°Ñ
+}  
+_textgtiviewtargetfileinaction_ [l=mn] {Ð­ÐœÑ ÑÐ°Ð¹Ð»ÑÐ³ Ò¯Ð¹Ð»ÐŽÑÐ» ÐŽÑÑÑ ÐœÑ Ñ
+Ð°ÑÐ°Ñ
+}  
+_textgtitranslatefileoffline_ [l=mn] {Ð­ÐœÑ ÑÐ°Ð¹Ð»ÑÐ³ offline Ð³ÐŸÑÐžÐŒÐŸÐœÐŽ ÐŸÑÑÑÑÐ»Ð°Ñ
+.}  
+
+_textgtinumchunksmatchingquery_ [l=mn] {Ð¥Ð°Ð¹Ð»ÑÐ°ÐœÐŽ ÑÐŸÑ
+ÐžÑÑÐŸÐœ Ò¯Ð³ÐžÐ¹Ðœ ÑÐŸÐŸ}  
+
+_textgtinumchunkstranslated_ [l=mn] {ÐŸÑÑÑÑÐ»Ð³Ð° ÐŽÑÑÑÐ»Ð°Ð°}  
+_textgtinumchunksrequiringupdating_ [l=mn] {Ð­ÐŽÐ³ÑÑÑÑÑÑ, _1_ ÐœÑ ÑÐžÐœÑÑÐ»ÑÐ³ÐŽÑÑ
+ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³ÑÐ°Ð¹}  
+_textgtinumchunksrequiringtranslation_ [l=mn] {ÐŸÑÑÑÑÐ»Ð³Ð° Ò¯Ð»ÐŽÑÑÐœ}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=mn] {Ð¥ÐžÐ¹Ð³ÐŽÑÐ¶ ÐŽÑÑÑÑÐ°Ðœ ÐŸÑÑÑÑÐ»Ð³ÑÐœ ÑÐŸÐŸ}  
+_textgtinumchunksrequiringupdating2_ [l=mn] {Ð¡Ð°Ð¹Ð¶ÑÑÑÐ»Ð°Ñ
+ ÑÐ°Ð°ÑÐŽÐ»Ð°Ð³Ð°ÑÐ°Ð¹ ÐŸÑÑÑÑÐ»Ð³ÑÐœ ÑÐŸÐŸ}  
+_textgtinumchunksrequiringtranslation2_ [l=mn] {ÐÑÑÑÑÐ»Ð°Ð³ÐŽÐ°Ð°Ð³Ò¯Ð¹ Ñ
+ÑÑÐ³ÐžÐ¹Ðœ ÑÐŸÐŸ}  
+
+_textgtienterquery_ [l=mn] {ÐÐ°ÑÐ²Ð°Ñ Ñ
+ÐžÐ¹Ñ
+ Ó©Ð³Ò¯Ò¯Ð»Ð±ÑÑ ÑÑÐ²ÑÐ» ÑÐµÐºÑÑÑÑÑÑÑ Ò¯Ð³ ÐŸÑÑÑÐ»ÐœÐ° ÑÑ}  
+_textgtifind_ [l=mn] {Ð¥ÐÐÐ¥}  
+
+_textgtitranslatingchunk_ [l=mn] {<i>_1_</i> ÑÐµÐºÑÑÐžÐ¹Ð³ ÐŸÑÑÑÑÐ»Ð¶ Ð±Ð°Ð¹ÐœÐ°}  
+_textgtiupdatingchunk_ [l=mn] {<i>_1_</i> ÑÐµÐºÑÑÐžÐ¹Ð³ ÑÐžÐœÑÑÐ»ÑÐ¶ Ð±Ð°Ð¹ÐœÐ°}  
+_textgtisubmit_ [l=mn] {ÐÑÑÑÐ»Ð°Ñ
+}  
+
+_textgtilastupdated_ [l=mn] {Ð¡Ò¯Ò¯Ð»ÐŽ ÑÐžÐœÑÑÐ»ÑÐ³ÐŽÑÑÐœ}  
+
+_textgtitranslationfilecomplete_ [l=mn] {Ð­ÐœÑ ÑÐ°Ð¹Ð»ÑÐ³ ÑÐ°Ð¹Ð¶ÑÑÑÐ»ÑÐ°ÐœÐŽ ÑÐ°ÐœÑ ÑÐ°Ð»Ð°ÑÑ
+Ð°Ð»Ð°Ð°! <p> ÐÐŸÐŸÑÑ
+Ðž Ñ
+ÐŸÐ»Ð±ÐŸÐŸÑÐŸÐŸÑ ÐŸÑÐŸÐŸÐŽ ÑÐœÑ ÑÐ°Ð¹Ð»ÑÐ³ ÑÐ°ÑÐ°Ðœ Ð°Ð²Ñ Ð±ÐŸÐ»ÐœÐŸ, ÑÒ¯Ò¯ÐœÑÐ»ÑÐœ ÑÐ³ ÑÐ°Ð¹Ð» Ð¿ÑÐŸÐ³ÑÐ°ÐŒÑÐœ ÐŽÐ°ÑÐ°Ð°Ð³ÑÐœ Ñ
+ÑÐ²ÐžÐ»Ð±Ð°ÑÑ ÐŸÑÐŸÑ
+ Ð±ÐŸÐ»ÐœÐŸ.}  
+
+_textgtiofflinetranslation_ [l=mn] {Ð¢Ð° Greenstone-ÐžÐ¹Ðœ ÑÐœÑ Ñ
+ÑÑÐ³ÐžÐ¹Ð³ Microsoft Excel ÑÐ°Ð¹Ð» Ñ
+ÑÑÑÐ³Ð»ÑÐœ offline Ð³ÐŸÑÐžÐŒÐŸÐœÐŽ ÐŸÑÑÑÑÐ»Ð¶ Ð±ÐŸÐ»ÐœÐŸ: <ol>
+<li>Ð­ÐœÑ ÑÐ°Ð¹Ð»ÑÐ³ <a href="_gwcgi_?a=gti&p=excel&e=_compressedoptions_">ÑÐ°ÑÐ°Ð¶ Ð°Ð²</a>.
+<li>Ð¢Ð°ÑÐ°Ð¶ Ð°Ð²ÑÐ°Ðœ ÑÐ°Ð¹Ð»ÑÐ³ Microsoft Excel Ñ
+ÑÑÑÐ³Ð»ÑÐœ ÐœÑÑÐ¶(Office 2003/XP ÑÑÐ²ÑÐ» Ñ
+Ð°ÐŒÐ³ÐžÐ¹Ðœ ÑÒ¯Ò¯Ð»ÐžÐ¹Ðœ Ñ
+ÑÐ²ÐžÐ»Ð±Ð°ÑÑÐ³ Ñ
+ÑÑÑÐ³Ð»ÑÐœÑ) Microsoft Excel workbook (.xls) ÑÐŸÑÐŒÐ°ÑÐ°Ð°Ñ Ñ
+Ð°ÐŽÐ³Ð°Ð»Ð°Ñ
+.
+<li>Ð¢ÐŸÑ
+ÐžÑÐŸÑ
+ ÐœÒ¯ÐŽÑÐœÐŽ ÐŸÑÑÑÑÐ»Ð³Ð°Ð° Ð±ÐžÑÐžÑ
+. 
+<li>ÐÒ¯Ð³ÐŽÐžÐ¹Ð³ ÐŸÑÑÑÑÐ»Ð¶ ÐŽÑÑÑÑÐ°ÐœÑ ÐŽÐ°ÑÐ°Ð° .xls ÑÐ°Ð¹Ð»Ð°Ð° ÐŽÐ°ÑÐ°Ð°Ñ
+ Ñ
+Ð°ÑÐ³ ÑÑÑ ÐžÐ»Ð³ÑÑÑ
+ <a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>.
+</ol>}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=mn] {greenstone-ÐžÐ¹ ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÑÑÐœ ÐžÐœÑÐµÑÑÑÐ¹Ñ}
+_textglihelp_ [l=mn] {Greenstone-ÐžÐ¹ ÐÐŸÐŒÑÐœ Ð¡Ð°ÐœÑÐžÐ¹Ðœ ÐÐœÑÐµÑÑÑÐ¹Ñ (GLI) ÐœÑ ÑÐ°ÐœÑÐ³ Greenstone-ÐžÐ¹Ð³ 
+Ñ
+ÑÑÑÐ³Ð»ÑÑ
+ÑÐŽ ÐžÐ»Ò¯Ò¯ Ñ
+ÑÐ»Ð±Ð°Ñ Ð±ÐŸÐ»Ð³ÐŸÐŽÐŸÐ³. ÐÓ©Ðœ ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹ Ñ
+ÑÐŒÐ¶ÑÑÐœÐžÐ¹ ÐŒÐ°ÑÐµÑÐžÐ°Ð»ÑÐ³ ÑÑÐ³Ð»ÑÑÐ»Ð°Ñ
+, ÑÐ°ÑÐ°Ð¶ Ð°Ð²Ð°Ñ
+ ÑÑÐ²ÑÐ» ÐŒÐµÑÐ°-Ó©Ð³Ó©Ð³ÐŽÐ»Ó©Ó©Ñ ÑÑÐŒÐŽÑÐ³Ð»ÑÑ
+ assign metadata, Ð±ÐŸÐ»ÐŸÐœ Greenstone-ÐžÐ¹ ÑÑÐ³Ð»ÑÑÐ»Ð³Ð° Ñ
+ÐžÐ¹Ñ
+ Ð±ÐŸÐ»ÐŸÐŒÐ¶ÐžÐ¹Ð³ ÐŸÐ»Ð³ÐŸÐŽÐŸÐ³. 
+ <p>
+GLI ÐœÑ Greenstone-ÑÑÐ¹ Ñ
+ÐŸÐ»Ð±ÐŸÐ³ÐŽÐŸÐ¶ Ð°Ð¶ÐžÐ»Ð»Ð°ÐŽÐ°Ð³ Ð³ÑÐŽÐ³ÐžÐ¹Ð³ Ð°ÐœÑ
+Ð°Ð°ÑÐ°Ñ
+ Ñ
+ÑÑÑÐ³ÑÑÐ¹ Ð±Ð° 
+ÑÐœÑ ÐœÑ Greenstone-ÐžÐ¹ ÐžÐœÑÑÐ°Ð»Ð»ÑÐœ ÐŽÑÐŽ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐŽ ÑÑÑÐŽÐ°Ð³. Ð¥ÑÑÐ²ÑÑ ÑÐ°
+Greenstone-ÐžÐ¹ Ð°Ð»Ñ ÐœÑÐ³ Ñ
+ÑÐ²ÐžÐ»Ð±Ð°ÑÑÐ³ ÑÐ°ÑÐ°Ð¶ Ð°Ð²ÑÐ°Ðœ, ÑÑÐ²ÑÐ» Greenstone-ÐžÐ¹
+CD-ROM-ÐœÐŸÐŸÑ ÑÑÑÐ»Ð³Ð°ÑÐ°Ðœ ÑÐŸÑ
+ÐžÐŸÐ»ÐŽÐŸÐ»ÐŽ 
+ 
+ 
+<h4>GLI -ÐžÐ¹Ð³ Windows-ÐžÐ¹Ðœ ÐŸÑÑÐžÐœÐŽ Ð°Ð¶ÐžÐ»Ð»ÑÑÐ»Ð°Ñ
+</h4>
+ 
+Windows-ÑÐœ ÐŸÑÑÐžÐœÐŽ ÐœÐŸÐŒÑÐœ ÑÐ°ÐœÑÐžÐ¹Ðœ ÐžÐœÑÐµÑÑÑÐ¹ÑÐžÐ¹Ð³ <i>Greenstone-ÐžÐ¹Ðœ ÐÐžÐ¶ÐžÑÐ°Ð» ÐÐŸÐŒÑÐœ Ð¡Ð°Ðœ </i> -Ð³ <i>Programs</i> Ñ
+ÑÑÐ³ÑÑÑ <i>Start</i> ÑÑÑ ÑÒ¯Ò¯ ÐŸÑÐ¶ <i>ÐÐŸÐŒÑÐœ Ð¡Ð°ÐœÑÑÐœ ÐÐœÑÐµÑÑÑÐ¹Ñ</i> Ð³ÑÐŽÐ³ÑÑÑ ÑÐŸÐœÐ³ÐŸÐ¶ Ð°Ð¶ÐžÐ»Ð»ÑÑÐ»ÐœÐ°. 
+
+ 
+<h4>GLI -Ð³ Unix-ÑÐœ ÐŸÑÑÐžÐœÐŽ Ð°Ð¶ÐžÐ»Ð»ÑÑÐ»Ð°Ñ
+Ð°ÐŽ</h4>
+ 
+GLI-Ð³ Unix-ÑÐœ ÐŸÑÑÐžÐœÐŽ Ð°Ð¶ÐžÐ»Ð»ÑÑÐ»Ð°Ñ
+ÑÐœ ÑÑÐ»ÐŽ Ó©Ó©ÑÐžÐ¹Ðœ Greenstone-ÐžÐ¹ ÐžÐœÑÑÐ°Ð»Ð»ÑÐœ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐ¹Ð³ <i>gli</i> ÑÑÑ ÑÐŸÐ»ÐžÐŸÐŽ 
+<i>gli.sh</i> ÑÐºÑÐžÐ¿ÑÐžÐ¹Ð³ ÑÐœÑÑÑÐ»ÐœÐ°. 
+ 
+<h4>GLI-ÑÐ³ ÐÐ°ÐºÐžÐœÑÐŸÑ Ò®Ð¹Ð»ÐŽÐ»ÐžÐ¹Ðœ ÑÐžÑÑÐµÐŒÐŽ Ð°Ð¶ÐžÐ»Ð»ÑÑÐ»Ð°Ñ
+ X</h4>
+
+Finder-Ñ <i>Applications</i> then <i>Greenstone</i> ÑÐ°ÑÐ°Ð¶ ÐŸÑÑÑÐ»ÐœÐ°.
+(Ð¥ÑÑÑÐ² ÑÐ° Greenstone-ÐžÐ¹Ð³ ÑÑ
+ Ð±ÑÑÑ default Ð³ÑÑÑÐœ Ð±Ð°Ð¹ÑÐ»Ð°Ð»ÐŽ ÑÑÑÐ»Ð³Ð°ÑÐ°Ðœ Ð±ÐŸÐ»), ÐŽÐ°ÑÐ°Ð° ÐœÑ <i>GLI</i>  -Ð³ ÑÐœÑÑÑÐ»ÐœÐ°.}
Index: /gsdl/stable/macros/nav_css.dm
===================================================================
--- /gsdl/stable/macros/nav_css.dm	(revision 20131)
+++ /gsdl/stable/macros/nav_css.dm	(revision 20131)
@@ -0,0 +1,94 @@
+# this file must be UTF-8 encoded
+
+# This macro file contains the definitions required for making the
+# navigation bar presentation controlled by the CSS file.
+
+#######################################################################
+# GLOBAL MACROS 
+#######################################################################
+
+package Global
+
+#######################################################################
+# global navigation links
+#######################################################################
+
+_globallinks_ {_If_("_cgiargu_" ne "1",_homelink_) _helplink_ _preflink_}
+_homelink_ {_navtaborig_(_httppagehome_,_linktextHOME_,_textdescrhome_)}
+_helplink_ {_navtaborig_(_httppagehelp_,_linktextHELP_,_textdescrhelp_)}
+_preflink_ {_navtaborig_(_httppagepref_,_linktextPREFERENCES_,_textdescrpref_)}
+
+# The following is useful if collection specific macro.  Override
+# _optnavigationbar_ to be empty if you don't want the navigation bar to
+# appear in the standard place, and then specify _navigationbar_ elsewhere
+# in a collection specific macro file(s) to be where you do want it.
+_optnavigationbar_{
+<div class="navbar">
+<p class="navbar">
+_navigationbar_
+</p>
+</div>
+} 
+
+_starthighlight_ {<span class="highlight">}
+_endhighlight_ {</span>}
+
+# parameters are:
+# 1. the url to go to when clicked
+# 2. the name of the tab
+# 3. alt/title explanatory text
+# 4. optional "selected" or not if it is the current tab
+_navtaborig_ {<a _If_("_4_" eq "selected",class="navlink_sel">_2_,class="navlink" href="_1_" title="_3_">_2_)</a>}
+
+# parameters are
+# 1. The url to go to when clicked
+# 2. The metadata name - this gets used to determine the title and alt text
+# 3. optional "selected" if it is the current tab
+_navtab_ {<a _If_("_3_" eq "selected",class="navlink_sel">_navlinktitle_(_2_),class="navlink" href="_1_" title="_navlinkalt_(_2_)">_navlinktitle_(_2_))</a>}
+
+
+#######################################################################
+# navigation bar images
+#
+#######################################################################
+
+# the spacer image - the width of this is calculated and set from server.
+#
+# Its height is now explicity set to 1 to avoid width x height "scaling
+# problem".  Given that spacer.gif's natural dimensions are 40x4 pixels,
+# left uncontrolled, when the image is stretched through _widthtspace_ to
+# a width of say 400 (as happens when there are only two items in the
+# navigation bar) then its height becomes 40 pixels, making the navbar
+# twice as high as the text in it, and quite ugly looking
+
+_navbarspacer_ {<img src="_httpimg_/spacer.gif" height="1" width="_widthtspace_" />}
+
+_navbarspacer_[v=1] {<br>
+}
+
+# cgiargu means "static page", so no search link should be shown
+_navtabsearch_ {_If_("_cgiargu_" ne "1",_navtab_(_httpquery_,Search,_1_))}
+
+package about
+
+_imagethispage_ {_titleabout_}
+
+package query
+
+_imagethispage_ {_labelSearch_}
+
+
+package Style
+
+_imagescript_ {}
+
+#_bannertitle_ {_If_(_imagethispage_,<p class="bannertitle"><span class="bannertitle">_imagethispage_</span></p>)}
+
+_bannertitle_ {_If_(_imagethispage_,<p class="bannertitle">_imagethispage_</p>)}
+
+#<span class="bannertitlebackground">i</span>
+
+package home
+
+_preflink_ {_navtab_(_home:httppagehomepref_,_linktextPREFERENCES_,_textdescrpref_)}
+
Index: /gsdl/stable/macros/nav_ns4.dm
===================================================================
--- /gsdl/stable/macros/nav_ns4.dm	(revision 20131)
+++ /gsdl/stable/macros/nav_ns4.dm	(revision 20131)
@@ -0,0 +1,8388 @@
+# this file must be UTF-8 encoded
+
+# navigation bar macros for netscape 4
+# provides some obsolete macros removed in gsdl 2.63, for customised cols
+# uses old images/table layout instead of css
+
+package Global
+_globallinks_ {_If_("_cgiargu_" ne "1",_homelink_) _helplink_ _preflink_}
+_javalinks_ {_globallinks_} # compat for people with older custom macros
+_homelink_ {_gsimage_(_httppagehome_,_httpiconchomeof_,_httpiconchomeon_,homer,_textdescrhome_)}
+_helplink_ {_gsimage_(_httppagehelp_,_httpiconchelpof_,_httpiconchelpon_,help,_textdescrhelp_)}
+_preflink_ {_If_("_cgiargu_" ne "1",_preflink2_)}
+_preflink2_ {_gsimage_(_httppagepref_,_httpiconcprefof_,_httpiconcprefon_,pref,_textdescrpref_)}
+
+
+
+_optnavigationbar_ {
+<center><nobr>_navigationbar_</nobr></center>
+}
+
+_starthighlight_ {<span style="background: #FFFF77">}
+_endhighlight_ {</span>}
+
+#######################################################################
+#
+# navigation bar images
+#
+#######################################################################
+
+# the spacer image - the width of this is set from server
+_imagespacer_ {<img 
+src="_httpicontspace_" width="_widthtspace_" height="_heighttspace_">}
+_imagespacer_[v=1] {<br>
+}
+_navbarspacer_{_imagespacer_}
+_navbarspacer_[v=1] {<br>
+}
+
+# I'm surprised _image_2__ works... but it does. _imageTitle_ _imageCreator_ etc
+# 1. the url to go to when clicked
+# 2. The metadata name - this gets used to determine the title and alt text
+# 3. optional "selected" if it is the current tab
+_navtab_ {_If_("_image_2__" eq "\_image_2_\_",_If_("_3_" eq "selected",_navlinktitle_(_2_),<a href="_1_" title="_navlinkalt_(_2_)">_navlinktitle_(_2_)</a>),_If_("_3_" eq "selected",_image_2_green_,_image_2__(_1_)))}
+# doesn't yet work for metadata that isn't dublin core... !!!
+
+_navtabsearch_ {_If_("_cgiargu_" ne "1",_navtabsearch2_(_1_),_iconnosearch_)}
+_navtabsearch2_ {_If_("_1_" eq "selected",_imagesearchgreen_,_imagesearch_)}
+_iconnosearch_ {<img class="icon" src="_httpimg_/en/nosearch.gif">}
+
+# gsimage should be used to define an instance of a flashy image
+# parameters are:
+# 1. the url to go to when the button is clicked
+# 2. the url of the "off" image
+# 3. the url of the "on" image
+# 4. the name of the image (must be unique)
+# 5. image alt text
+# (border=0 required for netscape4, it won't apply this from a style sheet)
+_gsimage_ {<a href="_1_" onMouseover="roll('_4_',1);" onMouseOut="roll('_4_',0);"><img name="_4_" class="link" src="_2_" alt="_5_" title="_5_" onLoad="gbutton(this,'_3_');" border="0"></a>}
+
+_gsimage_ [v=1] {<a href="_1_">_5_</a><br>}
+
+_imagesearch_ {_If_("_cgiargu_" ne "1",_imagesearch2_,_iconnosearch_)}
+_imagesearch2_ {_gsimage_(_httpquery_,_httpicontsrchof_,_httpicontsrchon_,srch,_navlinkalt_(Search))}
+_imagesearchgreen_ {<img src="_httpicontsrchgr_" width="_widthtsrchx_" border="0">}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_imageTitle_ {_gsimage_(_1_,_httpiconttitleof_,_httpiconttitleon_,titles,_navlinkalt_(Title))}
+_imageTitlegreen_ {<img src="_httpiconttitlegr_" width="_widthttitlex_" border="0">}
+_imageCreator_ {_gsimage_(_1_,_httpicontcreatof_,_httpicontcreaton_,creators,_navlinkalt_(Creator))}
+_imageCreatorgreen_ {<img src="_httpicontcreatgr_" width="_widthtcreatx_" border="0">}
+_imageSubject_ {_gsimage_(_1_,_httpicontsubjof_,_httpicontsubjon_,subjects,_navlinkalt_(Subject))}
+_imageSubjectgreen_ {<img src="_httpicontsubjgr_" width="_widthtsubjx_" border="0">}
+_imageDescription_ {_gsimage_(_1_,_httpicontdescof_,_httpicontdescon_,descriptions,_navlinkalt_(Description))}
+_imageDescriptiongreen_ {<img src="_httpicontdescgr_" width="_widthtdescx_" border="0">}
+_imagePublisher_ {_gsimage_(_1_,_httpicontpublof_,_httpicontpublon_,publishers,_navlinkalt_(Publisher))}
+_imagePublishergreen_ {<img src="_httpicontpublgr_" width="_widthtpublx_" border="0">}
+_imageContributor_ {_gsimage_(_1_,_httpicontcontrof_,_httpicontcontron_,contributors,_navlinkalt_(Contributor))}
+_imageContributorgreen_ {<img src="_httpicontcontrgr_" width="_widthtcontrx_" border="0">}
+_imageDate_ {_gsimage_(_1_,_httpicontdateof_,_httpicontdateon_,dates,_navlinkalt_(Date))}
+_imageDategreen_ {<img src="_httpicontdategr_" width="_widthtdatex_" border="0">}
+_imageType_ {_gsimage_(_1_,_httpiconttypeof_,_httpiconttypeon_,types,_navlinkalt_(Type))}
+_imageTypegreen_ {<img src="_httpiconttypegr_" width="_widthttypex_" border="0">}
+_imageFormat_ {_gsimage_(_1_,_httpicontformof_,_httpicontformon_,formats,_navlinkalt_(Format))}
+_imageFormatgreen_ {<img src="_httpicontformgr_" width="_widthtformx_" border="0">}
+_imageIdentifier_ {_gsimage_(_1_,_httpicontidentof_,_httpicontidenton_,identifiers,_navlinkalt_(Identifier))}
+_imageIdentifiergreen_ {<img src="_httpicontidentgr_" width="_widthtidentx_" border="0">}
+_imageSource_ {_gsimage_(_1_,_httpicontsrcof_,_httpicontsrcon_,source,_navlinkalt_(Source))}
+_imageSourcegreen_ {<img src="_httpicontsrcgr_" width="_widthtsrcx_" border="0">}
+_imageLanguage_ {_gsimage_(_1_,_httpicontlangof_,_httpicontlangon_,language,_navlinkalt_(Language))}
+_imageLanguagegreen_ {<img src="_httpicontlanggr_" width="_widthtlangx_" border="0">}
+_imageRelation_ {_gsimage_(_1_,_httpicontrelof_,_httpicontrelon_,relations,_navlinkalt_(Relation))}
+_imageRelationgreen_ {<img src="_httpicontrelgr_" width="_widthtrelx_" border="0">}
+_imageCoverage_ {_gsimage_(_1_,_httpicontcoverof_,_httpicontcoveron_,coverage,_navlinkalt_(Coverage))}
+_imageCoveragegreen_ {<img src="_httpicontcovergr_" width="_widthtcoverx_" border="0">}
+_imageRights_ {_gsimage_(_1_,_httpicontrightof_,_httpicontrighton_,rights,_navlinkalt_(Rights))}
+_imageRightsgreen_ {<img src="_httpicontrightgr_" width="_widthtrightx_" border="0">}
+_imageSeries_ {_gsimage_(_1_,_httpicontserof_,_httpicontseron_,series,_navlinkalt_(Series))}
+_imageSeriesgreen_ {<img src="_httpicontsergr_" width="_widthtserx_" border="0">}
+_imageTo_ {_gsimage_(_1_,_httpiconttoof_,_httpiconttoon_,to,_navlinkalt_(To))}
+_imageTogreen_ {<img src="_httpiconttogr_" width="_widthttox_" border="0">}
+_imageFrom_ {_gsimage_(_1_,_httpicontfromof_,_httpicontfromon_,from,_navlinkalt_(From))}
+_imageFromgreen_ {<img src="_httpicontfromgr_" width="_widthtfromx_" border="0">}
+_imageOrganization_ {_gsimage_(_1_,_httpicontorgof_,_httpicontorgon_,org,_navlinkalt_(Organization))}
+_imageOrganizationgreen_ {<img src="_httpicontorggr_" width="_widthtorgx_" border="0">}
+_imageHowto_ {_gsimage_(_1_,_httpiconthowof_,_httpiconthowon_,how,_navlinkalt_(Howto))}
+_imageHowtogreen_ {<img src="_httpiconthowgr_" width="_widththowx_" border="0">}
+_imageTopic_ {_gsimage_(_1_,_httpiconttopicof_,_httpiconttopicon_,topic,_navlinkalt_(Topic))}
+_imageTopicgreen_ {<img src="_httpiconttopicgr_" width="_widthttopicx_" border="0">}
+_imageBrowse_ {_gsimage_(_1_,_httpicontbrwseof_,_httpicontbrwseon_,browse,_navlinkalt_(Browse)}
+_imageBrowsegreen_ {<img src="_httpicontbrwsegr_" width="_widthtbrwsex_" border="0">}
+_imagePeople_ {_gsimage_(_1_,_httpicontpeopof_,_httpicontpeopon_,people,_navlinkalt_(People))}
+_imagePeoplegreen_ {<imgsrc="_httpicontpeopgr_" width="_widthtpeopx_" border="0">}
+_imageAcronym_ {_gsimage_(_1_,_httpicontacroof_,_httpicontacroon_,acronym,_navlinkalt_(Acronym))}
+_imageAcronymgreen_ {<imgsrc="_httpicontacrogr_" width="_widthtacrox_" border="0">}
+_imageCollage_ {_gsimage_(_1_,_httpicontcollof_,_httpicontcollon_,collage,_navlinkalt_(Collage))}
+_imageCollagegreen_ {<img src="_httpicontcollgr_" width="_widthtcollx_" border="0">}
+_imagePhrase_ {_gsimage_(_1_,_httpicontphrseof_,_httpicontphrseon_,phrase,_navlinkalt_(Phrase))}
+_imagePhrasegreen_ {<imgsrc="_httpicontphrsegr_" width="_widthtphrsex_" border="0">}
+_imageArtist_ {_gsimage_(_1_,_httpicontartstof_,_httpicontartston_,artist,_navlinkalt_(Artist))}
+_imageArtistgreen_ {<imgsrc="_httpicontartstgr_" width="_widthtartstx_" border="0">}
+_imageKeyword_ {_gsimage_(_1_,_httpicontkwof_,_httpicontkwon_,kw,_navlinkalt_(Keyword))}
+_imageKeywordgreen_ {<img src="_httpicontkwgr_" width="_widthtkwx_" border="0">}
+_imageVolume_ {_gsimage_(_1_,_httpicontvolof_,_httpicontvolon_,volume,_navlinkalt_(Volume))}
+_imageVolumegreen_ {<img src="_httpicontvolgr_" width="_widthtvolx_" border="0">}
+_imageCaptions_ {_gsimage_(_1_,_httpicontcaptof_,_httpicontcapton_,captions,_navlinkalt_(Captions))}
+_imageCaptionsgreen_ {<imgsrc="_httpicontcaptgr_" width="_widthtcaptx_" border="0">}
+_imageCountries_ {_gsimage_(_1_,_httpicontcountof_,_httpicontcounton_,countries,_navlinkalt_(Countries))}
+_imageCountriesgreen_ {<img src="_httpicontcountgr_" width="_widthtcountx_" border="0">}
+
+
+package about
+_imagethispage_ {<img src="_httpiconhabout_" width="_widthhabout_" height="_heighthabout_">}
+
+package query
+_imagethispage_ {<img src="_httpiconhsearch_" width="_widthhsearch_" height="_heighthsearch_">}
+
+
+
+package Style
+#######################################################################
+# flashy rollover image macro
+#
+#######################################################################
+
+# imagescript should always be included in html header if there are
+# flashy images on the page
+_imagescript_ {
+var loaded = new Array();
+function gbutton (image, onimage) \{
+  if (image && image.src && (image.out == null || typeof(image.out) == typeof(void(0)))) \{
+    s = image.src;
+    image.out = new Image();
+    image.out.src = s;
+    image.over = new Image();
+    image.over.src = onimage;
+    loaded[image.name] = image;
+  \}
+\}
+
+function roll (imagename, over) \{
+  if (document.images) \{
+    if (over) i = "over";
+    else i = "out";
+    image = loaded[imagename];
+    if (image) image.src = eval("image."+i+".src");
+  \}
+\}
+}
+
+_bannertitle_ {_If_(_imagethispage_,<p>_imagethispage_</p>)}
+
+
+package home
+_preflink_ {_gsimage_(_home:httppagehomepref_,_httpiconcprefof_,_httpiconcprefon_,pref,_linktextPREFERENCES_)}
+
+package Global
+#########################################################
+### title images
+#########################################################
+
+_titleimageabout_ {<img src="_httpiconhabout_" width="_widthhabout_" height="_heighthabout_">}
+_titleimageTitle_ {<img src="_httpiconhtitle_" width="_widthhtitle_" height="_heighthtitle_">}
+_titleimageCreator_ {<img src="_httpiconhcreat_" width="_widthhcreat_" height="_heighthcreat_">}
+_titleimageSubject_ {<img src="_httpiconhsubj_" width="_widthhsubj_" height="_heighthsubj_">}
+_titleimageDescription_ {<img src="_httpiconhdesc_" width="_widthhdesc_" height="_heighthdesc_">}
+_titleimagePublisher_ {<img src="_httpiconhpubl_" width="_widthhpubl_" height="_heighthpubl_">}
+_titleimageContributor_ {<img src="_httpiconhcontr_" width="_widthhcontr_" height="_heighthcontr_">}
+_titleimageDate_ {<img src="_httpiconhdate_" width="_widthhdate_" height="_heighthdate_">}
+_titleimageType_ {<img src="_httpiconhtype_" width="_widthhtype_" height="_heighthtype_">}
+_titleimageFormat_ {<img src="_httpiconhform_" width="_widthhform_" height="_heighthform_">}
+_titleimageIdentifier_ {<img src="_httpiconhident_" width="_widthhident_" height="_heighthident_">}
+_titleimageSource_ {<img src="_httpiconhsrc_" width="_widthhsrc_" height="_heighthsrc_">}
+_titleimageLanguage_ {<img src="_httpiconhlang_" width="_widthhlang_" height="_heighthlang_">}
+_titleimageRelation_ {<img src="_httpiconhrel_" width="_widthhrel_" height="_heighthrel_">}
+_titleimageCoverage_ {<img src="_httpiconhcover_" width="_widthhcover_" height="_heighthcover_">}
+_titleimageRights_ {<img src="_httpiconhright_" width="_widthhright_" height="_heighthright_">}
+_titleimageCollage_ {<img src="_httpiconhcoll_" width="_widthhcoll_" height="_heighthcoll_">}
+_titleimageList_ {<img src="_httpiconhlist_" width="_widthhlist_" height="_heighthlist_">}
+_titleimageTo_ {<img src="_httpiconhto_" width="_widthhto_" height="_heighthto_">}
+_titleimageFrom_ {<img src="_httpiconhfrom_" width="_widthhfrom_" height="_heighthfrom_">}
+_titleimageSeries_ {<img src="_httpiconhser_" width="_widthhser_" height="_heighthser_">}
+_titleimageHowto_ {<img src="_httpiconhhow_" width="_widthhhow_" height="_heighthhow_">}
+_titleimageTopic_ {<img src="_httpiconhtopic_" width="_widthhtopic_" height="_heighthtopic_">}
+_titleimageOrganization_ {<img src="_httpiconhorg_" width="_widthhorg_" height="_heighthorg_">}
+_titleimageBrowse_ {<img src="_httpiconhbrwse_" width="_widthhbrwse_" height="_heighthbrwse_">}
+_titleimagePeople_ {<img src="_httpiconhpeople_" width="_widthhpeople_" height="_heighthpeople_">}
+_titleimageAcronym_ {<img src="_httpiconhacronym_" width="_widthhacronym_" height="_heighthacronym_">}
+_titleimagePhrase_ {<img src="_httpiconhphrse_" width="_widthhphrse_" height="_heighthphrse_">}
+_titleimageArtist_ {<img src="_httpiconhartist_" width="_widthhartist_" height="_heighthartist_">}
+_titleimageKeyword_ {<img src="_httpiconhkw_" width="_widthhkw_" height="_heighthkw_">}
+_titleimageVolume_ {<img src="_httpiconhvol_" width="_widthhvol_" height="_heighthvol_">}
+_titleimageCaptions_ {<img src="_httpiconhcapt_" width="_widthhcapt_" height="_heighthcapt_">}
+_titleimageCountries_ {<img src="_httpiconhcount_" width="_widthhcount_" height="_heighthcount_">}
+
+#####################################################
+# language dependent image macros
+####################################################
+
+####################################################
+# top navigation icons and their title images
+####################################################
+
+#########
+# HELP
+#########
+
+## "HELP" ## top_nav_button ## chelp ##
+_httpiconchelpof_ {_httpimg_/en/chelpof.gif}
+_httpiconchelpon_ {_httpimg_/en/chelpon.gif}
+
+## "Ù
+Ø³Ø§Ø¹Ø¯Ø©" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=ar] {_httpimg_/ar/chelpof.gif}
+_httpiconchelpon_ [l=ar] {_httpimg_/ar/chelpon.gif}
+
+## "àŠžàŠŸàŠ¹àŠŸàŠ¯à§àŠ¯" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=bn] {_httpimg_/bn/chelpof.gif}
+_httpiconchelpon_ [l=bn] {_httpimg_/bn/chelpon.gif}
+
+## "AJUDA" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=ca] {_httpimg_/ca/chelpof.gif}
+_httpiconchelpon_ [l=ca] {_httpimg_/ca/chelpon.gif}
+
+## "NÃPOVÄDA" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=cs] {_httpimg_/cs/chelpof.gif}
+_httpiconchelpon_ [l=cs] {_httpimg_/cs/chelpon.gif}
+
+## "HILFE" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=de] {_httpimg_/de/chelpof.gif}
+_httpiconchelpon_ [l=de] {_httpimg_/de/chelpon.gif}
+
+## "ÎÎÎÎÎÎÎ" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=el] {_httpimg_/el/chelpof.gif}
+_httpiconchelpon_ [l=el] {_httpimg_/el/chelpon.gif}
+
+## "AYUDA" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=es] {_httpimg_/es/chelpof.gif}
+_httpiconchelpon_ [l=es] {_httpimg_/es/chelpon.gif}
+
+## "Ø±Ø§ÙÙÙ
+Ø§ÙÙ" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=fa] {_httpimg_/fa/chelpof.gif}
+_httpiconchelpon_ [l=fa] {_httpimg_/fa/chelpon.gif}
+
+## "OHJE" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=fi] {_httpimg_/fi/chelpof.gif}
+_httpiconchelpon_ [l=fi] {_httpimg_/fi/chelpon.gif}
+
+## "AIDE" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=fr] {_httpimg_/fr/chelpof.gif}
+_httpiconchelpon_ [l=fr] {_httpimg_/fr/chelpon.gif}
+
+## "AXUDA" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=gl] {_httpimg_/gl/chelpof.gif}
+_httpiconchelpon_ [l=gl] {_httpimg_/gl/chelpon.gif}
+
+## "××š××¢" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=he] {_httpimg_/he/chelpof.gif}
+_httpiconchelpon_ [l=he] {_httpimg_/he/chelpon.gif}
+
+## "POMOÄ" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=hr] {_httpimg_/hr/chelpof.gif}
+_httpiconchelpon_ [l=hr] {_httpimg_/hr/chelpon.gif}
+
+## "ÕÕ£Õ¶ÕžÖÕ©ÕµÕžÖÕ¶" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=hy] {_httpimg_/hy/chelpof.gif}
+_httpiconchelpon_ [l=hy] {_httpimg_/hy/chelpon.gif}
+
+## "BANTUAN" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=id] {_httpimg_/id/chelpof.gif}
+_httpiconchelpon_ [l=id] {_httpimg_/id/chelpon.gif}
+
+## "AIUTO" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=it] {_httpimg_/it/chelpof.gif}
+_httpiconchelpon_ [l=it] {_httpimg_/it/chelpon.gif}
+
+## "ãã«ã" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=ja] {_httpimg_/ja/chelpof.gif}
+_httpiconchelpon_ [l=ja] {_httpimg_/ja/chelpon.gif}
+
+## "ááá®ááá ááá" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=ka] {_httpimg_/ka/chelpof.gif}
+_httpiconchelpon_ [l=ka] {_httpimg_/ka/chelpon.gif}
+
+## "ÐÓšÐÐÐ" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=kk] {_httpimg_/kk/chelpof.gif}
+_httpiconchelpon_ [l=kk] {_httpimg_/kk/chelpon.gif}
+
+## "ÐÐÐ ÐÐÐ" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=ky] {_httpimg_/ky/chelpof.gif}
+_httpiconchelpon_ [l=ky] {_httpimg_/ky/chelpon.gif}
+
+## "PALÄªGS" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=lv] {_httpimg_/lv/chelpof.gif}
+_httpiconchelpon_ [l=lv] {_httpimg_/lv/chelpon.gif}
+
+## "ÄWHINA" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=mi] {_httpimg_/mi/chelpof.gif}
+_httpiconchelpon_ [l=mi] {_httpimg_/mi/chelpon.gif}
+
+## "Ð¢Ð£Ð¡ÐÐÐÐ" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=mn] {_httpimg_/mn/chelpof.gif}
+_httpiconchelpon_ [l=mn] {_httpimg_/mn/chelpon.gif}
+
+## "HELP" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=nl] {_httpimg_/nl/chelpof.gif}
+_httpiconchelpon_ [l=nl] {_httpimg_/nl/chelpon.gif}
+
+## "POMOC" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=pl] {_httpimg_/pl/chelpof.gif}
+_httpiconchelpon_ [l=pl] {_httpimg_/pl/chelpon.gif}
+
+## "AJUDA" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=pt-br] {_httpimg_/pt-br/chelpof.gif}
+_httpiconchelpon_ [l=pt-br] {_httpimg_/pt-br/chelpon.gif}
+
+## "AJUDA" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=pt-pt] {_httpimg_/pt-pt/chelpof.gif}
+_httpiconchelpon_ [l=pt-pt] {_httpimg_/pt-pt/chelpon.gif}
+
+## "ÐÐÐÐÐ©Ð¬" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=ru] {_httpimg_/ru/chelpof.gif}
+_httpiconchelpon_ [l=ru] {_httpimg_/ru/chelpon.gif}
+
+## "POMOÄ" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=sr] {_httpimg_/sr/chelpof.gif}
+_httpiconchelpon_ [l=sr] {_httpimg_/sr/chelpon.gif}
+
+## "àžà¹àž§àž¢à¹àž«àž¥àž·àž­" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=th] {_httpimg_/th/chelpof.gif}
+_httpiconchelpon_ [l=th] {_httpimg_/th/chelpon.gif}
+
+## "YARDIM" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=tr] {_httpimg_/tr/chelpof.gif}
+_httpiconchelpon_ [l=tr] {_httpimg_/tr/chelpon.gif}
+
+## "ÐÐÐÐÐÐÐÐ" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=uk] {_httpimg_/uk/chelpof.gif}
+_httpiconchelpon_ [l=uk] {_httpimg_/uk/chelpon.gif}
+
+## "GiÃºp Äá»¡" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=vi] {_httpimg_/vi/chelpof.gif}
+_httpiconchelpon_ [l=vi] {_httpimg_/vi/chelpon.gif}
+
+## "åž®å©" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=zh] {_httpimg_/zh/chelpof.gif}
+_httpiconchelpon_ [l=zh] {_httpimg_/zh/chelpon.gif}
+
+## "å¹«å©" ## top_nav_button ## chelp ##
+_httpiconchelpof_ [l=zh-tr] {_httpimg_/zh-tr/chelpof.gif}
+_httpiconchelpon_ [l=zh-tr] {_httpimg_/zh-tr/chelpon.gif}
+
+## "help" ## green_title ## h_help ##
+_httpiconhhelp_ {_httpimg_/en/h\_help.gif}
+_widthhhelp_ {200}
+_heighthhelp_ {57}
+## "Ù
+Ø³Ø§Ø¹Ø¯Ø©" ## green_title ## h_help ##
+_httpiconhhelp_ [l=ar] {_httpimg_/ar/h\_help.gif}
+_widthhhelp_ [l=ar] {200}
+_heighthhelp_ [l=ar] {57}
+## "àŠžàŠŸàŠ¹àŠŸàŠ¯à§àŠ¯" ## green_title ## h_help ##
+_httpiconhhelp_ [l=bn] {_httpimg_/bn/h\_help.gif}
+_widthhhelp_ [l=bn] {200}
+_heighthhelp_ [l=bn] {57}
+## "ajuda" ## green_title ## h_help ##
+_httpiconhhelp_ [l=ca] {_httpimg_/ca/h\_help.gif}
+_widthhhelp_ [l=ca] {200}
+_heighthhelp_ [l=ca] {57}
+## "nÃ¡povÄda" ## green_title ## h_help ##
+_httpiconhhelp_ [l=cs] {_httpimg_/cs/h\_help.gif}
+_widthhhelp_ [l=cs] {200}
+_heighthhelp_ [l=cs] {57}
+## "hilfe" ## green_title ## h_help ##
+_httpiconhhelp_ [l=de] {_httpimg_/de/h\_help.gif}
+_widthhhelp_ [l=de] {200}
+_heighthhelp_ [l=de] {57}
+## "Î²Î¿Î®ÎžÎµÎ¹Î±" ## green_title ## h_help ##
+_httpiconhhelp_ [l=el] {_httpimg_/el/h\_help.gif}
+_widthhhelp_ [l=el] {200}
+_heighthhelp_ [l=el] {57}
+## "ayuda" ## green_title ## h_help ##
+_httpiconhhelp_ [l=es] {_httpimg_/es/h\_help.gif}
+_widthhhelp_ [l=es] {200}
+_heighthhelp_ [l=es] {57}
+## "ÙÙ
+Ù" ## green_title ## h_help ##
+_httpiconhhelp_ [l=fa] {_httpimg_/fa/h\_help.gif}
+_widthhhelp_ [l=fa] {200}
+_heighthhelp_ [l=fa] {57}
+## "ohje" ## green_title ## h_help ##
+_httpiconhhelp_ [l=fi] {_httpimg_/fi/h\_help.gif}
+_widthhhelp_ [l=fi] {200}
+_heighthhelp_ [l=fi] {57}
+## "aide" ## green_title ## h_help ##
+_httpiconhhelp_ [l=fr] {_httpimg_/fr/h\_help.gif}
+_widthhhelp_ [l=fr] {200}
+_heighthhelp_ [l=fr] {57}
+## "axuda" ## green_title ## h_help ##
+_httpiconhhelp_ [l=gl] {_httpimg_/gl/h\_help.gif}
+_widthhhelp_ [l=gl] {200}
+_heighthhelp_ [l=gl] {57}
+## "××š××¢" ## green_title ## h_help ##
+_httpiconhhelp_ [l=he] {_httpimg_/he/h\_help.gif}
+_widthhhelp_ [l=he] {200}
+_heighthhelp_ [l=he] {57}
+## "POMOÄ" ## green_title ## h_help ##
+_httpiconhhelp_ [l=hr] {_httpimg_/hr/h_help.gif}
+_widthhhelp_ [l=hr] {200}
+_heighthhelp_ [l=hr] {57}
+## "Ö
+Õ£Õ¶ÕžÖÕ©ÕµÕžÖÕ¶" ## green_title ## h_help ##
+_httpiconhhelp_ [l=hy] {_httpimg_/hy/h\_help.gif}
+_widthhhelp_ [l=hy] {200}
+_heighthhelp_ [l=hy] {57}
+## "bantuan" ## green_title ## h_help ##
+_httpiconhhelp_ [l=id] {_httpimg_/id/h\_help.gif}
+_widthhhelp_ [l=id] {200}
+_heighthhelp_ [l=id] {57}
+## "aiuto" ## green_title ## h_help ##
+_httpiconhhelp_ [l=it] {_httpimg_/it/h\_help.gif}
+_widthhhelp_ [l=it] {200}
+_heighthhelp_ [l=it] {57}
+## "ãã«ã" ## green_title ## h_help ##
+_httpiconhhelp_ [l=ja] {_httpimg_/ja/h\_help.gif}
+_widthhhelp_ [l=ja] {200}
+_heighthhelp_ [l=ja] {57}
+## "ááá®ááá ááá" ## green_title ## h_help ##
+_httpiconhhelp_ [l=ka] {_httpimg_/ka/h\_help.gif}
+_widthhhelp_ [l=ka] {258}
+_heighthhelp_ [l=ka] {74}
+## "ÐºÓ©ÐŒÐµÐº" ## green_title ## h_help ##
+_httpiconhhelp_ [l=kk] {_httpimg_/kk/h\_help.gif}
+_widthhhelp_ [l=kk] {200}
+_heighthhelp_ [l=kk] {57}
+## "Ð¶Ð°ÑÐŽÐ°ÐŒ" ## green_title ## h_help ##
+_httpiconhhelp_ [l=ky] {_httpimg_/ky/h\_help.gif}
+_widthhhelp_ [l=ky] {200}
+_heighthhelp_ [l=ky] {57}
+## "palÄ«gs" ## green_title ## h_help ##
+_httpiconhhelp_ [l=lv] {_httpimg_/lv/h\_help.gif}
+_widthhhelp_ [l=lv] {200}
+_heighthhelp_ [l=lv] {57}
+## "Äwhina" ## green_title ## h_help ##
+_httpiconhhelp_ [l=mi] {_httpimg_/mi/h\_help.gif}
+_widthhhelp_ [l=mi] {200}
+_heighthhelp_ [l=mi] {57}
+## "ÑÑÑÐ»Ð°ÐŒÐ¶" ## green_title ## h_help ##
+_httpiconhhelp_ [l=mn] {_httpimg_/mn/h\_help.gif}
+_widthhhelp_ [l=mn] {200}
+_heighthhelp_ [l=mn] {57}
+## "help" ## green_title ## h_help ##
+_httpiconhhelp_ [l=nl] {_httpimg_/nl/h\_help.gif}
+_widthhhelp_ [l=nl] {200}
+_heighthhelp_ [l=nl] {57}
+## "pomoc" ## green_title ## h_help ##
+_httpiconhhelp_ [l=pl] {_httpimg_/pl/h\_help.gif}
+_widthhhelp_ [l=pl] {200}
+_heighthhelp_ [l=pl] {57}
+## "ajuda" ## green_title ## h_help ##
+_httpiconhhelp_ [l=pt-br] {_httpimg_/pt-br/h\_help.gif}
+_widthhhelp_ [l=pt-br] {200}
+_heighthhelp_ [l=pt-br] {57}
+## "ajuda" ## green_title ## h_help ##
+_httpiconhhelp_ [l=pt-pt] {_httpimg_/pt-pt/h\_help.gif}
+_widthhhelp_ [l=pt-pt] {200}
+_heighthhelp_ [l=pt-pt] {57}
+## "Ð¿ÐŸÐŒÐŸÑÑ" ## green_title ## h_help ##
+_httpiconhhelp_ [l=ru] {_httpimg_/ru/h\_help.gif}
+_widthhhelp_ [l=ru] {200}
+_heighthhelp_ [l=ru] {57}
+## "pomoÄ" ## green_title ## h_help ##
+_httpiconhhelp_ [l=sr] {_httpimg_/sr/h\_help.gif}
+_widthhhelp_ [l=sr] {200}
+_heighthhelp_ [l=sr] {57}
+## "àžà¹àž§àž¢à¹àž«àž¥àž·àž­" ## green_title ## h_help ##
+_httpiconhhelp_ [l=th] {_httpimg_/th/h\_help.gif}
+_widthhhelp_ [l=th] {200}
+_heighthhelp_ [l=th] {57}
+## "yardÄ±m" ## green_title ## h_help ##
+_httpiconhhelp_ [l=tr] {_httpimg_/tr/h\_help.gif}
+_widthhhelp_ [l=tr] {200}
+_heighthhelp_ [l=tr] {57}
+## "ÐŽÐŸÐ¿ÐŸÐŒÐŸÐ³Ð°" ## green_title ## h_help ##
+_httpiconhhelp_ [l=uk] {_httpimg_/uk/h\_help.gif}
+_widthhhelp_ [l=uk] {200}
+_heighthhelp_ [l=uk] {57}
+## "giÃºp Äá»¡" ## green_title ## h_help ##
+_httpiconhhelp_ [l=vi] {_httpimg_/vi/h\_help.gif}
+_widthhhelp_ [l=vi] {200}
+_heighthhelp_ [l=vi] {57}
+## "åž®å©" ## green_title ## h_help ##
+_httpiconhhelp_ [l=zh] {_httpimg_/zh/h\_help.gif}
+_widthhhelp_ [l=zh] {200}
+_heighthhelp_ [l=zh] {57}
+## "å¹«å©" ## green_title ## h_help ##
+_httpiconhhelp_ [l=zh-tr] {_httpimg_/zh-tr/h\_help.gif}
+_widthhhelp_ [l=zh-tr] {200}
+_heighthhelp_ [l=zh-tr] {57}
+
+#############
+# HOME
+##############
+
+## "HOME" ## top_nav_button ## chome ##
+_httpiconchomeof_ {_httpimg_/en/chomeof.gif}
+_httpiconchomeon_ {_httpimg_/en/chomeon.gif}
+
+## "Ø§ÙØ±ØŠÙØ³ÙØ©" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=ar] {_httpimg_/ar/chomeof.gif}
+_httpiconchomeon_ [l=ar] {_httpimg_/ar/chomeon.gif}
+
+## "àŠ¹à§àŠ® / àŠà§àŠ¹" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=bn] {_httpimg_/bn/chomeof.gif}
+_httpiconchomeon_ [l=bn] {_httpimg_/bn/chomeon.gif}
+
+## "PRINCIPAL" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=ca] {_httpimg_/ca/chomeof.gif}
+_httpiconchomeon_ [l=ca] {_httpimg_/ca/chomeon.gif}
+
+## "DOMÅ®" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=cs] {_httpimg_/cs/chomeof.gif}
+_httpiconchomeon_ [l=cs] {_httpimg_/cs/chomeon.gif}
+
+## "HAUPTSEITE" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=de] {_httpimg_/de/chomeof.gif}
+_httpiconchomeon_ [l=de] {_httpimg_/de/chomeon.gif}
+
+## "ÎÎ¡Î§ÎÎÎ Î£ÎÎÎÎÎ" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=el] {_httpimg_/el/chomeof.gif}
+_httpiconchomeon_ [l=el] {_httpimg_/el/chomeon.gif}
+
+## "PRINCIPAL" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=es] {_httpimg_/es/chomeof.gif}
+_httpiconchomeon_ [l=es] {_httpimg_/es/chomeon.gif}
+
+## "Ø®Ø§ÙÙ" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=fa] {_httpimg_/fa/chomeof.gif}
+_httpiconchomeon_ [l=fa] {_httpimg_/fa/chomeon.gif}
+
+## "ALKU" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=fi] {_httpimg_/fi/chomeof.gif}
+_httpiconchomeon_ [l=fi] {_httpimg_/fi/chomeon.gif}
+
+## "ACCUEIL" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=fr] {_httpimg_/fr/chomeof.gif}
+_httpiconchomeon_ [l=fr] {_httpimg_/fr/chomeon.gif}
+
+## "PRINCIPAL" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=gl] {_httpimg_/gl/chomeof.gif}
+_httpiconchomeon_ [l=gl] {_httpimg_/gl/chomeon.gif}
+
+## "××××¢ ×ª×××" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=he] {_httpimg_/he/chomeof.gif}
+_httpiconchomeon_ [l=he] {_httpimg_/he/chomeon.gif}
+
+## "NASLOVNA" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=hr] {_httpimg_/hr/chomeof.gif}
+_httpiconchomeon_ [l=hr] {_httpimg_/hr/chomeon.gif}
+
+## "ÕÕžÖÕ¶" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=hy] {_httpimg_/hy/chomeof.gif}
+_httpiconchomeon_ [l=hy] {_httpimg_/hy/chomeon.gif}
+
+## "INDUK" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=id] {_httpimg_/id/chomeof.gif}
+_httpiconchomeon_ [l=id] {_httpimg_/id/chomeon.gif}
+
+## "PAGINA PRINCIPALE" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=it] {_httpimg_/it/chomeof.gif}
+_httpiconchomeon_ [l=it] {_httpimg_/it/chomeon.gif}
+
+## "ããŒã " ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=ja] {_httpimg_/ja/chomeof.gif}
+_httpiconchomeon_ [l=ja] {_httpimg_/ja/chomeon.gif}
+
+## "áááááá á áááá áá" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=ka] {_httpimg_/ka/chomeof.gif}
+_httpiconchomeon_ [l=ka] {_httpimg_/ka/chomeon.gif}
+
+## "ÐÐÐ¡Ð«" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=kk] {_httpimg_/kk/chomeof.gif}
+_httpiconchomeon_ [l=kk] {_httpimg_/kk/chomeon.gif}
+
+## "Ò®Ð" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=ky] {_httpimg_/ky/chomeof.gif}
+_httpiconchomeon_ [l=ky] {_httpimg_/ky/chomeon.gif}
+
+## "MÄJA" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=lv] {_httpimg_/lv/chomeof.gif}
+_httpiconchomeon_ [l=lv] {_httpimg_/lv/chomeon.gif}
+
+## "KÄINGA" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=mi] {_httpimg_/mi/chomeof.gif}
+_httpiconchomeon_ [l=mi] {_httpimg_/mi/chomeon.gif}
+
+## "ÐÒ®Ò®Ð " ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=mn] {_httpimg_/mn/chomeof.gif}
+_httpiconchomeon_ [l=mn] {_httpimg_/mn/chomeon.gif}
+
+## "HOOFDPAGINA" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=nl] {_httpimg_/nl/chomeof.gif}
+_httpiconchomeon_ [l=nl] {_httpimg_/nl/chomeon.gif}
+
+## "STRONA GÅÃWNA" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=pl] {_httpimg_/pl/chomeof.gif}
+_httpiconchomeon_ [l=pl] {_httpimg_/pl/chomeon.gif}
+
+## "PRINCIPAL" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=pt-br] {_httpimg_/pt-br/chomeof.gif}
+_httpiconchomeon_ [l=pt-br] {_httpimg_/pt-br/chomeon.gif}
+
+## "ÃNICIO" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=pt-pt] {_httpimg_/pt-pt/chomeof.gif}
+_httpiconchomeon_ [l=pt-pt] {_httpimg_/pt-pt/chomeon.gif}
+
+## "ÐÐÐ§ÐÐÐ" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=ru] {_httpimg_/ru/chomeof.gif}
+_httpiconchomeon_ [l=ru] {_httpimg_/ru/chomeon.gif}
+
+## "PRISTUPNA STRANICA" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=sr] {_httpimg_/sr/chomeof.gif}
+_httpiconchomeon_ [l=sr] {_httpimg_/sr/chomeon.gif}
+
+## "àž«àžà¹àž²à¹àž£àž" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=th] {_httpimg_/th/chomeof.gif}
+_httpiconchomeon_ [l=th] {_httpimg_/th/chomeon.gif}
+
+## "ANA SAYFA" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=tr] {_httpimg_/tr/chomeof.gif}
+_httpiconchomeon_ [l=tr] {_httpimg_/tr/chomeon.gif}
+
+## "ÐÐÐÐÐšÐÐ¯ Ð¡Ð¢ÐÐ ÐÐÐÐ" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=uk] {_httpimg_/uk/chomeof.gif}
+_httpiconchomeon_ [l=uk] {_httpimg_/uk/chomeon.gif}
+
+## "Trang chá»§" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=vi] {_httpimg_/vi/chomeof.gif}
+_httpiconchomeon_ [l=vi] {_httpimg_/vi/chomeon.gif}
+
+## "äž»é¡µ" ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=zh] {_httpimg_/zh/chomeof.gif}
+_httpiconchomeon_ [l=zh] {_httpimg_/zh/chomeon.gif}
+
+## "éŠé " ## top_nav_button ## chome ##
+_httpiconchomeof_ [l=zh-tr] {_httpimg_/zh-tr/chomeof.gif}
+_httpiconchomeon_ [l=zh-tr] {_httpimg_/zh-tr/chomeon.gif}
+
+##############
+# PREFERENCES
+##############
+
+## "PREFERENCES" ## top_nav_button ## cpref ##
+_httpiconcprefof_ {_httpimg_/en/cprefof.gif}
+_httpiconcprefon_ {_httpimg_/en/cprefon.gif}
+
+## "Ø§ÙØ®ÙØ§Ø±Ø§Øª" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=ar] {_httpimg_/ar/cprefof.gif}
+_httpiconcprefon_ [l=ar] {_httpimg_/ar/cprefon.gif}
+
+## "àŠªàŠàŠšà§àŠŠ" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=bn] {_httpimg_/bn/cprefof.gif}
+_httpiconcprefon_ [l=bn] {_httpimg_/bn/cprefon.gif}
+
+## "PREFERÃNCIES" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=ca] {_httpimg_/ca/cprefof.gif}
+_httpiconcprefon_ [l=ca] {_httpimg_/ca/cprefon.gif}
+
+## "NASTAVENÃ" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=cs] {_httpimg_/cs/cprefof.gif}
+_httpiconcprefon_ [l=cs] {_httpimg_/cs/cprefon.gif}
+
+## "VOREINSTELLUNGEN" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=de] {_httpimg_/de/cprefof.gif}
+_httpiconcprefon_ [l=de] {_httpimg_/de/cprefon.gif}
+
+## "ÎÎ ÎÎÎÎÎÎ£" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=el] {_httpimg_/el/cprefof.gif}
+_httpiconcprefon_ [l=el] {_httpimg_/el/cprefon.gif}
+
+## "PREFERENCIAS" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=es] {_httpimg_/es/cprefof.gif}
+_httpiconcprefon_ [l=es] {_httpimg_/es/cprefon.gif}
+
+## "ØªÙØžÙÙ
+Ø§Øª" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=fa] {_httpimg_/fa/cprefof.gif}
+_httpiconcprefon_ [l=fa] {_httpimg_/fa/cprefon.gif}
+
+## "ASETUKSET" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=fi] {_httpimg_/fi/cprefof.gif}
+_httpiconcprefon_ [l=fi] {_httpimg_/fi/cprefon.gif}
+
+## "PRÃFÃRENCES" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=fr] {_httpimg_/fr/cprefof.gif}
+_httpiconcprefon_ [l=fr] {_httpimg_/fr/cprefon.gif}
+
+## "PREFERENCIAS" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=gl] {_httpimg_/gl/cprefof.gif}
+_httpiconcprefon_ [l=gl] {_httpimg_/gl/cprefon.gif}
+
+## "×ª××××€×××¢" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=he] {_httpimg_/he/cprefof.gif}
+_httpiconcprefon_ [l=he] {_httpimg_/he/cprefon.gif}
+
+## "POSTAVKE" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=hr] {_httpimg_/hr/cprefof.gif}
+_httpiconcprefon_ [l=hr] {_httpimg_/hr/cprefon.gif}
+
+## "ÕÔ±ÔœÔ±ÕÔ±ÕÕÕÕÔ¹Õ
+ÕÕÕÕÔµÕ" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=hy] {_httpimg_/hy/cprefof.gif}
+_httpiconcprefon_ [l=hy] {_httpimg_/hy/cprefon.gif}
+
+## "PREFERENSI" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=id] {_httpimg_/id/cprefof.gif}
+_httpiconcprefon_ [l=id] {_httpimg_/id/cprefon.gif}
+
+## "IMPOSTAZIONI" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=it] {_httpimg_/it/cprefof.gif}
+_httpiconcprefon_ [l=it] {_httpimg_/it/cprefon.gif}
+
+## "ããªãã¡ã¬ã³ã¹" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=ja] {_httpimg_/ja/cprefof.gif}
+_httpiconcprefon_ [l=ja] {_httpimg_/ja/cprefon.gif}
+
+## "ááá áááá¢á ááá" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=ka] {_httpimg_/ka/cprefof.gif}
+_httpiconcprefon_ [l=ka] {_httpimg_/ka/cprefon.gif}
+
+## "ÐÒ®ÐÐÐÐ ÐÐÐÐ¢ÐÐ Ð£ÐÐÐ " ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=kk] {_httpimg_/kk/cprefof.gif}
+_httpiconcprefon_ [l=kk] {_httpimg_/kk/cprefon.gif}
+
+## "Ð¢Ò®ÐÓšÐ¢Ò®Ò®ÐÓšÐ " ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=ky] {_httpimg_/ky/cprefof.gif}
+_httpiconcprefon_ [l=ky] {_httpimg_/ky/cprefon.gif}
+
+## "IESTATÄªJUMI" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=lv] {_httpimg_/lv/cprefof.gif}
+_httpiconcprefon_ [l=lv] {_httpimg_/lv/cprefon.gif}
+
+## "KÅWHIRINGA" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=mi] {_httpimg_/mi/cprefof.gif}
+_httpiconcprefon_ [l=mi] {_httpimg_/mi/cprefon.gif}
+
+## "Ð¢ÐÐ¥ÐÐ ÐÐÐ" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=mn] {_httpimg_/mn/cprefof.gif}
+_httpiconcprefon_ [l=mn] {_httpimg_/mn/cprefon.gif}
+
+## "PREFERENTIES" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=nl] {_httpimg_/nl/cprefof.gif}
+_httpiconcprefon_ [l=nl] {_httpimg_/nl/cprefon.gif}
+
+## "PREFERENCJE" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=pl] {_httpimg_/pl/cprefof.gif}
+_httpiconcprefon_ [l=pl] {_httpimg_/pl/cprefon.gif}
+
+## "PREFERÃNCIAS" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=pt-br] {_httpimg_/pt-br/cprefof.gif}
+_httpiconcprefon_ [l=pt-br] {_httpimg_/pt-br/cprefon.gif}
+
+## "PREFERÃNCIAS" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=pt-pt] {_httpimg_/pt-pt/cprefof.gif}
+_httpiconcprefon_ [l=pt-pt] {_httpimg_/pt-pt/cprefon.gif}
+
+## "ÐÐÐ¡Ð¢Ð ÐÐÐÐ" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=ru] {_httpimg_/ru/cprefof.gif}
+_httpiconcprefon_ [l=ru] {_httpimg_/ru/cprefon.gif}
+
+## "PODEÅ AVANJA" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=sr] {_httpimg_/sr/cprefof.gif}
+_httpiconcprefon_ [l=sr] {_httpimg_/sr/cprefon.gif}
+
+## "àžªàžŽàžàžàžŽàžàžŽà¹àžšàž©" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=th] {_httpimg_/th/cprefof.gif}
+_httpiconcprefon_ [l=th] {_httpimg_/th/cprefon.gif}
+
+## "TERCÄ°HLER" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=tr] {_httpimg_/tr/cprefof.gif}
+_httpiconcprefon_ [l=tr] {_httpimg_/tr/cprefon.gif}
+
+## "ÐÐÐÐÐšÐ¢Ð£ÐÐÐÐÐ¯" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=uk] {_httpimg_/uk/cprefof.gif}
+_httpiconcprefon_ [l=uk] {_httpimg_/uk/cprefon.gif}
+
+## "Thuá»c tÃ­nh" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=vi] {_httpimg_/vi/cprefof.gif}
+_httpiconcprefon_ [l=vi] {_httpimg_/vi/cprefon.gif}
+
+## "éé¡¹" ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=zh] {_httpimg_/zh/cprefof.gif}
+_httpiconcprefon_ [l=zh] {_httpimg_/zh/cprefon.gif}
+
+## "åäººåå¥œèš­å®é " ## top_nav_button ## cpref ##
+_httpiconcprefof_ [l=zh-tr] {_httpimg_/zh-tr/cprefof.gif}
+_httpiconcprefon_ [l=zh-tr] {_httpimg_/zh-tr/cprefon.gif}
+
+## "preferences" ## green_title ## h_pref ##
+_httpiconhpref_ {_httpimg_/en/h\_pref.gif}
+_widthhpref_ {200}
+_heighthpref_ {57}
+## "Ø§ÙØ®ÙØ§Ø±Ø§Øª" ## green_title ## h_pref ##
+_httpiconhpref_ [l=ar] {_httpimg_/ar/h\_pref.gif}
+_widthhpref_ [l=ar] {200}
+_heighthpref_ [l=ar] {57}
+## "àŠªàŠàŠšà§àŠŠàŠà§àŠ²àŠ¿" ## green_title ## h_pref ##
+_httpiconhpref_ [l=bn] {_httpimg_/bn/h\_pref.gif}
+_widthhpref_ [l=bn] {200}
+_heighthpref_ [l=bn] {57}
+## "preferÃšncies" ## green_title ## h_pref ##
+_httpiconhpref_ [l=ca] {_httpimg_/ca/h\_pref.gif}
+_widthhpref_ [l=ca] {200}
+_heighthpref_ [l=ca] {57}
+## "nastavenÃ­" ## green_title ## h_pref ##
+_httpiconhpref_ [l=cs] {_httpimg_/cs/h\_pref.gif}
+_widthhpref_ [l=cs] {200}
+_heighthpref_ [l=cs] {57}
+## "voreinstellungen" ## green_title ## h_pref ##
+_httpiconhpref_ [l=de] {_httpimg_/de/h\_pref.gif}
+_widthhpref_ [l=de] {200}
+_heighthpref_ [l=de] {57}
+## "ÎµÏÎ¹Î»Î¿Î³Î­Ï" ## green_title ## h_pref ##
+_httpiconhpref_ [l=el] {_httpimg_/el/h\_pref.gif}
+_widthhpref_ [l=el] {200}
+_heighthpref_ [l=el] {57}
+## "preferencias" ## green_title ## h_pref ##
+_httpiconhpref_ [l=es] {_httpimg_/es/h\_pref.gif}
+_widthhpref_ [l=es] {200}
+_heighthpref_ [l=es] {57}
+## "ØªÙØžÛÙ
+Ø§Øª" ## green_title ## h_pref ##
+_httpiconhpref_ [l=fa] {_httpimg_/fa/h\_pref.gif}
+_widthhpref_ [l=fa] {200}
+_heighthpref_ [l=fa] {57}
+## "Asetukset" ## green_title ## h_pref ##
+_httpiconhpref_ [l=fi] {_httpimg_/fi/h\_pref.gif}
+_widthhpref_ [l=fi] {200}
+_heighthpref_ [l=fi] {57}
+## "prÃ©fÃ©rences" ## green_title ## h_pref ##
+_httpiconhpref_ [l=fr] {_httpimg_/fr/h\_pref.gif}
+_widthhpref_ [l=fr] {200}
+_heighthpref_ [l=fr] {57}
+## "preferencias" ## green_title ## h_pref ##
+_httpiconhpref_ [l=gl] {_httpimg_/gl/h\_pref.gif}
+_widthhpref_ [l=gl] {200}
+_heighthpref_ [l=gl] {57}
+## "×ª×××€×××¢" ## green_title ## h_pref ##
+_httpiconhpref_ [l=he] {_httpimg_/he/h\_pref.gif}
+_widthhpref_ [l=he] {200}
+_heighthpref_ [l=he] {57}
+## "POSTAVKE" ## green_title ## h_pref ##
+_httpiconhpref_ [l=hr] {_httpimg_/hr/h_pref.gif}
+_widthhpref_ [l=hr] {200}
+_heighthpref_ [l=hr] {57}
+## "Õ¶Õ¡Õ­Õ¡ÕºÕ¡Õ¿ÕŸÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö:" ## green_title ## h_pref ##
+_httpiconhpref_ [l=hy] {_httpimg_/hy/h\_pref.gif}
+_widthhpref_ [l=hy] {200}
+_heighthpref_ [l=hy] {57}
+## "preferensi" ## green_title ## h_pref ##
+_httpiconhpref_ [l=id] {_httpimg_/id/h\_pref.gif}
+_widthhpref_ [l=id] {200}
+_heighthpref_ [l=id] {57}
+## "impostazioni" ## green_title ## h_pref ##
+_httpiconhpref_ [l=it] {_httpimg_/it/h\_pref.gif}
+_widthhpref_ [l=it] {200}
+_heighthpref_ [l=it] {57}
+## "ááá áááá¢á ááá" ## green_title ## h_pref ##
+_httpiconhpref_ [l=ka] {_httpimg_/ka/h\_pref.gif}
+_widthhpref_ [l=ka] {258}
+_heighthpref_ [l=ka] {74}
+## "ÐºÒ¯Ð¹ÑÐœÐµ ÐºÐµÐ»ÑÑÑÑÐ»ÐµÑ" ## green_title ## h_pref ##
+_httpiconhpref_ [l=kk] {_httpimg_/kk/h\_pref.gif}
+_widthhpref_ [l=kk] {200}
+_heighthpref_ [l=kk] {57}
+## "ÑÒ¯Ð·Ó©ÑÒ¯Ò¯Ð»Ó©Ñ" ## green_title ## h_pref ##
+_httpiconhpref_ [l=ky] {_httpimg_/ky/h\_pref.gif}
+_widthhpref_ [l=ky] {200}
+_heighthpref_ [l=ky] {57}
+## "iestatÄ«jumi" ## green_title ## h_pref ##
+_httpiconhpref_ [l=lv] {_httpimg_/lv/h\_pref.gif}
+_widthhpref_ [l=lv] {200}
+_heighthpref_ [l=lv] {57}
+## "kÅwhiringa" ## green_title ## h_pref ##
+_httpiconhpref_ [l=mi] {_httpimg_/mi/h\_pref.gif}
+_widthhpref_ [l=mi] {200}
+_heighthpref_ [l=mi] {57}
+## "ÑÐŸÑ
+ÐžÑÐ³ÐŸÐŸ" ## green_title ## h_pref ##
+_httpiconhpref_ [l=mn] {_httpimg_/mn/h\_pref.gif}
+_widthhpref_ [l=mn] {200}
+_heighthpref_ [l=mn] {57}
+## "preferenties" ## green_title ## h_pref ##
+_httpiconhpref_ [l=nl] {_httpimg_/nl/h\_pref.gif}
+_widthhpref_ [l=nl] {200}
+_heighthpref_ [l=nl] {57}
+## "preferencje" ## green_title ## h_pref ##
+_httpiconhpref_ [l=pl] {_httpimg_/pl/h\_pref.gif}
+_widthhpref_ [l=pl] {200}
+_heighthpref_ [l=pl] {57}
+## "preferÃªncias" ## green_title ## h_pref ##
+_httpiconhpref_ [l=pt-br] {_httpimg_/pt-br/h\_pref.gif}
+_widthhpref_ [l=pt-br] {200}
+_heighthpref_ [l=pt-br] {57}
+## "preferÃªncias" ## green_title ## h_pref ##
+_httpiconhpref_ [l=pt-pt] {_httpimg_/pt-pt/h\_pref.gif}
+_widthhpref_ [l=pt-pt] {200}
+_heighthpref_ [l=pt-pt] {57}
+## "ÐœÐ°ÑÑÑÐŸÐ¹ÐºÐž" ## green_title ## h_pref ##
+_httpiconhpref_ [l=ru] {_httpimg_/ru/h\_pref.gif}
+_widthhpref_ [l=ru] {200}
+_heighthpref_ [l=ru] {57}
+## "podeÅ¡avanja" ## green_title ## h_pref ##
+_httpiconhpref_ [l=sr] {_httpimg_/sr/h\_pref.gif}
+_widthhpref_ [l=sr] {200}
+_heighthpref_ [l=sr] {57}
+## "àžªàžŽàžàžàžŽàžàžŽà¹àžšàž©" ## green_title ## h_pref ##
+_httpiconhpref_ [l=th] {_httpimg_/th/h\_pref.gif}
+_widthhpref_ [l=th] {200}
+_heighthpref_ [l=th] {57}
+## "tercihler" ## green_title ## h_pref ##
+_httpiconhpref_ [l=tr] {_httpimg_/tr/h\_pref.gif}
+_widthhpref_ [l=tr] {200}
+_heighthpref_ [l=tr] {57}
+## "ÐœÐ°Ð»Ð°ÑÑÑÐ²Ð°ÐœÐœÑ" ## green_title ## h_pref ##
+_httpiconhpref_ [l=uk] {_httpimg_/uk/h\_pref.gif}
+_widthhpref_ [l=uk] {200}
+_heighthpref_ [l=uk] {57}
+## "thuá»c tÃ­nh" ## green_title ## h_pref ##
+_httpiconhpref_ [l=vi] {_httpimg_/vi/h\_pref.gif}
+_widthhpref_ [l=vi] {200}
+_heighthpref_ [l=vi] {57}
+## "éé¡¹" ## green_title ## h_pref ##
+_httpiconhpref_ [l=zh] {_httpimg_/zh/h\_pref.gif}
+_widthhpref_ [l=zh] {200}
+_heighthpref_ [l=zh] {57}
+## "åå¥œèš­å®" ## green_title ## h_pref ##
+_httpiconhpref_ [l=zh-tr] {_httpimg_/zh-tr/h\_pref.gif}
+_widthhpref_ [l=zh-tr] {200}
+_heighthpref_ [l=zh-tr] {57}
+
+####################
+# SEND FEEDBACK
+####################
+
+## "SEND FEEDBACK" ## top_nav_button ## cusab ##
+_httpiconcusabof_ {_httpimg_/en/cusabof.gif}
+_httpiconcusabon_ {_httpimg_/en/cusabon.gif}
+
+## "Ø§Ø±Ø³Ù Ø±Ø£ÙÙ" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=ar] {_httpimg_/ar/cusabof.gif}
+_httpiconcusabon_ [l=ar] {_httpimg_/ar/cusabon.gif}
+
+## "àŠ®àŠ€àŠŸàŠ®àŠ€ àŠàŠŸàŠšàŠŸàŠš" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=bn] {_httpimg_/bn/cusabof.gif}
+_httpiconcusabon_ [l=bn] {_httpimg_/bn/cusabon.gif}
+
+## "ENVIA COMENTARI" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=ca] {_httpimg_/ca/cusabof.gif}
+_httpiconcusabon_ [l=ca] {_httpimg_/ca/cusabon.gif}
+
+## "ODESLAT ZPRÃVU" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=cs] {_httpimg_/cs/cusabof.gif}
+_httpiconcusabon_ [l=cs] {_httpimg_/cs/cusabon.gif}
+
+## "Î£Î€ÎÎÎÎ€Î ÎÎÎ£ Î€Î ÎÎÎ©ÎÎ Î£ÎÎ£" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=el] {_httpimg_/el/cusabof.gif}
+_httpiconcusabon_ [l=el] {_httpimg_/el/cusabon.gif}
+
+## "ENVIAR COMENTARIOS" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=es] {_httpimg_/es/cusabof.gif}
+_httpiconcusabon_ [l=es] {_httpimg_/es/cusabon.gif}
+
+## "Ø§Ø±Ø³Ø§Ù ØšØ§Ø²Ø®ÙØ±Ø¯" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=fa] {_httpimg_/fa/cusabof.gif}
+_httpiconcusabon_ [l=fa] {_httpimg_/fa/cusabon.gif}
+
+## "LÃHETÃ PALUTETTA" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=fi] {_httpimg_/fi/cusabof.gif}
+_httpiconcusabon_ [l=fi] {_httpimg_/fi/cusabon.gif}
+
+## "ENVOYER FEEDBACK" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=fr] {_httpimg_/fr/cusabof.gif}
+_httpiconcusabon_ [l=fr] {_httpimg_/fr/cusabon.gif}
+
+## "ÕÖÕÔ±ÕÔ¿Ô»Õ Ô¿Ô±ÕÔŸÔ»Õ" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=hy] {_httpimg_/hy/cusabof.gif}
+_httpiconcusabon_ [l=hy] {_httpimg_/hy/cusabon.gif}
+
+## "KIRIM UMPAN BALIK" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=id] {_httpimg_/id/cusabof.gif}
+_httpiconcusabon_ [l=id] {_httpimg_/id/cusabon.gif}
+
+## "INVIA FEEDBACK" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=it] {_httpimg_/it/cusabof.gif}
+_httpiconcusabon_ [l=it] {_httpimg_/it/cusabon.gif}
+
+## "ãã£ãŒãããã¯ãéã" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=ja] {_httpimg_/ja/cusabof.gif}
+_httpiconcusabon_ [l=ja] {_httpimg_/ja/cusabon.gif}
+
+## "á£áá£áááášáá á" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=ka] {_httpimg_/ka/cusabof.gif}
+_httpiconcusabon_ [l=ka] {_httpimg_/ka/cusabon.gif}
+
+## "ÐÐÐ¢ ÐÐÐÐ£Ð£" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=ky] {_httpimg_/ky/cusabof.gif}
+_httpiconcusabon_ [l=ky] {_httpimg_/ky/cusabon.gif}
+
+## "SÅªTÄªT ATGRIEZENISKO SAITI" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=lv] {_httpimg_/lv/cusabof.gif}
+_httpiconcusabon_ [l=lv] {_httpimg_/lv/cusabon.gif}
+
+## "WHAKAHOKI KÅRERO MAI" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=mi] {_httpimg_/mi/cusabof.gif}
+_httpiconcusabon_ [l=mi] {_httpimg_/mi/cusabon.gif}
+
+## "Ð¥ÐÐÐÐÐ ÐÐÐ ÐÐ¥" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=mn] {_httpimg_/mn/cusabof.gif}
+_httpiconcusabon_ [l=mn] {_httpimg_/mn/cusabon.gif}
+
+## "WYÅLIJ UWAGI" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=pl] {_httpimg_/pl/cusabof.gif}
+_httpiconcusabon_ [l=pl] {_httpimg_/pl/cusabon.gif}
+
+## "ENVIAR NOTA" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=pt-pt] {_httpimg_/pt-pt/cusabof.gif}
+_httpiconcusabon_ [l=pt-pt] {_httpimg_/pt-pt/cusabon.gif}
+
+## "ÐÐ¡ÐÐÐÐ¬ÐÐÐÐÐ¢Ð¬ ÐÐÐ ÐÐ¢ÐÐ£Ð® Ð¡ÐÐ¯ÐÐ¬" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=ru] {_httpimg_/ru/cusabof.gif}
+_httpiconcusabon_ [l=ru] {_httpimg_/ru/cusabon.gif}
+
+## "POÅ ALJI POVRATNU INFORMACIJU" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=sr] {_httpimg_/sr/cusabof.gif}
+_httpiconcusabon_ [l=sr] {_httpimg_/sr/cusabon.gif}
+
+## "àžªà¹àžàžàž¥àžªàž°àžà¹àž­àžàžàž¥àž±àž" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=th] {_httpimg_/th/cusabof.gif}
+_httpiconcusabon_ [l=th] {_httpimg_/th/cusabon.gif}
+
+## "GERÄ°BÄ°LDÄ°RÄ°M" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=tr] {_httpimg_/tr/cusabof.gif}
+_httpiconcusabon_ [l=tr] {_httpimg_/tr/cusabon.gif}
+
+## "ÐÐÐšÐÐ¢Ð¬ ÐÐÐ" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=uk] {_httpimg_/uk/cusabof.gif}
+_httpiconcusabon_ [l=uk] {_httpimg_/uk/cusabon.gif}
+
+## "Pháº£n há»i" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=vi] {_httpimg_/vi/cusabof.gif}
+_httpiconcusabon_ [l=vi] {_httpimg_/vi/cusabon.gif}
+
+## "åéŠä¿¡æ¯" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=zh] {_httpimg_/zh/cusabof.gif}
+_httpiconcusabon_ [l=zh] {_httpimg_/zh/cusabon.gif}
+
+## "å°åèŠéåº" ## top_nav_button ## cusab ##
+_httpiconcusabof_ [l=zh-tr] {_httpimg_/zh-tr/cusabof.gif}
+_httpiconcusabon_ [l=zh-tr] {_httpimg_/zh-tr/cusabon.gif}
+
+##################################################
+# CONTINUE button (for document content expanding)
+##################################################
+
+## "CONTINUE?" ## top_nav_button ## cont ##
+_httpiconcontoff_ {_httpimg_/en/contof.gif}
+_httpiconconton_ {_httpimg_/en/conton.gif}
+
+## "ÙØ§ØµÙ?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=ar] {_httpimg_/ar/contof.gif}
+_httpiconconton_ [l=ar] {_httpimg_/ar/conton.gif}
+
+## "àŠàŠ²àŠ¬à§ ??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=bn] {_httpimg_/bn/contof.gif}
+_httpiconconton_ [l=bn] {_httpimg_/bn/conton.gif}
+
+## "VOLEU CONTINUAR??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=ca] {_httpimg_/ca/contof.gif}
+_httpiconconton_ [l=ca] {_httpimg_/ca/conton.gif}
+
+## "POKRAÄOVAT??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=cs] {_httpimg_/cs/contof.gif}
+_httpiconconton_ [l=cs] {_httpimg_/cs/conton.gif}
+
+## "WEITERMACHEN?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=de] {_httpimg_/de/contof.gif}
+_httpiconconton_ [l=de] {_httpimg_/de/conton.gif}
+
+## "ÎÎ­Î»ÎµÏÎµ ÎœÎ± ÏÏ
+ÎœÎµÏÎ¯ÏÎµÏÎµ;?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=el] {_httpimg_/el/contof.gif}
+_httpiconconton_ [l=el] {_httpimg_/el/conton.gif}
+
+## "Â¿DESEA CONTINUAR???" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=es] {_httpimg_/es/contof.gif}
+_httpiconconton_ [l=es] {_httpimg_/es/conton.gif}
+
+## "Ø§Ø¯Ø§Ù
+Ù" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=fa] {_httpimg_/fa/contof.gif}
+_httpiconconton_ [l=fa] {_httpimg_/fa/conton.gif}
+
+## "JATKA??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=fi] {_httpimg_/fi/contof.gif}
+_httpiconconton_ [l=fi] {_httpimg_/fi/conton.gif}
+
+## "CONTINUER ??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=fr] {_httpimg_/fr/contof.gif}
+_httpiconconton_ [l=fr] {_httpimg_/fr/conton.gif}
+
+## "Â¿DESEXA CONTINUAR?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=gl] {_httpimg_/gl/contof.gif}
+_httpiconconton_ [l=gl] {_httpimg_/gl/conton.gif}
+
+## " " ×××©×××" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=he] {_httpimg_/he/contoff.gif}
+_httpiconconton_ [l=he] {_httpimg_/he/conton.gif}
+
+## "NASTAVAK?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=hr] {_httpimg_/hr/contof.gif}
+_httpiconconton_ [l=hr] {_httpimg_/hr/conton.gif}
+
+## "ÕÔ±ÕÕÕÕÔ±Ô¿ÔµÕÔŒ?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=hy] {_httpimg_/hy/contof.gif}
+_httpiconconton_ [l=hy] {_httpimg_/hy/conton.gif}
+
+## "TERUSKAN??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=id] {_httpimg_/id/contof.gif}
+_httpiconconton_ [l=id] {_httpimg_/id/conton.gif}
+
+## "CONTINUA??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=it] {_httpimg_/it/contof.gif}
+_httpiconconton_ [l=it] {_httpimg_/it/conton.gif}
+
+## "ç¶ããŸããïŒ?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=ja] {_httpimg_/ja/contof.gif}
+_httpiconconton_ [l=ja] {_httpimg_/ja/conton.gif}
+
+## "áááá á«ááááá?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=ka] {_httpimg_/ka/contof.gif}
+_httpiconconton_ [l=ka] {_httpimg_/ka/conton.gif}
+
+## "ÐÐÐÒÐÐ¡Ð¢Ð«Ð ÐÐÐ«Ð ÐÐ?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=kk] {_httpimg_/kk/contof.gif}
+_httpiconconton_ [l=kk] {_httpimg_/kk/conton.gif}
+
+## "Ð£ÐÐÐÐ¢Ð«ÐÐ¡Ð«ÐÐÐ«??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=ky] {_httpimg_/ky/contof.gif}
+_httpiconconton_ [l=ky] {_httpimg_/ky/conton.gif}
+
+## "TURPINÄT???" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=lv] {_httpimg_/lv/contof.gif}
+_httpiconconton_ [l=lv] {_httpimg_/lv/conton.gif}
+
+## "HAERE TONU??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=mi] {_httpimg_/mi/contof.gif}
+_httpiconconton_ [l=mi] {_httpimg_/mi/conton.gif}
+
+## "Ò®Ð ÐÐ­ÐÐÐÒ®Ò®ÐÐ­Ð¥ Ò®Ò®??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=mn] {_httpimg_/mn/contof.gif}
+_httpiconconton_ [l=mn] {_httpimg_/mn/conton.gif}
+
+## "VOORTZETTEN?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=nl] {_httpimg_/nl/contof.gif}
+_httpiconconton_ [l=nl] {_httpimg_/nl/conton.gif}
+
+## "KONTYNUOWAÄ??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=pl] {_httpimg_/pl/contof.gif}
+_httpiconconton_ [l=pl] {_httpimg_/pl/conton.gif}
+
+## "CONTINUAR?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=pt-br] {_httpimg_/pt-br/contof.gif}
+_httpiconconton_ [l=pt-br] {_httpimg_/pt-br/conton.gif}
+
+## "CONTINUAR??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=pt-pt] {_httpimg_/pt-pt/contof.gif}
+_httpiconconton_ [l=pt-pt] {_httpimg_/pt-pt/conton.gif}
+
+## "ÐÐ ÐÐÐÐÐÐÐ¢Ð¬??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=ru] {_httpimg_/ru/contof.gif}
+_httpiconconton_ [l=ru] {_httpimg_/ru/conton.gif}
+
+## "NASTAVAK ??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=sr] {_httpimg_/sr/contof.gif}
+_httpiconconton_ [l=sr] {_httpimg_/sr/conton.gif}
+
+## "àžà¹àž­à¹àžàž·à¹àž­àžàž«àž£àž·àž­à¹àž¡à¹?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=th] {_httpimg_/th/contof.gif}
+_httpiconconton_ [l=th] {_httpimg_/th/conton.gif}
+
+## "DEVAM??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=tr] {_httpimg_/tr/contof.gif}
+_httpiconconton_ [l=tr] {_httpimg_/tr/conton.gif}
+
+## "ÐÐ ÐÐÐÐÐÐÐ¢Ð??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=uk] {_httpimg_/uk/contof.gif}
+_httpiconconton_ [l=uk] {_httpimg_/uk/conton.gif}
+
+## "Tiáº¿p tá»¥c??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=vi] {_httpimg_/vi/contof.gif}
+_httpiconconton_ [l=vi] {_httpimg_/vi/conton.gif}
+
+## "ç»§ç»­ïŒ??" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=zh] {_httpimg_/zh/contof.gif}
+_httpiconconton_ [l=zh] {_httpimg_/zh/conton.gif}
+
+## "ç¹ŒçºïŒ?" ## top_nav_button ## cont ##
+_httpiconcontoff_ [l=zh-tr] {_httpimg_/zh-tr/contof.gif}
+_httpiconconton_ [l=zh-tr] {_httpimg_/zh-tr/conton.gif}
+
+
+###########################
+# common title images
+#############################
+
+## "about" ## green_title ## h_about ##
+_httpiconhabout_ {_httpimg_/en/h\_about.gif}
+_widthhabout_ {200}
+_heighthabout_ {57}
+## "Ø­ÙÙ" ## green_title ## h_about ##
+_httpiconhabout_ [l=ar] {_httpimg_/ar/h\_about.gif}
+_widthhabout_ [l=ar] {200}
+_heighthabout_ [l=ar] {57}
+## "àŠžàŠ®à§àŠªàŠ°à§àŠà§" ## green_title ## h_about ##
+_httpiconhabout_ [l=bn] {_httpimg_/bn/h\_about.gif}
+_widthhabout_ [l=bn] {200}
+_heighthabout_ [l=bn] {57}
+## "sobre" ## green_title ## h_about ##
+_httpiconhabout_ [l=ca] {_httpimg_/ca/h\_about.gif}
+_widthhabout_ [l=ca] {200}
+_heighthabout_ [l=ca] {57}
+## "o nÃ¡s" ## green_title ## h_about ##
+_httpiconhabout_ [l=cs] {_httpimg_/cs/h\_about.gif}
+_widthhabout_ [l=cs] {200}
+_heighthabout_ [l=cs] {57}
+## "info" ## green_title ## h_about ##
+_httpiconhabout_ [l=de] {_httpimg_/de/h\_about.gif}
+_widthhabout_ [l=de] {200}
+_heighthabout_ [l=de] {57}
+## "ÏÎ»Î·ÏÎ¿ÏÎ¿ÏÎ¯ÎµÏ" ## green_title ## h_about ##
+_httpiconhabout_ [l=el] {_httpimg_/el/h\_about.gif}
+_widthhabout_ [l=el] {200}
+_heighthabout_ [l=el] {57}
+## "acerca de" ## green_title ## h_about ##
+_httpiconhabout_ [l=es] {_httpimg_/es/h\_about.gif}
+_widthhabout_ [l=es] {200}
+_heighthabout_ [l=es] {57}
+## "Ø¯Ø±ØšØ§Ø±Ù" ## green_title ## h_about ##
+_httpiconhabout_ [l=fa] {_httpimg_/fa/h\_about.gif}
+_widthhabout_ [l=fa] {200}
+_heighthabout_ [l=fa] {57}
+## "YleistÃ€" ## green_title ## h_about ##
+_httpiconhabout_ [l=fi] {_httpimg_/fi/h\_about.gif}
+_widthhabout_ [l=fi] {200}
+_heighthabout_ [l=fi] {57}
+## "Ã propos" ## green_title ## h_about ##
+_httpiconhabout_ [l=fr] {_httpimg_/fr/h\_about.gif}
+_widthhabout_ [l=fr] {200}
+_heighthabout_ [l=fr] {57}
+## "acerca de" ## green_title ## h_about ##
+_httpiconhabout_ [l=gl] {_httpimg_/gl/h\_about.gif}
+_widthhabout_ [l=gl] {200}
+_heighthabout_ [l=gl] {57}
+## "××¢" ## green_title ## h_about ##
+_httpiconhabout_ [l=he] {_httpimg_/he/h\_about.gif}
+_widthhabout_ [l=he] {200}
+_heighthabout_ [l=he] {57}
+## "o zbirci" ## green_title ## h_about ##
+_httpiconhabout_ [l=hr] {_httpimg_/hr/h_about.gif}
+_widthhabout_ [l=hr] {200}
+_heighthabout_ [l=hr] {57}
+## "ÕŽÕ¡ÕœÕ«Õ¶" ## green_title ## h_about ##
+_httpiconhabout_ [l=hy] {_httpimg_/hy/h\_about.gif}
+_widthhabout_ [l=hy] {200}
+_heighthabout_ [l=hy] {57}
+## "about" ## green_title ## h_about ##
+_httpiconhabout_ [l=id] {_httpimg_/id/h\_about.gif}
+_widthhabout_ [l=id] {200}
+_heighthabout_ [l=id] {57}
+## "informazioni su" ## green_title ## h_about ##
+_httpiconhabout_ [l=it] {_httpimg_/it/h\_about.gif}
+_widthhabout_ [l=it] {200}
+_heighthabout_ [l=it] {57}
+## "ášáá¡áá®áá" ## green_title ## h_about ##
+_httpiconhabout_ [l=ka] {_httpimg_/ka/h\_about.gif}
+_widthhabout_ [l=ka] {258}
+_heighthabout_ [l=ka] {74}
+## "ÑÐžÐ¿Ð°ÑÑÐ°ÐŒÐ°" ## green_title ## h_about ##
+_httpiconhabout_ [l=kk] {_httpimg_/kk/h\_about.gif}
+_widthhabout_ [l=kk] {200}
+_heighthabout_ [l=kk] {57}
+## "Ð¶Ó©ÐœÒ¯ÐœÐŽÓ©" ## green_title ## h_about ##
+_httpiconhabout_ [l=ky] {_httpimg_/ky/h\_about.gif}
+_widthhabout_ [l=ky] {200}
+_heighthabout_ [l=ky] {57}
+## "par" ## green_title ## h_about ##
+_httpiconhabout_ [l=lv] {_httpimg_/lv/h\_about.gif}
+_widthhabout_ [l=lv] {200}
+_heighthabout_ [l=lv] {57}
+## "e pÄ ana" ## green_title ## h_about ##
+_httpiconhabout_ [l=mi] {_httpimg_/mi/h\_about.gif}
+_widthhabout_ [l=mi] {200}
+_heighthabout_ [l=mi] {57}
+## "ÑÑÑ
+Ð°Ð¹" ## green_title ## h_about ##
+_httpiconhabout_ [l=mn] {_httpimg_/mn/h\_about.gif}
+_widthhabout_ [l=mn] {200}
+_heighthabout_ [l=mn] {57}
+## "informatie" ## green_title ## h_about ##
+_httpiconhabout_ [l=nl] {_httpimg_/nl/h\_about.gif}
+_widthhabout_ [l=nl] {200}
+_heighthabout_ [l=nl] {57}
+## "informacje" ## green_title ## h_about ##
+_httpiconhabout_ [l=pl] {_httpimg_/pl/h\_about.gif}
+_widthhabout_ [l=pl] {200}
+_heighthabout_ [l=pl] {57}
+## "sobre" ## green_title ## h_about ##
+_httpiconhabout_ [l=pt-br] {_httpimg_/pt-br/h\_about.gif}
+_widthhabout_ [l=pt-br] {200}
+_heighthabout_ [l=pt-br] {57}
+## "sobre" ## green_title ## h_about ##
+_httpiconhabout_ [l=pt-pt] {_httpimg_/pt-pt/h\_about.gif}
+_widthhabout_ [l=pt-pt] {200}
+_heighthabout_ [l=pt-pt] {57}
+## "ÐŸÐ¿ÐžÑÐ°ÐœÐžÐµ" ## green_title ## h_about ##
+_httpiconhabout_ [l=ru] {_httpimg_/ru/h\_about.gif}
+_widthhabout_ [l=ru] {200}
+_heighthabout_ [l=ru] {57}
+## "o" ## green_title ## h_about ##
+_httpiconhabout_ [l=sr] {_httpimg_/sr/h\_about.gif}
+_widthhabout_ [l=sr] {200}
+_heighthabout_ [l=sr] {57}
+## "à¹àžàžµà¹àž¢àž§àžàž±àž" ## green_title ## h_about ##
+_httpiconhabout_ [l=th] {_httpimg_/th/h\_about.gif}
+_widthhabout_ [l=th] {200}
+_heighthabout_ [l=th] {57}
+## "hakkÄ±nda" ## green_title ## h_about ##
+_httpiconhabout_ [l=tr] {_httpimg_/tr/h\_about.gif}
+_widthhabout_ [l=tr] {200}
+_heighthabout_ [l=tr] {57}
+## "Ð¿ÑÐŸ" ## green_title ## h_about ##
+_httpiconhabout_ [l=uk] {_httpimg_/uk/h\_about.gif}
+_widthhabout_ [l=uk] {200}
+_heighthabout_ [l=uk] {57}
+## "giá»i thiá»u" ## green_title ## h_about ##
+_httpiconhabout_ [l=vi] {_httpimg_/vi/h\_about.gif}
+_widthhabout_ [l=vi] {200}
+_heighthabout_ [l=vi] {57}
+## "å
+³äº" ## green_title ## h_about ##
+_httpiconhabout_ [l=zh] {_httpimg_/zh/h\_about.gif}
+_widthhabout_ [l=zh] {200}
+_heighthabout_ [l=zh] {57}
+## "éæŒ" ## green_title ## h_about ##
+_httpiconhabout_ [l=zh-tr] {_httpimg_/zh-tr/h\_about.gif}
+_widthhabout_ [l=zh-tr] {200}
+_heighthabout_ [l=zh-tr] {57}
+
+
+############################################################
+# Nav bar images and their title images: search and metadata
+#############################################################
+
+
+## "search" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ {_httpimg_/en/tsrchgr.gif}
+_httpicontsrchof_ {_httpimg_/en/tsrchof.gif}
+_httpicontsrchon_ {_httpimg_/en/tsrchon.gif}
+## "ØšØ­Ø«" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=ar] {_httpimg_/ar/tsrchgr.gif}
+_httpicontsrchof_ [l=ar] {_httpimg_/ar/tsrchof.gif}
+_httpicontsrchon_ [l=ar] {_httpimg_/ar/tsrchon.gif}
+## "àŠàŠà§àŠà§àŠš" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=bn] {_httpimg_/bn/tsrchgr.gif}
+_httpicontsrchof_ [l=bn] {_httpimg_/bn/tsrchof.gif}
+_httpicontsrchon_ [l=bn] {_httpimg_/bn/tsrchon.gif}
+## "cerca" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=ca] {_httpimg_/ca/tsrchgr.gif}
+_httpicontsrchof_ [l=ca] {_httpimg_/ca/tsrchof.gif}
+_httpicontsrchon_ [l=ca] {_httpimg_/ca/tsrchon.gif}
+## "hledej" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=cs] {_httpimg_/cs/tsrchgr.gif}
+_httpicontsrchof_ [l=cs] {_httpimg_/cs/tsrchof.gif}
+_httpicontsrchon_ [l=cs] {_httpimg_/cs/tsrchon.gif}
+## "suche" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=de] {_httpimg_/de/tsrchgr.gif}
+_httpicontsrchof_ [l=de] {_httpimg_/de/tsrchof.gif}
+_httpicontsrchon_ [l=de] {_httpimg_/de/tsrchon.gif}
+## "Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=el] {_httpimg_/el/tsrchgr.gif}
+_httpicontsrchof_ [l=el] {_httpimg_/el/tsrchof.gif}
+_httpicontsrchon_ [l=el] {_httpimg_/el/tsrchon.gif}
+## "buscar" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=es] {_httpimg_/es/tsrchgr.gif}
+_httpicontsrchof_ [l=es] {_httpimg_/es/tsrchof.gif}
+_httpicontsrchon_ [l=es] {_httpimg_/es/tsrchon.gif}
+## "Ø¬Ø³ØªØ¬Ù" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=fa] {_httpimg_/fa/tsrchgr.gif}
+_httpicontsrchof_ [l=fa] {_httpimg_/fa/tsrchof.gif}
+_httpicontsrchon_ [l=fa] {_httpimg_/fa/tsrchon.gif}
+## "haku" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=fi] {_httpimg_/fi/tsrchgr.gif}
+_httpicontsrchof_ [l=fi] {_httpimg_/fi/tsrchof.gif}
+_httpicontsrchon_ [l=fi] {_httpimg_/fi/tsrchon.gif}
+## "recherche" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=fr] {_httpimg_/fr/tsrchgr.gif}
+_httpicontsrchof_ [l=fr] {_httpimg_/fr/tsrchof.gif}
+_httpicontsrchon_ [l=fr] {_httpimg_/fr/tsrchon.gif}
+## "buscar" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=gl] {_httpimg_/gl/tsrchgr.gif}
+_httpicontsrchof_ [l=gl] {_httpimg_/gl/tsrchof.gif}
+_httpicontsrchon_ [l=gl] {_httpimg_/gl/tsrchon.gif}
+## "×©×€×" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=he] {_httpimg_/he/tsrchgr.gif}
+_httpicontsrchof_ [l=he] {_httpimg_/he/tsrchof.gif}
+_httpicontsrchon_ [l=he] {_httpimg_/he/tsrchon.gif}
+## "traÅŸi" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=hr] {_httpimg_/hr/tsrchgr.gif}
+_httpicontsrchof_ [l=hr] {_httpimg_/hr/tsrchof.gif}
+_httpicontsrchon_ [l=hr] {_httpimg_/hr/tsrchon.gif}
+## "ÕžÖÕžÕ¶ÕžÖÕŽ" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=hy] {_httpimg_/hy/tsrchgr.gif}
+_httpicontsrchof_ [l=hy] {_httpimg_/hy/tsrchof.gif}
+_httpicontsrchon_ [l=hy] {_httpimg_/hy/tsrchon.gif}
+## "mencari" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=id] {_httpimg_/id/tsrchgr.gif}
+_httpicontsrchof_ [l=id] {_httpimg_/id/tsrchof.gif}
+_httpicontsrchon_ [l=id] {_httpimg_/id/tsrchon.gif}
+## "cerca" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=it] {_httpimg_/it/tsrchgr.gif}
+_httpicontsrchof_ [l=it] {_httpimg_/it/tsrchof.gif}
+_httpicontsrchon_ [l=it] {_httpimg_/it/tsrchon.gif}
+## "æ€çŽ¢" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=ja] {_httpimg_/ja/tsrchgr.gif}
+_httpicontsrchof_ [l=ja] {_httpimg_/ja/tsrchof.gif}
+_httpicontsrchon_ [l=ja] {_httpimg_/ja/tsrchon.gif}
+## "á«áááá" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=ka] {_httpimg_/ka/tsrchgr.gif}
+_httpicontsrchof_ [l=ka] {_httpimg_/ka/tsrchof.gif}
+_httpicontsrchon_ [l=ka] {_httpimg_/ka/tsrchon.gif}
+## "ÑÐ·ÐŽÐµÑ" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=kk] {_httpimg_/kk/tsrchgr.gif}
+_httpicontsrchof_ [l=kk] {_httpimg_/kk/tsrchof.gif}
+_httpicontsrchon_ [l=kk] {_httpimg_/kk/tsrchon.gif}
+## "ÐžÐ·ÐŽÓ©Ó©" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=ky] {_httpimg_/ky/tsrchgr.gif}
+_httpicontsrchof_ [l=ky] {_httpimg_/ky/tsrchof.gif}
+_httpicontsrchon_ [l=ky] {_httpimg_/ky/tsrchon.gif}
+## "meklÄt" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=lv] {_httpimg_/lv/tsrchgr.gif}
+_httpicontsrchof_ [l=lv] {_httpimg_/lv/tsrchof.gif}
+_httpicontsrchon_ [l=lv] {_httpimg_/lv/tsrchon.gif}
+## "rapu" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=mi] {_httpimg_/mi/tsrchgr.gif}
+_httpicontsrchof_ [l=mi] {_httpimg_/mi/tsrchof.gif}
+_httpicontsrchon_ [l=mi] {_httpimg_/mi/tsrchon.gif}
+## "Ñ
+Ð°Ð¹Ñ
+" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=mn] {_httpimg_/mn/tsrchgr.gif}
+_httpicontsrchof_ [l=mn] {_httpimg_/mn/tsrchof.gif}
+_httpicontsrchon_ [l=mn] {_httpimg_/mn/tsrchon.gif}
+## "zoeken" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=nl] {_httpimg_/nl/tsrchgr.gif}
+_httpicontsrchof_ [l=nl] {_httpimg_/nl/tsrchof.gif}
+_httpicontsrchon_ [l=nl] {_httpimg_/nl/tsrchon.gif}
+## "znajdÅº" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=pl] {_httpimg_/pl/tsrchgr.gif}
+_httpicontsrchof_ [l=pl] {_httpimg_/pl/tsrchof.gif}
+_httpicontsrchon_ [l=pl] {_httpimg_/pl/tsrchon.gif}
+## "buscar" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=pt-br] {_httpimg_/pt-br/tsrchgr.gif}
+_httpicontsrchof_ [l=pt-br] {_httpimg_/pt-br/tsrchof.gif}
+_httpicontsrchon_ [l=pt-br] {_httpimg_/pt-br/tsrchon.gif}
+## "buscar" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=pt-pt] {_httpimg_/pt-pt/tsrchgr.gif}
+_httpicontsrchof_ [l=pt-pt] {_httpimg_/pt-pt/tsrchof.gif}
+_httpicontsrchon_ [l=pt-pt] {_httpimg_/pt-pt/tsrchon.gif}
+## "Ð¿ÐŸÐžÑÐº" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=ru] {_httpimg_/ru/tsrchgr.gif}
+_httpicontsrchof_ [l=ru] {_httpimg_/ru/tsrchof.gif}
+_httpicontsrchon_ [l=ru] {_httpimg_/ru/tsrchon.gif}
+## "pretraÅŸivanje" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=sr] {_httpimg_/sr/tsrchgr.gif}
+_httpicontsrchof_ [l=sr] {_httpimg_/sr/tsrchof.gif}
+_httpicontsrchon_ [l=sr] {_httpimg_/sr/tsrchon.gif}
+## "àžªàž·àžàžà¹àž" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=th] {_httpimg_/th/tsrchgr.gif}
+_httpicontsrchof_ [l=th] {_httpimg_/th/tsrchof.gif}
+_httpicontsrchon_ [l=th] {_httpimg_/th/tsrchon.gif}
+## "arama" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=tr] {_httpimg_/tr/tsrchgr.gif}
+_httpicontsrchof_ [l=tr] {_httpimg_/tr/tsrchof.gif}
+_httpicontsrchon_ [l=tr] {_httpimg_/tr/tsrchon.gif}
+## "Ð¿ÐŸÑÑÐº" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=uk] {_httpimg_/uk/tsrchgr.gif}
+_httpicontsrchof_ [l=uk] {_httpimg_/uk/tsrchof.gif}
+_httpicontsrchon_ [l=uk] {_httpimg_/uk/tsrchon.gif}
+## "tÃ¬m kiáº¿m" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=vi] {_httpimg_/vi/tsrchgr.gif}
+_httpicontsrchof_ [l=vi] {_httpimg_/vi/tsrchof.gif}
+_httpicontsrchon_ [l=vi] {_httpimg_/vi/tsrchon.gif}
+## "æ¥è¯¢" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=zh] {_httpimg_/zh/tsrchgr.gif}
+_httpicontsrchof_ [l=zh] {_httpimg_/zh/tsrchof.gif}
+_httpicontsrchon_ [l=zh] {_httpimg_/zh/tsrchon.gif}
+## "æ¥è©¢" ## nav_bar_button ## tsrch ##
+_httpicontsrchgr_ [l=zh-tr] {_httpimg_/zh-tr/tsrchgr.gif}
+_httpicontsrchof_ [l=zh-tr] {_httpimg_/zh-tr/tsrchof.gif}
+_httpicontsrchon_ [l=zh-tr] {_httpimg_/zh-tr/tsrchon.gif}
+
+## "search" ## green_title ## h_search ##
+_httpiconhsearch_ {_httpimg_/en/h\_search.gif}
+_widthhsearch_ {200}
+_heighthsearch_ {57}
+## "ØšØ­Ø«" ## green_title ## h_search ##
+_httpiconhsearch_ [l=ar] {_httpimg_/ar/h\_search.gif}
+_widthhsearch_ [l=ar] {200}
+_heighthsearch_ [l=ar] {57}
+## "àŠàŠà§àŠà§àŠš" ## green_title ## h_search ##
+_httpiconhsearch_ [l=bn] {_httpimg_/bn/h\_search.gif}
+_widthhsearch_ [l=bn] {200}
+_heighthsearch_ [l=bn] {57}
+## "cerca" ## green_title ## h_search ##
+_httpiconhsearch_ [l=ca] {_httpimg_/ca/h\_search.gif}
+_widthhsearch_ [l=ca] {200}
+_heighthsearch_ [l=ca] {57}
+## "hledej" ## green_title ## h_search ##
+_httpiconhsearch_ [l=cs] {_httpimg_/cs/h\_search.gif}
+_widthhsearch_ [l=cs] {200}
+_heighthsearch_ [l=cs] {57}
+## "suche" ## green_title ## h_search ##
+_httpiconhsearch_ [l=de] {_httpimg_/de/h\_search.gif}
+_widthhsearch_ [l=de] {200}
+_heighthsearch_ [l=de] {57}
+## "Î±ÎœÎ±Î¶Î®ÏÎ·ÏÎ·" ## green_title ## h_search ##
+_httpiconhsearch_ [l=el] {_httpimg_/el/h\_search.gif}
+_widthhsearch_ [l=el] {200}
+_heighthsearch_ [l=el] {57}
+## "buscar" ## green_title ## h_search ##
+_httpiconhsearch_ [l=es] {_httpimg_/es/h\_search.gif}
+_widthhsearch_ [l=es] {200}
+_heighthsearch_ [l=es] {57}
+## "Ø¬Ø³ØªØ¬Ù" ## green_title ## h_search ##
+_httpiconhsearch_ [l=fa] {_httpimg_/fa/h\_search.gif}
+_widthhsearch_ [l=fa] {200}
+_heighthsearch_ [l=fa] {57}
+## "haku" ## green_title ## h_search ##
+_httpiconhsearch_ [l=fi] {_httpimg_/fi/h\_search.gif}
+_widthhsearch_ [l=fi] {200}
+_heighthsearch_ [l=fi] {57}
+## "recherche" ## green_title ## h_search ##
+_httpiconhsearch_ [l=fr] {_httpimg_/fr/h\_search.gif}
+_widthhsearch_ [l=fr] {200}
+_heighthsearch_ [l=fr] {57}
+## "buscar" ## green_title ## h_search ##
+_httpiconhsearch_ [l=gl] {_httpimg_/gl/h\_search.gif}
+_widthhsearch_ [l=gl] {200}
+_heighthsearch_ [l=gl] {57}
+## "×©××€××" ## green_title ## h_search ##
+_httpiconhsearch_ [l=he] {_httpimg_/he/h\_search.gif}
+_widthhsearch_ [l=he] {200}
+_heighthsearch_ [l=he] {57}
+## "traÅŸi" ## green_title ## h_search ##
+_httpiconhsearch_ [l=hr] {_httpimg_/hr/h\_search.gif}
+_widthhsearch_ [l=hr] {200}
+_heighthsearch_ [l=hr] {57}
+## "ÖÕ¶Õ¿ÖÕžÖÕŽ" ## green_title ## h_search ##
+_httpiconhsearch_ [l=hy] {_httpimg_/hy/h\_search.gif}
+_widthhsearch_ [l=hy] {200}
+_heighthsearch_ [l=hy] {57}
+## "Mencari" ## green_title ## h_search ##
+_httpiconhsearch_ [l=id] {_httpimg_/id/h\_search.gif}
+_widthhsearch_ [l=id] {200}
+_heighthsearch_ [l=id] {57}
+## "cerca" ## green_title ## h_search ##
+_httpiconhsearch_ [l=it] {_httpimg_/it/h\_search.gif}
+_widthhsearch_ [l=it] {200}
+_heighthsearch_ [l=it] {57}
+## "æ€çŽ¢" ## green_title ## h_search ##
+_httpiconhsearch_ [l=ja] {_httpimg_/ja/h\_search.gif}
+_widthhsearch_ [l=ja] {200}
+_heighthsearch_ [l=ja] {57}
+## "á«áááá" ## green_title ## h_search ##
+_httpiconhsearch_ [l=ka] {_httpimg_/ka/h\_search.gif}
+_widthhsearch_ [l=ka] {258}
+_heighthsearch_ [l=ka] {74}
+## "ÑÐ·ÐŽÐµÑ" ## green_title ## h_search ##
+_httpiconhsearch_ [l=kk] {_httpimg_/kk/h\_search.gif}
+_widthhsearch_ [l=kk] {200}
+_heighthsearch_ [l=kk] {57}
+## "ÐžÐ·ÐŽÓ©Ó©" ## green_title ## h_search ##
+_httpiconhsearch_ [l=ky] {_httpimg_/ky/h\_search.gif}
+_widthhsearch_ [l=ky] {200}
+_heighthsearch_ [l=ky] {57}
+## "meklÄt" ## green_title ## h_search ##
+_httpiconhsearch_ [l=lv] {_httpimg_/lv/h\_search.gif}
+_widthhsearch_ [l=lv] {200}
+_heighthsearch_ [l=lv] {57}
+## "rapu" ## green_title ## h_search ##
+_httpiconhsearch_ [l=mi] {_httpimg_/mi/h\_search.gif}
+_widthhsearch_ [l=mi] {200}
+_heighthsearch_ [l=mi] {57}
+## "Ñ
+Ð°Ð¹Ñ
+" ## green_title ## h_search ##
+_httpiconhsearch_ [l=mn] {_httpimg_/mn/h\_search.gif}
+_widthhsearch_ [l=mn] {200}
+_heighthsearch_ [l=mn] {57}
+## "zoeken" ## green_title ## h_search ##
+_httpiconhsearch_ [l=nl] {_httpimg_/nl/h\_search.gif}
+_widthhsearch_ [l=nl] {200}
+_heighthsearch_ [l=nl] {57}
+## "wyszukiwanie" ## green_title ## h_search ##
+_httpiconhsearch_ [l=pl] {_httpimg_/pl/h\_search.gif}
+_widthhsearch_ [l=pl] {200}
+_heighthsearch_ [l=pl] {57}
+## "busca" ## green_title ## h_search ##
+_httpiconhsearch_ [l=pt-br] {_httpimg_/pt-br/h\_search.gif}
+_widthhsearch_ [l=pt-br] {200}
+_heighthsearch_ [l=pt-br] {57}
+## "pesquisa" ## green_title ## h_search ##
+_httpiconhsearch_ [l=pt-pt] {_httpimg_/pt-pt/h\_search.gif}
+_widthhsearch_ [l=pt-pt] {200}
+_heighthsearch_ [l=pt-pt] {57}
+## "Ð¿ÐŸÐžÑÐº" ## green_title ## h_search ##
+_httpiconhsearch_ [l=ru] {_httpimg_/ru/h\_search.gif}
+_widthhsearch_ [l=ru] {200}
+_heighthsearch_ [l=ru] {57}
+## "pretraÅŸivanje" ## green_title ## h_search ##
+_httpiconhsearch_ [l=sr] {_httpimg_/sr/h\_search.gif}
+_widthhsearch_ [l=sr] {200}
+_heighthsearch_ [l=sr] {57}
+## "àžà¹àžàž«àž²" ## green_title ## h_search ##
+_httpiconhsearch_ [l=th] {_httpimg_/th/h\_search.gif}
+_widthhsearch_ [l=th] {200}
+_heighthsearch_ [l=th] {57}
+## "arama" ## green_title ## h_search ##
+_httpiconhsearch_ [l=tr] {_httpimg_/tr/h\_search.gif}
+_widthhsearch_ [l=tr] {200}
+_heighthsearch_ [l=tr] {57}
+## "Ð¿ÐŸÑÑÐº" ## green_title ## h_search ##
+_httpiconhsearch_ [l=uk] {_httpimg_/uk/h\_search.gif}
+_widthhsearch_ [l=uk] {200}
+_heighthsearch_ [l=uk] {57}
+## "tÃ¬m kiáº¿m" ## green_title ## h_search ##
+_httpiconhsearch_ [l=vi] {_httpimg_/vi/h\_search.gif}
+_widthhsearch_ [l=vi] {200}
+_heighthsearch_ [l=vi] {57}
+## "æ¥è¯¢" ## green_title ## h_search ##
+_httpiconhsearch_ [l=zh] {_httpimg_/zh/h\_search.gif}
+_widthhsearch_ [l=zh] {200}
+_heighthsearch_ [l=zh] {57}
+## "æ¥è©¢" ## green_title ## h_search ##
+_httpiconhsearch_ [l=zh-tr] {_httpimg_/zh-tr/h\_search.gif}
+_widthhsearch_ [l=zh-tr] {200}
+_heighthsearch_ [l=zh-tr] {57}
+
+## "acronyms" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ {_httpimg_/en/tacrogr.gif}
+_httpicontacroof_ {_httpimg_/en/tacroof.gif}
+_httpicontacroon_ {_httpimg_/en/tacroon.gif}
+## "acronyms" ## green_title ## h_acro ##
+_httpiconhacronym_ {_httpimg_/en/h\_acro.gif}
+_widthhacronym_ {200}
+_heighthacronym_ {57}
+## "Ù
+Ø®ØªØµØ±" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=ar] {_httpimg_/ar/tacrogr.gif}
+_httpicontacroof_ [l=ar] {_httpimg_/ar/tacroof.gif}
+_httpicontacroon_ [l=ar] {_httpimg_/ar/tacroon.gif}
+## "Ø§ÙÙ
+Ø®ØªØµØ±Ø§Øª" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=ar] {_httpimg_/ar/h\_acro.gif}
+_widthhacronym_ [l=ar] {200}
+_heighthacronym_ [l=ar] {57}
+## "àŠ®à§àŠšà§àŠ¡àŠ®àŠŸàŠ² àŠ¶àŠ¬à§àŠŠ" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=bn] {_httpimg_/bn/h\_acro.gif}
+_widthhacronym_ [l=bn] {200}
+_heighthacronym_ [l=bn] {57}
+## "sigles" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=ca] {_httpimg_/ca/tacrogr.gif}
+_httpicontacroof_ [l=ca] {_httpimg_/ca/tacroof.gif}
+_httpicontacroon_ [l=ca] {_httpimg_/ca/tacroon.gif}
+## "sigles" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=ca] {_httpimg_/ca/h\_acro.gif}
+_widthhacronym_ [l=ca] {200}
+_heighthacronym_ [l=ca] {57}
+## "zkratky" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=cs] {_httpimg_/cs/tacrogr.gif}
+_httpicontacroof_ [l=cs] {_httpimg_/cs/tacroof.gif}
+_httpicontacroon_ [l=cs] {_httpimg_/cs/tacroon.gif}
+## "zkratky" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=cs] {_httpimg_/cs/h\_acro.gif}
+_widthhacronym_ [l=cs] {200}
+_heighthacronym_ [l=cs] {57}
+## "Î±ÎºÏÎ¿ÎœÏÎŒÎ¹Î¿" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=el] {_httpimg_/el/tacrogr.gif}
+_httpicontacroof_ [l=el] {_httpimg_/el/tacroof.gif}
+_httpicontacroon_ [l=el] {_httpimg_/el/tacroon.gif}
+## "Î±ÎºÏÎ¿ÎœÏÎŒÎ¹Î±" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=el] {_httpimg_/el/h\_acro.gif}
+_widthhacronym_ [l=el] {200}
+_heighthacronym_ [l=el] {57}
+## "sigla" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=es] {_httpimg_/es/tacrogr.gif}
+_httpicontacroof_ [l=es] {_httpimg_/es/tacroof.gif}
+_httpicontacroon_ [l=es] {_httpimg_/es/tacroon.gif}
+## "siglas" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=es] {_httpimg_/es/h\_acro.gif}
+_widthhacronym_ [l=es] {200}
+_heighthacronym_ [l=es] {57}
+## "Ù
+ØªØ¶Ø§Ø¯" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=fa] {_httpimg_/fa/tacrogr.gif}
+_httpicontacroof_ [l=fa] {_httpimg_/fa/tacroof.gif}
+_httpicontacroon_ [l=fa] {_httpimg_/fa/tacroon.gif}
+## "Ù
+ØªØ¶Ø§Ø¯ÙØ§" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=fa] {_httpimg_/fa/h\_acro.gif}
+_widthhacronym_ [l=fa] {200}
+_heighthacronym_ [l=fa] {57}
+## "akronyymi" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=fi] {_httpimg_/fi/tacrogr.gif}
+_httpicontacroof_ [l=fi] {_httpimg_/fi/tacroof.gif}
+_httpicontacroon_ [l=fi] {_httpimg_/fi/tacroon.gif}
+## "akronyymit" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=fi] {_httpimg_/fi/h\_acro.gif}
+_widthhacronym_ [l=fi] {200}
+_heighthacronym_ [l=fi] {57}
+## "acronyme" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=fr] {_httpimg_/fr/tacrogr.gif}
+_httpicontacroof_ [l=fr] {_httpimg_/fr/tacroof.gif}
+_httpicontacroon_ [l=fr] {_httpimg_/fr/tacroon.gif}
+## "acronymes" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=fr] {_httpimg_/fr/h\_acro.gif}
+_widthhacronym_ [l=fr] {200}
+_heighthacronym_ [l=fr] {57}
+## "sigla" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=gl] {_httpimg_/gl/tacrogr.gif}
+_httpicontacroof_ [l=gl] {_httpimg_/gl/tacroof.gif}
+_httpicontacroon_ [l=gl] {_httpimg_/gl/tacroon.gif}
+## "siglas" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=gl] {_httpimg_/gl/h\_acro.gif}
+_widthhacronym_ [l=gl] {200}
+_heighthacronym_ [l=gl] {57}
+## "××©××š ×ª××××ª" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=he] {_httpimg_/he/tacrogr.gif}
+_httpicontacroof_ [l=he] {_httpimg_/he/tacroof.gif}
+_httpicontacroon_ [l=he] {_httpimg_/he/tacroon.gif}
+## "××©××š ×ª××××ª" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=he] {_httpimg_/he/h\_acro.gif}
+_widthhacronym_ [l=he] {200}
+_heighthacronym_ [l=he] {57}
+## "akronimi" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=hr] {_httpimg_/hr/tacrogr.gif}
+_httpicontacroof_ [l=hr] {_httpimg_/hr/tacroof.gif}
+_httpicontacroon_ [l=hr] {_httpimg_/hr/tacroon.gif}
+## "akronimi" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=hr] {_httpimg_/hr/h\_acro.gif}
+_widthhacronym_ [l=hr] {200}
+_heighthacronym_ [l=hr] {57}
+## "Õ¡ÖÖÕžÕ¶Õ«ÕŽ" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=hy] {_httpimg_/hy/tacrogr.gif}
+_httpicontacroof_ [l=hy] {_httpimg_/hy/tacroof.gif}
+_httpicontacroon_ [l=hy] {_httpimg_/hy/tacroon.gif}
+## "Õ¡ÖÖÕžÕ¶Õ«ÕŽÕ¶Õ¥Ö" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=hy] {_httpimg_/hy/h\_acro.gif}
+_widthhacronym_ [l=hy] {200}
+_heighthacronym_ [l=hy] {57}
+## "singkatan" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=id] {_httpimg_/id/tacrogr.gif}
+_httpicontacroof_ [l=id] {_httpimg_/id/tacroof.gif}
+_httpicontacroon_ [l=id] {_httpimg_/id/tacroon.gif}
+## "singkatan" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=id] {_httpimg_/id/h\_acro.gif}
+_widthhacronym_ [l=id] {200}
+_heighthacronym_ [l=id] {57}
+## "acronimi" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=it] {_httpimg_/it/tacrogr.gif}
+_httpicontacroof_ [l=it] {_httpimg_/it/tacroof.gif}
+_httpicontacroon_ [l=it] {_httpimg_/it/tacroon.gif}
+## "acronimi" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=it] {_httpimg_/it/h\_acro.gif}
+_widthhacronym_ [l=it] {200}
+_heighthacronym_ [l=it] {57}
+## "é ­å­èª" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=ja] {_httpimg_/ja/tacrogr.gif}
+_httpicontacroof_ [l=ja] {_httpimg_/ja/tacroof.gif}
+_httpicontacroon_ [l=ja] {_httpimg_/ja/tacroon.gif}
+## "é ­å­èª" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=ja] {_httpimg_/ja/h\_acro.gif}
+_widthhacronym_ [l=ja] {200}
+_heighthacronym_ [l=ja] {57}
+## "ááá ááááá" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=ka] {_httpimg_/ka/tacrogr.gif}
+_httpicontacroof_ [l=ka] {_httpimg_/ka/tacroof.gif}
+_httpicontacroon_ [l=ka] {_httpimg_/ka/tacroon.gif}
+## "ááá ááááááá" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=ka] {_httpimg_/ka/h\_acro.gif}
+_widthhacronym_ [l=ka] {258}
+_heighthacronym_ [l=ka] {74}
+## "Ð°ÐºÑÐŸÐœÐžÐŒÐŽÐµÑ" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=kk] {_httpimg_/kk/tacrogr.gif}
+_httpicontacroof_ [l=kk] {_httpimg_/kk/tacroof.gif}
+_httpicontacroon_ [l=kk] {_httpimg_/kk/tacroon.gif}
+## "Ð°ÐºÑÐŸÐœÐžÐŒÐŽÐµÑ" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=kk] {_httpimg_/kk/h\_acro.gif}
+_widthhacronym_ [l=kk] {200}
+_heighthacronym_ [l=kk] {57}
+## "ÐºÑÑÐºÐ°ÑÑÑÑÐ»Ð°Ñ" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=ky] {_httpimg_/ky/tacrogr.gif}
+_httpicontacroof_ [l=ky] {_httpimg_/ky/tacroof.gif}
+_httpicontacroon_ [l=ky] {_httpimg_/ky/tacroon.gif}
+## "ÐºÑÑÐºÐ°ÑÑÑÑÐ»Ð°Ñ" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=ky] {_httpimg_/ky/h\_acro.gif}
+_widthhacronym_ [l=ky] {200}
+_heighthacronym_ [l=ky] {57}
+## "akronÄ«mi" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=lv] {_httpimg_/lv/tacrogr.gif}
+_httpicontacroof_ [l=lv] {_httpimg_/lv/tacroof.gif}
+_httpicontacroon_ [l=lv] {_httpimg_/lv/tacroon.gif}
+## "akronÄ«mi" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=lv] {_httpimg_/lv/h\_acro.gif}
+_widthhacronym_ [l=lv] {200}
+_heighthacronym_ [l=lv] {57}
+## "pÅ«tauÄkÄ«" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=mi] {_httpimg_/mi/tacrogr.gif}
+_httpicontacroof_ [l=mi] {_httpimg_/mi/tacroof.gif}
+_httpicontacroon_ [l=mi] {_httpimg_/mi/tacroon.gif}
+## "pÅ«tauÄkÄ«" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=mi] {_httpimg_/mi/h\_acro.gif}
+_widthhacronym_ [l=mi] {200}
+_heighthacronym_ [l=mi] {57}
+## "Ò¯Ð³ÐžÐ¹Ðœ ÑÐŸÐ²ÑÐ»ÐŸÐ»" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=mn] {_httpimg_/mn/tacrogr.gif}
+_httpicontacroof_ [l=mn] {_httpimg_/mn/tacroof.gif}
+_httpicontacroon_ [l=mn] {_httpimg_/mn/tacroon.gif}
+## "Ò¯Ð³ÐžÐ¹Ðœ ÑÐŸÐ²ÑÐ»ÐŸÐ»" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=mn] {_httpimg_/mn/h\_acro.gif}
+_widthhacronym_ [l=mn] {200}
+_heighthacronym_ [l=mn] {57}
+## "afkortingen" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=nl] {_httpimg_/nl/tacrogr.gif}
+_httpicontacroof_ [l=nl] {_httpimg_/nl/tacroof.gif}
+_httpicontacroon_ [l=nl] {_httpimg_/nl/tacroon.gif}
+## "afkortingen" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=nl] {_httpimg_/nl/h\_acro.gif}
+_widthhacronym_ [l=nl] {200}
+_heighthacronym_ [l=nl] {57}
+## "skrÃ³ty" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=pl] {_httpimg_/pl/tacrogr.gif}
+_httpicontacroof_ [l=pl] {_httpimg_/pl/tacroof.gif}
+_httpicontacroon_ [l=pl] {_httpimg_/pl/tacroon.gif}
+## "skrÃ³ty" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=pl] {_httpimg_/pl/h\_acro.gif}
+_widthhacronym_ [l=pl] {200}
+_heighthacronym_ [l=pl] {57}
+## "acrÃ³nimo" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=pt-pt] {_httpimg_/pt-pt/tacrogr.gif}
+_httpicontacroof_ [l=pt-pt] {_httpimg_/pt-pt/tacroof.gif}
+_httpicontacroon_ [l=pt-pt] {_httpimg_/pt-pt/tacroon.gif}
+## "acrÃ³nimos" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=pt-pt] {_httpimg_/pt-pt/h\_acro.gif}
+_widthhacronym_ [l=pt-pt] {200}
+_heighthacronym_ [l=pt-pt] {57}
+## "Ð°ÐºÑÐŸÐœÐžÐŒÑ" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=ru] {_httpimg_/ru/tacrogr.gif}
+_httpicontacroof_ [l=ru] {_httpimg_/ru/tacroof.gif}
+_httpicontacroon_ [l=ru] {_httpimg_/ru/tacroon.gif}
+## "Ð°ÐºÑÐŸÐœÐžÐŒÑ" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=ru] {_httpimg_/ru/h\_acro.gif}
+_widthhacronym_ [l=ru] {200}
+_heighthacronym_ [l=ru] {57}
+## "akronim" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=sr] {_httpimg_/sr/tacrogr.gif}
+_httpicontacroof_ [l=sr] {_httpimg_/sr/tacroof.gif}
+_httpicontacroon_ [l=sr] {_httpimg_/sr/tacroon.gif}
+## "akronimi" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=sr] {_httpimg_/sr/h\_acro.gif}
+_widthhacronym_ [l=sr] {200}
+_heighthacronym_ [l=sr] {57}
+## "àžàž±àž§àž¢à¹àž­" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=th] {_httpimg_/th/tacrogr.gif}
+_httpicontacroof_ [l=th] {_httpimg_/th/tacroof.gif}
+_httpicontacroon_ [l=th] {_httpimg_/th/tacroon.gif}
+## "àžàž³àž¢à¹àž­àžàž­àžàžàž¢àž±àžàžàžàž°àžàž±àž§à¹àž£àžàžàž­àžàž«àž¥àž²àž¢àžàž³àž¡àž²àž£àž§àž¡àžàž±àž" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=th] {_httpimg_/th/h\_acro.gif}
+_widthhacronym_ [l=th] {200}
+_heighthacronym_ [l=th] {57}
+## "kÄ±saltmalar" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=tr] {_httpimg_/tr/tacrogr.gif}
+_httpicontacroof_ [l=tr] {_httpimg_/tr/tacroof.gif}
+_httpicontacroon_ [l=tr] {_httpimg_/tr/tacroon.gif}
+## "kÄ±saltmalar" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=tr] {_httpimg_/tr/h\_acro.gif}
+_widthhacronym_ [l=tr] {200}
+_heighthacronym_ [l=tr] {57}
+## "Ð°ÐºÑÐŸÐœÑÐŒ" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=uk] {_httpimg_/uk/tacrogr.gif}
+_httpicontacroof_ [l=uk] {_httpimg_/uk/tacroof.gif}
+_httpicontacroon_ [l=uk] {_httpimg_/uk/tacroon.gif}
+## "Ð°ÐºÑÐŸÐœÑÐŒÐž" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=uk] {_httpimg_/uk/h\_acro.gif}
+_widthhacronym_ [l=uk] {200}
+_heighthacronym_ [l=uk] {57}
+## "chá»¯ viáº¿t táº¯t" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=vi] {_httpimg_/vi/tacrogr.gif}
+_httpicontacroof_ [l=vi] {_httpimg_/vi/tacroof.gif}
+_httpicontacroon_ [l=vi] {_httpimg_/vi/tacroon.gif}
+## "chá»¯ viáº¿t táº¯t" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=vi] {_httpimg_/vi/h\_acro.gif}
+_widthhacronym_ [l=vi] {200}
+_heighthacronym_ [l=vi] {57}
+## "è¯å€Ž" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=zh] {_httpimg_/zh/tacrogr.gif}
+_httpicontacroof_ [l=zh] {_httpimg_/zh/tacroof.gif}
+_httpicontacroon_ [l=zh] {_httpimg_/zh/tacroon.gif}
+## "è¯å€Ž" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=zh] {_httpimg_/zh/h\_acro.gif}
+_widthhacronym_ [l=zh] {200}
+_heighthacronym_ [l=zh] {57}
+## "çž®å¯«è©" ## nav_bar_button ## tacro ##
+_httpicontacrogr_ [l=zh-tr] {_httpimg_/zh-tr/tacrogr.gif}
+_httpicontacroof_ [l=zh-tr] {_httpimg_/zh-tr/tacroof.gif}
+_httpicontacroon_ [l=zh-tr] {_httpimg_/zh-tr/tacroon.gif}
+## "çž®å¯«" ## green_title ## h_acro ##
+_httpiconhacronym_ [l=zh-tr] {_httpimg_/zh-tr/h\_acro.gif}
+_widthhacronym_ [l=zh-tr] {200}
+_heighthacronym_ [l=zh-tr] {57}
+
+## "artists" ## green_title ## h_artist ##
+_httpiconhartist_ {_httpimg_/en/h\_artist.gif}
+_widthhartist_ {200}
+_heighthartist_ {57}
+## "Ø§ÙÙÙØ§ÙÙÙ" ## green_title ## h_artist ##
+_httpiconhartist_ [l=ar] {_httpimg_/ar/h\_artist.gif}
+_widthhartist_ [l=ar] {200}
+_heighthartist_ [l=ar] {57}
+## "àŠ¶àŠ¿àŠ²à§àŠªà§" ## green_title ## h_artist ##
+_httpiconhartist_ [l=bn] {_httpimg_/bn/h\_artist.gif}
+_widthhartist_ [l=bn] {200}
+_heighthartist_ [l=bn] {57}
+## "artistes" ## green_title ## h_artist ##
+_httpiconhartist_ [l=ca] {_httpimg_/ca/h\_artist.gif}
+_widthhartist_ [l=ca] {200}
+_heighthartist_ [l=ca] {57}
+## "umÄlci" ## green_title ## h_artist ##
+_httpiconhartist_ [l=cs] {_httpimg_/cs/h\_artist.gif}
+_widthhartist_ [l=cs] {200}
+_heighthartist_ [l=cs] {57}
+## "ÎºÎ±Î»Î»Î¹ÏÎ­ÏÎœÎµÏ" ## green_title ## h_artist ##
+_httpiconhartist_ [l=el] {_httpimg_/el/h\_artist.gif}
+_widthhartist_ [l=el] {200}
+_heighthartist_ [l=el] {57}
+## "artistas" ## green_title ## h_artist ##
+_httpiconhartist_ [l=es] {_httpimg_/es/h\_artist.gif}
+_widthhartist_ [l=es] {200}
+_heighthartist_ [l=es] {57}
+## "ÙÙØ±Ù
+ÙØ¯Ø§Ù" ## green_title ## h_artist ##
+_httpiconhartist_ [l=fa] {_httpimg_/fa/h\_artist.gif}
+_widthhartist_ [l=fa] {200}
+_heighthartist_ [l=fa] {57}
+## "taiteilijat" ## green_title ## h_artist ##
+_httpiconhartist_ [l=fi] {_httpimg_/fi/h\_artist.gif}
+_widthhartist_ [l=fi] {200}
+_heighthartist_ [l=fi] {57}
+## "artistes" ## green_title ## h_artist ##
+_httpiconhartist_ [l=fr] {_httpimg_/fr/h\_artist.gif}
+_widthhartist_ [l=fr] {200}
+_heighthartist_ [l=fr] {57}
+## "artistas" ## green_title ## h_artist ##
+_httpiconhartist_ [l=gl] {_httpimg_/gl/h\_artist.gif}
+_widthhartist_ [l=gl] {200}
+_heighthartist_ [l=gl] {57}
+## "umjetnici" ## green_title ## h_artist ##
+_httpiconhartist_ [l=hr] {_httpimg_/hr/h\_artist.gif}
+_widthhartist_ [l=hr] {200}
+_heighthartist_ [l=hr] {57}
+## "Õ¡ÖÕ¿Õ«ÕœÕ¿Õ¶Õ¥Ö" ## green_title ## h_artist ##
+_httpiconhartist_ [l=hy] {_httpimg_/hy/h\_artist.gif}
+_widthhartist_ [l=hy] {200}
+_heighthartist_ [l=hy] {57}
+## "penggambar" ## green_title ## h_artist ##
+_httpiconhartist_ [l=id] {_httpimg_/id/h\_artist.gif}
+_widthhartist_ [l=id] {200}
+_heighthartist_ [l=id] {57}
+## "artisti" ## green_title ## h_artist ##
+_httpiconhartist_ [l=it] {_httpimg_/it/h\_artist.gif}
+_widthhartist_ [l=it] {200}
+_heighthartist_ [l=it] {57}
+## "ã¢ãŒãã¹ã" ## green_title ## h_artist ##
+_httpiconhartist_ [l=ja] {_httpimg_/ja/h\_artist.gif}
+_widthhartist_ [l=ja] {200}
+_heighthartist_ [l=ja] {57}
+## "á®ááááááá" ## green_title ## h_artist ##
+_httpiconhartist_ [l=ka] {_httpimg_/ka/h\_artist.gif}
+_widthhartist_ [l=ka] {258}
+_heighthartist_ [l=ka] {74}
+## "ÑÒ¯ÑÓ©ÑÑÒ¯Ð»Ó©Ñ" ## green_title ## h_artist ##
+_httpiconhartist_ [l=ky] {_httpimg_/ky/h\_artist.gif}
+_widthhartist_ [l=ky] {200}
+_heighthartist_ [l=ky] {57}
+## "mÄkslinieki" ## green_title ## h_artist ##
+_httpiconhartist_ [l=lv] {_httpimg_/lv/h\_artist.gif}
+_widthhartist_ [l=lv] {200}
+_heighthartist_ [l=lv] {57}
+## "kaitito" ## green_title ## h_artist ##
+_httpiconhartist_ [l=mi] {_httpimg_/mi/h\_artist.gif}
+_widthhartist_ [l=mi] {200}
+_heighthartist_ [l=mi] {57}
+## "Ð·ÑÑÐ°Ð°ÑÐžÐŽ" ## green_title ## h_artist ##
+_httpiconhartist_ [l=mn] {_httpimg_/mn/h\_artist.gif}
+_widthhartist_ [l=mn] {200}
+_heighthartist_ [l=mn] {57}
+## "artyÅci" ## green_title ## h_artist ##
+_httpiconhartist_ [l=pl] {_httpimg_/pl/h\_artist.gif}
+_widthhartist_ [l=pl] {200}
+_heighthartist_ [l=pl] {57}
+## "artistas" ## green_title ## h_artist ##
+_httpiconhartist_ [l=pt-pt] {_httpimg_/pt-pt/h\_artist.gif}
+_widthhartist_ [l=pt-pt] {200}
+_heighthartist_ [l=pt-pt] {57}
+## "Ð¡ÐŸÐ·ÐŽÐ°ÑÐµÐ»Ðž/ÐžÑÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»Ðž" ## green_title ## h_artist ##
+_httpiconhartist_ [l=ru] {_httpimg_/ru/h\_artist.gif}
+_widthhartist_ [l=ru] {200}
+_heighthartist_ [l=ru] {57}
+## "imena umetnika" ## green_title ## h_artist ##
+_httpiconhartist_ [l=sr] {_httpimg_/sr/h\_artist.gif}
+_widthhartist_ [l=sr] {200}
+_heighthartist_ [l=sr] {57}
+## "àžàž±àžàžšàžŽàž¥àžàž°" ## green_title ## h_artist ##
+_httpiconhartist_ [l=th] {_httpimg_/th/h\_artist.gif}
+_widthhartist_ [l=th] {200}
+_heighthartist_ [l=th] {57}
+## "santÃ§Ä±lar" ## green_title ## h_artist ##
+_httpiconhartist_ [l=tr] {_httpimg_/tr/h\_artist.gif}
+_widthhartist_ [l=tr] {200}
+_heighthartist_ [l=tr] {57}
+## "Ñ
+ÑÐŽÐŸÐ¶ÐœÐžÐºÐž" ## green_title ## h_artist ##
+_httpiconhartist_ [l=uk] {_httpimg_/uk/h\_artist.gif}
+_widthhartist_ [l=uk] {200}
+_heighthartist_ [l=uk] {57}
+## "nghá» sÄ©" ## green_title ## h_artist ##
+_httpiconhartist_ [l=vi] {_httpimg_/vi/h\_artist.gif}
+_widthhartist_ [l=vi] {200}
+_heighthartist_ [l=vi] {57}
+## "èºæ¯å®¶" ## green_title ## h_artist ##
+_httpiconhartist_ [l=zh] {_httpimg_/zh/h\_artist.gif}
+_widthhartist_ [l=zh] {200}
+_heighthartist_ [l=zh] {57}
+## "èè¡å®¶" ## green_title ## h_artist ##
+_httpiconhartist_ [l=zh-tr] {_httpimg_/zh-tr/h\_artist.gif}
+_widthhartist_ [l=zh-tr] {200}
+_heighthartist_ [l=zh-tr] {57}
+
+## "artists" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ {_httpimg_/en/tartstgr.gif}
+_httpicontartstof_ {_httpimg_/en/tartstof.gif}
+_httpicontartston_ {_httpimg_/en/tartston.gif}
+## "Ø§ÙÙÙØ§ÙÙÙ" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=ar] {_httpimg_/ar/tartstgr.gif}
+_httpicontartstof_ [l=ar] {_httpimg_/ar/tartstof.gif}
+_httpicontartston_ [l=ar] {_httpimg_/ar/tartston.gif}
+## "àŠ¶àŠ¿àŠ²à§àŠªà§" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=bn] {_httpimg_/bn/tartstgr.gif}
+_httpicontartstof_ [l=bn] {_httpimg_/bn/tartstof.gif}
+_httpicontartston_ [l=bn] {_httpimg_/bn/tartston.gif}
+## "artistes" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=ca] {_httpimg_/ca/tartstgr.gif}
+_httpicontartstof_ [l=ca] {_httpimg_/ca/tartstof.gif}
+_httpicontartston_ [l=ca] {_httpimg_/ca/tartston.gif}
+## "umÄlci" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=cs] {_httpimg_/cs/tartstgr.gif}
+_httpicontartstof_ [l=cs] {_httpimg_/cs/tartstof.gif}
+_httpicontartston_ [l=cs] {_httpimg_/cs/tartston.gif}
+## "ÎºÎ±Î»Î»Î¹ÏÎ­ÏÎœÎµÏ" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=el] {_httpimg_/el/tartstgr.gif}
+_httpicontartstof_ [l=el] {_httpimg_/el/tartstof.gif}
+_httpicontartston_ [l=el] {_httpimg_/el/tartston.gif}
+## "artistas" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=es] {_httpimg_/es/tartstgr.gif}
+_httpicontartstof_ [l=es] {_httpimg_/es/tartstof.gif}
+_httpicontartston_ [l=es] {_httpimg_/es/tartston.gif}
+## "ÙÙØ±Ù
+ÙØ¯Ø§Ù" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=fa] {_httpimg_/fa/tartstgr.gif}
+_httpicontartstof_ [l=fa] {_httpimg_/fa/tartstof.gif}
+_httpicontartston_ [l=fa] {_httpimg_/fa/tartston.gif}
+## "taiteilijat" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=fi] {_httpimg_/fi/tartstgr.gif}
+_httpicontartstof_ [l=fi] {_httpimg_/fi/tartstof.gif}
+_httpicontartston_ [l=fi] {_httpimg_/fi/tartston.gif}
+## "artistes" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=fr] {_httpimg_/fr/tartstgr.gif}
+_httpicontartstof_ [l=fr] {_httpimg_/fr/tartstof.gif}
+_httpicontartston_ [l=fr] {_httpimg_/fr/tartston.gif}
+## "artistas" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=gl] {_httpimg_/gl/tartstgr.gif}
+_httpicontartstof_ [l=gl] {_httpimg_/gl/tartstof.gif}
+_httpicontartston_ [l=gl] {_httpimg_/gl/tartston.gif}
+## "umjetnici" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=hr] {_httpimg_/hr/tartstgr.gif}
+_httpicontartstof_ [l=hr] {_httpimg_/hr/tartstof.gif}
+_httpicontartston_ [l=hr] {_httpimg_/hr/tartston.gif}
+## "Õ¡ÖÕ¿Õ«ÕœÕ¿Õ¶Õ¥Ö" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=hy] {_httpimg_/hy/tartstgr.gif}
+_httpicontartstof_ [l=hy] {_httpimg_/hy/tartstof.gif}
+_httpicontartston_ [l=hy] {_httpimg_/hy/tartston.gif}
+## "penggambar" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=id] {_httpimg_/id/tartstgr.gif}
+_httpicontartstof_ [l=id] {_httpimg_/id/tartstof.gif}
+_httpicontartston_ [l=id] {_httpimg_/id/tartston.gif}
+## "artisti" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=it] {_httpimg_/it/tartstgr.gif}
+_httpicontartstof_ [l=it] {_httpimg_/it/tartstof.gif}
+_httpicontartston_ [l=it] {_httpimg_/it/tartston.gif}
+## "ã¢ãŒãã¹ã" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=ja] {_httpimg_/ja/tartstgr.gif}
+_httpicontartstof_ [l=ja] {_httpimg_/ja/tartstof.gif}
+_httpicontartston_ [l=ja] {_httpimg_/ja/tartston.gif}
+## "á®ááááááá" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=ka] {_httpimg_/ka/tartstgr.gif}
+_httpicontartstof_ [l=ka] {_httpimg_/ka/tartstof.gif}
+_httpicontartston_ [l=ka] {_httpimg_/ka/tartston.gif}
+## "ÑÒ¯ÑÓ©ÑÑÒ¯Ð»Ó©Ñ" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=ky] {_httpimg_/ky/tartstgr.gif}
+_httpicontartstof_ [l=ky] {_httpimg_/ky/tartstof.gif}
+_httpicontartston_ [l=ky] {_httpimg_/ky/tartston.gif}
+## "mÄkslinieki" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=lv] {_httpimg_/lv/tartstgr.gif}
+_httpicontartstof_ [l=lv] {_httpimg_/lv/tartstof.gif}
+_httpicontartston_ [l=lv] {_httpimg_/lv/tartston.gif}
+## "kaitito" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=mi] {_httpimg_/mi/tartstgr.gif}
+_httpicontartstof_ [l=mi] {_httpimg_/mi/tartstof.gif}
+_httpicontartston_ [l=mi] {_httpimg_/mi/tartston.gif}
+## "Ð·ÑÑÐ°Ð°ÑÐžÐŽ" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=mn] {_httpimg_/mn/tartstgr.gif}
+_httpicontartstof_ [l=mn] {_httpimg_/mn/tartstof.gif}
+_httpicontartston_ [l=mn] {_httpimg_/mn/tartston.gif}
+## "artyÅci" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=pl] {_httpimg_/pl/tartstgr.gif}
+_httpicontartstof_ [l=pl] {_httpimg_/pl/tartstof.gif}
+_httpicontartston_ [l=pl] {_httpimg_/pl/tartston.gif}
+## "artistas" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=pt-pt] {_httpimg_/pt-pt/tartstgr.gif}
+_httpicontartstof_ [l=pt-pt] {_httpimg_/pt-pt/tartstof.gif}
+_httpicontartston_ [l=pt-pt] {_httpimg_/pt-pt/tartston.gif}
+## "ÑÐŸÐ·ÐŽÐ°ÑÐµÐ»Ñ/ÐžÑÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»Ñ" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=ru] {_httpimg_/ru/tartstgr.gif}
+_httpicontartstof_ [l=ru] {_httpimg_/ru/tartstof.gif}
+_httpicontartston_ [l=ru] {_httpimg_/ru/tartston.gif}
+## "imena umetnika" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=sr] {_httpimg_/sr/tartstgr.gif}
+_httpicontartstof_ [l=sr] {_httpimg_/sr/tartstof.gif}
+_httpicontartston_ [l=sr] {_httpimg_/sr/tartston.gif}
+## "àžšàžŽàž¥àžàžŽàž" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=th] {_httpimg_/th/tartstgr.gif}
+_httpicontartstof_ [l=th] {_httpimg_/th/tartstof.gif}
+_httpicontartston_ [l=th] {_httpimg_/th/tartston.gif}
+## "sanatÃ§Ä±lar" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=tr] {_httpimg_/tr/tartstgr.gif}
+_httpicontartstof_ [l=tr] {_httpimg_/tr/tartstof.gif}
+_httpicontartston_ [l=tr] {_httpimg_/tr/tartston.gif}
+## "Ñ
+ÑÐŽÐŸÐ¶ÐœÐžÐºÐž" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=uk] {_httpimg_/uk/tartstgr.gif}
+_httpicontartstof_ [l=uk] {_httpimg_/uk/tartstof.gif}
+_httpicontartston_ [l=uk] {_httpimg_/uk/tartston.gif}
+## "nghá» sÄ©" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=vi] {_httpimg_/vi/tartstgr.gif}
+_httpicontartstof_ [l=vi] {_httpimg_/vi/tartstof.gif}
+_httpicontartston_ [l=vi] {_httpimg_/vi/tartston.gif}
+## "èºæ¯å®¶" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=zh] {_httpimg_/zh/tartstgr.gif}
+_httpicontartstof_ [l=zh] {_httpimg_/zh/tartstof.gif}
+_httpicontartston_ [l=zh] {_httpimg_/zh/tartston.gif}
+## "èè¡å®¶" ## nav_bar_button ## tartst ##
+_httpicontartstgr_ [l=zh-tr] {_httpimg_/zh-tr/tartstgr.gif}
+_httpicontartstof_ [l=zh-tr] {_httpimg_/zh-tr/tartstof.gif}
+_httpicontartston_ [l=zh-tr] {_httpimg_/zh-tr/tartston.gif}
+
+## "authors a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ {_httpimg_/en/tauthgr.gif}
+_httpicontcreatof_ {_httpimg_/en/tauthof.gif}
+_httpicontcreaton_ {_httpimg_/en/tauthon.gif}
+## "authors a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ {_httpimg_/en/h\_auth.gif}
+_widthhcreat_ {200}
+_heighthcreat_ {57}
+## "Ø§ÙÙ
+Ø€ÙÙÙÙ (Ø£ÙÙØšØ§ØŠÙØ§Ù)" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=ar] {_httpimg_/ar/tauthgr.gif}
+_httpicontcreatof_ [l=ar] {_httpimg_/ar/tauthof.gif}
+_httpicontcreaton_ [l=ar] {_httpimg_/ar/tauthon.gif}
+## "Ø§ÙÙ
+Ø€ÙÙÙÙ (Ø£ÙÙØšØ§ØŠÙØ§Ù)" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=ar] {_httpimg_/ar/h\_auth.gif}
+_widthhcreat_ [l=ar] {200}
+_heighthcreat_ [l=ar] {57}
+## "àŠ²à§àŠàŠ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=bn] {_httpimg_/bn/tauthgr.gif}
+_httpicontcreatof_ [l=bn] {_httpimg_/bn/tauthof.gif}
+_httpicontcreaton_ [l=bn] {_httpimg_/bn/tauthon.gif}
+## "àŠ²à§àŠàŠ àŠ€àŠŸàŠ²àŠ¿àŠàŠŸ" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=bn] {_httpimg_/bn/h\_auth.gif}
+_widthhcreat_ [l=bn] {200}
+_heighthcreat_ [l=bn] {57}
+## "autors a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=ca] {_httpimg_/ca/tauthgr.gif}
+_httpicontcreatof_ [l=ca] {_httpimg_/ca/tauthof.gif}
+_httpicontcreaton_ [l=ca] {_httpimg_/ca/tauthon.gif}
+## "autors a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=ca] {_httpimg_/ca/h\_auth.gif}
+_widthhcreat_ [l=ca] {200}
+_heighthcreat_ [l=ca] {57}
+## "autoÅi a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=cs] {_httpimg_/cs/tauthgr.gif}
+_httpicontcreatof_ [l=cs] {_httpimg_/cs/tauthof.gif}
+_httpicontcreaton_ [l=cs] {_httpimg_/cs/tauthon.gif}
+## "autoÅi a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=cs] {_httpimg_/cs/h\_auth.gif}
+_widthhcreat_ [l=cs] {200}
+_heighthcreat_ [l=cs] {57}
+## "autoren a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=de] {_httpimg_/de/tauthgr.gif}
+_httpicontcreatof_ [l=de] {_httpimg_/de/tauthof.gif}
+_httpicontcreaton_ [l=de] {_httpimg_/de/tauthon.gif}
+## "autoren a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=de] {_httpimg_/de/h\_auth.gif}
+_widthhcreat_ [l=de] {200}
+# -- Missing translation: _heighthcreat_
+## "ÏÏ
+Î³Î³ÏÎ±ÏÎµÎ¯Ï (Î±-Ï)" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=el] {_httpimg_/el/tauthgr.gif}
+_httpicontcreatof_ [l=el] {_httpimg_/el/tauthof.gif}
+_httpicontcreaton_ [l=el] {_httpimg_/el/tauthon.gif}
+## "ÏÏ
+Î³Î³ÏÎ±ÏÎµÎ¯Ï (Î±-Ï)" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=el] {_httpimg_/el/h\_auth.gif}
+_widthhcreat_ [l=el] {200}
+_heighthcreat_ [l=el] {57}
+## "creadores a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=es] {_httpimg_/es/tauthgr.gif}
+_httpicontcreatof_ [l=es] {_httpimg_/es/tauthof.gif}
+_httpicontcreaton_ [l=es] {_httpimg_/es/tauthon.gif}
+## "creadores a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=es] {_httpimg_/es/h\_auth.gif}
+_widthhcreat_ [l=es] {200}
+_heighthcreat_ [l=es] {57}
+## "ÙÙÙØ³ÙØ¯Ú¯Ø§Ù Ø§-Ù" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=fa] {_httpimg_/fa/tauthgr.gif}
+_httpicontcreatof_ [l=fa] {_httpimg_/fa/tauthof.gif}
+_httpicontcreaton_ [l=fa] {_httpimg_/fa/tauthon.gif}
+## "ÙÙÙØ³ÙÚ¯Ø§Ù Ø§-Ù" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=fa] {_httpimg_/fa/h\_auth.gif}
+_widthhcreat_ [l=fa] {200}
+_heighthcreat_ [l=fa] {57}
+## "tekijÃ€t a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=fi] {_httpimg_/fi/tauthgr.gif}
+_httpicontcreatof_ [l=fi] {_httpimg_/fi/tauthof.gif}
+_httpicontcreaton_ [l=fi] {_httpimg_/fi/tauthon.gif}
+## "tekijÃ€t a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=fi] {_httpimg_/fi/h\_auth.gif}
+_widthhcreat_ [l=fi] {200}
+_heighthcreat_ [l=fi] {57}
+## "auteurs a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=fr] {_httpimg_/fr/tauthgr.gif}
+_httpicontcreatof_ [l=fr] {_httpimg_/fr/tauthof.gif}
+_httpicontcreaton_ [l=fr] {_httpimg_/fr/tauthon.gif}
+## "auteurs a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=fr] {_httpimg_/fr/h\_auth.gif}
+_widthhcreat_ [l=fr] {200}
+_heighthcreat_ [l=fr] {57}
+## "autores a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=gl] {_httpimg_/gl/tauthgr.gif}
+_httpicontcreatof_ [l=gl] {_httpimg_/gl/tauthof.gif}
+_httpicontcreaton_ [l=gl] {_httpimg_/gl/tauthon.gif}
+## "autores a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=gl] {_httpimg_/gl/h\_auth.gif}
+_widthhcreat_ [l=gl] {200}
+_heighthcreat_ [l=gl] {57}
+## "×××š××× ×ª-×" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=he] {_httpimg_/he/tauthgr.gif}
+_httpicontcreatof_ [l=he] {_httpimg_/he/tauthof.gif}
+_httpicontcreaton_ [l=he] {_httpimg_/he/tauthon.gif}
+## "×××š××× ×ª-×" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=he] {_httpimg_/he/h\_auth.gif}
+_widthhcreat_ [l=he] {200}
+_heighthcreat_ [l=he] {57}
+## "autori a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=hr] {_httpimg_/hr/tauthgr.gif}
+_httpicontcreatof_ [l=hr] {_httpimg_/hr/tauthof.gif}
+_httpicontcreaton_ [l=hr] {_httpimg_/hr/tauthon.gif}
+## "autori a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=hr] {_httpimg_/hr/h\_auth.gif}
+_widthhcreat_ [l=hr] {200}
+_heighthcreat_ [l=hr] {57}
+## "Õ°Õ¥Õ²Õ«Õ¶Õ¡Õ¯Õ¶Õ¥Ö Õ¡-Ö" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=hy] {_httpimg_/hy/tauthgr.gif}
+_httpicontcreatof_ [l=hy] {_httpimg_/hy/tauthof.gif}
+_httpicontcreaton_ [l=hy] {_httpimg_/hy/tauthon.gif}
+## "Õ°Õ¥Õ²Õ«Õ¶Õ¡Õ¯Õ¶Õ¥Ö Õ¡-Ö" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=hy] {_httpimg_/hy/h\_auth.gif}
+_widthhcreat_ [l=hy] {200}
+_heighthcreat_ [l=hy] {57}
+## "pengarang a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=id] {_httpimg_/id/tauthgr.gif}
+_httpicontcreatof_ [l=id] {_httpimg_/id/tauthof.gif}
+_httpicontcreaton_ [l=id] {_httpimg_/id/tauthon.gif}
+## "pengarang a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=id] {_httpimg_/id/h\_auth.gif}
+_widthhcreat_ [l=id] {200}
+_heighthcreat_ [l=id] {57}
+## "autori a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=it] {_httpimg_/it/tauthgr.gif}
+_httpicontcreatof_ [l=it] {_httpimg_/it/tauthof.gif}
+_httpicontcreaton_ [l=it] {_httpimg_/it/tauthon.gif}
+## "autori a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=it] {_httpimg_/it/h\_auth.gif}
+_widthhcreat_ [l=it] {200}
+_heighthcreat_ [l=it] {57}
+## "èè
+ïŒèŸæžé ïŒ" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=ja] {_httpimg_/ja/tauthgr.gif}
+_httpicontcreatof_ [l=ja] {_httpimg_/ja/tauthof.gif}
+_httpicontcreaton_ [l=ja] {_httpimg_/ja/tauthon.gif}
+## "äœå®¶ïŒèŸæžé ïŒ" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=ja] {_httpimg_/ja/h\_auth.gif}
+_widthhcreat_ [l=ja] {200}
+_heighthcreat_ [l=ja] {57}
+## "ááá¢áá ááá ááááááá¡ á¡á®ááááá" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=ka] {_httpimg_/ka/tauthgr.gif}
+_httpicontcreatof_ [l=ka] {_httpimg_/ka/tauthof.gif}
+_httpicontcreaton_ [l=ka] {_httpimg_/ka/tauthon.gif}
+## "ááá¢áá ááá\nááááááá¡ á¡á®ááááá" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=ka] {_httpimg_/ka/h\_auth.gif}
+_widthhcreat_ [l=ka] {258}
+_heighthcreat_ [l=ka] {74}
+## "Ð°Ð²ÑÐŸÑÐ»Ð°Ñ Ð°-Ñ" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=kk] {_httpimg_/kk/tauthgr.gif}
+_httpicontcreatof_ [l=kk] {_httpimg_/kk/tauthof.gif}
+_httpicontcreaton_ [l=kk] {_httpimg_/kk/tauthon.gif}
+## "Ð°Ð²ÑÐŸÑÐ»Ð°Ñ Ð°-Ñ" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=kk] {_httpimg_/kk/h\_auth.gif}
+_widthhcreat_ [l=kk] {200}
+_heighthcreat_ [l=kk] {57}
+## "Ð°Ð²ÑÐŸÑÐ»ÐŸÑ Ð°-Ñ" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=ky] {_httpimg_/ky/tauthgr.gif}
+_httpicontcreatof_ [l=ky] {_httpimg_/ky/tauthof.gif}
+_httpicontcreaton_ [l=ky] {_httpimg_/ky/tauthon.gif}
+## "Ð°Ð²ÑÐŸÑÐ»ÐŸÑ Ð-Ð¯" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=ky] {_httpimg_/ky/h\_auth.gif}
+_widthhcreat_ [l=ky] {200}
+_heighthcreat_ [l=ky] {57}
+## "autori a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=lv] {_httpimg_/lv/tauthgr.gif}
+_httpicontcreatof_ [l=lv] {_httpimg_/lv/tauthof.gif}
+_httpicontcreaton_ [l=lv] {_httpimg_/lv/tauthon.gif}
+## "autori a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=lv] {_httpimg_/lv/h\_auth.gif}
+_widthhcreat_ [l=lv] {200}
+_heighthcreat_ [l=lv] {57}
+## "kaitito a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=mi] {_httpimg_/mi/tauthgr.gif}
+_httpicontcreatof_ [l=mi] {_httpimg_/mi/tauthof.gif}
+_httpicontcreaton_ [l=mi] {_httpimg_/mi/tauthon.gif}
+## "kaitito a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=mi] {_httpimg_/mi/h\_auth.gif}
+_widthhcreat_ [l=mi] {200}
+_heighthcreat_ [l=mi] {57}
+## "Ð·ÐŸÑ
+ÐžÐŸÐ³ÑÐžÐŽ Ð°-Ñ" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=mn] {_httpimg_/mn/tauthgr.gif}
+_httpicontcreatof_ [l=mn] {_httpimg_/mn/tauthof.gif}
+_httpicontcreaton_ [l=mn] {_httpimg_/mn/tauthon.gif}
+## "Ð·ÐŸÑ
+ÐžÐŸÐ³ÑÐžÐŽ Ð°-Ñ" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=mn] {_httpimg_/mn/h\_auth.gif}
+_widthhcreat_ [l=mn] {200}
+_heighthcreat_ [l=mn] {57}
+## "auteurs a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=nl] {_httpimg_/nl/tauthgr.gif}
+_httpicontcreatof_ [l=nl] {_httpimg_/nl/tauthof.gif}
+_httpicontcreaton_ [l=nl] {_httpimg_/nl/tauthon.gif}
+## "auteurs a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=nl] {_httpimg_/nl/h\_auth.gif}
+_widthhcreat_ [l=nl] {200}
+_heighthcreat_ [l=nl] {57}
+## "autorzy a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=pl] {_httpimg_/pl/tauthgr.gif}
+_httpicontcreatof_ [l=pl] {_httpimg_/pl/tauthof.gif}
+_httpicontcreaton_ [l=pl] {_httpimg_/pl/tauthon.gif}
+## "autorzy a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=pl] {_httpimg_/pl/h\_auth.gif}
+_widthhcreat_ [l=pl] {200}
+_heighthcreat_ [l=pl] {57}
+## "autores a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=pt-br] {_httpimg_/pt-br/tauthgr.gif}
+_httpicontcreatof_ [l=pt-br] {_httpimg_/pt-br/tauthof.gif}
+_httpicontcreaton_ [l=pt-br] {_httpimg_/pt-br/tauthon.gif}
+## "autores a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=pt-br] {_httpimg_/pt-br/h\_auth.gif}
+_widthhcreat_ [l=pt-br] {200}
+# -- Missing translation: _heighthcreat_
+## "autores a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=pt-pt] {_httpimg_/pt-pt/tauthgr.gif}
+_httpicontcreatof_ [l=pt-pt] {_httpimg_/pt-pt/tauthof.gif}
+_httpicontcreaton_ [l=pt-pt] {_httpimg_/pt-pt/tauthon.gif}
+## "autores a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=pt-pt] {_httpimg_/pt-pt/h\_auth.gif}
+_widthhcreat_ [l=pt-pt] {200}
+_heighthcreat_ [l=pt-pt] {57}
+## "Ð°Ð²ÑÐŸÑÑ Ð°-Ñ" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=ru] {_httpimg_/ru/tauthgr.gif}
+_httpicontcreatof_ [l=ru] {_httpimg_/ru/tauthof.gif}
+_httpicontcreaton_ [l=ru] {_httpimg_/ru/tauthon.gif}
+## "Ð°Ð²ÑÐŸÑÑ Ð°-Ñ" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=ru] {_httpimg_/ru/h\_auth.gif}
+_widthhcreat_ [l=ru] {200}
+_heighthcreat_ [l=ru] {57}
+## "autori a-ÅŸ/a-Ñ" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=sr] {_httpimg_/sr/tauthgr.gif}
+_httpicontcreatof_ [l=sr] {_httpimg_/sr/tauthof.gif}
+_httpicontcreaton_ [l=sr] {_httpimg_/sr/tauthon.gif}
+## "autori a-ÅŸ/a-Ñ" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=sr] {_httpimg_/sr/h\_auth.gif}
+_widthhcreat_ [l=sr] {200}
+_heighthcreat_ [l=sr] {57}
+## "àžàž±àžàžàž£àž°àžàž±àžàžà¹ à¹àž­àžàž¶àžà¹àžàž" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=th] {_httpimg_/th/tauthgr.gif}
+_httpicontcreatof_ [l=th] {_httpimg_/th/tauthof.gif}
+_httpicontcreaton_ [l=th] {_httpimg_/th/tauthon.gif}
+## "àžàž¹à¹àžàž£àžàž±àžàžà¹ a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=th] {_httpimg_/th/h\_auth.gif}
+_widthhcreat_ [l=th] {200}
+_heighthcreat_ [l=th] {57}
+## "yazarlar a-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=tr] {_httpimg_/tr/tauthgr.gif}
+_httpicontcreatof_ [l=tr] {_httpimg_/tr/tauthof.gif}
+_httpicontcreaton_ [l=tr] {_httpimg_/tr/tauthon.gif}
+## "yazarlar a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=tr] {_httpimg_/tr/h\_auth.gif}
+_widthhcreat_ [l=tr] {200}
+_heighthcreat_ [l=tr] {57}
+## "Ð°Ð²ÑÐŸÑÐž Ð°-Ñ" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=uk] {_httpimg_/uk/tauthgr.gif}
+_httpicontcreatof_ [l=uk] {_httpimg_/uk/tauthof.gif}
+_httpicontcreaton_ [l=uk] {_httpimg_/uk/tauthon.gif}
+## "Ð°Ð²ÑÐŸÑÐž Ð°-Ñ" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=uk] {_httpimg_/uk/h\_auth.gif}
+_widthhcreat_ [l=uk] {200}
+_heighthcreat_ [l=uk] {57}
+## "tÃ¡c giáº£" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=vi] {_httpimg_/vi/tauthgr.gif}
+_httpicontcreatof_ [l=vi] {_httpimg_/vi/tauthof.gif}
+_httpicontcreaton_ [l=vi] {_httpimg_/vi/tauthon.gif}
+## "tÃ¡c giáº£" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=vi] {_httpimg_/vi/h\_auth.gif}
+_widthhcreat_ [l=vi] {200}
+_heighthcreat_ [l=vi] {57}
+## "äœè
+çŽ¢åŒa-z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=zh] {_httpimg_/zh/tauthgr.gif}
+_httpicontcreatof_ [l=zh] {_httpimg_/zh/tauthof.gif}
+_httpicontcreaton_ [l=zh] {_httpimg_/zh/tauthon.gif}
+## "äœè
+çŽ¢åŒa-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=zh] {_httpimg_/zh/h\_auth.gif}
+_widthhcreat_ [l=zh] {200}
+_heighthcreat_ [l=zh] {57}
+## "äœè
+ A-Z" ## nav_bar_button ## tauth ##
+_httpicontcreatgr_ [l=zh-tr] {_httpimg_/zh-tr/tauthgr.gif}
+_httpicontcreatof_ [l=zh-tr] {_httpimg_/zh-tr/tauthof.gif}
+_httpicontcreaton_ [l=zh-tr] {_httpimg_/zh-tr/tauthon.gif}
+## "äœè
+ a-z" ## green_title ## h_auth ##
+_httpiconhcreat_ [l=zh-tr] {_httpimg_/zh-tr/h\_auth.gif}
+_widthhcreat_ [l=zh-tr] {200}
+_heighthcreat_ [l=zh-tr] {57}
+
+## "browse" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ {_httpimg_/en/tbrwsegr.gif}
+_httpicontbrwseon_ {_httpimg_/en/tbrwseon.gif}
+_httpicontbrwseof_ {_httpimg_/en/tbrwseof.gif}
+## "browse" ## green_title ## h_brwse ##
+_httpiconhbrwse_ {_httpimg_/en/h\_brwse.gif}
+_widthhbrwse_ {200}
+_heighthbrwse_ {57}
+## "ØªØµÙØ­" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=ar] {_httpimg_/ar/tbrwsegr.gif}
+_httpicontbrwseon_ [l=ar] {_httpimg_/ar/tbrwseon.gif}
+_httpicontbrwseof_ [l=ar] {_httpimg_/ar/tbrwseof.gif}
+## "ØªØµÙØ­" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=ar] {_httpimg_/ar/h\_brwse.gif}
+_widthhbrwse_ [l=ar] {200}
+_heighthbrwse_ [l=ar] {57}
+## "àŠŠà§àŠà§àŠš" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=bn] {_httpimg_/bn/tbrwsegr.gif}
+_httpicontbrwseon_ [l=bn] {_httpimg_/bn/tbrwseon.gif}
+_httpicontbrwseof_ [l=bn] {_httpimg_/bn/tbrwseof.gif}
+## "àŠŠà§àŠà§àŠš" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=bn] {_httpimg_/bn/h\_brwse.gif}
+_widthhbrwse_ [l=bn] {200}
+_heighthbrwse_ [l=bn] {57}
+## "examina" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=ca] {_httpimg_/ca/tbrwsegr.gif}
+_httpicontbrwseon_ [l=ca] {_httpimg_/ca/tbrwseon.gif}
+_httpicontbrwseof_ [l=ca] {_httpimg_/ca/tbrwseof.gif}
+## "examina" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=ca] {_httpimg_/ca/h\_brwse.gif}
+_widthhbrwse_ [l=ca] {200}
+_heighthbrwse_ [l=ca] {57}
+## "prochÃ¡zet" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=cs] {_httpimg_/cs/tbrwsegr.gif}
+_httpicontbrwseon_ [l=cs] {_httpimg_/cs/tbrwseon.gif}
+_httpicontbrwseof_ [l=cs] {_httpimg_/cs/tbrwseof.gif}
+## "prochÃ¡zet" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=cs] {_httpimg_/cs/h\_brwse.gif}
+_widthhbrwse_ [l=cs] {200}
+_heighthbrwse_ [l=cs] {57}
+## "stÃ¶bern" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=de] {_httpimg_/de/tbrwsegr.gif}
+_httpicontbrwseon_ [l=de] {_httpimg_/de/tbrwseon.gif}
+_httpicontbrwseof_ [l=de] {_httpimg_/de/tbrwseof.gif}
+## "stÃ¶bern" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=de] {_httpimg_/de/h\_brwse.gif}
+_widthhbrwse_ [l=de] {200}
+_heighthbrwse_ [l=de] {57}
+## "ÏÎ¬ÏÏÏÎ·" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=el] {_httpimg_/el/tbrwsegr.gif}
+_httpicontbrwseon_ [l=el] {_httpimg_/el/tbrwseon.gif}
+_httpicontbrwseof_ [l=el] {_httpimg_/el/tbrwseof.gif}
+## "ÏÎ¬ÏÏÏÎ·" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=el] {_httpimg_/el/h\_brwse.gif}
+_widthhbrwse_ [l=el] {200}
+_heighthbrwse_ [l=el] {57}
+## "navegar" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=es] {_httpimg_/es/tbrwsegr.gif}
+_httpicontbrwseon_ [l=es] {_httpimg_/es/tbrwseon.gif}
+_httpicontbrwseof_ [l=es] {_httpimg_/es/tbrwseof.gif}
+## "navegar" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=es] {_httpimg_/es/h\_brwse.gif}
+_widthhbrwse_ [l=es] {200}
+_heighthbrwse_ [l=es] {57}
+## "Ù
+Ø±ÙØ±" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=fa] {_httpimg_/fa/tbrwsegr.gif}
+_httpicontbrwseon_ [l=fa] {_httpimg_/fa/tbrwseon.gif}
+_httpicontbrwseof_ [l=fa] {_httpimg_/fa/tbrwseof.gif}
+## "Ù
+Ø±ÙØ±" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=fa] {_httpimg_/fa/h\_brwse.gif}
+_widthhbrwse_ [l=fa] {200}
+_heighthbrwse_ [l=fa] {57}
+## "selaa" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=fi] {_httpimg_/fi/tbrwsegr.gif}
+_httpicontbrwseon_ [l=fi] {_httpimg_/fi/tbrwseon.gif}
+_httpicontbrwseof_ [l=fi] {_httpimg_/fi/tbrwseof.gif}
+## "selaaminen" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=fi] {_httpimg_/fi/h\_brwse.gif}
+_widthhbrwse_ [l=fi] {200}
+_heighthbrwse_ [l=fi] {57}
+## "naviguer" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=fr] {_httpimg_/fr/tbrwsegr.gif}
+_httpicontbrwseon_ [l=fr] {_httpimg_/fr/tbrwseon.gif}
+_httpicontbrwseof_ [l=fr] {_httpimg_/fr/tbrwseof.gif}
+## "naviguer" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=fr] {_httpimg_/fr/h\_brwse.gif}
+_widthhbrwse_ [l=fr] {200}
+_heighthbrwse_ [l=fr] {57}
+## "navegar" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=gl] {_httpimg_/gl/tbrwsegr.gif}
+_httpicontbrwseon_ [l=gl] {_httpimg_/gl/tbrwseon.gif}
+_httpicontbrwseof_ [l=gl] {_httpimg_/gl/tbrwseof.gif}
+## "navegar" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=gl] {_httpimg_/gl/h\_brwse.gif}
+_widthhbrwse_ [l=gl] {200}
+_heighthbrwse_ [l=gl] {57}
+## "×£××€×" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=he] {_httpimg_/he/tbrwsegr.gif}
+_httpicontbrwseon_ [l=he] {_httpimg_/he/tbrwseon.gif}
+_httpicontbrwseof_ [l=he] {_httpimg_/he/tbrwseof.gif}
+## "××Š×" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=he] {_httpimg_/he/h\_brwse.gif}
+_widthhbrwse_ [l=he] {200}
+_heighthbrwse_ [l=he] {57}
+## "pregled" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=hr] {_httpimg_/hr/tbrwsegr.gif}
+_httpicontbrwseon_ [l=hr] {_httpimg_/hr/tbrwseon.gif}
+_httpicontbrwseof_ [l=hr] {_httpimg_/hr/tbrwseof.gif}
+## "metapregled" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=hr] {_httpimg_/hr/h\_brwse.gif}
+_widthhbrwse_ [l=hr] {200}
+_heighthbrwse_ [l=hr] {57}
+## "Õ©Õ¥ÖÕ©Õ¥Õ¬" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=hy] {_httpimg_/hy/tbrwsegr.gif}
+_httpicontbrwseon_ [l=hy] {_httpimg_/hy/tbrwseon.gif}
+_httpicontbrwseof_ [l=hy] {_httpimg_/hy/tbrwseof.gif}
+## "Õ©Õ¥ÖÕ©Õ¥Õ¬" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=hy] {_httpimg_/hy/h\_brwse.gif}
+_widthhbrwse_ [l=hy] {200}
+_heighthbrwse_ [l=hy] {57}
+## "melihat" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=id] {_httpimg_/id/tbrwsegr.gif}
+_httpicontbrwseon_ [l=id] {_httpimg_/id/tbrwseon.gif}
+_httpicontbrwseof_ [l=id] {_httpimg_/id/tbrwseof.gif}
+## "melihat" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=id] {_httpimg_/id/h\_brwse.gif}
+_widthhbrwse_ [l=id] {200}
+_heighthbrwse_ [l=id] {57}
+## "elenco" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=it] {_httpimg_/it/tbrwsegr.gif}
+_httpicontbrwseon_ [l=it] {_httpimg_/it/tbrwseon.gif}
+_httpicontbrwseof_ [l=it] {_httpimg_/it/tbrwseof.gif}
+## "elenco" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=it] {_httpimg_/it/h\_brwse.gif}
+_widthhbrwse_ [l=it] {200}
+_heighthbrwse_ [l=it] {57}
+## "ãã©ãŠãº" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=ja] {_httpimg_/ja/tbrwsegr.gif}
+_httpicontbrwseon_ [l=ja] {_httpimg_/ja/tbrwseon.gif}
+_httpicontbrwseof_ [l=ja] {_httpimg_/ja/tbrwseof.gif}
+## "ãã©ãŠãº" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=ja] {_httpimg_/ja/h\_brwse.gif}
+_widthhbrwse_ [l=ja] {200}
+_heighthbrwse_ [l=ja] {57}
+## "ááááááááá ááá" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=ka] {_httpimg_/ka/tbrwsegr.gif}
+_httpicontbrwseon_ [l=ka] {_httpimg_/ka/tbrwseon.gif}
+_httpicontbrwseof_ [l=ka] {_httpimg_/ka/tbrwseof.gif}
+## "ááááááááá ááá" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=ka] {_httpimg_/ka/h\_brwse.gif}
+_widthhbrwse_ [l=ka] {258}
+_heighthbrwse_ [l=ka] {74}
+## "ÑÑÐ·ÑÐŒ" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=kk] {_httpimg_/kk/tbrwsegr.gif}
+_httpicontbrwseon_ [l=kk] {_httpimg_/kk/tbrwseon.gif}
+_httpicontbrwseof_ [l=kk] {_httpimg_/kk/tbrwseof.gif}
+## "ÑÑÐ·ÑÐŒ" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=kk] {_httpimg_/kk/h\_brwse.gif}
+_widthhbrwse_ [l=kk] {200}
+_heighthbrwse_ [l=kk] {57}
+## "ÐºÓ©ÑÑÓ©ÑÒ¯Ò¯" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=ky] {_httpimg_/ky/tbrwsegr.gif}
+_httpicontbrwseon_ [l=ky] {_httpimg_/ky/tbrwseon.gif}
+_httpicontbrwseof_ [l=ky] {_httpimg_/ky/tbrwseof.gif}
+## "ÐºÓ©ÑÑÓ©ÑÒ¯Ò¯" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=ky] {_httpimg_/ky/h\_brwse.gif}
+_widthhbrwse_ [l=ky] {200}
+_heighthbrwse_ [l=ky] {57}
+## "pÄrlÅ«kot" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=lv] {_httpimg_/lv/tbrwsegr.gif}
+_httpicontbrwseon_ [l=lv] {_httpimg_/lv/tbrwseon.gif}
+_httpicontbrwseof_ [l=lv] {_httpimg_/lv/tbrwseof.gif}
+## "pÄrlÅ«kot" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=lv] {_httpimg_/lv/h\_brwse.gif}
+_widthhbrwse_ [l=lv] {200}
+_heighthbrwse_ [l=lv] {57}
+## "tirotiro" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=mi] {_httpimg_/mi/tbrwsegr.gif}
+_httpicontbrwseon_ [l=mi] {_httpimg_/mi/tbrwseon.gif}
+_httpicontbrwseof_ [l=mi] {_httpimg_/mi/tbrwseof.gif}
+## "tirotiro" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=mi] {_httpimg_/mi/h\_brwse.gif}
+_widthhbrwse_ [l=mi] {200}
+_heighthbrwse_ [l=mi] {57}
+## "Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ò¯Ð·ÑÑ
+" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=mn] {_httpimg_/mn/tbrwsegr.gif}
+_httpicontbrwseon_ [l=mn] {_httpimg_/mn/tbrwseon.gif}
+_httpicontbrwseof_ [l=mn] {_httpimg_/mn/tbrwseof.gif}
+## "Ð³Ò¯Ð¹Ð»Ð³ÑÐœ Ò¯Ð·ÑÑ
+" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=mn] {_httpimg_/mn/h\_brwse.gif}
+_widthhbrwse_ [l=mn] {200}
+_heighthbrwse_ [l=mn] {57}
+## "browsen" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=nl] {_httpimg_/nl/tbrwsegr.gif}
+_httpicontbrwseon_ [l=nl] {_httpimg_/nl/tbrwseon.gif}
+_httpicontbrwseof_ [l=nl] {_httpimg_/nl/tbrwseof.gif}
+## "browsen" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=nl] {_httpimg_/nl/h\_brwse.gif}
+_widthhbrwse_ [l=nl] {200}
+_heighthbrwse_ [l=nl] {57}
+## "przeglÄ
+daj" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=pl] {_httpimg_/pl/tbrwsegr.gif}
+_httpicontbrwseon_ [l=pl] {_httpimg_/pl/tbrwseon.gif}
+_httpicontbrwseof_ [l=pl] {_httpimg_/pl/tbrwseof.gif}
+## "przeglÄ
+daj" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=pl] {_httpimg_/pl/h\_brwse.gif}
+_widthhbrwse_ [l=pl] {200}
+_heighthbrwse_ [l=pl] {57}
+## "listar" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=pt-br] {_httpimg_/pt-br/tbrwsegr.gif}
+_httpicontbrwseon_ [l=pt-br] {_httpimg_/pt-br/tbrwseon.gif}
+_httpicontbrwseof_ [l=pt-br] {_httpimg_/pt-br/tbrwseof.gif}
+## "listar" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=pt-br] {_httpimg_/pt-br/h\_brwse.gif}
+_widthhbrwse_ [l=pt-br] {200}
+_heighthbrwse_ [l=pt-br] {57}
+## "listar" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=pt-pt] {_httpimg_/pt-pt/tbrwsegr.gif}
+_httpicontbrwseon_ [l=pt-pt] {_httpimg_/pt-pt/tbrwseon.gif}
+_httpicontbrwseof_ [l=pt-pt] {_httpimg_/pt-pt/tbrwseof.gif}
+## "listar" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=pt-pt] {_httpimg_/pt-pt/h\_brwse.gif}
+_widthhbrwse_ [l=pt-pt] {200}
+_heighthbrwse_ [l=pt-pt] {57}
+## "ÑÐ¿ÐžÑÐŸÐº" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=ru] {_httpimg_/ru/tbrwsegr.gif}
+_httpicontbrwseon_ [l=ru] {_httpimg_/ru/tbrwseon.gif}
+_httpicontbrwseof_ [l=ru] {_httpimg_/ru/tbrwseof.gif}
+## "ÑÐ¿ÐžÑÐŸÐº" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=ru] {_httpimg_/ru/h\_brwse.gif}
+_widthhbrwse_ [l=ru] {200}
+_heighthbrwse_ [l=ru] {57}
+## "prelistavanje" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=sr] {_httpimg_/sr/tbrwsegr.gif}
+_httpicontbrwseon_ [l=sr] {_httpimg_/sr/tbrwseon.gif}
+_httpicontbrwseof_ [l=sr] {_httpimg_/sr/tbrwseof.gif}
+## "prelistavanje" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=sr] {_httpimg_/sr/h\_brwse.gif}
+_widthhbrwse_ [l=sr] {200}
+_heighthbrwse_ [l=sr] {57}
+## "àžà¹àžàž«àž²" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=th] {_httpimg_/th/tbrwsegr.gif}
+_httpicontbrwseon_ [l=th] {_httpimg_/th/tbrwseon.gif}
+_httpicontbrwseof_ [l=th] {_httpimg_/th/tbrwseof.gif}
+## "à¹àž£àžµàž¢àžàžà¹àž­àž¡àž¹àž¥à¹àžàžàž²àž°àžªà¹àž§àžàžàž¶à¹àžàž¡àž²àžàž¹àž­àž¢à¹àž²àžàž£àž§àžà¹àž£à¹àž§" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=th] {_httpimg_/th/h\_brwse.gif}
+_widthhbrwse_ [l=th] {200}
+_heighthbrwse_ [l=th] {57}
+## "gÃ¶zat" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=tr] {_httpimg_/tr/tbrwsegr.gif}
+_httpicontbrwseon_ [l=tr] {_httpimg_/tr/tbrwseon.gif}
+_httpicontbrwseof_ [l=tr] {_httpimg_/tr/tbrwseof.gif}
+## "gÃ¶zat" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=tr] {_httpimg_/tr/h\_brwse.gif}
+_widthhbrwse_ [l=tr] {200}
+_heighthbrwse_ [l=tr] {57}
+## "Ð¿ÐµÑÐµÐ³Ð»ÑÐœÑÑÐž" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=uk] {_httpimg_/uk/tbrwsegr.gif}
+_httpicontbrwseon_ [l=uk] {_httpimg_/uk/tbrwseon.gif}
+_httpicontbrwseof_ [l=uk] {_httpimg_/uk/tbrwseof.gif}
+## "Ð¿ÐµÑÐµÐ³Ð»ÑÐŽÐ°ÑÐž" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=uk] {_httpimg_/uk/h\_brwse.gif}
+_widthhbrwse_ [l=uk] {200}
+_heighthbrwse_ [l=uk] {57}
+## "duyá»t" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=vi] {_httpimg_/vi/tbrwsegr.gif}
+_httpicontbrwseon_ [l=vi] {_httpimg_/vi/tbrwseon.gif}
+_httpicontbrwseof_ [l=vi] {_httpimg_/vi/tbrwseof.gif}
+## "trÃ¬nh duyá»t" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=vi] {_httpimg_/vi/h\_brwse.gif}
+_widthhbrwse_ [l=vi] {200}
+_heighthbrwse_ [l=vi] {57}
+## "æµè§" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=zh] {_httpimg_/zh/tbrwsegr.gif}
+_httpicontbrwseon_ [l=zh] {_httpimg_/zh/tbrwseon.gif}
+_httpicontbrwseof_ [l=zh] {_httpimg_/zh/tbrwseof.gif}
+## "æµè§" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=zh] {_httpimg_/zh/h\_brwse.gif}
+_widthhbrwse_ [l=zh] {200}
+_heighthbrwse_ [l=zh] {57}
+## "çèŠœ" ## nav_bar_button ## tbrwse ##
+_httpicontbrwsegr_ [l=zh-tr] {_httpimg_/zh-tr/tbrwsegr.gif}
+_httpicontbrwseon_ [l=zh-tr] {_httpimg_/zh-tr/tbrwseon.gif}
+_httpicontbrwseof_ [l=zh-tr] {_httpimg_/zh-tr/tbrwseof.gif}
+## "çèŠœ" ## green_title ## h_brwse ##
+_httpiconhbrwse_ [l=zh-tr] {_httpimg_/zh-tr/h\_brwse.gif}
+_widthhbrwse_ [l=zh-tr] {200}
+_heighthbrwse_ [l=zh-tr] {57}
+
+## "captions" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ {_httpimg_/en/tcaptgr.gif}
+_httpicontcaptof_ {_httpimg_/en/tcaptof.gif}
+_httpicontcapton_ {_httpimg_/en/tcapton.gif}
+## "captions" ## green_title ## h_capt ##
+_httpiconhcapt_ {_httpimg_/en/h\_capt.gif}
+_widthhcapt_ {200}
+_heighthcapt_ {57}
+## "Ø§ÙÙÙØ·Ø§Øª" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=ar] {_httpimg_/ar/tcaptgr.gif}
+_httpicontcaptof_ [l=ar] {_httpimg_/ar/tcaptof.gif}
+_httpicontcapton_ [l=ar] {_httpimg_/ar/tcapton.gif}
+## "Ø§ÙÙÙØ·Ø§Øª" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=ar] {_httpimg_/ar/h\_capt.gif}
+_widthhcapt_ [l=ar] {200}
+_heighthcapt_ [l=ar] {57}
+## "àŠ¬àŠ¿àŠ·à§ àŠšàŠŸàŠ®" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=bn] {_httpimg_/bn/tcaptgr.gif}
+_httpicontcaptof_ [l=bn] {_httpimg_/bn/tcaptof.gif}
+_httpicontcapton_ [l=bn] {_httpimg_/bn/tcapton.gif}
+## "àŠ¬àŠ¿àŠ·à§ àŠšàŠŸàŠ®" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=bn] {_httpimg_/bn/h\_capt.gif}
+_widthhcapt_ [l=bn] {200}
+_heighthcapt_ [l=bn] {57}
+## "peus de foto" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=ca] {_httpimg_/ca/tcaptgr.gif}
+_httpicontcaptof_ [l=ca] {_httpimg_/ca/tcaptof.gif}
+_httpicontcapton_ [l=ca] {_httpimg_/ca/tcapton.gif}
+## "peus de foto" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=ca] {_httpimg_/ca/h\_capt.gif}
+_widthhcapt_ [l=ca] {200}
+_heighthcapt_ [l=ca] {57}
+## "popisky" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=cs] {_httpimg_/cs/tcaptgr.gif}
+_httpicontcaptof_ [l=cs] {_httpimg_/cs/tcaptof.gif}
+_httpicontcapton_ [l=cs] {_httpimg_/cs/tcapton.gif}
+## "popisky" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=cs] {_httpimg_/cs/h\_capt.gif}
+_widthhcapt_ [l=cs] {200}
+_heighthcapt_ [l=cs] {57}
+## "Î»ÎµÎ¶Î¬ÎœÏÎµÏ" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=el] {_httpimg_/el/tcaptgr.gif}
+_httpicontcaptof_ [l=el] {_httpimg_/el/tcaptof.gif}
+_httpicontcapton_ [l=el] {_httpimg_/el/tcapton.gif}
+## "ÎµÏÎ¹ÎºÎµÏÎ±Î»Î¯ÎŽÎµÏ" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=el] {_httpimg_/el/h\_capt.gif}
+_widthhcapt_ [l=el] {200}
+_heighthcapt_ [l=el] {57}
+## "TÃ­tulos de las ilustraciones" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=es] {_httpimg_/es/tcaptgr.gif}
+_httpicontcaptof_ [l=es] {_httpimg_/es/tcaptof.gif}
+_httpicontcapton_ [l=es] {_httpimg_/es/tcapton.gif}
+## "tÃ­tulos de las ilustraciones" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=es] {_httpimg_/es/h\_capt.gif}
+_widthhcapt_ [l=es] {200}
+_heighthcapt_ [l=es] {57}
+## "Ø¹ÙØ§ÙÙÙ" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=fa] {_httpimg_/fa/tcaptgr.gif}
+_httpicontcaptof_ [l=fa] {_httpimg_/fa/tcaptof.gif}
+_httpicontcapton_ [l=fa] {_httpimg_/fa/tcapton.gif}
+## "Ø¹ÙØ§ÙÙÙ" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=fa] {_httpimg_/fa/h\_capt.gif}
+_widthhcapt_ [l=fa] {200}
+_heighthcapt_ [l=fa] {57}
+## "selitteet" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=fi] {_httpimg_/fi/tcaptgr.gif}
+_httpicontcaptof_ [l=fi] {_httpimg_/fi/tcaptof.gif}
+_httpicontcapton_ [l=fi] {_httpimg_/fi/tcapton.gif}
+## "selitteet" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=fi] {_httpimg_/fi/h\_capt.gif}
+_widthhcapt_ [l=fi] {200}
+_heighthcapt_ [l=fi] {57}
+## "lÃ©gendes" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=fr] {_httpimg_/fr/tcaptgr.gif}
+_httpicontcaptof_ [l=fr] {_httpimg_/fr/tcaptof.gif}
+_httpicontcapton_ [l=fr] {_httpimg_/fr/tcapton.gif}
+## "lÃ©gendes" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=fr] {_httpimg_/fr/h\_capt.gif}
+_widthhcapt_ [l=fr] {200}
+_heighthcapt_ [l=fr] {57}
+## "ÕŽÕ¡Õ¯Õ¡Õ£ÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=hy] {_httpimg_/hy/tcaptgr.gif}
+_httpicontcaptof_ [l=hy] {_httpimg_/hy/tcaptof.gif}
+_httpicontcapton_ [l=hy] {_httpimg_/hy/tcapton.gif}
+## "ÕŽÕ¡Õ¯Õ¡Õ£ÖÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=hy] {_httpimg_/hy/h\_capt.gif}
+_widthhcapt_ [l=hy] {200}
+_heighthcapt_ [l=hy] {57}
+## "penjelasan" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=id] {_httpimg_/id/tcaptgr.gif}
+_httpicontcaptof_ [l=id] {_httpimg_/id/tcaptof.gif}
+_httpicontcapton_ [l=id] {_httpimg_/id/tcapton.gif}
+## "penjelasan" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=id] {_httpimg_/id/h\_capt.gif}
+_widthhcapt_ [l=id] {200}
+_heighthcapt_ [l=id] {57}
+## "didascalie" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=it] {_httpimg_/it/tcaptgr.gif}
+_httpicontcaptof_ [l=it] {_httpimg_/it/tcaptof.gif}
+_httpicontcapton_ [l=it] {_httpimg_/it/tcapton.gif}
+## "didascalie" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=it] {_httpimg_/it/h\_capt.gif}
+_widthhcapt_ [l=it] {200}
+_heighthcapt_ [l=it] {57}
+## "á¬áá á¬áá ááá" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=ka] {_httpimg_/ka/tcaptgr.gif}
+_httpicontcaptof_ [l=ka] {_httpimg_/ka/tcaptof.gif}
+_httpicontcapton_ [l=ka] {_httpimg_/ka/tcapton.gif}
+## "á¬áá á¬áá ááá" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=ka] {_httpimg_/ka/h\_capt.gif}
+_widthhcapt_ [l=ka] {258}
+_heighthcapt_ [l=ka] {74}
+## "Ð¶Ð°Ð·ÑÑÐ»Ð°Ñ" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=ky] {_httpimg_/ky/tcaptgr.gif}
+_httpicontcaptof_ [l=ky] {_httpimg_/ky/tcaptof.gif}
+_httpicontcapton_ [l=ky] {_httpimg_/ky/tcapton.gif}
+## "Ð¶Ð°Ð·ÑÑÐ»Ð°Ñ" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=ky] {_httpimg_/ky/h\_capt.gif}
+_widthhcapt_ [l=ky] {200}
+_heighthcapt_ [l=ky] {57}
+## "virsraksti" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=lv] {_httpimg_/lv/tcaptgr.gif}
+_httpicontcaptof_ [l=lv] {_httpimg_/lv/tcaptof.gif}
+_httpicontcapton_ [l=lv] {_httpimg_/lv/tcapton.gif}
+## "virsraksti" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=lv] {_httpimg_/lv/h\_capt.gif}
+_widthhcapt_ [l=lv] {200}
+_heighthcapt_ [l=lv] {57}
+## "rerekÅrero" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=mi] {_httpimg_/mi/tcaptgr.gif}
+_httpicontcaptof_ [l=mi] {_httpimg_/mi/tcaptof.gif}
+_httpicontcapton_ [l=mi] {_httpimg_/mi/tcapton.gif}
+## "rerekÅrero" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=mi] {_httpimg_/mi/h\_capt.gif}
+_widthhcapt_ [l=mi] {200}
+_heighthcapt_ [l=mi] {57}
+## "Ð³Ð°ÑÑÐžÐ³ÑÑÐŽ" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=mn] {_httpimg_/mn/tcaptgr.gif}
+_httpicontcaptof_ [l=mn] {_httpimg_/mn/tcaptof.gif}
+_httpicontcapton_ [l=mn] {_httpimg_/mn/tcapton.gif}
+## "Ð³Ð°ÑÑÐžÐ³" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=mn] {_httpimg_/mn/h\_capt.gif}
+_widthhcapt_ [l=mn] {200}
+_heighthcapt_ [l=mn] {57}
+## "podpisy" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=pl] {_httpimg_/pl/tcaptgr.gif}
+_httpicontcaptof_ [l=pl] {_httpimg_/pl/tcaptof.gif}
+_httpicontcapton_ [l=pl] {_httpimg_/pl/tcapton.gif}
+## "podpisy" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=pl] {_httpimg_/pl/h\_capt.gif}
+_widthhcapt_ [l=pl] {200}
+_heighthcapt_ [l=pl] {57}
+## "legendas" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=pt-pt] {_httpimg_/pt-pt/tcaptgr.gif}
+_httpicontcaptof_ [l=pt-pt] {_httpimg_/pt-pt/tcaptof.gif}
+_httpicontcapton_ [l=pt-pt] {_httpimg_/pt-pt/tcapton.gif}
+## "legendas" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=pt-pt] {_httpimg_/pt-pt/h\_capt.gif}
+_widthhcapt_ [l=pt-pt] {200}
+_heighthcapt_ [l=pt-pt] {57}
+## "Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐž(ÐœÐ°ÐŽÐ¿ÐžÑÐž)" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=ru] {_httpimg_/ru/tcaptgr.gif}
+_httpicontcaptof_ [l=ru] {_httpimg_/ru/tcaptof.gif}
+_httpicontcapton_ [l=ru] {_httpimg_/ru/tcapton.gif}
+## "Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐž (ÐœÐ°ÐŽÐ¿ÐžÑÐž)" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=ru] {_httpimg_/ru/h\_capt.gif}
+_widthhcapt_ [l=ru] {200}
+_heighthcapt_ [l=ru] {57}
+## "natpisi" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=sr] {_httpimg_/sr/tcaptgr.gif}
+_httpicontcaptof_ [l=sr] {_httpimg_/sr/tcaptof.gif}
+_httpicontcapton_ [l=sr] {_httpimg_/sr/tcapton.gif}
+## "natpisi" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=sr] {_httpimg_/sr/h\_capt.gif}
+_widthhcapt_ [l=sr] {200}
+_heighthcapt_ [l=sr] {57}
+## "baÅlÄ±klar" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=tr] {_httpimg_/tr/tcaptgr.gif}
+_httpicontcaptof_ [l=tr] {_httpimg_/tr/tcaptof.gif}
+_httpicontcapton_ [l=tr] {_httpimg_/tr/tcapton.gif}
+## "captions" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=tr] {_httpimg_/tr/h\_capt.gif}
+_widthhcapt_ [l=tr] {200}
+_heighthcapt_ [l=tr] {57}
+## "Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐž" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=uk] {_httpimg_/uk/tcaptgr.gif}
+_httpicontcaptof_ [l=uk] {_httpimg_/uk/tcaptof.gif}
+_httpicontcapton_ [l=uk] {_httpimg_/uk/tcapton.gif}
+## "Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐž" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=uk] {_httpimg_/uk/h\_capt.gif}
+_widthhcapt_ [l=uk] {200}
+_heighthcapt_ [l=uk] {57}
+## "Äáº§u Äá»" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=vi] {_httpimg_/vi/tcaptgr.gif}
+_httpicontcaptof_ [l=vi] {_httpimg_/vi/tcaptof.gif}
+_httpicontcapton_ [l=vi] {_httpimg_/vi/tcapton.gif}
+## "Äáº§u Äá»" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=vi] {_httpimg_/vi/h\_capt.gif}
+_widthhcapt_ [l=vi] {200}
+_heighthcapt_ [l=vi] {57}
+## "æ é¢" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=zh] {_httpimg_/zh/tcaptgr.gif}
+_httpicontcaptof_ [l=zh] {_httpimg_/zh/tcaptof.gif}
+_httpicontcapton_ [l=zh] {_httpimg_/zh/tcapton.gif}
+## "æ é¢" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=zh] {_httpimg_/zh/h\_capt.gif}
+_widthhcapt_ [l=zh] {200}
+_heighthcapt_ [l=zh] {57}
+## "æšé¡" ## nav_bar_button ## tcapt ##
+_httpicontcaptgr_ [l=zh-tr] {_httpimg_/zh-tr/tcaptgr.gif}
+_httpicontcaptof_ [l=zh-tr] {_httpimg_/zh-tr/tcaptof.gif}
+_httpicontcapton_ [l=zh-tr] {_httpimg_/zh-tr/tcapton.gif}
+## "æšé¡" ## green_title ## h_capt ##
+_httpiconhcapt_ [l=zh-tr] {_httpimg_/zh-tr/h\_capt.gif}
+_widthhcapt_ [l=zh-tr] {200}
+_heighthcapt_ [l=zh-tr] {57}
+
+
+## "collage" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ {_httpimg_/en/tcollgr.gif}
+_httpicontcollof_ {_httpimg_/en/tcollof.gif}
+_httpicontcollon_ {_httpimg_/en/tcollon.gif}
+## "collage" ## green_title ## h_coll ##
+_httpiconhcoll_ {_httpimg_/en/h\_coll.gif}
+_widthhcoll_ {200}
+_heighthcoll_ {57}
+## "àŠà§àŠ²àŠŸàŠ" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=bn] {_httpimg_/bn/tcollgr.gif}
+_httpicontcollof_ [l=bn] {_httpimg_/bn/tcollof.gif}
+_httpicontcollon_ [l=bn] {_httpimg_/bn/tcollon.gif}
+## "àŠà§àŠ²àŠŸàŠ" ## green_title ## h_coll ##
+_httpiconhcoll_ [l=bn] {_httpimg_/bn/h\_coll.gif}
+_widthhcoll_ [l=bn] {200}
+_heighthcoll_ [l=bn] {57}
+## "mosaic" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=ca] {_httpimg_/ca/tcollgr.gif}
+_httpicontcollof_ [l=ca] {_httpimg_/ca/tcollof.gif}
+_httpicontcollon_ [l=ca] {_httpimg_/ca/tcollon.gif}
+## "mosaic" ## green_title ## h_coll ##
+_httpiconhcoll_ [l=ca] {_httpimg_/ca/h\_coll.gif}
+_widthhcoll_ [l=ca] {200}
+_heighthcoll_ [l=ca] {57}
+## "kolÃ¡ÅŸe" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=cs] {_httpimg_/cs/tcollgr.gif}
+_httpicontcollof_ [l=cs] {_httpimg_/cs/tcollof.gif}
+_httpicontcollon_ [l=cs] {_httpimg_/cs/tcollon.gif}
+## "collage" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=es] {_httpimg_/es/tcollgr.gif}
+_httpicontcollof_ [l=es] {_httpimg_/es/tcollof.gif}
+_httpicontcollon_ [l=es] {_httpimg_/es/tcollon.gif}
+## "collage" ## green_title ## h_coll ##
+_httpiconhcoll_ [l=es] {_httpimg_/es/h\_coll.gif}
+_widthhcoll_ [l=es] {200}
+_heighthcoll_ [l=es] {57}
+## "collage" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=fr] {_httpimg_/fr/tcollgr.gif}
+_httpicontcollof_ [l=fr] {_httpimg_/fr/tcollof.gif}
+_httpicontcollon_ [l=fr] {_httpimg_/fr/tcollon.gif}
+## "collage" ## green_title ## h_coll ##
+_httpiconhcoll_ [l=fr] {_httpimg_/fr/h\_coll.gif}
+_widthhcoll_ [l=fr] {200}
+_heighthcoll_ [l=fr] {57}
+## "susunan gambar" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=id] {_httpimg_/id/tcollgr.gif}
+_httpicontcollof_ [l=id] {_httpimg_/id/tcollof.gif}
+_httpicontcollon_ [l=id] {_httpimg_/id/tcollon.gif}
+## "susunan gambar" ## green_title ## h_coll ##
+_httpiconhcoll_ [l=id] {_httpimg_/id/h\_coll.gif}
+_widthhcoll_ [l=id] {200}
+_heighthcoll_ [l=id] {57}
+## "collage" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=it] {_httpimg_/it/tcollgr.gif}
+_httpicontcollof_ [l=it] {_httpimg_/it/tcollof.gif}
+_httpicontcollon_ [l=it] {_httpimg_/it/tcollon.gif}
+## "áááááá" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=ka] {_httpimg_/ka/tcollgr.gif}
+_httpicontcollof_ [l=ka] {_httpimg_/ka/tcollof.gif}
+_httpicontcollon_ [l=ka] {_httpimg_/ka/tcollon.gif}
+## "ÐºÐŸÐ»Ð»Ð°Ð¶" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=ky] {_httpimg_/ky/tcollgr.gif}
+_httpicontcollof_ [l=ky] {_httpimg_/ky/tcollof.gif}
+_httpicontcollon_ [l=ky] {_httpimg_/ky/tcollon.gif}
+## "ÐºÐŸÐ»Ð»Ð°Ð¶" ## green_title ## h_coll ##
+_httpiconhcoll_ [l=ky] {_httpimg_/ky/h\_coll.gif}
+_widthhcoll_ [l=ky] {200}
+_heighthcoll_ [l=ky] {57}
+## "kolÄÅŸa" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=lv] {_httpimg_/lv/tcollgr.gif}
+_httpicontcollof_ [l=lv] {_httpimg_/lv/tcollof.gif}
+_httpicontcollon_ [l=lv] {_httpimg_/lv/tcollon.gif}
+## "kolÄÅŸa" ## green_title ## h_coll ##
+_httpiconhcoll_ [l=lv] {_httpimg_/lv/h\_coll.gif}
+_widthhcoll_ [l=lv] {200}
+_heighthcoll_ [l=lv] {57}
+## "kÄpunipuni whakaahua" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=mi] {_httpimg_/mi/tcollgr.gif}
+_httpicontcollof_ [l=mi] {_httpimg_/mi/tcollof.gif}
+_httpicontcollon_ [l=mi] {_httpimg_/mi/tcollon.gif}
+## "Ð·ÑÑÐ°Ð³Ð¶ÑÑÐ»Ð°Ñ
+" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=mn] {_httpimg_/mn/tcollgr.gif}
+_httpicontcollof_ [l=mn] {_httpimg_/mn/tcollof.gif}
+_httpicontcollon_ [l=mn] {_httpimg_/mn/tcollon.gif}
+## "Ð·ÑÑÐ°Ð³Ð¶ÑÑÐ»Ð°Ñ
+" ## green_title ## h_coll ##
+_httpiconhcoll_ [l=mn] {_httpimg_/mn/h\_coll.gif}
+_widthhcoll_ [l=mn] {200}
+_heighthcoll_ [l=mn] {57}
+## "kolaÅŒ" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=pl] {_httpimg_/pl/tcollgr.gif}
+_httpicontcollof_ [l=pl] {_httpimg_/pl/tcollof.gif}
+_httpicontcollon_ [l=pl] {_httpimg_/pl/tcollon.gif}
+## "kolaÅŒ" ## green_title ## h_coll ##
+_httpiconhcoll_ [l=pl] {_httpimg_/pl/h\_coll.gif}
+_widthhcoll_ [l=pl] {200}
+_heighthcoll_ [l=pl] {57}
+## "ÐºÐŸÐ»Ð»Ð°Ð¶" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=ru] {_httpimg_/ru/tcollgr.gif}
+_httpicontcollof_ [l=ru] {_httpimg_/ru/tcollof.gif}
+_httpicontcollon_ [l=ru] {_httpimg_/ru/tcollon.gif}
+## "ÐºÐŸÐŒÐ±ÐžÐœÐ°ÑÐžÑ ÑÐ°Ð·ÐœÐŸÑÐŸÐŽÐœÑÑ
+ ÑÐ»ÐµÐŒÐµÐœÑÐŸÐ²" ## green_title ## h_coll ##
+_httpiconhcoll_ [l=ru] {_httpimg_/ru/h\_coll.gif}
+_widthhcoll_ [l=ru] {200}
+_heighthcoll_ [l=ru] {57}
+## "áº£nh ghÃ©p" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=vi] {_httpimg_/vi/tcollgr.gif}
+_httpicontcollof_ [l=vi] {_httpimg_/vi/tcollof.gif}
+_httpicontcollon_ [l=vi] {_httpimg_/vi/tcollon.gif}
+## "åé" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=zh] {_httpimg_/zh/tcollgr.gif}
+_httpicontcollof_ [l=zh] {_httpimg_/zh/tcollof.gif}
+_httpicontcollon_ [l=zh] {_httpimg_/zh/tcollon.gif}
+## "åèŒ¯" ## nav_bar_button ## tcoll ##
+_httpicontcollgr_ [l=zh-tr] {_httpimg_/zh-tr/tcollgr.gif}
+_httpicontcollof_ [l=zh-tr] {_httpimg_/zh-tr/tcollof.gif}
+_httpicontcollon_ [l=zh-tr] {_httpimg_/zh-tr/tcollon.gif}
+## "åèŒ¯" ## green_title ## h_coll ##
+_httpiconhcoll_ [l=zh-tr] {_httpimg_/zh-tr/h\_coll.gif}
+_widthhcoll_ [l=zh-tr] {200}
+_heighthcoll_ [l=zh-tr] {57}
+
+## "contributors" ## nav_bar_button ## tcontr ##
+_httpicontcontrgr_ {_httpimg_/en/tcontrgr.gif}
+_httpicontcontron_ {_httpimg_/en/tcontron.gif}
+_httpicontcontrof_ {_httpimg_/en/tcontrof.gif}
+## "contributors" ## green_title ## h_contr ##
+_httpiconhcontr_ {_httpimg_/en/h\_contr.gif}
+_widthhcontr_ {200}
+_heighthcontr_ {57}
+## "àŠ
+àŠ¬àŠŠàŠŸàŠšàŠàŠŸàŠ°àŠ¿" ## nav_bar_button ## tcontr ##
+_httpicontcontrgr_ [l=bn] {_httpimg_/bn/tcontrgr.gif}
+_httpicontcontron_ [l=bn] {_httpimg_/bn/tcontron.gif}
+_httpicontcontrof_ [l=bn] {_httpimg_/bn/tcontrof.gif}
+## "àŠ
+àŠ¬àŠŠàŠŸàŠšàŠàŠŸàŠ°àŠ¿" ## green_title ## h_contr ##
+_httpiconhcontr_ [l=bn] {_httpimg_/bn/h\_contr.gif}
+_widthhcontr_ [l=bn] {200}
+_heighthcontr_ [l=bn] {57}
+## "colaboradores" ## nav_bar_button ## tcontr ##
+_httpicontcontrgr_ [l=es] {_httpimg_/es/tcontrgr.gif}
+_httpicontcontron_ [l=es] {_httpimg_/es/tcontron.gif}
+_httpicontcontrof_ [l=es] {_httpimg_/es/tcontrof.gif}
+## "colaboradores" ## green_title ## h_contr ##
+_httpiconhcontr_ [l=es] {_httpimg_/es/h\_contr.gif}
+_widthhcontr_ [l=es] {200}
+_heighthcontr_ [l=es] {57}
+## "Collaborateurs" ## nav_bar_button ## tcontr ##
+_httpicontcontrgr_ [l=fr] {_httpimg_/fr/tcontrgr.gif}
+_httpicontcontron_ [l=fr] {_httpimg_/fr/tcontron.gif}
+_httpicontcontrof_ [l=fr] {_httpimg_/fr/tcontrof.gif}
+## "Collaborateurs" ## green_title ## h_contr ##
+_httpiconhcontr_ [l=fr] {_httpimg_/fr/h\_contr.gif}
+_widthhcontr_ [l=fr] {200}
+_heighthcontr_ [l=fr] {57}
+## "penyumbang" ## nav_bar_button ## tcontr ##
+_httpicontcontrgr_ [l=id] {_httpimg_/id/tcontrgr.gif}
+_httpicontcontron_ [l=id] {_httpimg_/id/tcontron.gif}
+_httpicontcontrof_ [l=id] {_httpimg_/id/tcontrof.gif}
+## "penyumbang" ## green_title ## h_contr ##
+_httpiconhcontr_ [l=id] {_httpimg_/id/h\_contr.gif}
+_widthhcontr_ [l=id] {200}
+_heighthcontr_ [l=id] {57}
+## "ÑÐŒÐ³ÐµÐºÑÐµÑÑÐµÑ" ## nav_bar_button ## tcontr ##
+_httpicontcontrgr_ [l=ky] {_httpimg_/ky/tcontrgr.gif}
+_httpicontcontron_ [l=ky] {_httpimg_/ky/tcontron.gif}
+_httpicontcontrof_ [l=ky] {_httpimg_/ky/tcontrof.gif}
+## "ÑÐŒÐ³ÐµÐºÑÐµÑÑÐµÑ" ## green_title ## h_contr ##
+_httpiconhcontr_ [l=ky] {_httpimg_/ky/h\_contr.gif}
+_widthhcontr_ [l=ky] {200}
+_heighthcontr_ [l=ky] {57}
+## "lÄ«dzautori" ## nav_bar_button ## tcontr ##
+_httpicontcontrgr_ [l=lv] {_httpimg_/lv/tcontrgr.gif}
+_httpicontcontron_ [l=lv] {_httpimg_/lv/tcontron.gif}
+_httpicontcontrof_ [l=lv] {_httpimg_/lv/tcontrof.gif}
+## "lÄ«dzautori" ## green_title ## h_contr ##
+_httpiconhcontr_ [l=lv] {_httpimg_/lv/h\_contr.gif}
+_widthhcontr_ [l=lv] {200}
+_heighthcontr_ [l=lv] {57}
+## "Ñ
+Ð°ÐœÐŽÐžÐ²Ð»Ð°Ð³ÑÐžÐŽ" ## nav_bar_button ## tcontr ##
+_httpicontcontrgr_ [l=mn] {_httpimg_/mn/tcontrgr.gif}
+_httpicontcontron_ [l=mn] {_httpimg_/mn/tcontron.gif}
+_httpicontcontrof_ [l=mn] {_httpimg_/mn/tcontrof.gif}
+## "Ñ
+Ð°ÐœÐŽÐžÐ²Ð»Ð°Ð³Ñ" ## green_title ## h_contr ##
+_httpiconhcontr_ [l=mn] {_httpimg_/mn/h\_contr.gif}
+_widthhcontr_ [l=mn] {200}
+_heighthcontr_ [l=mn] {57}
+## "wspÃ³Åpracownicy" ## nav_bar_button ## tcontr ##
+_httpicontcontrgr_ [l=pl] {_httpimg_/pl/tcontrgr.gif}
+_httpicontcontron_ [l=pl] {_httpimg_/pl/tcontron.gif}
+_httpicontcontrof_ [l=pl] {_httpimg_/pl/tcontrof.gif}
+## "wspÃ³Åpracownicy" ## green_title ## h_contr ##
+_httpiconhcontr_ [l=pl] {_httpimg_/pl/h\_contr.gif}
+_widthhcontr_ [l=pl] {200}
+_heighthcontr_ [l=pl] {57}
+## "ÑÑÐ°ÑÑÐœÐžÐºÐž" ## nav_bar_button ## tcontr ##
+_httpicontcontrgr_ [l=ru] {_httpimg_/ru/tcontrgr.gif}
+_httpicontcontron_ [l=ru] {_httpimg_/ru/tcontron.gif}
+_httpicontcontrof_ [l=ru] {_httpimg_/ru/tcontrof.gif}
+## "ÑÑÐ°ÑÑÐœÐžÐºÐž" ## green_title ## h_contr ##
+_httpiconhcontr_ [l=ru] {_httpimg_/ru/h\_contr.gif}
+_widthhcontr_ [l=ru] {200}
+_heighthcontr_ [l=ru] {57}
+## "è²¢ç»è
+" ## nav_bar_button ## tcontr ##
+_httpicontcontrgr_ [l=zh-tr] {_httpimg_/zh-tr/tcontrgr.gif}
+_httpicontcontron_ [l=zh-tr] {_httpimg_/zh-tr/tcontron.gif}
+_httpicontcontrof_ [l=zh-tr] {_httpimg_/zh-tr/tcontrof.gif}
+## "è²¢ç»è
+" ## green_title ## h_contr ##
+_httpiconhcontr_ [l=zh-tr] {_httpimg_/zh-tr/h\_contr.gif}
+_widthhcontr_ [l=zh-tr] {200}
+_heighthcontr_ [l=zh-tr] {57}
+
+## "countries" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ {_httpimg_/en/tcountgr.gif}
+_httpicontcountof_ {_httpimg_/en/tcountof.gif}
+_httpicontcounton_ {_httpimg_/en/tcounton.gif}
+## "countries" ## green_title ## h_count ##
+_httpiconhcount_ {_httpimg_/en/h\_count.gif}
+_widthhcount_ {200}
+_heighthcount_ {57}
+## "Ø§ÙØ¯ÙÙ" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=ar] {_httpimg_/ar/tcountgr.gif}
+_httpicontcountof_ [l=ar] {_httpimg_/ar/tcountof.gif}
+_httpicontcounton_ [l=ar] {_httpimg_/ar/tcounton.gif}
+## "Ø§ÙØ¯ÙÙ" ## green_title ## h_count ##
+_httpiconhcount_ [l=ar] {_httpimg_/ar/h\_count.gif}
+_widthhcount_ [l=ar] {200}
+_heighthcount_ [l=ar] {57}
+## "àŠŠà§àŠ¶àŠà§àŠ²àŠ¿" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=bn] {_httpimg_/bn/tcountgr.gif}
+_httpicontcountof_ [l=bn] {_httpimg_/bn/tcountof.gif}
+_httpicontcounton_ [l=bn] {_httpimg_/bn/tcounton.gif}
+## "àŠŠà§àŠ¶àŠà§àŠ²àŠ¿" ## green_title ## h_count ##
+_httpiconhcount_ [l=bn] {_httpimg_/bn/h\_count.gif}
+_widthhcount_ [l=bn] {200}
+_heighthcount_ [l=bn] {57}
+## "paÃ¯sos" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=ca] {_httpimg_/ca/tcountgr.gif}
+_httpicontcountof_ [l=ca] {_httpimg_/ca/tcountof.gif}
+_httpicontcounton_ [l=ca] {_httpimg_/ca/tcounton.gif}
+## "paÃ¯sos" ## green_title ## h_count ##
+_httpiconhcount_ [l=ca] {_httpimg_/ca/h\_count.gif}
+_widthhcount_ [l=ca] {200}
+_heighthcount_ [l=ca] {57}
+## "zemÄ" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=cs] {_httpimg_/cs/tcountgr.gif}
+_httpicontcountof_ [l=cs] {_httpimg_/cs/tcountof.gif}
+_httpicontcounton_ [l=cs] {_httpimg_/cs/tcounton.gif}
+## "zemÄ" ## green_title ## h_count ##
+_httpiconhcount_ [l=cs] {_httpimg_/cs/h\_count.gif}
+_widthhcount_ [l=cs] {200}
+_heighthcount_ [l=cs] {57}
+## "paÃ­ses" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=es] {_httpimg_/es/tcountgr.gif}
+_httpicontcountof_ [l=es] {_httpimg_/es/tcountof.gif}
+_httpicontcounton_ [l=es] {_httpimg_/es/tcounton.gif}
+## "paÃ­ses" ## green_title ## h_count ##
+_httpiconhcount_ [l=es] {_httpimg_/es/h\_count.gif}
+_widthhcount_ [l=es] {200}
+_heighthcount_ [l=es] {57}
+## "ÙØŽÙØ±ÙØ§" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=fa] {_httpimg_/fa/tcountgr.gif}
+_httpicontcountof_ [l=fa] {_httpimg_/fa/tcountof.gif}
+_httpicontcounton_ [l=fa] {_httpimg_/fa/tcounton.gif}
+## "ÙØŽÙØ±ÙØ§" ## green_title ## h_count ##
+_httpiconhcount_ [l=fa] {_httpimg_/fa/h\_count.gif}
+_widthhcount_ [l=fa] {200}
+_heighthcount_ [l=fa] {57}
+## "maat" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=fi] {_httpimg_/fi/tcountgr.gif}
+_httpicontcountof_ [l=fi] {_httpimg_/fi/tcountof.gif}
+_httpicontcounton_ [l=fi] {_httpimg_/fi/tcounton.gif}
+## "maat" ## green_title ## h_count ##
+_httpiconhcount_ [l=fi] {_httpimg_/fi/h\_count.gif}
+_widthhcount_ [l=fi] {200}
+_heighthcount_ [l=fi] {57}
+## "pays" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=fr] {_httpimg_/fr/tcountgr.gif}
+_httpicontcountof_ [l=fr] {_httpimg_/fr/tcountof.gif}
+_httpicontcounton_ [l=fr] {_httpimg_/fr/tcounton.gif}
+## "pays" ## green_title ## h_count ##
+_httpiconhcount_ [l=fr] {_httpimg_/fr/h\_count.gif}
+_widthhcount_ [l=fr] {200}
+_heighthcount_ [l=fr] {57}
+## "Õ¥ÖÕ¯ÖÕ¶Õ¥Ö" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=hy] {_httpimg_/hy/tcountgr.gif}
+_httpicontcountof_ [l=hy] {_httpimg_/hy/tcountof.gif}
+_httpicontcounton_ [l=hy] {_httpimg_/hy/tcounton.gif}
+## "Õ¥ÖÕ¯ÖÕ¶Õ¥Ö" ## green_title ## h_count ##
+_httpiconhcount_ [l=hy] {_httpimg_/hy/h\_count.gif}
+_widthhcount_ [l=hy] {200}
+_heighthcount_ [l=hy] {57}
+## "negara" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=id] {_httpimg_/id/tcountgr.gif}
+_httpicontcountof_ [l=id] {_httpimg_/id/tcountof.gif}
+_httpicontcounton_ [l=id] {_httpimg_/id/tcounton.gif}
+## "negara" ## green_title ## h_count ##
+_httpiconhcount_ [l=id] {_httpimg_/id/h\_count.gif}
+_widthhcount_ [l=id] {200}
+_heighthcount_ [l=id] {57}
+## "paesi" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=it] {_httpimg_/it/tcountgr.gif}
+_httpicontcountof_ [l=it] {_httpimg_/it/tcountof.gif}
+_httpicontcounton_ [l=it] {_httpimg_/it/tcounton.gif}
+## "paesi" ## green_title ## h_count ##
+_httpiconhcount_ [l=it] {_httpimg_/it/h\_count.gif}
+_widthhcount_ [l=it] {200}
+_heighthcount_ [l=it] {57}
+## "á¥ááá§áááá" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=ka] {_httpimg_/ka/tcountgr.gif}
+_httpicontcountof_ [l=ka] {_httpimg_/ka/tcountof.gif}
+_httpicontcounton_ [l=ka] {_httpimg_/ka/tcounton.gif}
+## "á¥ááá§áááá" ## green_title ## h_count ##
+_httpiconhcount_ [l=ka] {_httpimg_/ka/h\_count.gif}
+_widthhcount_ [l=ka] {258}
+_heighthcount_ [l=ka] {74}
+## "Ó©Ð»ÐºÓ©Ð»Ó©Ñ" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=ky] {_httpimg_/ky/tcountgr.gif}
+_httpicontcountof_ [l=ky] {_httpimg_/ky/tcountof.gif}
+_httpicontcounton_ [l=ky] {_httpimg_/ky/tcounton.gif}
+## "Ó©Ð»ÐºÓ©Ð»Ó©Ñ" ## green_title ## h_count ##
+_httpiconhcount_ [l=ky] {_httpimg_/ky/h\_count.gif}
+_widthhcount_ [l=ky] {200}
+_heighthcount_ [l=ky] {57}
+## "valstis" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=lv] {_httpimg_/lv/tcountgr.gif}
+_httpicontcountof_ [l=lv] {_httpimg_/lv/tcountof.gif}
+_httpicontcounton_ [l=lv] {_httpimg_/lv/tcounton.gif}
+## "valstis" ## green_title ## h_count ##
+_httpiconhcount_ [l=lv] {_httpimg_/lv/h\_count.gif}
+_widthhcount_ [l=lv] {200}
+_heighthcount_ [l=lv] {57}
+## "whenua" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=mi] {_httpimg_/mi/tcountgr.gif}
+_httpicontcountof_ [l=mi] {_httpimg_/mi/tcountof.gif}
+_httpicontcounton_ [l=mi] {_httpimg_/mi/tcounton.gif}
+## "whenua" ## green_title ## h_count ##
+_httpiconhcount_ [l=mi] {_httpimg_/mi/h\_count.gif}
+_widthhcount_ [l=mi] {200}
+_heighthcount_ [l=mi] {57}
+## "ÑÐ»ÑÑÑÐŽ" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=mn] {_httpimg_/mn/tcountgr.gif}
+_httpicontcountof_ [l=mn] {_httpimg_/mn/tcountof.gif}
+_httpicontcounton_ [l=mn] {_httpimg_/mn/tcounton.gif}
+## "ÑÐ»ÑÑÑÐŽ" ## green_title ## h_count ##
+_httpiconhcount_ [l=mn] {_httpimg_/mn/h\_count.gif}
+_widthhcount_ [l=mn] {200}
+_heighthcount_ [l=mn] {57}
+## "kraje" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=pl] {_httpimg_/pl/tcountgr.gif}
+_httpicontcountof_ [l=pl] {_httpimg_/pl/tcountof.gif}
+_httpicontcounton_ [l=pl] {_httpimg_/pl/tcounton.gif}
+## "kraje" ## green_title ## h_count ##
+_httpiconhcount_ [l=pl] {_httpimg_/pl/h\_count.gif}
+_widthhcount_ [l=pl] {200}
+_heighthcount_ [l=pl] {57}
+## "ÑÑÑÐ°ÐœÑ" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=ru] {_httpimg_/ru/tcountgr.gif}
+_httpicontcountof_ [l=ru] {_httpimg_/ru/tcountof.gif}
+_httpicontcounton_ [l=ru] {_httpimg_/ru/tcounton.gif}
+## "ÑÑÑÐ°ÐœÑ" ## green_title ## h_count ##
+_httpiconhcount_ [l=ru] {_httpimg_/ru/h\_count.gif}
+_widthhcount_ [l=ru] {200}
+_heighthcount_ [l=ru] {57}
+## "quá»c gia" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=vi] {_httpimg_/vi/tcountgr.gif}
+_httpicontcountof_ [l=vi] {_httpimg_/vi/tcountof.gif}
+_httpicontcounton_ [l=vi] {_httpimg_/vi/tcounton.gif}
+## "quá»c gia" ## green_title ## h_count ##
+_httpiconhcount_ [l=vi] {_httpimg_/vi/h\_count.gif}
+_widthhcount_ [l=vi] {200}
+_heighthcount_ [l=vi] {57}
+## "åœå®¶" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=zh] {_httpimg_/zh/tcountgr.gif}
+_httpicontcountof_ [l=zh] {_httpimg_/zh/tcountof.gif}
+_httpicontcounton_ [l=zh] {_httpimg_/zh/tcounton.gif}
+## "åœå®¶" ## green_title ## h_count ##
+_httpiconhcount_ [l=zh] {_httpimg_/zh/h\_count.gif}
+_widthhcount_ [l=zh] {200}
+_heighthcount_ [l=zh] {57}
+## "åå®¶" ## nav_bar_button ## tcount ##
+_httpicontcountgr_ [l=zh-tr] {_httpimg_/zh-tr/tcountgr.gif}
+_httpicontcountof_ [l=zh-tr] {_httpimg_/zh-tr/tcountof.gif}
+_httpicontcounton_ [l=zh-tr] {_httpimg_/zh-tr/tcounton.gif}
+## "åå®¶" ## green_title ## h_count ##
+_httpiconhcount_ [l=zh-tr] {_httpimg_/zh-tr/h\_count.gif}
+_widthhcount_ [l=zh-tr] {200}
+_heighthcount_ [l=zh-tr] {57}
+
+## "coverage" ## nav_bar_button ## tcover ##
+_httpicontcovergr_ {_httpimg_/en/tcovergr.gif}
+_httpicontcoveron_ {_httpimg_/en/tcoveron.gif}
+_httpicontcoverof_ {_httpimg_/en/tcoverof.gif}
+## "coverage" ## green_title ## h_cover ##
+_httpiconhcover_ {_httpimg_/en/h\_cover.gif}
+_widthhcover_ {200}
+_heighthcover_ {57}
+## "àŠ
+àŠšà§àŠ§àŠŸàŠ¬àŠš" ## nav_bar_button ## tcover ##
+_httpicontcovergr_ [l=bn] {_httpimg_/bn/tcovergr.gif}
+_httpicontcoveron_ [l=bn] {_httpimg_/bn/tcoveron.gif}
+_httpicontcoverof_ [l=bn] {_httpimg_/bn/tcoverof.gif}
+## "àŠ
+àŠšà§àŠ§àŠŸàŠ¬àŠš" ## green_title ## h_cover ##
+_httpiconhcover_ [l=bn] {_httpimg_/bn/h\_cover.gif}
+_widthhcover_ [l=bn] {200}
+_heighthcover_ [l=bn] {57}
+## "cobertura" ## nav_bar_button ## tcover ##
+_httpicontcovergr_ [l=es] {_httpimg_/es/tcovergr.gif}
+_httpicontcoveron_ [l=es] {_httpimg_/es/tcoveron.gif}
+_httpicontcoverof_ [l=es] {_httpimg_/es/tcoverof.gif}
+## "cobertura" ## green_title ## h_cover ##
+_httpiconhcover_ [l=es] {_httpimg_/es/h\_cover.gif}
+_widthhcover_ [l=es] {200}
+_heighthcover_ [l=es] {57}
+## "Couverture" ## nav_bar_button ## tcover ##
+_httpicontcovergr_ [l=fr] {_httpimg_/fr/tcovergr.gif}
+_httpicontcoveron_ [l=fr] {_httpimg_/fr/tcoveron.gif}
+_httpicontcoverof_ [l=fr] {_httpimg_/fr/tcoverof.gif}
+## "Couverture" ## green_title ## h_cover ##
+_httpiconhcover_ [l=fr] {_httpimg_/fr/h\_cover.gif}
+_widthhcover_ [l=fr] {200}
+_heighthcover_ [l=fr] {57}
+## "pencakupan" ## nav_bar_button ## tcover ##
+_httpicontcovergr_ [l=id] {_httpimg_/id/tcovergr.gif}
+_httpicontcoveron_ [l=id] {_httpimg_/id/tcoveron.gif}
+_httpicontcoverof_ [l=id] {_httpimg_/id/tcoverof.gif}
+## "pencakupan" ## green_title ## h_cover ##
+_httpiconhcover_ [l=id] {_httpimg_/id/h\_cover.gif}
+_widthhcover_ [l=id] {200}
+_heighthcover_ [l=id] {57}
+## "ÐŽÐ°ÑÐ°Ð»Ð°Ñ" ## nav_bar_button ## tcover ##
+_httpicontcovergr_ [l=ky] {_httpimg_/ky/tcovergr.gif}
+_httpicontcoveron_ [l=ky] {_httpimg_/ky/tcoveron.gif}
+_httpicontcoverof_ [l=ky] {_httpimg_/ky/tcoverof.gif}
+## "ÐŽÐ°ÑÐ°Ð»Ð°Ñ" ## green_title ## h_cover ##
+_httpiconhcover_ [l=ky] {_httpimg_/ky/h\_cover.gif}
+_widthhcover_ [l=ky] {200}
+_heighthcover_ [l=ky] {57}
+## "aptvÄrums" ## nav_bar_button ## tcover ##
+_httpicontcovergr_ [l=lv] {_httpimg_/lv/tcovergr.gif}
+_httpicontcoveron_ [l=lv] {_httpimg_/lv/tcoveron.gif}
+_httpicontcoverof_ [l=lv] {_httpimg_/lv/tcoverof.gif}
+## "aptvÄrums" ## green_title ## h_cover ##
+_httpiconhcover_ [l=lv] {_httpimg_/lv/h\_cover.gif}
+_widthhcover_ [l=lv] {200}
+_heighthcover_ [l=lv] {57}
+## "Ñ
+Ð°ÐŒÑÐ°Ñ
+ Ñ
+Ò¯ÑÑÑ" ## nav_bar_button ## tcover ##
+_httpicontcovergr_ [l=mn] {_httpimg_/mn/tcovergr.gif}
+_httpicontcoveron_ [l=mn] {_httpimg_/mn/tcoveron.gif}
+_httpicontcoverof_ [l=mn] {_httpimg_/mn/tcoverof.gif}
+## "Ñ
+Ð°ÐŒÑÐ°Ñ
+ Ñ
+Ò¯ÑÑÑ" ## green_title ## h_cover ##
+_httpiconhcover_ [l=mn] {_httpimg_/mn/h\_cover.gif}
+_widthhcover_ [l=mn] {200}
+_heighthcover_ [l=mn] {57}
+## "dziedzina" ## nav_bar_button ## tcover ##
+_httpicontcovergr_ [l=pl] {_httpimg_/pl/tcovergr.gif}
+_httpicontcoveron_ [l=pl] {_httpimg_/pl/tcoveron.gif}
+_httpicontcoverof_ [l=pl] {_httpimg_/pl/tcoverof.gif}
+## "dziedzina" ## green_title ## h_cover ##
+_httpiconhcover_ [l=pl] {_httpimg_/pl/h\_cover.gif}
+_widthhcover_ [l=pl] {200}
+_heighthcover_ [l=pl] {57}
+## "ÐŸÑ
+Ð²Ð°Ñ" ## nav_bar_button ## tcover ##
+_httpicontcovergr_ [l=ru] {_httpimg_/ru/tcovergr.gif}
+_httpicontcoveron_ [l=ru] {_httpimg_/ru/tcoveron.gif}
+_httpicontcoverof_ [l=ru] {_httpimg_/ru/tcoverof.gif}
+## "ÐŸÑ
+Ð²Ð°Ñ" ## green_title ## h_cover ##
+_httpiconhcover_ [l=ru] {_httpimg_/ru/h\_cover.gif}
+_widthhcover_ [l=ru] {200}
+_heighthcover_ [l=ru] {57}
+## "ç¯å" ## nav_bar_button ## tcover ##
+_httpicontcovergr_ [l=zh-tr] {_httpimg_/zh-tr/tcovergr.gif}
+_httpicontcoveron_ [l=zh-tr] {_httpimg_/zh-tr/tcoveron.gif}
+_httpicontcoverof_ [l=zh-tr] {_httpimg_/zh-tr/tcoverof.gif}
+## "ç¯å" ## green_title ## h_cover ##
+_httpiconhcover_ [l=zh-tr] {_httpimg_/zh-tr/h\_cover.gif}
+_widthhcover_ [l=zh-tr] {200}
+_heighthcover_ [l=zh-tr] {57}
+
+## "dates" ## nav_bar_button ## tdate ##
+_httpicontdategr_ {_httpimg_/en/tdategr.gif}
+_httpicontdateof_ {_httpimg_/en/tdateof.gif}
+_httpicontdateon_ {_httpimg_/en/tdateon.gif}
+## "dates" ## green_title ## h_date ##
+_httpiconhdate_ {_httpimg_/en/h\_date.gif}
+_widthhdate_ {200}
+_heighthdate_ {57}
+## "Ø§ÙØªÙØ§Ø±ÙØ®" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=ar] {_httpimg_/ar/tdategr.gif}
+_httpicontdateof_ [l=ar] {_httpimg_/ar/tdateof.gif}
+_httpicontdateon_ [l=ar] {_httpimg_/ar/tdateon.gif}
+## "Ø§ÙØªÙØ§Ø±ÙØ®" ## green_title ## h_date ##
+_httpiconhdate_ [l=ar] {_httpimg_/ar/h\_date.gif}
+_widthhdate_ [l=ar] {200}
+_heighthdate_ [l=ar] {57}
+## "àŠ€àŠŸàŠ°àŠ¿àŠàŠà§àŠ²àŠ¿" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=bn] {_httpimg_/bn/tdategr.gif}
+_httpicontdateof_ [l=bn] {_httpimg_/bn/tdateof.gif}
+_httpicontdateon_ [l=bn] {_httpimg_/bn/tdateon.gif}
+## "àŠ€àŠŸàŠ°àŠ¿àŠàŠà§àŠ²àŠ¿" ## green_title ## h_date ##
+_httpiconhdate_ [l=bn] {_httpimg_/bn/h\_date.gif}
+_widthhdate_ [l=bn] {200}
+_heighthdate_ [l=bn] {57}
+## "dates" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=ca] {_httpimg_/ca/tdategr.gif}
+_httpicontdateof_ [l=ca] {_httpimg_/ca/tdateof.gif}
+_httpicontdateon_ [l=ca] {_httpimg_/ca/tdateon.gif}
+## "dates" ## green_title ## h_date ##
+_httpiconhdate_ [l=ca] {_httpimg_/ca/h\_date.gif}
+_widthhdate_ [l=ca] {200}
+_heighthdate_ [l=ca] {57}
+## "datum" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=cs] {_httpimg_/cs/tdategr.gif}
+_httpicontdateof_ [l=cs] {_httpimg_/cs/tdateof.gif}
+_httpicontdateon_ [l=cs] {_httpimg_/cs/tdateon.gif}
+## "datum" ## green_title ## h_date ##
+_httpiconhdate_ [l=cs] {_httpimg_/cs/h\_date.gif}
+_widthhdate_ [l=cs] {200}
+_heighthdate_ [l=cs] {57}
+## "daten" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=de] {_httpimg_/de/tdategr.gif}
+_httpicontdateof_ [l=de] {_httpimg_/de/tdateof.gif}
+_httpicontdateon_ [l=de] {_httpimg_/de/tdateon.gif}
+## "daten" ## green_title ## h_date ##
+_httpiconhdate_ [l=de] {_httpimg_/de/h\_date.gif}
+_widthhdate_ [l=de] {200}
+_heighthdate_ [l=de] {57}
+## "Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯ÎµÏ" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=el] {_httpimg_/el/tdategr.gif}
+_httpicontdateof_ [l=el] {_httpimg_/el/tdateof.gif}
+_httpicontdateon_ [l=el] {_httpimg_/el/tdateon.gif}
+## "Î·ÎŒÎµÏÎ¿ÎŒÎ·ÎœÎ¯ÎµÏ" ## green_title ## h_date ##
+_httpiconhdate_ [l=el] {_httpimg_/el/h\_date.gif}
+_widthhdate_ [l=el] {200}
+_heighthdate_ [l=el] {57}
+## "fechas" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=es] {_httpimg_/es/tdategr.gif}
+_httpicontdateof_ [l=es] {_httpimg_/es/tdateof.gif}
+_httpicontdateon_ [l=es] {_httpimg_/es/tdateon.gif}
+## "fechas" ## green_title ## h_date ##
+_httpiconhdate_ [l=es] {_httpimg_/es/h\_date.gif}
+_widthhdate_ [l=es] {200}
+_heighthdate_ [l=es] {57}
+## "ØªØ§Ø±ÙØ® ÙØ§" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=fa] {_httpimg_/fa/tdategr.gif}
+_httpicontdateof_ [l=fa] {_httpimg_/fa/tdateof.gif}
+_httpicontdateon_ [l=fa] {_httpimg_/fa/tdateon.gif}
+## "ØªØ§Ø±ÙØ® ÙØ§" ## green_title ## h_date ##
+_httpiconhdate_ [l=fa] {_httpimg_/fa/h\_date.gif}
+_widthhdate_ [l=fa] {200}
+_heighthdate_ [l=fa] {57}
+## "pÃ€ivÃ€mÃ€Ã€rÃ€t" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=fi] {_httpimg_/fi/tdategr.gif}
+_httpicontdateof_ [l=fi] {_httpimg_/fi/tdateof.gif}
+_httpicontdateon_ [l=fi] {_httpimg_/fi/tdateon.gif}
+## "pÃ€ivÃ€mÃ€Ã€rÃ€t" ## green_title ## h_date ##
+_httpiconhdate_ [l=fi] {_httpimg_/fi/h\_date.gif}
+_widthhdate_ [l=fi] {200}
+_heighthdate_ [l=fi] {57}
+## "dates" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=fr] {_httpimg_/fr/tdategr.gif}
+_httpicontdateof_ [l=fr] {_httpimg_/fr/tdateof.gif}
+_httpicontdateon_ [l=fr] {_httpimg_/fr/tdateon.gif}
+## "dates" ## green_title ## h_date ##
+_httpiconhdate_ [l=fr] {_httpimg_/fr/h\_date.gif}
+_widthhdate_ [l=fr] {200}
+_heighthdate_ [l=fr] {57}
+## "datas" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=gl] {_httpimg_/gl/tdategr.gif}
+_httpicontdateof_ [l=gl] {_httpimg_/gl/tdateof.gif}
+_httpicontdateon_ [l=gl] {_httpimg_/gl/tdateon.gif}
+## "datas" ## green_title ## h_date ##
+_httpiconhdate_ [l=gl] {_httpimg_/gl/h\_date.gif}
+_widthhdate_ [l=gl] {200}
+_heighthdate_ [l=gl] {57}
+## "×××××š××ª" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=he] {_httpimg_/he/tdategr.gif}
+_httpicontdateof_ [l=he] {_httpimg_/he/tdateof.gif}
+_httpicontdateon_ [l=he] {_httpimg_/he/tdateon.gif}
+## "×××××š××ª" ## green_title ## h_date ##
+_httpiconhdate_ [l=he] {_httpimg_/he/h\_date.gif}
+_widthhdate_ [l=he] {200}
+_heighthdate_ [l=he] {57}
+## "datumi" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=hr] {_httpimg_/hr/tdategr.gif}
+_httpicontdateof_ [l=hr] {_httpimg_/hr/tdateof.gif}
+_httpicontdateon_ [l=hr] {_httpimg_/hr/tdateon.gif}
+## "datumi" ## green_title ## h_date ##
+_httpiconhdate_ [l=hr] {_httpimg_/hr/h\_date.gif}
+_widthhdate_ [l=hr] {200}
+_heighthdate_ [l=hr] {57}
+## "Õ¡ÕŽÕœÕ¡Õ©ÕŸÕ¥Ö" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=hy] {_httpimg_/hy/tdategr.gif}
+_httpicontdateof_ [l=hy] {_httpimg_/hy/tdateof.gif}
+_httpicontdateon_ [l=hy] {_httpimg_/hy/tdateon.gif}
+## "Õ¡ÕŽÕœÕ¡Õ©ÕŸÕ¥Ö" ## green_title ## h_date ##
+_httpiconhdate_ [l=hy] {_httpimg_/hy/h\_date.gif}
+_widthhdate_ [l=hy] {200}
+_heighthdate_ [l=hy] {57}
+## "tanggal" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=id] {_httpimg_/id/tdategr.gif}
+_httpicontdateof_ [l=id] {_httpimg_/id/tdateof.gif}
+_httpicontdateon_ [l=id] {_httpimg_/id/tdateon.gif}
+## "tanggal" ## green_title ## h_date ##
+_httpiconhdate_ [l=id] {_httpimg_/id/h\_date.gif}
+_widthhdate_ [l=id] {200}
+_heighthdate_ [l=id] {57}
+## "date" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=it] {_httpimg_/it/tdategr.gif}
+_httpicontdateof_ [l=it] {_httpimg_/it/tdateof.gif}
+_httpicontdateon_ [l=it] {_httpimg_/it/tdateon.gif}
+## "date" ## green_title ## h_date ##
+_httpiconhdate_ [l=it] {_httpimg_/it/h\_date.gif}
+_widthhdate_ [l=it] {200}
+_heighthdate_ [l=it] {57}
+## "æ¥ä»" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=ja] {_httpimg_/ja/tdategr.gif}
+_httpicontdateof_ [l=ja] {_httpimg_/ja/tdateof.gif}
+_httpicontdateon_ [l=ja] {_httpimg_/ja/tdateon.gif}
+## "æ¥ä»" ## green_title ## h_date ##
+_httpiconhdate_ [l=ja] {_httpimg_/ja/h\_date.gif}
+_widthhdate_ [l=ja] {200}
+_heighthdate_ [l=ja] {57}
+## "ááá ááŠá" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=ka] {_httpimg_/ka/tdategr.gif}
+_httpicontdateof_ [l=ka] {_httpimg_/ka/tdateof.gif}
+_httpicontdateon_ [l=ka] {_httpimg_/ka/tdateon.gif}
+## "ááá ááŠá" ## green_title ## h_date ##
+_httpiconhdate_ [l=ka] {_httpimg_/ka/h\_date.gif}
+_widthhdate_ [l=ka] {258}
+_heighthdate_ [l=ka] {74}
+## "ÐŽÐ°ÑÐ°Ð»Ð°Ñ" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=kk] {_httpimg_/kk/tdategr.gif}
+_httpicontdateof_ [l=kk] {_httpimg_/kk/tdateof.gif}
+_httpicontdateon_ [l=kk] {_httpimg_/kk/tdateon.gif}
+## "ÐŽÐ°ÑÐ°Ð»Ð°Ñ" ## green_title ## h_date ##
+_httpiconhdate_ [l=kk] {_httpimg_/kk/h\_date.gif}
+_widthhdate_ [l=kk] {200}
+_heighthdate_ [l=kk] {57}
+## "ÐŽÐ°ÑÐ°Ð»Ð°Ñ" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=ky] {_httpimg_/ky/tdategr.gif}
+_httpicontdateof_ [l=ky] {_httpimg_/ky/tdateof.gif}
+_httpicontdateon_ [l=ky] {_httpimg_/ky/tdateon.gif}
+## "ÐŽÐ°ÑÐ°Ð»Ð°Ñ" ## green_title ## h_date ##
+_httpiconhdate_ [l=ky] {_httpimg_/ky/h\_date.gif}
+_widthhdate_ [l=ky] {200}
+_heighthdate_ [l=ky] {57}
+## "datÄjums" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=lv] {_httpimg_/lv/tdategr.gif}
+_httpicontdateof_ [l=lv] {_httpimg_/lv/tdateof.gif}
+_httpicontdateon_ [l=lv] {_httpimg_/lv/tdateon.gif}
+## "datÄjums" ## green_title ## h_date ##
+_httpiconhdate_ [l=lv] {_httpimg_/lv/h\_date.gif}
+_widthhdate_ [l=lv] {200}
+_heighthdate_ [l=lv] {57}
+## "ngÄ rÄ" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=mi] {_httpimg_/mi/tdategr.gif}
+_httpicontdateof_ [l=mi] {_httpimg_/mi/tdateof.gif}
+_httpicontdateon_ [l=mi] {_httpimg_/mi/tdateon.gif}
+## "ngÄ rÄ" ## green_title ## h_date ##
+_httpiconhdate_ [l=mi] {_httpimg_/mi/h\_date.gif}
+_widthhdate_ [l=mi] {200}
+_heighthdate_ [l=mi] {57}
+## "Ó©ÐŽÑÒ¯Ò¯ÐŽ" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=mn] {_httpimg_/mn/tdategr.gif}
+_httpicontdateof_ [l=mn] {_httpimg_/mn/tdateof.gif}
+_httpicontdateon_ [l=mn] {_httpimg_/mn/tdateon.gif}
+## "ÐŸÐ³ÐœÐŸÐŸ" ## green_title ## h_date ##
+_httpiconhdate_ [l=mn] {_httpimg_/mn/h\_date.gif}
+_widthhdate_ [l=mn] {200}
+_heighthdate_ [l=mn] {57}
+## "datums" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=nl] {_httpimg_/nl/tdategr.gif}
+_httpicontdateof_ [l=nl] {_httpimg_/nl/tdateof.gif}
+_httpicontdateon_ [l=nl] {_httpimg_/nl/tdateon.gif}
+## "datums" ## green_title ## h_date ##
+_httpiconhdate_ [l=nl] {_httpimg_/nl/h\_date.gif}
+_widthhdate_ [l=nl] {200}
+_heighthdate_ [l=nl] {57}
+## "daty" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=pl] {_httpimg_/pl/tdategr.gif}
+_httpicontdateof_ [l=pl] {_httpimg_/pl/tdateof.gif}
+_httpicontdateon_ [l=pl] {_httpimg_/pl/tdateon.gif}
+## "daty" ## green_title ## h_date ##
+_httpiconhdate_ [l=pl] {_httpimg_/pl/h\_date.gif}
+_widthhdate_ [l=pl] {200}
+_heighthdate_ [l=pl] {57}
+## "datas" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=pt-br] {_httpimg_/pt-br/tdategr.gif}
+_httpicontdateof_ [l=pt-br] {_httpimg_/pt-br/tdateof.gif}
+_httpicontdateon_ [l=pt-br] {_httpimg_/pt-br/tdateon.gif}
+## "datas" ## green_title ## h_date ##
+_httpiconhdate_ [l=pt-br] {_httpimg_/pt-br/h\_date.gif}
+_widthhdate_ [l=pt-br] {200}
+_heighthdate_ [l=pt-br] {57}
+## "datas" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=pt-pt] {_httpimg_/pt-pt/tdategr.gif}
+_httpicontdateof_ [l=pt-pt] {_httpimg_/pt-pt/tdateof.gif}
+_httpicontdateon_ [l=pt-pt] {_httpimg_/pt-pt/tdateon.gif}
+## "datas" ## green_title ## h_date ##
+_httpiconhdate_ [l=pt-pt] {_httpimg_/pt-pt/h\_date.gif}
+_widthhdate_ [l=pt-pt] {200}
+_heighthdate_ [l=pt-pt] {57}
+## "ÐŽÐ°ÑÑ" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=ru] {_httpimg_/ru/tdategr.gif}
+_httpicontdateof_ [l=ru] {_httpimg_/ru/tdateof.gif}
+_httpicontdateon_ [l=ru] {_httpimg_/ru/tdateon.gif}
+## "ÐŽÐ°ÑÑ" ## green_title ## h_date ##
+_httpiconhdate_ [l=ru] {_httpimg_/ru/h\_date.gif}
+_widthhdate_ [l=ru] {200}
+_heighthdate_ [l=ru] {57}
+## "datumi" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=sr] {_httpimg_/sr/tdategr.gif}
+_httpicontdateof_ [l=sr] {_httpimg_/sr/tdateof.gif}
+_httpicontdateon_ [l=sr] {_httpimg_/sr/tdateon.gif}
+## "datumi" ## green_title ## h_date ##
+_httpiconhdate_ [l=sr] {_httpimg_/sr/h\_date.gif}
+_widthhdate_ [l=sr] {200}
+_heighthdate_ [l=sr] {57}
+## "àž§àž±àžàžàžµà¹" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=th] {_httpimg_/th/tdategr.gif}
+_httpicontdateof_ [l=th] {_httpimg_/th/tdateof.gif}
+_httpicontdateon_ [l=th] {_httpimg_/th/tdateon.gif}
+## "àž§àž±àžàžàžµà¹" ## green_title ## h_date ##
+_httpiconhdate_ [l=th] {_httpimg_/th/h\_date.gif}
+_widthhdate_ [l=th] {200}
+_heighthdate_ [l=th] {57}
+## "tarihler" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=tr] {_httpimg_/tr/tdategr.gif}
+_httpicontdateof_ [l=tr] {_httpimg_/tr/tdateof.gif}
+_httpicontdateon_ [l=tr] {_httpimg_/tr/tdateon.gif}
+## "tarihler" ## green_title ## h_date ##
+_httpiconhdate_ [l=tr] {_httpimg_/tr/h\_date.gif}
+_widthhdate_ [l=tr] {200}
+_heighthdate_ [l=tr] {57}
+## "ÐŽÐ°ÑÐž" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=uk] {_httpimg_/uk/tdategr.gif}
+_httpicontdateof_ [l=uk] {_httpimg_/uk/tdateof.gif}
+_httpicontdateon_ [l=uk] {_httpimg_/uk/tdateon.gif}
+## "ÐŽÐ°ÑÐž" ## green_title ## h_date ##
+_httpiconhdate_ [l=uk] {_httpimg_/uk/h\_date.gif}
+_widthhdate_ [l=uk] {200}
+_heighthdate_ [l=uk] {57}
+## "ngÃ y" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=vi] {_httpimg_/vi/tdategr.gif}
+_httpicontdateof_ [l=vi] {_httpimg_/vi/tdateof.gif}
+_httpicontdateon_ [l=vi] {_httpimg_/vi/tdateon.gif}
+## "ngÃ y" ## green_title ## h_date ##
+_httpiconhdate_ [l=vi] {_httpimg_/vi/h\_date.gif}
+_widthhdate_ [l=vi] {200}
+_heighthdate_ [l=vi] {57}
+## "æ¥å­" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=zh] {_httpimg_/zh/tdategr.gif}
+_httpicontdateof_ [l=zh] {_httpimg_/zh/tdateof.gif}
+_httpicontdateon_ [l=zh] {_httpimg_/zh/tdateon.gif}
+## "æ¥å­" ## green_title ## h_date ##
+_httpiconhdate_ [l=zh] {_httpimg_/zh/h\_date.gif}
+_widthhdate_ [l=zh] {200}
+_heighthdate_ [l=zh] {57}
+## "æ¥æ" ## nav_bar_button ## tdate ##
+_httpicontdategr_ [l=zh-tr] {_httpimg_/zh-tr/tdategr.gif}
+_httpicontdateof_ [l=zh-tr] {_httpimg_/zh-tr/tdateof.gif}
+_httpicontdateon_ [l=zh-tr] {_httpimg_/zh-tr/tdateon.gif}
+## "æ¥æ" ## green_title ## h_date ##
+_httpiconhdate_ [l=zh-tr] {_httpimg_/zh-tr/h\_date.gif}
+_widthhdate_ [l=zh-tr] {200}
+_heighthdate_ [l=zh-tr] {57}
+
+## "descriptions" ## nav_bar_button ## tdesc ##
+_httpicontdescgr_ {_httpimg_/en/tdescgr.gif}
+_httpicontdescon_ {_httpimg_/en/tdescon.gif}
+_httpicontdescof_ {_httpimg_/en/tdescof.gif}
+## "descriptions" ## green_title ## h_desc ##
+_httpiconhdesc_ {_httpimg_/en/h\_desc.gif}
+_widthhdesc_ {200}
+_heighthdesc_ {57}
+## "àŠ¬àŠ¿àŠ¬àŠ°àŠšà§" ## nav_bar_button ## tdesc ##
+_httpicontdescgr_ [l=bn] {_httpimg_/bn/tdescgr.gif}
+_httpicontdescon_ [l=bn] {_httpimg_/bn/tdescon.gif}
+_httpicontdescof_ [l=bn] {_httpimg_/bn/tdescof.gif}
+## "àŠ¬àŠ¿àŠ¬àŠ°àŠšà§" ## green_title ## h_desc ##
+_httpiconhdesc_ [l=bn] {_httpimg_/bn/h\_desc.gif}
+_widthhdesc_ [l=bn] {200}
+_heighthdesc_ [l=bn] {57}
+## "descripciÃ³nes" ## nav_bar_button ## tdesc ##
+_httpicontdescgr_ [l=es] {_httpimg_/es/tdescgr.gif}
+_httpicontdescon_ [l=es] {_httpimg_/es/tdescon.gif}
+_httpicontdescof_ [l=es] {_httpimg_/es/tdescof.gif}
+## "descripciÃ³nes" ## green_title ## h_desc ##
+_httpiconhdesc_ [l=es] {_httpimg_/es/h\_desc.gif}
+_widthhdesc_ [l=es] {200}
+_heighthdesc_ [l=es] {57}
+## "Descriptions" ## nav_bar_button ## tdesc ##
+_httpicontdescgr_ [l=fr] {_httpimg_/fr/tdescgr.gif}
+_httpicontdescon_ [l=fr] {_httpimg_/fr/tdescon.gif}
+_httpicontdescof_ [l=fr] {_httpimg_/fr/tdescof.gif}
+## "Descriptions" ## green_title ## h_desc ##
+_httpiconhdesc_ [l=fr] {_httpimg_/fr/h\_desc.gif}
+_widthhdesc_ [l=fr] {200}
+_heighthdesc_ [l=fr] {57}
+## "deskripsi" ## nav_bar_button ## tdesc ##
+_httpicontdescgr_ [l=id] {_httpimg_/id/tdescgr.gif}
+_httpicontdescon_ [l=id] {_httpimg_/id/tdescon.gif}
+_httpicontdescof_ [l=id] {_httpimg_/id/tdescof.gif}
+## "deskripsi" ## green_title ## h_desc ##
+_httpiconhdesc_ [l=id] {_httpimg_/id/h\_desc.gif}
+_widthhdesc_ [l=id] {200}
+_heighthdesc_ [l=id] {57}
+## "Ð±Ð°ÑÐœÐŽÐ°ÐŒÐ°Ð»Ð°Ñ" ## nav_bar_button ## tdesc ##
+_httpicontdescgr_ [l=ky] {_httpimg_/ky/tdescgr.gif}
+_httpicontdescon_ [l=ky] {_httpimg_/ky/tdescon.gif}
+_httpicontdescof_ [l=ky] {_httpimg_/ky/tdescof.gif}
+## "Ð±Ð°ÑÐœÐŽÐ°ÐŒÐ°Ð»Ð°Ñ" ## green_title ## h_desc ##
+_httpiconhdesc_ [l=ky] {_httpimg_/ky/h\_desc.gif}
+_widthhdesc_ [l=ky] {200}
+_heighthdesc_ [l=ky] {57}
+## "apraksti" ## nav_bar_button ## tdesc ##
+_httpicontdescgr_ [l=lv] {_httpimg_/lv/tdescgr.gif}
+_httpicontdescon_ [l=lv] {_httpimg_/lv/tdescon.gif}
+_httpicontdescof_ [l=lv] {_httpimg_/lv/tdescof.gif}
+## "apraksti" ## green_title ## h_desc ##
+_httpiconhdesc_ [l=lv] {_httpimg_/lv/h\_desc.gif}
+_widthhdesc_ [l=lv] {200}
+_heighthdesc_ [l=lv] {57}
+## "ÑÐ°Ð¹Ð»Ð±Ð°ÑÑÑÐŽ" ## nav_bar_button ## tdesc ##
+_httpicontdescgr_ [l=mn] {_httpimg_/mn/tdescgr.gif}
+_httpicontdescon_ [l=mn] {_httpimg_/mn/tdescon.gif}
+_httpicontdescof_ [l=mn] {_httpimg_/mn/tdescof.gif}
+## "ÑÐ°Ð¹Ð»Ð±Ð°ÑÑÑÐŽ" ## green_title ## h_desc ##
+_httpiconhdesc_ [l=mn] {_httpimg_/mn/h\_desc.gif}
+_widthhdesc_ [l=mn] {200}
+_heighthdesc_ [l=mn] {57}
+## "opisy" ## nav_bar_button ## tdesc ##
+_httpicontdescgr_ [l=pl] {_httpimg_/pl/tdescgr.gif}
+_httpicontdescon_ [l=pl] {_httpimg_/pl/tdescon.gif}
+_httpicontdescof_ [l=pl] {_httpimg_/pl/tdescof.gif}
+## "opisy" ## green_title ## h_desc ##
+_httpiconhdesc_ [l=pl] {_httpimg_/pl/h\_desc.gif}
+_widthhdesc_ [l=pl] {200}
+_heighthdesc_ [l=pl] {57}
+## "ÐŸÐ¿ÐžÑÐ°ÐœÐžÑ" ## nav_bar_button ## tdesc ##
+_httpicontdescgr_ [l=ru] {_httpimg_/ru/tdescgr.gif}
+_httpicontdescon_ [l=ru] {_httpimg_/ru/tdescon.gif}
+_httpicontdescof_ [l=ru] {_httpimg_/ru/tdescof.gif}
+## "ÐŸÐ¿ÐžÑÐ°ÐœÐžÑ" ## green_title ## h_desc ##
+_httpiconhdesc_ [l=ru] {_httpimg_/ru/h\_desc.gif}
+_widthhdesc_ [l=ru] {200}
+_heighthdesc_ [l=ru] {57}
+## "æè¿°" ## nav_bar_button ## tdesc ##
+_httpicontdescgr_ [l=zh-tr] {_httpimg_/zh-tr/tdescgr.gif}
+_httpicontdescon_ [l=zh-tr] {_httpimg_/zh-tr/tdescon.gif}
+_httpicontdescof_ [l=zh-tr] {_httpimg_/zh-tr/tdescof.gif}
+## "æè¿°" ## green_title ## h_desc ##
+_httpiconhdesc_ [l=zh-tr] {_httpimg_/zh-tr/h\_desc.gif}
+_widthhdesc_ [l=zh-tr] {200}
+_heighthdesc_ [l=zh-tr] {57}
+
+## "formats" ## nav_bar_button ## tform ##
+_httpicontformgr_ {_httpimg_/en/tformgr.gif}
+_httpicontformof_ {_httpimg_/en/tformof.gif}
+_httpicontformon_ {_httpimg_/en/tformon.gif}
+## "formats" ## green_title ## h_form ##
+_httpiconhform_ {_httpimg_/en/h\_form.gif}
+_widthhform_ {200}
+_heighthform_ {57}
+## "àŠ«àŠ°àŠ®à§àŠ¯àŠàŠž" ## nav_bar_button ## tform ##
+_httpicontformgr_ [l=bn] {_httpimg_/bn/tformgr.gif}
+_httpicontformof_ [l=bn] {_httpimg_/bn/tformof.gif}
+_httpicontformon_ [l=bn] {_httpimg_/bn/tformon.gif}
+## "àŠ«àŠ°àŠ®à§àŠ¯àŠàŠž" ## green_title ## h_form ##
+_httpiconhform_ [l=bn] {_httpimg_/bn/h\_form.gif}
+_widthhform_ [l=bn] {200}
+_heighthform_ [l=bn] {57}
+## "formatos" ## nav_bar_button ## tform ##
+_httpicontformgr_ [l=es] {_httpimg_/es/tformgr.gif}
+_httpicontformof_ [l=es] {_httpimg_/es/tformof.gif}
+_httpicontformon_ [l=es] {_httpimg_/es/tformon.gif}
+## "formatos" ## green_title ## h_form ##
+_httpiconhform_ [l=es] {_httpimg_/es/h\_form.gif}
+_widthhform_ [l=es] {200}
+_heighthform_ [l=es] {57}
+## "Formats" ## nav_bar_button ## tform ##
+_httpicontformgr_ [l=fr] {_httpimg_/fr/tformgr.gif}
+_httpicontformof_ [l=fr] {_httpimg_/fr/tformof.gif}
+_httpicontformon_ [l=fr] {_httpimg_/fr/tformon.gif}
+## "Formats" ## green_title ## h_form ##
+_httpiconhform_ [l=fr] {_httpimg_/fr/h\_form.gif}
+_widthhform_ [l=fr] {200}
+_heighthform_ [l=fr] {57}
+## "format" ## nav_bar_button ## tform ##
+_httpicontformgr_ [l=id] {_httpimg_/id/tformgr.gif}
+_httpicontformof_ [l=id] {_httpimg_/id/tformof.gif}
+_httpicontformon_ [l=id] {_httpimg_/id/tformon.gif}
+## "format" ## green_title ## h_form ##
+_httpiconhform_ [l=id] {_httpimg_/id/h\_form.gif}
+_widthhform_ [l=id] {200}
+_heighthform_ [l=id] {57}
+## "ÑÐŸÑÐŒÐ°ÑÑÐ°Ñ" ## nav_bar_button ## tform ##
+_httpicontformgr_ [l=ky] {_httpimg_/ky/tformgr.gif}
+_httpicontformof_ [l=ky] {_httpimg_/ky/tformof.gif}
+_httpicontformon_ [l=ky] {_httpimg_/ky/tformon.gif}
+## "ÑÐŸÑÐŒÐ°ÑÑÐ°Ñ" ## green_title ## h_form ##
+_httpiconhform_ [l=ky] {_httpimg_/ky/h\_form.gif}
+_widthhform_ [l=ky] {200}
+_heighthform_ [l=ky] {57}
+## "formÄti" ## nav_bar_button ## tform ##
+_httpicontformgr_ [l=lv] {_httpimg_/lv/tformgr.gif}
+_httpicontformof_ [l=lv] {_httpimg_/lv/tformof.gif}
+_httpicontformon_ [l=lv] {_httpimg_/lv/tformon.gif}
+## "formÄti" ## green_title ## h_form ##
+_httpiconhform_ [l=lv] {_httpimg_/lv/h\_form.gif}
+_widthhform_ [l=lv] {200}
+_heighthform_ [l=lv] {57}
+## "ÑÐŸÑÐŒÐ°Ñ" ## nav_bar_button ## tform ##
+_httpicontformgr_ [l=mn] {_httpimg_/mn/tformgr.gif}
+_httpicontformof_ [l=mn] {_httpimg_/mn/tformof.gif}
+_httpicontformon_ [l=mn] {_httpimg_/mn/tformon.gif}
+## "ÑÐŸÑÐŒÐ°Ñ" ## green_title ## h_form ##
+_httpiconhform_ [l=mn] {_httpimg_/mn/h\_form.gif}
+_widthhform_ [l=mn] {200}
+_heighthform_ [l=mn] {57}
+## "formaty" ## nav_bar_button ## tform ##
+_httpicontformgr_ [l=pl] {_httpimg_/pl/tformgr.gif}
+_httpicontformof_ [l=pl] {_httpimg_/pl/tformof.gif}
+_httpicontformon_ [l=pl] {_httpimg_/pl/tformon.gif}
+## "formaty" ## green_title ## h_form ##
+_httpiconhform_ [l=pl] {_httpimg_/pl/h\_form.gif}
+_widthhform_ [l=pl] {200}
+_heighthform_ [l=pl] {57}
+## "ÑÐŸÑÐŒÐ°ÑÑ" ## nav_bar_button ## tform ##
+_httpicontformgr_ [l=ru] {_httpimg_/ru/tformgr.gif}
+_httpicontformof_ [l=ru] {_httpimg_/ru/tformof.gif}
+_httpicontformon_ [l=ru] {_httpimg_/ru/tformon.gif}
+## "ÑÐŸÑÐŒÐ°ÑÑ" ## green_title ## h_form ##
+_httpiconhform_ [l=ru] {_httpimg_/ru/h\_form.gif}
+_widthhform_ [l=ru] {200}
+_heighthform_ [l=ru] {57}
+## "æ ŒåŒ" ## nav_bar_button ## tform ##
+_httpicontformgr_ [l=zh-tr] {_httpimg_/zh-tr/tformgr.gif}
+_httpicontformof_ [l=zh-tr] {_httpimg_/zh-tr/tformof.gif}
+_httpicontformon_ [l=zh-tr] {_httpimg_/zh-tr/tformon.gif}
+## "æ ŒåŒ" ## green_title ## h_form ##
+_httpiconhform_ [l=zh-tr] {_httpimg_/zh-tr/h\_form.gif}
+_widthhform_ [l=zh-tr] {200}
+_heighthform_ [l=zh-tr] {57}
+
+## "from" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ {_httpimg_/en/tfromgr.gif}
+_httpicontfromon_ {_httpimg_/en/tfromon.gif}
+_httpicontfromof_ {_httpimg_/en/tfromof.gif}
+## "from" ## green_title ## h_from ##
+_httpiconhfrom_ {_httpimg_/en/h\_from.gif}
+_widthhfrom_ {200}
+_heighthfrom_ {57}
+## "Ù
+Ù" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=ar] {_httpimg_/ar/tfromgr.gif}
+_httpicontfromon_ [l=ar] {_httpimg_/ar/tfromon.gif}
+_httpicontfromof_ [l=ar] {_httpimg_/ar/tfromof.gif}
+## "Ø§ÙØ±Ø§Ø³Ù" ## green_title ## h_from ##
+_httpiconhfrom_ [l=ar] {_httpimg_/ar/h\_from.gif}
+_widthhfrom_ [l=ar] {200}
+_heighthfrom_ [l=ar] {57}
+## "àŠ¥à§àŠà§" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=bn] {_httpimg_/bn/tfromgr.gif}
+_httpicontfromon_ [l=bn] {_httpimg_/bn/tfromon.gif}
+_httpicontfromof_ [l=bn] {_httpimg_/bn/tfromof.gif}
+## "àŠ¥à§àŠà§" ## green_title ## h_from ##
+_httpiconhfrom_ [l=bn] {_httpimg_/bn/h\_from.gif}
+_widthhfrom_ [l=bn] {200}
+_heighthfrom_ [l=bn] {57}
+## "de" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=ca] {_httpimg_/ca/tfromgr.gif}
+_httpicontfromon_ [l=ca] {_httpimg_/ca/tfromon.gif}
+_httpicontfromof_ [l=ca] {_httpimg_/ca/tfromof.gif}
+## "de" ## green_title ## h_from ##
+_httpiconhfrom_ [l=ca] {_httpimg_/ca/h\_from.gif}
+_widthhfrom_ [l=ca] {200}
+_heighthfrom_ [l=ca] {57}
+## "od" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=cs] {_httpimg_/cs/tfromgr.gif}
+_httpicontfromon_ [l=cs] {_httpimg_/cs/tfromon.gif}
+_httpicontfromof_ [l=cs] {_httpimg_/cs/tfromof.gif}
+## "od" ## green_title ## h_from ##
+_httpiconhfrom_ [l=cs] {_httpimg_/cs/h\_from.gif}
+_widthhfrom_ [l=cs] {200}
+_heighthfrom_ [l=cs] {57}
+## "Î±ÏÏ" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=el] {_httpimg_/el/tfromgr.gif}
+_httpicontfromon_ [l=el] {_httpimg_/el/tfromon.gif}
+_httpicontfromof_ [l=el] {_httpimg_/el/tfromof.gif}
+## "Î±ÏÏ" ## green_title ## h_from ##
+_httpiconhfrom_ [l=el] {_httpimg_/el/h\_from.gif}
+_widthhfrom_ [l=el] {200}
+_heighthfrom_ [l=el] {57}
+## "de" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=es] {_httpimg_/es/tfromgr.gif}
+_httpicontfromon_ [l=es] {_httpimg_/es/tfromon.gif}
+_httpicontfromof_ [l=es] {_httpimg_/es/tfromof.gif}
+## "de" ## green_title ## h_from ##
+_httpiconhfrom_ [l=es] {_httpimg_/es/h\_from.gif}
+_widthhfrom_ [l=es] {200}
+_heighthfrom_ [l=es] {57}
+## "Ø§Ø²" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=fa] {_httpimg_/fa/tfromgr.gif}
+_httpicontfromon_ [l=fa] {_httpimg_/fa/tfromon.gif}
+_httpicontfromof_ [l=fa] {_httpimg_/fa/tfromof.gif}
+## "Ø§Ø²" ## green_title ## h_from ##
+_httpiconhfrom_ [l=fa] {_httpimg_/fa/h\_from.gif}
+_widthhfrom_ [l=fa] {200}
+_heighthfrom_ [l=fa] {57}
+## "lÃ€hde" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=fi] {_httpimg_/fi/tfromgr.gif}
+_httpicontfromon_ [l=fi] {_httpimg_/fi/tfromon.gif}
+_httpicontfromof_ [l=fi] {_httpimg_/fi/tfromof.gif}
+## "lÃ€hde" ## green_title ## h_from ##
+_httpiconhfrom_ [l=fi] {_httpimg_/fi/h\_from.gif}
+_widthhfrom_ [l=fi] {200}
+_heighthfrom_ [l=fi] {57}
+## "de" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=fr] {_httpimg_/fr/tfromgr.gif}
+_httpicontfromon_ [l=fr] {_httpimg_/fr/tfromon.gif}
+_httpicontfromof_ [l=fr] {_httpimg_/fr/tfromof.gif}
+## "de" ## green_title ## h_from ##
+_httpiconhfrom_ [l=fr] {_httpimg_/fr/h\_from.gif}
+_widthhfrom_ [l=fr] {200}
+_heighthfrom_ [l=fr] {57}
+## "de" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=gl] {_httpimg_/gl/tfromgr.gif}
+_httpicontfromon_ [l=gl] {_httpimg_/gl/tfromon.gif}
+_httpicontfromof_ [l=gl] {_httpimg_/gl/tfromof.gif}
+## "de" ## green_title ## h_from ##
+_httpiconhfrom_ [l=gl] {_httpimg_/gl/h\_from.gif}
+_widthhfrom_ [l=gl] {200}
+_heighthfrom_ [l=gl] {57}
+## "××¢×" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=he] {_httpimg_/he/tfromgr.gif}
+_httpicontfromon_ [l=he] {_httpimg_/he/tfromon.gif}
+_httpicontfromof_ [l=he] {_httpimg_/he/tfromof.gif}
+## "××¢×" ## green_title ## h_from ##
+_httpiconhfrom_ [l=he] {_httpimg_/he/h\_from.gif}
+_widthhfrom_ [l=he] {200}
+_heighthfrom_ [l=he] {57}
+## "Õ¡ÕµÕœÕ¿Õ¥Õ²Õ«Ö" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=hy] {_httpimg_/hy/tfromgr.gif}
+_httpicontfromon_ [l=hy] {_httpimg_/hy/tfromon.gif}
+_httpicontfromof_ [l=hy] {_httpimg_/hy/tfromof.gif}
+## "Õ¡ÕµÕœÕ¿Õ¥Õ²Õ«Ö" ## green_title ## h_from ##
+_httpiconhfrom_ [l=hy] {_httpimg_/hy/h\_from.gif}
+_widthhfrom_ [l=hy] {200}
+_heighthfrom_ [l=hy] {57}
+## "dari" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=id] {_httpimg_/id/tfromgr.gif}
+_httpicontfromon_ [l=id] {_httpimg_/id/tfromon.gif}
+_httpicontfromof_ [l=id] {_httpimg_/id/tfromof.gif}
+## "dari" ## green_title ## h_from ##
+_httpiconhfrom_ [l=id] {_httpimg_/id/h\_from.gif}
+_widthhfrom_ [l=id] {200}
+_heighthfrom_ [l=id] {57}
+## "mittente" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=it] {_httpimg_/it/tfromgr.gif}
+_httpicontfromon_ [l=it] {_httpimg_/it/tfromon.gif}
+_httpicontfromof_ [l=it] {_httpimg_/it/tfromof.gif}
+## "mittente" ## green_title ## h_from ##
+_httpiconhfrom_ [l=it] {_httpimg_/it/h\_from.gif}
+_widthhfrom_ [l=it] {200}
+_heighthfrom_ [l=it] {57}
+## "âááá¡áááâ" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=ka] {_httpimg_/ka/tfromgr.gif}
+_httpicontfromon_ [l=ka] {_httpimg_/ka/tfromon.gif}
+_httpicontfromof_ [l=ka] {_httpimg_/ka/tfromof.gif}
+## "âááá¡áááâ" ## green_title ## h_from ##
+_httpiconhfrom_ [l=ka] {_httpimg_/ka/h\_from.gif}
+_widthhfrom_ [l=ka] {258}
+_heighthfrom_ [l=ka] {74}
+## "ÐºÑÐŒÐœÐµÐœ" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=kk] {_httpimg_/kk/tfromgr.gif}
+_httpicontfromon_ [l=kk] {_httpimg_/kk/tfromon.gif}
+_httpicontfromof_ [l=kk] {_httpimg_/kk/tfromof.gif}
+## "ÐºÑÐŒÐœÐµÐœ" ## green_title ## h_from ##
+_httpiconhfrom_ [l=kk] {_httpimg_/kk/h\_from.gif}
+_widthhfrom_ [l=kk] {200}
+_heighthfrom_ [l=kk] {57}
+## "ÐºÐžÐŒÐŽÐµÐœ" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=ky] {_httpimg_/ky/tfromgr.gif}
+_httpicontfromon_ [l=ky] {_httpimg_/ky/tfromon.gif}
+_httpicontfromof_ [l=ky] {_httpimg_/ky/tfromof.gif}
+## "ÑÐŸÑÐŒ" ## green_title ## h_from ##
+_httpiconhfrom_ [l=ky] {_httpimg_/ky/h\_from.gif}
+_widthhfrom_ [l=ky] {200}
+_heighthfrom_ [l=ky] {57}
+## "no" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=lv] {_httpimg_/lv/tfromgr.gif}
+_httpicontfromon_ [l=lv] {_httpimg_/lv/tfromon.gif}
+_httpicontfromof_ [l=lv] {_httpimg_/lv/tfromof.gif}
+## "no" ## green_title ## h_from ##
+_httpiconhfrom_ [l=lv] {_httpimg_/lv/h\_from.gif}
+_widthhfrom_ [l=lv] {200}
+_heighthfrom_ [l=lv] {57}
+## "nÄ wai" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=mi] {_httpimg_/mi/tfromgr.gif}
+_httpicontfromon_ [l=mi] {_httpimg_/mi/tfromon.gif}
+_httpicontfromof_ [l=mi] {_httpimg_/mi/tfromof.gif}
+## "nÄ wai" ## green_title ## h_from ##
+_httpiconhfrom_ [l=mi] {_httpimg_/mi/h\_from.gif}
+_widthhfrom_ [l=mi] {200}
+_heighthfrom_ [l=mi] {57}
+## "Ð°Ð°Ñ" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=mn] {_httpimg_/mn/tfromgr.gif}
+_httpicontfromon_ [l=mn] {_httpimg_/mn/tfromon.gif}
+_httpicontfromof_ [l=mn] {_httpimg_/mn/tfromof.gif}
+## "Ð°Ð°Ñ" ## green_title ## h_from ##
+_httpiconhfrom_ [l=mn] {_httpimg_/mn/h\_from.gif}
+_widthhfrom_ [l=mn] {200}
+_heighthfrom_ [l=mn] {57}
+## "afzender" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=nl] {_httpimg_/nl/tfromgr.gif}
+_httpicontfromon_ [l=nl] {_httpimg_/nl/tfromon.gif}
+_httpicontfromof_ [l=nl] {_httpimg_/nl/tfromof.gif}
+## "afzenders" ## green_title ## h_from ##
+_httpiconhfrom_ [l=nl] {_httpimg_/nl/h\_from.gif}
+_widthhfrom_ [l=nl] {200}
+_heighthfrom_ [l=nl] {57}
+## "od" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=pl] {_httpimg_/pl/tfromgr.gif}
+_httpicontfromon_ [l=pl] {_httpimg_/pl/tfromon.gif}
+_httpicontfromof_ [l=pl] {_httpimg_/pl/tfromof.gif}
+## "od" ## green_title ## h_from ##
+_httpiconhfrom_ [l=pl] {_httpimg_/pl/h\_from.gif}
+_widthhfrom_ [l=pl] {200}
+_heighthfrom_ [l=pl] {57}
+## "de" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=pt-pt] {_httpimg_/pt-pt/tfromgr.gif}
+_httpicontfromon_ [l=pt-pt] {_httpimg_/pt-pt/tfromon.gif}
+_httpicontfromof_ [l=pt-pt] {_httpimg_/pt-pt/tfromof.gif}
+## "de" ## green_title ## h_from ##
+_httpiconhfrom_ [l=pt-pt] {_httpimg_/pt-pt/h\_from.gif}
+_widthhfrom_ [l=pt-pt] {200}
+_heighthfrom_ [l=pt-pt] {57}
+## "ÐŸÑ ÐºÐŸÐ³ÐŸ" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=ru] {_httpimg_/ru/tfromgr.gif}
+_httpicontfromon_ [l=ru] {_httpimg_/ru/tfromon.gif}
+_httpicontfromof_ [l=ru] {_httpimg_/ru/tfromof.gif}
+## "ÐŸÑ ÐºÐŸÐ³ÐŸ" ## green_title ## h_from ##
+_httpiconhfrom_ [l=ru] {_httpimg_/ru/h\_from.gif}
+_widthhfrom_ [l=ru] {200}
+_heighthfrom_ [l=ru] {57}
+## "od koga" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=sr] {_httpimg_/sr/tfromgr.gif}
+_httpicontfromon_ [l=sr] {_httpimg_/sr/tfromon.gif}
+_httpicontfromof_ [l=sr] {_httpimg_/sr/tfromof.gif}
+## "od koga" ## green_title ## h_from ##
+_httpiconhfrom_ [l=sr] {_httpimg_/sr/h\_from.gif}
+_widthhfrom_ [l=sr] {200}
+_heighthfrom_ [l=sr] {57}
+## "àžàž²àž" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=th] {_httpimg_/th/tfromgr.gif}
+_httpicontfromon_ [l=th] {_httpimg_/th/tfromon.gif}
+_httpicontfromof_ [l=th] {_httpimg_/th/tfromof.gif}
+## "àžàž²àž" ## green_title ## h_from ##
+_httpiconhfrom_ [l=th] {_httpimg_/th/h\_from.gif}
+_widthhfrom_ [l=th] {200}
+_heighthfrom_ [l=th] {57}
+## "kimden" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=tr] {_httpimg_/tr/tfromgr.gif}
+_httpicontfromon_ [l=tr] {_httpimg_/tr/tfromon.gif}
+_httpicontfromof_ [l=tr] {_httpimg_/tr/tfromof.gif}
+## "kimden" ## green_title ## h_from ##
+_httpiconhfrom_ [l=tr] {_httpimg_/tr/h\_from.gif}
+_widthhfrom_ [l=tr] {200}
+_heighthfrom_ [l=tr] {57}
+## "Ð²ÑÐŽ" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=uk] {_httpimg_/uk/tfromgr.gif}
+_httpicontfromon_ [l=uk] {_httpimg_/uk/tfromon.gif}
+_httpicontfromof_ [l=uk] {_httpimg_/uk/tfromof.gif}
+## "Ð²ÑÐŽ" ## green_title ## h_from ##
+_httpiconhfrom_ [l=uk] {_httpimg_/uk/h\_from.gif}
+_widthhfrom_ [l=uk] {200}
+_heighthfrom_ [l=uk] {57}
+## "nguá»n gá»c" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=vi] {_httpimg_/vi/tfromgr.gif}
+_httpicontfromon_ [l=vi] {_httpimg_/vi/tfromon.gif}
+_httpicontfromof_ [l=vi] {_httpimg_/vi/tfromof.gif}
+## "nguá»n gá»c" ## green_title ## h_from ##
+_httpiconhfrom_ [l=vi] {_httpimg_/vi/h\_from.gif}
+_widthhfrom_ [l=vi] {200}
+_heighthfrom_ [l=vi] {57}
+## "åŒå§äº" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=zh] {_httpimg_/zh/tfromgr.gif}
+_httpicontfromon_ [l=zh] {_httpimg_/zh/tfromon.gif}
+_httpicontfromof_ [l=zh] {_httpimg_/zh/tfromof.gif}
+## "åŒå§äº" ## green_title ## h_from ##
+_httpiconhfrom_ [l=zh] {_httpimg_/zh/h\_from.gif}
+_widthhfrom_ [l=zh] {200}
+_heighthfrom_ [l=zh] {57}
+## "éå§æŒ" ## nav_bar_button ## tfrom ##
+_httpicontfromgr_ [l=zh-tr] {_httpimg_/zh-tr/tfromgr.gif}
+_httpicontfromon_ [l=zh-tr] {_httpimg_/zh-tr/tfromon.gif}
+_httpicontfromof_ [l=zh-tr] {_httpimg_/zh-tr/tfromof.gif}
+## "éå§æŒ" ## green_title ## h_from ##
+_httpiconhfrom_ [l=zh-tr] {_httpimg_/zh-tr/h\_from.gif}
+_widthhfrom_ [l=zh-tr] {200}
+_heighthfrom_ [l=zh-tr] {57}
+
+
+## "how to" ## nav_bar_button ## thow ##
+_httpiconthowgr_ {_httpimg_/en/thowgr.gif}
+_httpiconthowon_ {_httpimg_/en/thowon.gif}
+_httpiconthowof_ {_httpimg_/en/thowof.gif}
+## "how to" ## green_title ## h_how ##
+_httpiconhhow_ {_httpimg_/en/h\_how.gif}
+_widthhhow_ {200}
+_heighthhow_ {57}
+## "ÙÙÙ" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=ar] {_httpimg_/ar/thowgr.gif}
+_httpiconthowon_ [l=ar] {_httpimg_/ar/thowon.gif}
+_httpiconthowof_ [l=ar] {_httpimg_/ar/thowof.gif}
+## "ÙÙÙ" ## green_title ## h_how ##
+_httpiconhhow_ [l=ar] {_httpimg_/ar/h\_how.gif}
+_widthhhow_ [l=ar] {200}
+_heighthhow_ [l=ar] {57}
+## "àŠàŠ¿ àŠàŠ°à§" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=bn] {_httpimg_/bn/thowgr.gif}
+_httpiconthowon_ [l=bn] {_httpimg_/bn/thowon.gif}
+_httpiconthowof_ [l=bn] {_httpimg_/bn/thowof.gif}
+## "àŠàŠ¿ àŠàŠ°à§" ## green_title ## h_how ##
+_httpiconhhow_ [l=bn] {_httpimg_/bn/h\_how.gif}
+_widthhhow_ [l=bn] {200}
+_heighthhow_ [l=bn] {57}
+## "com" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=ca] {_httpimg_/ca/thowgr.gif}
+_httpiconthowon_ [l=ca] {_httpimg_/ca/thowon.gif}
+_httpiconthowof_ [l=ca] {_httpimg_/ca/thowof.gif}
+## "com" ## green_title ## h_how ##
+_httpiconhhow_ [l=ca] {_httpimg_/ca/h\_how.gif}
+_widthhhow_ [l=ca] {200}
+_heighthhow_ [l=ca] {57}
+## "jak na to" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=cs] {_httpimg_/cs/thowgr.gif}
+_httpiconthowon_ [l=cs] {_httpimg_/cs/thowon.gif}
+_httpiconthowof_ [l=cs] {_httpimg_/cs/thowof.gif}
+## "jak na to" ## green_title ## h_how ##
+_httpiconhhow_ [l=cs] {_httpimg_/cs/h\_how.gif}
+_widthhhow_ [l=cs] {200}
+_heighthhow_ [l=cs] {57}
+## "wie geht das?" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=de] {_httpimg_/de/thowgr.gif}
+_httpiconthowon_ [l=de] {_httpimg_/de/thowon.gif}
+_httpiconthowof_ [l=de] {_httpimg_/de/thowof.gif}
+## "wie geht das?" ## green_title ## h_how ##
+_httpiconhhow_ [l=de] {_httpimg_/de/h\_how.gif}
+_widthhhow_ [l=de] {200}
+_heighthhow_ [l=de] {57}
+## "ÏÏÏ ÎœÎ±" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=el] {_httpimg_/el/thowgr.gif}
+_httpiconthowon_ [l=el] {_httpimg_/el/thowon.gif}
+_httpiconthowof_ [l=el] {_httpimg_/el/thowof.gif}
+## "ÏÏÏ ÎœÎ±" ## green_title ## h_how ##
+_httpiconhhow_ [l=el] {_httpimg_/el/h\_how.gif}
+_widthhhow_ [l=el] {200}
+_heighthhow_ [l=el] {57}
+## "cÃ³mo" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=es] {_httpimg_/es/thowgr.gif}
+_httpiconthowon_ [l=es] {_httpimg_/es/thowon.gif}
+_httpiconthowof_ [l=es] {_httpimg_/es/thowof.gif}
+## "cÃ³mo" ## green_title ## h_how ##
+_httpiconhhow_ [l=es] {_httpimg_/es/h\_how.gif}
+_widthhhow_ [l=es] {200}
+_heighthhow_ [l=es] {57}
+## "ÚÚ¯ÙÙÙ Ø" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=fa] {_httpimg_/fa/thowgr.gif}
+_httpiconthowon_ [l=fa] {_httpimg_/fa/thowon.gif}
+_httpiconthowof_ [l=fa] {_httpimg_/fa/thowof.gif}
+## "ÚÚ¯ÙÙÙ" ## green_title ## h_how ##
+_httpiconhhow_ [l=fa] {_httpimg_/fa/h\_how.gif}
+_widthhhow_ [l=fa] {200}
+_heighthhow_ [l=fa] {57}
+## "how to" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=fi] {_httpimg_/fi/thowgr.gif}
+_httpiconthowon_ [l=fi] {_httpimg_/fi/thowon.gif}
+_httpiconthowof_ [l=fi] {_httpimg_/fi/thowof.gif}
+## "how to" ## green_title ## h_how ##
+_httpiconhhow_ [l=fi] {_httpimg_/fi/h\_how.gif}
+_widthhhow_ [l=fi] {200}
+_heighthhow_ [l=fi] {57}
+## "comment faire" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=fr] {_httpimg_/fr/thowgr.gif}
+_httpiconthowon_ [l=fr] {_httpimg_/fr/thowon.gif}
+_httpiconthowof_ [l=fr] {_httpimg_/fr/thowof.gif}
+## "comment faire" ## green_title ## h_how ##
+_httpiconhhow_ [l=fr] {_httpimg_/fr/h\_how.gif}
+_widthhhow_ [l=fr] {200}
+_heighthhow_ [l=fr] {57}
+## "como..." ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=gl] {_httpimg_/gl/thowgr.gif}
+_httpiconthowon_ [l=gl] {_httpimg_/gl/thowon.gif}
+_httpiconthowof_ [l=gl] {_httpimg_/gl/thowof.gif}
+## "como..." ## green_title ## h_how ##
+_httpiconhhow_ [l=gl] {_httpimg_/gl/h\_how.gif}
+_widthhhow_ [l=gl] {200}
+_heighthhow_ [l=gl] {57}
+## "××Š××" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=he] {_httpimg_/he/thowgr.gif}
+_httpiconthowon_ [l=he] {_httpimg_/he/thowon.gif}
+_httpiconthowof_ [l=he] {_httpimg_/he/thowof.gif}
+## "××Š××" ## green_title ## h_how ##
+_httpiconhhow_ [l=he] {_httpimg_/he/h\_how.gif}
+_widthhhow_ [l=he] {200}
+_heighthhow_ [l=he] {57}
+## "kako da" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=hr] {_httpimg_/hr/thowgr.gif}
+_httpiconthowon_ [l=hr] {_httpimg_/hr/thowon.gif}
+_httpiconthowof_ [l=hr] {_httpimg_/hr/thowof.gif}
+## "kako da" ## green_title ## h_how ##
+_httpiconhhow_ [l=hr] {_httpimg_/hr/h\_how.gif}
+_widthhhow_ [l=hr] {200}
+_heighthhow_ [l=hr] {57}
+## "Õ«Õ¶Õ¹ÕºÕ¥Õœ" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=hy] {_httpimg_/hy/thowgr.gif}
+_httpiconthowon_ [l=hy] {_httpimg_/hy/thowon.gif}
+_httpiconthowof_ [l=hy] {_httpimg_/hy/thowof.gif}
+## "Õ«Õ¶Õ¹ÕºÕ¥Õœ" ## green_title ## h_how ##
+_httpiconhhow_ [l=hy] {_httpimg_/hy/h\_how.gif}
+_widthhhow_ [l=hy] {200}
+_heighthhow_ [l=hy] {57}
+## "bagaimana" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=id] {_httpimg_/id/thowgr.gif}
+_httpiconthowon_ [l=id] {_httpimg_/id/thowon.gif}
+_httpiconthowof_ [l=id] {_httpimg_/id/thowof.gif}
+## "bagaimana" ## green_title ## h_how ##
+_httpiconhhow_ [l=id] {_httpimg_/id/h\_how.gif}
+_widthhhow_ [l=id] {200}
+_heighthhow_ [l=id] {57}
+## "guide pratiche" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=it] {_httpimg_/it/thowgr.gif}
+_httpiconthowon_ [l=it] {_httpimg_/it/thowon.gif}
+_httpiconthowof_ [l=it] {_httpimg_/it/thowof.gif}
+## "guide pratiche" ## green_title ## h_how ##
+_httpiconhhow_ [l=it] {_httpimg_/it/h\_how.gif}
+_widthhhow_ [l=it] {200}
+_heighthhow_ [l=it] {57}
+## "ã©ã®ããã«" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=ja] {_httpimg_/ja/thowgr.gif}
+_httpiconthowon_ [l=ja] {_httpimg_/ja/thowon.gif}
+_httpiconthowof_ [l=ja] {_httpimg_/ja/thowof.gif}
+## "á¡áášá£ááááááá" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=ka] {_httpimg_/ka/thowgr.gif}
+_httpiconthowon_ [l=ka] {_httpimg_/ka/thowon.gif}
+_httpiconthowof_ [l=ka] {_httpimg_/ka/thowof.gif}
+## "á¡áášá£ááááááá" ## green_title ## h_how ##
+_httpiconhhow_ [l=ka] {_httpimg_/ka/h\_how.gif}
+_widthhhow_ [l=ka] {258}
+_heighthhow_ [l=ka] {74}
+## "ÑÓÑÑÐ»ÐŽÐµÑ" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=kk] {_httpimg_/kk/thowgr.gif}
+_httpiconthowon_ [l=kk] {_httpimg_/kk/thowon.gif}
+_httpiconthowof_ [l=kk] {_httpimg_/kk/thowof.gif}
+## "ÑÓÑÑÐ»ÐŽÐµÑ" ## green_title ## h_how ##
+_httpiconhhow_ [l=kk] {_httpimg_/kk/h\_how.gif}
+_widthhhow_ [l=kk] {200}
+_heighthhow_ [l=kk] {57}
+## "Ð°ÑÐ°ÐºÐµÑÑÐµÑ" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=ky] {_httpimg_/ky/thowgr.gif}
+_httpiconthowon_ [l=ky] {_httpimg_/ky/thowon.gif}
+_httpiconthowof_ [l=ky] {_httpimg_/ky/thowof.gif}
+## "Ð°ÑÐ°ÐºÐµÑÑÐµÑ" ## green_title ## h_how ##
+_httpiconhhow_ [l=ky] {_httpimg_/ky/h\_how.gif}
+_widthhhow_ [l=ky] {200}
+_heighthhow_ [l=ky] {57}
+## "kÄdÄ veidÄ" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=lv] {_httpimg_/lv/thowgr.gif}
+_httpiconthowon_ [l=lv] {_httpimg_/lv/thowon.gif}
+_httpiconthowof_ [l=lv] {_httpimg_/lv/thowof.gif}
+## "kÄdÄ veidÄ" ## green_title ## h_how ##
+_httpiconhhow_ [l=lv] {_httpimg_/lv/h\_how.gif}
+_widthhhow_ [l=lv] {200}
+_heighthhow_ [l=lv] {57}
+## "pÄwhea te" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=mi] {_httpimg_/mi/thowgr.gif}
+_httpiconthowon_ [l=mi] {_httpimg_/mi/thowon.gif}
+_httpiconthowof_ [l=mi] {_httpimg_/mi/thowof.gif}
+## "pÄwhea te" ## green_title ## h_how ##
+_httpiconhhow_ [l=mi] {_httpimg_/mi/h\_how.gif}
+_widthhhow_ [l=mi] {200}
+_heighthhow_ [l=mi] {57}
+## "Ð¥ÑÑÑ
+ÑÐœ" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=mn] {_httpimg_/mn/thowgr.gif}
+_httpiconthowon_ [l=mn] {_httpimg_/mn/thowon.gif}
+_httpiconthowof_ [l=mn] {_httpimg_/mn/thowof.gif}
+## "Ñ
+ÑÑÑ
+ÑÐœ" ## green_title ## h_how ##
+_httpiconhhow_ [l=mn] {_httpimg_/mn/h\_how.gif}
+_widthhhow_ [l=mn] {200}
+_heighthhow_ [l=mn] {57}
+## "help onderwerpen" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=nl] {_httpimg_/nl/thowgr.gif}
+_httpiconthowon_ [l=nl] {_httpimg_/nl/thowon.gif}
+_httpiconthowof_ [l=nl] {_httpimg_/nl/thowof.gif}
+## "help onderwerpen" ## green_title ## h_how ##
+_httpiconhhow_ [l=nl] {_httpimg_/nl/h\_how.gif}
+_widthhhow_ [l=nl] {200}
+_heighthhow_ [l=nl] {57}
+## "jak..." ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=pl] {_httpimg_/pl/thowgr.gif}
+_httpiconthowon_ [l=pl] {_httpimg_/pl/thowon.gif}
+_httpiconthowof_ [l=pl] {_httpimg_/pl/thowof.gif}
+## "jak..." ## green_title ## h_how ##
+_httpiconhhow_ [l=pl] {_httpimg_/pl/h\_how.gif}
+_widthhhow_ [l=pl] {200}
+_heighthhow_ [l=pl] {57}
+## "como fazer" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=pt-br] {_httpimg_/pt-br/thowgr.gif}
+_httpiconthowon_ [l=pt-br] {_httpimg_/pt-br/thowon.gif}
+_httpiconthowof_ [l=pt-br] {_httpimg_/pt-br/thowof.gif}
+## "como fazer" ## green_title ## h_how ##
+_httpiconhhow_ [l=pt-br] {_httpimg_/pt-br/h\_how.gif}
+_widthhhow_ [l=pt-br] {200}
+_heighthhow_ [l=pt-br] {57}
+## "como" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=pt-pt] {_httpimg_/pt-pt/thowgr.gif}
+_httpiconthowon_ [l=pt-pt] {_httpimg_/pt-pt/thowon.gif}
+_httpiconthowof_ [l=pt-pt] {_httpimg_/pt-pt/thowof.gif}
+## "como" ## green_title ## h_how ##
+_httpiconhhow_ [l=pt-pt] {_httpimg_/pt-pt/h\_how.gif}
+_widthhhow_ [l=pt-pt] {200}
+_heighthhow_ [l=pt-pt] {57}
+## "ÑÐ¿ÐŸÑÐŸÐ±Ñ" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=ru] {_httpimg_/ru/thowgr.gif}
+_httpiconthowon_ [l=ru] {_httpimg_/ru/thowon.gif}
+_httpiconthowof_ [l=ru] {_httpimg_/ru/thowof.gif}
+## "ÑÐ¿ÐŸÑÐŸÐ±Ñ" ## green_title ## h_how ##
+_httpiconhhow_ [l=ru] {_httpimg_/ru/h\_how.gif}
+_widthhhow_ [l=ru] {200}
+_heighthhow_ [l=ru] {57}
+## "kako da" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=sr] {_httpimg_/sr/thowgr.gif}
+_httpiconthowon_ [l=sr] {_httpimg_/sr/thowon.gif}
+_httpiconthowof_ [l=sr] {_httpimg_/sr/thowof.gif}
+## "kako da" ## green_title ## h_how ##
+_httpiconhhow_ [l=sr] {_httpimg_/sr/h\_how.gif}
+_widthhhow_ [l=sr] {200}
+_heighthhow_ [l=sr] {57}
+## "àž­àž¢à¹àž²àžà¹àž£" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=th] {_httpimg_/th/thowgr.gif}
+_httpiconthowon_ [l=th] {_httpimg_/th/thowon.gif}
+_httpiconthowof_ [l=th] {_httpimg_/th/thowof.gif}
+## "àžªàž­àžàž«àž£àž·àž­àž­àžàžŽàžàž²àž¢àž§àžŽàžàžµàžàž²àž£àžàž³" ## green_title ## h_how ##
+_httpiconhhow_ [l=th] {_httpimg_/th/h\_how.gif}
+_widthhhow_ [l=th] {200}
+_heighthhow_ [l=th] {57}
+## "nasÄ±l" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=tr] {_httpimg_/tr/thowgr.gif}
+_httpiconthowon_ [l=tr] {_httpimg_/tr/thowon.gif}
+_httpiconthowof_ [l=tr] {_httpimg_/tr/thowof.gif}
+## "nasÄ±l" ## green_title ## h_how ##
+_httpiconhhow_ [l=tr] {_httpimg_/tr/h\_how.gif}
+_widthhhow_ [l=tr] {200}
+_heighthhow_ [l=tr] {57}
+## "ÑÐº" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=uk] {_httpimg_/uk/thowgr.gif}
+_httpiconthowon_ [l=uk] {_httpimg_/uk/thowon.gif}
+_httpiconthowof_ [l=uk] {_httpimg_/uk/thowof.gif}
+## "ÑÐº" ## green_title ## h_how ##
+_httpiconhhow_ [l=uk] {_httpimg_/uk/h\_how.gif}
+_widthhhow_ [l=uk] {200}
+_heighthhow_ [l=uk] {57}
+## "gá»£i Ãœ" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=vi] {_httpimg_/vi/thowgr.gif}
+_httpiconthowon_ [l=vi] {_httpimg_/vi/thowon.gif}
+_httpiconthowof_ [l=vi] {_httpimg_/vi/thowof.gif}
+## "gá»£i Ãœ" ## green_title ## h_how ##
+_httpiconhhow_ [l=vi] {_httpimg_/vi/h\_how.gif}
+_widthhhow_ [l=vi] {200}
+_heighthhow_ [l=vi] {57}
+## "âåŠäœâ" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=zh] {_httpimg_/zh/thowgr.gif}
+_httpiconthowon_ [l=zh] {_httpimg_/zh/thowon.gif}
+_httpiconthowof_ [l=zh] {_httpimg_/zh/thowof.gif}
+## "âåŠäœâ" ## green_title ## h_how ##
+_httpiconhhow_ [l=zh] {_httpimg_/zh/h\_how.gif}
+_widthhhow_ [l=zh] {200}
+_heighthhow_ [l=zh] {57}
+## "åŠäœïœ¥ïœ¥" ## nav_bar_button ## thow ##
+_httpiconthowgr_ [l=zh-tr] {_httpimg_/zh-tr/thowgr.gif}
+_httpiconthowon_ [l=zh-tr] {_httpimg_/zh-tr/thowon.gif}
+_httpiconthowof_ [l=zh-tr] {_httpimg_/zh-tr/thowof.gif}
+## "åŠäœïœ¥ïœ¥" ## green_title ## h_how ##
+_httpiconhhow_ [l=zh-tr] {_httpimg_/zh-tr/h\_how.gif}
+_widthhhow_ [l=zh-tr] {200}
+_heighthhow_ [l=zh-tr] {57}
+
+## "identifiers" ## nav_bar_button ## tident ##
+_httpicontidentgr_ {_httpimg_/en/tidentgr.gif}
+_httpicontidentof_ {_httpimg_/en/tidentof.gif}
+_httpicontidenton_ {_httpimg_/en/tidenton.gif}
+## "identifiers" ## green_title ## h_ident ##
+_httpiconhident_ {_httpimg_/en/h\_ident.gif}
+_widthhident_ {200}
+_heighthident_ {57}
+## "àŠšàŠ¿àŠ°à§àŠŠà§àŠ¶àŠ" ## nav_bar_button ## tident ##
+_httpicontidentgr_ [l=bn] {_httpimg_/bn/tidentgr.gif}
+_httpicontidentof_ [l=bn] {_httpimg_/bn/tidentof.gif}
+_httpicontidenton_ [l=bn] {_httpimg_/bn/tidenton.gif}
+## "àŠšàŠ¿àŠ°à§àŠŠà§àŠ¶àŠ" ## green_title ## h_ident ##
+_httpiconhident_ [l=bn] {_httpimg_/bn/h\_ident.gif}
+_widthhident_ [l=bn] {200}
+_heighthident_ [l=bn] {57}
+## "identificadores" ## nav_bar_button ## tident ##
+_httpicontidentgr_ [l=es] {_httpimg_/es/tidentgr.gif}
+_httpicontidentof_ [l=es] {_httpimg_/es/tidentof.gif}
+_httpicontidenton_ [l=es] {_httpimg_/es/tidenton.gif}
+## "identificadores" ## green_title ## h_ident ##
+_httpiconhident_ [l=es] {_httpimg_/es/h\_ident.gif}
+_widthhident_ [l=es] {200}
+_heighthident_ [l=es] {57}
+## "Identifiants" ## nav_bar_button ## tident ##
+_httpicontidentgr_ [l=fr] {_httpimg_/fr/tidentgr.gif}
+_httpicontidentof_ [l=fr] {_httpimg_/fr/tidentof.gif}
+_httpicontidenton_ [l=fr] {_httpimg_/fr/tidenton.gif}
+## "Identifiants" ## green_title ## h_ident ##
+_httpiconhident_ [l=fr] {_httpimg_/fr/h\_ident.gif}
+_widthhident_ [l=fr] {200}
+_heighthident_ [l=fr] {57}
+## "pengenal" ## nav_bar_button ## tident ##
+_httpicontidentgr_ [l=id] {_httpimg_/id/tidentgr.gif}
+_httpicontidentof_ [l=id] {_httpimg_/id/tidentof.gif}
+_httpicontidenton_ [l=id] {_httpimg_/id/tidenton.gif}
+## "pengenal" ## green_title ## h_ident ##
+_httpiconhident_ [l=id] {_httpimg_/id/h\_ident.gif}
+_widthhident_ [l=id] {200}
+_heighthident_ [l=id] {57}
+## "Ð±ÐµÐ»Ð³ÐžÐ»ÐµÑ" ## nav_bar_button ## tident ##
+_httpicontidentgr_ [l=ky] {_httpimg_/ky/tidentgr.gif}
+_httpicontidentof_ [l=ky] {_httpimg_/ky/tidentof.gif}
+_httpicontidenton_ [l=ky] {_httpimg_/ky/tidenton.gif}
+## "Ð±ÐµÐ»Ð³ÐžÐ»ÐµÑ" ## green_title ## h_ident ##
+_httpiconhident_ [l=ky] {_httpimg_/ky/h\_ident.gif}
+_widthhident_ [l=ky] {200}
+_heighthident_ [l=ky] {57}
+## "identifikatori" ## nav_bar_button ## tident ##
+_httpicontidentgr_ [l=lv] {_httpimg_/lv/tidentgr.gif}
+_httpicontidentof_ [l=lv] {_httpimg_/lv/tidentof.gif}
+_httpicontidenton_ [l=lv] {_httpimg_/lv/tidenton.gif}
+## "identifikatori" ## green_title ## h_ident ##
+_httpiconhident_ [l=lv] {_httpimg_/lv/h\_ident.gif}
+_widthhident_ [l=lv] {200}
+_heighthident_ [l=lv] {57}
+## "ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹Ð»ÐŸÐ³Ñ" ## nav_bar_button ## tident ##
+_httpicontidentgr_ [l=mn] {_httpimg_/mn/tidentgr.gif}
+_httpicontidentof_ [l=mn] {_httpimg_/mn/tidentof.gif}
+_httpicontidenton_ [l=mn] {_httpimg_/mn/tidenton.gif}
+## "ÑÐŸÐŽÐŸÑÑ
+ÐŸÐ¹Ð»ÐŸÐ³Ñ" ## green_title ## h_ident ##
+_httpiconhident_ [l=mn] {_httpimg_/mn/h\_ident.gif}
+_widthhident_ [l=mn] {200}
+_heighthident_ [l=mn] {57}
+## "identyfikatory" ## nav_bar_button ## tident ##
+_httpicontidentgr_ [l=pl] {_httpimg_/pl/tidentgr.gif}
+_httpicontidentof_ [l=pl] {_httpimg_/pl/tidentof.gif}
+_httpicontidenton_ [l=pl] {_httpimg_/pl/tidenton.gif}
+## "identyfikatory" ## green_title ## h_ident ##
+_httpiconhident_ [l=pl] {_httpimg_/pl/h\_ident.gif}
+_widthhident_ [l=pl] {200}
+_heighthident_ [l=pl] {57}
+## "ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑÑ" ## nav_bar_button ## tident ##
+_httpicontidentgr_ [l=ru] {_httpimg_/ru/tidentgr.gif}
+_httpicontidentof_ [l=ru] {_httpimg_/ru/tidentof.gif}
+_httpicontidenton_ [l=ru] {_httpimg_/ru/tidenton.gif}
+## "ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑÑ" ## green_title ## h_ident ##
+_httpiconhident_ [l=ru] {_httpimg_/ru/h\_ident.gif}
+_widthhident_ [l=ru] {200}
+_heighthident_ [l=ru] {57}
+## "ç¢ºèªè
+" ## nav_bar_button ## tident ##
+_httpicontidentgr_ [l=zh-tr] {_httpimg_/zh-tr/tidentgr.gif}
+_httpicontidentof_ [l=zh-tr] {_httpimg_/zh-tr/tidentof.gif}
+_httpicontidenton_ [l=zh-tr] {_httpimg_/zh-tr/tidenton.gif}
+## "ç¢ºèªè
+" ## green_title ## h_ident ##
+_httpiconhident_ [l=zh-tr] {_httpimg_/zh-tr/h\_ident.gif}
+_widthhident_ [l=zh-tr] {200}
+_heighthident_ [l=zh-tr] {57}
+
+## "keywords" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ {_httpimg_/en/tkwgr.gif}
+_httpicontkwof_ {_httpimg_/en/tkwof.gif}
+_httpicontkwon_ {_httpimg_/en/tkwon.gif}
+## "keywords" ## green_title ## h_kw ##
+_httpiconhkw_ {_httpimg_/en/h\_kw.gif}
+_widthhkw_ {200}
+_heighthkw_ {57}
+## "Ø§ÙÙÙØ§Ù
+Ø§Øª Ø§ÙÙ
+ÙØªØ§Ø­ÙØ©" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=ar] {_httpimg_/ar/tkwgr.gif}
+_httpicontkwof_ [l=ar] {_httpimg_/ar/tkwof.gif}
+_httpicontkwon_ [l=ar] {_httpimg_/ar/tkwon.gif}
+## "Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙÙ
+ÙØªØ§Ø­ÙØ©" ## green_title ## h_kw ##
+_httpiconhkw_ [l=ar] {_httpimg_/ar/h\_kw.gif}
+_widthhkw_ [l=ar] {200}
+_heighthkw_ [l=ar] {57}
+## "àŠàŠ¿àŠà§àŠŸàŠ°à§àŠ¡ / àŠ®à§àŠ²àŠ¶àŠ¬à§àŠŠ" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=bn] {_httpimg_/bn/tkwgr.gif}
+_httpicontkwof_ [l=bn] {_httpimg_/bn/tkwof.gif}
+_httpicontkwon_ [l=bn] {_httpimg_/bn/tkwon.gif}
+## "àŠàŠ¿àŠà§àŠŸàŠ°à§àŠ¡ / àŠ®à§àŠ²àŠ¶àŠ¬à§àŠŠ" ## green_title ## h_kw ##
+_httpiconhkw_ [l=bn] {_httpimg_/bn/h\_kw.gif}
+_widthhkw_ [l=bn] {200}
+_heighthkw_ [l=bn] {57}
+## "paraules clau" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=ca] {_httpimg_/ca/tkwgr.gif}
+_httpicontkwof_ [l=ca] {_httpimg_/ca/tkwof.gif}
+_httpicontkwon_ [l=ca] {_httpimg_/ca/tkwon.gif}
+## "paraules clau" ## green_title ## h_kw ##
+_httpiconhkw_ [l=ca] {_httpimg_/ca/h\_kw.gif}
+_widthhkw_ [l=ca] {200}
+_heighthkw_ [l=ca] {57}
+## "klÃ­ÄovÃ¡ slova" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=cs] {_httpimg_/cs/tkwgr.gif}
+_httpicontkwof_ [l=cs] {_httpimg_/cs/tkwof.gif}
+_httpicontkwon_ [l=cs] {_httpimg_/cs/tkwon.gif}
+## "klÃ­ÄovÃ¡ slova" ## green_title ## h_kw ##
+_httpiconhkw_ [l=cs] {_httpimg_/cs/h\_kw.gif}
+_widthhkw_ [l=cs] {200}
+_heighthkw_ [l=cs] {57}
+## "Î»Î­ÎŸÎµÎ¹Ï ÎºÎ»ÎµÎ¹ÎŽÎ¹Î¬" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=el] {_httpimg_/el/tkwgr.gif}
+_httpicontkwof_ [l=el] {_httpimg_/el/tkwof.gif}
+_httpicontkwon_ [l=el] {_httpimg_/el/tkwon.gif}
+## "Î»Î­ÎŸÎµÎ¹Ï ÎºÎ»ÎµÎ¹ÎŽÎ¹Î¬" ## green_title ## h_kw ##
+_httpiconhkw_ [l=el] {_httpimg_/el/h\_kw.gif}
+_widthhkw_ [l=el] {200}
+_heighthkw_ [l=el] {57}
+## "palabras clave" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=es] {_httpimg_/es/tkwgr.gif}
+_httpicontkwof_ [l=es] {_httpimg_/es/tkwof.gif}
+_httpicontkwon_ [l=es] {_httpimg_/es/tkwon.gif}
+## "palabras clave" ## green_title ## h_kw ##
+_httpiconhkw_ [l=es] {_httpimg_/es/h\_kw.gif}
+_widthhkw_ [l=es] {200}
+_heighthkw_ [l=es] {57}
+## "ÙÙÙ
+Ø§Øª ÙÙÙØ¯Ù" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=fa] {_httpimg_/fa/tkwgr.gif}
+_httpicontkwof_ [l=fa] {_httpimg_/fa/tkwof.gif}
+_httpicontkwon_ [l=fa] {_httpimg_/fa/tkwon.gif}
+## "ÙÙÙ
+Ø§Øª ÙÙÙØ¯Ù" ## green_title ## h_kw ##
+_httpiconhkw_ [l=fa] {_httpimg_/fa/h\_kw.gif}
+_widthhkw_ [l=fa] {200}
+_heighthkw_ [l=fa] {57}
+## "avainsanat" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=fi] {_httpimg_/fi/tkwgr.gif}
+_httpicontkwof_ [l=fi] {_httpimg_/fi/tkwof.gif}
+_httpicontkwon_ [l=fi] {_httpimg_/fi/tkwon.gif}
+## "avainsanat" ## green_title ## h_kw ##
+_httpiconhkw_ [l=fi] {_httpimg_/fi/h\_kw.gif}
+_widthhkw_ [l=fi] {200}
+_heighthkw_ [l=fi] {57}
+## "mots-clefs" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=fr] {_httpimg_/fr/tkwgr.gif}
+_httpicontkwof_ [l=fr] {_httpimg_/fr/tkwof.gif}
+_httpicontkwon_ [l=fr] {_httpimg_/fr/tkwon.gif}
+## "mots-clefs" ## green_title ## h_kw ##
+_httpiconhkw_ [l=fr] {_httpimg_/fr/h\_kw.gif}
+_widthhkw_ [l=fr] {200}
+_heighthkw_ [l=fr] {57}
+## "palabras clave" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=gl] {_httpimg_/gl/tkwgr.gif}
+_httpicontkwof_ [l=gl] {_httpimg_/gl/tkwof.gif}
+_httpicontkwon_ [l=gl] {_httpimg_/gl/tkwon.gif}
+## "palabras clave" ## green_title ## h_kw ##
+_httpiconhkw_ [l=gl] {_httpimg_/gl/h\_kw.gif}
+_widthhkw_ [l=gl] {200}
+_heighthkw_ [l=gl] {57}
+## "kljuÄne rijeÄi" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=hr] {_httpimg_/hr/tkwgr.gif}
+_httpicontkwof_ [l=hr] {_httpimg_/hr/tkwof.gif}
+_httpicontkwon_ [l=hr] {_httpimg_/hr/tkwon.gif}
+## "kljuÄne rijeÄi" ## green_title ## h_kw ##
+_httpiconhkw_ [l=hr] {_httpimg_/hr/h_kw.gif}
+_widthhkw_ [l=hr] {200}
+_heighthkw_ [l=hr] {57}
+## "Õ¢Õ¡Õ¶Õ¡Õ¬Õ« Õ¢Õ¡ÕŒÕ¥Ö" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=hy] {_httpimg_/hy/tkwgr.gif}
+_httpicontkwof_ [l=hy] {_httpimg_/hy/tkwof.gif}
+_httpicontkwon_ [l=hy] {_httpimg_/hy/tkwon.gif}
+## "Õ¢Õ¡Õ¶Õ¡Õ¬Õ« Õ¢Õ¡ÕŒÕ¥Ö" ## green_title ## h_kw ##
+_httpiconhkw_ [l=hy] {_httpimg_/hy/h\_kw.gif}
+_widthhkw_ [l=hy] {200}
+_heighthkw_ [l=hy] {57}
+## "kata kunci" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=id] {_httpimg_/id/tkwgr.gif}
+_httpicontkwof_ [l=id] {_httpimg_/id/tkwof.gif}
+_httpicontkwon_ [l=id] {_httpimg_/id/tkwon.gif}
+## "kata kunci" ## green_title ## h_kw ##
+_httpiconhkw_ [l=id] {_httpimg_/id/h\_kw.gif}
+_widthhkw_ [l=id] {200}
+_heighthkw_ [l=id] {57}
+## "parole chiave" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=it] {_httpimg_/it/tkwgr.gif}
+_httpicontkwof_ [l=it] {_httpimg_/it/tkwof.gif}
+_httpicontkwon_ [l=it] {_httpimg_/it/tkwon.gif}
+## "parole chiave" ## green_title ## h_kw ##
+_httpiconhkw_ [l=it] {_httpimg_/it/h\_kw.gif}
+_widthhkw_ [l=it] {200}
+_heighthkw_ [l=it] {57}
+## "ã­ãŒã¯ãŒã" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=ja] {_httpimg_/ja/tkwgr.gif}
+_httpicontkwof_ [l=ja] {_httpimg_/ja/tkwof.gif}
+_httpicontkwon_ [l=ja] {_httpimg_/ja/tkwon.gif}
+## "ã­ãŒã¯ãŒã" ## green_title ## h_kw ##
+_httpiconhkw_ [l=ja] {_httpimg_/ja/h\_kw.gif}
+_widthhkw_ [l=ja] {200}
+_heighthkw_ [l=ja] {57}
+## "á¡áááááá«á á¡áá¢á§áááá" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=ka] {_httpimg_/ka/tkwgr.gif}
+_httpicontkwof_ [l=ka] {_httpimg_/ka/tkwof.gif}
+_httpicontkwon_ [l=ka] {_httpimg_/ka/tkwon.gif}
+## "á¡áááááá«á\ná¡áá¢á§áááá" ## green_title ## h_kw ##
+_httpiconhkw_ [l=ka] {_httpimg_/ka/h\_kw.gif}
+_widthhkw_ [l=ka] {258}
+_heighthkw_ [l=ka] {74}
+## "ÐŒÐ°Ò£ÑÐ· ÑÓ©Ð·ÐŽÓ©Ñ" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=ky] {_httpimg_/ky/tkwgr.gif}
+_httpicontkwof_ [l=ky] {_httpimg_/ky/tkwof.gif}
+_httpicontkwon_ [l=ky] {_httpimg_/ky/tkwon.gif}
+## "ÐŒÐ°Ò£ÑÐ·ÐŽÑÑ ÑÓ©Ð·ÐŽÓ©Ñ" ## green_title ## h_kw ##
+_httpiconhkw_ [l=ky] {_httpimg_/ky/h\_kw.gif}
+_widthhkw_ [l=ky] {200}
+_heighthkw_ [l=ky] {57}
+## "atslÄgvÄrdi" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=lv] {_httpimg_/lv/tkwgr.gif}
+_httpicontkwof_ [l=lv] {_httpimg_/lv/tkwof.gif}
+_httpicontkwon_ [l=lv] {_httpimg_/lv/tkwon.gif}
+## "atslÄgvÄrdi" ## green_title ## h_kw ##
+_httpiconhkw_ [l=lv] {_httpimg_/lv/h\_kw.gif}
+_widthhkw_ [l=lv] {200}
+_heighthkw_ [l=lv] {57}
+## "kupu matua" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=mi] {_httpimg_/mi/tkwgr.gif}
+_httpicontkwof_ [l=mi] {_httpimg_/mi/tkwof.gif}
+_httpicontkwon_ [l=mi] {_httpimg_/mi/tkwon.gif}
+## "kupu matua" ## green_title ## h_kw ##
+_httpiconhkw_ [l=mi] {_httpimg_/mi/h\_kw.gif}
+_widthhkw_ [l=mi] {200}
+_heighthkw_ [l=mi] {57}
+## "ÑÒ¯Ð»Ñ
+Ò¯Ò¯Ñ Ò¯Ð³" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=mn] {_httpimg_/mn/tkwgr.gif}
+_httpicontkwof_ [l=mn] {_httpimg_/mn/tkwof.gif}
+_httpicontkwon_ [l=mn] {_httpimg_/mn/tkwon.gif}
+## "ÑÒ¯Ð»Ñ
+Ò¯Ò¯Ñ Ò¯Ð³Ñ" ## green_title ## h_kw ##
+_httpiconhkw_ [l=mn] {_httpimg_/mn/h\_kw.gif}
+_widthhkw_ [l=mn] {200}
+_heighthkw_ [l=mn] {57}
+## "sÅowa kluczowe" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=pl] {_httpimg_/pl/tkwgr.gif}
+_httpicontkwof_ [l=pl] {_httpimg_/pl/tkwof.gif}
+_httpicontkwon_ [l=pl] {_httpimg_/pl/tkwon.gif}
+## "sÅowa kluczowe" ## green_title ## h_kw ##
+_httpiconhkw_ [l=pl] {_httpimg_/pl/h\_kw.gif}
+_widthhkw_ [l=pl] {200}
+_heighthkw_ [l=pl] {57}
+## "palavras-chave" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=pt-pt] {_httpimg_/pt-pt/tkwgr.gif}
+_httpicontkwof_ [l=pt-pt] {_httpimg_/pt-pt/tkwof.gif}
+_httpicontkwon_ [l=pt-pt] {_httpimg_/pt-pt/tkwon.gif}
+## "palavras-chave" ## green_title ## h_kw ##
+_httpiconhkw_ [l=pt-pt] {_httpimg_/pt-pt/h\_kw.gif}
+_widthhkw_ [l=pt-pt] {200}
+_heighthkw_ [l=pt-pt] {57}
+## "ÐºÐ»ÑÑÐµÐ²ÑÐµ ÑÐ»ÐŸÐ²Ð°" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=ru] {_httpimg_/ru/tkwgr.gif}
+_httpicontkwof_ [l=ru] {_httpimg_/ru/tkwof.gif}
+_httpicontkwon_ [l=ru] {_httpimg_/ru/tkwon.gif}
+## "ÐºÐ»ÑÑÐµÐ²ÑÐµ ÑÐ»ÐŸÐ²Ð°" ## green_title ## h_kw ##
+_httpiconhkw_ [l=ru] {_httpimg_/ru/h\_kw.gif}
+_widthhkw_ [l=ru] {200}
+_heighthkw_ [l=ru] {57}
+## "kljuÄne reÄi" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=sr] {_httpimg_/sr/tkwgr.gif}
+_httpicontkwof_ [l=sr] {_httpimg_/sr/tkwof.gif}
+_httpicontkwon_ [l=sr] {_httpimg_/sr/tkwon.gif}
+## "kljuÄne reÄi" ## green_title ## h_kw ##
+_httpiconhkw_ [l=sr] {_httpimg_/sr/h\_kw.gif}
+_widthhkw_ [l=sr] {200}
+_heighthkw_ [l=sr] {57}
+## "àž£àž«àž±àžªàžàž³" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=th] {_httpimg_/th/tkwgr.gif}
+_httpicontkwof_ [l=th] {_httpimg_/th/tkwof.gif}
+_httpicontkwon_ [l=th] {_httpimg_/th/tkwon.gif}
+## "àžàž³à¹àžàž£àž«àž±àžª" ## green_title ## h_kw ##
+_httpiconhkw_ [l=th] {_httpimg_/th/h\_kw.gif}
+_widthhkw_ [l=th] {200}
+_heighthkw_ [l=th] {57}
+## "anahtar sÃ¶zcÃŒkler" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=tr] {_httpimg_/tr/tkwgr.gif}
+_httpicontkwof_ [l=tr] {_httpimg_/tr/tkwof.gif}
+_httpicontkwon_ [l=tr] {_httpimg_/tr/tkwon.gif}
+## "anahtar sÃ¶zcÃŒkler" ## green_title ## h_kw ##
+_httpiconhkw_ [l=tr] {_httpimg_/tr/h\_kw.gif}
+_widthhkw_ [l=tr] {200}
+_heighthkw_ [l=tr] {57}
+## "ÐºÐ»ÑÑÐŸÐ²Ñ ÑÐ»ÐŸÐ²Ð°" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=uk] {_httpimg_/uk/tkwgr.gif}
+_httpicontkwof_ [l=uk] {_httpimg_/uk/tkwof.gif}
+_httpicontkwon_ [l=uk] {_httpimg_/uk/tkwon.gif}
+## "ÐºÐ»ÑÑÐŸÐ²Ñ ÑÐŸÐ²Ð°" ## green_title ## h_kw ##
+_httpiconhkw_ [l=uk] {_httpimg_/uk/h\_kw.gif}
+_widthhkw_ [l=uk] {200}
+_heighthkw_ [l=uk] {57}
+## "tá»« khoÃ¡" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=vi] {_httpimg_/vi/tkwgr.gif}
+_httpicontkwof_ [l=vi] {_httpimg_/vi/tkwof.gif}
+_httpicontkwon_ [l=vi] {_httpimg_/vi/tkwon.gif}
+## "tá»« khoÃ¡" ## green_title ## h_kw ##
+_httpiconhkw_ [l=vi] {_httpimg_/vi/h\_kw.gif}
+_widthhkw_ [l=vi] {200}
+_heighthkw_ [l=vi] {57}
+## "å
+³é®è¯" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=zh] {_httpimg_/zh/tkwgr.gif}
+_httpicontkwof_ [l=zh] {_httpimg_/zh/tkwof.gif}
+_httpicontkwon_ [l=zh] {_httpimg_/zh/tkwon.gif}
+## "å
+³é®è¯" ## green_title ## h_kw ##
+_httpiconhkw_ [l=zh] {_httpimg_/zh/h\_kw.gif}
+_widthhkw_ [l=zh] {200}
+_heighthkw_ [l=zh] {57}
+## "ééµè©" ## nav_bar_button ## tkw ##
+_httpicontkwgr_ [l=zh-tr] {_httpimg_/zh-tr/tkwgr.gif}
+_httpicontkwof_ [l=zh-tr] {_httpimg_/zh-tr/tkwof.gif}
+_httpicontkwon_ [l=zh-tr] {_httpimg_/zh-tr/tkwon.gif}
+## "ééµè©" ## green_title ## h_kw ##
+_httpiconhkw_ [l=zh-tr] {_httpimg_/zh-tr/h\_kw.gif}
+_widthhkw_ [l=zh-tr] {200}
+_heighthkw_ [l=zh-tr] {57}
+
+## "languages" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ {_httpimg_/en/tlanggr.gif}
+_httpicontlangon_ {_httpimg_/en/tlangon.gif}
+_httpicontlangof_ {_httpimg_/en/tlangof.gif}
+## "languages" ## green_title ## h_lang ##
+_httpiconhlang_ {_httpimg_/en/h\_lang.gif}
+_widthhlang_ {200}
+_heighthlang_ {57}
+## "Ø§ÙÙØºØ©" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=ar] {_httpimg_/ar/tlanggr.gif}
+_httpicontlangon_ [l=ar] {_httpimg_/ar/tlangon.gif}
+_httpicontlangof_ [l=ar] {_httpimg_/ar/tlangof.gif}
+## "Ø§ÙÙØºØ§Øª" ## green_title ## h_lang ##
+_httpiconhlang_ [l=ar] {_httpimg_/ar/h\_lang.gif}
+_widthhlang_ [l=ar] {200}
+_heighthlang_ [l=ar] {57}
+## "àŠ­àŠŸàŠ·àŠŸàŠà§àŠ²àŠ¿" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=bn] {_httpimg_/bn/tlanggr.gif}
+_httpicontlangon_ [l=bn] {_httpimg_/bn/tlangon.gif}
+_httpicontlangof_ [l=bn] {_httpimg_/bn/tlangof.gif}
+## "àŠ­àŠŸàŠ·àŠŸàŠà§àŠ²àŠ¿" ## green_title ## h_lang ##
+_httpiconhlang_ [l=bn] {_httpimg_/bn/h\_lang.gif}
+_widthhlang_ [l=bn] {200}
+_heighthlang_ [l=bn] {57}
+## "idiomes" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=ca] {_httpimg_/ca/tlanggr.gif}
+_httpicontlangon_ [l=ca] {_httpimg_/ca/tlangon.gif}
+_httpicontlangof_ [l=ca] {_httpimg_/ca/tlangof.gif}
+## "idiomes" ## green_title ## h_lang ##
+_httpiconhlang_ [l=ca] {_httpimg_/ca/h\_lang.gif}
+_widthhlang_ [l=ca] {200}
+_heighthlang_ [l=ca] {57}
+## "jazyk" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=cs] {_httpimg_/cs/tlanggr.gif}
+_httpicontlangon_ [l=cs] {_httpimg_/cs/tlangon.gif}
+_httpicontlangof_ [l=cs] {_httpimg_/cs/tlangof.gif}
+## "jazyk" ## green_title ## h_lang ##
+_httpiconhlang_ [l=cs] {_httpimg_/cs/h\_lang.gif}
+_widthhlang_ [l=cs] {200}
+_heighthlang_ [l=cs] {57}
+## "Î³Î»ÏÏÏÎ±" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=el] {_httpimg_/el/tlanggr.gif}
+_httpicontlangon_ [l=el] {_httpimg_/el/tlangon.gif}
+_httpicontlangof_ [l=el] {_httpimg_/el/tlangof.gif}
+## "Î³Î»ÏÏÏÎµÏ" ## green_title ## h_lang ##
+_httpiconhlang_ [l=el] {_httpimg_/el/h\_lang.gif}
+_widthhlang_ [l=el] {200}
+_heighthlang_ [l=el] {57}
+## "idiomas" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=es] {_httpimg_/es/tlanggr.gif}
+_httpicontlangon_ [l=es] {_httpimg_/es/tlangon.gif}
+_httpicontlangof_ [l=es] {_httpimg_/es/tlangof.gif}
+## "idiomas" ## green_title ## h_lang ##
+_httpiconhlang_ [l=es] {_httpimg_/es/h\_lang.gif}
+_widthhlang_ [l=es] {200}
+_heighthlang_ [l=es] {57}
+## "Ø²ØšØ§Ù" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=fa] {_httpimg_/fa/tlanggr.gif}
+_httpicontlangon_ [l=fa] {_httpimg_/fa/tlangon.gif}
+_httpicontlangof_ [l=fa] {_httpimg_/fa/tlangof.gif}
+## "Ø²ØšØ§ÙÙØ§" ## green_title ## h_lang ##
+_httpiconhlang_ [l=fa] {_httpimg_/fa/h\_lang.gif}
+_widthhlang_ [l=fa] {200}
+_heighthlang_ [l=fa] {57}
+## "kieli" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=fi] {_httpimg_/fi/tlanggr.gif}
+_httpicontlangon_ [l=fi] {_httpimg_/fi/tlangon.gif}
+_httpicontlangof_ [l=fi] {_httpimg_/fi/tlangof.gif}
+## "kielet" ## green_title ## h_lang ##
+_httpiconhlang_ [l=fi] {_httpimg_/fi/h\_lang.gif}
+_widthhlang_ [l=fi] {200}
+_heighthlang_ [l=fi] {57}
+## "langue" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=fr] {_httpimg_/fr/tlanggr.gif}
+_httpicontlangon_ [l=fr] {_httpimg_/fr/tlangon.gif}
+_httpicontlangof_ [l=fr] {_httpimg_/fr/tlangof.gif}
+## "langues" ## green_title ## h_lang ##
+_httpiconhlang_ [l=fr] {_httpimg_/fr/h\_lang.gif}
+_widthhlang_ [l=fr] {200}
+_heighthlang_ [l=fr] {57}
+## "lingua" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=gl] {_httpimg_/gl/tlanggr.gif}
+_httpicontlangon_ [l=gl] {_httpimg_/gl/tlangon.gif}
+_httpicontlangof_ [l=gl] {_httpimg_/gl/tlangof.gif}
+## "linguas" ## green_title ## h_lang ##
+_httpiconhlang_ [l=gl] {_httpimg_/gl/h\_lang.gif}
+_widthhlang_ [l=gl] {200}
+_heighthlang_ [l=gl] {57}
+## "××€×©" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=he] {_httpimg_/he/tlanggr.gif}
+_httpicontlangon_ [l=he] {_httpimg_/he/tlangon.gif}
+_httpicontlangof_ [l=he] {_httpimg_/he/tlangof.gif}
+## "×ª××€×©" ## green_title ## h_lang ##
+_httpiconhlang_ [l=he] {_httpimg_/he/h\_lang.gif}
+_widthhlang_ [l=he] {200}
+_heighthlang_ [l=he] {57}
+## "jezici" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=hr] {_httpimg_/hr/tlanggr.gif}
+_httpicontlangon_ [l=hr] {_httpimg_/hr/tlangon.gif}
+_httpicontlangof_ [l=hr] {_httpimg_/hr/tlangof.gif}
+## "jezici" ## green_title ## h_lang ##
+_httpiconhlang_ [l=hr] {_httpimg_/hr/h\_lang.gif}
+_widthhlang_ [l=hr] {200}
+_heighthlang_ [l=hr] {57}
+## "Õ¬Õ¥ÕŠÕžÖ" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=hy] {_httpimg_/hy/tlanggr.gif}
+_httpicontlangon_ [l=hy] {_httpimg_/hy/tlangon.gif}
+_httpicontlangof_ [l=hy] {_httpimg_/hy/tlangof.gif}
+## "Õ¬Õ¥ÕŠÕžÖÕ¶Õ¥Ö" ## green_title ## h_lang ##
+_httpiconhlang_ [l=hy] {_httpimg_/hy/h\_lang.gif}
+_widthhlang_ [l=hy] {200}
+_heighthlang_ [l=hy] {57}
+## "bahasa" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=id] {_httpimg_/id/tlanggr.gif}
+_httpicontlangon_ [l=id] {_httpimg_/id/tlangon.gif}
+_httpicontlangof_ [l=id] {_httpimg_/id/tlangof.gif}
+## "bahasa" ## green_title ## h_lang ##
+_httpiconhlang_ [l=id] {_httpimg_/id/h\_lang.gif}
+_widthhlang_ [l=id] {200}
+_heighthlang_ [l=id] {57}
+## "lingue" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=it] {_httpimg_/it/tlanggr.gif}
+_httpicontlangon_ [l=it] {_httpimg_/it/tlangon.gif}
+_httpicontlangof_ [l=it] {_httpimg_/it/tlangof.gif}
+## "lingua" ## green_title ## h_lang ##
+_httpiconhlang_ [l=it] {_httpimg_/it/h\_lang.gif}
+_widthhlang_ [l=it] {200}
+_heighthlang_ [l=it] {57}
+## "èšèª" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=ja] {_httpimg_/ja/tlanggr.gif}
+_httpicontlangon_ [l=ja] {_httpimg_/ja/tlangon.gif}
+_httpicontlangof_ [l=ja] {_httpimg_/ja/tlangof.gif}
+## "èšèª" ## green_title ## h_lang ##
+_httpiconhlang_ [l=ja] {_httpimg_/ja/h\_lang.gif}
+_widthhlang_ [l=ja] {200}
+_heighthlang_ [l=ja] {57}
+## "ááá" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=ka] {_httpimg_/ka/tlanggr.gif}
+_httpicontlangon_ [l=ka] {_httpimg_/ka/tlangon.gif}
+_httpicontlangof_ [l=ka] {_httpimg_/ka/tlangof.gif}
+## "ááá" ## green_title ## h_lang ##
+_httpiconhlang_ [l=ka] {_httpimg_/ka/h\_lang.gif}
+_widthhlang_ [l=ka] {258}
+_heighthlang_ [l=ka] {74}
+## "Ð°ÑÐ°ÑÐ»Ð°Ñ" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=kk] {_httpimg_/kk/tlanggr.gif}
+_httpicontlangon_ [l=kk] {_httpimg_/kk/tlangon.gif}
+_httpicontlangof_ [l=kk] {_httpimg_/kk/tlangof.gif}
+## "ÑÑÐ»ÐŽÐµÑ" ## green_title ## h_lang ##
+_httpiconhlang_ [l=kk] {_httpimg_/kk/h\_lang.gif}
+_widthhlang_ [l=kk] {200}
+_heighthlang_ [l=kk] {57}
+## "ÑÐžÐ»ÐŽÐµÑ" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=ky] {_httpimg_/ky/tlanggr.gif}
+_httpicontlangon_ [l=ky] {_httpimg_/ky/tlangon.gif}
+_httpicontlangof_ [l=ky] {_httpimg_/ky/tlangof.gif}
+## "ÑÐžÐ»ÐŽÐµÑ" ## green_title ## h_lang ##
+_httpiconhlang_ [l=ky] {_httpimg_/ky/h\_lang.gif}
+_widthhlang_ [l=ky] {200}
+_heighthlang_ [l=ky] {57}
+## "valodas" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=lv] {_httpimg_/lv/tlanggr.gif}
+_httpicontlangon_ [l=lv] {_httpimg_/lv/tlangon.gif}
+_httpicontlangof_ [l=lv] {_httpimg_/lv/tlangof.gif}
+## "valodas" ## green_title ## h_lang ##
+_httpiconhlang_ [l=lv] {_httpimg_/lv/h\_lang.gif}
+_widthhlang_ [l=lv] {200}
+_heighthlang_ [l=lv] {57}
+## "reo" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=mi] {_httpimg_/mi/tlanggr.gif}
+_httpicontlangon_ [l=mi] {_httpimg_/mi/tlangon.gif}
+_httpicontlangof_ [l=mi] {_httpimg_/mi/tlangof.gif}
+## "ngÄ reo" ## green_title ## h_lang ##
+_httpiconhlang_ [l=mi] {_httpimg_/mi/h\_lang.gif}
+_widthhlang_ [l=mi] {200}
+_heighthlang_ [l=mi] {57}
+## "Ñ
+ÑÐ»Ò¯Ò¯ÐŽ" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=mn] {_httpimg_/mn/tlanggr.gif}
+_httpicontlangon_ [l=mn] {_httpimg_/mn/tlangon.gif}
+_httpicontlangof_ [l=mn] {_httpimg_/mn/tlangof.gif}
+## "Ñ
+ÑÐ»Ò¯Ò¯ÐŽ" ## green_title ## h_lang ##
+_httpiconhlang_ [l=mn] {_httpimg_/mn/h\_lang.gif}
+_widthhlang_ [l=mn] {200}
+_heighthlang_ [l=mn] {57}
+## "taal" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=nl] {_httpimg_/nl/tlanggr.gif}
+_httpicontlangon_ [l=nl] {_httpimg_/nl/tlangon.gif}
+_httpicontlangof_ [l=nl] {_httpimg_/nl/tlangof.gif}
+## "taalen" ## green_title ## h_lang ##
+_httpiconhlang_ [l=nl] {_httpimg_/nl/h\_lang.gif}
+_widthhlang_ [l=nl] {200}
+_heighthlang_ [l=nl] {57}
+## "jÄzyki" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=pl] {_httpimg_/pl/tlanggr.gif}
+_httpicontlangon_ [l=pl] {_httpimg_/pl/tlangon.gif}
+_httpicontlangof_ [l=pl] {_httpimg_/pl/tlangof.gif}
+## "jÄzyki" ## green_title ## h_lang ##
+_httpiconhlang_ [l=pl] {_httpimg_/pl/h\_lang.gif}
+_widthhlang_ [l=pl] {200}
+_heighthlang_ [l=pl] {57}
+## "lÃ­ngua" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=pt-pt] {_httpimg_/pt-pt/tlanggr.gif}
+_httpicontlangon_ [l=pt-pt] {_httpimg_/pt-pt/tlangon.gif}
+_httpicontlangof_ [l=pt-pt] {_httpimg_/pt-pt/tlangof.gif}
+## "lÃ­nguas" ## green_title ## h_lang ##
+_httpiconhlang_ [l=pt-pt] {_httpimg_/pt-pt/h\_lang.gif}
+_widthhlang_ [l=pt-pt] {200}
+_heighthlang_ [l=pt-pt] {57}
+## "ÐœÐ°Ð·Ð²Ð°ÐœÐžÑ" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=ru] {_httpimg_/ru/tlanggr.gif}
+_httpicontlangon_ [l=ru] {_httpimg_/ru/tlangon.gif}
+_httpicontlangof_ [l=ru] {_httpimg_/ru/tlangof.gif}
+## "ÑÐ·ÑÐºÐž" ## green_title ## h_lang ##
+_httpiconhlang_ [l=ru] {_httpimg_/ru/h\_lang.gif}
+_widthhlang_ [l=ru] {200}
+_heighthlang_ [l=ru] {57}
+## "jezik" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=sr] {_httpimg_/sr/tlanggr.gif}
+_httpicontlangon_ [l=sr] {_httpimg_/sr/tlangon.gif}
+_httpicontlangof_ [l=sr] {_httpimg_/sr/tlangof.gif}
+## "jezici" ## green_title ## h_lang ##
+_httpiconhlang_ [l=sr] {_httpimg_/sr/h\_lang.gif}
+_widthhlang_ [l=sr] {200}
+_heighthlang_ [l=sr] {57}
+## "àž àž²àž©àž²" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=th] {_httpimg_/th/tlanggr.gif}
+_httpicontlangon_ [l=th] {_httpimg_/th/tlangon.gif}
+_httpicontlangof_ [l=th] {_httpimg_/th/tlangof.gif}
+## "àž àž²àž©àž²" ## green_title ## h_lang ##
+_httpiconhlang_ [l=th] {_httpimg_/th/h\_lang.gif}
+_widthhlang_ [l=th] {200}
+_heighthlang_ [l=th] {57}
+## "dil" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=tr] {_httpimg_/tr/tlanggr.gif}
+_httpicontlangon_ [l=tr] {_httpimg_/tr/tlangon.gif}
+_httpicontlangof_ [l=tr] {_httpimg_/tr/tlangof.gif}
+## "diller" ## green_title ## h_lang ##
+_httpiconhlang_ [l=tr] {_httpimg_/tr/h\_lang.gif}
+_widthhlang_ [l=tr] {200}
+_heighthlang_ [l=tr] {57}
+## "ÐŒÐŸÐ²Ð°" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=uk] {_httpimg_/uk/tlanggr.gif}
+_httpicontlangon_ [l=uk] {_httpimg_/uk/tlangon.gif}
+_httpicontlangof_ [l=uk] {_httpimg_/uk/tlangof.gif}
+## "ÐŒÐŸÐ²Ðž" ## green_title ## h_lang ##
+_httpiconhlang_ [l=uk] {_httpimg_/uk/h\_lang.gif}
+_widthhlang_ [l=uk] {200}
+_heighthlang_ [l=uk] {57}
+## "ngÃŽn ngá»¯" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=vi] {_httpimg_/vi/tlanggr.gif}
+_httpicontlangon_ [l=vi] {_httpimg_/vi/tlangon.gif}
+_httpicontlangof_ [l=vi] {_httpimg_/vi/tlangof.gif}
+## "ngÃŽn ngá»¯" ## green_title ## h_lang ##
+_httpiconhlang_ [l=vi] {_httpimg_/vi/h\_lang.gif}
+_widthhlang_ [l=vi] {200}
+_heighthlang_ [l=vi] {57}
+## "è¯­èš" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=zh] {_httpimg_/zh/tlanggr.gif}
+_httpicontlangon_ [l=zh] {_httpimg_/zh/tlangon.gif}
+_httpicontlangof_ [l=zh] {_httpimg_/zh/tlangof.gif}
+## "è¯­èš" ## green_title ## h_lang ##
+_httpiconhlang_ [l=zh] {_httpimg_/zh/h\_lang.gif}
+_widthhlang_ [l=zh] {200}
+_heighthlang_ [l=zh] {57}
+## "èªèš" ## nav_bar_button ## tlang ##
+_httpicontlanggr_ [l=zh-tr] {_httpimg_/zh-tr/tlanggr.gif}
+_httpicontlangon_ [l=zh-tr] {_httpimg_/zh-tr/tlangon.gif}
+_httpicontlangof_ [l=zh-tr] {_httpimg_/zh-tr/tlangof.gif}
+## "èªèš" ## green_title ## h_lang ##
+_httpiconhlang_ [l=zh-tr] {_httpimg_/zh-tr/h\_lang.gif}
+_widthhlang_ [l=zh-tr] {200}
+_heighthlang_ [l=zh-tr] {57}
+
+## "organisations" ## nav_bar_button ## torg ##
+_httpicontorggr_ {_httpimg_/en/torggr.gif}
+_httpicontorgon_ {_httpimg_/en/torgon.gif}
+_httpicontorgof_ {_httpimg_/en/torgof.gif}
+## "organization" ## green_title ## h_org ##
+_httpiconhorg_ {_httpimg_/en/h\_org.gif}
+_widthhorg_ {200}
+_heighthorg_ {57}
+## "Ø§ÙÙÙØŠØ§Øª" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=ar] {_httpimg_/ar/torggr.gif}
+_httpicontorgon_ [l=ar] {_httpimg_/ar/torgon.gif}
+_httpicontorgof_ [l=ar] {_httpimg_/ar/torgof.gif}
+## "Ø§ÙÙÙØŠØ©" ## green_title ## h_org ##
+_httpiconhorg_ [l=ar] {_httpimg_/ar/h\_org.gif}
+_widthhorg_ [l=ar] {250}
+_heighthorg_ [l=ar] {57}
+## "àŠžàŠàŠàŠ àŠš / àŠžàŠàŠžà§àŠ¥àŠŸ" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=bn] {_httpimg_/bn/torggr.gif}
+_httpicontorgon_ [l=bn] {_httpimg_/bn/torgon.gif}
+_httpicontorgof_ [l=bn] {_httpimg_/bn/torgof.gif}
+## "àŠžàŠàŠàŠ àŠš / àŠžàŠàŠžà§àŠ¥àŠŸ" ## green_title ## h_org ##
+_httpiconhorg_ [l=bn] {_httpimg_/bn/h\_org.gif}
+_widthhorg_ [l=bn] {200}
+_heighthorg_ [l=bn] {57}
+## "organitzacions" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=ca] {_httpimg_/ca/torggr.gif}
+_httpicontorgon_ [l=ca] {_httpimg_/ca/torgon.gif}
+_httpicontorgof_ [l=ca] {_httpimg_/ca/torgof.gif}
+## "organitzaciÃ³" ## green_title ## h_org ##
+_httpiconhorg_ [l=ca] {_httpimg_/ca/h\_org.gif}
+_widthhorg_ [l=ca] {200}
+_heighthorg_ [l=ca] {57}
+## "organizace" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=cs] {_httpimg_/cs/torggr.gif}
+_httpicontorgon_ [l=cs] {_httpimg_/cs/torgon.gif}
+_httpicontorgof_ [l=cs] {_httpimg_/cs/torgof.gif}
+## "organizace" ## green_title ## h_org ##
+_httpiconhorg_ [l=cs] {_httpimg_/cs/h\_org.gif}
+_widthhorg_ [l=cs] {250}
+_heighthorg_ [l=cs] {57}
+## "organisation" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=de] {_httpimg_/de/torggr.gif}
+_httpicontorgon_ [l=de] {_httpimg_/de/torgon.gif}
+_httpicontorgof_ [l=de] {_httpimg_/de/torgof.gif}
+## "organisation" ## green_title ## h_org ##
+_httpiconhorg_ [l=de] {_httpimg_/de/h\_org.gif}
+_widthhorg_ [l=de] {250}
+_heighthorg_ [l=de] {57}
+## "Î¿ÏÎ³Î±ÎœÎ¹ÏÎŒÎ¿Î¯" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=el] {_httpimg_/el/torggr.gif}
+_httpicontorgon_ [l=el] {_httpimg_/el/torgon.gif}
+_httpicontorgof_ [l=el] {_httpimg_/el/torgof.gif}
+## "Î¿ÏÎ³Î±ÎœÎ¹ÏÎŒÏÏ" ## green_title ## h_org ##
+_httpiconhorg_ [l=el] {_httpimg_/el/h\_org.gif}
+_widthhorg_ [l=el] {250}
+_heighthorg_ [l=el] {57}
+## "organizaciÃ³n" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=es] {_httpimg_/es/torggr.gif}
+_httpicontorgon_ [l=es] {_httpimg_/es/torgon.gif}
+_httpicontorgof_ [l=es] {_httpimg_/es/torgof.gif}
+## "organizaciÃ³n" ## green_title ## h_org ##
+_httpiconhorg_ [l=es] {_httpimg_/es/h\_org.gif}
+_widthhorg_ [l=es] {200}
+_heighthorg_ [l=es] {57}
+## "Ø³Ø§Ø²Ù
+Ø§ÙÙØ§" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=fa] {_httpimg_/fa/torggr.gif}
+_httpicontorgon_ [l=fa] {_httpimg_/fa/torgon.gif}
+_httpicontorgof_ [l=fa] {_httpimg_/fa/torgof.gif}
+## "Ø³Ø§Ø²Ù
+Ø§Ù" ## green_title ## h_org ##
+_httpiconhorg_ [l=fa] {_httpimg_/fa/h\_org.gif}
+_widthhorg_ [l=fa] {250}
+_heighthorg_ [l=fa] {57}
+## "organisaatiot" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=fi] {_httpimg_/fi/torggr.gif}
+_httpicontorgon_ [l=fi] {_httpimg_/fi/torgon.gif}
+_httpicontorgof_ [l=fi] {_httpimg_/fi/torgof.gif}
+## "organisaatio" ## green_title ## h_org ##
+_httpiconhorg_ [l=fi] {_httpimg_/fi/h\_org.gif}
+_widthhorg_ [l=fi] {250}
+_heighthorg_ [l=fi] {57}
+## "organisation" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=fr] {_httpimg_/fr/torggr.gif}
+_httpicontorgon_ [l=fr] {_httpimg_/fr/torgon.gif}
+_httpicontorgof_ [l=fr] {_httpimg_/fr/torgof.gif}
+## "organisation" ## green_title ## h_org ##
+_httpiconhorg_ [l=fr] {_httpimg_/fr/h\_org.gif}
+_widthhorg_ [l=fr] {200}
+_heighthorg_ [l=fr] {57}
+## "organizaciÃ³ns" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=gl] {_httpimg_/gl/torggr.gif}
+_httpicontorgon_ [l=gl] {_httpimg_/gl/torgon.gif}
+_httpicontorgof_ [l=gl] {_httpimg_/gl/torgof.gif}
+## "organizacion" ## green_title ## h_org ##
+_httpiconhorg_ [l=gl] {_httpimg_/gl/h\_org.gif}
+_widthhorg_ [l=gl] {250}
+_heighthorg_ [l=gl] {57}
+## "××××š×" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=he] {_httpimg_/he/torggr.gif}
+_httpicontorgon_ [l=he] {_httpimg_/he/torgon.gif}
+_httpicontorgof_ [l=he] {_httpimg_/he/torgof.gif}
+## "××××š×" ## green_title ## h_org ##
+_httpiconhorg_ [l=he] {_httpimg_/he/h\_org.gif}
+_widthhorg_ [l=he] {250}
+_heighthorg_ [l=he] {57}
+## "organizacije" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=hr] {_httpimg_/hr/torggr.gif}
+_httpicontorgon_ [l=hr] {_httpimg_/hr/torgon.gif}
+_httpicontorgof_ [l=hr] {_httpimg_/hr/torgof.gif}
+## "organizacije" ## green_title ## h_org ##
+_httpiconhorg_ [l=hr] {_httpimg_/hr/h\_org.gif}
+_widthhorg_ [l=hr] {250}
+_heighthorg_ [l=hr] {57}
+## "Õ¯Õ¡ÕŠÕŽÕ¡Õ¯Õ¥ÖÕºÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=hy] {_httpimg_/hy/torggr.gif}
+_httpicontorgon_ [l=hy] {_httpimg_/hy/torgon.gif}
+_httpicontorgof_ [l=hy] {_httpimg_/hy/torgof.gif}
+## "Õ¯Õ¡ÕŠÕŽÕ¡Õ¯Õ¥ÖÕºÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö" ## green_title ## h_org ##
+_httpiconhorg_ [l=hy] {_httpimg_/hy/h\_org.gif}
+_widthhorg_ [l=hy] {250}
+_heighthorg_ [l=hy] {57}
+## "organisasi" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=id] {_httpimg_/id/torggr.gif}
+_httpicontorgon_ [l=id] {_httpimg_/id/torgon.gif}
+_httpicontorgof_ [l=id] {_httpimg_/id/torgof.gif}
+## "organisasi" ## green_title ## h_org ##
+_httpiconhorg_ [l=id] {_httpimg_/id/h\_org.gif}
+_widthhorg_ [l=id] {200}
+_heighthorg_ [l=id] {57}
+## "organizzazione" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=it] {_httpimg_/it/torggr.gif}
+_httpicontorgon_ [l=it] {_httpimg_/it/torgon.gif}
+_httpicontorgof_ [l=it] {_httpimg_/it/torgof.gif}
+## "organizzazione" ## green_title ## h_org ##
+_httpiconhorg_ [l=it] {_httpimg_/it/h\_org.gif}
+_widthhorg_ [l=it] {250}
+_heighthorg_ [l=it] {57}
+## "çµç¹" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=ja] {_httpimg_/ja/torggr.gif}
+_httpicontorgon_ [l=ja] {_httpimg_/ja/torgon.gif}
+_httpicontorgof_ [l=ja] {_httpimg_/ja/torgof.gif}
+## "áá áááááááªáááá" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=ka] {_httpimg_/ka/torggr.gif}
+_httpicontorgon_ [l=ka] {_httpimg_/ka/torgon.gif}
+_httpicontorgof_ [l=ka] {_httpimg_/ka/torgof.gif}
+## "áá áááááááªáá" ## green_title ## h_org ##
+_httpiconhorg_ [l=ka] {_httpimg_/ka/h\_org.gif}
+_widthhorg_ [l=ka] {258}
+_heighthorg_ [l=ka] {74}
+## "Ò±Ð¹ÑÐŒÐŽÐ°Ñ" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=kk] {_httpimg_/kk/torggr.gif}
+_httpicontorgon_ [l=kk] {_httpimg_/kk/torgon.gif}
+_httpicontorgof_ [l=kk] {_httpimg_/kk/torgof.gif}
+## "Ò±Ð¹ÑÐŒÐŽÐ°Ñ" ## green_title ## h_org ##
+_httpiconhorg_ [l=kk] {_httpimg_/kk/h\_org.gif}
+_widthhorg_ [l=kk] {250}
+_heighthorg_ [l=kk] {57}
+## "ÑÑÐŒÐŽÐ°Ñ" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=ky] {_httpimg_/ky/torggr.gif}
+_httpicontorgon_ [l=ky] {_httpimg_/ky/torgon.gif}
+_httpicontorgof_ [l=ky] {_httpimg_/ky/torgof.gif}
+## "ÑÑÐŒÐŽÐ°Ñ" ## green_title ## h_org ##
+_httpiconhorg_ [l=ky] {_httpimg_/ky/h\_org.gif}
+_widthhorg_ [l=ky] {200}
+_heighthorg_ [l=ky] {57}
+## "organizÄcijas" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=lv] {_httpimg_/lv/torggr.gif}
+_httpicontorgon_ [l=lv] {_httpimg_/lv/torgon.gif}
+_httpicontorgof_ [l=lv] {_httpimg_/lv/torgof.gif}
+## "organizÄcija" ## green_title ## h_org ##
+_httpiconhorg_ [l=lv] {_httpimg_/lv/h\_org.gif}
+_widthhorg_ [l=lv] {200}
+_heighthorg_ [l=lv] {57}
+## "rÅpÅ«" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=mi] {_httpimg_/mi/torggr.gif}
+_httpicontorgon_ [l=mi] {_httpimg_/mi/torgon.gif}
+_httpicontorgof_ [l=mi] {_httpimg_/mi/torgof.gif}
+## "rÅpÅ«" ## green_title ## h_org ##
+_httpiconhorg_ [l=mi] {_httpimg_/mi/h\_org.gif}
+_widthhorg_ [l=mi] {250}
+_heighthorg_ [l=mi] {57}
+## "Ð±Ð°Ð¹Ð³ÑÑÐ»Ð»Ð°Ð³ÑÑÐŽ" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=mn] {_httpimg_/mn/torggr.gif}
+_httpicontorgon_ [l=mn] {_httpimg_/mn/torgon.gif}
+_httpicontorgof_ [l=mn] {_httpimg_/mn/torgof.gif}
+## "Ð±Ð°Ð¹Ð³ÑÑÐ»Ð»Ð°Ð³ÑÑÐŽ" ## green_title ## h_org ##
+_httpiconhorg_ [l=mn] {_httpimg_/mn/h\_org.gif}
+_widthhorg_ [l=mn] {200}
+_heighthorg_ [l=mn] {57}
+## "organisatie" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=nl] {_httpimg_/nl/torggr.gif}
+_httpicontorgon_ [l=nl] {_httpimg_/nl/torgon.gif}
+_httpicontorgof_ [l=nl] {_httpimg_/nl/torgof.gif}
+## "organisaties" ## green_title ## h_org ##
+_httpiconhorg_ [l=nl] {_httpimg_/nl/h\_org.gif}
+_widthhorg_ [l=nl] {250}
+_heighthorg_ [l=nl] {57}
+## "organizacje" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=pl] {_httpimg_/pl/torggr.gif}
+_httpicontorgon_ [l=pl] {_httpimg_/pl/torgon.gif}
+_httpicontorgof_ [l=pl] {_httpimg_/pl/torgof.gif}
+## "organizacja" ## green_title ## h_org ##
+_httpiconhorg_ [l=pl] {_httpimg_/pl/h\_org.gif}
+_widthhorg_ [l=pl] {200}
+_heighthorg_ [l=pl] {57}
+## "organizaÃ§Ã£o" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=pt-br] {_httpimg_/pt-br/torggr.gif}
+_httpicontorgon_ [l=pt-br] {_httpimg_/pt-br/torgon.gif}
+_httpicontorgof_ [l=pt-br] {_httpimg_/pt-br/torgof.gif}
+## "organizaÃ§Ã£o" ## green_title ## h_org ##
+_httpiconhorg_ [l=pt-br] {_httpimg_/pt-br/h\_org.gif}
+_widthhorg_ [l=pt-br] {250}
+_heighthorg_ [l=pt-br] {57}
+## "organizaÃ§Ãµes" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=pt-pt] {_httpimg_/pt-pt/torggr.gif}
+_httpicontorgon_ [l=pt-pt] {_httpimg_/pt-pt/torgon.gif}
+_httpicontorgof_ [l=pt-pt] {_httpimg_/pt-pt/torgof.gif}
+## "organizaÃ§Ã£o" ## green_title ## h_org ##
+_httpiconhorg_ [l=pt-pt] {_httpimg_/pt-pt/h\_org.gif}
+_widthhorg_ [l=pt-pt] {250}
+_heighthorg_ [l=pt-pt] {57}
+## "ÐŸÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÐž" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=ru] {_httpimg_/ru/torggr.gif}
+_httpicontorgon_ [l=ru] {_httpimg_/ru/torgon.gif}
+_httpicontorgof_ [l=ru] {_httpimg_/ru/torgof.gif}
+## "ÐŸÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÐž" ## green_title ## h_org ##
+_httpiconhorg_ [l=ru] {_httpimg_/ru/h\_org.gif}
+_widthhorg_ [l=ru] {200}
+_heighthorg_ [l=ru] {57}
+## "organizacije" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=sr] {_httpimg_/sr/torggr.gif}
+_httpicontorgon_ [l=sr] {_httpimg_/sr/torgon.gif}
+_httpicontorgof_ [l=sr] {_httpimg_/sr/torgof.gif}
+## "organizacija" ## green_title ## h_org ##
+_httpiconhorg_ [l=sr] {_httpimg_/sr/h\_org.gif}
+_widthhorg_ [l=sr] {250}
+_heighthorg_ [l=sr] {57}
+## "àž­àžàžà¹àžàž£" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=th] {_httpimg_/th/torggr.gif}
+_httpicontorgon_ [l=th] {_httpimg_/th/torgon.gif}
+_httpicontorgof_ [l=th] {_httpimg_/th/torgof.gif}
+## "àž­àžàžà¹àžàž£" ## green_title ## h_org ##
+_httpiconhorg_ [l=th] {_httpimg_/th/h\_org.gif}
+_widthhorg_ [l=th] {250}
+_heighthorg_ [l=th] {57}
+## "kurumlar" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=tr] {_httpimg_/tr/torggr.gif}
+_httpicontorgon_ [l=tr] {_httpimg_/tr/torgon.gif}
+_httpicontorgof_ [l=tr] {_httpimg_/tr/torgof.gif}
+## "kurum" ## green_title ## h_org ##
+_httpiconhorg_ [l=tr] {_httpimg_/tr/h\_org.gif}
+_widthhorg_ [l=tr] {250}
+_heighthorg_ [l=tr] {57}
+## "ÐŸÑÐ³Ð°ÐœÑÐ·Ð°ÑÑÑ" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=uk] {_httpimg_/uk/torggr.gif}
+_httpicontorgon_ [l=uk] {_httpimg_/uk/torgon.gif}
+_httpicontorgof_ [l=uk] {_httpimg_/uk/torgof.gif}
+## "ÐŸÑÐ³Ð°ÐœÑÐ·Ð°ÑÑÑ" ## green_title ## h_org ##
+_httpiconhorg_ [l=uk] {_httpimg_/uk/h\_org.gif}
+_widthhorg_ [l=uk] {250}
+_heighthorg_ [l=uk] {57}
+## "tá» chá»©c" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=vi] {_httpimg_/vi/torggr.gif}
+_httpicontorgon_ [l=vi] {_httpimg_/vi/torgon.gif}
+_httpicontorgof_ [l=vi] {_httpimg_/vi/torgof.gif}
+## "tá» chá»©c" ## green_title ## h_org ##
+_httpiconhorg_ [l=vi] {_httpimg_/vi/h\_org.gif}
+_widthhorg_ [l=vi] {250}
+_heighthorg_ [l=vi] {57}
+## "ç»ç»" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=zh] {_httpimg_/zh/torggr.gif}
+_httpicontorgon_ [l=zh] {_httpimg_/zh/torgon.gif}
+_httpicontorgof_ [l=zh] {_httpimg_/zh/torgof.gif}
+## "ç»ç»" ## green_title ## h_org ##
+_httpiconhorg_ [l=zh] {_httpimg_/zh/h\_org.gif}
+_widthhorg_ [l=zh] {250}
+_heighthorg_ [l=zh] {57}
+## "çµç¹" ## nav_bar_button ## torg ##
+_httpicontorggr_ [l=zh-tr] {_httpimg_/zh-tr/torggr.gif}
+_httpicontorgon_ [l=zh-tr] {_httpimg_/zh-tr/torgon.gif}
+_httpicontorgof_ [l=zh-tr] {_httpimg_/zh-tr/torgof.gif}
+## "çµç¹" ## green_title ## h_org ##
+_httpiconhorg_ [l=zh-tr] {_httpimg_/zh-tr/h\_org.gif}
+_widthhorg_ [l=zh-tr] {200}
+_heighthorg_ [l=zh-tr] {57}
+
+## "people" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ {_httpimg_/en/tpeopgr.gif}
+_httpicontpeopof_ {_httpimg_/en/tpeopof.gif}
+_httpicontpeopon_ {_httpimg_/en/tpeopon.gif}
+## "Ø§ÙØ£ÙØ±Ø§Ø¯" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=ar] {_httpimg_/ar/tpeopgr.gif}
+_httpicontpeopof_ [l=ar] {_httpimg_/ar/tpeopof.gif}
+_httpicontpeopon_ [l=ar] {_httpimg_/ar/tpeopon.gif}
+## "àŠ®àŠŸàŠšà§àŠ·àŠàŠš" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=bn] {_httpimg_/bn/tpeopgr.gif}
+_httpicontpeopof_ [l=bn] {_httpimg_/bn/tpeopof.gif}
+_httpicontpeopon_ [l=bn] {_httpimg_/bn/tpeopon.gif}
+## "persones" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=ca] {_httpimg_/ca/tpeopgr.gif}
+_httpicontpeopof_ [l=ca] {_httpimg_/ca/tpeopof.gif}
+_httpicontpeopon_ [l=ca] {_httpimg_/ca/tpeopon.gif}
+## "lidÃ©" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=cs] {_httpimg_/cs/tpeopgr.gif}
+_httpicontpeopof_ [l=cs] {_httpimg_/cs/tpeopof.gif}
+_httpicontpeopon_ [l=cs] {_httpimg_/cs/tpeopon.gif}
+## "personen" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=de] {_httpimg_/de/tpeopgr.gif}
+_httpicontpeopof_ [l=de] {_httpimg_/de/tpeopof.gif}
+_httpicontpeopon_ [l=de] {_httpimg_/de/tpeopon.gif}
+## "Î¬ÎœÎžÏÏÏÎ¿Î¹" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=el] {_httpimg_/el/tpeopgr.gif}
+_httpicontpeopof_ [l=el] {_httpimg_/el/tpeopof.gif}
+_httpicontpeopon_ [l=el] {_httpimg_/el/tpeopon.gif}
+## "personas" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=es] {_httpimg_/es/tpeopgr.gif}
+_httpicontpeopof_ [l=es] {_httpimg_/es/tpeopof.gif}
+_httpicontpeopon_ [l=es] {_httpimg_/es/tpeopon.gif}
+## "Ø§ÙØ±Ø§Ø¯" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=fa] {_httpimg_/fa/tpeopgr.gif}
+_httpicontpeopof_ [l=fa] {_httpimg_/fa/tpeopof.gif}
+_httpicontpeopon_ [l=fa] {_httpimg_/fa/tpeopon.gif}
+## "henkilÃ¶t" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=fi] {_httpimg_/fi/tpeopgr.gif}
+_httpicontpeopof_ [l=fi] {_httpimg_/fi/tpeopof.gif}
+_httpicontpeopon_ [l=fi] {_httpimg_/fi/tpeopon.gif}
+## "personnes" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=fr] {_httpimg_/fr/tpeopgr.gif}
+_httpicontpeopof_ [l=fr] {_httpimg_/fr/tpeopof.gif}
+_httpicontpeopon_ [l=fr] {_httpimg_/fr/tpeopon.gif}
+## "persoas" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=gl] {_httpimg_/gl/tpeopgr.gif}
+_httpicontpeopof_ [l=gl] {_httpimg_/gl/tpeopof.gif}
+_httpicontpeopon_ [l=gl] {_httpimg_/gl/tpeopon.gif}
+## "×××©× ×" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=he] {_httpimg_/he/tpeopgr.gif}
+_httpicontpeopof_ [l=he] {_httpimg_/he/tpeopof.gif}
+_httpicontpeopon_ [l=he] {_httpimg_/he/tpeopon.gif}
+## "osobe" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=hr] {_httpimg_/hr/tpeopgr.gif}
+_httpicontpeopof_ [l=hr] {_httpimg_/hr/tpeopof.gif}
+_httpicontpeopon_ [l=hr] {_httpimg_/hr/tpeopon.gif}
+## "ÕŽÕ¡ÖÕ€Õ«Õ¯" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=hy] {_httpimg_/hy/tpeopgr.gif}
+_httpicontpeopof_ [l=hy] {_httpimg_/hy/tpeopof.gif}
+_httpicontpeopon_ [l=hy] {_httpimg_/hy/tpeopon.gif}
+## "orang" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=id] {_httpimg_/id/tpeopgr.gif}
+_httpicontpeopof_ [l=id] {_httpimg_/id/tpeopof.gif}
+_httpicontpeopon_ [l=id] {_httpimg_/id/tpeopon.gif}
+## "persone" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=it] {_httpimg_/it/tpeopgr.gif}
+_httpicontpeopof_ [l=it] {_httpimg_/it/tpeopof.gif}
+_httpicontpeopon_ [l=it] {_httpimg_/it/tpeopon.gif}
+## "äººã
+" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=ja] {_httpimg_/ja/tpeopgr.gif}
+_httpicontpeopof_ [l=ja] {_httpimg_/ja/tpeopof.gif}
+_httpicontpeopon_ [l=ja] {_httpimg_/ja/tpeopon.gif}
+## "ááá á¡áááááá ááááááá¡ á¡á®ááááá" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=ka] {_httpimg_/ka/tpeopgr.gif}
+_httpicontpeopof_ [l=ka] {_httpimg_/ka/tpeopof.gif}
+_httpicontpeopon_ [l=ka] {_httpimg_/ka/tpeopon.gif}
+## "Ð¿ÐµÑÑÐŸÐœÐ°Ð»ÐžÐ»ÐµÑ" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=kk] {_httpimg_/kk/tpeopgr.gif}
+_httpicontpeopof_ [l=kk] {_httpimg_/kk/tpeopof.gif}
+_httpicontpeopon_ [l=kk] {_httpimg_/kk/tpeopon.gif}
+## "Ð¿ÐµÑÑÐŸÐœÐ°Ð»ÐžÐ¹Ð»ÐµÑ" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=ky] {_httpimg_/ky/tpeopgr.gif}
+_httpicontpeopof_ [l=ky] {_httpimg_/ky/tpeopof.gif}
+_httpicontpeopon_ [l=ky] {_httpimg_/ky/tpeopon.gif}
+## "cilvÄki" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=lv] {_httpimg_/lv/tpeopgr.gif}
+_httpicontpeopof_ [l=lv] {_httpimg_/lv/tpeopof.gif}
+_httpicontpeopon_ [l=lv] {_httpimg_/lv/tpeopon.gif}
+## "tÄngata" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=mi] {_httpimg_/mi/tpeopgr.gif}
+_httpicontpeopof_ [l=mi] {_httpimg_/mi/tpeopof.gif}
+_httpicontpeopon_ [l=mi] {_httpimg_/mi/tpeopon.gif}
+## "Ñ
+Ò¯ÐŒÒ¯Ò¯Ñ" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=mn] {_httpimg_/mn/tpeopgr.gif}
+_httpicontpeopof_ [l=mn] {_httpimg_/mn/tpeopof.gif}
+_httpicontpeopon_ [l=mn] {_httpimg_/mn/tpeopon.gif}
+## "personen" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=nl] {_httpimg_/nl/tpeopgr.gif}
+_httpicontpeopof_ [l=nl] {_httpimg_/nl/tpeopof.gif}
+_httpicontpeopon_ [l=nl] {_httpimg_/nl/tpeopon.gif}
+## "osoby" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=pl] {_httpimg_/pl/tpeopgr.gif}
+_httpicontpeopof_ [l=pl] {_httpimg_/pl/tpeopof.gif}
+_httpicontpeopon_ [l=pl] {_httpimg_/pl/tpeopon.gif}
+## "pessoas" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=pt-br] {_httpimg_/pt-br/tpeopgr.gif}
+_httpicontpeopof_ [l=pt-br] {_httpimg_/pt-br/tpeopof.gif}
+_httpicontpeopon_ [l=pt-br] {_httpimg_/pt-br/tpeopon.gif}
+## "pessoas" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=pt-pt] {_httpimg_/pt-pt/tpeopgr.gif}
+_httpicontpeopof_ [l=pt-pt] {_httpimg_/pt-pt/tpeopof.gif}
+_httpicontpeopon_ [l=pt-pt] {_httpimg_/pt-pt/tpeopon.gif}
+## "Ð¿ÐµÑÑÐŸÐœÐ°Ð»ÐžÐž" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=ru] {_httpimg_/ru/tpeopgr.gif}
+_httpicontpeopof_ [l=ru] {_httpimg_/ru/tpeopof.gif}
+_httpicontpeopon_ [l=ru] {_httpimg_/ru/tpeopon.gif}
+## "ljudi" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=sr] {_httpimg_/sr/tpeopgr.gif}
+_httpicontpeopof_ [l=sr] {_httpimg_/sr/tpeopof.gif}
+_httpicontpeopon_ [l=sr] {_httpimg_/sr/tpeopon.gif}
+## "àžàž" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=th] {_httpimg_/th/tpeopgr.gif}
+_httpicontpeopof_ [l=th] {_httpimg_/th/tpeopof.gif}
+_httpicontpeopon_ [l=th] {_httpimg_/th/tpeopon.gif}
+## "kiÅiler" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=tr] {_httpimg_/tr/tpeopgr.gif}
+_httpicontpeopof_ [l=tr] {_httpimg_/tr/tpeopof.gif}
+_httpicontpeopon_ [l=tr] {_httpimg_/tr/tpeopon.gif}
+## "Ð»ÑÐŽÐž" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=uk] {_httpimg_/uk/tpeopgr.gif}
+_httpicontpeopof_ [l=uk] {_httpimg_/uk/tpeopof.gif}
+_httpicontpeopon_ [l=uk] {_httpimg_/uk/tpeopon.gif}
+## "ngÆ°á»i" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=vi] {_httpimg_/vi/tpeopgr.gif}
+_httpicontpeopof_ [l=vi] {_httpimg_/vi/tpeopof.gif}
+_httpicontpeopon_ [l=vi] {_httpimg_/vi/tpeopon.gif}
+## "äººå" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=zh] {_httpimg_/zh/tpeopgr.gif}
+_httpicontpeopof_ [l=zh] {_httpimg_/zh/tpeopof.gif}
+_httpicontpeopon_ [l=zh] {_httpimg_/zh/tpeopon.gif}
+## "äººå" ## nav_bar_button ## tpeop ##
+_httpicontpeopgr_ [l=zh-tr] {_httpimg_/zh-tr/tpeopgr.gif}
+_httpicontpeopof_ [l=zh-tr] {_httpimg_/zh-tr/tpeopof.gif}
+_httpicontpeopon_ [l=zh-tr] {_httpimg_/zh-tr/tpeopon.gif}
+
+## "people" ## green_title ## h_people ##
+_httpiconhpeople_ {_httpimg_/en/h\_people.gif}
+_widthhpeople_ {200}
+_heighthpeople_ {57}
+## "Ø§ÙØ£ÙØ±Ø§Ø¯" ## green_title ## h_people ##
+_httpiconhpeople_ [l=ar] {_httpimg_/ar/h\_people.gif}
+_widthhpeople_ [l=ar] {200}
+_heighthpeople_ [l=ar] {57}
+## "àŠ®àŠŸàŠšà§àŠ·àŠàŠš" ## green_title ## h_people ##
+_httpiconhpeople_ [l=bn] {_httpimg_/bn/h\_people.gif}
+_widthhpeople_ [l=bn] {200}
+_heighthpeople_ [l=bn] {57}
+## "persones" ## green_title ## h_people ##
+_httpiconhpeople_ [l=ca] {_httpimg_/ca/h\_people.gif}
+_widthhpeople_ [l=ca] {200}
+_heighthpeople_ [l=ca] {57}
+## "lidÃ©" ## green_title ## h_people ##
+_httpiconhpeople_ [l=cs] {_httpimg_/cs/h\_people.gif}
+_widthhpeople_ [l=cs] {200}
+_heighthpeople_ [l=cs] {57}
+## "personen" ## green_title ## h_people ##
+_httpiconhpeople_ [l=de] {_httpimg_/de/h\_people.gif}
+_widthhpeople_ [l=de] {200}
+_heighthpeople_ [l=de] {57}
+## "Î¬ÎœÎžÏÏÏÎ¿Î¹" ## green_title ## h_people ##
+_httpiconhpeople_ [l=el] {_httpimg_/el/h\_people.gif}
+_widthhpeople_ [l=el] {200}
+_heighthpeople_ [l=el] {57}
+## "personas" ## green_title ## h_people ##
+_httpiconhpeople_ [l=es] {_httpimg_/es/h\_people.gif}
+_widthhpeople_ [l=es] {200}
+_heighthpeople_ [l=es] {57}
+## "Ø§ÙØ±Ø§Ø¯" ## green_title ## h_people ##
+_httpiconhpeople_ [l=fa] {_httpimg_/fa/h\_people.gif}
+_widthhpeople_ [l=fa] {200}
+_heighthpeople_ [l=fa] {57}
+## "henkilÃ¶t" ## green_title ## h_people ##
+_httpiconhpeople_ [l=fi] {_httpimg_/fi/h\_people.gif}
+_widthhpeople_ [l=fi] {200}
+_heighthpeople_ [l=fi] {57}
+## "personnes" ## green_title ## h_people ##
+_httpiconhpeople_ [l=fr] {_httpimg_/fr/h\_people.gif}
+_widthhpeople_ [l=fr] {200}
+_heighthpeople_ [l=fr] {57}
+## "persoas" ## green_title ## h_people ##
+_httpiconhpeople_ [l=gl] {_httpimg_/gl/h\_people.gif}
+_widthhpeople_ [l=gl] {200}
+_heighthpeople_ [l=gl] {57}
+## "×××©× ×" ## green_title ## h_people ##
+_httpiconhpeople_ [l=he] {_httpimg_/he/h\_people.gif}
+_widthhpeople_ [l=he] {200}
+_heighthpeople_ [l=he] {57}
+## "ljudi" ## green_title ## h_people ##
+_httpiconhpeople_ [l=hr] {_httpimg_/hr/h\_people.gif}
+_widthhpeople_ [l=hr] {200}
+_heighthpeople_ [l=hr] {57}
+## "ÕŽÕ¡ÖÕ€Õ«Õ¯" ## green_title ## h_people ##
+_httpiconhpeople_ [l=hy] {_httpimg_/hy/h\_people.gif}
+_widthhpeople_ [l=hy] {200}
+_heighthpeople_ [l=hy] {57}
+## "orang" ## green_title ## h_people ##
+_httpiconhpeople_ [l=id] {_httpimg_/id/h\_people.gif}
+_widthhpeople_ [l=id] {200}
+_heighthpeople_ [l=id] {57}
+## "persone" ## green_title ## h_people ##
+_httpiconhpeople_ [l=it] {_httpimg_/it/h\_people.gif}
+_widthhpeople_ [l=it] {200}
+_heighthpeople_ [l=it] {57}
+## "äººå" ## green_title ## h_people ##
+_httpiconhpeople_ [l=ja] {_httpimg_/ja/h\_people.gif}
+_widthhpeople_ [l=ja] {200}
+_heighthpeople_ [l=ja] {57}
+## "ááá á¡áááááá" ## green_title ## h_people ##
+_httpiconhpeople_ [l=ka] {_httpimg_/ka/h\_people.gif}
+_widthhpeople_ [l=ka] {258}
+_heighthpeople_ [l=ka] {74}
+## "Ð¿ÐµÑÑÐŸÐœÐ°Ð»ÐžÐ»ÐµÑ" ## green_title ## h_people ##
+_httpiconhpeople_ [l=kk] {_httpimg_/kk/h\_people.gif}
+_widthhpeople_ [l=kk] {200}
+_heighthpeople_ [l=kk] {57}
+## "Ð¿ÐµÑÑÐŸÐœÐ°Ð»ÐžÐ¹Ð»ÐµÑ" ## green_title ## h_people ##
+_httpiconhpeople_ [l=ky] {_httpimg_/ky/h\_people.gif}
+_widthhpeople_ [l=ky] {200}
+_heighthpeople_ [l=ky] {57}
+## "cilvÄki" ## green_title ## h_people ##
+_httpiconhpeople_ [l=lv] {_httpimg_/lv/h\_people.gif}
+_widthhpeople_ [l=lv] {200}
+_heighthpeople_ [l=lv] {57}
+## "tÄngata" ## green_title ## h_people ##
+_httpiconhpeople_ [l=mi] {_httpimg_/mi/h\_people.gif}
+_widthhpeople_ [l=mi] {200}
+_heighthpeople_ [l=mi] {57}
+## "Ñ
+Ò¯ÐŒÒ¯Ò¯Ñ" ## green_title ## h_people ##
+_httpiconhpeople_ [l=mn] {_httpimg_/mn/h\_people.gif}
+_widthhpeople_ [l=mn] {200}
+_heighthpeople_ [l=mn] {57}
+## "personen" ## green_title ## h_people ##
+_httpiconhpeople_ [l=nl] {_httpimg_/nl/h\_people.gif}
+_widthhpeople_ [l=nl] {200}
+_heighthpeople_ [l=nl] {57}
+## "ludzie" ## green_title ## h_people ##
+_httpiconhpeople_ [l=pl] {_httpimg_/pl/h\_people.gif}
+_widthhpeople_ [l=pl] {200}
+_heighthpeople_ [l=pl] {57}
+## "pessoas" ## green_title ## h_people ##
+_httpiconhpeople_ [l=pt-br] {_httpimg_/pt-br/h\_people.gif}
+_widthhpeople_ [l=pt-br] {200}
+_heighthpeople_ [l=pt-br] {57}
+## "pessoas" ## green_title ## h_people ##
+_httpiconhpeople_ [l=pt-pt] {_httpimg_/pt-pt/h\_people.gif}
+_widthhpeople_ [l=pt-pt] {200}
+_heighthpeople_ [l=pt-pt] {57}
+## "Ð¿ÐµÑÑÐŸÐœÐ°Ð»ÐžÐž" ## green_title ## h_people ##
+_httpiconhpeople_ [l=ru] {_httpimg_/ru/h\_people.gif}
+_widthhpeople_ [l=ru] {200}
+_heighthpeople_ [l=ru] {57}
+## "ljudi" ## green_title ## h_people ##
+_httpiconhpeople_ [l=sr] {_httpimg_/sr/h\_people.gif}
+_widthhpeople_ [l=sr] {200}
+_heighthpeople_ [l=sr] {57}
+## "àžàž£àž°àžàž²àžàž" ## green_title ## h_people ##
+_httpiconhpeople_ [l=th] {_httpimg_/th/h\_people.gif}
+_widthhpeople_ [l=th] {200}
+_heighthpeople_ [l=th] {57}
+## "kiÅiler" ## green_title ## h_people ##
+_httpiconhpeople_ [l=tr] {_httpimg_/tr/h\_people.gif}
+_widthhpeople_ [l=tr] {200}
+_heighthpeople_ [l=tr] {57}
+## "Ð»ÑÐŽÐž" ## green_title ## h_people ##
+_httpiconhpeople_ [l=uk] {_httpimg_/uk/h\_people.gif}
+_widthhpeople_ [l=uk] {200}
+_heighthpeople_ [l=uk] {57}
+## "tÃªn ngÆ°á»i" ## green_title ## h_people ##
+_httpiconhpeople_ [l=vi] {_httpimg_/vi/h\_people.gif}
+_widthhpeople_ [l=vi] {200}
+_heighthpeople_ [l=vi] {57}
+## "äºº" ## green_title ## h_people ##
+_httpiconhpeople_ [l=zh] {_httpimg_/zh/h\_people.gif}
+_widthhpeople_ [l=zh] {200}
+_heighthpeople_ [l=zh] {57}
+## "äºº" ## green_title ## h_people ##
+_httpiconhpeople_ [l=zh-tr] {_httpimg_/zh-tr/h\_people.gif}
+_widthhpeople_ [l=zh-tr] {200}
+_heighthpeople_ [l=zh-tr] {57}
+
+## "phrases" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ {_httpimg_/en/tphrsegr.gif}
+_httpicontphrseof_ {_httpimg_/en/tphrseof.gif}
+_httpicontphrseon_ {_httpimg_/en/tphrseon.gif}
+## "phrases" ## green_title ## h_phrse ##
+_httpiconhphrse_ {_httpimg_/en/h\_phrse.gif}
+_widthhphrse_ {200}
+_heighthphrse_ {57}
+## "Ø§ÙØ¹ØšØ§Ø±Ø§Øª" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=ar] {_httpimg_/ar/tphrsegr.gif}
+_httpicontphrseof_ [l=ar] {_httpimg_/ar/tphrseof.gif}
+_httpicontphrseon_ [l=ar] {_httpimg_/ar/tphrseon.gif}
+## "Ø§ÙØ¹ØšØ§Ø±Ø§Øª" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=ar] {_httpimg_/ar/h\_phrse.gif}
+_widthhphrse_ [l=ar] {200}
+_heighthphrse_ [l=ar] {57}
+## "àŠ¶àŠ¬à§àŠŠ àŠžàŠ®àŠ·à§àŠàŠ¿" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=bn] {_httpimg_/bn/tphrsegr.gif}
+_httpicontphrseof_ [l=bn] {_httpimg_/bn/tphrseof.gif}
+_httpicontphrseon_ [l=bn] {_httpimg_/bn/tphrseon.gif}
+## "àŠ¶àŠ¬à§àŠŠ àŠžàŠ®àŠ·à§àŠàŠ¿" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=bn] {_httpimg_/bn/h\_phrse.gif}
+_widthhphrse_ [l=bn] {200}
+_heighthphrse_ [l=bn] {57}
+## "frases" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=ca] {_httpimg_/ca/tphrsegr.gif}
+_httpicontphrseof_ [l=ca] {_httpimg_/ca/tphrseof.gif}
+_httpicontphrseon_ [l=ca] {_httpimg_/ca/tphrseon.gif}
+## "frases" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=ca] {_httpimg_/ca/h\_phrse.gif}
+_widthhphrse_ [l=ca] {200}
+_heighthphrse_ [l=ca] {57}
+## "frÃ¡ze" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=cs] {_httpimg_/cs/tphrsegr.gif}
+_httpicontphrseof_ [l=cs] {_httpimg_/cs/tphrseof.gif}
+_httpicontphrseon_ [l=cs] {_httpimg_/cs/tphrseon.gif}
+## "frÃ¡ze" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=cs] {_httpimg_/cs/h\_phrse.gif}
+_widthhphrse_ [l=cs] {200}
+_heighthphrse_ [l=cs] {57}
+## "ÏÏÎ¬ÏÎµÎ¹Ï" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=el] {_httpimg_/el/tphrsegr.gif}
+_httpicontphrseof_ [l=el] {_httpimg_/el/tphrseof.gif}
+_httpicontphrseon_ [l=el] {_httpimg_/el/tphrseon.gif}
+## "ÏÏÎ¬ÏÎµÎ¹Ï" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=el] {_httpimg_/el/h\_phrse.gif}
+_widthhphrse_ [l=el] {200}
+_heighthphrse_ [l=el] {57}
+## "frases" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=es] {_httpimg_/es/tphrsegr.gif}
+_httpicontphrseof_ [l=es] {_httpimg_/es/tphrseof.gif}
+_httpicontphrseon_ [l=es] {_httpimg_/es/tphrseon.gif}
+## "frases" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=es] {_httpimg_/es/h\_phrse.gif}
+_widthhphrse_ [l=es] {200}
+_heighthphrse_ [l=es] {57}
+## "Ø¹ØšØ§Ø±Ø§Øª" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=fa] {_httpimg_/fa/tphrsegr.gif}
+_httpicontphrseof_ [l=fa] {_httpimg_/fa/tphrseof.gif}
+_httpicontphrseon_ [l=fa] {_httpimg_/fa/tphrseon.gif}
+## "Ø¹ØšØ§Ø±Ø§Øª" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=fa] {_httpimg_/fa/h\_phrse.gif}
+_widthhphrse_ [l=fa] {200}
+_heighthphrse_ [l=fa] {57}
+## "lausekkeet" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=fi] {_httpimg_/fi/tphrsegr.gif}
+_httpicontphrseof_ [l=fi] {_httpimg_/fi/tphrseof.gif}
+_httpicontphrseon_ [l=fi] {_httpimg_/fi/tphrseon.gif}
+## "lausekkeet" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=fi] {_httpimg_/fi/h\_phrse.gif}
+_widthhphrse_ [l=fi] {200}
+_heighthphrse_ [l=fi] {57}
+## "groupes de mots" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=fr] {_httpimg_/fr/tphrsegr.gif}
+_httpicontphrseof_ [l=fr] {_httpimg_/fr/tphrseof.gif}
+_httpicontphrseon_ [l=fr] {_httpimg_/fr/tphrseon.gif}
+## "groupes de mots" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=fr] {_httpimg_/fr/h\_phrse.gif}
+_widthhphrse_ [l=fr] {200}
+_heighthphrse_ [l=fr] {57}
+## "frases" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=gl] {_httpimg_/gl/tphrsegr.gif}
+_httpicontphrseof_ [l=gl] {_httpimg_/gl/tphrseof.gif}
+_httpicontphrseon_ [l=gl] {_httpimg_/gl/tphrseon.gif}
+## "frases" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=gl] {_httpimg_/gl/h\_phrse.gif}
+_widthhphrse_ [l=gl] {200}
+_heighthphrse_ [l=gl] {57}
+## "fraze" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=hr] {_httpimg_/hr/tphrsegr.gif}
+_httpicontphrseof_ [l=hr] {_httpimg_/hr/tphrseof.gif}
+_httpicontphrseon_ [l=hr] {_httpimg_/hr/tphrseon.gif}
+## "fraze" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=hr] {_httpimg_/hr/h\_phrse.gif}
+_widthhphrse_ [l=hr] {200}
+_heighthphrse_ [l=hr] {57}
+## "Õ¡ÖÕ¿Õ¡Õ°Õ¡ÕµÕ¿ÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=hy] {_httpimg_/hy/tphrsegr.gif}
+_httpicontphrseof_ [l=hy] {_httpimg_/hy/tphrseof.gif}
+_httpicontphrseon_ [l=hy] {_httpimg_/hy/tphrseon.gif}
+## "Õ¡ÖÕ¿Õ¡Õ°Õ¡ÕµÕ¿ÕžÖÕ©ÕµÕžÖÕ¶Õ¶Õ¥Ö" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=hy] {_httpimg_/hy/h\_phrse.gif}
+_widthhphrse_ [l=hy] {200}
+_heighthphrse_ [l=hy] {57}
+## "ungkapan" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=id] {_httpimg_/id/tphrsegr.gif}
+_httpicontphrseof_ [l=id] {_httpimg_/id/tphrseof.gif}
+_httpicontphrseon_ [l=id] {_httpimg_/id/tphrseon.gif}
+## "ungkapan" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=id] {_httpimg_/id/h\_phrse.gif}
+_widthhphrse_ [l=id] {200}
+_heighthphrse_ [l=id] {57}
+## "frasi" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=it] {_httpimg_/it/tphrsegr.gif}
+_httpicontphrseof_ [l=it] {_httpimg_/it/tphrseof.gif}
+_httpicontphrseon_ [l=it] {_httpimg_/it/tphrseon.gif}
+## "frasi" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=it] {_httpimg_/it/h\_phrse.gif}
+_widthhphrse_ [l=it] {200}
+_heighthphrse_ [l=it] {57}
+## "ãã¬ãŒãº" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=ja] {_httpimg_/ja/tphrsegr.gif}
+_httpicontphrseof_ [l=ja] {_httpimg_/ja/tphrseof.gif}
+_httpicontphrseon_ [l=ja] {_httpimg_/ja/tphrseon.gif}
+## "ãã¬ãŒãº" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=ja] {_httpimg_/ja/h\_phrse.gif}
+_widthhphrse_ [l=ja] {200}
+_heighthphrse_ [l=ja] {57}
+## "á€á ááááá" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=ka] {_httpimg_/ka/tphrsegr.gif}
+_httpicontphrseof_ [l=ka] {_httpimg_/ka/tphrseof.gif}
+_httpicontphrseon_ [l=ka] {_httpimg_/ka/tphrseon.gif}
+## "á€á ááááá" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=ka] {_httpimg_/ka/h\_phrse.gif}
+_widthhphrse_ [l=ka] {258}
+_heighthphrse_ [l=ka] {74}
+## "ÑÑÐ°Ð·Ð°Ð»Ð°Ñ" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=kk] {_httpimg_/kk/tphrsegr.gif}
+_httpicontphrseof_ [l=kk] {_httpimg_/kk/tphrseof.gif}
+_httpicontphrseon_ [l=kk] {_httpimg_/kk/tphrseon.gif}
+## "ÑÑÐ°Ð·Ð°Ð»Ð°Ñ" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=kk] {_httpimg_/kk/h\_phrse.gif}
+_widthhphrse_ [l=kk] {200}
+_heighthphrse_ [l=kk] {57}
+## "ÑÑÐ°Ð·Ð°Ð»Ð°Ñ" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=ky] {_httpimg_/ky/tphrsegr.gif}
+_httpicontphrseof_ [l=ky] {_httpimg_/ky/tphrseof.gif}
+_httpicontphrseon_ [l=ky] {_httpimg_/ky/tphrseon.gif}
+## "ÑÑÐ°Ð·Ð°Ð»Ð°Ñ" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=ky] {_httpimg_/ky/h\_phrse.gif}
+_widthhphrse_ [l=ky] {200}
+_heighthphrse_ [l=ky] {57}
+## "frÄzes" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=lv] {_httpimg_/lv/tphrsegr.gif}
+_httpicontphrseof_ [l=lv] {_httpimg_/lv/tphrseof.gif}
+_httpicontphrseon_ [l=lv] {_httpimg_/lv/tphrseon.gif}
+## "frÄzes" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=lv] {_httpimg_/lv/h\_phrse.gif}
+_widthhphrse_ [l=lv] {200}
+_heighthphrse_ [l=lv] {57}
+## "kÄ«waha" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=mi] {_httpimg_/mi/tphrsegr.gif}
+_httpicontphrseof_ [l=mi] {_httpimg_/mi/tphrseof.gif}
+_httpicontphrseon_ [l=mi] {_httpimg_/mi/tphrseon.gif}
+## "kÄ«waha" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=mi] {_httpimg_/mi/h\_phrse.gif}
+_widthhphrse_ [l=mi] {200}
+_heighthphrse_ [l=mi] {57}
+## "Ñ
+ÑÐ»Ñ Ò¯Ð³Ò¯Ò¯ÐŽ" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=mn] {_httpimg_/mn/tphrsegr.gif}
+_httpicontphrseof_ [l=mn] {_httpimg_/mn/tphrseof.gif}
+_httpicontphrseon_ [l=mn] {_httpimg_/mn/tphrseon.gif}
+## "Ñ
+ÑÐ»Ñ Ò¯Ð³ÐœÒ¯Ò¯ÐŽ" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=mn] {_httpimg_/mn/h\_phrse.gif}
+_widthhphrse_ [l=mn] {200}
+_heighthphrse_ [l=mn] {57}
+## "wyraÅŒenia" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=pl] {_httpimg_/pl/tphrsegr.gif}
+_httpicontphrseof_ [l=pl] {_httpimg_/pl/tphrseof.gif}
+_httpicontphrseon_ [l=pl] {_httpimg_/pl/tphrseon.gif}
+## "wyraÅŒenia" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=pl] {_httpimg_/pl/h\_phrse.gif}
+_widthhphrse_ [l=pl] {200}
+_heighthphrse_ [l=pl] {57}
+## "frases" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=pt-pt] {_httpimg_/pt-pt/tphrsegr.gif}
+_httpicontphrseof_ [l=pt-pt] {_httpimg_/pt-pt/tphrseof.gif}
+_httpicontphrseon_ [l=pt-pt] {_httpimg_/pt-pt/tphrseon.gif}
+## "frases" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=pt-pt] {_httpimg_/pt-pt/h\_phrse.gif}
+_widthhphrse_ [l=pt-pt] {200}
+_heighthphrse_ [l=pt-pt] {57}
+## "ÑÑÐ°Ð·Ñ" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=ru] {_httpimg_/ru/tphrsegr.gif}
+_httpicontphrseof_ [l=ru] {_httpimg_/ru/tphrseof.gif}
+_httpicontphrseon_ [l=ru] {_httpimg_/ru/tphrseon.gif}
+## "ÑÑÐ°Ð·Ñ" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=ru] {_httpimg_/ru/h\_phrse.gif}
+_widthhphrse_ [l=ru] {200}
+_heighthphrse_ [l=ru] {57}
+## "fraze" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=sr] {_httpimg_/sr/tphrsegr.gif}
+_httpicontphrseof_ [l=sr] {_httpimg_/sr/tphrseof.gif}
+_httpicontphrseon_ [l=sr] {_httpimg_/sr/tphrseon.gif}
+## "fraze" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=sr] {_httpimg_/sr/h\_phrse.gif}
+_widthhphrse_ [l=sr] {200}
+_heighthphrse_ [l=sr] {57}
+## "àž§àž¥àžµ" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=th] {_httpimg_/th/tphrsegr.gif}
+_httpicontphrseof_ [l=th] {_httpimg_/th/tphrseof.gif}
+_httpicontphrseon_ [l=th] {_httpimg_/th/tphrseon.gif}
+## "àž§àž¥àžµ" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=th] {_httpimg_/th/h\_phrse.gif}
+_widthhphrse_ [l=th] {200}
+_heighthphrse_ [l=th] {57}
+## "ifadeler" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=tr] {_httpimg_/tr/tphrsegr.gif}
+_httpicontphrseof_ [l=tr] {_httpimg_/tr/tphrseof.gif}
+_httpicontphrseon_ [l=tr] {_httpimg_/tr/tphrseon.gif}
+## "ifadeler" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=tr] {_httpimg_/tr/h\_phrse.gif}
+_widthhphrse_ [l=tr] {200}
+_heighthphrse_ [l=tr] {57}
+## "ÑÑÐ°Ð·Ðž" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=uk] {_httpimg_/uk/tphrsegr.gif}
+_httpicontphrseof_ [l=uk] {_httpimg_/uk/tphrseof.gif}
+_httpicontphrseon_ [l=uk] {_httpimg_/uk/tphrseon.gif}
+## "ÑÑÐ°Ð·Ðž" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=uk] {_httpimg_/uk/h\_phrse.gif}
+_widthhphrse_ [l=uk] {200}
+_heighthphrse_ [l=uk] {57}
+## "cá»¥m tá»«" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=vi] {_httpimg_/vi/tphrsegr.gif}
+_httpicontphrseof_ [l=vi] {_httpimg_/vi/tphrseof.gif}
+_httpicontphrseon_ [l=vi] {_httpimg_/vi/tphrseon.gif}
+## "cá»¥m tá»«" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=vi] {_httpimg_/vi/h\_phrse.gif}
+_widthhphrse_ [l=vi] {200}
+_heighthphrse_ [l=vi] {57}
+## "ç­å¥" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=zh] {_httpimg_/zh/tphrsegr.gif}
+_httpicontphrseof_ [l=zh] {_httpimg_/zh/tphrseof.gif}
+_httpicontphrseon_ [l=zh] {_httpimg_/zh/tphrseon.gif}
+## "ç­å¥" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=zh] {_httpimg_/zh/h\_phrse.gif}
+_widthhphrse_ [l=zh] {200}
+_heighthphrse_ [l=zh] {57}
+## "çèª" ## nav_bar_button ## tphrse ##
+_httpicontphrsegr_ [l=zh-tr] {_httpimg_/zh-tr/tphrsegr.gif}
+_httpicontphrseof_ [l=zh-tr] {_httpimg_/zh-tr/tphrseof.gif}
+_httpicontphrseon_ [l=zh-tr] {_httpimg_/zh-tr/tphrseon.gif}
+## "çèª" ## green_title ## h_phrse ##
+_httpiconhphrse_ [l=zh-tr] {_httpimg_/zh-tr/h\_phrse.gif}
+_widthhphrse_ [l=zh-tr] {200}
+_heighthphrse_ [l=zh-tr] {57}
+
+
+## "publishers" ## nav_bar_button ## tpubl ##
+_httpicontpublgr_ {_httpimg_/en/tpublgr.gif}
+_httpicontpublon_ {_httpimg_/en/tpublon.gif}
+_httpicontpublof_ {_httpimg_/en/tpublof.gif}
+## "publishers" ## green_title ## h_publ ##
+_httpiconhpubl_ {_httpimg_/en/h\_publ.gif}
+_widthhpubl_ {200}
+_heighthpubl_ {57}
+## "àŠªà§àŠ°àŠàŠŸàŠ¶àŠàŠàŠ£" ## nav_bar_button ## tpubl ##
+_httpicontpublgr_ [l=bn] {_httpimg_/bn/tpublgr.gif}
+_httpicontpublon_ [l=bn] {_httpimg_/bn/tpublon.gif}
+_httpicontpublof_ [l=bn] {_httpimg_/bn/tpublof.gif}
+## "àŠªà§àŠ°àŠàŠŸàŠ¶àŠàŠàŠ£" ## green_title ## h_publ ##
+_httpiconhpubl_ [l=bn] {_httpimg_/bn/h\_publ.gif}
+_widthhpubl_ [l=bn] {200}
+_heighthpubl_ [l=bn] {57}
+## "editores" ## nav_bar_button ## tpubl ##
+_httpicontpublgr_ [l=es] {_httpimg_/es/tpublgr.gif}
+_httpicontpublon_ [l=es] {_httpimg_/es/tpublon.gif}
+_httpicontpublof_ [l=es] {_httpimg_/es/tpublof.gif}
+## "editores" ## green_title ## h_publ ##
+_httpiconhpubl_ [l=es] {_httpimg_/es/h\_publ.gif}
+_widthhpubl_ [l=es] {200}
+_heighthpubl_ [l=es] {57}
+## "Ãditeurs" ## nav_bar_button ## tpubl ##
+_httpicontpublgr_ [l=fr] {_httpimg_/fr/tpublgr.gif}
+_httpicontpublon_ [l=fr] {_httpimg_/fr/tpublon.gif}
+_httpicontpublof_ [l=fr] {_httpimg_/fr/tpublof.gif}
+## "Ãditeurs" ## green_title ## h_publ ##
+_httpiconhpubl_ [l=fr] {_httpimg_/fr/h\_publ.gif}
+_widthhpubl_ [l=fr] {200}
+_heighthpubl_ [l=fr] {57}
+## "penerbit" ## nav_bar_button ## tpubl ##
+_httpicontpublgr_ [l=id] {_httpimg_/id/tpublgr.gif}
+_httpicontpublon_ [l=id] {_httpimg_/id/tpublon.gif}
+_httpicontpublof_ [l=id] {_httpimg_/id/tpublof.gif}
+## "penerbit" ## green_title ## h_publ ##
+_httpiconhpubl_ [l=id] {_httpimg_/id/h\_publ.gif}
+_widthhpubl_ [l=id] {200}
+_heighthpubl_ [l=id] {57}
+## "Ð±Ð°ÑÐŒÐ°ÐºÐ°ÐœÐ°Ð»Ð°Ñ" ## nav_bar_button ## tpubl ##
+_httpicontpublgr_ [l=ky] {_httpimg_/ky/tpublgr.gif}
+_httpicontpublon_ [l=ky] {_httpimg_/ky/tpublon.gif}
+_httpicontpublof_ [l=ky] {_httpimg_/ky/tpublof.gif}
+## "Ð±Ð°ÑÑÐ¿ ÑÑÐ³Ð°ÑÑÑÑÑÐ»Ð°Ñ" ## green_title ## h_publ ##
+_httpiconhpubl_ [l=ky] {_httpimg_/ky/h\_publ.gif}
+_widthhpubl_ [l=ky] {200}
+_heighthpubl_ [l=ky] {57}
+## "izdevÄji" ## nav_bar_button ## tpubl ##
+_httpicontpublgr_ [l=lv] {_httpimg_/lv/tpublgr.gif}
+_httpicontpublon_ [l=lv] {_httpimg_/lv/tpublon.gif}
+_httpicontpublof_ [l=lv] {_httpimg_/lv/tpublof.gif}
+## "izdevÄji" ## green_title ## h_publ ##
+_httpiconhpubl_ [l=lv] {_httpimg_/lv/h\_publ.gif}
+_widthhpubl_ [l=lv] {200}
+_heighthpubl_ [l=lv] {57}
+## "ÐœÐžÐ¹ÑÐ»ÑÐ³ÑÐžÐŽ" ## nav_bar_button ## tpubl ##
+_httpicontpublgr_ [l=mn] {_httpimg_/mn/tpublgr.gif}
+_httpicontpublon_ [l=mn] {_httpimg_/mn/tpublon.gif}
+_httpicontpublof_ [l=mn] {_httpimg_/mn/tpublof.gif}
+## "ÐœÐžÐ¹ÑÐ»ÑÐ³ÑÐžÐŽ" ## green_title ## h_publ ##
+_httpiconhpubl_ [l=mn] {_httpimg_/mn/h\_publ.gif}
+_widthhpubl_ [l=mn] {200}
+_heighthpubl_ [l=mn] {57}
+## "wydawcy" ## nav_bar_button ## tpubl ##
+_httpicontpublgr_ [l=pl] {_httpimg_/pl/tpublgr.gif}
+_httpicontpublon_ [l=pl] {_httpimg_/pl/tpublon.gif}
+_httpicontpublof_ [l=pl] {_httpimg_/pl/tpublof.gif}
+## "wydawcy" ## green_title ## h_publ ##
+_httpiconhpubl_ [l=pl] {_httpimg_/pl/h\_publ.gif}
+_widthhpubl_ [l=pl] {200}
+_heighthpubl_ [l=pl] {57}
+## "ÐžÐ·ÐŽÐ°ÑÐµÐ»Ðž" ## nav_bar_button ## tpubl ##
+_httpicontpublgr_ [l=ru] {_httpimg_/ru/tpublgr.gif}
+_httpicontpublon_ [l=ru] {_httpimg_/ru/tpublon.gif}
+_httpicontpublof_ [l=ru] {_httpimg_/ru/tpublof.gif}
+## "ÐžÐ·ÐŽÐ°ÑÐµÐ»Ðž" ## green_title ## h_publ ##
+_httpiconhpubl_ [l=ru] {_httpimg_/ru/h\_publ.gif}
+_widthhpubl_ [l=ru] {200}
+_heighthpubl_ [l=ru] {57}
+## "åºçè
+" ## nav_bar_button ## tpubl ##
+_httpicontpublgr_ [l=zh-tr] {_httpimg_/zh-tr/tpublgr.gif}
+_httpicontpublon_ [l=zh-tr] {_httpimg_/zh-tr/tpublon.gif}
+_httpicontpublof_ [l=zh-tr] {_httpimg_/zh-tr/tpublof.gif}
+## "åºçè
+" ## green_title ## h_publ ##
+_httpiconhpubl_ [l=zh-tr] {_httpimg_/zh-tr/h\_publ.gif}
+_widthhpubl_ [l=zh-tr] {200}
+_heighthpubl_ [l=zh-tr] {57}
+
+## "relations" ## nav_bar_button ## trel ##
+_httpicontrelgr_ {_httpimg_/en/trelgr.gif}
+_httpicontrelon_ {_httpimg_/en/trelon.gif}
+_httpicontrelof_ {_httpimg_/en/trelof.gif}
+## "relations" ## green_title ## h_rel ##
+_httpiconhrel_ {_httpimg_/en/h\_rel.gif}
+_widthhrel_ {200}
+_heighthrel_ {57}
+## "àŠžàŠ®à§àŠªàŠ°à§àŠ" ## nav_bar_button ## trel ##
+_httpicontrelgr_ [l=bn] {_httpimg_/bn/trelgr.gif}
+_httpicontrelon_ [l=bn] {_httpimg_/bn/trelon.gif}
+_httpicontrelof_ [l=bn] {_httpimg_/bn/trelof.gif}
+## "àŠžàŠ®à§àŠªàŠ°à§àŠàŠà§àŠ²àŠ¿" ## green_title ## h_rel ##
+_httpiconhrel_ [l=bn] {_httpimg_/bn/h\_rel.gif}
+_widthhrel_ [l=bn] {200}
+_heighthrel_ [l=bn] {57}
+## "relaciÃ³nes" ## nav_bar_button ## trel ##
+_httpicontrelgr_ [l=es] {_httpimg_/es/trelgr.gif}
+_httpicontrelon_ [l=es] {_httpimg_/es/trelon.gif}
+_httpicontrelof_ [l=es] {_httpimg_/es/trelof.gif}
+## "relaciÃ³nes" ## green_title ## h_rel ##
+_httpiconhrel_ [l=es] {_httpimg_/es/h\_rel.gif}
+_widthhrel_ [l=es] {200}
+_heighthrel_ [l=es] {57}
+## "RÃ©fÃ©rences" ## nav_bar_button ## trel ##
+_httpicontrelgr_ [l=fr] {_httpimg_/fr/trelgr.gif}
+_httpicontrelon_ [l=fr] {_httpimg_/fr/trelon.gif}
+_httpicontrelof_ [l=fr] {_httpimg_/fr/trelof.gif}
+## "RÃ©fÃ©rences" ## green_title ## h_rel ##
+_httpiconhrel_ [l=fr] {_httpimg_/fr/h\_rel.gif}
+_widthhrel_ [l=fr] {200}
+_heighthrel_ [l=fr] {57}
+## "hubungan" ## nav_bar_button ## trel ##
+_httpicontrelgr_ [l=id] {_httpimg_/id/trelgr.gif}
+_httpicontrelon_ [l=id] {_httpimg_/id/trelon.gif}
+_httpicontrelof_ [l=id] {_httpimg_/id/trelof.gif}
+## "hubungan" ## green_title ## h_rel ##
+_httpiconhrel_ [l=id] {_httpimg_/id/h\_rel.gif}
+_widthhrel_ [l=id] {200}
+_heighthrel_ [l=id] {57}
+## "ÐŒÐ°ÐŒÐžÐ»ÐµÐ»ÐµÑ" ## nav_bar_button ## trel ##
+_httpicontrelgr_ [l=ky] {_httpimg_/ky/trelgr.gif}
+_httpicontrelon_ [l=ky] {_httpimg_/ky/trelon.gif}
+_httpicontrelof_ [l=ky] {_httpimg_/ky/trelof.gif}
+## "ÐŒÐ°ÐŒÐžÐ»ÐµÐ»ÐµÑ" ## green_title ## h_rel ##
+_httpiconhrel_ [l=ky] {_httpimg_/ky/h\_rel.gif}
+_widthhrel_ [l=ky] {200}
+_heighthrel_ [l=ky] {57}
+## "saistÄ«bas" ## nav_bar_button ## trel ##
+_httpicontrelgr_ [l=lv] {_httpimg_/lv/trelgr.gif}
+_httpicontrelon_ [l=lv] {_httpimg_/lv/trelon.gif}
+_httpicontrelof_ [l=lv] {_httpimg_/lv/trelof.gif}
+## "saistÄ«bas" ## green_title ## h_rel ##
+_httpiconhrel_ [l=lv] {_httpimg_/lv/h\_rel.gif}
+_widthhrel_ [l=lv] {200}
+_heighthrel_ [l=lv] {57}
+## "Ó©Ð³Ò¯Ò¯Ð»Ð»Ò¯Ò¯ÐŽ" ## nav_bar_button ## trel ##
+_httpicontrelgr_ [l=mn] {_httpimg_/mn/trelgr.gif}
+_httpicontrelon_ [l=mn] {_httpimg_/mn/trelon.gif}
+_httpicontrelof_ [l=mn] {_httpimg_/mn/trelof.gif}
+## "Ñ
+Ð°ÐŒÐ°Ð°ÑÐ»ÑÑÐŽ" ## green_title ## h_rel ##
+_httpiconhrel_ [l=mn] {_httpimg_/mn/h\_rel.gif}
+_widthhrel_ [l=mn] {200}
+_heighthrel_ [l=mn] {57}
+## "relacje" ## nav_bar_button ## trel ##
+_httpicontrelgr_ [l=pl] {_httpimg_/pl/trelgr.gif}
+_httpicontrelon_ [l=pl] {_httpimg_/pl/trelon.gif}
+_httpicontrelof_ [l=pl] {_httpimg_/pl/trelof.gif}
+## "relacje" ## green_title ## h_rel ##
+_httpiconhrel_ [l=pl] {_httpimg_/pl/h\_rel.gif}
+_widthhrel_ [l=pl] {200}
+_heighthrel_ [l=pl] {57}
+## "ÑÐ²ÑÐ·Ðž" ## nav_bar_button ## trel ##
+_httpicontrelgr_ [l=ru] {_httpimg_/ru/trelgr.gif}
+_httpicontrelon_ [l=ru] {_httpimg_/ru/trelon.gif}
+_httpicontrelof_ [l=ru] {_httpimg_/ru/trelof.gif}
+## "ÑÐ²ÑÐ·Ðž" ## green_title ## h_rel ##
+_httpiconhrel_ [l=ru] {_httpimg_/ru/h\_rel.gif}
+_widthhrel_ [l=ru] {200}
+_heighthrel_ [l=ru] {57}
+## "éä¿" ## nav_bar_button ## trel ##
+_httpicontrelgr_ [l=zh-tr] {_httpimg_/zh-tr/trelgr.gif}
+_httpicontrelon_ [l=zh-tr] {_httpimg_/zh-tr/trelon.gif}
+_httpicontrelof_ [l=zh-tr] {_httpimg_/zh-tr/trelof.gif}
+## "éä¿" ## green_title ## h_rel ##
+_httpiconhrel_ [l=zh-tr] {_httpimg_/zh-tr/h\_rel.gif}
+_widthhrel_ [l=zh-tr] {200}
+_heighthrel_ [l=zh-tr] {57}
+
+## "rights" ## nav_bar_button ## tright ##
+_httpicontrightgr_ {_httpimg_/en/trightgr.gif}
+_httpicontrighton_ {_httpimg_/en/trighton.gif}
+_httpicontrightof_ {_httpimg_/en/trightof.gif}
+## "rights" ## green_title ## h_right ##
+_httpiconhright_ {_httpimg_/en/h\_right.gif}
+_widthhright_ {200}
+_heighthright_ {57}
+## "àŠ
+àŠ§àŠ¿àŠàŠŸàŠ°" ## nav_bar_button ## tright ##
+_httpicontrightgr_ [l=bn] {_httpimg_/bn/trightgr.gif}
+_httpicontrighton_ [l=bn] {_httpimg_/bn/trighton.gif}
+_httpicontrightof_ [l=bn] {_httpimg_/bn/trightof.gif}
+## "àŠ
+àŠ§àŠ¿àŠàŠŸàŠ°" ## green_title ## h_right ##
+_httpiconhright_ [l=bn] {_httpimg_/bn/h\_right.gif}
+_widthhright_ [l=bn] {200}
+_heighthright_ [l=bn] {57}
+## "derechos" ## nav_bar_button ## tright ##
+_httpicontrightgr_ [l=es] {_httpimg_/es/trightgr.gif}
+_httpicontrighton_ [l=es] {_httpimg_/es/trighton.gif}
+_httpicontrightof_ [l=es] {_httpimg_/es/trightof.gif}
+## "derechos" ## green_title ## h_right ##
+_httpiconhright_ [l=es] {_httpimg_/es/h\_right.gif}
+_widthhright_ [l=es] {200}
+_heighthright_ [l=es] {57}
+## "Droits" ## nav_bar_button ## tright ##
+_httpicontrightgr_ [l=fr] {_httpimg_/fr/trightgr.gif}
+_httpicontrighton_ [l=fr] {_httpimg_/fr/trighton.gif}
+_httpicontrightof_ [l=fr] {_httpimg_/fr/trightof.gif}
+## "Droits" ## green_title ## h_right ##
+_httpiconhright_ [l=fr] {_httpimg_/fr/h\_right.gif}
+_widthhright_ [l=fr] {200}
+_heighthright_ [l=fr] {57}
+## "hak-hak" ## nav_bar_button ## tright ##
+_httpicontrightgr_ [l=id] {_httpimg_/id/trightgr.gif}
+_httpicontrighton_ [l=id] {_httpimg_/id/trighton.gif}
+_httpicontrightof_ [l=id] {_httpimg_/id/trightof.gif}
+## "hak-hak" ## green_title ## h_right ##
+_httpiconhright_ [l=id] {_httpimg_/id/h\_right.gif}
+_widthhright_ [l=id] {200}
+_heighthright_ [l=id] {57}
+## "ÑÐºÑÐºÑÐ°Ñ" ## nav_bar_button ## tright ##
+_httpicontrightgr_ [l=ky] {_httpimg_/ky/trightgr.gif}
+_httpicontrighton_ [l=ky] {_httpimg_/ky/trighton.gif}
+_httpicontrightof_ [l=ky] {_httpimg_/ky/trightof.gif}
+## "ÑÐºÑÐºÑÐ°Ñ" ## green_title ## h_right ##
+_httpiconhright_ [l=ky] {_httpimg_/ky/h\_right.gif}
+_widthhright_ [l=ky] {200}
+_heighthright_ [l=ky] {57}
+## "tiesÄ«bas" ## nav_bar_button ## tright ##
+_httpicontrightgr_ [l=lv] {_httpimg_/lv/trightgr.gif}
+_httpicontrighton_ [l=lv] {_httpimg_/lv/trighton.gif}
+_httpicontrightof_ [l=lv] {_httpimg_/lv/trightof.gif}
+## "tiesÄ«bas" ## green_title ## h_right ##
+_httpiconhright_ [l=lv] {_httpimg_/lv/h\_right.gif}
+_widthhright_ [l=lv] {200}
+_heighthright_ [l=lv] {57}
+## "ÑÑÑ
+Ò¯Ò¯ÐŽ" ## nav_bar_button ## tright ##
+_httpicontrightgr_ [l=mn] {_httpimg_/mn/trightgr.gif}
+_httpicontrighton_ [l=mn] {_httpimg_/mn/trighton.gif}
+_httpicontrightof_ [l=mn] {_httpimg_/mn/trightof.gif}
+## "ÑÑÑ
+Ò¯Ò¯ÐŽ" ## green_title ## h_right ##
+_httpiconhright_ [l=mn] {_httpimg_/mn/h\_right.gif}
+_widthhright_ [l=mn] {200}
+_heighthright_ [l=mn] {57}
+## "prawa" ## nav_bar_button ## tright ##
+_httpicontrightgr_ [l=pl] {_httpimg_/pl/trightgr.gif}
+_httpicontrighton_ [l=pl] {_httpimg_/pl/trighton.gif}
+_httpicontrightof_ [l=pl] {_httpimg_/pl/trightof.gif}
+## "prawa autorskie" ## green_title ## h_right ##
+_httpiconhright_ [l=pl] {_httpimg_/pl/h\_right.gif}
+_widthhright_ [l=pl] {200}
+_heighthright_ [l=pl] {57}
+## "Ð¿ÑÐ°Ð²Ð°" ## nav_bar_button ## tright ##
+_httpicontrightgr_ [l=ru] {_httpimg_/ru/trightgr.gif}
+_httpicontrighton_ [l=ru] {_httpimg_/ru/trighton.gif}
+_httpicontrightof_ [l=ru] {_httpimg_/ru/trightof.gif}
+## "Ð¿ÑÐ°Ð²Ð°" ## green_title ## h_right ##
+_httpiconhright_ [l=ru] {_httpimg_/ru/h\_right.gif}
+_widthhright_ [l=ru] {200}
+_heighthright_ [l=ru] {57}
+## "æ¬å©" ## nav_bar_button ## tright ##
+_httpicontrightgr_ [l=zh-tr] {_httpimg_/zh-tr/trightgr.gif}
+_httpicontrighton_ [l=zh-tr] {_httpimg_/zh-tr/trighton.gif}
+_httpicontrightof_ [l=zh-tr] {_httpimg_/zh-tr/trightof.gif}
+## "æ¬å©" ## green_title ## h_right ##
+_httpiconhright_ [l=zh-tr] {_httpimg_/zh-tr/h\_right.gif}
+_widthhright_ [l=zh-tr] {200}
+_heighthright_ [l=zh-tr] {57}
+
+
+## "series" ## nav_bar_button ## tser ##
+_httpicontsergr_ {_httpimg_/en/tsergr.gif}
+_httpicontserof_ {_httpimg_/en/tserof.gif}
+_httpicontseron_ {_httpimg_/en/tseron.gif}
+## "series" ## green_title ## h_ser ##
+_httpiconhser_ {_httpimg_/en/h\_ser.gif}
+_widthhser_ {200}
+_heighthser_ {57}
+## "Ø§ÙØ³ÙØ§Ø³Ù" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=ar] {_httpimg_/ar/tsergr.gif}
+_httpicontserof_ [l=ar] {_httpimg_/ar/tserof.gif}
+_httpicontseron_ [l=ar] {_httpimg_/ar/tseron.gif}
+## "Ø§ÙØ³ÙØ§Ø³Ù" ## green_title ## h_ser ##
+_httpiconhser_ [l=ar] {_httpimg_/ar/h\_ser.gif}
+_widthhser_ [l=ar] {200}
+_heighthser_ [l=ar] {57}
+## "àŠà§àŠ°àŠ®àŠšà§àŠ¬à§" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=bn] {_httpimg_/bn/tsergr.gif}
+_httpicontserof_ [l=bn] {_httpimg_/bn/tserof.gif}
+_httpicontseron_ [l=bn] {_httpimg_/bn/tseron.gif}
+## "àŠà§àŠ°àŠ®àŠšà§àŠ¬à§" ## green_title ## h_ser ##
+_httpiconhser_ [l=bn] {_httpimg_/bn/h\_ser.gif}
+_widthhser_ [l=bn] {200}
+_heighthser_ [l=bn] {57}
+## "sÃšrie" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=ca] {_httpimg_/ca/tsergr.gif}
+_httpicontserof_ [l=ca] {_httpimg_/ca/tserof.gif}
+_httpicontseron_ [l=ca] {_httpimg_/ca/tseron.gif}
+## "sÃšrie" ## green_title ## h_ser ##
+_httpiconhser_ [l=ca] {_httpimg_/ca/h\_ser.gif}
+_widthhser_ [l=ca] {200}
+_heighthser_ [l=ca] {57}
+## "ÄÃ­sla" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=cs] {_httpimg_/cs/tsergr.gif}
+_httpicontserof_ [l=cs] {_httpimg_/cs/tserof.gif}
+_httpicontseron_ [l=cs] {_httpimg_/cs/tseron.gif}
+## "ÄÃ­sla" ## green_title ## h_ser ##
+_httpiconhser_ [l=cs] {_httpimg_/cs/h\_ser.gif}
+_widthhser_ [l=cs] {200}
+_heighthser_ [l=cs] {57}
+## "serien" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=de] {_httpimg_/de/tsergr.gif}
+_httpicontserof_ [l=de] {_httpimg_/de/tserof.gif}
+_httpicontseron_ [l=de] {_httpimg_/de/tseron.gif}
+## "serien" ## green_title ## h_ser ##
+_httpiconhser_ [l=de] {_httpimg_/de/h\_ser.gif}
+_widthhser_ [l=de] {200}
+_heighthser_ [l=de] {57}
+## "ÏÎµÎ¹ÏÎ­Ï" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=el] {_httpimg_/el/tsergr.gif}
+_httpicontserof_ [l=el] {_httpimg_/el/tserof.gif}
+_httpicontseron_ [l=el] {_httpimg_/el/tseron.gif}
+## "ÏÎµÎ¹ÏÎ­Ï" ## green_title ## h_ser ##
+_httpiconhser_ [l=el] {_httpimg_/el/h\_ser.gif}
+_widthhser_ [l=el] {200}
+_heighthser_ [l=el] {57}
+## "series" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=es] {_httpimg_/es/tsergr.gif}
+_httpicontserof_ [l=es] {_httpimg_/es/tserof.gif}
+_httpicontseron_ [l=es] {_httpimg_/es/tseron.gif}
+## "series" ## green_title ## h_ser ##
+_httpiconhser_ [l=es] {_httpimg_/es/h\_ser.gif}
+_widthhser_ [l=es] {200}
+_heighthser_ [l=es] {57}
+## "Ø³Ø±Ù ÙØ§" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=fa] {_httpimg_/fa/tsergr.gif}
+_httpicontserof_ [l=fa] {_httpimg_/fa/tserof.gif}
+_httpicontseron_ [l=fa] {_httpimg_/fa/tseron.gif}
+## "Ø³Ø±Ù ÙØ§" ## green_title ## h_ser ##
+_httpiconhser_ [l=fa] {_httpimg_/fa/h\_ser.gif}
+_widthhser_ [l=fa] {200}
+_heighthser_ [l=fa] {57}
+## "sarjat" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=fi] {_httpimg_/fi/tsergr.gif}
+_httpicontserof_ [l=fi] {_httpimg_/fi/tserof.gif}
+_httpicontseron_ [l=fi] {_httpimg_/fi/tseron.gif}
+## "sarjat" ## green_title ## h_ser ##
+_httpiconhser_ [l=fi] {_httpimg_/fi/h\_ser.gif}
+_widthhser_ [l=fi] {200}
+_heighthser_ [l=fi] {57}
+## "sÃ©ries" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=fr] {_httpimg_/fr/tsergr.gif}
+_httpicontserof_ [l=fr] {_httpimg_/fr/tserof.gif}
+_httpicontseron_ [l=fr] {_httpimg_/fr/tseron.gif}
+## "sÃ©ries" ## green_title ## h_ser ##
+_httpiconhser_ [l=fr] {_httpimg_/fr/h\_ser.gif}
+_widthhser_ [l=fr] {200}
+_heighthser_ [l=fr] {57}
+## "series" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=gl] {_httpimg_/gl/tsergr.gif}
+_httpicontserof_ [l=gl] {_httpimg_/gl/tserof.gif}
+_httpicontseron_ [l=gl] {_httpimg_/gl/tseron.gif}
+## "series" ## green_title ## h_ser ##
+_httpiconhser_ [l=gl] {_httpimg_/gl/h\_ser.gif}
+_widthhser_ [l=gl] {200}
+_heighthser_ [l=gl] {57}
+## "×ª××š××¡" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=he] {_httpimg_/he/tsergr.gif}
+_httpicontserof_ [l=he] {_httpimg_/he/tserof.gif}
+_httpicontseron_ [l=he] {_httpimg_/he/tseron.gif}
+## "×ª××š××¡" ## green_title ## h_ser ##
+_httpiconhser_ [l=he] {_httpimg_/he/h\_ser.gif}
+_widthhser_ [l=he] {200}
+_heighthser_ [l=he] {57}
+## "nizovi" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=hr] {_httpimg_/hr/tsergr.gif}
+_httpicontserof_ [l=hr] {_httpimg_/hr/tserof.gif}
+_httpicontseron_ [l=hr] {_httpimg_/hr/tseron.gif}
+## "nizovi" ## green_title ## h_ser ##
+_httpiconhser_ [l=hr] {_httpimg_/hr/h\_ser.gif}
+_widthhser_ [l=hr] {200}
+_heighthser_ [l=hr] {57}
+## "ÕŽÕ¡Õ¿Õ¥Õ¶Õ¡Õ·Õ¡Ö" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=hy] {_httpimg_/hy/tsergr.gif}
+_httpicontserof_ [l=hy] {_httpimg_/hy/tserof.gif}
+_httpicontseron_ [l=hy] {_httpimg_/hy/tseron.gif}
+## "ÕŽÕ¡Õ¿Õ¥Õ¶Õ¡Õ·Õ¡Ö" ## green_title ## h_ser ##
+_httpiconhser_ [l=hy] {_httpimg_/hy/h\_ser.gif}
+_widthhser_ [l=hy] {200}
+_heighthser_ [l=hy] {57}
+## "berkala" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=id] {_httpimg_/id/tsergr.gif}
+_httpicontserof_ [l=id] {_httpimg_/id/tserof.gif}
+_httpicontseron_ [l=id] {_httpimg_/id/tseron.gif}
+## "berkala" ## green_title ## h_ser ##
+_httpiconhser_ [l=id] {_httpimg_/id/h\_ser.gif}
+_widthhser_ [l=id] {200}
+_heighthser_ [l=id] {57}
+## "serie" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=it] {_httpimg_/it/tsergr.gif}
+_httpicontserof_ [l=it] {_httpimg_/it/tserof.gif}
+_httpicontseron_ [l=it] {_httpimg_/it/tseron.gif}
+## "serie" ## green_title ## h_ser ##
+_httpiconhser_ [l=it] {_httpimg_/it/h\_ser.gif}
+_widthhser_ [l=it] {200}
+_heighthser_ [l=it] {57}
+## "ã·ãªãŒãº" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=ja] {_httpimg_/ja/tsergr.gif}
+_httpicontserof_ [l=ja] {_httpimg_/ja/tserof.gif}
+_httpicontseron_ [l=ja] {_httpimg_/ja/tseron.gif}
+## "ã·ãªãŒãº" ## green_title ## h_ser ##
+_httpiconhser_ [l=ja] {_httpimg_/ja/h\_ser.gif}
+_widthhser_ [l=ja] {200}
+_heighthser_ [l=ja] {57}
+## "á¡áá áááá" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=ka] {_httpimg_/ka/tsergr.gif}
+_httpicontserof_ [l=ka] {_httpimg_/ka/tserof.gif}
+_httpicontseron_ [l=ka] {_httpimg_/ka/tseron.gif}
+## "á¡áá áááá" ## green_title ## h_ser ##
+_httpiconhser_ [l=ka] {_httpimg_/ka/h\_ser.gif}
+_widthhser_ [l=ka] {258}
+_heighthser_ [l=ka] {74}
+## "ÑÑÒÐ°ÑÑÐ»ÑÐŒÐŽÐ°Ñ" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=kk] {_httpimg_/kk/tsergr.gif}
+_httpicontserof_ [l=kk] {_httpimg_/kk/tserof.gif}
+_httpicontseron_ [l=kk] {_httpimg_/kk/tseron.gif}
+## "ÑÑÒÐ°ÑÑÐ»ÑÐŒÐŽÐ°Ñ" ## green_title ## h_ser ##
+_httpiconhser_ [l=kk] {_httpimg_/kk/h\_ser.gif}
+_widthhser_ [l=kk] {200}
+_heighthser_ [l=kk] {57}
+## "ÑÐµÑÐžÑÐ»Ð°Ñ" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=ky] {_httpimg_/ky/tsergr.gif}
+_httpicontserof_ [l=ky] {_httpimg_/ky/tserof.gif}
+_httpicontseron_ [l=ky] {_httpimg_/ky/tseron.gif}
+## "ÑÐµÑÐžÑÐ»Ð°Ñ" ## green_title ## h_ser ##
+_httpiconhser_ [l=ky] {_httpimg_/ky/h\_ser.gif}
+_widthhser_ [l=ky] {200}
+_heighthser_ [l=ky] {57}
+## "izdevumi" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=lv] {_httpimg_/lv/tsergr.gif}
+_httpicontserof_ [l=lv] {_httpimg_/lv/tserof.gif}
+_httpicontseron_ [l=lv] {_httpimg_/lv/tseron.gif}
+## "izdevumi" ## green_title ## h_ser ##
+_httpiconhser_ [l=lv] {_httpimg_/lv/h\_ser.gif}
+_widthhser_ [l=lv] {200}
+_heighthser_ [l=lv] {57}
+## "TÄnga Pukapuka" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=mi] {_httpimg_/mi/tsergr.gif}
+_httpicontserof_ [l=mi] {_httpimg_/mi/tserof.gif}
+_httpicontseron_ [l=mi] {_httpimg_/mi/tseron.gif}
+## "tÄnga pukapuka" ## green_title ## h_ser ##
+_httpiconhser_ [l=mi] {_httpimg_/mi/h\_ser.gif}
+_widthhser_ [l=mi] {200}
+_heighthser_ [l=mi] {57}
+## "Ð±Ò¯Ð»Ð³Ò¯Ò¯ÐŽ" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=mn] {_httpimg_/mn/tsergr.gif}
+_httpicontserof_ [l=mn] {_httpimg_/mn/tserof.gif}
+_httpicontseron_ [l=mn] {_httpimg_/mn/tseron.gif}
+## "ÑÑÐ²ÑÐ°Ð»ÑÑÐŽ" ## green_title ## h_ser ##
+_httpiconhser_ [l=mn] {_httpimg_/mn/h\_ser.gif}
+_widthhser_ [l=mn] {200}
+_heighthser_ [l=mn] {57}
+## "reksen" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=nl] {_httpimg_/nl/tsergr.gif}
+_httpicontserof_ [l=nl] {_httpimg_/nl/tserof.gif}
+_httpicontseron_ [l=nl] {_httpimg_/nl/tseron.gif}
+## "reeksen" ## green_title ## h_ser ##
+_httpiconhser_ [l=nl] {_httpimg_/nl/h\_ser.gif}
+_widthhser_ [l=nl] {200}
+_heighthser_ [l=nl] {57}
+## "serie" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=pl] {_httpimg_/pl/tsergr.gif}
+_httpicontserof_ [l=pl] {_httpimg_/pl/tserof.gif}
+_httpicontseron_ [l=pl] {_httpimg_/pl/tseron.gif}
+## "serie" ## green_title ## h_ser ##
+_httpiconhser_ [l=pl] {_httpimg_/pl/h\_ser.gif}
+_widthhser_ [l=pl] {200}
+_heighthser_ [l=pl] {57}
+## "sÃ©ries" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=pt-br] {_httpimg_/pt-br/tsergr.gif}
+_httpicontserof_ [l=pt-br] {_httpimg_/pt-br/tserof.gif}
+_httpicontseron_ [l=pt-br] {_httpimg_/pt-br/tseron.gif}
+## "sÃ©ries" ## green_title ## h_ser ##
+_httpiconhser_ [l=pt-br] {_httpimg_/pt-br/h\_ser.gif}
+_widthhser_ [l=pt-br] {200}
+_heighthser_ [l=pt-br] {57}
+## "sÃ©ries" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=pt-pt] {_httpimg_/pt-pt/tsergr.gif}
+_httpicontserof_ [l=pt-pt] {_httpimg_/pt-pt/tserof.gif}
+_httpicontseron_ [l=pt-pt] {_httpimg_/pt-pt/tseron.gif}
+## "sÃ©ries" ## green_title ## h_ser ##
+_httpiconhser_ [l=pt-pt] {_httpimg_/pt-pt/h\_ser.gif}
+_widthhser_ [l=pt-pt] {200}
+_heighthser_ [l=pt-pt] {57}
+## "Ð²ÑÐ¿ÑÑÐºÐž" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=ru] {_httpimg_/ru/tsergr.gif}
+_httpicontserof_ [l=ru] {_httpimg_/ru/tserof.gif}
+_httpicontseron_ [l=ru] {_httpimg_/ru/tseron.gif}
+## "Ð²ÑÐ¿ÑÑÐºÐž" ## green_title ## h_ser ##
+_httpiconhser_ [l=ru] {_httpimg_/ru/h\_ser.gif}
+_widthhser_ [l=ru] {200}
+_heighthser_ [l=ru] {57}
+## "edicije" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=sr] {_httpimg_/sr/tsergr.gif}
+_httpicontserof_ [l=sr] {_httpimg_/sr/tserof.gif}
+_httpicontseron_ [l=sr] {_httpimg_/sr/tseron.gif}
+## "edicije" ## green_title ## h_ser ##
+_httpiconhser_ [l=sr] {_httpimg_/sr/h\_ser.gif}
+_widthhser_ [l=sr] {200}
+_heighthser_ [l=sr] {57}
+## "àž­àžàžžàžàž£àž¡" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=th] {_httpimg_/th/tsergr.gif}
+_httpicontserof_ [l=th] {_httpimg_/th/tserof.gif}
+_httpicontseron_ [l=th] {_httpimg_/th/tseron.gif}
+## "àž¥àž³àžàž±àž" ## green_title ## h_ser ##
+_httpiconhser_ [l=th] {_httpimg_/th/h\_ser.gif}
+_widthhser_ [l=th] {200}
+_heighthser_ [l=th] {57}
+## "seriler" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=tr] {_httpimg_/tr/tsergr.gif}
+_httpicontserof_ [l=tr] {_httpimg_/tr/tserof.gif}
+_httpicontseron_ [l=tr] {_httpimg_/tr/tseron.gif}
+## "seriler" ## green_title ## h_ser ##
+_httpiconhser_ [l=tr] {_httpimg_/tr/h\_ser.gif}
+_widthhser_ [l=tr] {200}
+_heighthser_ [l=tr] {57}
+## "ÑÐµÑÑÑ" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=uk] {_httpimg_/uk/tsergr.gif}
+_httpicontserof_ [l=uk] {_httpimg_/uk/tserof.gif}
+_httpicontseron_ [l=uk] {_httpimg_/uk/tseron.gif}
+## "ÑÐµÑÑÑ" ## green_title ## h_ser ##
+_httpiconhser_ [l=uk] {_httpimg_/uk/h\_ser.gif}
+_widthhser_ [l=uk] {200}
+_heighthser_ [l=uk] {57}
+## "nhÃ³m" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=vi] {_httpimg_/vi/tsergr.gif}
+_httpicontserof_ [l=vi] {_httpimg_/vi/tserof.gif}
+_httpicontseron_ [l=vi] {_httpimg_/vi/tseron.gif}
+## "nhÃ³m" ## green_title ## h_ser ##
+_httpiconhser_ [l=vi] {_httpimg_/vi/h\_ser.gif}
+_widthhser_ [l=vi] {200}
+_heighthser_ [l=vi] {57}
+## "é" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=zh] {_httpimg_/zh/tsergr.gif}
+_httpicontserof_ [l=zh] {_httpimg_/zh/tserof.gif}
+_httpicontseron_ [l=zh] {_httpimg_/zh/tseron.gif}
+## "äžä¹Š" ## green_title ## h_ser ##
+_httpiconhser_ [l=zh] {_httpimg_/zh/h\_ser.gif}
+_widthhser_ [l=zh] {200}
+_heighthser_ [l=zh] {57}
+## "éå¢å" ## nav_bar_button ## tser ##
+_httpicontsergr_ [l=zh-tr] {_httpimg_/zh-tr/tsergr.gif}
+_httpicontserof_ [l=zh-tr] {_httpimg_/zh-tr/tserof.gif}
+_httpicontseron_ [l=zh-tr] {_httpimg_/zh-tr/tseron.gif}
+## "éå¢å" ## green_title ## h_ser ##
+_httpiconhser_ [l=zh-tr] {_httpimg_/zh-tr/h\_ser.gif}
+_widthhser_ [l=zh-tr] {200}
+_heighthser_ [l=zh-tr] {57}
+
+## "filenames" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ {_httpimg_/en/tsrcgr.gif}
+_httpicontsrcof_ {_httpimg_/en/tsrcof.gif}
+_httpicontsrcon_ {_httpimg_/en/tsrcon.gif}
+## "filenames" ## green_title ## h_src ##
+_httpiconhsrc_ {_httpimg_/en/h\_src.gif}
+_widthhsrc_ {200}
+_heighthsrc_ {57}
+## "Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙ" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=ar] {_httpimg_/ar/tsrcgr.gif}
+_httpicontsrcof_ [l=ar] {_httpimg_/ar/tsrcof.gif}
+_httpicontsrcon_ [l=ar] {_httpimg_/ar/tsrcon.gif}
+## "Ø§Ø³Ù
+Ø§Ø¡ Ø§ÙÙ
+ÙÙØ§Øª" ## green_title ## h_src ##
+_httpiconhsrc_ [l=ar] {_httpimg_/ar/h\_src.gif}
+_widthhsrc_ [l=ar] {200}
+_heighthsrc_ [l=ar] {57}
+## "àŠ«àŠŸàŠàŠ²à§àŠ° àŠšàŠŸàŠ®" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=bn] {_httpimg_/bn/tsrcgr.gif}
+_httpicontsrcof_ [l=bn] {_httpimg_/bn/tsrcof.gif}
+_httpicontsrcon_ [l=bn] {_httpimg_/bn/tsrcon.gif}
+## "àŠ«àŠŸàŠàŠ²à§àŠ° àŠšàŠŸàŠ®àŠà§àŠ²àŠ¿" ## green_title ## h_src ##
+_httpiconhsrc_ [l=bn] {_httpimg_/bn/h\_src.gif}
+_widthhsrc_ [l=bn] {200}
+_heighthsrc_ [l=bn] {57}
+## "noms de fitxers" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=ca] {_httpimg_/ca/tsrcgr.gif}
+_httpicontsrcof_ [l=ca] {_httpimg_/ca/tsrcof.gif}
+_httpicontsrcon_ [l=ca] {_httpimg_/ca/tsrcon.gif}
+## "noms de fitxers" ## green_title ## h_src ##
+_httpiconhsrc_ [l=ca] {_httpimg_/ca/h\_src.gif}
+_widthhsrc_ [l=ca] {200}
+_heighthsrc_ [l=ca] {57}
+## "nÃ¡zvy souborÅ¯" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=cs] {_httpimg_/cs/tsrcgr.gif}
+_httpicontsrcof_ [l=cs] {_httpimg_/cs/tsrcof.gif}
+_httpicontsrcon_ [l=cs] {_httpimg_/cs/tsrcon.gif}
+## "nÃ¡zvy souborÅ¯" ## green_title ## h_src ##
+_httpiconhsrc_ [l=cs] {_httpimg_/cs/h\_src.gif}
+_widthhsrc_ [l=cs] {200}
+_heighthsrc_ [l=cs] {57}
+## "Î¿ÎœÏÎŒÎ±ÏÎ± Î±ÏÏÎµÎ¯ÏÎœ" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=el] {_httpimg_/el/tsrcgr.gif}
+_httpicontsrcof_ [l=el] {_httpimg_/el/tsrcof.gif}
+_httpicontsrcon_ [l=el] {_httpimg_/el/tsrcon.gif}
+## "Î¿ÎœÏÎŒÎ±ÏÎ± Î±ÏÏÎµÎ¯ÏÎœ" ## green_title ## h_src ##
+_httpiconhsrc_ [l=el] {_httpimg_/el/h\_src.gif}
+_widthhsrc_ [l=el] {200}
+_heighthsrc_ [l=el] {57}
+## "fuente" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=es] {_httpimg_/es/tsrcgr.gif}
+_httpicontsrcof_ [l=es] {_httpimg_/es/tsrcof.gif}
+_httpicontsrcon_ [l=es] {_httpimg_/es/tsrcon.gif}
+## "fuente" ## green_title ## h_src ##
+_httpiconhsrc_ [l=es] {_httpimg_/es/h\_src.gif}
+_widthhsrc_ [l=es] {200}
+_heighthsrc_ [l=es] {57}
+## "ÙØ§Ù
+ ÙŸØ±ÙÙØ¯Ù ÙØ§" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=fa] {_httpimg_/fa/tsrcgr.gif}
+_httpicontsrcof_ [l=fa] {_httpimg_/fa/tsrcof.gif}
+_httpicontsrcon_ [l=fa] {_httpimg_/fa/tsrcon.gif}
+## "ÙØ§Ù
+ ÙŸØ±ÙÙØ¯Ù ÙØ§" ## green_title ## h_src ##
+_httpiconhsrc_ [l=fa] {_httpimg_/fa/h\_src.gif}
+_widthhsrc_ [l=fa] {200}
+_heighthsrc_ [l=fa] {57}
+## "tiedostonimet" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=fi] {_httpimg_/fi/tsrcgr.gif}
+_httpicontsrcof_ [l=fi] {_httpimg_/fi/tsrcof.gif}
+_httpicontsrcon_ [l=fi] {_httpimg_/fi/tsrcon.gif}
+## "tiedostonimet" ## green_title ## h_src ##
+_httpiconhsrc_ [l=fi] {_httpimg_/fi/h\_src.gif}
+_widthhsrc_ [l=fi] {200}
+_heighthsrc_ [l=fi] {57}
+## "noms de fichiers" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=fr] {_httpimg_/fr/tsrcgr.gif}
+_httpicontsrcof_ [l=fr] {_httpimg_/fr/tsrcof.gif}
+_httpicontsrcon_ [l=fr] {_httpimg_/fr/tsrcon.gif}
+## "noms de fichiers" ## green_title ## h_src ##
+_httpiconhsrc_ [l=fr] {_httpimg_/fr/h\_src.gif}
+_widthhsrc_ [l=fr] {200}
+_heighthsrc_ [l=fr] {57}
+## "nomes de ficheiros" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=gl] {_httpimg_/gl/tsrcgr.gif}
+_httpicontsrcof_ [l=gl] {_httpimg_/gl/tsrcof.gif}
+_httpicontsrcon_ [l=gl] {_httpimg_/gl/tsrcon.gif}
+## "nomes de ficheiros" ## green_title ## h_src ##
+_httpiconhsrc_ [l=gl] {_httpimg_/gl/h\_src.gif}
+_widthhsrc_ [l=gl] {200}
+_heighthsrc_ [l=gl] {57}
+## "nazivi datoteka" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=hr] {_httpimg_/hr/tsrcgr.gif}
+_httpicontsrcof_ [l=hr] {_httpimg_/hr/tsrcof.gif}
+_httpicontsrcon_ [l=hr] {_httpimg_/hr/tsrcon.gif}
+## "datoteke" ## green_title ## h_src ##
+_httpiconhsrc_ [l=hr] {_httpimg_/hr/h_src.gif}
+_widthhsrc_ [l=hr] {200}
+_heighthsrc_ [l=hr] {57}
+## "ÖÕ¡ÕµÕ¬Õ« Õ¡Õ¶ÕžÖÕ¶Õ¶Õ¥Ö" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=hy] {_httpimg_/hy/tsrcgr.gif}
+_httpicontsrcof_ [l=hy] {_httpimg_/hy/tsrcof.gif}
+_httpicontsrcon_ [l=hy] {_httpimg_/hy/tsrcon.gif}
+## "ÖÕ¡ÕµÕ¬Õ« Õ¡Õ¶ÕžÖÕ¶Õ¶Õ¥Ö" ## green_title ## h_src ##
+_httpiconhsrc_ [l=hy] {_httpimg_/hy/h\_src.gif}
+_widthhsrc_ [l=hy] {200}
+_heighthsrc_ [l=hy] {57}
+## "nama file" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=id] {_httpimg_/id/tsrcgr.gif}
+_httpicontsrcof_ [l=id] {_httpimg_/id/tsrcof.gif}
+_httpicontsrcon_ [l=id] {_httpimg_/id/tsrcon.gif}
+## "nama file" ## green_title ## h_src ##
+_httpiconhsrc_ [l=id] {_httpimg_/id/h\_src.gif}
+_widthhsrc_ [l=id] {200}
+_heighthsrc_ [l=id] {57}
+## "nomi dei file" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=it] {_httpimg_/it/tsrcgr.gif}
+_httpicontsrcof_ [l=it] {_httpimg_/it/tsrcof.gif}
+_httpicontsrcon_ [l=it] {_httpimg_/it/tsrcon.gif}
+## "nomi dei file" ## green_title ## h_src ##
+_httpiconhsrc_ [l=it] {_httpimg_/it/h\_src.gif}
+_widthhsrc_ [l=it] {200}
+_heighthsrc_ [l=it] {57}
+## "ãã¡ã€ã«å" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=ja] {_httpimg_/ja/tsrcgr.gif}
+_httpicontsrcof_ [l=ja] {_httpimg_/ja/tsrcof.gif}
+_httpicontsrcon_ [l=ja] {_httpimg_/ja/tsrcon.gif}
+## "ãã¡ã€ã«å" ## green_title ## h_src ##
+_httpiconhsrc_ [l=ja] {_httpimg_/ja/h\_src.gif}
+_widthhsrc_ [l=ja] {200}
+_heighthsrc_ [l=ja] {57}
+## "á€ááááááá¡ á¡áá®ááááá" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=ka] {_httpimg_/ka/tsrcgr.gif}
+_httpicontsrcof_ [l=ka] {_httpimg_/ka/tsrcof.gif}
+_httpicontsrcon_ [l=ka] {_httpimg_/ka/tsrcon.gif}
+## "á€ááááááá¡\ná¡áá®ááááá" ## green_title ## h_src ##
+_httpiconhsrc_ [l=ka] {_httpimg_/ka/h\_src.gif}
+_widthhsrc_ [l=ka] {258}
+_heighthsrc_ [l=ka] {74}
+## "ÑÐ°Ð¹Ð»ÐŽÑÐœ Ð°ÑÑ" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=ky] {_httpimg_/ky/tsrcgr.gif}
+_httpicontsrcof_ [l=ky] {_httpimg_/ky/tsrcof.gif}
+_httpicontsrcon_ [l=ky] {_httpimg_/ky/tsrcon.gif}
+## "ÑÐ°Ð¹Ð»ÐŽÑÐœ Ð°ÑÑÐ°ÑÑ" ## green_title ## h_src ##
+_httpiconhsrc_ [l=ky] {_httpimg_/ky/h\_src.gif}
+_widthhsrc_ [l=ky] {200}
+_heighthsrc_ [l=ky] {57}
+## "datnesvÄrdi" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=lv] {_httpimg_/lv/tsrcgr.gif}
+_httpicontsrcof_ [l=lv] {_httpimg_/lv/tsrcof.gif}
+_httpicontsrcon_ [l=lv] {_httpimg_/lv/tsrcon.gif}
+## "datnesvÄrdi" ## green_title ## h_src ##
+_httpiconhsrc_ [l=lv] {_httpimg_/lv/h\_src.gif}
+_widthhsrc_ [l=lv] {200}
+_heighthsrc_ [l=lv] {57}
+## "ingoa kÅnae" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=mi] {_httpimg_/mi/tsrcgr.gif}
+_httpicontsrcof_ [l=mi] {_httpimg_/mi/tsrcof.gif}
+_httpicontsrcon_ [l=mi] {_httpimg_/mi/tsrcon.gif}
+## "ingoa kÅnae" ## green_title ## h_src ##
+_httpiconhsrc_ [l=mi] {_httpimg_/mi/h\_src.gif}
+_widthhsrc_ [l=mi] {200}
+_heighthsrc_ [l=mi] {57}
+## "ÑÐ°Ð¹Ð»ÑÐœ ÐœÑÑÒ¯Ò¯ÐŽ" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=mn] {_httpimg_/mn/tsrcgr.gif}
+_httpicontsrcof_ [l=mn] {_httpimg_/mn/tsrcof.gif}
+_httpicontsrcon_ [l=mn] {_httpimg_/mn/tsrcon.gif}
+## "ÑÐ°Ð¹Ð»ÑÐœ ÐœÑÑÑ" ## green_title ## h_src ##
+_httpiconhsrc_ [l=mn] {_httpimg_/mn/h\_src.gif}
+_widthhsrc_ [l=mn] {200}
+_heighthsrc_ [l=mn] {57}
+## "nazwy plikÃ³w" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=pl] {_httpimg_/pl/tsrcgr.gif}
+_httpicontsrcof_ [l=pl] {_httpimg_/pl/tsrcof.gif}
+_httpicontsrcon_ [l=pl] {_httpimg_/pl/tsrcon.gif}
+## "nazwy plikÃ³w" ## green_title ## h_src ##
+_httpiconhsrc_ [l=pl] {_httpimg_/pl/h\_src.gif}
+_widthhsrc_ [l=pl] {200}
+_heighthsrc_ [l=pl] {57}
+## "nomes de ficheiros" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=pt-pt] {_httpimg_/pt-pt/tsrcgr.gif}
+_httpicontsrcof_ [l=pt-pt] {_httpimg_/pt-pt/tsrcof.gif}
+_httpicontsrcon_ [l=pt-pt] {_httpimg_/pt-pt/tsrcon.gif}
+## "ficheiros" ## green_title ## h_src ##
+_httpiconhsrc_ [l=pt-pt] {_httpimg_/pt-pt/h\_src.gif}
+_widthhsrc_ [l=pt-pt] {200}
+_heighthsrc_ [l=pt-pt] {57}
+## "ÐžÐŒÐµÐœÐ° ÑÐ°Ð¹Ð»ÐŸÐ²" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=ru] {_httpimg_/ru/tsrcgr.gif}
+_httpicontsrcof_ [l=ru] {_httpimg_/ru/tsrcof.gif}
+_httpicontsrcon_ [l=ru] {_httpimg_/ru/tsrcon.gif}
+## "ÐžÐŒÐµÐœÐ° ÑÐ°Ð¹Ð»ÐŸÐ²" ## green_title ## h_src ##
+_httpiconhsrc_ [l=ru] {_httpimg_/ru/h\_src.gif}
+_widthhsrc_ [l=ru] {200}
+_heighthsrc_ [l=ru] {57}
+## "imena datoteka" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=sr] {_httpimg_/sr/tsrcgr.gif}
+_httpicontsrcof_ [l=sr] {_httpimg_/sr/tsrcof.gif}
+_httpicontsrcon_ [l=sr] {_httpimg_/sr/tsrcon.gif}
+## "imena datoteka" ## green_title ## h_src ##
+_httpiconhsrc_ [l=sr] {_httpimg_/sr/h\_src.gif}
+_widthhsrc_ [l=sr] {200}
+_heighthsrc_ [l=sr] {57}
+## "àžàž·à¹àž­à¹àžàž¥à¹" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=th] {_httpimg_/th/tsrcgr.gif}
+_httpicontsrcof_ [l=th] {_httpimg_/th/tsrcof.gif}
+_httpicontsrcon_ [l=th] {_httpimg_/th/tsrcon.gif}
+## "àžàž·à¹àž­àž«àž¡àž§àžà¹àž­àžàžªàž²àž£" ## green_title ## h_src ##
+_httpiconhsrc_ [l=th] {_httpimg_/th/h\_src.gif}
+_widthhsrc_ [l=th] {200}
+_heighthsrc_ [l=th] {57}
+## "dosya adlarÄ±" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=tr] {_httpimg_/tr/tsrcgr.gif}
+_httpicontsrcof_ [l=tr] {_httpimg_/tr/tsrcof.gif}
+_httpicontsrcon_ [l=tr] {_httpimg_/tr/tsrcon.gif}
+## "dosya adlarÄ±" ## green_title ## h_src ##
+_httpiconhsrc_ [l=tr] {_httpimg_/tr/h\_src.gif}
+_widthhsrc_ [l=tr] {200}
+_heighthsrc_ [l=tr] {57}
+## "ÑÐŒÐµÐœÐ° ÑÐ°Ð¹Ð»ÑÐ²" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=uk] {_httpimg_/uk/tsrcgr.gif}
+_httpicontsrcof_ [l=uk] {_httpimg_/uk/tsrcof.gif}
+_httpicontsrcon_ [l=uk] {_httpimg_/uk/tsrcon.gif}
+## "ÑÐŒÐµÐœÐ° ÑÐ°Ð¹Ð»ÑÐ²" ## green_title ## h_src ##
+_httpiconhsrc_ [l=uk] {_httpimg_/uk/h\_src.gif}
+_widthhsrc_ [l=uk] {200}
+_heighthsrc_ [l=uk] {57}
+## "tÃªn táº­p tin" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=vi] {_httpimg_/vi/tsrcgr.gif}
+_httpicontsrcof_ [l=vi] {_httpimg_/vi/tsrcof.gif}
+_httpicontsrcon_ [l=vi] {_httpimg_/vi/tsrcon.gif}
+## "tÃªn táº­p tin" ## green_title ## h_src ##
+_httpiconhsrc_ [l=vi] {_httpimg_/vi/h\_src.gif}
+_widthhsrc_ [l=vi] {200}
+_heighthsrc_ [l=vi] {57}
+## "æä»¶å" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=zh] {_httpimg_/zh/tsrcgr.gif}
+_httpicontsrcof_ [l=zh] {_httpimg_/zh/tsrcof.gif}
+_httpicontsrcon_ [l=zh] {_httpimg_/zh/tsrcon.gif}
+## "æä»¶å" ## green_title ## h_src ##
+_httpiconhsrc_ [l=zh] {_httpimg_/zh/h\_src.gif}
+_widthhsrc_ [l=zh] {200}
+_heighthsrc_ [l=zh] {57}
+## "æªæ¡åçš±" ## nav_bar_button ## tsrc ##
+_httpicontsrcgr_ [l=zh-tr] {_httpimg_/zh-tr/tsrcgr.gif}
+_httpicontsrcof_ [l=zh-tr] {_httpimg_/zh-tr/tsrcof.gif}
+_httpicontsrcon_ [l=zh-tr] {_httpimg_/zh-tr/tsrcon.gif}
+## "æªæ¡åçš±" ## green_title ## h_src ##
+_httpiconhsrc_ [l=zh-tr] {_httpimg_/zh-tr/h\_src.gif}
+_widthhsrc_ [l=zh-tr] {200}
+_heighthsrc_ [l=zh-tr] {57}
+
+
+## "subjects" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ {_httpimg_/en/tsubjgr.gif}
+_httpicontsubjon_ {_httpimg_/en/tsubjon.gif}
+_httpicontsubjof_ {_httpimg_/en/tsubjof.gif}
+## "subjects" ## green_title ## h_subj ##
+_httpiconhsubj_ {_httpimg_/en/h\_subj.gif}
+_widthhsubj_ {200}
+_heighthsubj_ {57}
+## "Ø§ÙÙ
+ÙØ¶ÙØ¹Ø§Øª" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=ar] {_httpimg_/ar/tsubjgr.gif}
+_httpicontsubjon_ [l=ar] {_httpimg_/ar/tsubjon.gif}
+_httpicontsubjof_ [l=ar] {_httpimg_/ar/tsubjof.gif}
+## "Ø§ÙÙ
+ÙØ¶ÙØ¹Ø§Øª" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=ar] {_httpimg_/ar/h\_subj.gif}
+_widthhsubj_ [l=ar] {200}
+_heighthsubj_ [l=ar] {57}
+## "àŠ¬àŠ¿àŠ·à§àŠà§àŠ²àŠ¿" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=bn] {_httpimg_/bn/tsubjgr.gif}
+_httpicontsubjon_ [l=bn] {_httpimg_/bn/tsubjon.gif}
+_httpicontsubjof_ [l=bn] {_httpimg_/bn/tsubjof.gif}
+## "àŠ¬àŠ¿àŠ·à§àŠà§àŠ²àŠ¿" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=bn] {_httpimg_/bn/h\_subj.gif}
+_widthhsubj_ [l=bn] {200}
+_heighthsubj_ [l=bn] {57}
+## "matÃšries" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=ca] {_httpimg_/ca/tsubjgr.gif}
+_httpicontsubjon_ [l=ca] {_httpimg_/ca/tsubjon.gif}
+_httpicontsubjof_ [l=ca] {_httpimg_/ca/tsubjof.gif}
+## "matÃšries" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=ca] {_httpimg_/ca/h\_subj.gif}
+_widthhsubj_ [l=ca] {200}
+_heighthsubj_ [l=ca] {57}
+## "pÅedmÄt" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=cs] {_httpimg_/cs/tsubjgr.gif}
+_httpicontsubjon_ [l=cs] {_httpimg_/cs/tsubjon.gif}
+_httpicontsubjof_ [l=cs] {_httpimg_/cs/tsubjof.gif}
+## "pÅedmÄty" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=cs] {_httpimg_/cs/h\_subj.gif}
+_widthhsubj_ [l=cs] {200}
+_heighthsubj_ [l=cs] {57}
+## "sparten" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=de] {_httpimg_/de/tsubjgr.gif}
+_httpicontsubjon_ [l=de] {_httpimg_/de/tsubjon.gif}
+_httpicontsubjof_ [l=de] {_httpimg_/de/tsubjof.gif}
+## "sparten" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=de] {_httpimg_/de/h\_subj.gif}
+_widthhsubj_ [l=de] {200}
+_heighthsubj_ [l=de] {57}
+## "ÎžÎµÎŒÎ±ÏÎ¹ÎºÎ­Ï ÎºÎ±ÏÎ·Î³Î¿ÏÎ¯ÎµÏ" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=el] {_httpimg_/el/tsubjgr.gif}
+_httpicontsubjon_ [l=el] {_httpimg_/el/tsubjon.gif}
+_httpicontsubjof_ [l=el] {_httpimg_/el/tsubjof.gif}
+## "ÎžÎµÎŒÎ±ÏÎ¹ÎºÎ­Ï ÎºÎ±ÏÎ·Î³Î¿ÏÎ¯ÎµÏ" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=el] {_httpimg_/el/h\_subj.gif}
+_widthhsubj_ [l=el] {200}
+_heighthsubj_ [l=el] {57}
+## "temas" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=es] {_httpimg_/es/tsubjgr.gif}
+_httpicontsubjon_ [l=es] {_httpimg_/es/tsubjon.gif}
+_httpicontsubjof_ [l=es] {_httpimg_/es/tsubjof.gif}
+## "temas" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=es] {_httpimg_/es/h\_subj.gif}
+_widthhsubj_ [l=es] {200}
+_heighthsubj_ [l=es] {57}
+## "Ù
+ÙØ¶ÙØ¹Ø§Øª" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=fa] {_httpimg_/fa/tsubjgr.gif}
+_httpicontsubjon_ [l=fa] {_httpimg_/fa/tsubjon.gif}
+_httpicontsubjof_ [l=fa] {_httpimg_/fa/tsubjof.gif}
+## "Ù
+ÙØ¶ÙØ¹Ø§Øª" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=fa] {_httpimg_/fa/h\_subj.gif}
+_widthhsubj_ [l=fa] {200}
+_heighthsubj_ [l=fa] {57}
+## "aiheet" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=fi] {_httpimg_/fi/tsubjgr.gif}
+_httpicontsubjon_ [l=fi] {_httpimg_/fi/tsubjon.gif}
+_httpicontsubjof_ [l=fi] {_httpimg_/fi/tsubjof.gif}
+## "aiheet" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=fi] {_httpimg_/fi/h\_subj.gif}
+_widthhsubj_ [l=fi] {200}
+_heighthsubj_ [l=fi] {57}
+## "thÃšmes" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=fr] {_httpimg_/fr/tsubjgr.gif}
+_httpicontsubjon_ [l=fr] {_httpimg_/fr/tsubjon.gif}
+_httpicontsubjof_ [l=fr] {_httpimg_/fr/tsubjof.gif}
+## "thÃšmes" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=fr] {_httpimg_/fr/h\_subj.gif}
+_widthhsubj_ [l=fr] {200}
+_heighthsubj_ [l=fr] {57}
+## "materias" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=gl] {_httpimg_/gl/tsubjgr.gif}
+_httpicontsubjon_ [l=gl] {_httpimg_/gl/tsubjon.gif}
+_httpicontsubjof_ [l=gl] {_httpimg_/gl/tsubjof.gif}
+## "materias" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=gl] {_httpimg_/gl/h\_subj.gif}
+_widthhsubj_ [l=gl] {200}
+_heighthsubj_ [l=gl] {57}
+## "××××©×× " ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=he] {_httpimg_/he/tsubjgr.gif}
+_httpicontsubjon_ [l=he] {_httpimg_/he/tsubjon.gif}
+_httpicontsubjof_ [l=he] {_httpimg_/he/tsubjof.gif}
+## "××××©×× " ## green_title ## h_subj ##
+_httpiconhsubj_ [l=he] {_httpimg_/he/h\_subj.gif}
+_widthhsubj_ [l=he] {200}
+_heighthsubj_ [l=he] {57}
+## "podruÄja" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=hr] {_httpimg_/hr/tsubjgr.gif}
+_httpicontsubjon_ [l=hr] {_httpimg_/hr/tsubjon.gif}
+_httpicontsubjof_ [l=hr] {_httpimg_/hr/tsubjof.gif}
+## "podruÄja" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=hr] {_httpimg_/hr/h\_subj.gif}
+_widthhsubj_ [l=hr] {200}
+_heighthsubj_ [l=hr] {57}
+## "Õ¡ÕŒÕ¡ÖÕ¯Õ¡Õ¶Õ¥Ö" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=hy] {_httpimg_/hy/tsubjgr.gif}
+_httpicontsubjon_ [l=hy] {_httpimg_/hy/tsubjon.gif}
+_httpicontsubjof_ [l=hy] {_httpimg_/hy/tsubjof.gif}
+## "Õ¡ÕŒÕ¡ÖÕ¯Õ¡Õ¶Õ¥Ö" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=hy] {_httpimg_/hy/h\_subj.gif}
+_widthhsubj_ [l=hy] {200}
+_heighthsubj_ [l=hy] {57}
+## "subyek" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=id] {_httpimg_/id/tsubjgr.gif}
+_httpicontsubjon_ [l=id] {_httpimg_/id/tsubjon.gif}
+_httpicontsubjof_ [l=id] {_httpimg_/id/tsubjof.gif}
+## "subyek" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=id] {_httpimg_/id/h\_subj.gif}
+_widthhsubj_ [l=id] {200}
+_heighthsubj_ [l=id] {57}
+## "soggetti" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=it] {_httpimg_/it/tsubjgr.gif}
+_httpicontsubjon_ [l=it] {_httpimg_/it/tsubjon.gif}
+_httpicontsubjof_ [l=it] {_httpimg_/it/tsubjof.gif}
+## "soggetto" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=it] {_httpimg_/it/h\_subj.gif}
+_widthhsubj_ [l=it] {200}
+_heighthsubj_ [l=it] {57}
+## "äž»é¡" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=ja] {_httpimg_/ja/tsubjgr.gif}
+_httpicontsubjon_ [l=ja] {_httpimg_/ja/tsubjon.gif}
+_httpicontsubjof_ [l=ja] {_httpimg_/ja/tsubjof.gif}
+## "á¡áááááá ááá á á£áá ááááá" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=ka] {_httpimg_/ka/tsubjgr.gif}
+_httpicontsubjon_ [l=ka] {_httpimg_/ka/tsubjon.gif}
+_httpicontsubjof_ [l=ka] {_httpimg_/ka/tsubjof.gif}
+## "á¡áááááá ááá\ná á£áá ááááá" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=ka] {_httpimg_/ka/h\_subj.gif}
+_widthhsubj_ [l=ka] {258}
+_heighthsubj_ [l=ka] {74}
+## "ÐºÓ©ÑÑÐµÑÐºÑÑ" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=kk] {_httpimg_/kk/tsubjgr.gif}
+_httpicontsubjon_ [l=kk] {_httpimg_/kk/tsubjon.gif}
+_httpicontsubjof_ [l=kk] {_httpimg_/kk/tsubjof.gif}
+## "ÐºÓ©ÑÑÐµÑÐºÑÑ" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=kk] {_httpimg_/kk/h\_subj.gif}
+_widthhsubj_ [l=kk] {200}
+_heighthsubj_ [l=kk] {57}
+## "ÐŽÐžÑÑÐžÐ¿Ð»ÐžÐœÐ°Ð»Ð°Ñ" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=ky] {_httpimg_/ky/tsubjgr.gif}
+_httpicontsubjon_ [l=ky] {_httpimg_/ky/tsubjon.gif}
+_httpicontsubjof_ [l=ky] {_httpimg_/ky/tsubjof.gif}
+## "ÐŽÐžÑÑÐžÐ¿Ð»ÐžÐœÐ°Ð»Ð°Ñ" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=ky] {_httpimg_/ky/h\_subj.gif}
+_widthhsubj_ [l=ky] {200}
+_heighthsubj_ [l=ky] {57}
+## "priekÅ¡meti" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=lv] {_httpimg_/lv/tsubjgr.gif}
+_httpicontsubjon_ [l=lv] {_httpimg_/lv/tsubjon.gif}
+_httpicontsubjof_ [l=lv] {_httpimg_/lv/tsubjof.gif}
+## "priekÅ¡meti" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=lv] {_httpimg_/lv/h\_subj.gif}
+_widthhsubj_ [l=lv] {200}
+_heighthsubj_ [l=lv] {57}
+## "kaupapa" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=mi] {_httpimg_/mi/tsubjgr.gif}
+_httpicontsubjon_ [l=mi] {_httpimg_/mi/tsubjon.gif}
+_httpicontsubjof_ [l=mi] {_httpimg_/mi/tsubjof.gif}
+## "kaupapa" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=mi] {_httpimg_/mi/h\_subj.gif}
+_widthhsubj_ [l=mi] {200}
+_heighthsubj_ [l=mi] {57}
+## "ÑÑÐ³ÑÑÐŽ" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=mn] {_httpimg_/mn/tsubjgr.gif}
+_httpicontsubjon_ [l=mn] {_httpimg_/mn/tsubjon.gif}
+_httpicontsubjof_ [l=mn] {_httpimg_/mn/tsubjof.gif}
+## "Ð°Ð³ÑÑÐ»Ð³ÑÑÐŽ" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=mn] {_httpimg_/mn/h\_subj.gif}
+_widthhsubj_ [l=mn] {200}
+_heighthsubj_ [l=mn] {57}
+## "onderwerpen" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=nl] {_httpimg_/nl/tsubjgr.gif}
+_httpicontsubjon_ [l=nl] {_httpimg_/nl/tsubjon.gif}
+_httpicontsubjof_ [l=nl] {_httpimg_/nl/tsubjof.gif}
+## "onderwerpen" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=nl] {_httpimg_/nl/h\_subj.gif}
+_widthhsubj_ [l=nl] {200}
+_heighthsubj_ [l=nl] {57}
+## "tematy" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=pl] {_httpimg_/pl/tsubjgr.gif}
+_httpicontsubjon_ [l=pl] {_httpimg_/pl/tsubjon.gif}
+_httpicontsubjof_ [l=pl] {_httpimg_/pl/tsubjof.gif}
+## "tematy" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=pl] {_httpimg_/pl/h\_subj.gif}
+_widthhsubj_ [l=pl] {200}
+_heighthsubj_ [l=pl] {57}
+## "assuntos" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=pt-br] {_httpimg_/pt-br/tsubjgr.gif}
+_httpicontsubjon_ [l=pt-br] {_httpimg_/pt-br/tsubjon.gif}
+_httpicontsubjof_ [l=pt-br] {_httpimg_/pt-br/tsubjof.gif}
+## "assuntos" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=pt-br] {_httpimg_/pt-br/h\_subj.gif}
+_widthhsubj_ [l=pt-br] {200}
+_heighthsubj_ [l=pt-br] {57}
+## "assuntos" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=pt-pt] {_httpimg_/pt-pt/tsubjgr.gif}
+_httpicontsubjon_ [l=pt-pt] {_httpimg_/pt-pt/tsubjon.gif}
+_httpicontsubjof_ [l=pt-pt] {_httpimg_/pt-pt/tsubjof.gif}
+## "assuntos" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=pt-pt] {_httpimg_/pt-pt/h\_subj.gif}
+_widthhsubj_ [l=pt-pt] {200}
+_heighthsubj_ [l=pt-pt] {57}
+## "ÑÐºÐ°Ð·Ð°ÑÐµÐ»Ñ" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=ru] {_httpimg_/ru/tsubjgr.gif}
+_httpicontsubjon_ [l=ru] {_httpimg_/ru/tsubjon.gif}
+_httpicontsubjof_ [l=ru] {_httpimg_/ru/tsubjof.gif}
+## "ÑÐºÐ°Ð·Ð°ÑÐµÐ»Ñ" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=ru] {_httpimg_/ru/h\_subj.gif}
+_widthhsubj_ [l=ru] {200}
+_heighthsubj_ [l=ru] {57}
+## "oblasti" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=sr] {_httpimg_/sr/tsubjgr.gif}
+_httpicontsubjon_ [l=sr] {_httpimg_/sr/tsubjon.gif}
+_httpicontsubjof_ [l=sr] {_httpimg_/sr/tsubjof.gif}
+## "oblasti" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=sr] {_httpimg_/sr/h\_subj.gif}
+_widthhsubj_ [l=sr] {200}
+_heighthsubj_ [l=sr] {57}
+## "àž«àž±àž§àžà¹àž­" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=th] {_httpimg_/th/tsubjgr.gif}
+_httpicontsubjon_ [l=th] {_httpimg_/th/tsubjon.gif}
+_httpicontsubjof_ [l=th] {_httpimg_/th/tsubjof.gif}
+## "àžªàž²àžàž²àž§àžŽàžàž²" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=th] {_httpimg_/th/h\_subj.gif}
+_widthhsubj_ [l=th] {200}
+_heighthsubj_ [l=th] {57}
+## "konular" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=tr] {_httpimg_/tr/tsubjgr.gif}
+_httpicontsubjon_ [l=tr] {_httpimg_/tr/tsubjon.gif}
+_httpicontsubjof_ [l=tr] {_httpimg_/tr/tsubjof.gif}
+## "konular" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=tr] {_httpimg_/tr/h\_subj.gif}
+_widthhsubj_ [l=tr] {200}
+_heighthsubj_ [l=tr] {57}
+## "Ð¿ÑÐµÐŽÐŒÐµÑÐž" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=uk] {_httpimg_/uk/tsubjgr.gif}
+_httpicontsubjon_ [l=uk] {_httpimg_/uk/tsubjon.gif}
+_httpicontsubjof_ [l=uk] {_httpimg_/uk/tsubjof.gif}
+## "Ð¿ÑÐµÐŽÐŒÐµÑÐž" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=uk] {_httpimg_/uk/h\_subj.gif}
+_widthhsubj_ [l=uk] {200}
+_heighthsubj_ [l=uk] {57}
+## "Äá» má»¥c" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=vi] {_httpimg_/vi/tsubjgr.gif}
+_httpicontsubjon_ [l=vi] {_httpimg_/vi/tsubjon.gif}
+_httpicontsubjof_ [l=vi] {_httpimg_/vi/tsubjof.gif}
+## "Äá» má»¥c" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=vi] {_httpimg_/vi/h\_subj.gif}
+_widthhsubj_ [l=vi] {200}
+_heighthsubj_ [l=vi] {57}
+## "äž»é¢" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=zh] {_httpimg_/zh/tsubjgr.gif}
+_httpicontsubjon_ [l=zh] {_httpimg_/zh/tsubjon.gif}
+_httpicontsubjof_ [l=zh] {_httpimg_/zh/tsubjof.gif}
+## "äž»é¢" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=zh] {_httpimg_/zh/h\_subj.gif}
+_widthhsubj_ [l=zh] {200}
+_heighthsubj_ [l=zh] {57}
+## "äž»é¡" ## nav_bar_button ## tsubj ##
+_httpicontsubjgr_ [l=zh-tr] {_httpimg_/zh-tr/tsubjgr.gif}
+_httpicontsubjon_ [l=zh-tr] {_httpimg_/zh-tr/tsubjon.gif}
+_httpicontsubjof_ [l=zh-tr] {_httpimg_/zh-tr/tsubjof.gif}
+## "äž»é¡" ## green_title ## h_subj ##
+_httpiconhsubj_ [l=zh-tr] {_httpimg_/zh-tr/h\_subj.gif}
+_widthhsubj_ [l=zh-tr] {200}
+_heighthsubj_ [l=zh-tr] {57}
+
+## "titles a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ {_httpimg_/en/ttitlgr.gif}
+_httpiconttitleof_ {_httpimg_/en/ttitlof.gif}
+_httpiconttitleon_ {_httpimg_/en/ttitlon.gif}
+## "Ø§ÙØ¹ÙØ§ÙÙÙ (Ø£ÙÙØšØ§ØŠÙØ§Ù)" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=ar] {_httpimg_/ar/ttitlgr.gif}
+_httpiconttitleof_ [l=ar] {_httpimg_/ar/ttitlof.gif}
+_httpiconttitleon_ [l=ar] {_httpimg_/ar/ttitlon.gif}
+## "àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ®àŠà§àŠ²àŠ¿" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=bn] {_httpimg_/bn/ttitlgr.gif}
+_httpiconttitleof_ [l=bn] {_httpimg_/bn/ttitlof.gif}
+_httpiconttitleon_ [l=bn] {_httpimg_/bn/ttitlon.gif}
+## "tÃ­tols a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=ca] {_httpimg_/ca/ttitlgr.gif}
+_httpiconttitleof_ [l=ca] {_httpimg_/ca/ttitlof.gif}
+_httpiconttitleon_ [l=ca] {_httpimg_/ca/ttitlon.gif}
+## "nÃ¡zvy a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=cs] {_httpimg_/cs/ttitlgr.gif}
+_httpiconttitleof_ [l=cs] {_httpimg_/cs/ttitlof.gif}
+_httpiconttitleon_ [l=cs] {_httpimg_/cs/ttitlon.gif}
+## "titel a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=de] {_httpimg_/de/ttitlgr.gif}
+_httpiconttitleof_ [l=de] {_httpimg_/de/ttitlof.gif}
+_httpiconttitleon_ [l=de] {_httpimg_/de/ttitlon.gif}
+## "ÏÎ¯ÏÎ»Î¿Î¹ Î±- Ï" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=el] {_httpimg_/el/ttitlgr.gif}
+_httpiconttitleof_ [l=el] {_httpimg_/el/ttitlof.gif}
+_httpiconttitleon_ [l=el] {_httpimg_/el/ttitlon.gif}
+## "tÃ­tulos a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=es] {_httpimg_/es/ttitlgr.gif}
+_httpiconttitleof_ [l=es] {_httpimg_/es/ttitlof.gif}
+_httpiconttitleon_ [l=es] {_httpimg_/es/ttitlon.gif}
+## "Ø¹ÙØ§ÙÙÙ Ø§-Ù" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=fa] {_httpimg_/fa/ttitlgr.gif}
+_httpiconttitleof_ [l=fa] {_httpimg_/fa/ttitlof.gif}
+_httpiconttitleon_ [l=fa] {_httpimg_/fa/ttitlon.gif}
+## "nimikkeet a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=fi] {_httpimg_/fi/ttitlgr.gif}
+_httpiconttitleof_ [l=fi] {_httpimg_/fi/ttitlof.gif}
+_httpiconttitleon_ [l=fi] {_httpimg_/fi/ttitlon.gif}
+## "titres a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=fr] {_httpimg_/fr/ttitlgr.gif}
+_httpiconttitleof_ [l=fr] {_httpimg_/fr/ttitlof.gif}
+_httpiconttitleon_ [l=fr] {_httpimg_/fr/ttitlon.gif}
+## "tÃ­tulos a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=gl] {_httpimg_/gl/ttitlgr.gif}
+_httpiconttitleof_ [l=gl] {_httpimg_/gl/ttitlof.gif}
+_httpiconttitleon_ [l=gl] {_httpimg_/gl/ttitlon.gif}
+## "×ª-× ×ª××š×ª××" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=he] {_httpimg_/he/ttitlgr.gif}
+_httpiconttitleof_ [l=he] {_httpimg_/he/ttitlof.gif}
+_httpiconttitleon_ [l=he] {_httpimg_/he/ttitlon.gif}
+## "naslovi a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=hr] {_httpimg_/hr/ttitlgr.gif}
+_httpiconttitleof_ [l=hr] {_httpimg_/hr/ttitlof.gif}
+_httpiconttitleon_ [l=hr] {_httpimg_/hr/ttitlon.gif}
+## "ÕŸÕ¥ÖÕ¶Õ¡Õ£ÖÕ¥Ö Õ¡-Ö" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=hy] {_httpimg_/hy/ttitlgr.gif}
+_httpiconttitleof_ [l=hy] {_httpimg_/hy/ttitlof.gif}
+_httpiconttitleon_ [l=hy] {_httpimg_/hy/ttitlon.gif}
+## "judul a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=id] {_httpimg_/id/ttitlgr.gif}
+_httpiconttitleof_ [l=id] {_httpimg_/id/ttitlof.gif}
+_httpiconttitleon_ [l=id] {_httpimg_/id/ttitlon.gif}
+## "titoli a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=it] {_httpimg_/it/ttitlgr.gif}
+_httpiconttitleof_ [l=it] {_httpimg_/it/ttitlof.gif}
+_httpiconttitleon_ [l=it] {_httpimg_/it/ttitlon.gif}
+## "ã¿ã€ãã«ïŒèŸæžé ïŒ" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=ja] {_httpimg_/ja/ttitlgr.gif}
+_httpiconttitleof_ [l=ja] {_httpimg_/ja/ttitlof.gif}
+_httpiconttitleon_ [l=ja] {_httpimg_/ja/ttitlon.gif}
+## "á¡áááá£á ááá ááááááá¡ á¡á®ááááá" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=ka] {_httpimg_/ka/ttitlgr.gif}
+_httpiconttitleof_ [l=ka] {_httpimg_/ka/ttitlof.gif}
+_httpiconttitleon_ [l=ka] {_httpimg_/ka/ttitlon.gif}
+## "Ð°ÑÐ°ÑÐ»Ð°Ñ Ð°-Ñ" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=kk] {_httpimg_/kk/ttitlgr.gif}
+_httpiconttitleof_ [l=kk] {_httpimg_/kk/ttitlof.gif}
+_httpiconttitleon_ [l=kk] {_httpimg_/kk/ttitlon.gif}
+## "ÑÐžÐ·ÐŒÐµÐ»ÐµÑ Ð°-Ñ" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=ky] {_httpimg_/ky/ttitlgr.gif}
+_httpiconttitleof_ [l=ky] {_httpimg_/ky/ttitlof.gif}
+_httpiconttitleon_ [l=ky] {_httpimg_/ky/ttitlon.gif}
+## "nosaukumi a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=lv] {_httpimg_/lv/ttitlgr.gif}
+_httpiconttitleof_ [l=lv] {_httpimg_/lv/ttitlof.gif}
+_httpiconttitleon_ [l=lv] {_httpimg_/lv/ttitlon.gif}
+## "taitara a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=mi] {_httpimg_/mi/ttitlgr.gif}
+_httpiconttitleof_ [l=mi] {_httpimg_/mi/ttitlof.gif}
+_httpiconttitleon_ [l=mi] {_httpimg_/mi/ttitlon.gif}
+## "Ð³Ð°ÑÑÐžÐ³ Ð°-Ñ" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=mn] {_httpimg_/mn/ttitlgr.gif}
+_httpiconttitleof_ [l=mn] {_httpimg_/mn/ttitlof.gif}
+_httpiconttitleon_ [l=mn] {_httpimg_/mn/ttitlon.gif}
+## "titels a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=nl] {_httpimg_/nl/ttitlgr.gif}
+_httpiconttitleof_ [l=nl] {_httpimg_/nl/ttitlof.gif}
+_httpiconttitleon_ [l=nl] {_httpimg_/nl/ttitlon.gif}
+## "tytuÅy a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=pl] {_httpimg_/pl/ttitlgr.gif}
+_httpiconttitleof_ [l=pl] {_httpimg_/pl/ttitlof.gif}
+_httpiconttitleon_ [l=pl] {_httpimg_/pl/ttitlon.gif}
+## "tÃ­tulos a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=pt-br] {_httpimg_/pt-br/ttitlgr.gif}
+_httpiconttitleof_ [l=pt-br] {_httpimg_/pt-br/ttitlof.gif}
+_httpiconttitleon_ [l=pt-br] {_httpimg_/pt-br/ttitlon.gif}
+## "tÃ­tulos a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=pt-pt] {_httpimg_/pt-pt/ttitlgr.gif}
+_httpiconttitleof_ [l=pt-pt] {_httpimg_/pt-pt/ttitlof.gif}
+_httpiconttitleon_ [l=pt-pt] {_httpimg_/pt-pt/ttitlon.gif}
+## "ÐœÐ°Ð·Ð²Ð°ÐœÐžÑ Ð°-Ñ" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=ru] {_httpimg_/ru/ttitlgr.gif}
+_httpiconttitleof_ [l=ru] {_httpimg_/ru/ttitlof.gif}
+_httpiconttitleon_ [l=ru] {_httpimg_/ru/ttitlon.gif}
+## "naslovi a-ÅŸ/a-Ñ" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=sr] {_httpimg_/sr/ttitlgr.gif}
+_httpiconttitleof_ [l=sr] {_httpimg_/sr/ttitlof.gif}
+_httpiconttitleon_ [l=sr] {_httpimg_/sr/ttitlon.gif}
+## "àžàž·à¹àž­à¹àž£àž·à¹àž­àž à¹àž­àžàž¶àžà¹àžàž" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=th] {_httpimg_/th/ttitlgr.gif}
+_httpiconttitleof_ [l=th] {_httpimg_/th/ttitlof.gif}
+_httpiconttitleon_ [l=th] {_httpimg_/th/ttitlon.gif}
+## "baÅlÄ±klar a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=tr] {_httpimg_/tr/ttitlgr.gif}
+_httpiconttitleof_ [l=tr] {_httpimg_/tr/ttitlof.gif}
+_httpiconttitleon_ [l=tr] {_httpimg_/tr/ttitlon.gif}
+## "ÐœÐ°Ð·Ð²Ðž Ð°-Ñ" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=uk] {_httpimg_/uk/ttitlgr.gif}
+_httpiconttitleof_ [l=uk] {_httpimg_/uk/ttitlof.gif}
+_httpiconttitleon_ [l=uk] {_httpimg_/uk/ttitlon.gif}
+## "tiÃªu Äá»" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=vi] {_httpimg_/vi/ttitlgr.gif}
+_httpiconttitleof_ [l=vi] {_httpimg_/vi/ttitlof.gif}
+_httpiconttitleon_ [l=vi] {_httpimg_/vi/ttitlon.gif}
+## "æ é¢çŽ¢åŒa-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=zh] {_httpimg_/zh/ttitlgr.gif}
+_httpiconttitleof_ [l=zh] {_httpimg_/zh/ttitlof.gif}
+_httpiconttitleon_ [l=zh] {_httpimg_/zh/ttitlon.gif}
+## "æšé¡ a-z" ## nav_bar_button ## ttitl ##
+_httpiconttitlegr_ [l=zh-tr] {_httpimg_/zh-tr/ttitlgr.gif}
+_httpiconttitleof_ [l=zh-tr] {_httpimg_/zh-tr/ttitlof.gif}
+_httpiconttitleon_ [l=zh-tr] {_httpimg_/zh-tr/ttitlon.gif}
+
+## "titles a-z" ## green_title ## h_title ##
+_httpiconhtitle_ {_httpimg_/en/h\_title.gif}
+_widthhtitle_ {200}
+_heighthtitle_ {57}
+## "Ø§ÙØ¹ÙØ§ÙÙÙ (Ø£ÙÙØšØ§ØŠÙØ§Ù)" ## green_title ## h_title ##
+_httpiconhtitle_ [l=ar] {_httpimg_/ar/h\_title.gif}
+_widthhtitle_ [l=ar] {200}
+_heighthtitle_ [l=ar] {57}
+## "àŠ¶àŠ¿àŠ°à§àŠšàŠŸàŠ®àŠà§àŠ²àŠ¿" ## green_title ## h_title ##
+_httpiconhtitle_ [l=bn] {_httpimg_/bn/h\_title.gif}
+_widthhtitle_ [l=bn] {200}
+_heighthtitle_ [l=bn] {57}
+## "tÃ­tols a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=ca] {_httpimg_/ca/h\_title.gif}
+_widthhtitle_ [l=ca] {200}
+_heighthtitle_ [l=ca] {57}
+## "nÃ¡zvy a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=cs] {_httpimg_/cs/h\_title.gif}
+_widthhtitle_ [l=cs] {200}
+_heighthtitle_ [l=cs] {57}
+## "titel a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=de] {_httpimg_/de/h\_title.gif}
+_widthhtitle_ [l=de] {200}
+_heighthtitle_ [l=de] {57}
+## "ÏÎ¯ÏÎ»Î¿Î¹ Î±-Ï" ## green_title ## h_title ##
+_httpiconhtitle_ [l=el] {_httpimg_/el/h\_title.gif}
+_widthhtitle_ [l=el] {200}
+_heighthtitle_ [l=el] {57}
+## "tÃ­tulos a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=es] {_httpimg_/es/h\_title.gif}
+_widthhtitle_ [l=es] {200}
+_heighthtitle_ [l=es] {57}
+## "Ø¹ÙØ§ÙÙÙ Ø§-Ù" ## green_title ## h_title ##
+_httpiconhtitle_ [l=fa] {_httpimg_/fa/h\_title.gif}
+_widthhtitle_ [l=fa] {200}
+_heighthtitle_ [l=fa] {57}
+## "nimikkeet a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=fi] {_httpimg_/fi/h\_title.gif}
+_widthhtitle_ [l=fi] {200}
+_heighthtitle_ [l=fi] {57}
+## "titres a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=fr] {_httpimg_/fr/h\_title.gif}
+_widthhtitle_ [l=fr] {200}
+_heighthtitle_ [l=fr] {57}
+## "tÃ­tulos a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=gl] {_httpimg_/gl/h\_title.gif}
+_widthhtitle_ [l=gl] {200}
+_heighthtitle_ [l=gl] {57}
+## "×ª××š×ª×× ×ª-×" ## green_title ## h_title ##
+_httpiconhtitle_ [l=he] {_httpimg_/he/h\_title.gif}
+_widthhtitle_ [l=he] {200}
+_heighthtitle_ [l=he] {57}
+## "naslovi a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=hr] {_httpimg_/hr/h_title.gif}
+_widthhtitle_ [l=hr] {200}
+_heighthtitle_ [l=hr] {57}
+## "ÕŸÕ¥ÖÕ¶Õ¡Õ£ÖÕ¥Ö Õ¡-Ö" ## green_title ## h_title ##
+_httpiconhtitle_ [l=hy] {_httpimg_/hy/h\_title.gif}
+_widthhtitle_ [l=hy] {200}
+_heighthtitle_ [l=hy] {57}
+## "Judul A-Z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=id] {_httpimg_/id/h\_title.gif}
+_widthhtitle_ [l=id] {200}
+_heighthtitle_ [l=id] {57}
+## "titoli a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=it] {_httpimg_/it/h\_title.gif}
+_widthhtitle_ [l=it] {200}
+_heighthtitle_ [l=it] {57}
+## "ã¿ã€ãã«ïŒèŸæžé ïŒ" ## green_title ## h_title ##
+_httpiconhtitle_ [l=ja] {_httpimg_/ja/h\_title.gif}
+_widthhtitle_ [l=ja] {200}
+_heighthtitle_ [l=ja] {57}
+## "á¡áááá£á ááá\nááááááá¡ á¡á®ááááá" ## green_title ## h_title ##
+_httpiconhtitle_ [l=ka] {_httpimg_/ka/h\_title.gif}
+_widthhtitle_ [l=ka] {258}
+_heighthtitle_ [l=ka] {74}
+## "Ð°ÑÐ°ÑÐ»Ð°Ñ Ð°-Ñ" ## green_title ## h_title ##
+_httpiconhtitle_ [l=kk] {_httpimg_/kk/h\_title.gif}
+_widthhtitle_ [l=kk] {200}
+_heighthtitle_ [l=kk] {57}
+## "ÑÐžÐ·ÐŒÐµÐ»ÐµÑ Ð-Ð¯" ## green_title ## h_title ##
+_httpiconhtitle_ [l=ky] {_httpimg_/ky/h\_title.gif}
+_widthhtitle_ [l=ky] {200}
+_heighthtitle_ [l=ky] {57}
+## "nosaukumi a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=lv] {_httpimg_/lv/h\_title.gif}
+_widthhtitle_ [l=lv] {200}
+_heighthtitle_ [l=lv] {57}
+## "taitara a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=mi] {_httpimg_/mi/h\_title.gif}
+_widthhtitle_ [l=mi] {200}
+_heighthtitle_ [l=mi] {57}
+## "Ð³Ð°ÑÑÐžÐ³ Ð°-Ñ" ## green_title ## h_title ##
+_httpiconhtitle_ [l=mn] {_httpimg_/mn/h\_title.gif}
+_widthhtitle_ [l=mn] {200}
+_heighthtitle_ [l=mn] {57}
+## "titels a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=nl] {_httpimg_/nl/h\_title.gif}
+_widthhtitle_ [l=nl] {200}
+_heighthtitle_ [l=nl] {57}
+## "tytuÅy a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=pl] {_httpimg_/pl/h\_title.gif}
+_widthhtitle_ [l=pl] {200}
+_heighthtitle_ [l=pl] {57}
+## "tÃ­tulos a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=pt-br] {_httpimg_/pt-br/h\_title.gif}
+_widthhtitle_ [l=pt-br] {200}
+_heighthtitle_ [l=pt-br] {57}
+## "tÃ­tulos a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=pt-pt] {_httpimg_/pt-pt/h\_title.gif}
+_widthhtitle_ [l=pt-pt] {200}
+_heighthtitle_ [l=pt-pt] {57}
+## "ÐœÐ°Ð·Ð²Ð°ÐœÐžÑ Ð°-Ñ" ## green_title ## h_title ##
+_httpiconhtitle_ [l=ru] {_httpimg_/ru/h\_title.gif}
+_widthhtitle_ [l=ru] {200}
+_heighthtitle_ [l=ru] {57}
+## "naslovi a-ÅŸ/a-Ñ" ## green_title ## h_title ##
+_httpiconhtitle_ [l=sr] {_httpimg_/sr/h\_title.gif}
+_widthhtitle_ [l=sr] {200}
+_heighthtitle_ [l=sr] {57}
+## "àžàž·à¹àž­à¹àž£àž·à¹àž­àž a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=th] {_httpimg_/th/h\_title.gif}
+_widthhtitle_ [l=th] {200}
+_heighthtitle_ [l=th] {57}
+## "baÅlÄ±klar a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=tr] {_httpimg_/tr/h\_title.gif}
+_widthhtitle_ [l=tr] {200}
+_heighthtitle_ [l=tr] {57}
+## "Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐž Ð°-Ñ" ## green_title ## h_title ##
+_httpiconhtitle_ [l=uk] {_httpimg_/uk/h\_title.gif}
+_widthhtitle_ [l=uk] {200}
+_heighthtitle_ [l=uk] {57}
+## "tiÃªu Äá»" ## green_title ## h_title ##
+_httpiconhtitle_ [l=vi] {_httpimg_/vi/h\_title.gif}
+_widthhtitle_ [l=vi] {200}
+_heighthtitle_ [l=vi] {57}
+## "æ é¢çŽ¢åŒa-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=zh] {_httpimg_/zh/h\_title.gif}
+_widthhtitle_ [l=zh] {200}
+_heighthtitle_ [l=zh] {57}
+## "æšé¡ a-z" ## green_title ## h_title ##
+_httpiconhtitle_ [l=zh-tr] {_httpimg_/zh-tr/h\_title.gif}
+_widthhtitle_ [l=zh-tr] {200}
+_heighthtitle_ [l=zh-tr] {57}
+
+## "to" ## nav_bar_button ## tto ##
+_httpiconttogr_ {_httpimg_/en/ttogr.gif}
+_httpiconttoon_ {_httpimg_/en/ttoon.gif}
+_httpiconttoof_ {_httpimg_/en/ttoof.gif}
+## "to" ## green_title ## h_to ##
+_httpiconhto_ {_httpimg_/en/h\_to.gif}
+_widthhto_ {200}
+_heighthto_ {57}
+## "Ø¥ÙÙ" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=ar] {_httpimg_/ar/ttogr.gif}
+_httpiconttoon_ [l=ar] {_httpimg_/ar/ttoon.gif}
+_httpiconttoof_ [l=ar] {_httpimg_/ar/ttoof.gif}
+## "Ø§ÙÙ
+Ø±Ø³Ù Ø¥ÙÙÙ" ## green_title ## h_to ##
+_httpiconhto_ [l=ar] {_httpimg_/ar/h\_to.gif}
+_widthhto_ [l=ar] {200}
+_heighthto_ [l=ar] {57}
+## "àŠ€à§" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=bn] {_httpimg_/bn/ttogr.gif}
+_httpiconttoon_ [l=bn] {_httpimg_/bn/ttoon.gif}
+_httpiconttoof_ [l=bn] {_httpimg_/bn/ttoof.gif}
+## "àŠ€à§ / àŠªà§àŠ°àŠ€àŠ¿" ## green_title ## h_to ##
+_httpiconhto_ [l=bn] {_httpimg_/bn/h\_to.gif}
+_widthhto_ [l=bn] {200}
+_heighthto_ [l=bn] {57}
+## "a" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=ca] {_httpimg_/ca/ttogr.gif}
+_httpiconttoon_ [l=ca] {_httpimg_/ca/ttoon.gif}
+_httpiconttoof_ [l=ca] {_httpimg_/ca/ttoof.gif}
+## "a" ## green_title ## h_to ##
+_httpiconhto_ [l=ca] {_httpimg_/ca/h\_to.gif}
+_widthhto_ [l=ca] {200}
+_heighthto_ [l=ca] {57}
+## "pro" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=cs] {_httpimg_/cs/ttogr.gif}
+_httpiconttoon_ [l=cs] {_httpimg_/cs/ttoon.gif}
+_httpiconttoof_ [l=cs] {_httpimg_/cs/ttoof.gif}
+## "pro" ## green_title ## h_to ##
+_httpiconhto_ [l=cs] {_httpimg_/cs/h\_to.gif}
+_widthhto_ [l=cs] {200}
+_heighthto_ [l=cs] {57}
+## "ÏÏÎµÏÎ¹ÎºÎ¬ ÎŒÎµ" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=el] {_httpimg_/el/ttogr.gif}
+_httpiconttoon_ [l=el] {_httpimg_/el/ttoon.gif}
+_httpiconttoof_ [l=el] {_httpimg_/el/ttoof.gif}
+## "ÏÏÎ¿Ï" ## green_title ## h_to ##
+_httpiconhto_ [l=el] {_httpimg_/el/h\_to.gif}
+_widthhto_ [l=el] {200}
+_heighthto_ [l=el] {57}
+## "a" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=es] {_httpimg_/es/ttogr.gif}
+_httpiconttoon_ [l=es] {_httpimg_/es/ttoon.gif}
+_httpiconttoof_ [l=es] {_httpimg_/es/ttoof.gif}
+## "a" ## green_title ## h_to ##
+_httpiconhto_ [l=es] {_httpimg_/es/h\_to.gif}
+_widthhto_ [l=es] {200}
+_heighthto_ [l=es] {57}
+## "ØªØ§" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=fa] {_httpimg_/fa/ttogr.gif}
+_httpiconttoon_ [l=fa] {_httpimg_/fa/ttoon.gif}
+_httpiconttoof_ [l=fa] {_httpimg_/fa/ttoof.gif}
+## "ØªØ§" ## green_title ## h_to ##
+_httpiconhto_ [l=fa] {_httpimg_/fa/h\_to.gif}
+_widthhto_ [l=fa] {200}
+_heighthto_ [l=fa] {57}
+## "kohde" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=fi] {_httpimg_/fi/ttogr.gif}
+_httpiconttoon_ [l=fi] {_httpimg_/fi/ttoon.gif}
+_httpiconttoof_ [l=fi] {_httpimg_/fi/ttoof.gif}
+## "kohde" ## green_title ## h_to ##
+_httpiconhto_ [l=fi] {_httpimg_/fi/h\_to.gif}
+_widthhto_ [l=fi] {200}
+_heighthto_ [l=fi] {57}
+## "Ã " ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=fr] {_httpimg_/fr/ttogr.gif}
+_httpiconttoon_ [l=fr] {_httpimg_/fr/ttoon.gif}
+_httpiconttoof_ [l=fr] {_httpimg_/fr/ttoof.gif}
+## "Ã " ## green_title ## h_to ##
+_httpiconhto_ [l=fr] {_httpimg_/fr/h\_to.gif}
+_widthhto_ [l=fr] {200}
+_heighthto_ [l=fr] {57}
+## "para" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=gl] {_httpimg_/gl/ttogr.gif}
+_httpiconttoon_ [l=gl] {_httpimg_/gl/ttoon.gif}
+_httpiconttoof_ [l=gl] {_httpimg_/gl/ttoof.gif}
+## "para" ## green_title ## h_to ##
+_httpiconhto_ [l=gl] {_httpimg_/gl/h\_to.gif}
+_widthhto_ [l=gl] {200}
+_heighthto_ [l=gl] {57}
+## "×š××§×" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=he] {_httpimg_/he/ttogr.gif}
+_httpiconttoon_ [l=he] {_httpimg_/he/ttoon.gif}
+_httpiconttoof_ [l=he] {_httpimg_/he/ttoof.gif}
+## "×š××§×" ## green_title ## h_to ##
+_httpiconhto_ [l=he] {_httpimg_/he/h\_to.gif}
+_widthhto_ [l=he] {200}
+_heighthto_ [l=he] {57}
+## "Õ¡ÕµÕ¶Õ¿Õ¥Õ²" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=hy] {_httpimg_/hy/ttogr.gif}
+_httpiconttoon_ [l=hy] {_httpimg_/hy/ttoon.gif}
+_httpiconttoof_ [l=hy] {_httpimg_/hy/ttoof.gif}
+## "Õ¡ÕµÕ¶Õ¿Õ¥Õ²" ## green_title ## h_to ##
+_httpiconhto_ [l=hy] {_httpimg_/hy/h\_to.gif}
+_widthhto_ [l=hy] {200}
+_heighthto_ [l=hy] {57}
+## "kepada" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=id] {_httpimg_/id/ttogr.gif}
+_httpiconttoon_ [l=id] {_httpimg_/id/ttoon.gif}
+_httpiconttoof_ [l=id] {_httpimg_/id/ttoof.gif}
+## "kepada" ## green_title ## h_to ##
+_httpiconhto_ [l=id] {_httpimg_/id/h\_to.gif}
+_widthhto_ [l=id] {200}
+_heighthto_ [l=id] {57}
+## "destinatario" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=it] {_httpimg_/it/ttogr.gif}
+_httpiconttoon_ [l=it] {_httpimg_/it/ttoon.gif}
+_httpiconttoof_ [l=it] {_httpimg_/it/ttoof.gif}
+## "destinatario" ## green_title ## h_to ##
+_httpiconhto_ [l=it] {_httpimg_/it/h\_to.gif}
+_widthhto_ [l=it] {200}
+_heighthto_ [l=it] {57}
+## "âááá¡â" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=ka] {_httpimg_/ka/ttogr.gif}
+_httpiconttoon_ [l=ka] {_httpimg_/ka/ttoon.gif}
+_httpiconttoof_ [l=ka] {_httpimg_/ka/ttoof.gif}
+## "âááá¡â" ## green_title ## h_to ##
+_httpiconhto_ [l=ka] {_httpimg_/ka/h\_to.gif}
+_widthhto_ [l=ka] {258}
+_heighthto_ [l=ka] {74}
+## "ÐºÑÐŒÐ³Ðµ" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=kk] {_httpimg_/kk/ttogr.gif}
+_httpiconttoon_ [l=kk] {_httpimg_/kk/ttoon.gif}
+_httpiconttoof_ [l=kk] {_httpimg_/kk/ttoof.gif}
+## "ÐºÑÐŒÐ³Ðµ" ## green_title ## h_to ##
+_httpiconhto_ [l=kk] {_httpimg_/kk/h\_to.gif}
+_widthhto_ [l=kk] {200}
+_heighthto_ [l=kk] {57}
+## "ÐºÐžÐŒÐ³Ðµ" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=ky] {_httpimg_/ky/ttogr.gif}
+_httpiconttoon_ [l=ky] {_httpimg_/ky/ttoon.gif}
+_httpiconttoof_ [l=ky] {_httpimg_/ky/ttoof.gif}
+## "ÐºÐžÐŒÐ³Ðµ" ## green_title ## h_to ##
+_httpiconhto_ [l=ky] {_httpimg_/ky/h\_to.gif}
+_widthhto_ [l=ky] {200}
+_heighthto_ [l=ky] {57}
+## "kam" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=lv] {_httpimg_/lv/ttogr.gif}
+_httpiconttoon_ [l=lv] {_httpimg_/lv/ttoon.gif}
+_httpiconttoof_ [l=lv] {_httpimg_/lv/ttoof.gif}
+## "kam" ## green_title ## h_to ##
+_httpiconhto_ [l=lv] {_httpimg_/lv/h\_to.gif}
+_widthhto_ [l=lv] {200}
+_heighthto_ [l=lv] {57}
+## "ki a" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=mi] {_httpimg_/mi/ttogr.gif}
+_httpiconttoon_ [l=mi] {_httpimg_/mi/ttoon.gif}
+_httpiconttoof_ [l=mi] {_httpimg_/mi/ttoof.gif}
+## "ki a" ## green_title ## h_to ##
+_httpiconhto_ [l=mi] {_httpimg_/mi/h\_to.gif}
+_widthhto_ [l=mi] {200}
+_heighthto_ [l=mi] {57}
+## "ÑÑÑ" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=mn] {_httpimg_/mn/ttogr.gif}
+_httpiconttoon_ [l=mn] {_httpimg_/mn/ttoon.gif}
+_httpiconttoof_ [l=mn] {_httpimg_/mn/ttoof.gif}
+## "ÑÑÑ" ## green_title ## h_to ##
+_httpiconhto_ [l=mn] {_httpimg_/mn/h\_to.gif}
+_widthhto_ [l=mn] {200}
+_heighthto_ [l=mn] {57}
+## "geadresseerde" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=nl] {_httpimg_/nl/ttogr.gif}
+_httpiconttoon_ [l=nl] {_httpimg_/nl/ttoon.gif}
+_httpiconttoof_ [l=nl] {_httpimg_/nl/ttoof.gif}
+## "geadresseerde" ## green_title ## h_to ##
+_httpiconhto_ [l=nl] {_httpimg_/nl/h\_to.gif}
+_widthhto_ [l=nl] {200}
+_heighthto_ [l=nl] {57}
+## "do" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=pl] {_httpimg_/pl/ttogr.gif}
+_httpiconttoon_ [l=pl] {_httpimg_/pl/ttoon.gif}
+_httpiconttoof_ [l=pl] {_httpimg_/pl/ttoof.gif}
+## "do" ## green_title ## h_to ##
+_httpiconhto_ [l=pl] {_httpimg_/pl/h\_to.gif}
+_widthhto_ [l=pl] {200}
+_heighthto_ [l=pl] {57}
+## "para" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=pt-pt] {_httpimg_/pt-pt/ttogr.gif}
+_httpiconttoon_ [l=pt-pt] {_httpimg_/pt-pt/ttoon.gif}
+_httpiconttoof_ [l=pt-pt] {_httpimg_/pt-pt/ttoof.gif}
+## "para" ## green_title ## h_to ##
+_httpiconhto_ [l=pt-pt] {_httpimg_/pt-pt/h\_to.gif}
+_widthhto_ [l=pt-pt] {200}
+_heighthto_ [l=pt-pt] {57}
+## "ÐºÐŸÐŒÑ" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=ru] {_httpimg_/ru/ttogr.gif}
+_httpiconttoon_ [l=ru] {_httpimg_/ru/ttoon.gif}
+_httpiconttoof_ [l=ru] {_httpimg_/ru/ttoof.gif}
+## "ÐºÐŸÐŒÑ" ## green_title ## h_to ##
+_httpiconhto_ [l=ru] {_httpimg_/ru/h\_to.gif}
+_widthhto_ [l=ru] {200}
+_heighthto_ [l=ru] {57}
+## "kome" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=sr] {_httpimg_/sr/ttogr.gif}
+_httpiconttoon_ [l=sr] {_httpimg_/sr/ttoon.gif}
+_httpiconttoof_ [l=sr] {_httpimg_/sr/ttoof.gif}
+## "kome" ## green_title ## h_to ##
+_httpiconhto_ [l=sr] {_httpimg_/sr/h\_to.gif}
+_widthhto_ [l=sr] {200}
+_heighthto_ [l=sr] {57}
+## "àžàž¶àž" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=th] {_httpimg_/th/ttogr.gif}
+_httpiconttoon_ [l=th] {_httpimg_/th/ttoon.gif}
+_httpiconttoof_ [l=th] {_httpimg_/th/ttoof.gif}
+## "àžàž¶àž" ## green_title ## h_to ##
+_httpiconhto_ [l=th] {_httpimg_/th/h\_to.gif}
+_widthhto_ [l=th] {200}
+_heighthto_ [l=th] {57}
+## "kime" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=tr] {_httpimg_/tr/ttogr.gif}
+_httpiconttoon_ [l=tr] {_httpimg_/tr/ttoon.gif}
+_httpiconttoof_ [l=tr] {_httpimg_/tr/ttoof.gif}
+## "kime" ## green_title ## h_to ##
+_httpiconhto_ [l=tr] {_httpimg_/tr/h\_to.gif}
+_widthhto_ [l=tr] {200}
+_heighthto_ [l=tr] {57}
+## "ÐŽÐŸ" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=uk] {_httpimg_/uk/ttogr.gif}
+_httpiconttoon_ [l=uk] {_httpimg_/uk/ttoon.gif}
+_httpiconttoof_ [l=uk] {_httpimg_/uk/ttoof.gif}
+## "ÐŽÐŸ" ## green_title ## h_to ##
+_httpiconhto_ [l=uk] {_httpimg_/uk/h\_to.gif}
+_widthhto_ [l=uk] {200}
+_heighthto_ [l=uk] {57}
+## "nÆ¡i chá»©a" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=vi] {_httpimg_/vi/ttogr.gif}
+_httpiconttoon_ [l=vi] {_httpimg_/vi/ttoon.gif}
+_httpiconttoof_ [l=vi] {_httpimg_/vi/ttoof.gif}
+## "nÆ¡i chá»©a" ## green_title ## h_to ##
+_httpiconhto_ [l=vi] {_httpimg_/vi/h\_to.gif}
+_widthhto_ [l=vi] {200}
+_heighthto_ [l=vi] {57}
+## "æªæ­¢äº" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=zh] {_httpimg_/zh/ttogr.gif}
+_httpiconttoon_ [l=zh] {_httpimg_/zh/ttoon.gif}
+_httpiconttoof_ [l=zh] {_httpimg_/zh/ttoof.gif}
+## "æªæ­¢äº" ## green_title ## h_to ##
+_httpiconhto_ [l=zh] {_httpimg_/zh/h\_to.gif}
+_widthhto_ [l=zh] {200}
+_heighthto_ [l=zh] {57}
+## "æªæ­¢æŒ" ## nav_bar_button ## tto ##
+_httpiconttogr_ [l=zh-tr] {_httpimg_/zh-tr/ttogr.gif}
+_httpiconttoon_ [l=zh-tr] {_httpimg_/zh-tr/ttoon.gif}
+_httpiconttoof_ [l=zh-tr] {_httpimg_/zh-tr/ttoof.gif}
+## "æªæ­¢æŒ" ## green_title ## h_to ##
+_httpiconhto_ [l=zh-tr] {_httpimg_/zh-tr/h\_to.gif}
+_widthhto_ [l=zh-tr] {200}
+_heighthto_ [l=zh-tr] {57}
+
+## "topic" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ {_httpimg_/en/ttopicgr.gif}
+_httpiconttopicon_ {_httpimg_/en/ttopicon.gif}
+_httpiconttopicof_ {_httpimg_/en/ttopicof.gif}
+## "topics" ## green_title ## h_topic ##
+_httpiconhtopic_ {_httpimg_/en/h\_topic.gif}
+_widthhtopic_ {200}
+_heighthtopic_ {57}
+## "Ø§ÙÙ
+Ø¬Ø§Ù" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=ar] {_httpimg_/ar/ttopicgr.gif}
+_httpiconttopicon_ [l=ar] {_httpimg_/ar/ttopicon.gif}
+_httpiconttopicof_ [l=ar] {_httpimg_/ar/ttopicof.gif}
+## "Ø§ÙÙ
+Ø¬Ø§ÙØ§Øª" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=ar] {_httpimg_/ar/h\_topic.gif}
+_widthhtopic_ [l=ar] {200}
+_heighthtopic_ [l=ar] {57}
+## "àŠ¬àŠ¿àŠ·à§" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=bn] {_httpimg_/bn/ttopicgr.gif}
+_httpiconttopicon_ [l=bn] {_httpimg_/bn/ttopicon.gif}
+_httpiconttopicof_ [l=bn] {_httpimg_/bn/ttopicof.gif}
+## "àŠªà§àŠ°àŠžàŠà§àŠàŠà§àŠ²àŠ¿" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=bn] {_httpimg_/bn/h\_topic.gif}
+_widthhtopic_ [l=bn] {200}
+_heighthtopic_ [l=bn] {57}
+## "tema" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=ca] {_httpimg_/ca/ttopicgr.gif}
+_httpiconttopicon_ [l=ca] {_httpimg_/ca/ttopicon.gif}
+_httpiconttopicof_ [l=ca] {_httpimg_/ca/ttopicof.gif}
+## "temes" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=ca] {_httpimg_/ca/h\_topic.gif}
+_widthhtopic_ [l=ca] {200}
+_heighthtopic_ [l=ca] {57}
+## "tÃ©mata" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=cs] {_httpimg_/cs/ttopicgr.gif}
+_httpiconttopicon_ [l=cs] {_httpimg_/cs/ttopicon.gif}
+_httpiconttopicof_ [l=cs] {_httpimg_/cs/ttopicof.gif}
+## "tÃ©mata" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=cs] {_httpimg_/cs/h\_topic.gif}
+_widthhtopic_ [l=cs] {200}
+_heighthtopic_ [l=cs] {57}
+## "thema" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=de] {_httpimg_/de/ttopicgr.gif}
+_httpiconttopicon_ [l=de] {_httpimg_/de/ttopicon.gif}
+_httpiconttopicof_ [l=de] {_httpimg_/de/ttopicof.gif}
+## "themen" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=de] {_httpimg_/de/h\_topic.gif}
+_widthhtopic_ [l=de] {200}
+_heighthtopic_ [l=de] {57}
+## "ÎžÎ­ÎŒÎ±" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=el] {_httpimg_/el/ttopicgr.gif}
+_httpiconttopicon_ [l=el] {_httpimg_/el/ttopicon.gif}
+_httpiconttopicof_ [l=el] {_httpimg_/el/ttopicof.gif}
+## "ÎžÎ­ÎŒÎ±ÏÎ±" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=el] {_httpimg_/el/h\_topic.gif}
+_widthhtopic_ [l=el] {200}
+_heighthtopic_ [l=el] {57}
+## "temas" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=es] {_httpimg_/es/ttopicgr.gif}
+_httpiconttopicon_ [l=es] {_httpimg_/es/ttopicon.gif}
+_httpiconttopicof_ [l=es] {_httpimg_/es/ttopicof.gif}
+## "temas" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=es] {_httpimg_/es/h\_topic.gif}
+_widthhtopic_ [l=es] {200}
+_heighthtopic_ [l=es] {57}
+## "Ù
+ÙØ¶ÙØ¹" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=fa] {_httpimg_/fa/ttopicgr.gif}
+_httpiconttopicon_ [l=fa] {_httpimg_/fa/ttopicon.gif}
+_httpiconttopicof_ [l=fa] {_httpimg_/fa/ttopicof.gif}
+## "Ù
+ÙØ¶ÙØ¹Ø§Øª" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=fa] {_httpimg_/fa/h\_topic.gif}
+_widthhtopic_ [l=fa] {200}
+_heighthtopic_ [l=fa] {57}
+## "aihealue" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=fi] {_httpimg_/fi/ttopicgr.gif}
+_httpiconttopicon_ [l=fi] {_httpimg_/fi/ttopicon.gif}
+_httpiconttopicof_ [l=fi] {_httpimg_/fi/ttopicof.gif}
+## "aihealueet" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=fi] {_httpimg_/fi/h\_topic.gif}
+_widthhtopic_ [l=fi] {200}
+_heighthtopic_ [l=fi] {57}
+## "thÃšmes" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=fr] {_httpimg_/fr/ttopicgr.gif}
+_httpiconttopicon_ [l=fr] {_httpimg_/fr/ttopicon.gif}
+_httpiconttopicof_ [l=fr] {_httpimg_/fr/ttopicof.gif}
+## "thÃšmes" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=fr] {_httpimg_/fr/h\_topic.gif}
+_widthhtopic_ [l=fr] {200}
+_heighthtopic_ [l=fr] {57}
+## "temas" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=gl] {_httpimg_/gl/ttopicgr.gif}
+_httpiconttopicon_ [l=gl] {_httpimg_/gl/ttopicon.gif}
+_httpiconttopicof_ [l=gl] {_httpimg_/gl/ttopicof.gif}
+## "temas" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=gl] {_httpimg_/gl/h\_topic.gif}
+_widthhtopic_ [l=gl] {200}
+_heighthtopic_ [l=gl] {57}
+## "×ª×š×ª××" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=he] {_httpimg_/he/ttopicgr.gif}
+_httpiconttopicon_ [l=he] {_httpimg_/he/ttopicon.gif}
+_httpiconttopicof_ [l=he] {_httpimg_/he/ttopicof.gif}
+## "××××©×× " ## green_title ## h_topic ##
+_httpiconhtopic_ [l=he] {_httpimg_/he/h\_topic.gif}
+_widthhtopic_ [l=he] {200}
+_heighthtopic_ [l=he] {57}
+## "teme" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=hr] {_httpimg_/hr/ttopicgr.gif}
+_httpiconttopicon_ [l=hr] {_httpimg_/hr/ttopicon.gif}
+_httpiconttopicof_ [l=hr] {_httpimg_/hr/ttopicof.gif}
+## "teme" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=hr] {_httpimg_/hr/h\_topic.gif}
+_widthhtopic_ [l=hr] {200}
+_heighthtopic_ [l=hr] {57}
+## "Õ­ÕžÖÕ¡Õ£Õ«Ö" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=hy] {_httpimg_/hy/ttopicgr.gif}
+_httpiconttopicon_ [l=hy] {_httpimg_/hy/ttopicon.gif}
+_httpiconttopicof_ [l=hy] {_httpimg_/hy/ttopicof.gif}
+## "Õ­ÕžÖÕ¡Õ£ÖÕ¥Ö" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=hy] {_httpimg_/hy/h\_topic.gif}
+_widthhtopic_ [l=hy] {200}
+_heighthtopic_ [l=hy] {57}
+## "topik" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=id] {_httpimg_/id/ttopicgr.gif}
+_httpiconttopicon_ [l=id] {_httpimg_/id/ttopicon.gif}
+_httpiconttopicof_ [l=id] {_httpimg_/id/ttopicof.gif}
+## "topik" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=id] {_httpimg_/id/h\_topic.gif}
+_widthhtopic_ [l=id] {200}
+_heighthtopic_ [l=id] {57}
+## "argomento" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=it] {_httpimg_/it/ttopicgr.gif}
+_httpiconttopicon_ [l=it] {_httpimg_/it/ttopicon.gif}
+_httpiconttopicof_ [l=it] {_httpimg_/it/ttopicof.gif}
+## "argomento" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=it] {_httpimg_/it/h\_topic.gif}
+_widthhtopic_ [l=it] {200}
+_heighthtopic_ [l=it] {57}
+## "ãããã¯" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=ja] {_httpimg_/ja/ttopicgr.gif}
+_httpiconttopicon_ [l=ja] {_httpimg_/ja/ttopicon.gif}
+_httpiconttopicof_ [l=ja] {_httpimg_/ja/ttopicof.gif}
+## "ãããã¯" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=ja] {_httpimg_/ja/h\_topic.gif}
+_widthhtopic_ [l=ja] {200}
+_heighthtopic_ [l=ja] {57}
+## "áááá" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=ka] {_httpimg_/ka/ttopicgr.gif}
+_httpiconttopicon_ [l=ka] {_httpimg_/ka/ttopicon.gif}
+_httpiconttopicof_ [l=ka] {_httpimg_/ka/ttopicof.gif}
+## "ááá¡áá" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=ka] {_httpimg_/ka/h\_topic.gif}
+_widthhtopic_ [l=ka] {258}
+_heighthtopic_ [l=ka] {74}
+## "ÑÐ°ÒÑÑÑÐ¿ÑÐ°Ñ" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=kk] {_httpimg_/kk/ttopicgr.gif}
+_httpiconttopicon_ [l=kk] {_httpimg_/kk/ttopicon.gif}
+_httpiconttopicof_ [l=kk] {_httpimg_/kk/ttopicof.gif}
+## "ÑÐ°ÒÑÑÑÐ¿ÑÐ°Ñ" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=kk] {_httpimg_/kk/h\_topic.gif}
+_widthhtopic_ [l=kk] {200}
+_heighthtopic_ [l=kk] {57}
+## "ÑÐµÐŒÐ°" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=ky] {_httpimg_/ky/ttopicgr.gif}
+_httpiconttopicon_ [l=ky] {_httpimg_/ky/ttopicon.gif}
+_httpiconttopicof_ [l=ky] {_httpimg_/ky/ttopicof.gif}
+## "ÑÐµÐŒÐ°Ð»Ð°Ñ" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=ky] {_httpimg_/ky/h\_topic.gif}
+_widthhtopic_ [l=ky] {200}
+_heighthtopic_ [l=ky] {57}
+## "temats" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=lv] {_httpimg_/lv/ttopicgr.gif}
+_httpiconttopicon_ [l=lv] {_httpimg_/lv/ttopicon.gif}
+_httpiconttopicof_ [l=lv] {_httpimg_/lv/ttopicof.gif}
+## "temati" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=lv] {_httpimg_/lv/h\_topic.gif}
+_widthhtopic_ [l=lv] {200}
+_heighthtopic_ [l=lv] {57}
+## "kaupapa" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=mi] {_httpimg_/mi/ttopicgr.gif}
+_httpiconttopicon_ [l=mi] {_httpimg_/mi/ttopicon.gif}
+_httpiconttopicof_ [l=mi] {_httpimg_/mi/ttopicof.gif}
+## "kaupapa" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=mi] {_httpimg_/mi/h\_topic.gif}
+_widthhtopic_ [l=mi] {200}
+_heighthtopic_ [l=mi] {57}
+## "ÑÑÐŽÑÐ²" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=mn] {_httpimg_/mn/ttopicgr.gif}
+_httpiconttopicon_ [l=mn] {_httpimg_/mn/ttopicon.gif}
+_httpiconttopicof_ [l=mn] {_httpimg_/mn/ttopicof.gif}
+## "ÑÑÐŽÐ²Ò¯Ò¯ÐŽ" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=mn] {_httpimg_/mn/h\_topic.gif}
+_widthhtopic_ [l=mn] {200}
+_heighthtopic_ [l=mn] {57}
+## "thema" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=nl] {_httpimg_/nl/ttopicgr.gif}
+_httpiconttopicon_ [l=nl] {_httpimg_/nl/ttopicon.gif}
+_httpiconttopicof_ [l=nl] {_httpimg_/nl/ttopicof.gif}
+## "themas" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=nl] {_httpimg_/nl/h\_topic.gif}
+_widthhtopic_ [l=nl] {200}
+_heighthtopic_ [l=nl] {57}
+## "temat" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=pl] {_httpimg_/pl/ttopicgr.gif}
+_httpiconttopicon_ [l=pl] {_httpimg_/pl/ttopicon.gif}
+_httpiconttopicof_ [l=pl] {_httpimg_/pl/ttopicof.gif}
+## "tematy" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=pl] {_httpimg_/pl/h\_topic.gif}
+_widthhtopic_ [l=pl] {200}
+_heighthtopic_ [l=pl] {57}
+## "tÃ³pico" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=pt-br] {_httpimg_/pt-br/ttopicgr.gif}
+_httpiconttopicon_ [l=pt-br] {_httpimg_/pt-br/ttopicon.gif}
+_httpiconttopicof_ [l=pt-br] {_httpimg_/pt-br/ttopicof.gif}
+## "tÃ³picos" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=pt-br] {_httpimg_/pt-br/h\_topic.gif}
+_widthhtopic_ [l=pt-br] {200}
+_heighthtopic_ [l=pt-br] {57}
+## "tÃ³pico" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=pt-pt] {_httpimg_/pt-pt/ttopicgr.gif}
+_httpiconttopicon_ [l=pt-pt] {_httpimg_/pt-pt/ttopicon.gif}
+_httpiconttopicof_ [l=pt-pt] {_httpimg_/pt-pt/ttopicof.gif}
+## "tÃ³picos" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=pt-pt] {_httpimg_/pt-pt/h\_topic.gif}
+_widthhtopic_ [l=pt-pt] {200}
+_heighthtopic_ [l=pt-pt] {57}
+## "ÑÐµÐŒÑ" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=ru] {_httpimg_/ru/ttopicgr.gif}
+_httpiconttopicon_ [l=ru] {_httpimg_/ru/ttopicon.gif}
+_httpiconttopicof_ [l=ru] {_httpimg_/ru/ttopicof.gif}
+## "ÑÐµÐŒÑ" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=ru] {_httpimg_/ru/h\_topic.gif}
+_widthhtopic_ [l=ru] {200}
+_heighthtopic_ [l=ru] {57}
+## "tema" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=sr] {_httpimg_/sr/ttopicgr.gif}
+_httpiconttopicon_ [l=sr] {_httpimg_/sr/ttopicon.gif}
+_httpiconttopicof_ [l=sr] {_httpimg_/sr/ttopicof.gif}
+## "teme" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=sr] {_httpimg_/sr/h\_topic.gif}
+_widthhtopic_ [l=sr] {200}
+_heighthtopic_ [l=sr] {57}
+## "àž«àž±àž§àžà¹àž­" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=th] {_httpimg_/th/ttopicgr.gif}
+_httpiconttopicon_ [l=th] {_httpimg_/th/ttopicon.gif}
+_httpiconttopicof_ [l=th] {_httpimg_/th/ttopicof.gif}
+## "àž«àž±àž§àžà¹àž­" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=th] {_httpimg_/th/h\_topic.gif}
+_widthhtopic_ [l=th] {200}
+_heighthtopic_ [l=th] {57}
+## "konu" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=tr] {_httpimg_/tr/ttopicgr.gif}
+_httpiconttopicon_ [l=tr] {_httpimg_/tr/ttopicon.gif}
+_httpiconttopicof_ [l=tr] {_httpimg_/tr/ttopicof.gif}
+## "konular" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=tr] {_httpimg_/tr/h\_topic.gif}
+_widthhtopic_ [l=tr] {200}
+_heighthtopic_ [l=tr] {57}
+## "ÑÐµÐŒÐ°" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=uk] {_httpimg_/uk/ttopicgr.gif}
+_httpiconttopicon_ [l=uk] {_httpimg_/uk/ttopicon.gif}
+_httpiconttopicof_ [l=uk] {_httpimg_/uk/ttopicof.gif}
+## "ÑÐµÐŒÐž Ð°-Ñ" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=uk] {_httpimg_/uk/h\_topic.gif}
+_widthhtopic_ [l=uk] {200}
+_heighthtopic_ [l=uk] {57}
+## "chá»§ Äá»" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=vi] {_httpimg_/vi/ttopicgr.gif}
+_httpiconttopicon_ [l=vi] {_httpimg_/vi/ttopicon.gif}
+_httpiconttopicof_ [l=vi] {_httpimg_/vi/ttopicof.gif}
+## "chá»§ Äá»" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=vi] {_httpimg_/vi/h\_topic.gif}
+_widthhtopic_ [l=vi] {200}
+_heighthtopic_ [l=vi] {57}
+## "è®ºé¢" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=zh] {_httpimg_/zh/ttopicgr.gif}
+_httpiconttopicon_ [l=zh] {_httpimg_/zh/ttopicon.gif}
+_httpiconttopicof_ [l=zh] {_httpimg_/zh/ttopicof.gif}
+## "æ é¢" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=zh] {_httpimg_/zh/h\_topic.gif}
+_widthhtopic_ [l=zh] {200}
+_heighthtopic_ [l=zh] {57}
+## "è­°é¡" ## nav_bar_button ## ttopic ##
+_httpiconttopicgr_ [l=zh-tr] {_httpimg_/zh-tr/ttopicgr.gif}
+_httpiconttopicon_ [l=zh-tr] {_httpimg_/zh-tr/ttopicon.gif}
+_httpiconttopicof_ [l=zh-tr] {_httpimg_/zh-tr/ttopicof.gif}
+## "äž»æš" ## green_title ## h_topic ##
+_httpiconhtopic_ [l=zh-tr] {_httpimg_/zh-tr/h\_topic.gif}
+_widthhtopic_ [l=zh-tr] {200}
+_heighthtopic_ [l=zh-tr] {57}
+
+## "types" ## nav_bar_button ## ttype ##
+_httpiconttypegr_ {_httpimg_/en/ttypegr.gif}
+_httpiconttypeof_ {_httpimg_/en/ttypeof.gif}
+_httpiconttypeon_ {_httpimg_/en/ttypeon.gif}
+## "types" ## green_title ## h_type ##
+_httpiconhtype_ {_httpimg_/en/h\_type.gif}
+_widthhtype_ {200}
+_heighthtype_ {57}
+## "àŠ°àŠàŠ®àŠ­à§àŠŠ" ## nav_bar_button ## ttype ##
+_httpiconttypegr_ [l=bn] {_httpimg_/bn/ttypegr.gif}
+_httpiconttypeof_ [l=bn] {_httpimg_/bn/ttypeof.gif}
+_httpiconttypeon_ [l=bn] {_httpimg_/bn/ttypeon.gif}
+## "àŠªà§àŠ°àŠàŠŸàŠ°àŠ­à§àŠŠ" ## green_title ## h_type ##
+_httpiconhtype_ [l=bn] {_httpimg_/bn/h\_type.gif}
+_widthhtype_ [l=bn] {200}
+_heighthtype_ [l=bn] {57}
+## "tipos" ## nav_bar_button ## ttype ##
+_httpiconttypegr_ [l=es] {_httpimg_/es/ttypegr.gif}
+_httpiconttypeof_ [l=es] {_httpimg_/es/ttypeof.gif}
+_httpiconttypeon_ [l=es] {_httpimg_/es/ttypeon.gif}
+## "tipos" ## green_title ## h_type ##
+_httpiconhtype_ [l=es] {_httpimg_/es/h\_type.gif}
+_widthhtype_ [l=es] {200}
+_heighthtype_ [l=es] {57}
+## "Genres" ## nav_bar_button ## ttype ##
+_httpiconttypegr_ [l=fr] {_httpimg_/fr/ttypegr.gif}
+_httpiconttypeof_ [l=fr] {_httpimg_/fr/ttypeof.gif}
+_httpiconttypeon_ [l=fr] {_httpimg_/fr/ttypeon.gif}
+## "Genres" ## green_title ## h_type ##
+_httpiconhtype_ [l=fr] {_httpimg_/fr/h\_type.gif}
+_widthhtype_ [l=fr] {200}
+_heighthtype_ [l=fr] {57}
+## "tipe" ## nav_bar_button ## ttype ##
+_httpiconttypegr_ [l=id] {_httpimg_/id/ttypegr.gif}
+_httpiconttypeof_ [l=id] {_httpimg_/id/ttypeof.gif}
+_httpiconttypeon_ [l=id] {_httpimg_/id/ttypeon.gif}
+## "tipe" ## green_title ## h_type ##
+_httpiconhtype_ [l=id] {_httpimg_/id/h\_type.gif}
+_widthhtype_ [l=id] {200}
+_heighthtype_ [l=id] {57}
+## "ÑÐžÐ¿ÑÐµÑ" ## nav_bar_button ## ttype ##
+_httpiconttypegr_ [l=ky] {_httpimg_/ky/ttypegr.gif}
+_httpiconttypeof_ [l=ky] {_httpimg_/ky/ttypeof.gif}
+_httpiconttypeon_ [l=ky] {_httpimg_/ky/ttypeon.gif}
+## "ÑÐžÐ¿ÑÐµÑ" ## green_title ## h_type ##
+_httpiconhtype_ [l=ky] {_httpimg_/ky/h\_type.gif}
+_widthhtype_ [l=ky] {200}
+_heighthtype_ [l=ky] {57}
+## "tipi" ## nav_bar_button ## ttype ##
+_httpiconttypegr_ [l=lv] {_httpimg_/lv/ttypegr.gif}
+_httpiconttypeof_ [l=lv] {_httpimg_/lv/ttypeof.gif}
+_httpiconttypeon_ [l=lv] {_httpimg_/lv/ttypeon.gif}
+## "tipi" ## green_title ## h_type ##
+_httpiconhtype_ [l=lv] {_httpimg_/lv/h\_type.gif}
+_widthhtype_ [l=lv] {200}
+_heighthtype_ [l=lv] {57}
+## "ÑÓ©ÑÐ»Ò¯Ò¯ÐŽ" ## nav_bar_button ## ttype ##
+_httpiconttypegr_ [l=mn] {_httpimg_/mn/ttypegr.gif}
+_httpiconttypeof_ [l=mn] {_httpimg_/mn/ttypeof.gif}
+_httpiconttypeon_ [l=mn] {_httpimg_/mn/ttypeon.gif}
+## "ÑÓ©ÑÐ»Ò¯Ò¯ÐŽ" ## green_title ## h_type ##
+_httpiconhtype_ [l=mn] {_httpimg_/mn/h\_type.gif}
+_widthhtype_ [l=mn] {200}
+_heighthtype_ [l=mn] {57}
+## "typy" ## nav_bar_button ## ttype ##
+_httpiconttypegr_ [l=pl] {_httpimg_/pl/ttypegr.gif}
+_httpiconttypeof_ [l=pl] {_httpimg_/pl/ttypeof.gif}
+_httpiconttypeon_ [l=pl] {_httpimg_/pl/ttypeon.gif}
+## "typy" ## green_title ## h_type ##
+_httpiconhtype_ [l=pl] {_httpimg_/pl/h\_type.gif}
+_widthhtype_ [l=pl] {200}
+_heighthtype_ [l=pl] {57}
+## "ÑÐžÐ¿Ñ" ## nav_bar_button ## ttype ##
+_httpiconttypegr_ [l=ru] {_httpimg_/ru/ttypegr.gif}
+_httpiconttypeof_ [l=ru] {_httpimg_/ru/ttypeof.gif}
+_httpiconttypeon_ [l=ru] {_httpimg_/ru/ttypeon.gif}
+## "ÑÐžÐ¿Ñ" ## green_title ## h_type ##
+_httpiconhtype_ [l=ru] {_httpimg_/ru/h\_type.gif}
+_widthhtype_ [l=ru] {200}
+_heighthtype_ [l=ru] {57}
+## "é¡å" ## nav_bar_button ## ttype ##
+_httpiconttypegr_ [l=zh-tr] {_httpimg_/zh-tr/ttypegr.gif}
+_httpiconttypeof_ [l=zh-tr] {_httpimg_/zh-tr/ttypeof.gif}
+_httpiconttypeon_ [l=zh-tr] {_httpimg_/zh-tr/ttypeon.gif}
+## "é¡å" ## green_title ## h_type ##
+_httpiconhtype_ [l=zh-tr] {_httpimg_/zh-tr/h\_type.gif}
+_widthhtype_ [l=zh-tr] {200}
+_heighthtype_ [l=zh-tr] {57}
+
+## "volumes" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ {_httpimg_/en/tvolgr.gif}
+_httpicontvolof_ {_httpimg_/en/tvolof.gif}
+_httpicontvolon_ {_httpimg_/en/tvolon.gif}
+## "volumes" ## green_title ## h_vol ##
+_httpiconhvol_ {_httpimg_/en/h\_vol.gif}
+_widthhvol_ {200}
+_heighthvol_ {57}
+## "Ø§ÙÙ
+Ø¬ÙØ¯Ø§Øª" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=ar] {_httpimg_/ar/tvolgr.gif}
+_httpicontvolof_ [l=ar] {_httpimg_/ar/tvolof.gif}
+_httpicontvolon_ [l=ar] {_httpimg_/ar/tvolon.gif}
+## "Ø§ÙÙ
+Ø¬ÙØ¯Ø§Øª" ## green_title ## h_vol ##
+_httpiconhvol_ [l=ar] {_httpimg_/ar/h\_vol.gif}
+_widthhvol_ [l=ar] {200}
+_heighthvol_ [l=ar] {57}
+## "àŠàŠšà§àŠ¡" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=bn] {_httpimg_/bn/tvolgr.gif}
+_httpicontvolof_ [l=bn] {_httpimg_/bn/tvolof.gif}
+_httpicontvolon_ [l=bn] {_httpimg_/bn/tvolon.gif}
+## "àŠàŠšà§àŠ¡àŠà§àŠ²àŠ¿" ## green_title ## h_vol ##
+_httpiconhvol_ [l=bn] {_httpimg_/bn/h\_vol.gif}
+_widthhvol_ [l=bn] {200}
+_heighthvol_ [l=bn] {57}
+## "volums" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=ca] {_httpimg_/ca/tvolgr.gif}
+_httpicontvolof_ [l=ca] {_httpimg_/ca/tvolof.gif}
+_httpicontvolon_ [l=ca] {_httpimg_/ca/tvolon.gif}
+## "volums" ## green_title ## h_vol ##
+_httpiconhvol_ [l=ca] {_httpimg_/ca/h\_vol.gif}
+_widthhvol_ [l=ca] {200}
+_heighthvol_ [l=ca] {57}
+## "svazky" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=cs] {_httpimg_/cs/tvolgr.gif}
+_httpicontvolof_ [l=cs] {_httpimg_/cs/tvolof.gif}
+_httpicontvolon_ [l=cs] {_httpimg_/cs/tvolon.gif}
+## "roÄnÃ­ky" ## green_title ## h_vol ##
+_httpiconhvol_ [l=cs] {_httpimg_/cs/h\_vol.gif}
+_widthhvol_ [l=cs] {200}
+_heighthvol_ [l=cs] {57}
+## "ÏÏÎŒÎ¿Î¹" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=el] {_httpimg_/el/tvolgr.gif}
+_httpicontvolof_ [l=el] {_httpimg_/el/tvolof.gif}
+_httpicontvolon_ [l=el] {_httpimg_/el/tvolon.gif}
+## "ÏÏÎŒÎ¿Î¹" ## green_title ## h_vol ##
+_httpiconhvol_ [l=el] {_httpimg_/el/h\_vol.gif}
+_widthhvol_ [l=el] {200}
+_heighthvol_ [l=el] {57}
+## "volÃºmenes" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=es] {_httpimg_/es/tvolgr.gif}
+_httpicontvolof_ [l=es] {_httpimg_/es/tvolof.gif}
+_httpicontvolon_ [l=es] {_httpimg_/es/tvolon.gif}
+## "volÃºmenes" ## green_title ## h_vol ##
+_httpiconhvol_ [l=es] {_httpimg_/es/h\_vol.gif}
+_widthhvol_ [l=es] {200}
+_heighthvol_ [l=es] {57}
+## "Ù
+Ø¬ÙØ¯Ø§Øª" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=fa] {_httpimg_/fa/tvolgr.gif}
+_httpicontvolof_ [l=fa] {_httpimg_/fa/tvolof.gif}
+_httpicontvolon_ [l=fa] {_httpimg_/fa/tvolon.gif}
+## "Ù
+Ø¬ÙØ¯Ø§Øª" ## green_title ## h_vol ##
+_httpiconhvol_ [l=fa] {_httpimg_/fa/h\_vol.gif}
+_widthhvol_ [l=fa] {200}
+_heighthvol_ [l=fa] {57}
+## "volyymit" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=fi] {_httpimg_/fi/tvolgr.gif}
+_httpicontvolof_ [l=fi] {_httpimg_/fi/tvolof.gif}
+_httpicontvolon_ [l=fi] {_httpimg_/fi/tvolon.gif}
+## "volyymit" ## green_title ## h_vol ##
+_httpiconhvol_ [l=fi] {_httpimg_/fi/h\_vol.gif}
+_widthhvol_ [l=fi] {200}
+_heighthvol_ [l=fi] {57}
+## "volumes" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=fr] {_httpimg_/fr/tvolgr.gif}
+_httpicontvolof_ [l=fr] {_httpimg_/fr/tvolof.gif}
+_httpicontvolon_ [l=fr] {_httpimg_/fr/tvolon.gif}
+## "volumes" ## green_title ## h_vol ##
+_httpiconhvol_ [l=fr] {_httpimg_/fr/h\_vol.gif}
+_widthhvol_ [l=fr] {200}
+_heighthvol_ [l=fr] {57}
+## "volumes" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=gl] {_httpimg_/gl/tvolgr.gif}
+_httpicontvolof_ [l=gl] {_httpimg_/gl/tvolof.gif}
+_httpicontvolon_ [l=gl] {_httpimg_/gl/tvolon.gif}
+## "volumes" ## green_title ## h_vol ##
+_httpiconhvol_ [l=gl] {_httpimg_/gl/h\_vol.gif}
+_widthhvol_ [l=gl] {200}
+_heighthvol_ [l=gl] {57}
+## "Õ°Õ¡Õ¿ÕžÖÕ¶Õ¥Ö" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=hy] {_httpimg_/hy/tvolgr.gif}
+_httpicontvolof_ [l=hy] {_httpimg_/hy/tvolof.gif}
+_httpicontvolon_ [l=hy] {_httpimg_/hy/tvolon.gif}
+## "Õ°Õ¡Õ¿ÕžÖÕ¶Õ¥Ö" ## green_title ## h_vol ##
+_httpiconhvol_ [l=hy] {_httpimg_/hy/h\_vol.gif}
+_widthhvol_ [l=hy] {200}
+_heighthvol_ [l=hy] {57}
+## "jilid" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=id] {_httpimg_/id/tvolgr.gif}
+_httpicontvolof_ [l=id] {_httpimg_/id/tvolof.gif}
+_httpicontvolon_ [l=id] {_httpimg_/id/tvolon.gif}
+## "jilid" ## green_title ## h_vol ##
+_httpiconhvol_ [l=id] {_httpimg_/id/h\_vol.gif}
+_widthhvol_ [l=id] {200}
+_heighthvol_ [l=id] {57}
+## "volumi" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=it] {_httpimg_/it/tvolgr.gif}
+_httpicontvolof_ [l=it] {_httpimg_/it/tvolof.gif}
+_httpicontvolon_ [l=it] {_httpimg_/it/tvolon.gif}
+## "volumi" ## green_title ## h_vol ##
+_httpiconhvol_ [l=it] {_httpimg_/it/h\_vol.gif}
+_widthhvol_ [l=it] {200}
+_heighthvol_ [l=it] {57}
+## "á¢ááááá" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=ka] {_httpimg_/ka/tvolgr.gif}
+_httpicontvolof_ [l=ka] {_httpimg_/ka/tvolof.gif}
+_httpicontvolon_ [l=ka] {_httpimg_/ka/tvolon.gif}
+## "á¢ááááá" ## green_title ## h_vol ##
+_httpiconhvol_ [l=ka] {_httpimg_/ka/h\_vol.gif}
+_widthhvol_ [l=ka] {258}
+_heighthvol_ [l=ka] {74}
+## "ÑÐŸÐŒÐŽÐŸÑ" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=ky] {_httpimg_/ky/tvolgr.gif}
+_httpicontvolof_ [l=ky] {_httpimg_/ky/tvolof.gif}
+_httpicontvolon_ [l=ky] {_httpimg_/ky/tvolon.gif}
+## "ÑÐŸÐŒÐŽÐŸÑ" ## green_title ## h_vol ##
+_httpiconhvol_ [l=ky] {_httpimg_/ky/h\_vol.gif}
+_widthhvol_ [l=ky] {200}
+_heighthvol_ [l=ky] {57}
+## "sÄjumi" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=lv] {_httpimg_/lv/tvolgr.gif}
+_httpicontvolof_ [l=lv] {_httpimg_/lv/tvolof.gif}
+_httpicontvolon_ [l=lv] {_httpimg_/lv/tvolon.gif}
+## "sÄjumi" ## green_title ## h_vol ##
+_httpiconhvol_ [l=lv] {_httpimg_/lv/h\_vol.gif}
+_widthhvol_ [l=lv] {200}
+_heighthvol_ [l=lv] {57}
+## "pukapuka" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=mi] {_httpimg_/mi/tvolgr.gif}
+_httpicontvolof_ [l=mi] {_httpimg_/mi/tvolof.gif}
+_httpicontvolon_ [l=mi] {_httpimg_/mi/tvolon.gif}
+## "pukapuka" ## green_title ## h_vol ##
+_httpiconhvol_ [l=mi] {_httpimg_/mi/h\_vol.gif}
+_widthhvol_ [l=mi] {200}
+_heighthvol_ [l=mi] {57}
+## "Ð±ÐŸÑÐžÑÐŽ" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=mn] {_httpimg_/mn/tvolgr.gif}
+_httpicontvolof_ [l=mn] {_httpimg_/mn/tvolof.gif}
+_httpicontvolon_ [l=mn] {_httpimg_/mn/tvolon.gif}
+## "Ð±ÐŸÑÐžÑÐŽ" ## green_title ## h_vol ##
+_httpiconhvol_ [l=mn] {_httpimg_/mn/h\_vol.gif}
+_widthhvol_ [l=mn] {200}
+_heighthvol_ [l=mn] {57}
+## "wolumeny" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=pl] {_httpimg_/pl/tvolgr.gif}
+_httpicontvolof_ [l=pl] {_httpimg_/pl/tvolof.gif}
+_httpicontvolon_ [l=pl] {_httpimg_/pl/tvolon.gif}
+## "wolumeny" ## green_title ## h_vol ##
+_httpiconhvol_ [l=pl] {_httpimg_/pl/h\_vol.gif}
+_widthhvol_ [l=pl] {200}
+_heighthvol_ [l=pl] {57}
+## "volumes" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=pt-pt] {_httpimg_/pt-pt/tvolgr.gif}
+_httpicontvolof_ [l=pt-pt] {_httpimg_/pt-pt/tvolof.gif}
+_httpicontvolon_ [l=pt-pt] {_httpimg_/pt-pt/tvolon.gif}
+## "volumes" ## green_title ## h_vol ##
+_httpiconhvol_ [l=pt-pt] {_httpimg_/pt-pt/h\_vol.gif}
+_widthhvol_ [l=pt-pt] {200}
+_heighthvol_ [l=pt-pt] {57}
+## "ÐžÐ·ÐŽÐ°ÐœÐžÑ" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=ru] {_httpimg_/ru/tvolgr.gif}
+_httpicontvolof_ [l=ru] {_httpimg_/ru/tvolof.gif}
+_httpicontvolon_ [l=ru] {_httpimg_/ru/tvolon.gif}
+## "ÐžÐ·ÐŽÐ°ÐœÐžÑ" ## green_title ## h_vol ##
+_httpiconhvol_ [l=ru] {_httpimg_/ru/h\_vol.gif}
+_widthhvol_ [l=ru] {200}
+_heighthvol_ [l=ru] {57}
+## "sveske" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=sr] {_httpimg_/sr/tvolgr.gif}
+_httpicontvolof_ [l=sr] {_httpimg_/sr/tvolof.gif}
+_httpicontvolon_ [l=sr] {_httpimg_/sr/tvolon.gif}
+## "sveske" ## green_title ## h_vol ##
+_httpiconhvol_ [l=sr] {_httpimg_/sr/h\_vol.gif}
+_widthhvol_ [l=sr] {200}
+_heighthvol_ [l=sr] {57}
+## "à¹àžªàžµàž¢àž" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=th] {_httpimg_/th/tvolgr.gif}
+_httpicontvolof_ [l=th] {_httpimg_/th/tvolof.gif}
+_httpicontvolon_ [l=th] {_httpimg_/th/tvolon.gif}
+## "àžàž£àžŽàž¡àž²àž" ## green_title ## h_vol ##
+_httpiconhvol_ [l=th] {_httpimg_/th/h\_vol.gif}
+_widthhvol_ [l=th] {200}
+_heighthvol_ [l=th] {57}
+## "ciltler" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=tr] {_httpimg_/tr/tvolgr.gif}
+_httpicontvolof_ [l=tr] {_httpimg_/tr/tvolof.gif}
+_httpicontvolon_ [l=tr] {_httpimg_/tr/tvolon.gif}
+## "ciltler" ## green_title ## h_vol ##
+_httpiconhvol_ [l=tr] {_httpimg_/tr/h\_vol.gif}
+_widthhvol_ [l=tr] {200}
+_heighthvol_ [l=tr] {57}
+## "ÑÐŸÐŒÐž" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=uk] {_httpimg_/uk/tvolgr.gif}
+_httpicontvolof_ [l=uk] {_httpimg_/uk/tvolof.gif}
+_httpicontvolon_ [l=uk] {_httpimg_/uk/tvolon.gif}
+## "ÑÐŸÐŒÐž" ## green_title ## h_vol ##
+_httpiconhvol_ [l=uk] {_httpimg_/uk/h\_vol.gif}
+_widthhvol_ [l=uk] {200}
+_heighthvol_ [l=uk] {57}
+## "quyá»n" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=vi] {_httpimg_/vi/tvolgr.gif}
+_httpicontvolof_ [l=vi] {_httpimg_/vi/tvolof.gif}
+_httpicontvolon_ [l=vi] {_httpimg_/vi/tvolon.gif}
+## "quyá»n" ## green_title ## h_vol ##
+_httpiconhvol_ [l=vi] {_httpimg_/vi/h\_vol.gif}
+_widthhvol_ [l=vi] {200}
+_heighthvol_ [l=vi] {57}
+## "å·æ°" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=zh] {_httpimg_/zh/tvolgr.gif}
+_httpicontvolof_ [l=zh] {_httpimg_/zh/tvolof.gif}
+_httpicontvolon_ [l=zh] {_httpimg_/zh/tvolon.gif}
+## "å·æ°" ## green_title ## h_vol ##
+_httpiconhvol_ [l=zh] {_httpimg_/zh/h\_vol.gif}
+_widthhvol_ [l=zh] {200}
+_heighthvol_ [l=zh] {57}
+## "å¢æž" ## nav_bar_button ## tvol ##
+_httpicontvolgr_ [l=zh-tr] {_httpimg_/zh-tr/tvolgr.gif}
+_httpicontvolof_ [l=zh-tr] {_httpimg_/zh-tr/tvolof.gif}
+_httpicontvolon_ [l=zh-tr] {_httpimg_/zh-tr/tvolon.gif}
+## "å¢æž" ## green_title ## h_vol ##
+_httpiconhvol_ [l=zh-tr] {_httpimg_/zh-tr/h\_vol.gif}
+_widthhvol_ [l=zh-tr] {200}
+_heighthvol_ [l=zh-tr] {57}
+
+#######################
+# Collector images
+######################
+
+
+#################
+# Title image
+#################
+
+## "The collector" ## green_title ## h_colect ## en
+_httpiconhcolect_ {_httpimg_/en/h\_colect.gif}
+## "El colÂ·leccionista" ## green_title ## h_colect ## ca
+_httpiconhcolect_ [l=ca] {_httpimg_/ca/h\_colect.gif}
+## "Collector" ## green_title ## h_colect ## cs
+_httpiconhcolect_ [l=cs] {_httpimg_/cs/h\_colect.gif}
+## "El colector" ## green_title ## h_colect ## es
+_httpiconhcolect_ [l=es] {_httpimg_/es/h\_colect.gif}
+## "Le collector" ## green_title ## h_colect ## fr
+_httpiconhcolect_ [l=fr] {_httpimg_/fr/h\_colect.gif}
+## "O coleccionista" ## green_title ## h_colect ## gl
+_httpiconhcolect_ [l=gl] {_httpimg_/gl/h\_colect.gif}
+## "Il collector" ## green_title ## h_colect ## it
+_httpiconhcolect_ [l=it] {_httpimg_/it/h\_colect.gif}
+## "ááááá¥á¢áá á" ## green_title ## h_colect ## ka
+_httpiconhcolect_ [l=ka] {_httpimg_/ka/h\_colect.gif}
+## "ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ" ## green_title ## h_colect ## kk
+_httpiconhcolect_ [l=kk] {_httpimg_/kk/h\_colect.gif}
+## "Kolektors" ## green_title ## h_colect ## lv
+_httpiconhcolect_ [l=lv] {_httpimg_/lv/h\_colect.gif}
+## "ÐŠÑÐ³Ð»ÑÑÐ»Ð°Ð³Ñ" ## green_title ## h_colect ## mn
+_httpiconhcolect_ [l=mn] {_httpimg_/mn/h\_colect.gif}
+## "ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ" ## green_title ## h_colect ## ru
+_httpiconhcolect_ [l=ru] {_httpimg_/ru/h\_colect.gif}
+## "Táº¡o bá» sÆ°u táº­p" ## green_title ## h_colect ## vi
+_httpiconhcolect_ [l=vi] {_httpimg_/vi/h\_colect.gif}
+## "å
+žèè³æåº«" ## green_title ## h_colect ## zh-tr
+_httpiconhcolect_ [l=zh-tr] {_httpimg_/zh-tr/h\_colect.gif}
+
+########################
+# Collector bar buttons
+########################
+
+## "collection\ninformation" ## collector_bar_button ## info ## en
+## "informaciÃ³ de\nla colÂ·lecciÃ³" ## collector_bar_button ## info ## ca
+## "informace o\n    kolekci" ## collector_bar_button ## info ## cs
+## "informaciones\nsobre la colecciÃ³n" ## collector_bar_button ## info ## es
+## "informations\nsur la collection" ## collector_bar_button ## info ## fr
+## "informaciÃ³ns\nsobre a colecciÃ³n" ## collector_bar_button ## info ## gl
+## "informazioni\nsulla collezione" ## collector_bar_button ## info ## it
+## "ááá€áá áááªáá\nááááá¥áªááá¡\nášá¬á¡áá®áá" ## collector_bar_button ## info ## ka
+## "ÐÐŸÐ»Ð»ÐµÐºÑÐžÑÐ»Ð°Ñ\nÐ°ÒÐ¿Ð°ÑÐ°ÑÑ" ## collector_bar_button ## info ## kk
+## "kolekcijas\ninformÄcija" ## collector_bar_button ## info ## lv  # Updated 19-Aug-2005
+## "ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐœ\nÑÑÑ
+Ð°Ð¹\nÐŒÑÐŽÑÑÐ»ÑÐ»" ## collector_bar_button ## info ## mn
+## "collection\ninformation" ## collector_bar_button ## info ## ru
+## "thÃŽng tin bá»\nsÆ°u táº­p" ## collector_bar_button ## info ## vi
+## "å
+žèè³æåº«è³èš" ## collector_bar_button ## info ## zh-tr
+
+## "configure\ncollection" ## collector_bar_button ## conf ##
+_httpicongcconfof_ {_httpimg_/en/gcconfof.gif}
+_httpicongcconfon_ {_httpimg_/en/gcconfon.gif}
+_httpiconycconfof_ {_httpimg_/en/ycconfof.gif}
+## "configura\nla colÂ·lecciÃ³" ## collector_bar_button ## conf ##
+_httpicongcconfof_ [l=ca] {_httpimg_/ca/gcconfof.gif}
+_httpicongcconfon_ [l=ca] {_httpimg_/ca/gcconfon.gif}
+_httpiconycconfof_ [l=ca] {_httpimg_/ca/ycconfof.gif}
+## "konfigurovat\n     kolekci" ## collector_bar_button ## conf ##
+_httpicongcconfof_ [l=cs] {_httpimg_/cs/gcconfof.gif}
+_httpicongcconfon_ [l=cs] {_httpimg_/cs/gcconfon.gif}
+_httpiconycconfof_ [l=cs] {_httpimg_/cs/ycconfof.gif}
+## "configurar\nla colecciÃ³n" ## collector_bar_button ## conf ##
+_httpicongcconfof_ [l=es] {_httpimg_/es/gcconfof.gif}
+_httpicongcconfon_ [l=es] {_httpimg_/es/gcconfon.gif}
+_httpiconycconfof_ [l=es] {_httpimg_/es/ycconfof.gif}
+## "configurer\nla collection" ## collector_bar_button ## conf ##
+_httpicongcconfof_ [l=fr] {_httpimg_/fr/gcconfof.gif}
+_httpicongcconfon_ [l=fr] {_httpimg_/fr/gcconfon.gif}
+_httpiconycconfof_ [l=fr] {_httpimg_/fr/ycconfof.gif}
+## "configurar\na colecciÃ³n" ## collector_bar_button ## conf ##
+_httpicongcconfof_ [l=gl] {_httpimg_/gl/gcconfof.gif}
+_httpicongcconfon_ [l=gl] {_httpimg_/gl/gcconfon.gif}
+_httpiconycconfof_ [l=gl] {_httpimg_/gl/ycconfof.gif}
+## "configura\nla collezione" ## collector_bar_button ## conf ##
+_httpicongcconfof_ [l=it] {_httpimg_/it/gcconfof.gif}
+_httpicongcconfon_ [l=it] {_httpimg_/it/gcconfon.gif}
+_httpiconycconfof_ [l=it] {_httpimg_/it/ycconfof.gif}
+## "ááááá¥áªááá¡\náááá€ááá£á ááªáá" ## collector_bar_button ## conf ##
+_httpicongcconfof_ [l=ka] {_httpimg_/ka/gcconfof.gif}
+_httpicongcconfon_ [l=ka] {_httpimg_/ka/gcconfon.gif}
+_httpiconycconfof_ [l=ka] {_httpimg_/ka/ycconfof.gif}
+## "ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ\nÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÑÑÑ" ## collector_bar_button ## conf ##
+_httpicongcconfof_ [l=kk] {_httpimg_/kz/gcconfof.gif}
+_httpicongcconfon_ [l=kk] {_httpimg_/kz/gcconfon.gif}
+_httpiconycconfof_ [l=kk] {_httpimg_/kz/ycconfof.gif}
+## "ÑÑÐ³Ð»ÑÑÐ»Ð³ÑÐ³\nÑÐŸÑ
+ÐžÑÑÑÐ»Ð°Ñ
+" ## collector_bar_button ## conf ##
+_httpicongcconfof_ [l=mn] {_httpimg_/mn/gcconfof.gif}
+_httpicongcconfon_ [l=mn] {_httpimg_/mn/gcconfon.gif}
+_httpiconycconfof_ [l=mn] {_httpimg_/mn/ycconfof.gif}
+## "configure\ncollection" ## collector_bar_button ## conf ##
+_httpicongcconfof_ [l=ru] {_httpimg_/ru/gcconfof.gif}
+_httpicongcconfon_ [l=ru] {_httpimg_/ru/gcconfon.gif}
+_httpiconycconfof_ [l=ru] {_httpimg_/ru/ycconfof.gif}
+## "cáº¥u hÃ¬nh bá»\nsÆ°u táº­p" ## collector_bar_button ## conf ##
+_httpicongcconfof_ [l=vi] {_httpimg_/vi/gcconfof.gif}
+_httpicongcconfon_ [l=vi] {_httpimg_/vi/gcconfon.gif}
+_httpiconycconfof_ [l=vi] {_httpimg_/vi/ycconfof.gif}
+## "èš­å®å
+žèè³æåº«" ## collector_bar_button ## conf ##
+_httpicongcconfof_ [l=zh-tr] {_httpimg_/zh-tr/gcconfof.gif}
+_httpicongcconfon_ [l=zh-tr] {_httpimg_/zh-tr/gcconfon.gif}
+_httpiconycconfof_ [l=zh-tr] {_httpimg_/zh-tr/ycconfof.gif}
+
+
Index: /gsdl/stable/macros/nepali.dm
===================================================================
--- /gsdl/stable/macros/nepali.dm	(revision 20131)
+++ /gsdl/stable/macros/nepali.dm	(revision 20131)
@@ -0,0 +1,708 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Nepali Language text and icon macros 
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=ne] {à€à€µà€§à€¿à€}
+
+# these three used by the default format statement of the demo and dls collections.
+# -- Missing translation: _textsource_ 
+_textdate_ [l=ne] {à€ªà¥à€°à€à€Ÿà€¶à€¿à€€ à€®à€¿à€€à€¿ }
+_textnumpages_ [l=ne]  {à€ªà¥à€·à¥à€  à€žà€à€à¥à€¯à€Ÿ }
+
+_textsignin_ [l=ne] {à€­à€¿à€€à¥à€° à€ªà€žà¥à€šà¥à€¹à¥à€ž}
+
+# -- Missing translation: _textdefaultcontent_ 
+
+_textdefaulttitle_ [l=ne] {à€à€¿â à€à€ž à€¡à€¿ à€à€² à€à¥ à€Šà¥à€·}
+
+# -- Missing translation: _textbadcollection_ 
+
+# -- Missing translation: _textselectpage_
+
+# -- Missing translation: _collectionextra_ 
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+# -- Missing translation: _collectorextra_
+
+_textdescrcollection_ [l=ne] {}
+_textdescrabout_ [l=ne] {à€ªà¥à€·à¥à€ à€à€Ÿ à€µà€Ÿà€°à¥à€®à€Ÿ}
+_textdescrhome_ [l=ne] {à€à¥à€¹ à€ªà¥à€·à¥à€ }
+_textdescrhelp_ [l=ne] {à€žà€¹à€¯à¥à€à¥ à€ªà¥à€·à¥à€ }
+_textdescrpref_ [l=ne] {à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿ à€ªà¥à€°à€Ÿà€ªà¥à€€ à€ªà¥à€·à¥à€ }
+_textdescrgreenstone_ [l=ne] {à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€¡à€¿à€à€¿à€à€² à€²à€Ÿà€à€µà¥à€°à¥à€°à¥ à€žà€«à¥à€à€µà¥à€¯à€°}
+_textdescrusab_ [l=ne] {à€ªà¥à€°à€¯à¥à€ à€à€°à¥à€šà¥ à€à€Ÿà€°à¥à€¯à€®à€Ÿ à€à¥ à€à¥à€°à€Ÿ à€à€Ÿà€¹âà¥ à€ªà€Ÿà€à€šà¥à€­à€¯à¥}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=ne] {à€à¥à€}
+_labelSearch_ [l=ne] {à€à¥à€}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=ne] {à€¶à¥à€°à¥à€·à€}
+_labelTitle_ [l=ne] {à€¶à¥à€°à¥à€·à€ A-Z}
+_textCreator_ [l=ne] {à€žà€¿à€°à¥à€à€šà€Ÿ à€à€°à¥à€šà¥ à€®à€Ÿà€šà¥à€à¥}
+# -- Missing translation: _labelCreator_
+_textSubject_ [l=ne] {à€µà€¿à€·à€¯}
+_labelSubject_ [l=ne] {à€µà€¿à€·à€¯à€¹à€°à¥}
+_textDescription_ [l=ne] {à€µà€¿à€µà€°à€£}
+_labelDescription_ [l=ne] {à€µà€¿à€µà€°à€£}
+_textPublisher_ [l=ne] {à€ªà¥à€°à€à€Ÿà€¶à€}
+_labelPublisher_ [l=ne] {à€ªà¥à€°à€à€Ÿà€¶à€}
+_textContributor_ [l=ne] {à€
+à€šà¥à€Šà€Ÿà€€à€Ÿ}
+_labelContributor_ [l=ne] {à€žà€¹à€­à€Ÿà€à¥à€¹à€°à¥}
+_textDate_ [l=ne] {à€®à€¿à€€à€¿}
+_labelDate_ [l=ne] {à€®à€¿à€€à€¿}
+_textType_ [l=ne] {à€²à¥à€à¥à€šà¥à€¹à¥à€ž}
+_labelType_ [l=ne] {à€à€¿à€žà€¿à€®}
+_textFormat_ [l=ne] {à€žà€à€°à€à€šà€Ÿ}
+_labelFormat_ [l=ne] {à€žà€à€°à€à€šà€Ÿ}
+_textIdentifier_ [l=ne] {à€ªà€°à€¿à€à€¯à€Šà€Ÿà€€à€Ÿ}
+_labelIdentifier_ [l=ne] {à€ªà€°à€¿à€à€Ÿà€¯à€}
+_textSource_ [l=ne] {à€«à€Ÿà€à€²à€à¥ à€šà€Ÿà€®}  # Not true DC, kept for legacy reasons
+_labelSource_ [l=ne] {à€«à€Ÿà€à€²à€à€Ÿ à€šà€Ÿà€®à€¹à€°à¥}  # Not true DC, kept for legacy reasons
+_textLanguage_ [l=ne] {à€­à€Ÿà€·à€Ÿ}
+_labelLanguage_ [l=ne] {à€­à€Ÿà€·à€Ÿà€¹à€°à¥}
+_textRelation_ [l=ne] {à€žà€®à¥à€¬à€šà¥à€§}
+_labelRelation_ [l=ne] {à€žà€®à¥à€¬à€šà¥à€§à€¹à€°à¥}
+_textCoverage_ [l=ne] {à€à¥à€·à¥à€€à¥à€°}
+_labelCoverage_ [l=ne] {à€à¥à€·à¥à€€à¥à€°}
+_textRights_ [l=ne] {à€ à¥à€}
+_labelRights_ [l=ne] {à€
+à€§à€¿à€à€Ÿà€°}
+
+# DLS metadata set
+_textOrganization_ [l=ne] {à€žà€à€žà¥à€¥à€Ÿ}
+_labelOrganization_ [l=ne] {à€žà€à€žà¥à€¥à€Ÿ}
+_textKeyword_ [l=ne] {à€®à¥à€² à€¶à€µà¥à€Š}
+_labelKeyword_ [l=ne] {à€®à¥à€² à€¶à€µà¥à€Šà€¹à€°à¥}
+_textHowto_ [l=ne] {à€à€žà€°à¥}
+_labelHowto_ [l=ne] {à€à€žà€°à¥ ?}
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=ne] {à€à€à€Ÿà€š à€à¥à€à¥à€à€Ÿ}
+_labelPhrase_ [l=ne] {à€à€à€Ÿà€š à€à¥à€à¥à€à€Ÿ}
+_textCollage_ [l=ne] {à€à€²à¥à€}
+_labelCollage_ [l=ne] {à€à€²à¥à€}
+_textBrowse_ [l=ne] {à€Šà¥à€à€Ÿà€à€šà¥à€žà¥}
+_labelBrowse_ [l=ne] {à€à¥à€}
+_textTo_ [l=ne] {à€²à€Ÿà€}
+_labelTo_ [l=ne] {à€²à€Ÿà€}
+_textFrom_ [l=ne] {à€¬à€Ÿà€}
+_labelFrom_ [l=ne] {à€¬à€Ÿà€}
+# -- Missing translation: _textAcronym_
+# -- Missing translation: _labelAcronym_
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+# -- Missing translation: _textdescrdefault_
+
+# -- Missing translation: _textdescrSearch_
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrIdentifier_
+_textdescrSource_ [l=ne] {à€«à€Ÿà€à€²à€à¥ à€®à¥à€² à€šà€Ÿà€® à€
+à€šà¥à€žà€Ÿà€° à€à¥à€à¥ à€à€°à¥à€šà¥à€¹à¥à€žà¥}  # Not true DC, kept for legacy reasons
+# -- Missing translation: _textdescrTo_
+_textdescrFrom_ [l=ne] {à€à¥à€·à¥à€€à¥à€°à€à€Ÿ à€à€§à€Ÿà€°à€®à€Ÿ à€à¥à€à¥à€šà¥à€¹à¥à€žà¥}
+_textdescrCollage_ [l=ne] {à€à€²à¥à€à€à¥ à€à€¿à€€à¥à€°à€¬à€Ÿà€ à€Šà¥à€à€Ÿà€à€šà¥à€žà¥}
+# -- Missing translation: _textdescrAcronym_ 
+_textdescrPhrase_ [l=ne] {à€à€à€Ÿà€š à€à¥à€à¥à€à€Ÿ à€Šà¥à€à€Ÿà€à€šà¥à€¹à¥à€ž}
+_textdescrHowto_ [l=ne] {à€µà€°à¥à€à¥à€à€°à€£ à€à€°à¥à€šà¥ à€€à€°à€¿à€à€Ÿ à€¹à¥à€°à¥à€šà¥à€¹à¥à€ž}
+_textdescrBrowse_ [l=ne] {à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€¹à¥à€°à¥à€šà¥à€¹à¥à€žà¥}
+_texticontext_ [l=ne] {à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€¹à¥à€°à¥à€šà¥à€¹à¥à€ž}
+_texticonclosedbook_ [l=ne] {à€Šà€žà¥à€€à€Ÿà€µà¥à€à€²à€Ÿà€ à€à¥à€²à¥à€° à€¹à¥à€°à¥à€šà¥à€¹à¥à€ž}
+_texticonnext_ [l=ne] {à€
+à€à€¿à€²à¥à€²à¥ à€à€£à¥à€¡à€®à€Ÿ à€à€Ÿà€šà€à€Ÿ à€²à€Ÿà€à€¿}
+_texticonprev_ [l=ne] {à€
+à€à€¿à€à¥ à€à€£à¥à€¡à€€à€°à¥à€«}
+
+_texticonworld_ [l=ne] {à€µà¥à€­ à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€¹à¥à€°à¥à€šà¥à€¹à¥à€žà¥}
+
+_texticonmidi_ [l=ne] {MIDI à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€¹à¥à€°à¥à€šà¥à€¹à¥à€ž}
+_texticonmsword_ [l=ne] {à€®à€Ÿà€à€à¥à€°à¥à€žà€«à¥à€ à€µà€°à¥à€¡ à€¡à€à¥à€®à¥à€šà¥à€ à€¹à¥à€°à¥à€šà¥à€¹à¥à€žà¥}
+_texticonmp3_ [l=ne] {MP3 à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€¹à¥à€°à¥à€šà¥à€¹à¥à€žà¥}
+_texticonpdf_ [l=ne] {PDF  à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€¹à¥à€°à¥à€šà¥à€¹à¥à€žà¥}
+# -- Missing translation: _texticonps_ 
+_texticonppt_ [l=ne] {PowerPoint  à€ªà¥à€°à€žà¥à€€à¥à€€à€¿ à€¹à¥à€°à¥à€šà¥à€¹à¥à€ž}
+_texticonrtf_ [l=ne] {RTF à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€¹à¥à€°à¥à€šà¥à€¹à¥à€žà¥}
+_texticonxls_ [l=ne] {à€®à€Ÿà€à€à¥à€°à¥à€žà€«à¥à€ à€à€à¥à€žà¥à€² à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€¹à¥à€°à¥à€šà¥à€¹à¥à€ž}
+
+_page_ [l=ne] {à€ªà¥à€·à¥à€  }
+_pages_ [l=ne] {à€ªà¥à€·à¥à€ }
+_of_ [l=ne] { à€à¥ }
+_vol_ [l=ne] {à€à€£à¥à€¡}
+_num_ [l=ne] {à€žà€à€à¥à€¯à€Ÿ}
+
+_textmonth00_ [l=ne] {}
+_textmonth01_ [l=ne] {à€à€šà€µà€°à¥}
+_textmonth02_ [l=ne] {à€«à¥à€¬à¥à€°à¥à€µà€°à¥}
+_textmonth03_ [l=ne] {à€®à€Ÿà€°à¥à€}
+_textmonth04_ [l=ne] {à€
+à€ªà¥à€°à€¿à€²}
+_textmonth05_ [l=ne] {à€®à¥}
+_textmonth06_ [l=ne] {à€à¥à€š}
+_textmonth07_ [l=ne] {à€à¥à€²à€Ÿà€}
+_textmonth08_ [l=ne] {à€
+à€à€žà¥à€€}
+_textmonth09_ [l=ne] {à€žà¥à€ªà¥à€à¥à€®à¥à€µà€°}
+_textmonth10_ [l=ne] {à€
+à€à¥à€à¥à€µà€°}
+_textmonth11_ [l=ne] {à€šà¥à€­à¥à€®à¥à€µà€°}
+_textmonth12_ [l=ne] {à€¡à€¿à€žà¥à€®à¥à€µà€°}
+
+_textdocument_ [l=ne] {à€Šà€žà¥à€€à€Ÿà€µà¥à€}
+_textsection_ [l=ne] {à€­à€Ÿà€}
+_textparagraph_ [l=ne] {à€
+à€šà¥à€à¥à€à¥à€Š}
+
+_magazines_ [l=ne] {à€ªà€€à¥à€°à€¿à€à€Ÿà€¹à€°à¥}
+
+# -- Missing translation: _nzdlpagefooter_
+
+_linktextHOME_ [l=ne] {à€à€°}
+_linktextHELP_ [l=ne] {à€žà€¹à€¯à¥à€}
+_linktextPREFERENCES_ [l=ne] {à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿà€¹à€°à¥}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=ne] {à€à¥à€°à¥à€šà€žà¥à€à€š à€¡à€¿à€à€¿à€à€² à€ªà¥à€žà¥à€€à€à€Ÿà€²à€¯}
+
+_textnocollections_ [l=ne] {à€à¥à€šà¥ à€ªà€šà€¿ à€à€¿à€žà€¿à€®à€à¥ à€à€§à€¿à€à€Ÿà€°à€¿à€ à€žà€®à¥à€¹ à€à€ªà€²à€¬à¥à€§ à€à¥à€šà¥€}
+
+_textadmin_ [l=ne] {à€µà¥à€¯à€µà€žà¥à€¥à€Ÿà€ªà€à¥à€¯ à€ªà¥à€·à¥à€ }
+# -- Missing translation: _textabgs_
+_textgsdocs_ [l=ne] {à€à¥à€°à¥à€šà€žà¥à€à€š à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€°à€Ÿà€à€šà€§à€°à€š}
+
+# -- Missing translation: _textdescradmin_ 
+
+# -- Missing translation: _textdescrgogreenstone_ 
+
+# -- Missing translation: _textdescrgodocs_
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+# -- Missing translation: _textgli_ 
+# -- Missing translation: _textdescrgli_ 
+
+package collector
+
+_textcollector_ [l=ne] {à€žà€à€à¥à€°à€¹à€à€°à¥à€€à€Ÿ}
+# -- Missing translation: _textdescrcollector_ 
+
+package depositor
+
+# -- Missing translation: _textdepositor_ 
+_textdescrdepositor_  [l=ne] {à€­à€à€à€Ÿ à€žà€®à¥à€¹à€®à€Ÿ à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€à¥à€¡à¥à€š à€žà€¹à€¯à¥à€ à€à€°à¥à€}
+
+package gti
+
+# -- Missing translation: _textgti_ 
+# -- Missing translation: _textdescrtranslator_ 
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=ne] {à€¯à€ž à€žà€à€à¥à€°à€¹à€à€Ÿ à€µà€Ÿà€°à¥à€®à€Ÿ}
+
+_textsubcols1_ [l=ne] {<p>à€žà€®à¥à€ªà¥à€°à¥à€£ à€žà€à€à¥à€°à€¹_1_ à€žà€¹à€Ÿà€¯à€ à€žà€à€à¥à€°à€¹ à€à¥ à€à€ªà€²à€µà¥à€§ à€à€šà¥ à¥€
+ <blockquote>}
+
+_textsubcols2_ [l=ne] {</blockquote>
+à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿà€à€Ÿ à€žà€Ÿà€¥ à€€à€ªà€Ÿà€à€²à¥ à€€à€€à¥à€à€Ÿà€² à€ªà¥à€°à€¯à¥à€ à€à€°à€¿à€°à€¹à¥à€à¥ à€žà€Ÿà€®à€à¥à€°à¥ à€ªà€°à¥à€à¥à€·à€£ à€à€°à¥à€š à€žà€à¥à€šà¥à€¹à¥à€šà¥à€}
+
+_titleabout_ [l=ne] {à€µà€Ÿà€°à¥}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=ne] {à€à¥ à€¯à€ž à€­à€Ÿà€à€²à€Ÿà€ à€¬à€šà¥à€Š à€à€°à¥à€šà¥à€¹à¥à€žà¥}
+_texticonclosedbookshelf_ [l=ne] {à€ªà¥à€žà¥à€€à€à€Ÿà€²à€¯à€à¥ à€¯à¥ à€à€£à¥à€¡ à€à¥à€²à¥à€° à€°à€Ÿà€à€¿à€à€à€Ÿ à€žà€Ÿà€®à€à¥à€°à¥ à€¹à¥à€°à¥à€šà¥à€¹à¥à€žà¥}
+_texticonopenbook_ [l=ne] {à€¯à¥ à€à€¿à€€à€Ÿà€µ à€¬à€šà¥à€Š à€à€°à¥à€šà¥à€¹à¥à€žà¥}
+_texticonclosedfolder_ [l=ne] {à€¯à¥ à€«à¥à€²à¥à€¡à€°à€²à€Ÿà€ à€à¥à€²à¥à€° à€¹à¥à€°à¥à€šà¥à€¹à¥à€žà¥}
+_texticonclosedfolder2_ [l=ne] {à€žà€¹à€Ÿà€¯à€ à€à€£à¥à€¡ à€à¥à€²à¥à€šà¥à€¹à¥à€žà¥ }
+_texticonopenfolder_ [l=ne] {à€¯à€ž à€«à¥à€²à¥à€¡à€°à€²à€Ÿà€ à€¬à€šà¥à€Š à€à€°à¥à€šà¥à€¹à¥à€žà¥}
+_texticonopenfolder2_ [l=ne] {à€žà€¹à€Ÿà€¯à€ à€à€£à¥à€¡ à€¬à€šà¥à€Š à€à€°à¥à€šà¥à€¹à¥à€žà¥ }
+_texticonsmalltext_ [l=ne] {à€¯à€ž à€­à€Ÿà€à€à¥ à€®à¥à€² à€¶à€µà¥à€Šà€¹à€°à¥à€²à€Ÿà€ à€¹à¥à€°à¥à€šà¥à€¹à¥à€ž}
+_texticonsmalltext2_ [l=ne] {à€®à¥à€à¥à€¯ à€¶à€µà¥à€Šà€¹à€°à¥à€²à€Ÿà€ à€¹à¥à€°à¥à€šà¥à€¹à¥à€žà¥ }
+_texticonpointer_ [l=ne] {à€à€Ÿà€²à¥ à€à€£à¥à€¡}
+_texticondetach_ [l=ne] {à€¯à¥ à€ªà¥à€·à¥à€ à€²à€Ÿà€ à€šà€¯à€Ÿà€ Window à€®à€Ÿ à€à¥à€²à¥à€šà¥à€¹à¥à€žà¥}
+_texticonhighlight_ [l=ne] {à€à¥à€ à€à€°à€¿à€à€à€Ÿ à€ªà€Šà€¹à€°à¥à€²à€Ÿà€ à€¹à€Ÿà€à€²à€Ÿà€à€ à€à€°à¥à€šà¥à€¹à¥à€žà¥}
+_texticonnohighlight_ [l=ne] {à€à¥à€à€¿à€à€à€Ÿ à€žà€Ÿà€®à€à¥à€°à¥à€¹à€°à¥ à€¹à€Ÿà€à€²à€Ÿà€à€ à€šà€à€°à¥à€šà¥à€¹à¥à€žà¥}
+# -- Missing translation: _texticoncontracttoc_
+_texticonexpandtoc_ [l=ne] {à€µà€¿à€·à€¯ à€žà¥à€à¥ à€µà€¿à€žà¥à€€à€Ÿà€°}
+_texticonexpandtext_ [l=ne] {à€žà€®à¥à€ªà¥à€°à¥à€£ à€
+à€à¥à€·à€° à€Šà¥à€à€Ÿà€à€šà¥à€¹à¥à€žà¥}
+_texticoncontracttext_ [l=ne] {à€à€Ÿà€šà€¿à€à€à€Ÿ à€žà€Ÿà€®à€à¥à€°à¥ à€®à€Ÿà€€à¥à€° à€ªà¥à€°à€žà¥à€€à¥à€€ à€à€°à¥à€šà¥à€¹à¥à€ž}
+_texticonwarning_ [l=ne] {<b> à€žà€€à€°à¥à€à€€à€Ÿ</b>}
+# -- Missing translation: _texticoncont_ 
+
+_textltwarning_ [l=ne] {<div class="buttons">_imagecont_</div>
+ _iconwarning_
+ }
+
+_textgoto_ [l=ne] {à€ªà¥à€·à¥à€ à€®à€Ÿ à€à€Ÿà€šà¥à€¹à¥à€ž}
+# -- Missing translation: _textintro_
+
+_textCONTINUE_ [l=ne] {à€šà€¿à€°à€šà¥à€€à€°à€€à€Ÿ à€Šà€¿à€šà¥à€žà¥}
+
+_textEXPANDTEXT_ [l=ne] {à€
+à€à¥à€·à€° à€¬à€¢à€Ÿà€à€šà¥à€ž}
+
+_textCONTRACTCONTENTS_ [l=ne] {à€žà€®à¥à€à¥à€€à€Ÿà€à€Ÿ à€¬à¥à€à€Šà€Ÿà€¹à€°à¥}
+
+_textDETACH_ [l=ne] {à€à¥à€à¥à€¯à€Ÿà€à€šà¥à€ž}
+
+# -- Missing translation: _textEXPANDCONTENTS_ 
+
+_textCONTRACT_ [l=ne] {à€žà€®à¥à€à¥à€€à€Ÿà€à€Ÿ à€¬à¥à€à€Šà€Ÿà€¹à€°à¥}
+
+_textHIGHLIGHT_ [l=ne] {à€à€à€°à¥à€·à€£}
+
+# -- Missing translation: _textNOHIGHLIGHT_ 
+
+_textPRINT_ [l=ne] {à€ªà¥à€°à€¿à€šà¥à€}
+
+_textnextsearchresult_ [l=ne] {à€
+à€°à¥à€à¥ à€à¥à€ à€ªà€°à€¿à€£à€Ÿà€®}
+_textprevsearchresult_[l=ne] {à€ªà€¹à€¿à€²à¥à€à¥ à€à¥à€ à€ªà€°à€¿à€£à€Ÿà€®}
+
+# macros for printing page
+# -- Missing translation: _textreturnoriginal_ 
+_textprintpage_ [l=ne] {à€¯à¥ à€ªà¥à€·à¥à€  à€ªà¥à€°à€¿à€šà¥à€ à€à€°à¥à€šà¥à€¹à¥à€žà¥}
+_textshowcontents_ [l=ne] {à€µà€¿à€·à€¯ à€žà¥à€à¥ à€Šà¥à€à€Ÿà€à€šà¥à€ž}
+_texthidecontents_ [l=ne] {à€µà€¿à€·à€¯ à€žà¥à€à¥ à€²à¥à€à€Ÿà€à€šà¥à€¹à¥à€žà¥}
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=ne] {_If_(_thislast_, à€ªà€°à€¿à€£à€Ÿà€®_thisfirst_ - _thislast_ à€¯à€ž à€ªà¥à€°à€¶à¥à€šà€²à€Ÿà€: _cgiargq_, à€¯à¥ à€ªà¥à€°à€¶à¥à€š à€à€žà¥à€žà€à€ à€®à¥à€² à€à€Ÿà€à€Šà¥à€š: _cgiargq_)}
+_textnoquerytitle_ [l=ne] {à€à¥à€à€à¥ à€ªà¥à€·à¥à€ }
+
+# -- Missing translation: _textsome_ 
+# -- Missing translation: _textall_ 
+# -- Missing translation: _textboolean_ 
+_textranked_ [l=ne] {à€žà¥à€€à€° à€šà€¿à€°à¥à€§à€Ÿà€°à€£}
+_textnatural_ [l=ne] {à€ªà¥à€°à€Ÿà€à¥à€€à€¿à€}
+# -- Missing translation: _textsortbyrank_ 
+_texticonsearchhistorybar_ [l=ne] {à€à€€à€¿à€¹à€Ÿà€ž à€à¥à€à¥à€šà¥à€¹à¥à€žà¥}
+
+_textifeellucky_ [l=ne] {à€® à€à€«à¥à€²à€Ÿà€ à€­à€Ÿà€à¥à€¯à€®à€Ÿà€šà¥ à€ à€Ÿà€šà¥à€Šà¥à€à¥}
+
+#alt text for query buttons
+_textusequery_ [l=ne] {à€¯à¥ à€ªà¥à€°à€¶à¥à€š à€ªà¥à€°à€¯à¥à€ à€à€°à¥à€šà¥à€¹à¥à€žà¥}
+_textfreqmsg1_ [l=ne] {à€¶à€µà¥à€Š à€à€£à€šà€Ÿ }
+_textpostprocess_ [l=ne] {_If_(_quotedquery_,<br><i>
+à€ªà¥à€°à€à¥à€°à€¿à€¯à€Ÿà€à¥ à€à¥à€à¥ à€à€°à¥à€š_quotedquery_ </i>)}
+# -- Missing translation: _textinvalidquery_ 
+# -- Missing translation: _textstopwordsmsg_ 
+# -- Missing translation: _textlucenetoomanyclauses_ 
+
+_textmorethan_ [l=ne] {à€­à€šà¥à€Šà€Ÿ à€¬à€¢à¥ }
+_textapprox_ [l=ne] {à€µà€Ÿà€°à¥ }
+_textnodocs_ [l=ne] {à€à¥à€šà¥ à€žà€Ÿà€®à€à¥à€°à¥ à€ªà€šà€¿ à€¯à¥ à€ªà¥à€°à€¶à¥à€šà€žà€à€ à€®à¥à€² à€à€Ÿà€à€Šà¥à€š}
+_text1doc_ [l=ne] {à€¯à¥ à€ªà¥à€°à€¶à¥à€š à€à€à€à€Ÿ à€Šà€žà¥à€€à€Ÿà€µà¥à€à€žà€à€ à€­à€¿à€¡à€Ÿà€à€¯à¥}
+_textlotsdocs_ [l=ne] {à€¯à¥ à€ªà¥à€°à€¶à¥à€š à€žà€®à¥à€¬à€šà¥à€§à€¿à€€ à€à€Ÿà€à€à€Ÿà€€à€žà€à€ à€­à€¿à€¡à€Ÿà€à€¯à¥}
+_textmatches_ [l=ne] {à€­à€¿à€¡à€Ÿà€š}
+_textbeginsearch_ [l=ne] {à€à¥à€à¥à€š à€¶à¥à€°à¥ à€à€°à¥à€šà¥à€¹à¥à€ž}
+# -- Missing translation: _textrunquery_ 
+# -- Missing translation: _textclearform_ 
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=ne] {à€¶à€µà¥à€Šà€¹à€°à¥}
+_textinfield_ [l=ne] {âŠà€à¥à€·à¥à€€à¥à€°à€®à€Ÿ}
+# -- Missing translation: _textfoldstem_ 
+
+_textadvquery_ [l=ne] {à€µà€Ÿ à€ªà¥à€°à€¶à¥à€š à€ªà¥à€°à€¯à¥à€ à€à€°à¥à€šà¥à€¹à¥à€žà¥}
+_textallfields_ [l=ne] {à€žà€®à¥à€ªà¥à€°à¥à€£ à€à¥à€·à¥à€€à¥à€°à€¹à€°à¥}
+_texttextonly_ [l=ne] {à€žà€Ÿà€®à€à¥à€°à¥ à€®à€Ÿà€€à¥à€°}
+_textand_ [l=ne] {à€°}
+_textor_ [l=ne] {à€
+à€¥à€µà€Ÿ}
+# -- Missing translation: _textandnot_ 
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+# -- Missing translation: _textsimplesearch_ 
+
+# -- Missing translation: _textadvancedsearch_
+
+# -- Missing translation: _textadvancedmgppsearch_ 
+
+# -- Missing translation: _textadvancedlucenesearch_
+
+# -- Missing translation: _textformsimplesearch_ 
+
+# -- Missing translation: _textformadvancedsearchmgpp_ 
+
+# -- Missing translation: _textformadvancedsearchlucene_ 
+
+# -- Missing translation: _textnojsformwarning_ 
+# -- Missing translation: _textdatesearch_ 
+_textstartdate_ [l=ne] {à€®à€¿à€€à€¿ à€¶à¥à€°à¥ à€à€°à¥à€šà¥à€¹à¥à€ž}
+_textenddate_ [l=ne] {à€žà€®à€Ÿà€ªà¥à€€à€¿ à€®à€¿à€€à€¿}
+# -- Missing translation: _textbc_ 
+# -- Missing translation: _textad_ 
+# -- Missing translation: _textexplaineras_ 
+
+_textstemon_ [l=ne] {à€¶à€µà¥à€Šà€Ÿà€šà¥à€€à€¹à€°à¥à€²à€Ÿà€ à€šà€Šà¥à€à¥à€à¥ à€à€°à¥à€šà¥à€¹à¥à€žà¥}
+
+_textsearchhistory_ [l=ne] {à€à¥à€à€à¥ à€à€€à€¿à€¹à€Ÿà€ž}
+
+#text macros for search history
+_textnohistory_ [l=ne] {à€à¥à€à€à¥ à€à€€à€¿à€¹à€Ÿà€ž à€šà€Šà¥à€à€Ÿà€à€šà¥à€¹à¥à€žà¥}
+_texthresult_ [l=ne] {à€ªà€°à€¿à€£à€Ÿà€®}
+_texthresults_ [l=ne] {à€ªà€°à€¿à€£à€Ÿà€®}
+_texthallwords_ [l=ne] {à€žà€®à¥à€ªà¥à€°à¥à€£ à€¶à€µà¥à€Š}
+_texthsomewords_ [l=ne] {à€à¥à€¹à¥ à€¶à€µà¥à€Šà€¹à€°à¥}
+# -- Missing translation: _texthboolean_ 
+_texthranked_ [l=ne] {à€žà¥à€€à€°à¥à€à€°à€£}
+# -- Missing translation: _texthcaseon_
+# -- Missing translation: _texthcaseoff_ 
+# -- Missing translation: _texthstemon_ 
+# -- Missing translation: _texthstemoff_ 
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textprefschanged_ 
+_textsetprefs_ [l=ne] {à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿ à€€à¥à€à¥à€šà¥à€¹à¥à€žà¥}
+_textsearchprefs_ [l=ne] {à€à¥à€à¥à€šà¥ à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿà€¹à€°à¥}
+_textcollectionprefs_ [l=ne] {à€žà€à€à¥à€°à€¹ à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿ}
+_textpresentationprefs_ [l=ne] {à€ªà¥à€°à€žà¥à€€à¥à€€à¥à€à€°à€£à€à€Ÿ à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿà€¹à€°à¥}
+_textpreferences_ [l=ne] {à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿ}
+# -- Missing translation: _textcasediffs_ 
+# -- Missing translation: _textignorecase_ 
+# -- Missing translation: _textmatchcase_ 
+_textwordends_ [l=ne] {à€¶à€µà¥à€Šà€Ÿà€šà¥à€€}
+_textstem_ [l=ne] {à€¶à€µà¥à€Šà€¹à€°à¥à€²à€Ÿà€ à€µà€Ÿà€žà¥à€€à€Ÿ à€šà€à€°à¥à€šà¥à€¹à¥à€žà¥}
+_textnostem_ [l=ne] {à€žà€®à¥à€ªà¥à€°à¥à€£ à€¶à€µà¥à€Š à€­à€¿à€¡à€Ÿà€à€š à€à€°à¥à€°à¥ à€ à¥€}
+# -- Missing translation: _textaccentdiffs_ 
+# -- Missing translation: _textignoreaccents_ 
+# -- Missing translation: _textmatchaccents_ 
+
+_textprefop_ [l=ne] {à€à¥à€² _maxdocoption_à€ªà€°à€¿à€£à€Ÿà€®à€®à€§à¥à€¯à¥à€¬à€Ÿà€ à€ªà¥à€°à€€à€¿ à€ªà¥à€·à¥à€  _hitsperpageoption_ à€ªà€°à€¿à€£à€Ÿà€® à€Šà¥à€à€Ÿà€à€šà¥à€ž}
+_textextlink_ [l=ne] {à€¬à€Ÿà€¹à€¿à€°à€¿à€¯à€Ÿ à€µà¥à€­ à€ªà¥à€·à¥à€ à€¹à€°à¥ à€ªà¥à€°à€Ÿà€ªà¥à€€ à€à€°à¥à€šà¥à€¹à¥à€ž:}
+_textintlink_ [l=ne] {à€®à¥à€² à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€¯à€¹à€Ÿà€à€¬à€Ÿà€ à€žà€Ÿà€­à€Ÿà€° à€à€°à€¿à€à€à¥ à€: }
+_textlanguage_ [l=ne] {à€à€šà¥à€à€°à€«à¥à€žà€à¥ à€­à€Ÿà€·à€Ÿ:}
+_textencoding_ [l=ne] {à€à€šà€à¥à€¡à€¿à€à¥à€:}
+_textformat_ [l=ne] {à€à€£à¥à€à€°à€«à¥à€žà€à¥ à€žà€à€°à€à€šà€Ÿ:}
+_textall_ [l=ne] {à€žà€¬à¥}
+_textquerymode_ [l=ne] {à€à¥à€à¥à€à¥ à€ªà¥à€°à€£à€Ÿà€²à¥:}
+_textsimplemode_ [l=ne] {à€žà€Ÿà€§à€Ÿà€°à€£ à€à¥à€}
+_textadvancedmode_ [l=ne] {à€µà¥à€à¥à€à€Ÿà€šà€¿à€ à€€à€°à€¿à€à€Ÿà€à¥ à€à¥à€à€²à¥ à€¬à¥à€²à€¿à€¯à€š à€à¥à€ à€à€°à¥à€š à€žà€à¥à€}
+# -- Missing translation: _textlinkinterm_ 
+_textlinkdirect_ [l=ne] {à€žà€¿à€§à€Ÿ à€à€€à€Ÿ à€à€Ÿà€šà¥à€¹à¥à€žà¥}
+_textdigitlib_ [l=ne] {à€¡à€¿à€à€¿à€à€² à€ªà¥à€žà¥à€€à€à€Ÿà€²à€¯}
+_textweb_ [l=ne] {à€µà¥à€¬}
+_textgraphical_ [l=ne] {à€à€¿à€€à¥à€° à€žà€¹à€¿à€€}
+_texttextual_ [l=ne] {à€®à¥à€² à€ªà€Ÿà€ }
+_textcollectionoption_ [l=ne] {<p>
+à€à€ªà€žà€à€à¥à€°à€¹à€¹à€°à¥à€²à€Ÿà€ à€žà€®à€Ÿà€µà¥à€¶ à€à€°à¥à€šà¥à€¹à¥à€ž
+ <br>}
+
+_textsearchtype_ [l=ne] {à€ªà¥à€°à€¶à¥à€š à€¶à¥à€²à¥:}
+# -- Missing translation: _textformsearchtype_ 
+
+_textregularbox_ [l=ne] {à€à€ à€¹à€°à€«}
+_textlargebox_ [l=ne] {à€ à¥à€²à¥}
+
+_textrelateddocdisplay_ [l=ne] {à€žà€®à¥à€¬à€šà¥à€§à€¿à€€ à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€Šà¥à€à€Ÿà€à€šà¥à€žà¥}
+_textsearchhistory_ [l=ne] {à€à¥à€à€à¥ à€à€€à€¿à€¹à€Ÿà€ž:}
+_textnohistory_ [l=ne] {à€à¥à€à€à¥ à€à€€à€¿à€¹à€Ÿà€ž à€šà€Šà¥à€à€Ÿà€à€šà¥à€¹à¥à€žà¥}
+_texthistorydisplay_ [l=ne] {à€à¥à€à€à¥ _historynumrecords_ à€à€€à€¿à€¹à€Ÿà€ž à€Šà¥à€à€Ÿà€à€šà¥à€¹à¥à€žà¥}
+_textnohistorydisplay_ [l=ne] {à€à¥à€à€à¥ à€à€€à€¿à€¹à€Ÿà€ž à€šà€Šà¥à€à€Ÿà€à€šà¥à€ž}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textalsoshowing_ [l=ne] {à€ªà€šà€¿ à€Šà¥à€à€Ÿà€à€Šà¥à€}
+_textdocsperpage_ [l=ne] {à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€ªà¥à€°à€€à€¿ à€ªà¥à€·à¥à€ }
+
+_textfilterby_ [l=ne] {à€­à€à€à€Ÿ à€Šà€žà¥à€€à€Ÿà€µà¥à€à€¹à€°à¥ à€²à€¿à€šà¥à€¹à¥à€žà¥}
+_textall_ [l=ne] {à€žà€®à¥à€ªà¥à€°à¥à€£}
+_textany_ [l=ne] {à€à¥à€šà¥}
+_textwords_ [l=ne] {à€¶à€µà¥à€Šà€à€Ÿ}
+_textleaveblank_ [l=ne] {à€à€Ÿà€¹à¥ à€à€€à€¿ à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€ªà¥à€°à€Ÿà€ªà¥à€€ à€à€°à¥à€š à€¯à¥ à€à¥à€ à€Ÿ à€à€Ÿà€²à¥ à€°à€Ÿà€à¥à€šà¥à€¹à¥à€²à€Ÿ}	    
+
+_docs_ [l=ne] {à€Šà€žà¥à€€à€Ÿà€µà¥à€}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=ne] {à€žà€¹à€¯à¥à€}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+# -- Missing translation: _textdefaulthelp_
+
+# -- Missing translation: _textSearchhelp_ 
+# -- Missing translation: _textTohelp_ 
+# -- Missing translation: _textFromhelp_ 
+# -- Missing translation: _textBrowsehelp_ 
+# -- Missing translation: _textAcronymhelp_ 
+# -- Missing translation: _textPhrasehelp_ 
+
+_texthelptopicstitle_ [l=ne] {à€¶à¥à€°à¥à€·à€}
+
+_textreadingdocs_ [l=ne] {à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€à€žà€°à¥ à€ªà€¢à¥à€šà¥ }
+
+_texthelpreadingdocs_ [l=ne] {
+<p> à€€à€ªà€Ÿà€ à€ªà¥à€·à¥à€ à€à€Ÿ à€¬à€Ÿà€¯à€Ÿà€à€€à€°à¥à€« à€¶à¥à€°à¥à€·à€ à€²à¥à€à€à€à¥ à€šà€Ÿà€® à€­à¥à€à¥à€šà¥ à€¹à¥à€šà¥à€ à¥€ à€€à¥à€¯à€žà€ªà€à€¿ à€
+à€à€Ÿà€¡à€¿ à€à€Ÿà€šà¥ à€ªà¥à€·à¥à€  à€
+à€à€Ÿà€¡à€¿ à€° à€ªà€à€Ÿà€¡à€¿ à€²à¥à€à€Ÿà€šà¥ à€€à¥à€° à€­à¥à€à¥à€šà¥ à€¹à¥à€šà¥à€ à¥€
+ 
+ 
+<p> à€€à€² à€à€Ÿà€²à¥ à€Šà€žà¥à€€à€Ÿà€µà¥à€à€à¥ à€®à¥à€² à€­à¥à€à¥à€š à€žà€à€¿à€šà¥à€ à¥€ à€à€žà€à¥ à€
+à€šà¥à€€à€®à€Ÿ à€
+à€à€Ÿà€¡à€¿ à€° à€ªà€à€Ÿà€¡à€¿ à€²à¥à€à€Ÿà€šà¥ à€€à¥à€° à€­à¥à€à€¿à€šà¥à€ à¥€ 
+ 
+<p>à€¶à¥à€°à¥à€·à€ à€° à€²à¥à€à€à€à¥ à€šà€Ÿà€®à€­à€šà¥à€Šà€Ÿ à€€à€² à€€à¥à€šà€µà€à€Ÿ à€¬à€à€š à€­à¥à€à€¿à€šà¥à€ à¥€
+ à€à€Ÿà€²à¥ à€Šà€žà¥à€€à€Ÿà€µà¥à€à€à¥ à€®à¥à€² à€ªà€Ÿà€  à€à¥âà€²à¥à€š <i>à€à¥à€²à¥à€šà€à€Ÿ à€²à€Ÿà€à€¿</i>, 
+ à€à¥à€²à€¿à€ à€à¥à€²à€¿à€ à€à€°à¥à€šà¥à€¹à¥à€žà¥ à¥€ à€šà€¯à€Ÿà€ Window à€à¥à€²à¥à€š
+ <i>à€à¥à€à¥à€à¥</i>,
+ à€®à€Ÿ à€à¥à€²à€¿à€ à€à¥à€²à€¿à€ à€à€°à¥à€šà¥à€¹à¥à€žà¥ à¥€ à€Šà¥à€à€µà€à€Ÿ à€Šà€žà¥à€€à€Ÿà€µà¥à€à€¬à¥à€ à€€à¥à€²à€šà€Ÿ à€à€°à¥à€š à€ªà€°à¥à€®à€Ÿ à€šà€¯à€Ÿà€  Window à€à€ªà€¯à¥à€à¥ à€¹à¥à€šà¥à€ ._ à€
+à€šà¥à€€à€®à€Ÿ à€à¥à€à¥ à€à€°à¥à€à¥ à€¶à€µà¥à€Š à€Šà¥à€à€Ÿ à€ªà€°à¥à€Šà€ à¥€
+à€šà€Šà¥à€à€¿à€šà¥ à€¬à€šà€Ÿà€à€š à€ªà€°à¥à€®à€Ÿ <i>à€
+à€Šà¥à€¶à¥à€¯ /i>, 
+
+ à€¬à€à€šà€²à€Ÿà€ à€à¥à€²à€¿à€ à€à¥à€²à€¿à€ à€à€°à¥à€šà¥à€¹à¥à€žà¥ à¥€ 
+}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=ne] {à€à€¿à€€à€Ÿà€¬à€à¥ à€¯à¥ à€à€£à¥à€¡ à€à¥à€²à¥à€šà¥à€¹à¥à€žà¥ }
+_texthelpopenbook_ [l=ne] {à€¯à¥ à€à€¿à€€à€Ÿà€¬ à€à¥à€²à¥à€šà¥à€¹à¥à€žà¥ à€¬à€šà¥à€Š à€à€°à¥à€šà¥à€¹à¥à€žà¥}
+_texthelpviewtextsection_ [l=ne] {à€žà€Ÿà€®à€à¥à€°à¥à€à¥ à€¯à¥ à€­à€Ÿà€ à€Šà¥à€à€Ÿà€}
+_texthelpexpandtext_ [l=ne] {à€žà€®à¥à€ªà¥à€°à¥à€£ à€žà€Ÿà€®à€à¥à€°à¥à€²à€Ÿà€ à€ªà¥à€°à€Šà€°à¥à€¶à€š à€à€°à¥à€šà¥à€ž à€šà€à€°à¥à€šà¥à€ž}
+_texthelpexpandcontents_ [l=ne] {à€€à€Ÿà€²à€¿à€à€Ÿà€²à€Ÿà€ à€µà€¿à€žà¥à€€à€Ÿà€° à€à€°à¥à€šà¥ à€µà€Ÿ à€šà€à€°à¥à€šà¥}
+_texthelpdetachpage_ [l=ne] {à€¯à€ž à€ªà¥à€·à¥à€ à€²à€Ÿà€ à€šà€¯à€Ÿà€ Window à€®à€Ÿ à€à¥à€²à¥à€šà¥à€¹à¥à€žà¥}
+_texthelphighlight_ [l=ne] {à€à¥à€à€¿à€à€à€Ÿ à€¶à€µà¥à€Šà€¹à€°à¥à€²à€Ÿà€ à€ªà¥à€°à€à€Ÿà€¶à€¿à€€ à€à€°à¥à€šà¥ à€šà€à€°à¥à€šà¥}
+_texthelpsectionarrows_ [l=ne] {à€
+à€à€¿à€²à¥à€²à¥ à€ªà€à€¿à€²à¥à€²à¥ à€­à€Ÿà€à€®à€Ÿ à€à€Ÿà€šà¥à€¹à¥à€žà¥}
+
+
+_texthelpsearchingtitle_ [l=ne] {à€à€Ÿà€ž à€ªà€Šà€à¥ à€à¥à€à¥ à€à€žà€°à¥ à€à€°à¥à€šà¥ }
+
+_texthelpsearching_ [l=ne] {
+<p>
+   à€à¥à€ à€ªà¥à€·à¥à€ à€Šà¥à€µà€Ÿà€°à€Ÿ à€¯à¥ à€žà€Ÿà€®à€Ÿà€šà¥à€¯ à€à€Ÿà€°à¥à€¯à€¬à€Ÿà€ à€à€«à¥à€šà¥ à€à¥à€à¥ à€ªà¥à€°à€Ÿ à€à€°à¥à€š à€žà€à¥à€šà¥à€¹à¥à€šà¥à€ à¥€
+ :<p>
+
+   
+   <ol><li>à€€à€ªà€Ÿà€à€à¥ à€à¥à€à¥à€à¥ à€žà€Ÿà€®à€à¥à€°à¥ à€à¥ à€¹à¥ à€šà€¿à€°à¥à€§à€Ÿà€°à€£ à€à€°à¥à€šà¥à€¹à¥à€žà¥ à¥€
+       
+            <li>à€€à€ªà€Ÿà€ à€žà€®à¥à€ªà¥à€°à¥à€£ à€žà€Ÿà€®à€à¥à€°à¥ à€à¥à€à¥ à€à€°à¥à€š à€à€Ÿà€¹à€šà¥à€¹à¥à€šà¥à€ à€µà€Ÿ à€à¥à€¹à¥ à€
+à€à€¶ à€®à€Ÿà€€à¥à€° à€žà¥ à€šà€¿à€°à¥à€§à€Ÿà€°à€£ à€à€°à¥à€šà¥à€¹à¥à€žà¥ à¥€
+       
+            <li>à€à¥à€à¥ à€à€°à¥à€šà¥ à€ªà€°à¥à€šà¥ à€ªà€Š à€µà€Ÿ à€¶à€µà¥à€Š à€à€Ÿà€à€ª à€à€°à¥à€šà¥à€¹à¥à€žà¥ à¥€
+       
+            <li><i>à€à¥à€à¥à€š à€¶à¥à€°à¥ à€à€°à¥à€šà¥à€¹à¥à€žà¥ .</i> à€à¥à€²à€¿à€ à€à€°à¥à€šà¥à€¹à¥à€žà¥à¥€ .
+   
+      </ol>
+ 
+ 
+      
+<p> à€€à€ªà€Ÿà€à€²à¥ à€à¥à€à¥ à€¶à¥à€°à¥ à€à€°à¥à€ªà€à€¿ à€à¥à€à¥ à€à€°à¥à€à¥ à€à€¿à€à€žà€à€ à€®à€¿à€²à¥à€Šà€Ÿà€à¥à€²à¥à€Šà€Ÿ à€¬à¥à€žà€µà€à€Ÿ à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€Šà¥à€à¥à€š à€žà€à¥à€šà¥à€¹à¥à€šà¥à€ à¥€ 
+à€
+à€šà¥à€€à€®à€Ÿ à€
+à€°à¥ à€¬à¥à€žà€µà€à€Ÿ à€Šà€žà¥à€€à€Ÿà€µà¥à€à€®à€Ÿ à€ªà¥à€à¥à€šà¥ à€¬à€à€š à€­à¥à€à€¿à€šà¥à€ > à€à€¹à€Ÿà€à€¬à€Ÿà€ à€
+à€à€Ÿà€¡à€¿ à€ªà€à¥à€à€¿à€à€Ÿ à€¬à¥à€žà€µà€à€Ÿ à€Šà€žà¥à€€à€Ÿà€µà¥à€à€®à€Ÿ à€à€Ÿà€šà¥ à€° à€ªà€à€Ÿà€¡à€¿à€à€Ÿ à€¬à¥à€žà€µà€à€Ÿ à€Šà€žà¥à€€à€Ÿà€µà¥à€à€®à€Ÿ à€«à€°à¥à€à€šà¥ à€¬à€à€š à€­à¥à€à€¿à€šà¥à€ à¥€  
+à€€à€ªà€Ÿà€ à€¶à¥à€°à¥à€·à€ à€­à€šà¥à€šà¥ à€µà€Ÿ à€¶à¥à€°à¥à€·à€à€à¥ à€à¥à€µà¥à€à¥ à€¬à€à€š à€ªà¥à€°à€¯à¥à€ à€à€°à¥à€° à€€à¥ à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€¹à¥à€°à¥à€š à€žà€à€¿à€šà¥à€ à¥€
+ 
+ 
+<p> à€€à€ªà€Ÿà€ à€à€«à¥à€šà¥ à€à€µà€¶à¥à€¯à€à€€à€Ÿ à€
+à€šà¥à€žà€Ÿà€° à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿ à€ªà€°à€¿à€µà€°à¥à€€à€š à€à€°à¥à€š à€žà€à€¿à€šà¥à€ à¥€ <p> 
+ 
+}
+
+_texthelpquerytermstitle_ [l=ne] {à€à¥à€à¥ à€ªà€Š}
+_texthelpqueryterms_ [l=ne] {
+<p>à€€à€ªà€Ÿà€à€²à¥ à€à¥à€à¥ à€¬à€à¥à€žà€®à€Ÿ à€à€Ÿà€à€ª à€à€°à¥à€à¥ à€¶à€µà¥à€Šà€²à€Ÿà€ à€à¥à€à¥à€à€°à¥à€€à€Ÿ à€¶à€µà¥à€Š à€­à€šà¥à€° à€µà¥à€¯à€Ÿà€à¥à€¯à€Ÿ à€à€°à€¿à€šà¥à€ . 
+à€ªà¥à€°à€€à¥à€¯à¥à€ à€ªà€Š à€µà€°à¥à€£à€®à€Ÿà€²à€Ÿà€à€Ÿ à€à€¿à€šà¥à€¹ à€° à€
+à€à¥à€à€¬à€Ÿà€ à€¬à€šà¥à€Šà€à€šà¥ . à€Šà¥à€ à€
+à€²à€ à€
+à€²à€ à€ªà€Šà€²à€Ÿà€ à€¬à¥à€à€®à€Ÿ à€à€Ÿà€²à¥ à€ à€Ÿà€à€ à€°à€Ÿà€à¥à€° à€ªà€šà€¿ à€à¥à€à¥à€¯à€Ÿà€à€š à€žà€à€¿à€šà¥à€ à¥€ 
+ à€µà€¿à€°à€Ÿà€® à€à€¿à€šà¥à€¹à€²à€Ÿà€ à€ªà¥à€°à€¯à¥à€à€®à€Ÿ à€²à¥à€¯à€Ÿà€à€Šà¥à€š . à€à€žà€²à¥ à€à€°à¥à€Šà€Ÿ à€µà€¿à€°à€Ÿà€® à€à€¿à€šà¥à€¹ à€ªà¥à€°à€¯à¥à€ à€à€°à¥à€° à€à¥à€à¥ à€à€°à¥à€š à€žà€à€¿à€Šà¥à€š 
+
+
+ <p>à€à€Šà€Ÿà€¹à€°à€£M à€šà€¿à€®à¥à€šà€²à€¿à€à€¿à€€ à€à¥à€<p>
+     
+<ul><kbd> à€
+à€µà¥à€Šà¥à€² à€à€²à€Ÿà€® à€à€ à€žà€šà¥à€€ à€µà¥à€à¥à€à€Ÿà€šà€¿à€-
+ 
+ (2002)</kbd></ul>
+       
+<p>à€à¥ à€µà¥à€¯à€Ÿà€à¥à€¯à€Ÿ<p>
+       
+<ul><kbd>à€
+à€µà¥à€Šà¥à€² à€à€²à€Ÿà€® à€à€ à€žà€šà¥à€€ à€µà¥à€à¥à€à€šà€¿à€  2002 </kbd></ul><p>
+ <p>à€¹à¥à€šà¥à€ à¥€
+ 
+}
+
+# -- Missing translation: _texthelpmgppsearching_ 
+
+# -- Missing translation: _texthelplucenesearching_ 
+
+_texthelpquerytypetitle_ [l=ne] {à€à¥à€à€à€Ÿ à€ªà¥à€°à€à€Ÿà€°}
+# -- Missing translation: _texthelpquerytype_ 
+
+# -- Missing translation: _texthelpadvancedsearchtitle_ 
+
+# -- Missing translation: _texthelpadvancedsearch_ 
+
+# -- Missing translation: _texthelpadvsearchmg_ 
+
+# -- Missing translation: _texthelpbooleansearch_ 
+
+# -- Missing translation: _texthelpadvsearchmgpp_ 
+
+# -- Missing translation: _texthelpadvancedsearchextra_
+
+# -- Missing translation: _texthelpadvsearchlucene_ 
+
+_texthelpformsearchtitle_ [l=ne] {à€à¥à€·à¥à€€à¥à€° à€
+à€šà¥à€žà€Ÿà€°à€à¥ à€à¥à€}
+
+# -- Missing translation: _texthelpformsearch_ 
+
+# -- Missing translation: _texthelpformstemming_ 
+
+_textdatesearch_ [l=ne] {à€®à€¿à€€à€¿à€žà€à€à¥ à€à¥à€à¥à€šà¥}
+
+# -- Missing translation: _texthelpdatesearch_ 
+
+_texthelpdatehowtotitle_ [l=ne] {à€¯à¥ à€žà€Ÿà€®à€à¥à€°à¥ à€à€žà€°à¥ à€ªà¥à€°à€¯à¥à€ à€à€°à¥à€šà¥ :}
+# -- Missing translation: _texthelpdatehowto_ 
+
+# -- Missing translation: _texthelpdateresultstitle_ 
+# -- Missing translation: _texthelpdateresults_ 
+
+_textchangeprefs_ [l=ne] {à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿ à€ªà€°à€¿à€µà€°à¥à€€à€š}
+
+# -- Missing translation:_texthelppreferences_ 
+
+_texthelpcollectionprefstitle_ [l=ne] {à€žà€à€à¥à€°à€¹à€à€Ÿ à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿ}
+# -- Missing translation: _texthelpcollectionprefs_ 
+
+_texthelplanguageprefstitle_ [l=ne] {à€­à€Ÿà€·à€Ÿ à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿ}
+
+# -- Missing translation: _texthelplanguageprefs_ 
+
+_texthelppresentationprefstitle_ [l=ne] {à€ªà¥à€°à€žà¥à€€à¥à€€à€¿à€à€Ÿ à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿà€¹à€°à¥}
+# -- Missing translation: _texthelppresentationprefs_ 
+
+_texthelpsearchprefstitle_ [l=ne] {à€à¥à€ à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿ}
+# -- Missing translation: _texthelpsearchprefs_ 
+
+# -- Missing translation: _textcasefoldprefs_ 
+# -- Missing translation: _textstemprefs_
+# -- Missing translation: _textaccentfoldprefs_ 
+ 
+# -- Missing translation: _textstemoptionsprefs_ 
+
+# -- Missing translation: _textsearchtypeprefsplain_ 
+
+# -- Missing translation: _textsearchtypeprefsform_ 
+
+# -- Missing translation: _textsearchtypeprefsboth_ 
+
+
+
+_texttanumbrowseoptions_ [l=ne] { à€žà€à€à¥à€°à€¹à€¬à€Ÿà€ à€à€Ÿà€šà€à€Ÿà€°à¥ à€ªà¥à€°à€Ÿà€ªà¥à€€ à€à€°à¥à€š à€šà€¿à€®à¥à€š _numbrowseoptions_ à€€à€°à€¿à€à€Ÿ à€ªà¥à€°à€¯à¥à€ à€à€°à¥à€šà¥à€¹à¥à€žà¥:}
+
+_textsimplehelpheading_ [l=ne] {à€žà€à€à¥à€°à€¹à€¹à€°à¥à€¬à€Ÿà€ à€žà€à€à¥à€°à€¹à€à¥ à€šà€Ÿà€® à€žà€®à¥à€¬à€šà¥à€§à¥ à€à€Ÿà€šà€à€Ÿà€°à¥ à€à€žà€°à¥ à€ªà¥à€°à€Ÿà€ªà¥à€€ à€à€°à¥à€š à€žà€à€¿à€šà¥à€}
+
+# -- Missing translation: _texthelpscopetitle_
+# -- Missing translation: _texthelpscope_
Index: /gsdl/stable/macros/nzdlhome.dm
===================================================================
--- /gsdl/stable/macros/nzdlhome.dm	(revision 20131)
+++ /gsdl/stable/macros/nzdlhome.dm	(revision 20131)
@@ -0,0 +1,410 @@
+# this file must be UTF-8 encoded
+
+# nzdlhome.dm
+#
+# This file defines the homepage of the New Zealand Digital Library Project
+# as it appears on Http://www.nzdl.org. It is designed to override the default
+# homepage (defined in home.dm), so it should appear last in the "macrofiles"
+# section of the main.cfg file.
+#
+
+package home
+
+#######################################################################
+# global navigation links
+#######################################################################
+
+# we don't want any links shown on the front page
+_globallinks_ {}
+
+
+#######################################################################
+# icons
+#######################################################################
+
+_httpiconnzdl_ {_httpimg_/nzdl2gr.gif}
+_widthnzdl_ {457}
+_heightnzdl_ {181}
+
+_iconnzdl_ {<img src="_httpiconnzdl_" width=_widthnzdl_ height=_heightnzdl_ alt="The New Zealand Digital Library">}
+_icongbull_ {<img src="_httpicongbull_">}
+_iconpdf_ {<img src="_httpiconpdf_">}
+
+
+#######################################################################
+# http macros 
+#
+# These contain the url without any quotes
+#######################################################################
+
+_httpicongbull_ {_httpimg_/gbull.gif}
+
+_httpiconpdf_ {_httpimg_/pdf.gif}
+
+_httpicontmusic_ {_httpimg_/meldexsm.gif}
+
+
+#######################################################################
+# page content                     
+#######################################################################
+
+_pagetitle_ {_textpagetitle_}
+_imagethispage_ {}
+_imagecollection_ {<center>_iconnzdl_</center>}
+
+_content_ {
+_nzdlcollectionlist_
+<center><div class="divbar">&nbsp;</div></center>
+
+<p><center><h2>_textprojhead_</h2></center>
+
+<table border=0 cellpadding=5>
+
+<tr valign=top>
+<td>
+<table><tr valign="middle"><td>_icongbull_</td><td><a href="http://www.nzdl.org/html/people.html">People</a></td></tr></table>
+<table><tr valign="middle"><td>_icongbull_</td><td><a href="http://greenstone.cs.uct.ac.za/gsdl/cgi-bin/library">African Digital Library Centre</a></td></tr></table>
+<table><tr valign="middle"><td>_icongbull_</td><td><a href="http://sadl.uleth.ca">Southern Alberta Digital Library Centre</a></td></tr></table>
+</td>
+<td>_textprojinfo_</td>
+</tr>
+
+<tr>
+<td></td>
+<th align=left>_titlesoftwareinfo_</th>
+</tr>
+<tr valign=top>
+<td>
+<table><tr valign="middle"><td>_icongbull_</td><td><a href="_httppagex_(gsdl)">About<br>Greenstone</a></td></tr></table>
+<table><tr valign="middle"><td>_icongbull_</td><td><a href="http://www.greenstone.org/english/docs.html">Greenstone<br>Documentation</a></td></tr></table>
+</td>
+<td>_textsoftwareinfo_</td>
+</tr>
+
+<tr>
+<td></td>
+<th align=left>_titleresearchinfo_</th>
+</tr>
+<tr valign=top>
+<td>
+<table><tr valign="middle"><td>_icongbull_</td><td><a href="http://www.nzdl.org/html/research.html">Research</a></td></tr></table>
+<table><tr valign="middle"><td>_icongbull_</td><td><a href="http://www.nzdl.org/html/projects.html">Projects</a></td></tr></table>
+<table><tr valign="middle"><td>_icongbull_</td><td><a href="http://www.nzdl.org/html/software.html">Software<br>Downloads</a></td></tr></table>
+<table><tr valign="middle"><td>_icongbull_</td><td><a href="http://www.nzdl.org/cgi-bin/library?a=p&p=about&c=publicat">Publications</a></td></tr></table>
+</td>
+<td>_textresearchinfo_</td>
+</tr>
+
+<tr>
+<td></td>
+<th align=left>_titleaffiliateinfo_</th>
+</tr>
+<tr valign=top>
+<td>
+<img src="_httpimg_/ghproj.jpg" alt="Human Info NGO" width=100 height=90>
+</td>
+<td>_textaffiliatehumaninfo_</td></tr>
+<tr valign='top'>
+<td>
+<img src="_httpimg_/unescol.gif" alt="UNESCO" width=106 height=82>
+</td>
+<td>_textaffiliateunesco_</td>
+</tr></table></p>
+
+<div class="divbar">&nbsp;</div>
+<table>
+<tr valign=top>
+<td>_textpoem_</td>
+<td>_imagegreenstone_</td>
+</tr></table>
+<p>_textgreenstone_
+
+<p>
+_nzdlpagefooter_ 
+}
+
+#######################################################################
+# descriptions
+#######################################################################
+
+_textdescrcolun_ {Humanitarian and UN collections}
+
+_textdescrcolus_ {User contributed collections}
+
+_textdescrcolde_ {Demonstration collections}
+
+_textdescrcoldec_ {Documented Example collections}
+
+_textdescrcolgd_ {Greenstone documentation collections}
+
+#######################################################################
+# English language text macros
+#######################################################################
+_textpagetitle_ {New Zealand Digital Library}
+_textprojhead_ {The New Zealand Digital Library Project}
+
+_textprojinfo_ {
+<p>
+The New Zealand Digital Library project is a research programme at
+The University of Waikato whose aim is to develop the underlying
+technology for digital libraries and make it available publicly so that
+others can use it to create their own collections. 
+<p>
+Our web site provides several document collections, including historical
+documents, humanitarian and development information, computer
+science technical reports and bibliographies, literary works, and
+magazines. All are available over the Web, and can be accessed
+through searching and browsing interfaces provided by the
+Greenstone digital library software. Behind the query interface lies a
+huge collection providing gigabytes of information. We hope you find
+what you want, or at least something intriguing!
+}
+
+_titlesoftwareinfo_ {The Greenstone software}
+
+_textsoftwareinfo_ {
+<p>
+The <a href="http://www.greenstone.org">Greenstone Digital Library software</a> provides a new way of
+organizing information and making it available over the Internet or on
+CD-ROM. It is open-source software, available under the terms of the
+Gnu public license. 
+<p>
+A digital library is made up of a set of collections. Each collection of
+information comprises several (typically several thousand, or even
+several million) documents, which share a uniform searching and
+browsing interface. Collections can be organized in many different
+ways while retaining a strong family resemblance. 
+
+<p>To subscribe to the Greenstone mailing list, go to <a
+href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.</p>
+
+<p align=right>
+<a href="_httppagex_(gsdl)">More...</a>
+}
+
+_titleresearchinfo_ {Our research}
+
+_textresearchinfo_ {
+<p>
+The goal of our research program is to explore the potential of
+internet-based digital libraries. Our vision is to develop systems that
+automatically impose structure on anarchic, uncatalogued, distributed
+repositories of information, thereby providing information consumers
+with effective tools to locate what they need and to peruse it
+conveniently and comfortably. 
+<p>
+Project members are actively working on techniques for creating,
+managing, and and mainatining collections; extracting metadata from
+legacy documents; analysing library usage and user needs; Maori,
+Arabic and Chinese language systems; internationalising the library
+interface; optical music recognition and musical collections; novel
+interfaces for formulating queries and visualising results; novel
+interfaces for browsing metadata; text mining for keyphrases,
+acronyms, and other metadata; keyphrase extraction and
+phrase-based browsing; and other research topics. 
+<p align=right>
+<a href="http://www.nzdl.org/html/research.html">More...</a>
+}
+
+_titleaffiliateinfo_ {Our affiliates}
+
+_textaffiliatehumaninfo_ {
+<p>
+<a href="http://humaninfo.org">Human Info NGO</a>
+is a registered charity responsible for the
+provision of universal low-cost
+information access through co-operation between UN Agencies,
+universities and NGOs. Human Info NGO collaborates extensively
+with the NZDL project, and use the Greenstone software. 
+}
+
+_textaffiliateunesco_ {
+<p>
+<a href="http://www.unesco.org">United Nations Educational, Scientific and Cultural Organization</a>.
+The dissemination of educational, scientific and cultural information
+throughout the world, and particularly its availability in developing
+countries, is central to UNESCO's goals as pursued within its
+intergovernmental Information for All Programme, and appropriate,
+accessible information and communication technology is seen as an important
+tool in this context.
+}
+
+#######################################################################
+# The collection display
+# A hand-crafted alternative to the _homeextra_ macro
+#######################################################################
+
+_nzdlgwcgi_ {library}
+#_nzdlgwcgi_ {http://www.nzdl.org/cgi-bin/library}
+_nzdlhttpprefix_ {http://www.nzdl.org/gsdl}
+
+_nzdlcollection_ {library?a=p&p=about&c=_1_}
+#_nzdlcollection_ {http://www.nzdl.org/cgi-bin/library?a=p&p=about&c=_1_}
+_nzdlcollectionimage_ {<img width=150 border=1 src="_nzdlhttpprefix_/collect/_1_/images/_2_" alt=_3_ title=_3_>}
+
+_collectionlink_ {<a href="_nzdlcollection_(_4_)">_nzdlcollectionimage_(_1_,_2_,_3_)</a>}
+
+
+_nzdlcollectionlist_ {
+<center>
+<div class="divbar"><p class="navbar">_textdescrcolus_</p></div>
+<p>_collectusr_
+<div class="divbar"><p class="navbar">_textdescrcolun_</p></div>
+<p>_collectfao_
+<div class="divbar"><p class="navbar">_textdescrcolde_</p></div>
+<p>_collectrest_
+<a name="greenstonedocumentationcollections"></a>
+<div class="divbar"><p class="navbar">_textdescrcolgd_</p></div>
+<p>_collectgd_
+<a name="documentedexamplecollections"></a>
+<div class="divbar"><p class="navbar">_textdescrcoldec_</p></div>
+<p>_collectdec_
+</center>
+}
+
+_collectusr_{
+<table width=537>
+<tr valign=top>
+<td align=center>
+<p>_collectionlink_(aliveint, ait_sm.jpg, "Alive in Truth", aliveint)
+</td>
+<td align=center>
+<p>_collectionlink_(literatu,  hdlsm.gif, "Literature for Vietnam", literatu)
+</td>
+</tr>
+</table>
+}
+
+
+_collectfao_ {
+<table width=537>
+<tr valign=top>
+<td align=center>
+<p>_collectionlink_(hdl,  hdlsm.gif, "Humanity Development Library", hdl)
+<!--<p>_collectionlink_(fnl,  fnlsm.gif,   "Food and Nutrition Library", fnl)-->
+<p>_collectionlink_(envl, welsm.gif, "World Environment Library", envl)
+<p>_collectionlink_(aginfo, aginfo.gif, "Agricultural Information Modules", aginfo)
+<p>_collectionlink_(gtz, gtz.gif, "Crystal", gtz)
+<p>_collectionlink_(cdl, cdl.gif, "Community Development Library", cdl)
+<p>_collectionlink_(edudev, edudevsm.gif, "Human Info NGO Library for Education and Development", edudev)
+<p>_collectionlink_(nigeria, nigeriasm.gif, "Revitalizing Technical and Vocational Education in Nigeria", nigeria)
+<p>_collectionlink_(safem, safemsm.gif, "Safe Motherhood Strategies", safem)
+<p><a href="/cgi-bin/firstaid/library?a=p&p=about&c=firstaid&cl=0&l=en&w=utf-8"><img src="/custom/firstaid/collect/firstaid/images/colicon.jpg" border="1"></a>
+</td>
+
+<td align=center>
+<p>_collectionlink_(mhl,  mhlsm.gif,   "Medical and Health Library", mhl)
+<!--<p>_collectionlink_(fnl1\_1,  fnl1\_1.gif,   "Food and Nutrition Library 1.1", fnl1\_1)-->
+<p>_collectionlink_(paho, pahosml.gif, "Virtual Disaster Library", paho)
+<p>_collectionlink_(unesco, unescosm.gif, "Sahel point Doc", unesco)
+<p>_collectionlink_(muster, muster.gif, "The Multi-Site Teacher Education Research Project", muster)
+<p>_collectionlink_(unescoen, unescoensm.gif, "East African Development Library", unescoen)
+<p>_collectionlink_(dfid, dfidsm.gif, "Researching Education Development", dfid)
+<p>_collectionlink_(ewf, ewf.gif, "Education Work and the Future", ewf)
+<p>_collectionlink_(fi1998, faosm.gif, "FAO on the Internet &#40;1998&#41;", fi1998)
+<p>_collectionlink_(faodocs, faodrsm.gif, "FAO document repository", faodocs)</td>
+</td>
+
+<td align=center>
+<p>_collectionlink_(ccgi,   ccgism.gif,   "Collection on Critical Global Issues", ccgi)
+<p>_collectionlink_(fnl2.2,  fnl22.gif,   "Food and Nutrition Library 2.2", fnl2.2)
+<p>_collectionlink_(who, who.gif, "Biblioteca Virtual De Salud Para Desastres", who)
+<p>_collectionlink_(tulane, tulanesm.gif, "BibliothÃšque pour le dÃ©veloppement", tulane)
+<p>_collectionlink_(unaids, unaids.gif, "UNAIDS Library", unaids)
+<p>_collectionlink_(aedl, aedl.gif, "Africa Collection for Transition", aedl)
+<p>_collectionlink_(whoedm, whoedmsm.gif, "WHO Medicines Bookshelf 1.0", whoedm)
+<p>_collectionlink_(helid, helidsm.gif, "WHO Health Library for Disasters", helid)
+<p>_collectionlink_(ipc, ipcsm.gif, "Indigenous Peoples", ipc)
+<p>_collectionlink_(povsem, povsem_front.gif, "Poverty Alleviation", povsem)
+</tr>
+</table>
+}
+
+
+_collectrest_ {
+<table width=537>
+<tr valign=top>
+
+<td align=center>
+<p>_collectionlink_(acrodemo, acrodemosm.gif, "AGRIS: acronym extraction demo", acrodemo)
+<p><a href="library?a=p&p=about&c=niupepa&l=mi&nw=utf-8"><img width=150 border=1 src="_nzdlhttpprefix_/collect/niupepa/images/niupepsm.gif" alt="Niupepa: MÃ€ori Newspapers"></a>
+<p>_collectionlink_(arabic,  arabic.gif,  "Arabic text collection", arabic&l=ar&nw=windows-1256)
+<p>_collectionlink_(chinese, chinsm.jpg,  "Chinese text collection", chinese&l=zh&nw=utf-8)
+<p>_collectionlink_(folktale, folktale.gif, "Folktales: language extraction demo", folktale)
+<p>_collectionlink_(demooai, jcdl_logo_photo_tiled.gif, "OAI demo collection", demooai)
+<p>_collectionlink_(tidbits, tidbitsm.gif, "TidBITS", tidbits)
+<p>_collectionlink_(workingp, wp_logo.png, "Working Papers\, Dept of Computer Science\, University of Waikato", workingp)
+</td>
+
+<td align=center>
+<p><a href="/musiclib"><img src="_nzdlhttpprefix_/images/meldexsm.gif" border=1 alt="Meldex music library"></a>
+<p>_collectionlink_(wordpdf, wordpdf.gif, "MSWord and PDF demo", wordpdf)
+<p>_collectionlink_(musvid, musvid\_frontpage.gif, "Music Videos", musvid)
+<p>_collectionlink_(gberg,   gbergsm.gif, "Project Gutenberg Collection", gberg)
+<p>_collectionlink_(allshake, shakefront.gif, "The Complete works of Shakespeare", allshake)
+<p>_collectionlink_(aircraft, logo.gif, "aircraft images collection", aircraft)
+<p>_collectionlink_(csbib, csbibsm.gif, "Computer Science Bibliographies", csbib)
+<p>_collectionlink_(coltbib, coltsm.gif, "COLT Bibliography", coltbib)
+</td>
+
+<td align=center>
+<p>_collectionlink_(cstr, cstrsm.gif, "Computer Science Technical Reports", cstr)
+<p>_collectionlink_(ohist, ohist\_title\_small.gif, "Hamilton Public Library Youth Oral History Collection", ohist)
+<p>_collectionlink_(hcibib, hcibibsm.gif, "The HCI Bibliography", hcibib)
+<p>_collectionlink_(whist, whist\_logo\_small.gif, "Women\'s History Primary Source Documents", whist)
+<p>_collectionlink_(beowulf, beowulffront.jpg, "MARC Demonstration collection: Beowulf", beowulf)
+<p>_collectionlink_(tcc, tccsm.gif, "The Computists\' Weekly", tcc)
+<p>_collectionlink_(jair, jair-sm.gif, "Journal of Artificial Intelligence Research", jair)
+<p>_collectionlink_(lomdemo,ieeelom_sm.gif,"IEEE LOM Demonstration", lomdemo)
+</td>
+
+</tr>
+</table>
+}
+_collectgd_ {
+<table width=537>
+<tr valign=top>
+<td align=center>
+<p>_collectionlink_(publicat, nzdlpub.gif, "NZDL Publications collection", publicat)</td>
+<td align=center>
+<p>_collectionlink_(gsarch, gsarch.gif, "Greenstone mailing list archive", gsarch)
+<p><a href="/howto"><img width=150 height=110 border=1 src="/custom/howto/images/front_cover_tiled.gif" alt="How to build a digital library"></a></td>
+<td align=center>
+<p>_collectionlink_(gsdocs, gsdocs.gif, "Greenstone Documentation collection", gsdocs)</td>
+</tr></table>
+}
+
+_collectdec_ {
+<table width=537>
+<tr valign=top>
+
+<td align=center>
+<p>_collectionlink_(dls-e, en/dls-e.gif, "(Documented) Development Library Subset collection", dls-e)
+<p>_collectionlink_(wrdpdf-e, en/wrdpdf-e.gif, "(Documented) MSWord and PDF demonstration", wrdpdf-e)
+<p>_collectionlink_(gsarch-e, en/gsarch-e.gif, "(Documented) Greenstone Archives collection", gsarch-e)
+<p>_collectionlink_(isis-e, en/isis-e.gif, "(Documented) CDS/ISIS collection", isis-e)
+<p>_collectionlink_(dspace-e, en/dspace-e.gif,"(Documented) DSpace example collection", dspace-e)
+</td>
+
+<td align=center>
+<p>_collectionlink_(cltbib-e, en/cltbib-e.gif, "(Documented) bibliography collection", cltbib-e)
+<p>_collectionlink_(image-e, en/image-e.gif, "(Documented) simple image collection", image-e)
+<p>_collectionlink_(MARC-e, en/MARC-e.gif, "(Documented) MARC example", MARC-e)
+<p>_collectionlink_(oai-e, en/oai-e.gif, "(Documented) OAI demo collection", oai-e)
+</td>
+
+<td align=center>
+<p>_collectionlink_(cltext-e, en/cltext-e.gif, "(Documented) bibliography supplement", cltext-e)
+<p>_collectionlink_(pagedimg-e, en/pagedimg-e.gif, "(Documented) paged image collection", pagedimg-e)
+<p>_collectionlink_(garish, en/garish.gif, "(Documented) Garish version of demo collection", garish)
+<p>_collectionlink_(authen-e, en/authen-e.gif, "(Documented) Formatting and authentication demo", authen-e)
+<p>_collectionlink_(style-e, en/style-e.gif, "(Documented) Cascading Stylesheets collection", style-e)
+</td>
+
+</tr>
+</table>
+}
+
+
+# bbc no longer public
+#<p>_collectionlink_(bbc1, bbc_home.gif, "BBC archives (1900-1985)", bbc1)
Index: /gsdl/stable/macros/polish.dm
===================================================================
--- /gsdl/stable/macros/polish.dm	(revision 20131)
+++ /gsdl/stable/macros/polish.dm	(revision 20131)
@@ -0,0 +1,999 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Polish Language text and icon macros 
+# Many thanks to Lech Borkowski (translated March 2005)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=pl] {Periodyki}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=pl] {ÅºrÃ³dÅo:}
+_textdate_ [l=pl] {data publikacji:}
+_textnumpages_ [l=pl] {liczba stron}
+
+_textsignin_ [l=pl] {rejestracja}
+
+_textdefaultcontent_ [l=pl] {Nie znaleziono strony. Kliknij przycisk Wstecz przeglÄ
+darki
+internetowej lub przycisk Strona gÅÃ³wna, aby powrÃ³ciÄ do
+strony gÅÃ³wnej biblioteki cyfrowej Greenstone.}
+
+_textdefaulttitle_ [l=pl] {BÅÄ
+d GSDL}
+
+_textbadcollection_ [l=pl] {Ta kolekcja (zwana "_cvariable_") nie jest zainstalowana w tej bibliotece cyfrowej Greenstone.}
+
+_textselectpage_ [l=pl] {Wybierz stronÄ}
+
+_collectionextra_ [l=pl] {Kolekcja zawiera _about:numdocs_ dokumentÃ³w. 
+PowstaÅa _about:builddate_ dni temu. }
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=pl] {<p>Ta kolekcja zawiera _numdocs_ _If_("_numdocs_" eq "1",dokument,_If_("_numdocs_" lt "5",dokumenty,dokumentÃ³w)), ÅÄ
+cznie _numbytes_.
+<p><a href="_httppagex_(bsummary)">Kliknij</a>, aby obejrzeÄ podsumowanie kolekcji.
+}  
+
+_textdescrcollection_ [l=pl] {}
+_textdescrabout_ [l=pl] {Informacje}
+_textdescrhome_ [l=pl] {Strona gÅÃ³wna}
+_textdescrhelp_ [l=pl] {Pomoc}
+_textdescrpref_ [l=pl] {Preferencje}
+_textdescrgreenstone_ [l=pl] {Program Biblioteki Cyfrowej Greenstone}
+_textdescrusab_ [l=pl] {KtÃ³re elementy biblioteki sprawiajÄ
+ trudnoÅci?}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=pl] {Szukaj}  
+_labelSearch_ [l=pl] {Szukaj}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=pl] {TytuÅ}  
+_labelTitle_ [l=pl] {TytuÅy A-Z}
+_textCreator_ [l=pl] {TwÃ³rca}  
+_labelCreator_ [l=pl] {Autorzy A-Z}
+_textSubject_ [l=pl] {Temat}  
+_labelSubject_ [l=pl] {Tematy}
+_textDescription_ [l=pl] {Opis}  
+_labelDescription_ [l=pl] {Opisy}
+_textPublisher_ [l=pl] {Wydawca}  
+_labelPublisher_ [l=pl] {Wydawcy}
+_textContributor_ [l=pl] {WspÃ³ÅtwÃ³rca}  
+_labelContributor_ [l=pl] {WspÃ³Åpracownicy}
+_textDate_ [l=pl] {Data}  
+_labelDate_ [l=pl] {Daty}
+_textType_ [l=pl] {Typ}  
+_labelType_ [l=pl] {Typy}
+_textFormat_ [l=pl] {Format}  
+_labelFormat_ [l=pl] {Formaty}
+_textIdentifier_ [l=pl] {Indentyfikator}  
+_labelIdentifier_ [l=pl] {Identyfikatory}
+_textSource_ [l=pl] {Nazwa pliku}  
+_labelSource_ [l=pl] {Nazwy plikÃ³w}
+_textLanguage_ [l=pl] {JÄzyk}  
+_labelLanguage_ [l=pl] {JÄzyki}
+_textRelation_ [l=pl] {ZwiÄ
+zek}  
+_labelRelation_ [l=pl] {Relacje}
+_textCoverage_ [l=pl] {ReportaÅŒ}  
+_labelCoverage_ [l=pl] {Dziedzina}
+_textRights_ [l=pl] {Prawa}  
+_labelRights_ [l=pl] {Prawa}
+
+# DLS metadata set
+_textOrganization_ [l=pl] {Organizacja}  
+_labelOrganization_ [l=pl] {Organizacje}  
+_textKeyword_ [l=pl] {SÅowo kluczowe}  
+_labelKeyword_ [l=pl] {SÅowa kluczowe}
+_textHowto_ [l=pl] {Samouczek}  
+_labelHowto_ [l=pl] {Samouczek}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=pl] {Fraza}  
+_labelPhrase_ [l=pl] {Zwroty}
+_textCollage_ [l=pl] {KolaÅŒ}  
+_labelCollage_ [l=pl] {KolaÅŒ}
+_textBrowse_ [l=pl] {PrzeglÄ
+daj}  
+_labelBrowse_ [l=pl] {PrzeglÄ
+daj}  
+_textTo_ [l=pl] {Do}  
+_labelTo_ [l=pl] {Do}
+_textFrom_ [l=pl] {Od}  
+_labelFrom_ [l=pl] {Od (nadawca)}
+_textAcronym_ [l=pl] {Akronim}  
+_labelAcronym_ [l=pl] {SkrÃ³ty}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=pl] {PrzeglÄ
+daj po _1_}  
+
+_textdescrSearch_ [l=pl] {ZnajdÅº wyraÅŒenia}
+_textdescrType_ [l=pl] {PrzeglÄ
+daj wedÅug typu zasobÃ³w}
+_textdescrIdentifier_ [l=pl] {PrzeglÄ
+daj wedÅug identyfikatorÃ³w zasobÃ³w}
+_textdescrSource_ [l=pl] {PrzeglÄ
+daj wedÅug pierwotnych nazw plikÃ³w}
+_textdescrTo_ [l=pl] {PrzeglÄ
+daj wedÅug zawartoÅci pola Do}
+_textdescrFrom_ [l=pl] {PrzeglÄ
+daj wedÅug pola Od (nadawca)}
+_textdescrCollage_ [l=pl] {PrzeglÄ
+daj wedÅug obrazÃ³w}
+_textdescrAcronym_ [l=pl] {PrzeglÄ
+daj skrÃ³ty}
+_textdescrPhrase_ [l=pl] {PrzeglÄ
+daj wedÅug wyraÅŒeÅ}
+_textdescrHowto_ [l=pl] {PrzeglÄ
+daj kategorie Jak...}
+_textdescrBrowse_ [l=pl] {PrzeglÄ
+daj}
+_texticontext_ [l=pl] {PrzeglÄ
+daj dokument}
+_texticonclosedbook_ [l=pl] {otwÃ³rz dokument i przeglÄ
+daj}
+_texticonnext_ [l=pl] {nastÄpny rozdziaÅ}
+_texticonprev_ [l=pl] {poprzedni rozdziaÅ}
+
+_texticonworld_ [l=pl] {Zobacz dokument WWW}  
+
+_texticonmidi_ [l=pl] {PrzeglÄ
+daj dokument w formacie MIDI}
+_texticonmsword_ [l=pl] {PrzeglÄ
+daj dokument w formacie Microsoft Word}
+_texticonmp3_ [l=pl] {PrzeglÄ
+daj dokument w formacie MP3}
+_texticonpdf_ [l=pl] {PrzeglÄ
+daj dokument w formacie PDF}
+_texticonps_ [l=pl] {PrzeglÄ
+daj dokument w formacie PostScript}
+_texticonppt_ [l=pl] {PrzeglÄ
+daj dokument w formacie PowerPoint}
+_texticonrtf_ [l=pl] {PrzeglÄ
+daj dokument w formacie RTF}
+_texticonxls_ [l=pl] {PrzeglÄ
+daj dokument w formacie Microsoft Excel}
+
+_page_ [l=pl] {strona}
+_pages_ [l=pl] {stron}
+_of_ [l=pl] {z}
+_vol_ [l=pl] {Tom}
+_num_ [l=pl] {Nr}
+
+_textmonth00_ [l=pl] {}
+_textmonth01_ [l=pl] {StyczeÅ}
+_textmonth02_ [l=pl] {Luty}
+_textmonth03_ [l=pl] {Marzec}
+_textmonth04_ [l=pl] {KwiecieÅ}
+_textmonth05_ [l=pl] {Maj}
+_textmonth06_ [l=pl] {Czerwiec}
+_textmonth07_ [l=pl] {Lipiec}
+_textmonth08_ [l=pl] {SierpieÅ}
+_textmonth09_ [l=pl] {WrzesieÅ}
+_textmonth10_ [l=pl] {PaÅºdziernik}
+_textmonth11_ [l=pl] {Listopad}
+_textmonth12_ [l=pl] {GrudzieÅ}
+
+_textdocument_ [l=pl] {Dokument}
+_textsection_ [l=pl] {RozdziaÅ}
+_textparagraph_ [l=pl] {Akapit}
+
+_magazines_ [l=pl] {Czasopisma}
+
+_nzdlpagefooter_ [l=pl] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}
+
+_linktextHOME_ [l=pl] {STRONA GÅÃWNA}
+_linktextHELP_ [l=pl] {POMOC}
+_linktextPREFERENCES_ [l=pl] {PREFERENCJE}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=pl] {Biblioteka Cyfrowa Greenstone}  
+
+_textnocollections_ [l=pl] {Brak poprawnych (czyli np. zbudowanych i publicznych) kolekcji.}  
+
+_textadmin_ [l=pl] {Panel administracyjny}  
+_textabgs_ [l=pl] {O Greenstonie}  
+_textgsdocs_ [l=pl] {Dokumentacja do Greenstone'a}  
+
+_textdescradmin_ [l=pl] {Pozwala na dodanie nowych uÅŒytkownikÃ³w, przedstawia zestawienia dotyczÄ
+ce poszczegÃ³lnych kolekcji oraz zawiera techniczne informacje o systemie Greenstone.}  
+
+_textdescrgogreenstone_ [l=pl] {Przedstawia oprogramowanie Greenstone oraz projekt, z ktÃ³rego wyrosÅo: âNew Zealand Digital Library Projectâ}  
+
+_textdescrgodocs_ [l=pl] {PodrÄczniki do Greenstone'a}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=pl] {Interfejs Bibliotekarza}  
+_textdescrgli_ [l=pl] {Pomaga w tworzeniu nowych kolekcji, tworzeniu i modyfikacji juÅŒ istniejÄ
+cych oraz kasowaniu kolekcji}  
+
+package collector
+
+_textcollector_ [l=pl] {Kolekcjoner}  
+_textdescrcollector_ [l=pl] {Kolekcjoner jest poprzednikiem Bibliotekarza i w wiÄkszoÅci przypadkÃ³w naleÅŒy uÅŒywaÄ interfejsu dostarczanego wÅaÅnie przez Bibliotekarza}  
+
+package depositor
+
+_textdepositor_ [l=pl] {Depozytor}  
+_textdescrdepositor_ [l=pl] {Pomaga w dodawaniu nowych dokumentÃ³w do stworzonej kolekcji}  
+
+package gti
+
+_textgti_ [l=pl] {Interfejs TÅumacza Greenstone}  
+_textdescrtranslator_ [l=pl] {Pomaga w utrzymywaniu wielojÄzykowego interfejsu Greenstone}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=pl] {Informacje o kolekcji}
+
+_textsubcols1_ [l=pl] {<p>CaÅa kolekcja obejmuje _1_ podzbiorÃ³w. 
+DostÄpne sÄ
+:
+<blockquote>}
+
+_textsubcols2_ [l=pl] {</blockquote>
+Na stronie Preferencje moÅŒna zaznaczyÄ (i zmieniÄ) 
+przeglÄ
+dane podzbiory kolekcji.}
+
+_titleabout_ [l=pl] {informacje}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=pl] {zamknij dziaÅ}
+_texticonclosedbookshelf_ [l=pl] {otwÃ³rz ten dziaÅ i przeglÄ
+daj zawartoÅÄ}
+_texticonopenbook_ [l=pl] {zamknij ksiÄ
+ÅŒkÄ}
+_texticonclosedfolder_ [l=pl] {OtwÃ³rz folder i przeglÄ
+daj}
+_texticonclosedfolder2_ [l=pl] {otwÃ³rz podrozdziaÅ:}
+_texticonopenfolder_ [l=pl] {zamknij folder}
+_texticonopenfolder2_ [l=pl] {zamknij podrozdziaÅ:}
+_texticonsmalltext_ [l=pl] {PrzeglÄ
+daj ten rozdziaÅ}
+_texticonsmalltext2_ [l=pl] {PrzeglÄ
+daj tekst:}
+_texticonpointer_ [l=pl] {rozdziaÅ bieÅŒÄ
+cy}
+_texticondetach_ [l=pl] {OtwÃ³rz stronÄ w nowym oknie}
+_texticonhighlight_ [l=pl] {WyrÃ³ÅŒniaj poszukiwane wyraÅŒenia}
+_texticonnohighlight_ [l=pl] {Nie wyrÃ³ÅŒniaj poszukiwanych wyraÅŒeÅ}
+_texticoncontracttoc_ [l=pl] {ZwiÅ spis treÅci}
+_texticonexpandtoc_ [l=pl] {RozwiÅ spis treÅci}
+_texticonexpandtext_ [l=pl] {WyÅwietlaj caÅy tekst}
+_texticoncontracttext_ [l=pl] {WyÅwietlaj tekst jedynie dla bieÅŒÄ
+cego rozdziaÅu}
+_texticonwarning_ [l=pl] {<b>OstrzeÅŒenie: </b>}
+_texticoncont_ [l=pl] {kontynuowaÄ?}
+
+_textltwarning_ [l=pl] {<div class="buttons">_imagecont_</div>
+_iconwarning_RozwiniÄcie tekstu wymaga wyÅwietlenia 
+duÅŒej iloÅci danych w przeglÄ
+darce internetowej
+}
+
+_textgoto_ [l=pl] {przejdÅº do strony}
+_textintro_ [l=pl] {<i>(wstÄp)</i>}
+
+_textCONTINUE_ [l=pl] {KONTYNUOWAÄ??}
+
+_textEXPANDTEXT_ [l=pl] {ROZWIÅ\nTEKST}
+
+_textCONTRACTCONTENTS_ [l=pl] {ZWIÅ\nSPIS TREÅCI}
+
+_textDETACH_ [l=pl] {NOWE OKNO}
+
+_textEXPANDCONTENTS_ [l=pl] {ROZWIÅ\nSPIS TREÅCI}
+
+_textCONTRACT_ [l=pl] {ZWIÅ\nTEKST}
+
+_textHIGHLIGHT_ [l=pl] {WYRÃÅ»NIANIE}
+
+_textNOHIGHLIGHT_ [l=pl] {BRAK\nWYRÃÅ»NIANIA}
+
+_textPRINT_ [l=pl] {DRUKUJ}  
+
+_textnextsearchresult_ [l=pl] {nastÄpny wynik wyszukiwania}  
+_textprevsearchresult_ [l=pl] {poprzedni wynik wyszukiwania}  
+
+# macros for printing page
+_textreturnoriginal_ [l=pl] {WrÃ³Ä do pierwotnej strony}  
+_textprintpage_ [l=pl] {Wydrukuj tÄ stronÄ}  
+_textshowcontents_ [l=pl] {PokaÅŒ spis treÅci}  
+_texthidecontents_ [l=pl] {Ukryj spis treÅci}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=pl] {_If_(_thislast_,wynikÃ³w _thisfirst_ - _thislast_ dla kwerendy: _cgiargq_,Brak wynikÃ³w dla kwerendy: _cgiargq_)}
+_textnoquerytitle_ [l=pl] {Strona wyszukiwania}
+
+_textsome_ [l=pl] {niektÃ³re}
+_textall_ [l=pl] {wszystkie}
+_textboolean_ [l=pl] {logiczne}
+_textranked_ [l=pl] {nr pozycji na liÅcie}
+_textnatural_ [l=pl] {naturalny}
+_textsortbyrank_ [l=pl] {stopieÅ podobieÅstwa}  
+_texticonsearchhistorybar_ [l=pl] {historia wyszukiwania}
+
+_textifeellucky_ [l=pl] {WyÅwietl pierwszy znaleziony dokument }
+
+#alt text for query buttons
+_textusequery_ [l=pl] {uÅŒyj tej kwerendy}
+_textfreqmsg1_ [l=pl] {Liczba sÅÃ³w: }
+_textpostprocess_ [l=pl] {_If_(_quotedquery_,<br><i>przetworzone w celu znalezienia _quotedquery_</i>
+)}
+_textinvalidquery_ [l=pl] {NieprawidÅowa skÅadnia kwerendy}
+_textstopwordsmsg_ [l=pl] {PoniÅŒsze sÅowa sÄ
+ zbyt pospolite i zostaÅy zignorowane:}  
+_textlucenetoomanyclauses_ [l=pl] {Twoje zapytanie zawieraÅo zbyt wiele kryteriÃ³w wyszukiwania; sprÃ³buj bardziej zwiÄzÅego zapytania.}  
+
+_textmorethan_ [l=pl] {Ponad}
+_textapprox_ [l=pl] {Informacje}
+_textnodocs_ [l=pl] {Brak wynikÃ³w}
+_text1doc_ [l=pl] {znaleziono 1 dokument}
+_textlotsdocs_ [l=pl] {dokumentÃ³w speÅniajÄ
+cych warunki kwerendy.}
+_textmatches_ [l=pl] {Dopasowania}
+_textbeginsearch_ [l=pl] {Rozpocznij wyszukiwanie}
+_textrunquery_ [l=pl] {Uruchom kwerendÄ}
+_textclearform_ [l=pl] {WyczyÅÄ formularz}
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=pl] {SÅowo lub wyraÅŒenie
+}  
+_textinfield_ [l=pl] {... w polu}
+_textfoldstem_ [l=pl] {(zÅoÅŒenie, trzon)}
+
+_textadvquery_ [l=pl] {Lub wpisz kwerendÄ:}
+_textallfields_ [l=pl] {wszystkie pola}
+_texttextonly_ [l=pl] {tylko tekst}
+_textand_ [l=pl] {i}
+_textor_ [l=pl] {lub}
+_textandnot_ [l=pl] {i nie}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=pl] {ZnajdÅº _indexselection_ _If_(_jselection_,z _jselection_ )_If_(_gselection_, na poziomie _gselection_ )_If_(_nselection_,w jÄzyku _nselection_ ) zawierajÄ
+ce _querytypeselection_ sÅowa}
+
+_textadvancedsearch_ [l=pl] {ZnajdÅº _indexselection_ _If_(_jselection_,z _jselection_ )_If_(_gselection_,na poziomie _gselection_ )_If_(_nselection_,w jÄzyku _nselection_ )za pomocÄ
+ _querytypeselection_ kwerendy}
+
+_textadvancedmgppsearch_ [l=pl] {Szukaj _indexselection__If_(_jselection_, z _jselection_)_If_(_gselection_, na poziomie _gselection_)_If_(_nselection_, w jÄzyku _nselection_) i wyÅwietl wyniki w porzÄ
+dku _formquerytypeadvancedselection_}  
+
+_textadvancedlucenesearch_ [l=pl] {Szukaj _indexselection__If_(_jselection_, z _jselection_)_If_(_gselection_, na poziomie _gselection_)_If_(_nselection_, w jÄzyku _nselection_)_If_(_sfselection_,\,_allowformbreak_ wyniki zapytaÅ w _sfselection_\,) dla }  
+
+_textformsimplesearch_ [l=pl] {ZnajdÅº _If_(_jselection_,_jselection_ )_If_(_gformselection_,na poziomie _gformselection_ )_If_(_nselection_,w jÄzyku _nselection_ ) dla _formquerytypesimpleselection_}
+
+_textformadvancedsearchmgpp_ [l=pl] {Szukaj _If_(_jselection_,_jselection_ )_If_(_gformselection_,na poziomie _gformselection_ )_If_(_nselection_,w jÄzyku _nselection_) i wyÅwietl wyniki w porzÄ
+dku _formquerytypeadvancedselection_}  
+
+_textformadvancedsearchlucene_ [l=pl] {Szukaj _If_(_jselection_, _jselection_)_If_(_gformselection_,  na poziomie _gformselection_)_If_(_nselection_, w jÄzyku _nselection_)_If_(_sfselection_,\, wyÅwietlajÄ
+c wyniki _sfselection_\,) dla }  
+
+_textnojsformwarning_ [l=pl] {Uwaga: wyÅÄ
+czono obsÅugÄ jÄzyka Javascript w przeglÄ
+darce. <br>Aby uÅŒyÄ formularza wyszukiwania, wÅÄ
+cz Javascript.}
+_textdatesearch_ [l=pl] {W tej kolekcji moÅŒna szukaÄ dokumentÃ³w pasujÄ
+cych do zakresu dat lub dokumenty zawierajÄ
+ce konkretnÄ
+ datÄ. Jest to opcja wyszukiwania.}
+_textstartdate_ [l=pl] {Data poczÄ
+tkowa (lub jedyna):}
+_textenddate_ [l=pl] {Data koÅcowa:}
+_textbc_ [l=pl] {p.n.e.}
+_textad_ [l=pl] {n.e.}
+_textexplaineras_ [l=pl] {SkrÃ³ty C.E. i B.C.E sÄ
+ alternatywnymi oznaczeniami skrÃ³tÃ³w A.D. i B.C.  WyraÅŒenia te sÄ
+ uwaÅŒane za neutralne pod wzglÄdem kulturowym i oznaczajÄ
+ "Common Era", czyli "naszej ery" oraz "Before the Common Era", czyli "przed naszÄ
+ erÄ
+"}
+
+_textstemon_ [l=pl] {(nie uwzglÄdniaj koÅcÃ³wek sÅÃ³w)}
+
+_textsearchhistory_ [l=pl] {Historia wyszukiwania}
+
+#text macros for search history
+_textnohistory_ [l=pl] {Brak wpisÃ³w w historii wyszukiwania}
+_texthresult_ [l=pl] {wynik}
+_texthresults_ [l=pl] {wyniki}
+_texthallwords_ [l=pl] {wszystkie sÅowa}
+_texthsomewords_ [l=pl] {niektÃ³re sÅowa}
+_texthboolean_ [l=pl] {logiczne}
+_texthranked_ [l=pl] {pozycja na liÅcie}
+_texthcaseon_ [l=pl] {uwzglÄdnij wielkoÅÄ liter}
+_texthcaseoff_ [l=pl] {nierozrÃ³ÅŒnianie wielkoÅci liter}
+_texthstemon_ [l=pl] {ograniczenie do trzonu sÅowa}
+_texthstemoff_ [l=pl] {caÅe sÅowa}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=pl] {Oto zapisane preferencje. Nie uÅŒywaj przycisku Wstecz przeglÄ
+darki
+internetowej, poniewaÅŒ ustawienia zostaÅyby anulowane!
+Kliknij jeden z przyciskÃ³w na pasku powyÅŒej.}
+_textsetprefs_ [l=pl] {zapisz preferencje}
+_textsearchprefs_ [l=pl] {Preferencje wyszukiwania}
+_textcollectionprefs_ [l=pl] {Ustawienia kolekcji}
+_textpresentationprefs_ [l=pl] {Preferencje prezentacji}
+_textpreferences_ [l=pl] {Preferencje}
+_textcasediffs_ [l=pl] {RozrÃ³ÅŒnianie wielkoÅci liter:}
+_textignorecase_ [l=pl] {nie uwzglÄdniaj wielkoÅci liter}
+_textmatchcase_ [l=pl] {uwzglÄdnij wielkoÅÄ liter}
+_textwordends_ [l=pl] {KoÅcÃ³wki sÅÃ³w:}
+_textstem_ [l=pl] {Nie uwzglÄdniaj koÅcÃ³wek sÅÃ³w}
+_textnostem_ [l=pl] {dopasowane musi byÄ caÅe sÅowo}
+_textaccentdiffs_ [l=pl] {RÃ³ÅŒnice w akcentach:}  
+_textignoreaccents_ [l=pl] {ignoruj akcenty (ogonki)}  
+_textmatchaccents_ [l=pl] {akcenty (ogonki) majÄ
+ znaczenie}  
+
+_textprefop_ [l=pl] {PokaÅŒ do _maxdocoption_ trafieÅ, _hitsperpageoption_ trafieÅ na jednej stronie.}
+_textextlink_ [l=pl] {DostÄp do zewnÄtrznych stron WWW:}
+_textintlink_ [l=pl] {Lokalizacja dokumentÃ³w ÅºrÃ³dÅowych: }
+_textlanguage_ [l=pl] {JÄzyk interfejsu uÅŒytkownika}
+_textencoding_ [l=pl] {Kodowanie znakÃ³w:}
+_textformat_ [l=pl] {Format interfejsu:}
+_textall_ [l=pl] {wszystkie}
+_textquerymode_ [l=pl] {Tryb kwerendy:}
+_textsimplemode_ [l=pl] {wyszukiwanie proste}  
+_textadvancedmode_ [l=pl] {wyszukiwanie zaawansowane (umoÅŒliwia wyszukiwanie logiczne za pomocÄ
+ operatorÃ³w !, &, | i nawiasÃ³w)}  
+_textlinkinterm_ [l=pl] {przez stronÄ poÅredniÄ
+}
+_textlinkdirect_ [l=pl] {przejdÅº}
+_textdigitlib_ [l=pl] {biblioteka cyfrowa}
+_textweb_ [l=pl] {sieÄ WWW}
+_textgraphical_ [l=pl] {Graficzny}
+_texttextual_ [l=pl] {Tekstowy}
+_textcollectionoption_ [l=pl] {<p>
+UwzglÄdnij podzbiory kolekcji:
+<br>}
+
+_textsearchtype_ [l=pl] {Styl zapytaÅ:}  
+_textformsearchtype_ [l=pl] {wyszukiwanie w _formnumfieldoption_ polach}  
+_textplainsearchtype_ [l=pl] {normalne z _boxsizeoption_ rodzajem zapytaÅ}  
+_textregularbox_ [l=pl] {pojedyncze linie}  
+_textlargebox_ [l=pl] {duÅŒe}  
+
+_textrelateddocdisplay_ [l=pl] {wyÅwietl dokumenty pokrewne}
+_textsearchhistory_ [l=pl] {Historia wyszukiwania:}
+_textnohistory_ [l=pl] {Brak historii wyszukiwania}
+_texthistorydisplay_ [l=pl] {pokaÅŒ wpisy _historynumrecords_ ostatnich wyszukiwaÅ}
+_textnohistorydisplay_ [l=pl] {nie wyÅwietlaj historii wyszukiwania}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=pl] {Sortuj dokumenty wedÅug}
+_textalsoshowing_ [l=pl] {rÃ³wnieÅŒ}
+_textwith_ [l=pl] {zawierajÄ
+ce co najwyÅŒej}
+_textdocsperpage_ [l=pl] {dokumentÃ³w na stronie}
+
+_textfilterby_ [l=pl] {ZnajdÅº dokumenty zawierajÄ
+ce}
+_textall_ [l=pl] {wszystkie}
+_textany_ [l=pl] {niektÃ³re}
+_textwords_ [l=pl] {sÅowa}
+_textleaveblank_ [l=pl] {pozostaw pole nie zaznaczone, aby otrzymaÄ wszystkie dokumenty}
+
+_browsebuttontext_ [l=pl] {"Sortuj dokumenty"}
+
+_nodata_ [l=pl] {<i>brak danych</i>}
+_docs_ [l=pl] {dokumenty}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=pl] {Pomoc}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=pl] {przeglÄ
+daj dokumenty po _1_ klikajÄ
+c na przycisk _2_}  
+
+_textSearchhelp_ [l=pl] {moÅŒesz wyszukaÄ konkretne sÅowa, wystÄpujÄ
+ce w tekÅcie, klikajÄ
+c na przycisk _labelSearch_}  
+_textTohelp_ [l=pl] {przyciÅnij przycisk _labelTo_, aby przeglÄ
+daÄ dokumenty wedÅug pola Do.}  
+_textFromhelp_ [l=pl] {przeglÄ
+daj dokumenty po polu Od klikajÄ
+c przycisk _labelFrom_}  
+_textBrowsehelp_ [l=pl] {przeglÄ
+daj dokumenty}  
+_textAcronymhelp_ [l=pl] {przeglÄ
+daj pliki po wystÄ
+pieniach akronimÃ³w klikajÄ
+c na przycisk _labelAcronym_}  
+_textPhrasehelp_ [l=pl] {moÅŒesz przeglÄ
+daÄ poszczegÃ³lne frazy pojawiajÄ
+ce siÄ w dokumentach klikajÄ
+c przycisk _labelPhrase_. Do tego celu wykorzystywana jest przeglÄ
+darka fraz zwana Phind.}  
+
+_texthelptopicstitle_ [l=pl] {Tematy}
+
+_textreadingdocs_ [l=pl] {Jak czytaÄ dokumenty}
+
+_texthelpreadingdocs_ [l=pl] {<p>Po znalezieniu dokumentu w lewym gÃ³rnym rogu strony pojawia siÄ
+jego tytuÅ lub obraz strony tytuÅowej. W niektÃ³rych kolekcjach towarzysz temu spis treÅci,
+a w innych pojawia siÄ tylko numer strony bieÅŒÄ
+cej oraz pole umoÅŒliwiajÄ
+ce wybÃ³r
+nowej strony i przejÅcie do przodu lub wstecz. W spisie treÅci nagÅÃ³wek
+bieÅŒÄ
+cego rozdziaÅu jest drukowany czcionkÄ
+ pogrubionÄ
+, a spis jest rozwijalny --
+kliknij nazwÄ folderu, aby go otworzyÄ lub zamknÄ
+Ä; aby zamknÄ
+Ä ksiÄ
+ÅŒkÄ,
+kliknij u gÃ³ry ikonÄ otwartej ksiÄ
+ÅŒki.</p>
+
+<p>PoniÅŒej znajduje siÄ tekst bieÅŒÄ
+cego rozdziaÅu. StrzaÅki u doÅu strony
+umoÅŒliwiajÄ
+ przejÅcie do nastÄpnego lub poprzedniego rozdziaÅu.</p>
+
+<p>Pod tytuÅem lub fotografiÄ
+ znajduje siÄ kilka przyciskÃ³w. Aby rozwinÄ
+Ä
+caÅy tekst bieÅŒÄ
+cego rozdziaÅu lub ksiÄ
+ÅŒki, kliknij przycisk <i>RozwiÅ tekst</i>.
+Rozwijanie tekstu duÅŒego dokumentu moÅŒe trwaÄ dÅugo i zajÄ
+Ä sporo pamiÄci operacyjnej!
+Aby rozwinÄ
+Ä zawartoÅÄ spisu treÅci, kliknij przycisk<i>RozwiÅ spis treÅci</i>.
+Aby otworzyÄ nowe okno przeglÄ
+darki, kliknij przycisk <i>Nowe okno</i>
+(Jest to przydatne podczas porÃ³wnywania zawartoÅci lub jednoczesnego odczytywania dwÃ³ch dokumentÃ³w.)
+W wynikach wyszukiwania poszukiwane wyrazy sÄ
+ wyrÃ³ÅŒnione. Aby wyÅÄ
+czyÄ wyrÃ³ÅŒnianie, naleÅŒy kliknÄ
+Ä przycisk <i>Bez wyrÃ³ÅŒniania</i>.</p>
+}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=pl] {OtwÃ³rz pÃ³ÅkÄ z ksiÄ
+ÅŒkami}
+_texthelpopenbook_ [l=pl] {OtwÃ³rz/zamknij ksiÄ
+ÅŒkÄ}
+_texthelpviewtextsection_ [l=pl] {PrzeglÄ
+daj rozdziaÅ}
+_texthelpexpandtext_ [l=pl] {WÅÄ
+cz/WyÅÄ
+cz wyÅwietlanie caÅego tekstu}
+_texthelpexpandcontents_ [l=pl] {RozwiÅ/ZwiÅ spis treÅci}
+_texthelpdetachpage_ [l=pl] {OtwÃ³rz stronÄ w nowym oknie}
+_texthelphighlight_ [l=pl] {WyrÃ³ÅŒniaj/Nie wyrÃ³ÅŒniaj wyszukiwane wyraÅŒenia}
+_texthelpsectionarrows_ [l=pl] {PrzejdÅº do poprzedniej/nastÄpnej sekcji}  
+
+
+_texthelpsearchingtitle_ [l=pl] {Jak formuÅowaÄ kwerendÄ w poszukiwaniu konkretnych wyrazÃ³w}
+
+_texthelpsearching_ [l=pl] {<p>
+   Aby uruchomiÄ kwerendÄ, wykonaj na stronie wyszukiwania nastÄpujÄ
+ce czynnoÅci:<p>
+   
+   <ol><li>Wybierz rodzaj poszukiwanych wyraÅŒeÅ
+       <li>Zdecyduj, czy dopasowane majÄ
+ byÄ wszystkie sÅowa, czy tylko niektÃ³re sÅowa kwerendy
+       <li>Wpisz poszukiwane wyrazy
+       <li>Kliknij przycisk <i>Rozpocznij wyszukiwanie</i>
+   </ol>
+ 
+ <p>Po zakoÅczeniu kwerendy pojawiÄ
+ siÄ tytuÅy 20 dokumentÃ³w.
+ Przycisk u doÅu strony umoÅŒliwia przejÅcie do nastÄpnych 20 dokumentÃ³w.
+ Na nastÄpnej stronie moÅŒna wybraÄ kolejnych 20 dokumentÃ³w
+ lub powrÃ³ciÄ do poprzedniej dwudziestki itd.  Aby przejrzeÄ dokument, kliknij tytuÅ
+ dokumentu lub maÅy przycisk obok niego.
+ 
+ <p>Maksymalnie wynik wyszukiwania obejmuje 100 dokumentÃ³w.
+   Aby zmieniÄ tÄ liczbÄ, kliknij przycisk
+   <i>preferencje</i> u gÃ³ry strony.<p>
+}  
+
+_texthelpquerytermstitle_ [l=pl] {PostaÄ kwerendy}
+_texthelpqueryterms_ [l=pl] {<p>Wszystko co wpiszesz w pole zapytania, zostanie zinterpretowane jako lista sÅÃ³w lub zwrotÃ³w do wyszukania â tzw. âterminy wyszukiwawczeâ. Termin to pojedyncze sÅowo (zawierajÄ
+ce tylko litery i cyfry), albo zwrot zÅoÅŒony z ciÄ
+gu sÅÃ³w zamkniÄtych w podwÃ³jnych cudzysÅowach ("..."). PoszczegÃ³lne terminy oddzielone sÄ
+ spacjami lub innymi biaÅymi znakami (spacja, tabulacja, znak nowej linii). JeÅŒeli pojawiÄ
+ siÄ jakieÅ inne znaki â np. interpunkcyjne â to bÄdÄ
+ traktowane tak samo jak spacje, czyli sÅuÅŒyÄ tylko jako znaki rozdzielajÄ
+ce poszczegÃ³lne terminy i zostanÄ
+ zignorowane w wyszukiwaniu. Nie jest moÅŒliwe wyszukanie sÅÃ³w zawierajÄ
+cych znaki interpunkcyjne.
+
+<p>Na przykÅad, zapytanie<p>
+   <ul><kbd>LeÅne-ogrody na wyspach Australii i Oceanii: Systemy zrÃ³wnowaÅŒonego rozwÃ³j (1993)</kbd></ul>
+   <p>zostanie potraktowane identycznie jak<p>
+   <ul><kbd>LeÅne ogrody na wyspach Australii i Oceanii Systemy zrÃ³wnowaÅŒonego rozwÃ³j 1993</kbd></ul>
+}  
+
+_texthelpmgppsearching_ [l=pl] {W kolekcjach zbudowanych z uÅŒyciem "MGPP" wystÄpuje kilka innych opcji.
+
+<ul>
+<li><b>*</b> uÅŒywana na koÅcu zapytania pozwala na znalezienie wszystkich sÅÃ³w <b>zaczynajÄ
+cych siÄ od</b> podanego sÅowa, np. <b>komput*</b> zostanie dopasowane do wszystkich sÅÃ³w zaczynajÄ
+cych siÄ od <b>komput</b> (np. komputer, komputerowy).
+<li><b>/x</b> moÅŒe byÄ uÅŒyte do przypisania wiÄkszej wagi jednemu ze sÅÃ³w, np. <b>komputer/10 nauka</b> nadaje sÅowu komputer 10 razy wiÄkszÄ
+ wagÄ niÅŒ sÅowu nauka przy ocenie dopasowania do dokumentÃ³w.
+</ul>
+}  
+
+_texthelplucenesearching_ [l=pl] {W kolekcjach zbudowanych z uÅŒyciem "Lucene" wystÄpujÄ
+ dodatkowe opcje.
+
+<ul>
+<li><b>?</b> moÅŒe byÄ uÅŒywany jako znak zastÄpujÄ
+cy dowolny inny. Na przykÅad, <b>b?t</b> zostanie dopasowane do sÅÃ³w: <b>but</b>, <b>bit</b> and <b>byt</b> itp.
+<li><b>*</b> moÅŒe byÄ uÅŒywana jako znak zastÄpujÄ
+cy wiele dowolnych znakÃ³w. Na przykÅad, <b>komput*</b> zostanie dopasowane do wszystkich sÅÃ³w zaczynajÄ
+cych siÄ od <b>komput</b> (np. komputer, komputerowy).
+</ul>
+Oba te znaki mogÄ
+ byÄ uÅŒywane zarÃ³wno na koÅcu jak i w Årodku wyraÅŒenia. Jednak nie mogÄ
+ byÄ uÅŒywane na poczÄ
+tku wyraÅŒenia.
+}  
+
+_texthelpquerytypetitle_ [l=pl] {Typ kwerendy}
+_texthelpquerytype_ [l=pl] {<p>SÄ
+ dwa rodzaje zapytaÅ.
+
+<ul>
+  <li>Wyszukiwanie <b>wszystkich</b> wyrazÃ³w.  Dokumenty majÄ
+ zawieraÄ
+      wszystkie wpisane sÅowa.  Wyniki sÄ
+ wyÅwietlane w kolejnoÅci alfabetycznej.<p>
+
+  <li>Wyszukiwanie dokumentÃ³w zawierajÄ
+cych <b>niektÃ³re</b> spoÅrÃ³d wpisanych wyrazÃ³w.
+      Dokumenty sÄ
+ wyÅwietlane w kolejnoÅci najlepszego dopasowania do kwerendy.
+      StopieÅ dopasowania zaleÅŒy od nastÄpujÄ
+cych czynnikÃ³w:
+
+      <p><ul>
+        <li> im wiÄcej poszukiwanych wyrazÃ³w w dokumencie, tym lepsze dopasowanie;
+        <li> rzadko spotykane wyrazy sÄ
+ waÅŒniejsze niÅŒ wyrazy popularne;
+        <li> krÃ³tkie dokumenty dajÄ
+ lepsze dopasowanie.
+      </ul>
+</ul>
+
+<p>MoÅŒna uÅŒyÄ dowolnie wielu wyrazÃ³w -- moÅŒe to byÄ caÅe zdanie
+lub nawet caÅy akapit.  W przypadku podania tylko jednego wyrazu
+dokumenty bÄdÄ
+ uÅoÅŒone wedÅug czÄstotliwoÅci wystÄpowania wyrazu w dokumencie.<p>
+}  
+
+_texthelpadvancedsearchtitle_ [l=pl] {Zaawansowane wyszukiwanie z uÅŒyciem silnika _1_}  
+
+_texthelpadvancedsearch_ [l=pl] {<p>JeÅli wybraÅeÅ tryb zaawansowanych zapytaÅ (w swoich preferencjach), to moÅŒesz mieÄ nieco inne moÅŒliwoÅci wyszukiwania. _selectadvancedsearch_}  
+
+_texthelpadvsearchmg_ [l=pl] {Zaawansowane wyszukiwanie w kolekcjach MG daje Ci dwie moÅŒliwoÅci: rankingowÄ
+ i logicznÄ
+.
+Wyszukiwanie <b>rankingowe</b> jest dokÅadnie tym samym co wyszukiwanie <b>niektÃ³re</b> opisane w <a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_
+}  
+
+_texthelpbooleansearch_ [l=pl] {UÅŒywajÄ
+c <b>operatorÃ³w logicznych</b> moÅŒna ÅÄ
+czyÄ wyraÅŒenia
+uÅŒywajÄ
+c & (jako âiâ), | (jako âlubâ), oraz ! (jako zaprzeczenie), moÅŒna takÅŒe uÅŒywaÄ nawiasÃ³w, aby grupowaÄ wyraÅŒenia. DomyÅlnym operatorem jest | (czyli lub).
+<p>
+Na przykÅad, <b>Ålimak & rolnictwo</b> zostanie dopasowane do dokumentÃ³w zawierajÄ
+cych oba sÅowa - <b>Ålimak</b> i <b>rolnictwo</b>, natomiast <b>Ålimak | rolnictwo</b> zostanie dopasowane do dokumentÃ³w zawierajÄ
+cych jedno ze sÅÃ³w - <b>Ålimak</b> lub <b>rolnictwo</b>. Natomiast <b>Ålimak !rolnictwo</b> zostanie dopasowane do dokumentÃ³w zawierajÄ
+cych sÅowo <b>Ålimak</b> i nie zawierajÄ
+cych sÅowa <b>rolnictwo</b>.
+<p>
+Bardziej szczegÃ³Åowe zapytania moÅŒna okreÅliÄ przy uÅŒyciu nawiasÃ³w lub kombinacji operatorÃ³w - na przykÅad: <b>(owca | bydÅo) & (farma | pociÄ
+g)</b> lub <b>owca | bydÅo | koza !Åwinia</b>.}  
+
+_texthelpadvsearchmgpp_ [l=pl] {Zaawansowane wyszukiwanie w kolekcjach MGPP umoÅŒliwia uÅŒycie operatorÃ³w logicznych. _texthelpbooleansearch_
+<p>Resultaty mogÄ
+ byÄ przedstawione w porzÄ
+dku <b>rankingowym</b>, jak to opisano dla wyszukiwania <b>niektÃ³re</b> w <a href="\#query-type">_texthelpquerytypetitle_</a> lub w porzÄ
+dku "naturalnym" (lub "budowy"). Ten ostatni to kolejnoÅÄ, w ktÃ³rej dokumenty byÅy przetwarzane podczas tworzenia kolekcji.
+<p>
+Inne operatory to <b>NEARx</b> oraz <b>WITHINx</b>.
+NEARx uÅŒywa siÄ do podania maksymalnej odlegÅoÅci miÄdzy dwoma zapytaniami (skÅadajÄ
+cymi siÄ z x-sÅÃ³w), ktÃ³ra to odlegÅoÅÄ stanowiÄ bÄdzie o tym, czy dokument zostanie zakwalifikowany jako trafienie
+WITHINx okreÅla , ÅŒe nastÄpny fragment musi wystÄ
+piÄ w ciÄ
+gu x sÅÃ³w <i>po</i> pierwszym fragmencie. Jest to podobne zachowanie do NEAR ale kolejnoÅÄ ma tutaj znaczenie. DomyÅlny dystans wynosi 20.
+}  
+
+_texthelpadvancedsearchextra_ [l=pl] {UWAGA: Wszystkie te operatory w trybie uproszczonych zapytaÅ nie sÄ
+ brane pod uwagÄ.}  
+
+_texthelpadvsearchlucene_ [l=pl] {Zaawansowane wyszukiwanie w kolekcjach Lucene umoÅŒliwia uÅŒywanie operatorÃ³w logicznych. _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=pl] {Wyszukiwanie w polach}  
+
+_texthelpformsearch_ [l=pl] {Wyszukiwanie w (wielu) polach pozwala na ÅÄ
+czenie rÃ³ÅŒnych fraz wyszukiwawczych w rÃ³ÅŒnych polach. Na przykÅad moÅŒna wyszukiwaÄ nazwiska âKowalskiâ w Tytule i âhodowla ÅlimakÃ³wâ w Temacie. W trybie uproszczonych zapytaÅ kaÅŒdy wiersz formularza dziaÅa jako normalne wyszukiwanie w pojedynczej linii. PoszczegÃ³lne wiersze formularza sÄ
+ skÅadane przy pomocy operatora âiâ (jeÅli wybrano âcaÅoÅÄâ), albo przy pomocy âlubâ (jeÅli wybrano âczÄÅÄâ). PoszczegÃ³lne pojÄcia wewnÄ
+trz pÃ³l sÄ
+ skÅadane analogicznie. W trybie zaawansowanym dla kaÅŒdego wiersza moÅŒna wybraÄ (z rozwijalnej listy) jakim operatorem zostanÄ
+ poÅÄ
+czone (âiâ, âlubâ, zaprzeczenie), natomiast w kaÅŒdym z pÃ³l moÅŒna uÅŒywaÄ operatorÃ³w logicznych.}  
+
+_texthelpformstemming_ [l=pl] {Okienka "zÅoÅŒenie" i "trzon" pozwalajÄ
+ na wybranie, czy przy wyszukiwaniu wielkoÅÄ znakÃ³w powinna byÄ ignorowana oraz czy ignorowaÄ koÅcÃ³wki (odmianÄ) sÅÃ³w - to ostatnie obecnie dziaÅa tylko w jÄzyku angielskim. Obie te opcje sÄ
+ domyÅlnie wyÅÄ
+czone przy zaawansowanym wyszukiwaniu.}  
+
+_textdatesearch_ [l=pl] {Przeszukiwanie wedÅug dat}
+
+_texthelpdatesearch_ [l=pl] {Wyszukiwanie wedÅug dat umoÅŒliwia znalezienie dokumentÃ³w
+dotyczÄ
+cych zdarzeÅ z pewnego okresu.  MogÄ
+ to byÄ dokumenty 
+z jednego roku lub z przedziaÅu lat.  Wpisanie poszukiwanych wyraÅŒeÅ 
+nie jest konieczne. Wpisywanie dat rÃ³wnieÅŒ nie jest obowiÄ
+zkowe.<p>
+}
+
+_texthelpdatehowtotitle_ [l=pl] {SposÃ³b uÅŒycia:}
+_texthelpdatehowto_ [l=pl] {<ul>
+   <li>W celu wyszukania dokumentÃ³w dotyczÄ
+cych jednego roku:<p>
+   <ul>
+       B970<li>Wpisz poszukiwane wyraÅŒenia
+       <li>Wpisz rok w polu "Data poczÄ
+tkowa (lub jedyna data)"
+       <li>JeÅŒeli data naleÅŒy do okresu przed naszÄ
+ erÄ
+ (przed Chrystusem), 
+           w menu rozwijalnym obok tego pola zaznacz opcjÄ "p.n.e."
+       <li>Uruchom wyszukiwanie
+   </ul>
+<p><li>W celu wyszukania dokumentÃ³w dotyczÄ
+cych zakresu dat:<p>
+   <ul>
+       <li>Wpisz poszukiwane wyraÅŒenia
+       <li>W polu "Data poczÄ
+tkowa (lub jedyna data)" wpisz datÄ poczÄ
+tkowÄ
+
+       <li>W polu "Data koÅcowa" wpisz datÄ koÅcowÄ
+
+       <li>W meniu rozwijalnym zaznacz opcjÄ "p.n.e." obok tej daty lub dat, ktÃ³rych to dotyczy
+       <li>Uruchom wyszukiwanie
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=pl] {ReguÅy wyszukiwania}
+_texthelpdateresults_ [l=pl] {Wyszukiwanie dokumentÃ³w dotyczÄ
+cych roku 1903 oznacza wyszukiwanie dokumentÃ³w na temat roku 1903, a nie np. spisÃ³w literatury wydanych w 1903.  Wynik kwerendy moÅŒe zawieraÄ dokumenty dotyczÄ
+ce np. lat 1899-1911, poniewaÅŒ 1903 mieÅci siÄ w tym przedziale czasu oraz dokumenty z tytuÅem zawierajÄ
+cym wzmiankÄ o stuleciu, do ktÃ³rego naleÅŒy poszukiwany rok (np. 20 stulecie lub dwudziesty wiek).  Oznacza to, ÅŒe poszukiwane daty mogÄ
+ w ogÃ³le siÄ nie pojawiaÄ w dokumentach przedstawionych w wyniku kwerendy<p>
+}
+
+_textchangeprefs_ [l=pl] {Zmiana preferencji}
+
+_texthelppreferences_ [l=pl] {<p>Po klikniÄciu przycisku <i>_Global:linktextPREFERENCES_</i> u gÃ³ry strony, bÄdziesz mÃ³gÅ(-a) dostosowaÄ do swoich potrzeb niektÃ³re z elementÃ³w interfejsu.
+}  
+
+_texthelpcollectionprefstitle_ [l=pl] {Preferencje kolekcji}
+_texthelpcollectionprefs_ [l=pl] {NiektÃ³re kolekcje skÅadajÄ
+ siÄ z podzbiorÃ³w, ktÃ³re moÅŒna przeszukiwaÄ
+niezaleÅŒnie od siebie lub ÅÄ
+cznie, jak jednÄ
+ caÅoÅÄ.  Na stronie Preferencje moÅŒna
+wybraÄ podkolekcje, ktÃ³re majÄ
+ byÄ uwzglÄdnione podczas przeszukiwania.
+}
+
+_texthelplanguageprefstitle_ [l=pl] {Preferencje jÄzykowe}
+_texthelplanguageprefs_ [l=pl] {KaÅŒda kolekcja ma domyÅlny jÄzyk prezentacji, ale moÅŒna wÅÄ
+czyÄ inny jÄzyk.
+MoÅŒna takÅŒe zmieniÄ schemat kodowania znakÃ³w w bibliotece Greenstone, aby dostosowaÄ go
+do przeglÄ
+darki na swoim komputerze -- program wybiera wartoÅci domyÅlne,
+ktÃ³re zwykle dajÄ
+ dobre wyniki, ale w niektÃ³rych przeglÄ
+darkach lepiej jest wybraÄ
+inny schemat kodowania znakÃ³w. Wszystkie kolekcje umoÅŒliwiajÄ
+ zmianÄ domyÅlnego
+interfejsu graficznego na interfejs tekstowy. Jest to szczegÃ³lnie przydatne tym,
+ktÃ³rzy ze wzglÄdu na trudnoÅci wzrokowe uÅŒywajÄ
+ duÅŒych czcionek ekranowych
+lub syntezatorÃ³w mowy w celu prezentacji wynikÃ³w.
+}
+
+_texthelppresentationprefstitle_ [l=pl] {Preferencje prezentacji}
+_texthelppresentationprefs_ [l=pl] {W zaleÅŒnoÅci od kolekcji moÅŒna ustawiÄ kilka opcji w celu polepszenia wizualnej jakoÅci
+prezentacji.
+
+<p>W kolekcjach stron WWW moÅŒna wyÅÄ
+czyÄ pasek nawigacyjny u gÃ³ry kaÅŒdej strony
+dokumentu, dziÄki czemu po zakoÅczeniu wyszukiwania wyÅwietlana jest poszukiwana
+strona WWW bez nagÅÃ³wka biblioteki Greenstone.  Aby ponownie uruchomiÄ
+wyszukiwanie, naleÅŒy w oknie przeglÄ
+darki internetowej kliknÄ
+Ä przycisk Wstecz. 
+MoÅŒna takÅŒe wyÅÄ
+czyÄ komunikaty diagnostyczne biblioteki, klikajÄ
+c odsyÅacz
+strony internetowej ulokowanej poza bibliotekÄ
+.  W niektÃ³rych kolekcjach
+stron WWW moÅŒna wybraÄ, czy odsyÅacze na stronie Wyniki wyszukiwania
+majÄ
+ wskazywaÄ URL strony, czy jej kopiÄ przechowywanÄ
+ w bibliotece cyfrowej.
+}
+
+_texthelpsearchprefstitle_ [l=pl] {Preferencje wyszukiwania}
+_texthelpsearchprefs_ [l=pl] {<p>Rodzaj dopasowania podczas przeszukiwania tekstu moÅŒna wybraÄ za pomocÄ
+
+dwÃ³ch par przyciskÃ³w. Pierwsza para, WielkoÅÄ liter, okreÅla, czy dopasowanie
+ma uwzglÄdniaÄ wielkoÅÄ liter.  Druga, KoÅcÃ³wki sÅÃ³w, okreÅla, czy dopasowanie
+ma uwzglÄdniaÄ koÅcÃ³wki sÅÃ³w.  MoÅŒna takÅŒe wyszukiwaÄ za pomocÄ
+ duÅŒego
+okna kwerendy. DziÄki temu Åatwo jest wyszukaÄ tekst wielkoÅci caÅego akapitu.
+Czas przeszukiwania nawet znacznych iloÅci tekstu jest krÃ³tki.
+
+<p>Na przykÅad, jeÅŒeli wybrano przyciski <i>Nie uwzglÄdniaj wielkoÅci liter</i> i
+<i>Nie uwzglÄdniaj koÅcÃ³wek sÅÃ³w</i>, kwerenda<p>
+    <ul><kbd>African building</kbd></ul>
+      <p>bÄdzie rÃ³wnowaÅŒna kwerendzie<p>
+      <ul><kbd>africa builds</kbd></ul><p>
+      poniewaÅŒ wielka litera w wyrazie "African" bÄdzie zmieniona w maÅÄ
+,
+      a w wyrazach "African" i "building" zostanÄ
+ usuniÄte przyrostki "n" i "ing".
+      W sÅowie "builds" usuniÄta zostanie litera "s".
+
+<p>Zaawansowany tryb kwerendy umoÅŒliwia modyfikowanie wyraÅŒeÅ za pomocÄ
+
+koniunkcji AND (&), alternatywy OR (|), i zaprzeczenia NOT (!). MoÅŒna takÅŒe wÅÄ
+czyÄ 
+opcjÄ Historia wyszukiwania, ktÃ³ra pokazuje kilka ostatnich kwerend.
+UÅatwia to wykonywanie kwerend bÄdÄ
+cych niewielkÄ
+ modyfikacjÄ
+ wczeÅniejszych
+wyszukiwaÅ. UstawiÄ moÅŒna rÃ³wnieÅŒ maksymalnÄ
+ liczbÄ trafieÅ oraz liczbÄ trafieÅ
+prezentowanych jednorazowo w oknie.
+}
+
+_textcasefoldprefs_ [l=pl] {Ta para przyciskÃ³w decyduje, czy przy wyszukiwaniu powinna byÄ rozrÃ³ÅŒniana wielkoÅÄ liter. PrzykÅadowo, jeÅli zostanie wybrane "_preferences:textignorecase_", to zwrot <i>uprawa marchewek</i> bÄdzie traktowany tak samo jak <i>Uprawa Marchewek</i> oraz <i>UPRAWA MARCHEWEK</i>.}  
+_textstemprefs_ [l=pl] {Para przyciskÃ³w pozwalajÄ
+cych na wybÃ³r czy naleÅŒy ignorowaÄ koÅcÃ³wki sÅÃ³w przy wyszukiwaniu. Na przykÅad, jeÅli zaznaczysz "_preferences:textstem_", to zwrot <i>uprawa marchewek</i> bÄdzie traktowany tak samo jak <i>uprawy marchewek</i> i <i>uprawa marchewki</i>. Obecnie jednak dziaÅa to w peÅni poprawnie tylko w jÄzyku angielskim. _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=pl] {Ta para przyciskÃ³w umoÅŒliwia wybÃ³r, czy litery z akcentem i bez powinny byÄ rozrÃ³ÅŒniane przy wyszukiwaniu. PrzykÅadowo, jeÅli zostanie wybrane "_preferences:textignoreaccents_", to przy wyszukiwaniu sÅÃ³wko <i>fÃ©dÃ©ration</i> bÄdzie traktowane tak samo jak <i>fedÃ©ration</i> oraz <i>federation</i>.}  
+ 
+_textstemoptionsprefs_ [l=pl] {Czasem lepiej i wygodniej jest uÅŒyÄ funkcji do skracania wyszukiwanych pojÄÄ, ktÃ³ra zostaÅa opisana wyÅŒej w "_texthelpquerytermstitle_".}  
+
+_textsearchtypeprefsplain_ [l=pl] {Istnieje moÅŒliwoÅÄ uzyskania duÅŒego pola dla zapytaÅ, tak aby moÅŒna byÅo Åatwiej wyszukiwaÄ dÅuÅŒsze fragmenty. Wyszukiwanie dÅugich fragmentÃ³w tekstu jest zaskakujÄ
+co proste.}  
+
+_textsearchtypeprefsform_ [l=pl] {MoÅŒesz zmieniaÄ liczbÄ pÃ³l wyÅwietlanych w formularzu wyszukiwania.}  
+
+_textsearchtypeprefsboth_ [l=pl] {MoÅŒesz przeÅÄ
+czyÄ sposÃ³b przeszukiwania kolekcji miÄdzy "normalnym" wyszukiwaniem, a wyszukiwaniem "w polach"
+<ul>
+<li>Przy normalnym wyszukiwaniu dostÄpne jest tylko jedno okienko wyszukiwania.  _textsearchtypeprefsplain_</li>
+<li>Wyszukiwanie w wielu polach pozwala na przeszukiwaniu wielu pÃ³l naraz, dziÄki obecnoÅci wielu okienek, w ktÃ³rych moÅŒna wpisywaÄ zapytanie _textsearchtypeprefsform_</li>
+</ul>
+}  
+
+
+
+_texttanumbrowseoptions_ [l=pl] {Jest _numbrowseoptions_ sposobÃ³w wyszukiwania informacji w tej kolekcji:}
+
+_textsimplehelpheading_ [l=pl] {Jak znaleÅºÄ informacje w kolekcji _collectionname_}
+
+_texthelpscopetitle_ [l=pl] {Zakres kwerendy}
+_texthelpscope_ [l=pl] {<p>
+W wiÄkszoÅci kolekcji moÅŒna wybraÄ rÃ³ÅŒne indeksy przeszukiwania, na przykÅad
+spis autorÃ³w lub tytuÅÃ³w. DostÄpne mogÄ
+ byÄ rÃ³wnieÅŒ indeksy dotyczÄ
+ce rozdziaÅÃ³w
+lub akapitÃ³w. Zwykle zwracany jest peÅny dokument, niezaleÅŒnie od rodzaju przeszukiwanego indeksu.
+<p>KsiÄ
+ÅŒki sÄ
+ otwierane automatycznie w miejscu wÅaÅciwym dla wykonanej kwerendy.
+}
Index: /gsdl/stable/macros/port-br.dm
===================================================================
--- /gsdl/stable/macros/port-br.dm	(revision 20131)
+++ /gsdl/stable/macros/port-br.dm	(revision 20131)
@@ -0,0 +1,703 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Portuguese (Brasil) Language text and icon macros 
+# Updated by Claudia Wanderley and Nadia PK in March 2009
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=pt-br] {PeriÃ³dicos}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=pt-br] {ref. fonte}  
+_textdate_ [l=pt-br] {data de publicaÃ§Ã£o:}  
+_textnumpages_ [l=pt-br] {n. de pÃ¡ginas}  
+
+_textsignin_ [l=pt-br] {entrar}  
+
+_textdefaultcontent_ [l=pt-br] {A pÃ¡gina requerida nÃ£o pode ser encontrada. Por favor,  use o botÃ£o 'voltar' do seu navegador ou o botÃ£o 'pÃ¡gina principal' para retornar para a Biblioteca Digital Greenstone.}  
+
+_textdefaulttitle_ [l=pt-br] {Erro GSDL}  
+
+_textbadcollection_ [l=pt-br] {Esta ColeÃ§Ã£o (chamada "_cvariable_") nÃ£o estÃ¡ instalada neste sistema da biblioteca digital Greenstone .}  
+
+_textselectpage_ [l=pt-br] {-- Selecionar PÃ¡gina --}  
+
+_collectionextra_ [l=pt-br] {Esta coleÃ§Ã£o contÃ©m _about:numdocs_ documento(s). 
+Ãltima alteraÃ§Ã£o foi feita hÃ¡ _about:builddate_ dia(s) atrÃ¡s.}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=pt-br] {<p>Esta coleÃ§Ã£o contÃ©m _numdocs_ _If_("_numdocs_" eq "1",document,documents), um total de _numbytes_ de textos e metadados indexados.
+<p><a href="_httppagex_(bsummary)">Clique aqui</a> para ver o sumÃ¡rio construÃ­do para esta coleÃ§Ã£o.
+}  
+
+_textdescrcollection_ [l=pt-br] {}  
+_textdescrabout_ [l=pt-br] {Sobre a pÃ¡gina}  
+_textdescrhome_ [l=pt-br] {PÃ¡gina Principal}  
+_textdescrhelp_ [l=pt-br] {PÃ¡gina de Ajuda}  
+_textdescrpref_ [l=pt-br] {PÃ¡gina de PreferÃªncias}  
+_textdescrgreenstone_ [l=pt-br] {Software da Biblioteca Digital Greenstone}  
+_textdescrusab_ [l=pt-br] {O que vocÃª achou difÃ­cil de usar?}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=pt-br] {Busca}  
+_labelSearch_ [l=pt-br] {Busca}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=pt-br] {TÃ­tulo}  
+_labelTitle_ [l=pt-br] {TÃ­tulos}  
+_textCreator_ [l=pt-br] {Criador}  
+_labelCreator_ [l=pt-br] {Criadores}  
+_textSubject_ [l=pt-br] {Assunto}  
+_labelSubject_ [l=pt-br] {Assuntos}  
+_textDescription_ [l=pt-br] {DescriÃ§Ã£o}  
+_labelDescription_ [l=pt-br] {DescriÃ§Ãµes}  
+_textPublisher_ [l=pt-br] {Editor}  
+_labelPublisher_ [l=pt-br] {Editores}  
+_textContributor_ [l=pt-br] {ContribuiÃ§Ã£o}  
+_labelContributor_ [l=pt-br] {Contribuidores}  
+_textDate_ [l=pt-br] {Data}  
+_labelDate_ [l=pt-br] {Datas}  
+_textType_ [l=pt-br] {Tipo}  
+_labelType_ [l=pt-br] {Tipos}  
+_textFormat_ [l=pt-br] {Formato}  
+_labelFormat_ [l=pt-br] {Formatos}  
+_textIdentifier_ [l=pt-br] {Identificador}  
+_labelIdentifier_ [l=pt-br] {Identificadores}  
+_textSource_ [l=pt-br] {Nome do Arquivo}  
+_labelSource_ [l=pt-br] {Nomes dos arquivos}  
+_textLanguage_ [l=pt-br] {Linguagem}  
+_labelLanguage_ [l=pt-br] {LÃ­nguas}  
+_textRelation_ [l=pt-br] {RelaÃ§Ã£o}  
+_labelRelation_ [l=pt-br] {RelaÃ§Ãµes}  
+_textCoverage_ [l=pt-br] {Cobertura}  
+_labelCoverage_ [l=pt-br] {Cobertura}  
+_textRights_ [l=pt-br] {Direitos}  
+_labelRights_ [l=pt-br] {Direitos}  
+
+# DLS metadata set
+_textOrganization_ [l=pt-br] {OrganizaÃ§Ã£o}  
+_labelOrganization_ [l=pt-br] {OrganizaÃ§Ãµes}  
+_textKeyword_ [l=pt-br] {Palavra Chave}  
+_labelKeyword_ [l=pt-br] {Palavras Chave}  
+_textHowto_ [l=pt-br] {Como fazer}  
+_labelHowto_ [l=pt-br] {Como fazer}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=pt-br] {Frase}  
+_labelPhrase_ [l=pt-br] {Frases}  
+_textCollage_ [l=pt-br] {Colagem}  
+_labelCollage_ [l=pt-br] {Colagem}  
+_textBrowse_ [l=pt-br] {Navegar}  
+_labelBrowse_ [l=pt-br] {Navegar}  
+_textTo_ [l=pt-br] {Para}  
+_labelTo_ [l=pt-br] {Para}  
+_textFrom_ [l=pt-br] {De}  
+_labelFrom_ [l=pt-br] {De}  
+_textAcronym_ [l=pt-br] {AcrÃŽnimo}  
+_labelAcronym_ [l=pt-br] {AcrÃŽnimos}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=pt-br] {Navegar por _1_}  
+
+_textdescrSearch_ [l=pt-br] {Buscar por termos especÃ­ficos}  
+_textdescrType_ [l=pt-br] {Navegar pelo tipo de fonte}  
+_textdescrIdentifier_ [l=pt-br] {Navegar pelo identficador de fonte}  
+_textdescrSource_ [l=pt-br] {Navegar pelo nome original do arquivo}  
+_textdescrTo_ [l=pt-br] {Navegar pelo campo Para}  
+_textdescrFrom_ [l=pt-br] {Navegar pelo campo De}  
+_textdescrCollage_ [l=pt-br] {Navegar pelas colagens de imagem}  
+_textdescrAcronym_ [l=pt-br] {Navegar pelos acrÃŽnimos}  
+_textdescrPhrase_ [l=pt-br] {Navegar pelas frases}  
+_textdescrHowto_ [l=pt-br] {Navegar pelas categorias como fazer }  
+_textdescrBrowse_ [l=pt-br] {Navegar pelos documentos}  
+_texticontext_ [l=pt-br] {Ver o documento}  
+_texticonclosedbook_ [l=pt-br] {abrir este documento e ver o conteÃºdo}  
+_texticonnext_ [l=pt-br] {para a prÃ³xima seÃ§Ã£o}  
+_texticonprev_ [l=pt-br] {para a seÃ§Ã£o anterior}  
+
+_texticonworld_ [l=pt-br] {Ver o documento web}  
+
+_texticonmidi_ [l=pt-br] {Ver o documento MIDI}  
+_texticonmsword_ [l=pt-br] {Ver o documento do Microsoft Word}  
+_texticonmp3_ [l=pt-br] {Ver o documento MP3}  
+_texticonpdf_ [l=pt-br] {Ver o documento PDF}  
+_texticonps_ [l=pt-br] {Ver o documento Postscript}  
+_texticonppt_ [l=pt-br] {Ver o documento Power Point}  
+_texticonrtf_ [l=pt-br] {Ver o documento RTF}  
+_texticonxls_ [l=pt-br] {Ver o documento Microsoft Excel}  
+
+_page_ [l=pt-br] {pÃ¡gina }  
+_pages_ [l=pt-br] {pÃ¡ginas}  
+_of_ [l=pt-br] {de }  
+_vol_ [l=pt-br] {Volume}  
+_num_ [l=pt-br] {No.}  
+
+_textmonth00_ [l=pt-br] {}  
+_textmonth01_ [l=pt-br] {Janeiro}  
+_textmonth02_ [l=pt-br] {Fevereiro}  
+_textmonth03_ [l=pt-br] {MarÃ§o}  
+_textmonth04_ [l=pt-br] {Abril}  
+_textmonth05_ [l=pt-br] {Maio}  
+_textmonth06_ [l=pt-br] {Junho}  
+_textmonth07_ [l=pt-br] {Julho}  
+_textmonth08_ [l=pt-br] {Agosto}  
+_textmonth09_ [l=pt-br] {Setembro}  
+_textmonth10_ [l=pt-br] {Outubro}  
+_textmonth11_ [l=pt-br] {Novembro}  
+_textmonth12_ [l=pt-br] {Dezembro}  
+
+_textdocument_ [l=pt-br] {Documento}  
+_textsection_ [l=pt-br] {SeÃ§Ã£o}  
+_textparagraph_ [l=pt-br] {ParÃ¡grafo}  
+_textchapter_ [l=pt-br] {CapÃ­tulo}
+_textbook_ [l=pt-br] {Livro}
+
+_magazines_ [l=pt-br] {Revistas}  
+
+_nzdlpagefooter_ [l=pt-br] {<div class="divbar">Â </div>
+<p><a href="_gwcgi_">Projeto Biblioteca Digital da Nova ZelÃ¢ndia</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Departamento de CiÃªncias da ComputaÃ§Ã£o</a>, 
+<a href="http://www.waikato.ac.nz">Universidade de Waikato</a>, 
+Nova ZelÃ¢ndia}  
+
+_linktextHOME_ [l=pt-br] {PRINCIPAL}  
+_linktextHELP_ [l=pt-br] {AJUDA}  
+_linktextPREFERENCES_ [l=pt-br] {PREFERÃNCIAS}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=pt-br] {Biblioteca Digital Greenstone}  
+
+_textnocollections_ [l=pt-br] {NÃ£o hÃ¡ coleÃ§Ãµes vÃ¡lidas  (i.e. construÃ­das e pÃºblicas) disponÃ­veis}  
+
+_textadmin_ [l=pt-br] {PÃ¡gina do Administrador}  
+_textabgs_ [l=pt-br] {Sobre o Greenstone}  
+_textgsdocs_ [l=pt-br] {DocumentaÃ§Ã£o do Greenstone}  
+
+_textdescradmin_ [l=pt-br] {Permite que vocÃª adicione novos usuÃ¡rios, sumarize as coleÃ§Ãµes no sistema, e dÃ¡ informaÃ§Ã£o tÃ©cnica sobre a instalaÃ§Ã£o do Greenstone}  
+
+_textdescrgogreenstone_ [l=pt-br] {Conta para vocÃª fatos sobre o software Greenstone e sobre o Projeto da Biblioteca Digital da Nova ZelÃ¢ndia onde ele se originou.}  
+
+_textdescrgodocs_ [l=pt-br] {Manuais do Greenstone}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=pt-br] {A Interface da Biblioteca}  
+_textdescrgli_ [l=pt-br] {Ajuda vocÃª a criar novas coleÃ§Ãµes, a modificar ou a adicionar Ã s existentes, ou a apagar coleÃ§Ãµes}  
+
+package collector
+
+_textcollector_ [l=pt-br] {O Coletor}  
+_textdescrcollector_ [l=pt-br] {Isso Ã© anterior Ã  Interface da Biblioteca, e por propÃ³sitos prÃ¡ticos a Interface da Biblioteca deveria ser usada em seu lugar}  
+
+package depositor
+
+_textdepositor_ [l=pt-br] {O Depositor}  
+_textdescrdepositor_ [l=pt-br] {Ajuda vocÃª a adicionar documentos Ã s coleÃ§Ãµes existentes}  
+
+package gti
+
+_textgti_ [l=pt-br] {A Interface do Tradutor Greenstone}  
+_textdescrtranslator_ [l=pt-br] {Ajuda a manter as versÃµes multilingues da interface Greenstone atualizadas}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=pt-br] {Sobre esta coleÃ§Ã£o}  
+
+_textsubcols1_ [l=pt-br] {<p>A coleÃ§Ã£o completa contem _1_ subcoleÃ§Ãµes. As que estÃ£o atualmente disponÃ­veis sÃ£o:
+<blockquote>}  
+
+_textsubcols2_ [l=pt-br] {</blockquote>
+VocÃª pode checar (e alterar) quais subcoleÃ§Ãµes vocÃª estÃ¡ atualmente utlizando, na pÃ¡gina de PreferÃªncias.}  
+
+_titleabout_ [l=pt-br] {sobre}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=pt-br] {fechar esta seÃ§Ã£o da biblioteca}  
+_texticonclosedbookshelf_ [l=pt-br] {abrir esta seÃ§Ã£o da biblioteca e ver o conteÃºdo}  
+_texticonopenbook_ [l=pt-br] {fechar este livro}  
+_texticonclosedfolder_ [l=pt-br] {abrir esta pasta e ver o conteÃºdo}  
+_texticonclosedfolder2_ [l=pt-br] {abrir subseÃ§Ã£o: }  
+_texticonopenfolder_ [l=pt-br] {fechar esta pasta}  
+_texticonopenfolder2_ [l=pt-br] {fechar a subseÃ§Ã£o: }  
+_texticonsmalltext_ [l=pt-br] {Ver esta seÃ§Ã£o de texto}  
+_texticonsmalltext2_ [l=pt-br] {ver texto: }  
+_texticonpointer_ [l=pt-br] {seÃ§Ã£o atual}  
+_texticondetach_ [l=pt-br] {Abrir esta pÃ¡gina numa nova janela}  
+_texticonhighlight_ [l=pt-br] {Destacar termos buscados}  
+_texticonnohighlight_ [l=pt-br] {NÃ£o destacar termos buscados}  
+_texticoncontracttoc_ [l=pt-br] {Reduzir tabela de conteÃºdo}  
+_texticonexpandtoc_ [l=pt-br] {Ampliar a tabela de conteÃºdo}  
+_texticonexpandtext_ [l=pt-br] {Exibir todo o texto}  
+_texticoncontracttext_ [l=pt-br] {Exibir texto somente das seÃ§Ãµes selecionadas}  
+_texticonwarning_ [l=pt-br] {<b>Aviso: </b>}  
+_texticoncont_ [l=pt-br] {continuar?}  
+
+_textltwarning_ [l=pt-br] {<div class="buttons">_imagecont_</div>  _iconwarning_Expandir o texto aqui gerarÃ¡ uma grande quantidade de dados para o seu navegador exibir  }  
+
+_textgoto_ [l=pt-br] {ir para a pÃ¡gina}  
+_textintro_ [l=pt-br] {<i>(texto introdutÃ³rio)</i>}  
+
+_textCONTINUE_ [l=pt-br] {CONTINUAR?}  
+
+_textEXPANDTEXT_ [l=pt-br] {EXPANDIR TEXTO}  
+
+_textCONTRACTCONTENTS_ [l=pt-br] {REDUZIR CONTEÃDO}  
+
+_textDETACH_ [l=pt-br] {SEPARAR}  
+
+_textEXPANDCONTENTS_ [l=pt-br] {EXPANDIR CONTEÃºDOS}  
+
+_textCONTRACT_ [l=pt-br] {REDUZIR TEXTO}  
+
+_textHIGHLIGHT_ [l=pt-br] {DESTACAR}  
+
+_textNOHIGHLIGHT_ [l=pt-br] {NÃ£O DESTACAR}  
+
+_textPRINT_ [l=pt-br] {IMPRIMIR}  
+
+_textnextsearchresult_ [l=pt-br] {prÃ³ximo resultado de busca}  
+_textprevsearchresult_ [l=pt-br] {resultado de busca anterior}  
+
+# macros for printing page
+_textreturnoriginal_ [l=pt-br] {Retornar Ã  pÃ¡gina original}  
+_textprintpage_ [l=pt-br] {Imprimir esta pÃ¡gina}  
+_textshowcontents_ [l=pt-br] {Mostre o conteÃºdo das tabelas}  
+_texthidecontents_ [l=pt-br] {Esconder a tabela de conteÃºdos}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=pt-br] {_If_(_thislast_,resultados _thisfirst_ - _thislast_ para a consulta: _cgiargq_,Nenhuma combinaÃ§Ã£o encontrada para a consulta: _cgiargq_)}  
+_textnoquerytitle_ [l=pt-br] {PÃ¡gina de busca}  
+
+_textsome_ [l=pt-br] {algumas}  
+_textall_ [l=pt-br] {todos}  
+_textboolean_ [l=pt-br] {booleana}  
+_textranked_ [l=pt-br] {por ranking}  
+_textnatural_ [l=pt-br] {natural}  
+_textsortbyrank_ [l=pt-br] {ranque por relevÃ¢ncia}  
+_texticonsearchhistorybar_ [l=pt-br] {HistÃ³rico de busca:}  
+
+_textifeellucky_ [l=pt-br] {Estou me sentindo com sorte!}  
+
+#alt text for query buttons
+_textusequery_ [l=pt-br] {utilize esta consulta}  
+_textfreqmsg1_ [l=pt-br] {Contar Palavras:}  
+_textpostprocess_ [l=pt-br] {_If_(_quotedquery_,<br><i>encontrar pÃ³s-processadas _quotedquery_</i>)}  
+_textinvalidquery_ [l=pt-br] {sintaxe de consulta invÃ¡lida}  
+_textstopwordsmsg_ [l=pt-br] {As palavras seguintes sÃ£o muito comuns e foram ignoradas:}  
+_textlucenetoomanyclauses_ [l=pt-br] {Sua consulta continha termos de busca demais; por fevor tente uma consulta mais especÃ­fica}  
+
+_textmorethan_ [l=pt-br] {Mais que }  
+_textapprox_ [l=pt-br] {Sobre }  
+_textnodocs_ [l=pt-br] {Nenhum documento combinou com a consulta.}  
+_text1doc_ [l=pt-br] {1 documento correspondeu Ã  consulta}  
+_textlotsdocs_ [l=pt-br] {documentos encontrados para esta consulta.}  
+_textmatches_ [l=pt-br] {CombinaÃ§Ãµes}  
+_textbeginsearch_ [l=pt-br] {ComeÃ§ar a busca}  
+_textrunquery_ [l=pt-br] {Fazer Consulta}  
+_textclearform_ [l=pt-br] {Limpar formulÃ¡rio}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=pt-br] {Palavras
+}  
+_textinfield_ [l=pt-br] {... no campo}  
+_textfoldstem_ [l=pt-br] {(fold, stem)}  
+
+_textadvquery_ [l=pt-br] {Ou digite uma consulta diretamente:}  
+_textallfields_ [l=pt-br] {todos os campos}  
+_texttextonly_ [l=pt-br] {apenas texto}  
+_textand_ [l=pt-br] {e}  
+_textor_ [l=pt-br] {ou}  
+_textandnot_ [l=pt-br] {e nÃ£o}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=pt-br] {Buscar por _indexselection_ _If_(_jselection_, associado com _jselection_)_If_(_gselection_, no nÃ­vel _gselection_)_If_(_nselection_, no idioma_nselection_) _If_(_sfselection_,\,_allowformbreak_ organizando os resultados por _sfselection_) para _querytypeselection_ das palavras}  
+
+_textadvancedsearch_ [l=pt-br] {Buscar em _indexselection_ _If_(_jselection_, associado com _jselection_)_If_(_gselection_, em nÃ­vel _gselection_ )_If_(_nselection_, no idioma _nselection_ ) usando a consulta _querytypeselection_}  
+
+_textadvancedmgppsearch_ [l=pt-br] {Buscar em _indexselection_ _If_(_jselection_,associado com _jselection_ )_If_(_gselection_,em nÃ­vel _gselection_ )_If_(_nselection_,em idioma _nselection_ ), e mostre os resultados em ordem de _formquerytypeadvancedselection_, para}  
+
+_textadvancedlucenesearch_ [l=pt-br] {Buscar em _indexselection__if_(_jselection_, associado com _jselection_)_If_(_gselection_, em nÃ­vel _gselection_ )_If_(_nselection_, no idioma _nselection_)_If_(_sfselection_,\,_allowformbreak_ organizando os resultados por _sfselection_\,) para }  
+
+_textformsimplesearch_ [l=pt-br] {Buscar em _If_(_jselection_, em _jselection_)_If_(_gformselection_, em nÃ­vel _gformselection_  )_If_(_nselection_, em idioma _nselection_)_If_(_sfselection_,\, organizando os resultados por _sfselection_\,) para _formquerytypesimpleselection_ de}  
+
+_textformadvancedsearchmgpp_ [l=pt-br] {Buscar em _If_(_jselection_, em _jselection_ )_If_(_gformselection_, em nÃ­vel _gformselection_  )_If_(_nselection_, no idioma _nselection_) e mostrar resultados na ordem _formquerytypeadvancedselection_, para :}  
+
+_textformadvancedsearchlucene_ [l=pt-br] {Buscar em _If_(_jselection_, em _jselection_)_If_(_gformselection_,  no nÃ­vel _gformselection_ )_If_(_nselection_, no idioma _nselection_)_If_(_sfselection_,\, organizando os resultados por _sfselection_\,) para}  
+
+_textnojsformwarning_ [l=pt-br] {Aviso: Javascript estÃ¡ desativado em seu navegador. <br>Para utilizar busca por formas, por favor ative o Javascript.}  
+_textdatesearch_ [l=pt-br] {Nesta coleÃ§Ã£o Ã© possÃ­vel buscar por documentos dentro de um perÃ­odo de datas, ou documentos que contÃ©m uma data particular. Isto Ã© uma recurso opcional da busca.}  
+_textstartdate_ [l=pt-br] {Data de InÃ­cio (ou apenas):}  
+_textenddate_ [l=pt-br] {Data final:}  
+_textbc_ [l=pt-br] {B.C.E.}  
+_textad_ [l=pt-br] {C.E.}  
+_textexplaineras_ [l=pt-br] {C.E. e B.C.E sÃ£o alternativas para A.C. E D.C.  respectivamente. Estes termos sÃ£o considerados nÃ£o discriminantes para as culturas, e se traduzem como âEra Comumâ ou "Common Era" e âAntes da era Comumâ ou "Before the Common Era".}  
+
+_textstemon_ [l=pt-br] {(ignorar final das palavras)}  
+
+_textsearchhistory_ [l=pt-br] {Buscar Historico}  
+
+#text macros for search history
+_textnohistory_ [l=pt-br] {NÃ£o hÃ¡ registro no histÃ³rico de busca}  
+_texthresult_ [l=pt-br] {resultado}  
+_texthresults_ [l=pt-br] {resultados}  
+_texthallwords_ [l=pt-br] {todas as palavras}  
+_texthsomewords_ [l=pt-br] {algumas palavras}  
+_texthboolean_ [l=pt-br] {booleana}  
+_texthranked_ [l=pt-br] {por ranking}  
+_texthcaseon_ [l=pt-br] {MaiÃºsculas e minÃºsculas precisam corresponder}  
+_texthcaseoff_ [l=pt-br] {Passar para caixa alta}  
+_texthstemon_ [l=pt-br] {derivado}  
+_texthstemoff_ [l=pt-br] {nÃ£o derivado}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=pt-br] {PreferÃªncias foram configuradas da seguinte forma.  NÃ£o utilize o botÃ£o âvoltarâ do seu navegador â isso vai descofigurÃ¡-las. Em vez disso, clique em um dos botÃµes na barra de acesso acima. }  
+_textsetprefs_ [l=pt-br] {configurar preferÃªncias}  
+_textsearchprefs_ [l=pt-br] {PreferÃªncias de busca}  
+_textcollectionprefs_ [l=pt-br] {PreferÃªncias da coleÃ§Ã£o}  
+_textpresentationprefs_ [l=pt-br] {PreferÃªncias da apresentaÃ§Ã£o}  
+_textpreferences_ [l=pt-br] {PreferÃªncias}  
+_textcasediffs_ [l=pt-br] {DiferenÃ§as de Caixa (alta, baixa):}  
+_textignorecase_ [l=pt-br] {ignorar diferenÃ§as entre maiÃºsculas/minÃºsculas}  
+_textmatchcase_ [l=pt-br] {maiÃºsculas/minÃºsculas devem corresponder}  
+_textwordends_ [l=pt-br] {Finais das palavras:}  
+_textstem_ [l=pt-br] {ignorar terminaÃ§Ãµes das palavras}  
+_textnostem_ [l=pt-br] {a palavra inteira deve corresponder}  
+_textaccentdiffs_ [l=pt-br] {DiferenÃ§as de acento:}  
+_textignoreaccents_ [l=pt-br] {ignorar acentos}  
+_textmatchaccents_ [l=pt-br] {acentos precisam corresponder}  
+
+_textprefop_ [l=pt-br] {Retornar _maxdocoption_ hits com _hitsperpageoption_ hits por pÃ¡gina.}  
+_textextlink_ [l=pt-br] {Acesso a PÃ¡ginas Web externas: }  
+_textintlink_ [l=pt-br] {Origem dos documentos recebidos de:}  
+_textlanguage_ [l=pt-br] {Idioma da Interface: }  
+_textencoding_ [l=pt-br] {CÃ³digo: }  
+_textformat_ [l=pt-br] {Formato da Interface: }  
+_textall_ [l=pt-br] {todos}  
+_textquerymode_ [l=pt-br] {Modo de consulta:}  
+_textsimplemode_ [l=pt-br] {modo de consulta simples}  
+_textadvancedmode_ [l=pt-br] {modo de consulta avanÃ§ado (permite buscas booleanas usando !, &, |, e parÃªnteses)}  
+_textlinkinterm_ [l=pt-br] {direto para a pÃ¡gina intermediÃ¡ria}  
+_textlinkdirect_ [l=pt-br] {ir diretamente para lÃ¡}  
+_textdigitlib_ [l=pt-br] {a biblioteca digital}  
+_textweb_ [l=pt-br] {a web}  
+_textgraphical_ [l=pt-br] {GrÃ¡fico}  
+_texttextual_ [l=pt-br] {Textual}  
+_textcollectionoption_ [l=pt-br] {<p>
+SubcoleÃ§Ãµes para incluir:
+<br>}  
+
+_textsearchtype_ [l=pt-br] {Estilo de consulta:}  
+_textformsearchtype_ [l=pt-br] {Por campo com _formnumfieldoption_ campos}  
+_textplainsearchtype_ [l=pt-br] {normal com caixa de consulta  _boxsizeoption_}  
+_textregularbox_ [l=pt-br] {linha simples}  
+_textlargebox_ [l=pt-br] {grande}  
+
+_textrelateddocdisplay_ [l=pt-br] {mostrar documentos relacionados}  
+_textsearchhistory_ [l=pt-br] {HistÃ³rico de busca:}  
+_textnohistory_ [l=pt-br] {NÃ£o hÃ¡ histÃ³rico de busca.}  
+_texthistorydisplay_ [l=pt-br] {mostrar _historynumrecords_ dados do histÃ³rico das buscas}  
+_textnohistorydisplay_ [l=pt-br] {nÃ£o mostrar histÃ³rico de buscas}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=pt-br] {Organizar documentos por}  
+_textalsoshowing_ [l=pt-br] {tambÃ©m mostrando}  
+_textwith_ [l=pt-br] {com no mÃ¡ximo}  
+_textdocsperpage_ [l=pt-br] {documentos por pÃ¡gina}  
+
+_textfilterby_ [l=pt-br] {Achar documentos contendo}  
+_textall_ [l=pt-br] {tudo}  
+_textany_ [l=pt-br] {qualquer}  
+_textwords_ [l=pt-br] {das palavras}  
+_textleaveblank_ [l=pt-br] {deixar esta caixa de diÃ¡logo vazia para achar todos os documentos}  
+
+_browsebuttontext_ [l=pt-br] {âOrganizar Documentosâ}  
+
+_nodata_ [l=pt-br] {<i>nenhum dado</i>}  
+_docs_ [l=pt-br] {documentos}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=pt-br] {Ajuda}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=pt-br] {navegar pelos documentos por _1_ clicando no botÃ£o _2_ }  
+
+_textSearchhelp_ [l=pt-br] {buscar por palavras particulares que aparecem no texto clicando o botÃ£o _labelSearch_ }  
+_textTohelp_ [l=pt-br] {navegar por documentos pelo campo Para clicando o botÃ£o _labelTo_}  
+_textFromhelp_ [l=pt-br] {navegar por documentos pelo campo De clicando o botÃ£o _labelFrom_ }  
+_textBrowsehelp_ [l=pt-br] {navegar pelos documentos}  
+_textAcronymhelp_ [l=pt-br] {navegar pelos documentos por ocorrÃªncia de acrÃŽnimos clicando o  botÃ£o _labelAcronym_}  
+_textPhrasehelp_ [l=pt-br] {navegar por frases em documentos clicando o botÃ£o _labelPhrase_ . Isto usa do navegador de frases phind.}  
+
+_texthelptopicstitle_ [l=pt-br] {TÃ³picos}  
+
+_textreadingdocs_ [l=pt-br] {Como ler os documentos}  
+
+_texthelpreadingdocs_ [l=pt-br] {<p>VocÃª pode saber quando vocÃª chegou a um livro ou documento particular por que o seu tÃ­tulo, ou uma imagem da capa, aparece no topo esquerdo da pÃ¡gina. Em algumas coleÃ§Ãµes, aparece uma tabela de conteÃºdo- um Ã­ndice, enquanto em outras (i.e. Quando a opÃ§Ã£o de imagem paginada Ã© utilizada) apenas Ã© mostrado o nÃºmero da pÃ¡gina, junto com uma caixa que permite que vocÃª selecione uma nova pÃ¡gina e vÃ¡ para frente e para trÃ¡s na leitura. Na tabela de conteÃºdos, o cabeÃ§alho da seÃ§Ã£o corrente estÃ¡ em negrito, e a tabela Ã© expandÃ­vel â clique nos folders para abrÃ­-los ou fechÃ¡-los; clique no livro aberto no topo para fechÃ¡-lo. </p>
+
+<p>Sob ele estÃ¡ o texto da seÃ§Ã£o atual. Quando vocÃª tiver lido tudo, hÃ¡ setas no final para levar vocÃª para a prÃ³xima seÃ§Ã£o ou de volta para a seÃ§Ã£o anterior.</p>
+
+<p>Abaixo do tÃ­tulo ou da imagem da capa hÃ¡ alguns botÃµes. Clique em <i>_document:textEXPANDIRTEXTO_</i> para ampliar todo o texto do documento atual. Se o documento for grande, isto poderÃ¡ levar muito tempo e usar muita memÃ³ria! Clique em <i>_document:textEXPANDIRCONTEÃDO_</i> para expandir toda a tabela de conteÃºdo de forma que vocÃª possa ver todos os tÃ­tulos de todos os capÃ­tulos e subseÃ§Ãµes. Clique em <i>_document:textDESTACAR_</i> para abrir uma nova janela do navegador para este documento. (Isto Ã© Ãºtil se vocÃª quiser comparar documentos, ou ler dois ao mesmo tempo.)  Finalmente, quando vocÃª fizer uma busca por palavras as palavras de sua busca sÃ£o destacadas.  Clique em  <i>_document:textNÃO DESTACAR_</i>  para retirar os destaques.
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=pt-br] {Abrir esta estante de livros}  
+_texthelpopenbook_ [l=pt-br] {Abrir/fechar este livro}  
+_texthelpviewtextsection_ [l=pt-br] {Ver esta seÃ§Ã£o do texto}  
+_texthelpexpandtext_ [l=pt-br] {Exibir todo texto, ou nÃ£o}  
+_texthelpexpandcontents_ [l=pt-br] {Expandir a tabela de conteÃºdos, ou nÃ£o}  
+_texthelpdetachpage_ [l=pt-br] {Abrir esta pÃ¡gina em uma nova janela}  
+_texthelphighlight_ [l=pt-br] {Destacar termos de busca, ou nÃ£o}  
+_texthelpsectionarrows_ [l=pt-br] {Ir para a prÃ©via/prÃ³xima seÃ§Ã£o}  
+
+
+_texthelpsearchingtitle_ [l=pt-br] {Como buscar por palavras particulares}  
+
+_texthelpsearching_ [l=pt-br] {<p>
+  Na pÃ¡gina de busca, vocÃª faz uma consulta com passos simples:<p>
+
+  <ol><li>Especifique quais itens vocÃª quer buscar 
+      <li>Diga se vocÃª quer buscar por todas ou somente algumas das palavras 
+      <li>Digite as palavras que vocÃª quer buscar 
+      <li>Clique no botÃ£o <i>ComeÃ§ar Busca</i>
+  </ol>
+ <p>Quando vocÃª fizer uma consulta, os tÃ­tulos de vinte documentos que combinem melhor serÃ£o apresentados. HÃ¡ um botÃ£o no final que o levarÃ¡ aos prÃ³ximos vinte documentos.  De lÃ¡ vocÃª encontrarÃ¡ botÃµes para levÃ¡-lo para os terceiros vinte documentos ou voltar para os primeiros vinte e de assim em diante. Clique no tÃ­tulo de qualquer documento, ou no pequeno botÃ£o ao lado dele para vÃª-lo.
+
+<p>Um mÃ¡ximo de 50 documentos Ã© o nÃºmero imposto para os documentos no resultado. VocÃª pode mudar este nÃºmero clicando no botÃ£o <i>_Global:linktextPREFERENCIAS_</i> no topo da pÃ¡gina.<p>}  
+
+_texthelpquerytermstitle_ [l=pt-br] {Termos de busca }  
+_texthelpqueryterms_ [l=pt-br] {<p>Qualquer coisa que vocÃª digitar na caixa de consulta Ã© interpretado como uma lista de palavras ou frases chamadas "termos de busca". Um termo Ã© uma palavra simples contendo apenas letras e nÃºmeros , ou uma frase consistindo na sequÃªncia de palavras encerradas por aspas duplas (â...â). Os termos sÃ£o separados por espaÃ§os em branco. Se qualquer outro caractere, como por exemplo o de pontuaÃ§Ã£o, aparecer, eles servem para separar os termos como se fossem espaÃ§os. E entÃ£o eles sÃ£o ignorados. VocÃª nÃ£o pode buscar por palavras que incluem pontuaÃ§Ã£o.
+
+<p>Por exemplo, a consulta <p>
+    <ul><kbd>Agro-florestais em paÃ­ses em desenvolvimento: Sistemas para Sustentabilidade (1993)</kbd></ul>
+      <p>serÃ¡ tratada da mesma forma que<p>
+      <ul><kbd>Agro florestais em paÃ­ses em desenvolvimento: Sistemas para Sustentabilidade  1993 </kbd></ul><p>
+}  
+
+_texthelpmgppsearching_ [l=pt-br] {Algumas outras poucas opÃ§Ãµes estÃ£o disponÃ­veis para coleÃ§Ãµes construÃ­das com MGPP . 
+
+<ul>
+<li>Um <b>*</b> no final da consulta de um termo combina todas as palavras <b>comeÃ§ando com</b> aquela palavra, i.e. <b>comput*</b> combina todas as palavras comeÃ§ando com <b>comput</b>.
+<li><b>/x</b> pode ser utilizado para dar maior peso para um ou mais termos da consulta, i.e. <b>computaÃ§Ã£o/10 ciÃªncia</b> dÃ¡ a computaÃ§Ã£o 10 vezes mais peso que  a ciÃªncia quando faz o ranking dos documentos.
+</ul>
+}  
+
+_texthelplucenesearching_ [l=pt-br] {Para coleÃ§Ãµes construÃ­das com Lucene algumas outras poucas opÃ§Ãµes estÃ£o disponÃ­veis. 
+
+<ul>
+<li><b>?</b> pode ser utilizado como um wildcard no lugar de uma simples letra. Por exemplo, <b>c?rro</b> vai combinar  <b>carro</b>, <b>corro</b> e <b>cerro</b> etc.
+<li><b>*</b> pode ser utilizado como um wildcard no lugar de mÃºltiplas letras. Por exemplo, <b>comput*</b> combina todas as palavras que comeÃ§am com <b>comput</b>.
+</ul>
+Ambos wildcards podem ser usados no meio de um termo, ou no final. Eles nÃ£o podem ser usados no inÃ­cio do termo para a busca.
+}  
+
+_texthelpquerytypetitle_ [l=pt-br] {Tipo de consulta}  
+_texthelpquerytype_ [l=pt-br] {<p>Existem dois tipos diferentes de consulta. 
+<ul>
+  <li>Consultas por <b>todas</b> as palavras.  Esta opÃ§Ã£o busca por documentos (ou capÃ­tulos, ou tÃ­tulos) que contÃ©m todas as palavras que vocÃª especificou. Documentos que satisfaÃ§am a consulta serÃ£o visualizados em ordem de construÃ§Ã£o.<p>
+   <li>Consultas por <b>algumas</b> das palavras.  Apenas lista alguns dos termos que sÃ£o provÃ¡veis de aparecer nos documentos que vocÃª estÃ¡ procurando.  Documentos sÃ£o apresentados na ordem de quÃ£o prÃ³ximos eles estÃ£o da combinaÃ§Ã£o da consulta feita. Quando determinando o grau da combinaÃ§Ã£o,
+       <p><ul>
+        <li> quanto mais ocorrÃªncias de termos de busca um documento contem, mais prÃ³ximo da combinaÃ§Ã£o estarÃ¡;
+        <li> termos que sÃ£o raros na coleÃ§Ã£o sÃ£o mais importantes que os termos comuns;
+        <li> documentos menores combinam melhor que os documentos grandes.
+      </ul>
+</ul>
+ <p>Use quantos termos vocÃª quiser-uma sentenÃ§a completa, ou um parÃ¡grafo completo. Se vocÃª especificar somente um termo, os documentos serÃ£o ordenados pela maior frequÃªncia de ocorrÃªncia.<p>} 
+
+_texthelpadvancedsearchtitle_ [l=pt-br] {Busca avanÃ§ada utilizando a mÃ¡quina de busca  _1_}  
+
+_texthelpadvancedsearch_ [l=pt-br] {<p>Se vocÃª selecionou o modo avanÃ§ado de consulta (nas preferÃªncias) vocÃª tem algumas opÃ§Ãµes de busca um pouco diferentes. 
+}  
+
+_texthelpadvsearchmg_ [l=pt-br] {Busca avanÃ§ada em coleÃ§Ãµes MG dÃ¡ a vocÃª duas opÃ§Ãµes: por ranque e booleana.
+Uma busca por <b>por ranque</b>Ã© exatamente a mesma que a busca <b>algum</b> descrita em <a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_
+}  
+
+_texthelpbooleansearch_ [l=pt-br] {Uma busca <b>booleana</b> permite que vocÃª combine termos utilizando & (para "e"), | (para "ou"), e ! (para "nÃ£o"), utilizando parÃªnteses para agrupar caso necessÃ¡rio. O operador padrÃ£o Ã© | (para âouâ).
+<p>
+Por exemplo, <b>agricultura & sustentÃ¡vel</b> vÃ£o combinar documentos que contÃ©m ambos <b>agricultura</b> E <b>sustentÃ¡vel</b>, enquanto <b>agricultura | sustentÃ¡vel</b> vai combinar documentos que contÃ©m ou <b>agricultura</b> OU <b>sustentÃ¡vel</b>.
+<b>agricultura ! SustentÃ¡vel</b> vÃ£o combinar documentos que contÃ©m  <b>agricultura</b> E NÃO contÃ©m <b>sustentÃ¡vel</b>.
+<p>
+Consultas mais precisas podem ser especificadas utilizando combinaÃ§Ãµes de operadores e parÃªnteses. Por exemplo, <b>(semente | plantaÃ§Ã£o) & (fazenda | estaÃ§Ã£o)</b>, ou <b>semente | plantaÃ§Ã£o | horta ! transgÃªnico</b>.
+}  
+
+_texthelpadvsearchmgpp_ [l=pt-br] {Buscas avaÃ§adas em coleÃ§Ãµes MGPP usam operadores booleanos. _texthelpbooleansearch_  <p>Os resultados podem ser mostrados em ordem de <b>ranque</b> como descrito para <b>algum</b> busca em <a href="\#query-type">_texthelpquerytypetitle_</a>, ou em ordem ânaturalâ ou âconstruÃ­daâ. A Ãºltima (construÃ­da) Ã© a ordem em que os documentos foram processados durante a criaÃ§Ã£o da coleÃ§Ã£o.  <p>  Os prÃ³ximos operadores incluem <b>PERTOx</b> e <b>DENTROx</b>.  PERTOx Ã© usado para especificar a distÃ¢ncia mÃ¡xima (x palavras) que podem separar dois termos de consulta para que um documento combine com o outro.  DENTROx especifica que o segundo termo deve ocorrer dentro de x palavras <i>depois</i> do primeiro item. Isto Ã© parecido com o PERTO mas a ordem Ã© importante. A distÃ¢ncia padrÃ£o Ã© 20 palavras.  }  
+
+_texthelpadvancedsearchextra_ [l=pt-br] {NOTA: estes operadores sÃ£o todos ignorados se vocÃª estÃ¡ buscando atravÃ©s do modo de consulta simples}  
+
+_texthelpadvsearchlucene_ [l=pt-br] {Buscas avanÃ§adas em coleÃ§Ãµes Lucene usam operadores booleanos. _texthelpbooleansearch_
+}  
+
+_texthelpformsearchtitle_ [l=pt-br] {Busca feita por campo}  
+
+_texthelpformsearch_ [l=pt-br] {<p>Buscar por campos dÃ¡ a oportunidade de combinar buscas atravÃ©s dos campos. Por exemplo, pode-se buscar por "Silva" no TÃ­tulo E "agricultura sustentÃ¡vel" no Assunto. No modo simples de consulta, cada linha do formulÃ¡rio se comporta como uma linha de busca simples normal. As linhas individuais do formulÃ¡rio sÃ£o combinadas usando E (para uma busca com a clÃ¡usula "todo") ou OU (para a busca com a clÃ¡usula "algum"). Termos dentro do campo tambÃ©m sÃ£o combinados da mesma maneira. No modo avanÃ§ado, vocÃª pode especificar diferente combinaÃ§Ãµes e E/OU/NÃO entre os campos usando as listas drop-down, e dentro de um campo vocÃª pode usar operadores booleanos.
+}  
+
+_texthelpformstemming_ [l=pt-br] {As caixas de diÃ¡logo "fold" e "stem" permitem que vocÃª especifique se os termos dentro daquele campo sÃ£o ou casefolded ou stemmed. Estas sÃ£o ambas desligadas para forma avanÃ§ada de busca.}  
+
+_textdatesearch_ [l=pt-br] {Buscando com Datas}  
+
+_texthelpdatesearch_ [l=pt-br] {A busca por data permite que vocÃª encontre documentos que, alÃ©m de combinar com seus termos de busca, sÃ£o sobre eventos dentro de um espectro temporal especÃ­fico. VocÃª pode buscar por documentos de um certo ano ou de um certo perÃ­odo de anos. Note que vocÃª nÃ£o precisa ter nenhum termo para busca â vocÃª pode buscar apenas pela data; e tambÃ©m que vocÃª nÃ£o precisa usar datas em sua busca, se vocÃª nÃ£o digitar nenhuma data Ã© exatamente como se a busca por data nÃ£o existisse.<p>
+}  
+
+_texthelpdatehowtotitle_ [l=pt-br] {Como utilizar este recurso:}  
+_texthelpdatehowto_ [l=pt-br] {<ul>
+   <li>Para buscar documentos sobre um Ãºnico ano:<p>
+   <ul>
+       <li>Digite em qualquer busca comum os termos como vocÃª faria normalmente.        <li>Digite o ano que vocÃª quer na caixa de diÃ¡logo  "Data de inÃ­cio (ou apenas)" .
+       <li>Se sua data Ã© anterior Ã  era atual (tambÃ©m conhecida como antes de Cristo, A.C.), escolha a opÃ§Ã£o "B.C.E" no menu pulldown prÃ³ximo a esta caixa de diÃ¡logo.
+       <li>Inicie sua pesquisa como vocÃª faria normalmente.
+   </ul>
+<p><li>Para buscar por documentos sobre um perÃ­odo de tempo ou um perÃ­odo de anos:<p>
+   <ul>
+       <li>Digite quaisquer termos de busca como vocÃª faria normalmente.
+       <li>Digite a data mais anterior na caixa "Data de inÃ­cio (ou apenas)".
+       <li>Digite a data mais posterior na caixa "Data final".
+       <li>Selecione opÃ§Ã£o âA.C.â do texto do menu pulldown para qualquer data anterior Ã  era atual (tambÃ©m conhecida como antes de Cristo)
+       <li>Inicie sua busca como vocÃª faria normalmente.
+   </ul>    
+</ul><p>
+}  
+
+_texthelpdateresultstitle_ [l=pt-br] {Os resultados de sua busca}  
+_texthelpdateresults_ [l=pt-br] {Em termos gerais, uma busca por documentos sobre o ano 1903 nÃ£o terÃ¡ como retorno documentos que sejam livros de referÃªncia escritos em 1903, apenas documentos sobre 1903. No entanto, considerando a forma em que as datas dos documentos Ã© encontrada, ele vai retornar com documentos sobre um perÃ­odo de tempo (por exemplo 1899-1911) o que inclui 1903, e tambÃ©m responderÃ¡ com estes documentos que tÃªm como parte do texto de seu nome o sÃ©culo do qual 1903 Ã© parte (por exemplo sÃ©culo XX ou sÃ©culo vinte). Isto significa que para alguns documentos, as datas solicitadas na sua busca nÃ£o vÃ£o efetivamente aparecer no texto do documento. Para uma busca por perÃ­odo, tudo isso se aplica para cada data dentro do perÃ­odo.<p>
+}  
+
+_textchangeprefs_ [l=pt-br] {Mudando suas preferÃªncias }  
+
+_texthelppreferences_ [l=pt-br] {<p>Quando vocÃª clica no botÃ£o de <i>_Global:linktextPREFERENCIAS_</i> no topo da pÃ¡gina, vocÃª serÃ¡ capaz de mudar alguns aspectos da interface para moldÃ¡-la a suas prÃ³prias necessidades.
+}  
+
+_texthelpcollectionprefstitle_ [l=pt-br] {PreferÃªncias da coleÃ§Ã£o}  
+_texthelpcollectionprefs_ [l=pt-br] {Algumas coleÃ§Ãµes compreendem vÃ¡rias subcoleÃ§Ãµes, as quais podem ser buscadas de forma independente ou juntas, como uma unidade. Assim, vocÃª pode selecionar quais sub-coleÃ§Ãµes incluir em suas buscas na pÃ¡gina de PreferÃªncias. 
+}  
+
+_texthelplanguageprefstitle_ [l=pt-br] {PreferÃªncias de idioma}  
+_texthelplanguageprefs_ [l=pt-br] {<p>Cada coleÃ§Ã£o tem uma lÃ­ngua de apresentaÃ§Ã£o padrÃ£o, mas vocÃª pode mudar para uma lÃ­ngua diferente se vocÃª quiser. VocÃª tambÃ©m pode alterar o esquema para codificaÃ§Ã£o utilizado pelo Greenstone do output para o navegador â o software escolhe padrÃµes razoÃ¡veis, mas com alguns navegadores pode ser necessÃ¡rio mudar para uma codificaÃ§Ã£o distinta para assegurar a visualizaÃ§Ã£o correta dos caracteres. Todas as coleÃ§Ãµes permitem que vocÃª mude o formato da interface grÃ¡fica padrÃ£o para um textual. Isto Ã© particularmente de grande ajuda para usuÃ¡rios com deficiÃªncias visuais que usam fontes grandes na tela ou sintetizadores de fala para output.
+}  
+
+_texthelppresentationprefstitle_ [l=pt-br] {PreferÃªncias de apresentaÃ§Ã£o}  
+_texthelppresentationprefs_ [l=pt-br] {Dependendo de uma coleÃ§Ã£o particular, poderÃ£o haver vÃ¡rias opÃ§Ãµes que vocÃª pode definir para controlar a apresentaÃ§Ã£o. 
+
+<p>As coleÃ§Ãµes de Web pages permitirÃ£o a vocÃª suprimir a barra de navegaÃ§Ã£o do Greenstone no topo de cada pÃ¡gina de documento, assim, uma vez que vocÃª tenha feito uma busca, vocÃª aterrisa na pÃ¡gina Web exata que combina com sua a busca sem nenhum cabeÃ§alho do Greenstone. Para fazer outra busca vocÃª terÃ¡ que usar o botÃ£o "voltar" do seu navegador. Estas coleÃ§Ãµes tambÃ©m permitem que vocÃª suprima as mensagens de aviso do Greenstone quando vocÃª clica em um link que leva vocÃª para fora da coleÃ§Ã£o da biblioteca digital e para a Web mesma.
+E em algumas coleÃ§Ãµes vocÃª pode controlar se vocÃª prefere que os links na pÃ¡gina de resultados de busca levem vocÃª diretamente para a atual URL em questÃ£o, ou se para a cÃ³pia da pÃ¡gina na biblioteca digital.}  
+
+_texthelpsearchprefstitle_ [l=pt-br] {PreferÃªncias de busca }  
+_texthelpsearchprefs_ [l=pt-br] {<p>VocÃª pode mudar para um modo de consulta âavanÃ§adoâ que permite que vocÃª combine termos utilizando & (para "e"), | (para "ou"), e ! (para "nÃ£o"), utilizando parÃªnteses para agrupar, se desejado. Isto permite que vocÃª especifique as consultas de forma mais precisa. 
+<p>_selectsearchtypeprefs_
+<p>_selectwordmodificationprefs_
+<p>VocÃª pode ativar o recurso de buscar histÃ³rico, que mostra a vocÃª suas Ãºltimas consultas. Isto faz com que seja mais fÃ¡cil repetir versÃµes ligeiramente modificadas das consultas prÃ©vias. 
+<p>Finalmente, vocÃª pode controlar o nÃºmero de itens encontrados, e o nÃºmero apresentado em cada tela.
+}  
+
+_textcasefoldprefs_ [l=pt-br] {Um par de botÃµes controlam que os termos em caixa alta ou caixa baixa deverÃ£o ser encontrados atravÃ©s da busca. Por exemplo, se "_preferences:textignorecase_" for selecionado, <i>agricultura sustentÃ¡vel</i> serÃ¡ tratado da mesma forma que <i>Agricultura SustentÃ¡vel</i> e <i>AGRICULTURA SUSTENTÃVEL</i>.}  
+_textstemprefs_ [l=pt-br] {Um par de botÃµes controlam se deve-se ignorar ou nÃ£o o fim das palavras em uma busca, ou seja vocÃª pode buscar pelos radicais. Por exemplo, se "_preferences:textstem_" Ã© selecionado, <i>agricultura sustentÃ¡vel</i> serÃ¡ tratado da mesma forma que <i>agriculturas sustentÃ¡veis</i> e <i>agricultura de sustentabilidade</i>. Isto atualmente sÃ³ funciona apropriadamente para textos em lÃ­ngua inglesa. _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=pt-br] {Um par de botÃµes controlam que se as letras estejam acentuadas ou nÃ£o, deverÃ£o ser igualmente encontradas atravÃ©s da busca. Por exemplo, se "_preferences:textignoreaccents_" for selecionado, <i>Ã³rgÃ£o</i> serÃ¡ tratado da mesma forma que  <i>orgÃ£o</i> e  <i>orgao</i>.}  
+ 
+_textstemoptionsprefs_ [l=pt-br] {Pode ser mais conveniente e preciso usar o recurso de reduÃ§Ã£o de termos descrito acima em  "_texthelpquerytermstitle_".}  
+
+_textsearchtypeprefsplain_ [l=pt-br] {Ã possÃ­vel ter uma caixa de consulta grande, de forma que vocÃª possa facilmente fazer uma busca do tamanho de um parÃ¡grafo. Ã surpreendentemente rÃ¡pido buscar por grandes quantidades de texto.}  
+
+_textsearchtypeprefsform_ [l=pt-br] {VocÃª pode mudar o nÃºmero dos campos mostrados no formulÃ¡rio de busca.}  
+
+_textsearchtypeprefsboth_ [l=pt-br] {VocÃª pode escolher o tipo de busca da coleÃ§Ã£o entre busca "normal" e busca "por campo". 
+<ul>
+<li>Busca normal provÃª uma Ãºnica caixa de diÃ¡logo para consulta. _textsearchtypeprefsplain_</li>
+<li>Busca por campo provÃª um nÃºmero de caixas de diÃ¡logo para consulta, cada uma consultando um campo diferente do Ã­ndice. Isto permite buscar em diferentes campos de uma vez. _textsearchtypeprefsform_ </li>
+</ul>
+}  
+
+
+
+_texttanumbrowseoptions_ [l=pt-br] {Existem _numbrowseoptions_ formas de encontrar informaÃ§Ãµes nesta coleÃ§Ã£o:}  
+
+_textsimplehelpheading_ [l=pt-br] {Como encontrar informaÃ§Ãµes na coleÃ§Ã£o _collectionname_ }  
+
+_texthelpscopetitle_ [l=pt-br] {AbrangÃªncia das consultas}  
+_texthelpscope_ [l=pt-br] {<p>
+Na maioria das coleÃ§Ãµes vocÃª tem a possibilidade de escolha entre diferentes Ã­ndices de busca. Por exemplo, poderiam ser Ã­ndices de autores ou de tÃ­tulos. Ou poderiam ser Ã­ndices de capÃ­tulos ou de parÃ¡grafos. Geralmente, o documento completo vem como resultado de sua busca, isso Ã© independente do Ã­ndice no qual vocÃª busca.
+<p>Se os documentos sÃ£o livros, eles serÃ£o abertos no local apropriado.
+}  
Index: /gsdl/stable/macros/port-pt.dm
===================================================================
--- /gsdl/stable/macros/port-pt.dm	(revision 20131)
+++ /gsdl/stable/macros/port-pt.dm	(revision 20131)
@@ -0,0 +1,798 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Portuguese (Portugal) Language text and icon macros 
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=pt-pt] {PeriÃ³dicos}
+_textsource_ [l=pt-pt] {ref. da fonte:}
+_textdate_ [l=pt-pt] {data de publicaÃ§Ã£o:}
+_textnumpages_ [l=pt-pt] {no. de pÃ¡ginas:}
+
+_textsignin_ [l=pt-pt] {registar}
+
+_textdefaultcontent_ [l=pt-pt] {A pÃ¡gina requerida nÃ£o pode ser encontrada. Por favor,
+use o botÃ£o 'back' do seu browser ou o botÃ£o "home" para retornar para a Biblioteca Digital Greenstone.}
+
+_textdefaulttitle_ [l=pt-pt] {GSDL Erro}
+
+# -- Missing translation: _textbadcollection_
+
+_textselectpage_ [l=pt-pt] {-- Seleccionar PÃ¡gina --}
+
+_collectionextra_ [l=pt-pt] {Esta coleÃ§Ã£o contÃ©m _about:numdocs_ documentos. 
+Foi construÃ­da hÃ¡ _about:builddate_ dias.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=pt-pt] {<p>Esta colecÃ§Ã£o contÃ©m _numdocs_ _If_("_numdocs_" eq "1",documento,documentos), num total de _numbytes_.
+<p><a href="_httppagex_(bsummary)">Selecione aqui</a> para ver uma descriÃ§Ã£o desta colecÃ§Ã£o.}
+
+_textdescrcollection_ [l=pt-pt] {}
+_textdescrabout_ [l=pt-pt] {PÃ¡gina Sobre}
+_textdescrhome_ [l=pt-pt] {PÃ¡gina Ãnicial}
+_textdescrhelp_ [l=pt-pt] {PÃ¡gina de Ajuda}
+_textdescrpref_ [l=pt-pt] {PÃ¡gina de PreferÃªncias}
+_textdescrgreenstone_ [l=pt-pt] {Software da Biblioteca Digital Greenstone}
+_textdescrusab_ [l=pt-pt] {O que acha difÃ­cil de usar?}
+
+_textdescrSearch_ [l=pt-pt] {Busca por termos especÃ­ficos}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=pt-pt] {Ãndice alfabÃ©tico de tÃ­tulos}
+_textdescrCreator_ [l=pt-pt] {Ãndice alfabÃ©tico de autores}
+_textdescrSubject_ [l=pt-pt] {Ãndice de categorias de assunto}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=pt-pt] {Ãndice de datas}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+_textdescrSource_ [l=pt-pt] {Ãndice de nomes de ficheiros originais}
+_textdescrLanguage_ [l=pt-pt] {Ãndice de lÃ­nguas}
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=pt-pt] {Ãndice de organizaÃ§Ãµes}
+_textdescrKeyword_ [l=pt-pt] {Ãndice de palavras-chave}
+_textdescrHowto_ [l=pt-pt] {Ãndice de categorias como}
+_textdescrList_ [l=pt-pt] {Ãndice da lista de documentos}
+_textdescrSeries_ [l=pt-pt] {Ãndice de ediÃ§Ãµes}
+_textdescrTo_ [l=pt-pt] {Ãndice do campo Para}
+_textdescrFrom_ [l=pt-pt] {Indice do campo De}
+_textdescrTopic_ [l=pt-pt] {Ãndice de ediÃ§Ãµes de tÃ³picos especiais}
+_textdescrBrowse_ [l=pt-pt] {Listar}
+# -- Missing translation: _textdescrCollage_
+_textdescrPeople_ [l=pt-pt] {Ãndice alfabÃ©tico de pessoas}
+_textdescrAcronym_ [l=pt-pt] {Ãndice dos acrÃ³nimos}
+_textdescrPhrase_ [l=pt-pt] {Ãndice de frases}
+_textdescrArtist_ [l=pt-pt] {Ãndice dos artistas}
+_textdescrVolume_ [l=pt-pt] {Ãndice de volumes}
+# -- Missing translation: _textdescrCountries_
+_textdescrCaptions_ [l=pt-pt] {Ãndice das legendas das fotos}
+
+
+_labelSearch_ [l=pt-pt] {Pesquisa}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=pt-pt] {TÃ­tulos A-Z}
+_labelCreator_ [l=pt-pt] {Autors A-Z}
+_labelSubject_ [l=pt-pt] {Assuntos}
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=pt-pt] {Datas}
+# -- Missing translation: _labelType_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+_labelSource_ [l=pt-pt] {Ficheiros}
+_labelLanguage_ [l=pt-pt] {LÃ­ngua}
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=pt-pt] {OrganizaÃ§Ã£o}
+_labelKeyword_ [l=pt-pt] {Palavras-chave}
+_labelHow_ [l=pt-pt] {Como}
+_labelSeries_ [l=pt-pt] {SÃ©ries}
+_labelList_ [l=pt-pt] {Listagem}
+_labelTo_ [l=pt-pt] {Para}
+_labelFrom_ [l=pt-pt] {De}
+_labelTopic_ [l=pt-pt] {TÃ³picos}
+_labelBrwse_ [l=pt-pt] {Listar}
+# -- Missing translation: _labelCollage_
+_labelBrows_ [l=pt-pt] {Navegar}
+_labelPeople_ [l=pt-pt] {Pessoas A-Z}
+_labelAcronym_ [l=pt-pt] {AcrÃ³nimos}
+_labelPhrase_ [l=pt-pt] {Frases}
+_labelArtist_ [l=pt-pt] {Artistas}
+_labelVolume_ [l=pt-pt] {Volumes}
+# -- Missing translation: _labelCaptions_
+# -- Missing translation: _labelCountries_
+
+_texticontext_ [l=pt-pt] {Ver o documento}
+_texticonclosedbook_ [l=pt-pt] {Abrir este documento e visualizar o conteÃºdo}
+_texticonnext_ [l=pt-pt] {seÃ§Ã£o seguinte}
+_texticonprev_ [l=pt-pt] {seÃ§Ã£o anterior}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=pt-pt] {Ver o documento MIDI}
+_texticonmsword_ [l=pt-pt] {Ver o documento Microsoft Word}
+_texticonmp3_ [l=pt-pt] {Ver o documento MP3}
+_texticonpdf_ [l=pt-pt] {Ver o documento PDF}
+_texticonps_ [l=pt-pt] {Ver o documento PostScript}
+_texticonppt_ [l=pt-pt] {Ver o documento PowerPoint}
+_texticonrtf_ [l=pt-pt] {Ver o documento RTF}
+_texticonxls_ [l=pt-pt] {Ver o documento Microsoft Excell}
+
+_page_ [l=pt-pt] {pÃ¡gina }
+_pages_ [l=pt-pt] {pÃ¡ginas}
+_of_ [l=pt-pt] {de }
+_vol_ [l=pt-pt] {Vol.}
+_num_ [l=pt-pt] {No.}
+
+_textmonth00_ [l=pt-pt] {}
+_textmonth01_ [l=pt-pt] {Janeiro}
+_textmonth02_ [l=pt-pt] {Fevereiro}
+_textmonth03_ [l=pt-pt] {MarÃ§o}
+_textmonth04_ [l=pt-pt] {Abril}
+_textmonth05_ [l=pt-pt] {Maio}
+_textmonth06_ [l=pt-pt] {Junho}
+_textmonth07_ [l=pt-pt] {Julho}
+_textmonth08_ [l=pt-pt] {Agosto}
+_textmonth09_ [l=pt-pt] {Setembro}
+_textmonth10_ [l=pt-pt] {Outubro}
+_textmonth11_ [l=pt-pt] {Novembro}
+_textmonth12_ [l=pt-pt] {Dezembro}
+
+_textdocument_ [l=pt-pt] {Documento}
+_textsection_ [l=pt-pt] {SecÃ§Ã£o}
+_textparagraph_ [l=pt-pt] {ParÃ¡grafo}
+
+_magazines_ [l=pt-pt] {Revistas}
+
+_nzdlpagefooter_ [l=pt-pt] {<div class="divbar">&nbsp;</div>
+<p><a href="_gwcgi_">Projeto Biblioteca Digital da Nova ZelÃ¢ndia</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Departamento de CiÃªncia da ComputaÃ§Ã£o</a>, 
+<a href="http://www.waikato.ac.nz">Universidade de Waikato</a>, 
+Nova ZelÃ¢ndia}
+
+_linktextHOME_ [l=pt-pt] {ÃNICIO}
+_linktextHELP_ [l=pt-pt] {AJUDA}
+_linktextPREFERENCES_ [l=pt-pt] {PREFERÃNCIAS}
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=pt-pt] {Sobre esta coleÃ§Ã£o}
+
+_textsubcols1_ [l=pt-pt] {<p>A colecÃ§Ã£o completa contÃ©m _1_ sub-coleÃ§Ãµes:
+As disponÃ­veis actualmente sÃ£o:
+<blockquote>}
+
+_textsubcols2_ [l=pt-pt] {</blockquote>
+Pode verificar (e alterar) a sub-coleÃ§Ã£o que estÃ¡ 
+usando actualmente na pÃ¡gina de PreferÃªncias.}
+
+_titleabout_ [l=pt-pt] {sobre}
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+# -- Missing translation: _texticonhcoll_
+# -- Missing translation: _texticonhcapt_
+# -- Missing translation: _texticonhcount_
+
+_texticonopenbookshelf_ [l=pt-pt] {fechar esta secÃ§Ã£o da biblioteca}
+_texticonclosedbookshelf_ [l=pt-pt] {abre esta secÃ§Ã£o da biblioteca e visualiza o conteÃºdo}
+_texticonopenbook_ [l=pt-pt] {fechar este livro}
+_texticonclosedfolder_ [l=pt-pt] {abre esta pasta e visualiza o conteÃºdo}
+_texticonclosedfolder2_ [l=pt-pt] {abre sub-secÃ§Ã£o: }
+_texticonopenfolder_ [l=pt-pt] {fechar esta pasta}
+_texticonopenfolder2_ [l=pt-pt] {fechar sub-seÃ§Ã£o: }
+_texticonsmalltext_ [l=pt-pt] {Ver esta secÃ§Ã£o do texto}
+_texticonsmalltext2_ [l=pt-pt] {ver texto: }
+_texticonpointer_ [l=pt-pt] {secÃ§Ã£o actual}
+_texticondetach_ [l=pt-pt] {Abrir esta pÃ¡gina numa nova janela}
+_texticonhighlight_ [l=pt-pt] {Destacar termos de pesquisa}
+_texticonnohighlight_ [l=pt-pt] {NÃ£o destacar termos de pesquisa}
+_texticoncontracttoc_ [l=pt-pt] {Reduzir Ã­ndice de conteÃºdos}
+_texticonexpandtoc_ [l=pt-pt] {Expandir Ã­ndice de conteÃºdos}
+_texticonexpandtext_ [l=pt-pt] {Mostrar todo o texto}
+_texticoncontracttext_ [l=pt-pt] {Mostra texto apenas para as secÃ§Ãµes selecionadas}
+_texticonwarning_ [l=pt-pt] {<b>Aviso: </b>}
+_texticoncont_ [l=pt-pt] {continuar?}
+
+_textltwarning_ [l=pt-pt] {<div class="buttons">_imagecont_</div>
+_iconwarning_Expanding este texto irÃ¡ gerar uma grande 
+quantidade de dados para o seu browser mostrar
+}
+
+_textgoto_ [l=pt-pt] {ir para pÃ¡gina}
+_textintro_ [l=pt-pt] {<i>(texto introdutÃ³rio)</i>}
+
+_textCONTINUE_ [l=pt-pt] {CONTINUAR??}
+
+_textEXPANDTEXT_ [l=pt-pt] {EXPANDIR\nTEXTO}
+
+_textCONTRACTCONTENTS_ [l=pt-pt] {CONTRAIR\nCONTEÃDO}
+
+_textDETACH_ [l=pt-pt] {SEPARAR}
+
+_textEXPANDCONTENTS_ [l=pt-pt] {EXPANDIR\nCONTEÃDO}
+
+_textCONTRACT_ [l=pt-pt] {CONTRAIR\nTEXTO}
+
+_textHIGHLIGHT_ [l=pt-pt] {DESTACAR}
+
+_textNOHIGHLIGHT_ [l=pt-pt] {NÃO\nDESTACAR}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=pt-pt] {_If_(_thislast_,resultados _thisfirst_ - _thislast_ para a pesquisa: _cgiargq_,Nunhuma resposta encontrada: _cgiargq_)}
+_textnoquerytitle_ [l=pt-pt] {PÃ¡gina de pesquisa}
+
+_textsome_ [l=pt-pt] {algumas}
+_textall_ [l=pt-pt] {todos}
+_textboolean_ [l=pt-pt] {booleano}
+_textranked_ [l=pt-pt] {ordenado}
+_textnatural_ [l=pt-pt] {natural}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=pt-pt] {histÃ³rico de pesquisa}
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+_textusequery_ [l=pt-pt] {usar esta pesquisa}
+_textfreqmsg1_ [l=pt-pt] {Palavras contadas: }
+_textpostprocess_ [l=pt-pt] {_If_(_quotedquery_,<br><i>pÃ³s-processadas para encontrar _quotedquery_</i>
+)}
+_textinvalidquery_ [l=pt-pt] {Pesquisa com sintaxe invÃ¡lida}
+
+_textmorethan_ [l=pt-pt] {Mais do que }
+_textapprox_ [l=pt-pt] {Sobre }
+_textnodocs_ [l=pt-pt] {NÃ£o foi encontrato nenhum documento.}
+_text1doc_ [l=pt-pt] {1 documento encontrado.}
+_textlotsdocs_ [l=pt-pt] {documentos encontrados.}
+_textmatches_ [l=pt-pt] {Resultados}
+_textbeginsearch_ [l=pt-pt] {Iniciar a Pesquisa}
+_textrunquery_ [l=pt-pt] {Pesquisar}
+_textclearform_ [l=pt-pt] {Limpar}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=pt-pt] {Palavra ou frase}
+_textinfield_ [l=pt-pt] {... no campo}
+_textfoldstem_ [l=pt-pt] {(dobra, eixo)}
+
+_textadvquery_ [l=pt-pt] {Ou introduza a pesquisa directamente:}
+_textallfields_ [l=pt-pt] {todos os campos}
+_texttextonly_ [l=pt-pt] {apenas texto}
+_textand_ [l=pt-pt] {e}
+_textor_ [l=pt-pt] {ou}
+_textandnot_ [l=pt-pt] {e nÃ£o}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=pt-pt] {Procurar por _indexselection_ _If_(_jselection_, de _jselection_)_If_(_gselection_, no _gselection_ nÃ­vel)_If_(_nselection_, na _nselection_ lÃ­ngua) que contenha _querytypeselection_ palavras}
+
+_textadvancedsearch_ [l=pt-pt] {Pesquisar _indexselection_ _If_(_jselection_, de _jselection_)_If_(_gselection_, no _gselection_ nÃ­vel)_If_(_nselection_, na _nselection_ lÃ­ngua) usando _querytypeselection_}
+
+_textformsimplesearch_ [l=pt-pt] {Procurar _If_(_jselection_, _jselection_) _If_(_gformselection_, no _gformselection_ level) _If_(_nselection_, na _nselection_ lÃ­ngua)
+for _formquerytypesimpleselection_ of}
+
+_textformadvancedsearch_ [l=pt-pt] {Procurar _If_(_jselection_,_jselection_) _If_(_gformselection_, no _gformselection_ level)_If_(_nselection_, na _nselection_ lÃ­ngua) 
+e mostrar resultados ordenados por _formquerytypeadvancedselection_}
+
+
+_textnojsformwarning_ [l=pt-pt] {Aviso: O Javascript estÃ¡ desactivado no seu briwser. <br> Para usar formulÃ¡rios de pesquisa deve activÃ¡-lo.}
+_textdatesearch_ [l=pt-pt] {Nesta colecÃ§Ã£o podem-se pesquisar documentos contendo uma data ou que usando intervalos de datas. Esta opÃ§Ã£o de pesquisa Ã© opcional. }
+_textstartdate_ [l=pt-pt] {Data de inÃ­cio (ou Ãºnica):}
+_textenddate_ [l=pt-pt] {Data de inÃ­cio:}
+_textbc_ [l=pt-pt] {A.E.C.}
+_textad_ [l=pt-pt] {E.C.}
+_textexplaineras_ [l=pt-pt] {E.C. e A.E.C. sÃ£o alternativas para D.C. e A.C., respectivamente. Estes termos sÃ£o considerados culturalmente nÃ£o descriminatÃ³rios, significando "Era Comum" e "Antes da Era Comum"}
+
+_textstemon_ [l=pt-pt] {(ignorar final das palavras)}
+
+_textsearchhistory_ [l=pt-pt] {HistÃ³rial de Pesquisa}
+
+#text macros for search history
+_textnohistory_ [l=pt-pt] {HistÃ³rico de pesquisa nÃ£o disponÃ­vel}
+_texthresult_ [l=pt-pt] {resultado}
+_texthresults_ [l=pt-pt] {resultados}
+_texthallwords_ [l=pt-pt] {todas as palavras}
+_texthsomewords_ [l=pt-pt] {algumas palavras}
+_texthboolean_ [l=pt-pt] {booleano}
+_texthranked_ [l=pt-pt] {ordenado}
+_texthcaseon_ [l=pt-pt] {maiÃºsculas/minÃºsculas}
+_texthcaseoff_ [l=pt-pt] {"casefolded"}
+_texthstemon_ [l=pt-pt] {"stemmed"}
+_texthstemoff_ [l=pt-pt] {"unstemmed"}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=pt-pt] {PreferÃªncias foram definidas como se segue. NÃ£o use o botÃ£o de "back" do seu browser
+- irÃ¡ desfazer as preferÃªncias! Em alternativa, seleccione um dos botÃµes na barra acima.
+}
+_textsetprefs_ [l=pt-pt] {definir preferÃªncias}
+_textsearchprefs_ [l=pt-pt] {PreferÃªncias de pesquisa}
+_textcollectionprefs_ [l=pt-pt] {PreferÃªncias da colecÃ§Ã£o}
+_textpresentationprefs_ [l=pt-pt] {PreferÃªncias de apresentaÃ§Ã£o}
+_textpreferences_ [l=pt-pt] {PreferÃªncias}
+_textcasediffs_ [l=pt-pt] {DiferenÃ§as maiÃºsculas/minÃºsculas}
+_textignorecase_ [l=pt-pt] {ignorar diferenÃ§as entre maiÃºsculas/minÃºsculas}
+_textmatchcase_ [l=pt-pt] {verificar maiÃºsculas/minÃºsculas}
+_textwordends_ [l=pt-pt] {TerminaÃ§Ãµes de palavras:}
+_textstem_ [l=pt-pt] {ignorar terminaÃ§Ãµes das palavras}
+_textnostem_ [l=pt-pt] {verificar palavra inteira}
+_textprefop_ [l=pt-pt] {Retornar atÃ© _maxdocoption_ resultados com _hitsperpageoption_ resultados por pÃ¡gina.}
+_textextlink_ [l=pt-pt] {Acesso pÃ¡ginas Web externas: }
+_textintlink_ [l=pt-pt] {Documentos recuperados de:}
+_textlanguage_ [l=pt-pt] {LÃ­ngua da Interface: }
+_textencoding_ [l=pt-pt] {CodificaÃ§Ã£o:}
+_textformat_ [l=pt-pt] {Formato da Interface: }
+_textall_ [l=pt-pt] {todos}
+_textquerymode_ [l=pt-pt] {Modo de pesquisa:}
+_textsimplemode_ [l=pt-pt] {modo de pesquisa simples}
+_textadvancedmode_ [l=pt-pt] {modo de pesquisas avanÃ§adas (permite pesquisas booleanas usando !, &, |, e parÃªntesis)}
+_textlinkinterm_ [l=pt-pt] {atravÃ©s de pÃ¡gina intermÃ©dia}
+_textlinkdirect_ [l=pt-pt] {ir directamente para lÃ¡}
+_textdigitlib_ [l=pt-pt] {a biblioteca digital}
+_textweb_ [l=pt-pt] {a web}
+_textgraphical_ [l=pt-pt] {GrÃ¡fico}
+_texttextual_ [l=pt-pt] {Textual}
+_textcollectionoption_ [l=pt-pt] {<p>
+Sub-colecÃ§Ãµes a incluir:
+<br>}
+
+_textrelateddocdisplay_ [l=pt-pt] {mostrar documentos relacionados}
+_textsearchhistory_ [l=pt-pt] {HistÃ³rico de pesquisa:}
+_textnohistory_ [l=pt-pt] {Sem histÃ³rico de pesquisa}
+_texthistorydisplay_ [l=pt-pt] {mostrar _historynumrecords_ pesquisas do histÃ³rico}
+_textnohistorydisplay_ [l=pt-pt] {nÃ£o mostrar histÃ³rico de pesquisa}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=pt-pt] {Pesquisa:}
+_textplainsearch_ [l=pt-pt] {Pesquisa simples:}
+_textqueryboxsize_ [l=pt-pt] {Tamanho da caixa de pesquisa:}
+_textregbox_ [l=pt-pt] {caixa d epesquisa normal}
+_textbigbox_ [l=pt-pt] {caixa de pesquisa grande}
+_textformtype_ [l=pt-pt] {Tipo:}
+_textsimple_ [l=pt-pt] {simples}
+_textadvanced_ [l=pt-pt] {avanÃ§ado}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=pt-pt] {com}
+_textfields_ [l=pt-pt] {campos}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=pt-pt] {Ordenar documentos por}
+_textalsoshowing_ [l=pt-pt] {apresentando tambÃ©m}
+_textwith_ [l=pt-pt] {com o mÃ¡ximo}
+_textdocsperpage_ [l=pt-pt] {documentos por pÃ¡gina}
+
+_textfilterby_ [l=pt-pt] {Documentos contendo}
+_textall_ [l=pt-pt] {todos}
+_textany_ [l=pt-pt] {qualquer um}
+_textwords_ [l=pt-pt] {das palavras}
+_textleaveblank_ [l=pt-pt] {deixe esta caixa em branco para recuperar todos os documentos}
+
+_browsebuttontext_ [l=pt-pt] {"Ordenar Documentos"}
+
+_nodata_ [l=pt-pt] {<i>nÃ£o hÃ¡ dados</i>}
+_docs_ [l=pt-pt] {documentos}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=pt-pt] {Ajuda}
+_textSearchshort_ [l=pt-pt] {Pesquisa por palavras}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes por tÃ­tulo}
+_textCreatorshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes por autores}
+_textSubjectshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes por assunto}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes por data}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes por ficheiro}
+_textLanguageshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes por lÃ­ngua}
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes por sÃ©ries}
+_textToshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes pelo campo Para}
+_textFromshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes pelo campo De}
+_textBrowseshort_ [l=pt-pt] {listar publicaÃ§Ãµes}
+_textOrganizationshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes por organizaÃ§Ã£o}
+_textHowtoshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes pelas opÃ§Ãµes de "como"}
+_textTopicshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes por tÃ³pico}
+_textPeopleshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes por pessoas}
+_textAcronymshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes por acrÃ³nimos}
+_textPhraseshort_ [l=pt-pt] {navegar por frases que ocorrem nas publicaÃ§Ãµes}
+_textArtistshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes pelos nomes dos artistas}
+_textKeywordshort_ [l=pt-pt] {acesso Ã s publicaÃ§Ãµes por palavra-chave}
+_textVolumeshort_ [l=pt-pt] {aceder Ã s publicaÃ§Ãµes por volume}
+# -- Missing translation: _textCountriesshort_
+_textdefaultshorttext_ [l=pt-pt] {classificaÃ§Ã£o indefinida}
+
+_textSearchlong_ [l=pt-pt] {<p><i>Pesquisar por palavras</i> que
+aparecem no texto da pÃ¡gina "busca". Esta Ã© a primeira pÃ¡gina que
+aparece quando no inÃ­cio, e pode ser acedida a partir das outras pÃ¡ginas pressionando-se
+o botÃ£o <i>pesquisa</i>.  }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=pt-pt] {<p>Para <i>aceder Ã s publicaÃ§Ãµes por tÃ­tulo</i> seleccionar
+o botÃ£o <i>tÃ­tulos a-z</i>.  SerÃ¡ apresnetada uma lista de livros por ordem alfabÃ©tica.  }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=pt-pt] {<p>Para <i>aceder Ã s publicaÃ§Ãµes por autor</i> 
+seleccione o botÃ£o <i>autores a-z</i>.  SerÃ¡ apresentada uma lista de livros,
+ordenada por nome de autores.  }
+
+_textSubjectlong_ [l=pt-pt] {<p>Para <i>aceder Ã s publicaÃ§Ãµes por assuntos</i> 
+seleccionar o botÃ£o <i>assuntos</i>.  SrÃ¡ apresentada uma lista de assuntos,
+representando por estantes de livros.  }
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=pt-pt] {<p>Para <i>aceder Ã s publicaÃ§Ãµes por data</i> seleccioinar
+no botÃ£o <i>datas</i>.  SerÃ¡ apresentada uma lista de todas as ediÃ§Ãµes, ordenadas
+cronologicamente.  }
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=pt-pt] {<p>Pode <i>aceder Ã s publicaÃ§Ãµes por nome de ficheiro</i>
+seleccionando a opÃ§Ã£o <i>ficheiro</i>.  AparecerÃ¡ uma
+lista de nomes de ficheiros originais.  }
+
+_textLanguagelong_ [l=pt-pt] {<p>Pode <i>aceder Ã s publicaÃ§Ãµes por lÃ­ngua</i>
+seleccionando a opÃ§Ã£o <i>lÃ­ngua</i>.  AparecerÃ¡ uma
+lista ordenada de lÃ­nguas.  }
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=pt-pt] {<p>Pode <i>aceder Ã s publicaÃ§Ãµes por organizaÃ§Ã£o</i>
+seleccionando a opÃ§Ã£o <i>organizaÃ§Ã£o</i>.  AparecerÃ¡ uma
+lista de organizaÃ§Ãµes.  }
+
+_textHowtolong_ [l=pt-pt] {<p>Pode <i>aceder Ã s publicaÃ§Ãµes pela lista de "Como"</i>
+seleccionando a opÃ§Ã£o <i>como</i>.  AparecerÃ¡ a lista de termos.  }
+
+_textTopiclong_ [l=pt-pt] {<p>Para <i>aceder Ã s publicaÃ§Ãµes por tÃ³pico</i> 
+selecionar o botÃ£o <i>tÃ³pico</i>.  SerÃ¡ apresentada uma lista de tÃ³picos
+para navegaÃ§Ã£o.  }
+
+_textTolong_ [l=pt-pt] {<p>Pode <i>acede Ã s publicaÃ§Ãµes pelo campo Para</i> 
+selecionando a opÃ§Ã£o <i>para</i>.  AparecerÃ¡ uma lista de endereÃ§os.  }
+
+_textFromlong_ [l=pt-pt] {<p>Pode <i>aceder Ã s publicaÃ§Ãµes pelo campo De</i>
+seleccionando a opÃ§Ã£o <i>de</i>.  AparecerÃ¡ a lista de remetentes.  }
+
+_textSerieslong_ [l=pt-pt] {<p>Para <i>aceder a publicaÃ§Ãµes por sÃ©ries</i> 
+seleccionar o botÃ£o <i>sÃ©ries</i>.  SerÃ¡ apresentada uma lista das sÃ©ries
+que existem na coleÃ§Ã£o.  }
+
+_textBrowselong_ [l=pt-pt] {<p>Para <i>listar publicaÃ§Ãµes</i> seleccione o
+botÃ£o <i>folhear</i>.  }
+
+_textPeoplelong_ [l=pt-pt] {<p>Para <i>aceder Ã s publicaÃ§Ãµes por pessoas</i> 
+seleccciona o botÃ£o <i>pessoas a-z</i>.  SerÃ¡ apresentada uma lista ordenadas por apelido.  }
+
+_textAcronymlong_ [l=pt-pt] {<p>Pode <i>aceder Ã s publicaÃ§Ãµes por acrÃ³nimos</i> 
+seleccionando a opÃ§Ã£o <i>acrÃ³nimos</i>.  SerÃ¡ apresentada a lista de acrÃ³nimos,
+e os locais onde eles ocorrem.  }
+
+_textPhraselong_ [l=pt-pt] {<p>Pode <i>navegar por frases que ocorrem nas publicaÃ§Ãµes</i> 
+seleccionando a opÃ§Ã£o <i>frases</i>.  Esta opÃ§Ã£o usa o navegador de frases phind.  }
+
+_textArtistlong_ [l=pt-pt] {<p>Pode <i>aceder Ã s publicaÃ§Ãµes pelos nomes dos artistas</i> 
+seleccionando a opÃ§Ã£o <i>artistas</i>.  SerÃ¡ apresentada uma lista
+ordenada pelo nomes do artista.  }
+
+_textKeywordlong_ [l=pt-pt] {<p>Pode <i>aceder Ã s publicaÃ§Ãµes por palavra-chave</i>
+seleccionando a opÃ§Ã£o <i>palavras-chave</i>.  AparecerÃ¡ a lista de palavras-chave.  }
+
+_textVolumelong_ [l=pt-pt] {<p>Pode <i>acede Ã s publicaÃ§Ãµes pelo volume</i> 
+selecionando a opÃ§Ã£o <i>volume</i>.  AparecerÃ¡ uma lista de volumes.  }
+
+# -- Missing translation: _textCaptionslong_
+
+# -- Missing translation: _textCountrieslong_
+
+
+_textdefaultlongtext_ [l=pt-pt] {<p>Selecione o botÃ£o <i>nÃ£o encontrado</i> para listar
+publicaÃ§Ãµes (a ordenaÃ§Ã£o Ã© feita por um campo nÃ£o conhecido).  }
+
+
+_textreadingdocs_ [l=pt-pt] {Como ler os documentos}
+
+_texthelpreadingdocs_ [l=pt-pt] {
+<p>Pode-se saber quando se chegou a um documento especifico quando
+o tÃ­tulo ou a imagem da capa aparecerem no topo esquerdo da pÃ¡gina.
+Nalgumas colecÃ§Ãµes aparece tambÃ©m o Ã­ndice, enquanto noutras aparecerÃ¡ 
+apenas o nÃºmero da pÃ¡gina com uma caixa para seleccionar uma nova pÃ¡gina e ir para a frente ou pare trÃ¡s.
+No Ã­ndice, o capÃ­tulo actual Ã© apresentado a negro, e o Ã­ndice Ã© expansÃ­vel.
+
+<p>O texto de cada secÃ§Ã£o aparece sob o Ã­ndice. No final hÃ¡ setas que permitem avanÃ§ar
+para a prÃ³xima secÃ§Ã£o ou recuar para a anterior
+
+<p>Abaixo do tÃ­tulo ou capa hÃ¡ alguns botÃµes. Seleccione <i>expandir
+texto</i> para ver todo o texto do documento actual. Se o 
+documento for grande, isto poderÃ¡ levar muito tempo e usar muita memÃ³ria!
+Seleccione em <i> expandir conteÃºdo</i> para ver todo o Ã­ndice.
+Seleccione em <i>separar</i> para abrir uma nova janela com o
+documento. (Isto Ã© Ãºtil se quiser comparar documentos, ou ler dois ao
+mesmo tempo.)  Finalmente, quando fizer uma pesquisa por palavras as mesmas serÃ£o
+destacadas.  Clique em <i>nÃ£o destacar</i> para retirar os destaques.
+}
+
+# help about the icons
+_texthelpexpandtext_ [l=pt-pt] {Mostrar todo texto, ou nÃ£o}
+_texthelpdetachpage_ [l=pt-pt] {Abrir esta pÃ¡gina numa nova janela}
+_texthelphighlight_ [l=pt-pt] {Destacar termos pesquisados, ou nÃ£o}
+
+_texthelpsearchingtitle_ [l=pt-pt] {Como pesquisar por palavras}
+_texthelpsearching_ [l=pt-pt] {
+<p>
+  Na pÃ¡gina de pesquisa poderÃ¡ fazer uma consulta com estes simples passos:<p>
+  
+  <ol><li>Especifique os itens que quer pesquisar 
+      <li>Diga se quer pesquisar por todas ou apenas algumas palavras 
+      <li>Digite as palavras que quer pesquisar 
+      <li>Seleccione no botÃ£o <i>ComeÃ§ar pesquisa</i>
+  </ol>
+
+<p>Quando fizer uma pesquisa, os tÃ­tulos de vinte documentos serÃ£o apresentados.
+HaverÃ¡ um botÃ£o no final da pÃ¡gina que apresentarÃ¡ os prÃ³ximos vinte documentos.  LÃ¡ encontrarÃ¡ botÃµes para mostrar os prÃ³ximos
+vinte ou voltar para os primeiros vinte, e assim sucessivamente. Para ver um documento seleccione o tÃ­tulo de qualquer documento, 
+ou no pequeno botÃ£o ao lado dele.
+
+<p>Podem ser retornados um mÃ¡ximo de 100 documentos. Pode mudar este nÃºmero nas <i>preferÃªncias</i> no topo da pÃ¡gina.<p>
+}
+
+_texthelpquerytermstitle_ [l=pt-pt] {Termos de Pesquisa }
+_texthelpqueryterms_ [l=pt-pt] {
+<p>Tudo o que digitar na caixa de consulta Ã© interpretado como uma lista de palavras chamada "termos de pesquisa." 
+Cada termo deve conter apenas caracteres e dÃ­gitos. Termos sÃ£o separados por espaÃ§os em branco. Se aparecer qualquer 
+outro caracter, como por exemplo pontuaÃ§Ã£o, ele serÃ¡ usado como separadores de termos, tal como se fossem espaÃ§os. 
+NÃ£o se pode pesquisar palavras que incluam pontuaÃ§Ã£o. 
+
+<p>Por exemplo, a consulta <p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>SerÃ¡ processada como<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}
+
+_texthelpquerytypetitle_ [l=pt-pt] {Tipos de pesquisa}
+_texthelpquerytype_ [l=pt-pt] {
+<p>Existem dois tipos diferentes de pesquisa.
+
+<ul>
+  <li>Pesquisas por <b>todas</b> as palavras.  Esta opÃ§Ã£o procura documentos 
+      que contenham todas as palavras especificadas. Os documentos que
+ satisfaÃ§am a pesquisa serÃ£o apresentados por ordem alfabÃ©tica .<p>
+
+  <li> Pesquisas por <b>algumas</b> das palavras.  Podem-se indicar alguns termos 
+      que se espera existam nos documentos que se procuram. Os documentos sÃ£o apresentados na ordem mais prÃ³xima da pesquisa. 
+O grau de proximidade Ã© determinado
+
+      <p><ul>
+        <li> quanto mais termos um documento contenha, mais prÃ³ximo estarÃ¡;
+        <li> termos raros sÃ£o mais importantes que termos comuns;
+        <li> documentos menores sÃ£o mais relevantes que documentos grandes.
+      </ul>
+</ul>
+
+<p>Podem-se usar quantos termos se quiser - uma frase completa, ou mesmo um parÃ¡grafo completo. Se especificar apenas um termo, ~
+os documentos serÃ£o ordenados por frequÃªncia de ocorrÃªncia.<p>
+}
+
+_textdatesearch_ [l=pt-pt] {Pesquisa com Datas}
+
+_texthelpdatesearch_ [l=pt-pt] {
+A pesquisa por datas permite encontrar documentos que, alÃ©m de verificarem os termos de pesquisa, sÃ£o ainda sobre eventos dentro d eum determinado intervalo de tempo. Pode-se procurar por documentos de um determinado ano ou intervalo de anos. De notar que nÃ£o Ã© necessÃ¡rio usar nenhum termo de pesquisa -- pode-s epesquisar apenas por data; tambÃ©m Ã© possÃ­vel nÃ£o usar data na pesquisa, se tal acontecer a pesquisa serÃ¡ feita sem considerar datas.<p>
+}
+
+_texthelpdatehowtotitle_ [l=pt-pt] {Como usar esta opÃ§Ã£o:}
+_texthelpdatehowto_ [l=pt-pt] {
+<ul>
+   <li>Procurar documentos sobre um determinado ano:<p>
+   <ul>
+       <li>Escreva normalmente o termo de pesquisa. 
+       <li>Escreva a data mais antiga na caixa "Data inicial (ou Ãºnica)".
+       <li>Se a data Ã© antes da era comum (Antes de Cristo) escolha a opÃ§Ã£o E.A.C. no menu ao lado da caixa.
+       <li>Inicie a pesquisa como normalmente.
+   </ul>
+<p><li>Procurar documentos sobre um determinado perÃ­odo:<p>
+   <ul>
+       <li>Escreva normalmente o termo de pesquisa. 
+       <li>Escreva a data mais antiga na caixa "Data inicial (ou Ãºnica)".
+       <li>Escreva a data mais recente na caixa "Data Final".
+       <li>Selecione E.A.C no menu se a data Ã© antes da era comum (Antes de Cristo).
+       <li>Inicie a pesquisa como normalmente.
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=pt-pt] {Como funciona a pesquisa}
+_texthelpdateresults_ [l=pt-pt] {
+Regra geral, uma pesquisa por documentos sobre o ano 1903 nÃ£o encontra documentos sobre livros escritos em 1903, mas apenas documentos sobre o ano 1903. SerÃ£o encontrados ainda documentos que relativos a um intervalo de tempo que inclua 1903 (como por exemplo 1899-1911), assim como documentos relativos ao sÃ©culo (por exemplo, "sÃ©culo vinte" ou "sÃ©culo 20" para o ano 1903). Isto quer dizer que alguns documentos encontrados poderÃ£o nÃ£o referir explicitamente no texto a data de pesquisa. Para uma pesquisa com um intervalo de tempo, isto aplica-se a todas as data no intervalo.<p>
+}
+
+_textchangeprefs_ [l=pt-pt] {Mudar as preferÃªncias }
+
+_texthelppreferences_ [l=pt-pt] {
+<p>Seleccionando o botÃ£o <i>preferÃªncias</i> no topo da pÃ¡gina, serÃ¡
+possÃ­vel mudar alguns aspectos da interface segundo as suas preferÃªncias.
+}
+
+_texthelpcollectionprefstitle_ [l=pt-pt] {PreferÃªncias da colecÃ§Ã£o}
+_texthelpcollectionprefs_ [l=pt-pt] {
+Algumas colecÃ§Ãµes incluem vÃ¡rias sub-colecÃ§Ãµes, as quais podem ser pesquisadas
+independentemente ou juntas, como uma Ãºnica unidade. Nesses casos pode seleccionar na
+pÃ¡gina de PreferÃªncias que sub-colecÃ§Ãµes incluir nas pesquisas.
+}
+
+_texthelplanguageprefstitle_ [l=pt-pt] {PreferÃªncia de LÃ­ngua}
+_texthelplanguageprefs_ [l=pt-pt] {
+Cada colecÃ§Ã£o tem uma lÃ­ngua de apresentaÃ§Ã£o por omissÃ£o, mas pode-se mudar 
+para outra lÃ­ngua se pretendido. Pode-se alterar tambÃ©m o esquema de codificaÃ§Ã£o 
+usado pelo Greenstone para enviar a informaÃ§Ã£o para o browser -- o software escolhe 
+omissÃµes normais, mas nalguns browsers podem-se obter melhores resultados visuais 
+seleccionando outros esquemas de codificaÃ§Ã£o. Todas as colecÃ§Ãµes permitem mudar da 
+interface grÃ¡fica normal para uma interface textual. Esta opÃ§Ã£o Ã© especialmente Ãºtil 
+para utilizadores com problemas de visÃ£o, que usem fontes grandes ou sintetizadores 
+de voz
+}
+
+_texthelppresentationprefstitle_ [l=pt-pt] {PreferÃªncias de apresentaÃ§Ã£o}
+_texthelppresentationprefs_ [l=pt-pt] {
+Dependendo da colecÃ§Ã£o em causa, poderÃ£o existir opÃ§Ãµes que se podem definir para controlar a apresentaÃ§Ã£o. 
+
+As colecÃ§Ãµes de pÃ¡ginas Web permitem suprimir a barra de navegaÃ§Ã£o Greenstone no topo de cada pÃ¡gina, 
+pelo que quando uma pesquisa os documentos encontrados aparecerÃ£o sem nenhum cabeÃ§alho Greenstone. 
+Para fazer outra pesquisa terÃ¡ que usar o botÃ£o "back" do seu browser. Estas colecÃ§Ãµes tambÃ©m possibilitam
+suprimir as mensagens de avisos Greenstone quando seleccionar um link para fora da colecÃ§Ã£o da biblioteca digital.
+Nalgumas colecÃ§Ãµes podem-se controlar quaisquer links na pÃ¡gina de "Resultados de Pesquisa" para ir 
+directamente para a URL em questÃ£o, ao invÃ©s de ir para as cÃ³pias das pÃ¡ginas na biblioteca digital.
+}
+
+_texthelpsearchprefstitle_ [l=pt-pt] {PreferÃªncias de pesquisa }
+_texthelpsearchprefs_ [l=pt-pt] {
+Dois pares de botÃµes permitem controlar a forma como o texto Ã© interpretado na pesquisas. 
+O primeiro grupo de botÃµes ("maiÃºsculas/minÃºsculas) controlam quando se devem verificar 
+maiÃºsculas ou  minÃºsculas.  O segundo grupo ("terminaÃ§Ãµes de palavras") controla quando se deve ignorar ou nÃ£o qualquer final de palavras. 
+Ã espantosamente rÃ¡pido como se pode pesquisa em grandes quantidades de texto.
+
+<p>Por exemplo, se os botÃµes <i>ignorar maiÃºsculas/minÃºsculas/i> e
+<i>ignorar terminaÃ§Ãµes de palavras </i> estiverem seleccionados, a pesquisa <p>
+    <ul><kbd>African building</kbd></ul>
+      <p>serÃ¡ tratada como <p>
+      <ul><kbd>africa builds</kbd></ul><p>
+      porque as letras maiÃºsculas em "African" serÃ£o transformadas para 
+      minÃºsculas, e os sufixos "n" e "ing" serÃ£o removidos de 
+      "African" e "building" respectivamente (os "s" serÃ£o tambÃ©m removidos de 
+      "builds").
+
+<p>TambÃ©m se pode mudar para o modo "avanÃ§ado" de consulta que possibilitarÃ¡ 
+combinar termos usando AND (&), OR (|), e NOT (!). Isto darÃ¡ resultados mais precisos. 
+Seleccionando a opÃ§Ã£o de histÃ³rico de pesquisa recuperam-se as Ãºltimas pesquisas.
+Finalmente, pode-se controlar o nÃºmero de resultados retornados, e o nÃºmero de
+resultados por pÃ¡gina.}
+
+_texttanumbrowseoptions_ [l=pt-pt] {Existem _numbrowseoptions_ formas de encontrar informaÃ§Ã£o nesta colecÃ§Ã£o:}
+
+_textsimplehelpheading_ [l=pt-pt] {Como encontrar informaÃ§Ã£o na colecÃ§Ã£o _collectionname_}
+
+_texthelpscopetitle_ [l=pt-pt] {AbrangÃªncia das consultas}
+_texthelpscope_ [l=pt-pt] {
+<p>
+Na maioria das coleÃ§Ãµes podem-se escolher diferentes indices de pesquisa. Por exemplo, podem existir indeces de autores ou de tÃ­tulos. Ou podem ser Ã­ndices de capÃ­tulos ou parÃ¡grafos. Geralmente sÃ£o retornados todos os documentos que verifiquem as condiÃ§Ãµes de pesquisa, dependendo do Ã­ndice.
+<p>Se os documentos sÃ£o livros, os mesmos serÃ£o abertos no local apropriado.
+}
Index: /gsdl/stable/macros/pref.dm
===================================================================
--- /gsdl/stable/macros/pref.dm	(revision 20131)
+++ /gsdl/stable/macros/pref.dm	(revision 20131)
@@ -0,0 +1,558 @@
+# this file must be UTF-8 encoded
+
+package preferences
+
+# set within server
+
+# collectionoption is only set when cross-collection searching is turned on
+_collectionoption_ {}
+
+# this macro will be set to "1" when the "source docs retrived from dl/web
+# button is required - i.e. whenever PreferenceDocsFromWeb isn't set to false
+# in collect.cfg
+_PreferenceDocsFromWeb_ {}
+
+# this macro will be set to _textprefschanged_ when the "set preferences"
+# button has been pressed
+_prefschanged_ {}
+
+#######################################################################
+# global navigation links
+#######################################################################
+
+# this is overridden here as we don't want a 'preferences' link on this page
+
+_globallinks_ {_homelink_ _helplink_}
+
+#######################################################################
+# scripts
+# note that changing either the "m" or the "o" argument
+# from the preferences page necessitates reseting the "r"
+# argument to 1
+#######################################################################
+
+_ccsfunctions_ {argcc = "";
+savedccs = new Object();
+
+function initialize () \{
+  for (i = 0; i < document.links.length; i++)
+    savedhrefs[i] = document.links[i].href;
+
+  s = "_cgiargcc_";
+  a = s.split (",");
+  for (i = 0; i < a.length ;i++) \{
+    for (j = 0; j < document.PrefForm.cc.length; j++) \{
+      if (a[i] == document.PrefForm.elements["cc"][j].value) \{
+        document.PrefForm.elements["cc"][j].checked = true;
+        savedccs[a[i]] = 1;
+	argcc = argcc + "&cc=" + a[i];
+        break;
+      \} else \{
+        savedccs[a[i]] = 0;
+      \}
+    \}
+  \}
+  updatehrefs();
+\}
+
+function updatecc (collection) \{
+  if (savedccs[collection] == 1) savedccs[collection] = 0;
+  else savedccs[collection] = 1;
+       
+  var i;
+  argcc = "";
+  var changed = 0;
+  for (i in savedccs)
+    if (savedccs[i] == 1) \{
+       argcc += "&cc=" + i;
+       changed = 1;
+    \}
+  if (changed == 1) argcc += "&r=1";
+  updatehrefs();
+\}
+}
+
+_standardfunctions_ {
+function initialize () \{
+  for (i = 0; i < document.links.length; i++)
+    savedhrefs[i] = document.links[i].href;
+
+\}
+
+}
+
+_getargsfunction_ {
+function getargs () \{
+  return argk + args + argaf + argm + argo + argrd + arghd + argb + argqb + argfqn + argqt_If_(_collectionoption_,_ccsargs_)_If_(_htmloptions_,_htmlargs_);
+\}
+}
+
+_ccsargs_ {+ argcc}
+_htmlargs_ {+ argel + argil + argfc + arghl}
+
+_htmlfunctions_ {argel = "";
+argil = "";
+argfc = "";
+arghl = "";
+
+function updateel () \{
+  value = document.PrefForm.el.options[document.PrefForm.el.selectedIndex].value;
+  if (value != "_cgiargel_") argel = "&el=" + value;
+  else argel = "";
+  updatehrefs();
+\}
+
+function updateil () \{
+  value = document.PrefForm.il.options[document.PrefForm.il.selectedIndex].value;
+  if (value != "_cgiargil_") argil = "&il=" + value;
+  else argil = "";
+  updatehrefs();
+\}
+
+function updatefc(value) \{
+  if (value != _cgiargfc_) argfc = "&fc=" + value + "&f=" + value;
+  else argfc = "";
+  updatehrefs();
+\}
+
+function updatehl(value) \{
+  if (value != _cgiarghl_) arghl = "&hl=" + value;
+  else arghl = "";
+  updatehrefs();
+\}
+}
+
+_pagescriptextra_ {
+// preferences scripts generated from \_preferences:pagescriptextra\_
+
+savedhrefs = new Object();
+
+argk = "";
+args = "";		
+argm = "";
+argrd = "";
+argo = "";
+argb = "";
+arghd = "";
+argqb = "";
+argfqn = "";
+argqt= "";
+argaf = "";
+
+_If_(_collectionoption_,_ccsfunctions_,_standardfunctions_)
+_If_(_htmloptions_,_htmlfunctions_)
+_getargsfunction_
+function updatehrefs () \{
+  for (i = 0; i < document.links.length; i++)
+    document.links[i].href = savedhrefs[i] + getargs();
+\}
+
+function updatek (value) \{
+  if (value != _cgiargk_) argk = "&k=" + value;
+  else argk = "";
+  updatehrefs();
+\}
+
+function updates (value) \{
+  if (value != _cgiargs_) args = "&s=" + value;
+  else args = "";
+  updatehrefs();
+\}
+
+function updateaf (value) \{
+  if (value != _cgiargaf_) argaf = "&af=" + value;
+  else argaf = "";
+  updatehrefs();
+\}
+
+function updatem () \{
+  value = document.PrefForm.m.options[document.PrefForm.m.selectedIndex].value;
+  if (value != _cgiargm_) argm = "&r=1&m=" + value;
+  else argm = "";
+  updatehrefs();
+\}
+
+function updaterd () \{
+  if (document.PrefForm.rd.checked)
+    _If_("_cgiargrd_" eq "1",argrd="";,argrd="&rd=1";)
+  else 
+    _If_("_cgiargrd_" ne "1",argrd="";,argrd="&rd=0";)
+  updatehrefs();
+\}
+
+function updateo () \{
+  value = document.PrefForm.o.options[document.PrefForm.o.selectedIndex].value;
+  if (value != _cgiargo_) argo = "&r=1&o=" + value;
+  else argo = "";
+  updatehrefs();
+\}
+
+function updateqt (value) \{
+  if (value != "_cgiargqt_") argqt = "&qt=" + value;
+  else argqt = "";
+  updatehrefs();
+\}
+
+function updatefqn () \{
+  value = document.PrefForm.fqn.options[document.PrefForm.fqn.selectedIndex].value;
+  if (value != _cgiargfqn_) argfqn = "&fqn=" + value;
+  else argfqn = "";
+  updatehrefs();
+\}
+
+function updateb (value) \{
+  if (value != _cgiargb_) argb = "&b=" + value;
+  else argb = "";
+  updatehrefs();
+\}
+
+function updatehd() \{
+  arghd="";
+  if (document.PrefForm.hd[0].checked) \{
+     if ("_cgiarghd_" != "0") arghd = "&hd=0";
+  \}
+  else \{
+     value = document.PrefForm.hdn[document.PrefForm.hdn.selectedIndex].value;
+     if (_cgiarghd_ != value) arghd = "&hd="+value;
+  \}
+  updatehrefs();
+\}
+
+
+function updateqb() \{
+
+   value = document.PrefForm.qb.options[document.PrefForm.qb.selectedIndex].value;
+   if (value != _cgiargqb_) argqb = "&qb=" + value;
+  else argqb = "";
+   updatehrefs();
+\}
+
+function updatel () \{
+  value = document.PrefForm.l.options[document.PrefForm.l.selectedIndex].value;
+  href = location.href;
+  if (href.match(/&l=[\\w\\-]+/)) href = href.replace(/&l=[\\w\\-]+/, "&l=" + value);
+  else href += "&l=" + value;
+  if (!location.href.match(/&nl=1$/)) href += "&nl=1";
+  while (href.match(/&cc=[\\w]+/)) href = href.replace(/&cc=[\\w]+/, "");
+  location.href = href + getargs();
+\}
+
+function updatev () \{
+  value = document.PrefForm.v.options[document.PrefForm.v.selectedIndex].value;
+  href = location.href;
+  if (href.match(/&v=\\d/)) href = href.replace(/&v=\\d/, "&v=" + value);
+  else href += "&v=" + value;
+  while (href.match(/&cc=[\\w]+/)) href = href.replace(/&cc=[\\w]+/, "");
+  location.href = href + getargs();
+\}
+
+function updatew () \{
+  value = document.PrefForm.w.options[document.PrefForm.w.selectedIndex].value;
+  href = location.href;
+  if (href.match(/&nw=[^&]+/)) href = href.replace(/&nw=[^&]+/, "&nw=" + value);
+  else href += "&nw=" + value;
+  if (!location.href.match(/&nl=0$/)) href += "&nl=0";
+  while (href.match(/&cc=[\\w]+/)) href = href.replace(/&cc=[\\w]+/, "");
+  location.href = href + getargs();
+\}
+
+function updatebook () \{
+  value = document.PrefForm.book.options[document.PrefForm.book.selectedIndex].value;
+  href = location.href;
+  if (href.match(/&book=[^&]+/)) href = href.replace(/&book=[^&]+/, "&book=" + value);
+  else href += "&book=" + value;
+  while (href.match(/&cc=[\\w]+/)) href = href.replace(/&cc=[\\w]+/, "");
+  location.href = href + getargs();
+\}
+
+}
+
+#######################################################################
+# headers
+# these are overridden so we can put an onLoad event handler
+# in the <body> tag of this page
+#######################################################################
+
+
+_header_ {_cgihead_
+_htmlhead_(class="bgimage" onLoad="initialize();")_startspacer__pagebanner_
+}
+
+# this declaration ends up being the same as style=restrict, never mind
+_header_[v=1] {_cgihead_
+_htmlhead_(onLoad="initialize();")_pagebanner_
+}
+
+
+#######################################################################
+# page content
+#######################################################################
+
+_pagetitle_ {_collectionname_: _textpreferences_}
+_imagethispage_ {_textpreferences_}
+
+_htmloptions_ {}
+
+_htmloptionson_ {
+<p>
+<tr>_fcoption_</tr>
+<p>
+<tr>_hloption_</tr>
+<p>
+<tr>_extlinkoption_</tr>
+_If_(_PreferenceDocsFromWeb_,<p>
+<tr>_intlinkoption_</tr>)
+}
+
+_fcoption_ {
+<td valign=baseline>Document page layout</td>
+<td><input type=radio name=fc value=1 onClick="updatefc(1);"
+		_If_(_cgiargfc_, checked)>navigation bar at top<br>
+<input type=radio name=fc value=0 onClick="updatefc(0);"
+		_If_(_cgiargfc_,, checked)>no navigation bar</td>
+}
+
+_hloption_ {
+<td valign=baseline>Search term highlighting</td>
+<td><input type=radio name=hl value=1 onClick="updatehl(1);"
+		_If_(_cgiarghl_, checked)>highlight search terms<br>
+<input type=radio name=hl value=0 onClick="updatehl(0);"
+		_If_(_cgiarghl_,, checked)>don't highlight search terms</td>
+}
+
+#search pref options
+
+
+# search type option 
+_searchtypeoptionplain_ {
+<td valign=baseline>_textsearchtype_</td>
+<td>_textplainsearchtype_</td>
+}
+_searchtypeoptionform_ {
+<td valign=baseline>_textsearchtype_</td>
+<td>_textformsearchtype_</td>
+}
+_searchtypeoptionboth_ {
+<td valign=baseline>_textsearchtype_</td>
+<td><input type=radio name=qt value=0 onClick="updateqt(0);"
+		_If_(_cgiargqt_,, checked)>_textplainsearchtype_<br>
+<input type=radio name=qt value=1 onClick="updateqt(1);"
+		_If_(_cgiargqt_, checked)>_textformsearchtype_</td>
+}
+
+_boxsizeoption_{
+<select name="qb" onChange="updateqb();">
+  <option value="0"_If_("_cgiargqb_" eq "0", selected)>_textregularbox_
+  <option value="1"_If_("_cgiargqb_" eq "1", selected)>_textlargebox_
+</select>
+}
+
+_formnumfieldoption_ {
+<select name="fqn" onChange="updatefqn();">
+  <option value="2"_If_("_cgiargfqn_" eq "2", selected)>2  
+  <option value="4"_If_("_cgiargfqn_" eq "4", selected)>4
+  <option value="6"_If_("_cgiargfqn_" eq "6", selected)>6
+  <option value="8"_If_("_cgiargfqn_" eq "8", selected)>8
+</select>
+}
+
+_modeoption_ {
+<td valign=baseline>_textquerymode_</td>
+<td><input type=radio name=b value=0 onClick="updateb(0);"
+		_If_(_cgiargb_,, checked)>_textsimplemode_<br>
+<input type=radio name=b value=1 onClick="updateb(1);"
+		_If_(_cgiargb_, checked)>_textadvancedmode_</td>
+}
+
+_caseoption_ {
+<td valign=baseline>_textcasediffs_</td>
+<td><input type=radio name=k value=1 onClick="updatek(1);"
+		_If_(_cgiargk_, checked)>_textignorecase_<br>
+<input type=radio name=k value=0 onClick="updatek(0);"
+		_If_(_cgiargk_,, checked)>_textmatchcase_</td>
+}
+
+_caseoption_ [l=ar] {}
+_caseoption_ [l=zh] {}
+
+_stemoption_ {
+<td valign=baseline>_textwordends_</td>
+<td><input type=radio name=s value=1 onClick="updates(1);"
+  _If_(_cgiargs_, checked)>_textstem_<br>
+<input type=radio name=s value=0 onClick="updates(0);"
+  _If_(_cgiargs_,, checked)>_textnostem_</td>
+}
+
+_stemoption_ [l=zh] {}
+
+_accentoption_ {
+<td valign=baseline>_textaccentdiffs_</td>
+<td><input type=radio name=af value=1 onClick="updateaf(1);"
+  _If_(_cgiargaf_, checked)>_textignoreaccents_<br>
+<input type=radio name=af value=0 onClick="updateaf(0);"
+  _If_(_cgiargaf_,, checked)>_textmatchaccents_</td>
+}
+
+_searchhistoryop_ {
+<td valign=baseline>_textsearchhistory_</td>
+<td><input type=radio name="hd" value=0 onClick="updatehd();"
+                _If_("_cgiarghd_" eq "0", checked)>_textnohistorydisplay_<br>
+<input type=radio name="hd" value=1 onClick="updatehd();"
+		_If_("_cgiarghd_" eq "0",, checked)>_texthistorydisplay_</td>   
+}
+
+_relateddocop_ {
+<td colspan=2><nobr><input type=checkbox name="rd" value=1 onClick="updaterd();" _If_("_cgiargrd_" eq "1", checked)>
+Display related documents</nobr></td>
+}
+
+_historynumrecords_{<select name="hdn" onChange="updatehd();">
+    <option value="5"_If_("_cgiarghd_" eq "5", selected)>5
+    <option value="10"_If_("_cgiarghd_" eq "10", selected)>10
+    <option value="15"_If_("_cgiarghd_" eq "15", selected)>15
+    <option value="20"_If_("_cgiarghd_" eq "20", selected)>20
+</select>}
+
+_maxdocoption_ {
+<select name="m" onChange="updatem();">
+  <option value="50"_If_("_cgiargm_" eq "50", selected)>50
+  <option value="100"_If_("_cgiargm_" eq "100", selected)>100
+  <option value="200"_If_("_cgiargm_" eq "200", selected)>200
+  <option value="-1"_If_("_cgiargm_" eq "-1", selected)>_textall_
+</select>
+}
+
+_hitsperpageoption_ {
+<select name="o" onChange="updateo();">
+  <option value="10"_If_("_cgiargo_" eq "10", selected)>10  
+  <option value="20"_If_("_cgiargo_" eq "20", selected)>20
+  <option value="50"_If_("_cgiargo_" eq "50", selected)>50
+  <option value="-1"_If_("_cgiargo_" eq "-1", selected)>_textall_
+</select>
+}
+
+_extlinkoption_ {
+<td>_textextlink_</td>
+<td><select name="el" onChange="updateel();">
+  <option value="prompt"_If_("_cgiargel_" eq "prompt", selected)>
+     _textlinkinterm_
+  <option value="direct"_If_("_cgiargel_" eq "direct", selected)>
+     _textlinkdirect_
+</select></td>
+}
+
+_intlinkoption_ {
+<td>_textintlink_</td>
+<td><select name="il" onChange="updateil();">
+  <option value="l"_If_("_cgiargil_" eq "l", selected)>
+     _textdigitlib_
+  <option value="w"_If_("_cgiargil_" eq "w", selected)>
+     _textweb_
+</select></td>
+}
+
+# set from within pageaction
+_languageoption_ {}
+_encodingoption_ {}
+
+_formatoption_ {
+<td>_textformat_</td>
+<td><select name="v" onChange="updatev();">
+  <option value="0"_If_("_cgiargv_" eq "0", selected)>_textgraphical_
+  <option value="1"_If_("_cgiargv_" eq "1", selected)>_texttextual_
+</select></td>
+}
+
+
+_bookoption_ {
+<td valign=baseline>_textbookoption_</td>
+<td><select name="book" onChange="updatebook();">
+	<option value="off"_If_("_cgiargbook_" eq "off", selected)>_textbookvieweroff_
+	<option value="on"_If_("_cgiargbook_" eq "on", selected)>_textbookvieweron_
+</select></td>
+}
+
+_content_ {
+
+_optnavigationbar_
+_If_(_prefschanged_,<p>_prefschanged_<br><div class="divbar">&nbsp;</div>)
+
+<form name=PrefForm method=get action="_gwcgi_">
+<input type="hidden" name="e" value="_decodedcompressedoptions_">
+_If_(_collectionoption_,_collectionprefs_)
+_presentationprefs_
+_searchprefs_
+</form>
+}
+
+#search prefs 
+_searchprefs_ {
+<table border=0 cellpadding=0 cellspacing=0 width=_pagewidth_><tr>
+<td><h3>_textsearchprefs_</h3></td>
+<td align=right><input type=submit name="bp" value="_textsetprefs_"></td>
+</tr></table>
+<blockquote>
+
+<table>
+<tr>_modeoption_</tr>
+
+<tr>_querytypedependantoptions_</tr>
+
+_If_("_cgiargks_" eq "1",
+<tr>_caseoption_</tr>
+)
+_If_("_cgiargss_" eq "1",
+<tr>_stemoption_</tr>
+)
+_If_("_cgiargafs_" eq "1",
+<tr>_accentoption_</tr>
+)
+<tr>_searchhistoryop_</tr>
+
+<!--
+Don't include this for now
+<tr>_relateddocop_</tr>
+-->
+
+<tr><td colspan=2>_textprefop_</td></tr>
+</table>
+</blockquote>
+<div class="divbar">&nbsp;</div>
+}
+
+_querytypedependantoptions_ {
+_If_("_cgiargct_" eq "0",_searchtypeoptionplain_,_mgppqueryoptions_)
+}
+_mgppqueryoptions_ {
+_If_("_cgiargqto_" eq "1", _searchtypeoptionplain_)
+_If_("_cgiargqto_" eq "2", _searchtypeoptionform_)
+_If_("_cgiargqto_" eq "3", _searchtypeoptionboth_)
+}
+
+# should this go somewhere??
+#<noscript><tr><td colspan=2><b>_query:textnojsformwarning_</b></td></tr></noscript>
+
+_collectionprefs_ {
+<h3>_textcollectionprefs_</h3>
+<blockquote>
+_collectionoption_
+</blockquote>
+<div class="divbar">&nbsp;</div>
+}
+
+_presentationprefs_ {
+<h3>_textpresentationprefs_</h3>
+<blockquote>
+<table>_htmloptions_
+
+_If_(_languageoption_,<tr><td>_textlanguage_</td><td>_languageoption_</td></tr>)
+
+_If_(_encodingoption_,<tr><td>_textencoding_</td><td>_encodingoption_</td></tr>)
+
+<tr>_formatoption_</tr>
+_If_("_tidyoption_" ne "untidy",<tr>_bookoption_</tr>)
+</table>
+</blockquote>
+<div class="divbar">&nbsp;</div>
+}
+
Index: /gsdl/stable/macros/pushto.dm
===================================================================
--- /gsdl/stable/macros/pushto.dm	(revision 20131)
+++ /gsdl/stable/macros/pushto.dm	(revision 20131)
@@ -0,0 +1,980 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# English Language text and icon macros 
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=ps] {ÙŸØ±ÙÙ ÙŸØ³Û Ø®ÙŸØ±ÙÙÛ}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=ps] {Ø¯Ø³Ø±ÚÛÙÛ ÛØ§Ø¯ÙÙÙ:}  
+_textdate_ [l=ps] {Ø¯Ø®ÙŸØ±ÙÙÛ ÙÛÙŒÙ:}  
+_textnumpages_ [l=ps] {Ø¯Ù
+Ø®ÙÙÙ ØŽÙ
+ÛØ±Û:}  
+
+_textsignin_ [l=ps] {ÙÙÙØªÙÙ}  
+
+_textdefaultcontent_ [l=ps] {Ø¯ØºÙ ÙÚØ§ÙØ¯ÛØ² ØŽÙÛ Ù
+Ø® ÙŸÛØ¯Ø§ÙØŽÙ. Ù
+ÙØ±ØšØ§ÙÛ ÙÚ©ÚÛ Ø¯Ø®ÙŸÙ Ú©ØªÙ
+ÙÙ Ø¯ 'ØŽØ§ØªÙ' ØªÚŒÛ ÙŸÚ©Ø§Ø± ÙØ§ÚÙÛ Ø§ÙÛØ§ Ø¯Ú©ÙØ± ØªÚŒÛ ÙŸÚ©Ø§Ø± ÙØ§ÚÙÛ ØªØ±Ú
+Ù Ø¯Ú«Ø±ÛÙ Ø³ÙŒÙÙ ÚÛØ¬ÛÙŒÙ Ú©ØªØ§ØšØªÙÙ ØªÙ Ø±Ø§ÙÚ«Ø±ÚÛ.}  
+
+_textdefaulttitle_ [l=ps] {Ø¯GSDL ØºÙØ·Û}  
+
+_textbadcollection_ [l=ps] {Ø¯ØºÙ ÙŒÙÙÚ«Ù ÚÛ ("_cvariable_"ÙÙÙ
+ÛÚÛ) Ø¯Ø¯Û Ú«Ø±ÛÙ Ø³ÙŒÙÙ Ú©ØªØ§ØšØªÙÙ ÙŸÙ ÚÛØ¬ÛÙŒÙ Ø³ÛØ³ÙŒÙ
+ Ú©Û ÙØ¯Ù ÙŸÙØ±ØªÙ ØŽÙÛ.}  
+
+
+
+_collectionextra_ [l=ps] {Ø¯ØºÙ ÙŒÙÙÚ«Ù ÙØ±ÙÙÚ©Û Ø¯ _about:numdocs_Ø§Ø³ÙØ§Ø¯ÙØ¯Ù. Ø¯Ø§ÙØ±ÙØ³ØªÛ ÚÙ ÙÙŸØ§Ø±Ù _about:builddate_ÙØ±ÚÛ Ù
+Ø®Ú©Û Ø¬ÙÚ Ù ØŽÙÛ ÙÙ.}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+
+
+_textdescrcollection_ [l=ps] {}
+_textdescrabout_ [l=ps] {Ø¯Ù
+Ø® ÙŸÙ Ø§ÚÙ}  
+_textdescrhome_ [l=ps] {Ú©ÙØ±ÙŸØ§ÚŒÙ}  
+_textdescrhelp_ [l=ps] {ÙØ§Ø±ÚÙØ¯ Ù
+Ø®}  
+_textdescrpref_ [l=ps] {Ø¯Ø®ÙÚÛ Ù
+Ø®}  
+
+_textdescrusab_ [l=ps] {Ø¯Ø§Ø³ØªØ¹Ù
+Ø§Ù ÙÙŸØ§Ø±Ù Ø¯Ú
+Ù Ù
+ØŽÚ©Ù Ø³Ø±Ù Ù
+Ø®Ø§Ù
+Ø® ØŽÙÛ}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=ps] {ÙŸÙÙŒÙÙ}  
+_labelSearch_ [l=ps] {ÙŸÙÙŒÙÙ}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=ps] {Ø¹ÙÙØ§Ù}  
+_labelTitle_ [l=ps] {Ø¹ÙÙØ§ÙÙÙÙ}  
+_textCreator_ [l=ps] {Ù
+ÙÚØªÙ Ø±Ø§ÙÚÙÙÚ©Û}  
+_labelCreator_ [l=ps] {Ù
+ÙÚØªÙ Ø±Ø§ÙÚÙÙÚ©Û}  
+_textSubject_ [l=ps] {Ù
+Ø¶Ù
+ÙÙ}  
+_labelSubject_ [l=ps] {Ù
+Ø¶Ù
+ÙÙÙÙÙ}  
+_textDescription_ [l=ps] {ØªØŽØ±ÛØ­}  
+_labelDescription_ [l=ps] {ØªØŽØ±ÛØ­Ø§Øª}  
+_textPublisher_ [l=ps] {Ø®ÙŸØ±ÙÙÙÚ©Û}  
+_labelPublisher_ [l=ps] {Ø®ÙŸØ±ÙÙÙÚ©Û}  
+_textContributor_ [l=ps] {Ù
+Ø±Ø³ØªÛØ§ÙØ§Ù}  
+_labelContributor_ [l=ps] {Ù
+Ø±Ø³ØªÛØ§ÙØ§Ù}  
+_textDate_ [l=ps] {ÙÛÙŒÙ}  
+_labelDate_ [l=ps] {ÙÛÙŒÛ}  
+_textType_ [l=ps] {ÚÙÙ}  
+_labelType_ [l=ps] {ÚÙÙÙÙÙ}  
+_textFormat_ [l=ps] {Ø¬ÙÚÚØª}  
+_labelFormat_ [l=ps] {ØšÚŒÛ }  
+_textIdentifier_ [l=ps] {ÙŸÛÚÙØ¯ÙÙÚ©Û}  
+_labelIdentifier_ [l=ps] {ÙŸÛÚÙØ¯ÙÙÚ©Û}  
+_textSource_ [l=ps] {Ø¯Ø¯ÙØ³ÛÛ (Ù
+ÙÙ) ÙÙÙ
+}  
+_labelSource_ [l=ps] {Ø¯Ø¯ÙØ³ÛÙ(Ù
+ÙÙ) ÙÙÙ
+ÙÙÙ}  
+_textLanguage_ [l=ps] {ÚØšÙ}  
+_labelLanguage_ [l=ps] {ÚØšÛ}  
+_textRelation_ [l=ps] {Ø§ÚÛÚ©Ù}  
+_labelRelation_ [l=ps] {Ø§ÚÛÚ©Û}  
+_textCoverage_ [l=ps] {Ø§Ø­ØªÙØ§}  
+_labelCoverage_ [l=ps] {Ø§Ø­ØªÙØ§}  
+_textRights_ [l=ps] {Ø­ÙÙÙ}  
+_labelRights_ [l=ps] {Ø­ÙÙÙ}  
+
+# DLS metadata set
+_textOrganization_ [l=ps] {Ø§Ø¯Ø§Ø±Ù}  
+_labelOrganization_ [l=ps] {Ø§Ø¯Ø§Ø±Û}  
+_textKeyword_ [l=ps] {Ø¯ÙŸÙÙŒÙÛ ÙŒÚ©Û}  
+_labelKeyword_ [l=ps] {Ø¯ÙŸÙÙŒÙÛ ÙŒÚ©Û}  
+_textHowto_ [l=ps] {Ú
+ÙÚ«Ù}  
+_labelHowto_ [l=ps] {Ú
+ÙÚ«Ù}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=ps] {ÙÛÙ
+Ú«ÚÛ Ø¬Ù
+ÙÙ}  
+_labelPhrase_ [l=ps] {ÙÛÙ
+Ú«ÚÛ Ø¬Ù
+ÙÛ}  
+
+_labelCollage_ [l=ps] {Ú«Ú Ø±ÙÚ«ÙÙÙ}  
+_textBrowse_ [l=ps] {Ø³Ø±Ø³Ø±Û Ú©ØªÙÙ}  
+_labelBrowse_ [l=ps] {Ø³Ø±Ø³Ø±Û Ú©ØªÙÙ}  
+_textTo_ [l=ps] {ØªØ±}  
+_labelTo_ [l=ps] {ØªØ±}  
+_textFrom_ [l=ps] {ÙÙ}  
+_labelFrom_ [l=ps] {ÙÙ}  
+_textAcronym_ [l=ps] {Ø¯ÙÙÙ
+ÙÙÙ ÙÙÚÛØ²}  
+_labelAcronym_ [l=ps] {Ø¯ÙÙÚÛØ² ÙÙÙ
+ÙÙÙ}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=ps] {Ø³Ø±Ø³Ø±Û Ú©ØªÙ ÙŸÙ _1_ Ø³Ø±Ù}  
+
+_textdescrSearch_ [l=ps] {ÙŸÙÙŒÙÙ Ø¯Ø®Ø§ØµÛ Ø§ØµØ·ÙØ§Ø­ ÙÙŸØ§Ø±Ù}  
+_textdescrType_ [l=ps] {Ø³Ø±Ø³Ø± Û Ú©ØªÙÙ ÙØžØ± Ø¯ Ù
+ÙØ§Ø¯Ù ÚÙÙ ØªÙ}  
+_textdescrIdentifier_ [l=ps] {Ø³Ø±Ø³Ø±Û Ú©ØªÙÙ Ø¯ÙŸÛÚÙØ¯ÙÙÚ©Ù Ù
+ÙØ§Ø¯Ù ÙÙ ÙØžØ±Ù}  
+_textdescrSource_ [l=ps] {Ø³Ø±Ø³Ø±Û Ú©ØªÙÙ Ø¯Ø§ØµÙÛ Ø¯ÙØ³ÛÛ Ø¯ÙÙÙ
+ ÙÙŸØ§Ø±Ù}  
+_textdescrTo_ [l=ps] {Ø³Ø±Ø³Ø±Û Ú©ØªÙ ÙØžØ± ÙØ³Ø§Ø­Û ØªÙ}  
+_textdescrFrom_ [l=ps] {Ø³Ø±Ø³Ø±Û Ú©ØªÙ ÙØžØ± Ø³Ø§Ø­Û ØªÙ}  
+_textdescrCollage_ [l=ps] {Ø³Ø±Ø³Ø±Û Ú©ØªÙÙ Ø¯Ø§ÙÚÙØ± Ø¯Ú«ÚÙ Ø±ÙÚ«ÙÙÙÙÙ ÙØžØ±Ù}  
+_textdescrAcronym_ [l=ps] {Ø¯ÙÙÙ
+ÙÙÙ Ø¯ÙÙÚÛØ²ÙÙÙ Ø³Ø±Ø³Ø±Û Ú©ØªÙÙ}  
+_textdescrPhrase_ [l=ps] {Ø¯ÙÛÙ
+Ú«ÚÙ Ø¬Ù
+ÙÙ Ú©ØªÙÙ
+Ù}  
+_textdescrHowto_ [l=ps] {Ø³Ø±Ø³Ø±Û Ú©ØªÙÙ Ø¯Ú©ÙŒÙ Ú«ÙØ±ÛÙ ÙÙŸØ§Ø±Ù}  
+_textdescrBrowse_ [l=ps] {Ø¯Ø§Ø³ÙØ§Ø¯Ù Ø³Ø±Ø³Ø±Û Ú©ØªÙÙ}  
+_texticontext_ [l=ps] {Ø³ÙØ¯ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texticonclosedbook_ [l=ps] {Ø¯Ø§Ø³ÙØ¯ Ø®ÙØ§Øµ Ú©ÚÛ Ø§Ù Ù
+Ø­ØªÙÛØ§Øª ÛÛ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texticonnext_ [l=ps] {Ø±Ø§ØªÙÙÙÚ©Û ØšØ±Ø®Û ØªÙ}  
+_texticonprev_ [l=ps] {Ù
+Ø®Ú©Û ØšØ±Ø®Û ØªÙ}  
+
+_texticonworld_ [l=ps] {Ø¯ÙÛØš Ø³ÙØ¯ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+
+_texticonmidi_ [l=ps] {Ø¯MIDIØ³ÙØ¯ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texticonmsword_ [l=ps] {Ø¯Microsoft WordØ³ÙØ¯ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texticonmp3_ [l=ps] {Ø¯ MP3Ø³ÙØ¯ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texticonpdf_ [l=ps] {Ø¯PDFØ³ÙØ¯ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texticonps_ [l=ps] {Ø¯PostScriptØ³ÙØ¯ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texticonppt_ [l=ps] {Ø¯PowerPointØ³ÙØ¯ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texticonrtf_ [l=ps] {Ø¯ RTFØ³ÙØ¯ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texticonxls_ [l=ps] {Ø¯Microsoft ExcelØ³ÙØ¯ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+
+_page_ [l=ps] {Ù
+Ø®}  
+_pages_ [l=ps] {Ù
+Ø®ÙÙÙ}  
+
+_vol_ [l=ps] {ÙŒÙÚ©}  
+_num_ [l=ps] {ÙÙ
+ØšØ±}  
+
+_textmonth00_ [l=ps] {}
+_textmonth01_ [l=ps] {Ø¬ÙÙØ±Û}  
+_textmonth02_ [l=ps] {ÙØšØ±ÙØ±Û}  
+_textmonth03_ [l=ps] {Ù
+Ø§Ø±Ú}  
+_textmonth04_ [l=ps] {Ø§ÙŸØ±ÛÙ}  
+_textmonth05_ [l=ps] {Ù
+Û}  
+_textmonth06_ [l=ps] {Ø¬ÙÙ}  
+_textmonth07_ [l=ps] {Ø¬ÙÙØ§Û}  
+_textmonth08_ [l=ps] {Ø§Ú«Ø³Øª}  
+_textmonth09_ [l=ps] {Ø³ÙŸÙŒÙ
+ØšØ±}  
+_textmonth10_ [l=ps] {Ø§Ú©ØªÙØšØ±}  
+_textmonth11_ [l=ps] {ÙÙÙ
+ØšØ±}  
+_textmonth12_ [l=ps] {Ø¯ÛØ³Ù
+ØšØ±}  
+
+_textdocument_ [l=ps] {Ø³ÙØ¯}  
+_textsection_ [l=ps] {ØšØ±Ø®Ù}  
+_textparagraph_ [l=ps] {Ø¯ÙÛÚ©ÙÛ ÛÙÙ ØšØ±Ø®Ù}  
+
+_magazines_ [l=ps] {Ù
+Ø¬ÙÛ}  
+
+
+
+_linktextHOME_ [l=ps] {Ú©ÙØ±}  
+_linktextHELP_ [l=ps] {ÙØ§Ø±ÚÙÙÙÙ}  
+_linktextPREFERENCES_ [l=ps] {Ø®ÙÚÛ}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=ps] {Ø¯Ú«Ø±ÛÙ Ø³ÙŒÙÙ ÚÛØ¬ÛÙŒØ§Ù Ú©ØªØ§ØšØªÙÙ}  
+
+_textnocollections_ [l=ps] {ÙØ§Ø¯Ø±Ø³Øª(i.e. built and public) ÙŒÙÙÚ«Û Ù
+ÙØ¬ÙØ¯Û Ø¯Û}  
+
+_textadmin_ [l=ps] {Ø¯Ø§Ø¯Ø§Ø±Ù Ú©ÙÙÙ Ù
+Ø®}  
+_textabgs_ [l=ps] {Ø¯Ú«Ø±ÛÙ Ø³ÙŒÙÙ ÙŸÙ Ø§ÚÙ}  
+_textgsdocs_ [l=ps] {Ø¯Ú«Ø±ÛÙ Ø³ÙŒÙÙ Ø§Ø³ÙØ§Ø¯ ÛØ§ Ø³ÙØ¯ Ø±Ø§ÙÚÙÙ}  
+
+_textdescradmin_ [l=ps] {ØªØ§Ø³ÙØªÙ Ø§Ø¬Ø§Ø²Ù Ø¯Ø±Ú©ÙÛ ÚÛ ÙÙÛ Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÙÚ©Û Ø¹ÙØ§ÙÙ Ú©ÚÛØ ÙŒÙÙÚ«Û ÙŸÙ Ø³ÛØ³ÙŒÙ
+ Ú©Û Ø¯Ø±ØªÙ Ø®ÙØ§ØµÙ Ú©ÙÛØ Ø§Ù Ø¯Ú«Ø±ÛÙ Ø³ÙŒÙÙ Ø¯ÙŸÙØ±ØªÙ Ú©ÙÙÙ ÙŸÙ ØšØ§Ø±Ù Ú©Û ØªØ®ÙÛÚ©Û Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø¯Ø±Ú©ÙÛ.}  
+
+_textdescrgogreenstone_ [l=ps] {ØªØ§Ø³ÙØªÙ Ø¯Greenstone softwareØ§Ù Ø¯ÙÙÛ Ø²ÛÙØ§ÙÚ Ø¯ÚÛØ¬ÛÙŒÙ Ú©ØªØ§ØšØªÙÙ Ø¯ÙŸØ±ÙÚÛ ÙŸÙ ØšØ§Ø±Ù Ú©Û ÚÛ ÚÛØ±ØªÙ Ù
+ÙÙÛØ¹Øª ÙØ±Û Ø§ÙÚ
+Ù ÚÙÙÙÙ Ú©ÙÛ}  
+
+
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=ps] {Ø¯Ú©ØªØ§ØšØ¯Ø§Ø± ÙÛØ¯ Ù
+ÙÚ}  
+_textdescrgli_ [l=ps] {Ø¯ØªØ§Ø³Ø±Ù Ù
+Ø±Ø³ØªÙ Ú©Ù Û ÚÛ ÙÙÛ ÙŒÙÙÚ«Ù Ø¬ÙÚÛ Ú©ÚÛØ ØŽØªÙ ÙŒÙÙÚ«Ù Ú©Û ØšØ¯ÙÙÙ ÛØ§ Ø§Ø¶Ø§ÙÙ ÙØ§ÙÛØ ÛØ§ Ø¯ÙŒÙÙÚ«ÙÙŸØ§Ú©ÙÙ}  
+
+package collector
+
+_textcollector_ [l=ps] {Ø±Ø§ÙŒÙÙÙÙÚ©Û}  
+
+
+package depositor
+
+_textdepositor_ [l=ps] {Ø²ÛØ±Ù
+Ù Ú©ÙÙÙÚ©Û}  
+_textdescrdepositor_ [l=ps] {Ø¯ØªØ§Ø³ÙØ³Ø±Ù Ú©ÙÙ
+Ú© Ú©ÙÛ ÚÛ ÙŸÙ ØŽØªÙ ÙŒÙÙÚ«Û ØšØ§ÙØ¯ Ø§Ø³ÙØ§Ø¯ Ø¹ÙØ§ÙÙ Ú©ÚÛ}  
+
+package gti
+
+_textgti_ [l=ps] {Ø¯Ú«Ø±ÛÙ Ø³ÙŒÙÙ Ø¯ÚØšØ§ÚÙÙÚ©Û Ù
+ÙÚ ÙÛØ¯}  
+_textdescrtranslator_ [l=ps] {ØªØ§Ø³Ù ØªÙ ÙØ§Ø±ÚÙÙÙÙ Ú©ÙÛ ØªØ±Ú
+Ù Ø¯ÚÛØ±Ù ÚØšÙ Ø§ÚÛÚ©Û ÙŸÙ Ú«Ø±ÛÙ Ø³ÙŒÙÙ Ú©Û ÙÙ Û ÙØ³Ø§ØªÛ.}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=ps] {Ø¯Ø¯Û ÙŒÙÙÚ«Û ÙŸÙ Ø§ÚÙ}  
+
+_textsubcols1_ [l=ps] {ÙŒÙÙÙ ÙŒÙÙÚ«Ù_1_ ÙØ±Ø¹Û ÙŒÙÙÚ«Û ÙŸÙ ØšØ±Ú©Û ÙÛØ³Û.
+ÙØºÙ ÚÛ Ø§ÙØ³ ØŽØªÙ Ø¯Û Ø¹ØšØ§Ø±Øª Ø¯Û ÙÙ:
+<blockquote>}  
+
+_textsubcols2_ [l=ps] {</blockquote>
+(ØªØ§Ø³Ù Ú©ÙØ§Û ØŽÛ ÚÛ ÙØºÙ ÙØ±Ø¹Û ÙŒÙÙÚ«Û ÙÚ«ÙØ±Û Ø§Ù(ØšØ¯ÙÙÙ ÙŸÚ©Û Ø±Ø§ÙÚÛ 
+.Ú©ÙÙ
+Û ÚÛ ØªØ§Ø³Ù Ø¯Ø§ÙØ³ ÙØ®Øª ÙÙŸØ§Ø±Ù Ø¯Ø®ÙÚÛ ÙŸÙ Ù
+Ø® Ú©Û ÙŸÚ©Ø§Ø± Ø§ÚÙÛ}  
+
+_titleabout_ [l=ps] {ÙŸÙ Ø§ÚÙ}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=ps] {Ø¯Ú©ØªØ§ØšØªÙÙ Ø¯Ø§ØšØ±Ø®Ù ÙØªÚÛ}  
+_texticonclosedbookshelf_ [l=ps] {Ø¯Ø§ØšØ±Ø®Ù Ø¯Ú©ØªØ§ØšØªÙÙ Ø®ÙØ§ØµÙ Ú©ÚÛ Ø§Ù Ù
+Ø­ØªÙÛØ§Øª ÛÛ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texticonopenbook_ [l=ps] {Ø¯Ø§Ú©ØªØ§Øš ØšÙØ¯ Ú©ÚÛ}  
+_texticonclosedfolder_ [l=ps] {Ø¯Ø§Ø¯ÙØ³ÛÙ Ø®ÙØ§ØµÙ Ú©ÚÛ Ø§Ù Ù
+Ø­ØªÙÛØ§Øª ÛÛ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texticonclosedfolder2_ [l=ps] {ÙØ±Ø¹Û ØšØ±Ø®Ù Ø®ÙØ§ØµÙ Ú©ÚÛ}  
+_texticonopenfolder_ [l=ps] {Ø¯Ø§Ø¯ÙØ³ÛÙ(Ù
+ÙÙ) ÙØªÚÛ}  
+_texticonopenfolder2_ [l=ps] {ÙØ±Ø¹Û ØšØ±Ø®Ù ÙØªÚÛ}  
+_texticonsmalltext_ [l=ps] {Ø¯Ø§ØšØ±Ø®Ù Ø¯Ù
+ØªÙ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texticonsmalltext2_ [l=ps] {Ø¯Ù
+ØªÙ ÚÚ©Ø§Ø±Ù Ú©ÙÙ:}  
+_texticonpointer_ [l=ps] {Ø§ÙØ³ÙÛ ØšØ±Ø®Ù}  
+_texticondetach_ [l=ps] {Ø¯Ø§Ù
+Ø® ÙŸÙ ÛÙÙ ÙÙÛ Ú©ÚÚ©Û Ú©Û Ø®ÙØ§Øµ Ú©ÚÛ}  
+_texticonhighlight_ [l=ps] {Ø¯ÙŸÙÙŒÙÛ Ø§ØµØ·ÙØ§ Ø­ Ú«Ø§ÙÛ Ø±ÙÚØ§ÙÙ Ú©ÚÛ}  
+_texticonnohighlight_ [l=ps] {Ø¯ÙŸÙÙŒÙÛ Ø§ØµØ·ÙØ§ Ø­ Ú«Ø§ÙÛ Ù
+Ù Ø±ÙÚØ§ÙÙ Ú©ÙÛ}  
+_texticoncontracttoc_ [l=ps] {Ø¯Ù
+Ø­ØªÙÛØ§ØªÙ Ø¬Ø¯ÙÙ ÙÙØºØ§ÚÛ}  
+_texticonexpandtoc_ [l=ps] {Ø¯Ù
+Ø­ØªÙÛØ§ØªÙ Ø¬Ø¯ÙÙ  ÙŸØ±Ø§Ø®Ù Ú©ÚÛ}  
+_texticonexpandtext_ [l=ps] {ÙŒÙÙ Ù
+ØªÙ Ø¬ÙØª Ú©ÚÛ}  
+_texticoncontracttext_ [l=ps] {ÛÙØ§ÚÛ Ø¯ÙŸÙ ÙÚÙ ØŽÙÛ ØšØ±Ø®Û ÙÙŸØ§Ø±Ù Ù
+ØªÙ Ø¬ÙØª Ú©ÚÛ}  
+_texticonwarning_ [l=ps] {<b>Ø®ØšØ±Ø¯Ø§Ø±Û: </b>}  
+_texticoncont_ [l=ps] {Ø¯ÙØ§Ù
+Ø}  
+
+_textltwarning_ [l=ps] {<div class="buttons">_imagecont_</div>
+_iconwarning_Ø¯ÙØªÙ ØšÙ Ø¯Ù
+ØªÙ ÙŸØ±Ø§Ø®ÙÙ Ø³ØªØ§ Ø¯Ø³Ø±Ø³Ø±Û Ú©ØªÙ ÙÙŸØ§Ø±Ù ÙÙŸØ§Ø±Ù Ø¯Ø¯Ø§ØªØ§ ÛÙÙ ÙÙÛÙ 
+ÙŸÛÙ
+Ø§ÙÙ Ø¯Ø±Ø§ØšØ±Ø³ÛØ±Ù Ú©ÙÙÙ ÙÙŸØ§Ø±Ù Ø¬ÙÚÙ Ú©ÚÛ}  
+
+_textgoto_ [l=ps] {Ù
+Ø® ØªÙ ÙØ§ÚØŽÙ}  
+_textintro_ [l=ps] {<i>(ÙŸÛÚÙØ¯ÙÙÚ©Û Ù
+ØªÙ)</i>}  
+
+_textCONTINUE_ [l=ps] {Ø¯ÙØ§Ù
+Ø}  
+
+_textEXPANDTEXT_ [l=ps] {Ø¯Ù
+ØªÙ ÙŸØ±Ø§Ø®ÙÙ}  
+
+_textCONTRACTCONTENTS_ [l=ps] {Ø¯Ù
+Ø­ØªÙÛØ§ØªÙ Ø±Ø§ØºÙÙÚÙÙ}  
+
+_textDETACH_ [l=ps] {ØšÛÙÙÙ}  
+
+_textEXPANDCONTENTS_ [l=ps] {Ø¯Ù
+Ø­ØªÙÛØ§ØªÙ ÙŸØ±Ø§Ø®ÙÙ}  
+
+_textCONTRACT_ [l=ps] {Ø¯Ù
+ØªÙ Ø±Ø§ØºÙÙÚÙÙ}  
+
+_textHIGHLIGHT_ [l=ps] {Ø±ÙÚØ§ÙÙ Ú©ÙÙ}  
+
+_textNOHIGHLIGHT_ [l=ps] {ÙÙ Ø±ÙÚØ§ÙÙ Ú©ÙÙ}  
+
+_textPRINT_ [l=ps] {ÙŸØ±ÙÙŒ}  
+
+_textnextsearchresult_ [l=ps] {Ø¯Ø±Ø§ØªÙÙÙÚ©Û ÙŸÙÙŒÙÛ ÙŸØ§ÛÙÙ}  
+_textprevsearchresult_ [l=ps] {Ø¯ÙŸØ®ÙØ§ÙÛ ÙŸÙÙŒÙÛ ÙŸØ§ÛÙÙ}  
+
+# macros for printing page
+_textreturnoriginal_ [l=ps] {Ø§ØµÙÛ Ù
+Ø® ØªÙ Ø±Ø§Ú«Ø±ÚÛØ¯Ù}  
+_textprintpage_ [l=ps] {Ø¯Ø§Ù
+Ø® ÙŸØ±ÙÙŒ Ú©ÚÛ}  
+_textshowcontents_ [l=ps] {Ø¯Ù
+Ø­ØªÙÛØ§ØªÙ Ø¬Ø¯ÙÙ ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texthidecontents_ [l=ps] {Ø¯Ù
+Ø­ØªÙÛØ§ØªÙ Ø¯Ø¬Ø¯ÙÙ ÙŸÙŒÙÙ}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=ps] { ÙØªØšØ¬Ù Ø¯_If_(_thislast_,Ø¯_thisfirst_ - _thislast_Ø¯Ø³ÙØ³ÙÛ ÙÙŸØ§Ø±Ù Ø¯Ù:  _cgiargq_, Ø¯ÙŸÙÚØªÙÛ Ø³Ø± Ø³Ù
+ÙÙ ÙÙ Ø®ÙØ±Û: _cgiargq_)}  
+_textnoquerytitle_ [l=ps] {Ù
+Ø® ÙÙÙŒÙÛ}  
+
+_textsome_ [l=ps] {ÚÛÙÛ}  
+_textall_ [l=ps] {ÙŒÙÙ}  
+_textboolean_ [l=ps] {ØšÙÙÛÙ Ø³ÛØ³ÙŒÙ
+}  
+_textranked_ [l=ps] {Ø¯Ø±Ø¬Ù ØšÙØ¯Û ØŽÙÛ}  
+_textnatural_ [l=ps] {Ø·ØšÛØ¹Û}  
+_textsortbyrank_ [l=ps] {Ù
+ÙØ§Ø³ØšÙ Ø¯Ø±Ø¬Ù ØšÙØ¯Û}  
+_texticonsearchhistorybar_ [l=ps] {Ø¯ØªØ§Ø±ÛØ® ÙŸÙÙŒÙÙ}  
+
+_textifeellucky_ [l=ps] {Ø²Ù Ø¯ÙÛÚ©Ù
+Ø±ØºÛ Ø§Ø­Ø³Ø§Ø³ Ú©ÙÙ
+!}  
+
+#alt text for query buttons
+_textusequery_ [l=ps] {Ø¯Ø§ÙŸÙÚØªÙÙ ÙŸÚ©Ø§Ø±ÙØ§ÚÙÛ}  
+_textfreqmsg1_ [l=ps] {Ø¯ÙØºØ§ØªÙ ØŽÙ
+ÛØ±ÙÙ}  
+
+_textinvalidquery_ [l=ps] {Ø¯ÙŸÙÚØªÙÛ ØºÙØ·Ù ÙØ­ÙÙ}  
+_textstopwordsmsg_ [l=ps] {ÙØ§ÙØ¯Û Ú©ÙÛÙ
+Û ÚÛØ±Û Ø¹Ø§Ù
+ ØŽÙÛ ÙÛ Ø§Ù ÙÙ ÙØžØ±Ù ÙØºÙØ±ÚÙÙ ØŽÙÛ:}  
+_textlucenetoomanyclauses_ [l=ps] {Ø³ØªØ§ ÙŸÙÚØªÙÙ Ø²ÛØ§ØªÛ Ú©ÙÛÙ
+Û ÙŸÙ ØšØ± Ú©Û ÙÛØ³ÛØ Ù
+ÙØ±ØšØ§ÙÛ ÙÚ©ÚÛ ÙŸÙÚØªÙÙ Ù
+Ù ÙÙØ±Ù ÙÙÚÙ Ú©ÚÛ.}  
+
+_textmorethan_ [l=ps] {Ø²ÛØ§Øª ÙÙ}  
+_textapprox_ [l=ps] {ÙŸÙ Ø§ÚÙ}  
+_textnodocs_ [l=ps] {Ø§Ø³ÙØ§Ø¯ Ø¯ÙŸÙÚØªÙÛ Ø³Ø±Ù Ø³Ù
+ÙÙ ÙÙ Ø®ÙØ±Û.}  
+_text1doc_ [l=ps] {1Ø³ÙØ¯ Ø¯ÙŸÙÚØªÙÛ Ø³Ø±Ù Ø³Ù
+ÙÙ Ø®ÙØ±Û}  
+_textlotsdocs_ [l=ps] {Ø§Ø³ÙØ§Ø¯ Ø³ØªØ§Ø³Ù Ø¯ÙŸÙÚØªÙÛ Ø³Ø±Ù Ø³Ù
+ÙÙ Ø®ÙØ±Û.}  
+_textmatches_ [l=ps] {Ø³Ù
+ÙÙÙÙÙ}  
+_textbeginsearch_ [l=ps] {ÙŸÙÙŒÙÙ ÙŸÛÙ Ú©ÚÛ}  
+_textrunquery_ [l=ps] {ÙŸÙÚØªÙÛ ØªÙ Ø¯ÙØ§Ù
+ ÙØ±Ú©ÚÛ}  
+_textclearform_ [l=ps] {ÙŸØ§Ú©Ù ÙÙØ±Ù
+Ù}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=ps] {ÙØºØ§ØªÙÙÙ
+}  
+_textinfield_ [l=ps] {...ÙŸÙ Ø³Ø§Ø­Ù Ú©Û}  
+
+
+_textadvquery_ [l=ps] {ÛØ§ ÙŸÙÚØªÙÛ ØªÙ ÙŸÙ Ù
+Ø³ØªÙÛÙ
+Ù ØªÙÚ«Ù ÙÙÙØ²Û.}  
+_textallfields_ [l=ps] {ÙŒÙÙÛ Ø³Ø§Ø­Û}  
+_texttextonly_ [l=ps] {ÛÙØ§ÚÛ Ù
+ØªÙ}  
+_textand_ [l=ps] {Ø§Ù}  
+_textor_ [l=ps] {ÛØ§}  
+_textandnot_ [l=ps] {Ø§Ù ÙÙ}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=ps] {Ø¯_indexselection_ _If_(_jselection_,Ø¯_jselection_ )_If_(_gselection_,ÙŸÙ_gselection_ Ø³Ø·Ø­Ù )ÙŸÙ _If_(_nselection_, ÚØšÙ ÙŸÙÙŒÙÙ ÙÚ©ÚÛ) Ú©ÙÙ
+ ÚÛ Ù
+ØŽØªÙ
+Ù ÙŸÙ_If_(_nselection_,Ø¯Ø§ÙÙØ§ØžÙ _If_(_sfselection_,\,_allowformbreak_ Ø¯ØªØ±ØªÛØš ÙØªÛØ¬Ù ÙŸÙ _sfselection_)ÙÛ}  
+
+
+
+
+
+
+
+
+
+_textformadvancedsearchmgpp_ [l=ps] {Ø¯_If_(_jselection_,_jselection_ )_If_(_gformselection_,ÙŸÙ_gformselection__gformselection_Ø³Ø·Ø­Ù)_If_(_nselection_,ÙŸÙ_nselection_ÚØšÙ) ÙŸÙÙŒÙÙ ÙÚ©ÚÛ Ø§Ù ÙŸØ§ÛÙÙ ÛÛ ÙŸÙ_formquerytypeadvancedselection_ Ø­Ø§ÙØª ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+
+
+
+_textnojsformwarning_ [l=ps] {Ø®ØšØ±Ø¯Ø§Ø±Û: Javascript Ø³ØªØ§ ÙŸÙ ÙÛØš Ú©ØªÙÙ
+Ù Ú©Û Ú©Ø§Ø± ÙÚ©ÙÛ.<br> ÙÙŸØ§Ø±Ù Ø¯Ø¯Û ÚÛ Ø¯ÙŸÙÙŒÙÛ ØšÚŒÙ ÙŸÙ Ú©Ø§Ø± ÙØ§ÚÙÛ Ù
+ÙØ±ØšØ§ÙÛ ÙÚ©ÚÛ Ø¯Ø§ ØšÛÚ©Ø§Ø±Ù Ú©ÚÛ.}  
+_textdatesearch_ [l=ps] {Ø¯Ø§ÙŒÙÙÚ«Ù Ø¯ ÙØºÙ Ø§Ø³ÙØ§Ø¯Ù ÙÙŸØ§Ø±Ù ÙŸÙÙŒÙØ§Û ØŽÛ ÚÛ ÙØžØ± ÙÛÙŒÛ ØªÙ ØªÙÙŸÛØ± ÙÙØ±ÛØ ÛØ§ ÙØºÙ Ø§Ø³ÙØ§Ø¯ ÚÛ ÙØ±ÙÙÚ©Û Ø¯Ø®Ø§ØµÛ ÙÛÙŒÛ ÙÛ. Ø¯Ø§ ÛÙÙ Ø¯Ø®ÙÚÛ ÙÚ ØšÚŒÙ Ø¯ÙŸÙÙŒÙÛ Ø¯Ù.}  
+_textstartdate_ [l=ps] {ÙŸÛÙ (ÛØ§ ÛÙØ§Ø²Û) ÙÛÙŒÙ:}  
+_textenddate_ [l=ps] {ÙØ±ÙØ³ØªÛ ÙÛÙŒÙ:}  
+
+
+_textexplaineras_ [l=ps] {Ø¯ A.D.Ø§Ù B.C. Ù
+Ø¹ÙØ¶ C.E.Ø§ÙB.C.E Ø¯Û. Ø§Ù Ø¯Ø§Ú©ÙÛÙ
+Û ØšÛ ÙÛØ¯Ù Ø±ÙØ§Ø¬ ØŽÙÛ Ø¯Û Ø§Ù Ø¯ "Ø¹Ø§Ù
+ ÙŸÛÙ Ø¯ØªØ§Ø±ÛØ®" Ø§Ù "Ù
+Ø®Ú©Û Ø¯Ø¹Ø§Ù
+ ÙŸÛÙ Ø¯ØªØ§Ø±ÛØ®" ÙÙŸØ§Ø±Ù Ø±Ø§ÙŸÙØ±ØªÙ ØŽÙÛ Ø¯Û.}  
+
+_textstemon_ [l=ps] {(Ø¯ ÙØžØ±Ù ØºÙØ±ÚÙÙ ØŽÙÛÙ Ú©ÙÛÙ
+Ù ÙŸØ§Û)}  
+
+_textsearchhistory_ [l=ps] {ØªØ§Ø±ÛØ® ÙÙÙŒÙÛ}  
+
+#text macros for search history
+_textnohistory_ [l=ps] {Ø¯ÙŸÙÙŒÙÛ ÙŸÙ ØªØ§Ø±ÛØ® Ú©Û Ù
+Ù ÙÙÙØ²Û}  
+_texthresult_ [l=ps] {ÙŸØ§ÛÙÙ}  
+_texthresults_ [l=ps] {ÙŸØ§ÛÙÛ}  
+_texthallwords_ [l=ps] {ÙŒÙÙ ÙØºØ§ØªÙÙÙ}  
+_texthsomewords_ [l=ps] {ÚÛÙÛ ÙØºØ§ØªÙÙÙ}  
+_texthboolean_ [l=ps] {ØšÙÙÛÙ Ø³ÛØ³ÙŒÙ
+}  
+_texthranked_ [l=ps] {ØµÙ ØšÙØ¯Û}  
+_texthcaseon_ [l=ps] {Ø­Ø§ÙØª ØšØ§ÛØ¯ Ø³Ù
+ÙÙ ÙØ®ÙØ±Û}  
+
+_texthstemon_ [l=ps] {Ù
+Ø®Ù ÛÛ ÙÛÙÙ ØŽÙÛ}  
+_texthstemoff_ [l=ps] {Ù
+Ø®Ù ÛÛ ÙØ¯Ù ÙÛÙÙ ØŽÙÛ}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=ps] {Ø®ÙÚÛ ÙŸÙ ÙØ§ÙØ¯Û ÚÙÙ ØªØ±ØªÛØš ØŽÙÛ. Ø¯Ø®ÙŸÙ Ú©ØªÙÙ
+Ù  "ØŽØ§ØªØ¹"ØªÚŒÛ Ù
+Ù ÙŸÚ©Ø§Ø±ÙÛ Ø¯Ø§ØšÙ ÛÛ ØšÛ ØªØ±ØªÛØšÙ Ú©ÚÛ! Ø¯Ø¯Û ÙŸÙ ÚØ§Û ÙŸÙ ÙŸÙØ±ØªÙÛ ØšØ±Ø®Ù Ú©Û Ø¯access barÙŸÙ ØªÚŒÛ Ú©ÙÛÚ© ÙÚ©ÚÛ.}  
+_textsetprefs_ [l=ps] {Ø¯Ø®ÙÚÛ ØªØ±ØªÛØšÙÙ}  
+_textsearchprefs_ [l=ps] {Ø¯Ø®ÙÚÙ ÙŸÙÙŒÙÙ}  
+_textcollectionprefs_ [l=ps] {Ø¯ÙŒÙÙÚ«Û Ø®ÙÚÛ}  
+_textpresentationprefs_ [l=ps] {ÙÚØ§ÙØ¯ÛØ² ØŽÙÛ Ø®ÙÚÛ}  
+_textpreferences_ [l=ps] {Ø®ÙÚÛ}  
+_textcasediffs_ [l=ps] {Ø¯Ø­Ø±ÙÙÙ ÙÙÛÙØ§ÙÛ Ø§Ù Ú©ÙÚÙÛÙØ§ÙÛ:}  
+_textignorecase_ [l=ps] {Ø¯Ø­Ø±ÙÙÙ ÙŸÙ ÙÙÛÙØ§ÙÛ Ø§ÙÚ©ÙÚÙÛÙØ§ÙÛ Ø³ØªØ±Ú«Û ÙŸÙŒÙÙ}  
+_textmatchcase_ [l=ps] {ÙŸÙØ±ØªÙÛ/ÙØ§ÙØ¯ÙÛ ØšØ±Ø®Û ØšØ§ÛØ¯ Ø³Ù
+ÙÙ ÙØ®ÙØ±Û}  
+_textwordends_ [l=ps] {Ø¯ÙØºØ§Øª ÙŸØ§Û:}  
+_textstem_ [l=ps] {Ø¯ÙØºØ§Øª Ø¯ÙŸØ§Û ÙÙ ÙØžØ±Ù ØºÙØ±ÚÙÙ}  
+_textnostem_ [l=ps] {ÙŒÙÙ ÙØºØ§Øª ØšØ§ÛØ¯ Ø³Ù
+ÙÙ ÙØ®ÙØ±Û}  
+_textaccentdiffs_ [l=ps] {Ø¯ÙÙØ¬Û Ø§Ø®ØªÙØ§ÙØ§Øª:}  
+_textignoreaccents_ [l=ps] {ÙÙØ¬Û Ø¯ÙØžØ±Ù ÙØºÙØ±ÚÙÛ}  
+_textmatchaccents_ [l=ps] {ÙÙØ¬Û ØšØ§ÛØ¯ Ø³Ù
+ÙÙ ÙØ®ÙØ±Û}  
+
+
+_textprefop_ [l=ps] {ØšÛØ±ØªÙ_maxdocoption_ÙŸØ§ÛÙÙ ØªÙ Ø¯_hitsperpageoption_ÙŸØ§ÛÙÙ Ø³Ø±Ù ÙØžØ± ÙÙ
+Ø® ØªÙ Ø±Ø§ÙÚ«Ø±ÚÛ.}  
+_textextlink_ [l=ps] {ØšÙØ±ÙÛÙ ÙÛØš ÙŸØ§ÚŒÙ ØªÙ ÙØ§Ø±:}  
+
+_textlanguage_ [l=ps] {Ø¯ÚØšÛ Ù
+ÙÚ ÙÛØ¯:}  
+_textencoding_ [l=ps] {Ø±Ù
+Ø²Ú©ÙÙÙ:}  
+_textformat_ [l=ps] {ÙÚÙÙÙÙ Ø¯Ø¬ÙÚÚØª Ø³Ø±Ù:}  
+_textall_ [l=ps] {ÙŒÙÙ}  
+_textquerymode_ [l=ps] {Ø¯ÙŸÙÚØªÙÛ Ø­Ø§ÙØª:}  
+_textsimplemode_ [l=ps] {Ø¯ÙŸÙÚØªÙÛ Ø³Ø§Ø¯Ù Ø­Ø§ÙØª}  
+
+_textlinkinterm_ [l=ps] {Ø¯Ù
+ÙÚÙÛ Ù
+Ø® ÙŸÙØ§Ø³Ø·Ù}  
+_textlinkdirect_ [l=ps] {Ù
+Ø³ØªÙÛÙ
+ ÙÙØªÙ ÙØ§ÚØŽÙ}  
+_textdigitlib_ [l=ps] {ÚÛØ¬ÛÙŒÙ Ú©ØªØ§ØšØªÙÙ}  
+_textweb_ [l=ps] {ÙÛØš}  
+_textgraphical_ [l=ps] {Ú«Ø±Ø§ÙÛÚ©}  
+_texttextual_ [l=ps] {Ù
+ØªÙÛ}  
+_textcollectionoption_ [l=ps] {<p>
+:ÙØ±Ø¹Û ÙŒÙÙÚ«Û ÚÛ ÙØ±ÙÙÚ©Û Ø¯
+<br>}  
+
+_textsearchtype_ [l=ps] {Ø¯ÙŸÙÚØªÙÛ Ú
+Ø±ÙÚ«ÙØ§ÙÛ:}  
+_textformsearchtype_ [l=ps] {ØšÛÙ ØŽÙÛ ÙŸÙ _formnumfieldoption_Ø³Ø§Ø­Ù ØšØ§ÙØ¯Û}  
+
+_textregularbox_ [l=ps] {ÛÙØ§ÚÙÛ ÙÛÚ©Ù}  
+_textlargebox_ [l=ps] {ÙÙÛ}  
+
+_textrelateddocdisplay_ [l=ps] {Ø§ÚÙÙØ¯ Ø§Ø³ÙØ§Ø¯ Ø¬ÙØª Ú©ÚÛ}  
+_textsearchhistory_ [l=ps] {Ø¯ÙŸÙÙŒÙÛ ØªØ§Ø±ÛØ®}  
+_textnohistory_ [l=ps] {Ø¯ÙŸÙÙŒÙÛ ØªØ§Ø±ÛØ® ÙØŽØªÙ}  
+_texthistorydisplay_ [l=ps] {Ø¯ _historynumrecords_Ø¯ÙŸÙÙŒÙÛ ÙŸØ®ÙØ§ÙÛ ØªØ§Ø±ÛØ® Ø¬ÙØª Ú©ÚÛ}  
+_textnohistorydisplay_ [l=ps] {Ø¯ÙŸÙÙŒÙÛ ØªØ§Ø±ÛØ® Ù
+Ù Ø¬ÙØªÙÛ}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=ps] {Ø¯Ø§Ø³ÙØ§Ø¯Ù ØªØ±ØªÛØšÙÙ ÙØžØ± ÙŸÙ}  
+_textalsoshowing_ [l=ps] {ÙÙ
+Ø¯Ø§Ø±ÙÚ«Ù ÚØ§ÛÛ}  
+_textwith_ [l=ps] {Ø¯Ø²ÛØ§ØªÛ ÙÙ Ø²ÛØ§ØªÛ Ø³Ø±Ù}  
+_textdocsperpage_ [l=ps] {Ø§Ø³ÙØ§Ø¯ ÙØžØ±Ù Ù
+Ø® ØªÙ}  
+
+_textfilterby_ [l=ps] {Ø§Ø³ÙØ§Ø¯ ØªØ±ÙØ§Ø³Ù Ú©ÚÛ ÚÛ ÙØ±ÙÙÚ©Û Ø¯}  
+_textall_ [l=ps] {ÙŒÙÙ}  
+_textany_ [l=ps] {ÙØ±ÛÙ}  
+_textwords_ [l=ps] {Ø¯ÙØºØ§ØªÙ}  
+_textleaveblank_ [l=ps] {ÙÙŸØ§Ø±Ù Ø¯Ø¯Û ÚÛ ÙŒÙÙ Ø§Ø³ÙØ§Ø¯ ØªØ±ÙØ§Ø³Ù Ú©ÚÛ Ø¯Ø§ØšÚ©Ø³ ØªØŽ ÙŸØ±ÛÚØ¯Û}  
+
+_browsebuttontext_ [l=ps] {"Ø¯Ø§Ø³ÙØ§Ø¯Ù ØªØ±ØªÛØšÙÙ"}  
+
+_nodata_ [l=ps] {<i>Ø¯Ø¯Ø§ØªØ§ ØŽÙ
+ÛØ±Û</i>}  
+_docs_ [l=ps] {Ø§Ø³ÙØ§Ø¯}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=ps] {ÙØ§Ø±ÚÙÙÙÙ}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=ps] {Ø¯ _2_ ØªÚŒÛ ÙŸÙ Ú©ÙÛÚ© Ú©ÙÙÙØ³Ø±Ù Ø§Ø³ÙØ§Ø¯ ÙØžØ±_1_ ØªÙ Ø³Ø±Ø³Ø±Û ÙÚ«ÙØ±Û}  
+
+_textSearchhelp_ [l=ps] {ÚØ§ÙÚ«ÚÛ Ú©ÙÛÙ
+Û ÙÙŸÙÙŒÛ Ú©ÙÙ
+ ÚÛ ÙŸÙ Ù
+ØªÙ Ú©Û Ø¯_labelSearch_ ØªÚŒÛ ÙÙŸØ§Ø³Ù Ø¯Ú©ÙÛÚ© Ú©ÙÙÙØ³Ø±Ù ÚÚ©Ø§Ø±Ù Ú©ÛÚÛ}  
+
+_textFromhelp_ [l=ps] {Ø¯_labelFrom_ØªÚŒÛ ÙŸÙ Ú©ÙÛÚ© Ú©ÙÙÙØ³Ø±Ù Ø®ÙŸØ±ÙÙÛ ÙØžØ± ÙFromÚ
+Ø§ÙÚ«Û ØªÙ Ø³Ø±Ø³Ø±Û ÙÚ«ÙØ±Û}  
+_textBrowsehelp_ [l=ps] {Ø¯Ø§Ø³ÙØ§Ø¯ÙØ³Ø±Ø³Ø±Û Ú©ØªÙÙ}  
+_textAcronymhelp_ [l=ps] {Ø¯_labelAcronym_ØªÚŒÛ ØšÙ Ú©ÙÛÚ© Ú©ÙÙÙ Ø³Ø±Ù Ø¯ÙÙÙ
+ÙÙÙ ÙŸÛÚ ØŽÙÛ ÙÙÚÛØ²ÙÙÙ Ø³Ø±Ø³Ø±Û ÙÚ«ÙØ±Û}  
+
+
+_texthelptopicstitle_ [l=ps] {Ù
+ÙØ¶ÙØ¹Ø§Øª}  
+
+_textreadingdocs_ [l=ps] {Ø§Ø³ÙØ§Ø¯ ØšØ§ÛØ¯ Ú
+ÙÚ«Ù ÙÙÙØ³ØªÙ ØŽÛ}  
+
+_texthelpreadingdocs_ [l=ps] {<p>Ø¯ÙÙ ÚÙÙÙ ÙŸÙÚØªÙÛ ØŽØªÙØ§ÙÛ ÙØ±Û.
+
+<ul>
+  <li>ÙŸÙÚØªÙÛ ÙÙŸØ§Ø±Ù Ø¯ <b>Ø¯ÙŒÙÙÙ</b> ÙØºØªÙ ÙÙŸØ§Ø±Ù.  These look for documents (or
+      chapters, or titles) that contain all the words you have specified.
+      Documents that satisfy the query are displayed, in build order.
+<p>
+
+  <li>Queries for <b>some</b> of the words.  Just list some terms that are
+      likely to appear in the documents you are looking for.  Documents are
+      displayed in order of how closely they match the query.  When determining
+      the degree of match,
+
+      <p><ul>
+        <li> the more search term occurrences a document contains, the closer it matches;
+        <li> terms which are rare in the collection as a whole are more important than common ones;
+        <li> short documents match better than long ones.
+      </ul>
+</ul>
+
+<p>Use as many search terms as you like--a whole sentence, or even a
+whole paragraph.  If you specify only
+one term, documents will be ordered by its frequency of occurrence.<p>
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=ps] {Ø¯Ú©ØªØ§ØšÙ Ø¯Ø§ØªØ§Ø®ÚÙ Ø®ÙØ§Øµ Ú©ÚÛ}  
+_texthelpopenbook_ [l=ps] {Ø¯Ø§Ú©ØªØ§Øš Ø®ÙØ§Øµ/ÙØªÚÛ}  
+_texthelpviewtextsection_ [l=ps] {Ø¯Ù
+ØªÙ Ø¯Ø§ØšØ±Ø®Ù ÚÚ©Ø§Ø±Ù Ú©ÚÛ}  
+_texthelpexpandtext_ [l=ps] {ÙŒÙÙ Ù
+ØªÙ Ø¬ÙØª Ú©ÚÛ Ø§Ù ÛØ§ ÛÛ Ù
+Ù Ø¬ÙØªÙÛ}  
+_texthelpexpandcontents_ [l=ps] {Ø¯Ù
+Ø­ØªÙÛØ§ØªÙ Ø¬Ø¯ÙÙ ØªÙ ÙØ³Ø¹Øª ÙØ±Ú©ÚÛ Ø§Ù ÛØ§ ÛÛ Ù
+Ù ÙØ±Ú©ÙÛ}  
+_texthelpdetachpage_ [l=ps] {Ø¯Ø§Ù
+Ø® ÙŸÙ ÛÙÙ ÙÙÛ Ú©ÚÚ©Û Ú©Û Ø®ÙØ§Øµ Ú©ÚÛ}  
+_texthelphighlight_ [l=ps] {Ø¯ÙŸÙÙŒÙÛ Ú©ÙÛÙ
+Û Ø±ÙÚØ§ÙÙ Ú©ÚÛØ ÛØ§ Ù
+Ù Ø±ÙÚØ§ÙÙ Ú©ÙÛ}  
+_texthelpsectionarrows_ [l=ps] {Ù
+Ø®Ú©Û/Ø±Ø§ØªÙÙÙÚ©Û ØšØ±Ø®Û ØªÙ ÙØ§Ú ØŽÛ}  
+
+
+_texthelpsearchingtitle_ [l=ps] {ÚØ§ÙÚ«ÚÛ Ú©ÙÛÙ
+Û Ú
+ÙÚ«Ù ÙÙŸÙÙŒÙ}  
+
+
+
+_texthelpquerytermstitle_ [l=ps] {Ø¯Ø¹ØšØ§Ø±Ø§ØªÙ ÙŸÙÙŒÙÙ}  
+
+
+_texthelpmgppsearching_ [l=ps] {Ú©ÙÙ
+Ù ÙŒÙÙÚ«Ù ÚÛ ÙŸÙ MGPP Ø³Ø±Ù Ø¬ÙÚÙ ØŽÙÛ Ú
+Ù ÙÙØ±Û Ø®ÙÚÛ ÙÙ
+ ÙŸÚ©Ø§Ø± Ø§ÚÙÙ Ú©ÛÚÛ.
+
+<ul>
+<li>A <b>*</b>Ø¯ÙŸÙÚØªÙÛ Ø¯Ø§ØµØ·ÙØ§ ÙŸÙ ÙŸØ§Û Ú©Û ÙŒÙÙ ÙØºØ§ØªÙÙÙ<b> Ø³Ø±Ù Ø³Ù
+ÙÙ Ø®ÙØ±Û ÚÛ Ø¯</b> Ø¯ÙØºÙ ÙØºØ§Øª Ø³Ø±Ù ÙŸÛÙ Ú©ÛÚÛØ Ø¯Ù
+Ø«Ø§Ù ÙŸÙ ÚÙÙ<b>comput*</b> Ø¯ÙØºÙ ÙŒÙÙÙ ÙØºØ§ØªÙ Ø³Ø±Ù ÚÛ ÙŸÙ  <b>comput</b> ÙŸÛÙ ØŽÙÛ ÙÛ ÙØ±Ø³Ø±Ù Ø³Ù
+ÙÙ Ø®ÙØ±Û.}  
+
+_texthelplucenesearching_ [l=ps] {Ú©ÙÙ
+Û ÙŒÙÙÚ«Û ÚÛ ÙŸÙ LuceneØ³Ø±Ù Ø¬ÙÚÛ ØŽÙÛ Ú
+Ù ÙÙØ±Û Ø®ÙÚÛ ÙÙ
+ ÙŸÚ©Ø§Ø± Ø§ÚÙÙ Ú©ÛÚÛ.
+
+<ul>
+<li><b>?</b>Ú©ÙÙØ§Û ØŽÛ ÚÛ Ø¯ÛÙÙ Ø­Ø±Ù ÙŸÚØ§Û ÙŸÚ©Ø§Ø± ÙØ§ÚÙÙ ØŽÛ Ø¯ Ù
+Ø«Ø§Ù ÙŸÙ ÚÙÙØ <b>b?t</b>ØªÙ Ø¯<b>bet</b>, <b>bit</b>Ø§Ù<b>bat</b> Ø§Ù Ø¯Ø§Ø³Û ÙÙØ±ÙØ± Ø³Ø±Ù Ø³Ù
+ÙÙ ÙØ±Ú©ÙÛ.
+<li><b>*</b>Ú©ÙÙØ§Û ØŽÛ ÚÛ Ø¯Ú
+Ù Ø­Ø±ÙÙÙ ÙŸÚØ§Û ÙŸÚ©Ø§Ø± ÙØ§ÚÙÙ ØŽÛ Ø¯Ù
+Ø«Ø§Ù ÙŸÙ ÚÙÙØ <b>comput*</b>ØªÙ Ø¯ÙØºÙ ÙŒÙÙÙ Ú©ÙÛÙ
+Ù Ø³Ø±Ù Ø³Ù
+ÙÙ ÙØ±Ú©ÙÛ ÚÛ ÙŸÙ <b>comput</b> Ø³Ø±Ù ÙŸÛÙ ØŽÙÛ ÙÛ.
+</ul>
+Ø¯ÙØ§ÚÙ Ø¯Ø¯Û Ø¹ØšØ§Ø±Ø§ØªÙ Ú
+Ø®Ù Ú©ÛØ¯Ø§Û ØŽÛ ÚÛ ÙŸÙ Ù
+Ø§ØšÛÙ ÛØ§ ÙŸØ§Û Ø¯Ø§ØµØ·ÙØ§Ø­ Ú©Û ÙŸÚ©Ø§Ø±ÙØ§ÚÙÙ ØŽÛ. Ø§Ù
+Ø§ ÙŸÙ ÙŸÛÙ Ø¯ ÙŸÙÙŒÙÙÚ©Û Ø§ØµØ·ÙØ§Ø­ Ú©Û ÙØŽÛ ÙŸÚ©Ø§Ø± Ø§ÚÙÙ Ú©ÛØ¯Ø§Û.}  
+
+_texthelpquerytypetitle_ [l=ps] {Ø¯ÙŸÙÚØªÙÛ ÚÙÙ}  
+
+
+_texthelpadvancedsearchtitle_ [l=ps] {Ø¯ÙŸÙÙŒÙÛ Ø¯Ù
+Ø§ØŽÙÛ_1_ÙŸÚ©Ø§Ø± Ø§ÚÙÙ ÙŸØ±Ù
+Ø®ØªÙÙÛ ÙŸÙÙŒÙÙ Ú©ÙÛ}  
+
+_texthelpadvancedsearch_ [l=ps] {<p>Ú©Ù ÙŸÙ (Ø®ÙÚÛ Ú©Û) ØªØ§Ø³Ù Ø¯ÙŸÙÚØªÙÛ ÙŸØ±Ù
+Ø® ØªÙÙÛ Ø­Ø§ÙØª ÙŒØ§Ú©ÙÛ ÙÛ ÙÙ ÙŸÙ ÙÚÙ ÙŸÛÙ
+Ø§ÙÙ Ø³Ø±Ù Ù
+Ø®ØªÙÙÛ Ø®ÙÚÛ ÙØ±Û . _selectadvancedsearch_}  
+
+_texthelpadvsearchmg_ [l=ps] {ÙŸÙ MGÙŒÙÙÚ«ÙÚ©Û Ø¯ÙŸÙÙŒÙÙ Ø³Ø±Ù ØªØ§Ø³Ù ØªÙ Ø¯ÙÙ Ø®ÙÚÛ Ø¯Ø± ØšØ®ÚÛØ Ø¯Ø¯Ø±Ø¬Ù ØšÙØ¯Û Ø§Ù Ø¯ØšÙÙÛÙ Ø³ÛØ³ÙŒÙ
+.
+ÛÙÙ <b>ØµÙ ØšÙØ¯Û ØŽÙÛ</b>ÙŸÙÙŒÙÙ ÙŸÙ Ø¹ÛÙ ÚÙÙ ÙÚ©Ù Ø¯<b>ÚÛÙÙ</b> ÙŸÙÙŒÙÙ ÙŸÙ Ú
+ÛØ± Ø¯Ù Ú©ÙÙ
+ ÚÛ ÙŸÙ <a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_Ú©Û ØªØŽØ±ÛØ­ ØŽÙÛ Ø¯Ù.}  
+
+_texthelpbooleansearch_ [l=ps] {ÛÙ ØšÙÙÛÙ Ø³ÛØ³ÙŒÙ
+ Ø¯ÙŸÙÙŒÙÛ ØªØ§ØªÙ Ø§Ø¬Ø§Ø²Ù Ø¯Ø±Ú©ÙÛ ÚÛ Ø§ØµØ·ÙØ§Ø­Ø§Øª Ø¯& (and"ÙÙŸØ§Ø±Ù")Ø | Ø¯ (or"ÙÙŸØ§Ø±Ù"),Ø§Ù! Ø¯(not"ÙÙŸØ§Ø±Ù)Ø ÙŸÙØ§Ø³Ø·Ù ÙÙÚÙÙÛØ Ø§Ù Ú©Ù Ø®ÙÚÙ Ù
+Ù ÙÛ Ú©ÙÙØ§Û ØŽÛ ÚÛ ÙÙØ³ÙÙÙ Ø¯ Ú«Ø±ÙÙŸÙÙÙ Ø¯ØšÛÙÙÙÙ ÙÙŸØ§Ø±Ù ÙÙ
+ ÙÚ©Ø§Ø±ÙÛ. Ø®Ø±Ø§ØšÙ Ú©ÚÙÙ Ø¯(or"ÙÙŸØ§Ø±Ù") | Ø¯Ù.
+<p>
+Ø¯Ù
+Ø«Ø§Ù ÙŸÙ ÚÙÙ<b>snail & farming</b>ØšÙ ÙØºÙ Ø§Ø³ÙØ§Ø¯Ù ØªÙ Ø³Ø±Ù Ø³Ù
+ÙÙ ÙØ±Ú©ÚÛ Ú©ÙÙ
+ ÚÛ ÙØ±ÙÙÚ©Û Ø¯Ø¯ÙØ§ÚÙ<b>snail</b> Ø§Ù<b>farming</b> ÙÛØ ÙÙÛ <b>snail | farming</b>ØšÙ ÙØºÙ Ø§Ø³ÙØ§Ø¯Ù ØªÙ Ø³Ù
+ÙÙ ÙØ±Ú©ÚÛ ÚÛ ÙÙ
+Ø¯Ø§Ø±ÙÚ«Ù ÙØ±ÙÙÚ©Û Ø¯<b>snail</b>ÛØ§<b>farming</b>ÙÛ. 
+Ø§Ù<b>snail !farming</b>ØšÙ ÙØºÙ Ø§Ø³ÙØ§Ø¯Ù ØªÙ Ø³Ù
+ÙÙ ÙØ±Ú©ÚÛ<b>snail</b> Ø§ÙÙÙ ÙØ±ÙÙÚ©Û Ø¯<b>farming</b>ÙÛ.
+<p>
+Ø¯ÙÙØ±Ù Ø¯ÙÛÙØªÙ ÙŸÙÚØªÙÙ ÙÙŸØ§Ø±Ù Ø¯ÙŸÚ©Ø§Ø± Ø§ÚÙÙÛ Ø§Ù ÙÙØ³ÙÙÙ Ø¯ÙØ§ÚÙ Ú
+Ø®Ù Ú©Ø§Ø±Ø§Ø®ÙÙ. Ø¯Ù
+Ø«Ø§Ù ÙŸÙ ÚÙÙØ (<b> ÙŸØ³Ù  | Ú
+Ø§Ø±ÙÛ) &(ÙØ§Ø±Ù
+ | Ø³ÙŒÛØŽÙ)</b>ØÛØ§<b> ÙŸØ³Ù | Ú
+Ø§Ø±ÙÛ | ØšØ²Û ! Ø³Ø±Ú©ÙØ²Û</b>.}  
+
+_texthelpadvsearchmgpp_ [l=ps] {ÙŸØ±Ù
+Ø®ØªÙÙÛ ÙŸÙÙŒÙÙ ÙŸÙ MGPPÙŒÙÙÚ«Ù Ú©Û Ø¯ØšÙÙÛÙ Ø³ÛØ³ÙŒÙ
+ ÙŸÚ©Ø§Ø± Ø§ÚÙÙÙ Ú©Ø§Ø±ÙÛ._texthelpbooleansearch_
+<p>ÙŸØ§ÛÙÛ ÙŸÙ<b>Ø¯Ø±Ø¬Ù ØšÙØ¯Û</b>ØŽÚ©Ù ØšØ±Ø³ÛØ±Ù Ú©ÙÛØ ÙÚ©Ù Ø³Ø§Ø­Ù ÚÛ Ø¯<b>ÚÛÙÛ</b>ÙŸÙÙŒÙÙ ÙŸÙ<a href="\#query-type">_texthelpquerytypetitle_</a>,Ø§Ù ÛØ§ ÙŸÙ "natural" (or "build")Ø­Ø§ÙØª ØªØŽØ±ÛØ­ Ú©ÙÛ.
+Ø¯Ø§ÙØºÙ Ø­Ø§ÙØª Ø¯Ù ÚÛ Ø¯ÙŒÙÙÚ«Ù Ø¯Ù
+ÙÚØªÙ Ø±Ø§ÙÚÙÛ ÙŸÙ Ø¯ÙØ±Ø§Ù Ú©Û Ø§Ø³ÙØ§Ø¯ ÙŸØ±ÙØ³Ø³ ØŽÙÛ ÙÙ.
+<p>
+ÙÙØ±Û ÙŸÚ©Ø§Ø± Ø§ÚÙÙÛ Ø¹ØšØ§Ø±Øª Ø¯Û ÙÙ<b>NEARx</b>Ø§Ù<b>WITHINx</b>Ú
+Ø®Ù.
+
+}  
+
+_texthelpadvancedsearchextra_ [l=ps] {ÙÙÙŒ: Ú©Ù ØªØ§Ø³Û Ø¯ÙŸÙÚØªÙÛ Ø¯Ø³Ø§Ø¯Ù Ø­Ø§ÙØª ÙŸÙÙŒÙÙ Ú©ÙÛ ÙÙÙŸÙ Ø¯ØºÙ ÙŒÙÙÙ ÙŸÚ©Ø§Ø±Ø§ÚÙÙÙ ØšØ§ÙØ¯Û Ø³ØªØ±Ú«Û ÙŸÙŒÛÚÛ.}  
+
+
+
+_texthelpformsearchtitle_ [l=ps] {ÙŸÙ Ø³Ø§Ø­Ù ÙÛØŽÙ ØŽÙÛ ÙŸÙÙŒÙÙ}  
+
+
+
+
+
+_textdatesearch_ [l=ps] {ÙŸÙÙŒÙÙ ÙØžØ± ÙÛÙŒÙØªÙ}  
+
+_texthelpdatesearch_ [l=ps] {Ø¯ÙÛÙŒÛ ÙŸÙÙŒÙÙ ØªØ§Ø³Ù  ØªÙ Ø§Ø¬Ø§Ø²Ù Ø¯Ø±Ú©ÙÛ ÚÛ ÙØºÙ Ø§Ø³ÙØ§Ø¯ ÙŸÛØ¯Ø§Ú©ÚÛ Ú©ÙÙ
+ ÚÛ Ø³ØªØ§Ø³Ù Ø¯ÙŸÙÙŒÙÛ Ø¯Ú©ÙÛÙ
+Ù Ø³Ø±Ù Ø³Ù
+ÙÙ Ø®ÙØ±Û ÚÛ Ø¯ÚØ§ÙÚ«ÚÛ Ù
+ÙØ¯Û Ø¯ÙŸÛÚÛ ÙŸÙ Ø§ÚÙ ÙÛ ØªØ§Ø³Ù Ú©ÙÙØ§Û ØŽÛ Ø¯ÚØ§ÙÚ«ÚÛ Ú©Ø§Ù ÛØ§ Ø¯Ú©ÙÙÙÙØŽØ§ÙØ®ÙØ§ Ø§Ø³ÙØ§Ø¯ ÙÙÙŒÙÛ.
+ÙŸÙ ÛØ§Ø¯ÙÙØ±Û ÚÛ Ø¯ÙŸÙÙŒÙÛ ÙÙŸØ§Ø±Ù ÛÙÙ Ú©ÙÛÙ
+Ù ÙÙ ØšÙÚ©Ù ÛÙØ§ÚÛ ÛÙÙ ÙÛÙŒÙ ÙŸÚ©Ø§Ø±ÙØ§ÚÙÛ Ø§ÙÙÙ
+Ø¯Ø§Ø±ÙÚ«Ù Ø¯ÙŸÙÙŒÙÛ ÙÙŸØ§Ø±Ù ÙÛÙŒÛ ÙŸÚ©Ø§Ø± Ù
+Ù Ø§ÚÙÛ Ø Ø§ÙÚ©Ù ÙÛÙŒÙ ÙÙÙ ÙÛÚ©Û Ø¯Ø§Ù
+Ø§ÙØ§ ÙØ±Û ÚÛ Ø¯ÙÛÙŒÛ ÙŸÙÙŒÙÙ Ø¯Ø³Ø±Ù ÙØŽØªÙ.}  
+
+
+
+
+_texthelpdateresultstitle_ [l=ps] {Ø³ØªØ§ Ø¯ÙŸÙÙŒÙÛ ÙŸØ§ÛÙÛ Ú
+ÙÚ«Ù ÙŸÛØ¯Ø§ Ú©ÛÚÛ}  
+_texthelpdateresults_ [l=ps] {ÙŸÙ Ø¹Ù
+ÙÙ
+Û ØªÙÚ«Ù Ø¯Ø§Ø³ÙØ§Ø¯Ù ÛÙÙ ÙŸÙÙŒÙÙ Ø¯1903 Ú©Ø§Ù ÙŸÙ ØšØ§Ø±Ù Ú©Û Ø¯Ø§Ø³Û Ø§Ø³ÙØ§Ø¯ ÙÙ Ø±Ø§Ú«Ø±ÚÙÛ ÚÙ ÙŸÙ 1903 Ú©Ø§Ù Ú©Û ÙÛÚ©Ù ØŽÙÛ ÙÛ ØšÙÚ©Ù ÙØºÙ Ø§Ø³ÙØ§Ø¯ Ø±Ø§Ú«Ø±ÚÙÛ ÚÛ Ø¯1903 Ú©Ø§Ù ÙŸÙ ØšØ§Ø±Ù Ú©Û ÙÛÚ©Ù ØŽÙÛ ÙÛ. ÙÙŸØ§Ø±Ù Ø¯Ø¯Û ÚÛ Ø¯Ø§Ø³ÙØ§Ø¯Ù ÙÛÙŒÛ ÙŸÛØ¯Ø§ ØŽÛØ ÙØºÙ Ø§Ø³ÙØ§Ø¯ ØšÙ Ø±Ø§ÙÚ«Ø±ÚÙÛ ÚÛ Ø¯ÙÛÙŒÛ ÛÙÙ Ù
+ÙØ¯Ù  ÙÙØ±Û (Ø¯Ù
+Ø«Ø§Ù ÙŸÙ ÚÙÙ 1899-1911) ÚÛ 1903 ÙŸÚ©Û ØŽØ§Ù
+Ù Ø¯ÛØØ§ÙÙÙ
+Ø¯Ø§Ø±ÙÚ«Ù ÙØºÙ Ø§Ø³ÙØ§Ø¯ ÚÛ Ø¯Ø¯ÙÛ Ø¯Ù
+ØªÙ ÙŸÙ ÛÙÙ ØšØ±Ø®Ù Ú©Û ÙØºÙ ÙŸÛÚÛ ÙÙ
+ ÙÛ ÚÙ 1903 ÙŸÚ©Û ØŽØ§Ù
+Ù ÙÛ (Ø¯Ù
+Ø«Ø§Ù ÙŸÙ ÚÙÙ ÙÚ©Ù ØŽÙÙ
+Ù ÙŸÛÚÛ). Ø¯Ø§ÙŸØ¯Û Ù
+Ø§ÙØ§ Ø¯Ù ÚÛ ÙØºÙ Ø¹ÛÙ ÙÛÙŒÙ ÛØ§ ØªØ§Ø±ÛØ® ØšÙ Ø³ØªØ§ ÙŸÙ ÙŸÙÙŒÙÙ Ú©Û ÚÚ©Ø§Ø±Ù ÙÚ©ÚÛ ØšÙÚ©Ù ÙØºÙ Ù
+Ø­Ø¯ÙØ¯Ù Ø¯ØªØ§Ø±ÛØ® ØšÙ Ø¯Ø±ØªÙ ÚÚ©Ø§Ø±Ù Ú©ÚÛ Ú©ÙÙ
+ ÚÛ Ø³ØªØ§ Ø¯ØºÙÚØªÙÛ ÙÚ ÙÛÙŒÙ ÙÙ
+ ÙŸÙ ØšØ±Ú©Û ÙÛØ³Û. <p>}  
+
+_textchangeprefs_ [l=ps] {Ø³ØªØ§ Ø¯Ø®ÙÚÛ ØšØ¯ÙÙÙÙÙÙ}  
+
+_texthelppreferences_ [l=ps] { Ú©ÙÙ ÚÛ <i>_Global:linktextPREFERENCES_</i>ØªÚŒÛ Ø¯Ù
+Ø® ÙŸÙ ÙŸÙØ±ØªÙÛ ØšØ±Ø®Ù Ú©Û Ú©ÙÛÚ© Ú©ÚÛ ÙÙ ØªÙ Ú©ÙÙØ§Û ØŽÛ ÚÛ
+Ø¯Ù
+ÙÚ ÙÛØ¯ Ø§ÚÙ ØŽÚ©ÙÙÙÙ ØªÙ Ú©ÙÙ
+ ÚÛ ØªÙ ÛÛ ØºÙØ§ÚÛ ÙØ§ÚÙÛ.}  
+
+_texthelpcollectionprefstitle_ [l=ps] {Ø¯ÙŒÙÙÚ«Û ÙÙ
+ÚÛØªÙØšÙÙÙ}  
+
+
+_texthelplanguageprefstitle_ [l=ps] {Ø¯ÚØšÛ Ø®ÙÚÛ}  
+_texthelplanguageprefs_ [l=ps] {<p>ÙØ±Ù ÙŒÙÙÚ«Ù ÙØ±ÙÙÚ©Û Ø¯ÛÙÛ Ø®Ø·Ø§ ÚØšÛ Ø¯ÙØ Ø§Ù
+Ø§ ØªØ§Ø³Ù Ú©ÙÙØ§Û ØŽÛ ÚÛ ÙØžØ± Ø³ØªØ§Ø³Ù Ø®ÙÚÛ ØªÙ
+Ù
+Ø®ØªÙÙÙ ÚØšÙ ØªÙ ÙØ§ÚØŽÛ. ÙÙ
+Ø¯Ø§Ø±ÙÚ«Ù ØªØ§Ø³Ù Ú©ÙÙØ§Û ØŽÛ ÚÛ Ø¯Ú©ÙÚ ØŽÛÙ
+Ø§ ÚÛ Ø¯Ú«Ø±ÛÙ Ø³ÙŒÙÙ ÙŸÙØ§Ø³Ø·Ù Ø¯Ú
+ÚÛØ¯Ù ÙÙŸØ§Ø±Ù ÙŸÚ©Ø§Ø± Ø§ÚÙÙ Ú©ÛÚÛ ØšØ¯Ù Ú©ÚÛ- ÙØ±Ù
+ Ø§ÙØ²Ø§Ø± ÙØºÙ Ù
+Ø¹ÙÙÙÙ  Ø®Ø·Ø§ Ø§ÙØªØ®Ø§ØšÙÛ Ø®ÙÙÙŸØ§Ø±Ù Ø¯Ø¯Û ÚÛ Ø¯Ø±Ø³ØªÛ ÚØ§ÙÚ«ÚØªÛØ§Ù ÙÚØ§ÛÛ Ø¯Ø§ØšÙ Ù
+ÙÙ
+Ù ÙÛ ÚÛ Ù
+Ø®ØªÙÙ Ú©ÙÚÙÙÙ Ø¯ØŽÛÙ
+Ø§ ØšØ¯Ù Ú©ÚÙ.
+ÙŒÙÙÛ ÙŒÙÙÚ«Û ØªØ§ØªÙ Ø§Ø¬Ø§Ø²Ù Ø¯Ø±Ú©ÙÛ ÚÛ
+Ø¯Ù
+Ø¹ÛØ§Ø±Û Ú«Ø±Ø§ÙÛÚ©Û Ø§ÚÛÚ©Û Ú
+Ø®Ù Ù
+ØªÙÛ Ø§ÚÛÚ©Û ØªÙ ÙØ§ÚØŽÛ. Ø¯Ø§ Ø¯ÙØºÙ Ø®ÙÚ©Ù ÙÙŸØ§Ø±Ù ÚÙ Ø¯Ù ÚÛ Ø¯ÙÛØ¯ÙØ³ØªÙÙÚÙ ÙÙØ±Û Ø§Ù Ø¯ÙÙÛ Ù
+Ø® ÛØ§ ØªÙØ±Ù Ú
+Ø®Ù Ú©Ø§Ø±Ø§Ø®ÙÛ.}  
+
+_texthelppresentationprefstitle_ [l=ps] {Ø¯ÙÚØ§ÙØ¯ÛØ² ØºÙØ±Ù ØªÙØšÙÙÙ }  
+_texthelppresentationprefs_ [l=ps] {ÙØžØ± ÛÙÛ ÚØ§ÙÚ«ÚÛ ÙŒÙÙÚ«Û ØªÙØ Ú©ÛØ¯Ø§Û ØŽÛ Ù
+Ø®ØªÙÙÛ ÙŒØ§Ú©ÙÛ ÙØ¬ÙØ¯ ÙÙØ±Û ØªØ±Ú
+Ù Ø®ÙŸÙ ÙÚØ§ÙØ¯ÛØ² ØªØ±ØªÛØš Ø§Ù Ú©ÙÙŒØ±ÙÙ Ú©ÚÛ.
+
+Ø¯ÙÛØš ÙŸØ§ÚŒÛ ÙŒÙÙÚ«Ù ØªØ§ØªÙ Ø§Ø¬Ø§Ø²Ù Ø¯Ø±Ú©ÙÛ ØªØ±ÚÙ Ø¯Ú«Ø±ÛÙ Ø³ÙŒÙÙ ÙØ§Ø±ÚÙÙÙÚ©Û ÙÛØ³ÙŒ Ø¯ÙØ± Ø³ÙØ¯ Ø¯Ù
+Ø® ÙŸÙ ÙŸÙØ±ØªÙÛ ØšØ±Ø®Ù ØšØ§ÙØ¯ Ø±Ø§ÙŒÙÙ Ú©ÚÛØ ÛÙÚÙÛ ÚÛ ÙŸÙÙŒÙÙ ÙÚ©ÚÛ ØªÙ ØšÙ Ø¹ÛÙ ÙÛØš ÙŸØ§ÚŒÛ ØªÙ Ø¯Ø³Ù
+ÙÙ Ø³Ø±Ù ÙØ±Ø³ÛÚÛ. ÙÙŸØ§Ø±Ù Ø¯Ø¯Û ÚÛ ØšÙÙ ÙŸÙÙŒÙÙ ÙÚ©ÚÛ ØªÙ ØšØ§ÛØ¯ Ø¯Ø®ÙŸÙ Ú©ØªÙÙ
+Ù ÙŸÙ  "ØŽØ§ØªÙ" ØªÚŒÛ ØšØ§ÙØ¯ Ú©ÙÛÚ© ÙÚ©ÚÛ. ÙÙ
+Ø¯Ø§Ø±ÙÚ«Ù Ø¯Ø§ ÙŒÙÙÚ«Û ØªØ§ØªÙ Ø§Ø¬Ø§Ø²Ù Ø¯Ø±Ú©ÙÛ ÚÛ Ø¯Ú«Ø±ÛÙ Ø³ÙŒÙÙ Ø¯Ø®ØšØ±Ø¯Ø§Ø±Û ÙŸÛØºØ§Ù
+ÙÙÙ Ø³Ø±Ù Ø±Ø§ØºÙÙØ¬ Ú©ÚÛ Ú©ÙÙ ÚÛ ÙŸÙ ÛÙÙ Ø±Ø§ØšØ·Ù ØšØ§ÙØ¯Û Ú©ÙÛÚ© ÙÚ©ÚÛ ÙØºÙ ØšÙ ØªØ§Ø³Ù Ø¯ÚÛØ¬ÛÛÙŒÙ Ú©ØªØ§ØšØªÙÙ Ø¯ÙŒÙÙÚ«Û Ú
+Ø®Ù ØšÛØ±ÙÙ ÙŸØ®ÙŸÙÙ ÙÛØš ÙŸØ§ÚŒÛ ØªÙ ØšÙÚÛ. Ú©Ù Ø§ÚÛÚ©Ù Ø¯"ÙŸÙÙŒÙÛ ÙŸØ§ÛÙÙ" ÙŸÙ Ù
+Ø® ØªØ§Ø³Ù Ù
+Ø³ØªÙÛÙ
+Ø§ URLØªÙ ØšÙÚÛ ØªØ§Ø³Ù Ú©ÙÙØ§Û ØŽÛ ÚÛ ÙŸÙ ÚÛÙÙ ÙÛØš ÙŒÙÙÚ«Ù Ú©Û ÙŸÙÚØªÙÙ Ú©ÙÙŒØ±ÙÙ Ú©ÚÛØ ÙØ³ØšØª Ø¯ÚÛØ¬ÛÙŒÙ Ú©ØªØ§ØšØªÙÙ Ú©Ø§ÙŸÛ ØªÙ ÙŸÙ Ù
+Ø® Ú©Û.}  
+
+_texthelpsearchprefstitle_ [l=ps] {Ø¯Ø®ÙÚÛ ÙŸÙÙŒÙÙ}  
+
+
+_textcasefoldprefs_ [l=ps] {Ø¯ÙŸÙÙŒÙÛ ÙŸÙ Ø¯ÙØ±Ø§Ù Ú©Û Ø¯ÚÚ©ØªÙ Ø§Ù ÙŸÙØ±ØªÙ Ø­Ø±ÙÙÙ ØºÙŒÙØ§ÙÛ Ø§Ù Ú©ÙÚÙÙØ§ÙÛØ Ú
+Ø±ÙÚ«ÙØ§ÙÛ ØšØ§ÛØ¯ Ø³Ù
+ÙÙ ÙØ®ÙØ±Û Ø¯Ø§ Ú©Ø§Ø± Ø¯ÛÙÛ Ø¬ÙÚÛ ØªÚŒÛÙ ÙÙØ§Ø³ÛØ·Ù Ú©ÙÙŒØ±ÙÙÛÚÛ. Ø¯Ù
+Ø«Ø§Ù ÙŸÙ ÚÙÙØ Ú©Ù _preferences:textignorecase_"Ø§ÙØªØ®Ø§Øš ØŽÙÛ ÙÛØ<i>snail farming</i>ØšÙ Ù
+Ø¹Ø§Ù
+ÙÙ ØŽÙÛ ÙÛ ÙÚ©Ù<i>Snail Farming</i>Ø§Ù<i>SNAIL FARMING</i>.}  
+
+_textaccentfoldprefs_ [l=ps] {Ø¯ÙŸÙÙŒÙÛ ÙŸÙ Ø¯ÙØ±Ø§Ù Ú©Û ÙÙØ¬ÙÛ ÛØ§ ØºÛØ± ÙÙØ¬ÙÛ Ø­Ø±ÙÙ ØšØ§ÛØ¯ Ø³Ù
+ÙÙ ÙØ®ÙØ±Û Ø¯Ø§ Ú©Ø§Ø± Ø¯ÛÙÛ Ø¬ÙÚÛ ØªÚŒÛÙ ÙÙØ§Ø³ÛØ·Ù Ú©ÙÙŒØ±ÙÙÛÚÛ. Ø¯Ù
+Ø«Ø§Ù ÙŸÙ ÚÙÙØ Ú©Ù"_preferences:textignoreaccents_"Ø§ÙØªØ®Ø§Øš ØŽÙÛ ÙÛ<i>fÃ©dÃ©ration</i> ØšÙ Ù
+Ø¹Ø§Ù
+ÙÙ ØŽÙÛ ÙÛ ÙÚ©Ù<i>fedÃ©ration</i>Ø§Ù<i>federation</i>.}  
+ 
+_textstemoptionsprefs_ [l=ps] {Ø¯Ø§ØšÙ ÚÛØ±Ù Ù
+ÙØ§Ø³ØšÙ Ø§Ù Ø¯ÙÛÙÙ ÙÛ ÚÛ Ø¯ÙŸÙÙŒÙÛ ØšÛ Ø³Ø±Ù Ú©ÙÛÙ
+Û ÙŸÙ Ú©Ø§Ø± ÙØ§ÚÙÙ ÙÚ©Ù ÙŸÙØ±ØªÙ ÙŸÙ"_texthelpquerytermstitle_"Ú©Û.}  
+
+_textsearchtypeprefsplain_ [l=ps] {Ø¯Ø§Ù
+Ù
+Ú©ÙÙ Ø¯Ù ÚÛ ÛÙ ÙÙÛ ÙŸÙÚØªÙ ØšÚ©Ø³ ØªØ±ÙØ§Ø³Ù Ú©ÚÙØ ÙÙ ØªÙ ÙŸÙ Ø§Ø³Ø§ÙÛ Ø³Ø±Ù Ú©ÙÙØ§Û ØŽÛ ÚÛ paragraph-sized ÙŸÙÙŒÙÙ ÙÚ©ÚÛ. Ø§Ù Ø¯Ø§Ø­ÛØ±Ø§ÙÙÙÙÚ©Û Ø¯Ù ÚÛ ÛÙÙ ÙÙÛÙ Ø§ÙØ¯Ø§Ø²Ù Ø¯ Ù
+ØªÙ Ø²Ø±ØªØ±Ø²Ø±Ù ÙÙŸÙÙŒÛ.}  
+
+_textsearchtypeprefsform_ [l=ps] {ØªÙ Ú©ÙÙØ§Û ØŽÛ ÚÛ Ø¯Ø³Ø§Ø­Ù ØŽÙ
+ÛØ±Ù ØªÙ ØšØ¯ÙÙÙ ÙØ±Ú©ÚÛ Ú©ÙÙ
+Û ÚÛ ÙŸÙ Ø¯ÙŸÙÙŒÙÛ ÙŸÙ ÙÙØ±Ù
+Ù Ú©Û ÚÙØ¯Ù ØŽÙÛ.}  
+
+_textsearchtypeprefsboth_ [l=ps] {ØªØ§Ø³Ù Ú©ÙÙØ§Û ØŽÛ ÚÛ Ø¯ÙŒÙÙÚ«Ù Ø¯ "ÙÙØ±Ù
+Ø§ÙÛ" Ø§Ù  "Ø³Ø§Ø­Ù Ø§ÛØ²Û" ÙŸÙÙŒÙÙ ØªØ±Ù
+ÙÚ ÙØ§ÙÚÛ Ø§Ù Ø±Ø§ÙØ§ÙÚÛ.
+<ul>
+<li>ÙÙØ±Ù
+Ø§ÙÙ ÙŸÙÙŒÙÙ Ø¯ÛÙØ§ÚÛÙÛ ÙŸÙÚØªÙÛ ØšÚ©Ø³ ØªÛØ§Ø±ÙÛ . _textsearchtypeprefsplain_</li>
+<li>Ø³Ø§Ø­Ù Ø§ÛØ²Ù ÙŸÙÙŒÙÙ Ø¯ÙŸÙÚØªÙ ØšÚ©Ø³ÙÙÙ ÛÙ ØŽÙ
+ÛØ± ØšØ±Ø§ØšØ±ÙÛ, ÙØ±Ù Ú
+Ø§ÙÚ«Ù ÚØ§ÙÚ«ÚÛ ØšÚ©Ø³ Ø¯ÙŸÙÚØªÙÛ ØªÛØ§Ø±ÙÛ. This enables searching over different fields at once. _textsearchtypeprefsform_ </li>
+</ul>}  
+
+
+
+_texttanumbrowseoptions_ [l=ps] {Ø¯ÙØªÙ_numbrowseoptions_ ÙØ§Ø±Û ØŽØªÙ Ø¯Û ØªØ±Ú
+Ù ÙŸÙ Ø¯Û ÙŒÙÙÚ«Ù Ú©Û Ù
+Ø¹ÙÙÙ
+Ø§Øª ØªØ±ÙØ§Ø³Ù Ú©ÚÛ:}  
+
+_textsimplehelpheading_ [l=ps] {Ú
+ÙÚ«Ù Ú©ÙÙØ§Û ØŽÙ ÚÛ Ø¯ _collectionname_ ÙŒÙÙÚ«Ù Ú©Û Ù
+Ø¹ÙÙÙ
+Ø§Øª ØªØ±ÙØ§Ø³Ù Ú©ÚÙ}  
+
+_texthelpscopetitle_ [l=ps] {Ø¯ÙŸÙÚØªÙÛ Ø­Ø¯ÙØ¯}  
+
Index: /gsdl/stable/macros/query.dm
===================================================================
--- /gsdl/stable/macros/query.dm	(revision 20131)
+++ /gsdl/stable/macros/query.dm	(revision 20131)
@@ -0,0 +1,771 @@
+# this file must be UTF-8 encoded
+package query
+
+
+#######################################################################
+# Macros whose values are set from within the server at runtime. These 
+# are here only for reference and to set default values if required.           
+#######################################################################
+
+_quotedquery_ {}
+_freqmsg_ {}
+_stopwordsmsg_ {}
+_resultline_ {}
+_thisfirst_ {}
+_thislast_ {}
+_nextfirst_ {}
+_nextlast_ {}
+_prevfirst_ {}
+_prevlast_ {}
+_searchhistorylist_ {}
+#_histvalue0_ to _histvalue19_
+_advformlist_ {}
+_regformlist_ {}
+#_fqfselection_ {}
+
+
+#######################################################################
+# icons
+#######################################################################
+
+_queryresultsbar_ {
+<div class="divbar">
+<p class="navbar">_texthresults_</p>
+</div>
+}
+
+_searchhistorybar_ {
+<div class="divbar">
+<p class="navbar">_texticonsearchhistorybar_</p>
+</div>
+}
+
+
+# _iconnext_ and _iconprev_ are overridden in this package as we
+# don't want alt text here
+_iconnext_{<img src="_httpiconmore_" width="_widthmore_" height="_heightmore_" border="0" align="top">}
+_iconnext_ [v=1] {}
+_iconprev_{<img src="_httpiconless_" width="_widthless_" height="_heightless_" border="0" align="top">}
+_iconprev_ [v=1] {}
+
+# the small squares for search history
+## " " ## handmade ## mstds ##
+_httpiconmstdsqrof_ {_httpimg_/mstdsof.gif}
+_httpiconmstdsqron_ {_httpimg_/mstdson.gif}
+_widthmstdsqrx_ {13}
+_heightmstdsqrx_ {13}
+
+#######################################################################
+# images
+#######################################################################
+
+# _imagethispage_ set in nav_css/nav_ns4 macro files
+
+#the buttons for the search history entries
+# takes one arg - the entry number (0-num entries)
+_imagehistbutton_ {<a  href="_httpquery_" onMouseover="roll('histbutton_1_',1);" onMouseOut="roll('histbutton_1_',0);" onClick="inputQuery(histvalue_1_); return false;"><img name="histbutton_1_" src="_httpiconmstdsqrof_" onLoad="gbutton(this,'_httpiconmstdsqron_');" border="0" alt="_textusequery_" title="_textusequery_"></a>}
+
+
+#######################################################################
+# scripts (and some macros for the scripts)
+#######################################################################
+
+_pagescriptextra_ {_If_("_cgiargqt_" eq "1", _formpagescriptextra_, _selectpagescriptextra_)
+_If_("_cgiarghd_" ne "0",_historypagescriptextra_) }
+
+_selectpagescriptextra_{_If_("_cgiargqto_" eq "2", _formpagescriptextra_,_dummypagescriptextra_)}
+_dummypagescriptextra_{function initialize() \{
+\} }
+_formpagescriptextra_ {
+// query scripts generated by \_query:pagescriptextra\_
+
+_standardfunctions_
+_formfunctions_
+_searchfunctions_
+
+function getsearchargs () \{
+
+  var args="";
+  args = "&fqa=0&fqv="+argfqv+"&fqf="+argfqf;
+  _If_(_cgiargb_,args += "&fqk="+argfqk+"&fqs="+argfqs+"&fqc="+argfqc;)
+
+  return args;
+\}
+
+
+
+function getqueryargs () \{
+  return "&fqa=1"+"&q="+argq+"&fqv="+argfqv+"&fqf="+argfqf+
+	 "&fqk="+argfqk+"&fqs="+argfqs+"&fqc="+argfqc ;
+\}
+
+}
+
+_historypagescriptextra_{
+
+var histvalue0='_histvalue0_';
+var histvalue1='_histvalue1_';
+var histvalue2='_histvalue2_';
+var histvalue3='_histvalue3_';
+var histvalue4='_histvalue4_';
+var histvalue5='_histvalue5_';
+var histvalue6='_histvalue6_';
+var histvalue7='_histvalue7_';
+var histvalue8='_histvalue8_';
+var histvalue9='_histvalue9_';
+var histvalue10='_histvalue10_';
+var histvalue11='_histvalue11_';
+var histvalue12='_histvalue12_';
+var histvalue13='_histvalue13_';
+var histvalue14='_histvalue14_';
+var histvalue15='_histvalue15_';
+var histvalue16='_histvalue16_';
+var histvalue17='_histvalue17_';
+var histvalue18='_histvalue18_';
+var histvalue19='_histvalue19_';
+
+function inputQuery(value) \{
+  if ("_cgiargqt_" == "0") \{ // text search
+     document.QueryForm.q.value += " "+value;
+     document.QueryForm.q.focus();
+  \}
+  else \{
+     if ("_cgiargb_" == "1") \{ // advanced query
+        document.QueryForm.q.value += " "+value;
+	document.QueryForm.q.focus();	   
+	updateq();
+     \}
+     else \{ // simple form search
+	  // do something here, what??
+     \}
+  \}
+\}
+
+}
+
+_standardfunctions_{
+
+ function getstdargs() \{
+    
+    stdarg = "";
+    _If_(_gselection_,_getgarg_)	
+    _If_(_jselection_,_getjarg_)
+    _If_(_nselection_,_getnarg_)
+    _If_(_sfselection_,_getsfarg_)
+    if (document.QueryForm.t != null) \{
+      value = document.QueryForm.t.options[document.QueryForm.t.selectedIndex].value;
+      if (value != "_cgiargt_") stdarg += "&t="+value;
+    \}
+    stdarg += "&r=1&hs=1";    
+    return stdarg;
+  \}
+
+}
+
+_getgarg_{
+    if (document.QueryForm.g!= null) \{
+    value = document.QueryForm.g.options[document.QueryForm.g.selectedIndex].value;
+    if (value != "_cgiargg_") stdarg += "&g="+value;
+  \}
+}
+
+_getjarg_{
+    value = document.QueryForm.j.options[document.QueryForm.j.selectedIndex].value;
+    if (value != "_cgiargj_") stdarg += "&j="+value;
+}
+
+_getnarg_{
+    value = document.QueryForm.n.options[document.QueryForm.n.selectedIndex].value;
+    if (value != "_cgiargn_") stdarg += "&n="+value;
+}
+
+_getsfarg_{
+    value = document.QueryForm.sf.options[document.QueryForm.sf.selectedIndex].value;
+    if (value != "_cgiargsf_") stdarg += "&sf="+value;
+}
+
+_formfunctions_{
+
+argfqf="_cgiargfqf_";	
+argfqv="_cgiargfqv_";
+argfqk="_cgiargfqk_";
+argfqs="_cgiargfqs_";
+argfqc="_cgiargfqc_";
+argq = "";
+
+function initialize () \{
+
+   if (document.QueryForm.fqf != null) \{initfqf(); \}
+   if (document.QueryForm.fqv != null) \{initfqv(); \}
+   if (document.QueryForm.fqs != null) \{initfqs(); \}
+   if (document.QueryForm.fqk != null) \{initfqk(); \}
+   if (document.QueryForm.fqc != null) \{initfqc(); \}
+   if (document.QueryForm.q != null) \{initq(); \}   
+\}
+
+// makes a form submit itself when enter is pressed in a text field
+function entersubmit(event) \{
+	 
+  if (window.event && window.event.keyCode == 13) \{
+    beginSearch();
+  \} else \{
+     if (event && event.which == 13) \{
+       beginSearch();
+     \} else \{
+        return true;
+    \}
+  \} 
+\}
+
+   
+// fqf - the field selection box
+function initfqf() \{
+   var i;
+   fqf = argfqf.split(",");
+   num_opts = document.QueryForm.fqf[0].options.length; // assumes all have the same  options   
+   for (i=0; i<fqf.length && i<document.QueryForm.fqf.length; i++) \{
+     if (fqf[i] != "")\{			
+       for (j=0;j<num_opts;j++) \{
+	   if (fqf[i]== document.QueryForm.fqf[i].options[j].value) \{
+	      document.QueryForm.fqf[i].options[j].selected = true;
+	      break;	
+	   \}
+	\}
+     \}
+   \}
+   if (fqf.length < document.QueryForm.fqf.length) \{ // initialize remaining ones
+      for (i=fqf.length;i<document.QueryForm.fqf.length;i++) \{
+	  var z=i;
+	  while (z >= num_opts) \{
+	     z = z-(num_opts);
+	  \}
+	  document.QueryForm.fqf[i].options[z].selected = true;
+	  
+      \}
+   \}
+   updatefqf();
+
+\}
+
+function updatefqf() \{
+
+   var i;
+   argfqf = "";
+   var j = document.QueryForm.fqf[0].selectedIndex;
+   argfqf += document.QueryForm.fqf[0].options[j].value;
+   for (i=1; i<document.QueryForm.fqf.length;i++) \{
+      j = document.QueryForm.fqf[i].selectedIndex;
+      argfqf += "," + document.QueryForm.fqf[i].options[j].value;
+   \}
+
+\}
+
+
+function clearfqf() \{
+   var i;
+   for (i=0;i<document.QueryForm.fqf.length;i++) \{
+       var z = i;
+       if (i >= document.QueryForm.fqf[i].options.length) z = z-document.QueryForm.fqf[i].options.length;
+       document.QueryForm.fqf[i].options[z].selected = true;
+   \}
+   updatefqf();
+\}
+
+// fqc - the boolean operator selection box
+function initfqc() \{
+   var i,j;
+   fqc = argfqc.split(",");
+   if (_cgiargfqn_ == 2) \{ // there will only be one fqc element
+       for (j=0;j<document.QueryForm.fqc.options.length;j++) \{
+	   if (fqc[0] == document.QueryForm.fqc.options[j].value) \{
+	      document.QueryForm.fqc.options[j].selected = true;
+	      break;
+	   \}
+       \}   
+   \}
+   else \{   
+   for (i=0; i<fqc.length;i++) \{
+       for (j=0;j<document.QueryForm.fqc[i].options.length;j++) \{
+	   if (fqc[i] == document.QueryForm.fqc[i].options[j].value) \{
+	      document.QueryForm.fqc[i].options[j].selected = true;
+	      break;
+	   \}
+       \}
+   \}
+   \}
+   updatefqc();
+
+\}
+
+function updatefqc() \{
+  
+   var i,j;
+   argfqc = "";
+   if (_cgiargfqn_ == 2) \{
+      j = document.QueryForm.fqc.selectedIndex;
+      argfqc += document.QueryForm.fqc.options[j].value;
+   \}
+   else \{
+	j = document.QueryForm.fqc[0].selectedIndex;
+	argfqc += document.QueryForm.fqc[0].options[j].value;
+	for (i=1;i<document.QueryForm.fqc.length;i++) \{
+	    j = document.QueryForm.fqc[i].selectedIndex;
+	    argfqc += "," + document.QueryForm.fqc[i].options[j].value;
+	\}
+   \}
+
+\}
+
+
+function clearfqc() \{
+   
+   var i;
+   if (_cgiargfqn_ == 2) \{
+       document.QueryForm.fqc.options[0].selected = true;
+   \}
+   else \{
+	for (i=0; i<document.QueryForm.fqc.length; i++) \{
+	    document.QueryForm.fqc[i].options[0].selected = true;
+	\}
+   \}
+   updatefqc();
+\}
+
+// fqv - the query word/phrase text box       
+function initfqv() \{
+   var i;
+   fqv= argfqv.split(",");
+   for (i=0; i<fqv.length && i<document.QueryForm.fqv.length; i++) \{
+       document.QueryForm.fqv[i].value = fqv[i];
+   \}
+   updatefqv();
+
+
+\}
+
+   //argfqv += escape(format(document.QueryForm.fqv[0].value));
+
+function updatefqv() \{  
+   var i;
+   argfqv="";
+   argfqv += format(document.QueryForm.fqv[0].value);
+   for (i=1; i<document.QueryForm.fqv.length;i++) \{
+       argfqv += ",";
+       argfqv +=  format(document.QueryForm.fqv[i].value); 
+   \}
+\}
+
+function clearfqv() \{
+   var i;
+   for (i=0; i< document.QueryForm.fqv.length;i++) \{
+       document.QueryForm.fqv[i].value = "";
+   \}
+   updatefqv();
+\}
+
+// fqs - the stemming checkboxes
+function initfqs() \{
+
+   var i;
+   fqs = argfqs.split(",");
+   for (i=0; i<fqs.length; i++) \{
+       if (fqs[i]=="1") \{
+	  document.QueryForm.fqs[i].checked = true;
+       \}
+   \}
+   updatefqs();
+
+\}
+
+function updatefqs() \{
+   argfqs="";
+   if (document.QueryForm.fqs[0].checked) \{
+      argfqs += "1";
+   \}
+   else \{
+      argfqs += "0";	
+   \}
+   var i;
+   for (i=1; i<document.QueryForm.fqs.length; i++) \{
+       if (document.QueryForm.fqs[i].checked) \{
+	  argfqs += ",1";
+	\}
+	else \{
+	  argfqs += ",0";
+	\}
+   \}
+\}
+
+
+function clearfqs() \{
+   var i;
+   for (i=0; i<document.QueryForm.fqs.length; i++) \{
+       document.QueryForm.fqs[i].checked = false;
+   \}
+   updatefqs();
+\}
+
+// kqk - the casefolding checkboxes
+function initfqk() \{
+   var i;
+   fqk = argfqk.split(",");
+   for (i=0; i<fqk.length; i++) \{
+       if (fqk[i]=="1") \{
+	  document.QueryForm.fqk[i].checked = true;
+       \}
+   \}
+   updatefqk();
+
+\}
+
+
+function updatefqk() \{
+   argfqk="";
+   if (document.QueryForm.fqk[0].checked) \{
+      argfqk += "1";
+   \}
+   else \{
+      argfqk += "0";	
+   \}
+   var i;
+   for (i=1; i<document.QueryForm.fqk.length; i++) \{
+       if (document.QueryForm.fqk[i].checked) \{
+	  argfqk += ",1";
+	\}
+	else \{
+	  argfqk += ",0";
+	\}
+   \}
+\}
+
+function clearfqk() \{
+   var i;
+   for (i=0; i<document.QueryForm.fqk.length; i++) \{
+       document.QueryForm.fqk[i].checked = false;
+   \}
+   updatefqk();
+\}
+
+// q - the advanced query box
+function initq() \{
+   updateq();
+\}
+
+function updateq() \{
+  
+   argq = "";
+   argq += format(document.QueryForm.q.value);
+\}
+
+function clearq() \{
+   document.QueryForm.q.value="";
+\}
+
+
+// convert commas and spaces to plus
+// also convert other illegal characters to %xx codes
+function format(string) \{
+   var str = "" + string;
+   var out = "", flag = 0;
+   var ch = "";
+   var j;
+   for (j = 0; j < str.length; j++) \{
+       ch=str.charAt(j);
+       if (ch == " "|| ch == ",") \{
+           if ( flag == 0) \{     
+	      out += "+";
+	      flag=1;
+	    \}
+	    continue;
+	\}
+	if (ch == ";" || ch == ":" || ch == "/" || ch == "?" ||
+            ch == "@" || ch == "&" || ch == "=" || ch == "#") \{
+	    out += escape(ch);
+	    flag=0;
+	    continue;
+	 \}	      
+	out += str.charAt(j);
+	flag=0;
+   \}
+   return out;
+\}
+
+}
+
+#_httpquery_ has a=q&e=compressedargs
+#if adv form, need to set k=0 and s=0
+_advformargs_{_If_(_cgiargb_,&k=0&s=0)}
+
+_searchfunctions_ {
+
+function beginSearch() \{
+window.location="_httpquery_"+getstdargs()+"_advformargs_"+getsearchargs();
+\}
+
+function runQuery() \{
+window.location="_httpquery_"+getstdargs()+"_advformargs_"+getqueryargs();
+\}
+
+function clearForm() \{
+   clearfqf();
+   clearfqv();
+
+   if ("_cgiargb_" == "1") \{
+      clearfqk();
+      clearfqs();
+      clearfqc();
+   \}
+
+\}
+
+}
+
+#######################################################################
+# headers
+# these are overridden so we can put an onLoad event handler
+# in the <body> tag of this page - for mgpp, form search pages
+#######################################################################
+
+#copied from prefs 
+
+_header_ {_cgihead_
+_htmlhead_(class="bgimage" onLoad="initialize();")_startspacer__pagebanner_
+}
+
+# this declaration ends up being the same as style=restrict, never mind
+_header_[v=1] {_cgihead_
+_htmlhead_(onLoad="initialize();")_pagebanner_
+}
+
+#######################################################################
+# page content
+#######################################################################
+
+
+_pagetitle_ {_If_(_cgiargq_,_textquerytitle_,_textnoquerytitle_)}
+
+
+_content_ {
+
+_optnavigationbar_
+<div class="document">
+<div class="queryform">
+_If_(_cgiargct_,_selectqueryform_,_queryform_)
+</div>
+
+_If_(_searchhistorylist_,<center>_searchhistorybar_</center><br>
+<center>
+_searchhistorylist_
+</center>)
+_If_(_cgiargq_,_queryresultsbar_
+<small>
+_freqmsg_
+_textpostprocess_
+_If_(_stopwordsmsg_,(_stopwordsmsg_))</small><br />
+_resultline_
+,<div class="divbar">&nbsp;</div>)
+}
+
+_selectqueryform_{_If_("_cgiargqt_" eq "1",_fieldqueryform_,_queryform_)}
+
+_queryform_ {
+<!-- query form (\_query:plainqueryform\_) -->
+<form name="QueryForm" method="get" action="_gwcgi_">
+<p>
+<input type="hidden" name="a" value="q">
+<input type="hidden" name="r" value="1">
+<input type="hidden" name="hs" value="1">
+<input type="hidden" name="e" value="_decodedcompressedoptions_">
+_queryformcontent_
+_optdatesearch_
+</p>
+</form>
+<!-- end of query form -->
+}
+
+_ifeellucky_ { <br><input type="checkbox" name="ifl" value="1">_textifeellucky_ }
+_useifeellucky_ { }  # Set this to _ifeellucky_ if you want this functionality available
+
+_allowformbreak_{</span>  <span class="textselect">}
+
+_queryformcontent_{
+<span class="textselect">
+_textselect_
+</span>
+
+<span class="querybox">
+_If_(_cgiargqb_,_largequerybox_,_smallquerybox_)
+_useifeellucky_
+</span>
+}
+
+# Automatically set by receptionist if config file switches
+# date searching on
+_optdatesearch_ { } 
+
+
+_datesearch_
+{<table><tr><td>
+	<center>
+_textstartdate_
+<input type="text" name="ds" value="_cgiargds_" size="4" maxlength="4">
+<select name="dsbc" value="_cgiargdsbc_" size="1">
+	<option value="0"_If_(_cgiargdsbc_,, selected)>_textad_
+	<option value="1"_If_(_cgiargdsbc_, selected)>_textbc_
+</select> 
+_textenddate_
+<input type="text" name="de" value="_cgiargde_" size="4" maxlength="4"> 
+<select name="debc" size="1">
+	<option value="0" _If_(_cgiargdebc_,, selected)>_textad_
+	<option value="1" _If_(_cgiargdebc_, selected)>_textbc_
+</select> 
+</center>	  
+</td></tr>
+<tr><td>
+_textexplaineras_
+</td></tr>
+</table>
+</center>
+}
+
+_smallquerybox_ {<nobr><input type="text" name="q" value="_cgiargq_" size="50">&nbsp;<input type="submit" value="_textbeginsearch_"></nobr>}
+
+_largequerybox_ {
+<tr><td><textarea name="q" cols="63" rows="10">
+_cgiargq_
+</textarea></td></tr>
+<tr align="right"><td><table>
+<tr><td><input type="submit" value="_textbeginsearch_"></td>
+</tr></table></td></tr>}
+
+
+_fieldqueryform_ {
+<noscript>
+<p><b>_textnojsformwarning_</b></p>
+</noscript>
+<!-- field query form (\_query:fieldqueryform\_) -->
+<form name="QueryForm" method="get" action="_gwcgi_">
+
+<table><tr><td align="left">
+_textformselect_
+</td></tr>
+<tr><td>
+_If_(_cgiargb_,_advancedforms_,_simpleforms_)
+</td></tr>
+</table>
+_If_(_cgiargb_,<div class="divbar">&nbsp;</div>
+_advancedformextra_)
+
+</form>
+<!-- end of query form -->
+}
+
+_advancedforms_{
+<table border="0" cellspacing="0" cellpadding="0" width="90%">
+<tr><th></th><th align="left">_textwordphrase_</th>_If_("_cgiargct_" eq "1",<th colspan="2"><nobr>_textfoldstem_</nobr></th>)<th align="center">&nbsp;&nbsp;_textinfield_</th></tr>	
+_advformlist_
+<tr>
+<td colspan="2" align="left"><input type="button" value="_textclearform_" onClick="clearForm();"></td>
+<td colspan="3" align="right"><input type="button" value="_textbeginsearch_" onClick="beginSearch();"></td>
+</tr>
+</table>
+}
+
+_advancedformextra_{
+<table>
+<tr><td align="left">_textadvquery_</td></tr>
+<tr><td><textarea name="q" cols="57" rows="3" onChange="updateq();">_cgiargq_</textarea></td>
+<td valign="bottom">
+<input type="button" value="_textrunquery_" onClick="runQuery();"></td></tr>
+</table>
+}
+
+_simpleforms_{
+<table border="0" cellspacing="0" cellpadding="0" width="90%">
+<tr><th align="left">_textwordphrase_</th><th align="left">&nbsp;&nbsp;_textinfield_</th></tr>	
+_regformlist_
+<tr>
+<td align="left"><input type="button" value="_textclearform_" onClick="clearForm();"></td>
+<td align="right"><input type="button" value="_textbeginsearch_" onClick="beginSearch();"></td>
+</tr>
+</table>}
+
+_regformelement_{
+<tr><td><input type="text" size="39" name="fqv" onChange="updatefqv();" onkeypress="updatefqv(); entersubmit(event);"></td>
+<td>_fqfselection_</td></tr>}
+
+#has no and/or/not selection box
+_firstadvformelement_{
+<tr><td></td><td><input type="text" size="31" name="fqv" onChange="updatefqv();" onkeypress="updatefqv(); entersubmit(event);"></td>
+_If_("_cgiargct_" eq "1",<td align="center"><input type="checkbox" name="fqk" onClick="updatefqk();"></td>
+<td align="center"><input type="checkbox" name="fqs" onClick="updatefqs();"></td>)
+<td align="right">_fqfselection_</td></tr>}
+
+_advformelement_{
+<tr><td>_fqcselection_</td>
+<td><input type="text" size="31" name="fqv" onChange="updatefqv();" onkeypress="updatefqv(); entersubmit(event);"></td>
+_If_("_cgiargct_" eq "1",<td align="center"><input type="checkbox" name="fqk" onClick="updatefqk();"></td>
+<td align="center"><input type="checkbox" name="fqs" onClick="updatefqs();"></td>)
+<td align="right">_fqfselection_</td></tr>}
+
+
+
+_fqcselection_ {
+<select name="fqc" onChange="updatefqc();">
+<option value="and">_textand_
+<option value="or">_textor_
+<option value="not">_textandnot_
+</select>}
+
+_textselect_ {_If_(_cgiargb_,_chooseadvancedsearch_,_textsimplesearch_)}
+_chooseadvancedsearch_ {_If_(_cgiargct_,_If_("_cgiargct_" eq "2",_textadvancedlucenesearch_,_textadvancedmgppsearch_),_textadvancedsearch_}
+_textformselect_ {_If_(_cgiargb_,_chooseformadvancedsearch_,_textformsimplesearch_)}
+_chooseformadvancedsearch_ {_If_("_cgiargct_" eq "1",_textformadvancedsearchmgpp_)_If_("_cgiargct_" eq "2",_textformadvancedsearchlucene_)}
+
+# mg uses hselection for index, mgpp uses fqfselection 
+_indexselection_{_If_(_cgiargct_,_fqfselection_,_hselection_)}
+
+# we want to put the links to previous/next pages of results
+# in the footer
+_pagefooterextra_ {
+<center>
+<table cellspacing="0" cellpadding="0" width="_pagewidth_">
+<tr>
+<td align="left">_If_(_prevfirst_,<a href="_httpquery_&amp;r=_prevfirst_">_iconprev__textmatches__prevfirst_ - _prevlast_</a>)</td>
+<td align="right">_If_(_nextfirst_,<a href="_httpquery_&amp;r=_nextfirst_">_textmatches__nextfirst_ - _nextlast__iconnext_</a>)</td>
+</tr></table>
+</center>
+
+</div> <!-- document -->
+}
+
+_querytypeselection_ {
+<select name="t">
+<option value="1"_If_(_cgiargt_, selected)>_If_(_cgiargb_,_textranked_,_textsome_)
+<option value="0"_If_(_cgiargt_,, selected)>_If_(_cgiargb_,_textboolean_,_textall_)
+</select>
+}
+
+
+_formquerytypesimpleselection_ {
+<select name="t">
+<option value="1"_If_(_cgiargt_, selected)>_textsome_
+<option value="0"_If_(_cgiargt_,, selected)>_textall_
+</select>
+}
+
+_formquerytypeadvancedselection_ {
+<select name="t">
+<option value="1"_If_(_cgiargt_, selected)>_textranked_
+<option value="0"_If_(_cgiargt_,, selected)>_textnatural_
+</select>
+}
+
+# this one is not used by english.dm any more. But I have added it back for the other languages that haven't updated the translations for their form search  macros.
+_formquerytypeselection_ {
+<select name="t">
+<option value="1"_If_(_cgiargt_, selected)>_If_(_cgiargb_,_textranked_,_textsome_)
+<option value="0"_If_(_cgiargt_,, selected)>_If_(_cgiargb_,_textnatural_,_textall_)
+</select>
+}
+
Index: /gsdl/stable/macros/romanian.dm
===================================================================
--- /gsdl/stable/macros/romanian.dm	(revision 20131)
+++ /gsdl/stable/macros/romanian.dm	(revision 20131)
@@ -0,0 +1,743 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# English Language text and icon macros 
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=ro] {Periodice}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=ro] {sursa referitÄ:}  
+_textdate_ [l=ro] {data publicÄrii:}  
+_textnumpages_ [l=ro] {nr. de pagini:}  
+
+_textsignin_ [l=ro] {autentificare}  
+
+_textdefaultcontent_ [l=ro] {Pagina cerutÄ nu a fost gÄsitÄ. VÄ rugÄm folosiÅ£i funcÅ£ia 'back' a browserului sau butonul home de mai sus pentru a vÄ reÃ®ntoarce la Greenstone Digital Library.}  
+
+_textdefaulttitle_ [l=ro] {Eroare GSDL}  
+
+_textbadcollection_ [l=ro] {AceastÄ colecÅ£ie (intitulatÄ "_cvariable_") nu este instalatÄ pe acest sistem Greenstone.}  
+
+_textselectpage_ [l=ro] {-- Select Page --}  
+
+_collectionextra_ [l=ro] {AceastÄ colecÅ£ie conÅ£ine documente_about:numdocs_. 
+ColecÅ£ia a fost constituitÄ acum _about:builddate_ zile.}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=ro] {<p>AceastÄ colecÅ£ie conÅ£ine _numdocs_ _If_("_numdocs_" ex: â1â,document,documente) un total de _numbytes_ texte Åi metadate indexate.
+<p><a href="_httppagex_(bsummary)">ApasÄ aici</a> pentru a vedea raportul de Ã®ntocmire a acestei colecÅ£ii.
+}  
+
+_textdescrcollection_ [l=ro] {}
+_textdescrabout_ [l=ro] {Pagina Despre}  
+_textdescrhome_ [l=ro] {Pagina home}  
+_textdescrhelp_ [l=ro] {Pagina de asistenÅ£Ä}  
+_textdescrpref_ [l=ro] {Pagina PreferinÅ£elor}  
+_textdescrgreenstone_ [l=ro] {Greenstone Digital Library Software}  
+_textdescrusab_ [l=ro] {Ce Å£i s-a pÄrut greu de utilizat ?}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=ro] {CautÄ}  
+_labelSearch_ [l=ro] {CÄutare}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=ro] {Titlu}  
+_labelTitle_ [l=ro] {Titluri}  
+_textCreator_ [l=ro] {Creator}  
+_labelCreator_ [l=ro] {Creatori}  
+_textSubject_ [l=ro] {Subiect}  
+_labelSubject_ [l=ro] {Subiecte}  
+_textDescription_ [l=ro] {Descriere}  
+_labelDescription_ [l=ro] {Descrieri}  
+_textPublisher_ [l=ro] {Responsabilitate}  
+_labelPublisher_ [l=ro] {Responsabilitate}  
+_textContributor_ [l=ro] {Contribuitor}  
+_labelContributor_ [l=ro] {Contribuitori}  
+_textDate_ [l=ro] {Data}  
+_labelDate_ [l=ro] {Date calendaristice}  
+_textType_ [l=ro] {Tip}  
+_labelType_ [l=ro] {Tipuri}  
+_textFormat_ [l=ro] {Format}  
+_labelFormat_ [l=ro] {Formate}  
+_textIdentifier_ [l=ro] {Identificator}  
+_labelIdentifier_ [l=ro] {Identificatori}  
+_textSource_ [l=ro] {Numele fiÅierului}  
+_labelSource_ [l=ro] {Numele fiÅierelor}  
+_textLanguage_ [l=ro] {LimbÄ}  
+_labelLanguage_ [l=ro] {Limbi}  
+_textRelation_ [l=ro] {RelaÅ£ie}  
+_labelRelation_ [l=ro] {RelaÅ£ii}  
+_textCoverage_ [l=ro] {Domeniu}  
+_labelCoverage_ [l=ro] {Domeniu}  
+_textRights_ [l=ro] {Drepturi de autor}  
+_labelRights_ [l=ro] {Drepturi de autor}  
+
+# DLS metadata set
+_textOrganization_ [l=ro] {InstituÅ£ia}  
+_labelOrganization_ [l=ro] {OrganizaÅ£ii}  
+_textKeyword_ [l=ro] {Cuvinte cheie}  
+_labelKeyword_ [l=ro] {Cuvinte cheie}  
+_textHowto_ [l=ro] {Cum sÄ}  
+_labelHowto_ [l=ro] {Cum sÄ}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=ro] {FrazÄ}  
+_labelPhrase_ [l=ro] {Fraze}  
+_textCollage_ [l=ro] {Colaj}  
+_labelCollage_ [l=ro] {Colaj}  
+_textBrowse_ [l=ro] {Navigare}  
+_labelBrowse_ [l=ro] {NavigheazÄ}  
+_textTo_ [l=ro] {CÄtre}  
+_labelTo_ [l=ro] {CÄtre}  
+_textFrom_ [l=ro] {De la}  
+_labelFrom_ [l=ro] {De la}  
+_textAcronym_ [l=ro] {Acronim}  
+_labelAcronym_ [l=ro] {Acronime}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=ro] {NavigheazÄ prin _1_}  
+
+_textdescrSearch_ [l=ro] {CautÄ dupÄ termeni specifici}  
+_textdescrType_ [l=ro] {NavigheazÄ dupÄ tipul resurselor}  
+_textdescrIdentifier_ [l=ro] {NavigheazÄ dupÄ identificatorul resurselor}  
+_textdescrSource_ [l=ro] {NavigheazÄ dupÄ titlul original al fiÅierului}  
+_textdescrTo_ [l=ro] {NavigheazÄ dupÄ cÃ¢mpul CÄtre}  
+_textdescrFrom_ [l=ro] {NavigheazÄ dupÄ cÃ¢mpurile Formularului}  
+_textdescrCollage_ [l=ro] {NavigheazÄ prin colajele de imagini}  
+_textdescrAcronym_ [l=ro] {NavigheazÄ printre acronime}  
+_textdescrPhrase_ [l=ro] {NavigheazÄ frazele}  
+_textdescrHowto_ [l=ro] {NavigheazÄ prin ghidul referitor la categorii}  
+_textdescrBrowse_ [l=ro] {NavigheazÄ prin documente}  
+_texticontext_ [l=ro] {AfiÅeazÄ documentul}  
+_texticonclosedbook_ [l=ro] {deschide acest document Åi afiÅeazÄ conÅ£inutul}  
+_texticonnext_ [l=ro] {cÄtre urmÄtoarea secÅ£iune}  
+_texticonprev_ [l=ro] {cÄtr secÅ£iunea anterioarÄ}  
+
+_texticonworld_ [l=ro] {AfiÅeazÄ documentul web}  
+
+_texticonmidi_ [l=ro] {AfiÅeazÄ documentul MIDI}  
+_texticonmsword_ [l=ro] {AfiÅeazÄ documentul Microsoft Word}  
+_texticonmp3_ [l=ro] {AfiÅeazÄ documentul MP3}  
+_texticonpdf_ [l=ro] {AfiÅeazÄ documentul PDF}  
+_texticonps_ [l=ro] {AfiÅeazÄ documentul PostScript}  
+_texticonppt_ [l=ro] {AfiÅeazÄ documentul PowerPoint}  
+_texticonrtf_ [l=ro] {AfiÅeazÄ documentul RTF}  
+_texticonxls_ [l=ro] {AfiÅeazp documentul Excel}  
+
+_page_ [l=ro] {paginÄ}  
+_pages_ [l=ro] {pagini}  
+_of_ [l=ro] {al}  
+_vol_ [l=ro] {Vol.}  
+_num_ [l=ro] {Nr.}  
+
+_textmonth00_ [l=ro] {}
+_textmonth01_ [l=ro] {Ianuarie}  
+_textmonth02_ [l=ro] {Februarie}  
+_textmonth03_ [l=ro] {Martie}  
+_textmonth04_ [l=ro] {Aprilie}  
+_textmonth05_ [l=ro] {Mai}  
+_textmonth06_ [l=ro] {Iunie}  
+_textmonth07_ [l=ro] {Iulie}  
+_textmonth08_ [l=ro] {August}  
+_textmonth09_ [l=ro] {Septembrie}  
+_textmonth10_ [l=ro] {Octombrie}  
+_textmonth11_ [l=ro] {Noiembrie}  
+_textmonth12_ [l=ro] {Decembrie}  
+
+_textdocument_ [l=ro] {Document}  
+_textsection_ [l=ro] {SecÅ£ie}  
+_textparagraph_ [l=ro] {Paragraf}  
+
+_magazines_ [l=ro] {Reviste}  
+
+_nzdlpagefooter_ [l=ro] {<div class="divbar">Â </div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">Universitatea din Waikato</a>, 
+New Zealand}  
+
+_linktextHOME_ [l=ro] {HOME}  
+_linktextHELP_ [l=ro] {ASISTENÅ¢Ä}  
+_linktextPREFERENCES_ [l=ro] {PREFERINÅ¢E}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=ro] {Biblioteca DigitalÄ Greenstone}  
+
+_textnocollections_ [l=ro] {Nu existÄ colecÅ£ii disponibile (i.e. constituite Åi publice)}  
+
+_textadmin_ [l=ro] {Pagina de Administrare}  
+_textabgs_ [l=ro] {Despre Greenstone}  
+_textgsdocs_ [l=ro] {DocumentaÅ£ia Greenstone}  
+
+_textdescradmin_ [l=ro] {VÄ permite adÄugarea unor noi utilizatori, subsumeazÄ colecÅ£iile din sistem Åi oferÄ informaÅ£ii despre instalarea Greenstone
+}  
+
+_textdescrgogreenstone_ [l=ro] {InformaÅ£ii despre software-ul Greenstone Åi despre Proiectul Bibliotecilor Digitale din Noua ZeelandÄ, unde Ã®Åi are originile acest software
+}  
+
+_textdescrgodocs_ [l=ro] {Manualele Greenstone}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=ro] {InterfaÅ£a bibliotecarului}  
+_textdescrgli_ [l=ro] {VÄ ajutÄ sÄ creaÅ£i noi colecÅ£ii, sÄ le modificaÅ£i sau sÄ le adÄugaÅ£i la cele existente sau sÄ le ÅtergeÅ£i}  
+
+package collector
+
+_textcollector_ [l=ro] {Colectorul}  
+_textdescrcollector_ [l=ro] {scopurilor ar trebui utilizatÄ interfaÅ£a bibliotecarului}  
+
+package depositor
+
+_textdepositor_ [l=ro] {Depozitarul}  
+_textdescrdepositor_ [l=ro] {Te ajutÄ la adÄugarea documentelor la colecÅ£ia existentÄ}  
+
+package gti
+
+_textgti_ [l=ro] {InterfaÅ£a de Traducere a sistemului Greenstone}  
+_textdescrtranslator_ [l=ro] {VÄ ajutÄ sÄ actualizaÅ£i versiunile multilingve ale interfeÅ£ei Greenstone }  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=ro] {Despre aceastÄ colecÅ£ie}  
+
+_textsubcols1_ [l=ro] {<p>ColecÅ£ia completÄ cuprinde _1_ subcolecÅ£ii. 
+Cele disponibile sunt:
+<blockquote>}  
+
+_textsubcols2_ [l=ro] {</blockquote>
+PoÅ£i verifica (sau modifica) care dintre colecÅ£ii sunt folosite acum din pagina PreferinÅ£e.}  
+
+_titleabout_ [l=ro] {despre}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=ro] {Ã®nchide aceastÄ secÅ£iune a bibliotecii}  
+_texticonclosedbookshelf_ [l=ro] {deschide acestÄ secÅ£iune a bibliotecii Åi examineazÄ conÅ£inutul}  
+_texticonopenbook_ [l=ro] {Ã®nchide aceastÄ carte}  
+_texticonclosedfolder_ [l=ro] {Deschide acest folder Åi examineazÄ conÅ£inutul}  
+_texticonclosedfolder2_ [l=ro] {deschide sub-secÅ£iunea:}  
+_texticonopenfolder_ [l=ro] {Ã®nchide acest folder}  
+_texticonopenfolder2_ [l=ro] {Ã®nchide sub-secÅ£iunea:}  
+_texticonsmalltext_ [l=ro] {AfiÅeazÄ aceastÄ secÅ£iune a textului}  
+_texticonsmalltext2_ [l=ro] {afiÅeazÄ text:}  
+_texticonpointer_ [l=ro] {secÅ£iunea curentÄ}  
+_texticondetach_ [l=ro] {Deschide aceastÄ paginÄ Ã®ntr-o nouÄ fereastrÄ}  
+_texticonhighlight_ [l=ro] {SubliniazÄ termenii de cÄutare}  
+_texticonnohighlight_ [l=ro] {Nu sublinia termenii de cÄutare}  
+_texticoncontracttoc_ [l=ro] {Contrage cuprinsul}  
+_texticonexpandtoc_ [l=ro] {Deschide cuprinsul}  
+_texticonexpandtext_ [l=ro] {AfiÅeazÄ tot textul}  
+_texticoncontracttext_ [l=ro] {AfiÅeazÄ textul doar pentru secÅ£iunea selectata}  
+_texticonwarning_ [l=ro] {<b>AtenÅ£ie: </b>}  
+_texticoncont_ [l=ro] {continui?}  
+
+_textltwarning_ [l=ro] {<div class="buttons">_imagecont_</div>
+_iconwarning_CreÅterea volumului textului aici va genera o cantitate mare de date pentru a fi afiÅatÄ de browser
+}  
+
+_textgoto_ [l=ro] {mergi la pagina}  
+_textintro_ [l=ro] {<i>(text introductiv)</i>}  
+
+_textCONTINUE_ [l=ro] {CONTINUI ?}  
+
+_textEXPANDTEXT_ [l=ro] {DESCHIDE TEXTUL}  
+
+_textCONTRACTCONTENTS_ [l=ro] {CONTRAGE CONÅ¢INUTUL}  
+
+_textDETACH_ [l=ro] {DETAÅEAZÄ}  
+
+_textEXPANDCONTENTS_ [l=ro] {DESCHIDE CONÅ¢INUTUL}  
+
+_textCONTRACT_ [l=ro] {CONTRAGE TEXTUL}  
+
+_textHIGHLIGHT_ [l=ro] {SUBLINIERE}  
+
+_textNOHIGHLIGHT_ [l=ro] {FÄRÄ SUBLINIERE}  
+
+_textPRINT_ [l=ro] {PRINT}  
+
+_textnextsearchresult_ [l=ro] {urmÄtorul rezultat de cÄutare}  
+_textprevsearchresult_ [l=ro] {rezultatul de cÄutare anterior}  
+
+# macros for printing page
+_textreturnoriginal_ [l=ro] {Ãntoarce-te la pagina de start}  
+_textprintpage_ [l=ro] {PrinteazÄ aceastÄ paginÄ}  
+_textshowcontents_ [l=ro] {AratÄ cuprinsul}  
+_texthidecontents_ [l=ro] {Ascunde cuprinsul}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=ro] {_If_(_thislast_,results _thisfirst_ - _thislast_ pentru interogarea: _cgiargq_,No matches for query: _cgiargq_)}  
+_textnoquerytitle_ [l=ro] {Pagina de cÄutare}  
+
+_textsome_ [l=ro] {cÃ¢teva}  
+_textall_ [l=ro] {toate}  
+_textboolean_ [l=ro] {boolean}  
+_textranked_ [l=ro] {ordonat}  
+_textnatural_ [l=ro] {natural}  
+_textsortbyrank_ [l=ro] {relevanÅ£a dupÄ ordonare}  
+_texticonsearchhistorybar_ [l=ro] {instoricul cÄutÄrii}  
+
+_textifeellucky_ [l=ro] {MÄ simt norocos !}  
+
+#alt text for query buttons
+_textusequery_ [l=ro] {utilizeazÄ aceastÄ interogare}  
+_textfreqmsg1_ [l=ro] {NumÄrul cuvintelor:}  
+_textpostprocess_ [l=ro] {_If_(_quotedquery_,<br><i>post-procesat pentru a gÄsi _quotedquery_</i>
+)}  
+_textinvalidquery_ [l=ro] {sintaxÄ de cÄutare invalidÄ}  
+_textstopwordsmsg_ [l=ro] {UrmÄtoarele cuvinte sunt mult prea uzuale Åi vor fi ignorate:}  
+_textlucenetoomanyclauses_ [l=ro] {Interogarea conÅ£ine prea mulÅ£i termeni de cÄutare. ÃncearcÄ o interogare cu termeni specifici.}  
+
+_textmorethan_ [l=ro] {Mai multe decÃ¢t}  
+_textapprox_ [l=ro] {Despre}  
+_textnodocs_ [l=ro] {Nici un document nu s-a potrivit criteriilor}  
+_text1doc_ [l=ro] {1 document s-a potrivit criteriilor de cÄutare.}  
+_textlotsdocs_ [l=ro] {documente potrivite criteriilor de cÄutare}  
+_textmatches_ [l=ro] {Se potrivesc}  
+_textbeginsearch_ [l=ro] {PorneÅte cÄutarea}  
+_textrunquery_ [l=ro] {RuleazÄ interogarea}  
+_textclearform_ [l=ro] {CurÄÅ£Ä formularul}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=ro] {Cuvinte
+}  
+_textinfield_ [l=ro] {... Ã®n cÃ¢mp}  
+_textfoldstem_ [l=ro] {(mÄrime, rÄdÄcinÄ)}  
+
+_textadvquery_ [l=ro] {Sau introdu o interogare Ã®n mod direct:	}  
+_textallfields_ [l=ro] {cÃ¢mpurile}  
+_texttextonly_ [l=ro] {doar text}  
+_textand_ [l=ro] {Åi}  
+_textor_ [l=ro] {sau}  
+_textandnot_ [l=ro] {Åi nu}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=ro] {CautÄ dupÄ _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_, at _gselection_ level )_If_(_nselection_,in _nselection_ language )care conÅ£in _querytypeselection_ cuvintele _If_(_sfselection_,\,_allowformbreak_ sortarea rezultatelor dupÄ _sfselection_)}  
+
+_textadvancedsearch_ [l=ro] {CÄutare _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language )folosind _querytypeselection_ query}  
+
+_textadvancedmgppsearch_ [l=ro] {CÄutare _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_,at _gselection_ level )_If_(_nselection_,in _nselection_ language ) Åi afiÅarea rezultatelor Ã®n ordinea _formquerytypeadvancedselection_}  
+
+_textadvancedlucenesearch_ [l=ro] {CÄutare _indexselection__If_(_jselection_, of _jselection_)_If_(_gselection_, at _gselection_ level)_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ sortarea rezultatelor dupÄ _sfselection_\,) pentru}  
+
+_textformsimplesearch_ [l=ro] {CautÄ _If_(_jselection_, _jselection_)_If_(_gformselection_, la _gformselection_ level)_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\, sortÃ¢nd rezultatele dupÄ _sfselection_\,) pentru _formquerytypesimpleselection_ ale}  
+
+_textformadvancedsearchmgpp_ [l=ro] {CautÄ _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )Åi afiÅeazÄ rezultatele dupÄ _formquerytypeadvancedselection_ order }  
+
+_textformadvancedsearchlucene_ [l=ro] {CautÄ _If_(_jselection_, _jselection_)_If_(_gformselection_,  at _gformselection_ level)_If_(_nselection_, in _nselection_ language)_If_(_sfselection_,\, sortÃ¢nd rezultatele dupÄ _sfselection_\,) for }  
+
+_textnojsformwarning_ [l=ro] {Avertisment: Javascript este dezactivat pentru browserul pe care-l folosiÅ£i. <br>Pentru a folosi cÄutarea prin intermediul formularului, vÄ rugÄm activaÅ£i aceastÄ opÅ£iune.}  
+_textdatesearch_ [l=ro] {Documentele pot fi cÄutate Ã®n aceastÄ colecÅ£ie dupÄ limite temporale sau documente cu o anumitÄ datÄ. AceastÄ facilitatea este opÅ£ionalÄ la cÄutare.}  
+_textstartdate_ [l=ro] {Start (sau doar) data:}  
+_textenddate_ [l=ro] {Data limitÄ:}  
+_textbc_ [l=ro] {B.C.E.}  
+_textad_ [l=ro] {C.E.}  
+_textexplaineras_ [l=ro] {C.E. Åi B.C.E sunt alternativele pentru  A.D. Åi B.C.  AceÅti termeni sunt consideraÅ£i nediscriminatorii cultural Åi Ã®nseamnÄ "Common Era"(Era NoastrÄ) Åi "Before the Common Era"(Ãnainta Erei Noastre)}  
+
+_textstemon_ [l=ro] {(ignorarea terminaÅ£iei cuvintelor)}  
+
+_textsearchhistory_ [l=ro] {CautÄ Ã®n istoric}  
+
+#text macros for search history
+_textnohistory_ [l=ro] {nu existÄ intrÄri Ã®n istoricul de cÄutare}  
+_texthresult_ [l=ro] {rezultat}  
+_texthresults_ [l=ro] {rezultate}  
+_texthallwords_ [l=ro] {toate cuvintele}  
+_texthsomewords_ [l=ro] {cÃ¢teva cuvinte}  
+_texthboolean_ [l=ro] {boolean}  
+_texthranked_ [l=ro] {ordonat}  
+_texthcaseon_ [l=ro] {mÄrimea caracterelor trebuie sÄ se potriveascÄ}  
+_texthcaseoff_ [l=ro] {uniformizarea mÄrimii caracterelor}  
+_texthstemon_ [l=ro] {trunchiate}  
+_texthstemoff_ [l=ro] {netrunchiate}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=ro] {PreferinÅ£ele au fost setate dupÄ cum urmeazÄ. Nu folosiÅ£i butonul âbackâ al browserului pentru cÄ veÅ£i pierde setÄrile ! Ãn loc, apÄsaÅ£i unul din butoanele din bara de acces de mai sus.}  
+_textsetprefs_ [l=ro] {setarea preferinÅ£elor}  
+_textsearchprefs_ [l=ro] {PreferinÅ£e de cÄutare}  
+_textcollectionprefs_ [l=ro] {PreferinÅ£e de colecÅ£ie}  
+_textpresentationprefs_ [l=ro] {PreferinÅ£ele prezentÄrii}  
+_textpreferences_ [l=ro] {PreferinÅ£e}  
+_textcasediffs_ [l=ro] {MÄrimea caracterelor:}  
+_textignorecase_ [l=ro] {ignorÄ diferenÅ£ele de mÄrime a caracterelor}  
+_textmatchcase_ [l=ro] {MÄrimea caracterelor trebuie sÄ se potriveascÄ}  
+_textwordends_ [l=ro] {terminaÅ£iile cuvintelor:}  
+_textstem_ [l=ro] {ignorÄ terminaÅ£iile cuvintelor}  
+_textnostem_ [l=ro] {trebuie sÄ se protriveascÄ Ã®ntreg cuvÃ¢ntul}  
+_textaccentdiffs_ [l=ro] {Diferitele accente:}  
+_textignoreaccents_ [l=ro] {ignorÄ accentele}  
+_textmatchaccents_ [l=ro] {accentele trebuie sÄ se potriveascÄ}  
+
+_textprefop_ [l=ro] {Ãntoarce-te pÃ¢nÄ la _maxdocoption_ de hituri cu _hitsperpageoption_ hituri per paginÄ.}  
+_textextlink_ [l=ro] {Acces cÄtre pagini web externe:}  
+_textintlink_ [l=ro] {Documente sursÄ extrase de la:}  
+_textlanguage_ [l=ro] {Limba interfeÅ£ei}  
+_textencoding_ [l=ro] {Codarea:}  
+_textformat_ [l=ro] {Format de interfaÅ£Ä:}  
+_textall_ [l=ro] {toate}  
+_textquerymode_ [l=ro] {Modul de interogare:}  
+_textsimplemode_ [l=ro] {mod de interogare simplu}  
+_textadvancedmode_ [l=ro] {modul de cÄutare avansatÄ (permite cÄutÄri boolean folosindu-se !, &amp;, |, dar Åi parantezele)}  
+_textlinkinterm_ [l=ro] {printr-o paginÄ intermediarÄ}  
+_textlinkdirect_ [l=ro] {du-te direct acolo}  
+_textdigitlib_ [l=ro] {biblioteca digitalÄ}  
+_textweb_ [l=ro] {web}  
+_textgraphical_ [l=ro] {Mod grafic}  
+_texttextual_ [l=ro] {Textual}  
+_textcollectionoption_ [l=ro] {<p>
+SubcolecÅ£iile includ:
+<br>}  
+
+_textsearchtype_ [l=ro] {Mod de interogare:}  
+_textformsearchtype_ [l=ro] {pe cÃ¢mpuri utilizÃ¢ndu-se _formnumfieldoption_ fields}  
+_textplainsearchtype_ [l=ro] {normal cu _boxsizeoption_}  
+_textregularbox_ [l=ro] {o singurÄ linie}  
+_textlargebox_ [l=ro] {mare}  
+
+_textrelateddocdisplay_ [l=ro] {afiÅeazÄ documentele Ã®n relaÅ£ie}  
+_textsearchhistory_ [l=ro] {Istoricul cÄutÄrilor:}  
+_textnohistory_ [l=ro] {Nu existÄ istoric de cÄutare}  
+_texthistorydisplay_ [l=ro] {afiÅeazÄ _historynumrecords_ Ã®nregistrÄri ale istoricului de cÄutare}  
+_textnohistorydisplay_ [l=ro] {nu afiÅa istoricul de cÄutare}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=ro] {SorteazÄ documentele dupÄ}  
+_textalsoshowing_ [l=ro] {afiÅeazÄ deasemenea}  
+_textwith_ [l=ro] {Ã®mpreunÄ pÃ¢nÄ la}  
+_textdocsperpage_ [l=ro] {documente per paginÄ}  
+
+_textfilterby_ [l=ro] {ObÅ£ine documente conÅ£inÃ¢nd}  
+_textall_ [l=ro] {toate}  
+_textany_ [l=ro] {oricare}  
+_textwords_ [l=ro] {ale cuvintelor}  
+_textleaveblank_ [l=ro] {lasÄ aceastÄ cÄsuÅ£Ä goalÄ pentru a obÅ£ine toate documentele}  
+
+_browsebuttontext_ [l=ro] {âSorteazÄ documenteleâ}  
+
+_nodata_ [l=ro] {<i>nu sunt date</i>}  
+_docs_ [l=ro] {documente}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=ro] {AsistenÅ£Ä}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=ro] {navigarea printre documente prin _1_ apÄsÃ¢nd butonul _2_}  
+
+_textSearchhelp_ [l=ro] {cautÄ anumite cuvinte care apar Ã®n text prin apÄsarea pe butonul _labelSearch_}  
+_textTohelp_ [l=ro] {rÄsfoieÅte documentele cu ajutorul cÃ¢mpului To prin apÄsarea lui _labelTo_button}  
+_textFromhelp_ [l=ro] {navigarea printre publicaÅ£ii dupÄ cÃ¢mpul De la prin apÄsarea lui _labelFrom_}  
+_textBrowsehelp_ [l=ro] {navigheazÄ printre documente}  
+_textAcronymhelp_ [l=ro] {navigheazÄ printre documente dupÄ acronimele care apar prin apÄsarea pe}  
+_textPhrasehelp_ [l=ro] {navigheazÄ dupÄ frazele care apar Ã®n documente apÄsÃ¢nd butonul _labelPhrase_. Acesta utilizeazÄ browserul de fraze.}  
+
+_texthelptopicstitle_ [l=ro] {Subiecte}  
+
+_textreadingdocs_ [l=ro] {Cum trebuie citite documentele}  
+
+_texthelpreadingdocs_ [l=ro] {<p>Titlul sau fotografia coperÅ£ii apare Ã®n colÅ£ul stÃ¢nga sus al paginii Åi indicÄ faptul cÄ un document a fost gÄsit. Ãn unele colecÅ£ii acestea sunt Ã®nsoÅ£ite de un cuprins Ã®n timp ce altele conÅ£in doar de numÄrul paginii curente Åi o cÄsuÅ£Ä care Ã®Å£i permite selectarea unei noi pagini Åi navigarea Ã®nainte Åi Ã®napoi. La cuprins, titlul secÅ£iunii curente este trecut cu aldine iar tabelul poate fi desfÄÅ£urat - dÄ clic pe foldere pentru a le deschide sau Ã®nchide. DÄ clic pe cartea deschisÄ din partea de sus pentru a o Ã®nchide.</p>
+
+<p>Dedesubt este textul secÅ£iunii curente. DupÄ ce ai parcurs-o sunt observate niÅte sÄgeÅ£i Ã®n partea de jos care conduc cÄtre urmÄtoarea secÅ£iune sau Ã®napoi la cea anterioarÄ.</p>
+
+<p>Sub titlu sau fotografia primei pagini existÄ cÃ¢teva butoane. ApasÄ pe <i>_document:textEXPANDTEXT_</i> pentru a deschide textul Ã®ntreg al secÅ£iunii curente sau al cÄrÅ£ii. DacÄ documentul este de largÄ Ã®ntindere, acest proces ar putea lua ceva timp Åi poate sÄ fie folositÄ multÄ memorie! ApasÄ pe <i>_document:textEXPANDCONTENTS_</i> pentru a destinde Ã®ntregul cuprins astfel Ã®ncÃ¢t sÄ poÅ£i vedea titlurile tuturor capitolelor Åi secÅ£iunilor. ApasÄ pe <i>_document:textDETACH_</i> pentru a deschide o nouÄ fereastrÄ pentru acest document. (Acest lucru este util dacÄ doreÅti sÄ compari documente sau pentru a citi douÄ Ã®n acelaÅi timp.) Ãn final, atunci cÃ¢nd faci o cÄutare, cuvintele pe care le cauÅ£i sunt subliniate. ApasÄ pe <i>_document:textNOHIGHLIGHT_</i> pentru a scoate sublinierea.</p>
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=ro] {Mergi la acest raft}  
+_texthelpopenbook_ [l=ro] {Deschide/Ã®nchide aceastÄ carte}  
+_texthelpviewtextsection_ [l=ro] {Vezi aceastÄ secÅ£iune de text}  
+_texthelpexpandtext_ [l=ro] {AfiÅeazÄ tot textul sau nu}  
+_texthelpexpandcontents_ [l=ro] {Extinde Cuprinsul sau nu}  
+_texthelpdetachpage_ [l=ro] {Deschide aceastÄ paginÄ Ã®ntr-o nouÄ fereastrÄ}  
+_texthelphighlight_ [l=ro] {SubliniazÄ termenii de cÄutare sau nu}  
+_texthelpsectionarrows_ [l=ro] {Du-te la secÅ£iunea anterioarÄ / urmÄtoare}  
+
+
+_texthelpsearchingtitle_ [l=ro] {Cum cauÅ£i dupÄ anumite cuvinte}  
+
+_texthelpsearching_ [l=ro] {<p>
+  Din pagina de cÄutare se poate efectua o interogare urmÄrind urmÄtorii paÅi:<p>
+
+  <ol><li>Specifici ce elemente doreÅti sÄ cauÅ£i
+      <li>Specifici dacÄ vrei sÄ faci cÄutarea dupÄ toate sau doar dupÄ cÃ¢teva cuvinte
+      <li>Tastezi cuvintele de cÄutare
+      <li>ApeÅi pe <i>Ãncepe CÄutarea</i>
+  </ol>
+
+<p>Atunci cÃ¢nd efectuezi o cÄutare, vor fi afiÅate titlurile a 20 de documente care se potrivesc.
+ExistÄ un buton sub ele care te va direcÅ£iona la urmÄtoarele 20.  De acolo voi gÄsi un buton care te va duce la urmÄtoarele 20 Åi tot aÅa. ApeÅi pe titlul unui document sau pe butonul mic de lÃ¢ngÄ el pentru a-l vizualiza.
+
+<p>Este impusÄ o limitÄ maximÄ de 100 la returnarea documentelor rezultate ca urmare a unei cÄutÄri. PoÅ£i schimba aceastÄ limitÄ apÄsÃ¢nd butonul
+  <i>_Global:linktextPREFERENCES_</i> din capul paginii.<p>
+
+}  
+
+_texthelpquerytermstitle_ [l=ro] {Termeni de cÄutare}  
+_texthelpqueryterms_ [l=ro] {<p>Orice ai introduce Ã®n spaÅ£iul interogÄrii este interpretat ca o listÄ de cuvinte Åi fraze intitulate âtermeni de cÄutareâ. Un termen este un singur cuvÃ¢nt conÅ£inÃ¢nd doar litere Åi cifre sau o frazÄ alcÄtuitÄ dintr-o secvenÅ£Ä de cuvinte cuprinse Ã®ntre ghilimele (â...â).  Termenii sunt separaÅ£i de spaÅ£ii libere. DacÄ apar oricare alte caractere precum semne de punctuaÅ£ie, acestea servesc la separarea termenilor, exact ca Åi cum ar fi spaÅ£ii goale, fiind ignorate. Nu se poate efectua o cÄutare care include semne de punctuaÅ£ie.
+
+<p>De exemplu, interogarea:<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>va fi tratatÄ Ã®n acelaÅi mod precum:<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}  
+
+_texthelpmgppsearching_ [l=ro] {Pentru colecÅ£iile construite cu MGPP sunt disponibile Åi alte opÅ£iuni. 
+
+<ul>
+<li>A <b>*</b> la finalul unui termen de cÄutare face ca acesta sÄ se potriveascÄ cu toate cuvintele<b>Ã®ncepÃ¢nd cu</b> acel cuvÃ¢nt, ex. <b>comput*</b> se potriveÅte cu toate cuvintele care Ã®ncep cu <b>comput</b>.
+<li><b>/x</b> poate fi folosit pentru a da o mai mare greutate unuia sau mai multor termeni de cÄutare, ex <b>computer/10 science</b> returneazÄ cuvÃ¢ntul computer cu un accent de 10 ori mai mare decÃ¢t pe science atunci cÃ¢nd se stabileÅte ierarhia documentelor.
+</ul>
+}  
+
+_texthelplucenesearching_ [l=ro] {Pentru colecÅ£iile construite cu Lucene sunt disponibile Åi alte cÃ¢teva opÅ£iuni. 
+
+<ul>
+<li><b>?</b> poate fi folosit ca wildcard Ã®n locul unei singure litere. De exemplu, <b>b?t</b> se va potrivi cu  <b>bet</b>, <b>bit</b> Åi <b>bat</b> etc.
+<li><b>*</b> poate fi folosit ca wildcard Ã®nlocuind mai multe litere. De exemplu, <b>comput*</b> se potriveÅte cu <b>comput</b>.
+</ul>
+Ambele wildcard-uri pot fi folosite Ã®n mijlocul unui termen sau la final. Nu pot fi folosite la Ã®nceputul unui termen de cÄutare.
+}  
+
+_texthelpquerytypetitle_ [l=ro] {Tipul de interogare}  
+_texthelpquerytype_ [l=ro] {<p>ExistÄ douÄ tipuri de interogÄri.
+
+<ul>
+  <li>InterogÄri pentru <b>toate</b> cuvintele. Acestea cautÄ Ã®n documente (capitole sau titluri) care conÅ£in toate cuvintele specificate. Documentele care se potrivesc interogÄrii sunt afiÅate Ã®n ordinea lor de introducere.
+<p>
+
+  <li>InterogÄri pentru <b>unele</b> cuvinte. Introdu doar cÃ¢Å£iva termeni care ar putea sÄ fie Ã®n documentele cÄutate. Documentele sunt afiÅate Ã®n ordinea stabilitÄ de gradul de potrivire cu ceea ce existÄ Ã®n documente. Atunci cÃ¢nd se determinÄ gradul de potrivire,
+
+      <p><ul>
+        <li> cu cÃ¢t apar de mai multe ori Ã®n document, cu atÃ¢t gradul de potrivire este mai strÃ¢ns;
+        <li> termenii care sunt rar Ã®ntÃ¢lniÅ£i Ã®n colecÅ£ie, Ã®n Ã®ntregimea lor sunt mult mai importanÅ£i decÃ¢t cei comuni;
+        <li> documentele mai mici se preteazÄ mult mai bine cÄutÄrilor.
+      </ul>
+</ul>
+
+<p>PoÅ£i folosi cÃ¢Å£i termeni de cÄutare doreÅti - o propoziÅ£ie Ã®ntreagÄ sau chiar un paragraf Ã®ntreg. DacÄ specifici doar un singur termen, documentele vor fi ordonate dupÄ frecvenÅ£a de apariÅ£ie.<p>
+}  
+
+_texthelpadvancedsearchtitle_ [l=ro] {CÄutare avansatÄ folosindu-se motorul de cÄutare _1_}  
+
+_texthelpadvancedsearch_ [l=ro] {<p>DacÄ ai ales modul vansa de interogare (din preferinÅ£e) opÅ£iunile de cÄutare vor fi puÅ£in diferite. _selectadvancedsearch_
+}  
+
+_texthelpadvsearchmg_ [l=ro] {CÄutarea avansatÄ Ã®n colecÅ£iile MG oferÄ douÄ opÅ£iuni: dupÄ rang Åi boolean.
+O cÄutare <b>ranked</b> se comportÄ exact ca o cÄutare <b>some</b> descrisÄ Ã®n <a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_}  
+
+_texthelpbooleansearch_ [l=ro] {O cÄutare <b>boolean</b> permite combinarea termenilor folosind & (pentru âÅiâ), | (pentru âsauâ) Åi ! (pentru ânotâ) putÃ¢ndu-se folosi parantezele pentru grupare dacÄ acest lucru este dorit.  Operatorul implicit este | (pentru âsauâ).
+<p>
+De exemplu, <b>snail & farming</b> va regÄsi documentele care conÅ£in deopotrivÄ <b>snail</b> ÅI <b>farming</b>, unde <b>snail | farming</b> va regÄsi documentele care conÅ£in fie <b>snail</b> SAU <b>farming</b>.
+<b>snail !farming</b> va regÄsi documentele care conÅ£in <b>snail</b> ÅI CARE NU conÅ£in <b>farming</b>.
+<p>
+InterogÄri mai exacte pot fi specificate folosindu-se combinaÅ£ia de operatori Åi paranteze. De exemplu: <b>(sheep | cattle) & (farm | station)</b> sau <b>sheep | cattle | goat !pig</b>.}  
+
+_texthelpadvsearchmgpp_ [l=ro] {"CÄutÄrile avansate Ã®n colecÅ£iile MGPP folosesc operatorii boolean. _texthelpbooleansearch_
+<p>Rezultatele pot fi afiÅate dupÄ <b>ranked</b> dupÄ cum este descris Ã®n cazul cÄutÄrii <b>some</b> Ã®n <a href="\#query-type">_texthelpquerytypetitle_</a> sau Ã®n ordinea "naturalÄ" (sau cea a "constituirii"). Aceasta este ordinea Ã®n care documentele au fost procesate Ã®n timpul creÄrii colecÅ£iei.
+<p>
+Ãn completare, alÅ£i operatori sunt <b>NEARx</b> Åi <b>WITHINx</b>.
+NEARx este utilizat pentru a specifica distanÅ£a maximÄ Ã®n spaÅ£ierea a doi termeni de cÄutare(x words) pentru a se potrivi cu un document. 
+WITHINx specificÄ faptul cÄ cel de-al doilea termen trebuie sÄ apÄrÄ dupÄ x cuvinte <i>dupÄ</i> primul termen. Se comportÄ similar lui NEAR dar ordinea este importantÄ. DistanÅ£a implicitÄ este de 20."}  
+
+_texthelpadvancedsearchextra_ [l=ro] {NOTÄ: Acesti operatori sunt ignoraÅ£i dacÄ se va cÄuta Ã®n modul de interogare simplu.}  
+
+_texthelpadvsearchlucene_ [l=ro] {CÄutarea avansatÄ Ã®n colecÅ£iile Lucene foloseÅte operatori boolean. _texthelpbooleansearch_
+}  
+
+_texthelpformsearchtitle_ [l=ro] {CÄutare pe cÃ¢mpuri}  
+
+_texthelpformsearch_ [l=ro] {<p>CÄutarea pe cÃ¢mpuri dÄ posibilitatea de a combina cÄutÄrile. De exemplu, cineva poate face o cÄutare dupÄ âPopescuâ Ã®n Titlu AND(ÅI) âcreÅterea melcilorâ la Subiect. Ãn cazul unei cÄutÄri simple fiecare linie a formularului se comportÄ precum o simplÄ linie de cÄutare. Fiecare linie de cÄutare individualÄ se poate combina folosindu-se AND(ÅI) (pentru o cÄutare âglobalÄâ) sau prin OR (pentru o cÄutare âparÅ£ialÄâ). Termenii din cadrul cÃ¢mpului sunt combinaÅ£i Ã®n acelaÅi mod. Ãn modul avansat de lucru se pot specifica diferite combinaÅ£ii Ã®ntre AND/OR/NOT Ã®ntre cÃ¢mpuri folosindu-se listele derulante. Chiar Åi Ã®n interiorul unui cÃ¢mp pot fi folosiÅ£i operatori boolean.
+}  
+
+_texthelpformstemming_ [l=ro] {CasuÅ£ele âdimensionareâ Åi ârÄdÄcinÄâ permit specificarea dacÄ termenii din acel cÃ¢mp sunt la aceeasi dimensiune de caracter sau au doar rÄdÄcina cuvÃ¢ntului. IniÅ£ial ambele sunt dezactivate Ã®n cazul unei cÄutÄri avansate.}  
+
+_textdatesearch_ [l=ro] {CÄutarea dupÄ data calendaristicÄ}  
+
+_texthelpdatesearch_ [l=ro] {CÄutarea dupÄ datÄ Ã®Å£i permite regÄsirea documentelor care, fiind Ã®n acord cu termenii de cÄutare, exprimÄ evenimente dintr-un anumit cadru de timp. PoÅ£i cÄuta documentele dintr-un anumit an sau o plajÄ de ani.  Trebuie notat cÄ nu este necesarÄ existenÅ£a vreunui termen de cÄutare, se poate face cÄutare doar dupÄ datÄ. De asemenea, nu este neapÄrat necesar sÄ foloseÅti date calendaristice Ã®n cÄutare. DacÄ nu sunt introduse date calendaristice este ca Åi cum cÄutarea dupÄ datÄ nu existÄ.<p>}  
+
+_texthelpdatehowtotitle_ [l=ro] {Cum se foloseÅte aceastÄ opÅ£iune:}  
+_texthelpdatehowto_ [l=ro] {<ul>
+   <li>CÄutarea Ã®n documente privind un singur an:<p>
+   <ul>
+       <li>Introdu oricare termen de cÄutare dupÄ cum s-ar proceda de obicei.
+       <li>Introdu anul dorit Ã®n caseta "Data de pornire (e posibil doar aceasta)".
+       <li>DacÄ data este Ã®nainte de Hristos, alege opÅ£iunea "B.C.E" din meniul 
+           deruland de lÃ¢ngÄ acea casetÄ.
+       <li>PorneÅte cercetarea Ã®n mod normal.
+   </ul>
+<p><li>Pentru a cÄuta documentele Ã®n limitele unei perioade exprimatÄ Ã®n ani:<p>
+   <ul>
+       <li>Introdu oricare termen de cÄutare dupÄ cum s-ar proceda de obicei.
+       <li>Introdu data de pornire Ã®n caseta "Data de start (e posibil doar aceasta)".
+       <li>Introdu data limitÄ Ã®n caseta "Data limita".
+       <li>SelecteazÄ opÅ£iunea "B.C.E" din meniul derulant alÄturat oricÄrei date Ã®nainte de Hristos.
+       <li>PorneÅte cercetarea Ã®n mod normal.
+   </ul>    
+</ul><p>}  
+
+_texthelpdateresultstitle_ [l=ro] {Modul Ã®n care rezultatele muncii de cÄutare}  
+_texthelpdateresults_ [l=ro] {Ãn mod normal o cÄutare privind documente situate Ã®n jurul anului 1903 nu va avea rezultate, care, referenÅ£iazÄ documente scrise Ã®n 1903, ci doar documentele din 1903. Oricum, felul Ã®n care este regÄsitÄ data documentelor, va conduce la un rezultat care au o limitele (de exemplu, 1899-1911) ce includ 1903 Åi documentele, care implicÄ prin denumire secolul din care 1903 face parte (de exemplu, secolul 20). Acest lucru Ã®nseamnÄ cÄ pentru anumite documente, datele din cÄutare nu vor apÄrea in textul documentul. Pentru cÄutarea bazatÄ pe limite, toate acestea se aplicÄ petntru fiecare datÄ din alcÄtuirea plajei specificate.<p>}  
+
+_textchangeprefs_ [l=ro] {Schimbarea preferinÅ£elor}  
+
+_texthelppreferences_ [l=ro] {<p>CÃ¢nd apeÅi pe butonul <i>_Global:linktextPREFERENCES_</i> din capul paginii se pot schimba cÃ¢teva caracteristici ale interfeÅ£ei pentru a satisface nevoile particulare.
+}  
+
+_texthelpcollectionprefstitle_ [l=ro] {PreferinÅ£ele pentru colecÅ£ii}  
+_texthelpcollectionprefs_ [l=ro] {<p>"Unele colecÅ£ii au Ã®n alcÄtuire cÃ¢teva subcolecÅ£ii, care pot fi cercetate independent sau Ã®mpreunÄ ca o unitate.  Astfel cÄ se poate selecta subcolecÅ£ia care poate fi inclusÄ Ã®n cÄutÄrile din pagina de PreferinÅ£e."}  
+
+_texthelplanguageprefstitle_ [l=ro] {PreferinÅ£e de limbÄ}  
+_texthelplanguageprefs_ [l=ro] {<p>Fiecare colecÅ£ie are o limbÄ de prezentare iniÅ£ial, dar aceasta se poate schimba dupÄ dorinÅ£Ä.  Se poate modifica Åi schema de codare folositÄ de Greenstone pentru afiÅarea rezultatului Ã®n browser - software-ul alege o modalitate relevantÄ, dar se poate opta Åi pentru scheme de codare alternative pentru o corectÄ afiÅare a caracterelor pe ecran.
+Toate colecÅ£iile permit alternativa de la modul grafic la o afiÅare Ã®n mod text. Acest lucru este util mai ales pentru utilizatorii cu probleme de vedere care folosesc fonturi mari sau sintetizatoare de vorbire pentru rezultate.
+}  
+
+_texthelppresentationprefstitle_ [l=ro] {PreferinÅ£ele de prezentare}  
+_texthelppresentationprefs_ [l=ro] {Ãn funcÅ£ie de o anume colecÅ£ie, se pot seta cÃ¢teva opÅ£iuni pentru controlul caracteristicilor de afiÅare.
+
+<p>ColecÅ£iile de pagini web permit suprimarea barei de navigare Greenstone la capul fiecÄrei pagini a documentului, astfel cÄ dupÄ ce ai fÄcut o cÄutare vei ajunge exact la paginÄ fÄrÄ niciun header Greenstone. Pentru a efectua o altÄ cÄutare va trebui sÄ foloseÅti butonul âbackâ al browserului tÄu. Aceste colecÅ£ii permit de asemenea, suprimarea mesajelor de avertizare ale Greenstone atunci cÃ¢nd dai un clic care te poartÄ dincolo de cadrul colecÅ£iei bibliotecii digitale, cÄtre pagina accesatÄ. Ãn cÃ¢teva colecÅ£ii poate fi controlat modul Ã®n care linkurile din pagina âRezultatelor de CÄutareâ te duc direct cÄtre URL-ul Ã®n cauzÄ sau cÄtre o copie a paginii internÄ din propria biblioteca digitalÄ.
+}  
+
+_texthelpsearchprefstitle_ [l=ro] {PreferinÅ£e de cÄutare}  
+_texthelpsearchprefs_ [l=ro] {<p>PoÅ£i sÄ treci Ã®ntr-un mod âavansatâ de interogare care Ã®Å£i permite sÄ combini termeni folosind & (pentru âÅiâ - operatorul and), Ã (pentru âorâ) Åi ! (pentru ânegaÅ£ieâ) folosind parantezele pentru grupare dupÄ cum se doreÅte. Acest lucru Ã®Å£i permite sÄ specifici mai multe interogÄri cu un grad mÄrit de precizie. 
+<p>_selectsearchtypeprefs_
+<p>_selectwordmodificationprefs_
+<p>Se poate activa Åi istoricul cÄutÄrii care Ã®Å£i aratÄ ultimele interogÄri. Acest lucru permite repetarea cÄutÄrii cu mici modificÄri faÅ£Ä de cea anterioarÄ. 
+<p>Ãn final, poate fi controlat numÄrul de hituri returnate Åi cÃ¢te au fost prezentate pe ecran.
+
+}  
+
+_textcasefoldprefs_ [l=ro] {O pereche de butoane de control, unde fie cÄ apar majuscule sau normale, acestea trebuie sÄ se potriveascÄ cÃ¢nd se face o cÄutare. De exemplu, dacÄ "_preferences:textignorecase_" este selectat, atunci <i>snail farming</i> fa fi tratat Ã®n acelaÅi mod precum<i>Snail Farming</i> Åi <i>SNAIL FARMING</i>.}  
+_textstemprefs_ [l=ro] {O pereche de butoane controleazÄ dacÄ trebuie ignoratÄ terminaÅ£ia cuvÃ¢ntului sau nu atunci cÃ¢nd se face cÄutarea. De exemplu, dacÄ Ã®n "_preferences:textstem_" este selectat  <i>creÅterea melcilor</i> acesta va fi tratat la fel precum <i>crescÄtoria de melci</i> Åi <i>crescÄtor de melci</i>. AceastÄ facilitate lucreazÄ bine numai pentru textelel Ã®n limba englezÄ. _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=ro] {O pereche de butoane de control, unde fie cÄ sunt litere cu accent ascuÅ£it sau cu accent grav, acestea trebuie sÄ se potrivescÄ cÃ¢nd se face o cÄutare. De exemplu, dacÄ "_preferences:textignoreaccents_" este selectat, atunci <i>fÃ©dÃ©ration</i> va fi tratat Ã®n acelaÅi mod ca Åi <i>fedÃ©ration</i> Åi <i>federation</i>.}  
+ 
+_textstemoptionsprefs_ [l=ro] {Poate fi mult mai precisÄ Åi mai la Ã®ndemÃ¢nÄ cÄutarea prin utilizarea facilitÄÅ£ii de trunchiere descrisÄ mai sus Ã®n _texthelpquerytermstitle_".}  
+
+_textsearchtypeprefsplain_ [l=ro] {Este posibil de a obÅ£ine un cÃ®mp de cÄutare extins pentru a fi posibilÄ o cÄutare la nivel de paragraf. CÄutarea dupÄ bucÄÅ£i mai mari de text este surprinzÄtor de rapidÄ .}  
+
+_textsearchtypeprefsform_ [l=ro] {PoÅ£i schimba numÄrul de cÃ¢mpuri afiÅat Ã®n formularul de cÄutare.}  
+
+_textsearchtypeprefsboth_ [l=ro] {PoÅ£i schimba modul de cÄutare Ã®n colecÅ£ie Ã®ntre cÄutare ânormalÄâ Åi cÄutarea âpe cÃ¢mpuriâ. 
+<ul>
+<li>CÄutarea normalÄ are doar o singur cÃ¢mp de interogare. _textsearchtypeprefsplain_</li>
+<li>CÄutarea pe cÃ¢mpuri furnizeazÄ mai multe cÃ¢mpuri de cÄutare, fiecare interogÃ¢nd un domeniu diferit al indexului. Acest lucru permite cÄutarea pe mai multe cÃ¢mpuri diferite Ã®n acelaÅi timp. _textsearchtypeprefsform_ </li>
+</ul>
+}  
+
+
+
+_texttanumbrowseoptions_ [l=ro] {ExistÄ _numbrowseoptions_ modalitÄÅ£i de a gÄsi informaÅ£ie Ã®n aceastÄ colecÅ£ie:}  
+
+_textsimplehelpheading_ [l=ro] {Cum sÄ gÄseÅti informaÅ£ie Ã®n _collectionname_ collection}  
+
+_texthelpscopetitle_ [l=ro] {Aria de cÄutare}  
+_texthelpscope_ [l=ro] {<p>
+Ãn cele mai multe colecÅ£ii Å£i se oferÄ o variantÄ de a cÄuta Ã®n mai multe indexuri. De exemplu, ar putea exista indexuri de autori sau de titluri sau pot exista indexuri de capitole sau paragrafe. Ãn general, este returnat un document care se potriveÅte pe de-a Ã®ntregul indiferent de indexul de cÄutare.
+<p>DacÄ documentele sunt cÄrÅ£i, acestea vor fi deschise Ã®n locul unde este prezentÄ informaÅ£ia de interes.
+}  
Index: /gsdl/stable/macros/romanian2.dm
===================================================================
--- /gsdl/stable/macros/romanian2.dm	(revision 20131)
+++ /gsdl/stable/macros/romanian2.dm	(revision 20131)
@@ -0,0 +1,867 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Language text and icon macros 
+# -- this file contains text that is of less importance
+######################################################################
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=ro] {documente.}  
+_lastupdate_ [l=ro] {Ultima actualizare}  
+_ago_ [l=ro] {cu cÃ¢teva zile Ã®n urmÄ.}  
+_colnotbuilt_ [l=ro] {ColecÅ£ia nu este construitÄ.}  
+
+### taken from here
+
+_textpoem_ [l=ro] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>fie ca pacea Åi serenitatea sÄ te Ã®nconjoare,
+<br>fii Ã®mbrÄÅ£iÅat Ã®n cÄldura aburului verii,
+<br>fie ca oceanul cÄlÄtoriilor tale Ã®ntins Åi fin precum o piatrÄ-verde lustruitÄ.
+}  
+
+_textgreenstone_ [l=ro] {<p>Greenstone (piatrÄ-verde) este o piatrÄ semipreÅ£ioasÄ (precum acest software) care se gÄseÅte doar Ã®n Noua ZeelandÄ. Ãn societatea tradiÅ£ionalÄ Maori avea o valoare Ã®nsemnatÄ fiind cÄutatÄ mai presus decÃ¢t alte substanÅ£e. Are proprietatea de a absorbi <i>wairua</i>, care este spiritul forÅ£ei vitale fiind Ã®nzestrat cu virtuÅ£i tradiÅ£ionale care o transformÄ Ã®ntr-o emblemÄ potrivitÄ pentru domeniul public rezervat proiectului bibliotecii digitale. StrÄlucirea sa indicÄ caritatea, claritatea sa indicÄ onestitatea, duritatea - curajul iar muchiile ascuÅ£ite pe care le poate dobÃ¢ndi reprezintÄ dreptatea. Piesa sculptatÄ folositÄ Ã®n logo-ul Greenstone reprezintÄ un <i>patu</i>, adicÄ un club de lupte, fiind o bijuterie de familie a unuia dintre membrii proiectului. Ãn lupta corp-la-corp o loviturÄ astfel angajatÄ implicÄ rapiditate, acurateÅ£e Åi completitudine. Ne place sÄ credem cÄ aceste calitÄÅ£i se aplicÄ Åi acestui pachet software, muchia ascuÅ£ita ca o lamÄ a unui <i>patu</i> simbolizÃ¢nd avangarda tehnologicÄ.</p>
+}  
+
+_textaboutgreenstone_ [l=ro] {<p>Greenstone este o suitÄ software pentru a constitui Åi distribui colecÅ£ii de biblioteci digitale. Acest software propune noi metode de organizare a informaÅ£iei Åi de publicare a acesteia pe Internet sau CD-ROM. Greenstone este produs de 
+ <b>Proiectul Bibliotecii Digitale a Noii Zeelande</b> al <b>UniversitÄÅ£ii din Waikato</b>. Este dezvoltat Åi distribuit Ã®n cooperare cu <b>UNESCO</b> Åi <b>Human Info NGO</b>. Este un software open-source, disponibil la <a
+ href="http://greenstone.org">http://greenstone.org</a>. Acesta stÄ sub prevederile   licenÅ£ei GNU General Public License.
+ </p>
+ 
+ <p>Scopul acestui software este de a da forÅ£Ä utilizatorilor, Ã®n special din universitÄÅ£i, biblioteci Åi alte instituÅ£ii din serviciul public pentru a-Åi putea construi propria bibliotecÄ digitalÄ. Bibliotecile digitale reformeazÄ radical modul Ã®n care informaÅ£ia este diseminatÄ Åi achiziÅ£ionatÄ Ã®n cadrul comunitÄÅ£ilor partenere UNESCO Åi Ã®n cadrul instituÅ£iilor din domeniul educaÅ£iei, ÅtiinÅ£ei Åi culturii din Ã®ntreaga lume, dar Ã®n special Ã®n Å£Ärile Ã®n curs de dezvoltare. TrÄim cu speranÅ£a cÄ acest software va Ã®ncuraja desfÄÅurarea efectivÄ a bibliotecilor digitale pentru a partaja informaÅ£ia Åi pentru a o integra Ã®n circuitul public.
+ </p>
+ 
+ <p>Acest software este dezvoltat Åi distribuit printr-un efort de cooperare internaÅ£ional care a debutat Ã®n August 2000 Ã®ntre trei pÄrÅ£i.
+ </p>
+ 
+ <p>
+ <a href="http://nzdl.org"><b> Proiectul Bibliotecii Digitale a Noii Zeelande al UniversitÄÅ£ii din Waikato</b></a>
+ <br>
+ Software-ul Greenstone s-a dezvoltat din acest proiect iar aceastÄ iniÅ£iativÄ a fost sprijinitÄ de Subcomisia pentru Comunicare a Comisiei NaÅ£ionale UNESCO a Noii Zeelande ca parte a contribuÅ£iei Noii Zeelande la programul UNESCO.
+ </p>
+ 
+ <p>
+ <a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+ class="logo"></a>
+ <a href="http://www.unesco.org"><b>United Nations Educational, Scientific and Cultural Organization</b></a>
+ <br>
+ Diseminarea informaÅ£iei din domeniul educaÅ£iei, a celei ÅtiinÅ£ifice Åi culturale pe Ã®ntreg globul Åi Ã®n particular disponibilitatea acesteia Ã®n Å£Ärile Ã®n curs de dezvoltare, reprezintÄ una din Å£intele principale ale UNESCO fiind urmÄritÄ prin intermediul Programului interguvernamental InformaÅ£ie pentru ToÅ£i ajutat de tehnologia informaÅ£iei Åi comunicaÅ£iilor vÄzutÄ ca un instrument important Ã®n acest context.
+ </p>
+ 
+ <p>
+ <a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+ <a href="http://humaninfo.org"><b>The Human Info NGO, cu sediul Ã®n Antwerp, Belgia</b></a>
+ <br>
+ Acest proiect lucreazÄ cu agenÅ£iile UN Åi alte ONG-uri avÃ¢nd o reputaÅ£ie mondialÄ Ã®n ceea ce priveÅte digitizarea documentelor de interes Åi disponibilizÃ¢nd-o la scarÄ largÄ, fÄrÄ taxe naÅ£iunilor Ã®n curs de dezvoltare, dar cu anumite costuri pentru restul Å£Ärilor.
+ </p>
+ }  
+
+
+_textdescrselcol_ [l=ro] {alege o colecÅ£ie}  
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=ro] {ExistÄ alte patru butoane Ã®n pagina principalÄ}  
+
+_textnocollections_ [l=ro] {<p>Momentan nu existÄ colecÅ£ii disponibile Ã®n aceastÄ instalare Greenstone. 
+Pentru a adÄuga cÃ¢teva colecÅ£ii poÅ£i
+<ul><li>Use <a href="_httppagecollector_">Colectorul</a> sÄ construieÅti cÃ¢teva
+    <li>DacÄ aveÅ£i un cd-rom Greenstone se pot instal colecÅ£ii de pe cd-rom
+</ul>
+}  
+
+_text1coll_ [l=ro] {Instalarea Greenstone conÅ£ine o colecÅ£ie}  
+
+_textmorecolls_ [l=ro] {Instalarea Greenstone conÅ£ine _1_ colecÅ£ie}  
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=ro] {Link extern}  
+_textlinknotfound_ [l=ro] {Link intern negÄsit}  
+
+_textextlinkcontent_ [l=ro] {Linkul selectat este estern oricÄrei colecÅ£ii selectate Ã®n acest moment. DacÄ doriÅ£i sÄ vedeÅ£i acest link iar browserul are acces internet, atunci puteÅ£i <a href="_nexturl_">merge</a> la aceastÄ paginÄ, altfel, folosiÅ£i butonul âbackâ al browserului pentru a vÄ Ã®ntoarce la documentul anterior.}  
+
+_textlinknotfoundcontent_ [l=ro] {Din motive necunoscute, linkul intern selectat nu existÄ. Acest lucru se Ã®ntÃ¢mplÄ probabil datoritÄ unei erori Ã®n sursa colecÅ£iei. UtilizaÅ£i butonul âbackâ al browserului pentru a vÄ Ã®ntoarce la documentul anterior.}  
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=ro] {<h3>Link cÄtre colecÅ£ia "_2_" </h3>
+
+<p> Linkul selectat este extern colecÅ£iei "_collectionname_" (se leagÄ de colecÅ£ia "_2_").
+    DacÄ doriÅ£i vizualizarea acestui link din colecÅ£ia "_2_" puteÅ£i 
+    <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">merge</a> la aceastÄ paginÄ, altfel, folosiÅ£i butonul âbackâ al browserului pentru a vÄ Ã®ntoarce la documentul anterior.
+
+}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=ro] {Biblioteca DigitalÄ Greenstone}  
+
+_textusername_ [l=ro] {utilizator}  
+_textpassword_ [l=ro] {parolÄ}  
+
+_textmustbelongtogroup_ [l=ro] {AtenÅ£ie, trebuie sÄ faceÅ£i parte din grupul "_cgiargug_" pentru a accesa aceastÄ paginÄ}  
+
+_textmessageinvalid_ [l=ro] {Pagina cerutÄ necesitÄ Ã®nregistrarea.<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)
+VÄ rugÄm introduceÅ£i utilizatorul Åi parola Greenstone.}  
+
+_textmessagefailed_ [l=ro] {Numele utilizatorului sau parola sunt incorecte.}  
+
+_textmessagedisabled_ [l=ro] {Contul dumneavoastrÄ a fost dezactivat. VÄ rugÄm, contactaÅ£i administratorul site-ului.}  
+
+_textmessagepermissiondenied_ [l=ro] {Nu aveÅ£i permisiunea de a accesa aceastÄ paginÄ.}  
+
+_textmessagestalekey_ [l=ro] {VÄ rugÄm, introduceÅ£i parola pentru a accesa aceastÄ paginÄ.}  
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=ro] {<p>AceastÄ instalare Greenstone nu include nici o documentaÅ£ie. Acest lucru poate fi pentru cÄ:
+<ol>
+ <li>Greenstone a fost instalat de pe  CD-ROM cu o instalare compactÄ.
+ <li>Greenstone a fost instalat dintr-o distribuÅ£ie downloadatÄ de pe Internet.
+</ol>
+Ãn oricare caz documentaÅ£ia poate fi obÅ£inutÄ fie din directorul <i>docs</i>
+al CD-ROM-ului Greenstone CD-ROM sau prin vizitarea siteului <a
+href="http://www.greenstone.org">http://www.greenstone.org</a>.
+}  
+
+_textuserguide_ [l=ro] {Ghidul Utilizatorului}  
+_textinstallerguide_ [l=ro] {Ghidul de instalare}  
+_textdeveloperguide_ [l=ro] {Ghidul Dezvoltatorului}  
+_textpaperguide_ [l=ro] {De la hÃ¢rtie la colecÅ£ie}  
+_textorganizerguide_ [l=ro] {Utilizarea Organizatorului}  
+
+_textgsdocstitle_ [l=ro] {documentaÅ£ia greenstone}  
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=ro] {ConstruieÅte colecÅ£ia}  
+_textbildsuc_ [l=ro] {ColecÅ£ia a fost construitÄ cu succes.}  
+_textviewbildsummary_ [l=ro] {AÅ£i putea <a href="_httppagex_(bsummary)" target=_top>vedea sumarul de construcÅ£ie</a> a acestei colecÅ£ii pentru mai multe detalii.
+
+}  
+_textview_ [l=ro] {Vezi colecÅ£ia}  
+
+_textbild1_ [l=ro] {AceastÄ colecÅ£ie este construitÄ Ã®n acest moment. Acest lucru poate lua ceva limp. Linia de stare la momentul construcÅ£iei de mai jos dÄ informaÅ£ii despre cum progreseazÄ operaÅ£iunea.}  
+
+_textbild2_ [l=ro] {Pentru a opri procesul de construcÅ£ie Ã®n oricare moment, apÄsaÅ£i aici.
+<br>ColecÅ£ia la care lucrezi va rÄmÃ¢ne intactÄ.}  
+
+_textstopbuild_ [l=ro] {opreÅte construcÅ£ia}  
+
+_textbild3_ [l=ro] {DacÄ pÄrÄseÅti aceastÄ paginÄ (Åi nu ai anulat procesul de construcÅ£ie prin butonul âopreÅte construcÅ£iaâ) colecÅ£ia va contiua sÄ fie contruitÄ Åi va fi instalatÄ la Ã®ncheierea cu succes a operaÅ£iunii.}  
+
+_textbuildcancelled_ [l=ro] {ConstrucÅ£ie anulatÄ}  
+
+_textbildcancel1_ [l=ro] {Procesul de construcÅ£ie a fost anulat. FoloseÅte butoanele galbene pentru a face modificÄrile la colecÅ£ie sau pentru a reporni procesul de construcÅ£ie.}  
+
+_textbsupdate1_ [l=ro] {Starea construcÅ£iei se actualizeazÄ Ã®ntr-un minut}  
+_textbsupdate2_ [l=ro] {Statutul construcÅ£iei se actualizeazÄ Ã®n}  
+_textseconds_ [l=ro] {secunde}  
+
+_textfailmsg11_ [l=ro] {ColecÅ£ia nu a putut fi construitÄ deoarece nu conÅ£ine date. FiÅ£i Ã®ncredinÅ£aÅ£i cÄ cel puÅ£in un director sau un fiÅier specificate prin pagina <i>datelor sursÄ</i> existÄ Åi este de tipul (Ã®n cazul unui director) sau conÅ£ine fiÅiere de un tip procesabil de cÄtre Greenstone.}  
+
+_textfailmsg21_ [l=ro] {ColecÅ£ia nu a putut fi construitÄ (fiÅierul import.pl a eÅuat).}  
+_textfailmsg31_ [l=ro] {ColecÅ£ia nu a putut fi construitÄ (fiÅierul buildcol.pl a eÅuat).}  
+_textfailmsg41_ [l=ro] {ColecÅ£ia a fost construitÄ cu succes, dar nu a putut fi instalatÄ.}  
+_textfailmsg71_ [l=ro] {O eroare neaÅteptatÄ s-a ivit Ã®n timpul construirii colecÅ£iei}  
+
+
+_textblcont_ [l=ro] {Jurnalul de construire conÅ£ine urmÄtoarele informaÅ£ii:}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=ro] {structura iniÅ£ialÄ}  
+_textmore_ [l=ro] {mai departe}  
+_textinfo_ [l=ro] {InformaÅ£ii referitoare la colecÅ£ie}  
+_textsrce_ [l=ro] {Date sursÄ}  
+_textconf_ [l=ro] {ConfigureazÄ colecÅ£ia}  
+_textdel_ [l=ro] {Återge colecÅ£ia}  
+_textexpt_ [l=ro] {Exporarea colecÅ£iei}  
+
+_textdownloadingfiles_ [l=ro] {Downloadarea fiÅierelor...}  
+_textimportingcollection_ [l=ro] {Import colecÅ£ia...}  
+_textbuildingcollection_ [l=ro] {Construiesc colecÅ£ia...}  
+_textcreatingcollection_ [l=ro] {crearea colecÅ£iei}  
+
+_textcollectorblurb_ [l=ro] {<i>Pana este mai puternicÄ decÃ¢t spada !
+<br>Construirea Åi distribuirea colecÅ£iilor de informaÅ£ii implicÄ responsabilitÄÅ£i care ar trebui gÃ¢ndire cu atenÅ£ie Ã®nainte de a Ã®ncepe. ExistÄ problemele legate de drepturile de copyright, adicÄ posibilitatea de a accesa documente nu Ã®nseamnÄ neapÄrat cÄ poÅ£i sÄ le dai la alÅ£ii. ExistÄ implicaÅ£ii de ordin social: colecÅ£iile trebuie sÄ respecte obiceiurile comunitÄÅ£ii din cadrul cÄreia au izvorÃ¢t. ExistÄ Åi probleme de naturÄ etica precum faptul cÄ anumite lucruri nu trebuie sÄ fie disponibile altora.
+<br>ConÅtientizaÅ£i puterea informaÅ£iei Åi folosiÅ£i-o cu Ã®nÅ£elepciune.
+</i>}  
+
+_textcb1_ [l=ro] {Colectorul Ã®Å£i permite sÄ creezi noi colecÅ£ii, sÄ modifici sau sÄ adaugi la cele existente ori, chiar sÄ le Återgi. Pentru a face acest lucru vei fi condus printr-o serie de pagini web, care vor solicita informaÅ£iile necesare.}  
+
+_textcb2_ [l=ro] {Mai Ã®ntÃ¢i trebuie decis dacÄ}  
+_textcnc_ [l=ro] {crearea unei colecÅ£ii noi}  
+_textwec_ [l=ro] {lucru cu una existentÄ, adÄugare de date sau Återgerea.}  
+
+_textcb3_ [l=ro] {Pentru a construi sau modifica colecÅ£iile bibliotecii digitale mai Ã®ntÃ¢i trebuie ÅÄ te Ã®nregistrezi. Acest lucru este necesar pentru a te proteja de ceilalÅ£i utilizatori care se Ã®nregistreazÄ pe acelaÅi computer Åi care modificÄ informaÅ£ia existentÄ pe acesta. NotÄ: din motive de securitate vei fi automat deconectat dupÄ 30 de minute. DacÄ acest lucru se Ã®ntÃ¢mplÄ, nu trebuie sÄ vÄ impacientaÅ£i - veÅ£i fi invitat sÄ vÄ Ã®nregistraÅ£i din nou Åi veÅ£i putea relua de unde aÅ£i fost Ã®ntrerupt.}  
+
+_textcb4_ [l=ro] {IntroduceÅ£i numele de utilizator Åi parola, apoi apÄsaÅ£i pe buton pentru Ã®nregistrare.}  
+
+_textfsc_ [l=ro] {Mai Ã®ntÃ¢i, selectaÅ£i colecÅ£ia cu care doriÅ£i sÄ lucraÅ£i (colecÅ£iile protejate la scriere nu vor apÄrea Ã®n aceastÄ listÄ).}  
+
+_textwtc_ [l=ro] {Cu aceastÄ colecÅ£ie puteÅ£i sÄ}  
+_textamd_ [l=ro] {AdaugÄ mai multe date Åi reconstruieÅte colecÅ£ia}  
+_textetc_ [l=ro] {EditeazÄ fiÅierul de configurare a colecÅ£iei Åi reconstruieÅte colecÅ£ia}  
+_textdtc_ [l=ro] {Återge colecÅ£ia pe de-antregul}  
+_textetcfcd_ [l=ro] {ExportÄ colecÅ£ia pentru a fi inscripÅ£ionatÄ pe un CD-ROM Windows auto-instalabil}  
+_textcaec_ [l=ro] {modificarea unei colecÅ£ii existente}  
+_textnwec_ [l=ro] {Nu sunt disponibile colecÅ£ii pretabile la scriere pentru a fi modificate}  
+_textcianc_ [l=ro] {Crearea unei noi colecÅ£ii}  
+_texttsosn_ [l=ro] {SecvenÅ£a paÅilor necesari pentru a crea o nouÄ colecÅ£ie a unei biblioteci digitale sunt:}  
+_textsin_ [l=ro] {Specifica-i numele (Åi informaÅ£iile asociate)}  
+_textswts_ [l=ro] {SpecificÄ de unde provin datele sursÄ}  
+_textatco_ [l=ro] {AjusteazÄ opÅ£iunile de configurare (doar pentru utilizatorii avansaÅ£i)}  
+_textbtc_ [l=ro] {âConstruieÅteâ colecÅ£ia (vezi mai jos)}  
+_textpvyh_ [l=ro] {Vizualizarea muncii.}  
+
+_texttfsiw_ [l=ro] {Cel de-al patrulea pas este acela Ã®n care computerul face toatÄ munca. Ãn procesul de âconstruireâ, computerul face toate indexurile Åi adunÄ la un loc orice altÄ informaÅ£ie este necesarÄ pentru a face totul funcÅ£ional. Dar mai Ã®ntÃ¢i trebuie specificatÄ informaÅ£ia.}  
+
+_textadab_ [l=ro] {Mai jos apare o diagramÄ care ajutÄ la orientarea rapidÄ. Butonul verde este cel care permite continuarea operaÅ£iunilor. Pe mÄsurÄ de operaÅ£iunile se desfÄÅ£oarÄ, butonul se va schimba Ã®n galben. Te poÅ£i Ã®ntoarce la o paginÄ anterioarÄ prin apÄsarea pe butonul galben corespunzÄtor din cadrul diagramei.}  
+
+_textwyar_ [l=ro] {Atunci cÃ¢nd sunteÅ£i pregÄtit, apÄsaÅ£i butonul verde âinformaÅ£ii despre colecÅ£ieâ pentru a Ã®ncepe crearea unei noi colecÅ£ii digitale !}  
+
+_textcnmbs_ [l=ro] {Numele colecÅ£iei trebuie specificat}  
+_texteambs_ [l=ro] {Trebuie specificatÄ adresa de email}  
+_textpsea_ [l=ro] {VÄ rugÄm, specificaÅ£i adresa de email Ã®n forma: numeutilizator@domeniu}  
+_textdocmbs_ [l=ro] {Descrierea colecÅ£iei trebuie specificatÄ}  
+
+_textwcanc_ [l=ro] {Atunci cÃ¢nd este creatÄ o nouÄ colecÅ£ie trebui introduse informaÅ£ii preliminare despre datele sursÄ. Acest preces este structurat ca o serie de pagini web supervizate de cÄtre Colector. Bara din partea de jos a paginii aratÄ secvenÅ£a de pagini care trebuie completate.}  
+
+_texttfc_ [l=ro] {Titlul colecÅ£iei:}  
+
+_texttctiasp_ [l=ro] {Titlul colecÅ£iei este o frazÄ scurtÄ folositÄ Ã®n toatÄ biblioteca digitalÄ pentru a identifica conÅ£inutul colecÅ£iei. Titluri pentru exemplificare pot fi âRapoarte Tehnice din domeniul ÅtiinÅ£ei Calculatoarelorâ Åi âBibliteca pentru Dezvoltarea UmanitÄÅ£iiâ}  
+
+_textcea_ [l=ro] {AdresÄ de email de contact:}  
+
+_textteas_ [l=ro] {AceastÄ adresÄ de email specificÄ primul punct de contact pentru colecÅ£ie. DacÄ software-ul Greenstone detecteazÄ o problemÄ, este trimis un raport de diagnostic la aceastÄ adresÄ. IntroduceÅ£i o adresÄ de email Ã®n formÄ completÄ:
+<tt>nume@domeniu</tt>.}  
+
+_textatc_ [l=ro] {Despre aceastÄ colecÅ£ie:}  
+
+_texttiasd_ [l=ro] {Aceasta este declaraÅ£ia descriptivÄ a principiilor care guverneazÄ ce este cuprins Ã®n cadrul colecÅ£iei. Apare pe prima paginÄ atunci cÃ¢nd este prezentatÄ colecÅ£ia}  
+
+_textypits_ [l=ro] {PoziÅ£ia din proces este indicatÄ printr-o sÄgeatÄ dedesubt - Ã®n acest caz, stadiul âinformaÅ£ie despre colecÅ£ieâ. Pentru a continua, apÄsaÅ£i pe butonul verde âdate sursÄâ.}  
+
+_srcebadsources_ [l=ro] {<p>una sau mai multe surse de intrÄri specificate nu sunt disponibile (marcaj 
+_iconcross_ below).
+
+<p>Acest lucru se poate Ã®ntÃ¢mpla pentru cÄ:
+<ul>
+<li>FiÅierul, site-ul FTP sau URL-ul nu existÄ.
+<li>Mai Ã®ntÃ¢i trebuie sÄ stabiliÅ£i o conexiune cu furnizorul de servicii Internet.
+<li>ÃncercaÅ£i ÅÄ accesaÅ£i un URL din spatele unui firewall (acesta poate fi momentul Ã®n care Ã®n mod normal ar trebui sÄ introduceÅ£i un nume de utilizator Åi o parolÄ pentru a aceesa serviciile internet).
+</ul>
+
+<p>DacÄ este un URL pe care-l puteÅ£i vedea Ã®n browser, acesta poate proveni dintr-un cache local. Din pÄcate, copiile stocate Ã®n cachesunt invizibile procesului de mirroring al Greenstone. Ãn acest caz, recomandÄm ca mai Ã®ntÃ¢i sÄ downloadaÅ£i paginile mai Ã®ntÃ¢i folosind browserul.
+}  
+
+_textymbyco_ [l=ro] {<p>ÃÅ£i poÅ£i baza colecÅ£ia pe
+<ul>
+<li>Structura iniÅ£ialÄ
+<dl><dd>Noua colecÅ£ie poate conÅ£ine documente html (.htm, .html), text (.txt, .text), documente MS Word (.doc), documente PDF(.pdf) sau
+documente Ã®n format email âm-boxâ (.mbx).</dd></dl>
+<li>O colecÅ£ie preexistentÄ
+<dl><dd>FiÅierele din noua colecÅ£ie trebuie sÄ fie exact de acelaÅi tip precum cele folosite pentru a construcÅ£ia celei existente.</dd></dl>
+</ul>
+}  
+
+_textbtco_ [l=ro] {Pune bazele colecÅ£iei pe}  
+_textand_ [l=ro] {AdaugÄ mai multe date}  
+_textad_ [l=ro] {AdÄugarea datei:}  
+
+_texttftysb_ [l=ro] {FiÅierele specificate mai jos vor fi adÄugate la colecÅ£ie. AveÅ£i grijÄ sÄ nu specificaÅ£i fiÅiere care esitÄ deja Ã®n colecÅ£ie, altfel vor fi incluse douÄ copii ale aceluiaÅi fiÅier. FiÅierele sunt identificate prin calea completÄ, prin paginile web cu adresa absolutÄ.}  
+
+_textis_ [l=ro] {Surse de input:}  
+
+_textddd1_ [l=ro] {<p>DacÄ foloseÅti file:// sau ftp:// pentru a specifica un fiÅier, acel fiÅier va fi downloadat.
+
+<p>DacÄ foloseÅti http:// depinde dacÄ URL-ul returneazÄ o paginÄ web normalÄ sau o listÄ de fiÅiere. DacÄ este o paginÄ, atunci acea paginÄ va fi dowloadatÄ Åi astfel toate paginile care se leagÄ de aceasta cu condiÅ£ia ca acestea sÄ stea pe acelaÅi site.
+
+<p>DacÄ foloseÅti file:// sau ftp:// pentru a specifica un fiÅier sau un director sau introducerea unui URL http:// care conduce la o listÄ de fiÅiere, tot ce existÄ Ã®n director Åi toare subdirectoarele vor fi incluse Ã®n colecÅ£ie.
+
+<p>Clic pe butonul âmai multe surseâ pentru a completa mai multe cÃ¢mpuri.
+}  
+
+_textddd2_ [l=ro] {<p>ApasÄ unul din butoanele verzi. DacÄ eÅti un utilizator avansat poatre doreÅti sÄ ajustezi configurarile colecÅ£iei. Alternativ, poÅ£i merge direct la faza construcÅ£iei colecÅ£iei. Trebuie notat cÄ orice etapÄ anterioarÄ poare fi din nou editatÄ prin folosirea botonului galben.}  
+
+_textconf1_ [l=ro] {<p>Construirea Åi prezentarea colecÅ£iei sunt controlate de specificaÅ£ii Ã®ntr-un âfiÅier de configurareâ special. Utilizatorii avansaÅ£i poate vor dori sÄ modifice setÄrile de configurare.
+
+<center><p><b>DacÄ nu eÅti un utilizator avansat, procedaÅ£i spre partea de jos a paginii.</b></center> 
+
+<p>Pentru a modifica setÄrile de configurare, editaÅ£i datele de mai jos.
+DacÄ faceÅ£i o greÅealÄ, apÄsaÅ£i pe âResetâ pentru a reveni la setÄrile iniÅ£iale ale configurÄrii.
+}  
+
+_textreset_ [l=ro] {Reset}  
+
+
+_texttryagain_ [l=ro] {VÄ rugÄm <a href="_httppagecollector_" target=_top>restart the collector</a>
+Åi Ã®ncercaÅ£i din nou.
+}  
+
+
+_textretcoll_ [l=ro] {Ãntoarce-te la colector}  
+
+_textdelperm_ [l=ro] {O parte din colecÅ£ia _cgiargbc1dirname_ nu a putut fi ÅtearsÄ. Cauzele posibile pot fi:
+<ul>
+<li> Greenstone nu are permisiunea de a Återge directorul _gsdlhome_/collect/_cgiargbc1dirname_
+.<br>
+Este posibil sÄ fie nevoie de Återgerea manualÄ a acestui director pentru a Ã®ncheia Återgerea colecÅ£iei _cgiargbc1dirname_ din acest computer.</li>
+<li>Greenstone nu poate rula programul _gsdlhome_/bin/script/delcol.pl. AsiguraÅ£i-vÄ cÄ acest fiÅier poate fi citit Åi este executabil.</li>
+</ul>
+}  
+
+_textdelinv_ [l=ro] {ColecÅ£ia _cgiargbc1dirname_ este protejatÄ sau nevalidÄ. Återgerea a fost anulatÄ.
+}  
+
+_textdelsuc_ [l=ro] {ColecÅ£ia _cgiargbc1dirname_ a fost ÅtearsÄ cu succes.}  
+
+_textclonefail_ [l=ro] {ColecÅ£ia _cgiargclonecol_ nu poate fi clonatÄ. Cauzele posibile sunt:
+<ul>
+<li> ColecÅ£ia _cgiargclonecol_ nu existÄ
+<li> ColecÅ£ia _cgiargclonecol_ nu are fiÅier de configurare collect.cfg
+<li> Greenstone nu are permisiunea de a citi fiÅierul de configurare collect.cfg
+</ul>
+}  
+
+_textcolerr_ [l=ro] {Eroare la Colector.}  
+
+_texttmpfail_ [l=ro] {Colectorul a eÅuat citirea sau scrierea Ã®ntr-un fiÅier temporar sau director. Cauzele posibile sunt:
+<ul>
+<li> Greenstone nu are acces read/write pentru directoru _gsdlhome_/tmp .
+</ul>
+}  
+
+_textmkcolfail_ [l=ro] {Colectorul a eÅuat Ã®n crearea structurii de directoare necesare noii colecÅ£ii (fiÅierul mkcol.pl a eÅuat). Cauzele posibile sunt:
+<ul>
+<li> Greenstone nu are permisiunea de scriere asupra directorului _gsdlhome_/tmp.
+<li> Scriptul mkcol.pl prezintÄ erori.
+</ul>
+}  
+
+_textnocontent_ [l=ro] {Eroare de Colector: nu a fost furnizat nici un nume pentru noua colecÅ£ie. ÃncearcÄ repornirea Colectorului de la Ã®nceput.}  
+
+_textrestart_ [l=ro] {Repornirea Colectorului}  
+
+_textreloaderror_ [l=ro] {A apÄrut o eroare la crearea unei noi colecÅ£ii. Acest lucru se poate Ã®ntÃ¢mpla datoritÄ confuziei sistemului Greenstone privind utilizarea funcÅ£iei de âreloadâ sau a butoanelor âbackâ ale browserului folosit (vÄ rugÄm sÄ evitaÅ£i folosirea acestor butoane Ã®n timpul creÄrii unei colecÅ£ii cu ajutorul Colectorului). Se recomandÄ repornirea Colectorului de la Ã®nceput.}  
+
+_textexptsuc_ [l=ro] {ColecÅ£ia _cgiargbc1dirname_ a fost exportatÄ cu succes Ã®n directorul
+_gsdlhome_/tmp/exported\__cgiargbc1dirname_ .}  
+
+_textexptfail_ [l=ro] {<p>Eroare la exportarea colecÅ£iei _cgiargbc1dirname_ .
+
+<p>Acest lucru se Ã®ntÃ¢mplÄ de cele mai multe ori pentru cÄ Greenstone a fost instalat fÄrÄ componentele necesare pentru a suporta funcÅ£ia âExportÄ ColecÅ£iaâ.
+<ul>
+
+ <li>DacÄ ai instalat Greenstone de pe un CD-ROM, aceste componente nu ai fost instalate doare decÃ¢t sÄ fi fost selectate Ã®n cazul instalÄrii customizate.
+ Acestea pot fi adÄugate instalÄrii prin reluarea procedurii de instalare.
+
+ <li>DacÄ instalarea s-a fÄcut dupÄ o distribuÅ£ie web va fi necesar sÄ downloadezi Åi sÄ instalezi un pachet adiÅ£ional pentru a avea acces la aceastÄ funcÅ£ie. VizitaÅ£i <a href="http://www.greenstone.org">http://www.greenstone.org</a> sau trimiteÅ£i un
+ email la<a
+ href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>
+pentru mai multe detalii.
+
+</ul>
+}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=ro] {<p> VÄ rugÄm, specificaÅ£i urmÄtoarele informaÅ£ii despre fiÅier Åi apÄsaÅ£i pe _textintro_ below. </p>
+
+}  
+
+_textcaec_ [l=ro] {Completarea colecÅ£iei existente}  
+_textbild_ [l=ro] {Element de depozit}  
+_textintro_ [l=ro] {SelecteazÄ fiÅierul}  
+_textconfirm_ [l=ro] {Confirmare}  
+_textselect_ [l=ro] {SelecteazÄ colecÅ£ia}  
+_textmeta_ [l=ro] {SpecificÄ Metadatele}  
+
+_texttryagain_ [l=ro] {VÄ rugÄm, <a href="_httppagedepositor_" target=_top>reporniÅ£i depozitorul</a>
+Åi Ã®ncercaÅ£i din nou.
+}  
+
+_textselectcol_ [l=ro] {SelecteazÄ colecÅ£ia Ã®n care aÅ£i dori sÄ adÄugaÅ£i un nou document.}  
+_textfilename_ [l=ro] {Nume fiÅier}  
+_textfilesize_ [l=ro] {Dimensiunea fiÅierului}  
+
+_textretcoll_ [l=ro] {Ãntoarce-te la depozitar}  
+
+
+_texttmpfail_ [l=ro] {Depozitorul a eÅuat Ã®n citirea sau scrierea unui fiÅier temporar sau director. Cauzele posibile sunt:
+<ul>
+<li> Greenstone nu are acces read/write access la directorul _gsdlhome_/tmp.
+</ul>
+}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=ro] {"Greenstone este o suitÄ software care are capacitatea de a sluji colecÅ£iilor digitale de bibliotecÄ Åi sÄ construiascÄ noi colecÅ£ii. FurnizeazÄ o nouÄ metodÄ de a organiza Åi publica informaÅ£ie prin intermediul Internetului sau pe CD-ROM. Greenstone este produs de New Zealand Digital Library Project din cadrul UniversitÄÅ£ii din Waikato Åi este distribuit Ã®n cooperare cu Unesco Åi Human Info NGO. Este software open-source disponibil de la adresa <i>http://greenstone.org</i> sub termenii de licenÅ£iere GNU General Public License."}  
+
+_textgreenstone2_ [l=ro] {"Site-ul Bibliotecii Digitale a Noii Zeelande (<a
+href="http://nzdl.org">http://nzdl.org</a>) conÅ£ine numeroase colecÅ£ii pentru exemplificare, toate create cu pachetul software Greenstone, care sunt publice Åi sunt disponibile examinÄrii. Acestea simplificÄ diferitele opÅ£iuni de cÄutare Åi navigare, incluzÃ¢nd colecÅ£ii Ã®n limbile arabÄ, chinezÄ, francezÄ, maori, spaniolÄ precum Åi Ã®n englezÄ. ExistÄ chiar Åi colecÅ£ii de muzicÄ.
+"}  
+
+_textplatformtitle_ [l=ro] {platfomÄ}  
+_textgreenstone3_ [l=ro] {"Greenstone ruleazÄ pe Windows, Unix Åi Mac OS X. DistribuÅ£ia include fiÅierele binare pentru toate versiunile de Windows, Linux Åi Mac OS X. De asemenea, include codul sursÄ pentru sistem, care poate fi compilat folosindu-se Microsoft C++ sau gcc. Greenstone funcÅ£ioneazÄ Ã®mpreunÄ cu software-ul asociat, care este liber: webserver-ul Apache Åi PERL. InterfeÅ£ele cu utilizatorul folosesc un browser web, de obicei Netscape Navigator sau Internet Explorer."}  
+
+_textgreenstone4_ [l=ro] {Multe dintre colecÅ£iile de documente sunt distribuite pe CD-ROM, folosindu-se software-ul Greeenstone. De exemplu, <i>Humanity Development Library</i> conÅ£ine 1.230 de publicaÅ£ii variind de la contabilitate pÃ¢nÄ la tratarea apelor menajere. Acestea ruleazÄ cu necesitÄÅ£i minimale din partea calculatorul cum sunt cele Ã®ntÃ¢lnite preponderent Ã®n Å£Ärile Ã®n curs de dezvoltare. InformaÅ£ia poate fi accesatÄ prin cÄutare, trecerea Ã®n revistÄ a titlurilor, navigarea dupÄ organizaÅ£ii, parcurgerea unei liste de materiale âCum-SÄâ Åi prin alegerea la Ã®ntÃ¢mplare a coperÅ£ilor cÄrÅ£ilor.
+}  
+
+_textcustomisationtitle_ [l=ro] {personalizare}  
+_textgreenstone5_ [l=ro] {Greenstone este proiectat special pentru a fi foarte flexibil Åi configurabil. Un document nou Åi formatele de metadate sunt abordate prin scrierea de âextensiiâ (plugins) Ã®n limbajul de programare PERL. Ãn mod analog, structurile noi de metadate pentru navigare pot fi implementate prin scrierea âclasificatorilorâ. Modul Ã®n care aratÄ Åi se comportÄ interfaÅ£a poate fi modificat folosindu-se âmacro-uriâ scrise Ã®ntr-un limbaj accesibil. Un protocol tip CORBA permite agenÅ£ilor (ex. Ã®n Java) sÄ foloseascÄ toate facilitÄÅ£ile asociate colecÅ£iilor documentului. Ãn final, codul sursÄ scris Ã®n limbajul de programare C++ Åi PERL este disponibil Åi este accesibil pentru a putea fi modificat.}  
+
+_textdocumentationtitle_ [l=ro] {documentaÅ£ie}  
+_textdocuments_ [l=ro] {Pentru software-ul Greenstone este disponibilÄ documentaÅ£ie extensivÄ .}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=ro] {lista de mail}  
+_textmailinglist_ [l=ro] {ExistÄ o listÄ de mail gÃ¢nditÄ Ã®n primul rÃ¢nd pentru discuÅ£ii privind software-ul pentru biblioteci digitale - Greenstone. Utilizatorii activi ai Greenstone ar trebui sÄ ia Ã®n consideraÅ£ie Ã®ncrierea Ã®n lista de mail Åi contribuÅ£ia la discuÅ£ii. Pentru Ã®nscriere mergeti la <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+Pentru a trimite un mesaj listei, scrieÅ£i la adresa <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>.}  
+
+_textbugstitle_ [l=ro] {buguri}  
+_textreport_ [l=ro] {Dorim sÄ ne asigurÄm cÄ software-ul lucreazÄ corect pentru dumneavoastrÄ. VÄ rugÄm sÄ raportaÅ£i oricare deficienÅ£e la <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>}  
+
+_textgs3title_ [l=ro] {Ã®n lucru}  
+_textgs3_ [l=ro] {Greenstone 3 reprezintÄ un sistem reproiectat Åi reimplementat, care are aceleaÅi facilitÄÅ£i precum cele ale sistemului Greenstone 2 (versiunea curentÄ) - de exemplu, este multilingv, multiplatformÄ Åi prezintÄ un Ã®nalt grad de configurabilitate. IncorporeazÄ toate caracteristicile sistemului existent Åi este compatibil cu versiunile anterioare, astfel cÄ poate construi Åi rula colecÅ£ii existente fÄrÄ modificÄri. Este scris Ã®n Java Åi este structurat ca o reÅ£ea de module independente care comunicÄ folosind XML, astfel cÄ funcÅ£ioneazÄ Ã®ntr-o manierÄ distribuitÄ Åi poate fi desfÄÅurat pe mai multe servere dacÄ acest lucru este necesar. Acest design modular mÄreÅte flexibilitatea Åi extensibilitatea Greenstone. DocumentaÅ£ia Åi ediÅ£iile experimentale ale Greenstone 3 poate fi downloadat de la adresa <a href="http://www.greenstone.org/greenstone3.html">Greenstone 3 home page</a>.}  
+
+_textcreditstitle_ [l=ro] {credit}  
+
+_textwhoswho_ [l=ro] {Greenstone reprezintÄ un efort colaborativ Ã®ntre mai mulÅ£i participanÅ£i. Rodger McNab Åi Stefan Boddie sunt principalii arhitecÅ£i Åi implementatori. Au mai contribuit David Baunbridge, George
+Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd Reed, Bill Rogers, John Thompson Åi Stuart Yeates. Membrii proiectului Bibliotecii Digitale a Noii Zeelande au contribuit cu sfaturi Åi inspiraÅ£ie Ã®n proiectarea sistemului:  Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka
+Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols Åi Lloyd Smith. Dorim sÄ mulÅ£umim, de asemenea, Åi tuturor celor care au contribuit la elaborarea pachetelor licenÅ£iate GNU incluse Ã®n aceastÄ distribuÅ£ie: MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE Åi XLHTML.}  
+
+_textaboutgslong_ [l=ro] {despre software-ul greenstone}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=ro] {Lista curentÄ a utilizatorilor}  
+_textuser_ [l=ro] {utilizator}  
+_textas_ [l=ro] {starea contului}  
+_textgroups_ [l=ro] {grupuri}  
+_textcomment_ [l=ro] {comentariu}  
+_textadduser_ [l=ro] {adaugÄ un nou utilizator}  
+_textedituser_ [l=ro] {editeazÄ}  
+_textdeleteuser_ [l=ro] {Återge}  
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=ro] {EditeazÄ informaÅ£iile despre utilizator}  
+_textadduser_ [l=ro] {AdaugÄ un nou utilizator}  
+
+_textaboutusername_ [l=ro] {Numele utilizatorilor trebuie sÄ fie Ã®ntre 2 Åi 30 de caractere. Acestea pot conÅ£ine caractere alfanumerice, â.â Åi â_â}  
+
+_textaboutpassword_ [l=ro] {Parolele trebuie sÄ aibe o lungime cuprinsÄ Ã®ntre 3 Åi 128 caractere. Acestea pot conÅ£ine doar caractere printabile ASCII}  
+
+_textoldpass_ [l=ro] {dacÄ acest cÃ¢mp este gol, atunci parola veche va fi menÅ£inutÄ.}  
+_textenabled_ [l=ro] {activat}  
+_textdisabled_ [l=ro] {dezactivat}  
+
+_textaboutgroups_ [l=ro] {Grupurile sunt de fapt o listÄ de elemente separate prin virgulÄ, nu puneÅ£i spaÅ£ii dupÄ virgule.}  
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=ro] {Återge un utilizator}  
+_textremwarn_ [l=ro] {DoriÅ£i sÄ ÅtergeÅ£i definitiv utilizatorul <b>_cgiargumun_</b>?}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=ro] {SchimbÄ parola}  
+_textoldpw_ [l=ro] {vechea parolÄ}  
+_textnewpw_ [l=ro] {noua parolÄ}  
+_textretype_ [l=ro] {reintrodu noua parolÄ}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=ro] {Parola dumneavoastrÄ a fost schimbatÄ cu succes.}  
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=ro] {Numele utilizatorului este invalid.}  
+_textinvalidpassword_ [l=ro] {parola este invalidÄ.}  
+_textemptypassword_ [l=ro] {VÄ rugÄm introduceÅ£i o parolÄ iniÅ£ialÄ pentru acest utilizator.}  
+_textuserexists_ [l=ro] {Acest utilizator existÄ deja, vÄ rugÄm introduceÅ£i un alt nume de utilizator.}  
+
+_textusernameempty_ [l=ro] {VÄ rugÄm, introduceÅ£i numele utilizatorului.}  
+_textpasswordempty_ [l=ro] {Trebuie sÄ reintroduceÅ£i parola veche.}  
+_textnewpass1empty_ [l=ro] {IntroduceÅ£i o parolÄ nouÄ Åi apoi reintroduceÅ£i-o.}  
+_textnewpassmismatch_ [l=ro] {Cele douÄ versiuni ale noii parole nu corespund.}  
+_textnewinvalidpassword_ [l=ro] {AÅ£i introdus o parolÄ invalidÄ.}  
+_textfailed_ [l=ro] {Ori numele utilizatorului, ori parola au fost introduse incorect.}  
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=ro] {NumÄrul versiunii Greenstone}  
+_textframebrowser_ [l=ro] {Trebuie sÄ aveÅ£i un frame incorporat Ã®n browser pentru a vedea aceasta.}  
+_textusermanage_ [l=ro] {Managementul utilizatorilor}  
+_textlistusers_ [l=ro] {afiÅeazÄ utilizatorii}  
+_textaddusers_ [l=ro] {adaugÄ un nou utilizator}  
+_textchangepasswd_ [l=ro] {schimbÄ parola}  
+_textinfo_ [l=ro] {InformaÅ£ie tehnicÄ}  
+_textgeneral_ [l=ro] {general}  
+_textarguments_ [l=ro] {argumente}  
+_textactions_ [l=ro] {acÅ£iuni}  
+_textbrowsers_ [l=ro] {browsere}  
+_textprotocols_ [l=ro] {protocoale}  
+_textconfigfiles_ [l=ro] {FiÅiere de Configurare}  
+_textlogs_ [l=ro] {Jurnale}  
+_textusagelog_ [l=ro] {jurnalul de utilizare curent}  
+_textinitlog_ [l=ro] {jurnalier de iniÅ£ializare}  
+_texterrorlog_ [l=ro] {jurnalierul erorilor}  
+_textadminhome_ [l=ro] {administrator}  
+_textreturnhome_ [l=ro] {Greenstone home}  
+_titlewelcome_ [l=ro] {Administrare}  
+_textmaas_ [l=ro] {ÃntreÅ£inerea Åi administrarea serviciilor disponibile include:}  
+_textvol_ [l=ro] {vezi jurnalele on-line}  
+_textcmuc_ [l=ro] {creazÄ, gestioneazÄ Åi actualizeazÄ colecÅ£iile}  
+_textati_ [l=ro] {acceseazÄ informaÅ£ii tehnice precum argumentele CGI}  
+
+_texttsaa_ [l=ro] {Aceste servicii sunt disponibile folosind bara lateralÄ de navigare de pe partea stÃ¢ngÄ a paginii.}  
+
+_textcolstat_ [l=ro] {Starea ColecÅ£iei}  
+
+_textcwoa_ [l=ro] {ColecÅ£iile apar ca ârulÃ¢ndâ doar dacÄ existÄ fiÅierul build.cfg corespondent, dacÄ pot fi citite Åi dacÄ conÅ£in un cÃ¢mp builddate valid (i.e. > 0). De asemenea, trebuie sÄ fie Ã®n directorul index al colecÅ£iilor (i.e. SÄ NU fie Ã®n directorul de construcÅ£ie).}  
+
+_textcafi_ [l=ro] {apÄsaÅ£i <i>abr. </i>pentru informaÅ£ii privind o colecÅ£ie}  
+_textcctv_ [l=ro] {apÄsaÅ£i  <i>colecÅ£ie</i> pentru a o vedea}  
+_textsubc_ [l=ro] {Propune modificÄrile}  
+_texteom_ [l=ro] {Eroare la deschiderea fiÅierului main.cfg}  
+_textftum_ [l=ro] {Actualizarea fiÅierului main.cfg a eÅuat}  
+_textmus_ [l=ro] {fiÅierul main.cfg a fost actualizat cu succes}  
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=ro] {ConstruieÅte sumarul pentru colecÅ£ia "_collectionname_"}  
+_textflog_ [l=ro] {Logare eÅuatÄ pentru colecÅ£ia "_collectionname_"}  
+_textilog_ [l=ro] {ImportÄ logarea pentru colecÅ£ia "_collectionname_"}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=ro] {TRIMITE FEEDBACK}  
+
+_greenstoneusabilitytext_ [l=ro] {Ergonomia Greenstone}  
+
+_textwhy_ [l=ro] {<p> Trimite acest raport Ã®ntr-o formÄ prin care sÄ indici cÄ ai gÄsit pagina web pe care o vizualizezi cu dificultÄÅ£i.}  
+_textextraforform_ [l=ro] {Nu trebuie sÄ completezi formularul - orice informaÅ£ie ar putea fi de folos.}  
+_textprivacybasic_ [l=ro] {<p>Raportul va conÅ£ine doar informaÅ£ie despre pagina web Greenstone pe care o vedeÅ£i Åi despre tehnologia folositÄ pentru a o vedea (plus oricare altÄ informaÅ£ie o furnizaÅ£i).}  
+_textstillsend_ [l=ro] {DoriÅ£i sÄ trimiteÅ£i acest raport ?}  
+
+_texterror_ [l=ro] {eroare}  
+_textyes_ [l=ro] {Da}  
+_textno_ [l=ro] {Nu}  
+_textclosewindow_ [l=ro] {Ãnchide fereastra}  
+_textabout_ [l=ro] {Despre}  
+_textprivacy_ [l=ro] {Intimitate}  
+_textsend_ [l=ro] {Trimite}  
+_textdontsend_ [l=ro] {Nu trimite}  
+_textoptionally_ [l=ro] {OpÅ£ional}  
+
+_textunderdev_ [l=ro] {Vizualizarea detaliilor va fi disponibilÄ Ã®n versiunea finalÄ.}  
+
+_textviewdetails_ [l=ro] {Vezi detaliile raportului}  
+_textmoredetails_ [l=ro] {Mai multe detalii}  
+_texttrackreport_ [l=ro] {UrmÄreÅte acest raport}  
+_textcharacterise_ [l=ro] {Ce fel de problemÄ este}  
+_textseverity_ [l=ro] {CÃ¢t de gravÄ este problema ?}  
+ 
+_textbadrender_ [l=ro] {Pagina aratÄ ciudat}  
+_textcontenterror_ [l=ro] {Eroare de conÅ£inut}  
+_textstrangebehaviour_ [l=ro] {Comportament bizar}  
+_textunexpected_ [l=ro] {S-a Ã®ntÃ¢mplat ceva neaÅteptat}  
+_textfunctionality_ [l=ro] {Greu de utilizat}  
+_textother_ [l=ro] {Altele}  
+
+_textcritical_ [l=ro] {Critic}  
+_textmajor_ [l=ro] {Serios}  
+_textmedium_ [l=ro] {Mediu}  
+_textminor_ [l=ro] {Minor}  
+_texttrivial_ [l=ro] {Comun}  
+
+_textwhatdoing_ [l=ro] {Ce fÄceaÅ£i Ã®n acel moment ?}  
+_textwhatexpected_ [l=ro] {Ce asteptaÅ£i sÄ se Ã®ntÃ¢mple Ã®n acel moment ?}  
+_textwhathappened_ [l=ro] {Ce s-a Ã®ntÃ¢mplat de fapt ?}  
+
+_cannotfindcgierror_ [l=ro] {<h2>Ne pare rÄu!</h2>Nu poate fi gÄsit serverul de programe pentru butonul "_linktextusab_".}  
+
+_textusabbanner_ [l=ro] {Tipul de banner koru}  
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=ro] {A apÄrut o eroare}  
+
+_textgtihome_ [l=ro] {Aceste pagini te ajutÄ ÅÄ Ã®mbunÄtÄÅ£eÅti suportul multilingv al Greenstone. UtilizÃ¢ndu-le poÅ£i sÄ
+<ul>
+  <li>traduci pÄrÅ£i din Greenstone Ã®n alte limbi
+  <li>actualizezi traducerea unei interfeÅ£e existente atunci cÃ¢nd interfaÅ£a Ã®n englezÄ se modificÄ (de exemplu, pentru noile capacitÄÅ£i ale Greenstone)
+  <li>corectezi erorile din traducerile existente
+</ul>
+
+Vor fi prezentate o serie de pagini web, fiecare conÅ£inÃ¢nd cÃ¢te o frazÄ de tradus.
+Se va proceda prin traducerea interfeÅ£ei frazÄ dupÄ frazÄ.
+Multe fraze conÅ£in formatÄri HTML: nu trebuie procedat la traducerea acestora, ci se vor pÄstra intacte Ã®n versiunea tradusÄ. Cuvintele flancate de underscor (precum: _acestea_) nu trebuie traduse (reprezintÄ nume de âmacro-uriâ Greenstone).
+<p>
+DacÄ se actualizeazÄ o interfaÅ£Ä existentÄ nu vi se vor prezenta frazele pentru care existÄ deja un corespondent de traducere. Uneori se poate ca o traducere sÄ existe, dar textul Ã®n englezÄ sÄ se fi schimbat Ã®ntre timp. Ãn acest caz va fi prezentatÄ  traducerea curentÄ pentru a fi verificatÄ Åi actualizatÄ dacÄ este necesar.
+<p>
+Pentru a corecta o traducere, care a fost actualizatÄ deja, se foloseÅte facilitatea âCorectezÄ o traducere existentÄâ disponibilÄ pentru fiecare parte a Greenstone.
+<p>
+Fiecare paginÄ se Ã®ncheie cu un buton "_textgtisubmit_". CÃ¢nd este apÄsat, modificÄrile se fac imediat Ã®ntr-o instalare Greenstone separatÄ la nzdl.org. Ãn fiecare paginÄ existÄ un buton pentru a accesa acest site.
+}  
+
+_textgtiselecttlc_ [l=ro] {VÄ rugÄm, selectaÅ£i limba}  
+
+#for status page
+_textgtiviewstatus_ [l=ro] {ApÄsaÅ£i pentru a vedea  situaÅ£ia traducerilor actuale pentru toate limbile}  
+_textgtiviewstatusbutton_ [l=ro] {VEZI SITUAÅ¢IE}  
+_textgtistatustable_ [l=ro] {Lista situaÅ£iei traducerilor actuale pentru toate limbile}  
+_textgtilanguage_ [l=ro] {Limba}  
+_textgtitotalnumberoftranslations_ [l=ro] {NumÄrul total de traduceri}  
+
+_textgtiselecttfk_ [l=ro] {VÄ rugÄm, selectaÅ£i un fiÅier de lucru:}  
+
+_textgticoredm_ [l=ro] {InterfaÅ£a Greenstone (Nucleu)}  
+_textgtiauxdm_ [l=ro] {InterfaÅ£a Greenstone (AuxiliarÄ)}  
+_textgtiglidict_ [l=ro] {DicÅ£ionarul GLI}  
+_textgtiglihelp_ [l=ro] {AsistenÅ£a GLI}  
+_textgtiperlmodules_ [l=ro] {Module Perl}  
+_textgtitutorials_ [l=ro] {ExerciÅ£iile Tutorialului}  
+_textgtigreenorg_ [l=ro] {Greenstone.org}  
+_textgtigs3core_ [l=ro] {InterfaÅ£a Greenstone3 (Implicit)}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=ro] {Manualul Dezvoltatorului Greenstone}  
+_textgtiinstallmanual_ [l=ro] {Manualul de Instalare Greenstone}  
+_textgtipapermanual_ [l=ro] {Manualul Greenstone pentru ColecÅ£ia pe suport tradiÅ£ional (hÃ¢rtie)}  
+_textgtiusermanual_ [l=ro] {Manualul Utilizatorului Greenstone}  
+
+_textgtienter_ [l=ro] {ENTER}  
+
+_textgticorrectexistingtranslations_ [l=ro] {CorecteazÄ traducerile existente}  
+_textgtidownloadtargetfile_ [l=ro] {DownloadeazÄ fiÅierul}  
+_textgtiviewtargetfileinaction_ [l=ro] {ExperimenteazÄ acest fiÅier Ã®n acÅ£iune}  
+_textgtitranslatefileoffline_ [l=ro] {Tradu fiÅierul offline}  
+
+_textgtinumchunksmatchingquery_ [l=ro] {NumÄrul de fragmente de text care se potrivesc cÄutÄrii}  
+
+_textgtinumchunkstranslated_ [l=ro] {traduceri terminate}  
+_textgtinumchunksrequiringupdating_ [l=ro] {Dintre acestea _1_ necesitÄ actualizare}  
+_textgtinumchunksrequiringtranslation_ [l=ro] {Traduceri rÄmase de fÄcut}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=ro] {numÄrul traducerilor terminate}  
+_textgtinumchunksrequiringupdating2_ [l=ro] {numÄrul de traduceri necesitÄ actualizare}  
+_textgtinumchunksrequiringtranslation2_ [l=ro] {numÄrul traducerilor rÄmase de fÄcut}  
+
+_textgtienterquery_ [l=ro] {Introdu un cuvÃ¢nt sau o frazÄ din fragmentul de text pe care doreÅti sÄ-l corectezi}  
+_textgtifind_ [l=ro] {CAUTÄ}  
+
+_textgtitranslatingchunk_ [l=ro] {Traducerea fragmentului de text <i>_1_</i>}  
+_textgtiupdatingchunk_ [l=ro] {Actualizarea fragmentului de text <i>_1_</i>}  
+_textgtisubmit_ [l=ro] {INTRODU}  
+
+_textgtilastupdated_ [l=ro] {Ultima actualizare}  
+
+_textgtitranslationfilecomplete_ [l=ro] {VÄ mulÅ£umim pentru actualizarea acestui fiÅier - acum este complet ! <p> PuteÅ£i downloada o copie a acestui fiÅier folosind linkul de mai sus iar acesta va fi inclus Ã®n ediÅ£iile viitoare ale Greenstone}  
+
+_textgtiofflinetranslation_ [l=ro] {PoÅ£i traduce aceastÄ parte din Greenstone offline folosindu-se un fiÅier Microsoft Excel:
+
+<ol>
+<li>DownloadaÅ£i <a href="_gwcgi_?a=gti&p=excel&e=_compressedoptions_">acest fiÅier</a>.
+<li>DeschideÅ£i fiÅierul downloadat cu Microsoft Excel Åi salvaÅ£i-l ca format Microsoft Excel workbook (.xls).
+<li>IntroduceÅ£i traducerile Ã®n spaÅ£iile destinate.
+<li>CÃ¢nd aÅ£i terminat traducerea tuturor stringurilor trimiteÅ£i e-mail cu fiÅierul .xls ataÅat la <a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>.
+</ol>
+
+}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=ro] {interfaÅ£a bibliotecarului - Greenstone}  
+_textglihelp_ [l=ro] {<p>Greenstone Librarian Interface (GLI) - InterfaÅ£a Bibliotecarului vÄ oferÄ acces la funcÅ£ionalitÄÅ£ile Greenstone printr-o interfaÅ£Ä uÅor de utilizat 'point and click'. Aceasta permite colecatea unor seturi de documente, importul sau asignarea metadatelor Åi adÄugarea acestora Ã®n colecÅ£iile Greenstone.</p>
+
+<p>Trebuie remarcat cÄ GLI ruleazÄ conjugat cu sistemul Greenstone Åi se presupune cÄ este instalat Ã®ntr-un subdirector al instalÄrii Greenstone. DacÄ aÅ£i downloadat una din distribuÅ£iile Greenstone sau aÅ£i instalat Greenstone de pe CD-ROM, atunci trebuie cÄ GLI existÄ.</p>
+
+<h4>Rularea GLI sub Windows</h4>
+
+LansaÅ£i interfaÅ£a bibliotecarului sub Windows prin selectarea <i>Greenstone Digital Library</i> din secÅ£iunea <i>Programe</i> a meniului <i>Start</i> optÃ¢nd pentru <i>interfaÅ£a bibliotecarului</i>. 
+
+<h4>Rularea GLI sub Unix</h4>
+
+Pentru a rula GLI sub Unix, schimbaÅ£i directorul <i>gli</i> din instalarea Greenstone, apoi rulaÅ£i scriptul <i>gli.sh</i>. 
+
+<h4>Rularea GLI sub Mac OS X</h4>
+
+Ãn modulul de cÄutare, navigaÅ£i cÄtre <i>Applications</i> apoi <i>Greenstone</i> (dacÄ aÅ£i instalat Greenstone Ã®n lacaÅ£ia implictÄ) iar apoi lansaÅ£i aplicaÅ£ia<i>GLI</i>.}  
Index: /gsdl/stable/macros/russian.dm
===================================================================
--- /gsdl/stable/macros/russian.dm	(revision 20131)
+++ /gsdl/stable/macros/russian.dm	(revision 20131)
@@ -0,0 +1,787 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Russian Language text and icon macros 
+# Translated by UNESCO for the UNESCO CD-ROMs
+# Contributions made by Doug Carter, Sergei Korobitsin, Vyacheslav Bakharev and Sergey Karpov
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=ru] {ÐÐµÑÐžÐŸÐŽÐžÐºÐ°}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=ru] {ÐÑÑÐŸÑÐœÐžÐº: }
+_textdate_ [l=ru] {ÐÐ°ÑÐ° Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐž: }
+_textnumpages_ [l=ru] {ÐÐŸÐŒÐµÑ ÑÑÑÐ°ÐœÐžÑÑ}
+
+_textsignin_ [l=ru] {ÐÐ²ÑÐŸÑÐžÐ·ÐŸÐ²Ð°ÐœÐœÑÐ¹ Ð²Ñ
+ÐŸÐŽ}
+
+_textdefaultcontent_ [l=ru] {ÐÐ°Ð¿ÑÐ°ÑÐžÐ²Ð°ÐµÐŒÐ°Ñ ÑÑÑÐ°ÐœÐžÑÐ° ÐœÐµ ÐœÐ°Ð¹ÐŽÐµÐœÐ°. ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ° ÐœÐ°Ð¶ÐŒÐžÑÐµ ÐºÐœÐŸÐ¿ÐºÑ 'ÐÐ°Ð·Ð°ÐŽ' Ð² Ð²Ð°ÑÐµÐŒ Ð±ÑÐ°ÑÐ·ÐµÑÐµ ÐžÐ»Ðž ÑÑÑÐ»ÐºÑ ÐœÐ° ÐŽÐŸÐŒÐ°ÑÐœÑÑ ÑÑÑÐ°ÐœÐžÑÑ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž.}
+
+_textdefaulttitle_ [l=ru] {ÐÑÐžÐ±ÐºÐ° ÐÑÐžÐœÑÑÐŸÑÐœ}
+
+_textbadcollection_ [l=ru] {Ð­ÑÐ° ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ (Ñ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµÐŒ "_cvariable _") ÐœÐµ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐ° Ð² ÑÐžÑÑÐŸÐ²ÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐµ ÐÑÐžÐœÑÑÐŸÑÐœ.}
+
+_textselectpage_ [l=ru] {'ÐÑÐ±ÑÐ°ÑÑ ÑÑÑÐ°ÐœÐžÑÑ'}
+
+_collectionextra_ [l=ru] {ÐÐ°ÐœÐœÐ°Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÑÐŸÐŽÐµÑÐ¶ÐžÑ _about:numdocs_ ÐŽÐŸÐºÑÐŒÐµÐœÑ/ÐŸÐ². 
+ÐÐŸÑÐ»ÐµÐŽÐœÐžÐµ ÐžÐ·ÐŒÐµÐœÐµÐœÐžÑ Ð±ÑÐ»Ðž Ð¿ÑÐŸÐžÐ·Ð²ÐµÐŽÐµÐœÑ _about:builddate_ ÐŽÐœÐµÐ¹ ÐœÐ°Ð·Ð°ÐŽ.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=ru] {<p>Ð­ÑÐ° ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÑÐŸÐŽÐµÑÐ¶ÐžÑ _numdocs_ If_(â_numdocs_â eq â1â, ÐŽÐŸÐºÑÐŒÐµÐœÑ, ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ²), Ð²ÑÐµÐ³ÐŸ _numbytes_. 
+<p><a href=â_httppagex_(bsummary)â>ÐÐ°Ð¶ÐŒÐžÑÐµ ÑÑÐŽÐ°<\a> ÑÑÐŸÐ±Ñ Ð²ÐžÐŽÐµÑÑ ÐŸÑÑÐµÑ ÐŸ Ð¿ÑÐŸÑÐµÑÑÐµ ÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÐœÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.}  
+
+_textdescrcollection_ [l=ru] {}
+_textdescrabout_ [l=ru] {Ð Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐµ}
+_textdescrhome_ [l=ru] {ÐÐŸÐŒÐ°ÑÐœÑÑ ÑÑÑÐ°ÐœÐžÑÐ°}
+_textdescrhelp_ [l=ru] {Ð¡ÑÑÐ°ÐœÐžÑÐ° Ð¿ÐŸÐŒÐŸÑÐž}
+_textdescrpref_ [l=ru] {ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž}
+_textdescrgreenstone_ [l=ru] {Ð­Ð»ÐµÐºÑÑÐŸÐœÐœÐ°Ñ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ° ÐÑÐžÐœÑÑÐŸÑÐœ}
+_textdescrusab_ [l=ru] {ÐÐ°ÐºÐžÐµ Ð²ÐŸÐ·ÐœÐžÐºÐ»Ðž ÑÑÑÐŽÐœÐŸÑÑÐž Ð² ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐž?}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=ru] {ÐÐŸÐžÑÐº}  
+_labelSearch_ [l=ru] {ÐÐŸÐžÑÐº}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=ru] {ÐÐ°Ð³Ð»Ð°Ð²ÐžÐµ}  
+_labelTitle_ [l=ru] {ÐÐ°Ð·Ð²Ð°ÐœÐžÑ Ð-Ð¯}
+_textCreator_ [l=ru] {Ð¡ÐŸÐ·ÐŽÐ°ÑÐµÐ»Ñ}  
+_labelCreator_ [l=ru] {ÐÐ²ÑÐŸÑÑ Ð-Ð¯}
+_textSubject_ [l=ru] {Ð¢ÐµÐŒÐ°}  
+_labelSubject_ [l=ru] {Ð£ÐºÐ°Ð·Ð°ÑÐµÐ»Ñ}
+_textDescription_ [l=ru] {ÐÐ¿ÐžÑÐ°ÐœÐžÐµ}  
+_labelDescription_ [l=ru] {ÐŸÐ¿ÐžÑÐ°ÐœÐžÑ}
+_textPublisher_ [l=ru] {ÐÐ·ÐŽÐ°ÑÐµÐ»Ñ}  
+_labelPublisher_ [l=ru] {ÐÐ·ÐŽÐ°ÑÐµÐ»Ðž }
+_textContributor_ [l=ru] {ÐÐœÐŸÑÐžÑÐµÐ»Ñ}  
+_labelContributor_ [l=ru] {Ð£ÑÐ°ÑÑÐœÐžÐºÐž}
+_textDate_ [l=ru] {ÐÐ°ÑÐ°}  
+_labelDate_ [l=ru] {ÐÐ°ÑÑ}
+_textType_ [l=ru] {Ð¢ÐžÐ¿}  
+_labelType_ [l=ru] {Ð¢ÐžÐ¿Ñ}
+_textFormat_ [l=ru] {Ð€ÐŸÑÐŒÐ°Ñ}  
+_labelFormat_ [l=ru] {ÑÐŸÑÐŒÐ°ÑÑ}
+_textIdentifier_ [l=ru] {ÐÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑ}  
+_labelIdentifier_ [l=ru] {ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑÑ}
+_textSource_ [l=ru] {ÐÐŒÑ ÑÐ°Ð¹Ð»Ð°}  
+_labelSource_ [l=ru] {ÐÐŒÐµÐœÐ° ÑÐ°Ð¹Ð»ÐŸÐ²}
+_textLanguage_ [l=ru] {Ð¯Ð·ÑÐº}  
+_labelLanguage_ [l=ru] {Ð¯Ð·ÑÐºÐž}
+_textRelation_ [l=ru] {ÐÑÐœÐŸÑÐµÐœÐžÐµ}  
+_labelRelation_ [l=ru] {Ð¡Ð²ÑÐ·Ðž}
+_textCoverage_ [l=ru] {ÐÐŸÐºÑÑÑÐžÐµ}  
+_labelCoverage_ [l=ru] {ÐÑ
+Ð²Ð°Ñ}
+_textRights_ [l=ru] {ÐÑÐ°Ð²Ð°}  
+_labelRights_ [l=ru] {ÐÑÐ°Ð²Ð°}
+
+# DLS metadata set
+_textOrganization_ [l=ru] {ÐÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÑ}  
+_labelOrganization_ [l=ru] {ÐÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÐž}  
+_textKeyword_ [l=ru] {ÐÐ»ÑÑÐµÐ²ÐŸÐµ ÑÐ»ÐŸÐ²ÐŸ}  
+_labelKeyword_ [l=ru] {ÐÐ»ÑÑÐµÐ²ÑÐµ ÑÐ»ÐŸÐ²Ð°}
+_textHowto_ [l=ru] {ÐÐ°Ðº}  
+_labelHowto_ [l=ru] {ÐÐ°Ðº}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=ru] {Ð€ÑÐ°Ð·Ð°}  
+_labelPhrase_ [l=ru] {Ð€ÑÐ°Ð·Ñ}
+_textCollage_ [l=ru] {ÐÐŸÐ»Ð»Ð°Ð¶}  
+_labelCollage_ [l=ru] {ÐÐŸÐ»Ð»Ð°Ð¶}
+_textBrowse_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ}  
+_labelBrowse_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ}  
+_textTo_ [l=ru] {Ð}  
+_labelTo_ [l=ru] {ÐÐŸÐŒÑ}
+_textFrom_ [l=ru] {ÐÑ}  
+_labelFrom_ [l=ru] {ÐÑ ÐºÐŸÐ³ÐŸ}
+_textAcronym_ [l=ru] {Ð¡ÐŸÐºÑÐ°ÑÐµÐœÐžÐµ}  
+_labelAcronym_ [l=ru] {ÐÐºÑÐŸÐœÐžÐŒÑ}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ Ð¿ÐŸ _1_}  
+
+_textdescrSearch_ [l=ru] {ÐÐŸÐžÑÐº}
+_textdescrType_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ Ð¿ÐŸ ÑÐžÐ¿Ñ ÑÐµÑÑÑÑÐŸÐ²}
+_textdescrIdentifier_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ Ð¿ÑÐž Ð¿ÐŸÐŒÐŸÑÐž ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑÐ° ÑÐµÑÑÑÑÐŸÐ² }
+_textdescrSource_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ Ð¿ÐŸ ÐŸÑÐžÐ³ÐžÐœÐ°Ð»ÑÐœÐŸÐŒÑ ÐžÐŒÐµÐœÐž ÑÐ°Ð¹Ð»Ð°}
+_textdescrTo_ [l=ru] {ÐÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÐµ Ð¿ÐŸ Ð°ÐŽÑÐµÑÐ°ÑÐ°ÐŒ}
+_textdescrFrom_ [l=ru] {ÐÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÐµ Ð¿ÐŸ ÐŸÑÐ¿ÑÐ°Ð²ÐžÑÐµÐ»ÑÐŒ}
+_textdescrCollage_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ Ð¿ÐŸ ÐºÐŸÐ»Ð»Ð°Ð¶Ð°ÐŒ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹}
+_textdescrAcronym_ [l=ru] {ÐÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÐµ Ð¿ÐŸ Ð°ÐºÑÐŸÐœÐžÐŒÐ°ÐŒ}
+_textdescrPhrase_ [l=ru] {ÐÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÐµ Ð¿ÐŸ ÑÑÐ°Ð·Ð°ÐŒ}
+_textdescrHowto_ [l=ru] {ÐÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÐµ Ð¿ÐŸ ÑÐ¿ÐŸÑÐŸÐ±Ð°ÐŒ Ð¿ÑÐžÐŒÐµÐœÐµÐœÐžÑ}
+_textdescrBrowse_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ}
+_texticontext_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°}
+_texticonclosedbook_ [l=ru] {ÐÑÐºÑÑÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑ Ðž Ð¿ÑÐŸÑÐŒÐŸÑÑÐµÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ}
+_texticonnext_ [l=ru] {Ð¡Ð»ÐµÐŽÑÑÑÐ°Ñ}
+_texticonprev_ [l=ru] {ÐÑÐµÐŽÑÐŽÑÑÐ°Ñ}
+
+_texticonworld_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑÐµÑÑ Ð²ÐµÐ±-ÑÑÑÐ°ÐœÐžÑÑ}
+
+_texticonmidi_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° MIDI}
+_texticonmsword_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° Microsoft Word}
+_texticonmp3_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° MP3}
+_texticonpdf_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° ÐÐºÑÐŸÐ±Ð°Ñ PDF}
+_texticonps_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° PostScript}  
+_texticonppt_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° Ð¿ÑÐµÐ·ÐµÐœÑÐ°ÑÐžÐž PPT}
+_texticonrtf_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° RTF}  
+_texticonxls_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° Microsoft Excel}  
+
+_page_ [l=ru] {Ð¡ÑÑÐ°ÐœÐžÑÐ°}
+_pages_ [l=ru] {Ð¡ÑÑÐ°ÐœÐžÑÑ}
+_of_ [l=ru] {ÐžÐ· }
+_vol_ [l=ru] {Ð¢ÐŸÐŒ}
+_num_ [l=ru] {ÐÐŸÐŒÐµÑ}
+
+_textmonth00_ [l=ru] {}
+_textmonth01_ [l=ru] {Ð¯ÐœÐ²Ð°ÑÑ}
+_textmonth02_ [l=ru] {Ð€ÐµÐ²ÑÐ°Ð»Ñ}
+_textmonth03_ [l=ru] {ÐÐ°ÑÑ}
+_textmonth04_ [l=ru] {ÐÐ¿ÑÐµÐ»Ñ}
+_textmonth05_ [l=ru] {ÐÐ°Ð¹}
+_textmonth06_ [l=ru] {ÐÑÐœÑ}
+_textmonth07_ [l=ru] {ÐÑÐ»Ñ}
+_textmonth08_ [l=ru] {ÐÐ²Ð³ÑÑÑ}
+_textmonth09_ [l=ru] {Ð¡ÐµÐœÑÑÐ±ÑÑ}
+_textmonth10_ [l=ru] {ÐÐºÑÑÐ±ÑÑ}
+_textmonth11_ [l=ru] {ÐÐŸÑÐ±ÑÑ}
+_textmonth12_ [l=ru] {ÐÐµÐºÐ°Ð±ÑÑ}
+
+_texttext_ [l=ru] {Ð¢ÐµÐºÑÑ}  
+_labeltext_ {_texttext_}
+_textdocument_ [l=ru] {ÐÐŸÐºÑÐŒÐµÐœÑ}
+_textsection_ [l=ru] {Ð¡ÐµÐºÑÐžÑ}
+_textparagraph_ [l=ru] {ÐÐ±Ð·Ð°Ñ}
+_textchapter_ [l=ru] {ÐÐ»Ð°Ð²Ð°}  
+_textbook_ [l=ru] {ÐÐœÐžÐ³Ð°}  
+
+_magazines_ [l=ru] {ÐÑÑÐœÐ°Ð»Ñ}
+
+_nzdlpagefooter_ [l=ru] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">ÐÐŸÐ²ÐŸÐ·ÐµÐ»Ð°ÐœÐŽÑÐºÐžÐ¹ Ð¿ÑÐŸÐµÐºÑ ÐŠÐžÑÑÐŸÐ²ÐŸÐ¹ ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">ÐÑÐŽÐµÐ» ÐºÐŸÐ¿ÑÑÑÐµÑÐœÑÑ
+ ÐœÐ°ÑÐº</a>, 
+<a href="http://www.waikato.ac.nz">Ð£ÐœÐžÐ²ÐµÑÑÐžÑÐµÑ ÐÐ°Ð¹ÐºÐ°ÑÐŸ</a>, 
+ÐÐŸÐ²Ð°Ñ ÐÐµÐ»Ð°ÐœÐŽÐžÑ}
+
+_linktextHOME_ [l=ru] {ÐÐÐ§ÐÐÐ}
+_linktextHELP_ [l=ru] {ÐÐÐÐÐ©Ð¬}
+_linktextPREFERENCES_ [l=ru] {ÐÐÐ¡Ð¢Ð ÐÐÐÐ}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=ru] {Ð­Ð»ÐµÐºÑÑÐŸÐœÐœÐ°Ñ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ° Greenstone}  
+
+_textnocollections_ [l=ru] {ÐÐµ ÐŽÐŸÑÑÑÐ¿ÐœÐŸ ÐœÐž ÐŸÐŽÐœÐŸÐ¹ Ð¿ÐŸÐŽÑ
+ÐŸÐŽÑÑÐµÐ¹ (Ñ.Ðµ. ÑÐŸÐ±ÑÐ°ÐœÐœÐŸÐ¹ Ðž ÐŸÐ¿ÑÐ±Ð»ÐžÐºÐŸÐ²Ð°ÐœÐœÐŸÐ¹) ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž}  
+
+_textadmin_ [l=ru] {ÐÐŽÐŒÐžÐœÐžÑÑÑÐ°ÑÐžÐ²ÐœÐ°Ñ ÑÑÑÐ°ÐœÐžÑÐ°}
+_textabgs_ [l=ru] {Ð Greenstone}  
+_textgsdocs_ [l=ru] {ÐÐŸÐºÑÐŒÐµÐœÑÐ°ÑÐžÑ Greenstone}  
+
+_textdescradmin_ [l=ru] {ÐÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ ÐÐ°ÐŒ ÐŽÐŸÐ±Ð°Ð²Ð»ÑÑÑ ÐœÐŸÐ²ÑÑ
+ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐ¹,ÐŸÐ±ÑÐµÐŽÐžÐœÑÐµÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ð² ÑÐžÑÑÐµÐŒÑ, ÐŽÐ°ÐµÑ ÑÐµÑ
+ÐœÐžÑÐµÑÐºÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸÑÐœÐŸÑÐžÑÐµÐ»ÑÐœÐŸ ÐžÐœÑÑÐ°Ð»Ð»ÑÑÐžÐž Greenstone }  
+
+_textdescrgogreenstone_ [l=ru] {ÐÐ±ÑÑÑÐœÑÐµÑ ÐŸ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐŒ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐž Greenstone Ðž ÐÐŸÐ²ÐŸÐ·ÐµÐ»Ð°ÐœÐŽÑÐºÐŸÐŒ ÐÑÐŸÐµÐºÑÐµ ÐŠÐžÑÑÐŸÐ²ÐŸÐ¹ ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž, Ð³ÐŽÐµ ÐŸÐœÐŸ Ð±ÑÐ»ÐŸ ÑÐŸÐ·ÐŽÐ°ÐœÐŸ}  
+
+_textdescrgodocs_ [l=ru] {Ð ÑÐºÐŸÐ²ÐŸÐŽÑÑÐ²Ð° Greenstone}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=ru] {ÐÐžÐ±Ð»ÐžÐŸÑÐµÑÐœÑÐ¹ ÐžÐœÑÐµÑÑÐµÐ¹Ñ}
+_textdescrgli_ [l=ru] {ÐÐŸÐŒÐŸÑÑ Ð² ÑÐŸÐ·ÐŽÐ°ÐœÐžÐž ÐœÐŸÐ²ÑÑ
+ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹, Ð¿ÑÐµÐŸÐ±ÑÐ°Ð·ÐŸÐ²Ð°ÐœÐžÐž ÐžÐ»Ðž ÐŽÐŸÐ¿ÐŸÐ»ÐœÐµÐœÐžÐž ÑÑÑÐµÑÑÐ²ÑÑÑÐžÑ
+, ÐžÐ»Ðž ÑÐŽÐ°Ð»ÐµÐœÐžÐž }
+
+package collector
+
+_textcollector_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ}
+_textdescrcollector_ [l=ru] {Ð­ÑÐŸ Ð¿ÑÐµÐŽÑÐµÑÑÐ²ÐµÐœÐœÐžÐº ÐÐœÑÐµÑÑÐµÐ¹ÑÐ° ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ°ÑÑ, Ðž ÐŽÐ»Ñ Ð±ÐŸÐ»ÑÑÐžÐœÑÑÐ²Ð° Ð¿ÑÐ°ÐºÑÐžÑÐµÑÐºÐžÑ
+ ÑÐµÐ»ÐµÐ¹ ÐÐœÑÐµÑÑÐµÐ¹Ñ ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ°ÑÑ ÐŽÐŸÐ»Ð¶ÐµÐœ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑÑÑ Ð²ÐŒÐµÑÑÐŸ ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑÐ°.}
+
+package depositor
+
+_textdepositor_ [l=ru] {ÐÐµÐ¿ÐŸÐ·ÐžÑÐŸÑ}  
+_textdescrdepositor_ [l=ru] {ÐÐŸÐŒÐŸÐ³Ð°ÐµÑ ÐŽÐŸÐ±Ð°Ð²Ð»ÑÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ðº ÑÐ¶Ðµ ÑÑÑÐµÑÑÐ²ÑÑÑÐžÐŒ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŒ}  
+
+package gti
+
+_textgti_ [l=ru] {ÐÐœÑÐµÑÑÐµÐ¹Ñ ÐÐµÑÐµÐ²ÐŸÐŽÐ° Ð² Greenstone}  
+_textdescrtranslator_ [l=ru] {ÐÐŸÐŒÐŸÐ³Ð°ÐµÑ ÐÐ°ÐŒ Ð¿ÐŸÐŽÐµÑÐ¶ÐžÐ²Ð°ÑÑ ÑÐŸÐ²ÑÐµÐŒÐµÐœÐœÑÐµ ÐŒÐœÐŸÐ³ÐŸÑÐ·ÑÑÐœÑÐµ Ð²ÐµÑÑÐžÐž ÐžÐœÑÐµÑÑÐµÐ¹ÑÐ° Greenstone Ð² Ð°ÐºÑÑÐ°Ð»ÑÐœÐŸÐŒ ÑÐŸÑÑÐŸÑÐœÐžÐž }  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=ru] {ÐÐµÐŒÐœÐŸÐ³ÐŸ ÐŸ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž}
+
+_textsubcols1_ [l=ru] {<p>ÐÐ°ÐœÐœÐ°Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÑÐŸÐŽÐµÑÐ¶ÐžÑ _1_ Ð¿ÐŸÐŽÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹:
+<blockquote>}
+
+_textsubcols2_ [l=ru] {</blockquote>
+ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ Ð¿ÑÐŸÑÐŒÐŸÑÑÐµÑÑ/ÐžÐ·ÐŒÐµÐœÐžÑÑ ÑÐ¿ÐžÑÐŸÐº Ð¿ÐŸÐŽÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹, ÐºÐŸÑÐŸÑÑÐµ Ð²Ñ ÑÐµÐ¹ÑÐ°Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÐµ, ÐœÐ° ÑÑÑÐ°ÐœÐžÑÐµ ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž.}
+
+_titleabout_ [l=ru] {ÐŸÐ¿ÐžÑÐ°ÐœÐžÐµ}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=ru] {ÐÐ°ÐºÑÑÑÑ ÑÐµÐºÑÐžÑ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž}
+_texticonclosedbookshelf_ [l=ru] {ÐÑÐºÑÑÑÑ ÑÐµÐºÑÐžÑ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž Ðž Ð¿ÑÐŸÑÐŒÐŸÑÑÐµÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ}
+_texticonopenbook_ [l=ru] {ÐÐ°ÐºÑÑÑÑ ÐºÐœÐžÐ³Ñ}
+_texticonclosedfolder_ [l=ru] {ÐÑÐºÑÑÑÑ Ð¿Ð°Ð¿ÐºÑ Ðž Ð¿ÑÐŸÑÐŒÐŸÑÑÐµÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ}
+_texticonclosedfolder2_ [l=ru] {ÐÑÐºÑÑÑÑ Ð¿ÐŸÐŽÑÐµÐºÑÐžÑ: }
+_texticonopenfolder_ [l=ru] {ÐÐ°ÐºÑÑÑÑ Ð¿Ð°Ð¿ÐºÑ}
+_texticonopenfolder2_ [l=ru] {ÐÐ°ÐºÑÑÑÑ Ð¿ÐŸÐŽÑÐµÐºÑÐžÑ: }
+_texticonsmalltext_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ ÑÐµÐºÑÐžÐž ÑÐµÐºÑÑÐ°}
+_texticonsmalltext2_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑ ÑÐµÐºÑÑÐ°: }
+_texticonpointer_ [l=ru] {Ð¢ÐµÐºÑÑÐ°Ñ ÑÐµÐºÑÐžÑ}
+_texticondetach_ [l=ru] {ÐÑÐºÑÑÑÑ ÑÑÑÐ°ÐœÐžÑÑ Ð² ÐœÐŸÐ²ÐŸÐŒ ÐŸÐºÐœÐµ}
+_texticonhighlight_ [l=ru] {ÐÑÐŽÐµÐ»ÐžÑÑ ÐžÑÐºÐŸÐŒÑÐµ ÑÐµÑÐŒÐžÐœÑ}
+_texticonnohighlight_ [l=ru] {ÐÐµ Ð²ÑÐŽÐµÐ»ÑÑÑ ÐžÑÐºÐŸÐŒÑÐµ ÑÐµÑÐŒÐžÐœÑ}
+_texticoncontracttoc_ [l=ru] {Ð¡Ð²ÐµÑÐœÑÑÑ ÐŸÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÐµ }
+_texticonexpandtoc_ [l=ru] {Ð Ð°ÑÐºÑÑÑÑ Ð²ÑÐµ ÐŸÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÐµ}
+_texticonexpandtext_ [l=ru] {ÐÐŸÐºÐ°Ð·Ð°ÑÑ Ð²ÐµÑÑ ÑÐµÐºÑÑ}
+_texticoncontracttext_ [l=ru] {ÐÐŸÐºÐ°Ð·Ð°ÑÑ ÑÐµÐºÑÑ ÑÐŸÐ»ÑÐºÐŸ ÐŽÐ»Ñ Ð²ÑÐŽÐµÐ»ÐµÐœÐœÑÑ
+ ÑÐµÐºÑÐžÐ¹}
+_texticonwarning_ [l=ru] {<b>ÐÐœÐžÐŒÐ°ÐœÐžÐµ: </b>}
+_texticoncont_ [l=ru] {Ð¿ÑÐŸÐŽÐŸÐ»Ð¶ÐžÑÑ?}
+
+_textltwarning_ [l=ru] {<div class="buttons">_imagecont_</div>
+_iconwarning_ ÐÑÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐµ Ð²ÑÐµÐ³ÐŸ ÑÐµÐºÑÑÐ° Ð¿ÑÐžÐ²ÐµÐŽÐµÑ Ðº ÑÐ²ÐµÐ»ÐžÑÐµÐœÐžÑ  ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž ÐŽÐ»Ñ ÐŸÑÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ Ð² Ð±ÑÐ°ÑÐ·ÐµÑÐµ
+}
+
+_textgoto_ [l=ru] {Ð¿ÐµÑÐµÐ¹ÑÐž ÐœÐ° ÑÑÑÐ°ÐœÐžÑÑ}
+_textintro_ [l=ru] {<i>(Ð²Ð²ÐµÐŽÐµÐœÐžÐµ)</i>}
+
+_textCONTINUE_ [l=ru] {ÐÐ ÐÐÐÐÐÐÐ¢Ð¬??}
+
+_textEXPANDTEXT_ [l=ru] {ÐÐÐ¡Ð¬\nÐ¢ÐÐÐ¡Ð¢}
+
+_textCONTRACTCONTENTS_ [l=ru] {Ð¡ÐÐÐ ÐÐ£Ð¢Ð¬ Ð¡ÐÐÐÐ ÐÐÐÐÐ}  
+
+_textDETACH_ [l=ru] {ÐÐÐÐÐ\nÐÐÐÐ}
+
+_textEXPANDCONTENTS_ [l=ru] {Ð ÐÐ¡ÐÐ Ð«Ð¢Ð¬ Ð¡ÐÐÐÐ ÐÐÐÐÐ}  
+
+_textCONTRACT_ [l=ru] {Ð¡ÐÐÐ ÐÐ£Ð¢Ð¬ Ð¢ÐÐÐ¡Ð¢}  
+
+_textHIGHLIGHT_ [l=ru] {ÐÐ«ÐÐÐÐÐ¢Ð¬}
+
+_textNOHIGHLIGHT_ [l=ru] {Ð¡ÐÐ¯Ð¢Ð¬}
+
+_textPRINT_ [l=ru] {ÐÐÐÐÐ§ÐÐ¢ÐÐ¢Ð¬}  
+
+_textnextsearchresult_ [l=ru] {ÑÐ»ÐµÐŽÑÑÑÐžÐ¹ ÑÐµÐ·ÑÐ»ÑÑÐ°Ñ Ð¿ÐŸÐžÑÐºÐ°}  
+_textprevsearchresult_ [l=ru] {Ð¿ÑÐµÐŽÑÐŽÑÑÐžÐ¹ ÑÐµÐ·ÑÐ»ÑÑÐ°Ñ Ð¿ÐŸÐžÑÐºÐ°}  
+
+# macros for printing page
+_textreturnoriginal_ [l=ru] {ÐÐŸÐ·Ð²ÑÐ°ÑÐžÑÑÑÑ Ðº ÐŸÑÐžÐ³ÐžÐœÐ°Ð»ÑÐœÐŸÐ¹ ÑÑÑÐ°ÐœÐžÑÐµ}  
+_textprintpage_ [l=ru] {ÐÐ°Ð¿ÐµÑÐ°ÑÐ°ÑÑ ÑÑÑ ÑÑÑÐ°ÐœÐžÑÑ}  
+_textshowcontents_ [l=ru] {ÐÐŸÐºÐ°Ð·Ð°ÑÑ ÐŸÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÐµ}  
+_texthidecontents_ [l=ru] {Ð¡ÐºÑÑÑÑ ÐŸÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÐµ}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=ru] {_If_(_thislast_,ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÑ _thisfirst_ - _thislast_ Ð¿ÐŸÐžÑÐºÐ° Ð¿ÐŸ Ð·Ð°Ð¿ÑÐŸÑÑ: _cgiargq_,ÐÐžÑÐµÐ³ÐŸ ÐœÐµ ÐœÐ°Ð¹ÐŽÐµÐœÐŸ Ð¿ÐŸ Ð·Ð°Ð¿ÑÐŸÑÑ: _cgiargq_)}
+_textnoquerytitle_ [l=ru] {Ð¡ÑÑÐ°ÐœÐžÑÐ° Ð¿ÐŸÐŒÐŸÑÐž}
+
+_textsome_ [l=ru] {ÐœÐµÐºÐŸÑÐŸÑÑÐµ}
+_textall_ [l=ru] {Ð²ÑÐµ}
+_textboolean_ [l=ru] {Ð»ÐŸÐ³ÐžÑÐµÑÐºÐžÐ¹}
+_textranked_ [l=ru] {ÑÐ¿ÐŸÑÑÐŽÐŸÑÐµÐœÐœÑÐ¹}
+_textnatural_ [l=ru] {ÐŸÐ±ÑÑÐœÑÐ¹}
+_textsortbyrank_ [l=ru] {ÑÐ°ÐœÐ³ ÑÐµÐ»ÐµÐ²Ð°ÐœÑÐœÐŸÑÑÐž}  
+_texticonsearchhistorybar_ [l=ru] {ÐÑÑÐŸÑÐžÑ Ð¿ÐŸÐžÑÐºÐ°}
+
+_textifeellucky_ [l=ru] {Ð¯ ÑÑÐ²ÑÑÐ²ÑÑ ÑÐŽÐ°ÑÑ!}
+
+#alt text for query buttons
+_textusequery_ [l=ru] {ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÐŽÐ°ÐœÐœÑÐ¹ Ð·Ð°Ð¿ÑÐŸÑ}
+_textfreqmsg1_ [l=ru] {ÐÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ Ð²Ñ
+ÐŸÐ¶ÐŽÐµÐœÐžÐ¹: }
+_textpostprocess_ [l=ru] {_If_(_quotedquery_,<br><i>ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÐœÐŸ ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ° _quotedquery_</i>
+)}
+_textinvalidquery_ [l=ru] {ÐÐµÐ¿ÑÐ°Ð²ÐžÐ»ÑÐœÑÐ¹ ÑÐžÐœÑÐ°ÐºÑÐžÑ Ð²ÐŸÐ¿ÑÐŸÑÐ°}
+_textstopwordsmsg_ [l=ru] {Ð¡Ð»ÐµÐŽÑÑÑÐžÐµ ÑÐ»ÐŸÐ²Ð° Ð²ÑÑÑÐµÑÐ°ÑÑÑÑ ÑÐ»ÐžÑÐºÐŸÐŒ ÑÐ°ÑÑÐŸ Ðž Ð¿ÐŸÑÑÐŸÐŒÑ Ð±ÑÐ»Ðž ÐŸÐ¿ÑÑÐµÐœÑ:}  
+_textlucenetoomanyclauses_ [l=ru] {ÐÐ°Ñ Ð·Ð°Ð¿ÑÐŸÑ ÑÐŸÐŽÐµÑÐ¶ÐžÑ ÑÐ»ÐžÑÐºÐŸÐŒ ÐŒÐœÐŸÐ³ÐŸ Ð¿ÑÐœÐºÑÐŸÐ²; Ð¿ÐŸÑÑÐ°ÑÐ°Ð¹ÑÐµÑÑ ÑÐŽÐµÐ»Ð°ÑÑ Ð±ÐŸÐ»ÐµÐµ ÑÐ¿ÐµÑÐžÑÐžÑÐœÑÐ¹ Ð·Ð°Ð¿ÑÐŸÑ.}  
+
+_textmorethan_ [l=ru] {ÐÐŸÐ»ÑÑÐµ ÑÐµÐŒ}
+_textapprox_ [l=ru] {ÐÐºÐŸÐ»ÐŸ}
+_textnodocs_ [l=ru] {ÐÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÑÐŽÐŸÐ²Ð»ÐµÑÐ²ÐŸÑÑÑÑÐžÑ
+ Ð·Ð°Ð¿ÑÐŸÑÑ ÐœÐµ ÐœÐ°Ð¹ÐŽÐµÐœÐŸ.}
+_text1doc_ [l=ru] {1 ÐŽÐŸÐºÑÐŒÐµÐœÑ ÑÐŽÐŸÐ²Ð»ÐµÑÐ²ÐŸÑÑÐµÑ Ð·Ð°Ð¿ÑÐŸÑÑ.}
+_textlotsdocs_ [l=ru] {ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÑÐŽÐŸÐ²Ð»ÐµÑÐ²ÐŸÑÑÑÑÐžÑ
+ Ð·Ð°Ð¿ÑÐŸÑÑ.}
+_textmatches_ [l=ru] {Ð ÐµÐ·ÑÐ»ÑÑÐ°ÑÑ }
+_textbeginsearch_ [l=ru] {ÐÐ°ÑÐ°ÑÑ Ð¿ÐŸÐžÑÐº}
+_textrunquery_ [l=ru] {ÐÑÐ¿ÐŸÐ»ÐœÐžÑÑ Ð·Ð°Ð¿ÑÐŸÑ}  
+_textclearform_ [l=ru] {ÐÑÐžÑÑÐžÑÑ ÑÐŸÑÐŒÑ}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=ru] {Ð¡Ð»ÐŸÐ²ÐŸ ÐžÐ»Ðž ÑÑÐ°Ð·Ð°
+}  
+_textinfield_ [l=ru] {... Ð² Ð¿ÐŸÐ»Ðµ}  
+_textfoldstem_ [l=ru] {(ÑÑÑÐŸÑÐœÑÐŒÐž, ÐºÐŸÑÐµÐœÑ)}  
+
+_textadvquery_ [l=ru] {ÐžÐ»Ðž Ð²Ð²ÐµÐŽÐžÑÐµ ÑÐµÐºÑÑ Ð·Ð°Ð¿ÑÐŸÑÐ° ÐœÐ°Ð¿ÑÑÐŒÑÑ:}  
+_textallfields_ [l=ru] {Ð²ÑÐµ Ð¿ÐŸÐ»Ñ}  
+_texttextonly_ [l=ru] {ÑÐŸÐ»ÑÐºÐŸ ÑÐµÐºÑÑ
+}
+_textand_ [l=ru] {Ðž}  
+_textor_ [l=ru] {ÐžÐ»Ðž}  
+_textandnot_ [l=ru] {Ðž ÐœÐµ}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+# the space after "level" (before the right bracket) is required, otherwise no space between "Search" and "in"
+
+_textsimplesearch_ [l=ru] {ÐÐŸÐžÑÐº Ð¿ÐŸ _indexselection_ _If_(_jselection_,ÐžÐ· _jselection_ )_If_(_gselection_, ÐœÐ° ÑÑÐŸÐ²ÐœÐµ _gselection_ )_If_(_nselection_, ÑÐ·ÑÐº: _nselection_ ), Ðž ÑÐŸÐŽÐµÑÐ¶Ð°Ñ ÑÐ»ÐŸÐ²Ð° _querytypeselection_
+}  
+
+_textadvancedsearch_ [l=ru] {ÐÐŸÐžÑÐº Ð¿ÐŸ _indexselection__If_(_jselection_, Ð°ÑÑÐŸÑÐžÐžÑÐŸÐ²Ð°Ðœ Ñ _jselection_)_If_(_gselection_, ÐœÐ° ÑÑÐŸÐ²ÐœÐµ _gselection_ )_If_(_nselection_, ÑÐ·ÑÐº: _nselection_)  ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ Ð·Ð°Ð¿ÑÐŸÑ _querytypeselection_ }  
+
+_textadvancedmgppsearch_ [l=ru] {ÐÐŸÐžÑÐº Ð¿ÐŸ _indexselection__If_(_jselection_,ÑÐ²ÑÐ·Ð°ÑÑ Ñ _jselection_ )_If_(_gselection_,ÑÑÐŸÐ²ÐµÐœÑ _gselection_ )_If_(_nselection_,ÑÐ·ÑÐº: _nselection_ ) Ðž Ð¿ÑÐµÐŽÑÑÐ°Ð²ÐžÑÑ ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÑ Ð² Ð¿ÐŸÑÑÐŽÐºÐµ _formquerytypeadvancedselection_}  
+
+_textadvancedlucenesearch_ [l=ru] {ÐÐŸÐžÑÐº Ð² _indexselection__If_(_jselection_, ÑÐ²ÑÐ·Ð°ÑÑ Ñ _jselection_)_If_(_gselection_, ÑÑÐŸÐ²ÐµÐœÑ _gselection_)_If_(_nselection_, ÑÐ·ÑÐº: _nselection_ )_If_(_sfselection_,\,_allowformbreak_ Ðž ÐŸÑÑÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÑ Ð¿ÐŸ _sfselection_\,) ÐŽÐ»Ñ}  
+
+# the space after "Search" is required, otherwise no space between "Search" and "in"
+
+_textformsimplesearch_ [l=ru] {ÐÐŸÐžÑÐº Ð¿ÐŸ _If_(_jselection_, _jselection_) _If_(_gformselection_, ÐœÐ° ÑÑÐŸÐ²ÐœÐµ _gformselection_ ) _If_(_nselection_, ÑÐ·ÑÐº: _nselection_ ),Ð³ÐŽÐµ ÑÐŸÐŽÐµÑÐ¶ÐžÑÑÑ _formquerytypesimpleselection_ }  
+
+_textformadvancedsearchmgpp_ [l=ru] {ÐÐŸÐžÑÐº Ð¿ÐŸ _If_(_jselection_,_jselection_ )_If_(_gformselection_, ÐœÐ° ÑÑÐŸÐ²ÐœÐµ _gformselection_ )_If_(_nselection_, ÑÐ·ÑÐº: _nselection_ ), Ðž Ð¿ÑÐµÐŽÑÑÐ°Ð²ÐžÑÑ ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÑ Ð² Ð¿ÐŸÑÑÐŽÐºÐµ _formquerytypeadvancedselection_}  
+
+_textformadvancedsearchlucene_ [l=ru] {ÐÐŸÐžÑÐº Ð¿ÐŸ _If_(_jselection_, Ð¿ÐŸ _jselection_)_If_(_gformselection_, ÐœÐ° ÑÑÐŸÐ²ÐœÐµ _gformselection_ )_If_(_nselection_, ÑÐ·ÑÐº: _nselection_ )_If_(_sfselection_,\, ÐŸÑÑÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÑ Ð¿ÐŸ _sfselection_\,) ÐŽÐ»Ñ}  
+
+_textnojsformwarning_ [l=ru] {ÐÑÐµÐŽÑÐ¿ÑÐµÐ¶ÐŽÐµÐœÐžÐµ: Javascript Ð¿ÐŸÐ²ÑÐµÐ¶ÐŽÐµÐœ ÐœÐ° ÐÐ°ÑÐµÐŒ Ð²ÐµÐ±-Ð±ÑÐ°ÑÐ·ÐµÑÐµ. <br>Ð§ÑÐŸÐ±Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÑÐŸÑÐŒÑ Ð¿ÐŸÐžÑÐºÐ°, Ð¿ÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ°, ÑÐ°Ð·ÑÐµÑÐžÑÐµ ÑÑÐŸ.}
+_textdatesearch_ [l=ru] {ÐÐŸÐžÑÐº ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ð¿ÐŸ ÐŽÐ°ÐœÐœÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐŒÐŸÐ¶ÐµÑ ÐŸÑÑÑÐµÑÑÐ²Ð»ÑÑÑÑÑ ÐºÐ°Ðº Ð¿ÐŸ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÐŸÐŒÑ Ð²ÑÐµÐŒÐµÐœÐœÐŸÐŒÑ ÐžÐœÑÐµÑÐ²Ð°Ð»Ñ, ÑÐ°Ðº Ðž Ð¿ÐŸ ÐºÐŸÐœÐºÑÐµÑÐœÐŸÐ¹ ÑÐžÑÐ»ÐŸÐ²ÐŸÐ¹ ÐŽÐ°ÑÐµ.}
+_textstartdate_ [l=ru] {ÐÐ°ÑÐ°Ð»ÑÐœÐ°Ñ (ÐžÐ»Ðž ÐºÐŸÐœÐºÑÐµÑÐœÐ°Ñ) ÐŽÐ°ÑÐ°:}
+_textenddate_ [l=ru] {ÐÐŸÐœÐµÑÐœÐ°Ñ ÐŽÐ°ÑÐ°:}
+_textbc_ [l=ru] {ÐŽÐŸ Ðœ.Ñ.}
+_textad_ [l=ru] {Ðœ.Ñ.}
+_textexplaineras_ [l=ru] {Ð¢ÐµÑÐŒÐžÐœÑ Ð.Ð­. Ðž ÐÐŸ Ð.Ð­. ÐŸÐ±ÐŸÐ·ÐœÐ°ÑÐ°ÑÑ "ÐÐ°ÑÐµÐ¹ ÑÑÑ" Ðž "ÐÐŸ ÐœÐ°ÑÐµÐ¹ ÑÑÑ".}  
+
+_textstemon_ [l=ru] {(ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÑÑ ÐŸÐºÐŸÐœÑÐ°ÐœÐžÑ ÑÐ»ÐŸÐ²)}
+
+_textsearchhistory_ [l=ru] {ÐÑÑÐŸÑÐžÑ Ð·Ð°Ð¿ÑÐŸÑÐ°}
+
+#text macros for search history
+_textnohistory_ [l=ru] {Ð ÐŽÐ°ÐœÐœÑÐ¹ ÐŒÐŸÐŒÐµÐœÑ ÐœÐµ ÑÑÑÐµÑÑÐ²ÑÐµÑ ÐžÑÑÐŸÑÐžÐž Ð·Ð°Ð¿ÑÐŸÑÐ°}  
+_texthresult_ [l=ru] {Ð²Ñ
+ÐŸÐ¶ÐŽÐµÐœÐžÐµ}
+_texthresults_ [l=ru] {Ð²Ñ
+ÐŸÐ¶ÐŽÐµÐœÐžÐ¹}
+_texthallwords_ [l=ru] {Ð²ÑÐµ ÑÐ»ÐŸÐ²Ð°}
+_texthsomewords_ [l=ru] {ÐœÐµÐºÐŸÑÐŸÑÑÐµ ÑÐ»ÐŸÐ²Ð°}
+_texthboolean_ [l=ru] {Ð»ÐŸÐ³ÐžÑÐµÑÐºÐžÐ¹}
+_texthranked_ [l=ru] {ÑÐ¿ÐŸÑÑÐŽÐŸÑÐµÐœÐœÑÐ¹}
+_texthcaseon_ [l=ru] {Ñ ÑÑÐµÑÐŸÐŒ ÑÐµÐ³ÐžÑÑÑÐ°}
+_texthcaseoff_ [l=ru] {Ð±ÐµÐ· ÑÑÐµÑÐ° ÑÐµÐ³ÐžÑÑÑÐ°}
+_texthstemon_ [l=ru] {Ñ ÐŸÐºÐŸÐœÑÐ°ÐœÐžÑÐŒÐž}
+_texthstemoff_ [l=ru] {Ð±ÐµÐ· ÐŸÐºÐŸÐœÑÐ°ÐœÐžÐ¹}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=ru] {ÐÑÐµÐŽÐ¿ÐŸÑÑÐµÐœÐžÑ Ð±ÑÐ»Ðž ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÑ ÑÐ»ÐµÐŽÑÑÑÐžÐŒ ÐŸÐ±ÑÐ°Ð·ÐŸÐŒ. ÐÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ ÐºÐœÐŸÐ¿ÐºÑ "ÐœÐ°Ð·Ð°ÐŽ" Ð²Ð°ÑÐµÐ³ÐŸ Ð±ÑÐ°ÑÐ·ÐµÑÐ° - Ð¿ÑÐŸÐžÐ·ÐŸÐ¹ÐŽÐµÑ ÑÐ±ÑÐŸÑ! ÐÐŒÐµÑÑÐŸ ÑÑÐŸÐ³ÐŸ ÑÐµÐ»ÐºÐœÐžÑÐµ ÐŸÐŽÐœÑ ÐžÐ· ÐºÐœÐŸÐ¿ÐŸÐº ÐœÐ°ÐŽ Ð»ÐžÐœÐµÐ¹ÐºÐŸÐ¹ ÐŽÐŸÑÑÑÐ¿Ð°.}
+_textsetprefs_ [l=ru] {ÑÑÑÐ°ÐœÐŸÐ²ÐžÑÑ Ð¿ÑÐµÐŽÐ¿ÐŸÑÑÐµÐœÐžÑ}
+_textsearchprefs_ [l=ru] {ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž Ð¿ÐŸÐžÑÐºÐ°}
+_textcollectionprefs_ [l=ru] {ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž}
+_textpresentationprefs_ [l=ru] {ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž ÐžÐœÑÐµÑÑÐµÐ¹ÑÐ°}
+_textpreferences_ [l=ru] {ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž}
+_textcasediffs_ [l=ru] {Ð ÐµÐ³ÐžÑÑÑÑ:}
+_textignorecase_ [l=ru] {ÐžÐ³ÐœÐŸÐžÑÐŸÐ²Ð°ÑÑ ÑÐµÐ³ÐžÑÑÑÑ}  
+_textmatchcase_ [l=ru] {ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ Ð²ÐµÑÑ
+ÐœÐžÐ¹ Ðž ÐœÐžÐ¶ÐœÐžÐ¹ ÑÐµÐ³ÐžÑÑÑÑ }  
+_textwordends_ [l=ru] {ÐÐºÐŸÐœÑÐ°ÐœÐžÑ ÑÐ»ÐŸÐ²:}  
+_textstem_ [l=ru] {ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÑÑ ÐŸÐºÐŸÐœÑÐ°ÐœÐžÑ ÑÐ»ÐŸÐ²}  
+_textnostem_ [l=ru] {ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÑÐ»ÐŸÐ²Ð° Ñ ÐŸÐºÐŸÐœÑÐ°ÐœÐžÐµÐŒ}  
+_textaccentdiffs_ [l=ru] {ÐÐŸÐºÐ°Ð·Ð°ÑÑ ÐŸÑÐ»ÐžÑÐžÑ}  
+_textignoreaccents_ [l=ru] {ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÑÑ Ð°ÐºÑÐµÐœÑÑ}  
+_textmatchaccents_ [l=ru] {ÐœÐµ ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÑÑ Ð°ÐºÑÐµÐœÑÑ}  
+
+_textprefop_ [l=ru] {ÐÐŸÐºÐ°Ð·ÑÐ²Ð°ÑÑ _maxdocoption_ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² - ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÐŸÐ² Ð¿ÐŸÐžÑÐºÐ°, Ð¿ÐŸ  _hitsperpageoption_ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÐœÐ° ÑÑÑÐ°ÐœÐžÑÐµ.}
+_textextlink_ [l=ru] {ÐÐŸÑÑÑÐ¿ Ðº Ð²ÐœÐµÑÐœÐžÐŒ ÑÐ·Ð»Ð°ÐŒ Web:}
+_textintlink_ [l=ru] {ÐÐ°ÐœÐœÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð²Ð·ÑÑ ÐžÐ·:}
+_textlanguage_ [l=ru] {Ð¯Ð·ÑÐº ÐžÐœÑÐµÑÑÐµÐ¹ÑÐ°:}
+_textencoding_ [l=ru] {ÐÐŸÐŽÐžÑÐŸÐ²ÐºÐ°:}
+_textformat_ [l=ru] {Ð€ÐŸÑÐŒÐ°Ñ ÐžÐœÑÐµÑÑÐµÐ¹ÑÐ°:}
+_textall_ [l=ru] {Ð²ÑÐµ}
+_textquerymode_ [l=ru] {Ð¢ÐžÐ¿ Ð·Ð°Ð¿ÑÐŸÑÐ°:}  
+_textsimplemode_ [l=ru] {Ð¿ÑÐŸÑÑÐ°Ñ ÑÐŸÑÐŒÐ° Ð·Ð°Ð¿ÑÐŸÑÐ°}  
+_textadvancedmode_ [l=ru] {ÑÐ°ÑÑÐžÑÐµÐœÐœÐ°Ñ ÑÐŸÑÐŒÐ° Ð·Ð°Ð¿ÑÐŸÑÐ°(ÑÐ°Ð·ÑÐµÑÐµÐœ Ð»ÐŸÐ³ÐžÑÐµÑÐºÐžÐ¹ Ð¿ÐŸÐžÑÐº Ñ ÐŸÐ¿ÐµÑÐ°ÑÐžÑÐŒÐž ! (ÐÐ) , & (Ð), | (ÐÐÐ) , Ðž ÑÐºÐŸÐ±ÐºÐž)}  
+_textlinkinterm_ [l=ru] {ÑÐµÑÐµÐ· Ð¿ÑÐŸÐŒÐµÐ¶ÑÑÐŸÑÐœÑÑ ÑÑÑÐ°ÐœÐžÑÑ}
+_textlinkdirect_ [l=ru] {Ð¿ÐµÑÐµÐ¹ÑÐž ÐœÐµÐ¿ÐŸÑÑÐµÐŽÑÑÐ²ÐµÐœÐœÐŸ Ðº}
+_textdigitlib_ [l=ru] {ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐ°Ñ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ°}
+_textweb_ [l=ru] {Web}
+_textgraphical_ [l=ru] {ÐÑÐ°ÑÐžÑÐµÑÐºÐžÐ¹}
+_texttextual_ [l=ru] {TÐµÐºÑÑÐŸÐ²ÑÐ¹}
+_textcollectionoption_ [l=ru] {<p> ÐÐŸÐŽÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐŽÐ»Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ: <br>}
+
+_textsearchtype_ [l=ru] {Ð¡ÑÐžÐ»Ñ Ð·Ð°Ð¿ÑÐŸÑÐŸÐ²:}  
+_textformsearchtype_ [l=ru] {Ð¿ÐŸÐ»Ñ Ñ Ð¿ÐŸÐŒÐµÑÐºÐŸÐ¹ _formnumfieldoption_}  
+_textplainsearchtype_ [l=ru] {ÐœÐŸÑÐŒÐ°Ð»ÑÐœÑÐ¹ ÐŽÐžÐ°Ð»ÐŸÐ³ Ð·Ð°Ð¿ÑÐŸÐŸÐ² Ñ ÐŸÐ¿ÑÐžÐµÐ¹ _boxsizeoption_}  
+_textregularbox_ [l=ru] {ÐŸÐŽÐœÐ° ÑÑÑÐŸÐºÐ°}  
+_textlargebox_ [l=ru] {Ð±ÐŸÐ»ÑÑÐŸÐ¹}  
+
+_textrelateddocdisplay_ [l=ru] {ÐŸÑÐŸÐ±ÑÐ°Ð¶Ð°ÑÑ ÑÑ
+ÐŸÐ¶ÐžÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ }
+_textsearchhistory_ [l=ru] {ÐÑÑÐŸÑÐžÑ Ð·Ð°Ð¿ÑÐŸÑÐŸÐ²:}  
+_textnohistory_ [l=ru] {ÐÐžÐºÐ°ÐºÐŸÐ¹ ÐžÑÑÐŸÑÐžÐž Ð¿ÐŸÐžÑÐºÐ°}  
+_texthistorydisplay_ [l=ru] {ÐŸÑÐŸÐ±ÑÐ°Ð¶Ð°ÑÑ _historynumrecords_ ÐžÑÑÐŸÑÐžÑ Ð·Ð°Ð¿ÑÐŸÑÐ°}  
+_textnohistorydisplay_ [l=ru] {ÐœÐµ Ð¿ÐŸÐºÐ°Ð·ÑÐ²Ð°ÑÑ ÐžÑÑÐŸÑÐžÑ Ð·Ð°Ð¿ÑÐŸÑÐ°}  
+
+_textbookoption_ [l=ru] {Ð ÐµÐ¶ÐžÐŒ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° ÐºÐœÐžÐ³Ðž}  
+_textbookvieweron_ [l=ru] {Ð²ÐºÐ»ÑÑÐµÐœ}  
+_textbookvieweroff_ [l=ru] {Ð²ÑÐºÐ»ÑÑÐµÐœ}  
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=ru] {Ð¡ÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð¿ÐŸ}
+_textalsoshowing_ [l=ru] {ÑÐ°ÐºÐ¶Ðµ Ð¿ÐŸÐºÐ°Ð·ÑÐ²Ð°ÑÑ}
+_textwith_ [l=ru] {Ñ ÑÐ°ÐŒÑÐŒ Ð±ÐŸÐ»ÑÑÐžÐŒ}
+_textdocsperpage_ [l=ru] {ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÐœÐ° ÑÑÑÐ°ÐœÐžÑÐµ}
+
+_textfilterby_ [l=ru] {ÐÐŸÐ»ÑÑÐžÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ, ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐžÐµ}
+_textall_ [l=ru] {Ð²ÑÐµ}
+_textany_ [l=ru] {Ð»ÑÐ±ÐŸÐ¹}
+_textwords_ [l=ru] {ÐžÐ· ÑÐ»ÐŸÐ²}
+_textleaveblank_ [l=ru] {ÐŸÑÑÐ°Ð²ÑÐµ ÑÑÐŸ Ð¿ÐŸÐ»Ðµ Ð¿ÑÑÑÑÐŒ, ÑÑÐŸÐ±Ñ Ð¿ÐŸÐ»ÑÑÐžÑÑ Ð²ÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ}  
+
+_browsebuttontext_ [l=ru] {"ÐÐžÐŽ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ²"}
+
+_nodata_ [l=ru] {<i>ÐœÐµÑ ÐŽÐ°ÐœÐœÑÑ
+</i>}
+_docs_ [l=ru] {ÐŽÐŸÐºÑÐŒÐµÐœÑÑ}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=ru] {ÐÐŸÐŒÐŸÑÑ}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=ru] {Ð¿ÑÐŸÑÐŒÐŸÑÑÐµÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð¿ÐŸ _1_ ÐœÐ°Ð¶Ð°ÑÐžÐµÐŒ ÐºÐœÐŸÐ¿ÐºÐž _2_ }
+
+_textSearchhelp_ [l=ru] {Ð¿ÐŸÐžÑÐº Ð¿ÐŸ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÐœÐœÑÐŒ ÑÐ»ÐŸÐ²Ð°ÐŒ  Ð² ÑÐµÐºÑÑÐµ, ÐœÐ°Ð¶Ð°ÑÐžÐµÐŒ ÐºÐœÐŸÐ¿ÐºÐž  _labelSearch_ }
+_textTohelp_ [l=ru] {ÐŽÐ»Ñ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ð¿ÐŸ Ð¿ÐŸÐ»Ñ Ð ÐœÐ°Ð¶ÐŒÐžÑÐµ ÐœÐ° ÐºÐœÐŸÐ¿ÐºÑ  _labelTo_ }  
+_textFromhelp_ [l=ru] {ÐŽÐ»Ñ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐ¹ Ð¿ÐŸ Ð¿ÐŸÐ»Ñ Â«ÐÑÂ» ÐœÐ°Ð¶ÐŒÐžÑÐµ ÐœÐ° ÐºÐœÐŸÐ¿ÐºÑ _labelFrom_}  
+_textBrowsehelp_ [l=ru] {Ð¿ÑÐŸÑÐŒÐŸÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ²}  
+_textAcronymhelp_ [l=ru] {ÐŽÐ»Ñ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ð¿ÐŸ Ð²Ñ
+ÐŸÐ¶ÐŽÐµÐœÐžÑ Ð² ÐœÐžÑ
+ ÑÐŸÐºÑÐ°ÑÐµÐœÐžÑ ÐœÐ°Ð¶ÐŒÐžÑÐµ ÐœÐ° ÐºÐœÐŸÐ¿ÐºÑ _labelAcronym_}  
+_textPhrasehelp_ [l=ru] {ÐŽÐ»Ñ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° ÑÑÐ°Ð·, ÐœÐ°Ð¹ÐŽÐµÐœÐœÑÑ
+ Ð² ÐŽÐŸÐºÑÐŒÐµÐœÑÐµ, ÐœÐ°Ð¶ÐŒÐžÑÐµ ÐºÐœÐŸÐ¿ÐºÑ _labelPhrase_ . ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ Ð¿ÑÐŸÑÐŒÐŸÑÑÑÐžÐº ÑÑÐ°Ð·.}  
+
+_texthelptopicstitle_ [l=ru] {Ð Ð°Ð·ÐŽÐµÐ»Ñ}
+
+_textreadingdocs_ [l=ru] {ÐÐ°Ðº ÑÐ°Ð±ÐŸÑÐ°ÑÑ Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒÐž}
+
+_texthelpreadingdocs_ [l=ru] {<p>ÐÐŸÐ³ÐŽÐ° Ð²Ñ ÐŸÑÐºÑÐŸÐµÑÐµ ÐºÐ°ÐºÐŸÐ¹-ÐœÐžÐ±ÑÐŽÑ ÐŽÐŸÐºÑÐŒÐµÐœÑ, ÐÑ ÑÐ²ÐžÐŽÐžÑÐµ ÐµÐ³ÐŸ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ, Ð° ÑÐ°ÐºÐ¶Ðµ ÐžÐŒÑ Ð°Ð²ÑÐŸÑÐ° Ð² Ð»ÐµÐ²ÐŸÐŒ Ð²ÐµÑÑ
+ÐœÐµÐŒ ÑÐ³Ð»Ñ ÑÑÑÐ°ÐœÐžÑÑ. ÐÑÐŸÐŒÐµ ÑÑÐŸÐ³ÐŸ ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ ÐœÐ°Ð¹ÑÐž ÐœÐŸÐŒÐµÑ ÑÑÑÐ°ÐœÐžÑÑ, ÑÑÑÐµÐ»ÐºÐž Ð²Ð¿ÐµÑÐµÐŽ Ðž ÐœÐ°Ð·Ð°ÐŽ, ÐºÐœÐŸÐ¿ÐºÑ ÐŽÐ»Ñ Ð²ÑÐ±ÐŸÑÐ° ÐœÐŸÐ²ÐŸÐ¹ ÑÑÑÐ°ÐœÐžÑÑ.
+
+<p>ÐÐžÐ¶Ðµ ÐœÐ°Ñ
+ÐŸÐŽÐžÑÑÑ ÑÐµÐºÑÑ ÑÐµÐºÑÑÐµÐ³ÐŸ ÑÐ°Ð·ÐŽÐµÐ»Ð°. ÐÐŸÑÐ»Ðµ ÑÐŸÐ³ÐŸ, ÐºÐ°Ðº Ð²Ñ Ð¿ÑÐŸÑÐžÑÐ°ÐµÑÐµ ÐµÐ³ÐŸ, Ð²ÐœÐžÐ·Ñ Ð²Ñ ÑÐ²ÐžÐŽÐžÑÐµ ÑÑÑÐµÐ»ÐºÐž ÐŽÐ»Ñ Ð¿ÐµÑÐµÑ
+ÐŸÐŽÐ° Ðº ÑÐ»ÐµÐŽÑÑÑÐµÐŒÑ ÐžÐ»Ðž Ð¿ÑÐµÐŽÑÐŽÑÑÐµÐŒÑ ÑÐ°Ð·ÐŽÐµÐ»Ñ.
+
+<p>ÐÐžÐ¶Ðµ ÐœÐ°Ð·Ð²Ð°ÐœÐžÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° Ðž ÐµÐ³ÐŸ Ð°Ð²ÑÐŸÑÐ° ÐœÐ°Ñ
+ÐŸÐŽÑÑÑ ÑÑÐž ÐºÐœÐŸÐ¿ÐºÐž. ÐÐ°Ð¶ÐŒÐžÑÐµ ÐœÐ° <i>ÐÐµÑÑ ÑÐµÐºÑÑ</i> ÐŽÐ»Ñ ÑÐŸÐ³ÐŸ, ÑÑÐŸÐ±Ñ ÐŸÑÐŸÐ±ÑÐ°Ð·ÐžÑÑ ÐœÐ° ÑÐºÑÐ°ÐœÐµ Ð²ÐµÑÑ ÑÐµÐºÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°. ÐÑÐ»Ðž ÐŽÐŸÐºÑÐŒÐµÐœÑ ÐŽÐŸÑÑÐ°ÑÐŸÑÐœÐŸ Ð±ÐŸÐ»ÑÑÐŸÐ¹, ÑÐŸ ÑÑÐŸ ÐŒÐŸÐ¶ÐµÑ Ð·Ð°ÐœÑÑÑ ÐœÐµÐºÐŸÑÐŸÑÐŸÐµ Ð²ÑÐµÐŒÑ Ðž Ð¿ÑÐžÐ»ÐžÑÐœÑÐ¹ ÐŸÐ±ÑÐµÐŒ Ð¿Ð°ÐŒÑÑÐž!
+ÐÐ°Ð¶ÐŒÐžÑÐµ ÐœÐ° <i>Ð ÐœÐŸÐ²ÐŸÐŒ ÐŸÐºÐœÐµ</i>, ÑÑÐŸÐ±Ñ ÐŸÑÐŸÐ±ÑÐ°Ð·ÐžÑÑ ÐŽÐ°ÐœÐœÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð² ÐœÐŸÐ²ÐŸÐŒ ÐŸÐºÐœÐµ (ÑÑÐŸ Ð±ÑÐ²Ð°ÐµÑ Ð¿ÐŸÐ»ÐµÐ·ÐœÐŸ, ÐµÑÐ»Ðž Ð²Ñ Ñ
+ÐŸÑÐžÑÐµ ÑÑÐ°Ð²ÐœÐžÑÑ ÐœÐµÑÐºÐŸÐ»ÑÐºÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÐžÐ»Ðž ÑÐžÑÐ°ÑÑ ÐŽÐ²Ð° ÑÑÐ°Ð·Ñ).  ÐÐ°ÐºÐŸÐœÐµÑ, ÐµÑÐ»Ðž Ð²Ñ ÐœÐ°ÑÐ»Ðž ÑÑÐŸÑ ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð¿ÐŸ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÑÐŒ ÑÐ»ÐŸÐ²Ð°ÐŒ, ÑÐŸ ÐŸÐœÐž Ð±ÑÐŽÑÑ Ð²ÑÐŽÐµÐ»ÐµÐœÑ Ð² ÑÐµÐºÑÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°.  ÐÐ°Ð¶ÐŒÐžÑÐµ ÐœÐ° <i>Ð¡ÐœÑÑÑ Ð²ÑÐŽÐµÐ»ÐµÐœÐžÐµ</i> ÐŽÐ»Ñ ÑÐŸÐ³ÐŸ, ÑÑÐŸÐ±Ñ ÐžÑÐºÐŸÐŒÑÐµ ÑÐ»ÐŸÐ²Ð° ÐœÐµ Ð²ÑÐŽÐµÐ»ÑÐ»ÐžÑÑ Ð² ÑÐµÐºÑÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°.
+}
+
+# help about the icons
+_texthelpopenbookshelf_ [l=ru] {ÐÑÐºÑÑÑÑ ÑÑÑ ÐºÐœÐžÐ¶ÐœÑÑ Ð¿ÐŸÐ»ÐºÑ}  
+_texthelpopenbook_ [l=ru] {ÐÑÐºÑÑÑÑ/Ð·Ð°ÐºÑÑÑÑ ÑÑÑ ÐºÐœÐžÐ³Ñ}  
+_texthelpviewtextsection_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑÐµÑÑ ÑÑÑ ÑÐµÐºÑÐžÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°}  
+_texthelpexpandtext_ [l=ru] {ÐÑÐŸÐ±ÑÐ°Ð·ÐžÑÑ Ð²ÐµÑÑ ÑÐµÐºÑÑ ÐžÐ»Ðž ÐœÐµÑ}
+_texthelpexpandcontents_ [l=ru] {Ð Ð°Ð·Ð²ÐµÑÐœÑÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ, ÐžÐ»Ðž ÐœÐµÑ}  
+_texthelpdetachpage_ [l=ru] {ÐÑÐºÑÑÑÑ ÑÑÑ ÑÑÑÐ°ÐœÐžÑÑ Ð² ÐœÐŸÐ²ÐŸÐŒ ÐŸÐºÐœÐµ}
+_texthelphighlight_ [l=ru] {ÐÑÐŽÐµÐ»ÑÑÑ ÐžÑÐºÐŸÐŒÑÐµ ÑÐ»ÐŸÐ²Ð° ÐžÐ»Ðž ÐœÐµÑ}
+_texthelpsectionarrows_ [l=ru] {ÐÐµÑÐµÐ¹ÑÐž Ðº Ð¿ÑÐµÐŽÑÐŽÑÑÐµÐ¹/ÑÐ»ÐµÐŽÑÑÐµÐ¹ ÑÐµÐºÑÐžÐž}  
+
+
+_texthelpsearchingtitle_ [l=ru] {ÐÐ°Ðº ÐŸÑÑÑÐµÑÑÐ²Ð»ÑÑÑ Ð¿ÐŸÐžÑÐº Ð¿ÐŸ ÑÐ¿ÐµÑÐžÐ°Ð»ÑÐœÑÐŒ ÑÐµÑÐŒÐžÐœÐ°ÐŒ}
+
+_texthelpsearching_ [l=ru] {<p>
+   ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ ÑÐŽÐµÐ»Ð°ÑÑ Ð¿ÑÐŸÑÑÐŸÐ¹ Ð·Ð°Ð¿ÑÐŸÑ ÑÐŸ ÑÑÑÐ°ÐœÐžÑÑ Ð¿ÐŸÐžÑÐºÐ°, ÑÐŸÐ³Ð»Ð°ÑÐœÐŸ ÑÐ»ÐµÐŽÑÑÑÐžÐŒ ÑÐ°Ð³Ð°ÐŒ:
+ <p> 
+   <ol>
+       <li>ÐÐ¿ÑÐµÐŽÐµÐ»ÐžÑÐµ, ÑÑÐŸ Ð²Ñ Ñ
+ÐŸÑÐžÑÐµ ÐœÐ°Ð¹ÑÐž
+       <li>ÐÐ¿ÑÐµÐŽÐµÐ»ÐžÑÐµ, ÐºÐ°Ðº Ð²Ñ ÑÑÐŸ Ñ
+ÐŸÑÐžÑÐµ ÐžÑÐºÐ°ÑÑ: ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ ÑÑÐ°Ð·Ñ ÐžÐ»Ðž ÐŸÑÐŽÐµÐ»ÑÐœÑÐµ ÑÐ»ÐŸÐ²Ð°
+       <li>ÐÐ°Ð¿ÐµÑÐ°ÑÐ°Ð¹ÑÐµ ÑÐµÐºÑÑ Ð·Ð°Ð¿ÑÐŸÑÐ° Ð² ÑÑÑÐŸÐºÐµ Ð¿ÐŸÐžÑÐºÐ°
+       <li>ÐÐ°Ð¶ÐŒÐžÑÐµ ÐœÐ° ÐºÐœÐŸÐ¿ÐºÑ <i>ÐÐ°ÑÐ°ÑÑ Ð¿ÐŸÐžÑÐº</i> 
+   </ol>
+
+ <p>ÐÐŸÑÐ»Ðµ Ð²ÑÐ¿ÐŸÐ»ÐœÐµÐœÐžÑ Ð·Ð°Ð¿ÑÐŸÑÐ° ÐœÐ° ÑÐºÑÐ°ÐœÐµ Ð¿ÐŸÑÐ²ÐžÑÑÑ 20 ÐœÐ°ÐžÐŒÐµÐœÐŸÐ²Ð°ÐœÐžÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ². Ð ÐºÐŸÐœÑÐµ ÑÐ¿ÐžÑÐºÐ° ÐœÐ°Ñ
+ÐŸÐŽÐžÑÑÑ ÐºÐœÐŸÐ¿ÐºÐ°, Ñ Ð¿ÐŸÐŒÐŸÑÑÑ ÐºÐŸÑÐŸÑÐŸÐ¹ Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ Ð¿ÐµÑÐµÐ¹ÑÐž Ðº ÑÐ»ÐµÐŽÑÑÑÐžÐŒ 20.  ÐÐ° ÑÐ»ÐµÐŽÑÑÑÐžÑ
+ ÑÑÑÐ°ÐœÐžÑÐ°Ñ
+ ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÐŸÐ² Ð²Ñ ÑÐ²ÐžÐŽÐžÑÐµ ÐºÐœÐŸÐ¿ÐºÐž ÐŽÐ»Ñ Ð¿ÐµÑÐµÑ
+ÐŸÐŽÐ° Ðº ÑÐ»ÐµÐŽÑÑÑÐžÐŒ 20 ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒ ÐžÐ»Ðž ÐŸÐ±ÑÐ°ÑÐœÐŸ Ðº Ð¿ÑÐµÐŽÑÐŽÑÑÐžÐŒ, Ðž Ñ.ÐŽ. ÐÐ°Ð¶ÐŒÐžÑÐµ ÐœÐ° ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ Ð»ÑÐ±ÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° ÐžÐ»Ðž Ð·ÐœÐ°ÑÐŸÐº Ð¿ÐµÑÐµÐŽ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµÐŒ, ÐŽÐ»Ñ ÑÐŸÐ³ÐŸ ÑÑÐŸÐ±Ñ Ð¿ÑÐŸÑÐŒÐŸÑÑÐµÑÑ ÐµÐ³ÐŸ.
+
+ <p>ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÑÐžÑÐ»ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÐ° Ð¿ÐŸÐžÑÐºÐ° - 100. ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ ÐžÐ·ÐŒÐµÐœÐžÑÑ ÑÑÐŸ ÑÐžÑÐ»ÐŸ ÐœÐ° ÑÑÑÐ°ÐœÐžÑÐµ ÐœÐ°ÑÑÑÐŸÐµÐº ( ÐºÐœÐŸÐ¿ÐºÐ° <i>ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž</i> Ð²Ð²ÐµÑÑ
+Ñ ÑÑÑÐ°ÐœÐžÑÑ ).<p>
+}  
+
+_texthelpquerytermstitle_ [l=ru] {Ð¡Ð»ÐŸÐ²Ð° ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ°}
+_texthelpqueryterms_ [l=ru] {<p>Ð¢ÐŸ, ÑÑÐŸ Ð²Ñ Ð²Ð²ÐŸÐŽÐžÑÐµ Ð² ÑÑÑÐŸÐºÐµ Ð·Ð°Ð¿ÑÐŸÑÐ°, ÐœÐ°Ð·ÑÐ²Ð°ÐµÑÑÑ "ÑÐ»ÐŸÐ²Ð°ÐŒÐž ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ°". ÐÐ°Ð¶ÐŽÐŸÐµ ÑÐ»ÐŸÐ²ÐŸ ÑÐŸÐŽÐµÑÐ¶ÐžÑ Ð±ÑÐºÐ²Ñ Ðž ÑÐžÑÑÑ. Ð¡Ð»ÐŸÐ²Ð° ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÑ Ð¿ÑÐŸÐ±ÐµÐ»Ð°ÐŒÐž. ÐÑÐ»Ðž ÐžÐŒÐµÐµÑÑÑ ÐºÐ°ÐºÐŸÐ¹-Ð»ÐžÐ±ÐŸ ÐŽÑÑÐ³ÐŸÐ¹ Ð·ÐœÐ°Ðº, ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, Ð·ÐœÐ°ÐºÐž Ð¿ÑÐœÐºÑÑÐ°ÑÐžÐž, ÑÐŸ ÐŸÐœÐž ÑÐ»ÑÐ¶Ð°Ñ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÑÐ°Ð·ÐŽÐµÐ»ÐžÑÐµÐ»ÐµÐ¹ ÑÐ»ÐŸÐ², ÐºÐ°Ðº Ðž Ð¿ÑÐŸÐ±ÐµÐ»Ñ, ÑÐŸ ÐµÑÑÑ ÐžÐ³ÐœÐŸÑÐžÑÑÑÑÑÑ. ÐÑ ÐœÐµ ÐŒÐŸÐ¶ÐµÑÐµ ÐŸÑÑÑÐµÑÑÐ²ÐžÑÑ Ð¿ÐŸÐžÑÐº Ð¿ÐŸ ÑÐ»ÐŸÐ²Ð°ÐŒ, ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐžÐŒ Ð·ÐœÐ°ÐºÐž Ð¿ÑÐœÐºÑÑÐ°ÑÐžÐž.
+
+<p>ÐÐ°Ð¿ÑÐžÐŒÐµÑ, ÑÐ°ÑÑÐŒÐŸÑÑÐžÐŒ Ð·Ð°Ð¿ÑÐŸÑ<p>
+    <ul><kbd>Ð¡ÐµÐ»ÑÑÐºÐŸ-Ð»ÐµÑÐœÐŸÐµ Ñ
+ÐŸÐ·ÑÐ¹ÑÑÐ²ÐŸ ÐœÐ° ÐŸÑÑÑÐŸÐ²Ð°Ñ
+ Ð¢ÐžÑ
+ÐŸÐ³ÐŸ ÐŸÐºÐµÐ°ÐœÐ°: Ð¡ÐžÑÑÐµÐŒÐ° Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÐž (1993)</kbd></ul>
+      <p>ÐŸÐœ Ð±ÑÐŽÐµÑ ÑÐ°Ð²ÐœÐŸÑÐžÐ»ÐµÐœ ÑÐ»ÐµÐŽÑÑÑÐµÐŒÑ<p>
+      <ul><kbd> Ð¡ÐµÐ»ÑÑÐºÐŸÐµ Ð»ÐµÑÐœÐŸÐµ Ñ
+ÐŸÐ·ÑÐ¹ÑÑÐ²ÐŸ ÐœÐ° ÐŸÑÑÑÐŸÐ²Ð°Ñ
+ Ð¢ÐžÑ
+ÐŸÐ³ÐŸ ÐŸÐºÐµÐ°ÐœÐ° Ð¡ÐžÑÑÐµÐŒÐ° Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÐž 1993</kbd></ul><p>
+}  
+
+_texthelpmgppsearching_ [l=ru] {ÐÐ»Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹, Ð¿ÐŸÑÑÑÐŸÐµÐœÐœÑÑ
+ Ñ Ð¿ÐŸÐŒÐŸÑÑÑ MGPP ÐŽÐŸÑÑÑÐ¿ÐœÑ ÐŽÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÑÐµ ÐŸÐ¿ÑÐžÐž.     <ul>  <li><b>*</b> Ð² ÐºÐŸÐœÑÐµ Ð·Ð°Ð¿ÑÐŸÑÐ° ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÐµÑ Ð²ÑÐµÐŒ ÑÐ»ÐŸÐ²Ð°ÐŒ, <b>ÐœÐ°ÑÐžÐœÐ°ÑÑÐžÐŒÑÑ Ñ</b> ÑÑÐŸÐ³ÐŸ ÑÐ»ÐŸÐ²Ð°, ÐœÐ°Ð¿ÑÐžÐŒÐµÑ <b>comput*</b> ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÐµÑ Ð²ÑÐµÐŒ ÑÐ»ÐŸÐ²Ð°ÐŒ, ÐœÐ°ÑÐžÐœÐ°ÑÑÐžÐŒÑÑ Ñ <b>comput</b>.  <li><b>/x</b> ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐŽÐ»Ñ Ð·Ð°ÐŽÐ°ÐœÐžÑ Ð²ÐµÑÐ° ÐŸÐŽÐœÐŸÐ³ÐŸ ÐžÐ· ÑÐ»ÐŸÐ² Ð·Ð°Ð¿ÑÐŸÑÐ°, ÑÐ°Ðº <b>computer/10 science</b> ÑÐºÐ°Ð·ÑÐ²Ð°ÐµÑ ÐœÐ° ÑÐŸ, ÑÑÐŸ computer Ð² 10 Ð±ÐŸÐ»ÐµÐµ Ð²ÐµÑÐŸÐŒ, ÑÐµÐŒ science Ð¿ÑÐž ÐŸÑÐµÐœÐºÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ².  </ul>  }  
+
+_texthelplucenesearching_ [l=ru] {ÐÐ»Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹, Ð¿ÐŸÑÑÑÐŸÐµÐœÐœÑÑ
+ Ñ Ð¿ÐŸÐŒÐŸÑÑÑ Lucene, ÐŽÐŸÑÑÑÐ¿ÐœÑ ÐŽÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÑÐµ ÐŸÐ¿ÑÐžÐž.     <ul>  <li><b>?</b> Ð·Ð°ÐŒÐµÐœÑÐµÑ Ð»ÑÐ±ÐŸÐ¹ ÐµÐŽÐžÐœÐžÑÐœÑÐ¹ ÑÐžÐŒÐ²ÐŸÐ». ÐÐ°Ð¿ÑÐžÐŒÐµÑ, <b>b?t</b> ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÐµÑ <b>bet</b>, <b>bit</b> Ðž <b>bat</b> Ðž Ñ.ÐŽ.  <li><b>*</b> ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÐµÑ ÐŒÐœÐŸÐ³ÐžÐŒ ÑÐžÐŒÐ²ÐŸÐ»Ð°ÐŒ. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, <b>comput*</b> ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÐµÑ Ð²ÑÐµÐŒ ÑÐ»ÐŸÐ²Ð°ÐŒ, ÐœÐ°ÑÐžÐœÐ°ÑÑÐžÐŒÑÑ Ñ <b>comput</b>.  </ul>  ÐÐ±Ð° ÑÑÐžÑ
+ ÑÐ¿ÐµÑÐžÐ°Ð»ÑÐœÑÑ
+ ÑÐžÐŒÐ²ÐŸÐ»Ð° ÐŒÐŸÐ¶ÐœÐŸ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÐºÐ°Ðº Ð² ÑÐµÑÐµÐŽÐžÐœÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÑ Ð¿ÐŸÐžÑÐºÐ°, ÑÐ°Ðº Ðž Ð² ÐºÐŸÐœÑÐµ. Ð ÐœÐ°ÑÐ°Ð»Ðµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÑ ÐžÑ
+ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÐœÐµÐ»ÑÐ·Ñ.  }  
+
+_texthelpquerytypetitle_ [l=ru] {Ð¢ÐžÐ¿Ñ Ð·Ð°Ð¿ÑÐŸÑÐŸÐ²}
+_texthelpquerytype_ [l=ru] {<p>Ð¡ÑÑÐµÑÑÐ²ÑÐµÑ ÐŽÐ²Ð° ÑÐ°Ð·Ð»ÐžÑÐœÑÑ
+ ÑÐžÐ¿Ð° Ð·Ð°Ð¿ÑÐŸÑÐ°.
+
+<ul>
+  <li>ÐÐ°Ð¿ÑÐŸÑÑ Ð¿ÐŸ <b>Ð²ÑÐµÐŒ</b> ÑÐ»ÐŸÐ²Ð°ÐŒ. Ð­ÑÐŸ Ð¿ÐŸÐŽÑ
+ÐŸÐŽÐžÑ ÐŽÐ»Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÐºÐŸÑÐŸÑÑÐµ ÑÐŸÐŽÐµÑÐ¶Ð°Ñ Ð²ÑÐµ ÑÐ»ÐŸÐ²Ð°, ÐºÐŸÑÐŸÑÑÐµ Ð²Ñ Ñ
+ÐŸÑÐžÑÐµ Ð²ÐºÐ»ÑÑÐžÑÑ Ð² ÑÑÑÐŸÐºÑ Ð¿ÐŸÐžÑÐºÐ°.
+ÐÐŸÐºÑÐŒÐµÐœÑÑ, ÑÐŽÐŸÐ²Ð»ÐµÑÐ²ÐŸÑÑÑÑÐžÐµ Ð·Ð°Ð¿ÑÐŸÑÑ, Ð±ÑÐŽÑÑ Ð²ÑÐ²ÐµÐŽÐµÐœÑ Ð² Ð°Ð»ÑÐ°Ð²ÐžÑÐœÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ.<p>
+
+  <li>ÐÐ°Ð¿ÑÐŸÑÑ Ð¿ÐŸ <b>ÐœÐµÐºÐŸÑÐŸÑÑÐŒ</b> ÑÐ»ÐŸÐ²Ð°ÐŒ. ÐÐŸÑÑÐ°ÑÐŸÑÐœÐŸ ÐœÐ°Ð¿ÐžÑÐ°ÑÑ Ð»ÐžÑÑ ÐœÐµÑÐºÐŸÐ»ÑÐºÐŸ ÑÐ»ÐŸÐ², ÐºÐŸÑÐŸÑÑÐµ, Ð²ÐµÑÐŸÑÑÐœÐŸ, ÐœÐ°Ñ
+ÐŸÐŽÑÑÑÑ Ð² ÑÐµÐºÑÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°.  ÐÐŸÐºÑÐŒÐµÐœÑÑ Ð±ÑÐŽÑÑ ÐŸÑÐŸÐ±ÑÐ°Ð¶ÐµÐœÑ Ð² Ð¿ÐŸÑÑÐŽÐºÐµ ÑÐŒÐµÐœÑÑÐµÐœÐžÑ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐžÑ Ð·Ð°Ð¿ÑÐŸÑÑ. Ð¡ÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐžÐµ Ð·Ð°Ð¿ÑÐŸÑÑ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÐµÑÑÑ ÑÐ°Ðº:
+      <p><ul>
+        <li> ÑÐµÐŒ Ð±ÐŸÐ»ÑÑÐµ ÐžÑÐºÐŸÐŒÑÑ
+ ÑÐµÑÐŒÐžÐœÐŸÐ² ÑÐŸÐŽÐµÑÐ¶ÐžÑ ÐŽÐŸÐºÑÐŒÐµÐœÑ, ÑÐµÐŒ Ð±ÐŸÐ»ÑÑÐµ ÐŸÐœ Ð¿ÐŸÐŽÑ
+ÐŸÐŽÐžÑ;
+        <li> ÑÐµÐŽÐºÐžÐµ ÑÐ»ÐŸÐ²Ð° Ð±ÐŸÐ»ÐµÐµ Ð²Ð°Ð¶ÐœÑ, ÑÐµÐŒ ÐŸÐ±ÑÐžÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÑ;
+        <li> ÐŒÐ°Ð»ÐµÐœÑÐºÐžÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð¿ÐŸÐŽÑ
+ÐŸÐŽÑÑ Ð»ÑÑÑÐµ, ÑÐµÐŒ Ð±ÐŸÐ»ÑÑÐžÐµ.
+      </ul>
+</ul>
+
+<p>ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ ÑÑÐŸÐ»ÑÐºÐŸ ÑÐ»ÐŸÐ² ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ°, ÑÐºÐŸÐ»ÑÐºÐŸ Ð²Ð°ÐŒ ÑÐ³ÐŸÐŽÐœÐŸ - ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ ÑÐµÐ»ÐŸÐµ Ð¿ÑÐµÐŽÐ»ÐŸÐ¶ÐµÐœÐžÐµ, ÐžÐ»Ðž Ð¿Ð°ÑÐ°Ð³ÑÐ°Ñ.  ÐÑÐ»Ðž Ð²Ñ Ð²Ð²ÐµÐŽÐµÑÐµ ÑÐŸÐ»ÑÐºÐŸ ÐŸÐŽÐœÐŸ ÑÐ»ÐŸÐ²ÐŸ, ÑÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð±ÑÐŽÑÑ ÑÐ°ÑÐ¿ÐŸÐ»ÐŸÐ¶ÐµÐœÑ Ð¿ÐŸ ÑÐ±ÑÐ²Ð°ÐœÐžÑ ÑÐ°ÑÑÐŸÑÑ ÐµÐ³ÐŸ Ð¿ÐŸÑÐ²Ð»ÐµÐœÐžÑ.<p>
+}  
+
+_texthelpadvancedsearchtitle_ [l=ru] {Ð Ð°ÑÐžÑÐµÐœÐœÑÐ¹ Ð¿ÐŸÐžÑÐº Ð¿ÑÐž Ð¿ÐŸÐŒÐŸÑÐž Ð¿ÐŸÐžÑÐºÐŸÐ²ÐŸÐ¹ ÐŒÐ°ÑÐžÐœÑ _1_}  
+
+_texthelpadvancedsearch_ [l=ru] {<p>ÐÑÐ»Ðž Ð²Ñ Ð²ÑÐ±ÑÐ°Ð»Ðž Ð² ÐœÐ°ÑÑÑÐŸÐ¹ÐºÐ°Ñ
+ ÑÐ°ÑÑÐžÑÐµÐœÐœÑÐ¹ ÑÐµÐ¶ÐžÐŒ Ð·Ð°Ð¿ÑÐŸÑÐŸÐ², ÑÐŸ Ñ Ð²Ð°Ñ ÐœÐµÐŒÐœÐŸÐ³ÐŸ ÐŽÑÑÐ³ÐžÐµ ÐŸÐ¿ÑÐžÐž Ð¿ÐŸÐžÑÐºÐ°. _selectadvancedsearch_}  
+
+_texthelpadvsearchmg_ [l=ru] {Ð Ð°ÑÑÐžÑÐµÐœÐœÑÐ¹ Ð¿ÐŸÐžÑÐº Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÑ
+ MG ÐžÐŒÐµÐµÑ ÐŽÐ²Ðµ ÐŸÐ¿ÑÐžÐž, ÑÐ°ÐœÐ³ÐŸÐ²ÑÑ Ðž Ð»ÐŸÐ³ÐžÑÐµÑÐºÑÑ. <b>Ð Ð°ÐœÐ³ÐŸÐ²ÑÐ¹</b> Ð¿ÐŸÐžÑÐº â ÑÑÐŸ ÑÐŸ Ð¶Ðµ ÑÐ°ÐŒÐŸÐµ, ÑÑÐŸ Ðž Ð¿ÐŸÐžÑÐº <b>ÐœÐµÐºÐŸÑÐŸÑÑÑ
+</b>, ÐŸÐ¿ÐžÑÐ°ÐœÐœÑÐ¹ Ð² <a href="\#query-type">_texthelpquerytypetitle_</a>.  <p>_texthelpbooleansearch_ }  
+
+_texthelpbooleansearch_ [l=ru] {<b>ÐÐŸÐ³ÐžÑÐµÑÐºÐžÐ¹</b> Ð¿ÐŸÐžÑÐº Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ ÐºÐŸÐŒÐ±ÐžÐœÐžÑÐŸÐ²Ð°ÑÑ ÑÑÑÐŸÐºÐž Ð·Ð°Ð¿ÑÐŸÑÐŸÐ², ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ & (ÐŽÐ»Ñ "Ðž"), | (ÐŽÐ»Ñ "ÐžÐ»Ðž"), Ðž ! (ÐŽÐ»Ñ "ÐœÐµ"), Ð¿ÑÐž Ð¿ÐŸÐŒÐŸÑÐž ÑÐºÐŸÐ±ÐŸÐº ÐžÑ
+ ÐŒÐŸÐ¶ÐœÐŸ Ð³ÑÑÐ¿Ð¿ÐžÑÐŸÐ²Ð°ÑÑ. ÐÐ¿ÐµÑÐ°ÑÐŸÑ Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ - ÑÑÐŸ | ("ÐžÐ»Ðž").  <p>  ÐÐ°Ð¿ÑÐžÐŒÐµÑ, <b>snail & farming</b> ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÐµÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒ, ÐºÐŸÑÐŸÑÑÐµ ÑÐŸÐŽÐµÐ¶Ð°Ñ Ðž <b>snail</b> Ð <b>farming</b>, Ð¿ÑÐžÑÐµÐŒ <b>snail | farming</b> Ð±ÑÐŽÐµÑ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐŸÐ²Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒ, ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐžÐŒ ÐžÐ»Ðž <b>snail</b> ÐÐÐ <b>farming</b>.  <b>snail !farming</b> Ð±ÑÐŽÐµÑ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐŸÐ²Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒ, ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐžÐŒ <b>snail</b> Ð ÐÐ ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐžÐŒ <b>farming</b>.  <p>  ÐÐ°ÐžÐ±ÐŸÐ»ÐµÐµ ÑÐŸÑÐœÑÐµ Ð·Ð°Ð¿ÑÐŸÑÑ ÐŒÐŸÐ¶ÐœÐŸ ÑÐŸÑÑÐ°Ð²ÐžÑÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ ÐºÐŸÐŒÐ±ÐžÐœÐ°ÑÐžÐž ÐŸÐ¿ÐµÑÐ°ÑÐŸÑÐŸÐ² Ðž ÑÐºÐŸÐ±ÐŸÐº.ÐÐ°Ð¿ÑÐžÐŒÐµÑ, <b>(sheep | cattle) & (farm | station)</b>, ÐžÐ»Ðž <b>sheep | cattle | goat !pig</b>.  }  
+
+_texthelpadvsearchmgpp_ [l=ru] {ÐÐ»Ñ ÑÐ°ÑÑÐžÑÐµÐœÐœÐŸÐ³ÐŸ Ð¿ÐŸÐžÑÐºÐ° Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÑ
+ MGPP ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑÑÑÑ Ð»ÐŸÐ³ÐžÑÐµÑÐºÐžÐµ ÐŸÐ¿ÐµÑÐ°ÑÐŸÑÑ. _texthelpbooleansearch_  
+<p>Ð ÐµÐ·ÑÐ»ÑÑÐ°ÑÑ ÐŒÐŸÐ³ÑÑ Ð±ÑÑÑ ÐŸÑÐŸÐ±ÑÐ°Ð¶ÐµÐœÑ Ð² <b>ÑÐ°ÐœÐ³ÐŸÐ²ÐŸÐŒ</b> Ð¿ÐŸÑÑÐŽÐºÐµ, ÐºÐ°Ðº Ðž Ð² Ð¿ÐŸÐžÑÐºÐµ <b>ÐœÐµÐºÐŸÑÐŸÑÑÑ
+</b> Ð² <a href="\#query-type">_texthelpquerytypetitle_</a>, ÐžÐ»Ðž Ð² "ÐµÑÑÐµÑÑÐ²ÐµÐœÐœÐŸÐŒ" (ÐžÐ»Ðž "Ð¿ÐŸÑÑÐŽÐºÐµ ÑÐ±ÐŸÑÐºÐž") Ð¿ÐŸÑÑÐŽÐºÐµ. Ð­ÑÐŸ ÑÐŸÑ Ð¿ÐŸÑÑÐŽÐŸÐº, Ð² ÐºÐŸÑÐŸÑÐŸÐŒ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð±ÑÐ»Ðž ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÐœÑ Ð² Ð¿ÑÐŸÑÐµÑÑÐµ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.  
+<p>  ÐÐ¿ÐµÑÐ°ÑÐŸÑÑ Ð²ÐºÐ»ÑÑÐ°ÑÑ <b>NEARx</b> Ðž <b>WITHINx</b>.  NEARx ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐŽÐ»Ñ ÑÐºÐ°Ð·Ð°ÐœÐžÑ ÐŒÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐ¹ ÑÐ°Ð·ÐœÐžÑÑ (x ÑÐ»ÐŸÐ²) ÐŒÐµÐ¶ÐŽÑ ÐŽÐ²ÑÐŒÑ ÑÑÑÐŸÐºÐ°ÐŒÐž Ð·Ð°Ð¿ÑÐŸÑÐŸÐ² ÐŽÐ»Ñ ÐœÐ°Ð¹ÐŽÐµÐœÐœÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°.   WITHINx ÑÐºÐ°Ð·ÑÐ²Ð°ÐµÑ ÐœÐ° ÑÐŸ, ÑÑÐŸ Ð²ÑÐŸÑÐ°Ñ ÑÑÑÐŸÐºÐ° ÐŽÐŸÐ»Ð¶ÐœÐ° Ð²Ñ
+ÐŸÐŽÐžÑÑ ÐœÐ° x ÑÐ»ÐŸÐ² <i>ÐŽÐ°Ð»ÐµÐµ</i> Ð¿ÐµÑÐ²ÐŸÐ¹. Ð­ÑÐŸ Ð¿ÐŸÑ
+ÐŸÐ¶Ðµ ÐœÐ° NEAR, ÐœÐŸ Ð¿ÐŸÑÑÐŽÐŸÐº ÐžÐŒÐµÐµÑ Ð·ÐœÐ°ÑÐµÐœÐžÐµ. Ð Ð°ÑÑÑÐŸÑÐœÐžÐµ Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ 20.}  
+
+_texthelpadvancedsearchextra_ [l=ru] {ÐÐÐÐÐ§ÐÐÐÐ: ÐÑÐ»Ðž Ð²Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÐµ Ð¿ÐŸÐžÑÐº Ð² ÑÐµÐ¶ÐžÐŒÐµ Ð¿ÑÐŸÑÑÑÑ
+ Ð·Ð°Ð¿ÑÐŸÑÐŸÐ², ÑÐŸ Ð²ÑÐµ ÑÑÐž ÐŸÐ¿ÐµÑÐ°ÑÐŸÑÑ ÐœÐµÐŽÐŸÑÑÑÐ¿ÐœÑ.}  
+
+_texthelpadvsearchlucene_ [l=ru] {ÐÐ»Ñ ÑÐ°ÑÑÐžÑÐµÐœÐœÐŸÐ³ÐŸ Ð¿ÐŸÐžÑÐºÐ° Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÑ
+ Lucene ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑÑÑÑ Ð»ÐŸÐ³ÐžÑÐµÑÐºÐžÐµ ÐŸÐ¿ÐµÑÐ°ÑÐŸÑÑ. _texthelpbooleansearch_  }  
+
+_texthelpformsearchtitle_ [l=ru] {ÐÐŸÐžÑÐº Ð¿ÐŸ Ð¿ÐŸÐ»ÑÐŒ}  
+
+_texthelpformsearch_ [l=ru] {<p>ÐÐŸÐžÑÐº Ð¿ÐŸ Ð¿ÐŸÐ»ÑÐŒ Ð¿ÑÐµÐŽÐŸÑÑÐ°Ð²Ð»ÑÐµÑ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÑ ÐºÐŸÐŒÐ±ÐžÐœÐžÑÐŸÐ²Ð°ÑÑ Ð¿ÐŸÐžÑÐº ÑÐµÑÐµÐ· Ð¿ÐŸÐ»Ñ. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, ÐŒÐŸÐ¶ÐœÐŸ ÐžÑÐºÐ°ÑÑ "Smith" Ð² ÐÐ°Ð³Ð»Ð°Ð²ÐžÐž Ð "snail farming" Ð² Ð¢ÐµÐŒÐµ. Ð ÑÐµÐ¶ÐžÐŒÐµ Ð¿ÑÐŸÑÑÑÑ
+ Ð·Ð°Ð¿ÑÐŸÑÐŸÐ² ÐºÐ°Ð¶ÐŽÐ°Ñ ÑÑÑÐŸÐºÐ° ÑÐŸÑÐŒÑ Ð²ÐµÐŽÐµÑ ÑÐµÐ±Ñ ÐºÐ°Ðº ÐœÐŸÑÐŒÐ°Ð»ÑÐœÑÐ¹ ÐŸÐŽÐœÐŸÑÑÑÐŸÑÐœÑÐ¹ Ð¿ÐŸÐžÑÐº. ÐÑÐŽÐµÐ»ÑÐœÑÐµ ÑÑÑÐŸÐºÐž ÑÐŸÑÐŒÑ ÐºÐŸÐŒÐ±ÐžÐœÐžÑÑÑÑÑ Ð¿ÑÐž Ð¿ÐŸÐŒÐŸÑÐž AND (ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ° "Ð²ÑÐµÑ
+") ÐžÐ»Ðž OR (ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ° "ÐœÐµÐºÐŸÑÐŸÑÑÑ
+"). Ð¡ÑÑÐŸÐºÐž Ð·Ð°Ð¿ÑÐŸÑÐŸÐ² Ð²ÐœÑÑÑÐž Ð¿ÐŸÐ»Ñ ÐŒÐŸÐ³ÑÑ Ð±ÑÑÑ ÑÐºÐŸÐŒÐ±ÐžÐœÐžÑÐŸÐ²Ð°ÐœÑ ÑÐ°ÐºÐžÐŒ Ð¶Ðµ ÐŸÐ±ÑÐ°Ð·ÐŸÐŒ. Ð ÑÐ°ÑÑÐžÑÐµÐœÐœÐŸÐŒ ÑÐµÐ¶ÐžÐŒÐµ ÐŒÐŸÐ¶ÐœÐŸ ÑÐºÐ°Ð·Ð°ÑÑ ÐŽÑÑÐ³ÐžÐµ Ð²Ð°ÑÐžÐ°ÐœÑÑ AND/OR/NOT ÐŒÐµÐ¶ÐŽÑ Ð¿ÐŸÐ»ÑÐŒÐž Ð¿ÑÐž Ð¿ÐŸÐŒÐŸÑÐž Ð²ÑÐ¿Ð°ÐŽÐ°ÑÑÐžÑ
+ ÑÐ¿ÐžÑÐºÐŸÐ², Ð° Ð²ÐœÑÑÑÐž Ð¿ÐŸÐ»Ñ ÐŒÐŸÐ¶ÐœÐŸ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ Ð»ÐŸÐ³ÐžÑÐµÑÐºÐžÐµ ÐŸÐ¿ÐµÑÐ°ÑÐŸÑÑ.  }  
+
+_texthelpformstemming_ [l=ru] {Ð­Ð»ÐµÐŒÐµÐœÑÑ "Ð²ÐºÐ»Ð°ÐŽÐºÐ°" Ðž "ÐŽÐµÑÐµÐ²ÐŸ" Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÑÑ ÑÐºÐ°Ð·Ð°ÑÑ, ÑÑÐŸ ÑÑÑÐŸÐºÐž Ð·Ð°Ð¿ÑÐŸÑÐŸÐ² Ð²ÐœÑÑÑÐž Ð¿ÐŸÐ»Ñ Ð²Ð»ÐŸÐ¶ÐµÐœÐœÑ ÐžÐ»Ðž ÑÐ°Ð·Ð²ÐµÑÐ²Ð»ÐµÐœÑ. ÐÐ±Ð° Ð¿ÑÐœÐºÑÐ° Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ Ð²ÑÐºÐ»ÑÑÐµÐœÑ ÐŽÐ»Ñ ÑÐ°ÑÑÐžÑÐµÐœÐœÐŸÐ¹ ÑÐŸÑÐŒÑ Ð¿ÐŸÐžÑÐºÐ°.}  
+
+_textdatesearch_ [l=ru] {ÐÐŸÐžÑÐº Ð¿ÐŸ ÐŽÐ°ÑÐµ}  
+
+_texthelpdatesearch_ [l=ru] {ÐÐŸÐžÑÐº Ð¿ÐŸ ÐŽÐ°ÑÐµ Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ Ð²Ð°ÐŒ ÐœÐ°Ð¹ÑÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÑ, ÐŸÑÐœÐŸÑÑÑÐžÐµÑÑ Ðº ÑÐŸÐ±ÑÑÐžÑÐŒ, Ð¿ÑÐŸÑÐµÐŽÑÐžÐŒ Ð² ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÐŸÐŒ Ð²ÑÐµÐŒÐµÐœÐœÐŸÐŒ Ð¿ÑÐŸÐŒÐµÐ¶ÑÑÐºÐµ Ð¿ÐŸÐŽÐŸÐ±ÐœÐŸ ÑÐŸÐŒÑ, ÐºÐ°Ðº ÐœÐ°Ñ
+ÐŸÐŽÑÑÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ, ÑÐ²ÑÐ·Ð°ÐœÐœÑÐµ Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÑÐŒ Ð¿ÐŸÐžÑÐºÐŸÐ²ÑÐŒ ÑÐµÑÐŒÐžÐœÐŸÐŒ.  ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ ÐŸÑÑÑÐµÑÑÐ²ÐžÑÑ Ð¿ÐŸÐžÑÐº ÐºÐ°Ðº Ð¿ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒ, ÐŸÑÐœÐŸÑÑÑÐžÐŒÑÑ Ðº ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÐŸÐŒÑ Ð³ÐŸÐŽÑ, ÑÐ°Ðº Ðž Ð¿ÐµÑÐžÐŸÐŽÑ Ð»ÐµÑ. <p>
+}
+
+_texthelpdatehowtotitle_ [l=ru] {ÐÐ°Ðº ÑÑÐŸ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ:}
+_texthelpdatehowto_ [l=ru] {<ul>
+   <li>ÐÐŸÐžÑÐº ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ð¿ÐŸ ÐºÐŸÐœÐºÑÐµÑÐœÐŸÐ¹ ÐŽÐ°ÑÐµ:<p>
+   <ul>
+       <li>ÐÐ²ÐµÐŽÐžÑÐµ ÐŸÐ±ÑÐºÐœÐŸÐ²ÐµÐœÐœÑÐµ ÑÐ»ÐŸÐ²Ð° ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ°. 
+       <li>ÐÐ²ÐµÐŽÐžÑÐµ ÐœÑÐ¶ÐœÑÐ¹ Ð³ÐŸÐŽ Ð² ÑÐŸÑÐŒÐµ "ÐÐ°ÑÐ°Ð»ÑÐœÐ°Ñ (ÐžÐ»Ðž ÐºÐŸÐœÐºÑÐµÑÐœÐ°Ñ) ÐŽÐ°ÑÐ°".
+       <li>ÐÑÐ»Ðž Ð²Ð°Ñ Ð³ÐŸÐŽ ÐœÐ°Ñ
+ÐŸÐŽÐžÑÑÑ Ð² Ð¿ÐµÑÐžÐŸÐŽÐµ ÐŽÐŸ ÐœÐ°ÑÐµÐ¹ ÑÑÑ (ÐžÐ»Ðž ÐŽÐŸ Ð ÐŸÐ¶ÐŽÐµÑÑÐ²Ð° Ð¥ÑÐžÑÑÐŸÐ²Ð°), ÑÐŸ Ð²ÑÐ±ÐµÑÐžÑÐµ ÐŽÐ°Ð»ÐµÐµ "ÐÐŸ Ðœ.Ñ." ÐžÐ· Ð²ÑÐ¿Ð°ÐŽÐ°ÑÑÐµÐ³ÐŸ ÐŒÐµÐœÑ.
+       <li>ÐÐ°ÑÐœÐžÑÐµ Ð¿ÐŸÐžÑÐº.
+   </ul>
+<p><li>ÐÐŸÐžÑÐº ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ð¿ÐŸ Ð²ÑÐµÐŒÐµÐœÐœÐŸÐŒÑ Ð¿ÑÐŸÐŒÐµÐ¶ÑÑÐºÑ:<p>
+   <ul>
+       <li>ÐÐ²ÐµÐŽÐžÑÐµ ÐŸÐ±ÑÐºÐœÐŸÐ²ÐµÐœÐœÑÐµ ÑÐ»ÐŸÐ²Ð° ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ°.
+       <li>ÐÐ²ÐµÐŽÐžÑÐµ ÐœÐ°ÑÐ°Ð»ÑÐœÑÐ¹ Ð³ÐŸÐŽ Ð² ÑÐŸÑÐŒÐµ "ÐÐ°ÑÐ°Ð»ÑÐœÐ°Ñ (ÐžÐ»Ðž ÐºÐŸÐºÑÐµÑÐœÐ°Ñ) ÐŽÐ°ÑÐ°". 
+       <li>ÐÐ²ÐµÐŽÐžÑÐµ ÐºÐŸÐœÐµÑÐœÑÐ¹ Ð³ÐŸÐŽ Ð² ÑÐŸÑÐŒÐµ "ÐÐŸÐœÐµÑÐœÐ°Ñ ÐŽÐ°ÑÐ°".
+       <li>ÐÑÐ±ÐµÑÐžÑÐµ "ÐÐŸ Ðœ.Ñ" ÐžÐ· Ð²ÑÐ¿Ð°ÐŽÐ°ÑÑÐµÐ³ÐŸ ÐŒÐµÐœÑ ÐŽÐ»Ñ Ð»ÑÐ±ÐŸÐ¹ ÐŽÐ°ÑÑ ÐžÐ· ÑÑÐŸÐ³ÐŸ Ð¿ÐµÑÐžÐŸÐŽÐ° (ÑÐ°ÐºÐ¶Ðµ ÐžÐ·Ð²ÐµÑÑÐœÐŸÐ³ÐŸ ÐºÐ°Ðº Ð¿ÐµÑÐžÐŸÐŽ ÐŽÐŸ Ð ÐŸÐ¶ÐŽÐµÑÑÐ²Ð° Ð¥ÑÐžÑÑÐŸÐ²Ð°).
+       <li>ÐÐ°ÑÐœÐžÑÐµ Ð¿ÐŸÐžÑÐº.
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=ru] {ÐÐ°Ðº ÑÐ°Ð±ÐŸÑÐ°ÐµÑ Ð¿ÐŸÐžÑÐº Ð¿ÐŸ ÐŽÐ°ÑÐµ}
+_texthelpdateresults_ [l=ru] {ÐÐ»Ñ Ð¿ÐŸÐ»ÑÑÐµÐœÐžÑ ÐœÐ°ÐžÐ±ÐŸÐ»ÐµÐµ Ð¿ÐŸÐ»ÐœÐŸÐ³ÐŸ ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÐ° Ð·Ð°Ð¿ÑÐŸÑÐ° ÑÐµÐºÐŸÐŒÐµÐœÐŽÑÐµÑÑÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÐžÐœÑÐµÑÐ²Ð°Ð»ÑÐœÑÐ¹ Ð·Ð°Ð¿ÑÐŸÑ, Ñ.Ðº. Ð² ÐœÐµÐºÐŸÑÐŸÑÑÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°Ñ
+ ÐŽÐ°ÑÐ° ÑÐ²ÐœÐŸ ÐœÐµ ÑÐºÐ°Ð·Ð°ÐœÐ° (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ ÐŒ.Ð±. ÑÐºÐ°Ð·Ð°Ðœ Ð²ÐµÐº, Ð° ÐœÐµ Ð³ÐŸÐŽ). 
+<p>
+}
+
+_textchangeprefs_ [l=ru] {ÐÐ·ÐŒÐµÐœÐµÐœÐžÐµ ÐœÐ°ÑÑÑÐŸÐµÐº}
+
+_texthelppreferences_ [l=ru] {<p>ÐÐ° ÑÑÑÐ°ÐœÐžÑÐµ <i>ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž</i> (ÐºÐœÐŸÐ¿ÐºÐ° Ð² Ð²ÐµÑÑ
+ÐœÐµÐ¹ ÑÐ°ÑÑÐž ÑÑÑÐ°ÐœÐžÑÑ) Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ ÐžÐ·ÐŒÐµÐœÐžÑÑ ÐœÐµÐºÐŸÑÐŸÑÑÐµ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÑ ÐžÐœÑÐµÑÑÐµÐ¹ÑÐ°.
+}
+
+_texthelpcollectionprefstitle_ [l=ru] {ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž}
+_texthelpcollectionprefs_ [l=ru] {ÐÐµÐºÐŸÑÐŸÑÑÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÑÐŸÐŽÐµÑÐ¶Ð°Ñ ÐœÐµÑÐºÐŸÐ»ÑÐºÐŸ Ð¿ÐŸÐŽÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹, Ð¿ÐŸÐžÑÐº Ð¿ÐŸ ÐºÐŸÑÐŸÑÑÐŒ ÐŒÐŸÐ¶ÐµÑ ÐŸÑÑÑÐµÑÑÐ²Ð»ÑÑÑÑÑ ÐºÐ°Ðº Ð¿ÐŸ ÐºÐ°Ð¶ÐŽÐŸÐ¹ ÐžÐ· ÐœÐžÑ
+, ÑÐ°Ðº Ðž Ð¿ÐŸ Ð²ÑÐµÐŒ Ð²ÐŒÐµÑÑÐµ. ÐÐ° ÑÑÑÐ°ÐœÐžÑÐµ ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ Ð²ÑÐ±ÑÐ°ÑÑ ÑÐµ Ð¿ÐŸÐŽÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž, ÐºÐŸÑÐŸÑÑÐµ Ð²Ñ Ñ
+ÐŸÑÐžÑÐµ Ð²ÐºÐ»ÑÑÐžÑÑ Ð² Ð¿ÐŸÐžÑÐº.
+}
+
+_texthelplanguageprefstitle_ [l=ru] {ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž ÑÐ·ÑÐºÐ°}
+_texthelplanguageprefs_ [l=ru] {<p>ÐÐ°Ð¶ÐŽÐ°Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐžÐŒÐµÐµÑ ÑÑÐ°ÐœÐŽÐ°ÑÑÐœÑÐ¹ ÑÐ·ÑÐº ÐžÐœÑÐµÑÑÐµÐ¹ÑÐ°, ÐœÐŸ Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ Ð²ÑÐ±ÑÐ°ÑÑ Ð»ÑÐ±ÐŸÐ¹ ÐŽÑÑÐ³ÐŸÐ¹.  Ð¢Ð°ÐºÐ¶Ðµ Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ Ð²ÑÐ±ÑÐ°ÑÑ ÐŽÑÑÐ³ÑÑ ÐºÐŸÐŽÐžÑÐŸÐ²ÐºÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÑ Ð² ÐŽÐ°ÐœÐœÐŸÐ¹ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐµ, Ð¿ÐŸÐŽÑ
+ÐŸÐŽÑÑÑÑ ÐŽÐ»Ñ Ð²Ð°ÑÐµÐ³ÐŸ Ð±ÑÐ°ÑÐ·ÐµÑÐ° - Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐž ÑÑÐ°Ð²ÐžÑÑÑ ÑÑÐ°ÐœÐŽÐ°ÑÑÐœÐ°Ñ, ÐœÐŸ ÐœÐ° ÐœÐµÐºÐŸÑÑÑÑ
+ Ð±ÑÐ°ÑÐ·ÐµÑÐ°Ñ
+ Ð»ÑÑÑÐµ Ð²ÑÐ±ÑÐ°ÑÑ ÐºÐŸÐŽÐžÑÐŸÐ²ÐºÑ Ð²ÑÑÑÐœÑÑ. ÐÑÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÑÑ ÑÐ°ÐºÐ¶Ðµ Ð¿ÐµÑÐµÐ¹ÑÐž ÐŸÑ Ð³ÑÐ°ÑÐžÑÐµÑÐºÐŸÐ³ÐŸ ÑÐµÐ¶ÐžÐŒÐ° Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° Ðº ÑÐµÐºÑÑÐŸÐ²ÐŸÐŒÑ, Ðž ÐœÐ°ÐŸÐ±ÐŸÑÐŸÑ. 
+}  
+
+_texthelppresentationprefstitle_ [l=ru] {ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž ÐžÐœÑÐµÑÑÐµÐ¹ÑÐ°}
+_texthelppresentationprefs_ [l=ru] {Ð Ð·Ð°Ð²ÐžÑÐžÐŒÐŸÑÑÐž ÐŸÑ ÐºÐ°Ð¶ÐŽÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž, Ð² ÐœÐµÐ¹ ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ ÐœÐµÑÐºÐŸÐ»ÑÐºÐŸ ÑÐ°Ð·Ð»ÐžÑÐœÑÑ
+ ÐœÐ°ÑÑÑÐŸÐµÐº ÐžÐœÑÐµÑÑÐµÐ¹ÑÐ°.
+
+<p>ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ Web ÑÑÑÐ°ÐœÐžÑ Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ Ð¿Ð°ÐœÐµÐ»Ñ ÑÐ¿ÑÐ°Ð²Ð»ÐµÐœÐžÑ Ð²Ð²ÐµÑÑ
+Ñ ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°, ÑÐ°ÐºÐžÐŒ ÐŸÐ±ÑÐ°Ð·ÐŸÐŒ Ð¿ÐŸÑÐ»Ðµ Ð¿ÐŸÐžÑÐºÐ° Ð²Ñ ÑÑÐ°Ð·Ñ Ð¿ÐŸÐ¿Ð°ÐŽÐµÑÐµ ÐœÐ° Web-ÑÑÑÐ°ÐœÐžÑÑ Ð±ÐµÐ· Ð²ÑÑÐºÐŸÐ³ÐŸ Greenstone Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐ°.  Ð§ÑÐŸÐ±Ñ ÑÐŽÐµÐ»Ð°ÑÑ ÐœÐŸÐ²ÑÐ¹ Ð·Ð°Ð¿ÑÐŸÑ, ÐŽÐŸÑÑÐ°ÑÐŸÑÐœÐŸ ÐœÐ°Ð¶Ð°ÑÑ ÐºÐœÐŸÐ¿ÐºÑ "back" Ð² Ð²Ð°ÑÐµÐŒ Ð±ÑÐ°ÑÐ·ÐµÑÐµ. Ð¢Ð°ÐºÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÑÐ°ÐºÐ¶Ðµ Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÑÑ Ð·Ð°Ð¿ÑÐµÑÐ°ÑÑ ÑÐžÑÑÐµÐŒÐœÑÐµ ÐŸÑÐžÐ±ÐºÐž, ÐºÐŸÐ³ÐŽÐ° Ð²Ñ ÐœÐ°Ð¶ÐžÐŒÐ°ÐµÑÐµ ÐœÐ° ÑÑÑÐ»ÐºÐž, Ð²ÑÐ²ÐŸÐŽÑÑÐžÐµ Ð²Ð°Ñ Ð·Ð° ÑÐ°ÐŒÐºÐž ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž Ð² WWW. 
+}
+
+_texthelpsearchprefstitle_ [l=ru] {ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž Ð¿ÐŸÐžÑÐºÐ°}
+_texthelpsearchprefs_ [l=ru] {<p>ÐÐ²Ð° Ð¿ÐµÑÐµÐºÐ»ÑÑÐ°ÑÐµÐ»Ñ ÑÐ¿ÑÐ°Ð²Ð»ÑÑÑ ÑÐŸÑÐœÐŸÑÑÑÑ Ð¿ÐŸÐžÑÐºÐ° ÑÐµÐºÑÑÐ°. ÐÐµÑÐµÐºÐ»ÑÑÐ°ÑÐµÐ»Ñ ("Ð ÐµÐ³ÐžÑÑÑÑ") Ð²ÐºÐ»ÑÑÐ°ÐµÑ/ÐŸÑÐŒÐµÐœÑÐµÑ ÑÑÐµÑ ÑÐµÐ³ÐžÑÑÑÐ°. ÐÐµÑÐµÐºÐ»ÑÑÐ°ÑÐµÐ»Ñ "ÐÐºÐŸÐœÑÐ°ÐœÐžÑ ÑÐ»ÐŸÐ²" Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÐžÐ»Ðž ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÑÑ ÐŸÐºÐŸÐœÑÐ°ÐœÐžÑ Ñ ÑÐ»ÐŸÐ².  ÐÐµÑÐµÐºÐ»ÑÑÐ°ÑÐµÐ»Ñ "Ð Ð°Ð·ÐŒÐµÑ ÐŸÐºÐœÐ° Ð¿ÐŸÐžÑÐºÐ°" Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ Ð²Ð²ÐŸÐŽÐžÑÑ ÑÐµÐ»ÑÐ¹ Ð°Ð±Ð·Ð°Ñ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÑÐµÐºÑÑÐ° Ð·Ð°Ð¿ÑÐŸÑÐ°. 
+<p>ÐÐ°Ð¿ÑÐžÐŒÐµÑ, ÐµÑÐ»Ðž Ð²ÑÐ±ÑÐ°ÐœÐŸ <i>ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÑÑ ÑÐµÐ³ÐžÑÑÑÑ</i> Ðž
+<i>ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÑÑ ÐŸÐºÐŸÐœÑÐ°ÐœÐžÑ ÑÐ»ÐŸÐ²</i>,ÑÐŸ Ð·Ð°Ð¿ÑÐŸÑ<p>
+    <ul><kbd>African building</kbd></ul>
+      <p>Ð±ÑÐŽÐµÑ ÑÑÐ°ÐºÑÐŸÐ²Ð°ÑÑÑÑ ÐºÐ°Ðº<p>
+      <ul><kbd>africa builds</kbd></ul><p>
+      Ð¿ÐŸÑÐŸÐŒÑ ÑÑÐŸ Ð±ÑÐºÐ²Ð° Ð²ÐµÑÑ
+ÐœÐµÐ³ÐŸ ÑÐµÐ³ÐžÑÑÑÐ° ÐžÐ· ÑÐ»ÐŸÐ²Ð° "African" Ð±ÑÐŽÐµÑ ÐžÐ·ÐŒÐµÐœÐµÐœÐ° ÐœÐ° Ð±ÑÐºÐ²Ñ ÐœÐžÐ¶ÐœÐµÐ³ÐŸ ÑÐµÐ³ÐžÑÑÑÐ°, Ð° ÑÑÑÑÐžÐºÑÑ "n" Ðž "ing" Ð±ÑÐŽÑÑ ÑÐŽÐ°Ð»ÐµÐœÑ ÐžÐ· ÑÐ»ÐŸÐ²
+      "African" Ðž "building" (ÑÐ°ÐºÐ¶Ðµ, "s" Ð±ÑÐŽÐµÑ ÑÐŽÐ°Ð»ÐµÐœÐ° ÐžÐ· "builds").
+
+<p>ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ Ð¿ÐµÑÐµÐºÐ»ÑÑÐžÑÑÑÑ Ð² ÑÐ°ÑÑÐžÑÐµÐœÐœÑÑ ÑÐŸÑÐŒÑ Ð·Ð°Ð¿ÑÐŸÑÐ°, ÐºÐŸÑÐŸÑÐ°Ñ Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ ÑÐŸÑÐµÑÐ°ÑÑ ÑÐ»ÐŸÐ²Ð°, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ Ð (&), ÐÐÐ (|), Ð ÐÐ (!). Ð­ÑÐŸ Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ ÑÐŸÐ·ÐŽÐ°Ð²Ð°ÑÑ Ð±ÐŸÐ»ÐµÐµ ÑÐŸÑÐœÑÐµ Ð·Ð°Ð¿ÑÐŸÑÑ. Ð¢Ð°ÐºÐ¶Ðµ Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ Ð²ÐºÐ»ÑÑÐžÑÑ Ð¿ÐŸÐºÐ°Ð· ÐžÑÑÐŸÑÐžÐž Ð·Ð°Ð¿ÑÐŸÑÐ°, ÐºÐŸÐ³ÐŽÐ° Ð±ÑÐŽÑÑ Ð¿ÐŸÐºÐ°Ð·Ð°ÐœÑ Ð¿ÑÐµÐŽÑÐŽÑÑÐžÐµ ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÑ Ð¿ÐŸÐžÑÐºÐ°. Ð­ÑÐŸ Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ ÑÐŸÐ·ÐŽÐ°Ð²Ð°ÑÑ ÑÐ»ÐµÐ³ÐºÐ° ÐžÐ·ÐŒÐµÐœÐµÐœÐœÑÐµ ÑÐŸÑÐŒÑ Ð·Ð°Ð¿ÑÐŸÑÐŸÐ². ÐÐ°ÐºÐŸÐœÐµÑ, Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ ÑÐµÐ³ÑÐ»ÐžÑÐŸÐ²Ð°ÑÑ ÐŸÐ±ÑÐµÐµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² - ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÐŸÐ² Ð¿ÐŸÐžÑÐºÐ°, Ð° ÑÐ°ÐºÐ¶Ðµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÐœÐ° ÐŸÐŽÐœÐŸÐ¹ ÑÑÑÐ°ÐœÐžÑÐµ.
+}
+
+_textcasefoldprefs_ [l=ru] {Ð­ÑÐ° Ð¿Ð°ÑÐ° ÐºÐœÐŸÐ¿ÐŸÐº ÑÐ¿ÑÐ°Ð²Ð»ÑÐµÑ, ÐŽÐŸÐ»Ð¶ÐœÑ Ð»Ðž ÑÐŸÐ²Ð¿Ð°ÐŽÐ°ÑÑ Ð¿ÑÐž Ð¿ÐŸÐžÑÐºÐµ Ð±ÑÐºÐ²Ñ Ð²ÐµÑÑ
+ÐœÐžÑ
+ Ðž ÐœÐžÐ¶ÐœÐžÑ
+ ÑÐµÐ³ÐžÑÑÑÐŸÐ². ÐÐ°Ð¿ÑÐžÐŒÐµÑ, ÐµÑÐ»Ðž Ð²ÑÐ±ÑÐ°ÐœÐŸ "_preferences:textignorecase_", <i>snail farming</i> Ð±ÑÐŽÐµÑ ÑÐµÐŒ Ð¶Ðµ ÑÐ°ÐŒÑÐŒ, ÑÑÐŸ Ðž <i>Snail Farming</i> Ðž <i>SNAIL FARMING</i>.}  
+_textstemprefs_ [l=ru] {Ð­ÑÐ° Ð¿Ð°ÑÐ° ÐºÐœÐŸÐ¿ÐŸÐº ÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÐµÑ, ÐœÑÐ¶ÐœÐŸ Ð»Ðž ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÑÑ ÐŸÐºÐŸÐœÑÐ°ÐœÐžÑ ÑÐ»ÐŸÐ² Ð¿ÑÐž Ð¿ÐŸÐžÑÐºÐµ, ÐžÐ»Ðž ÐœÐµÑ. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, ÐµÑÐ»Ðž Ð²ÑÐ±ÑÐ°ÐœÐŸ "_preferences:textstem_", <i>snail farming</i> Ð±ÑÐŽÐµÑ ÑÑÐžÑÐ°ÑÑÑÑ ÑÐµÐŒ Ð¶Ðµ ÑÐ°ÐŒÑÐŒ, ÑÑÐŸ <i>snails farm</i> and <i>snail farmer</i>. ÐÐ° ÐŽÐ°ÐœÐœÑÐ¹ ÐŒÐŸÐŒÐµÐœÑ ÑÑÐ° ÑÑÐœÐºÑÐžÑ ÑÐ°Ð±ÐŸÑÐ°ÐµÑ Ð¿ÑÐ°Ð²ÐžÐ»ÑÐœÐŸ ÑÐŸÐ»ÑÐºÐŸ ÐŽÐ»Ñ Ð°ÐœÐ³Ð»ÐŸÑÐ·ÑÑÐœÑÑ
+ ÑÐµÐºÑÑÐŸÐ². _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=ru] {Ð­ÑÐ° Ð¿Ð°ÑÐ° ÐºÐœÐŸÐ¿ÐŸÐº ÑÐ¿ÑÐ°Ð²Ð»ÑÐµÑ, ÐŽÐŸÐ»Ð¶ÐœÑ Ð»Ðž ÑÐŸÐ²Ð¿Ð°ÐŽÐ°ÑÑ Ð¿ÑÐž Ð¿ÐŸÐžÑÐºÐµ Ð°ÐºÑÐµÐœÑÐžÑÐŸÐ²Ð°ÐœÐœÑÐµ Ðž ÐœÐµ Ð°ÐºÑÐµÐœÑÐžÑÐŸÐ²Ð°ÐœÐœÑÐµ Ð±ÑÐºÐ²Ñ. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, ÐµÑÐ»Ðž Ð²ÑÐ±ÑÐ°ÐœÐŸ "_preferences:textignoreaccents_", <i>fÃ©dÃ©ration</i> Ð±ÑÐŽÐµÑ ÑÑÐžÑÐ°ÑÑÑÑ ÑÐµÐŒ Ð¶Ðµ ÑÐ°ÐŒÑÐŒ, ÑÑÐŸ Ðž <i>fedÃ©ration</i> Ðž <i>federation</i>.}  
+ 
+_textstemoptionsprefs_ [l=ru] {ÐÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ, ÐŽÐ»Ñ Ð±ÐŸÐ»ÐµÐµ ÑÐŽÐŸÐ±ÐœÐŸÐ³ÐŸ Ðž ÑÐŸÑÐœÐŸÐ³ÐŸ Ð¿ÐŸÐžÑÐºÐ° Ð»ÑÑÑÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÑÐ¿ÐŸÑÐŸÐ± ÑÐŸÐºÑÐ°ÑÐµÐœÐžÑ Ð·Ð°Ð¿ÑÐŸÑÐŸÐ², ÐŸÐ¿ÐžÑÐ°ÐœÐœÑÐ¹ Ð² "_texthelpquerytermstitle_".}  
+
+_textsearchtypeprefsplain_ [l=ru] {Ð¡ÑÑÐµÑÑÐ²ÑÐµÑ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÑ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ Ð±ÐŸÐ»ÑÑÐŸÐ³ÐŸ Ð¿ÐŸÐ»Ñ Ð²Ð²ÐŸÐŽÐ° ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ°, ÑÐ°Ðº ÑÑÐŸ ÐŒÐŸÐ¶ÐœÐŸ Ð»ÐµÐ³ÐºÐŸ ÐžÑÐºÐ°ÑÑ ÑÐµÐ»ÑÐµ Ð°Ð±Ð·Ð°ÑÑ. ÐÐŸÐ»ÑÑÐžÐµ ÐŸÐ±ÑÐµÐŒÑ ÑÐµÐºÑÑÐ° ÐžÑÑÑÑÑ ÐœÐ° ÑÐŽÐžÐ²Ð»ÐµÐœÐžÐµ Ð»ÐµÐ³ÐºÐŸ.}  
+
+_textsearchtypeprefsform_ [l=ru] {ÐÐŸÐ¶ÐœÐŸ ÐžÐ·ÐŒÐµÐœÐžÑÑ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ Ð¿ÐŸÐ»ÐµÐ¹, Ð¿ÐŸÐºÐ°Ð·ÑÐ°ÐµÐŒÑÑ
+ Ð² ÑÐŸÑÐŒÐµ Ð¿ÐŸÐžÑÐºÐ°.}  
+
+_textsearchtypeprefsboth_ [l=ru] {ÐÐŸÐ¶ÐœÐŸ Ð²ÑÐ±ÑÐ°ÑÑ ÑÐµÐ¶ÐžÐŒ Ð¿ÐŸÐžÑÐºÐ° "ÐœÐŸÑÐŒÐ°Ð»ÑÐœÑÐ¹" ÐžÐ»Ðž "Ð¿ÐŸ Ð¿ÐŸÐ»ÑÐŒ".   <ul>  <li>ÐÐŸÑÐŒÐ°Ð»ÑÐœÑÐ¹ Ð¿ÐŸÐžÑÐº Ð¿ÑÐµÐŽÐŸÑÑÐ°Ð²Ð»ÑÐµÑ ÐŸÐŽÐœÑ ÑÑÑÐŸÐºÑ Ð·Ð°Ð¿ÑÐŸÑÐ°. _textsearchtypeprefsplain_</li>  <li>ÐÐŸÐžÑÐº Ð¿ÐŸ Ð¿ÐŸÐ»ÑÐŒ Ð¿ÑÐµÐŽÐŸÑÑÐ°Ð²Ð»ÑÐµÑ ÐœÐµÑÐºÐŸÐ»ÑÐºÐŸ ÑÑÑÐŸÐº, ÐºÐ°Ð¶ÐŽÐ°Ñ ÐžÐ· ÐºÐŸÑÐŸÑÑÑ
+ ÑÐºÐ°Ð·ÑÐ²Ð°ÐµÑ ÐœÐ° ÑÐ°Ð·Ð»ÐžÑÐœÐŸÐµ Ð¿ÐŸÐ»Ðµ ÐžÐœÐŽÐµÐºÑÐ°. Ð¢Ð°ÐºÐžÐŒ ÐŸÐ±ÑÐ°Ð·ÐŸÐŒ ÐŒÐŸÐ¶ÐœÐŸ ÐŸÐŽÐœÐŸÐ²ÑÐµÐŒÐµÐœÐœÐŸ ÐžÑÐºÐ°ÑÑ Ð¿ÐŸ ÐœÐµÑÐºÐŸÐ»ÑÐºÐžÐŒ Ð¿ÐŸÐ»ÑÐŒ. _textsearchtypeprefsform_ </li>  </ul>  }  
+
+
+
+_texttanumbrowseoptions_ [l=ru] {Ð¡ÑÑÐµÑÑÐ²ÑÑÑ (_numbrowseoptions_) Ð²ÐžÐŽÐ°/ÐŸÐ² Ð¿ÐŸÐžÑÐºÐ°  ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž Ð² ÑÑÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž:}
+
+_textsimplehelpheading_ [l=ru] {ÐÐ°Ðº ÐžÑÐºÐ°ÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ}
+
+_texthelpscopetitle_ [l=ru] {ÐÐžÐ°Ð¿Ð°Ð·ÐŸÐœ Ð¿ÐŸÐžÑÐºÐ°}
+_texthelpscope_ [l=ru] {<p>
+Ð Ð±ÐŸÐ»ÑÑÐžÐœÑÑÐ²Ðµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹ Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÑÐ°Ð·Ð»ÐžÑÐœÑÐµ ÐžÐœÐŽÐµÐºÑÑ ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ°. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, ÐžÐœÐŽÐµÐºÑ Ð¿ÐŸ ÐœÐ°Ð·Ð²Ð°ÐœÐžÑÐŒ ÐºÐœÐžÐ³, ÐžÐ»Ðž Ð¿ÐŸ ÑÐ°ÐŒÐžÐ»ÐžÑÐŒ Ð°Ð²ÑÐŸÑÐŸÐ². Ð­ÑÐŸ ÐŒÐŸÐ³ÑÑ Ð±ÑÑÑ ÑÐ°ÐºÐ¶Ðµ ÐžÐœÐŽÐµÐºÑÑ Ð¿ÐŸ Ð³Ð»Ð°Ð²Ð°ÐŒ ÐžÐ»Ðž Ð¿ÐŸ Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐ°ÐŒ ÑÐ°Ð·ÐŽÐµÐ»ÐŸÐ². ÐÑÐ»Ðž Ð²Ñ ÐœÐµ ÑÐºÐ°Ð¶ÐµÑÐµ  ÑÑÐµÐ±ÑÐµÐŒÑÐ¹ ÐžÐœÐŽÐµÐºÑ (Ð¿ÐŸ Ð³Ð»Ð°Ð²Ð°ÐŒ ÐžÐ»Ðž Ð¿ÐŸ ÑÐµÐºÑÐžÑÐŒ), ÑÐŸ ÐœÐ° ÑÐºÑÐ°Ðœ Ð±ÑÐŽÐµÑ Ð²ÑÐ²ÐµÐŽÐµÐœ Ð²ÐµÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑ<p> ÐÑÐ»Ðž ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐŒ ÑÐ²Ð»ÑÐµÑÑÑ ÑÐµÐ»Ð°Ñ ÐºÐœÐžÐ³Ð°, ÑÐŸ ÐŸÐœÐ° Ð±ÑÐŽÐµÑ ÐŸÑÐºÑÑÑÐ° Ð² ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÑÑÐµÐŒ ÐŒÐµÑÑÐµ.
+}
Index: /gsdl/stable/macros/russian2.dm
===================================================================
--- /gsdl/stable/macros/russian2.dm	(revision 20131)
+++ /gsdl/stable/macros/russian2.dm	(revision 20131)
@@ -0,0 +1,962 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Russian Language text and icon macros 
+# -- this file contains text that is of less importance
+# Translated by UNESCO for the UNESCO CD-ROMs
+# Contributions made by Sergei Korobitsin, Vyacheslav Bakharev and Sergey Karpov
+#
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=ru] {ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ². }
+_lastupdate_ [l=ru] {ÐÐŸÑÐ»ÐµÐŽÐœÐµÐµ ÐŸÐ±ÐœÐŸÐ²Ð»ÐµÐœÐžÐµ}
+_ago_ [l=ru] {ÐŽÐœÐµÐ¹ ÐœÐ°Ð·Ð°ÐŽ.}
+_colnotbuilt_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐœÐµ ÑÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÐœÐ°.}
+
+### taken from here
+
+_textpoem_ [l=ru] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+<p>Ð¿ÑÑÑÑ Ð²Ð°Ñ ÐŸÐºÑÑÐ¶Ð°ÑÑ ÐŒÐžÑ Ðž ÑÐ¿ÐŸÐºÐŸÐ¹ÑÑÐ²ÐžÐµ, 
+<p>Ð¿ÑÑÑÑ Ð¿ÐŸÑÑÐŸÑÐœÐœÐŸ Ð²Ñ Ð±ÑÐŽÐµÑÐµ ÐœÐ°Ñ
+ÐŸÐŽÐžÑÑÑÑ Ð² ÑÐµÐ¿Ð»ÑÑ
+ ÐŸÐ±ÑÑÑÐžÑÑ
+ Ð»ÐµÑÐ°, 
+<br>Ð¿ÑÑÑÑ Ð²ÐŸÐŽÑ ÐŸÐºÐµÐ°ÐœÐ° Ð²Ð°ÑÐžÑ
+ Ð¿ÑÑÐµÑÐµÑÑÐ²ÐžÐ¹ Ð±ÑÐŽÑÑ ÑÑÐŸÐ»Ñ Ð¶Ðµ Ð³Ð»Ð°ÐŽÐºÐžÐŒÐž, ÐºÐ°Ðº ÐŸÑÐ¿ÐŸÐ»ÐžÑÐŸÐ²Ð°ÐœÐœÑÐµ Ð³ÑÐ°ÐœÐž Greenstone.}  
+
+_textgreenstone_ [l=ru] {<p>
+<i>ÐÑÐžÐœÑÑÐŸÑÐœ</i>  - Ð¿ÐŸÐ»ÑÐŽÑÐ°Ð³ÐŸÑÐµÐœÐœÑÐ¹ ÐºÐ°ÐŒÐµÐœÑ, ÐºÐŸÑÐŸÑÑÐ¹ (Ð¿ÐŸÐŽÐŸÐ±ÐœÐŸ ÑÑÐŸÐŒÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐŒÑ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÑ) ÐžÐŒÐµÐµÑ ÑÐ²ÐŸÐµ Ð¿ÑÐŸÐžÑÑ
+ÐŸÐ¶ÐŽÐµÐœÐžÐµ Ð² ÐÐŸÐ²ÐŸÐ¹ ÐÐµÐ»Ð°ÐœÐŽÐžÐž. Ð ÑÑÐ°ÐŽÐžÑÐžÐŸÐœÐœÐŸÐŒ ÐŸÐ±ÑÐµÑÑÐ²Ðµ ÐŒÐ°ÐŸÑÐž ÐŸÐœ Ð±ÑÐ» ÑÐ°ÐŒÑÐŒ ÐŽÐŸÑÐŸÐ³ÐžÐŒ. ÐÐœ ÐŒÐŸÐ¶ÐµÑ Ð¿ÐŸÐ³Ð»ÐŸÑÐ°ÑÑ Ðž ÑÐŽÐµÑÐ¶ÐžÐ²Ð°ÑÑ <i>ÐÐ°Ð¹ÑÑÐ°,</i> ÑÐ²Ð»ÑÑÑÐžÐŒÑÑ ÐŽÑÑ
+ÐŸÐŒ ÐžÐ»Ðž ÑÐžÐ»ÐŸÐ¹ Ð¶ÐžÐ·ÐœÐž, ÐœÐ°ÐŽÐµÐ»ÐµÐœÐœÑÐ¹ ÑÑÐ°ÐŽÐžÑÐžÐŸÐœÐœÑÐŒÐž ÐŽÐŸÑÑÐŸÐžÐœÑÑÐ²Ð°ÐŒÐž, ÐºÐŸÑÐŸÑÑÐµ ÐŽÐµÐ»Ð°ÑÑ ÐµÐ³ÐŸ Ð²Ð¿ÐŸÐ»ÐœÐµ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐµÐœÐœÐŸÐ¹ ÑÐŒÐ±Ð»ÐµÐŒÐŸÐ¹ ÐŽÐ»Ñ Ð¿ÑÐŸÐŽÑÐºÑÐ° ÐŸÐ±ÑÐµÐ³ÐŸ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ - Ð¿ÑÐŸÐµÐºÑÐ° ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐºÐž. ÐÐ³ÐŸ Ð±Ð»ÐµÑÐº ÐŸÐ·ÐœÐ°ÑÐ°ÐµÑ ÐŒÐžÐ»ÐŸÑÐµÑÐŽÐžÐµ; ÐµÐ³ÐŸ Ð¿ÑÐŸÐ·ÑÐ°ÑÐœÐŸÑÑÑ - ÑÐµÑÑÐœÐŸÑÑÑ; ÐµÐ³ÐŸ ÐºÑÑÑÐžÐ·ÐœÐ° - Ñ
+ÑÐ°Ð±ÑÐŸÑÑÑ; Ð° ÐŸÑÑÑÑÐ¹ ÐºÑÐ°Ð¹ ÐŒÐŸÐ¶ÐµÑ ÐŸÐ·ÐœÐ°ÑÐ°ÑÑ Ð¿ÑÐ°Ð²ÐŸÑÑÐŽÐžÐµ. Ð ÐµÐ·ÐœÐ°Ñ ÑÐ°ÑÑÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÐ°Ñ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÑÐŒÐ±Ð»ÐµÐŒÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐ³ÐŸ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÑ Ð­Ð»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž Greenstone - ÑÑÐŸ <i>ÐÐ°ÑÑ</i>  ÐžÐ»Ðž Ð±ÐŸÑÑÐŸÐ²ÑÐºÐžÐ¹ ÐºÐ»ÑÐ±, Ðž  ÑÐµÐŒÐµÐ¹ÐœÐ°Ñ ÑÐµÐ»ÐžÐºÐ²ÐžÑ ÐŸÐŽÐœÐŸÐ³ÐŸ ÐžÐ· ÑÐ»ÐµÐœÐŸÐ² ÐœÐ°ÑÐµÐ³ÐŸ Ð¿ÑÐŸÐµÐºÑÐ°. Ð ÑÑÐºÐŸÐ¿Ð°ÑÐœÐŸÐŒ Ð±ÐŸÑ ÐµÐ³ÐŸ ÑÐµÐ°ÐºÑÐžÑ ÐŸÑÐµÐœÑ Ð±ÑÑÑÑÐ°, ÑÐŸÑÐœÐ°, Ðž ÐŸÑÐµÐœÑ Ð·Ð°ÐºÐŸÐœÑÐµÐœÐ°. ÐÐ°ÐŒ ÐœÑÐ°Ð²ÐžÑÑÑ ÐŽÑÐŒÐ°ÑÑ, ÑÑÐŸ ÑÑÐž ÐºÐ°ÑÐµÑÑÐ²Ð° ÑÐ°ÐºÐ¶Ðµ ÐŸÑÐœÐŸÑÑÑÑÑ Ðž Ðº ÐœÐ°ÑÐµÐŒÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐŒÑ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÑ, ÐŸÑÑÑÑÐ¹ ÐºÑÐ°Ð¹ Ð±ÑÐžÑÐ²Ñ -  <i>ÐÐ°ÑÑ,</i>  ÑÐžÐŒÐ²ÐŸÐ» ÑÐŸÐ³ÐŸ, ÑÑÐŸ ÐŒÑ ÐœÐ°Ñ
+ÐŸÐŽÐžÐŒÑÑ ÐœÐ° ÑÐ°ÐŒÐŸÐ¹ ÐºÑÐŸÐŒÐºÐµ ÑÐµÑ
+ÐœÐŸÐ»ÐŸÐ³ÐžÐž. 
+}  
+
+_textaboutgreenstone_ [l=ru] {<p>Greenstone - ÑÑÐŸ ÐºÐŸÐŒÐ¿Ð»ÐµÐºÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐ³ÐŸ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÑ ÐŽÐ»Ñ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ Ðž ÑÐ°ÑÐ¿ÑÐŸÑÑÑÐ°ÐœÐµÐœÐžÑ  ÑÐ»ÐµÐºÑÑÐŸÐœÐœÑÑ
+ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÑÐœÑÑ
+ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹. Ð­ÑÐ° ÑÐžÑÑÐµÐŒÐ° ÐŸÐ±ÐµÑÐ¿ÐµÑÐžÐ²Ð°ÐµÑ ÐœÐŸÐ²ÑÐ¹ ÑÐ¿ÐŸÑÐŸÐ± ÐŸÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÐž ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž ÐŽÐ»Ñ ÐŸÐ¿ÑÐ±Ð»ÐžÐºÐŸÐ²Ð°ÐœÐžÑ ÐœÐ° ÐºÐŸÐŒÐ¿Ð°ÐºÑ ÐŽÐžÑÐºÐ°Ñ
+, Ð»ÐŸÐºÐ°Ð»ÑÐœÑÑ
+ ÑÐµÑÑÑ
+ Ðž Ð² ÐÐœÑÐµÑÐœÐµÑÐµ. Greenstone ÑÐ°Ð·ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑÑÑ Ð² ÑÐ°ÐŒÐºÐ°Ñ
+ Ð¿ÑÐŸÐµÐºÑÐ° <b>ÐÐŸÐ²ÐŸÐ·ÐµÐ»Ð°ÐœÐŽÑÐºÐŸÐ¹ Ð­Ð»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž Ð£ÐœÐžÐ²ÐµÑÑÐžÑÐµÑÐ° ÐÐ°ÐžÐºÐ°ÑÐŸ</b>, Ð² ÑÐŸÑÑÑÐŽÐœÐžÑÐµÑÑÐ²Ðµ Ñ <b>Ð®ÐÐ­Ð¡ÐÐ</b> Ðž <b>ÐÐÐ Ð§ÐµÐ»ÐŸÐ²ÐµÑÐµÑÐºÐ°Ñ ÐÐœÑÐŸÑÐŒÐ°ÑÐžÑ</b> (Human Info). Ð­ÑÐŸ ÑÐ²ÐŸÐ±ÐŸÐŽÐœÐŸÐµ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐµ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐµ, Ñ ÐŸÑÐºÑÑÑÑÐŒÐž ÐžÑÑ
+ÐŸÐŽÐœÑÐŒÐž ÐºÐŸÐŽÐ°ÐŒÐž, Ðž ÐŽÐŸÑÑÑÐ¿ÐœÐŸ Ð¿ÐŸ Ð°ÐŽÑÐµÑÑ <a href="http://greenstone.org"> http://greenstone.org</a>, ÐœÐ° ÑÑÐ»ÐŸÐ²ÐžÑÑ
+ ÑÑÐ°ÐœÐŽÐ°ÑÑÐœÐŸÐ¹ ÐŸÐ±ÑÐµÑÑÐ²ÐµÐœÐœÐŸÐ¹ Ð»ÐžÑÐµÐœÐ·ÐžÐž (GNU)</p>. 
+
+<br>ÐŠÐµÐ»Ñ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐ³ÐŸ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÑ ÑÐ°ÑÑÐžÑÐžÑÑ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÐž Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐ¹, Ð² ÑÐ°ÑÑÐœÐŸÑÑÐž ÑÐœÐžÐ²ÐµÑÑÐžÑÐµÑÐŸÐ², Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐº, Ðž ÐŽÑÑÐ³ÐžÑ
+ ÑÑÑÐµÐ¶ÐŽÐµÐœÐžÐ¹ ÐŸÐ±ÑÐµÑÑÐ²ÐµÐœÐœÑÑ
+ ÑÐ»ÑÐ¶Ð±, ÑÑÐŸÐ±Ñ ÐŸÐœÐž ÑÐŒÐŸÐ³Ð»Ðž ÑÑÑÐŸÐžÑÑ ÑÐŸÐ±ÑÑÐ²ÐµÐœÐœÑÐµ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÑÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. Ð­Ð»ÐµÐºÑÑÐŸÐœÐœÑÐµ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž ÑÐ°ÐŽÐžÐºÐ°Ð»ÑÐœÐŸ Ð¿ÑÐµÐŸÐ±ÑÐ°Ð·ÑÑÑ ÑÐ¿ÐŸÑÐŸÐ±Ñ ÑÐ°ÑÐ¿ÑÐŸÑÑÑÐ°ÐœÐµÐœÐžÑ Ðž ÐŽÐŸÑÑÑÐ¿Ð° Ðº ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž Ð² ÑÐ°ÐŒÐºÐ°Ñ
+ Ð¿Ð°ÑÑÐœÐµÑÑÑÐ²Ð° Ð®ÐÐÐ¡ÐÐ Ðž ÑÐ°Ð·Ð»ÐžÑÐœÑÐŒÐž ÑÑÑÐµÐ¶ÐŽÐµÐœÐžÑÑ
+ Ð² ÐŸÐ±Ð»Ð°ÑÑÐž ÐŸÐ±ÑÐ°Ð·ÐŸÐ²Ð°ÐœÐžÑ, ÐœÐ°ÑÐºÐž Ðž ÐºÑÐ»ÑÑÑÑÑ Ð²ÐŸ Ð²ÑÐµÐŒ ÐŒÐžÑÐµ, Ðž ÐŸÑÐŸÐ±ÐµÐœÐœÐŸ Ð² ÑÐ°Ð·Ð²ÐžÐ²Ð°ÑÑÐžÑ
+ÑÑ ÑÑÑÐ°ÐœÐ°Ñ
+. ÐÑ ÐœÐ°ÐŽÐµÐµÐŒÑÑ, ÑÑÐŸ ÑÑÐŸ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐµ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐµ ÐŽÐ°ÑÑ ÑÐŸÐ»ÑÐŸÐº ÑÑÑÐµÐºÑÐžÐ²ÐœÐŸÐŒÑ ÑÐ°ÑÐ¿ÐŸÑÑÑÐ°ÐœÐµÐœÐžÑ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÑÑ
+ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐº ÐŽÐ»Ñ Ð¿ÐŸÐ²ÑÐµÐŒÐµÑÑÐœÐŸÐ³ÐŸ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž Ðž ÐµÐµ ÑÐ°Ð·ÐŒÐµÑÐµÐœÐžÑ ÐŽÐ»Ñ ÐŽÐŸÑÑÑÐ¿Ð° ÑÐžÑÐŸÐºÐžÑ
+ ÑÐ»ÐŸÐµÐ² ÐŸÐ±ÑÐµÑÑÐ²ÐµÐœÐœÐŸÑÑÐž. 
+</p>
+
+<p>Ð­ÑÐŸ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐµ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐµ ÑÐ°Ð·ÑÐ°Ð±ÐŸÑÐ°ÐœÐŸ Ðž ÑÐ°ÑÐ¿ÑÐŸÑÑÑÐ°ÐœÑÐµÑÑÑ Ñ Ð°Ð²Ð³ÑÑÑÐ° 2000 Ð³ÐŸÐŽÐ° ÐºÐ°Ðº Ð¿ÑÐŸÐŽÑÐºÑ  ÐŒÐµÐ¶ÐŽÑÐœÐ°ÑÐŸÐŽÐœÐŸÐ³ÐŸ ÑÐŸÐ²ÐŒÐµÑÑÐœÐŸÐ³ÐŸ ÑÐŸÑÑÑÐŽÐœÐžÑÐµÑÑÐ²Ð° ÐŒÐµÐ¶ÐŽÑ ÑÑÐµÐŒÑ ÑÑÐŸÑÐŸÐœÐ°ÐŒÐž. 
+
+</p>
+
+<p>
+<a href="http://nzdl.org"><b>ÐÑÐŸÐµÐºÑ ÐÐŸÐ²ÐŸÐ·ÐµÐ»Ð°ÐœÐŽÑÐºÐŸÐ¹ Ð­Ð»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž Ð£ÐœÐžÐ²ÐµÑÑÐžÑÐµÑÐ° ÐÐ°ÐžÐºÐ°ÑÐŸ</b></a>
+<br>
+ÐÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐµ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐµ Greenstone Ð²ÑÑÐŸÑÐ»ÐŸ ÐžÐ· ÑÑÐŸÐ³ÐŸ Ð¿ÑÐŸÐµÐºÑÐ°, Ðž ÑÑÐ° ÐžÐœÐžÑÐžÐ°ÑÐžÐ²Ð° Ð±ÑÐ»Ð° Ð¿ÐŸÐŽÐŽÐµÑÐ¶Ð°ÐœÐ° ÐºÐŸÐŒÐžÑÐµÑÐŸÐŒ Ð¿ÐŸ Ð¡Ð²ÑÐ·ÑÐŒ ÐÐŸÐ²ÐŸÐ·ÐµÐ»Ð°ÐœÐŽÑÐºÐŸÐ¹ ÐÐ°ÑÐžÐŸÐœÐ°Ð»ÑÐœÐŸÐ¹ ÐÐŸÐŒÐžÑÑÐžÐž Ð¿ÐŸ ÐŽÐµÐ»Ð°ÐŒ Ð®ÐÐÐ¡ÐÐ ÐºÐ°Ðº ÑÐ°ÑÑÑ Ð²ÐºÐ»Ð°ÐŽÐ° ÐÐŸÐ²ÐŸÐ¹ ÐÐµÐ»Ð°ÐœÐŽÐžÐž Ð² Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑ Ð®ÐÐÐ¡ÐÐ.
+</p>
+
+<p>
+<a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+class="logo"></a>
+<a href="http://www.unesco.org"><b>ÐÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÑ ÐÐ±ÑÐµÐŽÐžÐœÐµÐœÐœÑÑ
+ ÐÐ°ÑÐžÐ¹ Ð¿ÐŸ Ð²ÐŸÐ¿ÑÐŸÑÐ°ÐŒ ÐÐ±ÑÐ°Ð·ÐŸÐ²Ð°ÐœÐžÑ, ÐÐ°ÑÐºÐž Ðž ÐÑÐ»ÑÑÑÑÑ (Ð®ÐÐÐ¡ÐÐ)</b></a>
+<br>Ð Ð°ÑÐ¿ÑÐŸÑÑÑÐ°ÐœÐµÐœÐžÐµ Ðž ÐŽÐŸÑÑÑÐ¿ Ðº ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž ÐŸÐ± ÐŸÐ±ÑÐ°Ð·ÐŸÐ²Ð°ÐœÐžÐž, ÐœÐ°ÑÐºÐµ Ðž ÐºÑÐ»ÑÑÑÑÐµ Ð²ÐŸ Ð²ÑÐµÐŒ ÐŒÐžÑÐµ, ÐŸÑÐŸÐ±ÐµÐœÐœÐŸ Ð² ÑÐ°Ð·Ð²ÐžÐ²Ð°ÑÑÐžÑ
+ÑÑ ÑÑÑÐ°ÐœÐ°Ñ
+, ÑÐ²Ð»ÑÐµÑÑÑ ÐŸÑÐœÐŸÐ²ÐœÐŸÐ¹ ÑÐµÐ»ÑÑ Ð®ÐÐÐ¡ÐÐ, ÐŽÐŸÑÑÐžÐ³Ð°ÑÑÐµÐ¹ÑÑ Ð² ÑÐ°ÐŒÐºÐ°Ñ
+ ÐŒÐµÐ¶Ð¿ÑÐ°Ð²ÐžÑÐµÐ»ÑÑÑÐ²ÐµÐœÐœÐŸÐ¹ ÐÑÐŸÐ³ÑÐ°ÐŒÐŒÑ "ÐÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŽÐ»Ñ ÐÑÐµÑ
+". Ð¡ÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÑÑÐ°Ñ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ Ðž ÐŽÐŸÑÑÑÐ¿ Ðº ÑÑÐµÐŽÑÑÐ²Ð°ÐŒ ÐÐœÑÐŸÑÐŒÐ°ÑÐžÐŸÐœÐœÐŸ-ÐÐŸÐŒÐŒÑÐœÐžÐºÐ°ÑÐžÐŸÐœÐœÑÑ
+ Ð¢ÐµÑ
+ÐœÐŸÐ»ÐŸÐ³ÐžÐ¹, Ð² ÐŽÐ°ÐœÐœÐŸÐŒ ÐºÐŸÐœÑÐµÐºÑÑÐµ, ÑÐ²Ð»ÑÑÑÑÑ Ð²Ð°Ð¶ÐœÑÐŒÐž ÐžÐœÑÑÑÑÐŒÐµÐœÑÐ°ÐŒÐž.
+</p>
+
+<p>
+<a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>ÐÐÐ Ð§ÐµÐ»ÐŸÐ²ÐµÑÐµÑÐºÐ°Ñ ÐÐœÑÐŸÑÐŒÐ°ÑÐžÑ, ÐœÐ°Ñ
+ÐŸÐŽÑÑÐµÐµÑÑ Ð² ÐÐœÑÐ²ÐµÑÐ¿ÐµÐœÐµ, ÐÐµÐ»ÑÐ³ÐžÑ</b></a>
+<br>
+Ð­ÑÐŸÑ Ð¿ÑÐŸÐµÐºÑ ÑÐ°Ð±ÐŸÑÐ°ÐµÑ Ñ Ð°Ð³ÐµÐœÑÑÑÐ²Ð°ÐŒÐž ÐÐÐ Ðž ÐŽÑÑÐ³ÐžÐŒÐž ÐœÐµÐ¿ÑÐ°Ð²ÐžÑÐµÐ»ÑÑÑÐ²ÐµÐœÐœÑÐŒÐž ÐŸÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÑÐŒÐž, Ðž ÐžÐŒÐµÐµÑ Ð²ÑÑÐŸÐºÑÑ Ð²ÑÐµÐŒÐžÑÐœÑÑ ÑÐµÐ¿ÑÑÐ°ÑÐžÑ Ð² ÐŸÐ±Ð»Ð°ÑÑÐž ÑÐžÑÑÐŸÐ²ÐŸÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÑÐžÐž, Ð¿ÑÐµÐŽÑÑÐ°Ð²Ð»ÑÑÑÐµÐ¹ ÐžÐœÑÐµÑÐµÑ ÐŽÐ»Ñ ÑÐµÐ»ÐŸÐ²ÐµÑÐµÑÐºÐŸÐ³ÐŸ ÑÐ°Ð·Ð²ÐžÑÐžÑ, Ðž ÐŽÐµÐ»Ð°ÐµÑ ÐµÐµ ÑÐžÑÐŸÐºÐŸ-ÐŽÐŸÑÑÑÐ¿ÐœÐŸÐ¹ Ðž Ð±ÐµÑÐ¿Ð»Ð°ÑÐœÐŸÐ¹ ÐŽÐ»Ñ ÑÐ°Ð·Ð²ÐžÐ²Ð°ÑÑÐžÑ
+ÑÑ ÑÑÑÐ°Ðœ Ðž ÐŒÐµÑÐŸÐŽÐŸÐŒ Ð²ÐŸÐ·ÐŒÐµÑÐµÐœÐžÑ ÐžÐ·ÐŽÐµÑÐ¶ÐµÐº ÐŽÐ»Ñ ÐŽÑÑÐ³ÐžÑ
+.</p>}  
+
+
+_textdescrselcol_ [l=ru] {ÐÑÐ±ÐµÑÐžÑÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ}
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=ru] {ÐÐŽÐµÑÑ Ðž ÐœÐ° ÐŽÐŸÐŒÐ°ÑÐœÐµÐ¹ ÑÑÑÐ°ÐœÐžÑÐµ Ð±ÑÐŽÑÑ ÐŽÐ°Ð»ÐµÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑÑÑ ÑÐµÑÑÑÐµ ÐºÐœÐŸÐ¿ÐºÐž}
+
+_textnocollections_ [l=ru] {<p> Ð ÑÑÐŸÐ¹ ÑÑÑÐ°ÐœÐŸÐ²ÐºÐµ Greenstone ÐœÐµÑ ÐŽÐŸÑÑÑÐ¿ÐœÑÑ
+ ÐºÐŸÐ»ÐµÐºÑÐžÐ¹. Ð§ÑÐŸÐ±Ñ ÐŽÐŸÐ±Ð°Ð²ÐžÑÑ ÐœÐµÐºÐŸÑÐŸÑÑÐµ, ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ ÐžÐ»Ðž
+<ul><li>ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ <href = "_httppagecollector _ ">ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ</a>, ÐŽÐ»Ñ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ Ð¿ÑÐŸÑÑÐµÐ¹ÑÐµÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž
+<li>ÐžÐ»Ðž ÑÑÑÐ°ÐœÐŸÐ²ÐžÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ñ ÐºÐŸÐŒÐ¿Ð°ÐºÑ ÐŽÐžÑÐº, ÐµÑÐ»Ðž ÐÑ Ñ ÐœÐµÐ³ÐŸ ÑÑÑÐ°ÐœÐ°Ð²Ð»ÐžÐ²Ð°ÐµÑÐµ Greenstone</ul>}  
+
+_text1coll_ [l=ru] {ÐÐ°ÑÑÐŸÑÑÐ°Ñ ÑÑÑÐ°ÐœÐŸÐ²ÐºÐ° Greenstone ÑÐŸÐŽÐµÑÐ¶ÐžÑ 1 ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ}  
+
+_textmorecolls_ [l=ru] {ÐÐ°ÑÑÐŸÑÑÐ°Ñ ÑÑÑÐ°ÐœÐŸÐ²ÐºÐ° Greenstone ÑÐŸÐŽÐµÑÐ¶ÐžÑ _1_ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž/Ð¹}  
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=ru] {ÐÐœÐµÑÐœÑÑ ÑÑÑÐ»ÐºÐ°}
+_textlinknotfound_ [l=ru] {ÐÐœÑÑÑÐµÐœÐœÑÑ ÑÑÑÐ»ÐºÐ° ÐœÐµ ÐœÐ°Ð¹ÐŽÐµÐœÐ°}  
+
+_textextlinkcontent_ [l=ru] {<p>Ð¡ÑÑÐ»ÐºÐ°, ÐºÐŸÑÐŸÑÑÑ Ð²Ñ Ð²ÑÐ±ÑÐ°Ð»Ðž, ÑÐ²Ð»ÑÐµÑÑÑ Ð²ÐœÐµÑÐœÐµÐ¹ Ð¿ÐŸ ÐŸÑÐœÐŸÑÐµÐœÐžÑ Ðº Ð»ÑÐ±ÐŸÐ¹ ÐžÐ· Ð²ÑÐ±ÑÐ°ÐœÐœÑÑ
+ Ð² ÐœÐ°ÑÑÐŸÑÑÐµÐµ Ð²ÑÐµÐŒÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹. ÐÑÐ»Ðž ÐÑ Ð¶ÐµÐ»Ð°ÐµÑÐµ Ð¿ÐŸÐ¹ÑÐž Ð¿ÐŸ ÑÑÐŸÐ¹ ÑÑÑÐ»ÐºÐµ Ðž Ð²Ð°Ñ Ð±ÑÐ°ÑÐ·ÐµÑ ÐžÐŒÐµÐµÑ ÐŽÐŸÑÑÑÐ¿ Ðº ÑÐµÑÐž ÐÐœÑÐµÑÐœÐµÑ, ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ <a href="_nexturl_">   ÐŽÐ°Ð»ÐµÐµ Ð¿ÐµÑÐµÐ¹ÑÐž ÐœÐ° ÑÑÑ ÑÑÑÐ°ÐœÐžÑÑ </a>; ÐžÐœÐ°ÑÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ ÐºÐœÐŸÐ¿ÐºÑ "back/ÐœÐ°Ð·Ð°ÐŽ" Ð² Ð²Ð°ÑÐµÐŒ Ð±ÑÐ°ÑÐ·ÐµÑÐµ, ÑÑÐŸÐ±Ñ Ð²ÐµÑÐœÑÑÑÑÑ Ðº Ð¿ÑÐµÐŽÑÐŽÑÑÐµÐŒÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ.}  
+
+_textlinknotfoundcontent_ [l=ru] {ÐÐŸ Ð¿ÑÐžÑÐžÐœÐ°ÐŒ, ÐœÐ°Ñ
+ÐŸÐŽÑÑÐžÐŒÑÑ  Ð²ÐœÐµ ÐœÐ°ÑÐµÐ³ÐŸ ÐºÐŸÐœÑÑÐŸÐ»Ñ, Ð²ÐœÑÑÑÐµÐœÐœÑÑ ÑÑÑÐ»ÐºÐ°, ÐºÐŸÑÐŸÑÑÑ ÐÑ Ð²ÑÐ±ÑÐ°Ð»Ðž, ÐœÐµ ÑÑÑÐµÑÑÐ²ÑÐµÑ. ÐÐµÑÐŸÑÑÐœÐŸ ÑÑÐŸ ÐŸÐ±ÑÑÐ»ÐŸÐ²Ð»ÐµÐœÐŸ ÐŸÑÐžÐ±ÐºÐŸÐ¹ Ð² ÐžÑÑ
+ÐŸÐŽÐœÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ ÐºÐœÐŸÐ¿ÐºÑ  "back"  ÐÐ°ÑÐµÐ³ÐŸ Ð±ÑÐ°ÑÐ·ÐµÑÐ°, ÑÑÐŸÐ±Ñ Ð²ÐŸÐ·Ð²ÑÐ°ÑÐžÑÑÑÑ Ðº Ð¿ÑÐµÐŽÑÐŽÑÑÐµÐŒÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ.}
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=ru] {Ð¡ÑÑÐ»ÐºÐ° ÐœÐ° ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ " _2 _ " 
+Ð¡ÑÑÐ»ÐºÐ°, ÐºÐŸÑÐŸÑÑÑ Ð²Ñ Ð²ÑÐ±ÑÐ°Ð»Ðž, ÑÐ²Ð»ÑÐµÑÑÑ Ð²ÐœÐµÑÐœÐµÐ¹ Ðº " _collectionname _ " ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ (ÐŸÐœÐ° ÑÐ²ÑÐ·ÑÐ²Ð°ÐµÑÑÑ Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐµÐ¹ " _2 _ " ). ÐÑÐ»Ðž Ð²Ñ Ð¶ÐµÐ»Ð°ÐµÑÐµ Ð¿ÐµÑÐµÐ¹ÑÐž Ð¿ÐŸ ÑÑÐŸÐ¹ ÑÑÑÐ»ÐºÐµ Ðº ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž " _2 _ ", ÑÐŸ Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">    ÐžÐŽÑÐž ÐŽÐ°Ð»ÑÑÐµ ÐœÐ° ÑÑÑ ÑÑÑÐ°ÐœÐžÑÑ </a>; ÐžÐœÐ°ÑÐµ Ð²ÐŸÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµÑÑ ÐºÐœÐŸÐ¿ÐºÐŸÐ¹ "back/ÐœÐ°Ð·Ð°ÐŽ" Ð² Ð²Ð°ÑÐµÐŒ Ð±ÑÐ°ÑÐ·ÐµÑÐµ, ÑÑÐŸÐ±Ñ Ð²ÐµÑÐœÑÑÑÑÑ Ðº Ð¿ÑÐµÐŽÑÐŽÑÑÐµÐŒÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ. }  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=ru] {Ð­Ð»ÐµÐºÑÑÐŸÐœÐœÐ°Ñ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ° Greenstone}  
+
+_textusername_ [l=ru] {ÐÐŒÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ}
+_textpassword_ [l=ru] {ÐÐ°ÑÐŸÐ»Ñ}
+
+_textmustbelongtogroup_ [l=ru] {ÐÐ±ÑÐ°ÑÐžÑÐµ Ð²ÐœÐžÐŒÐ°ÐœÐžÐµ, ÑÑÐŸ ÐÑ ÐŽÐŸÐ»Ð¶ÐœÑ Ð¿ÑÐžÐœÐ°ÐŽÐ»ÐµÐ¶Ð°ÑÑ Ðº Ð³ÑÑÐ¿Ð¿Ðµ "_cgiargug_"   ÐŽÐŸÑÑÑÐ¿Ð° ÐœÐ° ÑÑÑ ÑÑÑÐ°ÐœÐžÑÑ.}
+
+_textmessageinvalid_ [l=ru] {Ð¡ÑÑÐ°ÐœÐžÑÐ° ÐºÐŸÑÑÑÑ Ð²Ñ Ð·Ð°Ð¿ÑÐ°ÑÐžÐ²Ð°ÐµÑÐµ ÑÑÐµÐ±ÑÐµÑ Ð°Ð²ÑÐŸÑÐžÐ·Ð°ÑÐžÐž<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_] <br>) ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ°, Ð²Ð²ÐµÐŽÐžÑÐµ ÐÐ°ÑÐµ ÐžÐŒÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ Ðž Ð¿Ð°ÑÐŸÐ»Ñ Greenstone.}  
+
+_textmessagefailed_ [l=ru] {ÐÐ²ÐµÐŽÐµÐœÐŸ ÐœÐµÐ²ÐµÑÐœÐŸÐµ ÐžÐŒÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ ÐžÐ»Ðž Ð¿Ð°ÑÐŸÐ»Ñ.}
+
+_textmessagedisabled_ [l=ru] {ÐÐ·Ð²ÐžÐœÐžÑÐµ, ÐœÐŸ Ð²Ð°ÑÐ° ÑÑÐµÑÐœÐ°Ñ Ð·Ð°Ð¿ÐžÑÑ Ð±ÑÐ»Ð° Ð·Ð°Ð±Ð»ÐŸÐºÐžÑÐŸÐ²Ð°ÐœÐ°. ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ° ÑÐ²ÑÐ¶ÐžÑÐµÑÑ Ñ Ð²ÐµÐ±-ÐŒÐ°ÑÑÐµÑÐŸÐŒ ÑÑÐŸÐ³ÐŸ ÑÐ°Ð¹ÑÐ°.}
+
+_textmessagepermissiondenied_ [l=ru] {ÐÐ·Ð²ÐžÐœÐžÑÐµ, ÐœÐŸ Ð²Ñ ÐœÐµ ÐŸÐ±Ð»Ð°ÐŽÐ°ÐµÑÐµ Ð¿ÐŸÐ»ÐœÐŸÐŒÐŸÑÐžÑÐŒÐž ÐŽÐŸÑÑÐ°ÑÐŸÑÐœÑÐŒÐž ÐŽÐ»Ñ ÐŽÐŸÑÑÑÐ¿Ð° Ðº Ð·Ð°Ð¿ÑÐŸÑÐµÐœÐœÐŸÐ¹ Ð²Ð°ÐŒÐž ÑÑÑÐ°ÐœÐžÑÐµ.}
+
+_textmessagestalekey_ [l=ru] {Ð¡ÑÑÐ»ÐºÐ°, Ð¿ÐŸ ÐºÐŸÑÐŸÑÐŸÐ¹ Ð²Ñ Ð¿ÑÐŸÑÐ»ÐµÐŽÐŸÐ²Ð°Ð»Ðž, Ð² ÐœÐ°ÑÑÐŸÑÑÐµÐµ Ð²ÑÐµÐŒÑ ÐŸÐ±ÐœÐŸÐ²Ð»ÐµÐœÐ°. ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ°, Ð²Ð²ÐµÐŽÐžÑÐµ Ð¿Ð°ÑÐŸÐ»Ñ ÐŽÐ»Ñ ÐŽÐŸÑÑÑÐ¿Ð° Ðº Ð·Ð°Ð¿ÑÐ°ÑÐžÐ²Ð°ÐµÐŒÐŸÐ¹ Ð²Ð°ÐŒÐž ÑÑÑÐ°ÐœÐžÑÐµ.}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=ru] {<br>
+ÐÐ°ÐœÐœÐ°Ñ ÑÑÑÐ°ÐœÐŸÐ²ÐºÐ°  Greenstone ÐœÐµ ÑÐŸÐŽÐµÑÐ¶ÐžÑ ÐœÐžÐºÐ°ÐºÐŸÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÑÐžÐž. Ð­ÑÐŸ ÐŒÐŸÐ¶ÐµÑ ÑÐ»ÑÑÐžÑÑÑÑ Ð¿ÐŸ Ð¿ÑÐžÑÐžÐœÐµ: 
+1. Greenstone Ð±ÑÐ»Ð° ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐ° Ñ CD-ROM, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ Ð¿Ð°ÑÐ°ÐŒÐµÑÑ ÐºÐŸÐŒÐ¿Ð°ÐºÑÐœÐŸÐ¹ ÑÑÑÐ°ÐœÐŸÐ²ÐºÐž. 
+2. Greenstone Ð±ÑÐ»Ð° ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐ° Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµÐŒ ÐŽÐžÑÑÑÐžÐ±ÑÑÐžÐ²ÐŸÐ², Ð·Ð°Ð³ÑÑÐ¶ÐµÐœÐœÑÑ
+ ÑÐµÑÐµÐ· ÑÐµÑÑ ÐÐœÑÐµÑÐœÐµÑ. 
+Ð Ð»ÑÐ±ÐŸÐŒ ÑÐ»ÑÑÐ°Ðµ Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ Ð¿ÐŸÐ»ÑÑÐžÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÑÐžÑ Ð»ÐžÐ±ÐŸ Ð² ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž docs ÐœÐ° ÑÑÑÐ°ÐœÐŸÐ²ÐŸÑÐœÐŸÐŒ  CD-ROM Greenstone Ð»ÐžÐ±ÐŸ ÐœÐ° ÑÐ°Ð¹ÑÐµ <a href="http://www.greenstone.org">http://www.greenstone.org</a>.}  
+
+_textuserguide_ [l=ru] {Ð ÑÐºÐŸÐ²ÐŸÐŽÑÑÐ²ÐŸ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ}
+_textinstallerguide_ [l=ru] {Ð ÑÐºÐŸÐ²ÐŸÐŽÑÑÐ²ÐŸ Ð¿ÐŸ ÐžÐœÑÑÐ°Ð»Ð»ÑÑÐžÐž}
+_textdeveloperguide_ [l=ru] {Ð ÑÐºÐŸÐ²ÐŸÐŽÑÑÐ²ÐŸ ÑÐ°Ð·ÑÐ°Ð±ÐŸÑÑÐžÐºÐ°}
+_textpaperguide_ [l=ru] {Ð ÑÐºÐŸÐ²ÐŸÐŽÑÑÐ²ÐŸ "ÐÑ Ð±ÑÐŒÐ°Ð³Ðž Ðº ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž"}  
+_textorganizerguide_ [l=ru] {ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµ ÐÑÐ³Ð°ÐœÐ°Ð¹Ð·ÐµÑÐ°}
+
+_textgsdocstitle_ [l=ru] {ÐÐŸÐºÑÐŒÐµÐœÑÐ°ÑÐžÑ Greenstone}  
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=ru] {ÐÐŸÑÑÑÐŸÐžÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ}  
+_textbildsuc_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÑÑÐ¿ÐµÑÐœÐŸ Ð¿ÐŸÑÑÑÐŸÐµÐœÐ°.}  
+_textviewbildsummary_ [l=ru] {ÐÐ»Ñ ÐŽÐ°Ð»ÑÐœÐµÐ¹ÑÐžÑ
+ ÐŽÐµÑÐ°Ð»ÐµÐ¹ Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ <a href="_httppagex_(bsummary)" target=_top>Ð¿ÐŸÑÐŒÐŸÑÑÐµÑÑ ÑÐµÐ·ÑÐŒÐµ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ</a> ÑÑÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž}  
+_textview_ [l=ru] {ÐÐŸÑÐŒÐŸÑÑÐµÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ}  
+
+_textbild1_ [l=ru] {ÐÐŽÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž: ÑÑÐŸ ÐŒÐŸÐ¶ÐµÑ Ð·Ð°ÐœÑÑÑ ÐœÐµÐºÐŸÑÐŸÑÐŸÐµ Ð²ÑÐµÐŒÑ. ÐÐžÐœÐžÑ ÑÑÐ°ÑÑÑÐ° Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ Ð²ÐœÐžÐ·Ñ Ð¿ÐŸÐºÐ°Ð·ÑÐ²Ð°ÐµÑ Ð¿ÑÐŸÐ³ÑÐµÑÑ ÐŸÐ¿ÐµÑÐ°ÑÐžÐž.}  
+
+_textbild2_ [l=ru] {Ð§ÑÐŸÐ±Ñ ÐŸÑÑÐ°ÐœÐŸÐ²ÐžÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÐµ Ð² Ð»ÑÐ±ÐŸÐµ Ð²ÑÐµÐŒÑ, ÐœÐ°Ð¶ÐŒÐžÑÐµ Ð·ÐŽÐµÑÑ. <br> ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ, ÐœÐ°ÐŽ ÐºÐŸÑÑÐŸÐ¹ Ð²Ñ ÑÐ°Ð±ÐŸÑÐ°ÐµÑÐµ, ÐŸÑÑÐ°ÐœÐµÑÑÑ ÐœÐµÐ¿ÐŸÐ²ÑÐµÐ¶ÐŽÑÐœÐœÐŸÐ¹.}  
+
+_textstopbuild_ [l=ru] {ÐŸÑÑÐ°ÐœÐŸÐ²ÐžÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÐµ}  
+
+_textbild3_ [l=ru] {ÐÑÐ»Ðž Ð²Ñ ÐŸÑÑÐ°Ð²ÐžÑÐµ ÑÑÑ ÑÑÑÐ°ÐœÐžÑÑ (Ðž ÐœÐµ ÐŸÑÑÐ°ÐœÐŸÐ²ÐžÑÐµ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÐµ Ð¿ÑÐž Ð¿ÐŸÐŒÐŸÑÐž "ÐŸÑÑÐ°ÐœÐŸÐ²ÐžÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÐµ"), ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ Ð±ÑÐŽÐµÑ Ð¿ÑÐŸÐŽÐŸÐ»Ð¶Ð°ÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÐµ Ðž Ð±ÑÐŽÐµÑ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐ° Ð¿ÐŸ ÐŒÐµÑÐµ ÑÐŽÐ°ÑÐœÐŸÐ³ÐŸ Ð·Ð°Ð²ÐµÑÑÐµÐœÐžÑ.}  
+
+_textbuildcancelled_ [l=ru] {ÐÐŸÑÑÑÐŸÐµÐœÐžÐµ ÐŸÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐŸ.}  
+
+_textbildcancel1_ [l=ru] {ÐÑÐŸÑÐµÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ð±ÑÐ» ÐŸÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœ. ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ Ð¶ÑÐ»ÑÑÑ ÐºÐœÐŸÐ¿ÐºÑ Ð²ÐœÐžÐ·Ñ ÐŽÐ»Ñ ÐžÐ·ÐŒÐµÐœÐµÐœÐžÑ Ð²Ð°ÑÐµÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐžÐ»Ðž ÑÑÐŸÐ±Ñ Ð¿ÐµÑÐµÐ·Ð°Ð¿ÑÑÑÐžÑÑ Ð¿ÑÐŸÑÐµÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ.}  
+
+_textbsupdate1_ [l=ru] {ÐÐ±ÐœÐŸÐ²Ð»ÐµÐœÐžÐµ ÑÑÐ°ÑÑÑÐ° Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ ÑÐµÑÐµÐ· 1 ÑÐµÐºÑÐœÐŽÑ}  
+_textbsupdate2_ [l=ru] {ÐÐ±ÐœÐŸÐ²Ð»ÐµÐœÐžÐµ ÑÑÐ°ÑÑÑÐ° Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ ÑÐµÑÐµÐ· }  
+_textseconds_ [l=ru] {ÑÐµÐºÑÐœÐŽÑ}  
+
+_textfailmsg11_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐœÐµ ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐ°, ÑÐ°Ðº ÐºÐ°Ðº ÐœÐµ ÑÐŸÐŽÐµÑÐ¶ÐžÑÐŽÐ°ÐœÐœÑÑ
+. ÐÑÐŸÐ²ÐµÑÑÑÐµ, ÑÑÐŸ Ñ
+ÐŸÑÑ Ð±Ñ ÐŸÐŽÐœÐ° ÐžÐ· ÐŽÐžÑÐµÐºÑÐŸÑÐžÐ¹, ÐºÐŸÑÐŸÑÑÑ Ð²Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐžÐ»Ðž Ð² <i>ÐžÑÑ
+ÐŸÐŽÐœÑÑ
+  ÐŽÐ°ÐœÐœÑÑ
+</i>, ÑÑÑÐµÑÑÐ²ÑÐµÑ, Ðž ÑÑÐŸ ÑÑÐŸ ÑÐžÐ¿,  ÐžÐ»Ðž  (Ð² ÑÐ»ÑÑÐ°Ðµ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž) ÑÐŸÐŽÐµÑÐ¶ÐžÑ ÑÐ°Ð¹Ð»Ñ ÑÐžÐ¿Ð°, ÐºÐŸÑÐŸÑÑÐµ ÐÑÐžÐœÑÑÐŸÑÐœ ÐŒÐŸÐ¶ÐµÑ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÑÑ.}  
+
+_textfailmsg21_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐœÐµ ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐ° (ÑÐ±ÐŸÐ¹ import.pl)}  
+_textfailmsg31_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐœÐµ ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐ° (ÑÐ±ÐŸÐ¹ buildcol.pl)}  
+_textfailmsg41_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÑÑÐ¿ÐµÑÐœÐŸ  Ð¿ÐŸÑÑÑÐŸÐµÐœÐ°, ÐœÐŸ ÐœÐµ ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐ°}  
+_textfailmsg71_ [l=ru] {ÐÐŸ Ð²ÑÐµÐŒÑ Ð¿ÐŸÐ¿ÑÑÐºÐž Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ Ð²Ð°ÑÐµÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ð¿ÑÐŸÐžÐ·ÐŸÑÐ»Ð° ÐœÐµÐ¿ÑÐµÐŽÐ²ÐžÐŽÐµÐœÐœÐ°Ñ ÐŸÑÐžÐ±ÐºÐ°}  
+
+
+_textblcont_ [l=ru] {Ð ÐµÐ³ÐžÑÑÑÐ°ÑÐžÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ ÑÐŸÐŽÐµÑÐ¶ÐžÑ ÑÐ»ÐµÐŽÑÑÑÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ:}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=ru] {Ð¡ÑÑÑÐºÑÑÑÐ° Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ}
+_textmore_ [l=ru] {ÐŽÐ°Ð»ÐµÐµ}
+_textinfo_ [l=ru] {ÐÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž}
+_textsrce_ [l=ru] {ÐÑÑÐŸÑÐœÐžÐº ÐŽÐ°ÐœÐœÑÑ
+}
+_textconf_ [l=ru] {ÐÐŸÐœÑÐžÐ³ÑÑÐžÑÐŸÐ²Ð°ÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž}
+_textdel_ [l=ru] {Ð£ÐŽÐ°Ð»ÐžÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ}  
+_textexpt_ [l=ru] {Ð­ÐºÑÐ¿ÐŸÑÑÐžÑÑÐµÐŒÐ°Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ}  
+
+_textdownloadingfiles_ [l=ru] {ÐÐ°Ð³ÑÑÐ·ÐºÐ° ÑÐ°Ð¹Ð»ÐŸÐ²...}
+_textimportingcollection_ [l=ru] {ÐÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž...}
+_textbuildingcollection_ [l=ru] {ÐÐŸÑÑÑÐŸÐµÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž...}
+_textcreatingcollection_ [l=ru] {Ð¡ÐŸÐ·ÐŽÐ°ÐœÐžÐµ ÐºÐŸÐ»ÐµÐºÑÐžÐž...}
+
+_textcollectorblurb_ [l=ru] {<i>ÐÐµÑÐŸ ÑÐžÐ»ÑÐœÐµÐµ ÐŒÐµÑÐ°!
+<br> ÐÐŸÑÑÑÐŸÐµÐœÐžÐµ Ðž ÑÐ°ÑÐ¿ÑÐŸÑÑÑÐ°ÐœÐµÐœÐžÐµ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐŸÐœÐœÑÑ
+ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹ ÑÑÐµÐ±ÑÐµÑ ÐŸÑÐ²ÐµÑÑÑÐ²ÐµÐœÐœÐŸÑÑÐž, ÐºÐŸÑÐŸÑÑÑ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐÑ Ð¿ÐŸÐ¶ÐµÐ»Ð°ÐµÑÐµ ÐŸÑÑÐ°Ð·ÐžÑÑ ÐŽÐŸ ÐœÐ°ÑÐ°Ð»Ð° ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. 
+Ð¡ÑÑÐµÑÑÐ²ÑÑÑ Ð¿ÑÐ°Ð²ÐŸÐ²ÑÐµ Ð²ÐŸÐ¿ÑÐŸÑÑ Ð°Ð²ÑÐŸÑÑÐºÐŸÐ³ÐŸ Ð¿ÑÐ°Ð²Ð°: Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÑ ÐŽÐŸÑÑÑÐ¿Ð° Ðº ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒ ÐœÐµ ÐŸÐ·ÐœÐ°ÑÐ°ÐµÑ, ÑÑÐŸ ÐÑ ÐžÐŒÐµÐµÑÐµ Ð¿ÐŸÐ»ÐœÐŸÐµ Ð¿ÑÐ°Ð²ÐŸ ÐžÑ
+ ÑÐ°ÑÐ¿ÑÐŸÑÑÑÐ°ÐœÑÑÑ. ÐÑÑÑ ÑÐŸÑÐžÐ°Ð»ÑÐœÑÐµ Ð²ÐŸÐ¿ÑÐŸÑÑ: ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐŽÐŸÐ»Ð¶ÐœÑ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐŸÐ²Ð°ÑÑ Ð·Ð°ÐºÐ°Ð·Ñ ÑÐŸÐŸÐ±ÑÐµÑÑÐ²Ð°, Ð¿ÑÐµÐŽÐŸÑÑÐ°Ð²ÐžÐ²ÑÐµÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ.
+Ð¢Ð°ÐºÐ¶Ðµ ÐžÐŒÐµÑÑÑÑ ÑÑÐžÑÐµÑÐºÐžÐµ Ð°ÑÐ¿ÐµÐºÑÑ: ÐœÐµÐºÐŸÑÐŸÑÑÐµ Ð²ÐµÑÐž ÐœÐµ ÐŒÐŸÐ³ÑÑ Ð±ÑÑÑ ÐŽÐŸÑÑÑÐ¿ÐœÑ ÐŽÑÑÐ³ÐžÐŒ.
+<br> ÐÑÐŽÑÑÐµ ÐŸÑÐµÐœÑ Ð²ÐœÐžÐŒÐ°ÑÐµÐ»ÑÐœÑ Ðº ÑÐžÐ»Ðµ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ ÐµÐµ ÐŒÑÐŽÑÐŸ.
+</i>
+}
+
+_textcb1_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ Ð¿ÐŸÐŒÐŸÐ¶ÐµÑ Ð²Ð°ÐŒ ÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÑÑ ÐœÐŸÐ²ÑÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž, ÐŽÐŸÐ¿ÐŸÐ»ÐœÑÑÑ ÐžÐ»Ðž ÐžÐ·ÐŒÐµÐœÑÑÑ ÑÑÑÐµÑÑÐ²ÑÑÑÐžÐµ, ÐžÐ»Ðž ÑÐŽÐ°Ð»ÐžÑÑ ÐžÑ
+ ÑÐŸÐ²ÑÐµÐŒ. ÐÐ»Ñ ÑÐŸÐ³ÐŸ ÑÑÐŸÐ±Ñ ÑÐŽÐµÐ»Ð°ÑÑ ÑÑÐŸ Ð²Ð°ÐŒ Ð¿ÑÐžÐŽÐµÑÑÑ Ð¿ÑÐŸÐ¹ÑÐž ÑÐµÑÐµÐ· Ð¿ÐŸÑÐ»ÐµÐŽÐŸÐ²Ð°ÑÐµÐ»ÑÐœÐŸÑÑÑ ÐÐµÐ±-ÑÑÑÐ°ÐœÐžÑ Ðž Ð¿ÑÐµÐŽÐŸÑÑÐ°Ð²ÐžÑÑ Ð·Ð°Ð¿ÑÐ°ÑÐžÐ²Ð°ÐµÐŒÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ. }
+
+_textcb2_ [l=ru] {Ð¡ÐœÐ°ÑÐ°Ð»Ð° Ð²Ñ ÐŽÐŸÐ»Ð¶ÐœÑ ÑÐµÑÐžÑÑ, ÑÑÐŸ Ð²Ñ Ñ
+ÐŸÑÐžÑÐµ Ð¿ÑÐµÐŽÐ¿ÑÐžÐœÑÑÑ:}
+_textcnc_ [l=ru] {ÑÐŸÐ·ÐŽÐ°ÑÑ ÐœÐŸÐ²ÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ}
+_textwec_ [l=ru] {ÑÐ°Ð±ÐŸÑÐ°ÑÑ Ñ ÑÑÑÐµÑÑÐ²ÑÑÑÐµÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐµÐ¹, ÐŽÐŸÐ±Ð°Ð²ÐžÑÑ ÐŽÐ°ÐœÐœÑÐµ ÐžÐ»Ðž ÑÐŽÐ°Ð»ÐžÑÑ.}
+
+_textcb3_ [l=ru] {Ð ÑÐ»ÑÑÐ°Ðµ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ ÐœÐŸÐ²ÐŸÐ¹ ÐžÐ»Ðž ÐŒÐŸÐŽÐžÑÐžÐºÐ°ÑÐžÐž ÑÑÑÐµÑÑÐ²ÑÑÑÐµÐ¹ Ð²Ð°ÐŒ ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÐŸ Ð¿ÑÐŸÐ¹ÑÐž ÑÐµÑÐµÐ· Ð¿ÑÐŸÑÐµÐŽÑÑÑ Ð°Ð²ÑÐŸÑÐžÐ·Ð°ÑÐžÐž. Ð­ÑÐŸ Ð·Ð°ÑÐžÑÐžÑ Ð²Ð°Ñ ÐŸÑ Ð¿ÐŸÑÑÐŸÑÐŸÐœÐœÐµÐ³ÐŸ Ð²ÑÐŸÑÐ¶ÐµÐœÐžÑ ÐœÐ° Ð²Ð°Ñ ÐºÐŸÐŒÐ¿ÑÑÑÐµÑ Ðž ÐœÐµ Ð¿ÐŸÐ·Ð²ÐŸÐ»ÐžÑ ÐžÑÐ¿ÐŸÑÑÐžÑÑ ÐžÐ»Ðž ÐžÐ·ÐŒÐµÐœÐžÑÑ Ð²Ð°ÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ. ÐÐ±ÑÐ°ÑÐžÑÐµ Ð²ÐœÐžÐŒÐ°ÐœÐžÐµ: ÐžÐ· ÑÐŸÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ Ð±ÐµÐ·ÐŸÐ¿Ð°ÑÐœÐŸÑÑÐž Ð²Ñ Ð±ÑÐŽÐµÑÐµ Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐž Ð·Ð°ÑÐµÐ³ÐžÑÑÑÐžÑÐŸÐ²Ð°ÐœÑ, Ðž ÐºÐ°Ðº ÑÐŸÐ»ÑÐºÐŸ Ð¿ÐµÑÐžÐŸÐŽ Ð² 30 ÐŒÐžÐœÑÑ ÐžÑÑÐµÐºÐ°ÐµÑ Ñ ÐŒÐŸÐŒÐµÐœÑÐ° Ð²Ð°ÑÐµÐ³ÐŸ Ð²Ñ
+ÐŸÐ¶ÐŽÐµÐœÐžÑ, Ð²Ñ ÐŽÐŸÐ»Ð¶ÐœÑ Ð±ÑÐŽÐµÑÐµ Ð¿ÐŸÐ²ÑÐŸÑÐœÐŸ Ð¿ÑÐŸÐ¹ÑÐž Ð¿ÑÐŸÑÐµÐŽÑÑÑ Ð°Ð²ÑÐŸÑÐžÐ·Ð°ÑÐžÐž. ÐÑÐ»Ðž ÑÑÐŸ Ð¿ÑÐŸÐžÐ·ÐŸÑÐ»ÐŸ - ÐœÐµ Ð²ÐŸÐ»ÐœÑÐ¹ÑÐµÑÑ! - ÐÑ Ð±ÑÐŽÐµÑÐµ ÑÐœÐŸÐ²Ð° Ð¿ÑÐžÐ³Ð»Ð°ÑÐµÐœÑ Ð²ÐŸÐ¹ÑÐž Ðž ÑÐŒÐŸÐ¶ÐµÑÐµ Ð¿ÑÐŸÐŽÐŸÐ»Ð¶ÐžÑÑ Ñ  ÑÐŸÐ³ÐŸ ÐŒÐŸÐŒÐµÐœÑÐ°, Ð³ÐŽÐµ ÐÑ ÐŸÑÑÐ°ÐœÐŸÐ²ÐžÐ»ÐžÑÑ. 
+}
+
+_textcb4_ [l=ru] {ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ°, Ð²Ð²ÐµÐŽÐžÑÐµ ÑÐ²ÐŸÐµ ÐžÐŒÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ Ðž Ð¿Ð°ÑÐŸÐ»Ñ ÐŽÐ»Ñ Greenstone Ðž ÐœÐ°Ð¶ÐŒÐžÑÐµ ÐœÐ° ÐºÐœÐŸÐ¿ÐºÑ Ð¿ÐŸÐŽÑÐ²ÐµÑÐ¶ÐŽÐµÐœÐžÑ. }  
+
+_textfsc_ [l=ru] {Ð¡ÐœÐ°ÑÐ°Ð»Ð° ÑÐºÐ°Ð¶ÐžÑÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ, Ñ ÐºÐŸÑÐŸÑÐŸÐ¹ Ð²Ñ Ñ
+ÐŸÑÐžÑÐµ ÑÐ°Ð±ÐŸÑÐ°ÑÑ (ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž, Ð·Ð°ÑÐžÑÐµÐœÐœÑÐµ ÐŸÑ Ð·Ð°Ð¿ÐžÑÐž, ÐœÐµ Ð±ÑÐŽÑÑ Ð¿ÐŸÑÐ²Ð»ÑÑÑÑÑ Ð² ÑÑÐŸÐŒ ÑÐ¿ÐžÑÐºÐµ). }
+
+_textwtc_ [l=ru] {Ð¡ Ð²ÑÐ±ÑÐ°ÐœÐœÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐµÐ¹ Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ:}
+_textamd_ [l=ru] {ÐÐŸÐ±Ð°Ð²ÐžÑÑ ÐŽÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÑÐµ ÐŒÐ°ÑÐµÑÐžÐ°Ð»Ñ Ðž Ð¿ÐµÑÐµÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ}
+_textetc_ [l=ru] {ÐÑÑÐµÐŽÐ°ÐºÑÐžÑÐŸÐ²Ð°ÑÑ ÑÐ°Ð¹Ð» ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐž Ðž Ð¿ÐŸÑÑÑÐŸÐžÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ Ð·Ð°ÐœÐŸÐ²ÐŸ}
+_textdtc_ [l=ru] {ÐÐŸÐ»ÐœÐŸÑÑÑÑ ÑÐŽÐ°Ð»ÐžÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ}
+_textetcfcd_ [l=ru] {Ð­ÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐŽÐ»Ñ Ð·Ð°Ð¿ÐžÑÐž ÐœÐ° ÑÐ°ÐŒÐŸÐ·Ð°Ð¿ÑÑÐºÐ°ÑÑÐžÐ¹ÑÑ CD-ROM Ð¿ÐŸÐŽ ÑÐ¿ÑÐ°Ð²Ð»ÐµÐœÐžÐµÐŒ Windows }
+_textcaec_ [l=ru] {ÐÐ·ÐŒÐµÐœÐµÐœÐžÐµ ÑÑÑÐµÑÑÐ²ÑÑÑÐµÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.}
+_textnwec_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÐž Ñ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÑÑ Ð·Ð°Ð¿ÐžÑÐž ÐœÐµ ÐŽÐŸÑÑÑÐ¿ÐœÑ ÐŽÐ»Ñ ÐžÐ·ÐŒÐµÐœÐµÐœÐžÑ }
+_textcianc_ [l=ru] {Ð¡ÐŸÐ·ÐŽÐ°ÐœÐžÐµ ÐœÐŸÐ²ÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.}
+_texttsosn_ [l=ru] {ÐÐŸÑÐ»ÐµÐŽÐŸÐ²Ð°ÑÐµÐ»ÑÐœÐŸÑÑÑ ÑÐ°Ð³ÐŸÐ², ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÑÑ
+ ÐŽÐ»Ñ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ ÐœÐŸÐ²ÐŸÐ¹ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÑÐœÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž:}  
+_textsin_ [l=ru] {Ð£ÐºÐ°Ð¶ÐžÑÐµ ÐžÐŒÑ (Ðž Ð»ÑÐ±ÑÑ ÑÐ²ÑÐ·Ð°ÐœÐœÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ)}
+_textswts_ [l=ru] {Ð£ÐºÐ°Ð¶ÐžÑÐµ ÐžÑÑÐŸÑÐœÐžÐº ÐŽÐ°ÐœÐœÑÑ
+, ÐžÐ· ÐºÐŸÑÐŸÑÑÑ
+ ÑÐŸÑÐŒÐžÑÑÐµÑÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ}
+_textatco_ [l=ru] {ÐÐŸÑÑÐµÐºÑÐžÑÐŸÐ²ÐºÐ° ÐŸÐ¿ÑÐžÐ¹ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐž (ÑÐŸÐ»ÑÐºÐŸ ÐŽÐ»Ñ ÐŸÐ¿ÑÑÐœÑÑ
+ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐ¹)}
+_textbtc_ [l=ru] {"ÐÐŸÑÑÑÐŸÐžÑÑ" ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ (ÑÐŒ. ÐœÐžÐ¶Ðµ)}
+_textpvyh_ [l=ru] {Ð¡ Ð³ÐŸÑÐŽÐŸÑÑÑÑ ÑÐ°ÑÑÐŒÐŸÑÑÐžÑÐµ ÑÐµÐ·ÑÐ»ÑÑÐ°Ñ ÑÐŸÐ·ÐŽÐ°ÐœÐœÑÐ¹ Ð²Ð°ÑÐžÐŒÐž ÑÑÐºÐ°ÐŒÐž.}
+
+_texttfsiw_ [l=ru] {Ð§ÐµÑÐ²ÐµÑÑÑÐ¹ ÑÐ°Ð³ - ÑÑÐŸ ÑÐ°Ð±ÐŸÑÐ° Ð²Ð°ÑÐµÐ³ÐŸ ÐºÐŸÐŒÐ¿ÑÑÑÐµÑÐ°. Ð Ð¿ÑÐŸÑÐµÑÑÐµ "ÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÐœÐžÑ" ÐºÐŸÐŒÐ¿ÑÑÑÐµÑ ÑÐŸÐ·ÐŽÐ°ÐµÑ Ð²ÑÐµ ÐžÐœÐŽÐµÐºÑÑ Ðž ÑÐŸÐ±ÐžÑÐ°ÐµÑ Ð²ÐŒÐµÑÑÐµ Ð»ÑÐ±ÑÑ ÐŽÑÑÐ³ÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ. ÐÐŸ ÑÐœÐ°ÑÐ°Ð»Ð° ÐÑ ÐŽÐŸÐ»Ð¶ÐœÑ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐžÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ. }
+
+_textadab_ [l=ru] {ÐÐžÐ¶Ðµ Ð¿ÐŸÑÐ²ÐžÑÑÑ ÐŽÐžÐ°Ð³ÑÐ°ÐŒÐŒÐ°, ÐºÐŸÑÐŸÑÐ°Ñ Ð¿ÐŸÐŒÐŸÐ¶ÐµÑ Ð²Ð°ÐŒ Ð¿ÑÐŸÑÐ»ÐµÐŽÐžÑÑ, ÐœÐ° ÐºÐ°ÐºÐŸÐŒ ÑÑÐ°Ð¿Ðµ Ð²Ñ ÐœÐ°Ñ
+ÐŸÐŽÐžÑÐµÑÑ. ÐÐµÐ»ÐµÐœÐ°Ñ ÐºÐœÐŸÐ¿ÐºÐ° - ÑÑÐŸ ÑÐ°, ÐºÐŸÑÐŸÑÑÑ Ð²Ñ ÐœÐ°Ð¶ÐžÐŒÐ°ÐµÑÐµ, ÑÑÐŸÐ±Ñ Ð¿ÑÐŸÐŽÐŸÐ»Ð¶ÐžÑÑ  Ð¿ÐŸÑÐ»ÐµÐŽÐŸÐ²Ð°ÑÐµÐ»ÑÐœÐŸÑÑÑ Ð²ÑÐ¿ÐŸÐ»ÐœÐµÐœÐžÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑ. ÐÐŸ ÐŒÐµÑÐµ Ð¿ÑÐŸÐŽÐ²ÐžÐ¶ÐµÐœÐžÑ Ð¿ÑÐŸÑÐµÑÑÐ° ÑÐ²ÐµÑ ÐºÐœÐŸÐ¿ÐºÐž ÐžÐ·ÐŒÐµÐœÐžÑÑÑ ÐœÐ° Ð¶ÐµÐ»ÑÑÐ¹. ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ Ð²ÐŸÐ·Ð²ÑÐ°ÑÐžÑÑÑÑ Ðº Ð¿ÑÐµÐŽÑÐŽÑÑÐµÐ¹ ÑÑÑÐ°ÐœÐžÑÐµ, ÐœÐ°Ð¶ÐžÐŒÐ°Ñ ÐœÐ° ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÑÑÑÑ Ð¶ÐµÐ»ÑÑÑ ÐºÐœÐŸÐ¿ÐºÑ Ð² ÐŽÐžÐ°Ð³ÑÐ°ÐŒÐŒÐµ. }
+
+_textwyar_ [l=ru] {ÐÐŸÐ³ÐŽÐ° ÐÑ Ð³ÐŸÑÐŸÐ²Ñ, ÐœÐ°Ð¶ÐŒÐžÑÐµ Ð·ÐµÐ»ÐµÐœÑÑ ÐºÐœÐŸÐ¿ÐºÑ "ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž", ÑÑÐŸÐ±Ñ ÐœÐ°ÑÐ°ÑÑ ÑÐŸÐ·ÐŽÐ°Ð²Ð°ÑÑ Ð²Ð°ÑÑ ÐœÐŸÐ²ÑÑ ÑÐžÑÑÐŸÐ²ÑÑ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÑÐœÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ!}
+
+_textcnmbs_ [l=ru] {ÐÐŒÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐŽÐŸÐ»Ð¶ÐœÐŸ Ð±ÑÑÑ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐŸ}
+_texteambs_ [l=ru] {ÐÐŽÑÐµÑ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ ÐŽÐŸÐ»Ð¶ÐµÐœ Ð±ÑÑÑ ÑÐºÐ°Ð·Ð°Ðœ}
+_textpsea_ [l=ru] {ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ°, ÑÐºÐ°Ð¶ÐžÑÐµ Ð°ÐŽÑÐµÑ ÑÐ».Ð¿ÐŸÑÑÑ Ð² Ð²ÐžÐŽÐµ: usename@domain}
+_textdocmbs_ [l=ru] {ÐÐ¿ÐžÑÐ°ÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐŽÐŸÐ»Ð¶ÐœÐŸ Ð±ÑÑÑ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐŸ}
+
+_textwcanc_ [l=ru] {ÐÑÐž ÑÐŸÐ·ÐŽÐ°ÐœÐžÐž ÐœÐŸÐ²ÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ð²Ñ ÐŽÐŸÐ»Ð¶ÐœÑ Ð²Ð²ÐµÑÑÐž ÐœÐµÐŒÐœÐŸÐ³ÐŸ Ð¿ÑÐµÐŽÐ²Ð°ÑÐžÑÐµÐ»ÑÐœÐŸÐ¹ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž ÐŸÐ± ÐžÑÑ
+ÐŸÐŽÐœÑÑ
+ ÐŽÐ°ÐœÐœÑÑ
+. Ð­ÑÐŸÑ Ð¿ÑÐŸÑÐµÑÑ ÑÑÑÑÐºÑÑÑÐžÑÐŸÐ²Ð°Ðœ ÐºÐ°Ðº ÑÑÐŽ Ð²ÐµÐ±-ÑÑÑÐ°ÐœÐžÑ, Ð·Ð° ÐºÐŸÑÐŸÑÑÐŒÐž ÐœÐ°Ð±Ð»ÑÐŽÐ°ÐµÑ ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ. ÐÐ±Ð»Ð°ÑÑÑ Ð²ÐœÐžÐ·Ñ ÑÑÑÐ°ÐœÐžÑÑ Ð¿ÐŸÐºÐ°Ð·ÑÐ²Ð°ÐµÑ ÐÐ°ÐŒ Ð¿ÐŸÑÐ»ÐµÐŽÐŸÐ²Ð°ÑÐµÐ»ÑÐœÐŸÑÑÑ ÑÑÑÐ°ÐœÐžÑ ÐŽÐŸ ÐŒÐŸÐŒÐµÐœÑÐ° ÐŸÐºÐŸÐœÑÐ°ÐœÐžÑ Ð¿ÑÐŸÑÐµÑÑÐ°. }
+
+_texttfc_ [l=ru] {ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž}
+
+_texttctiasp_ [l=ru] {ÐÐ°Ð³ÐŸÐ»ÐŸÐ²ÐŸÐº ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž - ÐºÐŸÑÐŸÑÐºÐ°Ñ ÑÑÐ°Ð·Ð°, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÐ°Ñ Ð²ÑÑÐŽÑ Ð² ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐµ, ÑÑÐŸÐ±Ñ ÐžÐŽÐµÐœÑÐžÑÐžÑÐžÑÐŸÐ²Ð°ÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. ÐÑÐžÐŒÐµÑ ÐÐ°Ð³ÐŸÐ»ÐŸÐ²ÐºÐ°: "Ð¢ÐµÑ
+ÐœÐžÑÐµÑÐºÐžÐ¹ ÐŸÑÑÐµÑ Ð¿ÐŸ Ð¿ÑÐŸÐµÐºÑÐ°ÐŒ ÐŸÑÐŽÐµÐ»Ð°"  Ðž  "ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ° Ð³ÑÐŒÐ°ÐœÐžÑÐ°ÑÐœÐŸÐ³ÐŸ ÑÐ°Ð·Ð²ÐžÑÐžÑ" }  
+
+_textcea_ [l=ru] {ÐÐŸÐœÑÐ°ÐºÑÐœÑÐ¹ Ð°ÐŽÑÐµÑ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ:}
+
+_textteas_ [l=ru] {Ð­ÑÐŸÑ Ð°ÐŽÑÐµÑ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÐµÑ Ð¿ÐµÑÐ²ÑÑ ÑÐŸÑÐºÑ ÐºÐŸÐœÑÐ°ÐºÑÐ° ÐŽÐ»Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. ÐÑÐ»Ðž Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐµ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐµ Greenstone ÐŸÐ±ÐœÐ°ÑÑÐ¶ÐžÐ²Ð°ÐµÑ Ð¿ÑÐŸÐ±Ð»ÐµÐŒÑ, ÐŽÐžÐ°Ð³ÐœÐŸÑÑÐžÑÐµÑÐºÐŸÐµ ÑÐŸÐŸÐ±ÑÐµÐœÐžÐµ Ð¿ÐŸÑÑÐ»Ð°ÑÑ Ð¿ÐŸ ÑÑÐŸÐŒÑ Ð°ÐŽÑÐµÑÑ. ÐÐ²ÐµÐŽÐžÑÐµ Ð°ÐŽÑÐµÑ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ Ð² ÐµÐ³ÐŸ Ð¿ÐŸÐ»ÐœÐŸÐ¹ ÑÐŸÑÐŒÐµ: name@domain. }  
+
+_textatc_ [l=ru] {Ð ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž:}
+
+_texttiasd_ [l=ru] {Ð­ÑÐŸ - ÐžÐœÑÑÑÑÐºÑÐžÑ, ÐŸÐ¿ÐžÑÑÐ²Ð°ÑÑÐ°Ñ Ð¿ÑÐžÐœÑÐžÐ¿Ñ, Ð¿ÐŸ ÐºÐŸÑÐŸÑÑÐŒ ÐŽÐ°ÐœÐœÑÐµ Ð±ÑÐ»Ðž Ð²ÐºÐ»ÑÑÐµÐœÑ Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ. Ð­ÑÐ° ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ Ð¿ÐŸÑÐ²Ð»ÑÐµÑÑÑ ÐœÐ° Ð¿ÐµÑÐ²ÐŸÐ¹ ÑÑÑÐ°ÐœÐžÑÐµ Ð¿ÑÐž Ð¿ÑÐµÐŽÑÑÐ°Ð²Ð»ÐµÐœÐžÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. }
+
+_textypits_ [l=ru] {ÐÐ°ÑÐ° Ð¿ÐŸÐ·ÐžÑÐžÑ Ð² Ð¿ÑÐŸÑÐµÑÑÐµ ÐŸÐ±ÐŸÐ·ÐœÐ°ÑÐµÐœÐ° ÑÑÑÐµÐ»ÐºÐŸÐ¹ Ð²ÐœÐžÐ·Ñ - Ð² ÑÑÐŸÐŒ ÑÐ»ÑÑÐ°Ðµ ÐœÐ° "ÑÑÐ°ÐŽÐžÐž" ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. ÐÐ»Ñ Ð¿ÑÐŸÐŽÐŸÐ»Ð¶ÐµÐœÐžÑ ÐœÐ°Ð¶ÐŒÐžÑÐµ Ð·ÐµÐ»ÐµÐœÑÑ ÐºÐœÐŸÐ¿ÐºÑ "source data/ÐžÑÑ
+ÐŸÐŽÐœÑÐµ ÐŽÐ°ÐœÐœÑÐµ". }
+
+_srcebadsources_ [l=ru] {ÐÐŽÐžÐœ ÐžÐ»Ðž Ð±ÐŸÐ»ÐµÐµ ÑÐºÐ°Ð·Ð°ÐœÐœÑÑ
+ Ð²Ð°ÐŒÐž ÐžÑÑÐŸÑÐœÐžÐºÐŸÐ² ÐœÐµ ÐŽÐŸÑÑÑÐ¿ÐœÑ (ÐœÐžÐ¶Ðµ Ð¿ÐŸÐŒÐµÑÐµÐœÑ _iconcross_).
+<p>Ð­ÑÐŸ ÐŒÐŸÐ¶ÐµÑ ÑÐ»ÑÑÐžÑÑÑÑ Ð¿ÐŸ Ð¿ÑÐžÑÐžÐœÐµ:
+<ul>
+<li>Ð€Ð°Ð¹Ð»,FTP-ÑÐ°Ð¹Ñ ÐžÐ»Ðž URL ÐœÐµ ÑÑÑÐµÑÑÐ²ÑÑÑ. 
+
+<li>Ð¡ÐœÐ°ÑÐ°Ð»Ð° Ð²Ñ ÐŽÐŸÐ»Ð¶ÐœÑ ÑÑÑÐ°ÐœÐŸÐ²ÐžÑÑ dial up ÑÐŸÐµÐŽÐžÐœÐµÐœÐžÐµ Ñ Ð²Ð°ÑÐžÐŒ ÐžÐœÑÐµÑÐœÐµÑ-ÑÐµÑÐ²ÐžÑ Ð¿ÑÐŸÐ²Ð°Ð¹ÐŽÐµÑÐŸÐŒ. 
+<li>ÐÑ Ð¿ÑÐŸÐ±ÑÐµÑÐµ ÐŸÐ±ÑÐ°ÑÐžÑÑÑÑ Ðº URL ÑÐµÑÐµÐ· - ÑÐžÑÑÐµÐŒÑ ÑÐµÑÐµÐ²ÐŸÐ¹ Ð·Ð°ÑÐžÑÑ ÑÐ°Ð¹ÐµÑÐ²ÐŸÐ»Ð» (ÐŽÐµÐ»ÐŸ ÐŸÐ±ÑÑÐŸÐžÑ ÑÐ°Ðº, ÐµÑÐ»Ðž ÐŸÐ±ÑÑÐœÐŸ Ð²Ñ ÐŽÐŸÐ»Ð¶ÐœÑ Ð²Ð²ÐµÑÑÐž ÐžÐŒÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ Ðž Ð¿Ð°ÑÐŸÐ»Ñ ÐŽÐ»Ñ ÐŽÐŸÑÑÑÐ¿Ð° Ðº ÑÐµÑÐž ÐÐœÑÐµÑÐœÐµÑ). 
+</ul>
+<p>ÐÑÐ»Ðž ÑÑÐŸ - URL, ÐºÐŸÑÐŸÑÑÐ¹ Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ Ð²ÐžÐŽÐµÑÑ Ð² Ð²Ð°ÑÐµÐŒ Ð±ÑÐ°ÑÐ·ÐµÑÐµ, ÑÐŸ ÐŸÐœ ÐŒÐŸÐ¶ÐµÑ ÐžÑÑ
+ÐŸÐŽÐžÑÑ ÐžÐ· Ð»ÐŸÐºÐ°Ð»ÑÐœÐŸÐ¹ ÐºÑÑ-ÐºÐŸÐ¿ÐžÐž. Ð ÑÐŸÐ¶Ð°Ð»ÐµÐœÐžÑ,  Ð»ÐŸÐºÐ°Ð»ÑÐœÑÐµ ÐºÑÑ-ÐºÐŸÐ¿ÐžÐž ÐœÐµÐ²ÐžÐŽÐžÐŒÑ ÐŽÐ»Ñ ÐœÐ°ÑÐµÐ³ÐŸ Ð¿ÑÐŸÑÐµÑÑÐ° Ð·ÐµÑÐºÐ°Ð»ÐžÑÐŸÐ²Ð°ÐœÐžÑ. Ð ÑÑÐŸÐŒ ÑÐ»ÑÑÐ°Ðµ ÐŒÑ ÑÐµÐºÐŸÐŒÐµÐœÐŽÑÐµÐŒ, ÑÑÐŸÐ±Ñ ÑÐœÐ°ÑÐ°Ð»Ð° Ð²Ñ Ð·Ð°Ð³ÑÑÐ·ÐžÐ»Ðž ÑÑÑÐ°ÐœÐžÑÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ Ð²Ð°Ñ Ð±ÑÐ°ÑÐ·ÐµÑ .}  
+
+_textymbyco_ [l=ru] {<p> ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ ÐŸÑÐœÐŸÐ²Ð°ÑÑ ÐÐ°ÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐžÐ»Ðž ÐœÐ°
+<ul>
+<li> Ð¡ÑÑÑÐºÑÑÑÐ° Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ   <dl><dd> ÐÐŸÐ²Ð°Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐŒÐŸÐ¶ÐµÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ HTML (.htm.html),  ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð¿ÑÐŸÑÑÐŸÐ³ÐŸ ÑÐµÐºÑÑÐ° (.txt.text), ÐŽÐŸÐºÑÐŒÐµÐœÑÑ MS Word (.doc), ÐŽÐŸÐºÑÐŒÐµÐœÑÑ PDF (.pdf) ÐžÐ»Ðž ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð² ÑÐŸÑÐŒÐ°ÑÐµ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ"m-box" (.mbx). </dd></dl>
+<li> Ð¡ÑÑÐµÑÑÐ²ÑÑÑÐ°Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ
+<dl><dd> Ð€Ð°Ð¹Ð»Ñ Ð² ÐÐ°ÑÐµÐ¹ ÐœÐŸÐ²ÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐŽÐŸÐ»Ð¶ÐœÑ Ð±ÑÑÑ ÑÐŸÑÐœÐŸ ÑÐ°ÐºÐŸÐ³ÐŸ Ð¶Ðµ ÑÐžÐ¿Ð°, ÐºÐ°Ðº ÑÐµ ÑÑÐŸ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÑ ÐŽÐ»Ñ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ ÑÑÑÐµÑÑÐ²ÑÑÑÐµÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. </dd> </dl>
+</ul>}
+
+_textbtco_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐŸÑÐœÐŸÐ²Ð°ÐœÐ° ÐœÐ°}
+_textand_ [l=ru] {ÐÐŸÐ±Ð°Ð²ÐžÑÑ ÐœÐŸÐ²ÑÐµ ÐŽÐ°ÐœÐœÑÐµ}
+_textad_ [l=ru] {ÐÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÑÐµ ÐŽÐ°ÐœÐœÑÐµ:}
+
+_texttftysb_ [l=ru] {<p> Ð€Ð°Ð¹Ð»Ñ, ÐºÐŸÑÐŸÑÑÐµ Ð²Ñ ÑÐºÐ°Ð¶ÐžÑÐµ ÐœÐžÐ¶Ðµ, Ð±ÑÐŽÑÑ ÐŽÐŸÐ±Ð°Ð²Ð»ÐµÐœÑ Ðº ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. Ð£ÐŽÐŸÑÑÐŸÐ²ÐµÑÑÑÐµÑÑ, ÑÑÐŸ Ð²Ñ ÐœÐµ Ð¿ÐµÑÐµÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÐµÑÐµ ÑÐ°Ð¹Ð»Ñ, ÐºÐŸÑÐŸÑÑÐµ ÐœÐ°Ñ
+ÐŸÐŽÑÑÑÑ ÑÐ¶Ðµ Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž: ÐžÐœÐ°ÑÐµ Ð±ÑÐŽÑÑ Ð²ÐºÐ»ÑÑÐµÐœÑ ÐŽÐ²Ðµ ÐºÐŸÐ¿ÐžÐž. Ð€Ð°Ð¹Ð»Ñ ÐŽÐŸÐ»Ð¶ÐœÑ Ð±ÑÑÑ ÐžÐŽÐµÐœÑÐžÑÐžÑÐžÑÐŸÐ²Ð°ÐœÑ  Ð¿ÐŸÐ»ÐœÑÐŒ ÐžÐŒÐµÐœÐµÐŒ ÐžÑ
+ Ð¿ÑÑÐž, Web-ÑÑÑÐ°ÐœÐžÑÑ ÐžÑ
+ Ð°Ð±ÑÐŸÐ»ÑÑÐœÑÐŒ Ð²ÐµÐ±-Ð°ÐŽÑÐµÑÐŸÐŒ.
+}
+
+_textis_ [l=ru] {ÐÑ
+ÐŸÐŽÐœÑÐµ ÐžÑÑÐŸÑÐœÐžÐºÐž:}
+
+_textddd1_ [l=ru] {<p> ÐÑÐ»Ðž ÐÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÐµ  file:// ÐžÐ»Ðž ftp:// ÐŽÐ»Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÑ ÑÐ°Ð¹Ð»Ð°, ÑÑÐŸÑ ÑÐ°Ð¹Ð» Ð±ÑÐŽÐµÑ Ð·Ð°Ð³ÑÑÐ¶ÐµÐœ.
+
+<p>ÐÑÐ»Ðž ÐÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÐµ http:// , ÑÑÐŸ Ð·Ð°Ð²ÐžÑÐžÑ ÐŸÑ ÑÐŸÐ³ÐŸ, ÐŽÐ°ÐµÑ Ð»Ðž ÐÐ°ÐŒ ÐŽÐ°ÐœÐœÑÐ¹ URL ÐœÐŸÑÐŒÐ°Ð»ÑÐœÐŸÐµ ÐŸÑÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐµ Ð²ÐµÐ±-ÑÑÑÐ°ÐœÐžÑÑ Ð¿ÑÐž ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐž ÐÐ°ÑÐµÐ³ÐŸ Ð±ÑÐ°ÑÐ·ÐµÑÐ° ÐžÐ»Ðž ÑÐ¿ÐžÑÐŸÐº ÑÐ°Ð¹Ð»ÐŸÐ². ÐÑÐ»Ðž ÑÑÑÐ°ÐœÐžÑÑ, ÑÐŸ ÑÑÐ° ÑÑÑÐ°ÐœÐžÑÐ° Ð±ÑÐŽÐµÑ Ð·Ð°Ð³ÑÑÐ¶ÐµÐœÐ° - Ðž ÑÐ°Ðº ÑÐŸ Ð²ÑÐµÐŒÐž ÑÑÑÐ°ÐœÐžÑÐ°ÐŒÐž, Ñ ÐºÐŸÑÐŸÑÑÐŒÐž ÐŸÐœÐ° ÐžÐŒÐµÐµÑ ÑÑÑÐ»ÐºÐž, Ðž ÑÐŸ Ð²ÑÐµÐŒÐž ÑÑÑÐ°ÐœÐžÑÐ°ÐŒÐž, Ðº ÐºÐŸÑÐŸÑÑÐŒ ÐŸÐœÐž ÐžÐŒÐµÐµÑÑ ÑÐ²ÑÐ·Ðž, Ðž Ñ.ÐŽ. - ÑÐ°Ð·ÐŒÐµÑÐµÐœÐœÑÑ
+ ÐœÐ° ÑÐŸÐ¹ Ð¶Ðµ ÑÑÑÐ°ÐœÐžÑÐµ ÐœÐžÐ¶Ðµ ÑÐºÐ°Ð·Ð°ÐœÐœÐŸÐ³ÐŸ Ð°ÐŽÑÐµÑÐ° URL.
+
+<p>ÐÑÐ»Ðž ÐÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÐµ file:// ÐžÐ»Ðž ftp:// ÐŽÐ»Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÑ Ð¿Ð°Ð¿ÐºÐž ÐžÐ»Ðž ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž ÐžÐ»Ðž ÐŽÐ°ÐµÑÐµ http:// URL, ÐºÐŸÑÐŸÑÑÐ¹ Ð²ÑÐ·ÑÐ²Ð°ÐµÑ ÑÐ¿ÐžÑÐŸÐº ÑÐ°Ð¹Ð»ÐŸÐ², Ð²ÑÐµ ÑÑÐŸ ÐµÑÑÑ Ð² Ð¿Ð°Ð¿ÐºÐ°Ñ
+ Ðž Ð²ÑÐµÑ
+ ÐµÐµ Ð¿ÐŸÐŽÐ¿Ð°Ð¿ÐºÐ°Ñ
+, Ð±ÑÐŽÐµÑ Ð²ÐºÐ»ÑÑÐµÐœÐŸ Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ.
+
+<p> Ð©ÐµÐ»ÐºÐœÐžÑÐµ ÐºÐœÐŸÐ¿ÐºÑ "Ð±ÐŸÐ»ÑÑÐµ ÐžÑÑÐŸÑÐœÐžÐºÐŸÐ²" , ÑÑÐŸÐ±Ñ Ð¿ÐŸÐ»ÑÑÐžÑÑ Ð±ÐŸÐ»ÑÑÐµ Ð²Ñ
+ÐŸÐŽÐœÑÑ
+ Ð¿ÐŸÐ»ÐµÐ¹.}
+
+_textddd2_ [l=ru] {<p> ÐÐ°Ð¶ÐŒÐžÑÐµ ÐŸÐŽÐœÑ ÐžÐ· Ð·ÐµÐ»ÐµÐœÑÑ
+ ÐºÐœÐŸÐ¿ÐŸÐº. ÐÑÐ»Ðž Ð²Ñ  ÑÑÐ²ÑÑÐ²ÑÐµÑÐµ ÑÐµÐ±Ñ ÐŸÐ¿ÑÑÐœÑÐŒ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐŒ, ÑÐŸ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ Ð¿ÐŸÐ¶ÐµÐ»Ð°ÐµÑÐµ ÐŸÑÐºÐŸÑÑÐµÐºÑÐžÑÐŸÐ²Ð°ÑÑ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. Ð ÐºÐ°ÑÐµÑÑÐ²Ðµ Ð°Ð»ÑÑÐµÑÐœÐ°ÑÐžÐ²Ñ Ð²Ð°ÐŒ Ð¿ÑÐµÐŽÐ»Ð°Ð³Ð°ÐµÑÑÑ Ð¿ÐµÑÐµÐ¹ÑÐž Ð¿ÑÑÐŒÐŸ Ð² ÑÑÐ°ÐŽÐžÑ ÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÐœÐžÑ. ÐÐŸÐŒÐœÐžÑÐµ, Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ Ð²ÑÐµÐ³ÐŽÐ° Ð¿ÐŸÐ²ÑÐŸÑÐœÐŸ Ð²ÐŸÐ¿ÐŸÑÐµÐ·Ð²ÑÐ°ÑÐžÑÑÑÑ ÐœÐ° ÑÐ°ÐœÐœÑÑ ÑÑÐ°ÐŽÐžÑ, ÑÐµÐ»ÐºÐ°Ñ Ð¿ÐŸ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÑÑÐµÐ¹ Ð¶ÐµÐ»ÑÐŸÐ¹ ÐºÐœÐŸÐ¿ÐºÐµ. }
+
+_textconf1_ [l=ru] {<p> Ð€ÐŸÑÐŒÐžÑÐŸÐ²Ð°ÐœÐžÐµ Ðž Ð¿ÑÐµÐŽÑÑÐ°Ð²Ð»ÐµÐœÐžÐµ Ð²Ð°ÑÐµÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐºÐŸÐœÑÑÐŸÐ»ÐžÑÐµÑÑÑ ÑÐ¿ÐµÑÐžÑÐžÐºÐ°ÑÐžÑÐŒÐž Ñ
+ÑÐ°ÐœÑÑÐžÐŒÐžÑÑ Ð² ÑÐ¿ÐµÑÐžÐ°Ð»ÑÐœÐŸÐŒ "ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐŸÐœÐœÐŸÐŒ ÑÐ°Ð¹Ð»Ðµ". ÐÐ¿ÑÑÐœÑÐµ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ðž Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ Ð¿ÐŸÐ¶ÐµÐ»Ð°ÑÑ ÐžÐ·ÐŒÐµÐœÐžÑÑ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÑ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐž. 
+<center><p><b>ÐÑÐ»Ðž Ð²Ñ  ÑÑÐ²ÑÑÐ²ÑÐµÑÐµ ÑÐµÐ±Ñ ÐŸÐ¿ÑÑÐœÑÐŒ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐŒ, Ð¿ÑÐŸÑÑÐŸ Ð¿ÐµÑÐµÐ¹ÐŽÐžÑÐµ Ð² ÐœÐžÐ¶ÐœÑÑ ÑÐ°ÑÑÑ ÑÑÑÐ°ÐœÐžÑÑ.</b></center>
+<p> Ð§ÑÐŸÐ±Ñ ÐžÐ·ÐŒÐµÐœÐžÑÑ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÑ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐž, ÐŸÑÑÐµÐŽÐ°ÐºÑÐžÑÑÐ¹ÑÐµ ÐŽÐ°ÐœÐœÑÐµ, ÐºÐŸÑÐŸÑÑÐµ Ð¿ÐŸÑÐ²ÑÑÑÑ ÐœÐžÐ¶Ðµ. ÐÑÐ»Ðž Ð²Ñ ÑÐŽÐµÐ»Ð°ÐµÑÐµ ÐŸÑÐžÐ±ÐºÑ, ÐœÐ°Ð¶ÐŒÐžÑÐµ ÐœÐ° ÐºÐœÐŸÐ¿ÐºÑ "ÐÑÐžÑÑÐžÑÑ", ÑÑÐŸÐ±Ñ Ð²ÐŸÑÑÑÐ°ÐœÐŸÐ²ÐžÑÑ Ð¿ÐµÑÐ²ÐŸÐœÐ°ÑÐ°Ð»ÑÐœÑÐµ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÑ ÐœÐ°ÑÑÑÐŸÐ¹ÐºÐž. }
+
+_textreset_ [l=ru] {Ð¡Ð±ÑÐŸÑÐžÑÑ}
+
+
+_texttryagain_ [l=ru] {ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ°, <a href="_httppagecollector_" target=_top>Ð¿ÐµÑÐµÐ·Ð°Ð¿ÑÑÑÐžÑÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐŸÑ </a>Ðž Ð¿ÐŸÐ¿ÑÑÐ°Ð¹ÑÐµÑÑ ÑÐœÐŸÐ²Ð°.  }
+
+
+_textretcoll_ [l=ru] {ÐÐµÑÐœÑÑÑÑÑ Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐŸÑ}
+
+_textdelperm_ [l=ru] {<p> ÐÐµÐºÐŸÑÐŸÑÑÐµ ÑÐ°ÑÑÐž ÐžÐ»Ðž Ð²ÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ _cgiargbc1dirname_ ÐœÐµ ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ ÑÐŽÐ°Ð»ÐµÐœÐ°. ÐÐŸÐ·ÐŒÐŸÐ¶ÐœÑÐµ Ð¿ÑÐžÑÐžÐœÑ: 
+<ul>
+<li> Greenstone ÐœÐµ ÐžÐŒÐµÐµÑ ÑÐ°Ð·ÑÐµÑÐµÐœÐžÑ ÐœÐ° ÑÐŽÐ°Ð»ÐµÐœÐžÐµ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž gsdlhome_/collect/_cgiargbc1dirname_.
+<br> ÐÐŸÐ¿ÑÐŸÐ±ÑÐ¹ÑÐµ Ð²ÑÑÑÐœÑÑ ÑÐŽÐ°Ð»ÐžÑÑ ÑÑÐŸÑ ÐºÐ°ÑÐ°Ð»ÐŸÐ³ Ñ Ð²Ð°ÑÐµÐ³ÐŸ ÐºÐŸÐŒÐ¿ÑÑÑÐµÑÐ°. }  
+
+_textdelinv_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ _cgiargbc1dirname_ Ð·Ð°ÑÐžÑÐµÐœÐ° ÐžÐ»Ðž Ð¿ÐŸÐ²ÑÐµÐ¶ÐŽÐµÐœÐ°. ÐÑÐŸÑÐµÑÑ ÑÐŽÐ°Ð»ÐµÐœÐžÑ ÐŸÑÐŒÐµÐœÐµÐœ. }
+
+_textdelsuc_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ _cgiargbc1dirname_ Ð±ÑÐ»Ð° ÑÑÐ¿ÐµÑÐœÐŸ ÑÐŽÐ°Ð»ÐµÐœÐ°.}
+
+_textclonefail_ [l=ru] {ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÑÐŸÐ·ÐŽÐ°ÑÑ ÐŽÑÐ±Ð»ÐžÐºÐ°Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž _cgiargclonecol_. ÐÐŸÐ·ÐŒÐŸÐ¶ÐœÑÐµ Ð¿ÑÐžÑÐžÐœÑ: 
+<ul>
+<li> ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ _cgiargclonecol_ ÐœÐµ ÑÑÑÐµÑÑÐ²ÑÐµÑ
+<li> ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ _cgiargclonecol_ ÐœÐµ ÐžÐŒÐµÐµÑ ÑÐ°Ð¹Ð»Ð° ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐž collect.cfg 
+<li> Greenstone ÐœÐµ ÐžÐŒÐµÐµÑ ÑÐ°Ð·ÑÐµÑÐµÐœÐžÑ ÐŽÐ»Ñ ÑÑÐµÐœÐžÑ ÑÐ°Ð¹Ð»Ð° ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐž collect.cfg </ul>}  
+
+_textcolerr_ [l=ru] {ÐÑÐžÐ±ÐºÐ° ÐºÐŸÐ»Ð»ÐµÐºÑÐŸÑÐ°.}
+
+_texttmpfail_ [l=ru] {ÐÑÐŸÐžÐ·ÐŸÑÐµÐ» ÑÐ±ÐŸÐ¹ ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑÐ° Ð¿ÑÐž ÑÑÐµÐœÐžÐž  ÐžÐ»Ðž Ð·Ð°Ð¿ÐžÑÐž Ð²ÐŸ Ð²ÑÐµÐŒÐµÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» ÐžÐ»Ðž ÐºÐ°ÑÐ°Ð»ÐŸÐ³. ÐÐŸÐ·ÐŒÐŸÐ¶ÐœÑÐµ Ð¿ÑÐžÑÐžÐœÑ: 
+<ul>
+<li> Greenstone ÐœÐµ ÐžÐŒÐµÐµÑ Ð¿ÑÐ°Ð²Ð° ÐŽÐŸÑÑÑÐ¿Ð° ÐŽÐ»Ñ ÑÑÐµÐœÐžÑ/Ð·Ð°Ð¿ÐžÑÐž ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž _gsdlhome_/tmp. </ul>}  
+
+_textmkcolfail_ [l=ru] {ÐÑÐŸÐžÐ·ÐŸÑÐµÐ» ÑÐ±ÐŸÐ¹ ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑÐ° Ð¿ÑÐž ÑÐŸÐ·ÐŽÐ°ÐœÐžÐž ÑÑÑÑÐºÑÑÑÑ Ð¿Ð°Ð¿ÐŸÐº, ÑÑÐµÐ±ÑÐµÐŒÐŸÐ¹ ÐŽÐ»Ñ ÐœÐŸÐ²ÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž (ÑÐ±ÐŸÐ¹ mkcol.pl). ÐÐŸÐ·ÐŒÐŸÐ¶ÐœÑÐµ Ð¿ÑÐžÑÐžÐœÑ: 
+<ul>
+<li> Greenstone ÐœÐµ ÐŸÐ±Ð»Ð°ÐŽÐ°ÐµÑ Ð¿ÑÐ°Ð²Ð°ÐŒÐž Ð·Ð°Ð¿ÐžÑÐž Ð² ÐŽÐžÑÐµÐºÑÐŸÑÐžÑ _gsdlhome_/tmp. 
+<li> ÐÑÐžÐ±ÐºÐ° Ð erl-ÑÐºÑÐžÐ¿ÑÐ° mkcol.pl.
+<li> ÐÐŒÑ ÐœÐ°Ð±ÑÐ°ÐœÐŸ ÐœÐ° ÐºÐžÑÐžÐ»Ð»ÐžÑÐµ. 
+</ul>}  
+
+_textnocontent_ [l=ru] {ÐÑÐžÐ±ÐºÐ° ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑÐ°: ÐœÐµ Ð±ÑÐ»ÐŸ Ð·Ð°ÐŽÐ°ÐœÐŸ ÐœÐžÐºÐ°ÐºÐŸÐ³ÐŸ ÐžÐŒÐµÐœÐž ÐŽÐ»Ñ ÐœÐŸÐ²ÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. ÐÐŸÐ¿ÑÐŸÐ±ÑÐ¹ÑÐµ Ð¿ÐµÑÐµÐ·Ð°Ð¿ÑÑÑÐžÑÑ ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ. }
+
+_textrestart_ [l=ru] {ÐÐµÑÐµÐ·Ð°Ð¿ÑÑÑÐžÑÑ ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ}
+
+_textreloaderror_ [l=ru] {ÐÑÐŸÐžÐ·ÐŸÑÐ»Ð° ÐŸÑÐžÐ±ÐºÐ°  Ð¿ÑÐž ÑÐŸÐ·ÐŽÐ°ÐœÐžÐž ÐœÐŸÐ²ÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. Ð­ÑÐŸ, Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ, Ð¿ÑÐŸÐžÐ·ÐŸÑÐ»ÐŸ ÐžÐ·-Ð·Ð° Ð¿ÑÑÐ°ÐœÐžÑÑ Ð² ÐºÐœÐŸÐ¿ÐºÐ°Ñ
+ "Ð¿ÐµÑÐµÐ·Ð°Ð³ÑÑÐ·ÐºÐ°" Ðž "ÐœÐ°Ð·Ð°ÐŽ" Ð²Ð°ÑÐµÐ³ÐŸ Ð±ÑÐ°ÑÐ·ÐµÑÐ° (Ð¿ÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ° Ð¿ÑÐŸÐ±ÑÐ¹ÑÐµ ÐžÐ·Ð±ÐµÐ¶Ð°ÑÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ ÑÑÐžÑ
+ ÐºÐœÐŸÐ¿ÐŸÐº Ð¿ÑÐž ÑÐŸÐ·ÐŽÐ°ÐœÐžÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ñ Ð¿ÐŸÐŒÐŸÑÑÑ ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑÐ°). Ð ÐµÐºÐŸÐŒÐµÐœÐŽÑÐµÑÑÑ Ð¿ÐµÑÐµÐ·Ð°Ð¿ÑÑÑÐžÑÑ ÐÐŸÐ»Ð»ÐµÐºÑÐŸÑ. }  
+
+_textexptsuc_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ  _cgiargbc1dirname_ Ð±ÑÐ»Ð° ÑÑÐ¿ÐµÑÐœÐŸ ÑÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐ° Ð² ÐŽÐžÑÐµÐºÑÐŸÑÐžÑ _gsdlhome_/tmp/exported\__cgiargbc1dirname_. }
+
+_textexptfail_ [l=ru] {Ð¡Ð±ÐŸÐ¹ Ð¿ÑÐž ÑÐºÑÐ¿ÐŸÑÑÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž _cgiargbc1dirname_. 
+Ð­ÑÐŸ, Ð²ÐµÑÐŸÑÑÐœÐŸ, Ð¿ÑÐŸÐžÐ·ÐŸÑÐ»ÐŸ Ð¿ÐŸÑÐŸÐŒÑ, ÑÑÐŸ Greenstone Ð±ÑÐ» ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœ Ð±ÐµÐ· ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÑÑ
+ ÐºÐŸÐŒÐ¿ÐŸÐœÐµÐœÑÐŸÐ² Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÐž ÑÑÐœÐºÑÐžÐž "Ð­ÐºÑÐ¿ÐŸÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž". 
+<ul>
+<li> ÐÑÐ»Ðž Ð²Ñ ÑÑÑÐ°ÐœÐ°Ð²Ð»ÐžÐ²Ð°Ð»Ðž Greenstone Ñ CD-ROM, ÑÑÐž ÐºÐŸÐŒÐ¿ÐŸÐœÐµÐœÑÑ ÐœÐµ Ð±ÑÐŽÑÑ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÑ, ÐµÑÐ»Ðž Ð²Ñ ÐœÐµ Ð²ÑÐ±ÑÐ°Ð»Ðž ÐžÑ
+ Ð²ÐŸ Ð²ÑÐµÐŒÑ Ð²ÑÐ±ÐŸÑÐŸÑÐœÐŸÐ¹ ÑÑÑÐ°ÐœÐŸÐ²ÐºÐž. ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ ÐŽÐŸÐ±Ð°Ð²ÐžÑÑ, Ð¿ÑÐŸÐ²ÐµÐŽÑ Ð¿ÐŸÐ²ÑÐŸÑÐœÑÑ ÑÑÑÐ°ÐœÐŸÐ²ÐºÑ.
+<li> ÐÑÐ»Ðž Ð²Ñ ÑÑÑÐ°ÐœÐ°Ð²Ð»ÐžÐ²Ð°Ð»Ðž Greenstone Ñ Ð²ÐµÐ±-ÐŽÐžÑÑÑÐžÐ±ÑÑÐžÐ²ÐŸÐ², ÑÐŸ Ð²Ð°ÐŒ ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÐŸ Ð±ÑÐŽÐµÑ Ð·Ð°Ð³ÑÑÐ·ÐžÑÑ Ðž ÑÑÑÐ°ÐœÐŸÐ²ÐžÑÑ ÐŽÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÑÐ¹ Ð¿Ð°ÐºÐµÑ, ÐŸÐ±ÐµÑÐ¿ÐµÑÐžÐ²Ð°ÑÑÐžÐ¹ ÑÐ°Ð±ÐŸÑÑ ÑÑÐœÐºÑÐžÐž ÑÐºÑÐ¿ÐŸÑÑÐ°. ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ°, Ð¿ÐŸÑÐµÑÐžÑÐµ ÑÐ°Ð¹Ñ  <a href="http://www.greenstone.org"> http://www.greenstone.org </a> ÐžÐ»Ðž Ð¿ÐŸÑÐ»ÐžÑÐµ Ð·Ð°Ð¿ÑÐŸÑ Ð¿ÐŸ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÐµ <a href="mailto:greenstone@cs.waikato.ac.nz">
+greenstone@cs.waikato.ac.nz </a>  ÐŽÐ»Ñ Ð¿ÐŸÐ»ÑÑÐµÐœÐžÑ ÐŽÐ°Ð»ÑÐœÐµÐ¹ÑÐžÑ
+ ÐžÐœÑÑÑÑÐºÑÐžÐ¹. }  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=ru] {<p> Ð£ÐºÐ°Ð¶ÐžÑÐµ ÑÐ»ÐµÐŽÑÑÑÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ ÑÐ°Ð¹Ð»Ðµ Ðž ÑÐµÐ»ÐºÐœÐžÑÐµ _textintro_ ÐœÐžÐ¶Ðµ. </p>   }  
+
+_textcaec_ [l=ru] {ÐÐŸÐ±Ð°Ð²ÐžÑÑ Ð² Ð¡ÑÑÐµÑÑÐ²ÑÑÑÑÑ ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ}  
+_textbild_ [l=ru] {ÐÐœÐµÑÑÐž}  
+_textintro_ [l=ru] {ÐÑÐ±ÑÐ°ÑÑ Ð€Ð°Ð¹Ð»}  
+
+_textselect_ [l=ru] {ÐÑÐ±ÑÐ°ÑÑ ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ}  
+_textmeta_ [l=ru] {ÐÐ¿ÑÐµÐŽÐµÐ»ÐžÑÑ ÐÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ}  
+
+_texttryagain_ [l=ru] {ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ°, <a href="_httppagedepositor_" target=_top> Ð¿ÐµÑÐµÐ·Ð°Ð¿ÑÑÑÐžÑÐµ Ð²ÐºÐ»Ð°ÐŽÑÐžÐº</a> Ðž Ð¿ÐŸÐ¿ÑÐŸÐ±ÑÐ¹ÑÐµ ÐµÑÑ ÑÐ°Ð·.}  
+
+
+
+
+
+_textretcoll_ [l=ru] {ÐÐµÑÐœÑÑÑÑÑ Ðº Ð²ÐºÐ»Ð°ÐŽÑÐžÐºÑ}  
+
+
+_texttmpfail_ [l=ru] {ÐÐºÐ»Ð°ÐŽÑÐžÐº ÐœÐµ ÑÐŒÐŸÐ³ ÑÑÐžÑÐ°ÑÑ ÐžÐ»Ðž Ð·Ð°Ð¿ÐžÑÐ°ÑÑ Ð²ÐŸ Ð²ÑÐµÐŒÐµÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» ÐžÐ»Ðž ÐŽÐžÑÐµÐºÑÐŸÑÐžÑ. ÐÐŸÐ·ÐŒÐŸÐ¶ÐœÑÐµ Ð¿ÑÐžÑÐžÐœÑ: 
+<ul>
+<li> Ð£ ÐÑÐžÐœÑÑÐŸÑÐœ ÐœÐµÑ ÐŽÐŸÐ¿ÑÑÐºÐ° ÑÑÐžÑÑÐ²Ð°ÑÑ/Ð·Ð°Ð¿ÐžÑÑÐ²Ð°ÑÑ Ð² _gsdlhome_/tmp
+     ÐŽÐžÑÐµÐºÑÐŸÑÐžÑ.
+</ul>}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=ru] {Greenstone, ÐºÐŸÐŒÐ¿Ð»ÐµÐºÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐ³ÐŸ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÑ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž ÐŽÐ»Ñ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ, Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ Ðž ÑÐ°ÑÐ¿ÑÐŸÑÑÑÐ°ÐœÐµÐœÐžÑ Ð¿ÐŸÐ»ÐœÐŸÑÐµÐºÑÑÐŸÐ²ÑÑ
+ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹. Ð­ÑÐ° ÑÐžÑÑÐµÐŒÐ° ÐŸÐ±ÐµÑÐ¿ÐµÑÐžÐ²Ð°ÐµÑ ÐœÐŸÐ²ÑÐ¹ ÑÐ¿ÐŸÑÐŸÐ± ÐŸÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÐž ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž ÐŽÐ»Ñ ÐŸÐ¿ÑÐ±Ð»ÐžÐºÐŸÐ²Ð°ÐœÐžÑ ÐœÐ° ÐºÐŸÐŒÐ¿Ð°ÐºÑ ÐŽÐžÑÐºÐ°Ñ
+, Ð»ÐŸÐºÐ°Ð»ÑÐœÑÑ
+ ÑÐµÑÑÑ
+ Ðž ÐžÐœÑÐµÑÐœÐµÑ. ÐÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐµ Ð¿ÑÐŸÐžÐ·Ð²ÐµÐŽÐµÐœÐŸ Ð² ÑÐ°ÐŒÐºÐ°Ñ
+ Ð¿ÑÐŸÐµÐºÑÐ° ÐÐŸÐ²ÐŸÐ·ÐµÐ»Ð°ÐœÐŽÑÐºÐŸÐ¹ ÐŠÐžÑÑÐŸÐ²ÐŸÐ¹ ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž Ð£ÐœÐžÐ²ÐµÑÑÐžÑÐµÑÐ° ÐÐ°ÐžÐºÐ°ÑÐŸ, Ð² ÑÐŸÑÑÑÐŽÐœÐžÑÐµÑÑÐ²Ðµ Ñ Ð®ÐÐÐ¡ÐÐ Ðž ÐÐÐ Ð§ÐµÐ»ÐŸÐ²ÐµÑÐµÑÐºÐ°Ñ ÐÐœÑÐŸÑÐŒÐ°ÑÐžÑ (Human Info). ÐÐœÑÐµÐ³ÑÐžÑÑÐµÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ, Ð¿ÐŸÐ»ÐœÐŸÑÐµÐºÑÑÐŸÐ²ÑÐ¹ Ð¿ÐŸÐžÑÐº Ðž ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÐµ, Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÑ ÐŒÐœÐŸÐ³ÐŸÑÐ·ÑÑÐžÑ, Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÑ ÐŒÐœÐŸÐ³ÐžÑ
+ ÐŸÐ±ÑÐµÑÐ¿ÐŸÑÑÐµÐ±ÐžÐŒÑÑ
+ ÑÐŸÑÐŒÐ°ÑÐŸÐ² Ðž Ð°ÐŽÐŒÐžÐœÐžÑÑÑÐžÑÐŸÐ²Ð°ÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŒÐž. Greenstone ÑÐ²ÐŸÐ±ÐŸÐŽÐœÐŸÐµ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐµ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐµ, Ñ ÐŸÑÐºÑÑÑÑÐŒÐž ÐžÑÑ
+ÐŸÐŽÐœÑÐŒÐž ÐºÐŸÐŽÐ°ÐŒÐž, ÐŽÐŸÑÑÑÐ¿ÐœÐŸ Ð¿ÐŸ Ð°ÐŽÑÐµÑÑ <i><a href="http://greenstone.org"> http://greenstone.org </a>, ÐœÐ° ÑÑÐ»ÐŸÐ²ÐžÑÑ
+ <a href="http://www.gnu.org/copyleft/gpl.html">ÑÑÐ°ÐœÐŽÐ°ÑÑÐœÐŸÐ¹ ÐŸÐ±ÑÐµÑÑÐ²ÐµÐœÐœÐŸÐ¹ Ð»ÐžÑÐµÐœÐ·ÐžÐž</a> (GNU)</i>.}  
+
+_textgreenstone2_ [l=ru] {ÐÐµÐ±-ÑÐ°Ð¹Ñ ÐÐŸÐ²ÐŸÐ·ÐµÐ»Ð°ÐœÐŽÑÐºÐŸÐ¹ Ð­Ð»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž  (<a href="http://nzdl.org">http://nzdl.org</a>)  ÑÐŸÐŽÐµÑÐ¶ÐžÑ ÐŒÐœÐŸÐ³ÐŸÑÐžÑÐ»ÐµÐœÐœÑÐµ Ð¿ÑÐžÐŒÐµÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹, ÐºÐŸÑÐŸÑÑÐµ  Ð±ÑÐ»Ðž ÑÐŸÐ·ÐŽÐ°ÐœÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐµ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐµ Greenstone, Ðž ÐºÐŸÑÐŸÑÑÐµ ÑÐ²Ð»ÑÑÑÑÑ ÐŽÐŸÑÑÑÐ¿ÐœÑÐŒÐž ÐŽÐ»Ñ ÑÐ²ÐŸÐ±ÐŸÐŽÐœÐŸÐ³ÐŸ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ°. ÐÐœÐž ÐžÐ»Ð»ÑÑÑÑÐžÑÑÑÑ ÑÐ°Ð·Ð»ÐžÑÐœÑÐµ Ð²Ð°ÑÐžÐ°ÐœÑÑ Ð¿ÐŸÐžÑÐºÐ° Ðž Ð¿ÑÐŸÑÐŒÐŸÑÑÐ°, Ðž Ð²ÐºÐ»ÑÑÐ°ÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐœÐ° Ð°ÑÐ°Ð±ÑÐºÐŸÐŒ, ÐºÐžÑÐ°Ð¹ÑÐºÐŸÐŒ, ÑÑÐ°ÐœÑÑÐ·ÑÐºÐŸÐŒ, ÐžÑÐ¿Ð°ÐœÑÐºÐŸÐŒ,  Ð°ÐœÐ³Ð»ÐžÐ¹ÑÐºÐŸÐŒ ÑÐ·ÑÐºÐ°Ñ
+, Ð° ÑÐ°ÐºÐ¶Ðµ ÐœÐ° ÑÐ·ÑÐºÐµ ÐŒÐ°ÐŸÑÐž. ÐÐŸÐŒÐžÐŒÐŸ ÑÑÐŸÐ³ÐŸ, Ð¿ÑÐµÐŽÑÑÐ°Ð²Ð»ÐµÐœÑ ÐŒÑÐ·ÑÐºÐ°Ð»ÑÐœÑÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.}  
+
+_textplatformtitle_ [l=ru] {ÐÐ»Ð°ÑÑÐŸÑÐŒÐ°}
+_textgreenstone3_ [l=ru] {Greenstone ÑÑÑÐ°ÐœÐ°Ð²Ð»ÐžÐ²Ð°ÐµÑÑÑ ÐŽÐ»Ñ ÑÐ°Ð±ÐŸÑÑ Ð² ÑÑÐµÐŽÐµ Windows Ðž Ð² ÑÑÐµÐŽÐµ Unix. ÐÐžÑÑÑÐžÐ±ÑÑÐžÐ² Ð²ÐºÐ»ÑÑÐ°ÐµÑ Ð³ÐŸÑÐŸÐ²ÑÐµ Ðº ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ ÐœÐ°Ð±ÐŸÑÑ ÐŽÐ»Ñ Ð²ÑÐµÑ
+ Ð²ÐµÑÑÐžÐ¹ Windows, Linux Ðž Mac OS X. ÐÐœ ÑÐ°ÐºÐ¶Ðµ Ð²ÐºÐ»ÑÑÐ°ÐµÑ Ð³ÐŸÑÐŸÐ²ÑÑ ÐžÑÑ
+ÐŸÐŽÐœÑÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑ ÐŽÐ»Ñ ÑÐžÑÑÐµÐŒÑ, ÐºÐŸÑÐŸÑÐ°Ñ ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ ÐŸÑÐºÐŸÐŒÐ¿ÐžÐ»ÐžÑÐŸÐ²Ð°ÐœÐ°, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ Microsoft C++ ÐžÐ»Ðž gcc. Greenstone ÑÐ°Ð±ÐŸÑÐ°ÐµÑ ÑÐŸÐ²ÐŒÐµÑÑÐœÐŸ Ñ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÑÐŒ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐµÐŒ, ÐºÐŸÑÐŸÑÐŸÐµ ÑÐ²Ð»ÑÐµÑÑÑ ÑÐ°ÐºÐ¶Ðµ ÑÐ²ÐŸÐ±ÐŸÐŽÐœÐŸ ÑÐ°ÑÐ¿ÑÐŸÑÑÑÐ°ÐœÑÐµÐŒÑÐŒ: ÐÐµÐ±ÑÐµÑÐ²ÐµÑ Apache Ðž ÑÐ·ÑÐº PERL. ÐÐœÑÐµÑÑÐµÐ¹Ñ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑ Ð²ÐµÐ±-Ð±ÑÐ°ÑÐ·ÐµÑ: ÐŸÐ±ÑÑÐœÐŸ ÐœÐ°Ð²ÐžÐ³Ð°ÑÐŸÑ ÐÐŸÐ·ÐžÐ»Ð»Ð° ÐžÐ»Ðž Internet Explorer. }  
+
+_textgreenstone4_ [l=ru] {ÐÐœÐŸÐ¶ÐµÑÑÐ²ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°Ð»ÑÐœÑÑ
+ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹ ÑÐ°ÑÐ¿ÑÐŸÑÑÑÐ°ÐœÑÑÑÑÑ ÐœÐ° CD-ROM, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐµ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐµ Greenstone. ÐÐ°Ð¿ÑÐžÐŒÐµÑ <i>ÐÑÐŒÐ°ÐœÐžÑÐ°ÑÐœÐ°Ñ  ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ° Ð Ð°Ð·Ð²ÐžÑÐžÑ</i> (Human Development Library) ÑÐŸÐŽÐµÑÐ¶ÐžÑ 1 230 Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐ¹. ÐÐœÐ° ÑÐ°Ð±ÐŸÑÐ°ÐµÑ Ð¿ÑÐž ÐŒÐžÐœÐžÐŒÐ°Ð»ÑÐœÑÑ
+ Ð°Ð¿Ð¿Ð°ÑÐ°ÑÐœÑÑ
+ ÑÑÐµÐ±ÐŸÐ²Ð°ÐœÐžÑÑ
+, ÑÑÐŸ ÑÐžÐ¿ÐžÑÐœÐŸ ÐŽÐ»Ñ ÑÐ°Ð·Ð²ÐžÐ²Ð°ÑÑÐžÑ
+ÑÑ ÑÑÑÐ°Ðœ. Ð ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž ÐŒÐŸÐ¶ÐœÐŸ ÐŸÐ±ÑÐ°ÑÐžÑÑÑÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ Ð¿ÑÐŸÑÐµÐŽÑÑÑ Ð¿ÐŸÐžÑÐºÐ°, Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° ÑÐµÐŒ, Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐŸÐ², Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° ÐŸÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÐ¹, Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° ÑÐ¿ÐžÑÐºÐ°  Ðž Ð±ÐµÑÐ¿ÐŸÑÑÐŽÐŸÑÐœÐŸÐ³ÐŸ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° ÐºÐœÐžÐ¶ÐœÑÑ
+ ÐŸÐ±Ð»ÐŸÐ¶ÐµÐº. }  
+
+_textcustomisationtitle_ [l=ru] {ÐÐ°ÑÑÑÐŸÐ¹ÐºÐ°}
+_textgreenstone5_ [l=ru] {Greenstone ÑÐ¿ÐµÑÐžÐ°Ð»ÑÐœÐŸ ÑÐ°Ð·ÑÐ°Ð±ÐŸÑÐ°ÐœÑ ÑÐ°Ðº, ÑÑÐŸÐ±Ñ Ð±ÑÑÑ ÐŒÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸ ÑÐ°ÑÑÐžÑÑÐµÐŒÑÐŒÐž Ðž ÐœÐ°ÑÑÑÐ°ÐžÐ²Ð°ÐµÐŒÑÐŒÐž. ÐÐŸÐ²ÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ Ðž ÑÐŸÑÐŒÐ°ÑÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ð¿ÑÐµÐŽÐŸÑÑÐ°Ð²Ð»ÑÑÑÑÑ ÐœÐ°Ð¿ÐžÑÐ°ÐœÐžÐµÐŒ "plugins/Ð¿ÑÐžÐ»ÐŸÐ¶ÐµÐœÐžÐ¹ Ðº Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐµ" (ÐœÐ° ÑÐ·ÑÐºÐµ Perl). ÐÐœÐ°Ð»ÐŸÐ³ÐžÑÐœÐŸ, ÐœÐŸÐ²ÑÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ, Ð¿ÑÐŸÑÐŒÐ°ÑÑÐžÐ²Ð°ÑÑÐžÐµ ÑÑÑÑÐºÑÑÑÑ ÐŒÐŸÐ³ÑÑ Ð±ÑÑÑ ÑÐŸÐ·ÐŽÐ°ÐœÑ ÐœÐ°Ð¿ÐžÑÐ°ÐœÐžÐµÐŒ "classifiers/ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐŸÐ²". ÐÐœÐµÑÐœÐžÐ¹ Ð²ÐžÐŽ ÐžÐœÑÐµÑÑÐµÐ¹ÑÐ° Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ ÐŒÐŸÐ¶ÐœÐŸ ÐžÐ·ÐŒÐµÐœÐžÑÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ "ÐŒÐ°ÐºÑÐŸÑÑ", ÐœÐ°Ð¿ÐžÑÐ°ÐœÐœÑÐµ ÐœÐ° Ð¿ÑÐŸÑÑÐŸÐŒ ÐŒÐ°ÐºÑÐŸÑÐ·ÑÐºÐµ. ÐÑÐŸÑÐŸÐºÐŸÐ» Corba  Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ Ð°Ð³ÐµÐœÑÐ°ÐŒ (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ Ð² Java) ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ Ð²ÑÐµ ÑÑÐµÐŽÑÑÐ²Ð°, ÑÐ²ÑÐ·Ð°ÐœÐœÑÐµ Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŒÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°. ÐÐ°ÐºÐŸÐœÐµÑ, ÐžÑÑ
+ÐŸÐŽÐœÐ°Ñ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐ°, ÐœÐ° C++ Ðž Perl, ÑÐ²Ð»ÑÐµÑÑÑ ÐŽÐŸÑÑÑÐ¿ÐœÐŸÐ¹ ÐŽÐ»Ñ ÐŒÐŸÐŽÐžÑÐžÐºÐ°ÑÐžÐž. }  
+
+_textdocumentationtitle_ [l=ru] {ÐÐŸÐºÑÐŒÐµÐœÑÐ°ÑÐžÑ}
+_textdocuments_ [l=ru] {ÐÐ±ÑÐžÑÐœÐ°Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÑÐžÑ Ð¿ÐŸ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐŒÑ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÑ Greenstone ÐŽÐŸÑÑÑÐ¿ÐœÐ°.}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=ru] {ÑÐ¿ÐžÑÐŸÐº Ð°ÐŽÑÐµÑÐ°ÑÐŸÐ²}
+_textmailinglist_ [l=ru] {Ð­ÑÐŸÑ ÑÐ¿ÐžÑÐŸÐº ÑÐ°ÑÑÑÐ»ÐºÐž, Ð¿ÑÐµÐŽÐœÐ°Ð·ÐœÐ°ÑÐµÐœ Ð¿ÑÐµÐ¶ÐŽÐµ Ð²ÑÐµÐ³ÐŸ ÐŽÐ»Ñ ÐŸÐ±ÑÑÐ¶ÐŽÐµÐœÐžÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐ³ÐŸ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÑ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž Greenstone. ÐÐºÑÐžÐ²ÐœÑÐµ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ðž Greenstone ÐŒÐŸÐ³ÑÑ Ð¿ÐŸÐŽÐºÐ»ÑÑÐ°ÑÑÑÑ Ðº ÑÐ¿ÐžÑÐºÑ ÑÐ°ÑÑÑÐ»ÐºÐž Ðž Ðº ÐŸÐ±ÑÑÐ¶ÐŽÐµÐœÐžÑÐŒ. Ð§ÑÐŸÐ±Ñ Ð¿ÐŸÐŽÐ¿ÐžÑÐ°ÑÑÑÑ, ÑÐµÐ»ÐºÐœÐžÑÐµ ÐœÐ° <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+ÐÑÑÐ»Ð°ÑÑ ÑÐŸÐŸÐ±ÑÐµÐœÐžÐµ Ð² ÑÐ¿ÐžÑÐŸÐº ÐŒÐŸÐ¶ÐœÐŸ Ð¿ÐŸ ÐŽÐ°ÐœÐœÐŸÐŒÑ Ð°ÐŽÑÐµÑÑ <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>.
+}  
+
+_textbugstitle_ [l=ru] {ÐÑÐžÐ±ÐºÐž}
+_textreport_ [l=ru] {ÐÑ Ñ
+ÐŸÑÐžÐŒ Ð±ÑÑÑ ÑÐ²ÐµÑÐµÐœÑ Ð² ÑÐŸÐŒ, ÑÑÐŸ ÑÐ°Ð±ÐŸÑÐ° Ñ ÐœÐ°ÑÐžÐŒ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÑÐŒ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐµÐŒ ÐœÐµ ÐŽÐŸÑÑÐ°Ð²Ð»ÑÐµÑ Ð²Ð°ÐŒ ÐœÐµÑÐŽÐŸÐ±ÑÑÐ². ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ°, ÑÐŸÐŸÐ±ÑÐ°Ð¹ÑÐµ ÐœÐ°ÐŒ ÐŸ Ð²ÑÐµÑ
+ Ð²ÑÑÐ²Ð»ÐµÐœÐœÑÑ
+ Ð² Ð¿ÑÐŸÑÐµÑÑÐµ ÑÐ°Ð±ÐŸÑÑ ÐŸÑÐžÐ±ÐºÐ°Ñ
+ Ð¿ÐŸ Ð°ÐŽÑÐµÑÑ <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>}
+
+_textgs3title_ [l=ru] {Ð² ÑÐ°Ð±ÐŸÑÐ°Ñ
+}
+_textgs3_ [l=ru] {Ð Greenstone 3  Ð¿ÐŸÐ»ÐœÐŸÑÑÑÑ Ð¿ÐµÑÐµÑÐ°Ð±ÐŸÑÐ°Ðœ ÐŽÐžÐ·Ð°Ð¹Ðœ Ðž ÐžÐœÑÑÑÑÐŒÐµÐœÑÐ°ÑÐžÐ¹, ÐºÐŸÑÐŸÑÑÐ¹ ÑÐŸÑ
+ÑÐ°ÐœÑÐµÑ Ð²ÑÐµ Ð¿ÑÐµÐžÐŒÑÑÐµÑÑÐ²Ð° Greenstone 2 (ÐœÐ°ÑÑÐŸÑÑÐµÐ¹ Ð²ÐµÑÑÐžÐž). Ð¢Ð°Ðº ÐŸÐœ ÑÐ²Ð»ÑÐµÑÑÑ ÐŒÐœÐŸÐ³ÐŸÑÐ·ÑÑÐœÑÐŒ, ÐŒÐœÐŸÐ³ÐŸÐ¿Ð»Ð°ÑÑÐŸÑÐŒÐµÐœÐœÑÐŒ Ðž ÐŸÑÐ»ÐžÑÐ°ÐµÑÑÑ Ð²ÑÑÐŸÐºÐŸÐ¹ ÐºÐŸÐœÑÐžÐ³ÑÑÐžÑÑÐµÐŒÐŸÑÑÑÑ. ÐÐœ Ð²ÐºÐ»ÑÑÐ°ÐµÑ ÑÑÐµÐŽÑÑÐ²Ð° ÐŽÐ°ÐœÐœÐŸÐ¹ ÑÐžÑÑÐµÐŒÑ Ðž ÐŸÐ±Ð»Ð°ÐŽÐ°ÐµÑ ÐŸÐ±ÑÐ°ÑÐœÐŸÐ¹ ÑÐŸÐ²ÐŒÐµÑÑÐžÐŒÐŸÑÑÑÑ.Ð­ÑÐŸ ÐŸÐ·ÐœÐ°ÑÐ°ÐµÑ, ÑÑÐŸ ÐŸÐœ ÐŒÐŸÐ¶ÐµÑ ÑÑÑÐŸÐžÑÑ Ðž Ð²Ð²ÐŸÐŽÐžÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ð±ÐµÐ· ÐžÑ
+ ÐŒÐŸÐŽÐžÑÐžÐºÐ°ÑÐžÐž. ÐÐ°Ð¿ÐžÑÐ°ÐœÐœÑÐ¹ ÐœÐ° Java, ÐŸÐœ ÑÑÑÑÐºÑÑÑÐžÑÐŸÐ²Ð°Ðœ ÐºÐ°Ðº ÑÐµÐ¿Ñ ÐœÐµÐ·Ð°Ð²ÐžÑÐžÐŒÑÑ
+ ÐŒÐŸÐŽÑÐ»ÐµÐ¹, ÐºÐŸÑÐŸÑÑÐµ Ð²Ð·Ð°ÐžÐŒÐŸÐŽÐµÐ¹ÑÑÐ²ÑÑÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ XML. Ð¢Ð°ÐºÐžÐŒ ÐŸÐ±ÑÐ°Ð·ÐŸÐŒ ÐŸÐœ Ð²ÑÐ¿ÐŸÐ»ÐœÐµÐœ Ð² ÑÐŸÑÐŒÐµ ÐŽÐžÑÑÑÐžÐ±ÑÑÐžÐ²Ð° Ðž ÐŒÐŸÐ¶ÐµÑ ÑÐ°ÑÐ¿ÑÐŸÑÑÑÐ°ÐœÑÑÑÑÑ ÑÐµÑÐµÐ· ÑÐ°Ð·Ð»ÐžÑÐœÑÐµ ÑÐµÑÐ²ÐµÑÐ°. Ð­ÑÐŸ ÐŒÐŸÐŽÑÐ»ÑÐœÐŸÐµ ÑÐµÑÐµÐœÐžÐµ ÑÐ²ÐµÐ»ÐžÑÐžÐ²Ð°ÐµÑ Ð³ÐžÐ±ÐºÐŸÑÑÑ Ðž ÑÐ°ÑÑÐžÑÑÐµÐŒÐŸÑÑÑ Greenstone. ÐÐµÑÐ²ÐŸÐœÐ°ÑÐ°Ð»ÑÐœÑÐ¹ ÐŽÐžÐ·Ð°Ð¹Ðœ ÑÐžÑÑÐµÐŒÑ ÐžÐ·Ð»ÐŸÐ¶ÐµÐœ Ð² ÐŽÐŸÐºÑÐŒÐµÐœÑÐµ "ÐÐžÐ·Ð°Ð¹Ðœ Greenstone 3: ÐÐ³ÐµÐœÑ ÐŸÑÐžÐµÐœÑÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐ¹ ÐŽÐžÐœÐ°ÐŒÐžÑÐµÑÐºÐŸÐ¹ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž" ( ÐºÐŸÑÐŸÑÑÐ¹ ÐŒÐŸÐ¶ÐœÐŸ Ð¿ÑÐŸÑÐžÑÐ°ÑÑ Ð² <a href="http://www.greenstone.org/manuals/gs3design.pdf">PDF</a>).
+}  
+
+_textcreditstitle_ [l=ru] {ÐÑÐµÐŽÐžÑÑ}
+
+_textwhoswho_ [l=ru] {ÐÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐµ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐµ Greenstone - Ð¿ÑÐŸÐŽÑÐºÑ ÑÐŸÐ²ÐŒÐµÑÑÐœÐŸÐ³ÐŸ ÑÑÑÐŽÐ° ÐŒÐœÐŸÐ¶ÐµÑÑÐ²Ð° Ð»ÑÐŽÐµÐ¹. Rodger McNab Ðž Stefan Boddie Ð³Ð»Ð°Ð²ÐœÑÐµ ÑÐ°Ð·ÑÐ°Ð±ÐŸÑÑÐžÐºÐž ÑÐžÑÑÐµÐŒÑ. ÐÐµÐŸÑÐµÐœÐžÐŒÑÐ¹ Ð²ÐºÐ»Ð°ÐŽ Ð²ÐœÐµÑÐ»Ðž David Bainbridge, George Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd Reed, Bill Rogers, John Thompson, Ðž Stuart Yeates. ÐÑÑÐ°Ð»ÑÐœÑÐµ ÑÐ»ÐµÐœÑ ÐÑÐŸÐµÐºÑÐ° ÐÐŸÐ²ÐŸÐ·ÐµÐ»Ð°ÐœÐŽÑÐºÐŸÐ¹ Ð­Ð»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ ÐÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž  ÑÐ°Ð·ÑÐ°Ð±ÐŸÑÐ°Ð»Ðž Ð²ÐŽÐŸÑ
+ÐœÐŸÐ²ÐµÐœÐœÑÐ¹ ÐŽÐžÐ·Ð°Ð¹Ðœ Ð²ÑÐµÐ¹ ÑÐžÑÑÐµÐŒÑ: Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols Ðž Lloyd Smith. 
+ÐÑ ÑÐ°ÐºÐ¶Ðµ Ð²ÑÑÐ°Ð¶Ð°ÐµÐŒ ÑÐ²ÐŸÑ Ð¿ÑÐžÐ·ÐœÐ°ÑÐµÐ»ÑÐœÐŸÑÑÑ Ð²ÑÐµÐŒ ÑÐµÐŒ, ÐºÑÐŸ ÑÑÑÐŽÐžÐ»ÑÑ ÐœÐ°ÐŽ ÑÐŸÐ·ÐŽÐ°ÐœÐžÐµÐŒ Ð¿Ð°ÐºÐµÑÐŸÐ², Ð¿ÐŸÐ¿Ð°ÐŽÐ°ÑÑÐžÑ
+ Ð¿ÐŸÐŽ ÐŽÐµÐ¹ÑÑÐ²ÐžÐµ Ð»ÐžÑÐµÐœÐ·ÐžÐž  GNU, Ðž Ð²ÐºÐ»ÑÑÐµÐœÐœÑÑ
+ Ð² ÐŽÐžÑÑÑÐžÐ±ÑÑÐžÐ²: MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE Ðž XLHTML. }  
+
+_textaboutgslong_ [l=ru] {ÐŸ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐŸÐŒ ÐŸÐ±ÐµÑÐ¿ÐµÑÐµÐœÐžÐž Greenstone}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=ru] {Ð¡Ð¿ÐžÑÐŸÐº ÑÐµÐºÑÑÐžÑ
+ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐ¹}
+_textuser_ [l=ru] {Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ
+}
+_textas_ [l=ru] {ÑÐŸÑÑÐŸÑÐœÐžÐµ ÑÑÐµÑÐœÐŸÐ¹ Ð·Ð°Ð¿ÐžÑÐž}
+_textgroups_ [l=ru] {Ð³ÑÑÐ¿Ð¿Ñ}
+_textcomment_ [l=ru] {ÐºÐŸÐŒÐŒÐµÐœÑÐ°ÑÐžÐ¹}
+_textadduser_ [l=ru] {ÐŽÐŸÐ±Ð°Ð²Ð»ÐµÐœÐžÐµ ÐœÐŸÐ²ÐŸÐ³ÐŸ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ}
+_textedituser_ [l=ru] {ÑÐµÐŽÐ°ÐºÑÐžÑÐŸÐ²Ð°ÐœÐžÐµ}
+_textdeleteuser_ [l=ru] {ÑÐŽÐ°Ð»ÐµÐœÐžÐµ}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=ru] {Ð ÐµÐŽÐ°ÐºÑÐžÑÐŸÐ²Ð°ÐœÐžÐµ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž ÐŸ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ðµ}
+_textadduser_ [l=ru] {ÐÐŸÐ±Ð°Ð²ÐžÑÑ ÐœÐŸÐ²ÐŸÐ³ÐŸ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ}
+
+_textaboutusername_ [l=ru] {ÐÐ»ÐžÐœÐ° ÐžÐŒÐµÐœÐž Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ ÐŽÐŸÐ»Ð¶ÐœÐ° ÐœÐ°Ñ
+ÐŸÐŽÐžÑÑÑÑ Ð² Ð¿ÑÐµÐŽÐµÐ»Ð°Ñ
+ ÐŸÑ 2 ÐŽÐŸ 30 ÑÐžÐŒÐ²ÐŸÐ»ÐŸÐ². ÐÐœÐŸ ÐŒÐŸÐ¶ÐµÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÑÑ Ð±ÑÐºÐ²ÐµÐœÐœÐŸ-ÑÐžÑÑÐŸÐ²ÑÐµ ÑÐžÐŒÐ²ÐŸÐ»Ñ, Ð·ÐœÐ°ÐºÐž '.', Ðž '_'. }
+
+_textaboutpassword_ [l=ru] {ÐÐ°ÑÐŸÐ»Ñ ÐŒÐŸÐ¶ÐµÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÑÑ ÐŸÑ 3 ÐŽÐŸ 128 ÑÐžÐŒÐ²ÐŸÐ»ÐŸÐ². Ð ÐºÐ°ÑÐµÑÑÐ²Ðµ Ð¿Ð°ÑÐŸÐ»Ñ ÐŒÐŸÐ³ÑÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑÑÑ ÐŸÐ±ÑÑÐœÑÐµ Ð¿ÐµÑÐ°ÑÐ°ÐµÐŒÑÐµ ASCII ÑÐžÐŒÐ²ÐŸÐ»Ñ. }
+
+_textoldpass_ [l=ru] {ÐÑÐ»Ðž ÐŽÐ°ÐœÐœÐŸÐµ Ð¿ÐŸÐ»Ðµ Ð¿ÑÑÑÐŸÐµ, ÑÐŸ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐžÐ²Ð°ÐµÑÑÑ ÑÑÐ°ÑÑÐ¹ Ð¿Ð°ÑÐŸÐ»Ñ.}
+_textenabled_ [l=ru] {ÑÐ°Ð·ÑÐµÑÐµÐœÐŸ}
+_textdisabled_ [l=ru] {Ð·Ð°Ð¿ÑÐµÑÐµÐœÐŸ}
+
+_textaboutgroups_ [l=ru] {ÐÑÑÐ¿Ð¿Ñ - ÑÐ¿ÐžÑÐŸÐº ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐœÑÐ¹ Ð·Ð°Ð¿ÑÑÑÐŒÐž, Ð¿ÑÐŸÐ±ÐµÐ»Ñ Ð¿ÐŸÑÐ»Ðµ Ð·Ð°Ð¿ÑÑÑÑ
+ ÐœÐµ ÑÑÐ°Ð²ÑÑÑÑ! }
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=ru] {Ð£ÐŽÐ°Ð»ÐžÑÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ}
+_textremwarn_ [l=ru] {ÐÑ  ÐŽÐµÐ¹ÑÑÐ²ÐžÑÐµÐ»ÑÐœÐŸ Ñ
+ÐŸÑÐžÑÐµ ÐŸÐºÐŸÐœÑÐ°ÑÐµÐ»ÑÐœÐŸ ÑÐŽÐ°Ð»ÐžÑÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ _cgiargumun_?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=ru] {ÐÐ·ÐŒÐµÐœÐžÑÑ Ð¿Ð°ÑÐŸÐ»Ñ}
+_textoldpw_ [l=ru] {Ð¡ÑÐ°ÑÑÐ¹ Ð¿Ð°ÑÐŸÐ»Ñ}
+_textnewpw_ [l=ru] {ÐÐŸÐ²ÑÐ¹ Ð¿Ð°ÑÐŸÐ»Ñ}
+_textretype_ [l=ru] {ÐÐ²ÐµÐŽÐžÑÐµ Ð¿ÐŸÐ²ÑÐŸÑÐœÐŸ ÐœÐŸÐ²ÑÐ¹ Ð¿Ð°ÑÐŸÐ»Ñ}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=ru] {ÐÐ°Ñ Ð¿Ð°ÑÐŸÐ»Ñ Ð±ÑÐ» ÑÑÐ¿ÐµÑÐœÐŸ ÐžÐ·ÐŒÐµÐœÐµÐœ.}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=ru] {ÐÐµÐ²ÐµÑÐœÐŸÐµ ÐžÐŒÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ.}
+_textinvalidpassword_ [l=ru] {ÐÐµÐ²ÐµÑÐœÑÐ¹ Ð¿Ð°ÑÐŸÐ»Ñ.}
+_textemptypassword_ [l=ru] {ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ°, Ð²Ð²ÐµÐŽÐžÑÐµ ÐœÐ°ÑÐ°Ð»ÑÐœÑÐ¹ Ð¿Ð°ÑÐŸÐ»Ñ ÐŽÐ»Ñ ÐŽÐ°ÐœÐœÐŸÐ³ÐŸ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ.}
+_textuserexists_ [l=ru] {ÐÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ Ñ ÑÐ°ÐºÐžÐŒ ÐžÐŒÐµÐœÐµÐŒ ÑÐ¶Ðµ ÑÑÑÐµÑÑÐ²ÑÐµÑ, ÐžÐ·ÐŒÐµÐœÐžÑÐµ ÐžÐŒÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ.}
+
+_textusernameempty_ [l=ru] {ÐÐ²ÐµÐŽÐžÑÐµ ÑÐ²ÐŸÐ¹ ÐœÐŸÐ²ÑÐ¹ Ð¿Ð°ÑÐŸÐ»Ñ Ðž Ð¿ÐŸÐŽÑÐ²ÐµÑÐŽÐžÑÐµ ÐµÐ³ÐŸ ÐµÑÐµ ÑÐ°Ð·.}
+_textpasswordempty_ [l=ru] {ÐÑ ÐŽÐŸÐ»Ð¶ÐœÑ Ð²Ð²ÐµÑÑÐž ÐÐ°Ñ ÑÑÐ°ÑÑÐ¹ Ð¿Ð°ÑÐŸÐ»Ñ.
+}
+_textnewpass1empty_ [l=ru] {ÐÐ²ÐµÐŽÐžÑÐµ ÐÐ°Ñ ÐœÐŸÐ²ÑÐ¹ Ð¿Ð°ÑÐŸÐ»Ñ Ðž Ð·Ð°ÑÐµÐŒ Ð¿ÐŸÐ²ÑÐŸÑÐžÑÐµ Ð²Ð²ÐŸÐŽ.}
+_textnewpassmismatch_ [l=ru] {ÐÐ²ÐµÐŽÐµÐœÑ ÑÐ°Ð·ÐœÑÐµ Ð²ÐµÑÑÐžÐž Ð²Ð°ÑÐµÐ³ÐŸ ÐœÐŸÐ²ÐŸÐ³ÐŸ Ð¿Ð°ÑÐŸÐ»Ñ.}
+_textnewinvalidpassword_ [l=ru] {ÐÐ°ÑÐµ ÐžÐŒÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ ÐžÐ»Ðž Ð¿Ð°ÑÐŸÐ»Ñ Ð±ÑÐ»Ðž Ð²Ð²ÐµÐŽÐµÐœÑ ÐœÐµÐ¿ÑÐ°Ð²ÐžÐ»ÑÐœÐŸ.}
+_textfailed_ [l=ru] {ÐÐžÐ±ÐŸ ÐÐ°ÑÐµ ÐžÐŒÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ ÐžÐ»Ðž Ð¿Ð°ÑÐŸÐ»Ñ Ð±ÑÐ»Ðž ÐœÐµÐºÐŸÑÑÐµÐºÑÐœÑ}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=ru] {ÐÐµÑÑÐžÑ Greenstone}  
+_textframebrowser_ [l=ru] {ÐÐ»Ñ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° ÑÐŸÐŽÐµÑÐ¶ÐžÐŒÐŸÐ³ÐŸ, ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÐŸ ÑÑÑÐ°ÐœÐŸÐ²ÐžÑÑ Ð² Ð²Ð°ÑÐµÐŒ Ð±ÑÐ°ÑÐ·ÐµÑÐµ ÑÐ°Ð·ÑÐµÑÐµÐœÐžÐµ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÐž ÑÑÐµÐ¹ÐŒÐŸÐ². }  
+_textusermanage_ [l=ru] {Ð£Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÐµ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÑÐŒÐž}
+_textlistusers_ [l=ru] {Ð¡Ð¿ÐžÑÐŸÐº Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐ¹}
+_textaddusers_ [l=ru] {ÐÐŸÐ±Ð°Ð²ÐžÑÑ ÐœÐŸÐ²ÐŸÐ³ÐŸ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ}
+_textchangepasswd_ [l=ru] {ÐÐ·ÐŒÐµÐœÐžÑÑ Ð¿Ð°ÑÐŸÐ»Ñ}
+_textinfo_ [l=ru] {Ð¢ÐµÑ
+ÐœÐžÑÐµÑÐºÐ°Ñ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ}
+_textgeneral_ [l=ru] {ÐÐ±ÑÐžÐµ}
+_textarguments_ [l=ru] {Ð°ÑÐ³ÑÐŒÐµÐœÑÑ}
+_textactions_ [l=ru] {ÐŽÐµÐ¹ÑÑÐ²ÐžÑ}
+_textbrowsers_ [l=ru] {Ð±ÑÐ°ÑÐ·ÐµÑÑ}  
+_textprotocols_ [l=ru] {Ð¿ÑÐŸÑÐŸÐºÐŸÐ»Ñ}
+_textconfigfiles_ [l=ru] {Ð€Ð°Ð¹Ð» ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐž}
+_textlogs_ [l=ru] {Ð ÐµÐ³ÐžÑÑÑÐ°ÑÐžÑ}
+_textusagelog_ [l=ru] {Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÑÑÐºÐ°Ñ ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÑ}
+_textinitlog_ [l=ru] {ÐÐ°ÑÐ°Ð»ÐŸ ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÐž}
+_texterrorlog_ [l=ru] {ÐŸÑÐžÐ±ÐºÐ° ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÐž}
+_textadminhome_ [l=ru] {ÐÐŸÐŒÐ°ÑÐœÑÑ ÑÑÑÐ°ÐœÐžÑÐ° Ð°ÐŽÐŒÐžÐœÐžÑÑÑÐ°ÑÐŸÑÐ°}
+_textreturnhome_ [l=ru] {ÐÐŸÐŒÐ°ÑÐœÑÑ ÑÑÑÐ°ÐœÐžÑÐ° Greenstone}  
+_titlewelcome_ [l=ru] {ÐÐŽÐŒÐžÐœÐžÑÑÑÐžÑÐŸÐ²Ð°ÐœÐžÐµ }
+_textmaas_ [l=ru] {Ð¡Ð»ÑÐ¶Ð±Ð° Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÐž Ðž Ð°ÐŽÐŒÐžÐœÐžÑÑÑÐžÑÐŸÐ²Ð°ÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ð²ÐºÐ»ÑÑÐ°ÐµÑ:}
+_textvol_ [l=ru] {Ð¿ÑÐŸÑÐŒÐŸÑÑ Ð»ÐŸÐ³ÐŸÐ² Ð² ÑÐµÐ¶ÐžÐŒÐµ ÐŸÐœ-Ð»Ð°Ð¹Ðœ}
+_textcmuc_ [l=ru] {ÑÐŸÐ·ÐŽÐ°ÐœÐžÐµ, Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÐ° Ðž ÐŸÐ±ÐœÐŸÐ²Ð»ÐµÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž}
+_textati_ [l=ru] {ÐÐŸÑÑÑÐ¿ Ðº ÑÐµÑ
+ÐœÐžÑÐµÑÐºÐŸÐ¹ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž, ÑÐžÐ¿Ð° Ð¿Ð°ÑÐ°ÐŒÐµÑÑÐŸÐ² CGI ÑÐºÑÐžÐ¿ÑÐŸÐ²}
+
+_texttsaa_ [l=ru] {Ð ÑÑÐžÐŒ ÑÑÐ»ÑÐ³Ð°ÐŒ ÐŸÐ±ÑÐ°ÑÐ°ÑÑÑÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ ÐœÐ°Ð²ÐžÐ³Ð°ÑÐžÐŸÐœÐœÐŸÐµ ÐŒÐµÐœÑ ÐœÐ° Ð»ÐµÐ²ÐŸÐ¹ ÑÑÐŸÑÐŸÐœÐµ ÑÑÑÐ°ÐœÐžÑÑ. }
+
+_textcolstat_ [l=ru] {Ð¡ÑÐ°ÑÑÑ ÐÐŸÐ»Ð»ÐµÐºÑÐžÐž}
+
+_textcwoa_ [l=ru] {ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ Ð¿ÐŸÑÐ²ÐžÑÑÑ Ðž Ð±ÑÐŽÐµÑ "Ð·Ð°Ð¿ÑÑÐµÐœÐ°", ÑÐŸÐ»ÑÐºÐŸ Ð¿ÑÐž ÑÑÐ»ÐŸÐ²ÐžÐž, ÐµÑÐ»Ðž Ð¿ÑÐžÑÑÑÑÑÐ²ÑÐµÑ ÐµÐµ ÑÐ°Ð¹Ð» build.cfg, ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ Ð¿ÑÐŸÑÐžÑÐ°Ðœ ÑÐžÑÑÐµÐŒÐŸÐ¹, ÑÐŸÐŽÐµÑÐ¶Ð°Ñ ÐŽÐŸÐ¿ÑÑÑÐžÐŒÐŸÐµ Ð¿ÐŸÐ»Ðµ  builddate ÑÐŸ Ð·ÐœÐ°ÑÐµÐœÐžÐµÐŒ Ð±ÐŸÐ»ÑÑÐµ ÐœÑÐ»Ñ, Ðž ÐœÐ°Ñ
+ÐŸÐŽÑÑÑÑ Ð² Ð¿Ð°Ð¿ÐºÐµ index Ð²Ð°ÑÐµÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž (ÐÐ Ð² Ð¿Ð°Ð¿ÐºÐµ building). }
+
+_textcafi_ [l=ru] {ÐÐ°Ð¶ÐŒÐžÑÐµ <i>ÐÐ±Ð±ÑÐµÐ².</i> ÐŽÐ»Ñ Ð¿ÐŸÐ»ÑÑÐµÐœÐžÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž ÐŸ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž}
+_textcctv_ [l=ru] {ÐÐ°Ð¶ÐŒÐžÑÐµ <i>ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ</i> ÐŽÐ»Ñ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž}
+_textsubc_ [l=ru] {ÐÐŸÐŽÑÐ²ÐµÑÐŽÐžÑÑ ÐžÐ·ÐŒÐµÐœÐµÐœÐžÑ}
+_texteom_ [l=ru] {ÐÑÐžÐ±ÐºÐ° ÐŸÑÐºÑÑÑÐžÑ main.cfg}
+_textftum_ [l=ru] {Ð¡Ð±ÐŸÐ¹ ÐŸÐ±ÐœÐŸÐ²Ð»ÐµÐœÐžÑ main.cfg}
+_textmus_ [l=ru] {Ð£ÑÐ¿ÐµÑÐœÐŸÐµ ÐŸÐ±ÐœÐŸÐ²Ð»ÐµÐœÐžÐµ main.cfg}
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=ru] {Ð ÐµÐ·ÑÐŒÐµ Ð¿ÑÐŸÑÐµÑÑÐ° ÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÐœÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž _collectionname_ }
+_textflog_ [l=ru] {Ð€Ð°Ð¹Ð» ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÐž ÑÐ±ÐŸÐµÐ² ÐŽÐ»Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž _collectionname_}  
+_textilog_ [l=ru] {Ð ÐµÐ³ÐžÑÑÑÐ°ÑÐžÐŸÐŸÐœÑÐ¹ ÑÐ°Ð¹Ð» ÐŽÐ»Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž "_collectionname_"}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=ru] {ÐÐ¢ÐÐ¡ÐÐÐ¢Ð¬ ÐÐÐ ÐÐ¢ÐÐ}  
+
+_greenstoneusabilitytext_ [l=ru] {ÐÑÐžÐŒÐµÐœÐžÐŒÐŸÑÑÑ Greenstone}  
+
+_textwhy_ [l=ru] {<p>ÐÑÐ¿ÑÐ°Ð²ÐºÐ° ÑÑÐŸÐ³ÐŸ ÑÐŸÐŸÐ±ÑÐµÐœÐžÑ - ÑÑÐŸ ÑÐ¿ÐŸÑÐŸÐ± ÑÐºÐ°Ð·Ð°ÑÑ, ÑÑÐŸ ÐÑ ÐœÐ°ÑÐ»Ðž Ð²ÐµÐ±-ÑÑÑÐ°ÐœÐžÑÑ, ÐºÐŸÑÐŸÑÑÑ Ð±ÑÐ»ÐŸ ÑÑÑÐŽÐœÐŸ Ð¿ÑÐŸÑÐŒÐŸÑÑÐµÑÑ.}  
+_textextraforform_ [l=ru] {ÐÑ ÐœÐµ ÐŽÐŸÐ»Ð¶ÐœÑ Ð·Ð°Ð¿ÐŸÐ»ÐœÑÑÑ ÑÑÑ ÑÐŸÑÐŒÑ - Ð»ÑÐ±Ð°Ñ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ Ð¿ÐŸÐŒÐŸÐ¶ÐµÑ.}
+_textprivacybasic_ [l=ru] {<p> Ð­ÑÐŸ ÑÐŸÐŸÐ±ÑÐµÐœÐžÐµ Ð±ÑÐŽÐµÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÑÑ ÑÐŸÐ»ÑÐºÐŸ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ Ð²ÐµÐ±-ÑÑÑÐ°ÐœÐžÑÐµ Greenstone, ÐºÐŸÑÐŸÑÑÑ ÐÑ ÑÐ°ÑÑÐŒÐ°ÑÑÐžÐ²Ð°Ð»Ðž, Ðž ÑÐµÑ
+ÐœÐŸÐ»ÐŸÐ³ÐžÐž, ÐºÐŸÑÐŸÑÑÑ ÐÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°Ð»Ðž ÐŽÐ»Ñ ÐµÐµ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° (ÑÐ°ÐºÐ¶Ðµ Ð»ÑÐ±Ð°Ñ ÐŽÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÐ°Ñ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ, ÐºÐŸÑÐŸÑÑÑ ÐÑ Ð¿ÑÐµÐŽÐŸÑÑÐ°Ð²Ð»ÑÐµÑÐµ).}  
+_textstillsend_ [l=ru] {ÐÑ Ð²ÑÐµ ÐµÑÐµ Ñ
+ÐŸÑÐµÐ»Ðž Ð±Ñ Ð¿ÐŸÑÐ»Ð°ÑÑ ÑÑÐŸ ÑÐŸÐŸÐ±ÑÐµÐœÐžÐµ?}  
+
+_texterror_ [l=ru] {ÐÑÐžÐ±ÐºÐ°}
+_textyes_ [l=ru] {ÐÐ°}  
+_textno_ [l=ru] {ÐÐµÑ}  
+_textclosewindow_ [l=ru] {ÐÐ°ÐºÑÑÑÑ ÐŸÐºÐœÐŸ}  
+_textabout_ [l=ru] {Ð}
+_textprivacy_ [l=ru] {Ð¡ÐµÐºÑÐµÑÐœÐŸ}
+_textsend_ [l=ru] {ÐÑÐ¿ÑÐ°Ð²ÐžÑÑ}
+_textdontsend_ [l=ru] {ÐÐµ Ð¿ÐŸÑÑÐ»Ð°ÑÑ}  
+_textoptionally_ [l=ru] {ÐÑÐŸÐžÐ·Ð²ÐŸÐ»ÑÐœÐŸ}
+
+_textunderdev_ [l=ru] {ÐÑÐµÐŽÐ²Ð°ÑÐžÑÐµÐ»ÑÐœÑÐ¹ Ð¿ÑÐŸÑÐŒÐŸÑÑ ÐŽÐµÑÐ°Ð»ÐµÐ¹ Ð±ÑÐŽÐµÑ ÐŽÐŸÑÑÑÐ¿ÐµÐœ Ð² Ð·Ð°ÐºÐ»ÑÑÐžÑÐµÐ»ÑÐœÐŸÐ¹ Ð²ÐµÑÑÐžÐž.}  
+
+_textviewdetails_ [l=ru] {ÐÑÐŸÑÐŒÐŸÑÑÐµÑÑ ÐŽÐµÑÐ°Ð»Ðž ÑÐŸÐŸÐ±ÑÐµÐœÐžÑ}  
+_textmoredetails_ [l=ru] {ÐÐŸÐ»ÑÑÐµ ÐŽÐµÑÐ°Ð»ÐµÐ¹}  
+_texttrackreport_ [l=ru] {ÐÑÑÐ»ÐµÐŽÐžÑÑ ÑÑÐŸ ÑÐŸÐŸÐ±ÑÐµÐœÐžÐµ}  
+_textcharacterise_ [l=ru] {ÐÐ°ÐºÐŸÐ³ÐŸ Ð¿Ð»Ð°ÐœÐ° ÑÑÐ° Ð¿ÑÐŸÐ±Ð»ÐµÐŒÐ°}
+_textseverity_ [l=ru] {ÐÐ°ÑÐºÐŸÐ»ÑÐºÐŸ Ð¿Ð»ÐŸÑ
+Ð° ÑÑÐ° Ð¿ÑÐŸÐ±Ð»ÐµÐŒÐ°}  
+ 
+_textbadrender_ [l=ru] {Ð¡ÑÑÐ°ÐœÐžÑÐ° Ð²ÑÐ³Ð»ÑÐŽÐžÑ ÑÑÑÐ°ÐœÐœÐŸ}
+_textcontenterror_ [l=ru] {ÐÑÐžÐ±ÐºÐ° ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÑ}  
+_textstrangebehaviour_ [l=ru] {Ð¡ÑÑÐ°ÐœÐœÐŸÐµ Ð¿ÐŸÐ²ÐµÐŽÐµÐœÐžÐµ}  
+_textunexpected_ [l=ru] {Ð¡Ð»ÑÑÐžÐ»ÐŸÑÑ ÑÑÐŸ-ÑÐŸ ÐœÐµÐŸÐ¶ÐžÐŽÐ°ÐœÐœÐŸÐµ.}  
+_textfunctionality_ [l=ru] {Ð¢ÑÑÐŽÐœÐŸ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ}  
+_textother_ [l=ru] {ÐÑÑÐ³ÐŸÐµ}
+
+_textcritical_ [l=ru] {ÐÑÐžÑÐžÑÐœÐŸ}
+_textmajor_ [l=ru] {Ð¡ÐµÑÑÐµÐ·ÐœÐŸ}
+_textmedium_ [l=ru] {Ð¡ÑÐµÐŽÐœÐµ}
+_textminor_ [l=ru] {ÐÐµÐœÑÑÐµ}
+_texttrivial_ [l=ru] {Ð¢ÑÐžÐ²ÐžÐ°Ð»ÑÐœÐŸ}
+
+_textwhatdoing_ [l=ru] {Ð§ÑÐŸ ÐÑ Ð¿ÑÐŸÐ±ÐŸÐ²Ð°Ð»Ðž ÑÐŽÐµÐ»Ð°ÑÑ?}  
+_textwhatexpected_ [l=ru] {Ð§ÐµÐ³ÐŸ Ð²Ñ ÐŸÐ¶ÐžÐŽÐ°Ð»Ðž?}
+_textwhathappened_ [l=ru] {Ð§ÑÐŸ ÑÐ»ÑÑÐžÐ»ÐŸÑÑ ÑÐ°ÐºÑÐžÑÐµÑÐºÐž?}
+
+_cannotfindcgierror_ [l=ru] {<h2>Ð ÑÐŸÐ¶Ð°Ð»ÐµÐœÐžÑ</h2>ÐœÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐœÐ°Ð¹ÑÐž ÑÐµÑÐ²ÐµÑÐœÑÐµ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑ ÐŽÐ»Ñ ÐºÐœÐŸÐ¿ÐºÐž "Ñ Ð±Ñ Ñ
+ÐŸÑÐµÐ» ÑÐŸÐŸÐ±ÑÐžÑÑ" }
+
+_textusabbanner_ [l=ru] {ÐÐ°ÐœÐœÐµÑ koru-ÑÑÐžÐ»Ñ Greenstone}  
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=ru] {ÐÐŸÐ·ÐœÐžÐºÐ»Ð° ÐŸÑÐžÐ±ÐºÐ°}  
+
+_textgtihome_ [l=ru] {Ð­ÑÐž ÑÑÑÐ°ÐœÐžÑÑ Ð¿ÑÐµÐŽÐœÐ°Ð·ÐœÐ°ÑÐµÐœÑ ÐŽÐ»Ñ ÑÐ»ÑÑÑÐµÐœÐžÑ ÑÐ·ÑÐºÐŸÐ²ÐŸÐ¹ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÐž Ð² Greenstone. ÐÐŽÐµÑÑ ÐÑ ÑÐŒÐŸÐ¶ÐµÑÐµ
+<ul>
+  <li>Ð¿ÐµÑÐµÐ²ÐµÑÑÐž ÑÐ°ÑÑÐž Greenstone ÐœÐ° ÐŽÑÑÐ³ÐžÐµ ÑÐ·ÑÐºÐž
+  <li>ÐŸÑÐºÐŸÑÑÐµÐºÑÐžÑÐŸÐ²Ð°ÑÑ ÑÑÑÐµÑÑÐ²ÑÑÑÐžÐ¹ ÑÐ·ÑÐºÐŸÐ²ÐŸÐ¹ ÐžÐœÑÐµÑÑÐµÐ¹Ñ Ð² ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐžÐž Ñ ÐœÐŸÐ²ÑÐŒÐž ÑÑÐœÐºÑÐžÑÐŒÐž Ð² Greenstone
+  <li>ÐŸÑÐºÐŸÑÑÐµÐºÑÐžÑÐŸÐ²Ð°ÑÑ ÑÑÑÐµÑÑÐ²ÑÑÑÐžÐµ Ð¿ÐµÑÐµÐ²ÐŸÐŽÑ
+</ul>
+
+ÐÑ ÑÐ²ÐžÐŽÐµÑÐµ ÑÐµÑÐžÑ Ð²ÐµÐ±ÑÑÑÐ°ÐœÐžÑ, ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐžÑ
+ ÐœÐµÑÐºÐŸÐ»ÑÐºÐŸ ÑÑÐ°Ð· ÐŽÐ»Ñ Ð¿ÐµÑÐµÐ²ÐŸÐŽÐ°.
+ÐÐµÑÐµÐ²ÐŸÐŽ ÐžÐœÑÐµÑÑÐµÐ¹ÑÐ° ÐœÐ° ÐœÐŸÐ²ÑÐ¹ ÑÐ·ÑÐº Ð¿ÑÐŸÐ²ÐŸÐŽÐžÑÑÑ Ð¿ÐŸ-ÑÑÐ°Ð·ÐœÐŸ. 
+ÐÐœÐŸÐ³ÐžÐµ ÑÑÐ°Ð·Ñ ÑÐŸÐŽÐµÑÐ¶Ð°Ñ ÑÐŸÑÐŒÐ°ÑÐžÑÐŸÐ²Ð°ÐœÐžÐµ Ð² HTML: ÐœÐµ Ð¿ÐµÑÐµÐ²ÐŸÐŽÐžÑÐµ ÑÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ Ðž Ð²ÐºÐ»ÑÑÐ°Ð¹ÑÐµ ÐµÐµ Ð² ÑÐŸÐŸÑÐ²ÐµÑÑÐ²ÑÑÑÐžÑ
+ ÐŒÐµÑÑÐ°Ñ
+ Ð¿ÐµÑÐµÐ²ÐµÐŽÐµÐœÐœÐŸÐ³ÐŸ ÑÐµÐºÑÑÐ°. Ð¡Ð»ÐŸÐ²Ð°, Ð·Ð°ÐºÐ»ÑÐµÐœÐœÑÐµ Ð² Ð¿ÐŸÐŽÑÐµÑÐºÐžÐ²Ð°ÑÑÐžÐµ Ð·ÐœÐ°ÐºÐž (ÐºÐ°Ðº _ÑÑÐŸ_), ÑÐŸÐ¶Ðµ ÐœÐµ ÐœÑÐ¶ÐŽÐ°ÑÑÑÑ Ð² Ð¿ÐµÑÐµÐ²ÐŸÐŽÐµ. (Ð­ÑÐŸ "ÐŒÐ°ÐºÑÐŸ" ÐœÐ°Ð·Ð²Ð°ÐœÐžÑ Ð² Greenstone.)
+<p>
+ÐÑÐ»Ðž ÐÑ ÐºÐŸÑÑÐµÐºÑÐžÑÑÐµÑÐµ ÑÑÑÐµÑÑÐ²ÑÑÑÐžÐµ Ð¿ÐµÑÐµÐ²ÐŸÐŽÑ, ÐÐ°ÐŒ Ð±ÑÐŽÑÑ Ð¿ÑÐµÐŽÑÑÐ°Ð²Ð»ÐµÐœÑ ÑÐŸÐ»ÑÐºÐŸ ÑÐµ ÑÑÐ°Ð·Ñ, Ð² ÐºÐŸÑÐŸÑÑÑ
+ Ð°ÐœÐ³Ð»ÐžÐ¹ÑÐºÐžÐ¹ ÐžÑÑ
+ÐŸÐŽÐœÑÐ¹ ÑÐµÐºÑÑ Ð±ÑÐ» ÐžÐ·ÐŒÐµÐœÐµÐœ. ÐÑÐŸÐ²ÐµÑÑÑÐµ, ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÐµÑ Ð»Ðž Ð¿ÐµÑÐµÐ²ÐŸÐŽ ÑÑÐžÑ
+ ÑÑÐ°Ð·, Ðž Ð²ÐœÐµÑÐžÑÐµ ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÑÐµ ÐžÐ·ÐŒÐµÐœÐµÐœÐžÑ. 
+<p>
+ÐÐ°Ð¶ÐŽÐ°Ñ ÑÑÑÐ°ÐœÐžÑÐ° Ð·Ð°ÐºÐ°ÐœÑÐžÐ²Ð°ÐµÑÑÑ ÐºÐœÐŸÐ¿ÐºÐŸÐ¹ "_textgtisubmit_". ÐÐ°Ð¶Ð°Ð² ÐµÐµ, ÐÑ ÑÑÐ°Ð·Ñ Ð¶Ðµ ÑÐŸÑ
+ÑÐ°ÐœÑÐµÑÐµ ÐžÐ·ÐŒÐµÐœÐµÐœÐžÑ Ð² ÐžÐœÑÑÐ°Ð»ÑÑÐžÐŸÐœÐœÐŸÐŒ Ð¿Ð°ÐºÐµÑÐµ Greenstone ÐœÐ° nzdl.org. Ð¡ ÐºÐ°Ð¶ÐŽÐŸÐ¹ ÑÑÑÐ°ÐœÐžÑÐµ Ð²Ñ ÐŒÐŸÐ¶ÐµÑÐµ Ð¿ÐŸÐ¿Ð°ÑÑÑ ÐœÐ° ÑÑÐŸÑ ÑÐ°Ð¹Ñ.
+}  
+
+_textgtiselecttlc_ [l=ru] {ÐÑÐ±ÐµÑÐžÑÐµ ÐÐ°Ñ ÑÐ·ÑÐº}  
+
+#for status page
+_textgtiviewstatus_ [l=ru] {ÐÐ°Ð¶ÐŒÐžÑÐµ, ÑÑÐŸÐ±Ñ ÑÐ²ÐžÐŽÐµÑÑ ÑÐ¿ÐžÑÐŸÐº Ð¿ÐµÑÐµÐ²ÐŸÐŽÐŸÐ² ÐœÐ° ÐŽÐ°ÐœÐœÐŸÐµ Ð²ÑÐµÐŒÑ ÐŽÐ»Ñ Ð²ÑÐµÑ
+ ÑÐ·ÑÐºÐŸÐ²}  
+_textgtiviewstatusbutton_ [l=ru] {ÐÐÐ¡ÐÐÐ¢Ð ÐÐ¢Ð¬ Ð¡Ð¢ÐÐ¢Ð£Ð¡}  
+_textgtistatustable_ [l=ru] {Ð¡Ð¿ÐžÑÐŸÐº Ð¿ÐµÑÐµÐ²ÐŸÐŽÐ° ÐŽÐ»Ñ Ð²ÑÐµÑ
+ ÑÐ·ÑÐºÐŸÐ² ÐœÐ° ÐœÐ°ÑÑÐŸÑÑÐµÐµ Ð²ÑÐµÐŒÑ}  
+_textgtilanguage_ [l=ru] {Ð¯Ð·ÑÐº}  
+_textgtitotalnumberoftranslations_ [l=ru] {ÐÐ±ÑÐµÐµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ Ð¿ÐµÑÐµÐ²ÐŸÐŽÐŸÐ²}  
+
+_textgtiselecttfk_ [l=ru] {ÐÑÐ±ÐµÑÐžÑÐµ ÑÐ°Ð¹Ð» ÐŽÐ»Ñ ÑÐ°Ð±ÐŸÑÑ}  
+
+_textgticoredm_ [l=ru] {ÐÐœÑÐµÑÑÐµÐ¹Ñ Greenstone (ÐŠÐµÐœÑÑÐ°Ð»ÑÐœÑÐ¹)}  
+_textgtiauxdm_ [l=ru] {ÐÐœÑÐµÑÑÐµÐ¹Ñ Greenstone (ÐÑÐ¿ÐŸÐŒÐŸÐ³Ð°ÑÐµÐ»ÑÐœÑÐ¹)}  
+_textgtiglidict_ [l=ru] {Ð¡Ð»ÐŸÐ²Ð°ÑÑ ÐÐÐ}  
+_textgtiglihelp_ [l=ru] {ÐÐŸÐŒÐŸÑÑ ÐŽÐ»Ñ ÐÐÐ}  
+_textgtiperlmodules_ [l=ru] {ÐÐŸÐŽÑÐ»Ðž Perl}  
+_textgtitutorials_ [l=ru] {Ð£ÑÐµÐ±ÐœÑÐµ ÑÐ¿ÑÐ°Ð¶ÐœÐµÐœÐžÑ}  
+_textgtigreenorg_ [l=ru] {Greenstone.org}  
+_textgtigs3core_ [l=ru] {ÐÐœÑÐµÑÑÐµÐ¹Ñ ÐÑÐžÐœÑÑÐŸÑÐœ (ÐÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ)}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=ru] {Ð ÑÐºÐŸÐ²ÐŸÐŽÑÑÐ²ÐŸ Ð Ð°Ð·ÑÐ°Ð±ÐŸÑÑÐžÐºÐ° ÐÑÐžÐœÑÑÐŸÑÐœ.}  
+_textgtiinstallmanual_ [l=ru] {Ð ÑÐºÐŸÐ²ÐŸÐŽÑÑÐ²ÐŸ Ð¿ÐŸ Ð£ÑÑÐ°ÐœÐŸÐ²ÐºÐµ ÐÑÐžÐœÑÑÐŸÑÐœ}  
+_textgtipapermanual_ [l=ru] {Ð ÑÐºÐŸÐ²ÐŸÐŽÑÑÐ²ÐŸ ÐÑÐžÐœÑÑÐŸÑÐœ ÐŽÐ»Ñ ÐÑÐŒÐ°Ð³Ð° Ð² ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ}  
+_textgtiusermanual_ [l=ru] {Ð ÑÐºÐŸÐ²ÐŸÐŽÑÑÐ²ÐŸ ÐÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ ÐÑÐžÐœÑÑÐŸÑÐœ}  
+
+_textgtienter_ [l=ru] {ÐÐÐÐ¢Ð}  
+
+_textgticorrectexistingtranslations_ [l=ru] {ÐÑÐºÐŸÑÑÐµÐºÑÐžÑÐŸÐ²Ð°ÑÑ ÑÑÑÐµÑÑÐ²ÑÑÑÐžÐµ Ð¿ÐµÑÐµÐ²ÐŸÐŽÑ}  
+_textgtidownloadtargetfile_ [l=ru] {Ð¡ÐºÐ°ÑÐ°ÑÑ ÑÐ°Ð¹Ð»}  
+_textgtiviewtargetfileinaction_ [l=ru] {ÐÐŸÑÐŒÐŸÑÑÐµÑÑ ÑÑÐŸÑ ÑÐ°Ð¹Ð» Ð² ÐŽÐµÐ¹ÑÑÐ²ÐžÐž}  
+_textgtitranslatefileoffline_ [l=ru] {ÐÐµÑÐµÐ²ÐµÑÑÐž ÑÑÐŸÑ ÑÐ°Ð¹Ð» ÐŸÑÑÐ»Ð°Ð¹Ðœ}  
+
+_textgtinumchunksmatchingquery_ [l=ru] {Ð§ÐžÑÐ»ÐŸ ÑÑÐ°Ð³ÐŒÐµÐœÑÐŸÐ² ÑÐµÐºÑÑÐ° ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÑÑÐžÑ
+ Ð·Ð°Ð¿ÑÐŸÑÑ}  
+
+_textgtinumchunkstranslated_ [l=ru] {Ð¿ÐµÑÐµÐ²ÐŸÐŽÐŸÐ² Ð·Ð°Ð²ÐµÑÑÐµÐœÐŸ}  
+_textgtinumchunksrequiringupdating_ [l=ru] {ÐÐ· ÐœÐžÑ
+, _1_ ÐœÑÐ¶ÐœÐŸ ÐŸÑÐºÐŸÑÑÐµÐºÑÐžÑÐŸÐ²Ð°ÑÑ}  
+_textgtinumchunksrequiringtranslation_ [l=ru] {Ð¿ÐµÑÐµÐ²ÐŸÐŽÐŸÐ² ÐŸÑÑÐ°Ð»ÐŸÑÑ}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=ru] {ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ Ð·Ð°ÐºÐŸÐœÑÐµÐœÐœÑÑ
+ Ð¿ÐµÑÐµÐ²ÐŸÐŽÐŸÐ²}  
+_textgtinumchunksrequiringupdating2_ [l=ru] {ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ Ð¿ÐµÑÐµÐ²ÐŸÐŽÐŸÐ², ÑÑÐµÐ±ÑÑÑÐžÑ
+ ÐŸÐ±ÐœÐŸÐ²Ð»ÐµÐœÐžÑ}  
+_textgtinumchunksrequiringtranslation2_ [l=ru] {ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ ÑÐŸÑ
+ÑÐ°ÐœÐµÐœÐžÐ¹ Ð¿ÐµÑÐµÐ²ÐŸÐŽÐŸÐ²}  
+
+_textgtienterquery_ [l=ru] {ÐÐ²ÐµÐŽÐžÑÐµ ÑÐ»ÐŸÐ²ÐŸ ÐžÐ»Ðž ÑÑÐ°Ð·Ñ ÐžÐ· ÑÑÐ°Ð³ÐŒÐµÐœÑÐ° ÑÐµÐºÑÑÐ°, ÐºÐŸÑÐŸÑÑÐ¹ ÐÑ Ð¶ÐµÐ»Ð°ÐµÑÐµ ÐŸÑÐºÐŸÑÑÐµÐºÑÐžÑÐŸÐ²Ð°ÑÑ}  
+_textgtifind_ [l=ru] {ÐÐÐÐ¢Ð}  
+
+_textgtitranslatingchunk_ [l=ru] {ÐÐµÑÐµÐ²ÐŸÐŽ ÑÑÐ°Ð³ÐŒÐµÐœÑÐ° ÑÐµÐºÑÑÐ°}  
+_textgtiupdatingchunk_ [l=ru] {ÐÐŸÑÑÐµÐºÑÐžÑÐŸÐ²ÐºÐ° ÑÑÐ°Ð³ÐŒÐµÐœÑÐ° ÑÐµÐºÑÑÐ° <i>_1_</i>}  
+_textgtisubmit_ [l=ru] {ÐÐ}  
+
+_textgtilastupdated_ [l=ru] {Ð Ð¿ÐŸÑÐ»ÐµÐŽÐœÐžÐ¹ ÑÐ°Ð· ÐžÐ·ÐŒÐµÐœÐµÐœ}  
+
+_textgtitranslationfilecomplete_ [l=ru] {Ð¡Ð¿Ð°ÑÐžÐ±ÐŸ Ð·Ð° ÐŸÐ±ÐœÐŸÐ²Ð»ÐµÐœÐžÐµ ÑÑÐŸÐ³ÐŸ ÑÐ°Ð¹Ð»Ð° -- ÑÐµÐ¿ÐµÑÑ ÐŸÐœ Ð·Ð°Ð²ÐµÑÑÐµÐœ!<p>ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ ÑÐºÐ°ÑÐ°ÑÑ ÐºÐŸÐ¿ÐžÑ ÑÑÐŸÐ³ÐŸ ÑÐ°Ð¹Ð»Ð° Ñ Ð¿ÐŸÐŒÐŸÑÑÑ ÑÑÑÐ»ÐºÐž Ð²Ð²ÐµÑÑ
+Ñ, Ðž ÐŸÐœ Ð±ÑÐŽÐµÑ ÑÐ°ÐºÐ¶Ðµ Ð²ÐºÐ»ÑÑÐµÐœ Ð² Ð±ÑÐŽÑÑÐžÐµ Ð²ÑÐ¿ÑÑÐºÐž Greenstone.}  
+
+_textgtiofflinetranslation_ [l=ru] {ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ  Ð¿ÐµÑÐµÐ²ÐµÑÑÐž ÑÑÑ ÑÐ°ÑÑÑ ÐÑÐžÐœÑÑÐŸÑÐœ ÐŸÑÑÐ»Ð°Ð¹Ðœ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ Microsoft Excel ÑÐ°Ð¹Ð»:
+
+<ol>
+<li>Ð¡ÐºÐ°ÑÐ°ÑÑ <a href="_gwcgi_?a=gti&p=excel&e=_compressedoptions_">ÑÑÐŸÑ ÑÐ°Ð¹Ð»</a>.
+<li>ÐÑÐºÑÑÑÑ ÑÐºÐ°ÑÐ°ÐœÑÐ¹ ÑÐ°Ð¹Ð» Ð² Microsoft Excel Ðž ÑÐŸÑ
+ÑÐ°ÐœÐžÑÑ ÐºÐ°Ðº  Microsoft Excel workbook (.xls) ÑÐŸÑÐŒÐ°Ñ.
+<li>ÐÐœÐµÑÐžÑÐµ Ð¿ÐµÑÐµÐ²ÐŸÐŽ Ð² Ð¿ÑÐµÐŽÐ»ÐŸÐ¶ÐµÐœÐœÑÐµ ÐºÐ»ÐµÑÐºÐž.
+<li>ÐÐŸÐ³ÐŽÐ° Ð²Ñ Ð·Ð°ÐºÐŸÐœÑÐžÑÐµ Ð¿ÐµÑÐµÐ²ÐŸÐŽ Ð²ÑÐµÑ
+ ÑÑÑÐžÐœÐ³ÐŸÐ², ÐŸÑÐŸÑÐ»ÐžÑÐµ .xls ÑÐ°Ð¹Ð» ÐœÐ° ÐµÐŒÐ°Ð¹Ð» <a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>.
+</ol>}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=ru] {ÐÐžÐ±Ð»ÐžÐŸÑÐµÑÐœÑÐ¹ ÐÐœÑÐµÑÑÐµÐ¹Ñ Greenstone}  
+_textglihelp_ [l=ru] {ÐÐžÐ±Ð»ÐžÐŸÑÐµÑÐœÑÐ¹ ÐÐœÑÐµÑÑÐµÐ¹Ñ Greenstone (ÐÐÐ) ÐŽÐ°ÑÑ ÐÐ°ÐŒ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÑ Ð¿ÐŸÐ»ÑÑÐžÑÑ ÐŽÐŸÑÑÑÐ¿ Ðº ÑÑÐœÐºÑÐžÐŸÐœÐ°Ð»ÑÐœÑÐŒ
+ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÑÐŒ Greenstone, ÑÐŽÐŸÐ±ÐœÐŸÐŒÑ Ð² ÑÐ°Ð±ÐŸÑÐµ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑ - ÑÐºÐ°Ð¶ÐžÑÐµ Ðž ÑÐµÐ»ÐºÐœÐžÑÐµ. ÐÐœ Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ ÐÐ°ÐŒ ÑÐŸÐ±ÐžÑÐ°ÑÑ Ð¿ÐŸÐŽÐ±ÐŸÑÐºÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ ÐžÐ»Ðž Ð·Ð°ÐŽÐ°Ð²Ð°ÑÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ Ðž Ð²ÑÑÑÐ°ÐžÐ²Ð°ÑÑ ÐžÑ
+ Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ Greenstone.
+ 
+ ÐÐ±ÑÐ°ÑÐžÑÐµ Ð²ÐœÐžÐŒÐ°ÐœÐžÐµ, ÑÑÐŸ ÐÐÐ ÑÐ²ÑÐ·Ð°Ðœ Ñ Greenstone. ÐÑÐµÐŽÐ¿ÐŸÐ»Ð°Ð³Ð°ÐµÑÑÑ, ÑÑÐŸ ÐŸÐœÐ° ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐ° Ð² Ð¿ÐŸÐŽÐŽÐžÑÐµÐºÑÐŸÑÐžÐž Ð¿ÑÐž ÐžÐœÑÑÐ°Ð»Ð»ÑÑÐžÐž Greenstone. ÐÑÐ»Ðž ÐÑ Ð·Ð°Ð³ÑÑÐ·ÐžÐ»Ðž ÐŸÐŽÐžÐœ ÐžÐ· ÐŽÐžÑÑÑÐžÐ±ÑÑÐžÐ²ÐŸÐ² Greenstone ÐžÐ»Ðž ÑÑÑÐ°ÐœÐŸÐ²ÐžÐ»Ðž ÐµÐ³ÐŸ Ñ CD-ROM, ÑÐŸ ÑÑÐŸ Ð±ÑÐŽÐµÑ ÐžÐŒÐµÑÑ ÐŒÐµÑÑÐŸ.
+ 
+ 
+ <h4>ÐÐ°Ð¿ÑÑÐº ÐÐÐ Ð¿ÐŸÐŽ Windows</h4>
+ 
+ ÐÐŸÐŽ Windows, ÐÐ°Ð¿ÑÑÑÐžÑÐµ ÐÐžÐ±Ð»ÐžÐŸÑÐµÑÐœÑÐ¹ ÐÐœÑÐµÑÑÐµÐ¹Ñ, Ð²ÑÐ±ÐµÑÐžÑÐµ Ð­Ð»ÐµÐºÑÑÐŸÐœÐœÐ°Ñ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ° Greenstone ÐžÐ· Ð¿ÐŸÐŽÐŒÐµÐœÑ ÐÑÐŸÐ³ÑÐ°ÐŒÐŒÑ ÐŒÐµÐœÑ Ð¡ÑÐ°ÑÑ Ðž Ð² ÐœÐµÐŒ - ÐÐžÐ±Ð»ÐžÐŸÑÐµÑÐœÑÐ¹ ÐžÐœÑÐµÑÑÐµÐ¹Ñ.     
+  
+ <h4>ÐÐ°Ð¿ÑÑÐº ÐÐÐ Ð¿ÐŸÐŽ Unix</h4>
+ 
+ Ð§ÑÐŸÐ±Ñ Ð·Ð°Ð¿ÑÑÑÐžÑÑ ÐÐÐ Ð¿ÐŸÐŽ Unix, ÐŸÑÐºÑÐŸÐ¹ÑÐµ ÐŽÐžÑÐµÐºÑÐŸÑÐžÑ gli Ð² Ð²Ð°ÑÐµÐŒ
+ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐœÐŸÐŒ Greenstone, Ð·Ð°ÑÐµÐŒ Ð·Ð°Ð¿ÑÑÑÐžÑÐµ ÑÐºÑÐžÐ¿Ñ gli.sh.
+}  
Index: /gsdl/stable/macros/serbian.dm
===================================================================
--- /gsdl/stable/macros/serbian.dm	(revision 20131)
+++ /gsdl/stable/macros/serbian.dm	(revision 20131)
@@ -0,0 +1,881 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Serbian (Latin version) Language text and icon macros 
+# Many thanks to Tamara Butigan (translated early 2004)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=sr] {PeriodiÄne publikacije}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=sr] {izvor:}
+_textdate_ [l=sr] {datum izdavanja:}
+_textnumpages_ [l=sr] {broj strana:}
+
+_textsignin_ [l=sr] {prijavljivanje}
+
+_textdefaultcontent_ [l=sr] {TraÅŸena stranica ne moÅŸe biti pronaÄena.
+Molimo da koristite dugme za povratak na prethodnu stranicu u vaÅ¡em web ÄitaÄu ili
+ dugme "home" za povratak u Greenstone digitalnu biblioteku.}
+
+_textdefaulttitle_ [l=sr] {GSDL greÅ¡ka}
+
+_textbadcollection_ [l=sr] {Ova kolekcija (pod imenom "_cvariable_") ne nalazi se na ovoj instalaciji Greenstone digitalne biblioteke}  
+
+_textselectpage_ [l=sr] {â Odaberi stranicu â}  
+
+_collectionextra_ [l=sr] {Ova kolekcija sadrÅŸi _about:numdocs_ dokumenata.
+Poslednji put je aÅŸurirana pre _about:builddate_
+dana.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=sr] {<p>Ova kolekcija sadrÅŸi _numdocs_ _If_("_numdocs_" eq
+"1",dokument,dokumenata), ukupno _numbytes_.
+<p><a href="_httppagex_(bsummary)">Kliknite ovde</a> da bi videli kratak opis kreiranja ove kolekcije. 
+}
+
+_textdescrcollection_ [l=sr] {}
+_textdescrabout_ [l=sr] {O stranici}
+_textdescrhome_ [l=sr] {Pristupna stranica}
+_textdescrhelp_ [l=sr] {Stranica za pomoÄ}
+_textdescrpref_ [l=sr] {Stranica za podeÅ¡avanja}
+_textdescrgreenstone_ [l=sr] {Softver za digitalne biblioteke Greenstone}
+_textdescrusab_ [l=sr] {Å ta vam je bilo teÅ¡ko za koriÅ¡Äenje?}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=sr] {PretraÅŸivanje}  
+_labelSearch_ [l=sr] {PretraÅŸivanje}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=sr] {Naslov}  
+_labelTitle_ [l=sr] {Naslovi A-Åœ/A-Ðš}
+_textCreator_ [l=sr] {Stvaralac}  
+_labelCreator_ [l=sr] {Autori A-Åœ/Ð-Ðš}
+_textSubject_ [l=sr] {Predmet}  
+_labelSubject_ [l=sr] {Oblasti}
+_textDescription_ [l=sr] {Opis}  
+_labelDescription_ [l=sr] {Opisi}  
+_textPublisher_ [l=sr] {IzdavaÄ}  
+_labelPublisher_ [l=sr] {IzdavaÄi}  
+_textContributor_ [l=sr] {Saradnik}  
+_labelContributor_ [l=sr] {Saradnici}  
+_textDate_ [l=sr] {Datum}  
+_labelDate_ [l=sr] {Datumi}
+_textType_ [l=sr] {Tip}  
+_labelType_ [l=sr] {Tipovi}  
+_textFormat_ [l=sr] {Format}  
+_labelFormat_ [l=sr] {Formati}  
+_textIdentifier_ [l=sr] {Identifikator}  
+_labelIdentifier_ [l=sr] {Identifikatori}  
+_textSource_ [l=sr] {Ime datoteke}  
+_labelSource_ [l=sr] {Imena datoteka}
+_textLanguage_ [l=sr] {Jezik}  
+_labelLanguage_ [l=sr] {Jezici}  
+_textRelation_ [l=sr] {Veza}  
+_labelRelation_ [l=sr] {Veze}  
+_textCoverage_ [l=sr] {Prenos}  
+_labelCoverage_ [l=sr] {Prenos}  
+_textRights_ [l=sr] {Prava}  
+_labelRights_ [l=sr] {Prava}  
+
+# DLS metadata set
+_textOrganization_ [l=sr] {Organizacija}  
+_labelOrganization_ [l=sr] {Organizacije}  
+_textKeyword_ [l=sr] {KljuÄna reÄ}  
+_labelKeyword_ [l=sr] {KljuÄne reÄi}
+_textHowto_ [l=sr] {Kako da}  
+_labelHowto_ [l=sr] {Kako da}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=sr] {Fraza}  
+_labelPhrase_ [l=sr] {ReÄenice}
+_textCollage_ [l=sr] {Sastaviti}  
+_labelCollage_ [l=sr] {Sastaviti}  
+_textBrowse_ [l=sr] {Listati}  
+_labelBrowse_ [l=sr] {Listati}  
+_textTo_ [l=sr] {Prema}  
+_labelTo_ [l=sr] {Kome}
+_textFrom_ [l=sr] {Od}  
+_labelFrom_ [l=sr] {Od koga}
+_textAcronym_ [l=sr] {SkraÄenica}  
+_labelAcronym_ [l=sr] {Akronimi}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=sr] {Prelistavanje od _1_}  
+
+_textdescrSearch_ [l=sr] {PretraÅŸivanje specifiÄnih termina}
+_textdescrType_ [l=sr] {Prelistavanje po tipu izvora}  
+_textdescrIdentifier_ [l=sr] {Prelistavanje identifikatora izvora}  
+_textdescrSource_ [l=sr] {Prelistavanje originalnih imena datoteka}
+_textdescrTo_ [l=sr] {Prelistavanje po polju "Prema"}  
+_textdescrFrom_ [l=sr] {Prelistavanje po polju "Od koga"}
+_textdescrCollage_ [l=sr] {Prelistavanje baze slika}  
+_textdescrAcronym_ [l=sr] {Prelistavanje akronima}
+_textdescrPhrase_ [l=sr] {Prelistavanje fraza}
+_textdescrHowto_ [l=sr] {Prelistavanje kategorija iz "kako da"}
+_textdescrBrowse_ [l=sr] {Prelistavanje dokumenata}  
+_texticontext_ [l=sr] {Prikazivanje dokumenta}
+_texticonclosedbook_ [l=sr] {otvaranje dokumenta i prikazivanje njegovog sadrÅŸaja}
+_texticonnext_ [l=sr] {na sledeÄi odeljak}
+_texticonprev_ [l=sr] {na prethodni odeljak}
+
+_texticonworld_ [l=sr] {Prikazivanje dokumenta sa interneta}  
+
+_texticonmidi_ [l=sr] {Prikazivanje dokumenta u MIDI formatu}
+_texticonmsword_ [l=sr] {Prikazivanje dokumenta u Word-u}
+_texticonmp3_ [l=sr] {Prikazivanje dokumenta u MP3 formatu}
+_texticonpdf_ [l=sr] {Prikazivanje dokumenta u PDF formatu}
+_texticonps_ [l=sr] {Prikazivanje dokumenta u PostScript formatu}
+_texticonppt_ [l=sr] {Prikazivanje dokumenta u PowerPoint-u}
+_texticonrtf_ [l=sr] {Prikazivanje dokumenta u RTF formatu}
+_texticonxls_ [l=sr] {Prikazivanje dokumenta u Excel-u}
+
+_page_ [l=sr] {stranica}
+_pages_ [l=sr] {stranice}
+_of_ [l=sr] {od}
+_vol_ [l=sr] {Sv.}
+_num_ [l=sr] {br.}
+
+_textmonth00_ [l=sr] {}
+_textmonth01_ [l=sr] {januar}
+_textmonth02_ [l=sr] {februar}
+_textmonth03_ [l=sr] {mart}
+_textmonth04_ [l=sr] {april}
+_textmonth05_ [l=sr] {maj}
+_textmonth06_ [l=sr] {jun}
+_textmonth07_ [l=sr] {jul}
+_textmonth08_ [l=sr] {avgust}
+_textmonth09_ [l=sr] {septembar}
+_textmonth10_ [l=sr] {oktobar}
+_textmonth11_ [l=sr] {novembar}
+_textmonth12_ [l=sr] {decembar}
+
+_textdocument_ [l=sr] {Dokument}
+_textsection_ [l=sr] {Odeljak}
+_textparagraph_ [l=sr] {Pasus}  
+
+_magazines_ [l=sr] {Äasopisi}
+
+_nzdlpagefooter_ [l=sr] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">Projekat digitalne biblioteke Novog Zelanda</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Odsek za raÄunarstvo</a>, 
+<a href="http://www.waikato.ac.nz">Univerzitet u Waikato-u</a>, 
+Novi Zeland}
+
+_linktextHOME_ [l=sr] {PRISTUPNA STRANICA}
+_linktextHELP_ [l=sr] {POMOÄ}
+_linktextPREFERENCES_ [l=sr] {PODEÅ AVANJA}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+
+
+
+package collector
+
+
+
+
+package depositor
+
+
+
+
+package gti
+
+
+
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=sr] {O ovoj kolekciji}
+
+_textsubcols1_ [l=sr] {<p>Kolekcija sadrÅŸi _1_ podkolekcija. Trenutno su dostupne:
+<blockquote>}
+
+_textsubcols2_ [l=sr] {</blockquote>
+MoÅŸete da proverite (i izmenite) koje podkolekcije trenutno koristite preko stranice
+za podeÅ¡avanja.}
+
+_titleabout_ [l=sr] {o}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=sr] {zatvaranje ovog odeljka biblioteke}
+_texticonclosedbookshelf_ [l=sr] {otvaranje ovog odeljka biblioteke i prikazivanje sadrÅŸaja}
+_texticonopenbook_ [l=sr] {zatvaranje ove knjige}
+_texticonclosedfolder_ [l=sr] {Otvaranje omotnice i prikazivanje sadrÅŸaja}
+_texticonclosedfolder2_ [l=sr] {otvaranje pododeljka:}
+_texticonopenfolder_ [l=sr] {zatvaranje omotnice}
+_texticonopenfolder2_ [l=sr] {zatvaranje pododeljka:}
+_texticonsmalltext_ [l=sr] {Prikazivanje ovog odeljka teksta}
+_texticonsmalltext2_ [l=sr] {Prikazivanje teksta:}
+_texticonpointer_ [l=sr] {aktivni odeljak}
+_texticondetach_ [l=sr] {Otvaranje stranice u novom prozoru}
+_texticonhighlight_ [l=sr] {Isticanje termina za pretraÅŸivanje}  
+_texticonnohighlight_ [l=sr] {Termini za pretraÅŸivanje se ne istiÄu}
+_texticoncontracttoc_ [l=sr] {SaÅŸimanje sadrÅŸaja}
+_texticonexpandtoc_ [l=sr] {Å irenje sadrÅŸaja}
+_texticonexpandtext_ [l=sr] {Prikazivanje celokupnog teksta}
+_texticoncontracttext_ [l=sr] {Prikazivanje teksta za trenutno odabrane odeljke}
+_texticonwarning_ [l=sr] {<b>PaÅŸnja: </b>}
+_texticoncont_ [l=sr] {Da li ÅŸelite da nastavite?}
+
+_textltwarning_ [l=sr] {<div class="buttons">_imagecont_</div>
+_iconwarning_ Prikazivanje celokupnog teksta predstavlja veliku  
+koliÄinu podataka koju vaÅ¡ web ÄitaÄ treba da prikaÅŸe
+}
+
+_textgoto_ [l=sr] {idi na stranicu}
+_textintro_ [l=sr] {<i>(uvodni tekst)</i>}
+
+_textCONTINUE_ [l=sr] {NASTAVAK?}  
+
+_textEXPANDTEXT_ [l=sr] {PRIKAZIVANJE\nTEKSTA}
+
+_textCONTRACTCONTENTS_ [l=sr] {SUÅœAVANJE\nSADRÅœAJA}
+
+_textDETACH_ [l=sr] {NOVI\nPROZOR}
+
+_textEXPANDCONTENTS_ [l=sr] {PRIKAZIVANJE\nSADRÅœAJA}
+
+_textCONTRACT_ [l=sr] {SUÅœAVANJE\nTEKSTA}
+
+_textHIGHLIGHT_ [l=sr] {ISTICANJE\nTEKSTA}
+
+_textNOHIGHLIGHT_ [l=sr] {BEZ ISTICANJA\nTEKSTA}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=sr] {_If_(_thislast_,rezultati _thisfirst_ - _thislast_ za upit: _cgiargq_,Nema dokumenata koji zadovoljavaju upit: _cgiargq_)}  
+_textnoquerytitle_ [l=sr] {Stranica za pretraÅŸivanje}
+
+_textsome_ [l=sr] {neki}
+_textall_ [l=sr] {sve}
+_textboolean_ [l=sr] {Bulovi operatori}
+_textranked_ [l=sr] {rangirano}
+_textnatural_ [l=sr] {prirodni}
+
+_texticonsearchhistorybar_ [l=sr] {prethodna pretraÅŸivanja}
+
+_textifeellucky_ [l=sr] {ProbaÄu na sreÄu!}  
+
+#alt text for query buttons
+_textusequery_ [l=sr] {koristiti ovaj upit}
+_textfreqmsg1_ [l=sr] {Broj reÄi:}
+_textpostprocess_ [l=sr] {_If_(_quotedquery_,<br><i>naknadno obraÄeno da se pronaÄe _quotedquery_</i>
+)}
+_textinvalidquery_ [l=sr] {PogreÅ¡na sintaksa u upitu}
+
+
+
+_textmorethan_ [l=sr] {ViÅ¡e od}
+_textapprox_ [l=sr] {O}
+_textnodocs_ [l=sr] {Nijedan dokument nije zadovoljio upit.}
+_text1doc_ [l=sr] {1 dokument zadovoljava upit.}
+_textlotsdocs_ [l=sr] {dokumenata je zadovoljilo upit.}
+_textmatches_ [l=sr] {Rezultati}
+_textbeginsearch_ [l=sr] {PoÄetak pretraÅŸivanja}
+_textrunquery_ [l=sr] {IzvrÅ¡avanje upita}
+_textclearform_ [l=sr] {Obrisati obrazac}
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=sr] {ReÄ ili fraza}
+_textinfield_ [l=sr] {... U polju}
+_textfoldstem_ [l=sr] {(prevoj, kraj reÄi)}
+
+_textadvquery_ [l=sr] {Ili ukucajte direktno upit:}
+_textallfields_ [l=sr] {sva polja}
+_texttextonly_ [l=sr] {samo tekst}
+_textand_ [l=sr] {i}
+_textor_ [l=sr] {ili}
+_textandnot_ [l=sr] {i ne}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=sr] {PretraÅŸivanje _indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_, at _gselection_ level )_If_(_nselection_,in _nselection_ language )koji sadrÅŸi _querytypeselection_ reÄi}
+
+_textadvancedsearch_ [l=sr] {PretraÅŸivanje _indexselection_ _If_(_jselection_,u _jselection_ )_If_(_gselection_, na _gselection_ nivou )_If_(_nselection_,na _nselection_ jezika ) uz koriÅ¡Äenje _querytypeselection_ upita}  
+
+_textadvancedmgppsearch_ [l=sr] {PretraÅŸivanje _indexselection_ _If_(_jselection_,u _jselection_ )_If_(_gselection_,na _gselection_ nivou )_If_(_nselection_,na _nselection_ jeziku ) i prikaÅŸi rezultate prema _formquerytypeadvancedselection_ redu}  
+
+
+
+_textformsimplesearch_ [l=sr] {PretraÅŸivanje _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )koji sadrÅŸi _formquerytypesimpleselection_}
+
+
+
+
+
+_textnojsformwarning_ [l=sr] {Upozorenje: VaÅ¡ web ÄitaÄ ne podrÅŸava Javascript. <br>Da bi koristili obrazac za pretraÅŸivanje, ukljuÄite tu opciju.}
+_textdatesearch_ [l=sr] {Kolekcija moÅŸe da se pretraÅŸuje po dokumentima u okviru jednog intervala vremena ili po dokumentima koji sadrÅŸe odreÄeni datum.}
+_textstartdate_ [l=sr] {Polazni (ili jedini) datum:}
+_textenddate_ [l=sr] {ZavrÅ¡ni datum:}
+_textbc_ [l=sr] {pre nove ere}
+_textad_ [l=sr] {nove ere}
+_textexplaineras_ [l=sr] {Â«pre nove ereÂ» i Â«nove ereÂ» su alternacije za PNE i NE.}
+
+_textstemon_ [l=sr] {(ignorisati krajeve reÄi)}
+
+_textsearchhistory_ [l=sr] {PretraÅŸivanje prethodnih pretraÅŸivanja}
+
+#text macros for search history
+_textnohistory_ [l=sr] {Prethodna pretraÅŸivanja nisu dostupna.}
+_texthresult_ [l=sr] {rezultat}
+_texthresults_ [l=sr] {rezultati}
+_texthallwords_ [l=sr] {sve reÄi}
+_texthsomewords_ [l=sr] {neke reÄi}
+_texthboolean_ [l=sr] {Bulovi operatori}
+_texthranked_ [l=sr] {rangirano}
+_texthcaseon_ [l=sr] {veliÄina slova mora da odgovara}  
+_texthcaseoff_ [l=sr] {ignorisanje veliÄine slova}  
+_texthstemon_ [l=sr] {osnova reÄi}  
+_texthstemoff_ [l=sr] {cela reÄ}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=sr] {PodeÅ¡avanja su izvrÅ¡ena. Ne koristite dugme "back" vaÅ¡eg web ÄitaÄa jer Äe poremetiti podeÅ¡avanja! Umesto toga, kliknite na neko dugme za pristup kolekcijama.}
+_textsetprefs_ [l=sr] {podeÅ¡avanja}  
+_textsearchprefs_ [l=sr] {PodeÅ¡avanja pretraÅŸivanja}
+_textcollectionprefs_ [l=sr] {PodeÅ¡avanja kolekcije}
+_textpresentationprefs_ [l=sr] {PodeÅ¡avanja prezentacije}
+_textpreferences_ [l=sr] {PodeÅ¡avanja}
+_textcasediffs_ [l=sr] {Razlika izmeÄu velikih i malih slova:}
+_textignorecase_ [l=sr] {ne razlikuju se velika i mala slova}
+_textmatchcase_ [l=sr] {velika i mala slova moraju se slagati}
+_textwordends_ [l=sr] {Krajevi reÄi:}
+_textstem_ [l=sr] {ignorisanje krajeva reÄi}
+_textnostem_ [l=sr] {cela reÄ mora da odgovara}
+
+
+
+
+_textprefop_ [l=sr] {Povratak na _maxdocoption_ rezultate sa _hitsperpageoption_ rezultata po strani.}
+_textextlink_ [l=sr] {Pristup eksternim web stranicama:}
+_textintlink_ [l=sr] {Izvorni dokumenti pronaÄeni u:}
+_textlanguage_ [l=sr] {Jezik interfejsa:}
+_textencoding_ [l=sr] {Kodiranje:}
+_textformat_ [l=sr] {Oblik interfejsa:}
+_textall_ [l=sr] {sve}
+_textquerymode_ [l=sr] {NaÄin pretraÅŸivanja:}
+_textsimplemode_ [l=sr] {jednostavno pretraÅŸivanje}
+_textadvancedmode_ [l=sr] {napredno pretraÅŸivanje (Bulovo pretraÅŸivanje uz koriÅ¡Äenje znakova !, &, | i zagrada)}
+_textlinkinterm_ [l=sr] {kroz meÄustranicu}
+_textlinkdirect_ [l=sr] {idi pravo tamo}
+_textdigitlib_ [l=sr] {digitalna biblioteka}
+_textweb_ [l=sr] {web}
+_textgraphical_ [l=sr] {GrafiÄki}
+_texttextual_ [l=sr] {Tekstualni}
+_textcollectionoption_ [l=sr] {<p>
+Podkolekcija za ukljuÄivanje:
+<br>}
+
+
+
+
+
+
+
+_textrelateddocdisplay_ [l=sr] {prikazivanje sliÄnih dokumenata}  
+_textsearchhistory_ [l=sr] {Prethodna pretraÅŸivanja:}
+_textnohistory_ [l=sr] {Nema istorije pretraÅŸivanja}
+_texthistorydisplay_ [l=sr] {prikazivanje _historynumrecords_ prethodnih pretraÅŸivanja}
+_textnohistorydisplay_ [l=sr] {Bez prikazivanja prethodnih pretraÅŸivanja}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=sr] {Sortiranje dokumenata prema}
+_textalsoshowing_ [l=sr] {takoÄe prikazuje}
+_textwith_ [l=sr] {sa najviÅ¡e}
+_textdocsperpage_ [l=sr] {dokumenata po strani}
+
+_textfilterby_ [l=sr] {Dobijanje dokumenata koji sadrÅŸe}
+_textall_ [l=sr] {sve}
+_textany_ [l=sr] {bilo koji}
+_textwords_ [l=sr] {reÄi}
+_textleaveblank_ [l=sr] {ostaviti prazan okvir da bi se dobili svi dokumenti}
+
+_browsebuttontext_ [l=sr] {Sortiranje dokumenata}
+
+_nodata_ [l=sr] {<i>nema podataka</i>}
+_docs_ [l=sr] {dokumenata}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=sr] {PomoÄ}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=sr] {prelistavanje dokumenata po _1_ pritiskanjem _2_ dugmeta}  
+
+_textSearchhelp_ [l=sr] {traÅŸi odreÄene reÄi koje se javljaju u tekstu klikom na _labelSearch_ dugme}  
+_textTohelp_ [l=sr] {pretraÅŸite dokumente po polju Prema klikom na _labelTo_ dugme}  
+_textFromhelp_ [l=sr] {prelistavanje dokumenata po polju ''Od koga'' pritiskanjem _labelFrom_ dugmeta}  
+_textBrowsehelp_ [l=sr] {prelistati dokumenta}  
+_textAcronymhelp_ [l=sr] {prelistavanje dokumenata po akronimima pritiskanjem _labelAcronym_ dugmeta}  
+_textPhrasehelp_ [l=sr] {prelistaj fraze koje se javljaju u dokumentima klikom na _labelPhrase_ dugme. Aktivira se pretraÅŸivaÄ za pronalaÅŸenje fraza.}  
+
+_texthelptopicstitle_ [l=sr] {Teme}  
+
+_textreadingdocs_ [l=sr] {Kako Äitati dokumente}
+
+_texthelpreadingdocs_ [l=sr] {<p>MoÅŸete prepoznati kada dobijete pojedinaÄnu knjigu ili dokument
+prema pojavljivanju naslova, ili fotografije prednje korice, u gornjem
+levom uglu stranice. U nekim kolekcijama ovome je pridruÅŸen i 
+sadrÅŸaj, dok druge sadrÅŸe samo broj aktivne strane uz
+polje koje vam omoguÄava da odaberete novu stranu i kreÄete se napred i
+nazad. U sadrÅŸaju je boldiran naslov otvorenog poglavlja,
+a sadrÅŸaj se moÅŸe i proÅ¡iriti -- kliknite na direktorijume da ih otvorite
+ili zatvorite; kliknite na otvorenu knjigu na vrhu da bi je zatvorili.<p>
+
+<p>Ispod se nalazi tekst otvorenog poglavlja. Kada ga proÄitate,
+strelicama na dnu prelazite na sledeÄe poglavlje
+ili se vraÄate na prethodno.<p>
+
+<p>Ispod naslova ili fotografije prednje korice nalaze se neka dugmad. Kliknite na
+<i>_document:textEXPANDTEXT_</i> da proÅ¡irite prikaz Äitavog teksta otvorenog
+poglavlja, ili knjige. Ako je dokument veliki, to bi moglo da potraje dugo vremena i zauzme
+znatnu koliÄinu memorije! Kliknite na <i>_document:textEXPANDCONTENTS_</i>
+da proÅ¡irite prikaz sadrÅŸaja kako bi ste videli naslove svih glava i
+poglavlja. Kliknite na <i>_document:textDETACH_</i> da otvorite novi prozor ÄitaÄa
+za taj dokument. (To je korisno ako ÅŸelite da uporedite dokumente ili Äitate dva
+od jednom.) Na kraju, kada pretraÅŸujete traÅŸene reÄi su
+naglaÅ¡ene. Kliknite na <i>_document:textNOHIGHLIGHT_</i> da uklonite
+naglaÅ¡avanje.</p>
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=sr] {Otvori policu za knjige}  
+_texthelpopenbook_ [l=sr] {Otvori/zatvori knjigu}  
+_texthelpviewtextsection_ [l=sr] {Pogledaj ovaj deo teksta}  
+_texthelpexpandtext_ [l=sr] {PrikaÅŸi sav tekst, ili ne}  
+_texthelpexpandcontents_ [l=sr] {ProÅ¡iri sadrÅŸaj, ili ne}  
+_texthelpdetachpage_ [l=sr] {Otvori ovu stranicu u novom prozoru}  
+_texthelphighlight_ [l=sr] {OznaÄi termine pretraÅŸivanja, ili ne}  
+_texthelpsectionarrows_ [l=sr] {PreÄi na prethodni/sledeÄi deo}  
+
+
+_texthelpsearchingtitle_ [l=sr] {Kako pronaÄi odreÄene reÄi}  
+
+_texthelpsearching_ [l=sr] {<h2>Kako pretraÅŸivati po pojedinim reÄima?</h2>
+<p>
+Na stranici za pretraÅŸivanje formiraÄete upit sledeÄi ova tri koraka: <p>
+
+  <ol>
+      <li>NaznaÄite na kojim dokumentima ÅŸelite da primenite ovo pretraÅŸivanje
+      <li>NaznaÄite da li ÅŸelite da pretraÅŸujete po svim reÄima ili samo po nekim 
+      <li>Ukucajte reÄi po kojima ÅŸelite da pretraÅŸujete 
+      <li>Kliknite na dugme <i>PoÄetak pretraÅŸivanja</i>
+  </ol>
+
+<p>Kada obavite pretraÅŸivanje, naslovi prvih dvadeset dokumenata koji zadovoljavaju pretraÅŸivanje, 
+naÄi Äe se na ekranu. Na kraju liste su dugmiÄi za navigaciju, koji vam omoguÄavaju da pristupite 
+sledeÄoj grupi od dvadeset dokumenata. Da biste pogledali dokument treba da kliknete na naslov 
+ili malo dugme iza njega.  
+
+
+<p>Broj dokumenata koji se pojavljuju kao rezultati pretraÅŸivanja limitiran je na 100.
+MoÅŸete da izmenite ovaj broj, ako kliknete na dugme 
+<i>"PodeÅ¡avanja"</i> na vrhu stranice.<p>
+
+<div class="divbar">Â </div>
+<a name="query-terms"></a>
+<h3>Termini za pretraÅŸivanje</h3>
+
+
+<p>Sve Å¡to ukucate u polje za pretraÅŸivanje tumaÄi se kao lista reÄi 
+nazvana Â«termini za pretraÅŸivanjeÂ». Svaki termin mora biti alfanumerik 
+i sme da sadrÅŸi samo slova i cifre. Termini za pretraÅŸivanje odvojeni su razmacima.
+Ako se u terminima za pretraÅŸivanje pojavi neki znak interpunkcije, biÄe ignorisan,  
+odnosno tretiran kao razmak. 
+
+<p>Na primer, upit<p>
+
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>daÄe iste rezultate kao i upit<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+
+<div class="divbar">Â </div>
+<a name="query-type"></a>
+<h3>Vrste upita</h3>
+
+<p>Postoje dve vrste upita.
+
+<ul>
+
+<li>Upit po <b>svim</b> reÄima.  Ovaj vrsta upita 
+pretraÅŸuje dokumente koji sadrÅŸe sve navedene reÄi.
+Dokumenti koji zadovoljavaju upit, prikazuju se u abecednom (azbuÄnom) redu.<p>
+
+<li>Upit po <b>nekim</b> reÄima. MoÅŸete dati listu
+reÄi koje se vrlo verovatno nalaze u dokumentima koje traÅŸite. 
+U ovom sluÄaju dokumenti se prikazuju prema stepenu zadovoljavanja upita. 
+Kada se odreÄuje stepen zadovoljavanja upita, vaÅŸi sledeÄe 
+
+<p><ul>
+
+<li>ukoliko dokument sadrÅŸi viÅ¡e termina za pretraÅŸivanje, bolje zadovoljava upit ;
+
+<li>neuobiÄajeni termini vaÅŸniji su za pretraÅŸivanje od uobiÄajenih; 
+
+<li>manji dokumenti bolje zadovoljavaju upit od veÄih.
+
+</ul>
+
+</ul>
+
+<p>MoÅŸete koristiti koliko god hoÄete termina za pretraÅŸivanje: 
+Äitavu reÄenicu ili Äitav paragraf. 
+Ako koristite samo jedan termin za pretraÅŸivanje, dokumenti koji zadovoljavaju upit
+biÄe ureÄeni prema uÄestanosti pojavljivanja tog termina. 
+
+<p>
+
+_texthelpscope_
+
+}  
+
+_texthelpquerytermstitle_ [l=sr] {Termini za pretraÅŸivanje}  
+
+
+_texthelpmgppsearching_ [l=sr] {Za kolekcije uraÄene sa "MGPP" dostupno je joÅ¡ nekoliko opcija.
+
+<ul>
+<li>A <b>*</b> na kraju termina za pretraÅŸivanje odgovaraÄe svim reÄima <b>koje poÄinju</b> tom
+reÄju, na primer  <b>kompjut*</b> odgovaraÄe svim reÄima koje poÄinju sa  <b>kompjut</b>.
+<li><b>/x</b> koristiti se da jednom ili viÅ¡e termina za pretraÅŸivanje da veÄu teÅŸinu, npr
+<b>kompjuter/10 nauka</b> daje kompjuteru 10 puta veÄu teÅŸinu nego nauci prilikom
+rangiranja dokumenata.
+</ul>
+}  
+
+_texthelplucenesearching_ [l=sr] {Za kolekcije uraÄene sa "Lucene" dostupno je joÅ¡ nekoliko opcija.
+
+<ul>
+<li><b>?</b> se moÅŸe koristiti kao zamena za pojedinaÄno slovo. Na primer,
+<b>n?s</b> odgovaraÄe za <b>nos</b> i <b>nas</b> itd.
+<li><b>*</b> se moÅŸe koristiti kao zamena za viÅ¡e slova. Na primer,
+<b>kompjut*</b> odgovaraÄe za sve reÄi koje poÄinju sa <b>kompjut</b>.
+</ul>
+Obe zamene slova mogu se koristiti u sredini termina ili na kraju. Ne mogu se
+koristiti na poÄetku termina za pretraÅŸivanje.
+}  
+
+_texthelpquerytypetitle_ [l=sr] {Vrsta upita}  
+
+
+
+
+
+
+_texthelpadvsearchmg_ [l=sr] {Napredno pretraÅŸivanje u MG kolekcijama pruÅŸa vam dve opcije pretraÅŸivanja, prema svrstavanju i Bulovim operatorima. 
+PretraÅŸivanje prema <b>svrstavanju</b> je potpuno identiÄno <b>pojedinaÄnom</b> pretraÅŸivanju opisanom u <a href="\#query-type">_texthelpquerytypetitle_</a>. <p>_texthelpbooleansearch_
+}  
+
+_texthelpbooleansearch_ [l=sr] {PretraÅŸivanje <b>Bulovim operatorima</b> omoguÄava kombinovanje termina
+koriÅ¡Äenjem & (za "i"), | (za "ili"), i ! (za "ne"), uz eventualno koriÅ¡Äenje zagrada. Podrazumevani operator je | (za "ili").
+<p>
+Na primer, <b>puÅŸ & uzgajanje</b> odgovaraÄe dokumentima koji sadrÅŸe i <b>puÅŸ</b> I <b>uzgajanje</b>, dok Äe <b>puÅŸ |
+uzgajanje</b> pronaÄi dokumenta koja sadrÅŸe <b>puÅŸ</b> ILI <b>uzgajanje</b>.
+<b>puÅŸ ! uzgajanje</b> odgovaraÄe dokumentima koji sadrÅŸe <b>puÅŸ</b> a NE sadrÅŸe <b>uzgajanje</b>. 
+<p>
+Precizniji upiti mogu biti odreÄeni koriÅ¡Äenjem kombinacija operatora i zagrada. Na primer, <b>(ovca | stoka) & (farma | poloÅŸaj)</b>, ili <b>ovca | stoka | koza ! svinja</b>.
+}  
+
+
+
+
+
+_texthelpadvsearchlucene_ [l=sr] {Napredno pretraÅŸivanje u Lusin kolekcijama koristi Bulove operatore. _texthelpbooleansearch_}  
+
+
+
+
+
+
+
+_textdatesearch_ [l=sr] {PretraÅŸivanje datuma}
+
+_texthelpdatesearch_ [l=sr] {<h2>_textdatesearch_</h2>
+
+PretraÅŸivanje po datumu omoguÄava vam da naÄete dokumente koji 
+ispunjavaju direktne kriterijume vaÅ¡eg pretraÅŸivanja, kao i dokumente koji se bave  
+dogaÄajima vremenski lociranim u zadati period. MoÅŸete da pretraÅŸujete
+dokumente vezane za jednu odreÄenu godinu ili za odreÄeni interval godina. UoÄite da nije neophodno imati ikakve termine za pretraÅŸivanje 
+kada se ima pretraÅŸivanje po datumu.
+S druge strane nije neophodno koriÅ¡Äenje datuma u pretraÅŸivanju: 
+ako ne precizirate niti jedan datum u dokumentu, to je kao da pretraÅŸivanje
+po datumu ne postoji. <p>
+
+<div class="divbar">Â </div>
+<a name="datesearch-howto"></a>
+<h3>Kako da koristite ovu funkciju:</h3>
+<ul>
+   <li>Da biste pretraÅŸivali dokumente vezane za samo jednu godinu:<p>
+   <ul>
+       <li>Unesite kriterijume za pretraÅŸivanje kao obiÄno. 
+       <li>Unesite ÅŸeljenu godinu u prozorÄiÄ "Polazni (ili jedinstveni) datum".
+       <li>Ako je vaÅ¡ datum iz perioda pre nove ere 
+           odaberite opciju "pre nove ere" iz padajuÄeg menija 
+           pored prozorÄiÄa. 
+       <li>ZapoÄnite pretraÅŸivanje kako obiÄno i Äinite. 
+   </ul>
+<p><li>Da biste pretraÅŸivali dokumente koji pokrivaju odreÄeni period ili interval godina:<p>
+   <ul>
+       <li>Unesite kriterijume za pretraÅŸivanje kao obiÄno.
+       <li>Unesite poÄetnu godinu u prozorÄiÄ "Polazni datum".
+       <li>Unesite zavrÅ¡nu godinu u prozorÄiÄ "ZavrÅ¡ni datum".
+       <li>Odaberite opciju "pre nove ere" iz padajuÄeg menija pored prozorÄiÄa
+           za sve datume iz tog perioda.  
+       <li>ZapoÄnite pretraÅŸivanje kako obiÄno i Äinite. 
+   </ul>    
+</ul><p>
+
+<div class="divbar">Â </div>
+<a name="datesearch-results"></a>
+<h3>Kako ovo pretraÅŸivanje funkcioniÅ¡e?</h3>
+
+Generalno govoreÄi, pretraÅŸivanje dokumenata po godini 1903. 
+neÄe dati rezultate koji ukljuÄuju knjige napisane 1903. godine   
+veÄ jedino dokumente koji se bave godinom 1903. Ipak, zbog naÄina na koji se datumi pretraÅŸuju  
+u dokumentima, meÄu rezultatima Äe se naÄi i dokumenti u intervalu godina    
+(na primer  1899-1911), kao i dokumenti koji u tekstu navode vek kome godina 1903. pripada
+(na primer XX vek ili dvadeseti vek). To znaÄi da se u nekim dokumentima 
+ne mora eksplicitno pojavljivati datum zadat u pretraÅŸivanju. Ovo takoÄe vaÅŸi i za  
+pretraÅŸivanje po vremesnkim intervalima, za svaku godinu u intrevalu. 
+}  
+
+_texthelpdatehowtotitle_ [l=sr] {Kako koristiti ovu opciju:}  
+_texthelpdatehowto_ [l=sr] {<ul>
+   <li>PretraÅŸivanje dokumenata o odreÄenoj godini: <p>
+   <ul>
+      <li>Unesite bilo koji uobiÄajeni termin za pretraÅŸivanje.
+      <li>Unesite traÅŸenu godinu u polje "PoÄetni (ili jedinstveni) datum".
+      <li>Ako je traÅŸeni datum pre nove ere, odaberite opciju "pre nove ere" iz padajuÄeg menija do tog polja.
+      <li>PoÄnite pretraÅŸivanje kao Å¡to i obiÄno Äinite.
+   </ul>
+<p><li>PretraÅŸivanje dokumenata koji pokrivaju odreÄeni vremenski period ili interval godina: <p>
+   <ul>
+       <li>Unesite bilo koji uobiÄajeni termin za pretraÅŸivanje.
+       <li>Unesite poÄetnu godinu u polje "PoÄetni (ili jedinstveni) datum".
+       <li>Unesite zavrÅ¡nu godinu u polje "Krajnji datum".
+       <li>Odaberite opciju "pre nove ere" iz padajuÄeg menija pored bilo koje godine pre
+nove ere.
+       <li>PoÄnite pretraÅŸivanje kao Å¡to i obiÄno Äinite.
+   </ul>
+</ul><p> 
+}  
+
+_texthelpdateresultstitle_ [l=sr] {NaÄin na koji se dobijaju rezultati pretraÅŸivanja}  
+_texthelpdateresults_ [l=sr] {UopÅ¡teno govoreÄi, pretraÅŸivanje dokumenata o godini 1903. neÄe prikazati dokumente poput referensnih knjiga objavljenih 1903, veÄ samo dokumente koji se tiÄu 1903. godine. MeÄutim, naÄin na koji se datumi u dokumentima pronalaze omoguÄava da se prikaÅŸu dokumenti Äiji vremenski opseg ukljuÄuje 1903. godinu (na primer 1899-1911), a takoÄe i one dokumente koji u naslovu sadrÅŸe vek Äiji je deo 1903. godina (na primer "20. vek" ili "dvadeseti vek"). To znaÄi da se za neke dokumente godina iz pretraÅŸivanja neÄe pojaviti u tekstu dokumenta. Za pretraÅŸivanje u vremenskom periodu ovo se odnosi na sve godine u okviru tog perioda.<p>}  
+
+_textchangeprefs_ [l=sr] {Promena podeÅ¡avanja}
+
+_texthelppreferences_ [l=sr] {<h2>_textchangeprefs_</h2>
+
+<p>Ako kliknete na dugme<i>podeÅ¡avanja</i> na vrhu stranice,
+moÄi Äete da izmenite neka svojstva interfejsa 
+da biste zadovoljili svoje zahteve. 
+
+<div class="divbar">Â </div>
+<a name="col-prefs"></a>
+<h3 align=left>Izbor kolekcije</h3>
+
+Neke kolekcije sastavljene su iz viÅ¡e podkolekcija. 
+One mogu da se pretraÅŸuju pojedinaÄno ili zajedno.  
+Ukoliko ÅŸelite, moÅŸete da precizirate koje podkolekcije treba da budu 
+ukljuÄene u pretraÅŸivanje na stranici Â«PodeÅ¡avanjaÂ».
+
+<div class="divbar">Â </div>
+<a name="lang-prefs"></a>
+<h3 align=left>Izbor jezika</h3>
+
+Jezik intefejsa se takoÄe moÅŸe birati, kao i kodni raspored u kome Äe se prikazivati tekst. 
+
+<p>
+KonaÄno, s obzirom na kolekciju, moÅŸete da odaberete iskljuÄivo tekstualni interfejs 
+umesto standardnog grafiÄkog. To moÅŸe da bude od koristi za one koji imaju probleme
+sa vidom, pa koriste veÄa slova ili uredjaje za sintezu govora.
+
+
+
+
+<div class="divbar">Â </div>
+<a name="pres-prefs"></a>
+<h3 align=left>PodeÅ¡avanja prezentacije</h3>
+
+Za svaku kolekciju moÅŸete da izaberete nekoliko svojstava koji kontroliÅ¡u 
+njenu prezentaciju.  
+
+<p>Kolekcije web stranica dozvoljavaju vam da eliminisete trake za navigaciju samog Greenstone-a, koje se javljaju na vrhu svake stranice prelistavanog dokumenta. Za naredno pretraÅŸivanje prisiljeni ste da koristite opciju web ÄitaÄa za povratak na prethodnu stranicu (klikom na "back" dugme ili strelicu). Isto tako, zbirke su u moguÄnosti da spreÄe pojavljivanje Greenstone-ove upozoravajuÄe poruke u sluÄaju da kliknete na link koji vodi van digitalne kolekcije, odnosno na sam Web. 
+
+
+<div class="divbar">Â </div>
+<a name="search-prefs"></a>
+<h3 align=left>PodeÅ¡avanja pretraÅŸivanja</h3>
+
+Dva para dugmiÄa omoguÄavaju podeÅ¡avanja pretraÅŸivanja. 
+Prvi ukljuÄuje ili iskljuÄuje osetljivost na velika i mala slova 
+a drugi ignoriÅ¡e ili uzima u obzir kraj reÄi. 
+MoÅŸe da se dobije i veliki prozor za pretraÅŸivanje tekstova veliÄine paragrafa. IznenaÄujuÄe brzo se pronalaze. 
+
+<p>Na primer, ako se aktivni dugmiÄi<i>Ignorisanje razlika u velikim i malim slovima 
+</i> i <i>Ignorisanje krajeva reÄi</i> 
+, pretraÅŸivanje
+
+<p><ul><kbd>AfriÄki ples</kbd></ul>
+
+<p>biÄe tretirano na isti naÄin kao i 
+
+<p><ul><kbd>afrika pleÅ¡e</kbd></ul>
+
+<p> 
+Veliko slovo A u reÄi "AfriÄki" biÄe konvertovano u malo, dok Äe se zanemariti 
+krajevi reÄi "Äki" i "s" u reÄima "AfriÄki" i "ples", kao i "ka" i "Å¡e" u reÄima 
+"afrika" i "pleÅ¡e" respektivno. 
+
+<p>MoÅŸete joÅ¡ odabrati i "napredni" naÄin pretraÅŸivanja koji omoguÄava
+da kombinujete termine za pretraÅŸivanje koriÅ¡Äenjem  Bulovih operatora AND
+(&), OR (|), i NOT (!). Tako moÅŸete sastaviti preciznije upite. 
+
+<p>KonaÄno, moÅŸete da zadate broj pogodaka, koje Äe vam pretraÅŸivanje vraÄati, kao 
+i broj dokumenata koji se prikazuju na jednoj stranici. 
+
+}  
+
+_texthelpcollectionprefstitle_ [l=sr] {PodeÅ¡avanja kolekcija}  
+_texthelpcollectionprefs_ [l=sr] {<p>Neke kolekcije sadrÅŸe nekoliko podkolekcija, koje se mogu pretraÅŸivati
+nezavisno ili grupno, kao jedna jedinica. Ukoliko je tako, moÅŸete
+na stranici PodeÅ¡avanja odrediti koje podkolekcije da budu ukljuÄene u pretraÅŸivanjima.
+}  
+
+_texthelplanguageprefstitle_ [l=sr] {PodeÅ¡avanja jezika}  
+
+
+_texthelppresentationprefstitle_ [l=sr] {PodeÅ¡avanja prikaza}  
+
+
+_texthelpsearchprefstitle_ [l=sr] {PodeÅ¡avanja pretraÅŸivanja}  
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+_texttanumbrowseoptions_ [l=sr] {Ima _numbrowseoptions_ naÄina da
+pronaÄete informacije u ovoj kolekciji:}  
+
+_textsimplehelpheading_ [l=sr] {Kako pronaÄi informacije u _collectionname_ kolekciji}
+
+_texthelpscopetitle_ [l=sr] {Opseg upita}  
+_texthelpscope_ [l=sr] {<p>
+U veÄini kolekcija moÅŸete da odaberete razliÄite indekse za pretraÅŸivanje.
+Na primer, moguÄe je da imate jedan indeks za autore a drugi za naslove, 
+pa Äak i indeks za odeljke ili paragrafe. 
+Generalno, dobiÄete dokument koji zadovoljava upit, ma 
+koji indeks za pretraÅŸivanje koristili. 
+
+<p>
+Ukoliko su dokumenti knjige, biÄe otvoreni baÅ¡ na odgovarajuÄim mestima. 
+
+}
Index: /gsdl/stable/macros/sinhalese.dm
===================================================================
--- /gsdl/stable/macros/sinhalese.dm	(revision 20131)
+++ /gsdl/stable/macros/sinhalese.dm	(revision 20131)
@@ -0,0 +1,826 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# English Language text and icon macros 
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=si] {à·à·à¶» à·à¶à¶»à·}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=si] {à¶žà·à¶œà¶º:}  
+_textdate_ [l=si] {à¶à·
+à·à¶¯à·à¶à·à·à· à¶¯à·à¶±à¶º}  
+_textnumpages_ [l=si] {à¶Žà·âà¶§à· à¶à¶«à¶±:}  
+
+_textsignin_ [l=si] {à¶à¶­à·à·
+à· à·à·à¶ž}  
+
+_textdefaultcontent_ [l=si] {à¶à¶¶ âà·à·à·à· à¶Žà·âà¶§à·à· à¶œà¶¶à·à¶¯à·à¶º âà·à¶±à·à·à·à¶. à¶à¶»à·à¶«à·à¶à¶» à·à·à¶¶à· à·à·à¶»à·à·à¶»âà·à¶ºà·( Broweser) 'Back'  à¶
+à¶ºà·à¶­à¶ž à¶à¶¶à· âà·à· à¶à·à¶­ à¶žà·à¶œà· à¶Žà·à¶§ à¶
+à¶ºà·à¶­à¶ž à¶à¶¶à· à¶à¶¶âà·à¶à· à·à¶à¶à·à¶­ à¶Žà·à·à·à¶®à¶à¶œâà·à¶ºà· à¶žà·à·/à¶žà·à¶œà· à¶Žà·à¶§à·à·à¶§ à¶ºà· à·à·à¶à·à¶º.}  
+
+_textdefaulttitle_ [l=si] {GSDLà·à· à¶Žà·âà¶»à·à·à¶«à¶ºà¶à·}  
+
+_textbadcollection_ [l=si] {"(called "_cvariable_") à¶žà·à¶ž à¶à¶à¶­à·à· Greenstone à·à¶à¶à·à¶­ à¶Žà·à·à·à¶­à¶à·à¶œ à¶Žà¶¯à·à¶°à¶­à·à¶ºà· à·à·à¶®âà·à¶Žà¶±à¶º à¶à¶» à¶±à·à¶­."}  
+
+_textselectpage_ [l=si] {-à¶
+à·à·à·âà¶º à¶Žà·à¶§à·à· à¶­à·à¶»à¶±à·à¶±/à¶­à·à¶»à· à¶à¶±à·à¶±-}  
+
+_collectionextra_ [l=si] {à¶žà·à¶ž à¶à¶à¶­à·à· à·à¶žà¶±à·à·à·à¶­ à·à¶±à·à¶±à· _about:numdocs_ à¶¯à¶­à·à¶­ à¶à·à¶±à· à·à¶œà·à¶±à·. à¶à¶º à¶
+à·à·à¶±à· à·à¶»à¶§ à·à¶à·à¶± à¶œà¶¯à·à¶¯à· _about:builddate_ à¶¯à·à¶±à¶à¶§ à¶Žà·à¶»à¶¯à·à¶º.}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=si] {<p>Tà¶žà·à¶ž à¶à¶à¶­à·à· à·à¶žà¶±à·à·à·à¶­ à·à¶±à·à¶±à· _numdocs_ _If_("_numdocs_" eq "1",document,documents), a total of _numbytes_ of indexed text and metadata.
+<p><a href="_httppagex_(bsummary)">Click here</a> à¶à·à¶©à¶±à¶à¶± à¶œà¶¯ à¶à¶à¶­à·à· à¶¶à·à¶œà·à¶ž à·à¶³à·à·.}  
+
+_textdescrcollection_ [l=si] {}
+_textdescrabout_ [l=si] {à¶žà·à¶ž à¶Žà·à¶§à·à· à¶à·à¶±}  
+_textdescrhome_ [l=si] {à¶žà·à·/à¶žà·à¶œà· à¶Žà·âà¶§à·à·}  
+_textdescrhelp_ [l=si] {à¶à¶Žà¶à·à¶»à·/à¶à¶¯âà·à· à¶Žà·à¶§à·à·}  
+_textdescrpref_ [l=si] {à¶žà¶±à·à¶Ž à¶Žà·à¶§}  
+_textdescrgreenstone_ [l=si] {Greenstone à·à¶à¶à·à¶­ à¶Žà·à·à·à¶­à¶à·à¶œ à¶žà·à¶¯à·à¶à·à¶à¶à¶º}  
+_textdescrusab_ [l=si] {à¶·âà·à·à·à¶­à· à¶à·à¶»à·à¶ž à·à¶³à·à· à¶à¶¶âà¶§ à¶à¶­à· à¶
+à¶Žà·à·à·à¶­âà·à·à¶º à¶à·à¶žà¶à·à¶¯?}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=si] {à·à·à¶ºà¶±à·à¶±}  
+_labelSearch_ [l=si] {à·à·à¶ºà¶±à·à¶±}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=si] {à¶žà·à¶­à·à¶à·à·}  
+_labelTitle_ [l=si] {à¶žà·à¶­à·à¶à·}  
+_textCreator_ [l=si] {à·à¶à·à¶± à¶œà¶¯à·à¶¯à·}  
+
+_textSubject_ [l=si] {à·à·à·à¶ºà¶º}  
+_labelSubject_ [l=si] {à·à·à·à¶ºà¶ºà¶±à·}  
+_textDescription_ [l=si] {à·à·à·à·à¶­à¶»à¶º}  
+_labelDescription_ [l=si] {âà·à·à·à·à¶­à¶»}  
+_textPublisher_ [l=si] {âà¶Žà·âà¶»à¶à·à·à¶ºâà¶§ à¶Žà¶­à· à¶à¶»à¶±à·à¶±à¶±à·}  
+_labelPublisher_ [l=si] {à¶Žà·âà¶»à¶à·à·à¶ºâà¶§ à¶Žà¶­à· à¶à¶»à¶±à·à¶±à¶±à·}  
+_textContributor_ [l=si] {à¶¯à·à¶ºà¶à¶­à·à·à¶º}  
+_labelContributor_ [l=si] {à¶¯à·à¶ºà¶à¶­à·à·à¶º à·à·à¶Žà¶ºà·à·à·}  
+_textDate_ [l=si] {à¶¯à·à¶±à¶º}  
+_labelDate_ [l=si] {à¶¯à·à¶±}  
+_textType_ [l=si] {à·à¶»à·à¶à¶º}  
+_labelType_ [l=si] {à¶à¶à·à¶»}  
+_textFormat_ [l=si] {à¶à¶à·à¶­à·à¶º(Format)}  
+_labelFormat_ [l=si] {âà·à·à·à·à¶­à¶»}  
+_textIdentifier_ [l=si] {à·à·à¶¯à·à¶±à·à¶ž(Identifier)}  
+_labelIdentifier_ [l=si] {à·à¶³à·à¶±à· à¶à·à¶±à·à¶žà·}  
+_textSource_ [l=si] {âà¶¯à¶­à·à¶­ à¶à·à¶±à·à·à· à¶±à¶ž}  
+_labelSource_ [l=si] {à¶¯à¶­à·à¶­ à¶à·à¶±à·à·à· à¶±à¶ž}  
+_textLanguage_ [l=si] {à¶·à·à·à·à·}  
+_labelLanguage_ [l=si] {à¶·à·à·à·à·à¶±à·}  
+_textRelation_ [l=si] {à·à¶žà·à¶¶à¶±à·à¶°à¶º}  
+_labelRelation_ [l=si] {à·à¶žà·à¶¶à¶±à·à¶°à¶º}  
+_textCoverage_ [l=si] {à¶à·à¶»à¶«à¶º}   
+_labelCoverage_ [l=si] {à¶à·à¶»à¶«à¶º}  
+_textRights_ [l=si] {à¶
+à¶ºà·à¶­à·à¶º}  
+_labelRights_ [l=si] {à¶
+à¶ºà·à¶­à·à¶º}  
+
+# DLS metadata set
+_textOrganization_ [l=si] {à·à¶žà·à¶žà·à¶œà¶±/à·à¶à·à·à¶°à·à¶±à¶º}  
+_labelOrganization_ [l=si] {à·à¶žà·à¶žà·à¶œà¶±/à·à¶à·à·à¶°à·à¶±à¶º}  
+_textKeyword_ [l=si] {à·à·à·à·à¶žà· à¶Žà¶¯}  
+_labelKeyword_ [l=si] {à·à·à·à·à¶žà· à¶Žà¶¯}  
+_textHowto_ [l=si] {à¶à·à·à·à¶¯}  
+_labelHowto_ [l=si] {à¶à·à·à·à¶žà¶¯}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=si] {âà·à·à¶à·âà¶º à¶à¶«à·à¶©à¶º}  
+_labelPhrase_ [l=si] {âà·à·à¶âà·âà¶º à¶à¶«à·à¶©}  
+_textCollage_ [l=si] {à¶à¶à¶­à·à·}  
+_labelCollage_ [l=si] {à¶à¶à¶­à·à·}  
+_textBrowse_ [l=si] {à·à·âà·à¶ºà¶±à·à¶±}  
+_labelBrowse_ [l=si] {à·à·à¶»à·à·à¶»à·à¶º}  
+_textTo_ [l=si] {à¶§}  
+_labelTo_ [l=si] {à·à·à¶§}  
+_textFrom_ [l=si] {à·à·à¶­à·à¶±à·}  
+_labelFrom_ [l=si] {à¶à·à¶±à·}  
+_textAcronym_ [l=si] {à¶à·âà¶§à· à¶ºà·à¶¯à·à¶žà·}  
+_labelAcronym_ [l=si] {à¶à·âà¶§à· à¶ºà·à¶¯à·à¶žà·}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=si] {à·à·à·à¶ºà¶±à·à¶± _1_}  
+
+_textdescrSearch_ [l=si] {à·à·âà·à·à·à·à·à¶­ à¶Žà¶¯ âà·à·à·à·à¶ž}  
+_textdescrType_ [l=si] {à¶œà·à¶Žà· âà·à¶à·à¶±à· à·à¶»à·à¶à¶º( type) à¶žà¶à·à¶±à· à·à·à¶ºà¶±à·à¶±}  
+_textdescrIdentifier_ [l=si] {à·à¶žà·à¶Žà¶­à·/à¶¯à¶­à·à¶­ à·à¶³à·à¶±à· à¶à·à¶±à·à¶ž à¶žà¶à·à¶±à· à·à·à¶ºà¶±à·à¶±}  
+_textdescrSource_ [l=si] {à¶žà·à¶œà· à¶œà·à¶Žà· âà·à¶à·à¶±à· à¶±à¶žà·à¶±à· à·à·à¶ºà¶±à·à¶±}  
+_textdescrTo_ [l=si] {To field  à¶žà¶à·à¶±à· à·à·à¶ºà¶±à·à¶±}  
+_textdescrFrom_ [l=si] {à¶
+à¶¯à·à¶œ à¶à·à·à·à¶­à·âà¶»à¶ºà¶±à·à·à· à·à·à¶ºà¶±à·à¶±}  
+_textdescrCollage_ [l=si] {à¶»à·à¶Ž à¶à¶à¶­à·à¶±à·à·à· à·à·à¶ºà¶±à·à¶±}  
+_textdescrAcronym_ [l=si] {à¶à·âà¶§à· à¶ºà·à¶¯à·à¶žà· à·à·à¶ºà¶±à·à¶±}  
+_textdescrPhrase_ [l=si] {à·à·à¶à·âà¶º à¶à¶«à·à¶© à·à·à¶ºà¶±à·à¶±}  
+_textdescrHowto_ [l=si] {à·à·à¶±à· à¶à¶»à¶±à·à¶±à· à¶à·à·à·à¶¯à·à¶ºà· à·à·à¶ºà¶±à·à¶±}  
+_textdescrBrowse_ [l=si] {à¶¯à¶­à·à¶­à¶à·à¶±à· à·à·à¶ºà¶±à·à¶±}  
+_texticontext_ [l=si] {à¶¯à¶­à·à¶­à¶à·à¶±à·à· à¶¶à¶œà¶±à·à¶±}  
+_texticonclosedbook_ [l=si] {à¶žà·à¶ž à¶¯à¶­à·à¶­ à¶à·âà·à¶±à·à· à·à·à·à·à¶­ à¶à¶» à¶
+à¶±à·à¶­à¶»à·à¶à¶­à¶º à¶¶à¶œà¶±à·à¶±}  
+_texticonnext_ [l=si] {à¶žà·à¶œà¶ à¶à·à¶§à·à¶§}  
+_texticonprev_ [l=si] {à¶Žà·à¶» à¶à·à¶§à·à¶§}  
+
+_texticonworld_ [l=si] {Web à¶¯à¶­à·à¶­à¶à·à¶±à·à· à¶¶à¶œà¶±à·à¶±}  
+
+_texticonmidi_ [l=si] {MIDI à¶¯à¶­à·à¶­à¶à·à¶±à·à· à¶¶à¶œà¶±à·à¶±}  
+_texticonmsword_ [l=si] {Microsoft Word  à¶¯à¶­à·à¶­à¶à·à¶±à·à· à¶¶à¶œà¶±à·à¶±}  
+_texticonmp3_ [l=si] {MP3 à¶¯à¶­à·à¶­à¶à·à¶±à·à· à¶¶à¶œà¶±à·à¶±}  
+_texticonpdf_ [l=si] {PDF à¶¯à¶­à·à¶­à¶à·à¶±à·à· à¶¶à¶œà¶±à·à¶±}  
+_texticonps_ [l=si] {PostScript à¶¯à¶­à·à¶­à¶à·à¶±à·à· à¶¶à¶œà¶±à·à¶±}  
+_texticonppt_ [l=si] {PowerPoint  à¶¯à¶­à·à¶­à¶à·à¶±à·à· à¶¶à¶œà¶±à·à¶±}  
+_texticonrtf_ [l=si] {RTF à¶¯à¶­à·à¶­à¶à·à¶±à·à· à¶¶à¶œà¶±à·à¶±}  
+_texticonxls_ [l=si] {Microsoft Excel  à¶¯à¶­à·à¶­à¶à·à¶±à·à· à¶¶à¶œà¶±à·à¶±}  
+
+_page_ [l=si] {à¶Žà·âà¶§à·à·}  
+
+_pages_ [l=si] {à¶Žà·âà¶§à·}  
+_of_ [l=si] {à¶±à·}   
+_vol_ [l=si] {à·à·à·
+à·à¶ž}  
+_num_ [l=so] {à¶
+à¶à¶}  
+
+_textmonth00_ [l=si] {}
+_textmonth01_ [l=si] {à¶¢à¶±ââà·à·à¶»à·/à¶¯à·à¶»à·à¶­à·}  
+_textmonth02_ [l=si] {à¶Žà·à¶¶à¶»à·à·à¶»à·/à¶±à·à¶žà·}  
+_textmonth03_ [l=si] {à¶žà·à¶»à·à¶­à·/à¶žà·à¶¯à·à¶±à·}  
+_textmonth04_ [l=si] {à¶
+à¶Žà·âà¶»à·à¶œà·/à¶¶à¶à·}  
+_textmonth05_ [l=si] {à¶žà·à¶ºà·/à·à·à·à¶à·}  
+_textmonth06_ [l=si] {à¶¢à·à¶±à·/à¶Žà·à·à·à¶±à·}  
+_textmonth07_ [l=si] {à¶¢à·à¶œà·/à¶à·à·
+}  
+_textmonth08_ [l=si] {à¶
+à¶à·à·à·à¶­à·/à¶±à·à¶à·à¶«à·}  
+_textmonth09_ [l=si] {à·à·à¶Žà·à¶­à·à¶žà·à¶¶à¶»à·/à¶¶à·à¶±à¶»}  
+_textmonth10_ [l=si] {à¶à¶à·à¶­à·à¶¶à¶»à·/à·à¶Žà·}  
+_textmonth11_ [l=si] {à¶±à·à·à·à¶žà·à¶¶à¶»à·/à¶à¶œà·}  
+_textmonth12_ [l=si] {à¶¯à·à·à·à¶žà·à¶¶à¶»à·/à¶à¶³à·à·à¶Žà·}  
+
+_textdocument_ [l=si] {à¶œà·à¶Žà· âà·à¶à·à¶±à·à·}  
+_textsection_ [l=si] {à¶à·à¶§à·}  
+_textparagraph_ [l=si] {à¶¡à·à¶¯à¶º/à¶Žà¶»à·à¶¡à·à¶¯à¶º}  
+
+_magazines_ [l=si] {à·à¶à¶»à·}  
+
+_nzdlpagefooter_ [l=si] {"<div class="divbar">Â </div>
+<p><a href="http://www.nzdl.org">à¶±à·à·à·à¶œà¶±à·à¶­ à·à¶à¶à·à¶­ à¶Žà·à·à·à¶­à¶à·à¶œ à·à·âà¶ºà·à¶Žà·à¶­à·à¶º</a>
+<br><a href="http://www.cs.waikato.ac.nz">à¶Žà¶»à·à¶à¶«à¶ à·à·à¶¯à·âà¶ºà· à¶
+à¶à·à¶º</a>, 
+<a href="http://www.waikato.ac.nz">Waikato âà·à·à·à·à· à·à·à¶¯à·âà¶ºà·à¶œà¶º</a>, 
+à¶±à·à·à·à¶œà¶±à·à¶­à¶º"}  
+
+_linktextHOME_ [l=si] {à¶žà·à¶œà· à¶Žà·âà¶§à·à·}  
+_linktextHELP_ [l=si] {à¶à¶Žà¶à·à¶»}  
+_linktextPREFERENCES_ [l=si] {à¶à·à¶žà·à¶­à·à¶­}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=si] {à¶Žà·à·à·à¶­à¶à·à·
+à·à¶°à·à¶Žà¶­à·à¶à· à¶
+à¶­à·à¶»à·à¶žà·à·à·à¶«à¶­}  
+_textdescrgli_ [l=si] {"à¶à¶à¶­à·à¶±à·,  à¶Žà·à¶­à·à¶±à· à¶à¶à¶­à·à¶±à· à¶±à·à·à¶­ à·à·à¶à·à·à¶ž à·à· à¶
+à·
+à·à¶­à·à¶±à· à¶¯à¶­à·à¶­ à¶à¶à¶­à· à¶à·à¶»à·à¶ž, à·à· à¶à¶à¶­à·à¶±à· à¶žà¶à· à¶¯à·à¶žà·à¶žà¶§ à¶à¶Žà¶à·à¶»à· à·à·."}  
+
+package collector
+
+_textcollector_ [l=si] {à¶à¶à¶à· à¶à¶»à¶±à·à¶±à·}  
+_textdescrcollector_ [l=si] {à¶žà·à¶º à¶Žà·à·à·à¶­à¶à·à·
+à·à¶°à·à¶Žà¶­à·à¶±à·à¶à· à¶
+à¶­à·à¶»à·à¶žà·à·à·à¶«à¶­( interface)à·âà·à¶à· à·à·à·à¶­à· à¶
+à¶±à·à¶žà¶­ à¶à¶»à¶±à·âà·à¶ºà· à¶±à·à¶ºà¶žà·à¶­ à¶Žà·à·à·à¶­à¶à·à·
+à·à¶°à·à¶Žà¶­à·à¶±à·à¶à· à¶
+à¶­à·à¶»à·à¶žà·à·à·à¶«à¶­ à¶·à·à·à¶­à· à¶à¶»à¶± ââà·à¶œà·à¶§à¶º}  
+
+package depositor
+
+_textdepositor_ [l=si] {à¶­à·à¶±à·à¶Žà¶­à· à¶à¶»à¶±à·à¶±à·}  
+_textdescrdepositor_ [l=si] {à¶Žà·à¶­à·à¶± à¶¯à¶­à·à¶­ à¶à·à¶±à· à¶à¶à¶­à·à·à¶§ à¶
+à¶œà·à¶­à· à¶¯à¶­à·à¶­à·à¶âà·à¶±à· à¶à¶à¶­à· à¶à·à¶»à·à¶ž à·à¶³à·à· à¶à¶¶âà¶§ ââà·à¶žà¶º à¶à¶Žà¶à·à¶»à· âà·à·à·.}  
+
+package gti
+
+_textgti_ [l=si] {Greenstoneà·à· à¶·à·à·à· à¶Žà¶»à·à·à¶»à·à¶®à¶âà·à¶à·  à¶
+à¶­à·à¶»à·à¶žà·à·à·à¶«à¶­}  
+_textdescrtranslator_ [l=si] {Greenstoneà·à· à¶¶à·à·-à¶·à·à·à·à¶­ à¶
+à¶­à·à¶»à·à¶žà·à·à·à¶«à¶­ à·à·à¶à·à·à¶žà¶§ à¶à¶¶à¶§ à¶à¶Žà¶à·à¶»à· à·à·}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=si] {à¶žà·à¶ž à¶à¶à¶­à·âà· à¶Žà·à·
+à·à¶¶à¶³}  
+
+_textsubcols1_ [l=si] {<p>à¶žà·à¶ž à¶à¶à¶­à·âà· à¶­à·à¶±à·  à¶à¶­à· à¶à¶Žà¶à¶à¶­à·  _1_ subcollections.à¶à·à·à¶ºà·à¶±à· à¶¯à·à¶±à¶§ à¶à¶­à·à¶­à·:  <blockquote>}  
+
+_textsubcols2_ [l=si] {</blockquote> à¶¯à·à¶±à¶§ à¶·âà·à·à·à¶­à·à¶à¶»à¶± à¶Žà·à¶»à·à·à·à¶œà¶± à¶Žà·à¶§à·à·à·   à¶à¶Žà¶à·à¶±à· à¶à¶à¶­à·à·à¶±à·   âà·à¶žà·à· à¶¯à· âà¶Žà¶»à·à¶à·à·à·à¶à¶» à¶à¶­  (à·à·à¶±à·à· à¶à¶») à·à·à¶à·à¶ºà·}  
+
+_titleabout_ [l=si] {à¶à·à¶±}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=si] {à¶à¶à¶­à·à·à·/à¶Žà·à·à·à¶­à¶à·à¶œà¶ºà· à¶žà·à¶ž âà·à¶à·à¶§à· à·à·à¶±à·à¶±}  
+_texticonclosedbookshelf_ [l=si] {à·à¶à·âà·à·à· à¶
+à¶±à·à¶­à¶»à·à¶à¶­à¶º à·à¶à·à¶±à·à¶±}  
+_texticonopenbook_ [l=si] {à¶žà·à¶ž âà·à¶Žà·à¶­ à·à·à¶±à·à¶±}  
+_texticonclosedfolder_ [l=si] {à¶žà·à¶ž à¶à·à¶±à·à·(folderà¶º) à·à·à·à·à¶­ à¶à¶» à¶
+à¶±à·à¶­à¶»à·à¶à¶­à¶º à¶¶à¶œà¶±à·à¶±}  
+_texticonclosedfolder2_ [l=si] {à¶à¶Ž-à¶à·à¶§à· à·à·à·à·à¶­ à¶à¶»à¶±à·à¶±:}  
+_texticonopenfolder_ [l=si] {à¶žà·à¶ž à¶à·à¶±à·à·(folderà¶º) à·à·à¶±à·à¶±}  
+_texticonopenfolder2_ [l=si] {à¶žà·à¶ž à¶à¶Ž-âà¶à·à¶§à· à·à·à¶±à·à¶±}  
+_texticonsmalltext_ [l=si] {à¶Žà·à¶šà¶ºà¶±à·à·à· à¶žà·à¶ž à¶à·à¶§à· à¶Žà·à¶±à·à·à¶±à·à¶±}  
+_texticonsmalltext2_ [l=si] {à¶Žà·à¶šà¶ºà¶±à· à¶Žà·à¶±à·à·à¶±à·à¶±}  
+_texticonpointer_ [l=si] {à¶¯à·à¶±à¶§ à¶Žà·à¶­à·à¶± à¶à·âà¶§à·}  
+_texticondetach_ [l=si] {à¶žà·à¶ž à¶Žà·à¶§à·âà· à¶
+à·
+à·à¶­à· à¶à·à·à·
+à·à·à¶ à·à·à·à·à¶­ à¶à¶»à¶±à·à¶±}  
+_texticonhighlight_ [l=si] {à·à·à¶ºà¶± à¶Žà¶¯à¶º à¶à·
+à·à¶Žà·à¶Žà· à¶¯à¶à·à·à¶±à·à¶±}  
+_texticonnohighlight_ [l=si] {à·à·à¶ºà¶± à¶Žà¶¯à¶º à¶à·
+à·à¶Žà·à¶Žà· à¶¯à¶à·à·à¶±à·à¶± à¶à¶Žà·}  
+_texticoncontracttoc_ [l=si] {à¶
+à¶±à·à¶­à¶»à·à¶à¶­à¶º}  
+_texticonexpandtoc_ [l=si] {âà·à¶à·à·à· à¶
+à¶±à·à¶­à¶»à·à¶à¶­à¶º à·à·à·à·à¶œà·à¶­ à¶à¶» à¶¯à¶à·à·à¶±à·à¶±}  
+_texticonexpandtext_ [l=si] {à·à·à¶ºà·
+à·âà¶ž à¶Žà·à·
+ à¶Žà·à¶±à·à·à¶±à·à¶±}  
+_texticoncontracttext_ [l=si] {à¶­à·à¶»à· à¶à¶­à· à¶à·âà¶§à·à· à¶
+à¶à·à¶»à· à¶Žà¶žà¶«à¶à· à¶Žà·à¶±à·à·à¶±à·à¶±}  
+_texticonwarning_ [l=si] {<b>à¶
+à·à·à·à¶¯à¶ºà¶ºà·: </b>}  
+_texticoncont_ [l=si] {à¶¯à·à¶à¶§à¶ž à¶à¶»à¶±à·à¶± à¶¯?}  
+
+
+
+_textgoto_ [l=si] {à¶Žà·à¶§à·à·à¶§ à¶ºà¶±à·à¶±}  
+_textintro_ [l=si] {<i>(à·à·à¶³à·à¶±à·à·à·à¶žà· à¶Žà·à¶šà¶º)</i>}  
+
+_textCONTINUE_ [l=si] {à¶¯à·à¶à¶§à¶ž à¶à¶»à¶±à·à¶± à¶¯?}  
+
+_textEXPANDTEXT_ [l=si] {à·à·à·à·à¶œà·à¶­ âà·à¶Žà·
+}  
+
+_textCONTRACTCONTENTS_ [l=si] {ââà¶à·à¶§à· âà¶ºà¶±à·}  
+
+_textDETACH_ [l=si] {à·à·à¶±à·à¶à¶»à¶±à·à·}  
+
+_textEXPANDCONTENTS_ [l=si] {à·à·à·à·à¶œà·à¶­ à¶
+à¶±à·à¶­à¶»à·à¶à¶­à¶ºà¶±à·}  
+
+_textCONTRACT_ [l=si] {à¶à·âà¶§à· à¶Žà·à·
+à·}  
+
+_textHIGHLIGHT_ [l=si] {à·à¶à·âà·à·à· à¶
+à¶±à·à¶­à¶»à·à¶à¶­à¶º à·à¶à·à¶±à·à¶±}  
+
+_textNOHIGHLIGHT_ [l=si] {à¶à·
+à·à¶Žà·à¶Žà· à¶¯à·à¶à·à·à·à¶žà¶à· à¶±à·à¶­}  
+
+_textPRINT_ [l=si] {à¶žà·à¶¯à·âà¶»à¶«}  
+
+_textnextsearchresult_ [l=si] {à¶žà·à·
+à¶ à·à·à·à·à¶žà· à¶Žà·âà¶»à¶­à·à¶µà¶œ}  
+_textprevsearchresult_ [l=si] {à¶Žà·à¶» à·à·à·à·à¶žà· à¶Žà·âà¶»à¶­à·à¶µà¶œ}  
+
+# macros for printing page
+
+_textprintpage_ [l=si] {à¶žà·à¶º à¶žà·à¶¯à·âà¶»à¶« à¶à¶»à¶±à·à¶±}  
+_textshowcontents_ [l=si] {à·à¶à·à·à· à¶
+à¶±à·à¶­à¶»à·à¶à¶­à¶º à¶Žà·à¶±à·à·à¶±à·à¶±}  
+_texthidecontents_ [l=si] {à·à¶à·âà·à·à· à¶
+à¶±à·à¶­à¶»à·à¶à¶­à¶º à·à¶à·à¶±à·à¶±}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+
+
+
+
+_textall_ [l=si] {à·à·à¶ºà·
+à·}  
+
+
+
+
+
+
+
+
+#alt text for query buttons
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+
+
+
+
+
+
+
+
+
+
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textdatesearch_ [l=si] {à¶¯à·à¶±à¶ºà¶±à· à·à¶žà¶ âà·à·à·à¶ºà¶±à·à¶±}  
+
+
+
+
+
+
+
+
+
+
+#text macros for search history
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=si] {à¶à·à¶±à· à·à¶à·à¶± à¶œà¶¯âà·à¶¯à·}  
+_textalsoshowing_ [l=si] {à¶Žà·à¶±à·}  
+_textwith_ [l=si] {à·à·à¶©à·à¶ºà·à¶±à·}  
+_textdocsperpage_ [l=si] {à¶Žà·à¶§à·à·à¶§ à¶à¶­à· âà·à¶à·à¶±à·}  
+
+_textfilterby_ [l=si] {à¶œà¶¶à· à¶à¶­à· à¶¯à¶­à·à¶­ à¶à·à¶±à· âââà·à¶œ à¶
+à¶©à¶à¶à·/à¶à¶­à·à¶œà¶­à· à·à¶±à·à¶±à·}  
+
+_textany_ [l=si] {à¶à·à¶žà¶à· à·à·}  
+_textwords_ [l=si] {à·à¶ à¶± à·à¶œà·à¶±à·}  
+_textleaveblank_ [l=si] {à¶œà¶¶à· à¶à¶­à· à¶¯à¶­à·à¶­ à¶à·à¶±à· à¶œà¶¶à· à¶à·à¶±à·à¶ž à·à¶³à·à· à¶žà·à¶ž à¶à·à¶§à·/à¶à·âà¶§à·âà· à·à·à·à·âà· à¶­à¶¶à¶±à·à¶±.}  
+
+_browsebuttontext_ [l=si] {à¶Žà·à·
+à¶§ à·à·à¶à·à· à¶¯à¶­à·à¶­à¶à·à¶±à·}  
+
+_nodata_ [l=si] {<i> à¶¯à¶­à·à¶­ à¶±à·à¶­</i>}  
+_docs_ [l=si] {à¶¯à¶­à·à¶­à¶à·à¶±à·}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=si] {à¶à¶Žà¶à·à¶»/à¶à¶¯à·à·}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=si] {à¶¯à¶­à·à¶­à·à¶âà·à¶±à· à·à·à·à·à¶žà¶§   _1_ à¶±à·    _2_ âà¶¶à·à¶­à·à¶­à¶ž  à¶à¶¶à¶±à·à¶±.}  
+
+
+
+_textFromhelp_ [l=si] {" à¶Žà·âà¶»à¶à·à·à¶± à·à·âà·à·à¶žà¶§ "à¶­à·à¶à·(From) " à·à· à¶à¶­à·  _labelFrom_ à¶¶à·à¶­à·à¶­à¶ž  à¶à¶¶à¶±à·à¶±."}  
+_textBrowsehelp_ [l=si] {à¶¯à¶­à·à¶­ à¶à·à¶±à· à·à·âà·à·à¶ž}  
+_textAcronymhelp_ [l=si] {à¶à·à¶§à· à·à¶¯à¶±à·(Acronym) à¶žà¶à·à¶±à· à¶¯à¶­à·à¶­à¶à·à¶±à· à·à·à·à·à¶žà¶§  _labelAcronym_ à¶¶à·à¶­à·à¶­à¶ž à¶à¶¶à¶±à·à¶±. }  
+
+
+
+
+
+
+
+
+# help about the icons
+_texthelpopenbookshelf_ [l=si] {à¶žà·à¶ž à¶Žà·à¶­à· à¶»à·à¶à·à¶à¶º à·à·à·à·à¶­ à¶à¶»à¶±à·à¶±}  
+_texthelpopenbook_ [l=si] {à¶žà·à¶ž à¶Žà·à¶­ à·à·à·à·à¶­ à¶à¶»à¶±à·à¶±/ââà·à·à¶±à·à¶±}  
+
+_texthelpexpandtext_ [l=si] {"à·à·à¶ºà¶œà·à¶œ à¶Žà·à¶±à·à·à¶±à·à¶±, âà·à· âà·à¶±à·à¶Žà·à¶±à·à·à¶±à·à¶±"}  
+_texthelpexpandcontents_ [l=si] {"à·à¶à·âà·à·à·à· à¶
+à¶±à·à¶­à¶»à·à¶à¶­à¶º à·à¶©à·à¶­à· à¶¯à·à¶à·à¶»à·à¶±à·à¶±, à·à· à¶âà·à·à· âà·à¶±à·à¶à¶»à¶±à·à¶± â"}  
+_texthelpdetachpage_ [l=si] {à¶žà·à¶ž à¶Žà·à¶§à·à· à¶
+à·
+à·à¶­à· à¶à·à·à·
+à·à·à¶à·à¶±à· à·à·à·à·à¶­ à¶à¶»à¶±à·à¶±}  
+_texthelphighlight_ [l=si] {âà·à·à·à· ââà·à¶ºà¶¯à·à¶žà· à¶à¶œà·à¶Žà·à¶Žà·(Highlight) à¶¯à¶à·à·à¶±à·à¶±}  
+
+
+
+
+
+
+
+_texthelpquerytermstitle_ [l=si] {à·à·à·à·à¶žà· à¶Žà¶¯}  
+_texthelpqueryterms_ [l=si] {"<p>à·à·à·à·à¶žà· à·à·à¶žà·à·à¶žà· à·à¶à·à·à¶¯ à¶à·à¶§à·à·à· à¶à¶¶ à·à¶³à·à¶±à· à¶à¶»à¶± à¶à¶±à·à¶ž à·à¶¯à¶±à¶à· à·à· à·à·à¶à·âà¶º à¶à¶«à·à¶©à¶ºà¶à· âà·à·à·à·à¶žà· à¶Žà¶¯à¶ºà¶à·â à¶œà·à· à·à¶³à·à¶±à·à·à¶±à· à¶œà¶¶à¶ºà·.  (à·à·à·à·à¶žà·) à¶Žà¶¯à¶ºà¶à· à¶œà·à· à¶
+à¶à·à¶»à· à·à· à·à¶à¶à·âà¶ºà· à¶à¶­à·à¶œà¶­à· à·à¶¯à¶±à¶à· à·à·, à¶à¶¯à·à¶°à·à¶­ à¶Žà·à¶š ("...") à¶œà·à· à¶à¶­à·à¶œà¶­à·  à·à·à¶à·âà¶º à¶à¶«à·à¶©à¶ºà¶à· à·à·à·à¶¯ à·à·à¶º à·à·à¶. (à·à·à·à·à¶žà·) à¶Žà¶¯ à¶
+à·à¶»à·à¶« à·à·à¶©à·à·à¶à·à¶±à·(white space) à·à·à¶±à· à¶à¶»à¶±à· à¶œà¶¶à¶ºà·. à¶­à·à¶¯ à·à·à¶»à·à¶ž à¶œà¶à·à¶«à·à¶¯(punctuation)  à¶à¶­à·à¶œà¶­à· à¶±à¶žà·, à¶à·à·à¶¯ à·à·à¶©à·à·à· à¶œà·à· à·à¶œà¶à· à·à·à¶±à· à¶à¶»à¶±à· à¶œà¶¶à¶ºà·. à¶à¶¶à¶§ à·à·à¶»à·à¶ž à¶œà¶à·à¶«à· (punctuation)  à¶à¶­à·à¶œà¶­à· à¶Žà¶¯ à¶·à·à·à·à¶­à· à¶à¶»à¶žà·à¶±à· à·à·à·à·à¶žà¶à· à¶à¶œ à¶±à·à·à·à¶.
+
+<p>à¶à¶¯à·à·à¶»à¶«à¶ºà¶à· à¶œà·à·, à·à·à¶žà·à·à¶žà¶à¶¯à·<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>à¶ºà¶±à·à¶± à¶Žà·à¶­ à¶¯à·à¶à·à·à·à¶± à¶Žà¶»à·à¶¯à·à¶ž à·à¶œà¶à¶±à· à¶œà¶¶à¶ºà·.<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+"}  
+
+_texthelpmgppsearching_ [l=si] {MGPPà·à·à·à¶­à· à¶à·à¶©à¶±à¶à·à¶± à¶œà¶¯ à¶à¶à¶­à·à¶±à·à·à· à¶
+à¶žà¶­à¶» à·à·à¶à¶œà·à¶Ž à¶à·à·à·à¶Žà¶ºà¶à· à¶¯ à¶à¶­à·à¶œà¶­à· à·à·.
+
+<ul>
+<li>à·à·à·à·à¶žà· à¶Žà¶¯à¶ºà¶ à¶
+à·à·à·à¶±à¶ºà· à¶à¶­à· à¶±à·à¶¯à·à·à· à¶œà¶à·à¶«à¶à· <b>*</b> à¶à¶ž âà·à¶ à¶±à¶ºà·à¶±à· à¶à¶»âà·à¶¹à¶± à·à·à¶ºà·
+à· à·à¶ à¶± à·à¶³à·à· à¶à·à¶œà¶Žà·à¶ºà· <b>à·à¶žà¶ à¶à¶»âà·à¶¹à¶±</b>, à¶à¶¯à·. <b>comput*</b> à¶ºà¶±à·à¶±  <b>comput</b> à·à¶œà·à¶±à· à¶à¶»à¶žà·à¶· à·à¶± à·à·à¶ºà·
+à· à·à¶ à¶± à·à¶³à·à· à¶à·à¶œà¶Žà·à¶ºà·.
+<li><b>/x</b> can be used to give higher weight to one or more of the query terms, eg <b>computer/10 science</b> gives computer 10 times more weight than science when ranking documents.
+</ul>}  
+
+_texthelplucenesearching_ [l=si] {Lucene à·à·à·à¶­à· à¶à·à¶©à¶±à¶à·à¶± à¶œà¶¯ à¶à¶à¶­à·à¶±à·à·à· à¶
+à¶žà¶­à¶» à·à·à¶à¶œà·à¶Ž à¶à·à·à·à¶Žà¶ºà¶à· à¶¯ à¶à¶­à·à¶œà¶­à· à·à·.
+
+<ul>
+<li><b>?</b> à¶ºà¶±à·à¶± à¶±à·à¶¯à·à·à· à¶œà¶à·à¶«à¶à·(wildcard) à¶œà·à· à¶­à¶±à· à¶
+à¶à·à¶»à¶à· à·à¶³à·à· à¶·à·à·à·à¶­à· à¶à¶œ à·à·à¶. à¶à¶¯à·à·à¶»à¶«à¶ºà¶à· à¶œà·à·, <b>b?t</b> à¶ºà¶±à·à¶± <b>bet</b>, <b>bit</b> à·à· <b>bat</b> à¶à¶¯à· à¶œà·à· à¶à·à¶œà¶Žà·à¶ºà·.
+<li><b>*</b> à¶ºà¶±à·à¶± à¶±à·à¶¯à·à·à· à¶œà¶à·à¶«à¶à·(wildcard) à¶œà·à· à¶¶à·à·à· à¶
+à¶à·à¶»à· à·à¶³à·à· à¶·à·à·à·à¶­à· à¶à¶œ à·à·à¶.. à¶à¶¯à·à·à¶»à¶«à¶ºà¶à· à¶œà·à·, <b>comput*</b> à¶ºà¶±à·à¶±  <b>comput</b> à·à¶œà·à¶±à· à¶à¶»à¶žà·à¶· à·à¶± à·à·à¶ºà·
+à· à·à¶ à¶± à·à¶³à·à· à¶à·à¶œà¶Žà·à¶ºà·.
+</ul>
+à¶žà·à¶ž à¶±à·à¶¯à·à·à· à¶œà¶à·à¶«à·(wildcard) à¶¯à·à¶à¶ž à·à·à·à·à¶žà· à¶Žà¶¯à¶ºà¶ à¶žà¶°à·âà¶ºà¶ºà· à·à· à¶
+à·à·à·à¶±à¶ºà· à¶·à·à·à·à¶­à· à¶à·
+ à·à·à¶. à¶±à¶žà·à¶­à· à¶à·à· à·à·à·à·à¶žà· à¶Žà¶¯à¶ºà¶ à¶à¶»à¶žà·à¶·à¶ºà¶§ à¶·à·à·à·à¶­à· à¶à·
+ à¶±à·à·à·à¶.}  
+
+_texthelpquerytypetitle_ [l=si] {à·à·à·à·à¶žà·/âà·à·à¶žà·à·à¶žà· à¶à¶à·à¶»}  
+_texthelpquerytype_ [l=si] {<p>âà¶à¶à·âà·à¶±à¶à¶§ à·à·à¶±à·à· à·à·à¶žà·à·à¶žà· à¶à¶à·à¶» à¶¯à·à¶à¶à· à¶­à·à¶¶à·.
+
+<ul>
+  <li> <b>à·à·à¶ºà·
+à·à¶ž</b> à¶Žà¶¯ à·à¶³à·à· à·à· à·à·à¶žà·à·à¶žà· à¶à¶à·à¶»à¶º.  à¶žà·à¶º à¶¯à¶­à·à¶­ à·à¶žà·à¶¯à·à¶ºà· (à·à· à¶Žà¶»à·à¶¡à·à¶¯à¶º, à·à· à¶žà·à¶­à·à¶à·à· )  à¶à¶¶ à·à·à·à·à·à¶«à¶º à¶à¶»à¶± à¶œà¶¯ à·à·à¶ºà·
+à· à¶ž  à·à¶¯à¶±à· à¶à¶­à·à¶œà¶­à· à·à· à¶¯à·à¶ºà· à·à·à¶ºà· à¶¶à¶œà¶ºà·.
+      à¶¯à¶­à·à¶­ à·à¶žà·à¶¯à·à¶º à¶à¶ºà·à¶±à· à¶­à·à¶Žà·à¶­ à·à·à¶±à¶žà· à¶
+à¶¯à·à¶œ à·à·à¶žà·à·à¶ž à¶à·à¶©à¶±à·à¶à·à· à¶à¶à·à¶»à¶ºà¶§ à¶¯à·à·âà· à·à·.
+<p>
+
+  <li> <b>à·à¶žà·à¶»</b> à¶Žà¶¯ à·à¶³à·à· à·à· à·à·à¶žà·à·à¶žà· à¶à¶à·à¶»à¶º. à¶à¶¶ à·à·à¶ºà¶± à¶Žà¶¯/à¶Žà¶¯à¶º à·à¶¯à·à¶±à· à·à¶± à¶¯à¶­à·à¶­à·à¶žà·à¶¯à·à¶ºà· à·à·à¶ºà·
+à· à¶­à·à¶»à¶­à·à¶»à· à¶Žà·à¶±à·à·à¶ºà·. à¶à¶¶à· à·à·à¶žà·à·à¶žâà¶§ à·à¶©à·à¶­à· à¶à·à¶œà¶Žà·à¶± à¶
+à¶±à·à¶Žà·à¶œà·à·à·à¶œà¶§ à¶¯à¶­à·à¶­ à¶œà¶¶à· à¶¯à·à¶ºà·. à¶¯à¶­à·à¶­ à¶à·à¶œà¶Žà·à¶± à¶
+à¶±à·à¶Žà·à¶œà·à·à·à¶œ à·à¶œà¶à· à¶¶à·à¶œà·à¶žà· à¶¯à·,
+
+      <p><ul>
+        <li> the more search term occurrences a document contains, the closer it matches;
+        <li> à·à·à¶žà·à¶±à·âà¶º  à·à·à·à·à¶žà· à¶Žà¶¯ à·à¶œà¶§ âà·à¶©à· à¶¯à·à¶»à·à¶œà¶· à·à·à·à·à¶žà· à¶Žà¶¯ à¶à¶­à·à¶œà¶­à· à¶à¶à¶­à·à¶±à· à·à¶©à· à·à·à¶¯à¶à¶­à· à·à·;
+        <li> à¶à·à¶§à· à¶¯à¶­à·à¶­, à¶¯à·à¶à· à¶¯à¶­à·à¶­ à·à¶œà¶§ à·à¶©à· à·à·à¶³à·à¶±à· à¶à·à¶œà¶Žà·à¶º à·à·à¶.
+      </ul>
+</ul>
+
+<p>à·à¶žà·à¶Žà·à¶»à·à¶« à·à·à¶à·âà¶ºà¶ºà¶à· à·à·, à·à¶žà·à¶Žà·à¶»à·à¶« à¶Žà¶»à·à¶¡à·à¶ºà¶à· à·à¶³à·à· à·à·à·à¶¯  à¶à¶¶âà¶§ à¶
+à·à·à·âà¶º à¶­à¶»à¶žà¶à· à·à·à·à·à¶žà· à¶Žà¶¯ à¶·à·à·à·à¶­à· à¶à¶œ à·à·à¶.  If you specify only
+one term, documents will be ordered by its frequency of occurrence.<p>
+}  
+
+_texthelpadvancedsearchtitle_ [l=si] {à·à·à·à·à·à¶­à¶» âà·à·à·à·à¶žà·(advance search) à·à¶œà¶¯à·  _1_  à·à·à·à·à¶žà· à¶ºà¶±à·à¶­à·âà¶»à¶º à¶·à·à·à·à¶­à· à¶à¶»à¶ºà·}  
+
+_texthelpadvancedsearch_ [l=si] {<p>à¶à¶¶ à·à·à·à·à·à¶­à¶» à·à·à·à·à¶žà· à¶à¶à·à¶»à¶º(advanced query) à¶à¶à·à¶»à¶º à¶­à·à¶»à·à¶à¶­à·à¶­à· à¶±à¶žà· âà·à·à·à·à¶žà· à¶à¶à·à¶»à¶º/à·à·à¶à¶œà·à¶Ž(options) à¶žà¶¯à¶à· âà·à·à¶±à·à· à·à·._selectadvancedsearch_}  
+
+_texthelpadvsearchmg_ [l=si] {"MG à¶à¶à¶­à·à¶±à·à·à· à·à·à·à·à·à¶­à¶»à·à¶­à·à¶žà¶ à·à·à·à·à¶žà· à¶à¶¶à¶§ à·à·à¶à¶œà·à¶Žâ à¶¯à·à¶à¶à· à¶œà¶¶à·â à¶¯à·à¶ºà·. à¶à¶±à¶žà· ranked à·à· (à·à·à¶¢) booleanà¶º.
+A <b>ranked</b> à·à·à·à·à¶ž à¶±à·à·à·à¶ à·à¶­à·à¶ž à·à¶žà·à¶± à·à¶±à·à¶ºà· <b>à·à¶žà·à¶»</b> à·à·à·à·à¶­à¶» à¶à¶» à¶
+âà·à¶­à· à·à·à·à·à¶žà· <a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_"	}  
+
+
+
+_texthelpadvsearchmgpp_ [l=si] {"MGPP collections  à·à¶œ  à·à·à·à·à·à¶­à¶» âà·à·à·à·à¶žà·(advance search) à·à¶¯à·à·  à¶·à·à·à·à¶­à· à¶âà·à¶œà·  boolean operators. _texthelpbooleansearch_
+<p>The results can be displayed in <b>ranked</b> order, as described for the <b>some</b> search in <a href="\#query-type">_texthelpquerytypetitle_</a>, or in "natural" (or "build") order. This is the order that documents were processed during the creation of the collection.
+<p>
+Further operators include <b>NEARx</b> and <b>WITHINx</b>.
+NEARx is used to specify the maximum distance apart (x words) two query
+terms must be for a document to match. 
+WITHINx specifies that the second term must occur within x words <i>after</i> the first term. This is similar to NEAR but the order is important. The default distance is 20."}  
+
+_texthelpadvancedsearchextra_ [l=si] {à·à¶§à·à¶±:à¶à¶¶ à·à¶»à¶œ  âà·à·à·à·à¶žà¶à·/à·à·à·à·à¶žà¶à· à¶à¶»à¶±à·à·à¶§ à¶žà·à¶ž operators à¶±à·à·à¶œà¶à· âà¶
+à¶­à·à·à¶»à·à¶±à· à¶à¶­. }  
+
+_texthelpadvsearchlucene_ [l=si] {Lucene collections  à·à¶œ  à·à·à·à·à·à¶­à¶» âà·à·à·à·à¶žà·(advance search) à·à¶³à·à· (à·à·à¶¢)boolean operators à¶·à·à·à·à¶­à· à¶à¶»à¶±à·à¶±. _texthelpbooleansearch_  }  
+
+_texthelpformsearchtitle_ [l=si] {à·à·à·à·à¶žà· à¶à·à·à·à¶­à·âà¶»à¶º}  
+
+_texthelpformsearch_ [l=si] {"<p> à¶
+à¶¯à·à¶œ à·à·à·à·à¶žà· à¶Žà¶¯ à¶à¶à·à¶±à·à¶ à·à¶»à·à· à·à¶ž à¶à¶»à¶žà·à¶±à· à·à·à·à·à¶žà· à¶à·âà¶»à·à¶žà¶§ à¶à·à·à·à¶­à·âà¶» à·à·à·à·à¶žà· à·à·à¶¯à· à¶
+à·à¶à·à·à¶º à¶œà¶¶à· à¶¯à·à¶ºà·. à¶à¶¯à·à·à¶»à¶«à¶ºà¶à· à¶œà·à·, à¶ºà¶žà· à¶
+à¶ºà·à¶à·à¶§ "Smith" à¶ºà¶±à·à¶± à¶žà·à¶­à·à¶à·à· à¶œà·à· à·à· "snail farming"  à¶ºà¶±à·à¶± à·à·à·à¶ºà¶º à¶œà·à· à·à¶³à·à¶±à· à¶à¶» à·à·à·à·à¶žà· à¶à¶œ à·à·à¶. à·à¶»à¶œ à·à·à¶žà·à·à¶žà· à¶à¶à·à¶»à¶ºà·à¶¯à·, à¶Žà¶­à·âà¶»à¶ºà· à¶à¶­à· à·à·à¶ž à¶­à¶±à· à¶Žà·à¶œà·à¶ºà¶à·à¶ž à·à·à¶žà·à¶±à·âà¶º à¶­à¶±à· à¶Žà·à¶œà· à·à·à·à·à¶žà¶à· à¶œà·à· à·à·à·à·à¶»à·. à¶Žà¶­à·âà¶»à¶ºà· à¶à¶­à· à¶­à¶±à· à¶Žà·à¶œà· à¶à¶à·à¶±à·à¶ à·à¶žà·à¶¶à¶±à·à¶° à¶à¶» à·à·à·à·à¶žà· à¶à·âà¶»à·à¶ž à·à¶¯à·à·, à·à·(AND) ("à·à·à¶ºà·
+à·(all)" âà·à·à·à·à¶žà· à·à¶³à·à· à¶¯)  à¶à·à·à¶­à· à¶±à·à¶­à·à¶±à¶žà· à·à·(OR)  ("à·à¶žà·à¶»(some)" à·à·à·à·à¶žà· à·à¶³à·à· à¶¯) à¶·à·à·à·à¶­à· à¶à¶œ à·à·à¶. à¶
+à¶¯à·à¶œ à¶à·à·à·à¶­à·âà¶»à¶º à¶­à·à·
+ à·à· à·à·à·à·à¶žà· à¶Žà¶¯ à¶¯ à¶à¶ž à¶Žà¶»à·à¶¯à·à¶ž à¶à¶à·âà·à¶±à¶ à·à¶žà·à¶¶à¶±à·à¶° à·à·. à·à·à·à·à·à¶­à¶»à·à¶­à·à¶žà¶ à·à·à·à·à¶žà·  à¶à·âà¶»à¶žà¶ºà· à¶¯à·  à¶
+à¶¯à·à¶œ à¶à·à·à·à¶­à·âà¶» à¶
+à¶­à¶» à¶à¶¶à¶§ à¶
+à·à·à·âà¶º AND/OR/NOT  à·à·à¶±à· à·à·à·à·à¶° à·à·à·à·à·à·à¶­ à·à¶žà·à¶¶à¶±à·à¶° à¶à·à¶»à·à¶žà· drop-down lists à¶·à·à·à·à¶­à¶ºà·à¶±à· à¶¯, à¶
+à¶¯à·à¶œ à¶à·à·à·à¶­à·âà¶» à¶­à·à·
+à¶¯à· à·à·à¶¢ operators à¶·à·à·à·à¶­à¶ºà·à¶±à· à¶¯ à¶à·
+ à·à·à¶."}  
+
+_texthelpformstemming_ [l=si] {""fold" à·à· "stem" à¶à·à¶§à·, à¶à¶¶à¶§ à·à·à·à·à¶žà· à¶Žà¶¯ casefolded à·à· stemmed à¶œà·à· à·à·à·à·à· à¶à¶» à¶¯à·à¶à·à·à·à¶žà¶§ à¶
+à·à¶à·à· à·à¶œà·à¶ºà·. à¶žà·à¶ž à¶à¶à·à¶» à¶¯à·à¶à¶ž à·à¶žà·à¶žà¶­à¶º à¶œà·à· à·à·à·à·à·à¶­à¶»à·à¶­à·à¶žà¶ à·à·à·à·à¶žà·à¶¯à· à¶
+à¶à·âà¶»à·à¶º à¶à¶» à¶­à·à¶¶à·à¶º à·à·à¶."}  
+
+
+
+_texthelpdatesearch_ [l=si] {à¶¯à·à¶± à·à·à·à¶­ à·à·à·à·à¶žà· à·à¶œà¶¯à·, à¶à¶º à¶à¶¶à· à·à·à·à·à¶žà· à¶Žà¶¯à¶º à¶±à·à·à·à¶ à·à¶­ à¶à·à¶œ à¶Žà¶»à·à·à¶ºà¶à· à¶­à·à·
+ à¶
+à¶¯à·à¶œ à¶¯à¶­à·à¶­ à·à¶žà·à¶¯à·à¶º à¶­à·à·
+ à·à·à¶ºà· à¶¶à·à¶œà·à¶žà¶§ à¶
+à·à¶à·à· à·à¶œà·à¶ºà·. 
+à¶à·à·à¶ž à¶à¶¶à¶§ à¶à·à·à·à¶ºà¶žà· à¶±à·à·à·à¶ à·à¶­ à¶à·à¶œ/à¶¯à·à¶± à·à·à¶žà·à·à¶ à·à·à¶§-à¶à·à·à·à¶ºà¶žà· à¶±à·à·à·à¶ à·à¶­ à¶à·à¶œ/à¶¯à·à¶± à·à·à¶žà·à·à¶à· à¶¯à¶à·à·âà· à¶
+à¶¯à·à¶œ à·à·à·à·à¶ž à¶à¶œ à·à·à¶. à·à¶§à·à¶±: à¶à¶¶à¶§ à·à·à·à·à¶žà· à¶Žà¶¯à¶ºà¶à· à¶·à·à·à·à¶­à¶º à¶
+à·à·à·âà¶ºà¶ž à¶±à·à·à· -- à¶à¶¶à¶§ à¶¯à·à¶±à¶º à·à¶žà¶ à¶Žà¶žà¶±à¶à· à·à·à·à¶¯ à¶
+à¶¯à·à¶œ à·à·à·à·à¶ž à¶à¶œ à·à·à¶, à¶­à·à¶¯ à¶à¶¶à¶à· à·à·à·à·à¶žà·à¶¯à· à¶¯à·à¶±à¶ºà¶à· à¶·à·à·à·à¶­à· à¶à·à¶»à·à¶ž à¶
+à¶­à·âà¶ºà·à·à·à·âà¶º à¶±à·à·à·, à¶à¶¶à¶à· à·à·à·à·à¶žà·à¶¯à· à¶¯à·à¶±à¶ºà¶à· à·à¶³à·à¶±à· à¶±à·à¶à¶œà¶¯ à¶à¶º is just the same as if the date search didn't exist.<p>}  
+
+
+_texthelpdatehowto_ [l=si] {"<ul>
+   <li>à¶­à¶±à· à·à¶»à·à·à¶ºà¶à· à·à¶³à·à· à¶¯à¶­à·à¶­ à·à¶žà·à¶¯à·à¶º à·à·à·à·à¶ž:<p>
+   <ul>
+       <li>à¶à¶¶ à¶à·à¶žà¶­à· à¶Žà¶»à·à¶¯à· à·à·à¶žà·à¶±à·âà¶º à·à¶ à¶±à¶ºà¶à·, à·à·à·à·à¶ž à·à¶³à·à· à¶à¶­à·à·
+à· à¶à¶»à¶±à·à¶±.
+       <li>à¶à¶¶à¶§ à¶
+à·à·à·âà¶º à·à¶»à·à·à¶º "Start (or only) date" à¶à·à¶§à·à· à¶­à·à·
+ à·à¶³à·à¶±à· à¶à¶»à¶±à·à¶±.
+       <li>à¶à¶¶à¶à· à¶¯à·à¶±à¶º à·à·à¶žà·à¶±à·âà¶º à¶ºà·à¶à¶ºà¶§ à¶Žà·à¶» à¶±à¶žà· (à¶à·âà¶»à·.à·.à¶§ à¶Žà·à¶» à¶±à¶žà·),  "B.C.E"  à·à·à¶à¶œà·à¶Žà¶º à¶à¶ž à¶à·à¶§à·à·à¶§ à¶ºà·à¶¶à¶¯à· à¶à¶­à· à¶à¶œà·à·à·à¶œà·à¶± menuà·à·à¶±à· à¶­à·à¶»à¶±à·à¶±.
+       <li>à¶à¶¶à· à·à·à·à·à¶ž à·à·à¶žà·à¶±à·âà¶º à¶Žà¶»à·à¶¯à· à¶
+à¶»à¶¹à¶±à·à¶±.
+   </ul>
+<p><li>à¶ºà¶žà·à¶à·à·à· à¶à·à¶œà¶ºà¶à¶§ à·à· à·à¶»à·à· à¶Žà¶»à·à·à¶ºà¶à¶§ à¶
+à¶ºà¶­à· à¶¯à¶­à·à¶­ à·à¶žà·à¶¯à·à¶º à·à·à·à·à¶ž:<p>
+   <ul>
+       <li>à¶à¶¶ à¶à·à¶žà¶­à· à¶Žà¶»à·à¶¯à· à·à·à¶žà·à¶±à·âà¶º à·à¶ à¶±à¶ºà¶à·, à·à·à·à·à¶ž à·à¶³à·à· à¶à¶­à·à·
+à· à¶à¶»à¶±à·à¶±..
+       <li>à¶à¶¶à¶§ à¶
+à·à·à·âà¶º à¶žà·à¶œà· à·à¶»à·à·à¶º "Start (or only) date" à¶à·à¶§à·à· à¶­à·à·
+ à·à¶³à·à¶±à· à¶à¶»à¶±à·à¶±.
+       <li>Tà¶à¶¶à¶§ à¶
+à·à·à·âà¶º à¶
+à·à·à·à¶± à·à¶»à·à·à¶º "End date" à¶à·à¶§à·à· à¶­à·à·
+ à·à¶³à·à¶±à· à¶à¶»à¶±à·à¶±..
+       <li>"à¶à¶¶à¶à· à¶¯à·à¶±à¶º à·à·à¶žà·à¶±à·âà¶º à¶ºà·à¶à¶ºà¶§ à¶Žà·à¶» à¶±à¶žà· (à¶à·âà¶»à·.à·.à¶§ à¶Žà·à¶» à¶±à¶žà·),  "B.C.E"  à·à·à¶à¶œà·à¶Žà¶º à¶à¶ž à¶à·à¶§à·à·à¶§ à¶ºà·à¶¶à¶¯à· à¶à¶­à· à¶à¶œà·à·à·à¶œà·à¶± menuà·à·à¶±à· à¶­à·à¶»à¶±à·à¶±.
+       <li>à¶à¶¶à· à·à·à·à·à¶ž à·à·à¶žà·à¶±à·âà¶º à¶Žà¶»à·à¶¯à· à¶
+à¶»à¶¹à¶±à·à¶±.
+   </ul>    
+</ul><p>"}  
+
+_texthelpdateresultstitle_ [l=si] {à¶à¶¶à· à·à·à·à·à¶žà· à¶Žà·âà¶»à¶­à·à¶µà¶œ à¶à·âà¶»à·à¶ºà· à¶à¶»à¶± à¶
+à¶ºà·à¶»à·/à¶à¶à·à¶»à¶º}  
+
+
+_textchangeprefs_ [l=si] {à¶à¶¶âà·à¶à· à¶žà¶±à·à¶Žà¶ºà¶±à· âà·à·à¶±à·à· à¶à¶»à¶±à·à¶±}  
+
+_texthelppreferences_ [l=si] {<p>à¶à¶¶ âà·à¶žà¶ž à¶Žà·à¶§à·âà·à· à¶à¶© à¶
+à¶­à· <i>_Global:linktextPREFERENCES_</i>à¶
+à¶ºà·à¶­à¶ž click à¶à¶» à·à·à¶§  à¶žà·à·à·à¶«à¶­( interface) à¶
+à¶­à· à·à¶žà·à¶» à¶
+à¶à¶ à¶žà¶±à¶Žà¶º à¶Žà¶»à·à¶¯à· à·à¶à·à·  à¶à¶­à·à·à¶à·à¶º.}   
+
+
+
+
+_texthelplanguageprefstitle_ [l=si] {à¶·à·à·à· à¶žà¶±à·à¶Ž}  
+_texthelplanguageprefs_ [l=si] { <p> à·à·à¶ž à¶à¶à¶­à·à·à¶à· à·à¶¯à·à· à¶ž à·à¶žà·à¶žà¶­ à¶·à·à·à· à¶à¶¯à·à¶»à·à¶Žà¶­à· à¶à·à¶»à·à¶žà¶à· à¶­à·à¶¶à·, à¶±à¶žà·à¶­à· à¶à¶¶âà¶§ à¶
+à·à·à·à· à¶Žà¶»à·à¶¯à· à¶à¶º à·à·à·à·à¶° à¶·à·à·à·à·à¶±à· à¶¶à·à¶§ à·à·à¶±à·à· à¶à¶» à¶à·à¶±à·à¶žà¶§ à·à·à¶. You can also alter the encoding scheme
+used by Greenstone for output to the browser -- the software chooses
+sensible defaults, à¶±à¶žà·à¶­à· à·à¶žà·à¶» à·à·à¶»à·à·à¶»à· à·à¶œà¶¯à· à·à·à·à·à¶° encoding scheme à·à¶œà¶§ à¶žà·à¶»à· à¶à·à¶»à·à¶žà·à¶±à· à¶Žà¶žà¶«à¶à· à¶±à·âà·à·à¶»à¶¯à· à¶œà·à· à¶
+à¶à·à¶»à· à¶¶à¶œà· à¶à¶­ à·à·à¶.  à¶à¶¶à¶§ à·à·à¶ºà·
+à·à¶ž à¶à¶à¶­à·à¶±à·à·à· à·à¶žà·à¶žà¶­ à¶ à·à¶­à·âà¶»à¶ à¶
+à¶­à·à¶»à·à¶žà·à·à·à¶«à¶­à· à¶à¶à·à¶­à·à¶ºà· à·à·à¶§ à¶Žà·à¶š à¶
+à¶­à·à¶»à·à¶žà·à·à·à¶«à¶­à· à¶à¶à·à¶­à·à¶º à¶¯à¶à·à·à· à·à·à¶±à·à· à¶à¶»à¶à¶­ à·à·à¶. à¶žà·à¶º à·à·à·à·à·à¶ºà·à¶±à· à¶¶à·à¶±à·à¶ž à¶¯à·à¶¶à¶œ à¶Žà¶»à·à·à·à¶œà¶à¶ºà¶±à·à¶§ à¶¯, à¶Žà·âà¶»à¶žà·à¶«à¶ºà·à¶±à· à·à·à·à·à¶œ à¶
+à¶à·à¶»à· à·à·à·à¶­ à¶­à·à¶»(screen) à¶·à·à·à·à¶­à· à¶à¶»à¶±à·à¶±à¶±à·à¶§à¶¯  speech synthesizersà¶§à¶¯ à¶Žà·âà¶»à¶ºà·à¶¢à¶±à·à¶­à· à·à·.}  
+
+_texthelppresentationprefstitle_ [l=si] {à¶à¶¯à·à¶»à·à¶Žà¶­à· à¶à·à¶»à·à¶žà· à¶žà¶±à·à¶Žà¶ºà¶±à·} 
+
+
+
+_texthelpsearchprefs_ [l=si] {<p>    à·à·à·à·à¶žà· à¶Žà·à¶§à·à·à·à¶±à· à¶à¶¶à¶§ à¶à¶­à· à·à¶»à¶œ à¶Žà·à¶ºà·à¶» à¶à·à·à·à¶Žà¶ºà¶à·à¶±à· à·à·à¶žà·à·à¶žà¶à· à·à·à¶¯à· à¶à¶œ à·à·à¶:<p>        <ol><li>à¶à¶¶à¶§ à·à·à·à·à¶žà¶§ à¶
+à·à·à·à· à¶Žà¶¯ à·à·à·à·à·à¶«à¶º à¶à¶» à¶¯à¶à·à·à¶±à·à¶±        <li> à¶à¶¶à¶§ à¶
+à·à·à·âà¶º  à·à¶±à·à¶±à· à¶Žà¶¯  à·à·à¶ºà¶œà·à¶œà¶ž à¶à¶­à·à¶œà¶­à·âà· à·à·à·à·à¶žà¶¯ à¶±à·à¶­à·à¶±à¶žà· à·à¶žà·à¶» à¶Žà¶¯ à¶à¶­à·à¶œà¶­à·â âà· à·à·à·à·à¶žà¶¯  à¶ºà¶±à·à¶± à·à¶³à·à¶±à· à¶à¶»à¶±à·à¶±        <li> à¶à¶¶à¶§ à·à·à·à·à¶žà¶§ à¶
+à·à·à·à· à¶Žà¶¯ à·à¶³à·à¶±à· à¶à¶»à¶±à·à¶±        <li> <i>Begin Search</i> à¶¶à·à¶­à·à¶­à¶ž  à¶à¶¶à¶±à·à¶±    </ol>    <p> à¶à¶¶ à·à·à¶žà·à·à¶žà¶à· à¶à¶»à¶± à·à·à¶§, à¶¯à¶­à·à¶­ à·à¶žà·à¶¯à·à¶ºà· à¶
+à¶¯à·à¶œ à¶à·à¶œà¶Žà·à¶± à¶žà·à¶­à·à¶à· âà·à·à·à·à·à¶à· à¶à¶âà·à¶» à¶Žà·à¶±à·à·à¶ºà·.  à¶
+à·à·à·à¶±à¶ºà· à¶à¶­à· à¶¶à·à¶­à·à¶­à¶ž à¶žà·à·
+à¶ à¶žà·à¶­à·à¶à· âà·à·à·à·à· à¶à¶»à· à¶à¶¶ à¶à·à¶± à¶ºà¶ºà·.  à¶à¶­à·à¶±à¶¯à· à¶­à·à·à·à¶±à·  à¶žà·à¶­à·à¶à· âà·à·à·à·à· à¶à¶»à· à·à· à¶±à·à·à¶­ à¶žà·à¶œà· à¶žà·à¶­à·à¶à· âà·à·à·à·à· à¶à¶»à· à¶ºà· à·à·à¶à·  à¶¶à·à¶­à·à¶­à¶žà· à¶à¶­. à¶à¶±à·à¶ž à¶žà·à¶­à·à¶à·à·à¶à· à¶žà¶­ à·à·, à¶ à¶
+à·à¶œ  à¶à¶­à· à¶à·à¶©à· à¶¶à·à¶­à·à¶­à¶ž à¶à¶¶à·à¶žà·à¶±à· à¶à¶¶âà¶§ à¶žà·à¶º à¶¯à·à¶ à¶à¶­ à·à·à¶.   <p>A maximum of 100 is imposed on the number of    documents returned.  à¶à¶¶âà¶§ à¶žà·à¶ž à¶Žà·âà¶»à¶žà·à¶«à¶º   à¶Žà·à¶§à·à·à· à¶à¶© à¶à¶­à· <i>_Global:linktextPREFERENCES_</i> à¶¶à·à¶­à·à¶­à¶ž à¶à¶¶à·à¶žà·à¶±à· à·à·à¶±à·à· à¶à¶» à¶à¶­ à·à·à¶.<p>}
+
+_textcasefoldprefs_ [l=si] {"à·à·à·à·à¶žà¶à¶¯à· upper à·à· lower à¶
+à¶à·à¶»à· à¶à·à¶œà¶Žà·à¶ž à¶žà·à¶ž à¶¶à·à¶­à·à¶­à¶žà· à¶ºà·à¶à¶œ à¶žà¶à·à¶±à· à¶Žà·à¶œà¶±à¶º à¶à¶»à¶±à· à¶œà¶¶à¶ºà·. à¶à¶¯à·à·à¶»à¶«à¶ºà¶à· à¶œà·à·."_preferences:textignorecase_" is selected, <i>snail farming</i> à¶­à·à¶»à·à¶à¶­à·à·à¶­à·, à¶à¶º, <i>Snail Farming</i> à·à· <i>SNAIL FARMING</i> à¶à¶à¶ž à¶œà·à· à·à¶œà¶à¶±à· à¶à¶­."}  
+
+_textaccentfoldprefs_ [l=si] {à·à·à·à·à¶žà¶à¶¯à· accented à·à· unaccented à¶
+à¶à·à¶»à· à¶à·à¶œà¶Žà·à¶ž à¶žà·à¶ž à¶¶à·à¶­à·à¶­à¶žà· à¶ºà·à¶à¶œ à¶žà¶à·à¶±à· à¶Žà·à¶œà¶±à¶º à¶à¶»à¶±à· à¶œà¶¶à¶ºà·. à¶à¶¯à·à·à¶»à¶«à¶ºà¶à· à¶œà·à·."_preferences:textignoreaccents_"  <i>fÃ©dÃ©ration</i> à¶­à·à¶»à·à¶à¶­à·à·à¶­à·, à¶à¶º <i>fedÃ©ration</i> à·à· <i>federation</i> à¶à¶à¶ž à¶œà·à· à·à¶œà¶à¶±à· à¶à¶­.}  
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_texthelpscopetitle_ [l=si] {à·à·à¶žà·à·à¶žà· à¶Žà¶»à¶žà·à¶»à·à¶®à¶º/à¶
+à¶»à¶žà·à¶«	}  
+_texthelpscope_ [l=si] {<p>
+à¶¶à·à·à· à¶à¶à¶­à·à¶±à·à·à· à¶à¶¶à¶§ à¶à·à¶žà¶­à· à·à·à·à¶° à¶Žà¶§à·à¶±à¶à·(indexes) à¶·à·à·à·à¶­à· à¶à¶»à¶žà·à¶±à· à¶
+à¶¯à·à¶œ à·à·à·à·à¶žà· à¶à¶œ à·à·à¶. à¶à¶¯à·à·à¶»à¶«à¶ºà¶à· à¶œà·à·, à¶à·à· à¶à¶»à·à¶­à·à¶±à·à¶à· à·à· à¶žà·à¶­à·à¶à· à·à· à¶Žà¶§à·à¶±à· à¶­à·à¶¶à·à¶º à·à·à¶. à·à¶žà·à¶» à·à·âà¶§ à¶à·à· à¶¡à·à¶¯ à·à· à¶Žà¶»à·à¶¡à·à¶¯ à¶œà·à·à¶¯ à¶Žà¶§à·à¶±à· à¶­à·à¶¶à·à¶º à·à·à¶. à·à·à¶žà·à¶±à·âà¶ºà¶ºà·à¶±à·,
+the full matching document is returned regardless of which index you search.
+<p>à¶à¶¶à¶à· à¶¯à¶­à·à¶­ à·à¶žà·à¶¯à·à¶º à¶Žà·à¶­à· à¶±à¶žà·, à¶à·à· à¶
+à¶¯à·à¶œ à·à·à¶®à·à¶±à¶ºà· à·à·à¶§ à·à·à·à·à¶­ à·à¶±à· à¶à¶­.}  
Index: /gsdl/stable/macros/slovak.dm
===================================================================
--- /gsdl/stable/macros/slovak.dm	(revision 20131)
+++ /gsdl/stable/macros/slovak.dm	(revision 20131)
@@ -0,0 +1,638 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Slovak Language text and icon macros 
+# Many thanks to Tomas Fiala
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=sk] {PeriodikÃ¡}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=sk] {Zdroj}  
+_textdate_ [l=sk] {dÃ¡tum vydania:}  
+_textnumpages_ [l=sk] {poÄet strÃ¡n}  
+
+_textsignin_ [l=sk] {prihlÃ¡siÅ¥ sa}  
+
+_textdefaultcontent_ [l=sk] {VyÅŸiadanÃ¡ strÃ¡nka nemohla byÅ¥ zobrazenÃ¡. PouÅŸite prosÃ­m funkciu "spÃ€Å¥" vo vaÅ¡om prehliadaÄi, alebo kliknite na tlaÄidlo domov pre nÃ¡vrat do digitÃ¡lnej kniÅŸnice.}  
+
+_textdefaulttitle_ [l=sk] {Chyba GSDL}  
+
+_textbadcollection_ [l=sk] {TÃ¡to zbierka (s nÃ¡zvom "_cvariable_") nie je nainÅ¡talovanÃ¡ v systÃ©me digitÃ¡lnej kniÅŸnice Greenstone. }  
+
+_textselectpage_ [l=sk] {â VybraÅ¥ stranu â}  
+
+_collectionextra_ [l=sk] {TÃ¡to zbierka obsahuje _about:numdocs_ dokumentov. PoslednÃœ termÃ­n aktualizÃ¡cie bol pred _about:builddate_ dÅami.}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=sk] {<p>TÃ¡to zbierka obsahuje _numdocs_ _If_("_numdocs_" eq "1",document,documents), celkom _numbytes_ indexovanÃ©ho textu a metadÃ¡t. <p><a href="_httppagex_(bsummary)">Klikni sem</a> pre zobrazenie prehÄŸadu o tejto zbierke. }  
+
+_textdescrcollection_ [l=sk] {}
+_textdescrabout_ [l=sk] {O kniÅŸnici}  
+_textdescrhome_ [l=sk] {DomovskÃ¡ strÃ¡nka}  
+_textdescrhelp_ [l=sk] {Pomoc}  
+_textdescrpref_ [l=sk] {Nastavenia}  
+_textdescrgreenstone_ [l=sk] {SoftvÃ©r digitÃ¡lnej kniÅŸnice Greenstone}  
+_textdescrusab_ [l=sk] {Äo je podÄŸa vÃ¡s nÃ¡roÄnÃ© na pouÅŸitie?}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=sk] {HÄŸadaÅ¥}  
+_labelSearch_ [l=sk] {VyhÄŸadaÅ¥}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=sk] {NÃ¡zvu}  
+_labelTitle_ [l=sk] {Tituly}  
+_textCreator_ [l=sk] {Autor}  
+_labelCreator_ [l=sk] {Autori}  
+_textSubject_ [l=sk] {Predmetu}  
+_labelSubject_ [l=sk] {K&#318;&#250;&#269;ov&#233; slov&#225;}  
+_textDescription_ [l=sk] {Popis}  
+_labelDescription_ [l=sk] {Popis}  
+_textPublisher_ [l=sk] {VydavateÄŸ}  
+_labelPublisher_ [l=sk] {Vydavatelia}  
+_textContributor_ [l=sk] {PrispievateÄŸ}  
+_labelContributor_ [l=sk] {Prispievatelia }  
+_textDate_ [l=sk] {DÃ¡tum}  
+_labelDate_ [l=sk] {DÃ¡tumy}  
+_textType_ [l=sk] {Typ}  
+_labelType_ [l=sk] {Typy}  
+_textFormat_ [l=sk] {FormÃ¡t}  
+_labelFormat_ [l=sk] {FormÃ¡ty}  
+_textIdentifier_ [l=sk] {identifikÃ¡tor}  
+_labelIdentifier_ [l=sk] {IdentifikÃ¡tor}  
+_textSource_ [l=sk] {NÃ¡zov sÃºboru}  
+_labelSource_ [l=sk] {NÃ¡zvy sÃºborov}  
+_textLanguage_ [l=sk] {Jazyk}  
+_labelLanguage_ [l=sk] {Jazyky}  
+_textRelation_ [l=sk] {VzÅ¥ah}  
+_labelRelation_ [l=sk] {VzÅ¥ahy}  
+_textCoverage_ [l=sk] {Pokrytie}  
+_labelCoverage_ [l=sk] {Pokrytie}  
+_textRights_ [l=sk] {PrÃ¡va}  
+_labelRights_ [l=sk] {PrÃ¡va}  
+
+# DLS metadata set
+_textOrganization_ [l=sk] {OrganizÃ¡cie}  
+_labelOrganization_ [l=sk] {OrganizÃ¡cie}  
+_textKeyword_ [l=sk] {KÄŸÃºÄovÃ© slovo}  
+_labelKeyword_ [l=sk] {KÄŸÃºÄovÃ© slovÃ¡}  
+_textHowto_ [l=sk] {spÃŽsobu rieÅ¡enia problematiky}  
+_labelHowto_ [l=sk] {Ako}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=sk] {FrÃ¡za}  
+_labelPhrase_ [l=sk] {FrÃ¡zy}  
+_textCollage_ [l=sk] {KolÃ¡ÅŸ}  
+_labelCollage_ [l=sk] {KolÃ¡ÅŸ}  
+_textBrowse_ [l=sk] {PrezrieÅ¥}  
+_labelBrowse_ [l=sk] {PrezrieÅ¥}  
+_textTo_ [l=sk] {Do}  
+_labelTo_ [l=sk] {Do}  
+_textFrom_ [l=sk] {PodÄŸa}  
+_labelFrom_ [l=sk] {Od}  
+_textAcronym_ [l=sk] {Skratka}  
+_labelAcronym_ [l=sk] {Skratky}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=sk] {PrezeraÅ¥ podÄŸa _1_ }  
+
+_textdescrSearch_ [l=sk] {HÄŸadaj presnÃœ termÃ­n}  
+_textdescrType_ [l=sk] {PrezeraÅ¥ podÄŸa typu zdroja}  
+_textdescrIdentifier_ [l=sk] {PrezrieÅ¥ podÄŸa identifikÃ¡tora zdroja}  
+_textdescrSource_ [l=sk] {PrezeraÅ¥ podÄŸa pÃŽvodnÃ©ho nÃ¡zvu sÃºboru}  
+_textdescrTo_ [l=sk] {PrezeraÅ¥ podÄŸa poÄŸa}  
+_textdescrFrom_ [l=sk] {PrezeraÅ¥ podÄŸa poÄŸa "Od" }  
+_textdescrCollage_ [l=sk] {PrezeraÅ¥ cez obrÃ¡zkovÃº kolÃ¡ÅŸ}  
+_textdescrAcronym_ [l=sk] {PrezeraÅ¥ skratkami  }  
+_textdescrPhrase_ [l=sk] {ListovaÅ¥ frÃ¡zy}  
+_textdescrHowto_ [l=sk] {PrezrieÅ¥ podÄŸa kategÃ³riÃ­}  
+_textdescrBrowse_ [l=sk] {PrezeraÅ¥ dokumenty}  
+_texticontext_ [l=sk] {PozrieÅ¥ dokument}  
+_texticonclosedbook_ [l=sk] {otvoriÅ¥ tento dokument a ukÃ¡zaÅ¥ obsah}  
+_texticonnext_ [l=sk] {do ÄalÅ¡ej Äasti}  
+_texticonprev_ [l=sk] {do predchÃ¡dzajÃºcej Äasti}  
+
+_texticonworld_ [l=sk] {PozrieÅ¥ webovÃœ dokument}  
+
+_texticonmidi_ [l=sk] {UkÃ¡ÅŸ MIDI dokument}  
+_texticonmsword_ [l=sk] {UkÃ¡ÅŸ dokument Microsoft Word}  
+_texticonmp3_ [l=sk] {UkÃ¡ÅŸ MP3 dokument}  
+_texticonpdf_ [l=sk] {UkÃ¡ÅŸ PDF dokument}  
+_texticonps_ [l=sk] {PozrieÅ¥ PostScript dokument}  
+_texticonppt_ [l=sk] {UkÃ¡ÅŸ PowerPoint dokument}  
+_texticonrtf_ [l=sk] {PozrieÅ¥ RTF dokument}  
+_texticonxls_ [l=sk] {PozrieÅ¥ Microsoft Excel dokument}  
+
+_page_ [l=sk] {strana}  
+_pages_ [l=sk] {strany}  
+_of_ [l=sk] {z}  
+_vol_ [l=sk] {RoÄnÃ­k}  
+_num_ [l=sk] {ÄÃ­slo}  
+
+_textmonth00_ [l=sk] {}
+_textmonth01_ [l=sk] {JanuÃ¡r}  
+_textmonth02_ [l=sk] {FebruÃ¡r}  
+_textmonth03_ [l=sk] {Marec}  
+_textmonth04_ [l=sk] {AprÃ­l}  
+_textmonth05_ [l=sk] {MÃ¡j}  
+_textmonth06_ [l=sk] {JÃºn}  
+_textmonth07_ [l=sk] {JÃºl}  
+_textmonth08_ [l=sk] {August}  
+_textmonth09_ [l=sk] {September}  
+_textmonth10_ [l=sk] {OktÃ³ber}  
+_textmonth11_ [l=sk] {November}  
+_textmonth12_ [l=sk] {December}  
+
+_textdocument_ [l=sk] {Dokument}  
+_textsection_ [l=sk] {Äast}  
+_textparagraph_ [l=sk] {Odsek}  
+
+_magazines_ [l=sk] {Äasopisy}  
+
+_nzdlpagefooter_ [l=sk] {<div class="divbar"> </div>
+ <p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+ <br><a href="http://www.cs.waikato.ac.nz">Department of Computer Science</a>, 
+ <a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+ New Zealand}  
+
+_linktextHOME_ [l=sk] {DOMOV}  
+_linktextHELP_ [l=sk] {POMOC}  
+_linktextPREFERENCES_ [l=sk] {NASTAVENIA}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=sk] {DigitÃ¡lna kniÅŸnica Greenstone}  
+
+_textnocollections_ [l=sk] {MomentÃ¡lne nie sÃº dostupnÃ© ÅŸiadne zbierky.}  
+
+_textadmin_ [l=sk] {SprÃ¡vcovskÃ¡ strÃ¡nka }  
+_textabgs_ [l=sk] {O Greenstone}  
+_textgsdocs_ [l=sk] {DokumentÃ¡cia Greenstone}  
+
+_textdescradmin_ [l=sk] {UmoÅŸÅuje pridÃ¡vaÅ¥ novÃœch pouÅŸÃ­vateÄŸov, manaÅŸovaÅ¥ kolekcie a poskytuje technickÃ© informÃ¡cie o inÅ¡talÃ¡cii.}  
+
+_textdescrgogreenstone_ [l=sk] {PrinÃ¡Å¡a informÃ¡cie o softvÃ©ri Greenstone a projekte digitÃ¡lnej kniÅŸnice NovÃ©ho ZÃ©landu.}  
+
+_textdescrgodocs_ [l=sk] {PrÃ­ruÄka Greenstone}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=sk] {KnihovnÃ­cke rozhranie}  
+_textdescrgli_ [l=sk] {UmoÅŸÅuje vytvÃ¡raÅ¥, upravovaÅ¥ a mazaÅ¥ zbierky.}  
+
+package collector
+
+_textcollector_ [l=sk] {ZberateÄŸ}  
+_textdescrcollector_ [l=sk] {PouÅŸÃ­vanie knihovnÃ­ckeho rozhrania je praktickejÅ¡ie a vhodnejÅ¡ie.}  
+
+package depositor
+
+_textdepositor_ [l=sk] {Depozit}  
+_textdescrdepositor_ [l=sk] {UmoÅŸÅuje pridaÅ¥ dokumenty do existujÃºcich zbierok}  
+
+package gti
+
+_textgti_ [l=sk] {PrekladovÃ© rozhranie Greenstone}  
+_textdescrtranslator_ [l=sk] {PomÃ¡ha udrÅŸiavaÅ¥ aktualizovanÃ© viacjazyÄnÃ© verzie Greenstone.  }  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=sk] {O tejto zbierke}  
+
+_textsubcols1_ [l=sk] {<p>CelÃ¡ zbierka zahÅÅa  _1_ ÄiastkovÃœch zbierok. PrÃ¡ve dostupnÃ© sÃº: <blockquote>}  
+
+_textsubcols2_ [l=sk] {</blockquote> Na webovej strÃ¡nke "Nastavenia" si mÃŽÅŸete skontrolovaÅ¥ (a zmeniÅ¥) ÄiastkovÃ© zbierky, ktorÃ© prÃ¡ve pouÅŸÃ­vate.  }  
+
+_titleabout_ [l=sk] {O zbierke}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=sk] {zavri tÃºto ÄasÅ¥ kniÅŸnice}  
+_texticonclosedbookshelf_ [l=sk] {otvoriÅ¥ tÃºto ÄasÅ¥ kniÅŸnice a zobraziÅ¥ obsah}  
+_texticonopenbook_ [l=sk] {zavri tÃºto knihu}  
+_texticonclosedfolder_ [l=sk] {OtvoriÅ¥ tento prieÄinok a zobraziÅ¥ obsah}  
+_texticonclosedfolder2_ [l=sk] {otvoriÅ¥ podsekciu}  
+_texticonopenfolder_ [l=sk] {zavri tento prieÄinok}  
+_texticonopenfolder2_ [l=sk] {zavri tÃºto podsekciu}  
+_texticonsmalltext_ [l=sk] {ZobraziÅ¥ tÃºto ÄasÅ¥ textu}  
+_texticonsmalltext2_ [l=sk] {zobraziÅ¥ text}  
+_texticonpointer_ [l=sk] {aktuÃ¡lna sekcia}  
+_texticondetach_ [l=sk] {OtvoriÅ¥ strÃ¡nku v novom okne}  
+_texticonhighlight_ [l=sk] {ZvÃœrazniÅ¥ hÄŸadanÃ© termÃ­ny}  
+_texticonnohighlight_ [l=sk] {NezvÃœrazniÅ¥ hÄŸadanÃ© termÃ­ny}  
+_texticoncontracttoc_ [l=sk] {ZbaliÅ¥ obsah}  
+_texticonexpandtoc_ [l=sk] {RozbaliÅ¥ obsah}  
+_texticonexpandtext_ [l=sk] {ZobraziÅ¥ celÃœ text}  
+_texticoncontracttext_ [l=sk] {ZobraziÅ¥ text len pre aktuÃ¡lnu sekciu}  
+_texticonwarning_ [l=sk] {<b>Upozornenie: </b>}  
+_texticoncont_ [l=sk] {POKRAÄOVAÅ€?}  
+
+_textltwarning_ [l=sk] {<div class="buttons">_imagecont_</div>_iconwarning_RozbalenÃ­m textu bude zaÅ¥aÅŸenÃœ vÃ¡Å¡ prehliadaÄ veÄŸkÃœm mnoÅŸstvom dÃ¡t}  
+
+_textgoto_ [l=sk] {choÄ na strÃ¡nku}  
+_textintro_ [l=sk] {<i>(ÃºvodnÃœ text)</i>}  
+
+_textCONTINUE_ [l=sk] {POKRAÄOVAÅ€?}  
+
+_textEXPANDTEXT_ [l=sk] {ROZBALIÅ€ TEXT}  
+
+_textCONTRACTCONTENTS_ [l=sk] {STIAHNUÅ€ OBSAH}  
+
+_textDETACH_ [l=sk] {OTVORIÅ€ V NOVOM OKNE}  
+
+_textEXPANDCONTENTS_ [l=sk] {ROZBALIÅ€ OBSAH}  
+
+_textCONTRACT_ [l=sk] {STIAHNUÅ€ TEXT}  
+
+_textHIGHLIGHT_ [l=sk] {ZVÃRAZNENIE}  
+
+_textNOHIGHLIGHT_ [l=sk] {BEZ ZVÃRAZNENIA}  
+
+_textPRINT_ [l=sk] {TLAÄ}  
+
+_textnextsearchresult_ [l=sk] {ÄalÅ¡Ã­ vÃœsledok vyhÄŸadÃ¡vania}  
+_textprevsearchresult_ [l=sk] {predchÃ¡dzajÃºci vÃœsledok vyhÄŸadÃ¡vania}  
+
+# macros for printing page
+_textreturnoriginal_ [l=sk] {NÃ¡vrat na pÃŽvodnÃº strÃ¡nku}  
+_textprintpage_ [l=sk] {VytlaÄiÅ¥ tÃºto stranu}  
+_textshowcontents_ [l=sk] {ZobraziÅ¥ obsah}  
+_texthidecontents_ [l=sk] {SkryÅ¥ obsah}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=sk] {_If_(_thislast_,vÃœsledky _thisfirst_ - _thislast_ na dotaz: _cgiargq_,Åœiadne vÃœsledky: _cgiargq_)}  
+_textnoquerytitle_ [l=sk] {VyhÄŸadÃ¡vacia strana}  
+
+_textsome_ [l=sk] {niektorÃœch}  
+_textall_ [l=sk] {vÅ¡etkÃœch}  
+_textboolean_ [l=sk] {boolov}  
+_textranked_ [l=sk] {klasifikovanÃœ}  
+_textnatural_ [l=sk] {prirodzenÃœ}  
+_textsortbyrank_ [l=sk] {PodÄŸa relevancie}  
+_texticonsearchhistorybar_ [l=sk] {histÃ³ria vyhÄŸadÃ¡vania}  
+
+_textifeellucky_ [l=sk] {CÃ­tim sa Å¡Å¥astne!}  
+
+#alt text for query buttons
+_textusequery_ [l=sk] {pouÅŸi tento dotaz}  
+_textfreqmsg1_ [l=sk] {PoÄet slov:}  
+_textpostprocess_ [l=sk] {_If_(_quotedquery_,<br>spracovanÃ© kvÃŽli vyhÄŸadaniu<i>_quotedquery_</i>
+)}  
+_textinvalidquery_ [l=sk] {ZlÃœ syntax dotazu}  
+_textstopwordsmsg_ [l=sk] {NasledujÃºce slovÃ¡ }  
+_textlucenetoomanyclauses_ [l=sk] {VÃ¡Å¡ dotaz obsahoval veÄŸa termÃ­nov; pouÅŸite konkrÃ©tnejÅ¡Ã­ dotaz. }  
+
+_textmorethan_ [l=sk] {Viac ako}  
+_textapprox_ [l=sk] {O}  
+_textnodocs_ [l=sk] {Åœiadne dokumenty nevyhovujÃº vaÅ¡ej poÅŸiadavke.}  
+_text1doc_ [l=sk] {1 dokument vyhovuje poÅŸiadavke.}  
+_textlotsdocs_ [l=sk] {dokumentov zodpovedÃ¡ poÅŸiadavke}  
+_textmatches_ [l=sk] {VÃœsledky}  
+_textbeginsearch_ [l=sk] {ZaÄaÅ¥ vyhÄŸadÃ¡vanie}  
+_textrunquery_ [l=sk] {SpusÅ¥ dotaz}  
+_textclearform_ [l=sk] {ÄistÃœ formulÃ¡r}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=sk] {SlovÃ¡ alebo frÃ¡zy
+}  
+_textinfield_ [l=sk] {... V poli}  
+_textfoldstem_ [l=sk] {(veÄŸkosÅ¥ znakov, stemming)}  
+
+_textadvquery_ [l=sk] {Alebo vloÅŸte dotaz priamo:}  
+_textallfields_ [l=sk] {vÅ¡etky polia}  
+_texttextonly_ [l=sk] {len text}  
+_textand_ [l=sk] {a}  
+_textor_ [l=sk] {alebo}  
+_textandnot_ [l=sk] {a nie}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=sk] {HÄŸadaj _indexselection_ _If_(_jselection_,z _jselection_ )_If_(_gselection_, na _gselection_ level )_If_(_nselection_,v jazyku _nselection_ ) s pomocou _querytypeselection_ slov_If_(_sfselection_,\,_allowformbreak_ a zoraÄ vÃœsledky podÄŸa _sfselection_)}  
+
+_textadvancedsearch_ [l=sk] {HÄŸadaj _indexselection_ _If_(_jselection_,z _jselection_ )_If_(_gselection_,na Ãºrovni _gselection_ level )_If_(_nselection_,v jazyku _nselection_ )s pouÅŸitÃ­m _querytypeselection_ dotazu}  
+
+_textadvancedmgppsearch_ [l=sk] {HÄŸadaj _indexselection_ _If_(_jselection_,z _jselection_ )_If_(_gselection_,na Ãºrovni _gselection_ level )_If_(_nselection_,v jazyku _nselection_ ) a zobraz vÃœsledky v _formquerytypeadvancedselection_ poradÃ­}  
+
+_textadvancedlucenesearch_ [l=sk] {HÄŸadaj  _indexselection_ _If_(_jselection_,z _jselection_ )_If_(_gselection_,na Ãºrovni _gselection_)_If_(_nselection_, v _nselection_ jazyku)_If_(_sfselection_,\,_allowformbreak_ zoraÄ vÃœsledky podÄŸa _sfselection_\,)}  
+
+_textformsimplesearch_ [l=sk] {HÄŸadaj _If_(_jselection_,_jselection_ )_If_(_gformselection_, na Ãºrovni _gformselection_ level )_If_(_nselection_, v _nselection_ jazyku)_If_(_sfselection_,\, zoraÄ vÃœsledky podÄŸa _sfselection_\,) pre _formquerytypesimpleselection_}  
+
+_textformadvancedsearchmgpp_ [l=sk] {HÄŸadaj _If_(_jselection_,_jselection_ )_If_(_gformselection_, v _gformselection_)_If_(_nselection_,v _nselection_ jazyku ) a zobraz vÃœsledky v _formquerytypeadvancedselection_ poradÃ­}  
+
+_textformadvancedsearchlucene_ [l=sk] {HÄŸadaj _If_(_jselection_, _jselection_)_If_(_gformselection_,  v _gformselection_ level)_If_(_nselection_, v _nselection_ jazyku)_If_(_sfselection_,\, usporiadaj vÃœsledky podÄŸa _sfselection_\,)}  
+
+_textnojsformwarning_ [l=sk] {Pozor: Javascript vo vaÅ¡om prehliadaÄi je vypnutÃœ. <br>Ak chcete vyhÄŸadÃ¡vaÅ¥ podÄŸa polÃ­, zapnite ho.}  
+_textdatesearch_ [l=sk] {V tejto zbierke mÃŽÅŸete prehÄŸadÃ¡vaÅ¥ podÄŸa dÃ¡tumu, alebo dokumenty v urÄitom Äasovom obdobÃ­. Je to voliteÄŸnÃ¡ funkcia vyhÄŸadÃ¡vania. }  
+_textstartdate_ [l=sk] {ZaÄiatoÄnÃœ (alebo aj koneÄnÃœ) dÃ¡tum}  
+_textenddate_ [l=sk] {KoncovÃœ dÃ¡tum:}  
+_textbc_ [l=sk] {p. n. l.}  
+_textad_ [l=sk] {n.l.}  
+_textexplaineras_ [l=sk] {C.E. a B.C.E predstavujÃº alternatÃ­vu k A.D. a B.C. A oznaÄujÃº "Common Era" a "Before the Common Era"}  
+
+_textstemon_ [l=sk] {(ignoruj anglickÃ© koncovky)}  
+
+_textsearchhistory_ [l=sk] {HistÃ³ria vyhÄŸadÃ¡vania}  
+
+#text macros for search history
+_textnohistory_ [l=sk] {HistÃ³ria dotazov nie je dostupnÃ¡}  
+_texthresult_ [l=sk] {zÃ¡znam}  
+_texthresults_ [l=sk] {zÃ¡znamov}  
+_texthallwords_ [l=sk] {vÅ¡etky slovÃ¡}  
+_texthsomewords_ [l=sk] {najmenej 1 slovo}  
+_texthboolean_ [l=sk] {boolove}  
+_texthranked_ [l=sk] {klasifikovanÃœ}  
+_texthcaseon_ [l=sk] {zÃ¡leÅŸÃ­ na veÄŸkosti pÃ­sma}  
+_texthcaseoff_ [l=sk] {nezÃ¡leÅŸÃ­ na veÄŸkosti pÃ­sma}  
+_texthstemon_ [l=sk] {automatickÃ© doplnenie koncoviek}  
+_texthstemoff_ [l=sk] {celÃ© slovo sa musÃ­ zhodovaÅ¥}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=sk] {Nastavenia boli zmenenÃ©. Neklikajte na tlaÄidlo spÃ€Å¥ vo vaÅ¡om prehliadaÄi - vaÅ¡e nastavenia by boli zmazanÃ©. Kliknite radÅ¡ej na jedno z tlaÄidiel hore.}  
+_textsetprefs_ [l=sk] {uloÅŸ nastavenia}  
+_textsearchprefs_ [l=sk] {Nastavenia vyhÄŸadÃ¡vania}  
+_textcollectionprefs_ [l=sk] {Nastavenia zbierok}  
+_textpresentationprefs_ [l=sk] {Nastavenie prezentÃ¡cie}  
+_textpreferences_ [l=sk] {Nastavenia}  
+_textcasediffs_ [l=sk] {MalÃ©, alebo veÄŸkÃ© pÃ­smenÃ¡:}  
+_textignorecase_ [l=sk] {ignoruj veÄŸkosÅ¥ znakov}  
+_textmatchcase_ [l=sk] {malÃ©/veÄŸkÃ© pÃ­smenÃ¡ sa musia zhodovaÅ¥}  
+_textwordends_ [l=sk] {Koncovky slov:}  
+_textstem_ [l=sk] {ignoruj koncovky slov}  
+_textnostem_ [l=sk] {zhodovaÅ¥ sa musÃ­ celÃ© slovo}  
+_textaccentdiffs_ [l=sk] {RozdielnosÅ¥:}  
+_textignoreaccents_ [l=sk] {ignorovaÅ¥ dÄºÅŸne}  
+_textmatchaccents_ [l=sk] {dÄºÅŸne sa musia zhodovaÅ¥}  
+
+_textprefop_ [l=sk] {VyhÄŸadaj _maxdocoption_ zÃ¡znamov s _hitsperpageoption_ na jednej strane.}  
+_textextlink_ [l=sk] {PrÃ­stup k webovÃœm strÃ¡nkam mimo kniÅŸnice:}  
+_textintlink_ [l=sk] {ZdrojovÃ© dokumenty zÃ­skanÃ© z:}  
+_textlanguage_ [l=sk] {Jazyk rozhrania:}  
+_textencoding_ [l=sk] {KÃ³dovanie:}  
+_textformat_ [l=sk] {FormÃ¡t rozhrania:}  
+_textall_ [l=sk] {vÅ¡etko}  
+_textquerymode_ [l=sk] {MÃ³d dotazu:}  
+_textsimplemode_ [l=sk] {jednoduchÃ© vyhÄŸadÃ¡vanie}  
+_textadvancedmode_ [l=sk] {rozÅ¡Ã­renÃ© vyhÄŸadÃ¡vanie (umoÅŸÅuje pouÅŸiÅ¥ zÃ¡tvorky s !, &, |)}  
+_textlinkinterm_ [l=sk] {cez vloÅŸenÃº strÃ¡nku}  
+_textlinkdirect_ [l=sk] {choÄ tam priamo }  
+_textdigitlib_ [l=sk] {digitÃ¡lna kniÅŸnica}  
+_textweb_ [l=sk] {web}  
+_textgraphical_ [l=sk] {GrafickÃ©}  
+_texttextual_ [l=sk] {textovÃœ}  
+_textcollectionoption_ [l=sk] {<p>
+ Podzbierka na zahrnutie:
+ <br>}  
+
+_textsearchtype_ [l=sk] {Okno vyhÄŸadÃ¡vania:}  
+_textformsearchtype_ [l=sk] {formÃ¡tovaÅ¥ podÄŸa _formnumfieldoption_ polÃ­}  
+_textplainsearchtype_ [l=sk] {_boxsizeoption_}  
+_textregularbox_ [l=sk] {normÃ¡lna veÄŸkosÅ¥}  
+_textlargebox_ [l=sk] {veÄŸkÃ©}  
+
+_textrelateddocdisplay_ [l=sk] {zobraz prÃ­buznÃ© dokumenty}  
+_textsearchhistory_ [l=sk] {HistÃ³ria vyhÄŸadÃ¡vania:}  
+_textnohistory_ [l=sk] {Åœiadna histÃ³ria vyhÄŸadÃ¡vanÃœch termÃ­nov}  
+_texthistorydisplay_ [l=sk] {zobraz poslednÃœch _historynumrecords_ vyhÄŸadanÃœch termÃ­nov}  
+_textnohistorydisplay_ [l=sk] {nezobrazuj histÃ³riu vyhÄŸadÃ¡vanÃœch termÃ­nov}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=sk] {ZoraÄ dokumenty podÄŸa}  
+_textalsoshowing_ [l=sk] {taktieÅŸ ukazujÃºce}  
+_textwith_ [l=sk] {nanajvÃœÅ¡ s}  
+_textdocsperpage_ [l=sk] {poÄet dokumentov na strÃ¡nke}  
+
+_textfilterby_ [l=sk] {Iba dokumenty obsahujÃºce}  
+_textall_ [l=sk] {vÅ¡etky}  
+_textany_ [l=sk] {akÃœkoÄŸvek}  
+_textwords_ [l=sk] {slov}  
+_textleaveblank_ [l=sk] {nechajte toto pole prÃ¡zdne, aby ste zÃ­skali vÅ¡etky dokumenty}  
+
+_browsebuttontext_ [l=sk] {"ZoradiÅ¥ dokumenty"}  
+
+_nodata_ [l=sk] {<i>ÅŸiadne dÃ¡ta</i>}  
+_docs_ [l=sk] {dokumenty}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=sk] {Pomoc}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=sk] {prezeranÃ­m dokumentov podÄŸa _1_, kliknutÃ­m na tlaÄidlo _2_}  
+
+_textSearchhelp_ [l=sk] {hÄŸadanÃ­m konkrÃ©tnych slov, ktorÃ© sa vyskytujÃº v texte, kliknutÃ­m na tlaÄidlo _labelSearch_ }  
+_textTohelp_ [l=sk] {Prezerajte dokumenty podÄŸa poÄŸa kliknutÃ­m na tlaÄidlo _labelTo_}  
+_textFromhelp_ [l=sk] {prezeraÅ¥ publikÃ¡cie podÄŸa _labelFrom_}  
+_textBrowsehelp_ [l=sk] {prezeraÅ¥ dokumenty}  
+_textAcronymhelp_ [l=sk] {ZobraziÅ¥ dokumenty podÄŸa vÃœskytu skratky _labelAcronym_}  
+_textPhrasehelp_ [l=sk] {Prezerajte frÃ¡zy vyskytujÃºce sa v dokumentoch, kliknutÃ­m na tlaÄidlo _labelPhrase_.}  
+
+_texthelptopicstitle_ [l=sk] {TÃ©my}  
+
+_textreadingdocs_ [l=sk] {Ako ÄÃ­taÅ¥ dokumenty}  
+
+_texthelpreadingdocs_ [l=sk] {<p>KeÄ sa vÃ¡m v hornej Äasti strÃ¡nky zobrazÃ­ nÃ¡zov dokumentu, fotografie, alebo obal knihy, spoznÃ¡te, Äi ste sa dostali ku konkrÃ©tnemu dokumentu, alebo knihe. V niektorÃœch zbierkach je zobrazenÃœ taktieÅŸ obsah, inÃ© mÃŽÅŸu obsahovaÅ¥ len ÄÃ­slo aktuÃ¡lnej strany spolu s textovÃœm poÄŸom pre vÃœber strÃ¡nky pre prechod na predchÃ¡dzajÃºcu/nasledujÃºcu strÃ¡nku. V obsahu je aktuÃ¡lne zobrazenÃ¡ strÃ¡nka zvÃœraznenÃ¡ tuÄne a obsah je moÅŸnÃ© Äalej otvoriÅ¥. </p><p>Pod obsahom (prÃ­padne navigÃ¡ciou medzi strÃ¡nkami) sa nachÃ¡dza text vybranej sekcie. HneÄ ako si ho preÄÃ­tate, budete mÃŽcÅ¥ pomocou Å¡Ã­pky v dolnej Äasti strÃ¡nky prejsÅ¥ na ÄalÅ¡iu sekciu, alebo sa vrÃ¡tiÅ¥ spÃ€Å¥ k predchÃ¡dzajÃºcej. </p><p>Pod nÃ¡zvom alebo obalom sa nachÃ¡dza niekoÄŸko tlaÄidiel. KliknutÃ­m na <i>rozvinÃºÅ¥ text</i> sa v okne zobrazÃ­ celÃœ text aktuÃ¡lnej sekcie, alebo knihy. PokiaÄŸ je dokument veÄŸkÃœ, mÃŽÅŸe to zabraÅ¥ veÄŸkÃº ÄasÅ¥ operaÄnej pamÃ€ti! KliknutÃ­m na <i>rozvinÃºÅ¥ obsah</i> sa zobrazia vÅ¡etky Ãºrovne obsahu dokumentu, takÅŸe sÃº vidieÅ¥ nÃ¡zvy vÅ¡etkÃœch kapitol a sekciÃ­. KliknutÃ­m na <i>zobraziÅ¥ v novom okne</i> sa prehliadanÃœ dokument otvorÃ­ v novom okne prehliadaÄa. SlovÃ¡, ktorÃ© ste hÄŸadali sÃº zvÃœraznenÃ©. KliknutÃ­m na <i>bez zvÃœraznenia</i> je moÅŸnÃ© zvÃœrazÅovanie zruÅ¡iÅ¥.</p>}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=sk] {Otvor tÃºto policu}  
+_texthelpopenbook_ [l=sk] {Otvor/zavri knihu}  
+_texthelpviewtextsection_ [l=sk] {Zobraz tÃºto ÄasÅ¥ textu}  
+_texthelpexpandtext_ [l=sk] {Zobraz plnÃœ text, alebo nie}  
+_texthelpexpandcontents_ [l=sk] {RozbaÄŸ obsah, alebo nie}  
+_texthelpdetachpage_ [l=sk] {Otvor tÃºto strÃ¡nku v novom okne}  
+_texthelphighlight_ [l=sk] {ZvÃœrazni hÄŸadanÃ© termÃ­ny, alebo nie}  
+_texthelpsectionarrows_ [l=sk] {ChoÄ do predchÃ¡dzajÃºcej/dalÅ¡ej Äasti}  
+
+
+_texthelpsearchingtitle_ [l=sk] {Ako hÄŸadaÅ¥ konkrÃ©tne slovÃ¡}  
+
+_texthelpsearching_ [l=sk] {<p>VyhÄŸadÃ¡vanie sa realizuje na strÃ¡nke "hÄŸadaj" vykonanÃ­m nasledujÃºcich krokov:<p><ol><li>UrÄite akÃ© vÃœrazy chcete vyhÄŸadÃ¡vaÅ¥<li>Rozhodnite sa Äi chcete vyhÄŸadÃ¡vaÅ¥ vÅ¡etky, alebo len niektorÃ© slovÃ¡ vÃœrazu<li>Zadajte slovÃ¡ do pola pre vyhÄŸadÃ¡vanie<li>Kliknite na tlaÄidlo <i>HÄŸadaÅ¥</i></ol><p>Po odoslanÃ­ dotazu sa vÃ¡m na obrazovke zobrazÃ­ prvÃœch dvadsaÅ¥ dokumentov, spÄºÅajÃºcich vaÅ¡u poÅŸiadavku. Na konci zoznamu je tlaÄidlo, ktorÃ© zobrazÃ­ ÄalÅ¡Ã­ch dvadsaÅ¥ zÃ¡znamov. OdtiaÄŸ je moÅŸnÃ© prekliknÃºÅ¥ sa na tretiu dvadsiatku, alebo sa vrÃ¡tiÅ¥ na prvÃº. Kliknutie na nÃ¡zov dokumentu, alebo na malÃ© tlaÄidlo vedÄŸa dokumentu, dokument zobrazÃ­.<p>Å tandardne sa zobrazuje prvÃœch 100 vÃœsledkov, tento limit sa dÃ¡ zmeniÅ¥ na strÃ¡nke <i>_Global:linktextPREFERENCES_</i><p>}  
+
+_texthelpquerytermstitle_ [l=sk] {VyhÄŸadÃ¡vacie termÃ­ny}  
+_texthelpqueryterms_ [l=sk] {<p>VÅ¡etko Äo napÃ­Å¡ete do pola na vyhÄŸadÃ¡vanie sa povaÅŸuje systÃ©m za "vyhÄŸadÃ¡vacie termÃ­ny", ktorÃ© sa mÃŽÅŸu skladaÅ¥ z ÄÃ­siel, alebo znakov abecedy. VyhÄŸadÃ¡vanie termÃ­nov spojenÃœch pomlÄkami systÃ©m povaÅŸuje za dve rozdielne slovÃ¡. VyhÄŸadÃ¡vanie podÄŸa slov, ktorÃ© obsahujÃº pomÄºÄku nie je moÅŸnÃ©. <p>NaprÃ­klad: dotaz <p> <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+       <p>bude vyhodnotenÃœ rovnako ako<p>
+       <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>}  
+
+_texthelpmgppsearching_ [l=sk] {Kolekcie vytvorenÃ© s MGPP ponÃºkajÃº viacero funkciÃ­.<ul> <li>A <b>*</b> NaprÃ­klad: <b>poÄÃ­t*</b> zahrnie vÅ¡etky slovÃ¡ zaÄÃ­najÃºce sa <b>poÄÃ­t</b>.<li><b>/x</b>mÃŽÅŸe byÅ¥ pouÅŸitÃ© na dodanie vÃ€ÄÅ¡ej vÃ¡hy dokumentu jednÃ©mu, alebo viacerÃœm vyhÄŸadÃ¡vanÃœm termÃ­nom. NaprÃ­klad: <b>informaÄnÃ¡/10 veda</b> priraÄuje termÃ­nu informaÄnÃ¡ 10x vÃ€ÄÅ¡iu vÃ¡hu ako slovu veda.</ul>}  
+
+_texthelplucenesearching_ [l=sk] {Kolekcie vytvorenÃ© s Lucene ponÃºkajÃº viac funkciÃ­. <ul> <li><b>?</b> mÃŽÅŸe byÅ¥ vyuÅŸitÃ© ako nÃ¡hradnÃ© znaky pri vyhÄŸadÃ¡vanÃ­. NaprÃ­klad: <b>b??</b> zahrnie slovÃ¡ <b>byt</b>, <b>bit</b>, <b>bod</b> a podobne. <li><b>*</b>mÃŽÅŸe byÅ¥ vyuÅŸitÃ© ako nÃ¡hradnÃ© znaky pri vyhÄŸadÃ¡vanÃ­. NaprÃ­klad: <b>poÄÃ­t*</b> zahrnie vÅ¡etky slovÃ¡ zaÄÃ­najÃºce sa <b>poÄÃ­t</b>. </ul> Oba nÃ¡hradnÃ© znaky je moÅŸnÃ© pouÅŸÃ­vaÅ¥ aj v strede slov.}  
+
+_texthelpquerytypetitle_ [l=sk] {Typ dotazu}  
+_texthelpquerytype_ [l=sk] {<p>ExistujÃº dva rÃŽzne druhy dotazov. <ul><li>Dotazy na <b>vÅ¡etky</b> slovÃ¡. Pri ich spracovanÃ­ sÃº vyhÄŸadanÃ© vÅ¡etky dokumenty (kapitoly, tituly) obsahujÃºce tieto slovÃ¡. Dokumenty spÄºÅajÃºce kritÃ©ria sÃº zoradenÃ© v poradÃ­ v akom boli pridanÃ© do systÃ©mu digitÃ¡lnej kniÅŸnice.<p> <li>Dotazy na <b>niektorÃ©</b> slovÃ¡. ZadÃ¡te slovÃ¡ pri ktorÃœch je pravdepodobnÃ©, ÅŸe sa nachÃ¡dzajÃº v dokumentoch, ktorÃ© hÄŸadÃ¡te. Dokumenty sÃº zoradenÃ© v poradÃ­, ktorÃ© zodpovedÃ¡ tomu, do akej miery zodpovedajÃº dotazu.<p><ul><li>ÄÃ­m viac hÄŸadanÃœch termÃ­nov dokument obsahuje, tÃœm viac zodpovedÃ¡ dotazu;<li>zriedkavÃ© slovÃ¡ sÃº dÃŽleÅŸitejÅ¡ie ako slovÃ¡ s ÄastÃœm vÃœskytom;<li>krÃ¡tke dokumenty sa zhodujÃº lepÅ¡ie ako dlhÃ©.</ul></ul><p>PouÅŸite toÄŸko vyhÄŸadÃ¡vacÃ­ch vÃœrazov, koÄŸko uznÃ¡te za vhodnÃ© - celÃº vetu, alebo aj odstavec. PokiaÄŸ zadÃ¡te ako dotaz len jedno slovo, budÃº dokumenty zoradenÃ© podÄŸa frekvencie jeho vÃœskytu.<p>}  
+
+_texthelpadvancedsearchtitle_ [l=sk] {rozÅ¡Ã­renÃ© vyhÄŸadÃ¡vanie}  
+
+_texthelpadvancedsearch_ [l=sk] {<p>ZvolenÃ­m rozÅ¡Ã­renÃ©ho vyhÄŸadÃ¡vania (v nastaveniach) budete maÅ¥ viac moÅŸnostÃ­ ako vyhÄŸadÃ¡vaÅ¥. _selectadvancedsearch_}  
+
+_texthelpadvsearchmg_ [l=sk] {RozÅ¡Ã­renÃ© vyhÄŸadÃ¡vanie v MG zbierkach vÃ¡m ponÃºka dve moÅŸnosti vyhÄŸadÃ¡vania: podÄŸa relevancie a boolove vyhÄŸadÃ¡vanie. <b>RelevanÄnÃ©</b> vyhÄŸadÃ¡vanie je rovnakÃ© ako vyhÄŸadÃ¡vanie popÃ­sanÃ© v <a href="\#query-type">_texthelpquerytypetitle_</a>. <p>_texthelpbooleansearch_}  
+
+_texthelpbooleansearch_ [l=sk] {VyhÄŸadÃ¡vanie s pouÅŸitÃ­m<b>boolovÃœch</b> operÃ¡torov, vÃ¡m umoÅŸÅuje spresniÅ¥ vÃ¡Å¡ prieskum. K zÃ¡kladnÃœm operÃ¡torom patria & ( "and" ),  | ("or") a ! ("not"). NaprÃ­klad, dotaz <b>slimÃ¡k & roÄŸnÃ­ctvo</b> zahrnie do vÃœsledkov vyhÄŸadÃ¡vania dokumenty, ktorÃ© obsahujÃº slovÃ¡ <b>slimÃ¡k</b> A <b>roÄŸnÃ­ctvo</b>, priÄom dotaz <b>slimÃ¡k | roÄŸnÃ­ctvo</b> zahrnie do vÃœsledkov vyhÄŸadÃ¡vania dokumenty v ktorÃœch sa nachÃ¡dza buÄ <b>slimÃ¡k</b> ALEBO <b>roÄŸnÃ­ctvo</b>. <b>SlimÃ¡k ! roÄŸnÃ­ctvo</b> vyhÄŸadÃ¡ dokumenty, ktorÃ© obsahujÃº <b>slimÃ¡k</b> ALE NEOBSAHUJÃ <b>roÄŸnÃ­ctvo</b>.  <p> NajpresnejÅ¡ie vÃœsledky vyhÄŸadÃ¡vania je moÅŸnÃ© dosiahnuÅ¥ kombinÃ¡ciou viacerÃœch operÃ¡torov a zÃ¡tvoriek. NaprÃ­klad:  <b>(slimÃ¡k | roÄŸnÃ­ctvo)</b> & <b>(traktor | postrek)</b>, alebo <b>krava | koza | prasa !kÃŽÅ</b>.}  
+
+_texthelpadvsearchmgpp_ [l=sk] {RozÅ¡Ã­renÃ© vyhÄŸadÃ¡vanie v MGPP zbierkach funguje na princÃ­pe boolovÃœch operÃ¡torov. _texthelpbooleansearch_ <p> VÃœsledky je moÅŸnÃ© zobraziÅ¥ podÄŸa <b>relevancie</b>, podobne ako v prÃ­pade <a href="\#query-type">_texthelpquerytypetitle_</a>, alebo v poradÃ­ v akom boli vytvorenÃ© a zaradenÃ© do zbierky systÃ©mu digitÃ¡lnej kniÅŸnice.  <p> ÄalÅ¡ie operÃ¡tory zahÅÅajÃº <b>NEARx</b> a <b>WITHINx</b>. NEARx sa pouÅŸÃ­va na urÄenie maximÃ¡lnej vzdialenosti medzi (x slovami). WITHINx urÄuje, ÅŸe druhÃœ termÃ­n sa musÃ­ vyskytnÃºÅ¥ do x slov <i>po prvom termÃ­ne</i>. Funkcia je podobnÃ¡ operÃ¡toru NEAR s rozdielom, ÅŸe predvolenÃ¡ vzdialenosÅ¥ slov je 20. }  
+
+_texthelpadvancedsearchextra_ [l=sk] {POZNÃMKA: Ak pouÅŸÃ­vate jednoduchÃ© vyhÄŸadÃ¡vanie, budÃº tieto operÃ¡tory ignorovanÃ©.}  
+
+_texthelpadvsearchlucene_ [l=sk] {RozÅ¡Ã­renÃ© vyhÄŸadÃ¡vania v kolekciÃ¡ch Lucene vyuÅŸÃ­vajÃº boolove operÃ¡tory. _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=sk] {VyhÄŸadÃ¡vanie vo formulÃ¡ri}  
+
+_texthelpformsearch_ [l=sk] {<p>VyhÄŸadÃ¡vanie vo formulÃ¡roch umoÅŸÅuje kombinovaÅ¥ termÃ­ny z viacerÃœch polÃ­. NaprÃ­klad vyhÄŸadanie termÃ­nu "Smith" v tituloch AND "snail farming" v predmetoch. KaÅŸdÃœ riadok formulÃ¡ra sa sprÃ¡va rovnako ako tradiÄnÃ© vyhÄŸadÃ¡vanie: boolove operÃ¡tory sÃº povolenÃ© len pri rozÅ¡Ã­renom vyhÄŸadÃ¡vanÃ­ a hÄŸadanÃ© frÃ¡zy musia byÅ¥ v ÃºvodzovkÃ¡ch. Pri rozÅ¡Ã­renom vyhÄŸadÃ¡vanÃ­ je moÅŸnÃ© vyuÅŸiÅ¥ medzi jednotlivÃœmi poliami operÃ¡tori AND/OR/NOT, tieto operÃ¡tory je tieÅŸ moÅŸnÃ© pouÅŸÃ­vaÅ¥ v jednotlivÃœch poliach.}  
+
+_texthelpformstemming_ [l=sk] {OknÃ¡ "fold" a "stem" umoÅŸÅujÃº modifikovaÅ¥ vyhÄŸadÃ¡vanie s vyuÅŸitÃ­m technolÃ³gie stemming a casefolded. Obe funkcie sÃº pri rozÅ¡Ã­renom vyhÄŸadÃ¡vanÃ­ Å¡tandardne vypnutÃ©.}  
+
+_textdatesearch_ [l=sk] {VyhÄŸadÃ¡vaÅ¥ v dÃ¡tumoch}  
+
+_texthelpdatesearch_ [l=sk] {VyhÄŸadÃ¡vanie podÄŸa dÃ¡tumu nÃ¡jde dokumenty, ktorÃ© spÄºÅajÃº hÄŸadanÃ© kritÃ©ria a spadajÃº do urÄitÃ©ho ÄasovÃ©ho obdobia. VyhÄŸadÃ¡vaÅ¥ mÃŽÅŸete dokumenty podÄŸa urÄitÃ©ho roku, alebo v rozsahu rokov. Pri vyhÄŸadÃ¡vanÃ­ podÄŸa roku nemusÃ­te, okrem roku, zadÃ¡vaÅ¥ ÅŸiadne dodatoÄnÃ© termÃ­ny vyhÄŸadÃ¡vania. Ak pri vyhÄŸadÃ¡vanÃ­ nezadÃ¡te ÅŸiadny dÃ¡tum, systÃ©m sa sprÃ¡va ako keby vyhÄŸadÃ¡vanie podÄŸa dÃ¡tumu neexistovalo.<p>}  
+
+_texthelpdatehowtotitle_ [l=sk] {Ako pouÅŸÃ­vaÅ¥ tÃºto funkciu:}  
+_texthelpdatehowto_ [l=sk] {<ul> <li>Ak hÄŸadÃ¡te dokumenty vzÅ¥ahujÃºce sa k presnÃ©mu roku:<p><ul> <li>ZaÄnite svoje vyhÄŸadÃ¡vanie napÃ­sanÃ­m dotazu.<li>Zadajte rok do okienka pre dÃ¡tum.<li>Ak dÃ¡tum nie je v naÅ¡om letopoÄte, vyberte si z rolovacieho menu moÅŸnosÅ¥ "B.C.E".<li>A zaÄnite vyhÄŸadÃ¡vaÅ¥.</ul><p><li>Ak chcete vyhÄŸadÃ¡vaÅ¥ v dokumentoch vzÅ¥ahujÃºcich sa na urÄitÃ© ÄasovÃ© obdobia:<p><ul><li>ZaÄnite vyhÄŸadÃ¡vanie napÃ­sanÃ­m dotazu.<li>Zadajte skorÅ¡Ã­ a neskorÅ¡Ã­ rok do okienka pre dÃ¡tum.<li>Ak dÃ¡tum nie je v naÅ¡om letopoÄte, vyberte si z rolovacieho menu moÅŸnosÅ¥ "B.C.E".<li>A zaÄnite vyhÄŸadÃ¡vaÅ¥.</ul></ul><p>}  
+
+_texthelpdateresultstitle_ [l=sk] {SpÃŽsob akÃœm sÃº vÃœsledky zobrazenÃ©}  
+_texthelpdateresults_ [l=sk] {HÄŸadanie dokumentov o roku 1903, nezahÅÅa dokumenty napÃ­sanÃ© v roku 1903, ale len dokumenty o roku 1903. Pri spÃŽsobe vyhÄŸadÃ¡vania podÄŸa dÃ¡tumu, systÃ©m zobrazÃ­ dokumenty, ktorÃ© sa nachÃ¡dzajÃº v danom intervale (naprÃ­klad 1899-1911) do ktorÃ©ho spadÃ¡ aj dÃ¡tum 1903. Rovnako budÃº zobrazenÃ© aj nÃ¡zvy dokumentov, ktorÃœch textovÃœ reÅ¥azec obsahuje storoÄie do ktorÃ©ho rok 1903 spadÃ¡ (naprÃ­klad "20-te storoÄie"). To znamenÃ¡, ÅŸe niektorÃ© dÃ¡tumy sa vo vyhÄŸadanÃœch textoch nemusia nachÃ¡dzaÅ¥. Pri hÄŸadanÃ­ v urÄitom Äasovom obdobÃ­ sa vÅ¡etko uvedenÃ© vyÅ¡Å¡ie, vzÅ¥ahuje na danÃœ rok kaÅŸdÃ©ho ÄasovÃ©ho obdobia. <p>}  
+
+_textchangeprefs_ [l=sk] {ZmeniÅ¥ nastavania}  
+
+_texthelppreferences_ [l=sk] {<p>Ak kliknete na tlaÄidlo <i>_Global:linktextPREFERENCES_</i>  hore na strÃ¡nke, budete mÃŽcÅ¥ zmeniÅ¥ nastavenia, tak aby viac vyhovovali vaÅ¡ej prÃ¡ci.}  
+
+_texthelpcollectionprefstitle_ [l=sk] {Nastavenia zbierok}  
+_texthelpcollectionprefs_ [l=sk] {NiektorÃ© zbierky zahÅÅajÃº viacero podkolekciÃ­, ktorÃ© je moÅŸnÃ© prehÄŸadÃ¡vaÅ¥ jednotlivo alebo naraz. PoÄet zbierok, ktorÃ© chcete prehÄŸadÃ¡vaÅ¥ si mÃŽÅŸete urÄiÅ¥ na strÃ¡nke s nastaveniami.}  
+
+_texthelplanguageprefstitle_ [l=sk] {JazykovÃ© nastavenia}  
+_texthelplanguageprefs_ [l=sk] {<p>KaÅŸdÃ¡ zbierka je v predvolenom jazyku, ktorÃœ je moÅŸnÃ© zmeniÅ¥ v nastaveniach. ZmeniÅ¥ mÃŽÅŸete aj schÃ©mu kÃ³dovania pre zobrazenie vÃœstupu v prehliadaÄi. SoftvÃ©r vyberie vÅŸdy optimÃ¡lnu hodnotu, ale pri niektorÃœch prehliadaÄoch je lepÅ¡ie zvoliÅ¥ kÃ³dovaciu tÃ©mu manuÃ¡lne. Pri vÅ¡etkÃœch zbierkach je moÅŸnÃ© zmeniÅ¥ grafickÃ© rozhranie na textovÃ©, ktorÃ© je vhodnÃ© najmÃ€ pre zrakovo znevÃœhodnenÃœch pouÅŸÃ­vateÄŸov.}  
+
+_texthelppresentationprefstitle_ [l=sk] {Nastavenia prezentÃ¡cie}  
+_texthelppresentationprefs_ [l=sk] {V zÃ¡vislosti od konkrÃ©tnej kolekcie, si mÃŽÅŸete nastaviÅ¥ viac moÅŸnostÃ­, ktorÃ© ovplyvnia spÃŽsob jej prezentÃ¡cie. <p>Kolekcie webovÃœch strÃ¡nok vÃ¡m umoÅŸÅujÃº zruÅ¡iÅ¥ navigaÄnÃœ panel na vrchu kaÅŸdej strÃ¡nky, takÅŸe po vyhÄŸadanÃ­ dokumentu sa dostanete na strÃ¡nku ktorÃ¡ uÅŸ hlaviÄku Greenstone obsahovaÅ¥ nebude. Pre ÄalÅ¡ie vyhÄŸadÃ¡vanie budete musieÅ¥ vo vaÅ¡om prehliadaÄi kliknÃºÅ¥ na tlaÄidlo "spÃ€Å¥". Pri kolekciÃ¡ch obsahujÃºcich webovÃ© dokumenty, smerujÃº Äasto ich linky na webovÃ© strÃ¡nky mimo kniÅŸnice, v takom prÃ­pade vÃ¡s systÃ©m Greenstone upozornÃ­, ÅŸe odchÃ¡dzate na strÃ¡nky nachÃ¡dzajÃºce sa mimo digitÃ¡lnej kniÅŸnice.  Toto upozornenie je moÅŸnÃ© vypnÃºÅ¥ na nastaveniach zbierky.  V niektorÃœch zbierkach, mÃŽÅŸete kontrolovaÅ¥ Äi linky na strÃ¡nke s vyhÄŸadanÃœmi dokumentmi smerujÃº priamo na URL na web, alebo do kÃ³pie v digitÃ¡lnej kniÅŸnici. }  
+
+_texthelpsearchprefstitle_ [l=sk] {Nastavenia vyhÄŸadÃ¡vania}  
+_texthelpsearchprefs_ [l=sk] {<p>Pri tvorbe dotazov si mÃŽÅŸete vybraÅ¥ medzi jednoduchÃœm a rozÅ¡Ã­renÃœm vyhÄŸadÃ¡vanÃ­m. RozÅ¡Ã­renÃ© vyhÄŸadÃ¡vanie VÃ¡m umoÅŸÅuje kombinovaÅ¥ operÃ¡tori & (pre "A"), | (pre "ALEBO"), and ! (pre "NIEâ).
+<p>_selectsearchtypeprefs_
+<p>_selectwordmodificationprefs_
+<p>HistÃ³ria vyhÄŸadÃ¡vanÃœch termÃ­nov zobrazuje vaÅ¡e poslednÃ© dotazy, to vÃ¡m umoÅŸÅuje lepÅ¡iu modifikÃ¡ciu dotazov.
+<p>NezabÃºdajte, ÅŸe aj poÄet hitov zobrazenÃœch na jednej webovej strÃ¡nke mÃŽÅŸete regulovaÅ¥.}  
+
+_textcasefoldprefs_ [l=sk] {Pri vyhÄŸadÃ¡vanÃ­ v texte je moÅŸnÃ© zapnÃºÅ¥, alebo vypnÃºÅ¥ zhodu veÄŸkÃœch/malÃœch pÃ­smen. NaprÃ­klad, po zapnutÃ­ "_preferences:textignorecase_", <i>snail farming</i> bude systÃ©m chÃ¡paÅ¥ rovnako ako <i>Snail Farming</i> a <i>SNAIL FARMING</i>.}  
+_textstemprefs_ [l=sk] {TlaÄidlami je moÅŸnÃ© zapnÃºÅ¥, alebo vypnÃºÅ¥ ignorovanie koncoviek slov. NaprÃ­klad, ak je zapnutÃ© "_preferences:textstem_", <i>snail farming</i> bude systÃ©m chÃ¡paÅ¥ rovnako ako <i>snails farm</i> a <i>snail farmer</i>. TÃ¡to funkcia funguje spoÄŸahlivo len pri textoch v anglickom jazyku. _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=sk] {Dve tlaÄidlÃ¡ urÄujÃº Äi sa mÃ¡ pri vyhÄŸadÃ¡vanÃ­ prihliadaÅ¥ na diakritiku termÃ­nov. NaprÃ­klad ak je zapnutÃ© "_preferences:textignoreaccents_", <i>fÃ©dÃ©ration</i> bude systÃ©m chÃ¡paÅ¥ rovnako ako <i>fedÃ©ration</i> a <i>federation</i>.}  
+ 
+_textstemoptionsprefs_ [l=sk] {Bude lepÅ¡ie ak pouÅŸijete kratÅ¡Ã­ vyhÄŸadÃ¡vacÃ­ termÃ­n (opÃ­sanÃœ vyÅ¡Å¡ie) v "_texthelpquerytermstitle_".}  
+
+_textsearchtypeprefsplain_ [l=sk] {Pri vyhÄŸadÃ¡vanÃ­ odsekov je moÅŸnÃ© okno vyhÄŸadÃ¡vania zvÃ€ÄÅ¡iÅ¥. }  
+
+_textsearchtypeprefsform_ [l=sk] {PoÄet zobrazenÃœch polÃ­ vo formulÃ¡ri mÃŽÅŸete meniÅ¥.}  
+
+_textsearchtypeprefsboth_ [l=sk] {Pri vyhÄŸadÃ¡vanÃ­ si mÃŽÅŸete vybraÅ¥ medzi ânormÃ¡lnymâ a âformulÃ¡rovÃœmâ oknom.
+<ul>
+<li>V normÃ¡lnom okne vyhÄŸadÃ¡vate v jednom poli. _textsearchtypeprefsplain_</li>
+<li>VyhÄŸadÃ¡vanie vo formulÃ¡rovÃœch oknÃ¡ch umoÅŸÅuje vyhÄŸadÃ¡vaÅ¥ vo viacerÃœch poliach. _textsearchtypeprefsform_ </li>
+</ul>
+}  
+
+
+
+_texttanumbrowseoptions_ [l=sk] {V zbierke je (sÃº) _numbrowseoptions_ spÃŽsoby (-bov) ako hÄŸadaÅ¥ informÃ¡cie:}  
+
+_textsimplehelpheading_ [l=sk] {Ako nÃ¡jsÅ¥ informÃ¡cie v zbierke _collectionname_ }  
+
+_texthelpscopetitle_ [l=sk] {Rozsah dotazov}  
+_texthelpscope_ [l=sk] {<p>Vo vÃ€ÄÅ¡ine kolekciÃ­ si mÃŽÅŸete vybraÅ¥ prehÄŸadÃ¡vanie rozliÄnÃœch indexov. NaprÃ­klad indexy autorov, titulov, jednotlivÃœch kapitol, alebo odstavcov. VÃœsledkom sÃº vÅŸdy dokumenty, ktorÃ© zodpovedajÃº dotazu - to platÃ­ nezÃ¡visle od prehÄŸadanÃ©ho indexu.<p>Ak sÃº dokumenty knihami, budÃº otvorenÃ© na sprÃ¡vnom mieste. KliknutÃ­m na prieÄinok je moÅŸnÃ© otvoriÅ¥ a zavrieÅ¥ dokument.}  
Index: /gsdl/stable/macros/slovak2.dm
===================================================================
--- /gsdl/stable/macros/slovak2.dm	(revision 20131)
+++ /gsdl/stable/macros/slovak2.dm	(revision 20131)
@@ -0,0 +1,753 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Language text and icon macros 
+# -- this file contains text that is of less importance
+######################################################################
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=sk] {dokumenty.}  
+_lastupdate_ [l=sk] {Naposledy aktualizovanÃ©}  
+_ago_ [l=sk] {dÅami.}  
+_colnotbuilt_ [l=sk] {Zbierka sa nevybudovala.}  
+
+### taken from here
+
+_textpoem_ [l=sk] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+<p>nech Å¥a obklopÃ­ mier a pokoj,
+<br>nech si v teplej letnej hmle 
+<br>nech oceÃ¡n tvojich ciest cestuje tak ÄŸahko ako vyleÅ¡tenÃœ greenstone.
+
+
+}  
+
+_textgreenstone_ [l=sk] {<p>Greenstone je drahokam (podobne ako tento softvÃ©r), pochÃ¡dza z NovÃ©ho ZÃ©landu. V tradiÄnej spoloÄnosti Maurov to bol najviac cenenÃœ predmet, ktorÃœ do seba mohol prijaÅ¥ a udrÅŸaÅ¥ <i>wairua</i>, teda "ducha", alebo "ÅŸivotnÃº silu". Greenstone predstavuje tradiÄnÃ© spoloÄenskÃ© hodnoty, preto je symbolom projektu verejne prÃ­stupnej digitÃ¡lnej kniÅŸnice. Jeho lesk je milostivÃœ, jeho priesvitnosÅ¥ vzneÅ¡enÃ¡; jeho pevnosÅ¥ smelÃ¡ a jeho ostrÃ© hrany spravodlivÃ©. VyrezÃ¡vanÃœ kameÅ, ktorÃœ vidÃ­te v logu Greenstone je, <i>patu</i>, bojovÃ¡ zbraÅ. Je to rodinnÃ© dediÄstvo zakladajÃºcich Älenov Greenstone. V bojoch muÅŸa proti muÅŸovi sÃº argumenty <i>patu</i> veÄŸmi rÃœchle a zdrvujÃºce. VerÃ­me, ÅŸe tieto vlastnosti sa prenÃ¡Å¡ajÃº aj na nÃ¡Å¡ program, ostrosÅ¥ <i>patu</i> symbolizuje rozhranie naÅ¡ej technolÃ³gie.</p>}  
+
+_textaboutgreenstone_ [l=sk] {<p>Greenstone je softvÃ©r na vytvÃ¡ranie a Å¡Ã­renie digitÃ¡lnych zbierok, prinÃ¡Å¡a novÃ© spÃŽsoby zverejÅovania a sprÃ­stupÅovania informÃ¡ciÃ­ prostrednÃ­ctvom internetu a CD-ROM. Greenstone je produkt <b>New Zealand Digital Library Project</b> vytvorenÃœ na <b>Univerzite Waikato</b> a distribuovanÃœ <b>UNESCO</b> s podporou organizÃ¡cie <b>Human Info NGO</b>.  Je to voÄŸne prÃ­stupnÃœ softvÃ©r s otvorenÃœm kÃ³dom, ktorÃœ je dostupnÃœ na <a 
+href="http://greenstone.org">http://greenstone.org</a> pod podmienkami GNU General Public License. </p>
+
+<p>CieÄŸom softvÃ©ru je podporiÅ¥ vytvÃ¡ranie digitÃ¡lnych kniÅŸnÃ­c v kniÅŸniciach, univerzitÃ¡ch a v ostatnÃœch verejnÃœch inÅ¡titÃºciÃ¡ch. VerÃ­me, ÅŸe tento softvÃ©r prispeje k lepÅ¡iemu Å¡Ã­reniu informÃ¡ciÃ­ vo verejnej sfÃ©re.</p>
+
+<p>Tento softvÃ©r chce poskytnÃºÅ¥ pouÅŸÃ­vateÄŸom nÃ¡stroje na vytvorenie vlastnÃœch digitÃ¡lnych zbierok (a to predovÅ¡etkÃœm pouÅŸÃ­vateÄŸom z univerzÃ­t, kniÅŸnÃ­c a ÄalÅ¡Ã­m organizÃ¡ciÃ¡m vo verejnej sprÃ¡ve). V ÄlenskÃœch Å¡tÃ¡toch UNESCO, ale aj v rozvojovÃœch krajinÃ¡ch majÃº digitÃ¡lne kniÅŸnice veÄŸkÃœ vÃœznam pri Å¡Ã­renÃ­ informÃ¡ciÃ­ v oblastiach vedy, kultÃºry a vzdelÃ¡vania. VerÃ­me, ÅŸe tento projekt podporÃ­ efektÃ­vne vyuÅŸitie digitÃ¡lnych kniÅŸnÃ­c a ich Ãºlohu zdieÄŸaÅ¥ a rozÅ¡irovaÅ¥ informÃ¡cie v spoloÄnosti. 
+
+<p>Tento softvÃ©r vznikol na zÃ¡klade medzinÃ¡rodnej spoluprÃ¡ce, ktorÃ¡ zaÄala v auguste 2000 medzi troma organizÃ¡ciami.</p>
+
+<p><a href="http://nzdl.org"><b>New Zealand Digital Library Project na univerzite Waikato</b></a>
+<br>Kde Greenstone vznikol za podpory novozÃ©landskÃ©ho nÃ¡rodnÃ©ho sekretariÃ¡tu pre UNESCO (ako sÃºÄasÅ¥ prÃ­spevku NovÃ©ho ZÃ©landu do UNESCO).</p>
+
+<p>
+<a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+class="logo"></a>
+<a href="http://www.unesco.org"><b>United Nations Educational, Scientific and Cultural Organization</b></a>
+<br>
+CieÄŸom UNESCO je rozÅ¡irovanie informÃ¡ciÃ­ pre vedu, vzdelÃ¡vanie a kultÃºru. HlavnÃœm bodom medzivlÃ¡dneho programu âInformÃ¡cie pre vÅ¡etkÃœchâ je dostupnosÅ¥ tÃœchto informÃ¡ciÃ­ v rozvojovÃœch krajinÃ¡ch. 
+</p> 
+
+<p>
+<a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>The Human Info NGO</b></a><br>
+Tento projekt v spoluprÃ¡ci s agentÃºrami UN a NGO si vÄaka digitalizÃ¡cii a sprÃ­stupÅovaniu digitÃ¡lnych dokumentov v krajinÃ¡ch tretieho sveta zÃ­skal svetovÃ© uznanie.}  
+
+
+_textdescrselcol_ [l=sk] {vyber zbierku}  
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=sk] {Na domovskej strÃ¡nke sa nachÃ¡dza niekoÄŸko tlaÄidiel.}  
+
+_textnocollections_ [l=sk] {<p>V sÃºÄasnosti inÅ¡talÃ¡cia Greenstone neobsahuje ÅŸiadne zbierky. Na ich vytvorenie mÃŽÅŸete <ul><li>pouÅŸiÅ¥<a href="_httppagecollector_">ZberateÄŸa</a><li>. Ak mÃ¡te Greenstone CD-ROM, mÃŽÅŸete z neho jednotlivÃ© zbierky nainÅ¡talovaÅ¥.</ul>}  
+
+_text1coll_ [l=sk] {InÅ¡talÃ¡cia Greenstone obsahuje 1 zbierku}  
+
+_textmorecolls_ [l=sk] {InÅ¡talÃ¡cia Greenstone obsahuje _1_ zbierok}  
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=sk] {ExternÃœ odkaz}  
+_textlinknotfound_ [l=sk] {InternÃœ odkaz sa nenaÅ¡iel}  
+
+_textextlinkcontent_ [l=sk] {VyznaÄenÃœ odkaz je externÃœ. Ak ho chcete zobraziÅ¥, mÃŽÅŸete Ã­sÅ¥<a href="_nexturl_">dopredu</a> na tÃºto strÃ¡nku. Pre nÃ¡vrat k predchÃ¡dzajÃºcemu dokumentu pouÅŸite tlaÄidlo "spÃ€Å¥" vo vaÅ¡om prehliadaÄi. }  
+
+_textlinknotfoundcontent_ [l=sk] {InternÃœ odkaz neexistuje. Pravdepodobne nastala chyba v zdrojovej zbierke. Pre nÃ¡vrat k predchÃ¡dzajÃºcemu dokumentu pouÅŸite tlaÄidlo "spÃ€Å¥" vo vaÅ¡om prehliadaÄi. }  
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=sk] {<h3>Odkaz na zbierku "_2_"</h3>
+
+<p>ZvolenÃœ odkaz pre zbierku "_collectionname_" je externÃœ (spÃ¡ja zbierky "_2_"). Ak   
+chcete zobraziÅ¥ tento odkaz v zbierke "_2_" mÃŽÅŸete Ã­sÅ¥ <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">dopredu</a>na tÃºto strÃ¡nku. Pre nÃ¡vrat k predchÃ¡dzajÃºcemu dokumentu pouÅŸite tlaÄidlo "spÃ€Å¥" vo vaÅ¡om prehliadaÄi.}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=sk] {DigitÃ¡lna kniÅŸnica Greenstone}  
+
+_textusername_ [l=sk] {meno}  
+_textpassword_ [l=sk] {heslo}  
+
+_textmustbelongtogroup_ [l=sk] {Pre prÃ­stup k tejto strÃ¡nke musÃ­te patriÅ¥ k uÅŸÃ­vateÄŸskej skupine "_cgiargug_".}  
+
+_textmessageinvalid_ [l=sk] {Pre zobrazenie strÃ¡nky musÃ­te byÅ¥ prihlÃ¡senÃœ.<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>) ProsÃ­m vloÅŸte vaÅ¡e meno a heslo.}  
+
+_textmessagefailed_ [l=sk] {NeznÃ¡my uÅŸÃ­vateÄŸ, alebo neplatnÃ© heslo.}  
+
+_textmessagedisabled_ [l=sk] {PrepÃ¡Äte, ale vÃ¡Å¡ ÃºÄet je zruÅ¡enÃœ. Kontaktujte sprÃ¡vcu strÃ¡nky.}  
+
+_textmessagepermissiondenied_ [l=sk] {PrepÃ¡Äte, ale nemÃ¡te prÃ¡vo vstÃºpiÅ¥ na tieto strÃ¡nky.}  
+
+_textmessagestalekey_ [l=sk] {NeplatnÃ¡ adresa ! ProsÃ­m zadajte svoje heslo pre vstup na tieto strÃ¡nky.}  
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=sk] {<p>InÅ¡talÃ¡cia Greenstone neobsahuje ÅŸiadnu dokumentÃ¡ciu. PravdepodobnÃ© prÃ­Äiny :  <ol><li>Zvolili ste kompaktnÃº inÅ¡talÃ¡ciu Greenstone (CD-ROM).<li>Greenstone bol inÅ¡talovanÃœ z webovej distribÃºcie.</ol> DokumentÃ¡ciu si mÃŽÅŸete pozrieÅ¥ v prieÄinku <i>docs</i> na inÅ¡talaÄnom CD-ROM, alebo na <a
+href="http://www.greenstone.org">http://www.greenstone.org</a>.}  
+
+_textuserguide_ [l=sk] {NÃ¡vod pre pouÅŸÃ­vateÄŸa}  
+_textinstallerguide_ [l=sk] {InÅ¡talÃ¡cia (nÃ¡vod) }  
+_textdeveloperguide_ [l=sk] {VÃœvojÃ¡rov nÃ¡vod}  
+_textpaperguide_ [l=sk] {Od dokumentu k zbierke}  
+_textorganizerguide_ [l=sk] {PouÅŸÃ­vam Organizer}  
+
+_textgsdocstitle_ [l=sk] {dokumentÃ¡cia }  
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=sk] {Vybuduj zbierku}  
+_textbildsuc_ [l=sk] {Zbierka bola ÃºspeÅ¡ne vybudovanÃ¡.}  
+_textviewbildsummary_ [l=sk] {Na strÃ¡nke <a href="_httppagex_(bsummary)" target=_top>si mÃŽÅŸete pozrieÅ¥ sprÃ¡vu o vybudovanÃ­ zbierky</a>.
+}  
+_textview_ [l=sk] {UkÃ¡ÅŸ zbierku}  
+
+_textbild1_ [l=sk] {Zbierka sa buduje, to mÃŽÅŸe trvaÅ¥ nejakÃœ Äas. Proces budovania mÃŽÅŸete sledovaÅ¥ v riadku dole.}  
+
+_textbild2_ [l=sk] {Proces budovania zbierky mÃŽÅŸete preruÅ¡iÅ¥ kliknutÃ­m sem. <br>Zbierka na ktorej pracujete zostane nezmenenÃ¡. }  
+
+_textstopbuild_ [l=sk] {zastaviÅ¥ proces budovania}  
+
+_textbild3_ [l=sk] {Ak opustÃ­te tÃºto strÃ¡nku (a nezruÅ¡Ã­te proces budovania) zbierka bude sa vybuduje sama.}  
+
+_textbuildcancelled_ [l=sk] {Proces budovania bol zruÅ¡enÃœ.}  
+
+_textbildcancel1_ [l=sk] {Proces budovania bol zruÅ¡enÃœ. PouÅŸite ÅŸltÃ© tlaÄidlÃ¡ dolu na vykonanie potrebnÃœch zmien a opÃ€Å¥ spustite proces budovania. }  
+
+_textbsupdate1_ [l=sk] {Priebeh vÃœstavby bude aktualizovanÃœ za 1 sekundu}  
+_textbsupdate2_ [l=sk] {Priebeh vÃœstavby bude aktualizovanÃœ za}  
+_textseconds_ [l=sk] {sekÃºnd}  
+
+_textfailmsg11_ [l=sk] {Zbierku nebolo moÅŸnÃ© vybudovaÅ¥, pretoÅŸe neobsahuje ÅŸiadne dÃ¡ta. Uistite sa, ÅŸe aspoÅ jeden z adresÃ¡rov, alebo sÃºborov z ktorÃœch chcete vybudovaÅ¥ novÃº zbierku obsahuje <i>data</i>, ktorÃ© vie Greenstone spracovaÅ¥.}  
+
+_textfailmsg21_ [l=sk] {Zbierku nebolo moÅŸnÃ© vytvoriÅ¥ (chyba import.pl).}  
+_textfailmsg31_ [l=sk] {Zbierku nebolo moÅŸnÃ© vytvoriÅ¥ (chyba buildcol.pl).}  
+_textfailmsg41_ [l=sk] {Zbierka bola ÃºspeÅ¡ne vybudovanÃ¡, ale nemohla byÅ¥ nainÅ¡talovanÃ¡.}  
+_textfailmsg71_ [l=sk] {PoÄas pokusu vybudovaÅ¥ zbierku nastala neoÄakÃ¡vanÃ¡ chyba.}  
+
+
+_textblcont_ [l=sk] {SprÃ¡va o vybudovanÃ­ obsahuje tieto informÃ¡cie:}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=sk] {prednastavenÃ¡ Å¡truktÃºra}  
+_textmore_ [l=sk] {viac}  
+_textinfo_ [l=sk] {O zbierke}  
+_textsrce_ [l=sk] {ZdrojovÃ© dÃ¡ta}  
+_textconf_ [l=sk] {KonfigurovaÅ¥ zbierku}  
+_textdel_ [l=sk] {VymazaÅ¥ zbierku}  
+_textexpt_ [l=sk] {Export zbierky}  
+
+_textdownloadingfiles_ [l=sk] {SÅ¥ahujem sÃºbory ...}  
+_textimportingcollection_ [l=sk] {Import zbierky ...}  
+_textbuildingcollection_ [l=sk] {Budujem zbierku ...}  
+_textcreatingcollection_ [l=sk] {vytvÃ¡ram zbierku ...}  
+
+_textcollectorblurb_ [l=sk] {<i><br>Pri vytvÃ¡ranÃ­ a Å¡Ã­renÃ­ informÃ¡ciÃ­ prostrednÃ­ctvom zbierok dodrÅŸujte autorskÃœ zÃ¡kon. VÅŸdy si overte, Äi dokument, ku ktorÃ©mu mÃ¡te prÃ­stup mÃŽÅŸete Å¡Ã­riÅ¥ Äalej.<br>Uvedomte si hodnotu a silu informÃ¡ciÃ­, ktorÃ© sa chystÃ¡te zverejniÅ¥, snaÅŸte sa, aby reÅ¡pektovali etickÃ© a morÃ¡lne hodnoty.</i>}  
+
+_textcb1_ [l=sk] {ZberateÄŸ VÃ¡m pomÃŽÅŸe novÃ© zbierky vytvÃ¡raÅ¥, mazaÅ¥, upravovaÅ¥, alebo zluÄovaÅ¥.}  
+
+_textcb2_ [l=sk] {Najprv sa musÃ­te rozhodnÃºÅ¥ Äi}  
+_textcnc_ [l=sk] {vytvoriÅ¥ novÃº zbierku}  
+_textwec_ [l=sk] {pracuj s existujÃºcou, pridaj dÃ¡ta, alebo vymaÅŸ. }  
+
+_textcb3_ [l=sk] {PozmeÅovaÅ¥ a budovaÅ¥ zbierky digitÃ¡lnej kniÅŸnice mÃŽÅŸu len prihlÃ¡senÃ­ pouÅŸÃ­vatelia. TÃœmto spÃŽsobom softvÃ©r digitÃ¡lnej kniÅŸnice chrÃ¡ni VaÅ¡e dÃ¡ta pred neoprÃ¡vnenou manipulÃ¡ciou. PoznÃ¡mka : Z bezpeÄnostnÃœch dÃŽvodov budete zo systÃ©mu automaticky odhlÃ¡senÃœ po tridsiatich minÃºtach, potom VÃ¡s systÃ©m vyzve k opÃ€tovnÃ©mu prihlÃ¡seniu. Po prihlÃ¡senÃ­ mÃŽÅŸete pokraÄovaÅ¥ tam, kde ste prestali.}  
+
+_textcb4_ [l=sk] {VloÅŸte svoje meno a heslo.}  
+
+_textfsc_ [l=sk] {Najprv si vyberte zbierku s ktorou chcete pracovaÅ¥ (V zozname sa nezobrazia zbierky chrÃ¡nenÃ© proti zÃ¡pisu).}  
+
+_textwtc_ [l=sk] {S vami vybratou zbierkou mÃŽÅŸete}  
+_textamd_ [l=sk] {Pridaj ÄalÅ¡ie dÃ¡ta a aktualizuj zbierku}  
+_textetc_ [l=sk] {Uprav konfiguraÄnÃœ sÃºbor a vybuduj zbierku}  
+_textdtc_ [l=sk] {VymazaÅ¥ celÃº kolekciu}  
+_textetcfcd_ [l=sk] {Export zbierky na samoinÅ¡talaÄnÃœ CD-ROM Windows}  
+_textcaec_ [l=sk] {Upravujem existujÃºcu zbierku}  
+_textnwec_ [l=sk] {Åœiadnu zo zbierok nie je moÅŸnÃ© upravovaÅ¥. }  
+_textcianc_ [l=sk] {VytvÃ¡ram novÃº zbierku}  
+_texttsosn_ [l=sk] {PostupnosÅ¥ krokov potrebnÃœch na vytvorenie novej zbierky digitÃ¡lnej kniÅŸnice je :}  
+_textsin_ [l=sk] {Zadajte nÃ¡zov (a pridruÅŸenÃ© informÃ¡cie)}  
+_textswts_ [l=sk] {Zadaj cestu zdrojovÃœch dÃ¡t}  
+_textatco_ [l=sk] {UpraviÅ¥ nastavenia (len pre skÃºsenÃœch pouÅŸÃ­vateÄŸov)}  
+_textbtc_ [l=sk] {"Vybuduj" zbierku (pozri niÅŸÅ¡ie)}  
+_textpvyh_ [l=sk] {PrezrieÅ¥ si svoju prÃ¡cu.}  
+
+_texttfsiw_ [l=sk] {V Å¡tvrtom kroku poÄÃ­taÄ samostatne indexuje a spÃ¡ja vÅ¡etky potrebnÃ© informÃ¡cie. Najprv vÅ¡ak tieto informÃ¡cie musÃ­te zadaÅ¥. }  
+
+_textadab_ [l=sk] {Diagram VÃ¡m pomÃŽÅŸe sledovaÅ¥ priebeh procesu. KliknutÃ­m na zelenÃ© tlaÄidlo pokraÄujete v procese. PoÄas procesu sa budÃº tlaÄidlÃ¡ meniÅ¥ na ÅŸltÃ©. KliknutÃ­m na ÅŸltÃ© tlaÄidlo v diagrame sa vrÃ¡tite na predchÃ¡dzajÃºcu stranu. }  
+
+_textwyar_ [l=sk] {Ak chcete spustiÅ¥ proces budovania novej zbierky stlaÄte zelenÃ© tlaÄidlo "O zbierke".}  
+
+_textcnmbs_ [l=sk] {NÃ¡zov zbierky musÃ­ byÅ¥ stanovenÃœ}  
+_texteambs_ [l=sk] {Zadajte svoju emailovÃº adresu}  
+_textpsea_ [l=sk] {NapÃ­Å¡te emailovÃº adresu vo formÃ¡te : pouÅŸÃ­vateÄŸ@domÃ©na}  
+_textdocmbs_ [l=sk] {Zbierka musÃ­ byÅ¥ popÃ­sanÃ¡ }  
+
+_textwcanc_ [l=sk] {Pri tvorbe novej zbierky digitÃ¡lnej kniÅŸnice je potrebnÃ© vyplniÅ¥ niekoÄŸko Ãºdajov o zdrojovÃœch dokumentoch. LiÅ¡ta (dole) ukazuje priebeh operÃ¡cie spracovania strÃ¡n.}  
+
+_texttfc_ [l=sk] {NÃ¡zov zbierky}  
+
+_texttctiasp_ [l=sk] {ProstrednÃ­ctvom nÃ¡zvu zbierky systÃ©m digitÃ¡lnej kniÅŸnice identifikuje jej obsah.}  
+
+_textcea_ [l=sk] {EmailovÃ¡ adresa:}  
+
+_textteas_ [l=sk] {V prÃ­pade akÃœchkoÄŸvek problÃ©mov, bude Greenstone zasielaÅ¥ sprÃ¡vy o chybÃ¡ch na vami zadanÃº emailovÃº adresu. EmailovÃº adresu pÃ­Å¡te v tvare : <tt>meno@domÃ©na</tt>.}  
+
+_textatc_ [l=sk] {O tejto zbierke:}  
+
+_texttiasd_ [l=sk] {Tieto informÃ¡cie o zbierke sa zobrazia na jej prvej strane.}  
+
+_textypits_ [l=sk] {Proces vÃœstavby mÃŽÅŸete sledovaÅ¥ prostrednÃ­ctvom Å¡Ã­pky (dole). Pre zaÄatie stlaÄte zelenÃ© tlaÄidlo "ZdrojovÃ© dÃ¡ta".}  
+
+_srcebadsources_ [l=sk] {<p>VstupnÃ© zdroje sÃº nedostupnÃ© ( _iconcross_ ).<p>PrÃ­Äinou mÃŽÅŸu byÅ¥:<ul><li>neexistujÃºci sÃºbor, FTP, alebo URL<li>nepripojenie sa na internet<li>Firewall</ul><p>Ak tÃºto URL vidÃ­te vo vaÅ¡om prehliadaÄi, mÃŽÅŸe Ã­sÅ¥ o kÃ³piu v pamÃ€ti VÃ¡Å¡ho poÄÃ­taÄa. }  
+
+_textymbyco_ [l=sk] {<p>Svoju zbierku mÃŽÅŸete vybudovaÅ¥ <ul><li>Od zaÄiatku<dl><dd>NovÃ¡ zbierka mÃŽÅŸe obsahovaÅ¥ html dokumenty (.htm, .html), textovÃ© dokumenty (.txt, .text), dokumenty MS Word (.doc), dokumenty PDF (.pdf), alebo emailovÃ© dokumenty vo formÃ¡te "m-box" (.mbx).</dd></dl><li>Z existujÃºcej zbierky<dl><dd>SÃºbory vo vaÅ¡ej novej zbierke musia byÅ¥ rovnakÃ©ho typu ako ste pouÅŸili pri tvorbe predchÃ¡dzajÃºcej zbierky.</dd></dl>
+</ul>}  
+
+_textbtco_ [l=sk] {Vybuduj kolekciu }  
+_textand_ [l=sk] {Pridaj novÃ© dÃ¡ta}  
+_textad_ [l=sk] {PridÃ¡vam dÃ¡ta:}  
+
+_texttftysb_ [l=sk] {SÃºbory, ktorÃ© ste urÄili (dole) budÃº zaÄlenenÃ© do zbierky. Uistite sa, ÅŸe tieto sÃºbory uÅŸ v zbierke nie sÃº.}  
+
+_textis_ [l=sk] {VstupnÃ© zdroje :}  
+
+_textddd1_ [l=sk] {<p>Na presnÃ© urÄenie sÃºborov, ktorÃ© sa majÃº stiahnuÅ¥ mÃŽÅŸete pouÅŸiÅ¥ protokoly file:// a  ftp://.  <p> Ak pouÅŸÃ­vate protokol http://  zÃ¡leÅŸÃ­ na URL Äi sa vÃ¡m stiahne webovÃ¡ strÃ¡nka, alebo sÃºbor. Ak sa vÃ¡m stiahne webovÃ¡ strÃ¡nka, stiahnu sa s Åou aj webovÃ© linky a strÃ¡nky na ktorÃ© linky smerujÃº. (PokiaÄŸ sa nachÃ¡dzajÃº na jednom webovom sÃ­dle, pod jednou URL). <p>Pri pouÅŸitÃ­ : file:// or ftp:// sa vÃ¡m stiahne celÃœ adresÃ¡r aj s podadresÃ¡rmi.}  
+
+_textddd2_ [l=sk] {<p>Kliknite na jedno zo zelenÃœch tlaÄidiel. Ak ste pokroÄilÃ­ pouÅŸÃ­vateÄŸ mÃŽÅŸete editovaÅ¥ nastavenia zbierky. Alebo choÄte priamo budovateÄŸskÃ©ho rozhrania. ZapamÃ€tajte si, ÅŸe sa kedykoÄŸvek mÃŽÅŸete vrÃ¡tiÅ¥ k predchÃ¡dzajÃºcej fÃ¡ze stlaÄenÃ­m zelenÃ©ho tlaÄidla.}  
+
+_textconf1_ [l=sk] {<p>Vybudovanie a dizajn vaÅ¡ej zbierky je ovplyvnenÃ© konfiguraÄnÃœm sÃºborom. SkÃºsenÃ­ pouÅŸÃ­vatelia ho mÃŽÅŸu editovaÅ¥ a meniÅ¥ jeho nastavenia.<center><p><b>Ak nie ste skÃºsenÃœ pouÅŸÃ­vateÄŸ, choÄte na spodok strÃ¡nky.</b></center> Pre zmenu nastavenÃ­, editujte dÃ¡ta dole. Pre nÃ¡vrat k pÃŽvodnÃœm nastaveniam kliknite na "Reset."}  
+
+_textreset_ [l=sk] {Reset }  
+
+
+_texttryagain_ [l=sk] {ProsÃ­m <a href="_httppagecollector_" target=_top>reÅ¡tartujte ZberateÄŸa</a> a skÃºste znova. }  
+
+
+_textretcoll_ [l=sk] {SpÃ€Å¥ }  
+
+_textdelperm_ [l=sk] {Zbierka _cgiargbc1dirname_ nemohla byÅ¥ vymazanÃ¡. PravdepodobnÃ© prÃ­Äiny : <ul> <li> Greenstone nie je oprÃ¡vnenÃœ vymazaÅ¥ prieÄinok _gsdlhome_/collect/_cgiargbc1dirname_.<br> MoÅŸno budete musieÅ¥ prieÄinok zbierky _cgiargbc1dirname_ zmazaÅ¥ manuÃ¡lne.</li><li>Greenstone nemÃŽÅŸe spustiÅ¥ program _gsdlhome_/bin/script/delcol.pl. Uistite sa, ÅŸe sÃºbor je moÅŸnÃ© ÄÃ­taÅ¥ a spustiÅ¥.</li>
+</ul>}  
+
+_textdelinv_ [l=sk] {Zbierka _cgiargbc1dirname_ je chrÃ¡nenÃ¡, alebo nefunkÄnÃ¡. VaÅ¡a operÃ¡cia bola zruÅ¡enÃ¡. }  
+
+_textdelsuc_ [l=sk] {Zbierka _cgiargbc1dirname_ bola ÃºspeÅ¡ne zmazanÃ¡.}  
+
+_textclonefail_ [l=sk] {Zbierka _cgiargclonecol_ nemohla byÅ¥ vyklonovanÃ¡. MoÅŸnÃ© prÃ­Äiny :  <ul> <li> Zbierka _cgiargclonecol_ neexistuje.<li> Zbierka _cgiargclonecol_ nemÃ¡ konfiguraÄnÃœ sÃºbor collect.cfg <li> Greenstone nemÃ¡ prÃ¡vo ÄÃ­taÅ¥ sÃºbor collect.cfg</ul>}  
+
+_textcolerr_ [l=sk] {Chyba ZberateÄŸa.}  
+
+_texttmpfail_ [l=sk] {ZberateÄŸ nedokÃ¡zal preÄÃ­taÅ¥, alebo zapÃ­saÅ¥ dÃ¡ta do prieÄinku Temporary. MoÅŸnÃ© prÃ­Äiny sÃº : <ul><li> Greenstone nemÃ¡ oprÃ¡vnenie ÄÃ­taÅ¥/zapisovaÅ¥ prieÄinok _gsdlhome_/tmp.</ul>}  
+
+_textmkcolfail_ [l=sk] {ZberateÄŸ nedokÃ¡zal vytvoriÅ¥ potrebnÃº Å¡truktÃºru prieÄinku (chyba mkcol.pl). PravdepodobnÃ© prÃ­Äiny :  <ul>Greenstone nemÃ¡ oprÃ¡vnenie zapisovaÅ¥ do prieÄinku _gsdlhome_/tmp.<li> Chyba perl skriptov mkcol.pl.</ul>}  
+
+_textnocontent_ [l=sk] {Chyba ZberateÄŸa: novÃ¡ zbierka nebola pomenovanÃ¡. ReÅ¡tartujte ZberateÄŸa. }  
+
+_textrestart_ [l=sk] {ReÅ¡tartuj ZberateÄŸa.}  
+
+_textreloaderror_ [l=sk] {Pri budovanÃ­ novej kolekcie nastala chyba. Greenstone mohlo zmiasÅ¥ pouÅŸÃ­vanie tlaÄidiel "spaÅ¥" a "obnov" vo vaÅ¡om prehliadaÄi (snaÅŸte sa poÄas budovania zbierky minimalizovaÅ¥ pouÅŸÃ­vanie tÃœchto tlaÄidiel). Teraz reÅ¡tartujte ZberateÄŸa.}  
+
+_textexptsuc_ [l=sk] {Zbierka _cgiargbc1dirname_ bola ÃºspeÅ¡ne exportovanÃ¡ do adresÃ¡ra _gsdlhome_/tmp/exported\__cgiargbc1dirname_.}  
+
+_textexptfail_ [l=sk] {<p>Export zbierky  _cgiargbc1dirname_ zlyhal. <p>Pravdepodobne ste nenainÅ¡talovali tÃºto funkciu.<ul> <li>Ak ste inÅ¡talovali Greenstone z CD-ROM, funkcia Export sa nenainÅ¡talovala, pokiaÄŸ ste poÄas inÅ¡talÃ¡cie nezvolili "VlastnÃº" (Custom) inÅ¡talÃ¡ciu. Funkciu je moÅŸnÃ© doinÅ¡talovaÅ¥ opÃ€tovnÃœm spustenÃ­m inÅ¡talÃ¡cie. <li>Ak ste inÅ¡talovali Greenstone z webovej distribÃºcie, musÃ­te si stiahnuÅ¥ inÅ¡talaÄnÃœ sÃºbor a doinÅ¡talovaÅ¥ potrebnÃº funkciu. Pre ÄalÅ¡ie informÃ¡cie navÅ¡tÃ­vte <a href="http://www.greenstone.org">http://www.greenstone.org</a> alebo pÃ­Å¡te na <a
+ href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>.</ul>
+}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=sk] {<p>Dopl&#328;te nasleduj&#250;ce inform&#225;cie a kliknite na _textintro_.</p>}  
+
+_textcaec_ [l=sk] {PridÃ¡vam k existujÃºcej zbierke}  
+_textbild_ [l=sk] {Do depozitu}  
+_textintro_ [l=sk] {Vyber sÃºbor}  
+_textconfirm_ [l=sk] {Potvrdenie}  
+_textselect_ [l=sk] {Vyber zbierku}  
+_textmeta_ [l=sk] {DoplniÅ¥ metadÃ¡ta}  
+
+_texttryagain_ [l=sk] {ProsÃ­m <a href="_httppagedepositor_" target=_top>ReÅ¡tartujte Depozit</a> a skÃºste znova.}  
+
+_textselectcol_ [l=sk] {Vyberte zbierku do ktorej chcete pridaÅ¥ novÃœ dokument.}  
+_textfilename_ [l=sk] {SÃºbor}  
+_textfilesize_ [l=sk] {VeÄŸkosÅ¥ sÃºboru}  
+
+_textretcoll_ [l=sk] {NÃ¡vrat do Depozitu}  
+
+
+_texttmpfail_ [l=sk] {Depozit nedokÃ¡zal zapÃ­saÅ¥, alebo preÄÃ­taÅ¥ sÃºbor/prieÄinok Temp. Pravdepodobne Greenstone nemÃŽÅŸe :<ul>
+<li>zapisovaÅ¥/ÄÃ­taÅ¥ prieÄinok _gsdlhome_/tmp.</ul>}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=sk] {Greenstone je softvÃ©r prostrednÃ­ctvom, ktorÃ©ho je moÅŸnÃ© vytvÃ¡raÅ¥ a spravovaÅ¥ digitÃ¡lne zbierky. PrinÃ¡Å¡a novÃœ spÃŽsob organizovania a sprÃ­stupÅovania informÃ¡ciÃ­ na internete, alebo CD-ROM. Greenstone je produktom New Zeland Digital Library Project, Univerzity Waikato, distribuovanÃœ v spoluprÃ¡ci s UNESCO  a Human info NGO. Je to voÄŸne dostupnÃœ softvÃ©r pod podmienkami GNU General Public Licence. <i>http://greenstone.org</i>}  
+
+_textgreenstone2_ [l=sk] {WebovÃ¡ strÃ¡nka digitÃ¡lnej kniÅŸnice NovÃ©ho ZÃ©landu (<a
+href="http://nzdl.org">http://nzdl.org</a>) obsahuje prÃ­klady zbierok, vytvorenÃœch prostrednÃ­ctvom softvÃ©ru Greenstone. Zbierky na strÃ¡nke demonÅ¡trujÃº rÃŽzne vyhÄŸadÃ¡vacie techniky, moÅŸnosti prehliadania a sÃº v rÃŽznych jazykoch.}  
+
+_textplatformtitle_ [l=sk] {platforma}  
+_textgreenstone3_ [l=sk] {Greenstone je schopnÃœ pracovaÅ¥ pod systÃ©mami Windows, Unix a Mac OS X. ZdrojovÃœ kÃ³d programu je plne prÃ­stupnÃœ s moÅŸnosÅ¥ou editÃ¡cie pod Microsoft C++, alebo gcc. Greenstone pracuje s voÄŸne dostupnÃœm softvÃ©rom : Apache Webserver a PERL.}  
+
+_textgreenstone4_ [l=sk] {NajrozmanitejÅ¡ie zbierky digitÃ¡lnych dokumentov na CD-ROM boli vytvorenÃ© softvÃ©rom Greenstone. NaprÃ­klad zbierka <i>Humanity Development Library</i> obsahuje 1230 rÃŽznych publikÃ¡ciÃ­, od oblasti ÃºÄtovnÃ­ctva, aÅŸ po problematiku Äistoty vody. HardvÃ©rovÃ© nÃ¡roky na spustenie tÃœchto zbierok sÃº minimÃ¡lne. PrÃ­stup k informÃ¡ciÃ¡m je zabezpeÄenÃœ vyhÄŸadÃ¡vanÃ­m a prehliadanÃ­m podÄŸa rÃŽznych kategÃ³riÃ­.}  
+
+_textcustomisationtitle_ [l=sk] {prispÃŽsobenie}  
+_textgreenstone5_ [l=sk] {Funkcie Greenstone je moÅŸnÃ© ÄŸahko prispÃŽsobiÅ¥ a rozÅ¡Ã­riÅ¥. MetadÃ¡tovÃ© prvky sa dajÃº podÄŸa aktuÃ¡lnych potrieb jednoducho vytvÃ¡raÅ¥, editovaÅ¥ a upravovaÅ¥. Greenstone disponuje jednoduchÃœm pouÅŸÃ­vateÄŸskÃœm rozhranÃ­m, ktorÃ© je ÄŸahko upravovateÄŸnÃ© prostrednÃ­ctvom macro sÃºborov napÃ­sanÃœch v jednoduchom jazyku.}  
+
+_textdocumentationtitle_ [l=sk] {dokumentÃ¡cia}  
+_textdocuments_ [l=sk] {Je dostupnÃ¡ aj rozsiahla dokumentÃ¡cia Greenstone.}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=sk] {diskusnÃ¡ skupina}  
+_textmailinglist_ [l=sk] {Na zabezpeÄenie komunikÃ¡cie o Greenstone vznikla diskusnÃ¡ skupina, do ktorej sa mÃŽÅŸete prihlÃ¡siÅ¥ na <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+
+Pre zasielanie sprÃ¡v do skupiny je potrebnÃ© sprÃ¡vu adresovaÅ¥ na adresu: <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>.}  
+
+_textbugstitle_ [l=sk] {chyby}  
+_textreport_ [l=sk] {Prajeme si, aby tento softvÃ©r fungoval sprÃ¡vne. PrÃ­padnÃ© chyby zasielajte na adresu <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>}  
+
+_textgs3title_ [l=sk] {verzie}  
+_textgs3_ [l=sk] {Verzia softvÃ©ru Greenstone 3 ponÃºka vÅ¡etky funkcie a vÃœhody verzie Greenstone 2.
+SoftvÃ©r je napÃ­sanÃœ v jazyku Java a funguje kompilÃ¡ciou nezÃ¡vislÃœch zÃ¡suvnÃœch modulov komunikujÃºcich v jazyku XML. DokumentÃ¡cia a testovacie verzie Greenstone 3 sÃº dostupnÃ© na strÃ¡nke <a href="http://www.greenstone.org/greenstone3.html"> Greenstone 3</a>.
+}  
+
+_textcreditstitle_ [l=sk] {autori}  
+
+_textwhoswho_ [l=sk] {SoftvÃ©r Greenstone je vÃœsledkom spoloÄnej prÃ¡ce : Rodger McNab a Stefan Boddie (principal architects and implementors). Äalej k vytvoreniu prispeli : David Bainbridge, George
+Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd Reed, Bill Rogers, John Thompson, Stuart Yeates, Älenovia projektu New Zealand Digital Library : Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols a Lloyd Smith.
+}  
+
+_textaboutgslong_ [l=sk] {o softvÃ©ri Greenstone}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=sk] {Zoznam pouÅŸÃ­vateÄŸov}  
+_textuser_ [l=sk] {pouÅŸÃ­vateÄŸ}  
+_textas_ [l=sk] {stav ÃºÄtu}  
+_textgroups_ [l=sk] {skupiny}  
+_textcomment_ [l=sk] {komentÃ¡r}  
+_textadduser_ [l=sk] {pridaj novÃ©ho pouÅŸÃ­vateÄŸa}  
+_textedituser_ [l=sk] {editovaÅ¥}  
+_textdeleteuser_ [l=sk] {vymazaÅ¥}  
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=sk] {ZmeniÅ¥ pouÅŸÃ­vateÄŸskÃ© nastavenia}  
+_textadduser_ [l=sk] {PridaÅ¥ novÃ©ho pouÅŸÃ­vateÄŸa}  
+
+_textaboutusername_ [l=sk] {PouÅŸÃ­vateÄŸskÃ© meno musÃ­ byÅ¥ dlhÃ© od 2 do 30 znakov a mÃŽÅŸe obsahovaÅ¥ znaky  '.', a '_'.}  
+
+_textaboutpassword_ [l=sk] {Heslo musÃ­ byÅ¥ dlhÃ© 3 aÅŸ 128 znakov a mÃŽÅŸe sa skladaÅ¥ zo znakov ASCII.}  
+
+_textoldpass_ [l=sk] {Ak zostane toto pole prÃ¡zdne bude zachovanÃ© starÃ© heslo.}  
+_textenabled_ [l=sk] {zapnutÃ©}  
+_textdisabled_ [l=sk] {vypnutÃ©}  
+
+_textaboutgroups_ [l=sk] {JednotlivÃ© slovÃ¡ oddeÄŸujte Äiarkou a nedÃ¡vajte medzi ne medzery.}  
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=sk] {VymazaÅ¥ pouÅŸÃ­vateÄŸa}  
+_textremwarn_ [l=sk] {Ste si istÃœ, ÅŸe chcete zmazaÅ¥ pouÅŸÃ­vateÄŸa <b>_cgiargumun_</b>?}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=sk] {ZmeniÅ¥ heslo}  
+_textoldpw_ [l=sk] {starÃ© heslo}  
+_textnewpw_ [l=sk] {novÃ© heslo}  
+_textretype_ [l=sk] {napÃ­Å¡te eÅ¡te raz novÃ© heslo}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=sk] {VaÅ¡e heslo bolo ÃºspeÅ¡ne zmenenÃ©.}  
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=sk] {NeplatnÃ© pouÅŸÃ­vateÄŸskÃ© meno.}  
+_textinvalidpassword_ [l=sk] {NeplatnÃ© heslo.}  
+_textemptypassword_ [l=sk] {VloÅŸte poÄiatoÄnÃ© heslo pre tohto pouÅŸÃ­vateÄŸa.}  
+_textuserexists_ [l=sk] {Tento pouÅŸÃ­vateÄŸ uÅŸ existuje, zvoÄŸte inÃ© pouÅŸÃ­vateÄŸskÃ© meno.}  
+
+_textusernameempty_ [l=sk] {VloÅŸte svoje pouÅŸÃ­vateÄŸskÃ© meno.}  
+_textpasswordempty_ [l=sk] {VloÅŸte svoje starÃ© heslo.}  
+_textnewpass1empty_ [l=sk] {VloÅŸte novÃ© heslo a napÃ­Å¡te ho znova.}  
+_textnewpassmismatch_ [l=sk] {NovÃ© heslÃ¡ sa nezhodujÃº.}  
+_textnewinvalidpassword_ [l=sk] {VloÅŸili ste nesprÃ¡vne heslo.}  
+_textfailed_ [l=sk] {NesprÃ¡vne pouÅŸÃ­vateÄŸskÃ© heslo, alebo meno.}  
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=sk] {Verzia Greenstone}  
+_textframebrowser_ [l=sk] {Na zobrazenie musÃ­te maÅ¥ povolenÃ© rÃ¡mce. }  
+_textusermanage_ [l=sk] {ManaÅŸment pouÅŸÃ­vateÄŸov}  
+_textlistusers_ [l=sk] {listuj v pouÅŸÃ­vateÄŸoch}  
+_textaddusers_ [l=sk] {pridaj novÃ©ho pouÅŸÃ­vateÄŸa}  
+_textchangepasswd_ [l=sk] {zmeniÅ¥ heslo}  
+_textinfo_ [l=sk] {TechnickÃ© informÃ¡cie}  
+_textgeneral_ [l=sk] {hlavnÃ¡}  
+_textarguments_ [l=sk] {argumenty}  
+_textactions_ [l=sk] {akcie}  
+_textbrowsers_ [l=sk] {prehliadaÄe}  
+_textprotocols_ [l=sk] {protokoly}  
+_textconfigfiles_ [l=sk] {SÃºbory s nastaveniami}  
+_textlogs_ [l=sk] {sprÃ¡vy}  
+_textusagelog_ [l=sk] {sprÃ¡va o pouÅŸÃ­vanÃ­}  
+_textinitlog_ [l=sk] {init sprÃ¡va }  
+_texterrorlog_ [l=sk] {sprÃ¡va o chybÃ¡ch}  
+_textadminhome_ [l=sk] {administrÃ¡torskÃ¡ strÃ¡nka}  
+_textreturnhome_ [l=sk] {Domov}  
+_titlewelcome_ [l=sk] {AdministrÃ¡cia}  
+_textmaas_ [l=sk] {MoÅŸnÃ© sprÃ¡vcovskÃ© a administrÃ¡torskÃ© sluÅŸby zahÅÅajÃº :}  
+_textvol_ [l=sk] {ukÃ¡ÅŸ on-line sprÃ¡vy}  
+_textcmuc_ [l=sk] {vytvor, spravuj a aktualizuj zbierky}  
+_textati_ [l=sk] {technickÃ© informÃ¡cie CGI argumenty}  
+
+_texttsaa_ [l=sk] {Tieto sluÅŸby sÃº prÃ­stupnÃ© prostrednÃ­ctvom navigaÄnej liÅ¡ty, na ÄŸavej strane strÃ¡nky.}  
+
+_textcolstat_ [l=sk] {Stav zbierky}  
+
+_textcwoa_ [l=sk] {Zbierky sa zobrazia v  "zapnutom" stave, len ak bude funk&#269;n&#253; build.cfg s&#250;bor v adres&#225;ri zbierky.}  
+
+_textcafi_ [l=sk] {kliknite na<i>info</i>, aby sa zobrazili inform&#225;cie o zbierke}  
+_textcctv_ [l=sk] {kliknite <i>na zbierku</i> aby sa zobrazila zbierka}  
+_textsubc_ [l=sk] {OdoslaÅ¥ zmeny}  
+_texteom_ [l=sk] {Chyba pri otvÃ¡ranÃ­ main.cfg}  
+_textftum_ [l=sk] {AktualizÃ¡cia main.cfg zlyhala}  
+_textmus_ [l=sk] {aktualizÃ¡cia main.cfg prebehla ÃºspeÅ¡ne}  
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=sk] {SprÃ¡va o vybudovanÃ­ zbierky "_collectionname_"}  
+_textflog_ [l=sk] {SprÃ¡va o chybÃ¡ch v zbierke "_collectionname_"}  
+_textilog_ [l=sk] {SprÃ¡va o importe zbierky "_collectionname_"}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=sk] {PoslaÅ¥ spÃ€tnÃº vÃ€zbu}  
+
+_greenstoneusabilitytext_ [l=sk] {PouÅŸÃ­vateÄŸnosÅ¥ webovÃœch strÃ¡nok}  
+
+_textwhy_ [l=sk] {<p>PoslanÃ­m tejto sprÃ¡vy nÃ¡s upozornÃ­te, ÅŸe prehliadanÃº strÃ¡nku povaÅŸujete za nÃ¡roÄnÃº.}  
+_textextraforform_ [l=sk] {NemusÃ­te vyplniÅ¥ celÃœ formulÃ¡r - kaÅŸdÃ¡ informÃ¡cia uÅŸitoÄnÃ¡. }  
+_textprivacybasic_ [l=sk] {<p>SprÃ¡va bude obsahovaÅ¥ informÃ¡cie len o navÅ¡tÃ­venÃœch strÃ¡nkach Greenstone a technolÃ³giÃ­, ktorÃº ste pri ich prehliadanÃ­ pouÅŸili.}  
+_textstillsend_ [l=sk] {SkutoÄne chcete poslaÅ¥ tÃºto sprÃ¡vu ?}  
+
+_texterror_ [l=sk] {chyba}  
+_textyes_ [l=sk] {Ãno}  
+_textno_ [l=sk] {Nie}  
+_textclosewindow_ [l=sk] {Zavri okno}  
+_textabout_ [l=sk] {O}  
+_textprivacy_ [l=sk] {SÃºkromie}  
+_textsend_ [l=sk] {PoslaÅ¥}  
+_textdontsend_ [l=sk] {Neposielaj }  
+_textoptionally_ [l=sk] {NepovinnÃ© }  
+
+_textunderdev_ [l=sk] {PrehÄŸad detailov bude prÃ­stupnÃœ v definitÃ­vnej verziÃ­.}  
+
+_textviewdetails_ [l=sk] {UkÃ¡ÅŸ detaily sprÃ¡vy}  
+_textmoredetails_ [l=sk] {Viac detailov}  
+_texttrackreport_ [l=sk] {SledovaÅ¥ tÃºto sprÃ¡vu}  
+_textcharacterise_ [l=sk] {O akÃœ problÃ©m ide}  
+_textseverity_ [l=sk] {Ako vÃ¡ÅŸny je problÃ©m}  
+ 
+_textbadrender_ [l=sk] {StrÃ¡nka nevyzerÃ¡ dobre}  
+_textcontenterror_ [l=sk] {Chyba obsahu}  
+_textstrangebehaviour_ [l=sk] {DivnÃ© sprÃ¡vanie}  
+_textunexpected_ [l=sk] {Stalo sa nieÄo neoÄakÃ¡vanÃ©. }  
+_textfunctionality_ [l=sk] {Å€aÅŸko pouÅŸÃ­vateÄŸnÃ©}  
+_textother_ [l=sk] {OstatnÃ©}  
+
+_textcritical_ [l=sk] {KritickÃ¡}  
+_textmajor_ [l=sk] {VÃ¡ÅŸne}  
+_textmedium_ [l=sk] {StrednÃ©}  
+_textminor_ [l=sk] {ÄœahkÃœ}  
+_texttrivial_ [l=sk] {BezvÃœznamnÃœ}  
+
+_textwhatdoing_ [l=sk] {Äo ste sa pokÃºÅ¡ali urobiÅ¥ ?}  
+_textwhatexpected_ [l=sk] {Äo ste oÄakÃ¡vali, ÅŸe sa stane ?}  
+_textwhathappened_ [l=sk] {Äo sa stalo ?}  
+
+_cannotfindcgierror_ [l=sk] {<h2>PrepÃ¡Äte !</h2>NemÃŽÅŸem nÃ¡jsÅ¥ program pre "_linktextusab_".}  
+
+_textusabbanner_ [l=sk] {Greenstone koru-style banner}  
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=sk] {Vyskytla sa chyba}  
+
+_textgtihome_ [l=sk] {ProstrednÃ­ctvom tÃœchto strÃ¡nok je moÅŸnÃ©:
+<ul>
+<li>prekladaÅ¥ Äasti Greenstone do novÃ©ho jazyka
+<li>aktualizovaÅ¥ existujÃºce preklady
+<li>opravovaÅ¥ chyby v existujÃºcich prekladoch
+</ul>
+Prekladanie sa realizuje prostrednÃ­ctvom webovÃ©ho rozhrania, alebo dokumentu vo formÃ¡te XLS. PrekladÃ¡ sa vÅŸdy celÃ¡ frÃ¡za, priÄom sa vynechÃ¡vajÃº znaÄky HTML a slovÃ¡ oznaÄenÃ© (_takto_).
+<p>
+KaÅŸdÃ¡ strÃ¡nka prekladateÄŸskÃ©ho rozhrania sa konÄÃ­ s tlaÄidlom _textgtisubmit_. Ak ho stlaÄÃ­te, zmeny sa okamÅŸite prejavia na inÅ¡talÃ¡ciÃ­ nzdl.org.
+}  
+
+_textgtiselecttlc_ [l=sk] {ZvoÄŸte svoj jazyk}  
+
+#for status page
+_textgtiviewstatus_ [l=sk] {UkÃ¡ÅŸ stav prekladov pre vÅ¡etky jazyky}  
+_textgtiviewstatusbutton_ [l=sk] {ZOBRAZ STAV}  
+_textgtistatustable_ [l=sk] {Zoznam stavu prekladov pre vÅ¡etky jazyky}  
+_textgtilanguage_ [l=sk] {Jazyk}  
+_textgtitotalnumberoftranslations_ [l=sk] {CelkovÃœ poÄet prekladov}  
+
+_textgtiselecttfk_ [l=sk] {ZvoÄŸte sÃºbor s ktorÃœm chcete pracovaÅ¥}  
+
+_textgticoredm_ [l=sk] {Rozhranie Greenstone (Jadro)}  
+_textgtiauxdm_ [l=sk] {Rozhranie Greenstone (PomocnÃ©)}  
+_textgtiglidict_ [l=sk] {SlovnÃ­k GLI}  
+_textgtiglihelp_ [l=sk] {Pomoc pre GLI}  
+_textgtiperlmodules_ [l=sk] {moduly Perl}  
+_textgtitutorials_ [l=sk] {CviÄenia}  
+_textgtigreenorg_ [l=sk] {Greenstone.org}  
+_textgtigs3core_ [l=sk] {Rozhranie Greenstone3 (prednastavenÃ©)}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=sk] {VÃœvojÃ¡rska prÃ­ruÄka Greenstone}  
+_textgtiinstallmanual_ [l=sk] {InÅ¡talaÄnÃœ manuÃ¡l Greenstone}  
+_textgtipapermanual_ [l=sk] {Greenstone prÃ­ruÄka pre "Paper to Collection"}  
+_textgtiusermanual_ [l=sk] {PouÅŸÃ­vateÄŸskÃ¡ prÃ­ruÄka Greenstone}  
+
+_textgtienter_ [l=sk] {VstÃºp}  
+
+_textgticorrectexistingtranslations_ [l=sk] {Oprav existujÃºci preklad}  
+_textgtidownloadtargetfile_ [l=sk] {Stiahni sÃºbor}  
+_textgtiviewtargetfileinaction_ [l=sk] {Zobraz aktualizovanÃœ sÃºbor}  
+_textgtitranslatefileoffline_ [l=sk] {PreloÅŸ tento sÃºbor offline}  
+
+_textgtinumchunksmatchingquery_ [l=sk] {PoÄet textovÃœch reÅ¥azcov spÄºÅajÃºcich poÅŸiadavku}  
+
+_textgtinumchunkstranslated_ [l=sk] {preloÅŸenÃ©}  
+_textgtinumchunksrequiringupdating_ [l=sk] {Z tÃœchto je potrebnÃ© _1_ aktualizovaÅ¥.}  
+_textgtinumchunksrequiringtranslation_ [l=sk] {poÄet zostÃ¡vajÃºcich prekladov}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=sk] {poÄet dokonÄenÃœch prekladov}  
+_textgtinumchunksrequiringupdating2_ [l=sk] {poÄet prekladov, ktorÃ© je potrebnÃ© aktualizovaÅ¥}  
+_textgtinumchunksrequiringtranslation2_ [l=sk] {zostÃ¡va eÅ¡te preloÅŸiÅ¥}  
+
+_textgtienterquery_ [l=sk] {VloÅŸ slovo alebo frÃ¡zu z Äasti textu, ktorÃœ chceÅ¡ opraviÅ¥. }  
+_textgtifind_ [l=sk] {NÃ¡jdi}  
+
+_textgtitranslatingchunk_ [l=sk] {PrekladÃ¡m <i>_1_</i>}  
+_textgtiupdatingchunk_ [l=sk] {Aktualizujem <i>_1_</i>}  
+_textgtisubmit_ [l=sk] {ODOSLAÅ€}  
+
+_textgtilastupdated_ [l=sk] {Naposledy aktualizovanÃ©}  
+
+_textgtitranslationfilecomplete_ [l=sk] {Äakujeme za vykonanie aktualizÃ¡cie! <p>KÃ³piu aktualizovanÃ©ho sÃºboru si mÃŽÅŸete stiahnuÅ¥ ak kliknete na odkaz hore. SÃºbor bude zahrnutÃœ do nasledujÃºcej distribÃºcie Greenstone.}  
+
+_textgtiofflinetranslation_ [l=sk] {TÃºto ÄasÅ¥ Greenstone mÃŽÅŸete preloÅŸiÅ¥ prostrednÃ­ctvom Excel sÃºboru:
+
+<ol>
+<li>SÅ¥iahnuÅ¥ <a href="_gwcgi_?a=gti&p=excel&e=_compressedoptions_">tento sÃºbor</a>.
+<li>Preklad vloÅŸte do zodpovedajÃºcich polÃ­.
+<li>Po skonÄenÃ­ prekladu zaÅ¡lite .xls sÃºbor na <a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>.
+</ol>}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=sk] {knihovnÃ­cke rozhranie Greenstone}  
+_textglihelp_ [l=sk] {<p>KnihovnÃ­cke rozhranie Greenstone (Greenstone Librarian Interface â GLI) umoÅŸÅuje prÃ­stup k jednoduchÃ©mu rozhraniu v ktorom je moÅŸnÃ© jednotlivÃ© zbierky budovaÅ¥ a upravovaÅ¥. </p>
+
+<p>GLI pracuje v spojenÃ­ so softvÃ©rom Greenstone a predpokladÃ¡, ÅŸe softvÃ©r je nainÅ¡talovanÃœ v jednom z podprieÄinkov inÅ¡talÃ¡cie Greenstone.</p>
+
+<h4>PouÅŸÃ­vanie GLI pod operaÄnÃœm systÃ©mom Windows</h4>
+
+Pre spustenie knihovnÃ­ckeho rozhrania pod operaÄnÃœm systÃ©mom Windows je potrebnÃ© nÃ¡jsÅ¥ inÅ¡talÃ¡ciu Greenstone. Å tandardne by sa mala nachÃ¡dzaÅ¥ v <i>Å tart</i> / <i>Programy</i> /  <i>Greenstone Digital Library</i> / <i>Librarian Interface</i>.
+
+<h4>Spustenie GLI pod Unix</h4>
+
+Pre spustenie pod systÃ©mom Unix, choÄte do adresÃ¡ra <i>gli</i> a spustite <i>gli.sh</i>.
+
+<h4>Spustenie GLI pod Mac OS X</h4>
+V prehliadaÄi choÄte cestou  <i>Applications</i> / <i>Greenstone</i> / <i>GLI</i>.
+}  
Index: /gsdl/stable/macros/spanish.dm
===================================================================
--- /gsdl/stable/macros/spanish.dm	(revision 20131)
+++ /gsdl/stable/macros/spanish.dm	(revision 20131)
@@ -0,0 +1,793 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Spanish Language text and icon macros 
+# Translated by UNESCO for the UNESCO CD-ROMs
+# Contributions made by Jesus Tramullas
+# Translations updated by Diego Spano in May 2009
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=es] {Publicaciones periÃ³dicas}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=es] {ref. fuente: }
+_textdate_ [l=es] {fecha de publicaciÃ³n: }
+_textnumpages_ [l=es] {nÃºmero de pÃ¡ginas: }
+
+_textsignin_ [l=es] {conectarse}
+
+_textdefaultcontent_ [l=es] {La pÃ¡gina solicitada no se encontrÃ³. Por 
+favor pulse el botÃ³n "AtrÃ¡s" de su navegador o el botÃ³n 
+"Inicio" para regresar a la Biblioteca Digital Greenstone.}
+
+_textdefaulttitle_ [l=es] {Error en GSDL}
+
+_textbadcollection_ [l=es] {Esta colecciÃ³n (llamada "_cvariable_") no ha sido instalada en el sistema de esta biblioteca digital Greenstone.}
+
+_textselectpage_ [l=es] {-- Seleccionar pÃ¡gina --}
+
+_collectionextra_ [l=es] {Esta colecciÃ³n contiene _about:numdocs_ documentos. 
+La colecciÃ³n se creÃ³ hace _about:builddate_ dÃ­as.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=es] {<p>Esta colecciÃ³n contiene _numdocs_ _If_("_numdocs_" eq
+"1",documento,documentos) y un total de _numbytes_.
+<p><a href="_httppagex_(bsummary)">Pulse aquÃ­</a> para visualizar el
+informe de creaciÃ³n de esta colecciÃ³n.
+}  
+
+_textdescrcollection_ [l=es] {}
+_textdescrabout_ [l=es] {PÃ¡gina Acerca de}
+_textdescrhome_ [l=es] {PÃ¡gina Principal}
+_textdescrhelp_ [l=es] {PÃ¡gina de ayuda}
+_textdescrpref_ [l=es] {PÃ¡gina de Preferencias}
+_textdescrgreenstone_ [l=es] {Programa de la Biblioteca Digital Greenstone}
+_textdescrusab_ [l=es] {Â¿QuÃ© es lo que encontrÃ³ difÃ­cil de usar?}
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=es] {bÃºsqueda}  
+_labelSearch_ [l=es] {BÃºsqueda}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=es] {TÃ­tulo}  
+_labelTitle_ [l=es] {TÃ­tulos}  
+_textCreator_ [l=es] {Creador/Autor}  
+_labelCreator_ [l=es] {Creadores/Autores}  
+_textSubject_ [l=es] {Materia}  
+_labelSubject_ [l=es] {Temas}
+_textDescription_ [l=es] {descripciÃ³n}  
+_labelDescription_ [l=es] {DescripciÃ³nes}
+_textPublisher_ [l=es] {Editor}  
+_labelPublisher_ [l=es] {Editores}
+_textContributor_ [l=es] {Contributor}  
+_labelContributor_ [l=es] {Colaboradores}
+_textDate_ [l=es] {Fecha}  
+_labelDate_ [l=es] {Fechas}
+_textType_ [l=es] {tipo}  
+_labelType_ [l=es] {tipos}  
+_textFormat_ [l=es] {formato
+}  
+_labelFormat_ [l=es] {Formatos}
+_textIdentifier_ [l=es] {identificador}  
+_labelIdentifier_ [l=es] {Identificadores}
+_textSource_ [l=es] {nombre del fichero}  
+_labelSource_ [l=es] {Fuente}
+_textLanguage_ [l=es] {Idioma}  
+_labelLanguage_ [l=es] {Idiomas}
+_textRelation_ [l=es] {relaciÃ³n}  
+_labelRelation_ [l=es] {RelaciÃ³nes}
+_textCoverage_ [l=es] {cobertura}  
+_labelCoverage_ [l=es] {Cobertura}
+_textRights_ [l=es] {derechos}  
+_labelRights_ [l=es] {Derechos}
+
+# DLS metadata set
+_textOrganization_ [l=es] {organizaciÃ³n}  
+_labelOrganization_ [l=es] {organizaciÃ³n}  
+_textKeyword_ [l=es] {palabra clave}  
+_labelKeyword_ [l=es] {Palabras clave}
+_textHowto_ [l=es] {CÃ³mo}  
+_labelHowto_ [l=es] {CÃ³mo}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=es] {frase}  
+_labelPhrase_ [l=es] {Frases}  
+_textCollage_ [l=es] {Collage}  
+_labelCollage_ [l=es] {Collage}  
+_textBrowse_ [l=es] {navegar}  
+_labelBrowse_ [l=es] {navegar}  
+_textTo_ [l=es] {a}  
+_labelTo_ [l=es] {A}
+_textFrom_ [l=es] {desde}  
+_labelFrom_ [l=es] {De}
+_textAcronym_ [l=es] {AcrÃ³nimo}  
+_labelAcronym_ [l=es] {Siglas}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=es] {Mostrar por _1_}  
+
+_textdescrSearch_ [l=es] {Buscar tÃ©rminos especÃ­ficos}
+_textdescrType_ [l=es] {Mostrar por tipo de recurso}  
+_textdescrIdentifier_ [l=es] {Mostrar por identificador del recurso}  
+_textdescrSource_ [l=es] {Mostrar por nombre de fichero original}  
+_textdescrTo_ [l=es] {Mostrar por campo To}  
+_textdescrFrom_ [l=es] {Mostrar por campo From}  
+_textdescrCollage_ [l=es] {Mostrar mediante collage de imÃ¡genes}  
+_textdescrAcronym_ [l=es] {Mostrar acrÃ³nimos}  
+_textdescrPhrase_ [l=es] {Mostrar frases}  
+_textdescrHowto_ [l=es] {Mostrar por categorÃ­as "cÃ³mo"}  
+_textdescrBrowse_ [l=es] {Mostrar documentos}  
+_texticontext_ [l=es] {Ver el documento}
+_texticonclosedbook_ [l=es] {Abrir este documento y ver su Ã­ndice de contenido}
+_texticonnext_ [l=es] {Ir a la siguiente secciÃ³n}
+_texticonprev_ [l=es] {Ir a la secciÃ³n anterior}
+
+_texticonworld_ [l=es] {Ver el documento Web}
+
+_texticonmidi_ [l=es] {Ver el documento en el formato MIDI}
+_texticonmsword_ [l=es] {Ver el documento en el formato Microsoft Word}
+_texticonmp3_ [l=es] {Ver el documento en el formato MP3}
+_texticonpdf_ [l=es] {Ver el documento (formato PDF)}  
+_texticonps_ [l=es] {Ver el documento (formato PostScript)}  
+_texticonppt_ [l=es] {Ver el documento (formato PowerPoint)}  
+_texticonrtf_ [l=es] {Ver el documento (formato RTF)}  
+_texticonxls_ [l=es] {Ver el documento (formato Microsoft Excel)}  
+
+_page_ [l=es] {pÃ¡gina }
+_pages_ [l=es] {pÃ¡ginas}
+_of_ [l=es] {de }
+_vol_ [l=es] {Volumen}  
+_num_ [l=es] {nÃºmero}
+
+_textmonth00_ [l=es] {}
+_textmonth01_ [l=es] {enero}
+_textmonth02_ [l=es] {febrero}
+_textmonth03_ [l=es] {marzo}
+_textmonth04_ [l=es] {abril}
+_textmonth05_ [l=es] {mayo}
+_textmonth06_ [l=es] {junio}
+_textmonth07_ [l=es] {julio}
+_textmonth08_ [l=es] {agosto}
+_textmonth09_ [l=es] {septiembre}
+_textmonth10_ [l=es] {octubre}
+_textmonth11_ [l=es] {noviembre}
+_textmonth12_ [l=es] {diciembre}
+
+_texttext_ [l=es] {Texto}  
+_labeltext_ [l=es] {_texttext_}  
+_textdocument_ [l=es] {Documento}
+_textsection_ [l=es] {SecciÃ³n}
+_textparagraph_ [l=es] {PÃ¡rrafo}
+_textchapter_ [l=es] {CapÃ­tulo}  
+_textbook_ [l=es] {Libro}  
+
+_magazines_ [l=es] {Revistas}
+
+_nzdlpagefooter_ [l=es] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">Proyecto de biblioteca Digital de Nueva
+Zelandia</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Departamento de informÃ¡tica</a>, 
+<a href="http://www.waikato.ac.nz">Universidad de Waikato</a>,
+Nueva Zelandia}
+
+_linktextHOME_ [l=es] {PRINCIPAL}
+_linktextHELP_ [l=es] {AYUDA}
+_linktextPREFERENCES_ [l=es] {PREFERENCIAS}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=es] {Biblioteca Digital Greenstone}
+
+_textnocollections_ [l=es] {No hay colecciones vÃ¡lidas disponibles (ej. construÃ­das y publicadas)}  
+
+_textadmin_ [l=es] {PÃ¡gina de administraciÃ³n}
+_textabgs_ [l=es] {Acerca de Greenstone}
+_textgsdocs_ [l=es] {DocumentaciÃ³n de Greenstone}
+
+_textdescradmin_ [l=es] {Le permite aÃ±adir nuevos usuarios, da un resumen de las colecciones que
+hay en el sistema y proporciona informaciones tÃ©cnicas sobre la
+instalaciÃ³n de Greenstone
+}
+
+_textdescrgogreenstone_ [l=es] {Le proporciona informaciÃ³n sobre el software Greenstone y el proyecto de
+Biblioteca Digital de Nueva Zelandia, de donde proviene
+}
+
+_textdescrgodocs_ [l=es] {Manuales de Greenstone}
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=es] {Interfaz de la Biblioteca Digital Greenstone}
+_textdescrgli_ [l=es] {Le ayuda a crear nuevas colecciones, modificar o suprimir colecciones
+existentes, o aÃ±adir documentos a una colecciÃ³n.
+}
+
+package collector
+
+_textcollector_ [l=es] {El Colector}
+_textdescrcollector_ [l=es] {Aunque este programa de recopilaciÃ³n antecede a la interfaz de la biblioteca digital, para fines prÃ¡cticos se recomienda usar esta Ãºltima en lugar del Colector. }  
+
+package depositor
+
+_textdepositor_ [l=es] {El Acumulador}  
+_textdescrdepositor_ [l=es] {Lo ayuda a agregar documentos a las colecciones existentes.
+}  
+
+package gti
+
+_textgti_ [l=es] {Interfaz de TraducciÃ³n de Greenstone}  
+_textdescrtranslator_ [l=es] {Le ayuda a mantener actualizadas las versiones en varias lenguas de la interfaz Greenstone.}
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=es] {Acerca de esta colecciÃ³n}
+
+_textsubcols1_ [l=es] {<p>La colecciÃ³n completa comprende _1_ subcolecciones: 
+<blockquote>}
+
+_textsubcols2_ [l=es] {</blockquote>
+Usted puede verificar (y modificar) las subcolecciones que estÃ¡ usando  
+actualmente en la pÃ¡gina de Preferencias.}
+
+_titleabout_ [l=es] {acerca de}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=es] {cerrar esta secciÃ³n de la biblioteca}
+_texticonclosedbookshelf_ [l=es] {abrir esta secciÃ³n de la biblioteca y ver su contenido}
+_texticonopenbook_ [l=es] {cerrar este libro}
+_texticonclosedfolder_ [l=es] {Abrir esta carpeta y ver su contenido}
+_texticonclosedfolder2_ [l=es] {abrir subsecciÃ³n: }
+_texticonopenfolder_ [l=es] {cerrar esta carpeta}
+_texticonopenfolder2_ [l=es] {cerrar subsecciÃ³n: }
+_texticonsmalltext_ [l=es] {Ver esta secciÃ³n del texto}
+_texticonsmalltext2_ [l=es] {ver texto: }
+_texticonpointer_ [l=es] {secciÃ³n en curso}
+_texticondetach_ [l=es] {Abrir esta pÃ¡gina en una nueva ventana}
+_texticonhighlight_ [l=es] {Resaltar los tÃ©rminos de la bÃºsqueda}
+_texticonnohighlight_ [l=es] {No resaltar los tÃ©rminos de la bÃºsqueda}
+_texticoncontracttoc_ [l=es] {Contraer el Ã­ndice de contenido}
+_texticonexpandtoc_ [l=es] {Expandir el Ã­ndice de contenido}
+_texticonexpandtext_ [l=es] {Mostrar el texto completo}
+_texticoncontracttext_ [l=es] {Mostrar Ãºnicamente el texto de la secciÃ³n seleccionada}
+_texticonwarning_ [l=es] {<b>Advertencia: </b>}
+_texticoncont_ [l=es] {Â¿desea continuar?}
+
+_textltwarning_ [l=es] {<div class="buttons">_imagecont_</div>
+_iconwarning_Expandir el texto aquÃ­ generarÃ¡ una gran
+cantidad de datos que su navegador deberÃ¡ procesar
+}
+
+_textgoto_ [l=es] {ir a la pÃ¡gina}
+_textintro_ [l=es] {<i>(texto inicial)</i>}
+
+_textCONTINUE_ [l=es] {Â¿DESEA CONTINUAR???}
+
+_textEXPANDTEXT_ [l=es] {EXPANDIR TEXTO}  
+
+_textCONTRACTCONTENTS_ [l=es] {CONTRAER CONTENIDOS}  
+
+_textDETACH_ [l=es] {SEPARAR}
+
+_textEXPANDCONTENTS_ [l=es] {EXPANDIR CONTENIDOS}  
+
+_textCONTRACT_ [l=es] {CONTRAER TEXTO}  
+
+_textHIGHLIGHT_ [l=es] {RESALTAR}  
+
+_textNOHIGHLIGHT_ [l=es] {NO RESALTAR}  
+
+_textPRINT_ [l=es] {IMPRIMIR}  
+
+_textnextsearchresult_ [l=es] {prÃ³ximo resultado de la bÃºsqueda}  
+_textprevsearchresult_ [l=es] {resultado previo de la bÃºsqueda}  
+
+# macros for printing page
+_textreturnoriginal_ [l=es] {Volver a la pÃ¡gina original}  
+_textprintpage_ [l=es] {Imprimir esta pÃ¡gina}  
+_textshowcontents_ [l=es] {Mostrar tabla de contenidos}  
+_texthidecontents_ [l=es] {Ocultar la tabla de contenidos}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=es] {_If_(_thislast_,resultados _thisfirst_ - _thislast_ para la consulta:_cgiargq_,No se encontraron resultados correspondientes a  la consulta: _cgiargq_)}
+_textnoquerytitle_ [l=es] {PÃ¡gina de bÃºsqueda}
+
+_textsome_ [l=es] {algunas de}
+_textall_ [l=es] {todas}
+_textboolean_ [l=es] {booleano}
+_textranked_ [l=es] {clasificado}
+_textnatural_ [l=es] {natural}
+_textsortbyrank_ [l=es] {rango de relevancia}  
+_texticonsearchhistorybar_ [l=es] {historial de bÃºsquedas}
+
+_textifeellucky_ [l=es] {Voy a tener suerte!}
+
+#alt text for query buttons
+_textusequery_ [l=es] {utilizar esta consulta}
+_textfreqmsg1_ [l=es] {Palabras contadas: }
+_textpostprocess_ [l=es] {_If_(_quotedquery_,<br><i>postprocesado para encontrar _quotedquery_</i>
+)}
+_textinvalidquery_ [l=es] {La sintaxis de la consulta no es vÃ¡lida}
+_textstopwordsmsg_ [l=es] {Las siguientes palabras son demasiadas comunes y serÃ¡n ignoradas:}  
+_textlucenetoomanyclauses_ [l=es] {Su bÃºsqueda contiene demasiados tÃ©rminos; por favor, pruebe una consulta mÃ¡s especÃ­fica.}  
+
+_textmorethan_ [l=es] {MÃ¡s que}
+_textapprox_ [l=es] {Acerca de }
+_textnodocs_ [l=es] {No hay documentos que correspondan a la consulta.}
+_text1doc_ [l=es] {1 documento corresponde a la consulta.}
+_textlotsdocs_ [l=es] {documentos corresponden a la consulta.}
+_textmatches_ [l=es] {Resultados }
+_textbeginsearch_ [l=es] {Iniciar la bÃºsqueda}
+_textrunquery_ [l=es] {Ejecutar la bÃºsqueda}  
+_textclearform_ [l=es] {Borrar el formulario}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=es] {Palabras}  
+_textinfield_ [l=es] {... en el campo}  
+_textfoldstem_ [l=es] {(mayÃºsculas y minÃºsculas, terminaciones de palabras)}  
+
+_textadvquery_ [l=es] {O escriba directamente una consulta:}  
+_textallfields_ [l=es] {todos los campos}  
+_texttextonly_ [l=es] {sÃ³lo texto
+}
+_textand_ [l=es] {y}  
+_textor_ [l=es] {o}  
+_textandnot_ [l=es] {y no}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+# the space after "level" (before the right bracket) is required, otherwise no space between "Search" and "in"
+
+_textsimplesearch_ [l=es] {Buscar en _indexselection__If_(_jselection_, asociada con _jselection_)_If_(_gselection_, a nivel de _gselection_)_If_(_nselection_, en idioma _nselection_) _allowformbreak_ que contenga  _querytypeselection_ de las palabras _If_(_sfselection_,\,_allowformbreak_ ordenando los resultados por _sfselection_)
+}  
+
+_textadvancedsearch_ [l=es] {Buscar en _indexselection__If_(_jselection_, asociada con _jselection_)_If_(_gselection_, a nivel de _gselection_)_If_(_nselection_, en idioma _nselection_ ) usando el tipo de consulta _querytypeselection_}  
+
+_textadvancedmgppsearch_ [l=es] {Buscar en _indexselection__If_(_jselection_, asociado con _jselection_)_If_(_gselection_, a nivel de _gselection_)_If_(_nselection_, en idioma _nselection_ ), y mostrar los resultados ordenados por _formquerytypeadvancedselection_}  
+
+_textadvancedlucenesearch_ [l=es] {Buscar en _indexselection__If_(_jselection_, asociado con _jselection_)_If_(_gselection_, a nivel de _gselection_ )_If_(_nselection_, en idioma _nselection_ )_If_(_sfselection_,\,_allowformbreak_ ordenando los resultados por _sfselection_\,)}  
+
+# the space after "Search" is required, otherwise no space between "Search" and "in"
+
+_textformsimplesearch_ [l=es] {Buscar_If_(_jselection_, en _jselection_)_If_(_gformselection_, a nivel de _gformselection_)_If_(_nselection_, en idioma  _nselection_ )_If_(_sfselection_,\, ordenando los resultados por _sfselection_\,) para _formquerytypesimpleselection_ }  
+
+_textformadvancedsearchmgpp_ [l=es] {Buscar _If_(_jselection_, en _jselection_)_If_(_gformselection_, a nivel de _gformselection_)_If_(_nselection_, en idioma _nselection_), y mostrar los resultados en orden _formquerytypeadvancedselection_}  
+
+_textformadvancedsearchlucene_ [l=es] {Buscar_If_(_jselection_, en _jselection_)_If_(_gformselection_, a nivel de _gformselection_)_If_(_nselection_, en idioma _nselection_ )_If_(_sfselection_,\, ordenando los resultados por _sfselection_\,)}  
+
+_textnojsformwarning_ [l=es] {Advertencia: Javascript no estÃ¡ habilitado en su navegador. <br>Para usar la bÃºsqueda de formas, por favor habilÃ­telo.}
+_textdatesearch_ [l=es] {<p>Se pueden buscar en esta colecciÃ³n
+documentos comprendidos en un intervalo de fechas, o documentos que
+contengan una fecha en particular. Ãsta es una caracterÃ­stica
+facultativa de la bÃºsqueda.}
+_textstartdate_ [l=es] {Fecha inicial (o Ãºnica):}
+_textenddate_ [l=es] {Fecha final:}
+_textbc_ [l=es] {antes de nuestra era}
+_textad_ [l=es] {de nuestra era}
+_textexplaineras_ [l=es] {Â«de nuestra eraÂ» y Â«antes de nuestra eraÂ» son
+formas alternativas de expresar Â«despuÃ©s de JesucristoÂ» y Â«antes de
+JesucristoÂ», respectivamente. Son expresiones con menos connotaciones
+culturales.}  
+
+_textstemon_ [l=es] {(ignorar las terminaciones de las palabras)}
+
+_textsearchhistory_ [l=es] {historial de bÃºsquedas}
+
+#text macros for search history
+_textnohistory_ [l=es] {No estÃ¡ disponible el historial de bÃºsquedas
+}
+_texthresult_ [l=es] {resultado}
+_texthresults_ [l=es] {resultados}
+_texthallwords_ [l=es] {todas las palabras}
+_texthsomewords_ [l=es] {algunas palabras}
+_texthboolean_ [l=es] {booleano}
+_texthranked_ [l=es] {clasificado}
+_texthcaseon_ [l=es] {tener en cuenta mayÃºsculas y minÃºsculas}
+_texthcaseoff_ [l=es] {no tener en cuenta mayÃºsculas y minÃºsculas}
+_texthstemon_ [l=es] {no tener en cuenta las terminaciones de las palabras}
+_texthstemoff_ [l=es] {tener en cuenta las terminaciones de las palabras}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=es] {Las preferencias se han fijado de la siguiente manera. Â¡No pulse el
+botÃ³n Â«AtrÃ¡sÂ» de su navegador, pues eso harÃ­a que no quedaran grabadas!
+Utilice mÃ¡s bien uno de los botones de la barra de acceso que aparece
+mÃ¡s arriba.
+
+}
+_textsetprefs_ [l=es] {fijar preferencias}
+_textsearchprefs_ [l=es] {Preferencias de bÃºsqueda}
+_textcollectionprefs_ [l=es] {Preferencias de colecciÃ³n}
+_textpresentationprefs_ [l=es] {Preferencias de presentaciÃ³n}
+_textpreferences_ [l=es] {Preferencias}
+_textcasediffs_ [l=es] {Reconocimiento de mayÃºsculas y minÃºsculas:}
+_textignorecase_ [l=es] {ignorar diferencias entre mayÃºsculas y minÃºsculas}  
+_textmatchcase_ [l=es] {deben corresponder mayÃºsculas y minÃºsculas}  
+_textwordends_ [l=es] {Terminaciones de las palabras:}  
+_textstem_ [l=es] {ignorar las terminaciones de las palabras}  
+_textnostem_ [l=es] {debe coincidir la palabra completa}  
+_textaccentdiffs_ [l=es] {Diferencias de acentos;}  
+_textignoreaccents_ [l=es] {ignorar acentos}  
+_textmatchaccents_ [l=es] {las tildes deben coincidir}  
+
+_textprefop_ [l=es] {Presentar hasta _maxdocoption_ resultados con _hitsperpageoption_ resultados por pÃ¡gina.}
+_textextlink_ [l=es] {Acceder a pÃ¡ginas Web externas: }
+_textintlink_ [l=es] {Documentos fuente recuperados de:}
+_textlanguage_ [l=es] {Idioma de la interfaz: }  
+_textencoding_ [l=es] {CodificaciÃ³n: }
+_textformat_ [l=es] {Formato de la interfaz: }  
+_textall_ [l=es] {todos}
+_textquerymode_ [l=es] {Modo de bÃºsqueda:}  
+_textsimplemode_ [l=es] {modo de bÃºsqueda simple}  
+_textadvancedmode_ [l=es] {bÃºsqueda avanzada (permite efectuar bÃºsquedas booleanas utilizando los caracteres !, &, | y los parÃ©ntesis)}  
+_textlinkinterm_ [l=es] {a travÃ©s de una pÃ¡gina intermedia}
+_textlinkdirect_ [l=es] {ir directamente ahÃ­}
+_textdigitlib_ [l=es] {la biblioteca digital}
+_textweb_ [l=es] {la red mundial (web)}
+_textgraphical_ [l=es] {GrÃ¡fico}
+_texttextual_ [l=es] {Textual}
+_textcollectionoption_ [l=es] {<p>
+Subcolecciones por incluir:
+<br>}
+
+_textsearchtype_ [l=es] {Estilo de bÃºsqueda:}  
+_textformsearchtype_ [l=es] {con campos _formnumfieldoption_ fields}  
+_textplainsearchtype_ [l=es] {normal con caja _boxsizeoption_ query}  
+_textregularbox_ [l=es] {lÃ­nea simple}  
+_textlargebox_ [l=es] {amplio}  
+
+_textrelateddocdisplay_ [l=es] {mostrar documentos conexos }
+_textsearchhistory_ [l=es] {Historial de bÃºsquedas:}  
+_textnohistory_ [l=es] {No hay historial de bÃºsquedas}  
+_texthistorydisplay_ [l=es] {mostrar _historynumrecords_ registros del histÃ³rico de bÃºsquedas}  
+_textnohistorydisplay_ [l=es] {no mostrar el historial de bÃºsquedas }  
+
+_textbookoption_ [l=es] {Modo Visualizador de libro:}  
+_textbookvieweron_ [l=es] {si
+}  
+_textbookvieweroff_ [l=es] {no}  
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=es] {Ordenar los documentos por}
+_textalsoshowing_ [l=es] {muestra tambiÃ©n}
+_textwith_ [l=es] {con un mÃ¡ximo de}
+_textdocsperpage_ [l=es] {documentos por pÃ¡gina}
+
+_textfilterby_ [l=es] {Buscar documentos que contengan}
+_textall_ [l=es] {todas}
+_textany_ [l=es] {algunas de}
+_textwords_ [l=es] {las palabras}
+_textleaveblank_ [l=es] {dejar este cuadro vacÃ­o para obtener todos los documentos}  
+
+_browsebuttontext_ [l=es] {"Ordenar los documentos"}
+
+_nodata_ [l=es] {<i>no datos</i>}
+_docs_ [l=es] {documentos}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=es] {Ayuda}
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=es] {mostrar documentos por _1_ pulsando el botÃ³n _2_}  
+
+_textSearchhelp_ [l=es] {buscar por palabras determinadas que aparecen en el texto pulsando el botÃ³n _labelSearch_}  
+_textTohelp_ [l=es] {mostrar documentos por el campo To pulsando el botÃ³n _labelTo_}  
+_textFromhelp_ [l=es] {mostrar publicaciones por el campo From pulsando el botÃ³n _labelFrom_}  
+_textBrowsehelp_ [l=es] {manejar documentos}  
+_textAcronymhelp_ [l=es] {navegar por documentos por la ocurrencia de un acrÃ³nimo pulsando en el botÃ³n _labelAcronym_}  
+_textPhrasehelp_ [l=es] {buscar frases contenidas en los documentos pulsando el botÃ³n _labelPhrase_. Utiliza el buscador de frases.}  
+
+_texthelptopicstitle_ [l=es] {Temas}
+
+_textreadingdocs_ [l=es] {Â¿CÃ³mo leer los documentos?}
+
+_texthelpreadingdocs_ [l=es] {<p>Puede decir que ha llegado a un libro o documento individual cuando en la parte superior izquierda visualice el tÃ­tulo o una imagen de la portada. En algunas colecciones, aparece una tabla de contenidos, mientras que en otras (por ejemplo, cuando se utiliza la opciÃ³n "paged images" -imÃ¡genes paginadas-) solo se muestra el nÃºmero de pÃ¡gina, junto a un recuadro que permite seleccionar el nÃºmero de pÃ¡gina a la cual acceder y flechas para acceder a la pÃ¡gina anterior y posterior. En la tabla de contenidos, el encabezado de la secciÃ³n actual estÃ¡ en letra negrita y la tabla es expandible -- haga click en las carpetas para abrir o cerrar las secciones, haga click en el libro abierto paraa cerrarlo.</p>
+
+<p>En la parte inferior estÃ¡ el texto de la secciÃ³n actual. Cuando la haya leÃ­do, hay flechas en la parte de abajo que lo llevan a la siguiente secciÃ³n o a la anterior.</p>
+
+<p>Abajo del tÃ­tulo o de la imagen de portada hay algunos botones. Haga Click en  <i>_document:textEXPANDTEXT_</i> para expandir el texto completo de la secciÃ³n actual o del libro. Si el documento es muy largo, esto puede llevar un largo tiempo y usar mucha memoria. Haga Click en <i>_document:textEXPANDCONTENTS_</i> para reducir la tabla de contenidos completa de forma tal que pueda ver los tÃ­tulos de todos los capÃ­tulos y subsecciones. Haga Click en <i>_document:textDETACH_</i> para abrir en una nueva ventana del navegador el documento seleccionado. (Esto es util si se quiere comparar documentos o leer dos a la vez). Finalmente, cuando hace una bÃºsqueda, las palabras son resaltadas. Haga Click en <i>_document:textNOHIGHLIGHT_</i> para remover el resaltado.</p>
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=es] {Abrir este estante}
+_texthelpopenbook_ [l=es] {Abrir/cerrar este libro}
+_texthelpviewtextsection_ [l=es] {Ver esta parte del texto}
+_texthelpexpandtext_ [l=es] {Mostrar/No mostrar el texto completo}
+_texthelpexpandcontents_ [l=es] {Mostrar/No mostrar la tabla de contenidos}
+_texthelpdetachpage_ [l=es] {Abrir esta pÃ¡gina en una nueva ventana}
+_texthelphighlight_ [l=es] {Resaltar/No resaltar los tÃ©rminos de la bÃºsqueda}
+_texthelpsectionarrows_ [l=es] {Vaya a la secciÃ³n anterior/proxima secciÃ³n}  
+
+
+_texthelpsearchingtitle_ [l=es] {Â¿CÃ³mo buscar determinadas palabras?}
+
+_texthelpsearching_ [l=es] {<p>
+Desde la pÃ¡gina de bÃºsqueda, se puede hacer una consulta siguiendo estos pasos:<p>
+
+  <ol><li>Especifique los items que quiere buscar.
+      <li>Indicar si se quiere buscar por todos o alguno de los tÃ©rminos
+      <li>Escriba las palabras que buscar
+      <li>Haga Click en el botÃ³n <i>Iniciar la bÃºsqueda</i>
+  </ol>
+
+<p>Cuando hace la consulta, se muestran los tÃ­tulos de 20 documentos coincidentes.
+Existe un botÃ³n al final que permite acceder al siguiente grupo de 20 documentos. Desde ahi, habrÃ¡ botones que permitirÃ¡n moverse hacia el grupo siguiente o el anterior.
+
+<p>Un mÃ¡ximo de 50 es el lÃ­mite impuesto para la cantidad de documentos retornados. Este nÃºmero puede cambiarse accediendo a <i>_Global:linktextPREFERENCES_</i> en la parte superior de la pÃ¡gina.<p>}  
+
+_texthelpquerytermstitle_ [l=es] {TÃ©rminos de la bÃºsqueda}
+_texthelpqueryterms_ [l=es] {<p>Cualquier cosa que se ingrese en el recuadro de bÃºsqueda es interpretada como una lista de palabras o frases llamada "tÃ©rminos de bÃºsqueda". Un tÃ©rmino es una palabra simple conteniendo solo letras y dÃ­gitos, o una frase consistente en una secuencia de palabras encerradas entre comillas dobles ("...") Los tÃ©rminos estÃ¡n separados por espacios en blanco. Si apareciera cualquier otro caracter, como por ejemplo, simbolos de puntuaciÃ³n, sirven tambiÃ©n como separadores, al igual que los espacio blancos y son ignorados. No pueden buscarse palabras que incluyan signos de puntuaciÃ³n.
+
+<p>For example, the query<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>will be treated the same as<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}  
+
+_texthelpmgppsearching_ [l=es] {Para colecciones construÃ­das con MGPP estÃ¡n disponibles algunas oopciones mÃ¡s.
+
+<ul>
+<li>Un <b>*</b> al final de un tÃ©rmino de bÃºsqueda recupera todas las palabras que <b>comiencen con </b> ese tÃ©rmino. <b>comput*</b> recupera todas las palabras que comiencen por <b>comput</b>.
+<li><b>/x</b> puede usarse para dar mÃ¡s peso a uno o mÃ¡s de los tÃ©rminos de la bÃºsqueda, por ej. <b>computador/10 ciencia</b> da a computador 10 veces mÃ¡s peso que a ciencia cuando se ordenan por relevancia los documentos.
+</ul>}  
+
+_texthelplucenesearching_ [l=es] {Para colecciones construidas con Lucene son disponibles varias opciones.
+
+<ul>
+<li><b>?</b> puede ser usada como un comodÃ­n en vez de un simple letra. Por ejemplo, <b>b?t</b> corresponderÃ¡ <b>bet</b>, <b>bit</b> y <b>bat</b> etc.
+<li><b>*</b> puede ser usado como un comodÃ­n en el lugar de mÃºltiples letras. Por ejemplo, <b>comput*</b> corresponderÃ¡ todas las palabras que empiecen por <b>comput</b>.
+</ul>
+Ambos comodines puedes ser usados en la mitad de una palabra, o al final. No pueden ser usados en el comienzo de la misma.
+
+}  
+
+_texthelpquerytypetitle_ [l=es] {Tipo de consulta}
+_texthelpquerytype_ [l=es] {<p>Existen dos tipos de consulta.
+
+<ul>
+
+<li>BÃºsqueda de <b>todas</b> las palabras. Se buscan los documentos (o capÃ­tulos o tÃ­tulos) que contienen todas las palabras especificadas. Los documentos que responden
+a la consulta se presentan por orden de construcciÃ³n.
+
+<li>BÃºsqueda de <b>alguna(s)</b> palabra(s). Basta con enumerar los
+tÃ©rminos que pueden aparecer en los documentos buscados. Los documentos
+aparecerÃ¡n en un orden que corresponde a su grado de relevancia con
+respecto a la consulta. Para determinar el grado de relevancia, se
+aplican los criterios siguientes:
+
+<ul>
+
+<li>cuantos mÃ¡s tÃ©rminos buscados contenga el documento, mayor serÃ¡ su
+relevancia;
+
+<li>los tÃ©rminos poco usuales se considerarÃ¡n mÃ¡s importantes que los
+comunes;
+
+<li>los documentos mÃ¡s cortos se considerarÃ¡n mÃ¡s relevantes que los
+documentos mÃ¡s largos.
+
+</ul>
+
+</ul>
+
+<p>Puede utilizar tantos tÃ©rminos de bÃºsqueda como desee: una oraciÃ³n
+completa, o incluso un pÃ¡rrafo entero.  Si sÃ³lo se especifica un
+tÃ©rmino, los documentos se ordenarÃ¡n por frecuencia de apariciÃ³n del
+tÃ©rmino buscado.
+}  
+
+_texthelpadvancedsearchtitle_ [l=es] {BÃºsqueda avanzada usando el motor _1_ search}  
+
+_texthelpadvancedsearch_ [l=es] {<p>Si ha seleccionado el modo de bÃºsqueda avanzada (en Preferencias) puede tener opciones de bÃºsqueda ligeramente diferentes.
+}  
+
+_texthelpadvsearchmg_ [l=es] {Las bÃºsquedas avanzadas en colecciones MG ofrecen dos opciones, ordenadas o booleanas. Una bÃºsqueda <b>ordenada</b> es exactamente los mismo que <b>algunas</b> bÃºsquedas descritas en <a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_
+}  
+
+_texthelpbooleansearch_ [l=es] {Una bÃºsqueda <b>booleana</b> le permite combinar tÃ©rminos usando & (por "y"), | (por "o"), y ! (por "no"), usando parÃ©ntesis si es necesario. El operador predefinido es | (por "o").<p>
+Por ejemplo, <b>caracol & cultivo</b> recuperarÃ¡ documentos que contengan ambas palabras <b>caracol</b> Y <b>cultivo</b>, mientras que <b>caracol | cultivo</b> recuperarÃ¡ documentos que contengan <b>caracol</b> O <b>cultivo</b>.
+<b>caracol !cultivo</b> recuperarÃ¡ documentos que contengan <b>caracol</b> Y NO contengan <b>cultivo</b>.
+<p>
+Se pueden especificar bÃºsquedas mÃ¡s precisas usando combinaciones de operadores y parÃ©ntesis. Por ejemplo, <b>(oveja | ganado) & (granja | estaciÃ³n)</b>, o <b>oveja | ganado | cabra !cerdo</b>.
+}  
+
+_texthelpadvsearchmgpp_ [l=es] {Las bÃºsquedas avanzadas en colecciones MGPP usan operadores booleanos (lÃ³gicos) . _texthelpbooleansearch_
+<p>Los resultados pueden mostrarse en orden <b>de ranking</b> como en <a href="\#query-type">_texthelpquerytypetitle_</a>, o en orden <b>natural</b>. Este Ãºltimo es el orden en el cual fueron procesados los documentos durante la creaciÃ³n de la colecciÃ³n.
+<p>
+Otros operadores incluyen <b>NEARx</b> y <b>WITHINx</b>.
+NEARx se utiliza para especificar la distancia mÃ¡xima (x palabras) que pueden separar 2 tÃ©rminos para que un documento encaje dentro de los resultados de la consulta.
+WITHINx especifica que el segundo tÃ©rmino debe aparecer dentro de x palabras <i>despuÃ©s</i> del primer tÃ©rmino. Este es similar al NEAR pero el ORDEN es importante. La distancia por defecto es 20.
+}  
+
+_texthelpadvancedsearchextra_ [l=es] {NOTA: estos operadores se ignorarÃ¡n se se busca en modo de bÃºsqueda simple}  
+
+_texthelpadvsearchlucene_ [l=es] {Las bÃºsquedas avanzadas en colecciones con Lucene usan operadores booleanos. _texthelpbooleansearch_}  
+
+_texthelpformsearchtitle_ [l=es] {BÃºsqueda con campos}  
+
+_texthelpformsearch_ [l=es] {<p>La bÃºsqueda por campos ofrece la posibilidad de combinar bÃºsquedas en varios campos. Por ejemplo, uno puede buscar "Smith" en TÃ­tulo Y "snail farming" en Tema. En modo de bÃºsqeuda simple, cada lÃ­nea del formulario se comporta como una lÃ­nea normal de bÃºsqueda. las lÃ­neas individuales del formulario se combinan usando Y (para una bÃºsqueda de "todo"), u O (para una bÃºsqeuda de "algo"). Los tÃ©rminos dentro de los campos se combinan de la misma forma. En el modo avanzado, puede especificar diferentes combinaciones de Y/O/NO entre los campos, usando las listas desplegables, y dentro de un campo puede usar operadores booleanos.}  
+
+_texthelpformstemming_ [l=es] {Los cuadros "may./min." y "truncamiento" le permiten indicar si los tÃ©rminos dentro de ese campo deben estar en mayÃºsculas/minÃºsculas o truncados. Ambos estÃ¡n dasactivados previamente en el formuario de bÃºsqueda avanzada.}  
+
+_textdatesearch_ [l=es] {Buscar con fechas}  
+
+_texthelpdatesearch_ [l=es] {La bÃºsqueda por fecha le permite encontrar documentos que, ademÃ¡s de corresponder a los criterios de bÃºsqueda, se refieren a acontecimientos situados dentro de un intervalo de tiempo determinado. Se pueden buscar documentos relativos a un aÃ±o en particular o comprendidos dentro de un nÃºmero determinado de aÃ±os. Recuerde que no es estrictamente necesario proporcionar tÃ©rminos de bÃºsqueda, sino que tambiÃ©n se puede buscar Ãºnicamente por fecha. Tampoco es preciso indicar las fechas de la bÃºsqueda: si no escribe ninguna fecha es como si no existiera la bÃºsqueda por fecha.<p>
+}
+
+_texthelpdatehowtotitle_ [l=es] {CÃ³mo utilizar esta funciÃ³n:}
+_texthelpdatehowto_ [l=es] {<ul>
+   <li>Para buscar documentos referentes a un aÃ±o en particular:<p>
+   <ul>
+       <li>Escriba los tÃ©rminos de la bÃºsqueda como de costumbre.
+       <li>Escriba el aÃ±o en el cuadro "Fecha inicial (o Ãºnica)".
+       <li>Si la fecha es anterior a nuestra era (antes de Cristo),  
+           elija la opciÃ³n "a.C." en el menÃº situado a un lado de ese cuadro.
+       <li>Inicie la bÃºsqueda como de costumbre.
+   </ul>
+<p><li>Para buscar documentos referentes a un periodo de tiempo o un nÃºmero de aÃ±os en particular:<p>
+   <ul>
+       <li>Escriba los tÃ©rminos de la bÃºsqueda como de costumbre.
+       <li>Escriba la fecha anterior en el cuadro "Fecha inicial (o Ãºnica)".
+       <li>Escriba la fecha posterior en el cuadro "Fecha final".
+       <li>Seleccione la opciÃ³n "a.C." en el menÃº situado a un lado del cuadro donde  
+           se haya escrito cualquier fecha anterior a nuestra era (antes de Cristo).
+       <li>Inicie la bÃºsqueda como de costumbre.
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=es] {Como interpretar los resultados de su bÃºsqueda}
+_texthelpdateresults_ [l=es] {Por lo general una bÃºsqueda de documentos referentes al aÃ±o 1903 no permitirÃ¡ obtener documentos que, por ejemplo, tratan de libros escritos en 1903, sino sÃ³lo documentos referentes al aÃ±o 1903.  Sin embargo, dada la manera en que se buscan las fechas de los documentos, se obtendrÃ¡n documentos referentes a un intervalo de tiempo (por ejemplo 1899-1911) que comprenda el aÃ±o 1903, asÃ­ como los documentos que citan en su texto el siglo al que pertenece el aÃ±o 1903 (por ejemplo siglo XX o siglo veinte).  Esto significa que para algunos documentos las fechas indicadas en la bÃºsqueda no aparecerÃ¡n realmente en el texto del documento. En el caso de una bÃºsqueda por intervalo de tiempo, todo lo anterior se aplica a cada fecha del intervalo.<p>
+}
+
+_textchangeprefs_ [l=es] {Cambio de preferencias}
+
+_texthelppreferences_ [l=es] {<p>Pulse el botÃ³n <i>_Global:linktextPREFERENCES_</i>, situado en la parte superior de la pÃ¡gina, para cambiar algunas caracterÃ­sticas de la interface y que se ajusten mejor a sus necesidades.
+}  
+
+_texthelpcollectionprefstitle_ [l=es] {Preferencias de colecciÃ³n}
+_texthelpcollectionprefs_ [l=es] {<p>
+Algunas colecciones se componen de varias subcolecciones, en las que se pueden buscar independientemente, o en su conjunto, como un todo. Si lo desea, puede usted seleccionar en la pÃ¡gina de <i>Preferencias</i> quÃ© subcolecciones incluir en sus
+bÃºsquedas.
+}  
+
+_texthelplanguageprefstitle_ [l=es] {Preferencias de lengua}
+_texthelplanguageprefs_ [l=es] {<p>Cada colecciÃ³n tiene una lengua de presentaciÃ³n predefinido, pero si
+lo desea puede usted cambiar de idioma. Puede usted modificar tambiÃ©n el
+sistema de codificaciÃ³n que utiliza Greentone para los navegadores: el software
+suele escoger los parÃ¡metros por defecto, pero con algunos navegadores
+se pueden conseguir mejores resultados grÃ¡ficos cambiando de sistema de
+codificaciÃ³n. En todas las colecciones se puede cambiar entre una
+interfaz grÃ¡fica normalizada y una interfaz textual. Ãsta resulta
+particularmente Ãºtil para los usuarios con problemas de vista que
+utilizan tipos de letra grandes o para la salida a sintetizadores
+de voz.
+}  
+
+_texthelppresentationprefstitle_ [l=es] {Preferencias de presentaciÃ³n}
+_texthelppresentationprefs_ [l=es] {Dependiendo de la colecciÃ³n en particular, existen muchas opciones que pueden configurarse para controlar la presentaciÃ³n.
+
+<p>Colecciones de pÃ¡ginas web permiten suprimir la barra de navegaciÃ³n de Greenstone al tope de cada pÃ¡gina de documento, de manera tal que una vez que se haya hecho una bÃºsqueda se derive directamente a la pÃ¡gina web exacta sin ningÃºn encabezado de Greenstone. Para hacer otra bÃºsqueda se debe usar el botÃ³n "AtrÃ¡s" del navegador.  Estas colecciones tambiÃ©n permiten suprimir los mensajes de aviso de Greenstone cuando el usuario selecciona un link que lo lleva afuera de la colecciÃ³n de la biblioteca digital, a la web misma. En otros casos de colecciones web puede controlarse si los enlaces de los resultados de bÃºsqueda lo llevan a la URL actual en vez de a la copia existente en la biblioteca digital.
+}  
+
+_texthelpsearchprefstitle_ [l=es] {Preferencias de bÃºsqueda}
+_texthelpsearchprefs_ [l=es] {<p>Puede cambiar al modo de bÃºsqueda avanzado, que le permite combinar tÃ©rminos usando & (por "Y"), | (por "O"), y ! (por "NO"), y parÃ©ntesis para agurparlos si lo desea. Esto permite formular consultas mÃ¡s especÃ­ficas.
+<p>_selectsearchtypeprefs_
+<p>_selectwordmodificationprefs_
+<p>Puede activar la caracterÃ­stica de histÃ³rico de bÃºsqueda, que le mostrarÃ¡ las Ãºltimas bÃºsquedas. Esto hace mÃ¡s sencillo ejecutar versiones modificadas de bÃºsquedas previas.
+<p>Por Ãºltimo, se puede controlar el nÃºmero respuestas obtenidas y el nÃºmero de las mismas que se muestra en cada pantalla.
+
+}  
+
+_textcasefoldprefs_ [l=es] {Un par de botnoes controlan la conincidencia con mayÃºsculas y minÃºsculas cuando se busca. Por ejemplo, si se selecciona "_preferences:textignorecase_", <i>snail farming</i> se tratarÃ¡ igual que<i>Snail Farming</i> y que <i>SNAIL FARMING</i>.}  
+_textstemprefs_ [l=es] {Un par de botones que controlan si se ignora o no la terminaciÃ³n de los tÃ©rminos cuando se busca. Por ejemplo, si se selecciona "_preferences:textstem_" <i>snail farming</i> se tratarÃ¡ igual que <i>snails farm</i> y que <i>snail farmer</i>. Actualmente sÃ³lo funciona correctamente para textos ingleses. _selectstemoptionsprefs}  
+_textaccentfoldprefs_ [l=es] {Un par de botones controlan que coincidan las letras con tilde o sin tilde durante la bÃºsqueda. Por ejemplo, si se selecciona <i>fÃ©dÃ©ration</i> se tratarÃ¡ igual que <i>fedÃ©ration</i> y que <i>federation</i>.}  
+ 
+_textstemoptionsprefs_ [l=es] {Puede ser conveniente y preciso usar la posibilidad de truncar tÃ©rminos descrita en "_texthelpquerytermstitle_".}  
+
+_textsearchtypeprefsplain_ [l=es] {Es posible disponer de un campo de interrogaciÃ³n mÃ¡s amplio, para poder formular fÃ¡cilmente bÃºsqueda de pÃ¡rrafos. Es sorprendentemente rÃ¡pido buscar grandes cantidades de texto.}  
+
+_textsearchtypeprefsform_ [l=es] {Puede cambiar el nÃºmero de campos montrados en el formulario de bÃºsqueda.}  
+
+_textsearchtypeprefsboth_ [l=es] {Puede cambiar el modo de bÃºsqueda de la colecciÃ³n entre "normal" y "por campos".
+<ul>
+<li>Normal ofrece una caja de bÃºsqueda simple. _textsearchtypeprefsplain_</li>
+<li>Por campos ofrece cierto nÃºmero de cajas de bÃºsqueda, cada una de las cuales busca sobre un campo diferente del Ã­ndice. Esto permite buscar en diferentes campos al mismo tiempo. _textsearchtypeprefsform_ </li>
+</ul>}  
+
+
+
+_texttanumbrowseoptions_ [l=es] {Existen _numbrowseoptions_ manera(s) de encontrar informaciÃ³n en esta colecciÃ³n:}
+
+_textsimplehelpheading_ [l=es] {Â¿CÃ³mo encontrar informaciÃ³n?}
+
+_texthelpscopetitle_ [l=es] {Campo de acciÃ³n de las bÃºsquedas}
+_texthelpscope_ [l=es] {<p>En la mayorÃ­a de las colecciones puede usted escoger diferentes
+Ã­ndices para la bÃºsqueda. Por ejemplo, puede haber Ã­ndices por autor o
+por tÃ­tulo. TambiÃ©n puede haber Ã­ndices por capÃ­tulo o por pÃ¡rrafo. Por
+lo general, se obtiene el documento correspondiente cualquiera que sea
+el Ã­ndice utilizado.
+
+<p>Si los documentos son libros, Ã©stos se abrirÃ¡n en la posiciÃ³n adecuada.
+
+}  
Index: /gsdl/stable/macros/spanish2.dm
===================================================================
--- /gsdl/stable/macros/spanish2.dm	(revision 20131)
+++ /gsdl/stable/macros/spanish2.dm	(revision 20131)
@@ -0,0 +1,1218 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Spanish Language text and icon macros 
+# -- this file contains text that is of less importance
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=es] {documentos. }
+_lastupdate_ [l=es] {Ãltima actualizaciÃ³n }
+_ago_ [l=es] {dÃ­as.}
+_colnotbuilt_ [l=es] {ColecciÃ³n no creada.}
+
+### taken from here
+
+_textpoem_ [l=es] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>que la paz y la tranquilidad te rodeen,
+<br>que vivas en el calor de una calina estival,
+<br>que el ocÃ©ano de tus viajes sea tan terso como la piedra verde
+pulida.
+
+}
+
+_textgreenstone_ [l=es] {<p>Greenstone (piedra verde) es una piedra semipreciosa que, como este
+programa informÃ¡tico, proviene de Nueva Zelanda. En la sociedad maorÃ­
+tradicional era la materia mÃ¡s apreciada y buscada. Esta piedra tiene el
+poder de absorber y encerrar el <i>wairua</i>, que es el espÃ­ritu de la
+fuerza de vida, y estÃ¡ dotada de virtudes tradicionales que hacen de
+ella un emblema muy apropiado para un proyecto de biblioteca digital
+de dominio pÃºblico. Su lustre simboliza la caridad; su transparencia, la
+honradez; su dureza, el coraje, y el filo que puede cobrar, la justicia.
+El objeto tallado utilizado como emblema del programa de biblioteca
+digital de Greenstone es un <i>patu</i>, una especie de maza. Esta
+arma de combate es una reliquia de la familia de uno de los miembros de
+nuestro proyecto. En el combate cuerpo a cuerpo, su lanzamiento podÃ­a
+ser de una rapidez y una precisiÃ³n fenomenal; esto lo convertÃ­a en un
+arma temible y completa. QuisiÃ©ramos que esas cualidades fueran tambiÃ©n
+las de este programa informÃ¡tico y que el afilado borde del <i>patu</i>
+simbolizara el aspecto avanzado y de vanguardia de la tecnologÃ­a.
+
+}  
+
+_textaboutgreenstone_ [l=es] {<p>Greenstone es un paquete de software para la
+creaciÃ³n y difusiÃ³n de colecciones documentales electrÃ³nicas. Ofrece
+una nueva forma para organizar la informaciÃ³n y publicarla en
+Internet o en CD-ROM. Se ha elaborado en el marco del proyecto de
+<b>Biblioteca Digital de Nueva Zelanda</b> en la <b>Universidad de
+Waikato</b>, y se desarrolla y distribuye en colaboraciÃ³n con la
+<b>UNESCO</b> y la <b>ONG Human Info</b>. Es software libre con
+cÃ³digo fuente abierto (open-source software), y puede descargarse en <a href="http://greenstone.org">http://greenstone.org</a>
+segÃºn las condiciones estipuladas en la Licencia PÃºblica General de
+GNU.</b>
+
+<p>La finalidad de este software es permitir que los usuarios, en particular en universidades,  bibliotecas y otras instituciones pÃºblicas,
+puedan crear sus propias bibliotecas digitales. Las bibliotecas
+digitales estÃ¡n transformando radicalmente el mÃ©todo de distribuciÃ³n
+y adquisiciÃ³n de informaciÃ³n utilizado por las comunidades e instituciones socias de UNESCO en las esferas de la educaciÃ³n, la ciencia y la cultura
+en todo el mundo, y particularmente en los paÃ­ses en desarrollo.
+Esperamos que este software contribuya a fomentar el desarrollo efectivo de bibliotecas digitales para compartir informaciÃ³n y ponerla a disposiciÃ³n del pÃºblico en general.
+
+<p>Este software se desarrolla y se distribuye como resultado de un esfuerzo de
+cooperaciÃ³n internacional iniciado en agosto de 2000 por tres
+protagonistas:
+
+<table border="0">
+<tr valign="top">
+<td>
+El proyecto de <a href="http://nzdl.org"><b>Biblioteca Digital de
+Nueva Zelanda en la Universidad de Waikato</b></a>
+<br>
+El software Greenstone surgiÃ³ de este
+proyecto, y esta iniciativa recibiÃ³ el respaldo de la SubcomisiÃ³n de la
+ComunicaciÃ³n de la ComisiÃ³n Nacional Neozelandesa para la UNESCO, como
+parte de la contribuciÃ³n de Nueva Zelanda al programa de UNESCO.
+</td>
+<td></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://www.unesco.org"><b>OrganizaciÃ³n de las Naciones Unidas
+para la EducaciÃ³n, la Ciencia y la Cultura</b></a>
+<br>
+La difusiÃ³n mundial de informaciÃ³n en materia de educaciÃ³n, ciencia y
+cultura , en particular en los paÃ­ses en desarrollo, es uno de los
+objetivos principales del programa intergubernamental de la UNESCO
+"InformaciÃ³n para Todos", y consecuentemente se considera que la
+tecnologÃ­a de la informaciÃ³n y la comunicaciÃ³n apropiada y accesible
+constituye un instrumento esencial en este contexto.
+</td>
+<td><a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+border="0"></a></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://humaninfo.org"><b>La ONG Human Info, con sede en Amberes,
+BÃ©lgica</b></a>
+<br>
+Este proyecto trabaja con agencias de Naciones Unidas y otras ONG, y se ha forjado una reputaciÃ³n mundial en la digitalizaciÃ³n de documentaciÃ³n de interÃ©s para el desarrollo humano, y en su difusiÃ³n pÃºblica, en forma gratuita para los paÃ­ses en desarrollo, y por el precio de costo en el resto.
+</td>
+<td><a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" border="0"></a></td>
+</tr>
+</table>
+
+}  
+
+
+_textdescrselcol_ [l=es] {seleccionar una colecciÃ³n}
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=es] {Hay otros cuatro botones en la pÃ¡gina principal }
+
+_textnocollections_ [l=es] {<p>No hay actualmente ninguna colecciÃ³n disponible para esta instalaciÃ³n
+de Greenstone. Para aÃ±adir colecciones, usted puede:
+
+<ul>
+
+<li>utilizar el Colector para crear nuevas colecciones
+
+<li>o bien instalar colecciones a partir del CD-ROM de Greenstone, si
+dispone de uno
+
+</ul>
+
+}
+
+_text1coll_ [l=es] {Esta instalaciÃ³n de Greenstone contiene 1 colecciÃ³n }
+
+_textmorecolls_ [l=es] {Esta instalaciÃ³n de Greenstone contiene _1_ colecciones }
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=es] {Enlace externo }
+_textlinknotfound_ [l=es] {No se encontrÃ³ el enlace interno }  
+
+_textextlinkcontent_ [l=es] {El enlace que usted ha seleccionado es externo a todas las colecciones
+actualmente seleccionadas. Si desea de todos modos activar este enlace y
+si su navegador estÃ¡ conectado a Internet, puede usted <a
+href="_nexturl_">acudir</a> a esta pÃ¡gina; en caso contrario, pulse el
+botÃ³n "AtrÃ¡s" de su navegador para volver al documento anterior.
+
+}
+
+_textlinknotfoundcontent_ [l=es] {El enlace interno que usted seleccionÃ³ no existe. Esto se debe
+probablemente a un error en la colecciÃ³n fuente. Pulse el botÃ³n "AtrÃ¡s"
+de su navegador para volver al documento anterior.
+
+}
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=es] {<h3>Enlace con la colecciÃ³n "_2_"</h3>
+
+<p>El enlace que ha seleccionado es externo a la colecciÃ³n
+"_collectionname_" (remite a la colecciÃ³n "_2_"). Si desea ver el
+documento que corresponde a este enlace en la colecciÃ³n "_2_", puede
+<a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">acudir</a> a esa pÃ¡gina;
+en caso contrario, pulse el botÃ³n "AtrÃ¡s" de su navegador para volver al
+documento anterior.
+
+}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=es] {Biblioteca Digital Greenstone }
+
+_textusername_ [l=es] {nombre de usuario}
+_textpassword_ [l=es] {contraseÃ±a}
+
+_textmustbelongtogroup_ [l=es] {Se advierte que para acceder a esta pÃ¡gina usted debe
+pertenecer al grupo "_cgiargug_"}
+
+_textmessageinvalid_ [l=es] {Para acceder a la pÃ¡gina que usted ha solicitado es necesario conectarse.<br>
+_If_(_cgiargug_, [_textmustbelongtogroup_]<br>) Teclee por favor su nombre de
+usuario de Greenstone y su contraseÃ±a.
+
+}
+
+_textmessagefailed_ [l=es] {Error en el nombre de usuario o la contraseÃ±a}
+
+_textmessagedisabled_ [l=es] {Lo sentimos, pero se ha invalidado su cuenta. Por favor pÃ³ngase en
+contacto con el administrador de este sitio.
+
+}
+
+_textmessagepermissiondenied_ [l=es] {Lo sentimos, pero usted no tiene permiso de acceder a esta pÃ¡gina.
+
+}
+
+_textmessagestalekey_ [l=es] {El enlace que usted ha seleccionado ya no es vÃ¡lido. Teclee por favor su
+contraseÃ±a para tener acceso a esta pÃ¡gina.
+
+}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=es] {<p>Esta instalaciÃ³n de Greenstone no incluye ninguna documentaciÃ³n. Esto
+puede ser porque:
+
+<ol>
+
+<li>Greenstone se instalÃ³ a partir de un CD-ROM en una versiÃ³n compacta.
+
+<li>Greenstone se instalÃ³ a partir de una
+distribuciÃ³n descargada en un sitio Internet.
+
+</ol>
+
+<p>En ambos casos usted puede obtener la documentaciÃ³n en el directorio
+<i>docs</i> de un CD-ROM de Greenstone o visitando <a
+href="http://www.greenstone.org">http://www.greenstone.org</a>.
+
+}
+
+_textuserguide_ [l=es] {GuÃ­a del usuario}
+_textinstallerguide_ [l=es] {GuÃ­a de instalaciÃ³n}
+_textdeveloperguide_ [l=es] {GuÃ­a del programador}
+_textpaperguide_ [l=es] {Del papel a la colecciÃ³n}
+_textorganizerguide_ [l=es] {Uso del Organizador}
+
+_textgsdocstitle_ [l=es] {documentaciÃ³n de greenstone}
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=es] {Construir colecciÃ³n}  
+_textbildsuc_ [l=es] {ColecciÃ³n construida exitosamente.}  
+_textviewbildsummary_ [l=es] {Puede <a href="_httppagex_(bsummary)" target=_top>ver el resumen </a> de esta colecciÃ³n para mayores detalles.}  
+_textview_ [l=es] {Ver colecciÃ³n}  
+
+_textbild1_ [l=es] {Se estÃ¡ construyendo la colecciÃ³n: llevarÃ¡ algÃºn tiempo. La lÃ­nea de estado de construcciÃ³n, en la parte inferior, le informarÃ¡ de cÃ³mo progresa la operaciÃ³n.}  
+
+_textbild2_ [l=es] {Para detener el proceso de creaciÃ³n en cualquier momento, pulse aquÃ­.
+<br>La colecciÃ³n en la que estÃ¡ trabajando permanecerÃ¡ intacta.}  
+
+_textstopbuild_ [l=es] {parar de construir}  
+
+_textbild3_ [l=es] {Si abandona esta pÃ¡gina (y no ha cancelado el proceso de construcciÃ³n mediante el botÃ³n "detener construcciÃ³n") la colecciÃ³n continuarÃ¡ construyÃ©ndose y se instalarÃ¡ tras el Ã©xito del proceso.}  
+
+_textbuildcancelled_ [l=es] {ConstrucciÃ³n cancelada}  
+
+_textbildcancel1_ [l=es] {El proceso de construcciÃ³n de la colecciÃ³n fuÃ© cancelado. Use los botones amarillos de la parte inferior para hacer cambios a la colecciÃ³n o para reiniciar el proceso.}  
+
+_textbsupdate1_ [l=es] {ActualizaciÃ³n del estado del proceso de construcciÃ³n en 1 segundo}  
+_textbsupdate2_ [l=es] {ActualizaciÃ³n del estado de construcciÃ³n}  
+_textseconds_ [l=es] {segundos}  
+
+_textfailmsg11_ [l=es] {La colecciÃ³n no pudo construirse y no contiene datos. AsegÃºrese de que al menos uno de los directorios o ficheros que especificÃ³ en la pÃ¡gina <i>fuente de datos</i> existe, y de que es de un tipo o, en el caso de un directorio, de que contiene ficheros de tipos que Greenstone puede procesar.}  
+
+_textfailmsg21_ [l=es] {La colecciÃ³n no pudo ser construida (import.fl fallÃ³)}  
+_textfailmsg31_ [l=es] {No pudo construirse la coleciÃ³n (fallÃ³ buildcol.pl)}  
+_textfailmsg41_ [l=es] {La construcciÃ³n se construyÃ³ correctamente pero no se pudo instalar.}  
+_textfailmsg71_ [l=es] {Ha ocurrido un error inesperado durante el intento de construir la colecciÃ³n}  
+
+
+_textblcont_ [l=es] {El registro de construcciÃ³n contiene la siguiente informaciÃ³n:}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=es] {Estructura por defecto}
+_textmore_ [l=es] {mÃ¡s}
+_textinfo_ [l=es] {Informaciones sobre la colecciÃ³n}
+_textsrce_ [l=es] {Datos fuente}
+_textconf_ [l=es] {Configurar la colecciÃ³n}
+_textdel_ [l=es] {Eliminar la colecciÃ³n}  
+_textexpt_ [l=es] {Exportar la colecciÃ³n}  
+
+_textdownloadingfiles_ [l=es] {Bajando ficheros...}  
+_textimportingcollection_ [l=es] {Importando una colecciÃ³n...}
+_textbuildingcollection_ [l=es] {Construyendo una colecciÃ³n...}
+_textcreatingcollection_ [l=es] {creando una colecciÃ³n...}
+
+_textcollectorblurb_ [l=es] {<i>Â¡La pluma es mÃ¡s poderosa que la espada!
+
+<br>
+Antes de crear y distribuir colecciones de informaciÃ³n, hay que
+reflexionar sobre las consecuencias y las responsabilidades que ello
+entraÃ±a. Hay cuestiones jurÃ­dicas de derecho de autor: poder tener
+acceso a documentos no significa necesariamente poder comunicarlos a
+terceros. Hay tambiÃ©n cuestiones de tipo social: en el manejo de las
+colecciones se deben respetar los usos y costumbres de la comunidad de
+la que proceden los documentos. Y hay tambiÃ©n cuestiones Ã©ticas: algunos
+documentos no deben ponerse a disposiciÃ³n de nadie.
+
+<br>Sea consciente del poder de la informaciÃ³n y utilÃ­celo con prudencia.
+
+</i>
+
+}
+
+_textcb1_ [l=es] {El Colector le ayuda a crear nuevas colecciones y modificar, aÃ±adir o
+suprimir colecciones. Para hacerlo, serÃ¡ guiado por una secuencia de
+pÃ¡ginas Web en que se le pedirÃ¡ la informaciÃ³n necesaria.
+
+}
+
+_textcb2_ [l=es] {Primero, debe decidir si }
+_textcnc_ [l=es] {Crear una nueva colecciÃ³n }
+_textwec_ [l=es] {Trabajar con una colecciÃ³n existente, aÃ±adiÃ©ndole datos o suprimiÃ©ndola }
+
+_textcb3_ [l=es] {Para crear o modificar colecciones de biblioteca digital es
+necesario registrarse. Esto permite evitar que otras personas entren en
+su computadora y alteren la informaciÃ³n. Nota: por razones de seguridad
+tendrÃ¡ que conectarse de nuevo cada media hora. Si esto sucede, Â¡no se
+preocupe! - se le invitarÃ¡ a abrir una nueva sesiÃ³n y podrÃ¡ usted
+continuar a partir de donde se encontraba en el momento de la
+desconexiÃ³n.
+
+}
+
+_textcb4_ [l=es] {Teclee por favor su nombre de usuario de Greenstone y su contraseÃ±a y
+pulse el botÃ³n para conectarse.
+
+}
+
+_textfsc_ [l=es] {Primero seleccione la colecciÃ³n con la cual desea usted trabajar (las
+colecciones protegidas contra la escritura no aparecerÃ¡n en esta lista).
+
+}
+
+_textwtc_ [l=es] {Con la colecciÃ³n seleccionada, usted puede
+
+}
+_textamd_ [l=es] {AÃ±adir mÃ¡s datos y recrear la colecciÃ³n
+
+
+}
+_textetc_ [l=es] {Modificar el fichero de configuraciÃ³n de la colecciÃ³n y recrear la
+colecciÃ³n
+
+}
+_textdtc_ [l=es] {Suprimir la colecciÃ³n definitivamente
+
+}
+_textetcfcd_ [l=es] {Exportar la colecciÃ³n para grabarla en un CD-ROM que se instala
+automÃ¡ticamente en Windows
+
+}
+_textcaec_ [l=es] {Cambiar una colecciÃ³n existente
+
+}
+_textnwec_ [l=es] {No estÃ¡ disponible para su modificaciÃ³n ninguna colecciÃ³n que permita la
+escritura
+
+}
+_textcianc_ [l=es] {Crear una nueva colecciÃ³n
+
+}
+_texttsosn_ [l=es] {La secuencia de las fases necesarias para crear una nueva colecciÃ³n de
+biblioteca digital es la siguiente:
+
+}
+_textsin_ [l=es] {Especificar su nombre (y otras informaciones asociadas)
+
+}
+_textswts_ [l=es] {Especificar de dÃ³nde provienen los datos fuente
+
+}
+_textatco_ [l=es] {Ajustar las opciones de configuraciÃ³n (sÃ³lo para usuarios
+experimentados)
+
+}
+_textbtc_ [l=es] {"Crear" la colecciÃ³n (vÃ©ase mÃ¡s abajo)
+
+}
+_textpvyh_ [l=es] {Â¡Admire su obra!
+
+}
+
+_texttfsiw_ [l=es] {La cuarta fase es cuando la computadora hace todo el trabajo. En el
+proceso de "creaciÃ³n" la computadora elabora todos los Ã­ndices y
+recopila todas las informaciones necesarias para el buen funcionamiento
+de la biblioteca digital. Pero primero tiene usted que especificar
+las informaciones.
+
+}
+
+_textadab_ [l=es] {MÃ¡s abajo aparece un diagrama que le ayudarÃ¡ ver dÃ³nde se encuentra. El
+botÃ³n verde es el que usted pulsarÃ¡ para continuar la secuencia. DespuÃ©s
+de cada paso en la secuencia, los botones cambiarÃ¡n al amarillo. Se
+puede volver a una pÃ¡gina anterior pulsando el botÃ³n amarillo
+correspondiente en el diagrama.
+
+}
+
+_textwyar_ [l=es] {Cuando estÃ© listo, pulse el botÃ³n verde "informaciones sobre la
+colecciÃ³n" para comenzar a crear su nueva colecciÃ³n de biblioteca
+digital.
+
+}
+
+_textcnmbs_ [l=es] {Se debe especificar el nombre de la colecciÃ³n}
+_texteambs_ [l=es] {Se debe especificar la direcciÃ³n de correo electrÃ³nico}
+_textpsea_ [l=es] {Compruebe por favor que la direcciÃ³n de correo electrÃ³nico corresponde al formato usuario@dominio}
+_textdocmbs_ [l=es] {Se debe especificar la descripciÃ³n de la colecciÃ³n}
+
+_textwcanc_ [l=es] {Al crear una nueva colecciÃ³n, es necesario incorporar algunas
+informaciones preliminares sobre los datos fuente. Este proceso se
+estructura en forma de una serie de pÃ¡ginas Web, supervisadas por el
+Colector. La barra en la parte inferior de la pÃ¡gina muestra la
+secuencia de las pÃ¡ginas que quedan.
+
+}
+
+_texttfc_ [l=es] {TÃ­tulo de la colecciÃ³n:
+
+}
+
+_texttctiasp_ [l=es] {El tÃ­tulo de la colecciÃ³n es una frase corta que se utiliza en la
+biblioteca digital para identificar el contenido de la colecciÃ³n.
+Por ejemplo: "Computer Science Technical Reports" (Informes tÃ©cnicos de
+informÃ¡tica) o "Humanity Development Library" (Biblioteca para el
+desarrollo de la humanidad).
+
+}
+
+_textcea_ [l=es] {DirecciÃ³n de correo electrÃ³nico de contacto:
+
+}
+
+_textteas_ [l=es] {Esta direcciÃ³n electrÃ³nica constituye el primer punto de contacto para
+la colecciÃ³n. Si el programa Greenstone detecta un problema, un informe
+de diagnÃ³stico se envÃ­a a esta direcciÃ³n. Teclee una direcciÃ³n
+electrÃ³nica en su forma completa: nombre@dominio.
+
+}
+
+_textatc_ [l=es] {Acerca de esta colecciÃ³n:
+
+}
+
+_texttiasd_ [l=es] {Ãsta es una declaraciÃ³n en que se enuncian los principios que rigen los
+elementos que forman parte de esta colecciÃ³n. AparecerÃ¡ en la primera
+pÃ¡gina de presentaciÃ³n de la colecciÃ³n.
+
+}
+
+_textypits_ [l=es] {Su posiciÃ³n en la secuencia se indica con una flecha por debajo - en
+este caso, la etapa de las "informaciones de colecciÃ³n". Para continuar,
+pulse el botÃ³n verde "datos fuente".
+
+}
+
+_srcebadsources_ [l=es] {<p>Uno o mÃ¡s de los ficheros fuente que usted especificÃ³ no estÃ¡ disponible
+(marcados _iconcross_ abajo).
+
+<p>Esto puede ser porque:
+
+<ul>
+
+<li>No existe el fichero, el sitio FTP o el URL.
+
+<li>Hay que conectarse primero a Internet.
+
+<li>Usted estÃ¡ intentando acceder a un URL que se encuentra detrÃ¡s de un
+cortafuego (esto ocurre normalmente cuando usted tiene que presentar un
+nombre de usuario y una contraseÃ±a para acceder a Internet).
+
+</ul>
+
+<p>Si Ã©ste es un URL que usted puede ver en su navegador, el problema
+puede provenir de una copia que se encuentra en la memoria cache local.
+Desafortunadamente, estas copias son invisibles para nuestro proceso de
+espejo de Greenstone. En este caso recomendamos que descargue las
+pÃ¡ginas mediante su navegador.
+
+}
+
+_textymbyco_ [l=es] {Usted puede basar su colecciÃ³n en:
+
+<ul>
+<li>La estructura por defecto
+</ul>
+<dl> <dd> La nueva colecciÃ³n puede contener documentos HTML (.htm,
+.html), documentos texto (.txt, .text), documentos MS-Word (.doc),
+documentos PDF (.pdf), o documentos de correo electrÃ³nico en el formato
+"m-box" (.mbx). </dd> </dl>
+<li>Una colecciÃ³n existente
+<dl> <dd> Los ficheros de su nueva colecciÃ³n deben ser exactamente del mismo
+tipo que los utilizados para crear la colecciÃ³n existente. </dd> </dl>
+</ul>
+}  
+
+_textbtco_ [l=es] {Basar la colecciÃ³n en:}
+_textand_ [l=es] {AÃ±adir nuevos datos}
+_textad_ [l=es] {AÃ±adir datos:}
+
+_texttftysb_ [l=es] {Los ficheros que usted especifique mÃ¡s abajo se aÃ±adirÃ¡n a la colecciÃ³n.
+CerciÃ³rese de no volver a especificar ficheros que ya estÃ¡n en la
+colecciÃ³n, pues de hacerlo habrÃ¡ dos copias. Los ficheros se especifican
+indicando su nombre completo y el directorio en que estÃ¡n almacenados,
+las pÃ¡ginas Web se identifican por su direcciÃ³n Internet absoluta.
+
+}
+
+_textis_ [l=es] {Datos de entrada: }
+
+_textddd1_ [l=es] {<p>Si usted utiliza file:// o ftp:// para especificar un fichero, Ã©ste
+se descargarÃ¡.
+
+<p>Si usted utiliza HTTP://, el resultado dependerÃ¡ del URL y serÃ¡
+diferente si Ã©ste abre en su navegador una pÃ¡gina Web o una lista de
+ficheros. Si se trata de una pÃ¡gina, Ã©sta se descargarÃ¡, al igual que
+todas las pÃ¡ginas con las que estÃ¡ vinculada mediante hiperenlaces,-
+siempre que se encuentren en el mismo sitio Web, en el URL inicial.
+
+<p>Si usted utiliza file:// o ftp:// para especificar un directorio, o
+si indica un URL HTTP:// que conduce a una lista de ficheros, todos los
+ficheros que se encuentran en esa carpeta y en sus subcarpetas se
+incluirÃ¡n en la colecciÃ³n.
+
+<p>Pulse el botÃ³n "mÃ¡s datos" para obtener mÃ¡s cuadros de introducciÃ³n
+de datos.
+
+}
+
+_textddd2_ [l=es] {<p>Pulse uno de los botones verdes. Si es usted un usuario
+experimentado, puede desear ajustar la configuraciÃ³n de la colecciÃ³n.
+Otra posibilidad es ir directamente a la etapa de creaciÃ³n. Recuerde, se
+puede volver a un paso anterior pulsando el botÃ³n amarillo
+correspondiente.
+
+}
+
+_textconf1_ [l=es] {<p>La creaciÃ³n y la presentaciÃ³n de su colecciÃ³n son controladas por
+especificaciones en un "fichero de configuraciÃ³n" especial. Los usuarios
+experimentados que lo deseen pueden modificar los parÃ¡metros de la
+configuraciÃ³n.
+
+<center><p><b>Si no es usted un usuario experimentado, vaya a la parte
+inferior de la pÃ¡gina.</b></center> 
+
+<p>Para modificar los parÃ¡metros de la configuraciÃ³n, corrija los datos que
+aparecen mÃ¡s abajo. Si comete una equivocaciÃ³n, pulse el botÃ³n
+"Reinicio" para restablecer los parÃ¡metros originales de la
+configuraciÃ³n.
+
+}
+
+_textreset_ [l=es] {Reiniciar}
+
+
+_texttryagain_ [l=es] {Por favor <a href="_httppagecollector_" target=_top>vuelva a
+arrancar el Colector</a> e intente de nuevo.
+
+}
+
+
+_textretcoll_ [l=es] {Volver al Colector
+
+}
+
+_textdelperm_ [l=es] {No se pudo suprimir toda o una parte de la colecciÃ³n _cgiargbc1dirname_ . Las causas pueden ser las siguientes:
+<ul>
+<li> Greenstone no tiene permiso para suprimir el directorio _gsdlhome_/collect/_cgiargbc1dirname_.<br> 
+Es posible que usted necesite eliminar este directorio manualmente para poder suprimir completamente la colecciÃ³n _cgiargbc1dirname_ de esta computadora.</</li>
+<li>Greenstone no pudo correr el programa _gsdlhome_/bin/script/delcol.pl. AsegÃºrese de que este fichero se pueda leer y sea ejecutable.</li>
+</ul>
+}  
+
+_textdelinv_ [l=es] {La colecciÃ³n _cgiargbc1dirname_ estÃ¡ protegida o no es vÃ¡lida. La
+supresiÃ³n se cancelÃ³.
+
+}
+
+_textdelsuc_ [l=es] {Se suprimiÃ³ la colecciÃ³n _cgiargbc1dirname_.
+
+}
+
+_textclonefail_ [l=es] {No se pudo clonar la colecciÃ³n _cgiargclonecol_. Las causas posibles
+son:
+
+<ul>
+
+<li>La colecciÃ³n _cgiargclonecol_ no existe
+
+<li>La colecciÃ³n _cgiargclonecol_ no tiene ningÃºn fichero collect.cfg
+
+<li>Greenstone no tiene permiso para leer el fichero de configuraciÃ³n
+collect.cfg
+
+</ul>
+
+}
+
+_textcolerr_ [l=es] {Error en el Colector. }
+
+_texttmpfail_ [l=es] {El Colector no pudo efectuar ninguna operaciÃ³n de lectura o de escritura
+en el fichero o directorio temporal. Las causas posibles son:
+
+<ul>
+
+<li>Greenstone no tiene acceso de lectura/escritura al directorio
+_gsdlhome_/tmp.
+
+</ul>
+
+}
+
+_textmkcolfail_ [l=es] {El Colector no pudo crear la estructura de directorios que requiere la
+nueva colecciÃ³n (mkcol.pl fallÃ³). Las causas posibles son:
+
+<ul>
+
+<li>Greenstone no tiene permiso para escribir en el directorio
+_gsdlhome_/tmp.
+
+<li>Errores en el guiÃ³n Perl mkcol.pl.
+
+</ul>
+
+}
+
+_textnocontent_ [l=es] {Error del Colector: no se proporcionÃ³ ningÃºn nombre para la nueva
+colecciÃ³n. Intente volver a arrancar el Colector.
+
+}
+
+_textrestart_ [l=es] {Volver a arrancar el Colector
+
+}
+
+_textreloaderror_ [l=es] {Se produjo un error cuando se creaba la nueva colecciÃ³n. Es posible que
+el uso de los botones "Volver a cargar" o "AtrÃ¡s" de su navegador haya
+perturbado a Greenstone (trate de evitar la utilizaciÃ³n de esos botones
+durante la creaciÃ³n de una colecciÃ³n con el Colector). Se recomienda
+volver a arrancar el Colector.
+
+}
+
+_textexptsuc_ [l=es] {La colecciÃ³n de _cgiargbc1dirname_ se exportÃ³ al directorio
+_gsdlhome_/tmp/exported\__cgiargbc1dirname_.
+
+}
+
+_textexptfail_ [l=es] {<p>Fallo en la exportaciÃ³n de la colecciÃ³n _cgiargbc1dirname_.
+
+<p>Esto puede deberse a que Greenstone fue instalado sin los componentes necesarios para soportar a la funciÃ³n "Exportar colecciÃ³n".
+<ul>
+
+ <li>Si instalÃ³ una versiÃ³n de Greenstone anterior a la 2.70 desde un CD-ROM 
+ estos componentes no se instalan a menos que los seleccione en una instalaciÃ³n personalizada ("Custom"). Puede agregarlos a su sistema ejecutando nuevamente el procedimiento de instalaciÃ³n.
+
+ <li>Si instalÃ³ Greenstone de una distribuciÃ³n descargada de la web entonces necesitarÃ¡ descargar un paquete adicional para habilitar esta funciÃ³n. Por favor, visite <a href="http://www.greenstone.org">http://www.greenstone.org</a> o 
+ <a
+ href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">la lista de mailing</a> para mayores detalles.
+
+</ul>
+}  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=es] {<p> Por favor, indique la siguiente informaciÃ³n de fichero y selecciÃ³nelo en la parte inferior</p>}  
+
+_textcaec_ [l=es] {AÃ±adiendo a una colecciÃ³n existente}  
+_textbild_ [l=es] {Depositar Elemento}  
+_textintro_ [l=es] {Seleccionar fichero}  
+_textconfirm_ [l=es] {ConfirmaciÃ³n}  
+_textselect_ [l=es] {Seleccionar ColecciÃ³n}  
+_textmeta_ [l=es] {Especificar metadatos}  
+_textselectoption_ [l=es] {seleccione la colecciÃ³nâŠ}  
+
+_texttryagain_ [l=es] {Por favor, <a href="_httppagedepositor_" target=_top>reinicie el acumulador</a> y pruebe de nuevo.}  
+
+_textselectcol_ [l=es] {Seleccione la colecciÃ³n a la que quiere aÃ±adir un documento nuevo.}  
+_textfilename_ [l=es] {Nombre de fichero}  
+_textfilesize_ [l=es] {TamaÃ±o del fichero}  
+
+_textretcoll_ [l=es] {Volver al acumulador}  
+
+
+_texttmpfail_ [l=es] {El Acumulador fallÃ³ en la lectura o escritura de un fichero temporal o directorio. Las causas posibles son:
+<ul>
+<li> Greenstone no tiene acceso de lectura/escritura para el directorio _gsdlhome_/tmp.
+</ul>
+}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=es] {<p>Greenstone es un conjunto de programas informÃ¡ticos cuya
+finalidad es dar acceso a colecciones de informaciones que constituyen
+una biblioteca digital y crear nuevas colecciones. Ofrece
+una nueva manera de organizar la informaciÃ³n y de publicarla en
+Internet o en un CD-ROM.  Elaborado dentro del proyecto de Biblioteca
+Digital de Nueva Zelandia de la Universidad de Waikato, este producto
+se distribuye en colaboraciÃ³n con la UNESCO y la ONG Human
+Info. Es un programa informÃ¡tico de cÃ³digo fuente
+abierto (<i>open-source software</i>), que puede descargarse en la
+direcciÃ³n <a
+href="http://greenstone.org">http://greenstone.org</a>, segÃºn
+las condiciones estipuladas en la Licencia PÃºblica General de
+GNU.
+
+}
+
+_textgreenstone2_ [l=es] {El sitio web de la Biblioteca Digital de Nueva Zelandia (<a
+href="http://nzdl.org">http://nzdl.org</a>) contiene numerosos ejemplos
+de colecciones, creados con el programa Greenstone, que se pueden
+consultar libremente. Muestran varias opciones de bÃºsqueda y navegaciÃ³n,
+e incluyen colecciones en Ã¡rabe, chino, francÃ©s, maorÃ­ y espaÃ±ol, asÃ­
+como en inglÃ©s. Hay tambiÃ©n algunas colecciones de mÃºsica.
+
+}
+
+_textplatformtitle_ [l=es] {plataforma}
+_textgreenstone3_ [l=es] {Greenstone funciona con Windows, UNIX y Mac OS X. La distribuciÃ³n incluye binarios listos para usarse en todas las versiones de Windows, Linux y Mac OS X. TambiÃ©n incluye el cÃ³digo fuente completo para el sistema, el cual se puede compilar usando Microsoft C++ o GCC. Greenstone funciona con otros programas libres de software, incluyendo el servidor Web Apache y Perl. La interfaz de usuario utiliza navegadores Web como Netscape Navigator o Internet Explorer.
+}
+
+_textgreenstone4_ [l=es] {Muchas colecciones de documentos se distribuyen en CD-ROM con el
+programa Greenstone. Por ejemplo, el proyecto de <i>Bibliotecas para el
+desarrollo de la humanidad</i> contiene 1.230 publicaciones cuyos temas
+son muy variados (desde la contabilidad hasta la depuraciÃ³n del agua).
+Se puede acceder a esta colecciÃ³n con computadoras de escasa potencia,
+como las que se suelen encontrar en los paÃ­ses en desarrollo. La
+informaciÃ³n puede obtenerse mediante bÃºsquedas o consultas por tema, por
+tÃ­tulos de publicaciones, por organizaciÃ³n, consultando una lista de
+"CÃ³mo", o visualizando de forma aleatoria las portadas de los
+libros.
+
+}
+
+_textcustomisationtitle_ [l=es] {personalizaciÃ³n}
+_textgreenstone5_ [l=es] {Greenstone estÃ¡ especialmente concebido para poder ampliarse y
+personalizarse a voluntad. Greenstone puede tratar nuevos formatos de
+documentos y de metadatos escribiendo "conectores" (<i>plugins</i>), en
+lenguaje Perl. Asimismo, se pueden implementar nuevas estructuras de
+navegaciÃ³n en los metadatos escribiendo "clasificadores." La interfaz de
+usuario y la presentaciÃ³n se pueden modificar utilizando las "macros"
+escritas en un lenguaje de macros simple. El protocolo CORBA permite que
+los agentes (por ejemplo en lenguaje Java) utilicen todas las funciones
+disponibles en las colecciones de documentos. Por Ãºltimo, se puede
+modificar el cÃ³digo fuente en C++ y Perl.
+
+}
+
+_textdocumentationtitle_ [l=es] {documentaciÃ³n}
+_textdocuments_ [l=es] {La documentaciÃ³n completa del software Greenstone ya estÃ¡ disponible.}
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=es] {lista de correo}
+_textmailinglist_ [l=es] {Existe una lista de correo electrÃ³nico para los debates sobre el
+programa de Biblioteca Digital Greenstone. Es deseable que los
+usuarios activos de Greenstone participen en estos debates.
+Para suscribirse, pulse <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+Para enviar un mensaje a la lista, utilice la direcciÃ³n <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz">greenstone-users@list.scms.waikato.ac.nz</a>.
+
+}
+
+_textbugstitle_ [l=es] {errores lÃ³gicos o de programaciÃ³n}
+_textreport_ [l=es] {Queremos asegurarnos de que este software le funcione correctamente. Por favor, informe cualquier error o bug a <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">la lista de mailing</a>.
+}  
+
+_textgs3title_ [l=es] {en los trabajos}
+_textgs3_ [l=es] {Greenstone 3 es un diseÃ±o e implementaciÃ³n completamente nuevos, que conserva todas las ventajas de Greenstone 2 (la versiÃ³n actual). Por ejemplo, es multilingÃŒe, multiplataforma y altamente configurable. Incorpora todas las prestaciones del sistema actual y es compatible con versiones anteriores, es decir, que puede construir y presentar colecciones preexistentes sin modificarlas. Escrito en Java, estÃ¡ estructurado como una red de mÃ³dulos independientes que se comunican por medio de XML. De esta manera funciona de manera distribuida y puede extenderse a diferentes servidores segÃºn se necesite. Su diseÃ±o modular aumenta la flexibilidad y capacidad de Greenstone. La documentaciÃ³n y las versiones experimentales de Greenstone 3 pueden descargarse de la <a href="http://www.greenstone.org/greenstone3.html">pÃ¡gina principal de Greenstone 3</a>.
+}
+
+_textcreditstitle_ [l=es] {crÃ©ditos}
+
+_textwhoswho_ [l=es] {El programa Greenstone es fruto de la colaboraciÃ³n de muchas personas. Rodger McNab y Stefan Boddie son los principales arquitectos y programadores. TambiÃ©n han contribuido David Bainbridge, George Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd Reed, Bill Rogers, John Thompson y Stuart Yeates. Otros miembros del proyecto Biblioteca Digital de Nueva Zelanda que proporcionaron asesorÃ­a y valiosas ideas para la concepciÃ³n del sistema son: Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols y Lloyd Smith. TambiÃ©n queremos dar las gracias a todos aquellos que contribuyeron a los paquetes de programas con licencias GNU incluidos en esta distribuciÃ³n: MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE y XLHTML.
+}
+
+_textaboutgslong_ [l=es] {acerca del programa greenstone}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=es] {Lista de los usuarios actuales}
+_textuser_ [l=es] {usuario}
+_textas_ [l=es] {estado de la cuenta}
+_textgroups_ [l=es] {grupos}
+_textcomment_ [l=es] {comentario}
+_textadduser_ [l=es] {aÃ±adir un nuevo usuario }
+_textedituser_ [l=es] {modificar}
+_textdeleteuser_ [l=es] {suprimir}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=es] {Modificar las informaciones relativas a los usuarios}
+_textadduser_ [l=es] {AÃ±adir un nuevo usuario}
+
+_textaboutusername_ [l=es] {Los nombres de usuarios deben tener entre 2 y 30 caracteres. Pueden
+estar compuestos de caracteres alfanumÃ©ricos, '.', y '_'.
+}
+
+_textaboutpassword_ [l=es] {Las contraseÃ±as deben ser de entre 3 y 128 caracteres, y pueden comprender
+todos los caracteres ASCII imprimibles.
+}
+
+_textoldpass_ [l=es] {Si este campo se deja vacÃ­o, se utilizarÃ¡ la antigua contraseÃ±a. }
+_textenabled_ [l=es] {activado }
+_textdisabled_ [l=es] {desactivado }
+
+_textaboutgroups_ [l=es] {Los grupos son listas cuyos elementos estÃ¡n separados por comas, no
+teclee espacios despuÃ©s de las comas.}
+_textavailablegroups_ [l=es] {Los grupos predefinidos incluyen al administrador y otros que pueden asignar permisos para la construccion remota de colecciones usando el GLI o el Depositor:
+<ul>
+<li><b>administrator</b>: Otorga permisos para acceder y cambiar la configuraciÃ³n del sitio y las cuentas de usuarios.
+<li><b>personal-collections-editor</b>: Otorga permisos para crear nuevas colecciones personales.
+<li><b><nombre-coleccion>-collection-editor</b>: Otorga permisos para crear y editar la colecciÃ³n "nombre-coleccion", por ejemplo, reportes-collection-editor.
+<li><b>all-collections-editor</b>: Otorga permisos para crear colecciones globales y personales y editar <b>todas</b> las colecciones.
+</ul>
+}  
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=es] {Suprimir un usuario}
+_textremwarn_ [l=es] {Â¿Confirma usted que desea suprimir definitivamente el usuario <b>_cgiargumun_</b>?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=es] {Cambiar la contraseÃ±a}
+_textoldpw_ [l=es] {antigua contraseÃ±a}
+_textnewpw_ [l=es] {nueva contraseÃ±a}
+_textretype_ [l=es] {vuelva a teclear su nueva contraseÃ±a}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=es] {Se ha registrado su nueva contraseÃ±a}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=es] {El nombre de usuario no es vÃ¡lido.}
+_textinvalidpassword_ [l=es] {La contraseÃ±a no es vÃ¡lida.}
+_textemptypassword_ [l=es] {Teclee una contraseÃ±a inicial para este usuario.}
+_textuserexists_ [l=es] {Este usuario ya existe, teclee por favor otro
+nombre de usuario.}
+
+_textusernameempty_ [l=es] {Teclee por favor su nombre de usuario.}
+_textpasswordempty_ [l=es] {Tiene que teclear su antigua contraseÃ±a.}
+_textnewpass1empty_ [l=es] {Teclee su nueva contraseÃ±a y vuÃ©lvala a teclear.}
+_textnewpassmismatch_ [l=es] {Las dos versiones de su nueva contraseÃ±a son distintas.}
+_textnewinvalidpassword_ [l=es] {La contraseÃ±a es incorrecta.}
+_textfailed_ [l=es] {Es incorrecto el nombre de usuario o la contraseÃ±a.}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=es] {NÃºmero de versiÃ³n de Greenstone}
+_textframebrowser_ [l=es] {Para visualizar esto se requiere un navegador que acepte los marcos ("frames").}
+_textusermanage_ [l=es] {GestiÃ³n de los usuarios}
+_textlistusers_ [l=es] {lista de los usuarios}
+_textaddusers_ [l=es] {aÃ±adir un nuevo usuario}
+_textchangepasswd_ [l=es] {cambiar de contraseÃ±a}
+_textinfo_ [l=es] {Informaciones tÃ©cnicas}
+_textgeneral_ [l=es] {general}
+_textarguments_ [l=es] {argumentos}
+_textactions_ [l=es] {acciones}
+_textbrowsers_ [l=es] {navegadores}
+_textprotocols_ [l=es] {protocolos}
+_textconfigfiles_ [l=es] {Ficheros de configuraciÃ³n}
+_textlogs_ [l=es] {Registros}
+_textusagelog_ [l=es] {registro de uso}
+_textinitlog_ [l=es] {registro de inicializaciÃ³n}
+_texterrorlog_ [l=es] {registro de errores}
+_textadminhome_ [l=es] {pÃ¡gina principal de la administraciÃ³n}
+_textreturnhome_ [l=es] {pÃ¡gina principal de Greenstone}
+_titlewelcome_ [l=es] {AdministraciÃ³n }
+_textmaas_ [l=es] {Los servicios de mantenimiento y de administraciÃ³n son los siguientes:}
+_textvol_ [l=es] {mostrar los registros en lÃ­nea}
+_textcmuc_ [l=es] {crear, mantener y actualizar colecciones}
+_textati_ [l=es] {acceder a informaciones tÃ©cnicas tales como los argumentos CGI}
+
+_texttsaa_ [l=es] {Se puede acceder a estos servicios mediante la barra de navegaciÃ³n
+situada en la parte izquierda de la pÃ¡gina.
+}
+
+_textcolstat_ [l=es] {Estado de la colecciÃ³n}
+
+_textcwoa_ [l=es] {Una colecciÃ³n sÃ³lo aparecerÃ¡ como "running" (en funcionamiento) si el
+fichero build.cfg existe, si es legible, si contiene un campo vÃ¡lido
+"builddate" (fecha de creaciÃ³n), es decir &gt; 0, y si se encuentra en
+el directorio "index" de la colecciÃ³n (es decir NO en el directorio
+"build").
+
+}
+
+_textcafi_ [l=es] {Pulse <i>abbrev.</i> para obtener informaciones sobre una colecciÃ³n}
+_textcctv_ [l=es] {Pulse <i>collection</i> para visualizar una colecciÃ³n}
+_textsubc_ [l=es] {Someter cambios }
+_texteom_ [l=es] {Error de lectura del fichero main.cfg}
+_textftum_ [l=es] {No se pudo actualizar el fichero main.cfg }
+_textmus_ [l=es] {se logrÃ³ actualizar el fichero main.cfg }
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=es] {Resumen de la creaciÃ³n de la colecciÃ³n "_collectionname_"
+
+}  
+_textflog_ [l=es] {Lista de errores de la colecciÃ³n  "_collectionname_"
+
+}  
+_textilog_ [l=es] {Fichero de control para la colecciÃ³n "_collectionname_"}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=es] {ENVIAR COMENTARIOS}  
+
+_greenstoneusabilitytext_ [l=es] {Capacidad de uso de Greenstone}
+
+_textwhy_ [l=es] {<p>Enviar este informe es una forma de indicar que la pÃ¡gina Web que usted estaba viendo era difÃ­cil de manejar o resultaba frustrante. }  
+_textextraforform_ [l=es] {Usted no tiene que llenar la forma. Cualquier informaciÃ³n serÃ¡ de ayuda.}
+_textprivacybasic_ [l=es] {<p>El informe sÃ³lo contendrÃ¡ informaciÃ³n sobre la pÃ¡gina web de Greenstone que usted estÃ¡ viendo, y de la tecnologÃ­a que estÃ¡ usando para verla (asÃ­ como cualquier informaciÃ³n adicional que usted proporcione).}  
+_textstillsend_ [l=es] {Â¿TodavÃ­a querrÃ­a enviar este informe?}  
+
+_texterror_ [l=es] {error}
+_textyes_ [l=es] {Si}  
+_textno_ [l=es] {No}  
+_textclosewindow_ [l=es] {Cerrar ventana}  
+_textabout_ [l=es] {Acerca de}
+_textprivacy_ [l=es] {Confidencialidad}
+_textsend_ [l=es] {Enviar}
+_textdontsend_ [l=es] {No enviar}  
+_textoptionally_ [l=es] {De manera opcional}  
+
+_textunderdev_ [l=es] {Una vista previa de los detalles estarÃ¡ disponible en la versiÃ³n final.}  
+
+_textviewdetails_ [l=es] {Ver los detalles del informe}  
+_textmoredetails_ [l=es] {MÃ¡s detalles}  
+_texttrackreport_ [l=es] {Dar seguimiento a este informe}  
+_textcharacterise_ [l=es] {Â¿QuÃ© clase de problema es?}  
+_textseverity_ [l=es] {Â¿CÃºal es la importancia del problema?}  
+ 
+_textbadrender_ [l=es] {La pÃ¡gina se ve extraÃ±a}  
+_textcontenterror_ [l=es] {Error de contenido}  
+_textstrangebehaviour_ [l=es] {Comportamiento extraÃ±o}  
+_textunexpected_ [l=es] {SucediÃ³ algo inesperado}  
+_textfunctionality_ [l=es] {DifÃ­cil de usar}  
+_textother_ [l=es] {Otro(s)}  
+
+_textcritical_ [l=es] {CrÃ­tico}  
+_textmajor_ [l=es] {Serio}  
+_textmedium_ [l=es] {Medio}  
+_textminor_ [l=es] {Menor}  
+_texttrivial_ [l=es] {Trivial}  
+
+_textwhatdoing_ [l=es] {Â¿QuÃ© estaba intentando hacer?}  
+_textwhatexpected_ [l=es] {Â¿QuÃ© esperaba usted que pasara?}  
+_textwhathappened_ [l=es] {Â¿QuÃ© pasÃ³ en realidad?}  
+
+_cannotfindcgierror_ [l=es] {<h2>Â¡Disculpe!</h2>No se pudieron encontrar los programas del servidor para el botÃ³n "_linktextusab_".}  
+
+_textusabbanner_ [l=es] {el rÃ³tulo estilo koru de Greenstone}
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=es] {Ha ocurrido un error}  
+
+_textgtihome_ [l=es] {Estas pÃ¡ginas le ayudan a mejorar el soporte de Greenstone para otros idiomas. UsÃ¡ndolo, usted puede
+<ul>
+  <li>traducir partes de Greenstone a un nuevo idioma
+  <li>actualizar una interfaz de idioma existente cuando cambie la interfaz en inglÃ©s (por ej., para incorporar nuevas prestaciones de Greenstone)
+  <li>corregir errores en traducciones existentes
+</ul>
+
+Se le mostrarÃ¡ una serie de pÃ¡ginas web, cada una de las cuales contiene una frase para traducir.
+Debe proceder traduciendo las frases una por una.
+Muchas frases contienen etiquetas de formato HTML: no debe intentar traducirlas, sino que debe dejarlas intactas en la versiÃ³n traducida. Las palabras rodeadas por guiones bajos (como _esta_) tampoco deben traducirse (son nombres de "macro" de Greenstone).
+<p>
+Si usted estÃ¡ actualziando una traducciÃ³n ya existente, no se le mostrarÃ¡n frases para las que ya exista traducciÃ³n. En ocasiones, una traducciÃ³n existe, pero el texto inglÃ©s correspondiente ha sido cambiado. En este caso se le mostrarÃ¡ la traducciÃ³n existente y deberÃ¡ comprobarla y cambiarla si es necesario.
+<p>
+Cada pÃ¡gina termina con un botÃ³n "_textgtisubmit_". Cuando lo pulse, los cambios serÃ¡n incorporados automÃ¡ticamente a una instalaciÃ³n independiente de Greenstone en nzdl.org. Se mostrarÃ¡ en cada pÃ¡gina un botÃ³n que permite acceder a esta instalaciÃ³n.}  
+
+_textgtiselecttlc_ [l=es] {Por favor, seleccione su idioma}  
+
+#for status page
+_textgtiviewstatus_ [l=es] {Pulse para ver el estado actual de las traducciones de todos los idiomas}  
+_textgtiviewstatusbutton_ [l=es] {VER ESTADO}  
+_textgtistatustable_ [l=es] {Lista del estado actual de las traducciones de todos los idiomas}  
+_textgtilanguage_ [l=es] {Idioma}  
+_textgtitotalnumberoftranslations_ [l=es] {NÃºmero total de traducciones}  
+
+_textgtiselecttfk_ [l=es] {Por favor, seleccione un fichero sobre el que trabajar}  
+
+_textgticoredm_ [l=es] {Interfaz Greenstone (NÃºcleo)}  
+_textgtiauxdm_ [l=es] {Interfaz Greenstone (Auxiliar)}  
+_textgtiglidict_ [l=es] {Diccionario GLI}  
+_textgtiglihelp_ [l=es] {Ayuda de GLI}  
+_textgtiperlmodules_ [l=es] {MÃ³dulos de Perl}  
+_textgtitutorials_ [l=es] {Ejercicios de Seminario}  
+_textgtigreenorg_ [l=es] {Greenstone.org}  
+_textgtigs3interface_ [l=es] {Interfaz de Greenstone3}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=es] {Manual de Desarrollador de Greenstone}  
+_textgtiinstallmanual_ [l=es] {Manual del Instalador de Greenstone}  
+_textgtipapermanual_ [l=es] {Manual Greenstone "Del papel a la colecciÃ³n"}  
+_textgtiusermanual_ [l=es] {Manual de Usuario de Greenstone}  
+
+_textgtienter_ [l=es] {RETORNO}  
+
+_textgticorrectexistingtranslations_ [l=es] {Corrige traducciones existentes}  
+_textgtidownloadtargetfile_ [l=es] {Descargar fichero}  
+_textgtiviewtargetfileinaction_ [l=es] {Ver este fichero en funcionamiento}  
+_textgtitranslatefileoffline_ [l=es] {Traducir este fichero sin conexiÃ³n}  
+
+_textgtinumchunksmatchingquery_ [l=es] {NÃºmero de fragmentos de texto que cumplen la condiciÃ³n}  
+
+_textgtinumchunkstranslated_ [l=es] {traducciones hechas}  
+_textgtinumchunksrequiringupdating_ [l=es] {De Ã©stos, _1_ requieren actualizaciÃ³n}  
+_textgtinumchunksrequiringtranslation_ [l=es] {traducciones pendientes}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=es] {nÃºmero de traducciones hechas}  
+_textgtinumchunksrequiringupdating2_ [l=es] {nÃºmero de traducciones que requieren actualizaciÃ³n}  
+_textgtinumchunksrequiringtranslation2_ [l=es] {nÃºmero de traducciones pendientes}  
+
+_textgtienterquery_ [l=es] {Introduzca una palabra o frase del fragmento de texto que quiere corregir}  
+_textgtifind_ [l=es] {BUSCAR}  
+
+_textgtitranslatingchunk_ [l=es] {Traduciendo el fragmento de texto <i>_1_</i>}  
+_textgtiupdatingchunk_ [l=es] {Actualizando el fragmento de texto <i>_1_</i>}  
+_textgtisubmit_ [l=es] {ENVIAR}  
+
+_textgtilastupdated_ [l=es] {Ãltima actualizaciÃ³n}  
+
+_textgtitranslationfilecomplete_ [l=es] {Gracias por actualizar este fichero -- Â¡ahora estÃ¡ completo!<p> Puede descargar una copia del fichero usando el enlace superior, y podrÃ¡ tambiÃ©n ser incluido en futuras versiones de Greenstone.}  
+
+_textgtiofflinetranslation_ [l=es] {Puede traducir esta parte de Greenstone offline usando una planilla de Microsoft Excel:
+
+<ol>
+<li>Descargue  <a href="_gwcgi_?a=gti&p=excel&tct=work&e=_compressedoptions_">este archivo</a> para ver todo el trabajo pendiente, o <a href="_gwcgi_?a=gti&p=excel&tct=all&e=_compressedoptions_">este archivo</a> para ver todos los textos de este mÃ³dulo.
+<li>Abra el archivo descargado en Microsoft Excel (Office 2003/XP o versiones mÃ¡s recientes) y guÃ¡rdelo en formato de Microsoft Excel (.xls).
+<li>Ingrese todas las traducciones en los recuadros provistos.
+<li>Cuando haya finalizado de traducir todas los textos, envie el archivo .xls a <a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>.
+</ol>
+}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=es] {Interfaz de la Biblioteca Digital Greenstone}
+_textglihelp_ [l=es] {La Interfaz de Bibliotecario de Greenstone (GLI) le da acceso a la funcionalidad de Greenstone desde una interfaz fÃ¡cil de usar con la que sÃ³lo tiene que apuntar y pulsar. Esto le permite reunir grupos de documentos, importar o asignar metadatos, e incluirlos en una colecciÃ³n de Greeenstone.
+<p>
+
+Recuerde que la GLI se ejecuta conjuntamente con Greenstone, por 
+lo que se asume que estarÃ¡ instalada en un subdirectorio de su instalaciÃ³n de Greenstone. Si usted ya descargÃ³ una de las versiones de Greenstone o la instalÃ³  
+desde un CD-ROM, entonces Ã©ste serÃ¡ el caso.
+
+<h4>EjecuciÃ³n de la GLI en Windows</h4>
+
+Ponga en marcha la Interfaz de Bibliotecario en Windows seleccionando <i>Biblioteca Digital Greenstone</i> en el submenÃº de <i>Programas</i> del menÃº de <i>Inicio</i> y eligiendo <i>Interfaz de Bibliotecario de Greenstone</i>. 
+
+<h4>EjecuciÃ³n de la GLI en UNIX</h4>
+
+Para poner en marcha la Interfaz de Bibliotecario en UNIX cambie al directorio <i>gli</i> que se encuentra en su instalaciÃ³n Greenstone y ejecute el script <i>gli.sh</i>.
+
+<h4>EjecuciÃ³n de la GLI en Mac OS X</h4>
+
+En el Finder, despliegue <i>Aplicaciones</i> y <i>Greenstone</i>
+(si instalÃ³ Greenstone de la manera preestablecida), y lanze la aplicaciÃ³n <i>GLI</i>.}  
Index: /gsdl/stable/macros/status.dm
===================================================================
--- /gsdl/stable/macros/status.dm	(revision 20131)
+++ /gsdl/stable/macros/status.dm	(revision 20131)
@@ -0,0 +1,145 @@
+# this file must be UTF-8 encoded
+
+package status
+
+_header_ {<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>_1_</title>
+
+_Style:cssheader_
+</head>
+<body>
+}
+
+_footer_ {</body>
+</html>
+}
+
+# frames need to be transitional, not strict, for target=""
+_infoheader_ {<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+
+<head>
+<title>_1_</title>
+_Style:cssheader_
+</head>
+
+<body>
+
+<div id="content">
+
+<div class="divbar">&nbsp;</div>
+<h2 style="text-align: center">_1_</h2>
+<div class="divbar">&nbsp;</div>
+
+}
+
+_infofooter_ {
+<div class="divbar">&nbsp;</div>
+
+</div> <!-- content -->
+
+</body>
+</html>
+}
+
+
+_frameset_ {
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
+<html>
+<head>
+<title>_titlewelcome_</title>
+</head>
+
+<frameset cols="180,*" frameborder=0>
+  <noframes><body>
+  <p>_textframebrowser_</p>
+  </body>
+  </noframes>
+  <frame src="_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=select" name="navframe">
+  <frame src="_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=welcome" name="infoframe">
+</frameset>
+
+</html>
+}
+
+_select_ {
+<a href="_httppagehome_" target="_top"><img class="icon" src="_httpimg_/gsdl.gif" alt="_textdescrhome_" title="_textdescrhome_"></a>
+<p>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=welcome" target=infoframe>_textadminhome_</a><br>
+<a href="_httppagehome_" target=\_top>_textreturnhome_</a>
+
+<p><b>_textconfigfiles_</b><br>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=llssite" target=infoframe>_textllssite_</a><br>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=maincfg" target=infoframe>_textmaincfg_</a>
+
+<p><b>_textlogs_</b><br>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=usagelog" target=infoframe>_textusagelog_</a><br>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=errorlog" target=infoframe>_texterrorlog_</a>
+
+_If_("_cgiarguma_" ne "\_cgiarguma\_", 
+<p><b>_textusermanage_</b><br>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=um&amp;uma=listusers" target=infoframe>_textlistusers_</a><br>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=um&amp;uma=adduser" target=infoframe>_textaddusers_</a><br>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=um&amp;uma=changepasswd" target=infoframe>_textchangepasswd_</a>
+)
+
+<p><b>_textinfo_</b><br>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=generalinfo" target=infoframe>_textgeneral_</a><br>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=argumentinfo" target=infoframe>_textarguments_</a><br>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=actioninfo" target=infoframe>_textactions_</a><br>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=browserinfo" target=infoframe>_textbrowsers_</a><br>
+<a href="_gwcgi_?e=_compressedoptions_&amp;a=status&amp;p=protocolinfo" target=infoframe>_textprotocols_</a>
+}
+
+_textllssite_ {llssite.cfg}
+_textmaincfg_ {main.cfg}
+
+_welcome_ {
+<b>_textversion_: _versionnum_</b>
+
+<p>_textmaas_
+<ul>
+<li>_textvol_
+<li>_textcmuc_
+<li>_textati_
+</ul>
+_texttsaa_
+</p>
+<div class="divbar">&nbsp;</div>
+<b>_textcolstat_</b>
+<p>
+_textcwoa_
+<p>
+_textcafi_
+<br>
+_textcctv_
+</p>
+}
+
+_maincfg_ {
+<form name="maincfgform" method=post action="_gwcgi_">
+<input type=hidden name="p" value="changemaincfg">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<p>_If_(_maincfgfile_,<textarea name="cfgfile" cols=72 rows=18 wrap=off>
+_maincfgfile_
+</textarea>
+<br><input type=submit value="_textsubc_"><input type=reset>,_texteom_)
+</form>
+}
+
+_changemaincfgfail_ {
+<html>
+<body>
+_textftum_
+_footer_
+}
+
+_changemaincfgsuccess_ {
+<html>
+<body>
+_textmus_
+_footer_
+}
Index: /gsdl/stable/macros/style.dm
===================================================================
--- /gsdl/stable/macros/style.dm	(revision 20131)
+++ /gsdl/stable/macros/style.dm	(revision 20131)
@@ -0,0 +1,202 @@
+# this file must be UTF-8 encoded
+#######################################################################
+# PAGE STYLES 
+#######################################################################
+
+package Style
+
+# to use this style system output
+# _header_
+# all your page content, then
+# _footer_
+
+# use the page parameter 'style' to choose the appropriate style
+
+# Current values: "html" and "xhtml"
+_compliance_ {html}
+
+# the style system uses
+# _pagetitle_  - what gets displayed at the top of the browser window
+# _pagescriptextra_ - any extra javascript you want included in the header
+# _pagebannerextra_ - anything extra you want displayed in the page banner
+# _pagefooterextra_ - anything extra you want displayed in the footer
+
+# defaults for the above macros
+_pagetitle_ {_collectionname_}
+_pagescriptfileextra_ {}
+_pagescriptextra_ {}
+_pagebannerextra_ {}
+_pagefooterextra_ {}
+
+# it also relies on lots of Globals, the most important of these are:
+# _cookie_ - put in the cgi header
+# _globalscripts_ - javascript stuff
+# _imagecollection_
+# _imagehome_
+# _imagehelp_
+# _imagepref_
+# _imagethispage_ (this is now not an image, but text. should be renamed?)
+# _linkotherversion_
+
+# _httpiconchalk_ - the image down the left of the page - is now done
+# by the style sheet.
+
+_header_ {_cgihead_
+_htmlhead_(class="bgimage")_startspacer__pagebanner_
+}
+
+_header_[v=1] {_cgihead_
+_htmlhead__pagebanner_
+}
+
+# _cgihead_ {Content-type: text/html
+# _cookie_
+#
+# }	
+_cgihead_{}
+
+# may be set in collection's extra.dm
+_collectionspecificstyle_ {}
+
+# any declarations relating to CSS that should go in the html head part.
+# declarations containing images are done here so the path is correct
+# at runtime.
+
+_csslink_{
+  <link rel="stylesheet" href="_cssfilelink_" type="text/css" 
+   title="Greenstone Style" charset="UTF-8" _linktagend_
+  <link rel="alternate stylesheet" href="_httpstyle_/style-print.css"
+   type="text/css" title="Printer" charset="UTF-8" media="print, screen" _linktagend_
+  <link rel="stylesheet" href="_httpstyle_/style-print.css" type="text/css" 
+   title="Printer" charset="UTF-8" media="print" _linktagend_ 
+}
+
+_cssheader_ {
+_csslink_
+<style type="text/css">
+body.bgimage \{ background: url("_httpimages_/chalk.gif") scroll repeat-y left top; \}
+div.navbar \{ background-image: url("_httpimages_/bg_green.png"); \}
+div.divbar \{ background-image: url("_httpimages_/bg_green.png"); \}
+a.navlink \{ background-image: url("_httpimages_/bg_off.png"); \}
+a.navlink_sel \{ background-image: url("_httpimages_/bg_green.png"); \}
+a.navlink:hover \{ background-image: url("_httpimages_/bg_on.png"); \}
+p.bannertitle \{background-image: url("_httpimages_/banner_bg.png"); \}
+p.collectiontitle \{background-image: url("_httpimages_/banner_bg.png"); \}
+</style>
+_collectionspecificstyle_
+
+}
+
+# separate macro so it can be easily overridden for customised collections
+_cssfilelink_ {_httpstyle_/style.css}
+
+# Languages that should be displayed right-to-left
+_htmlextra_ [l=ar] { dir=rtl }
+_htmlextra_ [l=fa] { dir=rtl }
+_htmlextra_ [l=he] { dir=rtl }
+_htmlextra_ [l=ur] { dir=rtl }
+_htmlextra_ [l=ps] { dir=rtl }
+_htmlextra_ [l=prs] { dir=rtl }
+
+# htmlhead uses:
+# _1_ - extra parameters for the body tag
+# _pagetitle_
+# _globalscripts_
+_htmlhead_ {<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+
+<html_htmlextra_>
+<head>
+<title>_pagetitle_</title>
+<meta name="_status:textversion_" content="_versionnum_" _metatagend_
+_globalscripts_
+_cssheader_
+_document:documentheader_
+</head>
+
+<body _1_>
+}
+
+# Link and meta tags must be closed differently for HTML/XHTML validation
+_linktagend_ {_If_("_compliance_" eq "xhtml",/>,>)}
+_metatagend_ {_If_("_compliance_" eq "xhtml",/>,>)}
+
+_spacerwidth_ {65}
+
+# _startspacer_ is a spacer that gives pages a left-hand margin. 
+# It must eventually be closed by _endspacer_.
+_startspacer_ {
+<div id="page">
+}
+
+# _bannertitle_ is defined in nav_css/ns4.dm, and is either text or
+# a banner image
+_pagebanner_ {
+<!-- page banner (\_style:pagebanner\_) -->
+<div id="banner">
+<div class="pageinfo"> 
+<p class="bannerlinks">_globallinks_</p>
+_bannertitle_
+</div>
+<div class="collectimage">_imagecollection_</div>
+</div>
+<div class="bannerextra">_pagebannerextra_</div>
+<!-- end of page banner -->
+}
+
+_pagebanner_[v=1] {
+<!-- page banner - text version [v=1] (\_style:pagebanner\_) -->
+<center><h2><b><u>_imagecollection_</u></b></h2></center><p>
+_globallinks_
+_pagebannerextra_
+<p>
+<!-- end of page banner -->
+}
+
+# note we no longer close off one of the startspacer tables here!!
+_footer_ {
+<!-- page footer (\_style:footer\_) -->
+_pagefooterextra__endspacer__htmlfooter_
+}
+
+# v=1 footer: not using startspacer in the header, so dont put it in the footer
+_footer_ [v=1]{
+<!-- page footer [v=1] (\_style:footer\_) -->
+_pagefooterextra_
+_htmlfooter_
+}
+
+# close off anything opened by startspacer
+_endspacer_ {	
+</div> <!-- id=page -->
+}	
+
+
+_htmlfooter_ {
+</body>
+</html>
+}
+
+# imagescript only used in nav_ns4.dm
+_globalscripts_{
+_If_(_pagescriptfileextra_,_pagescriptfileextra_)
+<script language="javascript" type="text/javascript">
+_If_(_pagescriptextra_,_pagescriptextra_)
+_imagescript_
+</script>
+}
+
+_globalscripts_ [v=1] {
+<script language="javascript" type="text/javascript">
+<!--
+_If_(_cgiargx_,_scriptdetach_)
+_pagescriptextra_
+// -->
+</script>
+}
+
+_scriptdetach_ {
+    function close\_detach() \{
+	close();
+    \}
+}
Index: /gsdl/stable/macros/tamil.dm
===================================================================
--- /gsdl/stable/macros/tamil.dm	(revision 20131)
+++ /gsdl/stable/macros/tamil.dm	(revision 20131)
@@ -0,0 +1,878 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Tamil Language text and icon macros translated from english.dm
+# on  8 January 2007 by Mr.Suralinathi.M. 
+# Information and Knowledge Management Course Trainee (2007-2008), 
+# National Centre for Science Information, Indian Institute of Science, 
+# Bangalore 560 012, Karnataka, India.) under the guidance of Ms.Anuradha.K.T.,
+# Senior Technical Officer, National Centre for Science Information, 
+# Indian Institute of Science, Bangalore 560 012, Karnataka, India.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textperiodicals_
+# -- Missing translation: _textsource_
+# -- Missing translation: _textdate_
+# -- Missing translation: _textnumpages_
+
+# -- Missing translation: _textsignin_
+
+# -- Missing translation: _textdefaultcontent_
+
+_textdefaulttitle_ [l=ta] {à®à®¿ à®à®žà¯ à®à®¿ à®à®²à¯ à®€à®µà®±à¯}
+# -- Missing translation: _textbadcollection_
+
+# -- Missing translation: _textselectpage_
+
+# -- Missing translation: _collectionextra_
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+# -- Missing translation: _collectorextra_
+
+_textdescrcollection_ [l=ta] {}
+# -- Missing translation: _textdescrabout_
+_textdescrhome_ [l=ta] {à®à®²à¯à®²à®ªà¯à®ªà®à¯à®à®®à¯}
+_textdescrhelp_ [l=ta] {à®à®€à®µà®¿à®à¯à®¯à¯}
+_textdescrpref_ [l=ta] {à®
+à®€à®¿à®à®µà®¿à®°à¯à®ªà¯à®ªà®®à¯}
+_textdescrgreenstone_ [l=ta] {à®à®¿à®°à®¿à®©à¯à®žà¯à®à¯à®£à¯ à®à®¿à®à®¿à®à¯à®à®²à¯ à®²à¯à®ªà¯à®°à¯à®°à®¿ à®à®Ÿà®ªà¯à®à¯à®µà¯à®°à¯}
+# -- Missing translation: _textdescrusab_
+
+_textdescrsearch_ [l=ta] {à®€à¯à®à®²à¯}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=ta] {à®€à®²à¯à®ªà¯à®ªà¯ à®
+à®à®°à®µà®°à®¿à®à¯à®ªà¯à®ªà®à®¿ à®€à¯à®à®²à¯}
+
+_textdescrCreator_ [l=ta] {à®à®£à¯à®à®Ÿà®à¯à®à¯à®ªà®µà®°à¯ à®
+à®à®°à®µà®°à®¿à®à¯à®ªà¯à®ªà®à®¿ à®€à¯à®à®²à¯}
+_textdescrSubject_ [l=ta] {à®µà®¿à®·à®¯à®®à¯ à®
+à®à®°à®µà®°à®¿à®à¯à®ªà¯à®ªà®à®¿ à®€à¯à®à®²à¯}
+
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=ta] {à®€à¯à®€à®¿à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®€à¯à®à®²à¯}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+# -- Missing translation: _textdescrSource_
+# -- Missing translation: _textdescrLanguage_
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=ta] {à®šà®¿à®±à¯à®µà®©à®®à¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®€à¯à®à®²à¯}
+# -- Missing translation: _textdescrKeyword_
+_textdescrHowto_ [l=ta] {à®µà®à¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®€à¯à®à®²à¯}
+_textdescrList_ [l=ta] {à®ªà®à¯à®à®¿à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®€à¯à®à®²à¯}
+_textdescrSeries_ [l=ta] {à®€à¯à®à®°à¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®€à¯à®à®²à¯}
+# -- Missing translation: _textdescrTo_
+# -- Missing translation: _textdescrFrom_
+_textdescrTopic_ [l=ta] {à®€à®©à®¿à®ªà¯à®ªà®à¯à®à®€à®²à¯à®ªà¯à®ªà¯à®µà¯à®³à®¿à®¯à¯à®à¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®€à¯à®à®²à¯}
+_textdescrBrowse_ [l=ta] {à®
+à®à®°à®µà®°à®¿à®à¯à®ªà¯à®ªà®à®¿ à®€à¯à®à®²à¯}
+# -- Missing translation: _textdescrCollage_
+_textdescrPeople_ [l=ta] {à®®à®à¯à®à®³à¯ à®
+à®à®°à®µà®°à®¿à®à¯à®ªà¯à®ªà®à®¿ à®€à¯à®à®²à¯}
+# -- Missing translation: _textdescrAcronym_
+# -- Missing translation: _textdescrPhrase_
+# -- Missing translation: _textdescrArtist_
+# -- Missing translation: _textdescrVolume_
+# -- Missing translation: _textdescrCountries_
+# -- Missing translation: _textdescrCaptions_
+
+
+_labelSearch_ [l=ta] {à®€à¯à®à®²à¯}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=ta] {à®€à®²à¯à®ªà¯à®ªà¯ A-Z}
+_labelCreator_ [l=ta] {à®à®£à¯à®à®Ÿà®à¯à®à¯à®ªà®µà®°à¯ A-Z}
+_labelSubject_ [l=ta] {à®µà®¿à®·à®¯à®®à¯}
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=ta] {à®€à¯à®€à®¿}
+# -- Missing translation: _labelTypes_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+# -- Missing translation: _labelSource_
+# -- Missing translation: _labelLanguage_
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=ta] {à®šà®¿à®±à¯à®µà®©à®®à¯}
+# -- Missing translation: _labelKeyword_
+_labelHow_ [l=ta] {à®µà®à¯}
+_labelSeries_ [l=ta] {à®€à¯à®à®°à¯}
+_labelList_ [l=ta] {à®ªà®à¯à®à®¿}
+# -- Missing translation: _labelTo_
+# -- Missing translation: _labelFrom_
+_labelTopic_ [l=ta] {à®€à®²à¯à®ªà¯à®ªà¯}
+_labelBrwse_ [l=ta] {à®€à¯à®à®²à¯}
+# -- Missing translation: _labelCollage_
+# -- Missing translation: _labelBrows_
+_labelPeople_ [l=ta] {à®®à®à¯à®à®³à¯ A-Z}
+# -- Missing translation: _labelAcronym_
+# -- Missing translation: _labelPhrase_
+# -- Missing translation: _labelArtist_
+# -- Missing translation: _labelVolume_
+# -- Missing translation: _labelCaptions_
+# -- Missing translation: _labelCountries_
+
+_texticontext_ [l=ta] {à®à®µà®£à®®à¯ à®ªà®Ÿà®°à¯à®€à¯à®€à®²à¯}
+_texticonclosedbook_ [l=ta] {à®à®µà®£à®®à¯ à®€à®¿à®±à®šà®€à¯ à®ªà¯à®°à¯à®³à®à®à¯à®à®®à¯ à®ªà®Ÿà®°à¯à®€à¯à®€à®²à¯}
+_texticonnext_ [l=ta] {à®
+à®à¯à®€à¯à®€ à®ªà®¿à®°à®¿à®µà¯à®à¯à®à¯}
+_texticonprev_ [l=ta] {à®®à¯à®©à¯ à®ªà®¿à®°à®¿à®µà¯à®à¯à®à¯}
+
+# -- Missing translation: _texticonworld_
+
+# -- Missing translation: _texticonmidi_
+# -- Missing translation: _texticonmsword_
+# -- Missing translation: _texticonmp3_
+# -- Missing translation: _texticonpdf_
+# -- Missing translation: _texticonps_
+# -- Missing translation: _texticonppt_
+# -- Missing translation: _texticonrtf_
+# -- Missing translation: _texticonxls_
+
+_page_ [l=ta] {à®ªà®à¯à®à®®à¯}
+_pages_ [l=ta] {à®ªà®à¯à®à®à¯à®à®³à¯}
+_of_ [l=ta] {à®à®©à®à®¯}
+_vol_ [l=ta] {à®ªà®°à®¿à®®à®Ÿà®£à®®à¯}
+_num_ [l=ta] {à®à®£à¯}
+
+_textmonth00_ [l=ta] {}
+_textmonth01_ [l=ta] {à®à®©à®µà®°à®¿}
+_textmonth02_ [l=ta] {à®ªà®¿à®ªà¯à®°à®µà®°à®¿}
+_textmonth03_ [l=ta] {à®®à®Ÿà®°à¯à®à¯}
+_textmonth04_ [l=ta] {à®à®ªà¯à®°à®²à¯}
+_textmonth05_ [l=ta] {à®®à¯}
+_textmonth06_ [l=ta] {à®à¯à®©à¯}
+_textmonth07_ [l=ta] {à®à¯à®²à¯}
+_textmonth08_ [l=ta] {à®à®à®žà¯à®à¯}
+_textmonth09_ [l=ta] {à®à¯à®ªà¯à®à®®à¯à®ªà®°à¯}
+_textmonth10_ [l=ta] {à®
+à®à¯à®à¯à®ªà®°à¯}
+_textmonth11_ [l=ta] {à®šà®µà®®à¯à®ªà®°à¯}
+_textmonth12_ [l=ta] {à®à®¿à®à®®à¯à®ªà®°à¯}
+
+# -- Missing translation: _textdocument_
+# -- Missing translation: _textsection_
+# -- Missing translation: _textparagraph_
+
+# -- Missing translation: _magazines_
+
+# -- Missing translation: _nzdlpagefooter_
+
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=ta] {à®€à¯à®à¯à®ªà¯à®ªà¯ à®€à¯à®à®°à¯à®ªà®Ÿà®}
+
+_textsubcols1_ [l=ta] {<p>à®®à¯à®Žà¯à®®à¯à®¯à®Ÿà®© à®€à¯à®à¯à®ªà®ªà¯ _1_ à®€à¯à®©à®£ à®€à¯à®à¯à®ªà®ªà¯ à®à®³à¯à®³à®à®à¯à®à®¿à®¯à®€à¯ à¥€:
+<blockquote>}
+
+_textsubcols2_ [l=ta] {</blockquote>
+à€
+à€ª à€à€¹à€¿à€ à€€à¥ à€à¥à€šà€Ÿà€µ
+à€ªà¥à€·à¥à€  à€®à¥à€ à€à¥à€
+à€à€ªà€žà€à€à¥à€°à€¹ à€à¥ à€ªà€°à¥à€à¥à€·
+à€à€° à€žà€à¥à€€à¥ à€¹à¥ à¥€}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhsrc_
+# -- Missing translation: _texticonhlang_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+# -- Missing translation: _texticonhcoll_
+# -- Missing translation: _texticonhto_
+# -- Missing translation: _texticonhfrom_
+# -- Missing translation: _texticonhbrows_
+# -- Missing translation: _texticonhacronym_
+# -- Missing translation: _texticonhphrases_
+# -- Missing translation: _texticonhartist_
+# -- Missing translation: _texticonhkw_
+# -- Missing translation: _texticonhvol_
+# -- Missing translation: _texticonhcapt_
+# -- Missing translation: _texticonhcount_
+
+_texticonopenbookshelf_ [l=ta] {à®šà¯à®²à®à®€à¯à®€à®¿à®©à¯ à®à®šà¯à®€ à®ªà®à¯à®€à®¿à®¯à¯ à®®à¯à®à¯ à¥€}
+_texticonclosedbookshelf_ [l=ta] {à®šà¯à®²à®à®€à¯à®€à®¿à®©à¯ à®à®šà¯à®€ à®ªà®à¯à®€à®¿à®¯à¯ à®€à®¿à®±à®šà¯à®€à¯ à®ªà¯à®°à¯à®³à®à®à¯à®à®®à¯ à®ªà®Ÿà®°à¯à®€à¯à®€à¯à®€à®²à¯ à¥€}
+_texticonopenbook_ [l=ta] {à®à®šà¯à®€ à®ªà¯à®€à¯à®€à®à®€à¯à®€à¯ à®®à¯à®à¯ à¥€}
+_texticonclosedfolder_ [l=ta] {à®à¯à®µà¯à®¯à¯ à®€à®¿à®±à®šà¯à®€à¯ à®ªà¯à®°à¯à®³à®à®à¯à®à®®à¯ à®ªà®Ÿà®°à¯à®€à¯à®€à¯à®€à®²à¯ à¥€}
+_texticonclosedfolder2_ [l=ta] {à®€à¯à®©à®£ à®ªà®à¯à®€à®¿à®¯à¯ à®€à®¿à®± à¥€}
+_texticonopenfolder_ [l=ta] {à®à®šà¯à®€ à®à¯à®µà¯à®¯à¯ à®®à¯à®à¯ à¥€}
+_texticonopenfolder2_ [l=ta] {à®€à¯à®©à®£ à®ªà®à¯à®€à®¿à®¯à¯ à®®à¯à®à¯ à¥€ }
+_texticonsmalltext_ [l=ta] {à®®à¯à®²à®ªà¯à®ªà®à¯à®€à®¿ à®ªà®Ÿà®°à¯à®€à¯à®€à®²à¯ à¥€}
+_texticonsmalltext2_ [l=ta] {à®µà®¿à®·à®¯à®®à¯ à®ªà®Ÿà®°à¯à®€à¯à®€à®²à¯ à¥€ }
+_texticonpointer_ [l=ta] {à®šà®à®ªà¯à®ªà¯ à®ªà®à¯à®€à®¿ à¥€}
+_texticondetach_ [l=ta] {à®ªà¯à®€à®¿à®¯ à®à®Ÿà®³à®°à®€à¯à®€à®¿à®²à¯ à®à®šà¯à®€ à®ªà®à¯à®à®€à¯à®€à¯ à®€à®¿à®± à¥€}
+_texticonhighlight_ [l=ta] {à®®à¯à®à¯à®à®¿à®¯ à®à®²à¯à®à¯à®à¯à®±à¯à®à®³à¯ à®€à¯à®à®²à¯ à¥€}
+
+# -- Missing translation: _texticonnohighlight_
+# -- Missing translation: _texticoncontracttoc_
+# -- Missing translation: _texticonexpandtoc_
+# -- Missing translation: _texticonexpandtext_
+# -- Missing translation: _texticoncontracttext_
+_texticonwarning_ [l=ta] {<b> </b>}
+# -- Missing translation: _texticoncont_
+
+_textltwarning_ [l=ta] {<div class="buttons">_imagecont_</div>
+_iconwarning_
+}
+
+# -- Missing translation: _textgoto_
+_textintro_ [l=ta] {<i></i>}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=ta] {_If_(_thislast_,à€ªà€°à€¿à€£à€Ÿà€® _thisfirst_ - _thislast_ à€à€žà€ªà¥à€°à€¶à¥à€š à€à¥: _cgiargq_,à€à€ž à€ªà¥à€°à€¶à¥à€š
+à€à€Ÿ à€à¥à€ à€®à¥à€² à€šà€¹à¥à€ à€¹à¥: _cgiargq_)}
+_textnoquerytitle_ [l=ta] {à®€à¯à®à®²à¯ à®ªà®à¯à®à®®à¯ à¥€}
+
+_textsome_ [l=ta] {_If_(_cgiargb_,à®à®¿à®²)}
+_textall_ [l=ta] {_If_(_cgiargb_,à®à®²à¯à®²à®Ÿà®®à¯)}
+# -- Missing translation: _textboolean_
+# -- Missing translation: _textranked_
+# -- Missing translation: _textnatural_
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+# -- Missing translation: _texticonsearchhistorybar_
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+# -- Missing translation: _textusequery_
+_textfreqmsg1_ [l=ta] {à®µà®Ÿà®°à¯à®€à¯à®€à¯ à®à®£à¯à®£à¯à®€à®²à¯: }
+_textpostprocess_ [l=ta] {_If_(_quotedquery_,<br><i>à®à¯à®¯à¯à®®à¯à®±à¯à®à¯à®à¯à®ªà®¿à®©à¯ à®€à¯à®à®²à¯
+ _quotedquery_ </i>)}
+# -- Missing translation: _textinvalidquery_
+
+_textmorethan_ [l=ta] {à®
+à®€à®¿à®à®®à®Ÿà®© }
+# -- Missing translation: _textapprox_
+_textnodocs_ [l=ta] {à®à¯à®³à¯à®µà®¿à®à®à®Ÿà®© à®à®µà®£à®®à¯ à®à®²à¯à®²à¯ à¥€}
+_text1doc_ [l=ta] {à®à¯à®³à¯à®µà®¿à®à®à®Ÿà®© à®à®µà®£à®®à¯ à¥€}
+_textlotsdocs_ [l=ta] {à®à¯à®³à¯à®µà®¿à®à®à®Ÿà®© à®à®µà®£à®à¯à®à®³à¯ à¥€}
+_textmatches_ [l=ta] {à®à®£à¯à®¯à®Ÿà®©à®µà¯à®à®³à¯ }
+_textbeginsearch_ [l=ta] {à®à®°à®®à¯à®ª à®€à¯à®à®²à¯}
+# -- Missing translation: _textrunquery_
+# -- Missing translation: _textclearform_
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+# -- Missing translation: _textwordphrase_
+# -- Missing translation: _textinfield_
+# -- Missing translation: _textfoldstem_
+
+# -- Missing translation: _textadvquery_
+# -- Missing translation: _textallfields_
+# -- Missing translation: _texttextonly_
+# -- Missing translation: _textand_
+# -- Missing translation: _textor_
+# -- Missing translation: _textandnot_
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=ta] {à€à¥à€à€¿à€¯à¥ _indexselection__If_(_jselection_, à€žà¥ _jselection_)_If_(_nselection_, _nselection_) à€à€¿à€žà€®à¥ _querytypeselection_ à€¶à€¬à¥à€Š à€¹à¥à€ à¥€}
+
+_textadvancedsearch_ [l=ta] {à€à¥à€à€¿à€¯à¥ _indexselection_ _If_(_jselection_, à€žà¥ _jselection_)_If_(_nselection_, _nselection_ à€­à€Ÿà€·à€Ÿ) à€à€¿à€žà€®à¥ _querytypeselection_ à€¶à€¬à¥à€Š à€¹à¥à€ à¥€}
+
+# -- Missing translation: _textformsimplesearch_
+
+# -- Missing translation: _textformadvancedsearch_
+
+
+# -- Missing translation: _textnojsformwarning_
+# -- Missing translation: _textdatesearch_
+# -- Missing translation: _textstartdate_
+# -- Missing translation: _textenddate_
+# -- Missing translation: _textbc_
+# -- Missing translation: _textad_
+# -- Missing translation: _textexplaineras_
+
+_textstemon_ [l=ta] {(à®µà®Ÿà®°à¯à®€à¯à®€à¯ à®®à¯à®à®¿à®µà¯ à®šà¯à®à¯à®à¯à®€à®²à¯ à¥€)}
+
+_textsearchhistory_ [l=ta] {à®€à¯à®à®²à¯ à®µà®°à®²à®Ÿà®±à¯ à¥€}
+
+#text macros for search history
+_textnohistory_ [l=ta] {à®€à¯à®à®²à¯ à®µà®°à®²à®Ÿà®±à¯à®±à®¿à®²à¯ à®ªà®€à®¿à®µà¯à®à®³à¯ à®à®²à¯à®²à¯ à¥€}
+# -- Missing translation: _texthresult_
+# -- Missing translation: _texthresults_
+# -- Missing translation: _texthallwords_
+# -- Missing translation: _texthsomewords_
+# -- Missing translation: _texthboolean_
+# -- Missing translation: _texthranked_
+# -- Missing translation: _texthcaseon_
+# -- Missing translation: _texthcaseoff_
+# -- Missing translation: _texthstemon_
+# -- Missing translation: _texthstemoff_
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textprefschanged_
+_textsetprefs_ [l=ta] {à®à¯à®µà¯ à®µà®¿à®°à¯à®ªà¯à®ªà®à¯à®à®³à¯}
+_textsearchprefs_ [l=ta] {à®€à¯à®à®²à¯ à®µà®¿à®°à¯à®ªà¯à®ªà®à¯à®à®³à¯}
+_textcollectionprefs_ [l=ta] {à®€à¯à®à¯à®ªà¯à®ªà¯ à®µà®¿à®°à¯à®ªà¯à®ªà®à¯à®à®³à¯}
+_textpresentationprefs_ [l=ta] {à®à®à®°à¯à®ªà®à¯à®€à¯à®€à®²à¯ à®µà®¿à®°à¯à®ªà¯à®ªà®à¯à®à®³à¯}
+_textpreferences_ [l=ta] {à®µà®¿à®°à¯à®ªà¯à®ªà®à¯à®à®³à¯}
+# -- Missing translation: _textcasediffs_
+# -- Missing translation: _textignorecase_
+# -- Missing translation: _textmatchcase_
+_textwordends_ [l=ta] {à®µà®Ÿà®°à¯à®€à¯à®€à¯ à®®à¯à®à®¿à®µà¯:}
+_textstem_ [l=ta] {à®µà®Ÿà®°à¯à®€à¯à®€à¯ à®®à¯à®à®¿à®µà¯ à®šà¯à®à¯à®à®²à¯ à¥€}
+_textnostem_ [l=ta] {à€ªà¥à€°à¥à€£ à€¶à€¬à¥à€Š à€à€°à¥à€°à€®à€¿à€²à€Ÿà€ à¥€}
+_textprefop_ [l=ta] {à®®à¯à®²à¯ à®€à®¿à®°à¯à®ªà¯à®ªà¯à®_maxdocoption_ à®à®°à®¿à®¯à®Ÿà®©à®µà®±à¯à®±à¯à®à®©à¯
+à€®à¥à€ à€žà¥ _hitsperpageoption_ à€ªà€°à€¿à€£à€Ÿà€®à€ªà¥à€°à€€à€¿ à€ªà¥à€·à¥à€  à€Šà€¿à€à€Ÿà€à¥€}
+_textextlink_ [l=ta] {à®µà¯à®³à®¿à®¯à¯à®¯à¯à®³à¯à®³ à®à®©à®£à®¯à®€à®³à®à¯à®à¯à®³à¯à®à¯à®à®Ÿà®© à®µà®Žà®¿ }
+_textintlink_ [l=ta] {à€®à¥à€² à€Šà€žà¥à€€à€Ÿà€µà¥à€à€à€ž à€žà¥ à€ªà€¯à€Ÿ à€¹à¥:}
+_textlanguage_ [l=ta] {à®à¯à®®à¯à® à®®à¯à®Žà®¿: }
+_textencoding_ [l=ta] {à®à¯à®±à®¿à®¯à¯à®à¯ à®à®à¯à®à¯à®à®¿à®©à¯à®±: }
+_textformat_ [l=ta] {à®à¯à®®à¯à® à®µà®à®¿à®µà®®à¯: }
+_textall_ [l=ta] {à®®à¯à®Žà¯}
+_textquerymode_ [l=ta] {à®µà®¿à®©à®Ÿ à®µà®à®¿à®µà®®à¯:}
+_textsimplemode_ [l=ta] {à®à®Ÿà®€à®°à®© à®µà®¿à®©à®Ÿ à®µà®à®¿à®µà®®à¯ à¥€}
+_textadvancedmode_ [l=ta] {à®à®¯à®°à¯ à®µà®¿à®©à®Ÿ à®µà®à®¿à®µà®®à¯ ) à¥€}
+# -- Missing translation: _textlinkinterm_
+_textlinkdirect_ [l=ta] {à®
+à®à¯à®à¯ à®šà¯à®°à®à®¿à®¯à®Ÿà® à®ªà¯à®à¯à®}
+_textdigitlib_ [l=ta] {à®²à®à¯à®à¯à®®à¯à®±à¯ à®šà¯à®²à®à®®à¯}
+_textweb_ [l=ta] {à®à®£à¯à®¯à®®à¯}
+_textgraphical_ [l=ta] {à®µà®°à¯à®µà®¿à®¯à®²à¯}
+_texttextual_ [l=ta] {à®à®°à¯}
+_textcollectionoption_ [l=ta] {<p>
+à®€à¯à®©à¯ à®€à¯à®à¯à®ªà¯à®ªà®¿à®±à¯à®à¯ à®à®©à¯à®€à¯à®€à®²à¯:
+<br>}
+
+_textrelateddocdisplay_ [l=ta] {à®à®©à¯à®¯à®Ÿà®© à®à®µà®£à®à¯à®à®³à¯ à®à®Ÿà®à¯à®à®¿à®¯à®³à®¿ à¥€}
+_textsearchhistory_ [l=ta] {à®€à¯à®à®²à¯ à®µà®°à®²à®Ÿà®±à¯}
+# -- Missing translation: _textnohistory_
+_texthistorydisplay_ [l=ta] {à®à®Ÿà®à¯à®à®¿ _historynumrecords_ à®€à¯à®à®²à¯ à®µà®°à®²à®Ÿà®±à¯à®±à¯ à®à®à¯à®à®³à¯ à¥€}
+_textnohistorydisplay_ [l=ta] {à®€à¯à®à®²à¯ à®µà®°à®²à®Ÿà®±à¯ à®à®Ÿà®à¯à®à®¿à®¯à®³à®¿à®à¯à® à®µà¯à®£à¯à®à®Ÿà®®à¯ à¥€}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+# -- Missing translation: _textformsearch_
+# -- Missing translation: _textplainsearch_
+_textqueryboxsize_ [l=ta] {à®µà®¿à®©à®Ÿ à®ªà¯à®à¯à®à®¿ à®
+à®³à®µà¯:}
+_textregbox_ [l=ta] {à®®à¯à®±à¯à®¯à®Ÿà®© à®µà®¿à®©à®Ÿ à®ªà¯à®à¯à®à®¿ à¥€}
+_textbigbox_ [l=ta] {à®ªà¯à®°à®¿à®¯ à®µà®¿à®©à®Ÿ à®ªà¯à®à¯à®à®¿ à¥€}
+# -- Missing translation: _textformtype_
+_textsimple_ [l=ta] {à®à®Ÿà®€à®°à®©}
+_textadvanced_ [l=ta] {à®à®¯à®°à¯}
+
+# used in "with 4 fields" in the form search box
+# -- Missing translation: _textwith_
+# -- Missing translation: _textfields_
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+# -- Missing translation: _textsortby_
+# -- Missing translation: _textalsoshowing_
+# -- Missing translation: _textwith_
+# -- Missing translation: _textdocsperpage_
+
+# -- Missing translation: _textfilterby_
+# -- Missing translation: _textall_
+# -- Missing translation: _textany_
+# -- Missing translation: _textwords_
+# -- Missing translation: _textleaveblank_
+
+# -- Missing translation: _browsebuttontext_
+
+# -- Missing translation: _nodata_
+# -- Missing translation: _docs_
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textHelp_
+_textSearchshort_ [l=ta] {à®€à®©à®¿à®ªà®à¯à® à®à¯à®±à¯à®à®³à¯ à®€à¯à®à®²à¯ à¥€}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=ta] {à®€à®²à¯à®ªà¯à®ªà¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®µà¯à®³à®¿à®¯à¯à®à¯à®à®³à¯ à®
+à®£à¯à®à¯à®€à®²à¯ à¥€}
+_textCreatorshort_ [l=ta] {à®à®Žà¯à®€à¯à®€à®Ÿà®³à®°à¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®µà¯à®³à®¿à®¯à¯à®à¯à®à®³à¯ à®
+à®£à¯à®à¯à®€à®²à¯  à¥€}
+_textSubjectshort_ [l=ta] {à®µà®¿à®·à®¯à®®à¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®µà¯à®³à®¿à®¯à¯à®à¯à®à®³à¯ à®
+à®£à¯à®à¯à®€à®²à¯ à¥€}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=ta] {à®€à¯à®€à®¿à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®µà¯à®³à®¿à®¯à¯à®à¯à®à®³à¯ à®
+à®£à¯à®à¯à®€à®²à¯ à¥€}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=ta] {à®à¯à®ªà¯à®ªà¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®µà¯à®³à®¿à®¯à¯à®à¯à®à®³à¯ à®
+à®£à¯à®à¯à®€à®²à¯ à¥€}
+# -- Missing translation: _textLanguageshort_
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=ta] {à®€à¯à®à®°à¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®µà¯à®³à®¿à®¯à¯à®à¯à®à®³à¯ à®
+à®£à¯à®à¯à®€à®²à¯ à¥€}
+# -- Missing translation: _textToshort_
+# -- Missing translation: _textFromshort_
+_textBrowseshort_ [l=ta] {à®µà¯à®³à®¿à®¯à¯à®à¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®µà¯à®³à®¿à®¯à¯à®à¯à®à®³à¯ à®
+à®£à¯à®à¯à®€à®²à¯  à¥€}
+_textOrganizationshort_ [l=ta] {
+à®šà®¿à®±à¯à®µà®©à®®à¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®µà¯à®³à®¿à®¯à¯à®à¯à®à®³à¯ à®
+à®£à¯à®à¯à®€à®²à¯ à¥€}
+_textHowtoshort_ [l=ta] {à€à¥à€žà¥ à€žà¥à€à€¿à€à¥ à€
+à€šà¥à€žà€Ÿà€° à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥ à€ªà¥à€°à€µà¥à€¶ à€à¥à€à€¿à€¯à¥ à¥€}
+_textTopicshort_ [l=ta] {à®€à®²à¯à®ªà¯à®ªà¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®µà¯à®³à®¿à®¯à¯à®à¯à®à®³à¯ à®
+à®£à¯à®à¯à®€à®²à¯ à¥€}
+_textPeopleshort_ [l=ta] {à®®à®à¯à®à®³à¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®µà¯à®³à®¿à®¯à¯à®à¯à®à®³à¯ à®
+à®£à¯à®à¯à®€à®²à¯  à¥€}
+# -- Missing translation: _textAcronymshort_
+# -- Missing translation: _textPhraseshort_
+_textArtistshort_ [l=ta] {
+à®à®²à¯à®à®©à¯à®µà®Ÿà®°à®¿à®¯à®Ÿà® à®µà¯à®³à®¿à®¯à¯à®à¯à®à®³à¯ à®
+à®£à¯à®à¯à®€à®²à¯ à¥€}
+# -- Missing translation: _textKeywordshort_
+# -- Missing translation: _textVolumeshort_
+# -- Missing translation: _textCountriesshort_
+# -- Missing translation: _textdefaultshorttext_
+
+_textSearchlong_ [l=ta] {<p>à€à€ª à€®à¥à€²à€à¥à€°à€šà¥à€¥à€žà¥ à€šà€¿à€¶à¥à€à€¿à€€ à€ªà€Šà€à¥ à€à¥à€ "à€à¥à€" à€ªà¥à€·à¥à€ 
+à€žà¥ à€à€° à€žà€à€€à¥ à€¹à¥
+à¥€ à€¯à€¹ à€µà¥ à€ªà€¹à€²à€Ÿ à€ªà¥à€·à¥à€ 
+à€¹à¥ à€à€¹à€Ÿà€žà¥ à€à€ª <b>à€à¥à€</b>, 
+à€¬à€à€š à€à€Ÿ
+à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€Šà¥à€žà€°à¥ à€ªà¥à€·à¥à€  à€à¥ à€à€° à€¬à€Œà€¢à€€à¥
+à€¹à¥ à¥€  }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <b> à®€à®²à¯à®ªà¯à®ªà¯</b>
+ à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€
+à€à€°à€à¥ à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥ à€ªà¥à€°à€µà¥à€¶
+à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ à€¯à¥
+à€µà€°à¥à€£à€®à€Ÿà€²à€Ÿ à€žà€à€¬à€šà¥à€§à€¿ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à€€à¥ à€¹à¥ à¥€  }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <b> à®à®£à¯à®à®Ÿà®à¯à®à¯à®ªà®µà®°à¯</b> 
+à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+ à€¯à¥ à€µà€°à¥à€£à€®à€Ÿà€²à€Ÿ
+à€žà€à€¬à€šà¥à€§à€¿ à€²à¥à€à€
+à€žà¥à€à€¿ à€à¥ à€ªà¥à€¶
+à€à€°à€€à¥ à€¹à¥ à¥€  }
+
+_textSubjectlong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <b> à€µà€¿à€·à€¯</b>
+ à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€
+à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥ à€ªà¥à€°à€µà¥à€¶
+à€à€° à€žà€à€€à¥
+à€¹à¥ à¥€ à€¯à¥ à€µà¥ à€µà€¿à€·à€¯ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à¥à€à€Ÿ à€à¥ à€à€¿à€€à€Ÿà€¬à¥ à€à¥
+à€€à€Ÿà€ à€à€Ÿ à€ªà¥à€°à€€à€¿à€šà€¿à€§à€¿à€€à¥à€µ
+à€à€°à€€à¥ à€¹à¥ à¥€ }
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <b> à€€à€Ÿà€°à¥à€</b> 
+à€¬à€à€šà€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥ à€ªà¥à€°à€µà¥à€¶
+à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ à€¯à¥à€à€µà¥à€€à¥à€€à€¿à€à¥
+à€žà¥à€à€¿à€à¥à€ªà¥à€¶à€à€°à€€à¥à€¹à¥ à¥€  }
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <i>à€²à¥à€à€ªà€€à¥à€°</i> à€¬à€à€š à€à€Ÿ
+à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ 
+à€¯à¥ à€®à¥à€² à€²à¥à€à€ªà€€à¥à€° à€à¥ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à€€à¥ à€¹à¥ à¥€ }
+
+# -- Missing translation: _textLanguagelong_
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <b> à€žà€à€à€ à€šà¥</b> 
+à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥ à€ªà¥à€°à€µà¥à€¶
+à€à€° à€žà€à€€à¥ 
+à€¹à¥ à¥€ à€¯à¥ à€žà€à€à€ à€šà¥à€à¥
+à€žà¥à€à€¿ à€à¥ à€ªà¥à€¶ à€à€°à€€à¥ à€¹à¥ à¥€ }
+
+_textHowtolong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <b> à®à®ªà®ªà®à®¿</b> à€¬à€à€š à€à€Ÿ
+à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+ à€¯à¥ à€à¥à€žà¥ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à€€à¥ 
+à€¹à¥ à¥€  }
+
+_textTopiclong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <b> à€ªà¥à€°à€žà€à€</b> 
+à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+ à€¯à¥ à€ªà¥à€°à€žà€à€
+à€žà¥à€à€¿ à€à¥ à€à€°à€š à€à¥ à€²à€¿à€
+à€ªà¥à€¶ à€à€°à€€à¥ à€¹à¥ à¥€ }
+
+_textTolong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <b>à€ªà€€à€Ÿ</b> à€¬à€à€š à€à€Ÿ
+à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+à€¯à¥ à€
+à€²à€-à€
+à€²à€ à€ªà€€à¥à€ à€à¥ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à€€à¥ à€¹à¥ à¥€  }
+
+_textFromlong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯<b>à€žà¥</b> à€¬à€à€š à€à€Ÿ
+à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+à€¯à¥ à€ªà¥à€°à¥à€·à€ à€à¥ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à€€à¥
+à€¹à¥ à¥€  }
+
+_textSerieslong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <b> à€¶à¥à€°à¥à€£à¥</b> 
+à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+à€¯à¥ à€¶à¥à€°à¥à€£à¥à€à€
+ à€à¥ à€žà¥à€à€¿ à€à¥ à€ªà¥à€¶ à€à€°à€€à¥
+à€¹à¥ à¥€ }
+
+_textBrowselong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <b>à€à€°à€šà€Ÿ</b> 
+à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€ à€à€Ÿ
+à€à€°à€š à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ }
+
+_textPeoplelong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <b> à€à€šà€€à€Ÿ</b> 
+à€¬à€à€š à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€
+à€¯à¥ à€à¥à€²à€šà€Ÿà€® à€à¥ à€žà¥à€à€¿ à€à¥ à€ªà¥à€¶
+à€à€°à€€à¥ à€¹à¥ à¥€  }
+
+# -- Missing translation: _textAcronymlong_
+
+# -- Missing translation: _textPhraselong_
+
+_textArtistlong_ [l=ta] {<p>à®šà¯à®à¯à®à®³à¯ <b>à€à€²à€Ÿà€à€Ÿà€°</b> à€¬à€à€š à€à€Ÿ
+à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€šà¥à€à€®à¥
+à€ªà¥à€°à€µà¥à€¶ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ 
+à€¯à¥ à€à€²à€Ÿà€à€Ÿà€° à€à¥ à€žà¥à€à€¿
+à€à¥ à€ªà¥à€¶ à€à€°à€€à¥ à€¹à¥ à¥€  }
+
+# -- Missing translation: _textKeywordlong_
+
+# -- Missing translation: _textVolumelong_
+
+# -- Missing translation: _textCaptionslong_
+
+# -- Missing translation: _textCountrieslong_
+
+
+# -- Missing translation: _textdefaultlongtext_
+
+
+_textreadingdocs_ [l=ta] {à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€à¥
+à€à¥à€žà¥ à€ªà€¢à¥à€ à¥€}
+
+_texthelpreadingdocs_ [l=ta] {
+<p> à€à€ª à€à¥ à€ªà¥à€·à¥à€
+à€ªà¥ à€¶à¥à€°à¥à€·à€, à€²à¥à€à€ à€à€Ÿ à€šà€Ÿà€®
+à€¬à€Ÿà€¯à¥à€ à€€à€°à€« à€®à¥à€²à¥à€à€Ÿ à¥€ 
+à€€à€Šà¥à€ªà€°à€Ÿà€à€€ à€à€ª
+à€à¥ à€µà€°à¥à€€à€®à€Ÿà€š à€ªà¥à€·à¥à€
+à€žà¥ à€à€à¥ à€²à¥ à€à€Ÿà€šà¥à€µà€Ÿà€²à¥
+à€ªà¥à€·à¥à€, à€à€à¥ à€à€° à€ªà¥à€à¥ à€²à¥
+à€à€Ÿà€šà¥à€µà€Ÿà€²à¥ à€€à¥à€° à€®à¥à€²à¥à€à€à¥ à¥€
+
+<p>à€šà¥à€à¥
+à€µà€°à¥à€€à€®à€Ÿà€š à€µà€¿à€­à€Ÿà€
+à€à€Ÿ à€®à¥à€² à€®à¥à€²à¥à€à€Ÿ
+à¥€ à€à€žà¥ à€ªà€¢à€šà¥ à€à¥
+à€¬à€Ÿà€Š à€žà€¬à€žà¥ à€šà¥à€à¥
+à€à€à¥ à€à€° à€ªà¥à€à¥ à€²à¥
+à€à€Ÿà€šà¥à€µà€Ÿà€²à¥ à€€à¥à€° à€®à¥à€²à¥à€à€à¥ à¥€
+
+<p>à€¶à¥à€°à¥à€·à€ à€à€°
+à€²à¥à€à€ à€à¥ à€šà€Ÿà€®
+à€à¥ à€šà¥à€à¥ à€€à¥à€š
+à€¬à€à€š à€®à¥à€²à¥à€à€à¥ à¥€
+à€µà€°à¥à€€à€®à€Ÿà€š à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€à€Ÿ
+à€ªà¥à€°à¥à€£ à€®à¥à€²
+à€«à¥à€²à€Ÿà€šà¥ à€à¥ à€²à€¿à€ <i>à€«à¥à€²à€Ÿà€šà€Ÿ à€à¥</i>, 
+à€à€¿à€ à€à€¿à€ à€à€°à¥à€ à¥€ 
+à€šà€¯à¥ à€à€¿à€¡à€à¥
+à€à¥à€²à€šà¥ à€à¥ à€²à€¿à€ <i>à€
+à€²à€</i>,
+ à€ªà€° à€à€¿à€ à€à€¿à€
+à€à€°à¥à€ à¥€ (à€Šà¥ à€Šà€žà¥à€€à€Ÿà€µà¥à€à¥à€
+à€à¥ à€€à¥à€²à€šà€Ÿ à€à€°à€šà¥
+à€à¥ à€²à€¿à€ à€šà€¯à¥ à€à€¿à€¡à€à¥
+à€žà€¹à€Ÿà€¯à€ à€¹à¥ à¥€) à€
+à€à€€ à€®à¥, à€à¥à€ à€à€¿à€¯à€Ÿ
+à€¹à¥à€ à€¶à€¬à¥à€Š à€ªà¥à€°à€à€Ÿà€¶à€¿à€€
+à€¹à¥à€à€Ÿ à¥€ à€
+à€ªà¥à€°à€à€Ÿà€¶à€¿à€€
+à€à€°à€šà¥ à€à¥ à€²à€¿à€ <i>à€
+à€ªà¥à€°à€à€Ÿà€¶à€¿à€€</i>, 
+à€¬à€à€š à€à¥ à€à€¿à€ à€à€¿à€ à€à€°à¥à€ à¥€
+}
+
+# help about the icons
+_texthelpexpandtext_ [l=ta] {à€ªà¥à€°à¥à€£ à€®à¥à€² à€à¥
+à€ªà¥à€°à€°à¥à€Šà€·à€¿à€€
+à€à€°à¥à€, à€š à€à€°à¥à€ à¥€}
+_texthelpdetachpage_ [l=ta] {à€à€ž à€ªà¥à€·à¥à€ à€à¥
+à€šà€¯à¥ à€à€¿à€¡à€à¥ à€®à¥
+à€à¥à€²à¥ à¥€}
+_texthelphighlight_ [l=ta] {à€à¥à€à¥ à€¹à¥à€
+à€¶à€¬à¥à€Š à€à¥
+à€ªà¥à€°à€à€Ÿà€¶à€¿à€€ à€à€°à¥à€,
+à€š à€à€°à¥à€ à¥€}
+
+_texthelpsearchingtitle_ [l=ta] {à€šà€¿à€¶à¥à€à€¿à€€
+à€ªà€Šà¥à€ à€à¥ à€à¥à€žà¥
+à€à¥à€à¥}
+
+_texthelpsearching_ [l=ta] {
+<p>
+  à€à¥à€ à€ªà¥à€·à¥à€ à€žà¥, à€à€ª
+à€à€ž à€ªà¥à€°à€à€Ÿà€° à€žà€°à€³
+à€µà€¿à€§à€Ÿà€š à€¬à€šà€Ÿà€¯à¥à€ :<p>
+  
+  <ol><li>à€à¥à€ à€à¥ à€šà€¿à€¶à¥à€à€¿à€€
+à€à€°à¥ à¥€
+      <li>à€à€ª à€žà€¬ à€
+à€¥à€µà€Ÿ
+à€à¥à€ à€ªà€Šà¥à€ à€à¥
+à€à¥à€ à€à¥ à€²à€¿à€ à€šà€¿à€¶à¥à€à€¿à€€
+à€à€°à¥ à¥€
+      <li>à€à¥à€ à€šà¥ à€µà€Ÿà€²à¥ à€ªà€Šà¥à€
+à€à¥ à€à€Ÿà€à€ª à€à€°à¥ à¥€
+      <li><i>à€à¥à€à€šà€Ÿ à€¶à¥à€°à¥
+à€à€°à¥</i> à€¬à€à€š à€ªà€° à€à€¿à€
+à€à€¿à€ à€à€°à¥ à¥€
+  </ol>
+
+<p> à€à€ª à€à¥ à€à¥à€ à€à¥
+à€¬à€Ÿà€Š, à€¬à¥à€ž à€žà€¹à¥
+à€®à¥à€² à€à¥ à€Šà€žà¥à€€à€Ÿà€µà¥à€
+à€à¥ à€¶à¥à€°à¥à€·à€
+à€Šà¥à€à¥à€à€à¥ à¥€ à€
+à€à€€
+
+à€®à¥ à€
+à€à€²à¥ à€¬à¥à€ž à€Šà€žà¥à€€à€Ÿà€µà¥à€
+à€®à¥ à€à€Ÿà€šà¥ à€à¥ à€²à€¿à€ à€¬à€à€š
+à€®à¥à€²à¥à€à€Ÿ à¥€ à€à€¹à€Ÿà€žà¥
+à€
+à€à€²à¥ à€¬à¥à€ž à€Šà€žà¥à€€à€Ÿà€µà¥à€
+
+à€®à¥ à€à€Ÿà€šà¥ à€à¥ à€²à€¿à€ à€à€° à€ªà¥à€à¥
+à€à€šà¥ à€à¥ à€²à€¿à€ à€­à¥ à€¬à€à€š
+à€®à¥à€²à¥à€à€Ÿ à¥€ à€à€ª à€¶à¥à€°à¥à€·à€
+à€
+à€¥à€µà€Ÿ à€¶à¥à€°à¥à€·à€ à€à¥ à€ªà€Ÿà€ž à€µà€Ÿà€²à€Ÿ
+à€¬à€à€š à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€à€ž à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€à¥ à€Šà¥à€ à€žà€à€€à¥
+à€¹à¥ à¥€ 
+
+<p> à€à€ª à€à€°à¥à€°à€€ à€à¥ 
+à€
+à€šà¥à€žà€Ÿà€° à€ªà¥à€°à€Ÿà€¥à€®à€¿à€à€€à€Ÿà€¯à¥à€
+à€¬à€Šà€² à€žà€à€€à¥ à€¹à¥ à¥€<p> 
+}
+
+_texthelpquerytermstitle_ [l=ta] {à€à¥à€ à€ªà€Š}
+_texthelpqueryterms_ [l=ta] {
+<p> à€à€ª à€à¥ à€ªà€Šà¥à€ à€à¥
+à€à¥à€ à€žà€šà¥à€Šà¥à€
+à€®à¥à€ à€à€Ÿà€à€ª
+à€à€°à¥à€à€à¥ à€à€žà€à€Ÿ
+à€
+à€°à¥à€¥à€à€à€š "à€à¥à€ à€ªà€Š" 
+à€¹à¥à€à€Ÿ à¥€ à€¹à€° à€à€ à€ªà€Š à€µà€°à¥à€£à€®à€Ÿà€²à€Ÿ
+à€à¥ à€à€¿à€šà¥à€¹ à€à€° à€
+à€à€à¥ à€žà¥ à€¬à€šà€€à€Ÿ
+à€¹à¥ à¥€ à€Šà¥ à€ªà€Šà¥à€ à€à¥ à€à€Ÿà€²à¥ à€à€à€¹
+à€žà¥ à€
+à€²à€ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ à€µà€¿à€°à€Ÿà€®
+à€à€¿à€šà¥à€¹ à€à€Ÿ à€à€ªà€¯à¥à€ à€­à¥ à€Šà¥
+à€ªà€Šà¥à€ à€à¥ à€
+à€²à€ à€à€°à¥à€à€Ÿ à¥€ à€à€ž
+à€€à€°à€¹ à€µà€¿à€°à€Ÿà€® à€à€¿à€šà¥à€¹à¥à€ à€à¥
+à€à¥à€¡ à€Šà€¿à€¯à€Ÿ à€à€Ÿà€¯à¥à€à€Ÿ à¥€
+à€à€žà€²à€¿à€ à€à€ª à€µà€¿à€°à€Ÿà€® à€à€¿à€šà¥à€¹
+à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€à¥à€ à€šà€¹à¥ à€à€° à€žà€à€€à¥ à¥€
+
+<p>à€à€Šà€Ÿà€¹à€°à€£: à€šà€¿à€®à¥à€šà€²à€¿à€à€¿à€€
+à€à¥à€<p>
+    <ul><kbd>à€
+à€¬à¥à€Šà¥à€² à€à€²à€Ÿà€®-
+à€à€ à€žà€à€€ à€µà¥à€à¥à€à€Ÿà€šà€¿à€
+(2002)</kbd></ul>
+      <p>à€à€Ÿ à€
+à€°à¥à€¥à€à€à€š<p>
+      <ul><kbd>à€
+à€¬à¥à€Šà¥à€² à€à€²à€Ÿà€®
+à€à€ à€žà€à€€ à€µà¥à€à¥à€à€Ÿà€šà€¿à€
+2002 </kbd></ul><p>
+<p>à€¹à¥à€à€Ÿ à¥€
+}
+
+_texthelpquerytypetitle_ [l=ta] {à€à¥à€ à€à€Ÿ à€ªà¥à€°à€à€Ÿà€°}
+_texthelpquerytype_ [l=ta] {
+<p>à€à¥à€ à€à¥ à€Šà¥
+à€ªà¥à€°à€à€Ÿà€° à€¹à¥ à¥€
+
+<ul>
+  <li>à€žà€¬ à€ªà€Šà¥à€ à€à¥ à€²à€¿à€
+à€à¥à€ à€à€°à€šà€Ÿ à¥€ à€à€ž
+à€®à¥à€ à€à€ª à€Šà¥à€¬à€Ÿà€°à€Ÿ
+à€µà€°à¥à€£à€¿à€€ à€ªà€Šà¥à€ à€à¥
+à€Šà€žà¥à€€à€Ÿà€µà¥à€, à€ªà¥à€°à€à€°à€£ à€à€°
+à€¶à¥à€°à¥à€·à€à¥à€ à€®à¥à€ à€¢à¥à€à€¢à¥à€à€Ÿ à¥€
+à€à€à€¿à€€ à€Šà€žà¥à€€à€Ÿà€µà¥à€à¥à€
+à€à¥ à€µà€°à¥à€£à€®à€Ÿà€²à€Ÿ à€žà€®à¥à€¬à€šà¥à€§à€¿
+à€à¥à€°à€® à€®à¥ à€Šà€°à¥à€¶à€Ÿà€¯à¥à€à€Ÿ à¥€<p>
+
+  <li>à€à¥à€ à€ªà€Šà¥à€ à€à¥ à€²à€¿à€
+à€à¥à€ à€à€°à€šà€Ÿ à¥€ à€à€ª à€¯à€¹à¥ à€à¥à€
+à€à¥à€¯à€Ÿà€Šà€Ÿ à€®à€¹à€€à¥à€€à¥à€µ
+à€à¥ à€ªà€Šà¥à€ à€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€à¥
+à€à¥à€ à€à€° à€žà€à€€à¥ à€¹à¥ à¥€ à€à¥à€ à€ªà€Š à€à¥
+à€šà€¿à€à€ à€µà€Ÿà€²à¥ à€Šà€žà¥à€€à€Ÿà€µà¥à€ à€à€Ÿ
+à€ªà¥à€°à€Šà€°à¥à€¶à€š à€žà€¬à€žà¥
+à€ªà€¹à€²à¥ à€¹à¥à€à€Ÿ à¥€ à€à€ªà€¯à¥à€à¥à€€à€¿
+à€à€Ÿ à€šà€¿à€°à¥à€£à€¯ à€šà€¿à€®à¥à€šà€²à€¿à€à€¿à€€
+à€¬à€Ÿà€€à¥à€ à€ªà¥ à€šà€¿à€°à¥à€­à€° à€¹à¥
+      <p>
+        
+</ul>
+
+}
+
+# -- Missing translation: _textdatesearch_
+
+# -- Missing translation: _texthelpdatesearch_
+
+# -- Missing translation: _textchangeprefs_
+
+# -- Missing translation: _texthelppreferences_
+
+_texttanumbrowseoptions_ [l=ta] {à€žà€à€à¥à€°à€¹ à€žà¥
+à€à€šà€à€Ÿà€°à¥ à€ªà¥à€°à€Ÿà€ªà¥à€€
+à€à€°à€šà¥ à€à¥ à€²à¥à€¯à¥
+à€šà€¿à€®à¥à€š _numbrowseoptions_ à€€à€°à¥à€à¥
+à€ªà¥à€°à€¯à¥à€ à€à€°à¥à€
+}
+
+_textsimplehelpheading_ [l=ta] {_collectionname_ à®€à¯à®à¯à®€à®€à®²à®¿à®²à¯ à®€à®à®µà®²à¯à®à®³à¯ à®à®ªà¯à®ªà®à®¿ à®€à¯à®à®²à¯ }
+
+# -- Missing translation: _texthelpscope_
+
Index: /gsdl/stable/macros/telugu.dm
===================================================================
--- /gsdl/stable/macros/telugu.dm	(revision 20131)
+++ /gsdl/stable/macros/telugu.dm	(revision 20131)
@@ -0,0 +1,687 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Telugu Language text and icon macros, translated from english.dm
+# 12 May 2007 by Ms.Shobha Rani, P.,  Bangalore, Karnataka, India.) 
+# under the guidance of Ms.Anuradha.K.T., Senior Technical Officer,
+# National Centre for Science Information, 
+# Indian Institute of Science, Bangalore 560 012, Karnataka, India.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textperiodicals_
+# -- Missing translation: _textsource_
+# -- Missing translation: _textdate_
+# -- Missing translation: _textnumpages_
+
+# -- Missing translation: _textsignin_
+
+# -- Missing translation: _textdefaultcontent_
+
+_textdefaulttitle_ [l=te] {à°à°¿ à°à°žà± à°¡à°¿ à°à°²à±}
+
+# -- Missing translation: _textbadcollection_
+
+# -- Missing translation: _textselectpage_
+
+# -- Missing translation: _collectionextra_
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+# -- Missing translation: _collectorextra_
+
+_textdescrcollection_ [l=te] {}
+# -- Missing translation: _textdescrabout_
+_textdescrhome_ [l=te] {à°®à±à°à±à°¯ à°®à±à°š à°ªà±à°à°¿}
+_textdescrhelp_ [l=te] {à°žà°¹à°Ÿà°¯ à°ªà±à°à°¿ }
+_textdescrpref_ [l=te] {à°à°šà±à°šà°¿à° à°ªà±à°à°¿}
+_textdescrgreenstone_ [l=te] {à°¡à°¿à°à°¿à°à°²à± à°à±à°°à±Šà°§à°Ÿà°²à°¯à°®à± à°žà°Ÿà°«à±à°à±à°«à°µà±à°°à±}
+# -- Missing translation: _textdescrusab_
+
+_textdescrsearch_ [l=te] { à°à°à±à°à°¿à°€à°®à±à°š à°ªà°Šà°Ÿà°²à°šà± à°µà±à°Šà°à±Šà°¡à°¿}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=te] { à°µà°°à±à°£à°®à°Ÿà°² à°ªà°à±à°à°¿ à°
+à°à°à±à°² à°¶à±à°°à±à°·à°¿à°à°šà±  à°¬à±à°°à±à°à± à°à±à°¯à°à°¡à°¿}
+_textdescrCreator_ [l=te] { à°°à°à°¯à°¿à°€à°²à°šà± à°µà°°à±à°£à°®à°Ÿà°² à°
+à°šà±à°žà°°à°¿à°à°à°¿ à°¬à±à°°à±à°à± à°à±à°¯à°à°¡à°¿}
+_textdescrSubject_ [l=te] {à°µà°¿à°·à°¯à°Ÿà°²à°šà± à°
+à°šà±à°žà°°à°¿à°à°à°¿ à°¬à±à°°à±à°à± à°à±à°¯à°à°¡à°¿}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=te] {à°€à±à°Šà±à°²à°šà± à°
+à°šà±à°žà°°à°¿à°à°à°¿ à°¬à±à°°à±à°à± à°à±à°¯à°à°¡à°¿}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+# -- Missing translation: _textdescrSource_
+# -- Missing translation: _textdescrLanguage_
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=te] {à°žà°à°žà±à°¥à°²à°šà± à°
+à°šà±à°žà°°à°¿à°à°à°¿ à°¬à±à°°à±à°à± à°à±à°¯à°à°¡à°¿}
+# -- Missing translation: _textdescrKeyword_
+_textdescrHowto_ [l=te] {à°à°²à°Ÿà°à°à°¿ à°µà°°à±à°£à°Ÿà°²à°šà± à°¬à±à°°à±à°à± à°à±à°¯à°à°¡à°¿}
+_textdescrList_ [l=te] {à°Šà°žà±à°€à°Ÿà°µà±à°à±à°²à°šà± à°
+à°šà±à°žà°°à°¿à°à°à°¿ à°¬à±à°°à±à°à± à°à±à°¯à°à°¡à°¿}
+_textdescrSeries_ [l=te] {à°žà°à°à°¿à°à°²à°šà± à°
+à°šà±à°žà°°à°¿à°à°à°¿ à°¬à±à°°à±à°à± à°à±à°¯à°à°¡à°¿}
+# -- Missing translation: _textdescrTo_
+# -- Missing translation: _textdescrFrom_
+_textdescrTopic_ [l=te] {à°µà°¿à°¶à±à°· à°ªà±à°°à°à°°à°£à°Ÿà°²à°šà± à°¬à±à°°à±à°à± à°à±à°¯à°à°¡à°¿}
+_textdescrBrowse_ [l=te] {à°¬à±à°°à±à°à± à°à±à°¯à°à°¡à°¿}
+# -- Missing translation: _textdescrCollage_
+_textdescrPeople_ [l=te] {à°ªà±à°°à°à°²à°šà± à°µà°°à±à°£à°®à°Ÿà°² à°à°ªà°¯à±à±à°à°¿à°à°à°¿ à°¬à±à°°à±à°à± à°à±à°¯à°à°¡à°¿}
+# -- Missing translation: _textdescrAcronym_
+# -- Missing translation: _textdescrPhrase_
+# -- Missing translation: _textdescrArtist_
+# -- Missing translation: _textdescrVolume_
+# -- Missing translation: _textdescrCountries_
+# -- Missing translation: _textdescrCaptions_
+
+
+_labelSearch_ [l=te] {à°¬à±à°°à±à°à± à°à±à°¯à°à°¡à°¿}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=te] {à°¶à±à°°à±à°·à°¿à° A-Z}
+
+_labelCreator_ [l=te] {à°¶à±à°°à±à°·à°¿à° à°°à°à°¯à°€à°²à±  à°žà±Šà°žà±à°¥à°²à±
+à€²à¥à€à€ A-Z}
+_labelSubject_ [l=te] {à°µà°¿à°·à°¯à±Š } 
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=te] {à°µà°Ÿà°°à±Š}
+# -- Missing translation: _labelTypes_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+# -- Missing translation: _labelSource_
+# -- Missing translation: _labelLanguage_
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=te] {à°žà±Šà°žà±à°¥à°²à±}
+# -- Missing translation: _labelKeyword_
+_labelHow_ [l=te] {à°à°²à°Ÿ}
+_labelSeries_ [l=te] {à°¶à±à°°à±à°£à°¿}
+_labelList_ [l=te] {à°žà±à°à°¿à°}
+# -- Missing translation: _labelTo_
+# -- Missing translation: _labelFrom_
+_labelTopic_ [l=te] {à°ªà±à°°à°à°°à°£à°²à±}
+_labelBrwse_ [l=te] {à°à°°à°£à°Ÿà°²à±}
+# -- Missing translation: _labelCollage_
+# -- Missing translation: _labelBrows_
+_labelPeople_ [l=te] {à°ªà±à°°à°à°²à±A-Z}
+# -- Missing translation: _labelAcronym_
+# -- Missing translation: _labelPhrase_
+# -- Missing translation: _labelArtist_
+# -- Missing translation: _labelVolume_
+# -- Missing translation: _labelCaptions_
+# -- Missing translation: _labelCountries_
+
+_texticontext_ [l=te] {à°ªà°Ÿà° à±à°¯à°Ÿà±Šà°¶à°Ÿà°šà±à°šà°¿ à°à±à°¡à±Šà°¡à°¿}
+_texticonclosedbook_ [l=te] {à°ªà°Ÿà° à±à°¯à°Ÿà±Šà°¶à°Ÿà°šà±à°šà°¿ à°€à±à°°à°¿à°à°¿ à°à±à°¡à±Šà°¡à°¿}
+ _texticonnext_ [l=te] {à°€à°°à±à°µà°Ÿà°€à°¿ à°­à°Ÿà°à°}
+_texticonprev_ [l=te] {à°®à±à±à°Šà°à°¿ à°­à°Ÿà°à°} 
+# -- Missing translation: _texticonworld_
+
+# -- Missing translation: _texticonmidi_
+# -- Missing translation: _texticonmsword_
+# -- Missing translation: _texticonmp3_
+# -- Missing translation: _texticonpdf_
+# -- Missing translation: _texticonps_
+# -- Missing translation: _texticonppt_
+# -- Missing translation: _texticonrtf_
+# -- Missing translation: _texticonxls_
+
+_page_ [l=te] {à°ªà±à°à°¿}
+_pages_ [l=te] {à°ªà±à°à±à°²à±}
+_of_ [l=te] {à°²à±}
+_vol_ [l=te] {à°žà±Šà°ªà±à°}
+_num_ [l=te] {à°šà±à±Šà°¬à°°à±}
+
+_textmonth00_ [l=te] {}
+_textmonth01_ [l=te] {à°à°šà°µà°°à°¿}
+_textmonth02_ [l=te] {à°«à°¿à°¬à±à°°à°µà°°à°¿}
+_textmonth03_ [l=te] {à°®à°Ÿà°°à±à°à°¿}
+_textmonth04_ [l=te] {à°à°ªà±à°°à°¿à°²à±}
+_textmonth05_ [l=te] { à°®à±}
+_textmonth06_ [l=te] { à°à±à°šà±}
+_textmonth07_ [l=te] {à°à±à°²à±}
+_textmonth08_ [l=te] {à°à°à°·à±à°à± }
+_textmonth09_ [l=te] {à°žà±à°ªà±à°à°à°­à°°à± }
+_textmonth10_ [l=te] {à°
+à°à±à°à±à°­à°°à± }
+
+_textmonth11_ [l=te] {à°šà°µà±Šà°­à°°à±}
+_textmonth12_ [l=te] {à°¡à°¿à°¶à±Šà°­à°°à±à°®à±à°°à± à°à°Ÿà°µà°²à±Šà°à± à°à°šà±à°šà°¿à° à°à±à°žà°¿à°š à°ªà±à°à°²à°²à±à°à°šà±à°š à°à°ªà°žà±Šà°à±à°°à°¹à°Ÿà°²à°€à± à°ªà°°à±à°à±à°·à±à±Šà°à°µà°à±à°à±}
+ 
+# -- Missing translation: _textdocument_
+# -- Missing translation: _textsection_
+# -- Missing translation: _textparagraph_
+
+# -- Missing translation: _magazines_
+
+# -- Missing translation: _nzdlpagefooter_
+
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=te] {à°à°à±à°à°¡ à°žà±Šà°à±à°°à°¹à±Š  à°à±à°°à°¿à±Šà°à°¿}
+
+_textsubcols1_ [l=te] {<p>à°žà±Šà°ªà±à°°à±à°£ à°žà±Šà°à±à°°à°¹à±Š à°à°ªà°žà±Šà°à±à°°à°¹à°²à°€à± à°à±à°žà°Ÿà°°à± :
+<blockquote>}
+
+_textsubcols2_ [l=te] {</blockquote> à°®à±à°°à± à°à°Ÿà°µà°²à±Šà°à± à°à°šà±à°šà°¿à° à°à±à°žà°¿à°š à°ªà±à°à°²à°²à±à°à°šà±à°š à°à°ªà°žà±Šà°à±à°°à°¹à°Ÿà°²à°€à± à°ªà°°à±à°à±à°·à±à±Šà°à°µà°à±à°à±}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhsrc_
+# -- Missing translation: _texticonhlang_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+# -- Missing translation: _texticonhcoll_
+# -- Missing translation: _texticonhto_
+# -- Missing translation: _texticonhfrom_
+# -- Missing translation: _texticonhbrows_
+# -- Missing translation: _texticonhacronym_
+# -- Missing translation: _texticonhphrases_
+# -- Missing translation: _texticonhartist_
+# -- Missing translation: _texticonhkw_
+# -- Missing translation: _texticonhvol_
+# -- Missing translation: _texticonhcapt_
+# -- Missing translation: _texticonhcount_
+
+_texticonopenbookshelf_ [l=te] {à° à°­à°Ÿà°à°Ÿà°šà±à°šà°¿ à°®à±à°žà°¿à°µà±à°¯à±Šà°¡à°¿}
+_texticonclosedbookshelf_ [l=te] {à° à°­à°Ÿà°à°Ÿà°šà±à°šà°¿ à°€à±à°°à°¿à°à°¿ à°à°à°à±Šà°¡à°¿}
+_texticonopenbook_ [l=te] {à° à°­à°Ÿà°à°Ÿà°šà±à°šà°¿  à°€à±à°°à°¿à°à°¿ à°à°à°à±Šà°¡à°¿}
+_texticonclosedfolder_ [l=te] {à°à°«à±à°²à±à°¡à°°à± à°€à±à°°à°¿à°à°¿ à°à°à°à±Šà°¡}
+_texticonclosedfolder2_ [l=te] {à°à°ªà°žà±Šà°à±à°°à°¹à°šà±à°šà°¿à¥€}
+_texticonopenfolder_ [l=te] {à°à°«à±à°²à±à°¡à°°à± à°®à±à°žà°¿à°µà±à°¯à±Šà°¡à°¿}
+_texticonopenfolder2_ [l=te] {à°à°ªà°žà±Šà°à±à°°à°¹à°šà±à°šà°¿ à°®à±à°žà°¿à°µà±à°¯à±Šà°¡à°¿ }
+_texticonsmalltext_ [l=te] {à°à°­à°Ÿà°à±Šà°²à±à°šà°¿ à°®à±à°Šà°²à± à°¶à°¬à±à°Šà°Ÿà°šà±à°šà°¿ à°à±à°¡à±Šà°¡à°¿} 
+_texticonsmalltext2_ [l=te] {à°®à±à°²à°žà±Šà°¬à±Šà°Šà°Ÿà°šà±à°šà°¿ à°à±à°¡à±Šà°¡à°¿}
+_texticonpointer_ [l=te] {à°ªà±à°°à°à°²à°¿à°€ à°­à°Ÿà°o}
+_texticondetach_ [l=te] {à° à°ªà±à°à±à°²à°šà±  à°šà±à°¯à± à°µà°¿à±Šà°¡à±à°²à± à°€à±à°°à°¿à°à°¿ à°à±à°¡à±Šà°¡à°¿ }
+_texticonhighlight_ [l=te] {à°µà±à°€à°¿à°à°¿à°š à°ªà°Šà°Ÿà°²à°šà± à°¹à±à°²à°à± à°à±à°¯à±Šà°¡à°¿}
+# -- Missing translation: _texticonnohighlight_
+# -- Missing translation: _texticoncontracttoc_
+# -- Missing translation: _texticonexpandtoc_
+# -- Missing translation: _texticonexpandtext_
+# -- Missing translation: _texticoncontracttext_
+_texticonwarning_ [l=te] {<b> </b>}
+# -- Missing translation: _texticoncont_
+
+_textltwarning_ [l=te] {<div class="buttons">_imagecont_</div>
+_iconwarning_
+}
+
+# -- Missing translation: _textgoto_
+_textintro_ [l=te] {<i></i>}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=te] {_If_(_thislast_,à°ªà°°à°¿à°£à°Ÿà°®à±Š_thisfirst_ - _thislast_à° à°ªà±à°°à°¶à±à°šà°à± 
+_cgiargq_,à° à°ªà±à°°à°¶à±à°šà°à± à°à°Šà°¿ à°®à±à°¯à°Ÿà°à± à°à°Ÿà°²à±à°Šà± _cgiargq_)}
+_textnoquerytitle_ [l=te] {à°
+à°šà±à°¶à±à°Šà°¿à±Šà°à°¿à°š à°ªà±à°à°¿} 
+_textsome_ [l=te] {_If_(_cgiargb_, à°¶à±à°°à±à°£à°¿à°¯ à°ªà±à°à°¿}
+_textall_ [l=te] {_If_(_cgiargb_, à°¬à±à°²à°¿à°¯à°šà±}
+# -- Missing translation: _textboolean_
+# -- Missing translation: _textranked_
+# -- Missing translation: _textnatural_
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+# -- Missing translation: _texticonsearchhistorybar_
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+# -- Missing translation: _textusequery_
+_textfreqmsg1_ [l=te] {à°ªà°Šà°à°®à°šà±Š}
+_textpostprocess_ [l=te] {_If_(_quotedquery_,<br><i>à°®à±à±Šà°Šà±à°à°Ÿ à°à°šà±à°š à°ªà°à±à°°à°¿à°¯à°šà± à°¶à±à°Šà°šà°à± à°€à±à°žà±à°à±à±Šà°¡à°¿
+_quotedquery_ </i>)}
+# -- Missing translation: _textinvalidquery_
+
+_textmorethan_ [l=te] {à°à°à±à°à±à°µà°à°Ÿ}
+# -- Missing translation: _textapprox_
+_textnodocs_ [l=te] {à° à°ªà±à°°à°¶à±à°šà°à± à°à°Šà°¿ à°®à±à°¯à°Ÿà°à± à°à°Ÿà°²à±à°Šà±}
+_text1doc_ [l=te] {à° à°ªà±à°°à°¶à±à°š à°Šà°žà±à°€à°Ÿà°µà±à°à±à°€à±  à°à°²à°¿à°žà°¿à±Šà°Šà°¿}
+_textlotsdocs_ [l=te] {à° à°ªà±à°°à°¶à±à°š à°Šà°žà±à°€à°Ÿà°µà±à°à±à°€à±  à°à°²à°¿à°žà°¿à±Šà°Šà°¿}
+_textmatches_ [l=te] {à°à°²à°¿à°žà°¿à±Šà°Šà°¿}
+_textbeginsearch_ [l=te] {à°µà±à°Šà°à°à±Š à°ªà±à°°à°Ÿà°°à°­à°¿à±Šà°à±Šà°¡à°¿}
+# -- Missing translation: _textrunquery_
+# -- Missing translation: _textclearform_
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+# -- Missing translation: _textwordphrase_
+# -- Missing translation: _textinfield_
+# -- Missing translation: _textfoldstem_
+
+# -- Missing translation: _textadvquery_
+# -- Missing translation: _textallfields_
+# -- Missing translation: _texttextonly_
+# -- Missing translation: _textand_
+# -- Missing translation: _textor_
+# -- Missing translation: _textandnot_
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=te] {à°µà±à°Šà°à±Šà°¡à°¿ _indexselection_ _If_(_jselection_, à°šà±à±Šà°¡à°¿ 
+_jselection_ )_If_(_nselection_, _nselection_ )  à°à±Šà°Šà±à°²à±  _querytypeselection_  à°ªà°Šà°Ÿà°²à± à°à±Šà°à±à¥€}
+
+_textadvancedsearch_ [l=te] {à°µà±à°Šà°à±Šà°¡à°¿ _indexselection_ _If_(_jselection_, à°šà±à±Šà°¡à°¿ _jselection_)_If_(_nselection_, _nselection_ à°­à°Ÿà°·) à°à±Šà°Šà±à°²à± _querytypeselection_à°ªà°Šà°Ÿà°²à± à°à±Šà°à± }
+
+# -- Missing translation: _textformsimplesearch_
+
+# -- Missing translation: _textformadvancedsearch_
+
+
+# -- Missing translation: _textnojsformwarning_
+# -- Missing translation: _textdatesearch_
+# -- Missing translation: _textstartdate_
+# -- Missing translation: _textenddate_
+# -- Missing translation: _textbc_
+# -- Missing translation: _textad_
+# -- Missing translation: _textexplaineras_
+
+_textstemon_ [l=te] {(à°žà°Ÿà°µà°Šà°Ÿà°šà±Šà° à°à±à°¡à±Šà°¡à°¿}
+
+_textsearchhistory_ [l=te] {à°
+à°šà±à°¶à±à°§à°š à°à°°à°¿à°€à±à°°}
+
+#text macros for search history
+_textnohistory_ [l=te] {à°
+à°šà±à°¶à±à°§à°š à°à°°à°¿à°€à±à°°à°šà± à°à±à°ªà±à°à±à°à°µà°Šà±à°Šà±}
+# -- Missing translation: _texthresult_
+# -- Missing translation: _texthresults_
+# -- Missing translation: _texthallwords_
+# -- Missing translation: _texthsomewords_
+# -- Missing translation: _texthboolean_
+# -- Missing translation: _texthranked_
+# -- Missing translation: _texthcaseon_
+# -- Missing translation: _texthcaseoff_
+# -- Missing translation: _texthstemon_
+# -- Missing translation: _texthstemoff_
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textprefschanged_
+_textsetprefs_ [l=te] {à°ªà±à°°à°Ÿà°§à°®à°¿à°à°€ à°šà°¿à°°à±à°£à°¯à°¿à±Šà°à±à°à±à±Šà°¡à°¿}
+_textsearchprefs_ [l=te] {à°ªà±à°°à°Ÿà°§à°®à°¿à°à°€ à°¶à±à°§à°¿à±Šà°à±Šà°¡à°¿}
+ _textcollectionprefs_ [l=te] {à°ªà±à°°à°Ÿà°§à°®à°¿à°à°€ à°žà±Šà°à±à°°à°¹à±Š}
+_textpresentationprefs_ [l=te] {à°ªà±à°°à°Šà°°à±à°¶à°¿à±Šà°à°Šà°à±à° à°ªà±à°°à°Ÿà°§à°®à°¿à°à°€}
+_textpreferences_ [l=te] {à°ªà±à°°à°Ÿà°§à°®à°¿à°à°€}
+# -- Missing translation: _textcasediffs_
+# -- Missing translation: _textignorecase_
+# -- Missing translation: _textmatchcase_
+_textwordends_ [l=te] {à°žà°Ÿà°µà°Šà°Ÿà°šà±Šà° à°à±à°¡à±Šà°¡à°¿}
+_textstem_ [l=te] {à°žà°Ÿà°µà°Šà°Ÿà°šà±Šà° à°à±à°¡à±Šà°¡à°¿}
+_textnostem_ [l=te] {à°ªà±à°°à±à°£à°®à±à°šà°¶à°­à±à°Šà°Ÿà°šà±à°šà°¿ à°à°²à°ªà±Šà°¡à°¿}
+_textprefop_ [l=te] {_maxdocoption_ à°ªà°°à°¿à°£à°Ÿà°®à°Ÿà°² à°ªà°à±à°à°¿à° à°šà±à±Šà°¡à°¿  _hitsperpageoption_à°ªà°°à°¿à°£à°Ÿà°®à°Ÿà°² à°ªà±à°°à°€à°¿ à°ªà±à°à±à°šà°¿ à°à±à°ªà±à°à±à°à±Šà°¡à°¿}
+_textextlink_ [l=te] {à°ªà°Ÿà°°à°Šà°°à±à°¶à°šà±Š à°¬à±à° à°à°šà±à°š à°µà±à°¬à± à°ªà±à°à°¿à°šà°¿ à°à±à°¡à±Šà°¡à°¿}
+_textintlink_ [l=te] {à°®à±à°² à°Šà°žà±à°€à°Ÿà°µà±à°à±à°šà± à°à°à±à°à°¡à°¿ à°šà±à±Šà°¡à°¿ à°²à°­à°¿à±Šà°à°¿à±Šà°Šà°¿:}
+_textlanguage_ [l=te] {à°à±Šà°à°°à± à°«à±à°žà± à°­à°Ÿà°·}
+_textencoding_ [l=te] {à°à°šà±à±à°à±à°¡à°¿à±Šà°à± à°°à°à°š: }
+_textformat_ [l=te] {à°à±Šà°à°°à± à°«à±à°žà± à°°à°à°š}
+_textall_ [l=te] {à°
+à°šà±à°šà°¿}
+_textquerymode_ [l=te] {à°ªà°°à°¿à°¶à±à°§à°š à°ªà±à°°à°à°Ÿà°°à±Š}
+_textsimplemode_ [l=te] {à°žà°°à°³à± à°ªà°°à°¿à°¶à±à°§à°š}
+_textadvancedmode_ [l=te] {à°à°šà±à°šà°€à°®à±à°š à°¶à±à°§à°š à°¬à±à°²à°¿à°¯à°šà± à°¶à±à°§à°šà°à±à°¯à°µà°à±à°à±}
+# -- Missing translation: _textlinkinterm_
+_textlinkdirect_ [l=te] {à°žà°°à°¿à°à±à°à°Ÿ à°
+à°à±à°µà±à°³à±à°²à±Šà°¡à°¿ à°à±à°°à±Šà°¥à°Ÿà°¡à°¿à°à°¿à°à°²à± à°²à°¯à±Š}
+_textdigitlib_ [l=te] {à°à±à°°à±Šà°¥à°Ÿà°¡à°¿à°à°¿à°à°²à± à°²à°¯à±Š}
+_textweb_ [l=te] {à°µà±à°¬à±}
+_textgraphical_ [l=te] {à°žà±à°à°¿à±Šà°à°¿à°š} 
+_texttextual_ [l=te] {à°®à±à°²à°ªà°Ÿà° à±Š}
+ _textcollectionoption_ [l=te] {<p>
+à°à°ªà°žà±Šà°à±à°°à°¹à°Ÿà°²à°šà± à°à°²à°ªà±Šà°¡à°¿ <br>}
+
+_textrelateddocdisplay_ [l=te]  {à°žà±Šà°­à±Šà°§à°¿à±Šà°à°¿à°š à°Šà°žà±à°€à°Ÿà°µà±à°à±à°²à°šà± à°ªà±à°°à°Šà°°à±à°¶à°¿à±Šà°à±Šà°¡à°¿ } 
+_textsearchhistory_ [l=te] { à°
+à°šà±à°¶à±à°§à°š à°à°°à°¿à°€à±à°°}
+# -- Missing translation: _textnohistory_
+_texthistorydisplay_ [l=te] { à°
+à°šà±à°¶à±à°§à°š _historynumrecords_ à°à°°à°¿à°€à±à°° à°ªà±à°°à°Šà°°à±à°¶à°¿à±Šà°à±Šà°¡à°¿ }
+_textnohistorydisplay_ [l=te] { à°
+à°šà±à°¶à±à°§à°š à°à°°à°¿à°€à±à°°à°šà±à°à±à°ªà±à°à±à°à°µà°Šà±à°Šà±}
+
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+# -- Missing translation: _textformsearch_
+# -- Missing translation: _textplainsearch_
+_textqueryboxsize_ [l=te] { à°ªà±à°Šà±à°Š à°ªà±à°°à°¶à±à°šà°² à°ªà°à±à°à°¿ à°žà°°à°³à±Š à°à°šà±à°šà°€à±Š  à°šà°¿à°¯à°®à°¿à°€	
+
+_textregbox_ [l=te] { à°šà°¿à°¯à°®à°¿à°€ à°ªà±à°°à°¶à±à°šà°² à°ªà°à±à°à°¿ }
+_textbigbox_ [l=te] {{ à°ªà±à°Šà±à°Š à°ªà±à°°à°¶à±à°šà°² à°ªà°à±à°à°¿ }
+# -- Missing translation: _textformtype_
+_textsimple_ [l=te] { à°žà°°à°³à±Š}
+_textadvanced_ [l=te] { à°à°šà±à°šà°€à±Š}
+
+# used in "with 4 fields" in the form search box
+# -- Missing translation: _textwith_
+# -- Missing translation: _textfields_
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+# -- Missing translation: _textsortby_
+# -- Missing translation: _textalsoshowing_
+# -- Missing translation: _textwith_
+# -- Missing translation: _textdocsperpage_
+
+# -- Missing translation: _textfilterby_
+# -- Missing translation: _textall_
+# -- Missing translation: _textany_
+# -- Missing translation: _textwords_
+# -- Missing translation: _textleaveblank_
+
+# -- Missing translation: _browsebuttontext_
+
+# -- Missing translation: _nodata_
+# -- Missing translation: _docs_
+
+
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textHelp_
+_textSearchshort_ [l=te] { à°à°à±à°à°¿à°€à°®à±à°š à°ªà°Šà°Ÿà°²à°šà± à°µà±à°Šà°à±Šà°¡à°¿ }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=te] { à°¶à±à°°à±à°·à°¿à°à°²à°šà± à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°à±à°à±Šà°¡à°¿ }
+_textCreatorshort_ [l=te] { à°°à°à°¯à±à°à°€à°²à°šà± à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°à±à°à±Šà°¡à°¿ }
+_textSubjectshort_ [l=te] { à°µà°¿à°·à°¯à°Ÿà°²à°šà± à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°à±à°à±Šà°¡à°¿ }
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=te] { à°€à±à°Šà±à°²à°šà± à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°à±à°à±Šà°¡à°¿ }
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=te] { à°°à°à°¯à±à°à°€à°²à°šà± à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°à±à°à±Šà°¡à°¿ }
+# -- Missing translation: _textLanguageshort_
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=te] { à°¶à±à°°à±à°£à°¿à°šà°¿ à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°à±à°à±Šà°¡à°¿ }
+# -- Missing translation: _textToshort_
+# -- Missing translation: _textFromshort_
+_textBrowseshort_ [l=te] { à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°šà± à°¬à±à°°à±à°žà± à°à±à°¯à±Šà°¡à°¿ }
+_textOrganizationshort_ [l=te] { à°žà±Šà°žà±à°¥à°²à°šà± à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°à±à°à±Šà°¡à°¿ }
+_textHowtoshort_ [l=te] { à°à°²à°Ÿ à°·à°Ÿà°°à±à°à± à°à±à°¯à°Ÿà°²à°šà°¿ à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°à±à°à±Šà°¡à°¿ }
+_textTopicshort_ [l=te] { à°ªà±à°°à°à°°à°£à°²à°šà± à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°à±à°à±Šà°¡à°¿ }
+_textPeopleshort_ [l=te] { à°ªà±à°°à°à°²à°šà± à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°à±à°à±Šà°¡à°¿ } 
+# -- Missing translation: _textAcronymshort_
+# -- Missing translation: _textPhraseshort_
+_textArtistshort_ [l=te] { à°à°³à°Ÿà°à°Ÿà°°à±à°²à°šà± à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°à±à°à±Šà°¡à°¿}
+# -- Missing translation: _textKeywordshort_
+# -- Missing translation: _textVolumeshort_
+# -- Missing translation: _textCountriesshort_
+# -- Missing translation: _textdefaultshorttext_
+
+_textSearchlong_ [l=te] {<p> à°®à±à°°à± à°®à±à°² à°à±à°°à±Šà°¥à±Šà°²à± à°à°à±à°à°¿à°€à°®à±à°š à°ªà°Šà±Šà°šà±  à°µà±à°€à±à°à± à°ªà±à°à±à°šà°¿à°à°ªà°¯à±à°Ÿà°à°¿à±Šà°à°¿  à°µà±à°Šà°à°µà°à±à°à± à°à°à±à°à°¡ à°®à±à±à°Šà° à°ªà±à°à°¿ à°à±Šà°Šà°¿ à°à°à±à°à°¡ à°®à±à°°à± à°¬à±à°°à±à°à± à°¬à°à°šà± à°à°ªà°¯à±à±à°à°¿à°à°à°¿ à°€à°°à±à°µà°Ÿà°€ à°ªà±à°à°¿à°à°¿ à°µà±à°³à±à°²à°µà°à±à°à±}
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=te] {<p> à°®à±à°°à± <b> à°¶à±à°°à±à°·à°¿à° </b>
+ à°¬à°à°šà± à°à°ªà°¯à±à±à°à°¿à°à°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°²à± à°ªà±à°°à°µà±à°¶à°¿à°à°à°µà°à±à°à±   à°à°Šà°¿ à°µà°°à±à°£à°®à°Ÿà°² à°žà°à°¬à°à°Šà°®à±à°š à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à°à°Šà°¿ }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=te] {<p> à°®à±à°°à± <b> à°°à°à°à°€</b> 
+{à°°à°à°à°€  à°¬à°à°šà± à°à°ªà°¯à±à±à°à°¿à°à°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°²à± à°ªà±à°°à°µà±à°¶à°¿à°à°à°µà°à±à°à±   à°à°Šà°¿  à°°à°à°à°€à°²à°à± à°žà°à°¬à°à°Šà°®à±à°š à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à°à°Šà°¿ }
+
+_textSubjectlong_ [l=te] {<p> à°®à±à°°à± <b> à°µà°¿à°·à°¯à±Š </b>
+ à°¬à°à°šà± à°à°ªà°¯à±à±à°à°¿à°à°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°²à± à°ªà±à°°à°µà±à°¶à°¿à°à°à°µà°à±à°à±   à°à°Šà°¿  à°ªà±à°žà±à°€à°à°Ÿà°² à°µà°°à°à± à°ªà±à°°à°Ÿà°€à°¿à°šà°¿à°Šà±à°¯à±Š à°µà°¹à°¿à±Šà°à°¿à°š  à°µà°¿à°·à°¯à±Š à°žà°à°¬à°à°Šà°®à±à°š à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à°à°Šà°¿ }
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=te] {<p> à°®à±à°°à± <b> à°€à°Ÿà°°à±à°à±</b> 
+à°¬à°à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°²à± à°ªà±à°°à°µà±à°¶à°¿à°à°à°µà°à±à°à±   à°à°Šà°¿ à°€à°Ÿà°°à±à°à±à°² à°žà°à°¬à°à°Šà°®à±à°š à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à°à°Šà°¿ }
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=te] {<p>à°®à±à°°à± <i>à°®à±à°²à°à±à°°à±Šà°¥à±Š</i> à°¬à°à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿  à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°²à± à°ªà±à°°à°µà±à°¶à°¿à°à°à°µà°à±à°à±   à°à°Šà°¿ à°®à±à°²à°à±à°°à±Šà°¥à±Š à°žà°à°¬à°à°Šà°®à±à°š à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à°à°Šà°¿ }
+
+# -- Missing translation: _textLanguagelong_
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=te] {<p>à°®à±à°°à± <b> à°žà±Šà°à°à°š </b> 
+à°¬à°à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿  à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°²à± à°ªà±à°°à°µà±à°¶à°¿à°à°à°µà°à±à°à±   à°à°Šà°¿ à°žà±Šà°à°à°š  à°žà°à°¬à°à°Šà°®à±à°š à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à°à°Šà°¿ }
+
+_textHowtolong_ [l=te] {<p>à°®à±à°°à± <b> à°à°²à°Ÿ </b> à°¬à°à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿  à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°²à± à°ªà±à°°à°µà±à°¶à°¿à°à°à°µà°à±à°à±   à°à°Šà°¿   à°à°²à°Ÿ à°žà°à°¬à°à°Šà°®à±à°š à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à°à°Šà°¿ }
+
+_textTopiclong_ [l=te] {<p>à°®à±à°°à± <b> à°ªà±à°°à°žà±Šà°à°Ÿà°² </b> à°¬à°à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿  à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°²à± à°ªà±à°°à°µà±à°¶à°¿à°à°à°µà°à±à°à±   à°à°Šà°¿ à°ªà±à°°à°žà±Šà°à°Ÿà°² à°žà°à°¬à°à°Šà°®à±à°š à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à°à°Šà°¿ }
+
+_textTolong_ [l=te] {<p>à°®à±à°°à±b>à°à°¿à°°à±à°šà°Ÿà°®</b>à°®à±à°°à± à°à°¿à°°à±à°šà°Ÿà°® à°¬à°à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°ªà±à°°à°µà±à°¶à°¿à±Šà°à°µà°à±à°à± à°à°Šà°¿ à°µà±à°°à± à°µà±à°°à± à°à°¿à°°à±à°šà°Ÿà°®à°² à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à±Šà°Šà°¿}
+ 
+ _textFromlong_ [l=te] {<p>à°®à±à°°à±<b>à°žà±</b> à°®à±à°°à± à°žà± à°¬à°à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°ªà±à°°à°µà±à°¶à°¿à±Šà°à°µà°à±à°à± à°à°Šà°¿ à°ªà±à°°à°à°°à°£à°²à± à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à±Šà°Šà°¿} 
+ 
+_textSerieslong_ [l=te] {<p>à°®à±à°°à± <b> à°¶à±à°°à±à°£à°¿/b> à°®à±à°°à± à°¶à±à°°à±à°£à°¿ à°¬à°à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°ªà±à°°à°µà±à°¶à°¿à±Šà°à°µà°à±à°à± à°à°Šà°¿ à°µà±à°°à± à°µà±à°°à± à°¶à±à°°à±à°£à°¿à°² à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à±Šà°Šà°¿}
+ 
+
+_textBrowselong_ [l=te] {<p>à°®à±à°°à±<b>à°à°°à°£à°Ÿà°²</b>à°®à±à°°à± à°à°°à°£à°Ÿà°² à°¬à°à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°ªà±à°°à°µà±à°¶à°¿à±Šà°à°µà°à±à°à± à°à°Šà°¿ à°µà±à°°à± à°µà±à°°à± à°à°°à°£à°Ÿà°²  à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à±Šà°Šà°¿}
+ 
+
+_textPeoplelong_ [l=te] {<p>à°®à±à°°à± <b> à°ªà±à°°à°à°² ,</b> à°®à±à°°à± à°ªà±à°°à°à°²  à°¬à°à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°ªà±à°°à°µà±à°¶à°¿à±Šà°à°µà°à±à°à± à°à°Šà°¿ à°µà±à°°à± à°µà±à°°à± à°ªà±à°°à°à°² à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à±Šà°Šà°¿}
+
+# -- Missing translation: _textAcronymlong_
+
+# -- Missing translation: _textPhraselong_
+
+_textArtistlong_ [l=te] {<p>à°®à±à°°à± <b>à°à°³à°Ÿà°à°Ÿà°°à±à°² </b>à°®à±à°°à± à°à°³à°Ÿà°à°Ÿà°°à±à°²  à°¬à°à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿ à°ªà°¬à±à°²à°¿à°à±à°·à°šà±à°žà± à°ªà±à°°à°µà±à°¶à°¿à±Šà°à°µà°à±à°à± à°à°Šà°¿ à°µà±à°°à± à°µà±à°°à± à°à°³à°Ÿà°à°Ÿà°°à±à°²  à°žà±à°à°¿à°à°šà± à°ªà±à°°à°µà±à°¶à°ªà±à°¡à±à°€à±à±Šà°Šà°¿|}
+# -- Missing translation: _textKeywordlong_
+
+# -- Missing translation: _textVolumelong_
+
+# -- Missing translation: _textCaptionslong_
+
+# -- Missing translation: _textCountrieslong_
+
+
+# -- Missing translation: _textdefaultlongtext_
+
+
+_textreadingdocs_ [l=te] {à°Šà°žà±à°€à°Ÿà°µà±à°à±à°²à°šà± à°à°²à°Ÿ à°à°Šà°Ÿà°µà°Ÿà°²à°¿ }
+_texthelpreadingdocs_ [l=te] {
+<p>à°žà°¹à°Ÿà°¯à±Š à°à±à°¯à± à°µà°¿à°·à°¯à°Ÿà°²à± à°®à±à°à± à°ªà±à°à± à°®à±à°Š
+à°¶à±à°°à±à°·à° à°à±à°¡à°¿à°µà±à°ªà±  à°°à°à°¯à±à°à°€ à°ªà±à°°à± à°à±Šà°à±à±Šà°Šà°¿ à°Šà±à°šà°¿ à°€à°°à±à°µà°Ÿà°€ à°®à±à°à± à°µà°°à±à°€à°®à°Ÿà°š à°ªà±à°à°¿ à°šà±à±Šà°¡à°¿ à°®à±à±Šà°Šà±à°à± à°µà±à°³à±à°²à°¡à°Ÿà°šà°¿à°à°¿ à°®à°°à°¿à°¯à± à°µà±à°šà°à°à± à°µà±à°³à±à°²à°¡à°Ÿà°šà°¿à°à°¿ à°à°Ÿà°µà°²à±à°žà°¿à°š à°à±à°°à±à°€à± à°à±Šà°à±à±Šà°Šà°¿</p>
+
+<p>à°à±à°°à°¿à±Šà°Š à°µà°°à±à°€à°®à°Ÿà°š à°µà°¿à°­à°Ÿà°à±Š à°¯à±à°à±à° à°®à±à°²à±Š à°Šà±à°°à±à°à±à°€à±à±Šà°Šà°¿ à°à°Šà°¿ à°à°Šà°¿à°µà°¿à°š à°€à°°à±à°µà°Ÿà°€ à°®à±à±Šà°Šà± à°ªà±à°à°¿ à°²à±à°Šà°Ÿ à°µà±à°šà° à°ªà±à°à°¿à°à°¿ à°µà±à°³à±à°²à°¡à°Ÿà°šà°¿à°à°¿ à°à°Ÿà°µà°²à±à°žà°¿à°š à°à±à°°à±à°€à± à°à±Šà°à±à±Šà°Šà°¿</p>
+
+<p>à°¶à±à°°à±à°·à°¿à° à°®à°°à°¿à°¯à± à°°à°à°à°€ à°ªà±à°°à± à°à±à°°à°¿à±Šà°Š à°®à±à°¡à± à°¬à°à°šà± à°²à± à°à±Šà°à°Ÿà°
+à°µà°°à±à°€à°®à°Ÿà°š  à°Šà°žà±à°€à°Ÿà°µà±à°à±à°²à°š à°ªà±à°°à±à°£à°®à±à°²à°šà±à°šà°¿à°µà°¿à°žà±à°€à°°à°¿à±Šà°à±  à°à±à°µà°Ÿà°²à±Šà°à±
+ <i>à°µà°¿à°žà±à°€à°°à°¿à±Šà°à± </i>, à°¬à°à°šà± à°à±à°²à°¿à°à± à°à±à°¯à±Šà°¡à°¿ 
+à°à±à°°à±à°€à±à°€ à°à°¿à°à°¿à°à°¿ à°€à±à°°à°µà°¡à°Ÿà°šà°¿à°à°¿  <i>à°ªà±à°°à°€à±à°¯à±à°à±Š </i>,
+ à°¬à°à°šà± à°à±à°²à°¿à°à± à°à±à°¯à±Šà°¡à°¿à¥€ (à°à°Šà°¿ à°°à±à±Šà°¡à± à°µà°°à±à°€à°®à°Ÿà°š  à°Šà°žà±à°€à°Ÿà°µà±à°à±à°²à°šà± à°à°à±à°žà°Ÿà°°à°¿ à°à°Šà°µà°¡à°Ÿà°šà°¿à°à°¿ à°à±à°°à±à°€à±à°€ à°à°¿à°à°¿à°à°¿ à°žà°¹à°Ÿà°¯à°ªà°¡à±à°€à±à±Šà°Šà°¿) à°ªà°°à°¿à°¶à±à°Šà°¿à±Šà°à°¿à°š à°à°¿à°µà°°à±à°²à±  à°ªà°°à°¿à°¶à±à°Šà°¿à±Šà°à°¿à°š à°¶à°¬à±à°Šà°Ÿà°²à± à°¹à±à°²à°à± à°
+à°à±à°šà±.   à°¹à±à°²à°à± à°à°Ÿà°µà°Šà±à°Šà± à°
+à°šà±à°à±à±Šà°à± <i>à°¹à±à°²à°à± à°à°Ÿà°µà°Šà±à°Šà±</i>, à°¬à°à°šà± à°à±à°²à°¿à°à± à°à±à°¯à±Šà°¡à°¿</p>
+}
+
+# help about the icons
+_texthelpexpandtext_ [l=te] {à°
+à°šà±à°šà°¿ à°ªà±à°à±à°²à°šà± à°ªà±à°°à°Šà°°à±à°¶à°¿à±Šà°à°¡à±Š à°²à±à°Šà°Ÿ à°µà°Šà±à°Šà±} 
+_texthelpdetachpage_ [l=te] {à° à°ªà±à°à±à°šà°¿ à°à±à°°à±à°€à±à°€ à°à°¿à°à°¿à°à°¿à°²à±à°à±à°ªà±Šà°¡à°¿ } 
+_texthelphighlight_ [l=te] {à°ªà°°à°¿à°¶à±à°Šà°¿à±Šà°à°¿à°š à°¶à°¬à±à°Šà°Ÿà°²à± à°¹à±à°²à°à± à°à±à°¯à±Šà°¡à°¿  à°²à±à°Šà°Ÿ à°µà°Šà±à°Šà±}
+_texthelpsearchingtitle_ [l=te] {à°šà°¿à°°à±à°§à°¿à°·à±à°à°®à±à°š à°ªà°Šà°Ÿà°²à°šà± à°à°²à°Ÿ à°¶à±à°Šà°¿à±Šà°à°Ÿà°²à°¿} 
+_texthelpsearching_ [l=te] {
+<p>
+  à°¶à±à°Šà°¿à±Šà°à°¿à°š à°ªà±à°à± à°šà±à±Šà°¡à°¿ à°®à± à°ªà±à°°à°¶à±à°šà°šà± à°žà°°à°³ à°°à±à°€à°¿à°²à± à°à±à°ªà±Šà°¡à°¿:<p>
+  
+  <ol>
+    <li>à°¶à±à°Šà°¿à±Šà°à°¡à°Ÿà°šà°¿à°à°¿ à°šà°¿à°¶à±à°à°à±Šà°à±à°à±à±Šà°¡à°¿ à°®à±à°°à± à°
+à°šà±à°šà°¿ à°²à±à°Šà°Ÿ à°à±à°šà±à°šà°¿ à°ªà°Šà°Ÿà°²à°šà± à°¶à±à°Šà°¿à±Šà°à°¡à°Ÿà°šà°¿à°à°¿ à°šà°¿à°¶à±à°à°à±Šà°à±à°à±à±Šà°¡à°¿ 
+    <li>à°®à±à°°à± à°
+à°šà±à°šà°¿ à°²à±à°Šà°Ÿ à°à±à°šà±à°šà°¿ à°ªà°Šà°Ÿà°²à°šà± à°¶à±à°Šà°¿à±Šà°à°¡à°Ÿà°šà°¿à°à°¿ à°šà°¿à°¶à±à°à°à±Šà°à±à°à±à±Šà°¡à°¿ 
+    <li>à°¶à±à°Šà°¿à±Šà°à°µà°²à°žà°¿à°š à°ªà°Šà°Ÿà°²à°šà±  à°à±à°ªà± à°à±à°¯à±Šà°¡à°¿ à¥€
+    <li><i>à°¶à± à°§à°š à°®à±à°Šà°²à± à°ªà±à°à±à°à±Šà°¡à°¿ </i> à°¬à°à°šà± à°®à±à°Š à°°à±à±Šà°¡à± à°žà°Ÿà°°à±à°²à± à°à±à°²à°¿à°à± à°à±à°¯à±Šà°¡à°¿   
+  </ol>
+
+<p> à°®à±à°à± à°ªà°°à°¿à°¶à±à°§à°š à°€à°°à±à°µà°Ÿà°€  à°à°°à±à°µà°Šà°¿ à°žà°°à°¿à°à±à°à°Ÿ à°à°²à±à°žà°¿à°š à°Šà°žà±à°€à°Ÿà°µà±à°à±à°² à°¶à±à°°à±à°·à°à°šà± à°à±à°¡à°µà°à±à°à± à°à°¿à°µà°°à±à°²à± à°à±Šà°à°Ÿ
+à°à°°à°µà°Šà°¿ à°Šà°žà±à°€à°Ÿà°µà±à°à±à°²à°à± à°µà±à°³à±à°²à°¡à°Ÿà°šà°¿à°à°¿ à°®à°°à°¿à°¯à± à°€à°°à±à°µà°Ÿà°€ à°Šà°žà±à°€à°Ÿà°µà±à°à±à°²à°à± à°µà±à°³à±à°²à°¡à°Ÿà°šà°¿à°à°¿ à°žà°¹à°Ÿà°¯à°ªà°¡à± à°¬à°à°šà± à°Šà±à°°à±à°à±à°€à±à±Šà°Šà°¿.à°à°à±à°à°¡à°¿à°šà±à±Šà°¡à°¿ à°®à±à°°à±  à°®à±à±Šà°Šà± à°à°°à±à°µà°Šà°¿ à°Šà°žà±à°€à°Ÿà°µà±à°à±à°²à°à± à°µà±à°³à±à°²à°¡à°Ÿà°šà°¿à°à°¿ à°€à°°à±à°µà°Ÿà°€à°¿ à°Šà°žà±à°€à°Ÿà°µà±à°à±à°²à°à± à°µà±à°³à±à°²à°¡à°Ÿà°šà°¿à°à°¿ à°¬à°à°šà± à°Šà±à°°à±à°à±à°€à±à±Šà°Šà°¿. à°®à±à°°à± à°¶à±à°°à±à°·à°¿à° à°¬à°à°šà± à°à°Ÿà°šà°¿ à°¶à±à°°à±à°·à°¿à°à°à± à°Šà°à±à°à°°à°à°Ÿ à°à°šà±à°šà°¬à°à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿ à°à°Šà°žà±à°€à°Ÿà°µà±à°à±à°²à± à°à±à°¡à°µà°à±à°à±.
+
+<p>à°®à±à°°à± à°
+à°µà°žà°°à°Ÿà°šà±à°šà°¿à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°®à°Ÿà°°à±à°à±à°à±à°µà°à±à°à±<p>
+}
+
+_texthelpquerytermstitle_ [l=te] {à°¶à±à°Šà°¿à±Šà°à°¿à°š à°ªà°Šà°Ÿà°²à±}
+_texthelpqueryterms_ [l=te] {
+<p> à°®à±à°°à± à°à°Ÿà°µà°²à±à°žà°¿à°š à°ªà°Šà°Ÿà°²à°šà± à°¬à±à°°à±à°à±à°à± à°®à°Ÿà°°à±à°à±Š à°Šà±à°µà°Ÿà°°à°à±à°ªà± à°à±à°žà±à°€à±à°Šà°Ÿ à°šà°¿à°²à± à°žà°à±Š à°¬à±à°°à±à°à±à°à± à°à±à°žà°¿à°š à°ªà°Šà°Ÿà°²à± à°à±Šà°à°Ÿà° à°ªà±à°°à°€à°¿ à°ªà°Šà±Š à°µà°°à±à°£à°®à°Ÿà°²à°€à± à°®à°°à°¿à°¯à± à°
+à±Šà°à±à°²à°€à± à°€à°¯à°Ÿà°°à°µà±à°€à±à±Šà°Šà°¿  à°°à±à±Šà°¡à± à°ªà°Šà°Ÿà°²à°šà± à°à°Ÿà°³à°¿ à°žà±à°¥à°²à±Šà°€à±  à°µà±à°°à± à°à±à°¯à°µà°à±à°à± à°µà°¿à°°à°Ÿà°® à°à°¿à°¹à±à°šà°Ÿà°šà±à°šà°¿ à°à°ªà°¯à±à°à°¿à±Šà°à°¿ à°à±à°¡ à°°à±à±Šà°¡à± à°ªà°Šà°Ÿà°²à°šà±à°µà±à°°à± à°à±à°¯à°µà°à±à°à±.  à°µà°¿à°°à°Ÿà°® à°à°¿à°¹à±à°šà°Ÿà°šà±à°šà°¿ à°µà°Šà°¿à°²à±à°¯à°µà°à±à°à± à°à±Šà°Šà±à°µà°²à°š à°®à±à°°à±  à°µà°¿à°°à°Ÿà°® à°à°¿à°¹à±à°šà°Ÿà°šà±à°šà°¿  à°à°ªà°¯à±à°à°¿à±Šà°à°¿ à°¶à±à°Šà°¿à±Šà°à°²à±à°°à±. à°à°Šà°¹à°°à°£ à°¬à±à°°à±à°à±
+<p>à°à°Šà°¹à°°à°£: à°à±à°°à°¿à±Šà°Š à°µà±à°°à°Ÿà°žà°¿à°š  à°¬à±à°°à±à°à±
+<p>
+    <ul><kbd>(2002)</kbd></ul>
+      <p>à€à€Ÿ à°
+à°°à±à°¥à°à°à°š<p>
+      <ul><kbd>à°
+à°¬à±à°Šà±à°²à± à°à°²à°Ÿà°®à± à°à°à°žà±Šà°€à± à°µà±à°à±à°à°Ÿà°šà°¿à°à± 
+
+
+2002 </kbd></ul><p>
+<p>à°
+à°à±à°šà± à¥€
+}
+
+_texthelpquerytypetitle_ [l=te] {à°¶à±à°Šà°š à°®à°Ÿà°°à±à°à°Ÿà°²à± }
+_texthelpquerytype_ [l=te] {
+<p>à°¶à±à°Šà°šà°à± à°°à±à±Šà°¡à± à°®à°Ÿà°°à±à°à°Ÿà°²à± à°à± 
+<ul>
+  <li>à°
+à°šà±à°šà°¿à°ªà°Šà°Ÿà°²à±à°à±à°žà±Š à°¬à±à°°à±à°à±
+à°à±à°¯à°¡à±Š à°à±Šà°Šà±à°²à± à°®à± à°Šà±à°µà°Ÿà°°à°Ÿà°µà°°à±à°£à°¿à°€à°®à±à°š à°ªà°Šà°Ÿà°² à°à±à°žà±Š à°Šà°žà±à°€à°Ÿà°µà±à°à±à°²à°²à±, à°ªà±à°°à°à°°à°£à°²à±, à°¶à±à°°à±à°·à°¿à°à°²à°²à± à°µà±à°Šà±à°à±à°€à±à±Šà°Šà°¿. à°à°à°¿à°€à°®à±à°š  à°Šà°žà±à°€à°Ÿà°µà±à°à±à°²à±, à°µà°°à±à°£à°®à°Ÿà°² à°ªà°à±à°à°¿à°à°šà± à°
+à°šà±à°žà°°à°¿à±Šà°à°¿ à°ªà±à°°à°Šà°°à±à°¶à°¿à°€à°®à°à±à°šà±à¥€
+
+<p>
+
+  <li>à¥€ à°à±à°šà±à°šà°¿ à°ªà°Šà°Ÿà°² à°à±à°žà±Š à°¬à±à°°à±à°à± à°à±à°¯à°¡à±Š à°®à±à°°à±à°à°à±à°à°¡ à°µà°¿à°¶à±à°·à°€ à°à°²à°¿à°à°¿à°š à°ªà°Šà°Ÿà°²à°šà± à°à°ªà°¯à±à°à°¿à±Šà°à°¿ à°¶à±à°§à°š à°à±à°¯à°µà°à±à°à± à°®à±à±Šà°Šà±à°à°Ÿ à°¶à±à°§à°š à°ªà°Šà°Ÿà°šà°¿à°à°¿ à°Šà°à±à°à°°à°à°Ÿ à°à°šà±à°šà°Šà°žà±à°€à°Ÿà°µà±à°à± à°ªà±à°°à°Šà°°à±à°¶à°š à°à±Šà°à±à±Šà°Šà°¿ à°®à±à±Šà°Šà±à°à°Ÿ à°¶à±à°§à°šà°ªà°Šà°Ÿà°šà°¿à°à°¿ à°Šà°à±à°à°°à°à°Ÿ à°à°šà±à°š à°Šà°žà±à°€à°Ÿà°µà±à°à±à°² à°ªà°Šà°°à±à°¶à°š à°à±Šà°à±à±Šà°Šà°¿ à°à°ªà°¯à±à°à±à°€à°¿ à°šà°¿à°°à±à°£à°¯à±Š à°à±à°°à°¿à±Šà°Š à°µà±à°°à°Ÿà°žà°¿à°š à°ªà°Šà°Ÿà°²à°²à±  à°µà°¿à°µà°°à±Šà°à°Ÿ à°à±Šà°Šà°¿ 
+  <p>        
+</ul>
+}
+
+# -- Missing translation: _textdatesearch_
+
+# -- Missing translation: _texthelpdatesearch_
+
+# -- Missing translation: _textchangeprefs_
+
+# -- Missing translation: _texthelppreferences_
+
+_texttanumbrowseoptions_ [l=te] {à°žà±Šà°à±à°°à°¹à°šà°² à°šà±à±Šà°¡à°¿ à°žà°®à°Ÿà°à°Ÿà°°à°šà±à°šà°¿ à°à°²à°Ÿ à°€à±à°²à±à°žà±à°à±à°µà°Ÿà°²à±Šà°à± à°€à±à°Šà±à°²à°šà± à°­à±à°°à±à°à± à°à±à°¯à±Šà°¡à°¿
+ _numbrowseoptions_ 
+
+_textsimplehelpheading_ [l=te] {_collectionname_à°žà±Šà°à±à°°à°¹à°šà°² à°šà±à±Šà°¡à°¿ à°žà°®à°Ÿà°à°Ÿà°°à°šà±à°šà°¿ à°à°²à°Ÿ à°€à±à°²à±à°žà±à°à±à°µà°à±à°à±}
+
+# -- Missing translation: _texthelpscope_
+
+
Index: /gsdl/stable/macros/thai.dm
===================================================================
--- /gsdl/stable/macros/thai.dm	(revision 20131)
+++ /gsdl/stable/macros/thai.dm	(revision 20131)
@@ -0,0 +1,778 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Thai Language text and icon macros 
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=th] {àžàž²àž¡àžàž³àž«àžàžà¹àž§àž¥àž²	}  
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=th] {à¹àž«àž¥à¹àžàž­à¹àž²àžàž­àžŽàž:	}  
+_textdate_ [l=th] {àž§àž±àžàžàžµà¹à¹àžàž¢à¹àžàž£à¹:	}  
+_textnumpages_ [l=th] {àžàž³àžàž§àžàž«àžà¹àž²:	}  
+
+_textsignin_ [l=th] {àžªàž¡àž±àžàž£àžªàž¡àž²àžàžŽàž	}  
+
+_textdefaultcontent_ [l=th] {"à¹àž¡à¹àžàžàž«àžà¹àž²àžàžµà¹àž£à¹àž­àžàžàž­  àžàž£àžžàžàž²àžàž¥àžŽàžàžàžžà¹àž¡ 'àž¢à¹àž­àžàžàž¥àž±àž' à¹àžà¹àžàž£àž²àž§à¹àžàž­àž£à¹àžàž­àžàžàžžàž
+àž«àž£àž·àž­àžàžžà¹àž¡ 'àž«àžà¹àž²à¹àž£àž' àžà¹àž²àžàžàž à¹àžàž·à¹àž­àžàž¥àž±àžà¹àžàž¢àž±àžàž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥àžàž­àž Greenstone"	}  
+
+_textdefaulttitle_ [l=th] {àžà¹àž­àžàžŽàžàžàž¥àž²àžàžàž­àž GSDL	}  
+
+_textbadcollection_ [l=th] {"à¹àž¡à¹àž¡àžµàžàž²àž£àžàžŽàžàžàž±à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹ (àžàžµà¹à¹àž£àžµàž¢àžàž§à¹àž² "_cvariable_") à¹àžàž£àž°àžàžàž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥àžàž­àž Greenstone"	}  
+
+_textselectpage_ [l=th] {-- à¹àž¥àž·àž­àž àž«àžà¹àž² --	}  
+
+_collectionextra_ [l=th] {"àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžàž£àž°àžàž­àžàžà¹àž§àž¢à¹àž­àžàžªàž²àž£àžàž³àžàž§àž _about:numdocs_ àžàžàž±àž
+àžàž¶à¹àžàžàž¹àžàžªàž£à¹àž²àžàžàž£àž±à¹àžàž¥à¹àž²àžªàžžàžà¹àž¡àž·à¹àž­ _about:builddate_ àž§àž±àžàžà¹àž­àž"	}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=th] {"<p>àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžàž£àž°àžàž­àžàžà¹àž§àž¢ _numdocs_ _If_("_numdocs_" eq "1",document,documents), àžà¹àž­àžàž§àž²àž¡à¹àž¥àž°à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹à¹àžà¹àž£àž±àžàžàž²àž£àžàž³àžàž±àžàžàžµàžàž±à¹àžàž«àž¡àž _numbytes_ àž£àž²àž¢àžàž²àž£
+<p><a href="_httppagex_(bsummary)">àžàž¥àžŽàžàžàžµà¹àžàžµà¹</a> à¹àžàž·à¹àž­àžàž¹àžàž¥àžªàž£àžžàžà¹àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹
+"	}  
+
+_textdescrcollection_ [l=th] {}
+_textdescrabout_ [l=th] {à¹àžàžµà¹àž¢àž§àžàž±àžà¹àžàž	}  
+_textdescrhome_ [l=th] {àž«àžà¹àž²à¹àž£àž	}  
+_textdescrhelp_ [l=th] {àž«àžà¹àž²àž§àžŽàžàžµà¹àžà¹	}  
+_textdescrpref_ [l=th] {àž«àžà¹àž²àžàž³àž«àžàžàž¥àž±àžàž©àžàž°	}  
+_textdescrgreenstone_ [l=th] {àžàž­àžàžà¹à¹àž§àž£à¹àž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥ Greenstone	}  
+_textdescrusab_ [l=th] {àžàžžàžàžàžŽàžàž§à¹àž²àž­àž°à¹àž£àžàžµà¹àž¢àž²àžàžà¹àž­àžàž²àž£à¹àžà¹àžàž²àž	}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=th] {àžà¹àžàž«àž²	}  
+_labelSearch_ [l=th] {àžà¹àžàž«àž²	}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=th] {àžàž·à¹àž­	}  
+_labelTitle_ [l=th] {àžàž·à¹àž­à¹àž£àž·à¹àž­àž	}  
+_textCreator_ [l=th] {à¹àžà¹àž²àžàž­àžàžàž²àž	}  
+_labelCreator_ [l=th] {àžàž¹à¹àžªàž£à¹àž²àžà¹àž­àžàžªàž²àž£	}  
+_textSubject_ [l=th] {àž«àž±àž§à¹àž£àž·à¹àž­àž	}  
+_labelSubject_ [l=th] {àž«àž±àž§à¹àž£àž·à¹àž­àž	}  
+_textDescription_ [l=th] {àžàž³àž­àžàžŽàžàž²àž¢	}  
+_labelDescription_ [l=th] {àžàž³àž­àžàžŽàžàž²àž¢	}  
+_textPublisher_ [l=th] {àžàž¹à¹à¹àžàž¢à¹àžàž£à¹	}  
+_labelPublisher_ [l=th] {àžàž¹à¹à¹àžàž¢à¹àžàž£à¹	}  
+_textContributor_ [l=th] {àžàž¹à¹à¹àžà¹àžàž£à¹àž§àž¡	}  
+_labelContributor_ [l=th] {àžàž¹à¹àž£à¹àž§àž¡àžàž²àž	}  
+_textDate_ [l=th] {àž§àž±àžàžàžµà¹	}  
+_labelDate_ [l=th] {àž§àž±àžàžàžµà¹	}  
+_textType_ [l=th] {àžàžàžŽàž	}  
+_labelType_ [l=th] {àžàžàžŽàž	}  
+_textFormat_ [l=th] {àž£àž¹àžà¹àžàž	}  
+_labelFormat_ [l=th] {àž£àž¹àžà¹àžàž	}  
+_textIdentifier_ [l=th] {àžàž±àž§àž£àž°àžàžž	}  
+_labelIdentifier_ [l=th] {àžàž±àž§àž£àž°àžàžž	}  
+_textSource_ [l=th] {àžàž·à¹àž­à¹àžà¹àž¡	}  
+_labelSource_ [l=th] {àžàž·à¹àž­à¹àžà¹àž¡	}  
+_textLanguage_ [l=th] {àž àž²àž©àž²	}  
+_labelLanguage_ [l=th] {àž àž²àž©àž²	}  
+_textRelation_ [l=th] {àžàž§àž²àž¡àžªàž±àž¡àžàž±àžàžà¹	}  
+_labelRelation_ [l=th] {àžàž§àž²àž¡àžªàž±àž¡àžàž±àžàžà¹	}  
+_textCoverage_ [l=th] {àžàž§àž²àž¡àžàž£àž­àžàžàž¥àžžàž¡	}  
+_labelCoverage_ [l=th] {àžàž§àž²àž¡àžàž£àž­àžàžàž¥àžžàž¡	}  
+_textRights_ [l=th] {àžªàžŽàžàžàžŽ	}  
+_labelRights_ [l=th] {àžªàžŽàžàžàžŽ	}  
+
+# DLS metadata set
+_textOrganization_ [l=th] {àž­àžàžà¹àžàž£	}  
+_labelOrganization_ [l=th] {àž­àžàžà¹àžàž£	}  
+_textKeyword_ [l=th] {àžàž³àžªàž³àžàž±àž	}  
+_labelKeyword_ [l=th] {àžàž³àžªàž³àžàž±àž	}  
+_textHowto_ [l=th] {àž§àžŽàžàžµàžàž³à¹àžàžŽàžàžàž²àž£	}  
+_labelHowto_ [l=th] {àž§àžŽàžàžµàžàž³à¹àžàžŽàžàžàž²àž£	}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=th] {àž§àž¥àžµ	}  
+_labelPhrase_ [l=th] {àž§àž¥àžµ	}  
+_textCollage_ [l=th] {àžàž²àž£àžàž°àžàžŽàžàžàž°àžà¹àž­	}  
+_labelCollage_ [l=th] {àžàž²àž£àžàž°àžàžŽàžàžàž°àžà¹àž­àžàž³	}  
+_textBrowse_ [l=th] {à¹àž£àžµàž¢àžàžàž¹	}  
+_labelBrowse_ [l=th] {à¹àž£àžµàž¢àžàžàž¹	}  
+_textTo_ [l=th] {àžàž¶àž	}  
+_labelTo_ [l=th] {àžàž¶àž	}  
+_textFrom_ [l=th] {àžàž²àž	}  
+_labelFrom_ [l=th] {àžàž²àž	}  
+_textAcronym_ [l=th] {àžàž·à¹àž­àž¢à¹àž­	}  
+_labelAcronym_ [l=th] {àžàž·à¹àž­àž¢à¹àž­	}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=th] {à¹àž£àžµàž¢àžàžàž¹àžàž²àž¡ _1_	}  
+
+_textdescrSearch_ [l=th] {àžà¹àžàž«àž²àžàž³à¹àžàžàž²àž°	}  
+_textdescrType_ [l=th] {à¹àž£àžµàž¢àžàžàž¹àžàž²àž¡àžàžàžŽàžàžàž­àžàžàž£àž±àžàž¢àž²àžàž£	}  
+_textdescrIdentifier_ [l=th] {à¹àž£àžµàž¢àžàžàž¹àžàž²àž¡àžàž±àž§àž£àž°àžàžžàžàž£àž±àžàž¢àž²àžàž£	}  
+_textdescrSource_ [l=th] {à¹àž£àžµàž¢àžàžàž¹àžàž²àž¡àžàž·à¹àž­à¹àžà¹àž¡àžà¹àžàžàžàž±àž	}  
+_textdescrTo_ [l=th] {à¹àž£àžµàž¢àžàžàž¹àžàž²àž¡à¹àžàžàžà¹àž­àž¡àž¹àž¥ To	}  
+_textdescrFrom_ [l=th] {à¹àž£àžµàž¢àžàžàž¹àžà¹àž§àž¢à¹àžàžàžà¹àž­àž¡àž¹àž¥ àžàž²àž	}  
+_textdescrCollage_ [l=th] {à¹àž£àžµàž¢àžàžàž¹àžàž²àž¡àžàž²àž£àžàž°àžàžŽàžàžàž°àžà¹àž­àž àž²àž	}  
+_textdescrAcronym_ [l=th] {à¹àž£àžµàž¢àžàžàž¹àžàž·à¹àž­àž¢à¹àž­	}  
+_textdescrPhrase_ [l=th] {à¹àž£àžµàž¢àžàžàž¹àž§àž¥àžµ	}  
+_textdescrHowto_ [l=th] {à¹àž£àžµàž¢àžàžàž¹àž§àžŽàžàžµàžàž²àž£àžàž±àžàž«àž¡àž§àžàž«àž¡àž¹à¹	}  
+_textdescrBrowse_ [l=th] {à¹àž£àžµàž¢àžàžàž¹à¹àž­àžàžªàž²àž£	}  
+_texticontext_ [l=th] {àžàž¹à¹àž­àžàžªàž²àž£	}  
+_texticonclosedbook_ [l=th] {à¹àžàžŽàžà¹àž­àžàžªàž²àž£àžàžµà¹à¹àž¥àž°àžàž¹à¹àžàž·à¹àž­àž«àž²	}  
+_texticonnext_ [l=th] {à¹àžàž¢àž±àžàžªà¹àž§àžàžàž±àžà¹àž	}  
+_texticonprev_ [l=th] {à¹àžàž¢àž±àžàžªà¹àž§àžàžà¹àž­àžàž«àžà¹àž²	}  
+
+_texticonworld_ [l=th] {àžàž¹à¹àž­àžàžªàž²àž£à¹àž§à¹àž	}  
+
+_texticonmidi_ [l=th] {àžàž¹à¹àž­àžàžªàž²àž£ MIDI	}  
+_texticonmsword_ [l=th] {àžàž¹à¹àž­àžàžªàž²àž£ Microsoft Word	}  
+_texticonmp3_ [l=th] {àžàž¹à¹àž­àžàžªàž²àž£ MP3	}  
+_texticonpdf_ [l=th] {àžàž¹à¹àž­àžàžªàž²àž£ PDF	}  
+_texticonps_ [l=th] {àžàž¹à¹àž­àžàžªàž²àž£ PostScript	}  
+_texticonppt_ [l=th] {àžàž¹à¹àž­àžàžªàž²àž£ PowerPoint	}  
+_texticonrtf_ [l=th] {àžàž¹à¹àž­àžàžªàž²àž£ RTF	}  
+_texticonxls_ [l=th] {àžàž¹à¹àž­àžàžªàž²àž£ Microsoft Excel	}  
+
+_page_ [l=th] {àž«àžà¹àž²	}  
+_pages_ [l=th] {àž«àžà¹àž²	}  
+_of_ [l=th] {àžàž­àž	}  
+_vol_ [l=th] {àžàžàž±àžàžàžµà¹ }  
+_num_ [l=th] {à¹àž¥àžàžàžµà¹	}  
+
+_textmonth00_ [l=th] {}  
+_textmonth01_ [l=th] {à¹àžàž·àž­àžàž¡àžàž£àž²àžàž¡	}  
+_textmonth02_ [l=th] {à¹àžàž·àž­àžàžàžžàž¡àž àž²àžàž±àžàžà¹	}  
+_textmonth03_ [l=th] {à¹àžàž·àž­àžàž¡àžµàžàž²àžàž¡	}  
+_textmonth04_ [l=th] {à¹àžàž·àž­àžà¹àž¡àž©àž²àž¢àž	}  
+_textmonth05_ [l=th] {à¹àžàž·àž­àžàžàž€àž©àž àž²àžàž¡	}  
+_textmonth06_ [l=th] {à¹àžàž·àž­àžàž¡àžŽàžàžžàžàž²àž¢àž	}  
+_textmonth07_ [l=th] {à¹àžàž·àž­àžàžàž£àžàžàž²àžàž¡	}  
+_textmonth08_ [l=th] {à¹àžàž·àž­àžàžªàžŽàžàž«àž²àžàž¡	}  
+_textmonth09_ [l=th] {à¹àžàž·àž­àžàžàž±àžàž¢àž²àž¢àž	}  
+_textmonth10_ [l=th] {à¹àžàž·àž­àžàžàžžàž¥àž²àžàž¡	}  
+_textmonth11_ [l=th] {à¹àžàž·àž­àžàžàž€àžšàžàžŽàžàž²àž¢àž	}  
+_textmonth12_ [l=th] {à¹àžàž·àž­àžàžàž±àžàž§àž²àžàž¡	}  
+
+_textdocument_ [l=th] {à¹àž­àžàžªàž²àž£	}  
+_textsection_ [l=th] {àžªà¹àž§àž	}  
+_textparagraph_ [l=th] {àž¢à¹àž­àž«àžà¹àž²	}  
+_textchapter_ [l=th] {àžàž}
+_textbook_ [l=th] {àž«àžàž±àžàžªàž·àž­}
+
+_magazines_ [l=th] {àžàžŽàžàž¢àžªàž²àž£	}  
+
+_nzdlpagefooter_ [l=th] {"<div class="divbar">Â </div>
+<p><a href="http://www.nzdl.org">à¹àžàž£àžàžàž²àž£àž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥àžàž£àž°à¹àžàžšàžàžŽàž§àžàžµà¹àž¥àžàžà¹</a>
+<br><a href="http://www.cs.waikato.ac.nz">àž àž²àžàž§àžŽàžàž²àž§àžŽàžàž¢àž²àžšàž²àžªàžàž£à¹àžàž­àž¡àžàžŽàž§à¹àžàž­àž£à¹</a> 
+<a href="http://www.waikato.ac.nz">àž¡àž«àž²àž§àžŽàžàž¢àž²àž¥àž±àž¢à¹àž§àžàž²à¹àž</a> 
+àžàž£àž°à¹àžàžšàžàžŽàž§àžàžµà¹àž¥àžàžà¹"	}  
+
+_linktextHOME_ [l=th] {àž«àžà¹àž²à¹àž£àž	}  
+_linktextHELP_ [l=th] {àž§àžŽàžàžµà¹àžà¹	}  
+_linktextPREFERENCES_ [l=th] {àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°	}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=th] {àž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥àžàž­àž+B349 Greenstone	}  
+
+_textnocollections_ [l=th] {à¹àž¡à¹àž¡àžµàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžàž¹àžàžà¹àž­àž (à¹àžà¹àž àžàžµà¹àžªàž£à¹àž²àžà¹àž§à¹à¹àž¥àž°à¹àžàžŽàžà¹àž«à¹à¹àžà¹àž²àžàž¶àžà¹àžà¹) àžàžµà¹àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžà¹àžà¹	}  
+
+_textadmin_ [l=th] {àž«àžà¹àž²àžàž²àž£àžàž¹à¹àž¥àž£àž°àžàž	}  
+_textabgs_ [l=th] {à¹àžàžµà¹àž¢àž§àžàž±àžà¹àžàž£à¹àžàž£àž¡ Greenstone	}  
+_textgsdocs_ [l=th] {à¹àž­àžàžªàž²àž£àžàž£àž°àžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone	}  
+
+_textdescradmin_ [l=th] {"àž­àžàžžàžàž²àžà¹àž«à¹àžàžžàžà¹àžàžŽà¹àž¡àžàž¹à¹à¹àžà¹à¹àž«àž¡à¹ àžªàž£àžžàžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžàž£àž°àžàž
+àžàž³à¹àžªàžàž­àžà¹àž­àž¡àž¹àž¥àžàž²àžà¹àžàžàžàžŽàžà¹àžàžµà¹àž¢àž§àžàž±àžàžàž²àž£àžàžŽàžàžàž±à¹àžà¹àžàž£à¹àžàž£àž¡ Greenstone"	}  
+
+_textdescrgogreenstone_ [l=th] {àžàž­àžàžàžžàžà¹àžàžµà¹àž¢àž§àžàž±àžàžàž­àžàžà¹à¹àž§àž£à¹ Greenstone à¹àž¥àž°à¹àžàž£àžàžàž²àž£àž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥àžàž£àž°à¹àžàžšàžàžŽàž§àžàžµà¹àž¥àžàžà¹àžàž¶à¹àžà¹àžà¹àžàžªàžàž²àžàžàžµà¹àžàž¶à¹àžà¹àžàž£àžàžàž²àž£àžàž·àž­àžàž³à¹àžàžŽàžàžàž¶à¹àž	}  
+
+_textdescrgodocs_ [l=th] {àžàž¹à¹àž¡àž·àž­à¹àžàž£à¹àžàž£àž¡ Greenstone	}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=th] {àž«àžà¹àž²àžàž­àžàž¹à¹à¹àžà¹àž£àž°àžàžàžªàž³àž«àž£àž±àžàžàž£àž£àžàž²àž£àž±àžàž©à¹	}  
+_textdescrgli_ [l=th] {àžà¹àž§àž¢à¹àž«à¹àžàžžàžàžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹ àžàž£àž±àžà¹àžàž¥àžµà¹àž¢àžàž«àž£àž·àž­à¹àžàžŽà¹àž¡àžà¹àž­àž¡àž¹àž¥àž¥àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž¡àžµàž­àž¢àž¹à¹ àž«àž£àž·àž­àž¥àžàžàž­àž¥à¹àž¥àžàžàž±àž	}  
+
+package collector
+
+_textcollector_ [l=th] {àžàž±àž§àž£àž§àžàž£àž§àž¡	}  
+_textdescrcollector_ [l=th] {àžàž±àž§àžàž±àžàžàž²àž£àžàžµà¹àžàž¹àžàžàž±àžàžàž²àžàž¶à¹àžàž¡àž²àžà¹àž­àžàž«àžà¹àž²àžàž­àžàž¹à¹à¹àžà¹àž£àž°àžàžàžªàž³àž«àž£àž±àžàžàž£àž£àžàž²àž£àž±àžàž©à¹ à¹àžàžàž²àžàžàžàžŽàžàž±àžàžŽàžàžžàžàžàž§àž£àžàž°à¹àžà¹àž«àžà¹àž²àžàž­àžàž¹à¹à¹àžà¹àž£àž°àžàžàžªàž³àž«àž£àž±àžàžàž£àž£àžàž²àž£àž±àžàž©à¹à¹àžàž }  
+
+package depositor
+
+_textdepositor_ [l=th] {àžàž±àž§àžàž±àžà¹àžà¹àžàžàž³	}  
+_textdescrdepositor_ [l=th] {àžà¹àž§àž¢à¹àž«à¹àžàžžàžà¹àžàžŽà¹àž¡à¹àž­àžàžªàž²àž£à¹àžà¹àž²à¹àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž¡àžµàž­àž¢àž¹à¹à¹àž¥à¹àž§à¹àžà¹	}  
+
+package gti
+
+_textgti_ [l=th] {àžªà¹àž§àžàžàžŽàžàžà¹àž­àžàž±àžàžàž¹à¹à¹àžà¹àžªàž³àž«àž£àž±àžàžàž¹à¹à¹àžàž¥àžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone	}  
+_textdescrtranslator_ [l=th] {àžà¹àž§àž¢à¹àž«à¹àžàžžàžàžªàž²àž¡àž²àž£àžàžàž£àž±àžàžàž£àžžàžàžªà¹àž§àžàžàžŽàžàžà¹àž­àžàž¹à¹à¹àžà¹àžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone à¹àžàž«àž¥àž²àž¢àž àž²àž©àž²à¹àžà¹àž­àž¢à¹àž²àžàžàž±àžàžªàž¡àž±àž¢	}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=th] {à¹àžàžµà¹àž¢àž§àžàž±àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹	}  
+
+_textsubcols1_ [l=th] {"<p>àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžªàž¡àžàž¹àž£àžà¹àžàž£àž°àžàž­àžàžà¹àž§àž¢àžàž­àž¥à¹àž¥àžàžàž±àžàž¢à¹àž­àž¢ _1_ àžàž­àž¥à¹àž¥àžàžàž±àž
+àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžà¹àžà¹à¹àžàžàžàž°àžàžµà¹ à¹àžà¹à¹àžà¹:
+<blockquote>"	}  
+
+_textsubcols2_ [l=th] {"</blockquote>
+àžàžžàžàžªàž²àž¡àž²àž£àžàžàž£àž§àžàžªàž­àž (à¹àž¥àž°àžàž£àž±àžà¹àžàž¥àžµà¹àž¢àž) àžàž­àž¥à¹àž¥àžàžàž±àžàž¢à¹àž­àž¢àžàžµà¹àžàžžàžàžàž³àž¥àž±àžà¹àžà¹àžàž²àžàž­àž¢àž¹à¹àž«àžà¹àž²àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°"	}  
+
+_titleabout_ [l=th] {à¹àžàžµà¹àž¢àž§àžàž±àž	}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=th] {àžàžŽàžà¹àž¥àžàž£àž²àž£àžµà¹àžªà¹àž§àžàžàžµà¹	}  
+_texticonclosedbookshelf_ [l=th] {à¹àžàžŽàžàžªà¹àž§àžàžàžµà¹àžàž­àžà¹àž¥àžàž£àž²àž£àžµà¹àž¥àž°àžàž¹à¹àžàž·à¹àž­àž«àž²	}  
+_texticonopenbook_ [l=th] {àžàžŽàžàž«àžàž±àžàžªàž·àž­à¹àž¥à¹àž¡àžàžµà¹	}  
+_texticonclosedfolder_ [l=th] {à¹àžàžŽàžà¹àžàž¥à¹àžàž­àž£à¹àžàžµà¹à¹àž¥àž°àžàž¹à¹àžàž·à¹àž­àž«àž²	}  
+_texticonclosedfolder2_ [l=th] {à¹àžàžŽàžàž«àž¡àž§àžàž¢à¹àž­àž¢:	}  
+_texticonopenfolder_ [l=th] {àžàžŽàžà¹àžàž¥à¹àžàž­àž£à¹àžàžµà¹	}  
+_texticonopenfolder2_ [l=th] {àžàžŽàžàž«àž¡àž§àžàž¢à¹àž­àž¢:	}  
+_texticonsmalltext_ [l=th] {àžàž¹àžà¹àž­àžàž§àž²àž¡àžªà¹àž§àžàžàžµà¹	}  
+_texticonsmalltext2_ [l=th] {àžàž¹àžà¹àž­àžàž§àž²àž¡:	}  
+_texticonpointer_ [l=th] {àžªà¹àž§àžàžàž±àžàžàžžàžàž±àž	}  
+_texticondetach_ [l=th] {à¹àžàžŽàžàž«àžà¹àž²àžàžµà¹à¹àžàž«àžà¹àž²àžà¹àž²àžà¹àž«àž¡à¹	}  
+_texticonhighlight_ [l=th] {à¹àžà¹àžàžàž³àžà¹àž	}  
+_texticonnohighlight_ [l=th] {à¹àž¡à¹àžà¹àž­àžà¹àžà¹àžàžàž³àžà¹àžàž«àž²	}  
+_texticoncontracttoc_ [l=th] {àž¢àžžàžàž£àž§àž¡àžªàž²àž£àžàž±àž	}  
+_texticonexpandtoc_ [l=th] {àžàž¢àž²àž¢àžªàž²àž£àžàž±àž	}  
+_texticonexpandtext_ [l=th] {à¹àžªàžàžàžà¹àž­àžàž§àž²àž¡àžàž±à¹àžàž«àž¡àž	}  
+_texticoncontracttext_ [l=th] {à¹àžªàžàžàžà¹àž­àžàž§àž²àž¡à¹àžàžàž²àž°àžªà¹àž§àžàžàžµà¹à¹àž¥àž·àž­àžà¹àž§à¹à¹àžàžàžàž°àžàžµà¹à¹àžà¹àž²àžàž±à¹àž	}  
+_texticonwarning_ [l=th] {<b>àžàž³à¹àžàž·àž­àž: </b>	}  
+_texticoncont_ [l=th] {àžàž³à¹àžàžŽàžàžàž²àž£àžà¹àž­àž«àž£àž·àž­à¹àž¡à¹	}  
+
+_textltwarning_ [l=th] {"<div class="buttons">_imagecont_</div>
+_iconwarning_Expanding àžà¹àž­àžàž§àž²àž¡à¹àžàžªà¹àž§àžàžàžµà¹àžàž°àžªàž£à¹àž²àž
+àžà¹àž­àž¡àž¹àž¥àžàž³àžàž§àžàž¡àž²àžà¹àžàž·à¹àž­à¹àžªàžàžàžàž¥à¹àžà¹àžàž£àž²àž§à¹àžàž­àž£à¹àžàž­àžàžàžžàž
+"	}  
+
+_textgoto_ [l=th] {à¹àžàž¢àž±àžàž«àžà¹àž²	}  
+_textintro_ [l=th] {<i>(àž­àž²àž£àž±àž¡àž àžàž)</i>	}  
+
+_textCONTINUE_ [l=th] {àžà¹àž­àžàžàž²àž£àžàž³à¹àžàžŽàžàžàž²àž£àžà¹àž­àž«àž£àž·àž­à¹àž¡à¹	}  
+
+_textEXPANDTEXT_ [l=th] {àžàž¢àž²àž¢àžà¹àž­àžàž§àž²àž¡	}  
+
+_textCONTRACTCONTENTS_ [l=th] {àžªàž²àž£àžàž±àžàžàž­àžàžªàž±àžàžàž²	}  
+
+_textDETACH_ [l=th] {à¹àž­àž²àž­àž­àž	}  
+
+_textEXPANDCONTENTS_ [l=th] {àžªàž²àž£àžàž±àžàžªà¹àž§àžàžàž¢àž²àž¢	}  
+
+_textCONTRACT_ [l=th] {àžà¹àž­àžàž§àž²àž¡à¹àžàžµà¹àž¢àž§àžàž±àžàžªàž±àžàžàž²	}  
+
+_textHIGHLIGHT_ [l=th] {àžàž²àž£à¹àžà¹àžàžàž³	}  
+
+_textNOHIGHLIGHT_ [l=th] {à¹àž¡à¹àž¡àžµàžàž²àž£à¹àžà¹àžàžàž³	}  
+
+_textPRINT_ [l=th] {àžàžŽàž¡àžà¹	}  
+
+_textnextsearchresult_ [l=th] {àžàž¥àžàž²àž£àžà¹àžàž«àž²àžàž±àžà¹àž	}  
+_textprevsearchresult_ [l=th] {àžàž¥àžàž²àž£àžà¹àžàž«àž²àžà¹àž­àžàž«àžà¹àž²	}  
+
+# macros for printing page
+_textreturnoriginal_ [l=th] {àžàž¥àž±àžà¹àžàž¢àž±àžàž«àžà¹àž²à¹àžàžŽàž¡	}  
+_textprintpage_ [l=th] {àžàžŽàž¡àžà¹àž«àžà¹àž²àžàžµà¹	}  
+_textshowcontents_ [l=th] {à¹àžªàžàžàžªàž²àž£àžàž±àž	}  
+_texthidecontents_ [l=th] {àžà¹àž­àžàžªàž²àž£àžàž±àž	}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=th] {"_If_(_thislast_,results _thisfirst_ - _thislast_ àžªàž³àž«àž£àž±àžàžàž³àžà¹àž: _cgiargq_,à¹àž¡à¹àžàž£àžàžàž±àžàžàž³àžà¹àž: _cgiargq_)"	}  
+_textnoquerytitle_ [l=th] {àž«àžà¹àž²àžà¹àžàž«àž²	}  
+
+_textsome_ [l=th] {àžàž²àžàžªà¹àž§àž	}  
+_textall_ [l=th] {àžàž±à¹àžàž«àž¡àž	}  
+_textboolean_ [l=th] {àžàž£àž£àžàž°	}  
+_textranked_ [l=th] {àžàž±àžàž­àž±àžàžàž±àž	
+
+}  
+_textnatural_ [l=th] {àžàž£àž£àž¡àžàž²àžàžŽ	}  
+_textsortbyrank_ [l=th] {àžàž²àž£àžàž±àžàž¥àž³àžàž±àžàžàž²àž¡àžàž§àž²àž¡àžªàž±àž¡àžàž±àžàžà¹	}  
+_texticonsearchhistorybar_ [l=th] {àžàž£àž°àž§àž±àžàžŽàžàž²àž£àžà¹àžàž«àž²	}  
+
+_textifeellucky_ [l=th] {àžàž±àžàž£àž¹à¹àžªàž¶àžà¹àžàžàžàžµàžàž±àž!	}  
+
+#alt text for query buttons
+_textusequery_ [l=th] {à¹àžà¹àžàž²àž£àžà¹àžàž«àž²àžàžµà¹	}  
+_textfreqmsg1_ [l=th] {àžàž³àžàž§àžàžàž³:	}  
+_textpostprocess_ [l=th] {"_If_(_quotedquery_,<br><i>àž«àž¥àž±àžàžàž³à¹àžàžŽàžàžàž²àž£à¹àžàž·à¹àž­àžà¹àžàž«àž² _quotedquery_</i>
+)"	}  
+_textinvalidquery_ [l=th] {àž£àž¹àžà¹àžàžàžàž²àž£àžà¹àžàž«àž²à¹àž¡à¹àžàž¹àžàžà¹àž­àž	}  
+_textstopwordsmsg_ [l=th] {àžàž³àžà¹àž­à¹àžàžàžµà¹à¹àžà¹àžàžàž³àžàžµà¹à¹àžà¹àžàž±àžàžàž±à¹àž§à¹àžà¹àž¥àž°àžàž§àž£àž¥àž°à¹àž§à¹àž:	}  
+_textlucenetoomanyclauses_ [l=th] {àžàž²àž£àžà¹àžàž«àž²àžàž­àžàžàžžàžàž¡àžµàžàž³àžàž§àžàžàž³àžà¹àžàžàžµà¹àž¡àž²àžà¹àžàžŽàžà¹àž àžàž£àžžàžàž²àž£àž°àžàžžàžàž³àžà¹àžàžàžµà¹à¹àžàžàž²àž°à¹àžàž²àž°àžàžàž¡àž²àžàžàž¶à¹àž	}  
+
+_textmorethan_ [l=th] {àž¡àž²àžàžàž§à¹àž²	}  
+_textapprox_ [l=th] {à¹àžàžµà¹àž¢àž§àžàž±àž	}  
+_textnodocs_ [l=th] {à¹àž¡à¹àž¡àžµà¹àž­àžàžªàž²àž£à¹àžàžàž£àžàžàž±àžàžàž²àž£àžà¹àžàž«àž²	}  
+_text1doc_ [l=th] {àž¡àžµà¹àž­àžàžªàž²àž£ 1 àžàžàž±àžàžàžµà¹àžàž£àžàžàž±àžàžàž³àžà¹àž	}  
+_textlotsdocs_ [l=th] {à¹àž­àžàžªàž²àž£àžàžµà¹àžàž£àžàžàž±àžàžàž²àž£àžà¹àžàž«àž²	}  
+_textmatches_ [l=th] {àžàž£àžàžàž±àž	}  
+_textbeginsearch_ [l=th] {à¹àž£àžŽà¹àž¡àžà¹àžàžàž²àž£àžà¹àžàž«àž²	}  
+_textrunquery_ [l=th] {à¹àž£àžµàž¢àžà¹àžà¹àžàž²àž£àžà¹àžàž«àž²	}  
+_textclearform_ [l=th] {àž¥à¹àž²àžàžàž­àž£à¹àž¡	}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=th] {àžàž³	}  
+_textinfield_ [l=th] {...à¹àžà¹àžàžàžà¹àž­àž¡àž¹àž¥	}  
+_textfoldstem_ [l=th] {"(fold, stem)"	}  
+
+_textadvquery_ [l=th] {àž«àž£àž·àž­à¹àžªà¹àžàž³àžà¹àžà¹àžàž¢àžàž£àž:	}  
+_textallfields_ [l=th] {à¹àžàžàžà¹àž­àž¡àž¹àž¥àžàž±à¹àžàž«àž¡àž	}  
+_texttextonly_ [l=th] {àžà¹àž­àžàž§àž²àž¡à¹àžà¹àž²àžàž±à¹àž	}  
+_textand_ [l=th] {à¹àž¥àž°	}  
+_textor_ [l=th] {àž«àž£àž·àž­	}  
+_textandnot_ [l=th] {à¹àž¥àž°à¹àž¡à¹à¹àžà¹	}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=th] {àžà¹àžàž«àž²à¹àž _indexselection_ _If_(_jselection_ àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àž _jselection_ ) _If_(_gselection_ àžàžµà¹àž£àž°àžàž±àž _gselection_ )_If_(_nselection_ à¹àžàž àž²àž©àž² _nselection_ )_If_(_sfselection_,\,_allowformbreak_ à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž¥àž¥àž±àžàžà¹àžà¹àž§àž¢ _sfselection_) àžªàž³àž«àž£àž±àž _querytypeselection_ àžàž­àžàžàž³
+}  
+
+_textadvancedsearch_ [l=th] {àžà¹àžàž«àž²à¹àž _indexselection_ _If_(_jselection_ àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àž _jselection_ )_If_(_gselection_ àžàžµà¹àž£àž°àžàž±àž _gselection_ level )_If_(_nselection_ à¹àžàž àž²àž©àž² _nselection_ ) à¹àžàž¢à¹àžà¹ _querytypeselection_ }  
+
+_textadvancedmgppsearch_ [l=th] {àžà¹àžàž«àž²à¹àž _indexselection_ _If_(_jselection_ àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àž _jselection_ )_If_(_gselection_àžàžµà¹àž£àž°àžàž±àž _gselection_ )_If_(_nselection_à¹àžàž àž²àž©àž² _nselection_) à¹àž¥àž°à¹àžªàžàžàžàž¥àž¥àž±àžàžà¹àžàž²àž¡àž¥àž³àžàž±àž _formquerytypeadvancedselection_ àžà¹àž§àž¢àžàž³àž§à¹àž²}  
+
+_textadvancedlucenesearch_ [l=th] {àžà¹àžàž«àž²à¹àž _indexselection__If_(_jselection_ àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àž _jselection_)_If_(_gselection_ àžàžµà¹àž£àž°àžàž±àž _gselection_ )_If_(_nselection_ à¹àžàž àž²àž©àž² _nselection_)_If_(_sfselection_\,_allowformbreak_ à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž¥àž¥àž±àžàžà¹àžà¹àž§àž¢ _sfselection_\,) àžà¹àž§àž¢àžàž³àž§à¹àž²}  
+
+_textformsimplesearch_ [l=th] {àžà¹àžàž«àž²_If_(_jselection_ à¹àž _jselection_)_If_(_gformselection_ àžàžµà¹àž£àž°àžàž±àž _gformselection_)_If_(_nselection_ à¹àžàž àž²àž©àž² _nselection_)_If_(_sfselection_\ à¹àž¥àž°à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž¥àž¥àž±àžàžà¹àžà¹àž§àž¢ _sfselection_\,) àžªàž³àž«àž£àž±àž _formquerytypesimpleselection_ of " }  
+
+_textformadvancedsearchmgpp_ [l=th] {àžà¹àžàž«àž² _If_(_jselection_ à¹àž _jselection_ )_If_(_gformselection_àžàžµà¹àž£àž°àžàž±àž _gformselection_)_If_(_nselection_à¹àžàž àž²àž©àž² _nselection_ ) à¹àž¥àž°à¹àžªàžàžàžàž¥àž¥àž±àžàžà¹àžàž²àž¡àž¥àž³àžàž±àž _formquerytypeadvancedselection_ àžà¹àž§àž¢àžàž³àž§à¹àž²}  
+
+_textformadvancedsearchlucene_ [l=th] {àžà¹àžàž«àž²_If_(_jselection_ à¹àž _jselection_)_If_(_gformselection_,  àžàžµà¹àž£àž°àžàž±àž _gformselection_)_If_(_nselection_ à¹àžàž àž²àž©àž² _nselection_)_If_(_sfselection_\, à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž¥àž¥àž±àžàžà¹àžà¹àž§àž¢ _sfselection_\,) àžà¹àž§àž¢àžàž³àž§à¹àž²}  
+
+_textnojsformwarning_ [l=th] {àžàž³à¹àžàž·àž­àž: à¹àž§à¹àžà¹àžàž£àž²àž§à¹àžàž­àž£à¹àžàž­àžàžàžžàžàžàžŽàžàžàž²àž£à¹àžà¹àžàž²àžàžàž²àž§àž²àžªàžàž£àžŽàžàžà¹  <br>à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àžà¹àžàž«àž²à¹àžàž¢à¹àžà¹à¹àžàžàžàž­àž£à¹àž¡ àžàž£àžžàžàž²à¹àžàžŽàžà¹àžà¹àžàž²àžàžàž²àž§àž²àžªàžàž£àžŽàžàžà¹	}  
+_textdatesearch_ [l=th] {àžàžžàžàžªàž²àž¡àž²àž£àžàžà¹àžàž«àž²à¹àž­àžàžªàž²àž£àž àž²àž¢à¹àžàžà¹àž§àžà¹àž§àž¥àž² àž«àž£àž·àž­à¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžµàžàž²àž£àž£àž°àžàžžàž§àž±àžàžàžµà¹àžàžµà¹à¹àžà¹àžàž­àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹à¹àžà¹  àžàžµà¹à¹àžà¹àžàžàžžàžàž¥àž±àžàž©àžàž°à¹àžàžàžàž²àžà¹àž¥àž·àž­àžàžàž­àžàžàž²àž£àžà¹àžàž«àž²	}  
+_textstartdate_ [l=th] {àž§àž±àžàžàžµà¹à¹àž£àžŽà¹àž¡àžà¹àž (à¹àžàžàž²àž°àžàžµà¹àž£àž°àžàžž):	}  
+_textenddate_ [l=th] {àž§àž±àžàžàžµà¹àžªàžŽà¹àžàžªàžžàž:	}  
+_textbc_ [l=th] {àžàžµàžà¹àž­àžàžàž£àžŽàžªàžàžšàž±àžàž£àž²àž	}  
+_textad_ [l=th] {C.E.	}  
+_textexplaineras_ [l=th] {"C.E. à¹àž¥àž° B.C.E à¹àžà¹à¹àžàžàžà¹àž²àžàž£àžŽàžªàžàžšàž±àžàž£àž²àž à¹àž¥àž°àžà¹àž­àžàžàž£àžŽàžªàžàžšàž±àžàž£àž²àžàžàž²àž¡àž¥àž³àžàž±àž  àžàž³à¹àž«àž¥à¹àž²àžàžµà¹à¹àž¡à¹àžàž·àž­à¹àžà¹àžàžàž§àž²àž¡à¹àžàžàžà¹àž²àžàžàž²àžàž§àž±àžàžàžàž£àž£àž¡ à¹àž¥àž°àž«àž¡àž²àž¢àžàž¶àžàžàž³àž§à¹àž² "àž¢àžžàžàžàž±àžàžàžžàžàž±àž" à¹àž¥àž° "àžà¹àž­àžàž¢àžžàžàžàž±àžàžàžžàžàž±àž""	}  
+
+_textstemon_ [l=th] {(à¹àž¡à¹àžªàžà¹àžàžàž±àž§àž­àž±àžàž©àž£àž¥àžàžà¹àž²àž¢àžàž³)	}  
+
+_textsearchhistory_ [l=th] {àžàž£àž°àž§àž±àžàžŽàžàž²àž£àžà¹àžàž«àž²	}  
+
+#text macros for search history
+_textnohistory_ [l=th] {à¹àž¡à¹àž¡àžµàž£àž²àž¢àžàž²àž£à¹àžà¹àžàžàž£àž°àž§àž±àžàžŽàžàž²àž£àžà¹àžàž«àž²	}  
+_texthresult_ [l=th] {àžàž¥àž¥àž±àžàžà¹	}  
+_texthresults_ [l=th] {àžàž¥àž¥àž±àžàžà¹	}  
+_texthallwords_ [l=th] {àžàž³àžàž±à¹àžàž«àž¡àž	}  
+_texthsomewords_ [l=th] {àžàž²àžàžàž³	}  
+_texthboolean_ [l=th] {àžàž£àž£àžàž°	}  
+_texthranked_ [l=th] {àžàž±àžàž­àž±àžàžàž±àž	}  
+_texthcaseon_ [l=th] {àžàž±àž§àžàžŽàž¡àžà¹à¹àž«àžà¹à¹àž¥à¹àžàžà¹àž­àžàžàž£àžàžàž±àž	}  
+_texthcaseoff_ [l=th] {à¹àž¡à¹àžàž³àž«àžàžàž¥àž±àžàž©àžàž°àžàž±àž§àžàžŽàž¡àžà¹	}  
+_texthstemon_ [l=th] {à¹àžà¹àžàž£àž²àžàžšàž±àžàžà¹	}  
+_texthstemoff_ [l=th] {à¹àž¡à¹àžàž¹àžàžàž±àžàžàž­àž	}  
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=th] {"àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°àžàž°à¹àžà¹àž£àž±àžàžàž²àž£àžàž±à¹àžàžà¹àž²à¹àž§à¹àžàž±àžàžàžµà¹  
+àžàž£àžžàžàž²àž­àž¢à¹àž²à¹àžà¹àžàžžà¹àž¡ "àž¢à¹àž­àžàžàž¥àž±àž" àžàžà¹àžàž£àž²àž§à¹àžàž­àž£à¹àžàž­àžàžàžžàž àžàž²àž£àžàž£àž°àžàž³àžàž±àžàžàž¥à¹àž²àž§àžàž°à¹àžà¹àžàžàž²àž£àž¢àžà¹àž¥àžŽàžàžà¹àž²àžàžµà¹à¹àžà¹àžàž³àž«àžàžàžàž±à¹àžàžàž±à¹àžàž«àž¡àž
+à¹àž«à¹àžàž¥àžŽàžàžàžžà¹àž¡à¹àžàžàžžà¹àž¡àž«àžàž¶à¹àžàžàžà¹àžàžà¹àžà¹àž²àžàž¶àžàžà¹àž²àžàžàžà¹àžàž
+"	}  
+_textsetprefs_ [l=th] {àžàž±à¹àžàžà¹àž²àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°	}  
+_textsearchprefs_ [l=th] {àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°àžàž²àž£àžà¹àžàž«àž²	}  
+_textcollectionprefs_ [l=th] {àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°àžàž­àž¥à¹àž¥àžàžàž±àž	}  
+_textpresentationprefs_ [l=th] {àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°àžàž²àž£àžàž³à¹àžªàžàž­	}  
+_textpreferences_ [l=th] {àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°	}  
+_textcasediffs_ [l=th] {àžàž§àž²àž¡à¹àžàžàžà¹àž²àžàžàž­àžàžàž±àž§àžàžŽàž¡àžà¹à¹àž«àžà¹-à¹àž¥à¹àž	}  
+_textignorecase_ [l=th] {àž¥àž°à¹àž§à¹àžàžàž§àž²àž¡à¹àžàžàžà¹àž²àžàž£àž°àž«àž§à¹àž²àžàžàž±àž§àžàžŽàž¡àžà¹à¹àž«àžà¹-à¹àž¥à¹àž	}  
+_textmatchcase_ [l=th] {àžàž±àž§àžàžŽàž¡àžà¹à¹àž«àžà¹/à¹àž¥à¹àžàžà¹àž­àžàžàž£àžàžàž±àž	}  
+_textwordends_ [l=th] {àžàž±àž§àž­àž±àžàž©àž£àž¥àžàžà¹àž²àž¢àžàž³	}  
+_textstem_ [l=th] {àž¥àž°à¹àž§à¹àžàž­àž±àžàžàž£àž°àž¥àžàžà¹àž²àž¢àžàž³	}  
+_textnostem_ [l=th] {àžàž±à¹àžàžàž³àžà¹àž­àžàžàž£àžàžàž±àž	}  
+_textaccentdiffs_ [l=th] {àžàž§àž²àž¡à¹àžàžàžà¹àž²àžàžà¹àž²àžàžàž²àž£à¹àžà¹àžà¹àžªàžµàž¢àž	}  
+_textignoreaccents_ [l=th] {àž¥àž°à¹àž§à¹àžàžàž²àž£à¹àžà¹àžà¹àžªàžµàž¢àž	}  
+_textmatchaccents_ [l=th] {àžàž²àž£à¹àžà¹àžà¹àžªàžµàž¢àžàžà¹àž­àžàžàž£àžàžàž±àž	}  
+
+_textprefop_ [l=th] {à¹àžªàžàžà¹àž­àžàžªàž²àž£àžàž³àžàž§àžàžªàž¹àžàžªàž _maxdocoption_ à¹àžàž¢à¹àžªàžàž _hitsperpageoption_ àž£àž²àž¢àžàž²àž£àžà¹àž­àž«àžà¹àž² 	}  
+_textextlink_ [l=th] {à¹àžà¹àž²àžàž¶àžàž«àžà¹àž²à¹àžàžàž àž²àž¢àžàž­àž:	}  
+_textintlink_ [l=th] {àžà¹àžàžàž·àžà¹àž­àžàžªàž²àž£àžà¹àžàžàžàž±àžàžàž²àž:	}  
+_textlanguage_ [l=th] {àž àž²àž©àž²àžàž­àžàž«àžà¹àž²àžàž­àžàž¹à¹à¹àžà¹àž£àž°àžàž:	}  
+_textencoding_ [l=th] {àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžª:	}  
+_textformat_ [l=th] {àž£àž¹àžà¹àžàžàž­àžŽàžà¹àžàž­àž£à¹à¹àžàž	}  
+_textall_ [l=th] {àžàž±à¹àžàž«àž¡àž	}  
+_textquerymode_ [l=th] {àž§àžŽàžàžµàžàž²àž£àžà¹àžàž«àž²:	}  
+_textsimplemode_ [l=th] {àžàž²àž£àžà¹àžàž«àž²àž­àž¢à¹àž²àžàžà¹àž²àž¢	}  
+_textadvancedmode_ [l=th] {à¹àž«àž¡àžàžàž²àž£àžà¹àžàž«àž²àž­àž¢à¹àž²àžàž¥àž°à¹àž­àžµàž¢àž (àžªàž²àž¡àž²àž£àžà¹àžà¹àžàž²àž£àžà¹àžàž«àž²àžàž²àžàžàž£àž£àžàž°à¹àžàž¢à¹àžà¹à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢ ! & | à¹àž¥àž°àž§àžà¹àž¥à¹àž)	}  
+_textlinkinterm_ [l=th] {àžà¹àž²àžàž«àžà¹àž²àžàž±à¹àž	}  
+_textlinkdirect_ [l=th] {à¹àžàžàžµà¹àžàž±à¹àžà¹àžàž¢àžàž£àž	}  
+_textdigitlib_ [l=th] {àž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥	}  
+_textweb_ [l=th] {à¹àž§à¹àž	}  
+_textgraphical_ [l=th] {àžà¹àž²àžàžàž£àž²àžàžŽàž	}  
+_texttextual_ [l=th] {à¹àžàžàžà¹àž­àžàž§àž²àž¡	}  
+_textcollectionoption_ [l=th] {"<p>
+àžàž­àž¥à¹àž¥àžàžàž±àžàž¢à¹àž­àž¢àžàžµà¹àžà¹àž­àžàžàž²àž£àž£àž§àž¡à¹àžà¹àž²àžà¹àž§àž¢àžàž±àž:
+<br>"	}  
+
+_textsearchtype_ [l=th] {àž£àž¹àžà¹àžàžàžàž­àžàžàž²àž£àžà¹àžàž«àž²:	}  
+_textformsearchtype_ [l=th] {à¹àžà¹àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àžàž¢à¹àžà¹ _formnumfieldoption_ à¹àžàžàžà¹àž­àž¡àž¹àž¥	}  
+_textplainsearchtype_ [l=th] {àžà¹àžàž«àž²à¹àžàžàžàžàžàžŽà¹àžàž¢à¹àžà¹àžàž¥à¹àž­àžàžà¹àžàž«àž² _boxsizeoption_ àžàž¥à¹àž­àž	}  
+_textregularbox_ [l=th] {àžàž£àž£àžàž±àžà¹àžàžµàž¢àž§	}  
+_textlargebox_ [l=th] {àžàžàž²àžà¹àž«àžà¹	}  
+
+_textrelateddocdisplay_ [l=th] {à¹àžªàžàžà¹àž­àžàžªàž²àž£àžàžµà¹à¹àžàžµà¹àž¢àž§àžà¹àž­àž	}  
+_textsearchhistory_ [l=th] {àžàž£àž°àž§àž±àžàžŽàžàž²àž£àžà¹àžàž«àž²:	}  
+_textnohistory_ [l=th] {à¹àž¡à¹àž¡àžµàžàž£àž°àž§àž±àžàžŽàžàž²àž£àžà¹àžàž«àž²	}  
+_texthistorydisplay_ [l=th] {à¹àžªàžàžàž£àž²àž¢àžàž²àž£àžàž£àž°àž§àž±àžàžŽàžàž²àž£àžà¹àžàž«àž²àžàž³àžàž§àž _historynumrecords_ àž£àž²àž¢àžàž²àž£	}  
+_textnohistorydisplay_ [l=th] {à¹àž¡à¹à¹àžªàžàžàžàž£àž°àž§àž±àžàžŽàžàž²àž£àžà¹àžàž«àž²	}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=th] {àžàž±àžàž¥àž³àžàž±àžà¹àž­àžàžªàž²àž£àžàž²àž¡	}  
+_textalsoshowing_ [l=th] {àžàž£à¹àž­àž¡àžàž±à¹àžà¹àžªàžàž	}  
+_textwith_ [l=th] {àžà¹àž§àž¢àžà¹àž²àžàžµà¹àž¡àž²àžàžàžµà¹àžªàžžàž	}  
+_textdocsperpage_ [l=th] {àžàž³àžàž§àžà¹àž­àžàžªàž²àž£àžà¹àž­àž«àžà¹àž²	}  
+
+_textfilterby_ [l=th] {à¹àžà¹à¹àž­àžàžªàž²àž£àžàžµà¹àžàž£àž°àžàž­àžàžà¹àž§àž¢	}  
+_textall_ [l=th] {àžàž±à¹àžàž«àž¡àž	}  
+_textany_ [l=th] {à¹àžà¹	}  
+_textwords_ [l=th] {àžàž­àžàžàž³àžàž±à¹àž	}  
+_textleaveblank_ [l=th] {àžàž¥à¹àž­àž¢à¹àž«à¹àžàž¥à¹àž­àžàžàžµà¹àž§à¹àž²àžà¹àž§à¹à¹àžàž·à¹àž­à¹àž£àžµàž¢àžàžàž¹à¹àž­àžàžªàž²àž£àžàž±à¹àžàž«àž¡àž	}  
+
+_browsebuttontext_ [l=th] {""à¹àž£àžµàž¢àžàž¥àž³àžàž±àžà¹àž­àžàžªàž²àž£""	}  
+
+_nodata_ [l=th] {<i>à¹àž¡à¹àž¡àžµàžà¹àž­àž¡àž¹àž¥</i>	}  
+_docs_ [l=th] {à¹àž­àžàžªàž²àž£	}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=th] {àž§àžŽàžàžµà¹àžà¹	}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=th] {à¹àž£àžµàž¢àžàžàž¹à¹àž­àžàžªàž²àž£àžàž²àž¡ _1_ à¹àžàž¢àžàž¥àžŽàžàžàžžà¹àž¡ _2_	}  
+
+_textSearchhelp_ [l=th] {àžà¹àžàž«àž²àžàž³à¹àžàžàžàž²àž°à¹àžàž²àž°àžàžàžàžµà¹àžàž£àž²àžàžà¹àžàžà¹àž­àžàž§àž²àž¡à¹àžàž¢àžàž¥àžŽàžàžàžžà¹àž¡ _labelSearch_	}  
+_textTohelp_ [l=th] {"à¹àž£àžµàž¢àžàžàž¹à¹àž­àžàžªàž²àž£àžàž²àž¡à¹àžàžàžà¹àž­àž¡àž¹àž¥ "àžàž¶àž" à¹àžàž¢àžàž¥àžŽàžàžàžžà¹àž¡ _labelTo_"	}  
+_textFromhelp_ [l=th] {à¹àž£àžµàž¢àžàžàž¹àžªàžŽà¹àžàžàžŽàž¡àžà¹àžà¹àž§àž¢à¹àžàžàžà¹àž­àž¡àž¹àž¥ From à¹àžàž¢àžàž¥àžŽàžàžàžžà¹àž¡ _labelFrom_	}  
+_textBrowsehelp_ [l=th] {à¹àž£àžµàž¢àžàžàž¹à¹àž­àžàžªàž²àž£	}  
+_textAcronymhelp_ [l=th] {à¹àž£àžµàž¢àžàžàž¹à¹àž­àžàžªàž²àž£àžàž²àž¡àžàž·à¹àž­àž¢à¹àž­àžàžµà¹à¹àžàžŽàžàžàž¶à¹àžà¹àžàž¢àžàž¥àžŽàžàžàžžà¹àž¡ _labelAcronym_	}  
+_textPhrasehelp_ [l=th] {à¹àž£àžµàž¢àžàžàž¹àž§àž¥àžµàžàžµà¹àžàž£àž²àžàžà¹àžà¹àž­àžàžªàž²àž£à¹àžà¹à¹àžàž¢àžàž¥àžŽàžàžàžžà¹àž¡ _labelPhrase_  àžàž¶à¹àžà¹àžà¹àžàž±àž§à¹àž£àžµàž¢àžàžàž¹àž§àž¥àžµ phind	}  
+
+_texthelptopicstitle_ [l=th] {àž«àž±àž§àžà¹àž­	}  
+
+_textreadingdocs_ [l=th] {àž§àžŽàžàžµàžàž²àž£àž­à¹àž²àžà¹àž­àžàžªàž²àž£	}  
+
+_texthelpreadingdocs_ [l=th] {<p>àžàžžàžàžªàž²àž¡àž²àž£àžàžàž­àžà¹àžà¹àž§à¹àž²àžàžžàžàžàžàž«àžàž±àžàžªàž·àž­àž«àž£àž·àž­à¹àž­àžàžªàž²àž£à¹àž¥à¹àž§àž«àž£àž·àž­àž¢àž±àž à¹àž¡àž·à¹àž­àžàž·à¹àž­à¹àž£àž·à¹àž­àž  
+àž«àž£àž·àž­àž àž²àžàž«àžà¹àž²àžàžàžàž£àž²àžàžàžàž¶à¹àžàžàž£àžŽà¹àž§àžàžà¹àž²àžàžàžàžà¹àž²àž¢àžàž­àžàž«àžà¹àž²  
+à¹àžàžàž²àžàžàž­àž¥à¹àž¥àžàžàž±à¹àž àžªàž²àž£àžàž±àžàžàž°àžàž£àž²àžàžàžàž¶à¹àžàžà¹àž§àž¢ àžàžàž°àžàžµà¹àžàž­àž¥à¹àž¥àžàžàž±àžàž­àž·à¹àžà¹ (à¹àžà¹àž à¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£à¹àžà¹àžàž±àž§à¹àž¥àž·àž­àž àž àž²àžàžàžµà¹àž¡àžµàžàž²àž£àžàž±àžàž«àžà¹àž²) àžàž°àž¡àžµà¹àžàžµàž¢àžà¹àž¥àžàžàžµà¹àžàž­àžàž«àžà¹àž²àžàž±àžàžàžžàžàž±àž
+àžàž£à¹àž­àž¡àžà¹àž§àž¢àžàž¥à¹àž­àžàžàžµà¹à¹àž«à¹àžàžžàžà¹àž¥àž·àž­àžàž«àžà¹àž²à¹àž«àž¡à¹ à¹àžàž«àžà¹àž²àžàž±àžà¹àž àž«àž£àž·àž­àž¢à¹àž­àžàžàž¥àž±àžà¹àžàž«àžà¹àž²àžà¹àž­àžàž«àžà¹àž²àžàžµà¹à¹àžà¹
+à¹àžàžªàž²àž£àžàž±àž àž«àž±àž§à¹àž£àž·à¹àž­àžàžàž­àžàžªà¹àž§àžàžàž±àžàžàžžàžàž±àžàžàž°à¹àžà¹àžàž­àž±àžàž©àž£àžàž±àž§àž«àžàž² à¹àž¥àž°àžàžžàžàžªàž²àž¡àž²àž£àžàžàž¢àž²àž¢àžàž²àž£àž²àžà¹àžà¹ à¹àžàž¢àžàž²àž£ àžàž¥àžŽàžàžàžµà¹à¹àžàž¥à¹àžàž­àž£à¹à¹àžàž·à¹àž­à¹àžàžŽàžàž«àž£àž·àž­àžàžŽàžàžªàž²àž£àžàž±àž
+àž«àž£àž·àž­àžàž¥àžŽàžàžàžµà¹àž£àž¹àžàž«àžàž±àžàžªàž·àž­àžàžµà¹à¹àžàžŽàžàž­àž¢àž¹à¹àžà¹àž²àžàžàžà¹àžàž·à¹àž­àžàžŽàžàž«àžàž±àžàžªàž·àž­</p>
+
+<p>àžà¹àž²àžàž¥à¹àž²àžàžàž°à¹àžªàžàžàžà¹àž­àžàž§àž²àž¡àžàž­àžàžªà¹àž§àžàžàž±àžàžàžžàžàž±àž àžàžàž°àžàžµà¹àžàžžàžàžàž³àž¥àž±àžàž­à¹àž²àžàžà¹àž­àžàž§àž²àž¡
+àžàž°àž¡àžµàž¥àž¹àžàžšàž£àž­àž¢àž¹à¹àžàžµà¹àžà¹àž²àžàž¥à¹àž²àžà¹àžàž·à¹àž­àžàž³àžàžžàžà¹àžàž¢àž±àžàžªà¹àž§àžàžàž±àžà¹àž àž«àž£àž·àž­àžàž¥àž±àžàž¡àž²àž¢àž±àžàžªà¹àž§àžàžà¹àž­àžàž«àžà¹àž²à¹àžà¹</p>
+
+<p>àžàž°àž¡àžµàžàžžà¹àž¡àžàžµà¹àžªàž²àž¡àž²àž£àžàžàž¥àžŽàžà¹àžà¹àž­àž¢àž¹à¹à¹àžà¹àžàž·à¹àž­à¹àž£àž·à¹àž­àžàž«àž£àž·àž­àž àž²àžàžàžàž«àžà¹àž²àž«àžàž±àžàžªàž·àž­  àžàžžàžàžªàž²àž¡àž²àž£àž àžàž¥àžŽàžàžàžµà¹
+<i>_document:textEXPANDTEXT_</i> à¹àžàž·à¹àž­àžàž¢àž²àž¢àžà¹àž­àžàž§àž²àž¡àžàž±à¹àžàž«àž¡àžàžàž­àžàžªà¹àž§àžàžàžµà¹à¹àžàžŽàžàž­àž¢àž¹à¹à¹àžàžàž±àžàžàžžàžàž±àžàž«àž£àž·àž­àž«àžàž±àžàžªàž·àž­à¹àžà¹
+àžà¹àž²à¹àž­àžàžªàž²àž£àž¡àžµàžàžàž²àžà¹àž«àžà¹àž¡àž²àž àž£àž°àžàžàž­àž²àžàžàž°à¹àžà¹à¹àž§àž¥àž²àžàž²àžà¹àž¥àž°àžàž°àžà¹àž­àžà¹àžà¹àž«àžà¹àž§àž¢àžàž§àž²àž¡àžàž³àžàž³àžàž§àžàž¡àž²àž 
+àžàž¥àžŽàžàžàžµà¹ <i>_document:textEXPANDCONTENTS_</i> à¹àžàž·à¹àž­àžàž¢àž²àž¢àžªàž²àž£àžàž±àžàžàž±à¹àžàž«àž¡àž 
+à¹àžàž·à¹àž­à¹àž«à¹àžªàž²àž¡àž²àž£àžàžàž¹àžàž·à¹àž­à¹àž£àž·à¹àž­àžàžàž­àžàžàžžàžàžàž à¹àž¥àž°àžªà¹àž§àžàž¢à¹àž­àž¢àž­àž·à¹àžà¹ à¹àžà¹
+àžàž¥àžŽàžàžàžµà¹ <i>_document:textDETACH_</i> à¹àžàž·à¹àž­à¹àžàžŽàžà¹àž­àžàžªàž²àž£àžàžµà¹à¹àžàž«àžà¹àž²àžà¹àž²àžà¹àž«àž¡à¹àžàž­àžà¹àžàž£àž²àž§à¹àžàž­àž£à¹à¹àžà¹
+(àžàžžàžàž¥àž±àžàž©àžàž°àžàžµà¹àžàž°à¹àžà¹àžàžàž£àž°à¹àž¢àžàžà¹àžà¹àž²àžàžžàžàžà¹àž­àžàžàž²àž£à¹àžàž£àžµàž¢àžà¹àžàžµàž¢àžà¹àž­àžàžªàž²àž£ àž«àž£àž·àž­àž­à¹àž²àžà¹àž­àžàžªàž²àž£àžªàž­àžàžàžàž±àžàžàž£à¹àž­àž¡àžàž±àž) 
+à¹àž¥àž°àžà¹àž²àž¢àžàžµà¹àžªàžžàž  à¹àž¡àž·à¹àž­àžàžžàžàžàž³à¹àžàžŽàžàžàž²àž£àžà¹àžàž«àž² àžàž³àžàžµà¹àžàžžàžàžà¹àžàž«àž²àžàž°àžàž¹àžà¹àžà¹àž
+àžà¹àž§àž¢à¹àžàžàžªàžµ àžàžžàžàžªàž²àž¡àž²àž£àžàžàž¥àžŽàžàžàžµà¹ <i>_document:textNOHIGHLIGHT_</i> à¹àžàž·à¹àž­à¹àž­àž²àžàž²àž£à¹àžà¹àžàžàž³àž­àž­àžà¹àžà¹</p>
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=th] {à¹àžàžŽàžàžàž±à¹àžàž§àž²àžàž«àžàž±àžàžªàž·àž­àžàžµà¹	}  
+_texthelpopenbook_ [l=th] {à¹àžàžŽàž/àžàžŽàžàž«àžàž±àžàžªàž·àž­àžàžµà¹	}  
+_texthelpviewtextsection_ [l=th] {àžàž¹àžªà¹àž§àžàžàžµà¹àžàž­àžàžà¹àž­àžàž§àž²àž¡	}  
+_texthelpexpandtext_ [l=th] {à¹àžªàžàžàžà¹àž­àžàž§àž²àž¡àžàž±à¹àžàž«àž¡àž àž«àž£àž·àž­à¹àž¡à¹à¹àžªàžàžàžà¹àž­àžàž§àž²àž¡àžàž±à¹àžàž«àž¡àž	}  
+_texthelpexpandcontents_ [l=th] {àžàž¢àž²àž¢àžàž²àž£àž²àžàžªàž²àž£àžàž±àž àž«àž£àž·àž­à¹àž¡à¹àžàž¢àž²àž¢	}  
+_texthelpdetachpage_ [l=th] {à¹àžàžŽàžàž«àžà¹àž²àžàžµà¹à¹àžàž«àžà¹àž²àžà¹àž²àžà¹àž«àž¡à¹	}  
+_texthelphighlight_ [l=th] {à¹àžà¹àžàžàž³àžà¹àž àž«àž£àž·àž­à¹àž¡à¹à¹àžà¹àž	}  
+_texthelpsectionarrows_ [l=th] {à¹àžàž¢àž±àžàžªà¹àž§àž àžà¹àž­àžàž«àžà¹àž²/àžàž±àžà¹àž	}  
+
+
+_texthelpsearchingtitle_ [l=th] {àž§àžŽàžàžµàžàž²àž£àžà¹àžàž«àž²àžàž³à¹àžàžà¹àžàžàž²àž°à¹àžàž²àž°àžàž	}  
+
+_texthelpsearching_ [l=th] {<p>
+  àžàž²àžàž«àžà¹àž²àžà¹àžàž«àž² àžàžžàžàžªàž²àž¡àž²àž£àžàžàž³à¹àžàžŽàžàžàž²àž£àžªàž·àžàžà¹àžà¹àžà¹àžà¹àž§àž¢àžàž±à¹àžàžàž­àžàžà¹àž²àž¢à¹ àžàž±àžàžà¹àž­à¹àžàžàžµà¹<p>
+
+  <ol><li>àž£àž°àžàžžàž£àž²àž¢àžàž²àž£àžàžµà¹àžàžžàžàžà¹àž­àžàžàž²àž£àžà¹àžàž«àž²
+      <li>àžàž³àž«àžàžàž§à¹àž²àžàžžàžàžà¹àž­àžàžàž²àž£àžàž°àžà¹àžàž«àž²àžàž±à¹àžàžàž³ àž«àž£àž·àž­à¹àžàžµàž¢àžàžàž²àžàžªà¹àž§àžàžàž­àžàžàž³
+      <li>àžàžŽàž¡àžà¹àžàž³àžàžµà¹àžàžžàžàžà¹àž­àžàžàž²àž£àžà¹àžàž«àž²
+      <li>àžàž¥àžŽàžàžàžžà¹àž¡ <i>à¹àž£àžŽà¹àž¡àžà¹àžàžà¹àžàž«àž²</i>
+  </ol>
+
+<p>à¹àž¡àž·à¹àž­àžàžžàžàžàž³àžàž²àž£àžªàž·àžàžà¹àž àžàž·à¹àž­à¹àž£àž·à¹àž­àžàžàž­àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž£àžàžàž±àžàžàž²àž£àžà¹àžàž«àž²àžàž³àžàž§àžàž¢àžµà¹àžªàžŽàžàžàž·à¹àž­àžàž°à¹àžªàžàžàžàž¶à¹àžàžàžàž«àžà¹àž²àžàž­
+àžàžžàžàžªàž²àž¡àž²àž£àžàžàž¥àžŽàžàžàžžà¹àž¡àžàžµà¹àžà¹àž²àžàž¥à¹àž²àžà¹àžàž·à¹àž­àžàž¹à¹àž­àžàžªàž²àž£àž¢àžµà¹àžªàžŽàžà¹àž£àž·à¹àž­àžàžàž±àžà¹àžà¹àžà¹
+àžàž²àžàžàžžàžàžàžµà¹ àžàžžàžàžàž°àžàžàžàžžà¹àž¡àžàžµà¹àžàžžàžàžªàž²àž¡àž²àž£àžàžàž¥àžŽàžà¹àžàž·à¹àž­à¹àžàž¢àž±àžàž­àžµàžàž¢àžµà¹àžªàžŽàžà¹àž£àž·à¹àž­àžàžàž±àžà¹àž àž«àž£àž·àž­àž¢à¹àž­àžàžàž¥àž±àžà¹àžàž¢àž±àžàž¢àžµà¹àžªàžŽàžà¹àž£àž·à¹àž­àžà¹àž£àž à¹àžà¹àžàžàžµà¹àž­àžµàž
+àž«àž²àžàžàžžàžàžà¹àž­àžàžàž²àž£àžàž¹à¹àž­àžàžªàž²àž£ à¹àž«à¹àžàž¥àžŽàžàžàžµà¹àžàž·à¹àž­à¹àž£àž·à¹àž­àžàžàž­àžà¹àž­àžàžªàž²àž£àžàžµà¹àžà¹àž­àžàžàž²àž£ àž«àž£àž·àž­àžàž¥àžŽàžàžàžžà¹àž¡à¹àž¥à¹àžà¹ àžàžµà¹àž­àž¢àž¹à¹àžà¹àž²àžà¹àž­àžàžªàž²àž£àžàž±à¹àž
+
+<p>àžàž¥àž¥àž±àžàžà¹àžàž­àžàžàž²àž£àžà¹àžàž«àž²àžàž°àžàž¹àžàžàž³àžàž±àžà¹àž§à¹àžàžµà¹à¹àž¡à¹à¹àžàžŽàž 50 à¹àž£àž·à¹àž­àž  àžàžžàžàžªàž²àž¡àž²àž£àžà¹àžàž¥àžµà¹àž¢àžàžàž±àž§à¹àž¥àžàžàžµà¹à¹àžà¹à¹àžàž¢àžàž¥àžŽàžàžàžžà¹àž¡
+  <i>_Global:linktextPREFERENCES_</i> àžàžµà¹àž­àž¢àž¹à¹àžà¹àž²àžàžàžàžªàžžàžàžàž­àžàž«àžà¹àž²<p>}  
+
+_texthelpquerytermstitle_ [l=th] {àžàž³àžà¹àž	}  
+_texthelpqueryterms_ [l=th] {"<p>àž£àž°àžàžàžàž°àžàžµàžàž§àž²àž¡àžàžžàžàžªàžŽà¹àžàžàžµà¹àžàžžàžàžàžŽàž¡àžà¹àž¥àžà¹àžàžàž¥à¹àž­àžàžà¹àžàž«àž²à¹àžà¹àžàž£àž²àž¢àžàž²àž£àžàž³àž«àž£àž·àž­àž§àž¥àžµ
+àžàž¶à¹àžà¹àž£àžµàž¢àžàž§à¹àž² "àžàž³àžà¹àž"  àžàž³àžà¹àžàž­àž²àžàžàž°à¹àžà¹àžàžàž³à¹àžàžµàž¢àžàžàž³à¹àžàžµàž¢àž§àžàž¶à¹àžàžàž£àž°àžàž­àžàžà¹àž§àž¢àžàž±àž§àž­àž±àžàž©àž£à¹àž¥àž°àžàž±àž§à¹àž¥àž àž«àž£àž·àž­
+àž§àž¥àžµàžàž¶à¹àžàžàž£àž°àžàž­àžàžà¹àž§àž¢àž¥àž³àžàž±àžàžàž­àžàžàž³àžàž¶à¹àžàžàž£àž­àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àž­àž±àžàžàž£àž°àžàž²àžš ("...")
+àžàž³àžà¹àžà¹àžà¹àž¥àž°àžàž³àžàž°àžàž¹àžà¹àžà¹àžàžà¹àž§àž¢àžà¹àž­àžàž§à¹àž²àž  àžà¹àž²àž¡àžµàž­àž±àžàžàž£àž°àž­àž·à¹àžà¹àž à¹àžà¹àž à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àž§àž£àž£àžàžàž­àž àžàž£àž²àžàžàž­àž¢àž¹à¹ àž­àž±àžàžàž£àž°à¹àž«àž¥à¹àž²àžàž±à¹àžàžàž°àžàž³àž«àžà¹àž²àžàžµà¹à¹àžà¹àžàžàž³à¹àž«àž¡àž·àž­àžàžàž±àžàž§à¹àž²àž­àž±àžàžàž£àž°àžàž±à¹àžà¹àžà¹àžàžà¹àž­àžàž§à¹àž²àž
+à¹àž¥àž°àžàž°àžàž¹àžàž¥àž°à¹àž§à¹àžà¹àžàž¢àž£àž°àžàž àžàžžàžàžàž°à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžà¹àžàž«àž²àžàž³àžàžµà¹àž¡àžµà¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àž§àž£àž£àžàžàž­àžàž­àž¢àž¹à¹àžà¹àž§àž¢à¹àžà¹
+
+<p>àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž àžàž²àž£àžà¹àžàž«àž²<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>àžàž°à¹àžà¹àž£àž±àžàžàž²àž£àžàžµàžàž§àž²àž¡à¹àž«àž¡àž·àž­àžàžàž±àž<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+"	}  
+
+_texthelpmgppsearching_ [l=th] {"àžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžªàž£à¹àž²àžàžà¹àž§àž¢ MGPP àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžàžàž±àž§à¹àž¥àž·àž­àžàž­àž·à¹àžà¹àžà¹àžàž±àžàžàžµà¹
+
+<ul>
+<li>A <b>*</b> àžàžµà¹àžà¹àž­àžà¹àž²àž¢àžàž³àžà¹àžàžàž°àžàž£àžàžàž±àžàžàž³àžàžžàžàžàž³àžàžµà¹ <b>àžàž¶à¹àžàžà¹àžàžà¹àž§àž¢</b> àžàž³àžàž±à¹àž à¹àžà¹àž <b>comput*</b> àžàž°àžàž£àžàžàž±àžàžàž³àžàžžàžàžàž³àžàžµà¹àžàž¶à¹àžàžà¹àžàžà¹àž§àž¢àžàž³àž§à¹àž²  <b>comput</b>
+<li><b>/x</b> àžªàž²àž¡àž²àž£àžà¹àžà¹à¹àžàžŽà¹àž¡àžà¹àž³àž«àžàž±àžà¹àž«à¹àžàž±àžàžàž³àžà¹àžàžàž±à¹àžà¹àžà¹àž«àžàž¶à¹àžàžàž³àžàž¶à¹àžà¹àž à¹àžà¹àž <b>computer/10 science</b> àžàž°à¹àž«à¹àžà¹àž³àž«àžàž±àžàžàž±àžàžàž³àž§à¹àž² computer à¹àžà¹àž 10 à¹àžà¹àž²àžàž­àžàžàž³àž§à¹àž² science à¹àž¡àž·à¹àž­àžàž³àžàž²àž£àžàž±àžàž£àž°àžàž±àžà¹àž­àžàžªàž²àž£
+</ul>
+"	}  
+
+_texthelplucenesearching_ [l=th] {"àžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžªàž£à¹àž²àžàžà¹àž§àž¢ Lucene àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžàžàž±àž§à¹àž¥àž·àž­àžàž­àž·à¹àžà¹àžà¹àžàž±àžàžàžµà¹ 
+
+<ul>
+<li><b>?</b> àžªàž²àž¡àž²àž£àžà¹àžà¹à¹àžà¹àžàž­àž±àžàžàž£àž°àžàžŽà¹àžšàž©à¹àžàžàžàž­àžàžàž±àž§àž­àž±àžàž©àž£àž«àžàž¶à¹àžàžàž±àž§  àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž <b>b?t</b> àžàž°àžàž£àžàžàž±àžàžàž³ <b>bet</b>, <b>bit</b> à¹àž¥àž° <b>bat</b> à¹àžà¹àžàžà¹àž
+<li><b>*</b> àžªàž²àž¡àž²àž£àžà¹àžà¹à¹àžà¹àžàž­àž±àžàžàž£àž°àžàžŽà¹àžšàž©à¹àžàžàžàž­àžàžàž±àž§àž­àž±àžàž©àž£àž«àž¥àž²àž¢àžàž±àž§  àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž <b>comput*</b> àžàž£àžàžàž±àžàžàž³àžàžžàžàžàž³àžàžµà¹àžàž¶à¹àžàžà¹àžàžà¹àž§àž¢ <b>comput</b>
+</ul>
+àž­àž±àžàžàž£àž°àžàžŽà¹àžšàž©àžàž±à¹àžàžªàž­àžàžàž±àž§àžàžµà¹àžªàž²àž¡àž²àž£àžàž§àž²àžà¹àž§à¹àžàž£àžàžàž¥àž²àžàžàž­àžàžàž³ àž«àž£àž·àž­àžà¹àž²àž¢àžàž³àžà¹à¹àžà¹ à¹àžà¹à¹àž¡à¹àžªàž²àž¡àž²àž£àžàž§àž²àžà¹àž§à¹àž«àžà¹àž²àžàž³àžàžµà¹àžàž°àžà¹àžàž«àž²à¹àžà¹
+"	}  
+
+_texthelpquerytypetitle_ [l=th] {àžàžàžŽàžàžàž­àžàžàž²àž£àžà¹àžàž«àž²	}  
+_texthelpquerytype_ [l=th] {"<p>àž¡àžµàžàž²àž£àžà¹àžàž«àž²àžàžµà¹à¹àžàžàžà¹àž²àžàžàž±àžàžªàž­àžàž£àž¹àžà¹àžàž àžàž·àž­
+
+<ul>
+  <li>àžàž²àž£àžà¹àžàž«àž² <b>àžàž±à¹àžàž«àž¡àž</b> àžàž­àžàžàž³ 
+      à¹àžà¹àžàžàž²àž£àžà¹àžàž«àž²à¹àž­àžàžªàž²àž£ (àž«àž£àž·àž­àžàž àž«àž£àž·àž­àžàž·à¹àž­à¹àž£àž·à¹àž­àž) àžàžµà¹àž¡àžµàžàž³àžàž±à¹àžàž«àž¡àžàžàžµà¹àžàžžàžàž£àž°àžàžžà¹àž§à¹
+      à¹àž­àžàžªàž²àž£àžàžµà¹àžàž£àžàžàž²àž¡àžàž²àž£àžà¹àžàž«àž²àžàž°à¹àžªàžàžàžàž¶à¹àžàžàž²àž¡àž¥àž³àžàž±àžàžàžµà¹à¹àžà¹àžàž³àž«àžàžà¹àž§à¹
+<p>
+
+  <li>àžàž²àž£àžà¹àžàž«àž² <b>àžàž²àžàžªà¹àž§àž</b> àžàž°à¹àžªàžàž
+      à¹àžàžµàž¢àžàžàž³àžàž²àžàžàž³àžàžµà¹àž­àž²àžàžàž£àž²àžàžà¹àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàžžàžàžàž³àž¥àž±àžàžà¹àžàž«àž²
+      àžàž¥àž¥àž±àžàžà¹àžàžµà¹à¹àžà¹àžàž°à¹àžªàžàžàžàž¶à¹àžàžàž²àž¡àž£àž°àžàž±àžàžà¹àž²àžàž§àž²àž¡à¹àžàž¥à¹à¹àžàžµàž¢àžàžàž±àžàžàž²àž£àžà¹àžàž«àž² 
+      àž£àž°àžàžàžàž°àžàž³àžàž²àž£àžàžŽàžàž²àž£àžàž²àž£àž°àžàž±àžàžà¹àž²àžàž±àžàžàžµà¹
+
+      <p><ul>
+        <li> àž«àž²àžàž¡àžµàžàž³àžàž§àžàžàž³àžà¹àžàžàž£àž²àžàžà¹àžà¹àž­àžàžªàž²àž£àž¡àž²àž àž£àž°àžàž±àžàžà¹àž²àžàž§àž²àž¡àžàž£àžàžàž±àžàžàž°àžªàž¹àž
+        <li> àžàž³àžàžµà¹à¹àž¡à¹àžà¹àž­àž¢àžàž£àž²àžàžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàž¡àžµàžàž§àž²àž¡àžªàž³àžàž±àžàž¡àž²àžàžàž§à¹àž²àžàž³àžàžµà¹àžàžà¹àžàž¢àžàž±à¹àž§à¹àž
+        <li> à¹àž­àžàžªàž²àž£àžàžàž²àžàžªàž±à¹àžàžàž°àž¡àžµàž£àž°àžàž±àžàžàž§àž²àž¡àžàž£àžàžàž±àžàžàžµàžàž§à¹àž²à¹àž­àžàžªàž²àž£àžàžàž²àžàž¢àž²àž§
+      </ul>
+</ul>
+
+<p>à¹àž«à¹à¹àžà¹àžàž³àžà¹àžàž«àž²à¹àžà¹àž¡àž²àžà¹àžà¹àž²àžàžµà¹àžàžžàžàžà¹àž­àžàžàž²àž£ à¹àžàž¢àž­àž²àžàžàž°à¹àžà¹àžàžàž±à¹àžàžàž£àž°à¹àž¢àž àž«àž£àž·àž­àžàž±à¹àžàž¢à¹àž­àž«àžà¹àž²
+àžà¹àž²àžàžžàžàž£àž°àžàžžàžàž³à¹àžàžµàž¢àžàž«àžàž¶à¹àžàžàž³ à¹àž­àžàžªàž²àž£àžàžµà¹à¹àžà¹àžàž²àžàžàž²àž£àžà¹àžàž«àž²àžàž°à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž²àž¡àžàž§àž²àž¡àžàžµà¹àžàž­àžàžàž³àžàžµà¹àžàž£àž²àžàžà¹àžà¹àž­àžàžªàž²àž£<p>
+"	}  
+
+_texthelpadvancedsearchtitle_ [l=th] {àžàž²àž£àžà¹àžàž«àž²àž­àž¢à¹àž²àžàž¥àž°à¹àž­àžµàž¢àžà¹àžà¹àžàž±àž§àžà¹àžàž«àž² _1_	}  
+
+_texthelpadvancedsearch_ [l=th] {<p>àžà¹àž²àžàžžàžà¹àž¥àž·àž­àžà¹àž«àž¡àžàžàž²àž£àžà¹àžàž«àž²àž­àž¢à¹àž²àžàž¥àž°à¹àž­àžµàž¢àž (à¹àž àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°) àžàžžàžàžàž°à¹àž«à¹àžàžàž±àž§à¹àž¥àž·àž­àžàžàž²àž£àžà¹àžàž«àž²àžàžµà¹àžà¹àž²àžàžàž±àžà¹àž¥à¹àžàžà¹àž­àž¢ }  
+
+_texthelpadvsearchmg_ [l=th] {"àžàž²àž£àžà¹àžàž«àž²àž­àž¢à¹àž²àžàž¥àž°à¹àž­àžµàž¢àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àž MG àž¡àžµàžªàž­àžàžàž±àž§à¹àž¥àž·àž­àž àžàž·àž­ à¹àžàžàžàž±àžàž£àž°àžàž±àž à¹àž¥àž°à¹àžàžàžàž£àž£àžàž°
+àžàž²àž£àžà¹àžàž«àž² <b>à¹àžàžàžàž±àžàž£àž°àžàž±àž</b> àžàž°à¹àž«àž¡àž·àž­àžàžàž±àžàžàž²àž£àžà¹àžàž«àž²à¹àžàž <b>àžàž²àžàžªà¹àž§àž</b> àžàž±àžàžàžµà¹à¹àžà¹àž­àžàžŽàžàž²àž¢à¹àž§à¹à¹àž <a href="\#query-type">_texthelpquerytypetitle_</a>
+<p>_texthelpbooleansearch_
+"	}  
+
+_texthelpbooleansearch_ [l=th] {"àžàž²àž£àžà¹àžàž«àž²à¹àžàž <b>àžàž£àž£àžàž°</b> àžàž°àž¢àž­àž¡à¹àž«à¹àžàžžàžàžàžªàž²àžàžàž³àžà¹àžàžà¹àž²àžà¹ à¹àžàž¢à¹àžà¹àž­àž±àžàžàž£àž° & (à¹àžàž "à¹àž¥àž°") | (à¹àžàž "àž«àž£àž·àž­") à¹àž¥àž° ! (à¹àžàž "à¹àž¡à¹") à¹àž¥àž°à¹àžà¹àž§àžà¹àž¥à¹àžà¹àžàžàž²àž£àžàž±àžàžàž¥àžžà¹àž¡àžà¹àž²àžà¹àž­àžàžàž²àž£  àžàž±àž§àžàž³à¹àžàžŽàžàžàž²àž£àžàž²àž¡àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžàžàž·àž­ | (à¹àžàž "àž«àž£àž·àž­")
+<p>
+àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž <b>snail & farming</b> àžàž°àžàž£àžàžàž±àžà¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžµàžàž±à¹àžàžàž³àž§à¹àž² <b>snail</b> à¹àž¥àž° <b>farming</b> àžàžàž°àžàžµà¹ <b>snail | farming</b> àžàž°àžàž£àžàžàž±àžà¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžµàžàž³àž§à¹àž² <b>snail</b> àž«àž£àž·àž­ <b>farming</b> àžà¹à¹àžà¹
+<b>snail !farming</b> àžàž°àžàž£àžàžàž±àžà¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžµàžàž³àž§à¹àž² <b>snail</b> à¹àž¥àž°à¹àž¡à¹àž¡àžµàžàž³àž§à¹àž² <b>farming</b>
+<p>
+àžàžžàžàžªàž²àž¡àž²àž£àžàž£àž°àžàžžàžàž²àž£àžà¹àžàž«àž²àžàžµà¹àžàž±àžà¹àžàžàžàž¶à¹àžà¹àžà¹à¹àžàž¢à¹àžà¹àžàž²àž£àžàžªàž¡àžàžªàž²àžàžàž±àžàžàž­àžàžàž±àž§àžàž³à¹àžàžŽàžàžàž²àž£à¹àž¥àž°àž§àžà¹àž¥à¹àž  àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž <b>(sheep | cattle) & (farm | station)</b> àž«àž£àž·àž­ <b>sheep | cattle | goat !pig</b>
+"	}  
+
+_texthelpadvsearchmgpp_ [l=th] {"àžàž²àž£àžà¹àžàž«àž²àž­àž¢à¹àž²àžàž¥àž°à¹àž­àžµàž¢àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àž MGPP à¹àžà¹àžàž±àž§àžàž³à¹àžàžŽàžàžàž²àž£à¹àžàžàžàž£àž£àžàž° _texthelpbooleansearch_
+<p>àž£àž°àžàžàžªàž²àž¡àž²àž£àžà¹àžªàžàžàžàž¥àž¥àž±àžàžà¹à¹àžàž£àž¹àžà¹àžàžàžàž­àžàž¥àž³àžàž±àž <b>àžàžµà¹àžàž±àžàž­àž±àžàžàž±àžà¹àž§à¹</b> àžàž±àžàžàžµà¹à¹àžà¹àž¡àžµàžàž²àž£àž­àžàžŽàžàž²àž¢à¹àžàžàž²àž£àžà¹àžàž«àž²à¹àžàž <b>àžàž²àžàžªà¹àž§àž</b> à¹àž <a href="\#query-type">_texthelpquerytypetitle_</a> àž«àž£àž·àž­àž£àž¹àžà¹àžàžàž¥àž³àžàž±àž "àžàžàžàžŽ" (àž«àž£àž·àž­ "àžªàž£à¹àž²àž")  àžàž¶à¹àžà¹àžà¹àžàžàž²àž£àžàž±àžàž¥àž³àžàž±àžàžàžàž°àžàž³à¹àžàžŽàžàžàž²àžà¹àž­àžàžªàž²àž£àž£àž°àž«àž§à¹àž²àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àž
+<p>
+àžàž±àž§àžàž³à¹àžàžŽàžàžàž²àž£àž­àž·à¹àžà¹ àžàž£àž°àžàž­àžàžà¹àž§àž¢ <b>NEARx</b> à¹àž¥àž° <b>WITHINx</b>
+NEARx àžàž°à¹àžà¹à¹àžàžàž²àž£àž£àž°àžàžžàž£àž°àž¢àž°àž«à¹àž²àžàžàžµà¹àž¡àž²àžàžàžµà¹àžªàžžàžà¹àž¡à¹à¹àžàžŽàž ( x àžàž³) àž£àž°àž«àž§à¹àž²àžàžàž³àžà¹àžàžªàž­àžàžàž³àž àž²àž¢à¹àžàž àž²àž¢à¹àž­àžàžªàž²àž£ 
+WITHINx àžàž°àž£àž°àžàžžàž§à¹àž² àžàž³àžàžµà¹àžªàž­àžàžà¹àž­àžàžàž£àž²àžàžàž àž²àž¢à¹àž x àžàž³ <i>àž«àž¥àž±àžàžàž²àž</i> àžàž³àžàžµà¹àž«àžàž¶à¹àž  àžàž¶à¹àžàžàž°àžàž¥à¹àž²àž¢àžàž±àž NEAR à¹àžà¹à¹àžà¹àžà¹àž£àž·à¹àž­àžàž¥àž³àžàž±àžà¹àžà¹àžàžªàž³àžàž±àž  àž£àž°àž¢àž°àž«à¹àž²àžà¹àž£àžŽà¹àž¡àžà¹àžàž¡àžµàžà¹àž²à¹àžà¹àž²àžàž±àž 20
+"	}  
+
+_texthelpadvancedsearchextra_ [l=th] {àž«àž¡àž²àž¢à¹àž«àžàžž: àžàž±àž§àžàž³à¹àžàžŽàžàžàž²àž£à¹àž«àž¥à¹àž²àžàžµà¹àžàž°àžàž¹àžàž¥àž°à¹àž§à¹àžàžàž±à¹àžàž«àž¡àžàžà¹àž²àžàžžàžàžàž³àž¥àž±àžàžà¹àžàž«àž²àžà¹àž§àž¢àž§àžŽàžàžµàžàž²àž£àžà¹àžàž«àž²àž­àž¢à¹àž²àžàžà¹àž²àž¢	}  
+
+_texthelpadvsearchlucene_ [l=th] {àžàž²àž£àžà¹àžàž«àž²àž­àž¢à¹àž²àžàž¥àž°à¹àž­àžµàž¢àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àž Lucene à¹àžà¹àžàž±àž§àžàž³à¹àžàžŽàžàžàž²àž£àžàž²àžàžàž£àž£àžàž° _texthelpbooleansearch_	}  
+
+_texthelpformsearchtitle_ [l=th] {àžàž²àž£àžà¹àžàž«àž²àžàž²àž¡à¹àžàžàžà¹àž­àž¡àž¹àž¥	}  
+
+_texthelpformsearch_ [l=th] {"<p>àžàž²àž£àžà¹àžàž«àž²àžà¹àž§àž¢à¹àžàžàžà¹àž­àž¡àž¹àž¥àžàž°àžà¹àž§àž¢à¹àž«à¹àžàžžàžàžªàž²àž¡àž²àž£àžàžàžªàž²àžàžàž²àž£àžà¹àžàž«àž²àžà¹àž²àž¡à¹àžàžàžà¹àž­àž¡àž¹àž¥àžà¹àž²àžà¹ à¹àžà¹  àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž àžàžžàžàžªàž²àž¡àž²àž£àžàžà¹àžàžàž³àž§à¹àž² "àžªàž¡àžàž²àž¢" à¹àžàžàž·à¹àž­à¹àž£àž·à¹àž­àž à¹àž¥àž° àžàž³àž§à¹àž² "àžàž²àž£à¹àžàž²àž°à¹àž¥àžµà¹àž¢àžàž«àž­àž¢àžàž²àž" à¹àžàž«àž±àž§à¹àž£àž·à¹àž­àžà¹àžà¹ à¹àžàž¢à¹àžà¹àžàž³à¹àžàž·à¹àž­àž¡ "à¹àž¥àž°"
+à¹àžàž§àžŽàžàžµàžàž²àž£àžà¹àžàž«àž²àž­àž¢à¹àž²àžàžà¹àž²àž¢àžàž±à¹àž à¹àžà¹àž¥àž°àžàž£àž£àžàž±àžàžàž­àžà¹àžàžàžàž­àž£à¹àž¡àžàž°àžàž³àž«àžà¹àž²àžàžµà¹à¹àž«àž¡àž·àž­àžàžàž±àžàžàž²àž£àžà¹àžàž«àž²àžàž£àž£àžàž±àžà¹àžàžµàž¢àž§à¹àžàžàžàžàžàžŽ  à¹àžàž¢à¹àžà¹àž¥àž°àžàž£àž£àžàž±àžàžàž­àžà¹àžàžàžàž­àž£à¹àž¡àžàž°àžàž¹àžàžàžªàž²àžàžàž±àžàžà¹àž§àž¢àžàž³àž§à¹àž² "à¹àž¥àž°" (àžªàž³àž«àž£àž±àžàžàž²àž£àžà¹àžàž«àž² "àžàž±à¹àžàž«àž¡àž") àž«àž£àž·àž­ "àž«àž£àž·àž­" (àžªàž³àž«àž£àž±àžàžàž²àž£àžà¹àžàž«àž² "àžàž²àžàžªà¹àž§àž")  àžàž³àž àž²àž¢à¹àžà¹àžàžàžà¹àž­àž¡àž¹àž¥àžàž°àžàž¹àžàžàžªàž²àžà¹àžà¹àž²àžà¹àž§àž¢àžàž±àžà¹àžàž£àž¹àžà¹àžàžà¹àžàžµàž¢àž§àžàž±àž
+à¹àžàž§àžŽàžàžµàžàž²àž£àžà¹àžàž«àž²àž­àž¢à¹àž²àžàž¥àž°à¹àž­àžµàž¢àžàžàž±à¹àž àžàžžàžàžªàž²àž¡àž²àž£àžàž£àž°àžàžžàžàž²àž£àžàžªàž²àžàžàž±àžàžàž­àž à¹àž¥àž°/àž«àž£àž·àž­/à¹àž¡à¹ àžàžµà¹à¹àžàžàžà¹àž²àžàžàž±àžàž£àž°àž«àž§à¹àž²àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àžà¹à¹àžàž¢à¹àžà¹àž£àž²àž¢àžàž²àž£àžàž£à¹àž­àžàžàž²àž§àžà¹ à¹àž¥àž°àž àž²àž¢à¹àžà¹àžàžàžà¹àž­àž¡àž¹àž¥àžàž±à¹àž àžàžžàžàžà¹àžªàž²àž¡àž²àž£àžà¹àžà¹àžàž±àž§àžàž³à¹àžàžŽàžàžàž²àž£àžàž²àžàžàž£àž£àžàž°à¹àžà¹à¹àžà¹àžàžàž±àž
+"	}  
+
+_texthelpformstemming_ [l=th] {"àžàž¥à¹àž­àž "fold" à¹àž¥àž° "stem" àžàž°àž­àžàžžàžàž²àžà¹àž«à¹àžàžžàžàž£àž°àžàžžà¹àžà¹àž§à¹àž² àžàž³àžàžµà¹àž­àž¢àž¹à¹à¹àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àžà¹àžà¹àžàžà¹àž¡à¹àžªàžà¹àžàž£àž¹àžà¹àžàžàžàž­àžàžàž±àž§àžàžŽàž¡àžà¹ àž«àž£àž·àž­à¹àžà¹àžà¹àžàžàž£àž²àžàžšàž±àžàžà¹  à¹àžàž¢àžàžàžàžŽà¹àž¥à¹àž§àžà¹àž²àžàž±à¹àžàžªàž­àžàžàž°àžàž¹àžàžàžŽàžà¹àž§à¹àžªàž³àž«àž£àž±àžàžàž²àž£àžà¹àžàž«àž²à¹àžàž¢à¹àžà¹à¹àž¡à¹à¹àžàžàž­àž¢à¹àž²àžàž¥àž°à¹àž­àžµàž¢àž"	}  
+
+_textdatesearch_ [l=th] {àžàž²àž£àžà¹àžàž«àž²àžà¹àž§àž¢àž§àž±àžàžàžµà¹	}  
+
+_texthelpdatesearch_ [l=th] {"àžàž²àž£àžà¹àžàž«àž²àžà¹àž§àž¢àž§àž±àžàžàžµà¹àžàž³à¹àž«à¹àžàžžàžàžàžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž£àžàžàž±àžàžàž³àžàžµà¹àžàžžàžàžà¹àžàž«àž²àžàž¶à¹àžà¹àžà¹àžà¹àž«àžàžžàžàž²àž£àžà¹àžàžµà¹à¹àžàžŽàžàžàž¶à¹àžàž àž²àž¢à¹àžàžà¹àž§àžà¹àž§àž¥àž²àžàžµà¹à¹àžà¹àžàž­àž
+àžàžžàžàžªàž²àž¡àž²àž£àžàžà¹àžàž«àž²à¹àž­àžàžªàž²àž£àžà¹àž§àž¢àžàžµàžàžµà¹à¹àžà¹àžàž­àž àž«àž£àž·àž­àžà¹àž§àžàžàžµàžà¹à¹àžà¹
+à¹àžàž£àžàžàž³à¹àž§à¹àž§à¹àž² àžàžžàžà¹àž¡à¹àžàž³à¹àžà¹àžàžà¹àž­àžà¹àžà¹àžàž³àžà¹àžà¹àžà¹ àžàžžàžàžªàž²àž¡àž²àž£àžàžà¹àžàž«àž²à¹àžàž¢àž£àž°àžàžžàž§àž±àžàžàžµà¹àž­àž¢à¹àž²àžà¹àžàžµàž¢àž§à¹àžà¹
+à¹àž¥àž°àžàžžàžàž¢àž±àžà¹àž¡à¹àžàž³à¹àžà¹àžàžà¹àž­àžà¹àžà¹àž§àž±àžàžàžµà¹à¹àžàžàž²àž£àžà¹àžàž«àž²àžàž­àžàžàžžàž à¹àžàž¢àžà¹àž²àžàžžàžà¹àž¡à¹à¹àžà¹à¹àžªà¹àžà¹àž²àž§àž±àžàžàžµà¹à¹àžà¹ àž£àž°àžàžàžà¹àžàž°à¹àž«à¹àžàž¥à¹àž«àž¡àž·àž­àžàžàž±àžàž§à¹àž²à¹àž¡à¹àž¡àžµàžàž²àž£àžà¹àžàž«àž²àžà¹àž§àž¢àž§àž±àžàžàžµà¹àžàž±à¹àžà¹àž­àž<p>
+"	}  
+
+_texthelpdatehowtotitle_ [l=th] {àž§àžŽàžàžµà¹àžà¹àžàžžàžàž¥àž±àžàž©àžàž°àžàžµà¹:	}  
+_texthelpdatehowto_ [l=th] {"<ul>
+   <li>à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àžà¹àžàž«àž²à¹àž­àžàžªàž²àž£à¹àžàž¢àž£àž°àžàžžàžàžµ à¹àž«à¹àžàž³à¹àžàžŽàžàžàž²àž£àžàž±àžàžàžµà¹<p>
+   <ul>
+       <li>àžàžŽàž¡àžà¹àžàž³àžàžµà¹àžàžžàžàžà¹àž­àžàžàž²àž£àžà¹àžàž«àž²àžàž²àž¡àžàžàžàžŽ
+       <li>àžàžŽàž¡àžà¹àžàžµàžàžµà¹àžàžžàžàžà¹àž­àžàžàž²àž£àž¥àžà¹àžàžàž¥à¹àž­àž "àž§àž±àžàžàžµà¹à¹àž£àžŽà¹àž¡àžà¹àž (àž«àž£àž·àž­à¹àžàžàž²àž°àžàžµà¹àž£àž°àžàžž)"
+       <li>àž«àž²àžàžàžµàžàžµà¹àžà¹àž­àžàžàž²àž£àžà¹àžàž«àž²à¹àžà¹àžàžàžµàžà¹àž­àžàžàž£àžŽàžªàžàžšàž±àžàž£àž²àž à¹àž«à¹à¹àž¥àž·àž­àžàžàž±àž§à¹àž¥àž·àž­àž "B.C.E" àžàž²àžà¹àž¡àžàž¹àžàž¶àžàž¥àžàž«àžà¹àž²àžàž¥à¹àž­àžàž§àž±àžàžàžµà¹
+       <li>à¹àž£àžŽà¹àž¡àžà¹àžàžàž²àž£àžà¹àžàž«àž²àžàž­àžàžàžžàžàžàž²àž¡àžàžàžàžŽ
+   </ul>
+<p><li>à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àžà¹àžàž«àž²à¹àž­àžàžªàž²àž£àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àžàž£àž°àž¢àž°à¹àž§àž¥àž² àž«àž£àž·àž­àžà¹àž§àžàžàžµ à¹àž«à¹àžàž³à¹àžàžŽàžàžàž²àž£àžàž±àžàžàžµà¹<p>
+   <ul>
+       <li>àžàžŽàž¡àžà¹àžàž³àžàžµà¹àžàžžàžàžà¹àž­àžàžàž²àž£àžà¹àžàž«àž²àžàž²àž¡àžàžàžàžŽ
+       <li>àžàžŽàž¡àžà¹àž§àž±àžàžàžµà¹à¹àž£àžŽà¹àž¡àžà¹àžàž¥àžà¹àžàžàž¥à¹àž­àž "àž§àž±àžàžàžµà¹à¹àž£àžŽà¹àž¡àžà¹àž (àž«àž£àž·àž­à¹àžàžàž²àž°àžàžµà¹àž£àž°àžàžž)"
+       <li>àžàžŽàž¡àžà¹àž§àž±àžàžàžµà¹àžªàžžàžàžà¹àž²àž¢àžàž¥à¹àž­àž "àž§àž±àžàžàžµà¹àžªàžŽà¹àžàžªàžžàž"
+       <li>à¹àž¥àž·àž­àžàžàž±àž§à¹àž¥àž·àž­àž "B.C.E" àžàž²àžà¹àž¡àžàž¹àžàž¶àžàž¥àžàž«àžà¹àž²àž§àž±àžàžàžµà¹à¹àžà¹ àžà¹àž­àžàžàžµàžàž£àžŽàžªàžàžšàž±àžàž£àž²àž
+       <li>à¹àž£àžŽà¹àž¡àžà¹àžàžàž²àž£àžà¹àžàž«àž²àžàž­àžàžàžžàžàžàž²àž¡àžàžàžàžŽ
+   </ul>    
+</ul><p>
+"	}  
+
+_texthelpdateresultstitle_ [l=th] {àž§àžŽàžàžµàžàžµà¹àžàž¥àžàž²àž£àžà¹àžàž«àž²àžàž­àžàžàžžàžàžàž³àžàž²àž	}  
+_texthelpdateresults_ [l=th] {"à¹àžàž¢àžàž±à¹àž§à¹àžà¹àž¥à¹àž§ àžàž²àž£àžà¹àžàž«àž²à¹àž­àžàžªàž²àž£à¹àžàžà¹àž§àžàžàžµ 1903 àžàž°à¹àž¡à¹à¹àžà¹àžàžàž²àž£àžà¹àžàžàž·àžà¹àž­àžàžªàž²àž£àžàž±àžàžàžµà¹àžàž¥à¹àž²àž§à¹àžà¹àž§à¹àž²à¹àžà¹àžàžàž²àž£àžà¹àžàžàž·àžà¹àž­àžàžªàž²àž£ à¹àžà¹àž àž«àžàž±àžàžªàž·àž­àž­à¹àž²àžàž­àžŽàžàžàžµà¹à¹àžàžµàž¢àžàžàž¶à¹àžà¹àžàžàžµ 1903 à¹àžà¹àž£àž°àžàžàžàž°à¹àžªàžàžàž£àž²àž¢àžàž²àž£à¹àž­àžàžªàž²àž£àžàž±à¹àžàž«àž¡àžàžàžµà¹àž¡àžµàžàž§àž²àž¡àžªàž±àž¡àžàž±àžàžà¹àžàž±àžàžàžµ 1903 àž­àž¢à¹àž²àžà¹àž£àžà¹àžàž²àž¡ àž§àžŽàžàžµàžàžµà¹àžà¹àžàžàž·àžàžàž²àž¡àž§àž±àžàžàžµà¹àžàž­àžà¹àž­àžàžªàž²àž£àžàž±à¹àž àž£àž°àžàžàžàž°à¹àžªàžàžàž£àž²àž¢àžàž²àž£à¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžµàžà¹àž§àžàžàž­àžàž§àž±àžàžàžµà¹àžàž£àž­àžàžàž¥àžžàž¡àžàžµ 1903 (à¹àžà¹àž 1899-1911) àžàž­àžàžàž²àžàžàžµà¹àž¢àž±àžàžàž£àž­àžàžàž¥àžžàž¡àžàž¶àžà¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžµàžà¹àž­àžàž§àž²àž¡àž£àž°àžàžžàžàž¶àžàžà¹àž§àžàžšàžàž§àž£àž£àž©àžàž­àžàžàžµ 1903 àžà¹àž§àž¢ (àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž àžšàžàž§àž£àž£àž©àžàžµà¹ 20 àž«àž£àž·àž­ àžšàžàž§àž£àž£àž©àžàžµà¹ 21)  àžàž¶à¹àžàž«àž¡àž²àž¢àžàž§àž²àž¡àž§à¹àž² àžªàž³àž«àž£àž±àžà¹àž­àžàžªàž²àž£àžàž²àžàžàžàž±àž àž§àž±àžàžàžµà¹àžàžµà¹àžàžžàžàžà¹àžàž«àž²àž­àž²àžàžàž°à¹àž¡à¹àžàž£àž²àžàžàž­àž¢àž¹à¹à¹àžà¹àžàž·à¹àž­àž«àž²àžàž­àžà¹àž­àžàžªàž²àž£  àžªàž³àž«àž£àž±àžàžàž²àž£àžà¹àžàž«àž²àžàž²àž¡àžà¹àž§àžà¹àž§àž¥àž² àžà¹àž­àžàž§àž²àž¡àžàžµà¹àžàž¥à¹àž²àž§àž¡àž²à¹àžàž·à¹àž­àžàžà¹àžàžàž°àžàž£àž­àžàžàž¥àžžàž¡àž§àž±àžàžàžµà¹àžàž±à¹àžàž«àž¡àžà¹àžàžà¹àž§àžà¹àž§àž¥àž²àžàžµà¹àžàž³àž«àžàž<p>
+"	}  
+
+_textchangeprefs_ [l=th] {àžàž²àž£à¹àžàž¥àžµà¹àž¢àžàžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°àžàž­àžàžàžžàž	}  
+
+_texthelppreferences_ [l=th] {"<p>à¹àž¡àž·à¹àž­àžàžžàžàžàž¥àžŽàžàžàžžà¹àž¡ <i>_Global:linktextPREFERENCES_</i> àžàžµà¹àžªà¹àž§àžàžàžàžªàžžàžàžàž­àžàž«àžà¹àž²à¹àž¥à¹àž§ 
+àžàžžàžàžàž°àžªàž²àž¡àž²àž£àžà¹àžàž¥àžµà¹àž¢àžàžàžžàžàž¥àž±àžàž©àžàž°àžàž²àžàž­àž¢à¹àž²àžàžàž­àžàžªà¹àž§àžàžàžŽàžàžà¹àž­àžàž±àžàžàž¹à¹à¹àžà¹à¹àžàž·à¹àž­à¹àž«à¹àžàž£àžàžàž±àžàžàž§àž²àž¡àžà¹àž­àžàžàž²àž£àžàž­àžàžàžžàžà¹àžà¹
+"	}  
+
+_texthelpcollectionprefstitle_ [l=th] {àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°àžàž­àž¥à¹àž¥àžàžàž±àž	}  
+_texthelpcollectionprefs_ [l=th] {"<p>àžàž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž£àž°àžàž­àžàžà¹àž§àž¢àžàž­àž¥à¹àž¥àžàžàž±àžàž¢à¹àž­àž¢àž«àž¥àž²àž¢àžàž­àž¥à¹àž¥àžàžàž±àž àžàž¶à¹àžàžàž¹à¹à¹àžà¹àžªàž²àž¡àž²àž£àžàžà¹àžàž«àž²àž àž²àž¢à¹àžà¹àžàž­àž¥à¹àž¥àžàžàž±àžàž¢à¹àž­àž¢
+à¹àžàžà¹àžà¹àžàž­àžŽàžªàž£àž°àžàž²àžàžàž±àžàž«àž£àž·àž­àž£àž§àž¡àžàž±àžà¹àžà¹ àžà¹àž²à¹àžà¹àžà¹àžà¹àžàžàž±à¹àž àžàžžàžàžªàž²àž¡àž²àž£àžà¹àž¥àž·àž­àžà¹àžà¹àž§à¹àž²
+àžàžžàžàžà¹àž­àžàžàž²àž£àžà¹àžàž«àž²àž àž²àž¢à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàž¢à¹àž­àž¢à¹àžàžà¹àž²àžà¹àžàž¢àžàž²àž£àžàž³àž«àžàžàžà¹àž²à¹àžàž«àžà¹àž²àžàž³àž«àžàžàž¥àž±àžàž©àžàž°
+"	}  
+
+_texthelplanguageprefstitle_ [l=th] {àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°àž àž²àž©àž²	}  
+_texthelplanguageprefs_ [l=th] {"<p>àžàž­àž¥à¹àž¥àžàžàž±àžà¹àžà¹àž¥àž°àžàžžàžàžàž°à¹àžà¹àž àž²àž©àž²à¹àžàžàž²àž£àžàž³à¹àžªàžàž­à¹àž£àžŽà¹àž¡àžà¹àž  à¹àžà¹àžàžžàžàžªàž²àž¡àž²àž£àžàžªàž¥àž±àžà¹àžà¹àžà¹àž àž²àž©àž²àž­àž·à¹àžà¹àžà¹àžà¹àž²àžàžžàžàžà¹àž­àžàžàž²àž£
+àžàž­àžàžàž²àžàžàžµà¹ àžàžžàžàž¢àž±àžàžªàž²àž¡àž²àž£àžàžàž£àž±àžà¹àžàž¥àžµà¹àž¢àžàžàžžàžàž£àž¹àžà¹àžàžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàžµà¹à¹àžà¹à¹àžàž¢à¹àžàž£à¹àžàž£àž¡ Greenstone àžªàž³àž«àž£àž±àžàžàž¥àž¥àž±àžàžà¹àžàžµà¹àžªà¹àžà¹àžàž¢àž±àžà¹àžàž£àž²àž§à¹àžàž­àž£à¹à¹àžà¹àžà¹àž§àž¢ à¹àžàž¢
+àžàž­àžàžà¹à¹àž§àž£à¹àžàž°à¹àž¥àž·àž­àžàžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžàžàžµà¹à¹àž«àž¡àž²àž°àžªàž¡ à¹àžà¹àžªàž³àž«àž£àž±àžà¹àžàž£àž²àž§à¹àžàž­àž£à¹àžàž²àžàžàž±àž§ à¹àž£àž²àžàž³à¹àžà¹àžàžà¹àž­àžàžªàž¥àž±àžà¹àžà¹àžà¹àžàžžàžàž£àž¹àžà¹àžàžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàžžàžàž­àž·à¹àž
+à¹àžàž·à¹àž­à¹àž«à¹àž¡àž±à¹àžà¹àžàž§à¹àž²àž£àž°àžàžàžàž°à¹àžªàžàžàž­àž±àžàžàž£àž°àž­àž­àžàž¡àž²àž­àž¢à¹àž²àžàžàž¹àžàžà¹àž­àž
+àžàž­àž¥à¹àž¥àžàžàž±àžàžàž±à¹àžàž«àž¡àžàžàž°àž­àžàžžàžàž²àžà¹àž«à¹àžàžžàžàžªàž¥àž±àžàž£àž¹àžà¹àžàžàžªà¹àž§àžàžàžŽàžàžà¹àž­àžàž¹à¹à¹àžà¹à¹àžàžàžàž£àž²àžàžŽàžàž¡àž²àžàž£àžàž²àžà¹àžà¹àžà¹àžà¹àžàžàžà¹àž­àžàž§àž²àž¡à¹àžà¹
+àž¥àž±àžàž©àžàž°àžàžµà¹àžàž°à¹àžà¹àžàžàž£àž°à¹àž¢àžàžà¹àž­àž¢à¹àž²àžàž¡àž²àžàžà¹àž­àžàž¹à¹àž¡àžµàžàž±àžàž«àž²àžàž²àžàžªàž²àž¢àžàž²àžàžµà¹à¹àžà¹à¹àžàžàž­àž±àžàž©àž£àžàžàž«àžà¹àž²àžàž­àžàžàž²àžà¹àž«àžà¹ àž«àž£àž·àž­àžà¹àž­àžàžàž²àž£àžªà¹àžàžàž¥àž¥àž±àžàžà¹à¹àžàž¢àž±àžà¹àžàž£à¹àžàž£àž¡àžªàž±àžà¹àžàž£àž²àž°àž«à¹à¹àžªàžµàž¢àžàžàž¹àž
+"	}  
+
+_texthelppresentationprefstitle_ [l=th] {àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°àžàž²àž£àžàž³à¹àžªàžàž­	}  
+_texthelppresentationprefs_ [l=th] {àžàž¶à¹àžàž­àž¢àž¹à¹àžàž±àžàžàž²àžàžàž­àž¥à¹àž¥àžàžàž±àž àž­àž²àžàžàž°àž¡àžµàžàž±àž§à¹àž¥àž·àž­àžàž«àž¥àž²àž¢àžàž±àž§àžàžµà¹àžàžžàžàžªàž²àž¡àž²àž£àžàžàž±à¹àžàžà¹àž²à¹àžàž·à¹àž­àžàž§àžàžàžžàž¡àž£àž¹àžà¹àžàžàžàž²àž£àžàž³à¹àžªàžàž­à¹àžà¹
+
+<p>àžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàž«àžà¹àž²à¹àž§à¹àžàž­àžàžžàžàž²àžà¹àž«à¹àžàžžàžàžàžŽàžà¹àžàžàžàž³àžàž²àž Greenstone àžàžµà¹àžªà¹àž§àžàžàžàžªàžžàžàžàž­àžàž«àžà¹àž²
+à¹àž­àžàžªàž²àž£à¹àžà¹àž¥àž°àž«àžà¹àž²à¹àžà¹ à¹àžàž·à¹àž­àžàžµà¹àž§à¹àž²àžàž±àžàžàžµàžàžµà¹àžàžžàžàžàž³à¹àžàžŽàžàžàž²àž£àžà¹àžàž«àž²à¹àžªàž£à¹àžàžªàžŽà¹àž àžàžžàžàžàž°à¹àžà¹à¹àžàž¢àž±àžàž«àžà¹àž²à¹àž§à¹àžàžàžµà¹àžàž£àžàžàž±àžàžàž²àž£àžà¹àžàž«àž²à¹àžàž¢à¹àž¡à¹àž¡àžµàžªà¹àž§àžàž«àž±àž§àžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone
+à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àžà¹àžàž«àž²àžàž£àž±à¹àžàžà¹àž­à¹àž àžàžžàžàžàž°àžà¹àž­àžà¹àžà¹àžàžžà¹àž¡ "àž¢à¹àž­àžàžàž¥àž±àž" à¹àžà¹àžàž£àž²àž§à¹àžàž­àž£à¹àžàž­àžàžàžžàž
+àžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¥à¹àž²àžàžµà¹àž­àžàžžàžàž²àžà¹àž«à¹àžàžžàžàžàžŽàžàžà¹àž­àžàž§àž²àž¡à¹àžàž·àž­àžàžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone à¹àž¡àž·à¹àž­àžàžžàžàžàž¥àžŽàžàžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àž
+àžàžµà¹àžàž°àžàž²àžàžžàžàž­àž­àžàžàž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥ à¹àž¥àž°à¹àžàž¢àž±àžàž«àžà¹àž²à¹àž§à¹àžàžàž±à¹àžà¹àžà¹
+à¹àž¥àž°à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž§à¹àžàžàž²àžàžàž­àž¥à¹àž¥àžàžàž±àž àžàžžàžàž¢àž±àžàžªàž²àž¡àž²àž£àžàžàž§àžàžàžžàž¡àž­àžµàžà¹àžà¹àž§à¹àž² àžà¹àž­àžàžàž²àž£à¹àž«à¹àžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàžàžàž«àžà¹àž² "àžàž¥àžàž²àž£àžà¹àžàž«àž²" 
+àžàž³àžàžžàžà¹àžàž¢àž±àž URL àžàžµà¹à¹àžà¹àžàž£àžŽàžàžàž­àžàžàž³àžàž²àž¡ à¹àžàžàžàžµà¹àžàž°à¹àžàž·à¹àž­àž¡à¹àž¢àžà¹àžàž¢àž±àžàžªàž³à¹àžàž²àžàž­àžàž«àžà¹àž²àžàž±à¹àžà¹àžàž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥
+}  
+
+_texthelpsearchprefstitle_ [l=th] {àžàž²àž£àžàž³àž«àžàžàž¥àž±àžàž©àžàž°àžàž²àž£àžà¹àžàž«àž²	}  
+_texthelpsearchprefs_ [l=th] {"<p>àžàžžàžàžªàž²àž¡àž²àž£àžàžªàž¥àž±àžà¹àžàž¢àž±àžà¹àž«àž¡àžàžàž²àž£àžà¹àžàž«àž² "àž­àž¢à¹àž²àžàž¥àž°à¹àž­àžµàž¢àž" àžàžµà¹àž­àžàžžàžàž²àžà¹àž«à¹àžàžžàžàžàž³àžàž³àž¡àž²àžàž£àž°àžàž­àžàžàž±àžà¹àžàž¢à¹àžà¹ & (à¹àžàž "à¹àž¥àž°") | (à¹àžàž "àž«àž£àž·àž­") à¹àž¥àž° ! (à¹àžàž "à¹àž¡à¹") 
+à¹àž¥àž°à¹àžà¹àž§àžà¹àž¥à¹àžà¹àžàžàž²àž£àžàž±àžàžàž¥àžžà¹àž¡àžàž²àž¡àžà¹àž­àžàžàž²àž£à¹àžà¹  àžàž¶à¹àžàžà¹àž§àž¢à¹àž«à¹àžàžžàžàžªàž²àž¡àž²àž£àžàž£àž°àžàžžàžàž²àž£àžà¹àžàž«àž²à¹àžà¹à¹àž¡à¹àžàž¢àž³àžàž¶à¹àž 
+<p>_selectsearchtypeprefs_
+<p>_selectwordmodificationprefs_
+<p>àžàžžàžàžªàž²àž¡àž²àž£àžà¹àžàžŽàžàžàžžàžàž¥àž±àžàž©àžàž°àžàž£àž°àž§àž±àžàžŽàžàž²àž£àžà¹àžàž«àž² àžàž¶à¹àžàžàž°à¹àžªàžàžàžàž³àžà¹àžàž¥à¹àž²àžªàžžàžàžàž­àžàžàžžàžà¹àžà¹  
+àžàžžàžàž¥àž±àžàž©àžàž°àžàžµà¹àžàž°àžà¹àž§àž¢à¹àž«à¹àžà¹àž²àž¢àžà¹àž­àžàž²àž£à¹àž£àžµàž¢àžà¹àžà¹àžàž³àžà¹àžàžà¹àž­àžàž«àžà¹àž²àžàžµà¹àž¡àžµàžàž²àž£à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àžà¹àžàžµàž¢àžà¹àž¥à¹àžàžà¹àž­àž¢àžà¹àž³àž­àžµàž 
+<p>àžàž­àžàžàž²àžàžàžµà¹ àžàžžàžàž¢àž±àžàžªàž²àž¡àž²àž£àžàžàž§àžàžàžžàž¡àžàž³àžàž§àžàžàž¥àž¥àž±àžàžà¹àžàžµà¹à¹àžà¹ à¹àž¥àž°àžàž³àžàž§àžàž£àž²àž¢àžàž²àž£àžàžµà¹àžàž°à¹àžªàžàžàžàžàž«àžà¹àž²àžàž­à¹àžà¹àž­àžµàžàžà¹àž§àž¢
+"	}  
+
+_textcasefoldprefs_ [l=th] {"àžàžžà¹àž¡àžàž¹à¹àžàžµà¹àžàž°àžàž³àž«àžà¹àž²àžàžµà¹àžàž§àžàžàžžàž¡àž§à¹àž² àž£àž°àžàžàžàž°àžàž³àžàž²àž£àžà¹àžàž«àž²à¹àžàž¢à¹àž¡à¹àžàž³àžàž¶àžàžàž¶àžàžàž±àž§àžàžŽàž¡àžà¹à¹àž«àžà¹à¹àž¥àž°àžàž±àž§àžàžŽàž¡àžà¹à¹àž¥à¹àžàž«àž£àž·àž­à¹àž¡à¹ àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž àžà¹àž²à¹àž¥àž·àž­àž "_preferences:textignorecase_" à¹àž¥à¹àž§ àžàž³àž§à¹àž² <i>snail farming</i> àžàž°àž¡àžµàžà¹àž²à¹àžàžµàž¢àžà¹àžà¹àž²àžàž±àž <i>Snail Farming</i> à¹àž¥àž° <i>SNAIL FARMING</i> àžà¹àž§àž¢"	}  
+_textstemprefs_ [l=th] {"àžàžžà¹àž¡àžàž¹à¹àžàžµà¹àžàž°àžàž³àž«àžà¹àž²àžàžµà¹àžàž§àžàžàžžàž¡àž§à¹àž² àž£àž°àžàžàžàž°àž¥àž°à¹àž§à¹àžàž­àž±àžàžàž£àž°àžà¹àž²àž¢àžàž³àžàžàž°àžà¹àžàž«àž²àž«àž£àž·àž­à¹àž¡à¹  àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž àžà¹àž²à¹àž¥àž·àž­àž "_preferences:textstem_" à¹àž¥à¹àž§ <i>snail farming</i> àžàž°àž¡àžµàžà¹àž²à¹àžàžµàž¢àžà¹àžà¹àž²àžàž±àž <i>snails farm</i> and <i>snail farmer</i>  àžàžžàžàž¥àž±àžàž©àžàž°àžàžµà¹àžàž°àžàž³àžàž²àžàž­àž¢à¹àž²àžàžàž¹àžàžà¹àž­àžàžàž±àžàžà¹àž­àžàž§àž²àž¡àž àž²àž©àž²àž­àž±àžàžàž€àž©à¹àžà¹àž²àžàž±à¹àž _selectstemoptionsprefs_"	}  
+_textaccentfoldprefs_ [l=th] {"àžàžžà¹àž¡àžàž¹à¹àžàžµà¹àžàž°àžàž³àž«àžà¹àž²àžàžµà¹àžàž§àžàžàžžàž¡àž§à¹àž² àž£àž°àžàžàžàž°àžàž³àžàž²àž£àžà¹àžàž«àž²àžàž±àž§àž­àž±àžàž©àž£àžàžµà¹àž¡àžµàžàž²àž£à¹àžà¹àžà¹àžªàžµàž¢àžà¹àž¥àž°à¹àž¡à¹à¹àžà¹àžà¹àžªàžµàž¢àžàž«àž£àž·àž­à¹àž¡à¹  àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž àžà¹àž²à¹àž¥àž·àž­àž "_preferences:textignoreaccents_" à¹àž¥à¹àž§ <i>fÃ©dÃ©ration</i> àžàž°àž¡àžµàžà¹àž²à¹àžàžµàž¢àžà¹àžà¹àž²àžàž±àž <i>fedÃ©ration</i> à¹àž¥àž° <i>federation</i>"	}  
+ 
+_textstemoptionsprefs_ [l=th] {"àžàž°à¹àžà¹àžàžàž²àž£àžªàž°àžàž§àžà¹àž¥àž°à¹àž¡à¹àžàž¢àž³àž¡àž²àžàžàž¶à¹àžàž«àž²àžàžàžžàžà¹àžà¹àžàž±àž§àžàž±àžàžàž³àžà¹àžàžàžµà¹àžàž£àž£àž¢àž²àž¢à¹àž§à¹àžà¹àž²àžàžàžà¹àž "_texthelpquerytermstitle_""	}  
+
+_textsearchtypeprefsplain_ [l=th] {àžàžžàžàžªàž²àž¡àž²àž£àžà¹àžà¹àžàž¥à¹àž­àžàžà¹àžàž«àž²àžàžàž²àžà¹àž«àžà¹ à¹àžàž·à¹àž­à¹àž«à¹àžªàž²àž¡àž²àž£àžàžàž³àžàž²àž£àžà¹àžàž«àž²àžàž£àž°à¹àž¢àžàžàžµà¹àž¢àž²àž§àž¡àž²àžà¹ à¹àžà¹  àžàž¶à¹àžàž£àž°àžàžàžªàž²àž¡àž²àž£àžàžà¹àžàž«àž²àžà¹àž­àžàž§àž²àž¡àžàžµà¹àž¡àžµàžàžàž²àžàž¢àž²àž§à¹àžà¹àž­àž¢à¹àž²àžàž£àž§àžà¹àž£à¹àž§àžàžàžà¹àž²à¹àžàž¥àžà¹àž	}  
+
+_textsearchtypeprefsform_ [l=th] {àžàžžàžàžªàž²àž¡àž²àž£àžà¹àžàž¥àžµà¹àž¢àžàžàž³àžàž§àžà¹àžàžàžà¹àž­àž¡àž¹àž¥àžàžµà¹à¹àžªàžàžà¹àžà¹àžàžàžàž­àž£à¹àž¡àžàž²àž£àžà¹àžàž«àž²à¹àžà¹	}  
+
+_textsearchtypeprefsboth_ [l=th] {"àžàžžàžàžªàž²àž¡àž²àž£àžàžªàž¥àž±àžàžàžàžŽàžàžàž­àžàžàž²àž£àžà¹àžàž«àž²àžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àžàž£àž°àž«àž§à¹àž²àžàžàž²àž£àžà¹àžàž«àž²à¹àžàž "àžàžàžàžŽ" à¹àž¥àž°à¹àžàžàž£àž°àžàžž "à¹àžàžàžà¹àž­àž¡àž¹àž¥" à¹àžà¹ 
+<ul>
+<li>àžàž²àž£àžà¹àžàž«àž²à¹àžàžàžàžàžàžŽ àž£àž°àžàžàžàž°à¹àžªàžàžàžàž¥à¹àž­àžàžà¹àžàž«àž²à¹àžàžµàž¢àžàžàž¥à¹àž­àžà¹àžàžµàž¢àž§ _textsearchtypeprefsplain_</li>
+<li>àžàž²àž£àžà¹àžàž«àž²à¹àžàžàž£àž°àžàžžà¹àžàžàžà¹àž­àž¡àž¹àž¥ àž£àž°àžàžàžàž°à¹àžªàžàžàžàž¥à¹àž­àžàžà¹àžàž«àž²àžàž³àžàž§àžàž«àžàž¶à¹àž à¹àžàž¢à¹àžà¹àž¥àž°àžàž¥à¹àž­àžàžàž°àžàž³àžàž²àž£àžà¹àžàž«àž²àžà¹àž­àž¡àž¹àž¥à¹àžà¹àžàžàžà¹àž­àž¡àž¹àž¥àžàž­àžàžàž±àžàžàžµàžàžµà¹à¹àžàžàžà¹àž²àžàžàž±àž àžàž¶à¹àžàžàž°àžà¹àž§àž¢à¹àž«à¹àžªàž²àž¡àž²àž£àžàžà¹àžàž«àž²àžà¹àž²àž¡à¹àžàžàžà¹àž­àž¡àž¹àž¥àžàžµà¹à¹àžàžàžà¹àž²àžàžàž±àžà¹àžà¹à¹àžàžàž£àž²àž§à¹àžàžµàž¢àž§ _textsearchtypeprefsform_ </li>
+</ul>
+"	}  
+
+
+
+_texttanumbrowseoptions_ [l=th] {àžàžžàžàžªàž²àž¡àž²àž£àžàžà¹àžàž«àž²àžà¹àž­àž¡àž¹àž¥à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹à¹àžà¹ _numbrowseoptions_ àž§àžŽàžàžµàžàž±àžàžàžµà¹	}  
+
+_textsimplehelpheading_ [l=th] {àž§àžŽàžàžµàžàž²àž£àžà¹àžàž«àž²àžà¹àž­àž¡àž¹àž¥à¹àžàžàž­àž¥à¹àž¥àžàžàž±àž _collectionname_	}  
+
+_texthelpscopetitle_ [l=th] {àžàž­àžà¹àžàžàžàž­àžàžàž²àž£àžà¹àžàž«àž²	}  
+_texthelpscope_ [l=th] {"<p>
+à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžªà¹àž§àžà¹àž«àžà¹ àžàžžàžàžàž°àž¡àžµàžàž±àž§à¹àž¥àž·àž­àžàžàž­àžàžàž±àžàžàžµàžàžµà¹à¹àžà¹à¹àžàžàž²àž£àžà¹àžàž«àž²àžàžµà¹à¹àžàžàžà¹àž²àžàžàž±àž
+àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž àžàž¹à¹à¹àžàžµàž¢àž àž«àž£àž·àž­àžàž±àžàžàžµàžàž·à¹àž­à¹àž£àž·à¹àž­àž  àž«àž£àž·àž­àž­àž²àžàžàž°à¹àžà¹àžàžàž±àžàžàžµàžàž·à¹àž­àžàž àž«àž£àž·àž­àžàž±àžàžàžµàž¢à¹àž­àž«àžà¹àž²
+à¹àžàž¢àžàž±à¹àž§à¹àžà¹àž¥à¹àž§ à¹àž­àžàžªàž²àž£àžàžµà¹àžàž£àžàžàž±àžàžàž²àž£àžà¹àžàž«àž²àžàž±à¹àžàž«àž¡àžàžàž°à¹àžªàžàžàžàž¶à¹àžà¹àž¡à¹àž§à¹àž²àžàžžàžàžàž°àžà¹àžàž«àž²àžà¹àž§àž¢àžàž±àžàžàžµà¹àž
+<p>àžà¹àž²à¹àž­àžàžªàž²àž£à¹àžà¹àžàž«àžàž±àžàžªàž·àž­ à¹àž­àžàžªàž²àž£à¹àž«àž¥à¹àž²àžàž±à¹àžàžàž°àžàž¹àžà¹àžàžŽàžàžà¹àž§àž¢à¹àžàž£à¹àžàž£àž¡àžàžµà¹à¹àž«àž¡àž²àž°àžªàž¡
+"	}  
Index: /gsdl/stable/macros/thai2.dm
===================================================================
--- /gsdl/stable/macros/thai2.dm	(revision 20131)
+++ /gsdl/stable/macros/thai2.dm	(revision 20131)
@@ -0,0 +1,1004 @@
+# this file must be UTF-8 encoded
+
+############################################################################
+#
+# This stuff is only used by the usability (I'd like to Complain) stuff
+#
+############################################################################
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=th] {à¹àž­àžàžªàž²àž£}  
+_lastupdate_ [l=th] {àžàž£àž±àžàžàž£àžžàžàžàž£àž±à¹àžàž¥à¹àž²àžªàžžàž}  
+_ago_ [l=th] {àž§àž±àžàžà¹àž­àž}  
+_colnotbuilt_ [l=th] {à¹àž¡à¹àž¡àžµàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àž}  
+
+### taken from here
+
+_textpoem_ [l=th] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>àžàž­à¹àž«à¹àžªàž±àžàžàžŽàž àž²àžà¹àž¥àž°àžàž§àž²àž¡àžªàžàžàžªàžžàžàžàžàž­àž¢àž¹à¹àž£àž²àž¢àž£àž­àžàžàž±àž§àžàžžàž
+<br>àžàž­à¹àž«à¹àžàžžàžà¹àžà¹àžàž±àžàžàž²àž¢àž­àž¢àž¹à¹àžà¹àž²àž¡àžàž¥àž²àžàžàž§àž²àž¡àž­àžàž­àžžà¹àžàžàž­àžà¹àž¡àžàž«àž¡àž­àžà¹àž«à¹àžàž€àžàž¹àž£à¹àž­àž
+<br>àžàž­à¹àž«à¹àž¡àž«àž²àžªàž¡àžžàžàž£à¹àž«à¹àžàžàž²àž£à¹àžàžŽàžàžàž²àžàžàž­àžàžàžžàžàžàžàž£àž²àžàž£àž·à¹àžà¹àžà¹àžà¹àžàžµàž¢àž§àžàž±àžàž«àžŽàžàžªàžµà¹àžàžµàž¢àž§àžàžµà¹à¹àžà¹àž£àž±àžàžàž²àž£à¹àžàžµàž¢àž£àž°à¹àžà¹àž¥à¹àž§
+}  
+
+_textgreenstone_ [l=th] {<p>Greenstone à¹àžà¹àžàž«àžŽàžàžàž¶à¹àžàž£àž±àžàžàžàž²àžàžŽàžàžµà¹àžà¹àžàžàžà¹àžàžàž£àž°à¹àžàžšàžàžŽàž§àžàžµà¹àž¥àžàžà¹ (à¹àž«àž¡àž·àž­àžàžàž±àžàžàž­àžàžà¹à¹àž§àž£à¹àžàžµà¹)
+à¹àžàžªàž±àžàžàž¡àžàž­àžàžàžà¹àžà¹àž²à¹àž¡àž²àž£àžµà¹àžàž£àž²àž àž«àžŽàžàžàžàžŽàžàžàžµà¹àžàž·àž­à¹àžà¹àžàžªàžŽà¹àžàž¡àžµàžà¹àž²àžªàž¹àžàžªàžžàž à¹àž¥àž°à¹àžà¹àžàžàž±àž§à¹àž«à¹àžàž³à¹àžàžŽàžàžªàžªàž²àž£àž­àž·à¹àžà¹
+àž«àžŽàžàžàžµà¹àžªàž²àž¡àž²àž£àžàžàž¹àžàžàž±àžà¹àž¥àž°àžàž±àž <i>wairua</i> àžàž¶à¹àžàžà¹àžàž·àž­ àžàžŽàžàž§àžŽàžàžàž²àžàž«àž£àž·àž­àžàž¥àž±àžàžàžµàž§àžŽàžà¹àžà¹
+à¹àž¥àž°àž¡àžµàžàžžàžàžªàž¡àžàž±àžàžŽàžà¹àž²àžàžàž§àž²àž¡àžàž¥àž±àžàžšàž±àžàžàžŽà¹àžªàžŽàžàžàžŽà¹ àžàž¶àžàžàž³à¹àž«à¹à¹àž«àž¡àž²àž°àžªàž¡àžàžµà¹àžàž°à¹àžà¹àžà¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàž­àž
+à¹àžàž£àžàžàž²àž£àž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥àžàžµà¹à¹àžà¹àžàžªàž²àžàž²àž£àžàž°
+àž¥àž±àžàž©àžàž°àž­àž±àžà¹àž§àž§àž§àž±àžàžàž­àžàž«àžŽàžàžàžàžŽàžàžàžµà¹à¹àžªàžàžàžàž¶àžàžàž§àž²àž¡à¹àž­àž·à¹àž­à¹àžàž·à¹àž­à¹àžàž·à¹àž­à¹àžà¹ àž¥àž±àžàž©àžàž°àžàž­àžàžàž§àž²àž¡à¹àžàž£à¹àžà¹àžªàžà¹àžªàžàžàžàž¶àžàžàž§àž²àž¡àžàž·à¹àž­àžªàž±àžàž¢à¹
+àž¥àž±àžàž©àžàž°àžàžàžàž²àžà¹àžªàžàžàžàž¶àžàžàž³àž¥àž±àžà¹àž à¹àž¥àž°àžàž­àžàžàž±àžàžàž¡à¹àžªàžàžàžàž¶àžàžàž§àž²àž¡àž¢àžžàžàžŽàžàž£àž£àž¡
+àžàžŽà¹àžàžªà¹àž§àžà¹àžàž°àžªàž¥àž±àžàžàžµà¹à¹àžà¹à¹àžà¹àžàžªàž±àžàž¥àž±àžàž©àžà¹àžàž­àžàžàž­àžàžà¹à¹àž§àž£à¹àž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥ Greenstone àžàžµà¹à¹àžà¹àž
+<i>patu</i> àž«àž£àž·àž­àžàžàž²àžªàž³àž«àž£àž±àžàžà¹àž­àžªàž¹à¹ à¹àž¥àž°à¹àžà¹àžàž¡àž£àžàžàžàžàžàž­àžàž¡àž²àžàž¶àžàž«àžàž¶à¹àžà¹àžàžªàž¡àž²àžàžŽàžà¹àžàž£àžàžàž²àž£àžàž­àžà¹àž£àž²
+à¹àž¡àž·à¹àž­à¹àžàžŽàžàžàž²àž£àžàž£àž°àžàžŽàžàžàž±àž§ àžàž²àž£àžàž­àžà¹àžà¹àžàž³à¹àžà¹àžàžà¹àž­àžàž£àž§àžà¹àž£à¹àž§ à¹àž¡à¹àžàž¢àž³à¹àž¥àž°àžªàž¡àžàž¹àž£àžà¹àž­àž¢à¹àž²àžàž¡àž²àž
+àžàž¶à¹àžà¹àž£àž²àž£àž¹à¹àžªàž¶àžàž§à¹àž²àžàžžàžàžªàž¡àžàž±àžàžŽà¹àž«àž¥à¹àž²àžàžµà¹àžªàž²àž¡àž²àž£àžà¹àžà¹à¹àžà¹àžàž±àžàžàž­àžàžà¹à¹àž§àž£à¹àžàž­àžà¹àž£àž²à¹àžà¹àžàžàž±àž àžàž­àžàžàž±àžàžàž£àžàžàžµà¹à¹àžàžµàž¢àžàžàž¡
+àžàž­àž <i>patu</i> à¹àžà¹àžàžªàž±àžàž¥àž±àžàž©àžà¹àžà¹àžàžàž­àžàžàž¶àžàžàž²àž£à¹àžà¹àžàžàž¹à¹àžàž³àžàž²àžà¹àžàžà¹àžà¹àž¥àž¢àžµ</p>
+}  
+
+_textaboutgreenstone_ [l=th] {<p>Greenstone à¹àžà¹àžàžàžžàžàžàž­àžàžàž­àžàžà¹à¹àž§àž£à¹àžàžµà¹àžà¹à¹àžàžàž²àž£àžªàž£à¹àž²àžà¹àž¥àž°à¹àžàžàžà¹àž²àž¢àžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥
+àžàž¶à¹àžà¹àžà¹àžà¹àžàž§àžàž²àžà¹àž«àž¡à¹à¹àžàžàž²àž£àžàž±àžàž£àž°à¹àžàžµàž¢àžàžà¹àž­àž¡àž¹àž¥à¹àž¥àž°à¹àžàž¢à¹àžàž£à¹à¹àžàžàžàž­àžŽàžà¹àžàž­àž£à¹à¹àžà¹àž àž«àž£àž·àž­àžàžµàžàžµàž£àž­àž¡
+à¹àžàž£à¹àžàž£àž¡ Greenstone àžàž¹àžàžªàž£à¹àž²àžàžàž¶à¹àžà¹àžàž¢<b>à¹àžàž£àžàžàž²àž£ New Zealand Digital Library </b> 
+àžàžµà¹ <b>àž¡àž«àž²àž§àžŽàžàž¢àž²àž¥àž±àž¢à¹àž§àžàž²à¹àž</b>  à¹àžàž¢àž¡àžµàžàž²àž£àžàž±àžàžàž²à¹àž¥àž°à¹àžàžàžà¹àž²àž¢àžà¹àž²àžàžàž²àž£àž£à¹àž§àž¡àž¡àž·àž­àžàž­àž<b>àž¢àž¹à¹àžàžªà¹àž</b>à¹àž¥àž°<b>àž­àžàžà¹àžàž£àžªàžŽàžàžàžŽàž¡àžàžžàž©àž¢àžàž NGO</b>
+Greenstone à¹àžà¹àžàžàž­àžàžà¹à¹àž§àž£à¹àž£àž«àž±àžªà¹àžàžŽàž àžàž¶à¹àžàžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžà¹àžà¹àžàž²àž <a href="http://greenstone.org">http://greenstone.org</a> àž àž²àž¢à¹àžà¹àž¥àžŽàžàžªàžŽàžàžàžŽà¹àžàž­àž GNU
+</p>
+
+<p>à¹àžà¹àž²àž«àž¡àž²àž¢àžàž­àžàžàž²àž£àžàž±àžàžàž²àžàž­àžàžà¹à¹àž§àž£à¹àžàžµà¹àžàž·àž­ àžàž²àž£à¹àžàžŽàžà¹àž«à¹àžàž¹à¹à¹àžà¹ à¹àžàž¢à¹àžàžàž²àž°à¹àžàž¡àž«àž²àž§àžŽàžàž¢àž²àž¥àž±àž¢ àž«à¹àž­àžàžªàž¡àžžàž à¹àž¥àž°àžªàžàž²àžàž±àžàžàžµà¹à¹àž«à¹àžàž£àžŽàžàž²àž£àžªàž²àžàž²àž£àžàž°àž­àž·à¹àžà¹ àžªàž²àž¡àž²àž£àžàžªàž£à¹àž²àžàž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥àžàž­àžàžàž±àž§à¹àž­àžà¹àžà¹  àž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥àžàž°àžà¹àž§àž¢àžàžàžŽàž£àž¹àžàž§àžŽàžàžµàžàž²àž£à¹àžàž¢à¹àžàž£à¹à¹àž¥àž°àžàž­àžàž£àž±àžàžà¹àž­àž¡àž¹àž¥à¹àžàžàžžàž¡àžàžàžàžµà¹à¹àžà¹àžàžàž¹à¹àž£à¹àž§àž¡àžàž²àžàžàž­àžàž­àžàžà¹àžàž²àž£àž¢àž¹à¹àžàžªà¹àž à¹àž¥àž°àžªàžàž²àžàž±àžàžà¹àž²àžà¹ àžàžµà¹àžàž³à¹àžàžŽàžàžàž²àž£àžà¹àž²àžàžàž²àž£àžšàž¶àžàž©àž² àž§àžŽàžàž¢àž²àžšàž²àžªàžàž£à¹ à¹àž¥àž°àž§àž±àžàžàžàž£àž£àž¡àžàž±à¹àž§à¹àž¥àž à¹àžàž¢à¹àžàžàž²àž°àž­àž¢à¹àž²àžàž¢àžŽà¹àžà¹àžàžàž£àž°à¹àžàžšàžàž³àž¥àž±àžàžàž±àžàžàž²
+à¹àž£àž²àž«àž§àž±àžàž§à¹àž²àžàž­àžàžà¹à¹àž§àž£à¹àžàžµà¹àžàž°àžà¹àž§àž¢àžàž£àž°àžàžžà¹àžà¹àž«à¹à¹àžàžŽàžàžàž²àž£àžàž³àž£àž°àžàžàž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥à¹àžà¹àžà¹àž­àž¢à¹àž²àžàž¡àžµàžàž£àž°àžªàžŽàžàžàžŽàž àž²àžà¹àžàž·à¹àž­àžàž£àž°à¹àž¢àžàžà¹à¹àžàžàž²àž£à¹àžà¹àžà¹àž­àž¡àž¹àž¥àž£à¹àž§àž¡àžàž±àžà¹àž¥àž°à¹àžàž¢à¹àžàž£à¹àžà¹àž­àž¡àž¹àž¥àžà¹àž­àžªàž²àžàž²àž£àžàžàž
+</p>
+
+<p>àžàž­àžàžà¹à¹àž§àž£à¹àžàžµà¹à¹àžà¹àž£àž±àžàžàž²àž£àžàž±àžàžàž²à¹àž¥àž°à¹àžàžàžà¹àž²àž¢à¹àžàž£àž¹àžà¹àžàžàžàž­àžàžàž§àž²àž¡àžàž¢àž²àž¢àž²àž¡à¹àžàž·à¹àž­à¹àž«à¹à¹àžàžŽàžàžàž§àž²àž¡àž£à¹àž§àž¡àž¡àž·àž­àž£àž°àž«àž§à¹àž²àžàžàž£àž°à¹àžàžšàžàžµà¹àžà¹àž­àžàž±à¹àžàžàž¶à¹àžà¹àžà¹àžàž·àž­àžàžªàžŽàžàž«àž²àžàž¡ 2543 àž£àž°àž«àž§à¹àž²àžàž­àžàžà¹àžàž£àžªàž²àž¡àžà¹àž²àž¢
+</p>
+
+<p>
+<a href="http://nzdl.org"><b>à¹àžàž£àžàžàž²àž£ New Zealand Digital Library àžàžµà¹àž¡àž«àž²àž§àžŽàžàž¢àž²àž¥àž±àž¢ Waikato</b></a>
+<br>
+àžàž­àžàžà¹à¹àž§àž£à¹ Greenstone à¹àžà¹àž£àž±àžàžàž²àž£àžàž±àžàžàž²àžà¹àž­àžàž²àžà¹àžàž£àžàžàž²àž£àžàžµà¹ à¹àž¥àž°àžàž²àž£àž£àžŽà¹àž£àžŽà¹àž¡àžàžµà¹à¹àžà¹àž£àž±àžàžàž²àž£àž£àž±àžàž£àž­àžàž­àž¢à¹àž²àžà¹àžà¹àžàžàž²àžàžàž²àž£àžàž²àž Communication Sub-Commission of the New Zealand National Commission for UNESCO à¹àžàž¢àžàž·àž­à¹àžà¹àžàžªà¹àž§àžàž«àžàž¶à¹àžàžàž­àžàžàž²àž£à¹àž«à¹àžàž§àž²àž¡àžà¹àž§àž¢à¹àž«àž¥àž·àž­àžàž­àžàž£àž±àžàžàž²àž¥àžàžŽàž§àžàžµà¹àž¥àžàžà¹àžà¹àž­à¹àžàž£à¹àžàž£àž¡àžàž­àžàž­àžàžà¹àžàž²àž£àž¢àž¹à¹àžàžªà¹àž
+</p>
+
+<p>
+<a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif" 
+class="logo"></a>
+<a href="http://www.unesco.org"><b>United Nations Educational, Scientific and Cultural Organization</b></a>
+<br>
+àžàž²àž£à¹àžàž¢à¹àžàž£à¹àžà¹àž­àž¡àž¹àž¥àžà¹àž²àžàžàž²àž£àžšàž¶àžàž©àž² àž§àžŽàžàž¢àž²àžšàž²àžªàžàž£à¹à¹àž¥àž°àž§àž±àžàžàžàž£àž£àž¡à¹àžàžàž±à¹àž§à¹àž¥àž à¹àžàž¢à¹àžàžàž²àž°àž­àž¢à¹àž²àžàž¢àžŽà¹àžà¹àžàžàž£àž°à¹àžàžšàžàž³àž¥àž±àžàžàž±àžàžàž²àžàž±à¹àž à¹àžà¹àžà¹àžà¹àž²àž«àž¡àž²àž¢àž«àž¥àž±àžàžàž­àžàž­àžàžà¹àžàž²àž£àž¢àž¹à¹àžàžªà¹àžà¹àžàž·à¹àž­àžªàžàž­àžàžà¹àž­àžàžàžŽàžàž²àžà¹àžà¹àžàž¢à¹àžàž£à¹àžà¹àž­àž¡àž¹àž¥àž£àž°àž«àž§à¹àž²àžàž£àž±àžàžªàž³àž«àž£àž±àžàžàžžàžà¹àžàž£à¹àžàž£àž¡ à¹àž¥àž°àžà¹àž­àž¡àž¹àž¥àžàžµà¹à¹àž«àž¡àž²àž°àžªàž¡à¹àž¥àž°àžªàž²àž¡àž²àž£àžà¹àžà¹àž²àžàž¶àžà¹àžà¹ àž£àž§àž¡àžàž±à¹àžà¹àžàžà¹àžà¹àž¥àž¢àžµàžà¹àž²àžàžàž²àž£àžªàž·à¹àž­àžªàž²àž£à¹àžà¹àžàž¹àžàž¡àž­àžàž§à¹àž²à¹àžà¹àžà¹àžàž£àž·à¹àž­àžàž¡àž·àž­àžàžµà¹àž¡àžµàžàž§àž²àž¡àžªàž³àžàž±àžà¹àžàžàž£àžŽàžàžàžàžµà¹
+</p>
+
+<p>
+<a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" class="logo"></a>
+<a href="http://humaninfo.org"><b>The Human Info NGO àžàž±à¹àžàž­àž¢àž¹à¹àžàžµà¹à¹àž¡àž·àž­àž Antwerp àžàž£àž°à¹àžàžšà¹àžàž¥à¹àž¢àžµà¹àž¢àž¡</b></a>
+<br>
+à¹àžàž£àžàžàž²àž£àžàžµà¹àžàž³àžàž²àžàž£à¹àž§àž¡àžàž±àžàžàž±àž§à¹àžàžàžªàž«àžàž£àž°àžàž²àžàž²àžàžŽ (UN) à¹àž¥àž°àž­àžàžà¹àžàž£à¹àž¡à¹à¹àžªàž§àžàžàž¥àžàž³à¹àž£ (à¹àž­à¹àžàžàžµà¹àž­) àž­àž·à¹àžà¹ à¹àž¥àž°à¹àž£àžŽà¹àž¡àž¡àžµàžàž·à¹àž­à¹àžªàžµàž¢àžà¹àžàžàž±à¹àž§à¹àž¥àžà¹àžàžà¹àž²àžàžàž²àž£àžàž³à¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžžà¹àžà¹àžà¹àžàžàž²àž£àžàž±àžàžàž²àž¡àžàžžàž©àž¢à¹à¹àž«à¹à¹àžà¹àžàžàžŽàžàžŽàžàž±àž¥ àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžà¹àžà¹àž­àž¢à¹àž²àžàžàž±à¹àž§àžàž¶àž à¹àž¡à¹àž¡àžµàžà¹àž²à¹àžà¹àžà¹àž²àž¢àžªàž³àž«àž£àž±àžàžàž£àž°à¹àžàžšàžàž³àž¥àž±àžàžàž±àžàžàž² à¹àž¥àž°àž­àž¢àž¹à¹àžàžàžàž·à¹àžàžàž²àžàžàž­àžàžàž²àž£àžàž·àžà¹àžàžŽàžàžªàž³àž«àž£àž±àžàžàž£àž°à¹àžàžšàž­àž·à¹àžà¹
+</p>
+}  
+
+
+_textdescrselcol_ [l=th] {à¹àž¥àž·àž­àžàžàž­àž¥à¹àž¥àžàžàž±àž}  
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=th] {àž¡àžµàžàžžà¹àž¡àž­àžµàžàžªàžµà¹àžàžžà¹àž¡àžàžàž«àžà¹àž²à¹àž£àž}  
+
+_textnocollections_ [l=th] {<p>à¹àž¡à¹àž¡àžµàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžà¹àžàžàžàž°àžàžµà¹àžàžµà¹àžªàž²àž¡àž²àž£àžà¹àž£àžµàžà¹àžà¹àžàž²àžà¹àžà¹àžàž±àžàžàž²àž£àžàžŽàžàžàž±à¹àžà¹àžàž£à¹àžàž£àž¡ Greenstone
+à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£à¹àžàžŽà¹àž¡àžàž­àž¥à¹àž¥àžàžàž±àž àžàžžàžàž­àž²àžàžàž³à¹àžà¹àžàž±à¹àžàžàž²àž£
+<ul><li>à¹àžà¹ <a href="_httppagecollector_">àžàž±àž§àž£àž§àžàž£àž§àž¡</a> à¹àžàž·à¹àž­àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹ àž«àž£àž·àž­
+    <li>àžà¹àž²àžàžžàžàž¡àžµàžàžµàžàžµàž£àž­àž¡à¹àžàž£à¹àžàž£àž¡ Greenstone àž­àž¢àž¹à¹ àžàžžàžàž­àž²àžàžàžŽàžàžàž±à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž²àžàžàžµàžàžµàž£àž­àž¡à¹àžà¹
+</ul>
+}  
+
+_text1coll_ [l=th] {àžàž²àž£àžàžŽàžàžàž±à¹àžà¹àžàž£à¹àžàž£àž¡ Greenstone àžàžµà¹àž¡àžµàžàž­àž¥à¹àž¥àžàžàž±àžàžàž±àž§àž­àž¢à¹àž²àž 1 àžàž­àž¥à¹àž¥àžàžàž±àž}  
+
+_textmorecolls_ [l=th] {àžàž²àž£àžàžŽàžàžàž±à¹àž Greenstone àžàžµà¹àž¡àžµ _1_ àžàž­àž¥à¹àž¥àžàžàž±àž}  
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=th] {àžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàž àž²àž¢àžàž­àž}  
+_textlinknotfound_ [l=th] {à¹àž¡à¹àžàžàžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàž àž²àž¢à¹àž}  
+
+_textextlinkcontent_ [l=th] {àžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàžàžµà¹àžàžžàžà¹àžà¹à¹àž¥àž·àž­àžà¹àž§à¹à¹àžà¹àžàžàž²àž£à¹àžàž·à¹àž­àž¡àžà¹àž­àžà¹àž²àžàžàž­àžà¹àžàž¢àž±àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžàžžàžà¹àž¥àž·àž­àžà¹àž§à¹à¹àžàžàž±àžàžàžžàžàž±àž
+    àžà¹àž²àžàžžàžàž¢àž±àžàžàžàžà¹àž­àžàžàž²àž£àžàžµà¹àžàž°àžàž¹àžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàžàžµà¹à¹àž¥àž°à¹àžàž£àž²àž§à¹à¹àžàž­àž£à¹àžàž­àžàžàžžàžàžªàž²àž¡àž²àž£àžà¹àžà¹àž²àžàž¶àžà¹àž§à¹àžà¹àžà¹
+    àžàžžàžàžªàž²àž¡àž²àž£àž <a href="_nexturl_">à¹àžàžà¹àž²àžàž«àžà¹àž²</a> à¹àžàž·à¹àž­à¹àžàž¢àž±àžàž«àžà¹àž²àžàžµà¹à¹àžà¹ 
+    àž«àž£àž·àž­ àžàžàžàžžà¹àž¡ "àž¢à¹àž­àžàžàž¥àž±àž" àžàžà¹àžàž£àž²àž§à¹à¹àžàž­àž£à¹àžàž­àžàžàžžàžà¹àžàž·à¹àž­àžàž¥àž±àžà¹àžàž¢àž±àžà¹àž­àžàžªàž²àž£àžà¹àž­àžàž«àžà¹àž²àžàžµà¹}  
+
+_textlinknotfoundcontent_ [l=th] {àžà¹àž§àž¢à¹àž«àžàžžàžàž¥àžàžµà¹àž­àž¢àž¹à¹àžàž­àžà¹àž«àžàž·àž­àžàž²àž£àžàž§àžàžàžžàž¡àžàž­àžà¹àž£àž² àžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàž àž²àž¢à¹àžàžàžµà¹àžàžžàžà¹àžà¹à¹àž¥àž·àž­àžà¹àž§à¹à¹àž¡à¹àž¡àžµàž­àž¢àž¹à¹à¹àž¥à¹àž§
+    àžàž¶à¹àžàž­àž²àžà¹àžà¹àžà¹àžà¹àžà¹àž§à¹àž² à¹àžàžŽàžàžà¹àž­àžàžŽàžàžàž¥àž²àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžà¹àžàžàžàž±àž
+    à¹àž«à¹à¹àžà¹àžàžžà¹àž¡ "àž¢à¹àž­àžàžàž¥àž±àž" à¹àžà¹àžàž£àž²àž§à¹àžàž­àž£à¹àžàž­àžàžàžžàžà¹àžàž·à¹àž­àžàž¥àž±àžà¹àžàž¢àž±àžà¹àž­àžàžªàž²àž£àžà¹àž­àžàž«àžà¹àž²àžàžµà¹}  
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=th] {<h3>à¹àžàž·à¹àž­àž¡à¹àž¢àžà¹àžàž¢àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž "_2_"</h3>
+
+<p> àžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàžàžµà¹àžàžžàžà¹àžà¹à¹àž¥àž·àž­àžà¹àž§à¹à¹àžà¹àžàžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàž àž²àž¢àžàž­àžà¹àžàž¢àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž "_collectionname_"
+    (àžàž¶à¹àžà¹àžàž·à¹àž­àž¡à¹àž¢àžà¹àžàž¢àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž "_2_")
+    àžà¹àž²àžàžžàžàžà¹àž­àžàžàž²àž£àžàž¹àžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàžàžµà¹à¹àžàžàž­àž¥à¹àž¥àžàžàž±àž "_2_" àžàžžàžàžªàž²àž¡àž²àž£àž 
+    <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">à¹àžàžà¹àž­àž¢àž±àž</a> àž«àžà¹àž²àžàžµà¹à¹àžà¹ 
+    àž«àž£àž·àž­à¹àžà¹àžàžžà¹àž¡ "àž¢à¹àž­àžàžàž¥àž±àž" àžàžà¹àžàž£àž²àž§à¹àžàž­àž£à¹àžàž­àžàžàžžàžà¹àžàž·à¹àž­àžàž¥àž±àžà¹àžà¹àž­àžàžªàž²àž£àžà¹àž­àžàž«àžà¹àž²àžàžµà¹
+}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=th] {àž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥ Greenstone}  
+
+_textusername_ [l=th] {àžàž·à¹àž­àžàž¹à¹à¹àžà¹}  
+_textpassword_ [l=th] {àž£àž«àž±àžªàžà¹àž²àž}  
+
+_textmustbelongtogroup_ [l=th] {à¹àžàž£àžàžªàž±àžà¹àžàžàžžàž§à¹àž² àžàžžàžàžà¹àž­àžàž­àž¢àž¹à¹à¹àžàžàž¥àžžà¹àž¡ "_cgiargug_" à¹àžàž·à¹àž­à¹àžà¹àž²àžàž¶àžàž«àžà¹àž²àžàžµà¹}  
+
+_textmessageinvalid_ [l=th] {àžàžžàžàžàž°àžà¹àž­àžà¹àžà¹àž²àžªàž¹à¹àž£àž°àžàžàžà¹àž­àžà¹àžàž¢àž±àžàž«àžà¹àž²àžàžµà¹àžàžžàžàž£à¹àž­àžàžàž­ <br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)
+àžàž£àžžàžàž²à¹àžªà¹àžàž·à¹àž­àžàž¹à¹à¹àžà¹à¹àž¥àž°àž£àž«àž±àžªàžà¹àž²àžà¹àžàž£à¹àžàž£àž¡ Greenstone àžàž­àžàžàžžàž}  
+
+_textmessagefailed_ [l=th] {àžàž·à¹àž­àžàž¹à¹à¹àžà¹àž«àž£àž·àž­àž£àž«àž±àžªàžà¹àž²àžàžàž­àžàžàžžàžà¹àž¡à¹àžàž¹àžàžà¹àž­àž}  
+
+_textmessagedisabled_ [l=th] {àžàž­àž­àž àž±àž¢ àžàž±àžàžàžµàžàž·à¹àž­àžàž­àžàžàžžàžàžàž¹àžàž£àž°àžàž±àžàžàž£àžŽàžàž²àž£  àžàž£àžžàžàž²àžàžŽàžàžà¹àž­àžàž¹à¹àžàž¹à¹àž¥à¹àž§à¹àžà¹àžàžà¹àžàžµà¹}  
+
+_textmessagepermissiondenied_ [l=th] {àžàž­àž­àž àž±àž¢ àžàžžàžà¹àž¡à¹à¹àžà¹àž£àž±àžàž­àžàžžàžàž²àžà¹àž«à¹à¹àžà¹àž²àžàž¶àžàž«àžà¹àž²àžàžµà¹}  
+
+_textmessagestalekey_ [l=th] {àžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàžàžµà¹àžàžžàžà¹àžà¹àž²àž¡àž²àžàžµà¹à¹àžà¹àž«àž¡àžàž­àž²àž¢àžžà¹àž¥à¹àž§
+àžàž£àžžàžàž²à¹àžªà¹àž£àž«àž±àžªàžà¹àž²àžàžàž­àžàžà¹àž²àžà¹àžàž·à¹àž­à¹àžà¹àž²àžàž¶àžàž«àžà¹àž²àžàžµà¹}  
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=th] {<p>àžàž²àž£àžàžŽàžàžàž±à¹àž Greenstone àžàžµà¹à¹àž¡à¹àž¡àžµà¹àž­àžàžªàž²àž£àžàž£àž°àžàž­àžà¹àžà¹ àž­àž²àžà¹àžàž·à¹àž­àžàž¡àž²àžàž²àž:
+<ol>
+ <li>à¹àžàž£à¹àžàž£àž¡ Greenstone à¹àžà¹àž£àž±àžàžàž²àž£àžàžŽàžàžàž±à¹àžàžàž²àžàžàžµàžàžµàž£àž­àž¡à¹àžàž¢à¹àžà¹àžàž²àž£àžàžŽàžàžàž±à¹àžà¹àžàžàžàž£àž°àžàž±àž
+ <li>à¹àžàž£à¹àžàž£àž¡ Greenstone à¹àžà¹àž£àž±àžàžàž²àž£àžàžŽàžàžàž±à¹àžàžàž²àžàž£àžžà¹àžàžàžµà¹à¹àžàžàžà¹àž²àž¢à¹àž«à¹àžàž²àž§àžà¹à¹àž«àž¥àžàžàž²àžàž­àžŽàžà¹àžàž­àž£à¹à¹àžà¹àž
+</ol>
+àžªàž³àž«àž£àž±àžàžàž±à¹àžàžªàž­àžàžàž£àžàžµ àžàžžàžàž­àž²àžàžàž­à¹àž­àžàžªàž²àž£à¹àžà¹àžàž±à¹àžàžàž²àžà¹àžà¹àž£àžàžàž­àž£àžµ <i>docs</i> à¹àžàžàžµàžàžµàž£àž­àž¡à¹àžàž£à¹àžàž£àž¡ Greenstone àž«àž£àž·àž­à¹àžà¹àž²à¹àžàžàžµà¹ <a href="http://www.greenstone.org">http://www.greenstone.org</a>
+}  
+
+_textuserguide_ [l=th] {àžàž¹à¹àž¡àž·àž­àžàž¹à¹à¹àžà¹àž£àž°àžàž}  
+_textinstallerguide_ [l=th] {àžàž¹à¹àž¡àž·àž­àžàž²àž£àžàžŽàžàžàž±à¹àž}  
+_textdeveloperguide_ [l=th] {àžàž¹à¹àž¡àž·àž­àžªàž³àž«àž£àž±àžàžàž±àžàžàž±àžàžàž²àž£àž°àžàž}  
+_textpaperguide_ [l=th] {àžàž²àžàžàž£àž°àžàž²àž©àžªàž¹à¹àžàž­àž¥à¹àž¥àžàžàž±àž}  
+_textorganizerguide_ [l=th] {àžàž²àž£à¹àžà¹àžàž±àž§àžàž±àžàžàž²àž£}  
+
+_textgsdocstitle_ [l=th] {à¹àž­àžàžªàž²àž£àžàž£àž°àžàž­àžà¹àžàž£à¹àžàž£àž¡ greenstone}  
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=th] {àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àž}  
+_textbildsuc_ [l=th] {àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžªàž£à¹àžà¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§}  
+_textviewbildsummary_ [l=th] {àžàžžàžàžªàž²àž¡àž²àž£àž <a href="_httppagex_(bsummary)" target=_top>àžàž¹àžàž¥àžªàž£àžžàžàžàž­àžàžàž²àž£àžªàž£à¹àž²àž</a> àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹à¹àžà¹à¹àžàž·à¹àž­à¹àžà¹àžàžà¹àž­àž¡àž¹àž¥à¹àžàžŽà¹àž¡à¹àžàžŽàž¡
+}  
+_textview_ [l=th] {àžàž¹àžàž­àž¥à¹àž¥àžàžàž±àž}  
+
+_textbild1_ [l=th] {àžàž³àž¥àž±àžàžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàž­àž¢àž¹à¹: àžàž²àž£àžàž³à¹àžàžŽàžàžàž²àž£àžàžµà¹àž­àž²àžà¹àžà¹à¹àž§àž¥àž²
+à¹àžàžàžªàžàž²àžàž°àžàž²àž£àžªàž£à¹àž²àžàžà¹àž²àžàž¥à¹àž²àžàžàžµà¹àžàž°à¹àžªàžàžàž£àž°àžàž±àžàžàž§àž²àž¡àžà¹àž²àž§àž«àžà¹àž²àžàž­àžàžàž²àž£àžàž³à¹àžàžŽàžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥àž¥à¹àžàžàž±àž}  
+
+_textbild2_ [l=th] {à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àž«àž¢àžžàžàžàž£àž°àžàž§àžàžàž²àž£àžªàž£à¹àž²àžà¹àž¡àž·à¹àž­à¹àžàžà¹àžàž²àž¡ à¹àž«à¹àžàž¥àžŽàžàžàžµà¹àžàžµà¹
+<br>àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžàžžàžàžàž³àž¥àž±àžàžàž³àžàž²àžàž­àž¢àž¹à¹àžàž°àž¢àž±àžàžàžàž­àž¢àž¹à¹àž­àž¢à¹àž²àžàžªàž¡àžàž¹àž£àžà¹
+}
+
+_textstopbuild_ [l=th] {àž«àž¢àžžàžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àž}  
+
+_textbild3_ [l=th] {àžà¹àž²àžàžžàžàž­àž­àžàžàž²àžàž«àžà¹àž²àžàžµà¹à¹àž¥à¹àž§ (à¹àž¥àž°à¹àž¡à¹à¹àžà¹àž¢àžà¹àž¥àžŽàžàžàž£àž°àžàž§àžàžàž²àž£àžªàž£à¹àž²àžà¹àžàž¢à¹àžà¹
+àžàžžà¹àž¡ "àž«àž¢àžžàžàžàž²àž£àžªàž£à¹àž²àž") àžàž­àž¥à¹àž¥àžàžàž±àžàžàž°àž¢àž±àžàžàžàžàž¹àžàžªàž£à¹àž²àžàžà¹àž­à¹àžà¹àž¥àž°àžàž°àžàž¹àžàžàžŽàžàžàž±à¹àž
+à¹àž¡àž·à¹àž­àžªàž£à¹àž²àžà¹àžªàž£à¹àžàžªàž¡àžàž¹àž£àžà¹à¹àž¥à¹àž§
+}  
+
+_textbuildcancelled_ [l=th] {àžàž²àž£àžªàž£à¹àž²àžàžàž¹àžàž¢àžà¹àž¥àžŽàž}  
+
+_textbildcancel1_ [l=th] {àžàž£àž°àžàž§àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž¹àžàž¢àžà¹àž¥àžŽàž  à¹àž«à¹à¹àžà¹àžàžžà¹àž¡àžªàžµà¹àž«àž¥àž·àž­àžàžà¹àž²àžàž¥à¹àž²àž
+à¹àžàž·à¹àž­àžàž³àžàž²àž£à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàžàžžàž àž«àž£àž·àž­à¹àž£àžŽà¹àž¡àžà¹àžàžàž£àž°àžàž§àžàžàž²àž£àžªàž£à¹àž²àžà¹àž«àž¡à¹}  
+
+_textbsupdate1_ [l=th] {àžªàžàž²àžàž°àžàž²àž£àžªàž£à¹àž²àžàžàž°àžàž£àž±àžàžàž£àžžàžàžà¹àž²àž àž²àž¢à¹àž 1 àž§àžŽàžàž²àžàžµ}  
+_textbsupdate2_ [l=th] {àžàž³àž¥àž±àžàžªàž£à¹àž²àžàžàž²àž£àžàž£àž±àžàžàž£àžžàžàžªàžàž²àžàž°à¹àž}  
+_textseconds_ [l=th] {àž§àžŽàžàž²àžàžµ}  
+
+_textfailmsg11_ [l=th] {à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžà¹à¹àžàž·à¹àž­àžàžàž²àžà¹àž¡à¹àž¡àžµàžà¹àž­àž¡àž¹àž¥à¹àžàžàž­àž¥à¹àž¥àžàžàž±àž àžàž£àžžàžàž²àžàž£àž§àžàžªàž­àž
+à¹àž«à¹à¹àžà¹à¹àžàž§à¹àž² àž­àž¢à¹àž²àžàžà¹àž­àž¢àž«àžàž¶à¹àžà¹àžà¹àž£àžàžàž­àž£àžµàž«àž£àž·àž­àž«àžàž¶à¹àžà¹àžà¹àž¡àžàžµà¹àžàžžàžàž£àž°àžàžžàžàžàž«àžà¹àž² 
+<i>àžà¹àž­àž¡àž¹àž¥àžà¹àžàžàžàž±àž</i> àž¡àžµàž­àž¢àž¹à¹àžàž£àžŽàž à¹àž¥àž°à¹àžà¹àžàžàžàžŽàžàžàžµà¹ àž«àž£àž·àž­(à¹àžàžàž£àžàžµàžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµ) 
+àžàž£àž°àžàž­àžàžà¹àž§àž¢à¹àžà¹àž¡àžàžàžŽàžàžàžµà¹ Greenstone àžªàž²àž¡àž²àž£àžàžàž³à¹àžàžŽàžàžàž²àž£à¹àžà¹
+}  
+
+_textfailmsg21_ [l=th] {à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžà¹ (import.pl à¹àž¡à¹àžàž³àžàž²àž)}  
+_textfailmsg31_ [l=th] {à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžà¹ (buildcol.pl à¹àž¡à¹àžàž³àžàž²àž)}  
+_textfailmsg41_ [l=th] {àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžªàž£à¹àž²àžà¹àžªàž£à¹àžà¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§ à¹àžà¹à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàžŽàžàžàž±à¹àžà¹àžà¹}  
+_textfailmsg71_ [l=th] {àžà¹àž­àžàžŽàžàžàž¥àž²àžàžàžµà¹à¹àž¡à¹àžàž²àžàžàžŽàžà¹àžàžŽàžàžàž¶à¹àžàžàžàž°àžàž¢àž²àž¢àž²àž¡àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàžàžžàž}  
+
+
+_textblcont_ [l=th] {à¹àžà¹àž¡àžàž±àžàžàž¶àžàžàž²àž£àžªàž£à¹àž²àžàžàž£àž°àžàž­àžàžà¹àž§àž¢àžà¹àž­àž¡àž¹àž¥àžàž±àžàžà¹àž­à¹àžàžàžµà¹:}  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=th] {à¹àžàž£àžàžªàž£à¹àž²àžà¹àž£àžŽà¹àž¡àžà¹àž}  
+_textmore_ [l=th] {àž¡àž²àžàžàž§à¹àž²}  
+_textinfo_ [l=th] {àžà¹àž­àž¡àž¹àž¥àžàž­àž¥à¹àž¥àžàžàž±àž}  
+_textsrce_ [l=th] {àžà¹àž­àž¡àž¹àž¥àžà¹àžàžàžàž±àž}  
+_textconf_ [l=th] {àžàž³àž«àžàžàžà¹àž²àžàž­àž¥à¹àž¥àžàžàž±àž}  
+_textdel_ [l=th] {àž¥àžàžàž­àž¥à¹àž¥àžàžàž±àž}  
+_textexpt_ [l=th] {àžªà¹àžàž­àž­àžàžàž­àž¥à¹àž¥àžàžàž±àž}  
+
+_textdownloadingfiles_ [l=th] {àžàž³àž¥àž±àžàžàž²àž§àžà¹à¹àž«àž¥àžà¹àžà¹àž¡ âŠ}  
+_textimportingcollection_ [l=th] {àžàž³àž¥àž±àžàžàž³à¹àžà¹àž²àžàž­àž¥à¹àž¥àžàžàž±àž âŠ}  
+_textbuildingcollection_ [l=th] {àžàž³àž¥àž±àžàžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àž âŠ}  
+_textcreatingcollection_ [l=th] {àžàž³àž¥àž±àžàžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àž âŠ}  
+
+_textcollectorblurb_ [l=th] {<i>àžàž²àžàžàž²àž­àž²àžàž¡àžµàž­àž²àžàžžàž àž²àžàž¡àž²àžàžàž§à¹àž²àžàž²àž!
+<br>àžàž²àž£àžªàž£à¹àž²àžà¹àž¥àž°à¹àžàžàžà¹àž²àž¢àžàž­àž¥à¹àž¥àžàžàž±àžàžà¹àž­àž¡àž¹àž¥àžàž±à¹àžà¹àžà¹àžàžàž²àž£à¹àžàžàž£àž±àžàžàž§àž²àž¡àž£àž±àžàžàžŽàžàžàž­àžàžàžµà¹
+àžàžžàžàž­àž²àžàžàž°àžà¹àž­àžàžàž³àžàž¶àžàžàž¶àžàžà¹àž­àžàžàžµà¹àžàžžàžàžàž°à¹àž£àžŽà¹àž¡àžàž³à¹àžàžŽàžàžàž²àž£
+àžàž£àž°à¹àžà¹àžàžàž²àžàžàžàž«àž¡àž²àž¢àž¥àžŽàžàžªàžŽàžàžàžŽà¹àžàžµà¹àžàž°àžà¹àž­àžàžàžŽàžàž²àž£àžàž² àžàž¥à¹àž²àž§àžàž·àž­ 
+àžàž§àž²àž¡àžªàž²àž¡àž²àž£àžà¹àžàžàž²àž£à¹àžà¹àž²àžàž¶àžà¹àž­àžàžªàž²àž£à¹àžà¹àžàž±à¹àž à¹àž¡à¹à¹àžà¹àž«àž¡àž²àž¢àžàž§àž²àž¡àž§à¹àž²
+àžàžžàžàžàž°àžªàž²àž¡àž²àž£àžàžàžµà¹àžàž°à¹àž«à¹à¹àž­àžàžªàž²àž£àžàž±à¹àžàžàž±àžàžàž¹à¹àž­àž·à¹àžà¹àžà¹
+àžàž£àž°à¹àžà¹àžàžàž²àžàžªàž±àžàžàž¡ àžàž¥à¹àž²àž§àžàž·àž­  
+àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžªàž£à¹àž²àžàžàž§àž£à¹àžàž²àž£àžàž§àž±àžàžàžàž£àž£àž¡àžàž­àžàžàžžàž¡àžàžàžàžµà¹àžªàž£à¹àž²àžà¹àž­àžàžªàž²àž£àžàž±à¹àž
+àžàž­àžàžàž²àžàžàžµà¹ àž¢àž±àžàž¡àžµàžàž£àž°à¹àžà¹àžàžàž²àžàžàž£àžŽàž¢àžàž£àž£àž¡ àžàž¥à¹àž²àž§àžàž·àž­
+àžàž²àžàžªàžŽà¹àžàžà¹à¹àž¡à¹àžàž§àž£à¹àžàžŽàžà¹àž«à¹àžàž¹à¹àž­àž·à¹àžà¹àžà¹àžàž²àžà¹àžàž¢àžà¹àž²àž¢
+<br>àžàžàžàž³àžàž¶àžàžàž¶àžàžàž¥àž±àžàžàž­àžàžà¹àž­àž¡àž¹àž¥à¹àž¥àž°àž£àž¹à¹àžàž±àžà¹àžà¹àž¡àž±àžàž­àž¢à¹àž²àžàžàž²àžàžàž¥àž²àž
+</i>
+}  
+
+_textcb1_ [l=th] {àžàž±àž§àž£àž§àžàž£àž§àž¡àžàž°àžà¹àž§àž¢àžàžžàžà¹àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹ à¹àžà¹à¹àžàž«àž£àž·àž­à¹àžàžŽà¹àž¡àžà¹àž­àž¡àž¹àž¥àž¥àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž¡àžµàž­àž¢àž¹à¹à¹àž¥à¹àž§
+àž«àž£àž·àž­àž¥àžàžàž­àž¥à¹àž¥àžàžàž±àž  à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àžàž³à¹àžàžŽàžàžàž²àž£àžàžµà¹ àžàžžàžàžàž°à¹àžà¹àž£àž±àžàžàž²àž£àžàž³àžàž²àžàžà¹àž²àžàžàžžàžàž¥àž³àžàž±àžàžàž­àžà¹àž§à¹àžà¹àžàžàžàžµà¹àž£à¹àž­àžàžàž­àžà¹àž­àž¡àž¹àž¥àžàžµà¹àžàž³à¹àžà¹àžàžàž±à¹àžà¹}  
+
+_textcb2_ [l=th] {àžà¹àž­àžàž­àž·à¹àž àžàžžàžàžà¹àž­àžàžàž±àžàžªàžŽàžà¹àžàž§à¹àž²àžàž°}  
+_textcnc_ [l=th] {àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹}  
+_textwec_ [l=th] {àžàž³àžàž²àžà¹àžà¹àžàž±àžàžàž±àž§àžàžµà¹àž¡àžµàž­àž¢àž¹à¹ à¹àžàžŽà¹àž¡àžà¹àž­àž¡àž¹àž¥à¹àžà¹àž²à¹àž àž«àž£àž·àž­àž¥àžàžàžŽà¹àž}  
+
+_textcb3_ [l=th] {àžàžžàžàžàž°àžà¹àž­àžà¹àžà¹àž²àžªàž¹à¹àž£àž°àžàžà¹àžªàžµàž¢àžà¹àž­àžà¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àžªàž£à¹àž²àžàž«àž£àž·àž­à¹àžà¹à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžàž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥
+àžàž²àž£àžàž£àž°àžàž³à¹àžà¹àžàžàžµà¹à¹àžà¹àžàžàž²àž£àžà¹àž­àžàžàž±àžà¹àž¡à¹à¹àž«à¹àžàž¹à¹àž­àž·à¹àžà¹àžà¹àž²àžªàž¹à¹àžàž­àž¡àžàžŽàž§à¹àžàž­àž£à¹àžàž­àžàžàžžàž 
+à¹àž¥àž°àžàž³àžàž²àž£àžàž£àž±àžà¹àžàž¥àžµà¹àž¢àžàžà¹àž­àž¡àž¹àž¥àžàžàžàž±à¹àž
+àž«àž¡àž²àž¢à¹àž«àžàžž: à¹àžàž·à¹àž­àžàžà¹àž§àž¢à¹àž«àžàžžàžàž¥àžà¹àž²àžàžàž§àž²àž¡àžàž¥àž­àžàž àž±àž¢ à¹àž¡àž·à¹àž­à¹àž§àž¥àž²àžà¹àž²àžà¹àž 30 àžàž²àžàžµàž«àž¥àž±àžàžàž²àžàžàžµà¹àžàžžàžà¹àžà¹àž²àžªàž¹à¹àž£àž°àžàž àžàžžàžàžàž°àžàž¹àžàžàž¥àžàž­àž­àžàžàž²àžàž£àž°àžàžàžàž±àžàžàžµ
+àžà¹àž²à¹àžàžŽàžà¹àž«àžàžžàžàž²àž£àžà¹à¹àžà¹àžàžàžµà¹ à¹àž¡à¹àžà¹àž­àžàžàž±àžàž§àž¥à¹àž! -- àžàžžàžàžàž°à¹àžà¹àž£àž±àžà¹àžàžŽàžà¹àž«à¹à¹àžà¹àž²àžªàž¹à¹àž£àž°àžàžàž­àžµàžàžàž£àž±à¹àžà¹àž¥àž°àžªàž²àž¡àž²àž£àž
+àžàž³à¹àžàžŽàžàžàž²àž£àžà¹àž­àžàž²àžàžàžžàžàžàžµà¹àžàžžàžàž­àž­àžàžàž²àžàž£àž°àžàžà¹àžà¹àž¥à¹àž§à¹àžà¹
+}  
+
+_textcb4_ [l=th] {àžàž£àžžàžàž²à¹àžªà¹àžàž·à¹àž­àžàž¹à¹à¹àžà¹à¹àžàž£à¹àžàž£àž¡ Greenstone à¹àž¥àž°àž£àž«àž±àžªàžà¹àž²àžàžàž­àžàžàžžàž à¹àž¥àž°àžàž¥àžŽàžàžàžµà¹àžàžžà¹àž¡à¹àžàž·à¹àž­à¹àžà¹àž²àžªàž¹à¹àž£àž°àžàž}  
+
+_textfsc_ [l=th] {àžàž±à¹àžà¹àž£àž à¹àž«à¹à¹àž¥àž·àž­àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžàžžàžàžà¹àž­àžàžàž²àž£àžàž³àžàž²àž (àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžà¹àž­àžàžàž±àžàžàž²àž£à¹àžàžµàž¢àžà¹àž§à¹
+àžàž°à¹àž¡à¹àžàž£àž²àžàžà¹àžàž£àž²àž¢àžàž·à¹àž­àžàžµà¹)}  
+
+_textwtc_ [l=th] {àžà¹àž§àž¢àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžàžžàžà¹àž¥àž·àž­àžà¹àž§à¹ àžàžžàžàžªàž²àž¡àž²àž£àž}  
+_textamd_ [l=th] {à¹àžàžŽà¹àž¡àžà¹àž­àž¡àž¹àž¥à¹àž¥àž°àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹}  
+_textetc_ [l=th] {à¹àžà¹à¹àžà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž²àžàž­àž¥à¹àž¥àžàžàž±àžà¹àž¥àž°àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹}  
+_textdtc_ [l=th] {àž¥àžàžàž­àž¥à¹àž¥àžàžàž±àžàž­àž­àžàžàž±à¹àžàž«àž¡àž}  
+_textetcfcd_ [l=th] {àžªà¹àžàž­àž­àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžàž·à¹àž­à¹àžàžµàž¢àžàž¥àžà¹àžàžàžµàžàžµàž£àž­àž¡à¹àžàžàžàžŽàžàžàž±à¹àžàžà¹àž§àž¢àžàžà¹àž­àž (Windows)}  
+_textcaec_ [l=th] {àžàž²àž£à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž¡àžµàž­àž¢àž¹à¹}  
+_textnwec_ [l=th] {à¹àž¡à¹àž¡àžµàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž­àžàžžàžàž²àžà¹àž«à¹à¹àžàžµàž¢àžà¹àžà¹à¹àžàžŽàžà¹àž«à¹àžàž³àžàž²àž£à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àž}  
+_textcianc_ [l=th] {àžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹}  
+_texttsosn_ [l=th] {àž¥àž³àžàž±àžàžàž­àžàžàž±à¹àžàžàž­àžàžàžµà¹àžàž³à¹àžà¹àžà¹àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥à¹àž«àž¡à¹àžàž·àž­:}  
+_textsin_ [l=th] {àž£àž°àžàžžàžàž·à¹àž­ (à¹àž¥àž°àžà¹àž­àž¡àž¹àž¥àžàžµà¹à¹àžàžµà¹àž¢àž§àžà¹àž­àž)}  
+_textswts_ [l=th] {àž£àž°àžàžžà¹àž«àž¥à¹àžàžàžµà¹àž¡àž²àžàž­àžàžà¹àž­àž¡àž¹àž¥}  
+_textatco_ [l=th] {àžàž£àž±àžàžà¹àž²àžàž±àž§à¹àž¥àž·àž­àžàžàž³àž«àžàžàžà¹àž² (àžªàž³àž«àž£àž±àžàžàž¹à¹à¹àžà¹àžàž±à¹àžàžªàž¹àžà¹àžà¹àž²àžàž±à¹àž)}  
+_textbtc_ [l=th] {"àžªàž£à¹àž²àž" àžàž­àž¥à¹àž¥àžàžàž±àž (àžàž¹àžà¹àž²àžàž¥à¹àž²àž)}  
+_textpvyh_ [l=th] {àžàž¹àžàž²àžàžàžµà¹àžàžžàžàžàž³à¹àž­àžàžà¹àž§àž¢àžàž§àž²àž¡àž àž¹àž¡àžŽà¹àž}  
+
+_texttfsiw_ [l=th] {àžàž±à¹àžàžàž­àžàžàžµà¹àžªàžµà¹ àžàž·àž­ àžàž²àž£àžàž³àž«àžàžàžàžµà¹àžàžµà¹àžàž­àž¡àžàžŽàž§à¹àžàž­àž£à¹àžàž°àžàž³à¹àžàžŽàžàžàž²àžàžàž±à¹àžàž«àž¡àž
+à¹àžàžàž±à¹àžàžàž­àžàžàž­àžàžàž²àž£ "àžªàž£à¹àž²àž" àžàž­àž¥à¹àž¥àžàžàž±àž àžàž­àž¡àžàžŽàž§à¹àžàž­àž£à¹àžàž°àžàž³àžàž²àž£àžªàž£à¹àž²àžàžàž±àžàžàžµàžàž±à¹àžàž«àž¡àž à¹àž¥àž°àž£àž§àžàž£àž§àž¡àžà¹àž­àž¡àž¹àž¥àž­àž·à¹àžà¹ àžàžµà¹àžàž³à¹àžà¹àžàžà¹àž­àžà¹àžà¹à¹àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžà¹àž²àžà¹àž§àž¢àžàž±àž  à¹àžàž¢à¹àžàžàž±à¹àžàžàž­àžà¹àž£àž àžàžžàžàžàž°àžà¹àž­àžàž£àž°àžàžžàžà¹àž­àž¡àž¹àž¥à¹àž«àž¥à¹àž²àžàž±à¹àžà¹àžªàžµàž¢àžà¹àž­àž}  
+
+_textadab_ [l=th] {à¹àžàž­àž°à¹àžàž£àž¡àžàž°àžàž£àž²àžàžàžàž¶à¹àžàžà¹àž²àžàž¥à¹àž²àžàžàž¶à¹àžàžàž°àžà¹àž§àž¢à¹àž«à¹àžàžžàžàžàž²àž¡àž£àž­àž¢à¹àžà¹àž§à¹àž²àžàž­àžàžàžµà¹àžàžžàžàž­àž¢àž¹à¹àžàžµà¹à¹àž«àž
+àžàžžà¹àž¡àžªàžµà¹àžàžµàž¢àž§à¹àžà¹àžàžàžžà¹àž¡àžàžµà¹àžàžžàžàžªàž²àž¡àž²àž£àžàžàž¥àžŽàžà¹àžàž·à¹àž­àžàž³à¹àžàžŽàžàžàž²àž£àžàž²àž¡àžàž±à¹àžàžàž­àžàžà¹àž­à¹àž
+àžàžàž°àžàžµà¹àžàžžàžàžàž³à¹àžàžŽàžàžàž²àž£àžàž²àž¡àžàž±à¹àžàžàž­àž àžàžžà¹àž¡àžàž°à¹àžàž¥àžµà¹àž¢àžà¹àžà¹àžà¹àžàžªàžµà¹àž«àž¥àž·àž­àž
+àžàžžàžàžªàž²àž¡àž²àž£àžàžàž¥àž±àžà¹àžàž¢àž±àžàž«àžà¹àž²àžà¹àž­àžàžàžµà¹à¹àžà¹à¹àžàž¢àžàž¥àžŽàžàžàžžà¹àž¡àžªàžµà¹àž«àž¥àž·àž­àžàžàžµà¹àžà¹àž­àžàžàž²àž£à¹àžà¹àžàž­àž°à¹àžàž£àž¡}  
+
+_textwyar_ [l=th] {à¹àž¡àž·à¹àž­àžàžžàžàžàž£à¹àž­àž¡ à¹àž«à¹àžàž¥àžŽàžàžàžžà¹àž¡àžªàžµà¹àžàžµàž¢àž§ "àžà¹àž­àž¡àž¹àž¥à¹àžàžµà¹àž¢àž§àžàž±àžàžàž­àž¥à¹àž¥àžàžàž±àž" à¹àžàž·à¹àž­à¹àž£àžŽà¹àž¡àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥à¹àž«àž¡à¹àžàž­àžàžàžžàž}  
+
+_textcnmbs_ [l=th] {àžà¹àž­àžàž£àž°àžàžžàžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àž}  
+_texteambs_ [l=th] {àžà¹àž­àžàž£àž°àžàžžàžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥}  
+_textpsea_ [l=th] {àžàž£àžžàžàž²àž£àž°àžàžžàžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥à¹àžàž£àž¹àžà¹àžàž: username@domain}  
+_textdocmbs_ [l=th] {àžà¹àž­àžàž£àž°àžàžžàžàž³àž­àžàžŽàžàž²àž¢àžàž­àž¥à¹àž¥àžàžàž±àž}  
+
+_textwcanc_ [l=th] {àžàžàž°àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹ àžàžžàžàžàž³à¹àžà¹àžàžà¹àž­àžà¹àžªà¹àžà¹àž­àž¡àž¹àž¥à¹àžàž·à¹àž­àžàžà¹àžà¹àžàžµà¹àž¢àž§àžàž±àžàžà¹àž­àž¡àž¹àž¥àžà¹àžàžàžàž±àžàžà¹àž§àž¢
+àžàž£àž°àžàž§àžàžàž²àž£àžàžµà¹àžàž°à¹àžà¹àž£àž±àžàžàž²àž£àžàž±àžà¹àžàž£àžàžªàž£à¹àž²àžà¹àž«à¹àž­àž¢àž¹à¹à¹àžàž£àž¹àžà¹àžàžàžàž­àžàžàžžàžàž¥àž³àžàž±àžàžàž­àžàž«àžà¹àž²à¹àžàž àžàž¶à¹àžàžàž¹à¹àž¥à¹àžàž¢àžàž±àž§àž£àž§àžàž£àž§àž¡
+à¹àžàžàžàž£àžŽà¹àž§àžàž¥à¹àž²àžàžªàžžàžàžàž­àžàž«àžà¹àž²àžàž°à¹àžªàžàžàž¥àž³àžàž±àžàžàž­àžàž«àžà¹àž²àžàžµà¹àžàž°àžà¹àž­àžàžªàž£à¹àž²àžà¹àž«à¹à¹àžªàž£à¹àž}  
+
+_texttfc_ [l=th] {àžàž·à¹àž­à¹àž£àž·à¹àž­àžàžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž:}  
+
+_texttctiasp_ [l=th] {àžàž·à¹àž­àžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž°à¹àžà¹àžàž§àž¥àžµàžàžàž²àžàžªàž±à¹àžàžàžµà¹à¹àžà¹àžàž±à¹àž§à¹àžà¹àžàž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥à¹àžàž·à¹àž­àž£àž°àžàžžàžàž¶àžà¹àžàž·à¹àž­àž«àž²àžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž±à¹àž
+àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž  "Computer Science Technical Reports" à¹àž¥àž° "Humanity Development Library"}  
+
+_textcea_ [l=th] {àžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥àžªàž³àž«àž£àž±àžàžàžŽàžàžà¹àž­:}  
+
+_textteas_ [l=th] {àžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥àžàžµà¹àž£àž°àžàžžàžàžµà¹àž­àž¢àž¹à¹àžàžŽàžàžà¹àž­àž«àž¥àž±àžàžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž
+àžà¹àž²àžàž­àžàžà¹à¹àž§àž£à¹ Greenstone àžàž£àž§àžàžàžàžàž±àžàž«àž²à¹àžà¹ àž£àž²àž¢àžàž²àžàžàž¥àžàž²àž£àž§àžŽàžàžŽàžàžàž±àž¢àžàž°àžàž¹àžàžªà¹àžà¹àžàž¢àž±àžàž­àžµà¹àž¡àž¥àžàžµà¹
+à¹àž«à¹à¹àžªà¹àžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥à¹àžàž£àž¹àžà¹àžàžà¹àžà¹àž¡: <tt>name@domain</tt>
+}  
+
+_textatc_ [l=th] {à¹àžàžµà¹àž¢àž§àžàž±àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹:}  
+
+_texttiasd_ [l=th] {àžàžµà¹àžàž·àž­àžà¹àž­àžàž§àž²àž¡àžàžµà¹àž­àžàžŽàžàž²àž¢àžàž¶àžàž«àž¥àž±àžàžàžµà¹à¹àžà¹àžàž±àžàžàž²àž£àžªàžŽà¹àžàžàžµà¹àž£àž§àž¡àž­àž¢àž¹à¹à¹àžàžàž­àž¥à¹àž¥àžàžàž±àž
+àžà¹àž­àžàž§àž²àž¡àžàžµà¹àžàž°àžàž£àž²àžàžàžàžàž«àžà¹àž²à¹àž£àžà¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£àžàž³à¹àžªàžàž­àžàž­àž¥à¹àž¥àžàžàž±àž}  
+
+_textypits_ [l=th] {àžàž³à¹àž«àžà¹àžàžàž­àžàžàžžàžà¹àžàž¥àž³àžàž±àžàžàž°àž£àž°àžàžžà¹àžàž¢àž¥àž¹àžàžšàž£àžà¹àž²àžàž¥à¹àž²àž -- à¹àžàžàž£àžàžµàžàžµà¹àžàž·àž­ àžàž±à¹àžàžàž­àž "àžà¹àž­àž¡àž¹àž¥àžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àž"
+à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àžàž³à¹àžàžŽàžàžàž²àž£àžà¹àž­ à¹àž«à¹àžàž¥àžŽàžàžàžžà¹àž¡ "àžà¹àž­àž¡àž¹àž¥àžà¹àžàžàžàž±àž" àžªàžµà¹àžàžµàž¢àž§}  
+
+_srcebadsources_ [l=th] {<p>à¹àž«àž¥à¹àžàžà¹àž­àž¡àž¹àž¥àžàž³à¹àžà¹àž²àžàžµà¹àžàžžàžàž£àž°àžàžžàž­àž¢à¹àž²àžàžà¹àž­àž¢àž«àžàž¶à¹àžà¹àž«àž¥à¹àžà¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžà¹àžà¹ (àžàž±àžà¹àžªàžàž _iconcross_ àžà¹àž²àžàž¥à¹àž²àž)
+
+<p>àžàž±àžàž«àž²àžàžµà¹àž­àž²àžà¹àžàžŽàžàžàž¶à¹àžà¹àžàž·à¹àž­àžàžàž²àž
+<ul>
+<li>à¹àžà¹àž¡ à¹àžàžà¹ FTP àž«àž£àž·àž­ URL à¹àž¡à¹àž¡àžµàž­àž¢àž¹à¹à¹àž¥à¹àž§
+<li>àžàžžàžàžàž³à¹àžà¹àžàžà¹àž­àžàžà¹àž­àžªàž²àž¢à¹àžàž¢àž±àžàžàž¹à¹à¹àž«à¹àžàž£àžŽàžàž²àž£àž­àžŽàžà¹àžàž­àž£à¹à¹àžà¹àžàžàž­àžàžàžžàžàžà¹àž­àž
+<li>àžàžžàžàžàž³àž¥àž±àžàžàž¢àž²àž¢àž²àž¡à¹àžà¹àž²àžàž¶àž URL àžàžµà¹àž­àž¢àž¹à¹àž«àž¥àž±àžà¹àžàž£à¹àž§àž­àž¥àž¥à¹ (àžàž£àžàžµàž­àž²àžà¹àžàžŽàžàžàž¶à¹àžà¹àžà¹àžà¹àž²àžàžžàžàžà¹àž­àžà¹àžªà¹àžàž·à¹àž­àžàž¹à¹à¹àžà¹à¹àž¥àž°àž£àž«àž±àžªàžà¹àž²àžà¹àžàž·à¹àž­à¹àžà¹àž²àžàž¶àžàž­àžŽàžà¹àžàž­àž£à¹à¹àžà¹àž)
+</ul>
+
+<p>àžà¹àž²àžàžµà¹à¹àžà¹àž URL àžàžµà¹àžàžžàžàžªàž²àž¡àž²àž£àžàžàž¹à¹àžà¹àžàž²àžà¹àžàž£àž²àž§à¹àžàž­àž£à¹àžàž­àžàžàžžàž àžà¹àž²àžàžµà¹àž­àž²àžà¹àžà¹àž¡àž²àžàž²àžàžªàž³à¹àžàž²àžàžµà¹à¹àžà¹àžà¹àž§à¹à¹àžàž«àžà¹àž§àž¢àžàž§àž²àž¡àžàž³àžàž­àžà¹àžàž£àž·à¹àž­àž
+àžà¹àž²à¹àžªàžµàž¢àžàž²àž¢àž§à¹àž² àžàž£àž°àžàž§àžàžàž²àž£àž¡àžŽà¹àž£àž­àž£à¹àžàž­àžà¹àž£àž²à¹àž¡à¹àžªàž²àž¡àž²àž£àžàž¡àž­àžà¹àž«à¹àžàžªàž³à¹àžàž²àžàžµà¹à¹àžà¹àžà¹àž§à¹à¹àžà¹àž«àžà¹àž§àž¢àžàž§àž²àž¡àžàž³àžàž­àžà¹àžàž£àž·à¹àž­àž
+à¹àžàžàž£àžàžµàžàžµà¹ à¹àž£àž²àžàž­à¹àžàž°àžàž³à¹àž«à¹àžàžžàžàžàž²àž§àžà¹à¹àž«àž¥àžàž«àžà¹àž²à¹àžàž¢à¹àžà¹à¹àžàž£àž²àž§à¹àžàž­àž£à¹àžàž­àžàžàžžàžàžà¹àž­àž
+}  
+
+_textymbyco_ [l=th] {<p>àžàžžàžàžªàž²àž¡àž²àž£àžàžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàžàžžàžà¹àžà¹à¹àžàž¢à¹àžà¹
+<ul>
+<li>à¹àžàž£àžàžªàž£à¹àž²àžà¹àž£àžŽà¹àž¡àžà¹àž
+<dl><dd>àžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹àž­àž²àžàžàž£àž°àžàž­àžàžà¹àž§àž¢à¹àž­àžàžªàž²àž£àžà¹àž²àžà¹ à¹àžàž£àž¹àžà¹àžàžàžà¹àž­à¹àžàžàžµà¹: HTML, àžà¹àž­àžàž§àž²àž¡àž­àž¢à¹àž²àžà¹àžàžµàž¢àž§, àž­àžµà¹àž¡àž¥à¹àžàž "m-box", PDF, RTF, MS Word, PostScript, PowerPoint, 
+Excel, àž£àž¹àžàž àž²àž, CDS/ISIS </dd></dl>
+<li>àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž¡àžµàž­àž¢àž¹à¹à¹àž¥à¹àž§
+<dl><dd>à¹àžà¹àž¡à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹àžàž­àžàžàžžàžàžàž°àžà¹àž­àžà¹àžà¹àžàžàžàžŽàžà¹àžàžµàž¢àž§àžàž±àžàžàž±àžà¹àžà¹àž¡àžàžµà¹à¹àžà¹àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž¡àžµàž­àž¢àž¹à¹à¹àž¥à¹àž§</dd></dl>
+</ul>
+}  
+
+_textbtco_ [l=th] {àž­àžŽàžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžà¹àž²àžàž±àž}  
+_textand_ [l=th] {à¹àžàžŽà¹àž¡àžà¹àž­àž¡àž¹àž¥à¹àž«àž¡à¹}  
+_textad_ [l=th] {àžàž²àž£à¹àžàžŽà¹àž¡àžà¹àž­àž¡àž¹àž¥:}  
+
+_texttftysb_ [l=th] {à¹àžà¹àž¡àžàžµà¹àžàžžàžàž£àž°àžàžžà¹àž§à¹àžà¹àž²àžàž¥à¹àž²àžàžàž°àžàž¹àžà¹àžàžŽà¹àž¡à¹àžà¹àž²à¹àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àž àžàž£àž§àžàžªàž­àžà¹àž«à¹à¹àžà¹à¹àžàž§à¹àž² àžàžžàžà¹àž¡à¹à¹àžà¹àž£àž°àžàžžà¹àžà¹àž¡àžàžµà¹àž¡àžµàž­àž¢àž¹à¹à¹àž¥à¹àž§à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžà¹àž³àž­àžµàžàžàž£àž±à¹àž:
+à¹àž¡à¹à¹àžà¹àžàžàž±à¹àžà¹àž¥à¹àž§ àžªàž³à¹àžàž²àžàž°àžàž¹àžà¹àžàžŽà¹àž¡à¹àžà¹àž²à¹àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž±à¹àžàžªàž­àžàž£àž²àž¢àžàž²àž£ 
+à¹àžà¹àž¡àžàž°àžàž¹àžàž£àž°àžàžžàžà¹àž§àž¢àžàž·à¹àž­à¹àžªà¹àžàžàž²àžà¹àžàžà¹àžà¹àž¡
+à¹àž¥àž°àž«àžà¹àž²à¹àž§à¹àžàžàž°àžàž¹àžàž£àž°àžàžžàžà¹àž§àž¢àžàžµà¹àž­àž¢àž¹à¹à¹àž§à¹àžàžàžµà¹àžªàž¡àžàž¹àž£àžà¹
+}  
+
+_textis_ [l=th] {à¹àž«àž¥à¹àžàžà¹àž­àž¡àž¹àž¥àžàž³à¹àžà¹àž²:}  
+
+_textddd1_ [l=th] {<p>àžà¹àž²àžàžžàžà¹àžà¹ file:// àž«àž£àž·àž­ ftp:// à¹àžàž·à¹àž­àž£àž°àžàžžàžàž·à¹àž­à¹àžà¹àž¡ à¹àžà¹àž¡àžàž±à¹àžàžàž°àžàž¹àžàžàž²àž§àžà¹à¹àž«àž¥àž
+
+<p>àžà¹àž²àžàžžàžà¹àžà¹ http:// àžàž¶à¹àžàž­àž¢àž¹à¹àžàž±àžàž§à¹àž² URL àžàž±à¹àžà¹àž£àžµàž¢àžà¹àžàž¢àž±àžàž«àžà¹àž²à¹àž§à¹àžàžàž£àž£àž¡àžàž²àžàžà¹àžàž£àž²àž§à¹à¹àžàž­àž£à¹àžàž­àžàžàžžàž
+àž«àž£àž·àž­àž£àž²àž¢àžàž·à¹àž­àžàž­àžà¹àžà¹àž¡  àžà¹àž²à¹àžà¹àžàž«àžà¹àž²à¹àž§à¹àžàžàž£àž£àž¡àžàž² àž«àžà¹àž²àžàž±à¹àžàžàž°àžàž¹àžàžàž²àž§àžà¹à¹àž«àž¥àž
+ -- àž£àž§àž¡àžàž¶àžàžàžžàžàž«àžà¹àž²àžàžµà¹àž«àžà¹àž²àžàž±à¹àžà¹àžàž·à¹àž­àž¡à¹àž¢àžàž­àž¢àž¹à¹ à¹àž¥àž°àžàžžàžàž«àžà¹àž²àžàžµà¹àž«àžà¹àž²à¹àž«àž¥à¹àž²àžàž±à¹àžà¹àžàž·à¹àž­àž¡à¹àž¢àž à¹àžà¹àžàžàžµà¹à¹àžà¹àž£àž·à¹àž­àž¢à¹
+ -- àžà¹àž²àž«àžà¹àž²à¹àž«àž¥à¹àž²àžàž±à¹àžàž­àž¢àž¹à¹àžàžà¹àžàžà¹à¹àžàžµàž¢àž§àžàž±àžàž àž²àž¢à¹àžà¹ URL à¹àžàžŽàž¡
+
+<p>àžà¹àž²àžàžžàžà¹àžà¹ file:// àž«àž£àž·àž­ ftp:// à¹àžàž·à¹àž­àž£àž°àžàžžà¹àžàž¥à¹àžàž­àž£à¹àž«àž£àž·àž­à¹àžà¹àž£àžàžàž­àž£àžµ àž«àž£àž·àž­ http:// URL 
+àžàžµà¹à¹àž£àžµàž¢àžà¹àžàž¢àž±àžàž£àž²àž¢àžàž·à¹àž­àžàž­àžà¹àžà¹àž¡ àžàžžàžàž­àž¢à¹àž²àžà¹àžà¹àžàž¥à¹àžàž­àž£à¹à¹àž¥àž°à¹àžàž¥à¹àžàž­àž£à¹àž¢à¹àž­àž¢àžàž±à¹àžàž«àž¡àžàžàž°àžàž¹àžàžàž£àž£àžàžž
+àž¥àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àž
+
+<p>àžàž¥àžŽàžàžàžžà¹àž¡ "à¹àž«àž¥à¹àžàž­àž·à¹àžà¹" à¹àžàž·à¹àž­à¹àžàžŽà¹àž¡àžàž¥à¹àž­àžàžà¹àž­àž¡àž¹àž¥àžàž³à¹àžà¹àž²
+}  
+
+_textddd2_ [l=th] {<p>à¹àž«à¹àžàž¥àžŽàžàžàžµà¹àžàžžà¹àž¡à¹àžàžµàž¢àž§àžàžžà¹àž¡à¹àžàžà¹à¹àžà¹  àžà¹àž²àžàžžàžà¹àžà¹àžàžàž¹à¹à¹àžà¹àžàž±à¹àžàžªàž¹àž 
+àžàžžàžàž­àž²àžàžàž°àžà¹àž­àžàžàž²àž£àžàž£àž±àžà¹àžà¹àžàžàž²àž£àžàž³àž«àžàžàžà¹àž²àžàž­àž¥à¹àž¥àžàžàž±àž
+àž«àž£àž·àž­àž­àž²àžàžàž°àžàž£àžà¹àžàž¢àž±àžàžàž±à¹àžàžàž­àžàžàž²àž£àžªàž£à¹àž²àžà¹àž¥àž¢àžà¹à¹àžà¹
+à¹àžàž£àžàžàž³à¹àž§à¹àž§à¹àž² àžàžžàžàžªàž²àž¡àž²àž£àžàžàž¥àž±àžà¹àžà¹àž²àž¡àž²àž¢àž±àžàžàž±à¹àžàžàž­àžàžà¹àž­àžàž«àžà¹àž²àžàžµà¹à¹àžà¹à¹àžªàž¡àž­à¹àžàž¢àžàž²àž£àžàž¥àžŽàžàžàžžà¹àž¡àžªàžµà¹àž«àž¥àž·àž­àž}  
+
+_textconf1_ [l=th] {<p>àžàž²àž£àžªàž£à¹àž²àžà¹àž¥àž°àžàž²àž£àžàž³à¹àžªàžàž­àžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàžàžžàžà¹àžà¹àž£àž±àžàžàž²àž£àžàž§àžàžàžžàž¡à¹àžàž¢àžà¹àž­àžàž³àž«àžàžàžàžµà¹àž­àž¢àž¹à¹à¹àž
+"à¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž²" àžàžŽà¹àžšàž©à¹àžà¹àž¡àž«àžàž¶à¹àž  àžàž¹à¹à¹àžà¹àžàž±à¹àžàžªàž¹àžàž­àž²àžàžà¹àž­àžàžàž²àž£àžàž£àž±àžà¹àžàž¥àžµà¹àž¢àžàžàž²àž£àžàž±à¹àžàžà¹àž²àžàž­àžàžàž²àž£àžàž³àž«àžàžàžà¹àž²
+
+<center><p><b>àžà¹àž²àžàžžàžà¹àž¡à¹à¹àžà¹à¹àžà¹àžàžàž¹à¹à¹àžà¹àžàž±à¹àžàžªàž¹àž à¹àž«à¹à¹àžàž¢àž±àžàžà¹àž²àžàž¥à¹àž²àžàžàž­àžàž«àžà¹àž²</b></center> 
+
+<p>à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àžàž£àž±àžà¹àžàž¥àžµà¹àž¢àžàžàž²àž£àžàž±à¹àžàžà¹àž²àžàž­àžàžàž²àž£àžàž³àž«àžàžàžà¹àž² à¹àž«à¹à¹àžà¹à¹àžàžà¹àž­àž¡àž¹àž¥àžàžµà¹àžàž£àž²àžàžàžà¹àž²àžàž¥à¹àž²àž
+àžà¹àž²àžàžžàžàžàž³àžàžŽàžàžàž¥àž²àž à¹àž«à¹àžàž¥àžŽàžàžàžµà¹ "àžàž±à¹àžàžà¹àž²à¹àž«àž¡à¹" à¹àžàž·à¹àž­àžàž£àž±àžàžàž²àž£àžàž±à¹àžàžà¹àž²à¹àž«à¹à¹àžà¹àžàžà¹àž²à¹àžàžŽàž¡
+}  
+
+_textreset_ [l=th] {àžàž±à¹àžàžà¹àž²à¹àž«àž¡à¹}  
+
+
+_texttryagain_ [l=th] {àžàž£àžžàžàž² <a href="_httppagecollector_" target=_top>à¹àž£àžŽà¹àž¡àžà¹àžàžàž±àž§àž£àž§àžàž£àž§àž¡à¹àž«àž¡à¹</a> à¹àž¥àž°àž¥àž­àžàž­àžµàžàžàž£àž±à¹àž}  
+
+
+_textretcoll_ [l=th] {àžàž¥àž±àžà¹àžàž¢àž±àžàžàž±àž§àž£àž§àžàž£àž§àž¡}  
+
+_textdelperm_ [l=th] {à¹àž¡à¹àžªàž²àž¡àž²àž£àžàž¥àžàžàž­àž¥à¹àž¥àžàžàž±àž _cgiargbc1dirname_ àžàž²àžàžàž±àž§àž«àž£àž·àž­àžàž±à¹àžàž«àž¡àžà¹àžà¹
+àžªàž²à¹àž«àžàžžàžàžµà¹àž­àž²àžà¹àžà¹àžà¹àžà¹àž¡àžµàžàž±àžàžàžµà¹:
+<ul>
+<li> à¹àžàž£à¹àžàž£àž¡ Greenstone à¹àž¡à¹à¹àžà¹àž£àž±àžàž­àžàžžàžàž²àžà¹àž«à¹àž¥àžà¹àžà¹àž£àžàžàž­àž£àžµ _gsdlhome_/collect/_cgiargbc1dirname_<br>
+àžàžžàžàž­àž²àžàžàž³à¹àžà¹àžàžà¹àž­àžàž¥àžà¹àžà¹àž£àžàžàž­àž£àžµàžàžµà¹àž­àž­àžàžà¹àž§àž¢àžàžà¹àž­àž à¹àžàž·à¹àž­àžà¹àž§àž¢à¹àž«à¹àžàž²àž£àž¥àžàžàž­àž¥à¹àž¥àžàžàž±àž _cgiargbc1dirname_ àž­àž­àžàžàž²àžàžàž­àž¡àžàžŽàž§à¹àžàž­àž£à¹àžàžµà¹à¹àžªàž£à¹àžàžªàž¡àžàž¹àž£àžà¹</li>
+<li>à¹àžàž£à¹àžàž£àž¡ Greenstone à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹à¹àžàž£à¹àžàž£àž¡ _gsdlhome_/bin/script/delcol.pl à¹àžà¹ àžàž£àžžàžàž²àžàž£àž§àžàžªàž­àžà¹àž«à¹à¹àžà¹à¹àžàž§à¹àž² à¹àžà¹àž¡àžàžµà¹àžªàž²àž¡àž²àž£àžàž­à¹àž²àžà¹àž¥àž°àžàžàžŽàžàž±àžàžŽàžàž²àž£à¹àžà¹</li>
+</ul>
+}  
+
+_textdelinv_ [l=th] {àžàž­àž¥à¹àž¥àžàžàž±àž _cgiargbc1dirname_ à¹àžà¹àž£àž±àžàžàž²àž£àžà¹àž­àžàžàž±àžàž«àž£àž·àž­à¹àž¡à¹àžàž¹àžàžà¹àž­àž  àžàž²àž£àž¥àžàžàž¹àžàž¢àžà¹àž¥àžŽàž}  
+
+_textdelsuc_ [l=th] {àžàž­àž¥à¹àž¥àžàžàž±àž _cgiargbc1dirname_ àžàž¹àžàž¥àžà¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§}  
+
+_textclonefail_ [l=th] {à¹àž¡à¹àžªàž²àž¡àž²àž£àžàž¥àž­àžà¹àžàžàžàž­àž¥à¹àž¥àžàžàž±àž _cgiargclonecol_ collection à¹àžà¹  àžªàž²à¹àž«àžàžžàžàžµà¹à¹àžà¹àžà¹àžà¹àžà¹à¹àžàžŽàžàžàž²àž:
+<ul>
+<li> à¹àž¡à¹àž¡àžµàžàž­àž¥à¹àž¥àžàžàž±àž _cgiargclonecol_ àž­àž¢àž¹à¹
+<li> àžàž­àž¥à¹àž¥àžàžàž±àž _cgiargclonecol_ à¹àž¡à¹àž¡àžµà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž² collect.cfg
+<li> à¹àžàž£à¹àžàž£àž¡Greenstone à¹àž¡à¹à¹àžà¹àž£àž±àžàž­àžàžžàžàž²àžà¹àž«à¹àž­à¹àž²àžà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž² collect.cfg
+</ul>
+}  
+
+_textcolerr_ [l=th] {à¹àžàžŽàžàžà¹àž­àžàžŽàžàžàž¥àž²àžàžàžµà¹àžàž±àž§àž£àž§àžàž£àž§àž¡}  
+
+_texttmpfail_ [l=th] {àžàž±àž§àž£àž§àžàž£àž§àž¡à¹àž¡à¹àžªàž²àž¡àž²àž£àžàž­à¹àž²àžàž«àž£àž·àž­à¹àžàžµàž¢àžà¹àžàž¢àž±àžà¹àžà¹àž¡àžàž±à¹àž§àžàž£àž²àž§ àž«àž£àž·àž­à¹àžà¹àž£àžàžàž­àž£àžµà¹àžà¹
+àžªàž²à¹àž«àžàžžàžàžµà¹àž­àž²àžà¹àžà¹àžà¹àžà¹àž¡àžµàžàž±àžàžàžµà¹:
+<ul>
+<li> à¹àžàž£à¹àžàž£àž¡ Greenstone à¹àž¡à¹àž¡àžµàžªàžŽàžàžàžŽà¹àžàžàž²àž£àž­à¹àž²àž/à¹àžàžµàž¢àžà¹àžà¹àž£àžàžàž­àž£àžµ _gsdlhome_/tmp
+</ul>
+}  
+
+_textmkcolfail_ [l=th] {àžàž±àž§àž£àž§àžàž£àž§àž¡à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžªàž£à¹àž²àžà¹àžàž£àžàžªàž£à¹àž²àžà¹àžà¹àž£àžàžàž­àž£àžµàžàžµà¹àžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹àžà¹àž­àžàžàž²àž£à¹àžà¹ 
+(mkcol.pl à¹àž¡à¹àžàž³àžàž²àž)  àžªàž²à¹àž«àžàžžàžàžµà¹à¹àžà¹àžà¹àžà¹àžà¹àž¡àžµàžàž±àžàžàžµà¹:
+<ul>
+<li> à¹àžàž£à¹àžàž£àž¡ Greenstone à¹àž¡à¹àž¡àžµàžªàžŽàžàžàžŽà¹àžàžàž²àž£à¹àžàžµàž¢àžà¹àžà¹àž£àžàžàž­àž£àžµ _gsdlhome_/tmp
+<li> à¹àžàžŽàžàžà¹àž­àžàžŽàžàžàž¥àž²àžàžàžµà¹àžªàžàž£àžŽàžàžà¹àž àž²àž©àž² perl àžàž·à¹àž­ mkcol.pl
+</ul>
+}  
+
+_textnocontent_ [l=th] {àžà¹àž­àžàžŽàžàžàž¥àž²àžà¹àžàžµà¹àž¢àž§àžàž±àžàžàž±àž§àž£àž§àžàž£àž§àž¡: à¹àž¡à¹àž¡àžµàžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžàž°à¹àžà¹àžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹
+àž¥àž­àžà¹àž£àžŽà¹àž¡àžàž±àž§àž£àž§àžàž£àž§àž¡à¹àž«àž¡à¹àžàž±à¹àžà¹àžà¹àžà¹àžàž­àžµàžàžàž£àž±à¹àž}  
+
+_textrestart_ [l=th] {à¹àž£àžŽà¹àž¡àžàž±àž§àž£àž§àžàž£àž§àž¡à¹àž«àž¡à¹}  
+
+_textreloaderror_ [l=th] {àž¡àžµàžà¹àž­àžàžŽàžàžàž¥àž²àžà¹àžàžŽàžàžàž¶à¹àžàž£àž°àž«àž§à¹àž²àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹  àžàž¶à¹àžàž­àž²àžà¹àžàž·à¹àž­àžàž¡àž²àžàž²àžà¹àžàž£à¹àžàž£àž¡ Greenstone à¹àžàžŽàžàžàž§àž²àž¡àžªàž±àžàžªàž
+àžàž²àžàžàž²àž£à¹àžà¹àžàžžà¹àž¡ "à¹àž«àž¥àžà¹àž«àž¡à¹" àž«àž£àž·àž­ "àž¢à¹àž­àžàžàž¥àž±àž" à¹àžà¹àžàž£àž²àž§à¹à¹àžàž­àž£à¹àžàž­àžàžàžžàž (àžàž£àžžàžàž²àžàž¢àž²àž¢àž²àž¡àž«àž¥àžµàžà¹àž¥àžµà¹àž¢àžàžàž²àž£à¹àžà¹àžàžžà¹àž¡à¹àž«àž¥à¹àž²àžàžµà¹
+àžàžàž°àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžà¹àž§àž¢àžàž±àž§àž£àž§àžàž£àž§àž¡)  àžàž­à¹àžàž°àžàž³à¹àž«à¹àžàžžàžà¹àž£àžŽà¹àž¡àžà¹àžàžàž±àž§àž£àž§àžàž£àž§àž¡à¹àž«àž¡à¹àžàž±à¹àžà¹àžà¹à¹àž£àž}  
+
+_textexptsuc_ [l=th] {àžàž­àž¥à¹àž¥àžàžàž±àž _cgiargbc1dirname_ collection à¹àžà¹àž£àž±àžàžàž²àž£àžªà¹àžàž­àž­àžà¹àžàž¢àž±àžà¹àžà¹àž£àžàžàž­àž£àžµ
+_gsdlhome_/tmp/exported\__cgiargbc1dirname_ à¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§
+}  
+
+_textexptfail_ [l=th] {<p>à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžªà¹àžàž­àž­àžàžàž­àž¥à¹àž¥àžàžàž±àž _cgiargbc1dirname_ à¹àžà¹
+
+<p>àžàž±à¹àžàžàžµà¹àž­àž²àžàžàž°à¹àžàžŽàžàžàž²àžàžàž²àž£àžàžŽàžàžàž±à¹àžà¹àžàž£à¹àžàž£àž¡ Greenstone à¹àžàž¢à¹àž¡à¹à¹àžà¹àžàžŽàžàžàž±à¹àžàžàž­àž¡à¹àžà¹àžàžàžà¹àžàžµà¹àžàž³à¹àžà¹àž
+àžàžµà¹àžªàžàž±àžàžªàžàžžàžàžàž±àžàžà¹àžàž±àž "àžªà¹àžàž­àž­àžà¹àžàž¢àž±àžàžàžµàžàžµàž£àž­àž¡" 
+<ul>
+
+ <li>àžà¹àž²àžàžžàžàžàžŽàžàžàž±à¹àžà¹àžàž£à¹àžàž£àž¡ Greenstone àž£àžžà¹àžàžà¹àž³àžàž§à¹àž² 2.70 àžàž²àžàžàžµàžàžµàž£àž­àž¡  àžàž­àž¡à¹àžà¹àžàžàžà¹à¹àž«àž¥à¹àž²àžàžµà¹àžàž°à¹àž¡à¹à¹àžà¹àž£àž±àžàžàžŽàžàžàž±à¹àž
+ àžàž­àžàžàž²àžàžàžžàžàžàž°à¹àž¥àž·àž­àžàžàžŽàžàžàž±à¹àžàžàž­àž¡à¹àžà¹àžàžàžà¹à¹àž«àž¥à¹àž²àžàžµà¹àž£àž°àž«àž§à¹àž²àžàžàž²àž£àžàžŽàžàžàž±à¹àžà¹àžàž "àžàž³àž«àžàžà¹àž­àž"
+ àžàžžàžàžªàž²àž¡àž²àž£àžà¹àžàžŽà¹àž¡àžàž­àž¡à¹àžà¹àžàžàžà¹à¹àž«àž¥à¹àž²àžàžµà¹à¹àžà¹àž²à¹àžàž¢àž±àžàžàž²àž£àžàžŽàžàžàž±à¹àžàžàž­àžàžàžžàžà¹àžà¹àžà¹àž§àž¢àžàž²àž£à¹àž£àžµàž¢àžà¹àžà¹àžàž£àž°àžàž§àžàžàž²àž£àžàžŽàžàžàž±à¹àžàž­àžµàžàžàž£àž±à¹àž
+
+ <li>àžà¹àž²àžàžžàžàžàžŽàžàžàž±à¹àžà¹àžàž£à¹àžàž£àž¡ Greenstone àžàž²àžàžàž²àž£à¹àžàžàžà¹àž²àž¢àžàž²àžà¹àž§à¹àž àžàžžàžàžàž³à¹àžà¹àžàžà¹àž­àžàžàž²àž§àžà¹à¹àž«àž¥àžà¹àž¥àž°àžàžŽàžàžàž±à¹àžà¹àžàžà¹àžàžà¹àžàžŽà¹àž¡à¹àžàžŽàž¡
+ à¹àžàž·à¹àž­à¹àžàžŽàžà¹àžà¹àžàž²àžàžàž±àžàžà¹àžàž±àžàžàžµà¹  àžàž£àžžàžàž²à¹àžàž¢àž±àž <a href="http://www.greenstone.org">http://www.greenstone.org</a>
+ àž«àž£àž·àž­  <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">àž£àž²àž¢àžàž²àž£àž­àžµà¹àž¡àž¥</a>
+ à¹àžàž·à¹àž­àžàž¹àž£àž²àž¢àž¥àž°à¹àž­àžµàž¢àžà¹àžàžŽà¹àž¡à¹àžàžŽàž¡
+
+</ul> }  
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=th] {
+<p> à¹àžàž£àžàž£àž°àžàžžàžà¹àž­àž¡àž¹àž¥à¹àžà¹àž¡àžà¹àž­à¹àžàžàžµà¹ à¹àž¥àž°àžàž¥àžŽàžàžàžµà¹ _textintro_ àžà¹àž²àžàž¥à¹àž²àž </p>
+}  
+
+_textcaec_ [l=th] {àžàž²àž£à¹àžàžŽà¹àž¡àž£àž²àž¢àžàž²àž£à¹àžà¹àž²à¹àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž¡àžµàž­àž¢àž¹à¹}  
+_textbild_ [l=th] {àžàž²àžàž£àž²àž¢àžàž²àž£}  
+_textintro_ [l=th] {à¹àž¥àž·àž­àžà¹àžà¹àž¡}  
+_textconfirm_ [l=th] {àžàž³àž¢àž·àžàž¢àž±àž}  
+_textselect_ [l=th] {à¹àž¥àž·àž­àžàžàž­àž¥à¹àž¥àžàžàž±àž}  
+_textmeta_ [l=th] {àž£àž°àžàžžà¹àž¡àžàž²àžàž²àžàž²}  
+_textselectoption_ [l=th] {à¹àž¥àž·àž­àžàžàž­àž¥à¹àž¥àžàžàž±àž ...}  
+
+_texttryagain_ [l=th] {àžàž£àžžàžàž² <a href="_httppagedepositor_" target=_top>à¹àž£àžŽà¹àž¡àžà¹àžà¹àžàž£à¹àžàž£àž¡àžàž²àž</a>
+à¹àž¥àž°àž¥àž­àžàž­àžµàžàžàž£àž±à¹àž}  
+
+_textselectcol_ [l=th] {à¹àž¥àž·àž­àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžàžžàžàžà¹àž­àžàžàž²àž£à¹àžàžŽà¹àž¡à¹àž­àžàžªàž²àž£à¹àž«àž¡à¹}  
+_textfilename_ [l=th] {àžàž·à¹àž­à¹àžà¹àž¡}  
+_textfilesize_ [l=th] {Filesize}  
+
+_textretcoll_ [l=th] {àžàž¥àž±àžà¹àžàž¢àž±àžà¹àžàž£à¹àžàž£àž¡àžàž²àž}  
+
+
+_texttmpfail_ [l=th] {à¹àžàž£à¹àžàž£àž¡àžàž²àžà¹àž¡à¹àžªàž²àž¡àž²àž£àžàž­à¹àž²àžàž«àž£àž·àž­à¹àžàžµàž¢àžàž¥àžà¹àžà¹àž¡àžàž±à¹àž§àžàž£àž²àž§ àž«àž£àž·àž­à¹àžà¹àž£àžàžàž­àž£àžµà¹àžà¹
+àžªàž²à¹àž«àžàžžàžàžµà¹àž­àž²àžà¹àžà¹àžà¹àžà¹àž¡àžµàžàž±àžàžàžµà¹:
+<ul>
+<li> Greenstone à¹àž¡à¹àž¡àžµàžªàžŽàžàžàžŽà¹àžàžàž²àž£àž­à¹àž²àž/à¹àžàžµàž¢àžà¹àžà¹àž£àžàžàž­àž£àžµ _gsdlhome_/tmp
+</ul>}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=th] {à¹àžàž£à¹àžàž£àž¡ Greenstone à¹àžà¹àžàžàžžàžàžàž­àžàžàž­àžàžà¹à¹àž§àž£à¹àžàžµà¹àž¡àžµàžàž§àž²àž¡àžªàž²àž¡àž²àž£àžà¹àžàžàž²àž£àž£àž­àžàž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àžàž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥
+à¹àž¥àž°àžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹  àžàž¶à¹àžà¹àžà¹àžà¹àžàž§àžàž²àžà¹àž«àž¡à¹à¹àžàžàž²àž£àžàž±àžàž£àž°à¹àžàžµàž¢àžà¹àž¥àž°à¹àžàž¢à¹àžàž£à¹àžà¹àž­àž¡àž¹àž¥àžàž
+àž­àžŽàžà¹àžàž­àž£à¹à¹àžà¹àž àž«àž£àž·àž­àžàžàžàžµàžàžµàž£àž­àž¡
+à¹àžàž£à¹àžàž£àž¡ Greenstone àžàž¹àžàžàž±àžàžàž²àžàž¶à¹àžàž àž²àž¢à¹àžà¹à¹àžàž£àžàžàž²àž£ New Zealand Digital Library à¹àžàž¢àž¡àž«àž²àž§àžŽàžàž¢àž²àž¥àž±àžà¹àž§àžàž²à¹àž
+à¹àž¥àž°àž¡àžµàžàž²àž£à¹àžàžàžà¹àž²àž¢àž­àž­àžà¹àžàžà¹àž§àž¢àžàž§àž²àž¡àž£à¹àž§àž¡àž¡àž·àž­àžàž­àžàž¢àž¹à¹àžàžªà¹àžà¹àž¥àž° Human Info NGO
+à¹àžàž£à¹àžàž£àž¡ Greenstone à¹àžà¹àžàžàž­àžàžà¹à¹àž§àž£à¹àž£àž«àž±àžªà¹àžàžŽàž àžàž¶à¹àžàžªàž²àž¡àž²àž£àžàžàž¹àž£àž²àž¢àž¥àž°à¹àž­àžµàž¢àžà¹àžà¹àžàž²àž
+<i>http://greenstone.org</i> àž àž²àž¢à¹àžà¹àž¥àžŽàžàžªàžŽàžàžàžŽà¹àžàž­àž GNU
+}  
+
+_textgreenstone2_ [l=th] {à¹àž§à¹àžà¹àžàžà¹àžàž­àž New Zealand Digital Library (<a
+href="http://nzdl.org">http://nzdl.org</a>) àžàž£àž°àžàž­àžàžà¹àž§àž¢àžàž­àž¥à¹àž¥àžàžàž±àžàžàž±àž§àž­àž¢à¹àž²àžàžàž³àžàž§àžàž¡àž²àž
+à¹àžàž¢àžàž­àž¥à¹àž¥àžàžàž±àžàžàž±à¹àžàž«àž¡àžàžàžµà¹àžªàž£à¹àž²àžàžàž¶à¹àžàžà¹àž§àž¢àžàž­àžàžà¹à¹àž§àž£à¹ Greenstone àžàž¶à¹àžàžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžàžàžàž¥àž­àžà¹àžà¹àžàž²àžà¹àžà¹àžàž±à¹àž§à¹àž
+àžàž±àž§àž­àž¢à¹àž²àžà¹àž«àž¥à¹àž²àžàžµà¹àžàž°à¹àžªàžàžàžàž±àž§àž­àž¢à¹àž²àžàžàž±àž§à¹àž¥àž·àž­àžàžàž­àžàžàž²àž£àžà¹àžàž«àž²à¹àž¥àž°à¹àž£àžµàž¢àžàžàž¹
+àž£àž§àž¡àžàž¶àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžàž àž²àž©àž²àž­àž²àž£àžàžŽàž àžàžµàž àžàž£àž±à¹àžà¹àžšàžª à¹àž¡àž²àž£àžµ à¹àž¥àž°àžªà¹àžàž àž£àž§àž¡àžàž±à¹àžàž àž²àž©àž²àž­àž±àžàžàž€àž©
+àžàž­àžàžàž²àžàžàžµà¹ àž¢àž±àžàž¡àžµàžàž­àž¥à¹àž¥àžàžàž±àžàžàžàžàž£àžµàž­àžµàžàžà¹àž§àž¢
+}  
+
+_textplatformtitle_ [l=th] {à¹àžàž¥àžàžàž­àž£à¹àž¡}  
+_textgreenstone3_ [l=th] {à¹àžàž£à¹àžàž£àž¡ Greenstone àžªàž²àž¡àž²àž£àžàžàž³à¹àžàžŽàžàžàž²àž£à¹àžà¹àžàžàž£àž°àžàžàžàžàžŽàžàž±àžàžŽàžàž²àž£àž§àžŽàžà¹àžàžªà¹, àž¢àž¹àžàžŽàžàžà¹ à¹àž¥àž° à¹àž¡àž à¹àž­à¹àž­àžª à¹àž­à¹àžàžà¹
+àžàžžàžà¹àžàž£à¹àžàž£àž¡àžªàž³àž«àž£àž±àžà¹àžàžàžà¹àž²àž¢àžàžµà¹àžàž£àž°àžàž­àžàžà¹àž§àž¢ àžàžžàžà¹àžàž£à¹àžàž£àž¡àžàž£à¹àž­àž¡à¹àžà¹àžàž²àžàžªàž³àž«àž£àž±àžàž£àž°àžàžàžàžàžŽàžàž±àžàžŽàžàž²àž£àž§àžŽàžà¹àžàžªà¹àžàžžàžàž£àžžà¹àž àž£àž§àž¡àžàž±à¹àžàž¥àžŽàžàžžàžàžà¹à¹àž¥àž°à¹àž¡àž à¹àž­à¹àž­àžª à¹àž­à¹àžàžà¹  àžàž­àžàžàž²àžàžàžµà¹àžàžžàžà¹àžàž£à¹àžàž£àž¡àž¢àž±àžàžàž£àž°àžàž­àžà¹àžàžà¹àž§àž¢à¹àžà¹àžàžà¹àžàžàžàž±àžàžàžµà¹àžªàž¡àžàž¹àž£àžà¹àžªàž³àž«àž£àž±àžàž£àž°àžàž àžàž¶à¹àžàžªàž²àž¡àž²àž£àžàžàž­àž¡à¹àžàž¥à¹à¹àžà¹à¹àžàž¢à¹àžà¹à¹àž¡à¹àžàž£àžàž­àžàžà¹ C++ àž«àž£àž·àž­ gcc à¹àžà¹
+à¹àžàž£à¹àžàž£àž¡ Greenstone àžªàž²àž¡àž²àž£àžàžàž³àžàž²àžàž£à¹àž§àž¡àžàž±àžàžàž­àžàžà¹à¹àž§àž£à¹àžàžµà¹à¹àžàžµà¹àž¢àž§àžà¹àž­àžàžàž¶à¹àžà¹àžàžŽàžà¹àž«à¹à¹àžà¹àžàž²àžà¹àžà¹àžàž£àžµ à¹àžà¹àž Apache Webserver à¹àž¥àž° PERL à¹àžà¹àž­àžµàžàžà¹àž§àž¢
+àž«àžà¹àž²àžàž­àžàž¹à¹à¹àžà¹àž£àž°àžàžàžàž°à¹àžà¹à¹àž§à¹àžà¹àžàž£àž²àž§à¹à¹àžàž­àž£à¹à¹àžàžàž²àž£à¹àžªàžàžàžàž¥ àžàž¶à¹àžà¹àžàž¢àžàžàžàžŽàžàž°à¹àžà¹àž Netscape Navigator àž«àž£àž·àž­ Internet Explorer}  
+
+_textgreenstone4_ [l=th] {àžàž­àž¥à¹àž¥àžàžàž±àžà¹àž­àžàžªàž²àž£àžàž³àžàž§àžàž¡àž²àžà¹àžà¹àžàž¹àžà¹àžàžàžà¹àž²àž¢àž­àž­àžà¹àžà¹àžàž£àž¹àžà¹àžàžàžàž­àžàžàžµàžàžµàž£àž­àž¡à¹àžàž¢à¹àžà¹àžàž­àžàžà¹à¹àž§àž£à¹ Greenstone
+àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž <i>Humanity Development Library</i> àžàž¶à¹àžàžàž£àž£àžàžžàžªàžŽà¹àžàžàžŽàž¡àžà¹àžàž³àžàž§àž
+1,230 àžàžàž±àžàžàžµà¹àž¡àžµà¹àžàž·à¹àž­àž«àž²àžàž±à¹àžà¹àžà¹àžà¹àž²àžàžàž±àžàžàžµàžàžàžàž¶àžàžàž²àž£àžàž³àžàž±àžàžà¹àž³à¹àžªàžµàž¢  àžàžµàžàžµà¹àžà¹àžàžàžµà¹àžªàž²àž¡àž²àž£àžà¹àžà¹àžàž²àžà¹àžà¹àžàž
+àž­àžžàžàžàž£àžà¹àžàž­àž¡àžàžŽàž§à¹àžàž­àž£à¹àžàžµà¹àž¡àžµàžàž£àž°àžªàžŽàžàžàžŽàž àž²àžà¹àž¡à¹àžªàž¹àžàžàž±àž à¹àžà¹àž àž­àžžàžàžàž£àžà¹àžàžµà¹à¹àžà¹àžàž±àžà¹àžàž¢àžàž±à¹àž§à¹àžà¹àžàžàž£àž°à¹àžàžšàžàž³àž¥àž±àžàžàž±àžàžàž²
+àžà¹àž­àž¡àž¹àž¥à¹àž¥àž°à¹àžàž·à¹àž­àž«àž²àžà¹àž²àžà¹ àžªàž²àž¡àž²àž£àžà¹àžà¹àž²àžàž¶àžà¹àžà¹à¹àžàž¢àžàž²àž£àžà¹àžàž«àž² àžàž²àž£à¹àž£àžµàž¢àžàžàž¹àžà¹àž§àž¢àž«àž±àž§à¹àž£àž·à¹àž­àž àžàž²àž£à¹àž£àžµàž¢àžàžàž¹àžà¹àž§àž¢àžàž·à¹àž­à¹àž£àž·à¹àž­àž
+àžàž²àž£à¹àž£àžµàž¢àžàžàž¹àžà¹àž§àž¢àžàž·à¹àž­àž­àžàžà¹àžàž£ àžàž²àž£à¹àž£àžµàž¢àžàžàž¹àž£àž²àž¢àžàž²àž£àž§àžŽàžàžµà¹àžà¹ à¹àž¥àž°à¹àžàž¢àžàž²àž£àžªàžžà¹àž¡àžàž¹àž«àžà¹àž²àžàžàž«àžàž±àžàžªàž·àž­
+}  
+
+_textcustomisationtitle_ [l=th] {àžàž²àž£àžàž³àž«àžàžà¹àž­àž}  
+_textgreenstone5_ [l=th] {Greenstone àžàž¹àžàž­àž­àžà¹àžàžàž¡àž²à¹àžà¹àžàžàžŽà¹àžšàž©à¹àžàž·à¹àž­à¹àž«à¹àž¡àžµàžàž§àž²àž¡àž¢àž·àžàž«àž¢àžžà¹àžàžªàž¹àžà¹àž¥àž°àžªàž²àž¡àž²àž£àžàžàž³àž«àžàžàžà¹àž²à¹àž­àžà¹àžà¹
+à¹àž­àžàžªàž²àž£à¹àž¥àž°àž£àž¹àžà¹àžàžà¹àž¡àžàž²àžàž²àžàž²à¹àž«àž¡à¹àžàž¹àžàžàž³à¹àž«à¹àžªàž°àžàž§àžàžàž¶à¹àžàžà¹àž§àž¢àžàž²àž£à¹àžàžµàž¢àž "àžàž¥àž±à¹àžàž­àžŽàž" (à¹àžàž àž²àž©àž² Perl)
+à¹àžàž£àž¹àžà¹àžàžà¹àžàžµàž¢àž§àžàž±àž à¹àžàž£àžàžªàž£à¹àž²àžàžàž²àž£à¹àž£àžµàž¢àžàžàž¹à¹àž¡àžàž²àžàž²àžàž²à¹àž«àž¡à¹àžªàž²àž¡àž²àž£àžàžàž£àž°àžàž³à¹àžà¹àžà¹àž§àž¢àžàž²àž£à¹àžàžµàž¢àžà¹àžà¹àž "àžàž¥àž²àžªàžªàžŽàžàž²àž¢à¹àž­àž­àž£à¹"
+àž£àž¹àžàž¥àž±àžàž©àžà¹àžàž­àžàž«àžà¹àž²àžàž­àžàž¹à¹à¹àžà¹àž£àž°àžàžàžªàž²àž¡àž²àž£àžàžàž£àž±àžà¹àžàž¥àžµà¹àž¢àžà¹àžà¹à¹àžàž¢àžàž²àž£à¹àžà¹ "à¹àž¡à¹àžàž£" 
+àžàžµà¹à¹àžàžµàž¢àžàžà¹àž§àž¢àž àž²àž©àž²à¹àž¡à¹àžàž£àž­àž¢à¹àž²àžàžà¹àž²àž¢  à¹àžàž£à¹àžàžàž­àž¥ Corba àž¢àž­àž¡à¹àž«à¹à¹àž­à¹àžàžàžà¹ (à¹àžà¹àž à¹àžàž àž²àž©àž²àžàž²àž§àž²)
+à¹àžà¹àžªàžŽà¹àžàžàžµà¹àž¡àžµàž­àž¢àž¹à¹àžàž±à¹àžàž«àž¡àžàžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž­àžàžªàž²àž£à¹àžà¹ 
+àžàž­àžàžàž²àžàžàžµà¹ à¹àžà¹àžàžà¹àžàžàžàž±àžà¹àžàž àž²àž©àž² C++ à¹àž¥àž° Perl àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àž à¹àž¥àž°àžªàž²àž¡àž²àž£àžà¹àžà¹àž²àžàž¶àžà¹àžàž·à¹àž­àžàž³àžàž²àž£à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àžà¹àžà¹
+}  
+
+_textdocumentationtitle_ [l=th] {à¹àž­àžàžªàž²àž£}  
+_textdocuments_ [l=th] {àž¡àžµà¹àž­àžàžªàž²àž£à¹àžàžŽà¹àž¡à¹àžàžŽàž¡àžªàž³àž«àž£àž±àžàžàž­àžàžà¹à¹àž§àž£à¹ Greenstone }  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=th] {àž£àž²àž¢àžàž·à¹àž­àžªàž³àž«àž£àž±àžàžªà¹àžàžàžàž«àž¡àž²àž¢}  
+_textmailinglist_ [l=th] {àž¡àžµà¹àž¡àž¥àž¥àžŽàžàž¥àžŽàžªàžà¹àžàžµà¹à¹àžà¹àž£àž±àžàžàž²àž£àžàž³àž«àžàžàžàž¶à¹àžà¹àžàž·à¹àž­à¹àžà¹à¹àžà¹àžàžàžµà¹à¹àž¥àžà¹àžàž¥àžµà¹àž¢àžàžàž§àž²àž¡àžàžŽàžà¹àž«à¹àžà¹àžàžµà¹àž¢àž§àžàž±àžàžàž­àžàžà¹à¹àž§àž£à¹àž«à¹àž­àžàžªàž¡àžžàžàžàžŽàžàžŽàžàž±àž¥àžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone àžàž¹à¹à¹àžà¹à¹àžàž£à¹àžàž£àž¡ Greenstone àžàžµà¹à¹àžà¹àžàž²àžàž­àž¢àž¹à¹àžàž§àž£àžàžŽàžàž²àž£àžàž²à¹àžà¹àž²àž£à¹àž§àž¡à¹àžà¹àž¡àž¥àž¥àžŽàžàž¥àžŽàžªàžà¹àžàžµà¹à¹àž¥àž°à¹àžà¹àž²àž£à¹àž§àž¡àžàž²àž£àžªàžàžàžàž²àžà¹àž§àž¢
+à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àžªàž¡àž±àžàž£àžªàž¡àž²àžàžŽàž à¹àž«à¹à¹àžàžàžµà¹ <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>
+
+à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àžªà¹àžàžà¹àž­àžàž§àž²àž¡à¹àžàž¢àž±àžàž¥àžŽàžªàžà¹ à¹àž«à¹àžªà¹àžà¹àžàž¢àž±àž <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>
+}  
+
+_textbugstitle_ [l=th] {àžà¹àž­àžàžŽàžàžàž¥àž²àž}  
+_textreport_ [l=th] {à¹àž£àž²àžà¹àž­àžàžàž²àž£àžàž£àž§àžàžªàž­àžà¹àž«à¹à¹àžà¹à¹àžàž§à¹àž²àžàž­àžàžà¹à¹àž§àž£à¹àžàžµà¹àž¢àž±àžàžàžàžàž³àžàž²àžà¹àžà¹àžàžàžàžàžŽ àžàž£àžžàžàž²àžªà¹àžàž£àž²àž¢àžàž²àžàžà¹àž­àžàžŽàžàžàž¥àž²àžà¹àžà¹ à¹àžàž¢àž±àž
+<a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">àž£àž²àž¢àžàž²àž£àž­àžµà¹àž¡àž¥</a>}  
+
+_textgs3title_ [l=th] {à¹àžàžàž²àž}  
+_textgs3_ [l=th] {à¹àžàž£à¹àžàž£àž¡ Greenstone 3 à¹àžà¹àžà¹àžàž£à¹àžàž£àž¡àž£àžžà¹àžàžàžµà¹àž­àž­àžà¹àžàž à¹àž¥àž°àžàž±àžàžàž³àžàž¶à¹àžà¹àž«àž¡à¹àžàž±à¹àžàž«àž¡àž
+àžàž¶à¹àžàž¢àž±àžàžàžàžà¹àž­àžàžµàžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone 2 (àž£àžžà¹àžàžàž±àžàžàžžàžàž±àž) à¹àž§à¹ àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž 
+àžàž²àž£àžªàžàž±àžàžªàžàžžàžà¹àžàžàž«àž¥àž²àž¢àž àž²àž©àž² àž«àž¥àž²àž¢à¹àžàž¥àžàžàž­àž£à¹àž¡ à¹àž¥àž°àž¡àžµàžàž§àž²àž¡àž¢àž·àžàž«àž¢àžžà¹àžà¹àžàžàž³àž«àžàžàžà¹àž²àžªàž¹àž
+àžàž­àžàžàž²àžàžàžµà¹ à¹àžàž£à¹àžàž£àž¡ Greenstone 3 àž¢àž±àžàž£àž§àž¡àžàžžàžàž¥àž±àžàž©àžàž°àžàž±à¹àžàž«àž¡àžàžàž­àžàž£àž°àžàžàžàžµà¹àž¡àžµàž­àž¢àž¹à¹ à¹àž¥àž°àž¢àž±àžàžªàž²àž¡àž²àž£àžà¹àžà¹àžàž²àžàžàž±àžàž£àžžà¹àžà¹àžà¹àž²à¹àžà¹
+àžàž±à¹àžàžàž·àž­ à¹àžàž£à¹àžàž£àž¡àžàžµà¹àžªàž²àž¡àž²àž£àžàžªàž£à¹àž²àžà¹àž¥àž°à¹àž£àžµàž¢àžà¹àžà¹àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž¡àžµàž­àž¢àž¹à¹à¹àž¥à¹àž§à¹àžà¹à¹àžàž¢à¹àž¡à¹àžà¹àž­àžàžàž³àžàž²àž£à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àžà¹àžà¹
+à¹àžàž·à¹àž­àžàžàž²àžà¹àžàžµàž¢àžàžà¹àž§àž¢àž àž²àž©àž²àžàž²àž§àž² àž£àž°àžàžàžàž¶àžà¹àžà¹àž£àž±àžàžàž²àž£àžàž±àžà¹àžàž£àžàžªàž£à¹àž²àžà¹àžàž£àž¹àžà¹àžàžàžàž­àžà¹àžàž£àž·àž­àžà¹àž²àž¢àžàž­àžà¹àž¡àžàž¹àž¥àžàžµà¹à¹àžà¹àžàž­àžŽàžªàž£àž°àžà¹àž­àžàž±àž
+àžàž¶à¹àžàžªàž·à¹àž­àžªàž²àž£àžàž±àžàžà¹àž§àž¢ XML àžà¹àž§àž¢à¹àž«àžàžžàžàžµà¹à¹àžàž£à¹àžàž£àž¡ Greenstone 3 àžàž¶àžàžàž³àžàž²àžà¹àžàž¥àž±àžàž©àžàž°à¹àžàž£àž·àž­àžà¹àž²àž¢à¹àžàžàžàž²àž£àžàž£àž°àžàž²àž¢
+à¹àž¥àž°àžªàž²àž¡àž²àž£àžà¹àžà¹àžàž²àžàžà¹àž²àž¡à¹àžàžŽàž£à¹àžà¹àž§àž­àž£à¹àžàžµà¹àžà¹àž²àžàžàž±àžà¹àžà¹à¹àž¡àž·à¹àž­àžàž³à¹àžà¹àž
+àžàž²àž£àž­àž­àžà¹àžàžà¹àžàž¥àž±àžàž©àžàž°àžàž­àžà¹àž¡àžàž¹àž¥àžàžµà¹àžà¹àž§àž¢à¹àžàžŽà¹àž¡àžàž§àž²àž¡àž¢àž·àžàž«àž¢àžžà¹àžà¹àž¥àž°àžàž²àž£àžàž±àžàžàž²àžà¹àž­àž¢àž­àžàžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone à¹àžà¹
+à¹àž­àžàžªàž²àž£à¹àž¥àž°àž£àžžà¹àžàžàžàž¥àž­àžàžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone 3 àžªàž²àž¡àž²àž£àžàžàž²àž§àžà¹à¹àž«àž¥àžà¹àžà¹àžàžµà¹ <a href="http://www.greenstone.org/greenstone3.html">àž«àžà¹àž²à¹àž£àžàžàž­àž Greenstone 3</a>}  
+
+_textcreditstitle_ [l=th] {à¹àžàž£àžàžŽàž}  
+
+_textwhoswho_ [l=th] {àžàž­àžàžà¹à¹àž§àž£à¹ Greenstone à¹àžàžŽàžàžàž¶à¹àžàžàž²àžàžàž§àž²àž¡àžàž¢àž²àž¢àž²àž¡à¹àžàžàž²àž£àž£à¹àž§àž¡àž¡àž·àž­àžàž±àžàžàž­àžàžàžžàžàžàž¥àž«àž¥àž²àž¢àžà¹àž²àž¢
+Rodger McNab à¹àž¥àž° Stefan Boddie à¹àžà¹àžàžªàžàž²àžàžàžŽàžàž«àž¥àž±àžà¹àž¥àž°àžàž¹à¹àž¥àžàž¡àž·àž­àžàžàžŽàžàž±àžàžŽàžàž²àž£ à¹àžàž¢à¹àžà¹àž£àž±àžàžàž§àž²àž¡àž£à¹àž§àž¡àž¡àž·àž­àžàž²àž
+David Bainbridge, George Buchanan, Hong Chen, Michael Dewsnip, Katherine Don, Elke Duncker, Carl Gutwin, Geoff Holmes, Dana McKay, John
+McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd
+Reed, Bill Rogers, John Thompson, à¹àž¥àž° Stuart Yeates
+àžªàž¡àž²àžàžŽàžàž­àž·à¹àžà¹ àžàž­àžà¹àžàž£àžàžàž²àž£ New Zealand Digital Library àžàž¹à¹à¹àž«à¹àžàž³à¹àžàž°àžàž³à¹àž¥àž°à¹àž£àžàžàž±àžàžàž²àž¥à¹àžà¹àžàžàž²àž£àž­àž­àžà¹àžàžàž£àž°àžàž àžàž£àž°àžàž­àžà¹àžàžà¹àž§àž¢ 
+Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka
+Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols à¹àž¥àž° Lloyd Smith
+àžªàž³àž«àž£àž±àžàžàž¹à¹àžàžµà¹à¹àž«à¹àžàž§àž²àž¡àž£à¹àž§àž¡àž¡àž·àž­àžà¹àž²àžà¹àžàžà¹àžàžàž¥àžŽàžàžªàžŽàžàžàžŽà¹àžàž­àž GNU àžàž¶à¹àžàž­àž¢àž¹à¹à¹àžàžàž­àžàžà¹à¹àž§àž£à¹àžàžµà¹à¹àžàžà¹àžàžà¹àž§àž¢ àžàž¶à¹àžàžàž£àž°àžàž­àžàžà¹àž§àž¢ MG, GDBM, PDFTOHTML, PERL, WGET, WVWARE à¹àž¥àž° XLHTML
+}  
+
+_textaboutgslong_ [l=th] {à¹àžàžµà¹àž¢àž§àžàž±àžàžàž­àžàžà¹à¹àž§àž£à¹ greenstone}  
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=th] {àž£àž²àž¢àžàž·à¹àž­àžàž¹à¹à¹àžà¹àžàž±àžàžàžžàžàž±àž}  
+_textuser_ [l=th] {àžàž¹à¹à¹àžà¹}  
+_textas_ [l=th] {àžªàžàž²àžàž°àžàž±àžàžàžµ}  
+_textgroups_ [l=th] {àžàž¥àžžà¹àž¡}  
+_textcomment_ [l=th] {à¹àžªàžàž­à¹àžàž°àžàž§àž²àž¡àžàžŽàžà¹àž«à¹àž}  
+_textadduser_ [l=th] {à¹àžàžŽà¹àž¡àžàž¹à¹à¹àžà¹à¹àž«àž¡à¹}  
+_textedituser_ [l=th] {à¹àžà¹à¹àž}  
+_textdeleteuser_ [l=th] {àž¥àž}  
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=th] {à¹àžà¹à¹àžàžà¹àž­àž¡àž¹àž¥àžàž¹à¹à¹àžà¹}  
+_textadduser_ [l=th] {à¹àžàžŽà¹àž¡àžàž¹à¹à¹àžà¹à¹àž«àž¡à¹}  
+
+_textaboutusername_ [l=th] {àžàž·à¹àž­àžàž¹à¹à¹àžà¹àžà¹àž­àžàž¡àžµàžàž§àž²àž¡àž¢àž²àž§àž£àž°àž«àž§à¹àž²àž 2 àžàž¶àž 30 àžàž±àž§àž­àž±àžàž©àž£  àžàž¶à¹àžàžªàž²àž¡àž²àž£àžàžàž£àž°àžàž­àžàžà¹àž§àž¢àžàž±àž§àž­àž±àžàž©àž£à¹àž¥àž°àžàž±àž§à¹àž¥àž
+à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àž¡àž«àž±àžàž àž²àž '.' à¹àž¥àž°à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžµàžàž¥à¹àž²àž '_'}  
+
+_textaboutpassword_ [l=th] {àž£àž«àž±àžªàžà¹àž²àžàžà¹àž­àžàž¡àžµàžàž§àž²àž¡àž¢àž²àž§àž£àž°àž«àž§à¹àž²àž 3 àžàž¶àž 128 àžàž±àž§àž­àž±àžàž©àž£  à¹àžàž¢àžªàž²àž¡àž²àž£àžàžàž£àž°àžàž­àžàžà¹àž§àž¢àž­àž±àžàžàž£àž°à¹àž­àžªàžàžµàžàžàžàžŽàžàžµà¹àžªàž²àž¡àž²àž£àžàžàžŽàž¡àžà¹à¹àžà¹ 
+}  
+
+_textoldpass_ [l=th] {àžà¹àž²à¹àžàžàžà¹àž­àž¡àž¹àž¥àžàžµà¹àž§à¹àž²àžàž­àž¢àž¹à¹ àž£àž«àž±àžªàžà¹àž²àžà¹àžàžŽàž¡àžàž°àžàž¹àžà¹àžà¹àžà¹àž§à¹}  
+_textenabled_ [l=th] {à¹àžàžŽàžà¹àžà¹àžàž²àž}  
+_textdisabled_ [l=th] {àžàžŽàžà¹àžà¹àžàž²àž}  
+
+_textaboutgroups_ [l=th] {àžàž¥àžžà¹àž¡àžàž·àž­àž£àž²àž¢àžàž·à¹àž­àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àž àžàž£àžžàžàž²àž­àž¢à¹àž²àžà¹àžªà¹àžà¹àž­àžàž§à¹àž²àžàž«àž¥àž±àžà¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àž}  
+_textavailablegroups_ [l=th] {àžàž¥àžžà¹àž¡àžàž¹à¹à¹àžà¹àžàžµà¹àžàž³àž«àžàžà¹àž§à¹à¹àž¥à¹àž§ àž£àž§àž¡àžàž¶àžàžàž¹à¹àžàž¹à¹àž¥àž£àž°àžàžà¹àž¥àž°àžàž¹à¹à¹àžà¹àž­àž·à¹àžà¹ àžàžµà¹à¹àžà¹àž£àž±àžàžªàžŽàžàžàžŽà¹àžàžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàž£àž°àž¢àž°à¹àžàž¥à¹àžàž¢à¹àžà¹àžªà¹àž§àžàžàžŽàžàžà¹àž­àžàž¹à¹à¹àžà¹àžªàž³àž«àž£àž±àžàžàž£àž£àžàž²àž£àž±àžàž©à¹àž«àž£àž·àž­ Depositor àžàž±àžàžàžµà¹:
+<ul>
+<li><b>administrator</b>: à¹àžà¹àž£àž±àžàžªàžŽàžàžàžŽà¹àžàžàž²àž£à¹àžà¹àž²àžàž¶àžàž«àž£àž·àž­à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àžàžàž²àž£àžàž³àž«àžàžàžà¹àž²à¹àžàžà¹à¹àž¥àž°àžàž±àžàžàžµàžàž¹à¹à¹àžà¹
+<li><b>personal-collections-editor</b>: à¹àžà¹àž£àž±àžàžªàžŽàžàžàžŽà¹àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžªà¹àž§àžàžàž±àž§à¹àž«àž¡à¹
+<li><b><collection-name>-collection-editor</b>: à¹àžà¹àž£àž±àžàžªàžŽàžàžàžŽà¹àžàžàž²àž£àžªàž£à¹àž²àžà¹àž¥àž°à¹àžà¹à¹àžàžàž­àž¥à¹àž¥àžàžàž±àž "collection-name" àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž reports-collection-editor à¹àžà¹àžàžà¹àž
+<li><b>all-collections-editor</b>: à¹àžà¹àž£àž±àžàžªàžŽàžàžàžŽà¹àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžªà¹àž§àžàžàž±àž§à¹àž¥àž°àžàž­àž¥à¹àž¥àžàžàž±àžàžªà¹àž§àžàžàž¥àž²àžà¹àž«àž¡à¹ àž£àž§àž¡àžàž±à¹àžàžªàž²àž¡àž²àž£àžà¹àžà¹à¹àžàžàž­àž¥à¹àž¥àžàžàž±àž <b>àžàž±à¹àžàž«àž¡àž</b> à¹àžà¹
+</ul>}  
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=th] {àž¥àžàžàž¹à¹à¹àžà¹}  
+_textremwarn_ [l=th] {àžàžžàžàžà¹àž­àžàžàž²àž£àž¥àžàžàž¹à¹à¹àžà¹ <b>_cgiargumun_</b> àž­àž­àžàž­àž¢à¹àž²àžàžàž²àž§àž£àž«àž£àž·àž­à¹àž¡à¹}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=th] {à¹àžàž¥àžµà¹àž¢àžàž£àž«àž±àžªàžà¹àž²àž}  
+_textoldpw_ [l=th] {àž£àž«àž±àžªàžà¹àž²àžà¹àžà¹àž²}  
+_textnewpw_ [l=th] {àž£àž«àž±àžªàžà¹àž²àžà¹àž«àž¡à¹}  
+_textretype_ [l=th] {à¹àžªà¹àž£àž«àž±àžªàžà¹àž²àžà¹àž«àž¡à¹àž­àžµàžàžàž£àž±à¹àž}  
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=th] {àž£àž«àž±àžªàžà¹àž²àžàžàž­àžàžàžžàžà¹àžà¹à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àžà¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§}  
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=th] {àžàž·à¹àž­àžàž¹à¹à¹àžà¹à¹àž¡à¹àžàž¹àžàžà¹àž­àž}  
+_textinvalidpassword_ [l=th] {àž£àž«àž±àžªàžà¹àž²àžà¹àž¡à¹àžàž¹àžàžà¹àž­àž}  
+_textemptypassword_ [l=th] {àžàž£àžžàžàž²à¹àžªà¹àž£àž«àž±àžªàžà¹àž²àžà¹àž£àžŽà¹àž¡àžà¹àžàžªàž³àž«àž£àž±àžàžàž¹à¹à¹àžà¹àž£àž²àž¢àžàžµà¹}  
+_textuserexists_ [l=th] {àžàž·à¹àž­àžàž¹à¹à¹àžà¹àžàžµà¹àž¡àžµàž­àž¢àž¹à¹à¹àž¥à¹àž§ àžàž£àžžàžàž²à¹àžªà¹àžàž·à¹àž­àžàž¹à¹à¹àžà¹àž­àž·à¹àž}  
+
+_textusernameempty_ [l=th] {àžàž£àžžàžàž²à¹àžªà¹àžàž·à¹àž­àžàž¹à¹à¹àžà¹àžàž­àžàžàžžàž}  
+_textpasswordempty_ [l=th] {àžàžžàžàžà¹àž­àžà¹àžªà¹àž£àž«àž±àžªàžà¹àž²àžà¹àžà¹àž²àžàž­àžàžàžžàž}  
+_textnewpass1empty_ [l=th] {à¹àžªà¹àž£àž«àž±àžªàžà¹àž²àžà¹àž«àž¡à¹àžàž­àžàžàžžàž à¹àž¥à¹àž§àžàž¶àžàžàžŽàž¡àžà¹àž£àž«àž±àžªàžà¹àž²àžàž­àžµàžàžàž£àž±à¹àž}  
+_textnewpassmismatch_ [l=th] {àž£àž«àž±àžªàžà¹àž²àžà¹àž«àž¡à¹àžàž­àžàžà¹àž²àžàžàž±à¹àžàžªàž­àžàžà¹àž²à¹àž¡à¹àžàž£àžàžàž±àž}  
+_textnewinvalidpassword_ [l=th] {àžàžžàžà¹àžªà¹àž£àž«àž±àžªàžà¹àž²àžà¹àž¡à¹àžàž¹àžàžà¹àž­àž}  
+_textfailed_ [l=th] {àžàž·à¹àž­àžàž¹à¹à¹àžà¹àž«àž£àž·àž­àž£àž«àž±àžªàžà¹àž²àžàžàž­àžàžàžžàžà¹àž¡à¹àžàž¹àžàžà¹àž­àž}  
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=th] {àž«àž¡àž²àž¢à¹àž¥àžàž£àžžà¹àžàžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone}  
+_textframebrowser_ [l=th] {àžàžžàžàžà¹àž­àžàž¡àžµà¹àžàž£àž²àž§à¹à¹àžàž­àž£à¹à¹àžàžàžàžµà¹à¹àžà¹à¹àžàž£àž¡à¹àžà¹à¹àžàž·à¹àž­àžàž¹àžà¹àž­àž¡àž¹àž¥}  
+_textusermanage_ [l=th] {àžàž²àž£àžàž±àžàžàž²àž£àžàž¹à¹à¹àžà¹}  
+_textlistusers_ [l=th] {à¹àžªàžàžàž£àž²àž¢àžàž²àž£àžàž¹à¹à¹àžà¹}  
+_textaddusers_ [l=th] {à¹àžàžŽà¹àž¡àžàž¹à¹à¹àžà¹à¹àž«àž¡à¹}  
+_textchangepasswd_ [l=th] {à¹àžàž¥àžµà¹àž¢àžàž£àž«àž±àžªàžà¹àž²àž}  
+_textinfo_ [l=th] {àžà¹àž­àž¡àž¹àž¥àžàž²àžà¹àžàžàžàžŽàž}  
+_textgeneral_ [l=th] {àžàž±à¹àž§à¹àž}  
+_textarguments_ [l=th] {àž­àž²àž£à¹àžàžŽàž§à¹àž¡àžàžà¹}  
+_textactions_ [l=th] {àžàž²àž£àžàž£àž°àžàž³}  
+_textbrowsers_ [l=th] {à¹àžàž£àž²àž§à¹àžàž­àž£à¹}  
+_textprotocols_ [l=th] {à¹àžàž£à¹àžàžàž­àž¥}  
+_textconfigfiles_ [l=th] {à¹àžà¹àž¡àžàž²àž£àžàž³àž«àžàžàžà¹àž²}  
+_textlogs_ [l=th] {à¹àžà¹àž¡àžàž±àžàžàž¶àž}  
+_textusagelog_ [l=th] {à¹àžà¹àž¡àžàž±àžàžàž¶àžàžàž²àž£à¹àžà¹àžàž²àž}  
+_textinitlog_ [l=th] {à¹àžà¹àž¡àžàž±àžàžàž¶àžà¹àž£àžŽà¹àž¡àžà¹àž}  
+_texterrorlog_ [l=th] {à¹àžà¹àž¡àžàž±àžàžàž¶àžàžà¹àž­àžàžŽàžàžàž¥àž²àž}  
+_textadminhome_ [l=th] {àž«àžà¹àž²à¹àž£àžàžàž­àžàžàž¹à¹àžàž¹à¹àž¥àž£àž°àžàž}  
+_textreturnhome_ [l=th] {àž«àžà¹àž²à¹àž£àžàžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone}  
+_titlewelcome_ [l=th] {àžàž²àž£àžàž¹à¹àž¥àž£àž°àžàž}  
+_textmaas_ [l=th] {àžàž£àžŽàžàž²àž£àžà¹àž²àžàžàž²àž£àžàž³àž£àžžàžàž£àž±àžàž©àž²à¹àž¥àž°àžàž¹à¹àž¥àž£àž°àžàžàžàžµà¹àžªàž²àž¡àž²àž£àžà¹àžà¹àžàž²àžà¹àžà¹àž¡àžµàžàž±àžàžàžµà¹:}  
+_textvol_ [l=th] {àžàž¹à¹àžà¹àž¡àžàž±àžàžàž¶àžà¹àžàžàž­àž­àžà¹àž¥àžà¹}  
+_textcmuc_ [l=th] {àžªàž£à¹àž²àž àžàž³àž£àžžàžàž£àž±àžàž©àž² à¹àž¥àž°àžàž£àž±àžàžàž£àžžàžàžàž­àž¥à¹àž¥àžàžàž±àž}  
+_textati_ [l=th] {à¹àžà¹àž²àžàž¶àžàžà¹àž­àž¡àž¹àž¥àžàž²àžà¹àžàžàžàžŽàž à¹àžà¹àž àž­àž²àž£à¹àžàžŽàž§à¹àž¡àžàžà¹ CGI}  
+
+_texttsaa_ [l=th] {àžàž£àžŽàžàž²àž£à¹àž«àž¥à¹àž²àžàžµà¹à¹àžà¹àž²àžàž¶àžà¹àžà¹à¹àžàž¢àžàž²àž£à¹àžà¹à¹àžàžàžàž³àžàž²àžàžà¹àž²àžàžà¹àž²àžàžàž¶à¹àžàž­àž¢àž¹à¹àžàž²àžàžà¹àž²àž¢àž¡àž·àž­àžàž­àžàž«àžà¹àž²}  
+
+_textcolstat_ [l=th] {àžªàžàž²àžàž°àžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àž}  
+
+_textcwoa_ [l=th] {àžàž­àž¥à¹àž¥àžàžàž±àžàžàž°à¹àžªàžàžàžàž³àž§à¹àž² "àžàž³àž¥àž±àžàžàž³àžàž²àž" àžà¹àž²àž¡àžµà¹àžà¹àž¡ build.cfg àž­àž¢àž¹à¹ àžªàž²àž¡àž²àž£àžàž­à¹àž²àžà¹àžà¹ àžàž£àž°àžàž­àžàžà¹àž§àž¢à¹àžàžàžà¹àž­àž¡àž¹àž¥ builddate àžàžµà¹àžàž¹àžàžà¹àž­àž (à¹àžà¹àž > 0) à¹àž¥àž°àž­àž¢àž¹à¹à¹àžà¹àžà¹àž£àžàžàž­àž£àžµàžàž±àžàžàžµàžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àž (à¹àžà¹àž à¹àž¡à¹à¹àžà¹à¹àžà¹àž£àžàžàž­àž£àžµàžàž²àž£àžªàž£à¹àž²àž) à¹àžà¹àž²àžàž±à¹àž}  
+
+_textcafi_ [l=th] {àžàž¥àžŽàž <i>àžàž±àž§àž¢à¹àž­</i> à¹àžàž·à¹àž­àžàž¹àžà¹àž­àž¡àž¹àž¥à¹àžàžµà¹àž¢àž§àžàž±àžàžàž­àž¥à¹àž¥àžàžàž±àž}  
+_textcctv_ [l=th] {àžàž¥àžŽàžàžàžµà¹ <i>àžàž­àž¥à¹àž¥àžàžàž±àž</i> à¹àžàž·à¹àž­àžàž¹àžàž­àž¥à¹àž¥àžàžàž±àž}  
+_textsubc_ [l=th] {àžªà¹àžàžà¹àž­àž¡àž¹àž¥àžàž²àž£à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àž}  
+_texteom_ [l=th] {à¹àžàžŽàžàžà¹àž­àžàžŽàžàžàž¥àž²àžà¹àžàžàž²àž£à¹àžàžŽàžà¹àžà¹àž¡ main.cfg}  
+_textftum_ [l=th] {à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàž£àž±àžàžàž£àžžàžà¹àžà¹àž¡ main.cfg à¹àžà¹}  
+_textmus_ [l=th] {àžàž£àž±àžàžàž£àžžàžà¹àžà¹àž¡ main.cfg à¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§}  
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=th] {àžªàž£à¹àž²àžàžàž¥àžªàž£àžžàžàžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž "_collectionname_"}  
+_textflog_ [l=th] {à¹àžà¹àž¡àžàž±àžàžàž¶àžàžàž§àž²àž¡àž¥à¹àž¡à¹àž«àž¥àž§àžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž "_collectionname_"}  
+_textilog_ [l=th] {àžàž³à¹àžà¹àž²à¹àžà¹àž¡àžàž±àžàžàž¶àžàžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž "_collectionname_"}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=th] {àžªà¹àžàžàž²àž£àžàž­àžàž£àž±àž}  
+
+_greenstoneusabilitytext_ [l=th] {àžàž²àž£à¹àžà¹àžàž²àžà¹àžàž£à¹àžàž£àž¡ Greenstone}  
+
+_textwhy_ [l=th] {<p>àžàž²àž£àžªà¹àžàž£àž²àž¢àžàž²àžàžàžµà¹à¹àžà¹àžàž§àžŽàžàžµàž«àžàž¶à¹àžàžàžµà¹àžàž°àžàž­àžàž§à¹àž² àžàžžàžàžàžàž§à¹àž²à¹àž§à¹àžà¹àžàžàžàžµà¹àžàžžàžàžàž³àž¥àž±àžàžàž¹àž­àž¢àž¹à¹àž¢àž²àžàž«àž£àž·àž­àžà¹àž²àžªàž±àžàžªàž}  
+_textextraforform_ [l=th] {àžàžžàžà¹àž¡à¹àžà¹àž­àžàžàž£àž­àžàžàž­àž£à¹àž¡ -- à¹àžªà¹àžà¹àž­àž¡àž¹àž¥à¹àžà¹ àžà¹à¹àžà¹}  
+_textprivacybasic_ [l=th] {<p>àž£àž²àž¢àžàž²àžàžàž°àžàž£àž°àžàž­àžàžà¹àž§àž¢àžà¹àž­àž¡àž¹àž¥à¹àžàžµà¹àž¢àž§àžàž±àžà¹àž§à¹àžà¹àžàžàžàž­àž Greenstone àžàžµà¹àžàžžàžàžàž³àž¥àž±àžàžàž¹àž­àž¢àž¹à¹ à¹àž¥àž°à¹àžàžà¹àžà¹àž¥àž¢àžµàžàžµà¹àžàžžàžàžàž³àž¥àž±àžà¹àžà¹à¹àžàžàž²àž£àžàž¹àžà¹àž­àž¡àž¹àž¥ (àžàž£à¹àž­àž¡àžàž±à¹àžàžà¹àž­àž¡àž¹àž¥àžàž±àž§à¹àž¥àž·àž­àžà¹àžà¹ àžàžµà¹àžàžžàžà¹àžªà¹à¹àž§à¹) à¹àžà¹àž²àžàž±à¹àž}  
+_textstillsend_ [l=th] {àžàžžàžàž¢àž±àžàžàžàžà¹àž­àžàžàž²àž£àžªà¹àžàž£àž²àž¢àžàž²àžàžàžµà¹àž«àž£àž·àž­à¹àž¡à¹}  
+
+_texterror_ [l=th] {àžà¹àž­àžàžŽàžàžàž¥àž²àž}  
+_textyes_ [l=th] {à¹àžà¹}  
+_textno_ [l=th] {à¹àž¡à¹à¹àžà¹}  
+_textclosewindow_ [l=th] {àžàžŽàžàž«àžà¹àž²àžà¹àž²àž}  
+_textabout_ [l=th] {à¹àžàžµà¹àž¢àž§àžàž±àž}  
+_textprivacy_ [l=th] {àžàž§àž²àž¡à¹àžà¹àžàžªà¹àž§àžàžàž±àž§}  
+_textsend_ [l=th] {àžªà¹àž}  
+_textdontsend_ [l=th] {à¹àž¡à¹àžªà¹àž}  
+_textoptionally_ [l=th] {à¹àžà¹àžàžàž±àž§à¹àž¥àž·àž­àž}  
+
+_textunderdev_ [l=th] {àžàž²àž£àžàž¹àžàž±àž§àž­àž¢à¹àž²àžàž£àž²àž¢àž¥àž°à¹àž­àžµàž¢àžàžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžà¹àžà¹à¹àžàž£àžžà¹àžàžªàžžàžàžà¹àž²àž¢}  
+
+_textviewdetails_ [l=th] {àžàž¹àž£àž²àž¢àž¥àž°à¹àž­àžµàž¢àžàžàž­àžàž£àž²àž¢àžàž²àž}  
+_textmoredetails_ [l=th] {àž£àž²àž¢àž¥àž°à¹àž­àžµàž¢àžà¹àžàžŽà¹àž¡à¹àžàžŽàž¡}  
+_texttrackreport_ [l=th] {àžàž²àž¡àž£àž­àž¢àž£àž²àž¢àžàž²àžàžàžàž±àžàžàžµà¹}  
+_textcharacterise_ [l=th] {àžàžàžŽàžàžàž­àžàžàž±àžàž«àž²àžàžµà¹àžàž·àž­àž­àž°à¹àž£}  
+_textseverity_ [l=th] {àžàž±àžàž«àž²àžàžµà¹àž£à¹àž²àž¢à¹àž£àžà¹àžà¹à¹àž«àž}  
+ 
+_textbadrender_ [l=th] {à¹àžàžàž¡àžµàž¥àž±àžàž©àžàž°à¹àžàž¥àžà¹àž}  
+_textcontenterror_ [l=th] {à¹àžàžŽàžàžà¹àž­àžàžŽàžàžàž¥àž²àžàžàžµà¹à¹àžàž·à¹àž­àž«àž²}  
+_textstrangebehaviour_ [l=th] {àžàž€àžàžŽàžàž£àž£àž¡àžàžµà¹àžàžŽàžàžàžàžàžŽ}  
+_textunexpected_ [l=th] {àž¡àžµàžàž²àžàž­àž¢à¹àž²àžàžàžµà¹à¹àž¡à¹àžàž²àžàžàžŽàžà¹àžàžŽàžàžàž¶à¹àž}  
+_textfunctionality_ [l=th] {àž¢àž²àžàžà¹àž­àžàž²àž£à¹àžà¹}  
+_textother_ [l=th] {àž­àž·à¹àžà¹}  
+
+_textcritical_ [l=th] {àž£à¹àž²àž¢à¹àž£àž}  
+_textmajor_ [l=th] {àž£à¹àž²àž¢à¹àž£àž}  
+_textmedium_ [l=th] {àžàžàž²àžàžàž¥àž²àž	
+
+		0
+}  
+_textminor_ [l=th] {àž£àž­àž}  
+_texttrivial_ [l=th] {àžªàžŽà¹àžà¹àž¥à¹àžàžà¹àž­àž¢}  
+
+_textwhatdoing_ [l=th] {àžàžžàžàžàž³àž¥àž±àžàžàž¢àž²àž¢àž²àž¡àžàž³àž­àž°à¹àž£àž­àž¢àž¹à¹}  
+_textwhatexpected_ [l=th] {àžàžžàžàžàžŽàžàž§à¹àž²àžàž°à¹àžàžŽàžàž­àž°à¹àž£àžàž¶à¹àžàžà¹àž²àž}  
+_textwhathappened_ [l=th] {à¹àžàžŽàžàž­àž°à¹àž£àžàž¶à¹àžàžàž±àžà¹àžà¹}  
+
+_cannotfindcgierror_ [l=th] {<h2>àžàž­àž­àž àž±àž¢!</h2>à¹àž¡à¹àžàžà¹àžàž£à¹àžàž£àž¡à¹àžàžŽàž£à¹àžà¹àž§àž­àž£à¹àžªàž³àž«àž£àž±àžàžàžžà¹àž¡ "_linktextusab_"}  
+
+_textusabbanner_ [l=th] {à¹àžàžà¹àžàž­àž£à¹à¹àžàž£àž¹àžà¹àžàž koru àžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone}  
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=th] {àž¡àžµàžà¹àž­àžàžŽàžàžàž¥àž²àžà¹àžàžŽàžàžàž¶à¹àž}  
+
+_textgtihome_ [l=th] {àž«àžà¹àž²à¹àž«àž¥à¹àž²àžàžµà¹àžàž°àžà¹àž§àž¢àžàžžàžàžàž£àž±àžàžàž£àžžàžàžàž²àž£àžªàžàž±àžàžªàžàžžàžàžà¹àž²àžàž àž²àž©àž²à¹àžàžàž«àž¥àž²àž¢àž àž²àž©àž²àžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone à¹àžà¹
+à¹àžàž¢àžàž²àž£à¹àžà¹àž«àžà¹àž²à¹àž«àž¥à¹àž²àžàžµà¹ àžàžžàžàžªàž²àž¡àž²àž£àž
+<ul>
+  <li>à¹àžàž¥àžªà¹àž§àžàžà¹àž²àžà¹ àžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone à¹àžà¹àžàž àž²àž©àž²à¹àž«àž¡à¹à¹àžà¹
+  <li>àžàž£àž±àžàžàž£àžžàžàžªà¹àž§àžàžàžŽàžàžà¹àž­àžàž¹à¹à¹àžà¹àžàž­àžàž àž²àž©àž²àžàžµà¹àž¡àžµàž­àž¢àž¹à¹à¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àžàžªà¹àž§àžàžàžŽàžàžà¹àž­àžàž¹à¹à¹àžà¹àž àž²àž©àž²àž­àž±àžàžàž€àž© (à¹àžà¹àž àžªàž³àž«àž£àž±àžàžªàžŽà¹àžàž­àž³àžàž§àž¢àžàž§àž²àž¡àžªàž°àžàž§àžàžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone)
+  <li>à¹àžà¹à¹àžàžà¹àž­àžàžŽàžàžàž¥àž²àžàžàž­àžàžàž²àž£à¹àžàž¥àžàžµà¹àž¡àžµàž­àž¢àž¹à¹à¹àž¥à¹àž§
+</ul>
+
+àžàžžàžàžàž°à¹àžà¹àžàžàžàž±àžàžàžžàžàž¥àž³àžàž±àžàžàž­àžàž«àžà¹àž²à¹àžàž à¹àžàž¢à¹àžà¹àž¥àž°àž«àžà¹àž²àžàž°àžàž£àž°àžàž­àžàžà¹àž§àž¢àž§àž¥àžµàžàžµà¹à¹àžà¹à¹àžàž¥
+àžàžžàžàžàž°àžàž³à¹àžàžŽàžàžàž²àž£à¹àžà¹à¹àžàž¢àžàž³à¹àžàžŽàžàžàž²àž£à¹àžàž¥àžªà¹àž§àžàžàžŽàžàžà¹àž­àžàž¹à¹à¹àžà¹àžà¹àž²àžàž àž²àž©àž²à¹àžàžàž§àž¥àžµàžà¹àž­àž§àž¥àžµ
+àž§àž¥àžµàžàž³àžàž§àžàž¡àž²àžàžàž£àž°àžàž­àžàžà¹àž§àž¢àžàž³àžªàž±à¹àžàžàž²àž£àžàž±àžàž£àž¹àžà¹àžàž HTML: àžàžžàžà¹àž¡à¹àžàž§àž£àžàž¢àž²àž¢àž²àž¡àžàžµà¹àžàž°à¹àžàž¥àž§àž¥àžµà¹àž«àž¥à¹àž²àžàžµà¹
+à¹àžà¹àžàž§àž£à¹àžà¹àžà¹àž§à¹àž­àž¢à¹àž²àžàžªàž¡àžàž¹àž£àžà¹à¹àžà¹àž§àž­àž£à¹àžàž±àžàžàžµà¹à¹àžàž¥à¹àž¥à¹àž§
+àžàž³àžàžµà¹àžàžàž²àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžµàžàž¥à¹àž²àž (à¹àž«àž¡àž·àž­àžàžàž±àžàžàž³àžàžµà¹ _this_) à¹àž¡à¹àžàž§àž£àžàž¹àžà¹àžàž¥à¹àžà¹àžàžàž±àž (àžàž³à¹àž«àž¥à¹àž²àžàž±à¹àžà¹àžà¹àžàžàž·à¹àž­ "à¹àž¡à¹àžàž£" àžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone)
+<p>
+àžà¹àž²àžàžžàžàžàž³àž¥àž±àžàžàž£àž±àžàžàž£àžžàžàžªà¹àž§àžàžàžŽàžàžà¹àž­àžàž¹à¹à¹àžà¹àžà¹àž²àžàž àž²àž©àž²àžàžµà¹àž¡àžµàž­àž¢àž¹à¹ àžàžžàžàžàž°à¹àž¡à¹à¹àž«à¹àžàž§àž¥àžµàžàžµà¹àž¡àžµàžàž²àž£à¹àžàž¥à¹àž§à¹à¹àž¥à¹àž§
+àžàž²àžàžàž£àž±à¹àžàžàž³à¹àžàž¥àž¡àžµàž­àž¢àž¹à¹à¹àž¥à¹àž§à¹àžà¹àžà¹àž­àžàž§àž²àž¡àž àž²àž©àž²àž­àž±àžàžàž€àž©à¹àžà¹àžàž¹àžà¹àžàž¥àžµà¹àž¢àžà¹àž
+à¹àžàžàž£àžàžµàžàžµà¹ àž£àž°àžàžàžàž°à¹àžªàžàžàžàž²àž£à¹àžàž¥àžàž±àžàžàžžàžàž±àž à¹àž¥àž°àžàžžàžàžàž§àž£àžàž£àž§àžàžªàž­àžà¹àž¥àž°àžàž£àž±àžàžàž£àžžàžàžàž²àž£à¹àžàž¥àžàž±à¹àžàž«àž²àžàžàž³à¹àžà¹àž
+<p>
+à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£à¹àžà¹à¹àžàžàž²àž£à¹àžàž¥àžàžµà¹à¹àžà¹àž£àž±àžàžàž²àž£àžàž£àž±àžàžàž£àžžàžà¹àž¥à¹àž§à¹àž«à¹àžàž¹àžàžà¹àž­àž à¹àž«à¹à¹àžà¹àžªàžŽà¹àžàž­àž³àžàž§àž¢àžàž§àž²àž¡àžªàž°àžàž§àž "à¹àžà¹à¹àžàžàž²àž£à¹àžàž¥àžàžµà¹àž¡àžµàž­àž¢àž¹à¹à¹àž«à¹àžàž¹àžàžà¹àž­àž" àžàžµà¹àžªàž²àž¡àž²àž£àžà¹àžà¹àžàž²àžà¹àžà¹àžªàž³àž«àž£àž±àžà¹àžà¹àž¥àž°àžªà¹àž§àžàžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone
+<p>
+à¹àžà¹àž¥àž°àž«àžà¹àž²àžàž°àžàžŽàžàžà¹àž²àž¢àžà¹àž§àž¢àžàžžà¹àž¡ "_textgtisubmit_"  à¹àž¡àž·à¹àž­àžàžžàžàžàžàžàžžà¹àž¡à¹àž¥à¹àž§ àžàž°àž¡àžµàžàž²àž£à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àžàžàžµà¹àžàž²àž£àžàžŽàžàžàž±à¹àžà¹àž¢àžàžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone àžàžµà¹ nzdl.org àžàž±àžàžàžµ
+àžàžžà¹àž¡àžàžµà¹àžàž°àžàž£àž²àžàžà¹àžà¹àžà¹àž¥àž°àž«àžà¹àž²à¹àžàž·à¹àž­à¹àžà¹àž²àžàž¶àžà¹àžàžà¹àžàžµà¹
+}  
+
+_textgtiselecttlc_ [l=th] {àžàž£àžžàžàž²à¹àž¥àž·àž­àžàž àž²àž©àž²}  
+
+#for status page
+_textgtiviewstatus_ [l=th] {àžàž¥àžŽàžà¹àžàž·à¹àž­àžàž¹àžªàžàž²àžàž°àžàž­àžàžàž²àž£à¹àžàž¥àžàž±àžàžàžžàžàž±àžàžªàž³àž«àž£àž±àžàžàžžàžàž àž²àž©àž²}  
+_textgtiviewstatusbutton_ [l=th] {àžàž¹àžªàžàž²àžàž°}  
+_textgtistatustable_ [l=th] {àž£àž²àž¢àžàž²àž£àžªàžàž²àžàž°àžàž²àž£à¹àžàž¥àžàž±àžàžàžžàžàž±àžàžªàž³àž«àž£àž±àžàž àž²àž©àž²àžàž±à¹àžàž«àž¡àž}  
+_textgtilanguage_ [l=th] {àž àž²àž©àž²}  
+_textgtitotalnumberoftranslations_ [l=th] {àžàž³àžàž§àžàžàž²àž£à¹àžàž¥àžàž±à¹àžàž«àž¡àž}  
+
+_textgtiselecttfk_ [l=th] {àžàž£àžžàžàž²à¹àž¥àž·àž­àžà¹àžà¹àž¡àžàžµà¹àžà¹àž­àžàžàž²àž£àžàž³àžàž²àž}  
+
+_textgticoredm_ [l=th] {àž«àžà¹àž²àžàž­àžàž¹à¹à¹àžà¹àž£àž°àžàž Greenstone (àž«àžà¹àž²àž«àž¥àž±àž)}  
+_textgtiauxdm_ [l=th] {àž«àžà¹àž²àžàž­àžàž¹à¹à¹àžà¹à¹àžàž£à¹àžàž£àž¡ Greenstone (àžªà¹àž§àžà¹àžªàž£àžŽàž¡)}  
+_textgtiglidict_ [l=th] {àžàžàžàž²àžàžžàžàž£àž¡ GLI}  
+_textgtiglihelp_ [l=th] {àž§àžŽàžàžµà¹àžà¹ GLI}  
+_textgtiperlmodules_ [l=th] {à¹àž¡àžàž¹àž¥àž àž²àž©àž² Perl}  
+_textgtitutorials_ [l=th] {à¹àžàžàžàž¶àžàž«àž±àžàžàžŽà¹àžšàž©}  
+_textgtigreenorg_ [l=th] {Greenstone.org}  
+_textgtigs3interface_ [l=th] {àžªà¹àž§àžàžàžŽàžàžà¹àž­àžàž¹à¹à¹àžà¹ Greenstone 3}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=th] {àžàž¹à¹àž¡àž·àž­àžªàž³àž«àž£àž±àžàžàž¹à¹àžàž±àžàžàž²àž£àž°àžàžàžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone}  
+_textgtiinstallmanual_ [l=th] {àžàž¹à¹àž¡àž·àž­àžàž²àž£àžàžŽàžàžàž±à¹àž Greenstone}  
+_textgtipapermanual_ [l=th] {àžàž¹à¹àž¡àž·àž­ Greenstone àžªàž³àž«àž£àž±àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àž	àžàž¹à¹àž¡àž·àž­ Greenstone àžªàž³àž«àž£àž±àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àž}  
+_textgtiusermanual_ [l=th] {àžàž¹à¹àž¡àž·àž­àžàž²àž£à¹àžà¹àžàž²àžà¹àžàž£à¹àžàž£àž¡ Greenstone}  
+
+_textgtienter_ [l=th] {à¹àžªà¹àžà¹àž²}  
+
+_textgticorrectexistingtranslations_ [l=th] {à¹àžà¹à¹àžàžàž²àž£à¹àžàž¥àžàžµà¹àž¡àžµàž­àž¢àž¹à¹}  
+_textgtidownloadtargetfile_ [l=th] {àžàž²àž§àžà¹à¹àž«àž¥àžà¹àžà¹àž¡}  
+_textgtiviewtargetfileinaction_ [l=th] {àžàž¹à¹àžà¹àž¡àžàžµà¹àžàžàž°àžàž³à¹àžàžŽàžàžàž²àž}  
+_textgtitranslatefileoffline_ [l=th] {à¹àžàž¥à¹àžà¹àž¡àžàžµà¹à¹àžàžàž­àž­àžà¹àž¥àžà¹}  
+
+_textgtinumchunksmatchingquery_ [l=th] {àžàž³àžàž§àžàžàž­àžàžàžŽà¹àžàžªà¹àž§àžàžà¹àž­àžàž§àž²àž¡àžàžµà¹àžàž£àžàžàž±àžàžàž³àžà¹àž}  
+
+_textgtinumchunkstranslated_ [l=th] {àžàž²àž£à¹àžàž¥à¹àžªàž£à¹àžàžªàžŽà¹àžà¹àž¥à¹àž§}  
+_textgtinumchunksrequiringupdating_ [l=th] {à¹àžàžàž³àžàž§àžàžàžµà¹ _1_ àžà¹àž­àžàžàž²àž£àžàž²àž£àžàž£àž±àžàžàž£àžžàž}  
+_textgtinumchunksrequiringtranslation_ [l=th] {àžàž²àž£à¹àžàž¥àžàžµà¹àžà¹àž²àžàž­àž¢àž¹à¹}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=th] {àžàž³àžàž§àžàžàž²àž£à¹àžàž¥àžàžµà¹à¹àžªàž£à¹àžà¹àž¥à¹àž§}  
+_textgtinumchunksrequiringupdating2_ [l=th] {àžàž³àžàž§àžàžàž­àžàžàž²àž£à¹àžàž¥àžàžµà¹àžà¹àž­àžàžàž£àž±àžàžàž£àžžàž}  
+_textgtinumchunksrequiringtranslation2_ [l=th] {àžàž³àžàž§àžàžàž­àžàžàž²àž£à¹àžàž¥àžàžµà¹à¹àž«àž¥àž·àž­àž­àž¢àž¹à¹}  
+
+_textgtienterquery_ [l=th] {à¹àžªà¹àžàž³àž«àž£àž·àž­àž§àž¥àžµàžàž²àžàžªà¹àž§àžàžà¹àž­àžàž§àž²àž¡àžàžµà¹àžàžžàžàžà¹àž­àžàžàž²àž£à¹àžà¹à¹àž}  
+_textgtifind_ [l=th] {àžà¹àžàž«àž²}  
+
+_textgtitranslatingchunk_ [l=th] {àžàž³àž¥àž±àžà¹àžàž¥àžàžŽà¹àžàžªà¹àž§àžàžà¹àž­àžàž§àž²àž¡ <i>_1_</i>}  
+_textgtiupdatingchunk_ [l=th] {àžàž£àž±àžàžàž£àžžàžàžàžŽà¹àžàžªà¹àž§àžàžà¹àž­àžàž§àž²àž¡ <i>_1_</i>}  
+_textgtisubmit_ [l=th] {àžªà¹àž}  
+
+_textgtilastupdated_ [l=th] {àžàž£àž±àžàžàž£àžžàžàžàž£àž±à¹àžàž¥à¹àž²àžªàžžàž}  
+
+_textgtitranslationfilecomplete_ [l=th] {àžàž­àžàžàžžàžàžªàž³àž«àž£àž±àžàžàž²àž£àžàž£àž±àžàžàž£àžžàžà¹àžà¹àž¡àžàžµà¹ -- àžàž²àž£àžàž£àž±àžàžàž£àžžàžà¹àžªàž£à¹àžàžªàžŽà¹àžà¹àž¥à¹àž§!<p>àžàžžàžàžªàž²àž¡àž²àž£àžàžàž²àž§àžà¹à¹àž«àž¥àžàžªàž³à¹àžàž²àžàž­àžà¹àžà¹àž¡àžàžµà¹à¹àžà¹à¹àžàž¢à¹àžà¹àžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàžà¹àž²àžàžàž à¹àž¥àž°à¹àžà¹àž¡àžàžµà¹àžàž°àžàž¹àžàž£àž§àž¡à¹àžà¹àž²àžàž±àžà¹àžàž£à¹àžàž£àž¡ Greenstone àž£àžžà¹àžàžàž±àžà¹àžàžà¹àž§àž¢}  
+
+_textgtiofflinetranslation_ [l=th] {àžàžžàžàžªàž²àž¡àž²àž£àžà¹àžàž¥àžªà¹àž§àžàžàžµà¹àžàž­àž Greenstone à¹àžàžàž­àž­àžà¹àž¥àžà¹à¹àžà¹àžà¹àž§àž¢à¹àžà¹àž¡àžàž²àž£àž²àžàžàž³àžàž§àž Microsoft Excel à¹àžàž¢àžàž²àž£:
+
+<ol>
+<li>àžàž²àž§àžà¹à¹àž«àž¥àž <a href="_gwcgi_?a=gti&p=excel&tct=work&e=_compressedoptions_">à¹àžà¹àž¡àžàžµà¹</a> à¹àžàž·à¹àž­à¹àž£àžµàž¢àžàžàž¹àžàž²àžà¹àžàž¥àžàžµà¹à¹àž«àž¥àž·àž­àžàž±à¹àžàž«àž¡àž àž«àž£àž·àž­ <a href="_gwcgi_?a=gti&p=excel&tct=all&e=_compressedoptions_">à¹àžà¹àž¡àžàžµà¹</a> à¹àžàž·à¹àž­à¹àž£àžµàž¢àžàžàž¹àžà¹àž­àžàž§àž²àž¡àžàž±à¹àžàž«àž¡àžà¹àžà¹àž¡àžàž¹àž¥àžàžµà¹
+<li>à¹àžàžŽàžà¹àžà¹àž¡àžàžµà¹àžàž²àž§àžà¹à¹àž«àž¥àžàž¡àž²àžà¹àž§àž¢à¹àžàž£à¹àžàž£àž¡ Microsoft Excel (àžà¹àž­àžàžàž²àž£ Office 2003/XP àž«àž£àž·àž­àž£àžžà¹àžàžàžµà¹à¹àž«àž¡à¹àžàž§à¹àž²) à¹àž¥àž°àžàž±àžàžàž¶àžà¹àžà¹àž¡à¹àžàž£àž¹àžà¹àžàžàžªàž¡àžžàžàžàž²àž Microsoft Excel (.xls)
+<li>à¹àžªà¹àžàž³à¹àžàž¥à¹àžàžàž¥à¹àž­àžàžàžµà¹àžàž±àžà¹àž«à¹
+<li>à¹àž¡àž·à¹àž­àžàžžàžàžàž³àžàž²àž£à¹àžàž¥àžà¹àž­àžàž§àž²àž¡àžàž±à¹àžàž«àž¡àžà¹àžªàž£à¹àžàžªàžŽà¹àžà¹àž¥à¹àž§ à¹àž«à¹àžªà¹àžàž­àžµà¹àž¡àž¥à¹àžà¹àž¡ .xls à¹àžàž¢àž±àž <a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>
+</ol>
+}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=th] {àž«àžà¹àž²àžàž­àžàž¹à¹à¹àžà¹àž£àž°àžàž Greenstone àžªàž³àž«àž£àž±àžàžàž£àž£àžàž²àž£àž±àžàž©à¹}  
+_textglihelp_ [l=th] {<p>àž«àžà¹àž²àžàž­àžàž¹à¹à¹àžà¹ Greenstone àžªàž³àž«àž£àž±àžàžàž£àž£àžàž²àž£àž±àžàž©à¹ (GLI) àžà¹àž§àž¢à¹àž«à¹àžàžžàžàžªàž²àž¡àž²àž£àžà¹àžà¹àž²àžàž¶àžàžàž±àžàžà¹àžàž±àžàžà¹àž²àžà¹ àžàž­àžà¹àžàž£à¹àžàž£àž¡ Greenstone àžà¹àž§àž¢àž«àžà¹àž²àžàž­àžàž¹à¹à¹àžà¹à¹àžàž 'àžàžµà¹à¹àž¥àž°àžàž¥àžŽàž' àžàžµà¹àžà¹àž²àž¢àžà¹àž­àžàž²àž£à¹àžà¹àžàž²àž àžàž¶à¹àžàžàž°àž­àžàžžàžàž²àžà¹àž«à¹àžàžžàžàž£àž§àžàž£àž§àž¡àžàžžàžàžàž­àžà¹àž­àžàžªàž²àž£ àžàž³à¹àžà¹àž²àž«àž£àž·àž­àžàž³àž«àžàžà¹àž¡àžàž²àžàž²àžàž² à¹àž¥àž°àžªàž£à¹àž²àžà¹àž­àžàžªàž²àž£àž¥àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àž Greenstone à¹àžà¹</p>
+
+<p>à¹àžàž£àžàžªàž±àžà¹àžàžàžžàž§à¹àž² GLI àžàž¹àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžàž£à¹àž§àž¡àžàž±àžà¹àžàž£à¹àžàž£àž¡ Greenstone à¹àž¥àž°à¹àžà¹àžàž·àž­àž§à¹àž²à¹àžà¹àž¡àžµàžàž²àž£àžàžŽàžàžàž±à¹àžà¹àžà¹àžà¹àž£àžàžàž­àž£àžµàž¢à¹àž­àž¢àžàž­àžàžàž²àž£àžàžŽàžàžàž±à¹àžà¹àžàž£à¹àžàž£àž¡ Greenstone à¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§  àžà¹àž²àžàžžàžàžàž²àž§àžà¹à¹àž«àž¥àžàžàž­àžàžà¹à¹àž§àž£à¹ Greenstone àž¡àž²à¹àž­àžàž«àž£àž·àž­àžàžŽàžàžàž±à¹àžàžàž²àžàžàžµàžàžµàž£àž­àž¡à¹àžàž£à¹àžàž£àž¡ Greenstone àžàžžàžàžà¹àžàž°àžªàž²àž¡àž²àž£àžà¹àžà¹àžàž²àžà¹àžà¹</p>
+
+<h4>àžàž²àž£à¹àž£àžµàž¢àžà¹àžà¹ GLI àž àž²àž¢à¹àžà¹àž£àž°àžàžàžàžàžŽàžàž±àžàžŽàžàž²àž£àž§àžŽàžà¹àžàžªà¹</h4>
+
+à¹àž£àžµàž¢àžà¹àžà¹àž«àžà¹àž²àžàž­àžàž¹à¹à¹àžà¹àž£àž°àžàžàžªàž³àž«àž£àž±àžàžàž£àž£àžàž²àž£àž±àžàž©à¹àž àž²àž¢à¹àžà¹àž£àž°àžàžàžàžàžŽàžàž±àžàžàž²àž£àž§àžŽàžà¹àžàžªà¹à¹àžà¹ à¹àžàž¢àžàž²àž£à¹àž¥àž·àž­àž <i>Greenstone Digital Library</i> àžàž²àžàžªà¹àž§àž <i>Programs</i> àžàž­àžà¹àž¡àžàž¹ <i>Start</i> à¹àž¥àž°à¹àž¥àž·àž­àž <i>Librarian Interface</i>
+
+<h4>àžàž²àž£à¹àž£àžµàž¢àžà¹àžà¹ GLI àž àž²àž¢à¹àžà¹àž£àž°àžàžàžàžàžŽàžàž±àžàžŽàžàž²àž£àž¢àž¹àžàžŽàžàžà¹</h4>
+
+à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£à¹àž£àžµàž¢àžà¹àžà¹ GLI àž àž²àž¢à¹àžà¹àž£àž°àžàžàžàžàžŽàžàž±àžàžŽàžàž²àž£àž¢àž¹àžàžŽàžàžà¹ à¹àž«à¹à¹àžàž¥àžµà¹àž¢àžà¹àžàž¢àž±àžà¹àžà¹àž£àžàžàž­àž£àžµ <i>gli</i> à¹àžàžªà¹àž§àžàžàžµà¹àž¡àžµàžàž²àž£àžàžŽàžàžàž±à¹àžà¹àžàž£à¹àžàž£àž¡ Greenstone àžàž²àžàžàž±à¹àžà¹àž«à¹à¹àž£àžµàž¢àžà¹àžà¹àžªàžàž£àžŽàžàžà¹ <i>gli.sh</i>
+
+<h4>àžàž²àž£à¹àž£àžµàž¢àžà¹àžà¹ GLI àž àž²àž¢à¹àžà¹àž£àž°àžàžàžàžàžŽàžàž±àžàžŽàžàž²àž£à¹àž¡àž à¹àž­à¹àž­àžª à¹àž­à¹àžàžà¹</h4>
+
+à¹àžàžàž±àž§àžà¹àžàž«àž² à¹àž«à¹à¹àžàž¢àž±àž <i>Applications</i> àžàž²àžàžàž±à¹àžà¹àžàžàžµà¹ <i>Greenstone</i> (àžà¹àž²àžàžžàžàžàžŽàžàžàž±à¹àžà¹àžàž£à¹àžàž£àž¡ Greenstone à¹àžàžàž³à¹àž«àžà¹àžàžàž²àž¡àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àž) àžàž²àžàžàž±à¹àžà¹àž«à¹à¹àž£àžµàž¢àžà¹àžà¹à¹àžàž£à¹àžàž£àž¡àžàž£àž°àž¢àžžàžàžà¹ <i>GLI</i>
+}  
Index: /gsdl/stable/macros/tip.dm
===================================================================
--- /gsdl/stable/macros/tip.dm	(revision 20131)
+++ /gsdl/stable/macros/tip.dm	(revision 20131)
@@ -0,0 +1,149 @@
+# this file must be UTF-8 encoded
+
+package tip
+
+#######################################################################
+# Tips
+# if you want a random tip to appear, use the macro name _tip:thistip_
+#######################################################################
+
+_tipstart_ {<center>}
+_tipquotestart_ {<b>}
+_tipquoteend_ {</b> }
+_tipattributionstart_ {<em>}
+_tipattributionend_ {</em>}
+_tipend_ {</center>}
+
+_tip1_ {
+       _tipstart_
+       _tipquotestart_
+       A word after a word after a word is power.
+       _tipquoteend_
+       _tipattributionstart_
+       Margaret Atwood
+       _tipattributionend_
+       _tipend_
+       _tipend_
+}
+
+_tip2_ {
+       _tipstart_
+       _tipquotestart_ Books are weapons in the war of ideas
+       _tipquoteend_
+       _tipattributionstart_ American Library Association, 1942
+       _tipattributionend_
+       _tipend_
+}
+
+_tip3_ {
+       _tipstart_
+       _tipquotestart_ Only the educated are free
+       _tipquoteend_
+       _tipattributionstart_ Epictetus
+       _tipattributionend_
+       _tipend_
+}
+
+_tip4_ {
+       _tipstart_
+       _tipquotestart_ We need our libraries open to all, so we can prepare our students for the 21st Century.
+       _tipquoteend_
+       _tipattributionstart_ Martin Luther King, quoted in the program at ALA midwinter, "Celebrating
+Equity and Empowerment," on Martin Luther King Day.
+       _tipattributionend_
+       _tipend_
+}
+
+_tip5_ {
+       _tipstart_
+       _tipquotestart_
+       Congress shall make no law abridging the freedom of sXXXch, or the right of the people peaceably to XXXemble, and to peXXXion the government for a redress of grievances.
+       _tipquoteend_
+       _tipattributionstart_
+The first amendment according to XStop (according to Marc Rotenberg, Electronic Privacy Information Center)
+       _tipattributionend_
+       _tipend_
+}
+_tip6_ {
+       _tipstart_
+       _tipquotestart_
+       My Alma mater was books, a good library . . . I could spend the rest of my life reading, just satisfying my curiosity.
+       _tipquoteend_
+       _tipattributionstart_
+       Malcolm X, Autobiograhy of Malcolm X
+       _tipattributionend_
+       _tipend_
+}
+_tip7_ {
+       _tipstart_
+       _tipquotestart_
+       To be literate is to possess the cow of plenty.
+       _tipquoteend_
+       _tipattributionstart_
+       Motto of the Madras Library Association
+       _tipattributionend_
+       _tipend_
+}
+
+_tip8_ {
+       _tipstart_
+       _tipquotestart_
+       It does not matter how many books you may have, but whether they are good or not.
+       _tipquoteend_
+       _tipattributionstart_
+       Seneca
+       _tipattributionend_
+       _tipend_
+}
+
+_tip9_ {
+       _tipstart_
+       _tipquotestart_
+       I have always imagined that Paradise will be a kind of library.
+       _tipquoteend_
+       _tipattributionstart_
+Jorge Luis Borges (1899-1986)
+       _tipattributionend_
+       _tipend_
+}
+
+_tip10_ {
+       _tipstart_
+       _tipquotestart_
+       When an old man dies, a library burns down.
+       _tipquoteend_
+       _tipattributionstart_
+       African Proverb
+       _tipattributionend_
+       _tipend_
+}
+
+_tip11_ {
+       _tipstart_
+       _tipquotestart_
+       My library / Was dukedom large enough. 
+       _tipquoteend_
+       _tipattributionstart_
+       William Shakespeare. The Tempest.
+       _tipattributionend_
+       _tipend_
+}
+
+_tip12_ {
+       _tipstart_
+       _tipquotestart_
+      Knowing I lov'd my books, he furnish'd me /
+      From mine own library with volumes that /
+      I prize above my dukedom. /
+       _tipquoteend_
+       _tipattributionstart_
+       William Shakespeare. The Tempest.
+       _tipattributionend_
+       _tipend_
+}
+
+
+_tip:tipmax_ {12}
+
+
+
Index: /gsdl/stable/macros/turkish.dm
===================================================================
--- /gsdl/stable/macros/turkish.dm	(revision 20131)
+++ /gsdl/stable/macros/turkish.dm	(revision 20131)
@@ -0,0 +1,794 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Turkish Language text and icon macros 
+# Translated by Ozcan Kabakcyoolu, October 2003
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=tr] {SÃŒreli YayÄ±nlar}
+_textsource_ [l=tr] {kaynak ref: }
+_textdate_ [l=tr] {yayÄ±n tarihi: }
+_textnumpages_ [l=tr] {sayfa sayÄ±sÄ±: }
+
+_textsignin_ [l=tr] {GiriÅ}
+
+_textdefaultcontent_ [l=tr] {Aranan sayfa bulunamadÄ±.
+LÃŒtfen tarayÄ±cÄ±nÄ±zÄ±n 'geri' yada ana sayfa dÃŒÄmesini kullanarak Sanal KÃŒtÃŒphaneye geri dÃ¶nÃŒnÃŒz.}
+
+_textdefaulttitle_ [l=tr] {GSDL Hata}
+
+# -- Missing translation: _textbadcollection_
+
+_textselectpage_ [l=tr] {Sayfa SeÃ§}
+
+_collectionextra_ [l=tr] {Bu koleksiyon _about:numdocs_ dokÃŒman iÃ§erir. 
+En son  _about:builddate_ gÃŒn Ã¶nce oluÅturuldu.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=tr] {<p>Bu koleksiyon _numdocs_ _If_("_numdocs_" eq "1",dokÃŒman,dokÃŒman), toplam _numbytes_ dÄ±r.
+<p><a href="_httppagex_(bsummary)">Koleksiyon Ã¶zeti</a>
+}
+
+_textdescrcollection_ [l=tr] {}
+_textdescrabout_ [l=tr] {HakkÄ±nda sayfasÄ±}
+_textdescrhome_ [l=tr] {Ana sayfa}
+_textdescrhelp_ [l=tr] {YardÄ±m}
+_textdescrpref_ [l=tr] {Tercihler}
+_textdescrgreenstone_ [l=tr] {Greenstone Sanal KÃŒtÃŒphane YazÄ±lÄ±mÄ±}
+_textdescrusab_ [l=tr] {Size gÃ¶re kullanÄ±mÄ± zor olanlar neler?}
+
+_textdescrSearch_ [l=tr] {Belirli sÃ¶zcÃŒkler iÃ§in arama}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=tr] {Alfabetik baÅlÄ±k listesine gÃ¶re gÃ¶zat}
+_textdescrCreator_ [l=tr] {Alfabetik yazar listesine gÃ¶zat}
+_textdescrSubject_ [l=tr] {Konu kategorisine gÃ¶re gÃ¶zat}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=tr] {Tarihe gÃ¶re gÃ¶zat}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+_textdescrSource_ [l=tr] {ÃzgÃŒn dosya adÄ±na gÃ¶re gÃ¶zat}
+_textdescrLanguage_ [l=tr] {Dile gÃ¶re gÃ¶zat}
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=tr] {Kuruma gÃ¶re gÃ¶zat}
+_textdescrKeyword_ [l=tr] {Anahtar sÃ¶zcÃŒklere gÃ¶re gÃ¶zat}
+_textdescrHowto_ [l=tr] {NasÄ±l kategorisine gÃ¶re gÃ¶zat}
+_textdescrList_ [l=tr] {Belge listesine gÃ¶re gÃ¶zat}
+_textdescrSeries_ [l=tr] {SayÄ±ya gÃ¶re gÃ¶zat}
+_textdescrTo_ [l=tr] {Kime alanÄ±na gÃ¶re gÃ¶zat}
+_textdescrFrom_ [l=tr] {Kimden alanÄ±na gÃ¶re gÃ¶zat}
+_textdescrTopic_ [l=tr] {Ãzel konulara gÃ¶re gÃ¶zat}
+_textdescrBrowse_ [l=tr] {GÃ¶zat}
+# -- Missing translation: _textdescrCollage_
+_textdescrPeople_ [l=tr] {Alfabetik kiÅi listesine gÃ¶re gÃ¶zat}
+_textdescrAcronym_ [l=tr] {KÄ±saltmalara gÃ¶zat}
+_textdescrPhrase_ [l=tr] {Ä°fadelere gÃ¶re gÃ¶zat}
+_textdescrArtist_ [l=tr] {SanatÃ§Ä±lara gÃ¶zat}
+_textdescrVolume_ [l=tr] {Ciltlere gÃ¶re gÃ¶zat}
+# -- Missing translation: _textdescrCountries_
+_textdescrCaptions_ [l=tr] {Resim baÅlÄ±klarÄ±na gÃ¶re gÃ¶zat}
+
+
+_labelSearch_ [l=tr] {Arama}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=tr] {BaÅlÄ±klar A-Z}
+_labelCreator_ [l=tr] {Yazarlar A-Z}
+_labelSubject_ [l=tr] {Konular}
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=tr] {Tarihler}
+# -- Missing translation: _labelType_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+_labelSource_ [l=tr] {Dosya adlarÄ±}
+_labelLanguage_ [l=tr] {Dil}
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=tr] {Kurum}
+_labelKeyword_ [l=tr] {Anahtar sÃ¶zcÃŒkler}
+_labelHow_ [l=tr] {NasÄ±l}
+_labelSeries_ [l=tr] {Seriler}
+_labelList_ [l=tr] {Listele}
+_labelTo_ [l=tr] {Kime}
+_labelFrom_ [l=tr] {Kime}
+_labelTopic_ [l=tr] {Konular}
+_labelBrwse_ [l=tr] {GÃ¶zat}
+# -- Missing translation: _labelCollage_
+_labelBrows_ [l=tr] {GÃ¶zat}
+_labelPeople_ [l=tr] {KiÅi A-Z}
+_labelAcronym_ [l=tr] {KÄ±saltmalar}
+_labelPhrase_ [l=tr] {Ä°fadeler}
+_labelArtist_ [l=tr] {SanatÃ§Ä±lar}
+_labelVolume_ [l=tr] {Ciltler}
+# -- Missing translation: _labelCaptions_
+# -- Missing translation: _labelCountries_
+
+_texticontext_ [l=tr] {Belgeyi gÃ¶rÃŒntÃŒle}
+_texticonclosedbook_ [l=tr] {bu belgeyi aÃ§ ve iÃ§eriÄini gÃ¶rÃŒntÃŒle}
+_texticonnext_ [l=tr] {sonraki bÃ¶lÃŒm}
+_texticonprev_ [l=tr] {Ã¶nceki bÃ¶lÃŒm}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=tr] {MIDI belgesini gÃ¶rÃŒntÃŒle}
+_texticonmsword_ [l=tr] {Word belgesini gÃ¶rÃŒntÃŒle}
+_texticonmp3_ [l=tr] {MP3 belgesini gÃ¶rÃŒntÃŒle}
+_texticonpdf_ [l=tr] {PDF belgesini gÃ¶rÃŒntÃŒle}
+_texticonps_ [l=tr] {PostScript belgesini gÃ¶rÃŒntÃŒle}
+_texticonppt_ [l=tr] {PowerPoint belgesini gÃ¶rÃŒntÃŒle}
+_texticonrtf_ [l=tr] {RTF belgesini gÃ¶rÃŒntÃŒle}
+_texticonxls_ [l=tr] {Microsoft Excel belgesini gÃ¶rÃŒntÃŒle}
+
+_page_ [l=tr] {sayfa }
+_pages_ [l=tr] {sayfa}
+# -- Missing translation: _of_
+_vol_ [l=tr] {Cilt}
+_num_ [l=tr] {No.}
+
+_textmonth00_ [l=tr] {}
+_textmonth01_ [l=tr] {Ocak}
+_textmonth02_ [l=tr] {Åubat}
+_textmonth03_ [l=tr] {Mart}
+_textmonth04_ [l=tr] {Nisan}
+_textmonth05_ [l=tr] {MayÄ±s}
+_textmonth06_ [l=tr] {Haziran}
+_textmonth07_ [l=tr] {Temmuz}
+_textmonth08_ [l=tr] {AÄustos}
+_textmonth09_ [l=tr] {EylÃŒl}
+_textmonth10_ [l=tr] {Ekim}
+_textmonth11_ [l=tr] {KasÄ±m}
+_textmonth12_ [l=tr] {AralÄ±k}
+
+_textdocument_ [l=tr] {Belge}
+_textsection_ [l=tr] {BÃ¶lÃŒm}
+_textparagraph_ [l=tr] {Paragraf}
+
+_magazines_ [l=tr] {Dergiler}
+
+_nzdlpagefooter_ [l=tr] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">Yeni Zelanda Sanal KÃŒtÃŒphane Projesi</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Bilgisayar BÃ¶lÃŒmÃŒ</a>, 
+<a href="http://www.waikato.ac.nz">Waikato Ãniversitesi</a>, 
+Yeni Zelanda}
+
+_linktextHOME_ [l=tr] {ANA SAYFA}
+_linktextHELP_ [l=tr] {YARDIM}
+_linktextPREFERENCES_ [l=tr] {TERCÄ°HLER}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=tr] {Greenstone Sanal KÃŒtÃŒphanesi}
+_textadmin_ [l=tr] {YÃ¶netici SayfasÄ±}
+_textabgs_ [l=tr] {Greenstone}
+_textgsdocs_ [l=tr] {Greenstone Belgelendirme}
+
+
+_textdescradmin_ [l=tr] {Yeni kullanÄ±cÄ±lar tanÄ±mlamanÄ±za izin verir, sistemdeki koleksiyonlarÄ± Ã¶zetler, 
+Greenstone'un kurulumu hakkÄ±nda teknik bilgiler verir.
+}
+
+_textdescrgogreenstone_ [l=tr] {Greenstone yazÄ±lÄ±mÄ± ve yazÄ±lÄ±mÄ±n kaynaÄÄ± olanYeni Zelanda Sanal KÃŒtÃŒphanesi Projesi 
+hakkÄ±nda bilgiler verir.
+}
+
+_textdescrgodocs_ [l=tr] {Greenstone elkitabÄ±}
+
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textdescrgli_ [l=tr] {Yeni koleksiyonlarÄ± oluÅturma, varolan koleksiyonlarÄ± deÄiÅtirme veya silme iÅlemlerine yardÄ±m eder.
+}
+
+package collector
+
+_textcollector_ [l=tr] {Koleksiyon AyarlarÄ±}
+
+package depositor
+
+
+package gti
+
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=tr] {Bu Koleksiyon hakkÄ±nda}
+
+_textsubcols1_ [l=tr] {<p>Bu koleksiyon _1_ alt koleksiyondan
+oluÅmaktadÄ±r:
+<blockquote>}
+
+_textsubcols2_ [l=tr] {</blockquote>
+Tercihler sayfasÄ±nda Åu anda kullandÄ±ÄÄ±nÄ±z alt koleksiyonlarÄ± kontrol edebilir ve deÄiÅtirebilirsiniz.}
+
+
+_titleabout_ [l=tr] {hakkÄ±nda}
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+# -- Missing translation: _texticonhcoll_
+# -- Missing translation: _texticonhcapt_
+# -- Missing translation: _texticonhcount_
+
+_texticonopenbookshelf_ [l=tr] {kÃŒtÃŒphanenin bu bÃ¶lÃŒmÃŒnÃŒ kapat}
+_texticonclosedbookshelf_ [l=tr] {kÃŒtÃŒphanenin bu bÃ¶lÃŒmÃŒnÃŒ aÃ§ ve iÃ§indekileri gÃ¶rÃŒntÃŒle}
+_texticonopenbook_ [l=tr] {kitabÄ± kapat}
+_texticonclosedfolder_ [l=tr] {dizini aÃ§ ve iÃ§indekileri gÃ¶rÃŒntÃŒle}
+_texticonclosedfolder2_ [l=tr] {alt bÃ¶lÃŒmÃŒ aÃ§: }
+_texticonopenfolder_ [l=tr] {dizini kapat}
+_texticonopenfolder2_ [l=tr] {alt bÃ¶lÃŒmÃŒ kapat: }
+_texticonsmalltext_ [l=tr] {metnin bu bÃ¶lÃŒmÃŒnÃŒ gÃ¶rÃŒntÃŒle}
+_texticonsmalltext2_ [l=tr] {metni gÃ¶rÃŒntÃŒle: }
+_texticonpointer_ [l=tr] {mevcut bÃ¶lÃŒm}
+_texticondetach_ [l=tr] {sayfayÄ± yeni pencerede aÃ§}
+_texticonhighlight_ [l=tr] {Aranan sÃ¶zcÃŒkleri iÅaretle}
+_texticonnohighlight_ [l=tr] {Aranan sÃ¶zcÃŒkleri}
+_texticoncontracttoc_ [l=tr] {Ä°Ã§indekiler tablosunu daralt}
+_texticonexpandtoc_ [l=tr] {Ä°Ã§indekiler tablosunu geniÅlet}
+_texticonexpandtext_ [l=tr] {TÃŒm metni gÃ¶ster}
+_texticoncontracttext_ [l=tr] {Sadece seÃ§ilmiÅ bÃ¶lÃŒmÃŒn metnini gÃ¶rÃŒntÃŒle}
+_texticonwarning_ [l=tr] {<b>UyarÄ±: </b>}
+_texticoncont_ [l=tr] {devam?}
+
+_textltwarning_ [l=tr] {<div class="buttons">_imagecont_</div>
+_iconwarning_Burada metinin geniÅletilmesi 
+tarayÄ±cÄ±nÄ±zÄ±n gÃ¶rÃŒntÃŒleyebileceÄinden daha bÃŒyÃŒk veri oluÅturur
+}
+
+_textgoto_ [l=tr] {sayfaya git}
+_textintro_ [l=tr] {<i>(giriÅ metni)</i>}
+
+
+_textCONTINUE_ [l=tr] {DEVAM??}
+
+_textEXPANDTEXT_ [l=tr] {METNÄ°\nGENÄ°ÅLET}
+
+_textCONTRACTCONTENTS_ [l=tr] {Ä°ÃÄ°NDEKÄ°LERÄ°\nDARALT}
+
+_textDETACH_ [l=tr] {AÃ}
+
+_textEXPANDCONTENTS_ [l=tr] {Ä°ÃÄ°NDEKÄ°LERÄ°\nAÃ}
+
+_textCONTRACT_ [l=tr] {METNÄ°\nDARALT}
+
+_textHIGHLIGHT_ [l=tr] {Ä°ÅARETLEME}
+
+_textNOHIGHLIGHT_ [l=tr] {Ä°ÅARETLEME\nYOK}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=tr] {_If_(_thislast_,results _thisfirst_ - _thislast_ for query: _cgiargq_,Arama sonucu bulunamadÄ±: _cgiargq_)}
+_textnoquerytitle_ [l=tr] {Arama sayfasÄ±}
+
+_textsome_ [l=tr] {bazÄ±larÄ±nÄ± }
+_textall_ [l=tr] {tÃŒmÃŒ}
+_textboolean_ [l=tr] {boolean}
+_textranked_ [l=tr] {sÄ±ralÄ±}
+_textnatural_ [l=tr] {basit}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=tr] {Ã¶nceki arama}
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+_textusequery_ [l=tr] {bu sorguyu kullan}
+_textfreqmsg1_ [l=tr] {SÃ¶zcÃŒk sayÄ±sÄ±: }
+_textpostprocess_ [l=tr] {_If_(_quotedquery_,<br><i>Åunu bulmak iÃ§in iÅlemden geÃ§ti:  _quotedquery_</i>
+)}
+_textinvalidquery_ [l=tr] {GeÃ§ersiz arama sÃ¶z dizimi}
+
+_textmorethan_ [l=tr] {Daha fazla }
+_textapprox_ [l=tr] {HakkÄ±nda }
+_textnodocs_ [l=tr] {Arama sonucu bulunamadÄ±.}
+_text1doc_ [l=tr] {1 belge bulundu.}
+_textlotsdocs_ [l=tr] {belge bulundu.}
+_textmatches_ [l=tr] {EÅleÅtirildi }
+_textbeginsearch_ [l=tr] {AramayÄ± BaÅlat}
+_textrunquery_ [l=tr] {Sorgula}
+_textclearform_ [l=tr] {Formu Temizle}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=tr] {SÃ¶zcÃŒk ya da ifade}
+_textinfield_ [l=tr] {... alanda}
+_textfoldstem_ [l=tr] {(gÃ¶vde, kÃ¶k)}
+
+_textadvquery_ [l=tr] {Ya da doÄrudan sorgula:}
+_textallfields_ [l=tr] {tÃŒm alanlar}
+_texttextonly_ [l=tr] {salt metin}
+_textand_ [l=tr] {ve}
+_textor_ [l=tr] {ya da}
+_textandnot_ [l=tr] {ve deÄil}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+# -- Missing translation: _textsimplesearch_
+
+# -- Missing translation: _textadvancedsearch_
+
+_textformsimplesearch_ [l=tr] {Arama yap _If_(_jselection_,_jselection_)_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )for _formquerytypesimpleselection_ of}
+
+_textformadvancedsearch_ [l=tr] {Arama yap _If_(_jselection_,_jselection_ )_If_(_gformselection_,at _gformselection_ level )_If_(_nselection_,in _nselection_ language )ve sonuÃ§larÄ± ÅÃ¶yle gÃ¶rÃŒntÃŒle: _formquerytypeadvancedselection_ order}
+
+
+_textnojsformwarning_ [l=tr] {UyarÄ±: TarayÄ±cÄ±nÄ±zda Javascript uygulamalarÄ± pasifleÅtirilmiÅ. <br>Form aramasÄ± yapabilmek iÃ§in etkinleÅtirmeniz gerekiyor.}
+_textdatesearch_ [l=tr] {Bu koleksiyonda belgeler belirli tarihler arasÄ±nda ya da belirli bir tarihe gÃ¶re aranÄ±r; bu, aramanÄ±n seÃ§ime baÄlÄ± opsiyonel bir Ã¶zelliÄidir.}
+_textstartdate_ [l=tr] {BaÅlama (ya da tek) tarihi:}
+_textenddate_ [l=tr] {BitiÅ tarihi:}
+_textbc_ [l=tr] {M.Ã.}
+_textad_ [l=tr] {M.S.}
+_textexplaineras_ [l=tr] {M.Ã. Milattan Ã¶nceyi, M.S. Milattan sonrayÄ± belirtmektedir.}
+
+_textstemon_ [l=tr] {(sÃ¶zcÃŒk bitimini gÃ¶zardÄ± et)}
+
+_textsearchhistory_ [l=tr] {Ãnceki Aramalar}
+
+#text macros for search history
+_textnohistory_ [l=tr] {Ãnceki arama sonuÃ§larÄ± mevcut deÄil}
+_texthresult_ [l=tr] {sonuÃ§}
+_texthresults_ [l=tr] {sonuÃ§}
+_texthallwords_ [l=tr] {tÃŒm sÃ¶zcÃŒkler}
+_texthsomewords_ [l=tr] {herhangi birini}
+_texthboolean_ [l=tr] {boolean}
+_texthranked_ [l=tr] {sÄ±ralÄ±}
+_texthcaseon_ [l=tr] {kÃŒÃ§ÃŒk/bÃŒyÃŒk harf duyarlÄ±}
+_texthcaseoff_ [l=tr] {kÃŒÃ§ÃŒk/bÃŒyÃŒk harf duyarSIZ}
+_texthstemon_ [l=tr] {stemmed}
+_texthstemoff_ [l=tr] {unstemmed}
+
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=tr] {Tercihleri aÅaÄÄ±daki menÃŒden deÄiÅtirebilirsiniz. TarayÄ±cÄ±nÄ±zÄ±n
+"geri" dÃŒÄmesini kullanmayÄ±nÄ±z! YukarÄ±daki eriÅim Ã§ubuÄunu kullanÄ±nÄ±z.
+}
+_textsetprefs_ [l=tr] {tercihleri kaydet}
+_textsearchprefs_ [l=tr] {Arama tercihleri}
+_textcollectionprefs_ [l=tr] {Koleksiyon tercihleri}
+_textpresentationprefs_ [l=tr] {GÃ¶rÃŒnÃŒm tercihleri}
+_textpreferences_ [l=tr] {Tercihler}
+_textcasediffs_ [l=tr] {BÃŒyÃŒk/kÃŒÃ§ÃŒk harf:}
+_textignorecase_ [l=tr] {bÃŒyÃŒk/kÃŒÃ§ÃŒk harf farklÄ±lÄ±klarÄ± dikkate alma}
+_textmatchcase_ [l=tr] {kÃŒÃ§ÃŒk/bÃŒyÃŒk harf farklÄ±lÄ±klarÄ± dikkate al}
+_textwordends_ [l=tr] {SÃ¶zcÃŒk sonu:}
+_textstem_ [l=tr] {sÃ¶zcÃŒk bitiÅlerini dikkate alma}
+_textnostem_ [l=tr] {tÃŒm sÃ¶zcÃŒk eÅleÅmeli}
+_textprefop_ [l=tr] {Taramada _maxdocoption_ adet bul, her sayfada _hitsperpageoption_ adet gÃ¶ster.}
+_textextlink_ [l=tr] {DÄ±Å web sayfalarÄ±na giriÅ:}
+_textintlink_ [l=tr] {Kaynak belgerinin Ã§aÄrÄ±ldÄ±ÄÄ± yer:}
+_textlanguage_ [l=tr] {ArayÃŒz dili:}
+_textencoding_ [l=tr] {Dil kodlamasÄ±:}
+_textformat_ [l=tr] {ArayÃŒz gÃ¶rÃŒnÃŒmÃŒ:}
+_textall_ [l=tr] {TÃŒmÃŒ}
+_textquerymode_ [l=tr] {Arama Åekli :}
+_textsimplemode_ [l=tr] {basit arama}
+_textadvancedmode_ [l=tr] {geliÅmiÅ arama ( !, &, |, ve parantezlerin kullanÄ±mÄ±yla "boolean" arama yapabilirsiniz)}
+_textlinkinterm_ [l=tr] {ara sayfa yoluyla}
+_textlinkdirect_ [l=tr] {doÄrudan git}
+_textdigitlib_ [l=tr] {sanal kÃŒtÃŒphane}
+_textweb_ [l=tr] {web}
+_textgraphical_ [l=tr] {Grafik}
+_texttextual_ [l=tr] {Metin}
+_textcollectionoption_ [l=tr] {<p>
+Alt koleksiyonlar:
+<br>}
+
+_textrelateddocdisplay_ [l=tr] {iliÅkili belgeleri gÃ¶ster}
+_textsearchhistory_ [l=tr] {Ãnceki arama:}
+_textnohistory_ [l=tr] {Ãnceki arama sonuÃ§larÄ± mevcut deÄil}
+_texthistorydisplay_ [l=tr] {Ã¶nceki arama sonuÃ§larÄ±ndan _historynumrecords_ adet gÃ¶ster.}
+_textnohistorydisplay_ [l=tr] {Ã¶nceki arama sonuÃ§larÄ±nÄ± gÃ¶sterme}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=tr] {form arama}
+_textplainsearch_ [l=tr] {DÃŒz arama:}
+_textqueryboxsize_ [l=tr] {arama kutusu bÃŒyÃŒklÃŒÄÃŒ :}
+_textregbox_ [l=tr] {normal arama kutusu}
+_textbigbox_ [l=tr] {geniÅ arama kutusu}
+_textformtype_ [l=tr] {Form tÃŒrÃŒ:}
+_textsimple_ [l=tr] {basit}
+_textadvanced_ [l=tr] {geliÅmiÅ}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=tr] {ile}
+_textfields_ [l=tr] {alanlar}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=tr] {DokÃŒmanlarÄ± sÄ±rala}
+_textalsoshowing_ [l=tr] {gÃ¶stererek}
+_textwith_ [l=tr] {with at most}
+_textdocsperpage_ [l=tr] {sayfa baÅÄ±na belge sayÄ±sÄ±}
+
+_textfilterby_ [l=tr] {Åunu iÃ§eren belgeleri getir:}
+_textall_ [l=tr] {hepsi}
+_textany_ [l=tr] {herhangi biri}
+_textwords_ [l=tr] {kelimede}
+_textleaveblank_ [l=tr] {TÃŒm belgeleri gÃ¶rmek iÃ§in kutuyu boÅ bÄ±rak}
+
+_browsebuttontext_ [l=tr] {"Belgeleri SÄ±rala"}
+
+_nodata_ [l=tr] {<i>veri yok</i>}
+_docs_ [l=tr] {belgeler}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=tr] {YardÄ±m}
+_textSearchshort_ [l=tr] {belirli sÃ¶zcÃŒklerle arama}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=tr] {belge baÅlÄ±ÄÄ±na gÃ¶re yayÄ±nlara eriÅim}
+_textCreatorshort_ [l=tr] {yazar adÄ±ndan yayÄ±nlara eriÅim}
+_textSubjectshort_ [l=tr] {konuya gÃ¶re yayÄ±nlara eriÅim}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=tr] {tarihe gÃ¶re yayÄ±nlara eriÅim}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=tr] {dosya adÄ±na gÃ¶re yayÄ±nlara eriÅim}
+_textLanguageshort_ [l=tr] {yayÄ±n diline gÃ¶re yayÄ±nlara eriÅim}
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=tr] {seri adÄ±na gÃ¶re yayÄ±nlara eriÅim}
+_textToshort_ [l=tr] {Kime alanÄ±na gÃ¶re yayÄ±nlara eriÅim}
+_textFromshort_ [l=tr] {Kimden alanÄ±na gÃ¶re yayÄ±nlara eriÅim}
+_textBrowseshort_ [l=tr] {yayÄ±nlara gÃ¶zat}
+_textOrganizationshort_ [l=tr] {kurum adÄ±na  gÃ¶re yayÄ±nlara eriÅim}
+_textHowtoshort_ [l=tr] {"nasÄ±l" listesi ile yayÄ±nlara eriÅim}
+_textTopicshort_ [l=tr] {konularÄ±na gÃ¶re yayÄ±nlara eriÅim}
+_textPeopleshort_ [l=tr] {kiÅi adÄ±na gÃ¶re yayÄ±nlara eriÅim}
+_textAcronymshort_ [l=tr] {kÄ±saltmalardan yayÄ±nlara eriÅim}
+_textPhraseshort_ [l=tr] {yayÄ±nlardaki ifadelere gÃ¶re }
+_textArtistshort_ [l=tr] {sanatÃ§Ä±lara gÃ¶re yayÄ±nlara eriÅim}
+_textKeywordshort_ [l=tr] {anahtar sÃ¶zcÃŒklerle yayÄ±nlara eriÅim }
+_textVolumeshort_ [l=tr] {ciltlerine gÃ¶re yayÄ±nlara eriÅim }
+# -- Missing translation: _textCountriesshort_
+_textdefaultshorttext_ [l=tr] {tanÄ±mlanamamÄ±Å sÄ±nÄ±flama}
+
+_textSearchlong_ [l=tr] {<p>Sanal kÃŒtÃŒphane'de <i>belirli kelimeleri </i> bulmak iÃ§in
+arama sayfasÄ± kullanÄ±lÄ±r. Programa giriÅte karÅÄ±nÄ±za gelen ilk sayfadÄ±r. DiÄer 
+sayfalardan <i>arama</i> butonu seÃ§ilerek ulaÅÄ±labilir. }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=tr] {<p>Sanal kÃŒtÃŒphane'de <i>yayÄ±nlara eser adÄ±yla eriÅim</i> 
+<i>baÅlÄ±k a-z</i> butonu seÃ§ilerek saÄlanÄ±r. YayÄ±n listesi ekrana alfabetik 
+sÄ±ralanÄ±r.  }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=tr] {<p>Sanal kÃŒtÃŒphane'de <i>yayÄ±nlara yazar adÄ±yla eriÅim</i> 
+<i>yazarlar a-z</i> butonu seÃ§ilerek saÄlanÄ±r. Yazar adlarÄ±na gÃ¶re sÄ±ralanmÄ±Å 
+yayÄ±n listesi gÃ¶rÃŒntÃŒlenir.  }
+
+_textSubjectlong_ [l=tr] {<p>Sanal kÃŒtÃŒphane'de <i>yayÄ±nlara konu baÅlÄ±ÄÄ±ndan eriÅim</i> 
+ <i>konu baÅlÄ±ÄÄ±</i> butonu seÃ§ilerek saÄlanÄ±r. 
+Bu bize konu baÅlÄ±ÄÄ± listesini oluÅturur.  }
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=tr] {<p>Sanal kÃŒtÃŒphane'de <i>yayÄ±nlara yayÄ±n tarihinden eriÅim</i> 
+<i>tarihler</i> butonu seÃ§ilerek saÄlanÄ±r. Bu bize kronolojik olarak listelenmiÅ
+sayÄ±larÄ±n gÃ¶sterilmesini saÄlar.  }
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=tr] {<p>Sanal kÃŒtÃŒphanede <i>yayÄ±nlara dosya adÄ±yla eriÅim</i> iÃ§in
+<i>dosya adÄ±</i> butonu seÃ§ilir. Bu bize Ã¶zgÃŒn dosya adÄ±na gÃ¶re oluÅturulan bir listeyi gÃ¶rÃŒntÃŒler.}
+
+_textLanguagelong_ [l=tr] {<p>Sanal kÃŒtÃŒphanede <i>yayÄ±nlara yayÄ±n dilinden eriÅim</i>
+<i>diller</i> butonu seÃ§ilerek saÄlanÄ±r.  }
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=tr] {<p>Sanal kÃŒtÃŒphane'de <i>yayÄ±ncÄ± kurumlara </i> eriÅim 
+ <i>kurumlar</i> butonu seÃ§ilerek saÄlanÄ±r. Kurumlar alfabetik olarak listelenir.  }
+
+_textHowtolong_ [l=tr] {<p>Sanal kÃŒtÃŒphane'de <i>"nasÄ±l" listesi</i>
+<i>nasÄ±l</i> butonu seÃ§ilerek oluÅturulur.  }
+
+_textTopiclong_ [l=tr] {<p>Sanal kÃŒtÃŒphane'de <i>yayÄ±nlara konu eriÅimi</i>
+<i>konu</i> butonu seÃ§ilerek saÄlanÄ±r. Konu listesi gÃ¶rÃŒntÃŒlenir.  }
+
+_textTolong_ [l=tr] {<p>Sanal kÃŒtÃŒphane'de e-posta koleksiyonlarÄ±nda <i>yayÄ±nlara Kime alanÄ±na gÃ¶re</i>eriÅim
+ <i>Kime</i> butonu seÃ§ilerek saÄlanÄ±r. Adres listesi ekrana alfabetik sÄ±ralanÄ±r.}
+
+_textFromlong_ [l=tr] {<p>Sanal kÃŒtÃŒphane'de <i>From</i>eriÅim 
+<i>from</i> butonu seÃ§ilerek saÄlanÄ±r.  }
+
+_textSerieslong_ [l=tr] {<p>Sanal kÃŒtÃŒphane'de <i>serilerle yayÄ±na eriÅim</i> 
+<i>seriler</i> butonu seÃ§ilerek saÄlanÄ±r. Bu bize koleksiyonda var olan 
+seriler listesini gÃ¶sterir. }
+
+_textBrowselong_ [l=tr] {<p>Sanal kÃŒtÃŒphanede <i>yayÄ±nlara gÃ¶zatmak iÃ§in</i> 
+<i>gÃ¶zat</i> butunu seÃ§ilir.  }
+
+_textPeoplelong_ [l=tr] {<p>Sanal kÃŒtÃŒphanede <i>yayÄ±nlara kiÅi adÄ±ndan eriÅim</i> 
+<i>kiÅiler a-z</i>butonu seÃ§ilerek saÄlanÄ±r. Bu soyadÄ±na gÃ¶re sÄ±ralanmÄ±Å 
+kiÅi listesi verir. }
+
+_textAcronymlong_ [l=tr] {<p>Sanal kÃŒtÃŒphanede <i>yayÄ±nlara kÄ±saltmalarla eriÅim</i>
+<i>kÄ±saltmalar</i> butonu seÃ§ilerek saÄlanÄ±r. Bu bize kÄ±saltmalar ve kÄ±saltmalarÄ±n
+geÃ§tiÄi yerleri veren liste oluÅturur.  }
+
+_textPhraselong_ [l=tr] {<p>Sanal kÃŒtÃŒphanede <i>yayÄ±nlarda geÃ§en ifadelere gÃ¶zatmak </i> iÃ§in
+<i>ifadeler</i> butonunu seÃ§eriz. }
+
+_textArtistlong_ [l=tr] {<p>Sanal kÃŒtÃŒphanede <i>yayÄ±nlara sanatÃ§Ä±larla eriÅim</i>
+<i>sanatÃ§Ä±lar</i>  butonu seÃ§ilerek saÄlanÄ±r.  }
+
+_textKeywordlong_ [l=tr] {<p>Sanal kÃŒtÃŒphanede <i>yayÄ±nlara anahtar sÃ¶zcÃŒklerle eriÅim</i>
+ <i>anahtar sÃ¶zcÃŒkler</i> butonu seÃ§ilerek saÄlanÄ±r.}
+
+# -- Missing translation: _textVolumelong_
+
+# -- Missing translation: _textCaptionslong_
+
+# -- Missing translation: _textCountrieslong_
+
+
+_textdefaultlongtext_ [l=tr] {<p><i>Bilinmeyen</i> botonu seÃ§ilerek yayÄ±nlara eriÅilir.  }
+
+_texthelptopicstitle_ [l=tr] {Konular}
+
+_textreadingdocs_ [l=tr] {Belgeler nasÄ±l okunur}
+
+_texthelpreadingdocs_ [l=tr] {
+<p>Belgeye eriÅtiÄimizde sol ÃŒst kÃ¶Åede baÅlÄ±k ve yazar
+adÄ± gÃ¶rÃŒlÃŒr. Bunun yanÄ±nda sayfa numarasÄ±, yeni bir sayfa seÃ§memize
+yarayan bir kutucuk ve ileri-geri oklarÄ± bulunmaktadÄ±r.
+
+<p>Alt kÄ±sÄ±mda seÃ§ilen bÃ¶lÃŒmÃŒn metni, devam ettiÄimizde
+bir Ã¶nceki veya bir sonraki bÃ¶lÃŒme geÃ§memizi saÄlayan oklar bulunmaktadÄ±r. 
+
+<p>BaÅlÄ±k ve yazar adÄ± altÄ±nda ÃŒÃ§ dÃŒÄme vardÄ±r. <i>GeniÅletilmiÅ metni</i>
+seÃ§tiÄimizde belgenin tamamÄ±nÄ± gÃ¶rebiliriz. EÄer belge bÃŒyÃŒkse yÃŒklenmesi 
+zaman alacaktÄ±r. <i>Yeni pencere</i> seÃ§ildiÄinde belge yeni bir 
+pencerede aÃ§Ä±lÄ±r. SonuÃ§ olarak arama yaptÄ±ÄÄ±mÄ±z sÃ¶zcÃŒkler <i>iÅaretli</i> dir. 
+Bunu kaldÄ±rmak istiyorsanÄ±z <i>iÅaretlemeyi kaldÄ±r</i> butonu seÃ§ilmelidir.  
+}
+
+# help about the icons
+_texthelpexpandtext_ [l=tr] {TÃŒm metni gÃ¶ster ya da gÃ¶sterme}
+_texthelpdetachpage_ [l=tr] {Bu sayfayÄ± yeni bir pencerede aÃ§}
+_texthelphighlight_ [l=tr] {Arama sÃ¶zcÃŒklerini iÅaretle ya da iÅaretleme}
+
+_texthelpsearchingtitle_ [l=tr] {Belirli kelimeler nasÄ±l aranÄ±r}
+
+_texthelpsearching_ [l=tr] {
+<p>
+  Arama sayfasÄ±ndan sorgulama yapÄ±lÄ±r, bunun iÃ§in:<p>
+  
+  <ol><li>Aranmak istenen bilgi belirlenir
+      <li>Hepsinin mi, yoksa bazÄ± sÃ¶zcÃŒklerin mi aranmak istendiÄi belirlenir
+      <li>Aranan sÃ¶zcÃŒkler yazÄ±lÄ±r
+      <li>Son olarak <i>Arama</i> dÃŒÄmesi seÃ§ilir.
+  </ol>
+
+<p>Arama sonunda yirmi belge gÃ¶rÃŒntÃŒlenecektir. SayfanÄ±n altÄ±nda bir sonraki yirmi 
+belgeye gÃ¶tÃŒrecek dÃŒÄme bulunmaktadÄ±r. <i>Tercihlerden</i>  gÃ¶sterilecek belge deÄiÅtirilebilir.
+}
+
+_texthelpquerytermstitle_ [l=tr] {Arama SÃ¶zcÃŒkleri}
+_texthelpqueryterms_ [l=tr] {
+<p>SÃ¶zcÃŒkler yazÄ±lÄ±rken aralarÄ±na boÅluk bÄ±rakÄ±lÄ±r. Noktalama iÅaretleri yazmayÄ±nÄ±z, taranamaz.
+}
+
+_texthelpquerytypetitle_ [l=tr] {Sorgulama}
+_texthelpquerytype_ [l=tr] {
+<p>Ä°ki farklÄ± sorgulama tÃŒrÃŒ vardÄ±r.
+
+<ul>
+  <li>BÃŒtÃŒn sÃ¶zcÃŒklerin yazÄ±ldÄ±ÄÄ± sorgulama
+     <p>
+
+  <li>BazÄ± sÃ¶zcÃŒklerin yazÄ±ldÄ±ÄÄ± sorgulama
+
+      
+</ul>
+
+<p>Ä°stediÄiniz birÃ§ok arama sÃ¶zcÃŒÄÃŒnÃŒ kullanabilirsiniz. BÃŒtÃŒn cÃŒmle veya paragraf yazÄ±labilir.
+Sadece tek bir sÃ¶zcÃŒk tanÄ±mlarsanÄ±z geÃ§me sÄ±klÄ±ÄÄ±na gÃ¶re sÄ±ralanÄ±r.<p>
+}
+
+_textdatesearch_ [l=tr] {Tarihe gÃ¶re tarama}
+
+_texthelpdatesearch_ [l=tr] {
+Tarihe gÃ¶re aramalarda belirli bir zaman aralÄ±ÄÄ± iÃ§erisindeki dokÃŒmanlar 
+aranÄ±r. Belirli bir yÄ±lÄ± veya yÄ±llar arasÄ±nÄ± arayabilirsiniz. HiÃ§bir arama
+sÃ¶zcÃŒÄÃŒnÃŒz yoksa yalnÄ±zca tarihe gÃ¶re arama yapabilirsiniz. Ve taramanÄ±zda 
+tarih belirtme zorunluluÄu da yoktur.<p>
+}
+
+_texthelpdatehowtotitle_ [l=tr] {Bu Ã¶zelliÄi nasÄ±l kullanÄ±rÄ±z:}
+_texthelpdatehowto_ [l=tr] {
+<ul>
+   <li>Tek bir yÄ±l iÃ§in belge arama:<p>
+   <ul>
+       <li>Ä°stediÄiniz bir arama sÃ¶zcÃŒÄÃŒnÃŒ yazÄ±nÄ±z 
+       <li>BaÅlangÄ±Ã§ tarihi kutucuÄuna istediÄiniz tarihi yazÄ±nÄ±z
+       <li>EÄer aradÄ±ÄÄ±nÄ±z tarih milattan Ã¶nceyse kutunun yanÄ±ndaki menÃŒden M.Ã. seÃ§in.
+       <li>Aramaya baÅlayÄ±n.
+   </ul>
+<p><li>Belirli bir zaman veya zaman aralÄ±ÄÄ±nda arama:<p>
+   <ul>
+       <li>Ä°stediÄiniz bir arama sÃ¶zcÃŒÄÃŒnÃŒ yazÄ±nÄ±z 
+       <li>BaÅlangÄ±Ã§ tarihi yazan kutucuÄa ilk tarihi yazÄ±yoruz. 
+       <li>BitiÅ tarihi kutucuÄuna sonraki tarihi yazÄ±yoruz.
+       <li>M.Ã. seÃ§iyoruz.
+       <li>Taramaya baÅlÄ±yoruz.
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=tr] {Arama sonuÃ§larÄ±}
+
+_textchangeprefs_ [l=tr] {AyarlarÄ±nÄ±zÄ± DeÄiÅtirmek}
+
+_texthelppreferences_ [l=tr] {
+<p>SayfanÄ±n ÃŒstÃŒndeki <i>tercihler</i> dÃŒÄmesini seÃ§tiÄinizde isteÄinize
+gÃ¶re sayfanÄ±n arayÃŒzÃŒndeki bazÄ± Ã¶zellikleri deÄiÅtirebilirsiniz.
+}
+
+_texthelpcollectionprefstitle_ [l=tr] {Koleksiyon tercihleri}
+_texthelpcollectionprefs_ [l=tr] {
+BazÄ± koleksiyonlar baÄÄ±msÄ±z ya da birlikte taranabilecek Åekilde alt 
+koleksiyonlardan oluÅmuÅtur. Ayarlar sayfasÄ±ndan istediÄiniz alt 
+koleksiyonu seÃ§ebilirsiniz.
+}
+
+_texthelplanguageprefstitle_ [l=tr] {Dil tercihleri}
+_texthelplanguageprefs_ [l=tr] {
+Her koleksiyonun kendine Ã¶zgÃŒ bir dili vardÄ±r. Ä°stediÄiniz farklÄ± bir dile
+Ã§evirebilirsiniz. Ä°stediÄiniz karakter setini ayarlamanÄ±z da mÃŒmkÃŒndÃŒr. TarayÄ±cÄ±nÄ±z
+tanÄ±mlÄ± olan karakter setini seÃ§ecektir. Kendiniz bu ayarlamayÄ± yaptÄ±ÄÄ±nÄ±zda 
+daha iyi sonuÃ§lar alabilirsiniz.
+}
+
+_texthelppresentationprefstitle_ [l=tr] {GÃ¶rÃŒnÃŒm tercihleri}
+_texthelppresentationprefs_ [l=tr] {
+GÃ¶rÃŒnÃŒmÃŒ ayarlayabileceÄiniz birkaÃ§ seÃ§enek vardÄ±r. 
+
+<p>Bu seÃ§enekler kullanÄ±m kolaylÄ±ÄÄ± saÄlar.
+}
+
+_texthelpsearchprefstitle_ [l=tr] {Arama tercihleri}
+_texthelpsearchprefs_ [l=tr] {
+<p> Ä°ki adet dÃŒÄme yaptÄ±ÄÄ±nÄ±z aramalardaki eÅleÅtirmeleri kontrol eder. 
+Birincisi bÃŒyÃŒk, kÃŒÃ§ÃŒk harf ayrÄ±mÄ±nÄ±, ikincisi ise kelime sonlandÄ±rmayÄ± 
+kontrol eder. Arama kutusu isteÄe gÃ¶re bÃŒyÃŒtÃŒlebilir.
+
+<p> AyrÄ±ntÄ±lÄ± taramada boolean operatÃ¶rleri kullanÄ±labilir. Bu da aramayÄ±
+Ã¶zelleÅtirmemizi saÄlar. Eski aramalar ekranda gÃ¶rÃŒntÃŒlenebilir. 
+}
+
+_texttanumbrowseoptions_ [l=tr] {Bu koleksiyondaki bilgilere eriÅim iÃ§in _numbrowseoptions_ yol vardÄ±r.}
+
+_textsimplehelpheading_ [l=tr] {_collectionname_ koleksiyonu}
+
+_texthelpscopetitle_ [l=tr] {Arama alanÄ±}
+
+_texthelpscope_ [l=tr] {
+<p>
+BirÃ§ok koleksiyonda arama yapmak iÃ§in farklÄ± indeksler seÃ§ebilirsiniz.
+ÃrneÄin bu bir yazar yada baÅlÄ±k indeksi  veya bÃ¶lÃŒm paragraf indeksi 
+olabilir. Hangi indeks seÃ§ilirse tarama sonucu o indeksten elde edilir. <p> 
+}
Index: /gsdl/stable/macros/turkish2.dm
===================================================================
--- /gsdl/stable/macros/turkish2.dm	(revision 20131)
+++ /gsdl/stable/macros/turkish2.dm	(revision 20131)
@@ -0,0 +1,971 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Turkish Language text and icon macros 
+# -- this file contains english text that is of less importance
+# -- to translate when creating a new interface language
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=tr] {DokÃŒmanlar }
+_lastupdate_ [l=tr] {En son GÃŒncelleme}
+_ago_ [l=tr] {gÃŒn Ã¶nce yapÄ±ldÄ±.}
+_colnotbuilt_ [l=tr] {Derleme yapÄ±landÄ±rÄ±lmadÄ±.}
+
+_textpoem_ [l=tr] {<p>BarÄ±Å ve huzur sarsÄ±n sizi.
+<br>Yaz sÄ±caklÄ±ÄÄ±nÄ±n pusu iÃ§inde kalÄ±n Ã¶ylece
+<br>ve okyanuslar boyunca sÃŒren yolculuklarÄ±nÄ±z pÃŒrÃŒzsÃŒz bir yeÅim taÅÄ±na dÃ¶nsÃŒn.
+}
+
+_textgreenstone_ [l=tr] {<p>
+
+Greenstone (yeÅim taÅÄ±) Yeni Zelanda'da bulunan yarÄ± kÄ±ymetli bir taÅtÄ±r. 
+Bu yazÄ±lÄ±m da aynÄ± Ã¶zellikleri gÃ¶stermektedir.Maori kabilesinin tÃ¶relerine
+gÃ¶re YeÅim taÅÄ± bÃŒtÃŒn diÄer madenlere gÃ¶re en fazla Ã¶vgÃŒye layÄ±k gÃ¶rÃŒlen bir taÅtÄ±r.
+YeÅim taÅÄ± yaÅama kuvvetinin kaynaÄÄ± ve ruhu olan <i>wairua</i>'yÄ± tutmakta ve iÃ§ermektedir
+ve bu nedenle bÃ¶ylesine bir sanal  kÃŒtÃŒphane projesinin esin kaynaÄÄ± olmuÅtur.
+
+}
+
+_textaboutgreenstone_ [l=tr] {<p>Greenstone sanal kÃŒtÃŒphane koleksiyonlarÄ± oluÅturmak ve daÄÄ±tÄ±mÄ±nÄ± 
+geÃ§ekleÅtirmek iÃ§in hazÄ±rlanmÄ±Å bir yazÄ±lÄ±mdÄ±r. Greenstone, bilginin dÃŒzenlenmesi ve
+Internet veya CD-ROM ÃŒzerinden yayÄ±mlanmasÄ± konusunda yenÃŒ usÃŒller sunmaktadÄ±r.
+Greenstone yazÄ±lÄ±mÄ± <b>University of Waikato</b> tarafÄ±ndan  <b>New Zealand Digital Library Project</b> 
+<i>(Yeni Zelanda Sanal KÃŒtÃŒphanesi  Projesi)</i> kapsamÄ±nda ÃŒretilmiÅ ve 
+<b>UNESCO</b>, <b>Human Info NGO</b> kuruluÅlarÄ± tarafÄ±ndan geliÅtirilmiÅ ve daÄÄ±tÄ±mÄ± saÄlanmÄ±ÅtÄ±r.
+Bu yazÄ±lÄ±mÄ±n aÃ§Ä±k kod kaynaÄÄ±nÄ± <a href="http://greenstone.org">http://greenstone.org</a> adresinden
+"GNU General Public Licence" ilkelerine uymak koÅulu ile temin edebilirsiniz.
+
+<p>Bu yazÄ±lÄ±mÄ±n amacÄ±, kullanÄ±cÄ±larÄ±n, Ã¶zellikle ÃŒniversitelerin, kÃŒtÃŒphanelerin,
+ve diÄer kamu hizmeti gÃ¶ren kurum ve kuruluÅlarÄ±n kendi sanal kÃŒtÃŒphanelerini
+kurmalarÄ±nÄ± saÄlamaktÄ±r. Sanal kÃŒtÃŒphaneler, Ã¶zellikle geliÅmekte olan ÃŒlkelerin
+eÄitim, bilim ve kÃŒltÃŒrel alanda; UNESCO'nun ortaklaÅa hareket ettiÄi kuruluÅlar ve kurumlarda 
+bilginin yayÄ±lmasÄ± ve edinilmesi konusunda kÃ¶kten bir deÄiÅiklik yapmÄ±ÅtÄ±r.
+Bu yazÄ±lÄ±mÄ± oluÅturanlarÄ±n dileÄi bu ve buna benzer yazÄ±lÄ±mlar ile sanal kÃŒtÃŒphanelerin
+etkin bir biÃ§imde yayÄ±lmasÄ± ve bilginin yaygÄ±nlaÅmasÄ±nÄ±n saÄlanmasÄ±dÄ±r.
+
+
+<p>Bu yazÄ±lÄ±m AÄustos 2000 tarihinde uluslararasÄ± iÅbirliÄi Ã§erÃ§evesinde aÅaÄÄ±da adÄ± geÃ§en 3 ayrÄ± kurumun 
+gayretleri ile yazÄ±lmÄ±Å ve daÄÄ±tÄ±mÄ± gerÃ§ekleÅtirilmiÅtir.
+
+<table border="0">
+<tr valign="top">
+<td>
+<a href="http://nzdl.org"><b>New Zealand Digital Library Project at the University of Waikato</b></a>
+<br>
+Greenstone software grew out of this project, and this initiative
+has been endorsed by the Communication Sub-Commission of the New
+Zealand National Commission for UNESCO as part of New Zealand's
+contribution to UNESCO's programme.
+</td>
+<td></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://www.unesco.org"><b>United Nations Educational, Scientific and Cultural Organization</b></a>
+<br>
+
+The dissemination of educational, scientific and cultural information
+throughout the world, and particularly its availability in developing
+countries, is central to UNESCO's goals as pursued within its
+intergovernmental Information for All Programme, and appropriate,
+accessible information and communication technology is seen as an important
+tool in this context.
+</td>
+<td><a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+border="0"></a></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://humaninfo.org"><b>The Human Info NGO, based in Antwerp, Belgium</b></a>
+<br>
+
+This project works with UN agencies and other NGOs, and has established
+a worldwide reputation for digitizing documentation of interest to
+human development and making it widely available, free of charge to
+developing nations and on a cost-recovery basis to others.
+</td>
+<td><a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" border="0"></a></td>
+</tr>
+</table>
+}
+
+# -- Missing translation: _textdescrselcol_
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=tr] {Ana Sayfada 4 buton daha bulunmaktadÄ±r.}
+
+_textnocollections_ [l=tr] {<p>Åu anda Greenstone'un kurulumunda herhangi bir koleksiyon bulunmamaktadÄ±r.
+Yeni koleksiyonlar eklemek iÃ§in 
+<ul><li>Use <a href="_httppagecollector_">The Collector</a> butonuna basarak yeni koleksiyonlar oluÅturabilirasiniz.
+    <li>EÄer Greenstone elinizde CD-ROM'u varsa koleksiyonlrÄ± CD-ROM'dan ekleyebilirsiniz.
+</ul>
+}
+
+_text1coll_ [l=tr] {Bu Greenstone kurulumu 1 adet koleksiyon iÃ§ermektedir.}
+
+_textmorecolls_ [l=tr] {Bu Greenstone kurulumu _1_ adet koleksiyon iÃ§ermektedir.}
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=tr] {DÄ±Å link (kÃ¶prÃŒ)}
+_textlinknotfound_ [l=tr] {Ä°Ã§ link bulunamadÄ±}
+
+_textextlinkcontent_ [l=tr] {SeÃ§tiÄiniz link Åu anda seÃ§miÅ olduÄunuz koleksiyonlarÄ±n dÄ±ÅÄ±ndadÄ±r.
+    EÄer hala bu linki gÃ¶rÃŒntÃŒlemek ve web tarayÄ±cÄ±nÄ±zÄ±n ilgili web sayfasÄ±na gitmesini istiyorsanÄ±z
+    <a href="_nexturl_">buraya tÄ±klayÄ±n</a> ; linki gÃ¶rÃŒntÃŒlemek istemiyorsanÄ±z
+     tarayÄ±cÄ±nÄ±zdaki "back" (geri) sekmesine tÄ±klayÄ±n ve Ã¶nceki belgeye ulaÅÄ±n.
+
+_textlinknotfoundcontent_ [l=tr] {Bizim kontrolumuzda olmayan bir nedenden dolayÄ± seÃ§tiÄiniz link 
+            bulunmamaktadÄ±r.Bunun nedeni kaynak koleksiyondaki bir hata olabilir.
+            LÃŒtfen tarayÄ±cÄ±nÄ±zdaki "back" (geri) sekmesine tÄ±klayÄ±n ve Ã¶nceki belgeye ulaÅÄ±n.
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=tr] {
+
+<h3>Link to "_2_" collection</h3>
+
+<p> SeÃ§tiÄiniz link "_collectionname_" kolesksiyonunun dÄ±ÅÄ±ndadÄ±r.
+("_2_" koleksiyonuna link baÄlantÄ± kurmaktadÄ±r.)
+EÄer "_2_" koleksiyonundaki linki gÃ¶rÃŒntÃŒlemek istiyorsanÄ±z
+<a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">bu sayfaya ilerleyin</a>
+Linki gÃ¶rÃŒntÃŒlemek istemiyorsanÄ±z  tarayÄ±cÄ±nÄ±zdaki "back" (geri) 
+sekmesine tÄ±klayÄ±n ve Ã¶nceki belgeye ulaÅÄ±n.
+}
+
+# -- Missing translation: _textlinknotfoundcontent_
+
+# should have arguments of collection, collectionname and link
+# -- Missing translation: _foundintcontent_
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=tr] {Greenstone Digital Library}
+
+_textusername_ [l=tr] {KullanÄ±cÄ± adÄ±}
+_textpassword_ [l=tr] {Åifre}
+
+_textmustbelongtogroup_ [l=tr] {Bu sayfaya ulaÅabilmek iÃ§in "_cgiargug_" grubuna kayÄ±tlÄ± olmanÄ±z gerekmektedir.}
+
+_textmessageinvalid_ [l=tr] {UlaÅmak istediÄiniz sayfa iÃ§i kullanÄ±cÄ± adÄ± ile kayÄ±t yapmanÄ±z gerekir.<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)
+LÃŒtfen  Greenstone kullanÄ±cÄ± adÄ± ve Åifrenizi giriniz.}
+
+_textmessagefailed_ [l=tr] {KullanÄ±cÄ± adÄ± ve/veya Åifreniz hatalÄ±}
+
+_textmessagedisabled_ [l=tr] {ÃzgÃŒnÃŒz, KullanÄ±m hakkÄ±nÄ±z kaldÄ±rÄ±lmÄ±Å. LÃŒtfen bu sitenin yÃ¶neticisine danÄ±ÅÄ±n.}
+
+_textmessagepermissiondenied_ [l=tr] {ÃzgÃŒnÃŒz, bu sayfaya giriÅ hakkÄ±nÄ±z yok.}
+
+_textmessagestalekey_ [l=tr] {Ä°zlediÄiniz link kullanÄ±mdan Åu anda Åifreli alanda. 
+LÃŒtfen kullanÄ±cÄ± adÄ± ve Åifrenizi giriniz.}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=tr] {<p> Bu Greenstone kurulumu hiÃ§bir belge iÃ§ermemektedir. Bunun nedeni 
+Åunlar olabilir:
+<ol>
+ <li>Greenstone CD-ROM'dan endÃŒÅÃŒk dÃŒzeyde kurulumla yÃŒklenmiÅtir.
+ <li>Greenstone Internet aracÄ±lÄ±Äi ile indirilmiÅtir.
+</ol>
+Her iki durumda da aÅaÄÄ±daki Ã§Ã¶zÃŒm yollarÄ±na baÅvurabilirsiniz.
+-Greenstone CD-ROM'u iÃ§indeki <i>docs</i> dizininden belgeleri elde 
+edebilirsiniz veya
+
+- <a href="http://www.greenstone.org">http://www.greenstone.org</a>
+sitesini ziyaret edebilirsiniz.
+}
+
+_textuserguide_ [l=tr] {KullanÄ±cÄ± Rehberi}
+_textinstallerguide_ [l=tr] {Kurulumcu Rehberi}
+_textdeveloperguide_ [l=tr] {GeliÅtirici Rehberi}
+_textpaperguide_ [l=tr] {Koleksiyona HazÄ±rlama Rehberi}
+# -- Missing translation: _textorganizerguide_
+
+_textgsdocstitle_ [l=tr] {greenstone documentation}
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textdefaultstructure_
+_textmore_ [l=tr] {Daha}
+_textinfo_ [l=tr] {Koleksiyon Bilgisi}
+_textsrce_ [l=tr] {Kaynak Veri}
+_textconf_ [l=tr] {Koleksiyon KonfigÃŒrasyonu}
+_textbild_ [l=tr] {YapÄ±landÄ±r}
+_textview_ [l=tr] {GÃ¶rÃŒntÃŒle}
+_textdel_ [l=tr] {Koleksiyon sil}
+_textexpt_ [l=tr] {Koleksiyonu dÄ±Åa ver}
+
+# -- Missing translation: _textdownloadingfiles_
+# -- Missing translation: _textimportingcollection_
+# -- Missing translation: _textbuildingcollection_
+# -- Missing translation: _textcreatingcollection_
+
+_textcollectorblurb_ [l=tr] {<i>Kalem KÄ±lÄ±Ã§tan Keskindir.
+<br>Bilgi KoleksiyonlarÄ±nÄ± yapÄ±landÄ±rma ve daÄÄ±tÄ±mÄ±nÄ± yapmaya baÅlamadan Ã¶nce 
+deÄinmek istediÄimiz bazÄ± konular var.
+
+Telif HaklarÄ± Konusunda bazÄ± yasal zorunluluklar bulunmaktadÄ±r:Bir belgeye ulaÅabilme, 
+bu belgeyi baÅkalarÄ±na verebilme hakkÄ±nÄ± size vermemektedir.BazÄ± sosyal zorunluluklar 
+vardÄ±r: koleksiyonlar belgelerin oluÅtuÄu toplumun geleneklerine saygÄ±lÄ± olmalÄ±dÄ±r.
+AyrÄ±ca ahlaki zorunluluklar vardÄ±r: BazÄ± bilgiler kolayca eriÅilebilecek yerlerde olmamalÄ±dÄ±r.
+<br>Bilginin gÃŒcÃŒne karÅÄ± duyarlÄ± olun ve onu bilgece kullanÄ±n.
+</i>
+}
+
+_textcb1_ [l=tr] {Koleksiyon ayarlarÄ± size yeni koleksiyon oluÅturmakta, varolan koleksiyonlarÄ± deÄiÅtirmek,
+silmek veya ekleme yapmakta yardÄ±mcÄ± olur. Bu iÅlemler iÃ§in gerekli bilgilere ulaÅmak amacÄ± 
+ile  bir dizi web sayfasÄ±ndan rehberlik hizmeti alacaksÄ±nÄ±z
+}
+
+_textcb2_ [l=tr] {Ãncelikle ne yapacaÄÄ±nÄ±za karar vermeniz gerekiyor}
+_textcnc_ [l=tr] {Yeni bir koleksiyon oluÅturmak }
+_textwec_ [l=tr] {Varolan bir koleksiyon ÃŒstÃŒnde Ã§alÄ±Åmak, veri ekleme veya silmek }
+
+_textcb3_ [l=tr] {Sanal kÃŒtÃŒphane koleksiyonlarÄ±nÄ± yapÄ±landÄ±rmak veya ÃŒzerinde deÄiÅiklik yapmak iÃ§in
+sisteme giriÅ yapmanÄ±z gerekmektedir. Bu, istenmeyen kiÅilerin bilgisayar 
+kayÄ±tlarÄ±na girerek istenmeyen deÄiÅiklikleri yapmasÄ±na engel olmak iÃ§in istenmektedir.
+
+Not: GÃŒvenlik iÃ§in 30 dakika iÃ§inde herhangi bir iÅlem yapmazsanÄ±z sistem ile baÄlantÄ±nÄ±z 
+kesilir. 
+}
+
+_textcb4_ [l=tr] {LÃŒtfen kullanÄ±cÄ± adÄ± ve Åifrenizi yazÄ±n ve giriÅ iÃ§in tÄ±klayÄ±n.
+}
+
+_textfsc_ [l=tr] {Ãncelikle Ã§alÄ±Åmak istediÄiniz koleksiyonu seÃ§iniz. Bu evrede salt 
+okunur koleksiyonlar listede gÃ¶zÃŒkmeyecektir.
+}
+
+_textwtc_ [l=tr] {SeÃ§tiÄiniz koleksiyonda}
+_textamd_ [l=tr] {daha fazla veri ekleyebilirsiniz ve koleksiyonu yeniden yapÄ±landÄ±rabilirsiniz.}
+_textetc_ [l=tr] {Koleksiyon konfigÃŒrasyon dosyasÄ± ÃŒzerinde deÄiÅiklik yapabilir ve koleksiyonu yeniden yapÄ±landÄ±rabilirsiniz.}
+_textdtc_ [l=tr] {BÃŒtÃŒn koleksiyonu silebilirsiniz.}
+_textetcfcd_ [l=tr] {Koleksiyonu yazma amaÃ§lÄ± olarak kendinden kurulumlu Windows CD-ROM'unda kullanÄ±lÄ±r hale getirebilirsiniz.}
+_textcaec_ [l=tr] {Varolan bir koleksiyon ÃŒstÃŒnde Ã§alÄ±Åmak, veri ekleme veya silmek}
+_textnwec_ [l=tr] {Yeni bir koleksiyon oluÅturmak amacÄ± ile }
+_textcianc_ [l=tr] {Yeni koleksiyon oluÅturma}
+_texttsosn_ [l=tr] {Yeni bir sanal kÃŒtÃŒphane oluÅturmak iÃ§in izlenmesi gereken adÄ±mlar dizisi ÅÃ¶yledir:}
+_textsin_ [l=tr] {AdÄ±nÄ± (ve baÄlÄ± bilgileri) belirt }
+_textswts_ [l=tr] {Verinin yerini belirle}
+_textatco_ [l=tr] {KonfigÃŒrasyon tercihlerini ayarla (YalnÄ±zca deneyimli kullanÄ±cÄ±lar iÃ§in)}
+_textbtc_ [l=tr] {Koleksiyonu "yapÄ±landÄ±r" (aÅaÄÄ±da aÃ§Ä±klanmaktadÄ±r)}
+_textpvyh_ [l=tr] {HazÄ±rladÄ±ÄÄ±nÄ±z koleksiyonu gÃ¶rebilirsiniz.}
+
+_texttfsiw_ [l=tr] {DÃ¶rdÃŒncÃŒ adÄ±mdaki iÅlerin tamamÄ±nÄ± bilgisayar yapar. "YapÄ±landÄ±rma prosesisinde
+bilgisayar bÃŒtÃŒn indeksleri yapar ve gerekli diÄer bilgileri de bulunduÄu 
+yerlerden alÄ±p biraraya getirir. Ancak Ã¶ncelikle bilgiyi belirtmeniz gerekmektedir.
+}
+
+_textadab_ [l=tr] {Altta sizin nerede olduÄunuzu gÃ¶steren bir diyagram belirecektir.
+YeÅil dÃŒÄmeye basarak siz iÅlemler dizisine devam edebilirsiniz.
+Ä°Ålem dizisi boyunca dÃŒÄmeler sarÄ±ya dÃŒnÃŒÅecektir. Ãnceki sayfalardan birine 
+dÃ¶nmek iÃ§in diyagramda ilgili sarÄ± dÃŒÄmeye basmanÄ±z gerekmektedir.
+}
+
+_textwyar_ [l=tr] {EÄer hazÄ±rsanÄ±z, "koleksiyon bilgisi" yazÄ±lÄ± yeÅil dÃŒÄmeye basÄ±n ve 
+yeni sanal kÃŒtÃŒphane koleksiyonunu yaratmaya baÅlayÄ±n.
+}
+
+_textcnmbs_ [l=tr] {Koleksiyon adÄ± belirtilmeli.}
+_texteambs_ [l=tr] {E-posta adresi belirtilmeli.}
+_textpsea_ [l=tr] {LÃŒtfen e-posta adresini kullaniciadi@alan biÃ§iminde belirtin.}
+_textdocmbs_ [l=tr] {Koleksiyonun betimlemesi belirtilmeli}
+
+_textwcanc_ [l=tr] {Yeni bir koleksiyon oluÅtuturken kaynak veri hakkÄ±nda bazÄ± bilgileri 
+girmeniz gerekmektedir. Bu iÅlemler bir  web sayfasÄ± dizisi halinde 
+yapÄ±landÄ±rÄ±lmÄ±ÅtÄ±r.  SayfanÄ±n altÄ±ndaki Ã§ubuk sizin bitirmeniz gereken 
+iÅlemler dizisinde hangi sayfada olduÄunuzu gÃ¶sterir.
+}
+
+_texttfc_ [l=tr] {Koleksiyonun baÅlÄ±ÄÄ±:}
+
+_texttctiasp_ [l=tr] {Koleksiyon baÅlÄ±ÄÄ± kÄ±sa bir sÃ¶zcÃŒk Ã¶beÄinden ibarettir ve sanal kÃŒtÃŒphane 
+tarafÄ±ndan koleksiyonun iÃ§eriÄini belirtmek amacÄ± ile kullanÄ±lÄ±r. BazÄ± Ã¶rnek 
+koleksiyon baÅlÄ±klarÄ±nÄ± sunarsak: "Bilgisayar Bilimleri Teknik raporlarÄ±" ve
+"SayÄ±sal Analiz YÃ¶ntemleri"
+}
+
+_textcea_ [l=tr] {BaÄlantÄ± iÃ§in e-posta adresi:}
+
+_textteas_ [l=tr] {Bu e-posta adresi koleksiyon hakkÄ±nda ilk baÄlantÄ± kurulacak kiÅiyi belirtir.
+EÄer Greenstone yazÄ±lÄ±mÄ± bir problem ortaya Ã§Ä±karÄ±rsa, bulgulara ait bir rapor 
+bu adrese gÃ¶nderilir.
+}
+
+_textatc_ [l=tr] {Bu koleksiyon hakkÄ±nda:}
+
+_texttiasd_ [l=tr] {Bu bir  koleksiyon iÃ§inde olanlarÄ± yÃ¶neten ilkeleri tanÄ±mlayan ifadedir.
+Koleksiyon sunulduÄunda ilk sayfada bu ilkeler gÃ¶rÃŒntÃŒlenir.
+}
+
+_textypits_ [l=tr] {Sizin iÅlem dizisi iÃ§indeki durumunuz "koleksiyon bilgisi" aÅamasÄ±nda 
+bir ok ile belirtilmektedir. Ä°Ålemi sÃŒrdÃŒrmek Ã§in yeÅil "kaynak veri"
+dÃŒÄmesine basÄ±n.
+}
+
+_srcebadsources_ [l=tr] {<p>BelirttiÄiniz giriÅ kaynaklarÄ±nda biri veya diÄerine ulaÅÄ±lamÄ±yor 
+(altta _iconcross_ belirtilmiÅtir).
+
+<p>Bunun sebebi Åu olabilir:
+<ul>
+<li>Dosya, FTP sitesi veya URL yoktur.
+<li>Ãncelikle sizin Internet Srvis SaÄlayÄ±cÄ±nÄ±za baÄlanmanÄ±z gerekmektedir.
+<li>Bir gÃŒvenli duvarÄ± (firewall) arkasÄ±nda bulunan bir URL'ye baÄlanmaya
+Ã§alÄ±ÅÄ±yorsunuz. (bu aslÄ±ndan eÄerinternette bie kullanÄ±cÄ± adÄ± ve Åifre ile
+giriÅ yapÄ±yorsanÄ±z normal bir durumdur).
+</ul>
+
+<p>EÄer URL'yi TarayÄ±cÄ±nÄ±zda gÃ¶rebiliyorsanÄ±z, bu sayfa kaÅelenmiÅ bir 
+kopyadan gelmiÅ olabilir. Ne yazÄ±k ki yerel diskinizde kaÅelenmiÅ kopya sayfalar
+yazÄ±lÄ±mÄ±n aynalama prosesinde gÃ¶rÃŒnmemektedir.  Bu gibi durumlarda size
+ilgili sayfanÄ±n bir tarayÄ±cÄ± tarafÄ±ndan  indirilmesini Ã¶neriyoruz.
+}
+
+_textymbyco_ [l=tr] {<p>Koleksiyonunuzu aÅaÄÄ±daki seÃ§eneklere dayandÄ±rabilirsiniz:
+<ul>
+<li>VarsayÄ±lan yapÄ±
+<dl><dd>Yeni koleksiyonlar aÅaÄÄ±daki dosya tÃŒrlerini iÃ§erebilir:
+ html belgeler (.htm, .html), dÃŒz metin belgeler
+(.txt, .text), MS Word belgeleri (.doc), PDF belgeler (.pdf) veya
+"m-box" formatlÄ± e-posta belgeleri (.mbx).</dd></dl>
+<li>Varolan bir koleksiyon
+<dl><dd>Yeni koleksiyonunuzdaki dosyalar kesinlikle oluÅturmak iÃ§in kullanÄ±lan koleksiyondaki dosya tÃŒrleri
+ile aynÄ± tÃŒrde olmalÄ±dÄ±r.</dd></dl>
+</ul>
+}
+
+_textbtco_ [l=tr] {Koleksiyonu aÅaÄÄ±daki sisteme dayandÄ±rÄ±n:}
+_textand_ [l=tr] {Yeni veri ekleyin}
+_textad_ [l=tr] {Veri ekleme:}
+
+_texttftysb_ [l=tr] {AÅaÄÄ±da belirttiÄiniz seÃ§ilmiÅ dosyalar koleksiyona eklenecektir.
+Koleksiyonda halihazÄ±rda bulunan dosyalarÄ± yeniden belirtmediÄinize emin olun:
+Aksi takdirde iki kopya eklenmiÅ olacaktÄ±r. Dosyalar; tam dosya yollarÄ±,
+web adreslerini gÃ¶steren web sayfalarÄ± ile belirtilebilir.
+}
+
+_textis_ [l=tr] {GiriÅ KaynaklarÄ±:}
+
+_textddd1_ [l=tr] {<p>EÄer bir dosyayÄ± belirtmek iÃ§in  file:// veya ftp:// kullanÄ±yorsanÄ±z bu dosya indirilecektir.
+
+<p>EÄer http:// sistemini kullanÄ±yorsanÄ±z kullandÄ±ÄÄ±nÄ±z URL'ye gÃ¶re ya 
+tarayÄ±cÄ±nÄ±zda bir web sayfasÄ± gÃ¶zÃŒkecektir ya da dosyalarÄ±n listesi
+belirecektir. 
+
+<p> EÄer bir dizini veya klasÃ¶rÃŒ belirtmek iÃ§in file:// veya ftp:// yÃ¶ntemini
+kullanÄ±yorsanÄ±z veya http:// URL usulÃŒnÃŒ kullanÄ±yorsanÄ±z bu yÃ¶ntemler sizi bir
+dosyalar listesine yÃ¶neltecektir. Bu listedeki klasÃ¶r ve altondaki klasÃ¶rler
+koleksiyondaki herÅeyi iÃ§erecektir.
+
+<p>"Daha fazla giriÅ kutusu elde etmek iÃ§in "Daha Ã§ok Kaynak" dÃŒÄmesine basÄ±n.
+}
+
+_textddd2_ [l=tr] {<p> YeÅil dÃŒÄmelerden birine basÄ±n. Deneyimli bir kullanÄ±cÄ± iseniz koleksiyonun
+konfigÃŒrasyon ayarlarÄ±nÄ± deÄiÅtirebilirsiniz. Ya da doÄrudan yapÄ±landÄ±rma evresine 
+geÃ§ebilirsiniz. Bir daha hatÄ±rlatalÄ±m, daha Ã¶nceki bir evreyi sarÄ± dÃŒÄmelere basarak 
+ulaÅabilirsiniz.
+}
+
+_textconf1_ [l=tr] {<p>Koleksiyonununuzun yapÄ±sÄ± ve sunum biÃ§imi Ã¶zel bir "konfigÃŒrasyon dosyasÄ±" 
+iÃ§inde belirtilen spesifikasyonlarla kontrol edilmektedir. Deneyimli kullanÄ±cÄ±lar bu
+konfigÃŒrasyon ayarlarÄ±nÄ± deÄiÅtirebilirler.
+
+<center><p><b> EÄer deneyimli bir kullanÄ±cÄ± deÄilseniz  doÄrudan sayfa sonuna gidin.
+</b></center> 
+
+<p>
+KonfigÃŒrasyon ayarlarÄ±nÄ± deÄiÅtirmek iÃ§in, aÅaÄÄ±da beliren veri ÃŒzerinde deÄiÅiklik yapÄ±n.
+EÄer bir hata yaparsanÄ±z "SÄ±fÄ±rla" tuÅuna basarak Ã¶zgÃŒn konfigÃŒrasyon ayarlarÄ±na dÃ¶nebilirsiniz.
+}
+
+_textreset_ [l=tr] {SÄ±fÄ±rla}
+
+_textbild1_ [l=tr] {Koleksiyon Åu anda yapÄ±landÄ±rÄ±lÄ±yor: Bu iÅlem bir sÃŒre devam edecek.
+YapÄ±landÄ±rma durumu Ã§izgisi size iÅlemin durumu hakkÄ±nda bilgi verecektir.
+}
+
+_textbild2_ [l=tr] {YapÄ±landÄ±rma iÅlemini herhangi bir anda durdurmak iÃ§in buraya basÄ±n.
+<br>ÃalÄ±ÅtÄ±ÄÄ±nÄ±z koleksiyon bir bÃŒtÃŒn halinde duracaktÄ±r.
+}
+
+_textstopbuild_ [l=tr] {YapÄ±landÄ±rmayÄ± durdur.}
+
+_textbild3_ [l=tr] {EÄer bu sayfayÄ± "yapÄ±landÄ±rmayÄ± durdur" dÃŒÄmesine basÄ±p da iptal iÅlemini
+yapmadan  terkederseniz, koleksiyon yapÄ±lanmaya devam edecek ve baÅarÄ±lÄ± 
+bir biÃ§imde kurulum tamamlanana kadar iÅlem sÃŒrecektir.
+}
+
+_textbuildcancelled_ [l=tr] {YapÄ±lanma iptal edildi.}
+
+_textbildcancel1_ [l=tr] {Koleksiyon yapÄ±landÄ±rma iÅlemi iptal edildi. YApÄ±landÄ±rma iÅlemine yeniden 
+baÅlamak ya da iÅlemde deÄiÅiklikler yapmak iÃ§in aÅaÄÄ±daki sarÄ± dÃŒÄmeleri 
+kullananÄ±n.
+}
+
+_textbsupdate1_ [l=tr] {YapÄ±landÄ±rma durumu 1 saniyede gÃŒncellenir}
+_textbsupdate2_ [l=tr] {YapÄ±landÄ±rma durumu gÃŒncellemesi}
+_textseconds_ [l=tr] {saniyede}
+_textbildsuc_ [l=tr] {Koleksiyon baÅarÄ±lÄ± bir biÃ§imde yapÄ±landÄ±rÄ±ldÄ±}
+
+_textviewbildsummary_ [l=tr] {Koleksiyon hakkÄ±nda yapÄ±landÄ±rma Ã¶zeti bilgisini daha ayrÄ±ntÄ±lÄ± olarak elde edebilirsiniz. 
+<a href="_httppagex_(bsummary)&c=_cgiargbc1dirname_" target=_top>. </a> 
+}
+
+_textfailmsg11_ [l=tr] {Koleksiyon, hiÃ§ veri iÃ§ermediÄinden dolayÄ± yapÄ±landÄ±rÄ±lamadÄ±. En azÄ±ndan bir 
+dizin veya dosyanÄ±n belirttiÄiniz "<i>kaynak veri <\i> sayfasÄ±nÄ±n iÃ§inde varolduÄuna ve
+ilgili dosya tÃŒrlerinin Greenstone'un iÅleyebileceÄi tÃŒrden olduÄuna emin olun.
+}
+
+_textfailmsg21_ [l=tr] {Koleksiyon yapÄ±landÄ±rÄ±lamadÄ± (import.pl hatasÄ±).}
+_textblcont_ [l=tr] {YapÄ±landÄ±rma seyri aÅaÄÄ±daki bilgiyi iÃ§ermektedir:}
+
+_texttryagain_ [l=tr] {LÃŒtfen <a href="_httppagecollector_" target=_top> koleksiyon ayarlarÄ±nÄ± yeniden Ã§alÄ±ÅtÄ±rÄ±n</a>
+ve yeniden deneyin.
+}
+
+_textfailmsg31_ [l=tr] {Koleksiyon yapÄ±landÄ±rÄ±lamadÄ±(buildcol.pl failed).}
+_textfailmsg41_ [l=tr] {Koleksiyon baÅarÄ± ile yapÄ±landÄ±rÄ±ldÄ± ancak kurulum gerÃ§ekleÅtirilemedi.}
+_textfailmsg71_ [l=tr] {Koleksiyonunuzun yapÄ±landÄ±rÄ±lmasÄ± sÄ±rasÄ±nda beklenmeyen bir hata oluÅtu.}
+_textretcoll_ [l=tr] {Koleksiyon ayarlarÄ±na geri dÃ¶n}
+
+_textdelperm_ [l=tr] {_cgiargbc1dirname_ koleksiyonunun tamamÄ± veya bir kÄ±smÄ± silinemedi. 
+OlasÄ± sebepleri aÅaÄÄ±dadÄ±r:
+<ul>
+<li> Greenstone'un  _gsdlhome_/collect/_cgiargbc1dirname_ directory<br> dizinini silmeye izni yok.
+Bilgisayardan _cgiargbc1dirname_ koleksiyonunu kaldÄ±rmak iÃ§in bu dizini program dÄ±ÅÄ±ndan "manuel"
+silmeniz gerekiyor.
+</ul>
+}
+
+_textdelinv_ [l=tr] {_cgiargbc1dirname_ koleksiyonu korunmalÄ± ya da geÃ§ersiz. Silme iÅlemi iptal edildi.
+}
+
+_textdelsuc_ [l=tr] {_cgiargbc1dirname_ koleksiyonu baÅarÄ± ile silindi.}
+
+_textclonefail_ [l=tr] {_cgiargclonecol_ koleksiyonu klonlanamadÄ±. OlasÄ± sebepler ÅunlardÄ±r:
+<ul>
+<li>  _cgiargclonecol_ koleksiyonu yok.
+<li> _cgiargclonecol_ koleksiyonu collect.cfg konfigÃŒrasyon dosyasÄ±na sahip deÄil.
+}
+
+_textcolerr_ [l=tr] {Koleksiyon ayarlarÄ± hatasÄ±.}
+
+_texttmpfail_ [l=tr] {Koleksiyoncu bir geÃ§ici dosyadan veya dizinden okuma veya dosyaya /dizine  
+yazma iÅleminde hata verdi. OlasÄ± hatalar ÅunlardÄ±r:
+<ul>
+<li> Greenstone _gsdlhome_/tmp dizinine okuma / yazma eriÅim hakkÄ±na sahip deÄil.
+</ul>
+}
+
+_textmkcolfail_ [l=tr] {Koleksiyoncu yeni koleksiyonun gerektirdiÄi dizin yapÄ±sÄ±nÄ± oluÅtururken
+hata verdi (mkcol.pl failed). OlasÄ± nedenleri ÅunlardÄ±r:
+<ul>
+<li> Greenstone _gsdlhome_/tmp dizinine yazma hakkÄ±na sahip deÄildir.
+<li> mkcol.pl perl skript hatasÄ±.
+</ul>
+}
+
+_textnocontent_ [l=tr] {Koleksiyoncu hatasÄ±: YEni koleksiyon iÃ§in bir isim belirlenmedi. Koleksiyoncuyu 
+yeniden Ã§alÄ±ÅtÄ±rÄ±n.
+}
+
+_textrestart_ [l=tr] {Koleksiyoncuyu yeniden Ã§alÄ±ÅtÄ±r.}
+
+_textreloaderror_ [l=tr] {Yeni koleksiyonu oluÅtururken bir hata oluÅtu. Bunun nedeni Green Stone'un
+sizin tarayÄ±cÄ±nÄ±zda "Reload : Yeniden YÃŒkle" veya "back : Geri" tuÅlarÄ±na 
+basmanÄ±z olabilir. LÃŒtfen, koleksiyoncu tarafÄ±ndan bir koleksiyon oluÅturulurken 
+bu dÃŒÄmelere basmaktan kaÃ§Ä±nÄ±n. Koleksiyoncuyu yeniden baÅlatmanÄ±zÄ± Ã¶neririz.
+}
+
+_textexptsuc_ [l=tr] {_cgiargbc1dirname_ koleksiyonu baÅarÄ±lÄ± bir biÃ§imde 
+_gsdlhome_/tmp/exported\__cgiargbc1dirname_  dizinine  ihraÃ§ edildi.
+}
+
+_textexptfail_ [l=tr] {<p> _cgiargbc1dirname_ koleksiyonunu ihraÃ§ ederken hata oluÅtu.
+
+<p> Bunun nedeni Greenstone'un "koleksiyon ihracÄ±" iÅlevini destekleyen 
+bileÅenleri iÃ§ermeden kurulumu olabilir.
+<ul>
+
+ <li>
+EÄer Greenstone'u CD-ROM'dan kurduysanÄ±z, bu bileÅenler eÄer siz 
+"Custom" kurulumu evresinde seÃ§mediyseniz yÃŒklenmeyecektir.
+Ä°lgili bileÅenleri  kurulumunuza eklemelek iÃ§in kurulum prosedÃŒrÃŒnÃŒ 
+yeniden Ã§alÄ±ÅtÄ±rabilirsiniz.
+
+ <li>
+EÄer Greenstone'u bir eweb daÄÄ±tÄ±cÄ±sÄ±ndan kurduysanÄ±z, bu iÅlevi etkin kÄ±lacak
+bir ek paketi indirmeniz ve kutmanÄ±z gerekmektedir. LÃŒtfen;
+<a href="http://www.greenstone.org">http://www.greenstone.org</a>  adresini 
+ziyaret edin veya <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>
+adresine daha ayrÄ±ntÄ±lÄ± bilgi  almak iÃ§in e-posta ile baÄlantÄ± kurun.
+</ul>
+}
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=tr] {Greenstone sanal kÃŒtÃŒphane koleksiyonlarÄ±nÄ± sunan ve yeni koleksiyonlarÄ± 
+yapÄ±landÄ±rabilen bir yazÄ±lÄ±m takÄ±mÄ±dÄ±r. Bu yazÄ±lÄ±m, Internet ÃŒzerinden veya
+CD-ROM aracÄ±lÄ±ÄÄ± ile bilginin dÃŒzenlenmesi ve yayÄ±nlanmasÄ± konusunda yeni bir
+yol aÃ§maktadÄ±r. Greenstone "Yeni Zelanda Sanal KÃŒtÃŒphane Projesi" kapsamÄ±nda
+Waikato Ãniversitesi'nde geliÅtirilmiÅ, UNESCO ve "Human Info" STK iÅbirliÄi ile 
+daÄÄ±tÄ±mÄ± gerÃ§ekleÅtirilmiÅtir. Greenstone aÃ§Ä±k kaynak kodlu bir yazÄ±lÄ±mdÄ±r,
+kod <i>http://greenstone.org</i> adresinden GNU "General Public License" 
+ilkelerine uygun bir biÃ§imde temin edilebilir.
+
+}
+
+_textgreenstone2_ [l=tr] {Yeni Zelanda Sanal KÃŒtÃŒphanesi web sitesi (<a href="http://nzdl.org">http://nzdl.org</a>) 
+Greenstone tarafÄ±ndan oluÅturulmuÅ ve sizin dikkatli incelemenize olanak 
+saÄlayan bir Ã§ok Ã¶rnek koleksiyon iÃ§ermektedir. Bu koleksiyonlar bir Ã§ok
+arama ve tarama seÃ§eneklerini ArapÃ§a, FransÄ±zca, Maori dilinde ve Ä°spanyolca olarak 
+Ã¶rneklerle gÃ¶stermektedir. AyrÄ±ca bazÄ± mÃŒzik koleksiyonlarÄ± da vardÄ±r.
+
+}
+
+# -- Missing translation: _textplatformtitle_
+_textgreenstone3_ [l=tr] {Greenstone Windows ve Unix ÃŒzerinde Ã§alÄ±Åabilir. Elinizdeki daÄÄ±tÄ±m, Windows ve Linux'un 
+bÃŒtÃŒn versiyonlarÄ± iÃ§in kullanÄ±ma hazÄ±r ikili kodlar iÃ§ermektedir. AyrÄ±ca bu daÄÄ±tÄ±m,
+sistemin Microsoft C++ veya gcc ile derlenebilen kaynak kod'un tamamÄ±nÄ± iÃ§ermektedir.
+Greenstone aynÄ± zamanda ÃŒcretsiz olarak edinilebilen Apache Webserver ve PERL ile 
+birlikte Ã§alÄ±Åabilmektedir. KullanÄ±cÄ± arayÃŒzÃŒ Netscape Navigator veya Internet 
+Explorer gibi web tarayÄ±cÄ±lar  kullanÄ±r.
+
+}
+
+_textgreenstone4_ [l=tr] {BirÃ§ok belge koleksiyonu CD-ROM'un ÃŒzerinde daÄÄ±tÄ±lmaktadÄ±r. ÃrneÄin
+<i>Humanity Development Library</i> koleksiyonu muhasebeden su saÄlÄ±ÄÄ± korumaya
+1230 yayÄ±nÄ± iÃ§ermektedir. Bu koleksiyon geliÅmekte olan ÃŒlkelerde rastlanabilen
+minimum konfigÃŒrasyonlu bilgisayarlarda rahatlÄ±kla Ã§alÄ±Åabilir. Koleksiyonun 
+iÃ§indeki bilgilere konuya gÃ¶re arama, tarama, baÅlÄ±klara gÃ¶re tarama,
+Ã¶rgÃŒtlenmeye gÃ¶re arama, nasÄ±l yapÄ±lÄ±rlar listesini tarama, ve rastgele 
+kitap kapaklarÄ±nÄ± gÃ¶zden geÃ§irme yÃ¶ntemleri ile ulaÅÄ±labilir.
+
+}
+
+# -- Missing translation: _textcustomisationtitle_
+_textgreenstone5_ [l=tr] {Greenstone esnek ve kiÅiye Ã¶zel dÃŒzenlenebilir biÃ§imde tasarlanmÄ±ÅtÄ±r.
+Yeni belge ve metadata formatlarÄ± yazÄ±lan "plugin"lerle (Perl dilinde) 
+barÄ±ndÄ±rÄ±labilir. AynÄ± Åekilde yeni metadata tarama yapÄ±larÄ± sÄ±nÄ±flandÄ±rÄ±cÄ±" 
+yazÄ±larak geliÅtirilebilir. KullanÄ±cÄ± arayÃŒzÃŒnÃŒnÃŒn genel gÃ¶rÃŒnÃŒmÃŒ ise basitÃ§e
+macro dilinde yazÄ±lan makrolarla deÄiÅtirilebilir. Corba protokolÃŒ Java tÃŒrÃŒ 
+aracÄ± programlar ile  belge koleksiyonuna yÃ¶nelik imkanlarÄ±n taamÄ±nÄ±n kullanÄ±lmasÄ±na
+imkan saÄlar.
+
+}
+
+# -- Missing translation: _textdocumentationtitle_
+# -- Missing translation: _textdocuments_
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+# -- Missing translation: _textmailinglisttitle_
+_textmailinglist_ [l=tr] {Greenstone Sanal KÃŒtÃŒphanesi YazÄ±lmÄ± hakkÄ±nda gÃ¶rÃŒÅme amaÃ§lÄ± bir  
+e-posta listesi kurulmuÅtur. Greenstone'un etkin kullanÄ±cÄ±larÄ±nÄ±n 
+bu listeye ÃŒye olmasÄ± ve gÃ¶rÃŒÅmelere katÄ±masÄ± tavsiye olunur.
+<a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.
+Listeye bir ileti gÃ¶ndermek iÃ§in <a
+href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a> adresini kullanÄ±n.
+
+}
+
+# -- Missing translation: _textbugstitle_
+_textreport_ [l=tr] {Biz, bu yazÄ±lÄ±mÄ±n sizin iÃ§in dÃŒzgÃŒn Ã§alÄ±ÅtÄ±ÄÄ±na emin olmak istiyoruz.
+LÃŒtfen her tÃŒrlÃŒ yazÄ±lÄ±m hatasÄ±nÄ± <a href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a>
+adresinden bize bildirin.
+
+}
+
+# -- Missing translation: _textgs3title_
+# -- Missing translation: _textgs3_
+
+# -- Missing translation: _textcreditstitle_
+
+_textwhoswho_ [l=tr] {Greenstone yazÄ±lÄ±mÄ± bir Ã§ok insanÄ±n iÅbirliÄini gerektiren bir Ã§alÄ±Åma 
+ile ortaya Ã§Ä±kmÄ±ÅtÄ±r. Rodger McNab ve Stefan Boddie bu projenin Ã¶ncÃŒl 
+mimarlarÄ± ve uygulamacÄ±larÄ±dÄ±r. David Bainbridge, George Buchanan, Hong Chen, 
+Elke Duncker, Carl Gutwin, Geoff Holmes, John McPherson, Craig Nevill-Manning, 
+Gordon Paynter, Bernhard Pfahringer, Todd Reed, Bill Rogers, ve  Stuart Yeates
+katkÄ±larÄ±nÄ± unutmamak gerekir. Yeni Zelanda Sanal KÃŒtÃŒphane Projesinin  diÄer 
+ÃŒyeleri de tavsiyeleri ve ilhamlarÄ± ile sistem tasarÄ±mÄ±nÄ± gerÃ§ekleÅmesinde
+Ã¶nemli katkÄ±da bulunmuÅtur. Bu kiÅiler:Mark Apperley, Sally Jo Cunningham, 
+Steve Jones, Te Taka Keegan, Michel Loots, Malika Mahoui and Lloyd Smith.
+AyrÄ±ca GNU lisanslÄ± paketlerin daÄÄ±Ä±mÄ±nda yardÄ±mlarÄ±nÄ± esirgemeyen
+MG, GDBM, PDFTOHTML, WGET, WVWARE and XLHTML kuruluÅlarÄ±na da ÅÃŒkranlarÄ±mÄ±zÄ±
+sunarÄ±z.
+
+}
+
+_textaboutgslong_ [l=tr] {about the greenstone software}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=tr] {Åu andaki kullanÄ±cÄ±larÄ±n listesi}
+_textuser_ [l=tr] {kullanÄ±cÄ±}
+_textas_ [l=tr] {hesap durumu}
+_textgroups_ [l=tr] {gruplar}
+_textcomment_ [l=tr] {comment}
+_textadduser_ [l=tr] {yeni bir kullanÄ±cÄ± ekle}
+_textedituser_ [l=tr] {deÄiÅtir}
+_textdeleteuser_ [l=tr] {sil}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=tr] {KullanÄ±cÄ± bilgisini deÄiÅtirin}
+_textadduser_ [l=tr] {Yeni bir kullanÄ±cÄ± ekleyin}
+
+_textaboutusername_ [l=tr] {KullanÄ±cÄ± adlarÄ± 2 ila 30 karakter arasÄ±nda uzunluÄa sahip olabilir.
+Bu adlar alfanÃŒmerik karakterler ile '.2 ve '_' karakterlerini iÃ§erebilir
+
+}
+
+_textaboutpassword_ [l=tr] {Åifreler 3 ila 128 karakter arasÄ±nda uzunluÄa sahip olabilir.
+Åifre iÃ§inde Ã§Ä±ktÄ±sÄ± alÄ±nabilir ASCII karakterleri kullanÄ±labilir.
+}
+
+_textoldpass_ [l=tr] {EÄer bu alan boÅ bÄ±rakÄ±lÄ±rsa eski Åifre tutulacaktÄ±r.}
+_textenabled_ [l=tr] {aktif}
+_textdisabled_ [l=tr] {kapalÄ±}
+
+_textaboutgroups_ [l=tr] {Gruplar virgÃŒlle ayrÄ±lmÄ±Å listedir, virgÃŒlden sonra boÅluk koymayÄ±n.
+
+}
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textdeleteuser_
+# -- Missing translation: _textremwarn_
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=tr] {Åifreyi deÄiÅtirin}
+_textoldpw_ [l=tr] {eski Åifre}
+_textnewpw_ [l=tr] {yeni Åifre}
+_textretype_ [l=tr] {yeni Åifreyi yeniden girin}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textsuccess_
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=tr] {KullanÄ±cÄ± adÄ± geÃ§ersiz.}
+_textinvalidpassword_ [l=tr] {Åifre geÃ§ersiz.}
+_textemptypassword_ [l=tr] {Bu kullanÄ±cÄ± iÃ§in bir baÅlangÄ±Ã§ Åifresi girin.}
+_textuserexists_ [l=tr] {Bu kullanÄ±cÄ± adÄ± halihazÄ±rda var, lÃŒtfen yeni bir kullanÄ±cÄ± adÄ± girin.}
+
+_textusernameempty_ [l=tr] {LÃŒtfen kullanÄ±cÄ± adÄ±nÄ±zÄ± girin.}
+_textpasswordempty_ [l=tr] {Eski Åifrenizi girmeniz gerekiyor.}
+_textnewpass1empty_ [l=tr] {Yeni Åifrenizi girin ve yeniden yazÄ±n.}
+_textnewpassmismatch_ [l=tr] {YazdÄ±ÄÄ±nÄ±z yeni Åifrelerin iki versiyonu birbirinden uyumsuz.}
+_textnewinvalidpassword_ [l=tr] {GeÃ§ersiz bir Åifre girdiniz.}
+_textfailed_ [l=tr] {KUllanÄ±cÄ± adÄ±nÄ±z veya Åifreniz geÃ§ersiz.}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=tr] {Greenstone SÃŒrÃŒm NumarasÄ±}
+_textframebrowser_ [l=tr] {Bu sistemi gÃ¶rÃŒntÃŒlemek iÃ§in "frame enabled" tarayÄ±cÄ±nÄ±z olmasÄ± gerekir.}
+_textusermanage_ [l=tr] {KullanÄ±cÄ± YÃ¶netimi}
+_textlistusers_ [l=tr] {kullanÄ±cÄ±larÄ± listele}
+_textaddusers_ [l=tr] {yeni bir kullanÄ±cÄ± ekle}
+_textchangepasswd_ [l=tr] {Åifre deÄiÅtir}
+_textinfo_ [l=tr] {Teknik Bilgi}
+_textgeneral_ [l=tr] {genel}
+_textarguments_ [l=tr] {argÃŒmanlar}
+_textactions_ [l=tr] {eylemler}
+_textbrowsers_ [l=tr] {tarayÄ±cÄ±lar}
+_textprotocols_ [l=tr] {protokoller}
+_textconfigfiles_ [l=tr] {KonfigÃŒrasyon dosyalarÄ±}
+_textlogs_ [l=tr] {Seyirler}
+_textusagelog_ [l=tr] {kullanÄ±m raporlarÄ±}
+# -- Missing translation: _textinitlog_
+_texterrorlog_ [l=tr] {hata raporlarÄ±}
+_textadminhome_ [l=tr] {Ana Sayfa}
+_textreturnhome_ [l=tr] {Greenstone Ana Sayfa}
+_titlewelcome_ [l=tr] {YÃ¶netim }
+_textmaas_ [l=tr] {BakÄ±m ve yÃ¶netim hizmetleri aÅaÄÄ±daki iÅlemler iÃ§in mevcuttur:}
+_textvol_ [l=tr] {seyirleri Ã§evrim iÃ§i izle}
+_textcmuc_ [l=tr] {koleksiyonlarÄ± oluÅtur, bakÄ±m yap ve gÃŒncelle}
+_textati_ [l=tr] {CGI ArgÃŒmanlarÄ± tÃŒrÃŒnde teknik bilgiye ulaÅ}
+
+_texttsaa_ [l=tr] {Bu hizmetlere sayfanÄ±n sol tarafÄ±ndaki yanal navigasyon Ã§ubuÄu ile ulaÅabilirsiniz.
+
+}
+
+_textcolstat_ [l=tr] {Koleksiyon Durumu}
+
+_textcwoa_ [l=tr] {Koleksiyonlar eÄer kendilerinin build.cfg dosyalarÄ± varsa, okunabiliyorsa  
+ve geÃ§erli bir builddate alanÄ± iÃ§eriyorsa ( >0 gibi) ve koleksiyonun ilgili index 
+dizininde  ise yalnÄ±zca "running" durumunda belirirler.
+(Bu dizin yapÄ±landÄ±rma dizini deÄildir)
+
+}
+
+# -- Missing translation: _textcafi_
+# -- Missing translation: _textcctv_
+# -- Missing translation: _textsubc_
+# -- Missing translation: _texteom_
+# -- Missing translation: _textftum_
+_textmus_ [l=tr] {main.cfg baÅarÄ±lÄ± bir biÃ§imde gÃŒncellendi}
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=tr] {_collectionname_ koleksiyonu iÃ§in Ã¶zet yapÄ±landÄ±r}
+_textflog_ [l=tr] {_collectionname_ koleksiyonu iÃ§in hata raporu}
+
+
+############################################################################
+#
+# This stuff is only used by the usability (I'd like to Complain) stuff
+#
+############################################################################
+package Global
+
+# -- Missing translation: _greenstoneusabilitytext_
+
+# -- Missing translation: _textwhy_
+# -- Missing translation: _textextraforform_
+# -- Missing translation: _textprivacybasic_
+# -- Missing translation: _textstillsend_
+
+# -- Missing translation: _texterror_
+# -- Missing translation: _textyes_
+# -- Missing translation: _textno_
+# -- Missing translation: _textclosewindow_
+# -- Missing translation: _textabout_
+# -- Missing translation: _textprivacy_
+# -- Missing translation: _textsend_
+# -- Missing translation: _textdontsend_
+# -- Missing translation: _textoptionally_
+
+# -- Missing translation: _textunderdev_
+
+# -- Missing translation: _textviewdetails_
+# -- Missing translation: _textmoredetails_
+# -- Missing translation: _texttrackreport_
+# -- Missing translation: _textcharacterise_
+# -- Missing translation: _textseverity_
+ 
+# -- Missing translation: _textbadrender_
+# -- Missing translation: _textcontenterror_
+# -- Missing translation: _textstrangebehaviour_
+# -- Missing translation: _textunexpected_
+# -- Missing translation: _textfunctionality_
+# -- Missing translation: _textother_
+
+# -- Missing translation: _textcritical_
+# -- Missing translation: _textmajor_
+# -- Missing translation: _textmedium_
+# -- Missing translation: _textminor_
+# -- Missing translation: _texttrivial_
+
+# -- Missing translation: _textwhatdoing_
+# -- Missing translation: _textwhatexpected_
+# -- Missing translation: _textwhathappened_
+
+# -- Missing translation: _cannotfindcgierror_
+
+# -- Missing translation: _textusabbanner_
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+# -- Missing translation: _textgti_
+
+# -- Missing translation: _textgtierror_
+
+# -- Missing translation: _textgtihome_
+
+# -- Missing translation: _textgtiselecttlc_
+
+# -- Missing translation: _textgtiselecttfk_
+
+# -- Missing translation: _textgticoredm_
+# -- Missing translation: _textgtiauxdm_
+# -- Missing translation: _textgtiglidict_
+# -- Missing translation: _textgtiperlmodules_
+# -- Missing translation: _textgtigreenorg_
+
+# -- Missing translation: _textgtienter_
+
+# -- Missing translation: _textgticorrectexistingtranslations_
+# -- Missing translation: _textgtidownloadtargetfile_
+# -- Missing translation: _textgtiviewtargetfileinaction_
+
+# -- Missing translation: _textgtinumchunksmatchingquery_
+
+# -- Missing translation: _textgtinumchunkstranslated_
+# -- Missing translation: _textgtinumchunksrequiringupdating_
+# -- Missing translation: _textgtinumchunksrequiringtranslation_
+
+# -- Missing translation: _textgtienterquery_
+# -- Missing translation: _textgtifind_
+
+# -- Missing translation: _textgtitranslatingchunk_
+# -- Missing translation: _textgtiupdatingchunk_
+# -- Missing translation: _textgtisubmit_
+
+# -- Missing translation: _textgtilastupdated_
+
+# -- Missing translation: _textgtitranslationfilecomplete_
+
+
+############
+# gli page
+############
+package gli
+
+# -- Missing translation: _textgli_
+# -- Missing translation: _textglilong_
+# -- Missing translation: _textglihelp_
Index: /gsdl/stable/macros/ukrainian.dm
===================================================================
--- /gsdl/stable/macros/ukrainian.dm	(revision 20131)
+++ /gsdl/stable/macros/ukrainian.dm	(revision 20131)
@@ -0,0 +1,641 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Ukrainian Language text and icon macros 
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=uk] {ÐÐµÑÑÐŸÐŽÐžÑÐœÑ Ð²ÐžÐŽÐ°ÐœÐœÑ}
+_textsource_ [l=uk] {ÐŽÐ¶ÐµÑÐµÐ»ÐŸ: }
+_textdate_ [l=uk] {ÐŽÐ°ÑÐ° Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÑ:}
+_textnumpages_ [l=uk] {Ðº-ÑÑÑ ÑÑÐŸÑÑÐœÐŸÐº: }
+
+_textsignin_ [l=uk] {ÑÐ²ÑÐ¹ÑÐž}
+
+_textdefaultcontent_ [l=uk] {Ð¡ÑÐŸÑÑÐœÐºÐ° ÐœÐµ Ð±ÑÐ»Ð° Ð·ÐœÐ°Ð¹ÐŽÐµÐœÐ°. ÐÐ°ÑÐžÑÐœÑÑÑ
+"ÐœÐ°Ð·Ð°ÐŽ" Ñ Ð²Ð°ÑÐŸÐŒÑ Ð±ÑÐ°ÑÐ·ÐµÑÑ ÑÐŸÐ± Ð¿ÐŸÐ²ÐµÑÐœÑÑÐžÑÑ ÐœÐ° ÑÑÐŸÑÑÐœÐºÑ
+Greenstone Digital Library.}
+
+_textdefaulttitle_ [l=uk] {ÐÐŸÐŒÐžÐ»ÐºÐ° GSDL}
+
+# -- Missing translation: _textbadcollection_
+
+_textselectpage_ [l=uk] {-- ÐÐžÐ±ÑÑ Ð¡ÑÐŸÑÑÐœÐºÐž --}
+
+_collectionextra_ [l=uk] {ÐŠÑ ÐºÐŸÐ»ÐµÐºÑÑÑ ÐŒÑÑÑÐžÑÑ _about:numdocs_ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐ². 
+ÐÐŸÐœÐ° Ð±ÑÐ»Ð° Ð¿ÐŸÐ±ÑÐŽÐŸÐ²Ð°ÐœÐ° _about:builddate_ ÐŽÐœÑÐ² ÑÐŸÐŒÑ.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=uk] {<p>ÐŠÑ ÐºÐŸÐ»ÐµÐºÑÑÑ ÐŒÑÑÑÐžÑÑ _numdocs_ _If_("_numdocs_" eq "1",ÐŽÐŸÐºÑÐŒÐµÐœÑ,ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐ²), Ð·Ð°Ð³Ð°Ð»ÐŸÐŒ _numbytes_.
+<p><a href="_httppagex_(bsummary)">ÐÐ°ÑÐžÑÐœÑÑÑ ÑÑÐŽÐž</a> ÑÐŸÐ± Ð¿ÐµÑÐµÐ³Ð»ÑÐœÑÑÐž ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÐž Ð¿ÐŸÐ±ÑÐŽÐŸÐ²Ðž ÐºÐŸÐ»ÐµÐºÑÑÑ.
+}
+
+_textdescrcollection_ [l=uk] {}
+# -- Missing translation: _textdescrabout_
+# -- Missing translation: _textdescrhome_
+_textdescrhelp_ [l=uk] {Ð¡ÑÐŸÑÑÐœÐºÐ° ÐŽÐŸÐ¿ÐŸÐŒÐŸÐ³Ðž}
+# -- Missing translation: _textdescrpref_
+_textdescrgreenstone_ [l=uk] {Greenstone Digital Library Software}
+_textdescrusab_ [l=uk] {Ð©ÐŸ ÐŽÐ»Ñ Ð²Ð°Ñ Ð±ÑÐ»ÐŸ ÐœÐ°Ð¹ÑÐºÐ»Ð°ÐŽÐœÑÑÐžÐŒ?}
+
+_textdescrSearch_ [l=uk] {ÐÐŸÑÑÐº ÑÐ¿ÐµÑÐžÑÑÑÐœÐžÑ
+ ÑÐµÑÐŒÑÐœÑÐ²}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textdescrTitle_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð°Ð»ÑÐ°Ð²ÑÑÐœÐžÐ¹ ÑÐ¿ÐžÑÐŸÐº Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÑÐ²}
+_textdescrCreator_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž ÑÐ¿ÐžÑÐŸÐº Ð°Ð²ÑÐŸÑÑÐ²}
+_textdescrSubject_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð·Ð° ÐºÐ°ÑÐµÐ³ÐŸÑÑÑÑ Ð¿ÑÐµÐŽÐŒÐµÑÐ°}
+# -- Missing translation: _textdescrDescription_
+# -- Missing translation: _textdescrPublisher_
+# -- Missing translation: _textdescrContributor_
+_textdescrDate_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð·Ð° ÐŽÐ°ÑÐŸÑ}
+# -- Missing translation: _textdescrType_
+# -- Missing translation: _textdescrFormat_
+# -- Missing translation: _textdescrIdentifier_
+_textdescrSource_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð·Ð° ÑÐŒ'ÑÐŒ ÑÐ°Ð¹Ð»Ð°}
+_textdescrLanguage_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð·Ð° ÐŒÐŸÐ²ÐŸÑ}
+# -- Missing translation: _textdescrRelation_
+# -- Missing translation: _textdescrCoverage_
+# -- Missing translation: _textdescrRights_
+
+_textdescrOrganization_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð·Ð° ÐŸÑÐ³Ð°ÐœÑÐ·Ð°ÑÑÑÑ}
+_textdescrKeyword_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð·Ð° ÐºÐ»ÑÑÐŸÐ²ÐžÐŒ ÑÐ»ÐŸÐ²ÐŸÐŒ}
+_textdescrHowto_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž ÐŽÐŸÐ¿ÐŸÐŒÐŸÐ³Ñ}
+_textdescrList_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž ÑÐµÐºÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°}
+_textdescrSeries_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð·Ð° Ð¿ÑÐžÐ·ÐœÐ°ÑÐµÐœÐœÑÐŒ}
+_textdescrTo_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð·Ð° Ð¿ÐŸÐ»ÐµÐŒ "ÐÑÐŽÐž"}
+_textdescrFrom_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð·Ð° Ð¿ÐŸÐ»ÐµÐŒ "ÐÐ²ÑÐŽÐºÐž"}
+_textdescrTopic_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž ÑÐ¿ÐµÑÑÐ°Ð»ÑÐœÑ ÑÐµÐŒÐž}
+_textdescrBrowse_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž}
+# -- Missing translation: _textdescrCollage_
+_textdescrPeople_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð°Ð»ÑÐ°Ð²ÑÑÐœÐžÐŒ ÑÐ¿ÐžÑÐºÐŸÐŒ Ð»ÑÐŽÐµÐ¹}
+_textdescrAcronym_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð°ÐºÑÐŸÐœÑÐŒÐž}
+_textdescrPhrase_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž ÑÑÐ°Ð·Ðž}
+_textdescrArtist_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ñ
+ÑÐŽÐŸÐ¶ÐœÐžÐºÑÐ²}
+_textdescrVolume_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð·Ð° ÑÐŸÐŒÐŸÐŒ}
+# -- Missing translation: _textdescrCountries_
+_textdescrCaptions_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Ð·Ð° Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐ°ÐŒÐž ÑÐŸÑÐŸÐ³ÑÐ°ÑÑÐ¹}
+
+
+_labelSearch_ [l=uk] {ÐÐŸÑÑÐº}
+
+# Dublin Core Metadata Element Set, Version 1.1
+_labelTitle_ [l=uk] {ÐÐ°Ð³ÐŸÐ»ÐŸÐ²ÐºÐž A-Z}
+_labelCreator_ [l=uk] {ÐÐ²ÑÐŸÑÐž A-Z}
+_labelSubject_ [l=uk] {ÐÑÐµÐŽÐŒÐµÑÐž}
+# -- Missing translation: _labelDescription_
+# -- Missing translation: _labelPublisher_
+# -- Missing translation: _labelContributor_
+_labelDate_ [l=uk] {ÐÐ°ÑÐž}
+# -- Missing translation: _labelType_
+# -- Missing translation: _labelFormat_
+# -- Missing translation: _labelIdentifier_
+_labelSource_ [l=uk] {ÐÐŒÐµÐœÐ° ÑÐ°Ð¹Ð»ÑÐ²}
+_labelLanguage_ [l=uk] {ÐÐŸÐ²Ð°}
+# -- Missing translation: _labelRelation_
+# -- Missing translation: _labelCoverage_
+# -- Missing translation: _labelRights_
+
+_labelOrg_ [l=uk] {ÐÑÐ³Ð°ÐœÑÐ·Ð°ÑÑÑ}
+_labelKeyword_ [l=uk] {ÐÐ»ÑÑÐŸÐ²Ñ ÑÐ»ÐŸÐ²Ð°}
+_labelHow_ [l=uk] {Ð¯Ðº}
+_labelSeries_ [l=uk] {Ð¡ÐµÑÑÑ}
+_labelList_ [l=uk] {Ð¡Ð¿ÐžÑÐŸÐº}
+_labelTo_ [l=uk] {ÐÐŸ}
+_labelFrom_ [l=uk] {ÐÑÐŽ}
+_labelTopic_ [l=uk] {Ð¢ÐµÐŒÐž}
+_labelBrwse_ [l=uk] {ÐÑÐŸÐŽÐžÐ²ÐžÑÐžÑÑ}
+# -- Missing translation: _labelCollage_
+_labelBrows_ [l=uk] {ÐÑÐŸÐŽÐžÐ²ÐžÑÐžÑÑ}
+_labelPeople_ [l=uk] {ÐÑÐŽÐž A-Z}
+_labelAcronym_ [l=uk] {ÐÐºÑÐŸÐœÑÐŒÐž}
+_labelPhrase_ [l=uk] {Ð€ÑÐ°Ð·Ðž}
+_labelArtist_ [l=uk] {Ð¥ÑÐŽÐŸÐ¶ÐœÐžÐºÐž}
+_labelVolume_ [l=uk] {Ð¢ÐŸÐŒÐž}
+# -- Missing translation: _labelCaptions_
+# -- Missing translation: _labelCountries_
+
+_texticontext_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž ÐŽÐŸÐºÑÐŒÐµÐœÑ}
+_texticonclosedbook_ [l=uk] {Ð²ÑÐŽÐºÑÐžÑÐž ÑÐµÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ Ñ Ð¿ÐŸÐ±Ð°ÑÐžÑÐž Ð²ÐŒÑÑÑ}
+_texticonnext_ [l=uk] {ÐŽÐŸ ÐœÐ°ÑÑÑÐ¿ÐœÐŸÑ ÑÐ°ÑÑÐžÐœÐž}
+_texticonprev_ [l=uk] {ÐŽÐŸ Ð¿ÐŸÐ¿ÐµÑÐµÐŽÐœÑÐŸÑ ÑÐ°ÑÑÐžÐœÐž}
+
+# -- Missing translation: _texticonworld_
+
+_texticonmidi_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž MIDI ÐŽÐŸÐºÑÐŒÐµÐœÑ}
+_texticonmsword_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Microsoft Word ÐŽÐŸÐºÑÐŒÐµÐœÑ}
+_texticonmp3_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž MP3 ÐŽÐŸÐºÑÐŒÐµÐœÑ}
+_texticonpdf_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž PDF ÐŽÐŸÐºÑÐŒÐµÐœÑ}
+_texticonps_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž PostScript ÐŽÐŸÐºÑÐŒÐµÐœÑ}
+_texticonppt_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž PowerPoint ÐŽÐŸÐºÑÐŒÐµÐœÑ}
+_texticonrtf_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž RTF ÐŽÐŸÐºÑÐŒÐµÐœÑ}
+_texticonxls_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž Microsoft Excel ÐŽÐŸÐºÑÐŒÐµÐœÑ}
+
+_page_ [l=uk] {ÑÑÐŸÑÑÐœÐºÐ° }
+_pages_ [l=uk] {ÑÑÐŸÑÑÐœÐºÐž}
+_of_ [l=uk] {Ð· }
+_vol_ [l=uk] {Ð¢ÐŸÐŒ}
+_num_ [l=uk] {ÐÑ.	}
+
+_textmonth00_ [l=uk] {}
+_textmonth01_ [l=uk] {Ð¡ÑÑÐµÐœÑ}
+_textmonth02_ [l=uk] {ÐÑÑÐžÐ¹}
+_textmonth03_ [l=uk] {ÐÐµÑÐµÐ·ÐµÐœÑ}
+_textmonth04_ [l=uk] {ÐÐ²ÑÑÐµÐœÑ}
+_textmonth05_ [l=uk] {Ð¢ÑÐ°Ð²ÐµÐœÑ}
+_textmonth06_ [l=uk] {Ð§ÐµÑÐ²ÐµÐœÑ}
+_textmonth07_ [l=uk] {ÐÐžÐ¿ÐµÐœÑ}
+_textmonth08_ [l=uk] {Ð¡ÐµÑÐ¿ÐµÐœÑ}
+_textmonth09_ [l=uk] {ÐÐµÑÐµÑÐµÐœÑ}
+_textmonth10_ [l=uk] {ÐÐŸÐ²ÑÐµÐœÑ}
+_textmonth11_ [l=uk] {ÐÐžÑÑÐŸÐ¿Ð°ÐŽ}
+_textmonth12_ [l=uk] {ÐÑÑÐŽÐµÐœÑ}
+
+_textdocument_ [l=uk] {ÐÐŸÐºÑÐŒÐµÐœÑ}
+_textsection_ [l=uk] {Ð§Ð°ÑÑÐžÐœÐ°}
+_textparagraph_ [l=uk] {Ð ÐŸÐ·ÐŽÑÐ»}
+
+_magazines_ [l=uk] {ÐÑÑÐœÐ°Ð»Ðž	}
+
+_nzdlpagefooter_ [l=uk] {<div class="divbar">&nbsp;</div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}
+
+_linktextHOME_ [l=uk] {ÐÐÐÐÐšÐÐ¯ Ð¡Ð¢ÐÐ ÐÐÐÐ}
+_linktextHELP_ [l=uk] {ÐÐÐÐÐÐÐÐ}
+_linktextPREFERENCES_ [l=uk] {ÐÐÐÐÐšÐ¢Ð£ÐÐÐÐÐ¯}
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=uk] {ÐÑÐŸ ÑÑ ÐºÐŸÐ»ÐµÐºÑÑÑ}
+
+# -- Missing translation: _textsubcols1_
+
+_textsubcols2_ [l=uk] {</blockquote>
+ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ Ð¿ÐµÑÐµÐ³Ð»ÑÐœÑÑÐž (Ñ Ð·ÐŒÑÐœÐžÑÐž ÐºÐŸÐ»ÐµÐºÑÑÑ, ÑÐºÑ Ð¿ÑÐŽÐºÐŸÐ»ÐµÐºÑÑÑ Ð²Ðž Ð²ÐžÐºÐŸÑÐžÑÑÐŸÐ²ÑÑÑÐµ
+ÐœÐ° ÑÑÐŸÑÑÐœÑÑ ÐœÐ°Ð»Ð°ÑÑÑÐ²Ð°ÐœÑ.}
+
+
+_titleabout_ [l=uk] {Ð¿ÑÐŸ}
+
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# Dublin Core Metadata Element Set, Version 1.1
+# -- Missing translation: _texticonhdesc_
+# -- Missing translation: _texticonhpubl_
+# -- Missing translation: _texticonhcontr_
+# -- Missing translation: _texticonhtype_
+# -- Missing translation: _texticonhform_
+# -- Missing translation: _texticonhident_
+# -- Missing translation: _texticonhrel_
+# -- Missing translation: _texticonhcover_
+# -- Missing translation: _texticonhright_
+
+# -- Missing translation: _texticonhcoll_
+# -- Missing translation: _texticonhcapt_
+# -- Missing translation: _texticonhcount_
+
+_texticonopenbookshelf_ [l=uk] {Ð·Ð°ÐºÑÐžÑÐž ÑÑ ÑÐ°ÑÑÐžÐœÑ Ð±ÑÐ±Ð»ÑÐŸÑÐµÐºÐž}
+_texticonclosedbookshelf_ [l=uk] {Ð²ÑÐŽÐºÑÐžÑÐž ÑÐµÐ¹ ÑÐŸÐ·ÐŽÑÐ» Ð±ÑÐ±Ð»ÑÐŸÑÐµÐºÐž Ñ Ð¿ÐŸÐ±Ð°ÑÐžÑÐž Ð²ÐŒÑÑÑ}
+_texticonopenbook_ [l=uk] {Ð·Ð°ÐºÑÐžÑÐž ÐºÐœÐžÐ³Ñ}
+_texticonclosedfolder_ [l=uk] {ÐÑÐŽÐºÑÐžÑÐž Ð¿Ð°Ð¿ÐºÑ Ñ Ð¿ÐŸÐ±Ð°ÑÐžÑÐž Ð²ÐŒÑÑÑ}
+_texticonclosedfolder2_ [l=uk] {Ð²ÑÐŽÐºÑÐžÑÐž Ð¿ÑÐŽÑÐŸÐ·ÐŽÑÐ»: }
+_texticonopenfolder_ [l=uk] {Ð·Ð°ÐºÑÐžÑÐž ÑÑ Ð¿Ð°Ð¿ÐºÑ}
+_texticonopenfolder2_ [l=uk] {Ð·Ð°ÐºÑÐžÑÐž Ð¿ÑÐŽÑÐµÐºÑÑÑ: }
+_texticonsmalltext_ [l=uk] {ÐÐµÑÐµÐ³Ð»ÑÐœÑÑÐž ÑÑ ÑÐ°ÑÑÐžÐœÑ ÑÐµÐºÑÑÑ}
+_texticonsmalltext2_ [l=uk] {Ð¿ÐµÑÐµÐ³Ð»ÑÐœÑÑÐž ÑÐµÐºÑÑ: }
+_texticonpointer_ [l=uk] {Ð°ÐºÑÐžÐ²ÐœÐ° ÑÐµÐºÑÑÑ}
+_texticondetach_ [l=uk] {ÐÑÐŽÐºÑÐžÑÐž ÑÑÐŸÑÑÐœÐºÑ Ð² ÐœÐŸÐ²ÐŸÐŒÑ Ð²ÑÐºÐœÑ}
+_texticonhighlight_ [l=uk] {ÐÐžÐŽÑÐ»ÐžÑÐž ÑÑÐºÐ°ÐœÑ ÑÐ»ÐŸÐ²Ð°}
+_texticonnohighlight_ [l=uk] {ÐÐµ Ð²ÐžÐŽÑÐ»ÑÑÐž ÑÑÐºÐ°ÐœÑ ÑÐ»ÐŸÐ²Ð°}
+_texticoncontracttoc_ [l=uk] {Ð ÐŸÐ·Ð³ÐŸÑÐœÑÑÐž ÑÐ°Ð±Ð»ÐžÑÑ Ð²ÐŒÑÑÑÑ}
+_texticonexpandtoc_ [l=uk] {ÐÐ³ÐŸÑÐœÑÑÐž ÑÐ°Ð±Ð»ÐžÑÑ Ð²ÐŒÑÑÑÑ}
+_texticonexpandtext_ [l=uk] {ÐÐŸÐºÐ°Ð·Ð°ÑÐž Ð²ÐµÑÑ ÑÐµÐºÑÑ}
+_texticoncontracttext_ [l=uk] {ÐÐŸÐºÐ°Ð·ÑÐ²Ð°ÑÐž ÑÐµÐºÑÑ Ð»ÐžÑÐµ ÐŽÐ»Ñ Ð²ÐžÐ±ÑÐ°ÐœÐŸÑ ÑÐ°ÑÑÐžÐœÐž}
+_texticonwarning_ [l=uk] {<b>Ð£Ð²Ð°Ð³Ð°: </b>}
+_texticoncont_ [l=uk] {Ð¿ÑÐŸÐŽÐŸÐ²Ð¶ÐžÑÐž?}
+
+_textltwarning_ [l=uk] {<div class="buttons">_imagecont_</div>
+_iconwarning_Ð ÐŸÐ·Ð³ÐŸÑÑÐ°ÐœÐœÑ ÑÑÐŸÐ³ÐŸ ÑÐµÐºÑÑÑ Ð±ÑÐŽÐµ ÐŒÑÑÑÐžÑÐž Ð²ÐµÐ»ÐžÐºÑ ÐºÑÐ»ÑÐºÑÑÑÑ 
+ÑÐœÑÐŸÑÐŒÐ°ÑÑÑ ÐŽÐ»Ñ ÐÐ°ÑÐŸÐ³ÐŸ Ð±ÑÐ°ÑÐ·ÐµÑÐ°
+}
+
+_textgoto_ [l=uk] {Ð¿ÐµÑÐµÐ¹ÑÐž ÐœÐ° ÑÑÐŸÑÑÐœÐºÑ}
+_textintro_ [l=uk] {<i>(Ð²ÑÑÑÐ¿ÐœÐžÐ¹ ÑÐµÐºÑÑ)</i>}
+
+_textCONTINUE_ [l=uk] {ÐÐ ÐÐÐÐÐÐÐ¢Ð??}
+
+_textEXPANDTEXT_ [l=uk] {Ð ÐÐÐÐÐ ÐÐ£Ð¢Ð\nÐ¢ÐÐÐ¡Ð¢}
+
+_textDETACH_ [l=uk] {ÐÐÐ'ÐÐÐÐÐ¢Ð}
+
+_textCONTRACT_ [l=uk] {ÐÐÐ ÐÐÐÐ¯Ð¢Ð\nÐ¢ÐÐÐ¡Ð¢}
+
+_textHIGHLIGHT_ [l=uk] {ÐÐÐÐÐÐÐÐÐ¯}
+
+_textNOHIGHLIGHT_ [l=uk] {ÐÐÐ\nÐÐÐÐÐÐÐÐÐ¯}
+
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=uk] {_If_(_thislast_,ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÑÐ² _thisfirst_ - _thislast_ ÐŽÐ»Ñ Ð·Ð°Ð¿ÐžÑÑ: _cgiargq_,ÐÐµÐŒÐ°Ñ ÑÐ¿ÑÐ²Ð¿Ð°ÐŽÐ°ÐœÑ ÐŽÐ»Ñ Ð·Ð°Ð¿ÐžÑÑ: _cgiargq_)}
+_textnoquerytitle_ [l=uk] {Ð¡ÑÐŸÑÑÐœÐºÐ° Ð¿ÐŸÑÑÐºÑ}
+
+_textsome_ [l=uk] {ÐŽÐµÑÐºÑ}
+_textall_ [l=uk] {Ð²ÑÐµ}
+_textboolean_ [l=uk] {Ð±ÑÐ»ÐµÐ²ÐžÐ¹}
+# -- Missing translation: _textranked_
+_textnatural_ [l=uk] {Ð¿ÑÐžÑÐŸÐŽÐœÑ}
+#_textsome_ {_If_(_cgiargb_,ranked,some)}
+#_textall_ {_If_(_cgiargb_,boolean,all)}
+#_textformsome_ {_If_(_cgiargb_,ranked,some)}
+#_textformall_ {_If_(_cgiargb_,natural,all)}
+_texticonsearchhistorybar_ [l=uk] {ÑÑÑÐŸÑÑÑ Ð¿ÐŸÑÑÐºÑ}
+
+# -- Missing translation: _textifeellucky_
+
+#alt text for query buttons
+_textusequery_ [l=uk] {Ð²ÐžÐºÐŸÑÐžÑÑÐŸÐ²ÑÐ²Ð°ÑÐž ÑÐµÐ¹ Ð·Ð°Ð¿ÐžÑ}
+# -- Missing translation: _textfreqmsg1_
+_textpostprocess_ [l=uk] {_If_(_quotedquery_,<br><i>Ð¿ÐµÑÐµÑÐ°Ñ
+ÐŸÐ²Ð°ÐœÐŸ ÑÐŸÐ± Ð·ÐœÐ°Ð¹ÑÐž _quotedquery_</i>
+)}
+_textinvalidquery_ [l=uk] {ÐÐµÐ¿ÑÐ°Ð²ÐžÐ»ÑÐœÑÐ¹ ÑÐŸÑÐŒÐ°Ñ Ð·Ð°Ð¿ÐžÑÑ}
+
+_textmorethan_ [l=uk] {ÐÑÐ»ÑÑ ÐœÑÐ¶ }
+_textapprox_ [l=uk] {ÐÑÐŸ }
+_textnodocs_ [l=uk] {ÐÐµÐŒÐ°Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐ², ÑÐŸ Ð²ÑÐŽÐ¿ÐŸÐ²ÑÐŽÐ°ÑÑÑ Ð·Ð°Ð¿ÐžÑÑ.}
+_text1doc_ [l=uk] {1 ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð²ÑÐŽÐ¿ÐŸÐ²ÑÐŽÐ°Ñ Ð·Ð°Ð¿ÐžÑÑ.}
+_textlotsdocs_ [l=uk] {ÐŽÐŸÐºÑÐŒÐµÐœÑÐž, ÑÐŸ Ð²ÑÐŽÐ¿ÐŸÐ²ÑÐŽÐ°ÑÑÑ Ð·Ð°Ð¿ÐžÑÑ.}
+_textmatches_ [l=uk] {Ð¡Ð¿ÑÐ²Ð¿Ð°ÐŽÐ°ÐœÐœÑ }
+_textbeginsearch_ [l=uk] {ÐÐŸÑÐ°ÑÐž ÐÐŸÑÑÐº}
+_textrunquery_ [l=uk] {ÐÐžÐºÐŸÐœÐ°ÑÐž ÐÐ°Ð¿ÐžÑ}
+_textclearform_ [l=uk] {ÐÑÐžÑÑÐžÑÐž ÑÐŸÑÐŒÑ}
+
+#these go together in form search:
+#"Word or phrase  (fold, stem)  ... in field"
+_textwordphrase_ [l=uk] {Ð¡Ð»ÐŸÐ²ÐŸ Ð°Ð±ÐŸ ÑÑÐ°Ð·Ð°}
+_textinfield_ [l=uk] {... Ð² Ð¿ÐŸÐ»Ñ}
+_textfoldstem_ [l=uk] {(fold, stem)}
+
+# -- Missing translation: _textadvquery_
+_textallfields_ [l=uk] {Ð²ÑÑ Ð¿ÐŸÐ»Ñ}
+_texttextonly_ [l=uk] {Ð»ÐžÑÐµ ÑÐµÐºÑÑ}
+_textand_ [l=uk] {Ñ}
+_textor_ [l=uk] {Ð°Ð±ÐŸ}
+_textandnot_ [l=uk] {Ñ ÐœÐµ}
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=uk] {ÐšÑÐºÐ°ÑÐž _indexselection_ _If_(_jselection_, of _jselection_) _If_(_gselection_, ÐœÐ° _gselection_ ÑÑÐ²ÐœÑ) _If_(_nselection_, ÐœÐ° _nselection_ ÐŒÐŸÐ²Ñ) ÑÐŸ ÐŒÑÑÑÐžÑÑ _querytypeselection_ ÑÐ»ÑÐ²}
+
+# -- Missing translation: _textadvancedsearch_
+
+# -- Missing translation: _textformsimplesearch_
+
+# -- Missing translation: _textformadvancedsearch_
+
+
+_textnojsformwarning_ [l=uk] {Ð£Ð²Ð°Ð³Ð°: Javascript Ð·Ð°Ð±ÐŸÑÐŸÐœÐµÐœÐ° ÐœÑ ÐÐ°ÑÐŸÐŒÑ Ð±ÑÐ°ÑÐ·ÐµÑÑ. <br>Ð©ÐŸÐ± Ð²ÐžÐºÐŸÑÐžÑÑÐŸÐ²ÑÐ²Ð°ÑÐž Ð¿ÐŸÑÑÐº Ð· ÑÐŸÑÐŒÐŸÑ ÐŽÐŸÐ·Ð²ÐŸÐ»ÑÑÐµ Ð¹ÐŸÐ³ÐŸ Ð²ÐžÐºÐŸÑÐžÑÑÐ°ÐœÐœÑ.}
+# -- Missing translation: _textdatesearch_
+_textstartdate_ [l=uk] {ÐÐŸÑÐžÐœÐ°ÑÑÐž Ð· (Ð°Ð±ÐŸ Ð»ÐžÑÐµ) ÐŽÐ°ÑÐž:}
+_textenddate_ [l=uk] {ÐÑÐœÑÐµÐ²Ð° ÐŽÐ°ÑÐ°:}
+_textbc_ [l=uk] {B.C.E.}
+_textad_ [l=uk] {C.E.}
+# -- Missing translation: _textexplaineras_
+
+_textstemon_ [l=uk] {(ÑÐ³ÐœÐŸÑÑÐ²Ð°ÑÐž Ð·Ð°ÐºÑÐœÑÐµÐœÐœÑ ÑÐ»ÑÐ²)}
+
+_textsearchhistory_ [l=uk] {ÐšÑÐºÐ°ÑÐž Ð² ÑÑÑÐŸÑÑÑ}
+
+#text macros for search history
+_textnohistory_ [l=uk] {ÐÑÑÐŸÑÑÑ Ð¿ÐŸÑÑÐºÑ ÐœÐµÐŽÐŸÑÑÑÐ¿ÐœÐ°}
+_texthresult_ [l=uk] {ÑÐµÐ·ÑÐ»ÑÑÐ°Ñ}
+_texthresults_ [l=uk] {ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÐž}
+# -- Missing translation: _texthallwords_
+_texthsomewords_ [l=uk] {ÐŽÐµÑÐºÑ ÑÐ»ÐŸÐ²Ð°}
+# -- Missing translation: _texthboolean_
+# -- Missing translation: _texthranked_
+_texthcaseon_ [l=uk] {Ð²ÐµÐ»ÐžÑÐžÐœÐ° Ð»ÑÑÐµÑ Ð¿ÐŸÐ²ÐžÐœÐœÐ° ÑÐ¿ÑÐ²Ð¿Ð°ÐŽÐ°ÑÐž}
+# -- Missing translation: _texthcaseoff_
+# -- Missing translation: _texthstemon_
+# -- Missing translation: _texthstemoff_
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# -- Missing translation: _textprefschanged_
+_textsetprefs_ [l=uk] {Ð²ÐžÑÑÐ°Ð²ÐžÑÐž ÐœÐ°Ð»Ð°ÑÑÑÐ²Ð°ÐœÐœÑ}
+_textsearchprefs_ [l=uk] {ÐÐ°Ð»Ð°ÑÑÑÐ²Ð°ÐœÐœÑ Ð¿ÐŸÑÑÐºÑ}
+_textcollectionprefs_ [l=uk] {ÐÐ°Ð»Ð°ÑÑÑÐ²Ð°ÐœÐœÑ ÐºÐŸÐ»ÐµÐºÑÑÑ}
+# -- Missing translation: _textpresentationprefs_
+_textpreferences_ [l=uk] {ÐÐ°Ð»Ð°ÑÑÑÐ²Ð°ÐœÐœÑ}
+_textcasediffs_ [l=uk] {Ð ÑÐ·ÐœÐžÑÑ Ð² Ð²ÐµÐ»ÐžÑÐžÐœÑ Ð±ÑÐºÐ²:}
+_textignorecase_ [l=uk] {ÑÐ³ÐœÐŸÑÑÐ²Ð°ÑÐž Ð²ÐµÐ»ÐžÑÐžÐœÑ Ð±ÑÐºÐ²}
+_textmatchcase_ [l=uk] {Ð²ÐµÐ»ÐžÐºÑ/ÐŒÐ°Ð»ÐµÐœÑÐºÑ Ð±ÑÐºÐ²Ðž Ð¿ÐŸÐ²ÐžÐœÐœÑ ÑÐ¿ÑÐ²Ð¿Ð°ÐŽÐ°ÑÐž}
+_textwordends_ [l=uk] {ÐÐ°ÐºÑÐœÑÐµÐœÐœÑ ÑÐ»ÑÐ²:}
+_textstem_ [l=uk] {ÑÐ³ÐœÐŸÑÑÐ²Ð°ÑÐž Ð·Ð°ÐºÑÐœÑÐµÐœÐœÑ ÑÐ»ÑÐ²}
+_textnostem_ [l=uk] {ÑÑÐ»Ðµ ÑÐ»ÐŸÐ²ÐŸ Ð¿ÐŸÐ²ÐžÐœÐœÐµ ÑÐ¿ÑÐ²Ð¿Ð°ÐŽÐ°ÑÐž}
+_textprefop_ [l=uk] {ÐÐŸÐ²ÐµÑÐœÑÑÐž ÐŽÐŸ _maxdocoption_ hits with _hitsperpageoption_ ÑÐ¿ÐŸÐ²Ð¿Ð°ÐŽÐ°ÐœÑ ÐœÐ° ÑÑÐŸÑÑÐœÐºÑ.}
+_textextlink_ [l=uk] {ÐÐŸÑÑÑÐ¿ ÐŽÐŸ Ð·ÐŸÐ²ÐœÑÑÐœÑÑ
+ Web-ÑÑÐŸÑÑÐœÐŸÐº:}
+_textintlink_ [l=uk] {ÐÐŸÐºÑÐŒÐµÐœÑÐž ÐŸÐŽÐµÑÐ¶Ð°ÐœÑ Ð·:}
+_textlanguage_ [l=uk] {ÐÐŸÐ²Ð° ÑÐœÑÐµÑÑÐµÐ¹ÑÑ:}
+_textencoding_ [l=uk] {ÐÐŸÐŽÑÐ²Ð°ÐœÐœÑ:}
+_textformat_ [l=uk] {ÑÐŸÑÐŒÐ°Ñ ÑÐœÑÐµÑÑÐµÐ¹ÑÑ:}
+_textall_ [l=uk] {Ð²ÑÐµ}
+# -- Missing translation: _textquerymode_
+_textsimplemode_ [l=uk] {ÑÐµÐ¶ÐžÐŒ Ð¿ÑÐŸÑÑÐŸÐ³ÐŸ Ð·Ð°Ð¿ÐžÑÑ}
+_textadvancedmode_ [l=uk] {ÑÐºÐ»Ð°ÐŽÐœÑÑÐžÐ¹ ÑÐµÐ¶ÐžÐŒ Ð·Ð°Ð¿ÐžÑÑ (ÐŽÐŸÐ·Ð²ÐŸÐ»ÑÑ Ð±ÑÐ»ÐµÐ²ÐžÐ¹ Ð¿ÐŸÑÑÐº, Ð²ÐžÐºÐŸÑÐžÑÑÐŸÐ²ÑÑÑÐž !, &, |, Ñ ÐŽÑÐ¶ÐºÐž)}
+_textlinkinterm_ [l=uk] {ÑÐµÑÐµÐ· intermediate ÑÑÐŸÑÑÐœÐºÑ}
+_textlinkdirect_ [l=uk] {Ð¿ÐµÑÐµÑ
+ÐŸÐŽÑÑÐµ Ð¿ÑÑÐŒÐŸ ÑÑÐŽÐž}
+_textdigitlib_ [l=uk] {ÐµÐ»ÐµÐºÑÑÐŸÐœÐœÐ° Ð±ÑÐ±Ð»ÑÐŸÑÐµÐºÐ°}
+# -- Missing translation: _textweb_
+_textgraphical_ [l=uk] {ÐÑÐ°ÑÑÑÐœÐžÐ¹}
+_texttextual_ [l=uk] {ÑÐµÐºÑÑÐŸÐ²ÐžÐ¹}
+_textcollectionoption_ [l=uk] {<p>
+ÐÐºÐ»ÑÑÐžÑÐž Ð¿ÑÐŽÐºÐŸÐ»ÐµÐºÑÑÑ:
+<br>}
+
+# -- Missing translation: _textrelateddocdisplay_
+_textsearchhistory_ [l=uk] {ÐÑÑÐŸÑÑÑ Ð¿ÐŸÑÑÐºÑ:}
+_textnohistory_ [l=uk] {ÐÐµÐŒÐ°Ñ ÑÑÑÐŸÑÑÑ Ð¿ÐŸÑÑÐºÑ}
+_texthistorydisplay_ [l=uk] {Ð¿ÐŸÐºÐ°Ð·Ð°ÑÐž _historynumrecords_ Ð·Ð°Ð¿ÐžÑÑÐ² ÑÑÑÐŸÑÑÑ Ð¿ÐŸÑÑÐºÑ}
+_textnohistorydisplay_ [l=uk] {ÐœÐµ Ð¿ÐŸÐºÐ°Ð·ÑÐ²Ð°ÑÐž ÑÑÑÐŸÑÑÑ Ð¿ÐŸÑÑÐºÑ}
+
+#_texttypesearch_ {Type of search:}
+#_texttextsearch_ {text search}
+_textformsearch_ [l=uk] {ÐÐŸÑÑÐº Ð·Ð° ÑÐŸÑÐŒÐŸÑ:}
+_textplainsearch_ [l=uk] {ÐÑÐŸÑÑÐžÐ¹ Ð¿ÐŸÑÑÐº:}
+# -- Missing translation: _textqueryboxsize_
+# -- Missing translation: _textregbox_
+_textbigbox_ [l=uk] {Ð²ÐµÐ»ÐžÐºÐµ Ð¿ÐŸÐ»Ðµ Ð·Ð°Ð¿ÐžÑÑ}
+_textformtype_ [l=uk] {Ð¢ÐžÐ¿ ÑÐŸÑÐŒÐž:}
+_textsimple_ [l=uk] {Ð¿ÑÐŸÑÑÐžÐ¹}
+_textadvanced_ [l=uk] {ÑÑÐºÐ»Ð°ÐŽÐœÐµÐœÐžÐ¹.}
+
+# used in "with 4 fields" in the form search box
+_textwith_ [l=uk] {Ð·}
+_textfields_ [l=uk] {Ð¿ÐŸÐ»Ñ}
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=uk] {Ð¡ÐŸÑÑÑÐ²Ð°ÑÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÐž Ð·Ð°}
+_textalsoshowing_ [l=uk] {ÑÐ°ÐºÐŸÐ¶ Ð¿ÐŸÐºÐ°Ð·Ð°ÐœÐŸ}
+_textwith_ [l=uk] {Ð· ÑÐŸÐœÐ°Ð¹Ð±ÑÐ»ÑÑÐµ}
+_textdocsperpage_ [l=uk] {ÐŽÐŸÐºÑÐŒÐµÐœÑÑÐ² ÐœÐ° ÑÑÐŸÑÑÐœÐºÑ}
+
+_textfilterby_ [l=uk] {ÐÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÐž, ÑÐŸ ÐŒÑÑÑÑÑÑ}
+_textall_ [l=uk] {Ð²ÑÐµ}
+_textany_ [l=uk] {Ð±ÑÐŽÑ-ÑÐºÐžÐ¹}
+_textwords_ [l=uk] {ÑÐ»ÑÐ²}
+_textleaveblank_ [l=uk] {Ð·Ð°Ð»ÐžÑÑÐµ ÑÐµ Ð¿ÐŸÐ»Ðµ Ð¿ÐŸÑÐŸÐ¶ÐœÑÐŒ, ÑÐŸÐ± ÐŸÐŽÐµÑÐ¶Ð°ÑÐž Ð²ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐž}
+
+_browsebuttontext_ [l=uk] {"Ð¡ÐŸÑÑÑÐ²Ð°ÑÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÐž"}
+
+_nodata_ [l=uk] {<i>ÐœÐµÐŒÐ°Ñ ÐŽÐ°ÐœÐžÑ
+</i>}
+_docs_ [l=uk] {ÐŽÐŸÐºÑÐŒÐµÐœÑÐž}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=uk] {ÐÐŸÐ¿ÐŸÐŒÐŸÐ³Ð°}
+_textSearchshort_ [l=uk] {ÑÑÐºÐ°ÑÐž ÑÐ»ÐŸÐ²Ð°}
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitleshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐŸÐŒ}
+_textCreatorshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð°Ð²ÑÐŸÑÐŸÐŒ}
+_textSubjectshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð¿ÑÐµÐŽÐŒÐµÑÐ°ÐŒÐž}
+# -- Missing translation: _textDescriptionshort_
+# -- Missing translation: _textPublishershort_
+# -- Missing translation: _textContributorshort_
+_textDateshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÐŽÐ°ÑÐŸÑ}
+# -- Missing translation: _textTypeshort_
+# -- Missing translation: _textFormatshort_
+# -- Missing translation: _textIdentifiershort_
+_textSourceshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÑÐŒ'ÑÐ² ÑÐ°Ð¹Ð»Ð°}
+_textLanguageshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÐŒÐŸÐ²ÐŸÑ}
+# -- Missing translation: _textRelationshort_
+# -- Missing translation: _textCoverageshort_
+# -- Missing translation: _textRightsshort_
+
+_textSeriesshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÑÐµÑÑÑÐŒÐž}
+_textToshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð¿ÐŸÐ»ÐµÐŒ ÐÐŸ}
+_textFromshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð¿ÐŸÐ»ÐµÐŒ ÐÐ²ÑÐŽÐºÐž}
+_textBrowseshort_ [l=uk] {Ð¿ÐµÑÐµÐ³Ð»ÑÐŽÐ°ÑÐž ÑÐµÐºÑÑÐž}
+_textOrganizationshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÐŸÑÐ³Ð°ÐœÑÐ·Ð°ÑÑÑÑ}
+_textHowtoshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÑÐ¿ÐžÑÐºÐŸÐŒ "ÑÐº"}
+_textTopicshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÑÐµÐŒÐŸÑ}
+_textPeopleshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð»ÑÐŽÑÐŒÐž}
+_textAcronymshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð¿ÐŸÑÐ»ÑÐŽÐŸÐ²ÐœÑÑÑÑ Ð°ÐºÑÐŸÐœÑÐŒÑÐ²}
+_textPhraseshort_ [l=uk] {ÑÑÐ°Ð·Ðž, ÑÐŸ Ð·ÑÑÑÑÑÑÐ°ÑÑÑÑÑ Ð² Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÑÑ
+}
+_textArtistshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ñ
+ÑÐŽÐŸÐ¶ÐœÐžÐºÐŸÐŒ}
+_textKeywordshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÐºÐ»ÑÑÐŸÐ²ÐžÐŒÐž ÑÐ»ÐŸÐ²Ð°ÐŒÐž}
+_textVolumeshort_ [l=uk] {ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÑÐŸÐŒÐŸÐŒ}
+# -- Missing translation: _textCountriesshort_
+_textdefaultshorttext_ [l=uk] {ÐœÐµÐ²ÑÐŽÐŸÐŒÐ° ÐºÐ»Ð°ÑÐžÑÑÐºÐ°ÑÑÑ}
+
+_textSearchlong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÑÑÐºÐ°ÑÐž ÑÐ»ÐŸÐ²Ð°</i>, 
+ÑÐŸ Ð²ÐžÐœÐžÐºÐ°ÑÑÑ ÐœÐ° ÑÑÐŸÑÑÐœÑÑ "Ð¿ÐŸÑÑÐº". ÐŠÐµ Ð¿ÐµÑÑÐ° ÑÑÐŸÑÑÐœÐºÐ°, ÑÐŸ Ð²ÐžÐœÐžÐºÐ°Ñ,
+ÐºÐŸÐ»Ðž ÐÐž Ð¿ÐŸÑÐžÐœÐ°ÑÑÐµ ÑÐŸÐ±ÐŸÑÑ, ÐŽÐŸ ÐœÐµÑ ÐŒÐŸÐ¶ÐœÐ° Ð¿ÐµÑÐµÐ¹ÑÐž Ð· ÑÐœÑÐžÑ
+ ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>Ð¿ÐŸÑÑÐº</i>. }
+
+
+# Dublin Core Metadata Element Set, Version 1.1
+
+_textTitlelong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐŸÐŒ</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐž Ð°-Ñ</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº ÐºÐœÐžÐ³ Ð² Ð°Ð»ÑÐ°Ð²ÑÑÐœÐŸÐŒÑ Ð¿ÐŸÑÑÐŽÐºÑ.  }
+
+# Not true DC, kept for legacy reasons
+_textCreatorlong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð°Ð²ÑÐŸÑÐŸÐŒ</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>Ð°Ð²ÑÐŸÑÐž Ð°-Ñ</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº, 
+Ð²ÑÐŽÑÐŸÑÑÐŸÐ²Ð°ÐœÐžÐ¹ Ð·Ð° ÑÐŒÐµÐœÐ°ÐŒÐž Ð°Ð²ÑÐŸÑÑÐ².  }
+
+_textSubjectlong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð¿ÑÐµÐŽÐŒÐµÑÐ°ÐŒÐž</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>Ð¿ÑÐµÐŽÐŒÐµÑÐž</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº Ð¿ÑÐµÐŽÐŒÐµÑÑÐ², 
+ÐœÐ° ÐºÐœÐžÐ¶ÐºÐŸÐ²ÑÐ¹ Ð¿ÐŸÐ»ÐžÑÑ.  }
+
+# -- Missing translation: _textDescriptionlong_
+
+# -- Missing translation: _textPublisherlong_
+
+# -- Missing translation: _textContributorlong_
+
+_textDatelong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÐŽÐ°ÑÐŸÑ</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>ÐŽÐ°ÑÐž</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº, 
+Ð²ÑÐŽÑÐŸÑÑÐŸÐ²Ð°ÐœÐžÐ¹ Ð·Ð° ÐŽÐ°ÑÐ°ÐŒÐž.  }
+
+# -- Missing translation: _textTypelong_
+
+# -- Missing translation: _textFormatlong_
+
+# -- Missing translation: _textIdentifierlong_
+
+# Not true DC, kept for legacy reasons
+_textSourcelong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÑÐŒ'ÑÐ² ÑÐ°Ð¹Ð»Ð°</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>ÑÐŒÐµÐœÐ° ÑÐ°Ð¹Ð»ÑÐ²</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº, 
+Ð²ÑÐŽÑÐŸÑÑÐŸÐ²Ð°ÐœÐžÐ¹ Ð·Ð° ÑÐŒÐµÐœÐ°ÐŒÐž ÑÐ°Ð¹Ð»ÑÐ².  }
+
+_textLanguagelong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÐŒÐŸÐ²ÐŸÑ</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>ÐŒÐŸÐ²Ðž</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº, 
+Ð²ÑÐŽÑÐŸÑÑÐŸÐ²Ð°ÐœÐžÐ¹ Ð·Ð° ÐŒÐŸÐ²Ð°ÐŒÐž.  }
+
+# -- Missing translation: _textRelationlong_
+
+# -- Missing translation: _textCoveragelong_
+
+# -- Missing translation: _textRightslong_
+
+
+
+_textOrganizationlong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÐŸÑÐ³Ð°ÐœÑÐ·Ð°ÑÑÑÑ</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>ÐŸÑÐ³Ð°ÐœÑÐ·Ð°ÑÑÑ</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº, 
+Ð²ÑÐŽÑÐŸÑÑÐŸÐ²Ð°ÐœÐžÐ¹ Ð·Ð° ÐŸÑÐ³Ð°ÐœÑÐ·Ð°ÑÑÑÐŒÐž.  }
+
+_textHowtolong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÑÐ¿ÐžÑÐºÐŸÐŒ "ÑÐº"</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>ÑÐº</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº ÑÑÑÑÑÐŸÐº.  }
+
+_textTopiclong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÑÐµÐŒÐŸÑ</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>ÑÐµÐŒÐž</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº ÑÐµÐŒ.  }
+
+_textTolong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð¿ÐŸÐ»ÐµÐŒ ÐÐŸ<i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>ÐÐŸ</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº Ð°ÐŽÑÐµÑ.  }
+
+_textFromlong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð¿ÐŸÐ»ÐµÐŒ ÐÐ²ÑÐŽÐºÐž</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>Ð·Ð²ÑÐŽÐºÐž</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº, 
+Ð²ÑÐŽÑÐŸÑÑÐŸÐ²Ð°ÐœÐžÐ¹ Ð·Ð° ÑÐŒÐµÐœÐ°ÐŒÐž ÑÐžÑ
+, Ñ
+ÑÐŸ Ð¿ÑÐžÑÐ»Ð°Ð² ÑÐµÐºÑÑÐž.  }
+
+_textSerieslong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÑÐµÑÑÑÐŒÐž</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>ÑÐµÑÑÑ</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº ÑÐµÑÑÐ¹, 
+ÑÐŸ Ñ Ð² ÐºÐŸÐ»ÐµÐºÑÑÑ.  }
+
+_textBrowselong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>Ð¿ÐµÑÐµÐ³Ð»ÑÐŽÐ°ÑÐž ÑÐµÐºÑÑÐž</i>, ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž
+ÐºÐœÐŸÐ¿ÐºÐž <i>Ð¿ÐµÑÐµÐ³Ð»ÑÐŽ</i>.  }
+
+_textPeoplelong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð»ÑÐŽÑÐŒÐž</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>Ð»ÑÐŽÐž</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº, 
+Ð²ÑÐŽÑÐŸÑÑÐŸÐ²Ð°ÐœÐžÐ¹ Ð·Ð° Ð¿ÑÐžÐ·Ð²ÐžÑÐ°ÐŒÐž.  }
+
+_textAcronymlong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ð¿ÐŸÑÐ»ÑÐŽÐŸÐ²ÐœÑÑÑÑ Ð°ÐºÑÐŸÐœÑÐŒÑÐ²</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>Ð°ÐºÑÐŸÐœÑÐŒÐž</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº Ð°ÐºÑÐŸÐœÑÐŒÑÐ²
+Ñ ÐŒÑÑÑÑ ÐŽÐµ Ð²ÐŸÐœÐž Ð·ÑÑÑÑÑÑÐ°ÑÑÑÑÑ.  }
+
+_textPhraselong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÑÑÐ°Ð·Ðž, ÑÐŸ Ð·ÑÑÑÑÑÑÐ°ÑÑÑÑÑ Ð² Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÑÑ
+</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>ÑÑÐ°Ð·Ðž</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº ÑÑÐ°Ð·.  }
+
+_textArtistlong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° Ñ
+ÑÐŽÐŸÐ¶ÐœÐžÐºÐŸÐŒ</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>Ñ
+ÑÐŽÐŸÐ¶ÐœÐžÐºÐž</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº, 
+Ð²ÑÐŽÑÐŸÑÑÐŸÐ²Ð°ÐœÐžÐ¹ Ð·Ð° ÑÐŒÐµÐœÐ°ÐŒÐž Ñ
+ÑÐŽÐŸÐ¶ÐœÐžÐºÑÐ².  }
+
+_textKeywordlong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÐºÐ»ÑÑÐŸÐ²ÐžÐŒÐž ÑÐ»ÐŸÐ²Ð°ÐŒÐž</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>ÐºÐ»ÑÑÐŸÐ²Ñ ÑÐ»ÐŸÐ²Ð°</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº ÐºÐ»ÑÑÐŸÐ²ÐžÑ
+ ÑÐ»ÑÐ².  }
+
+_textVolumelong_ [l=uk] {<p>ÐÐž ÐŒÐŸÐ¶ÐµÑÐµ <i>ÐŸÐŽÐµÑÐ¶Ð°ÑÐž ÐŽÐŸÑÑÑÐ¿ ÐŽÐŸ Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÐ¹ Ð·Ð° ÑÐŸÐŒÐŸÐŒ</i> 
+ÐœÐ°ÑÐžÑÐœÑÐ²ÑÐž ÐºÐœÐŸÐ¿ÐºÑ <i>ÑÐŸÐŒÐž</i>.  ÐŠÐµ Ð²ÐžÐ²ÐµÐŽÐµ ÑÐ¿ÐžÑÐŸÐº ÑÐŸÐŒÑÐ².  }
+
+# -- Missing translation: _textCaptionslong_
+
+# -- Missing translation: _textCountrieslong_
+
+
+_textdefaultlongtext_ [l=uk] {<p>ÐÐ°ÑÐžÑÐœÑÑÑ ÐœÐ° ÐºÐœÐŸÐ¿ÐºÑ <i>ÐœÐµÐ²ÑÐŽÐŸÐŒÑ</i> ÑÐŸÐ± Ð¿ÐµÑÐµÐ³Ð»ÑÐœÑÑÐž
+Ð¿ÑÐ±Ð»ÑÐºÐ°ÑÑÑ (Ð²ÑÐŽÑÐŸÑÑÐŸÐ²Ð°ÐœÑ Ð·Ð° ÐœÐµÐ²ÑÐŽÐŸÐŒÐžÐŒ Ð¿ÐŸÐ»ÐµÐŒ).  }
+
+# -- Missing translation: _texthelptopics_
+
+# -- Missing translation: _textreadingdocs_
+
+# -- Missing translation: _texthelpreadingdocs_
+
+# -- Missing translation: _texthelpsearching_
+
+_textdatesearch_ [l=uk] {ÐšÑÐºÐ°ÑÐž Ð·Ð° ÐÐ°ÑÐ°ÐŒÐž}
+
+# -- Missing translation: _texthelpdatesearch_
+
+_textchangeprefs_ [l=uk] {ÐÐŒÑÐœÐžÑÐž ÐÐ°ÑÑ ÐœÐ°Ð»Ð°ÑÑÑÐ²Ð°ÐœÐœÑ}
+
+# -- Missing translation: _texthelppreferences_
+
+_texttanumbrowseoptions_ [l=uk] {ÐÑÐœÑÑ _numbrowseoptions_ ÑÐ¿ÐŸÑÐŸÐ±ÑÐ² Ð·ÐœÐ°Ð¹ÑÐž ÑÐœÑÐŸÑÐ²Ð°ÑÑÑ Ð² ÑÑÐ¹ ÐºÐŸÐ»ÐµÐºÑÑÑ:}
+
+_textsimplehelpheading_ [l=uk] {Ð¯Ðº ÑÑÐºÐ°ÑÐž ÑÐœÑÐŸÑÐŒÐ°ÑÑÑ Ð² ÐºÐŸÐ»ÐµÐºÑÑÑ _collectionname_}
+
+# -- Missing translation: _texthelpscope_
Index: /gsdl/stable/macros/urdu.dm
===================================================================
--- /gsdl/stable/macros/urdu.dm	(revision 20131)
+++ /gsdl/stable/macros/urdu.dm	(revision 20131)
@@ -0,0 +1,862 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# English Language text and icon macros 
+#
+######################################################################
+#
+# This is the main macro file for translation when creating an 
+# interface in another language.
+
+# Under the 'text macros' comments are text macros of the form:
+# _macroname_ {macro value}
+# Everything between the {} is the text to be translated. This text 
+# may itself contain macros (i.e. characters other than space between
+# underscore characters, e.g. _about:numdocs_ or _textpage_). These
+# macro names occurring within text shouldn't be translated but should
+# be left as they are. Underscores or curly brackets occurring 
+# naturally within the text should be escaped with a leading backslash
+# (i.e. '\_', '\{' or '\}).
+#
+# Comment lines (other than those described above) need not be 
+# translated (i.e. any lines beginning with '#', like this line).
+#
+# The simplest way to translate this file is to save it as something
+# else (e.g. french.dm) and work through translating all the text
+# macro values and icon comments.
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=ur] {Ø¬Ø±Ø§ÛØ¯}  
+
+# these three used by the default format statement of the demo and dls collections.
+
+_textdate_ [l=ur] {ØªØ§Ø±ÛØ® Ø§ØŽØ§Ø¹Øª}  
+_textnumpages_ [l=ur] {ØµÙØ­Ø§Øª Ú©Û ØªØ¹Ø¯Ø§Ø¯}  
+
+
+
+_textdefaultcontent_ [l=ur] {Ø¢ÙŸ Ú©Ø§ Ù
+Ø·ÙÙØšÛ ØµÙØ­Û ÙÛÛÚº Ù
+Ù Ø³Ú©Ø§Û ØšØ±Ø§Û Ù
+ÛØ±ØšØ§ÙÛ Ø§ÙŸÙÛ ØšØ±Ø§Ø€Ø²Ø± Ú©Ø§ "ØšÛÚ©" ØšÙ¹Ù Ø¯ØšØ§ØŠÛÚº ÛØ§ Ú¯Ø±ÛÙ Ø³Ù¹ÙÙ Ø§ØµØšØ¹Û Ú©ØªØš Ø®Ø§ÙÛ Ú©Û ÙÛÛÛ Ø§ÙÙŸØ± Ø¯ÛØ§ Ú¯ÛØ§ ÛÙÙ
+ ØšÙ¹Ù Ø¯ØšØ§ ÛÛÚºÛ}  
+
+_textdefaulttitle_ [l=ur] {Ø¬Û Ø§ÛØ³ ÚÛ Ø§ÛÙ ØºÙØ·Û}  
+
+_textbadcollection_ [l=ur] {ÛÛ Ù
+Ø¬Ù
+ÙØ¹Û (ØšÙØ§Ù
+ "_cvariable_") Ø§Ø³ Ú¯Ø±ÛÙ Ø³Ù¹ÙÙ ÚÛØ¬ÛÙ¹Ù ÙØ§ØŠØšØ±ÛØ±Û Ù
+ÛÚº Ù
+ÙØ¬ÙØ¯ ÙÛÛÚº ÛÛ}  
+
+_textselectpage_ [l=ur] {ØµÙØ­Û Ù
+ÙØªØ®Øš Ú©Ø±ÛÚº}  
+
+_collectionextra_ [l=ur] {Ø§Ø³ Ù
+Ø¬Ù
+ÙØ¹Û Ù
+ÛÚº _about:numdocs_ Ù
+Ø³ÙØ¯Ø§Øª Ù
+ÙØ¬ÙØ¯ ÛÛÚº Ø§ÙØ± ÛÛ _about:builddate_ Ø¯Ù ÙØšÙ ØšÙØ§ÛØ§ Ú¯ÛØ§ ØªÚŸØ§}  
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=ur] {<p> Ø§Ø³ Ù
+Ø¬Ù
+ÙØ¹Û Ù
+ÛÚº _numbytes_ Ù
+ÛÚº Ø³Û __numdocs_ _If_("_numdocs_" eq "1",Ø¯Ø³ØªØ§ÙÛØ²,Ø¯Ø³ØªØ§ÙÛØ²),ÙŸØ§ÛÛ Ø¬Ø§ØªÛ ÛÛÚºÛ
+Ø§Ø³ ÙØ¶Ø¹ ÛÙÛ Ù
+Ø¬Ù
+ÙØ¹Û Ú©Ø§ Ø¬Ø§ÛØ²Û ÙÛÙÛ Ú©Û ÙÛÛ <p><a href="_httppagex_(bsummary)">Ø§Ø³ Ø¬Ú¯Û ÙŸØ± Ú©ÙÚ© Ú©Ø±ÛÚº}  
+
+_textdescrcollection_ [l=ur] {}
+_textdescrabout_ [l=ur] {ØØµÙØ­Û ØªØ¹Ø§Ø±Ù}  
+_textdescrhome_ [l=ur] {ØµÙØ­Û Ø§ÙÙ}  
+
+_textdescrpref_ [l=ur] {ØµÙØ­Û ØªÙØžÛÙ
+Ø§Øª}  
+_textdescrgreenstone_ [l=ur] {Ú¯Ø±ÛÙ Ø³Ù¹ÙÙ ÚÛØ¬ÛÙ¹Ù ÙØ§Ø¡ØšØ±ÛØ±Û Ø³Ø§ÙÙ¹ ÙÛØŠØ±}  
+_textdescrusab_ [l=ur] {Ú©Ø³ Ú©Û Ø§Ø³ØªØ¹Ù
+Ø§Ù Ù
+ÛÚº Ù
+ØŽÚ©Ù ÙŸÛØŽ Ø§ÙØ¡Û}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=ur] {ØªÙØ§ØŽ}  
+_labelSearch_ [l=ur] {ØªÙØ§ØŽ}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=ur] {Ø¹ÙÙØ§Ù}  
+_labelTitle_ [l=ur] {Ø¹ÙÙØ§ÙØ§Øª}  
+_textCreator_ [l=ur] {ØªÛØ§Ø± Ú©ÙÙØ¯Û}  
+_labelCreator_ [l=ur] {ØªØ¹Ù
+ÛØ± Ú©ÙÙØ¯Ú¯Ø§Ù}  
+_textSubject_ [l=ur] {Ù
+Ø¶Ù
+ÙÙ}  
+_labelSubject_ [l=ur] {Ù
+ÙØ¶ÙØ¹Ø§Øª}  
+
+_labelDescription_ [l=ur] {ØªÙØµÛÙØ§Øª}  
+_textPublisher_ [l=ur] {ØŽÙØ§Ø®Øª Ú©ÙÙØ¯Û}  
+_labelPublisher_ [l=ur] {ØŽØ§ØŠØ¹ Ú©Ø±Ø¯Û}  
+_textContributor_ [l=ur] {Ù
+Ø¹Ø§ÙÙ}  
+_labelContributor_ [l=ur] {Ø­ØµÛ ÚØ§ÙÙÛ ÙØ§ÙÛ}  
+_textDate_ [l=ur] {ØªØ§Ø±ÛØ®}  
+_labelDate_ [l=ur] {ØªÙØ§Ø±ÛØ®}  
+_textType_ [l=ur] {ÙØ³Ù
+}  
+_labelType_ [l=ur] {Ø§ÙØ³Ø§Ù
+}  
+
+
+_textIdentifier_ [l=ur] {ØŽÙØ§Ø®Øª Ú©ÙÙØ¯Û}  
+_labelIdentifier_ [l=ur] {ØŽÙØ§Ø®Øª Ú©ÙÙØ¯Ú¯Ø§Ù}  
+_textSource_ [l=ur] {Ù
+Ø³Ù Ú©Ø§ ÙØ§Ù
+}  
+_labelSource_ [l=ur] {Ø§Ø³Ù
+ Ù
+Ø³Ù}  
+_textLanguage_ [l=ur] {Ø²ØšØ§Ù}  
+_labelLanguage_ [l=ur] {Ø²ØšØ§ÙÛÚº}  
+_textRelation_ [l=ur] {Ø±Ø§ØšØ·Û}  
+_labelRelation_ [l=ur] {Ø±Ø§ØšØ·Û}  
+
+
+_textRights_ [l=ur] {Ø­ÙÙÙ}  
+_labelRights_ [l=ur] {Ø­ÙÙÙ}  
+
+# DLS metadata set
+_textOrganization_ [l=ur] {ØªÙØžÛÙ
+}  
+_labelOrganization_ [l=ur] {ØªÙØžÛÙ
+Ø§Øª}  
+_textKeyword_ [l=ur] {Ø§ÛÙ
+ Ø§ØµØ·ÙØ§Ø­}  
+_labelKeyword_ [l=ur] {Ø§ÛÙ
+ Ø§ØµØ·ÙØ§Ø­Ø§Øª}  
+_textHowto_ [l=ur] {Ú©ÛØ³Û}  
+_labelHowto_ [l=ur] {Ú©ÛØ³Û}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=ur] {Ø¬Ù
+ÙÛ}  
+_labelPhrase_ [l=ur] {Ø¹ØšØ§Ø±Ø§Øª}  
+
+
+_textBrowse_ [l=ur] {ÙØ±Ù Ú¯Ø±Ø¯Ø§ÙÛ}  
+_labelBrowse_ [l=ur] {ÙØ±Ù Ú¯Ø±Ø¯Ø§ÙÛ Ú©Ø±ÛÚº}  
+_textTo_ [l=ur] {Ú©Ù}  
+_labelTo_ [l=ur] {Ú©Ù}  
+_textFrom_ [l=ur] {Ù
+ÙØ¬Ø§ÙØš}  
+_labelFrom_ [l=ur] {Ù
+ÙØ¬Ø§ÙØš}  
+
+_labelAcronym_ [l=ur] {Ù
+Ø®ÙÙØ§Øª}  
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=ur] {ÙØ±Ù Ú¯Ø±Ø¯Ø§ÙÛ ØšÙØ­Ø§Øž _1_}  
+
+_textdescrSearch_ [l=ur] {Ù
+Ø®ØµÙØµ Ø§ØµØ·ÙØ§Ø­Ø§Øª Ú©Û ØªÙØ§ØŽ}  
+_textdescrType_ [l=ur] {ÙØ±Ù Ú¯Ø±Ø¯Ø§ÙÛ ØšÙØ­Ø§Øž ÙØ³Ù
+}  
+_textdescrIdentifier_ [l=ur] {ÙØ±Ù Ú¯Ø±Ø¯Ø§ÙÛ ØšÙØ­Ø§Øž ØŽÙØ§Ø®ØªÛ ÙÙ
+ØšØ±}  
+_textdescrSource_ [l=ur] {ÙØ±Ù Ú¯Ø±Ø¯Ø§ÙÛ ØšÙØ­Ø§Øž Ø§Ø³Ù
+ Ù
+Ø³Ù}  
+_textdescrTo_ [l=ur] {Browse by To field}  
+_textdescrFrom_ [l=ur] {ÙØ±Ù Ú¯Ø±Ø¯Ø§ÙÛ ØšÙØ­Ø§Øž Ú©Û Ø·Ø±Ù Ø³Û}  
+
+
+
+
+_textdescrBrowse_ [l=ur] {Ù
+Ø³ÙØ¯Ø§Øª Ú©Û ÙØ±Ù Ú¯Ø±Ø¯Ø§ÙÛ}  
+
+_texticonclosedbook_ [l=ur] {Ø§Ø³ Ù
+Ø³ÙØ¯Û Ú©Ù Ú©ÚŸÙÙÛÚº Ø§ÙØ± Ù
+ÙØ¯Ø±Ø¬Ø§Øª Ù
+ÙØ§Ø­ØžÛ ÙØ±Ù
+Ø§Ø¡ÛÚº}  
+_texticonnext_ [l=ur] {Ø§Ú¯ÙÛ Ø­ØµÛ ØªÚ©}  
+_texticonprev_ [l=ur] {ÙŸÚÚŸÙÛ Ø­ØµÛ ØªÚ©}  
+
+_texticonworld_ [l=ur] {ÙÛØš Ú©Ø§ Ù
+Ø³ÙØ¯Û Ù
+ÙØ§Ø­ØžÛ Ú©Ø±ÛÚº}  
+
+_texticonmidi_ [l=ur] {MIDI Ù
+Ø³ÙØ¯Û Ú©Ù Ù
+ÙØ§Ø­ØžÛ Ú©Ø±ÛÚº}  
+_texticonmsword_ [l=ur] {Ù
+Ø§Ø¡ÛÚ©Ø±Ù Ø³Ø§ÙÙ¹ ÙØ±Ú Ú©Ø§ Ù
+Ø³ÙØ¯Û Ù
+ÙØ§Ø­ØžÛ Ú©Ø±ÛÚº}  
+_texticonmp3_ [l=ur] {MP3 Ø¯Ø³ØªØ§ÙÛØ² Ú©Ù Ù
+ÙØ§Ø­Ø¶Û Ú©Û Ø¬ÛÛ}  
+_texticonpdf_ [l=ur] {PDF Ù
+Ø³ÙØ¯Û Ù
+ÙØ§Ø­ØžÛ Ú©Ø±ÛÚº }  
+_texticonps_ [l=ur] {ÙŸÙØ³Ù¹ Ø³Ú©Ø±ÙŸÙ¹ Ú©Ø§ Ù
+Ø³ÙØ¯Û Ù
+ÙØ§Ø­ØžÛ Ú©Ø±ÛÚº}  
+_texticonppt_ [l=ur] {ÙŸØ§ÙØ± ÙŸÙØ§Ø¡ÙÙ¹ Ú©Ø§ Ù
+Ø³ÙØ¯Û Ù
+ÙØ§Ø­ØžÛ Ú©Ø±ÛÚº}  
+_texticonrtf_ [l=ur] {RTFØ¯Ø³ØªØ§ÙÛØ² Ù
+ÙØ§Ø­ØžÛ Ú©Ø±ÛÚº}  
+_texticonxls_ [l=ur] {Ù
+Ø§Ø¡ÛÚ©Ø±ÙØ³Ø§ÙÙ¹ Ø§ÛÚ©Ø³Ù Ú©Ø§  Ù
+Ø³ÙØ¯Û Ù
+ÙØ§Ø­ØžÛ Ú©Ø±ÛÚº}  
+
+_page_ [l=ur] {ØµÙØ­Û}  
+_pages_ [l=ur] {ØµÙØ­Ø§Øª}  
+_of_ [l=ur] {Ú©Ø§}  
+
+_num_ [l=ur] {ÙÙ
+ØšØ±}  
+
+_textmonth00_ [l=ur] {}
+_textmonth01_ [l=ur] {Ø¬ÙÙØ±Û}  
+_textmonth02_ [l=ur] {ÙØ±ÙØ±Û}  
+_textmonth03_ [l=ur] {Ù
+Ø§Ø±Ú}  
+_textmonth04_ [l=ur] {Ø§ÙŸØ±ÛÙ}  
+_textmonth05_ [l=ur] {Ù
+ØŠÛ}  
+_textmonth06_ [l=ur] {Ø¬ÙÙ}  
+_textmonth07_ [l=ur] {Ø¬ÙÙØ§ ØŠÛ}  
+_textmonth08_ [l=ur] {Ø§Ú¯Ø³Øª}  
+_textmonth09_ [l=ur] {Ø³ØªÙ
+ØšØ±}  
+_textmonth10_ [l=ur] {Ø§Ú©ØªÙØšØ±}  
+_textmonth11_ [l=ur] {ÙÙÙ
+ØšØ±}  
+_textmonth12_ [l=ur] {Ø¯Ø³Ù
+ØšØ±}  
+
+_textdocument_ [l=ur] {Ø¯Ø³ØªØ§ÙÛØ²}  
+_textsection_ [l=ur] {Ø­ØµÛ}  
+_textparagraph_ [l=ur] {ÙŸÛØ±Ø§Ú¯Ø±Ø§Ù}  
+
+_magazines_ [l=ur] {Ù
+ÛÚ¯Ø²ÛÙ}  
+
+
+
+_linktextHOME_ [l=ur] {ØµÙØ­Û Ø§ÙÙ}  
+_linktextHELP_ [l=ur] {Ù
+Ø¯Ø¯}  
+_linktextPREFERENCES_ [l=ur] {ÙŸÛØŽÚ©Ø³ Ú©Û ØªÙØžÛÙ
+Ø§Øª}  
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=ur] {Ú¯Ø±ÛÙ Ø³Ù¹ÙÙ Ø§ØµØšØ¹Û Ú©ØªØš Ø®Ø§ÙÛ}  
+
+
+
+_textadmin_ [l=ur] {Ø­Ø§Ú©Ù
+ Ú©Ø§ ØµÙØ­Û}  
+_textabgs_ [l=ur] {Ú¯ÛÙ Ø³Ù¹ÙÙ Ú©Û ØšØ§Ø±Û Ù
+ÛÚº}  
+_textgsdocs_ [l=ur] {Ú¯ÛÙ Ø³Ù¹ÙÙ Ú©Û ÙÚ©ÚŸØª ÙŸÚÚŸØª}  
+
+_textdescradmin_ [l=ur] {ØØ§Ø³ Ø³Û Ø¢ÙŸ ÙÛ ØµØ§Ø±Ù Ø¯Ø§Ø®Ù Ú©Ø± Ø³Ú©ØªÛ ÛÛÚº Ø§ÙØ± Ú¯Ø±ÛÙ Ø³Ù¹ÙÙ Ú©Û Ø§ÙØ³Ù¹Ø§ÙÛØŽÙ Ù
+ÛÚº Ù
+Ø¬Ù
+ÙØ¹Û Ø¬Ø§Øª Ú©Û ØªÙØ®ÛØµ Ú©Ø± Ø³Ú©ØªÛ ÛÛÚº}  
+
+
+
+_textdescrgodocs_ [l=ur] {Ú¯Ø±ÛÙ Ø³Ù¹ÙÙ Ú©Û ÚŸØ¯Ø§ÛØª ÙØ§Ù
+Û}  
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+
+_textdescrgli_ [l=ur] {ÛÛ ÙØŠÛ Ù
+Ø¬Ù
+ÙØ¹Û Ø¬Ø§Øª ØšÙØ§ÙÛØ ÙŸÛÙÛ Ø³Û Ù
+ÙØ¬ÙØ¯ Ù
+Ø¬Ù
+ÙØ¹Û Ø¬Ø§Øª Ú©Ù ØªØšØ¯ÛÙ Ø§ÙØ± ÛÙ¹Ø§ÙÛ Ù
+ÛÚº Ù
+Ø¯Ø¯ ÙØ±Ø§ÛÙ
+ Ú©Ø±ØªØ§ ÛÛ}  
+
+package collector
+
+_textcollector_ [l=ur] {Ø¬Ù
+Ø¹ Ú©ÙÙØ¯Û}  
+
+
+package depositor
+
+_textdepositor_ [l=ur] {Ø¬Ù
+Ø¹ Ú©ÙÙØ¯Û	}  
+
+
+package gti
+
+_textgti_ [l=ur] {Ú¯Ø±ÛÙ Ø³Ù¹ÙÙ Ù
+ØªØ±Ø¬Ù
+}  
+_textdescrtranslator_ [l=ur] {ÛÛ Ú©Ø«ÛØ±Ø§ÙÙØ³Ø§ÙÛ Ú¯Ø±ÛÙ Ø³Ù¹ÙÙ Ø§ÙÙ¹Ø±ÙÛØ³ Ú©Ù ØªØ§Ø²Û ØªØ±ÛÙ Ø±Ú©ÚŸÙÛ Ù
+ÛÚº Ù
+Ø¯Ø¯ ÙØ±Ø§ÛÙ
+ Ú©Ø±ØªØ§ ÛÛ}  
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=ur] {Ø§Ø³ Ù
+Ø¬Ù
+ÙØ¹Û Ú©Û ØšØ§Ø±Û Ù
+ÛÚº	}  
+
+_textsubcols1_ [l=ur] {<p>ÛÛ Ù
+Ø¬Ù
+ÙØ¹Û _1_ ÚÚŸÙÙ¹Û Ù
+Ø¬Ù
+ÙØ¹Û Ø¬Ø§Øª ÙŸØ± Ù
+ØŽØªÙ
+ÙÛÛÛ Ø¬Ù Ù
+ÛÚº Ø³ÛØ¯Ø³ØªÛØ§Øš Ø¯Ø±Ø¬ Ø°ÛÙ ÛÛÚº :<blockquote>}  
+
+_textsubcols2_ [l=ur] {</blockquote>
+ØØ¢ÙŸ ÙŸÛØŽÚ©ØŽ Ú©Û ØªÙØ¶ÛÙ
+Ø§Øª Ú©Û ØµÙÚŸÛ ÙŸØ±Ù
+ÙØ¬ÙØ¯Û Ø²ÛØ± Ø§Ø³ØªØ¹Ù
+Ø§Ù Ù
+Ø¬Ù
+ÙØ¹Û Ø¬Ø§Øª Ø§ÙØ± Ø°ÛÙÛ Ù
+Ø¬Ù
+ÙØ¹Û Ø¬Ø§Øª Ú©Ø§ Ø¬Ø§ØŠØ²Û ÙÛ (ÛØ§ ØªØšØ¯ÛÙÛ Ú©Ø±) Ø³Ú©ØªÛ ÛÛÚºÛ}  
+
+_titleabout_ [l=ur] {ØšØ§Ø±Û Ù
+ÛÚº	}  
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=ur] {Ú©ØªØš Ø®Ø§ÙÛ Ú©Û Ø§Ø³ Ø­ØµÛ Ú©Ù ØšÙØ¯ Ú©Ø±ÛÚº}  
+_texticonclosedbookshelf_ [l=ur] {Ú©ØªØš Ø®Ø§ÙÛ Ú©Û Ø§Ø³ ØŽØ¹ØšÛ Ú©Ù Ú©ÚŸÙÙÛÚº Ø§ÙØ± Ù
+ÙØ¯Ø±Ø¬Ø§Øª Ù
+ÙØ§Ø­ØžÛ ÙØ±Ù
+Ø§ØŠÛÚº}  
+_texticonopenbook_ [l=ur] {Ø§Ø³ Ú©ØªØ§Øš Ú©Ù ØšÙØ¯ Ú©Ø±ÛÚº}  
+_texticonclosedfolder_ [l=ur] {Ø§Ø³ ØªÛ ØšÙØ¯ Ú©Ù Ú©ÚŸÙØÙÛ Ø§ÙØ± Ø§Ø³ Ù
+ÛÚº Ù
+ÙØ¬ÙØ¯ Ù
+ÙØ§Ø¯ Ú©Ø§ Ø¬Ø§ÛØ²Û ÙÛ Ø¬Û}  
+_texticonclosedfolder2_ [l=ur] {Ø°ÛÙÛ ØŽØ¹ØšÛ Ú©Ù Ú©ÚŸÙÙÛÚº}  
+_texticonopenfolder_ [l=ur] {Ø§Ø³ ÙÙÙÚØ± Ú©Ù ØšÙØ¯ Ú©Ø±ÛÚº}  
+
+_texticonsmalltext_ [l=ur] {Ù
+ØªÙ Ú©Û Ø§Ø³ Ø­ØµÛ Ú©Ù Ù
+ÙØ§Ø­ØžÛ Ú©Ø±ÛÚº}  
+_texticonsmalltext2_ [l=ur] {Ù
+ØªÙ Ù
+ÙØ§Ø­ØžÛ Ú©Ø±ÛÚº:}  
+_texticonpointer_ [l=ur] {Ù
+ÙØ¬ÙØ¯Û ØŽØ¹ØšÛ}  
+_texticondetach_ [l=ur] {Ø§Ø³ ØµÙØ­Û Ú©Ù Ø§ÙÚ¯ Ø¯Ø±ÛÚÛ Ù
+ÛÚº Ú©ÚŸÙÙÛÚº}  
+_texticonhighlight_ [l=ur] {ØªÙØ§ØŽ Ú©Û Ú¯ØŠ Ø§ØµØ·ÙØ§Ø­Ø§Øª Ú©Ù Ø§Ø¬Ø§Ú¯Ø± Ú©Ø±ÛÚº}  
+_texticonnohighlight_ [l=ur] {ØªÙØ§ØŽ Ú©Û Ú¯ØŠ Ø§ØµØ·ÙØ§Ø­Ø§Øª Ú©Ù Ø§Ø¬Ø§Ú¯Ø± ÙÛ Ú©Ø±ÛÚº}  
+_texticoncontracttoc_ [l=ur] {ÙÛØ±Ø³Øª Ø§ØšÙØ§Øš Ú©Ù Ø³Ú©ÛÚÙ}  
+_texticonexpandtoc_ [l=ur] {ÙÛØ±Ø³Øª Ù
+ÙØ¯Ø±Ø¬Ø§Øª Ú©Ù ÙŸÚŸÛÙØ§ØŠÛÚº}  
+_texticonexpandtext_ [l=ur] {ØªÙ
+Ø§Ù
+ Ù
+ØªÙ Ø¯Ú©ÚŸØ§ØŠÛÚº}  
+_texticoncontracttext_ [l=ur] {ØµØ±Ù Ù
+ÙØªØ®Øš Ú©Ø±Ø¯Û Ø­ØµÛ Ú©Ù Ø¯Ú©ÚŸØ§Ù}  
+_texticonwarning_ [l=ur] {<b>ØªÙØšÛÛ: </b>}  
+_texticoncont_ [l=ur] {Ø¬Ø§Ø±Û Ø±ÛÛØ}  
+
+
+
+_textgoto_ [l=ur] {ØµÙØ­Û ÙŸØ± Ø¬Ø§ØŠÛÚº}  
+_textintro_ [l=ur] {<i>(ØªØ¹Ø§Ø±ÙÛ Ù
+ØªÙ)</i>}  
+
+_textCONTINUE_ [l=ur] {Ø¬Ø§Ø±Û Ø±ÛÛØ}  
+
+_textEXPANDTEXT_ [l=ur] {Ù
+ØªÙ Ú©Ù ÙŸÚŸÛÙØ§ØŠÛÚº}  
+
+_textCONTRACTCONTENTS_ [l=ur] {Ù
+Ø¹Ø§ÛØ¯Û Ú©Ø§ Ù
+ØªÙ}  
+
+_textDETACH_ [l=ur] {Ø§ÙÚ¯ Ú©Ø±ÛÚº}  
+
+_textEXPANDCONTENTS_ [l=ur] {Ù
+ÙØ¯Ø±Ø¬Ø§Øª Ú©Ù ÙŸÚŸÛÙØ§ØŠÛÚº}  
+
+_textCONTRACT_ [l=ur] {Ù
+ØªÙ Ú©Ù ØšÙØ¯ Ú©Ø±ÛÚº}  
+
+_textHIGHLIGHT_ [l=ur] {Ø§Ø¬Ø§Ú¯Ø± Ú©Ø±ÛÚº}  
+
+_textNOHIGHLIGHT_ [l=ur] {Ø§Ø¬Ø§Ú¯Ø± ÙÛ Ú©Ø±ÛÚº}  
+
+_textPRINT_ [l=ur] {ÚÚŸØ§ÙŸÛÚº}  
+
+_textnextsearchresult_ [l=ur] {Ø§Ú¯ÙÛ ØªÙØ§ØŽ ØŽØ¯Û ÙØªØ§ØŠØ¬}  
+_textprevsearchresult_ [l=ur] {ØªÙØ§ØŽ Ú©ÛØ§ ÚŸÙØ§ ÙŸÚÚŸÙØ§ ÙØªÛØ¬Û}  
+
+# macros for printing page
+_textreturnoriginal_ [l=ur] {ØšÙÛØ§Ø¯Û ØµÙØ­Û ÙŸØ± ÙØ§ÙŸØ³ Ø¢ØŠÛÚº}  
+_textprintpage_ [l=ur] {Ø§Ø³ ØµÙØ­Û Ú©Ù ÚÚŸØ§ÛÛÚº}  
+_textshowcontents_ [l=ur] {ÙÛØ±Ø³Øª Ù
+ÙØ§Ø­ØžÛ Ú©Ø±ÛÚº}  
+_texthidecontents_ [l=ur] {ÙÛØ±Ø³Øª Ù
+ÙØ¯Ø±Ø¬Ø§Øª Ú©Ù ÚÚŸÙŸØ§ØŠÛÚº}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=ur] {Ø§Ú¯Ø±_(_thislast_,results _thisfirst_ - _thislast_ for query: _cgiargq_,No matches for query: _cgiargq}  
+_textnoquerytitle_ [l=ur] {ØµÙØ­Û ØªÙØ§ØŽ}  
+
+
+
+
+
+
+
+
+
+
+
+#alt text for query buttons
+
+_textfreqmsg1_ [l=ur] {Ø§ÙÙØ§Øž Ú©Û ØªØ¹Ø¯Ø§Ø¯}  
+
+
+
+
+
+
+
+
+
+
+_textmatches_ [l=ur] {Ù
+Ù
+Ø§Ø«Ù}  
+
+
+
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=ur] {Ø§ÙÙØ§Øž}  
+
+
+
+
+_textallfields_ [l=ur] {ØªÙ
+Ø§Ù
+ Ù
+ÙØ¯Ø±Ø¬Ø§Øª}  
+_texttextonly_ [l=ur] {ØµØ±Ù Ù
+ØªÙ}  
+
+
+
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=ur] {ØªÙØ§ØŽ Ú©Ø±Ù_indexselection_ _If_(_jselection_,of _jselection_ )_If_(_gselection_, at _gselection_ level )_If_(_nselection_,in _nselection_ language ) Ù
+ÛÚºØ Ø¬Ø³ Ù
+ÛÚº ÛÛ Ø§ÙÙØ§Øž ÙŸØ§Û Ø¬Ø§ØªÛ ÛÙÚº_querytypeselection_}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textdatesearch_ [l=ur] {Ø§ÙÙŸ Ø§Ø³ Ù
+ÙØ§Ø¯ Ú©Ù Ú©Ø³Û ØªØ§Ø±ÛØ® Ù
+ÛÚº ØªÙØ§ØŽ Ø³Ú©ØªÛ ÛÛÚºØ ÛØ§ Ú©Ø³Û Ø®Ø§Øµ ØªØ§Ø±ÛÚº Ú©Û Ù
+ÙØ§Ø¯ Ú©Ù ÚÚŸÙÙÚ Ø³Ú©ØªÛ ÛÛÚºÛ ÛÛ ØªÙØ§ØŽ Ú©Ø§ Ø§ÛÚ© Ø§Ø®ØªÛØ§Ø±Û ÙŸÛÙÙ ÛÛ}  
+
+
+
+_textad_ [l=ur] {C.E.}  
+_textexplaineras_ [l=ur] {ØšØ¹Ø¯ Ù
+ÛÙ}  
+
+
+
+
+
+#text macros for search history
+
+_texthresult_ [l=ur] {ÙØªÛØ¬Û}  
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+_textsearchprefs_ [l=ur] {ØªÙØ§ØŽ Ú©Ø±ÙÛ Ú©Û ØªÙØžÛÙ
+Ø§Øª}  
+
+_textpresentationprefs_ [l=ur] {ÙŸÛØŽÚ©ØŽ Ú©Û ØªÙØžÛÙ
+Ø§Øª}  
+
+_textcasediffs_ [l=ur] {ÚÚŸÙÙ¹Û Ø§ÙØ± ØšÚÛ Ø­Ø±ÙÙ ØªÛØ¬Û Ú©Û ÙØ±Ù}  
+_textignorecase_ [l=ur] {ØšÚÛ / ÚÚŸÙÙ¹Û Ø­Ø±ÙÙ ØªÛØ¬Û Ú©Û ÙØ±Ù Ú©Ù ÙØžØ± Ø§ÙØ¯Ø§Ø² Ú©Ø±ÛÚº}  
+_textmatchcase_ [l=ur] {ÚÚŸÙÙ¹Û /  ØšÚÛ Ø­Ø±ÙÙ ØªÛØ¬Û ÛØ± ØµÙØ±Øª Ù
+ÛÚº Ù
+Ø·Ø§ØšÙØª Ø±Ú©ÚŸØªÛ ÛÙÚº}  
+
+
+
+_textaccentdiffs_ [l=ur] {ÙÛØ¬Û Ú©Û ÙØ±Ù}  
+_textignoreaccents_ [l=ur] {ÙÛØ¬Û Ú©Û ÙØ±Ù Ú©Ù ÙØžØ± Ø§ÙØ¯Ø§Ø² Ú©Ø±ÛÚº}  
+_textmatchaccents_ [l=ur] {ÙÛØ¬Û ÛØ± ØµÙØ±Øª Ù
+ÛÚº Ù
+Ø·Ø§ØšÙØª Ø±Ú©ÚŸØªØ§ ÛÙ}  
+
+
+
+_textintlink_ [l=ur] {Ø¯Ø³ØªØ§ÙÛØ²Ø±Ø§Øª Ø­Ø§ØµÙ Ú©ÛÛ Ú¯Û ØšØ°Ø±ÛØ¹Û:}  
+_textlanguage_ [l=ur] {Ø§Ø³ØªØ¹Ù
+Ø§Ù ÛÙÙÛ ÙØ§ÙÛ Ø²ØšØ§Ù}  
+
+
+_textall_ [l=ur] {ØªÙ
+Ø§Ù
+}  
+
+
+
+_textlinkinterm_ [l=ur] {Ø¯Ø±Ù
+ÛØ§ÙÛ ØµÙØ­Û Ú©Û Ù
+Ø¯Ø¯ Ø³Û}  
+_textlinkdirect_ [l=ur] {ØšØ±Ø§Û Ø±Ø§Ø³Øª ÙÛØ§Úº Ø¬Ø§ØŠÛ}  
+_textdigitlib_ [l=ur] {Ø§ØµØšØ¹Û Ú©ØªØš Ø®Ø§ÙÛ}  
+
+
+
+_textcollectionoption_ [l=ur] {ØŽØ§Ù
+Ù Ú©ÛÛ Ø¬Ø§ÙÛ ÙØ§ÙÛ Ø°ÛÙÛ Ù
+Ø¬Ù
+ÙØ¹Û Ø¬Ø§Øª}  
+
+
+_textformsearchtype_ [l=ur] {ØšØ¹Ø¯ Ù
+ÛÙ}  
+
+
+_textlargebox_ [l=ur] {ØšÚØ§}  
+
+
+
+_textnohistory_ [l=ur] {ØªØ§Ø±ÛØ® ØªÙØ§ØŽ ÙØ¯Ø§Ø±Ø¯ ÛÛ}  
+
+_textnohistorydisplay_ [l=ur] {ØªØ§Ø±ÛØ® ØªÙØ§ØŽ ØžØ§ÛØ± ÙÛ ÛÙ}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=ur] {Ù
+Ø³ÙØ¯Ø§Øª Ú©Ù ØªØ±ØªÛØš Ø¯ÛÚº ØšÙØ­Ø§Øž}  
+_textalsoshowing_ [l=ur] {ÛÛ ØšÚŸÛ Ø¯Ú©ÚŸØ§ÛØ§ Ø¬Ø§ Ø±ÛØ§ ÛÛ}  
+
+_textdocsperpage_ [l=ur] {ÙÛ ØµÙØ­Û Ø¯Ø³ØªØ§ÙÛØ²Ø§Øª}  
+
+_textfilterby_ [l=ur] {Ù
+Ø³ÙØ¯Ø§Øª Ø­Ø§ØµÙ Ú©Ø±ÛÚº Ø¬Ù Ù
+ÛÚº ÙŸØ§ÛØ§ Ø¬Ø§ØªØ§ ÛÛ}  
+_textall_ [l=ur] {ØªÙ
+Ø§Ù
+}  
+_textany_ [l=ur] {Ú©ÙØŠ ØšÚŸÛ}  
+_textwords_ [l=ur] {Ø§Ù Ø§ÙÙØ§Øž Ù
+ÛÚº Ø³Û	}  
+_textleaveblank_ [l=ur] {ØªÙ
+Ø§Ù
+ Ø¯Ø³ØªØ§ÙÛØ²Ø§Øª Ú©Û Ø­ØµÙÙ Ú©Û ÙÛÛ Ø§Ø³ Ø®Ø§ÙÛ Ú©Ù Ø®Ø§ÙÛ ÚÚŸÙÚ Ø¯ÛÚº}  
+
+
+
+_nodata_ [l=ur] {<i>Ú©ÙØŠ Ù
+ÙØ§Ø¯ ÙÛÛÚº ÛÛ</i>	}  
+_docs_ [l=ur] {Ù
+Ø³ÙØ¯Ø§Øª	}  
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=ur] {Ù
+Ø¯Ø¯}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=ur] {Ù
+Ø³ÙØ¯Ø§Øª Ú©Û ÙØ±Ù Ú¯Ø±Ø¯Ø§ÙÛ ØšÙØ­Ø§Øž _1_ Ø§ÙØ± _2_ ØšÙ¹Ù}  
+
+
+
+
+_textBrowsehelp_ [l=ur] {Ù
+Ø³ÙØ¯Ø§Øª Ú©Û ÙØ±Ù Ú¯Ø±Ø¯Ø§ÙÛ}  
+
+
+
+_texthelptopicstitle_ [l=ur] {Ù
+ÙØ¶ÙØ¹Ø§Øª}  
+
+_textreadingdocs_ [l=ur] {Ù
+Ø³ÙØ¯Û Ú©Ù Ú©ÛØ³Û ÙŸÚÚŸÛÚº}  
+
+
+
+# help about the icons
+_texthelpopenbookshelf_ [l=ur] {Ø§Ø³ Ú©ØªØ§ØšÙÚº Ú©Û Ø§ÙÙ
+Ø§Ø±Û Ú©Ù Ú©ÚŸÙÙÙ}  
+_texthelpopenbook_ [l=ur] {Ø§Ø³ Ú©ØªØ§Øš Ú©Ù Ú©ÚŸÙÙÛÚº /ØšÙØ¯ Ú©Ø±ÛÚº}  
+_texthelpviewtextsection_ [l=ur] {Ù
+ØªÙ Ú©Ø§ ÛÛ Ø­ØµÛ Ù
+ÙØ§Ø­ØžÛ Ú©Ø±ÛÚº}  
+
+
+_texthelpdetachpage_ [l=ur] {Ø§Ø³ Ù
+Ø³Ù Ú©ÙØ§ÛÚ© ÙÛÙ Ø¯Ø±ÛÚÛ Ù
+ÛÚº Ú©ÚŸÙÙÙ}  
+
+_texthelpsectionarrows_ [l=ur] {Ø§Ú¯ÙÛ   /  ÙŸÚÚŸÙÛ Ø­ØµÛ ÙŸØ± Ø¬Ø§ØŠÛÚº}  
+
+
+_texthelpsearchingtitle_ [l=ur] {Ú©Ø³Û Ø®Ø§Øµ ÙÙØž Ú©Ù Ú©ÛØ³Û ØªÙØ§ØŽ Ú©ÛØ§ Ø¬Ø§ØªØ§ ÛÛ}  
+
+
+
+_texthelpquerytermstitle_ [l=ur] {ØªÙØ§ØŽ Ú©Û Ø§ØµØ·ÙØ§Ø­Ø§Øª}  
+
+
+
+
+
+
+_texthelpquerytypetitle_ [l=ur] {ØªÙØ§ØŽ Ú©Û ÙØ³Ù
+}  
+
+
+_texthelpadvancedsearchtitle_ [l=ur] {ÙŸÛÚÛØ¯Û ØªÙØ§ØŽ ØšØ°Ø±ÛØ¹Û _1_ Ø³Ø±Ú Ø§ÙØ¬Ù}  
+
+
+
+
+
+
+
+
+
+_texthelpadvancedsearchextra_ [l=ur] {ÙÙÙ¹: Ø§Ú¯Ø± Ø§ÙÙŸ Ø³Ø§Ø¯Û ØªÙØ§ØŽ Ú©Ù Ø§Ø³ØªØ¹Ù
+Ø§Ù Ú©Ø±ÛÚº ØªÙ ÛÛ ØªÙ
+Ø§Ù
+ operator ÙØžØ± Ø§ÙØ¯Ø§Ø² ÛÙ Ø¬Ø§ØŠÛÚº Ú¯Û}  
+
+_texthelpadvsearchlucene_ [l=ur] {ÛLucence Ù
+Ø¬Ù
+ÙØ¹Û Ø¬Ø§Øª Ù
+ÛÚº ÙŸÛÚÛØ¯Û ØªÙØ§ØŽ}  
+
+
+
+
+
+
+
+_textdatesearch_ [l=ur] {ØªÙØ§ØŽ ØšÙØ­Ø§Øž ØªÙØ§Ø±ÛØ®}  
+
+
+
+_texthelpdatehowtotitle_ [l=ur] {Ø§Ø³ Ø³ÛÙÙØª Ú©Ù Ú©ÛØ³Û Ø§Ø³ØªØ¹Ù
+Ø§Ù Ú©Ø±ÙØ§ ÛÛ}  
+
+
+
+
+
+_textchangeprefs_ [l=ur] {Ø§ÙŸÙÛ ØªÙØžÛÙ
+Ø§Øª Ù
+ÛÚº ØªØšØ¯ÛÙÛ}  
+
+
+
+_texthelpcollectionprefstitle_ [l=ur] {Ù
+Ø¬Ù
+ÙØ¹Û Ú©Û ØªÙØžÛÙ
+Ø§Øª}  
+_texthelpcollectionprefs_ [l=ur] {<p>Ú©ÚÚŸ Ù
+Ø¬Ù
+ÙØ¹Û Ø¬Ø§Øª Ø°ÛÙÛ Ù
+Ø¬Ù
+ÙØ¹Û ÙŸØ± Ù
+ØŽØªÙ
+Ù ÛÛÚº Ø§ÙØ± Ø§Ù Ù
+ÛÚº Ø¹ÙÛØ­Ø¯Û Ø¹ÙÛØ­Ø¯Û ÛØ§ Ù
+Ø¬Ù
+ÙØ¹Û Ø·ÙØ± ÙŸØ± ØªÙØ§ØŽ Ú©Û Ø¬Ø§ Ø³Ú©ØªÛ ÛÛÛØ§ÙØ± Ø§ÛØ³Ø§ Ú©Ø±ÙÛ Ú©Û ÙÛÛ Ø§ÙÙŸ ØµÙØ­Û ØªÙØžÛÙ
+Ø§Øª Ø³Û Ø§Ù Ø°ÛÙÛ Ù
+Ø¬Ù
+ÙØ¹Û Ø¬Ø§Øª Ú©Ù Ø§ÙŸÙÛ ØªÙØ§ØŽ Ù
+ÛÚº ØŽØ§Ù
+Ù Ú©Ø± Ø³Ú©ØªÛ ÛÛÚº}  
+
+_texthelplanguageprefstitle_ [l=ur] {ÙØ³Ø§ÙÛ ØªÙØžÛÙ
+Ø§Øª}  
+
+
+
+
+
+_texthelpsearchprefstitle_ [l=ur] {ØªÙØ§ØŽ Ú©Û ØªÙØžÛÙ
+Ø§Øª}  
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_texthelpscopetitle_ [l=ur] {ØªÙØ§ØŽ Ú©Ø§ Ø¯Ø§ØŠØ±Û Ú©Ø§Ø±}  
+_texthelpscope_ [l=ur] {<p>
+Ø²ÛØ§Ø¯Û ØªØ± Ù
+Ø¬Ù
+ÙØ¹Û Ø¬Ø§Øª Ù
+ÛÚº Ø¢ÙŸ ØªÙØ§ØŽ Ú©Û ÙÛÛ Ù
+Ø®ØªÙÙ Ø§ØŽØ§Ø±ÛÛ Ø¬Ø§Øª Ø§Ø³ØªØ¹Ù
+Ø§Ù Ú©Ø±ØªÛ ÛÛÚºÛ Ù
+Ø«Ø§Ù Ú©Û Ø·ÙØ± ÙŸØ±' Ø§ØŽØ§Ø±ÛÛ Ù
+ØµÙÙ'Ø§ØŽØ§Ø±ÛÛ Ø¹ÙÙØ§Ù ÛØ§ Ù
+Ø®ØªÙÙ Ø§ØšÙØ§Øš Ø§ÙØ± ÙÙØ±ÙÚº Ú©Û Ø§ØŽØ§Ø±ÛÛ Ø¬Ø§Øª ÛÙ Ø³Ú©ØªÛ ÛÛÚºÛ Ø¹Ù
+ÙÙ
+Ø§ Ø¢ÙŸ Ú©Ø³Û ØšÚŸÛ Ø§ØŽØ§Ø±ÛÛ Ø³Û ØªÙØ§ØŽ Ú©Ø±ÛÚº ØªÙ Ø¢ÙŸ Ú©Ù Ù
+Ú©Ù
+Ù Ø§ÙØ± Ù
+ÙØªØ§ Ø¬ÙØªØ§ Ù
+Ø³ÙØ¯Û ÛÛ Ù
+ÙØªØ§ ÛÛØ£ÙÙÙÙÙÙÙÙÙ 
+<p>
+Ø§Ú¯Ø± Ù
+Ø²Ú©ÙØ±Û Ù
+Ø³ÙØ¯Û Ú©ØªØ§ØšÛÚº ÛÛÚº ØªÙ ÙÛ Ù
+Ø®ØªØµ ØŽØ¯Û Ø¬Ú¯Û ÙŸØ± ÛÛ Ú©ÚŸÙÙÛ Ø¬Ø§ Ø³Ú©ØªÛ ÛÛÚºÛ}  
Index: /gsdl/stable/macros/urdu2.dm
===================================================================
--- /gsdl/stable/macros/urdu2.dm	(revision 20131)
+++ /gsdl/stable/macros/urdu2.dm	(revision 20131)
@@ -0,0 +1,723 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# English Language text and icon macros 
+# -- this file contains text that is of less importance
+######################################################################
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+# should have arguments of collection, collectionname and link
+
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# collectoraction
+package wizard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_textypits_ [l=ur] {Ø¢ÙŸ Ú©Û ÙŸÙØ²ÛØŽÙ Ú©Ø§ ØªØ¹ÛÙ Ø¯Ø±Ø¬ Ø°ÛÙ ØªÛØ±Ú©Û ÙØŽØ§Ù Ø³Û ÚŸÙØªØ§ÚŸÛ ÙÙÙÙÙÙÙ Ø§Ø³ ÙÙØª Ø¢ÙŸ Ú©Û Ø³Ø§Ù
+ÙÛ"Ø°Ø®ÛØ±Û Ú©ÛÙ
+ØªØ¹ÙÙ Ù
+Ø¹ÙÙÙ
+Ø§Øª ÚŸÛÙ"   }  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+_texttryagain_ [l=ur] {ØšØ±Ø§Û Ú©Ø±Ù
+<a href="_httppagecollector_" target=_top>restart the collector</a>  Ø§ÙØ± Ø¯ÙØšØ§Ø±ï·º Ú©ÙØŽØŽ Ú©Ø±ÛÙ}  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+
+
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+############
+# gli page
+############
+package gli
+
+
+
+
Index: /gsdl/stable/macros/usability.dm
===================================================================
--- /gsdl/stable/macros/usability.dm	(revision 20131)
+++ /gsdl/stable/macros/usability.dm	(revision 20131)
@@ -0,0 +1,270 @@
+# Macros for Usability (I'd like to complain!)
+
+package Usability
+
+_content_ {
+<h2>_textaboutusabilitytitle_</h2>
+<p>_textaboutusability_
+}
+_pagetitle_{_textaboutusabilitypagetitle_}
+
+package Style
+
+# override this to include _usabilityscript_
+_globalscripts_{
+<script language="javascript" type="text/javascript">
+_If_(_pagescriptextra_,_pagescriptextra_)
+_imagescript_
+_usabilityscript_
+</script>
+
+}
+
+
+package Global
+
+#override globallinks (in nav_css.dm) to include usability links if needed
+_globallinks_ {_If_("_cgiargu_" ne "1",_homelink_) _helplink_ _preflink_ _usability_}
+
+# set by receptionist to be _usablink_ if needed
+_usability_ {}
+_usablink_ {_navtaborig_(_httppageusab_,_linktextusab_,_textdescrusab_)}
+
+_httppageusab_ {javascript:usabilityfunction()}
+
+# set to _usab<type>_ by receptionist eg _usabmulti_
+# type comes from config file (format Usability <type>), options are 
+# textonly, stepwise, multi
+_usabinterface_ {}
+
+# set to usabshowscript by receptionist if needed
+_usabilityscript_ {}
+
+_httpusabbanner_ {_httpimg_/usabbnr.gif}
+
+_usabshowscript_ {
+
+//this is for where something goes wrong and an error message has to be shown.
+function failnicely(message,usabwindow)\{
+  var errhtml='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">';
+  errhtml+='<head><title>_greenstoneusabilitytext__texterror_</title><meta http-equiv="Content-Type" content="text/html; charset=_cgiargw_"></head><body bgcolor="#FFFFFF">';
+  errhtml+='_usabbanner_';	
+  errhtml+=message;
+  errhtml+='<p><form action=""><input type="button" value="_textclosewindow_" onClick="window.close();"></form>';
+  errhtml+='</body></html>';
+  usabwindow.document.write(errhtml);
+  usabwindow.document.close();
+\} 
+
+function usabilityfunction()\{
+
+  checkusab=window.open("","checkusab","scrollbars=1,toolbars=0,height=600,width=420");
+
+  //set up the window
+  var winhtml='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">';
+  winhtml += '<html><head><title>_greenstoneusabilitytext_</title>';
+  winhtml += '<script type="text/javascript">\\n<!--\\n';
+  
+  //this function is for getting the time when the complaint data is sent
+  winhtml += 'function gettime()\\{\\n';
+  winhtml += 'document.usabform.sendtime.value = (new Date()).toString();\\n'
+  winhtml+='\\}\\n';
+
+  //this function is to allow the user to track the usability report	
+  winhtml+='function viewdetails()\\{\\n';
+  winhtml+='\\t alert(\\'_textunderdev_\\');\\}';	
+
+  //this function is to show the privacy/about data in a new window
+  winhtml+='function infowindow(url)\\{  \\
+   infowin = window.open(url,\\'infowin\\',\\'toolbars=0, height=600, width=600\\');\\}';
+ 
+  winhtml += '\\n//-->\\n</';
+  winhtml += 'script>';
+  if(navigator.appName!="Netscape" || parseInt(navigator.appVersion)>=5)\{
+	winhtml += '_usabstyle_';
+  \}
+
+  //need a character type for valid html
+  winhtml+='<meta http-equiv="Content-Type" content="text/html; charset=_cgiargw_"></head><body bgcolor=\"#FFFFFF\">';
+
+  //get the location of the cgi program
+  cgiloc='_gwcgi_';
+  if(cgiloc.lastIndexOf("/")<0)\{
+     failnicely('_cannotfindcgierror_', checkusab);
+     return;
+  \}   
+  cgiloc=cgiloc.substring(0,(cgiloc.lastIndexOf("/")+1));	
+  cgiloc+='savereport.cgi';
+   
+  //adds the banner with the koru-thing and the links to about and privacy 
+  //information 
+  winhtml+='_usabbanner_';
+  winhtml+='_aboutprivacylinks_';
+	
+
+  // set up the form	
+  winhtml += '<form name="usabform" method="post" action="'+cgiloc+'" onSubmit="gettime();">';
+  winhtml += '_usabinterface_';
+
+
+  //get javascript environment variables
+
+  // to replace &s in the URL with &amp;s
+  urlgs=new String(window.location);
+  a=urlgs.split("&");
+  urlgs=a.join("&amp;"); 
+  winhtml+=('<input type="hidden" name="URL" value="'+urlgs+'">');
+  
+  winhtml+=('<input type="hidden" name="resolution" value="'+window.screen.width+'x'+window.screen.height+'">');
+  winhtml+=('<input type="hidden" name="screencolour" value="'+window.screen.color+'">');
+
+  //colordepth and pixeldepth are NS and IE versions of the same thing. 
+   if(screen.colorDepth)\{
+	winhtml+=('<input type="hidden" name="pixeldepth" value="'+window.screen.colorDepth+'">');
+   \}
+  else\{
+	winhtml+=('<input type="hidden" name="pixeldepth" value="'+window.screen.pixelDepth+'">');
+   \}
+	
+  winhtml+=('<input type="hidden" name="browser" value="'+navigator.platform+' ,'+navigator.appName+', '+navigator.appVersion+', '+navigator.appCodeName+', '+navigator.appUserAgent+'">');
+  winhtml+=('<input type="hidden" name="language" value="'+navigator.language+'">');		
+  winhtml+=('<input type="hidden" name="opentime" value="'+(new Date()).toString()+'">');	
+  winhtml+=('<input type="hidden" name="sendtime" value="None">');
+  winhtml+=('<input type="hidden" name="collection" value="_cgiargc_">');
+  if(document.getElementsByTagName)\{	
+   //get interface variables
+   if(document.getElementsByTagName("form"))\{
+     docarray=document.getElementsByTagName("input");
+     if(docarray.length>0)\{
+       for(i=0; i<docarray.length; i++)\{
+          //this leaves out uninteresting inputs, such as buttons 
+	  //and unchecked checkboxes
+         if(docarray[i].type!='reset' && docarray[i].type!='button' && 
+	    docarray[i].type!='image' && docarray[i].type!='submit'
+	    && !((docarray[i].type=='radio'|| docarray[i].type=='checkbox') && 
+	    !docarray[i].checked))\{
+	       winhtml+=('<input type="hidden" name="'+docarray[i].type+'-'+docarray[i].name+'" value="'+docarray[i].value+'">');
+	 \}     
+       \}
+     \} 
+     docarray=document.getElementsByTagName("select")
+     if(docarray.length>0)\{
+        for(i=0; i<docarray.length; i++)\{
+           winhtml+=('<input type="hidden" name="'+docarray[i].type+'-'+docarray[i].name+'" value="'+docarray[i].value+'">');
+         \} 
+      \}
+      docarray=document.getElementsByTagName("textarea")
+      if(docarray.length>0)\{
+        for(i=0; i<docarray.length; i++)\{
+           winhtml+=('<input type="hidden" name="'+docarray[i].type+'-'+docarray[i].name+'" value="'+docarray[i].value+'">');
+         \} 
+      \}
+   \}
+ \}	
+  //finish the form
+  winhtml += '</form>';
+  
+  winhtml +='</body></html>'
+
+	
+  //write to the window	
+  checkusab.document.write(winhtml);
+  checkusab.document.close();	
+  return;	
+
+\}
+}
+
+
+#####################################################################
+#
+#  These macros are for use by the usability logging (I'd like to
+#  complain)  functionality - they are to be included in a JavaScript
+#  string, hence the \s 
+#
+#####################################################################
+
+_usabinterface_{}
+_httpusabhtml_ {_httpprefix_/usability/}
+
+#the banner to "brand" any boxes as part of the usability interface
+_usabbanner_{<table width=\"100%\"><tr><td><h1>_greenstoneusabilitytext_</h1></td><td align="right" width="135"><img src=\"_httpusabbanner_\" title=\"_textusabbanner_\" alt=\"_textusabbanner_\"></td></tr></table>}
+
+#the about and privacy lins separated by a mid dot.
+_aboutprivacylinks_ {<p class="label"><a href="javascript:infowindow(\\'_httpusabhtml_about.html\\')">_textabout_</a> &#8226; <a href="javascript:infowindow(\\'_httpusabhtml_/privacy.html\\')">_textprivacy_</a>}
+
+
+###################################################################
+# Various usability interfaces: textonly, nosubmit, stepwise, multi
+###################################################################
+
+#gives a text only interface with some guff about privacy
+#########################################################
+_usabtextonly_{ \\
+_textwhy_\\
+_textprivacybasic_\\
+_textstillsend_\\
+_usabyesnosubmit_}
+
+_usabyesnosubmit_{<p><input type="submit" value="_textyes_"><input type="button" value="_textno_" onClick="window.close();">}
+
+#gives an interface with the privacy guff at the bottom, and 
+#steps to describe the problem
+############################################################
+
+_usabstepwise_{\\
+<p>_textwhatdoing_<br> \\
+<textarea name="doingwhat" rows="3" cols="40"></textarea> \\
+<p>_textwhatexpected_<br> \\
+<textarea name="whatexpected" rows="6" cols="40"></textarea> \\
+<p>_textwhathappened_<br> \\
+<textarea name="whathappened" rows="6" cols="40"></textarea> \\
+_usabtextonly_}
+
+
+#gives a multipart interface allowing the user to fill out less or more.
+########################################################################
+
+_usabmulti_{\\
+_textwhy__textextraforform_\\
+<h2>_textoptionally_:</h2>\\
+<p class="label">_textmoredetails_:<br>\\
+<textarea name="moredetails" rows="6" cols="45"></textarea>\\
+<table><tr><td>\\
+<p class="label">_textcharacterise_? </td>\\
+<td><select name="probtype">\\
+<option>\\
+<option>_textbadrender_\\
+<option>_textcontenterror_\\
+<option>_textstrangebehaviour_\\
+<option>_textunexpected_\\
+<option>_textfunctionality_\\
+<option>_textother_\\
+</select></td></tr>\\
+<tr><td><p class="label">_textseverity_? </td>\\
+<td><select name="severity">\\
+<option>\\
+<option>_textcritical_\\
+<option>_textmajor_\\
+<option>_textmedium_\\
+<option>_textminor_\\
+<option>_texttrivial_\\
+</select>\\
+</td></tr></table>\\
+_textprivacybasic__textstillsend_\\
+<table width="100%"><tr><td><a href="javascript:viewdetails()"><p class="label">_textviewdetails_</a></td><td align="right"><button type="button" onClick="window.close()"><b>_textdontsend_</b></button></td><td align="right"><button type="submit"><b>_textsend_</b></button></td></tr></table>\\
+}
+
+#style definitions to please NS 4.7
+_usabstyle_{\\
+<style type="text/css">\\
+\\
+table \{ width: 100% \} \\
+td.right \{ align:right \} \\
+\\
+h1 \{font-size:20px; font-family: sans-serif; vertical-align:middle\\} \\
+h2 \{font-size:14px; color: #009966; font-family: sans-serif; font-weight:bold \}\\
+p.label \{ font-family:sans-serif; \}\\
+</style>\\
+}
+
Index: /gsdl/stable/macros/users.dm
===================================================================
--- /gsdl/stable/macros/users.dm	(revision 20131)
+++ /gsdl/stable/macros/users.dm	(revision 20131)
@@ -0,0 +1,197 @@
+# this file must be UTF-8 encoded
+
+package userslistusers
+
+_header_ {
+<html>
+<head>
+<title>_textlocu_</title>
+</head>
+<body bgcolor="#ffffff" text="#000000" link="#006666"
+      alink="#cc9900" vlink="#666633">
+}
+
+_content_ {}
+
+_contentstart_ {
+<h2>_textlocu_</h2>
+
+
+<table border=0 cellspacing=1 cellpadding=3 width=100%>
+<tr>
+  <th bgcolor="\#d0d0d0">_textuser_</th>
+  <th bgcolor="\#d0d0d0">_textas_</th>
+  <th bgcolor="\#d0d0d0">_textgroups_</th>
+  <th bgcolor="\#d0d0d0">_textcomment_</th>
+  <th>&nbsp;</th>
+</tr>
+}
+
+_contentend_ {
+</table>
+}
+
+_footer_ {
+</body>
+</html>
+}
+
+
+
+package usersedituser
+
+_header_ {
+<html>
+<head>
+<title>_If_("_cgiarguma_" eq "edituser",_textedituser_,_textadduser_)</title>
+</head>
+<body bgcolor="#ffffff" text="#000000" link="#006666"
+      alink="#cc9900" vlink="#666633">
+}
+
+_content_ {
+<h2>_If_("_cgiarguma_" eq "edituser",_textedituser_,_textadduser_)</h2>
+
+
+_users:messagestatus_
+
+<form name="edituser" method="post" action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="a" value="um">
+<input type=hidden name="uma" value="_cgiarguma_">
+
+<table border=0>
+<tr><td>_authen:textusername_</td><td><input type="text" name="umun" value="_users:usersargun_" size=15></td>
+<td><font color=gray>_textaboutusername_</font></td>
+</tr>
+<tr><td>_authen:textpassword_</td><td><input type="text" name="umpw" value="_users:usersargpw_" size=9></td>
+<td><font color=gray>_textaboutpassword_
+_If_("_cgiarguma_" eq "edituser",_textoldpass_)
+</font></td></tr>
+<tr><td>_userslistusers:textas_</td><td>
+<select name="umus">
+<option value="enabled">_textenabled_
+<option value="disabled"_If_("_users:usersargus_" ne "enabled", selected)>_textdisabled_
+</select>
+</td></tr>
+<tr><td>_userslistusers:textgroups_</td><td colspan=2><input type="text" name="umug" value="_users:usersargug_" size=50></td></tr>
+<tr><td></td><td></td>
+<td><font color=gray>_textaboutgroups_</font><br/><font color=gray>_textavailablegroups_</font></td></tr>
+<tr><td>_userslistusers:textcomment_</td><td colspan=2><input type="text" name="umc" value="_users:usersargc_" size=50></td></tr>
+<tr><td></td><td colspan=2><input type="submit" name=beu value="submit">
+<input type="submit" name=uma value="cancel"></td></tr>
+</table>
+</form>
+}
+
+_footer_ {
+</body>
+</html>
+}
+
+
+
+
+package usersdeleteuser
+
+_header_ {
+<html>
+<head>
+<title>_textdeleteuser_</title>
+</head>
+<body bgcolor="#ffffff" text="#000000" link="#006666"
+      alink="#cc9900" vlink="#666633">
+}
+
+_content_ {
+
+<p>
+<table border=0>
+<tr><td>
+<form name="deleteuser" method="post" action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="a" value="um">
+<input type=hidden name="uma" value="_cgiarguma_">
+<input type=hidden name="umun" value="_cgiargumun_">
+<font color=red>_textremwarn_</font>
+<input type="submit" name=cm value="no">
+<input type="submit" name=cm value="yes">
+</form>
+</td></tr>
+</table>
+}
+
+_footer_ {
+</body>
+</html>
+}
+
+
+
+package userschangepasswd
+
+_header_ {
+<html>
+<head>
+<title>_textchangepw_</title>
+</head>
+<body bgcolor="#ffffff" text="#000000" link="#006666"
+      alink="#cc9900" vlink="#666633">
+}
+
+_content_ {
+<h2>_textchangepw_</h2>
+<p><font color=gray>_usersedituser:textaboutpassword_</font>
+
+<p>_users:messagestatus_
+
+<p>
+<form name="changepasswd" method="post" action="_gwcgi_">
+<input type=hidden name="e" value="_decodedcompressedoptions_">
+<input type=hidden name="a" value="um">
+<input type=hidden name="uma" value="_cgiarguma_">
+<table border=0>
+<tr><td align=right>_textoldpw_</td><td><input type="password" name="umpw" size=9></td></tr>
+<tr><td align=right>_textnewpw_</td><td><input type="password" name="umnpw1" size=9></td></tr>
+<tr><td align=right>_textretype_</td><td><input type="password" name="umnpw2" size=9></td></tr>
+<tr><td></td><td><input type="submit" name=bcp value="submit"></td></tr>
+</table>
+</table>
+</form>
+
+}
+
+
+package userschangepasswdok
+
+_header_ {
+<html>
+<head>
+<title>_userschangepasswd:textchangepw_</title>
+</head>
+<body bgcolor="#ffffff" text="#000000" link="#006666"
+      alink="#cc9900" vlink="#666633">
+}
+
+_content_ {
+<h2>_userschangepasswd:textchangepw_</h2>
+
+<p>_textsuccess_
+}
+
+
+
+package users
+
+_messageinvalidusername_ {<font color=red>_textinvalidusername_</font>}
+_messageinvalidpassword_ {<font color=red>_textinvalidpassword_</font>}
+_messageemptypassword_ {<font color=red>_textemptypassword_</font>}
+_messageuserexists_ {<font color=red>_textuserexists_</font>}
+
+_messageusernameempty_ {<font color=red>_textusernameempty_</font>}
+_messagepasswordempty_ {<font color=red>_textpasswordempty_</font>}
+_messagenewpass1empty_ {<font color=red>_textnewpass1empty_</font>}
+_messagenewpass2empty_ {_messagenewpass1empty_}
+_messagenewpassmismatch_ {<font color=red>_textnewpassmismatch_</font>}
+_messagenewinvalidpassword_ {<font color=red>_textnewinvalidpassword_</font>}
+_messagefailed_ {<font color=red>_textfailed_</font>}
Index: /gsdl/stable/macros/vietnamese.dm
===================================================================
--- /gsdl/stable/macros/vietnamese.dm	(revision 20131)
+++ /gsdl/stable/macros/vietnamese.dm	(revision 20131)
@@ -0,0 +1,732 @@
+# this file must be UTF-8 encoded
+#####################################################################
+#
+# Vietnamese Language text and icon macros 
+# Many thanks to Integrated e-Solutions Ltd., Saigon (August 2004)
+#
+######################################################################
+
+
+######################################################################
+# Global (base) package
+package Global
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textperiodicals_ [l=vi] {Xuáº¥t báº£n Äá»nh kÃ¬}
+
+# these three used by the default format statement of the demo and dls collections.
+_textsource_ [l=vi] {nguá»n: }
+_textdate_ [l=vi] {ngÃ y xuáº¥t báº£n: }
+_textnumpages_ [l=vi] {sá» trang: }
+
+_textsignin_ [l=vi] {ÄÄng nháº­p}
+
+_textdefaultcontent_ [l=vi] {KhÃŽng tÃ¬m tháº¥y trang yÃªu cáº§u. Vui lÃ²ng sá»­ dá»¥ng nÃºt 'back' trÃªn trÃ¬nh duyá»t hoáº·c nÃºt Trang chá»§ phÃ­a trÃªn
+Äá» quay láº¡i Greenstone Digital Library.}  
+
+_textdefaulttitle_ [l=vi] {Lá»i GSDL }
+
+_textbadcollection_ [l=vi] {Bá» sÆ°u táº­p nÃ y (cÃ³ tÃªn lÃ  "_cvariable_") khÃŽng ÄÆ°á»£c cÃ i Äáº·t trÃªn há» thá»ng thÆ° viá»n sá» Greenstone.}
+
+_textselectpage_ [l=vi] {-- Chá»n trang --}
+
+_collectionextra_ [l=vi] {Bá» sÆ°u táº­p nÃ y chá»©a _about:numdocs_ tÃ i liá»u. 
+NÃ³ ÄÆ°á»£c xÃ¢y dá»±ng láº§n cuá»i cÃ¡ch ÄÃ¢y _about:builddate_ ngÃ y.}
+
+# this is only used by the collector (where the above _collectionextra_
+# macro will always be set to another value)
+_collectorextra_ [l=vi] {<p>Bá» sÆ°u táº­p nÃ y chá»©a _numdocs_ _If_("_numdocs_" eq "1",tÃ i liá»u,tÃ i liá»u), tá»ng cá»ng _numbytes_.
+<p><a href="_httppagex_(bsummary)">Nháº¥n vÃ o ÄÃ¢y</a> Äá» xem tÃ³m táº¯t cÃ¡c thÃŽng tin trong quÃ¡ trÃ¬nh xÃ¢y dá»±ng bá» sÆ°u táº­p nÃ y.
+}  
+
+_textdescrcollection_ [l=vi] {}
+_textdescrabout_ [l=vi] {Giá»i thiá»u}
+_textdescrhome_ [l=vi] {Trang chá»§}
+_textdescrhelp_ [l=vi] {HÆ°á»ng dáº«n}  
+_textdescrpref_ [l=vi] {Thuá»c tÃ­nh}
+_textdescrgreenstone_ [l=vi] {Pháº§n má»m thÆ° viá»n sá» Greenstone}
+_textdescrusab_ [l=vi] {Gáº·p khÃ³ khÄn trong quÃ¡ trÃ¬nh sá»­ dá»¥ng?}  
+
+
+# Metadata names and navigation bar labels
+
+_textSearch_ [l=vi] {TÃ¬m kiáº¿m}  
+_labelSearch_ [l=vi] {TÃ¬m kiáº¿m}  
+
+# Dublin Core Metadata Element Set, Version 1.1
+_textTitle_ [l=vi] {Nhan Äá»}  
+_labelTitle_ [l=vi] {Nhan Äá»}  
+_textCreator_ [l=vi] {TÃ¡c giáº£}  
+_labelCreator_ [l=vi] {TÃ¡c giáº£}  
+_textSubject_ [l=vi] {Chá»§ Äá»}  
+_labelSubject_ [l=vi] {Äá» má»¥c}
+_textDescription_ [l=vi] {MÃŽ táº£}  
+_labelDescription_ [l=vi] {MÃŽ táº£}  
+_textPublisher_ [l=vi] {NgÆ°á»i xuáº¥t báº£n}  
+_labelPublisher_ [l=vi] {NgÆ°á»i xuáº¥t báº£n}  
+_textContributor_ [l=vi] {NgÆ°á»i cá»ng tÃ¡c}  
+_labelContributor_ [l=vi] {NgÆ°á»i cá»ng tÃ¡c}  
+_textDate_ [l=vi] {NgÃ y}  
+_labelDate_ [l=vi] {NgÃ y}
+_textType_ [l=vi] {Kiá»u}  
+_labelType_ [l=vi] {Kiá»u}  
+_textFormat_ [l=vi] {Äá»nh dáº¡ng}  
+_labelFormat_ [l=vi] {Äá»nh dáº¡ng}  
+_textIdentifier_ [l=vi] {Nháº­n dáº¡ng}  
+_labelIdentifier_ [l=vi] {Nháº­n dáº¡ng}  
+_textSource_ [l=vi] {TÃªn táº­p tin}  
+_labelSource_ [l=vi] {TÃªn táº­p tin}
+_textLanguage_ [l=vi] {NgÃŽn ngá»¯}  
+_labelLanguage_ [l=vi] {NgÃŽn ngá»¯}
+_textRelation_ [l=vi] {Quan há»}  
+_labelRelation_ [l=vi] {Quan há»}  
+_textCoverage_ [l=vi] {Má»©c Äá» bao phá»§}  
+_labelCoverage_ [l=vi] {Má»©c Äá» bao phá»§}  
+_textRights_ [l=vi] {Quyá»n}  
+_labelRights_ [l=vi] {Quyá»n}  
+
+# DLS metadata set
+_textOrganization_ [l=vi] {Tá» chá»©c}  
+_labelOrganization_ [l=vi] {Tá» chá»©c}  
+_textKeyword_ [l=vi] {Tá»« khÃ³a}  
+_labelKeyword_ [l=vi] {Tá»« khÃ³a}
+_textHowto_ [l=vi] {CÃ¡ch thá»±c hiá»n}  
+_labelHowto_ [l=vi] {CÃ¡ch thá»±c hiá»n}  
+
+# Miscellaneous Greenstone metadata
+_textPhrase_ [l=vi] {Cá»¥m tá»«}  
+_labelPhrase_ [l=vi] {Cá»¥m tá»«}
+_textCollage_ [l=vi] {Nghá» thuáº­t cáº¯t dÃ¡n áº£nh}  
+_labelCollage_ [l=vi] {áº¢nh ghÃ©p}
+_textBrowse_ [l=vi] {TÃ¬m}  
+_labelBrowse_ [l=vi] {TÃ¬m}  
+_textTo_ [l=vi] {Äáº¿n}  
+_labelTo_ [l=vi] {NÆ¡i chá»©a}
+_textFrom_ [l=vi] {Tá»«}  
+_labelFrom_ [l=vi] {Nguá»n gá»c}
+_textAcronym_ [l=vi] {Thuáº­t ngá»¯ viáº¿t táº¯t}  
+_labelAcronym_ [l=vi] {Viáº¿t táº¯t}
+
+# Navigation bar tooltip - to customize this for a specific metadata, add a macro named _textdescrXXX_ where XXX is the metadata name
+_textdescrdefault_ [l=vi] {TÃ¬m theo _1_}  
+
+_textdescrSearch_ [l=vi] {TÃ¬m kiáº¿m vá»i cÃ¡c Äiá»u kiá»n cá»¥ thá»}
+_textdescrType_ [l=vi] {TÃ¬m theo kiá»u tÃ i nguyÃªn}  
+_textdescrIdentifier_ [l=vi] {TÃ¬m theo sá»± nháº­n dáº¡ng tÃ i nguyÃªn}  
+_textdescrSource_ [l=vi] {TrÃ¬nh duyá»t theo tÃªn gá»c cá»§a táº­p tin}
+_textdescrTo_ [l=vi] {TrÃ¬nh duyá»t theo trÆ°á»ng NÆ¡i chá»©a}  
+_textdescrFrom_ [l=vi] {TrÃ¬nh duyá»t theo trÆ°á»ng Nguá»n gá»c}
+_textdescrCollage_ [l=vi] {TrÃ¬nh duyá»t theo nghá» thuáº­t táº¡o áº£nh}
+_textdescrAcronym_ [l=vi] {TrÃ¬nh duyá»t theo tá»« viáº¿t táº¯t}
+_textdescrPhrase_ [l=vi] {TrÃ¬nh duyá»t theo cá»¥m tá»«}
+_textdescrHowto_ [l=vi] {TrÃ¬nh duyá»t dá»±a vÃ o phÃ¢n loáº¡i}
+_textdescrBrowse_ [l=vi] {TrÃ¬nh duyá»t }
+_texticontext_ [l=vi] {Xem tÃ i liá»u}
+_texticonclosedbook_ [l=vi] {Má» tÃ i liá»u vÃ  xem ná»i dung}
+_texticonnext_ [l=vi] {Äáº¿n pháº§n káº¿ tiáº¿p}
+_texticonprev_ [l=vi] {quay láº¡i pháº§n trÆ°á»c}
+
+_texticonworld_ [l=vi] {Xem tÃ i liá»u web}  
+
+_texticonmidi_ [l=vi] {Xem tÃ i liá»u MIDI}
+_texticonmsword_ [l=vi] {Xem tÃ i liá»u Microsoft Word}
+_texticonmp3_ [l=vi] {Xem tÃ i liá»u MP3}  
+_texticonpdf_ [l=vi] {Xem tÃ i liá»u PDF}  
+_texticonps_ [l=vi] {Xem tÃ i liá»u PostScript}  
+_texticonppt_ [l=vi] {Xem tÃ i liá»u PowerPoint}  
+_texticonrtf_ [l=vi] {Xem tÃ i liá»u RTF}  
+_texticonxls_ [l=vi] {Xem tÃ i liá»u Microsoft Excel}  
+
+_page_ [l=vi] {trang}
+_pages_ [l=vi] {trang}
+_of_ [l=vi] {cá»§a }
+_vol_ [l=vi] {Quyá»n.}
+_num_ [l=vi] {Sá».}
+
+_textmonth00_ [l=vi] {}
+_textmonth01_ [l=vi] {ThÃ¡ng Má»t}  
+_textmonth02_ [l=vi] {ThÃ¡ng Hai}  
+_textmonth03_ [l=vi] {ThÃ¡ng Ba}  
+_textmonth04_ [l=vi] {ThÃ¡ng TÆ°}  
+_textmonth05_ [l=vi] {ThÃ¡ng NÄm}  
+_textmonth06_ [l=vi] {ThÃ¡ng SÃ¡u}  
+_textmonth07_ [l=vi] {ThÃ¡ng Báº£y}  
+_textmonth08_ [l=vi] {ThÃ¡ng TÃ¡m}  
+_textmonth09_ [l=vi] {ThÃ¡ng ChÃ­n}  
+_textmonth10_ [l=vi] {ThÃ¡ng MÆ°á»i}  
+_textmonth11_ [l=vi] {ThÃ¡ng MÆ°á»i má»t}  
+_textmonth12_ [l=vi] {ThÃ¡ng MÆ°á»i hai}  
+
+_textdocument_ [l=vi] {TÃ i liá»u}
+_textsection_ [l=vi] {Pháº§n}
+_textparagraph_ [l=vi] {Äoáº¡n vÄn báº£n}
+
+_magazines_ [l=vi] {Táº¡p chÃ­}  
+
+_nzdlpagefooter_ [l=vi] {<div class="divbar">Â </div>
+<p><a href="http://www.nzdl.org">New Zealand Digital Library Project</a>
+<br><a href="http://www.cs.waikato.ac.nz/cs">Department of Computer Science</a>, 
+<a href="http://www.waikato.ac.nz">University of Waikato</a>, 
+New Zealand}  
+
+_linktextHOME_ [l=vi] {Trang chá»§}
+_linktextHELP_ [l=vi] {HÆ°á»ng dáº«n}  
+_linktextPREFERENCES_ [l=vi] {Thuá»c tÃ­nh}
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+_textpagetitle_ [l=vi] {Pháº§n má»m thÆ° viá»n sá» Greenstone}
+
+_textnocollections_ [l=vi] {KhÃŽng cÃ³ sáºµn bá» sÆ°u táº­p há»£p lá» (nghÄ©a lÃ  khÃŽng tÃ¬m ÄÆ°á»£c bá» sÆ°u táº­p ÄÆ°á»£c xÃ¢y dá»±ng vÃ  ÄÃ£ ÄÆ°á»£c phá» biáº¿n)}  
+
+_textadmin_ [l=vi] {Trang quáº£n trá»}
+_textabgs_ [l=vi] {Giá»i thiá»u Greenstone}
+_textgsdocs_ [l=vi] {TÃ i liá»u Greenstone}
+
+_textdescradmin_ [l=vi] {Chá»©c nÄng táº¡o má»t tÃ i khoáº£n ngÆ°á»i dÃ¹ng má»i, tÃ³m táº¯t ná»i dung cÃ¡c bá» sÆ°u táº­p ÄÃ£ cÃ³ trong há» thá»ng, cung cáº¥p cÃ¡c thÃŽng tin ká»¹ thuáº­t vá» cÃ i Äáº·t pháº§n má»m Greenstone.
+}
+
+_textdescrgogreenstone_ [l=vi] {Chá»©c nÄng cung cáº¥p cÃ¡c thÃŽng tin vá» pháº§n má»m Greenstone vÃ  dá»± Ã¡n New Zealand Digital Library nÆ¡i mÃ  pháº§n má»m ÄÆ°á»£c báº¯t nguá»n.
+}
+
+_textdescrgodocs_ [l=vi] {TÃ i liá»u hÆ°á»ng dáº«n sá»­ dá»¥ng pháº§n má»m Greenstone}
+
+#####################################################################
+# some macros used on the home page from other packages
+#####################################################################
+package gli
+
+_textgli_ [l=vi] {Giao diá»n thá»§ thÆ°}
+_textdescrgli_ [l=vi] {GiÃºp táº¡o bá» sÆ°u táº­p má»i, chá»nh sá»­a hoáº·c thÃªm má»i, hoáº·c xoÃ¡ bá» sÆ°u táº­p ÄÃ£ cÃ³}
+
+package collector
+
+_textcollector_ [l=vi] {Táº¡o bá» sÆ°u táº­p}
+_textdescrcollector_ [l=vi] {Chá»©c nÄng táº¡o má»i cÃ¡c bá» sÆ°u táº­p, thay Äá»i, thÃªm vÃ o hoáº·c xoÃ¡ cÃ¡c bá» sÆ°u táº­p ÄÃ£ tá»n táº¡i.
+}
+
+package depositor
+
+_textdepositor_ [l=vi] {NgÆ°á»i gá»i Äá» váº­t}  
+_textdescrdepositor_ [l=vi] {GiÃºp thÃªm tÃ i liá»u vÃ o bá» sÆ°u táº­p ÄÃ£ cÃ³}  
+
+package gti
+
+_textgti_ [l=vi] {Giao diá»n dá»ch thuáº­t Greenstone}  
+_textdescrtranslator_ [l=vi] {Chá»©c nÄng lÆ°u giá»¯ cÃ¡c phiÃªn báº£n cá»§a Greenstone dÆ°á»i cÃ¡c dáº¡ng ngÃŽn ngá»¯ khÃ¡c nhau
+}
+
+
+######################################################################
+# 'about' page
+package about
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textabcol_ [l=vi] {Giá»i thiá»u vá» bá» sÆ°u táº­p}
+
+_textsubcols1_ [l=vi] {<p>Bá» sÆ°u táº­p hoÃ n chá»nh bao gá»m _1_ bá» sÆ°u táº­p con. 
+Nhá»¯ng bá» sÆ°u táº­p ÄÃ£ hoÃ n chá»nh lÃ : <blockquote>}  
+
+_textsubcols2_ [l=vi] {</blockquote>
+NgÆ°á»i dÃ¹ng cÃ³ thá» kiá»m tra (vÃ  thay tháº¿) nhá»¯ng bá» sÆ°u táº­p con ÄÆ°á»£c sá»­ dá»¥ng trÃªn trang Thuá»c tÃ­nh.}  
+
+_titleabout_ [l=vi] {giá»i thiá»u}
+
+
+######################################################################
+# document package
+package document
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_texticonopenbookshelf_ [l=vi] {ÄÃ³ng pháº§n nÃ y cá»§a thÆ° viá»n}
+_texticonclosedbookshelf_ [l=vi] {má» pháº§n nÃ y cá»§a thÆ° viá»n vÃ  xem ná»i dung}
+_texticonopenbook_ [l=vi] {ÄÃ³ng cuá»n sÃ¡ch nÃ y}
+_texticonclosedfolder_ [l=vi] {Má» thÆ° má»¥c nÃ y vÃ  xem ná»i dung}
+_texticonclosedfolder2_ [l=vi] {má» thÆ° má»¥c con: }
+_texticonopenfolder_ [l=vi] {ÄÃ³ng thÆ° má»¥c nÃ y}
+_texticonopenfolder2_ [l=vi] {ÄÃ³ng thÆ° má»¥c con: }
+_texticonsmalltext_ [l=vi] {Xem pháº§n nÃ y cá»§a vÄn báº£n}
+_texticonsmalltext2_ [l=vi] {xem ná»i dung: }
+_texticonpointer_ [l=vi] {pháº§n hiá»n táº¡i}
+_texticondetach_ [l=vi] {Má» trang nÃ y trong má»t cá»­a sá» má»i}
+_texticonhighlight_ [l=vi] {TÃŽ mÃ u tá»« khÃ³a}
+_texticonnohighlight_ [l=vi] {KhÃŽng tÃŽ mÃ u tá»« khÃ³a }
+_texticoncontracttoc_ [l=vi] {Thu nhá» báº£ng má»¥c lá»¥c}
+_texticonexpandtoc_ [l=vi] {Má» rá»ng báº£ng má»¥c lá»¥c}
+_texticonexpandtext_ [l=vi] {Hiá»n thá» toÃ n bá» ná»i dung}
+_texticoncontracttext_ [l=vi] {Chá» hiá»n thá» ná»i dung cho pháº§n ÄÆ°á»£c chá»n}
+_texticonwarning_ [l=vi] {<b>Cáº£nh bÃ¡o: </b>}
+_texticoncont_ [l=vi] {tiáº¿p tá»¥c?}
+
+_textltwarning_ [l=vi] {<div class="buttons">_imagecont_</div>
+_iconwarning_Expanding vÄn báº£n á» ÄÃ¢y sáºœ phÃ¡t sinh má»t lÆ°á»£ng dá»¯ liá»u so vá»i kháº£ nÄng hiá»n thá» cá»§a trÃ¬nh duyá»t
+}
+
+_textgoto_ [l=vi] {Äi Äáº¿n trang}
+_textintro_ [l=vi] {<i>(vÄn báº£n giá»i thiá»u)</i>}
+
+_textCONTINUE_ [l=vi] {Tiáº¿p tá»¥c??}
+
+_textEXPANDTEXT_ [l=vi] {Má» rá»ng vÄn báº£n}  
+
+_textCONTRACTCONTENTS_ [l=vi] {LiÃªn há» ná»i dung}  
+
+_textDETACH_ [l=vi] {Má» cá»­a\nsá» má»i}
+
+_textEXPANDCONTENTS_ [l=vi] {Má» rá»ng ná»i dung}  
+
+_textCONTRACT_ [l=vi] {LiÃªn há» tÃ i liá»u}  
+
+_textHIGHLIGHT_ [l=vi] {TÃŽ mÃ u}  
+
+_textNOHIGHLIGHT_ [l=vi] {KhÃŽng tÃŽ mÃ u}  
+
+_textPRINT_ [l=vi] {In}  
+
+_textnextsearchresult_ [l=vi] {káº¿t quáº£ tÃ¬m kiáº¿m káº¿ tiáº¿p}  
+_textprevsearchresult_ [l=vi] {Káº¿t quáº£ tÃ¬m kiáº¿m trÆ°á»c}  
+
+# macros for printing page
+_textreturnoriginal_ [l=vi] {Quay láº¡i trang chá»§}  
+_textprintpage_ [l=vi] {In trang nÃ y.}  
+_textshowcontents_ [l=vi] {Hiá»n thá» ra báº£ng ná»i dung}  
+_texthidecontents_ [l=vi] {áºšn báº£ng ná»i dung}  
+
+######################################################################
+# 'search' page
+package query
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+# this if statement produces the text 'results n1 - nn for query: querystring' or 
+# 'No matches for query: querystring', depending on whether or not there were
+# any matches
+_textquerytitle_ [l=vi] {_If_(_thislast_,káº¿t quáº£ _thisfirst_ - _thislast_ cho cÃ¢u truy váº¥n: _cgiargq_,KhÃŽng cÃ³ káº¿t quáº£ khá»p vá»i cÃ¢u truy váº¥n: _cgiargq_)}
+_textnoquerytitle_ [l=vi] {Trang tÃ¬m kiáº¿m}
+
+_textsome_ [l=vi] {má»t sá»}
+_textall_ [l=vi] {táº¥t cáº£ cÃ¡c}
+_textboolean_ [l=vi] {Káº¿t há»£p Boole}  
+_textranked_ [l=vi] {ÄÆ°á»£c xáº¿p háº¡ng thá»©}
+_textnatural_ [l=vi] {tá»± nhiÃªn}
+_textsortbyrank_ [l=vi] {hÃ ng liÃªn quan}  
+_texticonsearchhistorybar_ [l=vi] {tÃ¬m kiáº¿m trÆ°á»c ÄÃ³}
+
+_textifeellucky_ [l=vi] {TÃŽi tháº­t may máº¯n}
+
+#alt text for query buttons
+_textusequery_ [l=vi] {sá»­ dá»¥ng cÃ¢u truy váº¥n nÃ y}
+_textfreqmsg1_ [l=vi] {Sá» tá»« xuáº¥t hiá»n: }
+_textpostprocess_ [l=vi] {_If_(_quotedquery_,<br><i>ÄÆ°á»£c xá»­ lÃ­ sau Äá» tÃ¬m _quotedquery_</i>
+)}
+_textinvalidquery_ [l=vi] {CÃ¢u truy váº¥n khÃŽng ÄÃºng cÃº phÃ¡p}
+_textstopwordsmsg_ [l=vi] {Nhá»¯ng tá»« bÃªn dÆ°á»i thÃ¬ phá» biáº¿n vÃ  bá» tá»« chá»i:}  
+_textlucenetoomanyclauses_ [l=vi] {CÃ¢u truy váº¥n chá»©a Äá»±ng quÃ¡ nhiá»u thuáº­t ngá»¯ tÃ¬m kiáº¿m, vui lÃ²ng thá»­ láº¡i vá»i cÃ¢u cá»¥ thá» hÆ¡n.}  
+
+_textmorethan_ [l=vi] {Nhiá»u hÆ¡n }
+_textapprox_ [l=vi] {Giá»i thiá»u }
+_textnodocs_ [l=vi] {KhÃŽng cÃ³ tÃ i liá»u nÃ o khá»p vá»i cÃ¢u truy váº¥n.}
+_text1doc_ [l=vi] {1 tÃ i liá»u khá»p vá»i cÃ¢u truy váº¥n.}
+_textlotsdocs_ [l=vi] {tÃ i liá»u khá»p vá»i cÃ¢u truy váº¥n.}
+_textmatches_ [l=vi] {Khá»p }
+_textbeginsearch_ [l=vi] {Báº¯t Äáº§u tÃ¬m kiáº¿m}
+_textrunquery_ [l=vi] {Cháº¡y cÃ¢u truy váº¥n}  
+_textclearform_ [l=vi] {XoÃ¡ ÃŽ nháº­p liá»u}  
+
+#these go together in form search:
+#"Words  (fold, stem)  ... in field"
+_textwordphrase_ [l=vi] {Tá»« hoáº·c cá»¥m tá»«}  
+_textinfield_ [l=vi] {... trong trÆ°á»ng}  
+_textfoldstem_ [l=vi] {(Chuyá»n chá»¯, Gá»c tá»«)}  
+
+_textadvquery_ [l=vi] {Hoáº·c nháº­p trá»±c tiáº¿p cÃ¢u truy váº¥n:}  
+_textallfields_ [l=vi] {táº¥t cáº£ cÃ¡c trÆ°á»ng}  
+_texttextonly_ [l=vi] {chá» gá»m ná»i dung vÄn báº£n}
+_textand_ [l=vi] {vÃ }  
+_textor_ [l=vi] {hoáº·c}  
+_textandnot_ [l=vi] {vÃ  khÃŽng}  
+
+# _indexselection_, _jselection_, _nselection_ and _gselection_ are set from 
+# within the server - _indexselection_ is always set, but the others may be 
+# unset
+
+_textsimplesearch_ [l=vi] {TÃ¬m kiáº¿m trong _indexselection_ _If_(_jselection_, of _jselection_) _If_(_gselection_, táº¡i _gselection_ level) _If_(_nselection_, trong _nselection_ language)cÃ³ chá»©a _querytypeselection_ tá»« _If_(_sfselection_,\,_allowformbreak_ sáº¯p xáº¿p káº¿t quáº£ theo _sfselection_)} 
+
+_textadvancedsearch_ [l=vi] {TÃ¬m kiáº¿m _If_(_hselection_, _hselection_, _defaultindextext_) _If_(_jselection_,_textjselect_) _If_(_gselection_, at _gselection_ level)_If_(_nselection_, in _nselection_ language) 
+sá»­ dá»¥ng loáº¡i truy váº¥n _querytypeselection_}
+
+_textadvancedmgppsearch_ [l=vi] {TÃ¬m kiáº¿m _indexselection_ _If_(_jselection_, cá»§a _jselection_ )_If_(_gselection_, táº¡i _gselection_ level )_If_(_nselection_, trong _nselection_ language ) vÃ  hiá»n thá» káº¿t quáº£ theo thá»© tá»± _formquerytypeadvancedselection_ }  
+
+_textadvancedlucenesearch_ [l=vi] {TÃ¬m kiáº¿m _indexselection__If_(_jselection_, cá»§a _jselection_)_If_(_gselection_, táº¡i _gselection_ level)_If_(_nselection_, trong _nselection_ language)_If_(_sfselection_,\,_allowformbreak_ sáº¯p xáº¿p káº¿t quáº£ tÃ¬m ÄÆ°á»£c theo _sfselection_\,) Äá» }  
+
+_textformsimplesearch_ [l=vi] {TÃ¬m kiáº¿m _If_(_jselection_,_jselection_ )_If_(_gformselection_,táº¡i _gformselection_ level )_If_(_nselection_, trong _nselection_ language)_If_(_sfselection_,\, sáº¯p xáº¿p káº¿t quáº£ tÃ¬m ÄÆ°á»£c theo _sfselection_\,) cho _formquerytypesimpleselection_ cá»§a}  
+
+_textformadvancedsearchmgpp_ [l=vi] {TÃ¬m kiáº¿m _If_(_jselection_,_jselection_ )_If_(_gformselection_,táº¡i _gformselection_ level )_If_(_nselection_, trong _nselection_ language )vÃ  hiá»n thá» káº¿t quáº£ theo thá»© tá»± _formquerytypeadvancedselection_}  
+
+_textformadvancedsearchlucene_ [l=vi] {TÃ¬m kiáº¿m _If_(_jselection_, _jselection_)_If_(_gformselection_,  táº¡i _gformselection_ level)_If_(_nselection_, trong _nselection_ language)_If_(_sfselection_,\, sáº¯p xáº¿p káº¿t quáº£ tÃ¬m ÄÆ°á»£c theo _sfselection_\,) Äá»}  
+
+_textnojsformwarning_ [l=vi] {Cáº£nh bÃ¡o: Javascript bá» táº¯t hoáº¡t Äá»ng trÃªn trÃ¬nh duyá»t. <br>Äá» sá»­ dá»¥ng máº«u tÃ¬m kiáº¿m, vui lÃ²ng báº­t láº¡i nÃ³.}  
+_textdatesearch_ [l=vi] {Bá» sÆ°u táº­p nÃ y cÃ³ thá» tÃ¬m kiáº¿m cÃ¡c tÃ i liá»u theo má»t pháº¡m vi ngÃ y hoáº·c cÃ¡c tÃ i liá»u mÃ  chá»©a má»t ngÃ y cá»¥ thá». ÄÃ¢y lÃ  má»t tÃ¹y chá»n cá»§a tÃ¬m kiáº¿m.}
+_textstartdate_ [l=vi] {NgÃ y báº¯t Äáº§u:}
+_textenddate_ [l=vi] {NgÃ y káº¿t thÃºc:}
+_textbc_ [l=vi] {B.C.E.}
+_textad_ [l=vi] {C.E.}
+_textexplaineras_ [l=vi] {C.E. vÃ  B.C.E tÆ°Æ¡ng ÄÆ°Æ¡ng vá»i A.D. vÃ  B.C.  Nhá»¯ng tá»« nÃ y thay tháº¿ cho "CÃŽng nguyÃªn" vÃ  "TrÆ°á»c cÃŽng nguyÃªn"}  
+
+_textstemon_ [l=vi] {(bá» qua pháº§n háº­u tá» cá»§a tá»«)}
+
+_textsearchhistory_ [l=vi] {TÃ¬m kiáº¿m trÆ°á»c ÄÃ³}
+
+#text macros for search history
+_textnohistory_ [l=vi] {TÃ¬m kiáº¿m trÆ°á»c ÄÃ³ khÃŽng tá»n táº¡i}  
+_texthresult_ [l=vi] {káº¿t quáº£}
+_texthresults_ [l=vi] {cÃ¡c káº¿t quáº£}
+_texthallwords_ [l=vi] {táº¥t cáº£ cÃ¡c tá»«}
+_texthsomewords_ [l=vi] {má»t sá» tá»«}
+_texthboolean_ [l=vi] {Káº¿t há»£p boole}  
+_texthranked_ [l=vi] {ÄÆ°á»£c xáº¿p háº¡ng}  
+_texthcaseon_ [l=vi] {phÃ¢n biá»t chá»¯ hoa, chá»¯ thÆ°á»ng}
+_texthcaseoff_ [l=vi] {chuyá»n chá»¯ hoa-thÆ°á»ng}  
+_texthstemon_ [l=vi] {stemmed}
+_texthstemoff_ [l=vi] {unstemmed}
+
+
+######################################################################
+# 'preferences' page
+package preferences
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textprefschanged_ [l=vi] {CÃ¡c thuá»c tÃ­nh ÄÃ£ ÄÆ°á»£c thiáº¿t láº­p nhÆ° bÃªn dÆ°á»i. NgÆ°á»i dÃ¹ng khÃŽng nÃªn sá»­ dá»¥ng nÃºt "Back" trÃªn trÃ¬nh duyá»t vÃ¬ nhÆ° váº­y thÃ¬ cÃ¡c thiáº¿t láº­p thuá»c tÃ­nh trÆ°á»c ÄÃ³ sáºœ máº¥t tÃ¡c dá»¥ng.  CÃ³ thá» nháº¥n má»t trong cÃ¡c nÃºt trÃªn thanh chá»©c nÄng bÃªn trÃªn.}  
+_textsetprefs_ [l=vi] {Thiáº¿t láº­p thuá»c tÃ­nh}
+_textsearchprefs_ [l=vi] {Thuá»c tÃ­nh tÃ¬m kiáº¿m}
+_textcollectionprefs_ [l=vi] {Thuá»c tÃ­nh bá» sÆ°u táº­p}
+_textpresentationprefs_ [l=vi] {Thuá»c tÃ­nh trÃ¬nh bÃ y}
+_textpreferences_ [l=vi] {Thuá»c tÃ­nh}
+_textcasediffs_ [l=vi] {PhÃ¢n biá»t chá»¯ hoa chá»¯ thÆ°á»ng:}
+_textignorecase_ [l=vi] {KhÃŽng phÃ¢n biá»t}  
+_textmatchcase_ [l=vi] {Chá»¯ hoa/chá»¯ thÆ°á»ng pháº£i trÃ¹ng khá»p vá»i nhau}  
+_textwordends_ [l=vi] {Háº­u tá» cá»§a tá»«:}  
+_textstem_ [l=vi] {Bá» qua cÃ¡c háº­u tá» cá»§a tá»«}  
+_textnostem_ [l=vi] {ToÃ n bá» tá»« pháº£i khá»p}  
+_textaccentdiffs_ [l=vi] {KhÃ¡c nhau vá» trá»ng Ã¢m:}  
+_textignoreaccents_ [l=vi] {bá» qua chá»©c nÄng ÄÃ¡nh dáº¥u trá»ng Ã¢m}  
+_textmatchaccents_ [l=vi] {káº¿t há»£p vá»i dáº¥u nháº¥n Ã¢m}  
+
+_textprefop_ [l=vi] {Káº¿t quáº£ tráº£ vá» tá»i Äa _maxdocoption_ dÃ²ng vá»i _hitsperpageoption_ dÃ²ng trÃªn má»t trang.}
+_textextlink_ [l=vi] {Truy xuáº¥t cÃ¡c trang Web bÃªn ngoÃ i:}
+_textintlink_ [l=vi] {TÃ i liá»u nguá»n ÄÃ£ nháº­n vá» tá»«:}
+_textlanguage_ [l=vi] {NgÃŽn ngá»¯ hiá»n thá»:}
+_textencoding_ [l=vi] {MÃ£ hÃ³a dáº¡ng:}
+_textformat_ [l=vi] {Äá»nh dáº¡ng giao diá»n:}
+_textall_ [l=vi] {táº¥t cáº£}
+_textquerymode_ [l=vi] {CÃ¡ch truy váº¥n:}  
+_textsimplemode_ [l=vi] {Truy váº¥n ÄÆ¡n giáº£n}  
+_textadvancedmode_ [l=vi] {Truy váº¥n nÃ¢ng cao (cho phÃ©p thá»±c hiá»n cÃ¢u truy váº¥n báº±ng cÃ¡c toÃ¡n tá»­ liÃªn káº¿t kiá»u logic &, |, !)}  
+_textlinkinterm_ [l=vi] {thÃŽng qua trang trung gian}
+_textlinkdirect_ [l=vi] {Äi theo hÆ°á»ng ÄÃ³}
+_textdigitlib_ [l=vi] {thÆ° viá»n sá»}
+_textweb_ [l=vi] {trang web}
+_textgraphical_ [l=vi] {HÃ¬nh áº£nh}
+_texttextual_ [l=vi] {VÄn báº£n}
+_textcollectionoption_ [l=vi] {<p>
+Bá» sÆ°u táº­p con bao gá»m:
+<br>}
+
+_textsearchtype_ [l=vi] {Kiá»u truy váº¥n:}  
+_textformsearchtype_ [l=vi] {with _formnumfieldoption_ fields}  
+_textplainsearchtype_ [l=vi] {Há»p truy váº¥n _boxsizeoption_}  
+_textregularbox_ [l=vi] {Má»t dÃ²ng}  
+_textlargebox_ [l=vi] {Nhiá»u dÃ²ng}  
+
+_textrelateddocdisplay_ [l=vi] {hiá»n thá» cÃ¡c tÃ i liá»u liÃªn quan}
+_textsearchhistory_ [l=vi] {TÃ¬m kiáº¿m trÆ°á»c ÄÃ³:}  
+_textnohistory_ [l=vi] {KhÃŽng cÃ³ káº¿t quáº£ tÃ¬m kiáº¿m trÆ°á»c ÄÃ³}  
+_texthistorydisplay_ [l=vi] {Hiá»n thá» _historynumrecords_ máº«u tin tÃ¬m kiáº¿m trÆ°á»c ÄÃ³}  
+_textnohistorydisplay_ [l=vi] {KhÃŽng hiá»n thá» chá»©c nÄng tÃ¬m kiáº¿m trÆ°á»c ÄÃ³}  
+
+
+#####################################################################
+# 'browse' package for the dynamic browsing interface
+package browse
+#####################################################################
+
+_textsortby_ [l=vi] {Sáº¯p xáº¿p cÃ¡c tÃ i liá»u theo}
+_textalsoshowing_ [l=vi] {cÅ©ng trÃ¬nh bÃ y}
+_textwith_ [l=vi] {vá»i tá»i Äa lÃ }
+_textdocsperpage_ [l=vi] {tÃ i liá»u trÃªn má»t trang}
+
+_textfilterby_ [l=vi] {Láº¥y cÃ¡c tÃ i liá»u cÃ³ chá»©a}
+_textall_ [l=vi] {táº¥t cáº£}
+_textany_ [l=vi] {má»t sá»}
+_textwords_ [l=vi] {trong cÃ¡c tá»«}
+_textleaveblank_ [l=vi] {bá» há»p thoáº¡i nháº­p liá»u tráº¯ng Äá» nháº­n vá» cÃ¡c tÃ i liá»u}  
+
+_browsebuttontext_ [l=vi] {"Sáº¯p xáº¿p tÃ i liá»u"}
+
+_nodata_ [l=vi] {<i>khÃŽng cÃ³ dá»¯ liá»u</i>}
+_docs_ [l=vi] {cÃ¡c tÃ i liá»u}
+######################################################################
+# 'help' page -- this is lower priority for translating than the
+# rest of this file
+package help
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textHelp_ [l=vi] {HÆ°á»ng dáº«n}  
+
+# Macros giving a brief help message for navigation bar access buttons
+# The arguments to this will be _textXXX_ and _labelXXX_, where XXX is the metadata name. For example, to print out the help message for a titles classifier, the library will use _textdefaulthelp_(_textTitle_,_labelTitle_)
+# To customize this for a specific metadata, add a macro named _textXXXhelp_ where XXX is the metadata name
+_textdefaulthelp_ [l=vi] {TÃ¬m tÃ i liá»u theo _1_ báº±ng cÃ¡ch nháº¥n vÃ o nÃºt _2_}  
+
+_textSearchhelp_ [l=vi] {TÃ¬m kiáº¿m cÃ¡c tá»« liÃªn quan xuáº¥t hiá»n trong Äoáº¡n vÄn báº±ng cÃ¡ch nháº¥n vÃ o nÃºt _labelSearch_}  
+_textTohelp_ [l=vi] {TÃ¬m tÃ i liá»u theo trÆ°á»ng Äáº¿n báº±ng cÃ¡ch nháº¥n vÃ o the nÃºt _labelTo_}  
+_textFromhelp_ [l=vi] {tÃ¬m nhÃ  xuáº¥t báº£n báº±ng cÃ¡c trÆ°á»ng trÃªn giao diá»n báº±ng cÃ¡ch nháº¥n vÃ o nÃºt _labelFrom_}  
+_textBrowsehelp_ [l=vi] {TÃ¬m tÃ i liá»u}  
+_textAcronymhelp_ [l=vi] {TÃ¬m tÃ i liá»u dá»±a theo cÃ¡c Thuáº­t ngá»¯ viáº¿t táº¯t báº±ng cÃ¡ch nháº¥n vÃ o nÃºt _labelAcronym_}  
+_textPhrasehelp_ [l=vi] {tÃ¬m thÃ nh ngá»¯ xuáº¥t hiá»n trong tÃ i liá»u báº±ng cÃ¡ch nháº¥n vÃ o nÃºt _labelPhrase_ . CÃ¡ch nÃ y dÃ¹ng Äá» tÃ¬m cÃ¡c thuáº­t ngá»¯ phind}  
+
+_texthelptopicstitle_ [l=vi] {Chá»§ Äá»}
+
+_textreadingdocs_ [l=vi] {CÃ¡ch Äá»c cÃ¡c tÃ i liá»u}
+
+_texthelpreadingdocs_ [l=vi] {<p>- XÃ¡c Äá»nh quyá»n sÃ¡ch mÃ  ngÆ°á»i dÃ¹ng muá»n tÃ¬m dá»±a vÃ o tá»±a sÃ¡ch hoáº·c áº£nh bÃ¬a cá»§a nÃ³. Trong má»t sá» bá» sÆ°u táº­p nhá»¯ng hÃ¬nh minh há»a nÃ y ÄÆ°á»£c Äi kÃšm vá»i báº£ng má»¥c lá»¥c, má»t sá» khÃ¡c chá» chá»©a sá» cá»§a trang cá»§a sÃ¡ch cÃ¹ng vá»i vá»i má»t há»p thoáº¡i. NgÆ°á»i dÃ¹ng nháº­p vÃ o sá» trang muá»n xem trong há»p thoáº¡i vÃ  Äi tiáº¿p hoáº·c quay trá» láº¡i trang ÄÃ£ xem. Trong báº£ng má»¥c lá»¥c, pháº§n tiÃªu Äá» ÄÆ°á»£c in Äáº­m vÃ  báº£ng má»¥c lá»¥c cÃ³ thá» ÄÆ°á»£c má» rá»ng cÃ¡c thÃ nh pháº§n cáº¥p con cá»§a nÃ³ báº±ng cÃ¡ch nháº¥n chuá»t trÃªn thÆ° má»¥c Äá» má» hoáº·c ÄÃ³ng chÃºng; nháº¥n chuá»t vÃ o biá»u tÆ°á»£ng cuá»n sÃ¡ch má» á» bÃªn trÃªn Äá» ÄÃ³ng nÃ³.</p>
+
+<p>PhÃ­a bÃªn dÆ°á»i lÃ  ná»i dung cá»§a má»¥c ÄÆ°á»£c chá»n. Sau khi Äá»c xong, ngÆ°á»i dÃ¹ng cÃ³ thá» chuyá»n sang pháº§n káº¿ tiáº¿p hoáº·c quay trá» láº¡i trang trÆ°á»c ÄÃ¢y báº±ng cÃ¡c nÃºt mÅ©i tÃªn di chuyá»n á» bÃªn dÆ°á»i..</p>
+
+<p>PhÃ­a dÆ°á»i tiÃªu Äá» hoáº·c hÃ¬nh áº£nh cÃ³ má»t sá» nÃºt. NÃºt <i>Má» vÄn báº£n</i> sáºœ má» rá»ng
+toÃ n bá» ná»i dung thÆ° má»¥c hoáº·c ná»i dung quyá»n sÃ¡ch hiá»n hÃ nh.
+Náº¿u tÃ i liá»u quÃ¡ lá»n, cÃ³ thá» pháº£i Äá»£i má»t Ã­t thá»i gian. NÃºt <i>Má» ná»i dung</i> sáºœ
+má» rá»ng toÃ n bá» ná»i dung cá»§a báº£ng, giÃºp ngÆ°á»i dÃ¹ng tháº¥y tÃªn táº¥t cáº£ cÃ¡c chÆ°Æ¡ng, cÃ¡c
+thÆ° má»¥c con (subsections). NÃºt <i>Má» cá»­a sá» má»i</i> cÃ³ tÃ¡c dá»¥ng má» ra cá»­a sá» má»i. (Chá»©c nÄng nÃ y giÃºp ngÆ°á»i dÃ¹ng dá»
+ dÃ ng Äá»c vÃ  so sÃ¡nh cÃ¡c tÃ i liá»u vá»i nhau). Cuá»i cÃ¹ng, khi
+báº¡n tÃ¬m kiáº¿m vá»i cÃ¡c tá»«, cÃ¡c tá»« ÄÃ³ sáºœ ÄÆ°á»£c tÃŽ má»t vá»t sÃ¡ng. Nháº¥n chuá»t vÃ o nÃºt <i>KhÃŽng tÃŽ mÃ u</i> Äá»
+xoÃ¡ cÃ¡c pháº§n tÃŽ má»t vá»t sÃ¡ng.</p>
+}  
+
+# help about the icons
+_texthelpopenbookshelf_ [l=vi] {Má» ká» sÃ¡ch nÃ y}
+_texthelpopenbook_ [l=vi] {Má»/ÄÃ³ng sÃ¡ch nÃ y}
+_texthelpviewtextsection_ [l=vi] {Xem pháº§n nÃ y cá»§a vÄn báº£n}
+_texthelpexpandtext_ [l=vi] {Hiá»n thá» táº¥t cáº£ cÃ¡c vÄn báº£n hoáº·c khÃŽng}
+_texthelpexpandcontents_ [l=vi] {Má» báº£ng ná»i dung hoáº·c khÃŽng}
+_texthelpdetachpage_ [l=vi] {Má» trang nÃ y trong má»t cá»­a sá» má»i}
+_texthelphighlight_ [l=vi] {TÃŽ mÃ u Äiá»u kiá»n tÃ¬m kiáº¿m hoáº·c khÃŽng}
+_texthelpsectionarrows_ [l=vi] {Äi tá»i trang trÆ°á»c/sau}  
+
+
+_texthelpsearchingtitle_ [l=vi] {CÃ¡ch tÃ¬m kiáº¿m theo tá»« khoÃ¡}
+
+_texthelpsearching_ [l=vi] {<p>
+  Tá»« trang tÃ¬m kiáº¿m, cÃ³ thá» thá»±c hiá»n cÃ¢u truy váº¥n theo cÃ¡c bÆ°á»c ÄÆ¡n giáº£n sau:<p>
+  
+  <ol><li>XÃ¡c Äá»nh cÃ¡c má»¥c cáº§n tÃ¬m.
+      <li>TÃ¬m táº¥t cáº£ cÃ¡c tá»« hay chá» má»t sá» tá»«.
+      <li>Nháº­p vÃ o nhá»¯ng tá»« cáº§n tÃ¬m kiáº¿m
+      <li>Nháº¥n chuá»t vÃ o nÃºt <i>Báº¯t Äáº§u tÃ¬m kiáº¿m</i>.
+  </ol>
+
+<p>Khi thá»±c hiá»n cÃ¢u truy váº¥n, tÃªn cá»§a 20 tÃ i liá»u phÃ¹ há»£p yÃªu cáº§u
+sáºœ ÄÆ°á»£c trÃ¬nh bÃ y. á» cuá»i má»i trang sáºœ cÃ³ nÃºt Äá» cho ngÆ°á»i dÃ¹ng chuyá»n
+sang trang káº¿ cÅ©ng chá»©a tá»i Äa 20 tÃ i liá»u. Tá»« vá» trÃ­ ÄÃ³ ngÆ°á»i dÃ¹ng sáºœ tÃ¬m tháº¥y
+cÃ¡c nÃºt Äá» ngÆ°á»i dÃ¹ng chuyá»n sang trang tiáº¿p theo hoáº·c trá» vá» trang Äáº§u, cá»©
+tiáº¿p tá»¥c nhÆ° tháº¿ Äá» xem káº¿t quáº£. Nháº¥n lÃªn tÃªn cá»§a báº¥t kÃ¬ má»t tÃ i liá»u nÃ o hoáº·c
+nÃºt nhá» bÃªn cáº¡nh nÃ³ Äá» xem ná»i dung.
+
+<p>Tá»i Äa 100 káº¿t quáº£ ÄÆ°á»£c trÃ¬nh bÃ y trong sá» káº¿t quáº£ tráº£ vá». NgÆ°á»i dÃ¹ng cÃ³
+thá» thay Äá»i con sá» nÃ y báº±ng nháº¥n lÃªn nÃºt <i>cÃ¡c thuá»c tÃ­nh</i> phÃ­a trÃªn cÃ¹ng
+cá»§a trang. <p>
+}  
+
+_texthelpquerytermstitle_ [l=vi] {CÃ¡c Äiá»u kiá»n tÃ¬m kiáº¿m}
+_texthelpqueryterms_ [l=vi] {<p>NgÆ°á»i dÃ¹ng nháº­p danh sÃ¡ch cÃ¡c tá»« ÄÆ°á»£c Äá»nh nghÄ©a lÃ  âtá»« khÃ³aâ cáº§n tÃ¬m kiáº¿m vÃ o há»p truy váº¥n. Má»i Äiá»u kiá»n tÃ¬m kiáº¿m chá» chá»©a cÃ¡c kÃ­ tá»± alphabet hay chá»¯ sá». CÃ¡c tá»« pháº£i ÄÆ°á»£c cÃ¡ch ra báº±ng khoáº£ng tráº¯ng. Báº¥t cá»© cÃ¡c dáº¥u cháº¥m cÃ¢u, cháº¥m pháº©y, gáº¡ch ngang, v.v.. cÅ©ng Äá»u ÄÆ°á»£c xem nhÆ° lÃ  khoáº£ng tráº¯ng. KhÃŽng thá» tÃ¬m nhá»¯ng tá»« khÃ³a cÃ³ chá»©a dáº¥u cháº¥m.
+
+<p>CÃ¢u truy váº¥n sau<p>
+    <ul><kbd>Agro-forestry in the Pacific Islands: Systems for Sustainability (1993)</kbd></ul>
+      <p>sáºœ tÆ°Æ¡ng ÄÆ°Æ¡ng vá»i<p>
+      <ul><kbd>Agro forestry in the Pacific Islands  Systems for Sustainability  1993 </kbd></ul><p>
+}  
+
+_texthelpmgppsearching_ [l=vi] {Äá» bá» sÆ°u táº­p xÃ¢y dá»±ng MGPP,  má»t sá» tÃ¹y chá»n ÄÆ°á»£c cung cáº¥p sáºµn. 
+
+<ul>
+<li>Má»t <b>*</b> á» cuá»i cá»§a thuáº­t ngá»¯ truy váº¥n káº¿t há»£p vá»i táº¥t cáº£ cÃ¡c tá»« <b>báº¯t Äáº§u vá»i</b> tá»« ÄÃ³, e.g. <b>comput*</b> káº¿t há»£p táº¥t cáº£ cÃ¡c tá»« báº¯t Äáº§u báº±ng <b>comput</b>.
+<li><b>/x</b> ÄÆ°á»£c sá»­ dá»¥ng Äá» thá»±c hiá»n tÃ¬m kiáº¿m rá»ng hÆ¡n so vá»i má»t thuáº­t ngá»¯ truy váº¥n, eg <b>computer/10 science</b> cho káº¿t quáº£ computer 10 times more weight than science when ranking documents.
+</ul>
+}  
+
+_texthelplucenesearching_ [l=vi] {Äá»i vá»i cÃ¡c bá» sÆ°u táº­p ÄÆ°á»£c xÃ¢y dá»±ng báº±ng Lucene cÃ³ nhá»¯ng thao tÃ¡c lá»±a chá»n sau. 
+
+<ul>
+<li><b>?</b> cÃ³ thá» ÄÆ°á»£c sá»­ dá»¥ng lÃ m Äáº¡i diá»n cho má»t kÃœ tá»± báº¥t ká»³. VÃ­ dá»¥, <b>b?t</b> sáºœ cho káº¿t quáº£ <b>bet</b>, <b>bit</b> vÃ  <b>bat</b> ....
+<li><b>*</b> cÃ³ thá» ÄÆ°á»£c sá»­ dá»¥ng lÃ m Äáº¡i diá»n cho má»t nhÃ³m kÃœ tá»± báº¥t ká»³. VÃ­ dá»¥, <b>comput*</b> sáºœ cho káº¿t quáº£ táº¥t cáº£ cÃ¡c tá»« báº¯t Äáº§u báº±ng <b>comput</b>.
+</ul>
+Cáº£ 2 kÃœ tá»± Äáº¡i diá»n Äá»u cÃ³ thá» ÄÆ°á»£c sá»­ dá»¥ng á» vá» trÃ­ giá»¯a hoáº·c cuá»i cá»¥m tá»«. Hoáº·c cÃ³ thá» ÄÆ°á»£c sá»­ dá»¥ng á» vá» trÃ­ Äáº§u tiÃªn cá»§a cá»¥m tá»« cáº§n tÃ¬m.
+}  
+
+_texthelpquerytypetitle_ [l=vi] {Loáº¡i truy váº¥n}
+_texthelpquerytype_ [l=vi] {<p>CÃ³ 2 loáº¡i truy váº¥n khÃ¡c nhau.
+
+<ul>
+  <li>Loáº¡i truy váº¥n thá»© nháº¥t lÃ  tÃ¬m <b>Táº¥t cáº£</b> cÃ¡c tá»« trong há»p thoáº¡i tÃ¬m kiáº¿m. QuÃ¡ trÃ¬nh tÃ¬m kiáº¿m sáºœ tÃ¬m tá»« ÄÃ£ nháº­p vÃ o so vá»i cÃ¡c tá»« trong tÃ i liá»u (thÆ°á»ng tÃ¬m á» ChÆ°Æ¡ng vÃ  Nhan Äá»). Nhá»¯ng tÃ i liá»u nÃ o thá»a Äiá»u kiá»n tÃ¬m kiáº¿m sáºœ ÄÆ°á»£c trÃ¬nh bÃ y theo thá»© tá»± alphabe.<p>
+
+  <li>Loáº¡i thá»© hai lÃ  chá» tÃ¬m <b>má»t sá»</b> tá»« trong má»t loáº¡t tá»« mÃ  báº¡n ÄÃ£ nháº­p liá»u. Nhá»¯ng tÃ i liá»u nÃ o thá»a Äiá»u kiá»n tÃ¬m kiáº¿m hÆ¡n cáº£ sáºœ ÄÆ°á»£c hiá»n thá». CÃ¡c tÃ i liá»u ÄÆ°á»£c tÃ¬m tháº¥y sáºœ ÄÆ°á»£c sáº¯p xáº¿p theo Äá» phÃ¹ há»£p cá»§a chÃºng Äá»i vá»i yÃªu cáº§u tÃ¬m kiáº¿m. Äá» phÃ¹ há»£p nÃ y ÄÆ°á»£c xÃ¡c Äá»nh dá»±a trÃªn:
+      <p><ul>
+         <li> TÃ i liá»u nÃ o chá»©a cÃ ng nhiá»u cÃ¡c tá»« tÃ¬m kiáº¿m trong há»p thoáº¡i thÃ¬ káº¿t quáº£ cÃ ng chÃ­nh xÃ¡c.
+         <li> CÃ¡c tá»« Ã­t thÃŽng dá»¥ng quan trá»ng hÆ¡n cÃ¡c tá»« thÃŽng dá»¥ng
+         <li> TÃ i liá»u cÃ³ ná»i dung ngáº¯n dá»
+ thoáº£ Äiá»u kiá»n tÃ¬m kiáº¿m hÆ¡n.
+      </ul>
+</ul>
+  
+<p>Chá»n cÃ¡ch tÃ¬m kiáº¿m thÃ­ch há»£p - Chá»n tÃ¬m theo cÃ¢u vÄn hoáº·c tÃ¬m theo Äoáº¡n vÄn. Náº¿u ngÆ°á»i dÃ¹ng xÃ¡c Äá»nh chá» gÃµ vÃ o má»t tá»« thÃ¬ cÃ¡c 
+káº¿t quáº£ ÄÆ°á»£c sáº¯p thá»© tá»± theo sá» láº§n xuáº¥t hiá»n tá»« cáº§n tÃ¬m kiáº¿m trong má»i tÃ i liá»u.<p>
+}  
+
+_texthelpadvancedsearchtitle_ [l=vi] {TÃ¬m kiáº¿m nÃ¢ng cao sá»­ dá»¥ng phÆ°Æ¡ng tiá»n tÃ¬m kiáº¿m _1_}  
+
+_texthelpadvancedsearch_ [l=vi] {<p> Náº¿u chá»n chá»©c nÄng truy váº¥n nÄng cao, cÃ¡c tÃ¹y chá»n tÃ¬m kiáº¿m sáºœ khÃŽng khÃ¡c nhau nhiá»u.}  
+
+_texthelpadvsearchmg_ [l=vi] {TÃ¬m kiáº¿m nÃ¢ng cao trong bá» sÆ°u táº­p MG cung cáº¥p 2 tÃ¹y chá»n, hÃ ng vÃ  logic. Má»t tÃ¹y chá»n tÃ¬m kiáº¿m theo <b>hÃ ng</b> thÃ¬ giá»ng vá»i <b>má»t vÃ i</b> kiá»u tÃ¬m kiáº¿m ÄÃ£ ÄÆ°á»£c mÃŽ táº£ trong <a href="\#query-type">_texthelpquerytypetitle_</a>.
+<p>_texthelpbooleansearch_
+}  
+
+_texthelpbooleansearch_ [l=vi] {Kiá»u tÃ¬m kiáº¿m theo <b>logic</b> cho phÃ©p káº¿t há»£p cÃ¡c thuáº­t ngá»¯ báº±ng toÃ¡n tá»­ Boole vá»i cÃ¡c kÃœ hiá»u & ("vÃ " "AND"), | ("hoáº·c" "OR" ), vÃ  ! ("khÃŽng" "NOT"), sá»­ dá»¥ng dáº¥u ngoáº·c ÄÆ¡n Äá» nhÃ³m cÃ¡c thÃ nh pháº§n. ToÃ¡n tá»± máº·c Äá»nh lÃ  | (Äá» thá»±c hiá»n "hoáº·c").
+<p>
+VÃ­ dá»¥: <b> snail & farming</b> sáºœ thá»±c hiá»n tÃ¬m táº¥t cáº£ cÃ¡c tÃ i liá»u cÃ³ chá»©a Äá»ng thá»i cáº£ hai thuáº­t ngá»¯ <b>snail</b> VÃ <b>farming</b>; khi chá»n <b>snail | farming</b> thÃ¬ sáºœ thá»±c hiá»n tÃ¬m kiáº¿m nhá»¯ng tÃ i liá»u hoáº·c cÃ³ chá»©a hoáº·c <b>snail</b> hoáº·c <b>farming</b> hoáº·c cáº£ hai thuáº­t ngá»¯.
+}  
+
+_texthelpadvsearchmgpp_ [l=vi] {TÃ¬m kiáº¿m nÃ¢ng cao trong bá» sÆ°u táº­p MGPP sá»­ dá»¥ng cÃ¡c toÃ¡n tá»­ logic. _texthelpbooleansearch_<p> Káº¿t quáº£ cÃ³ thá» hiá»n thá» theo thá»© tá»± hÃ ng, mÃŽ táº£ cho má»t vÃ i tÃ¬m kiáº¿m theo <a href="\#query-type">_texthelpquerytypetitle_</a>, hoáº·c theo thá»© tá»± "natural"(hoáº·c theo "build"). ÄÃ¢y lÃ  thá»© tá»± mÃ  tÃ i liá»u cung cáº¥p trong suá»t tiáº¿n trÃ¬nh táº¡o bá» sÆ°u táº­p. <p> CÃ¡c toÃ¡n tá»­ nÃ¢ng cao bao gá»m NEARx vÃ  WITHINx. NEARx dÃ¹ng Äá» chá» Äá»nh khoáº£ng cÃ¡ch tá»i Äa (x tá»«) giá»¯a 2 thuáº­t ngá»¯ truy váº¥n ÄÆ°á»£c káº¿t há»£p. WITHINx chá» Äá»nh thuáº­t ngá»¯ thá»© 2 sáºœ xuáº¥t hiá»n x tá»« <i>sau</i> thuáº­t ngá»¯ thá»© nháº¥t. TÆ°Æ¡ng tá»± nhÆ° cÃ¡ch sá»­ dá»¥ng NEAR nhÆ°ng trong pháº§n nÃ y thÃ¬ quan trá»ng thá»© tá»± hÆ¡n. Khoáº£ng cÃ¡ch máº·c Äá»nh lÃ  20.}  
+
+_texthelpadvancedsearchextra_ [l=vi] {ChÃº Ãœ: CÃ¡c phÃ©p toÃ n nÃ y sáºœ ÄÆ°á»£c bá» qua náº¿u thá»±c hiá»n tÃ¬m kiáº¿m theo dáº¡ng cÃ¢u truy váº¥n ÄÆ¡n giáº£n.}  
+
+_texthelpadvsearchlucene_ [l=vi] {TÃ¬m kiáº¿m nÃ¢ng cao trong bá» sÆ°u táº­p Lucene sá»­ dá»¥ng cÃ¡c toÃ¡n tá»­ logic._texthelpbooleansearch_
+}  
+
+_texthelpformsearchtitle_ [l=vi] {TrÆ°á»ng tÃ¬m kiáº¿m}  
+
+_texthelpformsearch_ [l=vi] {<p>TrÆ°á»ng tÃ¬m kiáº¿m cung cáº¥p kháº£ nÄng tÃ¬m káº¿t há»£p giá»¯a cÃ¡c má»¥c. Cho vÃ­ dá»¥, má»t ngÆ°á»i cÃ³ thá» thá»±c hiá»n tÃ¬m kiáº¿m Nhan Äá» lÃ  "Smith" VÃ chá»§ Äá» "snail farming". Trong chá»©c nÄng tÃ¬m kiáº¿m ÄÆ¡n giáº£n, chÆ°Æ¡ng trÃ¬nh sáºœ thá»±c hiá»n viá»c tÃ¬m kiáº¿m riÃªng láº» tá»«ng dÃ²ng trÃªn giao diá»n, káº¿t há»£p theo phÃ©p toÃ¡n VÃ (khi chá»n tÃ¬m "Táº¥t cáº£") hoáº·c phÃ©p toÃ¡n Hoáº·c (khi tÃ¬m theo "Má»t VÃ i"). CÃ¡c thuáº­t ngá»¯ á» bÃªn trong cÃ¡c trÆ°á»ng cÅ©ng ÄÆ°á»£c káº¿t há»£p theo qui táº¯c tÆ°Æ¡ng tá»±. Trong chá»©c nÄng tÃ¬m kiáº¿m nÃ¢ng cao, ngÆ°á»i dÃ¹ng chá» Äá»nh viá»c sá»­ dá»¥ng cÃ¡c toÃ¡n tá»­ VÃ/HOáº¶C/KHÃNG trong cÃ¡c danh sÃ¡ch sá» xuá»ng Äá» káº¿t há»£p giá»¯a cÃ¡c trÆ°á»ng thá»±c hiá»n tÃ¬m kiáº¿m. NgoÃ i ra, cÃ²n cÃ³ thá» káº¿t há»£p cáº£ viá»c sá»­ dá»¥ng cÃ¡c toÃ¡n tá»­ logic.}  
+
+_texthelpformstemming_ [l=vi] {Há»p (Chuyá»n chá»¯, Gá»c tá»«) cho phÃ©p chá» Äá»nh ráº±ng : khi "Chuyá»n chá»¯" ÄÆ°á»£c kÃ­ch chá»n, chÆ°Æ¡ng trÃ¬nh sáºœ tá»± Äá»ng chuyá»n Äáº£o thuáº­t ngá»¯ trong há»p cÃ¢u há»i thanh chá»¯ hoa hoáº·c ngÆ°á»£c láº¡i, vÃ  khi "Gá»c tá»«" ÄÆ°á»£c chá»n, há» thá»ng sáºœ coi thuáº­t ngá»¯ trong há»p cÃ¢u há»i lÃ  gá»c tá»« Äá» so sÃ¡nh vÃ  thá»±c hiá»n tÃ¬m theo gá»c tá»« ÄÃ³ (nÃ³i cÃ¡ch khÃ¡c ÄÃ¢y lÃ  viá»c gÃ¡n kÃœ hiá»u cháº·t cá»¥t (truncation mark) vÃ o cuá»i tá»«). Máº·c Äá»nh, hai há»p kÃ­ch chá»n nÃ y á» dáº¡ng khÃŽng ÄÆ°á»£c chá»n trong biá»u máº«u tÃ¬m kiáº¿m nÃ¢ng cao.}  
+
+_textdatesearch_ [l=vi] {TÃ¬m kiáº¿m theo ngÃ y thÃ¡ng}  
+
+_texthelpdatesearch_ [l=vi] {TÃ¬m kiáº¿m theo ngÃ y thÃ¡ng cho phÃ©p ngÆ°á»i dÃ¹ng tÃ¬m cÃ¡c tÃ i liá»u thá»a mÃ£n cÃ¡c tá»« khÃ³a vÃ  náº±m trong má»t khaá»ng thá»i gian nÃ o ÄÃ³. NgÆ°á»i dÃ¹ng cÃ³ thá» tÃ¬m cÃ¡c tÃ i liá»u trong má»t nÄm hay trong má»t khoáº£ng thá»i gian nhiá»u nÄm. LÆ°u Ãœ ráº±ng ngÆ°á»i dÃ¹ng khÃŽng cáº§n pháº£i cÃ³ tá»« khÃ³a nÃ o cáº£ - cÃ³ thá» chá» tÃ¬m kiáº¿m theo ngÃ y thÃ¡ng, hay ngÆ°á»£c láº¡i, khÃŽng nháº¥t thiáº¿t pháº£i sá»­ dá»¥ng ngÃ y thÃ¡ng trong quÃ¡ trÃ¬nh tÃ¬m kiáº¿m. Náº¿u ngÆ°á»i dÃ¹ng khÃŽng chá» rÃµ ngÃ y thÃ¡ng thi viá»c tÃ¬m kiáº¿m sáºœ giá»ng nhÆ° khi chá»©c nÄng tÃ¬m kiáº¿m báº±ng ngÃ y thÃ¡ng khÃŽng tá»n táº¡i. <p>
+}  
+
+_texthelpdatehowtotitle_ [l=vi] {CÃ¡ch sá»­ dá»¥ng chá»©c nÄng nÃ y:}
+_texthelpdatehowto_ [l=vi] {<ul>
+   <li>Äá» tÃ¬m tÃ i liá»u trong má»t nÄm:<p>
+   <ul>
+       <li>ÄÃ¡nh vÃ o cÃ¡c tá»« khÃ³a Äá» tÃ¬m kiáº¿m nhÆ° bÃ¬nh thÆ°á»ng.
+       <li>ÄÃ¡nh nÄm cáº§n tÃ¬m vÃ o há»p "Start (or only) date".
+       <li>Náº¿u nÄm cáº§n tÃ¬m lÃ  trá»©Æ¡c cÃŽng nguyÃªn, hÃ£y chá»n chá»©c nÄng "B.C.E" tá»« há»p menu bÃªn cáº¡nh.
+       <li>Báº¯t Äáº§u tÃ¬m kiáº¿m nhÆ° bÃ¬nh thÆ°á»ng
+   </ul>
+<p><li> Äá» tÃ¬m tÃ i liá»u trong má»t khoáº£ng thá»i gian nhiá»u nÄm:<p>
+   <ul>
+       <li> ÄÃ¡nh vÃ o cÃ¡c tá»« khÃ³a Äá» tÃ¬m kiáº¿m nhÆ° bÃ¬nh thÆ°á»ng.
+       <li> ÄÃ¡nh nÄm báº¯t Äáº§u vÃ o há»p "Start (or only) date".
+       <li> ÄÃ¡nh nÄm káº¿t thÃºc vÃ o há»p "End date" box.
+       <li>Náº¿u nÄm cáº§n tÃ¬m lÃ  trá»©Æ¡c cÃŽng nguyÃªn, hÃ£y chá»n chá»©c nÄng "B.C.E" tá»« há»p menu bÃªn cáº¡nh.
+       <li> Báº¯t Äáº§u tÃ¬m kiáº¿m nhÆ° bÃ¬nh thÆ°á»ng
+   </ul>    
+</ul><p>
+}
+
+_texthelpdateresultstitle_ [l=vi] {CÃ¡ch quÃ¡ trÃ¬nh tÃ¬m kiáº¿m ÄÆ°á»£c thá»±c hiá»n}
+_texthelpdateresults_ [l=vi] {NÃ³i chung, khi tÃ¬m kiáº¿m cÃ¡c vÄn báº£n liÃªn quan Äáº¿n nÄm 1903, sáºœ khÃŽng tÃ¬m ÄÆ°á»£c cÃ¡c tÃ i liá»u viáº¿t vÃ o nÄm 1903, mÃ  chá» cÃ³ cÃ¡c tÃ i liá»u viáº¿t vá» nÄm 1903. Tuy nhiÃªn, káº¿t quáº£ sáºœ lÃ  cÃ¡c vÄn báº£n mÃ  ngÃ y thÃ¡ng cá»§a nÃ³ (vÃ­ dá»¥ 1899-1911) cÃ³ chá»©a 1903 vÃ  cáº£ nhá»¯ng vÄn báº£n mÃ  ná»i dung cÃ³ ghi tÃªn tháº¿ ká» mÃ  nÄm 1903 thuá»c vá» (vÃ­ dá»¥ tháº¿ ká» 20). CÃ³ nghÄ©a lÃ . Äá»i vá»i má»t sá» vÄn báº£n, ngÃ y thÃ¡ng cáº§n tÃ¬m khÃŽng xuáº¥t hiá»n trá»±c tiáº¿p trÃªn vÄn báº£n. Äá»i vá»i tÃ¬m kiáº¿m trong má»t khoáº£ng thá»i gian, táº¥t cáº£ nhá»¯ng nguyÃªn táº¯c trÃªn ÄÆ°á»£c Ã¡p dá»¥ng cho tá»«ng ngÃ y trong khoáº£ng thá»i gian ÄÃ³.
+<p>
+}  
+
+_textchangeprefs_ [l=vi] {Thay Äá»i nhá»¯ng thuá»c tÃ­nh}
+
+_texthelppreferences_ [l=vi] {<p>Khi ngÆ°á»i dÃ¹ng nháº¥n chuá»t lÃªn nÃºt <i>Thuá»c tÃ­nh</i> á» phÃ­a trÃªn cá»§a trang, ngÆ°á»i dÃ¹ng sáºœ cÃ³ thá» thay Äá»i má»t vÃ i Äáº·c Äiá»m cá»§a giao diá»n cho phÃ¹ há»£p vá»i cÃ¡ nhÃ¢n.}  
+
+_texthelpcollectionprefstitle_ [l=vi] {Thuá»c tÃ­nh Bá» sÆ°u táº­p}
+_texthelpcollectionprefs_ [l=vi] {Má»t sá» bá» sÆ°u táº­p ÄÆ°á»£c káº¿t há»£p tá»« nhiá»u bá» sÆ°u táº­p nhá» hÆ¡n. NgÆ°á»i dÃ¹ng cÃ³ thá» thá»±c hiá»n tÃ¬m kiáº¿m chÃºng má»t cÃ¡ch Äá»c láº­p hoáº·c káº¿t há»£p lÃ  má»t. VÃ¬ váº­y, trang Thuá»c tÃ­nh cho phÃ©p ngÆ°á»i dÃ¹ng thÃªm cÃ¡c bá» sÆ°u táº­p con vÃ o káº¿t quáº£ tÃ¬m kiáº¿m.
+}  
+
+_texthelplanguageprefstitle_ [l=vi] {Thuá»c tÃ­nh ngÃŽn ngá»¯}
+_texthelplanguageprefs_ [l=vi] {Má»i bá» sÆ°u táº­p Äá»u cÃ³ ngÃŽn ngá»¯ thá» hiá»n riÃªng, nhÆ°ng váº«n cÃ³ thá» chuyá»n sang ngÃŽn ngá»¯ khÃ¡c. Báº¡n cÃ³ thá» thay Äá»i cÃ¡ch mÃ£ hoÃ¡ mÃ  Greenstone sá»­ dá»¥ng Äá» hiá»n thá» ra trÃ¬nh duyá»t trong viá»c tÃ¬m kiáº¿m. ThÆ°á»ng thÃ¬ máº·c Äá»nh Greenstone sáºœ chá»n má»t cÃ¡ch thÃ­ch há»£p nháº¥t, nhÆ°ng má»t sá» trÃ¬nh duyá»t khÃ¡c sáºœ hoáº¡t Äá»ng tá»t hÆ¡n Äá»i vá»i má»t sá» loáº¡i mÃ£ hÃ³a khÃ¡c nhau.. Táº¥t cáº£ cÃ¡c bá» sÆ°u táº­p Äá»u cho phÃ©p ngÆ°á»i dÃ¹ng chuyá»n tá»« giao diá»n Äá» há»a dáº¡ng chuáº©n sang dáº¡ng vÄn báº£n. Náº¿u gáº·p khÃ³ khÄn trong viá»c Äá»c dá»¯ liá»u, ngÆ°á»i dÃ¹ng cÃ³ thá» Äiá»u chá»nh kÃ­ch thÆ°á»c chá»¯ lá»n hÆ¡n hoáº·c chuyá»n vÄn báº£n sang dáº¡ng Ã¢m thanh.}  
+
+_texthelppresentationprefstitle_ [l=vi] {Thuá»c tÃ­nh trÃ¬nh bÃ y}
+_texthelppresentationprefs_ [l=vi] {TÃ¹y thuá»c vÃ o tá»«ng bá» sÆ°u táº­p, ngÆ°á»i dÃ¹ng cÃ³ thá» chá»n cÃ¡c thuá»c tÃ­nh trÃ¬nh bÃ y khÃ¡c nhau.
+
+<p>NgÆ°á»i dÃ¹ng cáº§n táº¯t thanh Äiá»u khiá»n cá»§a Greenstone trÃªn Äáº§u má»i trang tÃ i liá»u Äá» chuyá»n sang má»t trang web khÃ¡c hiá»n thá» káº¿t quáº£ tÃ¬m kiáº¿m. Muá»n thá»±c hiá»n má»t tÃ¬m kiáº¿m má»i,  pháº£i báº¥m vÃ o nÃºt âbackâ Äá» quay trá» láº¡i trang ban Äáº§u. Bá» sÆ°u táº­p nÃ y cÅ©ng cho phÃ©p táº¯t nhá»¯ng cáº£nh bÃ¡o khi ngÆ°á»i dÃ¹ng nháº¥n vÃ o liÃªn káº¿t thoÃ¡t khá»i ThÆ° viá»n tÃ i liá»u sá». á» má»t sá» bá» sÆ°u táº­p dáº¡ng web, ngÆ°á»i dÃ¹ng cÃ³ thá» nháº¥n trá»±c tiáº¿p vÃ o cÃ¡c liÃªn káº¿t URL tá»« káº¿t quáº£ tÃ¬m kiáº¿m Äá» xem tÃ i liá»u gá»c hoáº·c sá»­ dá»¥ng báº£n sao cá»§a nÃ³ cÃ³ trong thÆ° viá»n sá». 
+}  
+
+_texthelpsearchprefstitle_ [l=vi] {CÃ¡c thuá»c tÃ­nh tÃ¬m kiáº¿m}
+_texthelpsearchprefs_ [l=vi] {<p>CÃ³ hai cáº·p nÃºt Äiá»u khiá»n loáº¡i vÄn báº£n thÃ­ch há»£p trong tÃ¬m kiáº¿m. Cáº·p nÃºt Äáº§u tiÃªn cho phÃ©p tÃ¬m kiáº¿m cÃ³ phÃ¢n biá»t chá»¯ hoa vá»i chá»¯ thÆ°á»ng. Cáº·p nÃºt tiáº¿p theo cho phÃ©p tÃ¬m kiáº¿m cÃ³ bá» qua pháº§n háº­u tá» cá»§a tá»« hay khÃŽng. NÃ³ cÃ³ thá» cho phÃ©p kÃ­ch thÆ°á»c há»p truy váº¥n nhiá»u dÃ²ng hÆ¡n bÃ¬nh thÆ°á»ng Äá» báº¡n cÃ³ thá» thá»±c hiá»n tÃ¬m kiáº¿m theo Äoáº¡n vÄn.
+
+<p>VÃ­ dá»¥ náº¿u ngÆ°á»i dÃ¹ng chá»n nÃºt <i>bá» qua phÃ¢n biá»t hoa/thÆ°á»ng</i> vÃ  <i>bá» qua pháº§n cuá»i cá»§a tá»«</i> thÃ¬
+cÃ¢u truy váº¥n <p>
+      <ul><kbd>African building</kbd></ul>
+       <p>sáºœ ÄÆ°á»£c xem nhÆ° lÃ <p>
+       <ul><kbd>africa builds</kbd></ul><p>bá»i vÃ¬ tá»« kÃœ tá»±
+hoa trong âAfricanâ sáºœ ÄÆ°á»£c chuyá»n thÃ nh chá»¯ thÆ°á»ng, vÃ  háº­u tá» ânâ vÃ  âingâ sáºœ
+ÄÆ°á»£c bá» Äi khá»i âAfricanâ vÃ  âbuildingâ (tÆ°Æ¡ng tá»±, âsâ cÅ©ng ÄÆ°á»£c bá» khá»i âbuildsâ).
+
+<p>NgÆ°á»i dÃ¹ng cÃ³ thá» chuyá»n Äáº¿n cháº¿ Äá» tÃ¬m kiáº¿m má» rá»ng Äá» káº¿t há»£p cÃ¡c Äiá»u kiá»n tÃ¬m kiáº¿m sá»­ dá»¥ng AND (&), OR(|), vÃ  NOT(!). Äiá»u nÃ y giÃºp tÄng Äá» chÃ­nh xÃ¡c cÃ¡c cÃ¢u truy váº¥n muá»n tÃ¬m. CÃ³ thá» xem láº¡i má»t vÃ i cÃ¢u truy váº¥n trÆ°á»c ÄÃ³ ÄÃ£ thá»±c hiá»n. Äiá»u nÃ y giÃºp ngÆ°á»i dÃ¹ng cÃ³ thá» chá»nh sá»­a cÃ¡c cÃ¢u nÃ y thÃ nh cÃ¡c cÃ¢u truy váº¥n má»i má»t cÃ¡ch dá»
+ dÃ ng. Cuá»i cÃ¹ng, cÃ³ thá» Äiá»u khiá»n sá» káº¿t quáº£ tráº£ vá» vÃ  sá» dÃ²ng ÄÆ°á»£c hiá»n thá» má»i láº§n trÃªn mÃ n hÃ¬nh.}  
+
+_textcasefoldprefs_ [l=vi] {Hai nÃºt cho phÃ©p thá»±c hiá»n chuyá»n sang chá»¯ hoa hoáº·c chá»¯ thÆ°á»ng khi tÃ¬m kiáº¿m. VÃ­ dá»¥: náº¿u "_preferences:textignorecase_" ÄÆ°á»£c chá»n, <i>snail farming</i> sáºœ ÄÆ°á»£c xem nhÆ° lÃ  <i>Snail Farming</i> vÃ  <i>SNAIL FARMING</i>.}  
+_textstemprefs_ [l=vi] {2 nÃºt cho phÃ©p bá» qua hay khÃŽng pháº§n cuá»i cá»§a má»t tá»« khi thá»±c hiá»n tÃ¬m kiáº¿m. VÃ­ dá»¥, náº¿u "_preferences:textstem_" ÄÆ°á»£c chá»n, <i>snail farming</i> sáºœ ÄÆ°á»£c xem nhÆ° lÃ  <i>snails farm</i> vÃ  <i>snail farmer</i>. Äiá»u nÃ y hiá»n táº¡i chá» sá»­ dá»¥ng khi cÃ¡c tá»« nháº­p vÃ o lÃ  tiáº¿ng Anh. _selectstemoptionsprefs_}  
+_textaccentfoldprefs_ [l=vi] {Hai nÃºt cho phÃ©p bá» qua hay khÃŽng viá»c Äáº·t dáº¥u nháº¥n trÃªn tá»« khi thá»±c hiá»n tÃ¬m kiáº¿m. VÃ­ dá»¥, náº¿u "_preferences:textignoreaccents_" ÄÆ°á»£c chá»n, <i>fÃ©dÃ©ration</i> sáºœ ÄÆ°á»£c xem nhÆ° lÃ  <i>fedÃ©ration</i> vÃ  <i>fedhttp://puka.cs.waikato.ac.nz/cgi-bin/gti/libraryeration</i>.}  
+ 
+_textstemoptionsprefs_ [l=vi] {Sá»­ dá»¥ng cÃ¡c chuá»i tÃ¬m kiáº¿m ÄÆ°á»£c cung cáº¥p sáºµn á» "_texthelpquerytermstitle_" giÃºp thá»±c hiá»n tÃ¬m kiáº¿m dá»
+ dÃ ng vÃ  chÃ­nh xÃ¡c.}  
+
+_textsearchtypeprefsplain_ [l=vi] {CÃ³ thá» chá»n má»t há»p truy váº¥n nhiá»u dÃ²ng Äá» nháº­p vÃ o nhá»¯ng Äoáº¡n vÄn báº£n cáº§n tÃ¬m. Sá»­ dá»¥ng há»p truy váº¥n giÃºp tÃ¬m kiáº¿m nhanh má»t sá» lÆ°á»£ng lá»n tá»« ngá»¯.}  
+
+_textsearchtypeprefsform_ [l=vi] {CÃ³ thá» thay Äá»i sá» lÆ°á»£ng cÃ¡c trÆ°á»ng hiá»n thá» trong trang TÃ¬m kiáº¿m.}  
+
+_textsearchtypeprefsboth_ [l=vi] {CÃ³ thá» chuyá»n Äá»i cÃ¡c kiá»u tÃ¬m kiáº¿m cá»§a bá» sÆ°u táº­p giá»¯a cháº¿ Äá» tÃ¬m kiáº¿m "CÆ¡ báº£n", vÃ  tÃ¬m kiáº¿m "Theo trÆ°á»ng". 
+<ul>
+<li>TÃ¬m kiáº¿m cÆ¡ báº£n cung cáº¥p má»t há»p truy váº¥n ÄÆ¡n. _textsearchtypeprefsplain_</li>
+<li>TÃ¬m kiáº¿m theo trÆ°á»ng cung cáº¥p má»t sá» há»p truy váº¥n, má»i há»p thá» hiá»n cho má»t trÆ°á»ng trong danh má»¥c. Äiá»u nÃ y cho phÃ©p thá»±c hiá»n tÃ¬m kiáº¿m nhiá»u trÆ°á»ng khÃ¡c nhau cÃ¹ng má»t lÃºc. _textsearchtypeprefsform_ </li>
+</ul>}  
+
+
+
+_texttanumbrowseoptions_ [l=vi] {CÃ³ _numbrowseoptions_ cÃ¡ch Äá» tÃ¬m kiáº¿m thÃŽng tin trong bá» sÆ°u táº­p nÃ y:}
+
+_textsimplehelpheading_ [l=vi] {TÃ¬m kiáº¿m thÃŽng tin trong bá» sÆ°u táº­p _collectionname_ nhÆ° tháº¿ nÃ o}
+
+_texthelpscopetitle_ [l=vi] {Pháº¡m vi cÃ¢u truy váº¥n}
+_texthelpscope_ [l=vi] {<p>
+Trong háº§u háº¿t cÃ¡c bá» sÆ°u táº­p ngÆ°á»i dÃ¹ng cÃ³ thá» lá»±a chá»n cÃ¡c danh má»¥c tÃ¬m kiáº¿m khÃ¡c nhau. VÃ­ dá»¥:  CÃ³ bá» sÆ°u táº­p chá» cho tÃ¬m kiáº¿m theo danh má»¥c tÃ¡c giáº£, tÃªn sÃ¡ch hoáº·c cÃ³ bá» sÆ°u táº­p láº¡i cho phÃ©p tÃ¬m theo ChÆ°Æ¡ng, theo Äoáº¡n. NÃ³i chung, káº¿t quáº£ thá»a Äiá»u kiá»n nháº¥t sáºœ ÄÆ°á»£c hiá»n thá», khÃŽng phá»¥ thuá»c vÃ o danh má»¥c tÃ¬m kiáº¿m mÃ  ngÆ°á»i dÃ¹ng ÄÃ£ chá»n.
+<p>Náº¿u tÃ i liá»u lÃ  sÃ¡ch thÃ¬ sáºœ ÄÆ°á»£c má» ra á» nÆ¡i thÃ­ch há»£p.
+}  
Index: /gsdl/stable/macros/vietnamese2.dm
===================================================================
--- /gsdl/stable/macros/vietnamese2.dm	(revision 20131)
+++ /gsdl/stable/macros/vietnamese2.dm	(revision 20131)
@@ -0,0 +1,895 @@
+# this file must be UTF-8 encoded
+######################################################################
+#
+# Vietnamese Language text and icon macros 
+# -- this file contains text that is of less importance
+# -- to translate when creating a new interface language
+######################################################################
+
+
+
+######################################################################
+# 'home' page
+package home
+######################################################################
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_documents_ [l=vi] {tÃ i liá»u. }
+_lastupdate_ [l=vi] {Cáº­p nháº­p láº§n cuá»i}
+_ago_ [l=vi] {cÃ¡ch ÄÃ¢y.}
+_colnotbuilt_ [l=vi] {Bá» sÆ°u táº­p khÃŽng ÄÆ°á»£c xÃ¢y dá»±ng.}
+
+### taken from here
+
+_textpoem_ [l=vi] {<br><h2>Kia papapounamu te moana</h2>
+
+<p>kia hora te marino,
+<br>kia tere te karohirohi,
+<br>kia papapounamu te moana
+
+<p>may peace and calmness surround you,
+<br>may you reside in the warmth of a summer's haze,
+<br>may the ocean of your travels be as smooth as the polished greenstone.
+}
+
+_textgreenstone_ [l=vi] {<p>Tá»« Greenstone cÃ³ nghÄ©a lÃ  má»t loáº¡i ÄÃ¡ quÃœ ÄÆ°á»£c tÃ¬m tháº¥y á» New Zealand. Trong vÄn hoÃ¡ truyá»n thá»ng Maori nÃ³ cÃ³ giÃ¡ trá» nháº¥t trong táº¥t cáº£ cÃ¡c váº­t cháº¥t ÄÆ°á»£c tÃ¬m tháº¥y. NÃ³ cÃ³ thá» háº¥p thá»¥ vÃ  chá»©a Äá»±ng <i> wairua</i>, má»t loáº¡i sá»©c máº¡nh tinh tháº§n ÄÆ°á»£c lÃ m giÃ u báº±ng nhá»¯ng giÃ¡ trá» truyá»n thá»ng, táº¥t cáº£ nhá»¯ng thá»© nÃ y táº¡o nÃªn má»t biá»u tÆ°á»£ng phÃ¹ há»£p cho dá»± Ã¡n thÆ° viá»n sá» nÃ y. Váº» Äáº¹p cá»§a nÃ³ toÃ¡t lÃªn sá»± nhÃ¢n Ã¡i, sá»± trong sÃ¡ng vÃ  tin cáº­y, sá»± kháº¯c nghiá»t, sá»± can Äáº£m vÃ  hÃ¬nh thÃ¹ cá»§a nÃ³ toÃ¡t lÃªn cáº£ sá»± cÃŽng báº±ng. Táº¥m kháº¯c ÄÆ°á»£c dÃ¹ng trÃªn logo cá»§a Greenstone ÄÆ°á»£c gá»i lÃ  <i>patu</i> - má»t vÅ© khÃ­ chiáº¿n Äáº¥u, ÄÃ¢y lÃ  má»t gia báº£o cá»§a má»t thÃ nh viÃªn trong dá»± Ã¡n. Trong chiáº¿n Äáº¥u, má»i thá»© pháº£i ÄÆ°á»£c phÃ¢n phá»i má»t cÃ¡ch nhanh chÃ³ng, chÃ­nh xÃ¡c vÃ  Äáº§y Äá»§. ChÃºng tÃŽi muá»n pháº§n má»m nÃ y cÅ©ng cÃ³ cÃ¡c tÃ­nh cháº¥t nÃ y. }  
+
+_textaboutgreenstone_ [l=vi] {<p>Greenstone lÃ  má»t bá» pháº§n má»m dÃ¹ng  Äá» xÃ¢y dá»±ng vÃ  phÃ¢n phá»i cÃ¡c bá» sÆ°u táº­p thÆ° viá»n sá». NÃ³ cung cáº¥p má»t phÆ°Æ¡ng phÃ¡p má»i Äá» tá» chá»©c vÃ  xuáº¥t báº£n thÃŽng tin trÃªn Internet hoáº·c trÃªn CD-ROM. Greenstone lÃ  sáº£n pháº©m cá»§a dá»± Ã¡n <b>New Zealand Digital Library</b> cá»§a trÆ°á»ng Äáº¡i há»c <b>University of Waikato</b>, ÄÆ°á»£c phÃ¡t triá»n vÃ   phÃ¢n phá»i vá»i sá»± tham gia cá»§a <b>UNESCO</b> vÃ  <b>Human Info NGO</b>. ÄÃ¢y lÃ  pháº§n má»m mÃ£ nguá»n má» ÄÆ°á»£c cung cáº¥p trÃªn <a href="http://greenstone.org">http://greenstone.org</a> theo thoáº£ thuáº­n ÄÄng kÃ­ GNU General Public License.
+
+<p>Má»¥c tiÃªu cá»§a pháº§n má»m lÃ  cung cáº¥p cho ngÆ°á»i sá»­ dá»¥ng, Äáº·c biá»t lÃ  cÃ¡c trÆ°á»ng Äáº¡i há»c, cÃ¡c thÆ° viá»n hoáº·c trong cÃ¡c trá»¥ sá» cÃŽng cá»ng xÃ¢y dá»±ng cÃ¡c thÆ° viá»n sá» riÃªng cá»§a há». CÃ¡c thÆ° viá»n sá» lÃ m thay Äá»i nhanh chÃ³ng cÃ¡ch thá»©c thÃŽng tin ÄÆ°á»£c thu tháº­p vÃ  phá» biáº¿n trong cÃ¡c thÃ nh viÃªn cá»§a UNESCO vÃ  cÃ¡c cÆ¡ quan trong lÄ©nh vá»±c giÃ¡o dá»¥c, khoa há»c vÃ  vÄn hÃ³a trÃªn toÃ n tháº¿ giá»i, Äáº·c biá»t lÃ  á» cÃ¡c quá»c gia Äang phÃ¡t triá»n. ChÃºng tÃŽi hy vá»ng ráº±ng pháº§n má»m thÆ° viá»n sá» nÃ y sáºœ gia tÄng hiá»u quáº£ trong viá»c chia sáº» thÃŽng tin vÃ  cÃŽng bá» rá»ng rÃ£i chÃºng.
+
+
+<p>Pháº§n má»m nÃ y ÄÆ°á»£c phÃ¡t triá»n vÃ  phÃ¢n phá»i dÆ°á»i sá»± há»£p tÃ¡c hiá»u quáº£ giá»¯a ba ÄÆ¡n vá» vÃ o thÃ¡ng 8 nÄm 2000.
+
+<table border="0">
+<tr valign="top">
+<td>
+<a href="http://nzdl.org"><b>New Zealand Digital Library Project at the University of Waikato</b></a>
+<br>
+Pháº§n má»m Greenstone ÄÆ°á»£c má» rá»ng tá»« dá»± Ã¡n nÃ y vÃ  Ãœ tÆ°á»ng ban Äáº§u cá»§a dá»± Ã¡n ÄÆ°á»£c phÃ¡t triá»n bá»i Communication Sub-Commission cá»§a New Zealand National Commission cho UNESCO nhÆ° lÃ  má»t pháº§n ÄÃ³ng gÃ³p cá»§a New Zealand cho cÃ¡c chÆ°Æ¡ng trÃ¬nh cá»§a UNESCO.
+</td>
+<td></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://www.unesco.org"><b>United Nations Educational, Scientific and Cultural Organization</b></a>
+<br>
+Má»¥c tiÃªu chÃ­nh cá»§a UNESCO lÃ  quáº£ng bÃ¡ cÃ¡c thÃŽng tin vá» giÃ¡o dá»¥c, khoa há»c vÃ  vÄn hoÃ¡ trÃªn toÃ n tháº¿ giá»i, Äáº·c biá»t Äá»i cÃ¡c quá»c gia Äang phÃ¡t triá»n. Viá»c sá»­ dá»¥ng rá»ng rÃ£i cÃ¡c phÆ°Æ¡ng tiá»n thÃŽng tin liÃªn láº¡c ÄÆ°á»£c xem nhÆ° má»t cÃŽng cá»¥ quan trá»ng trong viá»c thá»±c thi má»¥c tiÃªu nÃ y
+</td>
+<td><a href="http://www.unesco.org"><img alt="UNESCO logo" src="_httpimg_/unesco.gif"
+border="0"></a></td>
+</tr>
+<tr valign="top">
+<td>
+<a href="http://humaninfo.org"><b>The Human Info NGO, based in Antwerp, Belgium</b></a>
+<br>
+Dá»± Ã¡n nÃ y há»£p tÃ¡c vá»i cÃ¡c cÆ¡ quan UN & NGOs. ÄÃ¢y lÃ  hai tá» chá»©c nÃ y ná»i tiáº¿ng trÃªn tháº¿ giá»i trong viá»c sá» hoÃ¡ vÃ  phá» biáº¿n cÃ¡c tÃ i liá»u liÃªn quan Äáº¿n sá»± phÃ¡t triá»n cá»§a nhÃ¢n loáº¡i. 
+</td>
+<td><a href="http://humaninfo.org"><img alt="Human Info logo" src="_httpimg_/ghproj2.jpg" border="0"></a></td>
+</tr>
+</table>
+}  
+
+
+_textdescrselcol_ [l=vi] {chá»n má»t bá» sÆ°u táº­p}
+
+
+######################################################################
+# home help page
+package homehelp
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_text4buts_ [l=vi] {CÃ³ bá»n nÃºt liÃªn káº¿t trÃªn trang chá»§}
+
+_textnocollections_ [l=vi] {<p>Hiá»n táº¡i khÃŽng cÃ³ bá» sÆ°u táº­p nÃ o dÃ¹ng ÄÆ°á»£c trÃªn báº£n cÃ i Äáº·t nÃ y. 
+Äá» thÃªm cÃ¡c bá» sÆ°u táº­p báº¡n pháº£i 
+<ul><li>Sá»­ dá»¥ng chá»©c nÄng <a href="_httppagecollector_">Táº¡o bá» sÆ°u táº­p</a> Äá» xÃ¢y dá»±ng má»i cÃ¡c bá» sÆ°u táº­p
+    <li>Náº¿u báº¡n cÃ³ má»t ÄÄ©a cd-rom Greenstone, ban cÃ³ thá» cÃ i Äáº·t cÃ¡c bá» sÆ°u táº­p tá»« cd-rom
+</ul>
+}
+
+_text1coll_ [l=vi] {Báº£n cÃ i Äáº·t nÃ y chá»©a 1 bá» sÆ°u táº­p}
+
+_textmorecolls_ [l=vi] {Báº£n cÃ i Äáº·t nÃ y chá»©a _1_  bá» sÆ°u táº­p}
+
+######################################################################
+# external link package
+package extlink
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textextlink_ [l=vi] {LiÃªn káº¿t bÃªn ngoÃ i}
+_textlinknotfound_ [l=vi] {LiÃªn káº¿t bÃªn trong khÃŽng tÃ¬m tháº¥y}  
+
+_textextlinkcontent_ [l=vi] {LiÃªn káº¿t báº¡n chá»n lÃ  bÃªn ngoÃ i Äá»i vá»i bá» sÆ°u táº­p hiá»n táº¡i cá»§a báº¡n.
+    Náº¿u báº¡n váº«n muá»n xem liÃªn káº¿t nÃ y vÃ  trÃ¬nh duyá»t cá»§a báº¡n pháº£i truy xuáº¥t ÄÆ°á»£c Äáº¿n Web, báº¡n cÃ³
+    thá» <a href="_nexturl_">Äi tiáº¿p</a>Äáº¿n trang nÃ y; náº¿u khÃŽng báº¡n hÃ£y sá»­ dá»¥ng nÃºt "back" trÃªn trÃ¬nh duyá»t cá»§a báº¡n Äá» trá» vá» tÃ i liá»u trÆ°á»c. 
+    }
+
+_textlinknotfoundcontent_ [l=vi] {Má»t sá» nguyÃªn nhÃ¢n vÆ°á»£t khá»i táº§m kiá»m soÃ¡t cá»§a chÃºng ta, liÃªn káº¿t bÃªn trong 
+   báº¡n chá»n khÃŽng tá»n tÃ i. Äiá»u nÃ y cÃ³ thá» do má»t lá»i trong source bá» sÆ°u táº­p.
+   Sá»­ dá»¥ng nÃºt "back" trÃªn trÃ¬nh duyá»t cá»§a báº¡n Äá» chá» láº¡i tÃ i liá»u trÆ°á»c.
+}
+
+# should have arguments of collection, collectionname and link
+_foundintcontent_ [l=vi] {<h3>LiÃªn káº¿t Äáº¿n bá» sÆ°u táº­p "_2_"</h3>
+
+<p>LiÃªn káº¿t báº¡n chá»n náº±m bÃªn ngoÃ i bá» sÆ°u táº­p "_collectionname_".
+    Náº¿u báº¡n muá»n xem liÃªn káº¿t nÃ y trong bá» sÆ°u táº­p "_collectionname_" báº¡n cÃ³ thá» <a href="_httpdoc_&c=_1_&cl=_cgiargcl_&d=_3_">Äi tiáº¿p</a>
+    Äáº¿n trang nÃ y; máº·t khÃ¡c sá»­ dá»¥ng nÃºt "back" trÃªn trÃ¬nh duyá»t cá»§a báº¡n Äá» trá» vá» tÃ i liá»u trÆ°á»c.
+</p>
+}  
+
+
+######################################################################
+# authentication page
+package authen
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textGSDLtitle_ [l=vi] {Pháº§n má»m thÆ° viá»n sá» Greenstone}
+
+_textusername_ [l=vi] {tÃªn ÄÄng nháº­p}
+_textpassword_ [l=vi] {máº­t kháº©u}
+
+_textmustbelongtogroup_ [l=vi] {ChÃº Ãœ ráº±ng báº¡n pháº£i thuá»c nhÃ³m quáº£n trá» má»i truy xuáº¥t ÄÆ°á»£c trang nÃ y.}
+
+_textmessageinvalid_ [l=vi] {NgÆ°á»i dÃ¹ng cáº§n ÄÄng nháº­p má»i cÃ³ thá» truy xuáº¥t ÄÆ°á»£c trang thÃŽng tin nÃ y.<br>
+_If_(_cgiargug_,[_textmustbelongtogroup_]<br>)
+Vui lÃ²ng nháº­p tÃªn ÄÄng nháº­p vÃ  máº­t kháº©u.}  
+
+_textmessagefailed_ [l=vi] {TÃªn ÄÄng nháº­p cá»§a báº¡n hoáº·c máº­t kháº©u bá» sai.}
+
+_textmessagedisabled_ [l=vi] {Xin lá»i, tÃ i khoáº£n cá»§a báº¡n ÄÃ£ bá» khoÃ¡. Vui lÃ²ng liÃªn há» vá»i ngÆ°á»i quáº£n trá».}
+
+_textmessagepermissiondenied_ [l=vi] {Xin lá»i, báº¡n khÃŽng cÃ³ quyá»n truy xuáº¥t trang nÃ y.}
+
+_textmessagestalekey_ [l=vi] {LiÃªn káº¿t nÃ y ÄÃ£ quÃ¡ cÅ©. Báº¡n vui lÃ²ng nháº­p máº­t kháº©u Äá» truy xuáº¥t trang nÃ y.}
+
+
+######################################################################
+# 'docs' page 
+package docs
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textnodocumentation_ [l=vi] {<p>Báº£n cÃ i Äáº·t nÃ y khÃŽng chá»©a báº¥t ká»³ má»t tÃ i liá»u hÆ°á»ng dáº«n nÃ o. Äiá»u nÃ y cÃ³ thá» do:
+<ol>
+ <li>Greenstone ÄÆ°á»£c cÃ i Äáº·t tá»« CD-ROM.
+ <li>Greenstone ÄÆ°á»£c cÃ i Äáº·t tá»« má»t Äiá»m phÃ¢n phá»i trÃªn máº¡ng Internet.
+</ol>
+Trong trÆ°á»ng há»£p nÃ y báº¡n cÃ³ thá» láº¥y tÃ i liá»u tá»« thÆ° má»¥c <i>docs</i> cá»§a ÄÄ©a CD-ROM Greenstone hoáº·c báº±ng cÃ¡ch truy cáº­p Äá»a chá»<a
+href="http://www.greenstone.org">http://www.greenstone.org</a>.
+}  
+
+_textuserguide_ [l=vi] {TÃ i liá»u hÆ°á»ng dáº«n sá»­ dá»¥ng}
+_textinstallerguide_ [l=vi] {TÃ i liá»u cÃ i Äáº·t pháº§n má»m}
+_textdeveloperguide_ [l=vi] {TÃ i liá»u cho ngÆ°á»i phÃ¡t triá»n bá» sÆ°u táº­p}
+_textpaperguide_ [l=vi] {Tá»« giáº¥y Äáº¿n bá» sÆ°u táº­p}
+_textorganizerguide_ [l=vi] {Sá»­ dá»¥ng chÆ°Æ¡ng trÃ¬nh Organizer}
+
+_textgsdocstitle_ [l=vi] {tÃ i liá»u greenstone}
+
+######################################################################
+# collectoraction
+package wizard
+
+_textbild_ [l=vi] {XÃ¢y dá»±ng bá» sÆ°u táº­p}  
+_textbildsuc_ [l=vi] {XÃ¢y dá»±ng bá» sÆ°u táº­p thÃ nh cÃŽng}  
+_textviewbildsummary_ [l=vi] {CÃ³ thá» <a href="_httppagex_(bsummary)" target=_top>xem báº£ng tÃ³m táº¯t quÃ¡ trÃ¬nh xÃ¢y dá»±ng</a> bá» sÆ°u táº­p nÃ y biáº¿t thÃªm chi tiáº¿t.}  
+_textview_ [l=vi] {Xem bá» sÆ°u táº­p}  
+
+_textbild1_ [l=vi] {Bá» sÆ°u táº­p Äang ÄÆ°á»£c xÃ¢y dá»±ng: máº¥t má»t khoáº£ng thá»i gian. DÃ²ng bÃªn dÆ°á»i cho biáº¿t thÃŽng tin vá» xÃ¢y dá»±ng bá» sÆ°u táº­p}  
+
+_textbild2_ [l=vi] {To stop the building process at any time, click here.
+<br>The collection you are working on will remain intact.}  
+
+_textstopbuild_ [l=vi] {ngá»«ng xÃ¢y dá»±ng}  
+
+_textbild3_ [l=vi] {Náº¿u ngÆ°á»i dÃ¹ng muá»n ngá»«ng trang nÃ y (vÃ  cÅ©ng cÃ³ thá» há»§y bá» tiáº¿n trÃ¬nh thÃ¬ nháº¥n vÃ o nÃºt: "ngá»«ng xÃ¢y dá»±ng") bá» sÆ°u táº­p sáºœ tiáº¿p tá»¥c xÃ¢y dá»±ng vÃ  cÃ i Äáº·t thÃ nh cÃŽng}  
+
+_textbuildcancelled_ [l=vi] {Há»§y bá» xÃ¢y dá»±ng}  
+
+_textbildcancel1_ [l=vi] {Tiáº¿n trÃ¬nh xÃ¢y dá»±ng bá» sÆ°u táº­p bá» há»§y bá». Sá»­ dá»¥ng nÃºt mÃ u vÃ ng bÃªn dÆ°á»i Äá» thay Äá»i bá» sÆ°u táº­p hoáº·c khá»i Äá»ng láº¡i tiáº¿n trÃ¬nh.}  
+
+_textbsupdate1_ [l=vi] {Cáº­p nháº­t tráº¡ng thÃ¡i xÃ¢y dá»±ng trong má»t giÃ¢y}  
+_textbsupdate2_ [l=vi] {Cáº­p nháº­t tráº¡ng thÃ¡i xÃ¢y dá»±ng trong}  
+_textseconds_ [l=vi] {áº¥n pháº©m}  
+
+_textfailmsg11_ [l=vi] {Bá» sÆ°u táº­p khÃŽng thá» xÃ¢y dá»±ng ÄÆ°á»£c vÃ¬ khÃŽng cÃ³ dá»¯ liá»u. HÃ£y cháº¯c ráº±ng tá»i thiá»u má»t trong sá» cÃ¡c thÆ° má»¥c hoáº·c táº­p tin ÄÆ°á»£c chá» Äá»nh trong trang dá»¯ liá»u nguá»n cÃ³ tá»n táº¡i (trong trÆ°á»ng há»£p thÆ° má»¥c thÃ¬ pháº£i cÃ³ chá»©a táº­p tin), Äá» Greenstone cÃ³ thá» tiáº¿n hÃ nh.}  
+
+_textfailmsg21_ [l=vi] {khÃŽng thá» táº¡o ÄÆ°á»£c bá» sÆ°u táº­p nÃ y (táº­p tin import.pl bá» há»ng.}  
+_textfailmsg31_ [l=vi] {KhÃŽng thá» táº¡o ÄÆ°á»£c bá» sÆ°u táº­p nÃ y (táº­p tin buildcol.pl bá» há»ng).}  
+_textfailmsg41_ [l=vi] {Bá» sÆ°u táº­p ÄÆ°á»£c xÃ¢y dá»±ng thÃ nh cÃŽng nhÆ°ng khÃŽng cho phÃ©p cÃ i Äáº·t}  
+_textfailmsg71_ [l=vi] {Lá»i xuáº¥t hiá»n trong khi xÃ¢y dá»±ng bá» sÆ°u táº­p}  
+
+
+_textblcont_ [l=vi] {xÃ¢y dá»±ng báº£n ghi bao gá»m thÃŽng tin bÃªn dÆ°á»i: }  
+
+######################################################################
+# collectoraction
+package collector
+######################################################################
+
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdefaultstructure_ [l=vi] {cáº¥u trÃºc máº·c Äá»nh}
+_textmore_ [l=vi] {nhiá»u hÆ¡n}
+_textinfo_ [l=vi] {ThÃŽng tin bá» sÆ°u táº­p}
+_textsrce_ [l=vi] {TÃ i liá»u nguá»n}
+_textconf_ [l=vi] {Cáº¥u hÃ¬nh bá» sÆ°u táº­p}
+_textdel_ [l=vi] {XoÃ¡ bá» sÆ°u táº­p}
+_textexpt_ [l=vi] {Xuáº¥t báº£n bá» sÆ°u táº­p}
+
+_textdownloadingfiles_ [l=vi] {Äang táº£i xuá»ng cÃ¡c táº­p tin ...}
+_textimportingcollection_ [l=vi] {Äang nháº­p bá» sÆ°u táº­p ...}
+_textbuildingcollection_ [l=vi] {Äang xÃ¢y dá»±ng bá» sÆ°u táº­p ...}
+_textcreatingcollection_ [l=vi] {Äang táº¡o bá» sÆ°u táº­p ...}
+
+_textcollectorblurb_ [l=vi] {<i>
+<br>Viá»c xÃ¢y dá»±ng vÃ  phÃ¢n phá»i bá» sÆ°u táº­p cÃ³ nhá»¯ng váº¥n Äá» mÃ  báº¡n cáº§n pháº£i náº¯m rÃµ trÆ°á»c khi tiáº¿n hÃ nh quÃ¡ trÃ¬nh tá»ng há»£p tÃ i liá»u. CÃ³ nhá»¯ng váº¥n Äá» phÃ¡p lÃ­: Báº¡n cÃ³ thá» truy cáº­p tÃ i liá»u nÃ y khÃŽng cÃ³ nghÄ©a lÃ  báº¡n cÃ³ thá» Äá» cho nhá»¯ng ngÆ°á»i khÃ¡c tá»± do xem tÃ i liá»u. CÃ³ nhá»¯ng váº¥n Äá» mang tÃ­nh xÃ£ há»i: CÃ¡c bá» sÆ°u táº­p pháº£i phÃ¹ há»£p vá»i thuáº§n phong má»¹ tá»¥c á» nÆ¡i phÃ¡t hÃ nh. CÃ³ nhá»¯ng váº¥n Äá» chá»§ng tá»c, nhá»¯ng thá»© ÄÆ¡n giáº£n lÃ  chÃºng ta khÃŽng thá» phÃ¡t hÃ nh rá»ng rÃ£i.
+<br>HÃ£y tháº­n trá»ng vá»i sá»©c máº¡nh cá»§a thÃŽng tin vÃ  sá»­ dá»¥ng chÃºng má»t cÃ¡ch ÄÃºng Äáº¯n
+</i>
+}
+
+_textcb1_ [l=vi] {Táº¡o bá» sÆ°u táº­p giÃºp báº¡n táº¡o má»i cÃ¡c bá» sÆ°u táº­p, thay Äá»i, thÃªm thÃŽng tin hoáº·c xÃ³a cÃ¡c bá» sÆ°u táº­p cÃ³ sáºµn. Äá» lÃ m ÄÆ°á»£c Äiá»u nÃ y báº¡n sáºœ ÄÆ°á»£c hÆ°á»ng dáº«n Äiá»n nhá»¯ng Äiá»n nhá»¯ng thÃŽng tin cáº§n thiáº¿t má»t cÃ¡ch tuáº§n tá»± vÃ o cÃ¡c trang Web yÃªu cáº§u.
+}
+
+_textcb2_ [l=vi] {Äáº§u tiÃªn báº¡n pháº£i chá»n má»t trong hai thao tÃ¡c sau}
+_textcnc_ [l=vi] {táº¡o má»i má»t bá» sÆ°u táº­p}
+_textwec_ [l=vi] {thÃªm dá»¯ liá»u vÃ o má»t bá» sÆ°u táº­p cÃ³ sáºµn hoáº·c xÃ³a bá» sÆ°u táº­p ÄÃ³.}
+
+_textcb3_ [l=vi] {Äá» xÃ¢y dá»±ng hoáº·c thay Äá»i cÃ¡c bá» sÆ°u táº­p thÆ° viá»n sá» báº¡n pháº£i ÄÄng nháº­p vÃ o há» thá»ng. Äiá»u nÃ y sáºœ báº£o vá» cÃ¡c thÃŽng tin cá»§a báº¡n khÃŽng bá» thay Äá»i bá»i nhá»¯ng ngÆ°á»i khÃ¡c sá»­ dá»¥ng mÃ¡y tÃ­nh cá»§a báº¡n. ChÃº Ãœ, vÃ¬ lÃœ do an ninh, báº¡n sáºœ bá» tá»± Äá»ng thoÃ¡t ra khá»i há» thá»ng 30 phÃºt sau khi ÄÃ£ ÄÄng nháº­p. Khi ÄÃ³, báº¡n Äá»«ng lo láº¯ng - báº¡n sáºœ ÄÆ°á»£c yÃªu cáº§u ÄÄng nháº­p láº¡i vÃ  tiáº¿p tá»¥c táº¡i vá» trÃ­ báº¡n ra khá»i há» thá»ng.
+}
+
+_textcb4_ [l=vi] {Vui lÃ²ng, nháº­p tÃªn ÄÄng nháº­p vÃ  máº­t kháº©u cá»§a báº¡n, sau ÄÃ³ nháº¥p chuá»t vÃ o nÃºt ÄÄng nháº­p.
+}
+
+_textfsc_ [l=vi] {Äáº§u tiÃªn báº¡n chá»n bá» sÆ°u táº­p mÃ  báº¡n muá»n lÃ m viá»c (cÃ¡c bá» sÆ°u táº­p khÃŽng ÄÆ°á»£c phÃ©p ghi sáºœ khÃŽng ÄÆ°á»£c liá»t kÃª á» ÄÃ¢y).
+}
+
+_textwtc_ [l=vi] {Vá»i bá» sÆ°u táº­p báº¡n ÄÃ£ chá»n, báº¡n cÃ³ thá»}
+_textamd_ [l=vi] {ThÃªm dá»¯ liá»u vÃ  xÃ¢y dá»±ng láº¡i bá» sÆ°u táº­p}
+_textetc_ [l=vi] {Chá»nh sá»­a táº­p tin cáº¥u hÃ¬nh cá»§a bá» sÆ°u táº­p vÃ  xÃ¢y dá»±ng láº¡i bá» sÆ°u táº­p}
+_textdtc_ [l=vi] {XoÃ¡ bá» sÆ°u táº­p}
+_textetcfcd_ [l=vi] {Xuáº¥t báº£n bá» sÆ°u táº­p ra CD-ROM}
+_textcaec_ [l=vi] {Chá»nh sá»­a bá» sÆ°u táº­p ÄÃ£ cÃ³}
+_textnwec_ [l=vi] {KhÃŽng tá»n táº¡i bá» sÆ°u táº­p cho phÃ©p chá»nh sá»­a}
+_textcianc_ [l=vi] {Táº¡o má»i má»t bá» sÆ°u táº­p}
+_texttsosn_ [l=vi] {Thá»© tá»± cÃ¡c bÆ°á»c cáº§n thiáº¿t Äá» táº¡o má»i bá» sÆ°u táº­p thÆ° viá»n sá» lÃ :}
+_textsin_ [l=vi] {XÃ¡c Äá»nh tÃªn cá»§a bá» sÆ°u táº­p (vÃ  thÃŽng tin liÃªn quan)}
+_textswts_ [l=vi] {XÃ¡c Äá»nh nÆ¡i láº¥y tÃ i liá»u nguá»n}
+_textatco_ [l=vi] {Chá»nh sá»­a cÃ¡c tÃ¹y chá»n cáº¥u hÃ¬nh (chá» dÃ nh cho ngÆ°á»i sá»­ dá»¥ng cáº¥p cao)}
+_textbtc_ [l=vi] {"XÃ¢y dá»±ng" bá» sÆ°u táº­p (xem pháº§n dÆ°á»i)}
+_textpvyh_ [l=vi] {Xem láº¡i cÃ¡c cÃŽng viá»c báº¡n ÄÃ£ lÃ m}
+
+_texttfsiw_ [l=vi] {BÆ°á»c thá»© tÆ° lÃ  bÆ°á»c mÃ  mÃ¡y tÃ­nh sáºœ lÃ m táº¥t cáº£ cÃ¡c cÃŽng viá»c. Trong quÃ¡ trÃ¬nh xÃ¢y dá»±ng mÃ¡y tÃ­nh táº¡o ra táº¥t cáº£ cÃ¡c chá» má»¥c vÃ  thu tháº­p cÃ¡c thÃŽng tin liÃªn quan. NhÆ°ng trÆ°á»c tiÃªn báº¡n pháº£i xÃ¡c Äá»nh thÃŽng tin.  
+}
+
+_textadab_ [l=vi] {Má»t sÆ¡ Äá» xuáº¥t hiá»n á» dÆ°á»i sáºœ giÃºp báº¡n nháº­n biáº¿t báº¡n Äang á» bÆ°á»c nÃ o. NÃºt mÃ u xanh lÃ¡ cÃ¢y lÃ  nÃºt mÃ  báº¡n nháº¥n vÃ o Äá» tiáº¿p tá»¥c. Khi báº¡n Äi theo tuáº§n tá»± cÃ¡c tráº¡ng thÃ¡i, cÃ¡c nÃºt sáºœ thay Äá»i sang mÃ u vÃ ng. Báº¡n cÃ³ thá» trá» vá» má»t trang trÆ°á»c ÄÃ³ báº±ng cÃ¡ch nháº¥n chuá»t vÃ o nÃºt mÃ u vÃ ng thÃ­ch há»£p trÃªn sÆ¡ Äá».
+}
+
+_textwyar_ [l=vi] {Khi báº¡n ÄÃ£ sáºµn sÃ ng, nháº¥n nÃºt mÃ u xanh lÃ¡ cÃ¢y âthÃŽng tin bá» sÆ°u táº­pâ Äá» báº¯t Äáº§u táº¡o bá» sÆ°u táº­p sá» má»i.
+}
+
+_textcnmbs_ [l=vi] {TÃªn bá» sÆ°u táº­p pháº£i ÄÆ°á»£c xÃ¡c Äá»nh}
+_texteambs_ [l=vi] {Äá»a chá» Email pháº£i ÄÆ°á»£c xÃ¡c Äá»nh}
+_textpsea_ [l=vi] {XÃ¡c Äá»nh Äá»a chá» emai theo máº«u: username@domain}
+_textdocmbs_ [l=vi] {MÃŽ táº£ vá» bá» sÆ°u táº­p pháº£i ÄÆ°á»£c xÃ¡c Äá»nh}
+
+_textwcanc_ [l=vi] {Khi táº¡o má»i má»t bá» sÆ°u táº­p báº¡n cáº§n nháº­p má»t sá» thÃŽng tin sÆ¡ bá» vá» tÃ i liá»u nguá»n. QuÃ¡ trÃ¬nh xÃ¢y dá»±ng ÄÆ°á»£c cáº¥u trÃºc nhÆ° lÃ  má»t loáº¡t cÃ¡c trang web ÄÆ°á»£c giÃ¡m sÃ¡t bá»i chá»©c nÄng XÃ¢y dá»±ng bá» sÆ°u táº­p.
+}
+
+_texttfc_ [l=vi] {TÃªn bá» sÆ°u táº­p:}
+
+_texttctiasp_ [l=vi] {TiÃªu Äá» cá»§a bá» sÆ°u táº­p lÃ  má»t nhÃ³m tá»« ngáº¯n ÄÆ°á»£c sá»­ dá»¥ng trong chÆ°Æ¡ng trÃ¬nh nháº±m xÃ¡c Äá»nh ná»i dung cá»§a bá» sÆ°u táº­p. VÃ­ dá»¥ cÃ¡c tiÃªu Äá» sau: âComputer Science Technical Reportsâ vÃ  "Humanity Development Library".
+}
+
+_textcea_ [l=vi] {Äá»a chá» email liÃªn há»:}
+
+_textteas_ [l=vi] {Äá»a chá» email nÃ y lÃ  Äiáº¡ chá» liÃªn há» cá»§a bá» sÆ°u táº­p. Khi bá» sÆ°u táº­p gáº·p trá»¥c tráº·c, má»t bÃ¡o cÃ¡o cháº©n ÄoÃ¡n sáºœ ÄÆ°á»£c gá»­i tá»i Äá»a chá» nÃ y. Nháº­p má»t Äá»a chá» email theo máº«u Äáº§y Äá»§: <tt>name@domain</tt>.
+}
+
+_textatc_ [l=vi] {Giá»i thiá»u vá» bá» sÆ°u táº­p:}
+
+_texttiasd_ [l=vi] {ÄÃ¢y lÃ  má»t cÃ¢u diá»
+n táº£ cÃ¡c nguyÃªn táº¯c bao trÃ¹m bá» sÆ°u táº­p. NÃ³ sáºœ xuáº¥t hiá»n trÃªn trang Äáº§u khi bá» sÆ°u táº­p ÄÆ°á»£c trÃ¬nh bÃ y.
+}
+
+_textypits_ [l=vi] {Vá» trÃ­ cá»§a báº¡n theo thá»© tá»± ÄÆ°á»£c chá» ra bá»i má»t mÅ©i tÃªn á» dÆ°á»i - trong trÆ°á»ng há»£p nÃ y lÃ  tráº¡ng thÃ¡i âThÃŽng tin bá» sÆ°u táº­pâ. Äá» tiáº¿p tá»¥c, nháº¥n chuá»t vÃ o nÃºt mÃ u xanh lÃ¡ cÃ¢y âTÃ i liá»u nguá»nâ. 
+}
+
+_srcebadsources_ [l=vi] {<p>CÃ³ má»t hoáº·c nhiá»u tÃ i liá»u nguá»n báº¡n xÃ¡c Äá»nh lÃ  khÃŽng há»£p lá» (ÄÃ¡nh dáº¥u
+_iconcross_ á» dÆ°á»i).
+
+<p>Äiá»u nÃ y cÃ³ thá» lÃ  do
+<ul>
+<li>Táº­p tin, vá» trÃ­ FTP hoáº·c URL khÃŽng tá»n táº¡i.
+<li>Báº¡n cáº§n pháº£i káº¿t ná»i vÃ o máº¡ng Internet trÆ°á»c
+<li>Báº¡n Äang cá» truy xuáº¥t tá»« bÃªn trong má»t firewall (Äiá»u nÃ y xáº£y ra khi báº¡n thÆ°á»ng pháº£i cung cáº¥p tÃªn ÄÄng nháº­p vÃ  máº­t kháº©u Äá» truy cáº­p Interner).
+</ul>
+
+<p>Náº¿u trang Äá»a chá» URL nÃ y cÃ³ thá» nhÃ¬n tháº¥y tá»« trÃ¬nh duyá»t cá»§a báº¡n, nÃ³ cÃ³ thá» lÃ  má»t báº£n sao ÄÆ°á»£c lÆ°u trong mÃ¡y cá»¥c bá». Tháº­t ÄÃ¡ng tiáº¿c, cÃ¡c báº£n sao nÃ y thÃ¬ láº¡i hoÃ n toÃ n há»£p lá» Äá»i vá»i cÃ¡c quÃ¡ trÃ¬nh xá»­ lÃœ cá»§a chÃºng tÃŽi. Trong trÆ°á»ng há»£p nÃ y chÃºng tÃŽi khuyÃªn báº¡n táº£i xuá»ng láº¡i cÃ¡c trang Äang sá»­ dá»¥ng bá»i trÃ¬nh duyá»t cá»§a báº¡n trÆ°á»c.
+}
+
+_textymbyco_ [l=vi] {<p>Báº¡n chá»n má»t trong hai cáº¥u trÃºc sau Äá» xÃ¢y dá»±ng bá» sÆ°u táº­p cá»§a mÃ¬nh.
+<ul>
+<li>Cáº¥u trÃºc máº·c Äá»nh
+<dl><dd>Bá» sÆ°u táº­p má»i pháº£i chá»©a tÃ i liá»u dáº¡ng hmtl (.htm, .html), tÃ i liá»u dáº¡ng vÄn báº£n (.txt, .text), tÃ i liá»u dáº¡ng Word (.doc), tÃ i liá»u dáº¡ng PDF (.pdf) hoáº·c tÃ i liá»u dáº¡ng email (.mbx).</dd></dl>
+<li>Má»t bá» sÆ°u táº­p ÄÃ£ cÃ³ sáºµn
+<dl><dd>CÃ¡c táº­p tin trong bá» sÆ°u táº­p má»i cá»§a báº¡n pháº£i cÃ³ kiá»u giá»ng vá»i nhá»¯ng táº­p tin ÄÆ°á»£c dÃ¹ng Äá» xÃ¢y dá»±ng bá» sÆ°u táº­p ÄÃ£ cÃ³.</dd></dl>
+</ul>
+}
+
+_textbtco_ [l=vi] {XÃ¢y dá»±ng bá» sÆ°u táº­p trÃªn}
+_textand_ [l=vi] {ThÃªm má»i dá»¯ liá»u}
+_textad_ [l=vi] {Äang thÃªm dá»¯ liá»u:}
+
+_texttftysb_ [l=vi] {CÃ¡c táº­p tin mÃ  báº¡n xÃ¡c Äá»nh á» dÆ°á»i sáºœ ÄÆ°á»£c thÃªm vÃ o bá» sÆ°u táº­p. HÃ£y kiá»m tra xem báº¡n cÃ³ Äang thÃªm vÃ o má»t táº­p tin sáºµn cÃ³ trong bá» sÆ°u táº­p khÃŽng, náº¿u trÆ°á»ng há»£p ÄÃ³ xáº£y ra, cáº£ 3 táº­p tin sáºœ Äá»u náº±m trong bá» sÆ°u táº­p. CÃ¡c táº­p tin ÄÆ°á»£c xÃ¡c Äá»nh thÃŽng qua ÄÆ°á»ng dáº«n Äáº§y Äá»§, cÃ¡c trang Web ÄÆ°á»£c xÃ¡c Äá»nh thÃŽng qua Äá»a chá» Web.
+}
+
+_textis_ [l=vi] {TÃ i liá»u nguá»n:}
+
+_textddd1_ [l=vi] {<p>Náº¿u báº¡n sá»­ dá»¥ng file:// hoáº·c ftp:// Äá» xÃ¡c Äá»nh má»t táº­p tin, thÃ¬ táº­p tin ÄÃ³ sáºœ ÄÆ°á»£c láº¥y vá».
+
+<p>Náº¿u báº¡n sá»­ dá»¥ng http:// thÃ¬ tÃ¹y theo URL báº¡n sáºœ nháº­n má»t trang hoáº·c nhiá»u trang web. Khi má»t trang ÄÆ°á»£c láº¥y vá» thÃ¬ táº¥t cáº£ cÃ¡c trang mÃ  liÃªn káº¿t trá»±c tiáº¿p hoáº·c giÃ¡n tiáº¿p vá»i nÃ³ cÅ©ng ÄÆ°á»£c láº¥y xuá»ng. 
+
+<p>Khi báº¡n sá»­ dá»¥ng file:// hoáº·c ftp:// Äá» xÃ¡c Äá»nh má»t thÆ° má»¥c, hoáº·c cung cáº¥p má»t http:// URL mÃ  chá» Äáº¿n má»t danh sÃ¡ch cÃ¡c táº­p tin, thÃ¬ má»i thá»© trong thÆ° má»¥c vÃ  táº¥t cáº£ cÃ¡c thÆ° má»¥c con cá»§a nÃ³ sáºœ ÄÆ°á»£c ÄÆ°a vÃ o bá» sÆ°u táº­p. 
+
+<p>Nháº¥n chuá»t vÃ o nÃºt âThÃªm tÃ i liá»uâ Äá» cÃ³ nhiá»u há»p nháº­p liá»u hÆ¡n.
+}
+
+_textddd2_ [l=vi] {<p>Nháº¥n chuá»t má»t láº§n vÃ o cÃ¡c nÃºt mÃ u xanh lÃ¡ cÃ¢y. Náº¿u báº¡n lÃ  ngÆ°á»i sá»­ dá»¥ng cáº¥p cao báº¡n cÃ³ thá» chá»nh sá»­a cáº¥u hÃ¬nh cá»§a bá» sÆ°u táº­p. NgÆ°á»£c láº¡i, báº¡n Äáº¿n bÆ°á»c xÃ¢y dá»±ng bá» sÆ°u táº­p. Báº¡n cÃ³ thá» quay láº¡i cÃ¡c bÆ°á»c trÆ°á»c ÄÃ³ báº±ng cÃ¡ch nháº¥n chuá»t vÃ o nÃºt mÃ u vÃ ng.
+}
+
+_textconf1_ [l=vi] {<p>Viá»c xÃ¢y dá»±ng vÃ  trÃ¬nh bÃ y bá» sÆ°u táº­p cá»§a báº¡n ÄÆ°á»£c Äiá»u khiá»n báº±ng cÃ¡c xÃ¡c láº­p trong má»t táº­p tin cáº¥u hÃ¬nh Äáº·c biá»t. NgÆ°á»i sá»­ dá»¥ng cáº¥p cao cÃ³ thá» thay Äá»i cÃ¡c xÃ¡c láº­p ÄÃ³.
+
+<center><p><b>Náº¿u khÃŽng, báº¡n cÃ³ thá» di chuyá»n xuá»ng cuá»i trang.</b></center> 
+
+<p>Äá» thay tháº¿ cÃ¡c xÃ¡c láº­p cáº¥u hÃ¬nh cÃ³ sáºµn, báº¡n hÃ£y thay tháº¿ dá»¯ liá»u xuáº¥t hiá»n á» dÆ°á»i. Khi bá» sai, báº¡n nháº¥n chuá»t vÃ o âLÃ m láº¡iâ Äá» láº¥y láº¡i cÃ¡c xÃ¡c láº­p ban Äáº§u.
+}
+
+_textreset_ [l=vi] {LÃ m láº¡i}
+
+
+_texttryagain_ [l=vi] {<a href="_httppagecollector_" target=_top>khá»i Äá»ng láº¡i chá»©c nÄng xÃ¢y dá»±ng bá» sÆ°u táº­p</a>
+ vÃ  thá»­ láº¡i.
+}  
+
+
+_textretcoll_ [l=vi] {Quay láº¡i Táº¡o bá» sÆ°u táº­p}
+
+_textdelperm_ [l=vi] {Má»t sá» hoáº·c táº¥t cáº£ _cgiargbc1dirname_ bá» sÆ°u táº­p khÃŽng thá» ÄÆ°á»£c xoÃ¡. NguyÃªn nhÃ¢n cÃ³ thá» lÃ :
+<ul>
+<li> Greenstone khÃŽng cÃ³ quyá»n xoÃ¡ thÆ° má»¥c _gsdlhome_/collect/_cgiargbc1dirname_ .
+<br>
+Báº¡n cáº§n tá»± tay xoÃ¡ bá» thÆ° má»¥c nÃ y Äá» hoÃ n táº¥t viá»c xoÃ¡ bá» sÆ°u táº­p _cgiargbc1dirname_
+.</li>
+<li>Greenstone khÃŽng thá» cháº¡y chÆ°Æ¡ng trÃ¬nh _gsdlhome_/bin/script/delcol.pl. Báº¡n pháº£i báº£o Äáº£m táº­p tin nÃ y cÃ³ thá» Äá»c vÃ  thá»±c thi.</li>
+</ul>
+}
+
+_textdelinv_ [l=vi] {Bá» sÆ°u táº­p _cgiargbc1dirname_ ÄÆ°á»£c báº£o vá» hoáº·c khÃŽng há»£p lá». QuÃ¡ trÃ¬nh xoÃ¡ ÄÆ°á»£c huá»· bá».
+}
+
+_textdelsuc_ [l=vi] {Bá» sÆ°u táº­p _cgiargbc1dirname_ ÄÆ°á»£c xoÃ¡ thÃ nh cÃŽng.}
+
+_textclonefail_ [l=vi] {Bá» sÆ°u táº­p _cgiargclonecol_ khÃŽng thá» sao chÃ©p. NguyÃªn nhÃ¢n cÃ³ thá» lÃ :
+<ul>
+<li> Bá» sÆ°u táº­p _cgiargclonecol_ khÃŽng tá»n tÃ i
+<li> Bá» sÆ°u táº­p _cgiargclonecol_ khÃŽng cÃ³ táº­p tin cáº¥u hÃ¬nh collect.cfg
+<li> Greenstone khÃŽng cÃ³ quyá»n Äá»c táº­p tin cáº¥u hÃ¬nh collect.cfg
+</ul>
+}
+
+_textcolerr_ [l=vi] {XÃ¢y dá»±ng bá» sÆ°u táº­p bá» lá»i.}
+
+_texttmpfail_ [l=vi] {XÃ¢y dá»±ng bá» sÆ°u táº­p khÃŽng thá» Äá»c hoáº·c ghi tá»« táº­p tin hoáº·c thÆ° má»¥c táº¡m thá»i. NguyÃªn nhÃ¢n cÃ³ thá» lÃ :
+<ul>
+<li> Greenstone khÃŽng thá» Äá»c hoáº·c ghi trÃªn thÆ° má»¥c _gsdlhome_/tmp.
+</ul>
+}
+
+_textmkcolfail_ [l=vi] {XÃ¢y dá»±ng bá» sÆ°u táº­p khÃŽng thá» táº¡o cáº¥u trÃºc thÆ° má»¥c theo yÃªu cáº§u cá»§a bá» sÆ°u táº­p má»i (mkcol.pl tháº¥t báº¡i). NguyÃªn nhÃ¢n cÃ³ thá» lÃ :
+<ul>
+<li> Greenstone khÃŽng cÃ³ quyá»n ghi trÃªn thÆ° má»¥c _gsdlhome_/tmp.
+<li> mkcol.pl perl script cÃ³ lá»i.
+</ul>
+}
+
+_textnocontent_ [l=vi] {Bá» sÆ°u táº­p bá» lá»i: báº¡n khÃŽng cung cáº¥p tÃªn cho bá» sÆ°u táº­p má»i. HÃ£y khá»i Äá»ng láº¡i quÃ¡ trÃ¬nh xÃ¢y dá»±ng bá» sÆ°u táº­p tá»« Äáº§u.
+}
+
+_textrestart_ [l=vi] {Báº¯t Äáº§u táº¡o bá» sÆ°u táº­p}
+
+_textreloaderror_ [l=vi] {Má»t lá»i xáº£y ra trong khi táº¡o má»t bá» sÆ°u táº­p má»i. Äiá»u nÃ y xáº£y ra Greenstone khÃŽng phÃ¢n biá»t ÄÆ°á»£c nÃºt "reload" hoáº·c nÃºt "back" trÃªn trÃ¬nh duyá»t cá»§a báº¡n (báº¡n nÃªn trÃ¡nh sá»­ dá»¥ng nhá»¯ng nÃºt nÃ y trong khi táº¡o bá» sÆ°u táº­p). Báº¡n nÃªn báº¯t Äáº§u láº¡i quÃ¡ trÃ¬nh xÃ¢y dá»±ng bá» sÆ°u táº­p.
+}
+
+_textexptsuc_ [l=vi] {Bá» sÆ°u táº­p _cgiargbc1dirname_ export thÃ nh cÃŽng Äáº¿n thÆ° má»¥c _gsdlhome_/tmp/exported\__cgiargbc1dirname_.
+}
+
+_textexptfail_ [l=vi] {<p>Export tháº¥t báº¡i bá» sÆ°u táº­p _cgiargbc1dirname_.
+
+<p>Äiá»u nÃ y hÃ¬nh nhÆ° lÃ  do Greenstone ÄÆ°á»£c cÃ i Äáº·t mÃ  khÃŽng cÃ³ cÃ¡c thÃ nh pháº§n cáº§n thiáº¿t Äá» há» trá»£ chá»©c nÄng  "Truy xuáº¥t Collection".
+<ul>
+
+ <li>Khi báº¡n cÃ i Äáº·t Greenstone tá»« CD-ROM cÃ¡c thÃ nh pháº§n nÃ y sáºœ khÃŽng ÄÆ°á»£c ÄÆ°á»£c cÃ i Äáº·t máº·c nhiÃªn báº¡n pháº£i chá»n chÃºng trong má»¥c "Custom". Báº¡n cÃ³ thá» thÃªm chÃºng trong báº£n cÃ i Äáº·t cá»§a báº¡n báº±ng cÃ¡ch cháº¡y láº¡i thá»§ tá»¥c cÃ i Äáº·t.
+
+ <li>Khi báº¡n cÃ i Äáº·t Greenstone tá»« má»t Äiá»m phÃ¢n phá»i trÃªn Internet báº¡n cáº§n táº£i xuá»ng vÃ  cÃ i Äáº·t thÃªm cÃ¡c gÃ³i cho phÃ©p sá»­ dá»¥ng chá»©c nÄng nÃ y. LiÃªn há» trang web nÃ y <a href="http://www.greenstone.org">http://www.greenstone.org</a> hoáº·c Äá»a chá» email <a
+ href="mailto:greenstone@cs.waikato.ac.nz">greenstone@cs.waikato.ac.nz</a> Äá» biáº¿t thÃªm chi tiáº¿t.
+
+</ul>
+}
+
+######################################################################
+# depositoraction
+package depositor
+######################################################################
+
+
+_textdepositorblurb_ [l=vi] {<p> chá» Äá»nh  thÃŽng tin cá»§a nhá»¯ng táº­p tin dÆ°á»i ÄÃ¢y vÃ  nháº¥n vÃ o textintro bÃªn dÆ°á»i.</p>}  
+
+_textcaec_ [l=vi] {ThÃªm vÃ o bá» sÆ°u táº­p ÄÃ£ cÃ³}  
+_textbild_ [l=vi] {Má»¥c truyá»n dá»¯ liá»u}  
+_textintro_ [l=vi] {Chá»n táº­p tin}  
+_textselect_ [l=vi] {Chá»n bá» sÆ°u táº­p}  
+_textmeta_ [l=vi] {Chá» Äinh Metadata}  
+
+_texttryagain_ [l=vi] {<a href="_httppagedepositor_" target=_top>khá»i Äá»ng láº¡i há» thá»ng truyá»n dá»¯ liá»u </a> vÃ  thá»­ láº¡i láº§n ná»¯a}  
+
+
+_textretcoll_ [l=vi] {Quay láº¡i há» thá»ng truyá»n dá»¯ liá»u}  
+
+_texttmpfail_ [l=vi] {Há» thá»ng truyá»n dá»¯ liá»u bá» lá»i khi Äá»c hoáº·c ghi lÃªn má»t táº­p tin hoáº·c thÆ° má»¥c táº¡m. CÃ¡c nguyÃªn nhÃ¢n cÃ³ thá» xáº£y ra:
+<ul>
+<li> Greenstone khÃŽng cáº¥p quyá»n Äá»c/ghi cho thÆ° má»¥c _gsdlhome_/tmp.
+</ul>
+}  
+
+
+######################################################################
+# 'gsdl' page
+package gsdl
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textgreenstone1_ [l=vi] {Greenstone lÃ  má»t bá» pháº§n má»m dÃ¹ng Äá» xÃ¢y dá»±ng vÃ  phÃ¢n phá»i cÃ¡c bá» sÆ°u táº­p tÃ i liá»u sá». NÃ³ cung cáº¥p má»t phÆ°Æ¡ng phÃ¡p má»i Äá» tá» chá»©c vÃ  xuáº¥t báº£n thÃŽng tin trÃªn Internet hoáº·c trÃªn CD-ROM. Greenstone lÃ  sáº£n pháº©m cá»§a dá»± Ã¡n ThÆ° viá»n sá» New Zealand cá»§a trÆ°á»ng Äáº¡i há»c Waikato, ÄÆ°á»£c phÃ¡t triá»n vÃ   phÃ¢n phá»i vá»i sá»± tham gia cá»§a UNESCO vÃ  Human Info NGO. ÄÃ¢y lÃ  pháº§n má»m mÃ£ nguá»n má» ÄÆ°á»£c cung cáº¥p trÃªn <i>http://greenstone.org</i> theo thoáº£ thuáº­n cá»§a GNU General Public License.
+}  
+
+_textgreenstone2_ [l=vi] {Äá»a chá» trang web cá»§a New Zealand Digital Library (http://nzdl.org) chá»©a nhiá»u bá» sÆ°u táº­p máº«u, táº¥t cáº£ chÃºng ÄÆ°á»£c táº¡o vá»i pháº§n má»m Greenstone. CÃ¡c bá» sÆ°u táº­p nÃ y ÄÆ°á»£c cÃŽng bá» rá»ng rÃ£i cho báº¡n nghiÃªn cá»©u. Táº¥t cáº£ chÃºng ÄÆ°á»£c minh hoáº¡ báº±ng nhiá»u vÃ­ dá»¥ khÃ¡c nhau vá» cÃ¡ch tÃ¬m kiáº¿m vÃ  hiá»n thá» cÃ¡c tÃ¹y chá»n. Trang web nÃ y chá»©a Äá»±ng nhiá»u bá» sÆ°u táº­p báº±ng tiáº¿ng Arabic, Chinese, French, Maori vÃ  Spanish cÅ©ng nhÆ° tiáº¿ng English. NgoÃ i ra cÃ²n cÃ³ cÃ¡c bá» sÆ°u táº­p vá» Ã¢m nháº¡c.}  
+
+_textplatformtitle_ [l=vi] {cáº¥u hÃ¬nh ná»n}
+_textgreenstone3_ [l=vi] {Greenstone tÆ°Æ¡ng thÃ­ch vá»i há» Äiá»u hÃ nh Windows, Unix vÃ  Mac OS X. Viá»c phÃ¢n phá»i bao gá»m cÃ¡c báº£n cÃ i Äáº·t cho táº¥t cáº£ cÃ¡c phiÃªn báº£n cá»§a Windows, Linux vÃ  Mac OS X. NÃ³ cÅ©ng cung cáº¥p toÃ n bá» source code cá»§a há» thá»ng Äá» ngÆ°á»i sá»­ dá»¥ng cÃ³ thá» biÃªn dá»ch láº¡i báº±ng Microsoft C++ hoáº·c gcc. Pháº§n má»m Äi kÃšm vá»i Greenstone cÅ©ng Äá»u miá»
+n phÃ­, vÃ­ dá»¥ nhÆ° Apache Webserver vÃ  PERL. NgÆ°á»i sá»­ dá»¥ng cÃ³ thá» dÃ¹ng cÃ¡c trÃ¬nh duyá»t Web Äiá»n hÃ¬nh lÃ  Netscape Navigator hoáº·c Internet Explorer.
+}  
+
+_textgreenstone4_ [l=vi] {CÃ³ nhiá»u ÄÄ©a CD_ROM chá»©a sáºµn cÃ¡c bá» sÆ°u táº­p tÃ i liá»u Äá» phá»¥c vá»¥ cho pháº§n má»m Greenstone. VÃ­ dá»¥,  <i>Humanity Development</i> chá»©a 1.230 tÃ i liá»u tá»« káº¿ toÃ¡n tÃ i chÃ­nh cho Äáº¿n váº¥n Äá» an toÃ n nguá»n nÆ°á»c. NÃ³ cháº¡y trÃªn cÃ¡c mÃ¡y tÃ­nh cáº¥u hÃ¬nh tháº¥p cháº³ng háº¡n nhÆ° nhá»¯ng cÃ¡i thÆ°á»ng dÃ¹ng á» cÃ¡c nÆ°á»c Äang phÃ¡t triá»n. ThÃŽng tin cÃ³ thá» ÄÆ°á»£c truy xuáº¥t báº±ng cÃ¡ch tÃ¬m kiáº¿m, trÃ¬nh duyá»t dá»±a trÃªn chá»§ Äá», tÃªn tiÃªu Äá», tÃªn tá» chá»©c xuáº¥t báº£n, danh sÃ¡ch cÃ¡c gá»£i Ãœ hoáº·c xem bÃ¬a sÃ¡ch má»t cÃ¡ch tÃ¹y Ãœ.
+}  
+
+_textcustomisationtitle_ [l=vi] {tÃ¹y chá»nh}
+_textgreenstone5_ [l=vi] {Greenstone ÄÆ°á»£c thiáº¿t káº¿ Äá» dá»
+ nÃ¢ng cáº¥p vÃ  chá»nh sá»­a. CÃ¡c Äá»nh dáº¡ng má»i cá»§a má»t tÃ i liá»u vÃ  metadata ÄÆ°á»£c cung cáº¥p báº±ng cÃ¡ch viáº¿t âpluginsâ (trong Perl). TÆ°Æ¡ng tá»±, viá»c duyá»t cáº¥u trÃºc cá»§a metadata cÃ³ thá» thá»±c hiá»n báº±ng cÃ¡ch viáº¿t âclassifiersâ. Giao diá»n ngÆ°á»i sá»­ dá»¥ng cÃ³ thá» ÄÆ°á»£c thay tháº¿ báº±ng cÃ¡ch viáº¿t cÃ¡c âmacrosâ. Giao thá»©c Corba cho phÃ©p cÃ¡c chÆ°Æ¡ng trÃ¬nh thÃŽng minh (vÃ­ dá»¥ trong Java) sá»­ dá»¥ng táº¥t cáº£ cÃ¡c tiá»n Ã­ch Äi kÃšm vá»i bá» sÆ°u táº­p. Cuá»i cÃ¹ng, source code báº±ng C++ vÃ  Perl ÄÆ°á»£c cung cáº¥p miá»
+n phÃ­ vÃ  cho phÃ©p sá»­a Äá»i.
+}  
+
+_textdocumentationtitle_ [l=vi] {tÃ i liá»u}
+_textdocuments_ [l=vi] {TÃ i liá»u viáº¿t thÃªm cho pháº§n má»m Greenstone thÃ¬ khÃ¡ phá» biáº¿n.}  
+
+#_textthreedocs_ {There are three documents that explain the Greenstone system:}
+#_textinstall_ {The Greenstone Digital Library Software Installer's Guide}
+#_textuser_ {The Greenstone Digital Library Software User's Guide}
+#_textdevelop_ {The Greenstone Digital Library Software Developer's Guide}
+
+_textmailinglisttitle_ [l=vi] {danh sÃ¡ch Äá»a chá» mail}
+_textmailinglist_ [l=vi] {CÃ³ má»t danh sÃ¡ch nhá»¯ng Äá»a chá» nháº­n thÃŽng tin thÆ°á»ng xuyÃªn mÃ  má»¥c ÄÃ­ch chÃ­nh lÃ  Äá» tháº£o luáº­n vá» pháº§n má»m thÆ° viá»n sá» Greenstone. Nhá»¯ng ngÆ°á»i sá»­ dá»¥ng cá»§a Greenstone cÃ³ thá» ÄÄng kÃœ vÃ o danh sÃ¡ch nÃ y vÃ  tham gia vÃ o cÃ¡c buá»i tháº£o luáº­n.
+Äá» ÄÄng kÃœ, truy cáº­p Äá»a chá» <a href="https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users">https://list.scms.waikato.ac.nz/mailman/listinfo/greenstone-users</a>.Äá» gá»­i thÃŽng tin Äáº¿n nhÃ³m,  sá»­ dá»¥ng Äá»a chá» nÃ y greenstone-users@list.scms.waikato.ac.nz
+>greenstone-users@list.scms.waikato.ac.nz</a>.
+}  
+
+_textbugstitle_ [l=vi] {lá»i}
+_textreport_ [l=vi] {ChÃºng tÃŽi muá»n báº£o Äáº£m ráº±ng pháº§n má»m nÃ y lÃ m viá»c tá»t. Báº¡n vui lÃ²ng thÃŽng bÃ¡o cÃ¡c lá»i Äáº¿n <a href="mailto:greenstone-users@list.scms.waikato.ac.nz"
+>greenstone-users@list.scms.waikato.ac.nz</a>. 
+}
+
+_textgs3title_ [l=vi] {cÃŽng viá»c}
+_textgs3_ [l=vi] {Greenstone 3 lÃ  má»t phiÃªn báº£n ÄÆ°á»£c thiáº¿t káº¿ vÃ  cÃ i Äáº·t láº¡i, chá»©a táº¥t cáº£ cÃ¡c tÃ­nh nÄng tiÃªn tiáº¿n cá»§a Greenstone 2 (phiÃªn báº£n hiá»n táº¡i). NÃ³ káº¿t há»£p táº¥t cáº£ cÃ¡c Äáº·c Äiá»m cá»§a há» thá»ng ÄÃ£ tá»n táº¡i vÃ  tÆ°Æ¡ng thÃ­ch vá»i táº¥t cáº£ cÃ¡c há» thá»ng trÆ°á»c: cÃ³ thá» xÃ¢y dá»±ng vÃ  cháº¡y trÃªn cÃ¡c bá» sÆ°u táº­p ÄÃ£ cÃ³ mÃ  khÃŽng pháº£i chá»nh sá»­a. Greenstone 3 ÄÆ°á»£c viáº¿t báº±ng Java vÃ  ÄÆ°á»£c xÃ¢y dá»±ng nhÆ° má»t thÃ nh pháº§n máº¡ng Äá»c láº­p sá»­ dá»¥ng XML Äá» truyá»n thÃŽng. Nhá»¯ng tÃ­nh nÄng nÃ y giÃºp Greenstone phÃ¡t triá»n tÃ­nh kháº£ chuyá»n vÃ  má» rá»ng. PhiÃªn báº£n má»i ÄÆ°á»£c ÄÆ°a vÃ o sá»­ dá»¥ng thá»±c táº¿ vÃ o ngÃ y 23 thÃ¡ng 12 nÄm 2003. Ã tÆ°á»ng thiáº¿t káº¿ ban Äáº§u cá»§a há» thá»ng ÄÆ°á»£c phÃ¡c tháº£o trÃªn "The design of Greenstone 3: An agent based dynamic digital library"(<a href="http://www.greenstone.org/manuals/gs3design.pdf">PDF</a>). 
+}  
+
+_textcreditstitle_ [l=vi] {Danh sÃ¡ch tÃ¡c giáº£
+}  
+
+_textwhoswho_ [l=vi] {Pháº§n má»m Greenstone lÃ  káº¿t quáº£ ná» lá»±c cá»§a nhiá»u ngÆ°á»i. Rodger McNab vÃ  Stefan Boddie lÃ  nhá»¯ng kiáº¿n trÃºc sÆ° vÃ  ngÆ°á»i thá»±c hiá»n chÃ­nh. Nhá»¯ng ngÆ°á»i cá»ng tÃ¡c thá»±c hiá»n bao gá»m: David Bainbridge, George Buchanan, Michael Dewsnip, Katherine Don, Hong Chen, Elke Duncker, Carl Gutwin, Geoff Holmes, John McPherson, Craig Nevill-Manning, Dynal Patel, Gordon Paynter, Bernhard Pfahringer, Todd Reed, Bill Rogers, John Thompson, vÃ  Stuart Yeates. Má»t sá» thÃ nh viÃªn khÃ¡c cá»§a dá»± Ã¡n New Zealand Digital Library ÄÃ£ cung cáº¥p lá»i khuyÃªn vÃ  Ãœ tÆ°á»ng trong thiáº¿t káº¿ cá»§a há» thá»ng: Mark Apperley, Sally Jo Cunningham, Matt Jones, Steve Jones, Te Taka Keegan, Michel Loots, Malika Mahoui, Gary Marsden, Dave Nichols and Lloyd Smith. ChÃºng tÃŽi cÅ©ng muá»n cáº£m Æ¡n táº¥t cáº£ nhá»¯ng ngÆ°á»i ÄÃ£ gÃ³p pháº§n ÄÆ°a cÃ¡c gÃ³i cÃ³ báº£n quyá»n cá»§a GNU vÃ o trong báº£n phÃ¢n phá»i nÃ y: MG, GDBM, PDFTOHTML, WGET, WVWARE and XLHTML. 
+}  
+
+_textaboutgslong_ [l=vi] {giá»i thiá»u vá» pháº§n má»m greenstone}
+
+######################################################################
+# 'users' page
+package userslistusers
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textlocu_ [l=vi] {Danh sÃ¡ch ngÆ°á»i sá»­ dá»¥ng hiá»n táº¡i}
+_textuser_ [l=vi] {ngÆ°á»i sá»­ dá»¥ng
+}
+_textas_ [l=vi] {tÃ¬nh tráº¡ng tÃ i khoáº£n}
+_textgroups_ [l=vi] {nhÃ³m}
+_textcomment_ [l=vi] {chÃº thÃ­ch}
+_textadduser_ [l=vi] {thÃªm ngÆ°á»i sá»­ dá»¥ng}
+_textedituser_ [l=vi] {chá»nh sá»­a}
+_textdeleteuser_ [l=vi] {xoÃ¡}
+
+
+######################################################################
+# 'users' page
+package usersedituser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textedituser_ [l=vi] {Chá»nh sá»­a thÃŽng tin ngÆ°á»i dÃ¹ng}
+_textadduser_ [l=vi] {ThÃªm ngÆ°á»i sá»­ dá»¥ng}
+
+_textaboutusername_ [l=vi] {TÃªn ÄÄng nháº­p pháº£i dÃ i tá»« 2 Äáº¿n 30 kÃœ tá»±. ChÃºng cÃ³ thá» chá»©a cÃ¡c kÃœ tá»±, chá»¯ sá», '.' vÃ  '_'.
+}
+
+_textaboutpassword_ [l=vi] {Máº­t kháº©u pháº£i dÃ i tá»« 3 Äáº¿n 128 kÃœ tá»±. ChÃºng chá» chá»©a cÃ¡c kÃœ tá»± ASCII in ÄÆ°á»£c thÃŽng thÆ°á»ng.
+}
+
+_textoldpass_ [l=vi] {Náº¿u trÆ°á»ng nÃ y trá»ng máº­t kháº©u cÅ© sáºœ ÄÆ°á»£c bá» qua.}
+_textenabled_ [l=vi] {cho phÃ©p}
+_textdisabled_ [l=vi] {khÃŽng cho phÃ©p}
+
+_textaboutgroups_ [l=vi] {CÃ¡c nhÃ³m phÃ¢n biá»t bá»i dáº¥u pháº©y, khÃŽng Äáº·t khoáº£ng tráº¯ng sau dáº¥u pháº©y.
+}
+
+
+######################################################################
+# 'users' page
+package usersdeleteuser
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textdeleteuser_ [l=vi] {XoÃ¡ ngÆ°á»i sá»­ dá»¥ng}
+_textremwarn_ [l=vi] {Báº¡n cÃ³ tháº­t sá»± muá»n xoÃ¡ ngÆ°á»i sá»­ dá»¥ng khÃŽng <b>_cgiargumun_</b>?}
+
+
+######################################################################
+# 'users' page
+package userschangepasswd
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textchangepw_ [l=vi] {Thay Äá»i máº­t kháº©u}
+_textoldpw_ [l=vi] {máº­t kháº©u cÅ©}
+_textnewpw_ [l=vi] {máº­t kháº©u má»i}
+_textretype_ [l=vi] {ÄÃ¡nh láº¡i máº­t kháº©u má»i}
+
+
+######################################################################
+# 'users' page
+package userschangepasswdok
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textsuccess_ [l=vi] {Máº­t kháº©u ÄÃ£ ÄÆ°á»£c thay Äá»i thÃ nh cÃŽng.}
+
+
+######################################################################
+# 'users' page
+package users
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textinvalidusername_ [l=vi] {TÃªn ÄÄng nháº­p khÃŽng tá»n táº¡i.}
+_textinvalidpassword_ [l=vi] {Máº­t kháº©u bá» sai.}
+_textemptypassword_ [l=vi] {Vui lÃ²ng nháº­p láº¡i máº­t kháº©u cho ngÆ°á»i dÃ¹ng nÃ y.}
+_textuserexists_ [l=vi] {NgÆ°á»i sá»­ dá»¥ng nÃ y ÄÃ£ tá»n táº¡i, báº¡n nháº­p tÃªn ÄÄng nháº­p khÃ¡c.}
+
+_textusernameempty_ [l=vi] {Vui lÃ²ng nháº­p tÃªn ÄÄng nháº­p.}
+_textpasswordempty_ [l=vi] {Báº¡n pháº£i nháº­p máº­t kháº©u cÅ©.}
+_textnewpass1empty_ [l=vi] {Báº¡n nháº­p máº­t kháº©u má»i sau ÄÃ³ ÄÃ¡nh láº¡i má»t láº§n ná»¯a.}
+_textnewpassmismatch_ [l=vi] {2 máº­t kháº©u báº¡n nháº­p vÃ o khÃŽng khá»p.}
+_textnewinvalidpassword_ [l=vi] {Báº¡n nháº­p má»t máº­t kháº©u khÃŽng cÃ³ giÃ¡ trá».}
+_textfailed_ [l=vi] {TÃªn ÄÄng nháº­p hoáº·c máº­t kháº©u cá»§a báº¡n bá» sai.}
+
+
+######################################################################
+# 'status' pages
+package status
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+
+_textversion_ [l=vi] {Sá» phiÃªn báº£n Greenstone }
+_textframebrowser_ [l=vi] {Báº¡n pháº£i cÃ³ trÃ¬nh duyá»t hiá»n thá» ÄÆ°á»£c frame.}
+_textusermanage_ [l=vi] {Quáº£n lÃœ ngÆ°á»i dÃ¹ng}
+_textlistusers_ [l=vi] {danh sÃ¡ch ngÆ°á»i dÃ¹ng}
+_textaddusers_ [l=vi] {thÃªm ngÆ°á»i dÃ¹ng má»i}
+_textchangepasswd_ [l=vi] {thay Äá»i máº­t kháº©u}
+_textinfo_ [l=vi] {ThÃŽng tin ká»¹ thuáº­t}
+_textgeneral_ [l=vi] {thÃŽng tin chung}
+_textarguments_ [l=vi] {Äá»i sá»}
+_textactions_ [l=vi] {hoáº¡t Äá»ng}
+_textbrowsers_ [l=vi] {cÃ¡ch hiá»n thá»}
+_textprotocols_ [l=vi] {cÃ¡c qui Æ°á»c}
+_textconfigfiles_ [l=vi] {CÃ¡c táº­p tin cáº¥u hÃ¬nh}
+_textlogs_ [l=vi] {Nháº­t kÃœ}
+_textusagelog_ [l=vi] {nháº­t kÃœ sá»­ dá»¥ng}
+_textinitlog_ [l=vi] {nháº­t kÃœ khá»i Äá»ng}
+_texterrorlog_ [l=vi] {nháº­t kÃœ lá»i}
+_textadminhome_ [l=vi] {Trang quáº£n trá»}
+_textreturnhome_ [l=vi] {Trang chá»§ Greenstone}
+_titlewelcome_ [l=vi] {Quáº£n trá» }
+_textmaas_ [l=vi] {CÃ¡c dá»ch vá»¥ duy trÃ¬ vÃ  quáº£n trá» ngÆ°á»i dÃ¹ng bao gá»m:}
+_textvol_ [l=vi] {Xem nháº­t kÃœ on-line}
+_textcmuc_ [l=vi] {táº¡o, duy trÃ¬ vÃ  cáº­p nháº­t cÃ¡c bá» sÆ°u táº­p}
+_textati_ [l=vi] {truy xuáº¥t cÃ¡c thÃŽng tin ká»¹ thuáº­t vÃ­ dá»¥ nhÆ° cÃ¡c Äá»i sá» CGI}
+
+_texttsaa_ [l=vi] {Nhá»¯ng dá»ch vá»¥ nÃ y ÄÆ°á»£c truy xuáº¥t sá»­ dá»¥ng cÃ¡c thanh Äiá»u khiá»n á» bÃªn trÃ¡i cá»§a trang.
+}
+
+_textcolstat_ [l=vi] {TÃ¬nh tráº¡ng bá» sÆ°u táº­p}
+
+_textcwoa_ [l=vi] {CÃ¡c bá» sÆ°u táº­p sáºœ ÄÆ°á»£c kÃ­ch hoáº¡t náº¿u cÃ¡c táº­p tin build.cfg tá»n táº¡i, cÃ¡c táº­p tin nÃ y cho phÃ©p Äá»c, vÃ  trÆ°á»ng ngÃ y xÃ¢y dá»±ng cá»§a bá» sÆ°u táº­p lÃ  há»£p lá» vÃ  náº±m trong thÆ° má»¥c quáº£n lÃœ cá»§a bá» sÆ°u táº­p.
+}  
+
+_textcafi_ [l=vi] {nháº¥n vÃ o <i>abbrev.</i> Äá» xem thÃŽng tin chi tiáº¿t cá»§a má»t bá» sÆ°u táº­p.}
+_textcctv_ [l=vi] {nháº¥n vÃ o  <i>collection</i> Äá» xem tá»ng quan vá» bá» sÆ°u táº­p.}
+_textsubc_ [l=vi] {Cáº­p nháº­t cÃ¡c thay Äá»i}
+_texteom_ [l=vi] {Má» táº­p tin main.cfg lá»i}
+_textftum_ [l=vi] {Cáº­p nháº­t táº­p tin main.cfg tháº¥t báº¡i}
+_textmus_ [l=vi] {main.cfg cáº­p nháº­p thÃ nh cÃŽng}
+
+
+######################################################################
+# 'bsummary' pages
+package bsummary
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+
+_textbsummary_ [l=vi] {TÃ³m táº¯t quÃ¡ trÃ¬nh xÃ¢y dá»±ng bá» sÆ°u táº­p "_collectionname_"}  
+_textflog_ [l=vi] {Ghi nháº­t kÃœ cho bá» sÆ°u táº­p _collectionname_ bá» tháº¥t báº¡i}  
+_textilog_ [l=vi] {Nháº­p kháº©u báº£n ghi"_collectionname" cho bá» sÆ°u táº­p}  
+
+############################################################################
+#
+# This stuff is only used by the usability (SEND FEEDBACK) stuff
+#
+############################################################################
+package Global
+
+# old cusab button
+_linktextusab_ [l=vi] {Gá»­i thÃŽng tin pháº£n há»i}  
+
+_greenstoneusabilitytext_ [l=vi] {Tiá»n Ã­ch Greenstone}
+
+_textwhy_ [l=vi] {<p>QuÃ¡ trÃ¬nh gá»­i bÃ¡o cÃ¡o gáº·p sá»± cá» hoáº·c tháº¥t báº¡i.}  
+_textextraforform_ [l=vi] {Báº¡n khÃŽng pháº£i Äiá»n vÃ o máº«u -- báº¥t ká»³ thÃŽng tin hÆ°á»ng dáº«n nÃ o.}  
+_textprivacybasic_ [l=vi] {<p>BÃ¡o cÃ¡o chá» chá»©a cÃ¡c thÃŽng tin vá» trang web Greenstone vÃ  ká»¹ thuáº­t mÃ  ngÆ°á»i sá»­ dá»¥ng Äang dÃ¹ng Äá» xem nÃ³ (vÃ  báº¥t cá»© thÃŽng tin mÃ  báº¡n cung cáº¥p).}  
+_textstillsend_ [l=vi] {Báº¡n váº«n muá»n gá»­i bÃ¡o cÃ¡o nÃ y?}  
+
+_texterror_ [l=vi] {lá»i}
+_textyes_ [l=vi] {Äá»ng Ãœ}  
+_textno_ [l=vi] {KhÃŽng}  
+_textclosewindow_ [l=vi] {ÄÃ³ng cá»­a sá»}  
+_textabout_ [l=vi] {Giá»i thiá»u}
+_textprivacy_ [l=vi] {RiÃªng tÆ°}
+_textsend_ [l=vi] {Gá»­i}
+_textdontsend_ [l=vi] {KhÃŽng gá»­i}  
+_textoptionally_ [l=vi] {Tuá»³ chá»n}  
+
+_textunderdev_ [l=vi] {CÃ¡c chi tiáº¿t sáºœ ÄÆ°á»£c xem trÆ°á»c trong phiÃªn báº£n cuá»i cÃ¹ng.}  
+
+_textviewdetails_ [l=vi] {Xem chi tiáº¿t bÃ¡o cÃ¡o }  
+_textmoredetails_ [l=vi] {Chi tiáº¿t hÆ¡n}  
+_texttrackreport_ [l=vi] {Theo dÃµi bÃ¡o cÃ¡o nÃ y}  
+_textcharacterise_ [l=vi] {Váº¥n Äá» gáº·p pháº£i lÃ  gÃ¬?}  
+_textseverity_ [l=vi] {Má»©c Äá» nghiÃªm trá»ng cá»§a váº¥n Äá»}  
+ 
+_textbadrender_ [l=vi] {Trang bá» lá»i.}  
+_textcontenterror_ [l=vi] {Lá»i ná»i dung}  
+_textstrangebehaviour_ [l=vi] {Hoáº¡t Äá»ng má»t cÃ¡ch kÃ¬ láº¡}  
+_textunexpected_ [l=vi] {Xáº£y ra lá»i}  
+_textfunctionality_ [l=vi] {KhÃ³ sá»­ dá»¥ng}  
+_textother_ [l=vi] {Nhá»¯ng váº¥n Äá» khÃ¡c}  
+
+_textcritical_ [l=vi] {Nháº­n xÃ©t}  
+_textmajor_ [l=vi] {Quan trá»ng}  
+_textmedium_ [l=vi] {BÃ¬nh thÆ°á»ng}  
+_textminor_ [l=vi] {Thá»© yáº¿u}  
+_texttrivial_ [l=vi] {Hiá»n nhiÃªn}  
+
+_textwhatdoing_ [l=vi] {Báº¡n Äá»nh lÃ m gÃ¬?}  
+_textwhatexpected_ [l=vi] {Báº¡n mong Äá»£i cÃ¡i gÃ¬ sáºœ xáº£y ra?}  
+_textwhathappened_ [l=vi] {Váº¥n Äá» gÃ¬ thá»±c sá»± xáº£y ra?}  
+
+_cannotfindcgierror_ [l=vi] {<h2>Lá»i!</h2> KhÃŽng tÃ¬m tháº¥y chÆ°Æ¡ng trÃ¬nh chá»§ cho nÃºt "_linktextusab_".}  
+
+_textusabbanner_ [l=vi] {the Greenstone koru-style banner}
+
+
+######################################################################
+# GTI text strings
+package gti
+######################################################################
+
+
+#------------------------------------------------------------
+# text macros
+#------------------------------------------------------------
+	
+_textgtierror_ [l=vi] {Lá»i}  
+
+_textgtihome_ [l=vi] {Nhá»¯ng trang bÃªn dÆ°á»i giÃºp phÃ¡t triá»n bá» sÆ°u táº­p Greenstone theo nhiá»u ngÃŽn ngá»¯ khÃ¡c nhau. NgÆ°á»i dÃ¹ng cÃ³ thá»:
+<ul>
+  <li>Dá»ch tá»«ng pháº§n cá»§a Greenstone sang má»t ngÃŽn ngá»¯ má»i
+  <li> Cáº­p nháº­t láº¡i giao diá»n vá»i má»t ngÃŽn ngá»¯ ÄÃ£ tá»n táº¡i khi giao diá»n báº±ng tiáº¿ng Anh bá» thay Äá»i (eg. Äá»i vá»i kháº£ nÄng má»i cá»§a Greenstone )
+  <li>Chá»nh sá»­a lá»i á» báº£n dá»ch ÄÃ£ cÃ³.
+</ul>
+
+Má»t loáº¡t cÃ¡c ná»i dung trong trang web sáºœ ÄÆ°á»£c hiá»n thá», má»i ná»i dung lÃ  má»t tá»« hoáº·c cá»¥m tá»« cáº§n dá»ch.
+Tiáº¿n hÃ nh dá»ch sang ngÃŽn ngá»¯ khÃ¡c theo tá»«ng Äoáº¡n vÄn.
+Nhiá»u Äoáº¡n vÄn báº£n chá»©a Äá»±ng cÃ¡c lá»nh Äá»nh dáº¡ng theo kiá»u HTML thÃ¬ khÃŽng cáº§n pháº£i dá»ch vÃ  giá»¯ nguyÃªn chÃºng. Nhá»¯ng tá»« Äi kÃšm vá»i cÃ¡c dáº¥u gáº¡ch dÆ°á»i (vÃ­ dá»¥: _this_) thÃ¬ khÃŽng cáº§n dá»ch. 
+<p>
+Náº¿u Äang thá»±c hiá»n cáº­p nháº­t ngÃŽn ngá»¯ cho giao diá»n, ngÆ°á»i dÃ¹ng sáºœ khÃŽng thá» tháº¥y ngay ÄÆ°á»£c káº¿t quáº£ ÄÃ£ dá»ch. ÄÃŽi khi má»t ná»i dung ÄÃ£ ÄÆ°á»£c dá»ch nhÆ°ng trÃªn giao diá»n váº«n tháº¥y hiá»n thá» báº±ng tiáº¿ng Anh. Trong trÆ°á»ng há»£p nÃ y cáº§n kiá»m tra vÃ  cáº­p nháº­t láº¡i báº£n dá»ch hiá»n táº¡i.
+<p>
+Äá» hiá»u chá»nh láº¡i cÃ¡c ná»i dung ÄÃ£ dá»ch, nháº¥n vÃ o âChá»nh sá»­a báº£n dá»ch ÄÃ£ cÃ³â, chá»©c nÄng nÃ y ÄÆ°á»£c cung cáº¥p Äá»i vá»i má»i Greenstone.
+<p>
+Káº¿t thÃºc má»i trang lÃ  nÃºt â_textgtisubmit _â. Khi nháº¥n nÃºt nÃ y, cÃ¡c thay Äá»i ngay láº­p tá»©c sáºœ khá»i táº¡o má»t bá» Greenstone táº¡i nzdl.org. Má»i trang ÄÆ°á»£c cung cáº¥p má»t nÃºt Äá» truy cáº­p vÃ o Äá»a chá» nÃ y.
+}  
+
+_textgtiselecttlc_ [l=vi] {Vui lÃ²ng chá»n ngÃŽn ngá»¯}  
+
+#for status page
+_textgtiviewstatus_ [l=vi] {KÃ­ch chuá»t Äá» xem tÃ¬nh tráº¡ng dá»ch hiá»n táº¡i cho má»i ngÃŽn ngá»¯}  
+_textgtiviewstatusbutton_ [l=vi] {XEM TRáº NG THÃI}  
+_textgtistatustable_ [l=vi] {Tráº¡ng thÃ¡i báº£n Äá»a hiá»n táº¡i cá»§a táº¥t cáº£ cÃ¡c ngÃŽn ngá»¯}  
+_textgtilanguage_ [l=vi] {NgÃŽn ngá»¯}  
+_textgtitotalnumberoftranslations_ [l=vi] {Tá»ng sá» má»¥c báº£n Äá»a}  
+
+_textgtiselecttfk_ [l=vi] {Vui lÃ²ng chá»n má»t táº­p tin Äá» lÃ m viá»c vá»i}  
+
+_textgticoredm_ [l=vi] {Giao diá»n chÃ­nh cá»§a Greenstone}  
+_textgtiauxdm_ [l=vi] {Giao diá»n phá»¥ cá»§a Greenstone}  
+_textgtiglidict_ [l=vi] {Tá»« Äiá»n GLI}  
+_textgtiglihelp_ [l=vi] {trá»£ giÃºp GLI}  
+_textgtiperlmodules_ [l=vi] {mooddun Perl}  
+_textgtitutorials_ [l=vi] {BÃ i táº­p hÆ°á»ng dáº«n}  
+_textgtigreenorg_ [l=vi] {Táº­p tin Greenstone.org}  
+_textgtigs3core_ [l=vi] {Giao diá»n Greenstone3}  
+
+#for greenstone manuals
+_textgtidevmanual_ [l=vi] {TÃ i liá»u hÆ°á»ng dáº«n phÃ¡t triá»n Greenstone}  
+_textgtiinstallmanual_ [l=vi] {TÃ i liá»u hÆ°á»ng dáº«n cÃ i Äáº·t Greenstone}  
+_textgtipapermanual_ [l=vi] {TÃ i liá»u hÆ°á»ng dáº«n táº¡o bá» sÆ°u táº­p sá» tá»« giáº¥y}  
+_textgtiusermanual_ [l=vi] {TÃ i liá»u hÆ°á»ng dáº«n sá»­ dá»¥ng Greenstone}  
+
+_textgtienter_ [l=vi] {Äá»ng Ãœ}  
+
+_textgticorrectexistingtranslations_ [l=vi] {Chá»nh sá»­a báº£n dá»ch ÄÃ£ cÃ³}  
+_textgtidownloadtargetfile_ [l=vi] {Táº£i táº­p tin}  
+_textgtiviewtargetfileinaction_ [l=vi] {Xem táº­p tin}  
+_textgtitranslatefileoffline_ [l=vi] {Dá»ch tá»p tin nÃ y theo cÃ¡ch khÃŽng trá»±c tuyáº¿n}  
+
+_textgtinumchunksmatchingquery_ [l=vi] {Sá» cá»§a Äoáº¡n vÄn báº£n riÃªng biá»t thá»a vá»i cÃ¢u truy váº¥n}  
+
+_textgtinumchunkstranslated_ [l=vi] {translations done}  
+_textgtinumchunksrequiringupdating_ [l=vi] {Of these, _1_ YÃªu cáº§u cáº­p nháº­t}  
+_textgtinumchunksrequiringtranslation_ [l=vi] {Báº£n dá»ch cÃ²n láº¡i}  
+
+#for status page
+_textgtinumchunkstranslated2_ [l=vi] {sá» má»¥c Viá»t hoÃ¡ ÄÃ£ lÃ m}  
+_textgtinumchunksrequiringupdating2_ [l=vi] {sá» má»¥c báº£n Äá»a yÃªu cáº§u cáº­p nháº­t}  
+_textgtinumchunksrequiringtranslation2_ [l=vi] {sá» má»¥c báº£n Äá»a chÆ°a thá»±c hiá»n}  
+
+_textgtienterquery_ [l=vi] {Nháº­p vÃ o má»t tá»« hoáº·c má»t thuáº­t ngá»¯ }  
+_textgtifind_ [l=vi] {TÃ¬m kiáº¿m}  
+
+_textgtitranslatingchunk_ [l=vi] {dá»ch cÃ¡c Äoáº¡n vÄn báº£n riÃªng biá»t <i>_1_</i>}  
+_textgtiupdatingchunk_ [l=vi] {Cáº­p nháº­t tá»«ng vÄn báº£n riÃªng biá»t <i>_1_</i>}  
+_textgtisubmit_ [l=vi] {XÃ¡c nháº­n}  
+
+_textgtilastupdated_ [l=vi] {cáº­p nháº­t gáº§n nháº¥t}  
+
+_textgtitranslationfilecomplete_ [l=vi] {Táº­p tin nÃ y  ÄÆ°á»£c cáº­p nháº­t xong. CÃ³ thá» táº£i vá» táº­p tin nÃ y báº±ng liÃªn káº¿t bÃªn dÆ°á»i, vÃ  cÃ³ thá» thÃªm vÃ o bá» sÆ°u táº­p Greenstone trong tÆ°Æ¡ng lai.}  
+
+_textgtiofflinetranslation_ [l=vi] {Báº¡n cÃ³ thá» dá»ch pháº§n nÃ y cá»§a Greenstone theo phÆ°Æ¡ng thá»©c khÃŽng trá»±c tuyáº¿n báº±ng cÃ¡ch sá»­ dá»¥ng tá»p Microsoft Excel riÃªng biá»t:
+
+<ol>
+<li>Táº£i xuá»ng <a href="_gwcgi_?a=gti&p=excel&e=_compressedoptions_">tá»p tin nÃ y </a>.
+<li>Má» ra báº±ng Microsoft Excel vÃ  lÆ°u láº¡i dÆ°á»i dáº¡ng Microsoft Excel workbook (.xls) format.
+<li>Nháº­p nhá»¯ng Äoáº¡n ÄÆ°á»£c dá»ch vÃ  o cÃ¡c há»p thoáº¡i cÃ³ sáºµn.
+<li>Khi káº¿t thÃºc viá»c dá»ch, gá»­i (e-mail) tá»p tin trÃªn MS Excel .xls Äáº¿n <a href="mailto:_gtiadministratoremail_">_gtiadministratoremail_</a>.
+</ol>
+}  
+
+
+
+############
+# gli page
+############
+package gli
+
+_textglilong_ [l=vi] {giao diá»n thá»§ thÆ°}
+_textglihelp_ [l=vi] {<p>ThÆ° viá»n sá» Greestone (GLI) cho phÃ©p dá»
+ dÃ ng truy cáº­p Äáº¿n cÃ¡c chá»©c nÄng cá»§a Greentones thÃŽng qua thao tÃ¡c "KÃ©o tháº£ chuá»t". NÃ³ cho phÃ©p báº¡n táº­p há»£p tÃ i liá»u nguá»n, nháº­p hoáº·c chá» Äá»nh Metadata, vÃ  xÃ¢y dá»±ng chÃºng vÃ o bá» sÆ°u táº­p. </p>
+
+<p>ChÃº Ãœ ráº±ng GLI ÄÆ°á»£c cháº¡y káº¿t há»£p vá»i Greenstone vÃ  pháº£i ÄÆ°á»£c cÃ i Äáº·t trong thÆ° má»¥c con cá»§a thÆ° má»¥c cÃ i Äáº·t Greenstone.  DÆ°á»i ÄÃ¢y sáºœ lÃ  má»t sá» hÆ°á»ng dáº«n náº¿u báº¡n cÃ i Äáº·t tá»« má»t trong nhá»¯ng báº£n phÃ¢n phá»i cá»§a Greenstone hoáº·c tá»« má»t CD-ROM Greenstone.
+ 
+ 
+<h4>Cháº¡y GLI trÃªn Windows</h4>
+ 
+Cháº¡y giao diá»n thá»§ thÆ° trÃªn Windows báº±ng cÃ¡ch chá»n <i>Start\Programs\Greenstone Digital Library\Librarian Interface</i>. 
+
+ 
+<h4>Cháº¡y GLI trÃªn Unix</h4>
+ 
+Äá» cháº¡y GLI trÃªn Unix chuyá»n thÆ° má»¥c Äáº¿n thÆ° má»¥c <i>gli</i> trong thÆ° má»¥c cÃ i Äáº·t Greenstone sau ÄÃ³ cháº¡y táº­p tin <i>gli.sh</i>. 
+ 
+<h4>Cháº¡y GLI trÃªn Mac OS X</h4>
+
+Trong cÃŽng cá»¥ tÃ¬m kiáº¿m duyá»t thÆ° má»¥c Äáº¿n <i>Applications</i> sau ÄÃ³ lÃ  <i>Greenstone</i>
+(náº¿u báº¡n cÃ i Äáº·t Greenstone vÃ o thÆ° má»¥c máº·c Äá»nh) vÃ  cháº¡y á»©ng dá»¥ng <i>GLI</i>.
+}  
Index: /gsdl/stable/macros/yourhome-ar.dm
===================================================================
--- /gsdl/stable/macros/yourhome-ar.dm	(revision 20131)
+++ /gsdl/stable/macros/yourhome-ar.dm	(revision 20131)
@@ -0,0 +1,37 @@
+﻿# this file must be UTF-8 encoded
+
+package home
+_content_ {
+
+<h2>موقع greenstone خاصتك</h2>
+
+<ul>
+<table>
+<tr valign=top><td>صفحة البحث للمجموعات التوضيحية<br></td>
+    <td><a href="_httpquery_&c=demo">أنقر هنا</a></td></tr>
+
+<tr><td>صفحة "حول" للمجموعات التوضيحية</td>
+    <td><a href="_httppageabout_&c=demo">أنقر هنا</a></td></tr>
+
+<tr><td>صفحة التفضيلات للمجموعات التوضيحية</td>
+    <td><a href="_httppagepref_&c=demo">أنقر هنا</a></td></tr>
+
+<tr><td>الموقع</td>
+    <td><a href="_httppagehome_">أنقر هنا</a></td></tr>
+
+<tr><td>صفحة المساعدة</td>
+    <td><a href="_httppagehelp_">أنقر هنا</a></td></tr>
+
+<tr><td>صفحة الإدارة</td>
+    <td><a href="_httppagestatus_">أنقر هنا</a></td></tr>
+
+</table>
+</ul>
+
+}
+
+# if you hate the squirly green bar down the left-hand side of the page,
+# uncomment these lines:
+
+# _header_ { 
+#          }
Index: /gsdl/stable/macros/yourhome-es.dm
===================================================================
--- /gsdl/stable/macros/yourhome-es.dm	(revision 20131)
+++ /gsdl/stable/macros/yourhome-es.dm	(revision 20131)
@@ -0,0 +1,37 @@
+# this file must be UTF-8 encoded
+
+package home
+_content_ {
+
+<h2>Su propia pÃ¡gina principal para Greenstone</h2>
+
+<ul>
+<table>
+<tr valign=top><td>PÃ¡gina de bÃºsqueda para la colecciÃ³n demo<br></td>
+    <td><a href="_httpquery_&c=demo">Presione aquÃ­</a></td></tr>
+
+<tr><td>PÃ¡gina Â«sobreÂ» para la colecciÃ³n demo</td>
+    <td><a href="_httppageabout_&c=demo">Presione aquÃ­</a></td></tr>
+
+<tr><td>PÃ¡gina de preferencias para la colecciÃ³n demo</td>
+    <td><a href="_httppagepref_&c=demo">Presione aquÃ­</a></td></tr>
+
+<tr><td>PÃ¡gina principal</td>
+    <td><a href="_httppagehome_">Presione aquÃ­</a></td></tr>
+
+<tr><td>PÃ¡gina de ayuda</td>
+    <td><a href="_httppagehelp_">Presione aquÃ­</a></td></tr>
+
+<tr><td>PÃ¡gina de administraciÃ³n</td>
+    <td><a href="_httppagestatus_">Presione aquÃ­</a></td></tr>
+
+</table>
+</ul>
+
+}
+
+# if you hate the squirly green bar down the left-hand side of the page,
+# uncomment these lines:
+
+# _header_ { 
+# }
Index: /gsdl/stable/macros/yourhome-fr.dm
===================================================================
--- /gsdl/stable/macros/yourhome-fr.dm	(revision 20131)
+++ /gsdl/stable/macros/yourhome-fr.dm	(revision 20131)
@@ -0,0 +1,37 @@
+# this file must be UTF-8 encoded
+
+package home
+_content_ {
+
+<h2>Votre propre page d'accueil pour Greenstone</h2>
+
+<ul>
+<table>
+<tr valign=top><td>Page de recherche pour la collection demo<br></td>
+    <td><a href="_httpquery_&c=demo">Cliquez ici</a></td></tr>
+
+<tr><td>Page Â«Ã  proposÂ» pour la collection demo</td>
+    <td><a href="_httppageabout_&c=demo">Cliquez ici</a></td></tr>
+
+<tr><td>Page de prÃ©fÃ©rences pour la collection demo</td>
+    <td><a href="_httppagepref_&c=demo">Cliquez ici</a></td></tr>
+
+<tr><td>Page d'accueil</td>
+    <td><a href="_httppagehome_">Cliquez ici</a></td></tr>
+
+<tr><td>Page d'aide</td>
+    <td><a href="_httppagehelp_">Cliquez ici</a></td></tr>
+
+<tr><td>Page d'administration</td>
+    <td><a href="_httppagestatus_">Cliquez ici</a></td></tr>
+
+</table>
+</ul>
+
+}
+
+# if you hate the squirly green bar down the left-hand side of the page,
+# uncomment these lines:
+
+# _header_ { 
+# }
Index: /gsdl/stable/macros/yourhome.dm
===================================================================
--- /gsdl/stable/macros/yourhome.dm	(revision 20131)
+++ /gsdl/stable/macros/yourhome.dm	(revision 20131)
@@ -0,0 +1,37 @@
+# this file must be UTF-8 encoded
+
+package home
+_content_ {
+
+<h2>Your own Greenstone home page</h2>
+
+<ul>
+<table>
+<tr valign=top><td>Search page for the demo collection<br></td>
+    <td><a href="_httpquery_&c=demo">Click here</a></td></tr>
+
+<tr><td>"About" page for the demo collection</td>
+    <td><a href="_httppageabout_&c=demo">Click here</a></td></tr>
+
+<tr><td>Preferences page for the demo collection</td>
+    <td><a href="_httppagepref_&c=demo">Click here</a></td></tr>
+
+<tr><td>Home page</td>
+    <td><a href="_httppagehome_">Click here</a></td></tr>
+
+<tr><td>Help page</td>
+    <td><a href="_httppagehelp_">Click here</a></td></tr>
+
+<tr><td>Administration page</td>
+    <td><a href="_httppagestatus_">Click here</a></td></tr>
+
+</table>
+</ul>
+
+}
+
+# if you hate the squirly green bar down the left-hand side of the page,
+# uncomment these lines:
+
+# _header_ { 
+#          }
Index: /gsdl/stable/makegs2.bat
===================================================================
--- /gsdl/stable/makegs2.bat	(revision 20131)
+++ /gsdl/stable/makegs2.bat	(revision 20131)
@@ -0,0 +1,213 @@
+@echo off
+pushd "%CD%"
+CD /D "%~dp0"
+
+
+:: Path to VCVARS32.bat -- You can set this variable manually if needed
+:: e.g. set VCVARS="C:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"
+set VCVARS=""
+
+
+
+
+rem Checking for Winbin and Unzip utility
+IF NOT EXIST .\bin\windows\*.* GOTO ENDNOWINBIN
+IF NOT EXIST .\bin\windows\choice.exe GOTO ENDNOWINBIN
+
+
+echo.
+echo.
+echo  ####                        #                  ###  
+echo ##                           #                     # 
+echo #     ###  ##   ##  ### ### ###  ##  ###  ##       # 
+echo #   # #   #### #### # # ##   #  #  # # # ####    ##  
+echo ##  # #   #    #    # #   #  #  #  # # # #      ##   
+echo  #### #    ###  ### # # ###  ##  ##  # #  ###   #### 
+echo   (C) 2008, New Zealand Digital Library Project
+echo.
+echo.
+echo.
+
+
+rem Checking for existance of the packages extracted / zipped
+IF NOT EXIST .\common-src\packages\windows\crypt\crypt\*.* IF NOT EXIST .\common-src\packages\windows\crypt\crypt.zip GOTO ENDNOWINPACK
+
+IF NOT EXIST .\common-src\packages\windows\expat\expat\*.* IF NOT EXIST .\common-src\packages\windows\expat\expat.zip GOTO ENDNOWINPACK
+
+:: IF NOT EXIST .\common-src\packages\windows\gdbm\gdbm\*.* IF NOT EXIST .\common-src\packages\windows\gdbm\gdbm.zip GOTO ENDNOWINPACK
+
+IF NOT EXIST .\common-src\packages\windows\stlport\stlport\*.* IF NOT EXIST .\common-src\packages\windows\stlport\stlport.zip GOTO ENDNOWINPACK
+
+IF NOT EXIST .\common-src\indexers\packages\windows\iconv\iconv\*.* IF NOT EXIST .\common-src\indexers\packages\windows\iconv\iconv.zip GOTO ENDNOICONV
+
+IF NOT EXIST .\common-src\packages\sqlite\sqlite* IF NOT EXIST .\common-src\packages\sqlite\sqlite*.tar.gz GOTO ENDNOSQLITE
+
+rem Ask the user to extract now or to directly compile
+echo Do you want to extract the required packages (Recommended)? This will be the default action in 10 seconds.
+.\bin\windows\choice.exe /T:Y,10 /C:YN
+	IF errorlevel 2 GOTO COMPILE
+	IF errorlevel 1 GOTO UNZIP
+	IF errorlevel 0 GOTO END
+	
+
+:UNZIP
+IF NOT EXIST .\bin\windows\unzip.exe GOTO ENDNOUNZIP
+IF NOT EXIST .\bin\windows\gunzip.exe GOTO ENDNOUNZIP
+IF NOT EXIST .\bin\windows\tar.exe GOTO ENDNOUNZIP
+
+rem Extracting the packages
+IF EXIST .\common-src\packages\windows\crypt\crypt.zip .\bin\windows\unzip.exe -o .\common-src\packages\windows\crypt\crypt.zip -d .\common-src\packages\windows\crypt\
+
+IF EXIST .\common-src\packages\windows\expat\expat.zip .\bin\windows\unzip.exe -o .\common-src\packages\windows\expat\expat.zip -d .\common-src\packages\windows\expat\
+
+IF EXIST .\common-src\packages\windows\gdbm\gdbm.zip .\bin\windows\unzip.exe -o .\common-src\packages\windows\gdbm\gdbm.zip -d .\common-src\packages\windows\gdbm\
+
+IF EXIST .\common-src\packages\windows\stlport\stlport.zip .\bin\windows\unzip.exe -o .\common-src\packages\windows\stlport\stlport.zip -d .\common-src\packages\windows\stlport\
+
+IF EXIST .\common-src\indexers\packages\windows\iconv\iconv.zip .\bin\windows\unzip.exe -o .\common-src\indexers\packages\windows\iconv\iconv.zip -d .\common-src\indexers\packages\windows\iconv\
+
+IF EXIST .\common-src\packages\sqlite\sqlite*.tar.gz .\bin\windows\gunzip.exe -cd .\common-src\packages\sqlite\sqlite*.tar.gz | .\bin\windows\tar.exe xv --directory=./common-src/packages/sqlite
+echo.
+echo.
+:COMPILE
+
+rem Last check if all the packages have been extracted prior compilation
+IF NOT EXIST .\common-src\packages\windows\crypt\crypt\*.* GOTO NEEDUNZIP
+IF NOT EXIST .\common-src\packages\windows\expat\expat\*.* GOTO NEEDUNZIP
+:: IF NOT EXIST .\common-src\packages\windows\gdbm\gdbm\*.* GOTO NEEDUNZIP
+IF NOT EXIST .\common-src\packages\windows\stlport\stlport\*.* GOTO NEEDUNZIP
+IF NOT EXIST .\common-src\indexers\packages\windows\iconv\iconv\*.* GOTO NEEDUNZIP
+IF NOT EXIST .\common-src\packages\sqlite\sqlite* GOTO NEEDUNZIP
+
+rem Check some known paths to VCVARS32.BAT
+:: if the user has set VCVARS32 don't look in the default places at all
+IF NOT %VCVARS%=="" GOTO CALLVCVARS
+
+:: Visual Studio 2005 Pro --- NOT READY YET
+::IF EXIST "%programfiles%\Microsoft Visual Studio 8\VC\bin\vcvars32.bat" set VCVARS="%programfiles%\Microsoft Visual Studio 8\VC\bin\vcvars32.bat"
+
+:: Visual Studio 2003 \ VS7
+IF EXIST "%programfiles%\Microsoft Visual Studio .NET 2003\Vc7\bin\vcvars32.bat" set VCVARS="%programfiles%\Microsoft Visual Studio .NET 2003\Vc7\bin\vcvars32.bat"
+
+:: Visual Studio 6 \ VS6
+IF EXIST "%programfiles%\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT" set VCVARS="%programfiles%\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"
+
+
+IF %VCVARS%=="" GOTO ENDNOVCVARS32
+
+:CALLVCVARS
+call %VCVARS%
+echo.
+echo.
+echo.
+rem Ask the user what to compile
+echo What do you want to compile?
+echo.
+echo 1. Local library only
+echo 2. Web library only
+echo 3. Both
+echo 4. Quit
+echo.
+echo Please choose a number from the menu. Otherwise both libraries will be compiled in 15 seconds.
+.\bin\windows\choice.exe /N /T:3,15 /C:1234
+	IF errorlevel 4 GOTO END
+	IF errorlevel 3 GOTO WITHBOTH
+	IF errorlevel 2 GOTO WITHOUTLOCALLIB
+	IF errorlevel 1 GOTO WITHLOCALLIB
+	IF errorlevel 0 GOTO END
+
+
+:WITHOUTLOCALLIB
+nmake /f win32.mak
+GOTO ENDOK
+
+:WITHLOCALLIB
+nmake /f win32.mak LOCAL_LIBRARY=1
+GOTO ENDOK
+
+:WITHBOTH
+nmake /f win32.mak
+nmake /f win32.mak LOCAL_LIBRARY=1
+GOTO ENDOK
+
+:NEEDUNZIP
+echo.
+echo /!\ Error /!\ - Some or all the packages are not properly extracted.
+echo.
+echo If you wish to compile Greenstone 2 you need to unzip the required packages now.
+echo.
+rem Ask to Unzip the packages now otherwise quit
+echo Do you want to unzip these required packages now? This will be the default action in 10 seconds.
+.\bin\windows\choice.exe /T:Y,10 /c:YN
+	IF errorlevel 2 GOTO END
+	IF errorlevel 1 GOTO UNZIP
+	IF errorlevel 0 GOTO END
+
+:ENDNOWINBIN
+echo.
+echo /!\ Error /!\ - Winbin has not been found.
+echo This is required to get the conversion tools used for importing different types of files.
+echo For more info please visit this page
+echo http://wiki.greenstone.org/wiki/index.php/Installing_Greenstone_2_from_SVN_source_on_Windows#Getting_winbin
+GOTO END
+
+:ENDNOUNZIP
+echo.
+echo /!\ Error /!\ - Extacting tools are missing.
+echo They are required to extract all packages needed for compilation.
+echo These tools are contained in the Winbin folder, more info on this web page:
+echo http://wiki.greenstone.org/wiki/index.php/Installing_Greenstone_2_from_SVN_source_on_Windows#Getting_winbin
+GOTO END
+
+:ENDNOWINPACK
+echo.
+echo /!\ Error /!\ - Windows packages are missing.
+echo Some required packages are missing in .\common-src\packages\windows\
+echo Please go to this page for more information on how to get everything:
+echo http://wiki.greenstone.org/wiki/index.php/Installing_Greenstone_2_from_SVN_source_on_Windows
+GOTO END
+
+:ENDNOSQLITE
+echo.
+echo /!\ Error /!\ - SQLite is missing.
+echo Some required packages are missing in .\common-src\packages\sqlite\
+echo Please go to this page for more information on how to get everything:
+echo http://wiki.greenstone.org/wiki/index.php/Installing_Greenstone_2_from_SVN_source_on_Windows
+GOTO END
+
+:ENDNOICONV
+echo.
+echo /!\ Error /!\ - Indexers are missing.
+echo Some required packages are missing in .\common-src\indexers\packages\windows\
+echo Please go to this page for more information on how to get everything:
+echo http://wiki.greenstone.org/wiki/index.php/Installing_Greenstone_2_from_SVN_source_on_Windows
+GOTO END
+
+:ENDNOVCVARS32
+echo.
+echo /!\ Error /!\ - Not able to find 'vcvars32.bat'.
+echo You need Visual Studio to compile the source code but we were
+echo unable to find the file vcvars32.bat in your system.
+echo.
+echo Please edit this bat file and manually set the full path to 
+echo vcvars32.bat then run this script again.
+GOTO END
+
+:ENDOK
+echo.
+echo Done!
+echo.
+echo This program is free software; you can redistribute it and/or
+echo modify it under the terms of the GNU General Public License
+echo as published by the Free Software Foundation; either version 2
+echo of the License, or (at your option) any later version.
+echo.
+echo This program is distributed in the hope that it will be useful,
+echo but WITHOUT ANY WARRANTY; without even the implied warranty of
+echo MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+echo GNU General Public License for more details.
+echo.
+GOTO END
+
+:END
+popd
Index: /gsdl/stable/mappings/README
===================================================================
--- /gsdl/stable/mappings/README	(revision 20131)
+++ /gsdl/stable/mappings/README	(revision 20131)
@@ -0,0 +1,22 @@
+This directory and its subdirectories contain .ump mapping files for
+converting various character encodings to and from unicode.
+
+To generate .ump files use a command like "makemapfile.pl -encoding
+encodingname -mapfile textmapfile" where encodingname becomes the filename
+of the two new .ump files and textmapfile is a plain text file containing a
+tab separated list of the form:
+0x8167	      0x201C
+where the first column is the hexadecimal value of the encoded character
+and the second is the hexadecimal value of it's unicode equivalent.
+
+
+
+The following .ump files were generated from their corresponding Microsoft
+codepages. These codepages do, in some cases, differ very slightly from the
+standards they were based on but we've used them anyway as they're so
+extensively used on the web.
+
+* gbk.ump: Simplified Chinese - generated from Microsoft's codepage 936
+* shiftjis.ump: Japanese - generated from Microsoft's codepage 932
+* uhc.ump: UHC Korean - generated from Microsoft's codepage 949
+* big5.ump: Traditional Chinese - generated from Microsoft's codepage 950
Index: /gsdl/stable/micotest.cpp
===================================================================
--- /gsdl/stable/micotest.cpp	(revision 20131)
+++ /gsdl/stable/micotest.cpp	(revision 20131)
@@ -0,0 +1,11 @@
+#include <iostream.h>
+#include <stdlib.h>
+#include <mico/version.h>
+
+char version[] = MICO_VERSION;
+
+int main()
+{
+  cout << version;
+  exit(0);
+}
Index: /gsdl/stable/perllib/ClassifyTreeModel.pm
===================================================================
--- /gsdl/stable/perllib/ClassifyTreeModel.pm	(revision 20131)
+++ /gsdl/stable/perllib/ClassifyTreeModel.pm	(revision 20131)
@@ -0,0 +1,255 @@
+package ClassifyTreeModel;
+
+use ClassifyTreeNode;
+use GDBMUtils;
+use strict;
+
+# /** Constructor
+#  *
+#  *  @param  $class       The name of the class to bless as a string
+#  *  @param  $collection  The name of the collection whose GDBM database we
+#  *                       will be accessing as a string
+#  *  @param  $root        The oid of the root node of the classifier as a
+#  *                       string
+#  *  @return A reference to the ClassifyTreeModel object
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub new()
+  {
+    my ($class, $collection, $root) = @_;
+    my $debug = 0;
+    print STDERR "ClassifyTreeModel.new(\"$collection\", \"$root\")\n" unless !$debug;
+    # Store the variables
+    my $self = {};
+    $self->{'collection'} = $collection;
+    $self->{'debug'} = $debug;
+    $self->{'root'} = $root;
+    # Bless me father for I have sinned
+    bless $self, $class;
+    return $self;
+  }
+# /** new() **/
+
+# /** Given a path and a document id, add this document to the classifier tree
+#  *  creating any necessary tree nodes first.
+#  *
+#  *  @param  $value The path to store this document in
+#  *  @param  $oid Unique identifier of a document
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub addDocument()
+  {
+    my ($self, $value, $oid) = @_;
+    print STDERR "ClassifyTreeModel.addDocument(\"$value\", \"$oid\")\n" unless !$self->{'debug'};
+    # Generate a treepath object from the metadata value, remembering to prefix
+    # with the root nodes path
+    my $root_node_obj = $self->getRootNode();
+    my $path_obj = $root_node_obj->getPath();
+    $path_obj->addPathComponent($value);
+    # Ensure that this classifier node, and if necessary its ancestor nodes,
+    # exist in our tree.
+    my $node_obj = $self->getNodeByPath($path_obj);
+    if (!$node_obj)
+      {
+        # The node doesn't exist, so we need to add it
+        $node_obj = $self->addNode($path_obj);
+      }
+    # Add the document to the node.
+    $node_obj->addDocument($oid);
+    # Done.
+  }
+# /** addDocument() **/
+
+# /** Add a node into the tree first ensuring all its parent nodes are inserted
+#  *  to.
+#  *
+#  *  @param  $path_obj The path to insert the new node at
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub addNode()
+  {
+    my ($self, $path_obj) = @_;
+    print STDERR "ClassifyTreeModel.addNode(\"" . $path_obj->toString() . "\")\n" unless !$self->{'debug'};
+    # Ensure the parent exists, assuming we aren't at the root
+    my $parent_path_obj = $path_obj->getParentPath();
+    #rint STDERR "* parent path: " . $parent_path_obj->toString() . "\n";
+    my $parent_node_obj = $self->getNodeByPath($parent_path_obj);
+    #rint STDERR "* does parent node already exist? " . $parent_node_obj . "\n";
+    #rint STDERR "* are we at the root node yet? " . $parent_path_obj->isRootPath() . "\n";
+    if (!$parent_node_obj && !$parent_path_obj->isRootPath())
+      {
+        #rint STDERR "* recursive call!\n";
+        $parent_node_obj = $self->addNode($parent_path_obj);
+      }
+    # Insert this node into it's parent.
+    return $parent_node_obj->insertNode($path_obj);
+  }
+# /** addNode() **/
+
+# /** Retrieve the name of the collection this model is drawing from.
+#  *
+#  *  @return The collection name as a string
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getCollection()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreeModel.getCollection()\n" unless !$self->{'debug'};
+    return $self->{'collection'};
+  }
+# /** getCollection() **/
+
+# /** Retrieve a node from this tree based upon its CLID (OID).
+#  *  @param  $clid  The CLID as a string
+#  *  @return The indicated ClassifyTreeNode or null
+sub getNodeByCLID()
+  {
+    my ($self, $clid) = @_;
+    print STDERR "ClassifyTreeModel.getNodeByCLID(\"$clid\")\n" unless !$self->{'debug'};
+    my $result = 0;
+    # Test if this clid is even in our tree
+    if($clid !~ /^$self->{'root'}/)
+      {
+        print STDERR "Requested node $clid, which isn't part of " . $self->{'root'} . "\n";
+        return 0;
+      }
+    # Unfortunately I have to check that there is text to retrieve before I
+    # create a new node.
+    if(&GDBMUtils::gdbmCachedCollectionGet($self->getCollection(), $clid) =~ /\w+/)
+      {
+        # Since the CLID can directly reference the correct entry in the GDBM we
+        # just create the node and return it
+        $result = new ClassifyTreeNode($self, $clid);
+      }
+    return $result;
+  }
+
+# /** Retrieve a node from this tree based upon a path
+#  *
+#  *  @param  $path  The path to the node as a ClassifyTreePath
+#  *  @return The indicated ClassifyTreeNode or null
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getNodeByPath()
+  {
+    my ($self, $path_obj) = @_;
+    print STDERR "ClassifyTreeModel.getNodeByPath(\"" . $path_obj->toString() . "\")\n" unless !$self->{'debug'};
+    # Starting at the ROOT of the tree, and with the first path component,
+    # recursively descend through the tree looking for the node - we can assume
+    # that we've found the root node (otherwise we won't be in a tree)
+    my $cur_node_obj = $self->getRootNode();
+    my $cur_path_obj = $cur_node_obj->getPath();
+    my $depth = 1;
+    # Continue till we either find the node we want, or run out a nodes
+    while(!$cur_node_obj->getPath()->equals($path_obj))
+      {
+        # Append the path component at this depth to the current path we
+        # are searching for
+        $cur_path_obj->addPathComponent($path_obj->getPathComponent($depth));
+        $depth++;
+        #rint STDERR "Searching " . $cur_node_obj->getPath()->toString() . "'s children for: " . $cur_path_obj->toString() . "\n";
+        # Search through the current nodes children, looking for one that
+        # matches the current path
+        my $found = 0;
+        foreach my $child_node_obj ($cur_node_obj->getChildren())
+          {
+            #rint STDERR "* testing " . $child_node_obj->getPath()->toString() . "\n";
+            if($child_node_obj->getPath()->equals($cur_path_obj))
+              {
+                $cur_node_obj = $child_node_obj;
+                $found = 1;
+                last;
+              }
+          }
+        # Couldn't find any node with this path
+        if(!$found)
+          {
+            #rint STDERR "* no such node exists!\n";
+            return 0;
+          }
+      }
+    return $cur_node_obj;
+  }
+# /** getChild() **/
+
+# /** Retrieve the parent node of the given node.
+#  *
+#  *  @param  $child_node The node whose parent we want to retrieve
+#  *  @return The parent node, or 0 if this is the root
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getParentNode()
+  {
+    my ($self, $child_node) = @_;
+    print STDERR "ClassifyTreeModel.getParentNode()\n" unless !$self->{'debug'};
+    return $child_node->getParentNode();
+  }
+# /** getParentNode() **/
+
+sub getRootNode()
+{
+  my ($self) = @_;
+  print STDERR "ClassifyTreeModel.getRootNode()\n" unless !$self->{'debug'};
+  return new ClassifyTreeNode($self, $self->{'root'});
+}
+
+# /** Remove the given document from the classifier tree, and then remove any
+#  *  empty nodes if required.
+#  *
+#  *  @param  $value The value which contains the path of the node to remove
+#  *                 the document from
+#  *  @param  $oid The unique identifier of the document to remove
+#  *  @param  $remove_empty Sets whether empty nodes are removed
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub removeDocument()
+  {
+    my ($self, $path, $oid, $remove_empty) = @_;
+    print STDERR "ClassifyTreeModel.removeDocument(\"$path\",\"$oid\",$remove_empty)\n" unless !$self->{'debug'};
+    # Append to root path
+    my $root_node_obj = $self->getRootNode();
+    my $path_obj = $root_node_obj->getPath();
+    $path_obj->addPathComponent($path);
+    # Retrieve the node in question
+    my $node_obj = $self->getNodeByPath($path_obj);
+    # Check we retrieved a node
+    if ($node_obj)
+      {
+        # Remove the document
+        $node_obj->removeDocument($oid);
+        # If we have been asked to remove empty nodes, do so now.
+        if ($remove_empty)
+          {
+            my $cur_node_obj = $node_obj;
+            my $empty_node_obj = 0;
+            while ($cur_node_obj->getNumLeafDocs() == 0)
+              {
+                $empty_node_obj = $cur_node_obj;
+                $cur_node_obj = $cur_node_obj->getParentNode();
+              }
+            if ($empty_node_obj)
+              {
+                # Try to retrieve the parent of this node
+                my $parent_node_obj = $empty_node_obj->getParentNode();
+                # As long as we have a parent (i.e. we aren't the root node) go
+                # ahead and delete this subtree starting at empty node
+                if ($parent_node_obj)
+                  {
+                    $parent_node_obj->removeNode($empty_node_obj);
+                  }
+              }
+          }
+      }
+    # If the node doesn't exist in this tree, then we can't very well remove
+    # anything from it!
+  }
+# /** removeDocument() **/
+
+1;
Index: /gsdl/stable/perllib/ClassifyTreeNode.pm
===================================================================
--- /gsdl/stable/perllib/ClassifyTreeNode.pm	(revision 20131)
+++ /gsdl/stable/perllib/ClassifyTreeNode.pm	(revision 20131)
@@ -0,0 +1,704 @@
+package ClassifyTreeNode;
+
+use ClassifyTreeNode;
+use ClassifyTreePath;
+use GDBMUtils;
+use strict;
+
+# /** Constructor
+#  *
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub new()
+  {
+    my ($class, $model, $clid, $force_new) = @_;
+    my $debug = 0;
+    $force_new = 0 unless defined($force_new);
+    print STDERR "ClassifyTreeNode.new(model, \"$clid\", $force_new)\n" unless !$debug;
+    $force_new = 0 unless defined($force_new);
+    # Test the parameters
+    die("Can't create a tree node that doesn't belong to a tree model!") unless $model;
+    die("Can't create a tree node that doesn't have a unique id (OID)!") unless $clid;
+    # Store the variables
+    my $self = {};
+    $self->{'debug'} = $debug;
+    $self->{'model'} = $model;
+    $self->{'clid'} = $clid;
+
+    my $collection = $model->getCollection();
+
+    # Check if this node already exists in the database, and if not insert it
+    # now
+    my $text = &GDBMUtils::gdbmCachedCollectionGet($collection, $clid);
+    if($text !~ /\w+/ && $force_new)
+      {
+        &GDBMUtils::gdbmCachedCollectionSet($collection, $clid,
+                            "<doctype>classify\n<hastxt>0\n<childtype>VList\n<Title>\n<numleafdocs>0\n<contains>\n");
+      }
+    # Bless me father for I have sinned
+    bless $self, $class;
+    return $self;
+  }
+# /** new() **/
+
+# /** Add a document to this tree node.
+#  *
+#  *  @param  $oid The unique identifier of the document to add
+#  *
+#  *  @author John Thompson, DL Consulting Ltd
+#  */
+sub addDocument()
+  {
+    my ($self, $oid) = @_;
+    print STDERR "ClassifyTreeNode.addDocument(\"$oid\")\n" unless !$self->{'debug'};
+    # Get the current contains list
+    my $contains = $self->getContains();
+    # See whether this document already exists in the contains
+    if ($contains !~ /(^$oid$|^$oid;$|;$oid;|;$oid$)/)
+      {
+        # If not, append to the contains list
+        if ($contains ne "")
+          {
+            $contains .= ";$oid";
+          }
+        else
+          {
+            $contains = $oid;
+          }
+        # Store the changed contains
+        $self->setContains($contains);
+        # We now have to update the numleafdocs count for this node and its
+        # ancestor nodes
+        my $cur_node_obj = $self;
+        while ($cur_node_obj)
+          {
+            my $numleafdocs = $cur_node_obj->getNumLeafDocs();
+            if ($numleafdocs =~ /^\d+$/)
+              {
+                $numleafdocs ++;
+              }
+            else
+              {
+                $numleafdocs = 1;
+              }
+            $cur_node_obj->setNumLeafDocs($numleafdocs);
+            $cur_node_obj = $cur_node_obj->getParentNode();
+          }
+      }
+    else
+      {
+        print STDERR "Document already exists!\n" unless !$self->{'debug'};
+      }
+  }
+# /** addDocument() **/
+
+# /** Changes the CLID of a particular node. Note that this is significantly
+#  *  tricky step, as we have to remove the old node from the database, and
+#  *  then readd with the corrected CLID.
+#  *
+#  *  @param  $clid The new CLID as an integer
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub changeCLID()
+  {
+    my($self, $new_clid) = @_;
+    print STDERR "ClassifyTreeNode.changeCLID(\"$new_clid\")\n" unless !$self->{'debug'};
+    # Store the current clid for later use
+    my $old_clid = $self->{'clid'};
+    # And record the children now, as they'll change after we shift the parent
+    # CLID
+    my @child_nodes = $self->getChildren();
+
+    # Retrieve the current document
+    my $text = $self->toString();
+
+    my $collection = $self->{'model'}->getCollection();
+
+    # Create a new document with the correct CLID
+    &GDBMUtils::gdbmCachedCollectionSet($collection, $new_clid, $text);
+
+    # Remove the old document
+    &GDBMUtils::gdbmCachedCollectionSet($collection, $self->{'clid'});
+
+    # Finally, change the clid stored in this document
+    $self->{'clid'} = $new_clid;
+
+    # Now go through this nodes children, and shift them too
+    foreach my $child_node (@child_nodes)
+      {
+        # We determine the new clid by retrieving the childs current clid,
+        # and then replacing any occurance to the parents old clid with the
+        # parents new clid
+        my $old_child_clid = $child_node->getCLID();
+        #rint STDERR "* considering: " . $old_child_clid . "\n";
+        if($old_child_clid =~ /^CL/)
+          {
+            my $new_child_clid = $new_clid . substr($old_child_clid, length($old_clid));
+            #rint STDERR "* shifting child $old_child_clid to $new_child_clid\n";
+            $child_node->changeCLID($new_child_clid);
+          }
+      }
+  }
+# /** changeCLID() **/
+
+
+# /** Retrieve the unique id for this classifier.
+#  *
+#  *  @return The CLID as a string
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getCLID()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreeNode.getCLID()\n" unless !$self->{'debug'};
+    return $self->{'clid'};
+  }
+
+# /** Return the child objects of this node an as array.
+#  *
+#  *  @return An array of node objects
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getChildren()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreeNode.getChildren()\n" unless !$self->{'debug'};
+    my $text = $self->toString();
+    my @children = ();
+    # Retrieve the contains metadata item
+    if($text =~ /<contains>(.*?)\r?\n/)
+      {
+        #rint STDERR "* children formed from contains: $1\n";
+        my $contains_raw = $1;
+        my @contains = split(/;/, $contains_raw);
+        foreach my $child_clid (@contains)
+          {
+            # Replace the " with the parent clid
+            $child_clid =~ s/\"/$self->{'clid'}/;
+            # Create the node obj
+            my $child_node_obj = new ClassifyTreeNode($self->{'model'}, $child_clid);
+            # And insert into ever growing array of child nodes
+            push(@children, $child_node_obj);
+          }
+      }
+    return @children;
+  }
+# /** getChildren() **/
+
+# /** Retrieve the contains metadata which is used to determine this nodes
+#  *  children.
+#  *
+#  *  @return The contains metadata as a string
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getContains()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreeNode.getContains()\n" unless !$self->{'debug'};
+    my $result = 0;
+    my $text = $self->toString();
+    if($text =~ /<contains>(.*?)\r?\n/)
+      {
+        $result = $1;
+        # Replace " with this nodes CLID
+        $result =~ s/\"/$self->{'clid'}/g;
+      }
+    return $result;
+  }
+# /** getContains() **/
+
+# /** Retrieve this nodes next sibling.
+#  *
+#  *  @return The next sibling node object or 0 if no such node
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getNextSibling()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreeNode.getNextSibling()\n" unless !$self->{'debug'};
+    my $sibling_node = 0;
+    # The next sibling would be the node identified by the CLID with its
+    # suffix number one greater than this nodes CLID.
+    my @clid_parts = split(/\./, $self->{'clid'});
+    my $suffix = pop(@clid_parts);
+    $suffix++;
+    push(@clid_parts, $suffix);
+    my $next_clid = join(".", @clid_parts);
+
+    my $collection = $self->{'model'}->getCollection();
+
+    # Now determine if this node exists.
+    if(&GDBMUtils::gdbmCachedCollectionGet($collection, $next_clid) =~ /\w+/)
+      {
+        # And if so, create it.
+        $sibling_node = new ClassifyTreeNode($self->{'model'}, $next_clid);
+      }
+    # Done
+    return $sibling_node;
+  }
+# /** getNextSibling() **/
+
+# /** Retrieve the numleafdocs metadata which if affected by any changes to
+#  *  child nodes.
+#  *
+#  *  @return The numleafdocs as an integer
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getNumLeafDocs()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreeNode.getNumLeafDocs()\n" unless !$self->{'debug'};
+    my $result = 0;
+    my $text = $self->toString();
+    if($text =~ /<numleafdocs>(\d*?)\r?\n/)
+      {
+        $result = $1;
+      }
+    return $result;
+  }
+# /** getNumLeafDocs() **/
+
+# /** Retrieve the parent node of the given node.
+#  *
+#  *  @param  $child_node The node whose parent we want to retrieve
+#  *  @return The parent node, or 0 if this is the root
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getParentNode()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreeNode.getParentNode()\n" unless !$self->{'debug'};
+    my $parent_node = 0;
+    my $child_clid = $self->getCLID();
+    my @clid_parts = split(/\./, $child_clid);
+    if(scalar(@clid_parts) > 1)
+      {
+        pop(@clid_parts);
+        my $parent_clid = join(".", @clid_parts);
+        $parent_node = $self->{'model'}->getNodeByCLID($parent_clid);
+      }
+    # Otherwise we are already at the root node
+    return $parent_node;
+  }
+# /** getParentNode() **/
+
+# /** Retrieve the path to this node.
+#  *
+#  *  @return The path obj which represents the path to this node or 0 if no
+#  *          path information exists
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getPath()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreeNode.getPath()\n" unless !$self->{'debug'};
+    my $result = 0;
+    my $text = $self->toString();
+    if($text =~ /<Title>(.*?)\r?\n/ )
+      {
+        my $this_component = $1;
+        # If this node has a parent, then retrieve its path
+        my $parent_node = $self->getParentNode();
+        if ($parent_node)
+          {
+            # Get the path...
+            $result = $parent_node->getPath();
+            # ... and add our component
+            $result->addPathComponent($this_component);
+          }
+        else
+          {
+            $result = new ClassifyTreePath($this_component);
+          }
+      }
+    return $result;
+  }
+# /** getPath() **/
+
+# /** Retrieve the title of this node. This returns essentially the same
+#  *  information as getPath, but without the encapsulating object.
+#  *
+#  *  @return The title as a string
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getTitle()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreeNode.getTitle()\n" unless !$self->{'debug'};
+    my $result = 0;
+    my $text = $self->toString();
+    if($text =~ /<Title>(.*?)\r?\n/)
+      {
+        $result = $1;
+      }
+    return $result;
+  }
+# /** getTitle() **/
+
+# /** Using the given value locate the correct position to insert a new node,
+#  *  create it, and then establish it in the database.
+#  *
+#  *  @param  $path The path used to determine where to insert node as a string
+#  *  @return The newly inserted node object
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub insertNode()
+  {
+    my ($self, $path) = @_;
+    print STDERR "ClassifyTreeNode.insertNode(\"$path\")\n" unless !$self->{'debug'};
+    my $child_clid = "";
+    my $child_node = 0;
+    my $new_contains = "";
+    # Get the children of this node
+    my @children = $self->getChildren();
+    # If there are no current children, then this will be the first
+    if (scalar(@children) == 0)
+      {
+        #rint STDERR "ClassifyTreeNode.insertNode: first child!\n";
+        $child_clid = $self->{'clid'} . ".1"; # First child
+        # Contains needs to have this new clid added
+        $new_contains = $child_clid;
+      }
+    # Otherwise search through the current children, looking at their values
+    # to locate where to insert this node.
+    else
+      {
+        #rint STDERR "ClassifyTreeNode.insertNode: searching for position...\n";
+        my $found = 0;
+        my $offset = 1;
+        foreach my $sibling_node (@children)
+          {
+            my $sibling_path = $sibling_node->getPath();
+            # If we are still searching for the insertion point
+            if(!$found)
+              {
+                if($sibling_path->toString() eq $path->toString())
+                  {
+                    # What?!? This node already exists! why are we adding it again!
+                    print STDERR "ClassifyTreeNode.insertNode: what?!? node already exists... how did we get here?\n";
+                    return $sibling_node;
+                  }
+                elsif($sibling_path->toString() gt $path->toString())
+                  {
+                    # Found our location!
+                    $found = 1;
+                    $child_clid = $self->{'clid'} . "." . $offset;
+                    # You may notice we haven't added this node to contains.
+                    # This is because the parent node already contains this
+                    # clid - instead we need to record the new highest clid
+                    # created when we move the sibling nodes for here onwards
+                    # up one space.
+                    #rint STDERR "ClassifyTreeNode.insertNode: found our location: $child_clid \n";
+                    last;
+                  }
+              }
+            $offset++;
+          }
+        # If we haven't found the node, we insert at the end.
+        if(!$found)
+          {
+            #rint STDERR "ClassifyTreeNode.insertNode not found... insert at end \n";
+            $child_clid = $self->{'clid'} . "." . $offset;
+            # Contains needs to have this new clid added
+            $new_contains = $child_clid;
+          }
+        # If we did find the node, we now have to go through the sibling nodes
+        # shifting them up one CLID to ensure there's space.
+        else
+          {
+            # We need another copy of children, but this time with the last 
+            # children first!
+            @children = reverse $self->getChildren();
+            my $offset2 = scalar(@children) + 1;
+            foreach my $sibling_node (@children)
+              {
+                $sibling_node->changeCLID($self->{'clid'} . "." . $offset2);
+                # If this if the highest sibling node we are going to rename,
+                # then use it to set the contains metadata.
+                if($new_contains !~ /\w+/)
+                  {
+                    $new_contains = $self->{'clid'} . "." . $offset2;
+                  }
+                # Once we've processed the node exactly in the space the new
+                # node will occupy, we're done.
+                $offset2--;
+                if($offset2 == $offset)
+                  {
+                    last;
+                  }
+              }
+          }
+      }
+    $child_node = new ClassifyTreeNode($self->{'model'}, $child_clid, 1);
+    # Set the value, as this is the only piece of metadata we know and care
+    # about at this stage
+    $child_node->setTitle($path->getLastPathComponent());
+    # Update the contains metadata for this node
+    my $contains = $self->getContains();
+    if($contains =~ /\w/)
+      {
+        $contains .= ";" . $new_contains;
+      }
+    else
+      {
+        $contains = $new_contains;
+      }
+    $self->setContains($contains);
+    # And return the node
+    return $child_node;
+  }
+# /** insertNode() **/
+
+# /** Remove all the children of this node and return the number of document
+#  *  references (leaf nodes) removed by this process.
+#  *
+#  *  @return The count of document references removed as an integer
+#  *
+#  *  @author John Thompson, DL Consulting Ltd
+#  */
+sub removeAllNodes()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreeNode.removeAllNodes()\n" unless !$self->{'debug'};
+    my $num_leaf_docs = 0;
+    # Recursively remove this nodes children
+    my @children = $self->getChildren();
+    foreach my $child_node (@children)
+      {
+        $child_node->removeAllNodes();
+      }
+    # Retrieve the document count (leaf docs)
+    my $text = $self->toString();
+    if ($text =~ /<numleafdocs>(\d+)/)
+      {
+        $num_leaf_docs += $1;
+      }
+    # Now remove the node from the database. We do this calling set gdbm with
+    # no value argument.
+    my $collection = $self->{'model'}->getCollection();
+    &GDBMUtils::gdbmCachedCollectionSet($collection, $self->{'clid'});
+
+    # Return the leaf count (so we can adjust the numleafdocs at the root node
+    # of this deletion.
+    return $num_leaf_docs;
+  }
+# /** removeAllNodes() **/
+
+# /** Remove the given document this node, and then update the numleafdocs
+#  *  metadata for all the ancestor nodes.
+#  *
+#  *  @param  $oid The unique identifier of a greenstone document
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub removeDocument()
+  {
+    my ($self, $oid) = @_;
+    print STDERR "ClassifyTreeNode::removeDocument(\"$oid\")\n" unless !$self->{'debug'};
+    # Retrieve the contains metadata
+    my $contains = $self->getContains();
+    # Remove this oid
+    my @contains_parts = split(/;/, $contains);
+    my @new_contains_parts = ();
+    foreach my $oid_or_clid (@contains_parts)
+      {
+        if ($oid ne $oid_or_clid && $oid_or_clid =~ /[\w\d]+/)
+          {
+            push(@new_contains_parts, $oid_or_clid);
+          }
+      }
+    $contains = join(";", @new_contains_parts);
+    $self->setContains($contains);
+    # We now have to update the numleafdocs count for this node and its
+    # ancestor nodes
+    my $cur_node_obj = $self;
+    while ($cur_node_obj)
+      {
+        my $numleafdocs = $cur_node_obj->getNumLeafDocs();
+        if ($numleafdocs =~ /^\d+$/)
+          {
+            $numleafdocs--;
+          }
+        else
+          {
+            $numleafdocs = 0;
+          }
+        $cur_node_obj->setNumLeafDocs($numleafdocs);
+        $cur_node_obj = $cur_node_obj->getParentNode();
+      }
+    # Done
+  }
+# /** removeDocument() **/
+
+# /** Remove the node denoted by the path.
+#  *
+#  *  @param  $child_node The node to be removed
+#  *
+#  *  @author John Thompson, DL Consulting Ltd
+#  */
+sub removeNode()
+  {
+    my ($self, $child_node) = @_;
+    # Not as easy as it first sounds as we have to do a recursive remove,
+    # keeping track of any documents removed so we can update document count.
+    # We then remove this node, adjusting the sibling's clid's as necessary
+    # before altering the contains.
+    print STDERR "ClassifyTreeNode::removeNode(child_node)\n" unless !$self->{'debug'};
+    my $remove_clid = $child_node->getCLID();
+    my $sibling_node = $child_node->getNextSibling();
+    # Recursively remove this nodes and its children, taking note of decrease
+    # in document count.
+    my $removed_numleafdocs = $child_node->removeAllNodes();
+    # Determine if removing this node requires other nodes to be moved, and if
+    # so, do so. We do this in a repeating loop until there are no further
+    # siblings, overwriting the $remove_clid variable with the clid of the node
+    # just changed (you'll see why in a moment).
+    while ($sibling_node != 0)
+      {
+        my $current_node = $sibling_node;
+        # Get this nodes sibling
+        $sibling_node = $current_node->getNextSibling();
+        # Record the CLID to change to
+        my $new_clid = $remove_clid;
+        # Record the old clid
+        $remove_clid = $current_node->getCLID();
+        # Modify the clid of the current node
+        $current_node->changeCLID($new_clid);
+        # Continue until there are no further sibling nodes
+      }
+    # By now the $remove_clid will contain the CLID that has to be removed from
+    # the contains metadata for this node
+    my $contains = $self->getContains();
+    my @contains_parts = split(/;/, $contains);
+    my @new_contains_parts = ();
+    foreach my $oid_or_clid (@contains_parts)
+      {
+        if ($remove_clid ne $oid_or_clid && $oid_or_clid =~ /[\w\d]+/)
+          {
+            push(@new_contains_parts, $oid_or_clid);
+          }
+      }
+    $contains = join(";", @new_contains_parts);
+    $self->setContains($contains);
+    # We also alter the numleafdocs metadata to reflect the removal of these
+    # nodes.
+    my $numleafdocs = $self->getNumLeafDocs();
+    if ($numleafdocs =~ /^\d+$/)
+      {
+        $numleafdocs -= $removed_numleafdocs;
+      }
+    else
+      {
+        $numleafdocs = 0;
+      }
+    $self->setNumLeafDocs($numleafdocs);
+    # Done
+  }
+# /** removeNode() **/
+
+# /** Set the contains metadata in the database.
+#  *
+#  *  @param  $contains The new contains string
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub setContains()
+  {
+    my ($self, $contains) = @_;
+    print STDERR "ClassifyTreeNode::setContains(\"$contains\")\n" unless !$self->{'debug'};
+    # Replace any occurance of this nodes CLID with "
+    $contains =~ s/$self->{'clid'}/\"/g;
+
+    my $collection = $self->{'model'}->getCollection();
+    my $clid = $self->{'clid'};
+
+    # Load the text of this node
+    my $text = &GDBMUtils::gdbmCachedCollectionGet($collection, $clid);
+
+    # Replace the contains
+    #rint STDERR "Before: $text\n";
+    $text =~ s/<contains>.*?\n+/<contains>$contains\n/;
+    #rint STDERR "After:  $text\n";
+    # Store the changed text
+    &GDBMUtils::gdbmCachedCollectionSet($collection, $clid, $text);
+  }
+# /** setContains() **/
+
+# /** Set the numleafdocs metadata in the database.
+#  *
+#  *  @param  $numleafdocs The new count of leaf documents
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub setNumLeafDocs()
+  {
+    my ($self, $numleafdocs) = @_;
+    print STDERR "ClassifyTreeNode::setNumLeafDocs(numleafdocs)\n" unless !$self->{'debug'};
+
+    my $collection = $self->{'model'}->getCollection();
+    my $clid = $self->{'clid'};
+
+    # Load the text of this node
+    my $text = &GDBMUtils::gdbmCachedCollectionGet($collection, $clid);
+    # Replace the numleafdocs
+    $text =~ s/<numleafdocs>\d*?\n+/<numleafdocs>$numleafdocs\n/;
+    # Store the changed text
+    &GDBMUtils::gdbmCachedCollectionSet($collection, $clid, $text);
+  }
+# /** setNumLeafDocs() **/
+
+# /** Set the title metadata in the database.
+#  *  Note: Previously this was value and we extracted the title, but the new
+#  *        autohierarchies don't set values.
+#  *
+#  *  @param  $title The new title string
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub setTitle()
+  {
+    my ($self, $title) = @_;
+    print STDERR "ClassifyTreeNode::setTitle(\"$title\")\n" unless !$self->{'debug'};
+
+    my $collection = $self->{'model'}->getCollection();
+    my $clid = $self->{'clid'};
+
+    # Load the text of this node
+    my $text = &GDBMUtils::gdbmCachedCollectionGet($collection, $clid);
+    # Replace the title
+    $text =~ s/<Title>.*?\n+/<Title>$title\n/;
+    # Store the changed text
+    &GDBMUtils::gdbmCachedCollectionSet($collection, $clid, $text);
+  }
+# /** setValue() **/
+
+# /** Represent this node as a string.
+#  *
+#  * @return The string representation of this node
+#  *
+#  * @author John Thompson, DL Consulting Ltd.
+#  */
+sub toString()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreeNode::toString()\n" unless !$self->{'debug'};
+    my $collection = $self->{'model'}->getCollection();
+    my $clid = $self->{'clid'};
+
+    my $text = &GDBMUtils::gdbmCachedCollectionGet($collection, $clid);
+    return $text;
+  }
+# /** toString() **/
+
+1;
Index: /gsdl/stable/perllib/ClassifyTreePath.pm
===================================================================
--- /gsdl/stable/perllib/ClassifyTreePath.pm	(revision 20131)
+++ /gsdl/stable/perllib/ClassifyTreePath.pm	(revision 20131)
@@ -0,0 +1,168 @@
+package ClassifyTreePath;
+
+use strict;
+
+
+# /** Construct a new tree path object based on the given value path.
+#  *
+#  *  @param  $class  The name of the class to bless as a string
+#  *  @param  $path   The path as a pip delimited string
+#  *  @return A reference to the ClassifyTreePath object
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub new()
+  {
+    my ($class, $path) = @_;
+    my $debug = 0;
+    print STDERR "ClassifyTreePath.new(\"$path\")\n" unless !$debug;
+    # Store the variables
+    my $self = {};
+    $self->{'debug'} = $debug;
+    $self->{'path'} = $path;
+    # Bless me father for I have sinned
+    bless $self, $class;
+    return $self;
+  }
+# /** new() **/
+
+# /** Adds a new path component on to the end of the current path.
+#  *
+#  *  @param  $component The new component to add as a string
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub addPathComponent()
+  {
+    my ($self, $component) = @_;
+    print STDERR "ClassifyTreePath.addPathComponent(\"$component\")\n" unless !$self->{'debug'};
+    if($self->{'path'} =~ /\w+/)
+      {
+        $self->{'path'} .= "|" . $component;
+      }
+    else
+      {
+        $self->{'path'} = $component;
+      }
+  }
+# /** addPathComponent() **/
+
+# /** Compare this path against another for equality.
+#  *
+#  *  @param  $other_path_obj The path object to compare to
+#  *  @return 1 if the paths match, 0 otherwise
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub equals()
+  {
+    my ($self, $other_path_obj) = @_;
+    print STDERR "ClassifyTreePath.equals()\n" unless !$self->{'debug'};
+    return $self->{'path'} eq $other_path_obj->toString();
+  }
+# /** equals() **/
+
+# /** Extracts the first path component from the path.
+#  *
+#  * @return The first path component as a string
+#  *
+#  * @author John Thompson, DL Consulting Ltd.
+#  */
+sub getFirstPathComponent()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreePath.getFirstPathComponent()\n" unless !$self->{'debug'};
+    my @path = split(/\|/, $self->{'path'});
+    return $path[0];
+  }
+# /** getFirstPathComponent() **/
+
+# /** Extracts the last path component from the path.
+#  *
+#  * @return The last path component as a string
+#  *
+#  * @author John Thompson, DL Consulting Ltd.
+#  */
+sub getLastPathComponent()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreePath.getLastPathComponent()\n" unless !$self->{'debug'};
+    my @path = split(/\|/, $self->{'path'});
+    return @path[scalar(@path) - 1];
+  }
+# /** getLastPathComponent() **/
+
+# /** Return a path object which is the parent path of this one.
+#  *
+#  * @return The parent path object
+#  *
+#  * @author John Thompson, DL Consulting Ltd.
+#  */
+sub getParentPath()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreePath.getParentPath()\n" unless !$self->{'debug'};
+    my $result = 0;
+    my @path = split(/\|/, $self->{'path'});
+    if (scalar(@path) > 0)
+      {
+        pop(@path);
+        $result = new ClassifyTreePath(join("|", @path));
+      }
+    return $result;
+  }
+# /** getParentPath() **/
+
+# /** Retrieves the path component located at the indicated index.
+#  *
+#  *  @param  $index  The index of the component as an integer
+#  *  @return The component as a string, or 0 if index out of range
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getPathComponent()
+  {
+    my ($self, $index) = @_;
+    print STDERR "ClassifyTreePath.getPathComponent($index)\n" unless !$self->{'debug'};
+    my $result = 0;
+    my @path = split(/\|/, $self->{'path'});
+    # Check index is in range
+    if(0 <= $index && $index < scalar(@path))
+      {
+        $result = $path[$index];
+      }
+    return $result;
+  }
+# /** getPathComponent() **/
+
+# /** Determine is this path is the root node one - which it must be if it has
+#  *  one or fewer path components.
+#  *
+#  *  @return true if this is the root path, false otherwise
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub isRootPath()
+  {
+    my ($self, $index) = @_;
+    print STDERR "ClassifyTreePath.isRootPath()\n" unless !$self->{'debug'};
+    my @path = split(/\|/, $self->{'path'});
+    return (scalar(@path) <= 1);
+  }
+# /** isRootPath() **/
+
+# /** Represent this path as a string.
+#  *
+#  * @return The string representation of this path
+#  *
+#  * @author John Thompson, DL Consulting Ltd.
+#  */
+sub toString()
+  {
+    my ($self) = @_;
+    print STDERR "ClassifyTreePath.toString()\n" unless !$self->{'debug'};
+    return $self->{'path'};
+  }
+# /** toString() **/
+
+1;
Index: /gsdl/stable/perllib/DateExtract.pm
===================================================================
--- /gsdl/stable/perllib/DateExtract.pm	(revision 20131)
+++ /gsdl/stable/perllib/DateExtract.pm	(revision 20131)
@@ -0,0 +1,278 @@
+package DateExtract;
+
+##use BasPlug; ## no, DON'T use BasPlug, BasPlug uses us....
+use sorttools;
+use strict;
+use util;
+
+#75% of the instances of the word century use full name ordinals
+my %ordinals = ("first" => 1, "second" => 2, "third" => 3, "fourth" => 4,
+             "fifth" => 5, "sixth" => 6, "seventh" => 7, "eighth" => 8,
+             "ninth" => 9, "tenth" => 10, "eleventh" => 11, "twelfth" => 12,
+             "thirteenth" => 13, "fourteenth" => 14, "fifteenth" => 15,
+             "sixteenth" => 16, "seventeenth" => 17, "eighteenth" => 18,
+             "nineteenth" => 19, "twentieth" => 20);
+
+
+             
+
+#definitions for a date grammar.
+my $fulOrd = join('|',(keys %ordinals));
+
+my @months = ("january","february","march","april","may","june","july",
+              "august","september","october","november","december");
+
+my $shortmth = "";
+foreach my $m (@months) { $shortmth .= (substr($m,0,3)."\\.?|"); }
+chop($shortmth);
+
+my $longmth = join('|',@months);
+
+
+my $Qualifier = "(B(\\.)?C(\\.)?(E(\\.)?)?)|(A(\\.)?D(\\.)?)|(C(\\.)E(\\.)?)";
+my $Century = "Cent(\\.|ur(y|ies))";
+my $Ord = "st|nd|rd|th";
+my $seasonref = "(spring|fall|autumn|winter|summer)";
+my $sep = " ?- ?";
+my $tri_digit = "(in|since|(the year)|($seasonref of)) \\d{3}\\D( ($Qualifier))?";
+my $centurydate = "(((\\d{1,2})($Ord))|($fulOrd)) ($Century)( ($Qualifier))?";
+my $qualified = "(($Qualifier) ?(\\d{1,4}))|((\\d{1,4}) ?($Qualifier))";
+my $millenium = "[1-9]\\d{3}";
+my $range = "(($millenium)($sep)($millenium))|(($millenium)($sep)(\\d{1,2}))|(($qualified)($sep)($qualified))|(($Qualifier) ?(\\d{1,3})($sep)(\\d{1,3}))|((\\d{1,3})($sep)(\\d{1,3}) ?($Qualifier))";
+
+my $pgnum = "(p(p|g)?\\.? ?\\d+((-|,)(\\d+))?)|(page \\d+)|(pages \\d+((-|,)(\\d+))?)";
+my $lgnum = "\\d{1,3},(\\d{3})+";
+my $colon = ":\\d+";
+my $money = "\$(\\d{1,3}(((,\\d{3})+)|\\d+))";  $money = "\\" . $money; 
+my $microfilm = " reel([^\\.\\)])*(\\.|\\))";
+my $lastaltered = "last (edited|updated)";
+my $references = "reference(s?)(:?)\\n";
+my $cited = "work(s?) cited";
+my $biblio = "bibliography(:?)( ?)\\n";
+
+my $direction = "(N(\\.|o\\.|th\\.|orth))|(S(\\.|th\\.|outh))|(E(\\.|ast))|(W(\\.|est))";
+my $street_id = "(st\\.)|(street[^A-Za-z])|(ave\\.)|(avenue[^A-Za-z])|(boulevard[^A-Za-z])|(blvd\\.)|(rd\\.)|(road[^A-Za-z])";
+my $streetname = "(\\d{1,2}(<SUP>)?($Ord)(</SUP>)?)|([A-Za-z]+( [A-Za-z]+)?)|([A-Za-z]+-[A-Za-z]+($Ord))";
+my $address = "\\d{1,4} (($direction) )?($streetname) ($street_id)";
+
+my $bracket = "\\($millenium\\)";
+my $ref_end = ", ?$millenium\\)";
+my $colonsp = ": $millenium";
+my $reprint = "[Rr]eprint of \\d{4} edition";
+my $comma = ", $millenium\\.";
+my $fullstop = "\\. $millenium\\.";
+my $semi = "; $millenium\\.";
+
+my $lookalikes = "($pgnum)|($lgnum)|($colon)|($money)|($microfilm)|($address)";
+my $spurious = "($lastaltered)";
+my $bibheader = "($references)|($cited)|($biblio)";
+
+
+sub get_date_metadata {
+    #get the text of the document, the "document object" concerned,
+    #and the current section within the document
+    my ($text, $doc, $cursection, $keep_bib, $max_year, $max_century) = @_;
+    
+    #format a prechristian maximum century value to be negative so that it can
+    #be used in numeric comparison
+    if($max_century =~ /B/)
+    {
+        $max_century = $`;
+        $max_century =~ /\d+/;
+        $max_century = $&;
+        $max_century *=-1
+    }
+   
+    my $extr = &remove_excess($text);    
+    #print "EXTRACTION TEXT:\n $extr";
+    $extr = &remove_tags($extr);
+    if(!$keep_bib){
+        $extr = &remove_biblio($extr);
+    }
+  
+
+    my @datelist = ();
+    while($extr =~ m!($range)|($millenium)|($qualified)|($centurydate)|($tri_digit)!i)
+    { 
+        $extr = $';
+        my $fulldate = $&;
+        if ($fulldate =~ /$centurydate/i)
+        {
+            if($max_century!=-1)
+            {
+
+                my $date = $fulldate; if($date =~ /\d+/) {$date = $&;} 
+                else 
+                {
+                    $date=$fulldate; $date =~ m! ($Century)!i; $date = $`;
+                    $date =~ tr/A-Z/a-z/;
+                    $date = $ordinals{$date};
+                }
+                if($max_century >= $date){
+                    $date = ($date-1)*100 +1;
+                    #if it BC, make it negative
+                    $date = &convert_bc($fulldate,$date);
+                    my $end = $date + 99; 
+                    my @century = ($date..$end);
+                    @datelist = (@datelist,@century);
+                }
+            }
+        }
+        
+        elsif($fulldate =~ /$range/)
+        {
+            $fulldate =~ /$sep/;
+            my @addlist = ();
+            #print "Range: $fulldate\n";
+            my $fullfirst = $`; 
+            my $fullsecond = $'; 
+            $fullfirst =~ /\d+/;
+	    my $first = $&; 
+            $fullsecond =~ /\d+/;
+	    my $second = $&;
+            my $len1 = length($first);
+            my $len2 = length($second);
+            $second = (substr($first,0,($len1-$len2))).$second;
+            $first = &convert_bc($fullfirst,$first);
+            $second = &convert_bc($fullsecond,$second);
+            @addlist = ($first..$second);
+            @datelist = (@datelist,@addlist);
+            
+        }
+        else {
+            
+            my $date = $fulldate; $date =~ /\d+/; $date = $&;  
+            $date = &convert_bc($fulldate,$date);
+            #add the date metadata
+            push(@datelist,$date);
+            #print "datelist @datelist\n"
+        }
+        
+    }
+    
+    if(@datelist){
+        @datelist = sort { $a <=> $b } @datelist;
+        @datelist = &post_process($max_year, @datelist);
+        foreach my $date (@datelist)
+        {
+            if($date>0){
+                $doc->add_metadata($cursection,"Coverage",$date);}
+            else{
+                $doc->add_metadata($cursection,"Coverage","bc".(-1*$date));}
+                
+        }
+    }
+}
+sub convert_bc {
+    my ($full,$num) = @_;
+    if ($full =~ /B/) { $num *= -1; }
+    $num;
+}
+
+sub post_process {
+    my ($max_year, @list) = @_;
+    my @cleanlist = ();
+    my $prev = 0;
+    foreach my $e (@list) {
+        if ($e!=$prev && $e <= $max_year) {
+            push(@cleanlist, $e);
+        }
+        $prev = $e;
+    }
+    @cleanlist;
+}
+
+
+#removes all html tags from that data, as they will not contain dates which
+#are part of the content of the document, and therefore interesting, but do
+#contain date lookalikes
+sub remove_tags {
+    my ($tmp) = @_;
+   
+    my $parsed = "";
+    #while there is still text to be parsed and tags are still found
+    while($tmp=~ m!<([^>])*(>|$)! && $tmp ne "")
+    {
+        $parsed .= $`;#keep all that is not in a tag
+        $tmp = $';    #restart the search after then end of the tag
+    }
+    $parsed .= $tmp; #add anything after the last match
+    $parsed;
+}
+
+
+sub remove_excess {
+    my ($tmp) = @_;
+    my $parsed = "";
+   
+
+    if(($tmp =~ m!($spurious)|($lookalikes)!i) == 0 )
+    { 
+        $parsed = $tmp;
+    }
+    else { 
+        while ($tmp =~ m!($spurious)|($lookalikes)!i 
+               && $tmp ne "")
+        {
+            $parsed .= $`;
+            my $storage = $&;
+            $tmp = $';
+            #match the pattern which indicates most recent alteration 
+            if ($storage =~ m!$lastaltered!i)
+            {
+                #match a four digit year or up until the first / 
+                #(as in last edited 3/97). 
+                $tmp =~ m!($millenium)|(\/)!;
+                $tmp = $';
+            }
+                
+        }
+        
+        $parsed .= $tmp;
+           
+    }
+    #print "Parsed:\n $parsed\n\n";
+    $parsed;
+    
+}
+
+sub remove_biblio{
+    my ($tmp) = @_;
+    my $parsed = "";
+    
+    if($tmp =~ m!$bibheader!i)
+    {
+        $tmp=$`;
+    }
+    
+    $tmp =~ s/( |\t)+/ /g;
+    if(($tmp =~ m!($ref_end)|($bracket)|($colonsp)|($reprint)|($comma)|($fullstop)|($semi)|($seasonref) ($millenium)!i) == 0)
+    {
+        $parsed = $tmp;
+    }
+    else{
+
+        #print "removing bib\n";
+        while ($tmp =~ m!($ref_end)|($bracket)|($colonsp)|($reprint)|($comma)|($fullstop)|($semi)|(($seasonref) ($millenium))|($bibheader)!i && $tmp ne "")
+        {
+            
+            $parsed .= $`;
+            $tmp = $';
+            if($&=~m!($comma)|($fullstop)!)
+            {
+                
+                my $date = $&;
+                if($parsed =~ m!((\d)($Ord)$)|(($shortmth)$)|(($longmth)$)!i)
+                {
+                    $parsed .= $date;
+                }
+            }  
+            
+        }
+                   $parsed .= $tmp;
+    }
+    $parsed;
+}
+
+
+1;
Index: /gsdl/stable/perllib/GDBMUtils.pm
===================================================================
--- /gsdl/stable/perllib/GDBMUtils.pm	(revision 20131)
+++ /gsdl/stable/perllib/GDBMUtils.pm	(revision 20131)
@@ -0,0 +1,222 @@
+package GDBMUtils;
+
+use strict;
+use util;
+
+my $debug = 0;
+
+# /** Global variables to hold a strings containing:
+#  *    the last collection, oid and value
+#  *  a gdbmCachedCollectionGet() was performed on.
+#  */
+my $gdbmget_previous_collection = "";
+my $gdbmget_previous_oid = "";
+my $gdbmget_previous_value = "";
+
+
+
+sub gdbmDatabaseGet
+{
+    my ($database, $oid) = @_;
+
+    # Are we in windows? Do we need .exe?
+    my $exe = &util::get_os_exe();
+
+    # Retrieve the raw document content
+    print STDERR "#Get document\ncmd: gdbmget$exe \"$database\" \"$oid\"\n" if $debug;
+    my $value = `gdbmget$exe "$database" "$oid"`;
+
+    # Done
+    return $value;
+}
+
+sub gdbmRecordToHash
+{
+    my ($database, $oid) = @_;
+
+    my $val = gdbmDatabaseGet($database,$oid);
+
+    my $rec = {};
+
+    while ($val =~ m/^<(.*?)>(.*)$/mg) {
+	my $metaname = $1;
+	my $metavalue = $2;
+
+	if (!defined $rec->{$metaname}) {
+	    $rec->{$metaname} = [ $metavalue ];
+	}
+	else {
+	    push(@{$rec->{$metaname}},$metavalue);
+	}
+    }
+
+    return $rec;
+}
+
+sub serializeHash
+{
+    my ($hash) = @_;
+
+    my $shash = "";
+    
+    foreach my $metaname (keys %$hash) {
+	my $metavals = $hash->{$metaname};
+	foreach my $metaval (@$metavals) {
+	    # need to escape chars HTML entities ??
+	    $shash .= "<$metaname>$metaval\n";
+	}
+    }
+
+    return $shash;
+}
+
+
+sub gdbmDatabaseAppend
+{
+    my ($database, $oid, $value) = @_;
+
+    # Are we in windows? Do we need .exe?
+    my $exe = &util::get_os_exe();
+
+    # Escape any speech marks in the value
+    $value =~ s/\"/\\\"/g;
+    # Set the document content
+    print STDERR "#Set document\ncmd: gdbmset$exe \"$database\" \"$oid\" \"$value\" append\n" if $debug;
+    `gdbmset$exe "$database" "$oid" "$value" append`;
+}
+
+
+sub gdbmDatabaseSet
+  {
+    my ($database, $oid, $value) = @_;
+
+    # Are we in windows? Do we need .exe?
+    my $exe = &util::get_os_exe();
+
+    # Escape any speech marks in the value
+    $value =~ s/\"/\\\"/g;
+    # Set the document content
+    print STDERR "#Set document\ncmd: gdbmset$exe \"$database\" \"$oid\" \"$value\"\n" if $debug;
+    `gdbmset$exe "$database" "$oid" "$value"`;
+}
+
+
+sub gdbmDatabaseRemove
+  {
+    my ($database, $oid) = @_;
+
+    # Are we in windows? Do we need .exe?
+    my $exe = &util::get_os_exe();
+
+    # Remove the document from the database
+
+    my $cmd = "gdbmdel$exe \"$database\" \"$oid\"";
+    print STDERR "#Delete document\ncmd: $cmd" if $debug;
+
+    `$cmd`;
+
+}
+
+
+
+# /** This wraps John T's gdbmget executable to get the gdbm database entry for
+#  *  a particular OID.
+#  *
+#  *  @param $collection is the collection name.
+#  *  @param $oid is the internal document id.
+#  *
+#  *
+#  *  @author John Rowe, DL Consulting Ltd.
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub gdbmCachedCollectionGet
+  {
+    my ($collection, $oid) = @_;
+    # Start by checking if this request is the same as the previous one, and if
+    # so return the cache version instead. This is an optimization to improve
+    # performance when checking if a certain GDBM document exists before 
+    # creating a new node object
+    if($collection eq $gdbmget_previous_collection 
+       && $oid eq $gdbmget_previous_oid)
+      {
+        print STDERR "#Get document - using cached value\n" if $debug;
+        return $gdbmget_previous_value;
+      }
+
+    # Where's the database?
+    my $database = _getDatabasePath($collection);
+
+    my $value = gdbmDatabaseGet($database,$oid);
+
+    # Tidy up the ever growing number of newlines at the end of the value
+    $value =~ s/(\r?\n)+/$1/g;
+    # Why do we need the above line?  At the very least it would seem
+    # better that the data going in to the database through 'set' is
+    # monitored for superfluous \r\n which are then removed before being
+    # saved in GDBM
+
+    # Cache this result
+    $gdbmget_previous_collection = $collection;
+    $gdbmget_previous_oid = $oid;
+    $gdbmget_previous_value = $value;
+
+    # Done
+    return $value;
+  }
+# /** gdbmCachedCollectionGet **/
+
+# /** This wraps John T's gdbmset executable to set the gdbm database entry for
+#  *  a particular OID. This does not yet report errors.
+#  *
+#  *  @param $collection is the collection name.
+#  *  @param $oid is the internal document id.
+#  *  @param $value is the new value to set for the oid.
+#  *
+#  *  @author John Rowe, DL Consulting Ltd.
+#  */
+sub gdbmCachedCollectionSet
+  {
+    my ($collection, $oid, $value) = @_;
+
+    # Where's the database?
+    my $database = _getDatabasePath($collection);
+
+
+    # Check whether value is set
+    if (defined($value))
+      {
+	  gdbmDatabaseSet($database,$oid,$value);
+      }
+    else
+      {
+	  gdbmDatabaseRemove($database,$oid);
+      }
+
+    # Empty any cached values, as they may now be invalid
+
+    # Cache this result
+    $gdbmget_previous_collection = "";
+    $gdbmget_previous_oid = "";
+    $gdbmget_previous_value = 0;
+  }
+# /** gdbmCollectionSet **/
+
+# /** This works out the database path and returns it to the calling
+#  *  calling function.
+#  *
+#  *  @param $collection The current collection name
+#  *
+#  *  @author John Rowe, DL Consulting Ltd.
+#  */
+
+sub _getDatabasePath
+  {
+    my $collection = shift(@_);
+
+    # Return the full filename of the database
+
+    return &util::filename_cat($ENV{'GSDLHOME'}, "collect", $collection, "index", "text", "$collection.gdb");
+  }
+# /** getDatabasePath **/
+
+1;
Index: /gsdl/stable/perllib/IncrementalBuildUtils.pm
===================================================================
--- /gsdl/stable/perllib/IncrementalBuildUtils.pm	(revision 20131)
+++ /gsdl/stable/perllib/IncrementalBuildUtils.pm	(revision 20131)
@@ -0,0 +1,509 @@
+###########################################################################
+#
+# IncrementalBuildUtils.pm -- API to assist incremental building
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 DL Consulting Ltd and New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# /** Initial versions of these functions by John Thompson, revisions by
+#  *  and turning it into a package by John Rowe. Used heavily by
+#  *  basebuilder::remove_document() and getdocument.pl
+#  *
+#  *  @version 1.0 Initial version by John Thompson
+#  *  @version 1.1 Addition of get_document and change of get_document_as_xml
+#  *               by John Rowe
+#  *  @version 2.0 Package version including seperation from calling code and
+#  *               modularisation by creating gdbmget, gdbmset and
+#  *               get_database_path by John Rowe
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  *  @author John Rowe, DL Consulting Ltd.
+#  */
+###########################################################################
+package IncrementalBuildUtils;
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/plugins");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/classify");
+}
+
+use doc;
+use cfgread;
+use colcfg;
+use strict;
+use util;
+
+use ClassifyTreeModel;
+use IncrementalDocument;
+
+# Change debugging to 1 if you want verbose debugging output
+my $debug = 1;
+
+# Ensure the collection specific binaries are on the search path
+my $path_separator = ":";
+if($ENV{'GSDLOS'} =~ /win/) {
+  $path_separator = ";";
+}
+$ENV{'PATH'} = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}) . $path_separator . &util::filename_cat($ENV{'GSDLHOME'}, "bin", "script") . $path_separator.$ENV{'PATH'};
+
+# /**
+#  */
+sub addDocument()
+  {
+    my ($collection, $doc_obj, $section, $updateindex) = @_;
+
+    $updateindex = 0 unless defined($updateindex);
+
+    print STDERR "IncrementalBuildUtils::addDocument('$collection',$doc_obj,'$section')\n" unless !$debug;
+    # Gonna need to know in several places whether this is the top section
+    # of the document or not
+    my $is_top = ($section eq $doc_obj->get_top_section());
+
+    # Retrieve all of the metadata from this document object only - not any
+    # child documents
+    my $metadata = $doc_obj->get_all_metadata($section);
+    # Check and add the docnum first
+    my $found_docnum = 0;
+    foreach my $pair (@$metadata)
+      {
+        my ($key, $value) = (@$pair);
+        if ($key eq "docnum")
+          {
+            &setDocumentMetadata($collection, $doc_obj->get_OID() . "$section", $key, "", $value, $updateindex);
+            $found_docnum = 1;
+          }
+      }
+
+    if (!$found_docnum)
+      {
+        die("Fatal Error! Tried to add document without providing docnum");
+      }
+
+    # Add it piece by piece - this depends on the loading of a blank document
+    # working the way it should.
+    foreach my $pair (@$metadata)
+      {
+        my ($key, $value) = (@$pair);
+        if ($key ne "Identifier" && $key ne "docnum" && $key !~ /^gsdl/ && defined $value && $value ne "")
+          {
+            # escape problematic stuff
+            $value =~ s/\\/\\\\/g;
+            $value =~ s/\n/\\n/g;
+            $value =~ s/\r/\\r/g;
+            if ($value =~ /-{70,}/)
+              {
+                # if value contains 70 or more hyphens in a row we need
+                # to escape them to prevent txt2db from treating them
+                # as a separator
+                $value =~ s/-/&\#045;/gi;
+              }
+            # Go ahead and set the metadata
+            &setDocumentMetadata($collection, $doc_obj->get_OID() . "$section", $key, "", $value, $updateindex);
+          }
+      }
+    # We now have to load the browselist node too. We create a ClassifyTreeNode
+    # based on a dummy model.
+    # Note: only if section is the top section
+    if ($is_top)
+      {
+        my $dummy_model = new ClassifyTreeModel($collection, "");
+        my $browselist_node = new ClassifyTreeNode($dummy_model, "browselist");
+        # Add the document
+        $browselist_node->addDocument($doc_obj->get_OID());
+      }
+    # We now recursively move through the document objects child sections,
+    # adding them too. As we do this we build up a contains list for this
+    # document.
+    my $section_ptr = $doc_obj->_lookup_section($section);
+    my @contains = ();
+    if (defined $section_ptr)
+      {
+        foreach my $subsection (@{$section_ptr->{'subsection_order'}}) {
+          &addDocument($collection, $doc_obj, "$section.$subsection");
+          push(@contains, "\".$subsection");
+        }
+      }
+    # Done - clean up
+  }
+# /** addDocument() **/
+
+# /** Sets the metadata attached to a given document. This will update, at most,
+#  *  three different locations:
+#  *  1. The Lucene index must be updated. This will involve removing any
+#  *     existing value and, if required, adding a new value in its place.
+#  *  2. The GDBM database must be updated. Again any existing value will be
+#  *     removed and, if required, a new value added.
+#  *  3. Finally a check against the collect.cfg will be done to determine if
+#  *     the changed metadata would have an effect on a classifier and, if so
+#  *     the classifier tree will be updated to remove, add or replace any
+#  *     tree nodes or node 'contains lists' as necessary.
+#  *
+#  *  Pseudo Code:
+#  *  ------------
+#  *  To add metadata to the document NT1
+#  *  A. Establish connection to Lucene
+#  *  B. Create a IncrementalDocument object for 'NT1' loading the information
+#  *     from the GDBM
+#  *  C. Check to see if this metadata is used to build a classifier(s) and if
+#  *     so create the appropriate ClassifyTreeModel(s)
+#  *  D. If removing or replacing metadata:
+#  *     i/   Call ??? to remove key-value from Lucene index
+#  *     ii/  Use removeMetadata() to clear value in IncrementalDocument
+#  *     iii/ Call removeDocument() in ClassifyTreeModel(s) as necessary
+#  *  E. If adding or replacing metadata:
+#  *     i/   Call ??? to add key-value from Lucene index
+#  *     ii/ Use addMetadata() to add value in IncrementalDocument
+#  *     iii/ Call addDocument() in ClassifyTreeModel(s) as necessary
+#  *  F. Complete Lucene transaction
+#  *  G. Save IncrementalDocument to GDBM
+#  *  Note: ClassifyTreeModel automatically updates GDBM as necessary.
+#  *
+#  *  @param  $collection  The name of the collection to update as a string
+#  *  @param  $oid         The unique identifier of a Greenstone document as a
+#  *                       string
+#  *  @param  $key         The key of the metadata being added as a string
+#  *  @param  $old_value   The value of the metadata being removed/replaced
+#  *                       or an empty string if adding metadata
+#  *  @param  $new_value   The value of the metadata being added/replacing
+#  *                       or an empty string if removing metadata
+#  *  @param  $updateindex 1 to get the index updated. This is used to prevent
+#  *                       the indexes being changed when doing an incremental
+#  *                       addition of a new document.
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub setDocumentMetadata()
+  {
+    my ($collection, $oid, $key, $old_value, $new_value, $updateindex) = @_;
+    print STDERR "IncrementalBuildUtils::setDocumentMetadata('$collection','$oid','$key','$old_value','$new_value',$updateindex)\n" unless !$debug;
+    # A. Establish connection to Lucene
+    #    This isn't required at the moment, but might be later if we implement
+    #    Lucene daemon.
+    # B. Create a IncrementalDocument object for 'NT1' loading the information
+    #    from the GDBM
+    print STDERR "* creating incremental document for $oid\n" unless !$debug;
+    my $doc_obj = new IncrementalDocument($collection, $oid);
+    $doc_obj->loadDocument();
+    # C. Check to see if this metadata is used to build a classifier(s) and if
+    #    so create the appropriate ClassifyTreeModel(s)
+    print STDERR "* load collection configuration\n" unless !$debug;
+    my $config_obj = &getConfigObj($collection);
+    my $clidx = 1;
+    my @classifier_tree_models = ();
+    foreach my $classifier (@{$config_obj->{'classify'}})
+      {
+        my $index = 0;
+        my $option_count = scalar(@{$classifier});
+        for ($index = 0; $index < $option_count; $index++)
+          {
+            if ($index + 1 < $option_count && @{$classifier}[$index] eq "-metadata" && @{$classifier}[$index + 1] eq $key)
+              {
+                # Create a tree model for this classifier
+                print STDERR "* creating a tree model for classifier: CL$clidx\n" unless !$debug;
+                my $tree_model_obj = new ClassifyTreeModel($collection, "CL" . $clidx);
+                # And store it for later
+                push(@classifier_tree_models, $tree_model_obj);
+              }
+          }
+        $clidx++;
+      }
+    # D. If removing or replacing metadata:
+    if (defined($old_value) && $old_value =~ /[\w\d]+/)
+      {
+        print STDERR "* removing '$key'='$old_value' from GDBM database for document $oid\n" unless !$debug;
+        # i/   Call ??? to remove key-value from Lucene index
+        #      Moved elsewhere
+        # ii/  Use removeMetadata() to clear value in IncrementalDocument
+        $doc_obj->removeMetadata($key, $old_value);
+        # iii/ Call removeDocument() in ClassifyTreeModel(s) as necessary
+        foreach my $classifier_tree_model (@classifier_tree_models)
+          {
+            print STDERR "* removing '$old_value' from classifier tree\n" unless !$debug;
+            $classifier_tree_model->removeDocument($old_value, $oid, 1);
+          }
+      }
+    # E. If adding or replacing metadata:
+    if (defined($new_value) && $new_value =~ /[\w\d]+/)
+      {
+        print STDERR "* adding '$key'='$new_value' to GDBM database for document $oid\n" unless !$debug;
+        # i/   Call ??? to add key-value from Lucene index
+        #      Moved elsewhere
+        # ii/ Use addMetadata() to add value in IncrementalDocument
+        $doc_obj->addMetadata($key, $new_value);
+        # iii/ Call addDocument() in ClassifyTreeModel(s) as necessary
+        foreach my $classifier_tree_model (@classifier_tree_models)
+          {
+            print STDERR "* adding '$new_value' to classifier tree\n" unless !$debug;
+            $classifier_tree_model->addDocument($new_value, $oid);
+          }
+      }
+    # F. Complete Lucene transaction
+    if(defined($updateindex) && $updateindex)
+      {
+        print STDERR "* updating Lucene indexes\n" unless !$debug;
+        &callGS2LuceneEditor($collection, $doc_obj->getDocNum, $key, $old_value, $new_value);
+      }
+    # G. Save IncrementalDocument to GDBM
+    $doc_obj->saveDocument();
+    $doc_obj = 0;
+  }
+# /** setDocumentMetadata() **/
+
+# /**
+#  *
+#  */
+sub callGS2LuceneDelete()
+  {
+    my ($collection, $docnum) = @_;
+
+    # Some path information that is the same for all indexes
+    my $classpath = &util::filename_cat($ENV{'GSDLHOME'},"bin","java","LuceneWrap.jar");
+    my $java_lucene = "org.nzdl.gsdl.LuceneWrap.GS2LuceneDelete";
+    my $indexpath = &util::filename_cat($ENV{'GSDLHOME'},"collect",$collection,"index");
+    # Determine what indexes need to be changed by opening the collections
+    # index path and searching for directories named *idx
+    # If the directory doesn't exist, then there is no built index, and nothing
+    # for us to do.
+    if(opendir(INDEXDIR, $indexpath))
+      {
+        my @index_files = readdir(INDEXDIR);
+        closedir(INDEXDIR);
+        # For each index that matches or pattern, we call the java application
+        # to change the index (as necessary - not every index will include the
+        # document we have been asked to modify)
+        foreach my $actual_index_dir (@index_files)
+          {
+            next unless $actual_index_dir =~ /idx$/;
+            # Determine the path to the index to modify
+            my $full_index_dir = &util::filename_cat($indexpath, $actual_index_dir);
+            # Call java to remove the document
+            my $cmd = "java -classpath \"$classpath\" $java_lucene --index $full_index_dir --nodeid $docnum";
+            print STDERR "CMD: " . $cmd . "\n" unless !$debug;
+            # Run command
+            my $result = `$cmd 2>&1`;
+            print STDERR $result unless !$debug;
+          }
+      }
+    # Done
+  }
+# /** callGS2LuceneDelete() **/
+
+# /**
+#  */
+sub callGS2LuceneEditor()
+  {
+    my ($collection, $docnum, $key, $old_value, $new_value) = @_;
+
+    # Some path information that is the same for all indexes
+    my $classpath = &util::filename_cat($ENV{'GSDLHOME'},"collect",$collection,"java","classes");
+    my $jarpath = &util::filename_cat($ENV{'GSDLHOME'},"bin","java","LuceneWrap.jar");
+    my $java_lucene = "org.nzdl.gsdl.LuceneWrap.GS2LuceneEditor";
+    my $indexpath = &util::filename_cat($ENV{'GSDLHOME'},"collect",$collection,"index");
+    # And some commands that don't change
+    my $java_args = "";
+    # Append the node id
+    $java_args .= "--nodeid $docnum ";
+    # We have to convert the given metadata key into its two letter field code.
+    # We do this by looking in the build.cfg file.
+    my $field = &getFieldFromBuildCFG($indexpath, $key);
+    # The metadata field to change
+    $java_args .= "--field $field ";
+    # And the old and new values as necessary
+    if(defined($old_value) && $old_value =~ /[\w\d]+/)
+      {
+        $java_args .= "--oldvalue \"$old_value\" ";
+      }
+    if(defined($new_value) && $new_value =~ /[\w\d]+/)
+      {
+        $java_args .= "--newvalue \"$new_value\" ";
+      }
+    # Determine what indexes need to be changed by opening the collections
+    # index path and searching for directories named *idx
+    # If the directory doesn't exist, then there is no built index, and nothing
+    # for us to do.
+    # We also check if the field is something other than "". It is entirely
+    # possible that we have been asked to update a metadata field that isn't
+    # part of any index, so this is where we break out of editing the index if
+    # we have
+    if($field =~ /^\w\w$/ && opendir(INDEXDIR, $indexpath))
+      {
+        my @index_files = readdir(INDEXDIR);
+        closedir(INDEXDIR);
+        # For each index that matches or pattern, we call the java application
+        # to change the index (as necessary - not every index will include the
+        # document we have been asked to modify)
+        foreach my $actual_index_dir (@index_files)
+          {
+            next unless $actual_index_dir =~ /idx$/;
+            # Determine the path to the index to modify
+            my $full_index_dir = &util::filename_cat($indexpath, $actual_index_dir);
+            # And prepend to the command java arguments
+            my $cur_java_args = "--index $full_index_dir " . $java_args;
+            print STDERR "CMD: java -classpath \"$classpath:$jarpath\" $java_lucene $cur_java_args 2>&1\n" unless !$debug;
+            # Run command
+            my $result = `java -classpath \"$classpath:$jarpath\" $java_lucene $cur_java_args 2>&1`;
+            print STDERR $result unless !$debug;
+          }
+      }
+    # Done
+  }
+# /** callGS2LuceneEditor() **/
+
+## Remove a document from the GDBM and Index.
+#
+#  @param  collection  The collection to alter
+#  @param  oid         The unique identifier of the document to be removed
+##
+sub deleteDocument()
+  {
+    my ($collection, $oid) = @_;
+    # Load the incremental document to go with this oid, as we need some
+    # information from it.
+    my $doc_obj = new IncrementalDocument($collection, $oid);
+    $doc_obj->loadDocument();
+    # Check if this object even exists by retrieving the docnum.
+    my $doc_num = $doc_obj->getDocNum();
+    print STDERR "Removing document docnum: $doc_num\n" unless !$debug;
+    if ($doc_num > -1)
+      {
+        # Now use the GDBM utils to write a blank string to this oid in the
+        # database
+        &GDBMUtils::gdbmCachedCollectionSet($collection, $oid, "");
+        # Remove reverse lookup
+        &GDBMUtils::gdbmCachedCollectionSet($collection, $doc_num, "");
+        # And remove from the database
+        &callGS2LuceneDelete($collection, $doc_num);
+
+        # Regenerate the classifier trees.
+        print STDERR "* load collection configuration\n";# unless !$debug;
+        my $config_obj = &getConfigObj($collection);
+        my $clidx = 1;
+        my %classifier_tree_models = ();
+        foreach my $classifier (@{$config_obj->{'classify'}})
+          {
+            my $index = 0;
+            my $option_count = scalar(@{$classifier});
+            for ($index = 0; $index < $option_count; $index++)
+              {
+                if ($index + 1 < $option_count && @{$classifier}[$index] eq "-metadata")
+                  {
+                    my $key = @{$classifier}[$index + 1];
+                    # Create a tree model for this classifier
+                    print STDERR "* creating a tree model for classifier: CL" . $clidx . " [" . $key . "]\n";# unless !$debug;
+                    my $tree_model_obj = new ClassifyTreeModel($collection, "CL" . $clidx);
+                    # And store it against its key for later
+                    $classifier_tree_models{$key} = $tree_model_obj;
+                  }
+              }
+            $clidx++;
+          }
+        
+        # For each piece of metadata assigned to this document, if there is a 
+        # matching classifier tree, remove the path from the tree.
+        print STDERR "* searching for classifier paths to be removed\n";
+        
+        my $metadata = $doc_obj->getAllMetadata();
+        foreach my $pair (@$metadata)
+          {
+            my ($key, $value) = @$pair;
+            print STDERR "* testing " . $key . "=>" . $value . "\n";
+            if (defined($classifier_tree_models{$key}))
+              {
+                my $model = $classifier_tree_models{$key};
+                print STDERR "* removing '" . $value . "' from classifier " . $model->getRootNode()->getCLID() . "\n";
+                $model->removeDocument($value, $oid, 1);
+              }
+          }
+
+        # We also have to remove from browselist - the reverse process of
+        # adding to browselist shown above.
+        my $dummy_model = new ClassifyTreeModel($collection, "");
+        my $browselist_node = new ClassifyTreeNode($dummy_model, "browselist");
+        # Add the document
+        $browselist_node->removeDocument($oid);
+        # Clean up
+      }
+    # else, no document, no need to delete.
+  }
+## deleteDocument() ##
+
+# /**
+#  */
+sub getFieldFromBuildCFG()
+  {
+    my ($indexpath, $key) = @_;
+    my $field = "";
+    my $build_cfg = &util::filename_cat($indexpath, "build.cfg");
+    # If there isn't a build.cfg then the index hasn't been built and there is
+    # nothing to do
+    if(open(BUILDCFG, $build_cfg))
+      {
+        # For each line of the build configuration
+        my $line;
+        while($line = <BUILDCFG>)
+          {
+            # Only interested in the indexfieldmap line
+            if($line =~ /^indexfieldmap\s+/)
+              {
+                # Extract the field information by looking up the key pair
+                if($line =~ /\s$key->(\w\w)/)
+                  {
+                    $field = $1;
+                  }
+              }
+          }
+        # Done with file
+        close(BUILDCFG);
+      }
+    # Return whatever we found
+    return $field;
+  }
+# /** getFieldFromBuildCFG() **/
+
+
+
+
+
+# /** Retrieve an object (associative array) containing information about the
+#  *  collection configuration.
+#  *  @param  $collection The shortname of the collection as a string
+#  *  @return An associative array containing information from the collect.cfg
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub getConfigObj()
+  {
+    my ($collection) = @_;
+
+    #rint STDERR "getConfigObj()\n" unless !$debug;
+
+    my $colcfgname = &util::filename_cat($ENV{'GSDLHOME'}, "collect", $collection, "etc", "collect.cfg");
+    if (!-e $colcfgname)
+      {
+        die "IncrementalBuildUtils - couldn't find collect.cfg for collection $collection\n";
+      }
+    return &colcfg::read_collect_cfg ($colcfgname);
+  }
+# /** getConfigObj() **/
+
+1;
Index: /gsdl/stable/perllib/IncrementalDocument.pm
===================================================================
--- /gsdl/stable/perllib/IncrementalDocument.pm	(revision 20131)
+++ /gsdl/stable/perllib/IncrementalDocument.pm	(revision 20131)
@@ -0,0 +1,239 @@
+###########################################################################
+#
+# IncrementalDocument.pm -- An object to encapsulate the Greenstone 
+#                           document retrieved from the GDBM database.
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 DL Consulting Ltd and New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+package IncrementalDocument;
+
+use GDBMUtils;
+use strict;
+
+# /**
+#  */
+sub new()
+  {
+    my ($class, $collection, $oid) = @_;
+
+    #rint STDERR "IncrementalDocument::new($collection, $oid)\n";
+
+    # Test the parameters
+    die ("Error! Can't create a document that doesn't belong to a collection!") unless $collection;
+    die ("Error! Can't create a document that doesn't have a unique id (OID)!") unless $oid;
+
+    # Store the variables
+    my $self = {};
+
+    # The collection this document object has been loaded from.
+    $self->{'collection'} = $collection;
+
+    # An associative array of information retrieved from the GDBM database
+    # which maps a key string to a nested associative array listing values.
+    $self->{'data'} = {};
+
+    # The unique identifier of the document loaded
+    $self->{'oid'} = $oid;
+
+    # Stores the order in which metadata keys where discovered/added.
+    $self->{'order'} = {};
+
+    bless $self, $class;
+    return $self;
+  }
+# /** new() **/
+
+# /**
+#  */
+sub addMetadata()
+  {
+    my ($self, $key, $value, $internal) = @_;
+
+    # Validate the arguments
+    die ("Error! Can't add a metadata value to a document without a valid key!") unless $key =~ /[\w]+/;
+    die ("Error! Can't add a metadata key to a document without a valid value!") unless $value =~ /[\w\d]+/;
+
+    # Is this a new key that we haven't encountered before? If so ensure an
+    # array exists for its values, and record the order in which we encountered
+    # this key.
+    if (!defined($self->{'data'}->{$key}))
+      {
+        # Determine how many data keys we're already storing, so we can add the next
+        # one at the appropriate index
+        my $index = scalar(keys %{$self->{'order'}});
+        $self->{'order'}->{$index} = $key;
+        $self->{'data'}->{$key} = {};
+      }
+
+    # Set the value of the associative path to 1.
+    $self->{'data'}->{$key}->{$value} = 1;
+  }
+# /** addMetadata() **/
+
+# /** Retrieve all the metadata of this document as an array of pairs.
+#  *
+#  */
+sub getAllMetadata()
+{
+    my ($self) = @_;
+    my @all_metadata;
+
+    print STDERR "IncrementalDocument.getAllMetadata()\n";
+
+    my $key_count = scalar(keys %{$self->{'order'}});
+    for (my $i = 0; $i < $key_count; $i++)
+      {
+        my $key = $self->{'order'}->{$i};
+        # Check if this key has been set
+        if ($self->{'data'}->{$key})
+          {
+            # Note: there may be zero values left
+            foreach my $value (sort keys %{$self->{'data'}->{$key}})
+              {
+                if ($self->{'data'}->{$key}->{$value})
+                  {
+                    print STDERR "* Storing $key => $value\n";
+                    push(@all_metadata, [$key, $value]);
+                  }
+              }
+          }
+      }
+    print STDERR "Complete!\n";
+    return \@all_metadata;
+  }
+# /** getAllMetadata() **/
+
+# /**
+#  */
+sub getDocNum()
+  {
+    my ($self) = @_;
+    my $docnum = -1;
+    # Check the docnum path exists in the associated data
+    if(defined($self->{'data'}->{'docnum'}))
+      {
+        # Get the list of keys from that associative path
+        my @values = keys (%{$self->{'data'}->{'docnum'}});
+        # And since we know there will only ever be one value for docnum
+        $docnum = $values[0];
+      }
+    return $docnum;
+  }
+# /** getDocNum() **/
+
+# /**
+#  */
+sub loadDocument()
+  {
+    my ($self) = @_;
+    #rint STDERR "IncrementalDocument::loadDocument()\n";
+    # Load the raw text for the document object from GDBM
+    my $collection = $self->{'collection'};
+    my $text = &GDBMUtils::gdbmCachedCollectionGet($collection, $self->{'oid'});
+    # For each line in the raw text, extract the key (enclosed in angle
+    # brackets) and the value
+    $text =~ s/<([\w\d\.]+)>(.+?)\r?\n/&addMetadata($self, $1, $2, 1)/egs;
+    # Done
+  }
+# /** loadDocument() **/
+
+# /** Locates and removes the given key/value mappings from this document
+#  *  object.
+#  *
+#  *  @param  $self A reference to this IncrementalDocument object
+#  *  @param  $key The metadata key as a string
+#  *  @param  $value The obsolete metadata value as a string
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub removeMetadata()
+  {
+    my ($self, $key, $value) = @_;
+    # Ensure the value doesn't exist by simply setting to 0 the correct
+    # associative path
+    $self->{'data'}->{$key}->{$value} = 0;
+  }
+# /*** removeMetadat() **/
+
+# /**
+#  */
+sub saveDocument()
+  {
+    my ($self) = @_;
+    # Get a textual version of this object
+    my $text = $self->toString();
+
+    # Now store the object in the database using the GDBM utilities
+    my $collection = $self->{'collection'};
+    &GDBMUtils::gdbmCachedCollectionSet($collection, $self->{'oid'}, $text);
+
+    # There is a little bit of extra complexity when saving an incremental
+    # document in that we should ensure that a reverse lookup-from DocNum or
+    # nodeID to Greenstone document hash-exists in the database.
+    my $doc_num = $self->getDocNum();
+    if($doc_num >= 0)
+      {
+        my $text = &GDBMUtils::gdbmCachedCollectionGet($collection, $doc_num);
+        # If there is no reverse lookup, then add one now
+        if($text !~ /<section>/)
+          {
+            &GDBMUtils::gdbmCachedCollectionSet($collection, $doc_num, "<section>" . $self->{'oid'});
+          }
+      }
+    # Done
+    #rint STDERR "Stored document:\n[" . $self->{'oid'} . "]\n$text\n";
+  }
+# /** saveDocument() **/
+
+# /** Produces a textual representation of this object.
+#  *
+#  *  @return A string which describes this incremental document object
+#  *
+#  *  @author John Thompson, DL Consulting Ltd.
+#  */
+sub toString()
+  {
+    my ($self) = @_;
+    my $text = "";
+
+    my $key_count = scalar(keys %{$self->{'order'}});
+    for (my $i = 0; $i < $key_count; $i++)
+      {
+        my $key = $self->{'order'}->{$i};
+        # Check if this key has been set
+        if ($self->{'data'}->{$key})
+          {
+            # Note: there may be zero values left
+            foreach my $value (sort keys %{$self->{'data'}->{$key}})
+              {
+                if ($self->{'data'}->{$key}->{$value})
+                  {
+                    $text .= "<$key>$value\n";
+                  }
+              }
+          }
+      }
+    return $text;
+  }
+# /** toString() **/
+
+1;
Index: /gsdl/stable/perllib/Kea.pm
===================================================================
--- /gsdl/stable/perllib/Kea.pm	(revision 20131)
+++ /gsdl/stable/perllib/Kea.pm	(revision 20131)
@@ -0,0 +1,115 @@
+package Kea;
+
+use strict;
+
+# This function is called by BasPlug.pm when a flag in a collection
+# configuration document specifies that keyphrase metadata must be gathered for
+# that collection.
+# It is passed as arguments, the documents text and possibly some options for
+# how the keyphrase data is to be collected if the keyphrase option flag was
+# set in the collection configuration file.  This module then writes the
+# documents text to a file in a temporary directory because the stand-alone program Kea which will be
+# called to do the actual extraction of the keyphrases expects a directory with one or more files as argument.
+# Once Kea has been called upon, the file containing the keyphrase data
+# gathered by Kea should be stored in gsdl/tmp and this file is read, the data
+# we are interested in is extracted and passed back to BasPlug.pm in an
+# appropriate format.
+
+sub get_Kea_directory
+{
+    my $kea_version = shift(@_);
+    return &util::filename_cat($ENV{'GSDLHOME'}, "packages", "kea", "kea-$kea_version");
+}
+
+# returns a string containing comma-separated keyphrases
+sub extract_KeyPhrases
+{
+    my $kea_version = shift(@_);
+    my $doc = shift(@_);  # Document's text  
+    my $args = shift(@_);  # Options
+
+    # Set default models
+    my $kea_home = &get_Kea_directory($kea_version);
+    my $default_model_path = &util::filename_cat($kea_home, "CSTR-20");
+    if ($kea_version eq "4.0") {
+	# Use a different default model for Kea 4.0
+	$default_model_path = &util::filename_cat($kea_home, "FAO-20docs");
+    }
+
+    # Parse the Kea options
+    my $options_string;
+    my @args_list = split(/\s+/, $args) if (defined($args));
+    if (@args_list) {
+	my $model_specified = 0;
+	foreach my $arg (@args_list) {
+	    if (length($arg) == 1) {
+		$options_string .= " -$arg";
+	    }
+	    else {
+		my $option = substr($arg, 0, 1);
+		my $value = substr($arg, 1);
+		if ($option eq "m") {
+		    my $model_path = &util::filename_cat($kea_home, $value);
+		    if (-e $model_path) {
+			$options_string .= " -m $model_path";
+		    }
+		    else {
+			print STDERR "Warning: Couldn't find model $model_path; using the default model instead.\n";
+			$options_string .= " -m $default_model_path";
+		    }
+		    $model_specified = 1;
+		}
+		else {
+		    $options_string .= " -$option $value";
+		}
+	    }
+	}
+
+	# If none of the option specifies the model, use the default one
+	if ($model_specified != 1) {
+	    $options_string .= " -m $default_model_path";
+	}
+    }
+    else {
+	# If no options were specified, use the default model
+	$options_string = "-m $default_model_path";
+    }
+
+    # Remove all HTML tags from the original text
+    $doc =~ s/<P[^>]*>/\n/sgi;
+    $doc =~ s/<H[^>]*>/\n/sgi;
+    $doc =~ s/<[^>]*>//sgi;
+    $doc =~ tr/\n/\n/s;
+
+    # Write text to a temporary file doc.txt
+    my $tmp_directory_path = &util::filename_cat($ENV{'GSDLHOME'}, "tmp");
+    my $doc_txt_file_path = &util::filename_cat($tmp_directory_path, "doc.txt");
+    open(DOC_TXT, ">$doc_txt_file_path") or die "Error: Could not write $doc_txt_file_path in Kea.pm.\n";  
+    print DOC_TXT $doc;
+    close(DOC_TXT);
+
+    # Run Kea with the specified options
+    system("java -classpath \"$kea_home\" KEAKeyphraseExtractor -l $tmp_directory_path $options_string");
+
+    # Read the resulting doc.key file which contains the keyphrases
+    my $doc_key_file_path = &util::filename_cat($tmp_directory_path, "doc.key");
+    if (!open(IN, "<$doc_key_file_path")) {
+	# The doc.key file does not exist (either an option was wrongly specified, or no keyphrases were found)
+	return "";
+    }
+
+    my @keyphrase_list = ();
+    while (<IN>) {
+	chomp;
+	push(@keyphrase_list, $_);
+    }
+    close(IN);
+
+    # Delete doc.key so that in future it will not be opened and read (otherwise KEA sees it as more keyphrases!)
+    unlink($doc_key_file_path);
+
+    my $keyphrases = join(", ", @keyphrase_list);
+    return $keyphrases;
+}
+
+1;
Index: /gsdl/stable/perllib/XMLParser.pm
===================================================================
--- /gsdl/stable/perllib/XMLParser.pm	(revision 20131)
+++ /gsdl/stable/perllib/XMLParser.pm	(revision 20131)
@@ -0,0 +1,33 @@
+# Wrapper that ensures the right version of XML::Parser is loaded given
+# the version of Perl being used.  Need to distinguish between Perl 5.6 and
+# Perl 5.8
+
+
+sub BEGIN {
+    my $perl_dir;
+
+    # Note: $] encodes the version number of perl
+    if ($]>5.008) { 
+	# perl 5.8.1 or above
+	$perl_dir = "perl-5.8";
+    }
+    elsif ($]<5.008) {
+	# assume perl 5.6
+	$perl_dir = "perl-5.6";
+    }
+    else {
+	print STDERR "Warning: Perl 5.8.0 is not a maintained release.\n";
+	print STDERR "         Please upgrade to a newer version of Perl.\n";
+	$perl_dir = "perl-5.8";
+    }
+
+    if ($ENV{'GSDLOS'} !~ /^windows$/i) {
+	# Use push to put this on the end, so an existing XML::Parser will be used by default
+	push (@INC, "$ENV{'GSDLHOME'}/perllib/cpan/$perl_dir");
+    }
+}
+
+use XML::Parser;
+use strict;
+
+1;
Index: /gsdl/stable/perllib/acronym.pm
===================================================================
--- /gsdl/stable/perllib/acronym.pm	(revision 20131)
+++ /gsdl/stable/perllib/acronym.pm	(revision 20131)
@@ -0,0 +1,703 @@
+##########################################################################
+#
+# acronym.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+#    class to handle acronyms
+###########################################################################
+
+eval "require diagnostics"; # some perl distros (eg mac) don't have this
+
+package acronym;
+
+use util;
+use strict;
+
+###########################################################################
+#    global variables
+###########################################################################
+# valiables to control the recall/precision tradeoff
+
+#the maximum range to look for acronyms 
+my $max_offset = 30;
+#acronyms must be upper case
+my $upper_case = 1;
+#acronym case must match
+my $case_match = 1;
+#minimum acronym length
+my $min_def_length = 3;
+#minimum acronym length
+my $min_acro_length = 3;
+#minimum acronym length saving
+my $min_length_saving = 4;
+#allow recusive acronyms
+my $allow_recursive = 0;
+#let definitions be all capitals
+my $allow_all_caps = 0;
+
+my @stop_words = split / /, "OF AT THE IN TO AND";
+
+#the text split into an array, one word per element
+my @split_text = ();
+my @acronym_list = ();
+
+
+my %acronyms_found_in_collection = ();
+my %acronyms_banned_from_collection = ();
+
+my $writing_acronyms = 1;
+my $accumulate_acronyms = 1;
+my $markup_accumulate_acronyms = 1;
+my $markup_local_acronyms = 1;
+
+
+
+###########################################################################
+#   file saving / loading stuff
+###########################################################################
+
+sub initialise_acronyms {
+
+    my $local_max_offset = $max_offset;
+    my $local_upper_case = $upper_case;
+    my $local_case_match = $case_match ;
+    my $local_min_def_length = $min_def_length;
+    my $local_min_acro_length = $min_acro_length;
+    my $local_min_length_saving = $min_length_saving;
+    my $local_allow_recursive = $allow_recursive;
+    my $local_allow_all_caps = $allow_all_caps;
+    my @local_stop_words = @stop_words;
+    
+    
+    # the file to collate acronyms into
+
+    my $def_acronym_acc_file_pm = '&util::filename_cat($ENV{\'GSDLCOLLECTDIR\'}, "etc","acronym_definitions.pm");';
+    my $acronym_accumulate_file = eval { $def_acronym_acc_file_pm };
+    my $acronym_options_file = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"etc","acronym_options.pm");
+
+
+    my $file_text = "";
+    if (open ACRONYM_HANDLE, "<$acronym_options_file")
+    {
+	$file_text = do { local $/; <ACRONYM_HANDLE> };  
+    }
+    if ($file_text eq "")
+    {
+	print STDERR "failed to open $acronym_options_file\n";
+	open ACRONYM_HANDLE, ">$acronym_options_file\n";
+	print ACRONYM_HANDLE "use util;\n";
+	print ACRONYM_HANDLE "#Config file for acronym extraction. EDIT THIS FILE, it should\n";
+	print ACRONYM_HANDLE "#not be overridden by the software. It's read by GSDL using perl's\n";
+	print ACRONYM_HANDLE "#'eval' function, so pretty much anything that's valid in perl is \n";
+	print ACRONYM_HANDLE "#valid here.\n\n";
+	print ACRONYM_HANDLE "#Quite a few things here are defined in terms of recall and precision\n";
+	print ACRONYM_HANDLE "#which are the key measures from Information Retreval (IR). If you\n";
+	print ACRONYM_HANDLE "#don't understand recall and precision, any good IR textbook should\n";
+	print ACRONYM_HANDLE "#explain them fully \n\n";
+	print ACRONYM_HANDLE "#the maximum range to look for acronyms (raise to raise precision)\n"; 
+	print ACRONYM_HANDLE "\$local_max_offset = $max_offset;\n\n"; 
+	print ACRONYM_HANDLE "#acronyms must be upper case (0 = false, 1 = true (high precision))\n";
+	print ACRONYM_HANDLE "\$local_upper_case = $upper_case;\n\n";
+	print ACRONYM_HANDLE "#acronym case must match (0 = false, 1 = true (high precision))\n";
+	print ACRONYM_HANDLE "\$local_case_match = $case_match;\n\n";
+	print ACRONYM_HANDLE "#minimum acronym length (raise to raise precision)\n";
+	print ACRONYM_HANDLE "\$local_min_def_length = $min_def_length;\n\n";
+	print ACRONYM_HANDLE "#let definitions be all capitals\n";
+	print ACRONYM_HANDLE "\$local_allow_all_caps = $allow_all_caps;\n\n";
+	print ACRONYM_HANDLE "#minimum acronym length (raise to raise precision)\n";
+	print ACRONYM_HANDLE "\$local_min_acro_length = 3;\n\n";
+	print ACRONYM_HANDLE "#minimum acronym length saving (raise to raise precision)\n";
+	print ACRONYM_HANDLE "\$local_min_length_saving = 4;\n\n";
+	print ACRONYM_HANDLE "#allow recusive acronyms (0 = false (high precision), 1 = true)\n";
+	print ACRONYM_HANDLE "\$local_allow_recursive = 0;\n\n";
+	print ACRONYM_HANDLE "#stop words-words allowed in acronyms (the multi-lingual version\n";
+	print ACRONYM_HANDLE "#slows down acronym extraction slightly so is not the default)\n";
+	print ACRONYM_HANDLE "#\@local_stop_words = split / /, \"A OF AT THE IN TO AND VON BEI DER DIE DAS DEM DEN DES UND DE DU A LA LE LES L DANS ET S\";\n";
+	print ACRONYM_HANDLE "\@local_stop_words = split / /, \"OF AT THE IN TO AND\";\n"; 
+	print ACRONYM_HANDLE "\n"; 
+	print ACRONYM_HANDLE "#the file to collate acronyms into\n";
+	print ACRONYM_HANDLE "\$acronym_accumulate_file = $def_acronym_acc_file_pm\n";
+	print ACRONYM_HANDLE "\n";
+	print ACRONYM_HANDLE "# any acronym definitions which should always be marked up can be copied here\n";
+	print ACRONYM_HANDLE "# from the acronym_accumulate_file file ...\n";
+	print ACRONYM_HANDLE "# \n";
+	print ACRONYM_HANDLE "# \n";
+	print ACRONYM_HANDLE "# \n";
+	print STDERR "written new options file to $acronym_options_file...\n";
+    } else {
+	print STDERR "read file $acronym_options_file...\n";
+	eval $file_text ;
+	warn $@ if $@;
+	print STDERR "evaluated file $acronym_options_file...\n";
+    }
+
+    $max_offset = $local_max_offset;
+    $upper_case = $local_upper_case;
+    $case_match = $local_case_match ;
+    $min_def_length = $local_min_def_length;
+    $min_acro_length = $local_min_acro_length;
+    $min_length_saving = $local_min_length_saving;
+    $allow_recursive = $local_allow_recursive;
+    $allow_all_caps = $local_allow_all_caps;
+    @stop_words = @local_stop_words;
+        
+
+    &read_all_acronyms_from_file($acronym_accumulate_file);
+#    rename $acronym_file, $acronym_file . "." . int(rand (2<<7)). 
+#	int(rand (2<<7)). int(rand (2<<7)). int(rand (2<<7));
+    if ($writing_acronyms && open ACRONYM_HANDLE, ">$acronym_accumulate_file")
+    {
+	print ACRONYM_HANDLE "#This is an automatically generated file.\n";
+	print ACRONYM_HANDLE "#\n";
+	print ACRONYM_HANDLE "#If you edit this file and it will be overwritten the next\n";
+	print ACRONYM_HANDLE "#time the acronym code runs unless you set the file to \n";
+	print ACRONYM_HANDLE "#read-only. \n";
+	print ACRONYM_HANDLE "#\n";
+	print ACRONYM_HANDLE "#start of acronyms...\n";
+	$writing_acronyms = 1;
+    } else {
+	warn "failed to open $acronym_accumulate_file for writing\n";
+	$writing_acronyms = 0;
+    }
+}
+
+#close the list of accumulated acronyms
+sub finalise_acronyms {
+    if ($writing_acronyms)
+    {
+	print ACRONYM_HANDLE "#end of acronyms.\n";  
+	close ACRONYM_HANDLE;
+    }
+}
+
+#eval a file of accumulated acronyms
+sub read_all_acronyms_from_file {
+    my ($acronym_accumulate_file) = @_;
+
+    my $file_text = " ";
+    if (open ACRONYM_HANDLE, "<$acronym_accumulate_file")
+    {
+	$file_text = do { local $/; <ACRONYM_HANDLE> };  
+    } else {
+	print STDERR "failed to open $acronym_accumulate_file for reading (this is the first pass?).\n";
+    }
+    eval $file_text;
+    #promotes warnings/errors from evaluated file to current context 
+    warn $@ if $@;
+}
+
+#called from within the file of accumulated acronyms to indicate a good acronym
+sub add {
+    my $self = shift (@_);
+    if (defined ($acronyms_found_in_collection{$self->[0]}))
+    {
+	my $def = $self->to_def_string();
+	if ($acronyms_found_in_collection{$self->[0]} =~ m/(^|\|)$def(\||$)/)
+	{
+	    return;
+	}
+	$acronyms_found_in_collection{$self->[0]} = 
+	    $acronyms_found_in_collection{$self->[0]} . "|" . $self->to_def_string();
+    } else {
+	$acronyms_found_in_collection{$self->[0]} = $self->to_def_string();
+    }
+}
+
+#called from within the file of accumulated acronyms to indicate a bad acronym
+sub ban {
+    my $self = shift (@_);
+    
+    if (!defined $acronyms_banned_from_collection{$self->[0]})
+    {
+	$acronyms_banned_from_collection{$self->[0]} = $self->to_def_string();
+    } else {
+	$acronyms_banned_from_collection{$self->[0]} = $acronyms_banned_from_collection{$self->[0]} . "|" . $self->to_def_string();
+    }
+}
+
+
+#write a good acronym to the accumulated acronyms file
+sub write_to_file {
+    my $self = shift (@_);
+    if ($writing_acronyms)
+    {
+	print ACRONYM_HANDLE "new acronym(\"$self->[0]\",\"" . 
+	    $self->to_def_string() . 
+		"\")->add();\n";
+    }
+}
+
+
+###########################################################################
+# mark functionality    
+###########################################################################
+
+#small routine to sort by length 
+sub sort_by_length {
+    length($b) <=> length($a) or $a cmp $b
+}
+
+sub markup_acronyms {
+    my  $text = shift (@_);
+    my  $verbosity_obj = shift (@_);
+    if (defined $text)
+    {
+	for my $acro (sort sort_by_length keys %acronyms_found_in_collection)
+	{
+	    $text  =~ s/^((?:[^\<\n]|(?:\<[^\>\n]*\>))*)$acro([^\<A-Z])/$1$acro\<img src=\"\" width=8 height=8 alt=\"$acronyms_found_in_collection{$acro}\"\>$2/gm;
+	    printf STDERR " " .  $acro . ","
+		if ($verbosity_obj->{'verbosity'} >= 2);
+	}
+    }
+    return $text;
+}
+
+
+
+###########################################################################
+#    member functions 
+###########################################################################
+
+
+sub new {
+    my $trash = shift (@_); 
+    my $acro = shift (@_); 
+    my $def  = shift (@_); 
+    
+    my $self = [
+		"", # 0 acronym
+		[], # 1 definition
+               ];
+    
+    $self->[0] = $acro                    if defined $acro;
+    push @{$self->[1]},  split / /, $def  if defined $def;
+    
+    bless $self;
+}
+
+sub clone  {
+    my $self = shift (@_);
+
+    my $copy = new acronym;
+
+    $copy->[0] = $self->[0];
+    push @{$copy->[1]}, @{$self->[1]};
+    bless $copy;
+
+    return $copy;
+}
+
+#return the acronym
+sub to_acronym {
+    my $self = shift (@_);
+    my @array = @{$self->[1]};
+
+    return $self->[0];
+}
+
+#return the number of words in the acronym definition
+sub words_in_acronym_definition {
+    my $self = shift (@_);
+    my @array = @{$self->[1]};
+
+    return $#array + 1;
+}
+
+#return the number of letters in the acronym definition
+sub letters_in_acronym_definition {
+    my $self = shift (@_);
+
+    return length($self->to_def_string());
+}
+
+#return the number of letters in the acronym definition
+sub letters_in_acronym {
+    my $self = shift (@_);
+
+    return length($self->to_acronym());
+}
+
+#return the acronym definition
+sub to_def_string {
+    my $self = shift (@_);
+
+    my $result = "";
+
+    # do the definition
+    my @array = @{$self->[1]};
+    my $i = 0;
+    while ($i <= $#array)
+    {
+	$result = $result . $array[$i];
+
+	if ($i+1 <= $#array)
+	{
+	    $result = $result . " ";
+	}
+	$i++;
+    }
+    return $result;
+}
+
+
+#print out the kwic for the acronym
+sub to_string_kwic {
+    my $self = shift (@_);
+
+    # the list of all possible combinations
+    my @list = ();
+
+    my $result = "";
+
+    my $j = 0;
+    my @array = @{$self->[1]};
+    while ($j <= $#array)
+    {
+
+	# do the definition
+	my $i = 0;
+
+	#add the key word
+	$result = "<td halign=left>"  . $array[$j] . "</td><td halign=right>";
+
+	#add the proceeding words
+	while ($i < $j)
+	{
+	    $result = $result .  $array[$i] . " ";
+	    $i++;
+	}
+	#add the key word
+	$result = $result . "</td><td halign=left>"  . $array[$j] . 
+	    "</td><td halign=left>";
+
+	#add the trailing words
+	$i++;
+	while ($i <= $#array )
+	{
+	    $result = $result .  $array[$i] . " ";
+	    $i++;
+	}
+
+	#add the actual acronym
+
+	$result = $result . "</td><td halign=left>" . $self->[0] . "</td>";
+
+	push @list, $result;
+	$j++;
+    }
+    return @list;
+}
+
+#this is the one used when building the collection ...
+sub to_string {
+    my $self = shift (@_);
+
+    my $result = $self->[0] . " ";
+
+    # do the definition
+    my @array = @{$self->[1]};
+    my $i = 0;
+    while ($i <= $#array)
+    {
+	$result = $result . $array[$i];
+	if ($i+1 <= $#array)
+	{
+	    $result = $result . " ";
+	}
+	$i++;
+    }
+    return $result;
+}
+
+sub check {
+    my $self = shift (@_);
+
+    if (length($self->to_acronym()) < $min_acro_length) 
+    {
+#	print "acronym " . $self->to_string() . " rejected (too short I)\n";
+	return 0;
+    }
+    if ($self->words_in_acronym_definition() < $min_def_length) 
+    {
+#	print "acronym " . $self->to_string() . " rejected (too short II)\n";
+	return 0;
+    }
+    if ($min_length_saving * $self->letters_in_acronym() > 
+	$self->letters_in_acronym_definition()) 
+    {
+#	print "acronym " . $self->to_string() . " rejected (too short III)\n";
+#	print "" . $min_length_saving .
+#	    "|" . $self->letters_in_acronym() .
+#	    "|" . $self->letters_in_acronym_definition() . "\n";
+	return 0;
+    }
+    if (!$allow_all_caps && 
+	$self->to_def_string() eq uc($self->to_def_string()))
+    {
+#	print "acronym " . $self->to_string() . " rejected (all upper)\n";
+	return 0;
+    }
+    if (!$allow_all_caps)
+    {
+	my $upper_count = 0;
+	my $lower_count = 0;
+	my @letters = $self->to_def_string();
+	for my $letter (split //, $self->to_def_string())
+	{
+	    if ($letter eq uc($letter))
+	    { 
+		$upper_count++;
+	    } else {
+		$lower_count++;
+	    }		
+	}
+	return 0 if ($upper_count > $lower_count);
+    }
+    if (!$allow_recursive && $self->to_def_string() =~ /$self->to_acronym()/i )
+    {
+	return 0;
+    }
+#    print "acronym " . $self->to_string() . " not rejected\n";
+    return 1;
+}
+
+###########################################################################
+#    static functions 
+###########################################################################
+
+sub recurse {
+    my ($acro_offset,       #offset of word we're finding acronyms for
+	$text_offset,       
+	$letter_offset, 
+	@def_so_far) = @_;
+
+    my $word = $split_text[$text_offset];
+    my $acro = $split_text[$acro_offset];
+    $word = "" if !defined $word;
+    $acro = "" if !defined $acro;
+    
+#    print "recurse(" . $acro_offset . ", " . $text_offset . ", " . 
+#	$letter_offset  . ", " . @def_so_far . ")\n";
+
+    #check for termination ...
+    if ($letter_offset >= length($acro))
+    {	
+	my $acronym = new acronym();
+	$acronym->[0] = $acro;
+	push @{$acronym->[1]}, @def_so_far;
+	if ($acronym->check())
+	{
+	    push @acronym_list, ( $acronym );
+	}
+#	print "acronym created\n";
+	return;
+    }
+    #check for recursion
+    if (!$allow_recursive)
+    {
+	if ($word eq $acro)
+	{
+#	    print "recursion detected\n";
+	    return;
+	}
+    }
+    
+    #skip a stop-word
+    my $i = 0;
+    if ($letter_offset != 0)
+    {
+	while ($i <= $#stop_words)
+	{
+	    if ($stop_words[$i] eq uc($word))
+	    {
+#	    print "::found stop word::" . $stop_words[$i] . "\n";
+		&recurse($acro_offset,
+			 $text_offset+1,
+			 $letter_offset,
+			 @def_so_far, $word);
+	    }
+	    $i++;
+	}
+    }
+    $i = 1;
+    #using the first $i letters ...
+    while ($letter_offset+$i <= length($acro) )
+    {
+#	print "". ((substr $word, 0, $i) . " " . 
+#	    (substr $acro, $letter_offset, $i) . "\n");
+	if (((!$case_match) &&
+	     (uc(substr $word, 0, $i) eq
+	      uc(substr $acro, $letter_offset, $i)))
+	    ||
+	    (($case_match) &&
+	     ((substr $word, 0, $i) eq
+	      (substr $acro, $letter_offset, $i))))
+	{
+#	    print "::match::\n";
+#	    print "" . ((substr $word, 0, $i) . " " . 
+#		   (substr $acro, $letter_offset, $i) . "\n");
+	    &recurse($acro_offset,
+		     $text_offset+1,
+		     $letter_offset+$i,
+		     @def_so_far, $word);
+	} else {
+	    return;
+	}	    
+	$i++;
+    }
+    return;
+}
+
+#the main
+sub acronyms {
+    #clean up the text
+    my $processed_text =  shift @_;
+    $$processed_text =~ s/<[^>]*>/ /g;
+    $$processed_text =~ s/\W/ /g;
+    $$processed_text =~ s/[0-9_]/ /g;
+    $$processed_text =~ s/\s+/ /g;
+    $$processed_text =~ s/(\n|\>)References.*/ /i;
+    $$processed_text =~ s/(\n|\>)Bibliography.*/ /i;
+    $$processed_text =~ s/(\n|\>)(Cited Works?).*/ /i;
+    $$processed_text =~ s/(\n|\>)(Works? Cited).*/ /i;
+
+    #clear some global variables
+    @split_text = ();
+    @acronym_list = ();
+
+    return &acronyms_from_clean_text($processed_text);
+}
+
+sub acronyms_from_clean_text {
+    my ($processed_text) = @_;
+
+    @split_text = split / /, $$processed_text;
+
+#    my $i = 0;
+#    while ($i <= $#split_text)
+#    {
+#	print $split_text[$i] . "\n";
+#	$i++;
+#    }
+
+    my $first = 0;
+    my $last = $#split_text +1;
+    my $acro_counter = $first;
+    
+    while ($acro_counter < $last)
+    {
+	my $word = $split_text[$acro_counter];
+
+	if ((!$upper_case) ||
+	    (uc($word) eq $word))
+	{
+	    
+	    if (length $word >= $min_acro_length)
+	    {
+		my $def_counter = 0;
+		if ($acro_counter - $max_offset > 0)
+		{
+		    $def_counter = $acro_counter - $max_offset;
+		}
+		my $local_last = $acro_counter  + $max_offset;
+		if ($local_last > $last)
+		{
+		    $local_last = $last;
+		}
+		while ($def_counter <= $local_last)
+		{
+		    &recurse($acro_counter,$def_counter,0,());
+		    $def_counter++;
+		}
+	    }
+	}
+	$acro_counter++;
+    }
+
+    return \@acronym_list;
+}
+
+
+
+sub test {
+
+#    my $blarg = new acronym();
+#    my $simple;
+#    $simple = 10;
+#    $blarg->initialise($simple, $simple, $simple);
+#    my $blarg2 = $blarg->clone();
+#    print $blarg->to_string();
+#    print $blarg2;
+#    print "\n";
+#    
+    my $tla = new acronym();
+    $tla->[0] = "TLA";
+
+    my @array = ("Three", "Letter", "Acronym");
+#    my $i = 0;
+#    while ($i <= $#array)
+#    {
+#	print @array[$i] . "\n";
+#	$i++;
+#    }
+
+    print "\n";
+    push @{$tla->[1]}, ("Three" );
+    push @{$tla->[1]}, ("Letter" );
+    push @{$tla->[1]}, ("Acronym" );
+    print $tla->to_string(). "\n";
+    print "\n";
+    print "\n";
+    my $tla2 = $tla->clone();
+    push @{$tla2->[1]}, ("One");
+    push @{$tla2->[1]}, ("Two");
+    $tla2->[0] = "ALT";
+    print $tla->to_string(). "\n";
+    print $tla2->to_string(). "\n";
+
+    print "\n";
+    print "\n";
+
+    print "Testing recursion ...\n";
+    my $acros = &acronyms("TLA Three Letter Acronym in tla TlA");
+    
+    foreach my $acro (@$acros)
+    {
+	if ($acro->check)
+        {
+           print "accepted: " .$acro->to_string() . "\n";
+#           print "|" .  $acro->to_acronym() . "|" .  $acro->to_def_string() .
+#              "|" .  $acro->words_in_acronym_definition() .
+#              "|" .  $acro->letters_in_acronym_definition() . 
+#              "|" .  $acro->letters_in_acronym() . "|\n";
+        } else {
+#          print "found but rejected: " .$acro->to_string() . "\n";
+        }
+    }
+}
+
+#uncomment this line to test this package
+#&test();
+
+1;
+
+
Index: /gsdl/stable/perllib/arcinfo.pm
===================================================================
--- /gsdl/stable/perllib/arcinfo.pm	(revision 20131)
+++ /gsdl/stable/perllib/arcinfo.pm	(revision 20131)
@@ -0,0 +1,449 @@
+###########################################################################
+#
+# arcinfo.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This module stores information about the archives. At the moment
+# this information just consists of the file name (relative to the
+# directory the archives information file is in) and its OID.
+
+# This module assumes there is a one to one correspondance between
+# a file in the archives directory and an OID.
+
+package arcinfo;
+
+use constant ORDER_OID_INDEX  => 0;
+use constant ORDER_SORT_INDEX => 1;
+
+use constant INFO_FILE_INDEX    => 0;
+use constant INFO_STATUS_INDEX  => 1;
+
+use strict;
+
+use dbutil;
+
+# File format read in: OID <tab> Filename <tab> Optional-Index-Status
+
+# Index status can be:
+#  I = Index for the first time
+#  R = Reindex
+#  D = Delete
+#  B = Been indexed
+
+sub new {
+    my ($class) = @_;
+    my $self = {'info'=>{},
+		'reverse-info'=>{},
+		'order'=>[],
+		'reverse_sort'=>0};
+
+    return bless $self, $class;
+}
+
+sub _load_info_txt 
+{
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    if (defined $filename && -e $filename) {
+	open (INFILE, $filename) || 
+	    die "arcinfo::load_info couldn't read $filename\n";
+
+	my ($line, @line);
+	while (defined ($line = <INFILE>)) {
+	    $line =~ s/\cM|\cJ//g; # remove end-of-line characters
+	    @line = split ("\t", $line); # filename, 
+	    if (scalar(@line) >= 2) {
+		$self->add_info (@line);
+	    }
+	}
+	close (INFILE);
+    }
+
+
+}
+
+sub _load_info_gdbm
+{
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    my $infodb_map = {};
+
+    &dbutil::read_infodb_file_gdbm($filename,$infodb_map);
+
+    foreach my $oid ( keys %$infodb_map ) {
+	my $vals = $infodb_map->{$oid};
+	# interested in doc-file and index-status
+
+	my ($doc_file) = ($vals=~/^<doc-file>(.*)$/m);
+	my ($index_status) = ($vals=~/^<index-status>(.*)$/m);
+	$self->add_info ($oid,$doc_file,$index_status);
+    }
+}
+
+
+sub load_info {
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    $self->{'info'} = {};
+
+    if ((defined $filename) && (-e $filename)) {
+	if ($filename =~ m/\.inf$/) {
+	    $self->_load_info_txt($filename);
+	}
+	else {
+	    $self->_load_info_gdbm($filename);
+	}
+    }
+}
+
+sub _load_filelist_gdbm
+{
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    my $infodb_map = {};
+
+    &dbutil::read_infodb_keys_gdbm($filename,$infodb_map);
+
+    foreach my $file ( keys %$infodb_map ) {
+	$self->{'prev_import_filelist'}->{$file} = 1;
+    }
+}
+
+
+sub load_prev_import_filelist {
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    $self->{'import-filelist'} = {};
+
+    if ((defined $filename) && (-e $filename)) {
+	if ($filename =~ m/\.inf$/) {
+	    # e.g. 'archives-src.inf' (which includes complete list of file
+	    # from last time import.pl was run)
+	    $self->_load_info_txt($filename);
+	}
+	else {
+	    $self->_load_filelist_gdbm($filename);
+	}
+    }
+}
+
+sub load_revinfo_UNTESTED
+{
+    my $self = shift (@_);
+    my ($rev_filename) = @_;
+
+    my $rev_infodb_map = {};
+
+    &dbutil::read_infodb_file_gdbm($rev_filename,$rev_infodb_map);
+
+    foreach my $srcfile ( keys %$rev_infodb_map ) {
+	my $vals = $rev_infodb_map->{$srcfile};
+
+	foreach my $OID ($vals =~ m/^<oid>(.*)$/gm) {
+	    $self->add_revinfo($srcfile,$OID);
+	}
+    }
+}
+
+
+sub _save_info_txt {
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    my ($OID, $info);
+
+    open (OUTFILE, ">$filename") || 
+	die "arcinfo::save_info couldn't write $filename\n";
+  
+    foreach $info (@{$self->get_OID_list()}) {
+	if (defined $info) {
+	    print OUTFILE join("\t", @$info), "\n";
+	}
+    }
+    close (OUTFILE);
+}
+
+sub _save_info_gdbm {
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    # Not the most efficient operation, but will do for now
+
+    # read it in
+    my $infodb_map = {};
+    &dbutil::read_infodb_file_gdbm($filename,$infodb_map);
+
+    # change index-status values
+    foreach my $info (@{$self->get_OID_list()}) {
+	if (defined $info) {
+	    my ($oid,$doc_file,$index_status) = @$info;
+	    if (defined $infodb_map->{$oid}) {
+		my $vals_ref = \$infodb_map->{$oid};
+		$$vals_ref =~ s/^<index-status>(.*)$/<index-status>$index_status/m;
+	    }
+	    else {
+		print STDERR "Warning: $filename does not have key $oid\n";
+	    }
+	}
+    }
+
+
+    # write out again
+    my $infodb_handle = &dbutil::open_infodb_write_handle_gdbm($filename);
+    foreach my $oid ( keys %$infodb_map ) {
+	# consider making the following a method in dbutil
+	# e.g. write_infodb_rawentry_gdbm($infodb_handle,$oid,$vals);
+
+	# no need to escape, as $infodb_map->{$oid} hasn't been unescaped
+	print $infodb_handle "[$oid]\n";
+	print $infodb_handle $infodb_map->{$oid};
+	print $infodb_handle '-' x 70, "\n";
+    }
+    &dbutil::close_infodb_write_handle_gdbm($infodb_handle);
+
+}
+
+sub save_revinfo_gdbm {
+    my $self = shift (@_);
+    my ($rev_filename) = @_;
+
+    # Output reverse lookup database
+
+    my $rev_infodb_map = $self->{'reverse-info'};
+    my $rev_infodb_handle 
+	= &dbutil::open_infodb_write_handle_gdbm($rev_filename,"append");
+
+    foreach my $key ( keys %$rev_infodb_map ) {
+	my $val_hash = $rev_infodb_map->{$key};
+	&dbutil::write_infodb_entry_gdbm($rev_infodb_handle,$key,$val_hash);
+    }
+    &dbutil::close_infodb_write_handle_gdbm($rev_infodb_handle);
+
+}
+
+sub save_info {
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    if ($filename =~ m/\.inf$/) {
+	$self->_save_info_txt($filename);
+    }
+    else {
+	$self->_save_info_gdbm($filename);
+    }
+}
+
+sub delete_info {
+    my $self = shift (@_);
+    my ($OID) = @_;
+
+    if (defined $self->{'info'}->{$OID}) {
+	delete $self->{'info'}->{$OID};
+	
+	my $i = 0;
+	while ($i < scalar (@{$self->{'order'}})) {
+	    if ($self->{'order'}->[$i]->[ORDER_OID_INDEX] eq $OID) {
+		splice (@{$self->{'order'}}, $i, 1);
+		last;
+	    }
+	    
+	    $i ++;
+	}
+    }
+}
+
+sub add_info {
+    my $self = shift (@_);
+    my ($OID, $doc_file, $index_status, $sortmeta) = @_;
+    $sortmeta = "" unless defined $sortmeta;
+    $index_status = "I" unless defined $index_status; # I = needs indexing
+
+    if (! defined($OID)) {
+	# only happens when no files can be processed?
+	return undef;
+    }
+
+    if (defined $self->{'info'}->{$OID}) {
+	# test to see if we are in a reindex situation
+
+	my $existing_status_info = $self->get_status_info($OID);
+
+	if ($existing_status_info eq "D") {
+	    # yes, we're in a reindexing situation
+	    $self->delete_info ($OID);
+
+
+	    # force setting to "reindex"
+	    $index_status = "R";
+
+	}
+	else {
+	    # some other, possibly erroneous, situation has arisen
+	    # where the document already seems to exist
+	    print STDERR "Warning: $OID already exists with index status $existing_status_info\n";
+	    print STDERR "         Deleting previous version\n";
+
+	    $self->delete_info ($OID);
+	}
+    }
+
+    $self->{'info'}->{$OID} = [$doc_file,$index_status];
+    push (@{$self->{'order'}}, [$OID, $sortmeta]);
+
+
+}
+
+sub set_status_info {
+    my $self = shift (@_);
+    my ($OID, $index_status) = @_;
+
+    my $OID_info = $self->{'info'}->{$OID};
+    $OID_info->[INFO_STATUS_INDEX] = $index_status;
+}
+
+
+sub get_status_info {
+    my $self = shift (@_);
+    my ($OID) = @_;
+
+    my $index_status = undef;
+
+    my $OID_info = $self->{'info'}->{$OID};
+    if (defined $OID_info) {
+	$index_status = $OID_info->[INFO_STATUS_INDEX];
+    }
+    else {
+	die "Unable to find document id $OID\n";
+    }
+
+    return $index_status;
+
+}
+
+
+sub add_reverseinfo {
+    my $self = shift (@_);
+    my ($key, $OID) = @_;
+
+    my $existing_key = $self->{'reverse-info'}->{$key};
+    if (!defined $existing_key) {
+	$existing_key = {};
+	$self->{'reverse-info'}->{$key} = $existing_key;
+    }
+
+    my $existing_oid = $existing_key->{'oid'};	
+    if (!defined $existing_oid) {
+	$existing_oid = [];
+	$existing_key->{'oid'} = $existing_oid;
+    }
+
+    push(@$existing_oid,$OID);
+}
+
+
+sub reverse_sort 
+{
+    my $self = shift(@_);
+    $self->{'reverse_sort'} = 1;
+}
+
+# returns a list of the form [[OID, doc_file, index_status], ...]
+sub get_OID_list 
+{
+    my $self = shift (@_);
+
+    my $order = $self->{'order'};
+
+    my @sorted_order;
+    if ($self->{'reverse_sort'}) {
+	@sorted_order = sort {$b->[ORDER_SORT_INDEX] cmp $a->[ORDER_SORT_INDEX]} @$order;
+    } else {
+	@sorted_order = sort {$a->[ORDER_SORT_INDEX] cmp $b->[ORDER_SORT_INDEX]} @$order;
+    }
+
+    my @list = ();
+
+    foreach my $OID_order (@sorted_order) {
+	my $OID = $OID_order->[ORDER_OID_INDEX];
+	my $OID_info = $self->{'info'}->{$OID};
+
+	push (@list, [$OID, $OID_info->[INFO_FILE_INDEX], 
+		      $OID_info->[INFO_STATUS_INDEX]]);
+    }
+
+    return \@list;
+}
+
+# returns a list of the form [[doc_file, OID], ...]
+sub get_file_list {
+    my $self = shift (@_);
+
+    my $order = $self->{'order'};
+
+    my @sorted_order;
+    if ($self->{'reverse_sort'}) {
+	@sorted_order = sort {$b->[ORDER_SORT_INDEX] cmp $a->[ORDER_SORT_INDEX]} @$order;
+    } else {
+	@sorted_order = sort {$a->[ORDER_SORT_INDEX] cmp $b->[ORDER_SORT_INDEX]} @$order;
+    }
+
+    my @list = ();
+
+    foreach my $OID_order (@sorted_order) {
+	my $OID = $OID_order->[ORDER_OID_INDEX];
+	my $OID_info = $self->{'info'}->{$OID};
+
+	push (@list, [$OID_info->[INFO_FILE_INDEX], $OID]);
+    }
+
+    return \@list;
+}
+
+
+# returns a list of the form [doc_file]
+sub get_info {
+    my $self = shift (@_);
+    my ($OID) = @_;
+
+    if (defined $self->{'info'}->{$OID}) {
+	return $self->{'info'}->{$OID};
+    }
+
+    return undef;
+}
+
+
+# returns the number of documents so far
+sub size {
+    my $self = shift (@_);
+    return (scalar(@{$self->{'order'}}));
+}
+
+1;
+
Index: /gsdl/stable/perllib/basebuilder.pm
===================================================================
--- /gsdl/stable/perllib/basebuilder.pm	(revision 20131)
+++ /gsdl/stable/perllib/basebuilder.pm	(revision 20131)
@@ -0,0 +1,711 @@
+###########################################################################
+#
+# basebuilder.pm -- base class for collection builders
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package basebuilder;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+use classify;
+use cfgread;
+use colcfg;
+use dbutil;
+use plugin;
+use util;
+
+
+BEGIN {
+    # set autoflush on for STDERR and STDOUT so that mgpp
+    # doesn't get out of sync with plugins
+    STDOUT->autoflush(1);
+    STDERR->autoflush(1);
+}
+
+END {
+    STDOUT->autoflush(0);
+    STDERR->autoflush(0);
+}
+
+our $maxdocsize = 12000;
+
+# used to signify "gs2"(default) or "gs3"
+our $gs_mode = "gs2";
+
+sub new {
+    my ($class, $collection, $source_dir, $build_dir, $verbosity, 
+	$maxdocs, $debug, $keepold, $incremental,
+	$remove_empty_classifications, 
+	$outhandle, $no_text, $failhandle, $gli, $disable_OAI) = @_;
+
+    $outhandle = *STDERR unless defined $outhandle;
+    $no_text = 0 unless defined $no_text;
+    $failhandle = *STDERR unless defined $failhandle;
+
+    # create a builder object
+    my $self = bless {'collection'=>$collection,
+		      'source_dir'=>$source_dir,
+		      'build_dir'=>$build_dir,
+		      'verbosity'=>$verbosity,
+		      'maxdocs'=>$maxdocs,
+		      'debug'=>$debug,
+		      'keepold'=>$keepold,
+		      'incremental'=>$incremental,
+		      'remove_empty_classifications'=>$remove_empty_classifications,
+		      'outhandle'=>$outhandle,
+		      'no_text'=>$no_text,
+		      'failhandle'=>$failhandle,
+		      'notbuilt'=>{},    # indexes not built
+		      'gli'=>$gli,
+		      'disable_OAI'=>$disable_OAI
+		      }, $class;
+
+    $self->{'gli'} = 0 unless defined $self->{'gli'};
+    
+    # disable_OAI applies to greenstone 3 only and is only passed to &colcfg::write_build_cfg_xml (then buildConfigxml::write_build_cfg_file) when writing the buildConfig.xml
+    $self->{'disable_OAI'} = 0 unless defined $self->{'disable_OAI'};
+
+    # Read in the collection configuration file.
+    my ($colcfgname);
+    ($colcfgname, $gs_mode) = &colcfg::get_collect_cfg_name($outhandle);
+    $self->{'collect_cfg'} = &colcfg::read_collection_cfg ($colcfgname, $gs_mode);
+
+    if ($gs_mode eq "gs3") {
+	# read it in again to save the original form for later writing out
+	# of buildConfig.xml
+	# we use this preserve object because $self->{'collect_cfg'}->{'classify'} somewhat gets modified during the calling of &classify::load_classifiers.
+	$self->{'collect_cfg_preserve'} = &colcfg::read_collection_cfg ($colcfgname, $gs_mode);	
+    }
+    
+    # get the database type for this collection from the collect.cfg file (may be undefined)
+    $self->{'infodbtype'} = $self->{'collect_cfg'}->{'infodbtype'} || &dbutil::get_default_infodb_type();
+
+    # get the list of plugins for this collection
+    my $plugins = [];
+    if (defined $self->{'collect_cfg'}->{'plugin'}) {
+	$plugins = $self->{'collect_cfg'}->{'plugin'};
+    }
+    
+    # load all the plugins
+
+    #build up the extra global options for the plugins
+    my @global_opts = ();
+    if (defined $self->{'collect_cfg'}->{'separate_cjk'} && $self->{'collect_cfg'}->{'separate_cjk'} =~ /^true$/i) {
+	push @global_opts, "-separate_cjk";
+    }
+    $self->{'pluginfo'} = &plugin::load_plugins ($plugins, $verbosity, $outhandle, $failhandle, \@global_opts, $keepold);
+   
+    if (scalar(@{$self->{'pluginfo'}}) == 0) {
+	print $outhandle "No plugins were loaded.\n";
+	die "\n";
+    }
+
+    # get the list of classifiers for this collection
+    my $classifiers = [];
+    if (defined $self->{'collect_cfg'}->{'classify'}) {
+	$classifiers = $self->{'collect_cfg'}->{'classify'};
+    }
+
+    # load all the classifiers
+    $self->{'classifiers'} = &classify::load_classifiers ($classifiers, $build_dir, $outhandle);
+
+    # load up any dontdb fields
+    $self->{'dontdb'} = {};
+    if (defined ($self->{'collect_cfg'}->{'dontgdbm'})) {
+	foreach my $dg (@{$self->{'collect_cfg'}->{'dontgdbm'}}) {
+	    $self->{'dontdb'}->{$dg} = 1;
+	}
+    }
+
+    $self->{'maxnumeric'} = 4;
+    return $self;
+}
+
+# stuff has been moved here from new, so we can use subclass methods
+sub init {
+    my $self = shift(@_);
+    
+    $self->generate_index_list();
+    my $indexes = $self->{'collect_cfg'}->{'indexes'};
+    if (defined $indexes) {
+	# sort out subcollection indexes
+	if (defined $self->{'collect_cfg'}->{'indexsubcollections'}) {
+	    $self->{'collect_cfg'}->{'indexes'} = [];
+	    foreach my $subcollection (@{$self->{'collect_cfg'}->{'indexsubcollections'}}) {
+		foreach my $index (@$indexes) {
+		    push (@{$self->{'collect_cfg'}->{'indexes'}}, "$index:$subcollection");
+		}
+	    }
+	}
+	
+	# sort out language subindexes
+	if (defined $self->{'collect_cfg'}->{'languages'}) {
+	    $indexes = $self->{'collect_cfg'}->{'indexes'};
+	    $self->{'collect_cfg'}->{'indexes'} = [];
+	    foreach my $language (@{$self->{'collect_cfg'}->{'languages'}}) {
+		foreach my $index (@$indexes) {
+		    if (defined ($self->{'collect_cfg'}->{'indexsubcollections'})) {
+			push (@{$self->{'collect_cfg'}->{'indexes'}}, "$index:$language");
+		    }
+		    else { # add in an empty subcollection field
+			push (@{$self->{'collect_cfg'}->{'indexes'}}, "$index\:\:$language");
+		    }
+		}
+	    }
+	}
+    }
+    
+    if (defined($self->{'collect_cfg'}->{'indexes'})) {
+	# make sure that the same index isn't specified more than once
+	my %tmphash = ();
+	my @tmparray = @{$self->{'collect_cfg'}->{'indexes'}};
+	$self->{'collect_cfg'}->{'indexes'} = [];
+	foreach my $i (@tmparray) {
+	    if (!defined ($tmphash{$i})) {
+		push (@{$self->{'collect_cfg'}->{'indexes'}}, $i);
+		$tmphash{$i} = 1;
+	    }
+	}
+    } else {
+	$self->{'collect_cfg'}->{'indexes'} = [];
+    }
+
+    # load up the document processor for building
+    # if a buildproc class has been created for this collection, use it
+    # otherwise, use the mg buildproc
+    my ($buildprocdir, $buildproctype);
+    my $collection = $self->{'collection'};
+    if (-e "$ENV{'GSDLCOLLECTDIR'}/custom/${collection}/perllib/custombuildproc.pm") {
+	$buildprocdir = "$ENV{'GSDLCOLLECTDIR'}/custom/${collection}/perllib";
+	$buildproctype = "custombuildproc";
+    } elsif (-e "$ENV{'GSDLCOLLECTDIR'}/perllib/custombuildproc.pm") {
+	$buildprocdir = "$ENV{'GSDLCOLLECTDIR'}/perllib";
+	$buildproctype = "custombuildproc";
+    } elsif (-e "$ENV{'GSDLCOLLECTDIR'}/perllib/${collection}buildproc.pm") {
+	$buildprocdir = "$ENV{'GSDLCOLLECTDIR'}/perllib";
+	$buildproctype = "${collection}buildproc";
+    } else {
+	$buildprocdir = "$ENV{'GSDLHOME'}/perllib";
+	$buildproctype = $self->default_buildproc();
+    }
+    require "$buildprocdir/$buildproctype.pm";
+
+    eval("\$self->{'buildproc'} = new $buildproctype(\$self->{'collection'}, " .
+	 "\$self->{'source_dir'}, \$self->{'build_dir'}, \$self->{'keepold'}, \$self->{'verbosity'}, \$self->{'outhandle'})");
+    die "$@" if $@;
+
+    
+   $self->generate_index_options();
+
+    if (!$self->{'debug'} && !$self->{'keepold'}) {
+	# remove any old builds
+	&util::rm_r($self->{'build_dir'});
+	&util::mk_all_dir($self->{'build_dir'});
+        
+	# make the text directory
+	my $textdir = "$self->{'build_dir'}/text";
+	&util::mk_all_dir($textdir);
+    }
+
+    if ($self->{'incremental'}) {
+	# some classes may need to do some additional initialisation
+	$self->init_for_incremental_build();
+    }
+    
+}
+
+# implement this in subclass if want to do additional initialisation for an
+# incremental build
+sub init_for_incremental_build {
+    my $self = shift (@_);
+}
+
+sub deinit {
+    my $self = shift (@_);
+    
+    &plugin::deinit($self->{'pluginfo'},$self->{'buildproc'});
+}
+
+sub generate_index_options {
+    my $self = shift (@_);
+
+    my $separate_cjk = 0;
+    
+    if (defined($self->{'collect_cfg'}->{'indexoptions'})) {
+	foreach my $option (@{$self->{'collect_cfg'}->{'indexoptions'}}) {
+	    if ($option =~ /separate_cjk/) {
+		$separate_cjk = 1;
+	    }
+	}
+    }
+    # set this for building
+    $self->{'buildproc'}->set_separate_cjk($separate_cjk);
+    # record it for build.cfg
+    $self->{'separate_cjk'} = $separate_cjk;
+}
+ 
+sub set_sections_index_document_metadata {
+    my $self = shift (@_);
+    my ($index) = @_;
+  
+    $self->{'buildproc'}->set_sections_index_document_metadata($index);
+}
+
+sub set_maxnumeric {
+    my $self = shift (@_);
+    my ($maxnumeric) = @_;
+
+    $self->{'maxnumeric'} = $maxnumeric;
+}
+sub set_strip_html {
+    my $self = shift (@_);
+    my ($strip) = @_;
+    
+    $self->{'strip_html'} = $strip;
+    $self->{'buildproc'}->set_strip_html($strip);
+}
+
+sub compress_text {
+    my $self = shift (@_);
+    my ($textindex) = @_;
+
+    print STDERR "compress_text() should be implemented in subclass!!";
+    return;
+}
+
+
+sub build_indexes {
+    my $self = shift (@_);
+    my ($indexname) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my $indexes = [];
+    if (defined $indexname && $indexname =~ /\w/) {
+	push @$indexes, $indexname;
+    } else {
+	$indexes = $self->{'collect_cfg'}->{'indexes'};
+    }
+
+    # create the mapping between the index descriptions 
+    # and their directory names (includes subcolls and langs)
+    $self->{'index_mapping'} = $self->create_index_mapping ($indexes);
+   
+    # build each of the indexes
+    foreach my $index (@$indexes) {
+	if ($self->want_built($index)) {
+	    print $outhandle "\n*** building index $index in subdirectory " . 
+		"$self->{'index_mapping'}->{$index}\n" if ($self->{'verbosity'} >= 1);
+	    print STDERR "<Stage name='Index' source='$index'>\n" if $self->{'gli'};
+	    $self->build_index($index);
+	} else {
+	    print $outhandle "\n*** ignoring index $index\n" if ($self->{'verbosity'} >= 1);
+	}
+    }
+
+    $self->build_indexes_extra();
+
+}
+
+# implement this in subclass if want to do extra stuff at the end of building
+# all the indexes
+sub build_indexes_extra {
+    my $self = shift(@_);
+    
+}
+
+sub build_index {
+    my $self = shift (@_);
+    my ($index) = @_;
+    
+    print STDERR "build_index should be implemented in subclass\n";
+    return;
+}
+
+
+
+sub make_infodatabase {
+    my $self = shift (@_);
+    my $outhandle = $self->{'outhandle'};
+
+    print STDERR "BuildDir: $self->{'build_dir'}\n";
+
+    my $textdir = &util::filename_cat($self->{'build_dir'}, "text");
+    my $assocdir = &util::filename_cat($self->{'build_dir'}, "assoc");
+    &util::mk_all_dir ($textdir);
+    &util::mk_all_dir ($assocdir);
+
+    # Get info database file path
+    my $infodb_file_path = &dbutil::get_infodb_file_path($self->{'infodbtype'}, $self->{'collection'}, $textdir);
+
+    print $outhandle "\n*** creating the info database and processing associated files\n" 
+	if ($self->{'verbosity'} >= 1);
+    print STDERR "<Stage name='CreateInfoData'>\n" if $self->{'gli'};
+
+    # init all the classifiers
+    &classify::init_classifiers ($self->{'classifiers'});
+
+    my $reconstructed_docs = undef;
+    if ($self->{'keepold'}) {
+	# reconstruct doc_obj metadata from database for all docs
+	$reconstructed_docs = &classify::reconstruct_doc_objs_metadata($self->{'infodbtype'}, $infodb_file_path);
+    }
+    
+    # set up the document processor
+    my ($infodb_handle);
+    if ($self->{'debug'}) {
+	$infodb_handle = *STDOUT;
+    }
+    else {
+	$infodb_handle = &dbutil::open_infodb_write_handle($self->{'infodbtype'}, $infodb_file_path);
+	if (!defined($infodb_handle))
+	{
+	    print STDERR "<FatalError name='NoRunText2DB'/>\n</Stage>\n" if $self->{'gli'};
+	    die "builder::make_infodatabase - couldn't open infodb write handle\n";
+	}
+    }
+
+    $self->{'buildproc'}->set_infodbtype ($self->{'infodbtype'});
+    $self->{'buildproc'}->set_output_handle ($infodb_handle);
+    $self->{'buildproc'}->set_mode ('infodb');
+    $self->{'buildproc'}->set_assocdir ($assocdir);
+    $self->{'buildproc'}->set_dontdb ($self->{'dontdb'});
+    $self->{'buildproc'}->set_classifiers ($self->{'classifiers'});
+    $self->{'buildproc'}->set_indexing_text (0);
+    $self->{'buildproc'}->set_store_text(1);
+    $self->{'buildproc'}->set_store_metadata_coverage ($self->{'collect_cfg'}->{'store_metadata_coverage'});
+
+    # make_infodatabase needs full reset even for incremental build
+    # as incremental works by reconstructing all docs from the database and
+    # then adding in the new ones
+    $self->{'buildproc'}->zero_reset(); 
+
+    $self->{'buildproc'}->{'mdprefix_fields'} = {};
+
+    if ($self->{'keepold'}) {
+	# create flat classify structure, ready for new docs to be added
+	foreach my $doc_obj ( @$reconstructed_docs ) {	    
+	    print $outhandle "  Adding reconstructed ", $doc_obj->get_OID(), " into classify structures\n";
+	    $self->{'buildproc'}->process($doc_obj,undef);
+	}
+    }
+
+   
+    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'}, 
+		   "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'},0, $self->{'gli'});
+
+    # this has changed to only output collection meta if its 
+    # not in the config file
+    $self->output_collection_meta($infodb_handle);
+    
+    # output classification information
+    &classify::output_classify_info ($self->{'classifiers'}, $self->{'infodbtype'}, $infodb_handle,
+				     $self->{'remove_empty_classifications'}, 
+				     $self->{'gli'});
+
+    # Output classifier reverse lookup, used in incremental deletion
+    ####&classify::print_reverse_lookup($infodb_handle);
+
+    # output doclist
+    my @doc_list = $self->{'buildproc'}->get_doc_list();
+    my $browselist_infodb = { 'hastxt' => [ "0" ],
+			      'childtype' => [ "VList" ],
+			      'numleafdocs' => [ scalar(@doc_list) ],
+			      'thistype' => [ "Invisible" ],
+			      'contains' => [ join(";", @doc_list) ] };
+    &dbutil::write_infodb_entry($self->{'infodbtype'}, $infodb_handle, "browselist", $browselist_infodb);
+
+    &dbutil::close_infodb_write_handle($self->{'infodbtype'}, $infodb_handle) if !$self->{'debug'};
+
+    print STDERR "</Stage>\n" if $self->{'gli'};
+}
+
+sub make_auxiliary_files {
+    my $self = shift (@_);
+    my ($index);
+    my $build_cfg = {};
+    # subclasses may have already defined stuff in here
+    if (defined $self->{'build_cfg'}) {
+	$build_cfg = $self->{'build_cfg'};
+    }
+
+    my $outhandle = $self->{'outhandle'};
+
+    print $outhandle "\n*** creating auxiliary files \n" if ($self->{'verbosity'} >= 1);
+    print STDERR "<Stage name='CreatingAuxilary'>\n" if $self->{'gli'};
+
+    # get the text directory
+    &util::mk_all_dir ($self->{'build_dir'});
+
+    # store the build date
+    $build_cfg->{'builddate'} = time;
+    $build_cfg->{'buildtype'} = $self->{'buildtype'};
+    $build_cfg->{'indexstem'} = &util::get_dirsep_tail($self->{'collection'});
+    $build_cfg->{'stemindexes'} = $self->{'stemindexes'};
+    if ($self->{'separate_cjk'}) {
+	$build_cfg->{'separate_cjk'} = "true";
+    }
+    
+    # store the number of documents and number of bytes
+    $build_cfg->{'numdocs'} = $self->{'buildproc'}->get_num_docs();
+    $build_cfg->{'numsections'} = $self->{'buildproc'}->get_num_sections();
+    $build_cfg->{'numbytes'} = $self->{'buildproc'}->get_num_bytes();
+
+    # store the mapping between the index names and the directory names
+    # the index map is used to determine what indexes there are, so any that are not built should not be put into the map.
+    my @indexmap = ();
+    foreach my $index (@{$self->{'index_mapping'}->{'indexmaporder'}}) {
+	if (not defined ($self->{'notbuilt'}->{$index})) {
+	    push (@indexmap, "$index\-\>$self->{'index_mapping'}->{'indexmap'}->{$index}");
+	}
+    }
+    $build_cfg->{'indexmap'} = \@indexmap if scalar (@indexmap);
+
+    my @subcollectionmap = ();
+    foreach my $subcollection (@{$self->{'index_mapping'}->{'subcollectionmaporder'}}) {
+	push (@subcollectionmap, "$subcollection\-\>" .
+	      $self->{'index_mapping'}->{'subcollectionmap'}->{$subcollection});
+    }
+    $build_cfg->{'subcollectionmap'} = \@subcollectionmap if scalar (@subcollectionmap);
+
+    my @languagemap = ();
+    foreach my $language (@{$self->{'index_mapping'}->{'languagemaporder'}}) {
+	push (@languagemap, "$language\-\>" .
+	      $self->{'index_mapping'}->{'languagemap'}->{$language});
+    }
+    $build_cfg->{'languagemap'} = \@languagemap if scalar (@languagemap);
+
+    my @notbuilt = ();
+    foreach my $nb (keys %{$self->{'notbuilt'}}) {
+	push (@notbuilt, $nb);
+    }
+    $build_cfg->{'notbuilt'} = \@notbuilt if scalar (@notbuilt);
+
+    $build_cfg->{'maxnumeric'} = $self->{'maxnumeric'};
+
+    $build_cfg->{'infodbtype'} = $self->{'infodbtype'};
+
+    $self->build_cfg_extra($build_cfg);
+
+    if ($gs_mode eq "gs2") {
+      &colcfg::write_build_cfg(&util::filename_cat($self->{'build_dir'},"build.cfg"), $build_cfg);
+    }
+    if ($gs_mode eq "gs3") {
+
+      &colcfg::write_build_cfg_xml(&util::filename_cat($self->{'build_dir'}, "buildConfig.xml"), $build_cfg, $self->{'collect_cfg_preserve'}, $self->{'disable_OAI'});
+    }    
+
+    print STDERR "</Stage>\n" if $self->{'gli'};
+}
+
+# implement this in subclass if want to add extra stuff to build.cfg
+sub build_cfg_extra {
+   my $self = shift(@_);
+   my ($build_cfg) = @_;
+   
+}
+
+
+sub collect_specific {
+    my $self = shift (@_);
+}
+
+sub want_built {
+    my $self = shift (@_);
+    my ($index) = @_;
+
+    if (defined ($self->{'collect_cfg'}->{'dontbuild'})) {
+	foreach my $checkstr (@{$self->{'collect_cfg'}->{'dontbuild'}}) {
+	    if ($index =~ /^$checkstr$/) {
+		$self->{'notbuilt'}->{$index} = 1;
+		return 0;
+	    }
+	}
+    }
+
+    return 1;
+}
+
+sub create_index_mapping {
+    my $self = shift (@_);
+    my ($indexes) = @_;
+
+    print STDERR "create_index_mapping should be implemented in subclass\n";
+    my %mapping = ();
+    return \%mapping;
+}
+
+# returns a processed version of a field.
+# if the field has only one component the processed
+# version will contain the first character and next consonant
+# of that componant - otherwise it will contain the first 
+# character of the first two components 
+# only uses letdig (\w) characters now
+sub process_field {
+    my $self = shift (@_);
+    my ($field) = @_;
+
+    return "" unless (defined ($field) && $field =~ /\S/);
+    
+    my ($a, $b);
+    my @components = split /,/, $field;
+    if (scalar @components >= 2) {
+	# pick the first letdig from the first two field names
+	($a) = $components[0] =~ /^[^\w]*(\w)/;
+	($b) = $components[1] =~ /^[^\w]*(\w)/;
+    } else {
+	# pick the first two letdig chars
+	($a, $b) = $field =~ /^[^\w]*(\w)[^\w]*?(\w)/i;
+    }
+    # there may not have been any letdigs...
+    $a = 'a' unless defined $a;
+    $b = '0' unless defined $b;
+
+    return "$a$b";
+    
+}
+
+sub get_next_version {
+    my $self = shift (@_);
+    my ($nameref) = @_;
+    my $num=0;
+    if ($$nameref =~ /(\d\d)$/) {
+	$num = $1; $num ++;
+	$$nameref =~ s/\d\d$/$num/;
+    } elsif ($$nameref =~ /(\d)$/) {
+	$num = $1;
+	if ($num == 9) {$$nameref =~ s/\d$/10/;}
+	else {$num ++; $$nameref =~ s/\d$/$num/;}
+    } else {
+	$$nameref =~ s/.$/0/;
+    }
+}
+
+
+
+sub get_collection_meta_sets
+{
+    my $self = shift(@_);
+    my $collection_infodb = shift(@_);
+
+    my $mdprefix_fields = $self->{'buildproc'}->{'mdprefix_fields'};
+    foreach my $prefix (keys %$mdprefix_fields)
+    {
+	push(@{$collection_infodb->{"metadataset"}}, $prefix);
+
+	foreach my $field (keys %{$mdprefix_fields->{$prefix}})
+	{
+	    push(@{$collection_infodb->{"metadatalist-$prefix"}}, $field);
+
+	    my $val = $mdprefix_fields->{$prefix}->{$field};
+	    push(@{$collection_infodb->{"metadatafreq-$prefix-$field"}}, $val);
+	}
+    }
+}
+
+
+# default is to output the metadata sets (prefixes) used in collection
+sub output_collection_meta
+{
+    my $self = shift(@_);
+    my $infodb_handle = shift(@_);
+
+    my %collection_infodb = ();
+    $self->get_collection_meta_sets(\%collection_infodb);
+    &dbutil::write_infodb_entry($self->{'infodbtype'}, $infodb_handle, "collection", \%collection_infodb);
+}
+
+# sometimes we need to read in an existing build.cfg - for example, 
+# if doing each stage of building separately, or when doing incremental 
+# building
+sub read_build_cfg {
+    my $self = shift(@_);
+
+    my $buildconfigfilename;
+    
+    if ($gs_mode eq "gs2") {
+	$buildconfigfilename = "build.cfg";
+    } else {
+	$buildconfigfilename = "buildConfig.xml";
+    }
+    
+    my $buildconfigfile = &util::filename_cat($self->{'build_dir'}, $buildconfigfilename);
+    
+    if (!-e $buildconfigfile) {
+	# try the index dir - but do we know where it is?? try here
+	$buildconfigfile  = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "index", $buildconfigfilename);
+	if (!-e $buildconfigfile) {
+	    #we cant find a config file - just ignore the field list
+	    return undef;
+	}
+    } 
+    return &colcfg::read_building_cfg( $buildconfigfile, $gs_mode);
+    
+}
+
+sub print_stats {
+    my $self = shift (@_);
+
+    my $outhandle = $self->{'outhandle'};
+    my $indexing_text = $self->{'buildproc'}->get_indexing_text();
+    my $index = $self->{'buildproc'}->get_index();
+    my $num_bytes = $self->{'buildproc'}->get_num_bytes();
+    my $num_processed_bytes = $self->{'buildproc'}->get_num_processed_bytes();
+
+    if ($indexing_text) {
+	print $outhandle "Stats (Creating index $index)\n";
+    } else {
+	print $outhandle "Stats (Compressing text from $index)\n";
+    }
+    print $outhandle "Total bytes in collection: $num_bytes\n";
+    print $outhandle "Total bytes in $index: $num_processed_bytes\n";
+
+    if ($num_processed_bytes < 50 && ($indexing_text || !$self->{'no_text'})) {
+	
+	if ($self->{'keepold'}) {
+	    if ($num_processed_bytes == 0) {
+		if ($indexing_text) {
+		    print $outhandle "No additional text was added to $index\n";
+		} elsif (!$self->{'no_text'}) {
+		    print $outhandle "No additional text was compressed\n";
+		}	
+	    }	
+	}
+	else {
+	    print $outhandle "***************\n";
+	    if ($indexing_text) {
+		print $outhandle "WARNING: There is very little or no text to process for $index\n";
+	    } elsif (!$self->{'no_text'}) {
+		print $outhandle "WARNING: There is very little or no text to compress\n";
+	    }	   
+	    print $outhandle "         Was this your intention?\n";
+	    print $outhandle "***************\n";
+	}
+
+    }
+
+}
+
+  
+1;
+
Index: /gsdl/stable/perllib/basebuildproc.pm
===================================================================
--- /gsdl/stable/perllib/basebuildproc.pm	(revision 20131)
+++ /gsdl/stable/perllib/basebuildproc.pm	(revision 20131)
@@ -0,0 +1,840 @@
+##########################################################################
+#
+# basebuildproc.pm -- 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# This document processor outputs a document for indexing (should be 
+# implemented by subclass) and storing in the database
+
+package basebuildproc;
+
+eval {require bytes};
+
+use classify;
+use dbutil;
+use doc;
+use docproc;
+use strict; 
+no strict 'subs';
+no strict 'refs';
+use util;
+
+BEGIN {
+    @basebuildproc::ISA = ('docproc');
+}
+
+sub new()
+  {
+    my ($class, $collection, $source_dir, $build_dir, $keepold, $verbosity, $outhandle) = @_;
+    my $self = new docproc ();
+
+    # outhandle is where all the debugging info goes
+    # output_handle is where the output of the plugins is piped
+    # to (i.e. mg, database etc.)
+    $outhandle = STDERR unless defined $outhandle;
+
+    $self->{'collection'} = $collection;
+    $self->{'source_dir'} = $source_dir;
+    $self->{'build_dir'}  = $build_dir;
+    $self->{'keepold'}    = $keepold;
+    $self->{'verbosity'}  = $verbosity;
+    $self->{'outhandle'}  = $outhandle;
+
+    $self->{'classifiers'} = [];
+    $self->{'mode'} = "text";
+    $self->{'assocdir'} = $build_dir;
+    $self->{'dontdb'} = {};
+    $self->{'store_metadata_coverage'} = "false";
+
+    $self->{'index'} = "section:text";
+    $self->{'indexexparr'} = [];
+
+    $self->{'separate_cjk'} = 0;
+
+    my $found_num_data = 0;
+    my $buildconfigfile = undef;
+
+    if ($keepold) {
+	# For incremental building need to seed num_docs etc from values
+	# stored in build.cfg (if present)
+	$buildconfigfile = &util::filename_cat($build_dir, "build.cfg");
+	if (-e $buildconfigfile) {
+	    $found_num_data = 1;
+	}
+	else {
+	    # try the index dir
+	    $buildconfigfile = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, 
+						   "index", "build.cfg");
+	    if (-e $buildconfigfile) {
+		$found_num_data = 1;
+	    }
+	}
+
+    }
+
+    if ($found_num_data)
+      {
+        #print STDERR "Found_Num_Data!\n";
+	my $buildcfg = &colcfg::read_build_cfg($buildconfigfile);
+	$self->{'starting_num_docs'}     = $buildcfg->{'numdocs'};
+        #print STDERR "- num_docs:     $self->{'starting_num_docs'}\n";
+	$self->{'starting_num_sections'} = $buildcfg->{'numsections'};
+        #print STDERR "- num_sections: $self->{'starting_num_sections'}\n";
+	$self->{'starting_num_bytes'}    = $buildcfg->{'numbytes'};
+        #print STDERR "- num_bytes:    $self->{'starting_num_bytes'}\n";
+    }
+    else
+      {
+        #print STDERR "NOT Found_Num_Data!\n";
+        $self->{'starting_num_docs'}     = 0;
+	$self->{'starting_num_sections'} = 0;
+	$self->{'starting_num_bytes'}    = 0;
+      }
+
+    $self->{'output_handle'} = "STDOUT";
+    $self->{'num_docs'}      = $self->{'starting_num_docs'};
+    $self->{'num_sections'}  = $self->{'starting_num_sections'};
+    $self->{'num_bytes'}     = $self->{'starting_num_bytes'};
+
+    $self->{'num_processed_bytes'} = 0;
+    $self->{'store_text'} = 1;
+
+    # what level (section/document) the database - indexer intersection is
+    $self->{'db_level'} = "section";
+    #used by browse interface
+    $self->{'doclist'} = [];
+
+    $self->{'indexing_text'} = 0;
+
+    return bless $self, $class;
+
+}
+
+sub reset {
+    my $self = shift (@_);
+
+    $self->{'num_docs'}      = $self->{'starting_num_docs'};
+    $self->{'num_sections'}  = $self->{'starting_num_sections'};
+    $self->{'num_bytes'}     = $self->{'starting_num_bytes'};
+    
+    $self->{'num_processed_bytes'} = 0;
+}
+
+sub zero_reset {
+    my $self = shift (@_);
+
+    $self->{'num_docs'}      = 0;
+    $self->{'num_sections'}  = 0;
+    # reconstructed docs have no text, just metadata, so we need to 
+    # remember how many bytes we had initially
+    $self->{'num_bytes'}     = $self->{'starting_num_bytes'};
+    
+    $self->{'num_processed_bytes'} = 0;
+}
+
+sub is_incremental_capable
+{
+    # By default we return 'no' as the answer
+    # Safer to assume non-incremental to start with, and then override in
+    # inherited classes that are.
+
+    return 0;
+}
+
+sub get_num_docs {
+    my $self = shift (@_);
+
+    return $self->{'num_docs'};
+}
+
+sub get_num_sections {
+    my $self = shift (@_);
+
+    return $self->{'num_sections'};
+}
+
+# num_bytes is the actual number of bytes in the collection
+# this is normally the same as what's processed during text compression
+sub get_num_bytes {
+    my $self = shift (@_);
+
+    return $self->{'num_bytes'};
+}
+
+# num_processed_bytes is the number of bytes actually passed
+# to mg for the current index
+sub get_num_processed_bytes {
+    my $self = shift (@_);
+
+    return $self->{'num_processed_bytes'};
+}
+
+sub set_output_handle {
+    my $self = shift (@_);
+    my ($handle) = @_;
+
+    $self->{'output_handle'} = $handle;
+}
+
+
+sub set_mode {
+    my $self = shift (@_);
+    my ($mode) = @_;
+
+    $self->{'mode'} = $mode;
+}
+
+sub get_mode {
+    my $self = shift (@_);
+
+    return $self->{'mode'};
+}
+
+sub set_assocdir {
+    my $self = shift (@_);
+    my ($assocdir) = @_;
+
+    $self->{'assocdir'} = $assocdir;
+}
+
+sub set_dontdb {
+    my $self = shift (@_);
+    my ($dontdb) = @_;
+
+    $self->{'dontdb'} = $dontdb;
+}
+
+sub set_infodbtype
+{
+    my $self = shift(@_);
+    my $infodbtype = shift(@_);
+    $self->{'infodbtype'} = $infodbtype;
+}
+
+sub set_index {
+    my $self = shift (@_);
+    my ($index, $indexexparr) = @_;
+
+    $self->{'index'} = $index;
+    $self->{'indexexparr'} = $indexexparr if defined $indexexparr;
+}
+
+sub set_index_languages {
+    my $self = shift (@_);
+    my ($lang_meta, $langarr) = @_;
+    $self->{'lang_meta'} = $lang_meta;
+    $self->{'langarr'} = $langarr;
+}
+
+sub get_index {
+    my $self = shift (@_);
+
+    return $self->{'index'};
+}
+
+sub set_classifiers {
+    my $self = shift (@_);
+    my ($classifiers) = @_;
+
+    $self->{'classifiers'} = $classifiers;
+}
+
+sub set_indexing_text {
+    my $self = shift (@_);
+    my ($indexing_text) = @_;
+
+    $self->{'indexing_text'} = $indexing_text;
+}
+
+sub get_indexing_text {
+    my $self = shift (@_);
+
+    return $self->{'indexing_text'};
+}
+
+sub set_store_text {
+    my $self = shift (@_);
+    my ($store_text) = @_;
+
+    $self->{'store_text'} = $store_text;
+}
+
+sub set_store_metadata_coverage {
+    my $self = shift (@_);
+    my ($store_metadata_coverage) = @_;
+
+    $self->{'store_metadata_coverage'} = $store_metadata_coverage || "";
+}
+
+sub get_doc_list {
+    my $self = shift(@_);
+    
+    return @{$self->{'doclist'}};
+}
+
+# the standard database level is section, but you may want to change it to document
+sub set_db_level {
+    my $self= shift (@_);
+    my ($db_level) = @_;
+
+    $self->{'db_level'} = $db_level;
+}
+
+sub set_sections_index_document_metadata {
+    my $self= shift (@_);
+    my ($index_type) = @_;
+    
+    $self->{'sections_index_document_metadata'} = $index_type;
+}
+
+sub set_separate_cjk {
+    my $self = shift (@_);
+    my ($sep_cjk) = @_;
+
+    $self->{'separate_cjk'} = $sep_cjk;
+}
+
+sub process {
+    my $self = shift (@_);
+    my $method = $self->{'mode'};
+
+    $self->$method(@_);
+}
+
+# post process text depending on field. Currently don't do anything here
+# except cjk separation, and only for indexing
+# should only do this for indexed text (if $self->{'indexing_text'}), 
+# but currently search term highlighting doesn't work if you do that.
+# once thats fixed up, then fix this.
+sub filter_text {
+    my $self = shift (@_);
+    my ($field, $text) = @_;
+
+    # lets do cjk seg here
+    my $new_text =$text;
+    if ($self->{'separate_cjk'}) {
+	$new_text = &cnseg::segment($text);
+    }
+    return $new_text;
+}
+
+
+sub infodb_metadata_stats
+{
+    my $self = shift (@_);
+    my ($field,$edit_mode) = @_;
+
+    # Keep some statistics relating to metadata sets used and
+    # frequency of particular metadata fields within each set
+
+    # Union of metadata prefixes and frequency of fields
+    # (both scoped for this document alone, and across whole collection)
+    
+    if ($field =~ m/^(.+)\.(.*)$/) {
+	my $prefix = $1;
+	my $core_field = $2;
+
+	if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+	    $self->{'doc_mdprefix_fields'}->{$prefix}->{$core_field}++;
+	    $self->{'mdprefix_fields'}->{$prefix}->{$core_field}++;
+	}
+	else {
+	    # delete
+	    $self->{'doc_mdprefix_fields'}->{$prefix}->{$core_field}--;
+	    $self->{'mdprefix_fields'}->{$prefix}->{$core_field}--;
+	}
+
+    }
+    elsif ($field =~ m/^[[:upper:]]/) {
+	# implicit 'ex' metadata set
+
+	if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+
+	    $self->{'doc_mdprefix_fields'}->{'ex'}->{$field}++;
+	    $self->{'mdprefix_fields'}->{'ex'}->{$field}++;
+	}
+	else {
+	    # delete
+	    $self->{'doc_mdprefix_fields'}->{'ex'}->{$field}--;
+	    $self->{'mdprefix_fields'}->{'ex'}->{$field}--;
+	}
+    }
+
+}
+
+
+sub infodbedit {
+    my $self = shift (@_);
+    my ($doc_obj, $filename, $edit_mode) = @_;
+
+    # only output this document if it is a "indexed_doc" or "info_doc" (database only) document
+    my $doctype = $doc_obj->get_doc_type();
+    return if ($doctype ne "indexed_doc" && $doctype ne "info_doc");
+
+    my $archivedir = "";
+    if (defined $filename)
+    {
+	# doc_obj derived directly from file
+	my ($dir) = $filename =~ /^(.*?)(?:\/|\\)[^\/\\]*$/;
+	$dir = "" unless defined $dir;
+	$dir =~ s/\\/\//g;
+	$dir =~ s/^\/+//;
+	$dir =~ s/\/+$//;
+
+	$archivedir = $dir;
+
+	# resolve the final filenames of the files associated with this document
+	$self->assoc_files ($doc_obj, $archivedir);
+    }
+    else
+    {
+	# doc_obj reconstructed from database (has metadata, doc structure but no text)
+	my $top_section = $doc_obj->get_top_section();
+	$archivedir = $doc_obj->get_metadata_element($top_section,"archivedir");
+    }
+
+    if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+	#add this document to the browse structure
+	push(@{$self->{'doclist'}},$doc_obj->get_OID()) 
+	    unless ($doctype eq "classification");
+    }
+    else {
+	# delete => remove this doc from browse structure
+	my $del_doc_oid = $doc_obj->get_OID();
+
+	my @filtered_doc_list = ();
+	foreach my $oid (@{$self->{'doclist'}}) {
+	    push(@filtered_doc_list,$oid) if ($oid ne $del_doc_oid);
+	}
+	$self->{'doclist'} = \@filtered_doc_list;
+    }
+
+
+    # classify this document
+    &classify::classify_doc ($self->{'classifiers'}, $doc_obj, $edit_mode);
+
+    if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+	# this is another document
+	$self->{'num_docs'} += 1 unless ($doctype eq "classification");
+    }
+    else {
+	# delete
+	$self->{'num_docs'} -= 1 unless ($doctype eq "classification");
+    }
+
+    # is this a paged or a hierarchical document
+    my ($thistype, $childtype) = $self->get_document_type ($doc_obj);
+
+    my $section = $doc_obj->get_top_section ();
+    my $doc_OID = $doc_obj->get_OID();
+    my $first = 1;
+    my $infodb_handle = $self->{'output_handle'};
+
+    $self->{'doc_mdprefix_fields'} = {};
+
+    while (defined $section)
+    {
+	my $section_OID = $doc_OID;
+	if ($section ne "")
+	{
+	    $section_OID = $doc_OID . "." . $section;
+	}
+	my %section_infodb = ();
+
+	# update a few statistics
+	if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+
+	    $self->{'num_bytes'} += $doc_obj->get_text_length ($section);
+	    $self->{'num_sections'} += 1 unless ($doctype eq "classification");
+	}
+	else {
+	    # delete
+	    $self->{'num_bytes'} -= $doc_obj->get_text_length ($section);
+	    $self->{'num_sections'} -= 1 unless ($doctype eq "classification");
+	}
+
+	# output the fact that this document is a document (unless doctype
+	# has been set to something else from within a plugin
+	my $dtype = $doc_obj->get_metadata_element ($section, "doctype");
+	if (!defined $dtype || $dtype !~ /\w/) {
+	    $section_infodb{"doctype"} = [ "doc" ];
+	}
+
+	# Output whether this node contains text
+	#
+	# If doc_obj reconstructed from database file then no need to 
+	# explicitly add <hastxt> as this is preserved as metadata when
+	# the database file is loaded in
+	if (defined $filename)
+	{
+	    # doc_obj derived directly from file
+	    if ($doc_obj->get_text_length($section) > 0) {
+		$section_infodb{"hastxt"} = [ "1" ];
+	    } else {
+		$section_infodb{"hastxt"} = [ "0" ];
+	    }
+	}
+
+	# output all the section metadata
+	my $metadata = $doc_obj->get_all_metadata ($section);
+	foreach my $pair (@$metadata) {
+	    my ($field, $value) = (@$pair);
+
+	    if ($field ne "Identifier" && $field !~ /^gsdl/ && 
+		defined $value && $value ne "") {	    
+
+		# escape problematic stuff
+		$value =~ s/\\/\\\\/g;
+		$value =~ s/\n/\\n/g;
+		$value =~ s/\r/\\r/g;
+
+		# special case for URL metadata
+		if ($field =~ /^URL$/i) {
+		    if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+
+			&dbutil::write_infodb_entry($self->{'infodbtype'}, $infodb_handle, $value, { 'section' => [ $section_OID ] });
+		    }
+		    else {
+			# delete
+			&dbutil::delete_infodb_entry($self->{'infodbtype'}, $infodb_handle, $value);
+		    }
+
+		    
+		}
+
+		if (!defined $self->{'dontdb'}->{$field}) {
+		    push(@{$section_infodb{$field}}, $value);
+
+		    if ($section eq "" && $self->{'store_metadata_coverage'} =~ /^true$/i)
+		    {
+			$self->infodb_metadata_stats($field,$edit_mode);
+		    }
+		}
+	    }
+	}
+
+	if ($section eq "")
+	{
+	    my $doc_mdprefix_fields = $self->{'doc_mdprefix_fields'};
+
+	    foreach my $prefix (keys %$doc_mdprefix_fields)
+	    {
+		push(@{$section_infodb{"metadataset"}}, $prefix);
+
+		foreach my $field (keys %{$doc_mdprefix_fields->{$prefix}})
+		{
+		    push(@{$section_infodb{"metadatalist-$prefix"}}, $field);
+
+		    my $val = $doc_mdprefix_fields->{$prefix}->{$field};
+		    push(@{$section_infodb{"metadatafreq-$prefix-$field"}}, $val);
+		}
+	    }
+	}
+
+	# If doc_obj reconstructed from database file then no need to 
+	# explicitly add <archivedir> as this is preserved as metadata when
+	# the database file is loaded in
+	if (defined $filename)
+	{
+	    # output archivedir if at top level
+	    if ($section eq $doc_obj->get_top_section()) {
+		$section_infodb{"archivedir"} = [ $archivedir ];
+	    }
+	}
+
+	# output document display type
+	if ($first) {
+	    $section_infodb{"thistype"} = [ $thistype ];
+	}
+
+	if ($self->{'db_level'} eq "document") {
+	    # doc num is num_docs not num_sections
+	    # output the matching document number
+	    $section_infodb{"docnum"} = [ $self->{'num_docs'} ];
+	}
+	else {
+	    # output a list of children
+	    my $children = $doc_obj->get_children ($section);
+	    if (scalar(@$children) > 0) {
+		$section_infodb{"childtype"} = [ $childtype ];
+		my $contains = "";
+		foreach my $child (@$children)
+		{
+		    $contains .= ";" unless ($contains eq "");
+		    if ($child =~ /^.*?\.(\d+)$/)
+		    {
+			$contains .= "\".$1";
+		    }
+		    else
+		    {
+			$contains .= "\".$child";
+		    }
+		}
+		$section_infodb{"contains"} = [ $contains ];
+	    }
+	    # output the matching doc number
+	    $section_infodb{"docnum"} = [ $self->{'num_sections'} ];
+	} 
+	
+	if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+
+	    &dbutil::write_infodb_entry($self->{'infodbtype'}, $infodb_handle, $section_OID, \%section_infodb);
+	}
+	else {
+	    # delete
+	    &dbutil::delete_infodb_entry($self->{'infodbtype'}, $infodb_handle, $section_OID);
+	}
+
+	
+	# output a database entry for the document number, except for Lucene (which no longer needs this information)
+	unless (ref($self) eq "lucenebuildproc")
+	{
+	    if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+		
+		if ($self->{'db_level'} eq "document") {
+		    &dbutil::write_infodb_entry($self->{'infodbtype'}, $infodb_handle, $self->{'num_docs'}, { 'section' => [ $doc_OID ] });
+		}
+		else {
+		    &dbutil::write_infodb_entry($self->{'infodbtype'}, $infodb_handle, $self->{'num_sections'}, { 'section' => [ $section_OID ] });
+		}
+	    }
+	    else {
+
+		if ($self->{'db_level'} eq "document") {
+		    &dbutil::delete_infodb_entry($self->{'infodbtype'}, $infodb_handle, $self->{'num_docs'});
+		}
+		else {
+		    &dbutil::delete_infodb_entry($self->{'infodbtype'}, $infodb_handle, $self->{'num_sections'});
+		}
+
+	    }
+	}
+
+	$first = 0;
+	$section = $doc_obj->get_next_section($section);
+	last if ($self->{'db_level'} eq "document"); # if no sections wanted, only add the docs
+    }
+}
+
+
+
+
+sub infodb {
+    my $self = shift (@_);
+    my ($doc_obj, $filename) = @_;
+
+    $self->infodbedit($doc_obj,$filename,"add");
+}
+
+sub infodbreindex {
+    my $self = shift (@_);
+    my ($doc_obj, $filename) = @_;
+
+    $self->infodbedit($doc_obj,$filename,"update");
+}
+
+sub infodbdelete {
+    my $self = shift (@_);
+    my ($doc_obj, $filename) = @_;
+
+    $self->infodbedit($doc_obj,$filename,"delete");
+}
+
+
+sub text {
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+    
+    my $handle = $self->{'outhandle'};
+    print $handle "basebuildproc::text function must be implemented in sub classes\n";
+    die "\n";
+}
+
+sub textreindex
+{
+    my $self = shift @_;
+
+    my $outhandle = $self->{'outhandle'};
+    print $outhandle "basebuildproc::textreindex function must be implemented in sub classes\n";
+    if (!$self->is_incremental_capable()) {
+
+	print $outhandle "  This operation is only possible with indexing tools with that support\n";
+	print $outhandle "  incremental building\n";
+    }
+    die "\n";
+}
+
+sub textdelete
+{
+    my $self = shift @_;
+
+    my $outhandle = $self->{'outhandle'};
+    print $outhandle "basebuildproc::textdelete function must be implemented in sub classes\n";
+    if (!$self->is_incremental_capable()) {
+
+	print $outhandle "  This operation is only possible with indexing tools with that support\n";
+	print $outhandle "  incremental building\n";
+    }
+    die "\n";
+}
+
+
+# should the document be indexed - according to the subcollection and language
+# specification.
+sub is_subcollection_doc {
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+    
+    my $indexed_doc = 1;
+    foreach my $indexexp (@{$self->{'indexexparr'}}) {
+	$indexed_doc = 0;
+	my ($field, $exp, $options) = split /\//, $indexexp;
+	if (defined ($field) && defined ($exp)) {
+	    my ($bool) = $field =~ /^(.)/;
+	    $field =~ s/^.// if $bool eq '!';
+	    my @metadata_values;
+	    if ($field =~ /^filename$/i) {
+		push(@metadata_values, $doc_obj->get_source_filename());
+	    }
+	    else {
+		@metadata_values = @{$doc_obj->get_metadata($doc_obj->get_top_section(), $field)};
+	    }
+	    next unless @metadata_values;
+	    foreach my $metadata_value (@metadata_values) {
+		if ($bool eq '!') {
+		    if ($options =~ /^i$/i) {
+			if ($metadata_value !~ /$exp/i) {$indexed_doc = 1; last;}
+		    } else {
+			if ($metadata_value !~ /$exp/) {$indexed_doc = 1; last;}
+		    }
+		} else {
+		    if ($options =~ /^i$/i) {
+			if ($metadata_value =~ /$exp/i) {$indexed_doc = 1; last;}
+		    } else {
+			if ($metadata_value =~ /$exp/) {$indexed_doc = 1; last;}
+		    }
+		}
+	    }
+
+	    last if ($indexed_doc == 1);
+	}
+    }
+    
+    # if this doc is so far in the sub collection, and we have lang info, 
+    # now we check the languages to see if it matches
+    if($indexed_doc && defined $self->{'lang_meta'}) {
+	$indexed_doc = 0;
+	my $field = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $self->{'lang_meta'});
+	if (defined $field) {
+	    foreach my $lang (@{$self->{'langarr'}}) {
+		my ($bool) = $lang =~ /^(.)/;
+		if ($bool eq '!') {
+		    $lang =~ s/^.//;
+		    if ($field !~ /$lang/) {
+			$indexed_doc = 1; last;
+		    }
+		} else {
+		    if ($field =~ /$lang/) {
+			$indexed_doc = 1; last;
+		    }
+		}
+	    }
+	} 
+    }
+    return $indexed_doc;
+    
+}
+
+# use 'Paged' if document has no more than 2 levels
+# and each section at second level has a number for
+# Title metadata
+# also use Paged if gsdlthistype metadata is set to Paged
+sub get_document_type {
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+
+    my $thistype = "VList";
+    my $childtype = "VList";
+    my $title;
+    my @tmp = ();
+    
+    my $section = $doc_obj->get_top_section ();
+    
+    my $gsdlthistype = $doc_obj->get_metadata_element ($section, "gsdlthistype");
+    if (defined $gsdlthistype) {
+	if ($gsdlthistype eq "Paged") {
+	    $childtype = "Paged";
+	    if ($doc_obj->get_text_length ($doc_obj->get_top_section())) {
+		$thistype = "Paged";
+	    } else {
+		$thistype = "Invisible";
+	    }
+	    
+	    return ($thistype, $childtype);
+	} elsif ($gsdlthistype eq "Hierarchy") {
+	    return ($thistype, $childtype); # use VList, VList
+	}
+    }
+    my $first = 1;
+    while (defined $section) {
+	@tmp = split /\./, $section;
+	if (scalar(@tmp) > 1) {
+	    return ($thistype, $childtype);
+	}
+	if (!$first) {
+	    $title = $doc_obj->get_metadata_element ($section, "Title");
+	    if (!defined $title || $title !~ /^\d+$/) {
+		return ($thistype, $childtype);
+	    }
+	}
+	$first = 0;
+	$section = $doc_obj->get_next_section($section);
+    }
+    if ($doc_obj->get_text_length ($doc_obj->get_top_section())) {
+	$thistype = "Paged";
+    } else {
+	$thistype = "Invisible";
+    }
+    $childtype = "Paged";
+    return ($thistype, $childtype);
+}
+
+sub assoc_files 
+{
+    my $self = shift (@_);
+    my ($doc_obj, $archivedir) = @_;
+    my ($afile);
+    
+    foreach my $assoc_file (@{$doc_obj->get_assoc_files()}) {
+      #rint STDERR "Processing associated file - copy " . $assoc_file->[0] . " to " . $assoc_file->[1] . "\n";
+	# if assoc file starts with a slash, we put it relative to the assoc
+	# dir, otherwise it is relative to the HASH... directory
+	if ($assoc_file->[1] =~ m@^[/\\]@) {
+	    $afile = &util::filename_cat($self->{'assocdir'}, $assoc_file->[1]);
+	} else {
+	    $afile = &util::filename_cat($self->{'assocdir'}, $archivedir, $assoc_file->[1]);
+	}
+	&util::hard_link ($assoc_file->[0], $afile, $self->{'verbosity'});
+    }
+}
+
Index: /gsdl/stable/perllib/buildConfigxml.pm
===================================================================
--- /gsdl/stable/perllib/buildConfigxml.pm	(revision 20131)
+++ /gsdl/stable/perllib/buildConfigxml.pm	(revision 20131)
@@ -0,0 +1,564 @@
+###########################################################################
+#
+# buildConfigxml.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# reads in buildConfig.xml 
+# Note, only implemented the bits that are currently used, eg by incremental 
+# build code.
+# The resulting data is not a full representation on buildConfig.xml.
+
+package buildConfigxml;
+
+use strict;
+no strict 'refs';
+no strict 'subs';
+
+# Wrapper that ensures the right version of XML::Parser is loaded given
+# the version of Perl being used.  Need to distinguish between Perl 5.6 and
+# Perl 5.8
+sub BEGIN {
+    my $perl_dir;
+
+    # Note: $] encodes the version number of perl
+    if ($]>5.008) { 
+	# perl 5.8.1 or above
+	$perl_dir = "perl-5.8";
+    }
+    elsif ($]<5.008) {
+	# assume perl 5.6
+	$perl_dir = "perl-5.6";
+    }
+    else {
+	print STDERR "Warning: Perl 5.8.0 is not a maintained release.\n";
+	print STDERR "         Please upgrade to a newer version of Perl.\n";
+	$perl_dir = "perl-5.8";
+    }
+
+    if ($ENV{'GSDLOS'} !~ /^windows$/i) {
+	# Use push to put this on the end, so an existing XML::Parser will be used by default
+	push (@INC, "$ENV{'GSDLHOME'}/perllib/cpan/$perl_dir");
+    }
+}
+
+use XML::Parser;
+
+
+# A mapping hash to resolve name discrepancy between gs2 and gs3.
+my $nameMap = {"numDocs" => "numdocs",
+	       "buildType" => "buildtype"
+	       };
+
+
+# A hash structure which is returned by sub read_cfg_file.
+my $data = {};
+
+# use those unique attribute values to locate the text within the elements
+my $currentLocation = "";
+my $stringexp = q/^(buildType|numDocs)$/;
+  
+my $indexmap_name = "";
+my $haveindexfields = 0;
+
+# Reads in the model collection configuration file, collectionConfig.xml,
+# into a structure which complies with the one used by gs2 (i.e. one read
+# in by &cfgread::read_cfg_file).
+sub read_cfg_file {
+    my ($filename) = @_;
+    $data = {};
+    if ($filename !~ /buildConfig\.xml$/ || !-f $filename) {
+        return undef;
+    }
+
+    # create XML::Parser object for parsing metadata.xml files
+    my $parser;
+    if ($]<5.008) {
+	# Perl 5.6
+	$parser = new XML::Parser('Style' => 'Stream',
+				  'Handlers' => {'Char' => \&Char,
+						 'Doctype' => \&Doctype
+						 });
+    }
+    else {
+	# Perl 5.8
+	$parser = new XML::Parser('Style' => 'Stream',
+				  'ProtocolEncoding' => 'ISO-8859-1',
+				  'Handlers' => {'Char' => \&Char,
+						 'Doctype' => \&Doctype
+						 });
+    }
+
+    if (!open (COLCFG, $filename)) {
+	print STDERR "buildConfigxml::read_cfg_file couldn't read the cfg file $filename\n";
+    } else {
+
+      $parser->parsefile ($filename);# (COLCFG);
+      close (COLCFG);
+    }
+
+    #&Display; 
+    return $data;
+}
+
+sub StartTag {
+# Those marked with #@ will not be executed at the same time when this sub is being called
+# so that if/elsif is used to avoid unnecessary tests
+    my ($expat, $element) = @_;
+    
+    my $name = $_{'name'};
+    my $shortname = $_{'shortname'};
+
+    
+    #@ handling block metadataList
+    if (defined $name and $name =~ /$stringexp/){
+      $currentLocation = $name;
+      # the value will be retrieved later in Text sub
+    }
+
+    #@ handle indexes - store indexmap (mg) or indexfields and indexfieldmap (mgpp/lucene)
+    elsif ($element =~ /^indexList$/) {
+	# set up the data arrays
+	# this assumes that the build type has been read already, which is
+	# currently the order we save the file in.
+	if ($data->{'buildtype'} eq "mg") {
+	    $indexmap_name = "indexmap";
+	    if (!defined $data->{"indexmap"}) {
+		$data->{"indexmap"} = [];
+	    }
+	}
+	else {
+	    $indexmap_name = "indexfieldmap";
+	    $haveindexfields = 1;
+	    if (!defined $data->{"indexfieldmap"}) {
+		$data->{"indexfieldmap"} = [];
+	    }
+	    if (!defined $data->{"indexfields"}) {
+		$data->{"indexfields"} = [];
+	    }
+
+	}
+	
+    }
+    
+    elsif ($element =~ /index/) {
+	# store each index in the map
+	if (defined $name && defined $shortname) {
+	    push @{$data->{$indexmap_name}}, "$name->$shortname";
+	    if ($haveindexfields) {
+		push @{$data->{'indexfields'}}, $name;
+	    }
+	}
+    }
+
+
+}
+
+sub EndTag {
+    my ($expat, $element) = @_;
+}
+
+sub Text {
+    if (defined $currentLocation) { 
+	#@ Handling block metadataList(numDocs, buildType)
+	if($currentLocation =~ /$stringexp/){
+	    #print $currentLocation;
+	    my $key = $nameMap->{$currentLocation};	
+	    $data->{$key} = $_;
+	    undef $currentLocation;
+	}	
+    }	
+}
+
+# This sub is for debugging purposes
+sub Display {
+
+    print "NumDocs = ".$data->{'numdocs'}."\n" if (defined $data->{'numdocs'});
+    print "BuildType = ".$data->{'buildtype'}."\n" if (defined $data->{'buildtype'});
+    print  "IndexMap = ". join(" ",@{$data->{'indexmap'}})."\n" if (defined $data->{'indexmap'});
+    print  "IndexFieldMap = ". join(" ",@{$data->{'indexfieldmap'}})."\n" if (defined $data->{'indexfieldmap'});
+    print  "IndexFields = ". join(" ",@{$data->{'indexfields'}})."\n" if (defined $data->{'indexfields'});
+
+}
+
+# is this actually used??
+sub Doctype {
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+
+    die if ($name !~ /^buildConfig$/);
+}
+
+# This Char function overrides the one in XML::Parser::Stream to overcome a
+# problem where $expat->{Text} is treated as the return value, slowing
+# things down significantly in some cases.
+sub Char {
+    if ($]<5.008) {
+	use bytes;  # Necessary to prevent encoding issues with XML::Parser 2.31+ and Perl 5.6
+    }
+    $_[0]->{'Text'} .= $_[1];
+    return undef;
+}
+
+
+
+sub write_line {
+    my ($filehandle, $line) = @_;
+    print $filehandle join ("", @$line), "\n";
+}
+
+# Create the buildConfig.xml file for a specific collection
+sub write_cfg_file {
+    # this sub is called in make_auxiliary_files() in basebuilder.pm
+    # the received args: $buildoutfile - destination file: buildConfig.xml
+    #                    $buildcfg - all build options, eg, disable_OAI
+    #                    $collectcfg - contents of collectionConfig.xml read in by read_cfg_file sub in buildConfigxml.pm.
+    my ($buildoutfile, $buildcfg, $collectcfg, $disable_OAI) = @_;
+    my $line = [];
+
+    if (!open (COLCFG, ">$buildoutfile")) {
+	print STDERR "buildConfigxml::write_cfg_file couldn't write the build config file $buildoutfile\n";
+	die;
+    }
+
+    &write_line('COLCFG', ["<buildConfig xmlns:gsf=\"http://www.greenstone.org/greenstone3/schema/ConfigFormat\">"]);  
+
+    # output building metadata to build config file 
+    my $buildtype;
+    if (defined $buildcfg->{"buildtype"}) {
+	$buildtype = $buildcfg->{"buildtype"};
+    } else {
+	$buildtype = "mgpp";
+    }
+    my $numdocs;
+    if (defined $buildcfg->{"numdocs"}) {
+      $numdocs = $buildcfg->{"numdocs"};
+    }
+    &write_line('COLCFG', ["<metadataList>"]);
+    &write_line('COLCFG', ["<metadata name=\"numDocs\">", $numdocs, "</metadata>"]);
+    &write_line('COLCFG', ["<metadata name=\"buildType\">", $buildtype, "</metadata>"]);
+    &write_line('COLCFG', ["</metadataList>"]);
+
+    my $service_type = "MGPP";
+    if ($buildtype eq "mg") {
+	$service_type = "MG";
+    } elsif ($buildtype eq "lucene") {
+	$service_type = "Lucene";
+    }
+
+    # output serviceRackList
+    &write_line('COLCFG', ["<serviceRackList>"]);
+
+    # This serviceRack enables the collection to provide the oai metadata retrieve service, which is served by the OAIPMH.java class
+    # For each collection, we write the following serviceRack in the collection's buildConfig.xml file if the 'disable_OAI' argument is not checked in the GLI (or equivalently, a 'disable_OAI' flag is not specified on the command line). There are also other configurations in the OAIConfig.xml.
+    if ($disable_OAI == 0) {
+      &write_line('COLCFG', ["<serviceRack name=\"OAIPMH\">"]);
+      if (defined $buildcfg->{'indexstem'}) {
+        my $indexstem = $buildcfg->{'indexstem'};
+        &write_line('COLCFG', ["<indexStem name=\"", $indexstem, "\" />"]);     
+      }
+      &write_line('COLCFG', ["</serviceRack>"]);
+    }    
+    # do the search service 
+    &write_line('COLCFG', ["<serviceRack name=\"GS2", $service_type, "Search\">"]);
+    if (defined $buildcfg->{'indexstem'}) {
+      my $indexstem = $buildcfg->{'indexstem'};
+      &write_line('COLCFG', ["<indexStem name=\"", $indexstem, "\" />"]);     
+    }
+
+    #indexes
+    # maps index name to shortname
+    my $indexmap = {};
+    # keeps the order for indexes
+    my @indexlist = ();
+    
+    my $defaultindex = "";
+    my $first = 1;
+    my $maptype = "indexfieldmap";
+    if ($buildtype eq "mg") {
+	$maptype = "indexmap";
+    }
+
+    #map {print $_."\n"} keys %$buildcfg;
+
+    if (defined $buildcfg->{$maptype}) {
+	my $indexmap_t = $buildcfg->{$maptype};
+       foreach my $i (@$indexmap_t) {
+    my ($k, $v) = $i =~ /^(.*)\-\>(.*)$/;
+	    $indexmap->{$k} = $v;
+	    push @indexlist, $k;
+	    if ($first) {
+		$defaultindex = $v;
+		$first = 0;
+	    }	
+	}
+	# now if the user has assigned a default index, we use it 
+	if (defined $collectcfg->{"defaultindex"}) {
+	  $defaultindex = $indexmap->{$collectcfg->{"defaultindex"}};
+	}
+	
+    } else {
+	print STDERR "$maptype not defined";
+    }  
+    #for each index in indexList, write them out
+    &write_line('COLCFG', ["<indexList>"]);
+    foreach my $i (@indexlist) {
+	my $index = $indexmap->{$i};
+	&write_line('COLCFG', ["<index name=\"", $i, "\" ", "shortname=\"", $index, "\" />"]);
+    }	
+    &write_line('COLCFG', ["</indexList>"]);
+
+    
+    &write_line('COLCFG', ["<defaultIndex shortname=\"", $defaultindex, "\" />"]);
+
+
+    # do indexOptionList
+    if ($buildtype eq "mg" || $buildtype eq "mgpp") {
+        &write_line('COLCFG', ["<indexOptionList>"]);
+	my $stemindexes = 3; # default is stem and casefold
+	if (defined $buildcfg->{'stemindexes'} && $buildcfg->{'stemindexes'} =~ /^\d+$/ ) {
+	    $stemindexes = $buildcfg->{'stemindexes'};
+	}
+	&write_line('COLCFG', ["<indexOption name=\"stemIndexes\" value=\"", $stemindexes, "\" />"]);
+	
+	my $maxnumeric = 4; # default
+	if (defined $buildcfg->{'maxnumeric'} && $buildcfg->{'maxnumeric'} =~ /^\d+$/) {
+	    $maxnumeric = $buildcfg->{'maxnumeric'};
+	}
+	&write_line('COLCFG', ["<indexOption name=\"maxnumeric\" value=\"", $maxnumeric, "\" />"]);
+        &write_line('COLCFG', ["</indexOptionList>"]);
+    }
+
+    #  levelList
+    my $levelmap = {};
+    my @levellist = ();
+    my $default_search_level = "Doc";
+    my $default_retrieve_level = "Doc";
+    my $default_db_level = "Doc";
+    $first = 1;
+    if ($buildtype eq "mgpp" || $buildtype eq "lucene") {
+	if (defined $buildcfg->{'levelmap'}) {
+	    my $levelmap_t = $buildcfg->{'levelmap'};
+	    foreach my $l (@$levelmap_t) {
+		my ($key, $val) = $l =~ /^(.*)\-\>(.*)$/;
+		$levelmap->{$key} = $val;
+		push @levellist, $key;
+		if ($first) {
+		    # let default search level follow the first level in the level list
+		    $default_search_level = $val;
+		    # retrieve/database levels may get modified later if text level is defined
+		    $default_retrieve_level = $val;
+		    $default_db_level = $val;
+		    $first = 0;
+		}
+	    }
+	}
+	# the default level assigned by the user is no longer ignored [Shaoqun], but the retrievel level stays the same. 
+       	#if (defined $collectcfg->{"defaultlevel"}) {
+	$default_search_level = $levelmap->{$collectcfg->{"defaultlevel"}};
+        #  $default_retrieve_level = $default_search_level;
+	#}
+	
+	if (defined $buildcfg->{'textlevel'}) {
+	   # let the retrieve/database levels always follow the textlevel
+           $default_retrieve_level = $buildcfg->{'textlevel'};
+	   $default_db_level = $buildcfg->{'textlevel'};
+		 
+	}
+    }
+    #for each level in levelList, write them out
+	if ($buildtype ne "mg") {
+    &write_line('COLCFG', ["<levelList>"]);
+    foreach my $lv (@levellist) {
+	my $level = $levelmap->{$lv};
+        &write_line('COLCFG', ["<level name=\"", $lv, "\" shortname=\"", $level, "\" />"]);
+    }	
+    &write_line('COLCFG', ["</levelList>"]);
+    }
+    # add in defaultLevel as the same level as indexLevelList, making the reading job easier
+    if ($buildtype eq "lucene" || $buildtype eq "mgpp") {
+	&write_line('COLCFG', ["<defaultLevel shortname=\"", $default_search_level, "\" />"]);
+    }
+    if ($buildtype eq "lucene" || $buildtype eq "mgpp") {
+        &write_line('COLCFG', ["<defaultDBLevel shortname=\"", $default_db_level, "\" />"]);
+    }
+    # do searchTypeList
+    if ($buildtype eq "mgpp" || $buildtype eq "lucene") {
+	  &write_line('COLCFG', ["<searchTypeList>"]);
+      
+      if (defined $buildcfg->{"searchtype"}) {
+	  my $searchtype_t = $buildcfg->{"searchtype"};
+	  foreach my $s (@$searchtype_t) {
+	  &write_line('COLCFG', ["<searchType name=\"", $s, "\" />"]);
+	}
+      } else {
+	  &write_line('COLCFG', ["<searchType name=\"plain\" />"]);
+	  &write_line('COLCFG', ["<searchType name=\"form\" />"]);
+      }
+	  &write_line('COLCFG', ["</searchTypeList>"]);
+    }
+
+    # do indexLanguageList [in collect.cfg: languages; in build.cfg: languagemap]
+    $first = 1;
+    my $default_lang = "";
+    my $default_lang_short = "";
+    if (defined $buildcfg->{"languagemap"}) {
+      &write_line('COLCFG', ["<indexLanguageList>"]);
+
+      my $langmap_t = $buildcfg->{"languagemap"};
+      foreach my $l (@$langmap_t) {
+	my ($k, $v) = $l =~ /^(.*)\-\>(.*)$/; 
+
+	&write_line('COLCFG', ["<indexLanguage name=\"", $k, "\" shortname=\"", $v, "\" />"]);
+	if ($first) {
+	  $default_lang = $k; #name
+	  $default_lang_short = $v; #shortname
+	  $first = 0;
+	}
+      }
+
+      &write_line('COLCFG', ["</indexLanguageList>"]);
+      # now if the user has assigned a default language (as "en", "ru" etc.)
+      if (defined $collectcfg->{"defaultlanguage"}) {
+	$default_lang = $collectcfg->{"defaultlanguage"};
+      }
+      &write_line('COLCFG', ["<defaultIndexLanguage name=\"", $default_lang, "\" shortname=\"", $default_lang_short, "\" />"]);
+    }
+
+
+    # do indexSubcollectionList
+    my $default_subcol = "";# make it in sub scope to be used in the concatenation
+    if (defined $buildcfg->{'subcollectionmap'}) {
+      &write_line('COLCFG', ["<indexSubcollectionList>"]);
+      my $subcolmap = {};
+      my @subcollist = ();
+      $first = 1;
+      my $subcolmap_t = $buildcfg->{'subcollectionmap'};
+      foreach my $l (@$subcolmap_t) {
+	my ($k, $v) = $l =~ /^(.*)\-\>(.*)$/;
+	$subcolmap->{$k} = $v;
+	push @subcollist, $k;
+	if ($first) {
+	  $default_subcol = $v;
+	  $first = 0;
+	}
+      }
+      foreach my $sl (@subcollist) {
+	my $subcol = $subcolmap->{$sl};
+	&write_line('COLCFG', ["<indexSubcollection name=\"", $sl, "\" shortname=\"", $subcol, "\" />"]);
+      }	
+
+      &write_line('COLCFG', ["</indexSubcollectionList>"]);
+      &write_line('COLCFG', ["<defaultIndexSubcollection shortname=\"", $default_subcol, "\" />"]);
+    }
+      
+    # close off search service 
+    &write_line('COLCFG', ["</serviceRack>"]);
+
+    # do the retrieve service
+    &write_line('COLCFG', ["<serviceRack name=\"GS2", $service_type, "Retrieve\">"]);
+
+    # do default index 
+    if (defined $buildcfg->{"languagemap"}) {
+	&write_line('COLCFG', ["<defaultIndexLanguage shortname=\"", $default_lang, "\" />"]);
+    }
+    if (defined $buildcfg->{'subcollectionmap'}) {
+	&write_line('COLCFG', ["<defaultIndexSubcollection shortname=\"", $default_subcol, "\" />"]);
+    }
+    if ($buildtype eq "mg") {
+      &write_line('COLCFG', ["<defaultIndex shortname=\"", $defaultindex, "\" />"]);
+    }
+
+    if (defined $buildcfg->{'indexstem'}) {
+      my $indexstem = $buildcfg->{'indexstem'};
+      &write_line('COLCFG', ["<indexStem name=\"", $indexstem, "\" />"]);     
+    }
+    if ($buildtype eq "mgpp" || $buildtype eq "lucene") {
+      &write_line('COLCFG', ["<defaultLevel shortname=\"", $default_retrieve_level, "\" />"]);
+    }
+    &write_line('COLCFG', ["</serviceRack>"]);
+
+    # do the browse service
+    my $count = 1;
+    my $phind = 0;
+    my $started_classifiers = 0;
+
+    my $classifiers = $collectcfg->{"classify"};
+    foreach my $cl (@$classifiers) {
+      my $name = "CL$count";
+      $count++;
+      my ($classname) = @$cl[0];
+      if ($classname =~ /^phind$/i) {
+	$phind=1;
+	#should add it into coll config classifiers
+	next;
+      }
+      
+      if (not $started_classifiers) {
+	&write_line('COLCFG', ["<serviceRack name=\"GS2Browse\">"]);
+	if (defined $buildcfg->{'indexstem'}) {
+	  my $indexstem = $buildcfg->{'indexstem'};
+	  &write_line('COLCFG', ["<indexStem name=\"", $indexstem, "\" />"]);     
+	}
+	&write_line('COLCFG', ["<classifierList>"]);		
+	$started_classifiers = 1;
+      }
+      my $content = ''; #use buttonname first, then metadata
+      if ($classname eq "DateList") {
+	$content = "Date";
+      } else {
+	for (my $j=0; $j<scalar(@$cl); $j++) {
+	  my $arg = @$cl[$j];
+	  if ($arg eq "-buttonname"){
+	    $content = @$cl[$j+1];
+	    last;
+	  } elsif ($arg eq "-metadata") {
+	    $content = @$cl[$j+1];
+	  }
+	  
+	}
+      }
+      &write_line('COLCFG', ["<classifier name=\"", $name, "\" content=\"", $content, "\" />"]);
+    }     
+    if ($started_classifiers) {
+      # end the classifiers
+      &write_line('COLCFG', ["</classifierList>"]);
+      # close off the Browse service
+      &write_line('COLCFG', ["</serviceRack>"]);
+    }
+    
+    # the phind classifier is a separate service
+    if ($phind) {
+	# if phind classifier
+	&write_line('COLCFG', ["<serviceRack name=\"PhindPhraseBrowse\" />"]);
+    }
+
+    
+    &write_line('COLCFG', ["</serviceRackList>"]);
+    &write_line('COLCFG', ["</buildConfig>"]);
+
+    close (COLCFG);
+  }
+
+
+#########################################################
+
+1;
Index: /gsdl/stable/perllib/cfgread.pm
===================================================================
--- /gsdl/stable/perllib/cfgread.pm	(revision 20131)
+++ /gsdl/stable/perllib/cfgread.pm	(revision 20131)
@@ -0,0 +1,180 @@
+###########################################################################
+#
+# cfgread.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# reads in configuration files
+
+package cfgread;
+
+use strict; no strict 'refs';
+
+
+sub read_cfg_line {
+    my ($handle) = @_;
+    my $line = "";
+    my @line = ();
+    my $linecontinues = 0;
+
+    while (defined($line = <$handle>)) {
+	$line =~ s/^\#.*$//;   # remove comments
+	$line =~ s/\cM|\cJ//g; # remove end-of-line characters
+	$line =~ s/^\s+//;     # remove initial white space
+	# Merge with following line if a quoted phrase is left un-closed.
+	if ($line =~ m/^([\"\'])/ || $line =~ m/[^\\]([\"\'])/) {
+	    my $quote=$1;
+	    while ($line !~ m/$quote(.*?[^\\])?(\\\\)*$quote/) {
+		my $nextline = <$handle>;
+		if (defined($nextline)) {
+		    $nextline =~ s/\r?\n//; # remove end-of-line
+		    $line .= " " . $nextline;
+		} else {
+		    return undef; # parse error?
+		}
+	    }
+	}
+	$linecontinues = $line =~ s/\\$//;
+
+	while ($line =~ s/\s*(\".*?[^\\](\\\\)*\"|\'.*?[^\\](\\\\)*\'|\S+)\s*//) {
+	    if (defined $1) {
+		# remove any enclosing quotes
+		my $entry = $1;
+		$entry =~ s/^([\"\'])(.*)\1$/$2/;
+
+		# substitute an environment variables
+##		$entry =~ s/\$(\w+)/$ENV{$1}/g;
+		$entry =~ s/\$\{(\w+)\}/$ENV{$1}/g;
+		push (@line, $entry);
+	    } else {
+		push (@line, "");
+	    }
+	}
+
+	if (scalar(@line) > 0 && !$linecontinues) {
+#	    print STDERR "line: \"" . join ("\" \"", @line) . "\"\n";
+	    return \@line;
+	}
+    }
+
+    return undef;
+}
+
+sub write_cfg_line {
+    my ($handle, $line) = @_;
+    print $handle join ("\t", @$line), "\n";
+}
+
+
+# stringexp, arrayexp, hashexp,arrayarrayexp and hashhashexp
+# should be something like '^(this|that)$'
+sub read_cfg_file {
+    my ($filename, $stringexp, $arrayexp, $hashexp, $arrayarrayexp,
+	$hashhashexp) = @_;
+    my ($line);
+    my $data = {};
+
+    if (open (COLCFG, $filename)) {
+	while (defined ($line = &read_cfg_line('COLCFG'))) {
+	    if (scalar(@$line) >= 2) {
+		my $key = shift (@$line);
+		if (defined $stringexp && $key =~ /$stringexp/) {
+		    $data->{$key} = shift (@$line);
+
+		} elsif (defined $arrayexp && $key =~ /$arrayexp/) {
+		    push (@{$data->{$key}}, @$line);
+
+		} elsif (defined $hashexp && $key =~ /$hashexp/) {
+		    my $k = shift @$line;
+		    my $v = shift @$line;
+		    $data->{$key}->{$k} = $v;
+		} elsif (defined $arrayarrayexp && $key =~ /$arrayarrayexp/) {
+		    if (!defined $data->{$key}) {
+			$data->{$key} = [];
+		    }
+		    push (@{$data->{$key}}, $line);
+		}
+		elsif (defined $hashhashexp && $key =~ /$hashhashexp/) {
+		    my $k = shift @$line;
+		    my $p = shift @$line;
+		    my $v = shift @$line;
+		    if (!defined $v) {
+			$v = $p;
+			$p = 'default';
+		    }
+		    $data->{$key}->{$k}->{$p} = $v;
+		}
+	    }
+	}
+	close (COLCFG);
+
+    } else {
+	print STDERR "cfgread::read_cfg_file couldn't read the cfg file $filename\n";
+    }
+
+    return $data;
+}
+
+
+# stringexp, arrayexp, hashexp and arrayarrayexp 
+# should be something like '^(this|that)$'
+sub write_cfg_file {
+    my ($filename, $data, $stringexp, $arrayexp, $hashexp, $arrayarrayexp,
+	$hashhashexp) = @_;
+
+    if (open (COLCFG, ">$filename")) {
+	foreach my $key (sort(keys(%$data))) {
+	    if ($key =~ /$stringexp/) {
+		&write_cfg_line ('COLCFG', [$key, $data->{$key}]);
+	    } elsif ($key =~ /$arrayexp/) {
+		&write_cfg_line ('COLCFG', [$key, @{$data->{$key}}]);
+	    } elsif ($key =~ /$hashexp/) {
+		foreach my $k (keys (%{$data->{$key}})) {
+		    &write_cfg_line ('COLCFG', [$key, $k, $data->{$key}->{$k}]);
+		}
+	    } elsif ($key =~ /$arrayarrayexp/) {
+		foreach my $k (@{$data->{$key}}) {
+		    &write_cfg_line ('COLCFG', [$key, @$k]);
+		}
+	    } elsif ($key =~ /$hashhashexp/) {
+		foreach my $k (keys (%{$data->{$key}})) {
+		    foreach my $p (keys (%{$data->{$key}->{$k}})) {
+			if ($p =~ /default/) {
+			    &write_cfg_line ('COLCFG', 
+					     [$key, $k, $data->{$key}->{$k}]);
+			}
+			else {
+			    &write_cfg_line ('COLCFG', 
+			       [$key, $k, $p, $data->{$key}->{$k}->{$p}]);
+			}
+		    }
+		}
+	    }
+	}
+	close (COLCFG);
+    } else {
+	print STDERR "cfgread::write_cfg_file couldn't write the cfg file $filename\n";
+    }
+}
+
+
+1;
Index: /gsdl/stable/perllib/cgiactions/baseaction.pm
===================================================================
--- /gsdl/stable/perllib/cgiactions/baseaction.pm	(revision 20131)
+++ /gsdl/stable/perllib/cgiactions/baseaction.pm	(revision 20131)
@@ -0,0 +1,440 @@
+###########################################################################
+#
+# baseaction.pm -- 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2009 New Zealand Digital Library Project
+#
+# This program is free software; you can redistr   te it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+package baseaction;
+
+
+use strict;
+
+our $authenication_enabled = 0;
+our $mail_enabled = 0;
+
+
+# change this to get these values from a config file
+my $mail_to_address = "user\@server";  # Set this appropriately
+my $mail_from_address = "user\@server";  # Set this appropriately
+my $mail_smtp_server = "smtp.server";  # Set this appropriately
+
+
+
+# Required CGI arguments: "a" for action
+#                         "c" for collection
+# Optional CGI arguemnts: "ts" for timestamp (auto generated is missing)
+#                         "site" (used by Greenstone3)
+
+# allow "un" for username to be optional for now
+
+sub new 
+{
+    my $class = shift (@_);
+
+    my ($action_table,$gsdl_cgi,$iis6_mode) = @_;
+
+    my $self = { 'gsdl_cgi' => $gsdl_cgi, 
+		 'iis6_mode' => $iis6_mode,
+		 'gsdlhome' => $ENV{'GSDLHOME'} };
+
+
+    # Retrieve the (required) command CGI argument
+    my $action = $gsdl_cgi->clean_param("a");
+
+    if (!defined $action) {
+	my $err_mess = "No action (a=...) specified.\n";
+	$err_mess .= "\nPossible actions are:\n";
+
+	$err_mess .= "  check-installation\n\n";
+
+	foreach my $a (keys %$action_table) {
+	    $err_mess .= "  $a:\n";
+	    $err_mess .= "    Compulsory args: ";
+	    $err_mess .= join(", ", ("c", "un"), 
+			      @{$action_table->{$a}->{'compulsory-args'}});
+	    $err_mess .= "\n";
+
+	    if (scalar(@{$action_table->{$a}->{'optional-args'}})>0) {
+
+		$err_mess .= "    Optional args  : ";
+		$err_mess .= join(", ", @{$action_table->{$a}->{'optional-args'}});
+		$err_mess .= "\n";
+	    }
+	    $err_mess .= "\n";
+	}
+
+	$gsdl_cgi->generate_message($err_mess);
+	exit(-1);
+	    
+    }
+    $gsdl_cgi->delete("a");
+
+
+    # The check-installation command has no arguments
+    if ($action eq "check-installation") {
+	$self->check_installation($gsdl_cgi,$iis6_mode);
+	return;
+    }
+
+
+    if (!defined $action_table->{$action}) {
+	my $valid_actions = join(", ", keys %$action_table);
+
+	my $err_mess = "Unrecognised action (a=$action) specified.\n";
+	$err_mess .= "Valid actions are: $valid_actions\n";
+
+	$gsdl_cgi->generate_error($err_mess);		
+    }
+
+    
+    my $collect = $gsdl_cgi->clean_param("c");
+    if ((!defined $collect) || ($collect =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No collection specified.");
+    }
+    $gsdl_cgi->delete("c");
+
+    # allow un to be optional for now
+    my $username = $gsdl_cgi->clean_param("un");
+
+
+    # Get then remove the ts (timestamp) argument (since this can mess up 
+    #  other scripts)
+    my $timestamp = $gsdl_cgi->clean_param("ts");
+    if ((!defined $timestamp) || ($timestamp =~ m/^\s*$/)) {
+	# Fall back to using the Perl time() function to generate a timestamp
+	$timestamp = time();  
+    }
+    $gsdl_cgi->delete("ts");
+
+    my $site = undef; 
+    if($gsdl_cgi->greenstone_version() != 2) { 
+	# all GS versions after 2 may define site
+	$site = $gsdl_cgi->clean_param("site");   
+	if (!defined $site) {
+	    $gsdl_cgi->generate_error("No site specified.");
+	}
+	$gsdl_cgi->delete("site");
+    }
+    
+    $self->{'action'} = $action;
+    $self->{'collect'} = $collect;
+    $self->{'username'} = $username;
+    $self->{'timestamp'} = $timestamp;
+    $self->{'site'} = $site;
+
+    # Locate and store compulsory arguments
+    my $comp_args = $action_table->{$action}->{'compulsory-args'};
+    foreach my $ca (@$comp_args) {
+	if (!defined $gsdl_cgi->{$ca}) {
+	    $gsdl_cgi->generate_error("Compulsory argument '$ca' missing");
+	}
+	else {
+	    $self->{$ca} = $gsdl_cgi->clean_param($ca);
+	    $gsdl_cgi->delete($ca);
+	}
+    }
+
+    # Locate and store optional args if present
+    my $opt_args = $action_table->{$action}->{'optional-args'};
+    foreach my $oa (@$opt_args) {
+	if (defined $gsdl_cgi->{$oa}) {
+	    
+	    $self->{$oa} = $gsdl_cgi->clean_param($oa);
+	    $gsdl_cgi->delete($oa);
+	}
+    }
+
+
+    return bless $self, $class;
+}
+
+
+sub do_action
+{
+    my $self = shift @_;
+    my $action = $self->{'action'};
+
+    $action =~ s/-/_/g;
+
+    
+    $self->$action();
+
+}
+
+
+
+
+sub authenticate_user
+{
+    my $self = shift @_;
+    my ($username,$collection) = shift(@_);
+
+    my $gsdl_cgi = $self->{'gsdl_cgi'};
+
+    # Remove the pw argument (since this can mess up other scripts)
+    my $user_password = $gsdl_cgi->clean_param("pw");
+    $gsdl_cgi->delete("pw");
+
+    if ((!defined $user_password) || ($user_password =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("Authentication failed: no password specified.");
+    }
+
+    my $gsdlhome = $ENV{'GSDLHOME'};
+    my $etc_directory = &util::filename_cat($gsdlhome, "etc");
+    my $users_db_file_path = &util::filename_cat($etc_directory, "users.db");
+
+    # Use db2txt instead of GDBM_File to get the user accounts information
+    my $users_db_content = "";
+    open(USERS_DB, "db2txt \"$users_db_file_path\" |");
+    while (<USERS_DB>) {
+	$users_db_content .= $_;
+    }
+
+    # Get the user account information from the users.db database
+    my %users_db_data = ();
+    foreach my $users_db_entry (split(/-{70}/, $users_db_content)) {
+	if ($users_db_entry =~ /\n?\[(.+)\]\n/) {
+	    $users_db_data{$1} = $users_db_entry;
+	}
+    }
+
+    # Check username
+    my $user_data = $users_db_data{$username};
+    if (!defined $user_data) {
+	$gsdl_cgi->generate_error("Authentication failed: no account for user '$username'.");
+    }
+
+    # Check password
+    my ($valid_user_password) = ($user_data =~ /\<password\>(.*)/);
+    if ($user_password ne $valid_user_password) {
+	$gsdl_cgi->generate_error("Authentication failed: incorrect password.");
+    }
+
+    # Check group
+    my ($user_groups) = ($user_data =~ /\<groups\>(.*)/);
+    if ($collection eq "") {
+	# If we're not editing a collection then the user doesn't need to be in a particular group
+	return $user_groups;  # Authentication successful
+    }
+    foreach my $user_group (split(/\,/, $user_groups)) {
+	# Does this user have access to all collections?
+	if ($user_group eq "all-collections-editor") {
+	    return $user_groups;  # Authentication successful
+	}
+	# Does this user have access to personal collections, and is this one?
+	if ($user_group eq "personal-collections-editor" && $collection =~ /^$username\-/) {
+	    return $user_groups;  # Authentication successful
+	}
+	# Does this user have access to this collection
+	if ($user_group eq "$collection-collection-editor") {
+	    return $user_groups;  # Authentication successful
+	}
+    }
+
+    $gsdl_cgi->generate_error("Authentication failed: user is not in the required group.");
+}
+
+
+
+sub check_installation
+{
+    my $self = shift @_;
+    my ($iis6_mode) = @_;
+
+    my $gsdl_cgi = $self->{'gsdl_cgi'};
+
+    my $installation_ok = 1;
+    my $installation_status = "";
+
+    print STDOUT "Content-type:text/plain\n\n";
+
+    # Check that Java is installed and accessible
+    my $java = $gsdl_cgi->get_java_path();
+    my $java_command = "$java -version 2>&1";
+
+    # IIS 6: redirecting output from STDERR to STDOUT just doesn't work, so we have to let it go
+    #   directly out to the page
+    if ($iis6_mode)
+    {
+	$java_command = "java -version";
+    }
+
+    my $java_output = `$java_command`;
+    my $java_status = $?;
+    if ($java_status < 0) {
+	# The Java command failed
+	$installation_status = "Java failed -- do you have the Java run-time installed?\n" . $gsdl_cgi->check_java_home() . "\n";
+	$installation_ok = 0;
+    }
+    else {
+	$installation_status = "Java found: $java_output";
+    }
+
+    # Show the values of some important environment variables
+    $installation_status .= "\n";
+    $installation_status .= "GSDLHOME: " . $ENV{'GSDLHOME'} . "\n";
+    $installation_status .= "GSDLOS: " . $ENV{'GSDLOS'} . "\n";
+    $installation_status .= "PATH: " . $ENV{'PATH'} . "\n";
+
+    if ($installation_ok) {
+	print STDOUT $installation_status . "\nInstallation OK!";
+    }
+    else {
+	print STDOUT $installation_status;
+    }
+}
+
+sub lock_collection
+{
+    my $self = shift @_;
+
+    my ($username,$collection) = shift(@_);
+
+    my $gsdl_cgi = $self->{'gsdl_cgi'};
+
+    my $steal_lock = $gsdl_cgi->clean_param("steal_lock");
+    $gsdl_cgi->delete("steal_lock");
+
+    if (!defined $username) {
+	# don't have any user details for current user to compare with
+	# even if there is a lock file
+	# For now, allow the current user access.  Might want to
+	# revisit this in the future.
+	return;
+    }
+
+    my $gsdlhome = $ENV{'GSDLHOME'};
+    my $collection_directory = &util::filename_cat($gsdlhome, "collect", $collection);
+    $gsdl_cgi->checked_chdir($collection_directory);
+
+    # Check if a lock file already exists for this collection
+    my $lock_file_name = "gli.lck";
+    if (-e $lock_file_name) {
+	# A lock file already exists... check if it's ours
+	my $lock_file_content = "";
+	open(LOCK_FILE, "<$lock_file_name");
+	while (<LOCK_FILE>) {
+	    $lock_file_content .= $_;
+	}
+	close(LOCK_FILE);
+
+	# Pick out the owner of the lock file
+	$lock_file_content =~ /\<User\>(.*?)\<\/User\>/;
+	my $lock_file_owner = $1;
+
+	# The lock file is ours, so there is no problem
+	if ($lock_file_owner eq $username) {
+	    return;
+	}
+
+	# The lock file is not ours, so throw an error unless "steal_lock" is set
+	unless (defined $steal_lock) {
+	    $gsdl_cgi->generate_error("Collection is locked by: $lock_file_owner");
+	}
+    }
+
+    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
+    my $current_time = sprintf("%02d/%02d/%d %02d:%02d:%02d", $mday, $mon + 1, $year + 1900, $hour, $min, $sec);
+
+    # Create a lock file for us (in the same format as the GLI) and we're done
+    open(LOCK_FILE, ">$lock_file_name");
+    print LOCK_FILE "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+    print LOCK_FILE "<LockFile>\n";
+    print LOCK_FILE "    <User>" . $username . "</User>\n";
+    print LOCK_FILE "    <Machine>(Remote)</Machine>\n";
+    print LOCK_FILE "    <Date>" . $current_time . "</Date>\n";
+    print LOCK_FILE "</LockFile>\n";
+    close(LOCK_FILE);
+}
+
+
+sub send_mail
+{
+    my $self = shift @_;
+
+    my ($mail_subject,$mail_content) = @_;
+
+    my $gsdl_cgi = $self->{'gsdl_cgi'};
+
+    my $sendmail_command = "perl -S sendmail.pl";
+    $sendmail_command .= " -to \"" . $mail_to_address . "\"";
+    $sendmail_command .= " -from \"" . $mail_from_address . "\"";
+    $sendmail_command .= " -smtp \"" . $mail_smtp_server . "\"";
+    $sendmail_command .= " -subject \"" . $mail_subject . "\"";
+
+    if (!open(POUT, "| $sendmail_command")) {
+	$gsdl_cgi->generate_error("Unable to execute command: $sendmail_command");
+    }
+    print POUT $mail_content . "\n";
+    close(POUT);
+}
+
+
+
+
+sub run_script
+{
+    my $self = shift @_;
+
+    my ($collect, $site, $script) = @_;
+
+    my $gsdl_cgi = $self->{'gsdl_cgi'};
+
+    my $perl_args = $collect;
+
+    my $collect_dir = $gsdl_cgi->get_collection_dir($site); 
+    $perl_args = "-collectdir \"$collect_dir\" " . $perl_args;
+
+    my $perl_command = "perl -S $script $perl_args";
+
+
+    # IIS 6: redirecting output from STDERR to STDOUT just doesn't work, so
+    # we have to let it go directly out to the page
+
+    if (!$self->{'iis6_mode'})
+    {
+	$perl_command .= " 2>&1";
+    }
+
+    if (!open(PIN, "$perl_command |")) {
+	$gsdl_cgi->generate_error("Unable to execute command: $perl_command");
+    }
+
+    print STDOUT "Content-type:text/plain\n\n";
+    print "$perl_command  \n";
+
+    while (defined (my $perl_output_line = <PIN>)) {
+	print STDOUT $perl_output_line;
+    }
+    close(PIN);
+
+    my $perl_status = $?;
+    if ($perl_status > 0) {
+	$gsdl_cgi->generate_error("Perl failed: $perl_command\n--\nExit status: " . ($perl_status / 256));
+    }
+}
+
+
+
+
+1;
Index: /gsdl/stable/perllib/cgiactions/imageaction.pm
===================================================================
--- /gsdl/stable/perllib/cgiactions/imageaction.pm	(revision 20131)
+++ /gsdl/stable/perllib/cgiactions/imageaction.pm	(revision 20131)
@@ -0,0 +1,183 @@
+###########################################################################
+#
+# imageaction.pm -- 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2009 New Zealand Digital Library Project
+#
+# This program is free software; you can redistr   te it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package imageaction;
+
+use strict;
+
+use cgiactions::baseaction;
+
+@imageaction::ISA = ('baseaction');
+
+
+my $action_table =
+{ 
+    "fit-screen" => { 'compulsory-args' => [ "pageWidth", "pageHeight", 
+					     "assocDir", "assocFile" ],
+		      'optional-args'   => [ "orientation" ] },
+
+};
+
+
+sub new 
+{
+    my $class = shift (@_);
+    my ($gsdl_cgi,$iis6_mode) = @_;
+
+    my $self = new baseaction($action_table,$gsdl_cgi,$iis6_mode);
+
+    return bless $self, $class;
+}
+
+
+
+sub get_mime_type
+{
+    my $self = shift @_;
+
+    my ($file) = @_;
+
+    my %image_mime_re = 
+    (
+	"gif"   => "image/gif",
+	"jpe?g" => "image/jpeg",
+	"png"   => "image/png",
+	"tiff?" => "image/tiff",
+	"bmp"   => "image/bmp"
+    );
+
+    my ($ext) = ($file =~ m/^.*\.(.*)?$/);
+
+    foreach my $re (keys %image_mime_re) {
+	if ($ext =~ m/^$re$/i) {
+	    return $image_mime_re{$re};
+	}
+    }
+
+    return undef;
+}
+
+
+
+
+sub fit_screen
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdlhome  = $self->{'gsdlhome'};
+
+
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	&authenticate_user($gsdl_cgi, $username, $collect);
+    }
+
+    my $collect_directory = &util::filename_cat($gsdlhome, "collect");
+#    $gsdl_cgi->checked_chdir($collect_directory);
+
+
+#    # Make sure the collection isn't locked by someone else
+#
+
+    $self->lock_collection($username, $collect);
+
+    # look up additional args
+
+    my $pageWidth  = $self->{'pageWidth'};
+    my $pageHeight = $self->{'pageHeight'};
+    my $assocDir   = $self->{'assocDir'};
+    my $assocFile  = $self->{'assocFile'};
+
+    my $orientation = $self->{'orientation'};
+    $orientation = "portrait" if (!defined $orientation);
+
+    my $toplevel_assoc_dir
+	= &util::filename_cat($collect_directory,$collect,"index","assoc");
+    my $src_full_assoc_filename
+	= &util::filename_cat($toplevel_assoc_dir,$assocDir,$assocFile);
+
+    my $dst_width = $pageWidth;
+    my $dst_height = $pageHeight;
+
+    my $opt_ls = ($orientation eq "landscape") ? "-r" : "";
+    
+    my $dst_file = $dst_width."x".$dst_height."$opt_ls-$assocFile";
+
+    my $dst_full_assoc_filename
+	= &util::filename_cat($toplevel_assoc_dir,$assocDir,$dst_file);
+
+    # **** What if assoc folder is on read-only medium such as CD-ROM?
+    # Should really switch to using some collection specific tmp area
+    # => test if top_level assoc dir has write permission?
+
+    if (!-w $toplevel_assoc_dir) {
+	$gsdl_cgi->generate_error("Cannot write out resized image $dst_full_assoc_filename.");
+    }
+
+    # For now will assume it is writable
+
+    if (!-e $dst_full_assoc_filename) {
+	# generate resized image
+
+	# Better to make sure ImageMagick is installed 
+	
+        my $resize = "-filter Lanczos -resize $dst_width"."x"."$dst_height!";
+	# use of "!" forces convert to produce exactly these dimensions, rather
+	# than preserving aspect ratio.  In actual fact, it is intended that
+	# the width and height values passed in *do* preserve the aspect ratio
+	# Doing it this way makes it easier for the web browser to know (ahead of time) the
+	# width and height of the image that will be generated (useful for putting into
+	# <img> and <div> tags
+
+
+	my $cmd = "convert \"$src_full_assoc_filename\" ";
+	$cmd .= "-rotate 90 " if ($orientation eq "landscape");
+
+	$cmd .= "$resize \"$dst_full_assoc_filename\"";
+
+	`$cmd`;
+
+	# generate resized image in assoc file area (if writable)
+	# otherwise in (collection's??) tmp directory
+    }
+
+    my $mime_type = $self->get_mime_type($dst_file);
+    
+    if (defined $mime_type) {
+	# now output it with suitable mime header
+	print STDOUT "Content-type:$mime_type\n\n";
+	system("cat \"$dst_full_assoc_filename\"");
+    }
+    else {
+	$gsdl_cgi->generate_error("Unrecognised image mime-type for $dst_file");
+    }
+
+}
+
+
+1;
Index: /gsdl/stable/perllib/cgiactions/indexaction.pm
===================================================================
--- /gsdl/stable/perllib/cgiactions/indexaction.pm	(revision 20131)
+++ /gsdl/stable/perllib/cgiactions/indexaction.pm	(revision 20131)
@@ -0,0 +1,93 @@
+###########################################################################
+#
+# indexaction.pm -- 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2009 New Zealand Digital Library Project
+#
+# This program is free software; you can redistr   te it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+package indexaction;
+
+
+use strict;
+
+use cgiactions::baseaction;
+
+
+
+@indexaction::ISA = ('baseaction');
+
+
+
+my $action_table = { 
+    "incremental-rebuild" => 
+    { 'compulsory-args' => [ "un", "metaname" ],
+      'optional-args'   => [] 
+      },
+  };
+
+
+sub new 
+{
+    my $class = shift (@_);
+    my ($gsdl_cgi,$iis6_mode) = @_;
+
+    my $self = new baseaction($action_table,$gsdl_cgi,$iis6_mode);
+
+    return bless $self, $class;
+}
+
+
+
+
+sub incremental_rebuild
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $timestamp = $self->{'timestamp'};
+    my $site      = $self->{'site'};
+
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+
+    # timestamp could turn out to be useful, but not used just now
+
+    # don't user authenticate for now
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	$self->authenticate_user($username, $collect);
+    }
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect, $site);
+
+    $self->run_script($collect,$site,"incremental-rebuild.pl");
+
+
+    if ($baseaction::mail_enabled) {
+	$self->send_mail("Remote Greenstone building event", "Build of collection '$collect' complete.");
+    }
+
+}
+
+
+1;
Index: /gsdl/stable/perllib/cgiactions/metadataaction.pm
===================================================================
--- /gsdl/stable/perllib/cgiactions/metadataaction.pm	(revision 20131)
+++ /gsdl/stable/perllib/cgiactions/metadataaction.pm	(revision 20131)
@@ -0,0 +1,706 @@
+###########################################################################
+#
+# metadataaction.pm -- 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2009 New Zealand Digital Library Project
+#
+# This program is free software; you can redistr   te it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package metadataaction;
+
+use strict;
+
+use cgiactions::baseaction;
+
+use GDBMUtils;
+use ghtml;
+
+BEGIN {
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan/perl-5.8");
+    require XML::Rules;
+}
+
+
+@metadataaction::ISA = ('baseaction');
+
+
+
+my $action_table =
+{ 
+    "get-live-metadata"    => { 'compulsory-args' => [ "d", "metaname" ],
+			        'optional-args'   => [] }, 
+
+    "get-metadata"         => { 'compulsory-args' => [ "d", "metaname" ],
+			        'optional-args'   => [ "metapos" ] }, 
+
+    "set-live-metadata"    => { 'compulsory-args' => [ "d", "metaname", "metavalue" ],
+			        'optional-args'   => [ ] },
+
+    "set-metadata"         => { 'compulsory-args' => [ "d", "metaname", "metavalue" ],
+			        'optional-args'   => [ "metapos" ] },
+
+    "set-import-metadata"  => { 'compulsory-args' => [ "metaname", "metavalue" ],
+			        'optional-args'   => [ "d", "f", "metamode" ]
+				   # metamode can be "accumulate", "override", or "unique-id"
+				},
+    "remove-live-metadata" => { 'compulsory-args' => [ "d", "metaname" ],
+			        'optional-args'   => [ ] },
+
+    "remove-metadata"      => { 'compulsory-args' => [ "d", "metaname" ],
+			        'optional-args'   => [ "metapos" ] }
+};
+
+
+sub new 
+{
+    my $class = shift (@_);
+    my ($gsdl_cgi,$iis6_mode) = @_;
+
+    my $self = new baseaction($action_table,$gsdl_cgi,$iis6_mode);
+
+    return bless $self, $class;
+}
+
+
+
+sub get_live_metadata
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdlhome  = $self->{'gsdlhome'};
+
+    my $collect_dir = &util::filename_cat($gsdlhome, "collect");
+#    $gsdl_cgi->checked_chdir($collect_dir);
+
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect);
+
+    # look up additional args
+
+    my $docid  = $self->{'d'};
+    if ((!defined $docid) || ($docid =~ m/^\s*$/)) {
+	$gsdl_cgi->generate_error("No docid (d=...) specified.");
+    }
+
+    my $metaname  = $self->{'metaname'};
+
+    my $dbkey = "$docid.$metaname";
+
+    my $collect_tail = $collect;
+    $collect_tail =~ s/^.*[\/|\\]//;
+
+    my $gdbm_directory = &util::filename_cat($collect_dir,$collect,"index","text");
+    my $gdbm_db = &util::filename_cat($gdbm_directory,"live-$collect_tail.gdb");
+
+    my $cmd = "gdbmget $gdbm_db $dbkey";
+
+    if (open(GIN,"$cmd |") == 0) {
+	my $mess = "Failed to get metadata key: $metaname\n";
+	$mess .= "$!\n";
+
+	$gsdl_cgi->generate_error($mess);
+    }
+
+    else {
+	my $metavalue = "";
+
+	my $line;
+	while (defined ($line=<GIN>)) {
+	    $metavalue .= $line;
+	}
+	close(GIN);
+
+	chomp($metavalue);
+
+	$gsdl_cgi->generate_ok_message("$metavalue");
+    }
+}
+
+
+
+sub get_metadata
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdlhome  = $self->{'gsdlhome'};
+
+
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	&authenticate_user($gsdl_cgi, $username, $collect);
+    }
+
+    my $collect_dir = &util::filename_cat($gsdlhome, "collect");
+#    $gsdl_cgi->checked_chdir($collect_dir);
+
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect);
+
+    # look up additional args
+
+    my $docid     = $self->{'d'};
+    my $metaname  = $self->{'metaname'};
+    my $metapos   = $self->{'metapos'};
+
+    my $collect_tail = $collect;
+    $collect_tail =~ s/^.*[\/\\]//;
+
+    my $gdbm_directory = &util::filename_cat($collect_dir,$collect,"index","text");
+    my $gdbm_db = &util::filename_cat($gdbm_directory,"$collect_tail.gdb");
+
+    my $doc_rec = GDBMUtils::gdbmRecordToHash($gdbm_db,$docid);
+    foreach my $k (keys %$doc_rec) {
+	my @escaped_v = ();
+	foreach my $v (@{$doc_rec->{$k}}) {
+	    my $ev = &ghtml::unescape_html($v);
+	    push(@escaped_v, $ev);
+	}
+
+	$doc_rec->{$k} = \@escaped_v;
+    }
+
+    $metapos = 0 if (!defined $metapos);
+
+    my $metavalue = $doc_rec->{$metaname}->[$metapos];
+
+    $gsdl_cgi->generate_ok_message("$metavalue");
+
+}
+
+
+
+
+sub set_live_metadata
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdlhome  = $self->{'gsdlhome'};
+
+
+    # don't user authenticate for now
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	&authenticate_user($gsdl_cgi, $username, $collect);
+    }
+
+    my $collect_dir = &util::filename_cat($gsdlhome, "collect");
+#    $gsdl_cgi->checked_chdir($collect_dir);
+
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect);
+
+    # look up additional args
+
+    my $docid     = $self->{'d'};
+    my $metaname  = $self->{'metaname'};
+    my $metavalue = $self->{'metavalue'};
+
+    my $dbkey = "$docid.$metaname";
+
+    my $collect_tail = $collect;
+    $collect_tail =~ s/^.*[\/\\]//;
+
+    my $gdbm_directory = &util::filename_cat($collect_dir,$collect,"index","text");
+    my $gdbm_db = &util::filename_cat($gdbm_directory,"live-$collect_tail.gdb");
+
+    my $cmd = "gdbmset \"$gdbm_db\" \"$dbkey\" \"$metavalue\"";
+
+    my $status = system($cmd);
+
+    if ($status != 0) {
+	my $mess = "Failed to set metadata key: $dbkey\n";
+	
+	$mess .= "PATH: $ENV{'PATH'}\n";
+	$mess .= "cmd = $cmd\n";
+	$mess .= "Exit status: $status\n";
+	$mess .= "System Error Message: $!\n";
+
+	$gsdl_cgi->generate_error($mess);
+    }
+    else {
+	$gsdl_cgi->generate_ok_message("set-live-metadata successful: Key[$metaname]=$metavalue");
+    }
+
+}
+
+
+sub set_metadata
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdlhome  = $self->{'gsdlhome'};
+
+
+    # don't user authenticate for now
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	&authenticate_user($gsdl_cgi, $username, $collect);
+    }
+
+    my $collect_dir = &util::filename_cat($gsdlhome, "collect");
+#    $gsdl_cgi->checked_chdir($collect_dir);
+
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect);
+
+    # look up additional args
+
+    my $docid     = $self->{'d'};
+    my $metaname  = $self->{'metaname'};
+    my $metapos   = $self->{'metapos'};
+    my $metavalue = $self->{'metavalue'};
+
+    my $collect_tail = $collect;
+    $collect_tail =~ s/^.*[\/\\]//;
+
+    my $gdbm_directory = &util::filename_cat($collect_dir,$collect,"index","text");
+    my $gdbm_db = &util::filename_cat($gdbm_directory,"$collect_tail.gdb");
+
+    my $doc_rec = GDBMUtils::gdbmRecordToHash($gdbm_db,$docid);
+    foreach my $k (keys %$doc_rec) {
+	my @escaped_v = ();
+	foreach my $v (@{$doc_rec->{$k}}) {
+	    if ($k eq "contains") {
+		# protect quotes in ".2;".3 etc
+		$v =~ s/\"/\\\"/g;
+		push(@escaped_v, $v);
+	    }
+	    else {
+		my $ev = &ghtml::unescape_html($v);
+		$ev =~ s/\"/\\\"/g;
+		push(@escaped_v, $ev);
+	    }
+	}
+
+	$doc_rec->{$k} = \@escaped_v;
+    }
+
+    ## print STDERR "**** metavalue = $metavalue\n";
+
+    $metavalue =~ s/\"/\\\"/g;
+
+    if (defined $metapos) {
+	$doc_rec->{$metaname}->[$metapos] = $metavalue;
+    }
+    else {
+	$doc_rec->{$metaname} = [ $metavalue ];
+    }
+
+    ## print STDERR "**** metavalue = $metavalue\n";
+
+    my $serialized_doc_rec = GDBMUtils::serializeHash($doc_rec);
+
+    print STDERR "**** ser dr\n$serialized_doc_rec\n\n\n";
+
+    my $cmd = "gdbmset \"$gdbm_db\" \"$docid\" \"$serialized_doc_rec\"";
+
+    my $status = system($cmd);
+
+    if ($status != 0) {
+	my $mess = "Failed to set metadata key: $docid\n";
+	
+	$mess .= "PATH: $ENV{'PATH'}\n";
+	$mess .= "cmd = $cmd\n";
+	$mess .= "Exit status: $status\n";
+	$mess .= "System Error Message: $!\n";
+
+	$gsdl_cgi->generate_error($mess);
+    }
+    else {
+	my $mess = "set-document-metadata successful: Key[$docid]\n";
+	$mess .= "  $metaname";
+	$mess .= "->[$metapos]" if (defined $metapos);
+	$mess .= " = $metavalue";
+
+	$gsdl_cgi->generate_ok_message($mess);
+    }
+
+}
+
+
+
+
+
+
+sub mxml_metadata
+{
+
+    my ($tagname, $attrHash, $contextArray, $parentDataArray, $parser) = @_;
+
+
+    my $metaname = $parser->{'parameters'}->{'metaname'};
+    my $metamode = $parser->{'parameters'}->{'metamode'};
+
+    my $name_attr = $attrHash->{'name'};
+
+    if (($name_attr eq $metaname) && ($metamode eq "override")) {
+
+	my $metavalue = $parser->{'parameters'}->{'metavalue'};
+
+	$attrHash->{'_content'} = $metavalue;
+
+	# Don't want it to wipe out any other pieces of metadata
+	$parser->{'parameters'}->{'metamode'} = "done";
+
+    }
+
+    # raw extended
+    return (':'.$tagname => $attrHash, [$tagname => $attrHash]);
+}
+
+
+sub mxml_description
+{
+
+    my ($tagname, $attrHash, $contextArray, $parentDataArray, $parser) = @_;
+
+    my $metamode = $parser->{'parameters'}->{'metamode'};
+
+
+    if ($metamode eq "accumulate") {
+	# tack a new metadata tag on to the end of the <Metadata>+ block
+
+	my $metaname = $parser->{'parameters'}->{'metaname'};
+	my $metavalue = $parser->{'parameters'}->{'metavalue'};
+	
+
+	my $metadata_attr = { '_content' => $metavalue, 
+			      'name'     => $metaname, 
+			      'mode'     => "accumulate" };
+
+	my $append_metadata = [ "Metadata" => $metadata_attr ];
+
+	my $description_content = $attrHash->{'_content'};
+
+	push(@$description_content,"    ", $append_metadata ,"\n        ");
+
+    }
+
+    # raw
+    return $tagname => $attrHash;
+}
+
+sub edit_metadata_xml
+{
+    my $self = shift @_;
+
+    my ($gsdl_cgi, $metadata_xml_filename, $file, $metaname, $metavalue, $metamode) = @_;
+
+    # use XML::Rules to add it in (read in and out again)
+
+    my @rules = 
+	( _default => 'raw extended',
+	  'Metadata' => \&mxml_metadata,
+	  'Description' => \&mxml_description );
+	  
+
+    my $parser = XML::Rules->new(rules => \@rules, 
+				 style => 'filter' );
+
+
+    my $xml_in = "";
+    if (!open(MIN,"<$metadata_xml_filename")) {
+	$gsdl_cgi->generate_error("Unable to read in $metadata_xml_filename: $!");
+    }
+    else {
+	my $line;
+	while (defined ($line=<MIN>)) {
+	    $xml_in .= $line;
+	}
+	close(MIN);
+	
+	
+	my $xml_out = "";
+	$parser->filter($xml_in,\$xml_out, { metaname => $metaname,
+					     metavalue => $metavalue,
+					     metamode => $metamode } );
+    
+	if (!open(MOUT,">$metadata_xml_filename")) {
+	    $gsdl_cgi->generate_error("Unable to write out to $metadata_xml_filename: $!");
+	}
+	else {
+	    print MOUT $xml_out;
+	    close(MOUT);
+	    
+	}
+    }
+
+
+
+}
+
+sub set_import_metadata
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdlhome  = $self->{'gsdlhome'};
+
+
+    # don't user authenticate for now
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	$self->authenticate_user($username, $collect);
+    }
+
+    my $collect_dir = &util::filename_cat($gsdlhome, "collect");
+#    $gsdl_cgi->checked_chdir($collect_dir);
+
+    my $archive_dir = &util::filename_cat($collect_dir,$collect,"archives");
+
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect);
+
+    # look up additional args
+
+    # want either d= or f=
+    my $docid  = $self->{'d'};
+    my $import_file  = $self->{'f'};
+
+    if ((!defined $docid) && (!defined $import_file)) {
+	$gsdl_cgi->generate_error("No docid (d=...) or import file (f=) specified.");
+    } 
+
+    my $metaname   = $self->{'metaname'};
+    my $metavalue  = $self->{'metavalue'};
+    my $metamode   = $self->{'metamode'};
+
+    if ((!defined $metamode) || ($metamode =~ m/^\s*$/)) {
+	# make "accumulate" the default (less destructive, as won't actually 
+	# delete any existing values)
+
+	$metamode = "accumulate";
+    }
+
+    my $metadata_xml_file;
+
+    if (defined $docid) {
+
+	my $doc_db = "archiveinf-doc.gdb";
+	my $arcinfo_doc_filename = &util::filename_cat ($archive_dir, $doc_db);
+
+	my $doc_rec = GDBMUtils::gdbmRecordToHash($arcinfo_doc_filename,$docid);
+
+	$import_file = $doc_rec->{'src-file'}->[0];
+    }
+    
+
+    my $import_filename = &util::filename_cat($collect_dir,$collect,$import_file);
+
+
+    # Assuming that the metadata field is being indexed, then
+    # **** "touch" (in the Unix sense) $import_filename so we know it needs to
+    # be reindexed?
+    # (to be implemented)
+    
+    # figure out correct metadata.xml file
+
+    my ($import_tailname, $import_dirname) 
+	= File::Basename::fileparse($import_filename);
+
+    my $metadata_xml_filename = &util::filename_cat($import_dirname,"metadata.xml");
+
+    $self->edit_metadata_xml($gsdl_cgi,$metadata_xml_filename,$import_tailname,
+			     $metaname,$metavalue,$metamode);
+
+}
+
+
+
+
+
+sub remove_live_metadata
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdlhome  = $self->{'gsdlhome'};
+
+
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	&authenticate_user($gsdl_cgi, $username, $collect);
+    }
+
+    my $collect_dir = &util::filename_cat($gsdlhome, "collect");
+#    $gsdl_cgi->checked_chdir($collect_dir);
+
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect);
+
+    # look up additional args
+
+    my $docid     = $self->{'d'};
+    my $metaname  = $self->{'metaname'};
+
+    my $dbkey = "$docid.$metaname";
+
+    my $collect_tail = $collect;
+    $collect_tail =~ s/^.*[\/\\]//;
+
+    my $gdbm_directory = &util::filename_cat($collect_dir,$collect,"index","text");
+    my $gdbm_db = &util::filename_cat($gdbm_directory,"live-$collect_tail.gdb");
+
+    my $cmd = "gdbmdel \"$gdbm_db\" \"$dbkey\"";
+
+    my $status = system($cmd);
+
+    if ($status != 0) {
+	my $mess = "Failed to set metadata key: $dbkey\n";
+	
+	$mess .= "PATH: $ENV{'PATH'}\n";
+	$mess .= "cmd = $cmd\n";
+	$mess .= "Exit status: $status\n";
+	$mess .= "System Error Message: $!\n";
+
+	$gsdl_cgi->generate_error($mess);
+    }
+    else {
+	$gsdl_cgi->generate_ok_message("DB remove successful: Key[$metaname]");
+    }
+
+}
+
+
+sub remove_metadata
+{
+    my $self = shift @_;
+
+    my $username  = $self->{'username'};
+    my $collect   = $self->{'collect'};
+    my $gsdl_cgi  = $self->{'gsdl_cgi'};
+    my $gsdlhome  = $self->{'gsdlhome'};
+
+
+    # don't user authenticate for now
+    if ($baseaction::authentication_enabled) {
+	# Ensure the user is allowed to edit this collection
+	&authenticate_user($gsdl_cgi, $username, $collect);
+    }
+
+    my $collect_dir = &util::filename_cat($gsdlhome, "collect");
+#    $gsdl_cgi->checked_chdir($collect_dir);
+
+
+    # Make sure the collection isn't locked by someone else
+    $self->lock_collection($username, $collect);
+
+    # look up additional args
+
+    my $docid     = $self->{'d'};
+    my $metaname  = $self->{'metaname'};
+    my $metapos   = $self->{'metapos'};
+
+    my $collect_tail = $collect;
+    $collect_tail =~ s/^.*[\/\\]//;
+
+    my $gdbm_directory = &util::filename_cat($collect_dir,$collect,"index","text");
+    my $gdbm_db = &util::filename_cat($gdbm_directory,"$collect_tail.gdb");
+
+    my $doc_rec = GDBMUtils::gdbmRecordToHash($gdbm_db,$docid);
+    foreach my $k (keys %$doc_rec) {
+	my @escaped_v = ();
+	foreach my $v (@{$doc_rec->{$k}}) {
+	    if ($k eq "contains") {
+		# protect quotes in ".2;".3 etc
+		$v =~ s/\"/\\\"/g;
+		push(@escaped_v, $v);
+	    }
+	    else {
+		my $ev = &ghtml::unescape_html($v);
+		$ev =~ s/\"/\\\"/g;
+		push(@escaped_v, $ev);
+	    }
+	}
+
+	$doc_rec->{$k} = \@escaped_v;
+    }
+
+    $metapos = 0 if (!defined $metapos);
+
+    # consider check key is defined before deleting?
+
+    my $filtered_metadata = [];
+    my $num_metadata_vals = scalar(@{$doc_rec->{$metaname}});
+
+    for (my $i=0; $i<$num_metadata_vals; $i++) {
+	my $metavalue = shift(@{$doc_rec->{$metaname}});
+
+	if ($i != $metapos) {
+	    push(@$filtered_metadata,$metavalue)
+	}
+    }
+
+    $doc_rec->{$metaname} = $filtered_metadata;
+
+    my $serialized_doc_rec = GDBMUtils::serializeHash($doc_rec);
+
+    my $cmd = "gdbmset \"$gdbm_db\" \"$docid\" \"$serialized_doc_rec\"";
+
+    my $status = system($cmd);
+
+    if ($status != 0) {
+	my $mess = "Failed to set metadata key: $docid\n";
+	
+	$mess .= "PATH: $ENV{'PATH'}\n";
+	$mess .= "cmd = $cmd\n";
+	$mess .= "Exit status: $status\n";
+	$mess .= "System Error Message: $!\n";
+
+	$gsdl_cgi->generate_error($mess);
+    }
+    else {
+	my $mess = "DB set (with item deleted) successful: Key[$docid]\n";
+	$mess .= "  $metaname";
+	$mess .= "->[$metapos]" if (defined $metapos);
+
+	$gsdl_cgi->generate_ok_message($mess);
+    }
+
+}
+
+
+
+
+
+
+1;
Index: /gsdl/stable/perllib/classify.pm
===================================================================
--- /gsdl/stable/perllib/classify.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify.pm	(revision 20131)
@@ -0,0 +1,436 @@
+###########################################################################
+#
+# classify.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# functions to handle classifiers
+
+package classify;
+
+require util;
+require AllList;
+
+use dbutil;
+use gsprintf;
+use strict; no strict 'subs';
+
+
+sub gsprintf
+{
+    return &gsprintf::gsprintf(@_);
+}
+
+
+sub load_classifier_for_info {
+    my ($classifier) = shift @_;
+
+    # find the classifier
+    my $customclassname;
+    if (defined($ENV{'GSDLCOLLECTION'}))
+    {
+	$customclassname = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "custom", $ENV{'GSDLCOLLECTION'},
+                                              "perllib", "classify", "${classifier}.pm");
+    }
+    my $colclassname = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "perllib", "classify", "${classifier}.pm");
+    my $mainclassname = &util::filename_cat($ENV{'GSDLHOME'}, "perllib", "classify", "${classifier}.pm");
+
+    if (defined($customclassname) && -e $customclassname) { require $customclassname; }
+    elsif (-e $colclassname) { require $colclassname; }
+    elsif (-e $mainclassname) { require $mainclassname; }
+    else { 
+	&gsprintf(STDERR, "{classify.could_not_find_classifier}\n", $classifier) && die "\n";
+    }
+    my ($classobj);
+    my $options = "-gsdlinfo";
+    eval ("\$classobj = new \$classifier([],[$options])");
+    die "$@" if $@;
+
+    return $classobj;
+}
+
+sub load_classifiers {
+    my ($classify_list, $build_dir, $outhandle) = @_;
+    my @classify_objects = ();
+    my $classify_number  = 1;
+
+     my $colclassdir = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"perllib/classify");
+     unshift (@INC, $colclassdir);
+    
+    foreach my $classifyoption (@$classify_list) {
+
+	# get the classifier name
+	my $classname = shift @$classifyoption;
+	next unless defined $classname;
+
+	# find the classifier
+        my $customclassname = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "custom", $ENV{'GSDLCOLLECTION'},
+                                                  "perllib", "classify", "${classname}.pm");
+        my $colclassname = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "perllib", "classify", "${classname}.pm");
+        my $mainclassname = &util::filename_cat($ENV{'GSDLHOME'}, "perllib", "classify", "${classname}.pm");
+
+	if (-e $customclassname) { require $customclassname; }
+	elsif (-e $colclassname) { require $colclassname; }
+	elsif (-e $mainclassname) { require $mainclassname; }
+	else { &gsprintf(STDERR, "{classify.could_not_find_classifier}\n", $classname) && die "\n";
+	       # die "ERROR - couldn't find classifier \"$classname\"\n";
+        }
+
+	# create the classify object
+	my ($classobj);
+
+	my @newoptions;
+
+	# do these first so they can be overriden by user supplied options
+	push @newoptions, "-builddir", "$build_dir" if ($build_dir);
+	push @newoptions, "-outhandle", "$outhandle" if ($outhandle);
+	push @newoptions, "-verbosity", "2";
+
+	# backwards compatability hack: if the classifier options are 
+	# in "x=y" format, convert them to parsearg ("-x y") format.
+	my ($opt, $key, $value);
+	foreach $opt (@$classifyoption) {
+	    # if ($opt =~ /^(\w+)=(.*)$/) {
+	    #	push @newoptions, "-$1", $2;
+	    # } else {
+		push @newoptions, $opt;
+	    #}
+	}
+
+	map { $_ = "\"$_\""; } @newoptions;
+	my $options .= join (",", @newoptions);
+
+
+	eval ("\$classobj = new \$classname([],[$options])");
+	die "$@" if $@;
+
+	$classobj->set_number($classify_number);
+	$classify_number ++;
+
+       	# add this object to the list
+	push (@classify_objects, $classobj);
+    }
+
+    my ($classobj);
+    eval ("\$classobj = new AllList()");
+    die "$@" if $@;
+    push (@classify_objects, $classobj);
+
+    return \@classify_objects;
+}
+
+# init_classifiers resets all the classifiers and readys them to process
+# the documents.
+sub init_classifiers {
+    my ($classifiers) = @_;
+    
+    foreach my $classobj (@$classifiers) {
+	$classobj->init();
+    }
+}
+
+
+
+# takes a hashref containing the metadata for an infodb entry, and extracts 
+# the childrens numbers (from the 'contains' entry).	
+# assumes format is ".1;".2;".3
+sub get_children {	
+    my ($doc_db_hash) = @_; 
+
+    my $children = undef;
+
+    my $contains = $doc_db_hash->{'contains'};
+    if (defined ($contains)) {
+	$contains =~ s/\@$//;  #remove trailing @
+	$contains =~ s/^\"\.//; #remove initial ".
+	@$children = split /\;\"\./, $contains;
+    }
+
+    return $children;
+}
+
+    
+sub recurse_sections {
+    my ($doc_obj, $children, $parentoid, $parentsection, $database_recs) = @_;
+
+    return if (!defined $children);
+
+    foreach my $child (sort { $a <=> $b} @$children) {
+	$doc_obj->create_named_section("$parentsection.$child");
+	my $doc_db_rec = $database_recs->{"$parentoid.$child"};
+	my $doc_db_hash = db_rec_to_hash($doc_db_rec);
+
+	# get child's children
+	my $newchildren = &get_children($doc_db_hash); 
+
+	# add content for current section
+	add_section_content($doc_obj, "$parentsection.$child", $doc_db_hash);
+
+	# process all the children if there are any
+	if (defined ($newchildren))
+	{
+	    recurse_sections($doc_obj, $newchildren, "$parentoid.$child", 
+			     "$parentsection.$child", $database_recs);
+	}
+    }
+}					     
+
+
+sub add_section_content {
+    my ($doc_obj, $cursection, $doc_db_hash) = @_;
+ 
+    foreach my $key (keys %$doc_db_hash) {
+	#don't need to store these metadata
+	next if $key =~ /(thistype|childtype|contains|docnum|doctype|classifytype)/i;
+	# but do want things like hastxt and archivedir
+	my @items = split /@/, $doc_db_hash->{$key};
+	# metadata is all from gdbm so should already be in utf8
+	map {$doc_obj->add_utf8_metadata ($cursection, $key, $_); } @items;
+
+    }
+}
+
+
+# gets all the metadata from an infodb entry, and puts it into a hashref
+sub db_rec_to_hash {
+    
+    my ($gdb_str_ref) = @_;
+
+    my $hashref = {};
+
+    my @entries = split(/\n/, $gdb_str_ref);
+    foreach my $entry (@entries) {
+	my($key, $value) = ($entry =~ /^<([^>]*)>(.*?)$/ );
+	$hashref->{$key} .= '@' if defined $hashref->{$key};
+	$hashref->{$key} .= $value;
+	
+    }
+   
+    return $hashref;
+}					  
+
+
+sub reconstruct_doc_objs_metadata
+{
+    my $infodb_type = shift(@_);
+    my $infodb_file_path = shift(@_);
+
+    my %database_recs;
+    &dbutil::read_infodb_file($infodb_type, $infodb_file_path, \%database_recs);
+
+    # dig out top level doc sections
+    my %top_sections = ();
+    my %top_docnums = ();
+    foreach my $key ( keys %database_recs )
+    {
+	my $md_rec = $database_recs{$key};
+	my $md_hash = db_rec_to_hash($md_rec);
+
+	if ((defined $md_hash->{'doctype'}) && ($md_hash->{'doctype'} eq "doc")) {
+	    next if ($key =~ m/\./);
+	    $top_sections{$key} = $md_hash;
+	    $top_docnums{$key} = $md_hash->{'docnum'};
+	}
+    }
+
+    # for greenstone document objects based on metadata in database file
+    my @all_docs = ();
+    # we need to make sure the documents were processed in the same order as
+    # before, so sort based on their docnums
+    foreach my $oid ( sort { $top_docnums{$a} <=> $top_docnums{$b} } keys %top_sections )
+    {
+	my $doc_db_hash = $top_sections{$oid};
+
+	my $doc_obj = new doc();
+	$doc_obj->set_OID($oid);
+	my $top = $doc_obj->get_top_section();
+        add_section_content ($doc_obj, $top, $doc_db_hash);
+        my $children = &get_children($doc_db_hash);
+        recurse_sections($doc_obj, $children, $oid, $top, \%database_recs);
+
+	push(@all_docs,$doc_obj);
+    }    
+
+    return \@all_docs;   
+}
+
+
+
+
+
+# classify_doc lets each of the classifiers classify a document
+sub classify_doc {
+    my ($classifiers, $doc_obj, $edit_mode) = @_;
+
+    foreach my $classobj (@$classifiers) {
+	my $title = $classobj->{'title'};
+
+	$classobj->classify($doc_obj,$edit_mode);
+    }
+}
+
+
+our $next_classify_num = 1;
+
+# output_classify_info outputs all the info needed for the classification
+# to the database
+sub output_classify_info
+{
+    my ($classifiers, $infodb_type, $infodb_handle, $remove_empty_classifications, $gli) = @_;
+
+    $gli = 0 unless defined $gli;
+
+    # create a classification containing all the info
+    my $classifyinfo = { 'classifyOID'=> 'browse',
+			 'contains' => [] };
+
+    # get each of the classifications
+    foreach my $classifier (@$classifiers)
+    {
+	my $classifier_info = $classifier->get_classify_info($gli);
+	$classifier_info->{'classifyOID'} = "CL$next_classify_num" unless defined($classifier_info->{'classifyOID'});
+        print STDERR "*** outputting information for classifier: $classifier_info->{'classifyOID'}\n";
+
+	push(@{$classifyinfo->{'contains'}}, $classifier_info);
+	$next_classify_num++;
+    }
+
+    &print_classify_info($infodb_type, $infodb_handle, $classifyinfo, "", $remove_empty_classifications);
+}
+
+
+sub print_classify_info
+{
+    my ($infodb_type, $infodb_handle, $classifyinfo, $OID, $remove_empty_classifications) = @_;
+
+    $OID =~ s/^\.+//; # just for good luck
+
+    # book information is printed elsewhere
+    return if (defined ($classifyinfo->{'OID'}));
+ 
+    # don't want empty classifications
+    return if (&check_contents ($classifyinfo, $remove_empty_classifications) == 0 && $remove_empty_classifications);
+   
+    $OID = $classifyinfo->{'classifyOID'} if defined ($classifyinfo->{'classifyOID'});
+
+    my %classify_infodb = ();
+    $classify_infodb{"doctype"} = [ "classify" ];
+    $classify_infodb{"hastxt"} = [ "0" ];
+    $classify_infodb{"childtype"} = [ $classifyinfo->{'childtype'} ]
+	if defined $classifyinfo->{'childtype'};
+    $classify_infodb{"Title"} = [ $classifyinfo->{'Title'} ]
+	if defined $classifyinfo->{'Title'};
+    $classify_infodb{"numleafdocs"} = [ $classifyinfo->{'numleafdocs'} ]
+	if defined $classifyinfo->{'numleafdocs'};
+    $classify_infodb{"thistype"} = [ $classifyinfo->{'thistype'} ]
+	if defined $classifyinfo->{'thistype'};
+    $classify_infodb{"parameters"} = [ $classifyinfo->{'parameters'} ]
+	if defined $classifyinfo->{'parameters'};
+    $classify_infodb{"supportsmemberof"} = [ $classifyinfo->{'supportsmemberof'} ]
+	if defined $classifyinfo->{'supportsmemberof'};
+    
+    my $contains_text = "";
+    my $mdoffset_text = "";
+    
+    my $next_subOID = 1;
+    my $first = 1;
+    foreach my $tempinfo (@{$classifyinfo->{'contains'}}) {
+	# empty contents were made undefined by clean_contents()
+	next unless defined $tempinfo;
+	
+	if (!defined ($tempinfo->{'classifyOID'}) ||
+	    $tempinfo->{'classifyOID'} ne "oai") {
+	    $contains_text .= ";" unless $first;
+	}
+	$mdoffset_text .= ";" unless $first;
+	$first = 0;
+	
+	if (defined ($tempinfo->{'classifyOID'}))
+	{
+	    if ($tempinfo->{'classifyOID'} ne "oai")
+	    {
+		$contains_text .= $tempinfo->{'classifyOID'};
+	    }
+
+	    &print_classify_info ($infodb_type, $infodb_handle, $tempinfo, $tempinfo->{'classifyOID'},
+				  $remove_empty_classifications);
+	}
+	elsif (defined ($tempinfo->{'OID'}))
+	{
+	    $contains_text .= $tempinfo->{'OID'};
+	    $mdoffset_text .= $tempinfo->{'offset'} if (defined ($tempinfo->{'offset'}));
+	}
+	else
+	{
+	    # Supress having top-level node in Collage classifier
+	    # so no bookshelf icon appears, top-level, along with the
+	    # applet
+	    if (!defined ($tempinfo->{'Title'}) || $tempinfo->{'Title'} ne "Collage")
+	    {
+		$contains_text .= "\".$next_subOID"; 
+	    }
+
+	    &print_classify_info ($infodb_type, $infodb_handle, $tempinfo, "$OID.$next_subOID",
+				  $remove_empty_classifications);
+	    $next_subOID++;
+	}
+    }
+    
+    $classify_infodb{"contains"} = [ $contains_text ];
+    $classify_infodb{"mdtype"} = [ $classifyinfo->{'mdtype'} ]
+	if defined $classifyinfo->{'mdtype'};
+    $classify_infodb{"mdoffset"} = [ $mdoffset_text ]
+	if ($mdoffset_text !~ m/^;+$/);
+    
+    &dbutil::write_infodb_entry($infodb_type, $infodb_handle, $OID, \%classify_infodb);
+}
+
+
+sub check_contents {
+    my ($classifyinfo,$remove_empty_classifications) = @_;
+    $remove_empty_classifications = 0 unless ($remove_empty_classifications);
+    my $num_leaf_docs = 0;
+    my $sub_num_leaf_docs = 0;
+
+    return $classifyinfo->{'numleafdocs'} if (defined $classifyinfo->{'numleafdocs'});
+
+    foreach my $content (@{$classifyinfo->{'contains'}}) {
+	if (defined $content->{'OID'}) {
+	    # found a book
+	    $num_leaf_docs ++;
+	} elsif (($sub_num_leaf_docs = &check_contents ($content,$remove_empty_classifications)) > 0) {
+	    # there's a book somewhere below
+	    $num_leaf_docs += $sub_num_leaf_docs;
+	} else {
+	    if ($remove_empty_classifications){
+		# section contains no books so we want to remove 
+		# it from its parents contents
+		$content = undef;
+	    }
+	}
+    }
+
+    $classifyinfo->{'numleafdocs'} = $num_leaf_docs;
+    return $num_leaf_docs;
+}
+
+1;
Index: /gsdl/stable/perllib/classify/AZCompactList.pm
===================================================================
--- /gsdl/stable/perllib/classify/AZCompactList.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/AZCompactList.pm	(revision 20131)
@@ -0,0 +1,833 @@
+###########################################################################
+#
+# AZCompactList.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+# classifier plugin for sorting alphabetically
+
+package AZCompactList;
+
+use BaseClassifier;
+use sorttools;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @AZCompactList::ISA = ('BaseClassifier');
+}
+
+my $doclevel_list = 
+    [ {	'name' => "top",
+ 	'desc' => "{AZCompactList.doclevel.top}" },
+      { 'name' => "section",
+	'desc' => "{AZCompactList.doclevel.section}" } ];
+
+my $arguments = 
+    [ { 'name' => "metadata",
+	'desc' => "{AZCompactList.metadata}",
+	'type' => "metadata",
+	'reqd' => "yes" },
+      { 'name' => "firstvalueonly",
+	'desc' => "{AZCompactList.firstvalueonly}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "allvalues",
+	'desc' => "{AZCompactList.allvalues}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "sort",
+	'desc' => "{AZCompactList.sort}",
+	'type' => "metadata",
+#	'deft' => "Title",
+	'reqd' => "no" },
+      { 'name' => "removeprefix",
+	'desc' => "{BasClas.removeprefix}",
+	'type' => "regexp",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "removesuffix",
+	'desc' => "{BasClas.removesuffix}",
+	'type' => "regexp",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "mingroup",
+	'desc' => "{AZCompactList.mingroup}",
+	'type' => "int",
+	'deft' => "1",
+	'range' => "1,",
+	'reqd' => "no" },
+      { 'name' => "minnesting",
+	'desc' => "{AZCompactList.minnesting}",
+	'type' => "int",
+	'deft' => "20",
+	'range' => "2,",
+	'reqd' => "no" },
+      { 'name' => "mincompact",
+	'desc' => "{AZCompactList.mincompact}",
+	'type' => "int",
+	'deft' => "10",
+	'range' => "1,",
+	'reqd' => "no" },
+      { 'name' => "maxcompact",
+	'desc' => "{AZCompactList.maxcompact}",
+	'type' => "int",
+	'deft' => "30",
+	'range' => "1,",
+	'reqd' => "no" },
+      { 'name' => "doclevel",
+	'desc' => "{AZCompactList.doclevel}",
+	'type' => "enum",
+	'list' => $doclevel_list,
+	'deft' => "top",
+	'reqd' => "no" },
+      { 'name' => "freqsort",
+	'desc' => "{AZCompactList.freqsort}",
+	'type' => "flag"},
+      { 'name' => "recopt",
+	'desc' => "{AZCompactList.recopt}",
+	'type' => "flag",
+	'reqd' => "no" } ];
+
+my $options = 
+{ 	'name'     => "AZCompactList",
+	'desc'     => "{AZCompactList.desc}",
+	'abstract' => "no",
+	'inherits' => "yes",
+	'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseClassifier($pluginlist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+    
+    if (!$self->{"metadata"}) {
+	my $outhandle = $self->{'outhandle'};
+	print $outhandle "AZCompactList Error: required option -metadata not supplied\n";
+	$self->print_txt_usage("");  
+	die "AZCompactList Error: required option -metadata not supplied\n";
+    }
+
+    # Manually set $self parameters.
+    $self->{'list'} = {};
+    $self->{'listmetavalue'} = {};
+    $self->{'list_mvpair'} = {};
+    $self->{'reclassify'} = {};
+    $self->{'reclassifylist'} = {};
+
+    $self->{'buttonname'} = $self->generate_title_from_metadata($self->{'metadata'}) unless ($self->{'buttonname'});
+    
+    if (defined($self->{"removeprefix"}) && $self->{"removeprefix"}) {
+	$self->{"removeprefix"} =~ s/^\^//; # don't need a leading ^
+    }
+    if (defined($self->{"removesuffix"}) && $self->{"removesuffix"}) {
+	$self->{"removesuffix"} =~ s/\$$//; # don't need a trailing $
+    }
+	
+    $self->{'recopt'} = ($self->{'recopt'} == 0) ? undef : "on";
+
+    # Clean out the unused keys
+    if($self->{"removeprefix"} eq "") {delete $self->{"removeprefix"};}
+    if($self->{"removesuffix"} eq "") {delete $self->{"removesuffix"};}
+
+    return bless $self, $class;
+}
+
+sub init 
+{
+    my $self = shift (@_);
+    
+    $self->{'list'} = {};
+    $self->{'listmetavalue'} = {};
+    $self->{'list_mvpair'} = {};
+    $self->{'reclassify'} = {};
+    $self->{'reclassifylist'} = {};
+}
+
+my $tmp = 0;
+
+sub classify
+{
+    my $self = shift (@_);
+    my ($doc_obj,$edit_mode) = @_;
+
+    my $doc_OID = $doc_obj->get_OID();
+    my $outhandle = $self->{'outhandle'};
+
+    my @sectionlist = ();
+    my $topsection = $doc_obj->get_top_section();
+    my $metaname = $self->{'metadata'};
+
+    $metaname =~ s/(\/|\|).*//; # grab first name in n1/n2/n3 or n1|n2|n3 list
+    my @commameta_list = split(/,|;/, $metaname);
+
+    if ($self->{'doclevel'} =~ /^top(level)?/i)
+    {
+	push(@sectionlist,$topsection);
+    }
+    else
+    {
+	my $thissection = $doc_obj->get_next_section($topsection);
+	while (defined $thissection) 
+	{
+	    push(@sectionlist,$thissection);
+	    $thissection = $doc_obj->get_next_section ($thissection);
+	}
+    }
+
+    my $thissection;
+    foreach $thissection (@sectionlist)
+    {
+	my $full_doc_OID 
+	    = ($thissection ne "") ? "$doc_OID.$thissection" : $doc_OID;
+
+	if (($edit_mode eq "delete") || ($edit_mode eq "update")) {
+	    print $outhandle "  Deleting $full_doc_OID\n";
+	    delete $self->{'list'}->{$full_doc_OID};
+	    delete $self->{'listmetavalue'}->{$full_doc_OID};
+	    delete $self->{'list_mvpair'}->{$full_doc_OID};
+	    delete $self->{'reclassify'}->{$full_doc_OID};
+
+	    next if ($edit_mode eq "delete");
+	}
+
+
+	if (defined $self->{'list_mvpair'}->{$full_doc_OID}) 
+	{
+	    print $outhandle "WARNING: AZCompactList::classify called multiple times for $full_doc_OID\n";
+	} 
+	$self->{'list'}->{$full_doc_OID} = [];	
+	$self->{'listmetavalue'}->{$full_doc_OID} = [];
+	$self->{'list_mvpair'}->{$full_doc_OID} = [];
+
+	my $metavalues = [];
+	foreach my $cmn (@commameta_list) {
+	    my $cmvalues = $doc_obj->get_metadata($thissection,$cmn);
+	    push(@$metavalues,@$cmvalues) if (@{$cmvalues});
+	    last if (@{$cmvalues} && !$self->{'allvalues'});
+	}
+
+	my $metavalue;
+	foreach $metavalue (@$metavalues) 
+	{
+	    # Tidy up use of white space in metavalue for classifying
+	    $metavalue =~ s/^\s*//s;
+	    $metavalue =~ s/\s*$//s;
+	    $metavalue =~ s/\n/ /s;
+	    $metavalue =~ s/\s{2,}/ /s;
+
+	    # if this document doesn't contain the metadata element we're
+	    # sorting by we won't include it in this classification
+	    if (defined $metavalue && $metavalue =~ /\w/) 
+	    {
+		if (defined($self->{'removeprefix'}) &&
+		    length($self->{'removeprefix'})) {
+		    $metavalue =~ s/^$self->{'removeprefix'}//;
+
+		    # check that it's not now empty
+		    if (!$metavalue) {next;}
+		}
+
+		if (defined($self->{'removesuffix'}) &&
+		    length($self->{'removesuffix'})) {
+		    $metavalue =~ s/$self->{'removesuffix'}$//;
+
+		    # check that it's not now empty
+		    if (!$metavalue) {next;}
+		}
+
+		my $formatted_metavalue;
+		if ($self->{'no_metadata_formatting'}) {
+		    $formatted_metavalue = $metavalue;
+		} else {
+		    $formatted_metavalue = &sorttools::format_metadata_for_sorting($self->{'metadata'},	 $metavalue, $doc_obj);
+		}
+		
+		#### prefix-str
+		if (! defined($formatted_metavalue)) {
+		    print $outhandle "Warning: AZCompactList: metavalue is ";
+		    print $outhandle "empty\n";
+		    $formatted_metavalue="";
+		}
+
+		my $mv_pair = { 'mv' => $metavalue, 'fmv' => $formatted_metavalue };
+		push(@{$self->{'list'}->{$full_doc_OID}},$formatted_metavalue);
+		push(@{$self->{'listmetavalue'}->{$full_doc_OID}} ,$metavalue);
+		push(@{$self->{'list_mvpair'}->{$full_doc_OID}},$mv_pair);
+
+
+		last if ($self->{'firstvalueonly'});
+	    }
+	}
+
+	# This is used in reclassify below for AZCompactSectionList
+	my $sortmeta = $doc_obj->get_metadata_element($thissection, $self->{'sort'});
+	$self->{'reclassify'}->{$full_doc_OID} = [$doc_obj,$sortmeta];
+    }
+}
+
+sub reinit 
+{
+    my ($self,$classlist_ref) = @_;
+    my $outhandle = $self->{'outhandle'};
+    
+    my %mtfreq = ();
+    my @single_classlist = ();
+    my @multiple_classlist = ();
+
+    # find out how often each metavalue occurs
+    map 
+    { 
+	foreach my $mvp (@{$self->{'list_mvpair'}->{$_}} )
+	{
+###	    print STDERR "*** plain mv = $mvp->{'mv'}\n";
+###	    print STDERR "*** format mv = $mvp->{'fmv'}\n";
+
+	    my $metavalue = $mvp->{'mv'};
+	    $metavalue =~ s!^-!\\-!; # in case it starts with "-"
+	    $mtfreq{$metavalue}++;
+	}
+    } @$classlist_ref;
+
+    # use this information to split the list: single metavalue/repeated value
+    map
+    { 
+	my $i = 1;
+	my $metavalue;
+	foreach my $mvp (@{$self->{'list_mvpair'}->{$_}})
+	{
+	    my $metavalue = $mvp->{'mv'};
+	    $metavalue =~ s!^-!\\-!; # in case it starts with "-"
+	    my $cs_metavalue = $mvp->{'mv'}; # case sensative
+	    if ($mtfreq{$metavalue} >= $self->{'mingroup'})
+	    {
+###		print STDERR "*** pushing on $cs_metavalue\n";
+		push(@multiple_classlist,[$_,$i,$metavalue]); 
+	    } 
+	    else
+	    {
+		push(@single_classlist,[$_,$cs_metavalue]); 
+		$metavalue =~ tr/[A-Z]/[a-z]/;
+		$self->{'reclassifylist'}->{"Metavalue_$i.$_"} = $metavalue;
+	    }
+	    $i++;
+	}
+    } @$classlist_ref;
+    
+    
+    # Setup sub-classifiers for multiple list
+
+    $self->{'classifiers'} = {};
+
+    my $pm;
+    foreach $pm ("SimpleList", "SectionList")
+    {
+	my $listname 
+	    = &util::filename_cat($ENV{'GSDLHOME'},"perllib/classify/$pm.pm");
+	if (-e $listname) { require $listname; }
+	else 
+	{ 
+	    print $outhandle "AZCompactList ERROR - couldn't find classifier \"$listname\"\n"; 
+	    die "\n";
+	}
+    }
+
+    # Create classifiers objects for each entry >= mingroup
+    my $metavalue;
+    my $doclevel = $self->{'doclevel'};
+    my $mingroup = $self->{'mingroup'};
+    my @metaname_list = split(/\/|\|/,$self->{'metadata'});
+    my $metaname = shift(@metaname_list);
+    my $hierarchical = 0;
+    if (scalar(@metaname_list) > 1) {
+	$hierarchical = 1;
+	$metaname = join('/',@metaname_list);
+    }
+    foreach $metavalue (keys %mtfreq)
+    {
+	if ($mtfreq{$metavalue} >= $mingroup)
+	{
+	    # occurs more often than minimum required to compact into a group
+	    my $listclassobj;
+	    
+	    if (!$hierarchical) 
+	    {	
+		my @args;
+		push @args, ("-metadata", "$metaname");
+		# buttonname is also used for the node's title
+		push @args, ("-buttonname", "$metavalue");
+		push @args, ("-sort", $self->{'sort'});
+
+		my $ptArgs = \@args;
+		if ($doclevel =~ m/^top(level)?/i)
+		{
+		    eval ("\$listclassobj = new SimpleList([],\$ptArgs)"); 
+		}
+		else
+		{
+		    eval ("\$listclassobj = new SectionList([],\$ptArgs)");
+		}
+	    }
+	    else
+	    {
+		
+		my @args;
+		push @args, ("-metadata", "$metaname");
+		# buttonname is also used for the node's title
+		push @args, ("-buttonname", "$metavalue");
+		push @args, ("-sort", $self->{'sort'});
+
+		if (defined $self->{'removeprefix'}) {
+		    push @args, ("-removeprefix", $self->{'removeprefix'});
+		}
+		if (defined $self->{'removesuffix'}) {
+		    push @args, ("-removesuffix", $self->{'removesuffix'});
+		}
+		
+		push @args, ("-doclevel", "$doclevel");
+		push @args, ("-mingroup", $mingroup);
+		push @args, "-recopt ";
+
+		my $ptArgs = \@args;
+		eval ("\$listclassobj = new AZCompactList([],\$ptArgs)");
+	    }
+	    
+	    if ($@) {
+		print $outhandle "$@";
+		die "\n";
+	    }
+	    
+	    $listclassobj->init();
+
+	    if (defined $metavalue && $metavalue =~ /\w/) 
+	    {
+		my $formatted_node = $metavalue;
+
+		if (defined($self->{'removeprefix'}) &&
+		    length($self->{'removeprefix'})) {
+		    $formatted_node =~ s/^$self->{'removeprefix'}//;
+		    # check that it's not now empty
+		    if (!$formatted_node) {next;}
+		}
+		if (defined($self->{'removesuffix'}) &&
+		    length($self->{'removesuffix'})) {
+		    $formatted_node =~ s/$self->{'removesuffix'}$//;
+		    # check that it's not now empty
+		    if (!$formatted_node) {next;}
+		}
+
+		$formatted_node = &sorttools::format_metadata_for_sorting($self->{'metadata'}, $formatted_node) unless $self->{'no_metadata_formatting'};
+
+		# In case our formatted string is empty...
+		if (! defined($formatted_node)) {
+		    print $outhandle "Warning: AZCompactList: metavalue is ";
+		    print $outhandle "empty\n";
+		    $formatted_node="";
+		}
+
+		# use the lower case, for speed of lookup.
+		my $meta_lc=lc($metavalue);
+		$self->{'classifiers'}->{$meta_lc}
+		= { 'classifyobj'   => $listclassobj,
+		    'formattednode' => $formatted_node };
+	    }
+	}
+    }
+
+
+    return (\@single_classlist,\@multiple_classlist);
+}
+
+
+sub reclassify 
+{
+    my ($self,$multiple_cl_ref) = @_;
+
+    # Entries in the current classify list that are "book nodes"
+    # should be recursively classified.
+    #--
+    foreach my $dm_pair (@$multiple_cl_ref) 
+    {
+	my ($doc_OID,$mdoffset,$metavalue,$cs_metavalue) = @$dm_pair;
+        my $listclassobj;
+
+	# find metavalue in list of sub-classifiers
+	# check if we have a key (lower case) for this metadata value
+	my $node_name=lc($metavalue);
+	if (exists $self->{'classifiers'}->{$node_name})
+	{
+	    my ($doc_obj, $sortmeta) = @{$self->{'reclassify'}->{$doc_OID}};
+
+	    # record the metadata value offset temporarily, so eg AZList can
+	    # get the correct metadata value (for multi-valued metadata fields)
+	    $doc_obj->{'mdoffset'}=$mdoffset;
+
+	    if ($doc_OID =~ m/^[^\.]*\.([\d\.]+)$/)
+	    {
+		my $section=$1;
+		if ($self->{'doclevel'} =~ m/^top/i) { # toplevel
+		    $self->{'classifiers'}->{$node_name}->{'classifyobj'}
+		    ->classify($doc_obj,"add", "Section=$section");
+		} else { # section level
+		    # Thanks to Don Gourley for this...
+		    # classify can't handle multi-level section
+		    $self->{'classifiers'}->{$node_name}->{'classifyobj'}
+		    ->classify_section($section, $doc_obj, "add", $sortmeta);
+		}
+	    }
+	    else
+	    {
+		$self->{'classifiers'}->{$node_name}->{'classifyobj'}
+		->classify($doc_obj,"add"); 
+	    }
+	} else { # this key is not in the hash
+	    my $outhandle=$self->{outhandle};
+	    print $outhandle "Warning: AZCompactList::reclassify ";
+	    print $outhandle "could not find sub-node for metadata=`$metavalue' with doc_OID $doc_OID\n";
+	}
+    }
+}
+
+
+
+sub get_reclassify_info 
+{
+    my $self = shift (@_);
+    
+    my $node_name;
+    foreach $node_name (keys %{$self->{'classifiers'}}) 
+    {
+        my $classifyinfo 
+	    = $self->{'classifiers'}->{$node_name}->{'classifyobj'}
+	        ->get_classify_info();
+        $self->{'classifiers'}->{$node_name}->{'classifyinfo'} 
+	    = $classifyinfo;
+        $self->{'reclassifylist'}->{"CLASSIFY.$node_name"} 
+	    = $self->{'classifiers'}->{$node_name}->{'formattednode'};
+    }
+}
+
+
+sub alpha_numeric_cmp
+{
+    my ($self,$a,$b) = @_;
+
+    my $title_a = $self->{'reclassifylist'}->{$a};
+    my $title_b = $self->{'reclassifylist'}->{$b};
+    
+    if ($title_a =~ m/^(\d+(\.\d+)?)/)
+    {
+	my $val_a = $1;
+	if ($title_b =~ m/^(\d+(\.\d+)?)/)
+	{
+	    my $val_b = $1;
+	    if ($val_a != $val_b)
+	    {
+		return ($val_a <=> $val_b);
+	    }
+	}
+    }
+    
+    return ($title_a cmp $title_b);
+}
+
+sub frequency_cmp
+{
+    my ($self,$a,$b) = @_;
+
+
+    my $title_a = $self->{'reclassifylist'}->{$a};
+    my $title_b = $self->{'reclassifylist'}->{$b};
+
+    my $a_freq = 1;
+    my $b_freq = 1;
+
+    if ($a =~ m/^CLASSIFY\.(.*)$/)
+    {
+	my $a_node = $1;
+	my $a_nodeinfo = $self->{'classifiers'}->{$a_node}->{'classifyinfo'};
+	$a_freq = scalar(@{$a_nodeinfo->{'contains'}});
+    }
+    
+    if ($b =~ m/^CLASSIFY\.(.*)$/)
+    {
+	my $b_node = $1;
+	my $b_nodeinfo = $self->{'classifiers'}->{$b_node}->{'classifyinfo'};
+	$b_freq = scalar(@{$b_nodeinfo->{'contains'}});
+    }
+
+    return $b_freq <=> $a_freq;
+}
+
+sub get_classify_info {
+    my $self = shift (@_);
+
+    my @classlist =keys %{$self->{'list_mvpair'}}; # list all doc oids
+
+    my ($single_cl_ref,$multiple_cl_ref) = $self->reinit(\@classlist);
+    $self->reclassify($multiple_cl_ref);
+    $self->get_reclassify_info();
+
+    my @reclassified_classlist;
+    if ($self->{'freqsort'})
+    {
+	@reclassified_classlist 
+	    = sort { $self->frequency_cmp($a,$b) } keys %{$self->{'reclassifylist'}};
+	# supress sub-grouping by alphabet
+	map { $self->{'reclassifylist'}->{$_} = "A".$self->{'reclassifylist'}; } keys %{$self->{'reclassifylist'}};
+    }
+    else
+    {
+#	@reclassified_classlist 
+#	    = sort {$self->{'reclassifylist'}->{$a} cmp $self->{'reclassifylist'}->{$b};} keys %{$self->{'reclassifylist'}};
+
+	# alpha_numeric_cmp is slower than "cmp" but handles numbers better ...
+
+	@reclassified_classlist
+	    = sort { $self->alpha_numeric_cmp($a,$b) } keys %{$self->{'reclassifylist'}};
+
+    }
+
+    return $self->splitlist (\@reclassified_classlist);
+}
+
+sub get_entry {
+    my $self = shift (@_);
+    my ($title, $childtype, $metaname, $thistype) = @_;
+    # organise into classification structure
+    my %classifyinfo = ('childtype'=>$childtype,
+                        'Title'=>$title,
+                        'contains'=>[],
+			'mdtype'=>$metaname);
+
+    $classifyinfo{'thistype'} = $thistype
+        if defined $thistype && $thistype =~ /\w/;
+
+    return \%classifyinfo;
+}
+
+
+
+# splitlist takes an ordered list of classifications (@$classlistref) and 
+# splits it up into alphabetical sub-sections.
+sub splitlist {
+    my $self = shift (@_);
+    my ($classlistref) = @_;
+    my $classhash = {};
+
+    # top level
+    my @metanames = split(/\/|\|/,$self->{'metadata'});
+    my $metaname = shift(@metanames);
+
+    my $childtype = "HList";
+    $childtype = "VList" if (scalar (@$classlistref) <= $self->{'minnesting'});
+
+    my $title = $self->{'buttonname'}; # should always be defined by now.
+    my $classifyinfo;
+    if (!defined($self->{'recopt'}))
+    {
+	$classifyinfo 
+	    = $self->get_entry ($title, $childtype, $metaname, "Invisible");
+    }
+    else
+    {
+	$classifyinfo 
+	    = $self->get_entry ($title, $childtype, $metaname, "VList");
+    }
+
+    # don't need to do any splitting if there are less than 'minnesting' classifications
+    if ((scalar @$classlistref) <= $self->{'minnesting'}) {
+	foreach my $subOID (@$classlistref) {
+            if ($subOID =~ /^CLASSIFY\.(.*)$/ 
+		&& defined $self->{'classifiers'}->{$1}) 
+	    {
+                push (@{$classifyinfo->{'contains'}}, 
+		      $self->{'classifiers'}->{$1}->{'classifyinfo'});
+            } 
+	    else 
+	    {
+		$subOID =~ s/^Metavalue_(\d+)\.//;
+		my $metaname_offset = $1 -1;
+		my $oid_rec = {'OID'=>$subOID, 'offset'=>$metaname_offset};
+		push (@{$classifyinfo->{'contains'}}, $oid_rec);
+	    }
+	}
+	return $classifyinfo;
+    }
+	
+    # first split up the list into separate A-Z and 0-9 classifications
+    foreach my $classification (@$classlistref) {
+	my $title = $self->{'reclassifylist'}->{$classification};
+	$title =~ s/&(.){2,4};//g; # remove any HTML special chars
+	$title =~ s/^\W+//g; # remove leading non-word chars
+
+	# only want first character for classification
+	$title =~ m/^(.)/; # always a char, or first byte of wide char?
+	if (defined($1) && $1 ne "") {
+	    $title=$1;
+	} else {
+	    print STDERR "no first character found for \"$title\" - \"" .
+		$self->{'reclassifylist'}->{$classification} . "\"\n";
+	}
+	$title =~ tr/[a-z]/[A-Z]/;
+
+	if ($title =~ /^[0-9]$/) {$title = '0-9';}
+	elsif ($title !~ /^[A-Z]$/) {
+	    my $outhandle = $self->{'outhandle'};
+	    print $outhandle "AZCompactList: WARNING $classification has badly formatted title ($title)\n";
+	}
+	$classhash->{$title} = [] unless defined $classhash->{$title};
+	push (@{$classhash->{$title}}, $classification);
+    }
+    $classhash = $self->compactlist ($classhash);
+
+    my @tmparr = ();
+    foreach my $subsection (sort keys (%$classhash)) {
+	push (@tmparr, $subsection);
+    }
+    
+    # if there's a 0-9 section it will have been sorted to the beginning
+    # but we want it at the end
+    if ($tmparr[0] eq '0-9') {
+	shift @tmparr;
+	push (@tmparr, '0-9');
+    }
+    foreach my $subclass (@tmparr) 
+    {
+	my $tempclassify 
+	    = (scalar(@tmparr)==1) 
+		? ($self->get_entry(" ", "VList", $metaname))
+		: ($self->get_entry($subclass, "VList", $metaname));
+
+
+	foreach my $subsubOID (@{$classhash->{$subclass}}) 
+	{
+            if ($subsubOID =~ /^CLASSIFY\.(.*)$/ 
+		&& defined $self->{'classifiers'}->{$1}) 
+	    {
+		# this is a "bookshelf" node... >1 entry compacted
+                push (@{$tempclassify->{'contains'}}, 
+		      $self->{'classifiers'}->{$1}->{'classifyinfo'});
+		# set the metadata field name, for mdoffset to work
+		$self->{'classifiers'}->{$1}->{'classifyinfo'}->{'mdtype'}=
+		    $metaname;
+	    }
+	    else
+	    {
+		$subsubOID =~ s/^Metavalue_(\d+)\.//;
+		# record the offset if this metadata type has multiple values
+		my $metaname_offset = $1 -1;
+		my $oid_rec = {'OID'=>$subsubOID, 'offset'=>$metaname_offset};
+		push (@{$tempclassify->{'contains'}}, $oid_rec);
+	    }
+	}
+	push (@{$classifyinfo->{'contains'}}, $tempclassify);
+    }
+
+    return $classifyinfo;
+}
+
+sub compactlist {
+    my $self = shift (@_);
+    my ($classhashref) = @_;
+    my $compactedhash = {};
+    my @currentOIDs = ();
+    my $currentfirstletter = "";
+    my $currentlastletter = "";
+    my $lastkey = "";
+
+    # minimum and maximum documents to be displayed per page.
+    # the actual maximum will be max + (min-1).
+    # the smallest sub-section is a single letter at present
+    # so in this case there may be many times max documents
+    # displayed on a page.
+    my $min = $self->{'mincompact'}; 
+    my $max = $self->{'maxcompact'};
+
+    foreach my $subsection (sort keys %$classhashref) {
+	if ($subsection eq '0-9') {
+	    @{$compactedhash->{$subsection}} = @{$classhashref->{$subsection}};
+	    next;
+	}
+	$currentfirstletter = $subsection if $currentfirstletter eq "";
+	if ((scalar (@currentOIDs) < $min) ||
+	    ((scalar (@currentOIDs) + scalar (@{$classhashref->{$subsection}})) <= $max)) {
+	    push (@currentOIDs, @{$classhashref->{$subsection}});
+	    $currentlastletter = $subsection;
+	} else {
+
+	    if ($currentfirstletter eq $currentlastletter) {
+		@{$compactedhash->{$currentfirstletter}} = @currentOIDs;
+		$lastkey = $currentfirstletter;
+	    } else {
+		@{$compactedhash->{"$currentfirstletter-$currentlastletter"}} = @currentOIDs;
+		$lastkey = "$currentfirstletter-$currentlastletter";
+	    } 
+	    if (scalar (@{$classhashref->{$subsection}}) >= $max) {
+		$compactedhash->{$subsection} = $classhashref->{$subsection};
+		@currentOIDs = ();
+		$currentfirstletter = "";
+		$lastkey=$subsection;
+	    } else {
+		@currentOIDs = @{$classhashref->{$subsection}};
+		$currentfirstletter = $subsection;
+		$currentlastletter = $subsection;
+	    }
+	}
+    }
+
+    # add final OIDs to last sub-classification if there aren't many otherwise
+    # add final sub-classification
+
+    # don't add if there aren't any oids
+    if (! scalar (@currentOIDs)) {return $compactedhash;}
+
+    if (scalar (@currentOIDs) < $min) {
+	my ($newkey) = $lastkey =~ /^(.)/;
+	@currentOIDs = (@{$compactedhash->{$lastkey}}, @currentOIDs);
+	delete $compactedhash->{$lastkey};
+	@{$compactedhash->{"$newkey-$currentlastletter"}} = @currentOIDs;
+    } else {
+	if ($currentfirstletter eq $currentlastletter) {
+	    @{$compactedhash->{$currentfirstletter}} = @currentOIDs;
+	} else {
+	    @{$compactedhash->{"$currentfirstletter-$currentlastletter"}} = @currentOIDs;
+	} 
+    }
+
+    return $compactedhash;
+}
+
+1;
+
+
Index: /gsdl/stable/perllib/classify/AZCompactSectionList.pm
===================================================================
--- /gsdl/stable/perllib/classify/AZCompactSectionList.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/AZCompactSectionList.pm	(revision 20131)
@@ -0,0 +1,234 @@
+###########################################################################
+#
+# AZCompactSectionList.pm --
+#
+# Experimental AZCompactList with fixes to handle section-level metadata
+#
+###########################################################################
+
+package AZCompactSectionList;
+
+use AZCompactList;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @AZCompactSectionList::ISA = ('AZCompactList');
+}
+
+my $arguments = [
+		 ];
+my $options = 
+{ 	'name'     => "AZCompactSectionList",
+	'desc'     => "{AZCompactSectionList.desc}",
+	'abstract' => "no",
+	'inherits' => "yes",
+	'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+    
+    my $self = new AZCompactList($classifierslist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+#
+# override reinit() & reclassify() to demonstrate possible bug fixes
+# (search for SECTIONFIX? to see lines changed from AZCompactList.pm)
+#
+sub reinit 
+{
+    my ($self,$classlist_ref) = @_;
+    
+    my %mtfreq = ();
+    my @single_classlist = ();
+    my @multiple_classlist = ();
+
+    # find out how often each metavalue occurs
+    map 
+    { 
+	my $mv;
+	foreach $mv (@{$self->{'listmetavalue'}->{$_}} )
+	{
+	    $mtfreq{$mv}++; 
+	}
+    } @$classlist_ref;
+
+    # use this information to split the list: single metavalue/repeated value
+    map
+    { 
+	my $i = 1;
+	my $metavalue;
+	foreach $metavalue (@{$self->{'listmetavalue'}->{$_}})
+	{
+	    if ($mtfreq{$metavalue} >= $self->{'mingroup'})
+	    {
+		push(@multiple_classlist,[$_,$i,$metavalue]); 
+	    } 
+	    else
+	    {
+		push(@single_classlist,[$_,$metavalue]); 
+		$metavalue =~ tr/[A-Z]/[a-z]/;
+		$self->{'reclassifylist'}->{"Metavalue_$i.$_"} = $metavalue;
+	    }
+	    $i++;
+	}
+    } @$classlist_ref;
+    
+    
+    # Setup sub-classifiers for multiple list
+
+    $self->{'classifiers'} = {};
+
+    my $pm;
+    foreach $pm ("SimpleList", "SectionList")
+    {
+	my $listname 
+	    = &util::filename_cat($ENV{'GSDLHOME'},"perllib/classify/$pm.pm");
+	if (-e $listname) { require $listname; }
+	else 
+	{ 
+	    my $outhandle = $self->{'outhandle'};
+	    print $outhandle "AZCompactList ERROR - couldn't find classifier \"$listname\"\n"; 
+	    die "\n";
+	}
+    }
+
+    # Create classifiers objects for each entry >= mingroup
+    my $metavalue;
+    foreach $metavalue (keys %mtfreq)
+    {
+	if ($mtfreq{$metavalue} >= $self->{'mingroup'})
+	{
+	    my $listclassobj;
+	    my $doclevel = $self->{'doclevel'};
+	    my $metaname  = $self->{'metaname'};
+	    my @metaname_list = split('/',$metaname);
+	    $metaname = shift(@metaname_list);
+	    if (@metaname_list==0)
+	    {
+		my @args;
+		push @args, ("-metadata", "$metaname");
+# buttonname is also used for the node's title
+		push @args, ("-buttonname", "$metavalue");
+		push @args, ("-sort", $self->{'sort'});
+
+		my $ptArgs = \@args;
+		if ($doclevel =~ m/^top(level)?/i)
+		{
+		    eval ("\$listclassobj = new SimpleList([],\$ptArgs)"); warn $@ if $@;
+		}
+		else
+		{
+		    # SECTIONFIX?
+		    #eval ("\$listclassobj = new SectionList($args)");
+		    eval ("\$listclassobj = new SectionList([],\$ptArgs)");
+		}
+	    }
+	    else
+	    {
+		$metaname = join('/',@metaname_list);
+		
+		my @args;
+		push @args, ("-metadata", "$metaname");
+# buttonname is also used for the node's title
+		push @args, ("-buttonname", "$metavalue");
+		push @args, ("-doclevel", "$doclevel");
+		push @args, "-recopt";
+
+		# SECTIONFIX?
+		#eval ("\$listclassobj = new AZCompactList($args)");
+		my $ptArgs = \@args;
+		eval ("\$listclassobj = new AZCompactList([],\$ptArgs)");
+	    }
+	    if ($@) {
+		my $outhandle = $self->{'outhandle'};
+		print $outhandle "$@";
+		die "\n";
+	    }
+	    
+	    $listclassobj->init();
+
+	    if (defined $metavalue && $metavalue =~ /\w/) 
+	    {
+		my $formatted_node = $metavalue;
+		if ($self->{'metaname'} =~ m/^Creator(:.*)?$/)
+		{
+		    &sorttools::format_string_name_en(\$formatted_node);
+		} 
+		else 
+		{
+		    &sorttools::format_string_en(\$formatted_node);
+		}
+		
+		$self->{'classifiers'}->{$metavalue} 
+		= { 'classifyobj'   => $listclassobj,
+		    'formattednode' => $formatted_node };
+	    }
+	}
+    }
+
+
+    return (\@single_classlist,\@multiple_classlist);
+}
+
+
+sub reclassify 
+{
+    my ($self,$multiple_cl_ref) = @_;
+
+    # Entries in the current classify list that are "book nodes"
+    # should be recursively classified.
+    #--
+    foreach my $dm_pair (@$multiple_cl_ref) 
+    {
+	my ($doc_OID,$mdoffset,$metavalue) = @$dm_pair;
+        my $listclassobj;
+
+	# find metavalue in list of sub-classifiers
+	my $found = 0;
+	my $node_name;
+	foreach $node_name (keys %{$self->{'classifiers'}}) 
+	{
+	    my $resafe_node_name = $node_name;
+	    $resafe_node_name =~ s/(\(|\)|\[|\]|\{|\}|\^|\$|\.|\+|\*|\?|\|)/\\$1/g;
+	    if ($metavalue =~ m/^$resafe_node_name$/i) 
+	    {
+		my ($doc_obj, $sortmeta) = @{$self->{'reclassify'}->{$doc_OID}};
+
+		# SECTIONFIX?  section must include multiple levels, e.g. '1.12'
+		#if ($doc_OID =~ m/^.*\.(\d+)$/)
+		if ($doc_OID =~ m/^[^\.]*\.([\d\.]+)$/)
+		{
+		    $self->{'classifiers'}->{$node_name}->{'classifyobj'}
+		    # SECTIONFIX? classify can't handle multi-level section
+		    #->classify($doc_obj, "Section=$1"); 
+		    ->classify_section($1, $doc_obj, $sortmeta);
+		}
+		else
+		{
+		    $self->{'classifiers'}->{$node_name}->{'classifyobj'}
+		    ->classify($doc_obj); 
+		}
+		
+		$found = 1;
+		last;
+	    }
+	}
+	
+	if (!$found)
+	{
+	    my $outhandle = $self->{'outhandle'};
+	    print $outhandle "Warning: AZCompactList::reclassify ";
+	    print $outhandle "could not find sub-node for $metavalue with doc_OID $doc_OID\n";
+	}
+    }
+}
+
+1;
Index: /gsdl/stable/perllib/classify/AZList.pm
===================================================================
--- /gsdl/stable/perllib/classify/AZList.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/AZList.pm	(revision 20131)
@@ -0,0 +1,367 @@
+###########################################################################
+#
+# AZList.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# classifier plugin for sorting alphabetically
+
+package AZList;
+
+use BaseClassifier;
+use sorttools;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @AZList::ISA = ('BaseClassifier');
+}
+
+
+my $arguments =
+    [ { 'name' => "metadata",
+	'desc' => "{AZList.metadata}",
+	'type' => "metadata",
+	'reqd' => "yes" } ,
+      { 'name' => "removeprefix",
+	'desc' => "{BasClas.removeprefix}",
+	'type' => "regexp",
+	'deft' => "",
+	'reqd' => "no" } ,
+      { 'name' => "removesuffix",
+	'desc' => "{BasClas.removesuffix}",
+	'type' => "regexp",
+	'deft' => "",
+	'reqd' => "no" } 
+      ];
+
+my $options = { 'name'     => "AZList",
+		'desc'     => "{AZList.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseClassifier($classifierslist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    if (!$self->{"metadata"}) {
+	print STDERR "AZList Error: required option -metadata not supplied \n";
+	$self->print_txt_usage("");  # Use default resource bundle
+	
+	die "AZList Error: required option -metadata not supplied\n";
+    }
+        
+    # Manually set $self parameters.
+    $self->{'list'} = {};
+
+    # Transfer value from Auto Parsing to the variable name that used in previous GreenStone.
+    my @meta_list = split(/,/, $self->{"metadata"});
+    $self->{'meta_list'} = \@meta_list;
+
+    $self->{'buttonname'} = $self->generate_title_from_metadata($self->{'metadata'}) unless ($self->{'buttonname'});
+
+    # Further setup 
+    if (defined($self->{"removeprefix"}) && $self->{"removeprefix"}) {
+	$self->{"removeprefix"} =~ s/^\^//; # don't need a leading ^
+    }
+    if (defined($self->{"removesuffix"}) && $self->{"removesuffix"}) {
+	$self->{"removesuffix"} =~ s/\$$//; # don't need a trailing $
+    }
+
+    # Clean out the unused keys
+    delete $self->{"metadata"}; # Delete this key
+
+    if($self->{"removeprefix"} eq "") {delete $self->{"removeprefix"};}
+    if($self->{"removesuffix"} eq "") {delete $self->{"removesuffix"};}
+
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+
+    $self->{'list'} = {};
+}
+
+sub classify {
+    my $self = shift (@_);
+    my ($doc_obj,$edit_mode) = @_;
+
+    my $doc_OID = $doc_obj->get_OID();
+    my $outhandle = $self->{'outhandle'};
+
+    if (($edit_mode eq "delete") || ($edit_mode eq "update")) {
+	$self->oid_hash_delete($doc_OID,'list');
+	return if ($edit_mode eq "delete");	    
+    }
+
+    my $metavalue;
+    my $metaname;
+    # should we extend this to use all available metadata not just the first?
+    if (!defined $self->{'meta_list'}) {
+	# just in case
+	return;
+    }
+
+    # find the first available metadata
+    foreach my $m (@{$self->{'meta_list'}}) {
+	$metavalue = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $m);
+	$metaname = $m;
+	last if defined $metavalue;
+    } 
+    
+    #if we haven't found a metavalue here, then the doc shouldn't be included
+    if (!defined $metavalue || $metavalue eq "") {
+	print $outhandle "WARNING: AZList: $doc_OID metadata is empty - not classifying\n";
+	return;
+    }
+
+    if (defined($self->{'removeprefix'}) &&
+	length($self->{'removeprefix'})) {
+	$metavalue =~ s/^$self->{'removeprefix'}//;
+    }
+    if (defined($self->{'removesuffix'}) &&
+	length($self->{'removesuffix'})) {
+	$metavalue =~ s/$self->{'removesuffix'}$//;
+    }
+    
+    
+    $metavalue = &sorttools::format_metadata_for_sorting($metaname, $metavalue, $doc_obj) unless $self->{'no_metadata_formatting'};
+	
+    if (defined $self->{'list'}->{$doc_OID}) {
+	print $outhandle "WARNING: AZList::classify called multiple times for $doc_OID\n";
+    } 
+    if ($metavalue) {
+	$self->{'list'}->{$doc_OID} = $metavalue;
+    } else {
+	# the formatting has made it empty
+	my $outhandle = $self->{'outhandle'};
+	print $outhandle "WARNING: AZList: $doc_OID metadata has become empty - not classifying\n";
+    }
+    
+}
+
+sub alpha_numeric_cmp
+{
+    my ($self,$a,$b) = @_;
+
+    my $title_a = $self->{'list'}->{$a};
+    my $title_b = $self->{'list'}->{$b};
+
+    if ($title_a =~ m/^(\d+(\.\d+)?)/)
+    {
+	my $val_a = $1;
+	if ($title_b =~ m/^(\d+(\.\d+)?)/)
+	{
+	    my $val_b = $1;
+	    if ($val_a != $val_b)
+	    {
+		return ($val_a <=> $val_b);
+	    }
+	}
+    }
+    
+    return ($title_a cmp $title_b);
+}
+
+sub get_classify_info {
+    my $self = shift (@_);
+
+    my @classlist 
+	= sort { $self->alpha_numeric_cmp($a,$b) } keys %{$self->{'list'}};
+
+    return $self->splitlist (\@classlist);
+}
+
+sub get_entry {
+    my $self = shift (@_);
+    my ($title, $childtype, $thistype) = @_;
+    
+    # organise into classification structure
+    my %classifyinfo = ('childtype'=>$childtype,
+			'Title'=>$title,
+			'contains'=>[]);
+    $classifyinfo{'thistype'} = $thistype 
+	if defined $thistype && $thistype =~ /\w/;
+
+    return \%classifyinfo;
+}
+
+# splitlist takes an ordered list of classifications (@$classlistref) and splits it
+# up into alphabetical sub-sections.
+sub splitlist {
+    my $self = shift (@_);
+    my ($classlistref) = @_;
+    my $classhash = {};
+
+    # top level
+    my $childtype = "HList";
+    if (scalar (@$classlistref) <= 39) {$childtype = "VList";}
+    my $classifyinfo = $self->get_entry ($self->{'buttonname'}, $childtype, "Invisible");
+
+    # don't need to do any splitting if there are less than 39 (max + min -1) classifications
+    if ((scalar @$classlistref) <= 39) {
+	foreach my $subOID (@$classlistref) {
+	    push (@{$classifyinfo->{'contains'}}, {'OID'=>$subOID});
+	}
+	return $classifyinfo;
+    }
+	
+    # first split up the list into separate A-Z and 0-9 classifications
+    foreach my $classification (@$classlistref) {
+	my $title = $self->{'list'}->{$classification};
+
+	$title =~ s/^(&.{1,6};|<[^>]>|[^a-zA-Z0-9])//g; # remove any unwanted stuff
+	# only need first char for classification
+	$title =~ m/^(.)/; $title=$1;
+	$title =~ tr/[a-z]/[A-Z]/;
+	if ($title =~ /^[0-9]$/) {$title = '0-9';}
+	elsif ($title !~ /^[A-Z]$/) {
+	    my $outhandle = $self->{'outhandle'};
+	    print $outhandle "AZList: WARNING $classification has badly formatted title ($title)\n";
+	}
+	$classhash->{$title} = [] unless defined $classhash->{$title};
+	push (@{$classhash->{$title}}, $classification);
+    }
+    $classhash = $self->compactlist ($classhash);
+
+    my @tmparr = ();
+    foreach my $subsection (sort keys (%$classhash)) {
+	push (@tmparr, $subsection);
+    }
+    #if there is only one entry here, we suppress the buckets
+    if ((scalar @tmparr) == 1) {
+	$classifyinfo->{'childtype'} = "VList";
+	foreach my $OID (@{$classhash->{$tmparr[0]}}) {
+	    push (@{$classifyinfo->{'contains'}}, {'OID'=>$OID});
+	}
+	return $classifyinfo;
+    }
+    
+    # if there's a 0-9 section it will have been sorted to the beginning
+    # but we want it at the end
+    if ($tmparr[0] eq '0-9') {
+	shift @tmparr;
+	push (@tmparr, '0-9');
+    }
+
+    foreach my $subclass (@tmparr) {
+	my $tempclassify = $self->get_entry($subclass, "VList");
+	foreach my $subsubOID (@{$classhash->{$subclass}}) {
+	    push (@{$tempclassify->{'contains'}}, {'OID'=>$subsubOID});
+	}
+	push (@{$classifyinfo->{'contains'}}, $tempclassify);
+    }
+
+    return $classifyinfo;
+}
+
+sub compactlist {
+    my $self = shift (@_);
+    my ($classhashref) = @_;
+    my $compactedhash = {};
+    my @currentOIDs = ();
+    my $currentfirstletter = "";  # start of working bin
+    my $currentlastletter = "";   # end of working bin
+    my $lastkey = "";             # the name of the last completed key
+
+    # minimum and maximum documents to be displayed per page.
+    # the actual maximum will be max + (min-1).
+    # the smallest sub-section is a single letter at present
+    # so in this case there may be many times max documents
+    # displayed on a page.
+    my $min = 10; 
+    my $max = 30;
+
+    foreach my $subsection (sort keys %$classhashref) {
+	if ($subsection eq '0-9') {
+	    # leave this bin as-is... copy it straight across
+	    @{$compactedhash->{$subsection}} = @{$classhashref->{$subsection}};
+	    next;
+	}
+	$currentfirstletter = $subsection if $currentfirstletter eq "";
+	if ((scalar (@currentOIDs) < $min) ||
+	    ((scalar (@currentOIDs) + scalar (@{$classhashref->{$subsection}})) <= $max)) {
+	    # add this letter to the bin and continue
+	    push (@currentOIDs, @{$classhashref->{$subsection}});
+	    $currentlastletter = $subsection;
+	} else {
+	    # too many or too few for a separate bin
+	    if ($currentfirstletter eq $currentlastletter) {
+		@{$compactedhash->{$currentfirstletter}} = @currentOIDs;
+		$lastkey = $currentfirstletter;
+	    } else {
+		@{$compactedhash->{"$currentfirstletter-$currentlastletter"}} = @currentOIDs;
+		$lastkey = "$currentfirstletter-$currentlastletter";
+	    } 
+	    if (scalar (@{$classhashref->{$subsection}}) >= $max) {
+		# this key is now complete. Start a new one
+		$compactedhash->{$subsection} = $classhashref->{$subsection};
+		@currentOIDs = ();
+		$currentfirstletter = "";
+		$lastkey = $subsection;
+	    } else {
+		@currentOIDs = @{$classhashref->{$subsection}};
+		$currentfirstletter = $subsection;
+		$currentlastletter = $subsection;
+	    }
+	}
+    }
+
+    # add final OIDs to last sub-classification if there aren't many otherwise
+    # add final sub-classification
+    # BUG FIX: don't add anything if there are no currentOIDs (thanks to Don Gourley)
+    if (! scalar(@currentOIDs)) {return $compactedhash;}
+
+    if (scalar (@currentOIDs) < $min) {
+	my ($newkey) = $lastkey =~ /^(.)/;
+	@currentOIDs = (@{$compactedhash->{$lastkey}}, @currentOIDs);
+	delete $compactedhash->{$lastkey};
+	@{$compactedhash->{"$newkey-$currentlastletter"}} = @currentOIDs;
+    } else {
+	if ($currentfirstletter eq $currentlastletter) {
+	    @{$compactedhash->{$currentfirstletter}} = @currentOIDs;
+	}
+	else {
+	    @{$compactedhash->{"$currentfirstletter-$currentlastletter"}} =
+		@currentOIDs;
+	}
+    }
+
+    return $compactedhash;
+}
+
+1;
Index: /gsdl/stable/perllib/classify/AZSectionList.pm
===================================================================
--- /gsdl/stable/perllib/classify/AZSectionList.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/AZSectionList.pm	(revision 20131)
@@ -0,0 +1,129 @@
+###########################################################################
+#
+# AZSectionList.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# classifier plugin for sorting sections alphabetically
+
+# this is very similar to AZList except it sorts by
+# section level metadata (excluding the top level)
+# instead of just top level metadata
+
+# the only change is to the classify() subroutine which 
+# must now iterate through each section, adding each
+# to the classification
+
+# 12/05/02 Added usage datastructure - John Thompson
+
+package AZSectionList;
+
+use AZList;
+use sorttools;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @AZSectionList::ISA = ('AZList');
+}
+
+my $arguments = [
+		 ];
+my $options = { 'name'     => "AZSectionList",
+		'desc'     => "{AZSectionList.desc}",
+		'abstract' => "no",
+		'inherits' => "yes" }; 
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new AZList($classifierslist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+sub classify {
+    my $self = shift (@_);
+    my ($doc_obj,$edit_mode) = @_;
+
+    my $doc_OID = $doc_obj->get_OID();
+    my $thissection = $doc_obj->get_next_section ($doc_obj->get_top_section());
+
+    while (defined $thissection) {
+	$self->classify_section ($thissection, $doc_obj, $edit_mode);
+	$thissection = $doc_obj->get_next_section ($thissection);
+    }
+}
+
+sub classify_section {
+    my $self = shift (@_);
+    my ($section, $doc_obj, $edit_mode) = @_;
+
+    my $doc_OID = $doc_obj->get_OID();
+
+    if ($edit_mode eq "delete") {
+	$self->oid_hash_delete("$doc_OID$section",'list');
+	return;
+    }
+
+    my $metavalue;
+    my $metaname;
+
+    if (!defined $self->{'meta_list'}) {
+	# just in case
+	return;
+    }
+
+    # find the first available metadata
+    foreach my $m (@{$self->{'meta_list'}}) {
+	$metavalue = $doc_obj->get_metadata_element($section, $m);
+	$metaname = $m;
+	last if defined $metavalue;
+    } 
+
+    # if this section doesn't contain the metadata element we're
+    # sorting by we won't include it in this classification
+
+    if (defined $metavalue && $metavalue ne "") {
+	if ($self->{'removeprefix'}) {
+	    $metavalue =~ s/^$self->{'removeprefix'}//;
+	}
+	
+	$metavalue = &sorttools::format_metadata_for_sorting($metaname, $metavalue, $doc_obj) unless $self->{'no_metadata_formatting'};
+	if (defined $self->{'list'}->{"$doc_OID.$section"}) {
+	    my $outhandle = $self->{'outhandle'};
+	    print $outhandle "WARNING: AZSectionList::classify called multiple times " .
+		"for $doc_OID.$section\n";
+	} 
+	$self->{'list'}->{"$doc_OID.$section"} = $metavalue;
+    }
+}
+
+
+1;
Index: /gsdl/stable/perllib/classify/AllList.pm
===================================================================
--- /gsdl/stable/perllib/classify/AllList.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/AllList.pm	(revision 20131)
@@ -0,0 +1,116 @@
+###########################################################################
+#
+# AllList.pm -- Creates a single list of all documents. Use by the oaiserver.
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2005 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package AllList;
+
+use BaseClassifier;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @AllList::ISA = ('BaseClassifier');
+}
+
+my $arguments = 
+    [
+     ];
+
+my $options = { 'name'     => "AllList",
+		'desc' => "{AllList.desc}",
+	        'abstract' => "yes", # hide from gli
+	        'inherits' => "yes" };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseClassifier($classifierslist, $inputargs, $hashArgOptLists);
+    
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    # Manually set $self parameters.
+    $self->{'list'} = [];
+    $self->{'buttonname'} = "All Documents";
+
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+}
+
+sub classify {
+    my $self = shift (@_);
+    my ($doc_obj, $edit_mode) = @_;
+
+    my $doc_OID = $doc_obj->get_OID();
+    
+    if ($edit_mode eq "delete") {
+	$self->oid_array_delete($doc_OID,'list');
+    }
+    else {
+	push (@{$self->{'list'}}, $doc_OID);
+    }
+
+    return;
+}
+
+sub get_classify_info {
+    my $self = shift(@_);
+    my ($no_thistype) = @_;
+
+    my %classifyinfo = ('childtype'   =>'VList',
+			'Title'       =>$self->{'buttonname'},
+			'contains'    =>[],
+			'classifyOID' =>"oai");
+    $classifyinfo{'thistype'} = 'Invisible';
+    my @list = @{$self->{'list'}};
+
+    my $seqNo = 0;
+    foreach my $OID (@list) {
+	my $hashref={};
+	$hashref->{'OID'}=$OID;
+       
+	my %tempinfo=('childtype'=>'VList',
+		      'Title'=>$self->{'buttonname'},
+		      'classifyOID' =>"oai.$seqNo",
+		      'contains'    =>[]);
+
+	push (@{$tempinfo{'contains'}}, $hashref);
+
+	push (@{$classifyinfo{'contains'}}, \%tempinfo);
+	$seqNo ++;
+    }
+
+    return \%classifyinfo;
+}
Index: /gsdl/stable/perllib/classify/BaseClassifier.pm
===================================================================
--- /gsdl/stable/perllib/classify/BaseClassifier.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/BaseClassifier.pm	(revision 20131)
@@ -0,0 +1,371 @@
+###########################################################################
+#
+# BaseClassifier.pm -- base class for all classifiers
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2000 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package BaseClassifier;
+
+# How a classifier works.  
+#
+# For each classifier requested in the collect.cfg file, buildcol.pl creates
+# a new classifier object (a subclass of BaseClassifier).  Later, it passes each 
+# document object to each classifier in turn for classification.
+#
+# Four primary functions are used:
+#
+# 1. "new" is called before the documents are processed to set up the
+#    classifier.
+#
+# 2. "init" is called after buildcol.pl has created the indexes etc but
+#    before the documents are classified in order that the classifier might
+#    set any variables it requires, etc.
+#
+# 3. "classify" is called once for each document object.  The classifier
+#    "classifies" each document and updates its local data accordingly.
+#
+# 4. "get_classify_info" is called after every document has been
+#    classified.  It collates the information about the documents and
+#    stores a reference to the classifier so that Greenstone can later
+#    display it.
+
+# 09/05/02 Added usage datastructure - John Thompson
+# 28/11/03 Commented out verbosity argument - John Thompson
+
+use gsprintf;
+use printusage;
+use parse2;
+
+# suppress the annoying "subroutine redefined" warning that various
+# classifiers cause under perl 5.6
+$SIG{__WARN__} = sub {warn($_[0]) unless ($_[0] =~ /Subroutine\s+\S+\sredefined/)};
+
+use strict;
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+my $arguments = 
+    [ 
+      { 'name' => "buttonname",
+  	'desc' => "{BasClas.buttonname}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "no_metadata_formatting",
+        'desc' => "{BasClas.no_metadata_formatting}",
+        'type' => "flag" },
+      { 'name' => "builddir",
+	'desc' => "{BasClas.builddir}",
+	'type' => "string",
+	'deft' => "" },
+      { 'name' => "outhandle",
+	'desc' => "{BasClas.outhandle}",
+	'type' => "string",
+	'deft' => "STDERR" },
+      { 'name' => "verbosity",
+	'desc' => "{BasClas.verbosity}",
+#	'type' => "enum",
+	'type' => "int",
+	'deft' => "2",
+	'reqd' => "no" }
+      
+#      { 'name' => "ignore_namespace",
+#	'desc' => "{BasClas.ignore_namespace}",
+#	'type' => "flag"} 
+      ];
+
+my $options = { 'name'     => "BaseClassifier",
+		'desc'     => "{BasClas.desc}",
+		'abstract' => "yes",
+		'inherits' => "no",
+		'args'     => $arguments };
+
+
+sub gsprintf
+{
+    return &gsprintf::gsprintf(@_);
+}
+
+
+sub print_xml_usage
+{
+    my $self = shift(@_);
+    my $header = shift(@_);
+    my $high_level_information_only = shift(@_);
+    
+    # XML output is always in UTF-8
+    &gsprintf::output_strings_in_UTF8;
+
+    if ($header) {
+	&PrintUsage::print_xml_header("classify");
+    }
+    $self->print_xml($high_level_information_only);
+}
+
+
+sub print_xml
+{
+    my $self = shift(@_);
+    my $high_level_information_only = shift(@_);
+
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $classifieroptions = shift(@$optionlistref);
+    return if (!defined($classifieroptions));
+
+    &gsprintf(STDERR, "<ClassInfo>\n");
+    &gsprintf(STDERR, "  <Name>$classifieroptions->{'name'}</Name>\n");
+    my $desc = &gsprintf::lookup_string($classifieroptions->{'desc'});
+    $desc =~ s/</&amp;lt;/g; # doubly escaped
+    $desc =~ s/>/&amp;gt;/g;
+    &gsprintf(STDERR, "  <Desc>$desc</Desc>\n");
+    &gsprintf(STDERR, "  <Abstract>$classifieroptions->{'abstract'}</Abstract>\n");
+    &gsprintf(STDERR, "  <Inherits>$classifieroptions->{'inherits'}</Inherits>\n");
+    unless (defined($high_level_information_only)) {
+	&gsprintf(STDERR, "  <Arguments>\n");
+	if (defined($classifieroptions->{'args'})) {
+	    &PrintUsage::print_options_xml($classifieroptions->{'args'});
+	}
+	&gsprintf(STDERR, "  </Arguments>\n");
+
+	# Recurse up the classifier hierarchy
+	$self->print_xml();
+    }
+    &gsprintf(STDERR, "</ClassInfo>\n");
+}
+
+
+sub print_txt_usage
+{
+    my $self = shift(@_);
+
+    # Print the usage message for a classifier (recursively)
+    my $descoffset = $self->determine_description_offset(0);
+    $self->print_classifier_usage($descoffset, 1);
+}
+
+
+sub determine_description_offset
+{
+    my $self = shift(@_);
+    my $maxoffset = shift(@_);
+
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $classifieroptions = pop(@$optionlistref);
+    return $maxoffset if (!defined($classifieroptions));
+
+    # Find the length of the longest option string of this classifier
+    my $classifierargs = $classifieroptions->{'args'};
+    if (defined($classifierargs)) {
+	my $longest = &PrintUsage::find_longest_option_string($classifierargs);
+	if ($longest > $maxoffset) {
+	    $maxoffset = $longest;
+	}
+    }
+
+    # Recurse up the classifier hierarchy
+    $maxoffset = $self->determine_description_offset($maxoffset);
+    $self->{'option_list'} = \@optionlist;
+    return $maxoffset;
+}
+
+
+sub print_classifier_usage
+{
+    my $self = shift(@_);
+    my $descoffset = shift(@_);
+    my $isleafclass = shift(@_);
+
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $classifieroptions = shift(@$optionlistref);
+    return if (!defined($classifieroptions));
+
+    my $classifiername = $classifieroptions->{'name'};
+    my $classifierargs = $classifieroptions->{'args'};
+    my $classifierdesc = $classifieroptions->{'desc'};
+    # Produce the usage information using the data structure above
+    if ($isleafclass) {
+	if (defined($classifierdesc)) {
+	    &gsprintf(STDERR, "$classifierdesc\n\n");
+	}
+	&gsprintf(STDERR, " {common.usage}: classify $classifiername [{common.options}]\n\n");
+	
+    }
+
+    # Display the classifier options, if there are some
+    if (defined($classifierargs)) {
+	# Calculate the column offset of the option descriptions
+	my $optiondescoffset = $descoffset + 2;  # 2 spaces between options & descriptions
+
+	if ($isleafclass) {
+	    &gsprintf(STDERR, " {common.specific_options}:\n");
+	}
+	else {
+	    &gsprintf(STDERR, " {common.general_options}:\n", $classifiername);
+	}
+
+	# Display the classifier options
+	&PrintUsage::print_options_txt($classifierargs, $optiondescoffset);
+    }
+
+    # Recurse up the classifier hierarchy
+    $self->print_classifier_usage($descoffset, 0);
+    $self->{'option_list'} = \@optionlist;
+}
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($classifierslist,$args,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+    my $classifier_name = (defined $classifierslist->[0]) ? $classifierslist->[0] : $class;
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+
+    # Manually set $self parameters.
+    my $self = {};
+    $self->{'outhandle'} = STDERR;
+    $self->{'idnum'} = -1;
+    $self->{'option_list'} = $hashArgOptLists->{"OptList"};
+    $self->{"info_only"} = 0;
+
+    # Check if gsdlinfo is in the argument list or not - if it is, don't parse 
+    # the args, just return the object.  
+    foreach my $strArg (@{$args})
+    {
+	if($strArg eq "-gsdlinfo")
+	{
+	    $self->{"info_only"} = 1;
+	    return bless $self, $class;
+	}
+    }
+
+    # general options available to all classifiers
+    if(parse2::parse($args,$hashArgOptLists->{"ArgList"},$self) == -1)
+    {
+	#print out the text usage of this classifier. 
+	my $classTempClass = bless $self, $class;
+	print STDERR "<BadClassifier c=$classifier_name>\n";
+
+	&gsprintf(STDERR, "\n{BasClas.bad_general_option}\n", $classifier_name);
+	$classTempClass->print_txt_usage("");  # Use default resource bundle
+	die "\n";
+    }
+    
+    delete $self->{"info_only"};
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+
+    $self->{'supportsmemberof'} = &supports_memberof();
+}
+
+sub set_number {
+    my $self = shift (@_);
+    my ($id)   = @_;
+    $self->{'idnum'} = $id;
+}
+
+sub get_number {
+    my $self = shift (@_);
+    return $self->{'idnum'};
+}
+
+sub oid_array_delete
+{
+    my $self = shift (@_);
+    my ($delete_oid,$field) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+
+    my @filtered_list = ();
+    foreach my $existing_oid (@{$self->{$field}}) {
+	if ($existing_oid eq $delete_oid) {
+	    print $outhandle "  Deleting old $delete_oid for ", ref $self, "\n";
+	}
+	else {
+	    push(@filtered_list,$existing_oid);
+	}
+    }
+    $self->{$field} = \@filtered_list;
+}
+
+sub oid_hash_delete
+{
+    my $self = shift (@_);
+    my ($delete_oid,$field) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+
+    print $outhandle "  Deleting old $delete_oid for ", ref $self, "\n";
+    delete $self->{$field}->{$delete_oid};
+}
+
+sub classify {
+    my $self = shift (@_);
+    my ($doc_obj, $edit_mode) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+    &gsprintf($outhandle, "BaseClassifier::classify {common.must_be_implemented}\n");
+}
+
+sub get_classify_info {
+    my $self = shift (@_);
+
+    my $outhandle = $self->{'outhandle'};
+    &gsprintf($outhandle, "BaseClassifier::get_classify_info {common.must_be_implemented}\n");
+}
+
+sub supports_memberof {
+    my $self = shift(@_);
+
+    return "false";
+}
+
+# previously, if a buttonname wasn't specified, we just use the metadata value,
+# but with a list of metadata, we want to do something a bit nicer so that
+# eg -metadata dc.Title,Title will end up with Title as the buttonname
+
+# current algorithm - use the first element, but strip its namespace
+sub generate_title_from_metadata {
+    
+    my $self = shift (@_);
+    my $metadata = shift (@_);
+
+    return "" unless defined $metadata && $metadata =~ /\S/;
+    
+    my @metalist = split(/,|;/, $metadata);
+    my $firstmeta = $metalist[0];
+    if ($firstmeta =~ /\./) {
+	$firstmeta =~ s/^\w+\.//;
+    }
+    return $firstmeta; 
+}
+
+1; 
Index: /gsdl/stable/perllib/classify/Browse.pm
===================================================================
--- /gsdl/stable/perllib/classify/Browse.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/Browse.pm	(revision 20131)
@@ -0,0 +1,99 @@
+###########################################################################
+#
+# Browse.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package Browse;
+
+use BaseClassifier;
+use sorttools;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @Browse::ISA = ('BaseClassifier');
+}
+
+my $arguments = [
+		 ];
+my $options = { 'name'     => "Browse",
+		'desc'     => "{Browse.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes" };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseClassifier($classifierslist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    # Manually set $self parameters.
+    $self->{'collection'} = $ENV{'GSDLCOLLECTION'}; # classifier information
+    $self->{'buttonname'} = "Browse";
+
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+
+    
+}
+
+sub classify {
+    my $self = shift (@_);
+   
+}
+
+sub get_classify_info {
+    my $self = shift (@_);
+  
+
+    # Return the information about the classifier that we'll later want to
+    # use to create macros when the Phind classifier document is displayed.
+    my %classifyinfo = ('thistype'=>'Invisible', 
+                        'Title'=>$self->{'buttonname'},
+			'contains'=>[]);
+    
+    my $collection = $self->{'collection'};
+    my $url = "library?a=br&c=collection";
+    push (@{$classifyinfo{'contains'}}, {'OID'=>$url});
+   
+    return \%classifyinfo;
+
+ 
+}
+
+
+1;
Index: /gsdl/stable/perllib/classify/Collage.pm
===================================================================
--- /gsdl/stable/perllib/classify/Collage.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/Collage.pm	(revision 20131)
@@ -0,0 +1,270 @@
+##########################################################################
+#
+# Collage.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package Collage;
+
+use BaseClassifier;
+use sorttools;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @Collage::ISA = ('BaseClassifier');
+}
+
+my $arguments = 
+    [ { 'name' => "buttonname",
+  	'desc' => "{Collage.buttonname}",
+	'type' => "string",
+	'deft' => "Collage",
+	'reqd' => "no" }, 
+      { 'name' => "geometry",
+  	'desc' => "{Collage.geometry}",
+	'type' => "string",
+	'deft' => "600x300",
+	'reqd' => "no" },
+      { 'name' => "verbosity",
+  	'desc' => "{BasClas.verbosity}",
+	'type' => "string",
+	'deft' => "5",
+	'reqd' => "no" },
+      { 'name' => "maxDepth",
+  	'desc' => "{Collage.maxDepth}",
+	'type' => "string",
+	'deft' => "500"},
+#      { 'name' => "maxDownloads",
+#  	'desc' => "{Collage.maxDownloads}",
+#	'type' => "string",
+#	'deft' => "",
+#	'reqd' => "no" },
+      { 'name' => "maxDisplay",
+  	'desc' => "{Collage.maxDisplay}",
+	'type' => "string",
+	'deft' => "25",
+	'reqd' => "no" },
+      { 'name' => "imageType",
+  	'desc' => "{Collage.imageType}",
+	'type' => "string",
+	'deft' => ".jpg%%.png",
+	'reqd' => "no" },
+      { 'name' => "bgcolor",
+  	'desc' => "{Collage.bgcolor}",
+	'type' => "string",
+	'deft' => "#96c29a",
+	'reqd' => "no" },
+      { 'name' => "refreshDelay",
+  	'desc' => "{Collage.refreshDelay}",
+	'type' => "string",
+	'deft' => "1500",
+	'reqd' => "no" },
+      { 'name' => "isJava2",
+  	'desc' => "{Collage.isJava2}",
+	'type' => "string",
+	'deft' => "auto",
+	'reqd' => "no" },
+      { 'name' => "imageMustNotHave",
+  	'desc' => "{Collage.imageMustNotHave}",
+	'type' => "string",
+	'deft' => "hl=%%x=%%gt=%%gc=%%.pr",
+	'reqd' => "no" },
+      { 'name' => "caption",
+  	'desc' => "{Collage.caption}",
+	'type' => "string",
+	'deft' => " ",
+	'reqd' => "no" }
+      ];
+
+
+
+
+my $options = { 'name'     => "Collage",
+		'desc'     => "{Collage.desc}",
+		'abstract' => "no",
+		'inherits' => "Yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseClassifier($classifierslist, $inputargs, $hashArgOptLists);
+    
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    # Manually set $self parameters.
+    $self->{'list'} = {};
+    $self->{'buttonname'} = 'Collage' unless ($self->{'buttonname'});
+
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+
+    $self->{'list'} = [];
+}
+
+sub classify {
+   
+    my $self = shift (@_);
+    my ($doc_obj,$edit_mode) = @_;
+
+    my $has_image_type = 0;
+
+    my @image_type_split = split(/%/,$self->{'imageType'});
+    my @image_type_ext = map { "($_)" } @image_type_split;
+    my $image_type_re = join("|",@image_type_ext);
+    $image_type_re =~ s/\./\\\./g;
+
+    my $assoc_files = $doc_obj->{'associated_files'};
+
+    foreach my $af ( @$assoc_files ) {
+	my ($real_filename, $assoc_filename, $mime_type, $section) = @$af;
+	if ($assoc_filename =~ m/$image_type_re/) {
+	    $has_image_type = 1;
+	    last;
+	}
+    }
+
+    if ($has_image_type) {
+
+	my $doc_OID = $doc_obj->get_OID();
+
+	if ($edit_mode eq "delete") {
+	    $self->oid_array_delete($doc_OID,'list');
+	}
+	else {
+	    push (@{$self->{'list'}}, $doc_OID);
+	}
+    }
+
+}
+
+sub get_classify_info {
+    my $self = shift (@_);
+    
+    my $items_per_page = 2; 
+    my $max_items_per_page = 20;
+
+    my @list      = @{$self->{'list'}};
+
+    my $outhandle = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+
+    if ($verbosity>1) {
+	print $outhandle ("$self->{'buttonname'}\n");
+    }
+
+    my $collage_head = $self->get_entry ($self->{'buttonname'}, "Collage", "Invisible");
+    my $collage_curr = $self->get_entry("Collage","VList");
+    push (@{$collage_head->{'contains'}},$collage_curr);
+
+    my $global_c=1;
+    my $within_page_c=1;
+
+    foreach my $oid (@list) {
+	if ($within_page_c>$items_per_page) {
+	    my $title = "Items $global_c+";
+	    my $nested_node = $self->get_entry($title,"VList");
+	    push (@{$collage_curr->{'contains'}}, $nested_node);
+	    $collage_curr = $nested_node;
+
+	    $within_page_c=1;
+	    
+	    $items_per_page++ if ($items_per_page < $max_items_per_page);
+	}
+
+	push (@{$collage_curr->{'contains'}}, {'OID'=>$oid});
+	$global_c++;
+	$within_page_c++;
+    }
+   
+    return $collage_head;
+}
+
+
+sub get_entry {
+    my $self = shift (@_);
+    my ($title, $childtype, $thistype) = @_;
+
+    # organise into classification structure
+    my %classifyinfo = ('childtype'=>$childtype,
+			'Title'=>$title,
+			'contains'=>[]);
+
+    $classifyinfo{'thistype'} = $thistype if (defined $thistype);
+
+    if ($childtype eq "Collage") {
+	my $geometry = $self->{'geometry'};
+	my ($x_dim,$y_dim) = ($geometry =~ m/^(.*)x(.*)$/);
+	my $verbosity = $self->{'verbosity'};
+	my $maxDepth = $self->{'maxDepth'};
+#	my $maxDownloads = $self->{'maxDownloads'};
+	my $maxDisplay = $self->{'maxDisplay'};
+	my $imageType = $self->{'imageType'};
+	my $bgcolor = $self->{'bgcolor'};
+	my $refreshDelay = $self->{'refreshDelay'};
+	my $isJava2 = $self->{'isJava2'};
+	my $imageMustNotHave = $self->{'imageMustNotHave'};
+	my $caption = $self->{'caption'};
+	
+	#if (!defined($maxDownloads)) {
+	#    $maxDownloads="";
+	#}
+
+	my $parameters;
+
+	$parameters = "xdim=".$x_dim;
+	$parameters .= ";ydim=".$y_dim;
+	$parameters .= ";geometry=".$self->{'geometry'};
+	$parameters .= ";verbosity=".$self->{'verbosity'};
+	$parameters .= ";maxDepth=".$self->{'maxDepth'};
+#	$parameters .= ";maxDownloads=".$maxDownloads;
+	$parameters .= ";maxDisplay=".$self->{'maxDisplay'};
+	$parameters .= ";imageType=".$self->{'imageType'};
+	$parameters .= ";bgcolor=".$self->{'bgcolor'};
+	$parameters .= ";refreshDelay=".$self->{'refreshDelay'};
+	$parameters .= ";isJava2=".$self->{'isJava2'};
+	$parameters .= ";caption=".$self->{'caption'};
+
+#	$parameters .= ";imageMustNotHave=".$self->{'imageMustNotHave'};
+
+    
+	$classifyinfo{'parameters'} = $parameters;
+    }
+
+    return \%classifyinfo;
+}
+
+1;
Index: /gsdl/stable/perllib/classify/DateList.pm
===================================================================
--- /gsdl/stable/perllib/classify/DateList.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/DateList.pm	(revision 20131)
@@ -0,0 +1,413 @@
+###########################################################################
+#
+# DateList.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# classifier plugin for sorting by date
+
+# date is assumed to be in the form yyyymmdd
+
+# at present dates are split by year - this should change
+# jrm21 - added option "bymonth", which splits by year and month.
+
+# 23/09/03 Added some more options -kjdon.
+# these include:
+# -nogroup, which makes each year (or year+month) an individual entry in 
+# the horizontal list and prevents compaction
+# -metadata, use a different metadata for the date (instead of Date), still expects yyyymmdd format. this affects display cos greenstone displays Date metadata as dd month yyyy, whereas any other date metadata is displayed as yyyymmdd - this needs fixing
+# -sort specifies an additional metadata to use in sorting, will take affect when two docs have the same date.
+
+package DateList;
+
+use BaseClassifier;
+use sorttools;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @DateList::ISA = ('BaseClassifier');
+}
+
+my $arguments =
+    [ { 'name' => "metadata",
+        'desc' => "{DateList.metadata}",
+        'type' => "metadata",
+	'deft' => "Date",
+        'reqd' => "yes" } ,
+      { 'name' => "sort",
+        'desc' => "{DateList.sort}",
+        'type' => "metadata",
+	'reqd' => "no" } ,
+      { 'name' => "reverse_sort",
+	'desc' => "{DateList.reverse_sort}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "bymonth",
+	'desc' => "{DateList.bymonth}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "nogroup",
+	'desc' => "{DateList.nogroup}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "no_special_formatting",
+	'desc' => "{DateList.no_special_formatting}",
+	'type' => "flag",
+	'reqd' => "no" }
+      
+      ];
+
+my $options = { 'name'     => "DateList",
+		'desc'     => "{DateList.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseClassifier($classifierslist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    # Manually set $self parameters.
+    $self->{'list'} = {};
+
+    if (!defined $self->{"metadata"} || $self->{"metadata"} eq "") {
+	$self->{'metadata'} = "Date";
+    }
+    # now can have comma separated list of Dates - we just use the first one (for now)
+    my @meta_list = split(/,/, $self->{"metadata"});
+    $self->{'meta_list'} = \@meta_list;
+ 
+    $self->{'buttonname'} = $self->generate_title_from_metadata($self->{'metadata'}) unless ($self->{'buttonname'});
+
+    $self->{'childtype'} = "DateList";
+    if ($self->{'no_special_formatting'}) {
+	$self->{'childtype'} = "VList";
+    }
+    
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+
+    $self->{'list'} = {};
+}
+
+sub classify {
+    my $self = shift (@_);
+    my ($doc_obj, $edit_mode) = @_;
+
+    my $doc_OID = $doc_obj->get_OID();
+
+    # find the first available metadata
+    my $date;
+    foreach my $m (@{$self->{'meta_list'}}) {
+	$date = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $m);
+	last if defined $date;
+    } 
+    
+    #my $date = $doc_obj->get_metadata_element ($doc_obj->get_top_section(), $self->{'metadata'});
+    if (!defined $date || $date eq "") {
+	# if this document doesn't contain Date element we won't 
+	# include it in this classification
+	return;
+    }
+    
+    if (($edit_mode eq "delete") || ($edit_mode eq "update")) {
+	$self->oid_hash_delete($doc_OID,'list');
+	return if ($edit_mode eq "delete");
+    }
+
+    my $sort_other = "";
+    if (defined $self->{'sort'} && $self->{'sort'} ne "") {
+	$sort_other = $doc_obj->get_metadata_element ($doc_obj->get_top_section(), $self->{'sort'});
+	$sort_other = &sorttools::format_metadata_for_sorting($self->{'sort'}, $sort_other, $doc_obj) unless $self->{'no_metadata_formatting'};
+    }
+    
+    if (defined $self->{'list'}->{$doc_OID}) {
+	my $outhandle = $self->{'outhandle'};
+	print $outhandle "WARNING: DateList::classify called multiple times for $doc_OID\n";
+    } 
+   
+     
+    $self->{'list'}->{$doc_OID} = "$date$sort_other";
+
+}
+
+
+sub get_classify_info {
+    my $self = shift (@_);
+
+    my @classlist = sort {$self->{'list'}->{$a} cmp $self->{'list'}->{$b};} keys %{$self->{'list'}};
+
+    if ($self->{'reverse_sort'}) {
+	@classlist = reverse @classlist;
+    }
+
+
+    return $self->splitlist (\@classlist);
+}
+
+
+sub get_entry {
+    my $self = shift (@_);
+    my ($title, $childtype, $thistype) = @_;
+    
+    # organise into classification structure
+    my %classifyinfo = ('childtype'=>$childtype,
+			'Title'=>$title,
+			'contains'=>[],
+			'mdtype'=>$self->{'metadata'});
+    $classifyinfo{'thistype'} = $thistype 
+	if defined $thistype && $thistype =~ /\w/;
+
+    return \%classifyinfo;
+}
+
+# splitlist takes an ordered list of classifications (@$classlistref) and
+# splits it up into sub-sections by date
+sub splitlist {
+    my $self = shift (@_);
+    my ($classlistref) = @_;
+    my $classhash = {};
+
+    # top level
+    my $childtype = "HList";
+
+    if (scalar (@$classlistref) <= 39 &&
+	!$self->{'nogroup'}) {$childtype = $self->{'childtype'};}
+
+    my $classifyinfo = $self->get_entry ($self->{'buttonname'}, $childtype, "Invisible");
+    # don't need to do any splitting if there are less than 39 (max + min -1)
+    # classifications, unless nogroup is specified
+    if ((scalar @$classlistref) <= 39 && !$self->{'nogroup'}) {
+	foreach my $subOID (@$classlistref) {
+	    push (@{$classifyinfo->{'contains'}}, {'OID'=>$subOID});
+	}
+	return $classifyinfo;
+    }
+
+
+    if ($self->{'bymonth'}) {
+	# first split up the list into separate year+month classifications
+
+	if (!$self->{'nogroup'}) { # hlist of year+month pairs
+	    # single level of classifications
+	    foreach my $classification (@$classlistref) {
+		my $date = $self->{'list'}->{$classification};
+		$date =~ s/^(\d\d\d\d)-?(\d\d).*$/$1&nbsp;_textmonth$2_/;
+		# sanity check if month is zero
+		if ($date =~ /00_$/) {
+		    $date =~ s/^(\d\d\d\d).*$/$1/g;
+		}
+		$classhash->{$date} = [] unless defined $classhash->{$date};
+		push (@{$classhash->{$date}}, $classification);
+	    }
+	    
+	} else { # don't group - individual years and months
+	    foreach my $classification (@$classlistref) {
+		my $date = $self->{'list'}->{$classification};
+		$date =~ s/^(\d\d\d\d)-?(\d\d).*$/$1&nbsp;_textmonth$2_/;
+		my ($year, $month)=($1,$2);
+		# sanity check if month is zero
+		if ($date =~ /00_$/) {
+		    $date =~ s/^(\d\d\d\d).*$/$1/g;
+		}
+		# create subclass if it doesn't already exist
+		$classhash->{$year} = () unless defined $classhash->{$year};
+	          
+		$classhash->{$year}->{$month} = []
+		    unless defined $classhash->{$year}->{$month};
+		push (@{$classhash->{$year}->{$month}}, $classification);
+
+	    }
+	    # create hlist of years containing hlists of months
+
+	    
+	    if ($self->{'reverse_sort'}){
+               foreach my $subclass (sort {$b <=> $a} 
+				    (keys %$classhash)){
+		  my $yearclassify = $self->get_entry($subclass, "HList");
+		  foreach my $subsubclass (sort {$b <=> $a} 
+					   (keys %{$classhash->{$subclass}})) {
+		      my $monthname=$subsubclass;
+		      if ($monthname >= 1 && $monthname <= 12) {
+			  $monthname="_textmonth" . $monthname . "_";
+		      }
+		      my $monthclassify=$self->get_entry($monthname, $self->{'childtype'});
+		      push (@{$yearclassify->{'contains'}}, $monthclassify);
+		      
+		      foreach my $subsubOID 
+			  (@{$classhash->{$subclass}->{$subsubclass}}) {
+			      push (@{$monthclassify->{'contains'}},
+				  {'OID'=>$subsubOID});
+			  }
+		  }
+		  push (@{$classifyinfo->{'contains'}}, $yearclassify);
+	      }
+	    }
+	    else{
+		foreach my $subclass (sort {$a <=> $b} 
+				    (keys %$classhash)){
+		    my $yearclassify = $self->get_entry($subclass, "HList");
+		    foreach my $subsubclass (sort {$a <=> $b} 
+					     (keys %{$classhash->{$subclass}})) {
+		      my $monthname=$subsubclass;
+		      if ($monthname >= 1 && $monthname <= 12) {
+			  $monthname="_textmonth" . $monthname . "_";
+		      }
+		      my $monthclassify=$self->get_entry($monthname, $self->{'childtype'});
+		      push (@{$yearclassify->{'contains'}}, $monthclassify);
+		      
+		      foreach my $subsubOID 
+			  (@{$classhash->{$subclass}->{$subsubclass}}) {
+			      push (@{$monthclassify->{'contains'}},
+				    {'OID'=>$subsubOID});
+			  }
+		  }
+		    push (@{$classifyinfo->{'contains'}}, $yearclassify);
+		}
+		
+		
+	    }
+	    
+	    return $classifyinfo;
+	} # nogroup
+    }else {
+	# not by month
+	# first split up the list into separate year classifications
+	foreach my $classification (@$classlistref) {
+	    my $date = $self->{'list'}->{$classification};
+	    $date =~ s/^(\d\d\d\d).*$/$1/;
+	    $classhash->{$date} = [] unless defined $classhash->{$date};
+	    push (@{$classhash->{$date}}, $classification);
+	}
+          
+    }
+    
+    # only compact the list if nogroup not specified
+    if (!$self->{'nogroup'}) {
+	$classhash = $self->compactlist ($classhash);
+    }
+
+    if ($self->{'reverse_sort'} && $self->{'nogroup'} ) {
+ 	foreach my $subclass (reverse sort keys %$classhash) {
+	    my $tempclassify = $self->get_entry($subclass, $self->{'childtype'});
+	    foreach my $subsubOID (@{$classhash->{$subclass}}) {
+		push (@{$tempclassify->{'contains'}}, {'OID'=>$subsubOID});
+	    }
+	    push (@{$classifyinfo->{'contains'}}, $tempclassify);
+	}
+    }
+    else{
+	foreach my $subclass (sort keys %$classhash) {
+	    my $tempclassify = $self->get_entry($subclass, $self->{'childtype'});
+	    foreach my $subsubOID (@{$classhash->{$subclass}}) {
+		push (@{$tempclassify->{'contains'}}, {'OID'=>$subsubOID});
+	    }
+	    push (@{$classifyinfo->{'contains'}}, $tempclassify);
+	}
+
+    }
+    
+  
+    return $classifyinfo;
+}
+
+sub compactlist {
+    my $self = shift (@_);
+    my ($classhashref) = @_;
+    my $compactedhash = {};
+    my @currentOIDs = ();
+    my $currentfirstdate = "";
+    my $currentlastdate = "";
+    my $lastkey = "";
+
+    # minimum and maximum documents to be displayed per page.
+    # the actual maximum will be max + (min-1).
+    # the smallest sub-section is a single letter at present
+    # so in this case there may be many times max documents
+    # displayed on a page.
+    my $min = 10; 
+    my $max = 30;
+    foreach my $subsection (sort keys %$classhashref) {
+	$currentfirstdate = $subsection if $currentfirstdate eq "";
+	if ((scalar (@currentOIDs) < $min) ||
+	    ((scalar (@currentOIDs) + scalar (@{$classhashref->{$subsection}})) <= $max)) {
+	    push (@currentOIDs, @{$classhashref->{$subsection}});
+	    $currentlastdate = $subsection;
+	} else {
+
+	    if ($currentfirstdate eq $currentlastdate) {
+		@{$compactedhash->{$currentfirstdate}} = @currentOIDs;
+		$lastkey = $currentfirstdate;
+	    } else {
+		@{$compactedhash->{"$currentfirstdate-$currentlastdate"}} = @currentOIDs;
+		$lastkey = "$currentfirstdate-$currentlastdate";
+	    } 
+	    if (scalar (@{$classhashref->{$subsection}}) >= $max) {
+		$compactedhash->{$subsection} = $classhashref->{$subsection};
+		@currentOIDs = ();
+		$currentfirstdate = "";
+		$lastkey = $subsection;
+	    } else {
+		@currentOIDs = @{$classhashref->{$subsection}};
+		$currentfirstdate = $subsection;
+		$currentlastdate = $subsection;
+	    }
+	}
+    }
+
+    # add final OIDs to last sub-classification if there aren't many otherwise
+    # add final sub-classification
+    if ((scalar (@currentOIDs) < $min) && (scalar (@currentOIDs) > 0)) {
+	# want every thing in previous up to the dash
+	my ($newkey) = $lastkey =~ /^([^\-]+)/;
+	@currentOIDs = (@{$compactedhash->{$lastkey}}, @currentOIDs);
+	delete $compactedhash->{$lastkey};
+	@{$compactedhash->{"$newkey-$currentlastdate"}} = @currentOIDs;	
+    } else {
+	if ($currentfirstdate eq $currentlastdate) {
+	    @{$compactedhash->{$currentfirstdate}} = @currentOIDs;
+	} else {
+	    @{$compactedhash->{"$currentfirstdate-$currentlastdate"}} = @currentOIDs;
+	} 
+    }
+
+    return $compactedhash;
+}
+
+1;
Index: /gsdl/stable/perllib/classify/HFileHierarchy.pm
===================================================================
--- /gsdl/stable/perllib/classify/HFileHierarchy.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/HFileHierarchy.pm	(revision 20131)
@@ -0,0 +1,344 @@
+###########################################################################
+#
+# HFileHierarchy.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# classifier plugin for generating hierarchical classifications
+
+
+package HFileHierarchy;
+
+use BaseClassifier;
+use util;
+use cfgread;
+use sorttools;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @HFileHierarchy::ISA = ('BaseClassifier');
+}
+
+my $arguments =
+    [ { 'name' => "metadata",
+	'desc' => "{AZCompactList.metadata}",
+	'type' => "metadata",
+	'reqd' => "yes" },
+      { 'name' => "firstvalueonly",
+	'desc' => "{AZCompactList.firstvalueonly}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "allvalues",
+	'desc' => "{AZCompactList.allvalues}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "hfile",
+	'desc' => "{Hierarchy.hfile}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "sort",
+	'desc' => "{Hierarchy.sort}",
+	'type' => "metadata",
+	'reqd' => "no" },
+      { 'name' => "reverse_sort",
+	'desc' => "{Hierarchy.reverse_sort}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "hlist_at_top",
+	'desc' => "{Hierarchy.hlist_at_top}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "documents_last",
+	'desc' => "{Hierarchy.documents_last}",
+	'type' => "flag",
+	'reqd' => "no"}
+      ];
+
+my $options = 
+{ 	'name'     => "HFileHierarchy",
+	'desc'     => "{HFileHierarchy.desc}",
+	'abstract' => "yes",
+	'inherits' => "yes", 
+	'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseClassifier($classifierslist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    my $metadata = $self->{'metadata'};
+    if (!$metadata) {
+	print STDERR "$class Error: required option -metadata not supplied\n";
+	$self->print_txt_usage("");  # Use default resource bundle
+	
+	die "$class Error: required option -metadata not supplied\n";
+    }
+    
+    $self->{'buttonname'} = $self->generate_title_from_metadata($metadata) unless ($self->{'buttonname'});
+
+    #$self->{'metaname'} = $metadata;
+    my @meta_list = split(/,/, $metadata);
+    $self->{'meta_list'} = \@meta_list;
+
+    # sort = undef in this case is the same as sort=nosort
+    if ($self->{'sort'} eq "nosort") {
+	$self->{'sort'} = undef;
+    }
+
+    # sortname is handled a bit differently - kjdon
+    # undef means to sort, but use the metadata value from -metadata
+    # because there is no one metadata value to get for sorting when 
+    # we have a list of possible metadata.
+    # To get no sorting, set sortname = 'nosort'
+    # we don't need to set it to undef if its not defined do we???
+
+#    if (!$self->{'sort'}) {
+#	if (defined ($metadata)) {
+#	    $sortname = undef;
+#	} else {
+#	    $sortname = "nosort";
+#	}
+#    }
+ #   $self->{'sortname'} = $sortname;
+
+    #if (defined $self->{'sort'} && $reverse_sort) {
+#	$self->{'reverse_sort'} = 1;
+ #   }
+	
+    if ($self->{'hfile'}) {
+	my $hfile = $self->{'hfile'};
+	my $subjectfile;
+	$subjectfile = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"etc", $hfile);
+	if (!-e $subjectfile) {
+	    my $collfile = $subjectfile;
+	    $subjectfile = &util::filename_cat($ENV{'GSDLHOME'},"etc", $hfile);
+	    if (!-e $subjectfile) {
+		my $outhandle = $self->{'outhandle'};
+		print STDERR "\nHFileHierarchy Error: Can't locate subject file $hfile\n";
+		print STDERR "This file should be in $collfile or $subjectfile\n";
+		$self->print_txt_usage("");  # Use default resource bundle
+		print STDERR "\nHFileHierarchy Error: Can't locate subject file $hfile\n";
+		print STDERR "This file should be in $collfile or $subjectfile\n";
+		die "\n";
+	    }
+	}
+	$self->{'descriptorlist'} = {}; # first field in subject file
+	$self->{'locatorlist'} = {}; # second field in subject file
+	$self->{'subjectfile'} = $subjectfile;
+    }
+    
+
+   # $self->{'firstvalueonly'} = $firstvalueonly;
+   # $self->{'allvalues'} = $allvalues;
+
+    #$self->{'hlist_at_top'} = $hlist_at_top;
+
+    # Clean out the unused keys
+    delete $self->{'metadata'};
+    delete $self->{'hfile'};
+    
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+
+    my $subjectfile = $self->{'subjectfile'};
+    if (defined $subjectfile) {
+	# read in the subject file
+	my $list = &cfgread::read_cfg_file ($self->{'subjectfile'}, undef, '^[^#]?\S');
+	# $list is a hash that is indexed by the descriptor. The contents of this
+	# hash is a list of two items. The first item is the OID and the second item
+	# is the title
+	foreach my $descriptor (keys (%$list)) {
+	    $self->{'descriptorlist'}->{$descriptor} = $list->{$descriptor}->[0];
+	    unless (defined $self->{'locatorlist'}->{$list->{$descriptor}->[0]}) {
+		$self->{'locatorlist'}->{$list->{$descriptor}->[0]}->{'title'} = $list->{$descriptor}->[1];
+		$self->{'locatorlist'}->{$list->{$descriptor}->[0]}->{'contents'} = [];
+	    }
+	}
+    }
+}
+
+sub hfile_classify
+{
+    my $self = shift (@_);
+    my ($doc_obj,$edit_mode,$sortmeta,$metavalues) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+
+    my $doc_OID = $doc_obj->get_OID();
+
+    foreach my $metaelement (@$metavalues) {
+	if ((defined $self->{'descriptorlist'}->{$metaelement}) &&
+	    (defined $self->{'locatorlist'}->{$self->{'descriptorlist'}->{$metaelement}})) {
+
+	    if ($edit_mode eq "delete") {
+		# find it, and remove it
+		my $existing_list = $self->{'locatorlist'}->{$self->{'descriptorlist'}->{$metaelement}}->{'contents'};
+		
+		my $filtered_list = [];
+		foreach my $existing_oid_pair (@$existing_list) {
+		    if ($existing_oid_pair->[0] eq $doc_OID) {
+			print $outhandle "  Deleting $doc_OID for $metaelement in hierarchy\n";
+		    }
+		    else {
+			push(@$filtered_list,$existing_oid_pair);
+		    }
+		}
+		$self->{'locatorlist'}->{$self->{'descriptorlist'}->{$metaelement}}->{'contents'} = $filtered_list;
+	    }
+	    else {
+		push (@{$self->{'locatorlist'}->{$self->{'descriptorlist'}->{$metaelement}}->{'contents'}}, 
+		      [$doc_OID, $sortmeta]);
+		my $localid = $self->{'descriptorlist'}->{$metaelement};
+		my $classid = $self->get_number();
+
+		$doc_obj->add_metadata($doc_obj->get_top_section(), "memberof", "CL$classid.$localid");
+	    }
+	}
+    }
+}
+
+
+
+
+sub hfile_get_classify_info {
+    my $self = shift (@_);
+    
+    my ($classifyinfo) = @_;
+
+    my $list = $self->{'locatorlist'};
+
+    # sorted the keys - otherwise funny things happen - kjdon 03/01/03
+    foreach my $OID (sort keys (%$list)) {
+	my $tempinfo = $self->get_OID_entry ($OID, $classifyinfo, $list->{$OID}->{'title'}, "VList");
+	
+	if (defined $self->{'sort'}) {
+	    if ($self->{'reverse_sort'}) {
+		foreach my $subOID (sort {$b->[1] cmp $a->[1];} @{$list->{$OID}->{'contents'}}) {
+		    push (@{$tempinfo->{'contains'}}, {'OID'=>$subOID->[0]});
+		}
+	    }
+	    else {
+		foreach my $subOID (sort {$a->[1] cmp $b->[1];} @{$list->{$OID}->{'contents'}}) {
+		    push (@{$tempinfo->{'contains'}}, {'OID'=>$subOID->[0]});
+		}
+	    }
+	}
+	else {
+	    foreach my $subOID (@{$list->{$OID}->{'contents'}}) {
+		push (@{$tempinfo->{'contains'}}, {'OID'=>$subOID->[0]});
+	    }
+	}
+    }
+    
+    return $classifyinfo;
+}
+
+
+sub supports_memberof {
+    my $self = shift(@_);
+
+    return "true";
+}
+
+sub get_OID_entry {
+    my $self = shift (@_);
+    my ($OID, $classifyinfo, $title, $classifytype) = @_;
+
+    $OID = "" unless defined $OID;
+    $OID =~ s/^\.+//;
+
+    my ($headOID, $tailOID) = $OID =~ /^(\d+)(.*)$/;
+    $tailOID = "" unless defined $tailOID;
+
+    if (!defined $headOID) {
+	$classifyinfo->{'Title'} = $title;
+	$classifyinfo->{'classifytype'} = $classifytype;
+	return $classifyinfo;
+    }
+
+    $classifyinfo->{'contains'} = [] unless defined $classifyinfo->{'contains'};
+    if ($self->{'documents_last'}) {
+	# documents should come after nodes in the classifier
+
+	my $doc_pos = 0;
+	foreach my $thing (@{$classifyinfo->{'contains'}}) {
+	    last if defined $thing->{'OID'};
+	    $doc_pos++;
+	}
+	
+	while ($doc_pos < $headOID) {
+	    splice(@{$classifyinfo->{'contains'}}, $doc_pos, 0, $self->get_entry("", $classifytype));
+	    $doc_pos++;
+	}
+
+	return $self->get_OID_entry ($tailOID, $classifyinfo->{'contains'}->[($headOID-1)], $title, $classifytype);
+
+    }
+    
+    # else, documents come before nodes
+    my $offset = 0;
+    foreach my $thing (@{$classifyinfo->{'contains'}}) {
+	$offset ++ if defined $thing->{'OID'};
+    }
+
+    while (scalar(@{$classifyinfo->{'contains'}}) < ($headOID+$offset)) { 
+	push (@{$classifyinfo->{'contains'}}, $self->get_entry("", $classifytype));
+    }
+
+    return $self->get_OID_entry ($tailOID, $classifyinfo->{'contains'}->[($headOID+$offset-1)], $title, $classifytype);
+}
+
+sub get_entry {
+    my $self = shift (@_);
+    my ($title, $childtype, $thistype) = @_;
+    my $memberof = &supports_memberof();
+    
+    # organise into classification structure
+    my %classifyinfo = ('childtype'=>$childtype,
+			'Title'=>$title,
+			'supportsmemberof'=>$memberof,
+			'contains'=>[]);
+    $classifyinfo{'thistype'} = $thistype 
+	if defined $thistype && $thistype =~ /\w/;
+
+    return \%classifyinfo;
+}
+
+
+1;
Index: /gsdl/stable/perllib/classify/HTML.pm
===================================================================
--- /gsdl/stable/perllib/classify/HTML.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/HTML.pm	(revision 20131)
@@ -0,0 +1,107 @@
+###########################################################################
+#
+# HTML.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# html classifier plugin - creates an empty classification
+# that's simply a link to a web page
+
+package HTML;
+
+use BaseClassifier;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @HTML::ISA = ('BaseClassifier');
+}
+
+my $arguments = 
+    [ { 'name' => "url",
+	'desc' => "{HTML.url}",
+	'type' => "string",
+	'reqd' => "yes" } ,
+      { 'name' => "buttonname",
+	'desc' => "{BasClas.buttonname}",
+	'type' => "string",
+	'deft' => "Browse",
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "HTML",
+		'desc'     => "{HTML.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseClassifier($classifierslist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    if (!$self->{'url'}) {
+	my $outhandle = $self->{'outhandle'};
+	print $outhandle "HTML Error: required option -url not supplied\n";
+	$self->print_txt_usage("");
+	die "HTML Error: required option -url not supplied\n";
+    }
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+}
+
+sub classify {
+    my $self = shift (@_);
+    my ($doc_obj,$edit_mode) = @_;
+
+    # we don't do anything for individual documents
+}
+
+sub get_classify_info {
+    my $self = shift (@_);
+
+    my %classifyinfo = ('thistype'=>'Invisible',
+			'childtype'=>'HTML',
+			'Title'=>$self->{'buttonname'},
+			'contains'=>[]);
+
+    push (@{$classifyinfo{'contains'}}, {'OID'=>$self->{'url'}});
+
+    return \%classifyinfo;
+}
+
+
+1;
Index: /gsdl/stable/perllib/classify/Hierarchy.pm
===================================================================
--- /gsdl/stable/perllib/classify/Hierarchy.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/Hierarchy.pm	(revision 20131)
@@ -0,0 +1,362 @@
+###########################################################################
+#
+# Hierarchy.pm -- classifier that enables a Hierarchy to beformed without 
+#                 the need for a hierarchy file (like HFileHierarchy). Used
+#                 to be called AutoHierarchy.  Inherits from HFileHierarchy
+#                 so can also do everything that does as well.
+#                 Created by Imene, modified by Katherine and David.
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# An advanced Hierarchical classifier
+# to see the options, run "perl -S classinfo.pl Hierarchy"
+
+package Hierarchy;
+
+use HFileHierarchy;
+use sorttools;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @Hierarchy::ISA = ('HFileHierarchy');
+}
+
+my $arguments = 
+    [ { 'name' => "separator",
+	'desc' => "{Hierarchy.separator}",
+	'type' => "regexp",
+	'deft' => "[\\\\\\\/|\\\\\\\|]",
+	'reqd' => "no" },
+      { 'name' => "suppresslastlevel",
+	'desc' => "{Hierarchy.suppresslastlevel}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "suppressfirstlevel",
+	'desc' => "{Hierarchy.suppressfirstlevel}",
+	'type' => "flag",
+	'reqd' => "no" }
+      ];
+
+my $options = { 'name'     => "Hierarchy",
+		'desc'     => "{Hierarchy.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new HFileHierarchy($classifierslist, $inputargs, $hashArgOptLists);
+    
+    # the hash that we use to build up the hierarchy
+    $self->{'path_hash'}= {};
+    
+    return bless $self, $class;
+}
+
+
+sub auto_classify {
+    my $self = shift (@_);
+    my ($doc_obj,$edit_mode,$nosort,$sortmeta,$metavalues) = @_;
+
+    my $doc_OID = $doc_obj->get_OID();
+
+    if (($edit_mode eq "delete") || ($edit_mode eq "update")) {
+	if ($nosort) {
+	    $self->oid_array_delete($doc_OID,'docs');
+	}
+	else {
+	    $self->oid_hash_delete($doc_OID,'docs');
+	}
+	return if ($edit_mode eq "delete");
+    }
+
+    #Add all the metadata values to the hash
+    my $path_hash;
+    my $current_pos;
+    
+    
+    foreach my $metavalue (@$metavalues) {
+	$path_hash = $self->{'path_hash'};
+	my @chunks = split (/$self->{'separator'}/, $metavalue);
+	if ($self->{'suppresslastlevel'}) {
+	    pop(@chunks); # remove the last element from the end
+	}
+	if ($self->{'suppressfirstlevel'}) {
+	    shift(@chunks);
+	}
+	foreach my $folderName (@chunks) 
+	{
+	    # Removing leading and trailing spaces
+	    $folderName =~ s/^(\s+)//;
+	    $folderName =~ s/(\s+)$//;
+	    if ($folderName ne ""){ #sometimes the tokens are empty
+		$current_pos = $self->add_To_Hash($path_hash, $folderName, $nosort);
+		$path_hash = $current_pos->{'nodes'};
+	    } 
+	}
+	# now add the document, with sort meta if needed
+	if ($nosort) {
+	    push(@{$current_pos->{'docs'}}, $doc_OID);
+	} else {
+	    $current_pos->{'docs'}->{$doc_OID} = $sortmeta;
+	    
+	    #if (defined $sortmeta) {
+	#	# can you ever get the same doc twice in one classification??
+	#	$current_pos->{'docs'}->{$doc_OID} = $sortmeta;
+	#    } else {
+	#	$current_pos->{'docs'}->{$doc_OID} = $metavalue;
+	#    }
+	}
+    } # foreach metadata
+
+}
+
+sub classify {
+    my $self = shift (@_);
+    my ($doc_obj,$edit_mode) = @_;
+
+    my $doc_OID = $doc_obj->get_OID();
+
+    # are we sorting the list??
+    my $nosort = 0;
+    if (!defined $self->{'sort'}) {
+	$nosort = 1;
+    }
+    
+    my $metavalues = [];
+    # find all the metadata values
+    foreach my $m (@{$self->{'meta_list'}}) {
+	my $mvalues = $doc_obj->get_metadata($doc_obj->get_top_section(), $m);
+	next unless (@{$mvalues});
+	if ($self->{'firstvalueonly'}) {
+	    # we only want the first metadata value
+	    push (@$metavalues, $mvalues->[0]);
+	    last;
+	}
+	push (@$metavalues, @$mvalues);
+	last if (!$self->{'allvalues'}); # we don't want to try other elements
+ 	                                 # cos we have already found some 
+    } 
+    
+    return unless (@$metavalues);
+
+    #check for a sort element other than our metadata
+    my $sortmeta = undef;
+    if (!$nosort) {
+	if ($self->{'sort'} =~ /^filename$/i) {
+	    $sortmeta = $doc_obj->get_source_filename();
+	} else {
+	    $sortmeta = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $self->{'sort'});
+	    if (defined $sortmeta && !$self->{'no_metadata_formatting'}) {
+		$sortmeta = &sorttools::format_metadata_for_sorting($self->{'sort'}, $sortmeta, $doc_obj);
+	    }
+	}
+	$sortmeta = "" unless defined $sortmeta;
+    }
+
+    if (defined $self->{'subjectfile'}) {
+	$self->hfile_classify($doc_obj,$edit_mode,$sortmeta,$metavalues);
+    }
+    else {
+	$self->auto_classify($doc_obj,$edit_mode,$nosort,$sortmeta,$metavalues);
+    }
+}
+
+sub add_To_Hash {
+    my $self = shift (@_);
+    my ($myhash, $k, $nosort) = @_;
+    
+    if (!defined $myhash->{$k}){
+	$myhash->{$k}={};
+	$myhash->{$k}->{'nodes'}={};
+	if ($nosort) {
+	    $myhash->{$k}->{'docs'}=[];
+	} else {
+	    $myhash->{$k}->{'docs'} = {};
+	}
+    }
+    return $myhash->{$k}; 
+}
+
+sub print_Hash{
+    my $self = shift (@_); 
+    my ($myHash, $num_spaces) = @_;
+
+    foreach my $key (keys %{$myHash}){
+	print "\n";
+	$self->print_spaces($num_spaces);
+	print STDERR "$key*";
+	$self->print_Hash($myHash->{$key}, $num_spaces + 2);
+    }    
+}
+
+sub print_spaces{
+    my $self = shift (@_);
+    my ($num_spaces) = @_;
+    
+    for (my $i = 0; $i < $num_spaces; $i++){
+	print STDERR " ";
+    }
+}
+
+sub get_entry {
+    my $self = shift (@_);
+    my ($title, $childtype, $thistype) = @_;
+    
+    # organise into classification structure
+    my %classifyinfo = ('childtype'=>$childtype,
+			'Title'=>$title,
+			'contains'=>[],);
+    $classifyinfo{'thistype'} = $thistype 
+	if defined $thistype && $thistype =~ /\w/;
+    
+    return \%classifyinfo;
+}
+
+sub process_hash {
+    my $self = shift (@_);
+    my ($top_hash, $top_entry) = @_;   
+    my ($entry);
+    
+    my $hash = {};
+    foreach my $key (sort keys %{$top_hash}) {
+	$entry = $self->get_entry($key,"VList","VList");
+	my $has_content = 0;
+	my @doc_list;
+	# generate a sorted list of doc ids
+	if (not (defined ($self->{'sort'})) && scalar(@{$top_hash->{$key}->{'docs'}})) {
+	    @doc_list = @{$top_hash->{$key}->{'docs'}};
+	} elsif (defined ($self->{'sort'}) && (keys %{$top_hash->{$key}->{'docs'}})) {
+	    @doc_list = sort {$top_hash->{$key}->{'docs'}->{$a} 
+			      cmp $top_hash->{$key}->{'docs'}->{$b};} keys %{$top_hash->{$key}->{'docs'}};
+	    
+	}
+
+	if ($self->{'documents_last'}) {
+	    # add nodes, then documents
+	    # if this key has nodes, add them
+	    if (scalar(keys %{$top_hash->{$key}->{'nodes'}})) {
+		$has_content = 1;
+		$self->process_hash($top_hash->{$key}->{'nodes'}, $entry); 
+	    }
+
+	    # if this key has documents, add them
+	    if (@doc_list) {
+		$has_content = 1;
+		foreach my $d (@doc_list) {
+		    push (@{$entry->{'contains'}}, {'OID'=>$d});
+		}    
+	    }
+
+	} else {
+	    # add documents then nodes
+	    # if this key has documents, add them
+	    if (@doc_list) {
+		$has_content = 1;
+		foreach my $d (@doc_list) {
+		    push (@{$entry->{'contains'}}, {'OID'=>$d});
+		}    
+	    }
+	    # if this key has nodes, add them
+	    if (scalar(keys %{$top_hash->{$key}->{'nodes'}})) {
+		$has_content = 1;
+		$self->process_hash($top_hash->{$key}->{'nodes'}, $entry); 
+	    }
+	}
+	
+	# if we have found some content, add the new entry for this key into the parent node
+	if ($has_content) {
+	    push (@{$top_entry->{'contains'}}, $entry);
+	}
+
+    }    
+}
+
+sub auto_get_classify_info {
+    my $self = shift (@_);
+    my ($no_thistype) = @_;
+    $no_thistype = 0 unless defined $no_thistype;
+
+    my ($classification);
+    my $top_h = $self->{'path_hash'};
+
+    if ($self->{'path_hash'}) {
+	if ($self->{'hlist_at_top'}) {
+	    $classification = $self->get_entry ($self->{'buttonname'}, "HList", "Invisible");
+	}
+	else {
+	    $classification = $self->get_entry ($self->{'buttonname'}, "VList", "Invisible");
+	}
+    }
+
+    $self->process_hash($top_h, $classification);
+   
+    return  $classification;
+
+}
+
+sub auto_get_classify_info
+{
+    my $self = shift (@_);
+    my ($classifyinfo) = @_;
+
+    $self->process_hash($self->{'path_hash'}, $classifyinfo);
+
+    return $classifyinfo;
+}
+
+
+sub get_classify_info {
+    my $self = shift (@_);
+
+    my ($classifyinfo);
+
+    if ($self->{'hlist_at_top'}) {
+	$classifyinfo = $self->get_entry ($self->{'buttonname'}, "HList", "Invisible");
+    }
+    else {
+	$classifyinfo = $self->get_entry ($self->{'buttonname'}, "VList", "Invisible");
+    }
+
+    if (defined $self->{'subjectfile'}) {
+	return $self->hfile_get_classify_info($classifyinfo);
+    }
+    else {
+	return $self->auto_get_classify_info($classifyinfo);
+    }
+}
+
+
+1;
+
+
+
Index: /gsdl/stable/perllib/classify/List.pm
===================================================================
--- /gsdl/stable/perllib/classify/List.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/List.pm	(revision 20131)
@@ -0,0 +1,835 @@
+###########################################################################
+#
+# List.pm -- A general and flexible list classifier with most of
+#                   the abilities of AZCompactList, and better Unicode,
+#                   metadata and sorting capabilities.
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Author: Michael Dewsnip, NZDL Project, University of Waikato, NZ
+#
+# Copyright (C) 2005 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# TO DO: - Remove punctuation from metadata values before sorting.
+#        - Add an AZCompactList-style hlist option?
+#
+###########################################################################
+
+package List;
+
+
+use BaseClassifier;
+
+use strict;
+
+
+sub BEGIN {
+    @List::ISA = ('BaseClassifier');
+}
+
+my $partition_type_list = 
+    [ { 'name' => "per_letter",
+	'desc' => "{List.level_partition.per_letter}" },
+      { 'name' => "constant_size",
+	'desc' => "{List.level_partition.constant_size}" },      
+      { 'name' => "per_letter_fixed_size",
+	'desc' => "{List.level_partition.per_letter_fixed_size}"}, 
+      { 'name' => "none",
+	'desc' => "{List.level_partition.none}" } ];
+
+my $bookshelf_type_list = 
+    [ { 'name' => "always",
+	'desc' => "{List.bookshelf_type.always}" },
+      { 'name' => "duplicate_only",
+	'desc' => "{List.bookshelf_type.duplicate_only}" },
+      { 'name' => "never",
+	'desc' => "{List.bookshelf_type.never}" } ];  
+
+my $arguments = 
+    [ { 'name' => "metadata",
+	'desc' => "{List.metadata}",
+	'type' => "metadata",
+	'reqd' => "yes" },
+
+      # The interesting options
+      { 'name' => "bookshelf_type", 
+	'desc' => "{List.bookshelf_type}",
+	'type' => "enum",
+	'list' => $bookshelf_type_list,
+	'deft' => "never" }, 
+      { 'name' => "classify_sections",
+	'desc' => "{List.classify_sections}",
+	'type' => "flag" },
+      { 'name' => "partition_type_within_level",
+	'desc' => "{List.partition_type_within_level}",
+	'type' => "enum",
+	'list' => $partition_type_list,
+	'deft' => "per_letter" },
+      { 'name' => "partition_size_within_level",
+	'desc' => "{List.partition_size_within_level}",
+	'type' => "int",
+	'range' => "1,",
+	'deft' => "39" },
+      { 'name' => "partition_name_length",
+	'desc' => "{List.partition_name_length}",
+	'type' => "string" },
+      { 'name' => "sort_leaf_nodes_using",
+	'desc' => "{List.sort_leaf_nodes_using}",
+	'type' => "metadata",
+	'deft' => "Title" },
+      { 'name' => "sort_using_unicode_collation",
+	'desc' => "{List.sort_using_unicode_collation}",
+	'type' => "flag" },
+      { 'name' => "use_hlist_for",
+	'desc' => "{List.use_hlist_for}",
+	'type' => "string" },
+      { 'name' => "removeprefix",
+	'desc' => "{BasClas.removeprefix}",
+	'type' => "regexp" },
+      { 'name' => "removesuffix",
+	'desc' => "{BasClas.removesuffix}",
+	'type' => "regexp" } ];
+
+my $options = { 'name'     => "List",
+		'desc'     => "{List.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new
+{
+    my ($class) = shift(@_);
+    my ($classifierslist, $inputargs, $hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}}, @{$arguments}); 
+    push(@{$hashArgOptLists->{"OptList"}}, $options); 
+
+    my $self = new BaseClassifier($classifierslist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    # The metadata elements to use (required)
+    if (!$self->{'metadata'}) {
+	die "Error: No metadata fields specified for List.\n";
+    }
+    my @metadata_groups = split(/\//, $self->{'metadata'});
+    $self->{'metadata_groups'} = \@metadata_groups;
+
+    # The classifier button name (default: the first metadata element specified)
+    if (!$self->{'buttonname'}) {
+	my $first_metadata_group = $metadata_groups[0];
+	my $first_metadata_element = (split(/\;|,/, $first_metadata_group))[0];
+	$self->{'buttonname'} = $self->generate_title_from_metadata($first_metadata_element);
+    }
+
+    # Whether to group items into a bookshelf, (must be 'always' for all metadata fields except the last)
+    foreach my $metadata_group (@metadata_groups) {
+	$self->{$metadata_group . ".bookshelf_type"} = "always";
+    }    
+    my $last_metadata_group = $metadata_groups[$#metadata_groups];
+    # Default: duplicate_only, ie. leave leaf nodes ungrouped (equivalent to AZCompactList -mingroup 2)
+    $self->{$last_metadata_group . ".bookshelf_type"} = $self->{'bookshelf_type'};
+        
+    # Whether to use an hlist or a vlist for each level in the hierarchy (default: vlist)
+    foreach my $metadata_group (@metadata_groups) {
+	$self->{$metadata_group . ".list_type"} = "VList";
+    }
+    foreach my $metadata_group (split(/\,/, $self->{'use_hlist_for'})) {
+	$self->{$metadata_group . ".list_type"} = "HList";
+    }
+
+    # How the items are grouped into partitions (default: no partition) 
+    # for each level (metadata group), separated by '/'
+    if (!$self->{"partition_type_within_level"}) {
+	foreach my $metadata_group (@metadata_groups) {
+	    $self->{$metadata_group . ".partition_type_within_level"} = "none";
+	}
+    } else {
+	my @partition_type_within_levellist = split(/\//, $self->{'partition_type_within_level'});	
+	foreach my $metadata_group (@metadata_groups) {
+	    my $partition_type_within_levelelem = shift(@partition_type_within_levellist);
+	    if (defined($partition_type_within_levelelem)) {
+		$self->{$metadata_group . ".partition_type_within_level"} = $partition_type_within_levelelem;
+	    }
+	    else {
+		$self->{$metadata_group . ".partition_type_within_level"} = $self->{$metadata_groups[0] . ".partition_type_within_level"};
+	    }
+	}
+    }
+
+    # The number of items in each partition
+    if (!$self->{'partition_size_within_level'}) {
+	# Default: 20
+	foreach my $metadata_group (@metadata_groups) {
+	    $self->{$metadata_group . ".partition_size_within_level"} = 20;
+	}
+    }
+    else {
+	my @partition_size_within_levellist = split(/\//, $self->{'partition_size_within_level'});
+
+	# Assign values based on the partition_size_within_level parameter
+	foreach my $metadata_group (@metadata_groups) {
+	    my $partition_size_within_levelelem = shift(@partition_size_within_levellist);
+	    if (defined($partition_size_within_levelelem)) {
+		$self->{$metadata_group . ".partition_size_within_level"} = $partition_size_within_levelelem;
+	    }
+	    else {
+		$self->{$metadata_group . ".partition_size_within_level"} = $self->{$metadata_groups[0] . ".partition_size_within_level"};
+	    }
+	}
+    }
+
+    # The removeprefix and removesuffix expressions
+    if ($self->{'removeprefix'}) {
+	# If there are more than one expressions, use '' to quote each experession and '/' to separate
+	my @removeprefix_exprs_within_levellist = split(/'\/'/, $self->{'removeprefix'});
+
+	foreach my $metadata_group (@metadata_groups) {
+	    my $removeprefix_expr_within_levelelem = shift(@removeprefix_exprs_within_levellist);
+	    if (defined($removeprefix_expr_within_levelelem) && $removeprefix_expr_within_levelelem ne "") {
+		# Remove the other ' at the beginning and the end if there is any
+		$removeprefix_expr_within_levelelem =~ s/^'//;
+		$removeprefix_expr_within_levelelem =~ s/'$//;
+		# Remove the extra ^ at the beginning
+		$removeprefix_expr_within_levelelem =~ s/^\^//;
+		$self->{$metadata_group . ".remove_prefix_expr"} = $removeprefix_expr_within_levelelem;
+	    } else {
+		$self->{$metadata_group . ".remove_prefix_expr"} = $self->{$metadata_groups[0] . ".remove_prefix_expr"};
+	    }
+	}
+    } 
+    if ($self->{'removesuffix'}) {	
+	my @removesuffix_exprs_within_levellist = split(/'\/'/, $self->{'removesuffix'});
+
+	foreach my $metadata_group (@metadata_groups) {
+	    my $removesuffix_expr_within_levelelem = shift(@removesuffix_exprs_within_levellist);
+	    if (defined($removesuffix_expr_within_levelelem) && $removesuffix_expr_within_levelelem ne "") {
+		$removesuffix_expr_within_levelelem =~ s/^'//;
+		$removesuffix_expr_within_levelelem =~ s/'$//;
+		# Remove the extra $ at the end
+		$removesuffix_expr_within_levelelem =~ s/\$$//;
+		$self->{$metadata_group . ".remove_suffix_expr"} = $removesuffix_expr_within_levelelem;
+	    } else {
+		$self->{$metadata_group . ".remove_suffix_expr"} = $self->{$metadata_groups[0] . ".remove_suffix_expr"};
+	    }
+	}
+    }
+
+    # The metadata elements to use to sort the leaf nodes (default: Title)
+    my @sort_leaf_nodes_using_metadata_groups = ( "Title" );
+    if ($self->{'sort_leaf_nodes_using'}) {
+	@sort_leaf_nodes_using_metadata_groups = split(/\|/, $self->{'sort_leaf_nodes_using'});
+    }
+    $self->{'sort_leaf_nodes_using_metadata_groups'} = \@sort_leaf_nodes_using_metadata_groups;
+
+    # Create an instance of the Unicode::Collate object if better Unicode sorting is desired
+    if ($self->{'sort_using_unicode_collation'}) {
+	# To use this you first need to download the allkeys.txt file from 
+        # http://www.unicode.org/Public/UCA/latest/allkeys.txt and put it in the Perl
+        # Unicode/Collate directory.
+	require Unicode::Collate;
+	$self->{'unicode_collator'} = Unicode::Collate->new();
+    }
+
+    # An empty array for the document OIDs
+    $self->{'OIDs'} = [];
+
+    return bless $self, $class;
+}
+
+
+sub init
+{
+    # Nothing to do...
+}
+
+
+# Called for each document in the collection
+sub classify
+{
+    my $self = shift(@_);
+    my ($doc_obj,$edit_mode) = @_;
+
+    # If "-classify_sections" is set, classify every section of the document
+    if ($self->{'classify_sections'}) {
+	my $section = $doc_obj->get_next_section($doc_obj->get_top_section());
+	while (defined $section) {
+	    $self->classify_section($doc_obj, $doc_obj->get_OID() . ".$section", $section, $edit_mode);
+	    $section = $doc_obj->get_next_section($section);
+	}
+    }
+    # Otherwise just classify the top document section
+    else {
+	$self->classify_section($doc_obj, $doc_obj->get_OID(), $doc_obj->get_top_section(), $edit_mode);
+    }
+}
+
+
+sub classify_section
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section_OID,$section,$edit_mode) = @_;
+
+    my @metadata_groups = @{$self->{'metadata_groups'}};
+
+    # Only classify the section if it has a value for one of the metadata elements in the first group
+    my $classify_section = 0;
+    my $first_metadata_group = $metadata_groups[0];
+    foreach my $first_metadata_group_element (split(/\;|,/, $first_metadata_group)) {
+	my $first_metadata_group_element_value = $doc_obj->get_metadata_element($section, $first_metadata_group_element);	
+	
+	# Remove prefix/suffix if requested
+	my $remove_prefix_expr = $self->{$first_metadata_group_element . ".remove_prefix_expr"};
+	if (defined $remove_prefix_expr && $remove_prefix_expr ne "") {	    
+	    $first_metadata_group_element_value =~ s/^$remove_prefix_expr//;
+	}
+	my $remove_suffix_expr = $self->{$first_metadata_group_element . ".remove_suffix_expr"};
+	if (defined $remove_suffix_expr && $remove_suffix_expr ne "") {
+	    $first_metadata_group_element_value =~ s/$remove_suffix_expr$//;
+	}
+
+	if (defined($first_metadata_group_element_value) && $first_metadata_group_element_value ne "") {
+	    # This section must be included in the classifier
+	    $classify_section = 1;
+	    last;
+	} 
+    }
+
+    # We're not classifying this section because it doesn't have the required metadata
+    return if (!$classify_section);
+
+    if (($edit_mode eq "delete") || ($edit_mode eq "update")) {
+	$self->oid_array_delete($section_OID,'OIDs');
+	if ($edit_mode eq "delete") {
+	    return;
+	}
+    }
+   
+    # Otherwise, include this section in the classifier
+    push(@{$self->{'OIDs'}}, $section_OID);
+
+    # Create a hash for the metadata values of each metadata element we're interested in
+    my %metadata_groups_done = ();
+    foreach my $metadata_group (@metadata_groups, @{$self->{'sort_leaf_nodes_using_metadata_groups'}}) {
+	# Take care not to do a metadata group more than once
+	unless ($metadata_groups_done{$metadata_group}) {
+	    foreach my $metadata_element (split(/\;|,/, $metadata_group)) {		
+		my $remove_prefix_expr = $self->{$metadata_element . ".remove_prefix_expr"};
+		my $remove_suffix_expr = $self->{$metadata_element . ".remove_suffix_expr"};
+		my @metadata_values = @{$doc_obj->get_metadata($section, $metadata_element)};
+		foreach my $metadata_value (@metadata_values) {
+		    # Strip leading and trailing whitespace
+		    $metadata_value =~ s/^\s*//;
+		    $metadata_value =~ s/\s*$//;
+
+		    # Remove prefix/suffix if requested
+		    if (defined $remove_prefix_expr && $remove_prefix_expr ne "") {
+			$metadata_value =~ s/^$remove_prefix_expr//;
+		    }
+		    if (defined $remove_suffix_expr && $remove_suffix_expr ne "") {
+			$metadata_value =~ s/$remove_suffix_expr$//;
+		    }
+
+		    # Convert the metadata value from a UTF-8 string to a Unicode string
+		    # This means that length() and substr() work properly
+		    # We need to be careful to convert classifier node title values back to UTF-8, however
+		    my $metadata_value_unicode_string = $self->convert_utf8_string_to_unicode_string($metadata_value);
+
+		    # Add the metadata value into the list for this combination of metadata group and section
+		    push(@{$self->{$metadata_group . ".list"}->{$section_OID}}, $metadata_value_unicode_string);
+		}
+		last if (@metadata_values > 0);
+	    }
+
+	    $metadata_groups_done{$metadata_group} = 1;
+	}
+    }
+}
+
+
+sub get_classify_info
+{
+    my $self = shift(@_);
+
+    # The metadata groups to classify by
+    my @metadata_groups = @{$self->{'metadata_groups'}};
+    my $first_metadata_group = $metadata_groups[0];
+
+    # The OID values of the documents to include in the classifier
+    my @OIDs = @{$self->{'OIDs'}};
+
+    # Create the root node of the classification hierarchy
+    my %classifier_node = ( 'thistype' => "Invisible",
+			    'childtype' => $self->{$first_metadata_group . ".list_type"},
+			    'Title' => $self->{'buttonname'},
+			    'contains' => [],
+			    'mdtype' => $first_metadata_group );
+
+    # Recursively create the classification hierarchy, one level for each metadata group
+    $self->add_level(\@metadata_groups, \@OIDs, \%classifier_node);
+    return \%classifier_node;
+}
+
+
+sub add_level
+{
+    my $self = shift(@_);
+    my @metadata_groups = @{shift(@_)};
+    my @OIDs = @{shift(@_)};
+    my $classifier_node = shift(@_);
+    # print STDERR "\nAdding AZ list for " . $classifier_node->{'Title'} . "\n";
+
+    my $metadata_group = $metadata_groups[0];
+    # print STDERR "Processing metadata group: " . $metadata_group . "\n";
+    # print STDERR "Number of OID values: " . @OIDs . "\n";
+
+    if (!defined($self->{$metadata_group . ".list"})) {
+	print STDERR "Warning: No metadata values assigned to $metadata_group.\n";
+	return;
+    }
+
+    # Create a mapping from metadata value to OID
+    my $OID_to_metadata_values_hash_ref = $self->{$metadata_group . ".list"};
+    my %metadata_value_to_OIDs_hash = ();    
+    foreach my $OID (@OIDs)
+    {
+	if ($OID_to_metadata_values_hash_ref->{$OID})
+	{
+	    my @metadata_values = @{$OID_to_metadata_values_hash_ref->{$OID}};
+	    foreach my $metadata_value (@metadata_values)
+	    {
+		push(@{$metadata_value_to_OIDs_hash{$metadata_value}}, $OID);
+	    }
+	}
+    }
+    # print STDERR "Number of distinct values: " . scalar(keys %metadata_value_to_OIDs_hash) . "\n";
+
+    # Partition the values (if necessary)
+    my $partition_type_within_level = $self->{$metadata_group . ".partition_type_within_level"};
+    if ($partition_type_within_level =~ /^per_letter$/i) {
+	# Generate one hlist for each letter
+	my @sortedmetadata_values = $self->sort_metadata_values_array(keys(%metadata_value_to_OIDs_hash));
+	my %metadata_value_to_OIDs_subhash = ();
+
+	my $lastpartition = substr($sortedmetadata_values[0], 0, 1);
+	foreach my $metadata_value (@sortedmetadata_values) {
+	    my $metadata_valuepartition = substr($metadata_value, 0, 1);
+
+	    # Is this the start of a new partition?
+	    if ($metadata_valuepartition ne $lastpartition) {
+		$self->add_hlist_partition(\@metadata_groups, $classifier_node, $lastpartition, \%metadata_value_to_OIDs_subhash);
+		%metadata_value_to_OIDs_subhash = ();
+		$lastpartition = $metadata_valuepartition;
+	    }
+
+	    $metadata_value_to_OIDs_subhash{$metadata_value} = $metadata_value_to_OIDs_hash{$metadata_value};	    
+	}
+
+	# Don't forget to add the last partition
+	$self->add_hlist_partition(\@metadata_groups, $classifier_node, $lastpartition, \%metadata_value_to_OIDs_subhash);
+
+	# The partitions are stored in an HList
+	$classifier_node->{'childtype'} = "HList";
+    }
+    elsif ($partition_type_within_level =~ /^per_letter_fixed_size$/i) {
+	# Generate hlist based on the first letter of the metadata value (like per_letter) but with restriction on the partition size
+	# If a letter has fewer items than specified by the "partition_size_within_level", then group them together if possible
+	# If a letter has more items than specified, split into several hlists.
+	# Depends on the bookshelf_type, one item can be either a document (when bookshelf_type is "never") or a metadata value (otherwise)
+	my $partition_size_within_level = $self->{$metadata_group . ".partition_size_within_level"};		
+	my @sortedmetadata_values = $self->sort_metadata_values_array(keys(%metadata_value_to_OIDs_hash));
+	my $bookshelf_type = $self->{$metadata_group . ".bookshelf_type"};
+	
+	# Separate values by their first letter, each form a bucket, like the per_letter partition type
+	my $last_partition = substr($sortedmetadata_values[0], 0, 1);
+	my %partition_buckets = ();
+	my @metadata_values_in_bucket = ();
+	my $num_items_in_bucket = 0;
+	foreach my $metadata_value (@sortedmetadata_values) {	    
+	    my $metadata_valuepartition = substr($metadata_value, 0, 1);
+	    if ($metadata_valuepartition ne $last_partition) {
+		my @temp_array = @metadata_values_in_bucket;
+		# Cache the values that belong to this bucket, and the number of items in this bucket, not necessary to be the same number as the metadata values 
+		my %partition_info = ();		
+		$partition_info{'metadata_values'} = \@temp_array;
+		$partition_info{'size'} = $num_items_in_bucket;		
+		$partition_buckets{$last_partition} = \%partition_info;		
+		
+		@metadata_values_in_bucket = ($metadata_value);
+		$num_items_in_bucket = $bookshelf_type eq "never" ? scalar(@{$metadata_value_to_OIDs_hash{$metadata_value}}) : scalar(@metadata_values_in_bucket);
+		$last_partition = $metadata_valuepartition;
+	    } else {
+		$num_items_in_bucket += $bookshelf_type eq "never" ? scalar(@{$metadata_value_to_OIDs_hash{$metadata_value}}) : scalar(@metadata_values_in_bucket);
+		push (@metadata_values_in_bucket, $metadata_value);
+	    }
+	}
+	# Last one
+	my %partition_info = ();
+	$partition_info{'metadata_values'} = \@metadata_values_in_bucket;
+	$partition_info{'size'} = $num_items_in_bucket;	
+	$partition_buckets{$last_partition} = \%partition_info;
+		
+	my @partition_keys = $self->sort_metadata_values_array(keys(%partition_buckets));	
+	for (my $i = 0; $i < scalar(@partition_keys) - 1; $i++) {
+	    my $partition = $partition_keys[$i];
+	    my $items_in_partition = $partition_buckets{$partition}->{'size'};	    	    
+	    # Merge small buckets together, but keep the numeric bucket apart
+	    if ($items_in_partition < $partition_size_within_level) {
+		my $items_in_next_partition = $partition_buckets{$partition_keys[$i+1]}->{'size'};
+		if ($items_in_partition + $items_in_next_partition <= $partition_size_within_level 
+		    && !(($partition =~ /^[^0-9]/ && $partition_keys[$i+1] =~ /^[0-9]/) 
+			 || ($partition =~ /^[0-9]/ && $partition_keys[$i+1] =~ /^[^0-9]/))) {
+		    foreach my $metadata_value_to_merge (@{$partition_buckets{$partition}->{'metadata_values'}}) {
+			push(@{$partition_buckets{$partition_keys[$i+1]}->{'metadata_values'}}, $metadata_value_to_merge);
+		    }		    
+		    $partition_buckets{$partition_keys[$i+1]}->{'size'} += $items_in_partition;
+		    delete $partition_buckets{$partition};		    		    
+		} 
+	    }
+	}
+	@partition_keys = $self->sort_metadata_values_array(keys(%partition_buckets));
+	
+	# Add partitions, and divide big bucket into several
+	my $last_partition_end = "";
+	my $partition_start = "";
+	foreach my $partition (@partition_keys) {
+	    my @metadata_values = $self->sort_metadata_values_array(@{$partition_buckets{$partition}->{'metadata_values'}});
+	    my $items_in_partition = $partition_buckets{$partition}->{'size'}; 
+	    $partition_start = $self->generate_partition_start($metadata_values[0], $last_partition_end, $self->{"partition_name_length"});
+	    
+	    if ($items_in_partition > $partition_size_within_level) {	
+		my $items_done = 0;
+		my %metadata_values_to_OIDs_subhashes = ();
+		for (my $i = 0; $i < scalar(@metadata_values); $i++) {
+		    my $metadata_value = $metadata_values[$i];
+		    # If the bookshelf_type is "never", count the documents, otherwise count the distinct metadata values
+		    my $items_for_this_md_value = $bookshelf_type eq "never" ? scalar(@{$metadata_value_to_OIDs_hash{$metadata_value}}) : 1;
+
+		    my $partitionend = $self->generate_partition_end($metadata_value, $partition_start, $self->{"partition_name_length"});
+		    my $partitionname = $partition_start;
+		    if ($partitionend ne $partition_start) {
+			$partitionname = $partitionname . "-" . $partitionend;
+		    }
+		    
+		    # Start a new partition
+		    if ($items_done + $items_for_this_md_value > $partition_size_within_level && $items_done != 0) {
+			$self->add_hlist_partition(\@metadata_groups, $classifier_node, $partitionname, \%metadata_values_to_OIDs_subhashes);
+			$last_partition_end = $partitionend;			
+			$partition_start = $self->generate_partition_start($metadata_value, $last_partition_end, $self->{"partition_name_length"});
+			$items_done = 0;
+			%metadata_values_to_OIDs_subhashes = ();
+ 		    } 
+		    
+		    # If bookshelf_type is "never" and the current metadata value holds too many items, need to split into several partitions
+                    if ($bookshelf_type eq "never" && $items_for_this_md_value > $partition_size_within_level) {
+			my $partitionname_for_this_value = $self->generate_partition_start($metadata_value, $last_partition_end, $self->{"partition_name_length"});
+			# Get the number of partitions needed for this value
+			my $num_splits = int($items_for_this_md_value / $partition_size_within_level);
+			$num_splits++ if ($items_for_this_md_value / $partition_size_within_level > $num_splits);
+
+			my @OIDs_for_this_value = @{$metadata_value_to_OIDs_hash{$metadata_value}};
+			for (my $i = 0; $i < $num_splits; $i++) {
+			    my %OIDs_subhashes_for_this_value = ();
+			    my @OIDs_for_this_partition = ();
+			    for (my $d = $i * $partition_size_within_level; $d < (($i+1) * $partition_size_within_level > $items_for_this_md_value ? $items_for_this_md_value : ($i+1) * $partition_size_within_level); $d++) {
+				push (@OIDs_for_this_partition, $OIDs_for_this_value[$d]);
+			    } 
+			    
+			    # The last bucket might have only a few items and need to be merged with buckets for subsequent metadata values 
+			    if ($i == $num_splits - 1 && scalar(@OIDs_for_this_partition) < $partition_size_within_level) {
+				$metadata_values_to_OIDs_subhashes{$metadata_value} = \@OIDs_for_this_partition;
+				$items_done += scalar(@OIDs_for_this_partition);
+				next;
+			    }
+			    
+			    # Add an HList for this bucket
+			    $OIDs_subhashes_for_this_value{$metadata_value} = \@OIDs_for_this_partition;
+			    $self->add_hlist_partition(\@metadata_groups, $classifier_node, $partitionname_for_this_value, \%OIDs_subhashes_for_this_value);
+			    $last_partition_end = $partitionname_for_this_value;
+			}
+			next;
+                    }
+		    		    
+		    $metadata_values_to_OIDs_subhashes{$metadata_value} = $metadata_value_to_OIDs_hash{$metadata_value};
+		    $items_done += $bookshelf_type eq "never" ? scalar(@{$metadata_values_to_OIDs_subhashes{$metadata_value}}) : 1;		    
+		    
+		    # The last partition
+		    if($i == scalar(@metadata_values) - 1) {
+			$self->add_hlist_partition(\@metadata_groups, $classifier_node, $partitionname, \%metadata_values_to_OIDs_subhashes);
+		    }
+		}		
+	    } 
+	    else {
+		# The easier case, just add a partition
+		my %metadata_values_to_OIDs_subhashes = ();
+		for (my $i = 0; $i < scalar(@metadata_values); $i++) {
+		    my $metadata_value = $metadata_values[$i];
+		    $metadata_values_to_OIDs_subhashes{$metadata_value} = $metadata_value_to_OIDs_hash{$metadata_value};		    
+		}
+		my $last_metadata_value = $metadata_values[scalar(@metadata_values)-1];
+		my $partitionend = $self->generate_partition_end($last_metadata_value, $partition_start, $self->{"partition_name_length"});
+		my $partitionname = $partition_start;
+		if ($partitionend ne $partition_start) {
+		    $partitionname = $partitionname . "-" . $partitionend;
+		}
+		$self->add_hlist_partition(\@metadata_groups, $classifier_node, $partitionname, \%metadata_values_to_OIDs_subhashes);			
+		$last_partition_end = $partitionend;		
+	    }
+	}	
+    }
+    else {
+	# Generate hlists of a certain size
+	my $partition_size_within_level = $self->{$metadata_group . ".partition_size_within_level"};
+	if ($partition_type_within_level =~ /^constant_size$/i && scalar(keys %metadata_value_to_OIDs_hash) > $partition_size_within_level) {
+	    my @sortedmetadata_values = $self->sort_metadata_values_array(keys(%metadata_value_to_OIDs_hash));
+	    my $itemsdone = 0;
+	    my %metadata_value_to_OIDs_subhash = ();
+	    my $lastpartitionend = "";
+	    my $partitionstart;
+	    foreach my $metadata_value (@sortedmetadata_values) {
+		$metadata_value_to_OIDs_subhash{$metadata_value} = $metadata_value_to_OIDs_hash{$metadata_value};
+		$itemsdone++;
+		my $itemsinpartition = scalar(keys %metadata_value_to_OIDs_subhash);
+
+		# Is this the start of a new partition?
+		if ($itemsinpartition == 1) {
+		    $partitionstart = $self->generate_partition_start($metadata_value, $lastpartitionend, $self->{"partition_name_length"});
+		}
+
+		# Is this the end of the partition?
+		if ($itemsinpartition == $partition_size_within_level || $itemsdone == @sortedmetadata_values) {
+		    my $partitionend = $self->generate_partition_end($metadata_value, $partitionstart, $self->{"partition_name_length"});
+		    my $partitionname = $partitionstart;
+		    if ($partitionend ne $partitionstart) {
+			$partitionname = $partitionname . "-" . $partitionend;
+		    }
+
+		    $self->add_hlist_partition(\@metadata_groups, $classifier_node, $partitionname, \%metadata_value_to_OIDs_subhash);
+		    %metadata_value_to_OIDs_subhash = ();
+		    $lastpartitionend = $partitionend;
+		}
+	    }
+
+	    # The partitions are stored in an HList
+	    $classifier_node->{'childtype'} = "HList";
+	}
+
+	# Otherwise just add all the values to a VList
+	else {
+	    $self->add_vlist(\@metadata_groups, $classifier_node, \%metadata_value_to_OIDs_hash);
+	}
+    }
+}
+
+
+sub convert_utf8_string_to_unicode_string
+{
+    my $self = shift(@_);
+    my $utf8_string = shift(@_);
+
+    my $unicode_string = "";
+    foreach my $unicode_value (@{&unicode::utf82unicode($utf8_string)}) {
+	$unicode_string .= chr($unicode_value);
+    }
+    return $unicode_string;
+}
+
+
+sub convert_unicode_string_to_utf8_string
+{
+    my $self = shift(@_);
+    my $unicode_string = shift(@_);
+
+    my @unicode_array;
+    for (my $i = 0; $i < length($unicode_string); $i++) {
+	push(@unicode_array, ord(substr($unicode_string, $i, 1)));
+    }
+    return &unicode::unicode2utf8(\@unicode_array);
+}
+
+
+sub generate_partition_start
+{
+    my $self = shift(@_);
+    my $metadata_value = shift(@_);
+    my $lastpartitionend = shift(@_);
+    my $partition_name_length = shift(@_);
+
+    if ($partition_name_length) {
+	return substr($metadata_value, 0, $partition_name_length);
+    }
+
+    my $partitionstart = substr($metadata_value, 0, 1);
+    if ($partitionstart le $lastpartitionend) {
+	$partitionstart = substr($metadata_value, 0, 2);
+	# Give up after three characters
+	if ($partitionstart le $lastpartitionend) {
+	    $partitionstart = substr($metadata_value, 0, 3);
+	}
+    }
+
+    return $partitionstart;
+}
+
+
+sub generate_partition_end
+{
+    my $self = shift(@_);
+    my $metadata_value = shift(@_);
+    my $partitionstart = shift(@_);
+    my $partition_name_length = shift(@_);
+
+    if ($partition_name_length) {
+	return substr($metadata_value, 0, $partition_name_length);
+    }
+
+    my $partitionend = substr($metadata_value, 0, length($partitionstart));
+    if ($partitionend gt $partitionstart) {
+	$partitionend = substr($metadata_value, 0, 1);
+	if ($partitionend le $partitionstart) {
+	    $partitionend = substr($metadata_value, 0, 2);
+	    # Give up after three characters
+	    if ($partitionend le $partitionstart) {
+		$partitionend = substr($metadata_value, 0, 3);
+	    }
+	}
+    }
+
+    return $partitionend;
+}
+
+
+sub add_hlist_partition
+{
+    my $self = shift(@_);
+    my @metadata_groups = @{shift(@_)};
+    my $classifier_node = shift(@_);
+    my $partitionname = shift(@_);
+    my $metadata_value_to_OIDs_hash_ref = shift(@_);
+
+    # Create an hlist partition
+    my %child_classifier_node = ( 'Title' => $self->convert_unicode_string_to_utf8_string($partitionname),
+				  'childtype' => "VList",
+				  'contains' => [] );
+
+    # Add the children to the hlist partition
+    $self->add_vlist(\@metadata_groups, \%child_classifier_node, $metadata_value_to_OIDs_hash_ref);
+    push(@{$classifier_node->{'contains'}}, \%child_classifier_node);
+}
+
+
+sub add_vlist
+{
+    my $self = shift(@_);
+    my @metadata_groups = @{shift(@_)};
+    my $classifier_node = shift(@_);
+    my $metadata_value_to_OIDs_hash_ref = shift(@_);
+
+    my $metadata_group = shift(@metadata_groups);
+    $classifier_node->{'mdtype'} = $metadata_group;
+
+    # Create an entry in the vlist for each value
+    foreach my $metadata_value ($self->sort_metadata_values_array(keys(%{$metadata_value_to_OIDs_hash_ref})))
+    {
+	my @OIDs = @{$metadata_value_to_OIDs_hash_ref->{$metadata_value}};
+
+	# If there is only one item and 'bookshelf_type' is not always (ie. never or duplicate_only), add the item to the list
+	if (@OIDs == 1 && $self->{$metadata_group . ".bookshelf_type"} ne "always") {
+	    my $OID = $OIDs[0];
+
+	    # Find the offset of this metadata value
+	    my $offset = 0;
+	    my $OID_to_metadata_values_hash_ref = $self->{$metadata_group . ".list"};
+	    my @metadata_values = @{$OID_to_metadata_values_hash_ref->{$OID}};
+	    for (my $i = 0; $i < scalar(@metadata_values); $i++) {
+		if ($metadata_value eq $metadata_values[$i]) {
+		    $offset = $i;
+		    last;
+		}
+	    }
+	    push(@{$classifier_node->{'contains'}}, { 'OID' => $OID, 'offset' => $offset });
+	} 
+	# If 'bookshelf_type' is 'never', list all the items even if there are duplicated values
+	elsif ($self->{$metadata_group . ".bookshelf_type"} eq "never") {
+	   $self->add_sorted_leaf_items(\@OIDs, $classifier_node); 
+	}
+	# Otherwise create a sublist (bookshelf) for the metadata value
+	else {		    
+	    my %child_classifier_node = ( 'Title' => $self->convert_unicode_string_to_utf8_string($metadata_value),
+					  'childtype' => "VList",
+					  'contains' => [] );
+
+	    # If there are metadata elements remaining, recursively apply the process
+	    if (@metadata_groups > 0) {
+		my $next_metadata_group = $metadata_groups[0];
+		$child_classifier_node{'childtype'} = $self->{$next_metadata_group . ".list_type"};
+		$self->add_level(\@metadata_groups, \@OIDs, \%child_classifier_node);
+	    }
+	    # Otherwise just add the documents as children of this list
+	    else {
+		$self->add_sorted_leaf_items(\@OIDs, \%child_classifier_node); 
+	    }
+
+	    # Add the sublist to the list
+	    push(@{$classifier_node->{'contains'}}, \%child_classifier_node);
+	}
+    }
+}
+
+sub add_sorted_leaf_items
+{
+    my $self = shift(@_);
+    my @OIDs = @{shift(@_)};
+    my $classifier_node = shift(@_);    
+    
+    # Sort leaf nodes and add to list
+    my @sort_leaf_nodes_usingmetadata_groups = @{$self->{'sort_leaf_nodes_using_metadata_groups'}};
+    foreach my $sort_leaf_nodes_usingmetaelem (reverse @sort_leaf_nodes_usingmetadata_groups) {
+	my $OID_to_metadata_values_hash_ref = $self->{$sort_leaf_nodes_usingmetaelem . ".list"};
+	# Force a stable sort (Perl 5.6's sort isn't stable)
+	# !! The [0] bits aren't ideal (multiple metadata values) !! 
+	@OIDs = @OIDs[ sort { $OID_to_metadata_values_hash_ref->{$OIDs[$a]}[0] cmp $OID_to_metadata_values_hash_ref->{$OIDs[$b]}[0] || $a <=> $b; } 0..$#OIDs ];
+    }
+
+    foreach my $OID (@OIDs) {
+	push(@{$classifier_node->{'contains'}}, { 'OID' => $OID });
+    }
+}
+
+
+sub sort_metadata_values_array
+{
+    my $self = shift(@_);
+    my @metadata_values = @_;
+
+    if ($self->{'unicode_collator'}) {
+	return $self->{'unicode_collator'}->sort(@metadata_values);
+    }
+    else {
+	return sort(@metadata_values);
+    }
+}
+
+
+1;
Index: /gsdl/stable/perllib/classify/Phind.pm
===================================================================
--- /gsdl/stable/perllib/classify/Phind.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/Phind.pm	(revision 20131)
@@ -0,0 +1,1509 @@
+###########################################################################
+#
+# Phind.pm -- the Phind classifier
+#
+# Copyright (C) 2000 Gordon W. Paynter
+# Copyright (C) 2000 New Zealand Digital Library Project
+#
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# The Phind clasifier plugin. 
+# Type "classinfo.pl Phind" at the command line for a summary.
+
+# 12/05/02 Added usage datastructure - John Thompson
+
+package Phind;
+
+use BaseClassifier;
+use util;
+use ghtml;
+use unicode;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+my @removedirs = ();
+
+my %wanted_index_files = ('td'=>1,
+			  't'=>1,
+			  'ti'=>1,
+			  'tl'=>1,
+			  'tsd'=>1,
+			  'idb'=>1,
+			  'ib1'=>1,
+			  'ib2'=>1,
+			  'ib3'=>1,
+			  'i'=>1,
+			  'il'=>1,
+			  'w'=>1,
+			  'wa'=>1);
+
+sub BEGIN {
+    @Phind::ISA = ('BaseClassifier');
+}
+
+sub END {
+    
+    # Tidy up stray files - we do this here as there's some weird problem
+    # preventing us from doing it in the get_classify_info() function (on
+    # windows at least) where the close() appears to fail on txthandle and
+    # dochandle, thus preventing us from deleting those files
+
+    foreach my $dir (@removedirs) {
+	if (-d $dir && opendir (DIR, $dir)) {
+	    my @files = readdir DIR;
+	    closedir DIR;
+	
+	    foreach my $file (@files) {
+		next if $file =~ /^\.\.?$/;
+		my ($suffix) = $file =~ /\.([^\.]+)$/;
+		if (!defined $suffix || !defined $wanted_index_files{$suffix}) {
+		    # delete it!
+		    &util::rm (&util::filename_cat ($dir, $file));
+		}
+	    }
+	}
+    }
+}
+
+my $arguments =
+    [ { 'name' => "text",
+	'desc' => "{Phind.text}",
+	'type' => "string",
+	'deft' => "section:Title,section:text",
+	'reqd' => "no" },
+      { 'name' => "title",
+	'desc' => "{Phind.title}",
+	'type' => "metadata",
+	'deft' => "Title",
+	'reqd' => "no" },
+      { 'name' => "buttonname",
+	'desc' => "{BasClas.buttonname}",
+	'type' => "string",
+	'deft' => "Phrase",
+	'reqd' => "no" },
+      { 'name' => "language",
+	'desc' => "{Phind.language}",
+	'type' => "string",
+	'deft' => "en",
+	'reqd' => "no" },
+      { 'name' => "savephrases",
+	'desc' => "{Phind.savephrases}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "suffixmode",
+	'desc' => "{Phind.suffixmode}",
+	'type' => "int",
+	'deft' => "1",
+	'range' => "0,1",
+	'reqd' => "no" },
+      { 'name' => "min_occurs",
+	'desc' => "{Phind.min_occurs}",
+	'type' => "int",
+	'deft' => "2",
+	'range' => "1,",
+	'reqd' => "no" },
+      { 'name' => "thesaurus",
+	'desc' => "{Phind.thesaurus}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "untidy",
+	'desc' => "{Phind.untidy}",
+	'type' => "flag",
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "Phind",
+		'desc'     => "{Phind.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+# Phrase delimiter symbols - these should be abstracted out someplace
+
+my $colstart = "COLLECTIONSTART";
+my $colend   = "COLLECTIONEND";
+my $doclimit = "DOCUMENTLIMIT";
+my $senlimit = "SENTENCELIMIT";
+my @delimiters = ($colstart, $colend, $doclimit, $senlimit);
+
+
+# Create a new Phind browser based on collect.cfg
+
+sub new {
+    my ($class) = shift (@_);
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseClassifier($classifierslist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    # Ensure the Phind generate scripts are in place
+    my $file1 = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "suffix");
+    $file1 .= ".exe" if $ENV{'GSDLOS'} =~ /^windows$/;
+    my $src = &util::filename_cat($ENV{'GSDLHOME'}, "src", "phind", "generate");
+    if (!(-e $file1)) {
+	print STDERR "Phind.pm: ERROR: The Phind \"suffix\" program is not installed.\n\n";
+	exit(1);
+    }
+    
+    # Transfer value from Auto Parsing to the variable name that used in previous GreenStone.
+    $self->{"indexes"} = $self->{"text"};
+
+    # Further setup
+    $self->{'collection'} = $ENV{'GSDLCOLLECTION'}; # classifier information
+    $self->{'collectiondir'} = $ENV{'GSDLCOLLECTDIR'}; # collection directories
+    if (! defined $self->{'builddir'}) {
+	$self->{'builddir'} = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "building");
+    } 
+    $self->{'total'} = 0;
+    
+    # Clean out the unused keys
+    delete $self->{"text"};
+
+    return bless $self, $class;
+}
+
+
+# Initialise the Phind classifier
+
+sub init {
+    my $self = shift (@_);
+
+    # ensure we have a build directory
+    my $builddir = $self->{'builddir'};
+    die unless (-e "$builddir");
+
+    # create Phind directory
+    my $phnumber = 1;
+    my $phinddir = &util::filename_cat($builddir, "phind1");
+    while (-e "$phinddir") {
+	$phnumber++;
+	$phinddir = &util::filename_cat($builddir, "phind$phnumber");
+    }
+    &util::mk_dir("$phinddir");
+    $self->{'phinddir'} = $phinddir;
+    $self->{'phindnumber'} = $phnumber;
+
+    push(@removedirs, $phinddir) unless $self->{'untidy'};
+
+    # open filehandles for documents and text
+    my $clausefile =  &util::filename_cat("$phinddir", "clauses");
+    &util::rm($clausefile) if (-e $clausefile);
+
+    my $txthandle = 'TEXT' . $phnumber;
+    open($txthandle, ">$clausefile") || die "Cannot open $clausefile: $!";
+    $self->{'txthandle'} = $txthandle;
+
+    my $docfile = &util::filename_cat("$phinddir", "docs.txt");
+    &util::rm($docfile) if (-e $docfile);
+
+    my $dochandle = 'DOC' . $phnumber;
+    open($dochandle, ">$docfile") || die "Cannot open $docfile: $!";
+    $self->{'dochandle'} = $dochandle;
+    
+}
+
+
+# Classify each document.
+#
+# Each document is passed here in turn.  The classifier extracts the 
+# text of each and stores it in the clauses file.  Document details are
+# stored in the docs.txt file. 
+
+sub classify {
+    my $self = shift (@_);
+    my ($doc_obj,$edit_mode) = @_;
+
+    my $verbosity = $self->{'verbosity'};
+    my $top_section = $doc_obj->get_top_section();
+
+    my $titlefield = $self->{'title'};
+    
+    my $title = $doc_obj->get_metadata_element ($top_section, $titlefield);
+    if (!defined($title)) {
+	$title = "";
+	print STDERR "Phind: document has no title\n";
+    }
+    print "process: $title\n" if ($verbosity > 2);
+
+    # Only consider the file if it is in the correct language
+    my $doclanguage = $doc_obj->get_metadata_element ($top_section, "Language");
+    my $phrlanguage = $self->{'language'};
+    return if ($doclanguage && ($doclanguage !~ /$phrlanguage/i));
+
+    if ($edit_mode eq "delete") {
+	# This classifier works quite differently to the others
+	# Probably doesn't support incremental building anyway
+	return;
+    }
+
+    # record this file
+    $self->{'total'} ++;
+    # what is $file ???
+    # print "file $self->{'total'}: $file\n" if ($self->{'$verbosity'});
+
+    # Store document details
+    my $OID = $doc_obj->get_OID();
+    $OID = "NULL" unless defined $OID;
+    my $dochandle = $self->{'dochandle'};
+    print $dochandle "<Document>\t$OID\t$title\n";
+    
+    # Store the text occuring in this object
+
+    # output the document delimiter
+    my $txthandle = $self->{'txthandle'};
+    print $txthandle "$doclimit\n";
+
+    # iterate over the required indexes and store their text
+    my $indexes = $self->{'indexes'};
+    my $text = "";
+    my ($part, $level, $field, $section, $data, $dataref);
+
+    foreach $part (split(/,/, $indexes)) {
+
+	# Each field has a level and a data element ((e.g. document:Title)
+	($level, $field) = split(/:/, $part);
+	die unless ($level && $field);
+	
+	# Extract the text from every section
+	# (In phind, document:text and section:text are equivalent)
+	if ($field eq "text") {
+	    $data = "";
+	    $section = $doc_obj->get_top_section();
+	    while (defined($section)) {
+		$data .= $doc_obj->get_text($section) . "\n";
+		$section = $doc_obj->get_next_section($section);
+	    }
+	    $text .= convert_gml_to_tokens($phrlanguage, $data) . "\n";
+	}
+	
+	# Extract a metadata field from a document
+	# (If there is more than one element of the given type, get them all.)
+	elsif ($level eq "document") {
+	    $dataref = $doc_obj->get_metadata($doc_obj->get_top_section(), $field);
+	    foreach $data (@$dataref) {
+		$text .= convert_gml_to_tokens($phrlanguage, $data) . "\n";
+	    } 
+	}
+
+	# Extract metadata from every section in a document
+	elsif ($level eq "section") {
+	    $data = "";
+	    $section = $doc_obj->get_top_section();
+	    while (defined($section)) {
+		$dataref = $doc_obj->get_metadata($section, $field);
+		$data .= join("\n", @$dataref) . "\n";
+		$section = $doc_obj->get_next_section($section);
+	    }
+	    $text .= convert_gml_to_tokens($phrlanguage, $data) . "\n";
+	} 
+	
+	# Some sort of specification which I don't understand
+	else {
+	    die "Unknown level ($level) in Phind index ($part)\n";
+	}
+	
+    }
+
+    # output the text
+    $text =~ tr/\n//s;
+    print $txthandle "$text";
+}
+
+
+# Construct the classifier from the information already gathered
+#
+# When get_classify_info is called, the clauses and docs.txt files have
+# already been constructed in the Phind directory.  This function will
+# translate them into compressed, indexed MGPP files that can be read by
+# the phindcgi script.  It will also register our classifier so that it
+# shows up in the navigation bar.
+
+sub get_classify_info {
+    my $self = shift (@_);
+    my ($gli) = @_;    
+
+    close $self->{'dochandle'};
+    close $self->{'txthandle'};
+    my $verbosity = $self->{'verbosity'};
+    my $out = $self->{'outhandle'};
+    my $phinddir = $self->{'phinddir'};
+
+    my $osextra = "";
+    if ($ENV{'GSDLOS'} !~ /^windows$/i) {
+	$osextra = " -d /";
+    }
+
+    print STDERR "</Stage>\n" if $gli;
+
+    if ($verbosity) {
+	print $out "\n*** Phind.pm generating indexes for ", $self->{'indexes'}, "\n";
+	print $out "***          in ", $self->{'phinddir'}, "\n";
+    }
+
+    print STDERR "<Stage name='Phind'>\n" if $gli;
+
+    # Construct phind indexes
+    my $suffixmode = $self->{'suffixmode'};
+    my $min_occurs = $self->{'min_occurs'};
+    my ($command, $status);
+    
+    # Generate the vocabulary, symbol statistics, and numbers file
+    # from the clauses file
+    print $out "\nExtracting vocabulary and statistics\n" if $verbosity;
+    print STDERR "<Phase name='ExtractingVocab'/>\n" if $gli;
+    &extract_vocabulary($self);
+ 
+    # Use the suffix program to generate the phind/phrases file
+    print $out "\nExtracting phrases from processed text (with suffix)\n" if $verbosity;
+    print STDERR "<Phase name='ExtractingPhrase'/>\n" if $gli;
+    &execute("suffix \"$phinddir\" $suffixmode $min_occurs $verbosity", $verbosity, $out);
+
+    # check that we generated some files. It's not necessarily an error if
+    # we didn't (execute() would have quit on error), but we can't go on.
+    my $phrasesfile=&util::filename_cat($self->{'phinddir'}, 'phrases');
+    if (! -r $phrasesfile) {
+	print STDERR "<Warning name='NoPhrasesFound'/>\n" if $gli;
+	print $out "\nNo phrases found for Phind classifier!\n";
+	return;
+    }   
+
+    # Create the phrase file and put phrase numbers in phind/phrases
+    print $out "\nSorting and renumbering phrases for input to mgpp\n" if $verbosity;
+    print STDERR "<Phase name='SortAndRenumber'/>\n" if $gli;
+    &renumber_phrases($self);
+
+    print $out "\nCreating phrase databases\n";
+    print STDERR "<Phase name='PhraseDatabases'/>\n" if $gli;
+    my $mg_input = &util::filename_cat($phinddir, "pdata.txt");
+    my $mg_stem = &util::filename_cat($phinddir, "pdata");
+
+    &execute("mgpp_passes $osextra -f \"$mg_stem\" -T1 \"$mg_input\"", $verbosity, $out);
+    &execute("mgpp_compression_dict $osextra -f \"$mg_stem\"", $verbosity, $out);
+    &execute("mgpp_passes $osextra -f \"$mg_stem\" -T2 \"$mg_input\"", $verbosity, $out);
+
+    # create the mg index of words
+    print $out "\nCreating word-level search indexes\n";
+    print STDERR "<Phase name='WordLevelIndexes'/>\n" if $gli;
+    $mg_input = &util::filename_cat($phinddir, "pword.txt");
+    $mg_stem = &util::filename_cat($phinddir, "pword");
+
+    &execute("mgpp_passes $osextra -f \"$mg_stem\" -T1 -I1 \"$mg_input\"", $verbosity, $out);
+    &execute("mgpp_compression_dict $osextra -f \"$mg_stem\"", $verbosity, $out);
+    &execute("mgpp_perf_hash_build $osextra -f \"$mg_stem\"", $verbosity, $out);
+    &execute("mgpp_passes $osextra -f \"$mg_stem\" -T2 -I2 \"$mg_input\"", $verbosity, $out);
+    &execute("mgpp_weights_build $osextra -f \"$mg_stem\"", $verbosity, $out);
+    &execute("mgpp_invf_dict $osextra -f \"$mg_stem\"", $verbosity, $out);
+
+    &execute("mgpp_stem_idx $osextra -f \"$mg_stem\" -s 1", $verbosity, $out);
+    &execute("mgpp_stem_idx $osextra -f \"$mg_stem\" -s 2", $verbosity, $out);
+    &execute("mgpp_stem_idx $osextra -f \"$mg_stem\" -s 3", $verbosity, $out);
+
+    # create the mg document information database
+    print $out "\nCreating document information databases\n";
+    print STDERR "<Phase name='DocInfoDatabases'/>\n" if $gli;
+    $mg_input = &util::filename_cat($phinddir, "docs.txt");
+    $mg_stem = &util::filename_cat($phinddir, "docs");
+
+    &execute("mgpp_passes $osextra -f \"$mg_stem\" -T1 \"$mg_input\"", $verbosity, $out);
+    &execute("mgpp_compression_dict $osextra -f \"$mg_stem\"", $verbosity, $out);
+    &execute("mgpp_passes $osextra -f \"$mg_stem\" -T2 \"$mg_input\"", $verbosity, $out);
+
+    # Return the information about the classifier that we'll later want to
+    # use to create macros when the Phind classifier document is displayed.
+    my %classifyinfo = ('thistype'=>'Invisible',
+                        'childtype'=>'Phind', 
+                        'Title'=>$self->{'buttonname'},
+                        'parameters'=>"phindnumber=$self->{'phindnumber'}",
+			'contains'=>[]);
+    
+    my $collection = $self->{'collection'};
+    my $url = "library?a=p&p=phind&c=$collection";
+    push (@{$classifyinfo{'contains'}}, {'OID'=>$url});
+   
+    return \%classifyinfo;
+}
+
+
+
+sub convert_gml_to_tokens {
+    
+    my ($language_exp, $text) = @_;
+
+    # escape any magic words... - jrm21
+    foreach my $delim (@delimiters) {
+	my $replacement=lc($delim);
+	my $num= $text=~ s/$delim/$replacement/g;
+	if (!$num) {$num=0;}
+    }
+
+    if ($language_exp =~ /en/) {
+	return &convert_gml_to_tokens_EN($text);
+    }
+
+    if ($language_exp =~ /zh/) {
+	return &convert_gml_to_tokens_ZH($text);
+    }  
+    
+    $_ = $text;
+
+    # 1. remove GML tags
+
+    # Remove everything that is in a tag
+    s/\s*<p>\s*/ PARAGRAPHBREAK /isgo;
+    s/\s*<br>\s*/ LINEBREAK /isgo;
+    s/<[^>]*>/ /sgo;
+
+    # Now we have the text, but it may contain HTML 
+    # elements coded as &gt; etc.  Remove these tags. 
+    s/&amp;/&/sgo;
+    s/&lt;/</sgo;
+    s/&gt;/>/sgo;
+    s/\s*<p>\s*/ PARAGRAPHBREAK /isgo;
+    s/\s*<br>\s*/ LINEBREAK /isgo;
+    s/<[^>]*>/ /sgo;
+
+    # replace<p> and <br> placeholders with clause break symbol (\n)
+    s/\s+/ /gso;
+    s/PARAGRAPHBREAK/\n/sgo;
+    s/LINEBREAK/\n/sgo;
+
+    
+
+
+    # 2. Split the remaining text into space-delimited tokens
+
+    # Convert any HTML special characters (like &quot;) to their UTF8 equivalent
+    s/&([^;]+);/&unicode::ascii2utf8(\&ghtml::getcharequiv($1,1))/gse;
+
+    # Split text at word boundaries
+    s/\b/ /go;
+
+    # 3. Convert the remaining text to "clause format"
+
+    # Insert newline if the end of a sentence is detected
+    # (delimter is:  "[\.\?\!]\s")
+    # s/\s*[\.\?\!]\s+/\n/go; 
+
+    # remove unnecessary punctuation and replace with clause break symbol (\n)
+    s/[^\w ]/\n/go;
+
+    # remove extraneous whitespace
+    s/ +/ /sgo;
+    s/^\s+//mgo;
+    s/\s*$/\n/mgo;
+
+    # remove lines that contain one word or less
+    s/^\S*$//mgo;
+    s/^\s*$//mgo;
+    tr/\n//s;
+
+    return $_;
+}
+
+# a chinese version
+sub convert_gml_to_tokens_ZH {
+
+    $_ = shift @_;
+
+    # Replace all whitespace with a simple space
+    s/\s+/ /gs;
+    # Remove everything that is in a tag
+    s/\s*<p>\s*/ PARAGRAPHBREAK /isg;
+    s/\s*<br>\s*/ LINEBREAK /isg;
+    s/<[^>]*>/ /sg;
+
+    # Now we have the text, but it may contain HTML 
+    # elements coded as &gt; etc.  Remove these tags. 
+    s/&lt;/</sg;
+    s/&gt;/>/sg;
+
+    s/\s+/ /sg;
+    s/\s*<p>\s*/ PARAGRAPHBREAK /isg;
+    s/\s*<br>\s*/ LINEBREAK /isg;
+    s/<[^>]*>/ /sg;
+
+    # remove &amp; and other miscellaneous markup tags
+    s/&amp;/&/sg;
+    s/&lt;/</sg;
+    s/&gt;/>/sg;
+    s/&amp;/&/sg;
+
+    # replace<p> and <br> placeholders with carriage returns
+    s/PARAGRAPHBREAK/\n/sg;
+    s/LINEBREAK/\n/sg;
+
+    
+#    print STDERR "text:$_\n";
+    return $_;
+}
+
+# A version of convert_gml_to_tokens that is fine-tuned to the English language.
+
+sub convert_gml_to_tokens_EN {
+    $_ = shift @_;
+
+    # FIRST, remove GML tags
+
+    # Replace all whitespace with a simple space
+    s/\s+/ /gs;
+
+    # Remove everything that is in a tag
+    s/\s*<p>\s*/ PARAGRAPHBREAK /isg;
+    s/\s*<br>\s*/ LINEBREAK /isg;
+    s/<[^>]*>/ /sg;
+
+    # Now we have the text, but it may contain HTML 
+    # elements coded as &gt; etc.  Remove these tags. 
+    s/&lt;/</sg;
+    s/&gt;/>/sg;
+
+    s/\s+/ /sg;
+    s/\s*<p>\s*/ PARAGRAPHBREAK /isg;
+    s/\s*<br>\s*/ LINEBREAK /isg;
+    s/<[^>]*>/ /sg;
+
+    # remove &amp; and other miscellaneous markup tags
+    s/&amp;/&/sg;
+    s/&lt;/</sg;
+    s/&gt;/>/sg;
+    s/&amp;/&/sg;
+
+    # replace<p> and <br> placeholders with carriage returns
+    s/PARAGRAPHBREAK/\n/sg;
+    s/LINEBREAK/\n/sg;
+
+
+    # Exceptional punctuation
+    # 
+    # We make special cases of some punctuation
+
+    # remove any apostrophe that indicates omitted letters 
+    s/(\w+)\'(\w*\s)/ $1$2 /g;
+
+    # remove period that appears in a person's initals
+    s/\s([A-Z])\./ $1 /g;
+
+    # replace hyphens in hypheanted words and names with a space
+    s/([A-Za-z])-\s*([A-Za-z])/$1 $2/g;
+
+    # Convert the remaining text to "clause format",
+    # This means removing all excess punctuation and garbage text,
+    # normalising valid punctuation to fullstops and commas,
+    # then putting one cluse on each line.
+
+    # Insert newline when the end of a sentence is detected
+    # (delimter is:  "[\.\?\!]\s")
+    s/\s*[\.\?\!]\s+/\n/g; 
+
+    # split numbers after four digits
+    s/(\d\d\d\d)/$1 /g;
+
+    # split words after 32 characters
+
+    # squash repeated punctuation 
+    tr/A-Za-z0-9 //cs;
+
+    # save email addresses
+    # s/\w+@\w+\.[\w\.]+/EMAIL/g;
+
+    # normalise clause breaks (mostly punctuation symbols) to commas
+    s/[^A-Za-z0-9 \n]+/ , /g;
+
+    # Remove repeated commas, and replace with newline
+    s/\s*,[, ]+/\n/g;
+
+    # remove extra whitespace
+    s/ +/ /sg;
+    s/^\s+//mg;
+    s/\s*$/\n/mg;
+
+    # remove lines that contain one word or less
+    s/^\w*$//mg;
+    s/^\s*$//mg;
+    tr/\n//s;
+
+    return $_;
+
+}
+
+
+
+# Execute a system command
+
+sub execute {
+    my ($command, $verbosity, $outhandle) = @_;
+    print $outhandle "Executing: $command\n"  if ($verbosity > 2);
+    $! = 0;
+    my $status = system($command);
+    if ($status != 0) {
+	print STDERR "Phind - Error executing '$command': $!\n";
+	exit($status);  # this causes the build to fail... 
+    }
+}
+
+
+# Generate the vocabulary, symbol statistics, and numbers file from the
+# clauses file.  This is legacy code, so is a bit messy and probably wont
+# run under windows.
+
+sub extract_vocabulary {
+    my ($self) = @_;
+    
+    my $verbosity = $self->{'verbosity'};
+    my $out = $self->{'outhandle'};
+
+    my $collectiondir = $self->{'collectiondir'};
+    my $phinddir = $self->{'phinddir'};
+
+    my $language_exp = $self->{'language'};
+
+    my ($w, $l, $line, $word);
+    
+    my ($first_delimiter, $last_delimiter,
+	$first_stopword, $last_stopword,
+	$first_extractword, $last_extractword,
+	$first_contentword, $last_contentword,
+	$phrasedelimiter);
+    
+    my $thesaurus = $self->{'thesaurus'};
+    my ($thesaurus_links, $thesaurus_terms, 
+	%thesaurus, $first_thesaurusword, $last_thesaurusword);
+
+    my %symbol;
+    my (%freq);
+
+    print $out "Calculating vocabulary\n" if ($verbosity > 1);
+
+    # Read and store the stopwords
+    my $stopdir = &util::filename_cat($ENV{'GSDLHOME'}, "etc", "packages", "phind", "stopword");
+    my $stopword_files = ();
+    my ($language, $language_dir, $file, $file_name);
+    my %stopwords;
+
+    # Examine each directory in the stopword directory
+    opendir(STOPDIR, $stopdir);
+    foreach $language (readdir STOPDIR) {
+
+	# Ignore entries that do not match the classifier's language
+	next unless ($language =~ /$language_exp/);
+	$language_dir = &util::filename_cat($stopdir, $language);
+	next unless (-d "$language_dir");
+
+	opendir(LANGDIR, $language_dir);
+	foreach $file (readdir LANGDIR) {
+
+	    # Ignore entries that are not stopword files
+	    next unless ($file =~ /sw$/);
+	    $file_name = &util::filename_cat($language_dir, $file);
+	    next unless (-f "$file_name");
+
+	    # Read the stopwords
+	    open(STOPFILE, "<$file_name");
+	    while (<STOPFILE>) {
+		s/^\s+//;
+		s/\s.*//;
+		$word = $_;
+		$l = lc($word);
+		$stopwords{$l} = $word;
+	    }
+	    close STOPFILE;
+
+	}
+	closedir LANGDIR;
+    }
+    closedir STOPDIR;
+
+    # Read thesaurus information
+    if ($thesaurus) {
+
+	# link file exists
+	$thesaurus_links = &util::filename_cat($collectiondir, "etc", "$thesaurus.lnk");
+	die "Cannot find thesaurus link file" unless (-e "$thesaurus_links");
+
+	# ensure term file exists in the correct language
+	if ($language_exp =~ /^([a-z][a-z])/) {
+	    $language = $1;
+	} else {
+	    $language = 'en';
+	}
+	$thesaurus_terms = &util::filename_cat($collectiondir, "etc", "$thesaurus.$language");
+	die "Cannot find thesaurus term file" unless (-e "$thesaurus_terms");
+	
+
+	# Read the thesaurus terms
+	open(TH, "<$thesaurus_terms");
+	while(<TH>) {
+	    s/^\d+ //;
+	    s/\(.*\)//;
+	    foreach $w (split(/\s+/, $_)) {
+		$thesaurus{lc($w)} = $w;
+	    }
+	}
+	close TH;
+    }
+
+    # Read words in the text and count occurences
+    open(TXT, "<$phinddir/clauses");
+
+    my @words;
+    while(<TXT>) {
+	$line = $_;
+	next unless ($line =~ /./);
+	
+	@words = split(/\s+/, $line);
+	foreach $w (@words) {
+	    $l = lc($w);
+	    $w = $l if ((defined $stopwords{$l}) || (defined $thesaurus{$l}));
+	    $freq{$w}++;
+	}
+	$freq{$senlimit}++;
+    }
+    
+    close TXT;
+
+    # Calculate the "best" form of each word
+    my (%bestform, %totalfreq, %bestfreq);
+
+    foreach $w (sort (keys %freq)) {
+	$l = lc($w);
+	
+	# totalfreq is the number of times a term appears in any form
+	$totalfreq{$l} += $freq{$w};
+	
+	if (defined $stopwords{$l}) {
+	    $bestform{$l} = $stopwords{$l};
+	    
+	} elsif (defined $thesaurus{$l}) {
+	    $bestform{$l} = $thesaurus{$l};
+	    
+	} elsif (!$bestform{$l} || ($freq{$w} > $bestfreq{$l})) {
+	    $bestfreq{$l} = $freq{$w};
+	    $bestform{$l} = $w;
+	}
+    }
+    undef %freq;
+    undef %bestfreq;
+    
+
+    # Assign symbol numbers to tokens
+    my $nextsymbol = 1;
+    my (@vocab);
+    
+    # Delimiters
+    $first_delimiter = 1;
+    
+    foreach $word (@delimiters) {
+
+#	$word = lc($word); # jrm21
+	$word = uc($word);
+	$bestform{$word} = $word;
+	$vocab[$nextsymbol] = $word;
+	$symbol{$word} = $nextsymbol;
+	$nextsymbol++;
+    }
+    $last_delimiter = $nextsymbol - 1;
+    # Stopwords
+    $first_stopword = $nextsymbol;
+    
+    foreach my $word (sort keys %stopwords) {
+	# don't include stopword unless it occurs in the text
+	$word = lc($word);
+	next unless ($totalfreq{$word});
+	next if ($symbol{$word});
+	
+	$vocab[$nextsymbol] = $word;
+	$symbol{$word} = $nextsymbol;
+	$nextsymbol++;
+    }
+    $last_stopword = $nextsymbol - 1;
+    $first_contentword = $nextsymbol;
+    
+    # Thesaurus terms
+    if ($thesaurus) {
+	$first_thesaurusword = $nextsymbol;
+    
+	foreach my $word (sort keys %thesaurus) {
+	    
+	    $word = lc($word);
+	    next if ($symbol{$word});
+	    $bestform{$word} = $thesaurus{$word};
+	    
+	    $vocab[$nextsymbol] = $word;
+	    $symbol{$word} = $nextsymbol;
+	    $nextsymbol++;
+	    
+	}
+	$last_thesaurusword = $nextsymbol - 1;
+    }
+
+    # Other content words
+    $first_extractword = $nextsymbol;
+    
+    foreach my $word (sort (keys %bestform)) {
+	
+	next if ($symbol{$word});
+	
+	$vocab[$nextsymbol] = $word;
+	$symbol{$word} = $nextsymbol;
+	$nextsymbol++;
+    }
+    $last_extractword = $nextsymbol - 1;
+    $last_contentword = $nextsymbol - 1;
+    
+    # Outut the words
+    print $out "Saving vocabulary in $phinddir/clauses.vocab\n" if ($verbosity > 1);
+    open(VOC, ">$phinddir/clauses.vocab");
+
+    for (my $i = 1; $i < $nextsymbol; $i++) {
+	$w = $vocab[$i];
+
+	print VOC "$bestform{$w}\n";
+	$totalfreq{$w} = 0 unless ($totalfreq{$w});
+    }
+    close VOC;
+
+
+    # Create statistics file
+    # Output statistics about the vocablary
+    print $out "Saving statistics in $phinddir/clauses.stats\n" if ($verbosity > 1);
+    &util::rm("$phinddir/clauses.stats") if (-e "$phinddir/clauses.stats");
+
+    open(STAT, ">$phinddir/clauses.stats")
+	|| die "Cannot open $phinddir/clauses.stats: $!";
+
+    print STAT "first_delimiter $first_delimiter\n";
+    print STAT "last_delimiter $last_delimiter\n";
+    print STAT "first_stopword $first_stopword\n";
+    print STAT "last_stopword $last_stopword\n";
+    if ($thesaurus) {
+	print STAT "first_thesaurusword $first_thesaurusword\n";
+	print STAT "last_thesaurusword $last_thesaurusword\n";
+    }
+    print STAT "first_extractword $first_extractword\n";
+    print STAT "last_extractword $last_extractword\n";
+    print STAT "first_contentword $first_contentword\n";
+    print STAT "last_contentword $last_contentword\n";
+    print STAT "first_symbol $first_delimiter\n";
+    print STAT "last_symbol $last_contentword\n";
+    print STAT "first_word $first_stopword\n";
+    print STAT "last_word $last_contentword\n";
+    close STAT;
+
+    undef @vocab;
+
+
+    # Create numbers file
+    # Save text as symbol numbers
+    print $out "Saving text as numbers in $phinddir/clauses.numbers\n" if ($verbosity > 1);
+    
+    open(TXT, "<$phinddir/clauses");
+    open(NUM, ">$phinddir/clauses.numbers");
+    
+##    $phrasedelimiter = $symbol{lc($senlimit)}; # jrm21
+##    print NUM "$symbol{lc($colstart)}\n"; # jrm21
+    $phrasedelimiter = $symbol{$senlimit};
+    print NUM "$symbol{$colstart}\n";
+    
+    # set up the special symbols that delimit documents and sentences
+    while(<TXT>) {
+	
+	# split sentence into a list of tokens
+	$line = $_;
+	next unless ($line =~ /./);
+	@words = split(/\s+/, $line);
+	
+	# output one token at a time
+	foreach $word (@words) {
+# don't lower-case special delimiters - jrm21
+	    if (!map {if ($word eq $_) {1} else {()}} @delimiters) {
+		$word = lc($word);
+	    }
+	    print NUM "$symbol{$word}\n";
+	}
+	
+	# output phrase delimiter
+	print NUM "$phrasedelimiter\n";
+    }
+    
+    close TXT;
+#    print NUM "$symbol{lc($colend)}\n";# jrm21
+    print NUM "$symbol{$colend}\n";
+    close NUM;
+
+    # Save thesaurus  data in one convienient file
+    if ($thesaurus) {
+
+	my $thesaurusfile = &util::filename_cat($phinddir, "$thesaurus.numbers");
+
+
+	print $out "Saving thesaurus as numbers in $thesaurusfile\n" 
+	    if ($verbosity > 1);
+
+	# Read the thesaurus terms
+	my ($num, $text, %thes_symbols);
+	
+	open(TH, "<$thesaurus_terms");
+	while(<TH>) {
+	    chomp;
+	    @words = split(/\s+/, $_);
+	    $num = shift @words;
+	    $text = "";
+
+	    # translate words into symbol numbers
+	    foreach $word (@words) {
+		$word = lc($word);
+		if ($symbol{$word}) {
+		    $text .= "s$symbol{$word} ";
+		} elsif ($verbosity) {
+		    print $out "Phind: No thesaurus symbol, ignoring \"$word\"\n";
+		}
+	    }
+	    $text =~ s/ $//;
+	    $thes_symbols{$num} = $text;
+	}
+	close TH;
+
+	# Read the thesaurus links and write the corresponding data
+	open(TH, "<$thesaurus_links");
+	open(THOUT, ">$thesaurusfile");
+
+	while(<TH>) {
+	    chomp;
+	    ($num, $text) = split(/:/, $_);
+
+	    if (defined($thes_symbols{$num})) {
+		print THOUT "$num:$thes_symbols{$num}:$text\n";
+	    } else {
+		print THOUT "$num:untranslated:$text\n";
+	    }
+	}
+	close TH;    
+	close THOUT;
+    }
+
+
+
+
+}
+
+
+# renumber_phrases
+#
+# Prepare the phrases file to be input to mgpp.  The biggest problem is
+# reconciling the phrase identifiers used by the suffix program (which
+# we'll call suffix-id numbers) with the numbers used in the thesaurus
+# (theesaurus-id) to create a ciommon set of phind id numbers (phind-id).
+# Phind-id numbers must be sorted by frequency of occurance.
+#
+# Start creating a set of phind-id numbers from the sorted suffix-id
+# numbers and (if required) the thesaurus-id numbers.  Then add any other
+# phrases occuring in the thesaurus.
+#
+# The last thing we have to do is restore the vocabulary information to the
+# phrase file so that the phrases are stored as words, not as symbol
+# numbers.
+
+# The original phrases file looks something like this:
+#   159396-1:s5175:4:1:116149-2:3:d2240,2;d2253;d2254
+#   159409-1:s5263:6:1:159410-2:6:d2122;d2128;d2129;d2130;d2215;d2380
+#   159415-1:s5267:9:1:159418-2:8:d3,2;d632;d633;d668;d1934;d2010;d2281;d2374
+#   159426-1:s5273:5:2:159429-2,115168-17:5:d252;d815;d938;d939;d2361
+
+
+sub renumber_phrases {
+    my ($self) = @_;
+
+    renumber_suffix_data($self);
+    renumber_thesaurus_data($self);
+    restore_vocabulary_data($self);
+
+}
+
+
+
+# renumber_suffix_data
+#
+# Translate phrases file to phrases.2 using phind keys instead
+# of suffix keys and sorting the expansion data.
+
+sub renumber_suffix_data {
+    my ($self) = @_;
+    
+    my $verbosity = $self->{'verbosity'};
+    my $out = $self->{'outhandle'};
+    print $out "Translate phrases: suffix-ids become phind-id's\n" 
+	if ($verbosity);
+    
+    my $phinddir = $self->{'phinddir'};
+    my $infile = &util::filename_cat($phinddir, 'phrases');
+    my $outfile = &util::filename_cat($phinddir, 'phrases.2');
+
+    # Read the phrase file.  Calculate initial set of phind-id
+    # numbers and store (suffixid -> frequency) relation.
+
+    my %suffixtophind;
+    my @totalfrequency;
+    my (@fields, $suffixid);
+    my $nextphind = 1;
+    
+    open(IN, "<$infile");
+    while(<IN>) {
+
+	chomp;
+	@fields = split(/:/, $_);
+	
+	# get next suffixid and phindid
+	$suffixid = shift @fields;
+	$suffixtophind{$suffixid} = $nextphind;
+
+	# store total frequency
+	shift @fields;
+	$totalfrequency[$nextphind] = shift @fields;
+
+	$nextphind++;
+    }
+    close IN;
+
+
+    # Translate phrases file to phrases.2.  Use phind keys (not suffix
+    # keys), sort expansion and document occurance data in order of
+    # descending frequency..
+    open(IN, "<$infile");
+    open(OUT, ">$outfile");
+    
+    my ($phindid, $text, $tf, $countexp, $expansions, $countdocs, $documents);
+    my (@documwents, @newexp, $k, $n);
+    my $linenumber = 0;
+
+    while(<IN>) {
+	
+	# read the line
+	chomp;
+	@fields = split(/:/, $_);
+	
+	# get a phrase number for this line
+	$suffixid = shift @fields;
+	die unless (defined($suffixtophind{$suffixid}));
+	$phindid = $suffixtophind{$suffixid};
+	
+	# get the symbols in the phrase
+	$text = shift @fields;
+
+	# output status information
+	$linenumber++;
+	if ($verbosity > 2) {
+	    if ($linenumber % 1000 == 0) {
+		print $out "line $linenumber:\t$phindid\t$suffixid\t($text)\n";
+	    }
+	    # what are $num and $key??
+	    #print $out "$num: $key\t($text)\n" if ($verbosity > 3);
+	}
+
+	# get the phrase frequency
+	$tf = shift @fields;
+	
+	# get the number of expansions
+	$countexp = shift @fields;
+	
+	# get the expansions, convert them into phind-id numbers, and sort them
+	$expansions = shift @fields;
+	@newexp = ();
+	foreach $k (split(/,/, $expansions)) {
+	    die "ERROR - no phindid for: $k" unless (defined($suffixtophind{$k}));
+	    $n = $suffixtophind{$k};
+	    push @newexp, $n;
+	}
+	@newexp = sort {$totalfrequency[$b] <=> $totalfrequency[$a]} @newexp;
+
+	# get the number of documents
+	$countdocs = shift @fields;
+	
+	# get the documents and sort them
+	$documents = shift @fields;
+	$documents =~ s/d//g;
+	my @documents = split(/;/, $documents);
+	@documents = sort by_doc_frequency @documents;
+
+	# output the phrase data
+ 	print OUT "$phindid:$text:$tf:$countexp:$countdocs:";
+	print OUT join(",", @newexp), ",:", join(";", @documents), ";\n";
+	
+    }
+
+    close IN;
+    close OUT;
+}
+
+
+# renumber_thesaurus_data
+#
+# Translate phrases.2 to phrases.3, adding thesaurus data if available.
+
+sub renumber_thesaurus_data {
+    my ($self) = @_;
+  
+    my $out = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+    my $thesaurus = $self->{'thesaurus'};
+
+    my $phinddir = $self->{'phinddir'};
+    my $infile = &util::filename_cat($phinddir, "phrases.2");
+    my $outfile = &util::filename_cat($phinddir, "phrases.3");
+
+
+    # If no thesaurus is defined, simply move the phrases file.
+    if (!$thesaurus) {
+	print $out "Translate phrases.2: no thesaurus data\n" 
+	    if ($verbosity);
+	&util::mv($infile, $outfile);
+	return;
+    }
+
+    print $out "Translate phrases.2: add thesaurus data\n" 
+	if ($verbosity);
+
+    # 1.
+    # Read thesaurus file and store (symbols->thesaurusid) mapping
+    my $thesaurusfile = &util::filename_cat($phinddir, "$thesaurus.numbers");
+    my %symbolstothesid;
+    my (@fields, $thesid, $symbols);
+    
+    open(TH, "<$thesaurusfile");
+
+    while (<TH>) {
+	
+	chomp;
+	@fields = split(/:/, $_);
+	
+	# get id and text
+	$thesid = shift @fields;
+	$symbols = shift @fields;
+	$symbolstothesid{$symbols} = $thesid;
+    }
+    close TH;    
+
+    # 2. 
+    # Read phrases file to find thesaurus entries that already
+    # have a phindid.  Store their phind-ids for later translation,
+    # and store their frequency for later sorting.
+    my %thesaurustophindid;
+    my %phindidtofrequency;
+    my ($phindid, $freq);
+
+    open(IN, "<$infile");
+    
+    while(<IN>) {
+	
+	chomp;
+	@fields = split(/:/, $_);
+	
+	# phindid and symbols for this line
+	$phindid = shift @fields;
+	$symbols = shift @fields;
+	$freq = shift @fields;
+
+	# do we have a thesaurus id corresponding to this phrase?
+	if (defined($symbolstothesid{$symbols})) {
+	    $thesid = $symbolstothesid{$symbols};
+	    $thesaurustophindid{$thesid} = $phindid;
+	    $phindidtofrequency{$phindid} = $freq;
+	}
+    }
+    close IN;
+  
+    undef %symbolstothesid;
+
+    # 3.
+    # Create phind-id numbers for remaining thesaurus entries,
+    # and note that their frequency is 0 for later sorting.
+    my $nextphindid = $phindid + 1;
+
+    open(TH, "<$thesaurusfile");
+    while(<TH>) {
+	
+	chomp;
+	@fields = split(/:/, $_);
+	
+	# read thesaurus-id and ensure it has a corresponding phind-id
+	$thesid = shift @fields;
+	if (!defined($thesaurustophindid{$thesid})) {
+	    $thesaurustophindid{$thesid} = $nextphindid;
+	    $phindidtofrequency{$nextphindid} = 0;
+	    $nextphindid++;
+	}
+    }
+    close TH;
+
+    # 4.
+    # Translate thesaurus file, replacing thesaurus-id numbers with 
+    # phind-id numbers.
+    my $newthesaurusfile = &util::filename_cat($phinddir, "$thesaurus.phindid");
+    my ($relations, $linkcounter, $linktext, $linktype, @linkdata);
+    my (@links, $linkid, %linkidtotype, $newrelation);
+
+    open(TH, "<$thesaurusfile");
+    open(TO, ">$newthesaurusfile");
+    while(<TH>) {
+	
+	chomp;
+	@fields = split(/:/, $_);
+	
+	# phindid and symbols for this line
+	($thesid, $symbols, $relations) = @fields;
+	
+	die unless ($thesid && $symbols);
+	die unless $thesaurustophindid{$thesid};
+	$phindid = $thesaurustophindid{$thesid};
+
+	# convert each part of the relation string to use phind-id numbers
+	# at the same time, we want to sort the list by frequency.
+	undef %linkidtotype;
+	
+	foreach $linktext (split(/;/, $relations)) {
+	    @linkdata = split(/,/, $linktext);
+	    
+	    # remember the linktype (e.g. BT, NT)
+	    $linktype = shift @linkdata;
+	    
+	    # store the type of each link
+	    foreach $thesid (@linkdata) {
+		die unless (defined($thesaurustophindid{$thesid}));
+		$linkidtotype{$thesaurustophindid{$thesid}} = $linktype;
+	    }
+	}
+
+	# sort the list of links, first by frequency, then by type.
+	@links = sort { ($phindidtofrequency{$b} <=> $phindidtofrequency{$a}) 
+                        or ($linkidtotype{$a} cmp $linkidtotype{$b}) } (keys %linkidtotype);
+	$linkcounter = (scalar @links);
+
+	# create a string describing the link information
+	$linktype = $linkidtotype{$links[0]};
+	$newrelation = $linktype;
+	foreach $linkid (@links) {
+	    if ($linkidtotype{$linkid} ne $linktype) {
+		$linktype = $linkidtotype{$linkid};
+		$newrelation .= ";" . $linktype;
+	    }
+	    $newrelation .= "," . $linkid;
+	}
+	$newrelation .= ";";
+	
+
+	# output the new line
+	print TO "$phindid:$symbols:$linkcounter:$newrelation:\n";
+    }
+    close TH;
+    close TO;
+
+    undef %thesaurustophindid;
+    undef %linkidtotype;
+    undef %phindidtofrequency;
+
+    # 5.
+    # Read thesaurus data (in phind-id format) into memory
+    my %thesaurusdata;
+
+    open(TH, "<$newthesaurusfile");
+    while(<TH>) {
+	chomp;
+	($phindid, $symbols, $linkcounter, $relations) = split(/:/, $_);
+	die unless ($phindid && $symbols);
+	$thesaurusdata{$phindid} = "$symbols:$linkcounter:$relations";
+    }
+    close TH;
+
+    # 6. 
+    # Add thesaurus data to phrases file
+    my ($text, $tf, $countexp, $expansions, $countdocs, $documents);
+    my (@documwents, @newexp, $k, $n);
+    my $linenumber = 0;
+
+    open(IN, "<$infile");
+    open(OUT, ">$outfile");
+
+    # Update existing phrases
+    while(<IN>) {
+	
+	chomp;
+	@fields = split(/:/, $_);
+		
+	# get data for this line
+	$phindid = shift @fields;
+	
+	# output the phrase data, with thesaurus information
+ 	print OUT "$phindid:", join(":", @fields);
+
+	# add thesaurus data
+	if (defined($thesaurusdata{$phindid})) {
+	    @fields = split(/:/, $thesaurusdata{$phindid});
+	    shift @fields;
+	    $linkcounter = shift @fields;
+	    $relations = shift @fields;
+
+	    print OUT ":$linkcounter:$relations";
+	    $thesaurusdata{$phindid} = "";
+	}
+	print OUT "\n";
+    }
+    close IN;
+
+    # Add phrases that aren't already in the file
+    foreach $phindid (sort numerically keys %thesaurusdata) {
+	next unless ($thesaurusdata{$phindid});
+
+	@fields = split(/:/, $thesaurusdata{$phindid});
+	$symbols = shift @fields;
+	$linkcounter = shift @fields;
+	$relations = shift @fields;
+
+	print OUT "$phindid:$symbols:0:0:0:::$linkcounter:$relations\n";
+    }
+    close OUT;
+
+}
+
+# restore_vocabulary_data
+#
+# Read phrases.3 and restore vocabulary information. Then write 
+# this data to the MGPP input files (pword.txt and pdata.txt) and
+# (if requested) to the saved phrases file.
+
+sub restore_vocabulary_data {
+    my ($self) = @_;
+ 
+    my $out = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+    print $out "Translate phrases.3: restore vocabulary\n" if ($verbosity);
+
+    my $phinddir = $self->{'phinddir'};
+    my $infile = &util::filename_cat($phinddir, 'phrases.3');
+    my $vocabfile = &util::filename_cat($phinddir, 'clauses.vocab');
+    my $datafile = &util::filename_cat($phinddir, 'pdata.txt');
+    my $wordfile = &util::filename_cat($phinddir, 'pword.txt');
+
+    my $savephrases = $self->{'savephrases'};
+
+    # 1.
+    # Read the vocabulary file
+    open(V, "<$vocabfile")
+	|| die "Cannot open $vocabfile: $!";
+    my @symbol;
+    my $i = 1;
+    while(<V>) {
+	chomp;
+	$symbol[$i++] = $_;
+    }
+    close V;
+
+    # 2. 
+    # Translate phrases.3 to MGPP input files
+    my ($key, $text, $word, $isThesaurus, $line);
+    my @fields;
+    my $linenumber = 0;
+
+    open(IN, "<$infile");
+    open(DATA, ">$datafile");
+    open(WORD, ">$wordfile");
+
+    # Save the phrases in a separate text file
+    if ($savephrases) {
+	print $out "Saving phrases in $savephrases\n" if ($verbosity);
+	open(SAVE, ">$savephrases");
+    }
+
+    while(<IN>) {
+	
+	# read the line
+	chomp;
+	$line = $_;
+	@fields = split(/:/, $line);
+	
+	# get a phrase number for this line
+	$key = shift @fields;
+	
+	# restore the text of the phrase
+	$text = shift @fields;
+	$text =~ s/s(\d+)/$symbol[$1]/g;
+	if ($text =~ / /) {
+	    $word = "";
+	} elsif ($text ne 'untranslated') {
+	    $word = $text;
+	}
+
+	# output the phrase data
+	print DATA "<Document>";
+ 	print DATA "$key:$text:", join(":", @fields), ":\n";
+	
+	# output the word index search data
+	print WORD "<Document>$word\n";
+
+	# output the phrases to a text file
+	if ($savephrases) {
+	    if ((scalar @fields) == 7) {
+		$isThesaurus = 1;
+	    } else {
+		$isThesaurus = 0;
+	    }
+	    print SAVE $fields[0], "\t", $fields[2], "\t$isThesaurus\t$text\n";
+	}
+    }
+    close IN;
+    close WORD;
+    close DATA;
+    close SAVE if ($savephrases);
+
+}
+
+
+
+# sort routines used to renumber phrases
+
+sub numerically { $a <=> $b }
+
+sub by_doc_frequency { 
+    my $fa = 1;
+    if ($a =~ /,/) {
+	$fa = $a;
+	$fa =~ s/\d+,//;
+    }
+    my $fb = 1;
+    if ($b =~ /,/) {
+	$fb = $b;
+	$fb =~ s/\d+,//;
+    }
+
+    return ($fb <=> $fa);
+}
+
+1;
Index: /gsdl/stable/perllib/classify/RecentDocumentsList.pm
===================================================================
--- /gsdl/stable/perllib/classify/RecentDocumentsList.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/RecentDocumentsList.pm	(revision 20131)
@@ -0,0 +1,243 @@
+###########################################################################
+#
+# RecentDocumentsList.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# simple list classifier plugin 
+# to see the options, run "perl -S classinfo.pl RecentDocumentsList"
+
+package RecentDocumentsList;
+
+use BaseClassifier;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+use sorttools;
+use Time::Local;
+
+sub BEGIN {
+    @RecentDocumentsList::ISA = ('BaseClassifier');
+}
+
+my $arguments =   
+    [ { 'name' => "include_docs_added_since",
+	'desc' => "{RecentDocumentsList.include_docs_added_since}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "include_most_recently_added", 
+	'desc' => "{RecentDocumentsList.include_most_recently_added}",
+	'type' => "int",
+	'deft' => "20",
+        'reqd' => "no"},
+      { 'name' => "sort",
+	'desc' => "{RecentDocumentsList.sort}",
+	'type' => "metadata",
+	'reqd' => "no"}
+      ];
+
+my $options = { 'name'     => "RecentDocumentsList",
+		'desc'     => "{RecentDocumentsList.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseClassifier($classifierslist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+    # check the arguments
+    
+    if (!$self->{"buttonname"}) {
+	$self->{"buttonname"} = 'RecentDocuments';
+    }
+
+    # we want either include_docs_added_since, or include_most_recently_added, but not both.
+    if (defined $self->{'include_docs_added_since'} && !($self->{'include_docs_added_since'} eq "")){
+	$self->{'classify_by_date'} = 1;
+	my ($year, $month, $day) = $self->{'include_docs_added_since'} =~ 
+	    /^(\d\d\d\d)-?(\d\d)?-?(\d\d)?$/;
+	if (!defined $year) {
+	    &gsprintf($self->{'outhandle'}, "RecentDocumentsList::init {RecentDocumentsList.date_wrong_format}\n");
+	    die "\n";
+	}
+	if (!defined $month || $month < 1 || $month > 12) {
+	    $month = "01";
+	    $day = "01";
+	} elsif (!defined $day || $day < 1 || $day > 31) {
+	    $day = "01";
+	}
+	
+	$self->{'classification_date'} = timelocal(0,0,0,$day,$month-1, $year);
+
+    } else {
+	$self->{'classify_by_date'} = 0;
+    }	
+    if ($self->{'sort'} eq "") {
+	undef $self->{'sort'};
+    }
+    # Further setup 
+    $self->{'list'} = {};
+    # if we are getting top X docs, and sorting by meta, we need to store the 
+    # date and the metadata
+    if (!$self->{'classify_by_date'} && $self->{'sort'}) {
+	$self->{'meta_list'} = {};
+    }
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+
+}
+
+sub classify {
+    my $self = shift (@_);
+    my ($doc_obj,$edit_mode) = @_;
+
+    my $doc_OID = $doc_obj->get_OID();
+    my $lastmodified = $doc_obj->get_metadata_element($doc_obj->get_top_section(), "lastmodified");
+    if (!defined $lastmodified || $lastmodified eq "") {
+	print $self->{'outhandle'}, "RecentDocumentsList: $doc_OID has no lastmodified metadata, not classifying\n";
+	return;
+    }
+
+    if ($edit_mode eq "delete") {
+	$self->oid_hash_delete($doc_OID,'list');
+	return;
+    }
+
+    # doc goes into classification if we are not classifying by date, or the date is after the cutoff date.
+    if ($self->{'classify_by_date'}) {
+	if ($lastmodified > $self->{'classification_date'}) {
+	    my $sort_meta = $lastmodified;
+	    if (defined $self->{'sort'}) {
+		$sort_meta = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $self->{'sort'});
+	    }
+	    $self->{'list'}->{$doc_OID} = $sort_meta;
+	    $doc_obj->add_metadata($doc_obj->get_top_section(), "memberof", "CL".$self->get_number());
+	}	    
+    } else {
+
+	# need to store metadata as well...
+	$self->{'list'}->{$doc_OID} = $lastmodified;
+	if (defined $self->{'sort'}) {
+	    my $sort_meta = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $self->{'sort'});
+	    $self->{'meta_list'}->{$doc_OID} = $sort_meta;
+	}
+    }
+    
+}
+
+
+sub get_classify_info {
+    my $self = shift (@_);
+    my $return_doc_size=0;
+
+    my $list = $self->{'list'};
+
+
+    # organise into classification structure
+    my %classifyinfo = ('thistype'=>'Invisible',
+			'childtype'=>'VList',
+ 			'Title'=>$self->{'buttonname'},
+ 			'contains'=>[]);
+    
+
+    # may or may not support memberof, depending on options set
+    $classifyinfo{'supportsmemberof'} = &supports_memberof();
+
+    # get either all documents (sorted by date), or the top X docs
+    my @sorted_docs = sort {$self->date_or_metadata_sort($a,$b)} keys %{$self->{'list'}};
+    my $numdocs = $self->{'include_most_recently_added'};
+    if ($self->{'classify_by_date'}) { 
+	# just include all docs in the list
+	$numdocs = scalar  (@sorted_docs);
+    } else {
+	if ($numdocs > scalar  (@sorted_docs)) {
+	    $numdocs = scalar  (@sorted_docs);
+	}
+	if ($self->{'sort'}) {
+	    # we need to sort further by metadata
+	    # cut off the list
+	    @sorted_docs = @sorted_docs[0..$numdocs-1];
+	    # sort again
+	    @sorted_docs = sort {$self->external_meta_sort($a,$b)}@sorted_docs;
+	}
+    }
+    for (my $i=0; $i<$numdocs; $i++) {
+	push (@{$classifyinfo{'contains'}}, {'OID'=> $sorted_docs[$i]});
+    }
+	
+	
+    return \%classifyinfo;
+}
+
+# we can only support memberof if we have the include_docs_added_since option, otherwise we don't know at the time of classification of a document if it will be in the classifier or not.
+sub supports_memberof {
+    my $self = shift(@_);
+
+    if ($self->{'classify_by_date'}) {
+	return "true";
+    }
+    return "false";
+}
+
+sub date_or_metadata_sort {
+    my ($self,$a,$b) = @_;
+    # make it do metadata too
+    my $date_a = $self->{'list'}->{$a};
+    my $date_b = $self->{'list'}->{$b};
+    if (!$self->{'sort'} || !$self->{'classify_by_date'}) {
+	# want reverse order (latest to earliest)
+	return ($date_b <=> $date_a);
+    }
+    # meta sorting, use string cmp
+    return ($date_a cmp $date_b);
+}
+
+sub external_meta_sort {
+    my ($self,$a,$b) = @_;
+    
+    my $meta_a = $self->{'meta_list'}->{$a};
+    my $meta_b = $self->{'meta_list'}->{$b};
+
+    return ($meta_a cmp $meta_b);
+}
+
+    
+1;
+
+
+
+
Index: /gsdl/stable/perllib/classify/SectionList.pm
===================================================================
--- /gsdl/stable/perllib/classify/SectionList.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/SectionList.pm	(revision 20131)
@@ -0,0 +1,152 @@
+###########################################################################
+#
+# SectionList.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# Same as SimpleList classifier but includes all sections of document
+# (excluding top level) rather than just top level document 
+# itself
+
+
+package SectionList;
+
+use SimpleList;
+use sorttools;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @SectionList::ISA = ('SimpleList');
+}
+
+my $arguments = [];
+my $options = { 'name'     => "SectionList",
+		'desc'     => "{SectionList.desc}",
+		'abstract' => "no",
+		'inherits' => "yes" };
+
+
+sub new { 
+    my ($class) = shift (@_);
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new SimpleList($classifierslist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+sub classify {
+    my $self = shift (@_);
+    my ($doc_obj, $edit_mode, @options) = @_;
+    
+    # @options used by AZCompactList when is uses SectionList internally
+    # are we sorting the list??
+    my $nosort = 0;
+    if (defined $self->{'sort'} && $self->{'sort'} eq "nosort") {
+	$nosort = 1;
+    }
+
+    my $thissection = undef;
+
+    foreach my $option (@options)
+    {
+	if ($option =~ m/^section=(\d+)$/i) 
+	{
+	    $thissection = $1;
+	}
+    }
+
+    my $sortmeta = "";
+    if (!$nosort && defined $self->{'sort'}) {
+	if ($self->{'sort'} =~ /^filename$/i) {
+	    $sortmeta = $doc_obj->get_source_filename();
+	} else {
+	    $sortmeta = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $self->{'sort'});
+	    if (defined $sortmeta && !$self->{'no_metadata_formatting'}) {
+		$sortmeta = &sorttools::format_metadata_for_sorting($self->{'sort'}, $sortmeta, $doc_obj);
+	    }
+	}
+	$sortmeta = "" unless defined $sortmeta;
+    }
+
+    if (defined $thissection) {
+	# just classify the one section
+	$self->classify_section($thissection, $doc_obj, $edit_mode, $sortmeta, $nosort);
+    } else    
+    {
+	$thissection = $doc_obj->get_next_section ($doc_obj->get_top_section());
+	while (defined $thissection) {
+	    $self->classify_section($thissection, $doc_obj, $edit_mode, $sortmeta, $nosort);
+	    $thissection = $doc_obj->get_next_section ($thissection);
+	}
+    }
+}
+
+sub classify_section {
+    my $self = shift (@_);
+    my ($section, $doc_obj, $edit_mode, $sortmeta, $nosort) = @_;
+
+    my $doc_OID = $doc_obj->get_OID();
+    $nosort = 0 unless defined $nosort;
+    $sortmeta = "" unless defined $sortmeta;
+
+    my $metavalue;
+    my $metaname;
+    if (defined $self->{'meta_list'}) {
+	# find the first available metadata
+	foreach my $m (@{$self->{'meta_list'}}) {
+	    $metavalue = $doc_obj->get_metadata_element($section, $m);
+	    $metaname = $m;
+	    last if defined $metavalue;
+	} 
+	#if we haven't found a metavalue here, then the section shouldn't be included
+	return unless defined $metavalue;
+    }
+    
+    # we know the section should be included, add it now if we are not sorting
+    if ($nosort) {
+	push (@{$self->{'list'}}, "$doc_OID.$section");
+	return;
+    }
+    # check that it hasn't been added already
+    if (defined $self->{'list'}->{"$doc_OID.$section"}) {
+	my $outhandle = $self->{'outhandle'};
+	print $outhandle "WARNING: SectionList::classify called multiple times for $doc_OID.$section\n";
+    } 
+
+    if (defined $self->{'sort'}) {
+	# sorting on alternative metadata
+	$self->{'list'}->{"$doc_OID.$section"} = $sortmeta;
+    } else {
+	# sorting on the classification metadata
+	# do the same formatting on the meta value as for sort meta
+	$metavalue = &sorttools::format_metadata_for_sorting($metaname, $metavalue, $doc_obj) unless $self->{'no_metadata_formatting'};
+	$self->{'list'}->{"$doc_OID.$section"} = $metavalue;
+    }
+}
+1;
Index: /gsdl/stable/perllib/classify/SimpleList.pm
===================================================================
--- /gsdl/stable/perllib/classify/SimpleList.pm	(revision 20131)
+++ /gsdl/stable/perllib/classify/SimpleList.pm	(revision 20131)
@@ -0,0 +1,261 @@
+###########################################################################
+#
+# SimpleList.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# simple list classifier plugin 
+# to see the options, run "perl -S classinfo.pl SimpleList"
+
+use BaseClassifier;
+package SimpleList;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+use sorttools;
+
+sub BEGIN {
+    @SimpleList::ISA = ('BaseClassifier');
+}
+
+my $arguments = 
+    [ { 'name' => "metadata",
+	'desc' => "{SimpleList.metadata}",
+	'type' => "metadata",
+	'reqd' => "no" },
+      { 'name' => "sort",
+	'desc' => "{SimpleList.sort}",
+	'type' => "metadata",
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "SimpleList",
+		'desc'     => "{SimpleList.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+
+    my ($classifierslist,$inputargs,$hashArgOptLists) = @_;
+    push(@$classifierslist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseClassifier($classifierslist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    # Transfer value from Auto Parsing to the variable name that used in previous GreenStone.
+    my (@meta_list,$meta1);
+    if ($self->{"metadata"}) {
+	@meta_list = split(/,|;/, $self->{"metadata"});
+	$meta1 = $meta_list[0];
+	$self->{'meta_list'} = \@meta_list;
+    } else {
+	$meta1=undef;
+	@meta_list = undef;
+    }
+
+    if (!$self->{"buttonname"}) {
+	if (defined ($self->{'metadata'})) {
+	    $self->{"buttonname"} = $self->generate_title_from_metadata($self->{'metadata'});
+	} else {
+	    $self->{"buttonname"} = 'List';
+	}
+    }
+
+    # Further setup
+    # $self->{"sort"} is handled a bit differently - kjdon
+    # undef means to sort, but use the metadata value from -metadata
+    # because there is no one metadata value to get for sorting when 
+    # we have a list of possible metadata
+    # to get no sorting, set $self->{"sort"} = 'nosort'
+    if (!$self->{"sort"}) {
+	if (defined ($self->{"metadata"})) {
+	    $self->{"sort"} = undef;
+	} else {
+	    $self->{"sort"} = "nosort";
+	}
+    }    
+    if (defined  $self->{"sort"} &&  $self->{"sort"} eq "nosort") {
+	$self->{'list'} = [];
+    } else {
+	$self->{'list'} = {};
+    }
+        
+    # Clean out the unused keys
+    delete $self->{"metadata"}; # Delete this key
+    
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+
+}
+
+sub classify {
+    my $self = shift (@_);
+    my ($doc_obj, $edit_mode) = @_;
+
+    my $doc_OID = $doc_obj->get_OID();
+
+
+    # are we sorting the list??
+    my $nosort = 0;
+    if (defined $self->{'sort'} && $self->{'sort'} eq "nosort") {
+	$nosort = 1;
+    }
+    
+    if ($edit_mode eq "delete") {
+	if ($nosort) {
+	    $self->oid_array_delete($doc_OID,'list');
+	}
+	else {
+	    $self->oid_hash_delete($doc_OID,'list');
+	}
+	return;
+    }
+
+    my $metavalue;
+    my $metaname;
+    if (defined $self->{'meta_list'}) {
+	my $topsection=$doc_obj->get_top_section();
+
+	# find the correct bit of metadata, if multi-valued metadata field
+	if (exists $doc_obj->{'mdoffset'}) { # set by AZCompactList
+
+	    my $mdoffset=$doc_obj->{'mdoffset'} - 1;
+	    
+	    foreach my $m (@{$self->{'meta_list'}}) {
+		my $values_listref=
+		    $doc_obj->get_metadata($topsection, $m);
+		my $array_size = scalar(@{$values_listref});
+		if ($array_size==0 || $array_size < $mdoffset+1) {
+		    $mdoffset = $mdoffset - $array_size;
+		} else {
+		    $metaname = $m;
+		    # get the correct value using the offset
+		    $metavalue=@$values_listref[$mdoffset];
+                    # use a special format for docOID...
+		    $doc_OID .= ".offset$mdoffset";
+		    last;
+		}
+	    }
+	} else {
+	    # use the first available metadata
+	    foreach my $m (@{$self->{'meta_list'}}) {
+		$metavalue = $doc_obj->
+		    get_metadata_element($topsection, $m);
+		$metaname = $m;
+		last if defined $metavalue;
+	    }
+	} 
+	# if we haven't found a metavalue, then the doc shouldn't be included
+	return unless defined $metavalue;
+    }
+    
+    # we know the doc should be included, add it now if we are not sorting
+    if ($nosort) {
+	push (@{$self->{'list'}}, $doc_OID);
+	return;
+    }
+
+    #check for a sort element other than our metadata
+    if (defined $self->{'sort'}) {
+	my $sortmeta;
+	if ($self->{'sort'} =~ /^filename$/i) {
+	    $sortmeta = $doc_obj->get_source_filename();
+	} else {
+	    $sortmeta = $doc_obj->get_metadata_element($doc_obj->get_top_section(), $self->{'sort'});
+	    if (defined $sortmeta && !$self->{'no_metadata_formatting'}) {
+		$sortmeta = &sorttools::format_metadata_for_sorting($self->{'sort'}, $sortmeta, $doc_obj);
+	    }
+	}
+	$sortmeta = "" unless defined $sortmeta;
+	$self->{'list'}->{$doc_OID} = $sortmeta;
+    } else {
+	# we add to the list based on metadata value
+	# but we need to do the same formatting as for sort value
+	($metavalue) = &sorttools::format_metadata_for_sorting($metaname, $metavalue, $doc_obj) unless $self->{'no_metadata_formatting'};
+	$self->{'list'}->{$doc_OID} = $metavalue;
+    }
+    my $id = $self->get_number();
+    $doc_obj->add_metadata($doc_obj->get_top_section(), "memberof", "CL$id");
+}
+
+
+sub get_classify_info {
+    my $self = shift (@_);
+    my ($gli, $no_thistype) = @_;
+    $no_thistype = 0 unless defined $no_thistype;
+    my $memberof = &supports_memberof();
+
+    my @list = ();
+    if (defined $self->{'sort'} && $self->{'sort'} eq "nosort") {
+	@list = @{$self->{'list'}};
+    } else {
+	if (keys %{$self->{'list'}}) {
+	    @list = sort {$self->{'list'}->{$a} 
+			  cmp $self->{'list'}->{$b};} keys %{$self->{'list'}};
+	}	
+    }
+    # organise into classification structure
+    my %classifyinfo = ('childtype'=>'VList',
+			'Title'=>$self->{'buttonname'},
+			'contains'=>[]);
+    $classifyinfo{'thistype'} = 'Invisible' unless $no_thistype;
+    # always supports memberof
+    $classifyinfo{'supportsmemberof'} = $memberof;
+
+    foreach my $OID (@list) {
+	my $hashref={};
+	# special oid format, if using offsets (from AZCompactList)
+	if ($OID =~ s/\.offset(\d+)$//) {
+	    $hashref->{'offset'}=$1;
+	}
+	$hashref->{'OID'}=$OID;
+
+	push (@{$classifyinfo{'contains'}}, $hashref);
+    }
+
+    return \%classifyinfo;
+}
+
+sub supports_memberof {
+    my $self = shift(@_);
+
+    return "true";
+}
+
+1;
+
+
+
+
Index: /gsdl/stable/perllib/cnseg.pm
===================================================================
--- /gsdl/stable/perllib/cnseg.pm	(revision 20131)
+++ /gsdl/stable/perllib/cnseg.pm	(revision 20131)
@@ -0,0 +1,80 @@
+###########################################################################
+#
+# cnseg.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# this package segments a chinese UTF-8 encoded Unicode
+# string into words.
+
+package cnseg;
+
+use strict;
+use unicode;
+
+
+# 'segment' takes a UTF-8 encoded Unicode Chinese-language
+# string and places U-200B between words -- the ZERO
+# WIDTH SPACE. Each line is treated as a separate 
+# paragraph, so lines in one paragraph should
+# be joined before using this method (normally a single
+# word might span more than one line within a paragraph).
+#
+# 'segment' is currently written in Perl, however, I (Rodger)
+# plan to use C++ (via pipes) once a more complex (and useful!)
+# algorithm is being used. Currently, each Chinese character
+# is treated as a seperate word.
+
+sub segment {
+    my ($in) = @_;
+    my ($c);
+
+    my $uniin = &unicode::utf82unicode($in);
+    my $out = [];
+
+    my $space = 1; # start doesn't need a space
+    foreach $c (@$uniin) {
+	if (($c >= 0x2e80 && $c <= 0xd7a3) ||
+	    ( $c >= 0xf900 && $c <= 0xfa6a)) { # main east asian codes
+	    # currently c++ receptionist code can't handle these large numbers
+	    # search terms need to be segmented the same way. Add these back
+	    # in when fix up c++
+	   # ($c >= 0x20000 && $c <= 0x2a6d6) || # cjk unified ideographs ext B
+	   # ($c >= 0x2f800 && $c <= 0x2fa1d)) { #cjk compatibility ideographs supplement
+	    # CJK character
+	    push (@$out, 0x200b) unless $space;
+	    push (@$out, $c);
+	    push (@$out, 0x200b);
+	    $space = 1;
+
+	} else {
+	    # non-Chinese character
+	    push (@$out, $c);
+	    $space = 0;
+	}
+    }
+
+    return &unicode::unicode2utf8($out);
+}
+
+1;
Index: /gsdl/stable/perllib/colcfg.pm
===================================================================
--- /gsdl/stable/perllib/colcfg.pm	(revision 20131)
+++ /gsdl/stable/perllib/colcfg.pm	(revision 20131)
@@ -0,0 +1,304 @@
+###########################################################################
+#
+# colcfg.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# reads/writes the collection configuration files:
+# collect.cfg/collectionConfig.xml and build.cfg/buildConfig.xml
+
+package colcfg;
+
+use cfgread;
+use collConfigxml;
+use buildConfigxml;
+use gsprintf 'gsprintf';
+use strict;
+
+# the collection configuration file data is stored in the form
+#
+# {'infodbtype'}->string
+# {'creator'}->string
+# {'public'}->string
+# {'defaultindex'}->string
+# {'importdir'}->string
+# {'archivedir'}->string
+# {'cachedir'}->string
+# {'builddir'}->string
+# {'removeold'}->string
+# {'textcompress'}->string
+# {'buildtype'}->string
+# {'maxnumeric'}->string
+# {'separate_cjk'}->string
+# {'sections_index_document_metadata'}->string (always, unless_section_metadata_exists)
+# {'maintainer'}->array of strings
+# {'languages'}->array of strings
+# {'indexsubcollections'}->array of strings
+# {'indexes'}->array of strings
+# {'indexoptions'}->array of strings (stem, casefold, accentfold)
+# {'dontbuild'}->array of strings
+# {'dontgdbm'}->array of strings
+# {'mirror'}->array of strings
+# {'phind'}->array of strings
+# {'plugout'}->array of strings
+# {'levels'}->array of strings (for mgpp eg Section, Paragraph)
+# {'searchtype'}->array of strings (for mgpp, form or plain)
+
+# {'subcollection'}->hash of key-value pairs
+
+# {'acquire'}->array of arrays of strings
+# {'plugin'}->array of arrays of strings
+# {'classify'}->array of arrays of strings
+
+# {'collectionmeta'}->hash of key->hash of param-value -used 
+# for language specification
+#    for example, collectionmeta->collectionname->default->demo
+#                                               ->mi->maori demo
+
+# convenience method for reading in either collect.cfg/collectionConfig.xml
+sub read_collection_cfg {
+    my ($filename,$gs_mode) = @_;
+    
+    my $collectcfg = undef;
+
+    if ($gs_mode eq "gs2") {
+	$collectcfg = &colcfg::read_collect_cfg ($filename);
+    } elsif ($gs_mode eq "gs3") {
+	$collectcfg = &colcfg::read_collection_cfg_xml ($filename);
+    }
+    else {
+	print STDERR "Failed to read collection configuration file\n";
+	print STDERR "  Unrecognized mode: $gs_mode\n";
+    }
+
+    return $collectcfg;
+}
+
+# convenience method for writing out either collect.cfg/collectionConfig.xml
+# is this ever used??
+sub write_collection_cfg {
+     my ($filename, $collectcfg_data, $gs_mode) = @_;
+    
+    if ($gs_mode eq "gs2") {
+	&colcfg::write_collect_cfg ($filename, $collectcfg_data );
+    } elsif ($gs_mode eq "gs3") {
+	&colcfg::write_collection_cfg_xml ($filename, $collectcfg_data);
+    }
+    else {
+	print STDERR "Failed to write collection configuration file\n";
+	print STDERR "  Unrecognized mode: $gs_mode\n";
+    }
+}
+   
+# the build configuration file data is stored in the form
+#
+# {'infodbtype'}->string
+# {'builddate'}->string
+# {'buildtype'}->string
+# {'metadata'}->array of strings
+# {'languages'}->array of strings
+# {'numdocs'}->string
+# {'numsections'}->string
+# {'numwords'}->string
+# {'numbytes'}->string
+# {'maxnumeric'}->string
+# {'indexfields'}->array of strings
+# {'indexfieldmap'}->array of strings in the form "field->FI"
+# {'indexmap'} -> array of strings
+# {'indexlevels'} -> array of strings
+# {'stemindexes'} -> string (int)
+# {'textlevel'}->string
+# {'levelmap'} -> array of strings in the form "level->shortname"
+
+# convenience method for reading in either build.cfg/buildConfig.xml
+sub read_building_cfg {
+    my ($filename,$gs_mode) = @_;
+    
+    my $buildcfg = undef;
+
+    if ($gs_mode eq "gs2") {
+	$buildcfg = &colcfg::read_build_cfg ($filename);
+    } elsif ($gs_mode eq "gs3") {
+	$buildcfg = &colcfg::read_build_cfg_xml ($filename);
+    }
+    else {
+	print STDERR "Failed to read building configuration file\n";
+	print STDERR "  Unrecognized mode: $gs_mode\n";
+    }
+
+    return $buildcfg;
+}
+
+# convenience method for writing out either build.cfg/buildConfig.xml
+# haven't got one, as gs3 version needs extra parameters
+#sub write_building_cfg {}
+
+##############################
+### gs2/gs3 specific methods
+###############################
+
+#####################################
+### collect.cfg/collectionConfig.xml
+#####################################
+
+# gs2 read in collect.cfg
+sub read_collect_cfg {
+    my ($filename) = @_;
+
+    return &cfgread::read_cfg_file ($filename, 
+				    q/^(infodbtype|creator|public|defaultindex|importdir|/ .
+					q/archivedir|cachedir|builddir|removeold|/ .
+					q/textcompress|buildtype|no_text|keepold|gzip|/ .
+					q/verbosity|remove_empty_classifications|OIDtype|OIDmetadata|/ .
+					q/groupsize|maxdocs|debug|mode|saveas|/ .
+					q/sortmeta|removesuffix|removeprefix|create_images|/ .
+					q/maxnumeric|languagemetadata|/ .
+					q/no_strip_html|index|sections_index_document_metadata|/ .
+					q/store_metadata_coverage)$/,
+				    q/(maintainer|languages|indexsubcollections|/ .
+				       q/indexes|indexoptions|dontbuild|dontgdbm|mirror|levels|plugout|/ .
+				       q/searchtype|searchtypes)$/,
+				    q/^(subcollection|format)$/,
+				    q/^(acquire|plugin|classify)$/,
+				    q/^(collectionmeta)$/);
+}
+
+# gs2 write out collect.cfg
+sub write_collect_cfg {
+    my ($filename, $data) = @_;
+    
+    &cfgread::write_cfg_file($filename, $data,
+			     q/^(infodbtype|creator|public|defaultindex|importdir|/ .
+				 q/archivedir|cachedir|builddir|removeold|/ .
+				 q/textcompress|buildtype|no_text|keepold|gzip|/ .
+				 q/verbosity|remove_empty_classifications|OIDtype|OIDmetadata|/.
+				 q/groupsize|maxdocs|debug|mode|saveas|/ .
+				 q/sortmeta|removesuffix|removeprefix|create_images|/ .
+				 q/maxnumeric|language_metadata/ .
+				 q/no_strip_html|index|sections_index_document_metadata)$/,
+			     q/^(maintainer|languages|indexsubcollections|/ .
+				 q/indexes|indexoptions|dontbuild|dontgdbm|mirror|levels|/.
+				 q/searchtype|searchtypes)$/,
+			     q/^(subcollection|format)$/,
+			     q/^(acquire|plugin|classify)$/,
+			     q/^(collectionmeta)$/);
+}
+
+# gs3 read in collectionConfig.xml
+sub read_collection_cfg_xml {
+    my ($filename) = @_;
+
+    return &collConfigxml::read_cfg_file ($filename);
+}
+
+# gs3 write out collectionConfig.xml
+sub write_collection_cfg_xml {
+ 
+}
+
+#####################################
+### build.cfg/buildConfig.xml
+######################################
+
+# gs2 read build.cfg
+sub read_build_cfg {
+    my ($filename) = @_;
+
+    return &cfgread::read_cfg_file ($filename, 
+		   q/^(infodbtype|builddate|buildtype|numdocs|numsections|numwords|numbytes|maxnumeric|textlevel|indexstem|stemindexes|separate_cjk)$/,
+		   q/^(indexmap|subcollectionmap|languagemap|notbuilt|indexfields|indexfieldmap|indexlevels|levelmap)$/);
+				    
+}
+
+# gs2 write build.cfg
+sub write_build_cfg {
+    my ($filename, $data) = @_;
+
+    &cfgread::write_cfg_file($filename, $data,
+	       q/^(infodbtype|builddate|buildtype|numdocs|numsections|numwords|numbytes|maxnumeric|textlevel|indexstem|stemindexes|separate_cjk)$/,
+	       q/^(indexmap|subcollectionmap|languagemap|notbuilt|indexfields|indexfieldmap|indexlevels|levelmap)$/);		     
+}
+
+# gs3 read buildConfig.xml
+sub read_build_cfg_xml {
+
+    my ($filename) = @_;
+    
+    return &buildConfigxml::read_cfg_file($filename);
+}
+
+# gs3 write buildConfig.xml
+sub write_build_cfg_xml {
+    my ($buildoutfile, $buildcfg, $collectcfg, $disable_OAI) = @_;
+
+    return &buildConfigxml::write_cfg_file ($buildoutfile, $buildcfg, $collectcfg, $disable_OAI);
+}
+
+
+# method to check for filename of collect.cfg, and gs mode.
+sub get_collect_cfg_name {
+    my ($out) = @_;
+
+    # First check if there's a
+    # gsdl/collect/COLLECTION/custom/COLLECTION/etc/custom.cfg file. This
+    # customization was added for DLC by Stefan, 30/6/2007.
+    my $configfilename = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "custom", $ENV{'GSDLCOLLECTION'}, "etc", "custom.cfg");
+
+    if (-e $configfilename) {
+        return ($configfilename, "gs2");
+    }
+
+    # Now check if there is a collect.cfg file in the usual place, i.e. it is gs2.
+    $configfilename = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "etc", "collect.cfg");
+    if (-e $configfilename) {
+        return ($configfilename, "gs2");
+    }
+
+    # If we get to here we check if there is a collectionConfig.xml file,
+    # i.e. it is gs3.
+    $configfilename = &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, "etc", "collectionConfig.xml");    
+    if (-e $configfilename) {
+        return ($configfilename, "gs3");
+    }
+
+    # Error. No collection configuration file.
+    (&gsprintf($out, "{common.cannot_find_cfg_file}\n", $configfilename) && die);
+}
+
+
+sub use_collection {
+   my ($site, $collection, $collectdir) = @_;
+
+   if ((defined $site) && ($site ne ""))
+   {
+       return &util::use_site_collection($site, $collection, $collectdir);
+   }
+   else
+   {
+       return &util::use_collection($collection, $collectdir);
+   }
+}
+
+
+1;
+
+
Index: /gsdl/stable/perllib/collConfigxml.pm
===================================================================
--- /gsdl/stable/perllib/collConfigxml.pm	(revision 20131)
+++ /gsdl/stable/perllib/collConfigxml.pm	(revision 20131)
@@ -0,0 +1,432 @@
+###########################################################################
+#
+# collConfigxml.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# reads in configuration files of xml form
+
+package collConfigxml;
+use strict;
+no strict 'refs';
+no strict 'subs';
+
+# Wrapper that ensures the right version of XML::Parser is loaded given
+# the version of Perl being used.  Need to distinguish between Perl 5.6 and
+# Perl 5.8
+sub BEGIN {
+    my $perl_dir;
+
+    # Note: $] encodes the version number of perl
+    if ($]>5.008) { 
+	# perl 5.8.1 or above
+	$perl_dir = "perl-5.8";
+    }
+    elsif ($]<5.008) {
+	# assume perl 5.6
+	$perl_dir = "perl-5.6";
+    }
+    else {
+	print STDERR "Warning: Perl 5.8.0 is not a maintained release.\n";
+	print STDERR "         Please upgrade to a newer version of Perl.\n";
+	$perl_dir = "perl-5.8";
+    }
+
+    if ($ENV{'GSDLOS'} !~ /^windows$/i) {
+	# Use push to put this on the end, so an existing XML::Parser will be used by default
+	push (@INC, "$ENV{'GSDLHOME'}/perllib/cpan/$perl_dir");
+    }
+}
+
+use XML::Parser;
+
+# A mapping hash to resolve name discrepancy between gs2 and gs3.
+my $nameMap = {"key" => "value",
+	       "creator" => "creator",
+	       "maintainer" => "maintainer",
+	       "public" => "public",
+	       "infodb" => "infodbtype",
+	       "defaultIndex" => "defaultindex",
+	       "defaultLevel" => "defaultlevel",
+	       "name" => "collectionname",
+	       "description" => "collectionextra",
+	       "smallicon" => "iconcollectionsmall",
+	       "icon" => "iconcollection",
+	       "level" => "levels",
+	       "classifier" => "classify",
+	       "indexSubcollection" => "indexsubcollections",
+	       "indexLanguage" => "languages",
+	       "defaultIndexLanguage" => "defaultlanguage",
+	       "index" => "indexes",
+	       "plugin" => "plugin",
+	       "plugout" => "plugout",
+	       "indexOption" => "indexoptions",
+	       "searchType" => "searchtype",
+	       "languageMetadata" => "languagemetadata",
+	       "buildType" => "buildtype"
+	       };
+# A hash structure which is returned by sub read_cfg_file.
+my $data = {};
+
+my $repeatedBlock = q/^(browse|pluginList)$/;
+
+# use those unique attribute values to locate the text within the elements
+# creator, public, maintainer and within a displayItem.
+my $currentLocation = "";
+my $stringexp = q/^(creator|maintainer|public|buildType)$/;
+my $displayItemNames = q/^(name|description)$/;
+  
+# For storing the attributes during the StartTag subroutine, so that 
+# we can use it later in Text (or EndTag) subroutines
+my $currentAttrRef = undef; 
+
+my $currentLevel = "";
+
+# Count the elements with same name within the same block
+# ("plugin", "option")
+my $currentIndex = 0;
+my $arrayexp = q/^(index|level|indexSubcollection|indexLanguage)$/;
+my $arrayarrayexp= q/^(plugin|classifier)$/;
+my $hashexp = q/^(subcollection)$/; # add other element names that should be represented by hash expressions here
+my $hashhashexp = q/^(displayItem)$/; # add other (collectionmeta) element names that should be represented by hashes of hashes here.
+
+my $defaults = q/^(defaultIndex|defaultLevel|defaultIndexLanguage|languageMetadata)$/;
+
+# Reads in the model collection configuration file, collectionConfig.xml,
+# into a structure which complies with the one used by gs2 (i.e. one read
+# in by &cfgread::read_cfg_file).
+sub read_cfg_file {
+    my ($filename) = @_;
+    $data = {};
+    if ($filename !~ /collectionConfig\.xml$/ || !-f $filename) {
+        return undef;
+    }
+
+    # create XML::Parser object for parsing metadata.xml files
+    my $parser;
+    if ($]<5.008) {
+	# Perl 5.6
+	$parser = new XML::Parser('Style' => 'Stream',
+				  'Handlers' => {'Char' => \&Char,
+						 'Doctype' => \&Doctype
+						 });
+    }
+    else {
+	# Perl 5.8
+	$parser = new XML::Parser('Style' => 'Stream',
+				  'ProtocolEncoding' => 'ISO-8859-1',
+				  'Handlers' => {'Char' => \&Char,
+						 'Doctype' => \&Doctype
+						 });
+    }
+
+    if (!open (COLCFG, $filename)) {
+	print STDERR "cfgread::read_cfg_file couldn't read the cfg file $filename\n";
+    } else {
+
+      $parser->parsefile ($filename);# (COLCFG);
+      close (COLCFG);
+    }
+
+    #&Display; 
+    return $data;
+}
+
+sub StartTag {
+# Those marked with #@ will not be executed at the same time when this sub is being called
+# so that if/elsif is used to avoid unnecessary tests
+    my ($expat, $element) = @_;
+    
+    # See http://search.cpan.org/~msergeant/XML-Parser-2.36/Parser.pm#Stream
+    # %_ is a hash of all the attributes of this element, we want to store them so we can use the attributes
+    # when the textnode contents of the element are parsed in the subroutine Text (that's the handler for Text). 
+    $currentAttrRef = \%_; 
+
+    my $name = $_{'name'};
+    my $value = $_{'value'};
+    my $type = $_{'type'};
+
+    # for subcollections
+    my $filter = $_{'filter'};
+    
+    # was this just a flax thing??
+    my $assigned = $_{'assigned'};
+    
+    #@ Marking repeated block
+    if ($element =~ /$repeatedBlock/) {
+	$currentIndex = 0;
+    }
+
+    #@ handling block metadataList
+    elsif (defined $name and $name =~ /$stringexp/){
+      $currentLocation = $name;
+    }
+    #@ handling default search index/level/indexLanguage and languageMetadata
+    elsif ($element =~ /$defaults/) {
+      if (defined $name and $name =~ /\w/) {
+	$data->{$nameMap->{$element}} = $name;
+      }
+    }
+
+    #@ handling the displayItems name and description (known as collectionname and collectionextra in GS2)
+    elsif($element eq "displayItemList") {
+	$currentLevel = "displayItemList"; # storing the parent if it is displayItemList
+    } 
+    elsif($element =~ /$hashhashexp/) { # can expand on this to check for other collectionmeta elements
+	if((!defined $assigned) || (defined $assigned and $assigned =~ /\w/ and $assigned eq "true")) {
+	    # either when there is no "assigned" attribute, or when assigned=true (for displayItems):
+	    $currentLocation = $name;
+	}
+    }
+
+    #@ Handling database type: gdbm or gdbm-txtgz, later jdbm.
+    elsif ($element eq "infodb") {
+      $data->{'infodbtype'} = $type;
+    }
+    
+    #@ Handling indexer: mgpp/mg/lucene; stringexp
+    elsif ($element eq "search") {
+      $data->{'buildtype'} = $type;
+    }
+
+    #@ Handling searchtype: plain,form; arrayexp
+    #elsif ($element eq "format" and defined $name and $name =~ /searchType/) {
+	#@ Handling searchtype: plain, form
+	#$currentLocation = $name;	
+    #}
+ 
+    #@ Handle index|level|indexSubcollection|indexLanguage
+    elsif ($element =~ /$arrayexp/) {
+      my $key = $nameMap->{$element};	
+      if (!defined $data->{$key}) {
+	$data->{$key} = [];
+      }
+
+      push (@{$data->{$key}},$name);
+    }
+
+    #@ indexoptions: accentfold/casefold/stem; arrayexp
+    elsif ($element eq "indexOption") {
+      $currentLevel = "indexOption";
+    }
+    if ($currentLevel eq "indexOption" and $element eq "option") {
+      my $key = $nameMap->{$currentLevel};	
+      if (!defined $data->{$key}) {
+	$data->{$key} = [];
+      }
+      push (@{$data->{$key}},$name);
+    }
+    #@ plugout options
+    elsif ($element eq "plugout") {
+	$currentLevel = "plugout";
+	my $key = $nameMap->{$currentLevel};	
+	if (!defined $data->{$key}) {
+	    $data->{$key} = [];
+	}
+	if(defined $name and $name ne ""){
+	    push (@{$data->{$key}},$name);
+	}
+	else{
+	   push (@{$data->{$key}},"GreenstoneXMLPlugout"); 
+	}
+    }
+    if ($currentLevel eq "plugout" and $element eq "option") {     
+	my $key = $nameMap->{$currentLevel};
+	if (defined $name and $name ne ""){
+	    push (@{$data->{$key}},$name);
+	}
+	if (defined $value and $value ne  ""){
+	    push (@{$data->{$key}},$value);
+	}
+    }
+
+    #@ use hash of hash of strings: hashexp
+    elsif ($element =~ /$hashexp/) {
+      if (!defined $data->{$element}) {
+	$data->{$element} = {};
+      }
+      if (defined $name and $name =~ /\w/) {
+	if (defined $filter and $filter =~ /\w/) {
+	  $data->{$element}->{$name} = $filter;
+
+	}
+      }
+    }
+
+    #@ Handling each classifier/plugin element
+    elsif ($element =~ /$arrayarrayexp/) {
+	# find the gs2 mapping name
+        $currentLevel = $element;
+        my $key = $nameMap->{$element};	
+
+	# define an array of array of strings	foreach $k (@{$data->{$key}}) {
+	if (!defined $data->{$key}) {
+	  $data->{$key} = [];
+	}
+	# Push classifier/plugin name (e.g. AZList) into $data as the first string
+ 	push (@{$data->{$key}->[$currentIndex]},$name);
+	#print $currentIndex."indexup\n";
+      }
+    
+    #@ Handling the option elements in each classifier/plugin element (as the following strings)
+    elsif ($currentLevel =~ /$arrayarrayexp/ and $element eq "option") {
+	# find the gs2 mapping name for classifier and plugin
+        my $key = $nameMap->{$currentLevel};	
+
+	if (defined $name and $name =~ /\w/) {
+	    push (@{$data->{$key}->[$currentIndex]}, $name);
+	}
+	if (defined $value and $value =~ /\w/) {
+            push (@{$data->{$key}->[$currentIndex]}, $value);
+	}
+
+    }
+    
+}
+
+sub EndTag {
+    my ($expat, $element) = @_;
+    my $endTags = q/^(browse|pluginList|displayItemList)$/;   
+    if ($element =~ /$endTags/) {
+		$currentIndex = 0;
+		$currentLevel = "";
+    }
+    # $arrayarrayexp contains classifier|plugin
+    elsif($element =~ /$arrayarrayexp/ ){
+     	$currentIndex = $currentIndex + 1;
+    }
+}
+
+sub Text {
+    if (defined $currentLocation) { 
+	#@ Handling block metadataList(creator, maintainer, public)
+	if($currentLocation =~ /$stringexp/){
+	    #print $currentLocation;
+	    my $key = $nameMap->{$currentLocation};	
+	    $data->{$key} = $_;
+	    undef $currentLocation;
+	}
+	
+	#@ Handling displayItem metadata that are children of displayItemList
+	# that means we will be getting the collection's name and possibly description ('collectionextra' in GS2).
+	elsif($currentLevel eq "displayItemList" && $currentLocation =~ /$displayItemNames/) {
+	    my $lang = $currentAttrRef->{'lang'};
+	    my $name = $currentAttrRef->{'name'};
+	    
+	    # this is how data->collectionmeta's language is set in Greenstone 2. 
+	    # Need to be consistent, since export.pl accesses these values all in the same way
+	    if(!defined $lang) {
+		$lang = 'default';
+	    } else {
+		$lang = "[l=$lang]"; 
+	    }
+	    
+	    if(defined $name and $name =~ /$displayItemNames/) { # attribute name = 'name' || 'description'
+		# using $nameMap->$name resolves to 'collectionname' if $name='name' and 'collectionextra' if $name='description'
+		$data->{'collectionmeta'}->{$nameMap->{$name}}->{$lang} = $_; # the value is the Text parsed
+		#print STDERR "***Found: $nameMap->{$name} collectionmeta, lang is $lang. Value: $data->{'collectionmeta'}->{$nameMap->{$name}}->{$lang}\n";
+	    }
+	    undef $currentLocation;
+	}
+  
+	#@ Handling searchtype: plain,form; arrayexp
+	elsif (defined $currentLocation and $currentLocation =~ /searchType/) {
+	    # map 'searchType' into 'searchtype'
+	    my $key = $nameMap->{$currentLocation};
+	    # split it by ','
+	    my ($plain, $form) = split (",", $_);
+	    
+	    if (!defined $data->{$key}) {
+		$data->{$key} = [];
+	    }
+	    if (defined $plain and $plain =~ /\w/) {
+		push @{ $data->{$key} }, $plain;
+	    }
+	    if (defined $form and $form =~ /\w/) {
+		push @{ $data->{$key} }, $form;
+	    }
+	}
+    }	
+}
+
+# This sub is for debugging purposes
+sub Display {
+    # metadataList
+    foreach my $k (keys %{$data}) {
+	print STDERR "*** metadatalist key $k\n"; 
+    }
+  
+    print $data->{'creator'}."\n" if (defined $data->{'creator'});
+    print $data->{"maintainer"}."\n" if (defined $data->{"maintainer"});
+    print $data->{"public"}."\n" if (defined $data->{"public"});
+    print $data->{"defaultindex"}."\n" if (defined $data->{"defaultindex"});
+    print $data->{"defaultlevel"}."\n" if (defined $data->{"defaultlevel"});
+    print $data->{"buildtype"}."\n" if (defined $data->{"buildtype"});
+    print  join(",",@{$data->{"searchtype"}})."\n" if (defined $data->{"searchtype"});
+    print  join(",",@{$data->{'levels'}})."\n" if (defined $data->{'levels'});
+    print  join(",",@{$data->{'indexsubcollections'}})."\n" if (defined $data->{'indexsubcollections'});
+    print  join(",",@{$data->{'indexes'}})."\n" if (defined $data->{'indexes'});
+    print  join(",",@{$data->{'indexoptions'}})."\n" if (defined $data->{'indexoptions'});
+    print  join(",",@{$data->{'languages'}})."\n" if (defined $data->{'languages'});
+    print  join(",",@{$data->{'languagemetadata'}})."\n" if (defined $data->{'languagemetadata'});
+ 
+    if (defined $data->{'plugin'}) {
+	foreach $a (@{$data->{'plugin'}}) {
+	    print join(",",@$a);
+	    print "\n";
+	}
+    }
+    if (defined $data->{'classify'}) {
+	print "Classifiers: \n";
+	map { print join(",",@$_)."\n"; } @{$data->{'classify'}};
+    }
+    
+    if (defined $data->{'subcollection'}) {
+	foreach my $key (keys %{$data->{'subcollection'}}) {
+	    print "subcollection ".$key." ".$data->{'subcollection'}->{$key}."\n";
+	}
+    }
+}
+# is this actually used??
+sub Doctype {
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+
+    die if ($name !~ /^CollectionConfig$/);
+}
+
+# This Char function overrides the one in XML::Parser::Stream to overcome a
+# problem where $expat->{Text} is treated as the return value, slowing
+# things down significantly in some cases.
+sub Char {
+    if ($]<5.008) {
+	use bytes;  # Necessary to prevent encoding issues with XML::Parser 2.31+ and Perl 5.6
+    }
+    $_[0]->{'Text'} .= $_[1];
+    return undef;
+}
+
+
+
+
+#########################################################
+
+1;
Index: /gsdl/stable/perllib/convertutil.pm
===================================================================
--- /gsdl/stable/perllib/convertutil.pm	(revision 20131)
+++ /gsdl/stable/perllib/convertutil.pm	(revision 20131)
@@ -0,0 +1,332 @@
+###########################################################################
+#
+# convertutil.pm -- utility to help convert files using external applications
+#
+# Copyright (C) 1999 DigiLib Systems Limited, NZ
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+package convertutil;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+
+use File::Basename;
+
+
+sub monitor_init
+{
+    # do nothing
+    return {};
+}
+
+sub monitor_deinit
+{
+    my ($saved_rec) = @_;
+    
+    # nothing to do
+}
+
+sub monitor_init_unbuffered
+{
+    my $saved_buffer_len = $|;
+    $| = 1;
+
+    my $saved_rec = { 'saved_buffer_len' => $saved_buffer_len };
+
+    return $saved_rec;
+}
+
+sub monitor_deinit_unbuffered
+{
+    my ($saved_rec) = @_;
+
+    my $saved_buffer_len = $saved_rec->{'saved_buffer_len'};
+
+    $| = $saved_buffer_len;
+}
+
+sub monitor_line
+{
+    my ($line) = @_;
+
+    my $had_error = 0;
+    my $generate_dot = 0;
+
+    return ($had_error,$generate_dot);
+}
+
+sub monitor_line_with_dot
+{
+    my ($line) = @_;
+
+    my $had_error = 0;
+    my $generate_dot = 1;
+
+    return ($had_error,$generate_dot);
+}
+
+
+sub run_general_cmd
+{
+    my ($command,$options) = @_;
+
+
+    # $options points to a hashtable that must have fields for:
+    #  'verbosity', 'outhandle', 'message_prefix' and 'message'
+    #
+    # it can also include functions for monitoring
+    #  'monitor_init'   => takes no input arguments and returns a hashtable for saved data values
+    #  'monitor_line'   => takes $line as input argument, return tuple (had_error,generate_dot)
+    #  'monitor_deinit' => takes the saved data values as input, restores saved values
+    #
+    # Default are provided for these monitor functions if none specified
+
+
+    my $verbosity = $options->{'verbosity'};
+    my $outhandle = $options->{'outhandle'};
+
+    my $message_prefix = $options->{'message_prefix'};
+    my $message = $options->{'message'};
+
+    my $monitor_init   = $options->{'monitor_init'};
+    my $monitor_line   = $options->{'monitor_line'};
+    my $monitor_deinit = $options->{'monitor_deinit'};
+
+    if (!defined $monitor_init) {
+	$monitor_init = "monitor_init";
+    }
+    if (!defined $monitor_line) {
+	$monitor_line = "monitor_line";
+    }
+    if (!defined $monitor_deinit) {
+	$monitor_deinit = "monitor_deinit";
+    }
+
+    print $outhandle "$message_prefix: $command\n" if ($verbosity > 3);
+    print $outhandle "  $message ..." if ($verbosity >= 1);
+
+    my $command_status = undef;
+    my $result = "";
+    my $had_error = 0;
+
+    my $saved_rec = &$monitor_init();
+
+    if (open(CMD,"$command 2>&1 |"))
+    {
+	my $line;
+
+	my $linecount = 0;
+	my $dot_count = 0;
+
+
+	while (defined ($line = <CMD>))
+	{
+	    $linecount++;
+
+	    my ($had_local_error,$generate_dot) = &$monitor_line($line);
+	    
+	    if ($had_local_error) {
+		# set general flag, but allow loop to continue to end building up the $result line
+		print $outhandle "$line\n";
+		$had_error = 1;
+	    }
+
+	    if ($generate_dot)
+	    {
+		if ($dot_count == 0) { print $outhandle "\n  "; }
+		print $outhandle ".";
+		$dot_count++;
+
+		if (($dot_count%76)==0) 
+		{
+		    print $outhandle "\n  ";
+		}
+	    }
+	
+	    $result .= $line;
+	    
+	}
+	print $outhandle "\n";
+
+	
+	close(CMD);
+
+	$command_status = $?;
+	if ($command_status != 0) {
+	    $had_error = 1;
+
+	    print $outhandle "Error: processing command failed.  Exit status $?\n";
+
+	    if ($verbosity >= 3) {
+		print $outhandle "  Command was: $command\n";
+	    }
+	    if ($verbosity >= 4) {
+		print $outhandle "$message_prefix result: $result\n";
+	    }
+	}
+    }
+    else 
+    {
+	$had_error = 1;
+	print STDERR "Error: failed to execute $command\n";
+    }
+
+    &$monitor_deinit($saved_rec);
+
+    if ($verbosity >= 1) {
+	if ($had_error) {
+	    print $outhandle "  ...error encounterd\n";
+	}
+	else {
+	    print $outhandle "  ...done\n";
+	}
+    }
+
+    if (defined $command_status && ($command_status == 0))
+    {
+	# only want to print the following out if verbosity is high enough
+	# and we haven't already printed it out as a detected error above
+	print $outhandle "$message_prefix result: $result\n" if ($verbosity > 5);
+    }
+
+    return ($result,$had_error);
+}
+
+
+sub regenerate_general_cmd
+{
+    my ($command,$ofilename,$options) = @_;
+
+    my $regenerated = 1;
+    my $result = "";
+    my $had_error = 0;
+
+    ($result,$had_error) = run_general_cmd($command,$options);
+
+    # store command args so can be compared with subsequent runs of the command
+    my $args_filename = "$ofilename.args";
+
+    if (open(ARGSOUT,">$args_filename")) {
+	print ARGSOUT $command;
+	print ARGSOUT "\n";
+	close(ARGSOUT);
+    }
+    else {
+	my $outhandle = $options->{'outhandle'};
+	print $outhandle "Warning: Unable to write out caching information to file $args_filename\n";
+	print $outhandle "         This means $ofilename will be regenerated on next build whether\n";
+	print $outhandle "         processing args have changed or not.\n";
+    }
+
+    # Store the result, since ImageConverter.pm extracts the image height and width from the processed result
+    my $result_filename = "$ofilename.result";
+    if (open(RESOUT, ">$result_filename"))
+    {
+	print RESOUT $result;
+	close(RESOUT);
+    }
+    else
+    {
+	my $outhandle = $options->{'outhandle'};
+	print $outhandle "Warning: Unable to write out cached process result to file $result_filename.\n";
+    }
+
+    return ($regenerated,$result,$had_error);
+}
+
+
+
+sub run_cached_general_cmd
+{
+    my ($command,$ofilename,$options) = @_;
+
+    my $outhandle = $options->{'outhandle'};
+    my $verbosity = $options->{'verbosity'};
+    my $message_prefix = $options->{'message_prefix'};
+
+    my $regenerated = 0;
+    my $result = "";
+    my $had_error = 0;
+
+    my $args_filename = "$ofilename.args";
+
+    if (!-e $ofilename) {
+	($regenerated,$result,$had_error) 
+	    = regenerate_general_cmd($command,$ofilename,$options);
+    }
+    elsif (-M $ofilename > -M $args_filename) {
+	# Source files has been updated/changed in some way
+	# => regenerate
+	print $outhandle "$ofilename modified more recently than cached version\n";
+
+	($regenerated,$result,$had_error) 
+	    = regenerate_general_cmd($command,$ofilename,$options);	
+    }
+    else {
+	# file exists => check to see if command to generate it has changed
+
+	if (open (ARGSIN,"<$args_filename")) {
+	    my $prev_command = <ARGSIN>;
+	    chomp($prev_command);
+
+	    close(ARGSIN);
+
+	    if (defined $prev_command) {
+		# if commands are different
+		if ($prev_command ne $command) {
+		    # need to rerun command
+		    ($regenerated,$result,$had_error) 
+			= regenerate_general_cmd($command,$ofilename,$options);
+		}
+		else {
+		    my ($ofile) = ($ofilename =~ m/^.*(cached.*)$/);
+
+		    my $ofile_no_dir = basename($ofile);
+		    print $outhandle "  $message_prefix: Cached file $ofile_no_dir already exists.\n";
+		    print $outhandle "  $message_prefix: No need to regenerate $ofile\n" if ($verbosity > 2);
+                    
+                    # Read in the cached result lines and join them into a single string
+                    my $result_filename = "$ofilename.result";
+                    if (open(RESIN, "<$result_filename"))
+		    {
+                      my @result_lines = <RESIN>;
+                      $result = join("\n", @result_lines);
+                      close(RESIN);
+                    }
+                    else
+		    {
+                      print $outhandle "  $message_prefix: Error, failed to obtain cached result from $result_filename.\n";
+                    }
+		}
+		    
+	    }
+	}
+	else {
+	    print $outhandle "  $message_prefix: No cached previous args found.  Regenerating $ofilename\n";
+
+	    ($regenerated,$result,$had_error) = regenerate_general_cmd($command,$ofilename,$options);
+	}
+    }
+
+    return ($regenerated,$result,$had_error);
+}
+
+
+1;
Index: /gsdl/stable/perllib/cpan/Crypt/UnixCrypt.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Crypt/UnixCrypt.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Crypt/UnixCrypt.pm	(revision 20131)
@@ -0,0 +1,749 @@
+package Crypt::UnixCrypt;
+
+use 5.004;  # i.e. not tested under earlier versions
+use strict;
+use vars qw($VERSION @ISA @EXPORT $OVERRIDE_BUILTIN);
+
+$VERSION = '1.0';
+
+require Exporter;
+@ISA = qw(Exporter);
+
+# Don't override built-in crypt() unless forced to to so
+use Config;
+@EXPORT = qw(crypt)
+	if !defined $Config{d_crypt} ||
+	   (defined $OVERRIDE_BUILTIN && $OVERRIDE_BUILTIN);
+
+
+my $ITERATIONS = 16;
+
+my @con_salt =
+(
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 
+	0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 
+	0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 
+	0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 
+	0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 
+	0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 
+	0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24, 
+	0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 
+	0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 
+	0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 
+	0x3D, 0x3E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 
+);
+
+my @shifts2 =
+(
+	0, 0, 1, 1, 1, 1, 1, 1,
+	0, 1, 1, 1, 1, 1, 1, 0
+);
+
+my @skb0 =
+(
+	# for C bits (numbered as per FIPS 46) 1 2 3 4 5 6
+	0x00000000, 0x00000010, 0x20000000, 0x20000010, 
+	0x00010000, 0x00010010, 0x20010000, 0x20010010, 
+	0x00000800, 0x00000810, 0x20000800, 0x20000810, 
+	0x00010800, 0x00010810, 0x20010800, 0x20010810, 
+	0x00000020, 0x00000030, 0x20000020, 0x20000030, 
+	0x00010020, 0x00010030, 0x20010020, 0x20010030, 
+	0x00000820, 0x00000830, 0x20000820, 0x20000830, 
+	0x00010820, 0x00010830, 0x20010820, 0x20010830, 
+	0x00080000, 0x00080010, 0x20080000, 0x20080010, 
+	0x00090000, 0x00090010, 0x20090000, 0x20090010, 
+	0x00080800, 0x00080810, 0x20080800, 0x20080810, 
+	0x00090800, 0x00090810, 0x20090800, 0x20090810, 
+	0x00080020, 0x00080030, 0x20080020, 0x20080030, 
+	0x00090020, 0x00090030, 0x20090020, 0x20090030, 
+	0x00080820, 0x00080830, 0x20080820, 0x20080830, 
+	0x00090820, 0x00090830, 0x20090820, 0x20090830, 
+);
+my @skb1 =
+(
+	# for C bits (numbered as per FIPS 46) 7 8 10 11 12 13
+	0x00000000, 0x02000000, 0x00002000, 0x02002000, 
+	0x00200000, 0x02200000, 0x00202000, 0x02202000, 
+	0x00000004, 0x02000004, 0x00002004, 0x02002004, 
+	0x00200004, 0x02200004, 0x00202004, 0x02202004, 
+	0x00000400, 0x02000400, 0x00002400, 0x02002400, 
+	0x00200400, 0x02200400, 0x00202400, 0x02202400, 
+	0x00000404, 0x02000404, 0x00002404, 0x02002404, 
+	0x00200404, 0x02200404, 0x00202404, 0x02202404, 
+	0x10000000, 0x12000000, 0x10002000, 0x12002000, 
+	0x10200000, 0x12200000, 0x10202000, 0x12202000, 
+	0x10000004, 0x12000004, 0x10002004, 0x12002004, 
+	0x10200004, 0x12200004, 0x10202004, 0x12202004, 
+	0x10000400, 0x12000400, 0x10002400, 0x12002400, 
+	0x10200400, 0x12200400, 0x10202400, 0x12202400, 
+	0x10000404, 0x12000404, 0x10002404, 0x12002404, 
+	0x10200404, 0x12200404, 0x10202404, 0x12202404, 
+);
+my @skb2 =
+(
+	# for C bits (numbered as per FIPS 46) 14 15 16 17 19 20
+	0x00000000, 0x00000001, 0x00040000, 0x00040001, 
+	0x01000000, 0x01000001, 0x01040000, 0x01040001, 
+	0x00000002, 0x00000003, 0x00040002, 0x00040003, 
+	0x01000002, 0x01000003, 0x01040002, 0x01040003, 
+	0x00000200, 0x00000201, 0x00040200, 0x00040201, 
+	0x01000200, 0x01000201, 0x01040200, 0x01040201, 
+	0x00000202, 0x00000203, 0x00040202, 0x00040203, 
+	0x01000202, 0x01000203, 0x01040202, 0x01040203, 
+	0x08000000, 0x08000001, 0x08040000, 0x08040001, 
+	0x09000000, 0x09000001, 0x09040000, 0x09040001, 
+	0x08000002, 0x08000003, 0x08040002, 0x08040003, 
+	0x09000002, 0x09000003, 0x09040002, 0x09040003, 
+	0x08000200, 0x08000201, 0x08040200, 0x08040201, 
+	0x09000200, 0x09000201, 0x09040200, 0x09040201, 
+	0x08000202, 0x08000203, 0x08040202, 0x08040203, 
+	0x09000202, 0x09000203, 0x09040202, 0x09040203, 
+);
+my @skb3 =
+(
+	# for C bits (numbered as per FIPS 46) 21 23 24 26 27 28
+	0x00000000, 0x00100000, 0x00000100, 0x00100100, 
+	0x00000008, 0x00100008, 0x00000108, 0x00100108, 
+	0x00001000, 0x00101000, 0x00001100, 0x00101100, 
+	0x00001008, 0x00101008, 0x00001108, 0x00101108, 
+	0x04000000, 0x04100000, 0x04000100, 0x04100100, 
+	0x04000008, 0x04100008, 0x04000108, 0x04100108, 
+	0x04001000, 0x04101000, 0x04001100, 0x04101100, 
+	0x04001008, 0x04101008, 0x04001108, 0x04101108, 
+	0x00020000, 0x00120000, 0x00020100, 0x00120100, 
+	0x00020008, 0x00120008, 0x00020108, 0x00120108, 
+	0x00021000, 0x00121000, 0x00021100, 0x00121100, 
+	0x00021008, 0x00121008, 0x00021108, 0x00121108, 
+	0x04020000, 0x04120000, 0x04020100, 0x04120100, 
+	0x04020008, 0x04120008, 0x04020108, 0x04120108, 
+	0x04021000, 0x04121000, 0x04021100, 0x04121100, 
+	0x04021008, 0x04121008, 0x04021108, 0x04121108, 
+);
+my @skb4 =
+(
+	# for D bits (numbered as per FIPS 46) 1 2 3 4 5 6
+	0x00000000, 0x10000000, 0x00010000, 0x10010000, 
+	0x00000004, 0x10000004, 0x00010004, 0x10010004, 
+	0x20000000, 0x30000000, 0x20010000, 0x30010000, 
+	0x20000004, 0x30000004, 0x20010004, 0x30010004, 
+	0x00100000, 0x10100000, 0x00110000, 0x10110000, 
+	0x00100004, 0x10100004, 0x00110004, 0x10110004, 
+	0x20100000, 0x30100000, 0x20110000, 0x30110000, 
+	0x20100004, 0x30100004, 0x20110004, 0x30110004, 
+	0x00001000, 0x10001000, 0x00011000, 0x10011000, 
+	0x00001004, 0x10001004, 0x00011004, 0x10011004, 
+	0x20001000, 0x30001000, 0x20011000, 0x30011000, 
+	0x20001004, 0x30001004, 0x20011004, 0x30011004, 
+	0x00101000, 0x10101000, 0x00111000, 0x10111000, 
+	0x00101004, 0x10101004, 0x00111004, 0x10111004, 
+	0x20101000, 0x30101000, 0x20111000, 0x30111000, 
+	0x20101004, 0x30101004, 0x20111004, 0x30111004, 
+);
+my @skb5 =
+(
+	# for D bits (numbered as per FIPS 46) 8 9 11 12 13 14
+	0x00000000, 0x08000000, 0x00000008, 0x08000008, 
+	0x00000400, 0x08000400, 0x00000408, 0x08000408, 
+	0x00020000, 0x08020000, 0x00020008, 0x08020008, 
+	0x00020400, 0x08020400, 0x00020408, 0x08020408, 
+	0x00000001, 0x08000001, 0x00000009, 0x08000009, 
+	0x00000401, 0x08000401, 0x00000409, 0x08000409, 
+	0x00020001, 0x08020001, 0x00020009, 0x08020009, 
+	0x00020401, 0x08020401, 0x00020409, 0x08020409, 
+	0x02000000, 0x0A000000, 0x02000008, 0x0A000008, 
+	0x02000400, 0x0A000400, 0x02000408, 0x0A000408, 
+	0x02020000, 0x0A020000, 0x02020008, 0x0A020008, 
+	0x02020400, 0x0A020400, 0x02020408, 0x0A020408, 
+	0x02000001, 0x0A000001, 0x02000009, 0x0A000009, 
+	0x02000401, 0x0A000401, 0x02000409, 0x0A000409, 
+	0x02020001, 0x0A020001, 0x02020009, 0x0A020009, 
+	0x02020401, 0x0A020401, 0x02020409, 0x0A020409, 
+);
+my @skb6 =
+(
+	# for D bits (numbered as per FIPS 46) 16 17 18 19 20 21
+	0x00000000, 0x00000100, 0x00080000, 0x00080100, 
+	0x01000000, 0x01000100, 0x01080000, 0x01080100, 
+	0x00000010, 0x00000110, 0x00080010, 0x00080110, 
+	0x01000010, 0x01000110, 0x01080010, 0x01080110, 
+	0x00200000, 0x00200100, 0x00280000, 0x00280100, 
+	0x01200000, 0x01200100, 0x01280000, 0x01280100, 
+	0x00200010, 0x00200110, 0x00280010, 0x00280110, 
+	0x01200010, 0x01200110, 0x01280010, 0x01280110, 
+	0x00000200, 0x00000300, 0x00080200, 0x00080300, 
+	0x01000200, 0x01000300, 0x01080200, 0x01080300, 
+	0x00000210, 0x00000310, 0x00080210, 0x00080310, 
+	0x01000210, 0x01000310, 0x01080210, 0x01080310, 
+	0x00200200, 0x00200300, 0x00280200, 0x00280300, 
+	0x01200200, 0x01200300, 0x01280200, 0x01280300, 
+	0x00200210, 0x00200310, 0x00280210, 0x00280310, 
+	0x01200210, 0x01200310, 0x01280210, 0x01280310, 
+);
+my @skb7 =
+(
+	# for D bits (numbered as per FIPS 46) 22 23 24 25 27 28
+	0x00000000, 0x04000000, 0x00040000, 0x04040000, 
+	0x00000002, 0x04000002, 0x00040002, 0x04040002, 
+	0x00002000, 0x04002000, 0x00042000, 0x04042000, 
+	0x00002002, 0x04002002, 0x00042002, 0x04042002, 
+	0x00000020, 0x04000020, 0x00040020, 0x04040020, 
+	0x00000022, 0x04000022, 0x00040022, 0x04040022, 
+	0x00002020, 0x04002020, 0x00042020, 0x04042020, 
+	0x00002022, 0x04002022, 0x00042022, 0x04042022, 
+	0x00000800, 0x04000800, 0x00040800, 0x04040800, 
+	0x00000802, 0x04000802, 0x00040802, 0x04040802, 
+	0x00002800, 0x04002800, 0x00042800, 0x04042800, 
+	0x00002802, 0x04002802, 0x00042802, 0x04042802, 
+	0x00000820, 0x04000820, 0x00040820, 0x04040820, 
+	0x00000822, 0x04000822, 0x00040822, 0x04040822, 
+	0x00002820, 0x04002820, 0x00042820, 0x04042820, 
+	0x00002822, 0x04002822, 0x00042822, 0x04042822, 
+);
+
+my @SPtrans0 =
+(
+	# nibble 0
+	0x00820200, 0x00020000, 0x80800000, 0x80820200,
+	0x00800000, 0x80020200, 0x80020000, 0x80800000,
+	0x80020200, 0x00820200, 0x00820000, 0x80000200,
+	0x80800200, 0x00800000, 0x00000000, 0x80020000,
+	0x00020000, 0x80000000, 0x00800200, 0x00020200,
+	0x80820200, 0x00820000, 0x80000200, 0x00800200,
+	0x80000000, 0x00000200, 0x00020200, 0x80820000,
+	0x00000200, 0x80800200, 0x80820000, 0x00000000,
+	0x00000000, 0x80820200, 0x00800200, 0x80020000,
+	0x00820200, 0x00020000, 0x80000200, 0x00800200,
+	0x80820000, 0x00000200, 0x00020200, 0x80800000,
+	0x80020200, 0x80000000, 0x80800000, 0x00820000,
+	0x80820200, 0x00020200, 0x00820000, 0x80800200,
+	0x00800000, 0x80000200, 0x80020000, 0x00000000,
+	0x00020000, 0x00800000, 0x80800200, 0x00820200,
+	0x80000000, 0x80820000, 0x00000200, 0x80020200,
+);
+my @SPtrans1 =
+(
+	# nibble 1
+	0x10042004, 0x00000000, 0x00042000, 0x10040000,
+	0x10000004, 0x00002004, 0x10002000, 0x00042000,
+	0x00002000, 0x10040004, 0x00000004, 0x10002000,
+	0x00040004, 0x10042000, 0x10040000, 0x00000004,
+	0x00040000, 0x10002004, 0x10040004, 0x00002000,
+	0x00042004, 0x10000000, 0x00000000, 0x00040004,
+	0x10002004, 0x00042004, 0x10042000, 0x10000004,
+	0x10000000, 0x00040000, 0x00002004, 0x10042004,
+	0x00040004, 0x10042000, 0x10002000, 0x00042004,
+	0x10042004, 0x00040004, 0x10000004, 0x00000000,
+	0x10000000, 0x00002004, 0x00040000, 0x10040004,
+	0x00002000, 0x10000000, 0x00042004, 0x10002004,
+	0x10042000, 0x00002000, 0x00000000, 0x10000004,
+	0x00000004, 0x10042004, 0x00042000, 0x10040000,
+	0x10040004, 0x00040000, 0x00002004, 0x10002000,
+	0x10002004, 0x00000004, 0x10040000, 0x00042000,
+);
+my @SPtrans2 =
+(
+	# nibble 2
+	0x41000000, 0x01010040, 0x00000040, 0x41000040,
+	0x40010000, 0x01000000, 0x41000040, 0x00010040,
+	0x01000040, 0x00010000, 0x01010000, 0x40000000,
+	0x41010040, 0x40000040, 0x40000000, 0x41010000,
+	0x00000000, 0x40010000, 0x01010040, 0x00000040,
+	0x40000040, 0x41010040, 0x00010000, 0x41000000,
+	0x41010000, 0x01000040, 0x40010040, 0x01010000,
+	0x00010040, 0x00000000, 0x01000000, 0x40010040,
+	0x01010040, 0x00000040, 0x40000000, 0x00010000,
+	0x40000040, 0x40010000, 0x01010000, 0x41000040,
+	0x00000000, 0x01010040, 0x00010040, 0x41010000,
+	0x40010000, 0x01000000, 0x41010040, 0x40000000,
+	0x40010040, 0x41000000, 0x01000000, 0x41010040,
+	0x00010000, 0x01000040, 0x41000040, 0x00010040,
+	0x01000040, 0x00000000, 0x41010000, 0x40000040,
+	0x41000000, 0x40010040, 0x00000040, 0x01010000,
+);
+my @SPtrans3 =
+(
+	# nibble 3
+	0x00100402, 0x04000400, 0x00000002, 0x04100402,
+	0x00000000, 0x04100000, 0x04000402, 0x00100002,
+	0x04100400, 0x04000002, 0x04000000, 0x00000402,
+	0x04000002, 0x00100402, 0x00100000, 0x04000000,
+	0x04100002, 0x00100400, 0x00000400, 0x00000002,
+	0x00100400, 0x04000402, 0x04100000, 0x00000400,
+	0x00000402, 0x00000000, 0x00100002, 0x04100400,
+	0x04000400, 0x04100002, 0x04100402, 0x00100000,
+	0x04100002, 0x00000402, 0x00100000, 0x04000002,
+	0x00100400, 0x04000400, 0x00000002, 0x04100000,
+	0x04000402, 0x00000000, 0x00000400, 0x00100002,
+	0x00000000, 0x04100002, 0x04100400, 0x00000400,
+	0x04000000, 0x04100402, 0x00100402, 0x00100000,
+	0x04100402, 0x00000002, 0x04000400, 0x00100402,
+	0x00100002, 0x00100400, 0x04100000, 0x04000402,
+	0x00000402, 0x04000000, 0x04000002, 0x04100400,
+);
+my @SPtrans4 =
+(
+	# nibble 4
+	0x02000000, 0x00004000, 0x00000100, 0x02004108,
+	0x02004008, 0x02000100, 0x00004108, 0x02004000,
+	0x00004000, 0x00000008, 0x02000008, 0x00004100,
+	0x02000108, 0x02004008, 0x02004100, 0x00000000,
+	0x00004100, 0x02000000, 0x00004008, 0x00000108,
+	0x02000100, 0x00004108, 0x00000000, 0x02000008,
+	0x00000008, 0x02000108, 0x02004108, 0x00004008,
+	0x02004000, 0x00000100, 0x00000108, 0x02004100,
+	0x02004100, 0x02000108, 0x00004008, 0x02004000,
+	0x00004000, 0x00000008, 0x02000008, 0x02000100,
+	0x02000000, 0x00004100, 0x02004108, 0x00000000,
+	0x00004108, 0x02000000, 0x00000100, 0x00004008,
+	0x02000108, 0x00000100, 0x00000000, 0x02004108,
+	0x02004008, 0x02004100, 0x00000108, 0x00004000,
+	0x00004100, 0x02004008, 0x02000100, 0x00000108,
+	0x00000008, 0x00004108, 0x02004000, 0x02000008,
+);
+my @SPtrans5 =
+(
+	# nibble 5
+	0x20000010, 0x00080010, 0x00000000, 0x20080800,
+	0x00080010, 0x00000800, 0x20000810, 0x00080000,
+	0x00000810, 0x20080810, 0x00080800, 0x20000000,
+	0x20000800, 0x20000010, 0x20080000, 0x00080810,
+	0x00080000, 0x20000810, 0x20080010, 0x00000000,
+	0x00000800, 0x00000010, 0x20080800, 0x20080010,
+	0x20080810, 0x20080000, 0x20000000, 0x00000810,
+	0x00000010, 0x00080800, 0x00080810, 0x20000800,
+	0x00000810, 0x20000000, 0x20000800, 0x00080810,
+	0x20080800, 0x00080010, 0x00000000, 0x20000800,
+	0x20000000, 0x00000800, 0x20080010, 0x00080000,
+	0x00080010, 0x20080810, 0x00080800, 0x00000010,
+	0x20080810, 0x00080800, 0x00080000, 0x20000810,
+	0x20000010, 0x20080000, 0x00080810, 0x00000000,
+	0x00000800, 0x20000010, 0x20000810, 0x20080800,
+	0x20080000, 0x00000810, 0x00000010, 0x20080010,
+);
+my @SPtrans6 =
+(
+	# nibble 6
+	0x00001000, 0x00000080, 0x00400080, 0x00400001,
+	0x00401081, 0x00001001, 0x00001080, 0x00000000,
+	0x00400000, 0x00400081, 0x00000081, 0x00401000,
+	0x00000001, 0x00401080, 0x00401000, 0x00000081,
+	0x00400081, 0x00001000, 0x00001001, 0x00401081,
+	0x00000000, 0x00400080, 0x00400001, 0x00001080,
+	0x00401001, 0x00001081, 0x00401080, 0x00000001,
+	0x00001081, 0x00401001, 0x00000080, 0x00400000,
+	0x00001081, 0x00401000, 0x00401001, 0x00000081,
+	0x00001000, 0x00000080, 0x00400000, 0x00401001,
+	0x00400081, 0x00001081, 0x00001080, 0x00000000,
+	0x00000080, 0x00400001, 0x00000001, 0x00400080,
+	0x00000000, 0x00400081, 0x00400080, 0x00001080,
+	0x00000081, 0x00001000, 0x00401081, 0x00400000,
+	0x00401080, 0x00000001, 0x00001001, 0x00401081,
+	0x00400001, 0x00401080, 0x00401000, 0x00001001,
+);
+my @SPtrans7 =
+(
+	# nibble 7
+	0x08200020, 0x08208000, 0x00008020, 0x00000000,
+	0x08008000, 0x00200020, 0x08200000, 0x08208020,
+	0x00000020, 0x08000000, 0x00208000, 0x00008020,
+	0x00208020, 0x08008020, 0x08000020, 0x08200000,
+	0x00008000, 0x00208020, 0x00200020, 0x08008000,
+	0x08208020, 0x08000020, 0x00000000, 0x00208000,
+	0x08000000, 0x00200000, 0x08008020, 0x08200020,
+	0x00200000, 0x00008000, 0x08208000, 0x00000020,
+	0x00200000, 0x00008000, 0x08000020, 0x08208020,
+	0x00008020, 0x08000000, 0x00000000, 0x00208000,
+	0x08200020, 0x08008020, 0x08008000, 0x00200020,
+	0x08208000, 0x00000020, 0x00200020, 0x08008000,
+	0x08208020, 0x00200000, 0x08200000, 0x08000020,
+	0x00208000, 0x00008020, 0x08008020, 0x08200000,
+	0x00000020, 0x08208000, 0x00208020, 0x00000000,
+	0x08000000, 0x08200020, 0x00008000, 0x00208020
+);
+
+my @cov_2char =
+(
+	0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 
+	0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 
+	0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 
+	0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 
+	0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 
+	0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 
+	0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 
+	0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
+);
+
+sub ushr  # only for ints! (mimics the Java >>> operator)
+{
+	my ($n, $s) = @_;
+
+	$s &= 0x1f;
+
+	return( ($n >> $s) & (~0 >> $s) );
+}
+
+sub toByte
+{
+	my $value = shift;
+
+	$value &= 0xff;
+	$value = - ((~$value & 0xff) + 1)
+		if $value & 0x80;
+
+	return $value;
+}
+
+sub toInt
+{
+	my $value = shift;
+
+	$value = - ((~$value & 0xffffffff) + 1)
+		if $value & 0x80000000;
+
+	return $value;
+}
+
+sub byteToUnsigned # int byteToUnsigned(byte b)
+{
+	my $value = shift;
+
+	return( $value >= 0 ? $value : $value + 256 );
+}
+
+sub fourBytesToInt # int fourBytesToInt(byte b[], int offset)
+{
+	my ($b, $offset) = @_;
+	my $value;
+
+	$value  =  byteToUnsigned($b->[$offset++]);
+	$value |= (byteToUnsigned($b->[$offset++]) <<  8);
+	$value |= (byteToUnsigned($b->[$offset++]) << 16);
+	$value |= (byteToUnsigned($b->[$offset++]) << 24);
+
+	return toInt($value);
+}
+
+sub intToFourBytes # void intToFourBytes(int iValue, byte b[], int offset)
+{
+	my ($iValue, $b, $offset) = @_;
+
+	$b->[$offset++] = toByte(ushr($iValue, 0) & 0xff);
+	$b->[$offset++] = toByte(ushr($iValue, 8) & 0xff);
+	$b->[$offset++] = toByte(ushr($iValue,16) & 0xff);
+	$b->[$offset++] = toByte(ushr($iValue,24) & 0xff);
+
+	return undef;
+}
+
+sub PERM_OP # void PERM_OP(int a, int b, int n, int m, int results[])
+{
+	my ($a, $b, $n, $m, $results) = @_;
+	my $t;
+
+	$t = (ushr($a,$n) ^ $b) & $m;
+	$a ^= $t << $n;
+	$b ^= $t;
+
+	$results->[0] = toInt($a);
+	$results->[1] = toInt($b);
+
+	return undef;
+}
+
+sub HPERM_OP # void HPERM_OP(int a, int n, int m)
+{
+	my ($a, $n, $m) = @_;
+	my $t;
+
+	$t = (($a << (16 - $n)) ^ $a) & $m;
+	$a = $a ^ $t ^ ushr($t, 16 - $n);
+
+	return toInt($a);
+}
+
+sub des_set_key # int [] des_set_key(byte key[])
+{
+	my ($key) = @_;
+	my @schedule; $#schedule = $ITERATIONS * 2 -1;
+
+	my $c = fourBytesToInt($key, 0);
+	my $d = fourBytesToInt($key, 4);
+
+	my @results; $#results = 1;
+
+	PERM_OP($d, $c, 4, 0x0f0f0f0f, \@results);
+	$d = $results[0]; $c = $results[1];
+
+	$c = HPERM_OP($c, -2, 0xcccc0000);
+	$d = HPERM_OP($d, -2, 0xcccc0000);
+
+	PERM_OP($d, $c, 1, 0x55555555, \@results);
+	$d = $results[0]; $c = $results[1];
+
+	PERM_OP($c, $d, 8, 0x00ff00ff, \@results);
+	$c = $results[0]; $d = $results[1];
+
+	PERM_OP($d, $c, 1, 0x55555555, \@results);
+	$d = $results[0]; $c = $results[1];
+
+	$d = (    (($d & 0x000000ff) << 16) |     ($d & 0x0000ff00)  |
+	       ushr($d & 0x00ff0000,    16) | ushr($c & 0xf0000000, 4));
+	$c &= 0x0fffffff;
+
+	my ($s, $t);
+	my ($i, $j);
+
+	$j = 0;
+	for($i = 0; $i < $ITERATIONS; $i++)
+	{
+		if($shifts2[$i])
+		{
+			$c = ushr($c, 2) | ($c << 26);
+			$d = ushr($d, 2) | ($d << 26);
+		}
+		else
+		{
+			$c = ushr($c, 1) | ($c << 27);
+			$d = ushr($d, 1) | ($d << 27);
+		}
+
+		$c &= 0x0fffffff;
+		$d &= 0x0fffffff;
+
+		$s = $skb0[     ($c   ) & 0x3f                        ]|
+		     $skb1[(ushr($c, 6) & 0x03) | (ushr($c, 7) & 0x3c)]|
+		     $skb2[(ushr($c,13) & 0x0f) | (ushr($c,14) & 0x30)]|
+		     $skb3[(ushr($c,20) & 0x01) | (ushr($c,21) & 0x06) |
+		                                  (ushr($c,22) & 0x38)];
+
+		$t = $skb4[     ($d   ) & 0x3f                         ]|
+		     $skb5[(ushr($d, 7) & 0x03) | (ushr($d, 8) & 0x3c) ]|
+		     $skb6[ ushr($d,15) & 0x3f                         ]|
+		     $skb7[(ushr($d,21) & 0x0f) | (ushr($d,22) & 0x30)];
+
+		$schedule[$j++] = (    ($t << 16) | ($s & 0x0000ffff)) & 0xffffffff;
+		$s              = (ushr($s,   16) | ($t & 0xffff0000));
+
+		$s              = ($s << 4) | ushr($s,28);
+		$schedule[$j++] = $s & 0xffffffff;
+	}
+
+	return \@schedule;
+}
+
+sub D_ENCRYPT # int D_ENCRYPT(int L, int R, int S, int E0, int E1, int s[])
+{
+	my ($L, $R, $S, $E0, $E1, $s) = @_;
+	my ($t, $u, $v);
+
+	$v = $R ^ ushr($R,16);
+	$u = $v & $E0;
+	$v = $v & $E1;
+	$u = ($u ^ ($u << 16)) ^ $R ^ $s->[$S];
+	$t = ($v ^ ($v << 16)) ^ $R ^ $s->[$S + 1];
+	$t = ushr($t, 4) | ($t << 28);
+
+	$L ^= $SPtrans1[    ($t    ) & 0x3f] |
+	      $SPtrans3[ushr($t,  8) & 0x3f] |
+	      $SPtrans5[ushr($t, 16) & 0x3f] |
+	      $SPtrans7[ushr($t, 24) & 0x3f] |
+	      $SPtrans0[    ($u    ) & 0x3f] |
+	      $SPtrans2[ushr($u,  8) & 0x3f] |
+	      $SPtrans4[ushr($u, 16) & 0x3f] |
+	      $SPtrans6[ushr($u, 24) & 0x3f];
+
+	return $L;
+}
+
+sub body # int [] body(int schedule[], int Eswap0, int Eswap1)
+{
+	my ($schedule, $Eswap0, $Eswap1) = @_;
+	my $left  = 0;
+	my $right = 0;
+	my $t     = 0;
+
+	my ($i, $j);
+	for($j = 0; $j < 25; $j++)
+	{
+		for($i = 0; $i < $ITERATIONS * 2; $i += 4)
+		{
+			$left  = D_ENCRYPT($left,  $right, $i,     $Eswap0, $Eswap1, $schedule);
+			$right = D_ENCRYPT($right, $left,  $i + 2, $Eswap0, $Eswap1, $schedule);
+		}
+		$t     = $left; 
+		$left  = $right; 
+		$right = $t;
+	}
+
+	$t = $right;
+
+	$right = ushr($left, 1) | ($left << 31);
+	$left  = ushr($t   , 1) | ($t    << 31);
+
+	$left  &= 0xffffffff;
+	$right &= 0xffffffff;
+
+	my @results; $#results = 1;
+
+	PERM_OP($right, $left, 1, 0x55555555, \@results); 
+	$right = $results[0]; $left = $results[1];
+
+	PERM_OP($left, $right, 8, 0x00ff00ff, \@results); 
+	$left = $results[0]; $right = $results[1];
+
+	PERM_OP($right, $left, 2, 0x33333333, \@results); 
+	$right = $results[0]; $left = $results[1];
+
+	PERM_OP($left, $right, 16, 0x0000ffff, \@results);
+	$left = $results[0]; $right = $results[1];
+
+	PERM_OP($right, $left, 4, 0x0f0f0f0f, \@results);
+	$right = $results[0]; $left = $results[1];
+
+	my @out; $#out = 1;
+
+	$out[0] = $left; $out[1] = $right;
+
+	return \@out;
+}
+
+sub crypt($$) # String crypt(String plaintext, String salt)
+{
+	my ($plaintext, $salt) = @_;
+	my $buffer = '';
+
+	return $buffer if !defined $salt || $salt eq '';
+
+	$salt .= $salt if length $salt < 2;
+	$plaintext = '' if !defined $plaintext;
+ 
+	$buffer = substr $salt,0,2;
+
+	my $Eswap0 = $con_salt[ord(substr $salt,0,1)];
+	my $Eswap1 = $con_salt[ord(substr $salt,1,1)] << 4;
+
+	my @key;
+	@key[0..7] = (0) x 8;
+
+	my @iChar = map { ord($_) << 1 } split(//, $plaintext);
+	my $i;
+	for (my $i = 0; $i < @key && $i < @iChar; $i++) {
+		$key[$i] = toByte($iChar[$i]);
+	}
+
+	my $schedule = des_set_key(\@key);
+	my $out      = body($schedule, $Eswap0, $Eswap1);
+
+	my @b; $#b = 8;
+
+	intToFourBytes($out->[0], \@b, 0);
+	intToFourBytes($out->[1], \@b, 4);
+	$b[8] = 0;
+
+	my ($j, $c, $y, $u);
+	for($i = 2, $y = 0, $u = 0x80; $i < 13; $i++)
+	{
+		for($j = 0, $c = 0; $j < 6; $j++)
+		{
+			$c <<= 1;
+
+			$c |= 1 if ($b[$y] & $u) != 0;
+
+			$u >>= 1;
+
+			if($u == 0)
+			{
+				$y++;
+				$u = 0x80;
+			}
+		}
+		$buffer .= chr($cov_2char[$c]);
+	}
+
+	return $buffer;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Crypt::UnixCrypt - perl-only implementation of the C<crypt> function.
+
+=head1 SYNOPSIS
+
+  use Crypt::UnixCrypt;
+  $hashed = crypt($plaintext,$salt);
+
+  # always use this module's crypt
+  BEGIN { $Crypt::UnixCrpyt::OVERRIDE_BUILTIN = 1 }
+  use Crypt::UnixCrypt;
+
+=head1 DESCRIPTION
+
+This module is for all those poor souls whose perl port answers to the
+use of C<crypt()> with the message `The crypt() function is unimplemented
+due to excessive paranoia.'.
+
+This module won't overload a built-in C<crypt()> unless forced by a true
+value of the variable C<$Crypt::UnixCrypt::OVERRIDE_BUILTIN>.
+
+If you use this module, you probably neither have a built-in C<crypt()>
+function nor a L<crypt(3)> manpage; so I'll supply the appropriate portions
+of its description (from my Linux system) here:
+
+crypt is the password encryption function. It is based on the Data
+Encryption Standard algorithm with variations intended (among other
+things) to discourage use of hardware implementations of a key search.
+
+$plaintext is a user's typed password.
+
+$salt is a two-character string chosen from the set [a-zA-Z0-9./]. This
+string is used to perturb the algorithm in one of 4096 different ways.
+
+By taking the lowest 7 bit of each character of $plaintext (filling it up
+to 8 characters with zeros, if needed), a 56-bit key is obtained. This
+56-bit key is used to encrypt repeatedly a constant string (usually a
+string consisting of all zeros). The returned value points to the
+encrypted password, a series of 13 printable ASCII characters (the first
+two characters represent the salt itself).
+
+Warning: The key space consists of 2**56 equal 7.2e16 possible values.
+Exhaustive searches of this key space are possible using massively
+parallel computers. Software, such as crack(1), is available which will
+search the portion of this key space that is generally used by humans
+for passwords. Hence, password selection should, at minimum, avoid
+common words and names. The use of a passwd(1) program that checks for
+crackable passwords during the selection process is recommended.
+
+The DES algorithm itself has a few quirks which make the use of the
+crypt(3) interface a very poor choice for anything other than password
+authentication. If you are planning on using the crypt(3) interface for
+a cryptography project, don't do it: get a good book on encryption and
+one of the widely available DES libraries.
+
+=head1 COPYRIGHT
+
+This module is free software; you may redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 AUTHORS
+
+Written by Martin Vorlaender, martin@radiogaga.harz.de, 11-DEC-1997.
+Based upon Java source code written by jdumas@zgs.com, which in turn is
+based upon C source code written by Eric Young, eay@psych.uq.oz.au.
+
+=head1 CAVEATS
+
+In extreme situations, this function doesn't behave like C<crypt(3)>,
+e.g. when called with a salt not in [A-Za-z0-9./]{2}.
+
+=head1 SEE ALSO
+
+perl(1), perlfunc(1), crypt(3).
+
Index: /gsdl/stable/perllib/cpan/File/RandomAccess.pm
===================================================================
--- /gsdl/stable/perllib/cpan/File/RandomAccess.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/File/RandomAccess.pm	(revision 20131)
@@ -0,0 +1,345 @@
+#------------------------------------------------------------------------------
+# File:         RandomAccess.pm
+#
+# Description:  Buffer to support random access reading of sequential file
+#
+# Revisions:    02/11/04 - P. Harvey Created
+#               02/20/04 - P. Harvey Added flag to disable SeekTest in new()
+#               11/18/04 - P. Harvey Fixed bug with seek relative to end of file
+#               01/02/05 - P. Harvey Added DEBUG code
+#               01/09/06 - P. Harvey Fixed bug in ReadLine() when using
+#                          multi-character EOL sequences
+#               02/20/06 - P. Harvey Fixed bug where seek past end of file could
+#                          generate "substr outside string" warning
+#               06/10/06 - P. Harvey Decreased $CHUNK_SIZE from 64k to 8k
+#               11/23/06 - P. Harvey Limit reads to < 0x80000000 bytes
+#
+# Notes:        Calls the normal file i/o routines unless SeekTest() fails, in
+#               which case the file is buffered in memory to allow random access.
+#               SeekTest() is called automatically when the object is created
+#               unless specified.
+#
+#               May also be used for string i/o (just pass a scalar reference)
+#
+# Legal:        Copyright (c) 2004-2006 Phil Harvey (phil at owl.phy.queensu.ca)
+#               This library is free software; you can redistribute it and/or
+#               modify it under the same terms as Perl itself.
+#------------------------------------------------------------------------------
+
+package File::RandomAccess;
+
+use strict;
+require 5.002;
+require Exporter;
+
+use vars qw($VERSION @ISA @EXPORT_OK);
+$VERSION = '1.07';
+@ISA = qw(Exporter);
+
+# constants
+my $CHUNK_SIZE = 8192;  # size of chunks to read from file (must be power of 2)
+my $SLURP_CHUNKS = 16;  # read this many chunks at a time when slurping
+
+#------------------------------------------------------------------------------
+# Create new RandomAccess object
+# Inputs: 0) reference to RandomAccess object or RandomAccess class name
+#         1) file reference or scalar reference
+#         2) flag set if file is already random access (disables automatic SeekTest)
+sub new($$;$)
+{
+    my ($that, $filePt, $isRandom) = @_;
+    my $class = ref($that) || $that;
+    my $self;
+
+    if (ref $filePt eq 'SCALAR') {
+        # string i/o
+        $self = {
+            BUFF_PT => $filePt,
+            POS => 0,
+            LEN => length($$filePt),
+            TESTED => -1,
+        };
+        bless $self, $class;
+    } else {
+        # file i/o
+        my $buff = '';
+        $self = { 
+            FILE_PT => $filePt, # file pointer
+            BUFF_PT => \$buff,  # reference to file data
+            POS => 0,           # current position in file
+            LEN => 0,           # data length
+            TESTED => 0,        # 0=untested, 1=passed, -1=failed (requires buffering)
+        };
+        bless $self, $class;
+        $self->SeekTest() unless $isRandom;
+    }
+    return $self;
+}
+
+#------------------------------------------------------------------------------
+# Enable DEBUG code
+# Inputs: 0) reference to RandomAccess object
+sub Debug($)
+{
+    my $self = shift;
+    $self->{DEBUG} = { };
+}
+
+#------------------------------------------------------------------------------
+# Perform seek test and turn on buffering if necessary
+# Inputs: 0) reference to RandomAccess object
+# Returns: 1 if seek test passed (ie. no buffering required)
+# Notes: Must be done before any other i/o
+sub SeekTest($)
+{
+    my $self = shift;
+    unless ($self->{TESTED}) {
+        my $fp = $self->{FILE_PT};
+        if (seek($fp, 1, 1) and seek($fp, -1, 1)) {
+            $self->{TESTED} = 1;    # test passed
+        } else {
+            $self->{TESTED} = -1;   # test failed (requires buffering)
+        }
+    }
+    return $self->{TESTED} == 1 ? 1 : 0;
+}
+
+#------------------------------------------------------------------------------
+# Get current position in file
+# Inputs: 0) reference to RandomAccess object
+# Returns: current position in file
+sub Tell($)
+{
+    my $self = shift;
+    my $rtnVal;
+    if ($self->{TESTED} < 0) {
+        $rtnVal = $self->{POS};
+    } else {
+        $rtnVal = tell($self->{FILE_PT});
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Seek to position in file
+# Inputs: 0) reference to RandomAccess object
+#         1) position, 2) whence (0 or undef=from start, 1=from cur pos, 2=from end)
+# Returns: 1 on success
+# Notes: When buffered, this doesn't quite behave like seek() since it will return
+#        success even if you seek outside the limits of the file.  However if you
+#        do this, you will get an error on your next Read().
+sub Seek($$;$)
+{
+    my ($self, $num, $whence) = @_;
+    $whence = 0 unless defined $whence;
+    my $rtnVal;
+    if ($self->{TESTED} < 0) {
+        my $newPos;
+        if ($whence == 0) {
+            $newPos = $num;                 # from start of file
+        } elsif ($whence == 1) {
+            $newPos = $num + $self->{POS};  # relative to current position
+        } else {
+            $self->Slurp();                 # read whole file into buffer
+            $newPos = $num + $self->{LEN};  # relative to end of file
+        }
+        if ($newPos >= 0) {
+            $self->{POS} = $newPos;
+            $rtnVal = 1;
+        }
+    } else {
+        $rtnVal = seek($self->{FILE_PT}, $num, $whence);
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Read from the file
+# Inputs: 0) reference to RandomAccess object
+#         1) buffer, 2) bytes to read
+# Returns: Number of bytes read
+sub Read($$$)
+{
+    my $self = shift;
+    my $len = $_[1];
+    my $rtnVal;
+
+    # avoid dying with "Negative length" error
+    return 0 if $len & 0x80000000;
+
+    if ($self->{TESTED} < 0) {
+        my $buff;
+        my $newPos = $self->{POS} + $len;
+        # number of bytes to read from file
+        my $num = $newPos - $self->{LEN};
+        if ($num > 0 and $self->{FILE_PT}) {
+            # read data from file in multiples of $CHUNK_SIZE
+            $num = (($num - 1) | ($CHUNK_SIZE - 1)) + 1;
+            $num = read($self->{FILE_PT}, $buff, $num);
+            if ($num) {
+                ${$self->{BUFF_PT}} .= $buff;
+                $self->{LEN} += $num;
+            }
+        }
+        # number of bytes left in data buffer
+        $num = $self->{LEN} - $self->{POS};
+        if ($len <= $num) {
+            $rtnVal = $len;
+        } elsif ($num <= 0) {
+            $_[0] = '';
+            return 0;
+        } else {
+            $rtnVal = $num;
+        }
+        # return data from our buffer
+        $_[0] = substr(${$self->{BUFF_PT}}, $self->{POS}, $rtnVal);
+        $self->{POS} += $rtnVal;
+    } else {
+        $_[0] = '' unless defined $_[0];
+        $rtnVal = read($self->{FILE_PT}, $_[0], $len) || 0;
+    }
+    if ($self->{DEBUG}) {
+        my $pos = $self->Tell() - $rtnVal;
+        unless ($self->{DEBUG}->{$pos} and $self->{DEBUG}->{$pos} > $rtnVal) {
+            $self->{DEBUG}->{$pos} = $rtnVal;
+        }
+    } 
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Read a line from file (end of line is $/)
+# Inputs: 0) reference to RandomAccess object, 1) buffer
+# Returns: Number of bytes read
+sub ReadLine($$)
+{
+    my $self = shift;
+    my $rtnVal;
+    my $fp = $self->{FILE_PT};
+    
+    if ($self->{TESTED} < 0) {
+        my ($num, $buff);
+        my $pos = $self->{POS};
+        if ($fp) {
+            # make sure we have some data after the current position
+            while ($self->{LEN} <= $pos) {
+                $num = read($fp, $buff, $CHUNK_SIZE);
+                return 0 unless $num;
+                ${$self->{BUFF_PT}} .= $buff;
+                $self->{LEN} += $num;
+            }
+            # scan and read until we find the EOL (or hit EOF)
+            for (;;) {
+                $pos = index(${$self->{BUFF_PT}}, $/, $pos) + length($/);
+                last if $pos > 0;
+                $pos = $self->{LEN};    # have scanned to end of buffer
+                $num = read($fp, $buff, $CHUNK_SIZE) or last;
+                ${$self->{BUFF_PT}} .= $buff;
+                $self->{LEN} += $num;
+            }
+        } else {
+            # string i/o
+            $pos = index(${$self->{BUFF_PT}}, $/, $pos) + length($/);
+            $pos <= 0 and $pos = $self->{LEN};
+        }
+        # read the line from our buffer
+        $rtnVal = $pos - $self->{POS};
+        $_[0] = substr(${$self->{BUFF_PT}}, $self->{POS}, $rtnVal);
+        $self->{POS} = $pos;
+    } else {
+        $_[0] = <$fp>;
+        if (defined $_[0]) {
+            $rtnVal = length($_[0]);
+        } else {
+            $rtnVal = 0;
+        }
+    }
+    if ($self->{DEBUG}) {
+        my $pos = $self->Tell() - $rtnVal;
+        unless ($self->{DEBUG}->{$pos} and $self->{DEBUG}->{$pos} > $rtnVal) {
+            $self->{DEBUG}->{$pos} = $rtnVal;
+        }
+    } 
+    return $rtnVal;  
+}
+
+#------------------------------------------------------------------------------
+# Read whole file into buffer (without changing read pointer)
+# Inputs: 0) reference to RandomAccess object
+sub Slurp($)
+{
+    my $self = shift;
+    my $fp = $self->{FILE_PT} || return;
+    # read whole file into buffer (in large chunks)
+    my ($buff, $num);
+    while (($num = read($fp, $buff, $CHUNK_SIZE * $SLURP_CHUNKS)) != 0) {
+        ${$self->{BUFF_PT}} .= $buff;
+        $self->{LEN} += $num;
+    }
+}
+
+
+#------------------------------------------------------------------------------
+# set binary mode
+# Inputs: 0) reference to RandomAccess object
+sub BinMode($)
+{
+    my $self = shift;
+    binmode($self->{FILE_PT}) if $self->{FILE_PT};
+}
+
+#------------------------------------------------------------------------------
+# close the file and free the buffer
+# Inputs: 0) reference to RandomAccess object
+sub Close($)
+{
+    my $self = shift;
+    
+    if ($self->{DEBUG}) {
+        local $_;
+        if ($self->Seek(0,2)) {
+            $self->{DEBUG}->{$self->Tell()} = 0;    # set EOF marker
+            my $last;
+            my $tot = 0;
+            my $bad = 0;
+            foreach (sort { $a <=> $b } keys %{$self->{DEBUG}}) {
+                my $pos = $_;
+                my $len = $self->{DEBUG}->{$_};
+                if (defined $last and $last < $pos) {
+                    my $bytes = $pos - $last;
+                    $tot += $bytes;
+                    $self->Seek($last);
+                    my $buff;
+                    $self->Read($buff, $bytes);
+                    my $warn = '';
+                    if ($buff =~ /[^\0]/) {
+                        $bad += ($pos - $last);
+                        $warn = ' - NON-ZERO!';
+                    }
+                    printf "0x%.8x - 0x%.8x (%d bytes)$warn\n", $last, $pos, $bytes;
+                }
+                my $cur = $pos + $len;
+                $last = $cur unless defined $last and $last > $cur;
+            }
+            print "$tot bytes missed";
+            $bad and print ", $bad non-zero!";
+            print "\n";
+        } else {
+            warn "File::RandomAccess DEBUG not working (file already closed?)\n";
+        }
+        delete $self->{DEBUG};
+    }
+    # close the file
+    if ($self->{FILE_PT}) {
+        close($self->{FILE_PT});
+        delete $self->{FILE_PT};
+    }
+    # reset the buffer
+    my $emptyBuff = '';
+    $self->{BUFF_PT} = \$emptyBuff;
+    $self->{LEN} = 0;
+    $self->{POS} = 0;
+}
+
+#------------------------------------------------------------------------------
+1;  # end
Index: /gsdl/stable/perllib/cpan/File/RandomAccess.pod
===================================================================
--- /gsdl/stable/perllib/cpan/File/RandomAccess.pod	(revision 20131)
+++ /gsdl/stable/perllib/cpan/File/RandomAccess.pod	(revision 20131)
@@ -0,0 +1,231 @@
+#------------------------------------------------------------------------------
+# File:         RandomAccess.pod -- Documentation for File::RandomAccess
+#
+# Description:  Buffer to support random access reading of sequential file
+#
+# Legal:        Copyright (c) 2004-2006 Phil Harvey (phil at owl.phy.queensu.ca)
+#               This library is free software; you can redistribute it and/or
+#               modify it under the same terms as Perl itself.
+#------------------------------------------------------------------------------
+
+=head1 NAME
+
+File::RandomAccess - Random access reads of sequential file or scalar
+
+=head1 SYNOPSIS
+
+    use File::RandomAccess;
+
+    $raf = new File::RandomAccess(\*FILE, $disableSeekTest);
+
+    $raf = new File::RandomAccess(\$data);
+
+    $err = $raf->Seek($pos);
+    $num = $raf->Read($buff, $bytes);
+
+=head1 DESCRIPTION
+
+Allows random access to sequential file by buffering the file if necessary.
+Also allows access to data in memory to be accessed as if it were a file.
+
+=head1 METHODS
+
+=over 4
+
+=item B<new>
+
+Creates a new RandomAccess object given a file reference or
+reference to data in memory.
+
+    # Read from open file or pipe
+    $raf = new File::RandomAccess(\*FILE);
+
+    # Read from data in memory
+    $raf = new File::RandomAccess(\$data);
+
+=over 4
+
+=item Inputs:
+
+0) Reference to RandomAccess object.
+
+1) File reference or scalar reference.
+
+2) flag set if file is already random access (disables automatic SeekTest).
+
+=item Returns:
+
+Reference to RandomAccess object.
+
+=back
+
+=item B<SeekTest>
+
+Performs test seek() on file to determine if buffering is necessary.  If
+the seek() fails, then the file is buffered to allow random access.
+B<SeekTest>() is automatically called from B<new> unless specified.
+
+    $result = $raf->SeekTest();
+
+=over 4
+
+=item Inputs:
+
+0) Reference to RandomAccess object.
+
+=item Returns:
+
+1 if seek test passed (ie. no buffering required).
+
+=item Notes:
+
+Must be called before any other i/o.
+
+=back
+
+=item B<Tell>
+
+Get current position in file
+
+    $pos = $raf->Tell();
+
+=over 4
+
+=item Inputs:
+
+0) Reference to RandomAccess object.
+
+=item Returns:
+
+Current position in file
+
+=back
+
+=item B<Seek>
+
+Seek to specified position in file.  When buffered, this doesn't quite
+behave like seek() since it returns success even if you seek outside the
+limits of the file.
+
+    $success = $raf->Seek($pos, 0);
+
+=over 4
+
+=item Inputs:
+
+0) Reference to RandomAccess object.
+
+1) Position.
+
+2) Whence (0=from start, 1=from cur pos, 2=from end).
+
+=item Returns:
+
+1 on success, 0 otherwise
+
+=back
+
+=item B<Read>
+
+Read data from the file.
+
+    $num = $raf->Read($buff, 1024);
+
+=over 4
+
+=item Inputs:
+
+0) Reference to RandomAccess object.
+
+1) Buffer.
+
+2) Number of bytes to read.
+
+=item Returns:
+
+Number of bytes actually read.
+
+=back
+
+=item B<ReadLine>
+
+Read a line from file (end of line is $/).
+
+=over 4
+
+=item Inputs:
+
+0) Reference to RandomAccess object.
+
+1) Buffer.
+
+=item Returns:
+
+Number of bytes read.
+
+=back
+
+=item B<Slurp>
+
+Read whole file into buffer, without changing read pointer.
+
+=over 4
+
+=item Inputs:
+
+0) Reference to RandomAccess object.
+
+=item Returns:
+
+Nothing.
+
+=back
+
+=item B<BinMode>
+
+Set binary mode for file.
+
+=over 4
+
+=item Inputs:
+
+0) Reference to RandomAccess object.
+
+=item Returns:
+
+Nothing.
+
+=back
+
+=item B<Close>
+
+Close the file and free the buffer.
+
+=over 4
+
+=item Inputs:
+
+0) Reference to RandomAccess object.
+
+=item Returns:
+
+Nothing.
+
+=back
+
+=back
+
+=head1 AUTHOR
+
+Copyright 2004-2006 Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
+# end
Index: /gsdl/stable/perllib/cpan/HTML/Entities.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/Entities.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/Entities.pm	(revision 20131)
@@ -0,0 +1,491 @@
+package HTML::Entities;
+
+# $Id$
+
+=head1 NAME
+
+HTML::Entities - Encode or decode strings with HTML entities
+
+=head1 SYNOPSIS
+
+ use HTML::Entities;
+
+ $a = "V&aring;re norske tegn b&oslash;r &#230res";
+ decode_entities($a);
+ encode_entities($a, "\200-\377");
+
+For example, this:
+
+ $input = "vis-à-vis Beyoncé's naïve\npapier-mâché résumé";
+ print encode_entities($input), "\n"
+
+Prints this out:
+
+ vis-&agrave;-vis Beyonc&eacute;'s na&iuml;ve
+ papier-m&acirc;ch&eacute; r&eacute;sum&eacute;
+
+=head1 DESCRIPTION
+
+This module deals with encoding and decoding of strings with HTML
+character entities.  The module provides the following functions:
+
+=over 4
+
+=item decode_entities( $string, ... )
+
+This routine replaces HTML entities found in the $string with the
+corresponding Unicode character.  Under perl 5.6 and earlier only
+characters in the Latin-1 range are replaced. Unrecognized
+entities are left alone.
+
+If multiple strings are provided as argument they are each decoded
+separately and the same number of strings are returned.
+
+If called in void context the arguments are decoded in-place.
+
+This routine is exported by default.
+
+=item _decode_entities( $string, \%entity2char )
+
+=item _decode_entities( $string, \%entity2char, $expand_prefix )
+
+This will in-place replace HTML entities in $string.  The %entity2char
+hash must be provided.  Named entities not found in the %entity2char
+hash are left alone.  Numeric entities are expanded unless their value
+overflow.
+
+The keys in %entity2char are the entity names to be expanded and their
+values are what they should expand into.  The values do not have to be
+single character strings.  If a key has ";" as suffix,
+then occurrences in $string are only expanded if properly terminated
+with ";".  Entities without ";" will be expanded regardless of how
+they are terminated for compatiblity with how common browsers treat
+entities in the Latin-1 range.
+
+If $expand_prefix is TRUE then entities without trailing ";" in
+%entity2char will even be expanded as a prefix of a longer
+unrecognized name.  The longest matching name in %entity2char will be
+used. This is mainly present for compatibility with an MSIE
+misfeature.
+
+   $string = "foo&nbspbar";
+   _decode_entities($string, { nb => "@", nbsp => "\xA0" }, 1);
+   print $string;  # will print "foo bar"
+
+This routine is exported by default.
+
+=item encode_entities( $string )
+
+=item encode_entities( $string, $unsafe_chars )
+
+This routine replaces unsafe characters in $string with their entity
+representation. A second argument can be given to specify which
+characters to consider unsafe (i.e., which to escape). The default set
+of characters to encode are control chars, high-bit chars, and the
+C<< < >>, C<< & >>, C<< > >>, C<< ' >> and C<< " >>
+characters.  But this, for example, would encode I<just> the
+C<< < >>, C<< & >>, C<< > >>, and C<< " >> characters:
+
+  $encoded = encode_entities($input, '<>&"');
+
+This routine is exported by default.
+
+=item encode_entities_numeric( $string )
+
+=item encode_entities_numeric( $string, $unsafe_chars )
+
+This routine works just like encode_entities, except that the replacement
+entities are always C<&#xI<hexnum>;> and never C<&I<entname>;>.  For
+example, C<encode_entities("r\xF4le")> returns "r&ocirc;le", but
+C<encode_entities_numeric("r\xF4le")> returns "r&#xF4;le".
+
+This routine is I<not> exported by default.  But you can always
+export it with C<use HTML::Entities qw(encode_entities_numeric);>
+or even C<use HTML::Entities qw(:DEFAULT encode_entities_numeric);>
+
+=back
+
+All these routines modify the string passed as the first argument, if
+called in a void context.  In scalar and array contexts, the encoded or
+decoded string is returned (without changing the input string).
+
+If you prefer not to import these routines into your namespace, you can
+call them as:
+
+  use HTML::Entities ();
+  $decoded = HTML::Entities::decode($a);
+  $encoded = HTML::Entities::encode($a);
+  $encoded = HTML::Entities::encode_numeric($a);
+
+The module can also export the %char2entity and the %entity2char
+hashes, which contain the mapping from all characters to the
+corresponding entities (and vice versa, respectively).
+
+=head1 COPYRIGHT
+
+Copyright 1995-2006 Gisle Aas. All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
+
+use strict;
+use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
+use vars qw(%entity2char %char2entity);
+
+require 5.004;
+require Exporter;
+@ISA = qw(Exporter);
+
+@EXPORT = qw(encode_entities decode_entities _decode_entities);
+@EXPORT_OK = qw(%entity2char %char2entity encode_entities_numeric);
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+sub Version { $VERSION; }
+
+require HTML::Parser;  # for fast XS implemented decode_entities
+
+
+%entity2char = (
+ # Some normal chars that have special meaning in SGML context
+ amp    => '&',  # ampersand 
+'gt'    => '>',  # greater than
+'lt'    => '<',  # less than
+ quot   => '"',  # double quote
+ apos   => "'",  # single quote
+
+ # PUBLIC ISO 8879-1986//ENTITIES Added Latin 1//EN//HTML
+ AElig	=> chr(198),  # capital AE diphthong (ligature)
+ Aacute	=> chr(193),  # capital A, acute accent
+ Acirc	=> chr(194),  # capital A, circumflex accent
+ Agrave	=> chr(192),  # capital A, grave accent
+ Aring	=> chr(197),  # capital A, ring
+ Atilde	=> chr(195),  # capital A, tilde
+ Auml	=> chr(196),  # capital A, dieresis or umlaut mark
+ Ccedil	=> chr(199),  # capital C, cedilla
+ ETH	=> chr(208),  # capital Eth, Icelandic
+ Eacute	=> chr(201),  # capital E, acute accent
+ Ecirc	=> chr(202),  # capital E, circumflex accent
+ Egrave	=> chr(200),  # capital E, grave accent
+ Euml	=> chr(203),  # capital E, dieresis or umlaut mark
+ Iacute	=> chr(205),  # capital I, acute accent
+ Icirc	=> chr(206),  # capital I, circumflex accent
+ Igrave	=> chr(204),  # capital I, grave accent
+ Iuml	=> chr(207),  # capital I, dieresis or umlaut mark
+ Ntilde	=> chr(209),  # capital N, tilde
+ Oacute	=> chr(211),  # capital O, acute accent
+ Ocirc	=> chr(212),  # capital O, circumflex accent
+ Ograve	=> chr(210),  # capital O, grave accent
+ Oslash	=> chr(216),  # capital O, slash
+ Otilde	=> chr(213),  # capital O, tilde
+ Ouml	=> chr(214),  # capital O, dieresis or umlaut mark
+ THORN	=> chr(222),  # capital THORN, Icelandic
+ Uacute	=> chr(218),  # capital U, acute accent
+ Ucirc	=> chr(219),  # capital U, circumflex accent
+ Ugrave	=> chr(217),  # capital U, grave accent
+ Uuml	=> chr(220),  # capital U, dieresis or umlaut mark
+ Yacute	=> chr(221),  # capital Y, acute accent
+ aacute	=> chr(225),  # small a, acute accent
+ acirc	=> chr(226),  # small a, circumflex accent
+ aelig	=> chr(230),  # small ae diphthong (ligature)
+ agrave	=> chr(224),  # small a, grave accent
+ aring	=> chr(229),  # small a, ring
+ atilde	=> chr(227),  # small a, tilde
+ auml	=> chr(228),  # small a, dieresis or umlaut mark
+ ccedil	=> chr(231),  # small c, cedilla
+ eacute	=> chr(233),  # small e, acute accent
+ ecirc	=> chr(234),  # small e, circumflex accent
+ egrave	=> chr(232),  # small e, grave accent
+ eth	=> chr(240),  # small eth, Icelandic
+ euml	=> chr(235),  # small e, dieresis or umlaut mark
+ iacute	=> chr(237),  # small i, acute accent
+ icirc	=> chr(238),  # small i, circumflex accent
+ igrave	=> chr(236),  # small i, grave accent
+ iuml	=> chr(239),  # small i, dieresis or umlaut mark
+ ntilde	=> chr(241),  # small n, tilde
+ oacute	=> chr(243),  # small o, acute accent
+ ocirc	=> chr(244),  # small o, circumflex accent
+ ograve	=> chr(242),  # small o, grave accent
+ oslash	=> chr(248),  # small o, slash
+ otilde	=> chr(245),  # small o, tilde
+ ouml	=> chr(246),  # small o, dieresis or umlaut mark
+ szlig	=> chr(223),  # small sharp s, German (sz ligature)
+ thorn	=> chr(254),  # small thorn, Icelandic
+ uacute	=> chr(250),  # small u, acute accent
+ ucirc	=> chr(251),  # small u, circumflex accent
+ ugrave	=> chr(249),  # small u, grave accent
+ uuml	=> chr(252),  # small u, dieresis or umlaut mark
+ yacute	=> chr(253),  # small y, acute accent
+ yuml	=> chr(255),  # small y, dieresis or umlaut mark
+
+ # Some extra Latin 1 chars that are listed in the HTML3.2 draft (21-May-96)
+ copy   => chr(169),  # copyright sign
+ reg    => chr(174),  # registered sign
+ nbsp   => chr(160),  # non breaking space
+
+ # Additional ISO-8859/1 entities listed in rfc1866 (section 14)
+ iexcl  => chr(161),
+ cent   => chr(162),
+ pound  => chr(163),
+ curren => chr(164),
+ yen    => chr(165),
+ brvbar => chr(166),
+ sect   => chr(167),
+ uml    => chr(168),
+ ordf   => chr(170),
+ laquo  => chr(171),
+'not'   => chr(172),    # not is a keyword in perl
+ shy    => chr(173),
+ macr   => chr(175),
+ deg    => chr(176),
+ plusmn => chr(177),
+ sup1   => chr(185),
+ sup2   => chr(178),
+ sup3   => chr(179),
+ acute  => chr(180),
+ micro  => chr(181),
+ para   => chr(182),
+ middot => chr(183),
+ cedil  => chr(184),
+ ordm   => chr(186),
+ raquo  => chr(187),
+ frac14 => chr(188),
+ frac12 => chr(189),
+ frac34 => chr(190),
+ iquest => chr(191),
+'times' => chr(215),    # times is a keyword in perl
+ divide => chr(247),
+
+ ( $] > 5.007 ? (
+  'OElig;'    => chr(338),
+  'oelig;'    => chr(339),
+  'Scaron;'   => chr(352),
+  'scaron;'   => chr(353),
+  'Yuml;'     => chr(376),
+  'fnof;'     => chr(402),
+  'circ;'     => chr(710),
+  'tilde;'    => chr(732),
+  'Alpha;'    => chr(913),
+  'Beta;'     => chr(914),
+  'Gamma;'    => chr(915),
+  'Delta;'    => chr(916),
+  'Epsilon;'  => chr(917),
+  'Zeta;'     => chr(918),
+  'Eta;'      => chr(919),
+  'Theta;'    => chr(920),
+  'Iota;'     => chr(921),
+  'Kappa;'    => chr(922),
+  'Lambda;'   => chr(923),
+  'Mu;'       => chr(924),
+  'Nu;'       => chr(925),
+  'Xi;'       => chr(926),
+  'Omicron;'  => chr(927),
+  'Pi;'       => chr(928),
+  'Rho;'      => chr(929),
+  'Sigma;'    => chr(931),
+  'Tau;'      => chr(932),
+  'Upsilon;'  => chr(933),
+  'Phi;'      => chr(934),
+  'Chi;'      => chr(935),
+  'Psi;'      => chr(936),
+  'Omega;'    => chr(937),
+  'alpha;'    => chr(945),
+  'beta;'     => chr(946),
+  'gamma;'    => chr(947),
+  'delta;'    => chr(948),
+  'epsilon;'  => chr(949),
+  'zeta;'     => chr(950),
+  'eta;'      => chr(951),
+  'theta;'    => chr(952),
+  'iota;'     => chr(953),
+  'kappa;'    => chr(954),
+  'lambda;'   => chr(955),
+  'mu;'       => chr(956),
+  'nu;'       => chr(957),
+  'xi;'       => chr(958),
+  'omicron;'  => chr(959),
+  'pi;'       => chr(960),
+  'rho;'      => chr(961),
+  'sigmaf;'   => chr(962),
+  'sigma;'    => chr(963),
+  'tau;'      => chr(964),
+  'upsilon;'  => chr(965),
+  'phi;'      => chr(966),
+  'chi;'      => chr(967),
+  'psi;'      => chr(968),
+  'omega;'    => chr(969),
+  'thetasym;' => chr(977),
+  'upsih;'    => chr(978),
+  'piv;'      => chr(982),
+  'ensp;'     => chr(8194),
+  'emsp;'     => chr(8195),
+  'thinsp;'   => chr(8201),
+  'zwnj;'     => chr(8204),
+  'zwj;'      => chr(8205),
+  'lrm;'      => chr(8206),
+  'rlm;'      => chr(8207),
+  'ndash;'    => chr(8211),
+  'mdash;'    => chr(8212),
+  'lsquo;'    => chr(8216),
+  'rsquo;'    => chr(8217),
+  'sbquo;'    => chr(8218),
+  'ldquo;'    => chr(8220),
+  'rdquo;'    => chr(8221),
+  'bdquo;'    => chr(8222),
+  'dagger;'   => chr(8224),
+  'Dagger;'   => chr(8225),
+  'bull;'     => chr(8226),
+  'hellip;'   => chr(8230),
+  'permil;'   => chr(8240),
+  'prime;'    => chr(8242),
+  'Prime;'    => chr(8243),
+  'lsaquo;'   => chr(8249),
+  'rsaquo;'   => chr(8250),
+  'oline;'    => chr(8254),
+  'frasl;'    => chr(8260),
+  'euro;'     => chr(8364),
+  'image;'    => chr(8465),
+  'weierp;'   => chr(8472),
+  'real;'     => chr(8476),
+  'trade;'    => chr(8482),
+  'alefsym;'  => chr(8501),
+  'larr;'     => chr(8592),
+  'uarr;'     => chr(8593),
+  'rarr;'     => chr(8594),
+  'darr;'     => chr(8595),
+  'harr;'     => chr(8596),
+  'crarr;'    => chr(8629),
+  'lArr;'     => chr(8656),
+  'uArr;'     => chr(8657),
+  'rArr;'     => chr(8658),
+  'dArr;'     => chr(8659),
+  'hArr;'     => chr(8660),
+  'forall;'   => chr(8704),
+  'part;'     => chr(8706),
+  'exist;'    => chr(8707),
+  'empty;'    => chr(8709),
+  'nabla;'    => chr(8711),
+  'isin;'     => chr(8712),
+  'notin;'    => chr(8713),
+  'ni;'       => chr(8715),
+  'prod;'     => chr(8719),
+  'sum;'      => chr(8721),
+  'minus;'    => chr(8722),
+  'lowast;'   => chr(8727),
+  'radic;'    => chr(8730),
+  'prop;'     => chr(8733),
+  'infin;'    => chr(8734),
+  'ang;'      => chr(8736),
+  'and;'      => chr(8743),
+  'or;'       => chr(8744),
+  'cap;'      => chr(8745),
+  'cup;'      => chr(8746),
+  'int;'      => chr(8747),
+  'there4;'   => chr(8756),
+  'sim;'      => chr(8764),
+  'cong;'     => chr(8773),
+  'asymp;'    => chr(8776),
+  'ne;'       => chr(8800),
+  'equiv;'    => chr(8801),
+  'le;'       => chr(8804),
+  'ge;'       => chr(8805),
+  'sub;'      => chr(8834),
+  'sup;'      => chr(8835),
+  'nsub;'     => chr(8836),
+  'sube;'     => chr(8838),
+  'supe;'     => chr(8839),
+  'oplus;'    => chr(8853),
+  'otimes;'   => chr(8855),
+  'perp;'     => chr(8869),
+  'sdot;'     => chr(8901),
+  'lceil;'    => chr(8968),
+  'rceil;'    => chr(8969),
+  'lfloor;'   => chr(8970),
+  'rfloor;'   => chr(8971),
+  'lang;'     => chr(9001),
+  'rang;'     => chr(9002),
+  'loz;'      => chr(9674),
+  'spades;'   => chr(9824),
+  'clubs;'    => chr(9827),
+  'hearts;'   => chr(9829),
+  'diams;'    => chr(9830),
+ ) : ())
+);
+
+
+# Make the opposite mapping
+while (my($entity, $char) = each(%entity2char)) {
+    $entity =~ s/;\z//;
+    $char2entity{$char} = "&$entity;";
+}
+delete $char2entity{"'"};  # only one-way decoding
+
+# Fill in missing entities
+for (0 .. 255) {
+    next if exists $char2entity{chr($_)};
+    $char2entity{chr($_)} = "&#$_;";
+}
+
+my %subst;  # compiled encoding regexps
+
+sub decode_entities_old
+{
+    my $array;
+    if (defined wantarray) {
+	$array = [@_]; # copy
+    } else {
+	$array = \@_;  # modify in-place
+    }
+    my $c;
+    for (@$array) {
+	s/(&\#(\d+);?)/$2 < 256 ? chr($2) : $1/eg;
+	s/(&\#[xX]([0-9a-fA-F]+);?)/$c = hex($2); $c < 256 ? chr($c) : $1/eg;
+	s/(&(\w+);?)/$entity2char{$2} || $1/eg;
+    }
+    wantarray ? @$array : $array->[0];
+}
+
+sub encode_entities
+{
+    my $ref;
+    if (defined wantarray) {
+	my $x = $_[0];
+	$ref = \$x;     # copy
+    } else {
+	$ref = \$_[0];  # modify in-place
+    }
+    if (defined $_[1] and length $_[1]) {
+	unless (exists $subst{$_[1]}) {
+	    # Because we can't compile regex we fake it with a cached sub
+	    my $code = "sub {\$_[0] =~ s/([$_[1]])/\$char2entity{\$1} || num_entity(\$1)/ge; }";
+	    $subst{$_[1]} = eval $code;
+	    die( $@ . " while trying to turn range: \"$_[1]\"\n "
+	      . "into code: $code\n "
+	    ) if $@;
+	}
+	&{$subst{$_[1]}}($$ref);
+    } else {
+	# Encode control chars, high bit chars and '<', '&', '>', ''' and '"'
+	$$ref =~ s/([^\n\r\t !\#\$%\(-;=?-~])/$char2entity{$1} || num_entity($1)/ge;
+    }
+    $$ref;
+}
+
+sub encode_entities_numeric {
+    local %char2entity;
+    return &encode_entities;   # a goto &encode_entities wouldn't work
+}
+
+
+sub num_entity {
+    sprintf "&#x%X;", ord($_[0]);
+}
+
+# Set up aliases
+*encode = \&encode_entities;
+*encode_numeric = \&encode_entities_numeric;
+*encode_numerically = \&encode_entities_numeric;
+*decode = \&decode_entities;
+
+1;
Index: /gsdl/stable/perllib/cpan/HTML/Filter.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/Filter.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/Filter.pm	(revision 20131)
@@ -0,0 +1,112 @@
+package HTML::Filter;
+
+use strict;
+use vars qw(@ISA $VERSION);
+
+require HTML::Parser;
+@ISA=qw(HTML::Parser);
+
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+sub declaration { $_[0]->output("<!$_[1]>")     }
+sub process     { $_[0]->output($_[2])          }
+sub comment     { $_[0]->output("<!--$_[1]-->") }
+sub start       { $_[0]->output($_[4])          }
+sub end         { $_[0]->output($_[2])          }
+sub text        { $_[0]->output($_[1])          }
+
+sub output      { print $_[1] }
+
+1;
+
+__END__
+
+=head1 NAME
+
+HTML::Filter - Filter HTML text through the parser
+
+=head1 NOTE
+
+B<This module is deprecated.> The C<HTML::Parser> now provides the
+functionally of C<HTML::Filter> much more efficiently with the the
+C<default> handler.
+
+=head1 SYNOPSIS
+
+ require HTML::Filter;
+ $p = HTML::Filter->new->parse_file("index.html");
+
+=head1 DESCRIPTION
+
+C<HTML::Filter> is an HTML parser that by default prints the
+original text of each HTML element (a slow version of cat(1) basically).
+The callback methods may be overridden to modify the filtering for some
+HTML elements and you can override output() method which is called to
+print the HTML text.
+
+C<HTML::Filter> is a subclass of C<HTML::Parser>. This means that
+the document should be given to the parser by calling the $p->parse()
+or $p->parse_file() methods.
+
+=head1 EXAMPLES
+
+The first example is a filter that will remove all comments from an
+HTML file.  This is achieved by simply overriding the comment method
+to do nothing.
+
+  package CommentStripper;
+  require HTML::Filter;
+  @ISA=qw(HTML::Filter);
+  sub comment { }  # ignore comments
+
+The second example shows a filter that will remove any E<lt>TABLE>s
+found in the HTML file.  We specialize the start() and end() methods
+to count table tags and then make output not happen when inside a
+table.
+
+  package TableStripper;
+  require HTML::Filter;
+  @ISA=qw(HTML::Filter);
+  sub start
+  {
+     my $self = shift;
+     $self->{table_seen}++ if $_[0] eq "table";
+     $self->SUPER::start(@_);
+  }
+
+  sub end
+  {
+     my $self = shift;
+     $self->SUPER::end(@_);
+     $self->{table_seen}-- if $_[0] eq "table";
+  }
+
+  sub output
+  {
+      my $self = shift;
+      unless ($self->{table_seen}) {
+	  $self->SUPER::output(@_);
+      }
+  }
+
+If you want to collect the parsed text internally you might want to do
+something like this:
+
+  package FilterIntoString;
+  require HTML::Filter;
+  @ISA=qw(HTML::Filter);
+  sub output { push(@{$_[0]->{fhtml}}, $_[1]) }
+  sub filtered_html { join("", @{$_[0]->{fhtml}}) }
+
+=head1 SEE ALSO
+
+L<HTML::Parser>
+
+=head1 COPYRIGHT
+
+Copyright 1997-1999 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/perllib/cpan/HTML/HeadParser.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/HeadParser.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/HeadParser.pm	(revision 20131)
@@ -0,0 +1,259 @@
+package HTML::HeadParser;
+
+=head1 NAME
+
+HTML::HeadParser - Parse <HEAD> section of a HTML document
+
+=head1 SYNOPSIS
+
+ require HTML::HeadParser;
+ $p = HTML::HeadParser->new;
+ $p->parse($text) and  print "not finished";
+
+ $p->header('Title')          # to access <title>....</title>
+ $p->header('Content-Base')   # to access <base href="http://...">
+ $p->header('Foo')            # to access <meta http-equiv="Foo" content="...">
+
+=head1 DESCRIPTION
+
+The C<HTML::HeadParser> is a specialized (and lightweight)
+C<HTML::Parser> that will only parse the E<lt>HEAD>...E<lt>/HEAD>
+section of an HTML document.  The parse() method
+will return a FALSE value as soon as some E<lt>BODY> element or body
+text are found, and should not be called again after this.
+
+Note that the C<HTML::HeadParser> might get confused if raw undecoded
+UTF-8 is passed to the parse() method.  Make sure the strings are
+properly decoded before passing them on.
+
+The C<HTML::HeadParser> keeps a reference to a header object, and the
+parser will update this header object as the various elements of the
+E<lt>HEAD> section of the HTML document are recognized.  The following
+header fields are affected:
+
+=over 4
+
+=item Content-Base:
+
+The I<Content-Base> header is initialized from the E<lt>base
+href="..."> element.
+
+=item Title:
+
+The I<Title> header is initialized from the E<lt>title>...E<lt>/title>
+element.
+
+=item Isindex:
+
+The I<Isindex> header will be added if there is a E<lt>isindex>
+element in the E<lt>head>.  The header value is initialized from the
+I<prompt> attribute if it is present.  If no I<prompt> attribute is
+given it will have '?' as the value.
+
+=item X-Meta-Foo:
+
+All E<lt>meta> elements will initialize headers with the prefix
+"C<X-Meta->" on the name.  If the E<lt>meta> element contains a
+C<http-equiv> attribute, then it will be honored as the header name.
+
+=back
+
+=head1 METHODS
+
+The following methods (in addition to those provided by the
+superclass) are available:
+
+=over 4
+
+=cut
+
+
+require HTML::Parser;
+@ISA = qw(HTML::Parser);
+
+use HTML::Entities ();
+
+use strict;
+use vars qw($VERSION $DEBUG);
+#$DEBUG = 1;
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+=item $hp = HTML::HeadParser->new
+
+=item $hp = HTML::HeadParser->new( $header )
+
+The object constructor.  The optional $header argument should be a
+reference to an object that implement the header() and push_header()
+methods as defined by the C<HTTP::Headers> class.  Normally it will be
+of some class that isa or delegates to the C<HTTP::Headers> class.
+
+If no $header is given C<HTML::HeadParser> will create an
+C<HTTP::Header> object by itself (initially empty).
+
+=cut
+
+sub new
+{
+    my($class, $header) = @_;
+    unless ($header) {
+	require HTTP::Headers;
+	$header = HTTP::Headers->new;
+    }
+
+    my $self = $class->SUPER::new(api_version => 2,
+				  ignore_elements => [qw(script style)],
+				 );
+    $self->{'header'} = $header;
+    $self->{'tag'} = '';   # name of active element that takes textual content
+    $self->{'text'} = '';  # the accumulated text associated with the element
+    $self;
+}
+
+=item $hp->header;
+
+Returns a reference to the header object.
+
+=item $hp->header( $key )
+
+Returns a header value.  It is just a shorter way to write
+C<$hp-E<gt>header-E<gt>header($key)>.
+
+=cut
+
+sub header
+{
+    my $self = shift;
+    return $self->{'header'} unless @_;
+    $self->{'header'}->header(@_);
+}
+
+sub as_string    # legacy
+{
+    my $self = shift;
+    $self->{'header'}->as_string;
+}
+
+sub flush_text   # internal
+{
+    my $self = shift;
+    my $tag  = $self->{'tag'};
+    my $text = $self->{'text'};
+    $text =~ s/^\s+//;
+    $text =~ s/\s+$//;
+    $text =~ s/\s+/ /g;
+    print "FLUSH $tag => '$text'\n"  if $DEBUG;
+    if ($tag eq 'title') {
+	HTML::Entities::decode($text);
+	$self->{'header'}->push_header(Title => $text);
+    }
+    $self->{'tag'} = $self->{'text'} = '';
+}
+
+# This is an quote from the HTML3.2 DTD which shows which elements
+# that might be present in a <HEAD>...</HEAD>.  Also note that the
+# <HEAD> tags themselves might be missing:
+#
+# <!ENTITY % head.content "TITLE & ISINDEX? & BASE? & STYLE? &
+#                            SCRIPT* & META* & LINK*">
+#
+# <!ELEMENT HEAD O O  (%head.content)>
+
+
+sub start
+{
+    my($self, $tag, $attr) = @_;  # $attr is reference to a HASH
+    print "START[$tag]\n" if $DEBUG;
+    $self->flush_text if $self->{'tag'};
+    if ($tag eq 'meta') {
+	my $key = $attr->{'http-equiv'};
+	if (!defined($key) || !length($key)) {
+	    return unless $attr->{'name'};
+	    $key = "X-Meta-\u$attr->{'name'}";
+	}
+	$self->{'header'}->push_header($key => $attr->{content});
+    } elsif ($tag eq 'base') {
+	return unless exists $attr->{href};
+	$self->{'header'}->push_header('Content-Base' => $attr->{href});
+    } elsif ($tag eq 'isindex') {
+	# This is a non-standard header.  Perhaps we should just ignore
+	# this element
+	$self->{'header'}->push_header(Isindex => $attr->{prompt} || '?');
+    } elsif ($tag =~ /^(?:title|script|style)$/) {
+	# Just remember tag.  Initialize header when we see the end tag.
+	$self->{'tag'} = $tag;
+    } elsif ($tag eq 'link') {
+	return unless exists $attr->{href};
+	# <link href="http:..." rel="xxx" rev="xxx" title="xxx">
+	my $h_val = "<" . delete($attr->{href}) . ">";
+	for (sort keys %{$attr}) {
+	    $h_val .= qq(; $_="$attr->{$_}");
+	}
+	$self->{'header'}->push_header(Link => $h_val);
+    } elsif ($tag eq 'head' || $tag eq 'html') {
+	# ignore
+    } else {
+	 # stop parsing
+	$self->eof;
+    }
+}
+
+sub end
+{
+    my($self, $tag) = @_;
+    print "END[$tag]\n" if $DEBUG;
+    $self->flush_text if $self->{'tag'};
+    $self->eof if $tag eq 'head';
+}
+
+sub text
+{
+    my($self, $text) = @_;
+    $text =~ s/\x{FEFF}//;  # drop Unicode BOM if found
+    print "TEXT[$text]\n" if $DEBUG;
+    my $tag = $self->{tag};
+    if (!$tag && $text =~ /\S/) {
+	# Normal text means start of body
+        $self->eof;
+	return;
+    }
+    return if $tag ne 'title';
+    $self->{'text'} .= $text;
+}
+
+1;
+
+__END__
+
+=back
+
+=head1 EXAMPLE
+
+ $h = HTTP::Headers->new;
+ $p = HTML::HeadParser->new($h);
+ $p->parse(<<EOT);
+ <title>Stupid example</title>
+ <base href="http://www.linpro.no/lwp/">
+ Normal text starts here.
+ EOT
+ undef $p;
+ print $h->title;   # should print "Stupid example"
+
+=head1 SEE ALSO
+
+L<HTML::Parser>, L<HTTP::Headers>
+
+The C<HTTP::Headers> class is distributed as part of the
+I<libwww-perl> package.  If you don't have that distribution installed
+you need to provide the $header argument to the C<HTML::HeadParser>
+constructor with your own object that implements the documented
+protocol.
+
+=head1 COPYRIGHT
+
+Copyright 1996-2001 Gisle Aas. All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/HTML/LinkExtor.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/LinkExtor.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/LinkExtor.pm	(revision 20131)
@@ -0,0 +1,187 @@
+package HTML::LinkExtor;
+
+# $Id$
+
+require HTML::Parser;
+@ISA = qw(HTML::Parser);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+=head1 NAME
+
+HTML::LinkExtor - Extract links from an HTML document
+
+=head1 SYNOPSIS
+
+ require HTML::LinkExtor;
+ $p = HTML::LinkExtor->new(\&cb, "http://www.perl.org/");
+ sub cb {
+     my($tag, %links) = @_;
+     print "$tag @{[%links]}\n";
+ }
+ $p->parse_file("index.html");
+
+=head1 DESCRIPTION
+
+I<HTML::LinkExtor> is an HTML parser that extracts links from an
+HTML document.  The I<HTML::LinkExtor> is a subclass of
+I<HTML::Parser>. This means that the document should be given to the
+parser by calling the $p->parse() or $p->parse_file() methods.
+
+=cut
+
+use strict;
+use HTML::Tagset ();
+
+# legacy (some applications grabs this hash directly)
+use vars qw(%LINK_ELEMENT);
+*LINK_ELEMENT = \%HTML::Tagset::linkElements;
+
+=over 4
+
+=item $p = HTML::LinkExtor->new
+
+=item $p = HTML::LinkExtor->new( $callback )
+
+=item $p = HTML::LinkExtor->new( $callback, $base )
+
+The constructor takes two optional arguments. The first is a reference
+to a callback routine. It will be called as links are found. If a
+callback is not provided, then links are just accumulated internally
+and can be retrieved by calling the $p->links() method.
+
+The $base argument is an optional base URL used to absolutize all URLs found.
+You need to have the I<URI> module installed if you provide $base.
+
+The callback is called with the lowercase tag name as first argument,
+and then all link attributes as separate key/value pairs.  All
+non-link attributes are removed.
+
+=cut
+
+sub new
+{
+    my($class, $cb, $base) = @_;
+    my $self = $class->SUPER::new(
+                    start_h => ["_start_tag", "self,tagname,attr"],
+		    report_tags => [keys %HTML::Tagset::linkElements],
+	       );
+    $self->{extractlink_cb} = $cb;
+    if ($base) {
+	require URI;
+	$self->{extractlink_base} = URI->new($base);
+    }
+    $self;
+}
+
+sub _start_tag
+{
+    my($self, $tag, $attr) = @_;
+
+    my $base = $self->{extractlink_base};
+    my $links = $HTML::Tagset::linkElements{$tag};
+    $links = [$links] unless ref $links;
+
+    my @links;
+    my $a;
+    for $a (@$links) {
+	next unless exists $attr->{$a};
+	push(@links, $a, $base ? URI->new($attr->{$a}, $base)->abs($base)
+                               : $attr->{$a});
+    }
+    return unless @links;
+    $self->_found_link($tag, @links);
+}
+
+sub _found_link
+{
+    my $self = shift;
+    my $cb = $self->{extractlink_cb};
+    if ($cb) {
+	&$cb(@_);
+    } else {
+	push(@{$self->{'links'}}, [@_]);
+    }
+}
+
+=item $p->links
+
+Returns a list of all links found in the document.  The returned
+values will be anonymous arrays with the follwing elements:
+
+  [$tag, $attr => $url1, $attr2 => $url2,...]
+
+The $p->links method will also truncate the internal link list.  This
+means that if the method is called twice without any parsing
+between them the second call will return an empty list.
+
+Also note that $p->links will always be empty if a callback routine
+was provided when the I<HTML::LinkExtor> was created.
+
+=cut
+
+sub links
+{
+    my $self = shift;
+    exists($self->{'links'}) ? @{delete $self->{'links'}} : ();
+}
+
+# We override the parse_file() method so that we can clear the links
+# before we start a new file.
+sub parse_file
+{
+    my $self = shift;
+    delete $self->{'links'};
+    $self->SUPER::parse_file(@_);
+}
+
+=back
+
+=head1 EXAMPLE
+
+This is an example showing how you can extract links from a document
+received using LWP:
+
+  use LWP::UserAgent;
+  use HTML::LinkExtor;
+  use URI::URL;
+
+  $url = "http://www.perl.org/";  # for instance
+  $ua = LWP::UserAgent->new;
+
+  # Set up a callback that collect image links
+  my @imgs = ();
+  sub callback {
+     my($tag, %attr) = @_;
+     return if $tag ne 'img';  # we only look closer at <img ...>
+     push(@imgs, values %attr);
+  }
+
+  # Make the parser.  Unfortunately, we don't know the base yet
+  # (it might be diffent from $url)
+  $p = HTML::LinkExtor->new(\&callback);
+
+  # Request document and parse it as it arrives
+  $res = $ua->request(HTTP::Request->new(GET => $url),
+                      sub {$p->parse($_[0])});
+
+  # Expand all image URLs to absolute ones
+  my $base = $res->base;
+  @imgs = map { $_ = url($_, $base)->abs; } @imgs;
+
+  # Print them out
+  print join("\n", @imgs), "\n";
+
+=head1 SEE ALSO
+
+L<HTML::Parser>, L<HTML::Tagset>, L<LWP>, L<URI::URL>
+
+=head1 COPYRIGHT
+
+Copyright 1996-2001 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
+
+1;
Index: /gsdl/stable/perllib/cpan/HTML/Parser.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/Parser.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/Parser.pm	(revision 20131)
@@ -0,0 +1,1233 @@
+package HTML::Parser;
+
+# Copyright 1996-2007, Gisle Aas.
+# Copyright 1999-2000, Michael A. Chase.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the same terms as Perl itself.
+
+use strict;
+use vars qw($VERSION @ISA);
+
+$VERSION = '3.56';  # $Date$
+
+require HTML::Entities;
+
+require XSLoader;
+XSLoader::load('HTML::Parser', $VERSION);
+
+sub new
+{
+    my $class = shift;
+    my $self = bless {}, $class;
+    return $self->init(@_);
+}
+
+
+sub init
+{
+    my $self = shift;
+    $self->_alloc_pstate;
+
+    my %arg = @_;
+    my $api_version = delete $arg{api_version} || (@_ ? 3 : 2);
+    if ($api_version >= 4) {
+	require Carp;
+	Carp::croak("API version $api_version not supported " .
+		    "by HTML::Parser $VERSION");
+    }
+
+    if ($api_version < 3) {
+	# Set up method callbacks compatible with HTML-Parser-2.xx
+	$self->handler(text    => "text",    "self,text,is_cdata");
+	$self->handler(end     => "end",     "self,tagname,text");
+	$self->handler(process => "process", "self,token0,text");
+	$self->handler(start   => "start",
+		                  "self,tagname,attr,attrseq,text");
+
+	$self->handler(comment =>
+		       sub {
+			   my($self, $tokens) = @_;
+			   for (@$tokens) {
+			       $self->comment($_);
+			   }
+		       }, "self,tokens");
+
+	$self->handler(declaration =>
+		       sub {
+			   my $self = shift;
+			   $self->declaration(substr($_[0], 2, -1));
+		       }, "self,text");
+    }
+
+    if (my $h = delete $arg{handlers}) {
+	$h = {@$h} if ref($h) eq "ARRAY";
+	while (my($event, $cb) = each %$h) {
+	    $self->handler($event => @$cb);
+	}
+    }
+
+    # In the end we try to assume plain attribute or handler
+    while (my($option, $val) = each %arg) {
+	if ($option =~ /^(\w+)_h$/) {
+	    $self->handler($1 => @$val);
+	}
+        elsif ($option =~ /^(text|start|end|process|declaration|comment)$/) {
+	    require Carp;
+	    Carp::croak("Bad constructor option '$option'");
+        }
+	else {
+	    $self->$option($val);
+	}
+    }
+
+    return $self;
+}
+
+
+sub parse_file
+{
+    my($self, $file) = @_;
+    my $opened;
+    if (!ref($file) && ref(\$file) ne "GLOB") {
+        # Assume $file is a filename
+        local(*F);
+        open(F, $file) || return undef;
+	binmode(F);  # should we? good for byte counts
+        $opened++;
+        $file = *F;
+    }
+    my $chunk = '';
+    while (read($file, $chunk, 512)) {
+	$self->parse($chunk) || last;
+    }
+    close($file) if $opened;
+    $self->eof;
+}
+
+
+sub netscape_buggy_comment  # legacy
+{
+    my $self = shift;
+    require Carp;
+    Carp::carp("netscape_buggy_comment() is deprecated.  " .
+	       "Please use the strict_comment() method instead");
+    my $old = !$self->strict_comment;
+    $self->strict_comment(!shift) if @_;
+    return $old;
+}
+
+# set up method stubs
+sub text { }
+*start       = \&text;
+*end         = \&text;
+*comment     = \&text;
+*declaration = \&text;
+*process     = \&text;
+
+1;
+
+__END__
+
+
+=head1 NAME
+
+HTML::Parser - HTML parser class
+
+=head1 SYNOPSIS
+
+ use HTML::Parser ();
+
+ # Create parser object
+ $p = HTML::Parser->new( api_version => 3,
+                         start_h => [\&start, "tagname, attr"],
+                         end_h   => [\&end,   "tagname"],
+                         marked_sections => 1,
+                       );
+
+ # Parse document text chunk by chunk
+ $p->parse($chunk1);
+ $p->parse($chunk2);
+ #...
+ $p->eof;                 # signal end of document
+
+ # Parse directly from file
+ $p->parse_file("foo.html");
+ # or
+ open(my $fh, "<:utf8", "foo.html") || die;
+ $p->parse_file($fh);
+
+=head1 DESCRIPTION
+
+Objects of the C<HTML::Parser> class will recognize markup and
+separate it from plain text (alias data content) in HTML
+documents.  As different kinds of markup and text are recognized, the
+corresponding event handlers are invoked.
+
+C<HTML::Parser> is not a generic SGML parser.  We have tried to
+make it able to deal with the HTML that is actually "out there", and
+it normally parses as closely as possible to the way the popular web
+browsers do it instead of strictly following one of the many HTML
+specifications from W3C.  Where there is disagreement, there is often
+an option that you can enable to get the official behaviour.
+
+The document to be parsed may be supplied in arbitrary chunks.  This
+makes on-the-fly parsing as documents are received from the network
+possible.
+
+If event driven parsing does not feel right for your application, you
+might want to use C<HTML::PullParser>.  This is an C<HTML::Parser>
+subclass that allows a more conventional program structure.
+
+
+=head1 METHODS
+
+The following method is used to construct a new C<HTML::Parser> object:
+
+=over
+
+=item $p = HTML::Parser->new( %options_and_handlers )
+
+This class method creates a new C<HTML::Parser> object and
+returns it.  Key/value argument pairs may be provided to assign event
+handlers or initialize parser options.  The handlers and parser
+options can also be set or modified later by the method calls described below.
+
+If a top level key is in the form "<event>_h" (e.g., "text_h") then it
+assigns a handler to that event, otherwise it initializes a parser
+option. The event handler specification value must be an array
+reference.  Multiple handlers may also be assigned with the 'handlers
+=> [%handlers]' option.  See examples below.
+
+If new() is called without any arguments, it will create a parser that
+uses callback methods compatible with version 2 of C<HTML::Parser>.
+See the section on "version 2 compatibility" below for details.
+
+The special constructor option 'api_version => 2' can be used to
+initialize version 2 callbacks while still setting other options and
+handlers.  The 'api_version => 3' option can be used if you don't want
+to set any options and don't want to fall back to v2 compatible
+mode.
+
+Examples:
+
+ $p = HTML::Parser->new(api_version => 3,
+                        text_h => [ sub {...}, "dtext" ]);
+
+This creates a new parser object with a text event handler subroutine
+that receives the original text with general entities decoded.
+
+ $p = HTML::Parser->new(api_version => 3,
+			start_h => [ 'my_start', "self,tokens" ]);
+
+This creates a new parser object with a start event handler method
+that receives the $p and the tokens array.
+
+ $p = HTML::Parser->new(api_version => 3,
+		        handlers => { text => [\@array, "event,text"],
+                                      comment => [\@array, "event,text"],
+                                    });
+
+This creates a new parser object that stores the event type and the
+original text in @array for text and comment events.
+
+=back
+
+The following methods feed the HTML document
+to the C<HTML::Parser> object:
+
+=over
+
+=item $p->parse( $string )
+
+Parse $string as the next chunk of the HTML document.  The return
+value is normally a reference to the parser object (i.e. $p).
+Handlers invoked should not attempt to modify the $string in-place until
+$p->parse returns.
+
+If an invoked event handler aborts parsing by calling $p->eof, then
+$p->parse() will return a FALSE value.
+
+=item $p->parse( $code_ref )
+
+If a code reference is passed as the argument to be parsed, then the
+chunks to be parsed are obtained by invoking this function repeatedly.
+Parsing continues until the function returns an empty (or undefined)
+result.  When this happens $p->eof is automatically signaled.
+
+Parsing will also abort if one of the event handlers calls $p->eof.
+
+The effect of this is the same as:
+
+ while (1) {
+    my $chunk = &$code_ref();
+    if (!defined($chunk) || !length($chunk)) {
+        $p->eof;
+        return $p;
+    }
+    $p->parse($chunk) || return undef;
+ }
+
+But it is more efficient as this loop runs internally in XS code.
+
+=item $p->parse_file( $file )
+
+Parse text directly from a file.  The $file argument can be a
+filename, an open file handle, or a reference to an open file
+handle.
+
+If $file contains a filename and the file can't be opened, then the
+method returns an undefined value and $! tells why it failed.
+Otherwise the return value is a reference to the parser object.
+
+If a file handle is passed as the $file argument, then the file will
+normally be read until EOF, but not closed.
+
+If an invoked event handler aborts parsing by calling $p->eof,
+then $p->parse_file() may not have read the entire file.
+
+On systems with multi-byte line terminators, the values passed for the
+offset and length argspecs may be too low if parse_file() is called on
+a file handle that is not in binary mode.
+
+If a filename is passed in, then parse_file() will open the file in
+binary mode.
+
+=item $p->eof
+
+Signals the end of the HTML document.  Calling the $p->eof method
+outside a handler callback will flush any remaining buffered text
+(which triggers the C<text> event if there is any remaining text).
+
+Calling $p->eof inside a handler will terminate parsing at that point
+and cause $p->parse to return a FALSE value.  This also terminates
+parsing by $p->parse_file().
+
+After $p->eof has been called, the parse() and parse_file() methods
+can be invoked to feed new documents with the parser object.
+
+The return value from eof() is a reference to the parser object.
+
+=back
+
+
+Most parser options are controlled by boolean attributes.
+Each boolean attribute is enabled by calling the corresponding method
+with a TRUE argument and disabled with a FALSE argument.  The
+attribute value is left unchanged if no argument is given.  The return
+value from each method is the old attribute value.
+
+Methods that can be used to get and/or set parser options are:
+
+=over
+
+=item $p->attr_encoded
+
+=item $p->attr_encoded( $bool )
+
+By default, the C<attr> and C<@attr> argspecs will have general
+entities for attribute values decoded.  Enabling this attribute leaves
+entities alone.
+
+=item $p->boolean_attribute_value( $val )
+
+This method sets the value reported for boolean attributes inside HTML
+start tags.  By default, the name of the attribute is also used as its
+value.  This affects the values reported for C<tokens> and C<attr>
+argspecs.
+
+=item $p->case_sensitive
+
+=item $p->case_sensitive( $bool )
+
+By default, tagnames and attribute names are down-cased.  Enabling this
+attribute leaves them as found in the HTML source document.
+
+=item $p->closing_plaintext
+
+=item $p->closing_plaintext( $bool )
+
+By default, "plaintext" element can never be closed. Everything up to
+the end of the document is parsed in CDATA mode.  This historical
+behaviour is what at least MSIE does.  Enabling this attribute makes
+closing "</plaintext>" tag effective and the parsing process will resume
+after seeing this tag.  This emulates gecko-based browsers.
+
+=item $p->empty_element_tags
+
+=item $p->empty_element_tags( $bool )
+
+By default, empty element tags are not recognized as such and the "/"
+before ">" is just treated like a normal name character (unless
+C<strict_names> is enabled).  Enabling this attribute make
+C<HTML::Parser> recognize these tags.
+
+Empty element tags look like start tags, but end with the character
+sequence "/>" instead of ">".  When recognized by C<HTML::Parser> they
+cause an artificial end event in addition to the start event.  The
+C<text> for the artificial end event will be empty and the C<tokenpos>
+array will be undefined even though the the token array will have one
+element containing the tag name.
+
+=item $p->marked_sections
+
+=item $p->marked_sections( $bool )
+
+By default, section markings like <![CDATA[...]]> are treated like
+ordinary text.  When this attribute is enabled section markings are
+honoured.
+
+There are currently no events associated with the marked section
+markup, but the text can be returned as C<skipped_text>.
+
+=item $p->strict_comment
+
+=item $p->strict_comment( $bool )
+
+By default, comments are terminated by the first occurrence of "-->".
+This is the behaviour of most popular browsers (like Mozilla, Opera and
+MSIE), but it is not correct according to the official HTML
+standard.  Officially, you need an even number of "--" tokens before
+the closing ">" is recognized and there may not be anything but
+whitespace between an even and an odd "--".
+
+The official behaviour is enabled by enabling this attribute.
+
+Enabling of 'strict_comment' also disables recognizing these forms as
+comments:
+
+  </ comment>
+  <! comment>
+
+
+=item $p->strict_end
+
+=item $p->strict_end( $bool )
+
+By default, attributes and other junk are allowed to be present on end tags in a
+manner that emulates MSIE's behaviour.
+
+The official behaviour is enabled with this attribute.  If enabled,
+only whitespace is allowed between the tagname and the final ">".
+
+=item $p->strict_names
+
+=item $p->strict_names( $bool )
+
+By default, almost anything is allowed in tag and attribute names.
+This is the behaviour of most popular browsers and allows us to parse
+some broken tags with invalid attribute values like:
+
+   <IMG SRC=newprevlstGr.gif ALT=[PREV LIST] BORDER=0>
+
+By default, "LIST]" is parsed as a boolean attribute, not as
+part of the ALT value as was clearly intended.  This is also what
+Mozilla sees.
+
+The official behaviour is enabled by enabling this attribute.  If
+enabled, it will cause the tag above to be reported as text
+since "LIST]" is not a legal attribute name.
+
+=item $p->unbroken_text
+
+=item $p->unbroken_text( $bool )
+
+By default, blocks of text are given to the text handler as soon as
+possible (but the parser takes care always to break text at a
+boundary between whitespace and non-whitespace so single words and
+entities can always be decoded safely).  This might create breaks that
+make it hard to do transformations on the text. When this attribute is
+enabled, blocks of text are always reported in one piece.  This will
+delay the text event until the following (non-text) event has been
+recognized by the parser.
+
+Note that the C<offset> argspec will give you the offset of the first
+segment of text and C<length> is the combined length of the segments.
+Since there might be ignored tags in between, these numbers can't be
+used to directly index in the original document file.
+
+=item $p->utf8_mode
+
+=item $p->utf8_mode( $bool )
+
+Enable this option when parsing raw undecoded UTF-8.  This tells the
+parser that the entities expanded for strings reported by C<attr>,
+C<@attr> and C<dtext> should be expanded as decoded UTF-8 so they end
+up compatible with the surrounding text.
+
+If C<utf8_mode> is enabled then it is an error to pass strings
+containing characters with code above 255 to the parse() method, and
+the parse() method will croak if you try.
+
+Example: The Unicode character "\x{2665}" is "\xE2\x99\xA5" when UTF-8
+encoded.  The character can also be represented by the entity
+"&hearts;" or "&#x2665".  If we feed the parser:
+
+  $p->parse("\xE2\x99\xA5&hearts;");
+
+then C<dtext> will be reported as "\xE2\x99\xA5\x{2665}" without
+C<utf8_mode> enabled, but as "\xE2\x99\xA5\xE2\x99\xA5" when enabled.
+The later string is what you want.
+
+This option is only available with perl-5.8 or better.
+
+=item $p->xml_mode
+
+=item $p->xml_mode( $bool )
+
+Enabling this attribute changes the parser to allow some XML
+constructs.  This enables the behaviour controlled by individually by
+the C<case_sensitive>, C<empty_element_tags>, C<strict_names> and
+C<xml_pic> attributes and also suppresses special treatment of
+elements that are parsed as CDATA for HTML.
+
+=item $p->xml_pic
+
+=item $p->xml_pic( $bool )
+
+By default, I<processing instructions> are terminated by ">". When
+this attribute is enabled, processing instructions are terminated by
+"?>" instead.
+
+=back
+
+As markup and text is recognized, handlers are invoked.  The following
+method is used to set up handlers for different events:
+
+=over
+
+=item $p->handler( event => \&subroutine, $argspec )
+
+=item $p->handler( event => $method_name, $argspec )
+
+=item $p->handler( event => \@accum, $argspec )
+
+=item $p->handler( event => "" );
+
+=item $p->handler( event => undef );
+
+=item $p->handler( event );
+
+This method assigns a subroutine, method, or array to handle an event.
+
+Event is one of C<text>, C<start>, C<end>, C<declaration>, C<comment>,
+C<process>, C<start_document>, C<end_document> or C<default>.
+
+The C<\&subroutine> is a reference to a subroutine which is called to handle
+the event.
+
+The C<$method_name> is the name of a method of $p which is called to handle
+the event.
+
+The C<@accum> is an array that will hold the event information as
+sub-arrays.
+
+If the second argument is "", the event is ignored.
+If it is undef, the default handler is invoked for the event.
+
+The C<$argspec> is a string that describes the information to be reported
+for the event.  Any requested information that does not apply to a
+specific event is passed as C<undef>.  If argspec is omitted, then it
+is left unchanged.
+
+The return value from $p->handler is the old callback routine or a
+reference to the accumulator array.
+
+Any return values from handler callback routines/methods are always
+ignored.  A handler callback can request parsing to be aborted by
+invoking the $p->eof method.  A handler callback is not allowed to
+invoke the $p->parse() or $p->parse_file() method.  An exception will
+be raised if it tries.
+
+Examples:
+
+    $p->handler(start =>  "start", 'self, attr, attrseq, text' );
+
+This causes the "start" method of object $p to be called for 'start' events.
+The callback signature is $p->start(\%attr, \@attr_seq, $text).
+
+    $p->handler(start =>  \&start, 'attr, attrseq, text' );
+
+This causes subroutine start() to be called for 'start' events.
+The callback signature is start(\%attr, \@attr_seq, $text).
+
+    $p->handler(start =>  \@accum, '"S", attr, attrseq, text' );
+
+This causes 'start' event information to be saved in @accum.
+The array elements will be ['S', \%attr, \@attr_seq, $text].
+
+   $p->handler(start => "");
+
+This causes 'start' events to be ignored.  It also suppresses
+invocations of any default handler for start events.  It is in most
+cases equivalent to $p->handler(start => sub {}), but is more
+efficient.  It is different from the empty-sub-handler in that
+C<skipped_text> is not reset by it.
+
+   $p->handler(start => undef);
+
+This causes no handler to be associated with start events.
+If there is a default handler it will be invoked.
+
+=back
+
+Filters based on tags can be set up to limit the number of events
+reported.  The main bottleneck during parsing is often the huge number
+of callbacks made from the parser.  Applying filters can improve
+performance significantly.
+
+The following methods control filters:
+
+=over
+
+=item $p->ignore_elements( @tags )
+
+Both the C<start> event and the C<end> event as well as any events that
+would be reported in between are suppressed.  The ignored elements can
+contain nested occurrences of itself.  Example:
+
+   $p->ignore_elements(qw(script style));
+
+The C<script> and C<style> tags will always nest properly since their
+content is parsed in CDATA mode.  For most other tags
+C<ignore_elements> must be used with caution since HTML is often not
+I<well formed>.
+
+=item $p->ignore_tags( @tags )
+
+Any C<start> and C<end> events involving any of the tags given are
+suppressed.  To reset the filter (i.e. don't suppress any C<start> and
+C<end> events), call C<ignore_tags> without an argument.
+
+=item $p->report_tags( @tags )
+
+Any C<start> and C<end> events involving any of the tags I<not> given
+are suppressed.  To reset the filter (i.e. report all C<start> and
+C<end> events), call C<report_tags> without an argument.
+
+=back
+
+Internally, the system has two filter lists, one for C<report_tags>
+and one for C<ignore_tags>, and both filters are applied.  This
+effectively gives C<ignore_tags> precedence over C<report_tags>.
+
+Examples:
+
+   $p->ignore_tags(qw(style));
+   $p->report_tags(qw(script style));
+
+results in only C<script> events being reported.
+
+=head2 Argspec
+
+Argspec is a string containing a comma-separated list that describes
+the information reported by the event.  The following argspec
+identifier names can be used:
+
+=over
+
+=item C<attr>
+
+Attr causes a reference to a hash of attribute name/value pairs to be
+passed.
+
+Boolean attributes' values are either the value set by
+$p->boolean_attribute_value, or the attribute name if no value has been
+set by $p->boolean_attribute_value.
+
+This passes undef except for C<start> events.
+
+Unless C<xml_mode> or C<case_sensitive> is enabled, the attribute
+names are forced to lower case.
+
+General entities are decoded in the attribute values and
+one layer of matching quotes enclosing the attribute values is removed.
+
+The Unicode character set is assumed for entity decoding.  With Perl
+version 5.6 or earlier only the Latin-1 range is supported, and
+entities for characters outside the range 0..255 are left unchanged.
+
+=item C<@attr>
+
+Basically the same as C<attr>, but keys and values are passed as
+individual arguments and the original sequence of the attributes is
+kept.  The parameters passed will be the same as the @attr calculated
+here:
+
+   @attr = map { $_ => $attr->{$_} } @$attrseq;
+
+assuming $attr and $attrseq here are the hash and array passed as the
+result of C<attr> and C<attrseq> argspecs.
+
+This passes no values for events besides C<start>.
+
+=item C<attrseq>
+
+Attrseq causes a reference to an array of attribute names to be
+passed.  This can be useful if you want to walk the C<attr> hash in
+the original sequence.
+
+This passes undef except for C<start> events.
+
+Unless C<xml_mode> or C<case_sensitive> is enabled, the attribute
+names are forced to lower case.
+
+=item C<column>
+
+Column causes the column number of the start of the event to be passed.
+The first column on a line is 0.
+
+=item C<dtext>
+
+Dtext causes the decoded text to be passed.  General entities are
+automatically decoded unless the event was inside a CDATA section or
+was between literal start and end tags (C<script>, C<style>,
+C<xmp>, and C<plaintext>).
+
+The Unicode character set is assumed for entity decoding.  With Perl
+version 5.6 or earlier only the Latin-1 range is supported, and
+entities for characters outside the range 0..255 are left unchanged.
+
+This passes undef except for C<text> events.
+
+=item C<event>
+
+Event causes the event name to be passed.
+
+The event name is one of C<text>, C<start>, C<end>, C<declaration>,
+C<comment>, C<process>, C<start_document> or C<end_document>.
+
+=item C<is_cdata>
+
+Is_cdata causes a TRUE value to be passed if the event is inside a CDATA
+section or between literal start and end tags (C<script>,
+C<style>, C<xmp>, and C<plaintext>).
+
+if the flag is FALSE for a text event, then you should normally
+either use C<dtext> or decode the entities yourself before the text is
+processed further.
+
+=item C<length>
+
+Length causes the number of bytes of the source text of the event to
+be passed.
+
+=item C<line>
+
+Line causes the line number of the start of the event to be passed.
+The first line in the document is 1.  Line counting doesn't start
+until at least one handler requests this value to be reported.
+
+=item C<offset>
+
+Offset causes the byte position in the HTML document of the start of
+the event to be passed.  The first byte in the document has offset 0.
+
+=item C<offset_end>
+
+Offset_end causes the byte position in the HTML document of the end of
+the event to be passed.  This is the same as C<offset> + C<length>.
+
+=item C<self>
+
+Self causes the current object to be passed to the handler.  If the
+handler is a method, this must be the first element in the argspec.
+
+An alternative to passing self as an argspec is to register closures
+that capture $self by themselves as handlers.  Unfortunately this
+creates circular references which prevent the HTML::Parser object
+from being garbage collected.  Using the C<self> argspec avoids this
+problem.
+
+=item C<skipped_text>
+
+Skipped_text returns the concatenated text of all the events that have
+been skipped since the last time an event was reported.  Events might
+be skipped because no handler is registered for them or because some
+filter applies.  Skipped text also includes marked section markup,
+since there are no events that can catch it.
+
+If an C<"">-handler is registered for an event, then the text for this
+event is not included in C<skipped_text>.  Skipped text both before
+and after the C<"">-event is included in the next reported
+C<skipped_text>.
+
+=item C<tag>
+
+Same as C<tagname>, but prefixed with "/" if it belongs to an C<end>
+event and "!" for a declaration.  The C<tag> does not have any prefix
+for C<start> events, and is in this case identical to C<tagname>.
+
+=item C<tagname>
+
+This is the element name (or I<generic identifier> in SGML jargon) for
+start and end tags.  Since HTML is case insensitive, this name is
+forced to lower case to ease string matching.
+
+Since XML is case sensitive, the tagname case is not changed when
+C<xml_mode> is enabled.  The same happens if the C<case_sensitive> attribute
+is set.
+
+The declaration type of declaration elements is also passed as a tagname,
+even if that is a bit strange.
+In fact, in the current implementation tagname is
+identical to C<token0> except that the name may be forced to lower case.
+
+=item C<token0>
+
+Token0 causes the original text of the first token string to be
+passed.  This should always be the same as $tokens->[0].
+
+For C<declaration> events, this is the declaration type.
+
+For C<start> and C<end> events, this is the tag name.
+
+For C<process> and non-strict C<comment> events, this is everything
+inside the tag.
+
+This passes undef if there are no tokens in the event.
+
+=item C<tokenpos>
+
+Tokenpos causes a reference to an array of token positions to be
+passed.  For each string that appears in C<tokens>, this array
+contains two numbers.  The first number is the offset of the start of
+the token in the original C<text> and the second number is the length
+of the token.
+
+Boolean attributes in a C<start> event will have (0,0) for the
+attribute value offset and length.
+
+This passes undef if there are no tokens in the event (e.g., C<text>)
+and for artificial C<end> events triggered by empty element tags.
+
+If you are using these offsets and lengths to modify C<text>, you
+should either work from right to left, or be very careful to calculate
+the changes to the offsets.
+
+=item C<tokens>
+
+Tokens causes a reference to an array of token strings to be passed.
+The strings are exactly as they were found in the original text,
+no decoding or case changes are applied.
+
+For C<declaration> events, the array contains each word, comment, and
+delimited string starting with the declaration type.
+
+For C<comment> events, this contains each sub-comment.  If
+$p->strict_comments is disabled, there will be only one sub-comment.
+
+For C<start> events, this contains the original tag name followed by
+the attribute name/value pairs.  The values of boolean attributes will
+be either the value set by $p->boolean_attribute_value, or the
+attribute name if no value has been set by
+$p->boolean_attribute_value.
+
+For C<end> events, this contains the original tag name (always one token).
+
+For C<process> events, this contains the process instructions (always one
+token).
+
+This passes C<undef> for C<text> events.
+
+=item C<text>
+
+Text causes the source text (including markup element delimiters) to be
+passed.
+
+=item C<undef>
+
+Pass an undefined value.  Useful as padding where the same handler
+routine is registered for multiple events.
+
+=item C<'...'>
+
+A literal string of 0 to 255 characters enclosed
+in single (') or double (") quotes is passed as entered.
+
+=back
+
+The whole argspec string can be wrapped up in C<'@{...}'> to signal
+that the resulting event array should be flattened.  This only makes a
+difference if an array reference is used as the handler target.
+Consider this example:
+
+   $p->handler(text => [], 'text');
+   $p->handler(text => [], '@{text}']);
+
+With two text events; C<"foo">, C<"bar">; then the first example will end
+up with [["foo"], ["bar"]] and the second with ["foo", "bar"] in
+the handler target array.
+
+
+=head2 Events
+
+Handlers for the following events can be registered:
+
+=over
+
+=item C<comment>
+
+This event is triggered when a markup comment is recognized.
+
+Example:
+
+  <!-- This is a comment -- -- So is this -->
+
+=item C<declaration>
+
+This event is triggered when a I<markup declaration> is recognized.
+
+For typical HTML documents, the only declaration you are
+likely to find is <!DOCTYPE ...>.
+
+Example:
+
+  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+  "http://www.w3.org/TR/html40/strict.dtd">
+
+DTDs inside <!DOCTYPE ...> will confuse HTML::Parser.
+
+=item C<default>
+
+This event is triggered for events that do not have a specific
+handler.  You can set up a handler for this event to catch stuff you
+did not want to catch explicitly.
+
+=item C<end>
+
+This event is triggered when an end tag is recognized.
+
+Example:
+
+  </A>
+
+=item C<end_document>
+
+This event is triggered when $p->eof is called and after any remaining
+text is flushed.  There is no document text associated with this event.
+
+=item C<process>
+
+This event is triggered when a processing instructions markup is
+recognized.
+
+The format and content of processing instructions are system and
+application dependent.
+
+Examples:
+
+  <? HTML processing instructions >
+  <? XML processing instructions ?>
+
+=item C<start>
+
+This event is triggered when a start tag is recognized.
+
+Example:
+
+  <A HREF="http://www.perl.com/">
+
+=item C<start_document>
+
+This event is triggered before any other events for a new document.  A
+handler for it can be used to initialize stuff.  There is no document
+text associated with this event.
+
+=item C<text>
+
+This event is triggered when plain text (characters) is recognized.
+The text may contain multiple lines.  A sequence of text may be broken
+between several text events unless $p->unbroken_text is enabled.
+
+The parser will make sure that it does not break a word or a sequence
+of whitespace between two text events.
+
+=back
+
+=head2 Unicode
+
+The C<HTML::Parser> can parse Unicode strings when running under
+perl-5.8 or better.  If Unicode is passed to $p->parse() then chunks
+of Unicode will be reported to the handlers.  The offset and length
+argspecs will also report their position in terms of characters.
+
+It is safe to parse raw undecoded UTF-8 if you either avoid decoding
+entities and make sure to not use I<argspecs> that do, or enable the
+C<utf8_mode> for the parser.  Parsing of undecoded UTF-8 might be
+useful when parsing from a file where you need the reported offsets
+and lengths to match the byte offsets in the file.
+
+If a filename is passed to $p->parse_file() then the file will be read
+in binary mode.  This will be fine if the file contains only ASCII or
+Latin-1 characters.  If the file contains UTF-8 encoded text then care
+must be taken when decoding entities as described in the previous
+paragraph, but better is to open the file with the UTF-8 layer so that
+it is decoded properly:
+
+   open(my $fh, "<:utf8", "index.html") || die "...: $!";
+   $p->parse_file($fh);
+
+If the file contains text encoded in a charset besides ASCII, Latin-1
+or UTF-8 then decoding will always be needed.
+
+=head1 VERSION 2 COMPATIBILITY
+
+When an C<HTML::Parser> object is constructed with no arguments, a set
+of handlers is automatically provided that is compatible with the old
+HTML::Parser version 2 callback methods.
+
+This is equivalent to the following method calls:
+
+   $p->handler(start   => "start",   "self, tagname, attr, attrseq, text");
+   $p->handler(end     => "end",     "self, tagname, text");
+   $p->handler(text    => "text",    "self, text, is_cdata");
+   $p->handler(process => "process", "self, token0, text");
+   $p->handler(comment =>
+             sub {
+		 my($self, $tokens) = @_;
+		 for (@$tokens) {$self->comment($_);}},
+             "self, tokens");
+   $p->handler(declaration =>
+             sub {
+		 my $self = shift;
+		 $self->declaration(substr($_[0], 2, -1));},
+             "self, text");
+
+Setting up these handlers can also be requested with the "api_version =>
+2" constructor option.
+
+=head1 SUBCLASSING
+
+The C<HTML::Parser> class is subclassable.  Parser objects are plain
+hashes and C<HTML::Parser> reserves only hash keys that start with
+"_hparser".  The parser state can be set up by invoking the init()
+method, which takes the same arguments as new().
+
+=head1 EXAMPLES
+
+The first simple example shows how you might strip out comments from
+an HTML document.  We achieve this by setting up a comment handler that
+does nothing and a default handler that will print out anything else:
+
+  use HTML::Parser;
+  HTML::Parser->new(default_h => [sub { print shift }, 'text'],
+                    comment_h => [""],
+                   )->parse_file(shift || die) || die $!;
+
+An alternative implementation is:
+
+  use HTML::Parser;
+  HTML::Parser->new(end_document_h => [sub { print shift },
+                                       'skipped_text'],
+                    comment_h      => [""],
+                   )->parse_file(shift || die) || die $!;
+
+This will in most cases be much more efficient since only a single
+callback will be made.
+
+The next example prints out the text that is inside the <title>
+element of an HTML document.  Here we start by setting up a start
+handler.  When it sees the title start tag it enables a text handler
+that prints any text found and an end handler that will terminate
+parsing as soon as the title end tag is seen:
+
+  use HTML::Parser ();
+
+  sub start_handler
+  {
+    return if shift ne "title";
+    my $self = shift;
+    $self->handler(text => sub { print shift }, "dtext");
+    $self->handler(end  => sub { shift->eof if shift eq "title"; },
+		           "tagname,self");
+  }
+
+  my $p = HTML::Parser->new(api_version => 3);
+  $p->handler( start => \&start_handler, "tagname,self");
+  $p->parse_file(shift || die) || die $!;
+  print "\n";
+
+More examples are found in the F<eg/> directory of the C<HTML-Parser>
+distribution: the program C<hrefsub> shows how you can edit all links
+found in a document; the program C<htextsub> shows how to edit the text only; the
+program C<hstrip> shows how you can strip out certain tags/elements
+and/or attributes; and the program C<htext> show how to obtain the
+plain text, but not any script/style content.
+
+You can browse the F<eg/> directory online from the I<[Browse]> link on
+the http://search.cpan.org/~gaas/HTML-Parser/ page.
+
+=head1 BUGS
+
+The <style> and <script> sections do not end with the first "</", but
+need the complete corresponding end tag.  The standard behaviour is
+not really practical.
+
+When the I<strict_comment> option is enabled, we still recognize
+comments where there is something other than whitespace between even
+and odd "--" markers.
+
+Once $p->boolean_attribute_value has been set, there is no way to
+restore the default behaviour.
+
+There is currently no way to get both quote characters
+into the same literal argspec.
+
+Empty tags, e.g. "<>" and "</>", are not recognized.  SGML allows them
+to repeat the previous start tag or close the previous start tag
+respectively.
+
+NET tags, e.g. "code/.../" are not recognized.  This is SGML
+shorthand for "<code>...</code>".
+
+Unclosed start or end tags, e.g. "<tt<b>...</b</tt>" are not
+recognized.
+
+=head1 DIAGNOSTICS
+
+The following messages may be produced by HTML::Parser.  The notation
+in this listing is the same as used in L<perldiag>:
+
+=over
+
+=item Not a reference to a hash
+
+(F) The object blessed into or subclassed from HTML::Parser is not a
+hash as required by the HTML::Parser methods.
+
+=item Bad signature in parser state object at %p
+
+(F) The _hparser_xs_state element does not refer to a valid state structure.
+Something must have changed the internal value
+stored in this hash element, or the memory has been overwritten.
+
+=item _hparser_xs_state element is not a reference
+
+(F) The _hparser_xs_state element has been destroyed.
+
+=item Can't find '_hparser_xs_state' element in HTML::Parser hash
+
+(F) The _hparser_xs_state element is missing from the parser hash.
+It was either deleted, or not created when the object was created.
+
+=item API version %s not supported by HTML::Parser %s
+
+(F) The constructor option 'api_version' with an argument greater than
+or equal to 4 is reserved for future extensions.
+
+=item Bad constructor option '%s'
+
+(F) An unknown constructor option key was passed to the new() or
+init() methods.
+
+=item Parse loop not allowed
+
+(F) A handler invoked the parse() or parse_file() method.
+This is not permitted.
+
+=item marked sections not supported
+
+(F) The $p->marked_sections() method was invoked in a HTML::Parser
+module that was compiled without support for marked sections.
+
+=item Unknown boolean attribute (%d)
+
+(F) Something is wrong with the internal logic that set up aliases for
+boolean attributes.
+
+=item Only code or array references allowed as handler
+
+(F) The second argument for $p->handler must be either a subroutine
+reference, then name of a subroutine or method, or a reference to an
+array.
+
+=item No handler for %s events
+
+(F) The first argument to $p->handler must be a valid event name; i.e. one
+of "start", "end", "text", "process", "declaration" or "comment".
+
+=item Unrecognized identifier %s in argspec
+
+(F) The identifier is not a known argspec name.
+Use one of the names mentioned in the argspec section above.
+
+=item Literal string is longer than 255 chars in argspec
+
+(F) The current implementation limits the length of literals in
+an argspec to 255 characters.  Make the literal shorter.
+
+=item Backslash reserved for literal string in argspec
+
+(F) The backslash character "\" is not allowed in argspec literals.
+It is reserved to permit quoting inside a literal in a later version.
+
+=item Unterminated literal string in argspec
+
+(F) The terminating quote character for a literal was not found.
+
+=item Bad argspec (%s)
+
+(F) Only identifier names, literals, spaces and commas
+are allowed in argspecs.
+
+=item Missing comma separator in argspec
+
+(F) Identifiers in an argspec must be separated with ",".
+
+=item Parsing of undecoded UTF-8 will give garbage when decoding entities
+
+(W) The first chunk parsed appears to contain undecoded UTF-8 and one
+or more argspecs that decode entities are used for the callback
+handlers.
+
+The result of decoding will be a mix of encoded and decoded characters
+for any entities that expand to characters with code above 127.  This
+is not a good thing.
+
+The solution is to use the Encode::encode_utf8() on the data before
+feeding it to the $p->parse().  For $p->parse_file() pass a file that
+has been opened in ":utf8" mode.
+
+The parser can process raw undecoded UTF-8 sanely if the C<utf8_mode>
+is enabled or if the "attr", "@attr" or "dtext" argspecs is avoided.
+
+=item Parsing string decoded with wrong endianess
+
+(W) The first character in the document is U+FFFE.  This is not a
+legal Unicode character but a byte swapped BOM.  The result of parsing
+will likely be garbage.
+
+=item Parsing of undecoded UTF-32
+
+(W) The parser found the Unicode UTF-32 BOM signature at the start
+of the document.  The result of parsing will likely be garbage.
+
+=item Parsing of undecoded UTF-16
+
+(W) The parser found the Unicode UTF-16 BOM signature at the start of
+the document.  The result of parsing will likely be garbage.
+
+=back
+
+=head1 SEE ALSO
+
+L<HTML::Entities>, L<HTML::PullParser>, L<HTML::TokeParser>, L<HTML::HeadParser>,
+L<HTML::LinkExtor>, L<HTML::Form>
+
+L<HTML::TreeBuilder> (part of the I<HTML-Tree> distribution)
+
+http://www.w3.org/TR/html4
+
+More information about marked sections and processing instructions may
+be found at C<http://www.sgml.u-net.com/book/sgml-8.htm>.
+
+=head1 COPYRIGHT
+
+ Copyright 1996-2007 Gisle Aas. All rights reserved.
+ Copyright 1999-2000 Michael A. Chase.  All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/perllib/cpan/HTML/PullParser.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/PullParser.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/PullParser.pm	(revision 20131)
@@ -0,0 +1,211 @@
+package HTML::PullParser;
+
+# $Id$
+
+require HTML::Parser;
+@ISA=qw(HTML::Parser);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+use strict;
+use Carp ();
+
+sub new
+{
+    my($class, %cnf) = @_;
+
+    # Construct argspecs for the various events
+    my %argspec;
+    for (qw(start end text declaration comment process default)) {
+	my $tmp = delete $cnf{$_};
+	next unless defined $tmp;
+	$argspec{$_} = $tmp;
+    }
+    Carp::croak("Info not collected for any events")
+	  unless %argspec;
+
+    my $file = delete $cnf{file};
+    my $doc  = delete $cnf{doc};
+    Carp::croak("Can't parse from both 'doc' and 'file' at the same time")
+	  if defined($file) && defined($doc);
+    Carp::croak("No 'doc' or 'file' given to parse from")
+	  unless defined($file) || defined($doc);
+
+    # Create object
+    $cnf{api_version} = 3;
+    my $self = $class->SUPER::new(%cnf);
+
+    my $accum = $self->{pullparser_accum} = [];
+    while (my($event, $argspec) = each %argspec) {
+	$self->SUPER::handler($event => $accum, $argspec);
+    }
+
+    if (defined $doc) {
+	$self->{pullparser_str_ref} = ref($doc) ? $doc : \$doc;
+	$self->{pullparser_str_pos} = 0;
+    }
+    else {
+	if (!ref($file) && ref(\$file) ne "GLOB") {
+	    require IO::File;
+	    $file = IO::File->new($file, "r") || return;
+	}
+
+	$self->{pullparser_file} = $file;
+    }
+    $self;
+}
+
+
+sub handler
+{
+    Carp::croak("Can't set handlers for HTML::PullParser");
+}
+
+
+sub get_token
+{
+    my $self = shift;
+    while (!@{$self->{pullparser_accum}} && !$self->{pullparser_eof}) {
+	if (my $f = $self->{pullparser_file}) {
+	    # must try to parse more from the file
+	    my $buf;
+	    if (read($f, $buf, 512)) {
+		$self->parse($buf);
+	    } else {
+		$self->eof;
+		$self->{pullparser_eof}++;
+		delete $self->{pullparser_file};
+	    }
+	}
+	elsif (my $sref = $self->{pullparser_str_ref}) {
+	    # must try to parse more from the scalar
+	    my $pos = $self->{pullparser_str_pos};
+	    my $chunk = substr($$sref, $pos, 512);
+	    $self->parse($chunk);
+	    $pos += length($chunk);
+	    if ($pos < length($$sref)) {
+		$self->{pullparser_str_pos} = $pos;
+	    }
+	    else {
+		$self->eof;
+		$self->{pullparser_eof}++;
+		delete $self->{pullparser_str_ref};
+		delete $self->{pullparser_str_pos};
+	    }
+	}
+	else {
+	    die;
+	}
+    }
+    shift @{$self->{pullparser_accum}};
+}
+
+
+sub unget_token
+{
+    my $self = shift;
+    unshift @{$self->{pullparser_accum}}, @_;
+    $self;
+}
+
+1;
+
+
+__END__
+
+=head1 NAME
+
+HTML::PullParser - Alternative HTML::Parser interface
+
+=head1 SYNOPSIS
+
+ use HTML::PullParser;
+
+ $p = HTML::PullParser->new(file => "index.html",
+                            start => 'event, tagname, @attr',
+                            end   => 'event, tagname',
+                            ignore_elements => [qw(script style)],
+                           ) || die "Can't open: $!";
+ while (my $token = $p->get_token) {
+     #...do something with $token
+ }
+
+=head1 DESCRIPTION
+
+The HTML::PullParser is an alternative interface to the HTML::Parser class.
+It basically turns the HTML::Parser inside out.  You associate a file
+(or any IO::Handle object or string) with the parser at construction time and
+then repeatedly call $parser->get_token to obtain the tags and text
+found in the parsed document.
+
+The following methods are provided:
+
+=over 4
+
+=item $p = HTML::PullParser->new( file => $file, %options )
+
+=item $p = HTML::PullParser->new( doc => \$doc, %options )
+
+A C<HTML::PullParser> can be made to parse from either a file or a
+literal document based on whether the C<file> or C<doc> option is
+passed to the parser's constructor.
+
+The C<file> passed in can either be a file name or a file handle
+object.  If a file name is passed, and it can't be opened for reading,
+then the constructor will return an undefined value and $!  will tell
+you why it failed.  Otherwise the argument is taken to be some object
+that the C<HTML::PullParser> can read() from when it needs more data.
+The stream will be read() until EOF, but not closed.
+
+A C<doc> can be passed plain or as a reference
+to a scalar.  If a reference is passed then the value of this scalar
+should not be changed before all tokens have been extracted.
+
+Next the information to be returned for the different token types must
+be set up.  This is done by simply associating an argspec (as defined
+in L<HTML::Parser>) with the events you have an interest in.  For
+instance, if you want C<start> tokens to be reported as the string
+C<'S'> followed by the tagname and the attributes you might pass an
+C<start>-option like this:
+
+   $p = HTML::PullParser->new(
+          doc   => $document_to_parse,
+          start => '"S", tagname, @attr',
+          end   => '"E", tagname',
+        );
+
+At last other C<HTML::Parser> options, like C<ignore_tags>, and
+C<unbroken_text>, can be passed in.  Note that you should not use the
+I<event>_h options to set up parser handlers.  That would confuse the
+inner logic of C<HTML::PullParser>.
+
+=item $token = $p->get_token
+
+This method will return the next I<token> found in the HTML document,
+or C<undef> at the end of the document.  The token is returned as an
+array reference.  The content of this array match the argspec set up
+during C<HTML::PullParser> construction.
+
+=item $p->unget_token( @tokens )
+
+If you find out you have read too many tokens you can push them back,
+so that they are returned again the next time $p->get_token is called.
+
+=back
+
+=head1 EXAMPLES
+
+The 'eg/hform' script shows how we might parse the form section of
+HTML::Documents using HTML::PullParser.
+
+=head1 SEE ALSO
+
+L<HTML::Parser>, L<HTML::TokeParser>
+
+=head1 COPYRIGHT
+
+Copyright 1998-2001 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/perllib/cpan/HTML/Tagset.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/Tagset.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/Tagset.pm	(revision 20131)
@@ -0,0 +1,470 @@
+package HTML::Tagset;
+
+use strict;
+
+=head1 NAME
+
+HTML::Tagset - data tables useful in parsing HTML
+
+=head1 VERSION
+
+Version 3.10
+
+=cut
+
+use vars qw( $VERSION );
+
+$VERSION = '3.10';
+
+=head1 SYNOPSIS
+
+  use HTML::Tagset;
+  # Then use any of the items in the HTML::Tagset package
+  #  as need arises
+
+=head1 DESCRIPTION
+
+This module contains several data tables useful in various kinds of
+HTML parsing operations.
+
+Note that all tag names used are lowercase.
+
+In the following documentation, a "hashset" is a hash being used as a
+set -- the hash conveys that its keys are there, and the actual values
+associated with the keys are not significant.  (But what values are
+there, are always true.)
+
+=cut
+
+use vars qw(
+    $VERSION
+    %emptyElement %optionalEndTag %linkElements %boolean_attr
+    %isHeadElement %isBodyElement %isPhraseMarkup
+    %is_Possible_Strict_P_Content
+    %isHeadOrBodyElement
+    %isList %isTableElement %isFormElement
+    %isKnown %canTighten
+    @p_closure_barriers
+    %isCDATA_Parent
+);
+
+=head1 VARIABLES
+
+Note that none of these variables are exported.
+
+=head2 hashset %HTML::Tagset::emptyElement
+
+This hashset has as values the tag-names (GIs) of elements that cannot
+have content.  (For example, "base", "br", "hr".)  So
+C<$HTML::Tagset::emptyElement{'hr'}> exists and is true.
+C<$HTML::Tagset::emptyElement{'dl'}> does not exist, and so is not true.
+
+=cut
+
+%emptyElement   = map {; $_ => 1 } qw(base link meta isindex
+                                     img br hr wbr
+                                     input area param
+                                     embed bgsound spacer
+                                     basefont col frame
+                                     ~comment ~literal
+                                     ~declaration ~pi
+                                    );
+# The "~"-initial names are for pseudo-elements used by HTML::Entities
+#  and TreeBuilder
+
+=head2 hashset %HTML::Tagset::optionalEndTag
+
+This hashset lists tag-names for elements that can have content, but whose
+end-tags are generally, "safely", omissible.  Example:
+C<$HTML::Tagset::emptyElement{'li'}> exists and is true.
+
+=cut
+
+%optionalEndTag = map {; $_ => 1 } qw(p li dt dd); # option th tr td);
+
+=head2 hash %HTML::Tagset::linkElements
+
+Values in this hash are tagnames for elements that might contain
+links, and the value for each is a reference to an array of the names
+of attributes whose values can be links.
+
+=cut
+
+%linkElements =
+(
+ 'a'       => ['href'],
+ 'applet'  => ['archive', 'codebase', 'code'],
+ 'area'    => ['href'],
+ 'base'    => ['href'],
+ 'bgsound' => ['src'],
+ 'blockquote' => ['cite'],
+ 'body'    => ['background'],
+ 'del'     => ['cite'],
+ 'embed'   => ['pluginspage', 'src'],
+ 'form'    => ['action'],
+ 'frame'   => ['src', 'longdesc'],
+ 'iframe'  => ['src', 'longdesc'],
+ 'ilayer'  => ['background'],
+ 'img'     => ['src', 'lowsrc', 'longdesc', 'usemap'],
+ 'input'   => ['src', 'usemap'],
+ 'ins'     => ['cite'],
+ 'isindex' => ['action'],
+ 'head'    => ['profile'],
+ 'layer'   => ['background', 'src'],
+ 'link'    => ['href'],
+ 'object'  => ['classid', 'codebase', 'data', 'archive', 'usemap'],
+ 'q'       => ['cite'],
+ 'script'  => ['src', 'for'],
+ 'table'   => ['background'],
+ 'td'      => ['background'],
+ 'th'      => ['background'],
+ 'tr'      => ['background'],
+ 'xmp'     => ['href'],
+);
+
+=head2 hash %HTML::Tagset::boolean_attr
+
+This hash (not hashset) lists what attributes of what elements can be
+printed without showing the value (for example, the "noshade" attribute
+of "hr" elements).  For elements with only one such attribute, its value
+is simply that attribute name.  For elements with many such attributes,
+the value is a reference to a hashset containing all such attributes.
+
+=cut
+
+%boolean_attr = (
+# TODO: make these all hashes
+  'area'   => 'nohref',
+  'dir'    => 'compact',
+  'dl'     => 'compact',
+  'hr'     => 'noshade',
+  'img'    => 'ismap',
+  'input'  => { 'checked' => 1, 'readonly' => 1, 'disabled' => 1 },
+  'menu'   => 'compact',
+  'ol'     => 'compact',
+  'option' => 'selected',
+  'select' => 'multiple',
+  'td'     => 'nowrap',
+  'th'     => 'nowrap',
+  'ul'     => 'compact',
+);
+
+#==========================================================================
+# List of all elements from Extensible HTML version 1.0 Transitional DTD:
+#
+#   a abbr acronym address applet area b base basefont bdo big
+#   blockquote body br button caption center cite code col colgroup
+#   dd del dfn dir div dl dt em fieldset font form h1 h2 h3 h4 h5 h6
+#   head hr html i iframe img input ins isindex kbd label legend li
+#   link map menu meta noframes noscript object ol optgroup option p
+#   param pre q s samp script select small span strike strong style
+#   sub sup table tbody td textarea tfoot th thead title tr tt u ul
+#   var
+#
+# Varia from Mozilla source internal table of tags:
+#   Implemented:
+#     xmp listing wbr nobr frame frameset noframes ilayer
+#     layer nolayer spacer embed multicol
+#   But these are unimplemented:
+#     sound??  keygen??  server??
+# Also seen here and there:
+#     marquee??  app??  (both unimplemented)
+#==========================================================================
+
+=head2 hashset %HTML::Tagset::isPhraseMarkup
+
+This hashset contains all phrasal-level elements.
+
+=cut
+
+%isPhraseMarkup = map {; $_ => 1 } qw(
+  span abbr acronym q sub sup
+  cite code em kbd samp strong var dfn strike
+  b i u s tt small big 
+  a img br
+  wbr nobr blink
+  font basefont bdo
+  spacer embed noembed
+);  # had: center, hr, table
+
+
+=head2 hashset %HTML::Tagset::is_Possible_Strict_P_Content
+
+This hashset contains all phrasal-level elements that be content of a
+P element, for a strict model of HTML.
+
+=cut
+
+%is_Possible_Strict_P_Content = (
+ %isPhraseMarkup,
+ %isFormElement,
+ map {; $_ => 1} qw( object script map )
+  # I've no idea why there's these latter exceptions.
+  # I'm just following the HTML4.01 DTD.
+);
+
+#from html4 strict:
+#<!ENTITY % fontstyle "TT | I | B | BIG | SMALL">
+#
+#<!ENTITY % phrase "EM | STRONG | DFN | CODE |
+#                   SAMP | KBD | VAR | CITE | ABBR | ACRONYM" >
+#
+#<!ENTITY % special
+#   "A | IMG | OBJECT | BR | SCRIPT | MAP | Q | SUB | SUP | SPAN | BDO">
+#
+#<!ENTITY % formctrl "INPUT | SELECT | TEXTAREA | LABEL | BUTTON">
+#
+#<!-- %inline; covers inline or "text-level" elements -->
+#<!ENTITY % inline "#PCDATA | %fontstyle; | %phrase; | %special; | %formctrl;">
+
+=head2 hashset %HTML::Tagset::isHeadElement
+
+This hashset contains all elements that elements that should be
+present only in the 'head' element of an HTML document.
+
+=cut
+
+%isHeadElement = map {; $_ => 1 }
+ qw(title base link meta isindex script style object bgsound);
+
+=head2 hashset %HTML::Tagset::isList
+
+This hashset contains all elements that can contain "li" elements.
+
+=cut
+
+%isList         = map {; $_ => 1 } qw(ul ol dir menu);
+
+=head2 hashset %HTML::Tagset::isTableElement
+
+This hashset contains all elements that are to be found only in/under
+a "table" element.
+
+=cut
+
+%isTableElement = map {; $_ => 1 }
+ qw(tr td th thead tbody tfoot caption col colgroup);
+
+=head2 hashset %HTML::Tagset::isFormElement
+
+This hashset contains all elements that are to be found only in/under
+a "form" element.
+
+=cut
+
+%isFormElement  = map {; $_ => 1 }
+ qw(input select option optgroup textarea button label);
+
+=head2 hashset %HTML::Tagset::isBodyMarkup
+
+This hashset contains all elements that are to be found only in/under
+the "body" element of an HTML document.
+
+=cut
+
+%isBodyElement = map {; $_ => 1 } qw(
+  h1 h2 h3 h4 h5 h6
+  p div pre plaintext address blockquote
+  xmp listing
+  center
+
+  multicol
+  iframe ilayer nolayer
+  bgsound
+
+  hr
+  ol ul dir menu li
+  dl dt dd
+  ins del
+  
+  fieldset legend
+  
+  map area
+  applet param object
+  isindex script noscript
+  table
+  center
+  form
+ ),
+ keys %isFormElement,
+ keys %isPhraseMarkup,   # And everything phrasal
+ keys %isTableElement,
+;
+
+
+=head2 hashset %HTML::Tagset::isHeadOrBodyElement
+
+This hashset includes all elements that I notice can fall either in
+the head or in the body.
+
+=cut
+
+%isHeadOrBodyElement = map {; $_ => 1 }
+  qw(script isindex style object map area param noscript bgsound);
+  # i.e., if we find 'script' in the 'body' or the 'head', don't freak out.
+
+
+=head2 hashset %HTML::Tagset::isKnown
+
+This hashset lists all known HTML elements.
+
+=cut
+
+%isKnown = (%isHeadElement, %isBodyElement,
+  map{; $_=>1 }
+   qw( head body html
+       frame frameset noframes
+       ~comment ~pi ~directive ~literal
+));
+ # that should be all known tags ever ever
+
+
+=head2 hashset %HTML::Tagset::canTighten
+
+This hashset lists elements that might have ignorable whitespace as
+children or siblings.
+
+=cut
+
+%canTighten = %isKnown;
+delete @canTighten{
+  keys(%isPhraseMarkup), 'input', 'select',
+  'xmp', 'listing', 'plaintext', 'pre',
+};
+  # xmp, listing, plaintext, and pre  are untightenable, and
+  #   in a really special way.
+@canTighten{'hr','br'} = (1,1);
+ # exceptional 'phrasal' things that ARE subject to tightening.
+
+# The one case where I can think of my tightening rules failing is:
+#  <p>foo bar<center> <em>baz quux</em> ...
+#                    ^-- that would get deleted.
+# But that's pretty gruesome code anyhow.  You gets what you pays for.
+
+#==========================================================================
+
+=head2 array @HTML::Tagset::p_closure_barriers
+
+This array has a meaning that I have only seen a need for in
+C<HTML::TreeBuilder>, but I include it here on the off chance that someone
+might find it of use:
+
+When we see a "E<lt>pE<gt>" token, we go lookup up the lineage for a p
+element we might have to minimize.  At first sight, we might say that
+if there's a p anywhere in the lineage of this new p, it should be
+closed.  But that's wrong.  Consider this document:
+
+  <html>
+    <head>
+      <title>foo</title>
+    </head>
+    <body>
+      <p>foo
+        <table>
+          <tr>
+            <td>
+               foo
+               <p>bar
+            </td>
+          </tr>
+        </table>
+      </p>
+    </body>
+  </html>
+
+The second p is quite legally inside a much higher p.
+
+My formalization of the reason why this is legal, but this:
+
+  <p>foo<p>bar</p></p>
+
+isn't, is that something about the table constitutes a "barrier" to
+the application of the rule about what p must minimize.
+
+So C<@HTML::Tagset::p_closure_barriers> is the list of all such
+barrier-tags.
+
+=cut
+
+@p_closure_barriers = qw(
+  li blockquote
+  ul ol menu dir
+  dl dt dd
+  td th tr table caption
+ );
+
+# In an ideal world (i.e., XHTML) we wouldn't have to bother with any of this
+# monkey business of barriers to minimization!
+
+=head2 hashset %isCDATA_Parent
+
+This hashset includes all elements whose content is CDATA.
+
+=cut
+
+%isCDATA_Parent = map {; $_ => 1 }
+  qw(script style  xmp listing plaintext);
+
+# TODO: there's nothing else that takes CDATA children, right?
+
+# As the HTML3 DTD (Raggett 1995-04-24) noted:
+#   The XMP, LISTING and PLAINTEXT tags are incompatible with SGML
+#   and derive from very early versions of HTML. They require non-
+#   standard parsers and will cause problems for processing
+#   documents with standard SGML tools.
+
+
+=head1 CAVEATS
+
+You may find it useful to alter the behavior of modules (like
+C<HTML::Element> or C<HTML::TreeBuilder>) that use C<HTML::Tagset>'s
+data tables by altering the data tables themselves.  You are welcome
+to try, but be careful; and be aware that different modules may or may
+react differently to the data tables being changed.
+
+Note that it may be inappropriate to use these tables for I<producing>
+HTML -- for example, C<%isHeadOrBodyElement> lists the tagnames
+for all elements that can appear either in the head or in the body,
+such as "script".  That doesn't mean that I am saying your code that
+produces HTML should feel free to put script elements in either place!
+If you are producing programs that spit out HTML, you should be
+I<intimately> familiar with the DTDs for HTML or XHTML (available at
+C<http://www.w3.org/>), and you should slavishly obey them, not
+the data tables in this document.
+
+=head1 SEE ALSO
+
+L<HTML::Element>, L<HTML::TreeBuilder>, L<HTML::LinkExtor>
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 1995-2000 Gisle Aas.
+
+Copyright 2000-2005 Sean M. Burke.
+
+Copyright 2005 Andy Lester.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 ACKNOWLEDGEMENTS
+
+Most of the code/data in this module was adapted from code written
+by Gisle Aas for C<HTML::Element>, C<HTML::TreeBuilder>, and
+C<HTML::LinkExtor>.  Then it was maintained by Sean M. Burke.
+
+=head1 AUTHOR
+
+Current maintainer: Andy Lester, C<< <andy at petdance.com> >>
+
+=head1 BUGS
+
+Please report any bugs or feature requests to
+C<bug-html-tagset at rt.cpan.org>, or through the web interface at
+L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=HTML-Tagset>.  I will
+be notified, and then you'll automatically be notified of progress on
+your bug as I make changes.
+
+=cut
+
+1;
Index: /gsdl/stable/perllib/cpan/HTML/TokeParser.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/TokeParser.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/TokeParser.pm	(revision 20131)
@@ -0,0 +1,371 @@
+package HTML::TokeParser;
+
+# $Id$
+
+require HTML::PullParser;
+@ISA=qw(HTML::PullParser);
+$VERSION = sprintf("%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/);
+
+use strict;
+use Carp ();
+use HTML::Entities qw(decode_entities);
+use HTML::Tagset ();
+
+my %ARGS =
+(
+ start       => "'S',tagname,attr,attrseq,text",
+ end         => "'E',tagname,text",
+ text        => "'T',text,is_cdata",
+ process     => "'PI',token0,text",
+ comment     => "'C',text",
+ declaration => "'D',text",
+
+ # options that default on
+ unbroken_text => 1,
+);
+
+
+sub new
+{
+    my $class = shift;
+    my %cnf;
+    if (@_ == 1) {
+	my $type = (ref($_[0]) eq "SCALAR") ? "doc" : "file";
+	%cnf = ($type => $_[0]);
+    }
+    else {
+	%cnf = @_;
+    }
+
+    my $textify = delete $cnf{textify} || {img => "alt", applet => "alt"};
+
+    my $self = $class->SUPER::new(%cnf, %ARGS) || return undef;
+
+    $self->{textify} = $textify;
+    $self;
+}
+
+
+sub get_tag
+{
+    my $self = shift;
+    my $token;
+    while (1) {
+	$token = $self->get_token || return undef;
+	my $type = shift @$token;
+	next unless $type eq "S" || $type eq "E";
+	substr($token->[0], 0, 0) = "/" if $type eq "E";
+	return $token unless @_;
+	for (@_) {
+	    return $token if $token->[0] eq $_;
+	}
+    }
+}
+
+
+sub _textify {
+    my($self, $token) = @_;
+    my $tag = $token->[1];
+    return undef unless exists $self->{textify}{$tag};
+
+    my $alt = $self->{textify}{$tag};
+    my $text;
+    if (ref($alt)) {
+	$text = &$alt(@$token);
+    } else {
+	$text = $token->[2]{$alt || "alt"};
+	$text = "[\U$tag]" unless defined $text;
+    }
+    return $text;
+}
+
+
+sub get_text
+{
+    my $self = shift;
+    my @text;
+    while (my $token = $self->get_token) {
+	my $type = $token->[0];
+	if ($type eq "T") {
+	    my $text = $token->[1];
+	    decode_entities($text) unless $token->[2];
+	    push(@text, $text);
+	} elsif ($type =~ /^[SE]$/) {
+	    my $tag = $token->[1];
+	    if ($type eq "S") {
+		if (defined(my $text = _textify($self, $token))) {
+		    push(@text, $text);
+		    next;
+		}
+	    } else {
+		$tag = "/$tag";
+	    }
+	    if (!@_ || grep $_ eq $tag, @_) {
+		 $self->unget_token($token);
+		 last;
+	    }
+	    push(@text, " ")
+		if $tag eq "br" || !$HTML::Tagset::isPhraseMarkup{$token->[1]};
+	}
+    }
+    join("", @text);
+}
+
+
+sub get_trimmed_text
+{
+    my $self = shift;
+    my $text = $self->get_text(@_);
+    $text =~ s/^\s+//; $text =~ s/\s+$//; $text =~ s/\s+/ /g;
+    $text;
+}
+
+sub get_phrase {
+    my $self = shift;
+    my @text;
+    while (my $token = $self->get_token) {
+	my $type = $token->[0];
+	if ($type eq "T") {
+	    my $text = $token->[1];
+	    decode_entities($text) unless $token->[2];
+	    push(@text, $text);
+	} elsif ($type =~ /^[SE]$/) {
+	    my $tag = $token->[1];
+	    if ($type eq "S") {
+		if (defined(my $text = _textify($self, $token))) {
+		    push(@text, $text);
+		    next;
+		}
+	    }
+	    if (!$HTML::Tagset::isPhraseMarkup{$tag}) {
+		$self->unget_token($token);
+		last;
+	    }
+	    push(@text, " ") if $tag eq "br";
+	}
+    }
+    my $text = join("", @text);
+    $text =~ s/^\s+//; $text =~ s/\s+$//; $text =~ s/\s+/ /g;
+    $text;
+}
+
+1;
+
+
+__END__
+
+=head1 NAME
+
+HTML::TokeParser - Alternative HTML::Parser interface
+
+=head1 SYNOPSIS
+
+ require HTML::TokeParser;
+ $p = HTML::TokeParser->new("index.html") ||
+      die "Can't open: $!";
+ $p->empty_element_tags(1);  # configure its behaviour
+
+ while (my $token = $p->get_token) {
+     #...
+ }
+
+=head1 DESCRIPTION
+
+The C<HTML::TokeParser> is an alternative interface to the
+C<HTML::Parser> class.  It is an C<HTML::PullParser> subclass with a
+predeclared set of token types.  If you wish the tokens to be reported
+differently you probably want to use the C<HTML::PullParser> directly.
+
+The following methods are available:
+
+=over 4
+
+=item $p = HTML::TokeParser->new( $filename, %opt );
+
+=item $p = HTML::TokeParser->new( $filehandle, %opt );
+
+=item $p = HTML::TokeParser->new( \$document, %opt );
+
+The object constructor argument is either a file name, a file handle
+object, or the complete document to be parsed.  Extra options can be
+provided as key/value pairs and are processed as documented by the base
+classes.
+
+If the argument is a plain scalar, then it is taken as the name of a
+file to be opened and parsed.  If the file can't be opened for
+reading, then the constructor will return C<undef> and $! will tell
+you why it failed.
+
+If the argument is a reference to a plain scalar, then this scalar is
+taken to be the literal document to parse.  The value of this
+scalar should not be changed before all tokens have been extracted.
+
+Otherwise the argument is taken to be some object that the
+C<HTML::TokeParser> can read() from when it needs more data.  Typically
+it will be a filehandle of some kind.  The stream will be read() until
+EOF, but not closed.
+
+A newly constructed C<HTML::TokeParser> differ from its base classes
+by having the C<unbroken_text> attribute enabled by default. See
+L<HTML::Parser> for a description of this and other attributes that
+influence how the document is parsed. It is often a good idea to enable
+C<empty_element_tags> behaviour.
+
+Note that the parsing result will likely not be valid if raw undecoded
+UTF-8 is used as a source.  When parsing UTF-8 encoded files turn
+on UTF-8 decoding:
+
+   open(my $fh, "<:utf8", "index.html") || die "Can't open 'index.html': $!";
+   my $p = HTML::TokeParser->new( $fh );
+   # ...
+
+If a $filename is passed to the constructor the file will be opened in
+raw mode and the parsing result will only be valid if its content is
+Latin-1 or pure ASCII.
+
+If parsing from an UTF-8 encoded string buffer decode it first:
+
+   utf8::decode($document);
+   my $p = HTML::TokeParser->new( \$document );
+   # ...
+
+=item $p->get_token
+
+This method will return the next I<token> found in the HTML document,
+or C<undef> at the end of the document.  The token is returned as an
+array reference.  The first element of the array will be a string
+denoting the type of this token: "S" for start tag, "E" for end tag,
+"T" for text, "C" for comment, "D" for declaration, and "PI" for
+process instructions.  The rest of the token array depend on the type
+like this:
+
+  ["S",  $tag, $attr, $attrseq, $text]
+  ["E",  $tag, $text]
+  ["T",  $text, $is_data]
+  ["C",  $text]
+  ["D",  $text]
+  ["PI", $token0, $text]
+
+where $attr is a hash reference, $attrseq is an array reference and
+the rest are plain scalars.  The L<HTML::Parser/Argspec> explains the
+details.
+
+=item $p->unget_token( @tokens )
+
+If you find you have read too many tokens you can push them back,
+so that they are returned the next time $p->get_token is called.
+
+=item $p->get_tag
+
+=item $p->get_tag( @tags )
+
+This method returns the next start or end tag (skipping any other
+tokens), or C<undef> if there are no more tags in the document.  If
+one or more arguments are given, then we skip tokens until one of the
+specified tag types is found.  For example:
+
+   $p->get_tag("font", "/font");
+
+will find the next start or end tag for a font-element.
+
+The tag information is returned as an array reference in the same form
+as for $p->get_token above, but the type code (first element) is
+missing. A start tag will be returned like this:
+
+  [$tag, $attr, $attrseq, $text]
+
+The tagname of end tags are prefixed with "/", i.e. end tag is
+returned like this:
+
+  ["/$tag", $text]
+
+=item $p->get_text
+
+=item $p->get_text( @endtags )
+
+This method returns all text found at the current position. It will
+return a zero length string if the next token is not text. Any
+entities will be converted to their corresponding character.
+
+If one or more arguments are given, then we return all text occurring
+before the first of the specified tags found. For example:
+
+   $p->get_text("p", "br");
+
+will return the text up to either a paragraph of linebreak element.
+
+The text might span tags that should be I<textified>.  This is
+controlled by the $p->{textify} attribute, which is a hash that
+defines how certain tags can be treated as text.  If the name of a
+start tag matches a key in this hash then this tag is converted to
+text.  The hash value is used to specify which tag attribute to obtain
+the text from.  If this tag attribute is missing, then the upper case
+name of the tag enclosed in brackets is returned, e.g. "[IMG]".  The
+hash value can also be a subroutine reference.  In this case the
+routine is called with the start tag token content as its argument and
+the return value is treated as the text.
+
+The default $p->{textify} value is:
+
+  {img => "alt", applet => "alt"}
+
+This means that <IMG> and <APPLET> tags are treated as text, and that
+the text to substitute can be found in the ALT attribute.
+
+=item $p->get_trimmed_text
+
+=item $p->get_trimmed_text( @endtags )
+
+Same as $p->get_text above, but will collapse any sequences of white
+space to a single space character.  Leading and trailing white space is
+removed.
+
+=item $p->get_phrase
+
+This will return all text found at the current position ignoring any
+phrasal-level tags.  Text is extracted until the first non
+phrasal-level tag.  Textification of tags is the same as for
+get_text().  This method will collapse white space in the same way as
+get_trimmed_text() does.
+
+The definition of <i>phrasal-level tags</i> is obtained from the
+HTML::Tagset module.
+
+=back
+
+=head1 EXAMPLES
+
+This example extracts all links from a document.  It will print one
+line for each link, containing the URL and the textual description
+between the <A>...</A> tags:
+
+  use HTML::TokeParser;
+  $p = HTML::TokeParser->new(shift||"index.html");
+
+  while (my $token = $p->get_tag("a")) {
+      my $url = $token->[1]{href} || "-";
+      my $text = $p->get_trimmed_text("/a");
+      print "$url\t$text\n";
+  }
+
+This example extract the <TITLE> from the document:
+
+  use HTML::TokeParser;
+  $p = HTML::TokeParser->new(shift||"index.html");
+  if ($p->get_tag("title")) {
+      my $title = $p->get_trimmed_text;
+      print "Title: $title\n";
+  }
+
+=head1 SEE ALSO
+
+L<HTML::PullParser>, L<HTML::Parser>
+
+=head1 COPYRIGHT
+
+Copyright 1998-2005 Gisle Aas.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=cut
Index: /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple.pm	(revision 20131)
@@ -0,0 +1,627 @@
+package HTML::TokeParser::Simple;
+
+use strict;
+use HTML::TokeParser;
+use HTML::TokeParser::Simple::Token;
+use HTML::TokeParser::Simple::Token::Tag;
+use HTML::TokeParser::Simple::Token::Tag::Start;
+use HTML::TokeParser::Simple::Token::Tag::End;
+use HTML::TokeParser::Simple::Token::Text;
+use HTML::TokeParser::Simple::Token::Comment;
+use HTML::TokeParser::Simple::Token::Declaration;
+use HTML::TokeParser::Simple::Token::ProcessInstruction;
+
+use vars qw/ @ISA $VERSION $REVISION /;
+
+$REVISION = '$Id$';
+$VERSION  = '3.15';
+@ISA = qw/ HTML::TokeParser /;
+
+# constructors
+
+my %FACTORY_CLASSES = (
+    S   => 'HTML::TokeParser::Simple::Token::Tag::Start',
+    E   => 'HTML::TokeParser::Simple::Token::Tag::End',
+    T   => 'HTML::TokeParser::Simple::Token::Text',
+    C   => 'HTML::TokeParser::Simple::Token::Comment',
+    D   => 'HTML::TokeParser::Simple::Token::Declaration',
+    PI  => 'HTML::TokeParser::Simple::Token::ProcessInstruction',
+);
+
+sub _croak {
+    my ($proto, $message) = @_;
+    require Carp;
+    Carp::croak($message);
+}
+
+sub new {
+    my ($class, @args) = @_;
+    return 1 == @args
+        ? $class->SUPER::new(@args)
+        : $class->_init(@args);
+}
+
+sub _init {
+    my ($class, $source_type, $source) = @_;
+    my %sources = (
+        file   => sub { $source },
+        handle => sub { $source },
+        string => sub { \$source },
+        url    => sub {
+            eval "require LWP::Simple";
+            $class->_croak("Cannot load LWP::Simple: $@") if $@;
+            my $content = LWP::Simple::get($source);
+            $class->_croak("Could not fetch content from ($source)")
+                unless defined $content;
+            return \$content;
+        },
+    );
+    unless (exists $sources{$source_type}) {
+        $class->_croak("Unknown source type ($source_type)");
+    }
+    return $class->new($sources{$source_type}->());
+}
+
+sub get_token {
+    my $self = shift;
+    my @args = @_;
+    my $token = $self->SUPER::get_token( @args );
+    return unless defined $token;
+    if (my $factory_class = $FACTORY_CLASSES{$token->[0]}) {
+        return $factory_class->new($token);
+    }
+    else {
+        # this should never happen
+        $self->_croak("Cannot determine token class for token (@$token)");
+    }
+}
+
+sub get_tag {
+    my $self = shift;
+    my @args = @_;
+    my $token = $self->SUPER::get_tag( @args );
+    return unless defined $token;
+    return $token->[0] =~ /^\//
+        ?  HTML::TokeParser::Simple::Token::Tag::End->new($token)
+        :  HTML::TokeParser::Simple::Token::Tag::Start->new($token);
+}
+
+sub peek {
+    my ($self, $count) = @_;
+    $count  ||= 1;
+    
+    unless ($count =~ /^\d+$/) {
+        $self->_croak("Argument to peek() must be a positive integer, not ($count)");
+    }
+
+    my $items = 0;
+    my $html  = '';
+    my @tokens;
+    while ( $items++ < $count && defined ( my $token = $self->get_token ) ) {
+        $html .= $token->as_is;
+        push @tokens, $token;
+    }
+    $self->unget_token(@tokens);
+    return $html;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+HTML::TokeParser::Simple - Easy to use C<HTML::TokeParser> interface
+
+=head1 SYNOPSIS
+
+ use HTML::TokeParser::Simple;
+ my $p = HTML::TokeParser::Simple->new( $somefile );
+
+ while ( my $token = $p->get_token ) {
+     # This prints all text in an HTML doc (i.e., it strips the HTML)
+     next unless $token->is_text;
+     print $token->as_is;
+ }
+
+
+=head1 DESCRIPTION
+
+C<HTML::TokeParser> is an excellent module that's often used for parsing HTML.
+However, the tokens returned are not exactly intuitive to parse:
+
+ ["S",  $tag, $attr, $attrseq, $text]
+ ["E",  $tag, $text]
+ ["T",  $text, $is_data]
+ ["C",  $text]
+ ["D",  $text]
+ ["PI", $token0, $text]
+
+To simplify this, C<HTML::TokeParser::Simple> allows the user ask more
+intuitive (read: more self-documenting) questions about the tokens returned.
+
+You can also rebuild some tags on the fly.  Frequently, the attributes
+associated with start tags need to be altered, added to, or deleted.  This
+functionality is built in.
+
+Since this is a subclass of C<HTML::TokeParser>, all C<HTML::TokeParser>
+methods are available.  To truly appreciate the power of this module, please
+read the documentation for C<HTML::TokeParser> and C<HTML::Parser>.
+
+=head1 CONTRUCTORS
+
+=head2 C<new($source)>
+
+The constructor for C<HTML::TokeParser::Simple> can be used just like
+C<HTML::TokeParser>'s constructor:
+
+  my $parser = HTML::TokeParser::Simple->new($filename);
+  # or
+  my $parser = HTML::TokeParser::Simple->new($filehandle);
+  # or
+  my $parser = HTML::TokeParser::Simple->new(\$html_string);
+
+=head2 C<new($source_type, $source)>
+
+If you wish to be more explicit, there is a new style of
+constructor avaiable.
+
+  my $parser = HTML::TokeParser::Simple->new(file   => $filename);
+  # or
+  my $parser = HTML::TokeParser::Simple->new(handle => $filehandle);
+  # or
+  my $parser = HTML::TokeParser::Simple->new(string => $html_string);
+
+Note that you do not have to provide a reference for the string if using the
+string constructor.
+
+As a convenience, you can also attempt to fetch the HTML directly from a URL.
+
+  my $parser = HTML::TokeParser::Simple->new(url => 'http://some.url');
+
+This method relies on C<LWP::Simple>.  If this module is not found or the page
+cannot be fetched, the constructor will C<croak()>.
+
+=head1 PARSER METHODS
+
+=head2 get_token
+
+This method will return the next token that C<HTML::TokeParser::get_token()>
+method would return.  However, it will be blessed into a class appropriate
+which represents the token type.
+
+=head2 get_tag
+
+This method will return the next token that C<HTML::TokeParser::get_tag()>
+method would return.  However, it will be blessed into either the
+L<HTML::TokeParser::Simple::Token::Tag::Start> or
+L<HTML::TokeParser::Simple::Token::Tag::End> class.
+
+=head2 peek
+
+As of version C<3.14>, you can now C<peek()> at the upcomings tokens without
+affecting the state of the parser.  By default, C<peek()> will return the text
+of the next token, but specifying an integer C<$count> will return the text of
+the next C<$count> tokens.
+
+This is useful when you're trying to debug where you are in a document.
+
+ warn $parser->peek(3); # show the next 3 tokens
+
+=head1 ACCESSORS
+
+The following methods may be called on the token object which is returned,
+not on the parser object.
+
+=head2 Boolean Accessors
+
+These accessors return true or false.
+
+=over 4
+
+=item * C<is_tag([$tag])>
+
+Use this to determine if you have any tag.  An optional "tag type" may be
+passed.  This will allow you to match if it's a I<particular> tag.  The
+supplied tag is case-insensitive.
+
+ if ( $token->is_tag ) { ... }
+
+Optionally, you may pass a regular expression as an argument.
+
+=item * C<is_start_tag([$tag])>
+
+Use this to determine if you have a start tag.  An optional "tag type" may be
+passed.  This will allow you to match if it's a I<particular> start tag.  The
+supplied tag is case-insensitive.
+
+ if ( $token->is_start_tag ) { ... }
+ if ( $token->is_start_tag( 'font' ) ) { ... }
+
+Optionally, you may pass a regular expression as an argument.  To match all
+header (h1, h2, ... h6) tags:
+
+ if ( $token->is_start_tag( qr/^h[123456]$/ ) ) { ... }
+
+=item * C<is_end_tag([$tag])>
+
+Use this to determine if you have an end tag.  An optional "tag type" may be
+passed.  This will allow you to match if it's a I<particular> end tag.  The
+supplied tag is case-insensitive.
+
+When testing for an end tag, the forward slash on the tag is optional.
+
+ while ( $token = $p->get_token ) {
+   if ( $token->is_end_tag( 'form' ) ) { ... }
+ }
+
+Or:
+
+ while ( $token = $p->get_token ) {
+   if ( $token->is_end_tag( '/form' ) ) { ... }
+ }
+
+Optionally, you may pass a regular expression as an argument.
+
+=item * C<is_text()>
+
+Use this to determine if you have text.  Note that this is I<not> to be
+confused with the C<return_text> (I<deprecated>) method described below!
+C<is_text> will identify text that the user typically sees display in the Web
+browser.
+
+=item * C<is_comment()>
+
+Are you still reading this?  Nobody reads POD.  Don't you know you're supposed
+to go to CLPM, ask a question that's answered in the POD and get flamed?  It's
+a rite of passage.
+
+Really.
+
+C<is_comment> is used to identify comments.  See the HTML::Parser documentation
+for more information about comments.  There's more than you might think.
+
+=item * C<is_declaration()>
+
+This will match the DTD at the top of your HTML. (You I<do> use DTD's, don't
+you?)
+
+=item * C<is_process_instruction()>
+
+Process Instructions are from XML.  This is very handy if you need to parse out
+PHP and similar things with a parser.
+
+Currently, there appear to be some problems with process instructions.  You can
+override C<HTML::TokeParser::Simple::Token::ProcessInstruction> if you need to.
+
+=item * C<is_pi()>
+
+This is a shorthand for C<is_process_instruction()>.
+
+=back
+
+=head2 Data Accessors
+
+Some of these were originally C<return_> methods, but that name was not only
+unwieldy, but also went against reasonable conventions.  The C<get_> methods
+listed below still have C<return_> methods available for backwards
+compatibility reasons, but they merely call their C<get_> counterpart.  For
+example, calling C<return_tag()> actually calls C<get_tag()> internally.
+
+=over 4
+
+=item * C<get_tag()>
+
+Do you have a start tag or end tag?  This will return the type (lower case).
+Note that this is I<not> the same as the C<get_tag()> method on the actual
+parser object.
+
+=item * C<get_attr([$attribute])>
+
+If you have a start tag, this will return a hash ref with the attribute names
+as keys and the values as the values.
+
+If you pass in an attribute name, it will return the value for just that
+attribute.  
+
+Returns false if the token is not a start tag.
+
+=item * C<get_attrseq()>
+
+For a start tag, this is an array reference with the sequence of the
+attributes, if any.
+
+Returns false if the token is not a start tag.
+
+=item * C<return_text()>
+
+This method has been heavily deprecated (for a couple of years) in favor of
+C<as_is>.  Programmers were getting confused over the difference between
+C<is_text>, C<return_text>, and some parser methods such as
+C<HTML::TokeParser::get_text> and friends.
+
+Using this method still succeeds, but will now carp and B<will be removed>
+in the next major release of this module.
+
+=item * C<as_is()>
+
+This is the exact text of whatever the token is representing.
+
+=item * C<get_token0()>
+
+For processing instructions, this will return the token found immediately after
+the opening tag.  Example:  For <?php, "php" will be the start of the returned
+string.
+
+Note that process instruction handling appears to be incomplete in
+C<HTML::TokeParser>.
+
+Returns false if the token is not a process instruction.
+
+=back
+
+=head1 MUTATORS
+
+The C<delete_attr()> and C<set_attr()> methods allow the programmer to rewrite
+start tag attributes on the fly.  It should be noted that bad HTML will be
+"corrected" by this.  Specifically, the new tag will have all attributes
+lower-cased with the values properly quoted.
+
+Self-closing tags (e.g. E<lt>hr /E<gt>) are also handled correctly.  Some older
+browsers require a space prior to the final slash in a self-closed tag.  If
+such a space is detected in the original HTML, it will be preserved.
+
+Calling a mutator on an token type that does not support that property is a
+no-op.  For example:
+
+ if ($token->is_comment) {
+    $token->set_attr(foo => 'bar'); # does nothing
+ }
+
+=over 4
+
+=item * C<delete_attr($name)>
+
+This method attempts to delete the attribute specified.  It will silently fail
+if called on anything other than a start tag.  The argument is
+case-insensitive, but must otherwise be an exact match of the attribute you are
+attempting to delete.  If the attribute is not found, the method will return
+without changing the tag.
+
+ # <body bgcolor="#FFFFFF">
+ $token->delete_attr('bgcolor');
+ print $token->as_is;
+ # <body>
+ 
+After this method is called, if successful, the C<as_is()>, C<get_attr()>
+and C<get_attrseq()> methods will all return updated results.
+
+=item * C<set_attr($name,$value)>
+
+This method will set the value of an attribute.  If the attribute is not found,
+then C<get_attrseq()> will have the new attribute listed at the end.
+
+ # <p>
+ $token->set_attr(class => 'some_class');
+ print $token->as_is;
+ # <p class="some_class">
+
+ # <body bgcolor="#FFFFFF">
+ $token->set_attr('bgcolor','red');
+ print $token->as_is;
+ # <body bgcolor="red">
+
+After this method is called, if successful, the C<as_is()>, C<get_attr()>
+and C<get_attrseq()> methods will all return updated results.
+
+=item * C<set_attr($hashref)>
+
+Under the premise that C<set_> methods should accept what their corresponding
+C<get_> methods emit, the following works:
+
+  $tag->set_attr($tag->get_attr);
+
+Theoretically that's a no-op and for purposes of rendering HTML, it should be.
+However, internally this calls C<$tag-E<gt>rewrite_tag>, so see that method to
+understand how this may affect you.
+
+Of course, this is useless if you want to actually change the attributes, so you
+can do this:
+
+  my $attrs = {
+    class  => 'headline',
+    valign => 'top'
+  };
+  $token->set_attr($attrs) 
+    if $token->is_start_tag('td') &&  $token->get_attr('class') eq 'stories';
+
+=item * C<rewrite_tag()>
+
+This method rewrites the tag.  The tag name and the name of all attributes will
+be lower-cased.  Values that are not quoted with double quotes will be.  This
+may be called on both start or end tags.  Note that both C<set_attr()> and
+C<delete_attr()> call this method prior to returning.
+
+If called on a token that is not a tag, it simply returns.  Regardless of how
+it is called, it returns the token.
+
+ # <body alink=#0000ff BGCOLOR=#ffffff class='none'>
+ $token->rewrite_tag;
+ print $token->as_is;
+ # <body alink="#0000ff" bgcolor="#ffffff" class="none">
+
+A quick cleanup of sloppy HTML is now the following:
+
+ my $parser = HTML::TokeParser::Simple->new( string => $ugly_html );
+ while (my $token = $parser->get_token) {
+     $token->rewrite_tag;
+     print $token->as_is;
+ }
+
+=back
+
+=head1 PARSER VERSUS TOKENS 
+
+The parser returns tokens that are blessed into appropriate classes.  Some
+people get confused and try to call parser methods on tokens and token methods
+on the parser.  To prevent this, C<HTML::TokeParser::Simple> versions 1.4 and
+above now bless all tokens into appropriate token classes.  Please keep this in
+mind while using this module (and many thanks to PodMaster
+L<http://www.perlmonks.org/index.pl?node_id=107642> for pointing out this issue
+to me.)
+
+=head1 EXAMPLES
+
+=head2 Finding comments
+
+For some strange reason, your Pointy-Haired Boss (PHB) is convinced that the
+graphics department is making fun of him by embedding rude things about him in
+HTML comments.  You need to get all HTML comments from the HTML.
+
+ use strict;
+ use HTML::TokeParser::Simple;
+
+ my @html_docs = glob( "*.html" );
+
+ open PHB, "> phbreport.txt" or die "Cannot open phbreport for writing: $!";
+
+ foreach my $doc ( @html_docs ) {
+     print "Processing $doc\n";
+     my $p = HTML::TokeParser::Simple->new( file => $doc );
+     while ( my $token = $p->get_token ) {
+         next unless $token->is_comment;
+         print PHB $token->as_is, "\n";
+     }
+ }
+
+ close PHB;
+
+=head2 Stripping Comments
+
+Uh oh.  Turns out that your PHB was right for a change.  Many of the comments
+in the HTML weren't very polite.  Since your entire graphics department was
+just fired, it falls on you need to strip those comments from the HTML.
+
+ use strict;
+ use HTML::TokeParser::Simple;
+
+ my $new_folder = 'no_comment/';
+ my @html_docs  = glob( "*.html" );
+
+ foreach my $doc ( @html_docs ) {
+     print "Processing $doc\n";
+     my $new_file = "$new_folder$doc";
+
+     open PHB, "> $new_file" or die "Cannot open $new_file for writing: $!";
+
+     my $p = HTML::TokeParser::Simple->new( $file => doc );
+     while ( my $token = $p->get_token ) {
+         next if $token->is_comment;
+         print PHB $token->as_is;
+     }
+     close PHB;
+ }
+
+=head2 Changing form tags
+
+Your company was foo.com and now is bar.com.  Unfortunately, whoever wrote your
+HTML decided to hardcode "http://www.foo.com/" into the C<action> attribute of
+the form tags.  You need to change it to "http://www.bar.com/".
+
+ use strict;
+ use HTML::TokeParser::Simple;
+
+ my $new_folder = 'new_html/';
+ my @html_docs  = glob( "*.html" );
+
+ foreach my $doc ( @html_docs ) {
+     print "Processing $doc\n";
+     my $new_file = "$new_folder$doc";
+
+     open FILE, "> $new_file" or die "Cannot open $new_file for writing: $!";
+
+     my $p = HTML::TokeParser::Simple->new( file => $doc );
+     while ( my $token = $p->get_token ) {
+         if ( $token->is_start_tag('form') ) {
+             my $action = $token->get_attr(action);
+             $action =~ s/www\.foo\.com/www.bar.com/;
+             $token->set_attr('action', $action);
+         }
+         print FILE $token->as_is;
+     }
+     close FILE;
+ }
+
+=head1 CAVEATS
+
+For compatability reasons with C<HTML::TokeParser>, methods that return
+references are violating encapsulation and altering the references directly
+B<will> alter the state of the object.  Subsequent calls to C<rewrite_tag()>
+can thus have unexpected results.  Do not alter these references directly
+unless you are following behavior described in these docs.  In the future,
+certain methods such as C<get_attr>, C<get_attrseq> and others may return a
+copy of the reference rather than the original reference.  This behavior has
+not yet been changed in order to maintain compatability with previous versions
+of this module.  At the present time, your author is not aware of anyone taking
+advantage of this "feature," but it's better to be safe than sorry.
+
+Use of C<$HTML::Parser::VERSION> which is less than 3.25 may result in
+incorrect behavior as older versions do not always handle XHTML correctly.  It
+is the programmer's responsibility to verify that the behavior of this code
+matches the programmer's needs.
+
+Note that C<HTML::Parser> processes text in 512 byte chunks.  This sometimes
+will cause strange behavior and cause text to be broken into more than one
+token.  You can suppress this behavior with the following command:
+
+ $p->unbroken_text( [$bool] );
+
+See the C<HTML::Parser> documentation and
+http://www.perlmonks.org/index.pl?node_id=230667 for more information.
+
+=head1 BUGS
+
+There are no known bugs, but that's no guarantee.
+
+Address bug reports and comments to: E<lt>eop_divo_sitruc@yahoo.comE<gt>.  When
+sending bug reports, please provide the version of C<HTML::Parser>,
+C<HTML::TokeParser>, C<HTML::TokeParser::Simple>, the version of Perl, and the
+version of the operating system you are using.
+
+Reverse the name to email the author.
+
+=head1 SUBCLASSING
+
+You may wish to change the behavior of this module.  You probably do not want
+to subclass C<HTML::TokeParser::Simple>.  Instead, you'll want to subclass one
+of the token classes.  C<HTML::TokeParser::Simple::Token> is the base class for
+all tokens.  Global behavioral changes should go there.  Otherwise, see the
+appropriate token class for the behavior you wish to alter.
+
+=head1 SEE ALSO
+
+L<HTML::TokeParser::Simple::Token>
+
+L<HTML::TokeParser::Simple::Token::Tag>
+
+L<HTML::TokeParser::Simple::Token::Text>
+
+L<HTML::TokeParser::Simple::Token::Comment>
+
+L<HTML::TokeParser::Simple::Token::Declaration>
+
+L<HTML::TokeParser::Simple::Token::ProcessInstruction>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2004 by Curtis "Ovid" Poe.  All rights reserved.  This program is
+free software; you may redistribute it and/or modify it under the same terms as
+Perl itself
+
+=head1 AUTHOR
+
+Curtis "Ovid" Poe E<lt>eop_divo_sitruc@yahoo.comE<gt>
+
+Reverse the name to email the author.
+
+=cut
Index: /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token.pm	(revision 20131)
@@ -0,0 +1,133 @@
+package HTML::TokeParser::Simple::Token;
+
+use strict;
+
+use vars qw/ $VERSION $REVISION /;
+$REVISION = '$Id$';
+$VERSION  = '3.0';
+
+sub new {
+    my ($class, $token) = @_;
+    $class->_croak("This class should not be instantiated") if __PACKAGE__ eq $class;
+    return bless $token, $class;
+}
+
+sub _croak {
+    my ($proto, $message) = @_;
+    require Carp;
+    Carp::croak($message);
+}
+
+sub _carp {
+    my ($proto, $message) = @_;
+    require Carp;
+    Carp::carp($message);
+}
+
+sub is_tag         {}
+sub is_start_tag   {}
+sub is_end_tag     {}
+sub is_text        {}
+sub is_comment     {}
+sub is_declaration {}
+sub is_pi          {}
+sub is_process_instruction {}
+
+sub rewrite_tag    { shift }
+sub delete_attr    {}
+sub set_attr       {}
+sub get_tag        {}
+sub return_tag     {}  # deprecated
+sub get_attr       {}
+sub return_attr    {}  # deprecated
+sub get_attrseq    {}
+sub return_attrseq {}  # deprecated
+sub get_token0     {}
+sub return_token0  {}  # deprecated
+
+# get_foo methods
+
+sub return_text {
+    my ($self) = @_;
+    $self->_carp('return_text() is deprecated.  Use as_is() instead');
+    goto &as_is;
+}
+
+sub as_is { return shift->[-1] }
+
+1;
+
+__END__
+
+=head1 NAME
+
+HTML::TokeParser::Simple::Token - Base class for C<HTML::TokeParser::Simple>
+tokens.
+
+=head1 SYNOPSIS
+
+ use HTML::TokeParser::Simple;
+ my $p = HTML::TokeParser::Simple->new( $somefile );
+
+ while ( my $token = $p->get_token ) {
+     # This prints all text in an HTML doc (i.e., it strips the HTML)
+     next unless $token->is_text;
+     print $token->as_is;
+ }
+
+=head1 DESCRIPTION
+
+This is the base class for all returned tokens.  It should never be
+instantiated directly.  In fact, it will C<croak()> if it is.
+
+=head1 METHODS
+
+The following list of methods are provided by this class.  Most of these are
+stub methods which must be overridden in a subclass.  See 
+L<HTML::TokeParser::Simple> for descriptions of these methods.
+
+=over 4
+
+=item * as_is
+
+=item * delete_attr
+
+=item * get_attr
+
+=item * get_attrseq
+
+=item * get_tag
+
+=item * get_token0
+
+=item * is_comment
+
+=item * is_declaration
+
+=item * is_end_tag
+
+=item * is_pi
+
+=item * is_process_instruction
+
+=item * is_start_tag
+
+=item * is_tag
+
+=item * is_text
+
+=item * return_attr
+
+=item * return_attrseq
+
+=item * return_tag
+
+=item * return_text
+
+=item * return_token0
+
+=item * rewrite_tag
+
+=item * set_attr
+
+=back
Index: /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Comment.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Comment.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Comment.pm	(revision 20131)
@@ -0,0 +1,44 @@
+package HTML::TokeParser::Simple::Token::Comment;
+
+use strict;
+
+use vars qw/ $VERSION $REVISION /;
+$REVISION = '$Id$';
+$VERSION  = '1.0';
+use base 'HTML::TokeParser::Simple::Token';
+
+sub is_comment { 1 }
+
+1;
+
+__END__
+
+=head1 NAME
+
+HTML::TokeParser::Simple::Token::Comment - Token.pm comment class.
+
+=head1 SYNOPSIS
+
+ use HTML::TokeParser::Simple;
+ my $p = HTML::TokeParser::Simple->new( $somefile );
+
+ while ( my $token = $p->get_token ) {
+     # This prints all text in an HTML doc (i.e., it strips the HTML)
+     next unless $token->is_text;
+     print $token->as_is;
+ }
+
+=head1 DESCRIPTION
+
+This is the class for comment tokens.
+
+See L<HTML::Parser> for detailed information about comments.
+
+=head1 OVERRIDDEN METHODS
+
+=head2 is_comment
+
+C<is_comment()> will return true if the token is the DTD at the top of the
+HTML.
+
+=cut
Index: /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Declaration.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Declaration.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Declaration.pm	(revision 20131)
@@ -0,0 +1,42 @@
+package HTML::TokeParser::Simple::Token::Declaration;
+
+use strict;
+
+use vars qw/ $VERSION $REVISION /;
+$REVISION = '$Id$';
+$VERSION  = '1.0';
+use base 'HTML::TokeParser::Simple::Token';
+
+sub is_declaration { 1 }
+
+1;
+
+__END__
+
+=head1 NAME
+
+HTML::TokeParser::Simple::Token::Declaration - Token.pm declaration class.
+
+=head1 SYNOPSIS
+
+ use HTML::TokeParser::Simple;
+ my $p = HTML::TokeParser::Simple->new( $somefile );
+
+ while ( my $token = $p->get_token ) {
+     # This prints all text in an HTML doc (i.e., it strips the HTML)
+     next unless $token->is_text;
+     print $token->as_is;
+ }
+
+=head1 DESCRIPTION
+
+This is the declaration class for tokens. 
+
+=head1 OVERRIDDEN METHODS
+
+=head2 is_declaration
+
+C<is_declaration()> will return true if the token is the DTD at the top of the
+HTML.
+
+=cut
Index: /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/ProcessInstruction.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/ProcessInstruction.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/ProcessInstruction.pm	(revision 20131)
@@ -0,0 +1,63 @@
+package HTML::TokeParser::Simple::Token::ProcessInstruction;
+
+use strict;
+
+use vars qw/ $VERSION $REVISION /;
+$REVISION = '$Id$';
+$VERSION  = '2.0';
+use base 'HTML::TokeParser::Simple::Token';
+
+sub return_token0 { goto &get_token0 } # deprecated
+
+sub get_token0 {
+    return shift->[1];
+}
+
+sub is_pi { 1 }
+
+sub is_process_instruction { 1 }
+
+1;
+
+__END__
+
+=head1 NAME
+
+HTML::TokeParser::Simple::Token::ProcessInstruction - Token.pm process instruction class.
+
+=head1 SYNOPSIS
+
+ use HTML::TokeParser::Simple;
+ my $p = HTML::TokeParser::Simple->new( $somefile );
+
+ while ( my $token = $p->get_token ) {
+     # This prints all text in an HTML doc (i.e., it strips the HTML)
+     next unless $token->is_text;
+     print $token->as_is;
+ }
+
+=head1 DESCRIPTION
+
+Process Instructions are from XML.  This is very handy if you need to parse out
+PHP and similar things with a parser.
+
+Currently, there appear to be some problems with process instructions.  You can
+override this class if you need finer grained handling of process instructions.
+
+C<is_pi()> and C<is_process_instruction()> both return true.
+
+=head1 OVERRIDDEN METHODS
+
+=over 4
+
+=item * get_token0
+
+=item * is_pi
+
+=item * is_process_instruction
+
+=item * return_token0
+
+=back
+
+=cut
Index: /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Tag.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Tag.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Tag.pm	(revision 20131)
@@ -0,0 +1,84 @@
+package HTML::TokeParser::Simple::Token::Tag;
+
+use strict;
+
+use vars qw/ $VERSION $REVISION /;
+$REVISION = '$Id$';
+$VERSION  = '1.2';
+use base 'HTML::TokeParser::Simple::Token';
+
+my %INSTANCE;
+
+sub new {
+    my ($class, $object) = @_;
+    $class->_croak("This is a base class that should not be instantiated") 
+        if __PACKAGE__ eq $class;
+    my $self = bless $object, $class;
+    $self->_init;
+}
+
+sub _get_attrseq { return [] }
+
+sub _get_attr { return {} }
+
+sub _set_text   { 
+    my $self = shift; 
+    $self->[-1] = shift;
+    return $self;
+}
+
+# attribute munging methods
+# get_foo methods
+
+sub return_text {
+    carp('return_text() is deprecated.  Use as_is() instead');
+    goto &as_is;
+}
+
+sub as_is {
+    return shift->_get_text;
+}
+
+sub get_tag {
+    return shift->_get_tag;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+HTML::TokeParser::Simple::Token::Tag - Token.pm tag class.
+
+=head1 SYNOPSIS
+
+ use HTML::TokeParser::Simple;
+ my $p = HTML::TokeParser::Simple->new( $somefile );
+
+ while ( my $token = $p->get_token ) {
+     # This prints all text in an HTML doc (i.e., it strips the HTML)
+     next unless $token->is_text;
+     print $token->as_is;
+ }
+
+=head1 DESCRIPTION
+
+This is the base class for start and end tokens.  It should not be
+instantiated.  See C<HTML::TokeParser::Simple::Token::Tag::Start> and
+C<HTML::TokeParser::Simple::Token::Tag::End> for details.
+
+=head1 OVERRIDDEN METHODS
+
+The following list of methods are provided by this class.  See
+L<HTML::TokeParser::Simple> for descriptions of these methods.
+
+=over 4
+
+=item * as_is
+
+=item * get_tag
+
+=item * return_text
+
+=back
Index: /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Tag/End.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Tag/End.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Tag/End.pm	(revision 20131)
@@ -0,0 +1,135 @@
+package HTML::TokeParser::Simple::Token::Tag::End;
+
+use strict;
+
+use vars qw/ $VERSION $REVISION /;
+$REVISION = '$Id$';
+$VERSION  = '1.0';
+use base 'HTML::TokeParser::Simple::Token::Tag';
+
+my %TOKEN = (
+    tag   => 1,
+    text  => 2
+);
+
+# in order to maintain the 'drop-in replacement' ability with HTML::TokeParser,
+# we cannot alter the array refs.  Thus we must store instance data here.  Ugh.
+
+my %INSTANCE;
+
+sub _init {
+    my $self = shift;
+    if ('E' eq $self->[0]) {
+        $INSTANCE{$self}{offset} = 0;
+        $INSTANCE{$self}{tag}    = $self->[1];
+    }
+    else {
+        $INSTANCE{$self}{offset} = -1;
+        my $tag = $self->[0];
+        $tag =~ s/^\///;
+        $INSTANCE{$self}{tag}    = $tag;
+    }
+    return $self;
+}
+
+sub _get_offset { return $INSTANCE{+shift}{offset} }
+sub _get_text   { return shift->[-1] }
+
+sub _get_tag {
+    my $self  = shift;
+    return $INSTANCE{$self}{tag};
+}
+
+sub DESTROY     { delete $INSTANCE{+shift} }
+
+sub rewrite_tag {
+    my $self    = shift;
+    # capture the final slash if the tag is self-closing
+    my ($self_closing) = $self->_get_text =~ m{(\s?/)>$};
+    $self_closing ||= '';
+    
+    my $first = $self->is_end_tag ? '/' : '';
+    my $tag = sprintf '<%s%s%s>', $first, $self->get_tag, $self_closing;
+    $self->_set_text($tag);
+    return $self;
+}
+
+sub return_text {
+    require Carp;
+    Carp::carp('return_text() is deprecated.  Use as_is() instead');
+    goto &as_is;
+}
+
+sub as_is {
+    return shift->_get_text;
+}
+
+sub get_tag {
+    return shift->_get_tag;
+}
+
+# is_foo methods
+
+sub is_tag {
+    my $self = shift;
+    return $self->is_end_tag( @_ );
+}
+
+sub is_end_tag {
+    my ($self, $tag) = @_;
+    return $tag ? $self->_match_tag($tag) : 1;
+}
+
+sub _match_tag {
+    my ($self, $tag) = @_;
+    if ('Regexp' eq ref $tag) {
+        return $self->_get_tag =~ $tag;
+    }
+    else {
+        $tag = lc $tag;
+        $tag =~ s/^\///;
+        return $self->_get_tag eq $tag;
+    }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+HTML::TokeParser::Simple::Token::Tag::End - Token.pm "end tag" class.
+
+=head1 SYNOPSIS
+
+ use HTML::TokeParser::Simple;
+ my $p = HTML::TokeParser::Simple->new( $somefile );
+
+ while ( my $token = $p->get_token ) {
+     # This prints all text in an HTML doc (i.e., it strips the HTML)
+     next unless $token->is_text;
+     print $token->as_is;
+ }
+
+=head1 DESCRIPTION
+
+This class does most of the heavy lifting for C<HTML::TokeParser::Simple>.  See
+the C<HTML::TokeParser::Simple> docs for details.
+
+=head1 OVERRIDDEN METHODS
+
+=over 4
+
+=item * as_is
+
+=item * get_tag
+
+=item * is_end_tag
+
+=item * is_tag
+
+=item * return_text
+
+=item * rewrite_tag
+
+=cut
Index: /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Tag/Start.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Tag/Start.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Tag/Start.pm	(revision 20131)
@@ -0,0 +1,229 @@
+package HTML::TokeParser::Simple::Token::Tag::Start;
+
+use strict;
+
+use vars qw/ $VERSION $REVISION /;
+$REVISION = '$Id$';
+$VERSION  = '1.0';
+use base 'HTML::TokeParser::Simple::Token::Tag';
+
+use HTML::Entities qw/encode_entities/;
+
+my %TOKEN = (
+    tag     => 1,
+    attr    => 2,
+    attrseq => 3,
+    text    => 4
+);
+
+my %INSTANCE;
+
+sub _init {
+    my $self = shift;
+    if ('S' eq $self->[0]) {
+        $INSTANCE{$self}{offset} = 0;
+        $INSTANCE{$self}{tag}    = $self->[1];
+    }
+    else {
+        $INSTANCE{$self}{offset} = -1;
+        my $tag = $self->[0];
+        $tag =~ s/^\///;
+        $INSTANCE{$self}{tag}    = $tag;
+    }
+    return $self;
+}
+
+sub _get_offset { return $INSTANCE{+shift}{offset} }
+sub _get_text   { return shift->[-1] }
+
+sub _get_tag {
+    my $self  = shift;
+    return $INSTANCE{$self}{tag};
+}
+
+sub _get_attrseq {
+    my $self  = shift;
+    my $index = $TOKEN{attrseq} + $self->_get_offset;
+    return $self->[$index];
+}
+
+sub _get_attr {
+    my $self  = shift;
+    my $index = $TOKEN{attr} + $self->_get_offset;
+    return $self->[$index];
+}
+
+sub DESTROY     { delete $INSTANCE{+shift} }
+
+sub return_attr    { goto &get_attr }
+sub return_attrseq { goto &get_attrseq }
+sub return_tag     { goto &get_tag }
+
+# attribute munging methods
+
+sub set_attr {
+    my ($self, $name, $value) = @_;
+    return 'HASH' eq ref $name
+        ? $self->_set_attr_from_hashref($name)
+        : $self->_set_attr_from_string($name, $value);
+}
+
+sub _set_attr_from_string {
+    my ($self, $name, $value) = @_;
+    $name = lc $name;
+    my $attr    = $self->get_attr;
+    my $attrseq = $self->get_attrseq;
+    unless (exists $attr->{$name}) {
+        push @$attrseq => $name;
+    }
+    $attr->{$name} = $value;
+    $self->rewrite_tag;
+}
+
+sub _set_attr_from_hashref {
+    my ($self, $attr_hash) = @_;
+    while (my ($attr, $value) = each %$attr_hash) {
+        $self->set_attr($attr, $value);
+    }
+    return $self;
+}
+
+sub rewrite_tag {
+    my $self    = shift;
+    my $attr    = $self->get_attr;
+    my $attrseq = $self->get_attrseq;
+
+    # capture the final slash if the tag is self-closing
+    my ($self_closing) = $self->_get_text =~ m{(\s?/)>$};
+    $self_closing ||= '';
+    
+    my $tag = '';
+    foreach ( @$attrseq ) {
+        next if $_ eq '/'; # is this a bug in HTML::TokeParser?
+        $tag .= sprintf qq{ %s="%s"} => $_, encode_entities($attr->{$_});
+    }
+    my $first = $self->is_end_tag ? '/' : '';
+    $tag = sprintf '<%s%s%s%s>', $first, $self->get_tag, $tag, $self_closing;
+    $self->_set_text($tag);
+    return $self;
+}
+
+sub delete_attr {
+    my ($self,$name) = @_;
+    $name = lc $name;
+    my $attr = $self->get_attr;
+    return unless exists $attr->{$name};
+    delete $attr->{$name};
+    my $attrseq = $self->get_attrseq;
+    @$attrseq = grep { $_ ne $name } @$attrseq;
+    $self->rewrite_tag;
+}
+
+# get_foo methods
+
+sub return_text {
+    require Carp;
+    Carp::carp('return_text() is deprecated.  Use as_is() instead');
+    goto &as_is;
+}
+
+sub as_is {
+    return shift->_get_text;
+}
+
+sub get_tag {
+    return shift->_get_tag;
+}
+
+sub get_token0 {
+    return '';
+}
+
+sub get_attr {
+    my $self = shift;
+    my $attributes = $self->_get_attr;
+    return @_ ? $attributes->{lc shift} : $attributes;
+}
+
+sub get_attrseq {
+    my $self = shift;
+    $self->_get_attrseq;
+}
+
+# is_foo methods
+
+sub is_tag {
+    my $self = shift;
+    return $self->is_start_tag( @_ );
+}
+
+sub is_start_tag {
+    my ($self, $tag) = @_;
+    return $tag ? $self->_match_tag($tag) : 1;
+}
+
+sub _match_tag {
+    my ($self, $tag) = @_;
+    return 'Regexp' eq ref $tag
+        ? $self->_get_tag =~ $tag
+        : $self->_get_tag eq lc $tag;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+HTML::TokeParser::Simple::Token::Tag::Start - Token.pm "start tag" class.
+
+=head1 SYNOPSIS
+
+ use HTML::TokeParser::Simple;
+ my $p = HTML::TokeParser::Simple->new( $somefile );
+
+ while ( my $token = $p->get_token ) {
+     # This prints all text in an HTML doc (i.e., it strips the HTML)
+     next unless $token->is_text;
+     print $token->as_is;
+ }
+
+=head1 DESCRIPTION
+
+This class does most of the heavy lifting for C<HTML::TokeParser::Simple>.  See
+the C<HTML::TokeParser::Simple> docs for details.
+
+=head1 OVERRIDDEN METHODS
+
+=over 4
+
+=item * as_is
+
+=item * delete_attr
+
+=item * get_attr
+
+=item * get_attrseq
+
+=item * get_tag
+
+=item * get_token0
+
+=item * is_start_tag
+
+=item * is_tag
+
+=item * return_attr
+
+=item * return_attrseq
+
+=item * return_tag
+
+=item * return_text
+
+=item * rewrite_tag
+
+=item * set_attr
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Text.pm
===================================================================
--- /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Text.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/HTML/TokeParser/Simple/Token/Text.pm	(revision 20131)
@@ -0,0 +1,50 @@
+package HTML::TokeParser::Simple::Token::Text;
+
+use strict;
+
+use vars qw/ $VERSION $REVISION /;
+$REVISION = '$Id$';
+$VERSION  = '1.0';
+use base 'HTML::TokeParser::Simple::Token';
+
+sub as_is {
+    return shift->[1];
+}
+
+sub is_text { 1 }
+
+1;
+
+__END__
+
+=head1 NAME
+
+HTML::TokeParser::Simple::Token::Text - Token.pm text class.
+
+=head1 SYNOPSIS
+
+ use HTML::TokeParser::Simple;
+ my $p = HTML::TokeParser::Simple->new( $somefile );
+
+ while ( my $token = $p->get_token ) {
+     # This prints all text in an HTML doc (i.e., it strips the HTML)
+     next unless $token->is_text;
+     print $token->as_is;
+ }
+
+=head1 DESCRIPTION
+
+This class represents "text" tokens.  See the C<HTML::TokeParser::Simple>
+documentation for details.
+
+=head1 OVERRIDDEN METHODS
+
+=over 4
+
+=item * as_is
+
+=item * is_text
+
+=back
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool.pm	(revision 20131)
@@ -0,0 +1,4204 @@
+#------------------------------------------------------------------------------
+# File:         ExifTool.pm
+#
+# Description:  Read and write meta information
+#
+# URL:          http://owl.phy.queensu.ca/~phil/exiftool/
+#
+# Revisions:    Nov. 12/03 - P. Harvey Created
+#               (See html/history.html for revision history)
+#
+# Legal:        Copyright (c) 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+#               This library is free software; you can redistribute it and/or
+#               modify it under the same terms as Perl itself.
+#------------------------------------------------------------------------------
+
+package Image::ExifTool;
+
+use strict;
+require 5.004;  # require 5.004 for UNIVERSAL::isa (otherwise 5.002 would do)
+require Exporter;
+use File::RandomAccess;
+    
+use vars qw($VERSION $RELEASE @ISA %EXPORT_TAGS $AUTOLOAD @fileTypes %allTables
+            @tableOrder $exifAPP1hdr $xmpAPP1hdr $psAPP13hdr $psAPP13old
+            @loadAllTables %UserDefined $evalWarning);
+
+$VERSION = '7.00';
+$RELEASE = '';
+@ISA = qw(Exporter);
+%EXPORT_TAGS = (
+    # all public non-object-oriented functions
+    Public => [qw(
+        ImageInfo GetTagName GetShortcuts GetAllTags GetWritableTags
+        GetAllGroups GetDeleteGroups GetFileType CanWrite CanCreate
+    )],
+    DataAccess => [qw(
+        ReadValue GetByteOrder SetByteOrder ToggleByteOrder Get8u Get8s Get16u
+        Get16s Get32u Get32s GetFloat GetDouble GetFixed32s Write WriteValue
+        Tell Set8u Set8s Set16u Set32u
+    )],
+    Utils => [qw(
+        GetTagTable TagTableKeys GetTagInfoList GenerateTagIDs SetFileType
+        HtmlDump
+    )],
+    Vars => [qw(
+        %allTables @tableOrder @fileTypes
+    )],
+);
+# set all of our EXPORT_TAGS in EXPORT_OK
+Exporter::export_ok_tags(keys %EXPORT_TAGS);
+
+# test for problems that can arise if encoding.pm is used
+{ my $t = "\xff"; die "Incompatible encoding!\n" if ord($t) != 0xff; }
+
+# The following functions defined in Image::ExifTool::Writer are declared
+# here so their prototypes will be available.  The Writer routines will be
+# autoloaded when any of these are called.
+sub SetNewValue($;$$%);
+sub SetNewValuesFromFile($$;@);
+sub GetNewValues($;$$);
+sub CountNewValues($);
+sub SaveNewValues($);
+sub RestoreNewValues($);
+sub WriteInfo($$;$$);
+sub SetFileModifyDate($$;$);
+sub SetFileName($$;$);
+sub GetAllTags(;$);
+sub GetWritableTags(;$);
+sub GetAllGroups($);
+sub GetNewGroups($);
+sub GetDeleteGroups();
+# non-public routines below
+sub InsertTagValues($$$;$);
+sub IsWritable($);
+sub GetNewFileName($$);
+sub LoadAllTables();
+sub GetNewTagInfoList($;$);
+sub GetNewTagInfoHash($@);
+sub GetLangInfo($$);
+sub Get64s($$);
+sub Get64u($$);
+sub GetExtended($$);
+sub DecodeBits($$;$);
+sub EncodeBits($$;$$);
+sub HexDump($;$%);
+sub DumpTrailer($$);
+sub DumpUnknownTrailer($$);
+sub VerboseInfo($$$%);
+sub VerboseDir($$;$$);
+sub VPrint($$@);
+sub Rationalize($;$);
+sub Write($@);
+sub ProcessTrailers($$);
+sub WriteTrailerBuffer($$$);
+sub AddNewTrailers($;@);
+sub Tell($);
+sub WriteValue($$;$$$$);
+sub WriteDirectory($$$;$);
+sub WriteBinaryData($$$);
+sub CheckBinaryData($$$);
+sub WriteTIFF($$$);
+sub Charset2Unicode($$;$);
+sub Latin2Unicode($$);
+sub UTF82Unicode($$;$);
+sub Unicode2Charset($$;$);
+sub Unicode2Latin($$;$);
+sub Unicode2UTF8($$);
+sub PackUTF8(@);
+sub UnpackUTF8($);
+
+# list of main tag tables to load in LoadAllTables() (sub-tables are recursed
+# automatically).  Note: They will appear in this order in the documentation
+# (unless tweaked in BuildTagLookup::GetTableOrder()), so put Exif first.
+@loadAllTables = qw(
+    PhotoMechanic Exif GeoTiff CanonRaw KyoceraRaw MinoltaRaw SigmaRaw JPEG
+    Jpeg2000 BMP BMP PICT PNG MNG MIFF PDF PostScript Photoshop::Header
+    FujiFilm::RAF Panasonic::Raw Sony::SR2SubIFD ID3 Vorbis FLAC APE
+    APE::NewHeader APE::OldHeader MPC MPEG::Audio MPEG::Video QuickTime
+    QuickTime::ImageFile Flash Flash::FLV Real::Media Real::Audio
+    Real::Metafile RIFF AIFF ASF DICOM MIE HTML
+);
+
+# recognized file types, in the order we test unknown files
+# Notes: 1) There is no need to test for like types separately here
+# 2) Put types with no file signature at end of list to avoid false matches
+@fileTypes = qw(JPEG CRW TIFF GIF MRW RAF X3F JP2 PNG MIE MIFF PS PDF PSD XMP
+                BMP PPM RIFF AIFF ASF MOV MPEG Real SWF FLV OGG FLAC APE MPC
+                ICC HTML VRD QTIF FPX PICT MP3 DICM RAW);
+
+# file types that we can write (edit)
+my @writeTypes = qw(JPEG TIFF GIF CRW MRW ORF PNG MIE PSD XMP PPM EPS PS ICC
+                    VRD JP2);
+
+# file types that we can create from scratch
+my @createTypes = qw(XMP ICC MIE VRD);
+
+# file type lookup for all recognized file extensions
+my %fileTypeLookup = (
+    ACR  => ['DICM', 'American College of Radiology ACR-NEMA'],
+    AI   => [['PDF','PS'], 'Adobe Illustrator (PDF-like or PS-like)'],
+    AIF  => ['AIFF', 'Audio Interchange File Format'],
+    AIFC => ['AIFF', 'Audio Interchange File Format Compressed'],
+    AIFF => ['AIFF', 'Audio Interchange File Format'],
+    APE  => ['APE',  "Monkey's Audio format"],
+    ARW  => ['TIFF', 'Sony Alpha RAW format (TIFF-like)'],
+    ASF  => ['ASF',  'Microsoft Advanced Systems Format'],
+    AVI  => ['RIFF', 'Audio Video Interleaved (RIFF-based)'],
+    BMP  => ['BMP',  'Windows BitMaP'],
+    BTF  => ['BTF',  'Big Tagged Image File Format'],
+    CIFF => ['CRW',  'Camera Image File Format (same as CRW)'],
+    CR2  => ['TIFF', 'Canon RAW 2 format (TIFF-like)'],
+    CRW  => ['CRW',  'Canon RAW format'],
+    CS1  => ['PSD',  'Sinar CaptureShop 1-Shot RAW (PSD-like)'],
+    DC3  => ['DICM', 'DICOM image file'],
+    DCM  => ['DICM', 'DICOM image file'],
+    DIB  => ['BMP',  'Device Independent Bitmap (aka. BMP)'],
+    DIC  => ['DICM', 'DICOM image file'],
+    DICM => ['DICM', 'DICOM image file'],
+    DNG  => ['TIFF', 'Digital Negative (TIFF-like)'],
+    DCR  => ['TIFF', 'Kodak Digital Camera RAW (TIFF-like)'],
+    DOC  => ['FPX',  'Microsoft Word Document (FPX-like)'],
+    EPS  => ['EPS',  'Encapsulated PostScript Format'],
+    EPSF => ['EPS',  'Encapsulated PostScript Format'],
+    ERF  => ['TIFF', 'Epson Raw Format (TIFF-like)'],
+    FLAC => ['FLAC', 'Free Lossless Audio Codec'],
+    FLV  => ['FLV',  'Flash Video'],
+    FPX  => ['FPX',  'FlashPix'],
+    GIF  => ['GIF',  'Compuserve Graphics Interchange Format'],
+    HTM  => ['HTML', 'HyperText Markup Language'],
+    HTML => ['HTML', 'HyperText Markup Language'],
+    ICC  => ['ICC',  'International Color Consortium'],
+    ICM  => ['ICC',  'International Color Consortium'],
+    JNG  => ['PNG',  'JPG Network Graphics (PNG-like)'],
+    JP2  => ['JP2',  'JPEG 2000 file'],
+    JPEG => ['JPEG', 'Joint Photographic Experts Group'],
+    JPG  => ['JPEG', 'Joint Photographic Experts Group'],
+    JPX  => ['JP2',  'JPEG 2000 file'],
+    K25  => ['TIFF', 'Kodak DC25 RAW (TIFF-like)'],
+    M4A  => ['MOV',  'MPG4 Audio (QuickTime-based)'],
+    MEF  => ['TIFF', 'Mamiya (RAW) Electronic Format (TIFF-like)'],
+    MIE  => ['MIE',  'Meta Information Encapsulation format'],
+    MIF  => ['MIFF', 'Magick Image File Format'],
+    MIFF => ['MIFF', 'Magick Image File Format'],
+    MNG  => ['PNG',  'Multiple-image Network Graphics (PNG-like)'],
+    MOS  => ['TIFF', 'Creo Leaf Mosaic (TIFF-like)'],
+    MOV  => ['MOV',  'Apple QuickTime movie'],
+    MP3  => ['MP3',  'MPEG Layer 3 audio (uses ID3 information)'],
+    MP4  => ['MOV',  'MPEG Layer 4 video (QuickTime-based)'],
+    MPC  => ['MPC',  'Musepack Audio'],
+    MPEG => ['MPEG', 'MPEG audio/video format 1'],
+    MPG  => ['MPEG', 'MPEG audio/video format 1'],
+    MRW  => ['MRW',  'Minolta RAW format'],
+    NEF  => ['TIFF', 'Nikon (RAW) Electronic Format (TIFF-like)'],
+    OGG  => ['OGG',  'Ogg Vorbis audio file'],
+    ORF  => ['ORF',  'Olympus RAW format'],
+    PBM  => ['PPM',  'Portable BitMap (PPM-like)'],
+    PCT  => ['PICT', 'Apple PICTure'],
+    PDF  => ['PDF',  'Adobe Portable Document Format'],
+    PEF  => ['TIFF', 'Pentax (RAW) Electronic Format (TIFF-like)'],
+    PGM  => ['PPM',  'Portable Gray Map (PPM-like)'],
+    PICT => ['PICT', 'Apple PICTure'],
+    PNG  => ['PNG',  'Portable Network Graphics'],
+    PPM  => ['PPM',  'Portable Pixel Map'],
+    PPT  => ['FPX',  'Microsoft PowerPoint presentation (FPX-like)'],
+    PS   => ['PS',   'PostScript'],
+    PSD  => ['PSD',  'PhotoShop Drawing'],
+    QIF  => ['QTIF', 'QuickTime Image File'],
+    QT   => ['MOV',  'QuickTime movie'],
+    QTI  => ['QTIF', 'QuickTime Image File'],
+    QTIF => ['QTIF', 'QuickTime Image File'],
+    RA   => ['Real', 'Real Audio'],
+    RAF  => ['RAF',  'FujiFilm RAW Format'],
+    RAM  => ['Real', 'Real Audio Metafile'],
+    RAW  => ['RAW',  'Kyocera Contax N Digital RAW or Panasonic RAW'],
+    RIF  => ['RIFF', 'Resource Interchange File Format'],
+    RIFF => ['RIFF', 'Resource Interchange File Format'],
+    RM   => ['Real', 'Real Media'],
+    RMVB => ['Real', 'Real Media Variable Bitrate'],
+    RPM  => ['Real', 'Real Media Plug-in Metafile'],
+    RV   => ['Real', 'Real Video'],
+    SR2  => ['TIFF', 'Sony RAW Format 2 (TIFF-like)'],
+    SRF  => ['TIFF', 'Sony RAW Format (TIFF-like)'],
+    SWF  => ['SWF',  'Shockwave Flash'],
+    THM  => ['JPEG', 'Canon Thumbnail (aka. JPG)'],
+    TIF  => ['TIFF', 'Tagged Image File Format'],
+    TIFF => ['TIFF', 'Tagged Image File Format'],
+    VRD  => ['VRD',  'Canon VRD Recipe Data (written by DPP)'],
+    WAV  => ['RIFF', 'WAVeform (Windows digital audio format)'],
+    WDP  => ['TIFF', 'Windows Media Photo (TIFF-based)'],
+    WMA  => ['ASF',  'Windows Media Audio (ASF-based)'],
+    WMV  => ['ASF',  'Windows Media Video (ASF-based)'],
+    X3F  => ['X3F',  'Sigma RAW format'],
+    XHTML=> ['HTML', 'Extensible HyperText Markup Language'],
+    XLS  => ['FPX',  'Microsoft Excel worksheet (FPX-like)'],
+    XMP  => ['XMP',  'Extensible Metadata Platform data file'],
+);
+
+# MIME types for applicable file types above
+# (missing entries default to 'application/unknown')
+my %mimeType = (
+    AIFF => 'audio/aiff',
+    APE  => 'audio/x-monkeys-audio',
+    ASF  => 'video/x-ms-asf',
+    ARW  => 'image/x-raw',
+    AVI  => 'video/avi',
+    BMP  => 'image/bmp',
+    BTF  => 'application/unknown', #TEMPORARY!
+    CR2  => 'image/x-raw',
+    CRW  => 'image/x-raw',
+    EPS  => 'application/postscript',
+    ERF  => 'image/x-raw',
+    DCR  => 'image/x-raw',
+    DICM => 'application/dicom',
+    DNG  => 'image/x-raw',
+    DOC  => 'application/msword',
+    FLAC => 'audio/flac',
+    FLV  => 'video/x-flv',
+    FPX  => 'image/vnd.fpx',
+    GIF  => 'image/gif',
+    HTML => 'text/html',
+    JNG  => 'image/jng',
+    JP2  => 'image/jpeg2000',
+    JPEG => 'image/jpeg',
+    K25  => 'image/x-raw',
+    M4A  => 'audio/mp4',
+    MEF  => 'image/x-raw',
+    MIE  => 'application/x-mie',
+    MIFF => 'application/x-magick-image',
+    MNG  => 'video/mng',
+    MOS  => 'image/x-raw',
+    MOV  => 'video/quicktime',
+    MP3  => 'audio/mpeg',
+    MP4  => 'video/mp4',
+    MPC  => 'audio/x-musepack',
+    MPEG => 'video/mpeg',
+    MRW  => 'image/x-raw',
+    NEF  => 'image/x-raw',
+    OGG  => 'audio/x-ogg',
+    ORF  => 'image/x-raw',
+    PBM  => 'image/x-portable-bitmap',
+    PDF  => 'application/pdf',
+    PEF  => 'image/x-raw',
+    PGM  => 'image/x-portable-graymap',
+    PICT => 'image/pict',
+    PNG  => 'image/png',
+    PPM  => 'image/x-portable-pixmap',
+    PPT  => 'application/vnd.ms-powerpoint',
+    PS   => 'application/postscript',
+    PSD  => 'application/photoshop',
+    QTIF => 'image/x-quicktime',
+    RA   => 'audio/x-pn-realaudio',
+    RAF  => 'image/x-raw',
+    RAM  => 'audio/x-pn-realaudio',
+    RAW  => 'image/x-raw',
+    RM   => 'application/vnd.rn-realmedia',
+    RMVB => 'application/vnd.rn-realmedia-vbr',
+    RPM  => 'audio/x-pn-realaudio-plugin',
+    RV   => 'video/vnd.rn-realvideo',
+    SR2  => 'image/x-raw',
+    SRF  => 'image/x-raw',
+    SWF  => 'application/x-shockwave-flash',
+    TIFF => 'image/tiff',
+    WAV  => 'audio/x-wav',
+    WDP  => 'image/vnd.ms-photo',
+    WMA  => 'audio/x-ms-wma',
+    WMV  => 'video/x-ms-wmv',
+    X3F  => 'image/x-raw',
+    XLS  => 'application/vnd.ms-excel',
+    XMP  => 'application/rdf+xml',
+);
+
+# module names for each file type
+# (missing entries have same module name as file type)
+my %moduleName = (
+    BTF  => 'BigTIFF',
+    CRW  => 'CanonRaw',
+    DICM => 'DICOM',
+    EPS  => 'PostScript',
+    ICC  => 'ICC_Profile',
+    FLV  => 'Flash',
+    FPX  => 'FlashPix',
+    JP2  => 'Jpeg2000',
+    JPEG => '',     # (in the current module)
+    MOV  => 'QuickTime',
+    MP3  => 'ID3',
+    MRW  => 'MinoltaRaw',
+    OGG  => 'Vorbis',
+    ORF  => 'Olympus',
+    PS   => 'PostScript',
+    PSD  => 'Photoshop',
+    QTIF => 'QuickTime',
+    RAF  => 'FujiFilm',
+    RAW  => 'KyoceraRaw',
+    SWF  => 'Flash',
+    TIFF => '',
+    VRD  => 'CanonVRD',
+    X3F  => 'SigmaRaw',
+);
+
+# default group priority for writing
+my @defaultWriteGroups = qw(EXIF IPTC XMP MakerNotes Photoshop ICC_Profile CanonVRD);
+
+# group hash for ExifTool-generated tags
+my %allGroupsExifTool = ( 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'ExifTool' );
+
+# headers for various segment types
+$exifAPP1hdr = "Exif\0\0";
+$xmpAPP1hdr = "http://ns.adobe.com/xap/1.0/\0";
+$psAPP13hdr = "Photoshop 3.0\0";
+$psAPP13old = 'Adobe_Photoshop2.5:';
+
+sub DummyWriteProc { return 1; }
+
+# tag information for preview image -- this should be used for all
+# PreviewImage tags so they are handled properly when reading/writing
+%Image::ExifTool::previewImageTagInfo = (
+    Name => 'PreviewImage',
+    Writable => 'undef',
+    # a value of 'none' is ok...
+    WriteCheck => '$val eq "none" ? undef : $self->CheckImage(\$val)',
+    DataTag => 'PreviewImage',
+    # we allow preview image to be set to '', but we don't want a zero-length value
+    # in the IFD, so set it temorarily to 'none'.  Note that the length is <= 4,
+    # so this value will fit in the IFD so the preview fixup won't be generated.
+    ValueConv => '$self->ValidateImage(\$val,$tag)',
+    ValueConvInv => '$val eq "" and $val="none"; $val',
+);
+
+# extra tags that aren't truly EXIF tags, but are generated by the script
+# Note: any tag in this list with a name corresponding to a Group0 name is
+#       used to write the entire corresponding directory as a block.
+%Image::ExifTool::Extra = (
+    GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
+    DID_TAG_ID => 1,   # tag ID's aren't meaningful for these tags
+    WRITE_PROC => \&DummyWriteProc,
+    Comment => {
+        Notes => 'comment embedded in JPEG, GIF89a or PPM/PGM/PBM image',
+        Writable => 1,
+        WriteGroup => 'Comment',
+        Priority => 0,  # to preserve order of JPEG COM segments
+    },
+    Directory => {
+        Writable => 1,
+        Protected => 1,
+        # translate backslashes in directory names and add trailing '/'
+        ValueConvInv => '$_=$val; tr/\\\\/\//; m{[^/]$} and $_ .= "/"; $_',
+    },
+    FileName => {
+        Writable => 1,
+        Protected => 1,
+        ValueConvInv => '$val=~tr/\\\\/\//; $val',
+    },
+    FileSize => {
+        PrintConv => sub {
+            my $val = shift;
+            $val < 2048 and return "$val bytes";
+            $val < 2097152 and return sprintf('%.0f kB', $val / 1024);
+            return sprintf('%.0f MB', $val / 1048576);
+        },
+    },
+    FileType    => { },
+    FileModifyDate => {
+        Description => 'File Modification Date/Time',
+        Notes => 'the filesystem modification time',
+        Groups => { 2 => 'Time' },
+        Writable => 1,
+        Shift => 'Time',
+        ValueConv => 'ConvertUnixTime($val,"local")',
+        ValueConvInv => 'GetUnixTime($val,"local")',
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$val',
+    },
+    MIMEType    => { },
+    ImageWidth  => { },
+    ImageHeight => { },
+    XResolution => { },
+    YResolution => { },
+    MaxVal      => { }, # max pixel value in PPM or PGM image
+    EXIF => {
+        Notes => 'the full EXIF data block',
+        Groups => { 0 => 'EXIF' },
+        Binary => 1,
+    },
+    ICC_Profile => {
+        Notes => 'the full ICC_Profile data block',
+        Groups => { 0 => 'ICC_Profile' },
+        Flags => ['Writable' ,'Protected', 'Binary'],
+        WriteCheck => q{
+            require Image::ExifTool::ICC_Profile;
+            return Image::ExifTool::ICC_Profile::ValidateICC(\$val);
+        },
+    },
+    XMP => {
+        Notes => 'the full XMP data block',
+        Groups => { 0 => 'XMP' },
+        Flags => [ 'Writable', 'Binary' ],
+        WriteCheck => q{
+            require Image::ExifTool::XMP;
+            return Image::ExifTool::XMP::CheckXMP($self, $tagInfo, \$val);
+        },
+    },
+    CanonVRD => {
+        Notes => 'the full Canon DPP VRD trailer block',
+        Groups => { 0 => 'CanonVRD' },
+        Flags => ['Writable' ,'Protected', 'Binary'],
+        WriteCheck => q{
+            return undef if $val =~ /^CANON OPTIONAL DATA\0/;
+            return 'Invalid CanonVRD data';
+        },
+    },
+    Encryption  => { }, # PDF encryption filter
+    ExifByteOrder => {
+        Writable => 1,
+        Notes => 'only writable for newly created EXIF segments',
+        PrintConv => {
+            II => 'Little-endian (Intel)',
+            MM => 'Big-endian (Motorola)',
+        },
+    },
+    ExifToolVersion => {
+        Description => 'ExifTool Version Number',
+        Groups      => \%allGroupsExifTool
+    },
+    Error       => { Priority => 0, Groups => \%allGroupsExifTool },
+    Warning     => { Priority => 0, Groups => \%allGroupsExifTool },
+);
+
+# information decoded from JPEG SOF frame
+# (define this here to avoid loading JPEG.pm)
+# (ref http://www.w3.org/Graphics/JPEG/itu-t81.pdf)
+%Image::ExifTool::JPEG::SOF = (
+    GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
+    NOTES => 'This information is extracted from the JPEG Start Of Frame segment.',
+    VARS => { NO_ID => 1 },
+	EncodingProcess => {
+	    PrintHex => 1,
+	    PrintConv => {
+	        0x0 => 'Baseline DCT, Huffman coding',
+            0x1 => 'Extended sequential DCT, Huffman coding',
+            0x2 => 'Progressive DCT, Huffman coding',
+            0x3 => 'Lossless, Huffman coding',
+            0x5 => 'Sequential DCT, differential Huffman coding',
+            0x6 => 'Progressive DCT, differential Huffman coding',
+            0x7 => 'Lossless, Differential Huffman coding',
+            0x9 => 'Extended sequential DCT, arithmetic coding',
+            0xa => 'Progressive DCT, arithmetic coding',
+            0xb => 'Lossless, arithmetic coding',
+            0xd => 'Sequential DCT, differential arithmetic coding',
+            0xe => 'Progressive DCT, differential arithmetic coding',
+            0xf => 'Lossless, differential arithmetic coding',
+        }
+    },
+    BitsPerSample    => { },
+    ImageHeight      => { },
+    ImageWidth       => { },
+    ColorComponents  => { },
+    YCbCrSubSampling => {
+        Notes => 'calculated from components table',
+        PrintConv => {
+            '1 1' => 'YCbCr4:4:4 (1 1)',
+            '2 1' => 'YCbCr4:2:2 (2 1)',
+            '2 2' => 'YCbCr4:2:0 (2 2)',
+            '4 1' => 'YCbCr4:1:1 (4 1)',
+            '4 2' => 'YCbCr4:1:0 (4 2)',
+            '1 2' => 'YCbCr4:4:0 (1 2)',
+        },
+    },
+);
+
+# static private ExifTool variables
+
+%allTables = ( );   # list of all tables loaded (except composite tags)
+@tableOrder = ( );  # order the tables were loaded
+
+my $didTagID;       # flag indicating we are accessing tag ID's
+
+# composite tags (accumulation of all Composite tag tables)
+%Image::ExifTool::Composite = (
+    GROUPS => { 0 => 'Composite', 1 => 'Composite' },
+    DID_TAG_ID => 1,    # want empty tagID's for composite tags
+    WRITE_PROC => \&DummyWriteProc,
+);
+
+# JFIF APP0 definitions
+%Image::ExifTool::JFIF::Main = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'JFIF', 1 => 'JFIF', 2 => 'Image' },
+    DATAMEMBER => [ 2, 3, 5 ],
+    0 => {
+        Name => 'JFIFVersion',
+        Format => 'int8u[2]',
+        PrintConv => '$val=~tr/ /./;$val',
+    },
+    2 => {
+        Name => 'ResolutionUnit',
+        Writable => 1,
+        RawConv => '$$self{JFIFResolutionUnit} = $val',
+        PrintConv => {
+            0 => 'None',
+            1 => 'inches',
+            2 => 'cm',
+        },
+        Priority => -1,
+    },
+    3 => {
+        Name => 'XResolution',
+        Format => 'int16u',
+        Writable => 1,
+        Priority => -1,
+        RawConv => '$$self{JFIFXResolution} = $val',
+    },
+    5 => {
+        Name => 'YResolution',
+        Format => 'int16u',
+        Writable => 1,
+        Priority => -1,
+        RawConv => '$$self{JFIFYResolution} = $val',
+    },
+);
+%Image::ExifTool::JFIF::Extension = (
+    GROUPS => { 0 => 'JFIF', 1 => 'JFIF', 2 => 'Image' },
+    0x10 => {
+        Name => 'ThumbnailImage',
+        ValueConv => '$self->ValidateImage(\$val,$tag)',
+    },
+);
+
+# special tag names (not used for tag info)
+my %specialTags = (
+    PROCESS_PROC=>1, WRITE_PROC=>1, CHECK_PROC=>1, GROUPS=>1, FORMAT=>1,
+    FIRST_ENTRY=>1, TAG_PREFIX=>1, PRINT_CONV=>1, DID_TAG_ID=>1, WRITABLE=>1,
+    NOTES=>1, IS_OFFSET=>1, EXTRACT_UNKNOWN=>1, NAMESPACE=>1, PREFERRED=>1,
+    PARENT=>1, PRIORITY=>1, WRITE_GROUP=>1, LANG_INFO=>1, VARS=>1,
+    DATAMEMBER=>1,
+);
+
+#------------------------------------------------------------------------------
+# Warning handler routines (warning string stored in $evalWarning)
+#
+# Set warning message
+# Inputs: 0) warning string (undef to reset warning)
+sub SetWarning($) { $evalWarning = $_[0]; }
+
+# Get warning message
+sub GetWarning()  { return $evalWarning; }
+
+# Clean unnecessary information (line number, LF) from warning
+# Inputs: 0) warning string or undef to use current warning
+# Returns: cleaned warning
+sub CleanWarning(;$)
+{
+    my $str = shift;
+    unless (defined $str) {
+        return undef unless defined $evalWarning;
+        $str = $evalWarning;
+    }
+    $str = $1 if $str =~ /(.*) at /s;
+    $str =~ s/\s+$//s;
+    return $str;
+}
+
+#==============================================================================
+# New - create new ExifTool object
+# Inputs: 0) reference to exiftool object or ExifTool class name
+sub new
+{
+    local $_;
+    my $that = shift;
+    my $class = ref($that) || $that || 'Image::ExifTool';
+    my $self = bless {}, $class;
+
+    # make sure our main Exif tag table has been loaded
+    GetTagTable("Image::ExifTool::Exif::Main");
+
+    $self->ClearOptions();      # create default options hash
+    $self->{VALUE} = { };       # must initialize this for warning messages
+    $self->{DEL_GROUP} = { };   # list of groups to delete when writing
+
+    # initialize our new groups for writing
+    $self->SetNewGroups(@defaultWriteGroups);
+
+    return $self;
+}
+
+#------------------------------------------------------------------------------
+# ImageInfo - return specified information from image file
+# Inputs: 0) [optional] ExifTool object reference
+#         1) filename, file reference, or scalar data reference
+#         2-N) list of tag names to find (or tag list reference or options reference)
+# Returns: reference to hash of tag/value pairs (with "Error" entry on error)
+# Notes:
+#   - if no tags names are specified, the values of all tags are returned
+#   - tags may be specified with leading '-' to exclude
+#   - can pass a reference to list of tags to find, in which case the list will
+#     be updated with the tags found in the proper case and in the specified order.
+#   - can pass reference to hash specifying options
+#   - returned tag values may be scalar references indicating binary data
+#   - see ClearOptions() below for a list of options and their default values
+# Examples:
+#   use Image::ExifTool 'ImageInfo';
+#   my $info = ImageInfo($file, 'DateTimeOriginal', 'ImageSize');
+#    - or -
+#   my $exifTool = new Image::ExifTool;
+#   my $info = $exifTool->ImageInfo($file, \@tagList, {Sort=>'Group0'} );
+sub ImageInfo($;@)
+{
+    local $_;
+    # get our ExifTool object ($self) or create one if necessary
+    my $self;
+    if (ref $_[0] and UNIVERSAL::isa($_[0],'Image::ExifTool')) {
+        $self = shift;
+    } else {
+        $self = new Image::ExifTool;
+    }
+    my %saveOptions = %{$self->{OPTIONS}};  # save original options
+
+    # initialize file information
+    $self->{FILENAME} = $self->{RAF} = undef;
+
+    $self->ParseArguments(@_);              # parse our function arguments
+    $self->ExtractInfo(undef);              # extract meta information from image
+    my $info = $self->GetInfo(undef);       # get requested information
+
+    $self->{OPTIONS} = \%saveOptions;       # restore original options
+
+    return $info;   # return requested information
+}
+
+#------------------------------------------------------------------------------
+# Get/set ExifTool options
+# Inputs: 0) ExifTool object reference,
+#         1) Parameter name, 2) Value to set the option
+#         3-N) More parameter/value pairs
+# Returns: original value of last option specified
+sub Options($$;@)
+{
+    local $_;
+    my $self = shift;
+    my $options = $$self{OPTIONS};
+    my $oldVal;
+
+    while (@_) {
+        my $param = shift;
+        $oldVal = $options->{$param};
+        last unless @_;
+        $options->{$param} = shift;
+        # clone Exclude list and expand shortcuts
+        if ($param eq 'Exclude' and defined $options->{$param}) {
+            my @exclude;
+            my $val = $options->{$param};
+            if (ref $val eq 'ARRAY') {
+                @exclude = @$val;
+            } else {
+                @exclude = ($val);
+            }
+            ExpandShortcuts(\@exclude);
+            $options->{$param} = \@exclude;
+        }
+    }
+    return $oldVal;
+}
+
+#------------------------------------------------------------------------------
+# ClearOptions - set options to default values
+# Inputs: 0) ExifTool object reference
+sub ClearOptions($)
+{
+    local $_;
+    my $self = shift;
+
+    # create options hash with default values
+    # (commented out options don't need initializing)
+    $self->{OPTIONS} = {
+    #   Binary      => undef,   # flag to extract binary values even if tag not specified
+    #   ByteOrder   => undef,   # default byte order when creating EXIF information
+        Charset     => 'UTF8',  # character set for converting Unicode characters
+    #   Compact     => undef,   # compact XMP and IPTC data
+        Composite   => 1,       # flag to calculate Composite tags
+    #   Compress    => undef,   # flag to write new values as compressed if possible
+    #   CoordFormat => undef,   # GPS lat/long coordinate format
+    #   DateFormat  => undef,   # format for date/time
+        Duplicates  => 1,       # flag to save duplicate tag values
+    #   Exclude     => undef,   # tags to exclude
+    #   FastScan    => undef,   # flag to avoid scanning for trailer
+    #   FixBase     => undef,   # fix maker notes base offsets
+    #   Group#      => undef,   # return tags for specified groups in family #
+        HtmlDump    => 0,       # HTML dump (0-3, higher # = bigger limit)
+    #   HtmlDumpBase => undef,  # base address for HTML dump
+    #   IgnoreMinorErrors => undef, # ignore minor errors when reading/writing
+    #   List        => undef,   # extract lists of PrintConv values into arrays
+    #   MakerNotes  => undef,   # extract maker notes as a block
+    #   MissingTagValue =>undef,# value for missing tags when expanded in expressions
+        PrintConv   => 1,       # flag to enable print conversion
+    #   ScanForXMP  => undef,   # flag to scan for XMP information in all files
+        Sort        => 'Input', # order to sort found tags (Input, File, Alpha, Group#)
+    #   StrictDate  => undef,   # flag to return undef for invalid date conversions
+        TextOut     => \*STDOUT,# file for Verbose/HtmlDump output
+        Unknown     => 0,       # flag to get values of unknown tags (0-2)
+        Verbose     => 0,       # print verbose messages (0-4, higher # = more verbose)
+    };
+}
+
+#------------------------------------------------------------------------------
+# Extract meta information from image
+# Inputs: 0) ExifTool object reference
+#         1-N) Same as ImageInfo()
+# Returns: 1 if this was a valid image, 0 otherwise
+# Notes: pass an undefined value to avoid parsing arguments
+sub ExtractInfo($;@)
+{
+    local $_;
+    my $self = shift;
+    my $options = $self->{OPTIONS};     # pointer to current options
+    my %saveOptions;
+
+    if (defined $_[0] or $options->{HtmlDump}) {
+        %saveOptions = %$options;       # save original options
+        
+        # require duplicates for html dump
+        $self->Options(Duplicates => 1) if $options->{HtmlDump};
+
+        if (defined $_[0]) {
+            # only initialize filename if called with arguments
+            $self->{FILENAME} = undef;  # name of file (or '' if we didn't open it)
+            $self->{RAF} = undef;       # RandomAccess object reference
+    
+            $self->ParseArguments(@_);  # initialize from our arguments
+        }
+    }
+    # initialize ExifTool object members
+    $self->Init();
+
+    delete $self->{MAKER_NOTE_FIXUP};   # fixup information for extracted maker notes
+    delete $self->{MAKER_NOTE_BYTE_ORDER};
+    delete $self->{DONE_ID3};
+
+    my $filename = $self->{FILENAME};   # image file name ('' if already open)
+    my $raf = $self->{RAF};             # RandomAccess object
+
+    # return our version number
+    $self->FoundTag('ExifToolVersion', "$VERSION$RELEASE");
+
+    local *EXIFTOOL_FILE;   # avoid clashes with global namespace
+
+    unless ($raf) {
+        # save file name
+        if (defined $filename and $filename ne '') {
+            unless ($filename eq '-') {
+                my $name = $filename;
+                # extract file name from pipe if necessary
+                $name =~ /\|$/ and $name =~ s/.*?"(.*)".*/$1/;
+                my $dir;
+                if (eval 'require File::Basename') {
+                    $dir = File::Basename::dirname($name);
+                    $name = File::Basename::basename($name);
+                } else {
+                    $name =~ tr/\\/\//;
+                    if ($name =~ s/(.*)\///) {  # remove path
+                        $dir = length($1) ? $1 : '/';
+                    }
+                }
+                $self->FoundTag('FileName', $name);
+                $self->FoundTag('Directory', $dir) if defined $dir and length $dir;
+            }
+            # open the file
+            if (open(EXIFTOOL_FILE,$filename)) {
+                my $filePt = \*EXIFTOOL_FILE;
+                # create random access file object
+                $raf = new File::RandomAccess($filePt);
+                # patch to force pipe to be buffered because seek returns success
+                # in Windows cmd shell pipe even though it really failed
+                $raf->{TESTED} = -1 if $filename eq '-' or $filename =~ /\|$/;
+                $self->{RAF} = $raf;
+            } else {
+                $self->Error('Error opening file');
+            }
+        } else {
+            $self->Error('No file specified');
+        }
+    }
+
+    if ($raf) {
+        # get file size and last modified time if this is a plain file
+        if ($raf->{FILE_PT} and -f $raf->{FILE_PT}) {
+            my $fileSize = -s _;
+            my $fileTime = -M _;
+            $self->FoundTag('FileSize', $fileSize) if defined $fileSize;
+            $self->FoundTag('FileModifyDate', $^T - $fileTime*(24*3600)) if defined $fileTime;
+        }
+
+        # get list of file types to check
+        my $tiffType;
+        $self->{FILE_EXT} = GetFileExtension($filename);
+        my @fileTypeList = GetFileType($filename);
+        if (@fileTypeList) {
+            # add remaining types to end of list so we test them all
+            my $pat = join '|', @fileTypeList;
+            push @fileTypeList, grep(!/^($pat)$/, @fileTypes);
+            $tiffType = $self->{FILE_EXT};
+        } else {
+            # scan through all recognized file types
+            @fileTypeList = @fileTypes;
+            $tiffType = 'TIFF';
+        }
+        push @fileTypeList, ''; # end of list marker
+        # initialize the input file for seeking in binary data
+        $raf->BinMode();    # set binary mode before we start reading
+        my $pos = $raf->Tell(); # get file position so we can rewind
+        my %dirInfo = ( RAF => $raf, Base => $pos );
+        # loop through list of file types to test
+        my $type;
+        for (;;) {
+            $type = shift @fileTypeList;
+            unless ($type) {
+                last unless defined $type;
+                # last ditch effort to scan past unknown header for JPEG/TIFF
+                my $buff;
+                $raf->Read($buff, 1024);
+                next unless $buff =~ /(\xff\xd8\xff|MM\0\x2a|II\x2a\0)/g;
+                $type = ($1 eq "\xff\xd8\xff") ? 'JPEG' : 'TIFF';
+                my $skip = pos($buff) - length($1);
+                $dirInfo{Base} = $pos + $skip;
+                $raf->Seek($pos + $skip, 0);
+                $self->Warn("Skipped unknown $skip byte header");
+            }
+            # save file type in member variable
+            $self->{FILE_TYPE} = $type;
+            $dirInfo{Parent} = ($type eq 'TIFF') ? $tiffType : $type;
+            my $module = $moduleName{$type};
+            $module = $type unless defined $module;
+            my $func = "Process$type";
+
+            # load module if necessary
+            if ($module) {
+                require "Image/ExifTool/$module.pm";
+                $func = "Image::ExifTool::${module}::$func";
+            }
+            # process the file
+            no strict 'refs';
+            &$func($self, \%dirInfo) and last;
+            use strict 'refs';
+
+            # seek back to try again from the same position in the file
+            unless ($raf->Seek($pos, 0)) {
+                $self->Error('Error seeking in file');
+                last;
+            }
+        }
+        # scan for XMP if specified
+        if ($self->Options('ScanForXMP') and (not defined $type or
+            (not $self->Options('FastScan') and not $$self{FoundXMP})))
+        {
+            $raf->Seek($pos, 0);
+            require Image::ExifTool::XMP;
+            Image::ExifTool::XMP::ScanForXMP($self, $raf) and $type = '';
+        }
+        unless (defined $type) {
+            # if we were given a single image with a known type there
+            # must be a format error since we couldn't read it, otherwise
+            # it is likely we don't support images of this type
+            $self->Error(GetFileType($filename) ?
+                'File format error' : 'Unknown file type');
+        }
+        # extract binary EXIF data block only if requested
+        if (defined $self->{EXIF_DATA} and $self->{REQ_TAG_LOOKUP}->{exif}) {
+            $self->FoundTag('EXIF', $self->{EXIF_DATA});
+        }
+        # calculate composite tags
+        $self->BuildCompositeTags() if $options->{Composite};
+
+        # do our HTML dump if requested
+        if ($self->{HTML_DUMP}) {
+            $raf->Seek(0, 2);   # seek to end of file
+            $self->{HTML_DUMP}->FinishTiffDump($self, $raf->Tell());
+            my $pos = $options->{HtmlDumpBase};
+            $pos = ($self->{FIRST_EXIF_POS} || 0) unless defined $pos;
+            my $dataPt = defined $self->{EXIF_DATA} ? \$self->{EXIF_DATA} : undef;
+            undef $dataPt if defined $self->{EXIF_POS} and $pos != $self->{EXIF_POS};
+            $self->{HTML_DUMP}->Print($raf, $dataPt, $pos,
+                $options->{TextOut}, $options->{HtmlDump},
+                $self->{FILENAME} ? "HTML Dump ($self->{FILENAME})" : 'HTML Dump');
+        }
+
+        $raf->Close() if $filename;     # close the file if we opened it
+    }
+
+    # restore original options
+    %saveOptions and $self->{OPTIONS} = \%saveOptions;
+
+    return exists $self->{VALUE}->{Error} ? 0 : 1;
+}
+
+#------------------------------------------------------------------------------
+# Get hash of extracted meta information
+# Inputs: 0) ExifTool object reference
+#         1-N) options hash reference, tag list reference or tag names
+# Returns: Reference to information hash
+# Notes: - pass an undefined value to avoid parsing arguments
+#        - If groups are specified, first groups take precedence if duplicate
+#          tags found but Duplicates option not set.
+sub GetInfo($;@)
+{
+    local $_;
+    my $self = shift;
+    my %saveOptions;
+
+    unless (@_ and not defined $_[0]) {
+        %saveOptions = %{$self->{OPTIONS}}; # save original options
+        # must set FILENAME so it isn't parsed from the arguments
+        $self->{FILENAME} = '' unless defined $self->{FILENAME};
+        $self->ParseArguments(@_);
+    }
+
+    # get reference to list of tags for which we will return info
+    my $rtnTags = $self->SetFoundTags();
+
+    # build hash of tag information
+    my (%info, %ignored);
+    my $conv = $self->{OPTIONS}->{PrintConv} ? 'PrintConv' : 'ValueConv';
+    foreach (@$rtnTags) {
+        my $val = $self->GetValue($_, $conv);
+        defined $val or $ignored{$_} = 1, next;
+        $info{$_} = $val;
+    }
+
+    # remove ignored tags from the list
+    my $reqTags = $self->{REQUESTED_TAGS} || [ ];
+    if (%ignored and not @$reqTags) {
+        my @goodTags;
+        foreach (@$rtnTags) {
+            push @goodTags, $_ unless $ignored{$_};
+        }
+        $rtnTags = $self->{FOUND_TAGS} = \@goodTags;
+    }
+
+    # return sorted tag list if provided with a list reference
+    if ($self->{IO_TAG_LIST}) {
+        # use file order by default if no tags specified
+        # (no such thing as 'Input' order in this case)
+        my $sortOrder = $self->{OPTIONS}->{Sort};
+        unless (@$reqTags or ($sortOrder and $sortOrder ne 'Input')) {
+            $sortOrder = 'File';
+        }
+        # return tags in specified sort order
+        @{$self->{IO_TAG_LIST}} = $self->GetTagList($rtnTags, $sortOrder);
+    }
+
+    # restore original options
+    %saveOptions and $self->{OPTIONS} = \%saveOptions;
+
+    return \%info;
+}
+
+#------------------------------------------------------------------------------
+# Combine information from a list of info hashes
+# Unless Duplicates is enabled, first entry found takes priority
+# Inputs: 0) ExifTool object reference, 1-N) list of info hash references
+# Returns: Combined information hash reference
+sub CombineInfo($;@)
+{
+    local $_;
+    my $self = shift;
+    my (%combinedInfo, $info);
+
+    if ($self->{OPTIONS}->{Duplicates}) {
+        while ($info = shift) {
+            my $key;
+            foreach $key (keys %$info) {
+                $combinedInfo{$key} = $$info{$key};
+            }
+        }
+    } else {
+        my (%haveInfo, $tag);
+        while ($info = shift) {
+            foreach $tag (keys %$info) {
+                my $tagName = GetTagName($tag);
+                next if $haveInfo{$tagName};
+                $haveInfo{$tagName} = 1;
+                $combinedInfo{$tag} = $$info{$tag};
+            }
+        }
+    }
+    return \%combinedInfo;
+}
+
+#------------------------------------------------------------------------------
+# Inputs: 0) ExifTool object reference
+#         1) [optional] reference to info hash or tag list ref (default is found tags)
+#         2) [optional] sort order ('File', 'Input', ...)
+# Returns: List of tags in specified order
+sub GetTagList($;$$)
+{
+    local $_;
+    my ($self, $info, $sortOrder) = @_;
+
+    my $foundTags;
+    if (ref $info eq 'HASH') {
+        my @tags = keys %$info;
+        $foundTags = \@tags;
+    } elsif (ref $info eq 'ARRAY') {
+        $foundTags = $info;
+    }
+    my $fileOrder = $self->{FILE_ORDER};
+
+    if ($foundTags) {
+        # make sure a FILE_ORDER entry exists for all tags
+        # (note: already generated bogus entries for FOUND_TAGS case below)
+        foreach (@$foundTags) {
+            next if defined $$fileOrder{$_};
+            $$fileOrder{$_} = 999;
+        }
+    } else {
+        $sortOrder = $info if $info and not $sortOrder;
+        $foundTags = $self->{FOUND_TAGS} || $self->SetFoundTags() or return undef;
+    }
+    $sortOrder or $sortOrder = $self->{OPTIONS}->{Sort};
+
+    # return original list if no sort order specified
+    return @$foundTags unless $sortOrder and $sortOrder ne 'Input';
+
+    if ($sortOrder eq 'Alpha') {
+        return sort @$foundTags;
+    } elsif ($sortOrder =~ /^Group(\d*)/) {
+        my $family = $1 || 0;
+        # want to maintain a basic file order with the groups
+        # ordered in the way they appear in the file
+        my (%groupCount, %groupOrder);
+        my $numGroups = 0;
+        my $tag;
+        foreach $tag (sort { $$fileOrder{$a} <=> $$fileOrder{$b} } @$foundTags) {
+            my $group = $self->GetGroup($tag, $family);
+            my $num = $groupCount{$group};
+            $num or $num = $groupCount{$group} = ++$numGroups;
+            $groupOrder{$tag} = $num;
+        }
+        return sort { $groupOrder{$a} <=> $groupOrder{$b} or
+                      $$fileOrder{$a} <=> $$fileOrder{$b} } @$foundTags;
+    } else {
+        return sort { $$fileOrder{$a} <=> $$fileOrder{$b} } @$foundTags;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Get list of found tags in specified sort order
+# Inputs: 0) ExifTool object reference, 1) sort order ('File', 'Input', ...)
+# Returns: List of tags in specified order
+# Notes: If not specified, sort order is taken from OPTIONS
+sub GetFoundTags($;$)
+{
+    local $_;
+    my ($self, $sortOrder) = @_;
+    my $foundTags = $self->{FOUND_TAGS} || $self->SetFoundTags() or return undef;
+    return $self->GetTagList($foundTags, $sortOrder);
+}
+
+#------------------------------------------------------------------------------
+# Get list of requested tags
+# Inputs: 0) ExifTool object reference
+# Returns: List of requested tags
+sub GetRequestedTags($)
+{
+    local $_;
+    return @{$_[0]->{REQUESTED_TAGS}};
+}
+
+#------------------------------------------------------------------------------
+# Get tag value
+# Inputs: 0) ExifTool object reference, 1) tag key
+#         2) [optional] Value type: PrintConv, ValueConv, Both or Raw, the default
+#            is PrintConv or ValueConv, depending on the PrintConv option setting
+# Returns: Scalar context: tag value or undefined
+#          List context: list of values or empty list
+sub GetValue($$;$)
+{
+    local $_;
+    my ($self, $tag, $type) = @_;
+
+    # start with the raw value
+    my $value = $self->{VALUE}->{$tag};
+    return wantarray ? () : undef unless defined $value;
+
+    # figure out what conversions to do
+    my (@convTypes, $tagInfo);
+    $type or $type = $self->{OPTIONS}->{PrintConv} ? 'PrintConv' : 'ValueConv';
+    unless ($type eq 'Raw') {
+        $tagInfo = $self->{TAG_INFO}->{$tag};
+        push @convTypes, 'ValueConv';
+        push @convTypes, 'PrintConv' unless $type eq 'ValueConv';
+    }
+
+    # do the conversions
+    my (@val, @prt, @raw, $convType, $valueConv);
+    foreach $convType (@convTypes) {
+        last if ref $value eq 'SCALAR'; # don't convert a scalar reference
+        my $conv = $$tagInfo{$convType};
+        unless (defined $conv) {
+            if ($convType eq 'ValueConv') {
+                next unless $$tagInfo{Binary};
+                $conv = '\$val';  # return scalar reference for binary values
+            } else {
+                # use PRINT_CONV from tag table if PrintConv not defined
+                next unless defined($conv = $tagInfo->{Table}->{PRINT_CONV});
+            }
+        }
+        # save old ValueConv value if we want Both
+        $valueConv = $value if $type eq 'Both' and $convType eq 'PrintConv';
+        my ($i, $val, $vals, @values, $convList);
+        # split into list if conversion is an array
+        if (ref $conv eq 'ARRAY') {
+            $convList = $conv;
+            $conv = $$convList[0];
+            my @valList = split ' ', $value;
+            $value = \@valList;
+        }
+        # initialize array so we can iterate over values in list
+        if (ref $value eq 'ARRAY') {
+            $i = 0;
+            $vals = $value;
+            $val = $$vals[0];
+        } else {
+            $val = $value;
+        }
+        # loop through all values in list
+        for (;;) {
+            if (defined $conv) {
+                # get values of required tags if this is a composite tag
+                if (ref $val eq 'HASH' and not @val) {
+                    foreach (keys %$val) {
+                        $raw[$_] = $self->{VALUE}->{$$val{$_}};
+                        ($val[$_], $prt[$_]) = $self->GetValue($$val{$_}, 'Both');
+                        next if defined $val[$_] or not $tagInfo->{Require}->{$_};
+                        return wantarray ? () : undef;
+                    }
+                    # set $val to $val[0], or \@val for a CODE ref conversion
+                    $val = ref $conv eq 'CODE' ? \@val : $val[0];
+                }
+                if (ref $conv eq 'HASH') {
+                    # look up converted value in hash
+                    unless (defined($value = $$conv{$val})) {
+                        if ($$conv{BITMASK}) {
+                            $value = DecodeBits($val, $$conv{BITMASK});
+                        } else {
+                            if ($$tagInfo{PrintHex} and $val and IsInt($val) and
+                                $convType eq 'PrintConv')
+                            {
+                                $val = sprintf('0x%x',$val);
+                            }
+                            $value = "Unknown ($val)";
+                        }
+                    }
+                } else {
+                    # call subroutine or do eval to convert value
+                    local $SIG{'__WARN__'} = \&SetWarning;
+                    undef $evalWarning;
+                    if (ref $conv eq 'CODE') {
+                        $value = &$conv($val, $self);
+                    } else {
+                        #### eval ValueConv/PrintConv ($val, $self, @val, @prt, @raw)
+                        $value = eval $conv;
+                        $@ and $evalWarning = $@;
+                    }
+                    if ($evalWarning) {
+                        delete $SIG{'__WARN__'};
+                        warn "$convType $tag: " . CleanWarning() . "\n";
+                    }
+                }
+            } else {
+                $value = $val;
+            }
+            last unless $vals;
+            # save this converted value and step to next value in list
+            push @values, $value if defined $value;
+            if (++$i >= scalar(@$vals)) {
+                $value = \@values if @values;
+                last;
+            }
+            $val = $$vals[$i];
+            $conv = $$convList[$i] if $convList;
+        }
+        # return undefined now if no value
+        return wantarray ? () : undef unless defined $value;
+        # join back into single value if split for conversion list
+        if ($convList and ref $value eq 'ARRAY') {
+            $value = join($convType eq 'PrintConv' ? '; ' : ' ', @$value);
+        }
+    }
+    if ($type eq 'Both') {
+        # $valueConv is undefined if there was no print conversion done
+        $valueConv = $value unless defined $valueConv;
+        # return Both values as a list (ValueConv, PrintConv)
+        return ($valueConv, $value);
+    }
+    if (ref $value eq 'ARRAY') {
+        # return array if requested
+        return @$value if wantarray;
+        # return list reference for Raw, ValueConv or if List option set
+        return $value if @convTypes < 2 or $self->{OPTIONS}->{List};
+        # otherwise join in comma-separated string
+        $value = join ', ', @$value;
+    }
+    return $value;
+}
+
+#------------------------------------------------------------------------------
+# Get tag identification number
+# Inputs: 0) ExifTool object reference, 1) tag key
+# Returns: Tag ID if available, otherwise ''
+sub GetTagID($$)
+{
+    local $_;
+    my ($self, $tag) = @_;
+    my $tagInfo = $self->{TAG_INFO}->{$tag};
+
+    if ($tagInfo) {
+        GenerateAllTagIDs();    # make sure tag ID's are generated
+        defined $$tagInfo{TagID} and return $$tagInfo{TagID};
+    }
+    # no ID for this tag (shouldn't happen)
+    return '';
+}
+
+#------------------------------------------------------------------------------
+# Get description for specified tag
+# Inputs: 0) ExifTool object reference, 1) tag key
+# Returns: Tag description
+# Notes: Will always return a defined value, even if description isn't available
+sub GetDescription($$)
+{
+    local $_;
+    my ($self, $tag) = @_;
+    my $tagInfo = $self->{TAG_INFO}->{$tag};
+    # ($tagInfo should be defined for any extracted tag,
+    # but we might as well handle the case where it isn't)
+    my $desc;
+    $desc = $$tagInfo{Description} if $tagInfo;
+    # just make the tag more readable if description doesn't exist
+    unless ($desc) {
+        $desc = MakeDescription(GetTagName($tag));
+        # save description in tag information
+        $$tagInfo{Description} = $desc if $tagInfo;
+    }
+    return $desc;
+}
+
+#------------------------------------------------------------------------------
+# Get group name for specified tag
+# Inputs: 0) ExifTool object reference
+#         1) tag key (or reference to tagInfo hash, not part of the public API)
+#         2) [optional] group family number (-1 to get extended group list)
+# Returns: Scalar context: Group name (for family 0 if not otherwise specified)
+#          Array context: Group name if family specified, otherwise list of
+#          group names for each family.
+sub GetGroup($$;$)
+{
+    local $_;
+    my ($self, $tag, $family) = @_;
+    my ($tagInfo, @groups, $extra);
+    if (ref $tag eq 'HASH') {
+        $tagInfo = $tag;
+        $tag = $tagInfo->{Name};
+    } else {
+        $tagInfo = $self->{TAG_INFO}->{$tag} or return '';
+    }
+    my $groups = $$tagInfo{Groups};
+    # fill in default groups unless already done
+    unless ($$tagInfo{GotGroups}) {
+        my $tagTablePtr = $$tagInfo{Table};
+        if ($tagTablePtr) {
+            # construct our group list
+            $groups or $groups = $$tagInfo{Groups} = { };
+            # fill in default groups
+            foreach (keys %{$$tagTablePtr{GROUPS}}) {
+                $$groups{$_} or $$groups{$_} = $tagTablePtr->{GROUPS}->{$_};
+            }
+        }
+        # set flag indicating group list was built
+        $$tagInfo{GotGroups} = 1;
+    }
+    if (defined $family and $family >= 0) {
+        return $$groups{$family} || 'Other' unless $family == 1;
+        $groups[$family] = $$groups{$family};
+    } else {
+        return $$groups{0} unless wantarray;
+        foreach (0..2) { $groups[$_] = $$groups{$_}; }
+    }
+    # modify family 1 group name if necessary
+    if ($extra = $self->{GROUP1}->{$tag}) {
+        if ($extra =~ /^\+(.*)/) {
+            $groups[1] .= $1;
+        } else {
+            $groups[1] = $extra;
+        }
+    }
+    if ($family) {
+        return $groups[1] if $family == 1;
+        # add additional matching group names to list
+        # ie) for MIE-Doc, also add MIE1, MIE1-Doc, MIE-Doc1 and MIE1-Doc1
+        # and for MIE2-Doc3, also add MIE2, MIE-Doc3, MIE2-Doc and MIE-Doc
+        if ($groups[1] =~ /^MIE(\d*)-(.+?)(\d*)$/) {
+            push @groups, 'MIE' . ($1 || '1');
+            push @groups, 'MIE' . ($1 ? '' : '1') . "-$2$3";
+            push @groups, "MIE$1-$2" . ($3 ? '' : '1');
+            push @groups, 'MIE' . ($1 ? '' : '1') . "-$2" . ($3 ? '' : '1');
+        }
+    }
+    return @groups;
+}
+
+#------------------------------------------------------------------------------
+# Get group names for specified tags
+# Inputs: 0) ExifTool object reference
+#         1) [optional] information hash reference (default all extracted info)
+#         2) [optional] group family number (default 0)
+# Returns: List of group names in alphabetical order
+sub GetGroups($;$$)
+{
+    local $_;
+    my $self = shift;
+    my $info = shift;
+    my $family;
+
+    # figure out our arguments
+    if (ref $info ne 'HASH') {
+        $family = $info;
+        $info = $self->{VALUE};
+    } else {
+        $family = shift;
+    }
+    $family = 0 unless defined $family;
+
+    # get a list of all groups in specified information
+    my ($tag, %groups);
+    foreach $tag (keys %$info) {
+        $groups{ $self->GetGroup($tag, $family) } = 1;
+    }
+    return sort keys %groups;
+}
+
+#------------------------------------------------------------------------------
+# Set priority for group where new values are written
+# Inputs: 0) ExifTool object reference,
+#         1-N) group names (reset to default if no groups specified)
+sub SetNewGroups($;@)
+{
+    local $_;
+    my ($self, @groups) = @_;
+    @groups or @groups = @defaultWriteGroups;
+    my $count = @groups;
+    my %priority;
+    foreach (@groups) {
+        $priority{lc($_)} = $count--;
+    }
+    $priority{file} = 10;       # 'File' group is always written (Comment)
+    $priority{composite} = 10;  # 'Composite' group is always written
+    # set write priority (higher # is higher priority)
+    $self->{WRITE_PRIORITY} = \%priority;
+    $self->{WRITE_GROUPS} = \@groups;
+}
+
+#------------------------------------------------------------------------------
+# Build composite tags from required tags
+# Inputs: 0) ExifTool object reference
+# Note: Tag values are calculated in alphabetical order unless a tag Require's
+#       or Desire's another composite tag, in which case the calculation is
+#       deferred until after the other tag is calculated.
+sub BuildCompositeTags($)
+{
+    local $_;
+    my $self = shift;
+
+    # first, add user-defined composite tags if necessary
+    if (defined %UserDefined and $UserDefined{'Image::ExifTool::Composite'}) {
+        AddCompositeTags($UserDefined{'Image::ExifTool::Composite'},1);
+        delete $UserDefined{'Image::ExifTool::Composite'};
+    }
+    my @tagList = sort keys %Image::ExifTool::Composite;
+    my %tagsUsed;
+
+    my $rawValue = $self->{VALUE};
+    for (;;) {
+        my %notBuilt;
+        foreach (@tagList) {
+            $notBuilt{$_} = 1;
+        }
+        my @deferredTags;
+        my $tag;
+COMPOSITE_TAG:
+        foreach $tag (@tagList) {
+            next if $specialTags{$tag};
+            my $tagInfo = $self->GetTagInfo(\%Image::ExifTool::Composite, $tag);
+            next unless $tagInfo;
+            # put required tags into array and make sure they all exist
+            my (%tagKey, $type, $found);
+            foreach $type ('Require','Desire') {
+                my $req = $$tagInfo{$type} or next;
+                # save Require'd and Desire'd tag values in list
+                my $index;
+                foreach $index (keys %$req) {
+                    my $reqTag = $$req{$index};
+                    # allow tag group to be specified
+                    if ($reqTag =~ /(.+?):(.+)/) {
+                        my ($reqGroup, $name) = ($1, $2);
+                        my $family;
+                        $family = $1 if $reqGroup =~ s/^(\d+)//;
+                        my $i = 0;
+                        for (;;++$i) {
+                            $reqTag = $name;
+                            $reqTag .= " ($i)" if $i;
+                            last unless defined $$rawValue{$reqTag};
+                            my @groups = $self->GetGroup($reqTag, $family);
+                            last if grep { $reqGroup eq $_ } @groups;
+                        }
+                    } elsif ($notBuilt{$reqTag}) {
+                        # calculate this tag later if it relies on another
+                        # Composite tag which hasn't been calculated yet
+                        push @deferredTags, $tag;
+                        next COMPOSITE_TAG;
+                    }
+                    if (defined $$rawValue{$reqTag}) {
+                        $found = 1;
+                    } else {
+                        # don't continue if we require this tag
+                        $type eq 'Require' and next COMPOSITE_TAG;
+                    }
+                    $tagKey{$index} = $reqTag;
+                }
+            }
+            delete $notBuilt{$tag}; # this tag is OK to build now
+            next unless $found;     # can't build tag if no values found
+            # keep track of all require'd tag keys
+            foreach (keys %tagKey) {
+                # only tag keys with same name as a composite tag can be replaced
+                # (also eliminates keys with instance numbers which can't be replaced either)
+                next unless $Image::ExifTool::Composite{$tagKey{$_}};
+                my $keyRef = \$tagKey{$_};
+                $tagsUsed{$$keyRef} or $tagsUsed{$$keyRef} = [ ];
+                push @{$tagsUsed{$$keyRef}}, $keyRef;
+            }
+            # save reference to tag key lookup as value for composite tag
+            my $key = $self->FoundTag($tagInfo, \%tagKey);
+            # check to see if we just replaced one of the tag keys we require'd
+            next unless defined $key and $tagsUsed{$key};
+            foreach (@{$tagsUsed{$key}}) {
+                $$_ = $self->{MOVED_KEY};   # replace with new tag key
+            }
+            delete $tagsUsed{$key};         # can't be replaced again
+        }
+        last unless @deferredTags;
+        if (@deferredTags == @tagList) {
+            # everything was deferred in the last pass,
+            # must be a circular dependency
+            warn "Circular dependency in Composite tags\n";
+            last;
+        }
+        @tagList = @deferredTags; # calculate deferred tags now
+    }
+}
+
+#------------------------------------------------------------------------------
+# Get tag name (removes copy index)
+# Inputs: 0) Tag key
+# Returns: Tag name
+sub GetTagName($)
+{
+    local $_;
+    $_[0] =~ /^(\S+)/;
+    return $1;
+}
+
+#------------------------------------------------------------------------------
+# Get list of shortcuts
+# Returns: Shortcut list (sorted alphabetically)
+sub GetShortcuts()
+{
+    local $_;
+    require Image::ExifTool::Shortcuts;
+    return sort keys %Image::ExifTool::Shortcuts::Main;
+}
+
+#------------------------------------------------------------------------------
+# Get file type for specified extension
+# Inputs: 0) file name or extension (case is not significant)
+#         1) flag to return long description instead of type
+# Returns: File type (or desc) or undef if extension not supported.  In array
+#          context, may return more than one file type if the file may be
+#          different formats.  Returns list of all recognized extensions if no
+#          file specified
+sub GetFileType(;$$)
+{
+    local $_;
+    my ($file, $desc) = @_;
+    return sort keys %fileTypeLookup unless defined $file;
+    my $fileType;
+    my $fileExt = GetFileExtension($file);
+    $fileExt = uc($file) unless $fileExt;
+    $fileExt and $fileType = $fileTypeLookup{$fileExt}; # look up the file type
+    return $$fileType[1] if $desc;  # return description if specified
+    $fileType = $$fileType[0];      # get file type (or list of types)
+    if (wantarray) {
+        return () unless $fileType;
+        return @$fileType if ref $fileType eq 'ARRAY';
+    } elsif ($fileType) {
+        $fileType = $fileExt if ref $fileType eq 'ARRAY';
+    }
+    return $fileType;
+}
+
+#------------------------------------------------------------------------------
+# Return true if we can write the specified file type
+# Inputs: 0) file name or ext,
+# Returns: true if writable, 0 if not writable, undef if unrecognized
+# Note: This will return true for some TIFF-based RAW images which we shouldn't really write
+sub CanWrite($)
+{
+    local $_;
+    my $file = shift or return undef;
+    my $type = GetFileType($file) or return undef;
+    return scalar(grep /^$type$/, @writeTypes);
+}
+
+#------------------------------------------------------------------------------
+# Return true if we can create the specified file type
+# Inputs: 0) file name or ext,
+# Returns: true if creatable, 0 if not writable, undef if unrecognized
+sub CanCreate($)
+{
+    local $_;
+    my $file = shift or return undef;
+    my $type = GetFileType($file) or return undef;
+    return scalar(grep /^$type$/, @createTypes);
+}
+
+#==============================================================================
+# Functions below this are not part of the public API
+
+# Initialize member variables
+# Inputs: 0) ExifTool object reference
+sub Init($)
+{
+    local $_;
+    my $self = shift;
+    # delete all DataMember variables (lower-case names)
+    foreach (keys %$self) {
+        /[a-z]/ and delete $self->{$_};
+    }
+    delete $self->{FOUND_TAGS};     # list of found tags
+    delete $self->{EXIF_DATA};      # the EXIF data block
+    delete $self->{EXIF_POS};       # EXIF position in file
+    delete $self->{FIRST_EXIF_POS}; # position of first EXIF in file
+    delete $self->{EXIF_BYTE_ORDER};# the EXIF byte ordering
+    delete $self->{HTML_DUMP};      # html dump information
+    $self->{BASE}       = 0;        # base for offsets from start of file
+    $self->{FILE_ORDER} = { };      # hash of tag order in file
+    $self->{VALUE}      = { };      # hash of raw tag values
+    $self->{TAG_INFO}   = { };      # hash of tag information
+    $self->{GROUP1}     = { };      # hash of family 1 group names
+    $self->{PRIORITY}   = { };      # priority of current tags
+    $self->{PROCESSED}  = { };      # hash of processed directory start positions
+    $self->{DIR_COUNT}  = { };      # count various types of directories
+    $self->{NUM_FOUND}  = 0;        # total number of tags found (incl. duplicates)
+    $self->{CHANGED}    = 0;        # number of tags changed (writer only)
+    $self->{INDENT}     = '  ';     # initial indent for verbose messages
+    $self->{PRIORITY_DIR} = '';     # the priority directory name
+    $self->{TIFF_TYPE}  = '';       # type of TIFF data (APP1, TIFF, NEF, etc...)
+    $self->{CameraMake} = '';       # camera make
+    $self->{CameraModel}= '';       # camera model
+    $self->{CameraType} = '';       # Olympus camera type
+    if ($self->Options('HtmlDump')) {
+        require Image::ExifTool::HtmlDump;
+        $self->{HTML_DUMP} = new Image::ExifTool::HtmlDump;
+    }
+    # make sure our TextOut is a file reference
+    $self->{OPTIONS}->{TextOut} = \*STDOUT unless ref $self->{OPTIONS}->{TextOut};
+}
+
+#------------------------------------------------------------------------------
+# Parse function arguments and set member variables accordingly
+# Inputs: Same as ImageInfo()
+# - sets REQUESTED_TAGS, REQ_TAG_LOOKUP, IO_TAG_LIST, FILENAME, RAF, OPTIONS
+sub ParseArguments($;@)
+{
+    my $self = shift;
+    my $options = $self->{OPTIONS};
+    my @exclude;
+    my @oldGroupOpts = grep /^Group/, keys %{$self->{OPTIONS}};
+    my $wasExcludeOpt;
+
+    $self->{REQUESTED_TAGS} = [ ];
+    $self->{REQ_TAG_LOOKUP} = { };
+    $self->{IO_TAG_LIST} = undef;
+
+    # handle our input arguments
+    while (@_) {
+        my $arg = shift;
+        if (ref $arg) {
+            if (ref $arg eq 'ARRAY') {
+                $self->{IO_TAG_LIST} = $arg;
+                foreach (@$arg) {
+                    if (/^-(.*)/) {
+                        push @exclude, $1;
+                    } else {
+                        push @{$self->{REQUESTED_TAGS}}, $_;
+                    }
+                }
+            } elsif (ref $arg eq 'HASH') {
+                my $opt;
+                foreach $opt (keys %$arg) {
+                    # a single new group option overrides all old group options
+                    if (@oldGroupOpts and $opt =~ /^Group/) {
+                        foreach (@oldGroupOpts) {
+                            delete $options->{$_};
+                        }
+                        undef @oldGroupOpts;
+                    }
+                    $options->{$opt} = $$arg{$opt};
+                    $opt eq 'Exclude' and $wasExcludeOpt = 1;
+                }
+            } elsif (ref $arg eq 'SCALAR' or UNIVERSAL::isa($arg,'GLOB')) {
+                next if defined $self->{RAF};
+                # convert image data from UTF-8 to character stream if necessary
+                # (patches RHEL 3 UTF8 LANG problem)
+                if (ref $arg eq 'SCALAR' and eval 'require Encode; Encode::is_utf8($$arg)') {
+                    my $buff = pack('C*', unpack('U0U*', $$arg));
+                    $arg = \$buff;
+                }
+                $self->{RAF} = new File::RandomAccess($arg);
+                # set filename to empty string to indicate that
+                # we have a file but we didn't open it
+                $self->{FILENAME} = '';
+            } else {
+                warn "Don't understand ImageInfo argument $arg\n";
+            }
+        } elsif (defined $self->{FILENAME}) {
+            if ($arg =~ /^-(.*)/) {
+                push @exclude, $1;
+            } else {
+                push @{$self->{REQUESTED_TAGS}}, $arg;
+            }
+        } else {
+            $self->{FILENAME} = $arg;
+        }
+    }
+    # expand shortcuts in tag arguments if provided
+    if (@{$self->{REQUESTED_TAGS}}) {
+        ExpandShortcuts($self->{REQUESTED_TAGS});
+        # initialize lookup for requested tags
+        foreach (@{$self->{REQUESTED_TAGS}}) {
+            $self->{REQ_TAG_LOOKUP}->{lc(/.+?:(.+)/ ? $1 : $_)} = 1;
+        }
+    }
+
+    if (@exclude or $wasExcludeOpt) {
+        # must add existing excluded tags
+        if ($options->{Exclude}) {
+            if (ref $options->{Exclude} eq 'ARRAY') {
+                push @exclude, @{$options->{Exclude}};
+            } else {
+                push @exclude, $options->{Exclude};
+            }
+        }
+        $options->{Exclude} = \@exclude;
+        # expand shortcuts in new exclude list
+        ExpandShortcuts($options->{Exclude});
+    }
+}
+
+#------------------------------------------------------------------------------
+# Set list of found tags
+# Inputs: 0) ExifTool object reference
+# Returns: Reference to found tags list (in order of requested tags)
+sub SetFoundTags($)
+{
+    my $self = shift;
+    my $options = $self->{OPTIONS};
+    my $reqTags = $self->{REQUESTED_TAGS} || [ ];
+    my $duplicates = $options->{Duplicates};
+    my $exclude = $options->{Exclude};
+    my $fileOrder = $self->{FILE_ORDER};
+    my @groupOptions = sort grep /^Group/, keys %$options;
+    my $doDups = $duplicates || $exclude || @groupOptions;
+    my ($tag, $rtnTags);
+
+    # only return requested tags if specified
+    if (@$reqTags) {
+        $rtnTags or $rtnTags = [ ];
+        # scan through the requested tags and generate a list of tags we found
+        my $tagHash = $self->{VALUE};
+        my $reqTag;
+        foreach $reqTag (@$reqTags) {
+            my (@matches, $group, $family, $allGrp, $allTag);
+            if ($reqTag =~ /^(\d+)?(.+?):(.+)/) {
+                ($family, $group, $tag) = ($1, $2, $3);
+                $allGrp = 1 if $group =~ /^(\*|all)$/i;
+                $family = -1 unless defined $family;
+            } else {
+                $tag = $reqTag;
+                $family = -1;
+            }
+            if (defined $tagHash->{$reqTag} and not $doDups) {
+                $matches[0] = $tag;
+            } elsif ($tag =~ /^(\*|all)$/i) {
+                # tag name of '*' or 'all' matches all tags
+                if ($doDups or $allGrp) {
+                    @matches = keys %$tagHash;
+                } else {
+                    @matches = grep(!/ /, keys %$tagHash);
+                }
+                next unless @matches;   # don't want entry in list for '*' tag
+                $allTag = 1;
+            } elsif ($doDups or defined $group) {
+                # must also look for tags like "Tag (1)"
+                @matches = grep(/^$tag(\s|$)/i, keys %$tagHash);
+            } else {
+                # find first matching value
+                # (use in list context to return value instead of count)
+                ($matches[0]) = grep /^$tag$/i, keys %$tagHash;
+                defined $matches[0] or undef @matches;
+            }
+            if (defined $group and not $allGrp) {
+                # keep only specified group
+                my @grpMatches;
+                foreach (@matches) {
+                    my @groups = $self->GetGroup($_, $family);
+                    next unless grep /^$group$/i, @groups;
+                    push @grpMatches, $_;
+                }
+                @matches = @grpMatches;
+                next unless @matches or not $allTag;
+            }
+            if (@matches > 1) {
+                # maintain original file order for multiple tags
+                @matches = sort { $$fileOrder{$a} <=> $$fileOrder{$b} } @matches;
+                # return only the highest priority tag unless duplicates wanted
+                unless ($doDups or $allTag or $allGrp) {
+                    $tag = shift @matches;
+                    my $oldPriority = $self->{PRIORITY}->{$tag} || 1;
+                    foreach (@matches) {
+                        my $priority = $self->{PRIORITY}->{$_};
+                        $priority = 1 unless defined $priority;
+                        next unless $priority >= $oldPriority;
+                        $tag = $_;
+                        $oldPriority = $priority || 1;
+                    }
+                    @matches = ( $tag );
+                }
+            } elsif (not @matches) {
+                # put entry in return list even without value (value is undef)
+                $matches[0] = "$tag (0)";
+                # bogus file order entry to avoid warning if sorting in file order
+                $self->{FILE_ORDER}->{$matches[0]} = 999;
+            }
+            push @$rtnTags, @matches;
+        }
+    } else {
+        # no requested tags, so we want all tags
+        my @allTags;
+        if ($doDups) {
+            @allTags = keys %{$self->{VALUE}};
+        } else {
+            foreach (keys %{$self->{VALUE}}) {
+                # only include tag if it doesn't end in a copy number
+                push @allTags, $_ unless / /;
+            }
+        }
+        $rtnTags = \@allTags;
+    }
+
+    # filter excluded tags and group options
+    while (($exclude or @groupOptions) and @$rtnTags) {
+        if ($exclude) {
+            my @filteredTags;
+EX_TAG:     foreach $tag (@$rtnTags) {
+                my $tagName = GetTagName($tag);
+                my @matches = grep /(^|:)($tagName|\*|all)$/i, @$exclude;
+                foreach (@matches) {
+                    next EX_TAG unless /^(\d+)?(.+?):/;
+                    my ($family, $group) = ($1, $2);
+                    next EX_TAG if $group =~ /^(\*|all)$/i;
+                    $family = -1 unless defined $family;
+                    my @groups = $self->GetGroup($tag, $family);
+                    next EX_TAG if grep /^$group$/i, @groups;
+                }
+                push @filteredTags, $tag;
+            }
+            $rtnTags = \@filteredTags;      # use new filtered tag list
+            last if $duplicates and not @groupOptions;
+        }
+        # filter groups if requested, or to remove duplicates
+        my (%keepTags, %wantGroup, $family, $groupOpt);
+        my $allGroups = 1;
+        # build hash of requested/excluded group names for each group family
+        my $wantOrder = 0;
+        foreach $groupOpt (@groupOptions) {
+            $groupOpt =~ /^Group(\d*)/ or next;
+            $family = $1 || 0;
+            $wantGroup{$family} or $wantGroup{$family} = { };
+            my $groupList;
+            if (ref $options->{$groupOpt} eq 'ARRAY') {
+                $groupList = $options->{$groupOpt};
+            } else {
+                $groupList = [ $options->{$groupOpt} ];
+            }
+            foreach (@$groupList) {
+                # groups have priority in order they were specified
+                ++$wantOrder;
+                my ($groupName, $want);
+                if (/^-(.*)/) {
+                    # excluded group begins with '-'
+                    $groupName = $1;
+                    $want = 0;          # we don't want tags in this group
+                } else {
+                    $groupName = $_;
+                    $want = $wantOrder; # we want tags in this group
+                    $allGroups = 0;     # don't want all groups if we requested one
+                }
+                $wantGroup{$family}->{$groupName} = $want;
+            }
+        }
+        # loop through all tags and decide which ones we want
+        my (@tags, %bestTag);
+GR_TAG: foreach $tag (@$rtnTags) {
+            my $wantTag = $allGroups;   # want tag by default if want all groups
+            foreach $family (keys %wantGroup) {
+                my $group = $self->GetGroup($tag, $family);
+                my $wanted = $wantGroup{$family}->{$group};
+                next unless defined $wanted;
+                next GR_TAG unless $wanted;     # skip tag if group excluded
+                # take lowest non-zero want flag
+                next if $wantTag and $wantTag < $wanted;
+                $wantTag = $wanted;
+            }
+            next unless $wantTag;
+            if ($duplicates) {
+                push @tags, $tag;
+            } else {
+                my $tagName = GetTagName($tag);
+                my $bestTag = $bestTag{$tagName};
+                if (defined $bestTag) {
+                    next if $wantTag > $keepTags{$bestTag};
+                    if ($wantTag == $keepTags{$bestTag}) {
+                        # want two tags with the same name -- keep the latest one
+                        if ($tag =~ / \((\d+)\)$/) {
+                            my $tagNum = $1;
+                            next if $bestTag !~ / \((\d+)\)$/ or $1 > $tagNum;
+                        }
+                    }
+                    # this tag is better, so delete old best tag
+                    delete $keepTags{$bestTag};
+                }
+                $keepTags{$tag} = $wantTag;    # keep this tag (for now...)
+                $bestTag{$tagName} = $tag;      # this is our current best tag
+            }
+        }
+        unless ($duplicates) {
+            # construct new tag list with no duplicates, preserving order
+            foreach $tag (@$rtnTags) {
+                push @tags, $tag if $keepTags{$tag};
+            }
+        }
+        $rtnTags = \@tags;
+        last;
+    }
+
+    # save found tags and return reference
+    return $self->{FOUND_TAGS} = $rtnTags;
+}
+
+#------------------------------------------------------------------------------
+# Utility to load our write routines if required (called via AUTOLOAD)
+# Inputs: 0) autoload function, 1-N) function arguments
+# Returns: result of function or dies if function not available
+# To Do: Generalize this routine so it works on systems that don't use '/'
+#        as a path name separator.
+sub DoAutoLoad(@)
+{
+    my $autoload = shift;
+    my @callInfo = split(/::/, $autoload);
+    my $file = 'Image/ExifTool/Write';
+
+    return if $callInfo[$#callInfo] eq 'DESTROY';
+    if (@callInfo == 4) {
+        # load Image/ExifTool/WriteMODULE.pl
+        $file .= "$callInfo[2].pl";
+    } else {
+        # load Image/ExifTool/Writer.pl
+        $file .= 'r.pl';
+    }
+    # attempt to load the package
+    eval "require '$file'" or die "Error while attempting to call $autoload\n$@\n";
+    unless (defined &$autoload) {
+        my @caller = caller(0);
+        # reproduce Perl's standard 'undefined subroutine' message:
+        die "Undefined subroutine $autoload called at $caller[1] line $caller[2]\n";
+    }
+    no strict 'refs';
+    return &$autoload(@_);     # call the function
+}
+
+#------------------------------------------------------------------------------
+# AutoLoad our writer routines when necessary
+#
+sub AUTOLOAD
+{
+    return DoAutoLoad($AUTOLOAD, @_);
+}
+
+#------------------------------------------------------------------------------
+# Add warning tag
+# Inputs: 0) ExifTool object reference, 1) warning message, 2) true if minor
+# Returns: true if warning tag was added
+sub Warn($$;$)
+{
+    my ($self, $str, $ignorable) = @_;
+    if ($ignorable) {
+        return 0 if $self->{OPTIONS}->{IgnoreMinorErrors};
+        $str = "[minor] $str";
+    }
+    $self->FoundTag('Warning', $str);
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Add error tag
+# Inputs: 0) ExifTool object reference, 1) error message, 2) true if minor
+# Returns: true if error tag was added, otherwise warning was added
+sub Error($$;$)
+{
+    my ($self, $str, $ignorable) = @_;
+    if ($ignorable) {
+        if ($self->{OPTIONS}->{IgnoreMinorErrors}) {
+            $self->Warn($str);
+            return 0;
+        }
+        $str = "[minor] $str";
+    }
+    $self->FoundTag('Error', $str);
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Expand shortcuts
+# Inputs: 0) reference to list of tags
+# Notes: Handles leading '-' for excluded tags, group names, and redirected tags
+sub ExpandShortcuts($)
+{
+    my $tagList = shift || return;
+
+    require Image::ExifTool::Shortcuts;
+
+    # expand shortcuts
+    my @expandedTags;
+    my ($entry, $tag, $excl);
+    foreach $entry (@$tagList) {
+        # remove leading '-'
+        ($excl, $tag) = $entry =~ /^(-?)(.*)/s;
+        my ($post, @post);
+        # handle redirection
+        if ($tag =~ /(.+?)([-+]?[<>].+)/s and not $excl) {
+            ($tag, $post) = ($1, $2);
+            if ($post =~ /^[-+]?>/ or $post !~ /\$/) {
+                # expand shortcuts in postfix (rhs of redirection)
+                my ($op, $p2, $t2) = ($post =~ /([-+]?[<>])(.+?:)?(.+)/);
+                $p2 = '' unless defined $p2;
+                my ($match) = grep /^\Q$t2\E$/i, keys %Image::ExifTool::Shortcuts::Main;
+                if ($match) {
+                    foreach (@{$Image::ExifTool::Shortcuts::Main{$match}}) {
+                        /^-/ and next;  # ignore excluded tags
+                        if ($p2 and /(.+?:)(.+)/) {
+                            push @post, "$op$_";
+                        } else {
+                            push @post, "$op$p2$_";
+                        }
+                    }
+                    next unless @post;
+                    $post = shift @post;
+                }
+            }
+        } else {
+            $post = '';
+        }
+        # handle group names
+        my $pre;
+        if ($tag =~ /(.+?:)(.+)/) {
+            ($pre, $tag) = ($1, $2);
+        } else {
+            $pre = '';
+        }
+        # loop over all postfixes
+        for (;;) {
+            # expand the tag name
+            my ($match) = grep /^\Q$tag\E$/i, keys %Image::ExifTool::Shortcuts::Main;
+            if ($match) {
+                if ($excl) {
+                    # entry starts with '-', so exclude all tags in this shortcut
+                    foreach (@{$Image::ExifTool::Shortcuts::Main{$match}}) {
+                        /^-/ and next;  # ignore excluded exclude tags
+                        # group of expanded tag takes precedence
+                        if ($pre and /(.+?:)(.+)/) {
+                            push @expandedTags, "$excl$_";
+                        } else {
+                            push @expandedTags, "$excl$pre$_";
+                        }
+                    }
+                } elsif (length $pre or length $post) {
+                    foreach (@{$Image::ExifTool::Shortcuts::Main{$match}}) {
+                        /(-?)(.+?:)?(.+)/;
+                        if ($2) {
+                            # group from expanded tag takes precedence
+                            push @expandedTags, "$_$post";
+                        } else {
+                            push @expandedTags, "$1$pre$3$post";
+                        }
+                    }
+                } else {
+                    push @expandedTags, @{$Image::ExifTool::Shortcuts::Main{$match}};
+                }
+            } else {
+                push @expandedTags, "$excl$pre$tag$post";
+            }
+            last unless @post;
+            $post = shift @post;
+        }
+    }
+    @$tagList = @expandedTags;
+}
+
+#------------------------------------------------------------------------------
+# Add hash of composite tags to our composites
+# Inputs: 0) hash reference to table of composite tags to add or module name,
+#         1) overwrite existing tag
+sub AddCompositeTags($;$)
+{
+    local $_;
+    my ($add, $overwrite) = @_;
+    my $module;
+    unless (ref $add) {
+        $module = $add;
+        $add .= '::Composite';
+        no strict 'refs';
+        $add = \%$add;
+    }
+    my $defaultGroups = $$add{GROUPS};
+
+    # make sure default groups are defined in families 0 and 1
+    if ($defaultGroups) {
+        $defaultGroups->{0} or $defaultGroups->{0} = 'Composite';
+        $defaultGroups->{1} or $defaultGroups->{1} = 'Composite';
+        $defaultGroups->{2} or $defaultGroups->{2} = 'Other';
+    } else {
+        $defaultGroups = $$add{GROUPS} = { 0 => 'Composite', 1 => 'Composite', 2 => 'Other' };
+    }
+    SetupTagTable($add);
+    my $tagID;
+    foreach $tagID (keys %$add) {
+        next if $specialTags{$tagID};   # must skip special tags
+        my $tagInfo = $$add{$tagID};
+        # tagID's MUST be the exact tag name for logic in BuildCompositeTags()
+        my $tag = $$tagInfo{Name};
+        $$tagInfo{Module} = $module if $$tagInfo{Writable};
+        # allow composite tags with the same name
+        my ($t, $n, $type);
+        while ($Image::ExifTool::Composite{$tag} and not $overwrite) {
+            $n ? $n += 1 : $n = 2, $t = $tag;
+            $tag = "${t}_$n";
+        }
+        # convert scalar Require/Desire entries
+        foreach $type ('Require','Desire') {
+            my $req = $$tagInfo{$type} or next;
+            $$tagInfo{$type} = { 0 => $req } if ref($req) ne 'HASH';
+        }
+        # add this composite tag to our main composite table
+        $$tagInfo{Table} = \%Image::ExifTool::Composite;
+        $Image::ExifTool::Composite{$tag} = $tagInfo;
+        # set all default groups in tag
+        my $groups = $$tagInfo{Groups};
+        $groups or $groups = $$tagInfo{Groups} = { };
+        # fill in default groups
+        foreach (keys %$defaultGroups) {
+            $$groups{$_} or $$groups{$_} = $$defaultGroups{$_};
+        }
+        # set flag indicating group list was built
+        $$tagInfo{GotGroups} = 1;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Expand tagInfo Flags
+# Inputs: 0) tagInfo hash ref
+# Notes: $$tagInfo{Flags} must be defined to call this routine
+sub ExpandFlags($)
+{
+    my $tagInfo = shift;
+    my $flags = $$tagInfo{Flags};
+    if (ref $flags eq 'ARRAY') {
+        foreach (@$flags) {
+            $$tagInfo{$_} = 1;
+        }
+    } elsif (ref $flags eq 'HASH') {
+        my $key;
+        foreach $key (keys %$flags) {
+            $$tagInfo{$key} = $$flags{$key};
+        }
+    } else {
+        $$tagInfo{$flags} = 1;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Set up tag table (must be done once for each tag table used)
+# Inputs: 0) Reference to tag table
+# Notes: - generates 'Name' field from key if it doesn't exist
+#        - stores 'Table' pointer
+#        - expands 'Flags' for quick lookup
+sub SetupTagTable($)
+{
+    my $tagTablePtr = shift;
+    my $tagID;
+    foreach $tagID (TagTableKeys($tagTablePtr)) {
+        my @infoArray = GetTagInfoList($tagTablePtr,$tagID);
+        # process conditional tagInfo arrays
+        my $tagInfo;
+        foreach $tagInfo (@infoArray) {
+            $$tagInfo{Table} = $tagTablePtr;
+            my $tag = $$tagInfo{Name};
+            unless (defined $tag) {
+                # generate name equal to tag ID if 'Name' doesn't exist
+                $tag = $tagID;
+                $$tagInfo{Name} = ucfirst($tag); # make first char uppercase
+            }
+            $$tagInfo{Flags} and ExpandFlags($tagInfo);
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# Utilities to check for numerical types
+# Inputs: 0) value;  Returns: true if value is a numerical type
+# Notes: May change commas to decimals in floats for use in other locales
+sub IsFloat($) {
+    return 1 if $_[0] =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
+    # allow comma separators (for other locales)
+    return 0 unless $_[0] =~ /^([+-]?)(?=\d|,\d)\d*(,\d*)?([Ee]([+-]?\d+))?$/;
+    $_[0] =~ tr/,/./;   # but translate ',' to '.'
+    return 1;
+}
+sub IsInt($)   { return scalar($_[0] =~ /^[+-]?\d+$/); }
+sub IsHex($)   { return scalar($_[0] =~ /^(0x)?[0-9a-f]{1,8}$/i); }
+
+# round floating point value to specified number of significant digits
+# Inputs: 0) value, 1) number of sig digits;  Returns: rounded number
+sub RoundFloat($$)
+{
+    my ($val, $sig) = @_;
+    $val == 0 and return 0;
+    my $sign = $val < 0 ? ($val=-$val, -1) : 1;
+    my $log = log($val) / log(10);
+    my $exp = int($log) - $sig + ($log > 0 ? 1 : 0);
+    return $sign * int(10 ** ($log - $exp) + 0.5) * 10 ** $exp;
+}
+
+#------------------------------------------------------------------------------
+# Utility routines to for reading binary data values from file
+
+my $swapBytes;               # set if EXIF header is not native byte ordering
+my $swapWords;               # swap 32-bit words in doubles (ARM quirk)
+my $currentByteOrder = 'MM'; # current byte ordering ('II' or 'MM')
+my %unpackMotorola = ( S => 'n', L => 'N', C => 'C', c => 'c' );
+my %unpackIntel    = ( S => 'v', L => 'V', C => 'C', c => 'c' );
+my %unpackStd = %unpackMotorola;
+
+# Swap bytes in data if necessary
+# Inputs: 0) data, 1) number of bytes
+# Returns: swapped data
+sub SwapBytes($$)
+{
+    return $_[0] unless $swapBytes;
+    my ($val, $bytes) = @_;
+    my $newVal = '';
+    $newVal .= substr($val, $bytes, 1) while $bytes--;
+    return $newVal;
+}
+# Swap words.  Inputs: 8 bytes of data, Returns: swapped data
+sub SwapWords($)
+{
+    return $_[0] unless $swapWords and length($_[0]) == 8;
+    return substr($_[0],4,4) . substr($_[0],0,4)
+}
+
+# Unpack value, letting unpack() handle byte swapping
+# Inputs: 0) unpack template, 1) data reference, 2) offset
+# Returns: unpacked number
+# - uses value of %unpackStd to determine the unpack template
+# - can only be called for 'S' or 'L' templates since these are the only
+#   templates for which you can specify the byte ordering.
+sub DoUnpackStd(@)
+{
+    $_[2] and return unpack("x$_[2] $unpackStd{$_[0]}", ${$_[1]});
+    return unpack($unpackStd{$_[0]}, ${$_[1]});
+}
+# Pack value
+# Inputs: 0) template, 1) value, 2) data ref (or undef), 3) offset (if data ref)
+# Returns: packed value
+sub DoPackStd(@)
+{
+    my $val = pack($unpackStd{$_[0]}, $_[1]);
+    $_[2] and substr(${$_[2]}, $_[3], length($val)) = $val;
+    return $val;
+}
+
+# Unpack value, handling the byte swapping manually
+# Inputs: 0) # bytes, 1) unpack template, 2) data reference, 3) offset
+# Returns: unpacked number
+# - uses value of $swapBytes to determine byte ordering
+sub DoUnpack(@)
+{
+    my ($bytes, $template, $dataPt, $pos) = @_;
+    my $val;
+    if ($swapBytes) {
+        $val = '';
+        $val .= substr($$dataPt,$pos+$bytes,1) while $bytes--;
+    } else {
+        $val = substr($$dataPt,$pos,$bytes);
+    }
+    defined($val) or return undef;
+    return unpack($template,$val);
+}
+
+# Unpack double value
+# Inputs: 0) unpack template, 1) data reference, 2) offset
+# Returns: unpacked number
+sub DoUnpackDbl(@)
+{
+    my ($template, $dataPt, $pos) = @_;
+    my $val = substr($$dataPt,$pos,8);
+    defined($val) or return undef;
+    # swap bytes and 32-bit words (ARM quirk) if necessary, then unpack value
+    return unpack($template, SwapWords(SwapBytes($val, 8)));
+}
+
+# Inputs: 0) data reference, 1) offset into data
+sub Get8s($$)     { return DoUnpackStd('c', @_); }
+sub Get8u($$)     { return DoUnpackStd('C', @_); }
+sub Get16s($$)    { return DoUnpack(2, 's', @_); }
+sub Get16u($$)    { return DoUnpackStd('S', @_); }
+sub Get32s($$)    { return DoUnpack(4, 'l', @_); }
+sub Get32u($$)    { return DoUnpackStd('L', @_); }
+sub GetFloat($$)  { return DoUnpack(4, 'f', @_); }
+sub GetDouble($$) { return DoUnpackDbl('d', @_); }
+
+sub GetRational32s($$)
+{
+    my ($dataPt, $pos) = @_;
+    my $denom = Get16s($dataPt, $pos + 2) or return 'inf';
+    # round off to a reasonable number of significant figures
+    return RoundFloat(Get16s($dataPt,$pos) / $denom, 7);
+}
+sub GetRational32u($$)
+{
+    my ($dataPt, $pos) = @_;
+    my $denom = Get16u($dataPt, $pos + 2) or return 'inf';
+    return RoundFloat(Get16u($dataPt,$pos) / $denom, 7);
+}
+sub GetRational64s($$)
+{
+    my ($dataPt, $pos) = @_;
+    my $denom = Get32s($dataPt, $pos + 4) or return 'inf';
+    return RoundFloat(Get32s($dataPt,$pos) / $denom, 10);
+}
+sub GetRational64u($$)
+{
+    my ($dataPt, $pos) = @_;
+    my $denom = Get32u($dataPt, $pos + 4) or return 'inf';
+    return RoundFloat(Get32u($dataPt,$pos) / $denom, 10);
+}
+sub GetFixed16s($$)
+{
+    my ($dataPt, $pos) = @_;
+    my $val = Get16s($dataPt, $pos) / 0x100;
+    return int($val * 1000 + ($val<0 ? -0.5 : 0.5)) / 1000;
+}
+sub GetFixed16u($$)
+{
+    my ($dataPt, $pos) = @_;
+    return int((Get16u($dataPt, $pos) / 0x100) * 1000 + 0.5) / 1000;
+}
+sub GetFixed32s($$)
+{
+    my ($dataPt, $pos) = @_;
+    my $val = Get32s($dataPt, $pos) / 0x10000;
+    # remove insignificant digits
+    return int($val * 1e5 + ($val>0 ? 0.5 : -0.5)) / 1e5;
+}
+sub GetFixed32u($$)
+{
+    my ($dataPt, $pos) = @_;
+    # remove insignificant digits
+    return int((Get32u($dataPt, $pos) / 0x10000) * 1e5 + 0.5) / 1e5;
+}
+# Inputs: 0) value, 1) data ref, 2) offset
+sub Set8s(@)  { return DoPackStd('c', @_); }
+sub Set8u(@)  { return DoPackStd('C', @_); }
+sub Set16u(@) { return DoPackStd('S', @_); }
+sub Set32u(@) { return DoPackStd('L', @_); }
+
+#------------------------------------------------------------------------------
+# Get current byte order ('II' or 'MM')
+sub GetByteOrder() { return $currentByteOrder; }
+
+#------------------------------------------------------------------------------
+# Set byte ordering
+# Inputs: 0) 'II'=intel, 'MM'=motorola
+# Returns: 1 on success
+sub SetByteOrder($)
+{
+    my $order = shift;
+
+    if ($order eq 'MM') {       # big endian (Motorola)
+        %unpackStd = %unpackMotorola;
+    } elsif ($order eq 'II') {  # little endian (Intel)
+        %unpackStd = %unpackIntel;
+    } else {
+        return 0;
+    }
+    my $val = unpack('S','A ');
+    my $nativeOrder;
+    if ($val == 0x4120) {       # big endian
+        $nativeOrder = 'MM';
+    } elsif ($val == 0x2041) {  # little endian
+        $nativeOrder = 'II';
+    } else {
+        warn sprintf("Unknown native byte order! (pattern %x)\n",$val);
+        return 0;
+    }
+    $currentByteOrder = $order;  # save current byte order
+
+    # swap bytes if our native CPU byte ordering is not the same as the EXIF
+    $swapBytes = ($order ne $nativeOrder);
+
+    # little-endian ARM has big-endian words for doubles (thanks Riku Voipio)
+    # (Note: Riku's patch checked for '0ff3', but I think it should be 'f03f' since
+    # 1 is '000000000000f03f' on an x86 -- so check for both, but which is correct?)
+    my $pack1d = pack('d', 1);
+    $swapWords = ($pack1d eq "\0\0\x0f\xf3\0\0\0\0" or
+                  $pack1d eq "\0\0\xf0\x3f\0\0\0\0");
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Change byte order
+sub ToggleByteOrder()
+{
+    SetByteOrder(GetByteOrder() eq 'II' ? 'MM' : 'II');
+}
+
+#------------------------------------------------------------------------------
+# hash lookups for reading values from data
+my %formatSize = (
+    int8s => 1,
+    int8u => 1,
+    int16s => 2,
+    int16u => 2,
+    int32s => 4,
+    int32u => 4,
+    int64s => 8,
+    int64u => 8,
+    rational32s => 4,
+    rational32u => 4,
+    rational64s => 8,
+    rational64u => 8,
+    fixed16s => 2,
+    fixed16u => 2,
+    fixed32s => 4,
+    fixed32u => 4,
+    float => 4,
+    double => 8,
+    extended => 10,
+    string => 1,
+    binary => 1,
+   'undef' => 1,
+    ifd => 4,
+    ifd8 => 8,
+);
+my %readValueProc = (
+    int8s => \&Get8s,
+    int8u => \&Get8u,
+    int16s => \&Get16s,
+    int16u => \&Get16u,
+    int32s => \&Get32s,
+    int32u => \&Get32u,
+    int64s => \&Get64s,
+    int64u => \&Get64u,
+    rational32s => \&GetRational32s,
+    rational32u => \&GetRational32u,
+    rational64s => \&GetRational64s,
+    rational64u => \&GetRational64u,
+    fixed16s => \&GetFixed16s,
+    fixed16u => \&GetFixed16u,
+    fixed32s => \&GetFixed32s,
+    fixed32u => \&GetFixed32u,
+    float => \&GetFloat,
+    double => \&GetDouble,
+    extended => \&GetExtended,
+    ifd => \&Get32u,
+    ifd8 => \&Get64u,
+);
+sub FormatSize($) { return $formatSize{$_[0]}; }
+
+#------------------------------------------------------------------------------
+# Read value from binary data (with current byte ordering)
+# Inputs: 0) data reference, 1) value offset, 2) format string,
+#         3) number of values (or undef to use all data)
+#         4) valid data length relative to offset
+# Returns: converted value, or undefined if data isn't there
+#          or list of values in list context
+sub ReadValue($$$$$)
+{
+    my ($dataPt, $offset, $format, $count, $size) = @_;
+
+    my $len = $formatSize{$format};
+    unless ($len) {
+        warn "Unknown format $format";
+        $len = 1;
+    }
+    unless ($count) {
+        return '' if defined $count or $size < $len;
+        $count = int($size / $len);
+    }
+    # make sure entry is inside data
+    if ($len * $count > $size) {
+        $count = int($size / $len);     # shorten count if necessary
+        $count < 1 and return undef;    # return undefined if no data
+    }
+    my @vals;
+    my $proc = $readValueProc{$format};
+    if ($proc) {
+        for (;;) {
+            push @vals, &$proc($dataPt, $offset);
+            last if --$count <= 0;
+            $offset += $len;
+        }
+    } else {
+        # handle undef/binary/string
+        $vals[0] = substr($$dataPt, $offset, $count);
+        # truncate string at null terminator if necessary
+        $vals[0] =~ s/\0.*//s if $format eq 'string';
+    }
+    if (wantarray) {
+        return @vals;
+    } elsif (@vals > 1) {
+        return join(' ', @vals);
+    } else {
+        return $vals[0];
+    }
+}
+
+#------------------------------------------------------------------------------
+# Convert UTF-8 to current character set
+# Inputs: 0) ExifTool ref, 1) UTF-8 string
+# Return: Converted string
+sub UTF82Charset($$)
+{
+    my ($self, $val) = @_;
+    if ($self->{OPTIONS}->{Charset} eq 'Latin' and $val =~ /[\x80-\xff]/) {
+        $val = Image::ExifTool::UTF82Unicode($val,'n',$self);
+        $val = Image::ExifTool::Unicode2Latin($val,'n',$self);
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Convert Latin to current character set
+# Inputs: 0) ExifTool ref, 1) Latin string
+# Return: Converted string
+sub Latin2Charset($$)
+{
+    my ($self, $val) = @_;
+    if ($self->{OPTIONS}->{Charset} eq 'UTF8' and $val =~ /[\x80-\xff]/) {
+        $val = Image::ExifTool::Latin2Unicode($val,'n');
+        $val = Image::ExifTool::Unicode2UTF8($val,'n');
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Decode bit mask
+# Inputs: 0) value to decode, 1) Reference to hash for decoding (or undef)
+#         2) optional bits per word (defaults to 32)
+sub DecodeBits($$;$)
+{
+    my ($vals, $lookup, $bits) = @_;
+    $bits or $bits = 32;
+    my ($val, $i, @bitList);
+    my $num = 0;
+    foreach $val (split ' ', $vals) {
+        for ($i=0; $i<$bits; ++$i) {
+            next unless $val & (1 << $i);
+            my $n = $i + $num;
+            if (not $lookup) {
+                push @bitList, $n;
+            } elsif ($$lookup{$n}) {
+                push @bitList, $$lookup{$n};
+            } else {
+                push @bitList, "[$n]";
+            }
+        }
+        $num += $bits;
+    }
+    return '(none)' unless @bitList;
+    return join($lookup ? ', ' : ',', @bitList);
+}
+
+#------------------------------------------------------------------------------
+# Validate an extracted image and repair if necessary
+# Inputs: 0) ExifTool object reference, 1) image reference, 2) tag name
+# Returns: image reference or undef if it wasn't valid
+sub ValidateImage($$$)
+{
+    my ($self, $imagePt, $tag) = @_;
+    return undef if $$imagePt eq 'none';
+    unless ($$imagePt =~ /^(Binary data|\xff\xd8\xff)/ or
+            # the first byte of the preview of some Minolta cameras is wrong,
+            # so check for this and set it back to 0xff if necessary
+            $$imagePt =~ s/^.(\xd8\xff\xdb)/\xff$1/ or
+            $self->Options('IgnoreMinorErrors'))
+    {
+        # issue warning only if the tag was specifically requested
+        if ($self->{REQ_TAG_LOOKUP}->{lc($tag)}) {
+            $self->Warn("$tag is not a valid JPEG image",1);
+            return undef;
+        }
+    }
+    return $imagePt;
+}
+
+#------------------------------------------------------------------------------
+# Make description from a tag name
+# Inputs: 0) tag name 1) optional tagID to add at end of description
+# Returns: description
+sub MakeDescription($;$)
+{
+    my ($tag, $tagID) = @_;
+    # start with the tag name and force first letter to be upper case
+    my $desc = ucfirst($tag);
+    $desc =~ tr/_/ /;       # translate underlines to spaces
+    # put a space between lower/UPPER case and lower/number combinations
+    $desc =~ s/([a-z])([A-Z\d])/$1 $2/g;
+    # put a space between acronyms and words
+    $desc =~ s/([A-Z])([A-Z][a-z])/$1 $2/g;
+    # put spaces after numbers (if more than one character following number)
+    $desc =~ s/(\d)([A-Z]\S)/$1 $2/g;
+    # remove space in hex number
+    $desc =~ s/ 0x ([\dA-Fa-f])/ 0x$1/g;
+    $desc .= ' ' . $tagID if defined $tagID;
+    return $desc;
+}
+
+#------------------------------------------------------------------------------
+# Return printable value
+# Inputs: 0) ExifTool object reference
+#         1) value to print, 2) true for unlimited line length
+sub Printable($;$)
+{
+    my ($self, $outStr, $unlimited) = @_;
+    return '(undef)' unless defined $outStr;
+    $outStr =~ tr/\x01-\x1f\x7f-\xff/./;
+    $outStr =~ s/\x00//g;
+    # limit length if verbose < 4
+    if (length($outStr) > 60 and not $unlimited and $self->{OPTIONS}->{Verbose} < 4) {
+        $outStr = substr($outStr,0,54) . '[snip]';
+    }
+    return $outStr;
+}
+
+#------------------------------------------------------------------------------
+# Convert date/time from Exif format
+# Inputs: 0) ExifTool object reference, 1) Date/time in EXIF format
+# Returns: Formatted date/time string
+sub ConvertDateTime($$)
+{
+    my ($self, $date) = @_;
+    my $dateFormat = $self->{OPTIONS}->{DateFormat};
+    # only convert date if a format was specified and the date is recognizable
+    if ($dateFormat) {
+        if ($date =~ /^(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)/ and eval 'require POSIX') {
+            $date = POSIX::strftime($dateFormat, $6, $5, $4, $3, $2-1, $1-1900);
+        } elsif ($self->{OPTIONS}->{StrictDate}) {
+            undef $date;
+        }
+    }
+    return $date;
+}
+
+#------------------------------------------------------------------------------
+# Convert Unix time to EXIF date/time string
+# Inputs: 0) Unix time value, 1) non-zero to use local instead of GMT time
+# Returns: EXIF date/time string
+sub ConvertUnixTime($;$)
+{
+    my $time = shift;
+    return '0000:00:00 00:00:00' if $time == 0;
+    my @tm = shift() ? localtime($time) : gmtime($time);
+    return sprintf("%4d:%.2d:%.2d %.2d:%.2d:%.2d", $tm[5]+1900, $tm[4]+1,
+                   $tm[3], $tm[2], $tm[1], $tm[0]);
+}
+
+#------------------------------------------------------------------------------
+# Get Unix time from EXIF-formatted date/time string
+# Inputs: 0) EXIF date/time string, 1) non-zero to use local instead of GMT time
+# Returns: Unix time or undefined on error
+sub GetUnixTime($;$)
+{
+    my $timeStr = shift;
+    return 0 if $timeStr eq '0000:00:00 00:00:00';
+    my @tm = ($timeStr =~ /^(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)/);
+    return undef unless @tm == 6;
+    return undef unless eval 'require Time::Local';
+    $tm[0] -= 1900;     # convert year
+    $tm[1] -= 1;        # convert month
+    @tm = reverse @tm;  # change to order required by timelocal()
+    return shift() ? Time::Local::timelocal(@tm) : Time::Local::timegm(@tm);
+}
+
+#------------------------------------------------------------------------------
+# Save information for HTML dump
+# Inputs: 0) ExifTool hash ref, 1) start offset, 2) data size
+#         3) comment string, 4) tool tip (or SAME), 5) flags
+sub HtmlDump($$$$;$$)
+{
+    my $self = shift;
+    my $pos = shift;
+    $pos += $$self{BASE} if $$self{BASE};
+    $$self{HTML_DUMP} and $self->{HTML_DUMP}->Add($pos, @_);
+}
+
+#------------------------------------------------------------------------------
+# JPEG constants
+my %jpegMarker = (
+    0x01 => 'TEM',
+    0xc0 => 'SOF0', # to SOF15, with a few exceptions below
+    0xc4 => 'DHT',
+    0xc8 => 'JPGA',
+    0xcc => 'DAC',
+    0xd0 => 'RST0',
+    0xd8 => 'SOI',
+    0xd9 => 'EOI',
+    0xda => 'SOS',
+    0xdb => 'DQT',
+    0xdc => 'DNL',
+    0xdd => 'DRI',
+    0xde => 'DHP',
+    0xdf => 'EXP',
+    0xe0 => 'APP0', # to APP15
+    0xf0 => 'JPG0',
+    0xfe => 'COM',
+);
+
+#------------------------------------------------------------------------------
+# Get JPEG marker name
+# Inputs: 0) Jpeg number
+# Returns: marker name
+sub JpegMarkerName($)
+{
+    my $marker = shift;
+    my $markerName = $jpegMarker{$marker};
+    unless ($markerName) {
+        $markerName = $jpegMarker{$marker & 0xf0};
+        if ($markerName and $markerName =~ /^([A-Z]+)\d+$/) {
+            $markerName = $1 . ($marker & 0x0f);
+        } else {
+            $markerName = sprintf("marker 0x%.2x", $marker);
+        }
+    }
+    return $markerName;
+}
+
+#------------------------------------------------------------------------------
+# Identify trailer ending at specified offset from end of file
+# Inputs: 0) RAF reference, 1) offset from end of file (0 by default)
+# Returns: Trailer info hash (with RAF and DirName set),
+#          or undef if no recognized trailer was found
+# Notes: leaves file position unchanged
+sub IdentifyTrailer($;$)
+{
+    my $raf = shift;
+    my $offset = shift || 0;
+    my $pos = $raf->Tell();
+    my ($buff, $type, $len);
+    while ($raf->Seek(-$offset, 2) and ($len = $raf->Tell()) > 0) {
+        # read up to 64 bytes before specified offset from end of file
+        $len = 64 if $len > 64;
+        $raf->Seek(-$len, 1) and $raf->Read($buff, $len) == $len or last;
+        if ($buff =~ /AXS(!|\*).{8}$/s) {
+            $type = 'AFCP';
+        } elsif ($buff =~ /\xa1\xb2\xc3\xd4$/) {
+            $type = 'FotoStation';
+        } elsif ($buff =~ /cbipcbbl$/) {
+            $type = 'PhotoMechanic';
+        } elsif ($buff =~ /^CANON OPTIONAL DATA\0/) {
+            $type = 'CanonVRD';
+        } elsif ($buff =~ /~\0\x04\0zmie~\0\0\x06.{4}[\x10\x18]\x04$/s or
+                 $buff =~ /~\0\x04\0zmie~\0\0\x0a.{8}[\x10\x18]\x08$/s)
+        {
+            $type = 'MIE';
+        }
+        last;
+    }
+    $raf->Seek($pos, 0);    # restore original file position
+    return $type ? { RAF => $raf, DirName => $type } : undef;
+}
+
+#------------------------------------------------------------------------------
+# Extract EXIF information from a jpg image
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref with RAF set
+# Returns: 1 on success, 0 if this wasn't a valid JPEG file
+sub ProcessJPEG($$)
+{
+    my ($self, $dirInfo) = @_;
+    my ($ch,$s,$length);
+    my $verbose = $self->{OPTIONS}->{Verbose};
+    my $out = $self->{OPTIONS}->{TextOut};
+    my $raf = $$dirInfo{RAF};
+    my $htmlDump = $self->{HTML_DUMP};
+    my %dumpParms = ( Out => $out );
+    my ($success, $icc_profile, $wantPreview, $trailInfo);
+
+    # check to be sure this is a valid JPG file
+    return 0 unless $raf->Read($s, 2) == 2 and $s eq "\xff\xd8";
+    $dumpParms{MaxLen} = 128 if $verbose < 4;
+    $self->SetFileType();   # set FileType tag
+    if ($htmlDump) {
+        my $pos = $raf->Tell() - 2;
+        $self->HtmlDump(0, $pos, '[unknown header]') if $pos;
+        $self->HtmlDump($pos, 2, 'JPEG header', 'SOI Marker');
+    }
+
+    # set input record separator to 0xff (the JPEG marker) to make reading quicker
+    my $oldsep = $/;
+    $/ = "\xff";
+
+    my ($nextMarker, $nextSegDataPt, $nextSegPos, $combinedSegData, $dumpEnd);
+
+    # read file until we reach an end of image (EOI) or start of scan (SOS)
+    Marker: for (;;) {
+        # set marker and data pointer for current segment
+        my $marker = $nextMarker;
+        my $segDataPt = $nextSegDataPt;
+        my $segPos = $nextSegPos;
+        undef $nextMarker;
+        undef $nextSegDataPt;
+#
+# read ahead to the next segment unless we have reached EOI or SOS
+#
+        unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantPreview))) {
+            # read up to next marker (JPEG markers begin with 0xff)
+            my $buff;
+            $raf->ReadLine($buff) or last;
+            # JPEG markers can be padded with unlimited 0xff's
+            for (;;) {
+                $raf->Read($ch, 1) or last Marker;
+                $nextMarker = ord($ch);
+                last unless $nextMarker == 0xff;
+            }
+            # read data for all markers except 0xd9 (EOI) and stand-alone
+            # markers 0x00, 0x01 and 0xd0-0xd7 (NULL, TEM, RST0-RST7)
+            if ($nextMarker!=0xd9 and $nextMarker!=0x00 and $nextMarker!=0x01 and
+                ($nextMarker<0xd0 or $nextMarker>0xd7))
+            {
+                # read record length word
+                last unless $raf->Read($s, 2) == 2;
+                my $len = unpack('n',$s);   # get data length
+                last unless defined($len) and $len >= 2;
+                $nextSegPos = $raf->Tell();
+                $len -= 2;  # subtract size of length word
+                last unless $raf->Read($buff, $len) == $len;
+                $nextSegDataPt = \$buff;    # set pointer to our next data
+            }
+            # read second segment too if this was the first
+            next unless defined $marker;
+        }
+        # set some useful variables for the current segment
+        my $hdr = "\xff" . chr($marker);    # header for this segment
+        my $markerName = JpegMarkerName($marker);
+#
+# parse the current segment
+#
+        # handle SOF markers: SOF0-SOF15, except DHT(0xc4), JPGA(0xc8) and DAC(0xcc)
+        if (($marker & 0xf0) == 0xc0 and ($marker == 0xc0 or $marker & 0x03)) {
+            $length = length $$segDataPt;
+            if ($verbose) {
+                print $out "JPEG $markerName ($length bytes):\n";
+                HexDump($segDataPt, undef, %dumpParms, Addr=>$segPos) if $verbose>2;
+            }
+            next unless $length >= 6;
+            # extract some useful information
+            my ($p, $h, $w, $n) = unpack('Cn2C', $$segDataPt);
+            my $sof = GetTagTable('Image::ExifTool::JPEG::SOF');
+            $self->FoundTag($$sof{ImageWidth}, $w);
+            $self->FoundTag($$sof{ImageHeight}, $h);
+            $self->FoundTag($$sof{EncodingProcess}, $marker - 0xc0);
+            $self->FoundTag($$sof{BitsPerSample}, $p);
+            $self->FoundTag($$sof{ColorComponents}, $n);
+            next unless $n == 3 and $length >= 15;
+            my ($i, $hmin, $hmax, $vmin, $vmax);
+            # loop through all components to determine sampling frequency
+            for ($i=0; $i<$n; ++$i) {
+                my $sf = Get8u($segDataPt, 7 + 3 * $i);
+                # isolate horizontal and vertical components
+                my ($hf, $vf) = ($sf >> 4, $sf & 0x0f);
+                unless ($i) {
+                    $hmin = $hmax = $hf;
+                    $vmin = $vmax = $vf;
+                    next;
+                }
+                # determine min/max frequencies
+                $hmin = $hf if $hf < $hmin;
+                $hmax = $hf if $hf > $hmax;
+                $vmin = $vf if $vf < $vmin;
+                $vmax = $vf if $vf > $vmax;
+            }
+            if ($hmin and $vmin) {
+                my ($hs, $vs) = ($hmax / $hmin, $vmax / $vmin);
+                $self->FoundTag($$sof{YCbCrSubSampling}, "$hs $vs");
+            }
+            next;
+        } elsif ($marker == 0xd9) {         # EOI
+            $verbose and print $out "JPEG EOI\n";
+            my $pos = $raf->Tell();
+            if ($htmlDump and $dumpEnd) {
+                $self->HtmlDump($dumpEnd, $pos-2-$dumpEnd, '[JPEG Image Data]', undef, 0x08);
+                $self->HtmlDump($pos-2, 2, 'JPEG EOI', undef);
+                $dumpEnd = 0;
+            }
+            $success = 1;
+            # we are here because we are looking for trailer information
+            if ($wantPreview and $self->{VALUE}->{PreviewImageStart}) {
+                my $buff;
+                # most previews start right after the JPEG EOI, but the Olympus E-20
+                # preview is 508 bytes into the trailer, and the K-M Maxxum 7D preview
+                # is 979 bytes in, but Minolta previews can have a random first byte...
+                if ($raf->Read($buff, 1024) and ($buff =~ /\xff\xd8\xff./g or
+                    ($self->{CameraMake} =~ /Minolta/i and $buff =~ /.\xd8\xff\xdb/g)))
+                {
+                    # adjust PreviewImageStart to this location
+                    my $start = $self->{VALUE}->{PreviewImageStart};
+                    my $actual = $pos + pos($buff) - 4;
+                    if ($start ne $actual and $verbose > 1) {
+                        print $out "(Fixed PreviewImage location: $start -> $actual)\n";
+                    }
+                    $self->{VALUE}->{PreviewImageStart} = $actual;
+                }
+                $raf->Seek($pos, 0);
+            }
+            # process trailer now or finish processing trailers
+            # and scan for AFCP if necessary
+            my $fromEnd = 0;
+            if ($trailInfo) {
+                $$trailInfo{ScanForAFCP} = 1;   # scan now if necessary
+                $self->ProcessTrailers($trailInfo);
+                # save offset from end of file to start of first trailer
+                $fromEnd = $$trailInfo{Offset};
+                undef $trailInfo;
+            }
+            # finally, dump remaining information in JPEG trailer
+            if ($verbose or $htmlDump) {
+                $raf->Seek(0, 2);
+                my $endPos = $raf->Tell() - $fromEnd;
+                $self->DumpUnknownTrailer({
+                    RAF => $raf,
+                    DataPos => $pos,
+                    DirLen => $endPos - $pos
+                }) if $endPos > $pos;
+            }
+            last;       # all done parsing file
+        } elsif ($marker == 0xda) {         # SOS
+            # all done with meta information unless we have a trailer
+            $verbose and print $out "JPEG SOS\n";
+            unless ($self->Options('FastScan')) {
+                $trailInfo = IdentifyTrailer($raf);
+                # process trailer now unless we are doing verbose dump
+                if ($trailInfo and $verbose < 3 and not $htmlDump) {
+                    # process trailers (keep trailInfo to finish processing later
+                    # only if we can't finish without scanning from end of file)
+                    $self->ProcessTrailers($trailInfo) and undef $trailInfo;
+                }
+                if ($wantPreview) {
+                    # seek ahead and validate preview image
+                    my $buff;
+                    my $curPos = $raf->Tell();
+                    if ($raf->Seek($self->GetValue('PreviewImageStart'), 0) and
+                        $raf->Read($buff, 4) == 4 and
+                        $buff =~ /^.\xd8\xff[\xc4\xdb\xe0-\xef]/)
+                    {
+                        undef $wantPreview;
+                    }
+                    $raf->Seek($curPos, 0) or last;
+                }
+                next if $trailInfo or $wantPreview or $verbose > 2 or $htmlDump;
+            }
+            # nothing interesting to parse after start of scan (SOS)
+            $success = 1;
+            last;   # all done parsing file
+        } elsif ($marker==0x00 or $marker==0x01 or ($marker>=0xd0 and $marker<=0xd7)) {
+            # handle stand-alone markers 0x00, 0x01 and 0xd0-0xd7 (NULL, TEM, RST0-RST7)
+            $verbose and $marker and print $out "JPEG $markerName:\n";
+            next;
+        }
+        # handle all other markers
+        my $dumpType = '';
+        $length = length $$segDataPt;
+        if ($verbose) {
+            print $out "JPEG $markerName ($length bytes):\n";
+            if ($verbose > 2) {
+                my %extraParms = ( Addr => $segPos );
+                $extraParms{MaxLen} = 128 if $verbose == 4;
+                HexDump($segDataPt, undef, %dumpParms, %extraParms);
+            }
+        }
+        if ($marker == 0xe0) {              # APP0 (JFIF, CIFF)
+            if ($$segDataPt =~ /^JFIF\0/) {
+                $dumpType = 'JFIF';
+                my %dirInfo = (
+                    DataPt => $segDataPt,
+                    DataPos  => $segPos,
+                    DirStart => 5,
+                    DirLen => $length - 5,
+                );
+                SetByteOrder('MM');
+                my $tagTablePtr = GetTagTable('Image::ExifTool::JFIF::Main');
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            } elsif ($$segDataPt =~ /^JFXX\0\x10/) {
+                $dumpType = 'JFXX';
+                my $tagTablePtr = GetTagTable('Image::ExifTool::JFIF::Extension');
+                my $tagInfo = $self->GetTagInfo($tagTablePtr, 0x10);
+                $self->FoundTag($tagInfo, substr($$segDataPt, 6));
+            } elsif ($$segDataPt =~ /^(II|MM).{4}HEAPJPGM/s) {
+                $dumpType = 'CIFF';
+                my %dirInfo = (
+                    RAF => new File::RandomAccess($segDataPt),
+                );
+                $self->{SET_GROUP1} = 'CIFF';
+                require Image::ExifTool::CanonRaw;
+                Image::ExifTool::CanonRaw::ProcessCRW($self, \%dirInfo);
+                delete $self->{SET_GROUP1};
+            }
+        } elsif ($marker == 0xe1) {         # APP1 (EXIF, XMP)
+            if ($$segDataPt =~ /^Exif\0/) { # (some Kodak cameras don't put a second \0)
+                undef $dumpType;    # (will be dumped here)
+                # this is EXIF data --
+                # get the data block (into a common variable)
+                my $hdrLen = length($exifAPP1hdr);
+                my %dirInfo = (
+                    Parent => $markerName,
+                    DataPt => $segDataPt,
+                    DataPos => $segPos,
+                    DirStart => $hdrLen,
+                    Base => $segPos + $hdrLen,
+                );
+                if ($htmlDump) {
+                    $self->HtmlDump($segPos-4, 4, 'APP1 header',
+                             "Data size: $length bytes");
+                    $self->HtmlDump($segPos, $hdrLen, 'Exif header',
+                             'APP1 data type: Exif');
+                    $dumpEnd = $segPos + $length;
+                }
+                # extract the EXIF information (it is in standard TIFF format)
+                $self->ProcessTIFF(\%dirInfo);
+                # avoid looking for preview unless necessary because it really slows
+                # us down -- only look for it if we found pointer, and preview is
+                # outside EXIF, and PreviewImage is specifically requested
+                my $start = $self->GetValue('PreviewImageStart');
+                my $length = $self->GetValue('PreviewImageLength');
+                if ($start and $length and
+                    $start + $length > $self->{EXIF_POS} + length($self->{EXIF_DATA}) and
+                    $self->{REQ_TAG_LOOKUP}->{previewimage})
+                {
+                    $wantPreview = 1;
+                }
+            } else {
+                # Hmmm.  Could be XMP, let's see
+                my $processed;
+                if ($$segDataPt =~ /^http/ or $$segDataPt =~ /<exif:/) {
+                    $dumpType = 'XMP';
+                    my $start = ($$segDataPt =~ /^$xmpAPP1hdr/) ? length($xmpAPP1hdr) : 0;
+                    my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
+                    my %dirInfo = (
+                        Base     => 0,
+                        DataPt   => $segDataPt,
+                        DataPos  => $segPos,
+                        DataLen  => $length,
+                        DirStart => $start,
+                        DirLen   => $length - $start,
+                        Parent   => $markerName,
+                    );
+                    $processed = $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+                }
+                if ($verbose and not $processed) {
+                    $self->Warn("Ignored EXIF block length $length (bad header)");
+                }
+            }
+        } elsif ($marker == 0xe2) {         # APP2 (ICC Profile, FPXR)
+            if ($$segDataPt =~ /^ICC_PROFILE\0/) {
+                $dumpType = 'ICC_Profile';
+                # must concatenate blocks of profile
+                my $block_num = Get8u($segDataPt, 12);
+                my $blocks_tot = Get8u($segDataPt, 13);
+                $icc_profile = '' if $block_num == 1;
+                if (defined $icc_profile) {
+                    $icc_profile .= substr($$segDataPt, 14);
+                    if ($block_num == $blocks_tot) {
+                        my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
+                        my %dirInfo = (
+                            DataPt   => \$icc_profile,
+                            DataPos  => $segPos + 14,
+                            DataLen  => length($icc_profile),
+                            DirStart => 0,
+                            DirLen   => length($icc_profile),
+                            Parent   => $markerName,
+                        );
+                        $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+                        undef $icc_profile;
+                    }
+                }
+            } elsif ($$segDataPt =~ /^FPXR\0/) {
+                $dumpType = 'FPXR';
+                my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::Main');
+                my %dirInfo = (
+                    DataPt   => $segDataPt,
+                    DataPos  => $segPos,
+                    DataLen  => $length,
+                    DirStart => 0,
+                    DirLen   => $length,
+                    Parent   => $markerName,
+                    # set flag if this is the last FPXR segment
+                    LastFPXR => not ($nextMarker==$marker and $$nextSegDataPt=~/^FPXR\0/),
+                );
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            }
+        } elsif ($marker == 0xe3) {         # APP3 (Kodak "Meta")
+            if ($$segDataPt =~ /^(Meta|META|Exif)\0\0/) {
+                undef $dumpType;    # (will be dumped here)
+                my %dirInfo = (
+                    Parent => $markerName,
+                    DataPt => $segDataPt,
+                    DataPos => $segPos,
+                    DirStart => 6,
+                    Base => $segPos + 6,
+                );
+                if ($htmlDump) {
+                    $self->HtmlDump($segPos-4, 10, 'APP3 Meta header');
+                    $dumpEnd = $segPos + $length;
+                }
+                my $tagTablePtr = GetTagTable('Image::ExifTool::Kodak::Meta');
+                $self->ProcessTIFF(\%dirInfo, $tagTablePtr);
+            }
+        } elsif ($marker == 0xe5) {         # APP5 (Ricoh "RMETA")
+            if ($$segDataPt =~ /^RMETA\0/) {
+                $dumpType = 'Ricoh RMETA';
+                my %dirInfo = (
+                    Parent => $markerName,
+                    DataPt => $segDataPt,
+                    DataPos => $segPos,
+                    DirStart => 6,
+                    Base => $segPos + 6,
+                );
+                my $tagTablePtr = GetTagTable('Image::ExifTool::Ricoh::RMETA');
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            }
+        } elsif ($marker == 0xe6) {         # APP6 (Toshiba EPPIM)
+            if ($$segDataPt =~ /^EPPIM\0/) {
+                undef $dumpType;    # (will be dumped here)
+                my %dirInfo = (
+                    Parent => $markerName,
+                    DataPt => $segDataPt,
+                    DataPos => $segPos,
+                    DirStart => 6,
+                    Base => $segPos + 6,
+                );
+                if ($htmlDump) {
+                    $self->HtmlDump($segPos-4, 10, 'APP6 EPPIM header');
+                    $dumpEnd = $segPos + $length;
+                }
+                my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::EPPIM');
+                $self->ProcessTIFF(\%dirInfo, $tagTablePtr);
+            }
+        } elsif ($marker == 0xe8) {         # APP8 (SPIFF)
+            # my sample SPIFF has 32 bytes of data, but spec states 30
+            if ($$segDataPt =~ /^SPIFF\0/ and $length == 32) {
+                $dumpType = 'SPIFF';
+                my %dirInfo = (
+                    DataPt => $segDataPt,
+                    DataPos  => $segPos,
+                    DirStart => 6,
+                    DirLen => $length - 6,
+                );
+                my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::SPIFF');
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            }
+        } elsif ($marker == 0xea) {         # APP10 (PhotoStudio Unicode comments)
+            if ($$segDataPt =~ /^UNICODE\0/) {
+                $dumpType = 'PhotoStudio';
+                my $comment = $self->Unicode2Charset(substr($$segDataPt,8), 'MM');
+                $self->FoundTag('Comment', $comment);
+            }
+        } elsif ($marker == 0xec) {         # APP12 (Ducky, Picture Info)
+            if ($$segDataPt =~ /^Ducky/) {
+                $dumpType = 'Ducky';
+                my %dirInfo = (
+                    DataPt => $segDataPt,
+                    DataPos => $segPos,
+                    DirStart => 5,
+                    DirLen => $length - 5,
+                );
+                my $tagTablePtr = GetTagTable('Image::ExifTool::APP12::Ducky');
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            } else {
+                my %dirInfo = ( DataPt => $segDataPt );
+                my $tagTablePtr = GetTagTable('Image::ExifTool::APP12::PictureInfo');
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr) and $dumpType = 'Picture Info';
+            }
+        } elsif ($marker == 0xed) {         # APP13 (Photoshop, Adobe_CM)
+            my $isOld;
+            if ($$segDataPt =~ /^$psAPP13hdr/ or ($$segDataPt =~ /^$psAPP13old/ and $isOld=1)) {
+                $dumpType = 'Photoshop';
+                # add this data to the combined data if it exists
+                if (defined $combinedSegData) {
+                    $combinedSegData .= substr($$segDataPt,length($psAPP13hdr));
+                    $segDataPt = \$combinedSegData;
+                    $length = length $combinedSegData;  # update length
+                }
+                # peek ahead to see if the next segment is photoshop data too
+                if ($nextMarker == $marker and $$nextSegDataPt =~ /^$psAPP13hdr/) {
+                    # initialize combined data if necessary
+                    $combinedSegData = $$segDataPt unless defined $combinedSegData;
+                    next;   # will handle the combined data the next time around
+                }
+                my $hdrlen = $isOld ? 27 : 14;
+                # process APP13 Photoshop record
+                my $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
+                my %dirInfo = (
+                    DataPt   => $segDataPt,
+                    DataPos  => $segPos,
+                    DataLen  => $length,
+                    DirStart => $hdrlen,    # directory starts after identifier
+                    DirLen   => $length - $hdrlen,
+                    Parent   => $markerName,
+                );
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+                undef $combinedSegData;
+            } elsif ($$segDataPt =~ /^Adobe_CM/) {
+                $dumpType = 'Adobe_CM';
+                SetByteOrder('MM');
+                my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::AdobeCM');
+                my %dirInfo = (
+                    DataPt   => $segDataPt,
+                    DataPos  => $segPos,
+                    DirStart => 8,
+                    DirLen   => $length - 8,
+                );
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            }
+        } elsif ($marker == 0xee) {         # APP14 (Adobe)
+            if ($$segDataPt =~ /^Adobe/) {
+                $dumpType = 'Adobe';
+                SetByteOrder('MM');
+                my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::Adobe');
+                my %dirInfo = (
+                    DataPt   => $segDataPt,
+                    DataPos  => $segPos,
+                    DirStart => 5,
+                    DirLen   => $length - 5,
+                );
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            }
+        } elsif ($marker == 0xef) {         # APP15 (GraphicConverter)
+            if ($$segDataPt =~ /^Q\s*(\d+)/ and $length == 4) {
+                $dumpType = 'GraphicConverter';
+                my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::GraphConv');
+                $self->HandleTag($tagTablePtr, 'Q', $1);
+            }
+        } elsif ($marker == 0xfe) {         # COM (JPEG comment)
+            $dumpType = 'Comment';
+            $self->FoundTag('Comment', $$segDataPt);
+        } elsif (($marker & 0xf0) != 0xe0) {
+            undef $dumpType;    # only dump unknown APP segments
+        }
+        if (defined $dumpType) {
+            if (not $dumpType and $self->{OPTIONS}->{Unknown}) {
+                $self->Warn("Unknown $markerName segment", 1);
+            }
+            if ($htmlDump) {
+                my $desc = $markerName . ($dumpType ? " $dumpType" : '') . ' segment';
+                $self->HtmlDump($segPos-4, $length+4, $desc, undef, 0x08);
+                $dumpEnd = $segPos + $length;
+            }
+        }
+        undef $$segDataPt;
+    }
+    $/ = $oldsep;     # restore separator to original value
+    $success or $self->Warn('JPEG format error');
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process TIFF data
+# Inputs: 0) ExifTool object reference, 1) directory information reference
+#         2) optional tag table reference
+# Returns: 1 if this looked like a valid EXIF block, 0 otherwise, or -1 on write error
+sub ProcessTIFF($$;$)
+{
+    my ($self, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $fileType = $$dirInfo{Parent} || '';
+    my $raf = $$dirInfo{RAF};
+    my $base = $$dirInfo{Base} || 0;
+    my $outfile = $$dirInfo{OutFile};
+    my ($length, $err, $canonSig);
+
+    # read the image file header and offset to 0th IFD if necessary
+    if ($raf) {
+        if ($outfile) {
+            $raf->Seek(0, 0) or return 0;
+            if ($base) {
+                $raf->Read($$dataPt, $base) == $base or return 0;
+                Write($outfile, $$dataPt) or $err = 1;
+            }
+        } else {
+            $raf->Seek($base, 0) or return 0;
+        }
+        $raf->Read($self->{EXIF_DATA}, 8) == 8 or return 0;
+    } elsif ($dataPt) {
+        # save a copy of the EXIF data
+        my $dirStart = $$dirInfo{DirStart} || 0;
+        $self->{EXIF_DATA} = substr(${$$dirInfo{DataPt}}, $dirStart);
+    } elsif ($outfile) {
+        # create TIFF information from scratch
+        $self->{EXIF_DATA} = "MM\0\x2a\0\0\0\x08";
+    } else {
+        $self->{EXIF_DATA} = '';
+    }
+    $$self{FIRST_EXIF_POS} = $base + $$self{BASE} unless defined $$self{FIRST_EXIF_POS};
+    $$self{EXIF_POS} = $base;
+    $dataPt = \$self->{EXIF_DATA};
+
+    # set byte ordering
+    SetByteOrder(substr($$dataPt,0,2)) or return 0;
+    # save EXIF byte ordering
+    $self->{EXIF_BYTE_ORDER} = GetByteOrder();
+
+    # verify the byte ordering
+    my $identifier = Get16u($dataPt, 2);
+    # identifier is 0x2a for TIFF (but 0x4f52, 0x5352 or ?? for ORF)
+  # no longer do this because ORF files use different values
+  #  return 0 unless $identifier == 0x2a;
+
+    # get offset to IFD0
+    my $offset = Get32u($dataPt, 4);
+    $offset >= 8 or return 0;
+
+    if ($raf) {
+        # Canon CR2 images usually have an offset of 16, but it may be
+        # greater if edited by PhotoMechanic, so check the 4-byte signature
+        if ($identifier == 0x2a and $offset >= 16) {
+            $raf->Read($canonSig, 8) == 8 or return 0;
+            $$dataPt .= $canonSig;
+            if ($canonSig =~ /^CR\x02\0/) {
+                $fileType = 'CR2';
+                $self->HtmlDump($base+8, 8, '[CR2 header]') if $self->{HTML_DUMP};
+            } else {
+                undef $canonSig;
+            }
+        } elsif ($identifier == 0x55 and $fileType =~ /^(RAW|TIFF)$/) {
+            $fileType = 'RAW';  # Panasonic RAW file
+            $tagTablePtr = GetTagTable('Image::ExifTool::Panasonic::Raw');
+        } elsif ($identifier == 0x2b and $fileType eq 'TIFF') {
+            # this looks like a BigTIFF image
+            $raf->Seek(0);
+            require Image::ExifTool::BigTIFF;
+            return 1 if Image::ExifTool::BigTIFF::ProcessBTF($self, $dirInfo);
+        } elsif (Get8u($dataPt, 2) == 0xbc and $fileType eq 'TIFF') {
+            $fileType = 'WDP';  # Windows Media Photo file
+        }
+        # we have a valid TIFF (or whatever) file
+        if ($fileType and not $self->{VALUE}->{FileType}) {
+            $self->SetFileType($fileType);
+        }
+    }
+    $self->FoundTag('ExifByteOrder', GetByteOrder());
+    if ($self->{HTML_DUMP}) {
+        my $o = (GetByteOrder() eq 'II') ? 'Little' : 'Big';
+        $self->HtmlDump($base, 4, "TIFF header", "Byte order: $o endian", 0);
+        $self->HtmlDump($base+4, 4, "IFD0 pointer", sprintf("Offset: 0x%.4x",$offset), 0);
+    }
+    # remember where we found the TIFF data (APP1, APP3, TIFF, NEF, etc...)
+    $self->{TIFF_TYPE} = $fileType;
+
+    # get reference to the main EXIF table
+    $tagTablePtr or $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main');
+
+    # build directory information hash
+    my %dirInfo = (
+        Base     => $base,
+        DataPt   => $dataPt,
+        DataLen  => length $$dataPt,
+        DataPos  => 0,
+        DirStart => $offset,
+        DirLen   => length $$dataPt,
+        RAF      => $raf,
+        DirName  => 'IFD0',
+        Parent   => $fileType,
+        ImageData=> 1, # set flag to get information to copy image data later
+    );
+
+    # extract information from the image
+    unless ($outfile) {
+        # process the directory
+        $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        # process GeoTiff information if available
+        if ($self->{VALUE}->{GeoTiffDirectory}) {
+            require Image::ExifTool::GeoTiff;
+            Image::ExifTool::GeoTiff::ProcessGeoTiff($self);
+        }
+        # process information in recognized trailers
+        if ($raf) {
+            my $trailInfo = IdentifyTrailer($raf);
+            if ($trailInfo) {
+                $$trailInfo{ScanForAFCP} = 1;   # scan to find AFCP if necessary
+                $self->ProcessTrailers($trailInfo);
+            }
+        }
+        return 1;
+    }
+#
+# rewrite the image
+#
+    if ($$dirInfo{NoTiffEnd}) {
+        delete $self->{TIFF_END};
+    } else {
+        # initialize TIFF_END so it will be updated by WriteExif()
+        $self->{TIFF_END} = 0;
+    }
+    if ($canonSig) {
+        # write Canon CR2 specially because it has a header we want to preserve,
+        # and possibly trailers added by the Canon utilities and/or PhotoMechanic
+        $dirInfo{OutFile} = $outfile;
+        require Image::ExifTool::CanonRaw;
+        Image::ExifTool::CanonRaw::WriteCR2($self, \%dirInfo, $tagTablePtr) or $err = 1;
+    } else {
+        # write TIFF header (8 bytes to be immediately followed by IFD)
+        $dirInfo{NewDataPos} = 8;
+        # preserve padding between image data blocks in ORF images
+        # (otherwise dcraw has problems because it assumes fixed block spacing)
+        $dirInfo{PreserveImagePadding} = 1 if $fileType eq 'ORF' or $identifier != 0x2a;
+        my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+        if (not defined $newData) {
+            $err = 1;
+        } elsif (length($newData)) {
+            my $offset = 8;
+            my $header = substr($$dataPt, 0, 4) . Set32u($offset);
+            Write($outfile, $header, $newData) or $err = 1;
+            undef $newData; # free memory
+        }
+        # copy over image data now if necessary
+        if (ref $dirInfo{ImageData} and not $err) {
+            $self->CopyImageData($dirInfo{ImageData}, $outfile) or $err = 1;
+            delete $dirInfo{ImageData};
+        }
+    }
+    # rewrite trailers if they exist
+    if ($raf and $self->{TIFF_END} and not $err) {
+        my ($buf, $trailInfo);
+        $raf->Seek(0, 2) or $err = 1;
+        my $extra = $raf->Tell() - $self->{TIFF_END};
+        # check for trailer and process if possible
+        for (;;) {
+            last unless $extra > 12;
+            $raf->Seek($self->{TIFF_END});  # seek back to end of image
+            $trailInfo = IdentifyTrailer($raf);
+            last unless $trailInfo;
+            my $tbuf = '';
+            $$trailInfo{OutFile} = \$tbuf;  # rewrite trailer(s)
+            $$trailInfo{ScanForAFCP} = 1;   # scan for AFCP if necessary
+            # rewrite all trailers to buffer
+            unless ($self->ProcessTrailers($trailInfo)) {
+                undef $trailInfo;
+                $err = 1;
+                last;
+            }
+            # calculate unused bytes before trailer
+            $extra = $$trailInfo{DataPos} - $self->{TIFF_END};
+            last; # yes, the 'for' loop was just a cheap 'goto'
+        }
+        # ignore a single zero byte if used for padding
+        # (note that Photoshop CS adds a trailer with 2 zero bytes
+        #  for some reason, and these will be preserved)
+        if ($extra > 0 and $self->{TIFF_END} & 0x01) {
+            $raf->Seek($self->{TIFF_END}, 0) or $err = 1;
+            $raf->Read($buf, 1) or $err = 1;
+            $buf eq "\0" and --$extra, ++$self->{TIFF_END};
+        }
+        if ($extra > 0) {
+            if ($self->{DEL_GROUP}->{Trailer}) {
+                $self->VPrint(0, "  Deleting unknown trailer ($extra bytes)\n");
+                ++$self->{CHANGED};
+            } else {
+                $self->VPrint(0, "  Preserving unknown trailer ($extra bytes)\n");
+                $raf->Seek($self->{TIFF_END}, 0) or $err = 1;
+                while ($extra) {
+                    my $n = $extra < 65536 ? $extra : 65536;
+                    $raf->Read($buf, $n) == $n or $err = 1, last;
+                    Write($outfile, $buf) or $err = 1, last;
+                    $extra -= $n;
+                }
+            }
+        }
+        # write trailer buffer if necessary
+        $self->WriteTrailerBuffer($trailInfo, $outfile) or $err = 1 if $trailInfo;
+        # add any new trailers we are creating
+        my $trailPt = $self->AddNewTrailers();
+        Write($outfile, $$trailPt) or $err = 1 if $trailPt;
+    }
+    delete $self->{TIFF_END};
+    return $err ? -1 : 1;
+}
+
+#------------------------------------------------------------------------------
+# Return list of tag table keys (ignoring special keys)
+# Inputs: 0) reference to tag table
+# Returns: List of table keys (unsorted)
+sub TagTableKeys($)
+{
+    local $_;
+    my $tagTablePtr = shift;
+    my @keyList;
+    foreach (keys %$tagTablePtr) {
+        push(@keyList, $_) unless $specialTags{$_};
+    }
+    return @keyList;
+}
+
+#------------------------------------------------------------------------------
+# GetTagTable
+# Inputs: 0) table name
+# Returns: tag table reference, or undefined if not found
+# Notes: Always use this function instead of requiring module and using table
+# directly since this function also does the following the first time the table
+# is loaded:
+# - requires new module if necessary
+# - generates default GROUPS hash and Group 0 name from module name
+# - registers Composite tags if Composite table found
+# - saves descriptions for tags in specified table
+# - generates default TAG_PREFIX to be used for unknown tags
+sub GetTagTable($)
+{
+    my $tableName = shift or return undef;
+
+    my $table = $allTables{$tableName};
+
+    unless ($table) {
+        no strict 'refs';
+        unless (defined %$tableName) {
+            # try to load module for this table
+            if ($tableName =~ /(.*)::/) {
+                my $module = $1;
+                unless (eval "require $module") {
+                    $@ and warn $@;
+                }
+            }
+            unless (defined %$tableName) {
+                warn "Can't find table $tableName\n";
+                return undef;
+            }
+        }
+        no strict 'refs';
+        $table = \%$tableName;
+        use strict 'refs';
+        # set default group 0 and 1 from module name unless already specified
+        my $defaultGroups = $$table{GROUPS};
+        $defaultGroups or $defaultGroups = $$table{GROUPS} = { };
+        unless ($$defaultGroups{0} and $$defaultGroups{1}) {
+            if ($tableName =~ /Image::.*?::([^:]*)/) {
+                $$defaultGroups{0} = $1 unless $$defaultGroups{0};
+                $$defaultGroups{1} = $1 unless $$defaultGroups{1};
+            } else {
+                $$defaultGroups{0} = $tableName unless $$defaultGroups{0};
+                $$defaultGroups{1} = $tableName unless $$defaultGroups{1};
+            }
+        }
+        $$defaultGroups{2} = 'Other' unless $$defaultGroups{2};
+        # generate a tag prefix for unknown tags if necessary
+        unless ($$table{TAG_PREFIX}) {
+            my $tagPrefix;
+            if ($tableName =~ /Image::.*?::(.*)::Main/ || $tableName =~ /Image::.*?::(.*)/) {
+                ($tagPrefix = $1) =~ s/::/_/g;
+            } else {
+                $tagPrefix = $tableName;
+            }
+            $$table{TAG_PREFIX} = $tagPrefix;
+        }
+        # set up the new table
+        SetupTagTable($table);
+        # add any user-defined tags
+        if (defined %UserDefined and $UserDefined{$tableName}) {
+            my $tagID;
+            foreach $tagID (TagTableKeys($UserDefined{$tableName})) {
+                my $tagInfo = $UserDefined{$tableName}->{$tagID};
+                if (ref $tagInfo eq 'HASH') {
+                    $$tagInfo{Name} or $$tagInfo{Name} = ucfirst($tagID);
+                } else {
+                    $tagInfo = { Name => $tagInfo };
+                }
+                if ($$table{WRITABLE} and not defined $$tagInfo{Writable} and
+                    not $$tagInfo{SubDirectory})
+                {
+                    $$tagInfo{Writable} = $$table{WRITABLE};
+                }
+                delete $$table{$tagID}; # replace any existing entry
+                AddTagToTable($table, $tagID, $tagInfo);
+            }
+        }
+        # generate tag ID's if necessary
+        GenerateTagIDs($table) if $didTagID;
+        # remember order we loaded the tables in
+        push @tableOrder, $tableName;
+        # insert newly loaded table into list
+        $allTables{$tableName} = $table;
+    }
+    return $table;
+}
+
+#------------------------------------------------------------------------------
+# Process an image directory
+# Inputs: 0) ExifTool object reference, 1) directory information reference
+#         2) tag table reference, 3) optional reference to processing procedure
+# Returns: Result from processing (1=success)
+sub ProcessDirectory($$$;$)
+{
+    my ($self, $dirInfo, $tagTablePtr, $processProc) = @_;
+
+    return 0 unless $tagTablePtr and $dirInfo;
+    # use default proc from tag table if no proc specified
+    $processProc or $processProc = $$tagTablePtr{PROCESS_PROC};
+    # set directory name from default group0 name if not done already
+    $$dirInfo{DirName} or $$dirInfo{DirName} = $tagTablePtr->{GROUPS}->{0};
+    # guard against cyclical recursion into the same directory
+    if (defined $$dirInfo{DirStart} and defined $$dirInfo{DataPos}) {
+        my $addr = $$dirInfo{DirStart} + $$dirInfo{DataPos} + ($$dirInfo{Base}||0);
+        if ($self->{PROCESSED}->{$addr}) {
+            $self->Warn("$$dirInfo{DirName} pointer references previous $self->{PROCESSED}->{$addr} directory");
+            return 0;
+        }
+        $self->{PROCESSED}->{$addr} = $$dirInfo{DirName};
+    }
+    # otherwise process as an EXIF directory
+    $processProc or $processProc = \&Image::ExifTool::Exif::ProcessExif;
+    my $oldOrder = GetByteOrder();
+    my $oldIndent = $self->{INDENT};
+    my $oldDir = $self->{DIR_NAME};
+    $self->{INDENT} .= '| ';
+    $self->{DIR_NAME} = $$dirInfo{DirName};
+    my $rtnVal = &$processProc($self, $dirInfo, $tagTablePtr);
+    $self->{INDENT} = $oldIndent;
+    $self->{DIR_NAME} = $oldDir;
+    SetByteOrder($oldOrder);
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Get standardized file extension
+# Inputs: 0) file name
+# Returns: standardized extension (all uppercase)
+sub GetFileExtension($)
+{
+    my $filename = shift;
+    my $fileExt;
+    if ($filename and $filename =~ /.*\.(.+)$/) {
+        $fileExt = uc($1);   # change extension to upper case
+        # convert TIF extension to TIFF because we use the
+        # extension for the file type tag of TIFF images
+        $fileExt eq 'TIF' and $fileExt = 'TIFF';
+    }
+    return $fileExt;
+}
+
+#------------------------------------------------------------------------------
+# Get list of tag information hashes for given tag ID
+# Inputs: 0) Tag table reference, 1) tag ID
+# Returns: Array of tag information references
+# Notes: Generates tagInfo hash if necessary
+sub GetTagInfoList($$)
+{
+    my ($tagTablePtr, $tagID) = @_;
+    my $tagInfo = $$tagTablePtr{$tagID};
+
+    if (ref $tagInfo eq 'HASH') {
+        return ($tagInfo);
+    } elsif (ref $tagInfo eq 'ARRAY') {
+        return @$tagInfo;
+    } elsif ($tagInfo) {
+        # create hash with name
+        $tagInfo = $$tagTablePtr{$tagID} = { Name => $tagInfo };
+        return ($tagInfo);
+    }
+    return ();
+}
+
+#------------------------------------------------------------------------------
+# Find tag information, processing conditional tags
+# Inputs: 0) ExifTool object reference, 1) tagTable pointer, 2) tag ID
+#         3) optional value reference, 4) optional format type, 5) optional value count
+# Returns: pointer to tagInfo hash, undefined if none found, or '' if $valPt needed
+# Notes: You should always call this routine to find a tag in a table because
+# this routine will evaluate conditional tags.
+# Arguments 3-5 are only required if the information type allows $valPt, $format and/or
+# $count in a Condition, and if not given when needed this routine returns ''.
+sub GetTagInfo($$$;$$$)
+{
+    my ($self, $tagTablePtr, $tagID) = @_;
+    my ($valPt, $format, $count);
+
+    my @infoArray = GetTagInfoList($tagTablePtr, $tagID);
+    # evaluate condition
+    my $tagInfo;
+    foreach $tagInfo (@infoArray) {
+        my $condition = $$tagInfo{Condition};
+        if ($condition) {
+            ($valPt, $format, $count) = splice(@_, 3) if @_ > 3;
+            return '' if $condition =~ /\$(valPt|format|count)\b/ and not defined $valPt;
+            # set old value for use in condition if needed
+            my $oldVal = $self->{VALUE}->{$$tagInfo{Name}};
+            #### eval Condition ($self, $oldVal, [$valPt, $format, $count])
+            unless (eval $condition) {
+                $@ and warn "Condition $$tagInfo{Name}: $@";
+                next;
+            }
+        }
+        if ($$tagInfo{Unknown} and not $self->{OPTIONS}->{Unknown}) {
+            # don't return Unknown tags unless that option is set
+            return undef;
+        }
+        # return the tag information we found
+        return $tagInfo;
+    }
+    # generate information for unknown tags (numerical only) if required
+    if (not $tagInfo and $self->{OPTIONS}->{Unknown} and $tagID =~ /^\d+$/ and
+        not $$self{NO_UNKNOWN})
+    {
+        my $printConv;
+        if (defined $$tagTablePtr{PRINT_CONV}) {
+            $printConv = $$tagTablePtr{PRINT_CONV};
+        } else {
+            # limit length of printout (can be very long)
+            $printConv = 'length($val) > 60 ? substr($val,0,55) . "[...]" : $val';
+        }
+        my $hex = sprintf("0x%.4x", $tagID);
+        my $prefix = $$tagTablePtr{TAG_PREFIX};
+        $tagInfo = {
+            Name => "${prefix}_$hex",
+            Description => MakeDescription($prefix, $hex),
+            Unknown => 1,
+            Writable => 0,  # can't write unknown tags
+            PrintConv => $printConv,
+        };
+        # add tag information to table
+        AddTagToTable($tagTablePtr, $tagID, $tagInfo);
+    } else {
+        undef $tagInfo;
+    }
+    return $tagInfo;
+}
+
+#------------------------------------------------------------------------------
+# Add new tag to table (must use this routine to add new tags to a table)
+# Inputs: 0) reference to tag table, 1) tag ID
+#         2) reference to tag information hash
+# Notes: - will not overwrite existing entry in table
+# - info need contain no entries when this routine is called
+sub AddTagToTable($$$)
+{
+    my ($tagTablePtr, $tagID, $tagInfo) = @_;
+
+    # define necessary entries in information hash
+    if ($$tagInfo{Groups}) {
+        # fill in default groups from table GROUPS
+        foreach (keys %{$$tagTablePtr{GROUPS}}) {
+            next if $tagInfo->{Groups}->{$_};
+            $tagInfo->{Groups}->{$_} = $tagTablePtr->{GROUPS}->{$_};
+        }
+    } else {
+        $$tagInfo{Groups} = $$tagTablePtr{GROUPS};
+    }
+    $$tagInfo{Flags} and ExpandFlags($tagInfo);
+    $$tagInfo{GotGroups} = 1,
+    $$tagInfo{Table} = $tagTablePtr;
+    $$tagInfo{TagID} = $tagID;
+
+    unless ($$tagInfo{Name}) {
+        my $prefix = $$tagTablePtr{TAG_PREFIX};
+        $$tagInfo{Name} = "${prefix}_$tagID";
+        # make description to prevent tagID from getting mangled by MakeDescription()
+        $$tagInfo{Description} = MakeDescription($prefix, $tagID);
+    }
+    # add tag to table, but never overwrite existing entries (could potentially happen
+    # if someone thinks there isn't any tagInfo because a condition wasn't satisfied)
+    $$tagTablePtr{$tagID} = $tagInfo unless defined $$tagTablePtr{$tagID};
+}
+
+#------------------------------------------------------------------------------
+# Handle simple extraction of new tag information
+# Inputs: 0) ExifTool object ref, 1) tag table reference, 2) tagID, 3) value,
+#         4-N) parameters hash: Index, DataPt, DataPos, Start, Size, Parent,
+#              TagInfo, ProcessProc
+# Returns: tag key or undef if tag not found
+sub HandleTag($$$$;%)
+{
+    my ($self, $tagTablePtr, $tag, $val, %parms) = @_;
+    my $verbose = $self->{OPTIONS}->{Verbose};
+    my $tagInfo = $parms{TagInfo} || $self->GetTagInfo($tagTablePtr, $tag);
+    my $dataPt = $parms{DataPt};
+    my $subdir;
+
+    if ($tagInfo) {
+        $subdir = $$tagInfo{SubDirectory}
+    } else {
+        return undef unless $verbose;
+    }
+    # read value if not done already (not necessary for subdir)
+    unless (defined $val or $subdir) {
+        my $start = $parms{Start} || 0;
+        my $size = $parms{Size} || 0;
+        # read from data in memory if possible
+        if ($dataPt and $start >= 0 and $start + $size <= length($$dataPt)) {
+            $val = substr($$dataPt, $start, $size);
+        } else {
+            my $name = $tagInfo ? $$tagInfo{Name} : "tag $tag";
+            $self->Warn("Error extracting value for $name");
+            return undef;
+        }
+    }
+    # do verbose print if necessary
+    if ($verbose) {
+        $parms{Value} = $val;
+        $parms{Table} = $tagTablePtr;
+        $self->VerboseInfo($tag, $tagInfo, %parms);
+    }
+    if ($tagInfo) {
+        if ($subdir) {
+            $dataPt or $dataPt = \$val;
+            # process subdirectory information
+            my %dirInfo = (
+                DirName  => $$tagInfo{Name},
+                DataPt   => $dataPt,
+                DataLen  => length $$dataPt,
+                DataPos  => $parms{DataPos},
+                DirStart => $parms{Start},
+                DirLen   => $parms{Size},
+                Parent   => $parms{Parent},
+            );
+            my $subTablePtr = GetTagTable($$subdir{TagTable}) || $tagTablePtr;
+            $self->ProcessDirectory(\%dirInfo, $subTablePtr, $$subdir{ProcessProc});
+        } else {
+            return $self->FoundTag($tagInfo, $val);
+        }
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Add tag to hash of extracted information
+# Inputs: 0) reference to ExifTool object
+#         1) reference to tagInfo hash or tag name
+#         2) data value (or reference to require hash if composite)
+# Returns: tag key or undef if no value
+sub FoundTag($$$)
+{
+    local $_;
+    my ($self, $tagInfo, $value) = @_;
+    my $tag;
+
+    if (ref $tagInfo eq 'HASH') {
+        $tag = $$tagInfo{Name} or warn("No tag name\n"), return undef;
+    } else {
+        $tag = $tagInfo;
+        # look for tag in Extra
+        $tagInfo = $self->GetTagInfo(GetTagTable('Image::ExifTool::Extra'), $tag);
+        # make temporary hash if tag doesn't exist in Extra
+        # (not advised to do this since the tag won't show in list)
+        $tagInfo or $tagInfo = { Name => $tag, Groups => \%allGroupsExifTool };
+        $self->{OPTIONS}->{Verbose} and $self->VerboseInfo(undef, $tagInfo, Value => $value);
+    }
+    my $rawValueHash = $self->{VALUE};
+    if ($$tagInfo{RawConv}) {
+        my $conv = $$tagInfo{RawConv};
+        my $val = $value;   # must do this in case eval references $val
+        # initialize @val for use in Composite RawConv expressions
+        my @val;
+        if (ref $val eq 'HASH') {
+            foreach (keys %$val) { $val[$_] = $$rawValueHash{$$val{$_}}; }
+        }
+        if (ref $conv eq 'CODE') {
+            $value = &$conv($val, $self);
+        } else {
+            #### eval RawConv ($self, $val)
+            $value = eval $conv;
+            $@ and warn "RawConv: $@\n";
+        }
+        return undef unless defined $value;
+    }
+    # get tag priority
+    my $priority = $$tagInfo{Priority};
+    defined $priority or $priority = $tagInfo->{Table}->{PRIORITY};
+    # handle duplicate tag names
+    if (defined $rawValueHash->{$tag}) {
+        if ($$tagInfo{List} and $tagInfo eq $self->{TAG_INFO}->{$tag} and
+            not $self->{NO_LIST})
+        {
+            # use a list reference for multiple values
+            if (ref $rawValueHash->{$tag} ne 'ARRAY') {
+                $rawValueHash->{$tag} = [ $rawValueHash->{$tag} ];
+            }
+            push @{$rawValueHash->{$tag}}, $value;
+            return $tag;    # return without creating a new entry
+        }
+        # get next available tag key
+        my $nextTag = NextTagKey($rawValueHash, $tag);
+#
+# take tag with highest priority
+#
+        # promote existing 0-priority tag so it takes precedence over a new 0-tag
+        my $oldPriority = $self->{PRIORITY}->{$tag} || 1;
+        # set priority for this tag (default is 1)
+        $priority = 1 if not defined $priority or
+            # increase 0-priority tags if this is the priority directory
+            ($priority == 0 and $self->{DIR_NAME} and $self->{PRIORITY_DIR} and
+            $self->{DIR_NAME} eq $self->{PRIORITY_DIR});
+        if ($priority >= $oldPriority) {
+            $self->{MOVED_KEY} = $nextTag;  # used in BuildCompositeTags()
+            $self->{PRIORITY}->{$nextTag} = $self->{PRIORITY}->{$tag};
+            $rawValueHash->{$nextTag} = $rawValueHash->{$tag};
+            $self->{FILE_ORDER}->{$nextTag} = $self->{FILE_ORDER}->{$tag};
+            $self->{TAG_INFO}->{$nextTag} = $self->{TAG_INFO}->{$tag};
+            if ($self->{GROUP1}->{$tag}) {
+                $self->{GROUP1}->{$nextTag} = $self->{GROUP1}->{$tag};
+                delete $self->{GROUP1}->{$tag};
+            }
+        } else {
+            $tag = $nextTag;        # don't override the existing tag
+        }
+        $self->{PRIORITY}->{$tag} = $priority;
+    } elsif ($priority) {
+        # set tag priority (only if exists and non-zero)
+        $self->{PRIORITY}->{$tag} = $priority;
+    }
+
+    # save the raw value, file order, tagInfo ref and group1 name if necessary
+    $rawValueHash->{$tag} = $value;
+    $self->{FILE_ORDER}->{$tag} = ++$self->{NUM_FOUND};
+    $self->{TAG_INFO}->{$tag} = $tagInfo;
+    $self->{GROUP1}->{$tag} = $self->{SET_GROUP1} if $self->{SET_GROUP1};
+
+    return $tag;
+}
+
+#------------------------------------------------------------------------------
+# Get next available tag key
+# Inputs: 0) hash reference (keys are tag keys), 1) tag name
+# Returns: next available tag key
+sub NextTagKey($$)
+{
+    my ($info, $tag) = @_;
+    if (exists $$info{$tag}) {
+        my $name = $tag;
+        my $i;
+        for ($i=1; ; ++$i) {
+            $tag = "$name ($i)";
+            last unless exists $$info{$tag};
+        }
+    }
+    return $tag;
+}
+
+#------------------------------------------------------------------------------
+# Make current directory the priority directory if not set already
+# Inputs: 0) reference to ExifTool object
+sub SetPriorityDir($)
+{
+    my $self = shift;
+    $self->{PRIORITY_DIR} = $self->{DIR_NAME} unless $self->{PRIORITY_DIR};
+}
+
+#------------------------------------------------------------------------------
+# Set family 1 group name specific to this tag instance
+# Inputs: 0) reference to ExifTool object, 1) tag key, 2) group name
+sub SetGroup1($$$)
+{
+    my ($self, $tagKey, $extra) = @_;
+    $self->{GROUP1}->{$tagKey} = $extra;
+}
+
+#------------------------------------------------------------------------------
+# Set ID's for all tags in specified table
+# Inputs: 0) tag table reference
+sub GenerateTagIDs($)
+{
+    my $table = shift;
+
+    unless ($$table{DID_TAG_ID}) {
+        $$table{DID_TAG_ID} = 1;    # set flag so we won't do this table again
+        my ($tagID, $tagInfo);
+        foreach $tagID (keys %$table) {
+            next if $specialTags{$tagID};
+            # define tag ID in each element of conditional array
+            my @infoArray = GetTagInfoList($table,$tagID);
+            foreach $tagInfo (@infoArray) {
+                # define tag ID's in info hash
+                $$tagInfo{TagID} = $tagID;
+            }
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# Generate TagID's for all loaded tables
+# Inputs: None
+# Notes: Causes subsequently loaded tables to automatically generate TagID's too
+sub GenerateAllTagIDs()
+{
+    unless ($didTagID) {
+        my $tableName;
+        foreach $tableName (keys %allTables) {
+            # generate tag ID's for all tags in this table
+            GenerateTagIDs($allTables{$tableName});
+        }
+        $didTagID = 1;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Delete specified tag
+# Inputs: 0) reference to ExifTool object
+#         1) tag key
+sub DeleteTag($$)
+{
+    my ($self, $tag) = @_;
+    delete $self->{VALUE}->{$tag};
+    delete $self->{FILE_ORDER}->{$tag};
+    delete $self->{TAG_INFO}->{$tag};
+    delete $self->{GROUP1}->{$tag};
+}
+
+#------------------------------------------------------------------------------
+# Set the FileType and MIMEType tags
+# Inputs: 0) ExifTool object reference
+#         1) Optional file type (uses FILE_TYPE if not specified)
+sub SetFileType($;$)
+{
+    my $self = shift;
+    my $baseType = $self->{FILE_TYPE};
+    my $fileType = shift || $baseType;
+    my $mimeType = $mimeType{$fileType};
+    # use base file type if necessary (except if 'TIFF', which is a special case)
+    $mimeType = $mimeType{$baseType} unless $mimeType or $baseType eq 'TIFF';
+    $self->FoundTag('FileType', $fileType);
+    $self->FoundTag('MIMEType', $mimeType || 'application/unknown');
+}
+
+#------------------------------------------------------------------------------
+# Modify the value of the MIMEType tag
+# Inputs: 0) ExifTool object reference, 1) file or MIME type
+# Notes: combines existing type with new type: ie) a/b + c/d => c/b-d
+sub ModifyMimeType($;$)
+{
+    my ($self, $mime) = @_;
+    $mime =~ m{/} or $mime = $mimeType{$mime} or return;
+    my $old = $self->{VALUE}->{MIMEType};
+    if (defined $old) {
+        my ($a, $b) = split '/', $old;
+        my ($c, $d) = split '/', $mime;
+        $d =~ s/^x-//;
+        $self->{VALUE}->{MIMEType} = "$c/$b-$d";
+        $self->VPrint(0, "  Modified MIMEType = $c/$b-$d\n");
+    } else {
+        $self->FoundTag('MIMEType', $mime);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Print verbose output
+# Inputs: 0) ExifTool ref, 1) verbose level (prints if level > this), 2-N) print args
+sub VPrint($$@)
+{
+    my $self = shift;
+    my $level = shift;
+    if ($self->{OPTIONS}->{Verbose} and $self->{OPTIONS}->{Verbose} > $level) {
+        my $out = $self->{OPTIONS}->{TextOut};
+        print $out @_;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Verbose dump
+# Inputs: 0) ExifTool ref, 1) data ref, 2-N) HexDump options
+sub VerboseDump($$;%)
+{
+    my $self = shift;
+    my $dataPt = shift;
+    if ($self->{OPTIONS}->{Verbose} and $self->{OPTIONS}->{Verbose} > 2) {
+        HexDump($dataPt, undef,
+            Out => $self->{OPTIONS}->{TextOut},
+            MaxLen => $self->{OPTIONS}->{Verbose} < 4 ? 96 : undef,
+            @_
+        );
+    }
+}
+
+#------------------------------------------------------------------------------
+# Extract binary data from file
+# 0) ExifTool object reference, 1) offset, 2) length, 3) tag name if conditional
+# Returns: binary data, or undef on error
+# Notes: Returns "Binary data #### bytes" instead of data unless tag is
+#        specifically requested or the Binary option is set
+sub ExtractBinary($$$;$)
+{
+    my ($self, $offset, $length, $tag) = @_;
+
+    if ($tag and not $self->{OPTIONS}->{Binary} and
+        not $self->{REQ_TAG_LOOKUP}->{lc($tag)})
+    {
+        return "Binary data $length bytes";
+    }
+    my $buff;
+    unless ($self->{RAF}->Seek($offset,0)
+        and $self->{RAF}->Read($buff, $length) == $length)
+    {
+        $tag or $tag = 'binary data';
+        $self->Warn("Error reading $tag from file");
+        return undef;
+    }
+    return $buff;
+}
+
+#------------------------------------------------------------------------------
+# Process binary data
+# Inputs: 0) ExifTool object reference, 1) directory information reference
+#         2) tag table reference
+# Returns: 1 on success
+sub ProcessBinaryData($$$)
+{
+    my ($self, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $offset = $$dirInfo{DirStart} || 0;
+    my $size = $$dirInfo{DirLen} || (length($$dataPt) - $offset);
+    my $base = $$dirInfo{Base} || 0;
+    my $verbose = $self->{OPTIONS}->{Verbose};
+    my $unknown = $self->{OPTIONS}->{Unknown};
+    my $dataPos;
+
+    # get default format ('int8u' unless specified)
+    my $defaultFormat = $$tagTablePtr{FORMAT} || 'int8u';
+    my $increment = $formatSize{$defaultFormat};
+    unless ($increment) {
+        warn "Unknown format $defaultFormat\n";
+        $defaultFormat = 'int8u';
+        $increment = $formatSize{$defaultFormat};
+    }
+    # prepare list of tag numbers to extract
+    my @tags;
+    if ($unknown > 1 and defined $$tagTablePtr{FIRST_ENTRY}) {
+        # scan through entire binary table
+        @tags = ($$tagTablePtr{FIRST_ENTRY}..(int($size/$increment) - 1));
+    } elsif ($$dirInfo{DataMember}) {
+        @tags = @{$$dirInfo{DataMember}};
+        $verbose = 0;   # no verbose output of extracted values when writing
+    } else {
+        # extract known tags in numerical order
+        @tags = sort { $a <=> $b } TagTableKeys($tagTablePtr);
+    }
+    if ($verbose) {
+        $self->VerboseDir('BinaryData', undef, $size);
+        $dataPos = $$dirInfo{DataPos} || 0;
+    }
+    my $index;
+    my $nextIndex = 0;
+    my %val;
+    foreach $index (@tags) {
+        my $tagInfo;
+        if ($$tagTablePtr{$index}) {
+            $tagInfo = $self->GetTagInfo($tagTablePtr, $index) or next;
+            next if $$tagInfo{Unknown} and
+                   ($$tagInfo{Unknown} > $unknown or $index < $nextIndex);
+        } else {
+            # don't generate unknown tags in binary tables unless Unknown > 1
+            next unless $unknown > 1;
+            next if $index < $nextIndex;    # skip if data already used
+            $tagInfo = $self->GetTagInfo($tagTablePtr, $index) or next;
+            $$tagInfo{Unknown} = 2;    # set unknown to 2 for binary unknowns
+        }
+        my $count = 1;
+        my $format = $$tagInfo{Format};
+        my $entry = $index * $increment;        # relative offset of this entry
+        if ($format) {
+            if ($format =~ /(.*)\[(.*)\]/) {
+                $format = $1;
+                $count = $2;
+                # evaluate count to allow count to be based on previous values
+                #### eval Format (%val, $size)
+                $count = eval $count;
+                $@ and warn("Format $$tagInfo{Name}: $@"), next;
+                next if $count < 0;
+            } elsif ($format eq 'string') {
+                # allow string with no specified count to run to end of block
+                $count = ($size > $entry) ? $size - $entry : 0;
+            }
+        } else {
+            $format = $defaultFormat;
+        }
+        if ($unknown > 1) {
+            # calculate next valid index for unknown tag
+            my $ni = $index + ($formatSize{$format} * $count) / $increment;
+            $nextIndex = $ni unless $nextIndex > $ni;
+        }
+        my $val = ReadValue($dataPt, $entry+$offset, $format, $count, $size-$entry);
+        next unless defined $val;
+        if ($verbose) {
+            my $len = $count * ($formatSize{$format} || 1);
+            $len > $size - $entry and $len = $size - $entry;
+            $self->VerboseInfo($index, $tagInfo,
+                Table  => $tagTablePtr,
+                Value  => $val,
+                DataPt => $dataPt,
+                Size   => $len,
+                Start  => $entry+$offset,
+                Addr   => $entry+$offset+$base+$dataPos,
+                Format => $format,
+                Count  => $count,
+            );
+        }
+        $val += $base + $$self{BASE} if $$tagInfo{IsOffset};
+        $val{$index} = $val;
+        $self->FoundTag($tagInfo,$val);
+    }
+    return 1;
+}
+
+#..............................................................................
+# Load .ExifTool_config file from user's home directory (unless 'noConfig' set)
+unless ($Image::ExifTool::noConfig) {
+    my $config = '.ExifTool_config';
+    # get our home directory (HOMEDRIVE and HOMEPATH are used in Windows cmd shell)
+    my $home = $ENV{EXIFTOOL_HOME} || $ENV{HOME} ||
+               ($ENV{HOMEDRIVE} || '') . ($ENV{HOMEPATH} || '') || '.';
+    # look for the config file in 1) the home directory, 2) the program dir
+    my $file = "$home/$config";
+    -r $file or $file = ($0 =~ /(.*[\\\/])/ ? $1 : './') . $config;
+    if (-r $file) {
+        eval "require '$file'"; # load the config file
+        # print warning (minus "Compilation failed" part)
+        $@ and $_=$@, s/Compilation failed.*//s, warn $_;
+    }
+}
+
+#------------------------------------------------------------------------------
+1;  # end
Index: /gsdl/stable/perllib/cpan/Image/ExifTool.pod
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool.pod	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool.pod	(revision 20131)
@@ -0,0 +1,1607 @@
+#------------------------------------------------------------------------------
+# File:         ExifTool.pod - Documentation for File::ExifTool
+#
+# Description:  Read and write meta information
+#
+# URL:          http://owl.phy.queensu.ca/~phil/exiftool/
+#
+# Legal:        Copyright (c) 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+#               This library is free software; you can redistribute it and/or
+#               modify it under the same terms as Perl itself.
+#------------------------------------------------------------------------------
+
+=head1 NAME
+
+Image::ExifTool - Read and write meta information
+
+=head1 SYNOPSIS
+
+  use Image::ExifTool qw(:Public);
+
+  # ---- Simple procedural usage ----
+
+  # Get hash of meta information tag names/values from an image
+  $info = ImageInfo('a.jpg');
+
+  # ---- Object-oriented usage ----
+
+  # Create a new Image::ExifTool object
+  $exifTool = new Image::ExifTool;
+
+  # Extract meta information from an image
+  $exifTool->ExtractInfo($file, \%options);
+
+  # Get list of tags in the order they were found in the file
+  @tagList = $exifTool->GetFoundTags('File');
+
+  # Get the value of a specified tag
+  $value = $exifTool->GetValue($tag, $type);
+
+  # Get a tag description
+  $description = $exifTool->GetDescription($tag);
+
+  # Get the group name associated with this tag
+  $group = $exifTool->GetGroup($tag, $family);
+
+  # Set a new value for a tag
+  $exifTool->SetNewValue($tag, $newValue);
+
+  # Write new meta information to a file
+  $success = $exifTool->WriteInfo($srcfile, $dstfile);
+
+  # ...plus a host of other useful methods...
+
+=head1 DESCRIPTION
+
+ExifTool provides an extensible set of perl modules to read and write meta
+information in image, audio and video files, including the maker note
+information of many digital cameras by various manufacturers such as Canon,
+Casio, FujiFilm, HP, JVC/Victor, Kodak, Leaf, Minolta/Konica-Minolta, Nikon,
+Olympus/Epson, Panasonic/Leica, Pentax/Asahi, Ricoh, Sanyo, Sigma/Foveon and
+Sony.
+
+Below is a list of file types and meta information formats currently
+supported by ExifTool (r = read, w = write, c = create):
+
+                File Types                 |    Meta Information
+  ---------------------------------------  |  --------------------
+  ACR   r       JP2   r/w     PPT   r      |  EXIF           r/w/c
+  AI    r       JPEG  r/w     PS    r/w    |  GPS            r/w/c
+  AIFF  r       K25   r       PSD   r/w    |  IPTC           r/w/c
+  APE   r       M4A   r       QTIF  r      |  XMP            r/w/c
+  ARW   r       MEF   r/w     RA    r      |  MakerNotes     r/w/c
+  ASF   r       MIE   r/w/c   RAF   r      |  Photoshop IRB  r/w/c
+  AVI   r       MIFF  r       RAM   r      |  ICC Profile    r/w/c
+  BMP   r       MNG   r/w     RAW   r/w    |  MIE            r/w/c
+  BTF   r       MOS   r/w     RIFF  r      |  JFIF           r/w/c
+  CR2   r/w     MOV   r       RM    r      |  Ducky APP12    r/w/c
+  CRW   r/w     MP3   r       SR2   r      |  CIFF           r/w
+  CS1   r/w     MP4   r       SRF   r      |  AFCP           r/w
+  DCM   r       MPC   r       SWF   r      |  DICOM          r
+  DCR   r       MPG   r       THM   r/w    |  Flash          r
+  DNG   r/w     MRW   r/w     TIFF  r/w    |  FlashPix       r
+  DOC   r       NEF   r/w     VRD   r/w/c  |  GeoTIFF        r
+  EPS   r/w     OGG   r       WAV   r      |  PrintIM        r
+  ERF   r/w     ORF   r/w     WDP   r/w    |  ID3            r
+  FLAC  r       PBM   r/w     WMA   r      |  Kodak Meta     r
+  FLV   r       PDF   r       WMV   r      |  Ricoh RMETA    r
+  FPX   r       PEF   r/w     X3F   r      |  Picture Info   r
+  GIF   r/w     PGM   r/w     XLS   r      |  Adobe APP14    r
+  HTML  r       PICT  r       XMP   r/w/c  |  APE            r
+  ICC   r/w/c   PNG   r/w                  |  Vorbis         r
+  JNG   r/w     PPM   r/w                  |  (and more)
+
+=head1 CONFIGURATION
+
+User-defined tags can be added via the ExifTool configuration file.  See
+"ExifTool_config" in the ExifTool distribution for more details.  If
+necessary, the configuration feature can be disabled by setting the ExifTool
+C<noConfig> flag before loading Image::ExifTool.  For example:
+
+    BEGIN { $Image::ExifTool::noConfig = 1 }
+    use Image::ExifTool;
+
+=head1 METHODS
+
+=head2 new
+
+Creates a new ExifTool object.
+
+    $exifTool = new Image::ExifTool;
+
+Note that ExifTool uses AUTOLOAD to load non-member methods, so any class
+using Image::ExifTool as a base class must define an AUTOLOAD which calls
+Image::ExifTool::DoAutoLoad().  ie)
+
+    sub AUTOLOAD
+    {
+        Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
+    }
+
+=head2 ImageInfo
+
+Obtain meta information from image.  This is the one step function for
+obtaining meta information from an image.  Internally, L</ImageInfo> calls
+L</ExtractInfo> to extract the information, L</GetInfo> to generate the
+information hash, and L</GetTagList> for the returned tag list.
+
+    # Return meta information for 2 tags only (procedural)
+    $info = ImageInfo($filename, $tag1, $tag2);
+
+    # Return information about an open image file (object-oriented)
+    $info = $exifTool->ImageInfo(\*FILE);
+
+    # Return information from image data in memory for specified tags
+    %options = (PrintConv => 0);
+    @tagList = qw(filename imagesize xmp:creator exif:* -ifd1:*);
+    $info = ImageInfo(\$imageData, \@tagList, \%options);
+
+    # Extract information from an embedded thumbnail image
+    $info = ImageInfo('image.jpg', 'thumbnailimage');
+    $thumbInfo = ImageInfo($$info{ThumbnailImage});
+
+=over 4
+
+=item Inputs:
+
+L</ImageInfo> is very flexible about the input arguments, and interprets
+them based on their type.  It may be called with one or more arguments.
+The one required argument is either a SCALAR (the image file name), a file
+reference (a reference to the image file) or a SCALAR reference (a
+reference to the image in memory).  Other arguments are optional.  The
+order of the arguments is not significant, except that the first SCALAR is
+taken to be the file name unless a file reference or scalar reference comes
+earlier in the argument list.
+
+Below is an explanation of how the L</ImageInfo> function arguments are
+interpreted:
+
+=over 4
+
+=item ExifTool ref
+
+L</ImageInfo> may be called with an ExifTool object if desired.  The
+advantage of using the object-oriented form is that the options may be set
+before calling L</ImageInfo>, and the object may be used afterward to access
+member functions.  Must be the first argument if used.
+
+=item SCALAR
+
+The first scalar argument is taken to be the file name unless an earlier
+argument specified the image data via a file reference (file ref) or data
+reference (SCALAR ref).  The remaining scalar arguments are names of tags
+for requested information.  If no tags are specified, all possible
+information is extracted.
+
+Tag names are case-insensitive and may be prefixed by an optional group name
+followed by a colon.  The group name may begin with a family number
+(ie. '1IPTC:Keywords'), to restrict matches to a specific family.  A tag
+name of '*' may be used, thus allowing 'GROUP:*' to represent all tags in a
+specific group, or a group name of '*' may be used, in which case all
+available instances of the specified tag are returned regardless of the
+L</Duplicates> setting (ie. '*:WhiteBalance').  And finally, a leading '-'
+indicates tags to be excluded (ie. '-IFD1:*').
+
+Note that keys in the returned information hash and elements of the returned
+tag list are not necessarily the same as these tag names -- group names are
+removed, the case may be changed, and an instance number may be added.  For
+this reason it is best to use either the keys of the returned hash or the
+elements of the tag array when accessing the tag values.
+
+See L<Image::ExifTool::TagNames|Image::ExifTool::TagNames> for a complete
+list of ExifTool tag names.
+
+=item File ref
+
+A reference to an open image file.  If you use this method (or a SCALAR
+reference) to access information in an image, the FileName and Directory
+tags will not be returned.  (Also, the FileSize and FileModifyDate tags will
+not be returned unless it is a plain file.)  Image processing begins at the
+current file position, and on return the file position is unspecified.
+
+=item SCALAR ref
+
+A reference to image data in memory.
+
+=item ARRAY ref
+
+Reference to a list of tag names.  On entry, any elements in the list are
+added to the list of requested tags.  Tags with names beginning with '-' are
+excluded.  On return, this list is updated to contain an ordered list of tag
+keys for all extracted tags.
+
+=item HASH ref
+
+Reference to a hash containing the options settings.  See L</Options>
+documentation below for a list of available options.  Options specified
+as arguments to L</ImageInfo> take precedence over L</Options> settings.
+
+=back
+
+=item Return Values:
+
+L</ImageInfo> returns a reference to a hash of tag key/value pairs.  The tag
+keys are identifiers, which are similar to the tag names but may have an
+embedded instance number if multiple tags with the same name were extracted
+from the image.  Many of the ExifTool functions require a tag key as an
+argument. Use L</GetTagName> to get the tag name for a given tag key.  Note
+that the case of the tag names may not be the same as requested.  Here is a
+simple example to print out the information returned by L</ImageInfo>:
+
+    foreach (sort keys %$info) {
+        print "$_ => $$info{$_}\n";
+    }
+
+Values of the returned hash are usually simple scalars, but a scalar
+reference is used to indicate binary data and an array reference may be used
+to indicate a list.  Lists of values are joined by commas into a single
+string if and only if the PrintConv option is enabled and the List option is
+disabled (which are the defaults).  Note that binary values are not
+necessarily extracted unless specifically requested or the Binary option is
+set.  If not extracted the value is a reference to a string of the form
+"Binary data ##### bytes".
+
+The code below gives an example of how to handle these return values, as
+well as illustrating the use of other ExifTool functions:
+
+    use Image::ExifTool;
+    my $exifTool = new Image::ExifTool;
+    $exifTool->Options(Unknown => 1);
+    my $info = $exifTool->ImageInfo('a.jpg');
+    my $group = '';
+    my $tag;
+    foreach $tag ($exifTool->GetFoundTags('Group0')) {
+        if ($group ne $exifTool->GetGroup($tag)) {
+            $group = $exifTool->GetGroup($tag);
+            print "---- $group ----\n";
+        }
+        my $val = $info->{$tag};
+        if (ref $val eq 'SCALAR') {
+            if ($$val =~ /^Binary data/) {
+                $val = "($$val)";
+            } else {
+                my $len = length($$val);
+                $val = "(Binary data $len bytes)";
+            }
+        }
+        printf("%-32s : %s\n", $exifTool->GetDescription($tag), $val);
+    }
+
+As well as tags representing information extracted from the image,
+the following tags generated by ExifTool may be returned:
+
+    ExifToolVersion - The ExifTool version number.
+
+    Error - An error message if the image could not be read.
+
+    Warning - A warning message if problems were encountered
+              while extracting information from the image.
+
+=back
+
+=head2 Options
+
+Get/set ExifTool options.  This function can be called to set the default
+options for an ExifTool object.  Options set this way are in effect for
+all function calls but may be overridden by options passed as arguments
+to a specific function.
+
+    # Exclude the 'OwnerName' tag from returned information
+    $exifTool->Options(Exclude => 'OwnerName');
+
+    # Only get information in EXIF or MakerNotes groups
+    $exifTool->Options(Group0 => ['EXIF', 'MakerNotes']);
+
+    # Ignore information from IFD1
+    $exifTool->Options(Group1 => '-IFD1');
+
+    # Sort by groups in family 2, and extract unknown tags
+    $exifTool->Options(Sort => 'Group2', Unknown => 1);
+
+    # Do not extract duplicate tag names
+    $oldSetting = $exifTool->Options(Duplicates => 0);
+
+    # Get current setting
+    $isVerbose = $exifTool->Options('Verbose');
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference.
+
+1) Option parameter name.
+
+2) [optional] Option parameter value (may be undef to clear option).
+
+3-N) [optional] Additional parameter/value pairs.
+
+=item Option Parameters:
+
+=over 4
+
+=item Binary
+
+Flag to extract the value data for all binary tags.  Tag values representing
+large binary data blocks (ie. ThumbnailImage) are not necessarily extracted
+unless this option is set or the tag is specifically requested by name.
+Default is 0.
+
+=item ByteOrder
+
+The byte order for newly created EXIF segments when writing.  Note that if
+EXIF information already exists, the existing order is maintained.  Valid
+values are 'MM', 'II' and undef.  If ByteOrder is not defined (the default),
+then the maker note byte order is used (if they are being copied), otherwise
+big-endian ('MM') order is assumed.  This can also be set via the
+ExifByteOrder tag, but the ByteOrder option takes precedence if both are
+set.
+
+=item Charset
+
+Character set for converting special characters.  Valid values are:
+
+  UTF8  - UTF-8 characters (the default)
+  Latin - Windows Latin1 (cp1252)
+
+Note that this option affects some types of information when reading/writing
+the file and other types when getting/setting tag values, so it must be
+defined for both types of access.
+
+=item Compact
+
+Flag to write compact output.  Default is 0.  The XMP specification suggests
+that the data be padded with blanks to allow in-place editing.  By setting
+this flag, 2kB is saved for files with XMP data.
+
+=item Composite
+
+Flag to calculate Composite tags automatically.  Default is 1.
+
+=item Compress
+
+Flag to write new values in compressed format if possible.  Has no effect
+unless Compress::Zlib is installed.  Default is 0.
+
+=item CoordFormat
+
+Format for printing GPS coordinates.  This is a printf format string with
+specifiers for degrees, minutes and seconds in that order, however minutes
+and seconds may be omitted.  For example, the following table gives the
+output for the same coordinate using various formats:
+
+        CoordFormat          Example Output
+    -------------------    ------------------
+    q{%d deg %d' %.2f"}    54 deg 59' 22.80"   (the default)
+    q{%d deg %.4f min}     54 deg 59.3800 min
+    q{%.6f degrees}        54.989667 degrees
+
+=item DateFormat
+
+Format for printing EXIF date/time.  See C<strftime> in the L<POSIX> package
+for details about the format string.  The default format is equivalent to
+"%Y:%m:%d %H:%M:%S".  If date can not be converted, value is left unchanged
+unless the StrictDate option is set.
+
+=item Duplicates
+
+Flag to preserve values of duplicate tags (instead of overwriting existing
+value).  Default is 1.
+
+=item Exclude
+
+Exclude specified tags from tags extracted from an image.  The option value
+is either a tag name or reference to a list of tag names to exclude.  The
+case of tag names is not significant.  This option is ignored for
+specifically requested tags.  Tags may also be excluded by preceeding their
+name with a '-' in the arguments to L</ImageInfo>.
+
+=item FastScan
+
+Flag to increase speed of extracting information from JPEG images.  With
+this option set, ExifTool will not scan to the end of a JPEG image to check
+for an AFCP, CanonVRD, FotoStation, PhotoMechanic, MIE or PreviewImage
+trailer.  Also, when combined with the ScanForXMP option, prevents scanning
+for XMP in recognized file types.  Default 0.
+
+=item FixBase
+
+Fix maker notes base offset.  A common problem with image editing software
+is that offsets in the maker notes are not adjusted properly when the file
+is modified.  This may cause the wrong values to be extracted for some maker
+note entries when reading the edited file.  FixBase specifies an integer
+value to be added to the maker notes base offset.  It may also be set to the
+empty string ('') for ExifTool will take its best guess at the correct base,
+or undef (the default) for no base adjustment.
+
+=item Group#
+
+Extract tags only for specified groups in family # (Group0 assumed if #
+not given).  The option value may be a single group name or a reference
+to a list of groups.  Case is significant in group names.  Specify a
+group to be excluded by preceding group name with a '-'.  See
+L</GetAllGroups> for a list of available groups.
+
+=item HtmlDump
+
+Dump information in hex to dynamic HTML web page.  The value may be 0-3 for
+increasingly larger limits on the maximum block size.  Default is 0.  Output
+goes to the file specified by the TextOut option (\*STDOUT by default).
+
+=item HtmlDumpBase
+
+Specifies base for HTML dump offsets.  If not defined, the EXIF/TIFF base
+offset is used.  Set to 0 for absolute offsets.  Default is undef.
+
+=item IgnoreMinorErrors
+
+Flag to ignore minor errors.  Causes minor errors to be downgraded to
+warnings, and minor warnings to be ignored.  This option is provided mainly
+to allow writing of files when minor errors occur, but also allows thumbnail
+and preview images to be extracted even if they don't have a recognizable
+header.  Minor errors/warnings are denoted by '[minor]' at the start of the
+message.
+
+=item List
+
+Flag to extract lists of PrintConv values into arrays instead of
+concatenating them into comma-separated strings.  Default is 0.
+
+=item MakerNotes
+
+Option to extract MakerNotes and other writable subdirectories (such as
+PrintIM) as a data block.  Normally when the MakerNotes are extracted they
+are rebuilt to include data outside the boundaries of the original maker
+note data block, but a value of 2 disables this feature.  Possible values
+are:
+
+  0 - Do not extract writable subdirectories [default]
+  1 - Extract and rebuild maker notes into self-contained block
+  2 - Extract without rebuilding maker notes
+
+=item MissingTagValue
+
+Value for missing tags in expressions evaluated by L</SetNewValuesFromFile>.
+If not set, a minor error is issued for missing values, or the value is set
+to '' if L</IgnoreMinorErrors> is set.  Default is undef.
+
+=item PrintConv
+
+Flag to enable automatic print conversion.  Also enables inverse
+print conversion for writing.  Default is 1.
+
+=item ScanForXMP
+
+Flag for scan all files (even unrecognized formats) for XMP information
+unless XMP was already found in the file.  When combined with the FastScan
+option, only unrecognized file types are scanned for XMP.  Default is 0.
+
+=item Sort
+
+Specifies order to sort tags in returned list:
+
+  Alpha  - Sort alphabetically
+  File   - Sort in order that tags were found in the file
+  Group# - Sort by tag group, where # is the group family
+           number.  If # is not specified, Group0 is assumed.
+           See GetGroup for a list of groups.
+  Input  - Sort in same order as input tag arguments (default)
+
+=item StrictDate
+
+Flag to return undefined value for any date which can't be converted when
+the DateFormat option is used.  Default is 0.
+
+=item TextOut
+
+Output file reference for Verbose and HtmlDump options.  Default is
+\*STDOUT.
+
+=item Unknown
+
+Flag to get the values of unknown tags.  If set to 1, unknown tags are
+extracted from EXIF (or other tagged-format) directories.  If set to 2,
+unknown tags are also extracted from binary data blocks.  Default is 0.
+
+=item Verbose
+
+Print verbose messages to file specified by TextOut option.  Value may be
+from 0 to 5 for increasingly verbose messages.  Default is 0.  With the
+verbose option set, messages are printed to the console as the file is
+parsed.  Level 1 prints the tag names and raw values.  Level 2 adds more
+details about the tags.  Level 3 adds a hex dump of the tag data, but with
+limits on the number of bytes dumped.  Levels 4 and 5 remove the dump limit
+on tag values and JPEG segment data respectively.
+
+=back
+
+=item Return Values:
+
+The original value of the last specified parameter.
+
+=back
+
+=head2 ClearOptions
+
+Reset all options to their default values.
+
+    $exifTool->ClearOptions();
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+=item Return Values:
+
+(none)
+
+=back
+
+=head2 ExtractInfo
+
+Extract all meta information from an image.
+
+    $success = $exifTool->ExtractInfo('image.jpg', \%options);
+
+=over 4
+
+=item Inputs:
+
+L</ExtractInfo> takes exactly the same arguments as L</ImageInfo>.  The only
+difference is that a list of tag keys is not returned if an ARRAY reference
+is given.  The following options are effective in the call to
+L</ExtractInfo>:
+
+Binary, Composite, DateFormat, Unknown and Verbose.
+
+=item Return Value:
+
+1 if image was valid, 0 otherwise (and 'Error' tag set).
+
+=back
+
+=head2 GetInfo
+
+L</GetInfo> is called to return meta information after it has been extracted
+from the image by a previous call to L</ExtractInfo> or L</ImageInfo>. This
+function may be called repeatedly after a single call to L</ExtractInfo> or
+L</ImageInfo>.
+
+    # Get image width and hieght only
+    $info = $exifTool->GetInfo('ImageWidth', 'ImageHeight');
+
+    # Get information for all tags in list (list updated with tags found)
+    $info = $exifTool->GetInfo(\@ioTagList);
+
+    # Get all information in Author or Location groups
+    $info = $exifTool->GetInfo({Group2 => ['Author', 'Location']});
+
+=over 4
+
+=item Inputs:
+
+Inputs are the same as L</ExtractInfo> and L</ImageInfo> except that an
+image can not be specified.  Options in effect are:
+
+Duplicates, Exclude, Group#, PrintConv (and Sort if tag list reference is
+given).
+
+=item Return Value:
+
+Reference to information hash, the same as with L</ImageInfo>.
+
+=back
+
+=head2 WriteInfo
+
+Write meta information to a file.  The specified source file is rewritten to
+the same-type destination file with new information as specified by previous
+calls to L</SetNewValue>.  The necessary segments and/or directories are
+created in the destination file as required to store the specified
+information.  May be called repeatedly to write the same information to
+additional files without the need to call L</SetNewValue> again.
+
+    # add information to a source file, writing output to new file
+    $exifTool->WriteInfo($srcfile, $dstfile);
+
+    # create XMP data file from scratch
+    $exifTool->WriteInfo(undef, $dstfile, 'XMP');
+
+    # edit file in place (you do have backups, right?)
+    $exifTool->WriteInfo($srcfile);
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) Source file name, file reference, scalar reference, or undefined to
+create a file from scratch
+
+2) [optional] Destination file name, file or scalar reference
+
+3) [optional] Destination file type
+
+=item Return Value:
+
+1 if file was written OK, 2 if file was written but no changes made, 0 on
+file write error.
+
+If an error code is returned, an Error tag is set and GetValue('Error') can
+be called to obtain the error description.  A Warning tag may be set even if
+this routine is successful.
+
+    $errorMessage = $exifTool->GetValue('Error');
+    $warningMessage = $exifTool->GetValue('Warning');
+
+=item Notes:
+
+The source file name may be undefined to create a file from scratch
+(currently only XMP, ICC and MIE files can be created in this way).  If
+undefined, the destination file type is required unless the type can be
+determined from the destination file name.
+
+The destination file name may be undefined to edit a file in place (make
+sure you have backups!).  If a destination file name is given, the specified
+file must not exist because existing destination files will not be
+overwritten.
+
+The destination file type is only used if the source file is undefined.
+
+=back
+
+=head2 CombineInfo
+
+Combine information from more than one information hash into a single hash.
+
+    $info = $exifTool->CombineInfo($info1, $info2, $info3);
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1-N) Information hash references
+
+=back
+
+If the Duplicates option is disabled and duplicate tags exist, the order of
+the hashes is significant.  In this case, the value used is the first value
+found as the hashes are scanned in order of input.  The Duplicates option
+is the only option that is in effect for this function.
+
+=head2 GetTagList
+
+Get a sorted list of tags from the specified information hash or tag list.
+
+    @tags = $exifTool->GetTagList($info, 'Group0');
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference,
+
+1) [optional] Information hash reference or tag list reference,
+
+2) [optional] Sort order ('File', 'Input', 'Alpha' or 'Group#').
+
+If the information hash or tag list reference is not provided, then the list
+of found tags from the last call to L</ImageInfo>, L</ExtractInfo> or
+L</GetInfo> is used instead, and the result is the same as if
+L</GetFoundTags> was called.  If sort order is not specified, the sort order
+is taken from the current options settings.
+
+=item Return Values:
+
+A list of tags in the specified order.
+
+=back
+
+=head2 GetFoundTags
+
+Get list of found tags in specified sort order.  The found tags are the tags
+for the information obtained from the most recent call to L</ImageInfo>,
+L</ExtractInfo> or L</GetInfo> for this object.
+
+    @tags = $exifTool->GetFoundTags('File');
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) [optional] Sort order ('File', 'Input', 'Alpha' or 'Group#')
+
+If sort order is not specified, the sort order from the ExifTool options is
+used.
+
+=item Return Values:
+
+A list of tags in the specified order.
+
+=back
+
+=head2 GetRequestedTags
+
+Get list of requested tags.  These are the tags that were specified in the
+arguments of the most recent call to L</ImageInfo>, L</ExtractInfo> or
+L</GetInfo>, including tags specified via a tag list reference. Shortcut
+tags are expanded in the list.
+
+    @tags = $exifTool->GetRequestedTags();
+
+=over 4
+
+=item Inputs:
+
+(none)
+
+=item Return Values:
+
+List of requested tags in the same order that they were specified.
+Note that this list will be empty if tags were not specifically requested
+(ie. If extracting all tags).
+
+=back
+
+=head2 GetValue
+
+Get the value of a specified tag.  The returned value is either the
+human-readable (PrintConv) value, the converted machine-readable (ValueConv)
+value, or the original raw (Raw) value.  If the value type is not specified,
+the PrintConv value is returned if the PrintConv option is set, otherwise
+the ValueConv value is returned.  The PrintConv values are same as the
+values returned by L</ImageInfo> and L</GetInfo> in the tag/value hash
+unless the PrintConv option is disabled.
+
+Tags which represent lists of multiple values (as may happen with 'Keywords'
+for example) are handled specially.  In scalar context, the returned
+PrintConv value for these tags is either a comma-separated string of values
+or a list reference (depending on the List option setting), and the
+ValueConv value is always a list reference.  But in list context,
+L</GetValue> always returns the list itself.
+
+    # PrintConv example
+    my $val = $exifTool->GetValue($tag);
+    if (ref $val eq 'SCALAR') {
+        print "$tag = (unprintable value)\n";
+    } else {
+        print "$tag = $val\n";
+    }
+
+    # ValueConv examples
+    my $val = $exifTool->GetValue($tag, 'ValueConv');
+    if (ref $val eq 'ARRAY') {
+        print "$tag is a list of values\n";
+    } elsif (ref $val eq 'SCALAR') {
+        print "$tag represents binary data\n";
+    } else {
+        print "$tag is a simple scalar\n";
+    }
+
+    my @keywords = $exifTool->GetValue('Keywords', 'ValueConv');
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) Tag key
+
+2) [optional] Value type, 'PrintConv', 'ValueConv', 'Both' or 'Raw'
+
+The default value type is 'PrintConv' if the PrintConv option is set,
+otherwise the default is 'ValueConv'.  A value type of 'Both' returns both
+ValueConv and PrintConv values as a list.
+
+=item Return Values:
+
+The value of the specified tag.  If the tag represents a list of values and
+the List option is disabled then PrintConv returns a comma separated string
+of values, otherwise a reference to the list is returned in scalar context.
+The list itself is returned in list context.  Values may also be scalar
+references to binary data.
+
+Note: It is possible for L</GetValue> to return an undefined ValueConv or
+PrintConv value (or an empty list in list context) even if the tag exists,
+since it is possible for these conversions to yield undefined values.
+
+=back
+
+=head2 SetNewValue
+
+Set the new value for a tag.  The routine may be called multiple times to
+set the values of many tags before using L</WriteInfo> to write the new
+values to an image.
+
+For list-type tags (like Keywords), either call repeatedly with the same tag
+name for each value, or call with a reference to the list of values.
+
+    # set a new value for a tag (errors go to STDERR)
+    $success = $exifTool->SetNewValue($tag, $value);
+
+    # set a new value and capture any error message
+    ($success, $errStr) = $exifTool->SetNewValue($tag, $value);
+
+    # delete information for specified tag if it exists in image
+    # (also resets AddValue and DelValue options for this tag)
+    $exifTool->SetNewValue($tag);
+
+    # reset all values from previous calls to SetNewValue()
+    $exifTool->SetNewValue();
+
+    # delete a specific keyword
+    $exifTool->SetNewValue('Keywords', $word, DelValue => 1);
+
+    # write a list of keywords
+    $exifTool->SetNewValue('Keywords', ['word1','word2']);
+
+    # add a keyword without replacing existing keywords
+    $exifTool->SetNewValue(Keywords => $word, AddValue => 1);
+
+    # set a tag in a specific group
+    $exifTool->SetNewValue(Headline => $val, Group => 'XMP');
+    $exifTool->SetNewValue('XMP:Headline' => $val);  # equivalent
+
+    # shift original date/time back by 1 hour
+    $exifTool->SetNewValue(DateTimeOriginal => '1:00', Shift => -1);
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) [optional] Tag key or tag name, or undefined to clear all new values.  A
+tag name of '*' can be used when deleting tags to delete all tags, or all
+tags in a specified group.  The tag name may be prefixed by group name,
+separated by a colon (ie. 'GROUP:TAG'), which is equivalent to using a
+'Group' option argument.
+
+2) [optional] New value for tag.  Undefined to delete tag from file.  May be
+a scalar, scalar reference, or list reference to set a list of values.
+
+3-N) [optional] SetNewValue options hash entries (see below)
+
+=item SetNewValue Options:
+
+=over 4
+
+=item Type
+
+The type of value being set.  Valid values are PrintConv, ValueConv or Raw.
+Default is PrintConv if the L</PrintConv> Option is set, otherwise
+ValueConv.
+
+=item AddValue
+
+Specifies that the value be added to an existing list rather than replacing
+the list.  Valid values are 0 or 1.  Default is 0.
+
+=item DelValue
+
+Delete the existing tag if it has the specified value.  Valid values are
+0 or 1.  Default is 0.
+
+=item Group
+
+Specifies group name where tag should be written.  If not specified, tag is
+written to highest priority group as specified by L</SetNewGroups>.  Any
+family 0 or 1 group name may be used.  Case is not significant.
+
+=item NoShortcut
+
+Disables default behaviour of looking up tag in shortcuts if not found
+otherwise.
+
+=item Protected
+
+Bit mask for tag protection levels to write.  Bit 0x01 allows writing of
+'unsafe' tags (ie. tags not copied automatically via
+L</SetNewValuesFromFile>).  Bit 0x02 allows writing of 'protected' tags, and
+should only be used internally by ExifTool.  See
+L<Image::ExifTool::TagNames|Image::ExifTool::TagNames>, for a list of tag
+names indicating 'unsafe' and 'protected' tags.  Default is 0.
+
+=item Replace
+
+Flag to replace the previous new value for this tag (ie. replace the value
+set in a previous call to L</SetNewValue>).  Valid values are 0 (don't
+replace), 1 (replace with specified new value) or 2 (reset previous new
+value only).
+
+=item Shift
+
+Shift the tag by the specified value.  Currently only date/time tags can be
+shifted.  Undefined for no shift, 1 for a positive shift, or -1 for a
+negative shift.  If 0, the shift is applied only if the tag is shiftable.
+In this case, the direction of the shift is positive if AddValue is set, or
+negative if DelValue is set.  Default is undef.  See
+L<Image::ExifTool::Shift.pl|Image::ExifTool::Shift.pl> for more information.
+
+=back
+
+=item Return Values:
+
+In scalar context, returns the number of tags set and error messages are
+printed to STDERR.  In list context, returns the number of tags set and the
+error string.
+
+=back
+
+=head2 SetNewValuesFromFile
+
+A very powerful routine that sets new values for tags from information found
+in a specified file.
+
+    # set new values from all information in a file...
+    my $info = $exifTool->SetNewValuesFromFile($srcFile);
+    # ...then write these values to another image
+    my $result = $exifTool->WriteInfo($file2, $outFile);
+
+    # set all new values, preserving original groups
+    $exifTool->SetNewValuesFromFile($srcFile, '*:*');
+
+    # set specific information
+    $exifTool->SetNewValuesFromFile($srcFile, @tags);
+
+    # set new value from a different tag in specific group
+    $exifTool->SetNewValuesFromFile($fp, 'IPTC:Keywords>XMP-dc:Subject');
+
+    # add all IPTC keywords to XMP subject list
+    $exifTool->SetNewValuesFromFile($fp, 'IPTC:Keywords+>XMP-dc:Subject');
+
+    # set new value from an expression involving other tags
+    $exifTool->SetNewValuesFromFile($file,
+        'Comment<ISO=$ISO Aperture=$aperture Exposure=$shutterSpeed');
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) File name, file reference, or scalar reference
+
+2-N) [optional] List of tag names to set.  All writable tags are set if none
+are specified.  The tag names are not case sensitive, and may be prefixed by
+an optional family 0 or 1 group name, separated by a colon (ie. 'exif:iso').
+A leading '-' indicates tags to be excluded (ie. '-comment').  An asterisk
+('*') may be used for the tag name, and is useful when a group is specified
+to set all tags from a group (ie. 'XMP:*').  A special feature allows tag
+names of the form 'SRCTAG>DSTTAG' (or 'DSTTAGE<lt>SRCTAG') to be specified
+to copy information to a tag with a different name or a specified group.
+Both 'SRCTAG' and 'DSTTAG' may use '*' and/or be prefixed by a group name
+(ie. 'modifyDate>fileModifyDate' or '*>xmp:*').  Copied tags may also be
+added or deleted from a list with arguments of the form 'SRCTAG+>DSTTAG' or
+'SRCTAG->DSTTAG'.  Tags are evaluated in order, so exclusions apply only to
+tags included earlier in the list.  An extension of this feature allows the
+tag value to be set from an expression containing tag names with leading '$'
+symbols (ie. 'CommentE<lt>Filename: $filename').  Braces '{}' may be used
+around the tag name to separate it from subsequent text, and a '$$' is used
+to to represent a '$' symbol.  (The behaviour for missing tags in
+expressions is defined by the L</MissingTagValue> option.)
+
+By default, this routine will commute information between same-named tags in
+different groups, allowing information to be translated between images with
+different formats.  This behaviour may be modified by specifying a group
+name for extracted tags (even if '*' is used as a group name), in which case
+the information is written to the original group, unless redirected to a
+different group.  (For example, a tag name of '*:*' may be specified to copy
+all information while preserving the original groups.)
+
+=item Return Values:
+
+A hash of information that was set successfully.  May include Warning or
+Error entries if there were problems reading the input file.
+
+=item Notes:
+
+The PrintConv option applies to this routine, but it normally should be left
+on to provide more reliable transfer of information between groups.
+
+If a preview image exists, it is not copied.  The preview image must be
+transferred separately if desired.
+
+When simply copying all information between files of the same type, it is
+usually desirable to preserve the original groups by specifying '*:*' for
+the tags to set.
+
+=back
+
+=head2 GetNewValues
+
+Get list of new Raw values for the specified tag.  These are the values
+that will be written to file.  Only tags which support a 'List' may return
+more than one value.
+
+    $rawVal = $exifTool->GetNewValues($tag);
+
+    @rawVals = $exifTool->GetNewValues($tag);
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) Tag key or tag name
+
+=item Return Values:
+
+List of new Raw tag values.  The list may be empty if the tag is being
+deleted (ie. if SetNewValue was called without a value).
+
+=back
+
+=head2 CountNewValues
+
+Return the total number of new values set.
+
+    $numSet = $exifTool->CountNewValues();
+    ($numSet, $numPseudo) = $exifTool->CountNewValues();
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+=item Return Values:
+
+In scalar context, returns the total number of tags with new values set.  In
+list context, also returns the number of "pseudo" tag values which have been
+set.  "Pseudo" tags are tags like FileName and FileModifyDate which are not
+contained within the file and can be changed without rewriting the file.
+
+=back
+
+=head2 SaveNewValues
+
+Save state of new values to be later restored by L</RestoreNewValues>.
+
+    $exifTool->SaveNewValues();         # save state of new values
+    $exifTool->SetNewValue(ISO => 100); # set new value for ISO
+    $exifTool->WriteInfo($src, $dst1);  # write ISO + previous new values
+    $exifTool->RestoreNewValues();      # restore previous new values
+    $exifTool->WriteInfo($src, $dst2);  # write previous new values only
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+=item Return Value:
+
+None.
+
+=back
+
+=head2 RestoreNewValues
+
+Restore new values to the settings that existed when L</SaveNewValues> was
+last called.  May be called repeatedly after a single call to
+L</SaveNewValues>.  See L</SaveNewValues> above for an example.
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+=item Return Value:
+
+None.
+
+=back
+
+=head2 SetFileModifyDate
+
+Set the file modification time from the new value of the FileModifyDate tag.
+
+    $result = $exifTool->SetFileModifyDate($file);
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) File name
+
+2) [optional] Base time if applying shift (days before $^T)
+
+=item Return Value:
+
+1 if the time was changed, 0 if nothing was done, or -1 if there was an
+error setting the time.
+
+=back
+
+=head2 SetFileName
+
+Set the file name and directory.  If not specified, the new file name is
+derived from the new values of the FileName and Directory tags.  If the
+FileName tag contains a '/', then the file is renamed into a new directory.
+If FileName ends with '/', then it is taken as a directory name and the file
+is moved into the new directory.  The new value for the Directory tag takes
+precedence over any directory specified in FileName.
+
+    $result = $exifTool->SetFileName($file);
+    $result = $exifTool->SetFileName($file, $newName);
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) Current file name
+
+2) [optional] New file name
+
+=item Return Value:
+
+1 if the file name or directory was changed, 0 if nothing was done, or -1 if
+there was an error renaming the file.
+
+=item Notes:
+
+Will not overwrite existing files. New directories are created as necessary.
+
+=back
+
+=head2 SetNewGroups
+
+Set the order of the preferred groups when adding new information.  In
+subsequent calls to L</SetNewValue>, new information will be created in the
+first valid group of this list.  This has an impact only if the group is not
+specified when calling L</SetNewValue> and if the tag name exists in more
+than one group.  The default order is EXIF, IPTC, XMP then MakerNotes.  Any
+family 0 group name may be used.  Case is not significant.
+
+    $exifTool->SetNewGroups('XMP','EXIF','IPTC');
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1-N) Groups in order of priority.  If no groups are specified, the priorities
+are reset to the defaults.
+
+=item Return Value:
+
+None.
+
+=back
+
+=head2 GetNewGroups
+
+Get current group priority list.
+
+    @groups = $exifTool->GetNewGroups();
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+=item Return Values:
+
+List of group names in order of write priority.  Highest priority first.
+
+=back
+
+=head2 GetTagID
+
+Get the ID for the specified tag.  The ID is the IFD tag number in EXIF
+information, the property name in XMP information, or the data offset in a
+binary data block. For some tags, such as Composite tags where there is no ID,
+an empty string is returned.
+
+    $id = $exifTool->GetTagID($tag);
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) Tag key
+
+=item Return Values:
+
+Tag ID or '' of there is no ID for this tag.
+
+=back
+
+=head2 GetDescription
+
+Get description for specified tag.  This function will always return a
+defined value.  In the case where the description doesn't exist, the tag
+name is returned.
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) Tag key
+
+=item Return Values:
+
+A description for the specified tag.
+
+=back
+
+=head2 GetGroup
+
+Get group name for specified tag.
+
+    $group = $exifTool->GetGroup($tag, 0);
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) Tag key
+
+2) [optional] Group family number
+
+=item Return Values:
+
+Group name (or 'Other' if tag has no group).  If no group family is
+specified, L</GetGroup> returns the name of the group in family 0 when
+called in scalar context, or the names of groups for all families in list
+context. See L</GetAllGroups> for a list of groups in each famly.
+
+=back
+
+=head2 GetGroups
+
+Get list of group names for specified information.
+
+    @groups = $exifTool->GetGroups($info, 2);
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) [optional] Info hash ref (default is all extracted info)
+
+2) [optional] Group family number (default 0)
+
+=item Return Values:
+
+List of group names in alphabetical order. If information hash is not
+specified, the group names are returned for all extracted information.
+
+=back
+
+=head2 BuildCompositeTags
+
+Builds composite tags from required tags.  The composite tags are
+convenience tags which are derived from the values of other tags.  This
+routine is called automatically by L</ImageInfo> and L</ExtractInfo> if the
+Composite option is set.
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+=item Return Values:
+
+(none)
+
+=item Notes:
+
+Tag values are calculated in alphabetical order unless a tag Require's or
+Desire's another composite tag, in which case the calculation is deferred
+until after the other tag is calculated. Composite tags may need to read
+data from the image for their value to be determined, so for these
+L</BuildCompositeTags> must be called while the image is available.  This is
+only a problem if L</ImageInfo> is called with a filename (as opposed to a
+file reference or scalar reference) since in this case the file is closed
+before L</ImageInfo> returns.  However if you enable the Composite option,
+L</BuildCompositeTags> is called from within L</ImageInfo> before the file
+is closed.
+
+=back
+
+=head2 GetTagName [static]
+
+Get name of tag from tag key.  This is a convenience function that
+strips the embedded instance number, if it exists, from the tag key.
+
+Note: "static" in the heading above indicates that the function does not
+require an ExifTool object reference as the first argument.  All functions
+documented below are also static.
+
+    $tagName = Image::ExifTool::GetTagName($tag);
+
+=over 4
+
+=item Inputs:
+
+0) Tag key
+
+=item Return Value:
+
+Tag name.  This is the same as the tag key but has the instance number
+removed.
+
+=back
+
+=head2 GetShortcuts [static]
+
+Get a list of shortcut tags.
+
+=over 4
+
+=item Inputs:
+
+(none)
+
+=item Return Values:
+
+List of shortcut tags (as defined in Image::ExifTool::Shortcuts).
+
+=back
+
+=head2 GetAllTags [static]
+
+Get list of all available tag names.
+
+    @tagList = Image::ExifTool::GetAllTags($group);
+
+=over 4
+
+=item Inputs:
+
+0) [optional] Group name
+
+=item Return Values:
+
+A list of all available tags in alphabetical order, or all tags in specified
+group.  The group name is case insensitive, and any group in any family may
+be used except for EXIF family 1 groups (ie. the specific IFD).
+
+=back
+
+=head2 GetWritableTags [static]
+
+Get list of all writable tag names.
+
+    @tagList = Image::ExifTool::GetWritableTags($group);
+
+=over 4
+
+=item Inputs:
+
+0) [optional] Group name
+
+=item Return Values:
+
+A list of all writable tags in alphabetical order.  These are the tags for
+which values may be set through L</SetNewValue>.  If a group name is given,
+returns only writable tags in specified group.  The group name is case
+insensitive, and any group in any family may be used except for EXIF family
+1 groups (ie. the specific IFD).
+
+=back
+
+=head2 GetAllGroups [static]
+
+Get list of all group names in specified family.
+
+    @groupList = Image::ExifTool::GetAllGroups($family);
+
+=over 4
+
+=item Inputs:
+
+0) Group family number (0-2)
+
+=item Return Values:
+
+A list of all groups in the specified family in alphabetical order.
+
+=back
+
+Three families of groups are currently defined: 0, 1 and 2. Families 0 and 1
+are based on the file structure, and family 2 classifies information based
+on the logical category to which the information refers.
+
+Families 0 and 1 are similar except that family 1 is more specific, and
+sub-divides the EXIF, MakerNotes, XMP and ICC_Profile groups to give more
+detail about the specific location where the information was found.  The
+EXIF group is split up based on the specific IFD (Image File Directory), the
+MakerNotes group is divided into groups for each manufacturer, and the XMP
+group is separated based on the XMP namespace prefix.  Note that only common
+XMP namespaces are listed below but additional namespaces may be present in
+some XMP data.  Also note that the 'XMP-xmp...' group names may appear in
+the older form 'XMP-xap...' since these names evolved as the XMP standard
+was developed.  The ICC_Profile group is broken down to give information
+about the specific ICC_Profile tag from which multiple values were
+extracted.  As well, information extracted from the ICC_Profile header is
+separated into the ICC-header group.
+
+Here is a complete list of groups for each family:
+
+=over 4
+
+=item Family 0 (Information Type):
+
+AFCP, AIFF, APE, APP12, APP13, APP14, APP15, APP5, APP6, APP8, ASF, BMP,
+CanonVRD, Composite, DICOM, DNG, Ducky, EXIF, ExifTool, FLAC, File, Flash,
+FlashPix, FotoStation, GeoTiff, HTML, ICC_Profile, ID3, IPTC, JFIF, JPEG,
+Jpeg2000, Leaf, MIE, MIFF, MNG, MPC, MPEG, MakerNotes, Meta, PDF, PICT, PNG,
+PhotoMechanic, Photoshop, PostScript, PrintIM, QuickTime, RAF, RIFF, Real,
+SigmaRaw, Vorbis, XMP
+
+=item Family 1 (Specific Location):
+
+AFCP, AIFF, APE, ASF, Adobe, AdobeCM, BMP, Canon, CanonCustom, CanonRaw,
+CanonVRD, Casio, Composite, DICOM, DNG, Ducky, EPPIM, ExifIFD, ExifTool,
+FLAC, File, Flash, FlashPix, FotoStation, FujiFilm, GPS, GeoTiff,
+GlobParamIFD, GraphConv, HP, HTML, HTML-dc, HTML-ncc, HTML-prod, HTML-vw96,
+HTTP-equiv, ICC-chrm, ICC-clrt, ICC-header, ICC-meas, ICC-view, ICC_Profile,
+ID3, ID3v1, ID3v2_2, ID3v2_3, ID3v2_4, IFD0, IFD1, IPTC, InteropIFD, JFIF,
+JPEG, JVC, Jpeg2000, Kodak, KodakBordersIFD, KodakEffectsIFD, KyoceraRaw,
+Leaf, LeafSubIFD, MAC, MIE-Audio, MIE-Camera, MIE-Doc, MIE-Extender,
+MIE-Flash, MIE-GPS, MIE-Geo, MIE-Image, MIE-Lens, MIE-Main, MIE-MakerNotes,
+MIE-Meta, MIE-Orient, MIE-Preview, MIE-Thumbnail, MIE-UTM, MIE-Unknown,
+MIE-Video, MIFF, MNG, MPC, MPEG, MakerNotes, MakerUnknown, MetaIFD, Minolta,
+MinoltaRaw, Nikon, NikonCapture, NikonPreview, NikonScan, Olympus, PDF,
+PICT, PNG, Panasonic, Pentax, PhotoMechanic, Photoshop, PictureInfo,
+PostScript, PrintIM, QuickTime, RAF, RAF2, RIFF, RMETA, Real, Real-CONT,
+Real-MDPR, Real-PROP, Real-RA3, Real-RA4, Real-RA5, Real-RJMD, Ricoh, SPIFF,
+SR2, SRF#, Sanyo, Sigma, SigmaRaw, Sony, SubIFD, Track#, Vorbis, XMP,
+XMP-DICOM, XMP-PixelLive, XMP-aux, XMP-cc, XMP-crs, XMP-dc, XMP-dex,
+XMP-exif, XMP-iptcCore, XMP-lr, XMP-mediapro, XMP-microsoft, XMP-pdf,
+XMP-photomech, XMP-photoshop, XMP-tiff, XMP-xmp, XMP-xmpBJ, XMP-xmpDM,
+XMP-xmpMM, XMP-xmpPLUS, XMP-xmpRights, XMP-xmpTPg
+
+=item Family 2 (Category):
+
+Audio, Author, Camera, Document, ExifTool, Image, Location, Other, Printing,
+Time, Unknown, Video
+
+=back
+
+=head2 GetDeleteGroups [static]
+
+Get list of all deletable group names.
+
+    @delGroups = Image::ExifTool::GetDeleteGroups();
+
+=over 4
+
+=item Inputs:
+
+None.
+
+=item Return Values:
+
+A list of deletable group names in alphabetical order.  The current list of
+deletable group names is:
+
+AFCP, CIFF, CanonVRD, EXIF, ExifIFD, Ducky, File, FlashPix, FotoStation,
+GlobParamIFD, GPS, IFD0, IFD1, InteropIFD, ICC_Profile, IPTC, JFIF,
+MakerNotes, Meta, MetaIFD, MIE, PhotoMechanic, Photoshop, PNG, PrintIM,
+RMETA, SubIFD, Trailer, XMP
+
+All names in this list are either family 0 or family 1 group names, with the
+exception of 'Trailer' which allows all trailers in JPEG and TIFF-format
+images to be deleted at once, including unknown trailers.  To schedule a
+group for deletion, call L</SetNewValue> with an undefined value and a tag
+name like 'Trailer:*'.
+
+=back
+
+=head2 GetFileType [static]
+
+Get type of file given file name.
+
+    my $type = Image::ExifTool::GetFileType($filename);
+    my $desc = Image::ExifTool::GetFileType($filename, 1);
+
+=over 4
+
+=item Inputs:
+
+0) [optional] File name (or just an extension)
+
+1) [optional]  Flag to return a description instead of a type
+
+=item Return Value:
+
+A string, based on the file extension, which represents the type of file.
+Returns undefined value if file type is not supported by ExifTool.  In array
+context, may return more than one file type if the file may be different
+formats.  Returns a list of extensions for all recognized file types if no
+input extension is specified.
+
+=back
+
+=head2 CanWrite [static]
+
+Can the specified file or file type be written?
+
+    my $writable = Image::ExifTool::CanWrite($filename);
+
+=over 4
+
+=item Inputs:
+
+0) File name, file extension, or file type
+
+=item Return Value:
+
+True if the specified file type can be written (edited).
+
+=back
+
+=head2 CanCreate [static]
+
+Can the specified file or file type be created?
+
+    my $creatable = Image::ExifTool::CanCreate($filename);
+
+=over 4
+
+=item Inputs:
+
+0) File name, file extension, or file type
+
+=item Return Value:
+
+True if the specified file type can be created from scratch.  Currently,
+this can only be done with XMP files.
+
+=back
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 CREDITS
+
+Many people have helped in the development of ExifTool through their bug
+reports, comments and suggestions, and/or additions to the code.  See
+html/index.html in the Image::ExifTool distribution package for a list of
+people who have contributed to this project.
+
+=head1 SEE ALSO
+
+L<exiftool(1)|exiftool>,
+L<Image::ExifTool::TagNames(3pm)|Image::ExifTool::TagNames>,
+L<Image::ExifTool::Shortcuts(3pm)|Image::ExifTool::Shortcuts>,
+L<Image::ExifTool::Shift.pl|Image::ExifTool::Shift.pl>,
+L<Image::Info(3pm)|Image::Info>,
+L<Image::MetaData::JPEG(3pm)|Image::MetaData::JPEG>
+
+=cut
+
+# end
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/AFCP.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/AFCP.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/AFCP.pm	(revision 20131)
@@ -0,0 +1,273 @@
+#------------------------------------------------------------------------------
+# File:         AFCP.pm
+#
+# Description:  Read/write AFCP trailer
+#
+# Revisions:    12/26/2005 - P. Harvey Created
+#
+# References:   1) http://www.tocarte.com/media/axs_afcp_spec.pdf
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::AFCP;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.02';
+
+sub ProcessAFCP($$);
+
+%Image::ExifTool::AFCP::Main = (
+    PROCESS_PROC => \&ProcessAFCP,
+    NOTES => q{
+AFCP stands for AXS File Concatenation Protocol, and is a poorly designed
+protocol for appending information to the end of files.  This can be used as
+an auxiliary technique to store IPTC information in images, but is
+incompatible with some file formats.
+
+ExifTool will read and write (but not create) AFCP IPTC information in JPEG
+images, but not other image formats.
+    },
+    IPTC => { SubDirectory => { TagTable => 'Image::ExifTool::IPTC::Main' } },
+    TEXT => 'Text',
+    Nail => {
+        Name => 'ThumbnailImage',
+        ValueConv => q{
+            my $img = substr($val, 18);
+            return $self->ValidateImage(\$img,$tag);
+        },
+    },
+    PrVw => {
+        Name => 'PreviewImage',
+        ValueConv => q{
+            my $img = substr($val, 18);
+            return $self->ValidateImage(\$img,$tag);
+        },
+    },
+);
+
+#------------------------------------------------------------------------------
+# Read/write AFCP information in a file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# (Set 'ScanForAFCP' member in dirInfo to scan from current position for AFCP)
+# Returns: 1 on success, 0 if this file didn't contain AFCP information
+#          -1 on write error or if the offsets were incorrect on reading
+# - updates DataPos to point to actual AFCP start if ScanForAFCP is set
+# - updates DirLen to trailer length
+# - returns Fixup reference in dirInfo hash when writing
+sub ProcessAFCP($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $curPos = $raf->Tell();
+    my $offset = $$dirInfo{Offset} || 0;    # offset from end of file
+    my $rtnVal = 0;
+
+NoAFCP: for (;;) {
+        my ($buff, $fix, $dirBuff, $valBuff, $fixup, $vers);
+        # look for AXS trailer
+        last unless $raf->Seek(-12-$offset, 2) and
+                    $raf->Read($buff, 12) == 12 and
+                    $buff =~ /^(AXS(!|\*))/;
+        my $endPos = $raf->Tell();
+        my $hdr = $1;
+        SetByteOrder($2 eq '!' ? 'MM' : 'II');
+        my $startPos = Get32u(\$buff, 4);
+        if ($raf->Seek($startPos, 0) and $raf->Read($buff, 12) == 12 and $buff =~ /^$hdr/) {
+            $fix = 0;
+        } else {
+            $rtnVal = -1;
+            # look for start of AXS trailer if 'ScanForAFCP'
+            last unless $$dirInfo{ScanForAFCP} and $raf->Seek($curPos, 0);
+            my $actualPos = $curPos;
+            # first look for header right at current position
+            for (;;) {
+                last if $raf->Read($buff, 12) == 12 and $buff =~ /^$hdr/;
+                last NoAFCP if $actualPos != $curPos;
+                # scan for AXS header (could be after preview image)
+                for (;;) {
+                    my $buf2;
+                    $raf->Read($buf2, 65536) or last NoAFCP;
+                    $buff .= $buf2;
+                    if ($buff =~ /$hdr/g) {
+                        $actualPos += pos($buff) - length($hdr);
+                        last;   # ok, now go back and re-read header
+                    }
+                    $buf2 = substr($buf2, -3);  # only need last 3 bytes for next test
+                    $actualPos += length($buff) - length($buf2);
+                    $buff = $buf2;
+                }
+                last unless $raf->Seek($actualPos, 0);  # seek to start of AFCP
+            }
+            # calculate shift for fixing AFCP offsets
+            $fix = $actualPos - $startPos;
+        }
+        # set variables returned in dirInfo hash
+        $$dirInfo{DataPos} = $startPos + $fix;  # actual start position
+        $$dirInfo{DirLen} = $endPos - ($startPos + $fix);
+
+        $rtnVal = 1;
+        my $verbose = $exifTool->Options('Verbose');
+        my $out = $exifTool->Options('TextOut');
+        my $outfile = $$dirInfo{OutFile};
+        if ($outfile) {
+            # allow all AFCP information to be deleted
+            if ($exifTool->{DEL_GROUP}->{AFCP}) {
+                $verbose and print $out "  Deleting AFCP\n";
+                ++$exifTool->{CHANGED};
+                last;
+            }
+            $dirBuff = $valBuff = '';
+            require Image::ExifTool::Fixup;
+            $fixup = $$dirInfo{Fixup};
+            $fixup or $fixup = $$dirInfo{Fixup} = new Image::ExifTool::Fixup;
+            $vers = substr($buff, 4, 2); # get version number
+        } else {
+            $exifTool->DumpTrailer($dirInfo) if $verbose or $exifTool->{HTML_DUMP};
+        }
+        # read AFCP directory data
+        my $numEntries = Get16u(\$buff, 6);
+        my $dir;
+        unless ($raf->Read($dir, 12 * $numEntries) == 12 * $numEntries) {
+            $exifTool->Error('Error reading AFCP directory', 1);
+            last;
+        }
+        if ($verbose > 2 and not $outfile) {
+            my $dat = $buff . $dir;
+            print $out "  AFCP Directory:\n";
+            Image::ExifTool::HexDump(\$dat, undef,
+                Addr   => $$dirInfo{DataPos},
+                Width  => 12,
+                Prefix => $exifTool->{INDENT},
+                Out => $out,
+            );
+        }
+        $fix and $exifTool->Warn("Adjusted AFCP offsets by $fix", 1);
+#
+# process AFCP directory
+#
+        my $tagTablePtr = GetTagTable('Image::ExifTool::AFCP::Main');
+        my ($index, $entry);
+        for ($index=0; $index<$numEntries; ++$index) {
+            my $entry = 12 * $index;
+            my $tag = substr($dir, $entry, 4);
+            my $size = Get32u(\$dir, $entry + 4);
+            my $offset = Get32u(\$dir, $entry + 8);
+            if ($size < 0x80000000 and
+                $raf->Seek($offset+$fix, 0) and
+                $raf->Read($buff, $size) == $size)
+            {
+                if ($outfile) {
+                    # rewrite this information
+                    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+                    if ($tagInfo and $$tagInfo{SubDirectory}) {
+                        my %subdirInfo = (
+                            DataPt => \$buff,
+                            DirStart => 0,
+                            DirLen => $size,
+                            DataPos => $offset + $fix,
+                            Parent => 'AFCP',
+                        );
+                        my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                        my $newDir = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+                        if (defined $newDir) {
+                            $size = length $newDir;
+                            $buff = $newDir;
+                        }
+                    }
+                    $fixup->AddFixup(length($dirBuff) + 8);
+                    $dirBuff .= $tag . Set32u($size) . Set32u(length $valBuff);
+                    $valBuff .= $buff;
+                } else {
+                    # extract information
+                    $exifTool->HandleTag($tagTablePtr, $tag, $buff,
+                        DataPt => \$buff,
+                        Size => $size,
+                        Index => $index,
+                        DataPos => $offset + $fix,
+                    );
+                }
+            } else {
+                $exifTool->Warn("Bad AFCP directory");
+                $rtnVal = -1 if $outfile;
+                last;
+            }
+        }
+        if ($outfile and length($dirBuff)) {
+            my $outPos = Tell($outfile);    # get current outfile position
+            # apply fixup to directory pointers
+            my $valPos = $outPos + 12;      # start of value data
+            $fixup->{Shift} += $valPos + length($dirBuff);
+            $fixup->ApplyFixup(\$dirBuff);
+            # write the AFCP header, directory, value data and EOF record (with zero checksums)
+            Write($outfile, $hdr, $vers, Set16u(length($dirBuff)/12), Set32u(0),
+                  $dirBuff, $valBuff, $hdr, Set32u($outPos), Set32u(0)) or $rtnVal = -1;
+            # complete fixup so the calling routine can apply further shifts
+            $fixup->AddFixup(length($dirBuff) + length($valBuff) + 4);
+            $fixup->{Start} += $valPos;
+            $fixup->{Shift} -= $valPos;
+        }
+        last;
+    }
+    return $rtnVal;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::AFCP - Read/write AFCP trailer
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to extract
+information from the AFCP trailer.  Although the AFCP specification is
+compatible with various file formats, ExifTool currently only processes AFCP
+in JPEG images.
+
+=head1 NOTES
+
+AFCP is a specification which allows meta information (including IPTC) to be
+appended to the end of a file.
+
+It is a poorly designed protocol because (like TIFF) it uses absolute
+offsets to specify data locations.  This is a huge blunder because it makes
+the AFCP information dependent on the file length, so it is easily
+invalidated by image editing software which doesn't recognize the AFCP
+trailer to fix up these offsets when the file length changes.  ExifTool will
+attempt to fix these invalid offsets if possible.
+
+Scanning for AFCP information may be time consuming, especially when reading
+from a sequential device, since the information is at the end of the file.
+In these instances, the ExifTool FastScan option may be used to disable
+scanning for AFCP information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.tocarte.com/media/axs_afcp_spec.pdf>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/AFCP Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/AIFF.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/AIFF.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/AIFF.pm	(revision 20131)
@@ -0,0 +1,219 @@
+#------------------------------------------------------------------------------
+# File:         AIFF.pm
+#
+# Description:  Read AIFF meta information
+#
+# Revisions:    01/06/2006 - P. Harvey Created
+#
+# References:   1) http://developer.apple.com/documentation/QuickTime/INMAC/SOUND/imsoundmgr.30.htm#pgfId=3190
+#               2) http://astronomy.swin.edu.au/~pbourke/dataformats/aiff/
+#               3) http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::AIFF;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::ID3;
+
+$VERSION = '1.01';
+
+# information for time/date-based tags (time zero is Jan 1, 1904)
+my %timeInfo = (
+    Groups => { 2 => 'Time' },
+    ValueConv => 'ConvertUnixTime($val - ((66 * 365 + 17) * 24 * 3600))',
+    PrintConv => '$self->ConvertDateTime($val)',
+);
+
+# AIFF info
+%Image::ExifTool::AIFF::Main = (
+    PROCESS_PROC => \&Image::ExifTool::AIFF::ProcessSubChunks,
+    GROUPS => { 2 => 'Audio' },
+    NOTES => 'Only the tags decoded by ExifTool are listed in this table.',
+#    FORM => 'Format',
+    FVER => {
+        Name => 'FormatVersion',
+        SubDirectory => { TagTable => 'Image::ExifTool::AIFF::FormatVers' },
+    },
+    COMM => {
+        Name => 'Common',
+        SubDirectory => { TagTable => 'Image::ExifTool::AIFF::Common' },
+    },
+    COMT => {
+        Name => 'Comment',
+        SubDirectory => { TagTable => 'Image::ExifTool::AIFF::Comment' },
+    },
+    NAME => 'Name',
+    AUTH => { Name => 'Author', Groups => { 2 => 'Author' } },
+   '(c) ' => { Name => 'Copyright', Groups => { 2 => 'Author' } },
+    ANNO => 'Annotation',
+   'ID3 ' => {
+        Name => 'ID3',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ID3::Main',
+            ProcessProc => \&Image::ExifTool::ID3::ProcessID3,
+        },
+    },
+#    SSND => 'SoundData',
+#    MARK => 'Marker',
+#    INST => 'Instrument',
+#    MIDI => 'MidiData',
+#    AESD => 'AudioRecording',
+#    APPL => 'ApplicationSpecific',
+);
+
+%Image::ExifTool::AIFF::Common = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Audio' },
+    FORMAT => 'int16u',
+    0 => 'NumChannels',
+    1 => { Name => 'NumSampleFrames', Format => 'int32u' },
+    3 => 'SampleSize',
+    4 => { Name => 'SampleRate', Format => 'extended' }, #3
+    9 => {
+        Name => 'CompressionType',
+        Format => 'string[4]',
+        PrintConv => {
+            NONE => 'None',
+            ACE2 => 'ACE 2-to-1',
+            ACE8 => 'ACE 8-to-3',
+            MAC3 => 'MAC 3-to-1',
+            MAC6 => 'MAC 6-to-1',
+            sowt => 'Little-endian, no compression',
+        },
+    },
+);
+
+%Image::ExifTool::AIFF::FormatVers = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int32u',
+    0 => { Name => 'FormatVersionTime', %timeInfo },
+);
+
+%Image::ExifTool::AIFF::Comment = (
+    PROCESS_PROC => \&Image::ExifTool::AIFF::ProcessComment,
+    GROUPS => { 2 => 'Audio' },
+    0 => { Name => 'CommentTime', %timeInfo },
+    1 => 'MarkerID',
+    2 => 'Comment',
+);
+
+#------------------------------------------------------------------------------
+# Process AIFF Comment chunk
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) tag table ref
+# Returns: 1 on success
+sub ProcessComment($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirLen = $$dirInfo{DirLen};
+    my $verbose = $exifTool->Options('Verbose');
+    return 0 unless $dirLen > 2;
+    my $numComments = unpack('n',$$dataPt);
+    my $pos = 2;
+    my $i;
+    $verbose and $exifTool->VerboseDir('Comment', $numComments);
+    for ($i=0; $i<$numComments; ++$i) {
+        last if $pos + 8 > $dirLen;
+        my ($time, $markerID, $size) = unpack("x${pos}Nnn", $$dataPt);
+        $exifTool->HandleTag($tagTablePtr, 0, $time);
+        $exifTool->HandleTag($tagTablePtr, 1, $markerID) if $markerID;
+        $pos += 8;
+        last if $pos + $size > $dirLen;
+        my $val = substr($$dataPt, $pos, $size);
+        $exifTool->HandleTag($tagTablePtr, 2, $val);
+        ++$size if $size & 0x01;    # account for padding byte if necessary
+        $pos += $size;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Extract information from a AIFF file
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid AIFF file
+sub ProcessAIFF($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->Options('Verbose');
+    my ($buff, $err);
+
+    # verify this is a valid AIFF file
+    return 0 unless $raf->Read($buff, 12) == 12;
+    return 0 unless $buff =~ /^FORM....(AIF(F|C))/s;
+    $exifTool->SetFileType($1);
+    SetByteOrder('MM');
+    my $tagTablePtr = GetTagTable('Image::ExifTool::AIFF::Main');
+    my $pos = 12;
+#
+# Read chunks in AIFF image
+#
+    for (;;) {
+        $raf->Read($buff, 8) == 8 or last;
+        $pos += 8;
+        my ($tag, $len) = unpack('a4N', $buff);
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        $exifTool->VPrint(0, "AIFF '$tag' chunk ($len bytes of data):\n");
+        # AIFF chunks are padded to an even number of bytes
+        my $len2 = $len + ($len & 0x01);
+        if ($tagInfo) {
+            $raf->Read($buff, $len2) == $len2 or $err=1, last;
+            $exifTool->HandleTag($tagTablePtr, $tag, $buff,
+                DataPt => \$buff,
+                DataPos => $pos,
+                Start => 0,
+                Size => $len,
+            );
+        } else {
+            $raf->Seek($len2, 1) or $err=1, last;
+        }
+        $pos += $len2;
+    }
+    $err and $exifTool->Warn('Error reading AIFF file (corrupted?)');
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::AIFF - Read AIFF meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to extract
+information from AIFF (Audio Interchange File Format) audio files.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://developer.apple.com/documentation/QuickTime/INMAC/SOUND/imsoundmgr.30.htm#pgfId=3190>
+
+=item L<http://astronomy.swin.edu.au/~pbourke/dataformats/aiff/>
+
+=item L<http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/AIFF Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/APE.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/APE.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/APE.pm	(revision 20131)
@@ -0,0 +1,254 @@
+#------------------------------------------------------------------------------
+# File:         APE.pm
+#
+# Description:  Read Monkey's Audio meta information
+#
+# Revisions:    11/13/2006 - P. Harvey Created
+#
+# References:   1) http://www.monkeysaudio.com/
+#               2) http://www.personal.uni-jena.de/~pfk/mpp/sv8/apetag.html
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::APE;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.01';
+
+# APE metadata blocks
+%Image::ExifTool::APE::Main = (
+    GROUPS => { 2 => 'Audio' },
+    NOTES => q{
+        Tags found in Monkey's Audio (APE) information.  Only a few common tags are
+        listed below, but ExifTool will extract any tag found.  ExifTool supports
+        APEv1 and APEv2 tags, as well as ID3 information in APE files.
+    },
+    Album   => { },
+    Artist  => { },
+    Genre   => { },
+    Title   => { },
+    Track   => { },
+    Year    => { },
+    'Tool Version' => { Name => 'ToolVersion' },
+    'Tool Name'    => { Name => 'ToolName' },
+);
+
+# APE MAC header version 3.97 or earlier
+%Image::ExifTool::APE::OldHeader = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 1 => 'MAC', 2 => 'Audio' },
+    FORMAT => 'int16u',
+    NOTES => 'APE MAC audio header for version 3.97 or earlier.',
+    0 => {
+        Name => 'APEVersion',
+        ValueConv => '$val / 1000',
+    },
+    1 => 'CompressionLevel',
+  # 2 => 'FormatFlags',
+    3 => 'Channels',
+    4 => { Name => 'SampleRate', Format => 'int32u' },
+  # 6 => { Name => 'HeaderBytes', Format => 'int32u' }, # WAV header bytes
+  # 8 => { Name => 'TerminatingBytes', Format => 'int32u' },
+    10 => { Name => 'TotalFrames', Format => 'int32u' },
+    12 => { Name => 'FinalFrameBlocks', Format => 'int32u' },
+);
+
+# APE MAC header version 3.98 or later
+%Image::ExifTool::APE::NewHeader = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 1 => 'MAC', 2 => 'Audio' },
+    FORMAT => 'int16u',
+    NOTES => 'APE MAC audio header for version 3.98 or later.',
+    0 => 'CompressionLevel',
+  # 1 => 'FormatFlags',
+    2 => { Name => 'BlocksPerFrame',   Format => 'int32u' },
+    4 => { Name => 'FinalFrameBlocks', Format => 'int32u' },
+    6 => { Name => 'TotalFrames',      Format => 'int32u' },
+    8 => 'BitsPerSample',
+    9 => 'Channels',
+    10 => { Name => 'SampleRate',      Format => 'int32u' },
+);
+
+#------------------------------------------------------------------------------
+# Make tag info hash for specified tag
+# Inputs: 0) tag name, 1) tag table ref
+# - must only call if tag doesn't exist
+sub MakeTag($$)
+{
+    my ($tag, $tagTablePtr) = @_;
+    my $name = ucfirst(lc($tag));
+    # remove invalid characters in tag name and capitalize following letters
+    $name =~ s/[^\w-]+(.?)/\U$1/sg;
+    $name =~ s/([a-z0-9])_([a-z])/$1\U$2/g;
+    Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name });
+}
+
+#------------------------------------------------------------------------------
+# Extract information from an APE file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# - Just looks for APE trailer if FileType is already set
+# Returns: 1 on success, 0 if this wasn't a valid APE file
+sub ProcessAPE($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+
+    # must first check for leading/trailing ID3 information
+    unless ($exifTool->{DONE_ID3}) {
+        require Image::ExifTool::ID3;
+        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
+    }
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->Options('Verbose');
+    my ($buff, $i, $header, $tagTablePtr, $dataPos);
+
+    # check APE signature and process audio information
+    # unless this is some other type of file
+    unless ($exifTool->{VALUE}->{FileType}) {
+        $raf->Read($buff, 32) == 32 or return 0;
+        $buff =~ /^(MAC |APETAGEX)/ or return 0;
+        $exifTool->SetFileType();
+        SetByteOrder('II');
+
+        if ($buff =~ /^APETAGEX/) {
+            # we already read the APE header
+            $header = 1;
+        } else {
+            # process the MAC header
+            my $vers = Get16u(\$buff, 4);
+            my $table;
+            if ($vers <= 3970) {
+                $buff = substr($buff, 4);
+                $table = GetTagTable('Image::ExifTool::APE::OldHeader');
+            } else {
+                my $dlen = Get32u(\$buff, 8);
+                my $hlen = Get32u(\$buff, 12);
+                unless ($dlen & 0x80000000 or $hlen & 0x80000000) {
+                    if ($raf->Seek($dlen, 0) and $raf->Read($buff, $hlen) == $hlen) {
+                        $table = GetTagTable('Image::ExifTool::APE::NewHeader');
+                    }
+                }
+            }
+            $exifTool->ProcessDirectory( { DataPt => \$buff }, $table) if $table;
+        }
+    }
+    # look for APE trailer unless we already found an APE header
+    unless ($header) {
+        # look for the APE trailer footer...
+        my $footPos = -32;
+        # (...but before the ID3v1 trailer if it exists)
+        $footPos -= 128 if $exifTool->{DONE_ID3} == 2;
+        $raf->Seek($footPos, 2)     or return 1;
+        $raf->Read($buff, 32) == 32 or return 1;
+        $buff =~ /^APETAGEX/        or return 1;
+        SetByteOrder('II');
+    }
+#
+# Read the APE data (we have just read the APE header or footer into $buff)
+#
+    my ($version, $size, $count, $flags) = unpack('x8V4', $buff);
+    $version /= 1000;
+    $size -= 32;    # get size of data only
+    if (($size & 0x80000000) == 0 and
+        ($header or $raf->Seek(-$size-32, 1)) and
+        $raf->Read($buff, $size) == $size)
+    {
+        if ($verbose) {
+            $exifTool->VerboseDir("APEv$version", $count, $size);
+            $exifTool->VerboseDump(\$buff, DataPos => $raf->Tell() - $size);
+        }
+        $tagTablePtr = GetTagTable('Image::ExifTool::APE::Main');
+        $dataPos = $raf->Tell() - $size;
+    } else {
+        $count = -1;
+    }
+#
+# Process the APE tags
+#
+    my $pos = 0;
+    for ($i=0; $i<$count; ++$i) {
+        # read next APE tag
+        last if $pos + 8 > $size;
+        my $len = Get32u(\$buff, $pos);
+        my $flags = Get32u(\$buff, $pos + 4);
+        pos($buff) = $pos + 8;
+        last unless $buff =~ /\G(.*?)\0/sg;
+        my $tag = $1;
+        $pos = pos($buff);
+        last if $pos + $len > $size;
+        my $val = substr($buff, $pos, $len);
+        MakeTag($tag, $tagTablePtr) unless $$tagTablePtr{$tag};
+        # handle binary-value tags
+        if (($flags & 0x06) == 0x02) {
+            my $buf2 = $val;
+            $val = \$buf2;
+            # extract cover art description separately (hackitty hack)
+            if ($tag =~ /^Cover Art/) {
+                $buf2 =~ s/^([\x20-\x7f]*)\0//;
+                if ($1) {
+                    my $t = "$tag Desc";
+                    my $v = $1;
+                    MakeTag($t, $tagTablePtr) unless $$tagTablePtr{$t};
+                    $exifTool->HandleTag($tagTablePtr, $t, $v);
+                }
+            }
+        }
+        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            Index => $i,
+            DataPt => \$buff,
+            DataPos => $dataPos,
+            Start => $pos,
+            Size => $len,
+        );
+        $pos += $len;
+    }
+    $i == $count or $exifTool->Warn('Bad APE trailer');
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::APE - Read Monkey's Audio meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to extract meta
+information from Monkey's Audio (APE) audio files.
+
+=head1 BUGS
+
+Currently doesn't parse MAC header unless it is at the start of the file.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.monkeysaudio.com/>
+
+=item L<http://www.personal.uni-jena.de/~pfk/mpp/sv8/apetag.html>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/APE Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/APP12.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/APP12.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/APP12.pm	(revision 20131)
@@ -0,0 +1,329 @@
+#------------------------------------------------------------------------------
+# File:         APP12.pm
+#
+# Description:  Read APP12 meta information
+#
+# Revisions:    10/18/2005 - P. Harvey Created
+#
+# References:   1) Heinrich Giesen private communication
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::APP12;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess);
+
+$VERSION = '1.06';
+
+sub ProcessAPP12($$$);
+sub ProcessDucky($$$);
+sub WriteDucky($$$);
+
+# APP12 tags (ref PH)
+%Image::ExifTool::APP12::PictureInfo = (
+    PROCESS_PROC => \&ProcessAPP12,
+    GROUPS => { 0 => 'APP12', 1 => 'PictureInfo', 2 => 'Image' },
+    NOTES => q{
+        The JPEG APP12 "Picture Info" segment was used by some older cameras, and
+        contains ASCII-based meta information.  Below are some tags which have been
+        observed Agfa and Polaroid images, however ExifTool will extract information
+        from any tags found in this segment.
+    },
+    FNumber => {
+        ValueConv => '$val=~s/^[A-Za-z ]*//;$val',  # Agfa leads with an 'F'
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    Aperture => {
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    TimeDate => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Groups => { 2 => 'Time' },
+        ValueConv => '$val=~/^\d+$/ ? ConvertUnixTime($val) : $val',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    Shutter => {
+        Name => 'ExposureTime',
+        ValueConv => '$val * 1e-6',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    shtr => {
+        Name => 'ExposureTime',
+        ValueConv => '$val * 1e-6',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+   'Serial#'    => {
+        Name => 'SerialNumber',
+        Groups => { 2 => 'Camera' },
+    },
+    Flash       => { PrintConv => { 0 => 'Off', 1 => 'On' } },
+    Macro       => { PrintConv => { 0 => 'Off', 1 => 'On' } },
+    StrobeTime  => { },
+    Ytarget     => { Name => 'YTarget' },
+    ylevel      => { Name => 'YLevel' },
+    FocusPos    => { },
+    FocusMode   => { },
+    Quality     => { },
+    ExpBias     => 'ExposureCompensation',
+    FWare       => 'FirmwareVersion',
+    StrobeTime  => { },
+    Resolution  => { },
+    Protect     => { },
+    ConTake     => { },
+    ImageSize   => { PrintConv => '$val=~tr/-/x/;$val' },
+    ColorMode   => { },
+    Zoom        => { },
+    ZoomPos     => { },
+    LightS      => { },
+    Type        => {
+        Name => 'CameraType',
+        Groups => { 2 => 'Camera' },
+        DataMember => 'CameraType',
+        RawConv => '$self->{CameraType} = $val',
+    },
+    Version     => { Groups => { 2 => 'Camera' } },
+    ID          => { Groups => { 2 => 'Camera' } },
+);
+
+# APP12 segment written in Photoshop "Save For Web" images
+# (from tests with Photoshop 7 files - PH/1)
+%Image::ExifTool::APP12::Ducky = (
+    PROCESS_PROC => \&ProcessDucky,
+    WRITE_PROC => \&WriteDucky,
+    GROUPS => { 0 => 'Ducky', 1 => 'Ducky', 2 => 'Image' },
+    WRITABLE => 'string',
+    NOTES => q{
+        Photoshop uses the JPEG APP12 "Ducky" segment to store some information in
+        "Save for Web" images.
+    },
+    1 => { #PH
+        Name => 'Quality',
+        Priority => 0,
+        Avoid => 1,
+        Writable => 'int32u',
+        ValueConv => 'unpack("N",$val)',    # 4-byte integer
+        ValueConvInv => 'pack("N",$val)',
+        PrintConv => '"$val%"',
+        PrintConvInv => '$val=~/(\d+)/ ? $1 : undef',
+    },
+    2 => { #1
+        Name => 'Comment',
+        Priority => 0,
+        Avoid => 1,
+        # (ignore 4-byte character count at start of value)
+        ValueConv => '$self->Unicode2Charset(substr($val,4),"MM")',
+        ValueConvInv => 'pack("N",length $val) . $self->Charset2Unicode($val,"MM")',
+    },
+    3 => { #PH
+        Name => 'Copyright',
+        Priority => 0,
+        Avoid => 1,
+        Groups => { 2 => 'Author' },
+        # (ignore 4-byte character count at start of value)
+        ValueConv => '$self->Unicode2Charset(substr($val,4),"MM")',
+        ValueConvInv => 'pack("N",length $val) . $self->Charset2Unicode($val,"MM")',
+    },
+);
+
+#------------------------------------------------------------------------------
+# Write APP12 Ducky segment
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: New directory data or undefined on error
+sub WriteDucky($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    $exifTool or return 1;    # allow dummy access to autoload this package
+    my $dataPt = $$dirInfo{DataPt};
+    my $pos = $$dirInfo{DirStart};
+    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+    my @addTags = sort { $a <=> $b } keys(%$newTags);
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my ($dirEnd, %doneTags);
+    if ($dataPt) {
+        $dirEnd = $pos + $$dirInfo{DirLen};
+    } else {
+        my $tmp = '';
+        $dataPt = \$tmp;
+        $pos = $dirEnd = 0;
+    }
+    my $newData = '';
+    SetByteOrder('MM');
+    # process all data blocks in Ducky segment
+    for (;;) {
+        my ($tag, $len, $val);
+        if ($pos + 4 <= $dirEnd) {
+            $tag = Get16u($dataPt, $pos);
+            $len = Get16u($dataPt, $pos + 2);
+            $pos += 4;
+            if ($pos + $len > $dirEnd) {
+                $exifTool->Warn('Invalid Ducky block length');
+                return undef;
+            }
+            $val = substr($$dataPt, $pos, $len);
+            $pos += $len;
+        } else {
+            last unless @addTags;
+            $tag = pop @addTags;
+            next if $doneTags{$tag};
+        }
+        $doneTags{$tag} = 1;
+        my $tagInfo = $$newTags{$tag};
+        if ($tagInfo) {
+            my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+            my $isNew;
+            if (defined $val) {
+                if (Image::ExifTool::IsOverwriting($newValueHash, $val)) {
+                    if ($verbose > 1) {
+                        my $pval = $exifTool->Printable($val);
+                        print $out "    - Ducky:$$tagInfo{Name} = '$pval'\n";
+                    }
+                    $isNew = 1;
+                }
+            } else {
+                next unless Image::ExifTool::IsCreating($newValueHash);
+                $isNew = 1;
+            }
+            if ($isNew) {
+                $val = Image::ExifTool::GetNewValues($newValueHash);
+                ++$exifTool->{CHANGED};
+                next unless defined $val;   # next if tag is being deleted
+                if ($verbose > 1) {
+                    my $pval = $exifTool->Printable($val);
+                    print $out "    + Ducky:$$tagInfo{Name} = '$pval'\n";
+                }
+            }
+        }
+        $newData .= pack('nn', $tag, length $val) . $val;
+    }
+    $newData .= "\0\0" if length $newData;
+    return $newData;
+}
+
+#------------------------------------------------------------------------------
+# Process APP12 Ducky segment (ref PH)
+# Inputs: 0) ExifTool object reference, 1) Directory information ref, 2) tag table ref
+# Returns: 1 on success, 0 if this wasn't a recognized Ducky segment
+# Notes: This segment has the following format:
+#   1) 5 bytes: "Ducky"
+#   2) multiple data blocks (all integers are big endian):
+#      a) 2 bytes: block type (0=end, 1=Quality, 2=Comment, 3=Copyright)
+#      b) 2 bytes: block length (N)
+#      c) N bytes: block data
+sub ProcessDucky($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $pos = $$dirInfo{DirStart};
+    my $dirEnd = $pos + $$dirInfo{DirLen};
+    SetByteOrder('MM');
+    # process all data blocks in Ducky segment
+    for (;;) {
+        last if $pos + 4 > $dirEnd;
+        my $tag = Get16u($dataPt, $pos);
+        my $len = Get16u($dataPt, $pos + 2);
+        $pos += 4;
+        if ($pos + $len > $dirEnd) {
+            $exifTool->Warn('Invalid Ducky block length');
+            last;
+        }
+        my $val = substr($$dataPt, $pos, $len);
+        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            DataPt => $dataPt,
+            DataPos => $$dirInfo{DataPos},
+            Start => $pos,
+            Size => $len,
+        );
+        $pos += $len;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process APP12 Picture Info segment (ref PH)
+# Inputs: 0) ExifTool object reference, 1) Directory information ref, 2) tag table ref
+# Returns: 1 on success, 0 if this wasn't a recognized APP12
+sub ProcessAPP12($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
+    if ($dirLen != $dirStart + length($$dataPt)) {
+        my $buff = substr($$dataPt, $dirStart, $dirLen);
+        $dataPt = \$buff;
+    } else {
+        pos($$dataPt) = $$dirInfo{DirStart};
+    }
+    my $verbose = $exifTool->Options('Verbose');
+    my $success = 0;
+    my $section = '';
+    pos($$dataPt) = 0;
+
+    # this regular expression is a bit complex, but basically we are looking for
+    # section headers (ie. "[Camera Info]") and tag/value pairs (ie. "tag=value",
+    # where "value" may contain white space), separated by spaces or CR/LF.
+    # (APP12 uses CR/LF, but Olympus TextualInfo is similar and uses spaces)
+    while ($$dataPt =~ /(\[.*?\]|[\w#-]+=[\x20-\x7e]+?(?=\s*([\n\r\0]|[\w#-]+=|\[|$)))/g) {
+        my $token = $1;
+        # was this a section name?
+        if ($token =~ /^\[(.*)\]/) {
+            $exifTool->VerboseDir($1) if $verbose;
+            $section = ($token =~ /\[(\S+) ?Info\]/i) ? $1 : '';
+            $success = 1;
+            next;
+        }
+        $exifTool->VerboseDir($$dirInfo{DirName}) if $verbose and not $success;
+        $success = 1;
+        my ($tag, $val) = ($token =~ /(\S+)=(.+)/);
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        $verbose and $exifTool->VerboseInfo($tag, $tagInfo, Value => $val);
+        unless ($tagInfo) {
+            # add new tag to table
+            $tagInfo = { Name => $tag };
+            # put in Camera group if information in "Camera" section
+            $$tagInfo{Groups} = { 2 => 'Camera' } if $section =~ /camera/i;
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        $exifTool->FoundTag($tagInfo, $val);
+    }
+    return $success;
+}
+
+
+1;  #end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::APP12 - Read APP12 meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+APP12 meta information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Heinrich Giesen for his help decoding APP12 "Ducky" information.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/APP12 Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/ASF.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/ASF.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/ASF.pm	(revision 20131)
@@ -0,0 +1,981 @@
+#------------------------------------------------------------------------------
+# File:         ASF.pm
+#
+# Description:  Read ASF/WMA/WMV meta information
+#
+# Revisions:    12/23/2005 - P. Harvey Created
+#
+# References:   1) http://www.microsoft.com/windows/windowsmedia/format/asfspec.aspx
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::ASF;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.05';
+
+sub ProcessMetadata($$$);
+sub ProcessContentDescription($$$);
+sub ProcessPreview($$$);
+sub ProcessCodecList($$$);
+
+# GUID definitions
+my %errorCorrection = (
+    '20FB5700-5B55-11CF-A8FD-00805F5C442B' => 'No Error Correction',
+    'BFC3CD50-618F-11CF-8BB2-00AA00B4E220' => 'Audio Spread',
+);
+
+my %streamType = (
+    'F8699E40-5B4D-11CF-A8FD-00805F5C442B' => 'Audio',
+    'BC19EFC0-5B4D-11CF-A8FD-00805F5C442B' => 'Video',
+    '59DACFC0-59E6-11D0-A3AC-00A0C90348F6' => 'Command',
+    'B61BE100-5B4E-11CF-A8FD-00805F5C442B' => 'JFIF',
+    '35907DE0-E415-11CF-A917-00805F5C442B' => 'Degradable JPEG',
+    '91BD222C-F21C-497A-8B6D-5AA86BFC0185' => 'File Transfer',
+    '3AFB65E2-47EF-40F2-AC2C-70A90D71D343' => 'Binary',
+);
+
+my %mutex = (
+    'D6E22A00-35DA-11D1-9034-00A0C90349BE' => 'MutexLanguage',
+    'D6E22A01-35DA-11D1-9034-00A0C90349BE' => 'MutexBitrate',
+    'D6E22A02-35DA-11D1-9034-00A0C90349BE' => 'MutexUnknown',
+);
+
+my %bandwidthSharing = (
+    'AF6060AA-5197-11D2-B6AF-00C04FD908E9' => 'SharingExclusive',
+    'AF6060AB-5197-11D2-B6AF-00C04FD908E9' => 'SharingPartial',
+);
+
+my %typeSpecific = (
+    '776257D4-C627-41CB-8F81-7AC7FF1C40CC' => 'WebStreamMediaSubtype',
+    'DA1E6B13-8359-4050-B398-388E965BF00C' => 'WebStreamFormat',
+);
+
+my %advancedContentEncryption = (
+    '7A079BB6-DAA4-4e12-A5CA-91D38DC11A8D' => 'DRMNetworkDevices',
+);
+
+# ASF top level objects
+%Image::ExifTool::ASF::Main = (
+    PROCESS_PROC => \&Image::ExifTool::ASF::ProcessASF,
+    NOTES => q{
+        ASF format is used by Windows WMA and WMV files.  Tag ID's aren't listed
+        because they are huge 128-bit GUID's that would ruin the formatting of this
+        table.
+    },
+    '75B22630-668E-11CF-A6D9-00AA0062CE6C' => {
+        Name => 'Header',
+        SubDirectory => { TagTable => 'Image::ExifTool::ASF::Header', Size => 6 },
+    },
+    '75B22636-668E-11CF-A6D9-00AA0062CE6C' => 'Data',
+    '33000890-E5B1-11CF-89F4-00A0C90349CB' => 'SimpleIndex',
+    'D6E229D3-35DA-11D1-9034-00A0C90349BE' => 'Index',
+    'FEB103F8-12AD-4C64-840F-2A1D2F7AD48C' => 'MediaIndex',
+    '3CB73FD0-0C4A-4803-953D-EDF7B6228F0C' => 'TimecodeIndex',
+);
+
+# ASF header objects
+%Image::ExifTool::ASF::Header = (
+    PROCESS_PROC => \&Image::ExifTool::ASF::ProcessASF,
+    '8CABDCA1-A947-11CF-8EE4-00C00C205365' => {
+        Name => 'FileProperties',
+        SubDirectory => { TagTable => 'Image::ExifTool::ASF::FileProperties' },
+    },
+    'B7DC0791-A9B7-11CF-8EE6-00C00C205365' => {
+        Name => 'StreamProperties',
+        SubDirectory => { TagTable => 'Image::ExifTool::ASF::StreamProperties' },
+    },
+    '5FBF03B5-A92E-11CF-8EE3-00C00C205365' => {
+        Name => 'HeaderExtension',
+        SubDirectory => { TagTable => 'Image::ExifTool::ASF::HeaderExtension', Size => 22 },
+    },
+    '86D15240-311D-11D0-A3A4-00A0C90348F6' => {
+        Name => 'CodecList',
+        SubDirectory => { TagTable => 'Image::ExifTool::ASF::CodecList' },
+    },
+    '1EFB1A30-0B62-11D0-A39B-00A0C90348F6' => 'ScriptCommand',
+    'F487CD01-A951-11CF-8EE6-00C00C205365' => 'Marker',
+    'D6E229DC-35DA-11D1-9034-00A0C90349BE' => 'BitrateMutualExclusion',
+    '75B22635-668E-11CF-A6D9-00AA0062CE6C' => 'ErrorCorrection',
+    '75B22633-668E-11CF-A6D9-00AA0062CE6C' => {
+        Name => 'ContentDescription',
+        SubDirectory => { TagTable => 'Image::ExifTool::ASF::ContentDescr' },
+    },
+    '2211B3FA-BD23-11D2-B4B7-00A0C955FC6E' => {
+        Name => 'ContentBranding',
+        SubDirectory => { TagTable => 'Image::ExifTool::ASF::ContentBranding' },
+    },
+    'D2D0A440-E307-11D2-97F0-00A0C95EA850' => {
+        Name => 'ExtendedContentDescr',
+        SubDirectory => { TagTable => 'Image::ExifTool::ASF::ExtendedDescr' },
+    },
+    '7BF875CE-468D-11D1-8D82-006097C9A2B2' => 'StreamBitrateProps',
+    '2211B3FB-BD23-11D2-B4B7-00A0C955FC6E' => 'ContentEncryption',
+    '298AE614-2622-4C17-B935-DAE07EE9289C' => 'ExtendedContentEncryption',
+    '2211B3FC-BD23-11D2-B4B7-00A0C955FC6E' => 'DigitalSignature',
+    '1806D474-CADF-4509-A4BA-9AABCB96AAE8' => 'Padding',
+);
+
+%Image::ExifTool::ASF::ContentDescr = (
+    PROCESS_PROC => \&ProcessContentDescription,
+    GROUPS => { 2 => 'Video' },
+    0 => 'Title',
+    1 => { Name => 'Author', Groups => { 2 => 'Author' } },
+    2 => { Name => 'Copyright', Groups => { 2 => 'Author' } },
+    3 => 'Description',
+    4 => 'Rating',
+);
+
+%Image::ExifTool::ASF::ContentBranding = (
+    PROCESS_PROC => \&ProcessContentBranding,
+    GROUPS => { 2 => 'Author' },
+    0 => {
+        Name => 'BannerImageType',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Bitmap',
+            2 => 'JPEG',
+            3 => 'GIF',
+        },
+    },
+    1 => { Name => 'BannerImage', Binary => 1 },
+    2 => 'BannerImageURL',
+    3 => 'CopyrightURL',
+);
+
+%Image::ExifTool::ASF::ExtendedDescr = (
+    PROCESS_PROC => \&ProcessExtendedContentDescription,
+    GROUPS => { 2 => 'Video' },
+    ASFLeakyBucketPairs => { Binary => 1 },
+    AspectRatioX => {},
+    AspectRatioY => {},
+    Author => { Groups => { 2 => 'Author' } },
+    AverageLevel => {},
+    BannerImageData => {},
+    BannerImageType => {},
+    BannerImageURL => {},
+    Bitrate => {},
+    Broadcast => {},
+    BufferAverage => {},
+    Can_Skip_Backward => {},
+    Can_Skip_Forward => {},
+    Copyright => { Groups => { 2 => 'Author' } },
+    CopyrightURL => { Groups => { 2 => 'Author' } },
+    CurrentBitrate => {},
+    Description => {},
+    DRM_ContentID => {},
+    DRM_DRMHeader_ContentDistributor => {},
+    DRM_DRMHeader_ContentID => {},
+    DRM_DRMHeader_IndividualizedVersion => {},
+    DRM_DRMHeader_KeyID => {},
+    DRM_DRMHeader_LicenseAcqURL => {},
+    DRM_DRMHeader_SubscriptionContentID => {},
+    DRM_DRMHeader => {},
+    DRM_IndividualizedVersion => {},
+    DRM_KeyID => {},
+    DRM_LASignatureCert => {},
+    DRM_LASignatureLicSrvCert => {},
+    DRM_LASignaturePrivKey => {},
+    DRM_LASignatureRootCert => {},
+    DRM_LicenseAcqURL => {},
+    DRM_V1LicenseAcqURL => {},
+    Duration => {},
+    FileSize => {},
+    HasArbitraryDataStream => {},
+    HasAttachedImages => {},
+    HasAudio => {},
+    HasFileTransferStream => {},
+    HasImage => {},
+    HasScript => {},
+    HasVideo => {},
+    Is_Protected => {},
+    Is_Trusted => {},
+    IsVBR => {},
+    NSC_Address => {},
+    NSC_Description => {},
+    NSC_Email => {},
+    NSC_Name => {},
+    NSC_Phone => {},
+    NumberOfFrames => {},
+    OptimalBitrate => {},
+    PeakValue => {},
+    Rating => {},
+    Seekable => {},
+    Signature_Name => {},
+    Stridable => {},
+    Title => {},
+    VBRPeak => {},
+    # "WM/" tags...
+    AlbumArtist => {},
+    AlbumCoverURL => {},
+    AlbumTitle => {},
+    ASFPacketCount => {},
+    ASFSecurityObjectsSize => {},
+    AudioFileURL => {},
+    AudioSourceURL => {},
+    AuthorURL => { Groups => { 2 => 'Author' } },
+    BeatsPerMinute => {},
+    Category => {},
+    Codec => {},
+    Composer => {},
+    Conductor => {},
+    ContainerFormat => {},
+    ContentDistributor => {},
+    ContentGroupDescription => {},
+    Director => {},
+    DRM => {},
+    DVDID => {},
+    EncodedBy => {},
+    EncodingSettings => {},
+    EncodingTime => { Groups => { 2 => 'Time' } },
+    Genre => {},
+    GenreID => {},
+    InitialKey => {},
+    ISRC => {},
+    Language => {},
+    Lyrics => {},
+    Lyrics_Synchronised => {},
+    MCDI => {},
+    MediaClassPrimaryID => {},
+    MediaClassSecondaryID => {},
+    MediaCredits => {},
+    MediaIsDelay => {},
+    MediaIsFinale => {},
+    MediaIsLive => {},
+    MediaIsPremiere => {},
+    MediaIsRepeat => {},
+    MediaIsSAP => {},
+    MediaIsStereo => {},
+    MediaIsSubtitled => {},
+    MediaIsTape => {},
+    MediaNetworkAffiliation => {},
+    MediaOriginalBroadcastDateTime => { Groups => { 2 => 'Time' } },
+    MediaOriginalChannel => {},
+    MediaStationCallSign => {},
+    MediaStationName => {},
+    ModifiedBy => {},
+    Mood => {},
+    OriginalAlbumTitle => {},
+    OriginalArtist => {},
+    OriginalFilename => {},
+    OriginalLyricist => {},
+    OriginalReleaseTime => { Groups => { 2 => 'Time' } },
+    OriginalReleaseYear => { Groups => { 2 => 'Time' } },
+    ParentalRating => {},
+    ParentalRatingReason => {},
+    PartOfSet => {},
+    PeakBitrate => {},
+    Period => {},
+    Picture => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ASF::Preview',
+        },
+    },
+    PlaylistDelay => {},
+    Producer => {},
+    PromotionURL => {},
+    ProtectionType => {},
+    Provider => {},
+    ProviderCopyright => {},
+    ProviderRating => {},
+    ProviderStyle => {},
+    Publisher => {},
+    RadioStationName => {},
+    RadioStationOwner => {},
+    SharedUserRating => {},
+    StreamTypeInfo => {},
+    SubscriptionContentID => {},
+    SubTitle => {},
+    SubTitleDescription => {},
+    Text => {},
+    ToolName => {},
+    ToolVersion => {},
+    Track => {},
+    TrackNumber => {},
+    UniqueFileIdentifier => {},
+    UserWebURL => {},
+    VideoClosedCaptioning => {},
+    VideoFrameRate => {},
+    VideoHeight => {},
+    VideoWidth => {},
+    WMADRCAverageReference => {},
+    WMADRCAverageTarget => {},
+    WMADRCPeakReference => {},
+    WMADRCPeakTarget => {},
+    WMCollectionGroupID => {},
+    WMCollectionID => {},
+    WMContentID => {},
+    Writer => { Groups => { 2 => 'Author' } },
+    Year => { Groups => { 2 => 'Time' } },
+);
+
+%Image::ExifTool::ASF::Preview = (
+    PROCESS_PROC => \&ProcessPreview,
+    GROUPS => { 2 => 'Video' },
+    0 => {
+        Name => 'PreviewType',
+        PrintConv => {
+            0 => 'Other picture type',
+            1 => '32x32 PNG file icon',
+            2 => 'Other file icon',
+            3 => 'Front album cover',
+            4 => 'Back album cover',
+            5 => 'Leaflet page',
+            6 => 'Media label',
+            7 => 'Lead artist, performer, or soloist',
+            8 => 'Artists or performers',
+            9 => 'Conductor',
+            10 => 'Band or orchestra',
+            11 => 'Composer',
+            12 => 'Lyricist or writer',
+            13 => 'Recording studio or location',
+            14 => 'Recording session',
+            15 => 'Performance',
+            16 => 'Capture from movie or video',
+            17 => 'A bright colored fish',
+            18 => 'Illustration',
+            19 => 'Band or artist logo',
+            20 => 'Publisher or studio logo',
+        },
+    },
+    1 => 'PreviewMimeType',
+    2 => 'PreviewDescription',
+    3 => {
+        Name => 'PreviewImage',
+        ValueConv => '$self->ValidateImage(\$val,$tag)',
+    },
+);
+
+%Image::ExifTool::ASF::FileProperties = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    0  => {
+        Name => 'FileID',
+        Format => 'binary[16]',
+        ValueConv => 'Image::ExifTool::ASF::GetGUID($val)',
+    },
+    16 => { Name => 'FileSize',     Format => 'int64u' },
+    24 => {
+        Name => 'CreationDate',
+        Format => 'int64u',
+        Groups => { 2 => 'Time' },
+        # time is in 100 ns intervals since 0:00 UTC Jan 1, 1601
+        ValueConv => q{ # (89 leap years between 1601 and 1970)
+            my $t = $val / 1e7 - (((1970-1601)*365+89)*24*3600);
+            return Image::ExifTool::ConvertUnixTime($t) . 'Z';
+        }
+    },
+    32 => { Name => 'DataPackets',  Format => 'int64u' },
+    40 => {
+        Name => 'PlayDuration',
+        Format => 'int64u',
+        ValueConv => '$val / 1e7',
+        PrintConv => '"$val sec"',
+    },
+    48 => {
+        Name => 'SendDuration',
+        Format => 'int64u',
+        ValueConv => '$val / 1e7',
+        PrintConv => '"$val sec"',
+    },
+    56 => { Name => 'Preroll',      Format => 'int64u' },
+    64 => { Name => 'Flags',        Format => 'int32u' },
+    68 => { Name => 'MinPacketSize',Format => 'int32u' },
+    72 => { Name => 'MaxPacketSize',Format => 'int32u' },
+    76 => { Name => 'MaxBitrate',   Format => 'int32u' },
+);
+
+%Image::ExifTool::ASF::StreamProperties = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    NOTES => 'Tags with index 54 and greater are conditional based on the StreamType.',
+    0  => {
+        Name => 'StreamType',
+        Format => 'binary[16]',
+        RawConv => sub { # set ASF_STREAM_TYPE for use in conditional tags
+            my ($val, $exifTool) = @_;
+            $exifTool->{ASF_STREAM_TYPE} = $streamType{GetGUID($val)} || '';
+            return $val;
+        },
+        ValueConv => 'Image::ExifTool::ASF::GetGUID($val)',
+        PrintConv => \%streamType,
+    },
+    16 => {
+        Name => 'ErrorCorrectionType',
+        Format => 'binary[16]',
+        ValueConv => 'Image::ExifTool::ASF::GetGUID($val)',
+        PrintConv => \%errorCorrection,
+    },
+    32 => {
+        Name => 'TimeOffset',
+        Format => 'int64u',
+        ValueConv => '$val / 1e7',
+        PrintConv => '"$val sec"',
+    },
+    48 => {
+        Name => 'StreamNumber',
+        Format => 'int16u',
+        PrintConv => '($val & 0x7f) . ($val & 0x8000 ? " (encrypted)" : "")',
+    },
+    54 => [
+        {
+            Condition => '$self->{ASF_STREAM_TYPE} eq "Audio"',
+            Name => 'AudioCodecID',
+            Format => 'int16u',
+            PrintHex => 1,
+            # from http://www.iana.org/assignments/wave-avi-codec-registry
+            # and http://developers.videolan.org/vlc/vlc/doc/doxygen/html/codecs_8h-source.html
+            PrintConv => {
+                0x0001 => 'Microsoft PCM',
+                0x0002 => 'Microsoft ADPCM',
+                0x0003 => 'IEEE Float',
+                0x0004 => 'Cmpaq VSELP',
+                0x0005 => 'IBM CVSD',
+                0x0006 => 'Microsoft A-Law',
+                0x0007 => 'Microsoft Mu-Law',
+                0x0008 => 'DTS Coherent Acoustics 1',
+                0x0010 => 'OKI ADPCM',
+                0x0011 => 'Intel DVI ADPCM',
+                0x0012 => 'Videologic MediaSpace ADPCM',
+                0x0013 => 'Sierra ADPCM',
+                0x0014 => 'G.723 ADPCM',
+                0x0015 => 'DSP Solution DIGISTD',
+                0x0016 => 'DSP Solution DIGIFIX',
+                0x0017 => 'Dialogic OKI ADPCM',
+                0x0018 => 'MediaVision ADPCM',
+                0x0019 => 'HP CU',
+                0x0020 => 'Yamaha ADPCM',
+                0x0021 => 'Speech Compression Sonarc',
+                0x0022 => 'DSP Group True Speech',
+                0x0023 => 'Echo Speech EchoSC1',
+                0x0024 => 'Audiofile AF36',
+                0x0025 => 'APTX',
+                0x0026 => 'AudioFile AF10',
+                0x0027 => 'Prosody 1612',
+                0x0028 => 'LRC',
+                0x0030 => 'Dolby AC2',
+                0x0031 => 'GSM610',
+                0x0032 => 'MSNAudio',
+                0x0033 => 'Antex ADPCME',
+                0x0034 => 'Control Res VQLPC',
+                0x0035 => 'Digireal',
+                0x0036 => 'DigiADPCM',
+                0x0037 => 'Control Res CR10',
+                0x0038 => 'NMS VBXADPCM',
+                0x0039 => 'Roland RDAC',
+                0x003a => 'EchoSC3',
+                0x003b => 'Rockwell ADPCM',
+                0x003c => 'Rockwell Digit LK',
+                0x003d => 'Xebec',
+                0x0040 => 'Antex Electronics G.721',
+                0x0041 => 'G.728 CELP',
+                0x0042 => 'MSG723',
+                0x0045 => 'G.726 ADPCM',
+                0x0050 => 'MPEG',
+                0x0052 => 'RT24',
+                0x0053 => 'PAC',
+                0x0055 => 'MPEG Layer 3',
+                0x0059 => 'Lucent G.723',
+                0x0060 => 'Cirrus',
+                0x0061 => 'ESPCM',
+                0x0062 => 'Voxware',
+                0x0063 => 'Canopus Atrac',
+                0x0064 => 'G.726 ADPCM',
+                0x0066 => 'DSAT',
+                0x0067 => 'DSAT Display',
+                0x0069 => 'Voxware Byte Aligned',
+                0x0070 => 'Voxware AC8',
+                0x0071 => 'Voxware AC10',
+                0x0072 => 'Voxware AC16',
+                0x0073 => 'Voxware AC20',
+                0x0074 => 'Voxware MetaVoice',
+                0x0075 => 'Voxware MetaSound',
+                0x0076 => 'Voxware RT29HW',
+                0x0077 => 'Voxware VR12',
+                0x0078 => 'Voxware VR18',
+                0x0079 => 'Voxware TQ40',
+                0x0080 => 'Softsound',
+                0x0081 => 'Voxware TQ60',
+                0x0082 => 'MSRT24',
+                0x0083 => 'G.729A',
+                0x0084 => 'MVI MV12',
+                0x0085 => 'DF G.726',
+                0x0086 => 'DF GSM610',
+                0x0088 => 'ISIAudio',
+                0x0089 => 'Onlive',
+                0x0091 => 'SBC24',
+                0x0092 => 'Dolby AC3 SPDIF',
+                0x0097 => 'ZyXEL ADPCM',
+                0x0098 => 'Philips LPCBB',
+                0x0099 => 'Packed',
+                0x00FF => 'MPEG-4',
+                0x0100 => 'Rhetorex ADPCM',
+                0x0101 => 'BeCubed Software IRAT',
+                0x0111 => 'Vivo G.723',
+                0x0112 => 'Vivo Siren',
+                0x0123 => 'Digital G.723',
+                0x0160 => 'Windows Media v1',
+                0x0161 => 'Windows Media v2',
+                0x0162 => 'Windows Media 9 Professional',
+                0x0163 => 'Windows Media 9 Lossless',
+                0x0200 => 'Creative ADPCM',
+                0x0202 => 'Creative FastSpeech8',
+                0x0203 => 'Creative FastSpeech10',
+                0x0220 => 'Quarterdeck',
+                0x0300 => 'FM Towns Snd',
+                0x0400 => 'BTV Digital',
+                0x0680 => 'VME VMPCM',
+                0x1000 => 'OLIGSM',
+                0x1001 => 'OLIADPCM',
+                0x1002 => 'OLICELP',
+                0x1003 => 'OLISBC',
+                0x1004 => 'OLIOPR',
+                0x1100 => 'LH Codec',
+                0x1400 => 'Norris',
+                0x1401 => 'ISIAudio',
+                0x1500 => 'Soundspace Music Compression',
+                0x2000 => 'DVM',
+                0x2001 => 'DTS Coherent Acoustics 2',
+                0x4143 => 'MPEG-4 (Divio)',
+            },
+        },
+        {
+            Condition => '$self->{ASF_STREAM_TYPE} =~ /^(Video|JFIF|Degradable JPEG)$/',
+            Name => 'ImageWidth',
+            Format => 'int32u',
+        },
+    ],
+    56 => {
+        Condition => '$self->{ASF_STREAM_TYPE} eq "Audio"',
+        Name => 'AudioChannels',
+        Format => 'int16u',
+    },
+    58 => [
+        {
+            Condition => '$self->{ASF_STREAM_TYPE} eq "Audio"',
+            Name => 'AudioSampleRate',
+            Format => 'int32u',
+        },
+        {
+            Condition => '$self->{ASF_STREAM_TYPE} =~ /^(Video|JFIF|Degradable JPEG)$/',
+            Name => 'ImageHeight',
+            Format => 'int32u',
+        },
+    ],
+);
+
+%Image::ExifTool::ASF::HeaderExtension = (
+    PROCESS_PROC => \&Image::ExifTool::ASF::ProcessASF,
+    '14E6A5CB-C672-4332-8399-A96952065B5A' => 'ExtendedStreamProps',
+    'A08649CF-4775-4670-8A16-6E35357566CD' => 'AdvancedMutualExcl',
+    'D1465A40-5A79-4338-B71B-E36B8FD6C249' => 'GroupMutualExclusion',
+    'D4FED15B-88D3-454F-81F0-ED5C45999E24' => 'StreamPrioritization',
+    'A69609E6-517B-11D2-B6AF-00C04FD908E9' => 'BandwidthSharing',
+    '7C4346A9-EFE0-4BFC-B229-393EDE415C85' => 'LanguageList',
+    'C5F8CBEA-5BAF-4877-8467-AA8C44FA4CCA' => {
+        Name => 'Metadata',
+        SubDirectory => { TagTable => 'Image::ExifTool::ASF::Metadata' },
+    },
+    '44231C94-9498-49D1-A141-1D134E457054' => {
+        Name => 'MetadataLibrary',
+        SubDirectory => { TagTable => 'Image::ExifTool::ASF::Metadata' },
+    },
+    'D6E229DF-35DA-11D1-9034-00A0C90349BE' => 'IndexParameters',
+    '6B203BAD-3F11-48E4-ACA8-D7613DE2CFA7' => 'TimecodeIndexParms',
+    '75B22630-668E-11CF-A6D9-00AA0062CE6C' => 'Compatibility',
+    '43058533-6981-49E6-9B74-AD12CB86D58C' => 'AdvancedContentEncryption',
+    'ABD3D211-A9BA-11cf-8EE6-00C00C205365' => 'Reserved1',
+);
+
+%Image::ExifTool::ASF::Metadata = (
+    PROCESS_PROC => \&Image::ExifTool::ASF::ProcessMetadata,
+);
+
+%Image::ExifTool::ASF::CodecList = (
+    PROCESS_PROC => \&ProcessCodecList,
+    VideoCodecName => {},
+    VideoCodecDescription => {},
+    AudioCodecName => {},
+    AudioCodecDescription => {},
+    OtherCodecName => {},
+    OtherCodecDescription => {},
+);
+
+#------------------------------------------------------------------------------
+# Generate GUID from 16 bytes of binary data
+# Inputs: 0) data
+# Returns: GUID
+sub GetGUID($)
+{
+    # must do some byte swapping
+    my $buff = unpack('H*',pack('NnnNN',unpack('VvvNN',$_[0])));
+    $buff =~ s/(.{8})(.{4})(.{4})(.{4})/$1-$2-$3-$4-/;
+    return uc($buff);
+}
+
+#------------------------------------------------------------------------------
+# Process ASF content description
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table reference
+# Returns: 1 on success
+sub ProcessContentDescription($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $verbose = $exifTool->Options('Verbose');
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirLen = $$dirInfo{DirLen};
+    return 0 if $dirLen < 10;
+    my @len = unpack('v5', $$dataPt);
+    my $pos = 10;
+    my $tag;
+    foreach $tag (0..4) {
+        my $len = shift @len;
+        next unless $len;
+        return 0 if $pos + $len > $dirLen;
+        my $val = $exifTool->Unicode2Charset(substr($$dataPt,$pos,$len),'II');
+        $exifTool->HandleTag($tagTablePtr, $tag, $val);
+        $pos += $len;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process ASF content branding
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table reference
+# Returns: 1 on success
+sub ProcessContentBranding($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $verbose = $exifTool->Options('Verbose');
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirLen = $$dirInfo{DirLen};
+    return 0 if $dirLen < 40;
+    # decode banner image type
+    $exifTool->HandleTag($tagTablePtr, 0, unpack('V', $$dataPt));
+    # decode banner image, banner URL and copyright URL
+    my $pos = 4;
+    my $tag;
+    foreach $tag (1..3) {
+        return 0 if $pos + 4 > $dirLen;
+        my $size = unpack("x${pos}V", $$dataPt);
+        $pos += 4;
+        next unless $size;
+        return 0 if $pos + $size > $dirLen;
+        my $val = substr($$dataPt, $pos, $size);
+        $exifTool->HandleTag($tagTablePtr, $tag, $val);
+        $pos += $size;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Read ASF value
+# Inputs: 0) ExifTool object ref, 1) data reference, 2) value offset,
+#         3) format number, 4) size
+# Returns: converted value
+sub ReadASF($$$$$)
+{
+    my ($exifTool, $dataPt, $pos, $format, $size) = @_;
+    my @vals;
+    if ($format == 0) { # unicode string
+        $vals[0] = $exifTool->Unicode2Charset(substr($$dataPt,$pos,$size),'II');
+    } elsif ($format == 2) { # 4-byte boolean
+        @vals = ReadValue($dataPt, $pos, 'int32u', undef, $size);
+        foreach (@vals) {
+            $_ = $_ ? 'True' : 'False';
+        }
+    } elsif ($format == 3) { # int32u
+        @vals = ReadValue($dataPt, $pos, 'int32u', undef, $size);
+    } elsif ($format == 4) { # int64u
+        @vals = ReadValue($dataPt, $pos, 'int64u', undef, $size);
+    } elsif ($format == 5) { # int16u
+        @vals = ReadValue($dataPt, $pos, 'int16u', undef, $size);
+    } else { # any other format (including 1, byte array): return raw data
+        $vals[0] = substr($$dataPt,$pos,$size);
+    }
+    return join ' ', @vals;
+}
+
+#------------------------------------------------------------------------------
+# Process extended content description
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table reference
+# Returns: 1 on success
+sub ProcessExtendedContentDescription($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $verbose = $exifTool->Options('Verbose');
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirLen = $$dirInfo{DirLen};
+    return 0 if $dirLen < 2;
+    my $count = Get16u($dataPt, 0);
+    $exifTool->VerboseDir($dirInfo, $count);
+    my $pos = 2;
+    my $i;
+    for ($i=0; $i<$count; ++$i) {
+        return 0 if $pos + 6 > $dirLen;
+        my $nameLen = unpack("x${pos}v", $$dataPt);
+        $pos += 2;
+        return 0 if $pos + $nameLen + 4 > $dirLen;
+        my $tag = Image::ExifTool::Unicode2Latin(substr($$dataPt,$pos,$nameLen),'v');
+        $tag =~ s/^WM\///; # remove leading "WM/"
+        $pos += $nameLen;
+        my ($dType, $dLen) = unpack("x${pos}v2", $$dataPt);
+        my $val = ReadASF($exifTool,$dataPt,$pos+4,$dType,$dLen);
+        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            DataPt => $dataPt,
+            Start  => $pos + 4,
+            Size   => $dLen,
+        );
+        $pos += 4 + $dLen;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process WM/Picture preview
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table reference
+# Returns: 1 on success
+sub ProcessPreview($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $verbose = $exifTool->Options('Verbose');
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart};
+    my $dirLen = $$dirInfo{DirLen};
+    return 0 unless $dirLen > 9;
+    # extract picture type and length
+    my ($type, $picLen) = unpack("x${dirStart}CV", $$dataPt);
+    $exifTool->HandleTag($tagTablePtr, 0, $type);
+    # extract mime type and description strings (null-terminated unicode strings)
+    my $n = $dirLen - 5 - $picLen;
+    return 0 if $n & 0x01 or $n < 4;
+    my $str = substr($$dataPt, $dirStart+5, $n);
+    if ($str =~ /^((?:..)*?)\0\0((?:..)*?)\0\0/) {
+        my ($mime, $desc) = ($1, $2);
+        $exifTool->HandleTag($tagTablePtr, 1, $mime);
+        $exifTool->HandleTag($tagTablePtr, 2, $desc) if length $desc;
+    }
+    $exifTool->HandleTag($tagTablePtr, 3, substr($$dataPt, $dirStart+5+$n, $picLen));
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process codec list
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table reference
+# Returns: 1 on success
+sub ProcessCodecList($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $verbose = $exifTool->Options('Verbose');
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirLen = $$dirInfo{DirLen};
+    return 0 if $dirLen < 20;
+    my $count = Get32u($dataPt, 16);
+    $exifTool->VerboseDir($dirInfo, $count);
+    my $pos = 20;
+    my $i;
+    my %codecType = ( 1 => 'Video', 2 => 'Audio' );
+    for ($i=0; $i<$count; ++$i) {
+        return 0 if $pos + 8 > $dirLen;
+        my $type = ($codecType{Get16u($dataPt, $pos)} || 'Other') . 'Codec';
+        # stupid Windows programmers: these lengths are in characters (others are in bytes)
+        my $nameLen = Get16u($dataPt, $pos + 2) * 2;
+        $pos += 4;
+        return 0 if $pos + $nameLen + 2 > $dirLen;
+        my $name = $exifTool->Unicode2Charset(substr($$dataPt,$pos,$nameLen),'II');
+        $exifTool->HandleTag($tagTablePtr, "${type}Name", $name);
+        my $descLen = Get16u($dataPt, $pos + $nameLen) * 2;
+        $pos += $nameLen + 2;
+        return 0 if $pos + $descLen + 2 > $dirLen;
+        my $desc = $exifTool->Unicode2Charset(substr($$dataPt,$pos,$descLen),'II');
+        $exifTool->HandleTag($tagTablePtr, "${type}Description", $desc);
+        my $infoLen = Get16u($dataPt, $pos + $descLen);
+        $pos += $descLen + 2 + $infoLen;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process ASF metadata library
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table reference
+# Returns: 1 on success
+sub ProcessMetadata($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $verbose = $exifTool->Options('Verbose');
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirLen = $$dirInfo{DirLen};
+    return 0 if $dirLen < 2;
+    my $count = Get16u($dataPt, 0);
+    $exifTool->VerboseDir($dirInfo, $count);
+    my $pos = 2;
+    my $i;
+    for ($i=0; $i<$count; ++$i) {
+        return 0 if $pos + 12 > $dirLen;
+        my ($index, $stream, $nameLen, $dType, $dLen) = unpack("x${pos}v4V", $$dataPt);
+        $pos += 12;
+        return 0 if $pos + $nameLen + $dLen > $dirLen;
+        my $tag = Image::ExifTool::Unicode2Latin(substr($$dataPt,$pos,$nameLen),'v');
+        my $val = ReadASF($exifTool,$dataPt,$pos+$nameLen,$dType,$dLen);
+        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            DataPt => $dataPt,
+            Start  => $pos,
+            Size   => $dLen,
+        );
+        $pos += $nameLen + $dLen;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Extract information from a ASF file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) tag table ref
+# Returns: 1 on success, 0 if this wasn't a valid ASF file
+sub ProcessASF($$;$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->Options('Verbose');
+    my $rtnVal = 0;
+    my $pos = 0;
+    my ($buff, $err, @parentTable, @childEnd, %dumpParms);
+
+    if ($verbose > 2) {
+        $dumpParms{MaxLen} = 96 unless $verbose > 3;
+        $dumpParms{Prefix} = $$exifTool{INDENT};
+        $dumpParms{Out} = $exifTool->Options('TextOut');
+    }
+    for (;;) {
+        last unless $raf->Read($buff, 24) == 24;
+        $pos += 24;
+        my $tag = GetGUID($buff);
+        unless ($tagTablePtr) {
+            # verify this is a valid ASF file
+            last unless $tag eq '75B22630-668E-11CF-A6D9-00AA0062CE6C';
+            my $fileType = $exifTool->{FILE_EXT};
+            $fileType = 'ASF' unless $fileType and $fileType =~ /^(ASF|WMV|WMA)$/;
+            $exifTool->SetFileType($fileType);
+            SetByteOrder('II');
+            $tagTablePtr = GetTagTable('Image::ExifTool::ASF::Main');
+            $rtnVal = 1;
+        }
+        my $size = Image::ExifTool::Get64u(\$buff, 16) - 24;
+        if ($size < 0) {
+            $err = 'Invalid ASF object size';
+            last;
+        }
+        if ($size > 0x7fffffff) {
+            $err = 'Large ASF objects not supported';
+            last;
+        }
+        # go back to parent tag table if done with previous children
+        if (@childEnd and $pos >= $childEnd[-1]) {
+            pop @childEnd;
+            $tagTablePtr = pop @parentTable;
+            $exifTool->{INDENT} = substr($exifTool->{INDENT},0,-2);
+            $dumpParms{Prefix} = $exifTool->{INDENT};
+        }
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        $verbose and $exifTool->VerboseInfo($tag, $tagInfo);
+        if ($tagInfo) {
+            my $subdir = $$tagInfo{SubDirectory};
+            if ($subdir) {
+                my $subTable = GetTagTable($$subdir{TagTable});
+                if ($$subTable{PROCESS_PROC} eq \&ProcessASF) {
+                    if (defined $$subdir{Size}) {
+                        my $s = $$subdir{Size};
+                        if ($verbose > 2) {
+                            $raf->Read($buff, $s) == $s or $err = 'Truncated file', last;
+                            Image::ExifTool::HexDump(\$buff, undef, %dumpParms);
+                        } elsif (not $raf->Seek($s, 1)) {
+                            $err = 'Seek error';
+                            last;
+                        }
+                        # continue processing linearly using subTable
+                        push @parentTable, $tagTablePtr;
+                        push @childEnd, $pos + $size;
+                        $tagTablePtr = $subTable;
+                        $pos += $$subdir{Size};
+                        if ($verbose) {
+                            $exifTool->{INDENT} .= '| ';
+                            $dumpParms{Prefix} = $exifTool->{INDENT};
+                            $exifTool->VerboseDir($$tagInfo{Name});
+                        }
+                        next;
+                    }
+                } elsif ($raf->Read($buff, $size) == $size) {
+                    my %subdirInfo = (
+                        DataPt => \$buff,
+                        DirStart => 0,
+                        DirLen => $size,
+                        DirName => $$tagInfo{Name},
+                    );
+                    if ($verbose > 2) {
+                        Image::ExifTool::HexDump(\$buff, undef, %dumpParms);
+                    }
+                    unless ($exifTool->ProcessDirectory(\%subdirInfo, $subTable)) {
+                        $exifTool->Warn("Error processing $$tagInfo{Name} directory");
+                    }
+                    $pos += $size;
+                    next;
+                } else {
+                    $err = 'Unexpected end of file';
+                    last;
+                }
+            }
+        }
+        if ($verbose > 2) {
+            $raf->Read($buff, $size) == $size or $err = 'Truncated file', last;
+            Image::ExifTool::HexDump(\$buff, undef, %dumpParms);
+        } elsif (not $raf->Seek($size, 1)) { # skip the block
+            $err = 'Seek error';
+            last;
+        }
+        $pos += $size;
+    }
+    $err and $exifTool->Warn($err);
+    return $rtnVal;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::ASF - Read ASF/WMA/WMV meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to extract
+information from Microsoft Advanced Systems Format (ASF) files, including
+Windows Media Audio (WMA) and Windows Media Video (WMV) files.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.microsoft.com/windows/windowsmedia/format/asfspec.aspx>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/ASF Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/BMP.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/BMP.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/BMP.pm	(revision 20131)
@@ -0,0 +1,147 @@
+#------------------------------------------------------------------------------
+# File:         BMP.pm
+#
+# Description:  Read BMP meta information
+#
+# Revisions:    07/16/2005 - P. Harvey Created
+#
+# References:   1) http://www.fortunecity.com/skyscraper/windows/364/bmpffrmt.html
+#               2) http://www.fourcc.org/rgb.php
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::BMP;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.02';
+
+# BMP chunks
+%Image::ExifTool::BMP::Main = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    NOTES => q{
+        There really isn't much meta information in a BMP file as such, just a bit
+        of image related information.
+    },
+    4 => {
+        Name => 'ImageWidth',
+        Format => 'int32u',
+    },
+    8 => {
+        Name => 'ImageHeight',
+        Format => 'int32u',
+    },
+    12 => {
+        Name => 'Planes',
+        Format => 'int16u',
+    },
+    14 => {
+        Name => 'BitDepth',
+        Format => 'int16u',
+    },
+    16 => {
+        Name => 'Compression',
+        Format => 'int32u',
+        # (formatted as string[4] for some values in AVI images)
+        ValueConv => '$val > 256 ? unpack("A4",pack("V",$val)) : $val',
+        PrintConv => {
+            0 => 'None',
+            1 => '8-Bit RLE',
+            2 => '4-Bit RLE',
+            3 => 'Bitfields',
+            4 => 'JPEG', #2
+            5 => 'PNG', #2
+        },
+    },
+    20 => {
+        Name => 'ImageLength',
+        Format => 'int32u',
+    },
+    24 => {
+        Name => 'PixelsPerMeterX',
+        Format => 'int32u',
+    },
+    28 => {
+        Name => 'PixelsPerMeterY',
+        Format => 'int32u',
+    },
+    32 => {
+        Name => 'NumColors',
+        Format => 'int32u',
+        PrintConv => '$val ? $val : "Use BitDepth"',
+    },
+    36 => {
+        Name => 'NumImportantColors',
+        Format => 'int32u',
+        PrintConv => '$val ? $val : "All"',
+    },
+);
+
+#------------------------------------------------------------------------------
+# Extract EXIF information from a BMP image
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid BMP file
+sub ProcessBMP($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+
+    # verify this is a valid BMP file
+    return 0 unless $raf->Read($buff, 14) == 14;
+    return 0 unless $buff =~ /^BM/;
+    return 0 unless $raf->Read($buff, 40) == 40;
+    SetByteOrder('II');
+    return 0 unless Get32u(\$buff, 0) >= 40;    # make sure info is at least 40 bytes
+    $exifTool->SetFileType();   # set the FileType tag
+    my %dirInfo = (
+        DataPt => \$buff,
+        DirStart => 0,
+        DirLen => length($buff),
+    );
+    my $tagTablePtr = GetTagTable('Image::ExifTool::BMP::Main');
+    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::BMP - Read BMP meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read BMP
+(Windows Bitmap) images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.fortunecity.com/skyscraper/windows/364/bmpffrmt.html>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/BMP Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/BigTIFF.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/BigTIFF.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/BigTIFF.pm	(revision 20131)
@@ -0,0 +1,277 @@
+#------------------------------------------------------------------------------
+# File:         BigTIFF.pm
+#
+# Description:  Read Big TIFF meta information
+#
+# Revisions:    07/03/2007 - P. Harvey Created
+#
+# References:   1) http://www.awaresystems.be/imaging/tiff/bigtiff.html
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::BigTIFF;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.00';
+
+my $maxOffset = 0x7fffffff; # currently supported maximum data offset/size
+
+#------------------------------------------------------------------------------
+# Process Big IFD directory
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+sub ProcessBigIFD($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->{OPTIONS}->{Verbose};
+    my $htmlDump = $exifTool->{HTML_DUMP};
+    my $dirName = $$dirInfo{DirName};
+    my $dirStart = $$dirInfo{DirStart};
+
+    $verbose = -1 if $htmlDump; # mix htmlDump into verbose so we can test for both at once
+
+    # loop through IFD chain
+    for (;;) {
+        if ($dirStart > $maxOffset) {
+            $exifTool->Warn('Huge offsets not yet supported');
+            last;
+        }
+        unless ($raf->Seek($dirStart, 0)) {
+            $exifTool->Warn("Bad $dirName offset");
+            return 0;
+        }
+        my ($dirBuff, $index);
+        unless ($raf->Read($dirBuff, 8) == 8) {
+            $exifTool->Warn("Truncated $dirName count");
+            return 0;
+        }
+        my $numEntries = Image::ExifTool::Get64u(\$dirBuff, 0);
+        $verbose > 0 and $exifTool->VerboseDir($dirName, $numEntries);
+        my $bsize = $numEntries * 20;
+        if ($bsize > $maxOffset) {
+            $exifTool->Warn('Huge directory counts not yet supported');
+            last;
+        }
+        my $bufPos = $raf->Tell();
+        unless ($raf->Read($dirBuff, $bsize) == $bsize) {
+            $exifTool->Warn("Truncated $dirName directory");
+            return 0;
+        }
+        my $nextIFD;
+        $raf->Read($nextIFD, 8) == 8 or undef $nextIFD; # try to read next IFD pointer
+        if ($htmlDump) {
+            $exifTool->HtmlDump($bufPos-8, 8, "$dirName entries", "Entry count: $numEntries");
+            if (defined $nextIFD) {
+                my $tip = sprintf("Offset: 0x%.8x", Image::ExifTool::Get64u(\$nextIFD, 0));
+                $exifTool->HtmlDump($bufPos + 20 * $numEntries, 8, "Next IFD", $tip, 0);
+            }
+        }
+        # loop through all entries in this BigTIFF IFD
+        for ($index=0; $index<$numEntries; ++$index) {
+            my $entry = 20 * $index;
+            my $tagID = Get16u(\$dirBuff, $entry);
+            my $format = Get16u(\$dirBuff, $entry+2);
+            my $count = Image::ExifTool::Get64u(\$dirBuff, $entry+4);
+            my $formatSize = $Image::ExifTool::Exif::formatSize[$format];
+            unless (defined $formatSize) {
+                $exifTool->HtmlDump($bufPos+$entry,20,"[invalid IFD entry]",
+                         "Bad format value: $format", 1);
+                # warn unless the IFD was just padded with zeros
+                $exifTool->Warn(sprintf("Unknown format ($format) for $dirName tag 0x%x",$tagID));
+                return 0; # assume corrupted IFD
+            }
+            my $formatStr = $Image::ExifTool::Exif::formatName[$format];
+            my $size = $count * $formatSize;
+            my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+            next unless $tagInfo or $verbose;
+            my $valuePtr = $entry + 12;
+            my ($valBuff, $valBase);
+            if ($size > 8) {
+                if ($size > $maxOffset) {
+                    $exifTool->Warn("Can't yet handle $dirName entry $index (huge size)");
+                    next;
+                }
+                $valuePtr = Image::ExifTool::Get64u(\$dirBuff, $valuePtr);
+                if ($valuePtr > $maxOffset) {
+                    $exifTool->Warn("Can't yet handle $dirName entry $index (huge offset)");
+                    next;
+                }
+                unless ($raf->Seek($valuePtr, 0) and $raf->Read($valBuff, $size) == $size) {
+                    $exifTool->Warn("Error reading $dirName entry $index");
+                    next;
+                }
+                $valBase = 0;
+            } else {
+                $valBuff = substr($dirBuff, $valuePtr, $size);
+                $valBase = $bufPos;
+            }
+            my $val = ReadValue(\$valBuff, 0, $formatStr, $count, $size);
+            if ($htmlDump) {
+                my ($tagName, $colName);
+                if ($tagID == 0x927c and $dirName eq 'ExifIFD') {
+                    $tagName = 'MakerNotes';
+                } elsif ($tagInfo) {
+                    $tagName = $$tagInfo{Name};
+                } else {
+                    $tagName = sprintf("Tag 0x%.4x",$tagID);
+                }
+                my $dname = sprintf("$dirName-%.2d", $index);
+                # build our tool tip
+                my $tip = sprintf("Tag ID: 0x%.4x\\n", $tagID) .
+                          "Format: $formatStr\[$count]\\nSize: $size bytes\\n";
+                if ($size > 8) {
+                    $tip .= sprintf("Value offset: 0x%.8x\\n", $valuePtr);
+                    $colName = "<span class=H>$tagName</span>";
+                } else {
+                    $colName = $tagName;
+                }
+                my $tval = (length $val < 32) ? $val : substr($val,0,28) . '[...]';
+                if ($formatStr =~ /^(string|undef|binary)/) {
+                    # translate all characters that could mess up JavaScript
+                    $tval =~ tr/\\\x00-\x1f\x7f-\xff/./;
+                    $tval =~ tr/"/'/;
+                    $tval = "$tval";
+                } elsif ($tagInfo and Image::ExifTool::IsInt($tval)) {
+                    if ($$tagInfo{IsOffset}) {
+                        $tval = sprintf('0x%.4x', $tval);
+                    } elsif ($$tagInfo{PrintHex}) {
+                        $tval = sprintf('0x%x', $tval);
+                    }
+                }
+                $tip .= "Value: $tval";
+                $exifTool->HtmlDump($entry+$bufPos, 20, "$dname $colName", $tip, 1);
+                if ($size > 8) {
+                    # add value data block
+                    my $flg = ($tagInfo and $$tagInfo{SubDirectory} and $$tagInfo{MakerNotes}) ? 4 : 0;
+                    $exifTool->HtmlDump($valuePtr,$size,"$tagName value",'SAME', $flg);
+                }
+            }
+            if ($tagInfo and $$tagInfo{SubIFD}) {
+                # process all SubIFD's as BigTIFF
+                $verbose > 0 and $exifTool->VerboseInfo($tagID, $tagInfo,
+                    Table   => $tagTablePtr,
+                    Index   => $index,
+                    Value   => $val,
+                    DataPt  => \$valBuff,
+                    DataPos => $valBase + $valuePtr,
+                    Start   => 0,
+                    Size    => $size,
+                    Format  => $formatStr,
+                    Count   => $count,
+                );
+                my @offsets = split ' ', $val;
+                my $i;
+                for ($i=0; $i<scalar(@offsets); ++$i) {
+                    my $subdirName = $$tagInfo{Name};
+                    $subdirName .= $i if $i;
+                    my %subdirInfo = (
+                        RAF      => $raf,
+                        DataPos  => 0,
+                        DirStart => $offsets[$i],
+                        DirName  => $subdirName,
+                        Parent   => $dirInfo,
+                    );
+                    $exifTool->ProcessDirectory(\%subdirInfo, $tagTablePtr, \&ProcessBigIFD);
+                }
+            } else {
+                my $tagKey = $exifTool->HandleTag($tagTablePtr, $tagID, $val,
+                    Index   => $index,
+                    DataPt  => \$valBuff,
+                    DataPos => $valBase + $valuePtr,
+                    Start   => 0,
+                    Size    => $size,
+                    Format  => $formatStr,
+                    TagInfo => $tagInfo,
+                    RAF     => $raf,
+                );
+                $tagKey and $exifTool->SetGroup1($tagKey, $dirName);
+            }
+        }
+        last unless $dirName =~ /^(IFD|SubIFD)(\d*)$/;
+        $dirName = $1 . (($2 || 0) + 1);
+        defined $nextIFD or $exifTool->Warn("Bad $dirName pointer"), return 0;
+        $dirStart = Image::ExifTool::Get64u(\$nextIFD, 0);
+        $dirStart or last;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Extract meta information from a BigTIFF image
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid BigTIFF image
+sub ProcessBTF($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+
+    return 0 unless $raf->Read($buff, 16) == 16;
+    return 0 unless $buff =~ /^(MM\0\x2b\0\x08\0\0|II\x2b\0\x08\0\0\0)/;
+    if ($$dirInfo{OutFile}) {
+        $exifTool->Error('ExifTool does not support writing of BigTIFF images');
+        return 1;
+    }
+    $exifTool->SetFileType('BTF'); # set the FileType tag
+    SetByteOrder(substr($buff, 0, 2));
+    my $offset = Image::ExifTool::Get64u(\$buff, 8);
+    if ($exifTool->{HTML_DUMP}) {
+        my $o = (GetByteOrder() eq 'II') ? 'Little' : 'Big';
+        $exifTool->HtmlDump(0, 8, "BigTIFF header", "Byte order: $o endian", 0);
+        $exifTool->HtmlDump(8, 8, "IFD0 pointer", sprintf("Offset: 0x%.8x",$offset), 0);
+    }
+    my %dirInfo = (
+        RAF      => $raf,
+        DataPos  => 0,
+        DirStart => $offset,
+        DirName  => 'IFD0',
+        Parent   => 'BigTIFF',
+    );
+    my $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main');
+    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr, \&ProcessBigIFD);
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::BigTIFF - Read Big TIFF meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to read meta
+information in BigTIFF images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.awaresystems.be/imaging/tiff/bigtiff.html>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/EXIF Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/BuildTagLookup.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/BuildTagLookup.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/BuildTagLookup.pm	(revision 20131)
@@ -0,0 +1,1541 @@
+#------------------------------------------------------------------------------
+# File:         BuildTagLookup.pm
+#
+# Description:  Utility to build tag lookup tables in Image::ExifTool::TagLookup.pm
+#
+# Revisions:    12/31/2004 - P. Harvey Created
+#               02/15/2005 - PH Added ability to generate TagNames documentation
+#
+# Notes:        Documentation for the tag tables may either be placed in the
+#               %docs hash below or in a NOTES entry in the table itself, and
+#               individual tags may have their own Notes entry.
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::BuildTagLookup;
+
+use strict;
+require Exporter;
+
+BEGIN {
+    # prevent ExifTool from loading the user config file
+    $Image::ExifTool::noConfig = 1;
+}
+
+use vars qw($VERSION @ISA);
+use Image::ExifTool qw(:Utils :Vars);
+use Image::ExifTool::Shortcuts;
+use Image::ExifTool::HTML qw(EscapeHTML);
+use Image::ExifTool::IPTC;
+use Image::ExifTool::Canon;
+use Image::ExifTool::Nikon;
+
+$VERSION = '1.59';
+@ISA = qw(Exporter);
+
+sub NumbersFirst;
+
+# colors for html pages
+my $noteFont = "<span class=n>";
+my $noteFontSmall = "<span class='n s'>";
+
+my $docType = q{<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+        "http://www.w3.org/TR/html4/loose.dtd">
+};
+
+
+my $caseInsensitive;    # flag to ignore case when sorting tag names
+
+# Descriptions for the TagNames documentation
+# Note: POD headers in these descriptions start with '~' instead of '=' to keep
+# from confusing POD parsers which apparently parse inside quoted strings.
+my %docs = (
+    PodHeader => q{
+~head1 NAME
+
+Image::ExifTool::TagNames - ExifTool tag name documentation
+
+~head1 DESCRIPTION
+
+This document contains a complete list of ExifTool tag names, organized into
+tables based on information type.  Tag names are used to indicate the
+specific meta information that is extracted or written in an image.
+
+~head1 TAG TABLES
+},
+    ExifTool => q{
+The tables listed below give the names of all tags recognized by ExifTool.
+},
+    ExifTool2 => q{
+B<Tag ID>, B<Index> or B<Sequence> is given in the first column of each
+table.  A B<Tag ID> is the computer-readable equivalent of a tag name, and
+is the identifier that is actually stored in the file.  An B<Index> refers
+to the location of a value when found at a fixed position within a data
+block, and B<Sequence> gives the order of values for a serial data stream.
+
+A B<Tag Name> is the handle by which the information is accessed in
+ExifTool.  In some instances, more than one name may correspond to a single
+tag ID.  In these cases, the actual name used depends on the context in
+which the information is found.  Case is not significant for tag names.  A
+question mark after a tag name indicates that the information is either not
+understood, not verified, or not very useful -- these tags are not extracted
+by ExifTool unless the Unknown (-u) option is enabled.  Be aware that some
+tag names are different than the descriptions printed out by default when
+extracting information with exiftool.  To see the tag names instead of the
+descriptions, use C<exiftool -s>.
+
+The B<Writable> column indicates whether the tag is writable by ExifTool.
+Anything but an C<N> in this column means the tag is writable.  A C<Y>
+indicates writable information that is either unformatted or written using
+the existing format.  Other expressions give details about the information
+format, and vary depending on the general type of information.  The format
+name may be followed by a number in square brackets to indicate the number
+of values written, or the number of characters in a fixed-length string
+(including a null terminator which is added if required).
+
+An asterisk (C<*>) after an entry in the B<Writable> column indicates a
+"protected" tag which is not writable directly, but is set via a Composite
+tag.  A tilde (C<~>) indicates a tag this is only writable when print
+conversion is disabled (by setting PrintConv to 0, or using the -n option).
+A slash (C</>) indicates an "avoided" tag that is not created unless the
+group is specified (due to name conflicts with other tags).  An exclamation
+point (C<!>) indicates a tag that is considered unsafe to write under normal
+circumstances.  These "unsafe" tags are not set when calling
+SetNewValuesFromFile() or when using the exiftool -TagsFromFile option
+unless specified explicitly, and care should be taken when editing them
+manually since they may affect the way an image is rendered.  A plus sign
+(C<+>) indicates a "list" tag which supports multiple instances.
+
+The HTML version of these tables also list possible B<Values> for
+discrete-valued tags, as well as B<Notes> for some tags.
+
+B<Note>: If you are familiar with common meta-information tag names, you may
+find that some ExifTool tag names are different than expected.  The usual
+reason for this is to make the tag names more consistent across different
+types of meta information.  To determine a tag name, either consult this
+documentation or run C<exiftool -s> on a file containing the information in
+question.
+},
+    EXIF => q{
+EXIF stands for "Exchangeable Image File Format".  This type of information
+is formatted according to the TIFF specification, and may be found in JPG,
+TIFF, PNG, MIFF and WDP images, as well as many TIFF-based RAW images.
+
+The EXIF meta information is organized into different Image File Directories
+(IFD's) within an image.  The names of these IFD's correspond to the
+ExifTool family 1 group names.  When writing EXIF information, the default
+B<Group> listed below is used unless another group is specified.
+
+Also listed in the table below are TIFF, DNG, WDP and other tags which are
+not part of the EXIF specification, but may co-exist with EXIF tags in some
+images.
+},
+    GPS => q{
+These GPS tags are part of the EXIF standard, and are stored in a separate
+IFD within the EXIF information.
+
+ExifTool is very flexible about the input format when writing lat/long
+coordinates, and will accept from 1 to 3 floating point numbers (for decimal
+degrees, degrees and minutes, or degrees, minutes and seconds) separated by
+just about anything, and will format them properly according to the EXIF
+specification.
+
+Some GPS tags have values which are fixed-length strings. For these, the
+indicated string lengths include a null terminator which is added
+automatically by ExifTool.  Remember that the descriptive values are used
+when writing (ie. 'Above Sea Level', not '0') unless the print conversion is
+disabled (with '-n' on the command line, or the PrintConv option in the
+API).
+},
+    XMP => q{
+XMP stands for "Extensible Metadata Platform", an XML/RDF-based metadata
+format which is being pushed by Adobe.  Information in this format can be
+embedded in many different image file types including JPG, JP2, TIFF, PNG,
+MIFF, PS, PDF, PSD and DNG, as well as audio file formats supporting ID3v2
+information.
+
+The XMP B<Tag ID>'s aren't listed because in most cases they are identical
+to the B<Tag Name>.
+
+All XMP information is stored as character strings.  The B<Writable> column
+specifies the information format:  C<integer> is a string of digits
+(possibly beginning with a '+' or '-'), C<real> is a floating point number,
+C<rational> is two C<integer> strings separated by a '/' character, C<date>
+is a date/time string in the format "YYYY:MM:DD HH:MM:SS[+/-HH:MM]",
+C<boolean> is either "True" or "False", and C<lang-alt> is a list of string
+alternatives in different languages.
+
+Individual languages for C<lang-alt> tags are accessed by suffixing the tag
+name with a '-', followed by an RFC 3066 language code (ie. "XMP:Title-fr",
+or "Rights-en-US").  A C<lang-alt> tag with no language code accesses the
+"x-default" language, but causes other languages to be deleted when writing.
+The "x-default" language code may be specified when writing a new value to
+write only the default language, but note that all languages are still
+deleted if "x-default" tag is deleted.  When reading, "x-default" is not
+specified.
+
+The XMP tags are organized according to schema B<Namespace> in the following
+tables.  Note that a few of the longer namespace prefixes given below have
+been shortened for convenience (since the family 1 group names are derived
+from these by adding a leading "XMP-").  In cases where a tag name exists in
+more than one namespace, less common namespaces are avoided when writing.
+However, any namespace may be written by specifying a family 1 group name
+for the tag, ie) XMP-exif:Contrast or XMP-crs:Contrast.
+
+ExifTool will extract XMP information even if it is not listed in these
+tables.  For example, the C<pdfx> namespace doesn't have a predefined set of
+tag names because it is used to store application-defined PDF information,
+but this information is extracted by ExifTool anyway.
+},
+    IPTC => q{
+IPTC stands for "International Press Telecommunications Council".  This is
+an older meta information format that is slowly being phased out in favor of
+XMP.  IPTC information may be embedded in JPG, TIFF, PNG, MIFF, PS, PDF, PSD
+and DNG images.
+
+The IPTC specification dictates a length for ASCII (C<string> or C<digits>)
+values.  These lengths are given in square brackets after the B<Writable>
+format name.  For tags where a range of lengths is allowed, the minimum and
+maximum lengths are separated by a comma within the brackets.  IPTC strings
+are not null terminated.
+
+IPTC information is separated into different records, each of which has its
+own set of tags.
+},
+    Photoshop => q{
+Photoshop tags are found in PSD files, as well as inside embedded Photoshop
+information in many other file types (JPEG, TIFF, PDF, PNG to name a few).
+
+Many Photoshop tags are marked as Unknown (indicated by a question mark
+after the tag name) because the information they provide is not very useful
+under normal circumstances (and because Adobe denied my application for
+their file format documentation -- apparently open source software is too
+big a concept for them).  These unknown tags are not extracted unless the
+Unknown (-u) option is used.
+},
+    PrintIM => q{
+The format of the PrintIM information is known, however no PrintIM tags have
+been decoded.  Use the Unknown (-u) option to extract PrintIM information.
+},
+    Kodak => q{
+The Kodak maker notes aren't in standard IFD format, and the format varies
+frequently with different models.  Some information has been decoded, but
+much of the Kodak information remains unknown.
+},
+    'Kodak SpecialEffects' => q{
+The Kodak SpecialEffects and Borders tags are found in sub-IFD's within the
+Kodak JPEG APP3 "Meta" segment.
+},
+    Minolta => q{
+These tags are used by Minolta and Konica/Minolta cameras.  Minolta doesn't
+make things easy for decoders because the meaning of some tags and the
+location where some information is stored is different for different camera
+models.  (Take MinoltaQuality for example, which may be located in 5
+different places.)
+},
+    Olympus => q{
+Tags 0x0000 through 0x0103 are used by some older Olympus cameras, and are
+the same as Konica/Minolta tags.  The Olympus tags are also used for Epson
+and Agfa cameras.
+},
+    Panasonic => q{
+Panasonic tags are also used for Leica cameras.
+},
+    Pentax => q{
+The Pentax tags are also used in Asahi cameras.
+},
+    Sigma => q{
+These tags are used in Sigma/Foveon cameras.
+},
+    Sony => q{
+The maker notes in images from current Sony camera models contain a wealth
+of information, but very little is known about these tags.  Use the ExifTool
+Unknown (-u) or Verbose (-v) options to see information about the unknown
+tags.
+},
+    CanonRaw => q{
+These tags apply to CRW-format Canon RAW files and information in the APP0
+"CIFF" segment of JPEG images.  When writing CanonRaw/CIFF information, the
+length of the information is preserved (and the new information is truncated
+or padded as required) unless B<Writable> is C<resize>. Currently, only
+JpgFromRaw and ThumbnailImage are allowed to change size.
+},
+    Unknown => q{
+The following tags are decoded in unsupported maker notes.  Use the Unknown
+(-u) option to display other unknown tags.
+},
+    PDF => q{
+The tags listed in the PDF tables below are those which are used by ExifTool
+to extract meta information, but they are only a small fraction of the total
+number of available PDF tags.
+},
+    DNG => q{
+The main DNG tags are found in the EXIF table.  The tables below define only
+information found within structures of these main DNG tag values.
+},
+    MPEG => q{
+The MPEG format doesn't specify any file-level meta information.  In lieu of
+this, information is extracted from the first audio and video frame headers
+in the file.
+},
+    Real => q{
+ExifTool recognizes three basic types of Real audio/video files: 1)
+RealMedia (RM, RV and RMVB), 2) RealAudio (RA), and 3) Real Metafile (RAM
+and RPM).
+},
+    Extra => q{
+The extra tags represent information found in the image but not associated
+with any other tag group.  The three writable "pseudo" tags (Filename,
+Directory and FileModifyDate) may be written without the need to rewrite the
+file since their values are not contained within the file data.
+},
+    Composite => q{
+The values of the composite tags are derived from the values of other tags.
+These are convenience tags which are calculated after all other information
+is extracted.
+},
+    Shortcuts => q{
+Shortcut tags are convenience tags that represent one or more other tag
+names.  They are used like regular tags to read and write the information
+for a specified set of tags.
+
+The shortcut tags below have been pre-defined, but user-defined shortcuts
+may be added via the %Image::ExifTool::Shortcuts::UserDefined lookup in the
+~/.ExifTool_config file.  See the Image::ExifTool::Shortcuts documentation
+for more details.
+},
+    PodTrailer => q{
+~head1 NOTES
+
+This document generated automatically by
+L<Image::ExifTool::BuildTagLookup|Image::ExifTool::BuildTagLookup>.
+
+~head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+~head1 SEE ALSO
+
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+~cut
+},
+);
+
+
+#------------------------------------------------------------------------------
+# New - create new BuildTagLookup object
+# Inputs: 0) reference to BuildTagLookup object or BuildTagLookup class name
+sub new
+{
+    local $_;
+    my $that = shift;
+    my $class = ref($that) || $that || 'Image::ExifTool::BuildTagLookup';
+    my $self = bless {}, $class;
+    my (%subdirs, %isShortcut);
+    my %count = (
+        'unique tag names' => 0,
+        'total tags' => 0,
+    );
+#
+# loop through all tables, accumulating TagLookup and TagName information
+#
+    my (%tagNameInfo, %id, %longID, %longName, %shortName, %tableNum,
+        %tagLookup, %tagExists, %tableWritable, %sepTable, %compositeModules);
+    $self->{TAG_NAME_INFO} = \%tagNameInfo;
+    $self->{TAG_ID} = \%id;
+    $self->{LONG_ID} = \%longID;
+    $self->{LONG_NAME} = \%longName;
+    $self->{SHORT_NAME} = \%shortName;
+    $self->{TABLE_NUM} = \%tableNum;
+    $self->{TAG_LOOKUP} = \%tagLookup;
+    $self->{TAG_EXISTS} = \%tagExists;
+    $self->{TABLE_WRITABLE} = \%tableWritable;
+    $self->{SEPARATE_TABLE} = \%sepTable;
+    $self->{COMPOSITE_MODULES} = \%compositeModules;
+    $self->{COUNT} = \%count;
+
+    Image::ExifTool::LoadAllTables();
+    my @tableNames = sort keys %allTables;
+    push @tableNames, 'Image::ExifTool::Shortcuts::Main'; # add Shortcuts last
+    my $tableNum = 0;
+    my $tableName;
+    # create lookup for short table names
+    foreach $tableName (@tableNames) {
+        my $short = $tableName;
+        $short =~ s/^Image::ExifTool:://;
+        $short =~ s/::Main$//;
+        $short =~ s/::/ /;
+        $short =~ s/(.*)Tags$/\u$1/;
+        $short =~ s/^Exif\b/EXIF/;
+        $shortName{$tableName} = $short;    # remember short name
+        $tableNum{$tableName} = $tableNum++;
+    }
+    # make lookup table to check for shortcut tags
+    my $tag;
+    foreach $tag (keys %Image::ExifTool::Shortcuts::Main) {
+        my $entry = $Image::ExifTool::Shortcuts::Main{$tag};
+        # ignore if shortcut tag name includes itself
+        next if ref $entry eq 'ARRAY' and grep /^$tag$/, @$entry;
+        $isShortcut{lc($tag)} = 1;
+    }
+    foreach $tableName (@tableNames) {
+        # create short table name
+        my $short = $shortName{$tableName};
+        my $info = $tagNameInfo{$tableName} = [ ];
+        my ($table, $shortcut);
+        if ($short eq 'Shortcuts') {
+            # can't use GetTagTable() for Shortcuts (not a normal table)
+            $table = \%Image::ExifTool::Shortcuts::Main;
+            $shortcut = 1;
+        } else {
+            $table = GetTagTable($tableName);
+        }
+        my $tableNum = $tableNum{$tableName};
+        my $writeProc = $table->{WRITE_PROC};
+        $longID{$tableName} = 0;
+        $longName{$tableName} = 0;
+        # save all tag names
+        my ($tagID, $binaryTable, $noID, $isIPTC);
+        $isIPTC = 1 if $$table{WRITE_PROC} and $$table{WRITE_PROC} eq \&Image::ExifTool::IPTC::WriteIPTC;
+        $noID = 1 if $short =~ /^(Composite|XMP|Extra|Shortcuts|ASF.*)$/ or $table->{VARS}->{NO_ID};
+        if (($table->{VARS} and $table->{VARS}->{INDEX}) or
+            ($table->{PROCESS_PROC} and
+             $table->{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData))
+        {
+            $binaryTable = 1;
+            $id{$tableName} = 'Index';
+        } elsif ($table->{PROCESS_PROC} and
+            $table->{PROCESS_PROC} eq \&Image::ExifTool::Canon::ProcessSerialData)
+        {
+            $binaryTable = 1;
+            $id{$tableName} = 'Sequence';
+        } elsif ($isIPTC and $$table{PROCESS_PROC}) { #only the main IPTC table has a PROCESS_PROC
+            $id{$tableName} = 'Record';
+        } elsif (not $noID) {
+            $id{$tableName} = 'Tag ID';
+        }
+        $caseInsensitive = ($tableName =~ /::XMP::/);
+        my @keys = sort NumbersFirst TagTableKeys($table);
+        my $defFormat = $table->{FORMAT};
+        if (not $defFormat and $table->{PROCESS_PROC} and
+            $table->{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData)
+        {
+            $defFormat = 'int8u';   # use default format for binary data tables
+        }
+TagID:  foreach $tagID (@keys) {
+            my ($tagInfo, @tagNames, $subdir, $format, @values);
+            my (@infoArray, @require, @writeGroup, @writable);
+            if ($shortcut) {
+                # must build a dummy tagInfo list since Shortcuts is not a normal table
+                $tagInfo = { Name => $tagID, Writable => 1, Require => { } };
+                my $i;
+                for ($i=0; $i<@{$$table{$tagID}}; ++$i) {
+                    $tagInfo->{Require}->{$i} = $table->{$tagID}->[$i];
+                }
+                @infoArray = ( $tagInfo );
+            } else {
+                @infoArray = GetTagInfoList($table,$tagID);
+            }
+            $format = $defFormat;
+            foreach $tagInfo (@infoArray) {
+                if ($$tagInfo{Notes}) {
+                    my $note = $$tagInfo{Notes};
+                    # remove leading/trailing blank lines
+                    $note =~ s/(^\s+|\s+$)//g;
+                    # remove leading/trailing spaces on each line
+                    $note =~ s/(^[ \t]+|[ \t]+$)//mg;
+                    push @values, "($note)";
+                }
+                my $writable;
+                if (defined $$tagInfo{Writable}) {
+                    $writable = $$tagInfo{Writable};
+                } elsif (not $$tagInfo{SubDirectory}) {
+                    $writable = $$table{WRITABLE};
+                }
+                my $writeGroup;
+                $writeGroup = $$tagInfo{WriteGroup};
+                unless ($writeGroup) {
+                    $writeGroup = $$table{WRITE_GROUP} if $writable;
+                    $writeGroup = '-' unless $writeGroup;
+                }
+                $format = $$tagInfo{Format} if defined $$tagInfo{Format};
+                if ($$tagInfo{SubDirectory}) {
+                    # don't show XMP structure tags
+                    next TagID if $short =~ /^XMP /;
+                    $subdir = 1;
+                    my $subTable = $tagInfo->{SubDirectory}->{TagTable} || $tableName;
+                    push @values, $shortName{$subTable}
+                } else {
+                    $subdir = 0;
+                }
+                my $type;
+                foreach $type ('Require','Desire') {
+                    my $require = $$tagInfo{$type};
+                    if ($require) {
+                        foreach (sort { $a <=> $b } keys %$require) {
+                            push @require, $$require{$_};
+                        }
+                    }
+                }
+                my $printConv = $$tagInfo{PrintConv};
+                if (ref($printConv) =~ /^(HASH|ARRAY)$/) {
+                    my (@printConvList, @indexList, $index);
+                    if (ref $printConv eq 'ARRAY') {
+                        for ($index=0; $index<@$printConv; ++$index) {
+                            next if ref $$printConv[$index] ne 'HASH';
+                            push @printConvList, $$printConv[$index];
+                            push @indexList, $index;
+                        }
+                        $printConv = shift @printConvList;
+                        $index = shift @indexList;
+                    }
+                    while (defined $printConv) {
+                        push @values, "[Value $index]" if defined $index;
+                        if ($$tagInfo{SeparateTable}) {
+                            $subdir = 1;
+                            my $s = $$tagInfo{SeparateTable};
+                            $s = $$tagInfo{Name} if $s eq '1';
+                            # add module name if not specified
+                            $s =~ / / or ($short =~ /^(\w+)/ and $s = "$1 $s");
+                            push @values, $s;
+                            $sepTable{$s} = $printConv;
+                            # add PrintHex flag to PrintConv so we can check it later
+                            $$printConv{PrintHex} = 1 if $$tagInfo{PrintHex};
+                        } else {
+                            $caseInsensitive = 0;
+                            my @pk = sort NumbersFirst keys %$printConv;
+                            my $bits;
+                            foreach (@pk) {
+                                next if $_ eq '';
+                                $_ eq 'BITMASK' and $bits = $$printConv{$_}, next;
+                                my $index;
+                                if ($$tagInfo{PrintHex}) {
+                                    $index = sprintf('0x%x',$_);
+                                } elsif (/^[-+]?\d+$/) {
+                                    $index = $_;
+                                } else {
+                                    # ignore unprintable values
+                                    next if /[\x00-\x1f\x80-\xff]/;
+                                    $index = "'$_'";
+                                }
+                                push @values, "$index = " . $$printConv{$_};
+                            }
+                            if ($bits) {
+                                my @pk = sort NumbersFirst keys %$bits;
+                                foreach (@pk) {
+                                    push @values, "Bit $_ = " . $$bits{$_};
+                                }
+                            }
+                        }
+                        last unless @printConvList;
+                        $printConv = shift @printConvList;
+                        $index = shift @indexList;
+                    }
+                } elsif ($printConv and $printConv =~ /DecodeBits\(\$val,\s*(\{.*\})\s*\)/s) {
+                    my $bits = eval $1;
+                    if ($@) {
+                        warn $@;
+                    } else {
+                        my @pk = sort NumbersFirst keys %$bits;
+                        foreach (@pk) {
+                            push @values, "Bit $_ = " . $$bits{$_};
+                        }
+                    }
+                }
+                if ($subdir and not $$tagInfo{SeparateTable}) {
+                    # subdirectories are only writable if specified explicitly
+                    $writable = '-' . ($$tagInfo{Writable} ? $writable : '');
+                } else {
+                    # not writable if we can't do the inverse conversions
+                    my $noPrintConvInv;
+                    if ($writable) {
+                        foreach ('PrintConv','ValueConv') {
+                            next unless $$tagInfo{$_};
+                            next if $$tagInfo{$_ . 'Inv'};
+                            next if ref($$tagInfo{$_}) =~ /^(HASH|ARRAY)$/;
+                            next if $$tagInfo{WriteAlso};
+                            if ($_ eq 'ValueConv') {
+                                undef $writable;
+                            } else {
+                                $noPrintConvInv = 1;
+                            }
+                        }
+                    }
+                    if (not $writable) {
+                        $writable = 'N';
+                    } else {
+                        $writable eq '1' and $writable = $format ? $format : 'Y';
+                        my $count = $$tagInfo{Count} || 1;
+                        # adjust count to Writable size if different than Format
+                        if ($writable and $format and $writable ne $format and
+                            $Image::ExifTool::Exif::formatNumber{$writable} and
+                            $Image::ExifTool::Exif::formatNumber{$format})
+                        {
+                            my $n1 = $Image::ExifTool::Exif::formatNumber{$format};
+                            my $n2 = $Image::ExifTool::Exif::formatNumber{$writable};
+                            $count *= $Image::ExifTool::Exif::formatSize[$n1] /
+                                      $Image::ExifTool::Exif::formatSize[$n2];
+                        }
+                        if ($count != 1) {
+                            $count = 'n' if $count < 0;
+                            $writable .= "[$count]";
+                        }
+                        $writable .= '~' if $noPrintConvInv;
+                        # add a '*' if this tag is protected or a '~' for unsafe tags
+                        if ($$tagInfo{Protected}) {
+                            $writable .= '*' if $$tagInfo{Protected} & 0x02;
+                            $writable .= '!' if $$tagInfo{Protected} & 0x01;
+                        }
+                        $writable .= '/' if $$tagInfo{Avoid};
+                    }
+                    $writable .= '+' if $$tagInfo{List};
+                    # separate tables link like subdirectories (flagged with leading '-')
+                    $writable = "-$writable" if $subdir;
+                }
+                # don't duplicate a tag name unless an entry is different
+                my $name = $$tagInfo{Name};
+                my $lcName = lc($name);
+                # check for conflicts with shortcut names
+                if ($isShortcut{$lcName} and $short ne 'Shortcuts' and
+                    ($$tagInfo{Writable} or not $$tagInfo{SubDirectory}))
+                {
+                    warn "WARNING: $short $name is a shortcut tag!\n";
+                }
+                $name .= '?' if $$tagInfo{Unknown};
+                unless (@tagNames and $tagNames[-1] eq $name and
+                    $writeGroup[-1] eq $writeGroup and $writable[-1] eq $writable)
+                {
+                    push @tagNames, $name;
+                    push @writeGroup, $writeGroup;
+                    push @writable, $writable;
+                }
+#
+# add this tag to the tag lookup unless PROCESS_PROC is 0 or shortcut tag
+#
+                next if $shortcut or (defined $$table{PROCESS_PROC} and not $$table{PROCESS_PROC});
+                # count our tags
+                if ($$tagInfo{SubDirectory}) {
+                    $subdirs{$lcName} or $subdirs{$lcName} = 0;
+                    ++$subdirs{$lcName};
+                } else {
+                    ++$count{'total tags'};
+                    unless ($tagExists{$lcName} and (not $subdirs{$lcName} or $subdirs{$lcName} == $tagExists{$lcName})) {
+                        ++$count{'unique tag names'};
+                    }
+                }
+                $tagExists{$lcName} or $tagExists{$lcName} = 0;
+                ++$tagExists{$lcName};
+                # only add writable tags to lookup table (for speed)
+                my $wflag = $$tagInfo{Writable};
+                next unless $writeProc and ($wflag or ($$table{WRITABLE} and
+                    not defined $wflag and not $$tagInfo{SubDirectory}));
+                $tagLookup{$lcName} or $tagLookup{$lcName} = { };
+                # remember number for this table
+                my $tagIDs = $tagLookup{$lcName}->{$tableNum};
+                # must allow for duplicate tags with the same name in a single table!
+                if ($tagIDs) {
+                    if (ref $tagIDs eq 'HASH') {
+                        $$tagIDs{$tagID} = 1;
+                        next;
+                    } elsif ($tagID eq $tagIDs) {
+                        next;
+                    } else {
+                        $tagIDs = { $tagIDs => 1, $tagID => 1 };
+                    }
+                } else {
+                    $tagIDs = $tagID;
+                }
+                $tableWritable{$tableName} = 1;
+                $tagLookup{$lcName}->{$tableNum} = $tagIDs;
+                if ($short eq 'Composite' and $$tagInfo{Module}) {
+                    $compositeModules{$lcName} = $$tagInfo{Module};
+                }
+            }
+#
+# save TagName information
+#
+            my $tagIDstr;
+            if ($tagID =~ /^\d+$/) {
+                if ($binaryTable or $isIPTC or ($short =~ /^CanonCustom/ and $tagID < 256)) {
+                    $tagIDstr = $tagID;
+                } else {
+                    $tagIDstr = sprintf("0x%.4x",$tagID);
+                }
+            } elsif ($short eq 'DICOM') {
+                ($tagIDstr = $tagID) =~ s/_/,/;
+            } else {
+                # convert non-printable characters to hex escape sequences
+                if ($tagID =~ s/([\x00-\x1f\x7f-\xff])/'\x'.unpack('H*',$1)/eg) {
+                    $tagID =~ s/\\x00/\\0/g;
+                    next if $tagID eq 'jP\x1a\x1a'; # ignore abnormal JP2 signature tag
+                    $tagIDstr = qq{"$tagID"};
+                } else {
+                    $tagIDstr = "'$tagID'";
+                }
+            }
+            my $len = length $tagIDstr;
+            $longID{$tableName} = $len if $longID{$tableName} < $len;
+            foreach (@tagNames) {
+                $len = length $_;
+                $longName{$tableName} = $len if $longName{$tableName} < $len;
+            }
+            push @$info, [ $tagIDstr, \@tagNames, \@writable, \@values, \@require, \@writeGroup ];
+        }
+    }
+    return $self;
+}
+
+#------------------------------------------------------------------------------
+# Rewrite this file to build the lookup tables
+# Inputs: 0) BuildTagLookup object reference
+#         1) output tag lookup module name (ie. 'lib/Image/ExifTool/TagLookup.pm')
+# Returns: true on success
+sub WriteTagLookup($$)
+{
+    local $_;
+    my ($self, $file) = @_;
+    my $tagLookup = $self->{TAG_LOOKUP};
+    my $tagExists = $self->{TAG_EXISTS};
+    my $tableWritable = $self->{TABLE_WRITABLE};
+#
+# open/create necessary files and transfer file headers
+#
+    my $tmpFile = "${file}_tmp";
+    open(INFILE,$file) or warn("Can't open $file\n"), return 0;
+    unless (open(OUTFILE,">$tmpFile")) {
+        warn "Can't create temporary file $tmpFile\n";
+        close(INFILE);
+        return 0;
+    }
+    my $success;
+    while (<INFILE>) {
+        print OUTFILE $_ or last;
+        if (/^#\+{4} Begin/) {
+            $success = 1;
+            last;
+        }
+    }
+    print OUTFILE "\n# list of tables containing writable tags\n";
+    print OUTFILE "my \@tableList = (\n";
+
+#
+# write table list
+#
+    my @tableNames = sort keys %allTables;
+    my $tableName;
+    my %wrNum;      # translate from allTables index to writable tables index
+    my $count = 0;
+    my $num = 0;
+    foreach $tableName (@tableNames) {
+        if ($$tableWritable{$tableName}) {
+            print OUTFILE "\t'$tableName',\n";
+            $wrNum{$count} = $num++;
+        }
+        $count++;
+    }
+#
+# write the tag lookup table
+#
+    my $tag;
+    # verify that certain critical tag names aren't duplicated
+    foreach $tag (qw{filename directory}) {
+        next unless $$tagLookup{$tag};
+        my $n = scalar keys %{$$tagLookup{$tag}};
+        warn "Warning: $n writable '$tag' tags!\n" if $n > 1;
+    }
+    print OUTFILE ");\n\n# lookup for all writable tags\nmy \%tagLookup = (\n";
+    foreach $tag (sort keys %$tagLookup) {
+        print OUTFILE "\t'$tag' => { ";
+        my @tableNums = sort { $a <=> $b } keys %{$$tagLookup{$tag}};
+        my (@entries, $tableNum);
+        foreach $tableNum (@tableNums) {
+            my $tagID = $$tagLookup{$tag}->{$tableNum};
+            my $entry;
+            if (ref $tagID eq 'HASH') {
+                my @tagIDs = sort keys %$tagID;
+                foreach (@tagIDs) {
+                    if (/^\d+$/) {
+                        $_ = sprintf("0x%x",$_);
+                    } else {
+                        my $quot = "'";
+                        # escape non-printable characters in tag ID if necessary
+                        $quot = '"' if s/[\x00-\x1f,\x7f-\xff]/sprintf('\\x%.2x',ord($&))/ge;
+                        $_ = $quot . $_ . $quot;
+                    }
+                }
+                $entry = '[' . join(',', @tagIDs) . ']';
+            } elsif ($tagID =~ /^\d+$/) {
+                $entry = sprintf("0x%x",$tagID);
+            } else {
+                $entry = "'$tagID'";
+            }
+            my $wrNum = $wrNum{$tableNum};
+            push @entries, "$wrNum => $entry";
+        }
+        print OUTFILE join(', ', @entries);
+        print OUTFILE " },\n";
+    }
+#
+# write tag exists lookup
+#
+    print OUTFILE ");\n\n# lookup for non-writable tags to check if the name exists\n";
+    print OUTFILE "my \%tagExists = (\n";
+    foreach $tag (sort keys %$tagExists) {
+        next if $$tagLookup{$tag};
+        print OUTFILE "\t'$tag' => 1,\n";
+    }
+#
+# write module lookup for writable composite tags
+#
+    my $compositeModules = $self->{COMPOSITE_MODULES};
+    print OUTFILE ");\n\n# module names for writable Composite tags\n";
+    print OUTFILE "my \%compositeModules = (\n";
+    foreach (sort keys %$compositeModules) {
+        print OUTFILE "\t'$_' => '$$compositeModules{$_}',\n";
+    }
+    print OUTFILE ");\n\n";
+#
+# finish writing TagLookup.pm and clean up
+#
+    if ($success) {
+        $success = 0;
+        while (<INFILE>) {
+            $success or /^#\+{4} End/ or next;
+            print OUTFILE $_;
+            $success = 1;
+        }
+    }
+    close(INFILE);
+    close(OUTFILE) or $success = 0;
+#
+# return success code
+#
+    if ($success) {
+        rename($tmpFile, $file);
+    } else {
+        unlink($tmpFile);
+        warn "Error rewriting file\n";
+    }
+    return $success;
+}
+
+#------------------------------------------------------------------------------
+# sort numbers first numerically, then strings alphabetically (case insensitive)
+sub NumbersFirst
+{
+    my $rtnVal;
+    my $bNum = ($b =~ /^-?[0-9]+$/);
+    if ($a =~ /^-?[0-9]+$/) {
+        $rtnVal = ($bNum ? $a <=> $b : -1);
+    } elsif ($bNum) {
+        $rtnVal = 1;
+    } else {
+        my ($a2, $b2) = ($a, $b);
+        # expand numbers to 3 digits (with restrictions to avoid messing up ascii-hex tags)
+        $a2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $a2 =~ /^(APP)?[0-9 ]*$/ and length($a2)<16;
+        $b2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $b2 =~ /^(APP)?[0-9 ]*$/ and length($b2)<16;
+        $caseInsensitive and $rtnVal = (lc($a2) cmp lc($b2));
+        $rtnVal or $rtnVal = ($a2 cmp $b2);
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Convert pod documentation to pod
+# (funny, I know, but the pod headings must be hidden to prevent confusing
+#  the pod parser)
+# Inputs: 0) string
+sub Doc2Pod($)
+{
+    my $doc = shift;
+    $doc =~ s/\n~/\n=/g;
+    return $doc;
+}
+
+#------------------------------------------------------------------------------
+# Convert pod documentation to html
+# Inputs: 0) string
+sub Doc2Html($)
+{
+    my $doc = EscapeHTML(shift);
+    $doc =~ s/\n\n/<\/p>\n\n<p>/g;
+    $doc =~ s/B&lt;(.*?)&gt;/<b>$1<\/b>/sg;
+    $doc =~ s/C&lt;(.*?)&gt;/<code>$1<\/code>/sg;
+    $doc =~ s/L&lt;(.*?)&gt;/<a href="$1">$1<\/a>/sg;
+    return $doc;
+}
+
+#------------------------------------------------------------------------------
+# Get the order that we want to print the tables in the documentation
+# Returns: tables in the order we want
+sub GetTableOrder()
+{
+    my %gotTable;
+    my $count = 0;
+    my @tableNames = @tableOrder;
+    my (@orderedTables, %mainTables, @outOfOrder);
+    my $lastTable = '';
+
+    while (@tableNames) {
+        my $tableName = shift @tableNames;
+        next if $gotTable{$tableName};
+        if ($tableName =~ /^Image::ExifTool::(\w+)::Main/) {
+            $mainTables{$1} = 1;
+        } elsif ($lastTable and not $tableName =~ /^${lastTable}::/) {
+            push @outOfOrder, $tableName;
+        }
+        ($lastTable) = ($tableName =~ /^(Image::ExifTool::\w+)/);
+        push @orderedTables, $tableName;
+        $gotTable{$tableName} = 1;
+        my $table = GetTagTable($tableName);
+        # recursively scan through tables in subdirectories
+        my @moreTables;
+        $caseInsensitive = ($tableName =~ /::XMP::/);
+        my @keys = sort NumbersFirst TagTableKeys($table);
+        foreach (@keys) {
+            my @infoArray = GetTagInfoList($table,$_);
+            my $tagInfo;
+            foreach $tagInfo (@infoArray) {
+                my $subdir = $$tagInfo{SubDirectory} or next;
+                $tableName = $$subdir{TagTable} or next;
+                next if $gotTable{$tableName};  # next if table already loaded
+                push @moreTables, $tableName;   # must scan this one too
+            }
+        }
+        unshift @tableNames, @moreTables;
+    }
+    # clean up the order for tables which are out of order
+    # (groups all Canon and Kodak tables together)
+    my %fixOrder;
+    foreach (@outOfOrder) {
+        next unless /^Image::ExifTool::(\w+)/;
+        # only re-order tables which have a corresponding main table
+        next unless $mainTables{$1};
+        $fixOrder{$1} = [];     # fix the order of these tables
+    }
+    my (@sortedTables, %fixPos, $pos);
+    foreach (@orderedTables) {
+        if (/^Image::ExifTool::(\w+)/ and $fixOrder{$1}) {
+            my $fix = $fixOrder{$1};
+            unless (@$fix) {
+                $pos = @sortedTables;
+                $fixPos{$pos} or $fixPos{$pos} = [];
+                push @{$fixPos{$pos}}, $1;
+            }
+            push @{$fix}, $_;
+        } else {
+            push @sortedTables, $_;
+        }
+    }
+    # insert back in better order
+    foreach $pos (reverse sort { $a <=> $b } keys %fixPos) {
+        my $fix = $fixPos{$pos};
+        foreach (@$fix) {
+            splice(@sortedTables, $pos, 0, @{$fixOrder{$_}});
+        }
+    }
+    # tweak the table order
+    my %tweakOrder = (
+        JPEG    => '-',     # JPEG comes first
+        IPTC    => 'Exif',  # put IPTC after EXIF,
+        GPS     => 'XMP',   # etc...
+        GeoTiff => 'GPS',
+        Leaf    => 'Kodak',
+        Unknown => 'Sony',
+        DNG     => 'Unknown',
+        PrintIM => 'ICC_Profile',
+        Olympus => 'NikonCapture',
+        Pentax  => 'Panasonic',
+        Ricoh   => 'Pentax',
+        Sanyo   => 'Ricoh',
+        PhotoMechanic => 'FotoStation',
+    );
+    my @tweak = sort keys %tweakOrder;
+    while (@tweak) {
+        my $table = shift @tweak;
+        my $first = $tweakOrder{$table};
+        if ($tweakOrder{$first}) {
+            push @tweak, $table;    # must defer this till later
+            next;
+        }
+        delete $tweakOrder{$table}; # because the table won't move again
+        my @moving = grep /^Image::ExifTool::$table\b/, @sortedTables;
+        my @notMoving = grep !/^Image::ExifTool::$table\b/, @sortedTables;
+        my @after;
+        while (@notMoving) {
+            last if $notMoving[-1] =~ /^Image::ExifTool::$first\b/;
+            unshift @after, pop @notMoving;
+        }
+        @sortedTables = (@notMoving, @moving, @after);
+    }
+    return @sortedTables
+}
+
+#------------------------------------------------------------------------------
+# Open HTMLFILE and print header and description
+# Inputs: 0) Filename, 1) optional category
+# Returns: True on success
+my %createdFiles;
+sub OpenHtmlFile($;$$)
+{
+    my ($htmldir, $category, $sepTable) = @_;
+    my ($htmlFile, $head, $title, $url, $class);
+    my $top = '';
+
+    if ($category) {
+        my @names = split ' ', $category;
+        $class = shift @names;
+        $htmlFile = "$htmldir/TagNames/$class.html";
+        $head = $category . ($sepTable ? ' Values' : ' Tags');
+        ($title = $head) =~ s/ .* / /;
+        @names and $url = join '_', @names;
+    } else {
+        $htmlFile = "$htmldir/TagNames/index.html";
+        $category = $class = 'ExifTool';
+        $head = $title = 'ExifTool Tag Names';
+    }
+    if ($createdFiles{$htmlFile}) {
+        open(HTMLFILE,">>${htmlFile}_tmp") or return 0;
+    } else {
+        open(HTMLFILE,">${htmlFile}_tmp") or return 0;
+        print HTMLFILE "$docType<html>\n<head>\n<title>$title</title>\n";
+        print HTMLFILE "<link rel=stylesheet type='text/css' href='style.css' title='Style'>\n";
+        print HTMLFILE "</head>\n<body>\n";
+        if ($category ne $class and $docs{$class}) {
+            print HTMLFILE "<h2 class=top>$class Tags</h2>\n" or return 0;
+            print HTMLFILE '<p>',Doc2Html($docs{$class}),"</p>\n" or return 0;
+        } else {
+            $top = " class=top";
+        }
+    }
+    $head = "<a name='$url'>$head</a>" if $url;
+    print HTMLFILE "<h2$top>$head</h2>\n" or return 0;
+    print HTMLFILE '<p>',Doc2Html($docs{$category}),"</p>\n" if $docs{$category};
+    $createdFiles{$htmlFile} = 1;
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Close all html files and write trailers
+# Returns: true on success
+# Inputs: 0) BuildTagLookup object reference
+sub CloseHtmlFiles($)
+{
+    my $self = shift;
+    my $preserveDate = $$self{PRESERVE_DATE};
+    my $success = 1;
+    # get the date
+    my ($sec,$min,$hr,$day,$mon,$yr) = localtime;
+    my @month = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
+    $yr += 1900;
+    my $date = "$month[$mon] $day, $yr";
+    my $htmlFile;
+    my $countNewFiles = 0;
+    my $countSameFiles = 0;
+    foreach $htmlFile (keys %createdFiles) {
+        my $tmpFile = $htmlFile . '_tmp';
+        my $fileDate = $date;
+        if ($preserveDate) {
+            my @lines = `grep '<i>Last revised' $htmlFile`;
+            $fileDate = $1 if @lines and $lines[-1] =~ m{<i>Last revised (.*)</i>};
+        }
+        open(HTMLFILE,">>$tmpFile") or $success = 0, next;
+        # write the trailers
+        print HTMLFILE "<hr>\n";
+        print HTMLFILE "(This document generated automatically by Image::ExifTool::BuildTagLookup)\n";
+        print HTMLFILE "<br><i>Last revised $fileDate</i>\n";
+        print HTMLFILE "<p class=lf><a href=";
+        if ($htmlFile =~ /index\.html$/) {
+            print HTMLFILE "'../index.html'>&lt;-- Back to ExifTool home page</a></p>\n";
+        } else {
+            print HTMLFILE "'index.html'>&lt;-- ExifTool Tag Names</a></p>\n"
+        }
+        print HTMLFILE "</body>\n</html>\n" or $success = 0;
+        close HTMLFILE or $success = 0;
+        # check for differences and only use new file if it was changed
+        # (so the date only gets updated if changes were really made)
+        my $useNewFile;
+        if ($success) {
+            open (TEMPFILE, $tmpFile) or $success = 0, last;
+            if (open (HTMLFILE, $htmlFile)) {
+                while (<HTMLFILE>) {
+                    my $newLine = <TEMPFILE>;
+                    if (defined $newLine) {
+                        next if /^<br><i>Last revised/;
+                        next if $_ eq $newLine;
+                    }
+                    # files are different -- use the new file
+                    $useNewFile = 1;
+                    last;
+                }
+                $useNewFile = 1 if <TEMPFILE>;
+                close HTMLFILE;
+            } else {
+                $useNewFile = 1;
+            }
+            close TEMPFILE;
+            if ($useNewFile) {
+                ++$countNewFiles;
+                rename $tmpFile, $htmlFile or warn("Error renaming temporary file\n"), $success = 0;
+            } else {
+                ++$countSameFiles;
+                unlink $tmpFile;   # erase new file and use existing file
+            }
+        }
+        last unless $success;
+    }
+    # save number of files processed so we can check the results later
+    $self->{COUNT}->{'HTML files changed'} = $countNewFiles;
+    $self->{COUNT}->{'HTML files unchanged'} = $countSameFiles;
+    return $success;
+}
+
+#------------------------------------------------------------------------------
+# Write the TagName HTML and POD documentation
+# Inputs: 0) BuildTagLookup object reference
+#         1) output pod file (ie. 'lib/Image/ExifTool/TagNames.pod')
+#         2) output html directory (ie. 'html')
+# Returns: true on success
+sub WriteTagNames($$)
+{
+    my ($self, $podFile, $htmldir) = @_;
+    my ($tableName, $short, $url, @sepTables);
+    my $tagNameInfo = $self->{TAG_NAME_INFO} or return 0;
+    my $idTitle = $self->{TAG_ID};
+    my $shortName = $self->{SHORT_NAME};
+    my $sepTable = $self->{SEPARATE_TABLE};
+    my $success = 1;
+    my %htmlFiles;
+    my $columns = 6;    # number of columns in html index
+    my $percent = int(100 / $columns);
+
+    # open the file and write the header
+    open(PODFILE,">$podFile") or return 0;
+    print PODFILE Doc2Pod($docs{PodHeader}), $docs{ExifTool}, $docs{ExifTool2};
+    mkdir "$htmldir/TagNames";
+    OpenHtmlFile($htmldir) or return 0;
+    print HTMLFILE "<blockquote>\n";
+    print HTMLFILE "<table width='100%' class=frame><tr><td>\n";
+    print HTMLFILE "<table width='100%' class=inner cellspacing=1><tr class=h>\n";
+    print HTMLFILE "<th colspan=$columns><span class=l>Tag Table Index</span></th></tr>\n";
+    print HTMLFILE "<tr class=b><td width='$percent%'>\n";
+    # write the index
+    my @tableNames = GetTableOrder();
+    push @tableNames, 'Image::ExifTool::Shortcuts::Main';   # do Shortcuts last
+    # get list of headings and add any missing ones
+    my $heading = 'xxx';
+    my (@tableIndexNames, @headings);
+    foreach $tableName (@tableNames) {
+        $short = $$shortName{$tableName};
+        my @names = split ' ', $short;
+        my $class = shift @names;
+        if (@names) {
+            # add heading for tables without a Main
+            unless ($heading eq $class) {
+                $heading = $class;
+                push @tableIndexNames, $heading;
+                push @headings, $heading;
+            }
+        } else {
+            $heading = $short;
+            push @headings, $heading;
+        }
+        push @tableIndexNames, $tableName;
+    }
+    @tableNames = @tableIndexNames;
+    # print html index of headings only
+    my $count = 0;
+    my $lines = int((scalar(@headings) + $columns - 1) / $columns);
+    foreach $tableName (@headings) {
+        if ($count) {
+            if ($count % $lines) {
+                print HTMLFILE "<br>\n";
+            } else {
+                print HTMLFILE "</td><td width='$percent%'>\n";
+            }
+        }
+        $short = $$shortName{$tableName};
+        $short = $tableName unless $short;
+        $url = "$short.html";
+        print HTMLFILE "<a href='$url'>$short</a>";
+        ++$count;
+    }
+    print HTMLFILE "\n</td></tr></table></td></tr></table></blockquote>\n";
+    print HTMLFILE '<p>',Doc2Html($docs{ExifTool2}),"</p>\n";
+    # write all the tag tables
+    while (@tableNames or @sepTables) {
+        while (@sepTables) {
+            $tableName = shift @sepTables;
+            my $printConv = $$sepTable{$tableName};
+            next unless ref $printConv eq 'HASH';
+            $$sepTable{$tableName} = 1;
+            my $notes = $$printConv{Notes};
+            if ($notes) {
+                # remove unnecessary whitespace
+                $notes =~ s/(^\s+|\s+$)//g;
+                $notes =~ s/(^[ \t]+|[ \t]+$)//mg;
+            }
+            my $head = $tableName;
+            $head =~ s/.* //;
+            close HTMLFILE;
+            if (OpenHtmlFile($htmldir, $tableName, 1)) {
+                print HTMLFILE Doc2Html($notes), "\n" if $notes;
+                print HTMLFILE "<blockquote>\n";
+                print HTMLFILE "<table class=frame><tr><td>\n";
+                print HTMLFILE "<table class='inner sep' cellspacing=1>\n";
+                my $align = ' class=r';
+                my $wid = 0;
+                my @keys;
+                foreach (sort NumbersFirst keys %$printConv) {
+                    next if /^(Notes|PrintHex)$/;
+                    $align = '' if $align and /[^\d]/;
+                    my $w = length($_) + length($$printConv{$_});
+                    $wid = $w if $wid < $w;
+                    push @keys, $_;
+                }
+                $wid = length($tableName)+7 if $wid < length($tableName)+7;
+                # print in multiple columns if there is room
+                my $cols = int(80 / ($wid + 4));
+                $cols = 1 if $cols < 1 or $cols > @keys;
+                my $rows = int((scalar(@keys) + $cols - 1) / $cols);
+                my ($r, $c);
+                print HTMLFILE '<tr class=h>';
+                for ($c=0; $c<$cols; ++$c) {
+                    print HTMLFILE "<th>Value</th><th>$head</th>";
+                }
+                print HTMLFILE "</tr>\n";
+                for ($r=0; $r<$rows; ++$r) {
+                    print HTMLFILE '<tr>';
+                    for ($c=0; $c<$cols; ++$c) {
+                        my $key = $keys[$r + $c*$rows];
+                        my ($index, $prt);
+                        if (defined $key) {
+                            $index = $key;
+                            $prt = "= $$printConv{$key}";
+                            if ($$printConv{PrintHex}) {
+                                $index = sprintf('0x%x',$index);
+                            } elsif ($index !~ /^[-+]?\d+$/) {
+                                $index = "'" . EscapeHTML($index) . "'";
+                            }
+                        } else {
+                            $index = $prt = '&nbsp;';
+                        }
+                        my ($ic, $pc);
+                        if ($c & 0x01) {
+                            $pc = ' class=b';
+                            $ic = $align ? " class='r b'" : $pc;
+                        } else {
+                            $ic = $align;
+                            $pc = '';
+                        }
+                        print HTMLFILE "<td$ic>$index</td><td$pc>$prt</td>\n";
+                    }
+                    print HTMLFILE '</tr>';
+                }
+                print HTMLFILE "</table></td></tr></table></blockquote>\n\n";
+            }
+        }
+        last unless @tableNames;
+        $tableName = shift @tableNames;
+        $short = $$shortName{$tableName};
+        unless ($short) {
+            # this is just an index heading
+            print PODFILE "\n=head2 $tableName Tags\n";
+            print PODFILE $docs{$tableName} if $docs{$tableName};
+            next;
+        }
+        my $info = $$tagNameInfo{$tableName};
+        my $id = $$idTitle{$tableName};
+        my ($hid, $showGrp);
+        # widths of the different columns in the POD documentation
+        my ($wID,$wTag,$wReq,$wGrp) = (8,36,24,10);
+        my $composite = $short eq 'Composite' ? 1 : 0;
+        my $derived = $composite ? '<th>Derived From</th>' : '';
+        if ($short eq 'Shortcuts') {
+            $derived = '<th>Refers To</th>';
+            $composite = 2;
+        }
+        my $podIdLen = $self->{LONG_ID}->{$tableName};
+        my $notes;
+        unless ($composite == 2) {
+            my $table = GetTagTable($tableName);
+            $notes = $$table{NOTES};
+        }
+        my $prefix;
+        if ($notes) {
+            # remove unnecessary whitespace
+            $notes =~ s/(^\s+|\s+$)//g;
+            $notes =~ s/(^[ \t]+|[ \t]+$)//mg;
+            if ($notes =~ /leading '(.*?_)' which/) {
+                $prefix = $1;
+                $podIdLen -= length $prefix;
+            }
+        }
+        if ($podIdLen <= $wID) {
+            $podIdLen = $wID;
+        } elsif ($short eq 'DICOM') {
+            $podIdLen = 10;
+        } else {
+            # align tag names in secondary columns if possible
+            my $col = ($podIdLen <= 10) ? 12 : 20;
+            $podIdLen = $col if $podIdLen < $col;
+        }
+        $id = '' if $short =~ /^XMP/;
+        if ($id) {
+            ($hid = "<th>$id</th>") =~ s/ /&nbsp;/g;
+            $wTag -= $podIdLen - $wID;
+            $wID = $podIdLen;
+            my $longTag = $self->{LONG_NAME}->{$tableName};
+            if ($wTag < $longTag) {
+                $wID -= $longTag - $wTag;
+                $wTag = $longTag;
+                warn "Notice: Long tags in $tableName table\n";
+            }
+        } elsif ($short !~ /^(Composite|Shortcuts)/) {
+            $wTag += 9;
+            $hid = '';
+        } else {
+            $hid = '';
+            $wTag += $wID - $wReq if $composite;
+        }
+        if ($short eq 'EXIF') {
+            $derived = '<th>Group</th>';
+            $showGrp = 1;
+            $wTag -= $wGrp + 1;
+        }
+        my $head = ($short =~ / /) ? 'head3' : 'head2';
+        print PODFILE "\n=$head $short Tags\n";
+        print PODFILE $docs{$short} if $docs{$short};
+        print PODFILE "\n$notes\n" if $notes;
+        my $line = "\n";
+        if ($id) {
+            # shift over 'Index' heading by one character for a bit more balance
+            $id = " $id" if $id eq 'Index';
+            $line .= sprintf "  %-${wID}s", $id;
+        } else {
+            $line .= ' ';
+        }
+        my $tagNameHeading = ($short eq 'XMP') ? 'Namespace' : 'Tag Name';
+        $line .= sprintf " %-${wTag}s", $tagNameHeading;
+        $line .= sprintf " %-${wReq}s", $composite == 2 ? 'Refers To' : 'Derived From' if $composite;
+        $line .= sprintf " %-${wGrp}s", 'Group' if $showGrp;
+        $line .= ' Writable';
+        print PODFILE $line;
+        $line =~ s/Sequence /Sequence\t/;   # don't want an underline after 'Sequence'
+        $line =~ s/\S/-/g;
+        $line =~ s/- -/---/g;
+        $line =~ tr/\t/ /;
+        print PODFILE $line,"\n";
+        close HTMLFILE;
+        OpenHtmlFile($htmldir, $short) or $success = 0;
+        print HTMLFILE '<p>',Doc2Html($notes), "</p>\n" if $notes;
+        print HTMLFILE "<blockquote>\n";
+        print HTMLFILE "<table class=frame><tr><td>\n";
+        print HTMLFILE "<table class=inner cellspacing=1>\n";
+        print HTMLFILE "<tr class=h>$hid<th>$tagNameHeading</th>\n";
+        print HTMLFILE "<th>Writable</th>$derived<th>Values / ${noteFont}Notes</span></th></tr>\n";
+        my $rowClass = 1;
+        my $infoCount = 0;
+        my $infoList;
+        foreach $infoList (@$info) {
+            ++$infoCount;
+            my ($tagIDstr, $tagNames, $writable, $values, $require, $writeGroup) = @$infoList;
+            my ($align, $idStr, $w);
+            if (not $id) {
+                $idStr = '  ';
+            } elsif ($tagIDstr =~ /^\d+$/) {
+                $w = $wID - 3;
+                $idStr = sprintf "  %${w}d    ", $tagIDstr;
+                $align = " class=r";
+            } else {
+                $tagIDstr =~ s/^'$prefix/'/ if $prefix;
+                $w = $wID;
+                if (length $tagIDstr > $w) {
+                    # put tag name on next line if ID is too long
+                    $idStr = "  $tagIDstr\n   " . (' ' x $w);
+                    warn "Notice: Split $$tagNames[0] line\n";
+                } else {
+                    $idStr = sprintf "  %-${w}s ", $tagIDstr;
+                }
+                $align = '';
+            }
+            my @reqs;
+            my @tags = @$tagNames;
+            my @wGrp = @$writeGroup;
+            my @vals = @$writable;
+            my $wrStr = shift @vals;
+            my $subdir;
+            # if this is a subdirectory, print subdir name (from values) instead of writable
+            if ($wrStr =~ /^-/) {
+                $subdir = 1;
+                @vals = @$values;
+                # remove Notes if subdir has Notes as well
+                shift @vals if $vals[0] =~ /^\(/ and @vals >= @$writable;
+                foreach (@vals) { /^\(/ and $_ = '-' }
+                my $i;  # fill in any missing entries from non-directory tags
+                for ($i=0; $i<@$writable; ++$i) {
+                    $vals[$i] = $$writable[$i] unless defined $vals[$i];
+                }
+                if ($$sepTable{$vals[0]}) {
+                    $wrStr =~ s/^-//;
+                    $wrStr = 'N' unless $wrStr;
+                } else {
+                    $wrStr = $vals[0];
+                }
+                shift @vals;
+            }
+            my $tag = shift @tags;
+            printf PODFILE "%s%-${wTag}s", $idStr, $tag;
+            warn "Warning: Pushed $tag\n" if $id and length($tag) > $wTag;
+            printf PODFILE " %-${wGrp}s", shift(@wGrp) || '-' if $showGrp;
+            if ($composite) {
+                @reqs = @$require;
+                $w = $wReq; # Keep writable column in line
+                length($tag) > $wTag and $w -= length($tag) - $wTag;
+                printf PODFILE " %-${w}s", shift(@reqs) || '';
+            }
+            printf PODFILE " $wrStr\n";
+            my $n = 0;
+            while (@tags or @reqs or @vals) {
+                my $more = (@tags or @reqs);
+                $line = '  ';
+                $line .= ' 'x($wID+1) if $id;
+                $line .= sprintf("%-${wTag}s", shift(@tags) || '');
+                $line .= sprintf(" %-${wReq}s", shift(@reqs) || '') if $composite;
+                $line .= sprintf(" %-${wGrp}s", shift(@wGrp) || '-') if $showGrp;
+                ++$n;
+                if (@vals) {
+                    my $val = shift @vals;
+                    # use writable if this is a note
+                    my $wrStr = $$writable[$n];
+                    if ($subdir and ($val =~ /^\(/ or $val =~ /=/ or ($wrStr and $wrStr !~ /^-/))) {
+                        $val = $wrStr;
+                        if (defined $val) {
+                            $val =~ s/^-//;
+                        } else {
+                            # done with tag if nothing else to print
+                            last unless $more;
+                        }
+                    }
+                    $line .= " $val" if defined $val;
+                }
+                $line =~ s/\s+$//;  # trim trailing white space
+                print PODFILE "$line\n";
+            }
+            my @htmlTags;
+            foreach (@$tagNames) {
+                push @htmlTags, EscapeHTML($_);
+            }
+            $rowClass = $rowClass ? '' : " class=b";
+            my $isSubdir;
+            if ($$writable[0] =~ /^-/) {
+                $isSubdir = 1;
+                foreach (@$writable) {
+                    s/^-(.+)/$1/;
+                }
+            }
+            print HTMLFILE "<tr$rowClass>\n";
+            print HTMLFILE "<td$align>$tagIDstr</td>\n" if $id;
+            print HTMLFILE "<td>", join("\n  <br>",@htmlTags), "</td>\n";
+            print HTMLFILE "<td class=c>",join('<br>',@$writable),"</td>\n";
+            print HTMLFILE '<td>',join("\n  <br>",@$require),"</td>\n" if $composite;
+            print HTMLFILE "<td class=c>",join('<br>',@$writeGroup),"</td>\n" if $showGrp;
+            print HTMLFILE "<td>";
+            my $close = '';
+            my @values;
+            if (@$values) {
+                if ($isSubdir) {
+                    my $smallNote;
+                    foreach (@$values) {
+                        if (/^\(/) {
+                            $smallNote = 1 if $n <= 1;
+                            push @values, ($smallNote ? $noteFontSmall : $noteFont) . "$_</span>";
+                            next;
+                        }
+                        /=/ and push(@values, $_), next;
+                        my @names = split;
+                        $url = (shift @names) . '.html';
+                        @names and $url .= '#' . join '_', @names;
+                        my $suffix = ' Tags';
+                        if ($$sepTable{$_}) {
+                            push @sepTables, $_;
+                            $suffix = ' Values';
+                        }
+                        push @values, "--&gt; <a href='$url'>$_$suffix</a>";
+                    }
+                    # put small note last
+                    $smallNote and push @values, shift @values;
+                } else {
+                    foreach (@$values) {
+                        $_ = EscapeHTML($_);
+                        /^\(/ and $_ = "$noteFont$_</span>";
+                        push @values, $_;
+                    }
+                    print HTMLFILE "<span class=s>";
+                    $close = '</span>';
+                }
+            } else {
+                push @values, '&nbsp;';
+            }
+            print HTMLFILE join("\n  <br>",@values),"$close</td></tr>\n";
+        }
+        unless ($infoCount) {
+            printf PODFILE "  [no tags known]\n";
+            my $cols = 3;
+            ++$cols if $hid;
+            ++$cols if $derived;
+            print HTMLFILE "<tr><td colspan=$cols class=c>[no tags known]</td></tr>\n";
+        }
+        print HTMLFILE "</table></td></tr></table></blockquote>\n\n";
+    }
+    close(HTMLFILE) or $success = 0;
+    CloseHtmlFiles($self) or $success = 0;
+    print PODFILE Doc2Pod($docs{PodTrailer}) or $success = 0;
+    close(PODFILE) or $success = 0;
+    return $success;
+}
+
+1;  # end
+
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::BuildTagLookup - Build ExifTool tag lookup tables
+
+=head1 DESCRIPTION
+
+This module is used to generate the tag lookup tables in
+Image::ExifTool::TagLookup.pm and tag name documentation in
+Image::ExifTool::TagNames.pod, as well as HTML tag name documentation.  It
+is used before each new ExifTool release to update the lookup tables and
+documentation.
+
+=head1 SYNOPSIS
+
+  use Image::ExifTool::BuildTagLookup;
+
+  $builder = new Image::ExifTool::BuildTagLookup;
+
+  $ok = $builder->WriteTagLookup('lib/Image/ExifTool/TagLookup.pm');
+
+  $ok = $builder->WriteTagNames('lib/Image/ExifTool/TagNames.pod','html');
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool(3pm)|Image::ExifTool>,
+L<Image::ExifTool::TagLookup(3pm)|Image::ExifTool::TagLookup>,
+L<Image::ExifTool::TagNames(3pm)|Image::ExifTool::TagNames>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Canon.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Canon.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Canon.pm	(revision 20131)
@@ -0,0 +1,3302 @@
+#------------------------------------------------------------------------------
+# File:         Canon.pm
+#
+# Description:  Canon EXIF maker notes tags
+#
+# Revisions:    11/25/03 - P. Harvey Created
+#               12/03/03 - P. Harvey Figured out lots more tags and added
+#                            CanonAFInfo
+#               02/17/04 - Michael Rommel Added IxusAFPoint
+#               01/27/05 - P. Harvey Disable validation of CanonAFInfo
+#               01/30/05 - P. Harvey Added a few more tags (ref 4)
+#               02/10/06 - P. Harvey Decode a lot of new tags (ref 12)
+#
+# References:   1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
+#               2) Michael Rommel private communication (Digital Ixus)
+#               3) Daniel Pittman private communication (PowerShot S70)
+#               4) http://www.wonderland.org/crw/
+#               5) Juha Eskelinen private communication (20D)
+#               6) Richard S. Smith private communication (20D)
+#               7) Denny Priebe private communication (1D MkII)
+#               8) Irwin Poche private communication
+#               9) Michael Tiemann private communication (1D MkII)
+#              10) Volker Gering private communication (1D MkII)
+#              11) "cip" private communication
+#              12) Rainer Honle private communication (5D)
+#              13) http://www.cybercom.net/~dcoffin/dcraw/
+#              14) (bozi) http://www.cpanforum.com/threads/2476 and /2563
+#              15) http://homepage3.nifty.com/kamisaka/makernote/makernote_canon.htm and
+#                  http://homepage3.nifty.com/kamisaka/makernote/CanonLens.htm (2006/07/04)
+#              16) Emil Sit private communication (30D)
+#              17) http://www.asahi-net.or.jp/~xp8t-ymzk/s10exif.htm
+#              18) Samson Tai private communication (G7)
+#              19) Warren Stockton private communication
+#              20) Bogdan private communication
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Canon;
+
+use strict;
+use vars qw($VERSION %canonModelID);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+
+sub WriteCanon($$$);
+sub ProcessSerialData($$$);
+
+$VERSION = '1.77';
+
+my %canonLensTypes = ( #4
+    1 => 'Canon EF 50mm f/1.8',
+    2 => 'Canon EF 28mm f/2.8',
+    3 => 'Canon EF 135mm f/2.8 Soft', #15
+    4 => 'Sigma UC Zoom 35-135mm f/4-5.6',
+    6 => 'Sigma 18-125mm F3.5-5.6 DC IF ASP or Tokina AF193-2 19-35mm f/3.5-4.5',
+    7 => 'Canon EF 100-300mm F5.6L', #15
+    # 10 can be 3 different Sigma lenses:
+    # Sigma 50mm f/2.8 EX or Sigma 28mm f/1.8
+    # or Sigma 105mm f/2.8 Macro EX (ref 15)
+    10 => 'Canon EF 50mm f/2.5 Macro or Sigma', #10/4/15
+    11 => 'Canon EF 35mm f/2', #9
+    13 => 'Canon EF 15mm f/2.8', #9
+    21 => 'Canon EF 80-200mm f/2.8L',
+    22 => 'Tokina AT-X280AF PRO 28-80mm F2.8 ASPHERICAL', #15
+    # 26 can also be 2 Tamron lenses: (ref 15)
+    # Tamron SP AF 90mm f/2.8 Di Macro or Tamron SP AF 180mm F3.5 Di Macro
+    26 => 'Canon EF 100mm f/2.8 Macro or Cosina 100mm f/3.5 Macro AF or Tamron',
+    # 28 can be: (ref 15)
+    # - Tamron SP AF 28-105mm f/2.8 LD Aspherical IF
+    # - Tamron SP AF 28-75mm F/2.8 XR Di LD Aspherical [ IF ] Macro
+    28 => 'Tamron AF Aspherical 28-200mm f/3.8-5.6 or 28-75mm f/2.8 or 28-105mm f/2.8',#4/11/14/15
+    29 => 'Canon EF 50mm f/1.8 MkII',
+    31 => 'Tamron SP AF 300mm f/2.8 LD IF', #15
+    32 => 'Canon EF 24mm f/2.8 or Sigma 15mm f/2.8 EX Fisheye', #10/11
+    39 => 'Canon EF 75-300mm f/4-5.6',
+    40 => 'Canon EF 28-80mm f/3.5-5.6',
+    43 => 'Canon EF 28-105mm f/4-5.6', #10
+    45 => 'Canon EF-S 18-55mm f/3.5-5.6', #PH
+    124 => 'Canon MP-E 65mm f/2.8 1-5x Macro Photo', #9
+    125 => 'Canon TS-E 24mm f/3.5L',
+    126 => 'Canon TS-E 45mm f/2.8', #15
+    127 => 'Canon TS-E 90mm f/2.8', #15
+    130 => 'Canon EF 50mm f/1.0L', #10/15
+    131 => 'Sigma 17-35mm f2.8-4 EX Aspherical HSM',
+    134 => 'Canon EF 600mm f/4L IS', #15
+    135 => 'Canon EF 200mm f/1.8L',
+    136 => 'Canon EF 300mm f/2.8L',
+    137 => 'Canon EF 85mm f/1.2L', #10
+    139 => 'Canon EF 400mm f/2.8L',
+    141 => 'Canon EF 500mm f/4.5L',
+    142 => 'Canon EF 300mm f/2.8L IS', #15
+    143 => 'Canon EF 500mm f/4L IS', #15
+    149 => 'Canon EF 100mm f/2', #9
+    # 150 can be: (ref 15)
+    # Sigma 20mm EX F1.8/Sigma 30mm F1.4 DC HSM/Sigma 24mm F1.8 DG Macro EX
+    150 => 'Canon EF 14mm f/2.8L or Sigma 20mm EX f/1.8', #10/4
+    151 => 'Canon EF 200mm f/2.8L',
+    # 152 can be: (ref 15)
+    # Sigma 12-24mm F4.5-5.6 EX DG ASPHERICAL HSM
+    # Sigma 14mm F2.8 EX Aspherical HSM
+    # Sigma 10-20mm F4-5.6 (ref 14)
+    # Sigma 100-300 F4 (ref Bozi)
+    152 => 'Sigma Lens (various models)',
+    # 153 is Tamron AF 28-300mm, 18-200mm F3.5-6.3 Di II or
+    #        Tamron 18-250mm F3.5-6.3 Di II_LD Aspherical (IF) Macro (ref PH)
+    153 => 'Canon EF 35-350mm f/3.5-5.6L or Tamron or Sigma Bigma', #PH/15
+    155 => 'Canon EF 85mm f/1.8 USM',
+    156 => 'Canon EF 28-105mm f/3.5-4.5 USM',
+    160 => 'Canon EF 20-35mm f/3.5-4.5 USM',
+    161 => 'Canon EF 28-70mm f/2.8L or Sigma 24-70mm EX f/2.8 or Tamron 90mm f/2.8',
+    165 => 'Canon EF 70-200mm f/2.8 L',
+    166 => 'Canon EF 70-200mm f/2.8 L + x1.4',
+    167 => 'Canon EF 70-200mm f/2.8 L + x2',
+    168 => 'Canon EF 28mm f/1.8 USM', #15
+    169 => 'Canon EF17-35mm f/2.8L or Sigma 15-30mm f/3.5-4.5 EX DG Aspherical', #15/4
+    170 => 'Canon EF 200mm f/2.8L II', #9
+    # the following value is used by 2 different Sigma lenses (ref 14):
+    # Sigma 180mm EX HSM Macro f/3.5 or Sigma APO Macro 150mm F3.5 EX DG IF HSM
+    # 173 => 'Canon EF 180mm Macro f/3.5L or Sigma 180mm EX HSM Macro f/3.5', #9
+    173 => 'Canon EF 180mm Macro f/3.5L or Sigma 180mm F3.5 or 150mm f/2.8 Macro',
+    174 => 'Canon EF 135mm f/2L', #9
+    176 => 'Canon EF 24-85mm f/3.5-4.5 USM',
+    177 => 'Canon EF 300mm f/4L IS', #9
+    178 => 'Canon EF 28-135mm f/3.5-5.6 IS',
+    180 => 'Canon EF 35mm f/1.4L', #9
+    181 => 'Canon EF 100-400mm f/4.5-5.6L IS + x1.4', #15
+    182 => 'Canon EF 100-400mm f/4.5-5.6L IS + x2',
+    183 => 'Canon EF 100-400mm f/4.5-5.6L IS',
+    184 => 'Canon EF 400mm f/2.8L + x2', #15
+    186 => 'Canon EF 70-200mm f/4L', #9
+    190 => 'Canon EF 100mm f/2.8 Macro',
+    191 => 'Canon EF 400mm f/4 DO IS', #9
+    # 196 Canon 75-300mm F4? #15
+    197 => 'Canon EF 75-300mm f/4-5.6 IS',
+    198 => 'Canon EF 50mm f/1.4 USM', #9
+    202 => 'Canon EF 28-80 f/3.5-5.6 USM IV',
+    211 => 'Canon EF 28-200mm f/3.5-5.6', #15
+    213 => 'Canon EF 90-300mm f/4.5-5.6',
+    214 => 'Canon EF-S 18-55mm f/3.5-4.5 USM', #PH
+    224 => 'Canon EF 70-200mm f/2.8L IS USM', #11
+    225 => 'Canon EF 70-200mm f/2.8L IS USM + x1.4', #11
+    226 => 'Canon EF 70-200mm f/2.8L IS USM + x2', #14
+    229 => 'Canon EF 16-35mm f/2.8L', #PH
+    230 => 'Canon EF 24-70mm f/2.8L', #9
+    231 => 'Canon EF 17-40mm f/4L',
+    232 => 'Canon EF 70-300mm f/4.5-5.6 DO IS USM', #15
+    234 => 'Canon EF-S 17-85mm f4-5.6 IS USM', #19
+    235 => 'Canon EF-S10-22mm F3.5-4.5 USM', #15
+    236 => 'Canon EF-S60mm F2.8 Macro USM', #15
+    237 => 'Canon EF 24-105mm f/4L IS', #15
+    238 => 'Canon EF 70-300mm f/4-5.6 IS USM', #15
+    239 => 'Canon EF 85mm f/1.2L II USM', #15
+    240 => 'Canon EF-S 17-55mm f/2.8 IS USM', #15
+    241 => 'Canon EF 50mm f/1.2L USM', #15
+    242 => 'Canon EF 70-200mm f/4L IS USM', #PH
+);
+
+# Canon model ID numbers (PH)
+%canonModelID = (
+    0x1010000 => 'PowerShot A30',
+    0x1040000 => 'PowerShot S300 / Digital IXUS 300 / IXY Digital 300',
+    0x1060000 => 'PowerShot A20',
+    0x1080000 => 'PowerShot A10',
+    0x1090000 => 'PowerShot S110 / Digital IXUS v / IXY Digital 200',
+    0x1100000 => 'PowerShot G2',
+    0x1110000 => 'PowerShot S40',
+    0x1120000 => 'PowerShot S30',
+    0x1130000 => 'PowerShot A40',
+    0x1140000 => 'EOS D30',
+    0x1150000 => 'PowerShot A100',
+    0x1160000 => 'PowerShot S200 / Digital IXUS v2 / IXY Digital 200a',
+    0x1170000 => 'PowerShot A200',
+    0x1180000 => 'PowerShot S330 / Digital IXUS 330 / IXY Digital 300a',
+    0x1190000 => 'PowerShot G3',
+    0x1210000 => 'PowerShot S45',
+    0x1230000 => 'PowerShot SD100 / Digital IXUS II / IXY Digital 30',
+    0x1240000 => 'PowerShot S230 / Digital IXUS v3 / IXY Digital 320',
+    0x1250000 => 'PowerShot A70',
+    0x1260000 => 'PowerShot A60',
+    0x1270000 => 'PowerShot S400 / Digital IXUS 400 / IXY Digital 400',
+    0x1290000 => 'PowerShot G5',
+    0x1300000 => 'PowerShot A300',
+    0x1310000 => 'PowerShot S50',
+    0x1340000 => 'PowerShot A80',
+    0x1350000 => 'PowerShot SD10 / Digital IXUS i / IXY Digital L',
+    0x1360000 => 'PowerShot S1 IS',
+    0x1370000 => 'PowerShot Pro1',
+    0x1380000 => 'PowerShot S70',
+    0x1390000 => 'PowerShot S60',
+    0x1400000 => 'PowerShot G6',
+    0x1410000 => 'PowerShot S500 / Digital IXUS 500 / IXY Digital 500',
+    0x1420000 => 'PowerShot A75',
+    0x1440000 => 'PowerShot SD110 / Digital IXUS IIs / IXY Digital 30a',
+    0x1450000 => 'PowerShot A400',
+    0x1470000 => 'PowerShot A310',
+    0x1490000 => 'PowerShot A85',
+    0x1520000 => 'PowerShot S410 / Digital IXUS 430 / IXY Digital 450',
+    0x1530000 => 'PowerShot A95',
+    0x1540000 => 'PowerShot SD300 / Digital IXUS 40 / IXY Digital 50',
+    0x1550000 => 'PowerShot SD200 / Digital IXUS 30 / IXY Digital 40',
+    0x1560000 => 'PowerShot A520',
+    0x1570000 => 'PowerShot A510',
+    0x1590000 => 'PowerShot SD20 / Digital IXUS i5 / IXY Digital L2',
+    0x1640000 => 'PowerShot S2 IS',
+    0x1650000 => 'PowerShot SD430 / IXUS Wireless / IXY Wireless',
+    0x1660000 => 'PowerShot SD500 / Digital IXUS 700 / IXY Digital 600',
+    0x1668000 => 'EOS D60',
+    0x1700000 => 'PowerShot SD30 / Digital IXUS i zoom / IXY Digital L3',
+    0x1740000 => 'PowerShot A430',
+    0x1750000 => 'PowerShot A410',
+    0x1760000 => 'PowerShot S80',
+    0x1780000 => 'PowerShot A620',
+    0x1790000 => 'PowerShot A610',
+    0x1800000 => 'PowerShot SD630 / Digital IXUS 65 / IXY Digital 80',
+    0x1810000 => 'PowerShot SD450 / Digital IXUS 55 / IXY Digital 60',
+    0x1820000 => 'PowerShot TX1',
+    0x1870000 => 'PowerShot SD400 / Digital IXUS 50 / IXY Digital 55',
+    0x1880000 => 'PowerShot A420',
+    0x1890000 => 'PowerShot SD900 / Digital IXUS 900 Ti / IXY Digital 1000',
+    0x1900000 => 'PowerShot SD550 / Digital IXUS 750 / IXY Digital 700',
+    0x1920000 => 'PowerShot A700',
+    0x1940000 => 'PowerShot SD700 IS / Digital IXUS 800 IS / IXY Digital 800 IS',
+    0x1950000 => 'PowerShot S3 IS',
+    0x1960000 => 'PowerShot A540',
+    0x1970000 => 'PowerShot SD600 / Digital IXUS 60 / IXY Digital 70',
+    0x1980000 => 'PowerShot G7',
+    0x1990000 => 'PowerShot A530',
+    0x2000000 => 'PowerShot SD800 IS / Digital IXUS 850 IS / IXY Digital 900 IS',
+    0x2010000 => 'PowerShot SD40 / Digital IXUS i7 / IXY Digital L4',
+    0x2020000 => 'PowerShot A710 IS',
+    0x2030000 => 'PowerShot A640',
+    0x2040000 => 'PowerShot A630',
+    0x2090000 => 'PowerShot S5 IS',
+    0x2100000 => 'PowerShot A460',
+    0x2120000 => 'PowerShot SD850 IS / Digital IXUS 950 IS / IXY Digital 810 IS',
+    0x2130000 => 'PowerShot A570 IS',
+    0x2140000 => 'PowerShot A560',
+    0x2150000 => 'PowerShot SD750 / Digital IXUS 75 / IXY Digital 90',
+    0x2160000 => 'PowerShot SD1000 / Digital IXUS 70 / IXY Digital 10',
+    0x2180000 => 'PowerShot A550',
+    0x2190000 => 'PowerShot A450',
+    0x2230000 => 'PowerShot G9',
+    0x2240000 => 'PowerShot A650 IS',
+    0x2260000 => 'PowerShot A720 IS',
+    0x2290000 => 'PowerShot SX100 IS',
+    0x2300000 => 'PowerShot SD950 IS / Digital IXUS 960 IS / IXY Digital 2000 IS',
+    0x2310000 => 'PowerShot SD870 IS / Digital IXUS 860 IS / IXY Digital 910 IS',
+    0x3010000 => 'PowerShot Pro90 IS',
+    0x4040000 => 'PowerShot G1',
+    0x6040000 => 'PowerShot S100 / Digital IXUS / IXY Digital',
+    0x4007d675 => 'HV10',
+    0x4007d777 => 'iVIS DC50',
+    0x4007d778 => 'iVIS HV20',
+    0x80000001 => 'EOS-1D',
+    0x80000167 => 'EOS-1DS',
+    0x80000168 => 'EOS 10D',
+    0x80000169 => 'EOS-1D Mark III',
+    0x80000170 => 'EOS Digital Rebel / 300D / Kiss Digital',
+    0x80000174 => 'EOS-1D Mark II',
+    0x80000175 => 'EOS 20D',
+    0x80000188 => 'EOS-1Ds Mark II',
+    0x80000189 => 'EOS Digital Rebel XT / 350D / Kiss Digital N',
+    0x80000190 => 'EOS 40D',
+    0x80000213 => 'EOS 5D',
+    0x80000215 => 'EOS-1Ds Mark III',
+    0x80000232 => 'EOS-1D Mark II N',
+    0x80000234 => 'EOS 30D',
+    0x80000236 => 'EOS Digital Rebel XTi / 400D / Kiss Digital X',
+);
+
+my %canonQuality = (
+    1 => 'Economy',
+    2 => 'Normal',
+    3 => 'Fine',
+    4 => 'RAW',
+    5 => 'Superfine',
+);
+my %canonImageSize = (
+    0 => 'Large',
+    1 => 'Medium',
+    2 => 'Small',
+    5 => 'Medium 1', #PH
+    6 => 'Medium 2', #PH
+    7 => 'Medium 3', #PH
+    8 => 'Postcard', #PH (SD200 1600x1200 with DateStamp option)
+    9 => 'Widescreen', #PH (SD900 3648x2048)
+);
+my %canonWhiteBalance = (
+    0 => 'Auto',
+    1 => 'Daylight',
+    2 => 'Cloudy',
+    3 => 'Tungsten',
+    4 => 'Fluorescent',
+    5 => 'Flash',
+    6 => 'Custom',
+    7 => 'Black & White',
+    8 => 'Shade',
+    9 => 'Manual Temperature (Kelvin)',
+    10 => 'PC Set1', #PH
+    11 => 'PC Set2', #PH
+    12 => 'PC Set3', #PH
+    14 => 'Daylight Fluorescent', #3
+    15 => 'Custom 1', #PH
+    16 => 'Custom 2', #PH
+    17 => 'Underwater', #3
+);
+
+# picture styles used by the 5D
+# (styles 0x4X may be downloaded from Canon)
+my %pictureStyles = ( #12
+    0x00 => 'None', #PH
+    0x01 => 'Standard', #PH guess (1D)
+    0x02 => 'Set 1', #PH guess (1D)
+    0x03 => 'Set 2', #PH guess (1D)
+    0x04 => 'Set 3', #PH guess (1D)
+    0x21 => 'User Def. 1',
+    0x22 => 'User Def. 2',
+    0x23 => 'User Def. 3',
+    # "External" styles currently available from Canon are Nostalgia, Clear,
+    # Twilight and Emerald.  The "User Def" styles change to these "External"
+    # codes when these styles are installed in the camera
+    0x41 => 'External 1',
+    0x42 => 'External 2',
+    0x43 => 'External 3',
+    0x81 => 'Standard',
+    0x82 => 'Portrait',
+    0x83 => 'Landscape',
+    0x84 => 'Neutral',
+    0x85 => 'Faithful',
+    0x86 => 'Monochrome',
+);
+my %userDefStyles = ( #12
+    0x41 => 'Nostalgia',
+    0x42 => 'Clear',
+    0x43 => 'Twilight',
+    0x81 => 'Standard',
+    0x82 => 'Portrait',
+    0x83 => 'Landscape',
+    0x84 => 'Neutral',
+    0x85 => 'Faithful',
+    0x86 => 'Monochrome',
+);
+
+# ValueConv that makes long values binary type
+my %longBin = (
+    ValueConv => 'length($val) > 64 ? \$val : $val',
+    ValueConvInv => '$val',
+);
+
+#------------------------------------------------------------------------------
+# Canon EXIF Maker Notes
+%Image::ExifTool::Canon::Main = (
+    WRITE_PROC => \&WriteCanon,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x1 => {
+        Name => 'CanonCameraSettings',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::CameraSettings',
+        },
+    },
+    0x2 => {
+        Name => 'CanonFocalLength',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::FocalLength',
+        },
+    },
+    0x3 => {
+        Name => 'CanonFlashInfo',
+        Unknown => 1,
+    },
+    0x4 => {
+        Name => 'CanonShotInfo',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::ShotInfo',
+        },
+    },
+    0x5 => {
+        Name => 'CanonPanorama',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::Panorama',
+        },
+    },
+    0x6 => {
+        Name => 'CanonImageType',
+        Writable => 'string',
+    },
+    0x7 => {
+        Name => 'CanonFirmwareVersion',
+        Writable => 'string',
+    },
+    0x8 => {
+        Name => 'FileNumber',
+        Writable => 'int32u',
+        PrintConv => '$_=$val,s/(\d+)(\d{4})/$1-$2/,$_',
+        PrintConvInv => '$val=~s/-//g;$val',
+    },
+    0x9 => {
+        Name => 'OwnerName',
+        Writable => 'string',
+    },
+    0xa => {
+        Name => 'ColorInfoD30',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::ColorInfoD30',
+        },
+    },
+    0xc => [   # square brackets for a conditional list
+        {
+            # D30
+            Name => 'SerialNumber',
+            Description => 'Camera Body No.',
+            Condition => '$$self{CameraModel} =~ /EOS D30\b/',
+            Writable => 'int32u',
+            PrintConv => 'sprintf("%x-%.5d",$val>>16,$val&0xffff)',
+            PrintConvInv => '$val=~/(.*)-(\d+)/ ? (hex($1)<<16)+$2 : undef',
+        },
+        {
+            # serial number of 1D/1Ds/1D Mark II/1Ds Mark II is usually
+            # displayed w/o leeding zeros (ref 7) (1D uses 6 digits - PH)
+            Name => 'SerialNumber',
+            Description => 'Camera Body No.',
+            Condition => '$$self{CameraModel} =~ /EOS-1D/',
+            Writable => 'int32u',
+            PrintConv => 'sprintf("%.6u",$val)',
+            PrintConvInv => '$val',
+        },
+        {
+            # all other models (D60,300D,350D,REBEL,10D,20D,etc)
+            Name => 'SerialNumber',
+            Description => 'Camera Body No.',
+            Writable => 'int32u',
+            PrintConv => 'sprintf("%.10u",$val)',
+            PrintConvInv => '$val',
+        },
+    ],
+    0xd => [
+        {
+            Name => 'CanonCameraInfo',
+            Condition => '$$self{CameraModel} =~ /\b(1D(?! Mark III)|5D)/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Canon::CameraInfo',
+            },
+        },
+        {
+            Name => 'CanonCameraInfo1DmkIII',
+            Condition => '$$self{CameraModel} =~ /\b1D Mark III/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIII',
+            },
+        },
+        {
+            Name => 'CanonCameraInfo2',
+            # valid if format is int32u[138] or int32u[148]
+            Condition => q{ $format eq 'int32u' and ($count == 138 or $count == 148) },
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Canon::CameraInfo2',
+            },
+        },
+        {
+            Name => 'CanonCameraInfoUnknown32',
+            Condition => q{ $format =~ /^int32/ },
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown32',
+            },
+        },
+        {
+            Name => 'CanonCameraInfoUnknown16',
+            Condition => q{ $format =~ /^int16/ },
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown16',
+            },
+        },
+        {
+            Name => 'CanonCameraInfoUnknown8',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown8',
+            },
+        },
+    ],
+    0xe => {
+        Name => 'CanonFileLength',
+        Writable => 'int32u',
+        Groups => { 2 => 'Image' },
+    },
+    0xf => [
+        {   # used by 1DmkII, 1DsMkII and 1DmkIIN
+            Name => 'CustomFunctions1D',
+            Condition => '$$self{CameraModel} =~ /EOS-1D/',
+            SubDirectory => {
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+                TagTable => 'Image::ExifTool::CanonCustom::Functions1D',
+            },
+        },
+        {
+            Name => 'CustomFunctions5D',
+            Condition => '$$self{CameraModel} =~ /EOS 5D/',
+            SubDirectory => {
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+                TagTable => 'Image::ExifTool::CanonCustom::Functions5D',
+            },
+        },
+        {
+            Name => 'CustomFunctions10D',
+            Condition => '$$self{CameraModel} =~ /EOS 10D/',
+            SubDirectory => {
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+                TagTable => 'Image::ExifTool::CanonCustom::Functions10D',
+            },
+        },
+        {
+            Name => 'CustomFunctions20D',
+            Condition => '$$self{CameraModel} =~ /EOS 20D/',
+            SubDirectory => {
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+                TagTable => 'Image::ExifTool::CanonCustom::Functions20D',
+            },
+        },
+        {
+            Name => 'CustomFunctions30D',
+            Condition => '$$self{CameraModel} =~ /EOS 30D/',
+            SubDirectory => {
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+                TagTable => 'Image::ExifTool::CanonCustom::Functions30D',
+            },
+        },
+        {
+            Name => 'CustomFunctions350D',
+            Condition => '$$self{CameraModel} =~ /\b(350D|REBEL XT|Kiss Digital N)\b/',
+            SubDirectory => {
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+                TagTable => 'Image::ExifTool::CanonCustom::Functions350D',
+            },
+        },
+        {
+            Name => 'CustomFunctions400D',
+            Condition => '$$self{CameraModel} =~ /\b(400D|REBEL XTi|Kiss Digital X|K236)\b/',
+            SubDirectory => {
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+                TagTable => 'Image::ExifTool::CanonCustom::Functions400D',
+            },
+        },
+        {
+            Name => 'CustomFunctionsD30',
+            Condition => '$$self{CameraModel} =~ /EOS D30\b/',
+            SubDirectory => {
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+                TagTable => 'Image::ExifTool::CanonCustom::FunctionsD30',
+            },
+        },
+        {
+            Name => 'CustomFunctionsD60',
+            Condition => '$$self{CameraModel} =~ /EOS D60\b/',
+            SubDirectory => {
+                # the stored size in the D60 apparently doesn't include the size word:
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size-2,$size)',
+                # (D60 custom functions are basically the same as D30)
+                TagTable => 'Image::ExifTool::CanonCustom::FunctionsD30',
+            },
+        },
+        {
+            Name => 'CustomFunctionsUnknown',
+            SubDirectory => {
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+                TagTable => 'Image::ExifTool::CanonCustom::FuncsUnknown',
+            },
+        },
+    ],
+    0x10 => { #PH
+        Name => 'CanonModelID',
+        Writable => 'int32u',
+        PrintHex => 1,
+        SeparateTable => 1,
+        PrintConv => \%canonModelID,
+    },
+    0x12 => {
+        Name => 'CanonAFInfo',
+        # not really a condition -- just need to store the count for later
+        Condition => '$$self{AFInfoCount} = $count',
+        SubDirectory => {
+            # this record does not begin with a length word, so it
+            # has to be validated differently
+            Validate => 'Image::ExifTool::Canon::ValidateAFInfo($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::AFInfo',
+        },
+    },
+    # 0x13 - ('0 159 15 104' for widescreen image, '0 0 0 0' otherwise) - PH (A570IS)
+    0x15 => { #PH
+        # display format for serial number
+        Name => 'SerialNumberFormat',
+        Writable => 'int32u',
+        PrintHex => 1,
+        PrintConv => {
+            0x90000000 => 'Format 1',
+            0xa0000000 => 'Format 2',
+        },
+    },
+    0x1c => { #PH (A570IS)
+        Name => 'DateStampMode',
+        Writable => 'int16u',
+        Notes => 'only used in postcard mode',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Date',
+            2 => 'Date & Time',
+        },
+    },
+    0x1d => { #PH
+        Name => 'MyColors',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::MyColors',
+        },
+    },
+    0x1e => { #PH
+        Name => 'FirmwareRevision',
+        Writable => 'int32u',
+        # as a hex number: 0xAVVVRR00, where (a bit of guessing here...)
+        #  A = 'a' for alpha, 'b' for beta?
+        #  V = version? (100,101 for normal releases, 100,110,120,130,170 for alpha/beta)
+        #  R = revision? (01-07, except 00 for alpha/beta releases)
+        PrintConv => q{
+            my $rev = sprintf("%.8x", $val);
+            my ($rel, $v1, $v2, $r1, $r2) = ($rev =~ /^(.)(.)(..)0?(.+)(..)$/);
+            my %r = ( a => 'Alpha ', b => 'Beta ', '0' => '' );
+            $rel = defined $r{$rel} ? $r{$rel} : "Unknown($rel) ";
+            return "$rel$v1.$v2 rev $r1.$r2",
+        },
+        PrintConvInv => q{
+            $_=$val; s/Alpha ?/a/i; s/Beta ?/b/i;
+            s/Unknown ?\((.)\)/$1/i; s/ ?rev ?(.)\./0$1/; s/ ?rev ?//;
+            tr/a-fA-F0-9//dc; return hex $_;
+        },
+    },
+    # 0x1f - used for red-eye-corrected images - PH (A570IS)
+    # 0x22 - values 1 and 2 are 2 and 1 for flash pics, 0 otherwise - PH (A570IS)
+    0x24 => { #PH
+        Name => 'FaceDetect1',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::FaceDetect1',
+        },
+    },
+    0x25 => { #PH
+        Name => 'FaceDetect2',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::FaceDetect2',
+        },
+    },
+    0x26 => { #PH (A570IS,1DmkIII)
+        Name => 'CanonAFInfo2',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::AFInfo2',
+        },
+    },
+    # 0x27 - value 1 is 1 for high ISO pictures, 0 otherwise
+    0x83 => { #PH
+        Name => 'OriginalDecisionData',
+        Writable => 'int32u',
+    },
+    0x90 => {   # used by 1D and 1Ds
+        Name => 'CustomFunctions1D',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::CanonCustom::Functions1D',
+        },
+    },
+    0x91 => { #PH
+        Name => 'PersonalFunctions',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::CanonCustom::PersonalFuncs',
+        },
+    },
+    0x92 => { #PH
+        Name => 'PersonalFunctionValues',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::CanonCustom::PersonalFuncValues',
+        },
+    },
+    0x93 => {
+        Name => 'CanonFileInfo',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::FileInfo',
+        },
+    },
+    0x94 => { #PH
+        # AF points for 1D (45 points in 5 rows)
+        Name => 'AFPointsInFocus1D',
+        Notes => 'EOS 1D -- 5 rows: A1-7, B1-10, C1-11, D1-10, E1-7, center point is C6',
+        PrintConv => 'Image::ExifTool::Canon::PrintAFPoints1D($val)',
+    },
+    0x95 => { #PH (observed in 5D sample image)
+        Name => 'LensType',
+        Writable => 'string',
+    },
+    0x96 => { #PH
+        Name => 'InternalSerialNumber',
+        Writable => 'string',
+    },
+    0x97 => { #PH
+        Name => 'DustRemovalData',
+        # some interesting stuff is stored in here, like LensType and InternalSerialNumber...
+        Binary => 1,
+    },
+    0x99 => { #PH (EOS 1D Mark III, 40D, etc)
+        Name => 'CustomFunctions2',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::CanonCustom::Functions2',
+        },
+    },
+    # 0x9a - 5 numbers, the 2nd and 3rd are imagewidth/height (EOS 1DmkIII and 40D)
+    0xa0 => {
+        Name => 'ProccessingInfo',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::Processing',
+        },
+    },
+    0xa1 => { Name => 'ToneCurveTable', %longBin }, #PH
+    0xa2 => { Name => 'SharpnessTable', %longBin }, #PH
+    0xa3 => { Name => 'SharpnessFreqTable', %longBin }, #PH
+    0xa4 => { Name => 'WhiteBalanceTable', %longBin }, #PH
+    0xa9 => {
+        Name => 'ColorBalance',
+        SubDirectory => {
+            # this offset is necessary because the table is interpreted as short rationals
+            # (4 bytes long) but the first entry is 2 bytes into the table.
+            Start => '$valuePtr + 2',
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart-2,$size+2)',
+            TagTable => 'Image::ExifTool::Canon::ColorBalance',
+        },
+    },
+    # 0xaa - looks like maybe measured color balance (inverse of RGGBLevels)? - PH
+    0xae => {
+        Name => 'ColorTemperature',
+        Writable => 'int16u',
+    },
+    0xb0 => { #PH
+        Name => 'CanonFlags',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::Flags',
+        },
+    },
+    0xb1 => { #PH
+        Name => 'ModifiedInfo',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::ModifiedInfo',
+        },
+    },
+    0xb2 => { Name => 'ToneCurveMatching', %longBin }, #PH
+    0xb3 => { Name => 'WhiteBalanceMatching', %longBin }, #PH
+    0xb4 => { #PH
+        Name => 'ColorSpace',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'sRGB',
+            2 => 'Adobe RGB',
+        },
+    },
+    0xb6 => {
+        Name => 'PreviewImageInfo',
+        SubDirectory => {
+            # Note: first word if this block is the total number of words, not bytes!
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size/2)',
+            TagTable => 'Image::ExifTool::Canon::PreviewImageInfo',
+        },
+    },
+    0xd0 => { #PH
+        Name => 'VRDOffset',
+        Writable => 'int32u',
+        OffsetPair => 1, # (just used as a flag, since this tag has no pair)
+        Protected => 2,
+        DataTag => 'CanonVRD',
+        Notes => 'offset of VRD "recipe data" if it exists',
+    },
+    0xe0 => { #12
+        Name => 'SensorInfo',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::SensorInfo',
+        },
+    },
+    0x4001 => [ #13
+        {   # (int16u[582]) - 20D and 350D
+            Condition => '$count == 582',
+            Name => 'ColorBalance1',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Canon::ColorBalance1',
+            },
+        },
+        {   # (int16u[653]) - 1DmkII and 1DSmkII
+            Condition => '$count == 653',
+            Name => 'ColorBalance2',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Canon::ColorBalance2',
+            },
+        },
+        {   # (int16u[796]) - 1DmkIIN, 5D, 30D, 400D
+            Condition => '$count == 796',
+            Name => 'ColorBalance3',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Canon::ColorBalance3',
+            },
+        },
+        {
+            Name => 'ColorBalanceUnknown',
+            %longBin,
+        },
+    ],
+    0x4002 => { #PH
+        # unknown data block in some JPEG and CR2 images
+        # (5kB for most models, but 22kb for 5D and 30D)
+        Name => 'UnknownBlock1',
+        Format => 'undef',
+        Flags => [ 'Unknown', 'Binary' ],
+    },
+    0x4003 => { #PH
+        Name => 'ColorInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::ColorInfo',
+        },
+    },
+    0x4005 => { #PH
+        Name => 'UnknownBlock2',
+        Notes => 'unknown 49kB block, not copied to JPEG images',
+        # 'Drop' because not found in JPEG images (too large for APP1 anyway)
+        Flags => [ 'Unknown', 'Binary', 'Drop' ],
+    },
+    0x4008 => { #PH guess (1DmkIII)
+        Name => 'BlackLevel',
+        Unknown => 1,
+    },
+);
+
+#..............................................................................
+# Canon camera settings (MakerNotes tag 0x01)
+# BinaryData (keys are indices into the int16s array)
+%Image::ExifTool::Canon::CameraSettings = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 1,
+    DATAMEMBER => [ 25 ],   # FocalUnits necessary for writing
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    1 => {
+        Name => 'MacroMode',
+        PrintConv => {
+            1 => 'Macro',
+            2 => 'Normal',
+        },
+    },
+    2 => {
+        Name => 'Self-timer',
+        # Custom timer mode if bit 0x4000 is set - PH (A570IS)
+        PrintConv => q{
+            return 'Off' unless $val;
+            return (($val&0xfff) / 10) . ' sec' . ($val & 0x4000 ? ', Custom' : '');
+        },
+        PrintConvInv => q{
+            return 0 if $val =~ /^Off/i;
+            $val =~ s/\s*sec$//i;
+            $val =~ s/,?\s*Custom$//i ? ($val*10) | 0x4000 : $val*10;
+        },
+    },
+    3 => {
+        Name => 'Quality',
+        PrintConv => \%canonQuality,
+    },
+    4 => {
+        Name => 'CanonFlashMode',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'On',
+            3 => 'Red-eye reduction',
+            4 => 'Slow-sync',
+            5 => 'Red-eye reduction (Auto)',
+            6 => 'Red-eye reduction (On)',
+            16 => 'External flash', # not set in D30 or 300D
+        },
+    },
+    5 => {
+        Name => 'ContinuousDrive',
+        PrintConv => {
+            0 => 'Single',
+            1 => 'Continuous',
+            2 => 'Movie', #PH
+            3 => 'Continuous, Speed Priority', #PH
+            4 => 'Continuous, Low', #PH
+            5 => 'Continuous, High', #PH
+        },
+    },
+    7 => {
+        Name => 'FocusMode',
+        PrintConv => {
+            0 => 'One-shot AF',
+            1 => 'AI Servo AF',
+            2 => 'AI Focus AF',
+            3 => 'Manual Focus',
+            4 => 'Single',
+            5 => 'Continuous',
+            6 => 'Manual Focus',
+           16 => 'Pan Focus', #PH
+        },
+    },
+    9 => { #PH
+        Name => 'RecordMode',
+        PrintConv => {
+            1 => 'JPEG',
+            2 => 'CRW+THM', # (300D,etc)
+            3 => 'AVI+THM', # (30D)
+            4 => 'TIF', # +THM? (1Ds) (unconfirmed)
+            5 => 'TIF+JPEG', # (1D) (unconfirmed)
+            6 => 'CR2', # +THM? (1D,30D,350D)
+            7 => 'CR2+JPEG', # (S30)
+        },
+    },
+    10 => {
+        Name => 'CanonImageSize',
+        PrintConv => \%canonImageSize,
+    },
+    11 => {
+        Name => 'EasyMode',
+        PrintConv => {
+            0 => 'Full auto',
+            1 => 'Manual',
+            2 => 'Landscape',
+            3 => 'Fast shutter',
+            4 => 'Slow shutter',
+            5 => 'Night',
+            6 => 'Gray Scale', #PH
+            7 => 'Sepia',
+            8 => 'Portrait',
+            9 => 'Sports',
+            10 => 'Macro',
+            11 => 'Black & White', #PH
+            12 => 'Pan focus',
+            13 => 'Vivid', #PH
+            14 => 'Neutral', #PH
+            15 => 'Flash Off',  #8
+            16 => 'Long Shutter', #PH
+            17 => 'Super Macro', #PH
+            18 => 'Foliage', #PH
+            19 => 'Indoor', #PH
+            20 => 'Fireworks', #PH
+            21 => 'Beach', #PH
+            22 => 'Underwater', #PH
+            23 => 'Snow', #PH
+            24 => 'Kids & Pets', #PH
+            25 => 'Night Snapshot', #PH
+            26 => 'Digital Macro', #PH
+            27 => 'My Colors', #PH
+            28 => 'Still Image', #15 (animation frame?)
+            30 => 'Color Accent', #18
+            31 => 'Color Swap', #18
+            32 => 'Aquarium', #18
+            33 => 'ISO 3200', #18
+        },
+    },
+    12 => {
+        Name => 'DigitalZoom',
+        PrintConv => {
+            0 => 'None',
+            1 => '2x',
+            2 => '4x',
+            3 => 'Other',  # value obtained from 2*#37/#36
+        },
+    },
+    13 => {
+        Name => 'Contrast',
+        RawConv => '$val == 0x7fff ? undef : $val',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    14 => {
+        Name => 'Saturation',
+        RawConv => '$val == 0x7fff ? undef : $val',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    15 => {
+        Name => 'Sharpness',
+        RawConv => '$val == 0x7fff ? undef : $val',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    16 => {
+        Name => 'CameraISO',
+        RawConv => '$val != 0x7fff ? $val : undef',
+        ValueConv => 'Image::ExifTool::Canon::CameraISO($val)',
+        ValueConvInv => 'Image::ExifTool::Canon::CameraISO($val,1)',
+    },
+    17 => {
+        Name => 'MeteringMode',
+        PrintConv => {
+            0 => 'Default', # older Ixus
+            1 => 'Spot',
+            2 => 'Average', #PH
+            3 => 'Evaluative',
+            4 => 'Partial',
+            5 => 'Center-weighted averaging',
+        },
+    },
+    18 => {
+        # this is always 2 for the 300D - PH
+        Name => 'FocusRange',
+        PrintConv => {
+            0 => 'Manual',
+            1 => 'Auto',
+            2 => 'Not Known',
+            3 => 'Macro',
+            4 => 'Very Close', #PH
+            5 => 'Close', #PH
+            6 => 'Middle Range', #PH
+            7 => 'Far Range',
+            8 => 'Pan Focus',
+            9 => 'Super Macro', #PH
+            10=> 'Infinity', #PH
+        },
+    },
+    19 => {
+        Name => 'AFPoint',
+        Flags => 'PrintHex',
+        RawConv => '$val==0 ? undef : $val',
+        PrintConv => {
+            0x2005 => 'Manual AF point selection',
+            0x3000 => 'None (MF)',
+            0x3001 => 'Auto AF point selection',
+            0x3002 => 'Right',
+            0x3003 => 'Center',
+            0x3004 => 'Left',
+            0x4001 => 'Auto AF point selection',
+            0x4006 => 'Face Detect', #PH (A570IS)
+        },
+    },
+    20 => {
+        Name => 'CanonExposureMode',
+        PrintConv => {
+            0 => 'Easy',
+            1 => 'Program AE',
+            2 => 'Shutter speed priority AE',
+            3 => 'Aperture-priority AE',
+            4 => 'Manual',
+            5 => 'Depth-of-field AE',
+            6 => 'M-Dep', #PH
+        },
+    },
+    22 => { #4
+        Name => 'LensType',
+        RawConv => '$val ? $val : undef', # don't use if value is zero
+        SeparateTable => 1,
+        PrintConv => \%canonLensTypes,
+    },
+    23 => {
+        Name => 'LongFocal',
+        Format => 'int16u',
+        # this is a bit tricky, but we need the FocalUnits to convert this to mm
+        RawConvInv => '$val * ($$self{FocalUnits} || 1)',
+        ValueConv => '$val / ($$self{FocalUnits} || 1)',
+        ValueConvInv => '$val',
+        PrintConv => '"${val}mm"',
+        PrintConvInv => '$val=~s/mm//;$val',
+    },
+    24 => {
+        Name => 'ShortFocal',
+        Format => 'int16u',
+        RawConvInv => '$val * ($$self{FocalUnits} || 1)',
+        ValueConv => '$val / ($$self{FocalUnits} || 1)',
+        ValueConvInv => '$val',
+        PrintConv => '"${val}mm"',
+        PrintConvInv => '$val=~s/mm//;$val',
+    },
+    25 => {
+        Name => 'FocalUnits',
+        DataMember => 'FocalUnits',
+        RawConv => '$$self{FocalUnits} = $val',
+    },
+    26 => { #9
+        Name => 'MaxAperture',
+        RawConv => '$val > 0 ? $val : undef',
+        ValueConv => 'exp(Image::ExifTool::Canon::CanonEv($val)*log(2)/2)',
+        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(log($val)*2/log(2))',
+        PrintConv => 'sprintf("%.2g",$val)',
+        PrintConvInv => '$val',
+    },
+    27 => { #PH
+        Name => 'MinAperture',
+        RawConv => '$val > 0 ? $val : undef',
+        ValueConv => 'exp(Image::ExifTool::Canon::CanonEv($val)*log(2)/2)',
+        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(log($val)*2/log(2))',
+        PrintConv => 'sprintf("%.2g",$val)',
+        PrintConvInv => '$val',
+    },
+    28 => {
+        Name => 'FlashActivity',
+        RawConv => '$val==-1 ? undef : $val',
+    },
+    29 => {
+        Name => 'FlashBits',
+        PrintConv => { BITMASK => {
+            0 => 'Manual', #PH
+            1 => 'TTL', #PH
+            2 => 'A-TTL', #PH
+            3 => 'E-TTL', #PH
+            4 => 'FP sync enabled',
+            7 => '2nd-curtain sync used',
+            11 => 'FP sync used',
+            13 => 'Built-in',
+            14 => 'External',
+        } },
+    },
+    32 => {
+        Name => 'FocusContinuous',
+        RawConv => '$val==-1 ? undef : $val',
+        PrintConv => {
+            0 => 'Single',
+            1 => 'Continuous',
+        },
+    },
+    33 => { #PH
+        Name => 'AESetting',
+        RawConv => '$val==-1 ? undef : $val',
+        PrintConv => {
+            0 => 'Normal AE',
+            1 => 'Exposure Compensation',
+            2 => 'AE Lock',
+            3 => 'AE Lock + Exposure Comp.',
+            4 => 'No AE',
+        },
+    },
+    34 => { #PH
+        Name => 'ImageStabilization',
+        RawConv => '$val==-1 ? undef : $val',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On, Shot Only', #15
+            3 => 'On, Panning', #PH (A570IS)
+        },
+    },
+    35 => { #PH
+        Name => 'DisplayAperture',
+        RawConv => '$val ? $val : undef',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+    },
+    36 => 'ZoomSourceWidth', #PH
+    37 => 'ZoomTargetWidth', #PH
+    40 => { #PH
+        Name => 'PhotoEffect',
+        RawConv => '$val==-1 ? undef : $val',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Vivid',
+            2 => 'Neutral',
+            3 => 'Smooth',
+            4 => 'Sepia',
+            5 => 'B&W',
+            6 => 'Custom',
+            100 => 'My Color Data',
+        },
+    },
+    41 => { #PH (A570IS)
+        Name => 'ManualFlashOutput',
+        PrintHex => 1,
+        PrintConv => {
+            0 => 'n/a',
+            0x500 => 'Full',
+            0x502 => 'Medium',
+            0x504 => 'Low',
+            0x7fff => 'n/a', # (EOS models)
+        },
+    },
+    # 41 => non-zero for manual flash intensity - PH (A570IS)
+    42 => {
+        Name => 'ColorTone',
+        RawConv => '$val == 0x7fff ? undef : $val',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+);
+
+# focal length information (MakerNotes tag 0x02)
+%Image::ExifTool::Canon::FocalLength = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0 => { #9
+        Name => 'FocalType',
+        RawConv => '$val ? $val : undef', # don't use if value is zero
+	    PrintConv => {
+            1 => 'Fixed',
+            2 => 'Zoom',
+        },
+    },
+    1 => {
+        Name => 'FocalLength',
+        # the EXIF FocalLength is more reliable, so set this priority to zero
+        Priority => 0,
+        RawConv => '$val ? $val : undef', # don't use if value is zero
+        RawConvInv => q{
+            my $focalUnits = $$self{FocalUnits};
+            unless ($focalUnits) {
+                $focalUnits = 1;
+                # (this happens when writing FocalLength to CRW images)
+                $self->Warn("FocalUnits not available for FocalLength conversion (1 assumed)");
+            }
+            return $val * $focalUnits;
+        },
+        ValueConv => '$val / ($$self{FocalUnits} || 1)',
+        ValueConvInv => '$val',
+        PrintConv => '"${val}mm"',
+        PrintConvInv => '$val=~s/mm//;$val',
+    },
+    2 => { #4
+        Name => 'FocalPlaneXSize',
+        Notes => 'not valid for 1DmkIII',
+        Condition => '$$self{CameraModel} !~ /1D Mark III/',
+        # focal plane image dimensions in 1/1000 inch -- convert to mm
+        RawConv => '$val < 40 ? undef : $val',  # must be reasonable
+        ValueConv => '$val * 25.4 / 1000',
+        ValueConvInv => 'int($val * 1000 / 25.4 + 0.5)',
+        PrintConv => 'sprintf("%.2fmm",$val)',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
+    },
+    3 => {
+        Name => 'FocalPlaneYSize',
+        Notes => 'not valid for 1DmkIII',
+        Condition => '$$self{CameraModel} !~ /1D Mark III/',
+        RawConv => '$val < 40 ? undef : $val',  # must be reasonable
+        ValueConv => '$val * 25.4 / 1000',
+        ValueConvInv => 'int($val * 1000 / 25.4 + 0.5)',
+        PrintConv => 'sprintf("%.2fmm",$val)',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
+    },
+);
+
+# Canon shot information (MakerNotes tag 0x04)
+# BinaryData (keys are indices into the int16s array)
+%Image::ExifTool::Canon::ShotInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    1 => { #PH
+        Name => 'AutoISO',
+        Notes => 'actual ISO used = BaseISO * AutoISO / 100',
+        ValueConv => 'exp($val/32*log(2))*100',
+        ValueConvInv => '32*log($val/100)/log(2)',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    2 => {
+        Name => 'BaseISO',
+        Priority => 0,
+        RawConv => '$val ? $val : undef',
+        ValueConv => 'exp($val/32*log(2))*100/32',
+        ValueConvInv => '32*log($val*32/100)/log(2)',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    3 => { #9/PH
+        Name => 'MeasuredEV',
+        Notes => q{
+            this the Canon name for what should properly be called MeasuredLV, and is
+            offset by about -5 EV from the calculated LV for most models
+        },
+        ValueConv => '$val / 32',
+        ValueConvInv => '$val * 32',
+        PrintConv => 'sprintf("%.2f",$val)',
+        PrintConvInv => '$val',
+    },
+    4 => { #2, 9
+        Name => 'TargetAperture',
+        RawConv => '$val > 0 ? $val : undef',
+        ValueConv => 'exp(Image::ExifTool::Canon::CanonEv($val)*log(2)/2)',
+        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(log($val)*2/log(2))',
+        PrintConv => 'sprintf("%.2g",$val)',
+        PrintConvInv => '$val',
+    },
+    5 => { #2
+        Name => 'TargetExposureTime',
+        RawConv => '$val > 0 ? $val : undef',
+        ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val)*log(2))',
+        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val)/log(2))',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    6 => {
+        Name => 'ExposureCompensation',
+        ValueConv => 'Image::ExifTool::Canon::CanonEv($val)',
+        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv($val)',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => 'eval $val',
+    },
+    7 => {
+        Name => 'WhiteBalance',
+        PrintConv => \%canonWhiteBalance,
+    },
+    8 => { #PH
+        Name => 'SlowShutter',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Night Scene',
+            2 => 'On',
+            3 => 'None',
+        },
+    },
+    9 => {
+        Name => 'SequenceNumber',
+        Description => 'Shot Number In Continuous Burst',
+    },
+    10 => { #PH/17
+        Name => 'OpticalZoomCode',
+        Groups => { 2 => 'Camera' },
+        Notes => 'for many PowerShot models, a this is 0-6 for wide-tele zoom',
+        # (for many models, 0-6 represent 0-100% zoom, but it is always 8 for
+        #  EOS models, and I have seen values of 16,20,28,32 and 39 too...)
+    },
+    # 11 - (8 for all EOS samples, [0,8] for other models - PH)
+    13 => { #PH
+        Name => 'FlashGuideNumber',
+        RawConv => '$val == -1 ? undef : $val',
+        ValueConv => '$val / 32',
+        ValueConvInv => '$val * 32',
+    },
+    # AF points for Ixus and IxusV cameras - 02/17/04 M. Rommel (also D30/D60 - PH)
+    14 => { #2
+        Name => 'AFPointsInFocus',
+        Notes => 'used by D30, D60 and some PowerShot/Ixus models',
+        Groups => { 2 => 'Camera' },
+        Flags => 'PrintHex',
+        RawConv => '$val==0 ? undef : $val',
+        PrintConv => {
+            0x3000 => 'None (MF)',
+            0x3001 => 'Right',
+            0x3002 => 'Center',
+            0x3003 => 'Center+Right',
+            0x3004 => 'Left',
+            0x3005 => 'Left+Right',
+            0x3006 => 'Left+Center',
+            0x3007 => 'All',
+        },
+    },
+    15 => {
+        Name => 'FlashExposureComp',
+        Description => 'Flash Exposure Compensation',
+        ValueConv => 'Image::ExifTool::Canon::CanonEv($val)',
+        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv($val)',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => 'eval $val',
+    },
+    16 => {
+        Name => 'AutoExposureBracketing',
+        PrintConv => {
+            -1 => 'On',
+            0 => 'Off',
+            1 => 'On (shot 1)',
+            2 => 'On (shot 2)',
+            3 => 'On (shot 3)',
+        },
+    },
+    17 => {
+        Name => 'AEBBracketValue',
+        ValueConv => 'Image::ExifTool::Canon::CanonEv($val)',
+        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv($val)',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => 'eval $val',
+    },
+    19 => {
+        Name => 'FocusDistanceUpper',
+        ValueConv => '$val * 0.01',
+        ValueConvInv => '$val / 0.01',
+    },
+    20 => {
+        Name => 'FocusDistanceLower',
+        ValueConv => '$val * 0.01',
+        ValueConvInv => '$val / 0.01',
+    },
+    21 => {
+        Name => 'FNumber',
+        Priority => 0,
+        RawConv => '$val ? $val : undef',
+        # approximate big translation table by simple calculation - PH
+        ValueConv => 'exp(Image::ExifTool::Canon::CanonEv($val)*log(2)/2)',
+        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(log($val)*2/log(2))',
+        PrintConv => 'sprintf("%.2g",$val)',
+        PrintConvInv => '$val',
+    },
+    22 => [
+        {
+            Name => 'ExposureTime',
+            # encoding is different for 20D and 350D (darn!)
+            # (but note that encoding is the same for TargetExposureTime - PH)
+            Condition => '$$self{CameraModel} =~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/',
+            Priority => 0,
+            RawConv => '$val ? $val : undef',
+            # approximate big translation table by simple calculation - PH
+            ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val)*log(2))*1000/32',
+            ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val*32/1000)/log(2))',
+            PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+            PrintConvInv => 'eval $val',
+        },
+        {
+            Name => 'ExposureTime',
+            Priority => 0,
+            RawConv => '$val ? $val : undef',
+            # approximate big translation table by simple calculation - PH
+            ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val)*log(2))',
+            ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val)/log(2))',
+            PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+            PrintConvInv => 'eval $val',
+        },
+    ],
+    24 => {
+        Name => 'BulbDuration',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+    },
+    # 25 - (usually 0, but 1 for 2s timer?, 19 for small AVI, 14 for large
+    #       AVI, and -6 and -10 for shots 1 and 2 with stitch assist - PH)
+    26 => { #15
+        Name => 'CameraType',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            248 => 'EOS High-end',
+            250 => 'Compact',
+            252 => 'EOS Mid-range',
+            255 => 'DV Camera', #PH
+        },
+    },
+    27 => {
+        Name => 'AutoRotate',
+        PrintConv => {
+           -1 => 'Rotated by Software',
+            0 => 'None',
+            1 => 'Rotate 90 CW',
+            2 => 'Rotate 180',
+            3 => 'Rotate 270 CW',
+        },
+    },
+    28 => { #15
+        Name => 'NDFilter',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    29 => {
+        Name => 'Self-timer2',
+        RawConv => '$val >= 0 ? $val : undef',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+    },
+    33 => { #PH (A570IS)
+        Name => 'FlashOutput',
+        Notes => 'this has a maximum value of 500 for models like the A570IS',
+    },
+);
+
+# Canon camera information (MakerNotes tag 0x0d)
+# (ref 12 unless otherwise noted)
+%Image::ExifTool::Canon::CameraInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int8s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        Information in the "CameraInfo" records is tricky to decode because the
+        encodings are very different than in other Canon records (even sometimes
+        switching endianness between values within a single camera), plus there is
+        considerable variation in format from model to model. The table below is
+        common to the 1D, 1DS, 1DmkII, 1DSmkII and 5D, but individual tags may not
+        be valid for all these models.
+    },
+    0x03 => { #PH
+        Name => 'FNumber',
+        Groups => { 2 => 'Image' },
+        Condition => '$$self{CameraModel} =~ /EOS 5D/',
+        Format => 'int8u',
+        Notes => '5D only',
+        Priority => 0,
+        RawConv => '$val ? $val : undef',
+        ValueConv => 'exp(($val-8)/16*log(2))',
+        ValueConvInv => 'log($val)*16/log(2)+8',
+        PrintConv => 'sprintf("%.2g",$val)',
+        PrintConvInv => '$val',
+    },
+    0x04 => { #9
+        Name => 'ExposureTime',
+        Groups => { 2 => 'Image' },
+        Format => 'int8u',
+        Priority => 0,
+        RawConv => '$val ? $val : undef',
+        ValueConv => 'exp(4*log(2)*(1-Image::ExifTool::Canon::CanonEv($val-24)))',
+        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(1-log($val)/(4*log(2)))+24',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x06 => { #PH
+        Name => 'ISO',
+        Groups => { 2 => 'Image' },
+        Condition => '$$self{CameraModel} =~ /EOS 5D/',
+        Format => 'int8u',
+        Notes => '5D only',
+        Priority => 0,
+        ValueConv => '100*exp(($val/8-9)*log(2))',
+        ValueConvInv => '(log($val/100)/log(2)+9)*8',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x09 => { #9
+        Name => 'FocalLength',
+        Format => 'int16u',
+        Condition => '$$self{CameraModel} =~ /\b1Ds? Mark II\b/',
+        Notes => '1DmkII and 1DsMkII only',
+        # the EXIF FocalLength is more reliable, so set this priority to zero
+        Priority => 0,
+        # ignore if zero and change to big-endian
+        RawConv => '$val ? unpack("n",pack("v",$val)) : undef',
+        PrintConv => '"${val}mm"',
+        PrintConvInv => '$val=~s/mm//;$val',
+    },
+    0x0d => { #9
+        Name => 'LensType',
+        Format => 'int8u',
+        SeparateTable => 1,
+        RawConv => '$val ? $val : undef', # don't use if value is zero
+        PrintConv => \%canonLensTypes,
+    },
+    0x11 => { #9
+        Name => 'ShortFocal',
+        Format => 'int16u',
+        Condition => '$$self{CameraModel} =~ /\b1Ds? Mark II\b/',
+        Notes => '1DmkII and 1DsMkII only',
+        # the EXIF ShortFocal is more reliable, so set this priority to zero
+        Priority => 0,
+        ValueConv => 'unpack("n",pack("v",$val))',
+        ValueConvInv => 'unpack("v",pack("n",$val))',
+        PrintConv => '"${val}mm"',
+        PrintConvInv => '$val=~s/mm//;$val',
+    },
+    0x13 => { #9
+        Name => 'LongFocal',
+        Format => 'int16u',
+        Condition => '$$self{CameraModel} =~ /\b1Ds? Mark II\b/',
+        Notes => '1DmkII and 1DsMkII only',
+        # the EXIF LongFocal is more reliable, so set this priority to zero
+        Priority => 0,
+        ValueConv => 'unpack("n",pack("v",$val))',
+        ValueConvInv => 'unpack("v",pack("n",$val))',
+        PrintConv => '"${val}mm"',
+        PrintConvInv => '$val=~s/mm//;$val',
+    },
+    0x2d => { #9
+        Name => 'FocalType',
+        Format => 'int8u',
+        Condition => '$$self{CameraModel} =~ /\b1Ds? Mark II\b/',
+        Notes => '1DmkII and 1DSmkII only',
+        Priority => 0,
+        PrintConv => {
+           0 => 'Fixed',
+           2 => 'Zoom',
+        },
+    },
+    0x38 => {
+        Name => 'AFPointsInFocus5D',
+        Format => 'undef[2]',
+        Condition => '$$self{CameraModel} =~ /EOS 5D/',
+        Notes => 'EOS 5D, bit definitions are for big-endian int16u',
+        ValueConv => 'unpack("n",$val)',
+        ValueConvInv => 'pack("n",$val)',
+        PrintConv => { BITMASK => {
+            0 => 'Center',
+            1 => 'Top',
+            2 => 'Bottom',
+            3 => 'Upper-left',
+            4 => 'Upper-right',
+            5 => 'Lower-left',
+            6 => 'Lower-right',
+            7 => 'Left',
+            8 => 'Right',
+            9 => 'AI Servo1',
+           10 => 'AI Servo2',
+           11 => 'AI Servo3',
+           12 => 'AI Servo4',
+           13 => 'AI Servo5',
+           14 => 'AI Servo6',
+        } },
+    },
+    0x6c => {
+        Name => 'PictureStyle',
+        Format => 'int16u',
+        Condition => '$$self{CameraModel} =~ /EOS(-1Ds? Mark II| 5D)$/',
+        Notes => '1DmkII, 1DSmkII and 5D only',
+        PrintHex => 1,
+        PrintConv => \%pictureStyles,
+    },
+    0xa4 => { #PH (5D)
+        Name => 'FirmwareRevision',
+        Condition => '$$self{CameraModel} =~ /EOS 5D/',
+        Notes => '5D only',
+        Format => 'string[8]',
+    },
+    0xac => { #PH (5D)
+        Name => 'ShortOwnerName',
+        Format => 'string[16]',
+        Condition => '$$self{CameraModel} =~ /EOS 5D/',
+        Notes => '5D only',
+    },
+    0xd0 => {
+        Name => 'ImageNumber',
+        Groups => { 2 => 'Image' },
+        Format => 'int16u',
+        Condition => '$$self{CameraModel} =~ /EOS 5D/',
+        Notes => '5D only',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0xe8 => {
+        Name => 'ContrastStandard',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    0xe9 => {
+        Name => 'ContrastPortrait',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    0xea => {
+        Name => 'ContrastLandscape',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    0xeb => {
+        Name => 'ContrastNeutral',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    0xec => {
+        Name => 'ContrastFaithful',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    0xed => {
+        Name => 'ContrastMonochrome',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    0xee => {
+        Name => 'ContrastUserDef1',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    0xef => {
+        Name => 'ContrastUserDef2',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    0xf0 => {
+        Name => 'ContrastUserDef3',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    # sharpness values are 0-7
+    0xf1 => 'SharpnessStandard',
+    0xf2 => 'SharpnessPortrait',
+    0xf3 => 'SharpnessLandscape',
+    0xf4 => 'SharpnessNeutral',
+    0xf5 => 'SharpnessFaithful',
+    0xf6 => 'SharpnessMonochrome',
+    0xf7 => 'SharpnessUserDef1',
+    0xf8 => 'SharpnessUserDef2',
+    0xf9 => 'SharpnessUserDef3',
+    0xfa => 'SaturationStandard',
+    0xfb => 'SaturationPortrait',
+    0xfc => 'SaturationLandscape',
+    0xfd => 'SaturationNeutral',
+    0xfe => 'SaturationFaithful',
+    0xff => {
+        Name => 'FilterEffectMonochrome',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Yellow',
+            2 => 'Orange',
+            3 => 'Red',
+            4 => 'Green',
+        },
+    },
+    0x100 => 'SaturationUserDef1',
+    0x101 => 'SaturationUserDef2',
+    0x102 => 'SaturationUserDef3',
+    0x103 => 'ColorToneStandard',
+    0x104 => 'ColorTonePortrait',
+    0x105 => 'ColorToneLandscape',
+    0x106 => 'ColorToneNeutral',
+    0x107 => 'ColorToneFaithful',
+    0x108 => {
+        Name => 'ToningEffectMonochrome',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Sepia',
+            2 => 'Blue',
+            3 => 'Purple',
+            4 => 'Green',
+        },
+    },
+    0x109 => 'ColorToneUserDef1',
+    0x10a => 'ColorToneUserDef2',
+    0x10b => 'ColorToneUserDef3',
+    0x10c => {
+        Name => 'UserDef1PictureStyle',
+        Format => 'int16u',
+        PrintHex => 1,
+        PrintConv => \%userDefStyles,
+    },
+    0x10e => {
+        Name => 'UserDef2PictureStyle',
+        Format => 'int16u',
+        PrintHex => 1,
+        PrintConv => \%userDefStyles,
+    },
+    0x110 => {
+        Name => 'UserDef3PictureStyle',
+        Format => 'int16u',
+        PrintHex => 1,
+        PrintConv => \%userDefStyles,
+    },
+    0x11c => {
+        Name => 'TimeStamp',
+        Format => 'int32u',
+        Groups => { 2 => 'Time' },
+        Shift => 'Time',
+        RawConv => '$val ? $val : undef',
+        ValueConv => 'ConvertUnixTime($val)',
+        ValueConvInv => 'GetUnixTime($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$val',
+    },
+);
+
+# Canon camera information for 1DmkIII (MakerNotes tag 0x0d) - PH
+%Image::ExifTool::Canon::CameraInfo1DmkIII = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int8s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'CameraInfo tags valid for the EOS 1D Mark III.',
+    0x03 => {
+        Name => 'FNumber',
+        Groups => { 2 => 'Image' },
+        Format => 'int8u',
+        Priority => 0,
+        RawConv => '$val ? $val : undef',
+        ValueConv => 'exp(($val-8)/16*log(2))',
+        ValueConvInv => 'log($val)*16/log(2)+8',
+        PrintConv => 'sprintf("%.2g",$val)',
+        PrintConvInv => '$val',
+    },
+    0x04 => { #9
+        Name => 'ExposureTime',
+        Groups => { 2 => 'Image' },
+        Format => 'int8u',
+        Priority => 0,
+        RawConv => '$val ? $val : undef',
+        ValueConv => 'exp(4*log(2)*(1-Image::ExifTool::Canon::CanonEv($val-24)))',
+        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(1-log($val)/(4*log(2)))+24',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x06 => {
+        Name => 'ISO',
+        Groups => { 2 => 'Image' },
+        Format => 'int8u',
+        Priority => 0,
+        ValueConv => '100*exp(($val/8-9)*log(2))',
+        ValueConvInv => '(log($val/100)/log(2)+9)*8',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x1d => {
+        Name => 'FocalLength',
+        Format => 'int16u',
+        # the EXIF FocalLength is more reliable, so set this priority to zero
+        # (just to make things confusing, the focal lengths are big-endian,
+        #  while other values are stored little-endian)
+        Priority => 0,
+        # ignore if zero and change to big-endian
+        RawConv => '$val ? unpack("n",pack("v",$val)) : undef',
+        PrintConv => '"${val}mm"',
+        PrintConvInv => '$val=~s/mm//;$val',
+    },
+    0x86 => {
+        Name => 'PictureStyle',
+        Format => 'int8u',
+        PrintHex => 1,
+        PrintConv => \%pictureStyles,
+    },
+    0x113 => {
+        Name => 'ShortFocal',
+        Format => 'int16u',
+        # the EXIF ShortFocal is more reliable, so set this priority to zero
+        Priority => 0,
+        # byte order is big-endian
+        ValueConv => 'unpack("n",pack("v",$val))',
+        ValueConvInv => 'unpack("v",pack("n",$val))',
+        PrintConv => '"${val}mm"',
+        PrintConvInv => '$val=~s/mm//;$val',
+    },
+    0x115 => {
+        Name => 'LongFocal',
+        Format => 'int16u',
+        # the EXIF LongFocal is more reliable, so set this priority to zero
+        Priority => 0,
+        # byte order is big-endian
+        ValueConv => 'unpack("n",pack("v",$val))',
+        ValueConvInv => 'unpack("v",pack("n",$val))',
+        PrintConv => '"${val}mm"',
+        PrintConvInv => '$val=~s/mm//;$val',
+    },
+    0x172 => {
+        Name => 'FileNumber',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0x176 => {
+        Name => 'ShutterCount',
+        Notes => 'may be valid only for some 1DmkIII copies, even running the same firmware',
+        Format => 'int32u',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0x45e => {
+        Name => 'TimeStamp',
+        Format => 'int32u',
+        Groups => { 2 => 'Time' },
+        Shift => 'Time',
+        RawConv => '$val ? $val : undef',
+        ValueConv => 'ConvertUnixTime($val)',
+        ValueConvInv => 'GetUnixTime($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$val',
+    },
+);
+
+# type 2 Canon camera information (MakerNotes tag 0x0d) - PH
+%Image::ExifTool::Canon::CameraInfo2 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int32s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags used by a number of newer PowerShot models.',
+    0x00 => {
+        Name => 'ISO',
+        Groups => { 2 => 'Image' },
+        Priority => 0,
+        ValueConv => '100*exp(($val/100-4)*log(2))',
+        ValueConvInv => '(log($val/100)/log(2)+4)*100',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x05 => {
+        Name => 'FNumber',
+        Groups => { 2 => 'Image' },
+        Priority => 0,
+        ValueConv => 'exp(($val+16)/200*log(2))',
+        ValueConvInv => 'log($val)*200/log(2)-16',
+        PrintConv => 'sprintf("%.2g",$val)',
+        PrintConvInv => '$val',
+    },
+    0x06 => {
+        Name => 'ExposureTime',
+        Groups => { 2 => 'Image' },
+        Priority => 0,
+        RawConv => '$val ? $val : undef',
+        ValueConv => 'exp(-($val+24)/100*log(2))',
+        ValueConvInv => '-log($val)*100/log(2)-24',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x17 => 'Rotation', # usually the same as Orientation (but not always! why?)
+);
+
+# unknown Canon camera information (MakerNotes tag 0x0d) - PH
+%Image::ExifTool::Canon::CameraInfoUnknown32 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int32s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Unknown CameraInfo tags are divided into 3 tables based on format size.',
+);
+
+# unknown Canon camera information (MakerNotes tag 0x0d) - PH
+%Image::ExifTool::Canon::CameraInfoUnknown16 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+);
+
+# unknown Canon camera information (MakerNotes tag 0x0d) - PH
+%Image::ExifTool::Canon::CameraInfoUnknown8 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int8s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+);
+
+# Canon panorama information (MakerNotes tag 0x05)
+%Image::ExifTool::Canon::Panorama = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    2 => 'PanoramaFrame',
+    5 => {
+        Name => 'PanoramaDirection',
+        PrintConv => {
+            0 => 'Left to Right',
+            1 => 'Right to Left',
+            2 => 'Bottom to Top',
+            3 => 'Top to Bottom',
+            4 => '2x2 Matrix (Clockwise)',
+        },
+     },
+);
+
+# AF information (MakerNotes tag 0x12) - PH
+%Image::ExifTool::Canon::AFInfo = (
+    PROCESS_PROC => \&ProcessSerialData,
+    FORMAT => 'int16u',
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        Auto-focus information used by many older Canon models.  The values in this
+        record are sequential, and some have variable sizes based on the value of
+        NumAFPoints (which may be 1,5,7,9,15,45 or 53).  The AFArea coordinates are
+        given in a system where the image has dimensions given by AFImageWidth and
+        AFImageHeight, and 0,0 is the image center. The direction of the Y axis
+        depends on the camera model, with positive Y upwards for EOS models, but
+        apparently downwards for PowerShot models.
+    },
+    0 => {
+        Name => 'NumAFPoints',
+    },
+    1 => {
+        Name => 'ValidAFPoints',
+        Notes => 'number of AF points valid in the following information',
+    },
+    2 => {
+        Name => 'CanonImageWidth',
+        Groups => { 2 => 'Image' },
+    },
+    3 => {
+        Name => 'CanonImageHeight',
+        Groups => { 2 => 'Image' },
+    },
+    4 => {
+        Name => 'AFImageWidth',
+        Notes => 'size of image in AF coordinates',
+    },
+    5 => 'AFImageHeight',
+    6 => 'AFAreaWidth',
+    7 => 'AFAreaHeight',
+    8 => {
+        Name => 'AFAreaXPositions',
+        Format => 'int16s[$val{0}]',
+    },
+    9 => {
+        Name => 'AFAreaYPositions',
+        Format => 'int16s[$val{0}]',
+    },
+    10 => {
+        Name => 'AFPointsInFocus',
+        Format => 'int16s[int(($val{0}+15)/16)]',
+        PrintConv => 'Image::ExifTool::DecodeBits($val, undef, 16)',
+    },
+    11 => [
+        {
+            Name => 'PrimaryAFPoint',
+            Condition => q{
+                $$self{CameraModel} !~ /EOS/ and
+                (not $$self{AFInfoCount} or $$self{AFInfoCount} != 36)
+            },
+        },
+        {
+            # (some PowerShot 9-point systems put PrimaryAFPoint after 8 unknown values)
+            Name => 'Canon_AFInfo_0x000b',
+            Condition => '$$self{CameraModel} !~ /EOS/',
+            Format => 'int16u[8]',
+            Unknown => 1,
+        },
+        # (serial processing stops here for EOS cameras)
+    ],
+    12 => 'PrimaryAFPoint',
+);
+
+# newer AF information (MakerNotes tag 0x26) - PH (A570IS,1DmkIII,40D)
+# (Note: this tag is out of sequence in A570IS maker notes)
+%Image::ExifTool::Canon::AFInfo2 = (
+    PROCESS_PROC => \&ProcessSerialData,
+    FORMAT => 'int16u',
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        Newer version of the AFInfo record containing much of the same information
+        (and coordinate confusion) as the older version.  In this record, values of
+        9 and 45 have been observed for NumAFPoints.
+    },
+    0 => {
+        Name => 'AFInfoSize',
+        Unknown => 1, # normally don't print this out
+    },
+    1 => {
+        Name => 'AFMode',
+        PrintConv => {
+            0 => 'Off (Manual Focus)',
+            2 => 'Single-point AF',
+            4 => 'Multi-point AF', # AiAF on A570IS
+            5 => 'Face Detect AF',
+        },
+    },
+    2 => {
+        Name => 'NumAFPoints',
+        RawConv => '$$self{NumAFPoints} = $val', # save for later
+    },
+    3 => {
+        Name => 'ValidAFPoints',
+        Notes => 'number of AF points valid in the following information',
+    },
+    4 => {
+        Name => 'CanonImageWidth',
+        Groups => { 2 => 'Image' },
+    },
+    5 => {
+        Name => 'CanonImageWidth',
+        Groups => { 2 => 'Image' },
+    },
+    6 => {
+        Name => 'AFImageWidth',
+        Notes => 'size of image in AF coordinates',
+    },
+    7 => 'AFImageHeight',
+    8 => {
+        Name => 'AFAreaWidths',
+        Format => 'int16s[$val{2}]',
+    },
+    9 => {
+        Name => 'AFAreaHeights',
+        Format => 'int16s[$val{2}]',
+    },
+    10 => {
+        Name => 'AFAreaXPositions',
+        Format => 'int16s[$val{2}]',
+    },
+    11 => {
+        Name => 'AFAreaYPositions',
+        Format => 'int16s[$val{2}]',
+    },
+    12 => {
+        Name => 'AFPointsInFocus',
+        Format => 'int16s[int(($val{2}+15)/16)]',
+        PrintConv => 'Image::ExifTool::DecodeBits($val, undef, 16)',
+    },
+    13 => [
+        {
+            Name => 'AFPointsSelected',
+            Condition => '$$self{CameraModel} =~ /EOS/',
+            Format => 'int16s[int(($val{2}+15)/16)]',
+            PrintConv => 'Image::ExifTool::DecodeBits($val, undef, 16)',
+        },
+        {
+            Name => 'Canon_AFInfo2_0x000d',
+            Format => 'int16s[int(($val{2}+15)/16)+1]',
+            Unknown => 1,
+        },
+    ],
+    14 => {
+        # usually, but not always, the lowest number AF point in focus
+        Name => 'PrimaryAFPoint',
+        Condition => '$$self{CameraModel} !~ /EOS/',
+    },        
+);
+
+# my color mode information (MakerNotes tag 0x1d) - PH (A570IS)
+%Image::ExifTool::Canon::MyColors = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0x02 => {
+        Name => 'MyColorMode',
+        PrintConv => {
+            0 => 'Off',
+            9 => 'Custom',
+            12 => 'Vivid',
+            13 => 'Neutral',
+            14 => 'Sepia',
+            15 => 'B&W',
+        },
+    },
+);
+
+# face detect information (MakerNotes tag 0x24) - PH (A570IS)
+%Image::ExifTool::Canon::FaceDetect1 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    DATAMEMBER => [ 0x02 ],
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0x02 => {
+        Name => 'FacesDetected',
+        DataMember => 'FacesDetected',
+        RawConv => '$$self{FacesDetected} = $val',
+    },
+    0x03 => 'FaceDetectFrameWidth',
+    0x04 => 'FaceDetectFrameHeight',
+    0x08 => {
+        Name => 'Face0Position',
+        Format => 'int16s[2]',
+        RawConv => '$$self{FacesDetected} < 1 ? undef: $val',
+        Notes => q{
+            X-Y coordinates for the center of each face in the Face Detect frame at the
+            time of focus lock. "0 0" is the center, and positive X and Y are to the
+            right and downwards respectively
+        },
+    },
+    0x0a => {
+        Name => 'Face1Position',
+        Format => 'int16s[2]',
+        RawConv => '$$self{FacesDetected} < 2 ? undef : $val',
+    },
+    0x0c => {
+        Name => 'Face2Position',
+        Format => 'int16s[2]',
+        RawConv => '$$self{FacesDetected} < 3 ? undef : $val',
+    },
+    0x0e => {
+        Name => 'Face3Position',
+        Format => 'int16s[2]',
+        RawConv => '$$self{FacesDetected} < 4 ? undef : $val',
+    },
+    0x10 => {
+        Name => 'Face4Position',
+        Format => 'int16s[2]',
+        RawConv => '$$self{FacesDetected} < 5 ? undef : $val',
+    },
+    0x12 => {
+        Name => 'Face5Position',
+        Format => 'int16s[2]',
+        RawConv => '$$self{FacesDetected} < 6 ? undef : $val',
+    },
+    0x14 => {
+        Name => 'Face6Position',
+        Format => 'int16s[2]',
+        RawConv => '$$self{FacesDetected} < 7 ? undef : $val',
+    },
+    0x16 => {
+        Name => 'Face7Position',
+        Format => 'int16s[2]',
+        RawConv => '$$self{FacesDetected} < 8 ? undef : $val',
+    },
+    0x18 => {
+        Name => 'Face8Position',
+        Format => 'int16s[2]',
+        RawConv => '$$self{FacesDetected} < 9 ? undef : $val',
+    },
+);
+
+# more face detect information (MakerNotes tag 0x25) - PH (A570IS)
+%Image::ExifTool::Canon::FaceDetect2 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0x02 => 'FacesDetected',
+);
+
+# Preview image information (MakerNotes tag 0xb6)
+# - The 300D writes a 1536x1024 preview image that is accessed
+#   through this information - decoded by PH 12/14/03
+%Image::ExifTool::Canon::PreviewImageInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 1,
+    IS_OFFSET => [ 5 ],   # tag 5 is 'IsOffset'
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+# the size of the preview block in 2-byte increments
+#    0 => {
+#        Name => 'PreviewImageInfoWords',
+#    },
+    1 => {
+        Name => 'PreviewQuality',
+        PrintConv => \%canonQuality,
+    },
+    2 => {
+        Name => 'PreviewImageLength',
+        OffsetPair => 5,   # point to associated offset
+        DataTag => 'PreviewImage',
+        Protected => 2,
+    },
+    3 => 'PreviewImageWidth',
+    4 => 'PreviewImageHeight',
+    5 => {
+        Name => 'PreviewImageStart',
+        Flags => 'IsOffset',
+        OffsetPair => 2,  # associated byte count tagID
+        DataTag => 'PreviewImage',
+        Protected => 2,
+    },
+    6 => {
+        Name => 'PreviewFocalPlaneXResolution',
+        Format => 'rational64s',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    8 => {
+        Name => 'PreviewFocalPlaneYResolution',
+        Format => 'rational64s',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+# the following 2 values look like they are really 4 shorts
+# taking the values of 1,4,4 and 2 respectively - don't know what they are though
+#    10 => {
+#        Name => 'PreviewImageUnknown1',
+#        PrintConv => 'sprintf("0x%x",$val)',
+#    },
+#    11 => {
+#        Name => 'PreviewImageUnknown2',
+#        PrintConv => 'sprintf("0x%x",$val)',
+#    },
+);
+
+# Sensor information (MakerNotes tag 0xe0) (ref 12)
+%Image::ExifTool::Canon::SensorInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    # Note: Don't make these writable because it confuses Canon decoding software
+    # if these are changed
+    1 => 'SensorWidth',
+    2 => 'SensorHeight',
+    5 => 'SensorLeftBorder', #2
+    6 => 'SensorTopBorder', #2
+    7 => 'SensorRightBorder', #2
+    8 => 'SensorBottomBorder', #2
+);
+
+# File number information (MakerNotes tag 0x93)
+%Image::ExifTool::Canon::FileInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    1 => [
+        { #5
+            Name => 'FileNumber',
+            Condition => '$$self{CameraModel} =~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/',
+            Format => 'int32u',
+            # Thanks to Juha Eskelinen for figuring this out:
+            # [this is an odd bit mapping -- it looks like the file number exists as
+            # a 16-bit integer containing the high bits, followed by an 8-bit integer
+            # with the low bits.  But it is more convenient to have this in a single
+            # word, so some bit manipulations are necessary... - PH]
+            # The bit pattern of the 32-bit word is:
+            #   31....24 23....16 15.....8 7......0
+            #   00000000 ffffffff DDDDDDDD ddFFFFFF
+            #     0 = zero bits (not part of the file number?)
+            #     f/F = low/high bits of file number
+            #     d/D = low/high bits of directory number
+            # The directory and file number are then converted into decimal
+            # and separated by a '-' to give the file number used in the 20D
+            ValueConv => '(($val&0xffc0)>>6)*10000+(($val>>16)&0xff)+(($val&0x3f)<<8)',
+            ValueConvInv => q{
+                my $d = int($val/10000);
+                my $f = $val - $d * 10000;
+                return (($d<<6) & 0xffc0) + (($f & 0xff)<<16) + (($f>>8) & 0x3f);
+            },
+            PrintConv => '$_=$val,s/(\d+)(\d{4})/$1-$2/,$_',
+            PrintConvInv => '$val=~s/-//g;$val',
+        },
+        { #16
+            Name => 'FileNumber',
+            Condition => '$$self{CameraModel} =~ /\b(30D|400D|REBEL XTi|Kiss Digital X|K236)\b/',
+            Format => 'int32u',
+            Notes => q{
+                the location of the upper 4 bits of the directory number is a mystery for
+                the EOS 30D, so the reported directory number will be incorrect for original
+                images with a directory number of 164 or greater
+            },
+            # Thanks to Emil Sit for figuring this out:
+            # [more insane bit maniplations like the 20D/350D above, but this time we
+            # appear to have lost the upper 4 bits of the directory number (this was
+            # verified through tests with directory numbers 100, 222, 801 and 999) - PH]
+            # The bit pattern for the 30D is: (see 20D notes above for more information)
+            #   31....24 23....16 15.....8 7......0
+            #   00000000 ffff0000 ddddddFF FFFFFFFF
+            # [NOTE: the 4 high order directory bits don't appear in this record, but
+            # I have chosen to write them into bits 16-19 since these 4 zero bits look
+            # very suspicious, and are a convenient place to store this information - PH]
+            ValueConv  => q{
+                my $d = ($val & 0xffc00) >> 10;
+                # we know there are missing bits if directory number is < 100
+                $d += 0x40 while $d < 100;  # (repair the damage as best we can)
+                return $d*10000 + (($val&0x3ff)<<4) + (($val>>20)&0x0f);
+            },
+            ValueConvInv => q{
+                my $d = int($val/10000);
+                my $f = $val - $d * 10000;
+                return ($d << 10) + (($f>>4)&0x3ff) + (($f&0x0f)<<20);
+            },
+            PrintConv => '$_=$val,s/(\d+)(\d{4})/$1-$2/,$_',
+            PrintConvInv => '$val=~s/-//g;$val',
+        },
+        { #7 (1D, 1Ds)
+            Name => 'ShutterCount',
+            Condition => 'GetByteOrder() eq "MM"',
+            Format => 'int32u',
+        },
+        { #7 (1DmkII, 1DsMkII, 1DsMkIIN)
+            Name => 'ShutterCount',
+            Condition => '$$self{CameraModel} =~ /\b1Ds? Mark II\b/',
+            Format => 'int32u',
+            ValueConv => '($val>>16)|(($val&0xffff)<<16)',
+            ValueConvInv => '($val>>16)|(($val&0xffff)<<16)',
+        },
+        # 5D gives a single byte value (unknown)
+        # 40D stores all zeros
+    ],
+    3 => { #PH
+        Name => 'BracketMode',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'AEB',
+            2 => 'FEB',
+            3 => 'ISO',
+            4 => 'WB',
+        },
+    },
+    4 => 'BracketValue', #PH
+    5 => 'BracketShotNumber', #PH
+    6 => { #PH
+        Name => 'RawJpgQuality',
+        RawConv => '$val<=0 ? undef : $val',
+        PrintConv => \%canonQuality,
+    },
+    7 => { #PH
+        Name => 'RawJpgSize',
+        RawConv => '$val<0 ? undef : $val',
+        PrintConv => \%canonImageSize,
+    },
+    8 => { #PH
+        Name => 'NoiseReduction',
+        RawConv => '$val<0 ? undef : $val',
+        PrintConv => {
+            0 => 'Off',
+            # what do these modes mean?:
+            1 => 'On (mode 1)',
+            2 => 'On (mode 2)',
+            3 => 'On (mode 3)', # (1DmkII,5D)
+            4 => 'On (mode 4)', # (30D)
+        },
+    },
+    9 => { #PH
+        Name => 'WBBracketMode',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On (shift AB)',
+            2 => 'On (shift GM)',
+        },
+    },
+    12 => 'WBBracketValueAB', #PH
+    13 => 'WBBracketValueGM', #PH
+    14 => { #PH
+        Name => 'FilterEffect',
+        RawConv => '$val==-1 ? undef : $val',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Yellow',
+            2 => 'Orange',
+            3 => 'Red',
+            4 => 'Green',
+        },
+    },
+    15 => { #PH
+        Name => 'ToningEffect',
+        RawConv => '$val==-1 ? undef : $val',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Sepia',
+            2 => 'Blue',
+            3 => 'Purple',
+            4 => 'Green',
+        },
+    },
+);
+
+# color information (MakerNotes tag 0xa0)
+%Image::ExifTool::Canon::Processing = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    1 => { #PH
+        Name => 'ToneCurve',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Manual',
+            2 => 'Custom',
+        },
+    },
+    2 => { #12
+        Name => 'Sharpness',
+        Notes => '1D and 5D only',
+        Condition => '$$self{CameraModel} =~ /\b(1D|5D)/',
+    },
+    3 => { #PH
+        Name => 'SharpnessFrequency',
+        PrintConv => {
+            0 => 'n/a',
+            1 => 'Lowest',
+            2 => 'Low',
+            3 => 'Standard',
+            4 => 'High',
+            5 => 'Highest',
+        },
+    },
+    4 => 'SensorRedLevel', #PH
+    5 => 'SensorBlueLevel', #PH
+    6 => 'WhiteBalanceRed', #PH
+    7 => 'WhiteBalanceBlue', #PH
+    8 => { #PH
+        Name => 'WhiteBalance',
+        RawConv => '$val < 0 ? undef : $val',
+        PrintConv => \%canonWhiteBalance,
+    },
+    9 => 'ColorTemperature', #6
+    10 => { #12
+        Name => 'PictureStyle',
+        PrintHex => 1,
+        PrintConv => \%pictureStyles,
+    },
+    11 => { #PH
+        Name => 'DigitalGain',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+    },
+    12 => { #PH
+        Name => 'WBShiftAB',
+        Notes => 'positive is a shift toward red',
+    },
+    13 => { #PH
+        Name => 'WBShiftGM',
+        Notes => 'positive is a shift toward yellow/green',
+    },
+);
+
+# D30 color information (MakerNotes tag 0x0a)
+%Image::ExifTool::Canon::ColorInfoD30 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    9 => 'ColorTemperature',
+    10 => 'ColorMatrix',
+);
+
+# Color balance information (MakerNotes tag 0xa9) (ref PH)
+%Image::ExifTool::Canon::ColorBalance = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    NOTES => 'This table is used by the 10D and 300D.',
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    # red,green1,green2,blue (ref 2)
+    0  => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16u[4]' },
+    4  => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16u[4]' },
+    8  => { Name => 'WB_RGGBLevelsShade',      Format => 'int16u[4]' },
+    12 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16u[4]' },
+    16 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16u[4]' },
+    20 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16u[4]' },
+    24 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16u[4]' },
+    28 => { Name => 'WB_RGGBLevelsCustom',     Format => 'int16u[4]' },
+    32 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16u[4]' },
+);
+
+# Color balance (MakerNotes tag 0x4001) (ref 12)
+%Image::ExifTool::Canon::ColorBalance1 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    NOTES => 'This table is used by the 20D and 350D.',
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    25 => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16u[4]' },
+    29 => 'ColorTempAsShot',
+    30 => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16u[4]' },
+    34 => 'ColorTempAuto',
+    35 => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16u[4]' },
+    39 => 'ColorTempDaylight',
+    40 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16u[4]' },
+    44 => 'ColorTempShade',
+    45 => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16u[4]' },
+    49 => 'ColorTempCloudy',
+    50 => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16u[4]' },
+    54 => 'ColorTempTungsten',
+    55 => { Name => 'WB_RGGBLevelsFluorescent', Format => 'int16u[4]' },
+    59 => 'ColorTempFluorescent',
+    60 => { Name => 'WB_RGGBLevelsFlash',       Format => 'int16u[4]' },
+    64 => 'ColorTempFlash',
+    65 => { Name => 'WB_RGGBLevelsCustom1',     Format => 'int16u[4]' },
+    69 => 'ColorTempCustom1',
+    70 => { Name => 'WB_RGGBLevelsCustom2',     Format => 'int16u[4]' },
+    74 => 'ColorTempCustom2',
+);
+
+# Color balance (MakerNotes tag 0x4001) (ref 12)
+%Image::ExifTool::Canon::ColorBalance2 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    NOTES => 'This table is used by the 1DmkII and 1DSmkII.',
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    24 => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16u[4]' },
+    28 => 'ColorTempAsShot',
+    29 => { Name => 'WB_RGGBLevelsUnknown',     Format => 'int16u[4]', Unknown => 1 },
+    33 => { Name => 'ColorTempUnknown', Unknown => 1 },
+    34 => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16u[4]' },
+    38 => 'ColorTempAuto',
+    39 => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16u[4]' },
+    43 => 'ColorTempDaylight',
+    44 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16u[4]' },
+    48 => 'ColorTempShade',
+    49 => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16u[4]' },
+    53 => 'ColorTempCloudy',
+    54 => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16u[4]' },
+    58 => 'ColorTempTungsten',
+    59 => { Name => 'WB_RGGBLevelsFluorescent', Format => 'int16u[4]' },
+    63 => 'ColorTempFluorescent',
+    64 => { Name => 'WB_RGGBLevelsKelvin',      Format => 'int16u[4]' },
+    68 => 'ColorTempKelvin',
+    69 => { Name => 'WB_RGGBLevelsFlash',       Format => 'int16u[4]' },
+    73 => 'ColorTempFlash',
+    74 => { Name => 'WB_RGGBLevelsUnknown2',    Format => 'int16u[4]', Unknown => 1 },
+    78 => { Name => 'ColorTempUnknown2', Unknown => 1 },
+    79 => { Name => 'WB_RGGBLevelsUnknown3',    Format => 'int16u[4]', Unknown => 1 },
+    83 => { Name => 'ColorTempUnknown3', Unknown => 1 },
+    84 => { Name => 'WB_RGGBLevelsUnknown4',    Format => 'int16u[4]', Unknown => 1 },
+    88 => { Name => 'ColorTempUnknown4', Unknown => 1 },
+    89 => { Name => 'WB_RGGBLevelsUnknown5',    Format => 'int16u[4]', Unknown => 1 },
+    93 => { Name => 'ColorTempUnknown5', Unknown => 1 },
+    94 => { Name => 'WB_RGGBLevelsUnknown6',    Format => 'int16u[4]', Unknown => 1 },
+    98 => { Name => 'ColorTempUnknown6', Unknown => 1 },
+    99 => { Name => 'WB_RGGBLevelsUnknown7',    Format => 'int16u[4]', Unknown => 1 },
+    103 => { Name => 'ColorTempUnknown7', Unknown => 1 },
+    104 => { Name => 'WB_RGGBLevelsUnknown8',   Format => 'int16u[4]', Unknown => 1 },
+    108 => { Name => 'ColorTempUnknown8', Unknown => 1 },
+    109 => { Name => 'WB_RGGBLevelsUnknown9',   Format => 'int16u[4]', Unknown => 1 },
+    113 => { Name => 'ColorTempUnknown9', Unknown => 1 },
+    114 => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16u[4]', Unknown => 1 },
+    118 => { Name => 'ColorTempUnknown10', Unknown => 1 },
+    119 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16u[4]', Unknown => 1 },
+    123 => { Name => 'ColorTempUnknown11', Unknown => 1 },
+    124 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16u[4]', Unknown => 1 },
+    128 => { Name => 'ColorTempUnknown12', Unknown => 1 },
+    129 => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16u[4]', Unknown => 1 },
+    133 => { Name => 'ColorTempUnknown13', Unknown => 1 },
+    134 => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16u[4]', Unknown => 1 },
+    138 => { Name => 'ColorTempUnknown14', Unknown => 1 },
+    139 => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16u[4]', Unknown => 1 },
+    143 => { Name => 'ColorTempUnknown15', Unknown => 1 },
+    144 => { Name => 'WB_RGGBLevelsPC1',        Format => 'int16u[4]' },
+    148 => 'ColorTempPC1',
+    149 => { Name => 'WB_RGGBLevelsPC2',        Format => 'int16u[4]' },
+    153 => 'ColorTempPC2',
+    154 => { Name => 'WB_RGGBLevelsPC3',        Format => 'int16u[4]' },
+    158 => 'ColorTempPC3',
+    159 => { Name => 'WB_RGGBLevelsUnknown16',  Format => 'int16u[4]', Unknown => 1 },
+    163 => { Name => 'ColorTempUnknown16', Unknown => 1 },
+);
+
+# Color balance (MakerNotes tag 0x4001) (ref 12)
+%Image::ExifTool::Canon::ColorBalance3 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    NOTES => 'This table is used by the 1DmkIIN, 5D, 30D and 400D.',
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    63 => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16u[4]' },
+    67 => 'ColorTempAsShot',
+    68 => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16u[4]' },
+    72 => 'ColorTempAuto',
+    # not sure exactly what 'Measured' values mean...
+    73 => { Name => 'WB_RGGBLevelsMeasured',    Format => 'int16u[4]' },
+    77 => 'ColorTempMeasured',
+    78 => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16u[4]' },
+    82 => 'ColorTempDaylight',
+    83 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16u[4]' },
+    87 => 'ColorTempShade',
+    88 => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16u[4]' },
+    92 => 'ColorTempCloudy',
+    93 => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16u[4]' },
+    97 => 'ColorTempTungsten',
+    98 => { Name => 'WB_RGGBLevelsFluorescent', Format => 'int16u[4]' },
+    102 => 'ColorTempFluorescent',
+    103 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16u[4]' },
+    107 => 'ColorTempKelvin',
+    108 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16u[4]' },
+    112 => 'ColorTempFlash',
+    113 => { Name => 'WB_RGGBLevelsPC1',        Format => 'int16u[4]' },
+    117 => 'ColorTempPC1',
+    118 => { Name => 'WB_RGGBLevelsPC2',        Format => 'int16u[4]' },
+    122 => 'ColorTempPC2',
+    123 => { Name => 'WB_RGGBLevelsPC3',        Format => 'int16u[4]' },
+    127 => 'ColorTempPC3',
+    128 => { Name => 'WB_RGGBLevelsCustom',     Format => 'int16u[4]' },
+    132 => 'ColorTempCustom',
+);
+
+# Color information (MakerNotes tag 0x4003) (ref PH)
+%Image::ExifTool::Canon::ColorInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    1 => {
+        Condition => '$$self{CameraMake} =~ /EOS-1D/',
+        Name => 'Saturation',
+    },
+    2 => 'ColorHue',
+    3 => {
+        Name => 'ColorSpace',
+        RawConv => '$val ? $val : undef', # ignore tag if zero
+        PrintConv => {
+            1 => 'sRGB',
+            2 => 'Adobe RGB',
+        },
+    },
+);
+
+# Flags information (MakerNotes tag 0xb0) (ref PH)
+%Image::ExifTool::Canon::Flags = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    1 => 'ModifiedParamFlag',
+);
+
+# Modified information (MakerNotes tag 0xb1) (ref PH)
+%Image::ExifTool::Canon::ModifiedInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    1 => {
+        Name => 'ModifiedToneCurve',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Manual',
+            2 => 'Custom',
+        },
+    },
+    2 => {
+        Name => 'ModifiedSharpness',
+        Notes => '1D and 5D only',
+        Condition => '$$self{CameraModel} =~ /\b(1D|5D)/',
+    },
+    3 => {
+        Name => 'ModifiedSharpnessFreq',
+        PrintConv => {
+            0 => 'n/a',
+            1 => 'Smoothest',
+            2 => 'Smooth',
+            3 => 'Standard',
+            4 => 'Sharp',
+            5 => 'Sharpest',
+        },
+    },
+    4 => 'ModifiedSensorRedLevel',
+    5 => 'ModifiedSensorBlueLevel',
+    6 => 'ModifiedWhiteBalanceRed',
+    7 => 'ModifiedWhiteBalanceBlue',
+    8 => {
+        Name => 'ModifiedWhiteBalance',
+        PrintConv => \%canonWhiteBalance,
+    },
+    9 => 'ModifiedColorTemp',
+    10 => {
+        Name => 'ModifiedPictureStyle',
+        PrintHex => 1,
+        PrintConv => \%pictureStyles,
+    },
+    11 => {
+        Name => 'ModifiedDigitalGain',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+    },
+);
+
+# canon composite tags
+%Image::ExifTool::Canon::Composite = (
+    GROUPS => { 2 => 'Camera' },
+    DriveMode => {
+        Require => {
+            0 => 'ContinuousDrive',
+            1 => 'Self-timer',
+        },
+        ValueConv => '$val[0] ? 0 : ($val[1] ? 1 : 2)',
+        PrintConv => {
+            0 => 'Continuous shooting',
+            1 => 'Self-timer Operation',
+            2 => 'Single-frame shooting',
+        },
+    },
+    Lens => {
+        Require => {
+            0 => 'ShortFocal',
+            1 => 'LongFocal',
+        },
+        ValueConv => '$val[0]',
+        PrintConv => 'Image::ExifTool::Canon::PrintFocalRange(@val)',
+    },
+    Lens35efl => {
+        Description => 'Lens',
+        Require => {
+            0 => 'ShortFocal',
+            1 => 'LongFocal',
+            3 => 'Lens',
+        },
+        Desire => {
+            2 => 'ScaleFactor35efl',
+        },
+        ValueConv => '$val[3] * ($val[2] ? $val[2] : 1)',
+        PrintConv => '$prt[3] . ($val[2] ? sprintf(" (35mm equivalent: %s)",Image::ExifTool::Canon::PrintFocalRange(@val)) : "")',
+    },
+    ShootingMode => {
+        Require => {
+            0 => 'CanonExposureMode',
+            1 => 'EasyMode',
+        },
+        ValueConv => '$val[0] ? $val[0] : $val[1] + 10',
+        PrintConv => '$val[0] ? $prt[0] : $prt[1]',
+    },
+    FlashType => {
+        Require => {
+            0 => 'FlashBits',
+        },
+        RawConv => '$val[0] ? $val : undef',
+        ValueConv => '$val[0]&(1<<14)? 1 : 0',
+        PrintConv => {
+            0 => 'Built-In Flash',
+            1 => 'External',
+        },
+    },
+    RedEyeReduction => {
+        Require => {
+            0 => 'CanonFlashMode',
+            1 => 'FlashBits',
+        },
+        RawConv => '$val[1] ? $val : undef',
+        ValueConv => '($val[0]==3 or $val[0]==4 or $val[0]==6) ? 1 : 0',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    # fudge to display simple Flash On/Off for Canon cameras only
+    FlashOn => {
+        Description => 'Flash',
+        Desire => {
+            0 => 'FlashBits',
+            1 => 'Flash',
+        },
+        ValueConv => 'Image::ExifTool::Canon::FlashOn(@val)',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    # same as FlashExposureComp, but undefined if no flash
+    ConditionalFEC => {
+        Description => 'Flash Exposure Compensation',
+        Require => {
+            0 => 'FlashExposureComp',
+            1 => 'FlashBits',
+        },
+        RawConv => '$val[1] ? $val : undef',
+        ValueConv => '$val[0]',
+        PrintConv => '$prt[0]',
+    },
+    # hack to assume 1st curtain unless we see otherwise
+    ShutterCurtainHack => {
+        Description => 'Shutter Curtain Sync',
+        Desire => {
+            0 => 'ShutterCurtainSync',
+        },
+        Require => {
+            1 => 'FlashBits',
+        },
+        RawConv => '$val[1] ? $val : undef',
+        ValueConv => 'defined($val[0]) ? $val[0] : 0',
+        PrintConv => {
+            0 => '1st-curtain sync',
+            1 => '2nd-curtain sync',
+        },
+    },
+    WB_RGGBLevels => {
+        Require => {
+            0 => 'Canon:WhiteBalance',
+        },
+        Desire => {
+            1 => 'WB_RGGBLevelsAsShot',
+            # indices of the following entries correspond to Canon:WhiteBalance + 2
+            2 => 'WB_RGGBLevelsAuto',
+            3 => 'WB_RGGBLevelsDaylight',
+            4 => 'WB_RGGBLevelsCloudy',
+            5 => 'WB_RGGBLevelsTungsten',
+            6 => 'WB_RGGBLevelsFluorescent',
+            7 => 'WB_RGGBLevelsFlash',
+            8 => 'WB_RGGBLevelsCustom',
+           10 => 'WB_RGGBLevelsShade',
+           11 => 'WB_RGGBLevelsKelvin',
+        },
+        ValueConv => '$val[1] ? $val[1] : $val[($val[0] || 0) + 2]',
+    },
+    ISO => {
+        Priority => 0,  # let EXIF:ISO take priority
+        Desire => {
+            0 => 'Canon:CameraISO',
+            1 => 'Canon:BaseISO',
+            2 => 'Canon:AutoISO',
+        },
+        Notes => 'use CameraISO if numerical, otherwise calculate as BaseISO * AutoISO / 100',
+        ValueConv => q{
+            return $val[0] if $val[0] and $val[0] =~ /^\d+$/;
+            return undef unless $val[1] and $val[2];
+            return $val[1] * $val[2] / 100;
+        },
+        PrintConv => 'sprintf("%.0f",$val)',
+    },
+    DigitalZoom => {
+        Require => {
+            0 => 'Canon:ZoomSourceWidth',
+            1 => 'Canon:ZoomTargetWidth',
+            2 => 'Canon:DigitalZoom',
+        },
+        RawConv => q{
+            return undef unless $val[2] == 3 and $val[0];
+            return $val[1] / $val[0];
+        },
+        PrintConv => 'sprintf("%.2fx",$val)',
+    }
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::Canon');
+
+
+#------------------------------------------------------------------------------
+# Validate first word of Canon binary data
+# Inputs: 0) data pointer, 1) offset, 2-N) list of valid values
+# Returns: true if data value is the same
+sub Validate($$@)
+{
+    my ($dataPt, $offset, @vals) = @_;
+    # the first 16-bit value is the length of the data in bytes
+    my $dataVal = Image::ExifTool::Get16u($dataPt, $offset);
+    my $val;
+    foreach $val (@vals) {
+        return 1 if $val == $dataVal;
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Validate CanonAFInfo
+# Inputs: 0) data pointer, 1) offset, 2) size
+# Returns: true if data appears valid
+sub ValidateAFInfo($$$)
+{
+    my ($dataPt, $offset, $size) = @_;
+    return 0 if $size < 24; # must be at least 24 bytes long (PowerShot Pro1)
+    my $af = Get16u($dataPt, $offset);
+    return 0 if $af !~ /^(1|5|7|9|15|45|53)$/; # check NumAFPoints
+    my $w1 = Get16u($dataPt, $offset + 4);
+    my $h1 = Get16u($dataPt, $offset + 6);
+    return 0 unless $h1 and $w1;
+    my $f1 = $w1 / $h1;
+    # check for normal aspect ratio
+    return 1 if abs($f1 - 1.33) < 0.01 or abs($f1 - 1.67) < 0.01;
+    # ZoomBrowser can modify this for rotated images (ref Joshua Bixby)
+    return 1 if abs($f1 - 0.75) < 0.01 or abs($f1 - 0.60) < 0.01;
+    my $w2 = Get16u($dataPt, $offset + 8);
+    my $h2 = Get16u($dataPt, $offset + 10);
+    return 0 unless $h2 and $w2;
+    # compare aspect ratio with AF image size
+    # (but the Powershot AFImageHeight is odd, hence the test above)
+    return 0 if $w1 eq $h1;
+    my $f2 = $w2 / $h2;
+    return 1 if abs(1-$f1/$f2) < 0.01;
+    return 1 if abs(1-$f1*$f2) < 0.01;
+    return 0;
+}
+
+#------------------------------------------------------------------------------
+# Convert the CameraISO value
+# Inputs: 0) value, 1) set for inverse conversion
+sub CameraISO($;$)
+{
+    my ($val, $inv) = @_;
+    my $rtnVal;
+    my %isoLookup = (
+         0 => 'n/a',
+        14 => 'Auto High', #PH (S3IS)
+        15 => 'Auto',
+        16 => 50,
+        17 => 100,
+        18 => 200,
+        19 => 400,
+        20 => 800, #PH
+    );
+    if ($inv) {
+        $rtnVal = Image::ExifTool::ReverseLookup($val, \%isoLookup);
+        if (not defined $rtnVal and Image::ExifTool::IsInt($val)) {
+            $rtnVal = ($val & 0x3fff) | 0x4000;
+        }
+    } elsif ($val != 0x7fff) {
+        if ($val & 0x4000) {
+            $rtnVal = $val & 0x3fff;
+        } else {
+            $rtnVal = $isoLookup{$val} || "Unknown ($val)";
+        }
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Print range of focal lengths
+# Inputs: 0) short focal, 1) long focal, 2) optional scaling factor
+sub PrintFocalRange(@)
+{
+    my ($short, $long, $scale) = @_;
+
+    $scale or $scale = 1;
+    if ($short == $long) {
+        return sprintf("%.1fmm", $short * $scale);
+    } else {
+        return sprintf("%.1f - %.1fmm", $short * $scale, $long * $scale);
+    }
+}
+
+#------------------------------------------------------------------------------
+# process a serial stream of binary data
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+# Notes: The tagID's for serial stream tags are consecutive indices beginning
+#        at 0, and the corresponding values must be contiguous in memory.
+#        "Unknown" tags must be used to skip padding or unknown values.
+sub ProcessSerialData($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $offset = $$dirInfo{DirStart};
+    my $size = $$dirInfo{DirLen};
+    my $base = $$dirInfo{Base} || 0;
+    my $verbose = $exifTool->Options('Verbose');
+    my $dataPos = $$dirInfo{DataPos} || 0;
+
+    # temporarily set Unknown option so GetTagInfo() will return existing unknown tags
+    # (require to maintain serial data synchronization)
+    my $unknown = $exifTool->Options(Unknown => 1);
+    # but disable unknown tag generation (because processing ends when we run out of tags)
+    $$exifTool{NO_UNKNOWN} = 1;
+
+    $verbose and $exifTool->VerboseDir('SerialData', undef, $size);
+
+    # get default format ('int8u' unless specified)
+    my $defaultFormat = $$tagTablePtr{FORMAT} || 'int8u';
+
+    my ($index, %val);
+    my $pos = 0;
+    for ($index=0; $$tagTablePtr{$index} and $pos <= $size; ++$index) {
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $index) or last;
+        my $format = $$tagInfo{Format};
+        my $count = 1;
+        if ($format) {
+            if ($format =~ /(.*)\[(.*)\]/) {
+                $format = $1;
+                $count = $2;
+                # evaluate count to allow count to be based on previous values
+                #### eval Format (%val, $size)
+                $count = eval $count;
+                $@ and warn("Format $$tagInfo{Name}: $@"), last;
+            } elsif ($format eq 'string') {
+                # allow string with no specified count to run to end of block
+                $count = ($size > $pos) ? $size - $pos : 0;
+            }
+        } else {
+            $format = $defaultFormat;
+        }
+        my $len = (Image::ExifTool::FormatSize($format) || 1) * $count;
+        last if $pos + $len > $size;
+        my $val = ReadValue($dataPt, $pos+$offset, $format, $count, $size-$pos);
+        last unless defined $val;
+        if ($verbose) {
+            $exifTool->VerboseInfo($index, $tagInfo,
+                Index  => $index,
+                Table  => $tagTablePtr,
+                Value  => $val,
+                DataPt => $dataPt,
+                Size   => $len,
+                Start  => $pos+$offset,
+                Addr   => $pos+$offset+$base+$dataPos,
+                Format => $format,
+                Count  => $count,
+            );
+        }
+        $val{$index} = $val;
+        if ($$tagInfo{SubDirectory}) {
+            my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+            my %dirInfo = (
+                DataPt => \$val,
+                DataPos => $dataPos + $pos,
+                DirStart => 0,
+                DirLen => length($val),
+            );
+            $exifTool->ProcessDirectory(\%dirInfo, $subTablePtr);
+        } elsif (not $$tagInfo{Unknown} or $unknown) {
+            # don't extract zero-length information
+            $exifTool->FoundTag($tagInfo, $val) if $count;
+        }
+        $pos += $len;
+    }
+    $exifTool->Options(Unknown => $unknown);    # restore Unknown option
+    delete $$exifTool{NO_UNKNOWN};
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Print 1D AF points
+# Inputs: 0) value to convert
+# Focus point pattern:
+#          A1  A2  A3  A4  A5  A6  A7
+#    B1  B2  B3  B4  B5  B6  B7  B8  B9  B10
+#  C1  C2  C3  C4  C5  C6  C7  C9  C9  C10  C11
+#    D1  D2  D3  D4  D5  D6  D7  D8  D9  D10
+#          E1  E2  E3  E4  E5  E6  E7
+sub PrintAFPoints1D($)
+{
+    my $val = shift;
+    return 'Unknown' unless length $val == 8;
+    # these are the x/y positions of each bit in the AF point mask
+    # (x is upper 3 bits / y is lower 5 bits)
+    my @focusPts = (0,0,
+              0x04,0x06,0x08,0x0a,0x0c,0x0e,0x10,         0,0,
+      0x21,0x23,0x25,0x27,0x29,0x2b,0x2d,0x2f,0x31,0x33,
+    0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4d,0x50,0x52,0x54,
+      0x61,0x63,0x65,0x67,0x69,0x6b,0x6d,0x6f,0x71,0x73,  0,0,
+              0x84,0x86,0x88,0x8a,0x8c,0x8e,0x90,   0,0,0,0,0
+    );
+    my $focus = unpack('C',$val);
+    my @bits = split //, unpack('b*',substr($val,1));
+    my @rows = split //, '  AAAAAAA  BBBBBBBBBBCCCCCCCCCCCDDDDDDDDDD  EEEEEEE     ';
+    my ($focusing, $focusPt, @points);
+    my $lastRow = '';
+    my $col = 0;
+    foreach $focusPt (@focusPts) {
+        my $row = shift @rows;
+        $col = ($row eq $lastRow) ? $col + 1 : 1;
+        $lastRow = $row;
+        $focusing = "$row$col" if $focus eq $focusPt;
+        push @points, "$row$col" if shift @bits;
+    }
+    $focusing or $focusing = ($focus eq 0xff) ? 'Auto' : sprintf('Unknown (0x%.2x)',$focus);
+    return "$focusing (" . join(',',@points) . ')';
+}
+
+#------------------------------------------------------------------------------
+# Decide whether flash was on or off
+sub FlashOn(@)
+{
+    my @val = @_;
+
+    if (defined $val[0]) {
+        return $val[0] ? 1 : 0;
+    }
+    if (defined $val[1]) {
+        return $val[1]&0x07 ? 1 : 0;
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Convert Canon hex-based EV (modulo 0x20) to real number
+# Inputs: 0) value to convert
+# ie) 0x00 -> 0
+#     0x0c -> 0.33333
+#     0x10 -> 0.5
+#     0x14 -> 0.66666
+#     0x20 -> 1   ...  etc
+sub CanonEv($)
+{
+    my $val = shift;
+    my $sign;
+    # temporarily make the number positive
+    if ($val < 0) {
+        $val = -$val;
+        $sign = -1;
+    } else {
+        $sign = 1;
+    }
+    my $frac = $val & 0x1f;
+    $val -= $frac;      # remove fraction
+    # Convert 1/3 and 2/3 codes
+    if ($frac == 0x0c) {
+        $frac = 0x20 / 3;
+    } elsif ($frac == 0x14) {
+        $frac = 0x40 / 3;
+    }
+    return $sign * ($val + $frac) / 0x20;
+}
+
+#------------------------------------------------------------------------------
+# Convert number to Canon hex-based EV (modulo 0x20)
+# Inputs: 0) number
+# Returns: Canon EV code
+sub CanonEvInv($)
+{
+    my $num = shift;
+    my $sign;
+    # temporarily make the number positive
+    if ($num < 0) {
+        $num = -$num;
+        $sign = -1;
+    } else {
+        $sign = 1;
+    }
+    my $val = int($num);
+    my $frac = $num - $val;
+    if (abs($frac - 0.33) < 0.05) {
+        $frac = 0x0c
+    } elsif (abs($frac - 0.67) < 0.05) {
+        $frac = 0x14;
+    } else {
+        $frac = int($frac * 0x20 + 0.5);
+    }
+    return $sign * ($val * 0x20 + $frac);
+}
+
+#------------------------------------------------------------------------------
+# Write Canon maker notes
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table ref
+# Returns: data block (may be empty if no Exif data) or undef on error
+sub WriteCanon($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    $exifTool or return 1;    # allow dummy access to autoload this package
+    my $dirData = Image::ExifTool::Exif::WriteExif($exifTool, $dirInfo, $tagTablePtr);
+    # add trailer which is written by some Canon models (it's a TIFF header)
+    if (defined $dirData and length $dirData and $$dirInfo{Fixup}) {
+        $dirData .= GetByteOrder() . Set16u(42) . Set32u(0);
+        $dirInfo->{Fixup}->AddFixup(length($dirData) - 4);
+    }
+    return $dirData;
+}
+
+#------------------------------------------------------------------------------
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Canon - Canon EXIF maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+Canon maker notes in EXIF information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html>
+
+=item L<http://www.wonderland.org/crw/>
+
+=item L<http://www.cybercom.net/~dcoffin/dcraw/>
+
+=item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_canon.htm>
+
+=item (...plus lots of testing with my 300D and my daughter's A570IS!)
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks Michael Rommel and Daniel Pittman for information they provided about
+the Digital Ixus and PowerShot S70 cameras, Juha Eskelinen and Emil Sit for
+figuring out the 20D and 30D FileNumber, Denny Priebe for figuring out a
+couple of 1D tags, and Michael Tiemann and Rainer Honle for decoding a
+number of new tags.  Also thanks to everyone who made contributions to the
+LensType lookup list or the meanings of other tag values.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Canon Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/CanonCustom.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/CanonCustom.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/CanonCustom.pm	(revision 20131)
@@ -0,0 +1,2058 @@
+#------------------------------------------------------------------------------
+# File:         CanonCustom.pm
+#
+# Description:  Read and write Canon Custom functions
+#
+# Revisions:    11/25/2003  - P. Harvey Created
+#
+# References:   1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
+#               2) Christian Koller private communication (tests with the 20D)
+#               3) Rainer Honle private communication (tests with the 5D)
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::CanonCustom;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess);
+use Image::ExifTool::Canon;
+use Image::ExifTool::Exif;
+
+$VERSION = '1.17';
+
+sub ProcessCanonCustom($$$);
+sub ProcessCanonCustom2($$$);
+sub WriteCanonCustom($$$);
+sub WriteCanonCustom2($$$);
+sub CheckCanonCustom($$$);
+sub ConvertPFn($);
+sub ConvertPFnInv($);
+
+my %onOff = ( 0 => 'On', 1 => 'Off' );
+my %offOn = ( 0 => 'Off', 1 => 'On' );
+my %disableEnable = ( 0 => 'Disable', 1 => 'Enable' );
+my %enableDisable = ( 0 => 'Enable', 1 => 'Disable' );
+my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
+
+#------------------------------------------------------------------------------
+# Custom functions for the 1D
+# CanonCustom (keys are custom function number)
+%Image::ExifTool::CanonCustom::Functions1D = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessCanonCustom,
+    WRITE_PROC => \&WriteCanonCustom,
+    CHECK_PROC => \&CheckCanonCustom,
+    WRITABLE => 'int8u',
+    NOTES => q{
+        These custom functions are used by all 1D models up to but not including the
+        Mark III.
+    },
+    0 => {
+        Name => 'FocusingScreen',
+        PrintConv => {
+            0 => 'Ec-N, R',
+            1 => 'Ec-A,B,C,CII,CIII,D,H,I,L',
+        },
+    },
+    1 => {
+        Name => 'FinderDisplayDuringExposure',
+        PrintConv => \%offOn,
+    },
+    2 => {
+        Name => 'ShutterReleaseNoCFCard',
+        Description => 'Shutter Release W/O CF Card',
+        PrintConv => {
+            0 => 'Yes',
+            1 => 'No',
+        },
+    },
+    3 => {
+        Name => 'ISOSpeedExpansion',
+        Description => 'ISO Speed Expansion',
+        PrintConv => {
+            0 => 'No',
+            1 => 'Yes',
+        },
+    },
+    4 => {
+        Name => 'ShutterAELButton',
+        Description => 'Shutter Button/AEL Button',
+        PrintConv => {
+            0 => 'AF/AE lock stop',
+            1 => 'AE lock/AF',
+            2 => 'AF/AF lock, No AE lock',
+            3 => 'AE/AF, No AE lock',
+        },
+    },
+    5 => {
+        Name => 'ManualTv',
+        Description => 'Manual Tv/Av For M',
+        PrintConv => {
+            0 => 'Tv=Main/Av=Control',
+            1 => 'Tv=Control/Av=Main',
+            2 => 'Tv=Main/Av=Main w/o lens',
+            3 => 'Tv=Control/Av=Main w/o lens',
+        },
+    },
+    6 => {
+        Name => 'ExposureLevelIncrements',
+        PrintConv => {
+            0 => '1/3-stop set, 1/3-stop comp.',
+            1 => '1-stop set, 1/3-stop comp.',
+            2 => '1/2-stop set, 1/2-stop comp.',
+        },
+    },
+    7 => {
+        Name => 'USMLensElectronicMF',
+        PrintConv => {
+            0 => 'Turns on after one-shot AF',
+            1 => 'Turns off after one-shot AF',
+            2 => 'Always turned off',
+        },
+    },
+    8 => {
+        Name => 'LCDPanels',
+        Description => 'Top/Back LCD Panels',
+        PrintConv => {
+            0 => 'Remain. shots/File no.',
+            1 => 'ISO/Remain. shots',
+            2 => 'ISO/File no.',
+            3 => 'Shots in folder/Remain. shots',
+        },
+    },
+    9 => {
+        Name => 'AEBSequence',
+        PrintConv => {
+            0 => '0,-,+/Enabled',
+            1 => '0,-,+/Disabled',
+            2 => '-,0,+/Enabled',
+            3 => '-,0,+/Disabled',
+        },
+    },
+    10 => {
+        Name => 'AFPointIllumination',
+        PrintConv => {
+            0 => 'On',
+            1 => 'Off',
+            2 => 'On without dimming',
+            3 => 'Brighter',
+        },
+    },
+    11 => {
+        Name => 'AFPointSelection',
+        PrintConv => {
+            0 => 'H=AF+Main/V=AF+Command',
+            1 => 'H=Comp+Main/V=Comp+Command',
+            2 => 'H=Command only/V=Assist+Main',
+            3 => 'H=FEL+Main/V=FEL+Command',
+        },
+    },
+    12 => {
+        Name => 'MirrorLockup',
+        PrintConv => \%disableEnable,
+    },
+    13 => {
+        Name => 'AFPointSpotMetering',
+        Description => 'No. AF Points/Spot Metering',
+        PrintConv => {
+            0 => '45/Center AF point',
+            1 => '11/Active AF point',
+            2 => '11/Center AF point',
+            3 => '9/Active AF point',
+        },
+    },
+    14 => {
+        Name => 'FillFlashAutoReduction',
+        PrintConv => \%enableDisable,
+    },
+    15 => {
+        Name => 'ShutterCurtainSync',
+        PrintConv => {
+            0 => '1st-curtain sync',
+            1 => '2nd-curtain sync',
+        },
+    },
+    16 => {
+        Name => 'SafetyShiftInAvOrTv',
+        PrintConv => \%disableEnable,
+    },
+    17 => {
+        Name => 'AFPointActivationArea',
+        PrintConv => {
+            0 => 'Single AF point',
+            1 => 'Expanded (TTL. of 7 AF points)',
+            2 => 'Automatic expanded (max. 13)',
+        },
+    },
+    18 => {
+        Name => 'SwitchToRegisteredAFPoint',
+        PrintConv => {
+            0 => 'Assist + AF',
+            1 => 'Assist',
+            2 => 'Only while pressing assist',
+        },
+    },
+    19 => {
+        Name => 'LensAFStopButton',
+        PrintConv => {
+            0 => 'AF stop',
+            1 => 'AF start',
+            2 => 'AE lock while metering',
+            3 => 'AF point: M -> Auto / Auto -> Ctr.',
+            4 => 'AF mode: ONE SHOT <-> AI SERVO',
+            5 => 'IS start',
+        },
+    },
+    20 => {
+        Name => 'AIServoTrackingSensitivity',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Slow',
+            2 => 'Moderately slow',
+            3 => 'Moderately fast',
+            4 => 'Fast',
+        },
+    },
+);
+
+# Custom functions for the 5D (ref 3)
+%Image::ExifTool::CanonCustom::Functions5D = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessCanonCustom,
+    WRITE_PROC => \&WriteCanonCustom,
+    CHECK_PROC => \&CheckCanonCustom,
+    WRITABLE => 'int8u',
+    0 => {
+        Name => 'FocusingScreen',
+        PrintConv => {
+            0 => 'Ee-A',
+            1 => 'Ee-D',
+            2 => 'Ee-S',
+        },
+    },
+    1 => {
+        Name => 'SetFunctionWhenShooting',
+        PrintConv => {
+            0 => 'Default (no function)',
+            1 => 'Change quality',
+            2 => 'Change Parameters',
+            3 => 'Menu display',
+            4 => 'Image replay',
+        },
+    },
+    2 => {
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'On',
+        },
+    },
+    3 => {
+        Name => 'FlashSyncSpeedAv',
+        PrintConv => {
+            0 => 'Auto',
+            1 => '1/200 Fixed',
+        },
+    },
+    4 => {
+        Name => 'Shutter-AELock',
+        PrintConv => {
+            0 => 'AF/AE lock',
+            1 => 'AE lock/AF',
+            2 => 'AF/AF lock, No AE lock',
+            3 => 'AE/AF, No AE lock',
+        },
+    },
+    5 => {
+        Name => 'AFAssistBeam',
+        PrintConv => {
+            0 => 'Emits',
+            1 => 'Does not emit',
+        },
+    },
+    6 => {
+        Name => 'ExposureLevelIncrements',
+        PrintConv => {
+            0 => '1/3 Stop',
+            1 => '1/2 Stop',
+        },
+    },
+    7 => {
+        Name => 'FlashFiring',
+        PrintConv => {
+            0 => 'Fires',
+            1 => 'Does not fire',
+        },
+    },
+    8 => {
+        Name => 'ISOExpansion',
+        PrintConv => \%offOn,
+    },
+    9 => {
+        Name => 'AEBSequence',
+        PrintConv => {
+            0 => '0,-,+/Enabled',
+            1 => '0,-,+/Disabled',
+            2 => '-,0,+/Enabled',
+            3 => '-,0,+/Disabled',
+        },
+    },
+    10 => {
+        Name => 'SuperimposedDisplay',
+        PrintConv => \%onOff,
+    },
+    11 => {
+        Name => 'MenuButtonDisplayPosition',
+        PrintConv => {
+            0 => 'Previous (top if power off)',
+            1 => 'Previous',
+            2 => 'Top',
+        },
+    },
+    12 => {
+        Name => 'MirrorLockup',
+        PrintConv => \%disableEnable,
+    },
+    13 => {
+        Name => 'AFPointSelectionMethod',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Multi-controller direct',
+            2 => 'Quick Control Dial direct',
+        },
+    },
+    14 => {
+        Name => 'ETTLII',
+        Description => 'E-TTL II',
+        PrintConv => {
+            0 => 'Evaluative',
+            1 => 'Average',
+        },
+    },
+    15 => {
+        Name => 'ShutterCurtainSync',
+        PrintConv => {
+            0 => '1st-curtain sync',
+            1 => '2nd-curtain sync',
+        },
+    },
+    16 => {
+        Name => 'SafetyShiftInAvOrTv',
+        PrintConv => \%disableEnable,
+    },
+    17 => {
+        Name => 'AFPointActivationArea',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Expanded',
+        },
+    },
+    18 => {
+        Name => 'LCDDisplayReturnToShoot',
+        PrintConv => {
+            0 => 'With Shutter Button only',
+            1 => 'Also with * etc.',
+        },
+    },
+    19 => {
+        Name => 'LensAFStopButton',
+        PrintConv => {
+            0 => 'AF stop',
+            1 => 'AF start',
+            2 => 'AE lock while metering',
+            3 => 'AF point: M -> Auto / Auto -> Ctr.',
+            4 => 'ONE SHOT <-> AI SERVO',
+            5 => 'IS start',
+        },
+    },
+    20 => {
+        Name => 'AddOriginalDecisionData',
+        PrintConv => \%offOn,
+    },
+);
+
+# Custom functions for 10D
+%Image::ExifTool::CanonCustom::Functions10D = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessCanonCustom,
+    WRITE_PROC => \&WriteCanonCustom,
+    CHECK_PROC => \&CheckCanonCustom,
+    WRITABLE => 'int8u',
+    1 => {
+        Name => 'SetButtonFunction',
+        PrintConv => {
+            0 => 'Not assigned',
+            1 => 'Change quality',
+            2 => 'Change parameters',
+            3 => 'Menu display',
+            4 => 'Image replay',
+        },
+    },
+    2 => {
+        Name => 'ShutterReleaseNoCFCard',
+        Description => 'Shutter Release W/O CF Card',
+        PrintConv => {
+            0 => 'Yes',
+            1 => 'No',
+        },
+    },
+    3 => {
+        Name => 'FlashSyncSpeedAv',
+        PrintConv => {
+            0 => 'Auto',
+            1 => '1/200 Fixed',
+        },
+    },
+    4 => {
+        Name => 'Shutter-AELock',
+        PrintConv => {
+            0 => 'AF/AE lock',
+            1 => 'AE lock/AF',
+            2 => 'AF/AF lock, No AE lock',
+            3 => 'AE/AF, No AE lock',
+        },
+    },
+    5 => {
+        Name => 'AFAssist',
+        Description => 'AF Assist/Flash Firing',
+        PrintConv => {
+            0 => 'Emits/Fires',
+            1 => 'Does not emit/Fires',
+            2 => 'Only ext. flash emits/Fires',
+            3 => 'Emits/Does not fire',
+        },
+    },
+    6 => {
+        Name => 'ExposureLevelIncrements',
+        PrintConv => {
+            0 => '1/2 Stop',
+            1 => '1/3 Stop',
+        },
+    },
+    7 => {
+        Name => 'AFPointRegistration',
+        PrintConv => {
+            0 => 'Center',
+            1 => 'Bottom',
+            2 => 'Right',
+            3 => 'Extreme Right',
+            4 => 'Automatic',
+            5 => 'Extreme Left',
+            6 => 'Left',
+            7 => 'Top',
+        },
+    },
+    8 => {
+        Name => 'RawAndJpgRecording',
+        PrintConv => {
+            0 => 'RAW+Small/Normal',
+            1 => 'RAW+Small/Fine',
+            2 => 'RAW+Medium/Normal',
+            3 => 'RAW+Medium/Fine',
+            4 => 'RAW+Large/Normal',
+            5 => 'RAW+Large/Fine',
+        },
+    },
+    9 => {
+        Name => 'AEBSequence',
+        PrintConv => {
+            0 => '0,-,+/Enabled',
+            1 => '0,-,+/Disabled',
+            2 => '-,0,+/Enabled',
+            3 => '-,0,+/Disabled',
+        },
+    },
+    10 => {
+        Name => 'SuperimposedDisplay',
+        PrintConv => \%onOff,
+    },
+    11 => {
+        Name => 'MenuButtonDisplayPosition',
+        PrintConv => {
+            0 => 'Previous (top if power off)',
+            1 => 'Previous',
+            2 => 'Top',
+        },
+    },
+    12 => {
+        Name => 'MirrorLockup',
+        PrintConv => \%disableEnable,
+    },
+    13 => {
+        Name => 'AssistButtonFunction',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Select Home Position',
+            2 => 'Select HP (while pressing)',
+            3 => 'Av+/- (AF point by QCD)',
+            4 => 'FE lock',
+        },
+    },
+    14 => {
+        Name => 'FillFlashAutoReduction',
+        PrintConv => \%enableDisable,
+    },
+    15 => {
+        Name => 'ShutterCurtainSync',
+        PrintConv => {
+            0 => '1st-curtain sync',
+            1 => '2nd-curtain sync',
+        },
+    },
+    16 => {
+        Name => 'SafetyShiftInAvOrTv',
+        PrintConv => \%disableEnable,
+    },
+    17 => {
+        Name => 'LensAFStopButton',
+        PrintConv => {
+            0 => 'AF Stop',
+            1 => 'Operate AF',
+            2 => 'Lock AE and start timer',
+        },
+    },
+);
+
+# Custom functions for the 20D (ref 2)
+%Image::ExifTool::CanonCustom::Functions20D = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessCanonCustom,
+    WRITE_PROC => \&WriteCanonCustom,
+    CHECK_PROC => \&CheckCanonCustom,
+    WRITABLE => 'int8u',
+    0 => {
+        Name => 'SetFunctionWhenShooting',
+        PrintConv => {
+            0 => 'Default (no function)',
+            1 => 'Change quality',
+            2 => 'Change Parameters',
+            3 => 'Menu display',
+            4 => 'Image replay',
+        },
+    },
+    1 => {
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => \%offOn,
+    },
+    2 => {
+        Name => 'FlashSyncSpeedAv',
+        PrintConv => {
+            0 => 'Auto',
+            1 => '1/250 Fixed',
+        },
+    },
+    3 => {
+        Name => 'Shutter-AELock',
+        PrintConv => {
+            0 => 'AF/AE lock',
+            1 => 'AE lock/AF',
+            2 => 'AF/AF lock, No AE lock',
+            3 => 'AE/AF, No AE lock',
+        },
+    },
+    4 => {
+        Name => 'AFAssistBeam',
+        PrintConv => {
+            0 => 'Emits',
+            1 => 'Does not emit',
+            2 => 'Only ext. flash emits',
+        },
+    },
+    5 => {
+        Name => 'ExposureLevelIncrements',
+        PrintConv => {
+            0 => '1/3 Stop',
+            1 => '1/2 Stop',
+        },
+    },
+    6 => {
+        Name => 'FlashFiring',
+        PrintConv => {
+            0 => 'Fires',
+            1 => 'Does not fire',
+        },
+    },
+    7 => {
+        Name => 'ISOExpansion',
+        PrintConv => \%offOn,
+    },
+    8 => {
+        Name => 'AEBSequence',
+        PrintConv => {
+            0 => '0,-,+/Enabled',
+            1 => '0,-,+/Disabled',
+            2 => '-,0,+/Enabled',
+            3 => '-,0,+/Disabled',
+        },
+    },
+    9 => {
+        Name => 'SuperimposedDisplay',
+        PrintConv => \%onOff,
+    },
+    10 => {
+        Name => 'MenuButtonDisplayPosition',
+        PrintConv => {
+            0 => 'Previous (top if power off)',
+            1 => 'Previous',
+            2 => 'Top',
+        },
+    },
+    11 => {
+        Name => 'MirrorLockup',
+        PrintConv => \%disableEnable,
+    },
+    12 => {
+        Name => 'AFPointSelectionMethod',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Multi-controller direct',
+            2 => 'Quick Control Dial direct',
+        },
+    },
+    13 => {
+        Name => 'ETTLII',
+        Description => 'E-TTL II',
+        PrintConv => {
+            0 => 'Evaluative',
+            1 => 'Average',
+        },
+    },
+    14 => {
+        Name => 'ShutterCurtainSync',
+        PrintConv => {
+            0 => '1st-curtain sync',
+            1 => '2nd-curtain sync',
+        },
+    },
+    15 => {
+        Name => 'SafetyShiftInAvOrTv',
+        PrintConv => \%disableEnable,
+    },
+    16 => {
+        Name => 'LensAFStopButton',
+        PrintConv => {
+            0 => 'AF stop',
+            1 => 'AF start',
+            2 => 'AE lock while metering',
+            3 => 'AF point: M -> Auto / Auto -> Ctr.',
+            4 => 'ONE SHOT <-> AI SERVO',
+            5 => 'IS start',
+        },
+    },
+    17 => {
+        Name => 'AddOriginalDecisionData',
+        PrintConv => \%offOn,
+    },
+);
+
+# Custom functions for the 30D (PH)
+%Image::ExifTool::CanonCustom::Functions30D = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessCanonCustom,
+    WRITE_PROC => \&WriteCanonCustom,
+    CHECK_PROC => \&CheckCanonCustom,
+    WRITABLE => 'int8u',
+    1 => {
+        Name => 'SetFunctionWhenShooting',
+        PrintConv => {
+            0 => 'Default (no function)',
+            1 => 'Change quality',
+            2 => 'Change Picture Style',
+            3 => 'Menu display',
+            4 => 'Image replay',
+        },
+    },
+    2 => {
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'On',
+        },
+    },
+    3 => {
+        Name => 'FlashSyncSpeedAv',
+        PrintConv => {
+            0 => 'Auto',
+            1 => '1/250 Fixed',
+        },
+    },
+    4 => {
+        Name => 'Shutter-AELock',
+        PrintConv => {
+            0 => 'AF/AE lock',
+            1 => 'AE lock/AF',
+            2 => 'AF/AF lock, No AE lock',
+            3 => 'AE/AF, No AE lock',
+        },
+    },
+    5 => {
+        Name => 'AFAssistBeam',
+        PrintConv => {
+            0 => 'Emits',
+            1 => 'Does not emit',
+            2 => 'Only ext. flash emits',
+        },
+    },
+    6 => {
+        Name => 'ExposureLevelIncrements',
+        PrintConv => {
+            0 => '1/3 Stop',
+            1 => '1/2 Stop',
+        },
+    },
+    7 => {
+        Name => 'FlashFiring',
+        PrintConv => {
+            0 => 'Fires',
+            1 => 'Does not fire',
+        },
+    },
+    8 => {
+        Name => 'ISOExpansion',
+        PrintConv => \%offOn,
+    },
+    9 => {
+        Name => 'AEBSequence',
+        PrintConv => {
+            0 => '0,-,+/Enabled',
+            1 => '0,-,+/Disabled',
+            2 => '-,0,+/Enabled',
+            3 => '-,0,+/Disabled',
+        },
+    },
+    10 => {
+        Name => 'SuperimposedDisplay',
+        PrintConv => \%onOff,
+    },
+    11 => {
+        Name => 'MenuButtonDisplayPosition',
+        PrintConv => {
+            0 => 'Previous (top if power off)',
+            1 => 'Previous',
+            2 => 'Top',
+        },
+    },
+    12 => {
+        Name => 'MirrorLockup',
+        PrintConv => \%disableEnable,
+    },
+    13 => {
+        Name => 'AFPointSelectionMethod',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Multi-controller direct',
+            2 => 'Quick Control Dial direct',
+        },
+    },
+    14 => {
+        Name => 'ETTLII',
+        Description => 'E-TTL II',
+        PrintConv => {
+            0 => 'Evaluative',
+            1 => 'Average',
+        },
+    },
+    15 => {
+        Name => 'ShutterCurtainSync',
+        PrintConv => {
+            0 => '1st-curtain sync',
+            1 => '2nd-curtain sync',
+        },
+    },
+    16 => {
+        Name => 'SafetyShiftInAvOrTv',
+        PrintConv => \%disableEnable,
+    },
+    17 => {
+        Name => 'MagnifiedView',
+        PrintConv => {
+            0 => 'Image playback only',
+            1 => 'Image review and playback',
+        },
+    },
+    18 => {
+        Name => 'LensAFStopButton',
+        PrintConv => {
+            0 => 'AF stop',
+            1 => 'AF start',
+            2 => 'AE lock while metering',
+            3 => 'AF point: M -> Auto / Auto -> Ctr.',
+            4 => 'ONE SHOT <-> AI SERVO',
+            5 => 'IS start',
+        },
+    },
+    19 => {
+        Name => 'AddOriginalDecisionData',
+        PrintConv => \%offOn,
+    },
+);
+
+# Custom functions for the 350D (PH)
+%Image::ExifTool::CanonCustom::Functions350D = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessCanonCustom,
+    WRITE_PROC => \&WriteCanonCustom,
+    CHECK_PROC => \&CheckCanonCustom,
+    WRITABLE => 'int8u',
+    0 => {
+        Name => 'SetButtonCrossKeysFunc',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Set: Quality',
+            2 => 'Set: Parameter',
+            3 => 'Set: Playback',
+            4 => 'Cross keys: AF point select',
+        },
+    },
+    1 => {
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => \%offOn,
+    },
+    2 => {
+        Name => 'FlashSyncSpeedAv',
+        PrintConv => {
+            0 => 'Auto',
+            1 => '1/200 Fixed',
+        },
+    },
+    3 => {
+        Name => 'Shutter-AELock',
+        PrintConv => {
+            0 => 'AF/AE lock',
+            1 => 'AE lock/AF',
+            2 => 'AF/AF lock, No AE lock',
+            3 => 'AE/AF, No AE lock',
+        },
+    },
+    4 => {
+        Name => 'AFAssistBeam',
+        PrintConv => {
+            0 => 'Emits',
+            1 => 'Does not emit',
+            2 => 'Only ext. flash emits',
+        },
+    },
+    5 => {
+        Name => 'ExposureLevelIncrements',
+        PrintConv => {
+            0 => '1/3 Stop',
+            1 => '1/2 Stop',
+        },
+    },
+    6 => {
+        Name => 'MirrorLockup',
+        PrintConv => \%disableEnable,
+    },
+    7 => {
+        Name => 'ETTLII',
+        Description => 'E-TTL II',
+        PrintConv => {
+            0 => 'Evaluative',
+            1 => 'Average',
+        },
+    },
+    8 => {
+        Name => 'ShutterCurtainSync',
+        PrintConv => {
+            0 => '1st-curtain sync',
+            1 => '2nd-curtain sync',
+        },
+    },
+);
+
+# Custom functions for the 400D (PH)
+%Image::ExifTool::CanonCustom::Functions400D = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessCanonCustom,
+    WRITE_PROC => \&WriteCanonCustom,
+    CHECK_PROC => \&CheckCanonCustom,
+    WRITABLE => 'int8u',
+    0 => {
+        Name => 'SetButtonCrossKeysFunc',
+        PrintConv => {
+            0 => 'Set: Picture Style',
+            1 => 'Set: Quality',
+            2 => 'Set: Flash Exposure Comp',
+            3 => 'Set: Playback',
+            4 => 'Cross keys: AF point select',
+        },
+    },
+    1 => {
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'On',
+        },
+    },
+    2 => {
+        Name => 'FlashSyncSpeedAv',
+        PrintConv => {
+            0 => 'Auto',
+            1 => '1/200 Fixed',
+        },
+    },
+    3 => {
+        Name => 'Shutter-AELock',
+        PrintConv => {
+            0 => 'AF/AE lock',
+            1 => 'AE lock/AF',
+            2 => 'AF/AF lock, No AE lock',
+            3 => 'AE/AF, No AE lock',
+        },
+    },
+    4 => {
+        Name => 'AFAssistBeam',
+        PrintConv => {
+            0 => 'Emits',
+            1 => 'Does not emit',
+            2 => 'Only ext. flash emits',
+        },
+    },
+    5 => {
+        Name => 'ExposureLevelIncrements',
+        PrintConv => {
+            0 => '1/3 Stop',
+            1 => '1/2 Stop',
+        },
+    },
+    6 => {
+        Name => 'MirrorLockup',
+        PrintConv => \%disableEnable,
+    },
+    7 => {
+        Name => 'ETTLII',
+        Description => 'E-TTL II',
+        PrintConv => {
+            0 => 'Evaluative',
+            1 => 'Average',
+        },
+    },
+    8 => {
+        Name => 'ShutterCurtainSync',
+        PrintConv => {
+            0 => '1st-curtain sync',
+            1 => '2nd-curtain sync',
+        },
+    },
+    9 => {
+        Name => 'MagnifiedView',
+        PrintConv => {
+            0 => 'Image playback only',
+            1 => 'Image review and playback',
+        },
+    },
+    10 => {
+        Name => 'LCDDisplayAtPowerOn',
+        PrintConv => {
+            0 => 'Display',
+            1 => 'Retain power off status',
+        },
+    },
+);
+
+# Custom functions for the D30/D60
+%Image::ExifTool::CanonCustom::FunctionsD30 = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessCanonCustom,
+    WRITE_PROC => \&WriteCanonCustom,
+    CHECK_PROC => \&CheckCanonCustom,
+    NOTES => 'Custom functions for the EOS-D30 and D60.',
+    WRITABLE => 'int8u',
+    1 => {
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => \%offOn,
+    },
+    2 => {
+        Name => 'Shutter-AELock',
+        PrintConv => {
+            0 => 'AF/AE lock',
+            1 => 'AE lock/AF',
+            2 => 'AF/AF lock',
+            3 => 'AE+release/AE+AF',
+        },
+    },
+    3 => {
+        Name => 'MirrorLockup',
+        PrintConv => \%disableEnable,
+    },
+    4 => {
+        Name => 'ExposureLevelIncrements',
+        PrintConv => {
+            0 => '1/2 Stop',
+            1 => '1/3 Stop',
+        },
+    },
+    5 => {
+        Name => 'AFAssist',
+        PrintConv => {
+            0 => 'Emits/Fires',
+            1 => 'Does not emit/Fires',
+            2 => 'Only ext. flash emits/Fires',
+            3 => 'Emits/Does not fire',
+        },
+    },
+    6 => {
+        Name => 'FlashSyncSpeedAv',
+        PrintConv => {
+            0 => 'Auto',
+            1 => '1/200 Fixed',
+        },
+    },
+    7 => {
+        Name => 'AEBSequence',
+        PrintConv => {
+            0 => '0,-,+/Enabled',
+            1 => '0,-,+/Disabled',
+            2 => '-,0,+/Enabled',
+            3 => '-,0,+/Disabled',
+        },
+    },
+    8 => {
+        Name => 'ShutterCurtainSync',
+        PrintConv => {
+            0 => '1st-curtain sync',
+            1 => '2nd-curtain sync',
+        },
+    },
+    9 => {
+        Name => 'LensAFStopButton',
+        PrintConv => {
+            0 => 'AF Stop',
+            1 => 'Operate AF',
+            2 => 'Lock AE and start timer',
+        },
+    },
+    10 => {
+        Name => 'FillFlashAutoReduction',
+        PrintConv => \%enableDisable,
+    },
+    11 => {
+        Name => 'MenuButtonReturn',
+        PrintConv => {
+            0 => 'Top',
+            1 => 'Previous (volatile)',
+            2 => 'Previous',
+        },
+    },
+    12 => {
+        Name => 'SetButtonFunction',
+        PrintConv => {
+            0 => 'Not assigned',
+            1 => 'Change quality',
+            2 => 'Change ISO speed',
+            3 => 'Select parameters',
+        },
+    },
+    13 => {
+        Name => 'SensorCleaning',
+        PrintConv => \%disableEnable,
+    },
+    14 => {
+        Name => 'SuperimposedDisplay',
+        PrintConv => \%onOff,
+    },
+    15 => {
+        Name => 'ShutterReleaseNoCFCard',
+        Description => 'Shutter Release W/O CF Card',
+        PrintConv => {
+            0 => 'Yes',
+            1 => 'No',
+        },
+    },
+);
+
+# Custom functions for unknown cameras
+%Image::ExifTool::CanonCustom::FuncsUnknown = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessCanonCustom,
+);
+
+# 1D personal function settings (ref PH)
+%Image::ExifTool::CanonCustom::PersonalFuncs = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    NOTES => 'Personal function settings for the EOS-1D.',
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 1,
+    1 => { Name => 'PF0CustomFuncRegistration', %convPFn },
+    2 => { Name => 'PF1DisableShootingModes',   %convPFn },
+    3 => { Name => 'PF2DisableMeteringModes',   %convPFn },
+    4 => { Name => 'PF3ManualExposureMetering', %convPFn },
+    5 => { Name => 'PF4ExposureTimeLimits',     %convPFn },
+    6 => { Name => 'PF5ApertureLimits',         %convPFn },
+    7 => { Name => 'PF6PresetShootingModes',    %convPFn },
+    8 => { Name => 'PF7BracketContinuousShoot', %convPFn },
+    9 => { Name => 'PF8SetBracketShots',        %convPFn },
+    10 => { Name => 'PF9ChangeBracketSequence', %convPFn },
+    11 => { Name => 'PF10RetainProgramShift',   %convPFn },
+    #12 => { Name => 'PF11Unused',               %convPFn },
+    #13 => { Name => 'PF12Unused',               %convPFn },
+    14 => { Name => 'PF13DrivePriority',        %convPFn },
+    15 => { Name => 'PF14DisableFocusSearch',   %convPFn },
+    16 => { Name => 'PF15DisableAFAssistBeam',  %convPFn },
+    17 => { Name => 'PF16AutoFocusPointShoot',  %convPFn },
+    18 => { Name => 'PF17DisableAFPointSel',    %convPFn },
+    19 => { Name => 'PF18EnableAutoAFPointSel', %convPFn },
+    20 => { Name => 'PF19ContinuousShootSpeed', %convPFn },
+    21 => { Name => 'PF20LimitContinousShots',  %convPFn },
+    22 => { Name => 'PF21EnableQuietOperation', %convPFn },
+    #23 => { Name => 'PF22Unused',               %convPFn },
+    24 => { Name => 'PF23SetTimerLengths',      %convPFn },
+    25 => { Name => 'PF24LightLCDDuringBulb',   %convPFn },
+    26 => { Name => 'PF25DefaultClearSettings', %convPFn },
+    27 => { Name => 'PF26ShortenReleaseLag',    %convPFn },
+    28 => { Name => 'PF27ReverseDialRotation',  %convPFn },
+    29 => { Name => 'PF28NoQuickDialExpComp',   %convPFn },
+    30 => { Name => 'PF29QuickDialSwitchOff',   %convPFn },
+    31 => { Name => 'PF30EnlargementMode',      %convPFn },
+    32 => { Name => 'PF31OriginalDecisionData', %convPFn },
+);
+
+# 1D personal function values (ref PH)
+%Image::ExifTool::CanonCustom::PersonalFuncValues = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 1,
+    1 => 'PF1Value',
+    2 => 'PF2Value',
+    3 => 'PF3Value',
+    4 => {
+        Name => 'PF4ExposureTimeMin',
+        RawConv => '$val > 0 ? $val : 0',
+        ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val*4)*log(2))*1000/8',
+        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val*8/1000)/log(2))/4',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    5 => {
+        Name => 'PF4ExposureTimeMax',
+        RawConv => '$val > 0 ? $val : 0',
+        ValueConv => 'exp(-Image::ExifTool::Canon::CanonEv($val*4)*log(2))*1000/8',
+        ValueConvInv => 'Image::ExifTool::Canon::CanonEvInv(-log($val*8/1000)/log(2))/4',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    6 => {
+        Name => 'PF5ApertureMin',
+        RawConv => '$val > 0 ? $val : 0',
+        ValueConv => 'exp(Image::ExifTool::Canon::CanonEv($val*4-32)*log(2)/2)',
+        ValueConvInv => '(Image::ExifTool::Canon::CanonEvInv(log($val)*2/log(2))+32)/4',
+        PrintConv => 'sprintf("%.2g",$val)',
+        PrintConvInv => '$val',
+    },
+    7 => {
+        Name => 'PF5ApertureMax',
+        RawConv => '$val > 0 ? $val : 0',
+        ValueConv => 'exp(Image::ExifTool::Canon::CanonEv($val*4-32)*log(2)/2)',
+        ValueConvInv => '(Image::ExifTool::Canon::CanonEvInv(log($val)*2/log(2))+32)/4',
+        PrintConv => 'sprintf("%.2g",$val)',
+        PrintConvInv => '$val',
+    },
+    8 => 'PF8BracketShots',
+    9 => 'PF19ShootingSpeedLow',
+    10 => 'PF19ShootingSpeedHigh',
+    11 => 'PF20MaxContinousShots',
+    12 => 'PF23ShutterButtonTime',
+    13 => 'PF23FELockTime',
+    14 => 'PF23PostReleaseTime',
+    15 => 'PF25AEMode',
+    16 => 'PF25MeteringMode',
+    17 => 'PF25DriveMode',
+    18 => 'PF25AFMode',
+    19 => 'PF25AFPointSel',
+    20 => 'PF25ImageSize',
+    21 => 'PF25WBMode',
+    22 => 'PF25Parameters',
+    23 => 'PF25ColorMatrix',
+    24 => 'PF27Value',
+);
+
+# Custom functions used by the 1D Mark III and later models (ref PH)
+%Image::ExifTool::CanonCustom::Functions2 = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessCanonCustom2,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITE_PROC => \&WriteCanonCustom2,
+    WRITABLE => 'int32s',
+    NOTES => q{
+        Beginning with the EOS 1D Mark III, Canon finally created a set of custom
+        function tags which are consistent across models.  The EOS 1D Mark III has
+        57 custom function tags divided into four main groups: 1. Exposure
+        (0x0101-0x010f), 2. Image (0x0201-0x0203), Flash Exposure (0x0304-0x0306)
+        and Display (0x0407-0x0409), 3. Auto Focus (0x0501-0x050e) and Drive
+        (0x060f-0x0611), and 4. Operation (0x0701-0x070a) and Others
+        (0x080b-0x0810).  The table below lists tags used by the EOS 1D Mark III, as
+        well as newer values and tags used by the EOS 40D.  It is expected that
+        future models will re-use some of these tags (possibly with minor value
+        changes), as well as defining additional new tags of their own.
+    },
+    # grouped in 4 groups:
+    # 1) Exposure
+    0x0101 => [
+        {
+            Name => 'ExposureLevelIncrements',
+            Condition => '$$self{CameraModel} =~ /\b40D\b/',
+            Notes => '40D',
+            PrintConv => {
+                0 => '1/3 Stop',
+                1 => '1/2 Stop',
+            },
+        },
+        {
+            Name => 'ExposureLevelIncrements',
+            Notes => '1D Mark III',
+            PrintConv => {
+                0 => '1/3-stop set, 1/3-stop comp.',
+                1 => '1-stop set, 1/3-stop comp.',
+                2 => '1/2-stop set, 1/2-stop comp.',
+            },
+        },
+    ],
+    0x0102 => {
+        Name => 'ISOSpeedIncrements',
+        PrintConv => {
+            0 => '1/3-stop',
+            1 => '1-stop',
+        },
+    },
+    0x0103 => [
+        {
+            Name => 'ISOExpansion',
+            Condition => '$$self{CameraModel} =~ /\b40D\b/',
+            Notes => '40D',
+            PrintConv => {
+                0 => 'Off',
+                1 => 'On',
+            },
+        },
+        {
+            Name => 'ISOSpeedRange',
+            Notes => '1D Mark III',
+            Count => 3,
+            # (this decoding may not be valid for CR2 images?)
+            ValueConv => [
+                undef,
+                '$val < 1000 ? exp(($val/8-9)*log(2))*100 : 0', # (educated guess)
+                '$val < 1000 ? exp(($val/8-9)*log(2))*100 : 0', # (educated guess)
+            ],
+            ValueConvInv => [
+                undef,
+                '$val ? int(8*(log($val/100)/log(2)+9) + 0.5) : 0xffffffff',
+                '$val ? int(8*(log($val/100)/log(2)+9) + 0.5) : 0xffffffff',
+            ],
+            PrintConv => [
+                \%disableEnable,
+                'sprintf("Max %.0f",$val)',
+                'sprintf("Min %.0f",$val)',
+            ],
+            PrintConvInv => [
+                undef,
+                '$val=~/([\d.]+)/ ? $1 : 0',
+                '$val=~/([\d.]+)/ ? $1 : 0',
+            ],
+        },
+    ],
+    0x0104 => {
+        Name => 'AEBAutoCancel',
+        PrintConv => \%onOff,
+    },
+    0x0105 => {
+        Name => 'AEBSequence',
+        Notes => 'value of 2 not used by 40D',
+        PrintConv => {
+            0 => '0,-,+',
+            1 => '-,0,+',
+            2 => '+,0,-',
+        },
+    },
+    0x0106 => {
+        Name => 'AEBShotCount',
+        PrintConv => {
+            0 => 3,
+            1 => 2,
+            2 => 5,
+            3 => 7,
+        },
+    },
+    0x0107 => {
+        Name => 'SpotMeterLinkToAFPoint',
+        PrintConv => {
+            0 => 'Disable (use center AF point)',
+            1 => 'Enable (use active AF point)',
+        },
+    },
+    0x0108 => {
+        Name => 'SafetyShift',
+        Notes => 'value of 2 not used by 40D',
+        PrintConv => {
+            0 => 'Disable',
+            1 => 'Enable (Tv/Av)',
+            2 => 'Enable (ISO speed)',
+        },
+    },
+    0x0109 => {
+        Name => 'UsableShootingModes',
+        Count => 2,
+        PrintConv => [
+            \%disableEnable,
+            'sprintf("Flags 0x%x",$val)', # (M, Tv, Av, P, Bulb)
+        ],
+        PrintConvInv => [
+            undef,
+            '$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
+        ],
+    },
+    0x010a => {
+        Name => 'UsableMeteringModes',
+        Count => 2,
+        PrintConv => [
+            \%disableEnable,
+            'sprintf("Flags 0x%x",$val)', # (evaluative,partial,spot,center-weighted average)
+        ],
+        PrintConvInv => [
+            undef,
+            '$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
+        ],
+    },
+    0x010b => {
+        Name => 'ExposureModeInManual',
+        PrintConv => {
+            0 => 'Specified metering mode',
+            1 => 'Evaluative metering',
+            2 => 'Partial metering',
+            3 => 'Spot metering',
+            4 => 'Center-weighted average',
+        },
+    },
+    0x010c => {
+        Name => 'ShutterSpeedRange',
+        Count => 3,
+        ValueConv => [
+            undef,
+            'exp(-($val/8-7)*log(2))',
+            'exp(-($val/8-7)*log(2))',
+        ],
+        ValueConvInv => [
+            undef,
+            'int(-8*(log($val)/log(2)-7) + 0.5)',
+            'int(-8*(log($val)/log(2)-7) + 0.5)',
+        ],
+        PrintConv => [
+            \%disableEnable,
+            '"Hi " . Image::ExifTool::Exif::PrintExposureTime($val)',
+            '"Lo " . Image::ExifTool::Exif::PrintExposureTime($val)',
+        ],
+        PrintConvInv => [
+            undef,
+            '$val=~m{([\d./]+)} ? eval $1 : 0',
+            '$val=~m{([\d./]+)} ? eval $1 : 0',
+        ],
+    },
+    0x010d => {
+        Name => 'ApertureRange',
+        Count => 3,
+        ValueConv => [
+            undef,
+            'exp(($val/8-1)*log(2)/2)',
+            'exp(($val/8-1)*log(2)/2)',
+        ],
+        ValueConvInv => [
+            undef,
+            'int(8*(log($val)*2/log(2)+1) + 0.5)',
+            'int(8*(log($val)*2/log(2)+1) + 0.5)',
+        ],
+        PrintConv => [
+            \%disableEnable,
+            'sprintf("Closed %.2g",$val)',
+            'sprintf("Open %.2g",$val)',
+        ],
+        PrintConvInv => [
+            undef,
+            '$val=~/([\d.]+)/ ? $1 : 0',
+            '$val=~/([\d.]+)/ ? $1 : 0',
+        ],
+    },
+    0x010e => {
+        Name => 'ApplyShootingMeteringMode',
+        Count => 8,
+        PrintConv => [
+            \%disableEnable,
+        ],
+    },
+    0x010f => [
+        {
+            Name => 'FlashSyncSpeedAv',
+            Condition => '$$self{CameraModel} =~ /\b40D\b/',
+            Notes => '40D',
+            PrintConv => {
+                0 => 'Auto',
+                1 => '1/250 Fixed',
+            },
+        },
+        {
+            Name => 'FlashSyncSpeedAv',
+            Notes => '1D Mark III',
+            PrintConv => {
+                0 => 'Auto',
+                1 => '1/300 Fixed',
+            },
+        },
+    ],
+    #### 2a) Image
+    0x0201 => {
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'On',
+        },
+    },
+    0x0202 => {
+        Name => 'HighISONoiseReduction',
+        PrintConv => \%offOn,
+    },
+    0x0203 => {
+        Name => 'HighlightTonePriority',
+        PrintConv => \%disableEnable
+    },
+    #### 2b) Flash exposure
+    0x0304 => {
+        Name => 'ETTLII',
+        Description => 'E-TTL II',
+        PrintConv => {
+            0 => 'Evaluative',
+            1 => 'Average',
+        },
+    },
+    0x0305 => {
+        Name => 'ShutterCurtainSync',
+        PrintConv => {
+            0 => '1st-curtain sync',
+            1 => '2nd-curtain sync',
+        },
+    },
+    0x0306 => {
+        Name => 'FlashFiring',
+        PrintConv => {
+            0 => 'Fires',
+            1 => 'Does not fire',
+        },
+    },
+    #### 2c) Display
+    0x0407 => {
+        Name => 'ViewInfoDuringExposure',
+        PrintConv => \%disableEnable,
+    },
+    0x0408 => {
+        Name => 'LCDIlluminationDuringBulb',
+        PrintConv => \%offOn,
+    },
+    0x0409 => {
+        Name => 'InfoButtonWhenShooting',
+        PrintConv => {
+            0 => 'Displays camera settings',
+            1 => 'Displays shooting functions',
+        },
+    },
+    #### 3a) Auto focus
+    0x0501 => {
+        Name => 'USMLensElectronicMF',
+        PrintConv => {
+            0 => 'Enable after one-shot AF',
+            1 => 'Disable after one-shot AF',
+            2 => 'Disable in AF mode',
+        },
+    },
+    0x0502 => {
+        Name => 'AIServoTrackingSensitivity',
+        PrintConv => {
+           -2 => 'Slow',
+           -1 => 'Medium Slow',
+            0 => 'Standard',
+            1 => 'Medium Fast',
+            2 => 'Fast',
+        },
+    },
+    0x0503 => {
+        Name => 'AIServoImagePriority',
+        PrintConv => {
+            0 => '1: AF, 2: Tracking',
+            1 => '1: AF, 2: Drive speed',
+            2 => '1: Release, 2: Drive speed',
+        },
+    },
+    0x0504 => {
+        Name => 'AIServoTrackingMethod',
+        PrintConv => {
+            0 => 'Main focus point priority',
+            1 => 'Continuous AF track priority',
+        },
+    },
+    0x0505 => {
+        Name => 'LensDriveNoAF',
+        PrintConv => {
+            0 => 'Focus search on',
+            1 => 'Focus search off',
+        },
+    },
+    0x0506 => {
+        Name => 'LensAFStopButton',
+        Notes => 'value of 6 not used by 40D',
+        PrintConv => {
+            0 => 'AF stop',
+            1 => 'AF start',
+            2 => 'AE lock',
+            3 => 'AF point: M->Auto/Auto->ctr',
+            4 => 'One Shot <-> AI servo',
+            5 => 'IS start',
+            6 => 'Switch to registered AF point',
+        },
+    },
+    0x0507 => {
+        Name => 'AFMicroadjustment',
+        Count => 5,
+        PrintConv => [
+            {
+                0 => 'Disable',
+                1 => 'Adjust all by same amount',
+                2 => 'Adjust by lens',
+            },
+            # DECODE OTHER VALUES
+        ],
+    },
+    0x0508 => {
+        Name => 'AFExpansionWithSelectedPoint',
+        PrintConv => {
+            0 => 'Disable',
+            1 => 'Enable (left/right assist points)',
+            2 => 'Enable (surrounding assist points)',
+        },
+    },
+    0x0509 => {
+        Name => 'SelectableAFPoint',
+        PrintConv => {
+            0 => '19 points',
+            1 => 'Inner 9 points',
+            2 => 'Outer 9 points',
+        },
+    },
+    0x050a => {
+        Name => 'SwitchToRegisteredAFPoint',
+        PrintConv => \%disableEnable,
+    },
+    0x050b => {
+        Name => 'AFPointAutoSelection',
+        PrintConv => {
+            0 => 'Control-direct:disable/Main:enable',
+            1 => 'Control-direct:disable/Main:disable',
+            2 => 'Control-direct:enable/Main:enable',
+        },
+    },
+    0x050c => {
+        Name => 'AFPointDisplayDuringFocus',
+        PrintConv => {
+            0 => 'On',
+            1 => 'Off',
+            2 => 'On (when focus achieved)',
+        },
+    },
+    0x050d => {
+        Name => 'AFPointBrightness',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Brighter',
+        },
+    },
+    0x050e => {
+        Name => 'AFAssistBeam',
+        Notes => 'value of 2 not used by 1D Mark III',
+        PrintConv => {
+            0 => 'Emits',
+            1 => 'Does not emit',
+            2 => 'Only ext. flash emits',
+        },
+    },
+    0x050f => { # new for 40D
+        Name => 'AFPointSelectionMethod',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Multi-controller direct',
+            2 => 'Quick Control Dial direct',
+        },
+    },
+    0x0510 => { # new for 40D
+        Name => 'SuperimposedDisplay',
+        PrintConv => \%onOff,
+    },
+    0x0511 => { # new for 40D
+        Name => 'AFDuringLiveView',
+        PrintConv => \%disableEnable,
+    },
+    #### 3b) Drive
+    0x060f => {
+        Name => 'MirrorLockup',
+        Notes => 'value of 2 not used by 40D',
+        PrintConv => {
+            0 => 'Disable',
+            1 => 'Enable',
+            2 => 'Enable: Down with Set',
+        },
+    },
+    0x0610 => {
+        Name => 'ContinuousShootingSpeed',
+        Count => 3,
+        PrintConv => [
+            \%disableEnable,
+            '"Hi $val"',
+            '"Lo $val"',
+        ],
+        PrintConvInv => [
+            undef,
+            '$val=~/(\d+)/ ? $1 : 0',
+            '$val=~/(\d+)/ ? $1 : 0',
+        ],
+    },
+    0x0611 => {
+        Name => 'ContinuousShotLimit',
+        Count => 2,
+        PrintConv => [
+            \%disableEnable,
+            '"$val shots"',
+        ],
+        PrintConvInv => [
+            undef,
+            '$val=~/(\d+)/ ? $1 : 0',
+        ],
+    },
+    #### 4a) Operation
+    0x0701 => {
+        Name => 'ShutterButtonAFOnButton',
+        PrintConv => {
+            0 => 'Metering + AF start',
+            1 => 'Metering + AF start/AF stop',
+            2 => 'Metering start/Meter + AF start',
+            3 => 'AE lock/Metering + AF start',
+            4 => 'Metering + AF start / disable',
+        },
+    },
+    0x0702 => {
+        Name => 'AFOnAELockButtonSwitch',
+        PrintConv => \%disableEnable,
+    },
+    0x0703 => {
+        Name => 'QuickControlDialInMeter',
+        PrintConv => {
+            0 => 'Exposure comp/Aperture',
+            1 => 'AF point selection',
+            2 => 'ISO speed',
+        },
+    },
+    0x0704 => [
+        {
+            Name => 'SetButtonWhenShooting',
+            Condition => '$$self{CameraModel} =~ /\b40D\b/',
+            Notes => '40D',
+            PrintConv => {
+                0 => 'Normal (disabled)',
+                1 => 'Image quality',
+                2 => 'Picture style',
+                3 => 'Menu display',
+                4 => 'Image playback',
+            },
+        },
+        {
+            Name => 'SetButtonWhenShooting',
+            Notes => '1D Mark III',
+            PrintConv => {
+                0 => 'Normal (disabled)',
+                1 => 'White balance',
+                2 => 'Image size',
+                3 => 'ISO speed',
+                4 => 'Picture style',
+                5 => 'Record func. + media/folder',
+                6 => 'Menu display',
+                7 => 'Image playback',
+            },
+        },
+    ],
+    0x0705 => {
+        Name => 'ManualTv',
+        Description => 'Manual Tv/Av For M',
+        PrintConv => {
+            0 => 'Tv=Main/Av=Control',
+            1 => 'Tv=Control/Av=Main',
+        },
+    },
+    0x0706 => {
+        Name => 'DialDirectionTvAv',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Reversed',
+        },
+    },
+    0x0707 => {
+        Name => 'AvSettingWithoutLens',
+        PrintConv => \%disableEnable,
+    },
+    0x0708 => {
+        Name => 'WBMediaImageSizeSetting',
+        PrintConv => {
+            0 => 'Rear LCD panel',
+            1 => 'LCD monitor',
+        },
+    },
+    0x0709 => {
+        Name => 'LockMicrophoneButton',
+        PrintConv => {
+            0 => 'Protect (holding:sound rec.)',
+            1 => 'Sound rec. (protect:disable)',
+        },
+    },
+    0x070a => {
+        Name => 'ButtonFunctionControlOff',
+        PrintConv => {
+            0 => 'Normal (enable)',
+            1 => 'Disable main, Control, Multi-control',
+        },
+    },
+    #### 4b) Others
+    0x080b => [
+        {
+            Name => 'FocusingScreen',
+            Condition => '$$self{CameraModel} =~ /\b40D\b/',
+            Notes => '40D',
+            PrintConv => {
+                0 => 'Ef-A',
+                1 => 'Ef-D',
+                2 => 'Ef-S',
+            },
+        },
+        {
+            Name => 'FocusingScreen',
+            Notes => '1D Mark III',
+            PrintConv => {
+                0 => 'Ec-CIV',
+                1 => 'Ec-A,B,C,CII,CIII,D,H,I,L',
+                2 => 'Ec-S',
+                3 => 'Ec-N,R',
+            },
+        },
+    ],
+    0x080c => {
+        Name => 'TimerLength',
+        Count => 4,
+        PrintConv => [
+            \%disableEnable,
+            '"6 sec: $val"',
+            '"16 sec: $val"',
+            '"After release: $val"',
+        ],
+        PrintConvInv => [
+            undef,
+            '$val=~/(\d+)$/ ? $1 : 0',
+            '$val=~/(\d+)$/ ? $1 : 0',
+            '$val=~/(\d+)$/ ? $1 : 0',
+        ],
+    },
+    0x080d => {
+        Name => 'ShortReleaseTimeLag',
+        PrintConv => \%disableEnable,
+    },
+    0x080e => {
+        Name => 'AddAspectRatioInfo',
+        PrintConv => {
+            0 => 'Off',
+            1 => '6:6',
+            2 => '3:4',
+            3 => '4:5',
+            4 => '6:7',
+            5 => '10:12',
+            6 => '5:7',
+        },
+    },
+    0x080f => {
+        Name => 'AddOriginalDecisionData',
+        PrintConv => \%offOn,
+    },
+    0x0810 => {
+        Name => 'LiveViewExposureSimulation',
+        PrintConv => {
+            0 => 'Disable (LCD auto adjust)',
+            1 => 'Enable (simulates exposure)',
+        },
+    },
+);
+
+#------------------------------------------------------------------------------
+# Conversion routines
+# Inputs: 0) value to convert
+sub ConvertPfn($)
+{
+    my $val = shift;
+    return $val ? ($val==1 ? 'On' : "On ($val)") : "Off";
+}
+sub ConvertPfnInv($)
+{
+    my $val = shift;
+    return $1 if $val =~ /(\d+)/;
+    return  1 if $val =~ /on/i;
+    return  0 if $val =~ /off/i;
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Read/Write Canon custom 2 directory (used by 1D Mark III)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessCanonCustom2($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $offset = $$dirInfo{DirStart};
+    my $size = $$dirInfo{DirLen};
+    my $write = $$dirInfo{Write};
+    my $verbose = $exifTool->Options('Verbose');
+    my $newTags;
+
+    # first entry in array must be the size
+    my $len = Get16u($dataPt, $offset);
+    unless ($len == $size and $len >= 8) {
+        $exifTool->Warn("Invalid CanonCustom2 data");
+        return 0;
+    }
+    # get group count
+    my $count = Get32u($dataPt, $offset + 4);
+    if ($write) {
+        $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+        $exifTool->VPrint(0, "  Rewriting CanonCustom2\n") if $verbose;
+    } elsif ($verbose) {
+        $exifTool->VerboseDir('CanonCustom2', $count);
+    }
+    my $pos = $offset + 8;
+    my $end = $offset + $size;
+    # loop through group records
+    for (; $pos<$end; ) {
+        last if $pos + 12 > $end;
+        my $recNum = Get32u($dataPt, $pos);
+        my $recLen = Get32u($dataPt, $pos + 4);
+        my $recCount = Get32u($dataPt, $pos + 8);
+        last if $recLen < 8;    # must be at least 8 bytes for recNum and recLen
+        $pos += 12;
+        my $recPos = $pos;
+        my $recEnd = $pos + $recLen;
+        if ($verbose and not $write) {
+            $exifTool->VerboseDir("CanonCustom2 group $recNum", $recCount);
+        }
+        my ($i, $num, $tag);
+        for ($i=0; $recPos + 8 < $recEnd; ++$i, $recPos+=4*$num) {
+            $tag = Get32u($dataPt, $recPos);
+            $num = Get32u($dataPt, $recPos + 4);
+            $recPos += 8;
+            last if $recPos + $num * 4 > $recEnd;
+            my $val = ReadValue($dataPt, $recPos, 'int32s', $num, $num * 4);
+            if ($write) {
+                # write new value
+                my $tagInfo = $$newTags{$tag};
+                next unless $tagInfo;
+                my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+                next unless Image::ExifTool::IsOverwriting($newValueHash, $val);
+                my $newVal = Image::ExifTool::GetNewValues($newValueHash);
+                next unless defined $newVal;    # can't delete from a custom table
+                WriteValue($newVal, 'int32s', $num, $dataPt, $recPos);
+                if ($verbose > 1) {
+                    $exifTool->VPrint(0, "    - CanonCustom:$$tagInfo{Name} = '$val'\n",
+                                         "    + CanonCustom:$$tagInfo{Name} = '$newVal'\n");
+                }
+                ++$exifTool->{CHANGED};
+            } else {
+                # extract the value
+                my $oldInfo = $$tagTablePtr{$tag};
+                $exifTool->HandleTag($tagTablePtr, $tag, $val,
+                    Index  => $i,
+                    Format => 'int32u',
+                    Count  => $num,
+                    Size   => $num * 4,
+                );
+                my $tagInfo = $$tagTablePtr{$tag};
+                # generate properly formatted description if we just added the tag
+                if ($tagInfo and not $oldInfo) {
+                    ($$tagInfo{Description} = $$tagInfo{Name}) =~ tr/_/ /;
+                    $$tagInfo{Description} =~ s/CanonCustom Functions/Canon Custom Functions /;
+                }
+            }
+        }
+        $pos += $recLen - 8;
+    }
+    if ($pos != $end) {
+        $exifTool->Warn('Possibly corrupted CanonCustom2 data');
+        return 0;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Write Canon custom 2 data
+# Inputs: 0) ExifTool object reference, 1) dirInfo hash ref, 2) tag table ref
+# Returns: New custom data block or undefined on error
+sub WriteCanonCustom2($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    $exifTool or return 1;    # allow dummy access to autoload this package
+    my $dataPt = $$dirInfo{DataPt};
+    # edit a copy of the custom function 2 data
+    my $buff = substr($$dataPt, $$dirInfo{DirStart}, $$dirInfo{DirLen});
+    my %dirInfo = (
+        DataPt   => \$buff,
+        DirStart => 0,
+        DirLen   => $$dirInfo{DirLen},
+        Write    => 1,
+    );
+    ProcessCanonCustom2($exifTool, \%dirInfo, $tagTablePtr) or return undef;
+    return $buff;
+}
+
+#------------------------------------------------------------------------------
+# Process Canon custom directory
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessCanonCustom($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $offset = $$dirInfo{DirStart};
+    my $size = $$dirInfo{DirLen};
+    my $verbose = $exifTool->Options('Verbose');
+
+    # first entry in array must be the size
+    my $len = Get16u($dataPt,$offset);
+    unless ($len == $size or ($$exifTool{CameraModel}=~/\bD60\b/ and $len+2 == $size)) {
+        $exifTool->Warn("Invalid CanonCustom data");
+        return 0;
+    }
+    $verbose and $exifTool->VerboseDir('CanonCustom', $size/2-1);
+    my $pos;
+    for ($pos=2; $pos<$size; $pos+=2) {
+        # ($pos is position within custom directory)
+        my $val = Get16u($dataPt,$offset+$pos);
+        my $tag = ($val >> 8);
+        $val = ($val & 0xff);
+        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            Index  => $pos/2-1,
+            Format => 'int8u',
+            Count  => 1,
+            Size   => 1,
+        );
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Check new value for Canon custom data block
+# Inputs: 0) ExifTool object reference, 1) tagInfo hash ref, 2) raw value ref
+# Returns: error string or undef (and may modify value) on success
+sub CheckCanonCustom($$$)
+{
+    my ($exifTool, $tagInfo, $valPtr) = @_;
+    return Image::ExifTool::CheckValue($valPtr, 'int8u');
+}
+
+#------------------------------------------------------------------------------
+# Write Canon custom data
+# Inputs: 0) ExifTool object reference, 1) dirInfo hash ref, 2) tag table ref
+# Returns: New custom data block or undefined on error
+sub WriteCanonCustom($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    $exifTool or return 1;    # allow dummy access to autoload this package
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $dirStart;
+    my $dirName = $$dirInfo{DirName};
+    my $verbose = $exifTool->Options('Verbose');
+    my $newData = substr($$dataPt, $dirStart, $dirLen) or return undef;
+    $dataPt = \$newData;
+
+    # first entry in array must be the size
+    my $len = Get16u($dataPt, 0);
+    unless ($len == $dirLen or ($$exifTool{CameraModel}=~/\bD60\b/ and $len+2 == $dirLen)) {
+        $exifTool->Warn("Invalid CanonCustom data");
+        return undef;
+    }
+    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+    my $pos;
+    for ($pos=2; $pos<$dirLen; $pos+=2) {
+        my $val = Get16u($dataPt, $pos);
+        my $tag = ($val >> 8);
+        my $tagInfo = $$newTags{$tag};
+        next unless $tagInfo;
+        my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+        $val = ($val & 0xff);
+        next unless Image::ExifTool::IsOverwriting($newValueHash, $val);
+        my $newVal = Image::ExifTool::GetNewValues($newValueHash);
+        next unless defined $newVal;    # can't delete from a custom table
+        Set16u(($newVal & 0xff) + ($tag << 8), $dataPt, $pos);
+        if ($verbose > 1) {
+            $exifTool->VPrint(0, "    - $dirName:$$tagInfo{Name} = '$val'\n",
+                                 "    + $dirName:$$tagInfo{Name} = '$newVal'\n");
+        }
+        ++$exifTool->{CHANGED};
+    }
+    return $newData;
+}
+
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::CanonCustom - Read and Write Canon custom functions
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+The Canon custom functions meta information is very specific to the
+camera model, and is found in both the EXIF maker notes and in the
+Canon RAW files.  This module contains the definitions necessary for
+Image::ExifTool to read this information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html>
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Christian Koller for his work in decoding the 20D custom
+functions, and Rainer Honle for decoding the 5D custom functions.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Canon Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/CanonRaw.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/CanonRaw.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/CanonRaw.pm	(revision 20131)
@@ -0,0 +1,844 @@
+#------------------------------------------------------------------------------
+# File:         CanonRaw.pm
+#
+# Description:  Read Canon RAW (CRW) meta information
+#
+# Revisions:    11/25/2003 - P. Harvey Created
+#               12/02/2003 - P. Harvey Completely reworked and figured out many
+#                            more tags
+#               01/19/2004 - P. Harvey Added CleanRaw()
+#
+# References:   1) http://www.cybercom.net/~dcoffin/dcraw/
+#               2) http://www.wonderland.org/crw/
+#               3) http://xyrion.org/ciff/CIFFspecV1R04.pdf
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::CanonRaw;
+
+use strict;
+use vars qw($VERSION $AUTOLOAD %crwTagFormat);
+use Image::ExifTool qw(:DataAccess);
+use Image::ExifTool::Exif;
+use Image::ExifTool::Canon;
+
+$VERSION = '1.42';
+
+sub WriteCRW($$);
+sub ProcessCanonRaw($$$);
+sub WriteCanonRaw($$$);
+sub CheckCanonRaw($$$);
+sub InitMakerNotes($);
+sub SaveMakerNotes($);
+sub BuildMakerNotes($$$$$$);
+
+# formats for CRW tag types (($tag >> 8) & 0x38)
+# Note: don't define format for undefined types
+%crwTagFormat = (
+    0x00 => 'int8u',
+    0x08 => 'string',
+    0x10 => 'int16u',
+    0x18 => 'int32u',
+  # 0x20 => 'undef',
+  # 0x28 => 'undef',
+  # 0x30 => 'undef',
+);
+
+# Canon raw file tag table
+# Note: Tag ID's have upper 2 bits set to zero, since these 2 bits
+# just specify the location of the information
+%Image::ExifTool::CanonRaw::Main = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessCanonRaw,
+    WRITE_PROC => \&WriteCanonRaw,
+    CHECK_PROC => \&CheckCanonRaw,
+    WRITABLE => 1,
+    0x0000 => { Name => 'NullRecord', Writable => 'undef' }, #3
+    0x0001 => { #3
+        Name => 'FreeBytes',
+        Format => 'undef',
+        Binary => 1,
+    },
+    0x0032 => { Name => 'CanonColorInfo1', Writable => 0 },
+    0x0805 => [
+        # this tag is found in more than one directory...
+        {
+            Condition => '$self->{DIR_NAME} eq "ImageDescription"',
+            Name => 'CanonFileDescription',
+            Writable => 'string[32]',
+        },
+        {
+            Name => 'UserComment',
+            Writable => 'string[256]',
+        },
+    ],
+    0x080a => {
+        Name => 'CanonRawMakeModel',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::CanonRaw::MakeModel',
+        },
+    },
+    0x080b => { Name => 'CanonFirmwareVersion', Writable => 'string[32]' },
+    0x080c => { Name => 'ComponentVersion',     Writable => 'string'     }, #3
+    0x080d => { Name => 'ROMOperationMode',     Writable => 'string[8]'  }, #3
+    0x0810 => { Name => 'OwnerName',            Writable => 'string[32]' },
+    0x0815 => { Name => 'CanonImageType',       Writable => 'string[32]' },
+    0x0816 => { Name => 'OriginalFileName',     Writable => 'string[32]' },
+    0x0817 => { Name => 'ThumbnailFileName',    Writable => 'string[32]' },
+    0x100a => { #3
+        Name => 'TargetImageType',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Real-world Subject',
+            1 => 'Written Document',
+        },
+    },
+    0x1010 => { #3
+        Name => 'ShutterReleaseMethod',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Single Shot',
+            2 => 'Continuous Shooting',
+        },
+    },
+    0x1011 => { #3
+        Name => 'ShutterReleaseTiming',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Priority on shutter',
+            1 => 'Priority on focus',
+        },
+    },
+    0x1016 => { Name => 'ReleaseSetting',       Writable => 'int16u' }, #3
+    0x101c => { Name => 'BaseISO',              Writable => 'int16u' }, #3
+    0x1028=> { #PH
+        Name => 'CanonFlashInfo',
+        Writable => 'int16u',
+        Count => 4,
+        Unknown => 1,
+    },
+    0x1029 => {
+        Name => 'CanonFocalLength',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::FocalLength',
+        },
+    },
+    0x102a => {
+        Name => 'CanonShotInfo',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::ShotInfo',
+        },
+    },
+    0x102c => { Name => 'CanonColorInfo2', Writable => 0 },
+    0x102d => {
+        Name => 'CanonCameraSettings',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::CameraSettings',
+        },
+    },
+    0x1031 => {
+        Name => 'SensorInfo',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::SensorInfo',
+        },
+    },
+    # this tag has only be verified for the 10D in CRW files, but the D30 and D60
+    # also produce CRW images and have CustomFunction information in their JPEG's
+    0x1033 => [
+        {
+            Name => 'CustomFunctions10D',
+            Condition => '$self->{CameraModel} =~ /EOS 10D/',
+            SubDirectory => {
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+                TagTable => 'Image::ExifTool::CanonCustom::Functions10D',
+            },
+        },
+        {
+            Name => 'CustomFunctionsD30',
+            Condition => '$self->{CameraModel} =~ /EOS D30\b/',
+            SubDirectory => {
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+                TagTable => 'Image::ExifTool::CanonCustom::FunctionsD30',
+            },
+        },
+        {
+            Name => 'CustomFunctionsD60',
+            Condition => '$self->{CameraModel} =~ /EOS D60\b/',
+            SubDirectory => {
+                # the stored size in the D60 apparently doesn't include the size word:
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size-2,$size)',
+                # (D60 custom functions are basically the same as D30)
+                TagTable => 'Image::ExifTool::CanonCustom::FunctionsD30',
+            },
+        },
+        {
+            Name => 'CustomFunctionsUnknown',
+            SubDirectory => {
+                Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+                TagTable => 'Image::ExifTool::CanonCustom::FuncsUnknown',
+            },
+        },
+    ],
+    0x1038 => {
+        Name => 'CanonAFInfo',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::AFInfo',
+        },
+    },
+    0x1093 => {
+        Name => 'CanonFileInfo',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::FileInfo',
+        },
+    },
+    0x10a9 => {
+        Name => 'ColorBalance',
+        Writable => 0,
+        SubDirectory => {
+            # this offset is necessary because the table contains short rationals
+            # (4 bytes long) but the first entry is 2 bytes into the table.
+            Start => '2',
+            TagTable => 'Image::ExifTool::Canon::ColorBalance',
+        },
+    },
+    0x10b5 => { #PH
+        Name => 'RawJpgInfo',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::CanonRaw::RawJpgInfo',
+        },
+    },
+    0x10ae => {
+        Name => 'ColorTemperature',
+        Writable => 'int16u',
+    },
+    0x10b4 => {
+        Name => 'ColorSpace',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'sRGB',
+            2 => 'Adobe RGB',
+            0xffff => 'Uncalibrated',
+        },
+    },
+    0x1803 => { #3
+        Name => 'ImageFormat',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::CanonRaw::ImageFormat',
+        },
+    },
+    0x1804 => { Name => 'RecordID', Writable => 'int32u' }, #3
+    0x1806 => { #3
+        Name => 'SelfTimerTime',
+        Writable => 'int32u',
+        ValueConv => '$val / 1000',
+        ValueConvInv => '$val * 1000',
+        PrintConv => '"$val sec"',
+        PrintConvInv => '$val=~s/\s*sec.*//;$val',
+    },
+    0x1807 => {
+        Name => 'TargetDistanceSetting',
+        Format => 'float',
+        PrintConv => '"$val mm"',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
+    },
+    0x180b => {
+        Name => 'SerialNumber',
+        Writable => 'int32u',
+        Description => 'Camera Body No.',
+        PrintConv => 'sprintf("%.10d",$val)',
+        PrintConvInv => '$val',
+    },
+    0x180e => {
+        Name => 'TimeStamp',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::CanonRaw::TimeStamp',
+        },
+    },
+    0x1810 => {
+        Name => 'ImageInfo',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::CanonRaw::ImageInfo',
+        },
+    },
+    0x1813 => { #3
+        Name => 'FlashInfo',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::CanonRaw::FlashInfo',
+        },
+    },
+    0x1814 => { #3
+        Name => 'MeasuredEV',
+        Notes => q{
+            this the Canon name for what should properly be called MeasuredLV, and is
+            offset by about -5 EV from the calculated LV for most models
+        },
+        Format => 'float',
+    },
+    0x1817 => {
+        Name => 'FileNumber',
+        Writable => 'int32u',
+        Groups => { 2 => 'Image' },
+        PrintConv => '$_=$val;s/(\d+)(\d{4})/$1-$2/;$_',
+        PrintConvInv => '$_=$val;s/-//;$_',
+    },
+    0x1818 => { #3
+        Name => 'ExposureInfo',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::CanonRaw::ExposureInfo',
+        },
+    },
+    0x1834 => { #PH
+        Name => 'CanonModelID',
+        Writable => 'int32u',
+        PrintHex => 1,
+        Notes => q{
+            this is the complete list of model ID numbers, but note that many of these
+            models do not produce CRW images
+        },
+        SeparateTable => 'Canon CanonModelID',
+        PrintConv => \%Image::ExifTool::Canon::canonModelID,
+    },
+    0x1835 => {
+        Name => 'DecoderTable',
+        Writable => 0,
+    },
+    0x183b => { #PH
+        # display format for serial number
+        Name => 'SerialNumberFormat',
+        Writable => 'int32u',
+        PrintHex => 1,
+        PrintConv => {
+            0x90000000 => 'Format 1',
+            0xa0000000 => 'Format 2',
+        },
+    },
+    0x2005 => {
+        Name => 'RawData',
+        Writable => 0,
+        Binary => 1,
+    },
+    0x2007 => {
+        Name => 'JpgFromRaw',
+        Writable => 'resize',  # 'resize' allows this value to change size
+        Permanent => 0,
+        ValueConv => '$self->ValidateImage(\$val,$tag)',
+        ValueConvInv => '$val',
+    },
+    0x2008 => {
+        Name => 'ThumbnailImage',
+        Writable => 'resize',  # 'resize' allows this value to change size
+        WriteCheck => '$self->CheckImage(\$val)',
+        Permanent => 0,
+        ValueConv => '$self->ValidateImage(\$val,$tag)',
+        ValueConvInv => '$val',
+    },
+    # the following entries are subdirectories
+    # (any 0x28 and 0x30 tag types are handled automatically by the decoding logic)
+    0x2804 => {
+        Name => 'ImageDescription',
+        SubDirectory => { },
+        Writable => 0,
+    },
+    0x2807 => { #3
+        Name => 'CameraObject',
+        SubDirectory => { },
+        Writable => 0,
+    },
+    0x3002 => { #3
+        Name => 'ShootingRecord',
+        SubDirectory => { },
+        Writable => 0,
+    },
+    0x3003 => { #3
+        Name => 'MeasuredInfo',
+        SubDirectory => { },
+        Writable => 0,
+    },
+    0x3004 => { #3
+        Name => 'CameraSpecification',
+        SubDirectory => { },
+        Writable => 0,
+    },
+    0x300a => { #3
+        Name => 'ImageProps',
+        SubDirectory => { },
+        Writable => 0,
+    },
+    0x300b => {
+        Name => 'ExifInformation',
+        SubDirectory => { },
+        Writable => 0,
+    },
+);
+
+# Canon binary data blocks
+%Image::ExifTool::CanonRaw::MakeModel = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    DATAMEMBER => [ 0, 6 ], # indices of data members to extract when writing
+    WRITABLE => 1,
+    FORMAT => 'string',
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    # (can't specify a first entry because this isn't
+    # a simple binary table with fixed offsets)
+    0 => {
+        Name => 'Make',
+        Format => 'string[6]',  # "Canon\0"
+        DataMember => 'CameraMake',
+        RawConv => '$self->{CameraMake} = $val',
+    },
+    6 => {
+        Name => 'Model',
+        Format => 'string[$size-6]',
+        Description => 'Camera Model Name',
+        DataMember => 'CameraModel',
+        RawConv => '$self->{CameraModel} = $val',
+    },
+);
+
+%Image::ExifTool::CanonRaw::TimeStamp = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Time' },
+    0 => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Shift => 'Time',
+        ValueConv => 'ConvertUnixTime($val)',
+        ValueConvInv => 'GetUnixTime($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$val',
+    },
+    1 => { #3
+        Name => 'TimeZoneCode',
+        Format => 'int32s',
+        ValueConv => '$val / 3600',
+        ValueConvInv => '$val * 3600',
+    },
+    2 => { #3
+        Name => 'TimeZoneInfo',
+        Notes => 'set to 0x80000000 if TimeZoneCode is valid',
+    },
+);
+
+%Image::ExifTool::CanonRaw::ImageFormat = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0 => {
+        Name => 'FileFormat',
+        Flags => 'PrintHex',
+        PrintConv => {
+            0x00010000 => 'JPEG (lossy)',
+            0x00010002 => 'JPEG (non-quantization)',
+            0x00010003 => 'JPEG (lossy/non-quantization toggled)',
+            0x00020001 => 'CRW',
+        },
+    },
+    1 => {
+        Name => 'TargetCompressionRatio',
+        Format => 'float',
+    },
+);
+
+%Image::ExifTool::CanonRaw::RawJpgInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+#    0 => 'RawJpgInfoSize',
+    1 => { #PH
+        Name => 'RawJpgQuality',
+        PrintConv => {
+            1 => 'Economy',
+            2 => 'Normal',
+            3 => 'Fine',
+            5 => 'Superfine',
+        },
+    },
+    2 => { #PH
+        Name => 'RawJpgSize',
+        PrintConv => {
+            0 => 'Large',
+            1 => 'Medium',
+            2 => 'Small',
+        },
+    },
+    3 => 'RawJpgWidth', #PH
+    4 => 'RawJpgHeight', #PH
+);
+
+%Image::ExifTool::CanonRaw::FlashInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'float',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0 => 'FlashGuideNumber',
+    1 => 'FlashThreshold',
+);
+
+%Image::ExifTool::CanonRaw::ExposureInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'float',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0 => 'ExposureCompensation',
+    1 => 'TvValue',
+    2 => 'AvValue',
+);
+
+%Image::ExifTool::CanonRaw::ImageInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    # Note: Don't make these writable (except rotation) because it confuses
+    # Canon decoding software if the are changed
+    0 => 'ImageWidth', #3
+    1 => 'ImageHeight', #3
+    2 => { #3
+        Name => 'PixelAspectRatio',
+        Format => 'float',
+    },
+    3 => {
+        Name => 'Rotation',
+        Format => 'int32s',
+        Writable => 'int32s',
+    },
+    4 => 'ComponentBitDepth', #3
+    5 => 'ColorBitDepth', #3
+    6 => 'ColorBW', #3
+);
+
+#------------------------------------------------------------------------------
+# AutoLoad our writer routines when necessary
+#
+sub AUTOLOAD
+{
+    return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
+}
+
+#------------------------------------------------------------------------------
+# Process Raw file directory
+# Inputs: 0) ExifTool object reference
+#         1) directory information reference, 2) tag table reference
+# Returns: 1 on success
+sub ProcessCanonRaw($$$)
+{
+    my ($exifTool, $dirInfo, $rawTagTable) = @_;
+    my $blockStart = $$dirInfo{DirStart};
+    my $blockSize = $$dirInfo{DirLen};
+    my $raf = $$dirInfo{RAF} or return 0;
+    my $buff;
+    my $verbose = $exifTool->Options('Verbose');
+    my $buildMakerNotes = $exifTool->Options('MakerNotes');
+
+    # 4 bytes at end of block give directory position within block
+    $raf->Seek($blockStart+$blockSize-4, 0) or return 0;
+    $raf->Read($buff, 4) == 4 or return 0;
+    my $dirOffset = Get32u(\$buff,0) + $blockStart;
+    $raf->Seek($dirOffset, 0) or return 0;
+    $raf->Read($buff, 2) == 2 or return 0;
+    my $entries = Get16u(\$buff,0);         # get number of entries in directory
+    # read the directory (10 bytes per entry)
+    $raf->Read($buff, 10 * $entries) == 10 * $entries or return 0;
+
+    $verbose and $exifTool->VerboseDir('Raw', $entries);
+    my $index;
+    for ($index=0; $index<$entries; ++$index) {
+        my $pt = 10 * $index;
+        my $tag = Get16u(\$buff, $pt);
+        my $size = Get32u(\$buff, $pt+2);
+        my $valuePtr = Get32u(\$buff, $pt+6);
+        my $ptr = $valuePtr + $blockStart;  # all pointers relative to block start
+        if ($tag & 0x8000) {
+            $exifTool->Warn('Bad CRW directory entry');
+            return 1;
+        }
+        my $tagID = $tag & 0x3fff;          # get tag ID
+        my $tagType = ($tag >> 8) & 0x38;   # get tag type
+        my $valueInDir = ($tag & 0x4000);   # flag for value in directory
+        my $tagInfo = $exifTool->GetTagInfo($rawTagTable, $tagID);
+        if (($tagType==0x28 or $tagType==0x30) and not $valueInDir) {
+            # this type of tag specifies a raw subdirectory
+            my $name;
+            $tagInfo and $name = $$tagInfo{Name};
+            $name or $name = sprintf("CanonRaw_0x%.4x", $tag);
+            my %subdirInfo = (
+                DirName  => $name,
+                DataLen  => 0,
+                DirStart => $ptr,
+                DirLen   => $size,
+                Nesting  => $$dirInfo{Nesting} + 1,
+                RAF      => $raf,
+                Parent   => $$dirInfo{DirName},
+            );
+            if ($verbose) {
+                my $fakeInfo = { Name => $name, SubDirectory => { } };
+                $exifTool->VerboseInfo($tagID, $fakeInfo,
+                    'Index'  => $index,
+                    'Size'   => $size,
+                    'Start'  => $ptr,
+                );
+            }
+            $exifTool->ProcessDirectory(\%subdirInfo, $rawTagTable);
+            next;
+        }
+        my ($valueDataPos, $count, $subdir);
+        my $format = $crwTagFormat{$tagType};
+        if ($tagInfo) {
+            $subdir = $$tagInfo{SubDirectory};
+            $format = $$tagInfo{Format} if $$tagInfo{Format};
+            $count = $$tagInfo{Count};
+        }
+        # get value data
+        my ($value, $delRawConv);
+        if ($valueInDir) {  # is the value data in the directory?
+            # this type of tag stores the value in the 'size' and 'ptr' fields
+            $valueDataPos = $dirOffset + $pt + 4;
+            $size = 8;
+            $value = substr($buff, $pt+2, $size);
+            # set count to 1 by default for normal values in directory
+            $count = 1 if not defined $count and $format and
+                          $format ne 'string' and not $subdir;
+        } else {
+            $valueDataPos = $ptr;
+            if ($size <= 512 or ($verbose > 2 and $size <= 65536)
+                or ($tagInfo and ($$tagInfo{SubDirectory}
+                or grep(/^$$tagInfo{Name}$/i, $exifTool->GetRequestedTags()) )))
+            {
+                # read value if size is small or specifically requested
+                # or if this is a SubDirectory
+                unless ($raf->Seek($ptr, 0) and $raf->Read($value, $size) == $size) {
+                    $exifTool->Warn(sprintf("Error reading %d bytes from 0x%x",$size,$ptr));
+                    next;
+                }
+            } else {
+                $value = "Binary data $size bytes";
+                if ($tagInfo) {
+                    if ($exifTool->Options('Binary')) {
+                        # read the value anyway
+                        unless ($raf->Seek($ptr, 0) and $raf->Read($value, $size) == $size) {
+                            $exifTool->Warn(sprintf("Error reading %d bytes from 0x%x",$size,$ptr));
+                            next;
+                        }
+                    }
+                    # force this to be a binary (scalar reference)
+                    $$tagInfo{RawConv} = '\$val';
+                    $delRawConv = 1;
+                }
+                $size = length $value;
+                undef $format;
+            }
+        }
+        # set count from tagInfo count if necessary
+        if ($format and not $count) {
+            # set count according to format and size
+            my $fnum = $Image::ExifTool::Exif::formatNumber{$format};
+            my $fsiz = $Image::ExifTool::Exif::formatSize[$fnum];
+            $count = int($size / $fsiz);
+        }
+        if ($verbose) {
+            my $val = $value;
+            $format and $val = ReadValue(\$val, 0, $format, $count, $size);
+            $exifTool->VerboseInfo($tagID, $tagInfo,
+                Table   => $rawTagTable,
+                Index   => $index,
+                Value   => $val,
+                DataPt  => \$value,
+                DataPos => $valueDataPos,
+                Size    => $size,
+                Format  => $format,
+                Count   => $count,
+            );
+        }
+        if ($buildMakerNotes) {
+            # build maker notes information if requested
+            BuildMakerNotes($exifTool, $tagID, $tagInfo, \$value, $format, $count);
+        }
+        next unless defined $tagInfo;
+
+        if ($subdir) {
+            my $name = $$tagInfo{Name};
+            my $newTagTable;
+            if ($$subdir{TagTable}) {
+                $newTagTable = Image::ExifTool::GetTagTable($$subdir{TagTable});
+                unless ($newTagTable) {
+                    warn "Unknown tag table $$subdir{TagTable}\n";
+                    next;
+                }
+            } else {
+                warn "Must specify TagTable for SubDirectory $name\n";
+                next;
+            }
+            my $subdirStart = 0;
+            #### eval Start ()
+            $subdirStart = eval $$subdir{Start} if $$subdir{Start};
+            my $dirData = \$value;
+            my %subdirInfo = (
+                Name     => $name,
+                DataPt   => $dirData,
+                DataLen  => $size,
+                DataPos  => $valueDataPos,
+                DirStart => $subdirStart,
+                DirLen   => $size - $subdirStart,
+                Nesting  => $$dirInfo{Nesting} + 1,
+                RAF      => $raf,
+                Parent   => $$dirInfo{DirName},
+            );
+            #### eval Validate ($dirData, $subdirStart, $size)
+            if (defined $$subdir{Validate} and not eval $$subdir{Validate}) {
+                $exifTool->Warn("Invalid $name data");
+            } else {
+                $exifTool->ProcessDirectory(\%subdirInfo, $newTagTable, $$subdir{ProcessProc});
+            }
+        } else {
+            # convert to specified format if necessary
+            $format and $value = ReadValue(\$value, 0, $format, $count, $size);
+            # save the information
+            $exifTool->FoundTag($tagInfo, $value);
+            delete $$tagInfo{RawConv} if $delRawConv;
+        }
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# get information from raw file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 if this was a valid Canon RAW file
+sub ProcessCRW($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my ($buff, $sig);
+    my $raf = $$dirInfo{RAF};
+    my $buildMakerNotes = $exifTool->Options('MakerNotes');
+
+    $raf->Read($buff,2) == 2      or return 0;
+    SetByteOrder($buff)           or return 0;
+    $raf->Read($buff,4) == 4      or return 0;
+    $raf->Read($sig,8) == 8       or return 0;  # get file signature
+    $sig =~ /^HEAP(CCDR|JPGM)/    or return 0;  # validate signature
+    my $hlen = Get32u(\$buff, 0);
+
+    $raf->Seek(0, 2)              or return 0;  # seek to end of file
+    my $filesize = $raf->Tell()   or return 0;
+
+    # initialize maker note data if building maker notes
+    $buildMakerNotes and InitMakerNotes($exifTool);
+
+    # set the FileType tag unless already done (ie. APP0 CIFF record in JPEG image)
+    $exifTool->SetFileType() unless $exifTool->GetValue('FileType');
+
+    # build directory information for main raw directory
+    my %dirInfo = (
+        DataLen  => 0,
+        DirStart => $hlen,
+        DirLen   => $filesize - $hlen,
+        Nesting  => 0,
+        RAF      => $raf,
+        Parent   => 'CRW',
+    );
+
+    # process the raw directory
+    my $rawTagTable = Image::ExifTool::GetTagTable('Image::ExifTool::CanonRaw::Main');
+    unless ($exifTool->ProcessDirectory(\%dirInfo, $rawTagTable)) {
+        $exifTool->Warn('CRW file format error');
+    }
+
+    # finish building maker notes if necessary
+    $buildMakerNotes and SaveMakerNotes($exifTool);
+
+    # process trailers if they exist
+    my $trailInfo = Image::ExifTool::IdentifyTrailer($raf);
+    $exifTool->ProcessTrailers($trailInfo) if $trailInfo;
+
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::CanonRaw - Read Canon RAW (CRW) meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+meta information from Canon CRW raw files.  These files are written directly
+by some Canon cameras, and contain meta information similar to that found in
+the EXIF Canon maker notes.
+
+=head1 NOTES
+
+The CR2 format written by some Canon cameras is very different the CRW
+format processed by this module.  (CR2 is TIFF-based and uses standard EXIF
+tags.)
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.cybercom.net/~dcoffin/dcraw/>
+
+=item L<http://www.wonderland.org/crw/>
+
+=item L<http://xyrion.org/ciff/>
+
+=item L<http://owl.phy.queensu.ca/~phil/exiftool/canon_raw.html>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/CanonRaw Tags>,
+L<Image::ExifTool::Canon(3pm)|Image::ExifTool::Canon>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/CanonVRD.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/CanonVRD.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/CanonVRD.pm	(revision 20131)
@@ -0,0 +1,703 @@
+#------------------------------------------------------------------------------
+# File:         CanonVRD.pm
+#
+# Description:  Read/write Canon VRD information
+#
+# Revisions:    10/30/2006 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::CanonVRD;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.05';
+
+sub ProcessCanonVRD($$);
+
+my $debug;  # set this to 1 for offsets relative to binary data start
+
+my %noYes = ( 0 => 'No', 1 => 'Yes' );
+
+# main tag table IPTC-format records in CanonVRD trailer
+%Image::ExifTool::CanonVRD::Main = (
+    VARS => { INDEX => 1 },
+    NOTES => q{
+        Canon Digital Photo Professional writes VRD (Recipe Data) information as a
+        trailer record to JPEG, TIFF, CRW and CR2 images, or as a stand-alone VRD
+        file. The tags listed below represent information found in this record.  The
+        complete VRD data record may be accessed as a block using the Extra
+        'CanonVRD' tag, but this tag is not extracted or copied unless specified
+        explicitly.
+    },
+    0 => {
+        Name => 'VRD1',
+        Size => 0x272,  # size of version 1.0 edit information in bytes
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::Ver1' },
+    },
+    1 => {
+        Name => 'VRDStampTool',
+        # (size is variable, and obtained from int32u at end of last directory)
+        Size => 0,      # size is variable, and obtained from int32u at directory start
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::StampTool' },
+    },
+    2 => {
+        Name => 'VRD2',
+        Size => undef,  # size is the remaining edit data
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::Ver2' },
+    },
+);
+
+# VRD version 1 tags
+%Image::ExifTool::CanonVRD::Ver1 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    GROUPS => { 2 => 'Image' },
+#
+# RAW image adjustment
+#
+    0x002 => {
+        Name => 'VRDVersion',
+        Format => 'int16u',
+        Writable => 0,
+        PrintConv => 'sprintf("%.2f", $val / 100)',
+    },
+    # 0x006 related somehow to RGB levels
+    0x008 => {
+        Name => 'WBAdjRGBLevels',
+        Format => 'int16u[3]',
+    },
+    0x018 => {
+        Name => 'WhiteBalanceAdj',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Daylight',
+            2 => 'Cloudy',
+            3 => 'Tungsten',
+            4 => 'Fluorescent',
+            5 => 'Flash',
+            8 => 'Shade',
+            9 => 'Kelvin',
+            30 => 'Manual (Click)',
+            31 => 'Shot Settings',
+        },
+    },
+    0x01a => {
+        Name => 'WBAdjColorTemp',
+        Format => 'int16u',
+    },
+    # 0x01c similar to 0x006
+    # 0x01e similar to 0x008
+    0x024 => {
+        Name => 'WBFineTuneActive',
+        Format => 'int16u',
+        PrintConv => \%noYes,
+    },
+    0x028 => {
+        Name => 'WBFineTuneSaturation',
+        Format => 'int16u',
+    },
+    0x02c => {
+        Name => 'WBFineTuneTone',
+        Format => 'int16u',
+    },
+    0x02e => {
+        Name => 'RawColorAdj',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Shot Settings',
+            1 => 'Faithful',
+            2 => 'Custom',
+        },
+    },
+    0x030 => {
+        Name => 'RawCustomSaturation',
+        Format => 'int32s',
+    },
+    0x034 => {
+        Name => 'RawCustomTone',
+        Format => 'int32s',
+    },
+    0x038 => {
+        Name => 'RawBrightnessAdj',
+        Format => 'int32s',
+        ValueConv => '$val / 6000',
+        ValueConvInv => 'int($val * 6000 + ($val < 0 ? -0.5 : 0.5))',
+        PrintConv => 'sprintf("%.2f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x03c => {
+        Name => 'ToneCurveProperty',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Shot Settings',
+            1 => 'Linear',
+            2 => 'Custom 1',
+            3 => 'Custom 2',
+            4 => 'Custom 3',
+            5 => 'Custom 4',
+            6 => 'Custom 5',
+        },
+    },
+    # 0x040 usually "10 9 2"
+    0x07a => {
+        Name => 'DynamicRangeMin',
+        Format => 'int16u',
+    },
+    0x07c => {
+        Name => 'DynamicRangeMax',
+        Format => 'int16u',
+    },
+    # 0x0c6 usually "10 9 2"
+#
+# RGB image adjustment
+#
+    0x110 => {
+        Name => 'ToneCurveActive',
+        Format => 'int16u',
+        PrintConv => \%noYes,
+    },
+    0x114 => {
+        Name => 'BrightnessAdj',
+        Format => 'int8s',
+    },
+    0x115 => {
+        Name => 'ContrastAdj',
+        Format => 'int8s',
+    },
+    0x116 => {
+        Name => 'SaturationAdj',
+        Format => 'int16s',
+    },
+    0x11e => {
+        Name => 'ColorToneAdj',
+        Notes => 'in degrees, so -1 is the same as 359',
+        Format => 'int32s',
+    },
+    0x160 => {
+        Name => 'RedCurvePoints',
+        Format => 'int16u[21]',
+        PrintConv => 'Image::ExifTool::CanonVRD::ToneCurvePrint($val)',
+        PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)',
+    },
+    0x19a => {
+        Name => 'GreenCurvePoints',
+        Format => 'int16u[21]',
+        PrintConv => 'Image::ExifTool::CanonVRD::ToneCurvePrint($val)',
+        PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)',
+    },
+    0x1d4 => {
+        Name => 'BlueCurvePoints',
+        Format => 'int16u[21]',
+        PrintConv => 'Image::ExifTool::CanonVRD::ToneCurvePrint($val)',
+        PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)',
+    },
+    0x18a => {
+        Name => 'RedCurveLimits',
+        Notes => '4 numbers: input and output highlight and shadow points',
+        Format => 'int16u[4]',
+    },
+    0x1c4 => {
+        Name => 'GreenCurveLimits',
+        Format => 'int16u[4]',
+    },
+    0x1fe => {
+        Name => 'BlueCurveLimits',
+        Format => 'int16u[4]',
+    },
+    0x20e => {
+        Name => 'RGBCurvePoints',
+        Format => 'int16u[21]',
+        PrintConv => 'Image::ExifTool::CanonVRD::ToneCurvePrint($val)',
+        PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)',
+    },
+    0x238 => {
+        Name => 'RGBCurveLimits',
+        Format => 'int16u[4]',
+    },
+    0x244 => {
+        Name => 'CropActive',
+        Format => 'int16u',
+        PrintConv => \%noYes,
+    },
+    0x246 => {
+        Name => 'CropLeft',
+        Notes => 'crop coordinates in original unrotated image',
+        Format => 'int16u',
+    },
+    0x248 => {
+        Name => 'CropTop',
+        Format => 'int16u',
+    },
+    0x24a => {
+        Name => 'CropWidth',
+        Format => 'int16u',
+    },
+    0x24c => {
+        Name => 'CropHeight',
+        Format => 'int16u',
+    },
+    0x260 => {
+        Name => 'CropAspectRatio',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Free',
+            1 => '3:2',
+            2 => '2:3',
+            3 => '4:3',
+            4 => '3:4',
+            5 => 'A-size Landscape',
+            6 => 'A-size Portrait',
+            7 => 'Letter-size Landscape',
+            8 => 'Letter-size Portrait',
+            9 => '4:5',
+            10 => '5:4',
+            11 => '1:1',
+        },
+    },
+    0x262 => {
+        Name => 'ConstrainedCropWidth',
+        Format => 'float',
+        PrintConv => 'sprintf("%.7g",$val)',
+        PrintConvInv => '$val',
+    },
+    0x266 => {
+        Name => 'ConstrainedCropHeight',
+        Format => 'float',
+        PrintConv => 'sprintf("%.7g",$val)',
+        PrintConvInv => '$val',
+    },
+    0x26a => {
+        Name => 'CheckMark',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Clear',
+            1 => 1,
+            2 => 2,
+            3 => 3,
+        },
+    },
+    0x26e => {
+        Name => 'Rotation',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 0,
+            1 => 90,
+            2 => 180,
+            3 => 270,
+        },
+    },
+    0x270 => {
+        Name => 'WorkColorSpace',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'sRGB',
+            1 => 'Adobe RGB',
+            2 => 'Wide Gamut RGB',
+            3 => 'Apple RGB',
+            4 => 'ColorMatch RGB',
+        },
+    },
+    # (VRD 1.0 edit data ends here -- 0x272 bytes long)
+);
+
+# VRD Stamp Tool tags
+%Image::ExifTool::CanonVRD::StampTool = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0x00 => {
+        Name => 'StampToolCount',
+        Format => 'int32u',
+    },
+);
+
+# VRD version 2 and 3 tags
+%Image::ExifTool::CanonVRD::Ver2 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    GROUPS => { 2 => 'Image' },
+    NOTES => 'Tags added in DPP version 2.0 and later.',
+    0x04 => {
+        Name => 'PictureStyle',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Portrait',
+            2 => 'Landscape',
+            3 => 'Neutral',
+            4 => 'Faithful',
+            5 => 'Monochrome',
+        },
+    },
+    0x1a => {
+        Name => 'RawColorToneAdj',
+        Format => 'int16s',
+    },
+    0x1c => {
+        Name => 'RawSaturationAdj',
+        Format => 'int16s',
+    },
+    0x1e => {
+        Name => 'RawContrastAdj',
+        Format => 'int16s',
+    },
+    0x20 => {
+        Name => 'RawLinear',
+        Format => 'int16u',
+        PrintConv => \%noYes,
+    },
+    0x22 => {
+        Name => 'RawSharpnessAdj',
+        Format => 'int16s',
+    },
+    0x24 => {
+        Name => 'RawHighlightPoint',
+        Format => 'int16s',
+    },
+    0x26 => {
+        Name => 'RawShadowPoint',
+        Format => 'int16s',
+    },
+    0x74 => {
+        Name => 'MonochromeFilterEffect',
+        Format => 'int16s',
+        PrintConv => {
+            -2 => 'None',
+            -1 => 'Yellow',
+            0 => 'Orange',
+            1 => 'Red',
+            2 => 'Green',
+        },
+    },
+    0x76 => {
+        Name => 'MonochromeToningEffect',
+        Format => 'int16s',
+        PrintConv => {
+            -2 => 'None',
+            -1 => 'Sepia',
+            0 => 'Blue',
+            1 => 'Purple',
+            2 => 'Green',
+        },
+    },
+    0x78 => {
+        Name => 'MonochromeContrast',
+        Format => 'int16s',
+    },
+    0x7a => {
+        Name => 'MonochromeLinear',
+        Format => 'int16u',
+        PrintConv => \%noYes,
+    },
+    0x7c => {
+        Name => 'MonochromeSharpness',
+        Format => 'int16s',
+    },
+    # (VRD 2.0 edit data ends here -- offset 0xb2)
+    0xbc => {
+        Name => 'ChrominanceNoiseReduction',
+        Format => 'int16u',
+        PrintConv => {
+            0   => 'Off',
+            58  => 'Low',
+            100 => 'High',
+        },
+    },
+    0xbe => {
+        Name => 'LuminanceNoiseReduction',
+        Format => 'int16u',
+        PrintConv => {
+            0   => 'Off',
+            65  => 'Low',
+            100 => 'High',
+        },
+    },
+    0xc0 => {
+        Name => 'ChrominanceNR_TIFF_JPEG',
+        Format => 'int16u',
+        PrintConv => {
+            0   => 'Off',
+            33  => 'Low',
+            100 => 'High',
+        },
+    }
+    # (VRD 3.0 edit data ends here -- offset 0xc4)
+);
+
+#------------------------------------------------------------------------------
+# Tone curve print conversion
+sub ToneCurvePrint($)
+{
+    my $val = shift;
+    my @vals = split ' ', $val;
+    return $val unless @vals == 21;
+    my $n = shift @vals;
+    return $val unless $n >= 2 and $n <= 10;
+    $val = '';
+    while ($n--) {
+        $val and $val .= ' ';
+        $val .= '(' . shift(@vals) . ',' . shift(@vals) . ')';
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Inverse print conversion for tone curve
+sub ToneCurvePrintInv($)
+{
+    my $val = shift;
+    my @vals = ($val =~ /\((\d+),(\d+)\)/g);
+    return undef unless @vals >= 4 and @vals <= 20 and not @vals & 0x01;
+    unshift @vals, scalar(@vals) / 2;
+    while (@vals < 21) { push @vals, 0 }
+    return join(' ',@vals);
+}
+
+#------------------------------------------------------------------------------
+# Read/write Canon VRD file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 if this was a Canon VRD file, 0 otherwise, -1 on write error
+sub ProcessVRD($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+    my $num = $raf->Read($buff, 0x1c);
+    if (not $num and $$dirInfo{OutFile}) {
+        # create new VRD file from scratch
+        my $newVal = $exifTool->GetNewValues('CanonVRD');
+        if ($newVal) {
+            $exifTool->VPrint(0, "  Writing CanonVRD as a block\n");
+            Write($$dirInfo{OutFile}, $newVal) or return -1;
+            ++$exifTool->{CHANGED};
+        } else {
+            $exifTool->Error('No CanonVRD information to write');
+        }
+    } else {
+        $num == 0x1c or return 0;
+        $buff =~ /^CANON OPTIONAL DATA\0/ or return 0;
+        $exifTool->SetFileType();
+        $$dirInfo{DirName} = 'CanonVRD';    # set directory name for verbose output
+        my $result = ProcessCanonVRD($exifTool, $dirInfo);
+        return $result if $result < 0;
+        $result or $exifTool->Warn('Format error in VRD file');
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Read/write CanonVRD information
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 not valid VRD, or -1 error writing
+# - updates DataPos to point to start of CanonVRD information
+# - updates DirLen to trailer length
+sub ProcessCanonVRD($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $offset = $$dirInfo{Offset} || 0;
+    my $outfile = $$dirInfo{OutFile};
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my ($buff, $footer, $header, $err);
+    my ($blockLen, $blockType, $recLen, $size);
+
+    # read and validate the trailer footer
+    $raf->Seek(-64-$offset, 2)    or return 0;
+    $raf->Read($footer, 64) == 64 or return 0;
+    $footer =~ /^CANON OPTIONAL DATA\0(.{4})/s or return 0;
+    $size = unpack('N', $1);
+
+    # read and validate the header too
+    # (header is 0x1c bytes and footer is 0x40 bytes)
+    unless ($size > 12 and ($size & 0x80000000) == 0 and
+            $raf->Seek(-$size-0x5c, 1) and
+            $raf->Read($header, 0x1c) == 0x1c and
+            $header =~ /^CANON OPTIONAL DATA\0/ and
+            $raf->Read($buff, $size) == $size)
+    {
+        $exifTool->Warn('Bad CanonVRD trailer');
+        return 0;
+    }
+    # extract CanonVRD block if Binary option set, or if requested
+    if ($exifTool->{OPTIONS}->{Binary} or $exifTool->{REQ_TAG_LOOKUP}->{canonvrd}) {
+        $exifTool->FoundTag('CanonVRD', $header . $buff . $footer);
+    }
+    # set variables returned in dirInfo hash
+    $$dirInfo{DataPos} = $raf->Tell() - $size - 0x1c;
+    $$dirInfo{DirLen} = $size + 0x5c;
+
+    if ($outfile) {
+        # delete CanonVRD information if specified
+        if ($exifTool->{DEL_GROUP}->{CanonVRD} or $exifTool->{DEL_GROUP}->{Trailer} or
+            # also delete if writing as a block (will get added back again later)
+            $exifTool->{NEW_VALUE}->{$Image::ExifTool::Extra{CanonVRD}})
+        {
+            if ($exifTool->{FILE_TYPE} eq 'VRD') {
+                my $newVal = $exifTool->GetNewValues('CanonVRD');
+                if ($newVal) {
+                    $verbose and printf $out "  Writing CanonVRD as a block\n";
+                    Write($outfile, $newVal) or return -1;
+                    ++$exifTool->{CHANGED};
+                } else {
+                    $exifTool->Error("Can't delete all CanonVRD information from a VRD file");
+                }
+            } else {
+                $verbose and printf $out "  Deleting CanonVRD trailer\n";
+                ++$exifTool->{CHANGED};
+            }
+            return 1;
+        }
+        # write now and return if CanonVRD was set as a block
+        my $val = $exifTool->GetNewValues('CanonVRD');
+        if ($val) {
+            $verbose and print $out "  Writing CanonVRD as a block\n";
+            Write($outfile, $val) or return -1;
+            ++$exifTool->{CHANGED};
+            return 1;
+        }
+    } elsif ($verbose or $exifTool->{HTML_DUMP}) {
+        $exifTool->DumpTrailer($dirInfo);
+    }
+
+    # validate VRD trailer and get position and length of edit record
+    SetByteOrder('MM');
+    my $pos = 0;
+    my $vrdPos = $$dirInfo{DataPos} + length($header);
+Block: for (;;) {
+        if ($pos + 8 > $size) {
+            last if $pos == $size;
+            $blockLen = $size;  # mark as invalid
+        } else {
+            $blockType = Get32u(\$buff, $pos);
+            $blockLen = Get32u(\$buff, $pos + 4);
+        }
+        $pos += 8;          # move to start of block
+        if ($pos + $blockLen > $size) {
+            $exifTool->Warn('Possibly corrupt CanonVRD block');
+            last;
+        }
+        printf $out "  CanonVRD block %x ($blockLen bytes at offset 0x%x)\n",
+            $blockType, $pos + $vrdPos if $verbose > 1 and not $outfile;
+        # process edit-data block
+        if ($blockType == 0xffff00f4) {
+            my $blockEnd = $pos + $blockLen;
+            my $recNum;
+            for ($recNum=0;; ++$recNum, $pos+=$recLen) {
+                if ($pos + 4 > $blockEnd) {
+                    last Block if $pos == $blockEnd;  # all done if we arrived at end
+                    $recLen = $blockEnd;    # mark as invalid
+                } else {
+                    $recLen = Get32u(\$buff, $pos);
+                }
+                $pos += 4;      # move to start of record
+                if ($pos + $recLen > $blockEnd) {
+                    $exifTool->Warn('Possibly corrupt CanonVRD record');
+                    last Block;
+                }
+                printf $out "  CanonVRD record ($recLen bytes at offset 0x%x)\n",
+                    $pos + $vrdPos if $verbose > 1 and not $outfile;
+
+                # our edit information is the first record
+                # (don't process if simply deleting VRD)
+                next if $recNum;
+
+                # process VRD edit information
+                my $tagTablePtr = GetTagTable('Image::ExifTool::CanonVRD::Main');
+                my $index;
+                my $editData = substr($buff, $pos, $recLen);
+                my %subdirInfo = (
+                    DataPt => \$editData,
+                    DataPos => $debug ? 0 : $vrdPos + $pos,
+                );
+                my $start = 0;
+                for ($index=0; ; ++$index) {
+                    my $tagInfo = $$tagTablePtr{$index} or last;
+                    my $dirLen;
+                    my $maxLen = $recLen - $start;
+                    if ($$tagInfo{Size}) {
+                        $dirLen = $$tagInfo{Size};
+                    } elsif (defined $$tagInfo{Size}) {
+                        # get size from int32u at $start
+                        last unless $start + 4 <= $recLen;
+                        $dirLen = Get32u(\$editData, $start);
+                        $start += 4; # skip the length word
+                    } else {
+                        $dirLen = $maxLen;
+                    }
+                    $dirLen > $maxLen and $dirLen = $maxLen;
+                    if ($dirLen) {
+                        my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                        my $subName = $$tagInfo{Name};
+                        $subdirInfo{DirStart} = $start;
+                        $subdirInfo{DirLen} = $dirLen;
+                        $subdirInfo{DirName} = $subName;
+                        if ($outfile) {
+                            # rewrite CanonVRD information
+                            $verbose and print $out "  Rewriting Canon $subName\n";
+                            my $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+                            substr($buff, $pos+$start, $dirLen) = $newVal if $newVal;
+                        } else {
+                            Image::ExifTool::HexDump(\$editData, $dirLen,
+                                Start  => $start,
+                                Addr   => 0,
+                                Prefix => $$tagInfo{Name}
+                            ) if $debug;
+                            # extract CanonVRD information
+                            $exifTool->ProcessDirectory(\%subdirInfo, $subTable);
+                        }
+                    }
+                    # next directory starts at the end of this one
+                    $start += $dirLen;
+                }
+            }
+        } else {
+            $pos += $blockLen;  # skip other blocks
+        }
+    }
+    # write CanonVRD trailer
+    Write($outfile, $header, $buff, $footer) or $err = 1 if $outfile;
+
+    undef $buff;
+    return $err ? -1 : 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::CanonVRD - Read/write Canon VRD information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read and
+write VRD Recipe Data information as written by the Canon Digital Photo
+Professional software.  This information is written to VRD files, and as a
+trailer in JPEG, CRW and CR2 images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/CanonVRD Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Casio.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Casio.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Casio.pm	(revision 20131)
@@ -0,0 +1,583 @@
+#------------------------------------------------------------------------------
+# File:         Casio.pm
+#
+# Description:  Casio EXIF maker notes tags
+#
+# Revisions:    12/09/2003 - P. Harvey Created
+#               09/10/2004 - P. Harvey Added MakerNote2 (thanks to Joachim Loehr)
+#
+# References:   1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
+#               2) Joachim Loehr private communication
+#               3) http://homepage3.nifty.com/kamisaka/makernote/makernote_casio.htm
+#               4) http://www.gvsoft.homedns.org/exif/makernote-casio.html
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Casio;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.21';
+
+# older Casio maker notes (ref 1)
+%Image::ExifTool::Casio::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x0001 => {
+        Name => 'RecordingMode' ,
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Single Shutter',
+            2 => 'Panorama',
+            3 => 'Night Scene',
+            4 => 'Portrait',
+            5 => 'Landscape',
+            7 => 'Panorama', #4
+            10 => 'Night Scene', #4
+            15 => 'Portrait', #4
+            16 => 'Landscape', #4
+        },
+    },
+    0x0002 => {
+        Name => 'Quality',
+        Writable => 'int16u',
+        PrintConv => { 1 => 'Economy', 2 => 'Normal', 3 => 'Fine' },
+    },
+    0x0003 => {
+        Name => 'FocusMode',
+        Writable => 'int16u',
+        PrintConv => {
+            2 => 'Macro',
+            3 => 'Auto',
+            4 => 'Manual',
+            5 => 'Infinity',
+            7 => 'Spot AF', #4
+        },
+    },
+    0x0004 => [
+        {
+            Name => 'FlashMode',
+            Condition => '$self->{CameraModel} =~ /^QV-(3500EX|8000SX)/',
+            Writable => 'int16u',
+            PrintConv => {
+                1 => 'Auto',
+                2 => 'On',
+                3 => 'Off',
+                4 => 'Off', #4
+                5 => 'Red-eye Reduction', #4
+            },
+        },
+        {
+            Name => 'FlashMode',
+            Writable => 'int16u',
+            PrintConv => {
+                1 => 'Auto',
+                2 => 'On',
+                3 => 'Off',
+                4 => 'Red-eye Reduction',
+            },
+        },
+    ],
+    0x0005 => {
+        Name => 'FlashIntensity',
+        Writable => 'int16u',
+        PrintConv => {
+            11 => 'Weak',
+            12 => 'Low', #4
+            13 => 'Normal',
+            14 => 'High', #4
+            15 => 'Strong',
+        },
+    },
+    0x0006 => {
+        Name => 'ObjectDistance',
+        Writable => 'int32u',
+        ValueConv => '$val / 1000', #4
+        ValueConvInv => '$val * 1000',
+        PrintConv => '"$val m"',
+        PrintConvInv => '$val=~s/\s*m$//;$val',
+    },
+    0x0007 => {
+        Name => 'WhiteBalance',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Auto',
+            2 => 'Tungsten',
+            3 => 'Daylight',
+            4 => 'Fluorescent',
+            5 => 'Shade',
+            129 => 'Manual',
+        },
+    },
+    # 0x0009 Bulb? (ref unknown)
+    0x000a => {
+        Name => 'DigitalZoom',
+        Writable => 'int32u',
+        PrintHex => 1,
+        PrintConv => {
+            0x10000 => 'Off',
+            0x10001 => '2x',
+            0x19999 => '1.6x', #4
+            0x20000 => '2x', #4
+            0x33333 => '3.2x', #4
+            0x40000 => '4x', #4
+        },
+    },
+    0x000b => {
+        Name => 'Sharpness',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Soft',
+            2 => 'Hard',
+            16 => 'Normal', #4
+            17 => '+1', #4
+            18 => '-1', #4
+         },
+    },
+    0x000c => {
+        Name => 'Contrast',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Low',
+            2 => 'High',
+            16 => 'Normal', #4
+            17 => '+1', #4
+            18 => '-1', #4
+        },
+    },
+    0x000d => {
+        Name => 'Saturation',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Low',
+            2 => 'High',
+            16 => 'Normal', #4
+            17 => '+1', #4
+            18 => '-1', #4
+        },
+    },
+    0x0014 => {
+        Name => 'ISO',
+        Writable => 'int16u',
+        Priority => 0,
+    },
+    0x0016 => { #4
+        Name => 'Enhancement',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Off',
+            2 => 'Red',
+            3 => 'Green',
+            4 => 'Blue',
+            5 => 'Flesh Tones',
+        },
+    },
+    0x0017 => { #4
+        Name => 'ColorFilter',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Off',
+            2 => 'Black & White',
+            3 => 'Sepia',
+            4 => 'Red',
+            5 => 'Green',
+            6 => 'Blue',
+            7 => 'Yellow',
+            8 => 'Pink',
+            9 => 'Purple',
+        },
+    },
+    0x0018 => { #4
+        Name => 'AFPoint',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Center',
+            2 => 'Upper Left',
+            3 => 'Upper Right',
+            4 => 'Near Left/Right of Center',
+            5 => 'Far Left/Right of Center',
+            6 => 'Far Left/Right of Center/Bottom',
+            7 => 'Top Near-Left',
+            8 => 'Near Upper/Left',
+            9 => 'Top Near-Right',
+            10 => 'Top Left',
+            11 => 'Top Center',
+            12 => 'Top Right',
+            13 => 'Center Left',
+            14 => 'Center Right',
+            15 => 'Bottom Left',
+            16 => 'Bottom Center',
+            17 => 'Bottom Right',
+        },
+    },
+    0x0019 => { #4
+        Name => 'FlashIntensity',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Normal',
+            2 => 'Weak',
+            3 => 'Strong',
+        },
+    },
+    0x0e00 => {
+        Name => 'PrintIM',
+        Description => 'Print Image Matching',
+        # crazy I know, but the offset for this value is entry-based
+        # (QV-2100, QV-2900UX, QV-3500EX and QV-4000) even though the
+        # offsets for other values isn't
+        EntryBased => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+);
+
+# ref 2:
+%Image::ExifTool::Casio::Type2 = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x0002 => {
+        Name => 'PreviewImageSize',
+        Groups => { 2 => 'Image' },
+        Writable => 'int16u',
+        Count => 2,
+        PrintConv => '$val =~ tr/ /x/; $val',
+        PrintConvInv => '$val =~ tr/x/ /; $val',
+    },
+    0x0003 => {
+        Name => 'PreviewImageLength',
+        Groups => { 2 => 'Image' },
+        OffsetPair => 0x0004, # point to associated offset
+        DataTag => 'PreviewImage',
+        Writable => 'int32u',
+        Protected => 2,
+    },
+    0x0004 => {
+        Name => 'PreviewImageStart',
+        Groups => { 2 => 'Image' },
+        Flags => 'IsOffset',
+        OffsetPair => 0x0003, # point to associated byte count
+        DataTag => 'PreviewImage',
+        Writable => 'int32u',
+        Protected => 2,
+    },
+    0x0008 => {
+        Name => 'QualityMode',
+        Writable => 'int16u',
+        PrintConv => {
+           0 => 'Economy',
+           1 => 'Normal',
+           2 => 'Fine',
+        },
+    },
+    0x0009 => {
+        Name => 'CasioImageSize',
+        Groups => { 2 => 'Image' },
+        Writable => 'int16u',
+        PrintConv => {
+            0 => '640x480',
+            4 => '1600x1200',
+            5 => '2048x1536',
+            20 => '2288x1712',
+            21 => '2592x1944',
+            22 => '2304x1728',
+            36 => '3008x2008',
+        },
+    },
+    0x000d => {
+        Name => 'FocusMode',
+        Writable => 'int16u',
+        PrintConv => {
+           0 => 'Normal',
+           1 => 'Macro',
+        },
+    },
+    0x0014 => {
+        Name => 'ISO',
+        Writable => 'int16u',
+        Priority => 0,
+        PrintConv => {
+           3 => 50,
+           4 => 64,
+           6 => 100,
+           9 => 200,
+        },
+    },
+    0x0019 => {
+        Name => 'WhiteBalance',
+        Writable => 'int16u',
+        PrintConv => {
+           0 => 'Auto',
+           1 => 'Daylight',
+           2 => 'Shade',
+           3 => 'Tungsten',
+           4 => 'Fluorescent',
+           5 => 'Manual',
+        },
+    },
+    0x001d => {
+        Name => 'FocalLength',
+        Writable => 'rational64u',
+        PrintConv => 'sprintf("%.1fmm",$val)',
+        PrintConvInv => '$val=~s/mm$//;$val',
+    },
+    0x001f => {
+        Name => 'Saturation',
+        Writable => 'int16u',
+        PrintConv => {
+           0 => 'Low',
+           1 => 'Normal',
+           2 => 'High',
+        },
+    },
+    0x0020 => {
+        Name => 'Contrast',
+        Writable => 'int16u',
+        PrintConv => {
+           0 => 'Low',
+           1 => 'Normal',
+           2 => 'High',
+        },
+    },
+    0x0021 => {
+        Name => 'Sharpness',
+        Writable => 'int16u',
+        PrintConv => {
+           0 => 'Soft',
+           1 => 'Normal',
+           2 => 'Hard',
+        },
+    },
+    0x0e00 => {
+        Name => 'PrintIM',
+        Description => 'Print Image Matching',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+    0x2000 => {
+        # this image data is also referenced by tags 3 and 4
+        # (nasty that they double-reference the image!)
+        %Image::ExifTool::previewImageTagInfo,
+    },
+    0x2001 => { #PH
+        # I downloaded images from 12 different EX-Z50 cameras, and they showed
+        # only 3 distinct dates here (2004:08:31 18:55, 2004:09:13 14:14, and
+        # 2004:11:26 17:07), so I'm guessing this is a firmware version date - PH
+        Name => 'FirmwareDate',
+        Writable => 'string',
+        Format => 'undef', # the 'string' contains nulls
+        Count => 18,
+        PrintConv => q{
+            $_ = $val;
+            if (/^(\d{2})(\d{2})\0\0(\d{2})(\d{2})\0\0(\d{2})\0{4}$/) {
+                my $yr = $1 + ($1 < 70 ? 2000 : 1900);
+                return "$yr:$2:$3 $4:$5";
+            }
+            tr/\0/./;  s/\.+$//;
+            return "Unknown ($_)";
+        },
+        PrintConvInv => q{
+            $_ = $val;
+            if (/^(19|20)(\d{2}):(\d{2}):(\d{2}) (\d{2}):(\d{2})$/) {
+                return "$2$3\0\0$4$5\0\0$6\0\0\0\0";
+            } elsif (/^Unknown\s*\((.*)\)$/i) {
+                $_ = $1;  tr/./\0/;
+                return $_;
+            } else {
+                return undef;
+            }
+        },
+    },
+    0x2011 => {
+        Name => 'WhiteBalanceBias',
+        Writable => 'int16u',
+        Count => 2,
+    },
+    0x2012 => {
+        Name => 'WhiteBalance',
+        Writable => 'int16u',
+        PrintConv => {
+           0 => 'Manual',
+           1 => 'Daylight', #3
+           3 => 'Shade', #3
+           4 => 'Flash?',
+           6 => 'Fluorescent', #3
+           10 => 'Tungsten', #3
+           12 => 'Flash',
+        },
+    },
+    0x2022 => {
+        Name => 'ObjectDistance',
+        Writable => 'int32u',
+        ValueConv => '$val >= 0x20000000 ? "inf" : $val / 1000',
+        ValueConvInv => '$val eq "inf" ? 0x20000000 : $val * 1000',
+        PrintConv => '$val eq "inf" ? $val : "$val m"',
+        PrintConvInv => '$val=~s/\s*m$//;$val',
+    },
+    # 0x2023 looks interesting (values 0,1,2,3,5 in samples) - PH
+    0x2034 => {
+        Name => 'FlashDistance',
+        Writable => 'int16u',
+    },
+    0x3000 => {
+        Name => 'RecordMode',
+        Writable => 'int16u',
+        PrintConv => {
+            2 => 'Program AE', #3
+            3 => 'Shutter Priority', #3
+            4 => 'Aperture Priority', #3
+            5 => 'Manual', #3
+            6 => 'Best Shot', #3
+        },
+    },
+    # 0x3001 is ShutterMode according to ref 3!
+    0x3001 => {
+        Name => 'SelfTimer',
+        Writable => 'int16u',
+        PrintConv => { 1 => 'Off' },
+    },
+    0x3002 => {
+        Name => 'Quality',
+        Writable => 'int16u',
+        PrintConv => {
+           1 => 'Economy',
+           2 => 'Normal',
+           3 => 'Fine',
+        },
+    },
+    0x3003 => {
+        Name => 'FocusMode',
+        Writable => 'int16u',
+        PrintConv => {
+           0 => 'Manual?',
+           1 => 'Fixation?',
+           2 => 'Macro', #3
+           3 => 'Single-Area Auto Focus',
+           6 => 'Multi-Area Auto Focus',
+        },
+    },
+    0x3006 => {
+        Name => 'HometownCity',
+        Writable => 'string',
+    },
+    0x3007 => {
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        PrintConv => {
+           0 => 'Off',
+           1 => 'On?',
+        },
+    },
+    0x3008 => { #3
+        Name => 'AutoISO',
+        Writable => 'int16u',
+        PrintConv => { 1 => 'On', 2 => 'Off' },
+    },
+    0x3011 => { #3
+        Name => 'Sharpness',
+        Format => 'int16s',
+        Writable => 'undef',
+    },
+    0x3012 => { #3
+        Name => 'Contrast',
+        Format => 'int16s',
+        Writable => 'undef',
+    },
+    0x3013 => { #3
+        Name => 'Saturation',
+        Format => 'int16s',
+        Writable => 'undef',
+    },
+    0x3014 => {
+        Name => 'ISO',
+        Writable => 'int16u',
+        Priority => 0,
+    },
+    0x3015 => {
+        Name => 'ColorMode',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off' },
+    },
+    0x3016 => {
+        Name => 'Enhancement',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off' },
+    },
+    0x3017 => {
+        Name => 'Filter',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off' },
+    },
+    0x301c => { #3
+        Name => 'SequenceNumber', # for continuous shooting
+        Writable => 'int16u',
+    },
+    0x301d => { #3
+        Name => 'BracketSequence',
+        Writable => 'int16u',
+        Count => 2,
+    },
+    # 0x301e - MultiBracket ? (ref 3)
+    0x3020 => { #3
+        Name => 'ImageStabilization',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'Best Shot',
+        },
+    },
+);
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Casio - Casio EXIF maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+Casio maker notes in EXIF information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html>
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Joachim Loehr for adding support for the type 2 maker notes.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Casio Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/DICOM.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/DICOM.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/DICOM.pm	(revision 20131)
@@ -0,0 +1,2651 @@
+#------------------------------------------------------------------------------
+# File:         DICOM.pm
+#
+# Description:  Read DICOM and ACR-NEMA medical images
+#
+# Revisions:    11/09/2005 - P. Harvey Created
+#
+# References:   1) http://medical.nema.org/dicom/2004.html
+#               2) http://www.sph.sc.edu/comd/rorden/dicom.html
+#               3) http://www.dclunie.com/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::DICOM;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.06';
+
+# DICOM VR (Value Representation) format conversions
+my %dicomFormat = (
+    FD => 'double',
+    FL => 'float',
+    OB => 'int8u',
+    OF => 'float',
+    OW => 'int16u',
+    SL => 'int32s',
+    SS => 'int16s',
+    UL => 'int32u',
+    US => 'int16u',
+);
+
+# VR elements with 32-bit length in explicit VR syntax
+my %vr32 = ( OB=>1, OW=>1, OF=>1, SQ=>1, UT=>1, UN=>1 );
+
+# data elements with implicit VR regardless of syntax
+my %implicitVR = (
+    'FFFE,E000' => 1,
+    'FFFE,E00D' => 1,
+    'FFFE,E0DD' => 1,
+);
+
+# DICOM tags
+# Note: "XxxGroupLength" tags are generated automatically if they don't exist
+%Image::ExifTool::DICOM::Main = (
+    GROUPS => { 2 => 'Image' },
+    PROCESS_PROC => 0,  # set this to zero to omit tags from lookup (way too many!)
+    NOTES => q{
+        The DICOM format is based on the ACR-NEMA specification, but adds a file
+        header and a number of new tags.  ExifTool will extract information from
+        either type of file.  The Tag ID's in the following table are the tag group
+        and element numbers in hexadecimal, as given in the DICOM specification.
+    },
+    # file meta information group (names end with VR)
+    '0002,0000' => { VR => 'UL', Name => 'FileMetaInfoGroupLength' },
+    '0002,0001' => { VR => 'OB', Name => 'FileMetaInfoVersion' },
+    '0002,0002' => { VR => 'UI', Name => 'MediaStorageSOPClassUID' },
+    '0002,0003' => { VR => 'UI', Name => 'MediaStorageSOPInstanceUID' },
+    '0002,0010' => { VR => 'UI', Name => 'TransferSyntaxUID' },
+    '0002,0012' => { VR => 'UI', Name => 'ImplementationClassUID' },
+    '0002,0013' => { VR => 'SH', Name => 'ImplementationVersionName' },
+    '0002,0016' => { VR => 'AE', Name => 'SourceApplicationEntityTitle' },
+    '0002,0100' => { VR => 'UI', Name => 'PrivateInformationCreatorUID' },
+    '0002,0102' => { VR => 'OB', Name => 'PrivateInformation' },
+    # directory structuring group
+    '0004,1130' => { VR => 'CS', Name => 'FileSetID' },
+    '0004,1141' => { VR => 'CS', Name => 'FileSetDescriptorFileID' },
+    '0004,1142' => { VR => 'CS', Name => 'SpecificCharacterSetOfFile' },
+    '0004,1200' => { VR => 'UL', Name => 'FirstDirectoryRecordOffset' },
+    '0004,1202' => { VR => 'UL', Name => 'LastDirectoryRecordOffset' },
+    '0004,1212' => { VR => 'US', Name => 'FileSetConsistencyFlag' },
+    '0004,1220' => { VR => 'SQ', Name => 'DirectoryRecordSequence' },
+    '0004,1400' => { VR => 'UL', Name => 'OffsetOfNextDirectoryRecord' },
+    '0004,1410' => { VR => 'US', Name => 'RecordInUseFlag' },
+    '0004,1420' => { VR => 'UL', Name => 'LowerLevelDirectoryEntityOffset' },
+    '0004,1430' => { VR => 'CS', Name => 'DirectoryRecordType' },
+    '0004,1432' => { VR => 'UI', Name => 'PrivateRecordUID' },
+    '0004,1500' => { VR => 'CS', Name => 'ReferencedFileID' },
+    '0004,1504' => { VR => 'UL', Name => 'MRDRDirectoryRecordOffset' },
+    '0004,1510' => { VR => 'UI', Name => 'ReferencedSOPClassUIDInFile' },
+    '0004,1511' => { VR => 'UI', Name => 'ReferencedSOPInstanceUIDInFile' },
+    '0004,1512' => { VR => 'UI', Name => 'ReferencedTransferSyntaxUIDInFile' },
+    '0004,151A' => { VR => 'UI', Name => 'ReferencedRelatedSOPClassUIDInFile' },
+    '0004,1600' => { VR => 'UL', Name => 'NumberOfReferences' },
+    # identifying group
+    '0008,0000' => { VR => 'UL', Name => 'IdentifyingGroupLength' },
+    '0008,0001' => { VR => 'RET',Name => 'LengthToEnd' },
+    '0008,0005' => { VR => 'CS', Name => 'SpecificCharacterSet' },
+    '0008,0008' => { VR => 'CS', Name => 'ImageType' },
+    '0008,0010' => { VR => 'RET',Name => 'RecognitionCode' },
+    '0008,0012' => { VR => 'DA', Name => 'InstanceCreationDate' },
+    '0008,0013' => { VR => 'TM', Name => 'InstanceCreationTime' },
+    '0008,0014' => { VR => 'UI', Name => 'InstanceCreatorUID' },
+    '0008,0016' => { VR => 'UI', Name => 'SOPClassUID' },
+    '0008,0018' => { VR => 'UI', Name => 'SOPInstanceUID' },
+    '0008,001A' => { VR => 'UI', Name => 'RelatedGeneralSOPClassUID' },
+    '0008,001B' => { VR => 'UI', Name => 'OriginalSpecializedSOPClassUID' },
+    '0008,0020' => { VR => 'DA', Name => 'StudyDate' },
+    '0008,0021' => { VR => 'DA', Name => 'SeriesDate' },
+    '0008,0022' => { VR => 'DA', Name => 'AcquisitionDate' },
+    '0008,0023' => { VR => 'DA', Name => 'ContentDate' },
+    '0008,0024' => { VR => 'DA', Name => 'OverlayDate' },
+    '0008,0025' => { VR => 'DA', Name => 'CurveDate' },
+    '0008,002A' => { VR => 'DT', Name => 'AcquisitionDatetime' },
+    '0008,0030' => { VR => 'TM', Name => 'StudyTime' },
+    '0008,0031' => { VR => 'TM', Name => 'SeriesTime' },
+    '0008,0032' => { VR => 'TM', Name => 'AcquisitionTime' },
+    '0008,0033' => { VR => 'TM', Name => 'ContentTime' },
+    '0008,0034' => { VR => 'TM', Name => 'OverlayTime' },
+    '0008,0035' => { VR => 'TM', Name => 'CurveTime' },
+    '0008,0040' => { VR => 'RET',Name => 'DataSetType' },
+    '0008,0041' => { VR => 'RET',Name => 'DataSetSubtype' },
+    '0008,0042' => { VR => 'RET',Name => 'NuclearMedicineSeriesType' },
+    '0008,0050' => { VR => 'SH', Name => 'AccessionNumber' },
+    '0008,0052' => { VR => 'CS', Name => 'Query-RetrieveLevel' },
+    '0008,0054' => { VR => 'AE', Name => 'RetrieveAETitle' },
+    '0008,0056' => { VR => 'CS', Name => 'InstanceAvailability' },
+    '0008,0058' => { VR => 'UI', Name => 'FailedSOPInstanceUIDList' },
+    '0008,0060' => { VR => 'CS', Name => 'Modality' },
+    '0008,0061' => { VR => 'CS', Name => 'ModalitiesInStudy' },
+    '0008,0062' => { VR => 'UI', Name => 'SOPClassesInStudy' },
+    '0008,0064' => { VR => 'CS', Name => 'ConversionType' },
+    '0008,0068' => { VR => 'CS', Name => 'PresentationIntentType' },
+    '0008,0070' => { VR => 'LO', Name => 'Manufacturer' },
+    '0008,0080' => { VR => 'LO', Name => 'InstitutionName' },
+    '0008,0081' => { VR => 'ST', Name => 'InstitutionAddress' },
+    '0008,0082' => { VR => 'SQ', Name => 'InstitutionCodeSequence' },
+    '0008,0090' => { VR => 'PN', Name => 'ReferringPhysiciansName' },
+    '0008,0092' => { VR => 'ST', Name => 'ReferringPhysiciansAddress' },
+    '0008,0094' => { VR => 'SH', Name => 'ReferringPhysiciansTelephoneNumber' },
+    '0008,0096' => { VR => 'SQ', Name => 'ReferringPhysicianIDSequence' },
+    '0008,0100' => { VR => 'SH', Name => 'CodeValue' },
+    '0008,0102' => { VR => 'SH', Name => 'CodingSchemeDesignator' },
+    '0008,0103' => { VR => 'SH', Name => 'CodingSchemeVersion' },
+    '0008,0104' => { VR => 'LO', Name => 'CodeMeaning' },
+    '0008,0105' => { VR => 'CS', Name => 'MappingResource' },
+    '0008,0106' => { VR => 'DT', Name => 'ContextGroupVersion' },
+    '0008,0107' => { VR => 'DT', Name => 'ContextGroupLocalVersion' },
+    '0008,010B' => { VR => 'CS', Name => 'ContextGroupExtensionFlag' },
+    '0008,010C' => { VR => 'UI', Name => 'CodingSchemeUID' },
+    '0008,010D' => { VR => 'UI', Name => 'ContextGroupExtensionCreatorUID' },
+    '0008,010F' => { VR => 'CS', Name => 'ContextIdentifier' },
+    '0008,0110' => { VR => 'SQ', Name => 'CodingSchemeIDSequence' },
+    '0008,0112' => { VR => 'LO', Name => 'CodingSchemeRegistry' },
+    '0008,0114' => { VR => 'ST', Name => 'CodingSchemeExternalID' },
+    '0008,0115' => { VR => 'ST', Name => 'CodingSchemeName' },
+    '0008,0116' => { VR => 'ST', Name => 'ResponsibleOrganization' },
+    '0008,0201' => { VR => 'SH', Name => 'TimezoneOffsetFromUTC' },
+    '0008,1000' => { VR => 'RET',Name => 'NetworkID' },
+    '0008,1010' => { VR => 'SH', Name => 'StationName' },
+    '0008,1030' => { VR => 'LO', Name => 'StudyDescription' },
+    '0008,1032' => { VR => 'SQ', Name => 'ProcedureCodeSequence' },
+    '0008,103E' => { VR => 'LO', Name => 'SeriesDescription' },
+    '0008,1040' => { VR => 'LO', Name => 'InstitutionalDepartmentName' },
+    '0008,1048' => { VR => 'PN', Name => 'PhysicianOfRecord' },
+    '0008,1049' => { VR => 'SQ', Name => 'PhysicianOfRecordIDSequence' },
+    '0008,1050' => { VR => 'PN', Name => 'PerformingPhysiciansName' },
+    '0008,1052' => { VR => 'SQ', Name => 'PerformingPhysicianIDSequence' },
+    '0008,1060' => { VR => 'PN', Name => 'NameOfPhysicianReadingStudy' },
+    '0008,1062' => { VR => 'SQ', Name => 'PhysicianReadingStudyIDSequence' },
+    '0008,1070' => { VR => 'PN', Name => 'OperatorsName' },
+    '0008,1072' => { VR => 'SQ', Name => 'OperatorIDSequence' },
+    '0008,1080' => { VR => 'LO', Name => 'AdmittingDiagnosesDescription' },
+    '0008,1084' => { VR => 'SQ', Name => 'AdmittingDiagnosesCodeSequence' },
+    '0008,1090' => { VR => 'LO', Name => 'ManufacturersModelName' },
+    '0008,1100' => { VR => 'SQ', Name => 'ReferencedResultsSequence' },
+    '0008,1110' => { VR => 'SQ', Name => 'ReferencedStudySequence' },
+    '0008,1111' => { VR => 'SQ', Name => 'ReferencedProcedureStepSequence' },
+    '0008,1115' => { VR => 'SQ', Name => 'ReferencedSeriesSequence' },
+    '0008,1120' => { VR => 'SQ', Name => 'ReferencedPatientSequence' },
+    '0008,1125' => { VR => 'SQ', Name => 'ReferencedVisitSequence' },
+    '0008,1130' => { VR => 'SQ', Name => 'ReferencedOverlaySequence' },
+    '0008,113A' => { VR => 'SQ', Name => 'ReferencedWaveformSequence' },
+    '0008,1140' => { VR => 'SQ', Name => 'ReferencedImageSequence' },
+    '0008,1145' => { VR => 'SQ', Name => 'ReferencedCurveSequence' },
+    '0008,114A' => { VR => 'SQ', Name => 'ReferencedInstanceSequence' },
+    '0008,1150' => { VR => 'UI', Name => 'ReferencedSOPClassUID' },
+    '0008,1155' => { VR => 'UI', Name => 'ReferencedSOPInstanceUID' },
+    '0008,115A' => { VR => 'UI', Name => 'SOPClassesSupported' },
+    '0008,1160' => { VR => 'IS', Name => 'ReferencedFrameNumber' },
+    '0008,1195' => { VR => 'UI', Name => 'TransactionUID' },
+    '0008,1197' => { VR => 'US', Name => 'FailureReason' },
+    '0008,1198' => { VR => 'SQ', Name => 'FailedSOPSequence' },
+    '0008,1199' => { VR => 'SQ', Name => 'ReferencedSOPSequence' },
+    '0008,1200' => { VR => 'SQ', Name => 'OtherReferencedStudiesSequence' },
+    '0008,1250' => { VR => 'SQ', Name => 'RelatedSeriesSequence' },
+    '0008,2110' => { VR => 'RET',Name => 'LossyImageCompression' },
+    '0008,2111' => { VR => 'ST', Name => 'DerivationDescription' },
+    '0008,2112' => { VR => 'SQ', Name => 'SourceImageSequence' },
+    '0008,2120' => { VR => 'SH', Name => 'StageName' },
+    '0008,2122' => { VR => 'IS', Name => 'StageNumber' },
+    '0008,2124' => { VR => 'IS', Name => 'NumberOfStages' },
+    '0008,2127' => { VR => 'SH', Name => 'ViewName' },
+    '0008,2128' => { VR => 'IS', Name => 'ViewNumber' },
+    '0008,2129' => { VR => 'IS', Name => 'NumberOfEventTimers' },
+    '0008,212A' => { VR => 'IS', Name => 'NumberOfViewsInStage' },
+    '0008,2130' => { VR => 'DS', Name => 'EventElapsedTime' },
+    '0008,2132' => { VR => 'LO', Name => 'EventTimerName' },
+    '0008,2142' => { VR => 'IS', Name => 'StartTrim' },
+    '0008,2143' => { VR => 'IS', Name => 'StopTrim' },
+    '0008,2144' => { VR => 'IS', Name => 'RecommendedDisplayFrameRate' },
+    '0008,2200' => { VR => 'RET',Name => 'TransducerPosition' },
+    '0008,2204' => { VR => 'RET',Name => 'TransducerOrientation' },
+    '0008,2208' => { VR => 'RET',Name => 'AnatomicStructure' },
+    '0008,2218' => { VR => 'SQ', Name => 'AnatomicRegionSequence' },
+    '0008,2220' => { VR => 'SQ', Name => 'AnatomicRegionModifierSequence' },
+    '0008,2228' => { VR => 'SQ', Name => 'PrimaryAnatomicStructureSequence' },
+    '0008,2229' => { VR => 'SQ', Name => 'AnatomicStructureOrRegionSequence' },
+    '0008,2230' => { VR => 'SQ', Name => 'AnatomicStructureModifierSequence' },
+    '0008,2240' => { VR => 'SQ', Name => 'TransducerPositionSequence' },
+    '0008,2242' => { VR => 'SQ', Name => 'TransducerPositionModifierSequence' },
+    '0008,2244' => { VR => 'SQ', Name => 'TransducerOrientationSequence' },
+    '0008,2246' => { VR => 'SQ', Name => 'TransducerOrientationModifierSeq' },
+    '0008,3001' => { VR => 'SQ', Name => 'AlternateRepresentationSequence' },
+    '0008,4000' => { VR => 'RET',Name => 'IdentifyingComments' },
+    '0008,9007' => { VR => 'CS', Name => 'FrameType' },
+    '0008,9092' => { VR => 'SQ', Name => 'ReferencedImageEvidenceSequence' },
+    '0008,9121' => { VR => 'SQ', Name => 'ReferencedRawDataSequence' },
+    '0008,9123' => { VR => 'UI', Name => 'CreatorVersionUID' },
+    '0008,9124' => { VR => 'SQ', Name => 'DerivationImageSequence' },
+    '0008,9154' => { VR => 'SQ', Name => 'SourceImageEvidenceSequence' },
+    '0008,9205' => { VR => 'CS', Name => 'PixelPresentation' },
+    '0008,9206' => { VR => 'CS', Name => 'VolumetricProperties' },
+    '0008,9207' => { VR => 'CS', Name => 'VolumeBasedCalculationTechnique' },
+    '0008,9208' => { VR => 'CS', Name => 'ComplexImageComponent' },
+    '0008,9209' => { VR => 'CS', Name => 'AcquisitionContrast' },
+    '0008,9215' => { VR => 'SQ', Name => 'DerivationCodeSequence' },
+    '0008,9237' => { VR => 'SQ', Name => 'GrayscalePresentationStateSequence' },
+    # patient group
+    '0010,0000' => { VR => 'UL', Name => 'PatientGroupLength' },
+    '0010,0010' => { VR => 'PN', Name => 'PatientsName' },
+    '0010,0020' => { VR => 'LO', Name => 'PatientID' },
+    '0010,0021' => { VR => 'LO', Name => 'IssuerOfPatientID' },
+    '0010,0030' => { VR => 'DA', Name => 'PatientsBirthDate' },
+    '0010,0032' => { VR => 'TM', Name => 'PatientsBirthTime' },
+    '0010,0040' => { VR => 'CS', Name => 'PatientsSex' },
+    '0010,0050' => { VR => 'SQ', Name => 'PatientsInsurancePlanCodeSequence' },
+    '0010,0101' => { VR => 'SQ', Name => 'PatientsPrimaryLanguageCodeSeq' },
+    '0010,0102' => { VR => 'SQ', Name => 'PatientsPrimaryLanguageCodeModSeq' },
+    '0010,1000' => { VR => 'LO', Name => 'OtherPatientIDs' },
+    '0010,1001' => { VR => 'PN', Name => 'OtherPatientNames' },
+    '0010,1005' => { VR => 'PN', Name => 'PatientsBirthName' },
+    '0010,1010' => { VR => 'AS', Name => 'PatientsAge' },
+    '0010,1020' => { VR => 'DS', Name => 'PatientsSize' },
+    '0010,1030' => { VR => 'DS', Name => 'PatientsWeight' },
+    '0010,1040' => { VR => 'LO', Name => 'PatientsAddress' },
+    '0010,1050' => { VR => 'RET',Name => 'InsurancePlanIdentification' },
+    '0010,1060' => { VR => 'PN', Name => 'PatientsMothersBirthName' },
+    '0010,1080' => { VR => 'LO', Name => 'MilitaryRank' },
+    '0010,1081' => { VR => 'LO', Name => 'BranchOfService' },
+    '0010,1090' => { VR => 'LO', Name => 'MedicalRecordLocator' },
+    '0010,2000' => { VR => 'LO', Name => 'MedicalAlerts' },
+    '0010,2110' => { VR => 'LO', Name => 'ContrastAllergies' },
+    '0010,2150' => { VR => 'LO', Name => 'CountryOfResidence' },
+    '0010,2152' => { VR => 'LO', Name => 'RegionOfResidence' },
+    '0010,2154' => { VR => 'SH', Name => 'PatientsTelephoneNumbers' },
+    '0010,2160' => { VR => 'SH', Name => 'EthnicGroup' },
+    '0010,2180' => { VR => 'SH', Name => 'Occupation' },
+    '0010,21A0' => { VR => 'CS', Name => 'SmokingStatus' },
+    '0010,21B0' => { VR => 'LT', Name => 'AdditionalPatientHistory' },
+    '0010,21C0' => { VR => 'US', Name => 'PregnancyStatus' },
+    '0010,21D0' => { VR => 'DA', Name => 'LastMenstrualDate' },
+    '0010,21F0' => { VR => 'LO', Name => 'PatientsReligiousPreference' },
+    '0010,4000' => { VR => 'LT', Name => 'PatientComments' },
+    '0012,0010' => { VR => 'LO', Name => 'ClinicalTrialSponsorName' },
+    '0012,0020' => { VR => 'LO', Name => 'ClinicalTrialProtocolID' },
+    '0012,0021' => { VR => 'LO', Name => 'ClinicalTrialProtocolName' },
+    '0012,0030' => { VR => 'LO', Name => 'ClinicalTrialSiteID' },
+    '0012,0031' => { VR => 'LO', Name => 'ClinicalTrialSiteName' },
+    '0012,0040' => { VR => 'LO', Name => 'ClinicalTrialSubjectID' },
+    '0012,0042' => { VR => 'LO', Name => 'ClinicalTrialSubjectReadingID' },
+    '0012,0050' => { VR => 'LO', Name => 'ClinicalTrialTimePointID' },
+    '0012,0051' => { VR => 'ST', Name => 'ClinicalTrialTimePointDescription' },
+    '0012,0060' => { VR => 'LO', Name => 'ClinicalTrialCoordinatingCenter' },
+    # acquisition group
+    '0018,0000' => { VR => 'UL', Name => 'AcquisitionGroupLength' },
+    '0018,0010' => { VR => 'LO', Name => 'Contrast-BolusAgent' },
+    '0018,0012' => { VR => 'SQ', Name => 'Contrast-BolusAgentSequence' },
+    '0018,0014' => { VR => 'SQ', Name => 'Contrast-BolusAdministrationRoute' },
+    '0018,0015' => { VR => 'CS', Name => 'BodyPartExamined' },
+    '0018,0020' => { VR => 'CS', Name => 'ScanningSequence' },
+    '0018,0021' => { VR => 'CS', Name => 'SequenceVariant' },
+    '0018,0022' => { VR => 'CS', Name => 'ScanOptions' },
+    '0018,0023' => { VR => 'CS', Name => 'MRAcquisitionType' },
+    '0018,0024' => { VR => 'SH', Name => 'SequenceName' },
+    '0018,0025' => { VR => 'CS', Name => 'AngioFlag' },
+    '0018,0026' => { VR => 'SQ', Name => 'InterventionDrugInformationSeq' },
+    '0018,0027' => { VR => 'TM', Name => 'InterventionDrugStopTime' },
+    '0018,0028' => { VR => 'DS', Name => 'InterventionDrugDose' },
+    '0018,0029' => { VR => 'SQ', Name => 'InterventionDrugSequence' },
+    '0018,002A' => { VR => 'SQ', Name => 'AdditionalDrugSequence' },
+    '0018,0030' => { VR => 'RET',Name => 'Radionuclide' },
+    '0018,0031' => { VR => 'LO', Name => 'Radiopharmaceutical' },
+    '0018,0032' => { VR => 'RET',Name => 'EnergyWindowCenterline' },
+    '0018,0033' => { VR => 'RET',Name => 'EnergyWindowTotalWidth' },
+    '0018,0034' => { VR => 'LO', Name => 'InterventionDrugName' },
+    '0018,0035' => { VR => 'TM', Name => 'InterventionDrugStartTime' },
+    '0018,0036' => { VR => 'SQ', Name => 'InterventionSequence' },
+    '0018,0037' => { VR => 'RET',Name => 'TherapyType' },
+    '0018,0038' => { VR => 'CS', Name => 'InterventionStatus' },
+    '0018,0039' => { VR => 'RET',Name => 'TherapyDescription' },
+    '0018,003A' => { VR => 'ST', Name => 'InterventionDescription' },
+    '0018,0040' => { VR => 'IS', Name => 'CineRate' },
+    '0018,0050' => { VR => 'DS', Name => 'SliceThickness' },
+    '0018,0060' => { VR => 'DS', Name => 'KVP' },
+    '0018,0070' => { VR => 'IS', Name => 'CountsAccumulated' },
+    '0018,0071' => { VR => 'CS', Name => 'AcquisitionTerminationCondition' },
+    '0018,0072' => { VR => 'DS', Name => 'EffectiveDuration' },
+    '0018,0073' => { VR => 'CS', Name => 'AcquisitionStartCondition' },
+    '0018,0074' => { VR => 'IS', Name => 'AcquisitionStartConditionData' },
+    '0018,0075' => { VR => 'IS', Name => 'AcquisitionEndConditionData' },
+    '0018,0080' => { VR => 'DS', Name => 'RepetitionTime' },
+    '0018,0081' => { VR => 'DS', Name => 'EchoTime' },
+    '0018,0082' => { VR => 'DS', Name => 'InversionTime' },
+    '0018,0083' => { VR => 'DS', Name => 'NumberOfAverages' },
+    '0018,0084' => { VR => 'DS', Name => 'ImagingFrequency' },
+    '0018,0085' => { VR => 'SH', Name => 'ImagedNucleus' },
+    '0018,0086' => { VR => 'IS', Name => 'EchoNumber' },
+    '0018,0087' => { VR => 'DS', Name => 'MagneticFieldStrength' },
+    '0018,0088' => { VR => 'DS', Name => 'SpacingBetweenSlices' },
+    '0018,0089' => { VR => 'IS', Name => 'NumberOfPhaseEncodingSteps' },
+    '0018,0090' => { VR => 'DS', Name => 'DataCollectionDiameter' },
+    '0018,0091' => { VR => 'IS', Name => 'EchoTrainLength' },
+    '0018,0093' => { VR => 'DS', Name => 'PercentSampling' },
+    '0018,0094' => { VR => 'DS', Name => 'PercentPhaseFieldOfView' },
+    '0018,0095' => { VR => 'DS', Name => 'PixelBandwidth' },
+    '0018,1000' => { VR => 'LO', Name => 'DeviceSerialNumber' },
+    '0018,1004' => { VR => 'LO', Name => 'PlateID' },
+    '0018,1010' => { VR => 'LO', Name => 'SecondaryCaptureDeviceID' },
+    '0018,1011' => { VR => 'LO', Name => 'HardcopyCreationDeviceID' },
+    '0018,1012' => { VR => 'DA', Name => 'DateOfSecondaryCapture' },
+    '0018,1014' => { VR => 'TM', Name => 'TimeOfSecondaryCapture' },
+    '0018,1016' => { VR => 'LO', Name => 'SecondaryCaptureDeviceManufacturer' },
+    '0018,1017' => { VR => 'LO', Name => 'HardcopyDeviceManufacturer' },
+    '0018,1018' => { VR => 'LO', Name => 'SecondaryCaptureDeviceModelName' },
+    '0018,1019' => { VR => 'LO', Name => 'SecondaryCaptureDeviceSoftwareVers' },
+    '0018,101A' => { VR => 'LO', Name => 'HardcopyDeviceSoftwareVersion' },
+    '0018,101B' => { VR => 'LO', Name => 'HardcopyDeviceModelName' },
+    '0018,1020' => { VR => 'LO', Name => 'SoftwareVersion' },
+    '0018,1022' => { VR => 'SH', Name => 'VideoImageFormatAcquired' },
+    '0018,1023' => { VR => 'LO', Name => 'DigitalImageFormatAcquired' },
+    '0018,1030' => { VR => 'LO', Name => 'ProtocolName' },
+    '0018,1040' => { VR => 'LO', Name => 'Contrast-BolusRoute' },
+    '0018,1041' => { VR => 'DS', Name => 'Contrast-BolusVolume' },
+    '0018,1042' => { VR => 'TM', Name => 'Contrast-BolusStartTime' },
+    '0018,1043' => { VR => 'TM', Name => 'Contrast-BolusStopTime' },
+    '0018,1044' => { VR => 'DS', Name => 'Contrast-BolusTotalDose' },
+    '0018,1045' => { VR => 'IS', Name => 'SyringeCounts' },
+    '0018,1046' => { VR => 'DS', Name => 'ContrastFlowRate' },
+    '0018,1047' => { VR => 'DS', Name => 'ContrastFlowDuration' },
+    '0018,1048' => { VR => 'CS', Name => 'Contrast-BolusIngredient' },
+    '0018,1049' => { VR => 'DS', Name => 'Contrast-BolusConcentration' },
+    '0018,1050' => { VR => 'DS', Name => 'SpatialResolution' },
+    '0018,1060' => { VR => 'DS', Name => 'TriggerTime' },
+    '0018,1061' => { VR => 'LO', Name => 'TriggerSourceOrType' },
+    '0018,1062' => { VR => 'IS', Name => 'NominalInterval' },
+    '0018,1063' => { VR => 'DS', Name => 'FrameTime' },
+    '0018,1064' => { VR => 'LO', Name => 'FramingType' },
+    '0018,1065' => { VR => 'DS', Name => 'FrameTimeVector' },
+    '0018,1066' => { VR => 'DS', Name => 'FrameDelay' },
+    '0018,1067' => { VR => 'DS', Name => 'ImageTriggerDelay' },
+    '0018,1068' => { VR => 'DS', Name => 'MultiplexGroupTimeOffset' },
+    '0018,1069' => { VR => 'DS', Name => 'TriggerTimeOffset' },
+    '0018,106A' => { VR => 'CS', Name => 'SynchronizationTrigger' },
+    '0018,106C' => { VR => 'US', Name => 'SynchronizationChannel' },
+    '0018,106E' => { VR => 'UL', Name => 'TriggerSamplePosition' },
+    '0018,1070' => { VR => 'LO', Name => 'RadiopharmaceuticalRoute' },
+    '0018,1071' => { VR => 'DS', Name => 'RadiopharmaceuticalVolume' },
+    '0018,1072' => { VR => 'TM', Name => 'RadiopharmaceuticalStartTime' },
+    '0018,1073' => { VR => 'TM', Name => 'RadiopharmaceuticalStopTime' },
+    '0018,1074' => { VR => 'DS', Name => 'RadionuclideTotalDose' },
+    '0018,1075' => { VR => 'DS', Name => 'RadionuclideHalfLife' },
+    '0018,1076' => { VR => 'DS', Name => 'RadionuclidePositronFraction' },
+    '0018,1077' => { VR => 'DS', Name => 'RadiopharmaceuticalSpecActivity' },
+    '0018,1080' => { VR => 'CS', Name => 'BeatRejectionFlag' },
+    '0018,1081' => { VR => 'IS', Name => 'LowRRValue' },
+    '0018,1082' => { VR => 'IS', Name => 'HighRRValue' },
+    '0018,1083' => { VR => 'IS', Name => 'IntervalsAcquired' },
+    '0018,1084' => { VR => 'IS', Name => 'IntervalsRejected' },
+    '0018,1085' => { VR => 'LO', Name => 'PVCRejection' },
+    '0018,1086' => { VR => 'IS', Name => 'SkipBeats' },
+    '0018,1088' => { VR => 'IS', Name => 'HeartRate' },
+    '0018,1090' => { VR => 'IS', Name => 'CardiacNumberOfImages' },
+    '0018,1094' => { VR => 'IS', Name => 'TriggerWindow' },
+    '0018,1100' => { VR => 'DS', Name => 'ReconstructionDiameter' },
+    '0018,1110' => { VR => 'DS', Name => 'DistanceSourceToDetector' },
+    '0018,1111' => { VR => 'DS', Name => 'DistanceSourceToPatient' },
+    '0018,1114' => { VR => 'DS', Name => 'EstimatedRadiographicMagnification' },
+    '0018,1120' => { VR => 'DS', Name => 'Gantry-DetectorTilt' },
+    '0018,1121' => { VR => 'DS', Name => 'Gantry-DetectorSlew' },
+    '0018,1130' => { VR => 'DS', Name => 'TableHeight' },
+    '0018,1131' => { VR => 'DS', Name => 'TableTraverse' },
+    '0018,1134' => { VR => 'CS', Name => 'TableMotion' },
+    '0018,1135' => { VR => 'DS', Name => 'TableVerticalIncrement' },
+    '0018,1136' => { VR => 'DS', Name => 'TableLateralIncrement' },
+    '0018,1137' => { VR => 'DS', Name => 'TableLongitudinalIncrement' },
+    '0018,1138' => { VR => 'DS', Name => 'TableAngle' },
+    '0018,113A' => { VR => 'CS', Name => 'TableType' },
+    '0018,1140' => { VR => 'CS', Name => 'RotationDirection' },
+    '0018,1141' => { VR => 'DS', Name => 'AngularPosition' },
+    '0018,1142' => { VR => 'DS', Name => 'RadialPosition' },
+    '0018,1143' => { VR => 'DS', Name => 'ScanArc' },
+    '0018,1144' => { VR => 'DS', Name => 'AngularStep' },
+    '0018,1145' => { VR => 'DS', Name => 'CenterOfRotationOffset' },
+    '0018,1146' => { VR => 'RET',Name => 'RotationOffset' },
+    '0018,1147' => { VR => 'CS', Name => 'FieldOfViewShape' },
+    '0018,1149' => { VR => 'IS', Name => 'FieldOfViewDimensions' },
+    '0018,1150' => { VR => 'IS', Name => 'ExposureTime' },
+    '0018,1151' => { VR => 'IS', Name => 'XRayTubeCurrent' },
+    '0018,1152' => { VR => 'IS', Name => 'Exposure' },
+    '0018,1153' => { VR => 'IS', Name => 'ExposureInMicroAmpSec' },
+    '0018,1154' => { VR => 'DS', Name => 'AveragePulseWidth' },
+    '0018,1155' => { VR => 'CS', Name => 'RadiationSetting' },
+    '0018,1156' => { VR => 'CS', Name => 'RectificationType' },
+    '0018,115A' => { VR => 'CS', Name => 'RadiationMode' },
+    '0018,115E' => { VR => 'DS', Name => 'ImageAreaDoseProduct' },
+    '0018,1160' => { VR => 'SH', Name => 'FilterType' },
+    '0018,1161' => { VR => 'LO', Name => 'TypeOfFilters' },
+    '0018,1162' => { VR => 'DS', Name => 'IntensifierSize' },
+    '0018,1164' => { VR => 'DS', Name => 'ImagerPixelSpacing' },
+    '0018,1166' => { VR => 'CS', Name => 'Grid' },
+    '0018,1170' => { VR => 'IS', Name => 'GeneratorPower' },
+    '0018,1180' => { VR => 'SH', Name => 'Collimator-GridName' },
+    '0018,1181' => { VR => 'CS', Name => 'CollimatorType' },
+    '0018,1182' => { VR => 'IS', Name => 'FocalDistance' },
+    '0018,1183' => { VR => 'DS', Name => 'XFocusCenter' },
+    '0018,1184' => { VR => 'DS', Name => 'YFocusCenter' },
+    '0018,1190' => { VR => 'DS', Name => 'FocalSpot' },
+    '0018,1191' => { VR => 'CS', Name => 'AnodeTargetMaterial' },
+    '0018,11A0' => { VR => 'DS', Name => 'BodyPartThickness' },
+    '0018,11A2' => { VR => 'DS', Name => 'CompressionForce' },
+    '0018,1200' => { VR => 'DA', Name => 'DateOfLastCalibration' },
+    '0018,1201' => { VR => 'TM', Name => 'TimeOfLastCalibration' },
+    '0018,1210' => { VR => 'SH', Name => 'ConvolutionKernel' },
+    '0018,1240' => { VR => 'RET',Name => 'Upper-LowerPixelValues' },
+    '0018,1242' => { VR => 'IS', Name => 'ActualFrameDuration' },
+    '0018,1243' => { VR => 'IS', Name => 'CountRate' },
+    '0018,1244' => { VR => 'US', Name => 'PreferredPlaybackSequencing' },
+    '0018,1250' => { VR => 'SH', Name => 'ReceiveCoilName' },
+    '0018,1251' => { VR => 'SH', Name => 'TransmitCoilName' },
+    '0018,1260' => { VR => 'SH', Name => 'PlateType' },
+    '0018,1261' => { VR => 'LO', Name => 'PhosphorType' },
+    '0018,1300' => { VR => 'DS', Name => 'ScanVelocity' },
+    '0018,1301' => { VR => 'CS', Name => 'WholeBodyTechnique' },
+    '0018,1302' => { VR => 'IS', Name => 'ScanLength' },
+    '0018,1310' => { VR => 'US', Name => 'AcquisitionMatrix' },
+    '0018,1312' => { VR => 'CS', Name => 'InPlanePhaseEncodingDirection' },
+    '0018,1314' => { VR => 'DS', Name => 'FlipAngle' },
+    '0018,1315' => { VR => 'CS', Name => 'VariableFlipAngleFlag' },
+    '0018,1316' => { VR => 'DS', Name => 'SAR' },
+    '0018,1318' => { VR => 'DS', Name => 'DB-Dt' },
+    '0018,1400' => { VR => 'LO', Name => 'AcquisitionDeviceProcessingDescr' },
+    '0018,1401' => { VR => 'LO', Name => 'AcquisitionDeviceProcessingCode' },
+    '0018,1402' => { VR => 'CS', Name => 'CassetteOrientation' },
+    '0018,1403' => { VR => 'CS', Name => 'CassetteSize' },
+    '0018,1404' => { VR => 'US', Name => 'ExposuresonPlate' },
+    '0018,1405' => { VR => 'IS', Name => 'RelativeXRayExposure' },
+    '0018,1450' => { VR => 'DS', Name => 'ColumnAngulation' },
+    '0018,1460' => { VR => 'DS', Name => 'TomoLayerHeight' },
+    '0018,1470' => { VR => 'DS', Name => 'TomoAngle' },
+    '0018,1480' => { VR => 'DS', Name => 'TomoTime' },
+    '0018,1490' => { VR => 'CS', Name => 'TomoType' },
+    '0018,1491' => { VR => 'CS', Name => 'TomoClass' },
+    '0018,1495' => { VR => 'IS', Name => 'NumberOfTomosynthesisSourceImages' },
+    '0018,1500' => { VR => 'CS', Name => 'PositionerMotion' },
+    '0018,1508' => { VR => 'CS', Name => 'PositionerType' },
+    '0018,1510' => { VR => 'DS', Name => 'PositionerPrimaryAngle' },
+    '0018,1511' => { VR => 'DS', Name => 'PositionerSecondaryAngle' },
+    '0018,1520' => { VR => 'DS', Name => 'PositionerPrimaryAngleIncrement' },
+    '0018,1521' => { VR => 'DS', Name => 'PositionerSecondaryAngleIncrement' },
+    '0018,1530' => { VR => 'DS', Name => 'DetectorPrimaryAngle' },
+    '0018,1531' => { VR => 'DS', Name => 'DetectorSecondaryAngle' },
+    '0018,1600' => { VR => 'CS', Name => 'ShutterShape' },
+    '0018,1602' => { VR => 'IS', Name => 'ShutterLeftVerticalEdge' },
+    '0018,1604' => { VR => 'IS', Name => 'ShutterRightVerticalEdge' },
+    '0018,1606' => { VR => 'IS', Name => 'ShutterUpperHorizontalEdge' },
+    '0018,1608' => { VR => 'IS', Name => 'ShutterLowerHorizontalEdge' },
+    '0018,1610' => { VR => 'IS', Name => 'CenterOfCircularShutter' },
+    '0018,1612' => { VR => 'IS', Name => 'RadiusOfCircularShutter' },
+    '0018,1620' => { VR => 'IS', Name => 'VerticesOfPolygonalShutter' },
+    '0018,1622' => { VR => 'US', Name => 'ShutterPresentationValue' },
+    '0018,1623' => { VR => 'US', Name => 'ShutterOverlayGroup' },
+    '0018,1700' => { VR => 'CS', Name => 'CollimatorShape' },
+    '0018,1702' => { VR => 'IS', Name => 'CollimatorLeftVerticalEdge' },
+    '0018,1704' => { VR => 'IS', Name => 'CollimatorRightVerticalEdge' },
+    '0018,1706' => { VR => 'IS', Name => 'CollimatorUpperHorizontalEdge' },
+    '0018,1708' => { VR => 'IS', Name => 'CollimatorLowerHorizontalEdge' },
+    '0018,1710' => { VR => 'IS', Name => 'CenterOfCircularCollimator' },
+    '0018,1712' => { VR => 'IS', Name => 'RadiusOfCircularCollimator' },
+    '0018,1720' => { VR => 'IS', Name => 'VerticesOfPolygonalCollimator' },
+    '0018,1800' => { VR => 'CS', Name => 'AcquisitionTimeSynchronized' },
+    '0018,1801' => { VR => 'SH', Name => 'TimeSource' },
+    '0018,1802' => { VR => 'CS', Name => 'TimeDistributionProtocol' },
+    '0018,1803' => { VR => 'LO', Name => 'NTPSourceAddress' },
+    '0018,2001' => { VR => 'IS', Name => 'PageNumberVector' },
+    '0018,2002' => { VR => 'SH', Name => 'FrameLabelVector' },
+    '0018,2003' => { VR => 'DS', Name => 'FramePrimaryAngleVector' },
+    '0018,2004' => { VR => 'DS', Name => 'FrameSecondaryAngleVector' },
+    '0018,2005' => { VR => 'DS', Name => 'SliceLocationVector' },
+    '0018,2006' => { VR => 'SH', Name => 'DisplayWindowLabelVector' },
+    '0018,2010' => { VR => 'DS', Name => 'NominalScannedPixelSpacing' },
+    '0018,2020' => { VR => 'CS', Name => 'DigitizingDeviceTransportDirection' },
+    '0018,2030' => { VR => 'DS', Name => 'RotationOfScannedFilm' },
+    '0018,3100' => { VR => 'CS', Name => 'IVUSAcquisition' },
+    '0018,3101' => { VR => 'DS', Name => 'IVUSPullbackRate' },
+    '0018,3102' => { VR => 'DS', Name => 'IVUSGatedRate' },
+    '0018,3103' => { VR => 'IS', Name => 'IVUSPullbackStartFrameNumber' },
+    '0018,3104' => { VR => 'IS', Name => 'IVUSPullbackStopFrameNumber' },
+    '0018,3105' => { VR => 'IS', Name => 'LesionNumber' },
+    '0018,4000' => { VR => 'RET',Name => 'AcquisitionComments' },
+    '0018,5000' => { VR => 'SH', Name => 'OutputPower' },
+    '0018,5010' => { VR => 'LO', Name => 'TransducerData' },
+    '0018,5012' => { VR => 'DS', Name => 'FocusDepth' },
+    '0018,5020' => { VR => 'LO', Name => 'ProcessingFunction' },
+    '0018,5021' => { VR => 'LO', Name => 'PostprocessingFunction' },
+    '0018,5022' => { VR => 'DS', Name => 'MechanicalIndex' },
+    '0018,5024' => { VR => 'DS', Name => 'BoneThermalIndex' },
+    '0018,5026' => { VR => 'DS', Name => 'CranialThermalIndex' },
+    '0018,5027' => { VR => 'DS', Name => 'SoftTissueThermalIndex' },
+    '0018,5028' => { VR => 'DS', Name => 'SoftTissueFocusThermalIndex' },
+    '0018,5029' => { VR => 'DS', Name => 'SoftTissueSurfaceThermalIndex' },
+    '0018,5030' => { VR => 'RET',Name => 'DynamicRange' },
+    '0018,5040' => { VR => 'RET',Name => 'TotalGain' },
+    '0018,5050' => { VR => 'IS', Name => 'DepthOfScanField' },
+    '0018,5100' => { VR => 'CS', Name => 'PatientPosition' },
+    '0018,5101' => { VR => 'CS', Name => 'ViewPosition' },
+    '0018,5104' => { VR => 'SQ', Name => 'ProjectionEponymousNameCodeSeq' },
+    '0018,5210' => { VR => 'RET',Name => 'ImageTransformationMatrix' },
+    '0018,5212' => { VR => 'RET',Name => 'ImageTranslationVector' },
+    '0018,6000' => { VR => 'DS', Name => 'Sensitivity' },
+    '0018,6011' => { VR => 'SQ', Name => 'SequenceOfUltrasoundRegions' },
+    '0018,6012' => { VR => 'US', Name => 'RegionSpatialFormat' },
+    '0018,6014' => { VR => 'US', Name => 'RegionDataType' },
+    '0018,6016' => { VR => 'UL', Name => 'RegionFlags' },
+    '0018,6018' => { VR => 'UL', Name => 'RegionLocationMinX0' },
+    '0018,601A' => { VR => 'UL', Name => 'RegionLocationMinY0' },
+    '0018,601C' => { VR => 'UL', Name => 'RegionLocationMaxX1' },
+    '0018,601E' => { VR => 'UL', Name => 'RegionLocationMaxY1' },
+    '0018,6020' => { VR => 'SL', Name => 'ReferencePixelX0' },
+    '0018,6022' => { VR => 'SL', Name => 'ReferencePixelY0' },
+    '0018,6024' => { VR => 'US', Name => 'PhysicalUnitsXDirection' },
+    '0018,6026' => { VR => 'US', Name => 'PhysicalUnitsYDirection' },
+    '0018,6028' => { VR => 'FD', Name => 'ReferencePixelPhysicalValueX' },
+    '0018,602A' => { VR => 'FD', Name => 'ReferencePixelPhysicalValueY' },
+    '0018,602C' => { VR => 'FD', Name => 'PhysicalDeltaX' },
+    '0018,602E' => { VR => 'FD', Name => 'PhysicalDeltaY' },
+    '0018,6030' => { VR => 'UL', Name => 'TransducerFrequency' },
+    '0018,6031' => { VR => 'CS', Name => 'TransducerType' },
+    '0018,6032' => { VR => 'UL', Name => 'PulseRepetitionFrequency' },
+    '0018,6034' => { VR => 'FD', Name => 'DopplerCorrectionAngle' },
+    '0018,6036' => { VR => 'FD', Name => 'SteeringAngle' },
+    '0018,6038' => { VR => 'RET',Name => 'DopplerSampleVolumeXPositionUL' },
+    '0018,6039' => { VR => 'SL', Name => 'DopplerSampleVolumeXPosition' },
+    '0018,603A' => { VR => 'RET',Name => 'DopplerSampleVolumeYPositionUL' },
+    '0018,603B' => { VR => 'SL', Name => 'DopplerSampleVolumeYPosition' },
+    '0018,603C' => { VR => 'RET',Name => 'TMLinePositionX0UL' },
+    '0018,603D' => { VR => 'SL', Name => 'TMLinePositionX0' },
+    '0018,603E' => { VR => 'RET',Name => 'TMLinePositionY0UL' },
+    '0018,603F' => { VR => 'SL', Name => 'TMLinePositionY0' },
+    '0018,6040' => { VR => 'RET',Name => 'TMLinePositionX1UL' },
+    '0018,6041' => { VR => 'SL', Name => 'TMLinePositionX1' },
+    '0018,6042' => { VR => 'RET',Name => 'TMLinePositionY1UL' },
+    '0018,6043' => { VR => 'SL', Name => 'TMLinePositionY1' },
+    '0018,6044' => { VR => 'US', Name => 'PixelComponentOrganization' },
+    '0018,6046' => { VR => 'UL', Name => 'PixelComponentMask' },
+    '0018,6048' => { VR => 'UL', Name => 'PixelComponentRangeStart' },
+    '0018,604A' => { VR => 'UL', Name => 'PixelComponentRangeStop' },
+    '0018,604C' => { VR => 'US', Name => 'PixelComponentPhysicalUnits' },
+    '0018,604E' => { VR => 'US', Name => 'PixelComponentDataType' },
+    '0018,6050' => { VR => 'UL', Name => 'NumberOfTableBreakPoints' },
+    '0018,6052' => { VR => 'UL', Name => 'TableOfXBreakPoints' },
+    '0018,6054' => { VR => 'FD', Name => 'TableOfYBreakPoints' },
+    '0018,6056' => { VR => 'UL', Name => 'NumberOfTableEntries' },
+    '0018,6058' => { VR => 'UL', Name => 'TableOfPixelValues' },
+    '0018,605A' => { VR => 'FL', Name => 'TableOfParameterValues' },
+    '0018,6060' => { VR => 'FL', Name => 'RWaveTimeVector' },
+    '0018,7000' => { VR => 'CS', Name => 'DetectorConditionsNominalFlag' },
+    '0018,7001' => { VR => 'DS', Name => 'DetectorTemperature' },
+    '0018,7004' => { VR => 'CS', Name => 'DetectorType' },
+    '0018,7005' => { VR => 'CS', Name => 'DetectorConfiguration' },
+    '0018,7006' => { VR => 'LT', Name => 'DetectorDescription' },
+    '0018,7008' => { VR => 'LT', Name => 'DetectorMode' },
+    '0018,700A' => { VR => 'SH', Name => 'DetectorID' },
+    '0018,700C' => { VR => 'DA', Name => 'DateOfLastDetectorCalibration' },
+    '0018,700E' => { VR => 'TM', Name => 'TimeOfLastDetectorCalibration' },
+    '0018,7010' => { VR => 'IS', Name => 'DetectorExposuresSinceCalibration' },
+    '0018,7011' => { VR => 'IS', Name => 'DetectorExposuresSinceManufactured' },
+    '0018,7012' => { VR => 'DS', Name => 'DetectorTimeSinceLastExposure' },
+    '0018,7014' => { VR => 'DS', Name => 'DetectorActiveTime' },
+    '0018,7016' => { VR => 'DS', Name => 'DetectorActiveOffsetFromExposure' },
+    '0018,701A' => { VR => 'DS', Name => 'DetectorBinning' },
+    '0018,7020' => { VR => 'DS', Name => 'DetectorElementPhysicalSize' },
+    '0018,7022' => { VR => 'DS', Name => 'DetectorElementSpacing' },
+    '0018,7024' => { VR => 'CS', Name => 'DetectorActiveShape' },
+    '0018,7026' => { VR => 'DS', Name => 'DetectorActiveDimensions' },
+    '0018,7028' => { VR => 'DS', Name => 'DetectorActiveOrigin' },
+    '0018,702A' => { VR => 'LO', Name => 'DetectorManufacturerName' },
+    '0018,702B' => { VR => 'LO', Name => 'DetectorManufacturersModelName' },
+    '0018,7030' => { VR => 'DS', Name => 'FieldOfViewOrigin' },
+    '0018,7032' => { VR => 'DS', Name => 'FieldOfViewRotation' },
+    '0018,7034' => { VR => 'CS', Name => 'FieldOfViewHorizontalFlip' },
+    '0018,7040' => { VR => 'LT', Name => 'GridAbsorbingMaterial' },
+    '0018,7041' => { VR => 'LT', Name => 'GridSpacingMaterial' },
+    '0018,7042' => { VR => 'DS', Name => 'GridThickness' },
+    '0018,7044' => { VR => 'DS', Name => 'GridPitch' },
+    '0018,7046' => { VR => 'IS', Name => 'GridAspectRatio' },
+    '0018,7048' => { VR => 'DS', Name => 'GridPeriod' },
+    '0018,704C' => { VR => 'DS', Name => 'GridFocalDistance' },
+    '0018,7050' => { VR => 'CS', Name => 'FilterMaterial' },
+    '0018,7052' => { VR => 'DS', Name => 'FilterThicknessMinimum' },
+    '0018,7054' => { VR => 'DS', Name => 'FilterThicknessMaximum' },
+    '0018,7060' => { VR => 'CS', Name => 'ExposureControlMode' },
+    '0018,7062' => { VR => 'LT', Name => 'ExposureControlModeDescription' },
+    '0018,7064' => { VR => 'CS', Name => 'ExposureStatus' },
+    '0018,7065' => { VR => 'DS', Name => 'PhototimerSetting' },
+    '0018,8150' => { VR => 'DS', Name => 'ExposureTimeInMicroSec' },
+    '0018,8151' => { VR => 'DS', Name => 'XRayTubeCurrentInMicroAmps' },
+    '0018,9004' => { VR => 'CS', Name => 'ContentQualification' },
+    '0018,9005' => { VR => 'SH', Name => 'PulseSequenceName' },
+    '0018,9006' => { VR => 'SQ', Name => 'MRImagingModifierSequence' },
+    '0018,9008' => { VR => 'CS', Name => 'EchoPulseSequence' },
+    '0018,9009' => { VR => 'CS', Name => 'InversionRecovery' },
+    '0018,9010' => { VR => 'CS', Name => 'FlowCompensation' },
+    '0018,9011' => { VR => 'CS', Name => 'MultipleSpinEcho' },
+    '0018,9012' => { VR => 'CS', Name => 'MultiPlanarExcitation' },
+    '0018,9014' => { VR => 'CS', Name => 'PhaseContrast' },
+    '0018,9015' => { VR => 'CS', Name => 'TimeOfFlightContrast' },
+    '0018,9016' => { VR => 'CS', Name => 'Spoiling' },
+    '0018,9017' => { VR => 'CS', Name => 'SteadyStatePulseSequence' },
+    '0018,9018' => { VR => 'CS', Name => 'EchoPlanarPulseSequence' },
+    '0018,9019' => { VR => 'FD', Name => 'TagAngleFirstAxis' },
+    '0018,9020' => { VR => 'CS', Name => 'MagnetizationTransfer' },
+    '0018,9021' => { VR => 'CS', Name => 'T2Preparation' },
+    '0018,9022' => { VR => 'CS', Name => 'BloodSignalNulling' },
+    '0018,9022' => { VR => 'CS', Name => 'BloodSignalNulling' },
+    '0018,9024' => { VR => 'CS', Name => 'SaturationRecovery' },
+    '0018,9025' => { VR => 'CS', Name => 'SpectrallySelectedSuppression' },
+    '0018,9026' => { VR => 'CS', Name => 'SpectrallySelectedExcitation' },
+    '0018,9027' => { VR => 'CS', Name => 'SpatialPreSaturation' },
+    '0018,9028' => { VR => 'CS', Name => 'Tagging' },
+    '0018,9029' => { VR => 'CS', Name => 'OversamplingPhase' },
+    '0018,9030' => { VR => 'FD', Name => 'TagSpacingFirstDimension' },
+    '0018,9032' => { VR => 'CS', Name => 'GeometryOfKSpaceTraversal' },
+    '0018,9033' => { VR => 'CS', Name => 'SegmentedKSpaceTraversal' },
+    '0018,9034' => { VR => 'CS', Name => 'RectilinearPhaseEncodeReordering' },
+    '0018,9035' => { VR => 'FD', Name => 'TagThickness' },
+    '0018,9036' => { VR => 'CS', Name => 'PartialFourierDirection' },
+    '0018,9037' => { VR => 'CS', Name => 'CardiacSynchronizationTechnique' },
+    '0018,9041' => { VR => 'LO', Name => 'ReceiveCoilManufacturerName' },
+    '0018,9042' => { VR => 'SQ', Name => 'MRReceiveCoilSequence' },
+    '0018,9043' => { VR => 'CS', Name => 'ReceiveCoilType' },
+    '0018,9044' => { VR => 'CS', Name => 'QuadratureReceiveCoil' },
+    '0018,9045' => { VR => 'SQ', Name => 'MultiCoilDefinitionSequence' },
+    '0018,9046' => { VR => 'LO', Name => 'MultiCoilConfiguration' },
+    '0018,9047' => { VR => 'SH', Name => 'MultiCoilElementName' },
+    '0018,9048' => { VR => 'CS', Name => 'MultiCoilElementUsed' },
+    '0018,9049' => { VR => 'SQ', Name => 'MRTransmitCoilSequence' },
+    '0018,9050' => { VR => 'LO', Name => 'TransmitCoilManufacturerName' },
+    '0018,9051' => { VR => 'CS', Name => 'TransmitCoilType' },
+    '0018,9052' => { VR => 'FD', Name => 'SpectralWidth' },
+    '0018,9053' => { VR => 'FD', Name => 'ChemicalShiftReference' },
+    '0018,9054' => { VR => 'CS', Name => 'VolumeLocalizationTechnique' },
+    '0018,9058' => { VR => 'US', Name => 'MRAcquisitionFrequencyEncodeSteps' },
+    '0018,9059' => { VR => 'CS', Name => 'Decoupling' },
+    '0018,9060' => { VR => 'CS', Name => 'DecoupledNucleus' },
+    '0018,9061' => { VR => 'FD', Name => 'DecouplingFrequency' },
+    '0018,9062' => { VR => 'CS', Name => 'DecouplingMethod' },
+    '0018,9063' => { VR => 'FD', Name => 'DecouplingChemicalShiftReference' },
+    '0018,9064' => { VR => 'CS', Name => 'KSpaceFiltering' },
+    '0018,9065' => { VR => 'CS', Name => 'TimeDomainFiltering' },
+    '0018,9066' => { VR => 'US', Name => 'NumberOfZeroFills' },
+    '0018,9067' => { VR => 'CS', Name => 'BaselineCorrection' },
+    '0018,9069' => { VR => 'FD', Name => 'ParallelReductionFactorInPlane' },
+    '0018,9070' => { VR => 'FD', Name => 'CardiacRRIntervalSpecified' },
+    '0018,9073' => { VR => 'FD', Name => 'AcquisitionDuration' },
+    '0018,9074' => { VR => 'DT', Name => 'FrameAcquisitionDatetime' },
+    '0018,9075' => { VR => 'CS', Name => 'DiffusionDirectionality' },
+    '0018,9076' => { VR => 'SQ', Name => 'DiffusionGradientDirectionSequence' },
+    '0018,9077' => { VR => 'CS', Name => 'ParallelAcquisition' },
+    '0018,9078' => { VR => 'CS', Name => 'ParallelAcquisitionTechnique' },
+    '0018,9079' => { VR => 'FD', Name => 'InversionTimes' },
+    '0018,9080' => { VR => 'ST', Name => 'MetaboliteMapDescription' },
+    '0018,9081' => { VR => 'CS', Name => 'PartialFourier' },
+    '0018,9082' => { VR => 'FD', Name => 'EffectiveEchoTime' },
+    '0018,9083' => { VR => 'SQ', Name => 'MetaboliteMapCodeSequence' },
+    '0018,9084' => { VR => 'SQ', Name => 'ChemicalShiftSequence' },
+    '0018,9085' => { VR => 'CS', Name => 'CardiacSignalSource' },
+    '0018,9087' => { VR => 'FD', Name => 'DiffusionBValue' },
+    '0018,9089' => { VR => 'FD', Name => 'DiffusionGradientOrientation' },
+    '0018,9090' => { VR => 'FD', Name => 'VelocityEncodingDirection' },
+    '0018,9091' => { VR => 'FD', Name => 'VelocityEncodingMinimumValue' },
+    '0018,9093' => { VR => 'US', Name => 'NumberOfKSpaceTrajectories' },
+    '0018,9094' => { VR => 'CS', Name => 'CoverageOfKSpace' },
+    '0018,9095' => { VR => 'UL', Name => 'SpectroscopyAcquisitionPhaseRows' },
+    '0018,9098' => { VR => 'FD', Name => 'TransmitterFrequency' },
+    '0018,9100' => { VR => 'CS', Name => 'ResonantNucleus' },
+    '0018,9101' => { VR => 'CS', Name => 'FrequencyCorrection' },
+    '0018,9103' => { VR => 'SQ', Name => 'MRSpectroscopyFOV-GeometrySequence' },
+    '0018,9104' => { VR => 'FD', Name => 'SlabThickness' },
+    '0018,9105' => { VR => 'FD', Name => 'SlabOrientation' },
+    '0018,9106' => { VR => 'FD', Name => 'MidSlabPosition' },
+    '0018,9107' => { VR => 'SQ', Name => 'MRSpatialSaturationSequence' },
+    '0018,9112' => { VR => 'SQ', Name => 'MRTimingAndRelatedParametersSeq' },
+    '0018,9114' => { VR => 'SQ', Name => 'MREchoSequence' },
+    '0018,9115' => { VR => 'SQ', Name => 'MRModifierSequence' },
+    '0018,9117' => { VR => 'SQ', Name => 'MRDiffusionSequence' },
+    '0018,9118' => { VR => 'SQ', Name => 'CardiacTriggerSequence' },
+    '0018,9119' => { VR => 'SQ', Name => 'MRAveragesSequence' },
+    '0018,9125' => { VR => 'SQ', Name => 'MRFOV-GeometrySequence' },
+    '0018,9126' => { VR => 'SQ', Name => 'VolumeLocalizationSequence' },
+    '0018,9127' => { VR => 'UL', Name => 'SpectroscopyAcquisitionDataColumns' },
+    '0018,9147' => { VR => 'CS', Name => 'DiffusionAnisotropyType' },
+    '0018,9151' => { VR => 'DT', Name => 'FrameReferenceDatetime' },
+    '0018,9152' => { VR => 'SQ', Name => 'MRMetaboliteMapSequence' },
+    '0018,9155' => { VR => 'FD', Name => 'ParallelReductionFactorOutOfPlane' },
+    '0018,9159' => { VR => 'UL', Name => 'SpectroscopyOutOfPlanePhaseSteps' },
+    '0018,9166' => { VR => 'CS', Name => 'BulkMotionStatus' },
+    '0018,9168' => { VR => 'FD', Name => 'ParallelReductionFactSecondInPlane' },
+    '0018,9169' => { VR => 'CS', Name => 'CardiacBeatRejectionTechnique' },
+    '0018,9170' => { VR => 'CS', Name => 'RespiratoryMotionCompTechnique' },
+    '0018,9171' => { VR => 'CS', Name => 'RespiratorySignalSource' },
+    '0018,9172' => { VR => 'CS', Name => 'BulkMotionCompensationTechnique' },
+    '0018,9173' => { VR => 'CS', Name => 'BulkMotionSignalSource' },
+    '0018,9174' => { VR => 'CS', Name => 'ApplicableSafetyStandardAgency' },
+    '0018,9175' => { VR => 'LO', Name => 'ApplicableSafetyStandardDescr' },
+    '0018,9176' => { VR => 'SQ', Name => 'OperatingModeSequence' },
+    '0018,9177' => { VR => 'CS', Name => 'OperatingModeType' },
+    '0018,9178' => { VR => 'CS', Name => 'OperatingMode' },
+    '0018,9179' => { VR => 'CS', Name => 'SpecificAbsorptionRateDefinition' },
+    '0018,9180' => { VR => 'CS', Name => 'GradientOutputType' },
+    '0018,9181' => { VR => 'FD', Name => 'SpecificAbsorptionRateValue' },
+    '0018,9182' => { VR => 'FD', Name => 'GradientOutput' },
+    '0018,9183' => { VR => 'CS', Name => 'FlowCompensationDirection' },
+    '0018,9184' => { VR => 'FD', Name => 'TaggingDelay' },
+    '0018,9195' => { VR => 'FD', Name => 'ChemicalShiftsMinIntegrateLimitHz' },
+    '0018,9196' => { VR => 'FD', Name => 'ChemicalShiftsMaxIntegrateLimitHz' },
+    '0018,9197' => { VR => 'SQ', Name => 'MRVelocityEncodingSequence' },
+    '0018,9198' => { VR => 'CS', Name => 'FirstOrderPhaseCorrection' },
+    '0018,9199' => { VR => 'CS', Name => 'WaterReferencedPhaseCorrection' },
+    '0018,9200' => { VR => 'CS', Name => 'MRSpectroscopyAcquisitionType' },
+    '0018,9214' => { VR => 'CS', Name => 'RespiratoryCyclePosition' },
+    '0018,9217' => { VR => 'FD', Name => 'VelocityEncodingMaximumValue' },
+    '0018,9218' => { VR => 'FD', Name => 'TagSpacingSecondDimension' },
+    '0018,9219' => { VR => 'SS', Name => 'TagAngleSecondAxis' },
+    '0018,9220' => { VR => 'FD', Name => 'FrameAcquisitionDuration' },
+    '0018,9226' => { VR => 'SQ', Name => 'MRImageFrameTypeSequence' },
+    '0018,9227' => { VR => 'SQ', Name => 'MRSpectroscopyFrameTypeSequence' },
+    '0018,9231' => { VR => 'US', Name => 'MRAcqPhaseEncodingStepsInPlane' },
+    '0018,9232' => { VR => 'US', Name => 'MRAcqPhaseEncodingStepsOutOfPlane' },
+    '0018,9234' => { VR => 'UL', Name => 'SpectroscopyAcqPhaseColumns' },
+    '0018,9236' => { VR => 'CS', Name => 'CardiacCyclePosition' },
+    '0018,9239' => { VR => 'SQ', Name => 'SpecificAbsorptionRateSequence' },
+    '0018,9240' => { VR => 'US', Name => 'RFEchoTrainLength' },
+    '0018,9241' => { VR => 'US', Name => 'GradientEchoTrainLength' },
+    '0018,9295' => { VR => 'FD', Name => 'ChemicalShiftsMinIntegrateLimitPPM' },
+    '0018,9296' => { VR => 'FD', Name => 'ChemicalShiftsMaxIntegrateLimitPPM' },
+    '0018,9301' => { VR => 'SQ', Name => 'CTAcquisitionTypeSequence' },
+    '0018,9302' => { VR => 'CS', Name => 'AcquisitionType' },
+    '0018,9303' => { VR => 'FD', Name => 'TubeAngle' },
+    '0018,9304' => { VR => 'SQ', Name => 'CTAcquisitionDetailsSequence' },
+    '0018,9305' => { VR => 'FD', Name => 'RevolutionTime' },
+    '0018,9306' => { VR => 'FD', Name => 'SingleCollimationWidth' },
+    '0018,9307' => { VR => 'FD', Name => 'TotalCollimationWidth' },
+    '0018,9308' => { VR => 'SQ', Name => 'CTTableDynamicsSequence' },
+    '0018,9309' => { VR => 'FD', Name => 'TableSpeed' },
+    '0018,9310' => { VR => 'FD', Name => 'TableFeedPerRotation' },
+    '0018,9311' => { VR => 'FD', Name => 'SpiralPitchFactor' },
+    '0018,9312' => { VR => 'SQ', Name => 'CTGeometrySequence' },
+    '0018,9313' => { VR => 'FD', Name => 'DataCollectionCenterPatient' },
+    '0018,9314' => { VR => 'SQ', Name => 'CTReconstructionSequence' },
+    '0018,9315' => { VR => 'CS', Name => 'ReconstructionAlgorithm' },
+    '0018,9316' => { VR => 'CS', Name => 'ConvolutionKernelGroup' },
+    '0018,9317' => { VR => 'FD', Name => 'ReconstructionFieldOfView' },
+    '0018,9318' => { VR => 'FD', Name => 'ReconstructionTargetCenterPatient' },
+    '0018,9319' => { VR => 'FD', Name => 'ReconstructionAngle' },
+    '0018,9320' => { VR => 'SH', Name => 'ImageFilter' },
+    '0018,9321' => { VR => 'SQ', Name => 'CTExposureSequence' },
+    '0018,9322' => { VR => 'FD', Name => 'ReconstructionPixelSpacing' },
+    '0018,9323' => { VR => 'CS', Name => 'ExposureModulationType' },
+    '0018,9324' => { VR => 'FD', Name => 'EstimatedDoseSaving' },
+    '0018,9325' => { VR => 'SQ', Name => 'CTXRayDetailsSequence' },
+    '0018,9326' => { VR => 'SQ', Name => 'CTPositionSequence' },
+    '0018,9327' => { VR => 'FD', Name => 'TablePosition' },
+    '0018,9328' => { VR => 'FD', Name => 'ExposureTimeInMilliSec' },
+    '0018,9329' => { VR => 'SQ', Name => 'CTImageFrameTypeSequence' },
+    '0018,9330' => { VR => 'FD', Name => 'XRayTubeCurrentInMilliAmps' },
+    '0018,9332' => { VR => 'FD', Name => 'ExposureInMilliAmpSec' },
+    '0018,9333' => { VR => 'CS', Name => 'ConstantVolumeFlag' },
+    '0018,9334' => { VR => 'CS', Name => 'FluoroscopyFlag' },
+    '0018,9335' => { VR => 'FD', Name => 'SourceToDataCollectionCenterDist' },
+    '0018,9337' => { VR => 'US', Name => 'Contrast-BolusAgentNumber' },
+    '0018,9338' => { VR => 'SQ', Name => 'Contrast-BolusIngredientCodeSeq' },
+    '0018,9340' => { VR => 'SQ', Name => 'ContrastAdministrationProfileSeq' },
+    '0018,9341' => { VR => 'SQ', Name => 'Contrast-BolusUsageSequence' },
+    '0018,9342' => { VR => 'CS', Name => 'Contrast-BolusAgentAdministered' },
+    '0018,9343' => { VR => 'CS', Name => 'Contrast-BolusAgentDetected' },
+    '0018,9344' => { VR => 'CS', Name => 'Contrast-BolusAgentPhase' },
+    '0018,9345' => { VR => 'FD', Name => 'CTDIvol' },
+    '0018,A001' => { VR => 'SQ', Name => 'ContributingEquipmentSequence' },
+    '0018,A002' => { VR => 'DT', Name => 'ContributionDateTime' },
+    '0018,A003' => { VR => 'ST', Name => 'ContributionDescription' },
+    # relationship group
+    '0020,0000' => { VR => 'UL', Name => 'RelationshipGroupLength' },
+    '0020,000D' => { VR => 'UI', Name => 'StudyInstanceUID' },
+    '0020,000E' => { VR => 'UI', Name => 'SeriesInstanceUID' },
+    '0020,0010' => { VR => 'SH', Name => 'StudyID' },
+    '0020,0011' => { VR => 'IS', Name => 'SeriesNumber' },
+    '0020,0012' => { VR => 'IS', Name => 'AcquisitionNumber' },
+    '0020,0013' => { VR => 'IS', Name => 'InstanceNumber' },
+    '0020,0014' => { VR => 'RET',Name => 'IsotopeNumber' },
+    '0020,0015' => { VR => 'RET',Name => 'PhaseNumber' },
+    '0020,0016' => { VR => 'RET',Name => 'IntervalNumber' },
+    '0020,0017' => { VR => 'RET',Name => 'TimeSlotNumber' },
+    '0020,0018' => { VR => 'RET',Name => 'AngleNumber' },
+    '0020,0019' => { VR => 'IS', Name => 'ItemNumber' },
+    '0020,0020' => { VR => 'CS', Name => 'PatientOrientation' },
+    '0020,0022' => { VR => 'IS', Name => 'OverlayNumber' },
+    '0020,0024' => { VR => 'IS', Name => 'CurveNumber' },
+    '0020,0026' => { VR => 'IS', Name => 'LookupTableNumber' },
+    '0020,0030' => { VR => 'DS', Name => 'ImagePosition' },
+    '0020,0032' => { VR => 'DS', Name => 'ImagePositionPatient' },
+    '0020,0035' => { VR => 'DS', Name => 'ImageOrientation' },
+    '0020,0037' => { VR => 'DS', Name => 'ImageOrientationPatient' },
+    '0020,0050' => { VR => 'RET',Name => 'Location' },
+    '0020,0052' => { VR => 'UI', Name => 'FrameOfReferenceUID' },
+    '0020,0060' => { VR => 'CS', Name => 'Laterality' },
+    '0020,0062' => { VR => 'CS', Name => 'ImageLaterality' },
+    '0020,0070' => { VR => 'RET',Name => 'ImageGeometryType' },
+    '0020,0080' => { VR => 'RET',Name => 'MaskingImage' },
+    '0020,0100' => { VR => 'IS', Name => 'TemporalPositionIdentifier' },
+    '0020,0105' => { VR => 'IS', Name => 'NumberOfTemporalPositions' },
+    '0020,0110' => { VR => 'DS', Name => 'TemporalResolution' },
+    '0020,0200' => { VR => 'UI', Name => 'SynchronizationFrameOfReferenceUID' },
+    '0020,1000' => { VR => 'IS', Name => 'SeriesInStudy' },
+    '0020,1001' => { VR => 'RET',Name => 'AcquisitionsInSeries' },
+    '0020,1002' => { VR => 'IS', Name => 'ImagesInAcquisition' },
+    '0020,1004' => { VR => 'IS', Name => 'AcquisitionsInStudy' },
+    '0020,1020' => { VR => 'RET',Name => 'Reference' },
+    '0020,1040' => { VR => 'LO', Name => 'PositionReferenceIndicator' },
+    '0020,1041' => { VR => 'DS', Name => 'SliceLocation' },
+    '0020,1070' => { VR => 'IS', Name => 'OtherStudyNumbers' },
+    '0020,1200' => { VR => 'IS', Name => 'NumberOfPatientRelatedStudies' },
+    '0020,1202' => { VR => 'IS', Name => 'NumberOfPatientRelatedSeries' },
+    '0020,1204' => { VR => 'IS', Name => 'NumberOfPatientRelatedInstances' },
+    '0020,1206' => { VR => 'IS', Name => 'NumberOfStudyRelatedSeries' },
+    '0020,1208' => { VR => 'IS', Name => 'NumberOfStudyRelatedInstances' },
+    '0020,1209' => { VR => 'RET',Name => 'NumberOfSeriesRelatedInstances' },
+    '0020,31xx' => { VR => 'RET',Name => 'SourceImageIDs' },
+    '0020,3401' => { VR => 'RET',Name => 'ModifyingDeviceID' },
+    '0020,3402' => { VR => 'RET',Name => 'ModifiedImageID' },
+    '0020,3403' => { VR => 'RET',Name => 'ModifiedImageDate' },
+    '0020,3404' => { VR => 'RET',Name => 'ModifyingDeviceManufacturer' },
+    '0020,3405' => { VR => 'RET',Name => 'ModifiedImageTime' },
+    '0020,3406' => { VR => 'RET',Name => 'ModifiedImageDescription' },
+    '0020,4000' => { VR => 'LT', Name => 'ImageComments' },
+    '0020,5000' => { VR => 'US', Name => 'OriginalImageIdentification' },
+    '0020,5002' => { VR => 'RET',Name => 'OriginalImageIdentNomenclature' },
+    '0020,9056' => { VR => 'SH', Name => 'StackID' },
+    '0020,9057' => { VR => 'UL', Name => 'InStackPositionNumber' },
+    '0020,9071' => { VR => 'SQ', Name => 'FrameAnatomySequence' },
+    '0020,9072' => { VR => 'CS', Name => 'FrameLaterality' },
+    '0020,9111' => { VR => 'SQ', Name => 'FrameContentSequence' },
+    '0020,9113' => { VR => 'SQ', Name => 'PlanePositionSequence' },
+    '0020,9116' => { VR => 'SQ', Name => 'PlaneOrientationSequence' },
+    '0020,9128' => { VR => 'UL', Name => 'TemporalPositionIndex' },
+    '0020,9153' => { VR => 'FD', Name => 'TriggerDelayTime' },
+    '0020,9156' => { VR => 'US', Name => 'FrameAcquisitionNumber' },
+    '0020,9157' => { VR => 'UL', Name => 'DimensionIndexValues' },
+    '0020,9158' => { VR => 'LT', Name => 'FrameComments' },
+    '0020,9161' => { VR => 'UI', Name => 'ConcatenationUID' },
+    '0020,9162' => { VR => 'US', Name => 'InconcatenationNumber' },
+    '0020,9163' => { VR => 'US', Name => 'InconcatenationTotalNumber' },
+    '0020,9164' => { VR => 'UI', Name => 'DimensionOrganizationUID' },
+    '0020,9165' => { VR => 'AT', Name => 'DimensionIndexPointer' },
+    '0020,9167' => { VR => 'AT', Name => 'FunctionalGroupPointer' },
+    '0020,9213' => { VR => 'LO', Name => 'DimensionIndexPrivateCreator' },
+    '0020,9221' => { VR => 'SQ', Name => 'DimensionOrganizationSequence' },
+    '0020,9222' => { VR => 'SQ', Name => 'DimensionIndexSequence' },
+    '0020,9228' => { VR => 'UL', Name => 'ConcatenationFrameOffsetNumber' },
+    '0020,9238' => { VR => 'LO', Name => 'FunctionalGroupPrivateCreator' },
+    '0022,0001' => { VR => 'US', Name => 'LightPathFilterPassThroughWavelen' },
+    '0022,0002' => { VR => 'US', Name => 'LightPathFilterPassBand' },
+    '0022,0003' => { VR => 'US', Name => 'ImagePathFilterPassThroughWavelen' },
+    '0022,0004' => { VR => 'US', Name => 'ImagePathFilterPassBand' },
+    '0022,0005' => { VR => 'CS', Name => 'PatientEyeMovementCommanded' },
+    '0022,0006' => { VR => 'SQ', Name => 'PatientEyeMovementCommandCodeSeq' },
+    '0022,0007' => { VR => 'FL', Name => 'SphericalLensPower' },
+    '0022,0008' => { VR => 'FL', Name => 'CylinderLensPower' },
+    '0022,0009' => { VR => 'FL', Name => 'CylinderAxis' },
+    '0022,000A' => { VR => 'FL', Name => 'EmmetropicMagnification' },
+    '0022,000B' => { VR => 'FL', Name => 'IntraOcularPressure' },
+    '0022,000C' => { VR => 'FL', Name => 'HorizontalFieldOfView' },
+    '0022,000D' => { VR => 'CS', Name => 'PupilDilated' },
+    '0022,000E' => { VR => 'FL', Name => 'DegreeOfDilation' },
+    '0022,0010' => { VR => 'FL', Name => 'StereoBaselineAngle' },
+    '0022,0011' => { VR => 'FL', Name => 'StereoBaselineDisplacement' },
+    '0022,0012' => { VR => 'FL', Name => 'StereoHorizontalPixelOffset' },
+    '0022,0013' => { VR => 'FL', Name => 'StereoVerticalPixelOffset' },
+    '0022,0014' => { VR => 'FL', Name => 'StereoRotation' },
+    '0022,0015' => { VR => 'SQ', Name => 'AcquisitionDeviceTypeCodeSequence' },
+    '0022,0016' => { VR => 'SQ', Name => 'IlluminationTypeCodeSequence' },
+    '0022,0017' => { VR => 'SQ', Name => 'LightPathFilterTypeStackCodeSeq' },
+    '0022,0018' => { VR => 'SQ', Name => 'ImagePathFilterTypeStackCodeSeq' },
+    '0022,0019' => { VR => 'SQ', Name => 'LensesCodeSequence' },
+    '0022,001A' => { VR => 'SQ', Name => 'ChannelDescriptionCodeSequence' },
+    '0022,001B' => { VR => 'SQ', Name => 'RefractiveStateSequence' },
+    '0022,001C' => { VR => 'SQ', Name => 'MydriaticAgentCodeSequence' },
+    '0022,001D' => { VR => 'SQ', Name => 'RelativeImagePositionCodeSequence' },
+    '0022,0020' => { VR => 'SQ', Name => 'StereoPairsSequence' },
+    '0022,0021' => { VR => 'SQ', Name => 'LeftImageSequence' },
+    '0022,0022' => { VR => 'SQ', Name => 'RightImageSequence' },
+    # image presentation group
+    '0028,0000' => { VR => 'UL', Name => 'ImagePresentationGroupLength' },
+    '0028,0002' => { VR => 'US', Name => 'SamplesPerPixel' },
+    '0028,0003' => { VR => 'US', Name => 'SamplesPerPixelUsed' },
+    '0028,0004' => { VR => 'CS', Name => 'PhotometricInterpretation' },
+    '0028,0005' => { VR => 'US', Name => 'ImageDimensions' },
+    '0028,0006' => { VR => 'US', Name => 'PlanarConfiguration' },
+    '0028,0008' => { VR => 'IS', Name => 'NumberOfFrames' },
+    '0028,0009' => { VR => 'AT', Name => 'FrameIncrementPointer' },
+    '0028,000A' => { VR => 'AT', Name => 'FrameDimensionPointer' },
+    '0028,0010' => { VR => 'US', Name => 'Rows' },
+    '0028,0011' => { VR => 'US', Name => 'Columns' },
+    '0028,0012' => { VR => 'US', Name => 'Planes' },
+    '0028,0014' => { VR => 'US', Name => 'UltrasoundColorDataPresent' },
+    '0028,0030' => { VR => 'DS', Name => 'PixelSpacing' },
+    '0028,0031' => { VR => 'DS', Name => 'ZoomFactor' },
+    '0028,0032' => { VR => 'DS', Name => 'ZoomCenter' },
+    '0028,0034' => { VR => 'IS', Name => 'PixelAspectRatio' },
+    '0028,0040' => { VR => 'RET',Name => 'ImageFormat' },
+    '0028,0050' => { VR => 'RET',Name => 'ManipulatedImage' },
+    '0028,0051' => { VR => 'CS', Name => 'CorrectedImage' },
+    '0028,0060' => { VR => 'RET',Name => 'CompressionCode' },
+    '0028,0100' => { VR => 'US', Name => 'BitsAllocated' },
+    '0028,0101' => { VR => 'US', Name => 'BitsStored' },
+    '0028,0102' => { VR => 'US', Name => 'HighBit' },
+    '0028,0103' => { VR => 'US', Name => 'PixelRepresentation' },
+    '0028,0104' => { VR => 'RET',Name => 'SmallestValidPixelValue' },
+    '0028,0105' => { VR => 'RET',Name => 'LargestValidPixelValue' },
+    '0028,0106' => { VR => 'SS', Name => 'SmallestImagePixelValue' },
+    '0028,0107' => { VR => 'SS', Name => 'LargestImagePixelValue' },
+    '0028,0108' => { VR => 'SS', Name => 'SmallestPixelValueInSeries' },
+    '0028,0109' => { VR => 'SS', Name => 'LargestPixelValueInSeries' },
+    '0028,0110' => { VR => 'SS', Name => 'SmallestImagePixelValueInPlane' },
+    '0028,0111' => { VR => 'SS', Name => 'LargestImagePixelValueInPlane' },
+    '0028,0120' => { VR => 'SS', Name => 'PixelPaddingValue' },
+    '0028,0200' => { VR => 'SS', Name => 'ImageLocation' },
+    '0028,0300' => { VR => 'CS', Name => 'QualityControlImage' },
+    '0028,0301' => { VR => 'CS', Name => 'BurnedInAnnotation' },
+    '0028,1040' => { VR => 'CS', Name => 'PixelIntensityRelationship' },
+    '0028,1041' => { VR => 'SS', Name => 'PixelIntensityRelationshipSign' },
+    '0028,1050' => { VR => 'DS', Name => 'WindowCenter' },
+    '0028,1051' => { VR => 'DS', Name => 'WindowWidth' },
+    '0028,1052' => { VR => 'DS', Name => 'RescaleIntercept' },
+    '0028,1053' => { VR => 'DS', Name => 'RescaleSlope' },
+    '0028,1054' => { VR => 'LO', Name => 'RescaleType' },
+    '0028,1055' => { VR => 'LO', Name => 'WindowCenterAndWidthExplanation' },
+    '0028,1080' => { VR => 'RET',Name => 'GrayScale' },
+    '0028,1090' => { VR => 'CS', Name => 'RecommendedViewingMode' },
+    '0028,1100' => { VR => 'RET',Name => 'GrayLookupTableDescriptor' },
+    '0028,1101' => { VR => 'SS', Name => 'RedPaletteColorTableDescriptor' },
+    '0028,1102' => { VR => 'SS', Name => 'GreenPaletteColorTableDescriptor' },
+    '0028,1103' => { VR => 'SS', Name => 'BluePaletteColorTableDescriptor' },
+    '0028,1199' => { VR => 'UI', Name => 'PaletteColorTableUID' },
+    '0028,1200' => { VR => 'RET',Name => 'GrayLookupTableData' },
+    '0028,1201' => { VR => 'OW', Name => 'RedPaletteColorTableData' },
+    '0028,1202' => { VR => 'OW', Name => 'GreenPaletteColorTableData' },
+    '0028,1203' => { VR => 'OW', Name => 'BluePaletteColorTableData' },
+    '0028,1221' => { VR => 'OW', Name => 'SegmentedRedColorTableData' },
+    '0028,1222' => { VR => 'OW', Name => 'SegmentedGreenColorTableData' },
+    '0028,1223' => { VR => 'OW', Name => 'SegmentedBlueColorTableData' },
+    '0028,1300' => { VR => 'CS', Name => 'ImplantPresent' },
+    '0028,1350' => { VR => 'CS', Name => 'PartialView' },
+    '0028,1351' => { VR => 'ST', Name => 'PartialViewDescription' },
+    '0028,2110' => { VR => 'CS', Name => 'LossyImageCompression' },
+    '0028,2112' => { VR => 'DS', Name => 'LossyImageCompressionRatio' },
+    '0028,2114' => { VR => 'CS', Name => 'LossyImageCompressionMethod' },
+    '0028,3000' => { VR => 'SQ', Name => 'ModalityLUTSequence' },
+    '0028,3002' => { VR => 'SS', Name => 'LUTDescriptor' },
+    '0028,3003' => { VR => 'LO', Name => 'LUTExplanation' },
+    '0028,3004' => { VR => 'LO', Name => 'ModalityLUTType' },
+    '0028,3006' => { VR => 'SS', Name => 'LUTData' },
+    '0028,3010' => { VR => 'SQ', Name => 'VOILUTSequence' },
+    '0028,3110' => { VR => 'SQ', Name => 'SoftcopyVOILUTSequence' },
+    '0028,4000' => { VR => 'RET',Name => 'ImagePresentationComments' },
+    '0028,5000' => { VR => 'SQ', Name => 'BiPlaneAcquisitionSequence' },
+    '0028,6010' => { VR => 'US', Name => 'RepresentativeFrameNumber' },
+    '0028,6020' => { VR => 'US', Name => 'FrameNumbersOfInterestFOI' },
+    '0028,6022' => { VR => 'LO', Name => 'FrameOfInterestDescription' },
+    '0028,6023' => { VR => 'CS', Name => 'FrameOfInterestType' },
+    '0028,6030' => { VR => 'RET',Name => 'MaskPointers' },
+    '0028,6040' => { VR => 'US', Name => 'RWavePointer' },
+    '0028,6100' => { VR => 'SQ', Name => 'MaskSubtractionSequence' },
+    '0028,6101' => { VR => 'CS', Name => 'MaskOperation' },
+    '0028,6102' => { VR => 'US', Name => 'ApplicableFrameRange' },
+    '0028,6110' => { VR => 'US', Name => 'MaskFrameNumbers' },
+    '0028,6112' => { VR => 'US', Name => 'ContrastFrameAveraging' },
+    '0028,6114' => { VR => 'FL', Name => 'MaskSubPixelShift' },
+    '0028,6120' => { VR => 'SS', Name => 'TIDOffset' },
+    '0028,6190' => { VR => 'ST', Name => 'MaskOperationExplanation' },
+    '0028,9001' => { VR => 'UL', Name => 'DataPointRows' },
+    '0028,9002' => { VR => 'UL', Name => 'DataPointColumns' },
+    '0028,9003' => { VR => 'CS', Name => 'SignalDomainColumns' },
+    '0028,9099' => { VR => 'US', Name => 'LargestMonochromePixelValue' },
+    '0028,9108' => { VR => 'CS', Name => 'DataRepresentation' },
+    '0028,9110' => { VR => 'SQ', Name => 'PixelMeasuresSequence' },
+    '0028,9132' => { VR => 'SQ', Name => 'FrameVOILUTSequence' },
+    '0028,9145' => { VR => 'SQ', Name => 'PixelValueTransformationSequence' },
+    '0028,9235' => { VR => 'CS', Name => 'SignalDomainRows' },
+    # study group
+    '0032,0000' => { VR => 'UL', Name => 'StudyGroupLength' },
+    '0032,000A' => { VR => 'CS', Name => 'StudyStatusID' },
+    '0032,000C' => { VR => 'CS', Name => 'StudyPriorityID' },
+    '0032,0012' => { VR => 'LO', Name => 'StudyIDIssuer' },
+    '0032,0032' => { VR => 'DA', Name => 'StudyVerifiedDate' },
+    '0032,0033' => { VR => 'TM', Name => 'StudyVerifiedTime' },
+    '0032,0034' => { VR => 'DA', Name => 'StudyReadDate' },
+    '0032,0035' => { VR => 'TM', Name => 'StudyReadTime' },
+    '0032,1000' => { VR => 'DA', Name => 'ScheduledStudyStartDate' },
+    '0032,1001' => { VR => 'TM', Name => 'ScheduledStudyStartTime' },
+    '0032,1010' => { VR => 'DA', Name => 'ScheduledStudyStopDate' },
+    '0032,1011' => { VR => 'TM', Name => 'ScheduledStudyStopTime' },
+    '0032,1020' => { VR => 'LO', Name => 'ScheduledStudyLocation' },
+    '0032,1021' => { VR => 'AE', Name => 'ScheduledStudyLocationAETitle' },
+    '0032,1030' => { VR => 'LO', Name => 'ReasonForStudy' },
+    '0032,1031' => { VR => 'SQ', Name => 'RequestingPhysicianIDSequence' },
+    '0032,1032' => { VR => 'PN', Name => 'RequestingPhysician' },
+    '0032,1033' => { VR => 'LO', Name => 'RequestingService' },
+    '0032,1040' => { VR => 'DA', Name => 'StudyArrivalDate' },
+    '0032,1041' => { VR => 'TM', Name => 'StudyArrivalTime' },
+    '0032,1050' => { VR => 'DA', Name => 'StudyCompletionDate' },
+    '0032,1051' => { VR => 'TM', Name => 'StudyCompletionTime' },
+    '0032,1055' => { VR => 'CS', Name => 'StudyComponentStatusID' },
+    '0032,1060' => { VR => 'LO', Name => 'RequestedProcedureDescription' },
+    '0032,1064' => { VR => 'SQ', Name => 'RequestedProcedureCodeSequence' },
+    '0032,1070' => { VR => 'LO', Name => 'RequestedContrastAgent' },
+    '0032,4000' => { VR => 'LT', Name => 'StudyComments' },
+    # visit group
+    '0038,0004' => { VR => 'SQ', Name => 'ReferencedPatientAliasSequence' },
+    '0038,0008' => { VR => 'CS', Name => 'VisitStatusID' },
+    '0038,0010' => { VR => 'LO', Name => 'AdmissionID' },
+    '0038,0011' => { VR => 'LO', Name => 'IssuerOfAdmissionID' },
+    '0038,0016' => { VR => 'LO', Name => 'RouteOfAdmissions' },
+    '0038,001A' => { VR => 'DA', Name => 'ScheduledAdmissionDate' },
+    '0038,001B' => { VR => 'TM', Name => 'ScheduledAdmissionTime' },
+    '0038,001C' => { VR => 'DA', Name => 'ScheduledDischargeDate' },
+    '0038,001D' => { VR => 'TM', Name => 'ScheduledDischargeTime' },
+    '0038,001E' => { VR => 'LO', Name => 'ScheduledPatientInstitResidence' },
+    '0038,0020' => { VR => 'DA', Name => 'AdmittingDate' },
+    '0038,0021' => { VR => 'TM', Name => 'AdmittingTime' },
+    '0038,0030' => { VR => 'DA', Name => 'DischargeDate' },
+    '0038,0032' => { VR => 'TM', Name => 'DischargeTime' },
+    '0038,0040' => { VR => 'LO', Name => 'DischargeDiagnosisDescription' },
+    '0038,0044' => { VR => 'SQ', Name => 'DischargeDiagnosisCodeSequence' },
+    '0038,0050' => { VR => 'LO', Name => 'SpecialNeeds' },
+    '0038,0300' => { VR => 'LO', Name => 'CurrentPatientLocation' },
+    '0038,0400' => { VR => 'LO', Name => 'PatientsInstitutionResidence' },
+    '0038,0500' => { VR => 'LO', Name => 'PatientState' },
+    '0038,4000' => { VR => 'LT', Name => 'VisitComments' },
+    '003A,0004' => { VR => 'CS', Name => 'WaveformOriginality' },
+    '003A,0005' => { VR => 'US', Name => 'NumberOfWaveformChannels' },
+    '003A,0010' => { VR => 'UL', Name => 'NumberOfWaveformSamples' },
+    '003A,001A' => { VR => 'DS', Name => 'SamplingFrequency' },
+    '003A,0020' => { VR => 'SH', Name => 'MultiplexGroupLabel' },
+    '003A,0200' => { VR => 'SQ', Name => 'ChannelDefinitionSequence' },
+    '003A,0202' => { VR => 'IS', Name => 'WaveformChannelNumber' },
+    '003A,0203' => { VR => 'SH', Name => 'ChannelLabel' },
+    '003A,0205' => { VR => 'CS', Name => 'ChannelStatus' },
+    '003A,0208' => { VR => 'SQ', Name => 'ChannelSourceSequence' },
+    '003A,0209' => { VR => 'SQ', Name => 'ChannelSourceModifiersSequence' },
+    '003A,020A' => { VR => 'SQ', Name => 'SourceWaveformSequence' },
+    '003A,020C' => { VR => 'LO', Name => 'ChannelDerivationDescription' },
+    '003A,0210' => { VR => 'DS', Name => 'ChannelSensitivity' },
+    '003A,0211' => { VR => 'SQ', Name => 'ChannelSensitivityUnitsSequence' },
+    '003A,0212' => { VR => 'DS', Name => 'ChannelSensitivityCorrectionFactor' },
+    '003A,0213' => { VR => 'DS', Name => 'ChannelBaseline' },
+    '003A,0214' => { VR => 'DS', Name => 'ChannelTimeSkew' },
+    '003A,0215' => { VR => 'DS', Name => 'ChannelSampleSkew' },
+    '003A,0218' => { VR => 'DS', Name => 'ChannelOffset' },
+    '003A,021A' => { VR => 'US', Name => 'WaveformBitsStored' },
+    '003A,0220' => { VR => 'DS', Name => 'FilterLowFrequency' },
+    '003A,0221' => { VR => 'DS', Name => 'FilterHighFrequency' },
+    '003A,0222' => { VR => 'DS', Name => 'NotchFilterFrequency' },
+    '003A,0223' => { VR => 'DS', Name => 'NotchFilterBandwidth' },
+    '003A,0300' => { VR => 'SQ', Name => 'MultiplexAudioChannelsDescrCodeSeq' },
+    '003A,0301' => { VR => 'IS', Name => 'ChannelIdentificationCode' },
+    '003A,0302' => { VR => 'CS', Name => 'ChannelMode' },
+    '0040,0001' => { VR => 'AE', Name => 'ScheduledStationAETitle' },
+    '0040,0002' => { VR => 'DA', Name => 'ScheduledProcedureStepStartDate' },
+    '0040,0003' => { VR => 'TM', Name => 'ScheduledProcedureStepStartTime' },
+    '0040,0004' => { VR => 'DA', Name => 'ScheduledProcedureStepEndDate' },
+    '0040,0005' => { VR => 'TM', Name => 'ScheduledProcedureStepEndTime' },
+    '0040,0006' => { VR => 'PN', Name => 'ScheduledPerformingPhysiciansName' },
+    '0040,0007' => { VR => 'LO', Name => 'ScheduledProcedureStepDescription' },
+    '0040,0008' => { VR => 'SQ', Name => 'ScheduledProtocolCodeSequence' },
+    '0040,0009' => { VR => 'SH', Name => 'ScheduledProcedureStepID' },
+    '0040,000A' => { VR => 'SQ', Name => 'StageCodeSequence' },
+    '0040,000B' => { VR => 'SQ', Name => 'ScheduledPerformingPhysicianIDSeq' },
+    '0040,0010' => { VR => 'SH', Name => 'ScheduledStationName' },
+    '0040,0011' => { VR => 'SH', Name => 'ScheduledProcedureStepLocation' },
+    '0040,0012' => { VR => 'LO', Name => 'PreMedication' },
+    '0040,0020' => { VR => 'CS', Name => 'ScheduledProcedureStepStatus' },
+    '0040,0100' => { VR => 'SQ', Name => 'ScheduledProcedureStepSequence' },
+    '0040,0220' => { VR => 'SQ', Name => 'ReferencedNonImageCompositeSOPSeq' },
+    '0040,0241' => { VR => 'AE', Name => 'PerformedStationAETitle' },
+    '0040,0242' => { VR => 'SH', Name => 'PerformedStationName' },
+    '0040,0243' => { VR => 'SH', Name => 'PerformedLocation' },
+    '0040,0244' => { VR => 'DA', Name => 'PerformedProcedureStepStartDate' },
+    '0040,0245' => { VR => 'TM', Name => 'PerformedProcedureStepStartTime' },
+    '0040,0250' => { VR => 'DA', Name => 'PerformedProcedureStepEndDate' },
+    '0040,0251' => { VR => 'TM', Name => 'PerformedProcedureStepEndTime' },
+    '0040,0252' => { VR => 'CS', Name => 'PerformedProcedureStepStatus' },
+    '0040,0253' => { VR => 'SH', Name => 'PerformedProcedureStepID' },
+    '0040,0254' => { VR => 'LO', Name => 'PerformedProcedureStepDescription' },
+    '0040,0255' => { VR => 'LO', Name => 'PerformedProcedureTypeDescription' },
+    '0040,0260' => { VR => 'SQ', Name => 'PerformedProtocolCodeSequence' },
+    '0040,0270' => { VR => 'SQ', Name => 'ScheduledStepAttributesSequence' },
+    '0040,0275' => { VR => 'SQ', Name => 'RequestAttributesSequence' },
+    '0040,0280' => { VR => 'ST', Name => 'CommentsOnPerformedProcedureStep' },
+    '0040,0281' => { VR => 'SQ', Name => 'ProcStepDiscontinueReasonCodeSeq' },
+    '0040,0293' => { VR => 'SQ', Name => 'QuantitySequence' },
+    '0040,0294' => { VR => 'DS', Name => 'Quantity' },
+    '0040,0295' => { VR => 'SQ', Name => 'MeasuringUnitsSequence' },
+    '0040,0296' => { VR => 'SQ', Name => 'BillingItemSequence' },
+    '0040,0300' => { VR => 'US', Name => 'TotalTimeOfFluoroscopy' },
+    '0040,0301' => { VR => 'US', Name => 'TotalNumberOfExposures' },
+    '0040,0302' => { VR => 'US', Name => 'EntranceDose' },
+    '0040,0303' => { VR => 'US', Name => 'ExposedArea' },
+    '0040,0306' => { VR => 'DS', Name => 'DistanceSourceToEntrance' },
+    '0040,0307' => { VR => 'RET',Name => 'DistanceSourceToSupport' },
+    '0040,030E' => { VR => 'SQ', Name => 'ExposureDoseSequence' },
+    '0040,0310' => { VR => 'ST', Name => 'CommentsOnRadiationDose' },
+    '0040,0312' => { VR => 'DS', Name => 'XRayOutput' },
+    '0040,0314' => { VR => 'DS', Name => 'HalfValueLayer' },
+    '0040,0316' => { VR => 'DS', Name => 'OrganDose' },
+    '0040,0318' => { VR => 'CS', Name => 'OrganExposed' },
+    '0040,0320' => { VR => 'SQ', Name => 'BillingProcedureStepSequence' },
+    '0040,0321' => { VR => 'SQ', Name => 'FilmConsumptionSequence' },
+    '0040,0324' => { VR => 'SQ', Name => 'BillingSuppliesAndDevicesSequence' },
+    '0040,0330' => { VR => 'RET',Name => 'ReferencedProcedureStepSequence' },
+    '0040,0340' => { VR => 'SQ', Name => 'PerformedSeriesSequence' },
+    '0040,0400' => { VR => 'LT', Name => 'CommentsOnScheduledProcedureStep' },
+    '0040,0440' => { VR => 'SQ', Name => 'ProtocolContextSequence' },
+    '0040,0441' => { VR => 'SQ', Name => 'ContentItemModifierSequence' },
+    '0040,050A' => { VR => 'LO', Name => 'SpecimenAccessionNumber' },
+    '0040,0550' => { VR => 'SQ', Name => 'SpecimenSequence' },
+    '0040,0551' => { VR => 'LO', Name => 'SpecimenIdentifier' },
+    '0040,0555' => { VR => 'SQ', Name => 'AcquisitionContextSequence' },
+    '0040,0556' => { VR => 'ST', Name => 'AcquisitionContextDescription' },
+    '0040,059A' => { VR => 'SQ', Name => 'SpecimenTypeCodeSequence' },
+    '0040,06FA' => { VR => 'LO', Name => 'SlideIdentifier' },
+    '0040,071A' => { VR => 'SQ', Name => 'ImageCenterPointCoordinatesSeq' },
+    '0040,072A' => { VR => 'DS', Name => 'XOffsetInSlideCoordinateSystem' },
+    '0040,073A' => { VR => 'DS', Name => 'YOffsetInSlideCoordinateSystem' },
+    '0040,074A' => { VR => 'DS', Name => 'ZOffsetInSlideCoordinateSystem' },
+    '0040,08D8' => { VR => 'SQ', Name => 'PixelSpacingSequence' },
+    '0040,08DA' => { VR => 'SQ', Name => 'CoordinateSystemAxisCodeSequence' },
+    '0040,08EA' => { VR => 'SQ', Name => 'MeasurementUnitsCodeSequence' },
+    '0040,1001' => { VR => 'SH', Name => 'RequestedProcedureID' },
+    '0040,1002' => { VR => 'LO', Name => 'ReasonForRequestedProcedure' },
+    '0040,1003' => { VR => 'SH', Name => 'RequestedProcedurePriority' },
+    '0040,1004' => { VR => 'LO', Name => 'PatientTransportArrangements' },
+    '0040,1005' => { VR => 'LO', Name => 'RequestedProcedureLocation' },
+    '0040,1006' => { VR => 'RET',Name => 'PlacerOrderNumber-Procedure' },
+    '0040,1007' => { VR => 'RET',Name => 'FillerOrderNumber-Procedure' },
+    '0040,1008' => { VR => 'LO', Name => 'ConfidentialityCode' },
+    '0040,1009' => { VR => 'SH', Name => 'ReportingPriority' },
+    '0040,100A' => { VR => 'SQ', Name => 'ReasonForRequestedProcedureCodeSeq' },
+    '0040,1010' => { VR => 'PN', Name => 'NamesOfIntendedRecipientsOfResults' },
+    '0040,1011' => { VR => 'SQ', Name => 'IntendedRecipientsOfResultsIDSeq' },
+    '0040,1101' => { VR => 'SQ', Name => 'PersonIdentificationCodeSequence' },
+    '0040,1102' => { VR => 'ST', Name => 'PersonsAddress' },
+    '0040,1103' => { VR => 'LO', Name => 'PersonsTelephoneNumbers' },
+    '0040,1400' => { VR => 'LT', Name => 'RequestedProcedureComments' },
+    '0040,2001' => { VR => 'RET',Name => 'ReasonForImagingServiceRequest' },
+    '0040,2004' => { VR => 'DA', Name => 'IssueDateOfImagingServiceRequest' },
+    '0040,2005' => { VR => 'TM', Name => 'IssueTimeOfImagingServiceRequest' },
+    '0040,2006' => { VR => 'RET',Name => 'PlacerOrderNum-ImagingServiceReq' },
+    '0040,2007' => { VR => 'RET',Name => 'FillerOrderNum-ImagingServiceReq' },
+    '0040,2008' => { VR => 'PN', Name => 'OrderEnteredBy' },
+    '0040,2009' => { VR => 'SH', Name => 'OrderEnterersLocation' },
+    '0040,2010' => { VR => 'SH', Name => 'OrderCallbackPhoneNumber' },
+    '0040,2016' => { VR => 'LO', Name => 'PlacerOrderNum-ImagingServiceReq' },
+    '0040,2017' => { VR => 'LO', Name => 'FillerOrderNum-ImagingServiceReq' },
+    '0040,2400' => { VR => 'LT', Name => 'ImagingServiceRequestComments' },
+    '0040,3001' => { VR => 'LO', Name => 'ConfidentialityOnPatientDataDescr' },
+    '0040,4001' => { VR => 'CS', Name => 'GenPurposeScheduledProcStepStatus' },
+    '0040,4002' => { VR => 'CS', Name => 'GenPurposePerformedProcStepStatus' },
+    '0040,4003' => { VR => 'CS', Name => 'GenPurposeSchedProcStepPriority' },
+    '0040,4004' => { VR => 'SQ', Name => 'SchedProcessingApplicationsCodeSeq' },
+    '0040,4005' => { VR => 'DT', Name => 'SchedProcedureStepStartDateAndTime' },
+    '0040,4006' => { VR => 'CS', Name => 'MultipleCopiesFlag' },
+    '0040,4007' => { VR => 'SQ', Name => 'PerformedProcessingAppsCodeSeq' },
+    '0040,4009' => { VR => 'SQ', Name => 'HumanPerformerCodeSequence' },
+    '0040,4010' => { VR => 'DT', Name => 'SchedProcStepModificationDateTime' },
+    '0040,4011' => { VR => 'DT', Name => 'ExpectedCompletionDateAndTime' },
+    '0040,4015' => { VR => 'SQ', Name => 'ResultingGenPurposePerfProcStepSeq' },
+    '0040,4016' => { VR => 'SQ', Name => 'RefGenPurposeSchedProcStepSeq' },
+    '0040,4018' => { VR => 'SQ', Name => 'ScheduledWorkitemCodeSequence' },
+    '0040,4019' => { VR => 'SQ', Name => 'PerformedWorkitemCodeSequence' },
+    '0040,4020' => { VR => 'CS', Name => 'InputAvailabilityFlag' },
+    '0040,4021' => { VR => 'SQ', Name => 'InputInformationSequence' },
+    '0040,4022' => { VR => 'SQ', Name => 'RelevantInformationSequence' },
+    '0040,4023' => { VR => 'UI', Name => 'RefGenPurSchedProcStepTransUID' },
+    '0040,4025' => { VR => 'SQ', Name => 'ScheduledStationNameCodeSequence' },
+    '0040,4026' => { VR => 'SQ', Name => 'ScheduledStationClassCodeSequence' },
+    '0040,4027' => { VR => 'SQ', Name => 'SchedStationGeographicLocCodeSeq' },
+    '0040,4028' => { VR => 'SQ', Name => 'PerformedStationNameCodeSequence' },
+    '0040,4029' => { VR => 'SQ', Name => 'PerformedStationClassCodeSequence' },
+    '0040,4030' => { VR => 'SQ', Name => 'PerformedStationGeogLocCodeSeq' },
+    '0040,4031' => { VR => 'SQ', Name => 'RequestedSubsequentWorkItemCodeSeq' },
+    '0040,4032' => { VR => 'SQ', Name => 'NonDICOMOutputCodeSequence' },
+    '0040,4033' => { VR => 'SQ', Name => 'OutputInformationSequence' },
+    '0040,4034' => { VR => 'SQ', Name => 'ScheduledHumanPerformersSequence' },
+    '0040,4035' => { VR => 'SQ', Name => 'ActualHumanPerformersSequence' },
+    '0040,4036' => { VR => 'LO', Name => 'HumanPerformersOrganization' },
+    '0040,4037' => { VR => 'PN', Name => 'HumanPerformersName' },
+    '0040,8302' => { VR => 'DS', Name => 'EntranceDoseInMilliGy' },
+    '0040,9096' => { VR => 'SQ', Name => 'RealWorldValueMappingSequence' },
+    '0040,9210' => { VR => 'SH', Name => 'LUTLabel' },
+    '0040,9211' => { VR => 'SS', Name => 'RealWorldValueLastValueMapped' },
+    '0040,9212' => { VR => 'FD', Name => 'RealWorldValueLUTData' },
+    '0040,9216' => { VR => 'SS', Name => 'RealWorldValueFirstValueMapped' },
+    '0040,9224' => { VR => 'FD', Name => 'RealWorldValueIntercept' },
+    '0040,9225' => { VR => 'FD', Name => 'RealWorldValueSlope' },
+    '0040,A010' => { VR => 'CS', Name => 'RelationshipType' },
+    '0040,A027' => { VR => 'LO', Name => 'VerifyingOrganization' },
+    '0040,A030' => { VR => 'DT', Name => 'VerificationDateTime' },
+    '0040,A032' => { VR => 'DT', Name => 'ObservationDateTime' },
+    '0040,A040' => { VR => 'CS', Name => 'ValueType' },
+    '0040,A043' => { VR => 'SQ', Name => 'ConceptNameCodeSequence' },
+    '0040,A050' => { VR => 'CS', Name => 'ContinuityOfContent' },
+    '0040,A073' => { VR => 'SQ', Name => 'VerifyingObserverSequence' },
+    '0040,A075' => { VR => 'PN', Name => 'VerifyingObserverName' },
+    '0040,A088' => { VR => 'SQ', Name => 'VerifyingObserverIdentCodeSequence' },
+    '0040,A0B0' => { VR => 'US', Name => 'ReferencedWaveformChannels' },
+    '0040,A120' => { VR => 'DT', Name => 'DateTime' },
+    '0040,A121' => { VR => 'DA', Name => 'Date' },
+    '0040,A122' => { VR => 'TM', Name => 'Time' },
+    '0040,A123' => { VR => 'PN', Name => 'PersonName' },
+    '0040,A124' => { VR => 'UI', Name => 'UID' },
+    '0040,A130' => { VR => 'CS', Name => 'TemporalRangeType' },
+    '0040,A132' => { VR => 'UL', Name => 'ReferencedSamplePositions' },
+    '0040,A136' => { VR => 'US', Name => 'ReferencedFrameNumbers' },
+    '0040,A138' => { VR => 'DS', Name => 'ReferencedTimeOffsets' },
+    '0040,A13A' => { VR => 'DT', Name => 'ReferencedDatetime' },
+    '0040,A160' => { VR => 'UT', Name => 'TextValue' },
+    '0040,A168' => { VR => 'SQ', Name => 'ConceptCodeSequence' },
+    '0040,A170' => { VR => 'SQ', Name => 'PurposeOfReferenceCodeSequence' },
+    '0040,A180' => { VR => 'US', Name => 'AnnotationGroupNumber' },
+    '0040,A195' => { VR => 'SQ', Name => 'ModifierCodeSequence' },
+    '0040,A300' => { VR => 'SQ', Name => 'MeasuredValueSequence' },
+    '0040,A301' => { VR => 'SQ', Name => 'NumericValueQualifierCodeSequence' },
+    '0040,A30A' => { VR => 'DS', Name => 'NumericValue' },
+    '0040,A360' => { VR => 'SQ', Name => 'PredecessorDocumentsSequence' },
+    '0040,A370' => { VR => 'SQ', Name => 'ReferencedRequestSequence' },
+    '0040,A372' => { VR => 'SQ', Name => 'PerformedProcedureCodeSequence' },
+    '0040,A375' => { VR => 'SQ', Name => 'CurrentRequestedProcEvidenceSeq' },
+    '0040,A385' => { VR => 'SQ', Name => 'PertinentOtherEvidenceSequence' },
+    '0040,A491' => { VR => 'CS', Name => 'CompletionFlag' },
+    '0040,A492' => { VR => 'LO', Name => 'CompletionFlagDescription' },
+    '0040,A493' => { VR => 'CS', Name => 'VerificationFlag' },
+    '0040,A504' => { VR => 'SQ', Name => 'ContentTemplateSequence' },
+    '0040,A525' => { VR => 'SQ', Name => 'IdenticalDocumentsSequence' },
+    '0040,A730' => { VR => 'SQ', Name => 'ContentSequence' },
+    '0040,B020' => { VR => 'SQ', Name => 'AnnotationSequence' },
+    '0040,DB00' => { VR => 'CS', Name => 'TemplateIdentifier' },
+    '0040,DB06' => { VR => 'RET',Name => 'TemplateVersion' },
+    '0040,DB07' => { VR => 'RET',Name => 'TemplateLocalVersion' },
+    '0040,DB0B' => { VR => 'RET',Name => 'TemplateExtensionFlag' },
+    '0040,DB0C' => { VR => 'RET',Name => 'TemplateExtensionOrganizationUID' },
+    '0040,DB0D' => { VR => 'RET',Name => 'TemplateExtensionCreatorUID' },
+    '0040,DB73' => { VR => 'UL', Name => 'ReferencedContentItemIdentifier' },
+    # calibration group
+    '0050,0004' => { VR => 'CS', Name => 'CalibrationImage' },
+    '0050,0010' => { VR => 'SQ', Name => 'DeviceSequence' },
+    '0050,0014' => { VR => 'DS', Name => 'DeviceLength' },
+    '0050,0016' => { VR => 'DS', Name => 'DeviceDiameter' },
+    '0050,0017' => { VR => 'CS', Name => 'DeviceDiameterUnits' },
+    '0050,0018' => { VR => 'DS', Name => 'DeviceVolume' },
+    '0050,0019' => { VR => 'DS', Name => 'InterMarkerDistance' },
+    '0050,0020' => { VR => 'LO', Name => 'DeviceDescription' },
+    # nuclear acquisition group
+    '0054,0010' => { VR => 'US', Name => 'EnergyWindowVector' },
+    '0054,0011' => { VR => 'US', Name => 'NumberOfEnergyWindows' },
+    '0054,0012' => { VR => 'SQ', Name => 'EnergyWindowInformationSequence' },
+    '0054,0013' => { VR => 'SQ', Name => 'EnergyWindowRangeSequence' },
+    '0054,0014' => { VR => 'DS', Name => 'EnergyWindowLowerLimit' },
+    '0054,0015' => { VR => 'DS', Name => 'EnergyWindowUpperLimit' },
+    '0054,0016' => { VR => 'SQ', Name => 'RadiopharmaceuticalInformationSeq' },
+    '0054,0017' => { VR => 'IS', Name => 'ResidualSyringeCounts' },
+    '0054,0018' => { VR => 'SH', Name => 'EnergyWindowName' },
+    '0054,0020' => { VR => 'US', Name => 'DetectorVector' },
+    '0054,0021' => { VR => 'US', Name => 'NumberOfDetectors' },
+    '0054,0022' => { VR => 'SQ', Name => 'DetectorInformationSequence' },
+    '0054,0030' => { VR => 'US', Name => 'PhaseVector' },
+    '0054,0031' => { VR => 'US', Name => 'NumberOfPhases' },
+    '0054,0032' => { VR => 'SQ', Name => 'PhaseInformationSequence' },
+    '0054,0033' => { VR => 'US', Name => 'NumberOfFramesInPhase' },
+    '0054,0036' => { VR => 'IS', Name => 'PhaseDelay' },
+    '0054,0038' => { VR => 'IS', Name => 'PauseBetweenFrames' },
+    '0054,0039' => { VR => 'CS', Name => 'PhaseDescription' },
+    '0054,0050' => { VR => 'US', Name => 'RotationVector' },
+    '0054,0051' => { VR => 'US', Name => 'NumberOfRotations' },
+    '0054,0052' => { VR => 'SQ', Name => 'RotationInformationSequence' },
+    '0054,0053' => { VR => 'US', Name => 'NumberOfFramesInRotation' },
+    '0054,0060' => { VR => 'US', Name => 'RRIntervalVector' },
+    '0054,0061' => { VR => 'US', Name => 'NumberOfRRIntervals' },
+    '0054,0062' => { VR => 'SQ', Name => 'GatedInformationSequence' },
+    '0054,0063' => { VR => 'SQ', Name => 'DataInformationSequence' },
+    '0054,0070' => { VR => 'US', Name => 'TimeSlotVector' },
+    '0054,0071' => { VR => 'US', Name => 'NumberOfTimeSlots' },
+    '0054,0072' => { VR => 'SQ', Name => 'TimeSlotInformationSequence' },
+    '0054,0073' => { VR => 'DS', Name => 'TimeSlotTime' },
+    '0054,0080' => { VR => 'US', Name => 'SliceVector' },
+    '0054,0081' => { VR => 'US', Name => 'NumberOfSlices' },
+    '0054,0090' => { VR => 'US', Name => 'AngularViewVector' },
+    '0054,0100' => { VR => 'US', Name => 'TimeSliceVector' },
+    '0054,0101' => { VR => 'US', Name => 'NumberOfTimeSlices' },
+    '0054,0200' => { VR => 'DS', Name => 'StartAngle' },
+    '0054,0202' => { VR => 'CS', Name => 'TypeOfDetectorMotion' },
+    '0054,0210' => { VR => 'IS', Name => 'TriggerVector' },
+    '0054,0211' => { VR => 'US', Name => 'NumberOfTriggersInPhase' },
+    '0054,0220' => { VR => 'SQ', Name => 'ViewCodeSequence' },
+    '0054,0222' => { VR => 'SQ', Name => 'ViewModifierCodeSequence' },
+    '0054,0300' => { VR => 'SQ', Name => 'RadionuclideCodeSequence' },
+    '0054,0302' => { VR => 'SQ', Name => 'AdministrationRouteCodeSequence' },
+    '0054,0304' => { VR => 'SQ', Name => 'RadiopharmaceuticalCodeSequence' },
+    '0054,0306' => { VR => 'SQ', Name => 'CalibrationDataSequence' },
+    '0054,0308' => { VR => 'US', Name => 'EnergyWindowNumber' },
+    '0054,0400' => { VR => 'SH', Name => 'ImageID' },
+    '0054,0410' => { VR => 'SQ', Name => 'PatientOrientationCodeSequence' },
+    '0054,0412' => { VR => 'SQ', Name => 'PatientOrientationModifierCodeSeq' },
+    '0054,0414' => { VR => 'SQ', Name => 'PatientGantryRelationshipCodeSeq' },
+    '0054,0500' => { VR => 'CS', Name => 'SliceProgressionDirection' },
+    '0054,1000' => { VR => 'CS', Name => 'SeriesType' },
+    '0054,1001' => { VR => 'CS', Name => 'Units' },
+    '0054,1002' => { VR => 'CS', Name => 'CountsSource' },
+    '0054,1004' => { VR => 'CS', Name => 'ReprojectionMethod' },
+    '0054,1100' => { VR => 'CS', Name => 'RandomsCorrectionMethod' },
+    '0054,1101' => { VR => 'LO', Name => 'AttenuationCorrectionMethod' },
+    '0054,1102' => { VR => 'CS', Name => 'DecayCorrection' },
+    '0054,1103' => { VR => 'LO', Name => 'ReconstructionMethod' },
+    '0054,1104' => { VR => 'LO', Name => 'DetectorLinesOfResponseUsed' },
+    '0054,1105' => { VR => 'LO', Name => 'ScatterCorrectionMethod' },
+    '0054,1200' => { VR => 'DS', Name => 'AxialAcceptance' },
+    '0054,1201' => { VR => 'IS', Name => 'AxialMash' },
+    '0054,1202' => { VR => 'IS', Name => 'TransverseMash' },
+    '0054,1203' => { VR => 'DS', Name => 'DetectorElementSize' },
+    '0054,1210' => { VR => 'DS', Name => 'CoincidenceWindowWidth' },
+    '0054,1220' => { VR => 'CS', Name => 'SecondaryCountsType' },
+    '0054,1300' => { VR => 'DS', Name => 'FrameReferenceTime' },
+    '0054,1310' => { VR => 'IS', Name => 'PrimaryCountsAccumulated' },
+    '0054,1311' => { VR => 'IS', Name => 'SecondaryCountsAccumulated' },
+    '0054,1320' => { VR => 'DS', Name => 'SliceSensitivityFactor' },
+    '0054,1321' => { VR => 'DS', Name => 'DecayFactor' },
+    '0054,1322' => { VR => 'DS', Name => 'DoseCalibrationFactor' },
+    '0054,1323' => { VR => 'DS', Name => 'ScatterFractionFactor' },
+    '0054,1324' => { VR => 'DS', Name => 'DeadTimeFactor' },
+    '0054,1330' => { VR => 'US', Name => 'ImageIndex' },
+    '0054,1400' => { VR => 'CS', Name => 'CountsIncluded' },
+    '0054,1401' => { VR => 'CS', Name => 'DeadTimeCorrectionFlag' },
+    '0060,3000' => { VR => 'SQ', Name => 'HistogramSequence' },
+    '0060,3002' => { VR => 'US', Name => 'HistogramNumberOfBins' },
+    '0060,3004' => { VR => 'SS', Name => 'HistogramFirstBinValue' },
+    '0060,3006' => { VR => 'SS', Name => 'HistogramLastBinValue' },
+    '0060,3008' => { VR => 'US', Name => 'HistogramBinWidth' },
+    '0060,3010' => { VR => 'LO', Name => 'HistogramExplanation' },
+    '0060,3020' => { VR => 'UL', Name => 'HistogramData' },
+    '0070,0001' => { VR => 'SQ', Name => 'GraphicAnnotationSequence' },
+    '0070,0002' => { VR => 'CS', Name => 'GraphicLayer' },
+    '0070,0003' => { VR => 'CS', Name => 'BoundingBoxAnnotationUnits' },
+    '0070,0004' => { VR => 'CS', Name => 'AnchorPointAnnotationUnits' },
+    '0070,0005' => { VR => 'CS', Name => 'GraphicAnnotationUnits' },
+    '0070,0006' => { VR => 'ST', Name => 'UnformattedTextValue' },
+    '0070,0008' => { VR => 'SQ', Name => 'TextObjectSequence' },
+    '0070,0009' => { VR => 'SQ', Name => 'GraphicObjectSequence' },
+    '0070,0010' => { VR => 'FL', Name => 'BoundingBoxTopLeftHandCorner' },
+    '0070,0011' => { VR => 'FL', Name => 'BoundingBoxBottomRightHandCorner' },
+    '0070,0012' => { VR => 'CS', Name => 'BoundingBoxTextHorizJustification' },
+    '0070,0014' => { VR => 'FL', Name => 'AnchorPoint' },
+    '0070,0015' => { VR => 'CS', Name => 'AnchorPointVisibility' },
+    '0070,0020' => { VR => 'US', Name => 'GraphicDimensions' },
+    '0070,0021' => { VR => 'US', Name => 'NumberOfGraphicPoints' },
+    '0070,0022' => { VR => 'FL', Name => 'GraphicData' },
+    '0070,0023' => { VR => 'CS', Name => 'GraphicType' },
+    '0070,0024' => { VR => 'CS', Name => 'GraphicFilled' },
+    '0070,0041' => { VR => 'CS', Name => 'ImageHorizontalFlip' },
+    '0070,0042' => { VR => 'US', Name => 'ImageRotation' },
+    '0070,0052' => { VR => 'SL', Name => 'DisplayedAreaTopLeftHandCorner' },
+    '0070,0053' => { VR => 'SL', Name => 'DisplayedAreaBottomRightHandCorner' },
+    '0070,005A' => { VR => 'SQ', Name => 'DisplayedAreaSelectionSequence' },
+    '0070,0060' => { VR => 'SQ', Name => 'GraphicLayerSequence' },
+    '0070,0062' => { VR => 'IS', Name => 'GraphicLayerOrder' },
+    '0070,0066' => { VR => 'US', Name => 'GraphicLayerRecDisplayGraysclValue' },
+    '0070,0067' => { VR => 'US', Name => 'GraphicLayerRecDisplayRGBValue' },
+    '0070,0068' => { VR => 'LO', Name => 'GraphicLayerDescription' },
+    '0070,0080' => { VR => 'CS', Name => 'ContentLabel' },
+    '0070,0081' => { VR => 'LO', Name => 'ContentDescription' },
+    '0070,0082' => { VR => 'DA', Name => 'PresentationCreationDate' },
+    '0070,0083' => { VR => 'TM', Name => 'PresentationCreationTime' },
+    '0070,0084' => { VR => 'PN', Name => 'ContentCreatorsName' },
+    '0070,0100' => { VR => 'CS', Name => 'PresentationSizeMode' },
+    '0070,0101' => { VR => 'DS', Name => 'PresentationPixelSpacing' },
+    '0070,0102' => { VR => 'IS', Name => 'PresentationPixelAspectRatio' },
+    '0070,0103' => { VR => 'FL', Name => 'PresentationPixelMagRatio' },
+    '0070,0306' => { VR => 'CS', Name => 'ShapeType' },
+    '0070,0308' => { VR => 'SQ', Name => 'RegistrationSequence' },
+    '0070,0309' => { VR => 'SQ', Name => 'MatrixRegistrationSequence' },
+    '0070,030A' => { VR => 'SQ', Name => 'MatrixSequence' },
+    '0070,030C' => { VR => 'CS', Name => 'FrameOfRefTransformationMatrixType' },
+    '0070,030D' => { VR => 'SQ', Name => 'RegistrationTypeCodeSequence' },
+    '0070,030F' => { VR => 'ST', Name => 'FiducialDescription' },
+    '0070,0310' => { VR => 'SH', Name => 'FiducialIdentifier' },
+    '0070,0311' => { VR => 'SQ', Name => 'FiducialIdentifierCodeSequence' },
+    '0070,0312' => { VR => 'FD', Name => 'ContourUncertaintyRadius' },
+    '0070,0314' => { VR => 'SQ', Name => 'UsedFiducialsSequence' },
+    '0070,0318' => { VR => 'SQ', Name => 'GraphicCoordinatesDataSequence' },
+    '0070,031A' => { VR => 'UI', Name => 'FiducialUID' },
+    '0070,031C' => { VR => 'SQ', Name => 'FiducialSetSequence' },
+    '0070,031E' => { VR => 'SQ', Name => 'FiducialSequence' },
+    # storage group
+    '0088,0130' => { VR => 'SH', Name => 'StorageMediaFileSetID' },
+    '0088,0140' => { VR => 'UI', Name => 'StorageMediaFileSetUID' },
+    '0088,0200' => { VR => 'SQ', Name => 'IconImageSequence' },
+    '0088,0904' => { VR => 'LO', Name => 'TopicTitle' },
+    '0088,0906' => { VR => 'ST', Name => 'TopicSubject' },
+    '0088,0910' => { VR => 'LO', Name => 'TopicAuthor' },
+    '0088,0912' => { VR => 'LO', Name => 'TopicKeyWords' },
+    '0100,0410' => { VR => 'CS', Name => 'SOPInstanceStatus' },
+    '0100,0420' => { VR => 'DT', Name => 'SOPAuthorizationDateAndTime' },
+    '0100,0424' => { VR => 'LT', Name => 'SOPAuthorizationComment' },
+    '0100,0426' => { VR => 'LO', Name => 'AuthorizationEquipmentCertNumber' },
+    '0400,0005' => { VR => 'US', Name => 'MACIDNumber' },
+    '0400,0010' => { VR => 'UI', Name => 'MACCalculationTransferSyntaxUID' },
+    '0400,0015' => { VR => 'CS', Name => 'MACAlgorithm' },
+    '0400,0020' => { VR => 'AT', Name => 'DataElementsSigned' },
+    '0400,0100' => { VR => 'UI', Name => 'DigitalSignatureUID' },
+    '0400,0105' => { VR => 'DT', Name => 'DigitalSignatureDateTime' },
+    '0400,0110' => { VR => 'CS', Name => 'CertificateType' },
+    '0400,0115' => { VR => 'OB', Name => 'CertificateOfSigner' },
+    '0400,0120' => { VR => 'OB', Name => 'Signature' },
+    '0400,0305' => { VR => 'CS', Name => 'CertifiedTimestampType' },
+    '0400,0310' => { VR => 'OB', Name => 'CertifiedTimestamp' },
+    '0400,0500' => { VR => 'SQ', Name => 'EncryptedAttributesSequence' },
+    '0400,0510' => { VR => 'UI', Name => 'EncryptedContentTransferSyntaxUID' },
+    '0400,0520' => { VR => 'OB', Name => 'EncryptedContent' },
+    '0400,0550' => { VR => 'SQ', Name => 'ModifiedAttributesSequence' },
+    '2000,0010' => { VR => 'IS', Name => 'NumberOfCopies' },
+    '2000,001E' => { VR => 'SQ', Name => 'PrinterConfigurationSequence' },
+    '2000,0020' => { VR => 'CS', Name => 'PrintPriority' },
+    '2000,0030' => { VR => 'CS', Name => 'MediumType' },
+    '2000,0040' => { VR => 'CS', Name => 'FilmDestination' },
+    '2000,0050' => { VR => 'LO', Name => 'FilmSessionLabel' },
+    '2000,0060' => { VR => 'IS', Name => 'MemoryAllocation' },
+    '2000,0061' => { VR => 'IS', Name => 'MaximumMemoryAllocation' },
+    '2000,0062' => { VR => 'CS', Name => 'ColorImagePrintingFlag' },
+    '2000,0063' => { VR => 'CS', Name => 'CollationFlag' },
+    '2000,0065' => { VR => 'CS', Name => 'AnnotationFlag' },
+    '2000,0067' => { VR => 'CS', Name => 'ImageOverlayFlag' },
+    '2000,0069' => { VR => 'CS', Name => 'PresentationLUTFlag' },
+    '2000,006A' => { VR => 'CS', Name => 'ImageBoxPresentationLUTFlag' },
+    '2000,00A0' => { VR => 'US', Name => 'MemoryBitDepth' },
+    '2000,00A1' => { VR => 'US', Name => 'PrintingBitDepth' },
+    '2000,00A2' => { VR => 'SQ', Name => 'MediaInstalledSequence' },
+    '2000,00A4' => { VR => 'SQ', Name => 'OtherMediaAvailableSequence' },
+    '2000,00A8' => { VR => 'SQ', Name => 'SupportedImageDisplayFormatSeq' },
+    # film box group
+    '2000,0500' => { VR => 'SQ', Name => 'ReferencedFilmBoxSequence' },
+    '2000,0510' => { VR => 'SQ', Name => 'ReferencedStoredPrintSequence' },
+    '2010,0010' => { VR => 'ST', Name => 'ImageDisplayFormat' },
+    '2010,0030' => { VR => 'CS', Name => 'AnnotationDisplayFormatID' },
+    '2010,0040' => { VR => 'CS', Name => 'FilmOrientation' },
+    '2010,0050' => { VR => 'CS', Name => 'FilmSizeID' },
+    '2010,0052' => { VR => 'CS', Name => 'PrinterResolutionID' },
+    '2010,0054' => { VR => 'CS', Name => 'DefaultPrinterResolutionID' },
+    '2010,0060' => { VR => 'CS', Name => 'MagnificationType' },
+    '2010,0080' => { VR => 'CS', Name => 'SmoothingType' },
+    '2010,00A6' => { VR => 'CS', Name => 'DefaultMagnificationType' },
+    '2010,00A7' => { VR => 'CS', Name => 'OtherMagnificationTypesAvailable' },
+    '2010,00A8' => { VR => 'CS', Name => 'DefaultSmoothingType' },
+    '2010,00A9' => { VR => 'CS', Name => 'OtherSmoothingTypesAvailable' },
+    '2010,0100' => { VR => 'CS', Name => 'BorderDensity' },
+    '2010,0110' => { VR => 'CS', Name => 'EmptyImageDensity' },
+    '2010,0120' => { VR => 'US', Name => 'MinDensity' },
+    '2010,0130' => { VR => 'US', Name => 'MaxDensity' },
+    '2010,0140' => { VR => 'CS', Name => 'Trim' },
+    '2010,0150' => { VR => 'ST', Name => 'ConfigurationInformation' },
+    '2010,0152' => { VR => 'LT', Name => 'ConfigurationInformationDescr' },
+    '2010,0154' => { VR => 'IS', Name => 'MaximumCollatedFilms' },
+    '2010,015E' => { VR => 'US', Name => 'Illumination' },
+    '2010,0160' => { VR => 'US', Name => 'ReflectedAmbientLight' },
+    '2010,0376' => { VR => 'DS', Name => 'PrinterPixelSpacing' },
+    '2010,0500' => { VR => 'SQ', Name => 'ReferencedFilmSessionSequence' },
+    '2010,0510' => { VR => 'SQ', Name => 'ReferencedImageBoxSequence' },
+    '2010,0520' => { VR => 'SQ', Name => 'ReferencedBasicAnnotationBoxSeq' },
+    # image box group
+    '2020,0010' => { VR => 'US', Name => 'ImagePosition' },
+    '2020,0020' => { VR => 'CS', Name => 'Polarity' },
+    '2020,0030' => { VR => 'DS', Name => 'RequestedImageSize' },
+    '2020,0040' => { VR => 'CS', Name => 'RequestedDecimate-CropBehavior' },
+    '2020,0050' => { VR => 'CS', Name => 'RequestedResolutionID' },
+    '2020,00A0' => { VR => 'CS', Name => 'RequestedImageSizeFlag' },
+    '2020,00A2' => { VR => 'CS', Name => 'Decimate-CropResult' },
+    '2020,0110' => { VR => 'SQ', Name => 'BasicGrayscaleImageSequence' },
+    '2020,0111' => { VR => 'SQ', Name => 'BasicColorImageSequence' },
+    '2020,0130' => { VR => 'RET',Name => 'ReferencedImageOverlayBoxSequence' },
+    '2020,0140' => { VR => 'RET',Name => 'ReferencedVOILUTBoxSequence' },
+    # annotation group
+    '2030,0010' => { VR => 'US', Name => 'AnnotationPosition' },
+    '2030,0020' => { VR => 'LO', Name => 'TextString' },
+    # overlay box group
+    '2040,0010' => { VR => 'SQ', Name => 'ReferencedOverlayPlaneSequence' },
+    '2040,0011' => { VR => 'US', Name => 'ReferencedOverlayPlaneGroups' },
+    '2040,0020' => { VR => 'SQ', Name => 'OverlayPixelDataSequence' },
+    '2040,0060' => { VR => 'CS', Name => 'OverlayMagnificationType' },
+    '2040,0070' => { VR => 'CS', Name => 'OverlaySmoothingType' },
+    '2040,0072' => { VR => 'CS', Name => 'OverlayOrImageMagnification' },
+    '2040,0074' => { VR => 'US', Name => 'MagnifyToNumberOfColumns' },
+    '2040,0080' => { VR => 'CS', Name => 'OverlayForegroundDensity' },
+    '2040,0082' => { VR => 'CS', Name => 'OverlayBackgroundDensity' },
+    '2040,0090' => { VR => 'RET',Name => 'OverlayMode' },
+    '2040,0100' => { VR => 'RET',Name => 'ThresholdDensity' },
+    '2040,0500' => { VR => 'RET',Name => 'ReferencedImageBoxSequence' },
+    '2050,0010' => { VR => 'SQ', Name => 'PresentationLUTSequence' },
+    '2050,0020' => { VR => 'CS', Name => 'PresentationLUTShape' },
+    '2050,0500' => { VR => 'SQ', Name => 'ReferencedPresentationLUTSequence' },
+    '2100,0010' => { VR => 'SH', Name => 'PrintJobID' },
+    '2100,0020' => { VR => 'CS', Name => 'ExecutionStatus' },
+    '2100,0030' => { VR => 'CS', Name => 'ExecutionStatusInfo' },
+    '2100,0040' => { VR => 'DA', Name => 'CreationDate' },
+    '2100,0050' => { VR => 'TM', Name => 'CreationTime' },
+    '2100,0070' => { VR => 'AE', Name => 'Originator' },
+    '2100,0140' => { VR => 'AE', Name => 'Destination' },
+    '2100,0160' => { VR => 'SH', Name => 'OwnerID' },
+    '2100,0170' => { VR => 'IS', Name => 'NumberOfFilms' },
+    '2100,0500' => { VR => 'SQ', Name => 'ReferencedPrintJobSequence' },
+    # printer group
+    '2110,0010' => { VR => 'CS', Name => 'PrinterStatus' },
+    '2110,0020' => { VR => 'CS', Name => 'PrinterStatusInfo' },
+    '2110,0030' => { VR => 'LO', Name => 'PrinterName' },
+    '2110,0099' => { VR => 'SH', Name => 'PrintQueueID' },
+    '2120,0010' => { VR => 'CS', Name => 'QueueStatus' },
+    # print job group
+    '2120,0050' => { VR => 'SQ', Name => 'PrintJobDescriptionSequence' },
+    '2120,0070' => { VR => 'SQ', Name => 'ReferencedPrintJobSequence' },
+    '2130,0010' => { VR => 'SQ', Name => 'PrintManagementCapabilitiesSeq' },
+    '2130,0015' => { VR => 'SQ', Name => 'PrinterCharacteristicsSequence' },
+    '2130,0030' => { VR => 'SQ', Name => 'FilmBoxContentSequence' },
+    '2130,0040' => { VR => 'SQ', Name => 'ImageBoxContentSequence' },
+    '2130,0050' => { VR => 'SQ', Name => 'AnnotationContentSequence' },
+    '2130,0060' => { VR => 'SQ', Name => 'ImageOverlayBoxContentSequence' },
+    '2130,0080' => { VR => 'SQ', Name => 'PresentationLUTContentSequence' },
+    '2130,00A0' => { VR => 'SQ', Name => 'ProposedStudySequence' },
+    '2130,00C0' => { VR => 'SQ', Name => 'OriginalImageSequence' },
+    '2200,0001' => { VR => 'CS', Name => 'LabelFromInfoExtractedFromInstance' },
+    '2200,0002' => { VR => 'UT', Name => 'LabelText' },
+    '2200,0003' => { VR => 'CS', Name => 'LabelStyleSelection' },
+    '2200,0004' => { VR => 'LT', Name => 'MediaDisposition' },
+    '2200,0005' => { VR => 'LT', Name => 'BarcodeValue' },
+    '2200,0006' => { VR => 'CS', Name => 'BarcodeSymbology' },
+    '2200,0007' => { VR => 'CS', Name => 'AllowMediaSplitting' },
+    '2200,0008' => { VR => 'CS', Name => 'IncludeNonDICOMObjects' },
+    '2200,0009' => { VR => 'CS', Name => 'IncludeDisplayApplication' },
+    '2200,000A' => { VR => 'CS', Name => 'SaveCompInstancesAfterMediaCreate' },
+    '2200,000B' => { VR => 'US', Name => 'TotalNumberMediaPiecesCreated' },
+    '2200,000C' => { VR => 'LO', Name => 'RequestedMediaApplicationProfile' },
+    '2200,000D' => { VR => 'SQ', Name => 'ReferencedStorageMediaSequence' },
+    '2200,000E' => { VR => 'AT', Name => 'FailureAttributes' },
+    '2200,000F' => { VR => 'CS', Name => 'AllowLossyCompression' },
+    '2200,0020' => { VR => 'CS', Name => 'RequestPriority' },
+    '3002,0002' => { VR => 'SH', Name => 'RTImageLabel' },
+    '3002,0003' => { VR => 'LO', Name => 'RTImageName' },
+    '3002,0004' => { VR => 'ST', Name => 'RTImageDescription' },
+    '3002,000A' => { VR => 'CS', Name => 'ReportedValuesOrigin' },
+    '3002,000C' => { VR => 'CS', Name => 'RTImagePlane' },
+    '3002,000D' => { VR => 'DS', Name => 'XRayImageReceptorTranslation' },
+    '3002,000E' => { VR => 'DS', Name => 'XRayImageReceptorAngle' },
+    '3002,0010' => { VR => 'DS', Name => 'RTImageOrientation' },
+    '3002,0011' => { VR => 'DS', Name => 'ImagePlanePixelSpacing' },
+    '3002,0012' => { VR => 'DS', Name => 'RTImagePosition' },
+    '3002,0020' => { VR => 'SH', Name => 'RadiationMachineName' },
+    '3002,0022' => { VR => 'DS', Name => 'RadiationMachineSAD' },
+    '3002,0024' => { VR => 'DS', Name => 'RadiationMachineSSD' },
+    '3002,0026' => { VR => 'DS', Name => 'RTImageSID' },
+    '3002,0028' => { VR => 'DS', Name => 'SourceToReferenceObjectDistance' },
+    '3002,0029' => { VR => 'IS', Name => 'FractionNumber' },
+    '3002,0030' => { VR => 'SQ', Name => 'ExposureSequence' },
+    '3002,0032' => { VR => 'DS', Name => 'MetersetExposure' },
+    '3002,0034' => { VR => 'DS', Name => 'DiaphragmPosition' },
+    '3002,0040' => { VR => 'SQ', Name => 'FluenceMapSequence' },
+    '3002,0041' => { VR => 'CS', Name => 'FluenceDataSource' },
+    '3002,0042' => { VR => 'DS', Name => 'FluenceDataScale' },
+    '3004,0001' => { VR => 'CS', Name => 'DVHType' },
+    '3004,0002' => { VR => 'CS', Name => 'DoseUnits' },
+    '3004,0004' => { VR => 'CS', Name => 'DoseType' },
+    '3004,0006' => { VR => 'LO', Name => 'DoseComment' },
+    '3004,0008' => { VR => 'DS', Name => 'NormalizationPoint' },
+    '3004,000A' => { VR => 'CS', Name => 'DoseSummationType' },
+    '3004,000C' => { VR => 'DS', Name => 'GridFrameOffsetVector' },
+    '3004,000E' => { VR => 'DS', Name => 'DoseGridScaling' },
+    '3004,0010' => { VR => 'SQ', Name => 'RTDoseROISequence' },
+    '3004,0012' => { VR => 'DS', Name => 'DoseValue' },
+    '3004,0014' => { VR => 'CS', Name => 'TissueHeterogeneityCorrection' },
+    '3004,0040' => { VR => 'DS', Name => 'DVHNormalizationPoint' },
+    '3004,0042' => { VR => 'DS', Name => 'DVHNormalizationDoseValue' },
+    '3004,0050' => { VR => 'SQ', Name => 'DVHSequence' },
+    '3004,0052' => { VR => 'DS', Name => 'DVHDoseScaling' },
+    '3004,0054' => { VR => 'CS', Name => 'DVHVolumeUnits' },
+    '3004,0056' => { VR => 'IS', Name => 'DVHNumberOfBins' },
+    '3004,0058' => { VR => 'DS', Name => 'DVHData' },
+    '3004,0060' => { VR => 'SQ', Name => 'DVHReferencedROISequence' },
+    '3004,0062' => { VR => 'CS', Name => 'DVHROIContributionType' },
+    '3004,0070' => { VR => 'DS', Name => 'DVHMinimumDose' },
+    '3004,0072' => { VR => 'DS', Name => 'DVHMaximumDose' },
+    '3004,0074' => { VR => 'DS', Name => 'DVHMeanDose' },
+    '3006,0002' => { VR => 'SH', Name => 'StructureSetLabel' },
+    '3006,0004' => { VR => 'LO', Name => 'StructureSetName' },
+    '3006,0006' => { VR => 'ST', Name => 'StructureSetDescription' },
+    '3006,0008' => { VR => 'DA', Name => 'StructureSetDate' },
+    '3006,0009' => { VR => 'TM', Name => 'StructureSetTime' },
+    '3006,0010' => { VR => 'SQ', Name => 'ReferencedFrameOfReferenceSequence' },
+    '3006,0012' => { VR => 'SQ', Name => 'RTReferencedStudySequence' },
+    '3006,0014' => { VR => 'SQ', Name => 'RTReferencedSeriesSequence' },
+    '3006,0016' => { VR => 'SQ', Name => 'ContourImageSequence' },
+    '3006,0020' => { VR => 'SQ', Name => 'StructureSetROISequence' },
+    '3006,0022' => { VR => 'IS', Name => 'ROINumber' },
+    '3006,0024' => { VR => 'UI', Name => 'ReferencedFrameOfReferenceUID' },
+    '3006,0026' => { VR => 'LO', Name => 'ROIName' },
+    '3006,0028' => { VR => 'ST', Name => 'ROIDescription' },
+    '3006,002A' => { VR => 'IS', Name => 'ROIDisplayColor' },
+    '3006,002C' => { VR => 'DS', Name => 'ROIVolume' },
+    '3006,0030' => { VR => 'SQ', Name => 'RTRelatedROISequence' },
+    '3006,0033' => { VR => 'CS', Name => 'RTROIRelationship' },
+    '3006,0036' => { VR => 'CS', Name => 'ROIGenerationAlgorithm' },
+    '3006,0038' => { VR => 'LO', Name => 'ROIGenerationDescription' },
+    '3006,0039' => { VR => 'SQ', Name => 'ROIContourSequence' },
+    '3006,0040' => { VR => 'SQ', Name => 'ContourSequence' },
+    '3006,0042' => { VR => 'CS', Name => 'ContourGeometricType' },
+    '3006,0044' => { VR => 'DS', Name => 'ContourSlabThickness' },
+    '3006,0045' => { VR => 'DS', Name => 'ContourOffsetVector' },
+    '3006,0046' => { VR => 'IS', Name => 'NumberOfContourPoints' },
+    '3006,0048' => { VR => 'IS', Name => 'ContourNumber' },
+    '3006,0049' => { VR => 'IS', Name => 'AttachedContours' },
+    '3006,0050' => { VR => 'DS', Name => 'ContourData' },
+    '3006,0080' => { VR => 'SQ', Name => 'RTROIObservationsSequence' },
+    '3006,0082' => { VR => 'IS', Name => 'ObservationNumber' },
+    '3006,0084' => { VR => 'IS', Name => 'ReferencedROINumber' },
+    '3006,0085' => { VR => 'SH', Name => 'ROIObservationLabel' },
+    '3006,0086' => { VR => 'SQ', Name => 'RTROIIdentificationCodeSequence' },
+    '3006,0088' => { VR => 'ST', Name => 'ROIObservationDescription' },
+    '3006,00A0' => { VR => 'SQ', Name => 'RelatedRTROIObservationsSequence' },
+    '3006,00A4' => { VR => 'CS', Name => 'RTROIInterpretedType' },
+    '3006,00A6' => { VR => 'PN', Name => 'ROIInterpreter' },
+    '3006,00B0' => { VR => 'SQ', Name => 'ROIPhysicalPropertiesSequence' },
+    '3006,00B2' => { VR => 'CS', Name => 'ROIPhysicalProperty' },
+    '3006,00B4' => { VR => 'DS', Name => 'ROIPhysicalPropertyValue' },
+    '3006,00C0' => { VR => 'SQ', Name => 'FrameOfReferenceRelationshipSeq' },
+    '3006,00C2' => { VR => 'UI', Name => 'RelatedFrameOfReferenceUID' },
+    '3006,00C4' => { VR => 'CS', Name => 'FrameOfReferenceTransformType' },
+    '3006,00C6' => { VR => 'DS', Name => 'FrameOfReferenceTransformMatrix' },
+    '3006,00C8' => { VR => 'LO', Name => 'FrameOfReferenceTransformComment' },
+    '3008,0010' => { VR => 'SQ', Name => 'MeasuredDoseReferenceSequence' },
+    '3008,0012' => { VR => 'ST', Name => 'MeasuredDoseDescription' },
+    '3008,0014' => { VR => 'CS', Name => 'MeasuredDoseType' },
+    '3008,0016' => { VR => 'DS', Name => 'MeasuredDoseValue' },
+    '3008,0020' => { VR => 'SQ', Name => 'TreatmentSessionBeamSequence' },
+    '3008,0022' => { VR => 'IS', Name => 'CurrentFractionNumber' },
+    '3008,0024' => { VR => 'DA', Name => 'TreatmentControlPointDate' },
+    '3008,0025' => { VR => 'TM', Name => 'TreatmentControlPointTime' },
+    '3008,002A' => { VR => 'CS', Name => 'TreatmentTerminationStatus' },
+    '3008,002B' => { VR => 'SH', Name => 'TreatmentTerminationCode' },
+    '3008,002C' => { VR => 'CS', Name => 'TreatmentVerificationStatus' },
+    '3008,0030' => { VR => 'SQ', Name => 'ReferencedTreatmentRecordSequence' },
+    '3008,0032' => { VR => 'DS', Name => 'SpecifiedPrimaryMeterset' },
+    '3008,0033' => { VR => 'DS', Name => 'SpecifiedSecondaryMeterset' },
+    '3008,0036' => { VR => 'DS', Name => 'DeliveredPrimaryMeterset' },
+    '3008,0037' => { VR => 'DS', Name => 'DeliveredSecondaryMeterset' },
+    '3008,003A' => { VR => 'DS', Name => 'SpecifiedTreatmentTime' },
+    '3008,003B' => { VR => 'DS', Name => 'DeliveredTreatmentTime' },
+    '3008,0040' => { VR => 'SQ', Name => 'ControlPointDeliverySequence' },
+    '3008,0042' => { VR => 'DS', Name => 'SpecifiedMeterset' },
+    '3008,0044' => { VR => 'DS', Name => 'DeliveredMeterset' },
+    '3008,0048' => { VR => 'DS', Name => 'DoseRateDelivered' },
+    '3008,0050' => { VR => 'SQ', Name => 'TreatmentSummaryCalcDoseRefSeq' },
+    '3008,0052' => { VR => 'DS', Name => 'CumulativeDoseToDoseReference' },
+    '3008,0054' => { VR => 'DA', Name => 'FirstTreatmentDate' },
+    '3008,0056' => { VR => 'DA', Name => 'MostRecentTreatmentDate' },
+    '3008,005A' => { VR => 'IS', Name => 'NumberOfFractionsDelivered' },
+    '3008,0060' => { VR => 'SQ', Name => 'OverrideSequence' },
+    '3008,0062' => { VR => 'AT', Name => 'OverrideParameterPointer' },
+    '3008,0064' => { VR => 'IS', Name => 'MeasuredDoseReferenceNumber' },
+    '3008,0066' => { VR => 'ST', Name => 'OverrideReason' },
+    '3008,0070' => { VR => 'SQ', Name => 'CalculatedDoseReferenceSequence' },
+    '3008,0072' => { VR => 'IS', Name => 'CalculatedDoseReferenceNumber' },
+    '3008,0074' => { VR => 'ST', Name => 'CalculatedDoseReferenceDescription' },
+    '3008,0076' => { VR => 'DS', Name => 'CalculatedDoseReferenceDoseValue' },
+    '3008,0078' => { VR => 'DS', Name => 'StartMeterset' },
+    '3008,007A' => { VR => 'DS', Name => 'EndMeterset' },
+    '3008,0080' => { VR => 'SQ', Name => 'ReferencedMeasuredDoseReferenceSeq' },
+    '3008,0082' => { VR => 'IS', Name => 'ReferencedMeasuredDoseReferenceNum' },
+    '3008,0090' => { VR => 'SQ', Name => 'ReferencedCalculatedDoseRefSeq' },
+    '3008,0092' => { VR => 'IS', Name => 'ReferencedCalculatedDoseRefNumber' },
+    '3008,00A0' => { VR => 'SQ', Name => 'BeamLimitingDeviceLeafPairsSeq' },
+    '3008,00B0' => { VR => 'SQ', Name => 'RecordedWedgeSequence' },
+    '3008,00C0' => { VR => 'SQ', Name => 'RecordedCompensatorSequence' },
+    '3008,00D0' => { VR => 'SQ', Name => 'RecordedBlockSequence' },
+    '3008,00E0' => { VR => 'SQ', Name => 'TreatmentSummaryMeasuredDoseRefSeq' },
+    '3008,0100' => { VR => 'SQ', Name => 'RecordedSourceSequence' },
+    '3008,0105' => { VR => 'LO', Name => 'SourceSerialNumber' },
+    '3008,0110' => { VR => 'SQ', Name => 'TreatmentSessionAppSetupSeq' },
+    '3008,0116' => { VR => 'CS', Name => 'ApplicationSetupCheck' },
+    '3008,0120' => { VR => 'SQ', Name => 'RecordedBrachyAccessoryDeviceSeq' },
+    '3008,0122' => { VR => 'IS', Name => 'ReferencedBrachyAccessoryDeviceNum' },
+    '3008,0130' => { VR => 'SQ', Name => 'RecordedChannelSequence' },
+    '3008,0132' => { VR => 'DS', Name => 'SpecifiedChannelTotalTime' },
+    '3008,0134' => { VR => 'DS', Name => 'DeliveredChannelTotalTime' },
+    '3008,0136' => { VR => 'IS', Name => 'SpecifiedNumberOfPulses' },
+    '3008,0138' => { VR => 'IS', Name => 'DeliveredNumberOfPulses' },
+    '3008,013A' => { VR => 'DS', Name => 'SpecifiedPulseRepetitionInterval' },
+    '3008,013C' => { VR => 'DS', Name => 'DeliveredPulseRepetitionInterval' },
+    '3008,0140' => { VR => 'SQ', Name => 'RecordedSourceApplicatorSequence' },
+    '3008,0142' => { VR => 'IS', Name => 'ReferencedSourceApplicatorNumber' },
+    '3008,0150' => { VR => 'SQ', Name => 'RecordedChannelShieldSequence' },
+    '3008,0152' => { VR => 'IS', Name => 'ReferencedChannelShieldNumber' },
+    '3008,0160' => { VR => 'SQ', Name => 'BrachyControlPointDeliveredSeq' },
+    '3008,0162' => { VR => 'DA', Name => 'SafePositionExitDate' },
+    '3008,0164' => { VR => 'TM', Name => 'SafePositionExitTime' },
+    '3008,0166' => { VR => 'DA', Name => 'SafePositionReturnDate' },
+    '3008,0168' => { VR => 'TM', Name => 'SafePositionReturnTime' },
+    '3008,0200' => { VR => 'CS', Name => 'CurrentTreatmentStatus' },
+    '3008,0202' => { VR => 'ST', Name => 'TreatmentStatusComment' },
+    '3008,0220' => { VR => 'SQ', Name => 'FractionGroupSummarySequence' },
+    '3008,0223' => { VR => 'IS', Name => 'ReferencedFractionNumber' },
+    '3008,0224' => { VR => 'CS', Name => 'FractionGroupType' },
+    '3008,0230' => { VR => 'CS', Name => 'BeamStopperPosition' },
+    '3008,0240' => { VR => 'SQ', Name => 'FractionStatusSummarySequence' },
+    '3008,0250' => { VR => 'DA', Name => 'TreatmentDate' },
+    '3008,0251' => { VR => 'TM', Name => 'TreatmentTime' },
+    '300A,0002' => { VR => 'SH', Name => 'RTPlanLabel' },
+    '300A,0003' => { VR => 'LO', Name => 'RTPlanName' },
+    '300A,0004' => { VR => 'ST', Name => 'RTPlanDescription' },
+    '300A,0006' => { VR => 'DA', Name => 'RTPlanDate' },
+    '300A,0007' => { VR => 'TM', Name => 'RTPlanTime' },
+    '300A,0009' => { VR => 'LO', Name => 'TreatmentProtocols' },
+    '300A,000A' => { VR => 'CS', Name => 'TreatmentIntent' },
+    '300A,000B' => { VR => 'LO', Name => 'TreatmentSites' },
+    '300A,000C' => { VR => 'CS', Name => 'RTPlanGeometry' },
+    '300A,000E' => { VR => 'ST', Name => 'PrescriptionDescription' },
+    '300A,0010' => { VR => 'SQ', Name => 'DoseReferenceSequence' },
+    '300A,0012' => { VR => 'IS', Name => 'DoseReferenceNumber' },
+    '300A,0013' => { VR => 'UI', Name => 'DoseReferenceUID' },
+    '300A,0014' => { VR => 'CS', Name => 'DoseReferenceStructureType' },
+    '300A,0015' => { VR => 'CS', Name => 'NominalBeamEnergyUnit' },
+    '300A,0016' => { VR => 'LO', Name => 'DoseReferenceDescription' },
+    '300A,0018' => { VR => 'DS', Name => 'DoseReferencePointCoordinates' },
+    '300A,001A' => { VR => 'DS', Name => 'NominalPriorDose' },
+    '300A,0020' => { VR => 'CS', Name => 'DoseReferenceType' },
+    '300A,0021' => { VR => 'DS', Name => 'ConstraintWeight' },
+    '300A,0022' => { VR => 'DS', Name => 'DeliveryWarningDose' },
+    '300A,0023' => { VR => 'DS', Name => 'DeliveryMaximumDose' },
+    '300A,0025' => { VR => 'DS', Name => 'TargetMinimumDose' },
+    '300A,0026' => { VR => 'DS', Name => 'TargetPrescriptionDose' },
+    '300A,0027' => { VR => 'DS', Name => 'TargetMaximumDose' },
+    '300A,0028' => { VR => 'DS', Name => 'TargetUnderdoseVolumeFraction' },
+    '300A,002A' => { VR => 'DS', Name => 'OrganAtRiskFullVolumeDose' },
+    '300A,002B' => { VR => 'DS', Name => 'OrganAtRiskLimitDose' },
+    '300A,002C' => { VR => 'DS', Name => 'OrganAtRiskMaximumDose' },
+    '300A,002D' => { VR => 'DS', Name => 'OrganAtRiskOverdoseVolumeFraction' },
+    '300A,0040' => { VR => 'SQ', Name => 'ToleranceTableSequence' },
+    '300A,0042' => { VR => 'IS', Name => 'ToleranceTableNumber' },
+    '300A,0043' => { VR => 'SH', Name => 'ToleranceTableLabel' },
+    '300A,0044' => { VR => 'DS', Name => 'GantryAngleTolerance' },
+    '300A,0046' => { VR => 'DS', Name => 'BeamLimitingDeviceAngleTolerance' },
+    '300A,0048' => { VR => 'SQ', Name => 'BeamLimitingDeviceToleranceSeq' },
+    '300A,004A' => { VR => 'DS', Name => 'BeamLimitingDevicePositionTol' },
+    '300A,004C' => { VR => 'DS', Name => 'PatientSupportAngleTolerance' },
+    '300A,004E' => { VR => 'DS', Name => 'TableTopEccentricAngleTolerance' },
+    '300A,0051' => { VR => 'DS', Name => 'TableTopVerticalPositionTolerance' },
+    '300A,0052' => { VR => 'DS', Name => 'TableTopLongitudinalPositionTol' },
+    '300A,0053' => { VR => 'DS', Name => 'TableTopLateralPositionTolerance' },
+    '300A,0055' => { VR => 'CS', Name => 'RTPlanRelationship' },
+    '300A,0070' => { VR => 'SQ', Name => 'FractionGroupSequence' },
+    '300A,0071' => { VR => 'IS', Name => 'FractionGroupNumber' },
+    '300A,0072' => { VR => 'LO', Name => 'FractionGroupDescription' },
+    '300A,0078' => { VR => 'IS', Name => 'NumberOfFractionsPlanned' },
+    '300A,0079' => { VR => 'IS', Name => 'NumberFractionPatternDigitsPerDay' },
+    '300A,007A' => { VR => 'IS', Name => 'RepeatFractionCycleLength' },
+    '300A,007B' => { VR => 'LT', Name => 'FractionPattern' },
+    '300A,0080' => { VR => 'IS', Name => 'NumberOfBeams' },
+    '300A,0082' => { VR => 'DS', Name => 'BeamDoseSpecificationPoint' },
+    '300A,0084' => { VR => 'DS', Name => 'BeamDose' },
+    '300A,0086' => { VR => 'DS', Name => 'BeamMeterset' },
+    '300A,00A0' => { VR => 'IS', Name => 'NumberOfBrachyApplicationSetups' },
+    '300A,00A2' => { VR => 'DS', Name => 'BrachyAppSetupDoseSpecPoint' },
+    '300A,00A4' => { VR => 'DS', Name => 'BrachyApplicationSetupDose' },
+    '300A,00B0' => { VR => 'SQ', Name => 'BeamSequence' },
+    '300A,00B2' => { VR => 'SH', Name => 'TreatmentMachineName' },
+    '300A,00B3' => { VR => 'CS', Name => 'PrimaryDosimeterUnit' },
+    '300A,00B4' => { VR => 'DS', Name => 'SourceAxisDistance' },
+    '300A,00B6' => { VR => 'SQ', Name => 'BeamLimitingDeviceSequence' },
+    '300A,00B8' => { VR => 'CS', Name => 'RTBeamLimitingDeviceType' },
+    '300A,00BA' => { VR => 'DS', Name => 'SourceToBeamLimitingDeviceDistance' },
+    '300A,00BC' => { VR => 'IS', Name => 'NumberOfLeaf-JawPairs' },
+    '300A,00BE' => { VR => 'DS', Name => 'LeafPositionBoundaries' },
+    '300A,00C0' => { VR => 'IS', Name => 'BeamNumber' },
+    '300A,00C2' => { VR => 'LO', Name => 'BeamName' },
+    '300A,00C3' => { VR => 'ST', Name => 'BeamDescription' },
+    '300A,00C4' => { VR => 'CS', Name => 'BeamType' },
+    '300A,00C6' => { VR => 'CS', Name => 'RadiationType' },
+    '300A,00C7' => { VR => 'CS', Name => 'HighDoseTechniqueType' },
+    '300A,00C8' => { VR => 'IS', Name => 'ReferenceImageNumber' },
+    '300A,00CA' => { VR => 'SQ', Name => 'PlannedVerificationImageSequence' },
+    '300A,00CC' => { VR => 'LO', Name => 'ImagingDeviceSpecificAcqParams' },
+    '300A,00CE' => { VR => 'CS', Name => 'TreatmentDeliveryType' },
+    '300A,00D0' => { VR => 'IS', Name => 'NumberOfWedges' },
+    '300A,00D1' => { VR => 'SQ', Name => 'WedgeSequence' },
+    '300A,00D2' => { VR => 'IS', Name => 'WedgeNumber' },
+    '300A,00D3' => { VR => 'CS', Name => 'WedgeType' },
+    '300A,00D4' => { VR => 'SH', Name => 'WedgeID' },
+    '300A,00D5' => { VR => 'IS', Name => 'WedgeAngle' },
+    '300A,00D6' => { VR => 'DS', Name => 'WedgeFactor' },
+    '300A,00D8' => { VR => 'DS', Name => 'WedgeOrientation' },
+    '300A,00DA' => { VR => 'DS', Name => 'SourceToWedgeTrayDistance' },
+    '300A,00E0' => { VR => 'IS', Name => 'NumberOfCompensators' },
+    '300A,00E1' => { VR => 'SH', Name => 'MaterialID' },
+    '300A,00E2' => { VR => 'DS', Name => 'TotalCompensatorTrayFactor' },
+    '300A,00E3' => { VR => 'SQ', Name => 'CompensatorSequence' },
+    '300A,00E4' => { VR => 'IS', Name => 'CompensatorNumber' },
+    '300A,00E5' => { VR => 'SH', Name => 'CompensatorID' },
+    '300A,00E6' => { VR => 'DS', Name => 'SourceToCompensatorTrayDistance' },
+    '300A,00E7' => { VR => 'IS', Name => 'CompensatorRows' },
+    '300A,00E8' => { VR => 'IS', Name => 'CompensatorColumns' },
+    '300A,00E9' => { VR => 'DS', Name => 'CompensatorPixelSpacing' },
+    '300A,00EA' => { VR => 'DS', Name => 'CompensatorPosition' },
+    '300A,00EB' => { VR => 'DS', Name => 'CompensatorTransmissionData' },
+    '300A,00EC' => { VR => 'DS', Name => 'CompensatorThicknessData' },
+    '300A,00ED' => { VR => 'IS', Name => 'NumberOfBoli' },
+    '300A,00EE' => { VR => 'CS', Name => 'CompensatorType' },
+    '300A,00F0' => { VR => 'IS', Name => 'NumberOfBlocks' },
+    '300A,00F2' => { VR => 'DS', Name => 'TotalBlockTrayFactor' },
+    '300A,00F4' => { VR => 'SQ', Name => 'BlockSequence' },
+    '300A,00F5' => { VR => 'SH', Name => 'BlockTrayID' },
+    '300A,00F6' => { VR => 'DS', Name => 'SourceToBlockTrayDistance' },
+    '300A,00F8' => { VR => 'CS', Name => 'BlockType' },
+    '300A,00F9' => { VR => 'LO', Name => 'AccessoryCode' },
+    '300A,00FA' => { VR => 'CS', Name => 'BlockDivergence' },
+    '300A,00FB' => { VR => 'CS', Name => 'BlockMountingPosition' },
+    '300A,00FC' => { VR => 'IS', Name => 'BlockNumber' },
+    '300A,00FE' => { VR => 'LO', Name => 'BlockName' },
+    '300A,0100' => { VR => 'DS', Name => 'BlockThickness' },
+    '300A,0102' => { VR => 'DS', Name => 'BlockTransmission' },
+    '300A,0104' => { VR => 'IS', Name => 'BlockNumberOfPoints' },
+    '300A,0106' => { VR => 'DS', Name => 'BlockData' },
+    '300A,0107' => { VR => 'SQ', Name => 'ApplicatorSequence' },
+    '300A,0108' => { VR => 'SH', Name => 'ApplicatorID' },
+    '300A,0109' => { VR => 'CS', Name => 'ApplicatorType' },
+    '300A,010A' => { VR => 'LO', Name => 'ApplicatorDescription' },
+    '300A,010C' => { VR => 'DS', Name => 'CumulativeDoseReferenceCoefficient' },
+    '300A,010E' => { VR => 'DS', Name => 'FinalCumulativeMetersetWeight' },
+    '300A,0110' => { VR => 'IS', Name => 'NumberOfControlPoints' },
+    '300A,0111' => { VR => 'SQ', Name => 'ControlPointSequence' },
+    '300A,0112' => { VR => 'IS', Name => 'ControlPointIndex' },
+    '300A,0114' => { VR => 'DS', Name => 'NominalBeamEnergy' },
+    '300A,0115' => { VR => 'DS', Name => 'DoseRateSet' },
+    '300A,0116' => { VR => 'SQ', Name => 'WedgePositionSequence' },
+    '300A,0118' => { VR => 'CS', Name => 'WedgePosition' },
+    '300A,011A' => { VR => 'SQ', Name => 'BeamLimitingDevicePositionSequence' },
+    '300A,011C' => { VR => 'DS', Name => 'Leaf-JawPositions' },
+    '300A,011E' => { VR => 'DS', Name => 'GantryAngle' },
+    '300A,011F' => { VR => 'CS', Name => 'GantryRotationDirection' },
+    '300A,0120' => { VR => 'DS', Name => 'BeamLimitingDeviceAngle' },
+    '300A,0121' => { VR => 'CS', Name => 'BeamLimitingDeviceRotateDirection' },
+    '300A,0122' => { VR => 'DS', Name => 'PatientSupportAngle' },
+    '300A,0123' => { VR => 'CS', Name => 'PatientSupportRotationDirection' },
+    '300A,0124' => { VR => 'DS', Name => 'TableTopEccentricAxisDistance' },
+    '300A,0125' => { VR => 'DS', Name => 'TableTopEccentricAngle' },
+    '300A,0126' => { VR => 'CS', Name => 'TableTopEccentricRotateDirection' },
+    '300A,0128' => { VR => 'DS', Name => 'TableTopVerticalPosition' },
+    '300A,0129' => { VR => 'DS', Name => 'TableTopLongitudinalPosition' },
+    '300A,012A' => { VR => 'DS', Name => 'TableTopLateralPosition' },
+    '300A,012C' => { VR => 'DS', Name => 'IsocenterPosition' },
+    '300A,012E' => { VR => 'DS', Name => 'SurfaceEntryPoint' },
+    '300A,0130' => { VR => 'DS', Name => 'SourceToSurfaceDistance' },
+    '300A,0134' => { VR => 'DS', Name => 'CumulativeMetersetWeight' },
+    '300A,0180' => { VR => 'SQ', Name => 'PatientSetupSequence' },
+    '300A,0182' => { VR => 'IS', Name => 'PatientSetupNumber' },
+    '300A,0184' => { VR => 'LO', Name => 'PatientAdditionalPosition' },
+    '300A,0190' => { VR => 'SQ', Name => 'FixationDeviceSequence' },
+    '300A,0192' => { VR => 'CS', Name => 'FixationDeviceType' },
+    '300A,0194' => { VR => 'SH', Name => 'FixationDeviceLabel' },
+    '300A,0196' => { VR => 'ST', Name => 'FixationDeviceDescription' },
+    '300A,0198' => { VR => 'SH', Name => 'FixationDevicePosition' },
+    '300A,01A0' => { VR => 'SQ', Name => 'ShieldingDeviceSequence' },
+    '300A,01A2' => { VR => 'CS', Name => 'ShieldingDeviceType' },
+    '300A,01A4' => { VR => 'SH', Name => 'ShieldingDeviceLabel' },
+    '300A,01A6' => { VR => 'ST', Name => 'ShieldingDeviceDescription' },
+    '300A,01A8' => { VR => 'SH', Name => 'ShieldingDevicePosition' },
+    '300A,01B0' => { VR => 'CS', Name => 'SetupTechnique' },
+    '300A,01B2' => { VR => 'ST', Name => 'SetupTechniqueDescription' },
+    '300A,01B4' => { VR => 'SQ', Name => 'SetupDeviceSequence' },
+    '300A,01B6' => { VR => 'CS', Name => 'SetupDeviceType' },
+    '300A,01B8' => { VR => 'SH', Name => 'SetupDeviceLabel' },
+    '300A,01BA' => { VR => 'ST', Name => 'SetupDeviceDescription' },
+    '300A,01BC' => { VR => 'DS', Name => 'SetupDeviceParameter' },
+    '300A,01D0' => { VR => 'ST', Name => 'SetupReferenceDescription' },
+    '300A,01D2' => { VR => 'DS', Name => 'TableTopVerticalSetupDisplacement' },
+    '300A,01D4' => { VR => 'DS', Name => 'TableTopLongitudinalSetupDisplace' },
+    '300A,01D6' => { VR => 'DS', Name => 'TableTopLateralSetupDisplacement' },
+    '300A,0200' => { VR => 'CS', Name => 'BrachyTreatmentTechnique' },
+    '300A,0202' => { VR => 'CS', Name => 'BrachyTreatmentType' },
+    '300A,0206' => { VR => 'SQ', Name => 'TreatmentMachineSequence' },
+    '300A,0210' => { VR => 'SQ', Name => 'SourceSequence' },
+    '300A,0212' => { VR => 'IS', Name => 'SourceNumber' },
+    '300A,0214' => { VR => 'CS', Name => 'SourceType' },
+    '300A,0216' => { VR => 'LO', Name => 'SourceManufacturer' },
+    '300A,0218' => { VR => 'DS', Name => 'ActiveSourceDiameter' },
+    '300A,021A' => { VR => 'DS', Name => 'ActiveSourceLength' },
+    '300A,0222' => { VR => 'DS', Name => 'SourceEncapsulationNomThickness' },
+    '300A,0224' => { VR => 'DS', Name => 'SourceEncapsulationNomTransmission' },
+    '300A,0226' => { VR => 'LO', Name => 'SourceIsotopeName' },
+    '300A,0228' => { VR => 'DS', Name => 'SourceIsotopeHalfLife' },
+    '300A,022A' => { VR => 'DS', Name => 'ReferenceAirKermaRate' },
+    '300A,022C' => { VR => 'DA', Name => 'AirKermaRateReferenceDate' },
+    '300A,022E' => { VR => 'TM', Name => 'AirKermaRateReferenceTime' },
+    '300A,0230' => { VR => 'SQ', Name => 'ApplicationSetupSequence' },
+    '300A,0232' => { VR => 'CS', Name => 'ApplicationSetupType' },
+    '300A,0234' => { VR => 'IS', Name => 'ApplicationSetupNumber' },
+    '300A,0236' => { VR => 'LO', Name => 'ApplicationSetupName' },
+    '300A,0238' => { VR => 'LO', Name => 'ApplicationSetupManufacturer' },
+    '300A,0240' => { VR => 'IS', Name => 'TemplateNumber' },
+    '300A,0242' => { VR => 'SH', Name => 'TemplateType' },
+    '300A,0244' => { VR => 'LO', Name => 'TemplateName' },
+    '300A,0250' => { VR => 'DS', Name => 'TotalReferenceAirKerma' },
+    '300A,0260' => { VR => 'SQ', Name => 'BrachyAccessoryDeviceSequence' },
+    '300A,0262' => { VR => 'IS', Name => 'BrachyAccessoryDeviceNumber' },
+    '300A,0263' => { VR => 'SH', Name => 'BrachyAccessoryDeviceID' },
+    '300A,0264' => { VR => 'CS', Name => 'BrachyAccessoryDeviceType' },
+    '300A,0266' => { VR => 'LO', Name => 'BrachyAccessoryDeviceName' },
+    '300A,026A' => { VR => 'DS', Name => 'BrachyAccessoryDeviceNomThickness' },
+    '300A,026C' => { VR => 'DS', Name => 'BrachyAccessoryDevNomTransmission' },
+    '300A,0280' => { VR => 'SQ', Name => 'ChannelSequence' },
+    '300A,0282' => { VR => 'IS', Name => 'ChannelNumber' },
+    '300A,0284' => { VR => 'DS', Name => 'ChannelLength' },
+    '300A,0286' => { VR => 'DS', Name => 'ChannelTotalTime' },
+    '300A,0288' => { VR => 'CS', Name => 'SourceMovementType' },
+    '300A,028A' => { VR => 'IS', Name => 'NumberOfPulses' },
+    '300A,028C' => { VR => 'DS', Name => 'PulseRepetitionInterval' },
+    '300A,0290' => { VR => 'IS', Name => 'SourceApplicatorNumber' },
+    '300A,0291' => { VR => 'SH', Name => 'SourceApplicatorID' },
+    '300A,0292' => { VR => 'CS', Name => 'SourceApplicatorType' },
+    '300A,0294' => { VR => 'LO', Name => 'SourceApplicatorName' },
+    '300A,0296' => { VR => 'DS', Name => 'SourceApplicatorLength' },
+    '300A,0298' => { VR => 'LO', Name => 'SourceApplicatorManufacturer' },
+    '300A,029C' => { VR => 'DS', Name => 'SourceApplicatorWallNomThickness' },
+    '300A,029E' => { VR => 'DS', Name => 'SourceApplicatorWallNomTrans' },
+    '300A,02A0' => { VR => 'DS', Name => 'SourceApplicatorStepSize' },
+    '300A,02A2' => { VR => 'IS', Name => 'TransferTubeNumber' },
+    '300A,02A4' => { VR => 'DS', Name => 'TransferTubeLength' },
+    '300A,02B0' => { VR => 'SQ', Name => 'ChannelShieldSequence' },
+    '300A,02B2' => { VR => 'IS', Name => 'ChannelShieldNumber' },
+    '300A,02B3' => { VR => 'SH', Name => 'ChannelShieldID' },
+    '300A,02B4' => { VR => 'LO', Name => 'ChannelShieldName' },
+    '300A,02B8' => { VR => 'DS', Name => 'ChannelShieldNominalThickness' },
+    '300A,02BA' => { VR => 'DS', Name => 'ChannelShieldNominalTransmission' },
+    '300A,02C8' => { VR => 'DS', Name => 'FinalCumulativeTimeWeight' },
+    '300A,02D0' => { VR => 'SQ', Name => 'BrachyControlPointSequence' },
+    '300A,02D2' => { VR => 'DS', Name => 'ControlPointRelativePosition' },
+    '300A,02D4' => { VR => 'DS', Name => 'ControlPoint3DPosition' },
+    '300A,02D6' => { VR => 'DS', Name => 'CumulativeTimeWeight' },
+    '300A,02E0' => { VR => 'CS', Name => 'CompensatorDivergence' },
+    '300A,02E1' => { VR => 'CS', Name => 'CompensatorMountingPosition' },
+    '300A,02E2' => { VR => 'DS', Name => 'SourceToCompensatorDistance' },
+    '300C,0002' => { VR => 'SQ', Name => 'ReferencedRTPlanSequence' },
+    '300C,0004' => { VR => 'SQ', Name => 'ReferencedBeamSequence' },
+    '300C,0006' => { VR => 'IS', Name => 'ReferencedBeamNumber' },
+    '300C,0007' => { VR => 'IS', Name => 'ReferencedReferenceImageNumber' },
+    '300C,0008' => { VR => 'DS', Name => 'StartCumulativeMetersetWeight' },
+    '300C,0009' => { VR => 'DS', Name => 'EndCumulativeMetersetWeight' },
+    '300C,000A' => { VR => 'SQ', Name => 'ReferencedBrachyAppSetupSeq' },
+    '300C,000C' => { VR => 'IS', Name => 'ReferencedBrachyAppSetupNumber' },
+    '300C,000E' => { VR => 'IS', Name => 'ReferencedSourceNumber' },
+    '300C,0020' => { VR => 'SQ', Name => 'ReferencedFractionGroupSequence' },
+    '300C,0022' => { VR => 'IS', Name => 'ReferencedFractionGroupNumber' },
+    '300C,0040' => { VR => 'SQ', Name => 'ReferencedVerificationImageSeq' },
+    '300C,0042' => { VR => 'SQ', Name => 'ReferencedReferenceImageSequence' },
+    '300C,0050' => { VR => 'SQ', Name => 'ReferencedDoseReferenceSequence' },
+    '300C,0051' => { VR => 'IS', Name => 'ReferencedDoseReferenceNumber' },
+    '300C,0055' => { VR => 'SQ', Name => 'BrachyReferencedDoseReferenceSeq' },
+    '300C,0060' => { VR => 'SQ', Name => 'ReferencedStructureSetSequence' },
+    '300C,006A' => { VR => 'IS', Name => 'ReferencedPatientSetupNumber' },
+    '300C,0080' => { VR => 'SQ', Name => 'ReferencedDoseSequence' },
+    '300C,00A0' => { VR => 'IS', Name => 'ReferencedToleranceTableNumber' },
+    '300C,00B0' => { VR => 'SQ', Name => 'ReferencedBolusSequence' },
+    '300C,00C0' => { VR => 'IS', Name => 'ReferencedWedgeNumber' },
+    '300C,00D0' => { VR => 'IS', Name => 'ReferencedCompensatorNumber' },
+    '300C,00E0' => { VR => 'IS', Name => 'ReferencedBlockNumber' },
+    '300C,00F0' => { VR => 'IS', Name => 'ReferencedControlPointIndex' },
+    '300E,0002' => { VR => 'CS', Name => 'ApprovalStatus' },
+    '300E,0004' => { VR => 'DA', Name => 'ReviewDate' },
+    '300E,0005' => { VR => 'TM', Name => 'ReviewTime' },
+    '300E,0008' => { VR => 'PN', Name => 'ReviewerName' },
+    # text group
+    '4000,0000' => { VR => 'UL', Name => 'TextGroupLength' },
+    '4000,0010' => { VR => 'RET',Name => 'Arbitrary' },
+    '4000,4000' => { VR => 'RET',Name => 'TextComments' },
+    # results group
+    '4008,0040' => { VR => 'SH', Name => 'ResultsID' },
+    '4008,0042' => { VR => 'LO', Name => 'ResultsIDIssuer' },
+    '4008,0050' => { VR => 'SQ', Name => 'ReferencedInterpretationSequence' },
+    '4008,0100' => { VR => 'DA', Name => 'InterpretationRecordedDate' },
+    '4008,0101' => { VR => 'TM', Name => 'InterpretationRecordedTime' },
+    '4008,0102' => { VR => 'PN', Name => 'InterpretationRecorder' },
+    '4008,0103' => { VR => 'LO', Name => 'ReferenceToRecordedSound' },
+    '4008,0108' => { VR => 'DA', Name => 'InterpretationTranscriptionDate' },
+    '4008,0109' => { VR => 'TM', Name => 'InterpretationTranscriptionTime' },
+    '4008,010A' => { VR => 'PN', Name => 'InterpretationTranscriber' },
+    '4008,010B' => { VR => 'ST', Name => 'InterpretationText' },
+    '4008,010C' => { VR => 'PN', Name => 'InterpretationAuthor' },
+    '4008,0111' => { VR => 'SQ', Name => 'InterpretationApproverSequence' },
+    '4008,0112' => { VR => 'DA', Name => 'InterpretationApprovalDate' },
+    '4008,0113' => { VR => 'TM', Name => 'InterpretationApprovalTime' },
+    '4008,0114' => { VR => 'PN', Name => 'PhysicianApprovingInterpretation' },
+    '4008,0115' => { VR => 'LT', Name => 'InterpretationDiagnosisDescription' },
+    '4008,0117' => { VR => 'SQ', Name => 'InterpretationDiagnosisCodeSeq' },
+    '4008,0118' => { VR => 'SQ', Name => 'ResultsDistributionListSequence' },
+    '4008,0119' => { VR => 'PN', Name => 'DistributionName' },
+    '4008,011A' => { VR => 'LO', Name => 'DistributionAddress' },
+    '4008,0200' => { VR => 'SH', Name => 'InterpretationID' },
+    '4008,0202' => { VR => 'LO', Name => 'InterpretationIDIssuer' },
+    '4008,0210' => { VR => 'CS', Name => 'InterpretationTypeID' },
+    '4008,0212' => { VR => 'CS', Name => 'InterpretationStatusID' },
+    '4008,0300' => { VR => 'ST', Name => 'Impressions' },
+    '4008,4000' => { VR => 'ST', Name => 'ResultsComments' },
+    '4FFE,0001' => { VR => 'SQ', Name => 'MACParametersSequence' },
+    # curve group
+    '50xx,0005' => { VR => 'US', Name => 'CurveDimensions' },
+    '50xx,0010' => { VR => 'US', Name => 'NumberOfPoints' },
+    '50xx,0020' => { VR => 'CS', Name => 'TypeOfData' },
+    '50xx,0022' => { VR => 'LO', Name => 'CurveDescription' },
+    '50xx,0030' => { VR => 'SH', Name => 'AxisUnits' },
+    '50xx,0040' => { VR => 'SH', Name => 'AxisLabels' },
+    '50xx,0103' => { VR => 'US', Name => 'DataValueRepresentation' },
+    '50xx,0104' => { VR => 'US', Name => 'MinimumCoordinateValue' },
+    '50xx,0105' => { VR => 'US', Name => 'MaximumCoordinateValue' },
+    '50xx,0106' => { VR => 'SH', Name => 'CurveRange' },
+    '50xx,0110' => { VR => 'US', Name => 'CurveDataDescriptor' },
+    '50xx,0112' => { VR => 'US', Name => 'CoordinateStartValue' },
+    '50xx,0114' => { VR => 'US', Name => 'CoordinateStepValue' },
+    '50xx,1001' => { VR => 'CS', Name => 'CurveActivationLayer' },
+    '50xx,2000' => { VR => 'US', Name => 'AudioType' },
+    '50xx,2002' => { VR => 'US', Name => 'AudioSampleFormat' },
+    '50xx,2004' => { VR => 'US', Name => 'NumberOfChannels' },
+    '50xx,2006' => { VR => 'UL', Name => 'NumberOfSamples' },
+    '50xx,2008' => { VR => 'UL', Name => 'SampleRate' },
+    '50xx,200A' => { VR => 'UL', Name => 'TotalTime' },
+    '50xx,200C' => { VR => 'OB', Name => 'AudioSampleData' },
+    '50xx,200E' => { VR => 'LT', Name => 'AudioComments' },
+    '50xx,2500' => { VR => 'LO', Name => 'CurveLabel' },
+    '50xx,2600' => { VR => 'SQ', Name => 'ReferencedOverlaySequence' },
+    '50xx,2610' => { VR => 'US', Name => 'ReferencedOverlayGroup' },
+    '50xx,3000' => { VR => 'OB', Name => 'CurveData' },
+    '5200,9229' => { VR => 'SQ', Name => 'SharedFunctionalGroupsSequence' },
+    '5200,9230' => { VR => 'SQ', Name => 'PerFrameFunctionalGroupsSequence' },
+    '5400,0100' => { VR => 'SQ', Name => 'WaveformSequence' },
+    '5400,0110' => { VR => 'OW', Name => 'ChannelMinimumValue' },
+    '5400,0112' => { VR => 'OW', Name => 'ChannelMaximumValue' },
+    '5400,1004' => { VR => 'US', Name => 'WaveformBitsAllocated' },
+    '5400,1006' => { VR => 'CS', Name => 'WaveformSampleInterpretation' },
+    '5400,100A' => { VR => 'OW', Name => 'WaveformPaddingValue' },
+    '5400,1010' => { VR => 'OW', Name => 'WaveformData' },
+    '5600,0010' => { VR => 'OF', Name => 'FirstOrderPhaseCorrectionAngle' },
+    '5600,0020' => { VR => 'OF', Name => 'SpectroscopyData' },
+    # overlay group
+    '6000,0000' => { VR => 'UL', Name => 'OverlayGroupLength' },
+    '60xx,0010' => { VR => 'US', Name => 'OverlayRows' },
+    '60xx,0011' => { VR => 'US', Name => 'OverlayColumns' },
+    '60xx,0012' => { VR => 'US', Name => 'OverlayPlanes' },
+    '60xx,0015' => { VR => 'IS', Name => 'NumberOfFramesInOverlay' },
+    '60xx,0022' => { VR => 'LO', Name => 'OverlayDescription' },
+    '60xx,0040' => { VR => 'CS', Name => 'OverlayType' },
+    '60xx,0045' => { VR => 'LO', Name => 'OverlaySubtype' },
+    '60xx,0050' => { VR => 'SS', Name => 'OverlayOrigin' },
+    '60xx,0051' => { VR => 'US', Name => 'ImageFrameOrigin' },
+    '60xx,0052' => { VR => 'US', Name => 'OverlayPlaneOrigin' },
+    '60xx,0060' => { VR => 'RET',Name => 'CompressionCode' },
+    '60xx,0100' => { VR => 'US', Name => 'OverlayBitsAllocated' },
+    '60xx,0102' => { VR => 'US', Name => 'OverlayBitPosition' },
+    '60xx,0110' => { VR => 'RET',Name => 'OverlayFormat' },
+    '60xx,0200' => { VR => 'RET',Name => 'OverlayLocation' },
+    '60xx,1001' => { VR => 'CS', Name => 'OverlayActivationLayer' },
+    '60xx,1100' => { VR => 'RET',Name => 'OverlayDescriptorGray' },
+    '60xx,1101' => { VR => 'RET',Name => 'OverlayDescriptorRed' },
+    '60xx,1102' => { VR => 'RET',Name => 'OverlayDescriptorGreen' },
+    '60xx,1103' => { VR => 'RET',Name => 'OverlayDescriptorBlue' },
+    '60xx,1200' => { VR => 'RET',Name => 'OverlaysGray' },
+    '60xx,1201' => { VR => 'RET',Name => 'OverlaysRed' },
+    '60xx,1202' => { VR => 'RET',Name => 'OverlaysGreen' },
+    '60xx,1203' => { VR => 'RET',Name => 'OverlaysBlue' },
+    '60xx,1301' => { VR => 'IS', Name => 'ROIArea' },
+    '60xx,1302' => { VR => 'DS', Name => 'ROIMean' },
+    '60xx,1303' => { VR => 'DS', Name => 'ROIStandardDeviation' },
+    '60xx,1500' => { VR => 'LO', Name => 'OverlayLabel' },
+    '60xx,3000' => { VR => 'OW', Name => 'OverlayData' },
+    '60xx,4000' => { VR => 'RET',Name => 'OverlayComments' },
+    # pixel data group
+    '7FE0,0000' => { VR => 'UL', Name => 'PixelDataGroupLength' },
+    '7FE0,0010' => { VR => 'OB', Name => 'PixelData' },
+    'FFFA,FFFA' => { VR => 'SQ', Name => 'DigitalSignaturesSequence' },
+    'FFFC,FFFC' => { VR => 'OB', Name => 'DataSetTrailingPadding' },
+    # the sequence delimiters have no VR:
+    'FFFE,E000' => 'StartOfItem',
+    'FFFE,E00D' => 'EndOfItems',
+    'FFFE,E0DD' => 'EndOfSequence',
+);
+
+# table to translate registered UID values to readable strings
+my %uid = (
+    '1.2.840.10008.1.1' => 'Verification SOP Class',
+    '1.2.840.10008.1.2' => 'Implicit VR Little Endian',
+    '1.2.840.10008.1.2.1' => 'Explicit VR Little Endian',
+    '1.2.840.10008.1.2.1.99' => 'Deflated Explicit VR Little Endian',
+    '1.2.840.10008.1.2.2' => 'Explicit VR Big Endian',
+    '1.2.840.10008.1.2.4.50' => 'JPEG Baseline (Process 1)',
+    '1.2.840.10008.1.2.4.51' => 'JPEG Extended (Process 2 & 4)',
+    '1.2.840.10008.1.2.4.52' => 'JPEG Extended (Process 3 & 5)',
+    '1.2.840.10008.1.2.4.53' => 'JPEG Spectral Selection, Non-Hierarchical (Process 6 & 8)',
+    '1.2.840.10008.1.2.4.54' => 'JPEG Spectral Selection, Non-Hierarchical (Process 7 & 9)',
+    '1.2.840.10008.1.2.4.55' => 'JPEG Full Progression, Non-Hierarchical (Process 10 & 12)',
+    '1.2.840.10008.1.2.4.56' => 'JPEG Full Progression, Non-Hierarchical (Process 11 & 13)',
+    '1.2.840.10008.1.2.4.57' => 'JPEG Lossless, Non-Hierarchical (Process 14)',
+    '1.2.840.10008.1.2.4.58' => 'JPEG Lossless, Non-Hierarchical (Process 15) ',
+    '1.2.840.10008.1.2.4.59' => 'JPEG Extended, Hierarchical (Process 16 & 18) ',
+    '1.2.840.10008.1.2.4.60' => 'JPEG Extended, Hierarchical (Process 17 & 19) ',
+    '1.2.840.10008.1.2.4.61' => 'JPEG Spectral Selection, Hierarchical (Process 20 & 22)',
+    '1.2.840.10008.1.2.4.62' => 'JPEG Spectral Selection, Hierarchical (Process 21 & 23)',
+    '1.2.840.10008.1.2.4.63' => 'JPEG Full Progression, Hierarchical (Process 24 & 26)',
+    '1.2.840.10008.1.2.4.64' => 'JPEG Full Progression, Hierarchical (Process 25 & 27)',
+    '1.2.840.10008.1.2.4.65' => 'JPEG Lossless, Hierarchical (Process 28) ',
+    '1.2.840.10008.1.2.4.66' => 'JPEG Lossless, Hierarchical (Process 29) ',
+    '1.2.840.10008.1.2.4.70' => 'JPEG Lossless, Non-Hierarchical, First-Order Prediction (Process 14-1)',
+    '1.2.840.10008.1.2.4.80' => 'JPEG-LS Lossless Image Compression',
+    '1.2.840.10008.1.2.4.81' => 'JPEG-LS Lossy (Near-Lossless) Image Compression',
+    '1.2.840.10008.1.2.4.90' => 'JPEG 2000 Image Compression (Lossless Only)',
+    '1.2.840.10008.1.2.4.91' => 'JPEG 2000 Image Compression',
+    '1.2.840.10008.1.2.4.100' => 'MPEG2 Main Profile @ Main Level',
+    '1.2.840.10008.1.2.5' => 'RLE Lossless',
+    '1.2.840.10008.1.3.10' => 'Media Storage Directory Storage',
+    '1.2.840.10008.1.4.1.1' => 'Talairach Brain Atlas Frame of Reference',
+    '1.2.840.10008.1.4.1.2' => 'SPM2 T1 Frame of Reference',
+    '1.2.840.10008.1.4.1.3' => 'SPM2 T2 Frame of Reference',
+    '1.2.840.10008.1.4.1.4' => 'SPM2 PD Frame of Reference',
+    '1.2.840.10008.1.4.1.5' => 'SPM2 EPI Frame of Reference',
+    '1.2.840.10008.1.4.1.6' => 'SPM2 FIL T1 Frame of Reference',
+    '1.2.840.10008.1.4.1.7' => 'SPM2 PET Frame of Reference',
+    '1.2.840.10008.1.4.1.8' => 'SPM2 TRANSM Frame of Reference',
+    '1.2.840.10008.1.4.1.9' => 'SPM2 SPECT Frame of Reference',
+    '1.2.840.10008.1.4.1.10' => 'SPM2 GRAY Frame of Reference',
+    '1.2.840.10008.1.4.1.11' => 'SPM2 WHITE Frame of Reference',
+    '1.2.840.10008.1.4.1.12' => 'SPM2 CSF Frame of Reference',
+    '1.2.840.10008.1.4.1.13' => 'SPM2 BRAINMASK Frame of Reference',
+    '1.2.840.10008.1.4.1.14' => 'SPM2 AVG305T1 Frame of Reference',
+    '1.2.840.10008.1.4.1.15' => 'SPM2 AVG152T1 Frame of Reference',
+    '1.2.840.10008.1.4.1.16' => 'SPM2 AVG152T2 Frame of Reference',
+    '1.2.840.10008.1.4.1.17' => 'SPM2 AVG152PD Frame of Reference',
+    '1.2.840.10008.1.4.1.18' => 'SPM2 SINGLESUBJT1 Frame of Reference',
+    '1.2.840.10008.1.4.2.1' => 'ICBM 452 T1 Frame of Reference',
+    '1.2.840.10008.1.4.2.2' => 'ICBM Single Subject MRI Frame of Reference',
+    '1.2.840.10008.1.9' => 'Basic Study Content Notification SOP Class',
+    '1.2.840.10008.1.20.1' => 'Storage Commitment Push Model SOP Class',
+    '1.2.840.10008.1.20.1.1' => 'Storage Commitment Push Model SOP Instance',
+    '1.2.840.10008.1.20.2' => 'Storage Commitment Pull Model SOP Class ',
+    '1.2.840.10008.1.20.2.1' => 'Storage Commitment Pull Model SOP Instance ',
+    '1.2.840.10008.1.40' => 'Procedural Event Logging SOP Class',
+    '1.2.840.10008.1.40.1' => 'Procedural Event Logging SOP Instance',
+    '1.2.840.10008.2.16.4' => 'DICOM Controlled Terminology Coding Scheme PS 3.16',
+    '1.2.840.10008.3.1.1.1' => 'DICOM Application Context Name',
+    '1.2.840.10008.3.1.2.1.1' => 'Detached Patient Management SOP Class',
+    '1.2.840.10008.3.1.2.1.4' => 'Detached Patient Management Meta SOP Class',
+    '1.2.840.10008.3.1.2.2.1' => 'Detached Visit Management SOP Class',
+    '1.2.840.10008.3.1.2.3.1' => 'Detached Study Management SOP Class',
+    '1.2.840.10008.3.1.2.3.2' => 'Study Component Management SOP Class',
+    '1.2.840.10008.3.1.2.3.3' => 'Modality Performed Procedure Step SOP Class',
+    '1.2.840.10008.3.1.2.3.4' => 'Modality Performed Procedure Step Retrieve SOP Class',
+    '1.2.840.10008.3.1.2.3.5' => 'Modality Performed Procedure Step Notification SOP Class',
+    '1.2.840.10008.3.1.2.5.1' => 'Detached Results Management SOP Class',
+    '1.2.840.10008.3.1.2.5.4' => 'Detached Results Management Meta SOP Class',
+    '1.2.840.10008.3.1.2.5.5' => 'Detached Study Management Meta SOP Class',
+    '1.2.840.10008.3.1.2.6.1' => 'Detached Interpretation Management SOP Class',
+    '1.2.840.10008.4.2' => 'Storage Service Class Service Class PS 3.4',
+    '1.2.840.10008.5.1.1.1' => 'Basic Film Session SOP Class',
+    '1.2.840.10008.5.1.1.2' => 'Basic Film Box SOP Class',
+    '1.2.840.10008.5.1.1.4' => 'Basic Grayscale Image Box SOP Class',
+    '1.2.840.10008.5.1.1.4.1' => 'Basic Color Image Box SOP Class',
+    '1.2.840.10008.5.1.1.4.2' => 'Referenced Image Box SOP Class',
+    '1.2.840.10008.5.1.1.9' => 'Basic Grayscale Print ManagementMeta SOP Class',
+    '1.2.840.10008.5.1.1.9.1' => 'Referenced Grayscale Print Management Meta SOP Class',
+    '1.2.840.10008.5.1.1.14' => 'Print Job SOP Class',
+    '1.2.840.10008.5.1.1.15' => 'Basic Annotation Box SOP Class',
+    '1.2.840.10008.5.1.1.16' => 'Printer SOP Class',
+    '1.2.840.10008.5.1.1.16.376' => 'Printer Configuration Retrieval SOP Class',
+    '1.2.840.10008.5.1.1.17' => 'Printer SOP Instance',
+    '1.2.840.10008.5.1.1.17.376' => 'Printer Configuration RetrievalSOP Instance',
+    '1.2.840.10008.5.1.1.18' => 'Basic Color Print Management Meta SOP Class',
+    '1.2.840.10008.5.1.1.18.1' => 'Referenced Color Print Management Meta SOP Class',
+    '1.2.840.10008.5.1.1.22' => 'VOI LUT Box SOP Class',
+    '1.2.840.10008.5.1.1.23' => 'Presentation LUT SOP Class',
+    '1.2.840.10008.5.1.1.24' => 'Image Overlay Box SOP Class',
+    '1.2.840.10008.5.1.1.24.1' => 'Basic Print Image Overlay Box SOP Class',
+    '1.2.840.10008.5.1.1.25' => 'Print Queue SOP Instance',
+    '1.2.840.10008.5.1.1.26' => 'Print Queue Management SOP Class',
+    '1.2.840.10008.5.1.1.27' => 'Stored Print Storage SOP Class',
+    '1.2.840.10008.5.1.1.29' => 'Hardcopy Grayscale Image',
+    '1.2.840.10008.5.1.1.30' => 'Hardcopy Color Image Storage SOP Class',
+    '1.2.840.10008.5.1.1.31' => 'Pull Print Request SOP Class',
+    '1.2.840.10008.5.1.1.32' => 'Pull Stored Print Management Meta SOP Class',
+    '1.2.840.10008.5.1.1.33' => 'Media Creation Management SOP Class',
+    '1.2.840.10008.5.1.4.1.1.1' => 'Computed Radiography Image Storage',
+    '1.2.840.10008.5.1.4.1.1.1.1' => 'Digital X-Ray Image Storage Ð For Presentation',
+    '1.2.840.10008.5.1.4.1.1.1.1.1' => 'Digital X-Ray Image Storage Ð For Processing',
+    '1.2.840.10008.5.1.4.1.1.1.2' => 'Digital Mammography X-Ray Image Storage Ð For Presentation',
+    '1.2.840.10008.5.1.4.1.1.1.2.1' => 'Digital Mammography X-Ray Image Storage Ð For Processing',
+    '1.2.840.10008.5.1.4.1.1.1.3' => 'Digital Intra-oral X-Ray Image Storage Ð For Presentation',
+    '1.2.840.10008.5.1.4.1.1.1.3.1' => 'Digital Intra-oral X-Ray Image Storage Ð For Processing',
+    '1.2.840.10008.5.1.4.1.1.2' => 'CT Image Storage',
+    '1.2.840.10008.5.1.4.1.1.2.1' => 'Enhanced CT Image Storage',
+    '1.2.840.10008.5.1.4.1.1.3' => 'Ultrasound Multi-frame Image Storage ',
+    '1.2.840.10008.5.1.4.1.1.3.1' => 'Ultrasound Multi-frame Image Storage',
+    '1.2.840.10008.5.1.4.1.1.4' => 'MR Image Storage',
+    '1.2.840.10008.5.1.4.1.1.4.1' => 'Enhanced MR Image Storage',
+    '1.2.840.10008.5.1.4.1.1.4.2' => 'MR Spectroscopy Storage',
+    '1.2.840.10008.5.1.4.1.1.5' => 'Nuclear Medicine Image Storage',
+    '1.2.840.10008.5.1.4.1.1.6' => 'Ultrasound Image Storage',
+    '1.2.840.10008.5.1.4.1.1.6.1' => 'Ultrasound Image Storage',
+    '1.2.840.10008.5.1.4.1.1.7' => 'Secondary Capture Image Storage',
+    '1.2.840.10008.5.1.4.1.1.7.1' => 'Multi-frame Single Bit Secondary',
+    '1.2.840.10008.5.1.4.1.1.7.2' => 'Multi-frame Grayscale Byte Secondary Capture Image Storage',
+    '1.2.840.10008.5.1.4.1.1.7.3' => 'Multi-frame Grayscale Word Secondary Capture Image Storage',
+    '1.2.840.10008.5.1.4.1.1.7.4' => 'Multi-frame True Color Secondary Capture Image Storage',
+    '1.2.840.10008.5.1.4.1.1.8' => 'Standalone Overlay Storage',
+    '1.2.840.10008.5.1.4.1.1.9' => 'Standalone Curve Storage',
+    '1.2.840.10008.5.1.4.1.1.9.1.1' => '12-lead ECG Waveform Storage',
+    '1.2.840.10008.5.1.4.1.1.9.1.2' => 'General ECG Waveform Storage',
+    '1.2.840.10008.5.1.4.1.1.9.1.3' => 'Ambulatory ECG Waveform Storage',
+    '1.2.840.10008.5.1.4.1.1.9.2.1' => 'Hemodynamic Waveform Storage',
+    '1.2.840.10008.5.1.4.1.1.9.3.1' => 'Cardiac Electrophysiology Waveform Storage',
+    '1.2.840.10008.5.1.4.1.1.9.4.1' => 'Basic Voice Audio Waveform Storage',
+    '1.2.840.10008.5.1.4.1.1.10' => 'Standalone Modality LUT Storage',
+    '1.2.840.10008.5.1.4.1.1.11' => 'Standalone VOI LUT Storage',
+    '1.2.840.10008.5.1.4.1.1.11.1' => 'Grayscale Softcopy Presentation State Storage SOP Class',
+    '1.2.840.10008.5.1.4.1.1.12.1' => 'X-Ray Angiographic Image Storage',
+    '1.2.840.10008.5.1.4.1.1.12.2' => 'X-Ray Radiofluoroscopic Image Storage',
+    '1.2.840.10008.5.1.4.1.1.12.3' => 'X-Ray Angiographic Bi-Plane Image Storage ',
+    '1.2.840.10008.5.1.4.1.1.20' => 'Nuclear Medicine Image Storage',
+    '1.2.840.10008.5.1.4.1.1.66' => 'Raw Data Storage',
+    '1.2.840.10008.5.1.4.1.1.66.1' => 'Spatial Registration Storage',
+    '1.2.840.10008.5.1.4.1.1.66.2' => 'Spatial Fiducials Storage',
+    '1.2.840.10008.5.1.4.1.1.77.1' => 'VL Image Storage ',
+    '1.2.840.10008.5.1.4.1.1.77.2' => 'VL Multi-frame Image Storage',
+    '1.2.840.10008.5.1.4.1.1.77.1.1' => 'VL Endoscopic Image Storage',
+    '1.2.840.10008.5.1.4.1.1.77.1.1.1' => 'Video Endoscopic Image Storage',
+    '1.2.840.10008.5.1.4.1.1.77.1.2' => 'VL Microscopic Image Storage',
+    '1.2.840.10008.5.1.4.1.1.77.1.2.1' => 'Video Microscopic Image Storage',
+    '1.2.840.10008.5.1.4.1.1.77.1.3' => 'VL Slide-Coordinates Microscopic Image Storage',
+    '1.2.840.10008.5.1.4.1.1.77.1.4' => 'VL Photographic Image Storage',
+    '1.2.840.10008.5.1.4.1.1.77.1.4.1' => 'Video Photographic Image Storage',
+    '1.2.840.10008.5.1.4.1.1.77.1.5.1' => 'Ophthalmic Photography 8 Bit Image Storage',
+    '1.2.840.10008.5.1.4.1.1.77.1.5.2' => 'Ophthalmic Photography 16 Bit Image Storage',
+    '1.2.840.10008.5.1.4.1.1.77.1.5.3' => 'Stereometric Relationship Storage',
+    '1.2.840.10008.5.1.4.1.1.88.11' => 'Basic Text SR',
+    '1.2.840.10008.5.1.4.1.1.88.22' => 'Enhanced SR',
+    '1.2.840.10008.5.1.4.1.1.88.33' => 'Comprehensive SR',
+    '1.2.840.10008.5.1.4.1.1.88.40' => 'Procedure Log Storage',
+    '1.2.840.10008.5.1.4.1.1.88.50' => 'Mammography CAD SR',
+    '1.2.840.10008.5.1.4.1.1.88.59' => 'Key Object Selection Document',
+    '1.2.840.10008.5.1.4.1.1.88.65' => 'Chest CAD SR',
+    '1.2.840.10008.5.1.4.1.1.128' => 'Positron Emission Tomography Image Storage',
+    '1.2.840.10008.5.1.4.1.1.129' => 'Standalone PET Curve Storage',
+    '1.2.840.10008.5.1.4.1.1.481.1' => 'RT Image Storage',
+    '1.2.840.10008.5.1.4.1.1.481.2' => 'RT Dose Storage',
+    '1.2.840.10008.5.1.4.1.1.481.3' => 'RT Structure Set Storage',
+    '1.2.840.10008.5.1.4.1.1.481.4' => 'RT Beams Treatment Record Storage',
+    '1.2.840.10008.5.1.4.1.1.481.5' => 'RT Plan Storage',
+    '1.2.840.10008.5.1.4.1.1.481.6' => 'RT Brachy Treatment Record Storage',
+    '1.2.840.10008.5.1.4.1.1.481.7' => 'RT Treatment Summary Record Storage',
+    '1.2.840.10008.5.1.4.1.2.1.1' => 'Patient Root Query/Retrieve Information Model Ð FIND',
+    '1.2.840.10008.5.1.4.1.2.1.2' => 'Patient Root Query/Retrieve Information Model Ð MOVE',
+    '1.2.840.10008.5.1.4.1.2.1.3' => 'Patient Root Query/Retrieve Information Model Ð GET',
+    '1.2.840.10008.5.1.4.1.2.2.1' => 'Study Root Query/Retrieve Information Model Ð FIND',
+    '1.2.840.10008.5.1.4.1.2.2.2' => 'Study Root Query/Retrieve Information Model Ð MOVE',
+    '1.2.840.10008.5.1.4.1.2.2.3' => 'Study Root Query/Retrieve Information Model Ð GET',
+    '1.2.840.10008.5.1.4.1.2.3.1' => 'Patient/Study Only Query/Retrieve Information Model - FIND',
+    '1.2.840.10008.5.1.4.1.2.3.2' => 'Patient/Study Only Query/Retrieve Information Model - MOVE',
+    '1.2.840.10008.5.1.4.1.2.3.3' => 'Patient/Study Only Query/Retrieve Information Model - GET',
+    '1.2.840.10008.5.1.4.31' => 'Modality Worklist Information Model Ð FIND',
+    '1.2.840.10008.5.1.4.32.1' => 'General Purpose Worklist Information Model Ð FIND',
+    '1.2.840.10008.5.1.4.32.2' => 'General Purpose Scheduled Procedure Step SOP Class',
+    '1.2.840.10008.5.1.4.32.3' => 'General Purpose Performed Procedure Step SOP Class',
+    '1.2.840.10008.5.1.4.32' => 'General Purpose Worklist Management Meta SOP Class',
+    '1.2.840.10008.5.1.4.33' => 'Instance Availability Notification SOP Class',
+    '1.2.840.10008.5.1.4.37.1' => 'General Relevant Patient Information Query',
+    '1.2.840.10008.5.1.4.37.2' => 'Breast Imaging Relevant Patient Information Query',
+    '1.2.840.10008.5.1.4.37.3' => 'Cardiac Relevant Patient Information Query',
+    '1.2.840.10008.15.0.3.1' => 'dicomDeviceName',
+    '1.2.840.10008.15.0.3.2' => 'dicomDescription',
+    '1.2.840.10008.15.0.3.3' => 'dicomManufacturer',
+    '1.2.840.10008.15.0.3.4' => 'dicomManufacturerModelName',
+    '1.2.840.10008.15.0.3.5' => 'dicomSoftwareVersion',
+    '1.2.840.10008.15.0.3.6' => 'dicomVendorData',
+    '1.2.840.10008.15.0.3.7' => 'dicomAETitle',
+    '1.2.840.10008.15.0.3.8' => 'dicomNetworkConnectionReference',
+    '1.2.840.10008.15.0.3.9' => 'dicomApplicationCluster',
+    '1.2.840.10008.15.0.3.10' => 'dicomAssociationInitiator',
+    '1.2.840.10008.15.0.3.11' => 'dicomAssociationAcceptor',
+    '1.2.840.10008.15.0.3.12' => 'dicomHostname',
+    '1.2.840.10008.15.0.3.13' => 'dicomPort',
+    '1.2.840.10008.15.0.3.14' => 'dicomSOPClass',
+    '1.2.840.10008.15.0.3.15' => 'dicomTransferRole',
+    '1.2.840.10008.15.0.3.16' => 'dicomTransferSyntax',
+    '1.2.840.10008.15.0.3.17' => 'dicomPrimaryDeviceType',
+    '1.2.840.10008.15.0.3.18' => 'dicomRelatedDeviceReference',
+    '1.2.840.10008.15.0.3.19' => 'dicomPreferredCalledAETitle',
+    '1.2.840.10008.15.0.3.20' => 'dicomTLSCyphersuite',
+    '1.2.840.10008.15.0.3.21' => 'dicomAuthorizedNodeCertificateReference',
+    '1.2.840.10008.15.0.3.22' => 'dicomThisNodeCertificateReference',
+    '1.2.840.10008.15.0.3.23' => 'dicomInstalled',
+    '1.2.840.10008.15.0.3.24' => 'dicomStationName',
+    '1.2.840.10008.15.0.3.25' => 'dicomDeviceSerialNumber',
+    '1.2.840.10008.15.0.3.26' => 'dicomInstitutionName',
+    '1.2.840.10008.15.0.3.27' => 'dicomInstitutionAddress',
+    '1.2.840.10008.15.0.3.28' => 'dicomInstitutionDepartmentName',
+    '1.2.840.10008.15.0.3.29' => 'dicomIssuerOfPatientID',
+    '1.2.840.10008.15.0.3.30' => 'dicomPreferredCallingAETitle',
+    '1.2.840.10008.15.0.3.31' => 'dicomSupportedCharacterSet',
+    '1.2.840.10008.15.0.4.1' => 'dicomConfigurationRoot',
+    '1.2.840.10008.15.0.4.2' => 'dicomDevicesRoot',
+    '1.2.840.10008.15.0.4.3' => 'dicomUniqueAETitlesRegistryRoot',
+    '1.2.840.10008.15.0.4.4' => 'dicomDevice',
+    '1.2.840.10008.15.0.4.5' => 'dicomNetworkAE',
+    '1.2.840.10008.15.0.4.6' => 'dicomNetworkConnection',
+    '1.2.840.10008.15.0.4.7' => 'dicomUniqueAETitle',
+    '1.2.840.10008.15.0.4.8' => 'dicomTransferCapability',
+);
+
+#------------------------------------------------------------------------------
+# Extract information from a DICOM (DCM) image
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid DICOM file
+sub ProcessDICM($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $unknown = $exifTool->Options('Unknown');
+    my $verbose = $exifTool->Options('Verbose');
+    my ($hdr, $buff, $implicit, $vr, $len);
+#
+# identify the DICOM or ACR-NEMA file
+#
+    $raf->Read($hdr, 12) == 12 or return 0; # save for ACR identification later
+    $raf->Seek(128, 0) or return 0;         # skip to end of DICM header
+    $raf->Read($buff, 4) == 4 or return 0;  # read signature
+    if ($buff eq 'DICM') {
+        # file meta information transfer syntax is explicit little endian
+        SetByteOrder('II');
+        $exifTool->SetFileType('DICOM');
+    } else {
+        # test for a RAW DCM image (ACR-NEMA format, ie. no header)
+        foreach ('II','MM','') {
+            return 0 unless $_; # no luck identifying the syntax
+            SetByteOrder($_);
+            my $g = Get16u(\$hdr, 0);
+            # expect group number to be small and even
+            next if $g < 2 or $g > 8 or $g & 0x01;
+            my $e = Get16u(\$hdr, 2);
+            next if $e > 0x20;          # expect a low element number at start
+            $vr = substr($hdr, 4, 2);   # look for explicit VR
+            if ($vr =~ /^[A-Z]{2}$/) {
+                $implicit = 0;
+                if ($vr32{$vr}) {
+                    next unless Get16u(\$hdr, 6) == 0;  # must be 2 zero bytes
+                    $len = Get32u(\$hdr, 8);
+                } else {
+                    next if $e == 0 and $vr ne 'UL';    # group length must be UL
+                    $len = Get16u(\$hdr, 6);
+                }
+            } else {
+                $implicit = 1;
+                $len = Get32u(\$hdr, 4);
+            }
+            next if $e == 0 and $len != 4;  # group length value must be 4 bytes
+            next if $len > 64;      # first element shouldn't be too long
+            last;   # success!
+        }
+        $raf->Seek(0, 0) or return 0;   # rewind to start of file
+        $exifTool->SetFileType('ACR');
+    }
+#
+# process the meta information
+#
+    my $tagTablePtr = GetTagTable('Image::ExifTool::DICOM::Main');
+    my $pos = $raf->Tell();
+    my $err = 1;
+    my ($transferSyntax, $group2end);
+    for (;;) {
+        $raf->Read($buff, 8) == 8 or $err = 0, last;
+        $pos += 8;
+        my $group = Get16u(\$buff, 0);
+        # implement the transfer syntax at the end of the group 2 data
+        if ($transferSyntax and ($group != 0x0002 or
+            ($group2end and $pos > $group2end)))
+        {
+            # 1.2.840.10008.1.2   = implicit VR little endian
+            # 1.2.840.10008.1.2.2 = explicit VR big endian
+            # 1.2.840.10008.1.2.x = explicit VR little endian
+            # 1.2.840.10008.1.2.1.99 = deflated
+            unless ($transferSyntax =~ /^1\.2\.840\.10008\.1\.2(\.\d+)?(\.\d+)?/) {
+                $exifTool->Warn("Unrecognized transfer syntax $transferSyntax");
+                last;
+            }
+            if (not $1) {
+                $implicit = 1;
+            } elsif ($1 eq '.2') {
+                SetByteOrder('MM');
+                $group = Get16u(\$buff, 0); # must get group again
+            } elsif ($1 eq '.1' and $2 and $2 eq '.99') {
+                # inflate compressed data stream
+                if (eval 'require Compress::Zlib') {
+                    # must use undocumented zlib feature to disable zlib header information
+                    # because DICOM deflated data doesn't have the zlib header (ref 3)
+                    my $wbits = -Compress::Zlib::MAX_WBITS();
+                    my $inflate = Compress::Zlib::inflateInit(-WindowBits => $wbits);
+                    if ($inflate) {
+                        $raf->Seek(-8, 1) or last;
+                        my $data = '';
+                        while ($raf->Read($buff, 65536)) {
+                            my ($buf, $stat) = $inflate->inflate($buff);
+                            if ($stat == Compress::Zlib::Z_OK() or
+                                $stat == Compress::Zlib::Z_STREAM_END())
+                            {
+                                $data .= $buf;
+                                last if $stat == Compress::Zlib::Z_STREAM_END();
+                            } else {
+                                $exifTool->Warn('Error inflating compressed data stream');
+                                return 1;
+                            }
+                        }
+                        last if length $data < 8;
+                        # create new RAF object from inflated data stream
+                        $raf = new File::RandomAccess(\$data);
+                        # re-read start of stream (now decompressed)
+                        $raf->Read($buff, 8) == 8 or last;
+                        $group = Get16u(\$buff, 0);
+                    } else {
+                        $exifTool->Warn('Error initializing inflation');
+                        return 1;
+                    }
+                } else {
+                    $exifTool->Warn('Install Compress::Zlib to decode compressed data stream');
+                    return 1;
+                }
+            }
+            undef $transferSyntax;
+        }
+        my $element = Get16u(\$buff,2);
+        my $tag = sprintf('%.4X,%.4X', $group, $element);
+
+        if ($implicit or $implicitVR{$tag}) {
+            # treat everything as string if implicit VR because it
+            # isn't worth it to generate the necessary VR lookup tables
+            # for the thousands of defined data elements
+            $vr = '';       # no VR (treat everything as string)
+            $len = Get32u(\$buff, 4);
+        } else {
+            $vr = substr($buff,4,2);
+            last unless $vr =~ /^[A-Z]{2}$/;
+            if ($vr32{$vr}) {
+                $raf->Read($buff, 4) == 4 or last;
+                $pos += 4;
+                $len = Get32u(\$buff, 0);
+                $len = 0 if $vr eq 'SQ';    # just recurse into sequences
+            } else {
+                $len = Get16u(\$buff, 6);
+            }
+        }
+        if ($len == 0xffffffff) {
+            $len = 0;   # don't read value if undefined length
+            if ($verbose) {
+                # start list of items in verbose output
+                $exifTool->VPrint(0, "$exifTool->{INDENT}+ [List of items]\n");
+                $exifTool->{INDENT} .= '| ';
+            }
+        }
+        # read the element value
+        if ($len) {
+            $raf->Read($buff, $len) == $len or last;
+            $pos += $len;
+        } else {
+            $buff = '';
+        }
+
+        # handle tags not found in the table
+        my $tagInfo = $$tagTablePtr{$tag};
+        unless ($tagInfo) {
+            # look for a tag like '60xx,1203' or '0020,31xx' in table
+            my $xx;
+            if ((($xx = $tag) =~ s/^(..)../$1xx/ and $$tagTablePtr{$xx}) or
+                (($xx = $tag) =~ s/(..)$/xx/ and $$tagTablePtr{$xx}))
+            {
+                $tag = $xx;
+                $tagInfo = $$tagTablePtr{$xx};
+            } elsif ($unknown) {
+                # create tag info hash for unknown elements
+                if ($element == 0) {    # element zero is group length
+                    $tagInfo = {
+                        Name => sprintf("Group%.4X_Length", $group),
+                        Description => sprintf("Group %.4X Length", $group),
+                    };
+                } else {
+                    $tagInfo = {
+                        Name => sprintf("DICOM_%.4X_%.4X", $group, $element),
+                        Description => sprintf("DICOM %.4X,%.4X", $group, $element),
+                    };
+                }
+                $$tagInfo{Unknown} = 1;
+                Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            }
+        }
+        # get VR from our tag information if implicit
+        $vr = $$tagInfo{VR} || '  ' if $tagInfo and not $vr;
+
+        if ($element == 0) {
+            $vr = 'UL'; # group length element is always unsigned long
+        }
+        my $val;
+        my $format = $dicomFormat{$vr};
+        if ($len > 1024) {
+            # treat large data elements as binary data
+            my $binData;
+            if ($exifTool->Options('Binary') or ($tagInfo and
+                $exifTool->{REQ_TAG_LOOKUP}->{lc($$tagInfo{Name})}))
+            {
+                $binData = $buff;   # must make a copy
+            } else {
+                $binData = "Binary data $len bytes";
+            }
+            $val = \$binData;
+        } elsif ($format) {
+            $val = ReadValue(\$buff, 0, $format, undef, $len);
+        } else {
+            $val = $buff;
+            $format = 'string';
+            if ($vr eq 'DA') {
+                # format date values
+                $val =~ s/^(\d{4})(\d{2})(\d{2})/$1:$2:$3/;
+            } elsif ($vr eq 'TM') {
+                # format time values
+                $val =~ s/^(\d{2})(\d{2})(\d{2}.*)/$1:$2:$3/;
+            } elsif ($vr eq 'DT') {
+                # format date/time values
+                $val =~ s/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2}.*)/$1:$2:$3 $4:$5:$6/;
+            } elsif ($vr eq 'AT' and $len == 4) {
+                # convert attribute tag ID to hex format
+                my ($g, $e) = (Get16u(\$buff,0), Get16u(\$buff,2));
+                $val = sprintf('%.4X,%.4X', $g, $e);
+            } elsif ($vr eq 'UI') {
+                # add PrintConv to translate registered UID's
+                $val =~ s/\0.*//; # truncate at null
+                $$tagInfo{PrintConv} = \%uid if $uid{$val} and $tagInfo;
+            }
+        }
+        # save the group 2 end position and transfer syntax
+        if ($group == 0x0002) {
+            $element == 0x0000 and $group2end = $pos + $val;
+            $element == 0x0010 and $transferSyntax = $val;
+        }
+
+        # handle the new tag information
+        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            DataPt => \$buff,
+            DataPos => $pos - $len,
+            Format => $format,
+            Start => 0,
+            Size => $len,
+            Extra => " ($vr)",
+        );
+
+        # stop indenting for list if we reached EndOfItems tag
+        $exifTool->{INDENT} =~ s/..$// if $verbose and $tag eq 'FFFE,E00D';
+    }
+    $err and $exifTool->Warn('Error reading DICOM file (corrupted?)');
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::DICOM - Read DICOM and ACR-NEMA medical images
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to extract meta
+information from DICOM (Digital Imaging and Communications in Medicine) DCM
+and ACR-NEMA (American College of Radiology - National Electrical
+Manufacturer's Association) ACR medical images.
+
+=head1 NOTES
+
+Values of retired elements in implicit VR format files are intepreted as
+strings, hence they may not be displayed properly.  This is because the
+specification no longer lists these VR's, but simply lists 'RET' for these
+elements.  (Doh. Who's idea was that? :P)
+
+Images compressed using the DICOM deflated transfer syntax will be decoded
+if Compress::Zlib is installed.
+
+No translation of special characters sets is done.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://medical.nema.org/dicom/2004.html>
+
+=item L<http://www.sph.sc.edu/comd/rorden/dicom.html>
+
+=item L<http://www.dclunie.com/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/DICOM Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/DNG.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/DNG.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/DNG.pm	(revision 20131)
@@ -0,0 +1,694 @@
+#------------------------------------------------------------------------------
+# File:         DNG.pm
+#
+# Description:  Read DNG-specific information
+#
+# Revisions:    01/09/2006 - P. Harvey Created
+#
+# References:   1) http://www.adobe.com/products/dng/pdfs/dng_spec.pdf
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::DNG;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+use Image::ExifTool::MakerNotes;
+use Image::ExifTool::CanonRaw;
+
+$VERSION = '1.07';
+
+sub ProcessOriginalRaw($$$);
+sub ProcessAdobeData($$$);
+sub ProcessAdobeMakN($$$);
+sub ProcessAdobeCRW($$$);
+sub ProcessAdobeMRW($$$);
+sub ProcessAdobeSR2($$$);
+sub WriteAdobeStuff($$$);
+
+# data in OriginalRawFileData
+%Image::ExifTool::DNG::OriginalRaw = (
+    GROUPS => { 2 => 'Image' },
+    PROCESS_PROC => \&ProcessOriginalRaw,
+    NOTES => q{
+        This table defines tags extracted from the DNG OriginalRawFileData
+        information.
+    },
+    0 => { Name => 'OriginalRawImage',    Binary => 1 },
+    1 => { Name => 'OriginalRawResource', Binary => 1 },
+    2 => 'OriginalRawFileType',
+    3 => 'OriginalRawCreator',
+    4 => { Name => 'OriginalTHMImage',    Binary => 1 },
+    5 => { Name => 'OriginalTHMResource', Binary => 1 },
+    6 => 'OriginalTHMFileType',
+    7 => 'OriginalTHMCreator',
+);
+
+%Image::ExifTool::DNG::AdobeData = ( #PH
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Adobe', 2 => 'Image' },
+    PROCESS_PROC => \&ProcessAdobeData,
+    WRITE_PROC => \&WriteAdobeStuff,
+    NOTES => q{
+        This information is found in the "Adobe" DNGPrivateData.
+
+        The maker notes ('MakN') are processed by ExifTool, but some information may
+        have been lost by the Adobe DNG Converter.  This is because the Adobe DNG
+        Converter (as of version 3.3) doesn't properly handle information referenced
+        from inside the maker notes that lies outside the original maker notes
+        block, and this information is lost when only the maker note block is copied
+        to the DNG image.   While this isn't a big problem for most camera makes, it
+        is serious for some makes like Olympus.
+
+        The CRW data is from DNG-converted CRW images, but it has been restructured
+        to a proprietary Adobe format (which results in a loss of the original
+        hierarchical information structure, and creates extra work for everyone else
+        who wants to use this information).
+    },
+    MakN  => [ ],   # (filled in later)
+   'CRW ' => {
+        Name => 'AdobeCRW',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::CanonRaw::Main',
+            ProcessProc => \&ProcessAdobeCRW,
+            WriteProc => \&WriteAdobeStuff,
+        },
+    },
+   'MRW ' => {
+        Name => 'AdobeMRW',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MinoltaRaw::Main',
+            ProcessProc => \&ProcessAdobeMRW,
+            WriteProc => \&WriteAdobeStuff,
+        },
+    },
+   'SR2 ' => {
+        Name => 'AdobeSR2',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sony::SR2Private',
+            ProcessProc => \&ProcessAdobeSR2,
+        },
+    },
+   'RAF ' => {
+        Name => 'AdobeRAF',
+        Flags => [qw(Binary Unknown)],
+    },
+);
+
+# fill in maker notes
+{
+    my $tagInfo;
+    my $list = $Image::ExifTool::DNG::AdobeData{MakN};
+    foreach $tagInfo (@Image::ExifTool::MakerNotes::Main) {
+        unless (ref $tagInfo eq 'HASH') {
+            push @$list, $tagInfo;
+            next;
+        }
+        my %copy = %$tagInfo;
+        delete $copy{Groups};
+        delete $copy{Table};
+        push @$list, \%copy;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Process DNG OriginalRawFileData information
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+sub ProcessOriginalRaw($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $start = $$dirInfo{DirStart};
+    my $end = $start + $$dirInfo{DirLen};
+    my $pos = $start;
+    my ($index, $err);
+    SetByteOrder('MM'); # pointers are always big-endian in this structure
+    for ($index=0; $index<8; ++$index) {
+        last if $pos + 4 > $end;
+        my $val = Get32u($dataPt, $pos);
+        $val or $pos += 4, next; # ignore zero values
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $index);
+        $tagInfo or $err = "Missing DNG tag $index", last;
+        if ($index & 0x02) {
+            # extract a simple file type (tags 2, 3, 6 and 7)
+            $val = substr($$dataPt, $pos, 4);
+            $pos += 4;
+        } else {
+            # extract a compressed data block (tags 0, 1, 4 and 5)
+            my $n = int(($val + 65535) / 65536);
+            my $hdrLen = 4 * ($n + 2);
+            $pos + $hdrLen > $end and $err = '', last;
+            my $tag = $$tagInfo{Name};
+            # only extract this information if requested (because it takes time)
+            if ($exifTool->{OPTIONS}->{Binary} or
+                $exifTool->{REQ_TAG_LOOKUP}->{lc($tag)})
+            {
+                unless (eval 'require Compress::Zlib') {
+                    $err = 'Install Compress::Zlib to extract compressed images';
+                    last;
+                }
+                my $i;
+                $val = '';
+                my $p2 = $pos + Get32u($dataPt, $pos + 4);
+                for ($i=0; $i<$n; ++$i) {
+                    # inflate this compressed block
+                    my $p1 = $p2;
+                    $p2 = $pos + Get32u($dataPt, $pos + ($i + 2) * 4);
+                    if ($p1 >= $p2 or $p2 > $end) {
+                        $err = 'Bad compressed RAW image';
+                        last;
+                    }
+                    my $buff = substr($$dataPt, $p1, $p2 - $p1);
+                    my ($v2, $stat);
+                    my $inflate = Compress::Zlib::inflateInit();
+                    $inflate and ($v2, $stat) = $inflate->inflate($buff);
+                    if ($inflate and $stat == Compress::Zlib::Z_STREAM_END()) {
+                        $val .= $v2;
+                    } else {
+                        $err = 'Error inflating compressed RAW image';
+                        last;
+                    }
+                }
+                $pos = $p2;
+            } else {
+                $pos + $hdrLen > $end and $err = '', last;
+                my $len = Get32u($dataPt, $pos + $hdrLen - 4);
+                $pos + $len > $end and $err = '', last;
+                $val = substr($$dataPt, $pos + $hdrLen, $len - $hdrLen);
+                $val = "Binary data $len bytes";
+                $pos += $len;   # skip over this block
+            }
+        }
+        $exifTool->FoundTag($tagInfo, $val);
+    }
+    $exifTool->Warn($err || 'Bad OriginalRawFileData') if defined $err;
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process Adobe DNGPrivateData directory
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessAdobeData($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{DataPos};
+    my $pos = $$dirInfo{DirStart};
+    my $end = $$dirInfo{DirLen} + $pos;
+    my $outfile = $$dirInfo{OutFile};
+    my $verbose = $exifTool->Options('Verbose');
+    my $htmlDump = $exifTool->Options('HtmlDump');
+
+    return 0 unless $$dataPt =~ /^Adobe\0/;
+    unless ($outfile) {
+        $exifTool->VerboseDir($dirInfo);
+    }
+    $htmlDump and $exifTool->HtmlDump($dataPos, 6, 'Adobe DNGPrivateData header');
+    SetByteOrder('MM'); # always big endian
+    $pos += 6;
+    while ($pos + 8 <= $end) {
+        my ($tag, $size) = unpack("x${pos}a4N", $$dataPt);
+        $pos += 8;
+        last if $pos + $size > $end;
+        my $tagInfo = $$tagTablePtr{$tag};
+        if ($htmlDump) {
+            my $name = "Adobe$tag";
+            $name =~ tr/ //d;
+            $exifTool->HtmlDump($dataPos + $pos - 8, 8, "$name header", "Data Size: $size bytes");
+            # dump non-EXIF format data
+            unless ($tag =~ /^(MakN|SR2 )$/) {
+                $exifTool->HtmlDump($dataPos + $pos, $size, "$name data");
+            }
+        }
+        $verbose and not $outfile and $exifTool->VerboseInfo($tag,
+            ref $tagInfo eq 'HASH' ? $tagInfo : undef,
+            DataPt => $dataPt,
+            DataPos => $dataPos,
+            Start => $pos,
+            Size => $size,
+        );
+        my $value;
+        while ($tagInfo) {
+            my ($subTable, $subName, $processProc);
+            if (ref $tagInfo eq 'HASH') {
+                unless ($$tagInfo{SubDirectory}) {
+                    if ($outfile) {
+                        # copy value across to outfile
+                        $value = substr($$dataPt, $pos, $size);
+                    } else {
+                        $exifTool->HandleTag($tagTablePtr, $tag, substr($$dataPt, $pos, $size));
+                    }
+                    last;
+                }
+                $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                $subName = $$tagInfo{Name};
+                $processProc = $tagInfo->{SubDirectory}->{ProcessProc};
+            } else {
+                $subTable = $tagTablePtr;
+                $subName = 'AdobeMakN';
+                $processProc = \&ProcessAdobeMakN;
+            }
+            my %dirInfo = (
+                Base     => $$dirInfo{Base},
+                DataPt   => $dataPt,
+                DataPos  => $dataPos,
+                DataLen  => $$dirInfo{DataLen},
+                DirStart => $pos,
+                DirLen   => $size,
+                DirName  => $subName,
+            );
+            if ($outfile) {
+                $dirInfo{Proc} = $processProc;  # WriteAdobeStuff() calls this to do the actual writing
+                $value = $exifTool->WriteDirectory(\%dirInfo, $subTable, \&WriteAdobeStuff);
+                # use old directory if an error occurred
+                defined $value or $value = substr($$dataPt, $pos, $size);
+            } else {
+                # override process proc for MakN
+                $exifTool->ProcessDirectory(\%dirInfo, $subTable, $processProc);
+            }
+            last;
+        }
+        if (defined $value and length $value) {
+            # add "Adobe" header if necessary
+            $$outfile = "Adobe\0" unless $$outfile and length $$outfile;
+            $$outfile .= $tag . pack('N', length $value) . $value;
+            $$outfile .= "\0" if length($value) & 0x01; # pad if necessary
+        }
+        $pos += $size;
+        ++$pos if $size & 0x01; # (darn padding)
+    }
+    $pos == $end or $exifTool->Warn("$pos $end Adobe private data is corrupt");
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process Adobe CRW directory
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+# Notes: data has 4 byte header (2 for byte order and 2 for entry count)
+# - this routine would be as simple as ProcessAdobeMRW() below if Adobe hadn't
+#   pulled the bonehead move of reformatting the CRW information
+sub ProcessAdobeCRW($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $start = $$dirInfo{DirStart};
+    my $end = $start + $$dirInfo{DirLen};
+    my $verbose = $exifTool->Options('Verbose');
+    my $buildMakerNotes = $exifTool->Options('MakerNotes');
+    my $outfile = $$dirInfo{OutFile};
+    my ($newTags, $oldChanged);
+
+    SetByteOrder('MM'); # always big endian
+    return 0 if $$dirInfo{DirLen} < 4;
+    my $byteOrder = substr($$dataPt, $start, 2);
+    return 0 unless $byteOrder =~ /^(II|MM)$/;
+
+    # initialize maker note data if building maker notes
+    $buildMakerNotes and Image::ExifTool::CanonRaw::InitMakerNotes($exifTool);
+
+    my $entries = Get16u($dataPt, $start + 2);
+    my $pos = $start + 4;
+    $exifTool->VerboseDir($dirInfo, $entries) unless $outfile;
+    if ($outfile) {
+        # get hash of new tags
+        $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+        $$outfile = substr($$dataPt, $start, 4);
+        $oldChanged = $exifTool->{CHANGED};
+    }
+    # loop through entries in Adobe CRW information
+    my $index;
+    for ($index=0; $index<$entries; ++$index) {
+        last if $pos + 6 > $end;
+        my $tag = Get16u($dataPt, $pos);
+        my $size = Get32u($dataPt, $pos + 2);
+        $pos += 6;
+        last if $pos + $size > $end;
+        my $value = substr($$dataPt, $pos, $size);
+        my $tagID = $tag & 0x3fff;
+        my $tagType = ($tag >> 8) & 0x38;   # get tag type
+        my $format = $Image::ExifTool::CanonRaw::crwTagFormat{$tagType};
+        my $count;
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$value);
+        if ($tagInfo) {
+            $format = $$tagInfo{Format} if $$tagInfo{Format};
+            $count = $$tagInfo{Count};
+        }
+        # set count to 1 by default for values that were in the directory entry
+        if (not defined $count and $tag & 0x4000 and $format and $format ne 'string') {
+            $count = 1;
+        }
+        # set count from tagInfo count if necessary
+        if ($format and not $count) {
+            # set count according to format and size
+            my $fnum = $Image::ExifTool::Exif::formatNumber{$format};
+            my $fsiz = $Image::ExifTool::Exif::formatSize[$fnum];
+            $count = int($size / $fsiz);
+        }
+        $format or $format = 'undef';
+        SetByteOrder($byteOrder);
+        my $val = ReadValue(\$value, 0, $format, $count, $size);
+        if ($outfile) {
+            if ($tagInfo) {
+                my $subdir = $$tagInfo{SubDirectory};
+                if ($subdir and $$subdir{TagTable}) {
+                    my $name = $$tagInfo{Name};
+                    my $newTagTable = Image::ExifTool::GetTagTable($$subdir{TagTable});
+                    return 0 unless $newTagTable;
+                    my $subdirStart = 0;
+                    #### eval Start ()
+                    $subdirStart = eval $$subdir{Start} if $$subdir{Start};
+                    my $dirData = \$value;
+                    my %subdirInfo = (
+                        Name     => $name,
+                        DataPt   => $dirData,
+                        DataLen  => $size,
+                        DirStart => $subdirStart,
+                        DirLen   => $size - $subdirStart,
+                        Parent   => $$dirInfo{DirName},
+                    );
+                    #### eval Validate ($dirData, $subdirStart, $size)
+                    if (defined $$subdir{Validate} and not eval $$subdir{Validate}) {
+                        $exifTool->Warn("Invalid $name data");
+                    } else {
+                        $subdir = $exifTool->WriteDirectory(\%subdirInfo, $newTagTable);
+                        if (defined $subdir and length $subdir) {
+                            if ($subdirStart) {
+                                # add header before data directory
+                                $value = substr($value, 0, $subdirStart) . $subdir;
+                            } else {
+                                $value = $subdir;
+                            }
+                        }
+                    }
+                } elsif ($$newTags{$tagID}) {
+                    my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+                    if (Image::ExifTool::IsOverwriting($newValueHash, $val)) {
+                        my $newVal = Image::ExifTool::GetNewValues($newValueHash);
+                        my $verboseVal;
+                        $verboseVal = $newVal if $verbose > 1;
+                        # convert to specified format if necessary
+                        if (defined $newVal and $format) {
+                            $newVal = WriteValue($newVal, $format, $count);
+                        }
+                        if (defined $newVal) {
+                            if ($verbose > 1) {
+                                my $oldStr = $exifTool->Printable($value);
+                                my $newStr = $exifTool->Printable($verboseVal);
+                                my $out = $exifTool->Options('TextOut');
+                                print $out "    - CanonRaw:$$tagInfo{Name} = '$oldStr'\n";
+                                print $out "    + CanonRaw:$$tagInfo{Name} = '$newStr'\n";
+                            }
+                            $value = $newVal;
+                            ++$exifTool->{CHANGED};
+                        }
+                    }
+                }
+            }
+            # write out new value (always big-endian)
+            SetByteOrder('MM');
+            # (verified that there is no padding here)
+            $$outfile .= Set16u($tag) . Set32u(length($value)) . $value;
+        } else {
+            $exifTool->HandleTag($tagTablePtr, $tagID, $val,
+                Index   => $index,
+                DataPt  => $dataPt,
+                DataPos => $$dirInfo{DataPos},
+                Start   => $pos,
+                Size    => $size,
+                TagInfo => $tagInfo,
+            );
+            if ($buildMakerNotes) {
+                # build maker notes information if requested
+                Image::ExifTool::CanonRaw::BuildMakerNotes($exifTool, $tagID, $tagInfo,
+                                                           \$value, $format, $count);
+            }
+        }
+        # (we lost the directory structure, but the second tag 0x0805
+        # should be in the ImageDescription directory)
+        $exifTool->{DIR_NAME} = 'ImageDescription' if $tagID == 0x0805;
+        SetByteOrder('MM');
+        $pos += $size;
+    }
+    if ($outfile and (not defined $$outfile or $index != $entries or
+        $exifTool->{CHANGED} ==  $oldChanged))
+    {
+        $exifTool->{CHANGED} = $oldChanged; # nothing changed
+        undef $$outfile;    # rewrite old directory
+    }
+    if ($index != $entries) {
+        $exifTool->Warn('Truncated CRW notes');
+    } elsif ($pos < $end) {
+        $exifTool->Warn($end-$pos . ' extra bytes at end of CRW notes');
+    }
+    # finish building maker notes if necessary
+    if ($buildMakerNotes) {
+        SetByteOrder($byteOrder);
+        Image::ExifTool::CanonRaw::SaveMakerNotes($exifTool);
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process Adobe MRW directory
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+# Notes: data has 4 byte header (2 for byte order and 2 for entry count)
+sub ProcessAdobeMRW($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirLen = $$dirInfo{DirLen};
+    my $dirStart = $$dirInfo{DirStart};
+    my $outfile = $$dirInfo{OutFile};
+    # construct fake MRW file
+    my $buff = "\0MRM" . pack('N', $dirLen - 4);
+    # ignore leading byte order and directory count words
+    $buff .= substr($$dataPt, $dirStart + 4, $dirLen - 4);
+    my $raf = new File::RandomAccess(\$buff);
+    my %dirInfo = ( RAF => $raf, OutFile => $outfile );
+    my $rtnVal = Image::ExifTool::MinoltaRaw::ProcessMRW($exifTool, \%dirInfo);
+    if ($outfile and defined $$outfile and length $$outfile) {
+        # remove MRW header and add Adobe header
+        $$outfile = substr($$dataPt, $dirStart, 4) . substr($$outfile, 8);
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Process Adobe SR2 directory
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+# Notes: data has 6 byte header (2 for byte order and 4 for original offset)
+sub ProcessAdobeSR2($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $start = $$dirInfo{DirStart};
+    my $len = $$dirInfo{DirLen};
+    return 0 if $$dirInfo{OutFile}; # (can't write this yet)
+
+    return 0 if $len < 6;
+    SetByteOrder('MM');
+    my $originalPos = Get32u($dataPt, $start + 2);
+    return 0 unless SetByteOrder(substr($$dataPt, $start, 2));
+
+    $exifTool->VerboseDir($dirInfo);
+    my $dataPos = $$dirInfo{DataPos};
+    my $dirStart = $start + 6;  # pointer to maker note directory
+    my $dirLen = $len - 6;
+
+    # initialize subdirectory information
+    my $fix = $dataPos + $dirStart - $originalPos;
+    my %subdirInfo = (
+        DirName   => 'AdobeSR2',
+        Base      => $$dirInfo{Base} + $fix,
+        DataPt    => $dataPt,
+        DataPos   => $dataPos - $fix,
+        DataLen   => $$dirInfo{DataLen},
+        DirStart  => $dirStart,
+        DirLen    => $dirLen,
+        Parent    => $$dirInfo{DirName},
+    );
+    if ($exifTool->Options('HtmlDump')) {
+        $exifTool->HtmlDump($dataPos + $start, 6, 'Adobe SR2 data');
+    }
+    # parse the SR2 directory
+    $exifTool->ProcessDirectory(\%subdirInfo, $tagTablePtr);
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process Adobe MakerNotes directory
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+# Notes: data has 6 byte header (2 for byte order and 4 for original offset)
+sub ProcessAdobeMakN($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $start = $$dirInfo{DirStart};
+    my $len = $$dirInfo{DirLen};
+    my $outfile = $$dirInfo{OutFile};
+
+    return 0 if $len < 6;
+    SetByteOrder('MM');
+    my $originalPos = Get32u($dataPt, $start + 2);
+    return 0 unless SetByteOrder(substr($$dataPt, $start, 2));
+
+    $exifTool->VerboseDir($dirInfo) unless $outfile;
+    my $dataPos = $$dirInfo{DataPos};
+    my $dirStart = $start + 6;  # pointer to maker note directory
+    my $dirLen = $len - 6;
+
+    my $hdr = substr($$dataPt, $dirStart, $dirLen < 48 ? $dirLen : 48);
+    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, 'MakN', \$hdr);
+    return 0 unless $tagInfo and $$tagInfo{SubDirectory};
+    my $subdir = $$tagInfo{SubDirectory};
+    my $subTable = GetTagTable($$subdir{TagTable});
+    # initialize subdirectory information
+    my %subdirInfo = (
+        DirName   => 'MakerNotes',
+        Name      => $$tagInfo{Name},   # needed for maker notes verbose dump
+        Base      => $$dirInfo{Base},
+        DataPt    => $dataPt,
+        DataPos   => $dataPos,
+        DataLen   => $$dirInfo{DataLen},
+        DirStart  => $dirStart,
+        DirLen    => $dirLen,
+        TagInfo   => $tagInfo,
+        FixBase   => $$subdir{FixBase},
+        EntryBased=> $$subdir{EntryBased},
+        Parent    => $$dirInfo{DirName},
+    );
+    # look for start of maker notes IFD
+    my $loc = Image::ExifTool::MakerNotes::LocateIFD($exifTool,\%subdirInfo);
+    unless (defined $loc) {
+        $exifTool->Warn('Maker notes could not be parsed');
+        return 0;
+    }
+    if ($exifTool->Options('HtmlDump')) {
+        $exifTool->HtmlDump($dataPos + $start, 6, 'Adobe MakN data');
+        $exifTool->HtmlDump($dataPos + $dirStart, $loc, "$$tagInfo{Name} header") if $loc;
+    }
+
+    my $fix = 0;
+    unless ($$subdir{Base}) {
+        # adjust base offset for current maker note position
+        $fix = $dataPos + $dirStart - $originalPos;
+        $subdirInfo{Base} += $fix;
+        $subdirInfo{DataPos} -= $fix;
+    }
+    if ($outfile) {
+        # rewrite the maker notes directory
+        my $fixup = $subdirInfo{Fixup} = new Image::ExifTool::Fixup;
+        my $oldChanged = $$exifTool{CHANGED};
+        my $buff = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+        # nothing to do if error writing directory or nothing changed
+        unless (defined $buff and $exifTool->{CHANGED} != $oldChanged) {
+            $exifTool->{CHANGED} = $oldChanged;
+            return 1;
+        }
+        # deleting maker notes if directory is empty
+        unless (length $buff) {
+            $$outfile = '';
+            return 1;
+        }
+        # apply a one-time fixup to offsets
+        if ($subdirInfo{Relative}) {
+            # shift all offsets to be relative to new base
+            my $baseShift = $dataPos + $dirStart + $$dirInfo{Base} - $subdirInfo{Base};
+            $fixup->{Shift} += $baseShift;
+        } else {
+            # shift offsets to position of original maker notes
+            $fixup->{Shift} += $originalPos;
+        }
+        $fixup->{Shift} += $loc;    # adjust for makernotes header
+        $fixup->ApplyFixup(\$buff); # fix up pointer offsets
+        # get copy of original Adobe header (6) and makernotes header ($loc)
+        my $header = substr($$dataPt, $start, 6 + $loc);
+        # add Adobe and makernotes headers to new directory
+        $$outfile = $header . $buff;
+    } else {
+        # parse the maker notes directory
+        $exifTool->ProcessDirectory(\%subdirInfo, $subTable, $$subdir{ProcessProc});
+        # extract maker notes as a block if specified
+        if ($exifTool->Options('MakerNotes') or
+            $exifTool->{REQ_TAG_LOOKUP}->{lc($$tagInfo{Name})})
+        {
+            my $val;
+            if ($$tagInfo{MakerNotes}) {
+                $subdirInfo{Base}     = $$dirInfo{Base} + $fix;
+                $subdirInfo{DataPos}  = $dataPos - $fix;
+                $subdirInfo{DirStart} = $dirStart;
+                $subdirInfo{DirLen}   = $dirLen;
+                # rebuild the maker notes to identify all offsets that require fixing up
+                $val = Image::ExifTool::Exif::RebuildMakerNotes($exifTool, $subTable, \%subdirInfo);
+                defined $val or $exifTool->Warn('Error rebuilding maker notes (may be corrupt)');
+            } else {
+                # extract this directory as a block if specified
+                return 1 unless $$tagInfo{Writable};
+            }
+            $val = substr($$dataPt, 20) unless defined $val;
+            $exifTool->FoundTag($tagInfo, $val);
+        }
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Write Adobe information (calls appropriate ProcessProc to do the actual work)
+# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref
+# Returns: new data block (may be empty if directory is deleted) or undef on error
+sub WriteAdobeStuff($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    $exifTool or return 1;    # allow dummy access
+    my $proc = $$dirInfo{Proc} || \&ProcessAdobeData;
+    my $buff;
+    $$dirInfo{OutFile} = \$buff;
+    &$proc($exifTool, $dirInfo, $tagTablePtr) or undef $buff;
+    return $buff;
+}
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::DNG.pm - Read DNG-specific information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to process
+information in DNG (Digital Negative) images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.adobe.com/products/dng/pdfs/dng_spec.pdf>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/DNG Tags>,
+L<Image::ExifTool::TagNames/EXIF Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Exif.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Exif.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Exif.pm	(revision 20131)
@@ -0,0 +1,2952 @@
+#------------------------------------------------------------------------------
+# File:         Exif.pm
+#
+# Description:  Read EXIF meta information
+#
+# Revisions:    11/25/2003 - P. Harvey Created
+#               02/06/2004 - P. Harvey Moved processing functions from ExifTool
+#               03/19/2004 - P. Harvey Check PreviewImage for validity
+#               11/11/2004 - P. Harvey Split off maker notes into MakerNotes.pm
+#               12/13/2004 - P. Harvey Added AUTOLOAD to load write routines
+#
+# References:   0) http://www.exif.org/Exif2-2.PDF
+#               1) http://partners.adobe.com/asn/developer/pdfs/tn/TIFF6.pdf
+#               2) http://www.adobe.com/products/dng/pdfs/dng_spec.pdf
+#               3) http://www.awaresystems.be/imaging/tiff/tifftags.html
+#               4) http://www.remotesensing.org/libtiff/TIFFTechNote2.html
+#               5) http://www.asmail.be/msg0054681802.html
+#               6) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
+#               7) http://www.fine-view.com/jp/lab/doc/ps6ffspecsv2.pdf
+#               8) http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html
+#               9) http://hul.harvard.edu/jhove/tiff-tags.html
+#              10) http://partners.adobe.com/public/developer/en/tiff/TIFFPM6.pdf
+#              11) Robert Mucke private communication
+#              12) http://www.broomscloset.com/closet/photo/exif/TAG2000-22_DIS12234-2.PDF
+#              13) http://www.microsoft.com/whdc/xps/wmphoto.mspx
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Exif;
+
+use strict;
+use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber
+            %lightSource %compression %photometricInterpretation %orientation);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::MakerNotes;
+
+$VERSION = '2.42';
+
+sub ProcessExif($$$);
+sub WriteExif($$$);
+sub CheckExif($$$);
+sub RebuildMakerNotes($$$);
+sub EncodeExifText($$);
+sub ValidateIFD($;$);
+
+# byte sizes for the various EXIF format types below
+@formatSize = (undef,1,1,2,4,8,1,1,2,4,8,4,8,4,undef,undef,8,8,8);
+
+@formatName = (
+    undef, 'int8u', 'string', 'int16u',
+    'int32u', 'rational64u', 'int8s', 'undef',
+    'int16s', 'int32s', 'rational64s', 'float',
+    'double', 'ifd', undef, undef, # (14 is unicode, 15 is complex? http://remotesensing.org/libtiff/bigtiffdesign.html)
+    'int64u', 'int64s', 'ifd8', # (new BigTIFF formats)
+);
+
+# hash to look up EXIF format numbers by name
+# (format types are all lower case)
+%formatNumber = (
+    'int8u'         => 1,   # BYTE
+    'string'        => 2,   # ASCII
+    'int16u'        => 3,   # SHORT
+    'int32u'        => 4,   # LONG
+    'rational64u'   => 5,   # RATIONAL
+    'int8s'         => 6,   # SBYTE
+    'undef'         => 7,   # UNDEFINED
+    'binary'        => 7,   # (treat binary data as undef)
+    'int16s'        => 8,   # SSHORT
+    'int32s'        => 9,   # SLONG
+    'rational64s'   => 10,  # SRATIONAL
+    'float'         => 11,  # FLOAT
+    'double'        => 12,  # DOUBLE
+    'ifd'           => 13,  # IFD (with int32u format)
+    'int64u'        => 16,  # LONG8 [BigTIFF]
+    'int64s'        => 17,  # SLONG8 [BigTIFF]
+    'ifd8'          => 18,  # IFD8 (with int64u format) [BigTIFF]
+);
+
+# EXIF LightSource PrintConv values
+%lightSource = (
+    1 => 'Daylight',
+    2 => 'Fluorescent',
+    3 => 'Tungsten',
+    4 => 'Flash',
+    9 => 'Fine Weather',
+    10 => 'Cloudy',
+    11 => 'Shade',
+    12 => 'Daylight Fluorescent',
+    13 => 'Day White Fluorescent',
+    14 => 'Cool White Fluorescent',
+    15 => 'White Fluorescent',
+    17 => 'Standard Light A',
+    18 => 'Standard Light B',
+    19 => 'Standard Light C',
+    20 => 'D55',
+    21 => 'D65',
+    22 => 'D75',
+    23 => 'D50',
+    24 => 'ISO Studio Tungsten',
+    255 => 'Other',
+);
+
+%compression = (
+    1 => 'Uncompressed',
+    2 => 'CCITT 1D',
+    3 => 'T4/Group 3 Fax',
+    4 => 'T6/Group 4 Fax',
+    5 => 'LZW',
+    6 => 'JPEG (old-style)', #3
+    7 => 'JPEG', #4
+    8 => 'Adobe Deflate', #3
+    9 => 'JBIG B&W', #3
+    10 => 'JBIG Color', #3
+    32766 => 'Next', #3
+    32769 => 'Epson ERF Compressed', #PH
+    32771 => 'CCIRLEW', #3
+    32773 => 'PackBits',
+    32809 => 'Thunderscan', #3
+    32895 => 'IT8CTPAD', #3
+    32896 => 'IT8LW', #3
+    32897 => 'IT8MP', #3
+    32898 => 'IT8BL', #3
+    32908 => 'PixarFilm', #3
+    32909 => 'PixarLog', #3
+    32946 => 'Deflate', #3
+    32947 => 'DCS', #3
+    34661 => 'JBIG', #3
+    34676 => 'SGILog', #3
+    34677 => 'SGILog24', #3
+    34712 => 'JPEG 2000', #3
+    34713 => 'Nikon NEF Compressed', #PH
+    65000 => 'Kodak DCR Compressed', #PH
+    65535 => 'Pentax PEF Compressed', #Jens
+    
+);
+
+%photometricInterpretation = (
+    0 => 'WhiteIsZero',
+    1 => 'BlackIsZero',
+    2 => 'RGB',
+    3 => 'RGB Palette',
+    4 => 'Transparency Mask',
+    5 => 'CMYK',
+    6 => 'YCbCr',
+    8 => 'CIELab',
+    9 => 'ICCLab', #3
+    10 => 'ITULab', #3
+    32803 => 'Color Filter Array', #2
+    32844 => 'Pixar LogL', #3
+    32845 => 'Pixar LogLuv', #3
+    34892 => 'Linear Raw', #2
+);
+
+%orientation = (
+    1 => 'Horizontal (normal)',
+    2 => 'Mirror horizontal',
+    3 => 'Rotate 180',
+    4 => 'Mirror vertical',
+    5 => 'Mirror horizontal and rotate 270 CW',
+    6 => 'Rotate 90 CW',
+    7 => 'Mirror horizontal and rotate 90 CW',
+    8 => 'Rotate 270 CW',
+);
+
+# ValueConv that makes long values binary type
+my %longBin = (
+    ValueConv => 'length($val) > 64 ? \$val : $val',
+    ValueConvInv => '$val',
+);
+
+# main EXIF tag table
+%Image::ExifTool::Exif::Main = (
+    GROUPS => { 0 => 'EXIF', 1 => 'IFD0', 2 => 'Image'},
+    WRITE_PROC => \&WriteExif,
+    WRITE_GROUP => 'ExifIFD',   # default write group
+    0x1 => {
+        Name => 'InteropIndex',
+        Description => 'Interoperability Index',
+        PrintConv => {
+            R98 => 'R98 - DCF basic file (sRGB)',
+            R03 => 'R03 - DCF option file (Adobe RGB)',
+            THM => 'THM - DCF thumbnail file',
+        },
+    },
+    0x2 => {
+        Name => 'InteropVersion',
+        Description => 'Interoperability Version',
+    },
+    0x0b => { #PH
+        Name => 'ProcessingSoftware',
+        Notes => 'used by ACD Systems Digital Imaging',
+    },
+    0xfe => {
+        Name => 'SubfileType',
+        # set priority directory if this is the full resolution image
+        RawConv => '$self->SetPriorityDir() if $val == 0; $val',
+        PrintConv => {
+            0 => 'Full-resolution Image',
+            1 => 'Reduced-resolution image',
+            2 => 'Single page of multi-page image',
+            3 => 'Single page of multi-page reduced-resolution image',
+            4 => 'Transparency mask',
+            5 => 'Transparency mask of reduced-resolution image',
+            6 => 'Transparency mask of multi-page image',
+            7 => 'Transparency mask of reduced-resolution multi-page image',
+        },
+    },
+    0xff => {
+        Name => 'OldSubfileType',
+        # set priority directory if this is the full resolution image
+        RawConv => '$self->SetPriorityDir() if $val == 1; $val',
+        PrintConv => {
+            1 => 'Full-resolution image',
+            2 => 'Reduced-resolution image',
+            3 => 'Single page of multi-page image',
+        },
+    },
+    0x100 => {
+        Name => 'ImageWidth',
+        # even though Group 1 is set dynamically we need to register IFD1 once
+        # so it will show up in the group lists
+        Groups => { 1 => 'IFD1' },
+        # set Priority to zero so the value found in the first IFD (IFD0) doesn't
+        # get overwritten by subsequent IFD's (same for ImageHeight below)
+        Priority => 0,
+    },
+    0x101 => {
+        Name => 'ImageHeight',
+        Priority => 0,
+    },
+    0x102 => {
+        Name => 'BitsPerSample',
+        Priority => 0,
+    },
+    0x103 => {
+        Name => 'Compression',
+        PrintConv => \%compression,
+        Priority => 0,
+    },
+    0x106 => {
+        Name => 'PhotometricInterpretation',
+        PrintConv => \%photometricInterpretation,
+        Priority => 0,
+    },
+    0x107 => {
+        Name => 'Thresholding',
+        PrintConv => {
+            1 => 'No dithering or halftoning',
+            2 => 'Ordered dither or halftone',
+            3 => 'Randomized dither',
+        },
+    },
+    0x108 => 'CellWidth',
+    0x109 => 'CellLength',
+    0x10a => {
+        Name => 'FillOrder',
+        PrintConv => {
+            1 => 'Normal',
+            2 => 'Reversed',
+        },
+    },
+    0x10d => 'DocumentName',
+    0x10e => {
+        Name => 'ImageDescription',
+        Priority => 0,
+    },
+    0x10f => {
+        Name => 'Make',
+        Groups => { 2 => 'Camera' },
+        DataMember => 'CameraMake',
+        # save this value as an ExifTool member variable
+        RawConv => '$self->{CameraMake} = $val',
+    },
+    0x110 => {
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Groups => { 2 => 'Camera' },
+        DataMember => 'CameraModel',
+        # save this value as an ExifTool member variable
+        RawConv => '$self->{CameraModel} = $val',
+    },
+    0x111 => [
+        {
+            Condition => q[
+                ($self->{TIFF_TYPE} ne "CR2" or $self->{DIR_NAME} ne "IFD0") and
+                ($self->{TIFF_TYPE} ne "DNG" or $self->{DIR_NAME} !~ /^SubIFD[12]$/)
+            ],
+            Name => 'StripOffsets',
+            IsOffset => 1,
+            OffsetPair => 0x117,  # point to associated byte counts
+            ValueConv => 'length($val) > 32 ? \$val : $val',
+        },
+        {
+            Condition => '$self->{DIR_NAME} eq "IFD0"',
+            Name => 'PreviewImageStart',
+            IsOffset => 1,
+            OffsetPair => 0x117,
+            Notes => q{
+                PreviewImageStart in IFD0 of CR2 images and SubIFD1 of DNG images, and
+                JpgFromRawStart in SubIFD2 of DNG images
+            },
+            DataTag => 'PreviewImage',
+            Writable => 'int32u',
+            WriteGroup => 'IFD0',
+            WriteCondition => '$self->{TIFF_TYPE} eq "CR2"',
+            Protected => 2,
+        },
+        {
+            Condition => '$self->{DIR_NAME} eq "SubIFD1"',
+            Name => 'PreviewImageStart',
+            IsOffset => 1,
+            OffsetPair => 0x117,
+            DataTag => 'PreviewImage',
+            Writable => 'int32u',
+            WriteGroup => 'SubIFD1',
+            WriteCondition => '$self->{TIFF_TYPE} eq "DNG"',
+            Protected => 2,
+        },
+        {
+            Name => 'JpgFromRawStart',
+            IsOffset => 1,
+            OffsetPair => 0x117,
+            DataTag => 'JpgFromRaw',
+            Writable => 'int32u',
+            WriteGroup => 'SubIFD2',
+            WriteCondition => '$self->{TIFF_TYPE} eq "DNG"',
+            Protected => 2,
+        },
+    ],
+    0x112 => {
+        Name => 'Orientation',
+        PrintConv => \%orientation,
+        Priority => 0,  # so IFD1 doesn't take precedence
+    },
+    0x115 => {
+        Name => 'SamplesPerPixel',
+        Priority => 0,
+    },
+    0x116 => {
+        Name => 'RowsPerStrip',
+        Priority => 0,
+    },
+    0x117 => [
+        {
+            Condition => q[
+                ($self->{TIFF_TYPE} ne "CR2" or $self->{DIR_NAME} ne "IFD0") and
+                ($self->{TIFF_TYPE} ne "DNG" or $self->{DIR_NAME} !~ /^SubIFD[12]$/)
+            ],
+            Name => 'StripByteCounts',
+            OffsetPair => 0x111,   # point to associated offset
+            ValueConv => 'length($val) > 32 ? \$val : $val',
+        },
+        {
+            Condition => '$self->{DIR_NAME} eq "IFD0"',
+            Name => 'PreviewImageLength',
+            OffsetPair => 0x111,
+            Notes => q{
+                PreviewImageLength in IFD0 of CR2 images and SubIFD1 of DNG images, and
+                JpgFromRawLength in SubIFD2 of DNG images
+            },
+            DataTag => 'PreviewImage',
+            Writable => 'int32u',
+            WriteGroup => 'IFD0',
+            WriteCondition => '$self->{TIFF_TYPE} eq "CR2"',
+            Protected => 2,
+        },
+        {
+            Condition => '$self->{DIR_NAME} eq "SubIFD1"',
+            Name => 'PreviewImageLength',
+            OffsetPair => 0x111,
+            DataTag => 'PreviewImage',
+            Writable => 'int32u',
+            WriteGroup => 'SubIFD1',
+            WriteCondition => '$self->{TIFF_TYPE} eq "DNG"',
+            Protected => 2,
+        },
+        {
+            Name => 'JpgFromRawLength',
+            OffsetPair => 0x111,
+            DataTag => 'JpgFromRaw',
+            Writable => 'int32u',
+            WriteGroup => 'SubIFD2',
+            WriteCondition => '$self->{TIFF_TYPE} eq "DNG"',
+            Protected => 2,
+        },
+    ],
+    0x118 => 'MinSampleValue',
+    0x119 => 'MaxSampleValue',
+    0x11a => {
+        Name => 'XResolution',
+        Priority => 0,  # so IFD0 takes priority over IFD1
+    },
+    0x11b => {
+        Name => 'YResolution',
+        Priority => 0,
+    },
+    0x11c => {
+        Name => 'PlanarConfiguration',
+        PrintConv => {
+            1 => 'Chunky',
+            2 => 'Planar',
+        },
+        Priority => 0,
+    },
+    0x11d => 'PageName',
+    0x11e => 'XPosition',
+    0x11f => 'YPosition',
+    0x120 => {
+        Name => 'FreeOffsets',
+        IsOffset => 1,
+        OffsetPair => 0x121,
+        ValueConv => 'length($val) > 32 ? \$val : $val',
+    },
+    0x121 => {
+        Name => 'FreeByteCounts',
+        OffsetPair => 0x120,
+        ValueConv => 'length($val) > 32 ? \$val : $val',
+    },
+    0x122 => {
+        Name => 'GrayResponseUnit',
+        PrintConv => { #3
+            1 => 0.1,
+            2 => 0.001,
+            3 => 0.0001,
+            4 => 0.00001,
+            5 => 0.000001,
+        },
+    },
+    0x123 => {
+        Name => 'GrayResponseCurve',
+        Binary => 1,
+    },
+    0x124 => {
+        Name => 'T4Options',
+        PrintConv => { BITMASK => {
+            0 => '2-Dimensional encoding',
+            1 => 'Uncompressed',
+            2 => 'Fill bits added',
+        } }, #3
+    },
+    0x125 => {
+        Name => 'T6Options',
+        PrintConv => { BITMASK => {
+            1 => 'Uncompressed',
+        } }, #3
+    },
+    0x128 => {
+        Name => 'ResolutionUnit',
+        PrintConv => {
+            1 => 'None',
+            2 => 'inches',
+            3 => 'cm',
+        },
+        Priority => 0,
+    },
+    0x129 => 'PageNumber',
+    0x12c => 'ColorResponseUnit', #9
+    0x12d => {
+        Name => 'TransferFunction',
+        Binary => 1,
+    },
+    0x131 => {
+        Name => 'Software',
+    },
+    0x132 => {
+        Name => 'ModifyDate',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    0x13b => {
+        Name => 'Artist',
+        Groups => { 2 => 'Author' },
+    },
+    0x13c => 'HostComputer',
+    0x13d => {
+        Name => 'Predictor',
+        PrintConv => {
+            1 => 'None',
+            2 => 'Horizontal differencing',
+        },
+    },
+    0x13e => {
+        Name => 'WhitePoint',
+        Groups => { 2 => 'Camera' },
+    },
+    0x13f => {
+        Name => 'PrimaryChromaticities',
+        Priority => 0,
+    },
+    0x140 => {
+        Name => 'ColorMap',
+        Format => 'binary',
+        Binary => 1,
+    },
+    0x141 => 'HalftoneHints',
+    0x142 => 'TileWidth',
+    0x143 => 'TileLength',
+    0x144 => {
+        Name => 'TileOffsets',
+        IsOffset => 1,
+        OffsetPair => 0x145,
+        ValueConv => 'length($val) > 32 ? \$val : $val',
+    },
+    0x145 => {
+        Name => 'TileByteCounts',
+        OffsetPair => 0x144,
+        ValueConv => 'length($val) > 32 ? \$val : $val',
+    },
+    0x146 => 'BadFaxLines', #3
+    0x147 => { #3
+        Name => 'CleanFaxData',
+        PrintConv => {
+            0 => 'Clean',
+            1 => 'Regenerated',
+            2 => 'Unclean',
+        },
+    },
+    0x148 => 'ConsecutiveBadFaxLines', #3
+    0x14a => {
+        Name => 'SubIFD',
+        Groups => { 1 => 'SubIFD' },
+        Flags => 'SubIFD',
+        SubDirectory => {
+            Start => '$val',
+            MaxSubdirs => 3,
+        },
+    },
+    0x14c => {
+        Name => 'InkSet',
+        PrintConv => { #3
+            1 => 'CMYK',
+            2 => 'Not CMYK',
+        },
+    },
+    0x14d => 'InkNames', #3
+    0x14e => 'NumberofInks', #3
+    0x150 => 'DotRange',
+    0x151 => 'TargetPrinter',
+    0x152 => 'ExtraSamples',
+    0x153 => {
+        Name => 'SampleFormat',
+        PrintConv => {
+            1 => 'Unsigned integer',
+            2 => "Two's complement signed integer",
+            3 => 'IEEE floating point',
+            4 => 'Undefined',
+            5 => 'Complex integer', #3
+            6 => 'IEEE floating point', #3
+        },
+    },
+    0x154 => 'SMinSampleValue',
+    0x155 => 'SMaxSampleValue',
+    0x156 => 'TransferRange',
+    0x157 => 'ClipPath', #3
+    0x158 => 'XClipPathUnits', #3
+    0x159 => 'YClipPathUnits', #3
+    0x15a => { #3
+        Name => 'Indexed',
+        PrintConv => { 0 => 'Not indexed', 1 => 'Indexed' },
+    },
+    0x15b => {
+        Name => 'JPEGTables',
+        Binary => 1,
+    },
+    0x15f => { #10
+        Name => 'OPIProxy',
+        PrintConv => {
+            0 => 'Higher resolution image does not exist',
+            1 => 'Higher resolution image exists',
+        },
+    },
+    0x190 => { #3
+        Name => 'GlobalParametersIFD',
+        Groups => { 1 => 'GlobParamIFD' },
+        Flags => 'SubIFD',
+        SubDirectory => {
+            DirName => 'GlobParamIFD',
+            Start => '$val',
+        },
+    },
+    0x191 => { #3
+        Name => 'ProfileType',
+        PrintConv => { 0 => 'Unspecified', 1 => 'Group 3 FAX' },
+    },
+    0x192 => { #3
+        Name => 'FaxProfile',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'Minimal B&W lossless, S',
+            2 => 'Extended B&W lossless, F',
+            3 => 'Lossless JBIG B&W, J',
+            4 => 'Lossy color and grayscale, C',
+            5 => 'Lossless color and grayscale, L',
+            6 => 'Mixed raster content, M',
+        },
+    },
+    0x193 => { #3
+        Name => 'CodingMethods',
+        PrintConv => { BITMASK => {
+            0 => 'Unspecified compression',
+            1 => 'Modified Huffman',
+            2 => 'Modified Read',
+            3 => 'Modified MR',
+            4 => 'JBIG',
+            5 => 'Baseline JPEG',
+            6 => 'JBIG color',
+        } },
+    },
+    0x194 => 'VersionYear', #3
+    0x195 => 'ModeNumber', #3
+    0x1b1 => 'Decode', #3
+    0x1b2 => 'DefaultImageColor', #3
+    0x200 => {
+        Name => 'JPEGProc',
+        PrintConv => {
+            1 => 'Baseline',
+            14 => 'Lossless',
+        },
+    },
+    0x201 => [
+        {
+            Name => 'ThumbnailOffset',
+            # thumbnail is found in IFD1 of JPEG and TIFF images, and
+            # IFD0 of EXIF information in FujiFilm AVI (RIFF) videos
+            Condition => q{
+                $self->{DIR_NAME} eq 'IFD1' or
+                ($self->{FILE_TYPE} eq 'RIFF' and $self->{DIR_NAME} eq 'IFD0')
+            },
+            IsOffset => 1,
+            OffsetPair => 0x202,
+            DataTag => 'ThumbnailImage',
+            Writable => 'int32u',
+            WriteGroup => 'IFD1',
+            WriteCondition => '$$self{FILE_TYPE} ne "TIFF"',
+            Protected => 2,
+        },
+        {
+            Name => 'PreviewImageStart',
+            Condition => '$self->{DIR_NAME} eq "MakerNotes"',
+            IsOffset => 1,
+            OffsetPair => 0x202,
+            DataTag => 'PreviewImage',
+            Writable => 'int32u',
+            WriteGroup => 'MakerNotes',
+            Protected => 2,
+        },
+        {
+            Name => 'JpgFromRawStart',
+            Condition => '$self->{DIR_NAME} eq "SubIFD"',
+            IsOffset => 1,
+            OffsetPair => 0x202,
+            DataTag => 'JpgFromRaw',
+            Writable => 'int32u',
+            WriteGroup => 'SubIFD',
+            # JpgFromRaw is in SubIFD of NEF files
+            WriteCondition => '$self->{TIFF_TYPE} eq "NEF"',
+            Protected => 2,
+        },
+        {
+            Name => 'JpgFromRawStart',
+            Condition => '$self->{DIR_NAME} eq "IFD2"',
+            IsOffset => 1,
+            OffsetPair => 0x202,
+            DataTag => 'JpgFromRaw',
+            Writable => 'int32u',
+            WriteGroup => 'IFD2',
+            # JpgFromRaw is in IFD2 of PEF files
+            WriteCondition => '$self->{TIFF_TYPE} eq "PEF"',
+            Protected => 2,
+        },
+        {
+            Name => 'OtherImageStart',
+            IsOffset => 1,
+            OffsetPair => 0x202,
+        },
+    ],
+    0x202 => [
+        {
+            Name => 'ThumbnailLength',
+            Condition => q{
+                $self->{DIR_NAME} eq 'IFD1' or
+                ($self->{FILE_TYPE} eq 'RIFF' and $self->{DIR_NAME} eq 'IFD0')
+            },
+            OffsetPair => 0x201,
+            DataTag => 'ThumbnailImage',
+            Writable => 'int32u',
+            WriteGroup => 'IFD1',
+            WriteCondition => '$$self{FILE_TYPE} ne "TIFF"',
+            Protected => 2,
+        },
+        {
+            Name => 'PreviewImageLength',
+            Condition => '$self->{DIR_NAME} eq "MakerNotes"',
+            OffsetPair => 0x201,
+            DataTag => 'PreviewImage',
+            Writable => 'int32u',
+            WriteGroup => 'MakerNotes',
+            Protected => 2,
+        },
+        {
+            Name => 'JpgFromRawLength',
+            Condition => '$self->{DIR_NAME} eq "SubIFD"',
+            OffsetPair => 0x201,
+            DataTag => 'JpgFromRaw',
+            Writable => 'int32u',
+            WriteGroup => 'SubIFD',
+            WriteCondition => '$self->{TIFF_TYPE} eq "NEF"',
+            Protected => 2,
+        },
+        {
+            Name => 'JpgFromRawLength',
+            Condition => '$self->{DIR_NAME} eq "IFD2"',
+            OffsetPair => 0x201,
+            DataTag => 'JpgFromRaw',
+            Writable => 'int32u',
+            WriteGroup => 'IFD2',
+            WriteCondition => '$self->{TIFF_TYPE} eq "PEF"',
+            Protected => 2,
+        },
+        {
+            Name => 'OtherImageLength',
+            OffsetPair => 0x201,
+        },
+    ],
+    0x203 => 'JPEGRestartInterval',
+    0x205 => 'JPEGLosslessPredictors',
+    0x206 => 'JPEGPointTransforms',
+    0x207 => 'JPEGQTables',
+    0x208 => 'JPEGDCTables',
+    0x209 => 'JPEGACTables',
+    0x211 => {
+        Name => 'YCbCrCoefficients',
+        Priority => 0,
+    },
+    0x212 => {
+        Name => 'YCbCrSubSampling',
+        PrintConv => {
+            '1 1' => 'YCbCr4:4:4 (1 1)', #PH
+            '2 1' => 'YCbCr4:2:2 (2 1)', #6
+            '2 2' => 'YCbCr4:2:0 (2 2)', #6
+            '4 1' => 'YCbCr4:1:1 (4 1)', #6
+            '4 2' => 'YCbCr4:1:0 (4 2)', #PH
+            '1 2' => 'YCbCr4:4:0 (1 2)', #PH
+        },
+        Priority => 0,
+    },
+    0x213 => {
+        Name => 'YCbCrPositioning',
+        PrintConv => {
+            1 => 'Centered',
+            2 => 'Co-sited',
+        },
+        Priority => 0,
+    },
+    0x214 => {
+        Name => 'ReferenceBlackWhite',
+        Priority => 0,
+    },
+    0x22f => 'StripRowCounts',
+    0x2bc => {
+        Name => 'ApplicationNotes',
+        # this could be an XMP block
+        SubDirectory => {
+            DirName => 'XMP',
+            TagTable => 'Image::ExifTool::XMP::Main',
+        },
+    },
+    0x1000 => 'RelatedImageFileFormat',
+    0x1001 => 'RelatedImageWidth',
+    0x1002 => 'RelatedImageLength',
+    # (0x474x tags written by MicrosoftPhoto)
+    0x4746 => 'Rating', #PH
+    0x4749 => 'RatingPercent', #PH
+    0x800d => 'ImageID', #10
+    0x80a4 => 'WangAnnotation',
+    0x80e3 => 'Matteing', #9
+    0x80e4 => 'DataType', #9
+    0x80e5 => 'ImageDepth', #9
+    0x80e6 => 'TileDepth', #9
+    0x827d => 'Model2',
+    0x828d => 'CFARepeatPatternDim',
+    0x828e => 'CFAPattern2',
+    0x828f => {
+        Name => 'BatteryLevel',
+        Groups => { 2 => 'Camera' },
+    },
+    0x8298 => {
+        Name => 'Copyright',
+        Groups => { 2 => 'Author' },
+    },
+    0x829a => {
+        Name => 'ExposureTime',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    0x829d => {
+        Name => 'FNumber',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x82a5 => { #3
+        Name => 'MDFileTag',
+        Notes => 'tags 0x82a5-0x82ac are used in Molecular Dynamics GEL files',
+    },
+    0x82a6 => 'MDScalePixel', #3
+    0x82a7 => 'MDColorTable', #3
+    0x82a8 => 'MDLabName', #3
+    0x82a9 => 'MDSampleInfo', #3
+    0x82aa => 'MDPrepDate', #3
+    0x82ab => 'MDPrepTime', #3
+    0x82ac => 'MDFileUnits', #3
+    0x830e => 'PixelScale',
+    0x83bb => {
+        Name => 'IPTC-NAA',
+        SubDirectory => {
+            DirName => 'IPTC',
+            TagTable => 'Image::ExifTool::IPTC::Main',
+        },
+    },
+    0x847e => 'IntergraphPacketData', #3
+    0x847f => 'IntergraphFlagRegisters', #3
+    0x8480 => 'IntergraphMatrix',
+    0x8482 => {
+        Name => 'ModelTiePoint',
+        Groups => { 2 => 'Location' },
+    },
+    0x84e0 => 'Site', #9
+    0x84e1 => 'ColorSequence', #9
+    0x84e2 => 'IT8Header', #9
+    0x84e3 => 'RasterPadding', #9
+    0x84e4 => 'BitsPerRunLength', #9
+    0x84e5 => 'BitsPerExtendedRunLength', #9
+    0x84e6 => 'ColorTable', #9
+    0x84e7 => 'ImageColorIndicator', #9
+    0x84e8 => 'BackgroundColorIndicator', #9
+    0x84e9 => 'ImageColorValue', #9
+    0x84ea => 'BackgroundColorValue', #9
+    0x84eb => 'PixelIntensityRange', #9
+    0x84ec => 'TransparencyIndicator', #9
+    0x84ed => 'ColorCharacterization', #9
+    0x84ee => 'HCUsage', #9
+    0x8546 => { #11
+        Name => 'SEMInfo',
+        Notes => 'found in some scanning electron microscope images',
+    },
+    0x8568 => {
+        Name => 'AFCP_IPTC',
+        SubDirectory => {
+            DirName => 'IPTC2', # change name because this isn't the IPTC we want to write
+            TagTable => 'Image::ExifTool::IPTC::Main',
+        },
+    },
+    0x85d8 => {
+        Name => 'ModelTransform',
+        Groups => { 2 => 'Location' },
+    },
+    0x8606 => {
+        Name => 'LeafData',
+        Format => 'undef',    # avoid converting huge block to string of int8u's!
+        SubDirectory => {
+            DirName => 'LeafIFD',
+            TagTable => 'Image::ExifTool::Leaf::Main',
+        },
+    },
+    0x8649 => {
+        Name => 'PhotoshopSettings',
+        Format => 'binary',
+        SubDirectory => {
+            DirName => 'Photoshop',
+            TagTable => 'Image::ExifTool::Photoshop::Main',
+        },
+    },
+    0x8769 => {
+        Name => 'ExifOffset',
+        Groups => { 1 => 'ExifIFD' },
+        Flags => 'SubIFD',
+        SubDirectory => {
+            DirName => 'ExifIFD',
+            Start => '$val',
+        },
+    },
+    0x8773 => {
+        Name => 'ICC_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+        },
+    },
+    0x87ac => 'ImageLayer',
+    0x87af => {
+        Name => 'GeoTiffDirectory',
+        Format => 'binary',
+        Binary => 1,
+    },
+    0x87b0 => {
+        Name => 'GeoTiffDoubleParams',
+        Format => 'binary',
+        Binary => 1,
+    },
+    0x87b1 => {
+        Name => 'GeoTiffAsciiParams',
+        Binary => 1,
+    },
+    0x8822 => {
+        Name => 'ExposureProgram',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            1 => 'Manual',
+            2 => 'Program AE',
+            3 => 'Aperture-priority AE',
+            4 => 'Shutter speed priority AE',
+            5 => 'Creative (Slow speed)',
+            6 => 'Action (High speed)',
+            7 => 'Portrait',
+            8 => 'Landscape',
+        },
+    },
+    0x8824 => {
+        Name => 'SpectralSensitivity',
+        Groups => { 2 => 'Camera' },
+    },
+    0x8825 => {
+        Name => 'GPSInfo',
+        Groups => { 1 => 'GPS' },
+        Flags => 'SubIFD',
+        SubDirectory => {
+            DirName => 'GPS',
+            TagTable => 'Image::ExifTool::GPS::Main',
+            Start => '$val',
+        },
+    },
+    0x8827 => 'ISO',
+    0x8828 => {
+        Name => 'Opto-ElectricConvFactor',
+        Binary => 1,
+    },
+    0x8829 => 'Interlace',
+    0x882a => 'TimeZoneOffset',
+    0x882b => 'SelfTimerMode',
+    0x885c => 'FaxRecvParams', #9
+    0x885d => 'FaxSubAddress', #9
+    0x885e => 'FaxRecvTime', #9
+    0x888a => { #PH
+        Name => 'LeafSubIFD',
+        Format => 'int32u',     # Leaf incorrectly uses 'undef' format!
+        Groups => { 1 => 'LeafSubIFD' },
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::SubIFD',
+            Start => '$val',
+        },
+    },
+    0x9000 => 'ExifVersion',
+    0x9003 => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    0x9004 => {
+        Name => 'CreateDate',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    0x9101 => {
+        Name => 'ComponentsConfiguration',
+        PrintConv => '$_=$val;s/\0.*//s;tr/\x01-\x06/YbrRGB/;s/b/Cb/g;s/r/Cr/g;$_',
+    },
+    0x9102 => 'CompressedBitsPerPixel',
+    0x9201 => {
+        Name => 'ShutterSpeedValue',
+        ValueConv => 'abs($val)<100 ? 1/(2**$val) : 0',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    0x9202 => {
+        Name => 'ApertureValue',
+        ValueConv => '2 ** ($val / 2)',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x9203 => 'BrightnessValue',
+    0x9204 => {
+        Name => 'ExposureCompensation',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x9205 => {
+        Name => 'MaxApertureValue',
+        Groups => { 2 => 'Camera' },
+        ValueConv => '2 ** ($val / 2)',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x9206 => {
+        Name => 'SubjectDistance',
+        Groups => { 2 => 'Camera' },
+        PrintConv => '$val eq "inf" ? $val : "${val} m"',
+    },
+    0x9207 => {
+        Name => 'MeteringMode',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            1 => 'Average',
+            2 => 'Center-weighted average',
+            3 => 'Spot',
+            4 => 'Multi-spot',
+            5 => 'Multi-segment',
+            6 => 'Partial',
+            255 => 'Other',
+        },
+    },
+    0x9208 => {
+        Name => 'LightSource',
+        Groups => { 2 => 'Camera' },
+        PrintConv => \%lightSource,
+    },
+    0x9209 => {
+        Name => 'Flash',
+        Groups => { 2 => 'Camera' },
+        Flags => 'PrintHex',
+        PrintConv => {
+            0x00 => 'No Flash',
+            0x01 => 'Fired',
+            0x05 => 'Fired, Return not detected',
+            0x07 => 'Fired, Return detected',
+            0x08 => 'On, Did not fire', # not charged up?
+            0x09 => 'On',
+            0x0d => 'On, Return not detected',
+            0x0f => 'On, Return detected',
+            0x10 => 'Off',
+            0x14 => 'Off, Did not fire, Return not detected',
+            0x18 => 'Auto, Did not fire',
+            0x19 => 'Auto, Fired',
+            0x1d => 'Auto, Fired, Return not detected',
+            0x1f => 'Auto, Fired, Return detected',
+            0x20 => 'No flash function',
+            0x30 => 'Off, No flash function',
+            0x41 => 'Fired, Red-eye reduction',
+            0x45 => 'Fired, Red-eye reduction, Return not detected',
+            0x47 => 'Fired, Red-eye reduction, Return detected',
+            0x49 => 'On, Red-eye reduction',
+            0x4d => 'On, Red-eye reduction, Return not detected',
+            0x4f => 'On, Red-eye reduction, Return detected',
+            0x50 => 'Off, Red-eye reduction',
+            0x58 => 'Auto, Did not fire, Red-eye reduction',
+            0x59 => 'Auto, Fired, Red-eye reduction',
+            0x5d => 'Auto, Fired, Red-eye reduction, Return not detected',
+            0x5f => 'Auto, Fired, Red-eye reduction, Return detected',
+        },
+    },
+    0x920a => {
+        Name => 'FocalLength',
+        Groups => { 2 => 'Camera' },
+        PrintConv => 'sprintf("%.1fmm",$val)',
+    },
+    # Note: tags 0x920b-0x9217 are duplicates of 0xa20b-0xa217
+    # (The TIFF standard uses 0xa2xx, but you'll find both in images)
+    0x920b => {
+        Name => 'FlashEnergy',
+        Groups => { 2 => 'Camera' },
+    },
+    0x920c => 'SpatialFrequencyResponse',   # ?? (not in Fuji images - PH)
+    0x920d => 'Noise',
+    0x920e => 'FocalPlaneXResolution',
+    0x920f => 'FocalPlaneYResolution',
+    0x9210 => {
+        Name => 'FocalPlaneResolutionUnit',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            1 => 'None',
+            2 => 'inches',
+            3 => 'cm',
+            4 => 'mm',
+            5 => 'um',
+        },
+    },
+    0x9211 => 'ImageNumber',
+    0x9212 => { #12
+        Name => 'SecurityClassification',
+        PrintConv => {
+            T => 'Top Secret',
+            S => 'Secret',
+            C => 'Confidential',
+            R => 'Restricted',
+            U => 'Unclassified',
+        },
+    },
+    0x9213 => 'ImageHistory',
+    0x9214 => {
+        Name => 'SubjectLocation',
+        Groups => { 2 => 'Camera' },
+    },
+    0x9215 => 'ExposureIndex',
+    0x9216 => 'TIFF-EPStandardID',
+    0x9217 => {
+        Name => 'SensingMethod',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            1 => 'Monochrome area', #12
+            2 => 'One-chip color area',
+            3 => 'Two-chip color area',
+            4 => 'Three-chip color area',
+            5 => 'Color sequential area',
+            6 => 'Monochrome linear', #12
+            7 => 'Trilinear',
+            8 => 'Color sequential linear',
+        },
+    },
+    0x9213 => 'ImageHistory',
+    0x923f => 'StoNits', #9
+    # handle maker notes as a conditional list
+    0x927c => \@Image::ExifTool::MakerNotes::Main,
+    0x9286 => {
+        Name => 'UserComment',
+        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+    },
+    0x9290 => {
+        Name => 'SubSecTime',
+        Groups => { 2 => 'Time' },
+    },
+    0x9291 => {
+        Name => 'SubSecTimeOriginal',
+        Groups => { 2 => 'Time' },
+    },
+    0x9292 => {
+        Name => 'SubSecTimeDigitized',
+        Groups => { 2 => 'Time' },
+    },
+    0x935c => { #3
+        Name => 'ImageSourceData',
+        Binary => 1,
+    },
+    0x9c9b => {
+        Name => 'XPTitle',
+        Format => 'undef',
+        ValueConv => '$self->Unicode2Charset($val,"II")',
+    },
+    0x9c9c => {
+        Name => 'XPComment',
+        Format => 'undef',
+        ValueConv => '$self->Unicode2Charset($val,"II")',
+    },
+    0x9c9d => {
+        Name => 'XPAuthor',
+        Groups => { 2 => 'Author' },
+        Format => 'undef',
+        ValueConv => '$self->Unicode2Charset($val,"II")',
+    },
+    0x9c9e => {
+        Name => 'XPKeywords',
+        Format => 'undef',
+        ValueConv => '$self->Unicode2Charset($val,"II")',
+    },
+    0x9c9f => {
+        Name => 'XPSubject',
+        Format => 'undef',
+        ValueConv => '$self->Unicode2Charset($val,"II")',
+    },
+    0xa000 => 'FlashpixVersion',
+    0xa001 => {
+        Name => 'ColorSpace',
+        Notes => q{
+            the value of 2 is not standard EXIF.  Instead, an Adobe RGB image is
+            indicated by "Uncalibrated" with an InteropIndex of "R03"'
+        },
+        PrintConv => {
+            1 => 'sRGB',
+            2 => 'Adobe RGB',
+            0xffff => 'Uncalibrated',
+        },
+    },
+    0xa002 => 'ExifImageWidth',
+    0xa003 => 'ExifImageLength',
+    0xa004 => 'RelatedSoundFile',
+    0xa005 => {
+        Name => 'InteropOffset',
+        Groups => { 1 => 'InteropIFD' },
+        Flags => 'SubIFD',
+        Description => 'Interoperability Offset',
+        SubDirectory => {
+            DirName => 'InteropIFD',
+            Start => '$val',
+        },
+    },
+    0xa20b => {
+        Name => 'FlashEnergy',
+        Groups => { 2 => 'Camera' },
+    },
+    0xa20c => {
+        Name => 'SpatialFrequencyResponse',
+        PrintConv => 'Image::ExifTool::Exif::PrintSFR($val)',
+    },
+    0xa20d => 'Noise',
+    0xa20e => { Name => 'FocalPlaneXResolution', Groups => { 2 => 'Camera' } },
+    0xa20f => { Name => 'FocalPlaneYResolution', Groups => { 2 => 'Camera' } },
+    0xa210 => {
+        Name => 'FocalPlaneResolutionUnit',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            1 => 'None', # (not standard EXIF)
+            2 => 'inches',
+            3 => 'cm',
+            4 => 'mm',   # (not standard EXIF)
+            5 => 'um',   # (not standard EXIF)
+        },
+    },
+    0xa211 => 'ImageNumber',
+    0xa212 => 'SecurityClassification',
+    0xa213 => 'ImageHistory',
+    0xa214 => {
+        Name => 'SubjectLocation',
+        Groups => { 2 => 'Camera' },
+    },
+    0xa215 => 'ExposureIndex',
+    0xa216 => 'TIFF-EPStandardID',
+    0xa217 => {
+        Name => 'SensingMethod',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            1 => 'Not defined',
+            2 => 'One-chip color area',
+            3 => 'Two-chip color area',
+            4 => 'Three-chip color area',
+            5 => 'Color sequential area',
+            7 => 'Trilinear',
+            8 => 'Color sequential linear',
+        },
+    },
+    0xa300 => {
+        Name => 'FileSource',
+        PrintConv => {
+            1 => 'Film Scanner',
+            2 => 'Reflection Print Scanner',
+            3 => 'Digital Camera',
+            # handle the case where Sigma incorrectly gives this tag a count of 4
+            "\3\0\0\0" => 'Sigma Digital Camera',
+        },
+    },
+    0xa301 => {
+        Name => 'SceneType',
+        PrintConv => {
+            1 => 'Directly photographed',
+        },
+    },
+    0xa302 => {
+        Name => 'CFAPattern',
+        PrintConv => 'Image::ExifTool::Exif::PrintCFAPattern($val)',
+    },
+    0xa401 => {
+        Name => 'CustomRendered',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Custom',
+        },
+    },
+    0xa402 => {
+        Name => 'ExposureMode',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Manual',
+            2 => 'Auto bracket',
+        },
+    },
+    0xa403 => {
+        Name => 'WhiteBalance',
+        Groups => { 2 => 'Camera' },
+        # set Priority to zero to keep this WhiteBalance from overriding the
+        # MakerNotes WhiteBalance, since the MakerNotes WhiteBalance and is more
+        # accurate and contains more information (if it exists)
+        Priority => 0,
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Manual',
+        },
+    },
+    0xa404 => {
+        Name => 'DigitalZoomRatio',
+        Groups => { 2 => 'Camera' },
+    },
+    0xa405 => {
+        Name => 'FocalLengthIn35mmFormat',
+        Groups => { 2 => 'Camera' },
+        PrintConv => '"${val}mm"',
+    },
+    0xa406 => {
+        Name => 'SceneCaptureType',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Landscape',
+            2 => 'Portrait',
+            3 => 'Night',
+        },
+    },
+    0xa407 => {
+        Name => 'GainControl',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            0 => 'None',
+            1 => 'Low gain up',
+            2 => 'High gain up',
+            3 => 'Low gain down',
+            4 => 'High gain down',
+        },
+    },
+    0xa408 => {
+        Name => 'Contrast',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Low',
+            2 => 'High',
+        },
+    },
+    0xa409 => {
+        Name => 'Saturation',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Low',
+            2 => 'High',
+        },
+    },
+    0xa40a => {
+        Name => 'Sharpness',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Soft',
+            2 => 'Hard',
+        },
+    },
+    0xa40b => {
+        Name => 'DeviceSettingDescription',
+        Groups => { 2 => 'Camera' },
+    },
+    0xa40c => {
+        Name => 'SubjectDistanceRange',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            1 => 'Macro',
+            2 => 'Close',
+            3 => 'Distant',
+        },
+    },
+    0xa420 => 'ImageUniqueID',
+    0xa480 => 'GDALMetadata', #3
+    0xa481 => 'GDALNoData', #3
+    0xa500 => 'Gamma',
+#
+# Windows Media Photo WDP tags
+#
+    0xbc01 => { #13
+        Name => 'PixelFormat',
+        PrintHex => 1,
+        Format => 'undef',
+        Notes => q{
+            tags 0xbc** are used in Windows Media Photo WDP images. The actual
+            PixelFormat values are 16-byte GUID's but the leading 15 bytes,
+            '6fddc324-4e03-4bfe-b1853-d77768dc9', have been removed below to avoid
+            unnecessary clutter
+        },
+        ValueConv => q{
+            require Image::ExifTool::ASF;
+            $val = Image::ExifTool::ASF::GetGUID($val);
+            # GUID's are too long, so remove redundant information
+            $val =~ s/^6fddc324-4e03-4bfe-b185-3d77768dc9//i and $val = hex($val);
+            return $val;
+        },
+        PrintConv => {
+            0x0d => '24-bit RGB',
+            0x0c => '24-bit BGR',
+            0x0e => '32-bit BGR',
+            0x15 => '48-bit RGB',
+            0x12 => '48-bit RGB Fixed Point',
+            0x3b => '48-bit RGB Half',
+            0x18 => '96-bit RGB Fixed Point',
+            0x1b => '128-bit RGB Float',
+            0x0f => '32-bit BGRA',
+            0x16 => '64-bit RGBA',
+            0x1d => '64-bit RGBA Fixed Point',
+            0x3a => '64-bit RGBA Half',
+            0x1e => '128-bit RGBA Fixed Point',
+            0x19 => '128-bit RGBA Float',
+            0x10 => '32-bit PBGRA',
+            0x17 => '64-bit PRGBA',
+            0x1a => '128-bit PRGBA Float',
+            0x1c => '32-bit CMYK',
+            0x2c => '40-bit CMYK Alpha',
+            0x1f => '64-bit CMYK',
+            0x2d => '80-bit CMYK Alpha',
+            0x20 => '24-bit 3 Channels',
+            0x21 => '32-bit 4 Channels',
+            0x22 => '40-bit 5 Channels',
+            0x23 => '48-bit 6 Channels',
+            0x24 => '56-bit 7 Channels',
+            0x25 => '64-bit 8 Channels',
+            0x2e => '32-bit 3 Channels Alpha',
+            0x2f => '40-bit 4 Channels Alpha',
+            0x30 => '48-bit 5 Channels Alpha',
+            0x31 => '56-bit 6 Channels Alpha',
+            0x32 => '64-bit 7 Channels Alpha',
+            0x33 => '72-bit 8 Channels Alpha',
+            0x26 => '48-bit 3 Channels',
+            0x27 => '64-bit 4 Channels',
+            0x28 => '80-bit 5 Channels',
+            0x29 => '96-bit 6 Channels',
+            0x2a => '112-bit 7 Channels',
+            0x2b => '128-bit 8 Channels',
+            0x34 => '64-bit 3 Channels Alpha',
+            0x35 => '80-bit 4 Channels Alpha',
+            0x36 => '96-bit 5 Channels Alpha',
+            0x37 => '112-bit 6 Channels Alpha',
+            0x38 => '128-bit 7 Channels Alpha',
+            0x39 => '144-bit 8 Channels Alpha',
+            0x08 => '8-bit Gray',
+            0x0b => '16-bit Gray',
+            0x13 => '16-bit Gray Fixed Point',
+            0x3e => '16-bit Gray Half',
+            0x3f => '32-bit Gray Fixed Point',
+            0x11 => '32-bit Gray Float',
+            0x05 => 'Black & White',
+            0x09 => '16-bit BGR555',
+            0x0a => '16-bit BGR565',
+            0x13 => '32-bit BGR101010',
+            0x3d => '32-bit RGBE',
+        },
+    },
+    0xbc04 => { #13
+        Name => 'ImageType',
+        PrintConv => { BITMASK => {
+            0 => 'Preview',
+            1 => 'Page',
+        } },
+    },
+    0xbc02 => { #13
+        Name => 'Transfomation',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Mirror vertical',
+            2 => 'Mirror horizontal',
+            3 => 'Rotate 180',
+            4 => 'Rotate 90 CW',
+            5 => 'Mirror horizontal and rotate 90 CW',
+            6 => 'Mirror horizontal and rotate 270 CW',
+            7 => 'Rotate 270 CW',
+        },
+    },
+    0xbc03 => { #13
+        Name => 'Uncompressed',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    0xbcc0 => { #13
+        Name => 'ImageOffset',
+        IsOffset => 1,
+        OffsetPair => 0xbcc1,  # point to associated byte count
+    },
+    0xbcc1 => { #13
+        Name => 'ImageByteCount',
+        OffsetPair => 0xbcc0,  # point to associated offset
+    },
+    0xbcc2 => { #13
+        Name => 'AlphaOffset',
+        IsOffset => 1,
+        OffsetPair => 0xbcc3,  # point to associated byte count
+    },
+    0xbcc3 => { #13
+        Name => 'AlphaByteCount',
+        OffsetPair => 0xbcc2,  # point to associated offset
+    },
+    0xbcc4 => { #13
+        Name => 'ImageDataDiscard',
+        PrintConv => {
+            0 => 'Full Resolution',
+            1 => 'Flexbits Discarded',
+            2 => 'HighPass Frequency Data Discarded',
+            3 => 'Highpass and LowPass Frequency Data Discarded',
+        },
+    },
+    0xbcc5 => { #13
+        Name => 'AlphaDataDiscard',
+        PrintConv => {
+            0 => 'Full Resolution',
+            1 => 'Flexbits Discarded',
+            2 => 'HighPass Frequency Data Discarded',
+            3 => 'Highpass and LowPass Frequency Data Discarded',
+        },
+    },
+    0xbc80 => 'ImageWidth', #13
+    0xbc81 => 'ImageHeight', #13
+    0xbc82 => 'WidthResolution', #13
+    0xbc83 => 'HeightResolution', #13
+#
+    0xc427 => 'OceScanjobDesc', #3
+    0xc428 => 'OceApplicationSelector', #3
+    0xc429 => 'OceIDNumber', #3
+    0xc42a => 'OceImageLogic', #3
+    0xc44f => 'Annotations', #7
+    0xc4a5 => {
+        Name => 'PrintIM',
+        # must set Writable here so this tag will be saved with MakerNotes option
+        Writable => 'undef',
+        Description => 'Print Image Matching',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+#
+# DNG tags 0xc6XX (ref 2 unless otherwise stated)
+#
+    0xc612 => {
+        Name => 'DNGVersion',
+        Notes => 'tags 0xc612-0xc65d are used in DNG images',
+    },
+    0xc613 => 'DNGBackwardVersion',
+    0xc614 => 'UniqueCameraModel',
+    0xc615 => {
+        Name => 'LocalizedCameraModel',
+        Format => 'string',
+        PrintConv => '$self->Printable($val)',
+    },
+    0xc616 => {
+        Name => 'CFAPlaneColor',
+        PrintConv => q{
+            my @cols = qw(Red Green Blue Cyan Magenta Yellow White);
+            my @vals = map { $cols[$_] || "Unknown($_)" } split(' ', $val);
+            return join(',', @vals);
+        },
+    },
+    0xc617 => {
+        Name => 'CFALayout',
+        PrintConv => {
+            1 => 'Rectangular',
+            2 => 'Even columns offset down 1/2 row',
+            3 => 'Even columns offset up 1/2 row',
+            4 => 'Even rows offset right 1/2 column',
+            5 => 'Even rows offset left 1/2 column',
+        },
+    },
+    0xc618 => {
+        Name => 'LinearizationTable',
+        Binary => 1,
+    },
+    0xc619 => 'BlackLevelRepeatDim',
+    0xc61a => 'BlackLevel',
+    0xc61b => { Name => 'BlackLevelDeltaH', %longBin },
+    0xc61c => { Name => 'BlackLevelDeltaV', %longBin },
+    0xc61d => 'WhiteLevel',
+    0xc61e => 'DefaultScale',
+    0xc61f => 'DefaultCropOrigin',
+    0xc620 => 'DefaultCropSize',
+    0xc621 => 'ColorMatrix1',
+    0xc622 => 'ColorMatrix2',
+    0xc623 => 'CameraCalibration1',
+    0xc624 => 'CameraCalibration2',
+    0xc625 => 'ReductionMatrix1',
+    0xc626 => 'ReductionMatrix2',
+    0xc627 => 'AnalogBalance',
+    0xc628 => 'AsShotNeutral',
+    0xc629 => 'AsShotWhiteXY',
+    0xc62a => 'BaselineExposure',
+    0xc62b => 'BaselineNoise',
+    0xc62c => 'BaselineSharpness',
+    0xc62d => 'BayerGreenSplit',
+    0xc62e => 'LinearResponseLimit',
+    0xc62f => {
+        Name => 'CameraSerialNumber',
+        Groups => { 2 => 'Camera' },
+    },
+    0xc630 => {
+        Name => 'DNGLensInfo',
+        Groups => { 2 => 'Camera' },
+        PrintConv => '$_=$val;s/(\S+) (\S+) (\S+) (\S+)/$1-$2mm f\/$3-$4/;$_',
+    },
+    0xc631 => 'ChromaBlurRadius',
+    0xc632 => 'AntiAliasStrength',
+    0xc633 => 'ShadowScale',
+    0xc634 => [
+        {
+            Condition => '$self->{TIFF_TYPE} eq "SR2"',
+            Name => 'SR2Private',
+            Groups => { 1 => 'SR2' },
+            Flags => 'SubIFD',
+            Format => 'int32u',
+            SubDirectory => {
+                DirName => 'SR2Private',
+                TagTable => 'Image::ExifTool::Sony::SR2Private',
+                Start => '$val',
+            },
+        },
+        {
+            Condition => '$$valPt =~ /^Adobe\0/',
+            Name => 'DNGAdobeData',
+            DNGMakerNotes => 1,
+            SubDirectory => { TagTable => 'Image::ExifTool::DNG::AdobeData' },
+            Format => 'undef',  # written incorrectly as int8u (change to undef for speed)
+        },
+        {
+            Condition => '$$valPt =~ /^PENTAX \0/',
+            Name => 'DNGPentaxData',
+            DNGMakerNotes => 1,
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Pentax::Main',
+                Start => '$valuePtr + 10',
+                Base => '$start - 10',
+                ByteOrder => 'Unknown', # easier to do this than read byteorder word
+            },
+            Format => 'undef',  # written incorrectly as int8u (change to undef for speed)
+        },
+        {
+            Name => 'DNGPrivateData',
+            Binary => 1,
+            Format => 'undef',
+        },
+    ],
+    0xc635 => {
+        Name => 'MakerNoteSafety',
+        PrintConv => {
+            0 => 'Unsafe',
+            1 => 'Safe',
+        },
+    },
+    0xc65a => {
+        Name => 'CalibrationIlluminant1',
+        PrintConv => \%lightSource,
+    },
+    0xc65b => {
+        Name => 'CalibrationIlluminant2',
+        PrintConv => \%lightSource,
+    },
+    0xc65c => 'BestQualityScale',
+    0xc65d => {
+        Name => 'RawDataUniqueID',
+        Format => 'undef',
+        ValueConv => 'uc(unpack("H*",$val))',
+    },
+    0xc660 => { #3
+        Name => 'AliasLayerMetadata',
+        Notes => 'used by Alias Sketchbook Pro, not a DNG tag',
+    },
+    0xc68b => {
+        Name => 'OriginalRawFileName',
+        Format => 'string', # sometimes written as int8u
+    },
+    0xc68c => {
+        Name => 'OriginalRawFileData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::DNG::OriginalRaw',
+        },
+    },
+    0xc68d => 'ActiveArea',
+    0xc68e => 'MaskedAreas',
+    0xc68f => {
+        Name => 'AsShotICCProfile',
+        Binary => 1,
+        Writable => 'undef', # must be defined here so tag will be extracted if specified
+        SubDirectory => {
+            DirName => 'AsShotICCProfile',
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+        },
+    },
+    0xc690 => 'AsShotPreProfileMatrix',
+    0xc691 => {
+        Name => 'CurrentICCProfile',
+        Binary => 1,
+        Writable => 'undef', # must be defined here so tag will be extracted if specified
+        SubDirectory => {
+            DirName => 'CurrentICCProfile',
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+        },
+    },
+    0xc692 => 'CurrentPreProfileMatrix',
+    # 0xea1c - unknown tag written by MicrosoftPhoto (undef)
+    #  observed: 1720 bytes in IFD0 or 1988 bytes in ExifIFD, in both cases
+    #  the data starts with "1c ea 00 00 00 08" followed by all 00's
+    0xea1d => {
+        Name => 'OffsetSchema',
+        Notes => "Microsoft's ill-conceived maker note offset difference",
+    },
+
+    # tags in the range 0xfde8-0xfe58 have been observed in PS7 files
+    # generated from RAW images.  They are all strings with the
+    # tag name at the start of the string.  To accomodate these types
+    # of tags, all tags with values above 0xf000 are handled specially
+    # by ProcessExif().
+);
+
+# the Composite tags are evaluated last, and are used
+# to calculate values based on the other tags
+# (the main script looks for the special 'Composite' hash)
+%Image::ExifTool::Exif::Composite = (
+    GROUPS => { 2 => 'Image' },
+    ImageSize => {
+        Require => {
+            0 => 'ImageWidth',
+            1 => 'ImageHeight',
+        },
+        ValueConv => '"$val[0]x$val[1]"',
+    },
+    # pick the best shutter speed value
+    ShutterSpeed => {
+        Desire => {
+            0 => 'ExposureTime',
+            1 => 'ShutterSpeedValue',
+            2 => 'BulbDuration',
+        },
+        ValueConv => '($val[2] and $val[2]>0) ? $val[2] : (defined($val[0]) ? $val[0] : $val[1])',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    Aperture => {
+        Desire => {
+            0 => 'FNumber',
+            1 => 'ApertureValue',
+        },
+        RawConv => '($val[0] || $val[1]) ? $val : undef',
+        ValueConv => '$val[0] || $val[1]',
+        PrintConv => 'sprintf("%.1f", $val)',
+    },
+    LightValue => {
+        Notes => 'calculated LV -- similar to exposure value but includes ISO speed',
+        Require => {
+            0 => 'Aperture',
+            1 => 'ShutterSpeed',
+            2 => 'ISO',
+        },
+        ValueConv => 'Image::ExifTool::Exif::CalculateLV($val[0],$val[1],$prt[2])',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    FocalLength35efl => {
+        Description => 'Focal Length',
+        Notes => 'this value may be incorrect if the image has been resized',
+        Groups => { 2 => 'Camera' },
+        Require => {
+            0 => 'FocalLength',
+        },
+        Desire => {
+            1 => 'ScaleFactor35efl',
+        },
+        ValueConv => '$val[0] * ($val[1] ? $val[1] : 1)',
+        PrintConv => '$val[1] ? sprintf("%.1fmm (35mm equivalent: %.1fmm)", $val[0], $val) : sprintf("%.1fmm", $val)',
+    },
+    ScaleFactor35efl => {
+        Description => 'Scale Factor To 35mm Equivalent',
+        Notes => 'this value and any derived values may be incorrect if image has been resized',
+        Groups => { 2 => 'Camera' },
+        Desire => {
+            0 => 'FocalLength',
+            1 => 'FocalLengthIn35mmFormat',
+            2 => 'Composite:DigitalZoom',
+            3 => 'FocalPlaneDiagonal',
+            4 => 'FocalPlaneXSize',
+            5 => 'FocalPlaneYSize',
+            6 => 'FocalPlaneResolutionUnit',
+            7 => 'FocalPlaneXResolution',
+            8 => 'FocalPlaneYResolution',
+            9 => 'CanonImageWidth',
+           10 => 'CanonImageHeight',
+           11 => 'ExifImageWidth',
+           12 => 'ExifImageLength',
+           13 => 'ImageWidth',
+           14 => 'ImageHeight',
+        },
+        ValueConv => 'Image::ExifTool::Exif::CalcScaleFactor35efl(@val)',
+        PrintConv => 'sprintf("%.1f", $val)',
+    },
+    CircleOfConfusion => {
+        Notes => q{
+            this value may be incorrect if the image has been resized.  Calculated as
+            D/1440, where D is the focal plane diagonal in mm
+        },
+        Groups => { 2 => 'Camera' },
+        Require => 'ScaleFactor35efl',
+        ValueConv => 'sqrt(24*24+36*36) / ($val * 1440)',
+        PrintConv => 'sprintf("%.3f mm",$val)',
+    },
+    HyperfocalDistance => {
+        Notes => 'this value may be incorrect if the image has been resized',
+        Groups => { 2 => 'Camera' },
+        Require => {
+            0 => 'FocalLength',
+            1 => 'Aperture',
+            2 => 'CircleOfConfusion',
+        },
+        ValueConv => q{
+            return undef unless $val[1] and $val[2];
+            return $val[0] * $val[0] / ($val[1] * $val[2] * 1000);
+        },
+        PrintConv => 'sprintf("%.2f m", $val)',
+    },
+    DOF => {
+        Description => 'Depth of Field',
+        Notes => 'this value may be incorrect if the image has been resized',
+        Require => {
+            0 => 'FocusDistance', # FocusDistance in meters, 0 means 'inf'
+            1 => 'FocalLength',
+            2 => 'Aperture',
+            3 => 'CircleOfConfusion',
+        },
+        ValueConv => q{
+            return undef unless $val[1] and $val[3];
+            $val[0] or $val[0] = 1e10;  # use a large number for 'inf'
+            my ($s, $f) = ($val[0], $val[1]);
+            my $t = $val[2] * $val[3] * ($s * 1000 - $f) / ($f * $f);
+            my @v = ($s / (1 + $t), $s / (1 - $t));
+            $v[1] < 0 and $v[1] = 0; # 0 means 'inf'
+            return join(' ',@v);
+        },
+        PrintConv => q{
+            $val =~ tr/,/./;    # in case locale is whacky
+            my @v = split ' ', $val;
+            $v[1] or return sprintf("inf (%.2f m - inf)", $v[0]);
+            return sprintf("%.2f m (%.2f - %.2f)",$v[1]-$v[0],$v[0],$v[1]);
+        },
+    },
+    DateTimeCreated => { # used by IPTC, XMP, WAV, etc
+        Description => 'Date/Time Created',
+        Groups => { 2 => 'Time' },
+        Require => {
+            0 => 'DateCreated',
+            1 => 'TimeCreated',
+        },
+        ValueConv => '"$val[0] $val[1]"',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    # create DateTimeOriginal from DateTimeCreated if not set already
+    DateTimeOriginal => {
+        Condition => 'not defined($oldVal)',
+        Description => 'Date/Time Original',
+        Groups => { 2 => 'Time' },
+        Require => 'DateTimeCreated',
+        ValueConv => '$val[0]',
+        PrintConv => '$prt[0]',
+    },
+    ThumbnailImage => {
+        Writable => 1,
+        WriteCheck => '$self->CheckImage(\$val)',
+        WriteAlso => {
+            # (the 0xfeedfeed values are translated in the Exif write routine)
+            ThumbnailOffset => 'defined $val ? 0xfeedfeed : undef',
+            ThumbnailLength => 'defined $val ? 0xfeedfeed : undef',
+        },
+        Require => {
+            0 => 'ThumbnailOffset',
+            1 => 'ThumbnailLength',
+        },
+        # retrieve the thumbnail from our EXIF data
+        RawConv => 'Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"ThumbnailImage")',
+    },
+    PreviewImage => {
+        Writable => 1,
+        WriteCheck => '$self->CheckImage(\$val)',
+        WriteAlso => {
+            PreviewImageStart  => 'defined $val ? 0xfeedfeed : undef',
+            PreviewImageLength => 'defined $val ? 0xfeedfeed : undef',
+            PreviewImageValid  => 'defined $val and length $val ? 1 : 0',
+        },
+        Require => {
+            0 => 'PreviewImageStart',
+            1 => 'PreviewImageLength',
+        },
+        Desire => {
+            2 => 'PreviewImageValid',
+            # (DNG may be have 2 preview images)
+            3 => 'PreviewImageStart (1)',
+            4 => 'PreviewImageLength (1)',
+        },
+        RawConv => q{
+            if ($val[3] and $val[4]) {
+                my %val = (
+                    0 => 'PreviewImageStart (1)',
+                    1 => 'PreviewImageLength (1)',
+                    2 => 'PreviewImageValid',
+                );
+                $self->FoundTag($tagInfo, \%val);
+            }
+            return undef if defined $val[2] and not $val[2];
+            return Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],'PreviewImage');
+        },
+    },
+    JpgFromRaw => {
+        Writable => 1,
+        WriteCheck => '$self->CheckImage(\$val)',
+        WriteAlso => {
+            JpgFromRawStart  => 'defined $val ? 0xfeedfeed : undef',
+            JpgFromRawLength => 'defined $val ? 0xfeedfeed : undef',
+        },
+        Require => {
+            0 => 'JpgFromRawStart',
+            1 => 'JpgFromRawLength',
+        },
+        RawConv => 'Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"JpgFromRaw")',
+    },
+    OtherImage => {
+        Require => {
+            0 => 'OtherImageStart',
+            1 => 'OtherImageLength',
+        },
+        # retrieve the thumbnail from our EXIF data
+        RawConv => 'Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"OtherImage")',
+    },
+    PreviewImageSize => {
+        Require => {
+            0 => 'PreviewImageWidth',
+            1 => 'PreviewImageHeight',
+        },
+        ValueConv => '"$val[0]x$val[1]"',
+    },
+    SubSecDateTimeOriginal => {
+        Description => 'Date/Time Original',
+        Require => {
+            0 => 'DateTimeOriginal',
+            1 => 'SubSecTimeOriginal',
+        },
+        # be careful here in case there is a timezone following the seconds
+        ValueConv => '$_=$val[0];s/(.*:\d{2})/$1\.$val[1]/;$_',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    CFAPattern => {
+        Require => {
+            0 => 'CFARepeatPatternDim',
+            1 => 'CFAPattern2',
+        },
+        # generate CFAPattern
+        ValueConv => q{
+            my @a = split / /, $val[0];
+            my @b = split / /, $val[1];
+            return undef unless @a==2 and @b==$a[0]*$a[1];
+            return Set16u($a[0]) . Set16u($a[1]) . pack('C*', @b);
+        },
+        PrintConv => 'Image::ExifTool::Exif::PrintCFAPattern($val)',
+    },
+    RedBalance => {
+        Groups => { 2 => 'Camera' },
+        Desire => {
+            0 => 'WB_RGGBLevels',
+            1 => 'WB_RGBGLevels',
+            2 => 'WB_RBGGLevels',
+            3 => 'WB_GRBGLevels',
+            4 => 'WB_GRGBLevels',
+            5 => 'WB_RBLevels',
+            6 => 'WBRedLevel',
+            7 => 'WBGreenLevel',
+        },
+        ValueConv => 'Image::ExifTool::Exif::RedBlueBalance(0,@val)',
+        PrintConv => 'int($val * 1e6 + 0.5) * 1e-6',
+    },
+    BlueBalance => {
+        Groups => { 2 => 'Camera' },
+        Desire => {
+            0 => 'WB_RGGBLevels',
+            1 => 'WB_RGBGLevels',
+            2 => 'WB_RBGGLevels',
+            3 => 'WB_GRBGLevels',
+            4 => 'WB_GRGBLevels',
+            5 => 'WB_RBLevels',
+            6 => 'WBBlueLevel',
+            7 => 'WBGreenLevel',
+        },
+        ValueConv => 'Image::ExifTool::Exif::RedBlueBalance(1,@val)',
+        PrintConv => 'int($val * 1e6 + 0.5) * 1e-6',
+    },
+    GPSPosition => {
+        Require => {
+            0 => 'GPSLatitude',
+            1 => 'GPSLongitude',
+        },
+        ValueConv => '"$val[0] $val[1]"',
+        PrintConv => '"$prt[0], $prt[1]"',
+    },
+);
+
+# table for unknown IFD entries
+%Image::ExifTool::Exif::Unknown = (
+    GROUPS => { 0 => 'EXIF', 1 => 'UnknownIFD', 2 => 'Image'},
+    WRITE_PROC => \&WriteExif,
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::Exif');
+
+
+#------------------------------------------------------------------------------
+# AutoLoad our writer routines when necessary
+#
+sub AUTOLOAD
+{
+    return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
+}
+
+#------------------------------------------------------------------------------
+# Calculate LV (Light Value)
+# Inputs: 0) Aperture, 1) ShutterSpeed, 2) ISO
+# Returns: LV value
+sub CalculateLV($$$)
+{
+    local $_;
+    # do validity checks on arguments
+    return undef unless @_ >= 3;
+    foreach (@_) {
+        return undef unless defined $_ and Image::ExifTool::IsFloat($_) and $_ > 0;
+    }
+    # (A light value of 0 is defined as f/1.0 at 1 second with ISO 100)
+    return (2*log($_[0]) - log($_[1]) - log($_[2]/100)) / log(2);
+}
+
+#------------------------------------------------------------------------------
+# Calculate scale factor for 35mm effective focal length
+# Inputs: 0) Focal length
+#         1) Focal length in 35mm format
+#         2) Canon digital zoom factor
+#         3) Focal plane diagonal size (in mm)
+#         4/5) Focal plane X/Y size (in mm)
+#         6) focal plane resolution units (1=None,2=inches,3=cm,4=mm,5=um)
+#         7/8) Focal plane X/Y resolution
+#         9/10,11/12...) Image width/height in order of precedence (first valid pair is used)
+# Returns: 35mm conversion factor (or undefined if it can't be calculated)
+sub CalcScaleFactor35efl
+{
+    my $focal = shift;
+    my $foc35 = shift;
+
+    return $foc35 / $focal if $focal and $foc35;
+
+    my $digz = shift || 1;
+    my $diag = shift;
+    unless ($diag and Image::ExifTool::IsFloat($diag)) {
+        my $xsize = shift;
+        my $ysize = shift;
+        if ($xsize and $ysize) {
+            $diag = sqrt($xsize * $xsize + $ysize * $ysize);
+        } else {
+            # get number of mm in units (assume inches unless otherwise specified)
+            my $units = { 3=>10, 4=>1, 5=>0.001 }->{ shift() || '' } || 25.4;
+            my $x_res = shift || return undef;
+            my $y_res = shift || return undef;
+            Image::ExifTool::IsFloat($x_res) and $x_res != 0 or return undef;
+            Image::ExifTool::IsFloat($y_res) and $y_res != 0 or return undef;
+            my ($w, $h);
+            for (;;) {
+                @_ < 2 and return undef;
+                $w = shift;
+                $h = shift;
+                next unless $w and $h;
+                my $a = $w / $h;
+                last if $a > 0.5 and $a < 2; # stop if we get a reasonable value
+            }
+            # calculate focal plane size in mm
+            $w *= $units / $x_res;
+            $h *= $units / $y_res;
+            $diag = sqrt($w*$w+$h*$h);
+            # make sure size is reasonable
+            return undef unless $diag > 1 and $diag < 100;
+        }
+    }
+    return sqrt(36*36+24*24) * $digz / $diag;
+}
+
+#------------------------------------------------------------------------------
+# Convert exposure compensation fraction
+sub ConvertFraction($)
+{
+    my $val = shift;
+    my $str;
+    if (defined $val) {
+        $val *= 1.00001;    # avoid round-off errors
+        if (not $val) {
+            $str = '0';
+        } elsif (int($val)/$val > 0.999) {
+            $str = sprintf("%+d", int($val));
+        } elsif ((int($val*2))/($val*2) > 0.999) {
+            $str = sprintf("%+d/2", int($val * 2));
+        } elsif ((int($val*3))/($val*3) > 0.999) {
+            $str = sprintf("%+d/3", int($val * 3));
+        } else {
+            $str = sprintf("%.3g", $val);
+        }
+    }
+    return $str;
+}
+
+#------------------------------------------------------------------------------
+# Convert EXIF text to something readable
+# Inputs: 0) ExifTool object reference, 1) EXIF text
+# Returns: UTF8 or Latin text
+sub ConvertExifText($$)
+{
+    my ($exifTool, $val) = @_;
+    return $val if length($val) < 8;
+    my $id = substr($val, 0, 8);
+    my $str = substr($val, 8);
+    # by the EXIF spec, the string should be "UNICODE\0", but apparently Kodak
+    # sometimes uses "Unicode\0" in the APP3 "Meta" information.  But unfortunately
+    # Ricoh uses "Unicode\0" in the RR30 EXIF UserComment when the text is actually
+    # ASCII, so only recognize uppercase "UNICODE\0" here.
+    if ($id eq "UNICODE\0") {
+        # MicrosoftPhoto writes as little-endian even in big-endian EXIF,
+        # so we must guess at the true byte ordering
+        my ($ii, $mm) = (0, 0);
+        foreach (unpack('n*', $str)) {
+            ++$mm unless $_ & 0xff00;
+            ++$ii unless $_ & 0x00ff;
+        }
+        my $order;
+        $order = ($ii > $mm) ? 'II' : 'MM' if $ii != $mm;
+        # convert from unicode
+        $str = $exifTool->Unicode2Charset($str, $order);
+    } else {
+        # assume everything else is ASCII (Don't convert JIS... yet)
+        $str =~ s/\0.*//s;   # truncate at null terminator
+    }
+    return $str;
+}
+
+#------------------------------------------------------------------------------
+# Print conversion for SpatialFrequencyResponse
+sub PrintSFR($)
+{
+    my $val = shift;
+    return $val unless length $val > 4;
+    my ($n, $m) = (Get16u(\$val, 0), Get16u(\$val, 2));
+    my @cols = split /\0/, substr($val, 4), $n+1;
+    my $pos = length($val) - 8 * $n * $m;
+    return $val unless @cols == $n+1 and $pos >= 4;
+    pop @cols;
+    my ($i, $j);
+    for ($i=0; $i<$n; ++$i) {
+        my @rows;
+        for ($j=0; $j<$m; ++$j) {
+            push @rows, Image::ExifTool::GetRational64u(\$val, $pos + 8*($i+$j*$n));
+        }
+        $cols[$i] .= '=' . join(',',@rows) . '';
+    }
+    return join '; ', @cols;
+}
+
+#------------------------------------------------------------------------------
+# Print numerical parameter value (with sign, or 'Normal' for zero)
+sub PrintParameter($)
+{
+    my $val = shift;
+    if ($val > 0) {
+        if ($val > 0xfff0) {    # a negative value in disguise?
+            $val = $val - 0x10000;
+        } else {
+            $val = "+$val";
+        }
+    } elsif ($val == 0) {
+        $val = 'Normal';
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Convert parameter back to standard EXIF value
+#   0 or "Normal" => 0
+#   -1,-2,etc or "Soft" or "Low" => 1
+#   +1,+2,1,2,etc or "Hard" or "High" => 2
+sub ConvertParameter($)
+{
+    my $val = shift;
+    # normal is a value of zero
+    return 0 if $val =~ /\bn/i or not $val;
+    # "soft", "low" or any negative number is a value of 1
+    return 1 if $val =~ /\b(s|l|-)/i;
+    # "hard", "high" or any positive number is a vail of 2
+    return 2 if $val =~ /\b(h|\+|\d)/i;
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Calculate Red/BlueBalance
+# Inputs: 0) 0=red, 1=blue, 1-6) WB_RGGB/RGBG/RBGG/GRBG/GRGB/RBLevels,
+#         7) red or blue level, 8) green level
+my @rggbLookup = (
+    [ 0, 1, 2, 3 ], # RGGB
+    [ 0, 1, 3, 2 ], # RGBG
+    [ 0, 2, 3, 1 ], # RBGG
+    [ 1, 0, 3, 2 ], # GRBG
+    [ 1, 0, 2, 3 ], # GRGB
+    [ 0, 256, 256, 1 ], # RB (green level is 256)
+);
+sub RedBlueBalance($@)
+{
+    my $blue = shift;
+    my ($i, $val, $levels);
+    for ($i=0; $i<@rggbLookup; ++$i) {
+        $levels = shift or next;
+        my @levels = split ' ', $levels;
+        next if @levels < 2;
+        my $lookup = $rggbLookup[$i];
+        my $g = $$lookup[1];    # get green level or index
+        if ($g < 4) {
+            next if @levels < 4;
+            $g = ($levels[$g] + $levels[$$lookup[2]]) / 2 or next;
+        }
+        $val = $levels[$$lookup[$blue * 3]] / $g;
+        last;
+    }
+    $val = $_[0] / $_[1] if not defined $val and ($_[0] and $_[1]);
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Print exposure time as a fraction
+sub PrintExposureTime($)
+{
+    my $secs = shift;
+    if ($secs < 0.25001 and $secs > 0) {
+        return sprintf("1/%d",int(0.5 + 1/$secs));
+    }
+    $_ = sprintf("%.1f",$secs);
+    s/\.0$//;
+    return $_;
+}
+
+#------------------------------------------------------------------------------
+# Print CFA Pattern
+sub PrintCFAPattern($)
+{
+    my $val = shift;
+    return '<truncated data>' unless length $val > 4;
+    # some panasonic cameras (SV-AS3, SV-AS30) write this in ascii (very odd)
+    $val =~ /^[0-6]+$/ and $val =~ tr/0-6/\x00-\x06/;
+    my ($nx, $ny) = (Get16u(\$val, 0), Get16u(\$val, 2));
+    return '<zero pattern size>' unless $nx and $ny;
+    my $end = 4 + $nx * $ny;
+    if ($end > length $val) {
+        # try swapping byte order (I have seen this order different than in EXIF)
+        ($nx, $ny) = unpack('n2',pack('v2',$nx,$ny));
+        $end = 4 + $nx * $ny;
+        return '<invalid pattern size>' if $end > length $val;
+    }
+    my @cfaColor = qw(Red Green Blue Cyan Magenta Yellow White);
+    my ($pos, $rtnVal) = (4, '[');
+    for (;;) {
+        $rtnVal .= $cfaColor[Get8u(\$val,$pos)] || 'Unknown';
+        last if ++$pos >= $end;
+        ($pos - 4) % $ny and $rtnVal .= ',', next;
+        $rtnVal .= '][';
+    }
+    return $rtnVal . ']';
+}
+
+#------------------------------------------------------------------------------
+# translate date into standard EXIF format
+# Inputs: 0) date
+# Returns: date in format '2003:10:22'
+# - bad formats recognized: '2003-10-22','2003/10/22','2003 10 22','20031022'
+# - removes null terminator if it exists
+sub ExifDate($)
+{
+    my $date = shift;
+    $date =~ s/\0$//;       # remove any null terminator
+    # separate year:month:day with colons (instead of -, /, space or nothing)
+    $date =~ s/(\d{4})[- \/:]*(\d{2})[- \/:]*(\d{2})$/$1:$2:$3/;
+    return $date;
+}
+
+#------------------------------------------------------------------------------
+# translate time into standard EXIF format
+# Inputs: 0) time
+# Returns: time in format '10:30:55'
+# - bad formats recognized: '10 30 55', '103055', '103055+0500'
+# - removes null terminator if it exists
+# - leaves time zone intact if specified (ie. '10:30:55+05:00')
+sub ExifTime($)
+{
+    my $time = shift;
+    $time =~ tr/ /:/;   # use ':' (not ' ') as a separator
+    $time =~ s/\0$//;   # remove any null terminator
+    # add separators if they don't exist
+    $time =~ s/^(\d{2})(\d{2})(\d{2})/$1:$2:$3/;
+    $time =~ s/([+-]\d{2})(\d{2})\s*$/$1:$2/;   # to timezone too
+    return $time;
+}
+
+#------------------------------------------------------------------------------
+# extract image from file
+# Inputs: 0) ExifTool object reference, 1) data offset (in file), 2) data length
+#         3) [optional] tag name
+# Returns: Reference to Image if specifically requested or "Binary data" message
+#          Returns undef if there was an error loading the image
+sub ExtractImage($$$$)
+{
+    my ($exifTool, $offset, $len, $tag) = @_;
+    my $dataPt = \$exifTool->{EXIF_DATA};
+    my $dataPos = $exifTool->{EXIF_POS};
+    my $image;
+
+    return undef unless $len;   # no image if length is zero
+
+    # take data from EXIF block if possible
+    if (defined $dataPos and $offset>=$dataPos and $offset+$len<=$dataPos+length($$dataPt)) {
+        $image = substr($$dataPt, $offset-$dataPos, $len);
+    } else {
+        $image = $exifTool->ExtractBinary($offset, $len, $tag);
+        return undef unless defined $image;
+    }
+    return $exifTool->ValidateImage(\$image, $tag);
+}
+
+#------------------------------------------------------------------------------
+# Process EXIF directory
+# Inputs: 0) ExifTool object reference
+#         1) Reference to directory information hash
+#         2) Pointer to tag table for this directory
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+sub ProcessExif($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{DataPos} || 0;
+    my $dataLen = $$dirInfo{DataLen};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || $dataLen - $dirStart;
+    my $dirName = $$dirInfo{DirName};
+    my $base = $$dirInfo{Base} || 0;
+    my $firstBase = $base;
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->Options('Verbose');
+    my $htmlDump = $exifTool->{HTML_DUMP};
+    my $success = 1;
+    my ($tagKey, $name, $dirSize, $makerAddr);
+
+    $verbose = -1 if $htmlDump; # mix htmlDump into verbose so we can test for both at once
+    $dirName eq 'EXIF' and $dirName = $$dirInfo{DirName} = 'IFD0';
+    $$dirInfo{Multi} = 1 if $dirName eq 'IFD0' or $dirName eq 'SubIFD';
+    $htmlDump and $name = ($dirName eq 'MakerNotes') ? $$dirInfo{Name} : $dirName;
+
+    my ($numEntries, $dirEnd);
+    if ($dirStart >= 0 and $dirStart <= $dataLen-2) {
+        # make sure data is large enough (patches bug in Olympus subdirectory lengths)
+        $numEntries = Get16u($dataPt, $dirStart);
+        $dirSize = 2 + 12 * $numEntries;
+        $dirEnd = $dirStart + $dirSize;
+        if ($dirSize > $dirLen) {
+            if ($verbose > 0 and not $$dirInfo{SubIFD}) {
+                my $short = $dirSize - $dirLen;
+                $exifTool->Warn("Short directory size (missing $short bytes)");
+            }
+            undef $dirSize if $dirEnd > $dataLen; # read from file if necessary
+        }
+    }
+    # read IFD from file if necessary
+    unless ($dirSize) {
+        $success = 0;
+        if ($raf) {
+            # read the count of entries in this IFD
+            my $offset = $dirStart + $dataPos;
+            my ($buff, $buf2);
+            if ($raf->Seek($offset + $base, 0) and $raf->Read($buff,2) == 2) {
+                my $len = 12 * Get16u(\$buff,0);
+                # also read next IFD pointer if available
+                if ($raf->Read($buf2, $len+4) >= $len) {
+                    $buff .= $buf2;
+                    # make copy of dirInfo since we're going to modify it
+                    my %newDirInfo = %$dirInfo;
+                    $dirInfo = \%newDirInfo;
+                    # update directory parameters for the newly loaded IFD
+                    $dataPt = $$dirInfo{DataPt} = \$buff;
+                    $dataPos = $$dirInfo{DataPos} = $offset;
+                    $dataLen = $$dirInfo{DataLen} = length $buff;
+                    $dirStart = $$dirInfo{DirStart} = 0;
+                    $success = 1;
+                }
+            }
+        }
+        unless ($success) {
+            $exifTool->Warn("Bad $dirName directory");
+            return 0;
+        }
+        $numEntries = Get16u($dataPt, $dirStart);
+        $dirSize = 2 + 12 * $numEntries;
+        $dirEnd = $dirStart + $dirSize;
+    }
+    $verbose > 0 and $exifTool->VerboseDir($dirName, $numEntries);
+    my $bytesFromEnd = $dataLen - $dirEnd;
+    if ($bytesFromEnd < 4) {
+        unless ($bytesFromEnd==2 or $bytesFromEnd==0) {
+            $exifTool->Warn(sprintf"Illegal $dirName directory size (0x%x entries)",$numEntries);
+            return 0;
+        }
+    }
+    # fix base offset for maker notes if necessary
+    if (defined $$dirInfo{MakerNoteAddr}) {
+        $makerAddr = $$dirInfo{MakerNoteAddr};
+        delete $$dirInfo{MakerNoteAddr};
+        if (Image::ExifTool::MakerNotes::FixBase($exifTool, $dirInfo)) {
+            $base = $$dirInfo{Base};
+            $dataPos = $$dirInfo{DataPos};
+        }
+    }
+    if ($htmlDump) {
+        if (defined $makerAddr) {
+            my $hdrLen = $dirStart + $dataPos + $base - $makerAddr;
+            $exifTool->HtmlDump($makerAddr, $hdrLen, "MakerNotes header", $name) if $hdrLen > 0;
+        }
+        $exifTool->HtmlDump($dirStart + $dataPos + $base, 2, "$name entries",
+                 "Entry count: $numEntries");
+        my $tip;
+        if ($bytesFromEnd >= 4) {
+            my $nxt = ($name =~ /^IFD(\d+)/) ? "IFD" . ($1 + 1) : 'Next IFD';
+            $tip = sprintf("$nxt offset: 0x%.4x", Get32u($dataPt, $dirEnd));
+        }
+        $exifTool->HtmlDump($dirEnd + $dataPos + $base, 4, "Next IFD", $tip, 0);
+        $name = $dirName if $name =~ /^MakerNote/;
+    }
+
+    # loop through all entries in an EXIF directory (IFD)
+    my ($index, $valEnd);
+    for ($index=0; $index<$numEntries; ++$index) {
+        my $entry = $dirStart + 2 + 12 * $index;
+        my $tagID = Get16u($dataPt, $entry);
+        my $format = Get16u($dataPt, $entry+2);
+        my $count = Get32u($dataPt, $entry+4);
+        if ($format < 1 or $format > 13) {
+            $exifTool->HtmlDump($entry+$dataPos+$base,12,"[invalid IFD entry]",
+                     "Bad format type: $format", 1);
+            # warn unless the IFD was just padded with zeros
+            $format and $exifTool->Warn(
+                sprintf("Unknown format ($format) for $dirName tag 0x%x",$tagID));
+            return 0 unless $index; # assume corrupted IFD if this is our first entry
+            next;
+        }
+        my $formatStr = $formatName[$format];   # get name of this format
+        my $size = $count * $formatSize[$format];
+        my $valueDataPt = $dataPt;
+        my $valueDataPos = $dataPos;
+        my $valueDataLen = $dataLen;
+        my $valuePtr = $entry + 8;      # pointer to value within $$dataPt
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+        if ($size > 4) {
+            if ($size > 0x7fffffff) {
+                $exifTool->Warn(sprintf("Invalid size ($size) for $dirName tag 0x%x",$tagID));
+                next;
+            }
+            $valuePtr = Get32u($dataPt, $valuePtr);
+            # fix valuePtr if necessary
+            if ($$dirInfo{FixOffsets}) {
+                my $wFlag;
+                $valEnd or $valEnd = $dataPos + $dirEnd + 4;
+                #### eval FixOffsets($valuePtr, $valEnd, $size, $tagID, $wFlag)
+                eval $$dirInfo{FixOffsets};
+            }
+            # convert offset to pointer in $$dataPt
+            if ($$dirInfo{EntryBased} or (ref $$tagTablePtr{$tagID} eq 'HASH' and
+                $tagTablePtr->{$tagID}->{EntryBased}))
+            {
+                $valuePtr += $entry;
+            } else {
+                $valuePtr -= $dataPos;
+            }
+            if ($valuePtr < 0 or $valuePtr+$size > $dataLen) {
+                # get value by seeking in file if we are allowed
+                my $buff;
+                if ($raf) {
+                    if ($raf->Seek($base + $valuePtr + $dataPos,0) and
+                        $raf->Read($buff,$size) == $size)
+                    {
+                        $valueDataPt = \$buff;
+                        $valueDataPos = $valuePtr + $dataPos;
+                        $valueDataLen = $size;
+                        $valuePtr = 0;
+                    } else {
+                        $exifTool->Warn("Error reading value for $dirName entry $index");
+                        return 0;
+                    }
+                } else {
+                    my $tagStr;
+                    if ($tagInfo) {
+                        $tagStr = $$tagInfo{Name};
+                    } elsif (defined $tagInfo) {
+                        my $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \ '', $formatStr, $count);
+                        $tagStr = $$tmpInfo{Name} if $tmpInfo;
+                    }
+                    $tagStr or $tagStr = sprintf("tag 0x%x",$tagID);
+                    # allow PreviewImage to run outside EXIF data
+                    if ($tagStr eq 'PreviewImage' and $exifTool->{RAF}) {
+                        my $pos = $exifTool->{RAF}->Tell();
+                        $buff = $exifTool->ExtractBinary($base + $valuePtr + $dataPos, $size, 'PreviewImage');
+                        $exifTool->{RAF}->Seek($pos, 0);
+                        $valueDataPt = \$buff;
+                        $valueDataPos = $valuePtr + $dataPos;
+                        $valueDataLen = $size;
+                        $valuePtr = 0;
+                    } else {
+                        $exifTool->Warn("Bad $dirName directory pointer for $tagStr");
+                    }
+                    unless (defined $buff) {
+                        next unless $htmlDump and $size < 1000000;
+                        $valueDataPt = \ (' ' x $size);
+                        $valueDataPos = $valuePtr + $dataPos;
+                        $valueDataLen = -1; # flag the bad pointer
+                        $valuePtr = 0;
+                    }
+                }
+            }
+        }
+        # treat single unknown byte as int8u
+        $formatStr = 'int8u' if $format == 7 and $count == 1;
+
+        my $val;
+        if ($tagID > 0xf000 and not $$tagTablePtr{$tagID}
+            and $tagTablePtr eq \%Image::ExifTool::Exif::Main)
+        {
+            # handle special case of Photoshop RAW tags (0xfde8-0xfe58)
+            # --> generate tags from the value if possible
+            $val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$size);
+            if (defined $val and $val =~ /(.*): (.*)/) {
+                my $tag = $1;
+                $val = $2;
+                $tag =~ s/'s//; # remove 's (so "Owner's Name" becomes "OwnerName")
+                $tag =~ tr/a-zA-Z0-9_//cd; # remove unknown characters
+                if ($tag) {
+                    $tagInfo = {
+                        Name => $tag,
+                        ValueConv => '$_=$val;s/.*: //;$_', # remove descr
+                    };
+                    Image::ExifTool::AddTagToTable($tagTablePtr, $tagID, $tagInfo);
+                }
+            }
+        }
+        if (defined $tagInfo and not $tagInfo) {
+            # GetTagInfo() required the value for a Condition
+            my $tmpVal = substr($$valueDataPt, $valuePtr, $size < 48 ? $size : 48);
+            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$tmpVal, $formatStr, $count);
+        }
+        # override EXIF format if specified
+        my $origFormStr;
+        if (defined $tagInfo) {
+            if ($$tagInfo{Format}) {
+                $formatStr = $$tagInfo{Format};
+                # must adjust number of items for new format size
+                my $newNum = $formatNumber{$formatStr};
+                if ($newNum) {
+                    $origFormStr = $formatName[$format] . '[' . $count . ']';
+                    $format = $newNum;
+                    $count = $size / $formatSize[$format];
+                }
+            }
+        } else {
+            next unless $verbose;
+        }
+        # convert according to specified format
+        $val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$size);
+
+        if ($verbose) {
+            if ($htmlDump) {
+                my ($tagName, $colName);
+                if ($tagID == 0x927c and $dirName eq 'ExifIFD') {
+                    $tagName = 'MakerNotes';
+                } elsif ($tagInfo) {
+                    $tagName = $$tagInfo{Name};
+                } else {
+                    $tagName = sprintf("Tag 0x%.4x",$tagID);
+                }
+                my $dname = sprintf("${name}-%.2d", $index);
+                # build our tool tip
+                $size < 0 and $size = $count * $formatSize[$format];
+                my $tip = sprintf("Tag ID: 0x%.4x\\n", $tagID) .
+                          "Format: $formatName[$format]\[$count]\\nSize: $size bytes\\n";
+                if ($size > 4) {
+                    my $offPt = Get32u($dataPt,$entry+8);
+                    $tip .= sprintf("Value offset: 0x%.4x\\n", $offPt);
+                    my $actPt = $valuePtr + $valueDataPos + $base - ($$exifTool{EXIF_POS} || 0);
+                    # highlight tag name (red for bad size)
+                    my $style = ($valueDataLen < 0) ? 'V' : 'H';
+                    if ($actPt != $offPt) {
+                        $tip .= sprintf("Actual offset: 0x%.4x\\n", $actPt);
+                        $style = 'F' if $style eq 'H';  # purple for different offsets
+                    }
+                    $colName = "<span class=$style>$tagName</span>";
+                } else {
+                    $colName = $tagName;
+                }
+                my $tval;
+                if ($valueDataLen < 0) {
+                    $tval = '<bad offset>';
+                } else {
+                    $tval = (length $val < 32) ? $val : substr($val,0,28) . '[...]';
+                    if ($formatStr =~ /^(string|undef|binary)/) {
+                        # translate all characters that could mess up JavaScript
+                        $tval =~ tr/\\\x00-\x1f\x7f-\xff/./;
+                        $tval =~ tr/"/'/;
+                        $tval = "$tval";
+                    } elsif ($tagInfo and Image::ExifTool::IsInt($tval)) {
+                        if ($$tagInfo{IsOffset}) {
+                            $tval = sprintf('0x%.4x', $tval);
+                        } elsif ($$tagInfo{PrintHex}) {
+                            $tval = sprintf('0x%x', $tval);
+                        }
+                    }
+                }
+                $tip .= "Value: $tval";
+                $exifTool->HtmlDump($entry+$dataPos+$base, 12, "$dname $colName", $tip, 1);
+                next if $valueDataLen < 0;  # don't process bad pointer entry
+                if ($size > 4) {
+                    my $exifDumpPos = $valuePtr + $valueDataPos + $base;
+                    # add value data block (underlining maker notes data)
+                    $exifTool->HtmlDump($exifDumpPos,$size,"$tagName value",'SAME',
+                        ($tagInfo and $$tagInfo{SubDirectory} and
+                        ($$tagInfo{MakerNotes} or $$tagInfo{DNGMakerNotes})) ? 4 : 0);
+                }
+            } else {
+                my $fstr = $formatName[$format];
+                $origFormStr and $fstr = "$origFormStr read as $fstr";
+                $exifTool->VerboseInfo($tagID, $tagInfo,
+                    Table   => $tagTablePtr,
+                    Index   => $index,
+                    Value   => $val,
+                    DataPt  => $valueDataPt,
+                    DataPos => $valueDataPos + $base,
+                    Size    => $size,
+                    Start   => $valuePtr,
+                    Format  => $fstr,
+                    Count   => $count,
+                );
+            }
+            next unless $tagInfo;
+        }
+#..............................................................................
+# Handle SubDirectory tag types
+#
+        my $subdir = $$tagInfo{SubDirectory};
+        if ($subdir) {
+            my (@values, $newTagTable, $dirNum, $newByteOrder, $invalid);
+            my $tagStr = $$tagInfo{Name};
+            if ($$subdir{MaxSubdirs}) {
+                @values = split ' ', $val;
+                # limit the number of subdirectories we parse
+                my $over = @values - $$subdir{MaxSubdirs};
+                if ($over > 0) {
+                    $exifTool->Warn("Ignoring $over $tagStr directories");
+                    pop @values while $over--;
+                }
+                $val = shift @values;
+            }
+            if ($$subdir{TagTable}) {
+                $newTagTable = GetTagTable($$subdir{TagTable});
+                $newTagTable or warn("Unknown tag table $$subdir{TagTable}"), next;
+            } else {
+                $newTagTable = $tagTablePtr;    # use existing table
+            }
+            # loop through all sub-directories specified by this tag
+            for ($dirNum=0; ; ++$dirNum) {
+                my $subdirBase = $base;
+                my $subdirDataPt = $valueDataPt;
+                my $subdirDataPos = $valueDataPos;
+                my $subdirDataLen = $valueDataLen;
+                my $subdirStart = $valuePtr;
+                if (defined $$subdir{Start}) {
+                    # set local $valuePtr relative to file $base for eval
+                    my $valuePtr = $subdirStart + $subdirDataPos;
+                    #### eval Start ($valuePtr, $val)
+                    my $newStart = eval($$subdir{Start});
+                    unless (Image::ExifTool::IsInt($newStart)) {
+                        $exifTool->Warn("Bad value for $tagStr");
+                        last;
+                    }
+                    # convert back to relative to $subdirDataPt
+                    $newStart -= $subdirDataPos;
+                    # must adjust directory size if start changed
+                    $size -= $newStart - $subdirStart unless $$subdir{BadOffset};
+                    $subdirStart = $newStart;
+                }
+                # this is a pain, but some maker notes are always a specific
+                # byte order, regardless of the byte order of the file
+                my $oldByteOrder = GetByteOrder();
+                $newByteOrder = $$subdir{ByteOrder};
+                if ($newByteOrder) {
+                    if ($newByteOrder =~ /^Little/i) {
+                        $newByteOrder = 'II';
+                    } elsif ($newByteOrder =~ /^Big/i) {
+                        $newByteOrder = 'MM';
+                    } elsif ($$subdir{OffsetPt}) {
+                        undef $newByteOrder;
+                        warn "Can't have variable byte ordering for SubDirectories using OffsetPt";
+                        last;
+                    } elsif ($subdirStart + 2 <= $subdirDataLen) {
+                        # attempt to determine the byte ordering by checking
+                        # at the number of directory entries.  This is an int16u
+                        # that should be a reasonable value.
+                        my $num = Get16u($subdirDataPt, $subdirStart);
+                        if ($num & 0xff00 and ($num>>8) > ($num&0xff)) {
+                            # This looks wrong, we shouldn't have this many entries
+                            my %otherOrder = ( II=>'MM', MM=>'II' );
+                            $newByteOrder = $otherOrder{$oldByteOrder};
+                        } else {
+                            $newByteOrder = $oldByteOrder;
+                        }
+                    }
+                } else {
+                    $newByteOrder = $oldByteOrder;
+                }
+                # set base offset if necessary
+                if ($$subdir{Base}) {
+                    # calculate subdirectory start relative to $base for eval
+                    my $start = $subdirStart + $subdirDataPos;
+                    #### eval Base ($start)
+                    $subdirBase = eval($$subdir{Base}) + $base;
+                }
+                # add offset to the start of the directory if necessary
+                if ($$subdir{OffsetPt}) {
+                    #### eval OffsetPt ($valuePtr)
+                    my $pos = eval $$subdir{OffsetPt};
+                    if ($pos + 4 > $subdirDataLen) {
+                        $exifTool->Warn("Bad $tagStr OffsetPt");
+                        last;
+                    }                    
+                    SetByteOrder($newByteOrder);
+                    $subdirStart += Get32u($subdirDataPt, $pos);
+                    SetByteOrder($oldByteOrder);
+                }
+                if ($subdirStart < 0 or $subdirStart + 2 > $subdirDataLen) {
+                    # convert $subdirStart back to a file offset
+                    $subdirStart += $subdirDataPos;
+                    my $dirOK;
+                    if ($raf) {
+                        # read the directory from the file
+                        if ($raf->Seek($subdirStart + $base,0)) {
+                            my ($buff, $buf2);
+                            if ($raf->Read($buff,2) == 2) {
+                                # get no. dir entries
+                                $size = 12 * Get16u(\$buff, 0);
+                                # read dir (plus next IFD pointer)
+                                if ($raf->Read($buf2,$size+4) >= $size) {
+                                    # set up variables to process new subdir data
+                                    $buff .= $buf2;
+                                    $size = length $buff;
+                                    $subdirDataPt = \$buff;
+                                    $subdirDataPos = $subdirStart;
+                                    $subdirDataLen = $size;
+                                    $subdirStart = 0;
+                                    $dirOK = 1;
+                                }
+                            }
+                        }
+                    }
+                    unless ($dirOK) {
+                        my $msg = "Bad $tagStr SubDirectory start";
+                        if ($verbose > 0) {
+                            if ($subdirStart < 0) {
+                                $msg .= " (directory start $subdirStart is before EXIF start)";
+                            } else {
+                                my $end = $subdirStart + $size;
+                                $msg .= " (directory end is $end but EXIF size is only $subdirDataLen)";
+                            }
+                        }
+                        $exifTool->Warn($msg);
+                        last;
+                    }
+                }
+
+                # must update subdirDataPos if $base changes for this subdirectory
+                $subdirDataPos += $base - $subdirBase;
+
+                # build information hash for new directory
+                my %subdirInfo = (
+                    Name       => $tagStr,
+                    Base       => $subdirBase,
+                    DataPt     => $subdirDataPt,
+                    DataPos    => $subdirDataPos,
+                    DataLen    => $subdirDataLen,
+                    DirStart   => $subdirStart,
+                    DirLen     => $size,
+                    RAF        => $raf,
+                    Parent     => $dirName,
+                    FixBase    => $$subdir{FixBase},
+                    FixOffsets => $$subdir{FixOffsets},
+                    EntryBased => $$subdir{EntryBased},
+                    TagInfo    => $tagInfo,
+                    SubIFD     => $$tagInfo{SubIFD},
+                );
+                if ($$tagInfo{MakerNotes}) {
+                    $subdirInfo{MakerNoteAddr} = $valuePtr + $valueDataPos + $base;
+                    $subdirInfo{NoFixBase} = 1 if $$subdir{Base};
+                }
+                # some Pentax cameras (Optio 330) write maker notes in IFD0
+                # set directory IFD name from group name of family 1 in tag information if it exists
+                if ($$tagInfo{Groups}) {
+                    $subdirInfo{DirName} = $tagInfo->{Groups}->{1};
+                    # number multiple subdirectories
+                    $dirNum and $subdirInfo{DirName} .= $dirNum;
+                }
+                SetByteOrder($newByteOrder);    # set byte order for this subdir
+                # validate the subdirectory if necessary
+                my $dirData = $subdirDataPt;    # set data pointer to be used in eval
+                #### eval Validate ($val, $dirData, $subdirStart, $size)
+                my $ok = 0;
+                if (defined $$subdir{Validate} and not eval $$subdir{Validate}) {
+                    $exifTool->Warn("Invalid $tagStr data");
+                    $invalid = 1;
+                } else {
+                    # process the subdirectory
+                    $ok = $exifTool->ProcessDirectory(\%subdirInfo, $newTagTable, $$subdir{ProcessProc});
+                }
+                # print debugging information if there were errors
+                if (not $ok and $verbose > 1 and $subdirStart != $valuePtr) {
+                    my $out = $exifTool->Options('TextOut');
+                    printf $out "%s    (SubDirectory start = 0x%x)\n", $exifTool->{INDENT}, $subdirStart;
+                }
+                SetByteOrder($oldByteOrder);    # restore original byte swapping
+
+                @values or last;
+                $val = shift @values;           # continue with next subdir
+            }
+            my $doMaker = $exifTool->Options('MakerNotes');
+            next unless $doMaker or $exifTool->{REQ_TAG_LOOKUP}->{lc($tagStr)};
+            # extract as a block if specified
+            if ($$tagInfo{MakerNotes}) {
+                # save maker note byte order (if it was significant and valid)
+                if ($$subdir{ByteOrder} and not $invalid) {
+                    $exifTool->{MAKER_NOTE_BYTE_ORDER} = 
+                        defined ($exifTool->{UnknownByteOrder}) ? 
+                                 $exifTool->{UnknownByteOrder} : $newByteOrder;
+                }
+                if ($doMaker and $doMaker eq '2') {
+                    # extract maker notes without rebuilding (no fixup information)
+                    delete $exifTool->{MAKER_NOTE_FIXUP};
+                } elsif (not $$tagInfo{NotIFD}) {
+                    # this is a pain, but we must rebuild EXIF-typemaker notes to
+                    # include all the value data if data was outside the maker notes
+                    my %makerDirInfo = (
+                        Name       => $tagStr,
+                        Base       => $base,
+                        DataPt     => $valueDataPt,
+                        DataPos    => $valueDataPos,
+                        DataLen    => $valueDataLen,
+                        DirStart   => $valuePtr,
+                        DirLen     => $size,
+                        RAF        => $raf,
+                        Parent     => $dirName,
+                        DirName    => 'MakerNotes',
+                        FixOffsets => $$subdir{FixOffsets},
+                        TagInfo    => $tagInfo,
+                    );
+                    $makerDirInfo{FixBase} = 1 if $$subdir{FixBase};
+                    # rebuild maker notes (creates $exifTool->{MAKER_NOTE_FIXUP})
+                    my $val2 = RebuildMakerNotes($exifTool, $newTagTable, \%makerDirInfo);
+                    if (defined $val2) {
+                        $val = $val2;
+                    } else {
+                        $exifTool->Warn('Error rebuilding maker notes (may be corrupt)');
+                    }
+                }
+            } else {
+                # extract this directory as a block if specified
+                next unless $$tagInfo{Writable};
+            }
+        }
+ #..............................................................................
+        # convert to absolute offsets if this tag is an offset
+        if ($$tagInfo{IsOffset}) {
+            my $offsetBase = $$tagInfo{IsOffset} eq '2' ? $firstBase : $base;
+            $offsetBase += $$exifTool{BASE};
+            my @vals = split(' ',$val);
+            foreach $val (@vals) {
+                $val += $offsetBase;
+            }
+            $val = join(' ', @vals);
+        }
+        # save the value of this tag
+        $tagKey = $exifTool->FoundTag($tagInfo, $val);
+        # set the group 1 name for tags in main table
+        if (defined $tagKey and $tagTablePtr eq \%Image::ExifTool::Exif::Main) {
+            $exifTool->SetGroup1($tagKey, $dirName);
+        }
+    }
+
+    # scan for subsequent IFD's if specified
+    if ($$dirInfo{Multi} and $bytesFromEnd >= 4) {
+        my $offset = Get32u($dataPt, $dirEnd);
+        if ($offset) {
+            my $subdirStart = $offset - $dataPos;
+            # use same directory information for trailing directory,
+            # but change the start location (ProcessDirectory will
+            # test to make sure we don't reprocess the same dir twice)
+            my %newDirInfo = %$dirInfo;
+            $newDirInfo{DirStart} = $subdirStart;
+            # increment IFD number
+            $newDirInfo{DirName} =~ s/(\d+)$//;
+            $newDirInfo{DirName} .= ($1 || 0) + 1;
+            # must validate SubIFD1 because the nextIFD pointer is invalid for some RAW formats
+            if ($newDirInfo{DirName} ne 'SubIFD1' or ValidateIFD(\%newDirInfo)) {
+                $exifTool->{INDENT} =~ s/..$//; # keep indent the same
+                $exifTool->ProcessDirectory(\%newDirInfo, $tagTablePtr) or $success = 0;
+            } elsif ($verbose or $exifTool->{TIFF_TYPE} eq 'TIFF') {
+                $exifTool->Warn('Ignored bad IFD linked from SubIFD');
+            }
+        }
+    }
+    return $success;
+}
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Exif - Read EXIF meta information
+
+=head1 SYNOPSIS
+
+This module is required by Image::ExifTool.
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool for processing
+EXIF meta information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.exif.org/Exif2-2.PDF>
+
+=item L<http://partners.adobe.com/asn/developer/pdfs/tn/TIFF6.pdf>
+
+=item L<http://partners.adobe.com/public/developer/en/tiff/TIFFPM6.pdf>
+
+=item L<http://www.adobe.com/products/dng/pdfs/dng_spec.pdf>
+
+=item L<http://www.awaresystems.be/imaging/tiff/tifftags.html>
+
+=item L<http://www.remotesensing.org/libtiff/TIFFTechNote2.html>
+
+=item L<http://www.asmail.be/msg0054681802.html>
+
+=item L<http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html>
+
+=item L<http://www.fine-view.com/jp/lab/doc/ps6ffspecsv2.pdf>
+
+=item L<http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html>
+
+=item L<http://hul.harvard.edu/jhove/tiff-tags.html>
+
+=item L<http://www.microsoft.com/whdc/xps/wmphoto.mspx>
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Matt Madrid for his help with the XP character code conversions.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/EXIF Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/FLAC.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/FLAC.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/FLAC.pm	(revision 20131)
@@ -0,0 +1,235 @@
+#------------------------------------------------------------------------------
+# File:         FLAC.pm
+#
+# Description:  Read Free Lossless Audio Codec information
+#
+# Revisions:    11/13/2006 - P. Harvey Created
+#
+# References:   1) http://flac.sourceforge.net/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::FLAC;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.00';
+
+sub ProcessBitStream($$$);
+
+# FLAC metadata blocks
+%Image::ExifTool::FLAC::Main = (
+    NOTES => q{
+        Free Lossless Audio Codec (FLAC) meta information.  ExifTool also extracts
+        ID3 information from these files.
+    },
+    0 => {
+        Name => 'StreamInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLAC::StreamInfo' },
+    },
+    4 => {
+        Name => 'VorbisComment',
+        SubDirectory => { TagTable => 'Image::ExifTool::Vorbis::Comments' },
+    },
+);
+
+%Image::ExifTool::FLAC::StreamInfo = (
+    PROCESS_PROC => \&ProcessBitStream,
+    NOTES => 'FLAC is big-endian, so bit 0 is the high-order bit in this table.',
+    GROUPS => { 2 => 'Audio' },
+    'Bit000-015' => 'BlockSizeMin',
+    'Bit016-031' => 'BlockSizeMax',
+    'Bit032-055' => 'FrameSizeMin',
+    'Bit056-079' => 'FrameSizeMax',
+    'Bit080-099' => 'SampleRate',
+    'Bit100-102' => {
+        Name => 'Channels',
+        ValueConv => '$val + 1',
+    },
+    'Bit103-107' => {
+        Name => 'BitsPerSample',
+        ValueConv => '$val + 1',
+    },
+    'Bit108-143' => 'TotalSamples',
+);
+
+# FLAC composite tags
+%Image::ExifTool::FLAC::Composite = (
+    Duration => {
+        Require => {
+            0 => 'FLAC:SampleRate',
+            1 => 'FLAC:Channels',
+            2 => 'FLAC:TotalSamples',
+        },
+        ValueConv => '$val[0] and $val[1] and $val[2] ? $val[2] / ($val[0] * $val[1]) : undef',
+        PrintConv => 'sprintf("%.2fs",$val)',
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::FLAC');
+
+
+#------------------------------------------------------------------------------
+# Process information in a bit stream
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Notes: Byte order is used to determine the ordering of bits in the stream:
+# 'MM' = bit 0 is most significant, 'II' = bit 0 is least significant
+# - can handle arbitrarily wide values (ie. 8-byte or larger integers)
+sub ProcessBitStream($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt   = $$dirInfo{DataPt};
+    my $dataPos  = $$dirInfo{DataPos};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen   = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
+    my $verbose  = $exifTool->Options('Verbose');
+    my $byteOrder = GetByteOrder();
+    my $tag;
+
+    if ($verbose) {
+        $exifTool->VPrint(0, "  + [BitStream directory, $dirLen bytes, '$byteOrder' order]\n");
+    }
+    foreach $tag (sort keys %$tagTablePtr) {
+        next unless $tag =~ /^Bit(\d+)-?(\d+)?/;
+        my ($b1, $b2) = ($1, $2 || $1);     # start/end bit numbers in stream
+        my ($i1, $i2) = (int($b1 / 8), int($b2 / 8)); # start/end byte numbers
+        my ($f1, $f2) = ($b1 % 8, $b2 % 8); # start/end bit numbers within each byte
+        last if $i2 >= $dirLen;
+        my $val = 0;
+        my ($i, $mask, $extra);
+        $extra = ', Mask=0x' if $verbose and ($f1 != 0 or $f2 != 7);
+        if ($byteOrder eq 'MM') {
+            # loop from high byte to low byte
+            for ($i=$i1; $i<=$i2; ++$i) {
+                $mask = 0xff;
+                if ($i == $i1 and $f1) {
+                    # mask off high bits in first word (0 is high bit)
+                    foreach ((8-$f1) .. 7) { $mask ^= (1 << $_) }
+                }
+                if ($i == $i2 and $f2 < 7) {
+                    # mask off low bits in last word (7 is low bit)
+                    foreach (0 .. (6-$f2)) { $mask ^= (1 << $_) }
+                }
+                $val = $val * 256 + ($mask & Get8u($dataPt, $i + $dirStart));
+                $extra .= sprintf('%.2x', $mask) if $extra;
+            }
+        } else {
+            # (FLAC is big-endian, but support little-endian bit streams
+            #  so this routine can be used by other modules)
+            # loop from high byte to low byte
+            for ($i=$i2; $i>=$i1; --$i) {
+                $mask = 0xff;
+                if ($i == $i1 and $f1) {
+                    # mask off low bits in first word (0 is low bit)
+                    foreach (0 .. ($f1-1)) { $mask ^= (1 << $_) }
+                }
+                if ($i == $i2 and $f2 < 7) {
+                    # mask off high bits in last word (7 is high bit)
+                    foreach (($f2+1) .. 7) { $mask ^= (1 << $_) }
+                }
+                $val = $val * 256 + ($mask & Get8u($dataPt, $i + $dirStart));
+                $extra .= sprintf('%.2x', $mask) if $extra;
+            }
+        }
+        # shift word down until low bit is in position 0
+        until ($mask & 0x01) {
+            $val /= 2;
+            $mask >>= 1;
+        }
+        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            DataPt  => $dataPt,
+            DataPos => $dataPos,
+            Start   => $dirStart + $i1,
+            Size    => $i2 - $i1 + 1,
+            Extra   => $extra,
+        );
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Extract information from an Ogg FLAC file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid Ogg FLAC file
+sub ProcessFLAC($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+
+    # must first check for leading/trailing ID3 information
+    unless ($exifTool->{DONE_ID3}) {
+        require Image::ExifTool::ID3;
+        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
+    }
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my ($buff, $err);
+
+    # check FLAC signature
+    $raf->Read($buff, 4) == 4 and $buff eq 'fLaC' or return 0;
+    $exifTool->SetFileType() unless $exifTool->{VALUE}->{FileType};
+    SetByteOrder('MM');
+    my $tagTablePtr = GetTagTable('Image::ExifTool::FLAC::Main');
+    for (;;) {
+        # read next metadata block header
+        $raf->Read($buff, 4) == 4 or last;
+        my $flag = unpack('C', $buff);
+        my $size = unpack('N', $buff) & 0x00ffffff;
+        $raf->Read($buff, $size) == $size or $err = 1, last;
+        my $last = $flag & 0x80;    # last-metadata-block flag
+        my $tag  = $flag & 0x7f;    # tag bits
+        if ($verbose) {
+            print $out "FLAC metadata block, type $tag:\n";
+            $exifTool->VerboseDump(\$buff, DataPos => $raf->Tell() - $size);
+        }
+        $exifTool->HandleTag($tagTablePtr, $tag, undef,
+            DataPt  => \$buff,
+            DataPos => $raf->Tell() - $size,
+        );
+        last if $last;   # all done if  is set
+    }
+    $err and $exifTool->Warn('Format error in FLAC file');
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::FLAC - Read Free Lossless Audio Codec information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to extract meta
+information from Free Lossless Audio Codec (FLAC) audio files.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://flac.sourceforge.net/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/FLAC Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Fixup.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Fixup.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Fixup.pm	(revision 20131)
@@ -0,0 +1,333 @@
+#------------------------------------------------------------------------------
+# File:         Fixup.pm
+#
+# Description:  Utility to handle pointer fixups
+#
+# Revisions:    01/19/2005 - P. Harvey Created
+#               04/11/2005 - P. Harvey Allow fixups to be tagged with a marker,
+#                            and add new marker-related routines
+#               06/21/2006 - P. Harvey Patch to work with negative offsets
+#               07/07/2006 - P. Harvey Added support for 16-bit pointers
+#
+# Data Members:
+#
+#   Start     - Position in data where a zero pointer points to.
+#   Shift     - Amount to shift offsets (relative to Start).
+#   Fixups    - List of Fixup object references to to shift relative to this Fixup.
+#   Pointers  - Hash of references to fixup pointer arrays, keyed by ByteOrder
+#               string (with "2" added if pointer is 16-bit [default is 32-bit],
+#               plus "_$marker" suffix if tagged with a marker name).
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Fixup;
+
+use strict;
+use Image::ExifTool qw(GetByteOrder SetByteOrder Get32u Get32s Set32u
+                       Get16u Get16s Set16u);
+use vars qw($VERSION);
+
+$VERSION = '1.04';
+
+sub AddFixup($$;$$);
+sub ApplyFixup($$);
+sub Dump($;$);
+
+#------------------------------------------------------------------------------
+# New - create new Fixup object
+# Inputs: 0) reference to Fixup object or Fixup class name
+sub new
+{
+    local $_;
+    my $that = shift;
+    my $class = ref($that) || $that || 'Image::ExifTool::Fixup';
+    my $self = bless {}, $class;
+
+    # initialize required members
+    $self->{Start} = 0;
+    $self->{Shift} = 0;
+
+    return $self;
+}
+
+#------------------------------------------------------------------------------
+# Clone this object
+# Inputs: 0) reference to Fixup object or Fixup class name
+# Returns: reference to new Fixup object
+sub Clone($)
+{
+    my $self = shift;
+    my $clone = new Image::ExifTool::Fixup;
+    $clone->{Start} = $self->{Start};
+    $clone->{Shift} = $self->{Shift};
+    my $phash = $self->{Pointers};
+    if ($phash) {
+        $clone->{Pointers} = { };
+        my $byteOrder;
+        foreach $byteOrder (keys %$phash) {
+            my @pointers = @{$phash->{$byteOrder}};
+            $clone->{Pointers}->{$byteOrder} = \@pointers;
+        }
+    }
+    if ($self->{Fixups}) {
+        $clone->{Fixups} = [ ];
+        my $subFixup;
+        foreach $subFixup (@{$self->{Fixups}}) {
+            push @{$clone->{Fixups}}, $subFixup->Clone();
+        }
+    }
+    return $clone;
+}
+
+#------------------------------------------------------------------------------
+# Add fixup pointer or another fixup object below this one
+# Inputs: 0) Fixup object reference
+#         1) Scalar for pointer offset, or reference to Fixup object
+#         2) Optional marker name for the pointer
+#         3) Optional pointer format ('int16u' or 'int32u', defaults to 'int32u')
+# Notes: Byte ordering must be set properly for the pointer being added (must keep
+# track of the byte order of each offset since MakerNotes may have different byte order!)
+sub AddFixup($$;$$)
+{
+    my ($self, $pointer, $marker, $format) = @_;
+    if (ref $pointer) {
+        $self->{Fixups} or $self->{Fixups} = [ ];
+        push @{$self->{Fixups}}, $pointer;
+    } else {
+        my $byteOrder = GetByteOrder();
+        if (defined $format) {
+            if ($format eq 'int16u') {
+                $byteOrder .= '2';
+            } elsif ($format ne 'int32u') {
+                warn "Bad Fixup pointer format $format\n";
+            }
+        }
+        $byteOrder .= "_$marker" if defined $marker;
+        my $phash = $self->{Pointers};
+        $phash or $phash = $self->{Pointers} = { };
+        $phash->{$byteOrder} or $phash->{$byteOrder} = [ ];
+        push @{$phash->{$byteOrder}}, $pointer;
+    }
+}
+
+#------------------------------------------------------------------------------
+# fix up pointer offsets
+# Inputs: 0) Fixup object reference, 1) data reference
+# Outputs: Collapses fixup hierarchy into linear lists of fixup pointers
+sub ApplyFixup($$)
+{
+    my ($self, $dataPt) = @_;
+
+    my $start = $self->{Start};
+    my $shift = $self->{Shift} + $start;   # make shift relative to start
+    my $phash = $self->{Pointers};
+
+    # fix up pointers in this fixup
+    if ($phash and ($start or $shift)) {
+        my $saveOrder = GetByteOrder(); # save original byte ordering
+        my ($byteOrder, $ptr);
+        foreach $byteOrder (keys %$phash) {
+            SetByteOrder(substr($byteOrder,0,2));
+            # apply the fixup offset shift (must get as signed integer
+            # to avoid overflow in case it was negative before)
+            my ($get, $set) = ($byteOrder =~ /^(II2|MM2)/) ?
+                              (\&Get16s, \&Set16u) : (\&Get32s, \&Set32u);
+            foreach $ptr (@{$phash->{$byteOrder}}) {
+                $ptr += $start;         # update pointer to new start location
+                next unless $shift;
+                &$set(&$get($dataPt, $ptr) + $shift, $dataPt, $ptr);
+            }
+        }
+        SetByteOrder($saveOrder);       # restore original byte ordering
+    }
+    # recurse into contained fixups
+    if ($self->{Fixups}) {
+        # create our pointer hash if it doesn't exist
+        $phash or $phash = $self->{Pointers} = { };
+        # loop through all contained fixups
+        my $subFixup;
+        foreach $subFixup (@{$self->{Fixups}}) {
+            # adjust the subfixup start and shift
+            $subFixup->{Start} += $start;
+            $subFixup->{Shift} += $shift - $start;
+            # recursively apply contained fixups
+            ApplyFixup($subFixup, $dataPt);
+            my $shash = $subFixup->{Pointers} or next;
+            # add all pointers to our collapsed lists
+            my $byteOrder;
+            foreach $byteOrder (keys %$shash) {
+                $phash->{$byteOrder} or $phash->{$byteOrder} = [ ];
+                push @{$phash->{$byteOrder}}, @{$shash->{$byteOrder}};
+                delete $shash->{$byteOrder};
+            }
+            delete $subFixup->{Pointers};
+        }
+        delete $self->{Fixups};    # remove our contained fixups
+    }
+    # reset our Start/Shift for the collapsed fixup
+    $self->{Start} = $self->{Shift} = 0;
+}
+
+#------------------------------------------------------------------------------
+# Does specified marker exist?
+# Inputs: 0) Fixup object reference, 1) marker name
+# Returns: True if fixup contains specified marker name
+sub HasMarker($$)
+{
+    my ($self, $marker) = @_;
+    my $phash = $self->{Pointers};
+    return 0 unless $phash;
+    return 1 if grep /_$marker$/, keys %$phash;
+    return 0 unless $self->{Fixups};
+    my $subFixup;
+    foreach $subFixup (@{$self->{Fixups}}) {
+        return 1 if $subFixup->HasMarker($marker);
+    }
+    return 0;
+}
+
+#------------------------------------------------------------------------------
+# Set all marker pointers to specified value
+# Inputs: 0) Fixup object reference, 1) data reference
+#         2) marker name, 3) pointer value, 4) offset to start of data
+sub SetMarkerPointers($$$$;$)
+{
+    my ($self, $dataPt, $marker, $value, $startOffset) = @_;
+    my $start = $self->{Start} + ($startOffset || 0);
+    my $phash = $self->{Pointers};
+
+    if ($phash) {
+        my $saveOrder = GetByteOrder(); # save original byte ordering
+        my ($byteOrder, $ptr);
+        foreach $byteOrder (keys %$phash) {
+            next unless $byteOrder =~ /^(II|MM)(2?)_$marker$/;
+            SetByteOrder($1);
+            my $set = $2 ? \&Set16u : \&Set32u;
+            foreach $ptr (@{$phash->{$byteOrder}}) {
+                &$set($value, $dataPt, $ptr + $start);
+            }
+        }
+        SetByteOrder($saveOrder);       # restore original byte ordering
+    }
+    if ($self->{Fixups}) {
+        my $subFixup;
+        foreach $subFixup (@{$self->{Fixups}}) {
+            $subFixup->SetMarkerPointers($dataPt, $marker, $value, $start);
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# Get pointer values for specified marker
+# Inputs: 0) Fixup object reference, 1) data reference,
+#         2) marker name, 3) offset to start of data
+# Returns: List of marker pointers in list context, or first marker pointer otherwise
+sub GetMarkerPointers($$$;$)
+{
+    my ($self, $dataPt, $marker, $startOffset) = @_;
+    my $start = $self->{Start} + ($startOffset || 0);
+    my $phash = $self->{Pointers};
+    my @pointers;
+
+    if ($phash) {
+        my $saveOrder = GetByteOrder();
+        my ($byteOrder, $ptr);
+        foreach $byteOrder (grep /_$marker$/, keys %$phash) {
+            SetByteOrder(substr($byteOrder,0,2));
+            my $get = ($byteOrder =~ /^(II2|MM2)/) ? \&Get16u : \&Get32u;
+            foreach $ptr (@{$phash->{$byteOrder}}) {
+                push @pointers, &$get($dataPt, $ptr + $start);
+            }
+        }
+        SetByteOrder($saveOrder);       # restore original byte ordering
+    }
+    if ($self->{Fixups}) {
+        my $subFixup;
+        foreach $subFixup (@{$self->{Fixups}}) {
+            push @pointers, $subFixup->GetMarkerPointers($dataPt, $marker, $start);
+        }
+    }
+    return @pointers if wantarray;
+    return $pointers[0];
+}
+
+#------------------------------------------------------------------------------
+# Dump fixup to console for debugging
+# Inputs: 0) Fixup object reference, 1) optional initial indent string
+sub Dump($;$)
+{
+    my ($self, $indent) = @_;
+    $indent or $indent = '';
+    printf "${indent}Fixup start=0x%x shift=0x%x\n", $self->{Start}, $self->{Shift};
+    my $phash = $self->{Pointers};
+    if ($phash) {
+        my $byteOrder;
+        foreach $byteOrder (sort keys %$phash) {
+            print "$indent  $byteOrder: ", join(' ',@{$phash->{$byteOrder}}),"\n";
+        }
+    }
+    if ($self->{Fixups}) {
+        my $subFixup;
+        foreach $subFixup (@{$self->{Fixups}}) {
+            Dump($subFixup, $indent . '  ');
+        }
+    }
+}
+
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Fixup - Utility to handle pointer fixups
+
+=head1 SYNOPSIS
+
+    use Image::ExifTool::Fixup;
+
+    $fixup = new Image::ExifTool::Fixup;
+
+    # add a new fixup to a pointer at the specified offset in data
+    $fixup->AddFixup($offset);
+
+    # add a new Fixup object to the tree
+    $fixup->AddFixup($subFixup);
+
+    $fixup->{Start} += $shift1;   # shift pointer offsets and values
+
+    $fixup->{Shift} += $shift2;   # shift pointer values only
+
+    # recursively apply fixups to the specified data
+    $fixup->ApplyFixups(\$data);
+
+    $fixup->Dump();               # dump debugging information
+
+=head1 DESCRIPTION
+
+This module contains the code to keep track of pointers in memory and to
+shift these pointers as required.  It is used by ExifTool to maintain the
+pointers in image file directories (IFD's).
+
+=head1 NOTES
+
+Keeps track of pointers with different byte ordering, and relies on
+Image::ExifTool::GetByteOrder() to determine the current byte ordering
+when adding new pointers to a fixup.
+
+Maintains a hierarchical list of fixups so that the whole hierarchy can
+be shifted by a simple shift at the base.  Hierarchy is collapsed to a
+linear list when ApplyFixups() is called.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Flash.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Flash.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Flash.pm	(revision 20131)
@@ -0,0 +1,608 @@
+#------------------------------------------------------------------------------
+# File:         Flash.pm
+#
+# Description:  Read Shockwave Flash meta information
+#
+# Revisions:    05/16/2006 - P. Harvey Created
+#               06/07/2007 - PH Added support for FLV (Flash Video) files
+#
+# References:   1) http://www.the-labs.com/MacromediaFlash/SWF-Spec/SWFfileformat.html
+#               2) http://sswf.sourceforge.net/SWFalexref.html
+#               3) http://osflash.org/flv/
+#
+# Notes:        I'll add AMF3 support if someone sends me a FLV with AMF3 data
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Flash;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::FLAC;
+
+$VERSION = '1.02';
+
+sub ProcessMeta($$$;$);
+
+# information extracted from SWF header
+%Image::ExifTool::Flash::Main = (
+    GROUPS => { 2 => 'Video' },
+    NOTES => q{
+        The information below is extracted from the header of SWF (Shockwave Flash)
+        files.
+    },
+    FlashVersion => { },
+    Compressed   => { PrintConv => { 0 => 'False', 1 => 'True' } },
+    ImageWidth   => { },
+    ImageHeight  => { },
+    FrameRate    => { },
+    FrameCount   => { },
+    Duration => {
+        Notes => 'calculated from FrameRate and FrameCount',
+        PrintConv => 'sprintf("%.2f sec",$val)',
+    },
+);
+
+# packets in Flash Video files
+%Image::ExifTool::Flash::FLV = (
+    NOTES => q{
+        Information is extracted from the following packets in FLV (Flash Video)
+        files.
+    },
+    0x08 => {
+        Name => 'Audio',
+        BitMask => 0x04,
+        SubDirectory => { TagTable => 'Image::ExifTool::Flash::Audio' },
+    },
+    0x09 => {
+        Name => 'Video',
+        BitMask => 0x01,
+        SubDirectory => { TagTable => 'Image::ExifTool::Flash::Video' },
+    },
+    0x12 => {
+        Name => 'Meta',
+        SubDirectory => { TagTable => 'Image::ExifTool::Flash::Meta' },
+    },
+);
+
+# tags in Flash Video packet header
+%Image::ExifTool::Flash::Audio = (
+    PROCESS_PROC => \&Image::ExifTool::FLAC::ProcessBitStream,
+    GROUPS => { 2 => 'Audio' },
+    NOTES => 'Information extracted from the Flash Audio header.',
+    'Bit0-3' => {
+        Name => 'AudioEncoding',
+        PrintConv => {
+            0 => 'Uncompressed',
+            1 => 'ADPCM',
+            2 => 'MP3',
+            5 => 'Nellymoser 8kHz mono',
+            6 => 'Nellymoser',
+        },
+    },
+    'Bit4-5' => {
+        Name => 'AudioSampleRate',
+        ValueConv => {
+            0 => 5512,
+            1 => 11025,
+            2 => 22050,
+            3 => 44100,
+        },
+    },
+    'Bit6' => {
+        Name => 'AudioSampleBits',
+        ValueConv => '8 * ($val + 1)',
+    },
+    'Bit7' => {
+        Name => 'AudioChannels',
+        ValueConv => '$val + 1',
+        PrintConv => {
+            1 => '1 (mono)',
+            2 => '2 (stereo)',
+        },
+    },
+);
+
+# tags in Flash Video packet header
+%Image::ExifTool::Flash::Video = (
+    PROCESS_PROC => \&Image::ExifTool::FLAC::ProcessBitStream,
+    GROUPS => { 2 => 'Video' },
+    NOTES => 'Information extracted from the Flash Video header.',
+    'Bit4-7' => {
+        Name => 'VideoEncoding',
+        PrintConv => {
+            2 => 'Sorensen H.263',
+            3 => 'Screen video',
+            4 => 'On2 VP6',
+        },
+    },
+);
+
+# tags in Flash META packet (in ActionScript Message Format)
+%Image::ExifTool::Flash::Meta = (
+    PROCESS_PROC => \&ProcessMeta,
+    GROUPS => { 2 => 'Video' },
+    NOTES => q{
+        Below are a few observed FLV Meta tags, but ExifTool will attempt to extract
+        information from any tag found.
+    },
+    'audiocodecid'  => { Name => 'AudioCodecID',    Groups => { 2 => 'Audio' } },
+    'audiodatarate' => {
+        Name => 'AudioBitrate',
+        Groups => { 2 => 'Audio' },
+        ValueConv => '$val * 1000',
+        PrintConv => 'int($val + 0.5)',
+    },
+    'audiodelay'    => { Name => 'AudioDelay',      Groups => { 2 => 'Audio' } },
+    'audiosamplerate'=>{ Name => 'AudioSampleRate', Groups => { 2 => 'Audio' } },
+    'audiosamplesize'=>{ Name => 'AudioSampleSize', Groups => { 2 => 'Audio' } },
+    'audiosize'     => { Name => 'AudioSize',       Groups => { 2 => 'Audio' } },
+    'canSeekToEnd'  => 'CanSeekToEnd',
+    'creationdate'  => {
+        # (not an AMF date type in my sample)
+        Name => 'CreateDate',
+        Groups => { 2 => 'Time' },
+        ValueConv => '$val=~s/\s+$//; $val',    # trim trailing whitespace
+    },
+    'cuePoints'     => {
+        Name => 'CuePoint',
+        SubDirectory => { TagTable => 'Image::ExifTool::Flash::CuePoint' },
+    },
+    'datasize'      => 'DataSize',
+    'duration' => {
+        Name => 'Duration',
+        PrintConv => 'sprintf("%.3fs",$val)',
+    },
+    'filesize'      => 'FileSizeBytes',
+    'framerate'     => {
+        Name => 'FrameRate',
+        PrintConv => 'int($val * 1000 + 0.5) / 1000',
+    },
+    'hasAudio'      => { Name => 'HasAudio',        Groups => { 2 => 'Audio' } },
+    'hasCuePoints'  => 'HasCuePoints',
+    'hasKeyframes'  => 'HasKeyFrames',
+    'hasMetadata'   => 'HasMetadata',
+    'hasVideo'      => 'HasVideo',
+    'height'        => 'ImageHeight',
+    'keyframesTimes'=> 'KeyFramesTimes',
+    'keyframesFilepositions' => 'KeyFramePositions',
+    'lasttimestamp' => 'LastTimeStamp',
+    'lastkeyframetimestamp' => 'LastKeyFrameTime',
+    'metadatacreator'=>'MetadataCreator',
+    'metadatadate'  => {
+        Name => 'MetadataDate',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    'stereo'        => { Name => 'Stereo',          Groups => { 2 => 'Audio' } },
+    'videocodecid'  => 'VideoCodecID',
+    'videodatarate' => {
+        Name => 'VideoBitrate',
+        ValueConv => '$val * 1000',
+        PrintConv => 'int($val + 0.5)',
+    },
+    'videosize'     => 'VideoSize',
+    'width'         => 'ImageWidth',
+);
+
+# tags in Flash META CuePoint structure
+%Image::ExifTool::Flash::CuePoint = (
+    PROCESS_PROC => \&ProcessMeta,
+    GROUPS => { 2 => 'Video' },
+    NOTES => q{
+        These tag names are added to the CuePoint name to generate complete tag
+        names like "CuePoint0Name".
+    },
+    'name' => 'Name',
+    'type' => 'Type',
+    'time' => 'Time',
+    'parameters' => {
+        Name => 'Parameter',
+        SubDirectory => { TagTable => 'Image::ExifTool::Flash::Parameter' },
+    },
+);
+
+# tags in Flash META CuePoint Parameter structure
+%Image::ExifTool::Flash::Parameter = (
+    PROCESS_PROC => \&ProcessMeta,
+    GROUPS => { 2 => 'Video' },
+    NOTES => q{
+        There are no pre-defined parameter tags, but ExifTool will extract any
+        existing parameters, with tag names like "CuePoint0ParameterXxx".
+    },
+);
+
+# name lookup for known AMF data types
+my @amfType = qw(double boolean string object movieClip null undefined reference
+                 mixedArray objectEnd array date longString unsupported recordSet
+                 XML typedObject AMF3data);
+
+# test for AMF structure types (object, mixed array or typed object)
+my %isStruct = ( 0x03 => 1, 0x08 => 1, 0x10 => 1 );
+
+#------------------------------------------------------------------------------
+# Process Flash Video AMF Meta packet (ref 3)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+#         3) Set to extract single type/value only
+# Returns: 1 on success, (or type/value if extracting single value)
+# Notes: Updates DataPos in dirInfo if extracting single value
+sub ProcessMeta($$$;$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr, $single) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{DataPos};
+    my $dirLen = $$dirInfo{DirLen} || length($$dataPt);
+    my $pos = $$dirInfo{Pos} || 0;
+    my $verbose = $exifTool->Options('Verbose');
+    my ($type, $val, $rec);
+
+    $exifTool->VerboseDir('Meta') unless $single;
+
+Record: for ($rec=0; ; ++$rec) {
+        last if $pos >= $dirLen;
+        $type = ord(substr($$dataPt, $pos));
+        ++$pos;
+        if ($type == 0x00 or $type == 0x0b) {   # double or date
+            last if $pos + 8 > $dirLen;
+            $val = GetDouble($dataPt, $pos);
+            $pos += 8;
+            if ($type == 0x0b) {    # date
+                $val /= 1000;       # convert to seconds
+                my $frac = $val - int($val);    # fractional seconds
+                # get time zone
+                last if $pos + 2 > $dirLen;
+                my $tz = Get16s($dataPt, $pos);
+                $pos += 2;
+                # construct date/time string
+                $val = Image::ExifTool::ConvertUnixTime(int($val));
+                if ($frac) {
+                    $frac = sprintf('%.6f', $frac);
+                    $frac =~ s/(^0|0+$)//g;
+                    $val .= $frac;
+                }
+                # add timezone
+                if ($tz < 0) {
+                    $val .= '-';
+                    $tz *= -1;
+                } else {
+                    $val .= '+';
+                }
+                $val .= sprintf('%.2d:%.2d', int($tz/60), $tz%60);
+            }
+        } elsif ($type == 0x01) {   # boolean
+            last if $pos + 1 > $dirLen;
+            $val = Get8u($dataPt, $pos);
+            $val = { 0 => 'No', 1 => 'Yes' }->{$val} if $val < 2;
+            ++$pos;
+        } elsif ($type == 0x02) {   # string
+            last if $pos + 2 > $dirLen;
+            my $len = Get16u($dataPt, $pos);
+            last if $pos + 2 + $len > $dirLen;
+            $val = substr($$dataPt, $pos + 2, $len);
+            $pos += 2 + $len;
+        } elsif ($isStruct{$type}) {   # object, mixed array or typed object
+            $exifTool->VPrint(1, "  + [$amfType[$type]]\n");
+            my $getName;
+            $val = '';  # dummy value
+            if ($type == 0x08) {        # mixed array
+                # skip last array index for mixed array
+                last if $pos + 4 > $dirLen;
+                $pos += 4;
+            } elsif ($type == 0x10) {   # typed object
+                $getName = 1;
+            }
+            for (;;) {
+                # get tag ID (or typed object name)
+                last Record if $pos + 2 > $dirLen;
+                my $len = Get16u($dataPt, $pos);
+                if ($pos + 2 + $len > $dirLen) {
+                    $exifTool->Warn("Truncated $amfType[$type] record");
+                    last Record;
+                }
+                my $tag = substr($$dataPt, $pos + 2, $len);
+                $pos += 2 + $len;
+                # first string of a typed object is the object name
+                if ($getName) {
+                    $exifTool->VPrint(1,"  | (object name '$tag')\n");
+                    undef $getName;
+                    next; # (ignore name for now)
+                }
+                my $subTablePtr = $tagTablePtr;
+                my $tagInfo = $$subTablePtr{$tag};
+                # switch to subdirectory table if necessary
+                if ($tagInfo and $$tagInfo{SubDirectory}) {
+                    $tag = $$tagInfo{Name}; # use our name for the tag
+                    $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                }
+                # get object value
+                my $valPos = $pos + 1;
+                $$dirInfo{Pos} = $pos;
+                my $structName = $$dirInfo{StructName};
+                # add structure name to start of tag name
+                $tag = $structName . ucfirst($tag) if defined $structName;
+                $$dirInfo{StructName} = $tag;       # set new structure name
+                my ($t, $v) = ProcessMeta($exifTool, $dirInfo, $subTablePtr, 1);
+                $$dirInfo{StructName} = $structName;# restore original structure name
+                $pos = $$dirInfo{Pos};  # update to new position in packet
+                # all done if this value contained tags
+                last Record unless defined $t and defined $v;
+                next if $isStruct{$t};  # already handled tags in sub-structures
+                next if ref($v) eq 'ARRAY' and not @$v; # ignore empty arrays
+                last if $t == 0x09; # (end of object)
+                if (not $$subTablePtr{$tag} and $tag =~ /^\w+$/) {
+                    Image::ExifTool::AddTagToTable($subTablePtr, $tag, { Name => ucfirst($tag) });
+                    $verbose > 1 and $exifTool->VPrint(1, "  | (adding $tag)\n");
+                }
+                $exifTool->HandleTag($subTablePtr, $tag, $v,
+                    DataPt  => $dataPt,
+                    DataPos => $dataPos,
+                    Start   => $valPos,
+                    Size    => $pos - $valPos,
+                    Format  => $amfType[$t] || sprintf('0x%x',$t),
+                );
+            }
+      # } elsif ($type == 0x04) {   # movie clip (not supported)
+        } elsif ($type == 0x05 or $type == 0x06 or $type == 0x09 or $type == 0x0d) {
+            # null, undefined, dirLen of object, or unsupported
+            $val = '';
+        } elsif ($type == 0x07) {   # reference
+            last if $pos + 2 > $dirLen;
+            $val = Get16u($dataPt, $pos);
+            $pos += 2;
+        } elsif ($type == 0x0a) {   # array
+            last if $pos + 4 > $dirLen;
+            my $num = Get32u($dataPt, $pos);
+            $$dirInfo{Pos} = $pos + 4;
+            my ($i, @vals);
+            # add array index to compount tag name
+            my $structName = $$dirInfo{StructName};
+            for ($i=0; $i<$num; ++$i) {
+                $$dirInfo{StructName} = $structName . $i if defined $structName;
+                my ($t, $v) = ProcessMeta($exifTool, $dirInfo, $tagTablePtr, 1);
+                last Record unless defined $v;
+                # save value unless contained in a sub-structure
+                push @vals, $v unless $isStruct{$t};
+            }
+            $$dirInfo{StructName} = $structName;
+            $pos = $$dirInfo{Pos};
+            $val = \@vals;
+        } elsif ($type == 0x0c or $type == 0x0f) {  # long string or XML
+            last if $pos + 4 > $dirLen;
+            my $len = Get32u($dataPt, $pos);
+            last if $pos + 4 + $len > $dirLen;
+            $val = substr($$dataPt, $pos + 4, $len);
+            $pos += 4 + $len;
+      # } elsif ($type == 0x0e) {   # record set (not supported)
+      # } elsif ($type == 0x11) {   # AMF3 data (can't add support for this without a test sample)
+        } else {
+            my $t = $amfType[$type] || sprintf('type 0x%x',$type);
+            $exifTool->Warn("AMF $t record not yet supported");
+            undef $type;    # (so we don't print another warning)
+            last;           # can't continue
+        }
+        last if $single;        # all done if extracting single value
+        unless ($isStruct{$type}) {
+            # only process "onMetaData" Meta packets
+            if ($type == 0x02 and not $rec) {
+                my $verb = ($val eq 'onMetaData') ? 'processing' : 'ignoring';
+                $exifTool->VPrint(0, "  | ($verb $val information)\n");
+                last unless $val eq 'onMetaData';
+            } else {
+                # give verbose indication if we ignore a lone value
+                my $t = $amfType[$type] || sprintf('type 0x%x',$type);
+                $exifTool->VPrint(1, "  | (ignored lone $t value '$val')\n");
+            }
+        }
+    }
+    if (not defined $val and defined $type) {
+        $exifTool->Warn(sprintf("Truncated AMF record 0x%x",$type));
+    }
+    return 1 unless $single;    # all done
+    $$dirInfo{Pos} = $pos;      # update position
+    return($type,$val);         # return single type/value pair
+}
+
+#------------------------------------------------------------------------------
+# Read information frame a Flash Video file
+# Inputs: 0) ExifTool object reference, 1) Directory information reference
+# Returns: 1 on success, 0 if this wasn't a valid Flash Video file
+sub ProcessFLV($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $verbose = $exifTool->Options('Verbose');
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+
+    $raf->Read($buff, 9) == 9 or return 0;
+    $buff =~ /^FLV\x01/ or return 0;
+    SetByteOrder('MM');
+    $exifTool->SetFileType();
+    my ($flags, $offset) = unpack('x4CN', $buff);
+    $raf->Seek($offset-9, 1) or return 1 if $offset > 9;
+    $flags &= 0x05; # only look for audio/video
+    my $found = 0;
+    my $tagTablePtr = GetTagTable('Image::ExifTool::Flash::FLV');
+    for (;;) {
+        $raf->Read($buff, 15) == 15 or last;
+        my $len = unpack('x4N', $buff);
+        my $type = $len >> 24;
+        $len &= 0x00ffffff;
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $type);
+        if ($verbose > 1) {
+            my $name = $tagInfo ? $$tagInfo{Name} : "type $type";
+            $exifTool->VPrint(1, "FLV $name packet, len $len\n");
+        }
+        undef $buff;
+        if ($tagInfo and $$tagInfo{SubDirectory}) {
+            my $mask = $$tagInfo{BitMask};
+            if ($mask) {
+                # handle audio or video packet
+                unless ($found & $mask) {
+                    $found |= $mask;
+                    $flags &= ~$mask;
+                    if ($len>=1 and $raf->Read($buff, 1) == 1) {
+                        $len -= 1;
+                    } else {
+                        $exifTool->Warn("Bad $$tagInfo{Name} packet");
+                        last;
+                    }
+                }
+            } elsif ($raf->Read($buff, $len) == $len) {
+                $len = 0;
+            } else {
+                $exifTool->Warn('Truncated Meta packet');
+                last;
+            }
+        }
+        if (defined $buff) {
+            $exifTool->HandleTag($tagTablePtr, $type, undef,
+                DataPt  => \$buff,
+                DataPos => $raf->Tell() - length($buff),
+            );
+        }
+        last unless $flags;
+        $raf->Seek($len, 1) or last if $len;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Found a Flash tag
+# Inputs: 0) ExifTool object ref, 1) tag name, 2) tag value
+sub FoundFlashTag($$$)
+{
+    my ($exifTool, $tag, $val) = @_;
+    $exifTool->HandleTag(\%Image::ExifTool::Flash::Main, $tag, $val);
+}
+
+#------------------------------------------------------------------------------
+# Read information frame a Flash file
+# Inputs: 0) ExifTool object reference, 1) Directory information reference
+# Returns: 1 on success, 0 if this wasn't a valid Flash file
+sub ProcessSWF($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $verbose = $exifTool->Options('Verbose');
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+
+    $raf->Read($buff, 8) == 8 or return 0;
+    $buff =~ /^(F|C)WS([^\0])/ or return 0;
+    my ($compressed, $vers) = ($1 eq 'C' ? 1 : 0, ord($2));
+
+    # read the first bit of the file
+    $raf->Read($buff, 64) or return 0;
+
+    $exifTool->SetFileType();
+    GetTagTable('Image::ExifTool::Flash::Main');  # make sure table is initialized
+
+    FoundFlashTag($exifTool, FlashVersion => $vers);
+    FoundFlashTag($exifTool, Compressed => $compressed);
+
+    # uncompress if necessary
+    if ($compressed) {
+        unless (eval 'require Compress::Zlib') {
+            $exifTool->Warn('Install Compress::Zlib to extract compressed information');
+            return 1;
+        }
+        my $inflate = Compress::Zlib::inflateInit();
+        my $tmp = $buff;
+        $buff = '';
+        # read file 64 bytes at a time and inflate until we get enough uncompressed data
+        for (;;) {
+            unless ($inflate) {
+                $exifTool->Warn('Error inflating compressed Flash data');
+                return 1;
+            }
+            my ($dat, $stat) = $inflate->inflate($tmp);
+            if ($stat == Compress::Zlib::Z_STREAM_END() or
+                $stat == Compress::Zlib::Z_OK())
+            {
+                $buff .= $dat;  # add inflated data to buffer
+                last if length $buff >= 64 or $stat == Compress::Zlib::Z_STREAM_END();
+                $raf->Read($tmp,64) or last;    # read some more data
+            } else {
+                undef $inflate; # issue warning the next time around
+            }
+        }
+    }
+    # unpack elements of bit-packed Flash Rect structure
+    my ($nBits, $totBits, $nBytes);
+    for (;;) {
+        if (length($buff)) {
+            $nBits = unpack('C', $buff) >> 3;    # bits in x1,x2,y1,y2 elements
+            $totBits = 5 + $nBits * 4;           # total bits in Rect structure
+            $nBytes = int(($totBits + 7) / 8);   # byte length of Rect structure
+            last if length $buff >= $nBytes + 4; # make sure header is long enough
+        }
+        $exifTool->Warn('Truncated Flash file');
+        return 1;
+    }
+    my $bits = unpack("B$totBits", $buff);
+    # isolate Rect elements and convert from ASCII bit strings to integers
+    my @vals = unpack('x5' . "a$nBits" x 4, $bits);
+    # (do conversion the hard way because oct("0b$val") requires Perl 5.6)
+    map { $_ = unpack('N', pack('B32', '0' x (32 - length $_) . $_)) } @vals;
+
+    # calculate and store ImageWidth/Height
+    FoundFlashTag($exifTool, ImageWidth  => ($vals[1] - $vals[0]) / 20);
+    FoundFlashTag($exifTool, ImageHeight => ($vals[3] - $vals[2]) / 20);
+
+    # get frame rate and count
+    @vals = unpack("x${nBytes}v2", $buff);
+    FoundFlashTag($exifTool, FrameRate => $vals[0] / 256);
+    FoundFlashTag($exifTool, FrameCount => $vals[1]);
+    FoundFlashTag($exifTool, Duration => $vals[1] * 256 / $vals[0]) if $vals[0];
+
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Flash - Read Shockwave Flash meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read SWF
+(Shockwave Flash) and FLV (Flash Video) files.
+
+=head1 NOTES
+
+Flash Video AMF3 support has not yet been added because I haven't yet found
+a FLV file containing AMF3 information.  If someone sends me a sample then I
+will add AMF3 support.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.the-labs.com/MacromediaFlash/SWF-Spec/SWFfileformat.html>
+
+=item L<http://sswf.sourceforge.net/SWFalexref.html>
+
+=item L<http://osflash.org/flv/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Flash Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/FlashPix.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/FlashPix.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/FlashPix.pm	(revision 20131)
@@ -0,0 +1,1494 @@
+#------------------------------------------------------------------------------
+# File:         FlashPix.pm
+#
+# Description:  Read FlashPix meta information
+#
+# Revisions:    05/29/2006 - P. Harvey Created
+#
+# References:   1) http://www.exif.org/Exif2-2.PDF
+#               2) http://www.graphcomp.com/info/specs/livepicture/fpx.pdf
+#               3) http://search.cpan.org/~jdb/libwin32/
+#               4) http://msdn2.microsoft.com/en-us/library/aa380374.aspx
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::FlashPix;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+use Image::ExifTool::ASF;   # for GetGUID()
+
+$VERSION = '1.04';
+
+sub ProcessFPX($$);
+sub ProcessFPXR($$$);
+sub ProcessProperties($$$);
+sub ReadFPXValue($$$$$;$);
+sub ConvertTimeSpan($);
+sub ProcessHyperlinks($$);
+
+# sector type constants
+sub HDR_SIZE           () { 512; }
+sub DIF_SECT           () { 0xfffffffc; }
+sub FAT_SECT           () { 0xfffffffd; }
+sub END_OF_CHAIN       () { 0xfffffffe; }
+sub FREE_SECT          () { 0xffffffff; }
+
+# format flags
+sub VT_VECTOR          () { 0x1000; }
+sub VT_ARRAY           () { 0x2000; }
+sub VT_BYREF           () { 0x4000; }
+sub VT_RESERVED        () { 0x8000; }
+
+# other constants
+sub VT_VARIANT         () { 12; }
+sub VT_LPSTR           () { 30; }
+
+# list of OLE format codes (unsupported codes commented out)
+my %oleFormat = (
+    0  => undef,        # VT_EMPTY
+    1  => undef,        # VT_NULL
+    2  => 'int16s',     # VT_I2
+    3  => 'int32s',     # VT_I4
+    4  => 'float',      # VT_R4
+    5  => 'double',     # VT_R8
+    6  => undef,        # VT_CY
+    7  => 'VT_DATE',    # VT_DATE (double, number of days since Dec 30, 1899)
+    8  => 'VT_BSTR',    # VT_BSTR (int32u count, followed by binary string)
+#   9  => 'VT_DISPATCH',
+    10 => 'int32s',     # VT_ERROR
+    11 => 'int16s',     # VT_BOOL
+    12 => 'VT_VARIANT', # VT_VARIANT
+#   13 => 'VT_UNKNOWN',
+#   14 => 'VT_DECIMAL',
+    16 => 'int8s',      # VT_I1
+    17 => 'int8u',      # VT_UI1
+    18 => 'int16u',     # VT_UI2
+    19 => 'int32u',     # VT_UI4
+    20 => 'int64s',     # VT_I8
+    21 => 'int64u',     # VT_UI8
+#   22 => 'VT_INT',
+#   23 => 'VT_UINT',
+#   24 => 'VT_VOID',
+#   25 => 'VT_HRESULT',
+#   26 => 'VT_PTR',
+#   27 => 'VT_SAFEARRAY',
+#   28 => 'VT_CARRAY',
+#   29 => 'VT_USERDEFINED',
+    30 => 'VT_LPSTR',   # VT_LPSTR (int32u count, followed by string)
+    31 => 'VT_LPWSTR',  # VT_LPWSTR (int32u word count, followed by Unicode string)
+    64 => 'VT_FILETIME',# VT_FILETIME (int64u, number of nanoseconds since Jan 1, 1601)
+    65 => 'VT_BLOB',    # VT_BLOB
+#   66 => 'VT_STREAM',
+#   67 => 'VT_STORAGE',
+#   68 => 'VT_STREAMED_OBJECT',
+#   69 => 'VT_STORED_OBJECT',
+#   70 => 'VT_BLOB_OBJECT',
+    71 => 'VT_CF',      # VT_CF
+    72 => 'VT_CLSID',   # VT_CLSID
+);
+
+# OLE flag codes (high nibble of property type)
+my %oleFlags = (
+    0x1000 => 'VT_VECTOR',
+    0x2000 => 'VT_ARRAY',   # not yet supported
+    0x4000 => 'VT_BYREF',   # ditto
+    0x8000 => 'VT_RESERVED',
+);
+
+# byte sizes for supported VT_* format and flag types
+my %oleFormatSize = (
+    VT_DATE     => 8,
+    VT_BSTR     => 4,   # (+ string length)
+    VT_VARIANT  => 4,   # (+ data length)
+    VT_LPSTR    => 4,   # (+ string length)
+    VT_LPWSTR   => 4,   # (+ string character length)
+    VT_FILETIME => 8,
+    VT_BLOB     => 4,   # (+ data length)
+    VT_CF       => 4,   # (+ data length)
+    VT_CLSID    => 16,
+    VT_VECTOR   => 4,   # (+ vector elements)
+);
+
+# names for each type of directory entry
+my @dirEntryType = qw(INVALID STORAGE STREAM LOCKBYTES PROPERTY ROOT);
+
+%Image::ExifTool::FlashPix::Main = (
+    PROCESS_PROC => \&ProcessFPXR,
+    GROUPS => { 2 => 'Image' },
+    NOTES => q{
+        The FlashPix file format, introduced in 1996, was developed by Kodak,
+        Hewlett-Packard and Microsoft.  Internally the FPX file structure mimics
+        that of an old DOS disk with fixed-sized "sectors" (usually 512 bytes) and a
+        "file allocation table" (FAT).  No wonder the format never became popular.
+
+        However, some of the structures used in FlashPix streams are part of the
+        EXIF specification, and are still being used in the APP2 FPXR segment of
+        JPEG images by some Kodak and Hewlett-Packard digital cameras.
+
+        ExifTool extracts FlashPix information from both FPX images and the APP2
+        FPXR segment of JPEG images.  As well, FlashPix information is extracted
+        from DOC, XLS and PPT (Microsoft Word, Excel and PowerPoint) documents since
+        the FlashPix file format is closely related to the formats of these files.
+    },
+    "\x05SummaryInformation" => {
+        Name => 'SummaryInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::SummaryInfo',
+        },
+    },
+    "\x05DocumentSummaryInformation" => {
+        Name => 'DocumentInfo',
+        Multi => 1, # flag to process UserDefined information after this
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::DocumentInfo',
+        },
+    },
+    "\x01CompObj" => {
+        Name => 'CompObj',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::CompObj',
+            DirStart => 0x1c,   # skip stream header
+        },
+    },
+    "\x05Image Info" => {
+        Name => 'ImageInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::ImageInfo',
+        },
+    },
+    "\x05Image Contents" => {
+        Name => 'Image',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::Image',
+        },
+    },
+    "ICC Profile 0001" => {
+        Name => 'ICC_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+            DirStart => 0x1c,   # skip stream header
+        },
+    },
+    "\x05Extension List" => {
+        Name => 'Extensions',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::Extensions',
+        },
+    },
+    'Subimage 0000 Header' => {
+        Name => 'SubimageHdr',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::SubimageHdr',
+            DirStart => 0x1c,   # skip stream header
+        },
+    },
+#   'Subimage 0000 Data'
+    "\x05Data Object" => {  # plus instance number (ie. " 000000")
+        Name => 'DataObject',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::DataObject',
+        },
+    },
+#   "\x05Data Object Store" => { # plus instance number (ie. " 000000")
+    "\x05Transform" => {    # plus instance number (ie. " 000000")
+        Name => 'Transform',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::Transform',
+        },
+    },
+    "\x05Operation" => {    # plus instance number (ie. " 000000")
+        Name => 'Operation',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::Operation',
+        },
+    },
+    "\x05Global Info" => {
+        Name => 'GlobalInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::GlobalInfo',
+        },
+    },
+    "\x05Screen Nail" => { # plus class ID (ie. "_bd0100609719a180")
+        Name => 'ScreenNail',
+        Groups => { 2 => 'Other' },
+        # strip off stream header
+        ValueConv => 'length($val) > 0x1c and $val = substr($val, 0x1c); \$val',
+    },
+    "\x05Audio Info" => {
+        Name => 'AudioInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::AudioInfo',
+        },
+    },
+    'Audio Stream' => { # plus instance number (ie. " 000000")
+        Name => 'AudioStream',
+        Groups => { 2 => 'Audio' },
+        # strip off stream header
+        ValueConv => 'length($val) > 0x1c and $val = substr($val, 0x1c); \$val',
+    },
+    "Current User" => { #PH
+        Name => 'CurrentUser',
+        # not sure what the rest of this data is, but extract ASCII name from it - PH
+        ValueConv => q{
+            return undef if length $val < 12;
+            my ($size,$pos) = unpack('x4VV', $val);
+            my $len = $size - $pos - 4;
+            return undef if $len < 0 or length $val < $size + 8;
+            return substr($val, 8 + $pos, $len);
+        },
+    },
+);
+
+# Summary Information properties
+%Image::ExifTool::FlashPix::SummaryInfo = (
+    PROCESS_PROC => \&ProcessProperties,
+    GROUPS => { 2 => 'Image' },
+    NOTES => q{
+        The Dictionary, CodePage and LocalIndicator tags are common to all FlashPix
+        property tables, even though they are only listed in the SummaryInfo table.
+    },
+    0x00 => { Name => 'Dictionary', Groups => { 2 => 'Other' }, Binary => 1 },
+    0x01 => { Name => 'CodePage',   Groups => { 2 => 'Other' } },
+    0x02 => 'Title',
+    0x03 => 'Subject',
+    0x04 => { Name => 'Author',     Groups => { 2 => 'Author' } },
+    0x05 => 'Keywords',
+    0x06 => 'Comments',
+    0x07 => 'Template',
+    0x08 => { Name => 'LastSavedBy',Groups => { 2 => 'Author' } },
+    0x09 => 'RevisionNumber',
+    0x0a => { Name => 'TotalEditTime', PrintConv => \&ConvertTimeSpan },
+    0x0b => 'LastPrinted',
+    0x0c => { Name => 'CreateDate', Groups => { 2 => 'Time' } },
+    0x0d => { Name => 'ModifyDate', Groups => { 2 => 'Time' } },
+    0x0e => 'PageCount',
+    0x0f => 'WordCount',
+    0x10 => 'CharCount',
+    0x11 => { Name => 'ThumbnailClip', Binary => 1 },
+    0x12 => 'Software',
+    0x13 => 'Security',
+    0x80000000 => { Name => 'LocaleIndicator', Groups => { 2 => 'Other' } },
+);
+
+# Document Summary Information properties (ref 4)
+%Image::ExifTool::FlashPix::DocumentInfo = (
+    PROCESS_PROC => \&ProcessProperties,
+    GROUPS => { 2 => 'Document' },
+    NOTES => q{
+        The DocumentSummaryInformation property set includes a UserDefined property
+        set for which only the Hyperlinks and HyperlinkBase tags are pre-defined. 
+        However, ExifTool will also extract any other information found in the
+        UserDefined properties.
+    },
+    0x02 => 'Category',
+    0x03 => 'PresentationTarget',
+    0x04 => 'Bytes',
+    0x05 => 'Lines',
+    0x06 => 'Paragraphs',
+    0x07 => 'Slides',
+    0x08 => 'Notes',
+    0x09 => 'HiddenSlides',
+    0x0a => 'MMClips',
+    0x0b => 'ScaleCrop',
+    0x0c => 'HeadingPairs',
+    0x0d => 'TitleOfParts',
+    0x0e => 'Manager',
+    0x0f => 'Company',
+    0x10 => 'LinksUpToDate',
+    0x11 => 'CharCountWithSpaces',
+  # 0x12 ?
+    0x13 => 'SharedDoc', #PH (unconfirmed)
+  # 0x14 ?
+  # 0x15 ?
+    0x16 => 'HyperlinksChanged',
+    0x17 => { #PH (unconfirmed)
+        Name => 'AppVersion',
+        # (not sure what the lower 16 bits mean, so print them in hex inside brackets)
+        ValueConv => 'sprintf("%d (%.4x)",$val >> 16, $val & 0xffff)',
+    },
+   '_PID_LINKBASE' => 'HyperlinkBase',
+   '_PID_HLINKS' => {
+        Name => 'Hyperlinks',
+        RawConv => \&ProcessHyperlinks,
+    },
+);
+
+# Image Information properties
+%Image::ExifTool::FlashPix::ImageInfo = (
+    PROCESS_PROC => \&ProcessProperties,
+    GROUPS => { 2 => 'Image' },
+    0x21000000 => {
+        Name => 'FileSource',
+        PrintConv => {
+            1 => 'Film Scanner',
+            2 => 'Reflection Print Scanner',
+            3 => 'Digital Camera',
+            4 => 'Video Capture',
+            5 => 'Computer Graphics',
+        },
+    },
+    0x21000001 => {
+        Name => 'SceneType',
+        PrintConv => {
+            1 => 'Original Scene',
+            2 => 'Second Generation Scene',
+            3 => 'Digital Scene Generation',
+        },
+    },
+    0x21000002 => 'CreationPathVector',
+    0x21000003 => 'SoftwareRelease',
+    0x21000004 => 'UserDefinedID',
+    0x21000005 => 'SharpnessApproximation',
+    0x22000000 => { Name => 'Copyright',                 Groups => { 2 => 'Author' } },
+    0x22000001 => { Name => 'OriginalImageBroker',       Groups => { 2 => 'Author' } },
+    0x22000002 => { Name => 'DigitalImageBroker',        Groups => { 2 => 'Author' } },
+    0x22000003 => { Name => 'Authorship',                Groups => { 2 => 'Author' } },
+    0x22000004 => { Name => 'IntellectualPropertyNotes', Groups => { 2 => 'Author' } },
+    0x23000000 => {
+        Name => 'TestTarget',
+        PrintConv => {
+            1 => 'Color Chart',
+            2 => 'Gray Card',
+            3 => 'Grayscale',
+            4 => 'Resolution Chart',
+            5 => 'Inch Scale',
+            6 => 'Centimeter Scale',
+            7 => 'Millimeter Scale',
+            8 => 'Micrometer Scale',
+        },
+    },
+    0x23000002 => 'GroupCaption',
+    0x23000003 => 'CaptionText',
+    0x23000004 => 'People',
+    0x23000007 => 'Things',
+    0x2300000A => { Name => 'DateTimeOriginal', Groups => { 2 => 'Time' } },
+    0x2300000B => 'Events',
+    0x2300000C => 'Places',
+    0x2300000F => 'ContentDescriptionNotes',
+    0x24000000 => { Name => 'Make',             Groups => { 2 => 'Camera' } },
+    0x24000001 => {
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Groups => { 2 => 'Camera' },
+    },
+    0x24000002 => { Name => 'SerialNumber',     Groups => { 2 => 'Camera' } },
+    0x25000000 => { Name => 'CreateDate',       Groups => { 2 => 'Time' } },
+    0x25000001 => {
+        Name => 'ExposureTime',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    0x25000002 => {
+        Name => 'FNumber',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x25000003 => {
+        Name => 'ExposureProgram',
+        Groups => { 2 => 'Camera' },
+        # use PrintConv of corresponding EXIF tag
+        PrintConv => $Image::ExifTool::Exif::Main{0x8822}->{PrintConv},
+    },
+    0x25000004 => 'BrightnessValue',
+    0x25000005 => 'ExposureCompensation',
+    0x25000006 => {
+        Name => 'SubjectDistance',
+        Groups => { 2 => 'Camera' },
+        PrintConv => 'sprintf("%.3f m", $val)',
+    },
+    0x25000007 => {
+        Name => 'MeteringMode',
+        Groups => { 2 => 'Camera' },
+        PrintConv => $Image::ExifTool::Exif::Main{0x9207}->{PrintConv},
+    },
+    0x25000008 => {
+        Name => 'LightSource',
+        Groups => { 2 => 'Camera' },
+        PrintConv => $Image::ExifTool::Exif::Main{0x9208}->{PrintConv},
+    },
+    0x25000009 => {
+        Name => 'FocalLength',
+        Groups => { 2 => 'Camera' },
+        PrintConv => 'sprintf("%.1fmm",$val)',
+    },
+    0x2500000A => {
+        Name => 'MaxApertureValue',
+        Groups => { 2 => 'Camera' },
+        ValueConv => '2 ** ($val / 2)',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x2500000B => {
+        Name => 'Flash',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            1 => 'No Flash',
+            2 => 'Flash Fired',
+        },
+    },
+    0x2500000C => {
+        Name => 'FlashEnergy',
+        Groups => { 2 => 'Camera' },
+    },
+    0x2500000D => {
+        Name => 'FlashReturn',
+        Groups => { 2 => 'Camera' },
+        PrintConv => {
+            1 => 'Subject Outside Flash Range',
+            2 => 'Subject Inside Flash Range',
+        },
+    },
+    0x2500000E => {
+        Name => 'BackLight',
+        PrintConv => {
+            1 => 'Front Lit',
+            2 => 'Back Lit 1',
+            3 => 'Back Lit 2',
+        },
+    },
+    0x2500000F => { Name => 'SubjectLocation', Groups => { 2 => 'Camera' } },
+    0x25000010 => 'ExposureIndex',
+    0x25000011 => {
+        Name => 'SpecialEffectsOpticalFilter',
+        PrintConv => {
+            1 => 'None',
+            2 => 'Colored',
+            3 => 'Diffusion',
+            4 => 'Multi-image',
+            5 => 'Polarizing',
+            6 => 'Split-field',
+            7 => 'Star',
+        },
+    },
+    0x25000012 => 'PerPictureNotes',
+    0x26000000 => {
+        Name => 'SensingMethod',
+        Groups => { 2 => 'Camera' },
+        PrintConv => $Image::ExifTool::Exif::Main{0x9217}->{PrintConv},
+    },
+    0x26000001 => { Name => 'FocalPlaneXResolution', Groups => { 2 => 'Camera' } },
+    0x26000002 => { Name => 'FocalPlaneYResolution', Groups => { 2 => 'Camera' } },
+    0x26000003 => {
+        Name => 'FocalPlaneResolutionUnit',
+        Groups => { 2 => 'Camera' },
+        PrintConv => $Image::ExifTool::Exif::Main{0xa210}->{PrintConv},
+    },
+    0x26000004 => 'SpatialFrequencyResponse',
+    0x26000005 => 'CFAPattern',
+    0x27000001 => {
+        Name => 'FilmCategory',
+        PrintConv => {
+            1 => 'Negative B&W',
+            2 => 'Negative Color',
+            3 => 'Reversal B&W',
+            4 => 'Reversal Color',
+            5 => 'Chromagenic',
+            6 => 'Internegative B&W',
+            7 => 'Internegative Color',
+        },
+    },
+    0x26000007 => 'ISO',
+    0x26000008 => 'Opto-ElectricConvFactor',
+    0x27000000 => 'FilmBrand',
+    0x27000001 => 'FilmCategory',
+    0x27000002 => 'FilmSize',
+    0x27000003 => 'FilmRollNumber',
+    0x27000004 => 'FilmFrameNumber',
+    0x29000000 => 'OriginalScannedImageSize',
+    0x29000001 => 'OriginalDocumentSize',
+    0x29000002 => {
+        Name => 'OriginalMedium',
+        PrintConv => {
+            1 => 'Continuous Tone Image',
+            2 => 'Halftone Image',
+            3 => 'Line Art',
+        },
+    },
+    0x29000003 => {
+        Name => 'TypeOfOriginal',
+        PrintConv => {
+            1 => 'B&W Print',
+            2 => 'Color Print',
+            3 => 'B&W Document',
+            4 => 'Color Document',
+        },
+    },
+    0x28000000 => 'ScannerMake',
+    0x28000001 => 'ScannerModel',
+    0x28000002 => 'ScannerSerialNumber',
+    0x28000003 => 'ScanSoftware',
+    0x28000004 => { Name => 'ScanSoftwareRevisionDate', Groups => { 2 => 'Time' } },
+    0x28000005 => 'ServiceOrganizationName',
+    0x28000006 => 'ScanOperatorID',
+    0x28000008 => { Name => 'ScanDate',   Groups => { 2 => 'Time' } },
+    0x28000009 => { Name => 'ModifyDate', Groups => { 2 => 'Time' } },
+    0x2800000A => 'ScannerPixelSize',
+);
+
+# Image Contents properties
+%Image::ExifTool::FlashPix::Image = (
+    PROCESS_PROC => \&ProcessProperties,
+    GROUPS => { 2 => 'Image' },
+    # VARS storage is used as a hash lookup for tagID's which aren't constant.
+    # The key is a mask for significant bits of the tagID, and the value
+    # is a lookup for tagID's for which this mask is valid.
+    VARS => {
+        # ID's are different for each subimage
+        0xff00ffff => {
+            0x02000000=>1, 0x02000001=>1, 0x02000002=>1, 0x02000003=>1,
+            0x02000004=>1, 0x02000005=>1, 0x02000006=>1, 0x02000007=>1,
+            0x03000001=>1,
+        },
+    },
+    0x01000000 => 'NumberOfResolutions',
+    0x01000002 => 'ImageWidth',     # width of highest resolution image
+    0x01000003 => 'ImageHeight',
+    0x01000004 => 'DefaultDisplayHeight',
+    0x01000005 => 'DefaultDisplayWidth',
+    0x01000006 => {
+        Name => 'DisplayUnits',
+        PrintConv => {
+            0 => 'inches',
+            1 => 'meters',
+            2 => 'cm',
+            3 => 'mm',
+        },
+    },
+    0x02000000 => 'SubimageWidth',
+    0x02000001 => 'SubimageHeight',
+    0x02000002 => {
+        Name => 'SubimageColor',
+        # decode only component count and color space of first component
+        ValueConv => 'sprintf("%.2x %.4x", unpack("x4vx4v",$val))',
+        PrintConv => {
+            '01 0000' => 'Opacity Only',
+            '01 8000' => 'Opacity Only (uncalibrated)',
+            '01 0001' => 'Monochrome',
+            '01 8001' => 'Monochrome (uncalibrated)',
+            '03 0002' => 'YCbCr',
+            '03 8002' => 'YCbCr (uncalibrated)',
+            '03 0003' => 'RGB',
+            '03 8003' => 'RGB (uncalibrated)',
+            '04 0002' => 'YCbCr with Opacity',
+            '04 8002' => 'YCbCr with Opacity (uncalibrated)',
+            '04 0003' => 'RGB with Opacity',
+            '04 8003' => 'RGB with Opacity (uncalibrated)',
+        },
+    },
+    0x02000003 => {
+        Name => 'SubimageNumericalFormat',
+        PrintConv => {
+            17 => '8-bit, Unsigned',
+            18 => '16-bit, Unsigned',
+            19 => '32-bit, Unsigned',
+        },
+    },
+    0x02000004 => {
+        Name => 'DecimationMethod',
+        PrintConv => {
+            0 => 'None (Full-sized Image)',
+            8 => '8-point Prefilter',
+        },
+    },
+    0x02000005 => 'DecimationPrefilterWidth',
+    0x02000007 => 'SubimageICC_Profile',
+    0x03000001 => { Name => 'JPEGTables', Binary => 1 },
+    0x03000002 => 'MaxJPEGTableIndex',
+);
+
+# Extension List properties
+%Image::ExifTool::FlashPix::Extensions = (
+    PROCESS_PROC => \&ProcessProperties,
+    GROUPS => { 2 => 'Other' },
+    VARS => {
+        # ID's are different for each extension type
+        0x0000ffff => {
+            0x0001=>1, 0x0002=>1, 0x0003=>1, 0x0004=>1,
+            0x0005=>1, 0x0006=>1, 0x0007=>1, 0x1000=>1,
+            0x2000=>1, 0x2001=>1, 0x3000=>1, 0x4000=>1,
+        },
+        0x0000f00f => { 0x3001=>1, 0x3002=>1 },
+    },
+    0x10000000 => 'UsedExtensionNumbers',
+    0x0001 => 'ExtensionName',
+    0x0002 => 'ExtensionClassID',
+    0x0003 => {
+        Name => 'ExtensionPersistence',
+        PrintConv => {
+            0 => 'Always Valid',
+            1 => 'Invalidated By Modification',
+            2 => 'Potentially Invalidated By Modification',
+        },
+    },
+    0x0004 => { Name => 'ExtensionCreateDate', Groups => { 2 => 'Time' } },
+    0x0005 => { Name => 'ExtensionModifyDate', Groups => { 2 => 'Time' } },
+    0x0006 => 'CreatingApplication',
+    0x0007 => 'ExtensionDescription',
+    0x1000 => 'Storage-StreamPathname',
+    0x2000 => 'FlashPixStreamPathname',
+    0x2001 => 'FlashPixStreamFieldOffset',
+    0x3000 => 'PropertySetPathname',
+    0x3001 => 'PropertySetIDCodes',
+    0x3002 => 'PropertyVectorElements',
+    0x4000 => 'SubimageResolutions',
+);
+
+# Subimage Header tags
+%Image::ExifTool::FlashPix::SubimageHdr = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int32u',
+#   0 => 'HeaderLength',
+    1 => 'SubimageWidth',
+    2 => 'SubimageHeight',
+    3 => 'SubimageTileCount',
+    4 => 'SubimageTileWidth',
+    5 => 'SubimageTileHeight',
+    6 => 'NumChannels',
+#   7 => 'TileHeaderOffset',
+#   8 => 'TileHeaderLength',
+    # ... followed by tile header table
+);
+
+# Data Object properties
+%Image::ExifTool::FlashPix::DataObject = (
+    PROCESS_PROC => \&ProcessProperties,
+    GROUPS => { 2 => 'Other' },
+    0x00010000 => 'DataObjectID',
+    0x00010002 => 'LockedPropertyList',
+    0x00010003 => 'DataObjectTitle',
+    0x00010004 => 'LastModifier',
+    0x00010005 => 'RevisionNumber',
+    0x00010006 => { Name => 'DataCreateDate', Groups => { 2 => 'Time' } },
+    0x00010007 => { Name => 'DataModifyDate', Groups => { 2 => 'Time' } },
+    0x00010008 => 'CreatingApplication',
+    0x00010100 => {
+        Name => 'DataObjectStatus',
+        PrintConv => q{
+            ($val & 0x0000ffff ? 'Exists' : 'Does Not Exist') .
+            ', ' . ($val & 0xffff0000 ? 'Not ' : '') . 'Purgeable'
+        },
+    },
+    0x00010101 => {
+        Name => 'CreatingTransform',
+        PrintConv => '$val ? $val :  "Source Image"',
+    },
+    0x00010102 => 'UsingTransforms',
+    0x10000000 => 'CachedImageHeight',
+    0x10000001 => 'CachedImageWidth',
+);
+
+# Transform properties
+%Image::ExifTool::FlashPix::Transform = (
+    PROCESS_PROC => \&ProcessProperties,
+    GROUPS => { 2 => 'Other' },
+    0x00010000 => 'TransformNodeID',
+    0x00010001 => 'OperationClassID',
+    0x00010002 => 'LockedPropertyList',
+    0x00010003 => 'TransformTitle',
+    0x00010004 => 'LastModifier',
+    0x00010005 => 'RevisionNumber',
+    0x00010006 => { Name => 'TransformCreateDate', Groups => { 2 => 'Time' } },
+    0x00010007 => { Name => 'TransformModifyDate', Groups => { 2 => 'Time' } },
+    0x00010008 => 'CreatingApplication',
+    0x00010100 => 'InputDataObjectList',
+    0x00010101 => 'OutputDataObjectList',
+    0x00010102 => 'OperationNumber',
+    0x10000000 => 'ResultAspectRatio',
+    0x10000001 => 'RectangleOfInterest',
+    0x10000002 => 'Filtering',
+    0x10000003 => 'SpatialOrientation',
+    0x10000004 => 'ColorTwistMatrix',
+    0x10000005 => 'ContrastAdjustment',
+);
+
+# Operation properties
+%Image::ExifTool::FlashPix::Operation = (
+    PROCESS_PROC => \&ProcessProperties,
+    0x00010000 => 'OperationID',
+);
+
+# Global Info properties
+%Image::ExifTool::FlashPix::GlobalInfo = (
+    PROCESS_PROC => \&ProcessProperties,
+    0x00010002 => 'LockedPropertyList',
+    0x00010003 => 'TransformedImageTitle',
+    0x00010004 => 'LastModifier',
+    0x00010100 => 'VisibleOutputs',
+    0x00010101 => 'MaximumImageIndex',
+    0x00010102 => 'MaximumTransformIndex',
+    0x00010103 => 'MaximumOperationIndex',
+);
+
+# Audio Info properties
+%Image::ExifTool::FlashPix::AudioInfo = (
+    PROCESS_PROC => \&ProcessProperties,
+    GROUPS => { 2 => 'Audio' },
+);
+
+# CompObj tags
+%Image::ExifTool::FlashPix::CompObj = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Other' },
+    FORMAT => 'int32u',
+    0 => { Name => 'CompObjUserTypeLen' },
+    1 => { Name => 'CompObjUserType', Format => 'string[$val{0}]' },
+);
+
+# composite FlashPix tags
+%Image::ExifTool::FlashPix::Composite = (
+    GROUPS => { 2 => 'Image' },
+    PreviewImage => {
+        # extract JPEG preview from ScreenNail if possible
+        Require => {
+            0 => 'ScreenNail',
+        },
+        Binary => 1,
+        RawConv => q{
+            return undef unless $val[0] =~ /\xff\xd8\xff/g;
+            return substr($val[0], pos($val[0])-3);
+        },
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::FlashPix');
+
+#------------------------------------------------------------------------------
+# Process hyperlinks from PID_HYPERLINKS array
+# (ref http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dnaro97ta/html/msdn_hyper97.asp)
+# Inputs: 0) value, 1) ExifTool ref
+# Returns: list of hyperlinks
+sub ProcessHyperlinks($$)
+{
+    my ($val, $exifTool) = @_;
+
+    # process as an array of VT_VARIANT's
+    my $dirEnd = length $val;
+    return undef if $dirEnd < 4;
+    my $num = Get32u(\$val, 0);
+    my $valPos = 4;
+    my ($i, @vals);
+    for ($i=0; $i<$num; ++$i) {
+        # read VT_BLOB entries as an array of VT_VARIANT's
+        my $value = ReadFPXValue($exifTool, \$val, $valPos, VT_VARIANT, $dirEnd);
+        last unless defined $value;
+        push @vals, $value;
+    }
+    # filter values to extract only the links
+    my @links;
+    for ($i=0; $i<@vals; $i+=6) {
+        push @links, $vals[$i+4];    # get address
+        $links[-1] .= '#' . $vals[$i+5] if length $vals[$i+5]; # add subaddress
+    }
+    return \@links;
+}
+
+#------------------------------------------------------------------------------
+# Print conversion for time span value
+sub ConvertTimeSpan($)
+{
+    my $val = shift;
+    if (Image::ExifTool::IsFloat($val) and $val != 0) {
+        if ($val < 60) {
+            $val = "$val seconds";
+        } elsif ($val < 3600) {
+            $val = sprintf("%.1f minutes", $val / 60);
+        } elsif ($val < 24 * 3600) {
+            $val = sprintf("%.1f hours", $val / 3600);
+        } else {
+            $val = sprintf("%.1f days", $val / (24 * 3600));
+        }
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Read FlashPix value
+# Inputs: 0) ExifTool ref, 1) data ref, 2) value offset, 3) FPX format number,
+#         4) end offset, 5) options: 0x01=no padding, 0x02=translate to UTF8
+# Returns: converted value (or list of values in list context) and updates
+#          value offset to end of value if successful, or returns undef on error
+sub ReadFPXValue($$$$$;$)
+{
+    my ($exifTool, $dataPt, $valPos, $type, $dirEnd, $opts) = @_;
+    $opts = 0 unless defined $opts;
+    my @vals;
+
+    my $format = $oleFormat{$type & 0x0fff};
+    while ($format) {
+        my $count = 1;
+        # handle VT_VECTOR types
+        my $flags = $type & 0xf000;
+        if ($flags) {
+            if ($flags == VT_VECTOR) {
+                $opts |= 0x01;  # values don't seem to be padded inside vectors
+                my $size = $oleFormatSize{VT_VECTOR};
+                last if $valPos + $size > $dirEnd;
+                $count = Get32u($dataPt, $valPos);
+                push @vals, '' if $count == 0;  # allow zero-element vector
+                $valPos += 4;
+            } else {
+                # can't yet handle this property flag
+                last;
+            }
+        }
+        unless ($format =~ /^VT_/) {
+            my $size = Image::ExifTool::FormatSize($format) * $count;
+            last if $valPos + $size > $dirEnd;
+            @vals = ReadValue($dataPt, $valPos, $format, $count, $size);
+            # update position to end of value plus padding
+            $valPos += ($count * $size + 3) & 0xfffffffc;
+            last;
+        }
+        my $size = $oleFormatSize{$format};
+        my ($item, $val);
+        for ($item=0; $item<$count; ++$item) {
+            last if $valPos + $size > $dirEnd;
+            if ($format eq 'VT_VARIANT') {
+                my $subType = Get32u($dataPt, $valPos);
+                $valPos += $size;
+                $val = ReadFPXValue($exifTool, $dataPt, $valPos, $subType, $dirEnd, $opts);
+                last unless defined $val;
+                push @vals, $val;
+                next;   # avoid adding $size to $valPos again
+            } elsif ($format eq 'VT_FILETIME') {
+                # get time in seconds
+                $val = 1e-7 * Image::ExifTool::Get64u($dataPt, $valPos);
+                # print as date/time if value is greater than one year (PH hack)
+                if ($val > 365 * 24 * 3600) {
+                    # shift from Jan 1, 1601 to Jan 1, 1970
+                    $val -= 134774 * 24 * 3600 if $val != 0;
+                    $val = Image::ExifTool::ConvertUnixTime($val);
+                }
+            } elsif ($format eq 'VT_DATE') {
+                $val = Image::ExifTool::GetDouble($dataPt, $valPos);
+                # shift zero from Dec 30, 1899 to Jan 1, 1970 and convert to secs
+                $val = ($val - 25569) * 24 * 3600 if $val != 0;
+                $val = Image::ExifTool::ConvertUnixTime($val);
+            } elsif ($format =~ /STR$/) {
+                my $len = Get32u($dataPt, $valPos);
+                $len *= 2 if $format eq 'VT_LPWSTR';    # convert to byte count
+                last if $valPos + $len + 4 > $dirEnd;
+                $val = substr($$dataPt, $valPos + 4, $len);
+                if ($format eq 'VT_LPWSTR') {
+                    # convert wide string from Unicode
+                    $val = $exifTool->Unicode2Charset($val);
+                } elsif ($opts & 0x02) {
+                    # convert from Latin1 to UTF-8
+                    $val = Image::ExifTool::Latin2Unicode($val,'v');
+                    $val = Image::ExifTool::Unicode2UTF8($val,'v');
+                }
+                $val =~ s/\0.*//s;  # truncate at null terminator
+                # update position for string length
+                # (the spec states that strings should be padded to align
+                #  on even 32-bit boundaries, but this isn't always the case)
+                $valPos += ($opts & 0x01) ? $len : ($len + 3) & 0xfffffffc;
+            } elsif ($format eq 'VT_BLOB' or $format eq 'VT_CF') {
+                my $len = Get32u($dataPt, $valPos);
+                last if $valPos + $len + 4 > $dirEnd;
+                $val = substr($$dataPt, $valPos + 4, $len);
+                # update position for data length plus padding
+                # (does this padding disappear in arrays too?)
+                $valPos += ($len + 3) & 0xfffffffc;
+            } elsif ($format eq 'VT_CLSID') {
+                $val = Image::ExifTool::ASF::GetGUID(substr($$dataPt, $valPos, $size));
+            }
+            $valPos += $size;   # update value pointer to end of value
+            push @vals, $val;
+        }
+        # join VT_ values with commas unless we want an array
+        @vals = ( join ', ', @vals ) if @vals > 1 and not wantarray;
+        last;   # didn't really want to loop
+    }
+    $_[2] = $valPos;    # return updated value position
+
+    if (wantarray) {
+        return @vals;
+    } elsif (@vals > 1) {
+        return join(' ', @vals);
+    } else {
+        return $vals[0];
+    }
+}
+
+#------------------------------------------------------------------------------
+# Check FPX byte order mark (BOM) and set byte order appropriately
+# Inputs: 0) data ref, 1) offset to BOM
+# Returns: true on success
+sub CheckBOM($$)
+{
+    my ($dataPt, $pos) = @_;
+    my $bom = Get16u($dataPt, $pos);
+    return 1 if $bom == 0xfffe;
+    return 0 unless $bom == 0xfeff;
+    ToggleByteOrder();
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process FlashPix properties
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessProperties($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $pos = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $pos;
+    my $dirEnd = $pos + $dirLen;
+    my $verbose = $exifTool->Options('Verbose');
+    my ($out, $n);
+
+    if ($dirLen < 48) {
+        $exifTool->Warn('Truncated FPX properties');
+        return 0;
+    }
+    # check and set our byte order if necessary
+    unless (CheckBOM($dataPt, $pos)) {
+        $exifTool->Warn('Bad FPX property byte order mark');
+        return 0;
+    }
+    # get position of start of section
+    $pos = Get32u($dataPt, $pos + 44);
+    if ($pos < 48) {
+        $exifTool->Warn('Bad FPX property section offset');
+        return 0;
+    }
+    for ($n=0; $n<2; ++$n) {
+        my %dictionary;     # dictionary to translate user-defined properties
+        my $opts = 0;       # option flags for converting values
+        last if $pos + 8 > $dirEnd;
+        # read property section header
+        my $size = Get32u($dataPt, $pos);
+        last unless $size;
+        my $numEntries = Get32u($dataPt, $pos + 4);
+        $verbose and $exifTool->VerboseDir('Property Info', $numEntries, $size);
+        if ($pos + 8 + 8 * $numEntries > $dirEnd) {
+            $exifTool->Warn('Truncated property list');
+            last;
+        }
+        my $index;
+        for ($index=0; $index<$numEntries; ++$index) {
+            my $entry = $pos + 8 + 8 * $index;
+            my $tag = Get32u($dataPt, $entry);
+            my $offset = Get32u($dataPt, $entry + 4);
+            my $valStart = $pos + 4 + $offset;
+            last if $valStart >= $dirEnd;
+            my $valPos = $valStart;
+            my $type = Get32u($dataPt, $pos + $offset);
+            if ($tag == 0) {
+                # read dictionary to get tag name lookup for this property set
+                my $i;
+                for ($i=0; $i<$type; ++$i) {
+                    last if $valPos + 8 > $dirEnd;
+                    $tag = Get32u($dataPt, $valPos);
+                    my $len = Get32u($dataPt, $valPos + 4);
+                    $valPos += 8 + $len;
+                    last if $valPos > $dirEnd;
+                    my $name = substr($$dataPt, $valPos - $len, $len);
+                    $name =~ s/\0.*//s;
+                    next unless length $name;
+                    $dictionary{$tag} = $name;
+                    next if $$tagTablePtr{$name};
+                    $tag = $name;
+                    $name =~ tr/a-zA-Z0-9//dc;
+                    next unless length $name;
+                    Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => ucfirst($name) });
+                }
+                next;
+            }
+            # use tag name from dictionary if available
+            my ($custom, $val);
+            if (defined $dictionary{$tag}) {
+                $tag = $dictionary{$tag};
+                $custom = 1;
+            }
+            my @vals = ReadFPXValue($exifTool, $dataPt, $valPos, $type, $dirEnd, $opts);
+            @vals or $exifTool->Warn('Error reading property value');
+            $val = @vals > 1 ? \@vals : $vals[0];
+            my $format = $type & 0x0fff;
+            my $flags = $type & 0xf000;
+            my $formStr = $oleFormat{$format} || "Type $format";
+            $formStr .= '|' . ($oleFlags{$flags} || sprintf("0x%x",$flags)) if $flags;
+            my $tagInfo;
+            # check for common tag ID's: Dictionary, CodePage and LocaleIndicator
+            # (must be done before masking because masked tags may overlap these ID's)
+            if (not $custom and ($tag == 1 or $tag == 0x80000000)) {
+                # get tagInfo from SummaryInfo table
+                my $summaryTable = GetTagTable('Image::ExifTool::FlashPix::SummaryInfo');
+                $tagInfo = $exifTool->GetTagInfo($summaryTable, $tag);
+                if ($tag == 1 and $val == 1252 and $exifTool->Options('Charset') eq 'UTF8') {
+                    # set flag to translate 8-bit text only if
+                    # code page is cp1252 and Charset is UTF8
+                    $opts |= 0x02;
+                }
+            } elsif ($$tagTablePtr{$tag}) {
+                $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+            } elsif ($$tagTablePtr{VARS} and not $custom) {
+                # mask off insignificant bits of tag ID if necessary
+                my $masked = $$tagTablePtr{VARS};
+                my $mask;
+                foreach $mask (keys %$masked) {
+                    if ($masked->{$mask}->{$tag & $mask}) {
+                        $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag & $mask);
+                        last;
+                    }
+                }
+            }
+            $exifTool->HandleTag($tagTablePtr, $tag, $val,
+                DataPt => $dataPt,
+                Start => $valStart,
+                Size => $valPos - $valStart,
+                Format => $formStr,
+                Index => $index,
+                TagInfo => $tagInfo,
+                Extra => ", type=$type",
+            );
+        }
+        # issue warning if we hit end of property section prematurely
+        $exifTool->Warn('Truncated property data') if $index < $numEntries;
+        last unless $$dirInfo{Multi};
+        $pos += $size;
+    }
+
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Load chain of sectors from file
+# Inputs: 0) RAF ref, 1) first sector number, 2) FAT ref, 3) sector size, 4) header size
+sub LoadChain($$$$$)
+{
+    my ($raf, $sect, $fatPt, $sectSize, $hdrSize) = @_;
+    return undef unless $raf;
+    my $chain = '';
+    my ($buff, %loadedSect);
+    for (;;) {
+        last if $sect == END_OF_CHAIN;
+        return undef if $loadedSect{$sect}; # avoid infinite loop
+        $loadedSect{$sect} = 1;
+        my $offset = $sect * $sectSize + $hdrSize;
+        return undef unless $offset <= 0x7fffffff and
+                            $raf->Seek($offset, 0) and
+                            $raf->Read($buff, $sectSize) == $sectSize;
+        $chain .= $buff;
+        # step to next sector in chain
+        return undef if $sect * 4 > length($$fatPt) - 4;
+        $sect = Get32u($fatPt, $sect * 4);
+    }
+    return $chain;
+}
+
+#------------------------------------------------------------------------------
+# Extract information from a JPEG APP2 FPXR segment
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessFPXR($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart};
+    my $dirLen = $$dirInfo{DirLen};
+    my $verbose = $exifTool->Options('Verbose');
+
+    if ($dirLen < 13) {
+        $exifTool->Warn('FPXR segment to small');
+        return 0;
+    }
+
+    # get version and segment type (version is 0 in all my samples)
+    my ($vers, $type) = unpack('x5C2', $$dataPt);
+
+    if ($type == 1) {   # a "Contents List" segment
+
+        $vers != 0 and $exifTool->Warn("Untested FPXR version $vers");
+        if ($$exifTool{FPXR}) {
+            $exifTool->Warn('Multiple FPXR contents lists');
+            delete $$exifTool{FPXR};
+        }
+        my $numEntries = unpack('x7n', $$dataPt);
+        my @contents;
+        $verbose and $exifTool->VerboseDir('Contents List', $numEntries);
+        my $pos = 9;
+        my $entry;
+        for ($entry = 0; $entry < $numEntries; ++$entry) {
+            if ($pos + 4 > $dirLen) {
+                $exifTool->Warn('Truncated FPXR contents');
+                return 0;
+            }
+            my ($size, $default) = unpack("x${pos}Na", $$dataPt);
+            pos($$dataPt) = $pos + 5;
+            # according to the spec, this string is little-endian
+            # (very odd, since the size word is big-endian),
+            # and the first char must be '/'
+            unless ($$dataPt =~ m{\G(/\0(..)*?)\0\0}sg) {
+                $exifTool->Warn('Invalid FPXR stream name');
+                return 0;
+            }
+            # convert stream pathname to ascii
+            my $name = Image::ExifTool::Unicode2Latin($1, 'v');
+            if ($verbose) {
+                my $psize = ($size == 0xffffffff) ? 'storage' : "$size bytes";
+                $exifTool->VPrint(0,"  |  $entry) Name: '$name' [$psize]\n");
+            }
+            # remove directory specification
+            $name =~ s{.*/}{}s;
+            # read storage class ID if necessary
+            my $classID;
+            if ($size == 0xffffffff) {
+                unless ($$dataPt =~ m{(.{16})}sg) {
+                    $exifTool->Warn('Truncated FPXR storage class ID');
+                    return 0;
+                }
+                # unpack class ID in case we want to use it sometime
+                $classID = Image::ExifTool::ASF::GetGUID($1);
+            }
+            # update position in list
+            $pos = pos($$dataPt);
+            # add to our contents list
+            push @contents, {
+                Name => $name,
+                Size => $size,
+                Default => $default,
+                ClassID => $classID,
+            };
+        }
+        # save contents list as $exifTool member variable
+        # (must do this last so we don't save list on error)
+        $$exifTool{FPXR} = \@contents;
+
+    } elsif ($type == 2) {  # a "Stream Data" segment
+
+        # get the contents list index and stream data offset
+        my ($index, $offset) = unpack('x7nN', $$dataPt);
+        my $fpxr = $$exifTool{FPXR};
+        if ($fpxr and $$fpxr[$index]) {
+            my $obj = $$fpxr[$index];
+            # extract stream data (after 13-byte header)
+            if (not defined $$obj{Stream}) {
+                # ignore offset for first segment of this type
+                # (in my sample images, this isn't always zero as one would expect)
+                $$obj{Stream} = substr($$dataPt, $dirStart+13);
+            } else {
+                # add data to the stream at the proper offset
+                my $pad = $offset - length($$obj{Stream});
+                if ($pad >= 0) {
+                    if ($pad) {
+                        if ($pad > 0x10000) {
+                            $exifTool->Warn("Bad FPXR stream offset ($offset)");
+                        } else {
+                            # pad with default value to specified offset
+                            $exifTool->Warn("Padding FPXR stream with $pad default bytes",1);
+                            $$obj{Stream} .= ($$obj{Default} x $pad);
+                        }
+                    }
+                    # concatinate data with this stream
+                    $$obj{Stream} .= substr($$dataPt, $dirStart+13);
+                } else {
+                    $exifTool->Warn("Duplicate FPXR stream data at offset $offset");
+                    substr($$obj{Stream}, $offset, -$pad) = substr($$dataPt, $dirStart+13);
+                }
+            }
+            # save value for this tag if stream is complete
+            my $len = length $$obj{Stream};
+            if ($len >= $$obj{Size}) {
+                if ($verbose) {
+                    $exifTool->VPrint(0, "  + [FPXR stream, Contents index $index, $len bytes]\n");
+                }
+                if ($len > $$obj{Size}) {
+                    $exifTool->Warn('Extra data in FPXR segment (truncated)');
+                    $$obj{Stream} = substr($$obj{Stream}, 0, $$obj{Size});
+                }
+                my $tag = $$obj{Name};
+                my $tagInfo;
+                unless ($$tagTablePtr{$tag}) {
+                    # remove instance number or class ID from tag if necessary
+                    $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $1) if
+                        ($tag =~ /(.*) \d{6}$/s and $$tagTablePtr{$1}) or
+                        ($tag =~ /(.*)_[0-9a-f]{16}$/s and $$tagTablePtr{$1});
+                }
+                # save the data for this tag
+                $exifTool->HandleTag($tagTablePtr, $tag, $$obj{Stream},
+                    DataPt => \$$obj{Stream},
+                    TagInfo => $tagInfo,
+                );
+                delete $$obj{Stream}; # done with this stream
+            }
+        } else {
+            $exifTool->Warn("Unlisted FPXR segment (index $index)");
+        }
+
+    } elsif ($type ne 3) {  # not a "Reserved" segment
+
+        $exifTool->Warn("Unknown FPXR segment (type $type)");
+
+    }
+
+    # clean up if this was the last FPXR segment
+    if ($$dirInfo{LastFPXR} and $$exifTool{FPXR}) {
+        my $obj;
+        my $i = 0;
+        foreach $obj (@{$$exifTool{FPXR}}) {
+            $exifTool->Warn("Missing stream for FPXR object $i") if defined $$obj{Stream};
+            ++$i;
+        }
+        delete $$exifTool{FPXR};    # delete our temporary variables
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Extract information from a FlashPix (FPX) file
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref
+# Returns: 1 on success, 0 if this wasn't a valid FPX image
+sub ProcessFPX($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my ($buff, $out, %dumpParms, $oldIndent, $miniStreamBuff);
+
+    # read header
+    return 0 unless $raf->Read($buff,HDR_SIZE) == HDR_SIZE;
+    # check signature
+    return 0 unless $buff =~ /^\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1/;
+
+    my $fileType = $exifTool->{FILE_EXT};
+    $fileType = 'FPX' unless $fileType and $fileType =~ /^(DOC|XLS|PPT)$/;
+    $exifTool->SetFileType($fileType);
+    SetByteOrder(substr($buff, 0x1c, 2) eq "\xff\xfe" ? 'MM' : 'II');
+    my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::Main');
+    my $verbose = $exifTool->Options('Verbose');
+
+    my $sectSize = 1 << Get16u(\$buff, 0x1e);
+    my $miniSize = 1 << Get16u(\$buff, 0x20);
+    my $fatCount   = Get32u(\$buff, 0x2c);  # number of FAT sectors
+    my $dirStart   = Get32u(\$buff, 0x30);  # first directory sector
+    my $miniCutoff = Get32u(\$buff, 0x38);  # minimum size for big-FAT streams
+    my $miniStart  = Get32u(\$buff, 0x3c);  # first sector of mini-FAT
+    my $miniCount  = Get32u(\$buff, 0x40);  # number of mini-FAT sectors
+    my $difStart   = Get32u(\$buff, 0x44);  # first sector of DIF chain
+    my $difCount   = Get32u(\$buff, 0x48);  # number of DIF sectors
+
+    if ($verbose) {
+        $out = $exifTool->Options('TextOut');
+        $dumpParms{MaxLen} = 96 if $verbose == 3;
+        print $out "  Sector size=$sectSize\n  FAT: Count=$fatCount\n";
+        print $out "  DIR: Start=$dirStart\n";
+        print $out "  MiniFAT: Mini-sector size=$miniSize Start=$miniStart Count=$miniCount Cutoff=$miniCutoff\n";
+        print $out "  DIF FAT: Start=$difStart Count=$difCount\n";
+    }
+#
+# load the FAT
+#
+    my $pos = 0x4c;
+    my $endPos = length($buff);
+    my $fat = '';
+    my $fatCountCheck = 0;
+    for (;;) {
+        while ($pos <= $endPos - 4) {
+            my $sect = Get32u(\$buff, $pos);
+            $pos += 4;
+            next if $sect == FREE_SECT;
+            my $offset = $sect * $sectSize + HDR_SIZE;
+            my $fatSect;
+            unless ($raf->Seek($offset, 0) and
+                    $raf->Read($fatSect, $sectSize) == $sectSize)
+            {
+                $exifTool->Error("Error reading FAT from sector $sect");
+                return 1;
+            }
+            $fat .= $fatSect;
+            ++$fatCountCheck;
+        }
+        last if $difStart == END_OF_CHAIN;
+        # read next DIF (Dual Indirect FAT) sector
+        my $offset = $difStart * $sectSize + HDR_SIZE;
+        unless ($raf->Seek($offset, 0) and $raf->Read($buff, $sectSize) == $sectSize) {
+            $exifTool->Error("Error reading DIF sector $difStart");
+            return 1;
+        }
+        # set end of sector information in this DIF
+        $endPos = $sectSize - 4;
+        # next time around we want to read next DIF in chain
+        $difStart = Get32u(\$buff, $endPos);
+    }
+    if ($fatCountCheck != $fatCount) {
+        $exifTool->Warn("Bad number of FAT sectors (expected $fatCount but found $fatCountCheck)");
+    }
+#
+# load the mini-FAT and the directory
+#
+    my $miniFat = LoadChain($raf, $miniStart, \$fat, $sectSize, HDR_SIZE);
+    my $dir = LoadChain($raf, $dirStart, \$fat, $sectSize, HDR_SIZE);
+    unless (defined $miniFat and defined $dir) {
+        $exifTool->Error('Error reading mini-FAT or directory stream');
+        return 1;
+    }
+    if ($verbose) {
+        print $out "  FAT [",length($fat)," bytes]:\n";
+        Image::ExifTool::HexDump(\$fat, undef, %dumpParms) if $verbose > 2;
+        print $out "  Mini-FAT [",length($miniFat)," bytes]:\n";
+        Image::ExifTool::HexDump(\$miniFat, undef, %dumpParms) if $verbose > 2;
+        print $out "  Directory [",length($dir)," bytes]:\n";
+        Image::ExifTool::HexDump(\$dir, undef, %dumpParms) if $verbose > 2;
+    }
+#
+# process the directory
+#
+    if ($verbose) {
+        $oldIndent = $exifTool->{INDENT};
+        $exifTool->{INDENT} .= '| ';
+        $exifTool->VerboseDir('FPX', undef, length $dir);
+    }
+    my $miniStream;
+    $endPos = length($dir);
+    my $index = 0;
+
+    for ($pos=0; $pos<=$endPos-128; $pos+=128) {
+
+        # get directory entry type
+        # (0=invalid, 1=storage, 2=stream, 3=lockbytes, 4=property, 5=root)
+        my $type = Get8u(\$dir, $pos + 0x42);
+        next if $type == 0; # skip invalid entries
+        if ($type > 5) {
+            $exifTool->Warn("Invalid directory entry type $type");
+            last;   # rest of directory is probably garbage
+        }
+        # get entry name (note: this is supposed to be length in 2-byte
+        # characters but this isn't what is done in my sample FPX file, so
+        # be very tolerant of this count -- it's null terminated anyway)
+        my $len = Get16u(\$dir, $pos + 0x40);
+        $len > 32 and $len = 32;
+        my $tag = Image::ExifTool::Unicode2Latin(substr($dir, $pos, $len * 2), 'v');
+        $tag =~ s/\0.*//s;  # truncate at null (in case length was wrong)
+
+        my $sect = Get32u(\$dir, $pos + 0x74);  # start sector number
+        my $size = Get32u(\$dir, $pos + 0x78);  # stream length
+
+        # load Ministream (referenced from first directory entry)
+        unless ($miniStream) {
+            $miniStreamBuff = LoadChain($raf, $sect, \$fat, $sectSize, HDR_SIZE);
+            unless (defined $miniStreamBuff) {
+                $exifTool->Warn('Error loading Mini-FAT stream');
+                last;
+            }
+            $miniStream = new File::RandomAccess(\$miniStreamBuff);
+        }
+
+        my $tagInfo;
+        if ($$tagTablePtr{$tag}) {
+            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        } else {
+            # remove instance number or class ID from tag if necessary
+            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $1) if
+                ($tag =~ /(.*) \d{6}$/s and $$tagTablePtr{$1}) or
+                ($tag =~ /(.*)_[0-9a-f]{16}$/s and $$tagTablePtr{$1});
+        }
+
+        next unless $tagInfo or $verbose;
+
+        # load the data for stream types
+        my $extra = '';
+        my $typeStr = $dirEntryType[$type] || $type;
+        if ($typeStr eq 'STREAM') {
+            if ($size >= $miniCutoff) {
+                # stream is in the main FAT
+                $buff = LoadChain($raf, $sect, \$fat, $sectSize, HDR_SIZE);
+            } elsif ($size) {
+                # stream is in the mini-FAT
+                $buff = LoadChain($miniStream, $sect, \$miniFat, $miniSize, 0);
+            } else {
+                $buff = ''; # an empty stream
+            }
+            unless (defined $buff) {
+                my $name = $tagInfo ? $$tagInfo{Name} : 'unknown';
+                $exifTool->Warn("Error reading $name stream");
+                $buff = '';
+            }
+        } elsif ($typeStr eq 'ROOT') {
+            $buff = $miniStreamBuff;
+            $extra .= ' (Ministream)';
+        } else {
+            $buff = '';
+            undef $size;
+        }
+        if ($verbose) {
+            my $flags = Get8u(\$dir, $pos + 0x43);  # 0=red, 1=black
+            my $lSib = Get32u(\$dir, $pos + 0x44);  # left sibling
+            my $rSib = Get32u(\$dir, $pos + 0x48);  # right sibling
+            my $chld = Get32u(\$dir, $pos + 0x4c);  # child directory
+            my $col = { 0 => 'Red', 1 => 'Black' }->{$flags} || $flags;
+            $extra .= " Type=$typeStr Flags=$col";
+            $extra .= " Left=$lSib" unless $lSib == FREE_SECT;
+            $extra .= " Right=$rSib" unless $rSib == FREE_SECT;
+            $extra .= " Child=$chld" unless $chld == FREE_SECT;
+            $exifTool->VerboseInfo($tag, $tagInfo,
+                Index => $index++,
+                Value => $buff,
+                DataPt => \$buff,
+                Extra => $extra,
+                Size => $size,
+            );
+        }
+        if ($tagInfo and $buff) {
+            if ($$tagInfo{SubDirectory}) {
+                my %dirInfo = (
+                    DataPt => \$buff,
+                    DirStart => $tagInfo->{SubDirectory}->{DirStart},
+                    DirLen => length $buff,
+                    Multi => $$tagInfo{Multi},
+                );
+                my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                $exifTool->ProcessDirectory(\%dirInfo, $subTablePtr);
+            } else {
+                $exifTool->FoundTag($tagInfo, $buff);
+            }
+        }
+    }
+    $exifTool->{INDENT} = $oldIndent if $verbose;
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::FlashPix - Read FlashPix meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to extract
+FlashPix meta information from FPX images, and from the APP2 FPXR segment of
+JPEG images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.exif.org/Exif2-2.PDF>
+
+=item L<http://www.graphcomp.com/info/specs/livepicture/fpx.pdf>
+
+=item L<http://search.cpan.org/~jdb/libwin32/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/FlashPix Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/FotoStation.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/FotoStation.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/FotoStation.pm	(revision 20131)
@@ -0,0 +1,260 @@
+#------------------------------------------------------------------------------
+# File:         FotoStation.pm
+#
+# Description:  Read/write FotoWare FotoStation trailer
+#
+# Revisions:    10/28/2006 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::FotoStation;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.00';
+
+sub ProcessFotoStation($$);
+
+%Image::ExifTool::FotoStation::Main = (
+    PROCESS_PROC => \&ProcessFotoStation,
+    WRITE_PROC => \&ProcessFotoStation,
+    GROUPS => { 2 => 'Image' },
+    NOTES => q{
+        The following tables define information found in the FotoWare FotoStation
+        trailer.
+    },
+    0x01 => {
+        Name => 'IPTC',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::IPTC::Main',
+        },
+    },
+    0x02 => {
+        Name => 'SoftEdit',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FotoStation::SoftEdit',
+        },
+    },
+    0x03 => {
+        Name => 'ThumbnailImage',
+        Writable => 1,
+        ValueConv => '$self->ValidateImage(\$val,$tag)',
+        ValueConvInv => '$val',
+    },
+    0x04 => {
+        Name => 'PreviewImage',
+        Writable => 1,
+        ValueConv => '$self->ValidateImage(\$val,$tag)',
+        ValueConvInv => '$val',
+    },
+);
+
+# crop coordinate conversions
+my %cropConv = (
+    ValueConv => '$val / 1000',
+    ValueConvInv => '$val * 1000',
+    PrintConv => '"$val%"',
+    PrintConvInv => '$val=~tr/ %//d; $val',
+);
+
+# soft crop record
+%Image::ExifTool::FotoStation::SoftEdit = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int32s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'OriginalImageWidth',
+    },
+    1 => 'OriginalImageHeight',
+    2 => 'ColorPlanes',
+    3 => {
+        Name => 'XYResolution',
+        ValueConv => '$val / 1000',
+        ValueConvInv => '$val * 1000',
+    },
+    4 => {
+        Name => 'Rotation',
+        Notes => q{
+            rotations are stored as degrees CCW * 100, but converted to degrees CW by
+            ExifTool
+        },
+        # raw value is 0, 9000, 18000 or 27000
+        ValueConv => '$val ? 360 - $val / 100 : 0',
+        ValueConvInv => '$val ? (360 - $val) * 100 : 0',
+    },
+    # 5 Validity Check (0x11222211)
+    6 => {
+        Name => 'CropLeft',
+        %cropConv,
+    },
+    7 => {
+        Name => 'CropTop',
+        %cropConv,
+    },
+    8 => {
+        Name => 'CropRight',
+        %cropConv,
+    },
+    9 => {
+        Name => 'CropBottom',
+        %cropConv,
+    },
+    11 => {
+        Name => 'CropRotation',
+        # raw value in the range -4500 to 4500
+        ValueConv => '-$val / 100',
+        ValueConvInv => '-$val * 100',
+    },
+);
+
+#------------------------------------------------------------------------------
+# Read/write FotoStation information in a file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this file didn't contain FotoStation information
+# - updates DataPos to point to start of FotoStation information
+# - updates DirLen to trailer length
+sub ProcessFotoStation($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    $exifTool or return 1;    # allow dummy access to autoload this package
+    my ($buff, $footer, $dirBuff, $tagTablePtr);
+    my $raf = $$dirInfo{RAF};
+    my $outfile = $$dirInfo{OutFile};
+    my $offset = $$dirInfo{Offset} || 0;
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my $rtnVal = 0;
+
+    $$dirInfo{DirLen} = 0;      # initialize returned trailer length
+    $raf->Seek(-$offset, 2);    # seek to specified offset from end of file
+
+    # loop through FotoStation records
+    for (;;) {
+        # look for trailer signature
+        last unless $raf->Seek(-10, 1) and $raf->Read($footer, 10) == 10;
+        my ($tag, $size, $sig) = unpack('nNN', $footer);
+        last unless $sig == 0xa1b2c3d4 and $size >= 10 and $raf->Seek(-$size, 1);
+        $size -= 10; # size of data only
+        last unless $raf->Read($buff, $size) == $size;
+        $raf->Seek(-$size, 1);
+        # set variables returned in dirInfo hash
+        $$dirInfo{DataPos} = $raf->Tell();
+        $$dirInfo{DirLen} += $size + 10;
+
+        unless ($tagTablePtr) {
+            $tagTablePtr = GetTagTable('Image::ExifTool::FotoStation::Main');
+            SetByteOrder('MM'); # necessary for the binary data
+            $rtnVal = 1;        # we found a valid FotoStation trailer
+        }
+        unless ($outfile) {
+            # print verbose trailer information
+            if ($verbose or $exifTool->{HTML_DUMP}) {
+                $exifTool->DumpTrailer({
+                    RAF => $raf,
+                    DataPos => $$dirInfo{DataPos},
+                    DirLen => $size + 10,
+                    DirName => "FotoStation_$tag",
+                });
+            }
+            # extract information for this tag
+            $exifTool->HandleTag($tagTablePtr, $tag, $buff,
+                                 DataPt => \$buff,
+                                 Start => 0,
+                                 Size => $size,
+                                 DataPos => $$dirInfo{DataPos});
+            next;
+        }
+        if ($exifTool->{DEL_GROUP}->{FotoStation}) {
+            $verbose and printf $out "  Deleting FotoStation trailer\n";
+            $verbose = 0;   # no more verbose messages after this
+            ++$exifTool->{CHANGED};
+            next;
+        }
+        # rewrite this information
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        if ($tagInfo) {
+            my $newVal;
+            my $tagName = $$tagInfo{Name};
+            if ($$tagInfo{SubDirectory}) {
+                my %subdirInfo = (
+                    DataPt => \$buff,
+                    DirStart => 0,
+                    DirLen => $size,
+                    DataPos => $$dirInfo{DataPos},
+                    DirName => $tagName,
+                    Parent => 'FotoStation',
+                );
+                my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+            } else {
+                my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+                if (Image::ExifTool::IsOverwriting($newValueHash) > 0) {
+                    $newVal = Image::ExifTool::GetNewValues($newValueHash);
+                    $newVal = '' unless defined $newVal;
+                    if ($verbose > 1) {
+                        my $n = length $newVal;
+                        print $out "    - FotoStation:$tagName ($size bytes)\n" if $size;
+                        print $out "    + FotoStation:$tagName ($n bytes)\n" if $n;
+                    }
+                    ++$exifTool->{CHANGED};
+                }
+            }
+            if (defined $newVal) {
+                # note: length may be 0 here, but we write the empty record anyway
+                $buff = $newVal;
+                $size = length($newVal) + 10;
+                $footer = pack('nNN', $tag, $size, $sig);
+            }
+        }
+        if (defined $dirBuff) {
+            # maintain original record order
+            $dirBuff = $buff . $footer . $dirBuff;
+        } else {
+            $dirBuff = $buff . $footer;
+        }
+    }
+    # write the modified FotoStation trailer
+    Write($outfile, $dirBuff) or $rtnVal = -1 if $dirBuff;
+    return $rtnVal;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::FotoStation - Read/write FotoWare FotoStation trailer
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read and
+write information from the FotoWare FotoStation trailer.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Mark Tate for information about the FotoStation data format.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/FotoStation Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/FujiFilm.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/FujiFilm.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/FujiFilm.pm	(revision 20131)
@@ -0,0 +1,490 @@
+#------------------------------------------------------------------------------
+# File:         FujiFilm.pm
+#
+# Description:  FujiFilm EXIF maker notes tags
+#
+# Revisions:    11/25/2003  - P. Harvey Created
+#
+# References:   1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
+#               2) http://homepage3.nifty.com/kamisaka/makernote/makernote_fuji.htm
+#               3) Michael Meissner private communication
+#               4) Paul Samuelson private communication (S5)
+#               5) http://www.cybercom.net/~dcoffin/dcraw/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::FujiFilm;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.14';
+
+%Image::ExifTool::FujiFilm::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x0 => {
+        Name => 'Version',
+        Writable => 'undef',
+    },
+    0x0010 => { #PH (how does this compare to actual serial number?)
+        Name => 'InternalSerialNumber',
+        Writable => 'string',
+        Notes => q{
+            this number is unique, and contains the date of manufacture, but doesn't
+            necessarily correspond to the camera body number -- this needs to be checked
+        },
+        # ie)  "FPX20017035 592D31313034060427796060110384"
+        # "FPX 20495643     592D313335310701318AD010110047" (F40fd)
+        #                               yymmdd
+        PrintConv => q{
+            return $val unless $val=~/^(.*)(\d{2})(\d{2})(\d{2})(.{12})$/;
+            my $yr = $2 + ($2 < 70 ? 2000 : 1900);
+            return "$1 $yr:$3:$4 $5";
+        },
+        PrintConvInv => '$_=$val; s/ (19|20)(\d{2}):(\d{2}):(\d{2}) /$2$3$4/; $_',
+    },
+    0x1000 => {
+        Name => 'Quality',
+        Writable => 'string',
+    },
+    0x1001 => {
+        Name => 'Sharpness',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Soft',
+            2 => 'Soft2',
+            3 => 'Normal',
+            4 => 'Hard',
+            5 => 'Hard2',
+        },
+    },
+    0x1002 => {
+        Name => 'WhiteBalance',
+        Flags => 'PrintHex',
+        Writable => 'int16u',
+        PrintConv => {
+            0x0   => 'Auto',
+            0x100 => 'Daylight',
+            0x200 => 'Cloudy',
+            0x300 => 'Daylight Fluorescent',
+            0x301 => 'Day White Fluorescent',
+            0x302 => 'White Fluorescent',
+            0x400 => 'Incandescent',
+            0x500 => 'Flash', #4
+            0xf00 => 'Custom',
+            0xff0 => 'Kelvin', #4
+        },
+    },
+    0x1003 => {
+        Name => 'Saturation',
+        Flags => 'PrintHex',
+        Writable => 'int16u',
+        PrintConv => {
+            0x0   => 'Normal',
+            0x100 => 'High',
+            0x200 => 'Low',
+            0x300 => 'None (B&W)', #2
+        },
+    },
+    0x1004 => {
+        Name => 'Contrast',
+        Flags => 'PrintHex',
+        Writable => 'int16u',
+        PrintConv => {
+            0x0   => 'Normal',
+            0x100 => 'High',
+            0x200 => 'Low',
+        },
+    },
+    0x1005 => { #4
+        Name => 'ColorTemperature',
+        Writable => 'int16u',
+    },
+    0x1010 => {
+        Name => 'FujiFlashMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'On',
+            2 => 'Off',
+            3 => 'Red-eye reduction',
+        },
+    },
+    0x1011 => {
+        Name => 'FlashStrength',
+        Writable => 'rational64s',
+    },
+    0x1020 => {
+        Name => 'Macro',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    0x1021 => {
+        Name => 'FocusMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Manual',
+        },
+    },
+    0x1023 => { #2
+        Name => 'FocusPixel',
+        Writable => 'int16u',
+        Count => 2,
+    },
+    0x1030 => {
+        Name => 'SlowSync',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    0x1031 => {
+        Name => 'PictureMode',
+        Flags => 'PrintHex',
+        Writable => 'int16u',
+        PrintConv => {
+            0x0 => 'Auto',
+            0x1 => 'Portrait',
+            0x2 => 'Landscape',
+            0x4 => 'Sports',
+            0x5 => 'Night Scene',
+            0x6 => 'Program AE',
+            0x7 => 'Natural Light', #3
+            0x8 => 'Anti-blur', #3
+            0xa => 'Sunset', #3
+            0xb => 'Museum', #3
+            0xc => 'Party', #3
+            0xd => 'Flower', #3
+            0xe => 'Text', #3
+            0xf => 'Natural Light & Flash', #3
+            0x10 => 'Beach', #3
+            0x11 => 'Snow', #3
+            0x12 => 'Fireworks', #3
+            0x13 => 'Underwater', #3
+            0x100 => 'Aperture-priority AE',
+            0x200 => 'Shutter speed priority AE',
+            0x300 => 'Manual',
+        },
+    },
+# this usually has a value of 1
+#    0x1032 => { #2
+#        Name => 'ShutterCount',
+#        Writable => 'int16u',
+#    },
+    0x1100 => {
+        Name => 'AutoBracketing',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'No flash & flash', #3
+        },
+    },
+    0x1101 => {
+        Name => 'SequenceNumber',
+        Writable => 'int16u',
+    },
+    0x1210 => { #2
+        Name => 'ColorMode',
+        Writable => 'int16u',
+        PrintHex => 1,
+        PrintConv => {
+            0x00 => 'Standard',
+            0x10 => 'Chrome',
+            0x30 => 'B & W',
+        },
+    },
+    0x1300 => {
+        Name => 'BlurWarning',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Blur Warning',
+        },
+    },
+    0x1301 => {
+        Name => 'FocusWarning',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Good',
+            1 => 'Out of focus',
+        },
+    },
+    0x1302 => {
+        Name => 'ExposureWarning',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Good',
+            1 => 'Bad exposure',
+        },
+    },
+    0x1400 => { #2
+        Name => 'DynamicRange',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Standard',
+            3 => 'Wide',
+        },
+    },
+    0x1401 => { #2
+        Name => 'FilmMode',
+        Writable => 'int16u',
+        PrintHex => 1,
+        PrintConv => {
+            0x000 => 'F0/Standard',
+            0x100 => 'F1/Studio Portrait',
+            0x200 => 'F2/Fujichrome',
+            0x300 => 'F3/Studio Portrait Ex',
+            0x400 => 'F4/Velvia',
+        },
+    },
+    0x1402 => { #2
+        Name => 'DynamicRangeSetting',
+        Writable => 'int16u',
+        PrintHex => 1,
+        PrintConv => {
+            0x000 => 'Auto (100-400%)',
+            0x001 => 'RAW',
+            0x100 => 'Standard (100%)',
+            0x200 => 'Wide1 (230%)',
+            0x201 => 'Wide2 (400%)',
+            0x8000 => 'Film Simulation Mode',
+        },
+    },
+    0x1403 => { #2
+        Name => 'DevelopmentDynamicRange',
+        Writable => 'int16u',
+    },
+    0x1404 => { #2
+        Name => 'MinFocalLength',
+        Writable => 'rational64s',
+    },
+    0x1405 => { #2
+        Name => 'MaxFocalLength',
+        Writable => 'rational64s',
+    },
+    0x1406 => { #2
+        Name => 'MaxApertureAtMinFocal',
+        Writable => 'rational64s',
+    },
+    0x1407 => { #2
+        Name => 'MaxApertureAtMaxFocal',
+        Writable => 'rational64s',
+    },
+    0x8000 => { #2
+        Name => 'FileSource',
+        Writable => 'string',
+    },
+    0x8002 => { #2
+        Name => 'OrderNumber',
+        Writable => 'int32u',
+    },
+    0x8003 => { #2
+        Name => 'FrameNumber',
+        Writable => 'int16u',
+    },
+);
+
+# tags in RAF images (ref 5)
+%Image::ExifTool::FujiFilm::RAF = (
+    GROUPS => { 0 => 'RAF', 1 => 'RAF', 2 => 'Image' },
+    NOTES => 'Tags extracted from FujiFilm RAF-format information.',
+    0x100 => {
+        Name => 'RawImageFullSize',
+        Format => 'int16u',
+        Groups => { 1 => 'RAF2' }, # (so RAF2 shows up in family 1 list)
+        Count => 2,
+        Notes => 'including borders',
+        ValueConv => 'my @v=reverse split(" ",$val);"@v"',
+        PrintConv => '$val=~tr/ /x/; $val',
+    },
+    0x121 => [
+        {
+            Name => 'RawImageSize',
+            Condition => '$$self{CameraModel} eq "FinePixS2Pro"',
+            Format => 'int16u',
+            Count => 2,
+            ValueConv => q{
+                my @v=split(" ",$val);
+                $v[0]*=2, $v[1]/=2;
+                return "@v";
+            },
+            PrintConv => '$val=~tr/ /x/; $val',
+        },
+        {
+            Name => 'RawImageSize',
+            Format => 'int16u',
+            Count => 2,
+            # values are height then width, adjusted for the layout
+            ValueConv => q{
+                my @v=reverse split(" ",$val);
+                $$self{FujiLayout} and $v[0]/=2, $v[1]*=2;
+                return "@v";
+            },
+            PrintConv => '$val=~tr/ /x/; $val',
+        },
+    ],
+    0x130 => {
+        Name => 'FujiLayout',
+        Format => 'int8u',
+        RawConv => q{
+            my ($v) = split ' ', $val;
+            $$self{FujiLayout} = $v & 0x80 ? 1 : 0;
+            return $val;
+        },
+    },
+    0x2ff0 => {
+        Name => 'WB_GRGBLevels',
+        Format => 'int16u',
+        Count => 4,
+    },
+);
+
+#------------------------------------------------------------------------------
+# get information from FujiFilm RAF directory
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) tag table ref
+# Returns: 1 if this was a valid FujiFilm directory
+sub ProcessFujiDir($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $offset = $$dirInfo{DirStart};
+    $raf->Seek($offset, 0) or return 0;
+    my $buff;
+    $raf->Read($buff, 4) or return 0;
+    my $entries = unpack 'N', $buff;
+    $entries < 256 or return 0;
+    SetByteOrder('MM');
+    while ($entries--) {
+        $raf->Read($buff,4) or return 0;
+        my ($tag, $len) = unpack 'nn', $buff;
+        my ($val, $vbuf);
+        $raf->Read($vbuf, $len) or return 0;
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        if ($tagInfo and $$tagInfo{Format}) {
+            $val = ReadValue(\$vbuf, 0, $$tagInfo{Format}, $$tagInfo{Count}, $len);
+            next unless defined $val;
+        } else {
+            $val = \$vbuf;
+        }
+        $exifTool->HandleTag($tagTablePtr, $tag, $val);
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# get information from FujiFilm RAW file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 if this was a valid FujiFilm RAW file
+sub ProcessRAF($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my ($buff, $warn);
+
+    my $raf = $$dirInfo{RAF};
+    $raf->Read($buff,8) == 8        or return 0;
+    $buff eq 'FUJIFILM'             or return 0;
+    $raf->Seek(84, 0)               or return 0;
+    $raf->Read($buff, 8) == 8       or return 0;
+    my ($pos, $len) = unpack('NN', $buff);
+    $pos & 0x8000                  and return 0;
+    $raf->Seek($pos, 0)             or return 0;
+    $raf->Read($buff, $len) == $len or return 0;
+    my %dirInfo = (
+        Parent => 'RAF',
+        RAF    => new File::RandomAccess(\$buff),
+    );
+    $$exifTool{BASE} += $pos;
+    my $rtnVal = $exifTool->ProcessJPEG(\%dirInfo);
+    $$exifTool{BASE} -= $pos;
+    $exifTool->FoundTag('PreviewImage', \$buff) if $rtnVal;
+
+    if ($raf->Seek(92, 0) and $raf->Read($buff, 4)) {
+        my $tagTablePtr = GetTagTable('Image::ExifTool::FujiFilm::RAF');
+        %dirInfo = (
+            RAF => $raf,
+            DirStart => unpack('N', $buff),
+        );
+        $$exifTool{SET_GROUP1} = 'RAF';
+        ProcessFujiDir($exifTool, \%dirInfo, $tagTablePtr) or $warn = 1;
+    
+        # extract information from 2nd image if available
+        if ($pos > 120) {
+            $raf->Seek(120, 0) or return 0;
+            $raf->Read($buff, 4) or return 0;
+            my $start = unpack('N',$buff);
+            if ($start) {
+                $$dirInfo{DirStart} = $start;
+                $$exifTool{SET_GROUP1} = 'RAF2';
+                ProcessFujiDir($exifTool, \%dirInfo, $tagTablePtr) or $warn = 1;
+            }
+        }
+        delete $$exifTool{SET_GROUP1};
+    } else {
+        $warn = 1;
+    }
+    $warn and $exifTool->Warn('Possibly corrupt RAF information');
+
+    return $rtnVal;
+}
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::FujiFilm - FujiFilm EXIF maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+FujiFilm maker notes in EXIF information, and to read FujiFilm RAW (RAF)
+images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html>
+
+=item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_fuji.htm>
+
+=item L<http://www.cybercom.net/~dcoffin/dcraw/>
+
+=item (...plus testing with my own FinePix 2400 Zoom)
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Michael Meissner for decoding some new PictureMode and
+AutoBracketing values, and to Paul Samuelson for decoding some WhiteBalance
+values and the ColorTemperature tag.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/FujiFilm Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/GIF.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/GIF.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/GIF.pm	(revision 20131)
@@ -0,0 +1,221 @@
+#------------------------------------------------------------------------------
+# File:         GIF.pm
+#
+# Description:  Read and write GIF meta information
+#
+# Revisions:    10/18/2005 - P. Harvey Separated from ExifTool.pm
+#
+# References:   http://www.w3.org/Graphics/GIF/spec-gif89a.txt
+#
+# Notes:        GIF really doesn't have much meta information, except for
+#               comments which are allowed in GIF89a images
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::GIF;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess);
+
+$VERSION = '1.04';
+
+#------------------------------------------------------------------------------
+# Process meta information in GIF image
+# Inputs: 0) ExifTool object reference, 1) Directory information ref
+# Returns: 1 on success, 0 if this wasn't a valid GIF file, or -1 if
+#          an output file was specified and a write error occurred
+sub ProcessGIF($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my ($type, $a, $s, $ch, $length, $buff);
+    my ($err, $newComment, $setComment);
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my $outfile = $$dirInfo{OutFile};
+    my $raf = $$dirInfo{RAF};
+    my $rtnVal = 0;
+
+    # verify this is a valid GIF file
+    # (must do a RAF read until we know the file is ours)
+    return 0 unless $raf->Read($type, 6) == 6
+        and $type =~ /^GIF8[79]a$/
+        and $raf->Read($s, 4) == 4;
+
+    $verbose and print $out "GIF file version $type\n";
+    if ($outfile) {
+        Write($outfile, $type, $s) or $err = 1;
+        if ($exifTool->{DEL_GROUP}->{File}) {
+            $setComment = 1;
+            if ($exifTool->{DEL_GROUP}->{File} == 2) {
+                $newComment = $exifTool->GetNewValues('Comment');
+            }
+        } else {
+            my $newValueHash;
+            $newComment = $exifTool->GetNewValues('Comment', \$newValueHash);
+            $setComment = 1 if $newValueHash;
+        }
+    }
+    $exifTool->SetFileType();   # set file type
+    my ($w, $h) = unpack("v"x2, $s);
+    $exifTool->FoundTag('ImageWidth', $w);
+    $exifTool->FoundTag('ImageHeight', $h);
+    if ($raf->Read($s, 3) == 3) {
+        Write($outfile, $s) or $err = 1 if $outfile;
+        if (ord($s) & 0x80) { # does this image contain a color table?
+            # calculate color table size
+            $length = 3 * (2 << (ord($s) & 0x07));
+            $raf->Read($buff, $length) == $length or return 0; # skip color table
+            Write($outfile, $buff) or $err = 1 if $outfile;
+        }
+        # write the comment first if necessary
+        if ($outfile and defined $newComment) {
+            if ($type ne 'GIF87a') {
+                # write comment marker
+                Write($outfile, "\x21\xfe") or $err = 1;
+                my $len = length($newComment);
+                # write out the comment in 255-byte chunks, each
+                # chunk beginning with a length byte
+                my $n;
+                for ($n=0; $n<$len; $n+=255) {
+                    my $size = $len - $n;
+                    $size > 255 and $size = 255;
+                    my $str = substr($newComment,$n,$size);
+                    Write($outfile, pack('C',$size), $str) or $err = 1;
+                }
+                Write($outfile, "\0") or $err = 1;  # empty chunk as terminator
+                undef $newComment;
+                ++$exifTool->{CHANGED};     # increment file changed flag
+            } else {
+                $exifTool->Warn("The GIF87a format doesn't support comments");
+            }
+        }
+        my $comment;
+        for (;;) {
+            last unless $raf->Read($ch, 1);
+            if (ord($ch) == 0x2c) {
+                Write($outfile, $ch) or $err = 1 if $outfile;
+                # image descriptor
+                last unless $raf->Read($buff, 8) == 8;
+                last unless $raf->Read($ch, 1);
+                Write($outfile, $buff, $ch) or $err = 1 if $outfile;
+                if (ord($ch) & 0x80) { # does color table exist?
+                    $length = 3 * (2 << (ord($ch) & 0x07));
+                    # skip the color table
+                    last unless $raf->Read($buff, $length) == $length;
+                    Write($outfile, $buff) or $err = 1 if $outfile;
+                }
+                # skip "LZW Minimum Code Size" byte
+                last unless $raf->Read($buff, 1);
+                Write($outfile,$buff) or $err = 1 if $outfile;
+                # skip image blocks
+                for (;;) {
+                    last unless $raf->Read($ch, 1);
+                    Write($outfile, $ch) or $err = 1 if $outfile;
+                    last unless ord($ch);
+                    last unless $raf->Read($buff, ord($ch));
+                    Write($outfile,$buff) or $err = 1 if $outfile;
+                }
+                next;  # continue with next field
+            }
+#               last if ord($ch) == 0x3b;  # normal end of GIF marker
+            unless (ord($ch) == 0x21) {
+                if ($outfile) {
+                    Write($outfile, $ch) or $err = 1;
+                    # copy the rest of the file
+                    while ($raf->Read($buff, 65536)) {
+                        Write($outfile, $buff) or $err = 1;
+                    }
+                }
+                $rtnVal = 1;
+                last;
+            }
+            # get extension block type/size
+            last unless $raf->Read($s, 2) == 2;
+            # get marker and block size
+            ($a,$length) = unpack("C"x2, $s);
+            if ($a == 0xfe) {  # is this a comment?
+                if ($setComment) {
+                    ++$exifTool->{CHANGED}; # increment the changed flag
+                } else {
+                    Write($outfile, $ch, $s) or $err = 1 if $outfile;
+                }
+                while ($length) {
+                    last unless $raf->Read($buff, $length) == $length;
+                    $verbose > 2 and Image::ExifTool::HexDump(\$buff, undef, Out => $out);
+                    if (defined $comment) {
+                        $comment .= $buff;  # add to comment string
+                    } else {
+                        $comment = $buff;
+                    }
+                    last unless $raf->Read($ch, 1);  # read next block header
+                    unless ($setComment) {
+                        Write($outfile, $buff, $ch) or $err = 1 if $outfile;
+                    }
+                    $length = ord($ch);  # get next block size
+                }
+                last if $length;    # was a read error if length isn't zero
+                unless ($outfile) {
+                    $rtnVal = 1;
+                    $exifTool->FoundTag('Comment', $comment) if $comment;
+                    undef $comment;
+                    # assume no more than one comment in FastScan mode
+                    last if $exifTool->Options('FastScan');
+                }
+            } else {
+                Write($outfile, $ch, $s) or $err = 1 if $outfile;
+                # skip the block
+                while ($length) {
+                    last unless $raf->Read($buff, $length) == $length;
+                    Write($outfile, $buff) or $err = 1 if $outfile;
+                    last unless $raf->Read($ch, 1);  # read next block header
+                    Write($outfile, $ch) or $err = 1 if $outfile;
+                    $length = ord($ch);  # get next block size
+                }
+            }
+        }
+        $exifTool->FoundTag('Comment', $comment) if $comment;
+    }
+    # set return value to -1 if we only had a write error
+    $rtnVal = -1 if $rtnVal and $err;
+    return $rtnVal;
+}
+
+
+1;  #end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::GIF - Read and write GIF meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read and
+write GIF meta information.  GIF87a images contain no meta information, and
+only the Comment tag is currently supported in GIF89a images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.w3.org/Graphics/GIF/spec-gif89a.txt>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/GPS.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/GPS.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/GPS.pm	(revision 20131)
@@ -0,0 +1,413 @@
+#------------------------------------------------------------------------------
+# File:         GPS.pm
+#
+# Description:  EXIF GPS meta information tags
+#
+# Revisions:    12/09/2003  - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::GPS;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.17';
+
+my %coordConv = (
+    ValueConv    => 'Image::ExifTool::GPS::ToDegrees($val)',
+    ValueConvInv => 'Image::ExifTool::GPS::ToDMS($self, $val)',
+    PrintConv    => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
+    PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val)',
+);
+
+%Image::ExifTool::GPS::Main = (
+    GROUPS => { 0 => 'EXIF', 1 => 'GPS', 2 => 'Location' },
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    WRITE_GROUP => 'GPS',
+    NOTES => q{
+        When adding GPS information to an image, it is important to set all of the
+        following tags: GPSLatitude, GPSLatitudeRef, GPSLongitude, GPSLongitudeRef,
+        GPSAltitude and GPSAltitudeRef.  ExifTool will write the required
+        GPSVersionID tag automatically if new a GPS IFD is added to an image.
+    },
+    0x0000 => {
+        Name => 'GPSVersionID',
+        Writable => 'int8u',
+        Count => 4,
+        PrintConv => '$val =~ tr/ /./; $val',
+        PrintConvInv => '$val =~ tr/./ /; $val',
+    },
+    0x0001 => {
+        Name => 'GPSLatitudeRef',
+        Writable => 'string',
+        Count => 2,
+        PrintConv => {
+            N => 'North',
+            S => 'South',
+        },
+    },
+    0x0002 => {
+        Name => 'GPSLatitude',
+        Writable => 'rational64u',
+        Count => 3,
+        %coordConv,
+    },
+    0x0003 => {
+        Name => 'GPSLongitudeRef',
+        Writable => 'string',
+        Count => 2,
+        PrintConv => {
+            E => 'East',
+            W => 'West',
+        },
+    },
+    0x0004 => {
+        Name => 'GPSLongitude',
+        Writable => 'rational64u',
+        Count => 3,
+        %coordConv,
+    },
+    0x0005 => {
+        Name => 'GPSAltitudeRef',
+        Writable => 'int8u',
+        PrintConv => {
+            0 => 'Above Sea Level',
+            1 => 'Below Sea Level',
+        },
+    },
+    0x0006 => {
+        Name => 'GPSAltitude',
+        Writable => 'rational64u',
+        PrintConv => '$val eq "inf" ? $val : "$val m"',
+        PrintConvInv => '$val=~s/\s*m$//;$val',
+    },
+    0x0007 => {
+        Name => 'GPSTimeStamp',
+        Groups => { 2 => 'Time' },
+        Writable => 'rational64u',
+        Count => 3,
+        Shift => 'Time',
+        ValueConv => sub {
+            my $val = shift;
+            my ($h,$m,$s) = split ' ', $val;
+            my $f = (($h || 0) * 60 + ($m || 0)) * 60 + ($s || 0);
+            $h = int($f / 3600); $f -= $h * 3600;
+            $m = int($f / 60);   $f -= $m * 60;
+            $s = int($f);        $f -= $s;
+            $f = int($f * 1000000 + 0.5);
+            if ($f) {
+                ($f = sprintf(".%.6d", $f)) =~ s/0+$//;
+            } else {
+                $f = ''
+            }
+            return sprintf("%.2d:%.2d:%.2d$f",$h,$m,$s);
+        },
+        ValueConvInv => '$val=~tr/:/ /;$val',
+        # pull time out of any format date/time string
+        # (eventually handle timezones? -- timestamp should be UTC)
+        PrintConvInv => sub {
+            my $v = shift;
+            $v =~ s/[-+].*//s; # remove timezone
+            my @a = ($v =~ /((?=\d|\.\d)\d*(?:\.\d*)?)/g);
+            push @a, '00' while @a < 3;
+            return "$a[-3]:$a[-2]:$a[-1]";
+        },
+    },
+    0x0008 => {
+        Name => 'GPSSatellites',
+        Writable => 'string',
+    },
+    0x0009 => {
+        Name => 'GPSStatus',
+        Writable => 'string',
+        Count => 2,
+        PrintConv => {
+            A => 'Measurement In Progress',
+            V => 'Measurement Interoperability',
+        },
+    },
+    0x000A => {
+        Name => 'GPSMeasureMode',
+        Writable => 'string',
+        Count => 2,
+        PrintConv => {
+            2 => '2-Dimensional Measurement',
+            3 => '3-Dimensional Measurement',
+        },
+    },
+    0x000B => {
+        Name => 'GPSDOP',
+        Description => 'GPS Dilution Of Precision',
+        Writable => 'rational64u',
+    },
+    0x000C => {
+        Name => 'GPSSpeedRef',
+        Writable => 'string',
+        Count => 2,
+        PrintConv => {
+            K => 'km/h',
+            M => 'mph',
+            N => 'knots',
+        },
+    },
+    0x000D => {
+        Name => 'GPSSpeed',
+        Writable => 'rational64u',
+    },
+    0x000E => {
+        Name => 'GPSTrackRef',
+        Writable => 'string',
+        Count => 2,
+        PrintConv => {
+            M => 'Magnetic North',
+            T => 'True North',
+        },
+    },
+    0x000F => {
+        Name => 'GPSTrack',
+        Writable => 'rational64u',
+    },
+    0x0010 => {
+        Name => 'GPSImgDirectionRef',
+        Writable => 'string',
+        Count => 2,
+        PrintConv => {
+            M => 'Magnetic North',
+            T => 'True North',
+        },
+    },
+    0x0011 => {
+        Name => 'GPSImgDirection',
+        Writable => 'rational64u',
+    },
+    0x0012 => {
+        Name => 'GPSMapDatum',
+        Writable => 'string',
+    },
+    0x0013 => {
+        Name => 'GPSDestLatitudeRef',
+        Writable => 'string',
+        Count => 2,
+        PrintConv => {
+            N => 'North',
+            S => 'South',
+        },
+    },
+    0x0014 => {
+        Name => 'GPSDestLatitude',
+        Writable => 'rational64u',
+        Count => 3,
+        %coordConv,
+    },
+    0x0015 => {
+        Name => 'GPSDestLongitudeRef',
+        Writable => 'string',
+        Count => 2,
+        PrintConv => {
+            E => 'East',
+            W => 'West',
+        },
+    },
+    0x0016 => {
+        Name => 'GPSDestLongitude',
+        Writable => 'rational64u',
+        Count => 3,
+        %coordConv,
+    },
+    0x0017 => {
+        Name => 'GPSDestBearingRef',
+        Writable => 'string',
+        Count => 2,
+        PrintConv => {
+            M => 'Magnetic North',
+            T => 'True North',
+        },
+    },
+    0x0018 => {
+        Name => 'GPSDestBearing',
+        Writable => 'rational64u',
+    },
+    0x0019 => {
+        Name => 'GPSDestDistanceRef',
+        Writable => 'string',
+        Count => 2,
+        PrintConv => {
+            K => 'Kilometers',
+            M => 'Miles',
+            N => 'Nautical Miles',
+        },
+    },
+    0x001A => {
+        Name => 'GPSDestDistance',
+        Writable => 'rational64u',
+    },
+    0x001B => {
+        Name => 'GPSProcessingMethod',
+        Writable => 'undef',
+        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+        PrintConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
+    },
+    0x001C => {
+        Name => 'GPSAreaInformation',
+        Writable => 'undef',
+        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+        PrintConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
+    },
+    0x001D => {
+        Name => 'GPSDateStamp',
+        Groups => { 2 => 'Time' },
+        Writable => 'string',
+        Notes => 'YYYY:MM:DD',
+        Count => 11,
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
+        ValueConvInv => '$val',
+        # pull date out of any format date/time string
+        PrintConvInv => '$val=~/(\d{4}).*?(\d{2}).*?(\d{2})/ ? "$1:$2:$3" : $val',
+    },
+    0x001E => {
+        Name => 'GPSDifferential',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'No Correction',
+            1 => 'Differential Corrected',
+        },
+    },
+);
+
+# Composite GPS tags
+%Image::ExifTool::GPS::Composite = (
+    GPSDateTime => {
+        Description => 'GPS Date/Time',
+        Groups => { 2 => 'Time' },
+        Require => {
+            0 => 'GPSDateStamp',
+            1 => 'GPSTimeStamp',
+        },
+        ValueConv => '"$val[0] $val[1]"',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    GPSLatitude => {
+        Require => {
+            0 => 'GPS:GPSLatitude',
+            1 => 'GPS:GPSLatitudeRef',
+        },
+        ValueConv => '$val[1] =~ /^S/i ? -$val[0] : $val[0]',
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
+    },
+    GPSLongitude => {
+        Require => {
+            0 => 'GPS:GPSLongitude',
+            1 => 'GPS:GPSLongitudeRef',
+        },
+        ValueConv => '$val[1] =~ /^W/i ? -$val[0] : $val[0]',
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::GPS');
+
+#------------------------------------------------------------------------------
+# Convert degrees to DMS, or whatever the current settings are
+# Inputs: 0) ExifTool reference, 1) Value in degrees,
+#         2) format code (0=no format, 1=CoordFormat, 2=XMP format)
+#         3) 'N' or 'E' if sign is significant and N/S/E/W should be added
+# Returns: DMS string
+sub ToDMS($$;$$)
+{
+    my ($exifTool, $val, $doPrintConv, $ref) = @_;
+    my ($fmt, $num);
+
+    if ($ref) {
+        if ($val < 0) {
+            $val = -$val;
+            $ref = {N => 'S', E => 'W'}->{$ref};
+        }
+        $ref = " $ref" unless $doPrintConv and $doPrintConv eq '2';
+    } else {
+        $ref = '';
+    }
+    if ($doPrintConv) {
+        if ($doPrintConv eq '1') {
+            $fmt = ($exifTool->Options('CoordFormat') || q{%d deg %d' %.2f"}) . $ref;
+        } else {
+            $fmt = "%d,%.6f$ref";   # use XMP standard format
+        }
+        # count the number of format specifiers
+        $num = ($fmt =~ tr/%/%/);
+    } else {
+        $num = 3;
+    }
+    my ($d, $m, $s);
+    $d = $val;
+    if ($num > 1) {
+        $d = int($d);
+        $m = ($val - $d) * 60;
+        if ($num > 2) {
+            $m = int($m);
+            $s = ($val - $d - $m / 60) * 3600;
+        }
+    }
+    return $doPrintConv ? sprintf($fmt, $d, $m, $s) : "$d $m $s$ref";
+}
+
+#------------------------------------------------------------------------------
+# Convert to decimal degrees
+# Inputs: 0) a string containing 1-3 decimal numbers and any amount of other garbage
+#         1) true if value should be negative if coordinate ends in 'S' or 'W'
+# Returns: Coordinate in degrees
+sub ToDegrees($;$)
+{
+    my ($val, $doSign) = @_;
+    # extract decimal values out of any other garbage
+    my ($d, $m, $s) = ($val =~ /((?:[+-]?)(?=\d|\.\d)\d*(?:\.\d*)?)/g);
+    my $deg = ($d || 0) + (($m || 0) + ($s || 0)/60) / 60;
+    # make negative if S or W coordinate
+    $deg = -$deg if $doSign ? $val =~ /[^A-Z](S|W)$/i : $deg < 0;
+    return $deg;
+}
+
+
+1;  #end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::GPS - EXIF GPS meta information tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+GPS (Global Positioning System) meta information in EXIF data.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<Image::Info|Image::Info>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/GPS Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>,
+L<Image::Info(3pm)|Image::Info>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/GeoTiff.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/GeoTiff.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/GeoTiff.pm	(revision 20131)
@@ -0,0 +1,2190 @@
+#------------------------------------------------------------------------------
+# File:         GeoTiff.pm
+#
+# Description:  Read GeoTiff meta information
+#
+# Revisions:    02/23/04 - P. Harvey Created
+#               02/25/04 - P. Harvey Added new codes from libgeotiff-1.2.1
+#               02/01/07 - P. Harvey Added new codes from libgeotiff-1.2.3
+#
+# Reference:    ftp://ftp.remotesensing.org/geotiff/libgeotiff/libgeotiff-1.1.4.tar.gz
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::GeoTiff;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess);
+
+$VERSION = '1.06';
+
+# format codes for geoTiff directory entries
+my %geoTiffFormat = (
+    0      => 'int16u',
+    0x87b0 => 'double',
+    0x87b1 => 'string',
+);
+
+my %epsg_units = (
+    9001 => 'Linear Meter',
+    9002 => 'Linear Foot',
+    9003 => 'Linear Foot US Survey',
+    9004 => 'Linear Foot Modified American',
+    9005 => 'Linear Foot Clarke',
+    9006 => 'Linear Foot Indian',
+    9007 => 'Linear Link',
+    9008 => 'Linear Link Benoit',
+    9009 => 'Linear Link Sears',
+    9010 => 'Linear Chain Benoit',
+    9011 => 'Linear Chain Sears',
+    9012 => 'Linear Yard Sears',
+    9013 => 'Linear Yard Indian',
+    9014 => 'Linear Fathom',
+    9015 => 'Linear Mile International Nautical',
+    9101 => 'Angular Radian',
+    9102 => 'Angular Degree',
+    9103 => 'Angular Arc Minute',
+    9104 => 'Angular Arc Second',
+    9105 => 'Angular Grad',
+    9106 => 'Angular Gon',
+    9107 => 'Angular DMS',
+    9108 => 'Angular DMS Hemisphere',
+    32767 => 'User Defined',
+);
+
+%Image::ExifTool::GeoTiff::Main = (
+    GROUPS => { 2 => 'Location' },
+    1 => {
+        # this isn't a real GeoTiff key, but put it here
+        # so it will appear in tag lists since we generate it below
+        Name => 'GeoTiffVersion',
+    },
+    1024 => {
+        Name => 'GTModelType',
+        PrintConv => {
+            1 => 'Projected',
+            2 => 'Geographic',
+            3 => 'Geocentric',
+            32767 => 'User Defined',
+        },
+    },
+    1025 => {
+        Name => 'GTRasterType',
+        PrintConv => {
+            1 => 'Pixel Is Area',
+            2 => 'Pixel Is Point',
+            32767 => 'User Defined',
+        },
+    },
+    1026 => 'GTCitation',
+    2048 => {
+        Name => 'GeographicType',
+        PrintConv => {
+            # epsg_gcs
+            4001 => 'Airy 1830',
+            4002 => 'Airy Modified 1849',
+            4003 => 'Australian National Spheroid',
+            4004 => 'Bessel 1841',
+            4005 => 'Bessel Modified',
+            4006 => 'Bessel Namibia',
+            4007 => 'Clarke 1858',
+            4008 => 'Clarke 1866',
+            4009 => 'Clarke 1866 Michigan',
+            4010 => 'Clarke 1880 Benoit',
+            4011 => 'Clarke 1880 IGN',
+            4012 => 'Clarke 1880 RGS',
+            4013 => 'Clarke 1880 Arc',
+            4014 => 'Clarke 1880 SGA 1922',
+            4015 => 'Everest 1830 1937 Adjustment',
+            4016 => 'Everest 1830 1967 Definition',
+            4017 => 'Everest 1830 1975 Definition',
+            4018 => 'Everest 1830 Modified',
+            4019 => 'GRS 1980',
+            4020 => 'Helmert 1906',
+            4021 => 'Indonesian National Spheroid',
+            4022 => 'International 1924',
+            4023 => 'International 1967',
+            4024 => 'Krassowsky 1940',
+            4025 => 'NWL9D',
+            4026 => 'NWL10D',
+            4027 => 'Plessis 1817',
+            4028 => 'Struve 1860',
+            4029 => 'War Office',
+            4030 => 'WGS84',
+            4031 => 'GEM10C',
+            4032 => 'OSU86F',
+            4033 => 'OSU91A',
+            4034 => 'Clarke 1880',
+            4035 => 'Sphere',
+            4120 => 'Greek',
+            4121 => 'GGRS87',
+            4123 => 'KKJ',
+            4124 => 'RT90',
+            4133 => 'EST92',
+            4815 => 'Greek Athens',
+            4201 => 'Adindan',
+            4202 => 'AGD66',
+            4203 => 'AGD84',
+            4204 => 'Ain el Abd',
+            4205 => 'Afgooye',
+            4206 => 'Agadez',
+            4207 => 'Lisbon',
+            4208 => 'Aratu',
+            4209 => 'Arc 1950',
+            4210 => 'Arc 1960',
+            4211 => 'Batavia',
+            4212 => 'Barbados',
+            4213 => 'Beduaram',
+            4214 => 'Beijing 1954',
+            4215 => 'Belge 1950',
+            4216 => 'Bermuda 1957',
+            4217 => 'Bern 1898',
+            4218 => 'Bogota',
+            4219 => 'Bukit Rimpah',
+            4220 => 'Camacupa',
+            4221 => 'Campo Inchauspe',
+            4222 => 'Cape',
+            4223 => 'Carthage',
+            4224 => 'Chua',
+            4225 => 'Corrego Alegre',
+            4226 => 'Cote d Ivoire',
+            4227 => 'Deir ez Zor',
+            4228 => 'Douala',
+            4229 => 'Egypt 1907',
+            4230 => 'ED50',
+            4231 => 'ED87',
+            4232 => 'Fahud',
+            4233 => 'Gandajika 1970',
+            4234 => 'Garoua',
+            4235 => 'Guyane Francaise',
+            4236 => 'Hu Tzu Shan',
+            4237 => 'HD72',
+            4238 => 'ID74',
+            4239 => 'Indian 1954',
+            4240 => 'Indian 1975',
+            4241 => 'Jamaica 1875',
+            4242 => 'JAD69',
+            4243 => 'Kalianpur',
+            4244 => 'Kandawala',
+            4245 => 'Kertau',
+            4246 => 'KOC',
+            4247 => 'La Canoa',
+            4248 => 'PSAD56',
+            4249 => 'Lake',
+            4250 => 'Leigon',
+            4251 => 'Liberia 1964',
+            4252 => 'Lome',
+            4253 => 'Luzon 1911',
+            4254 => 'Hito XVIII 1963',
+            4255 => 'Herat North',
+            4256 => 'Mahe 1971',
+            4257 => 'Makassar',
+            4258 => 'EUREF89',
+            4259 => 'Malongo 1987',
+            4260 => 'Manoca',
+            4261 => 'Merchich',
+            4262 => 'Massawa',
+            4263 => 'Minna',
+            4264 => 'Mhast',
+            4265 => 'Monte Mario',
+            4266 => 'M poraloko',
+            4267 => 'NAD27',
+            4268 => 'NAD Michigan',
+            4269 => 'NAD83',
+            4270 => 'Nahrwan 1967',
+            4271 => 'Naparima 1972',
+            4272 => 'GD49',
+            4273 => 'NGO 1948',
+            4274 => '73',
+            4275 => 'NTF',
+            4276 => 'NSWC 9Z 2',
+            4277 => 'OSGB 1936',
+            4278 => 'OSGB70',
+            4279 => 'OS SN80',
+            4280 => 'Padang',
+            4281 => 'Palestine 1923',
+            4282 => 'Pointe Noire',
+            4283 => 'GDA94',
+            4284 => 'Pulkovo 1942',
+            4285 => 'Qatar',
+            4286 => 'Qatar 1948',
+            4287 => 'Qornoq',
+            4288 => 'Loma Quintana',
+            4289 => 'Amersfoort',
+            4290 => 'RT38',
+            4291 => 'SAD69',
+            4292 => 'Sapper Hill 1943',
+            4293 => 'Schwarzeck',
+            4294 => 'Segora',
+            4295 => 'Serindung',
+            4296 => 'Sudan',
+            4297 => 'Tananarive',
+            4298 => 'Timbalai 1948',
+            4299 => 'TM65',
+            4300 => 'TM75',
+            4301 => 'Tokyo',
+            4302 => 'Trinidad 1903',
+            4303 => 'TC 1948',
+            4304 => 'Voirol 1875',
+            4305 => 'Voirol Unifie',
+            4306 => 'Bern 1938',
+            4307 => 'Nord Sahara 1959',
+            4308 => 'Stockholm 1938',
+            4309 => 'Yacare',
+            4310 => 'Yoff',
+            4311 => 'Zanderij',
+            4312 => 'MGI',
+            4313 => 'Belge 1972',
+            4314 => 'DHDN',
+            4315 => 'Conakry 1905',
+            4317 => 'Dealul Piscului 1970',
+            4322 => 'WGS 72',
+            4324 => 'WGS 72BE',
+            4326 => 'WGS 84',
+            4801 => 'Bern 1898 Bern',
+            4802 => 'Bogota Bogota',
+            4803 => 'Lisbon Lisbon',
+            4804 => 'Makassar Jakarta',
+            4805 => 'MGI Ferro',
+            4806 => 'Monte Mario Rome',
+            4807 => 'NTF Paris',
+            4808 => 'Padang Jakarta',
+            4809 => 'Belge 1950 Brussels',
+            4810 => 'Tananarive Paris',
+            4811 => 'Voirol 1875 Paris',
+            4812 => 'Voirol Unifie Paris',
+            4813 => 'Batavia Jakarta',
+            4901 => 'ATF Paris',
+            4902 => 'NDG Paris',
+            32767 => 'User Defined',
+        },
+    },
+    2049 => 'GeogCitation',
+    2050 => {
+        Name => 'GeogGeodeticDatum',
+        PrintConv => {
+            # epsg_datum,
+            6001 => 'Airy 1830',
+            6002 => 'Airy Modified 1849',
+            6003 => 'Australian National Spheroid',
+            6004 => 'Bessel 1841',
+            6005 => 'Bessel Modified',
+            6006 => 'Bessel Namibia',
+            6007 => 'Clarke 1858',
+            6008 => 'Clarke 1866',
+            6009 => 'Clarke 1866 Michigan',
+            6010 => 'Clarke 1880 Benoit',
+            6011 => 'Clarke 1880 IGN',
+            6012 => 'Clarke 1880 RGS',
+            6013 => 'Clarke 1880 Arc',
+            6014 => 'Clarke 1880 SGA 1922',
+            6015 => 'Everest 1830 1937 Adjustment',
+            6016 => 'Everest 1830 1967 Definition',
+            6017 => 'Everest 1830 1975 Definition',
+            6018 => 'Everest 1830 Modified',
+            6019 => 'GRS 1980',
+            6020 => 'Helmert 1906',
+            6021 => 'Indonesian National Spheroid',
+            6022 => 'International 1924',
+            6023 => 'International 1967',
+            6024 => 'Krassowsky 1960',
+            6025 => 'NWL9D',
+            6026 => 'NWL10D',
+            6027 => 'Plessis 1817',
+            6028 => 'Struve 1860',
+            6029 => 'War Office',
+            6030 => 'WGS84',
+            6031 => 'GEM10C',
+            6032 => 'OSU86F',
+            6033 => 'OSU91A',
+            6034 => 'Clarke 1880',
+            6035 => 'Sphere',
+            6201 => 'Adindan',
+            6202 => 'Australian Geodetic Datum 1966',
+            6203 => 'Australian Geodetic Datum 1984',
+            6204 => 'Ain el Abd 1970',
+            6205 => 'Afgooye',
+            6206 => 'Agadez',
+            6207 => 'Lisbon',
+            6208 => 'Aratu',
+            6209 => 'Arc 1950',
+            6210 => 'Arc 1960',
+            6211 => 'Batavia',
+            6212 => 'Barbados',
+            6213 => 'Beduaram',
+            6214 => 'Beijing 1954',
+            6215 => 'Reseau National Belge 1950',
+            6216 => 'Bermuda 1957',
+            6217 => 'Bern 1898',
+            6218 => 'Bogota',
+            6219 => 'Bukit Rimpah',
+            6220 => 'Camacupa',
+            6221 => 'Campo Inchauspe',
+            6222 => 'Cape',
+            6223 => 'Carthage',
+            6224 => 'Chua',
+            6225 => 'Corrego Alegre',
+            6226 => 'Cote d Ivoire',
+            6227 => 'Deir ez Zor',
+            6228 => 'Douala',
+            6229 => 'Egypt 1907',
+            6230 => 'European Datum 1950',
+            6231 => 'European Datum 1987',
+            6232 => 'Fahud',
+            6233 => 'Gandajika 1970',
+            6234 => 'Garoua',
+            6235 => 'Guyane Francaise',
+            6236 => 'Hu Tzu Shan',
+            6237 => 'Hungarian Datum 1972',
+            6238 => 'Indonesian Datum 1974',
+            6239 => 'Indian 1954',
+            6240 => 'Indian 1975',
+            6241 => 'Jamaica 1875',
+            6242 => 'Jamaica 1969',
+            6243 => 'Kalianpur',
+            6244 => 'Kandawala',
+            6245 => 'Kertau',
+            6246 => 'Kuwait Oil Company',
+            6247 => 'La Canoa',
+            6248 => 'Provisional S American Datum 1956',
+            6249 => 'Lake',
+            6250 => 'Leigon',
+            6251 => 'Liberia 1964',
+            6252 => 'Lome',
+            6253 => 'Luzon 1911',
+            6254 => 'Hito XVIII 1963',
+            6255 => 'Herat North',
+            6256 => 'Mahe 1971',
+            6257 => 'Makassar',
+            6258 => 'European Reference System 1989',
+            6259 => 'Malongo 1987',
+            6260 => 'Manoca',
+            6261 => 'Merchich',
+            6262 => 'Massawa',
+            6263 => 'Minna',
+            6264 => 'Mhast',
+            6265 => 'Monte Mario',
+            6266 => 'M poraloko',
+            6267 => 'North American Datum 1927',
+            6268 => 'NAD Michigan',
+            6269 => 'North American Datum 1983',
+            6270 => 'Nahrwan 1967',
+            6271 => 'Naparima 1972',
+            6272 => 'New Zealand Geodetic Datum 1949',
+            6273 => 'NGO 1948',
+            6274 => 'Datum 73',
+            6275 => 'Nouvelle Triangulation Francaise',
+            6276 => 'NSWC 9Z 2',
+            6277 => 'OSGB 1936',
+            6278 => 'OSGB 1970 SN',
+            6279 => 'OS SN 1980',
+            6280 => 'Padang 1884',
+            6281 => 'Palestine 1923',
+            6282 => 'Pointe Noire',
+            6283 => 'Geocentric Datum of Australia 1994',
+            6284 => 'Pulkovo 1942',
+            6285 => 'Qatar',
+            6286 => 'Qatar 1948',
+            6287 => 'Qornoq',
+            6288 => 'Loma Quintana',
+            6289 => 'Amersfoort',
+            6290 => 'RT38',
+            6291 => 'South American Datum 1969',
+            6292 => 'Sapper Hill 1943',
+            6293 => 'Schwarzeck',
+            6294 => 'Segora',
+            6295 => 'Serindung',
+            6296 => 'Sudan',
+            6297 => 'Tananarive 1925',
+            6298 => 'Timbalai 1948',
+            6299 => 'TM65',
+            6300 => 'TM75',
+            6301 => 'Tokyo',
+            6302 => 'Trinidad 1903',
+            6303 => 'Trucial Coast 1948',
+            6304 => 'Voirol 1875',
+            6305 => 'Voirol Unifie 1960',
+            6306 => 'Bern 1938',
+            6307 => 'Nord Sahara 1959',
+            6308 => 'Stockholm 1938',
+            6309 => 'Yacare',
+            6310 => 'Yoff',
+            6311 => 'Zanderij',
+            6312 => 'Militar Geographische Institut',
+            6313 => 'Reseau National Belge 1972',
+            6314 => 'Deutsche Hauptdreiecksnetz',
+            6315 => 'Conakry 1905',
+            6317 => 'Dealul Piscului 1970',
+            6322 => 'WGS72',
+            6324 => 'WGS72 Transit Broadcast Ephemeris',
+            6326 => 'WGS84',
+            6901 => 'Ancienne Triangulation Francaise',
+            6902 => 'Nord de Guerre',
+            32767 => 'User Defined',
+        },
+    },
+    2051 => {
+        Name => 'GeogPrimeMeridian',
+        PrintConv => {
+            # epsg_pm
+            8901 => 'Greenwich',
+            8902 => 'Lisbon',
+            8903 => 'Paris',
+            8904 => 'Bogota',
+            8905 => 'Madrid',
+            8906 => 'Rome',
+            8907 => 'Bern',
+            8908 => 'Jakarta',
+            8909 => 'Ferro',
+            8910 => 'Brussels',
+            8911 => 'Stockholm',
+            32767 => 'User Defined',
+        },
+    },
+    2052 => {
+        Name => 'GeogLinearUnits',
+        SeparateTable => 'Units',
+        PrintConv => \%epsg_units,
+    },
+    2053 => 'GeogLinearUnitSize',
+    2054 => {
+        Name => 'GeogAngularUnits',
+        SeparateTable => 'Units',
+        PrintConv => \%epsg_units,
+    },
+    2055 => 'GeogAngularUnitSize',
+    2056 => {
+        Name => 'GeogEllipsoid',
+        PrintConv => {
+            # epsg_ellipse
+            7001 => 'Airy 1830',
+            7002 => 'Airy Modified 1849',
+            7003 => 'Australian National Spheroid',
+            7004 => 'Bessel 1841',
+            7005 => 'Bessel Modified',
+            7006 => 'Bessel Namibia',
+            7007 => 'Clarke 1858',
+            7008 => 'Clarke 1866',
+            7009 => 'Clarke 1866 Michigan',
+            7010 => 'Clarke 1880 Benoit',
+            7011 => 'Clarke 1880 IGN',
+            7012 => 'Clarke 1880 RGS',
+            7013 => 'Clarke 1880 Arc',
+            7014 => 'Clarke 1880 SGA 1922',
+            7015 => 'Everest 1830 1937 Adjustment',
+            7016 => 'Everest 1830 1967 Definition',
+            7017 => 'Everest 1830 1975 Definition',
+            7018 => 'Everest 1830 Modified',
+            7019 => 'GRS 1980',
+            7020 => 'Helmert 1906',
+            7021 => 'Indonesian National Spheroid',
+            7022 => 'International 1924',
+            7023 => 'International 1967',
+            7024 => 'Krassowsky 1940',
+            7025 => 'NWL 9D',
+            7026 => 'NWL 10D',
+            7027 => 'Plessis 1817',
+            7028 => 'Struve 1860',
+            7029 => 'War Office',
+            7030 => 'WGS 84',
+            7031 => 'GEM 10C',
+            7032 => 'OSU86F',
+            7033 => 'OSU91A',
+            7034 => 'Clarke 1880',
+            7035 => 'Sphere',
+            32767 => 'User Defined',
+        },
+    },
+    2057 => 'GeogSemiMajorAxis',
+    2058 => 'GeogSemiMinorAxis',
+    2059 => 'GeogInvFlattening',
+    2060 => {
+        Name => 'GeogAzimuthUnits',
+        SeparateTable => 'Units',
+        PrintConv => \%epsg_units,
+    },
+    2061 => 'GeogPrimeMeridianLong',
+    3072 => {
+        Name => 'ProjectedCSType',
+        PrintConv => {
+            # epsg_pcs
+            2100 => 'GGRS87 Greek Grid',
+            2176 => 'ETRS89 Poland CS2000 zone 5',
+            2177 => 'ETRS89 Poland CS2000 zone 6',
+            2177 => 'ETRS89 Poland CS2000 zone 7',
+            2178 => 'ETRS89 Poland CS2000 zone 8',
+            2180 => 'ETRS89 Poland CS92',
+            2204 => 'NAD27 Tennessee',
+            2205 => 'NAD83 Kentucky North',
+            2391 => 'KKJ Finland zone 1',
+            2392 => 'KKJ Finland zone 2',
+            2393 => 'KKJ Finland zone 3',
+            2394 => 'KKJ Finland zone 4',
+            2400 => 'RT90 2 5 gon W',
+            2600 => 'Lietuvos Koordinoei Sistema 1994',
+            3053 => 'Hjorsey 1955 Lambert',
+            3057 => 'ISN93 Lambert 1993',
+            3300 => 'Estonian Coordinate System of 1992',
+            20137 => 'Adindan UTM zone 37N',
+            20138 => 'Adindan UTM zone 38N',
+            20248 => 'AGD66 AMG zone 48',
+            20249 => 'AGD66 AMG zone 49',
+            20250 => 'AGD66 AMG zone 50',
+            20251 => 'AGD66 AMG zone 51',
+            20252 => 'AGD66 AMG zone 52',
+            20253 => 'AGD66 AMG zone 53',
+            20254 => 'AGD66 AMG zone 54',
+            20255 => 'AGD66 AMG zone 55',
+            20256 => 'AGD66 AMG zone 56',
+            20257 => 'AGD66 AMG zone 57',
+            20258 => 'AGD66 AMG zone 58',
+            20348 => 'AGD84 AMG zone 48',
+            20349 => 'AGD84 AMG zone 49',
+            20350 => 'AGD84 AMG zone 50',
+            20351 => 'AGD84 AMG zone 51',
+            20352 => 'AGD84 AMG zone 52',
+            20353 => 'AGD84 AMG zone 53',
+            20354 => 'AGD84 AMG zone 54',
+            20355 => 'AGD84 AMG zone 55',
+            20356 => 'AGD84 AMG zone 56',
+            20357 => 'AGD84 AMG zone 57',
+            20358 => 'AGD84 AMG zone 58',
+            20437 => 'Ain el Abd UTM zone 37N',
+            20438 => 'Ain el Abd UTM zone 38N',
+            20439 => 'Ain el Abd UTM zone 39N',
+            20499 => 'Ain el Abd Bahrain Grid',
+            20538 => 'Afgooye UTM zone 38N',
+            20539 => 'Afgooye UTM zone 39N',
+            20700 => 'Lisbon Portugese Grid',
+            20822 => 'Aratu UTM zone 22S',
+            20823 => 'Aratu UTM zone 23S',
+            20824 => 'Aratu UTM zone 24S',
+            20973 => 'Arc 1950 Lo13',
+            20975 => 'Arc 1950 Lo15',
+            20977 => 'Arc 1950 Lo17',
+            20979 => 'Arc 1950 Lo19',
+            20981 => 'Arc 1950 Lo21',
+            20983 => 'Arc 1950 Lo23',
+            20985 => 'Arc 1950 Lo25',
+            20987 => 'Arc 1950 Lo27',
+            20989 => 'Arc 1950 Lo29',
+            20991 => 'Arc 1950 Lo31',
+            20993 => 'Arc 1950 Lo33',
+            20995 => 'Arc 1950 Lo35',
+            21100 => 'Batavia NEIEZ',
+            21148 => 'Batavia UTM zone 48S',
+            21149 => 'Batavia UTM zone 49S',
+            21150 => 'Batavia UTM zone 50S',
+            21413 => 'Beijing Gauss zone 13',
+            21414 => 'Beijing Gauss zone 14',
+            21415 => 'Beijing Gauss zone 15',
+            21416 => 'Beijing Gauss zone 16',
+            21417 => 'Beijing Gauss zone 17',
+            21418 => 'Beijing Gauss zone 18',
+            21419 => 'Beijing Gauss zone 19',
+            21420 => 'Beijing Gauss zone 20',
+            21421 => 'Beijing Gauss zone 21',
+            21422 => 'Beijing Gauss zone 22',
+            21423 => 'Beijing Gauss zone 23',
+            21473 => 'Beijing Gauss 13N',
+            21474 => 'Beijing Gauss 14N',
+            21475 => 'Beijing Gauss 15N',
+            21476 => 'Beijing Gauss 16N',
+            21477 => 'Beijing Gauss 17N',
+            21478 => 'Beijing Gauss 18N',
+            21479 => 'Beijing Gauss 19N',
+            21480 => 'Beijing Gauss 20N',
+            21481 => 'Beijing Gauss 21N',
+            21482 => 'Beijing Gauss 22N',
+            21483 => 'Beijing Gauss 23N',
+            21500 => 'Belge Lambert 50',
+            21790 => 'Bern 1898 Swiss Old',
+            21817 => 'Bogota UTM zone 17N',
+            21818 => 'Bogota UTM zone 18N',
+            21891 => 'Bogota Colombia 3W',
+            21892 => 'Bogota Colombia Bogota',
+            21893 => 'Bogota Colombia 3E',
+            21894 => 'Bogota Colombia 6E',
+            22032 => 'Camacupa UTM 32S',
+            22033 => 'Camacupa UTM 33S',
+            22191 => 'C Inchauspe Argentina 1',
+            22192 => 'C Inchauspe Argentina 2',
+            22193 => 'C Inchauspe Argentina 3',
+            22194 => 'C Inchauspe Argentina 4',
+            22195 => 'C Inchauspe Argentina 5',
+            22196 => 'C Inchauspe Argentina 6',
+            22197 => 'C Inchauspe Argentina 7',
+            22332 => 'Carthage UTM zone 32N',
+            22391 => 'Carthage Nord Tunisie',
+            22392 => 'Carthage Sud Tunisie',
+            22523 => 'Corrego Alegre UTM 23S',
+            22524 => 'Corrego Alegre UTM 24S',
+            22832 => 'Douala UTM zone 32N',
+            22992 => 'Egypt 1907 Red Belt',
+            22993 => 'Egypt 1907 Purple Belt',
+            22994 => 'Egypt 1907 Ext Purple',
+            23028 => 'ED50 UTM zone 28N',
+            23029 => 'ED50 UTM zone 29N',
+            23030 => 'ED50 UTM zone 30N',
+            23031 => 'ED50 UTM zone 31N',
+            23032 => 'ED50 UTM zone 32N',
+            23033 => 'ED50 UTM zone 33N',
+            23034 => 'ED50 UTM zone 34N',
+            23035 => 'ED50 UTM zone 35N',
+            23036 => 'ED50 UTM zone 36N',
+            23037 => 'ED50 UTM zone 37N',
+            23038 => 'ED50 UTM zone 38N',
+            23239 => 'Fahud UTM zone 39N',
+            23240 => 'Fahud UTM zone 40N',
+            23433 => 'Garoua UTM zone 33N',
+            23700 => 'HD72 EOV',
+            23846 => 'ID74 UTM zone 46N',
+            23847 => 'ID74 UTM zone 47N',
+            23848 => 'ID74 UTM zone 48N',
+            23849 => 'ID74 UTM zone 49N',
+            23850 => 'ID74 UTM zone 50N',
+            23851 => 'ID74 UTM zone 51N',
+            23852 => 'ID74 UTM zone 52N',
+            23853 => 'ID74 UTM zone 53N',
+            23886 => 'ID74 UTM zone 46S',
+            23887 => 'ID74 UTM zone 47S',
+            23888 => 'ID74 UTM zone 48S',
+            23889 => 'ID74 UTM zone 49S',
+            23890 => 'ID74 UTM zone 50S',
+            23891 => 'ID74 UTM zone 51S',
+            23892 => 'ID74 UTM zone 52S',
+            23893 => 'ID74 UTM zone 53S',
+            23894 => 'ID74 UTM zone 54S',
+            23947 => 'Indian 1954 UTM 47N',
+            23948 => 'Indian 1954 UTM 48N',
+            24047 => 'Indian 1975 UTM 47N',
+            24048 => 'Indian 1975 UTM 48N',
+            24100 => 'Jamaica 1875 Old Grid',
+            24200 => 'JAD69 Jamaica Grid',
+            24370 => 'Kalianpur India 0',
+            24371 => 'Kalianpur India I',
+            24372 => 'Kalianpur India IIa',
+            24373 => 'Kalianpur India IIIa',
+            24374 => 'Kalianpur India IVa',
+            24382 => 'Kalianpur India IIb',
+            24383 => 'Kalianpur India IIIb',
+            24384 => 'Kalianpur India IVb',
+            24500 => 'Kertau Singapore Grid',
+            24547 => 'Kertau UTM zone 47N',
+            24548 => 'Kertau UTM zone 48N',
+            24720 => 'La Canoa UTM zone 20N',
+            24721 => 'La Canoa UTM zone 21N',
+            24818 => 'PSAD56 UTM zone 18N',
+            24819 => 'PSAD56 UTM zone 19N',
+            24820 => 'PSAD56 UTM zone 20N',
+            24821 => 'PSAD56 UTM zone 21N',
+            24877 => 'PSAD56 UTM zone 17S',
+            24878 => 'PSAD56 UTM zone 18S',
+            24879 => 'PSAD56 UTM zone 19S',
+            24880 => 'PSAD56 UTM zone 20S',
+            24891 => 'PSAD56 Peru west zone',
+            24892 => 'PSAD56 Peru central',
+            24893 => 'PSAD56 Peru east zone',
+            25000 => 'Leigon Ghana Grid',
+            25231 => 'Lome UTM zone 31N',
+            25391 => 'Luzon Philippines I',
+            25392 => 'Luzon Philippines II',
+            25393 => 'Luzon Philippines III',
+            25394 => 'Luzon Philippines IV',
+            25395 => 'Luzon Philippines V',
+            25700 => 'Makassar NEIEZ',
+            25932 => 'Malongo 1987 UTM 32S',
+            26191 => 'Merchich Nord Maroc',
+            26192 => 'Merchich Sud Maroc',
+            26193 => 'Merchich Sahara',
+            26237 => 'Massawa UTM zone 37N',
+            26331 => 'Minna UTM zone 31N',
+            26332 => 'Minna UTM zone 32N',
+            26391 => 'Minna Nigeria West',
+            26392 => 'Minna Nigeria Mid Belt',
+            26393 => 'Minna Nigeria East',
+            26432 => 'Mhast UTM zone 32S',
+            26591 => 'Monte Mario Italy 1',
+            26592 => 'Monte Mario Italy 2',
+            26632 => 'M poraloko UTM 32N',
+            26692 => 'M poraloko UTM 32S',
+            26703 => 'NAD27 UTM zone 3N',
+            26704 => 'NAD27 UTM zone 4N',
+            26705 => 'NAD27 UTM zone 5N',
+            26706 => 'NAD27 UTM zone 6N',
+            26707 => 'NAD27 UTM zone 7N',
+            26708 => 'NAD27 UTM zone 8N',
+            26709 => 'NAD27 UTM zone 9N',
+            26710 => 'NAD27 UTM zone 10N',
+            26711 => 'NAD27 UTM zone 11N',
+            26712 => 'NAD27 UTM zone 12N',
+            26713 => 'NAD27 UTM zone 13N',
+            26714 => 'NAD27 UTM zone 14N',
+            26715 => 'NAD27 UTM zone 15N',
+            26716 => 'NAD27 UTM zone 16N',
+            26717 => 'NAD27 UTM zone 17N',
+            26718 => 'NAD27 UTM zone 18N',
+            26719 => 'NAD27 UTM zone 19N',
+            26720 => 'NAD27 UTM zone 20N',
+            26721 => 'NAD27 UTM zone 21N',
+            26722 => 'NAD27 UTM zone 22N',
+            26729 => 'NAD27 Alabama East',
+            26730 => 'NAD27 Alabama West',
+            26731 => 'NAD27 Alaska zone 1',
+            26732 => 'NAD27 Alaska zone 2',
+            26733 => 'NAD27 Alaska zone 3',
+            26734 => 'NAD27 Alaska zone 4',
+            26735 => 'NAD27 Alaska zone 5',
+            26736 => 'NAD27 Alaska zone 6',
+            26737 => 'NAD27 Alaska zone 7',
+            26738 => 'NAD27 Alaska zone 8',
+            26739 => 'NAD27 Alaska zone 9',
+            26740 => 'NAD27 Alaska zone 10',
+            26741 => 'NAD27 California I',
+            26742 => 'NAD27 California II',
+            26743 => 'NAD27 California III',
+            26744 => 'NAD27 California IV',
+            26745 => 'NAD27 California V',
+            26746 => 'NAD27 California VI',
+            26747 => 'NAD27 California VII',
+            26748 => 'NAD27 Arizona East',
+            26749 => 'NAD27 Arizona Central',
+            26750 => 'NAD27 Arizona West',
+            26751 => 'NAD27 Arkansas North',
+            26752 => 'NAD27 Arkansas South',
+            26753 => 'NAD27 Colorado North',
+            26754 => 'NAD27 Colorado Central',
+            26755 => 'NAD27 Colorado South',
+            26756 => 'NAD27 Connecticut',
+            26757 => 'NAD27 Delaware',
+            26758 => 'NAD27 Florida East',
+            26759 => 'NAD27 Florida West',
+            26760 => 'NAD27 Florida North',
+            26761 => 'NAD27 Hawaii zone 1',
+            26762 => 'NAD27 Hawaii zone 2',
+            26763 => 'NAD27 Hawaii zone 3',
+            26764 => 'NAD27 Hawaii zone 4',
+            26765 => 'NAD27 Hawaii zone 5',
+            26766 => 'NAD27 Georgia East',
+            26767 => 'NAD27 Georgia West',
+            26768 => 'NAD27 Idaho East',
+            26769 => 'NAD27 Idaho Central',
+            26770 => 'NAD27 Idaho West',
+            26771 => 'NAD27 Illinois East',
+            26772 => 'NAD27 Illinois West',
+            26773 => 'NAD27 Indiana East',
+            26774 => 'NAD27 BLM 14N feet',
+            26774 => 'NAD27 Indiana West',
+            26775 => 'NAD27 BLM 15N feet',
+            26775 => 'NAD27 Iowa North',
+            26776 => 'NAD27 BLM 16N feet',
+            26776 => 'NAD27 Iowa South',
+            26777 => 'NAD27 BLM 17N feet',
+            26777 => 'NAD27 Kansas North',
+            26778 => 'NAD27 Kansas South',
+            26779 => 'NAD27 Kentucky North',
+            26780 => 'NAD27 Kentucky South',
+            26781 => 'NAD27 Louisiana North',
+            26782 => 'NAD27 Louisiana South',
+            26783 => 'NAD27 Maine East',
+            26784 => 'NAD27 Maine West',
+            26785 => 'NAD27 Maryland',
+            26786 => 'NAD27 Massachusetts',
+            26787 => 'NAD27 Massachusetts Is',
+            26788 => 'NAD27 Michigan North',
+            26789 => 'NAD27 Michigan Central',
+            26790 => 'NAD27 Michigan South',
+            26791 => 'NAD27 Minnesota North',
+            26792 => 'NAD27 Minnesota Cent',
+            26793 => 'NAD27 Minnesota South',
+            26794 => 'NAD27 Mississippi East',
+            26795 => 'NAD27 Mississippi West',
+            26796 => 'NAD27 Missouri East',
+            26797 => 'NAD27 Missouri Central',
+            26798 => 'NAD27 Missouri West',
+            26801 => 'NAD Michigan Michigan East',
+            26802 => 'NAD Michigan Michigan Old Central',
+            26803 => 'NAD Michigan Michigan West',
+            26903 => 'NAD83 UTM zone 3N',
+            26904 => 'NAD83 UTM zone 4N',
+            26905 => 'NAD83 UTM zone 5N',
+            26906 => 'NAD83 UTM zone 6N',
+            26907 => 'NAD83 UTM zone 7N',
+            26908 => 'NAD83 UTM zone 8N',
+            26909 => 'NAD83 UTM zone 9N',
+            26910 => 'NAD83 UTM zone 10N',
+            26911 => 'NAD83 UTM zone 11N',
+            26912 => 'NAD83 UTM zone 12N',
+            26913 => 'NAD83 UTM zone 13N',
+            26914 => 'NAD83 UTM zone 14N',
+            26915 => 'NAD83 UTM zone 15N',
+            26916 => 'NAD83 UTM zone 16N',
+            26917 => 'NAD83 UTM zone 17N',
+            26918 => 'NAD83 UTM zone 18N',
+            26919 => 'NAD83 UTM zone 19N',
+            26920 => 'NAD83 UTM zone 20N',
+            26921 => 'NAD83 UTM zone 21N',
+            26922 => 'NAD83 UTM zone 22N',
+            26923 => 'NAD83 UTM zone 23N',
+            26929 => 'NAD83 Alabama East',
+            26930 => 'NAD83 Alabama West',
+            26931 => 'NAD83 Alaska zone 1',
+            26932 => 'NAD83 Alaska zone 2',
+            26933 => 'NAD83 Alaska zone 3',
+            26934 => 'NAD83 Alaska zone 4',
+            26935 => 'NAD83 Alaska zone 5',
+            26936 => 'NAD83 Alaska zone 6',
+            26937 => 'NAD83 Alaska zone 7',
+            26938 => 'NAD83 Alaska zone 8',
+            26939 => 'NAD83 Alaska zone 9',
+            26940 => 'NAD83 Alaska zone 10',
+            26941 => 'NAD83 California 1',
+            26942 => 'NAD83 California 2',
+            26943 => 'NAD83 California 3',
+            26944 => 'NAD83 California 4',
+            26945 => 'NAD83 California 5',
+            26946 => 'NAD83 California 6',
+            26948 => 'NAD83 Arizona East',
+            26949 => 'NAD83 Arizona Central',
+            26950 => 'NAD83 Arizona West',
+            26951 => 'NAD83 Arkansas North',
+            26952 => 'NAD83 Arkansas South',
+            26953 => 'NAD83 Colorado North',
+            26954 => 'NAD83 Colorado Central',
+            26955 => 'NAD83 Colorado South',
+            26956 => 'NAD83 Connecticut',
+            26957 => 'NAD83 Delaware',
+            26958 => 'NAD83 Florida East',
+            26959 => 'NAD83 Florida West',
+            26960 => 'NAD83 Florida North',
+            26961 => 'NAD83 Hawaii zone 1',
+            26962 => 'NAD83 Hawaii zone 2',
+            26963 => 'NAD83 Hawaii zone 3',
+            26964 => 'NAD83 Hawaii zone 4',
+            26965 => 'NAD83 Hawaii zone 5',
+            26966 => 'NAD83 Georgia East',
+            26967 => 'NAD83 Georgia West',
+            26968 => 'NAD83 Idaho East',
+            26969 => 'NAD83 Idaho Central',
+            26970 => 'NAD83 Idaho West',
+            26971 => 'NAD83 Illinois East',
+            26972 => 'NAD83 Illinois West',
+            26973 => 'NAD83 Indiana East',
+            26974 => 'NAD83 Indiana West',
+            26975 => 'NAD83 Iowa North',
+            26976 => 'NAD83 Iowa South',
+            26977 => 'NAD83 Kansas North',
+            26978 => 'NAD83 Kansas South',
+            26979 => 'NAD83 Kentucky North',
+            26980 => 'NAD83 Kentucky South',
+            26981 => 'NAD83 Louisiana North',
+            26982 => 'NAD83 Louisiana South',
+            26983 => 'NAD83 Maine East',
+            26984 => 'NAD83 Maine West',
+            26985 => 'NAD83 Maryland',
+            26986 => 'NAD83 Massachusetts',
+            26987 => 'NAD83 Massachusetts Is',
+            26988 => 'NAD83 Michigan North',
+            26989 => 'NAD83 Michigan Central',
+            26990 => 'NAD83 Michigan South',
+            26991 => 'NAD83 Minnesota North',
+            26992 => 'NAD83 Minnesota Cent',
+            26993 => 'NAD83 Minnesota South',
+            26994 => 'NAD83 Mississippi East',
+            26995 => 'NAD83 Mississippi West',
+            26996 => 'NAD83 Missouri East',
+            26997 => 'NAD83 Missouri Central',
+            26998 => 'NAD83 Missouri West',
+            27038 => 'Nahrwan 1967 UTM 38N',
+            27039 => 'Nahrwan 1967 UTM 39N',
+            27040 => 'Nahrwan 1967 UTM 40N',
+            27120 => 'Naparima UTM 20N',
+            27200 => 'GD49 NZ Map Grid',
+            27291 => 'GD49 North Island Grid',
+            27292 => 'GD49 South Island Grid',
+            27429 => 'Datum 73 UTM zone 29N',
+            27500 => 'ATF Nord de Guerre',
+            27581 => 'NTF France I',
+            27582 => 'NTF France II',
+            27583 => 'NTF France III',
+            27591 => 'NTF Nord France',
+            27592 => 'NTF Centre France',
+            27593 => 'NTF Sud France',
+            27700 => 'British National Grid',
+            28232 => 'Point Noire UTM 32S',
+            28348 => 'GDA94 MGA zone 48',
+            28349 => 'GDA94 MGA zone 49',
+            28350 => 'GDA94 MGA zone 50',
+            28351 => 'GDA94 MGA zone 51',
+            28352 => 'GDA94 MGA zone 52',
+            28353 => 'GDA94 MGA zone 53',
+            28354 => 'GDA94 MGA zone 54',
+            28355 => 'GDA94 MGA zone 55',
+            28356 => 'GDA94 MGA zone 56',
+            28357 => 'GDA94 MGA zone 57',
+            28358 => 'GDA94 MGA zone 58',
+            28404 => 'Pulkovo Gauss zone 4',
+            28405 => 'Pulkovo Gauss zone 5',
+            28406 => 'Pulkovo Gauss zone 6',
+            28407 => 'Pulkovo Gauss zone 7',
+            28408 => 'Pulkovo Gauss zone 8',
+            28409 => 'Pulkovo Gauss zone 9',
+            28410 => 'Pulkovo Gauss zone 10',
+            28411 => 'Pulkovo Gauss zone 11',
+            28412 => 'Pulkovo Gauss zone 12',
+            28413 => 'Pulkovo Gauss zone 13',
+            28414 => 'Pulkovo Gauss zone 14',
+            28415 => 'Pulkovo Gauss zone 15',
+            28416 => 'Pulkovo Gauss zone 16',
+            28417 => 'Pulkovo Gauss zone 17',
+            28418 => 'Pulkovo Gauss zone 18',
+            28419 => 'Pulkovo Gauss zone 19',
+            28420 => 'Pulkovo Gauss zone 20',
+            28421 => 'Pulkovo Gauss zone 21',
+            28422 => 'Pulkovo Gauss zone 22',
+            28423 => 'Pulkovo Gauss zone 23',
+            28424 => 'Pulkovo Gauss zone 24',
+            28425 => 'Pulkovo Gauss zone 25',
+            28426 => 'Pulkovo Gauss zone 26',
+            28427 => 'Pulkovo Gauss zone 27',
+            28428 => 'Pulkovo Gauss zone 28',
+            28429 => 'Pulkovo Gauss zone 29',
+            28430 => 'Pulkovo Gauss zone 30',
+            28431 => 'Pulkovo Gauss zone 31',
+            28432 => 'Pulkovo Gauss zone 32',
+            28464 => 'Pulkovo Gauss 4N',
+            28465 => 'Pulkovo Gauss 5N',
+            28466 => 'Pulkovo Gauss 6N',
+            28467 => 'Pulkovo Gauss 7N',
+            28468 => 'Pulkovo Gauss 8N',
+            28469 => 'Pulkovo Gauss 9N',
+            28470 => 'Pulkovo Gauss 10N',
+            28471 => 'Pulkovo Gauss 11N',
+            28472 => 'Pulkovo Gauss 12N',
+            28473 => 'Pulkovo Gauss 13N',
+            28474 => 'Pulkovo Gauss 14N',
+            28475 => 'Pulkovo Gauss 15N',
+            28476 => 'Pulkovo Gauss 16N',
+            28477 => 'Pulkovo Gauss 17N',
+            28478 => 'Pulkovo Gauss 18N',
+            28479 => 'Pulkovo Gauss 19N',
+            28480 => 'Pulkovo Gauss 20N',
+            28481 => 'Pulkovo Gauss 21N',
+            28482 => 'Pulkovo Gauss 22N',
+            28483 => 'Pulkovo Gauss 23N',
+            28484 => 'Pulkovo Gauss 24N',
+            28485 => 'Pulkovo Gauss 25N',
+            28486 => 'Pulkovo Gauss 26N',
+            28487 => 'Pulkovo Gauss 27N',
+            28488 => 'Pulkovo Gauss 28N',
+            28489 => 'Pulkovo Gauss 29N',
+            28490 => 'Pulkovo Gauss 30N',
+            28491 => 'Pulkovo Gauss 31N',
+            28492 => 'Pulkovo Gauss 32N',
+            28600 => 'Qatar National Grid',
+            28991 => 'RD Netherlands Old',
+            28992 => 'RD Netherlands New',
+            29118 => 'SAD69 UTM zone 18N',
+            29119 => 'SAD69 UTM zone 19N',
+            29120 => 'SAD69 UTM zone 20N',
+            29121 => 'SAD69 UTM zone 21N',
+            29122 => 'SAD69 UTM zone 22N',
+            29177 => 'SAD69 UTM zone 17S',
+            29178 => 'SAD69 UTM zone 18S',
+            29179 => 'SAD69 UTM zone 19S',
+            29180 => 'SAD69 UTM zone 20S',
+            29181 => 'SAD69 UTM zone 21S',
+            29182 => 'SAD69 UTM zone 22S',
+            29183 => 'SAD69 UTM zone 23S',
+            29184 => 'SAD69 UTM zone 24S',
+            29185 => 'SAD69 UTM zone 25S',
+            29220 => 'Sapper Hill UTM 20S',
+            29221 => 'Sapper Hill UTM 21S',
+            29333 => 'Schwarzeck UTM 33S',
+            29635 => 'Sudan UTM zone 35N',
+            29636 => 'Sudan UTM zone 36N',
+            29700 => 'Tananarive Laborde',
+            29738 => 'Tananarive UTM 38S',
+            29739 => 'Tananarive UTM 39S',
+            29800 => 'Timbalai 1948 Borneo',
+            29849 => 'Timbalai 1948 UTM 49N',
+            29850 => 'Timbalai 1948 UTM 50N',
+            29900 => 'TM65 Irish Nat Grid',
+            30200 => 'Trinidad 1903 Trinidad',
+            30339 => 'TC 1948 UTM zone 39N',
+            30340 => 'TC 1948 UTM zone 40N',
+            30491 => 'Voirol N Algerie ancien',
+            30492 => 'Voirol S Algerie ancien',
+            30591 => 'Voirol Unifie N Algerie',
+            30592 => 'Voirol Unifie S Algerie',
+            30600 => 'Bern 1938 Swiss New',
+            30729 => 'Nord Sahara UTM 29N',
+            30730 => 'Nord Sahara UTM 30N',
+            30731 => 'Nord Sahara UTM 31N',
+            30732 => 'Nord Sahara UTM 32N',
+            31028 => 'Yoff UTM zone 28N',
+            31121 => 'Zanderij UTM zone 21N',
+            31291 => 'MGI Austria West',
+            31292 => 'MGI Austria Central',
+            31293 => 'MGI Austria East',
+            31300 => 'Belge Lambert 72',
+            31491 => 'DHDN Germany zone 1',
+            31492 => 'DHDN Germany zone 2',
+            31493 => 'DHDN Germany zone 3',
+            31494 => 'DHDN Germany zone 4',
+            31495 => 'DHDN Germany zone 5',
+            31700 => 'Dealul Piscului 1970 Stereo 70',
+            32001 => 'NAD27 Montana North',
+            32002 => 'NAD27 Montana Central',
+            32003 => 'NAD27 Montana South',
+            32005 => 'NAD27 Nebraska North',
+            32006 => 'NAD27 Nebraska South',
+            32007 => 'NAD27 Nevada East',
+            32008 => 'NAD27 Nevada Central',
+            32009 => 'NAD27 Nevada West',
+            32010 => 'NAD27 New Hampshire',
+            32011 => 'NAD27 New Jersey',
+            32012 => 'NAD27 New Mexico East',
+            32013 => 'NAD27 New Mexico Cent',
+            32014 => 'NAD27 New Mexico West',
+            32015 => 'NAD27 New York East',
+            32016 => 'NAD27 New York Central',
+            32017 => 'NAD27 New York West',
+            32018 => 'NAD27 New York Long Is',
+            32019 => 'NAD27 North Carolina',
+            32020 => 'NAD27 North Dakota N',
+            32021 => 'NAD27 North Dakota S',
+            32022 => 'NAD27 Ohio North',
+            32023 => 'NAD27 Ohio South',
+            32024 => 'NAD27 Oklahoma North',
+            32025 => 'NAD27 Oklahoma South',
+            32026 => 'NAD27 Oregon North',
+            32027 => 'NAD27 Oregon South',
+            32028 => 'NAD27 Pennsylvania N',
+            32029 => 'NAD27 Pennsylvania S',
+            32030 => 'NAD27 Rhode Island',
+            32031 => 'NAD27 South Carolina N',
+            32033 => 'NAD27 South Carolina S',
+            32034 => 'NAD27 South Dakota N',
+            32035 => 'NAD27 South Dakota S',
+            32036 => 'NAD27 Tennessee',
+            32037 => 'NAD27 Texas North',
+            32038 => 'NAD27 Texas North Cen',
+            32039 => 'NAD27 Texas Central',
+            32040 => 'NAD27 Texas South Cen',
+            32041 => 'NAD27 Texas South',
+            32042 => 'NAD27 Utah North',
+            32043 => 'NAD27 Utah Central',
+            32044 => 'NAD27 Utah South',
+            32045 => 'NAD27 Vermont',
+            32046 => 'NAD27 Virginia North',
+            32047 => 'NAD27 Virginia South',
+            32048 => 'NAD27 Washington North',
+            32049 => 'NAD27 Washington South',
+            32050 => 'NAD27 West Virginia N',
+            32051 => 'NAD27 West Virginia S',
+            32052 => 'NAD27 Wisconsin North',
+            32053 => 'NAD27 Wisconsin Cen',
+            32054 => 'NAD27 Wisconsin South',
+            32055 => 'NAD27 Wyoming East',
+            32056 => 'NAD27 Wyoming E Cen',
+            32057 => 'NAD27 Wyoming W Cen',
+            32058 => 'NAD27 Wyoming West',
+            32059 => 'NAD27 Puerto Rico',
+            32060 => 'NAD27 St Croix',
+            32100 => 'NAD83 Montana',
+            32104 => 'NAD83 Nebraska',
+            32107 => 'NAD83 Nevada East',
+            32108 => 'NAD83 Nevada Central',
+            32109 => 'NAD83 Nevada West',
+            32110 => 'NAD83 New Hampshire',
+            32111 => 'NAD83 New Jersey',
+            32112 => 'NAD83 New Mexico East',
+            32113 => 'NAD83 New Mexico Cent',
+            32114 => 'NAD83 New Mexico West',
+            32115 => 'NAD83 New York East',
+            32116 => 'NAD83 New York Central',
+            32117 => 'NAD83 New York West',
+            32118 => 'NAD83 New York Long Is',
+            32119 => 'NAD83 North Carolina',
+            32120 => 'NAD83 North Dakota N',
+            32121 => 'NAD83 North Dakota S',
+            32122 => 'NAD83 Ohio North',
+            32123 => 'NAD83 Ohio South',
+            32124 => 'NAD83 Oklahoma North',
+            32125 => 'NAD83 Oklahoma South',
+            32126 => 'NAD83 Oregon North',
+            32127 => 'NAD83 Oregon South',
+            32128 => 'NAD83 Pennsylvania N',
+            32129 => 'NAD83 Pennsylvania S',
+            32130 => 'NAD83 Rhode Island',
+            32133 => 'NAD83 South Carolina',
+            32134 => 'NAD83 South Dakota N',
+            32135 => 'NAD83 South Dakota S',
+            32136 => 'NAD83 Tennessee',
+            32137 => 'NAD83 Texas North',
+            32138 => 'NAD83 Texas North Cen',
+            32139 => 'NAD83 Texas Central',
+            32140 => 'NAD83 Texas South Cen',
+            32141 => 'NAD83 Texas South',
+            32142 => 'NAD83 Utah North',
+            32143 => 'NAD83 Utah Central',
+            32144 => 'NAD83 Utah South',
+            32145 => 'NAD83 Vermont',
+            32146 => 'NAD83 Virginia North',
+            32147 => 'NAD83 Virginia South',
+            32148 => 'NAD83 Washington North',
+            32149 => 'NAD83 Washington South',
+            32150 => 'NAD83 West Virginia N',
+            32151 => 'NAD83 West Virginia S',
+            32152 => 'NAD83 Wisconsin North',
+            32153 => 'NAD83 Wisconsin Cen',
+            32154 => 'NAD83 Wisconsin South',
+            32155 => 'NAD83 Wyoming East',
+            32156 => 'NAD83 Wyoming E Cen',
+            32157 => 'NAD83 Wyoming W Cen',
+            32158 => 'NAD83 Wyoming West',
+            32161 => 'NAD83 Puerto Rico Virgin Is',
+            32201 => 'WGS72 UTM zone 1N',
+            32202 => 'WGS72 UTM zone 2N',
+            32203 => 'WGS72 UTM zone 3N',
+            32204 => 'WGS72 UTM zone 4N',
+            32205 => 'WGS72 UTM zone 5N',
+            32206 => 'WGS72 UTM zone 6N',
+            32207 => 'WGS72 UTM zone 7N',
+            32208 => 'WGS72 UTM zone 8N',
+            32209 => 'WGS72 UTM zone 9N',
+            32210 => 'WGS72 UTM zone 10N',
+            32211 => 'WGS72 UTM zone 11N',
+            32212 => 'WGS72 UTM zone 12N',
+            32213 => 'WGS72 UTM zone 13N',
+            32214 => 'WGS72 UTM zone 14N',
+            32215 => 'WGS72 UTM zone 15N',
+            32216 => 'WGS72 UTM zone 16N',
+            32217 => 'WGS72 UTM zone 17N',
+            32218 => 'WGS72 UTM zone 18N',
+            32219 => 'WGS72 UTM zone 19N',
+            32220 => 'WGS72 UTM zone 20N',
+            32221 => 'WGS72 UTM zone 21N',
+            32222 => 'WGS72 UTM zone 22N',
+            32223 => 'WGS72 UTM zone 23N',
+            32224 => 'WGS72 UTM zone 24N',
+            32225 => 'WGS72 UTM zone 25N',
+            32226 => 'WGS72 UTM zone 26N',
+            32227 => 'WGS72 UTM zone 27N',
+            32228 => 'WGS72 UTM zone 28N',
+            32229 => 'WGS72 UTM zone 29N',
+            32230 => 'WGS72 UTM zone 30N',
+            32231 => 'WGS72 UTM zone 31N',
+            32232 => 'WGS72 UTM zone 32N',
+            32233 => 'WGS72 UTM zone 33N',
+            32234 => 'WGS72 UTM zone 34N',
+            32235 => 'WGS72 UTM zone 35N',
+            32236 => 'WGS72 UTM zone 36N',
+            32237 => 'WGS72 UTM zone 37N',
+            32238 => 'WGS72 UTM zone 38N',
+            32239 => 'WGS72 UTM zone 39N',
+            32240 => 'WGS72 UTM zone 40N',
+            32241 => 'WGS72 UTM zone 41N',
+            32242 => 'WGS72 UTM zone 42N',
+            32243 => 'WGS72 UTM zone 43N',
+            32244 => 'WGS72 UTM zone 44N',
+            32245 => 'WGS72 UTM zone 45N',
+            32246 => 'WGS72 UTM zone 46N',
+            32247 => 'WGS72 UTM zone 47N',
+            32248 => 'WGS72 UTM zone 48N',
+            32249 => 'WGS72 UTM zone 49N',
+            32250 => 'WGS72 UTM zone 50N',
+            32251 => 'WGS72 UTM zone 51N',
+            32252 => 'WGS72 UTM zone 52N',
+            32253 => 'WGS72 UTM zone 53N',
+            32254 => 'WGS72 UTM zone 54N',
+            32255 => 'WGS72 UTM zone 55N',
+            32256 => 'WGS72 UTM zone 56N',
+            32257 => 'WGS72 UTM zone 57N',
+            32258 => 'WGS72 UTM zone 58N',
+            32259 => 'WGS72 UTM zone 59N',
+            32260 => 'WGS72 UTM zone 60N',
+            32301 => 'WGS72 UTM zone 1S',
+            32302 => 'WGS72 UTM zone 2S',
+            32303 => 'WGS72 UTM zone 3S',
+            32304 => 'WGS72 UTM zone 4S',
+            32305 => 'WGS72 UTM zone 5S',
+            32306 => 'WGS72 UTM zone 6S',
+            32307 => 'WGS72 UTM zone 7S',
+            32308 => 'WGS72 UTM zone 8S',
+            32309 => 'WGS72 UTM zone 9S',
+            32310 => 'WGS72 UTM zone 10S',
+            32311 => 'WGS72 UTM zone 11S',
+            32312 => 'WGS72 UTM zone 12S',
+            32313 => 'WGS72 UTM zone 13S',
+            32314 => 'WGS72 UTM zone 14S',
+            32315 => 'WGS72 UTM zone 15S',
+            32316 => 'WGS72 UTM zone 16S',
+            32317 => 'WGS72 UTM zone 17S',
+            32318 => 'WGS72 UTM zone 18S',
+            32319 => 'WGS72 UTM zone 19S',
+            32320 => 'WGS72 UTM zone 20S',
+            32321 => 'WGS72 UTM zone 21S',
+            32322 => 'WGS72 UTM zone 22S',
+            32323 => 'WGS72 UTM zone 23S',
+            32324 => 'WGS72 UTM zone 24S',
+            32325 => 'WGS72 UTM zone 25S',
+            32326 => 'WGS72 UTM zone 26S',
+            32327 => 'WGS72 UTM zone 27S',
+            32328 => 'WGS72 UTM zone 28S',
+            32329 => 'WGS72 UTM zone 29S',
+            32330 => 'WGS72 UTM zone 30S',
+            32331 => 'WGS72 UTM zone 31S',
+            32332 => 'WGS72 UTM zone 32S',
+            32333 => 'WGS72 UTM zone 33S',
+            32334 => 'WGS72 UTM zone 34S',
+            32335 => 'WGS72 UTM zone 35S',
+            32336 => 'WGS72 UTM zone 36S',
+            32337 => 'WGS72 UTM zone 37S',
+            32338 => 'WGS72 UTM zone 38S',
+            32339 => 'WGS72 UTM zone 39S',
+            32340 => 'WGS72 UTM zone 40S',
+            32341 => 'WGS72 UTM zone 41S',
+            32342 => 'WGS72 UTM zone 42S',
+            32343 => 'WGS72 UTM zone 43S',
+            32344 => 'WGS72 UTM zone 44S',
+            32345 => 'WGS72 UTM zone 45S',
+            32346 => 'WGS72 UTM zone 46S',
+            32347 => 'WGS72 UTM zone 47S',
+            32348 => 'WGS72 UTM zone 48S',
+            32349 => 'WGS72 UTM zone 49S',
+            32350 => 'WGS72 UTM zone 50S',
+            32351 => 'WGS72 UTM zone 51S',
+            32352 => 'WGS72 UTM zone 52S',
+            32353 => 'WGS72 UTM zone 53S',
+            32354 => 'WGS72 UTM zone 54S',
+            32355 => 'WGS72 UTM zone 55S',
+            32356 => 'WGS72 UTM zone 56S',
+            32357 => 'WGS72 UTM zone 57S',
+            32358 => 'WGS72 UTM zone 58S',
+            32359 => 'WGS72 UTM zone 59S',
+            32360 => 'WGS72 UTM zone 60S',
+            32401 => 'WGS72BE UTM zone 1N',
+            32402 => 'WGS72BE UTM zone 2N',
+            32403 => 'WGS72BE UTM zone 3N',
+            32404 => 'WGS72BE UTM zone 4N',
+            32405 => 'WGS72BE UTM zone 5N',
+            32406 => 'WGS72BE UTM zone 6N',
+            32407 => 'WGS72BE UTM zone 7N',
+            32408 => 'WGS72BE UTM zone 8N',
+            32409 => 'WGS72BE UTM zone 9N',
+            32410 => 'WGS72BE UTM zone 10N',
+            32411 => 'WGS72BE UTM zone 11N',
+            32412 => 'WGS72BE UTM zone 12N',
+            32413 => 'WGS72BE UTM zone 13N',
+            32414 => 'WGS72BE UTM zone 14N',
+            32415 => 'WGS72BE UTM zone 15N',
+            32416 => 'WGS72BE UTM zone 16N',
+            32417 => 'WGS72BE UTM zone 17N',
+            32418 => 'WGS72BE UTM zone 18N',
+            32419 => 'WGS72BE UTM zone 19N',
+            32420 => 'WGS72BE UTM zone 20N',
+            32421 => 'WGS72BE UTM zone 21N',
+            32422 => 'WGS72BE UTM zone 22N',
+            32423 => 'WGS72BE UTM zone 23N',
+            32424 => 'WGS72BE UTM zone 24N',
+            32425 => 'WGS72BE UTM zone 25N',
+            32426 => 'WGS72BE UTM zone 26N',
+            32427 => 'WGS72BE UTM zone 27N',
+            32428 => 'WGS72BE UTM zone 28N',
+            32429 => 'WGS72BE UTM zone 29N',
+            32430 => 'WGS72BE UTM zone 30N',
+            32431 => 'WGS72BE UTM zone 31N',
+            32432 => 'WGS72BE UTM zone 32N',
+            32433 => 'WGS72BE UTM zone 33N',
+            32434 => 'WGS72BE UTM zone 34N',
+            32435 => 'WGS72BE UTM zone 35N',
+            32436 => 'WGS72BE UTM zone 36N',
+            32437 => 'WGS72BE UTM zone 37N',
+            32438 => 'WGS72BE UTM zone 38N',
+            32439 => 'WGS72BE UTM zone 39N',
+            32440 => 'WGS72BE UTM zone 40N',
+            32441 => 'WGS72BE UTM zone 41N',
+            32442 => 'WGS72BE UTM zone 42N',
+            32443 => 'WGS72BE UTM zone 43N',
+            32444 => 'WGS72BE UTM zone 44N',
+            32445 => 'WGS72BE UTM zone 45N',
+            32446 => 'WGS72BE UTM zone 46N',
+            32447 => 'WGS72BE UTM zone 47N',
+            32448 => 'WGS72BE UTM zone 48N',
+            32449 => 'WGS72BE UTM zone 49N',
+            32450 => 'WGS72BE UTM zone 50N',
+            32451 => 'WGS72BE UTM zone 51N',
+            32452 => 'WGS72BE UTM zone 52N',
+            32453 => 'WGS72BE UTM zone 53N',
+            32454 => 'WGS72BE UTM zone 54N',
+            32455 => 'WGS72BE UTM zone 55N',
+            32456 => 'WGS72BE UTM zone 56N',
+            32457 => 'WGS72BE UTM zone 57N',
+            32458 => 'WGS72BE UTM zone 58N',
+            32459 => 'WGS72BE UTM zone 59N',
+            32460 => 'WGS72BE UTM zone 60N',
+            32501 => 'WGS72BE UTM zone 1S',
+            32502 => 'WGS72BE UTM zone 2S',
+            32503 => 'WGS72BE UTM zone 3S',
+            32504 => 'WGS72BE UTM zone 4S',
+            32505 => 'WGS72BE UTM zone 5S',
+            32506 => 'WGS72BE UTM zone 6S',
+            32507 => 'WGS72BE UTM zone 7S',
+            32508 => 'WGS72BE UTM zone 8S',
+            32509 => 'WGS72BE UTM zone 9S',
+            32510 => 'WGS72BE UTM zone 10S',
+            32511 => 'WGS72BE UTM zone 11S',
+            32512 => 'WGS72BE UTM zone 12S',
+            32513 => 'WGS72BE UTM zone 13S',
+            32514 => 'WGS72BE UTM zone 14S',
+            32515 => 'WGS72BE UTM zone 15S',
+            32516 => 'WGS72BE UTM zone 16S',
+            32517 => 'WGS72BE UTM zone 17S',
+            32518 => 'WGS72BE UTM zone 18S',
+            32519 => 'WGS72BE UTM zone 19S',
+            32520 => 'WGS72BE UTM zone 20S',
+            32521 => 'WGS72BE UTM zone 21S',
+            32522 => 'WGS72BE UTM zone 22S',
+            32523 => 'WGS72BE UTM zone 23S',
+            32524 => 'WGS72BE UTM zone 24S',
+            32525 => 'WGS72BE UTM zone 25S',
+            32526 => 'WGS72BE UTM zone 26S',
+            32527 => 'WGS72BE UTM zone 27S',
+            32528 => 'WGS72BE UTM zone 28S',
+            32529 => 'WGS72BE UTM zone 29S',
+            32530 => 'WGS72BE UTM zone 30S',
+            32531 => 'WGS72BE UTM zone 31S',
+            32532 => 'WGS72BE UTM zone 32S',
+            32533 => 'WGS72BE UTM zone 33S',
+            32534 => 'WGS72BE UTM zone 34S',
+            32535 => 'WGS72BE UTM zone 35S',
+            32536 => 'WGS72BE UTM zone 36S',
+            32537 => 'WGS72BE UTM zone 37S',
+            32538 => 'WGS72BE UTM zone 38S',
+            32539 => 'WGS72BE UTM zone 39S',
+            32540 => 'WGS72BE UTM zone 40S',
+            32541 => 'WGS72BE UTM zone 41S',
+            32542 => 'WGS72BE UTM zone 42S',
+            32543 => 'WGS72BE UTM zone 43S',
+            32544 => 'WGS72BE UTM zone 44S',
+            32545 => 'WGS72BE UTM zone 45S',
+            32546 => 'WGS72BE UTM zone 46S',
+            32547 => 'WGS72BE UTM zone 47S',
+            32548 => 'WGS72BE UTM zone 48S',
+            32549 => 'WGS72BE UTM zone 49S',
+            32550 => 'WGS72BE UTM zone 50S',
+            32551 => 'WGS72BE UTM zone 51S',
+            32552 => 'WGS72BE UTM zone 52S',
+            32553 => 'WGS72BE UTM zone 53S',
+            32554 => 'WGS72BE UTM zone 54S',
+            32555 => 'WGS72BE UTM zone 55S',
+            32556 => 'WGS72BE UTM zone 56S',
+            32557 => 'WGS72BE UTM zone 57S',
+            32558 => 'WGS72BE UTM zone 58S',
+            32559 => 'WGS72BE UTM zone 59S',
+            32560 => 'WGS72BE UTM zone 60S',
+            32601 => 'WGS84 UTM zone 1N',
+            32602 => 'WGS84 UTM zone 2N',
+            32603 => 'WGS84 UTM zone 3N',
+            32604 => 'WGS84 UTM zone 4N',
+            32605 => 'WGS84 UTM zone 5N',
+            32606 => 'WGS84 UTM zone 6N',
+            32607 => 'WGS84 UTM zone 7N',
+            32608 => 'WGS84 UTM zone 8N',
+            32609 => 'WGS84 UTM zone 9N',
+            32610 => 'WGS84 UTM zone 10N',
+            32611 => 'WGS84 UTM zone 11N',
+            32612 => 'WGS84 UTM zone 12N',
+            32613 => 'WGS84 UTM zone 13N',
+            32614 => 'WGS84 UTM zone 14N',
+            32615 => 'WGS84 UTM zone 15N',
+            32616 => 'WGS84 UTM zone 16N',
+            32617 => 'WGS84 UTM zone 17N',
+            32618 => 'WGS84 UTM zone 18N',
+            32619 => 'WGS84 UTM zone 19N',
+            32620 => 'WGS84 UTM zone 20N',
+            32621 => 'WGS84 UTM zone 21N',
+            32622 => 'WGS84 UTM zone 22N',
+            32623 => 'WGS84 UTM zone 23N',
+            32624 => 'WGS84 UTM zone 24N',
+            32625 => 'WGS84 UTM zone 25N',
+            32626 => 'WGS84 UTM zone 26N',
+            32627 => 'WGS84 UTM zone 27N',
+            32628 => 'WGS84 UTM zone 28N',
+            32629 => 'WGS84 UTM zone 29N',
+            32630 => 'WGS84 UTM zone 30N',
+            32631 => 'WGS84 UTM zone 31N',
+            32632 => 'WGS84 UTM zone 32N',
+            32633 => 'WGS84 UTM zone 33N',
+            32634 => 'WGS84 UTM zone 34N',
+            32635 => 'WGS84 UTM zone 35N',
+            32636 => 'WGS84 UTM zone 36N',
+            32637 => 'WGS84 UTM zone 37N',
+            32638 => 'WGS84 UTM zone 38N',
+            32639 => 'WGS84 UTM zone 39N',
+            32640 => 'WGS84 UTM zone 40N',
+            32641 => 'WGS84 UTM zone 41N',
+            32642 => 'WGS84 UTM zone 42N',
+            32643 => 'WGS84 UTM zone 43N',
+            32644 => 'WGS84 UTM zone 44N',
+            32645 => 'WGS84 UTM zone 45N',
+            32646 => 'WGS84 UTM zone 46N',
+            32647 => 'WGS84 UTM zone 47N',
+            32648 => 'WGS84 UTM zone 48N',
+            32649 => 'WGS84 UTM zone 49N',
+            32650 => 'WGS84 UTM zone 50N',
+            32651 => 'WGS84 UTM zone 51N',
+            32652 => 'WGS84 UTM zone 52N',
+            32653 => 'WGS84 UTM zone 53N',
+            32654 => 'WGS84 UTM zone 54N',
+            32655 => 'WGS84 UTM zone 55N',
+            32656 => 'WGS84 UTM zone 56N',
+            32657 => 'WGS84 UTM zone 57N',
+            32658 => 'WGS84 UTM zone 58N',
+            32659 => 'WGS84 UTM zone 59N',
+            32660 => 'WGS84 UTM zone 60N',
+            32701 => 'WGS84 UTM zone 1S',
+            32702 => 'WGS84 UTM zone 2S',
+            32703 => 'WGS84 UTM zone 3S',
+            32704 => 'WGS84 UTM zone 4S',
+            32705 => 'WGS84 UTM zone 5S',
+            32706 => 'WGS84 UTM zone 6S',
+            32707 => 'WGS84 UTM zone 7S',
+            32708 => 'WGS84 UTM zone 8S',
+            32709 => 'WGS84 UTM zone 9S',
+            32710 => 'WGS84 UTM zone 10S',
+            32711 => 'WGS84 UTM zone 11S',
+            32712 => 'WGS84 UTM zone 12S',
+            32713 => 'WGS84 UTM zone 13S',
+            32714 => 'WGS84 UTM zone 14S',
+            32715 => 'WGS84 UTM zone 15S',
+            32716 => 'WGS84 UTM zone 16S',
+            32717 => 'WGS84 UTM zone 17S',
+            32718 => 'WGS84 UTM zone 18S',
+            32719 => 'WGS84 UTM zone 19S',
+            32720 => 'WGS84 UTM zone 20S',
+            32721 => 'WGS84 UTM zone 21S',
+            32722 => 'WGS84 UTM zone 22S',
+            32723 => 'WGS84 UTM zone 23S',
+            32724 => 'WGS84 UTM zone 24S',
+            32725 => 'WGS84 UTM zone 25S',
+            32726 => 'WGS84 UTM zone 26S',
+            32727 => 'WGS84 UTM zone 27S',
+            32728 => 'WGS84 UTM zone 28S',
+            32729 => 'WGS84 UTM zone 29S',
+            32730 => 'WGS84 UTM zone 30S',
+            32731 => 'WGS84 UTM zone 31S',
+            32732 => 'WGS84 UTM zone 32S',
+            32733 => 'WGS84 UTM zone 33S',
+            32734 => 'WGS84 UTM zone 34S',
+            32735 => 'WGS84 UTM zone 35S',
+            32736 => 'WGS84 UTM zone 36S',
+            32737 => 'WGS84 UTM zone 37S',
+            32738 => 'WGS84 UTM zone 38S',
+            32739 => 'WGS84 UTM zone 39S',
+            32740 => 'WGS84 UTM zone 40S',
+            32741 => 'WGS84 UTM zone 41S',
+            32742 => 'WGS84 UTM zone 42S',
+            32743 => 'WGS84 UTM zone 43S',
+            32744 => 'WGS84 UTM zone 44S',
+            32745 => 'WGS84 UTM zone 45S',
+            32746 => 'WGS84 UTM zone 46S',
+            32747 => 'WGS84 UTM zone 47S',
+            32748 => 'WGS84 UTM zone 48S',
+            32749 => 'WGS84 UTM zone 49S',
+            32750 => 'WGS84 UTM zone 50S',
+            32751 => 'WGS84 UTM zone 51S',
+            32752 => 'WGS84 UTM zone 52S',
+            32753 => 'WGS84 UTM zone 53S',
+            32754 => 'WGS84 UTM zone 54S',
+            32755 => 'WGS84 UTM zone 55S',
+            32756 => 'WGS84 UTM zone 56S',
+            32757 => 'WGS84 UTM zone 57S',
+            32758 => 'WGS84 UTM zone 58S',
+            32759 => 'WGS84 UTM zone 59S',
+            32760 => 'WGS84 UTM zone 60S',
+            32767 => 'User Defined',
+        },
+    },
+    3073 => 'PCSCitation',
+    3074 => {
+        Name => 'Projection',
+        PrintConv => {
+            # epsg_proj
+            10101 => 'Alabama CS27 East',
+            10102 => 'Alabama CS27 West',
+            10131 => 'Alabama CS83 East',
+            10132 => 'Alabama CS83 West',
+            10201 => 'Arizona Coordinate System east',
+            10202 => 'Arizona Coordinate System Central',
+            10203 => 'Arizona Coordinate System west',
+            10231 => 'Arizona CS83 east',
+            10232 => 'Arizona CS83 Central',
+            10233 => 'Arizona CS83 west',
+            10301 => 'Arkansas CS27 North',
+            10302 => 'Arkansas CS27 South',
+            10331 => 'Arkansas CS83 North',
+            10332 => 'Arkansas CS83 South',
+            10401 => 'California CS27 I',
+            10402 => 'California CS27 II',
+            10403 => 'California CS27 III',
+            10404 => 'California CS27 IV',
+            10405 => 'California CS27 V',
+            10406 => 'California CS27 VI',
+            10407 => 'California CS27 VII',
+            10431 => 'California CS83 1',
+            10432 => 'California CS83 2',
+            10433 => 'California CS83 3',
+            10434 => 'California CS83 4',
+            10435 => 'California CS83 5',
+            10436 => 'California CS83 6',
+            10501 => 'Colorado CS27 North',
+            10502 => 'Colorado CS27 Central',
+            10503 => 'Colorado CS27 South',
+            10531 => 'Colorado CS83 North',
+            10532 => 'Colorado CS83 Central',
+            10533 => 'Colorado CS83 South',
+            10600 => 'Connecticut CS27',
+            10630 => 'Connecticut CS83',
+            10700 => 'Delaware CS27',
+            10730 => 'Delaware CS83',
+            10901 => 'Florida CS27 East',
+            10902 => 'Florida CS27 West',
+            10903 => 'Florida CS27 North',
+            10931 => 'Florida CS83 East',
+            10932 => 'Florida CS83 West',
+            10933 => 'Florida CS83 North',
+            11001 => 'Georgia CS27 East',
+            11002 => 'Georgia CS27 West',
+            11031 => 'Georgia CS83 East',
+            11032 => 'Georgia CS83 West',
+            11101 => 'Idaho CS27 East',
+            11102 => 'Idaho CS27 Central',
+            11103 => 'Idaho CS27 West',
+            11131 => 'Idaho CS83 East',
+            11132 => 'Idaho CS83 Central',
+            11133 => 'Idaho CS83 West',
+            11201 => 'Illinois CS27 East',
+            11202 => 'Illinois CS27 West',
+            11231 => 'Illinois CS83 East',
+            11232 => 'Illinois CS83 West',
+            11301 => 'Indiana CS27 East',
+            11302 => 'Indiana CS27 West',
+            11331 => 'Indiana CS83 East',
+            11332 => 'Indiana CS83 West',
+            11401 => 'Iowa CS27 North',
+            11402 => 'Iowa CS27 South',
+            11431 => 'Iowa CS83 North',
+            11432 => 'Iowa CS83 South',
+            11501 => 'Kansas CS27 North',
+            11502 => 'Kansas CS27 South',
+            11531 => 'Kansas CS83 North',
+            11532 => 'Kansas CS83 South',
+            11601 => 'Kentucky CS27 North',
+            11602 => 'Kentucky CS27 South',
+            11631 => 'Kentucky CS83 North',
+            11632 => 'Kentucky CS83 South',
+            11701 => 'Louisiana CS27 North',
+            11702 => 'Louisiana CS27 South',
+            11731 => 'Louisiana CS83 North',
+            11732 => 'Louisiana CS83 South',
+            11801 => 'Maine CS27 East',
+            11802 => 'Maine CS27 West',
+            11831 => 'Maine CS83 East',
+            11832 => 'Maine CS83 West',
+            11900 => 'Maryland CS27',
+            11930 => 'Maryland CS83',
+            12001 => 'Massachusetts CS27 Mainland',
+            12002 => 'Massachusetts CS27 Island',
+            12031 => 'Massachusetts CS83 Mainland',
+            12032 => 'Massachusetts CS83 Island',
+            12101 => 'Michigan State Plane East',
+            12102 => 'Michigan State Plane Old Central',
+            12103 => 'Michigan State Plane West',
+            12111 => 'Michigan CS27 North',
+            12112 => 'Michigan CS27 Central',
+            12113 => 'Michigan CS27 South',
+            12141 => 'Michigan CS83 North',
+            12142 => 'Michigan CS83 Central',
+            12143 => 'Michigan CS83 South',
+            12201 => 'Minnesota CS27 North',
+            12202 => 'Minnesota CS27 Central',
+            12203 => 'Minnesota CS27 South',
+            12231 => 'Minnesota CS83 North',
+            12232 => 'Minnesota CS83 Central',
+            12233 => 'Minnesota CS83 South',
+            12301 => 'Mississippi CS27 East',
+            12302 => 'Mississippi CS27 West',
+            12331 => 'Mississippi CS83 East',
+            12332 => 'Mississippi CS83 West',
+            12401 => 'Missouri CS27 East',
+            12402 => 'Missouri CS27 Central',
+            12403 => 'Missouri CS27 West',
+            12431 => 'Missouri CS83 East',
+            12432 => 'Missouri CS83 Central',
+            12433 => 'Missouri CS83 West',
+            12501 => 'Montana CS27 North',
+            12502 => 'Montana CS27 Central',
+            12503 => 'Montana CS27 South',
+            12530 => 'Montana CS83',
+            12601 => 'Nebraska CS27 North',
+            12602 => 'Nebraska CS27 South',
+            12630 => 'Nebraska CS83',
+            12701 => 'Nevada CS27 East',
+            12702 => 'Nevada CS27 Central',
+            12703 => 'Nevada CS27 West',
+            12731 => 'Nevada CS83 East',
+            12732 => 'Nevada CS83 Central',
+            12733 => 'Nevada CS83 West',
+            12800 => 'New Hampshire CS27',
+            12830 => 'New Hampshire CS83',
+            12900 => 'New Jersey CS27',
+            12930 => 'New Jersey CS83',
+            13001 => 'New Mexico CS27 East',
+            13002 => 'New Mexico CS27 Central',
+            13003 => 'New Mexico CS27 West',
+            13031 => 'New Mexico CS83 East',
+            13032 => 'New Mexico CS83 Central',
+            13033 => 'New Mexico CS83 West',
+            13101 => 'New York CS27 East',
+            13102 => 'New York CS27 Central',
+            13103 => 'New York CS27 West',
+            13104 => 'New York CS27 Long Island',
+            13131 => 'New York CS83 East',
+            13132 => 'New York CS83 Central',
+            13133 => 'New York CS83 West',
+            13134 => 'New York CS83 Long Island',
+            13200 => 'North Carolina CS27',
+            13230 => 'North Carolina CS83',
+            13301 => 'North Dakota CS27 North',
+            13302 => 'North Dakota CS27 South',
+            13331 => 'North Dakota CS83 North',
+            13332 => 'North Dakota CS83 South',
+            13401 => 'Ohio CS27 North',
+            13402 => 'Ohio CS27 South',
+            13431 => 'Ohio CS83 North',
+            13432 => 'Ohio CS83 South',
+            13501 => 'Oklahoma CS27 North',
+            13502 => 'Oklahoma CS27 South',
+            13531 => 'Oklahoma CS83 North',
+            13532 => 'Oklahoma CS83 South',
+            13601 => 'Oregon CS27 North',
+            13602 => 'Oregon CS27 South',
+            13631 => 'Oregon CS83 North',
+            13632 => 'Oregon CS83 South',
+            13701 => 'Pennsylvania CS27 North',
+            13702 => 'Pennsylvania CS27 South',
+            13731 => 'Pennsylvania CS83 North',
+            13732 => 'Pennsylvania CS83 South',
+            13800 => 'Rhode Island CS27',
+            13830 => 'Rhode Island CS83',
+            13901 => 'South Carolina CS27 North',
+            13902 => 'South Carolina CS27 South',
+            13930 => 'South Carolina CS83',
+            14001 => 'South Dakota CS27 North',
+            14002 => 'South Dakota CS27 South',
+            14031 => 'South Dakota CS83 North',
+            14032 => 'South Dakota CS83 South',
+            14100 => 'Tennessee CS27',
+            14130 => 'Tennessee CS83',
+            14201 => 'Texas CS27 North',
+            14202 => 'Texas CS27 North Central',
+            14203 => 'Texas CS27 Central',
+            14204 => 'Texas CS27 South Central',
+            14205 => 'Texas CS27 South',
+            14231 => 'Texas CS83 North',
+            14232 => 'Texas CS83 North Central',
+            14233 => 'Texas CS83 Central',
+            14234 => 'Texas CS83 South Central',
+            14235 => 'Texas CS83 South',
+            14301 => 'Utah CS27 North',
+            14302 => 'Utah CS27 Central',
+            14303 => 'Utah CS27 South',
+            14331 => 'Utah CS83 North',
+            14332 => 'Utah CS83 Central',
+            14333 => 'Utah CS83 South',
+            14400 => 'Vermont CS27',
+            14430 => 'Vermont CS83',
+            14501 => 'Virginia CS27 North',
+            14502 => 'Virginia CS27 South',
+            14531 => 'Virginia CS83 North',
+            14532 => 'Virginia CS83 South',
+            14601 => 'Washington CS27 North',
+            14602 => 'Washington CS27 South',
+            14631 => 'Washington CS83 North',
+            14632 => 'Washington CS83 South',
+            14701 => 'West Virginia CS27 North',
+            14702 => 'West Virginia CS27 South',
+            14731 => 'West Virginia CS83 North',
+            14732 => 'West Virginia CS83 South',
+            14801 => 'Wisconsin CS27 North',
+            14802 => 'Wisconsin CS27 Central',
+            14803 => 'Wisconsin CS27 South',
+            14831 => 'Wisconsin CS83 North',
+            14832 => 'Wisconsin CS83 Central',
+            14833 => 'Wisconsin CS83 South',
+            14901 => 'Wyoming CS27 East',
+            14902 => 'Wyoming CS27 East Central',
+            14903 => 'Wyoming CS27 West Central',
+            14904 => 'Wyoming CS27 West',
+            14931 => 'Wyoming CS83 East',
+            14932 => 'Wyoming CS83 East Central',
+            14933 => 'Wyoming CS83 West Central',
+            14934 => 'Wyoming CS83 West',
+            15001 => 'Alaska CS27 1',
+            15002 => 'Alaska CS27 2',
+            15003 => 'Alaska CS27 3',
+            15004 => 'Alaska CS27 4',
+            15005 => 'Alaska CS27 5',
+            15006 => 'Alaska CS27 6',
+            15007 => 'Alaska CS27 7',
+            15008 => 'Alaska CS27 8',
+            15009 => 'Alaska CS27 9',
+            15010 => 'Alaska CS27 10',
+            15031 => 'Alaska CS83 1',
+            15032 => 'Alaska CS83 2',
+            15033 => 'Alaska CS83 3',
+            15034 => 'Alaska CS83 4',
+            15035 => 'Alaska CS83 5',
+            15036 => 'Alaska CS83 6',
+            15037 => 'Alaska CS83 7',
+            15038 => 'Alaska CS83 8',
+            15039 => 'Alaska CS83 9',
+            15040 => 'Alaska CS83 10',
+            15101 => 'Hawaii CS27 1',
+            15102 => 'Hawaii CS27 2',
+            15103 => 'Hawaii CS27 3',
+            15104 => 'Hawaii CS27 4',
+            15105 => 'Hawaii CS27 5',
+            15131 => 'Hawaii CS83 1',
+            15132 => 'Hawaii CS83 2',
+            15133 => 'Hawaii CS83 3',
+            15134 => 'Hawaii CS83 4',
+            15135 => 'Hawaii CS83 5',
+            15201 => 'Puerto Rico CS27',
+            15202 => 'St Croix',
+            15230 => 'Puerto Rico Virgin Is',
+            15302 => 'Kentucky CS27',
+            15303 => 'Kentucky CS83 North',
+            15914 => 'BLM 14N feet',
+            15915 => 'BLM 15N feet',
+            15916 => 'BLM 16N feet',
+            15917 => 'BLM 17N feet',
+            16001 => 'UTM zone 1N',
+            16002 => 'UTM zone 2N',
+            16003 => 'UTM zone 3N',
+            16004 => 'UTM zone 4N',
+            16005 => 'UTM zone 5N',
+            16006 => 'UTM zone 6N',
+            16007 => 'UTM zone 7N',
+            16008 => 'UTM zone 8N',
+            16009 => 'UTM zone 9N',
+            16010 => 'UTM zone 10N',
+            16011 => 'UTM zone 11N',
+            16012 => 'UTM zone 12N',
+            16013 => 'UTM zone 13N',
+            16014 => 'UTM zone 14N',
+            16015 => 'UTM zone 15N',
+            16016 => 'UTM zone 16N',
+            16017 => 'UTM zone 17N',
+            16018 => 'UTM zone 18N',
+            16019 => 'UTM zone 19N',
+            16020 => 'UTM zone 20N',
+            16021 => 'UTM zone 21N',
+            16022 => 'UTM zone 22N',
+            16023 => 'UTM zone 23N',
+            16024 => 'UTM zone 24N',
+            16025 => 'UTM zone 25N',
+            16026 => 'UTM zone 26N',
+            16027 => 'UTM zone 27N',
+            16028 => 'UTM zone 28N',
+            16029 => 'UTM zone 29N',
+            16030 => 'UTM zone 30N',
+            16031 => 'UTM zone 31N',
+            16032 => 'UTM zone 32N',
+            16033 => 'UTM zone 33N',
+            16034 => 'UTM zone 34N',
+            16035 => 'UTM zone 35N',
+            16036 => 'UTM zone 36N',
+            16037 => 'UTM zone 37N',
+            16038 => 'UTM zone 38N',
+            16039 => 'UTM zone 39N',
+            16040 => 'UTM zone 40N',
+            16041 => 'UTM zone 41N',
+            16042 => 'UTM zone 42N',
+            16043 => 'UTM zone 43N',
+            16044 => 'UTM zone 44N',
+            16045 => 'UTM zone 45N',
+            16046 => 'UTM zone 46N',
+            16047 => 'UTM zone 47N',
+            16048 => 'UTM zone 48N',
+            16049 => 'UTM zone 49N',
+            16050 => 'UTM zone 50N',
+            16051 => 'UTM zone 51N',
+            16052 => 'UTM zone 52N',
+            16053 => 'UTM zone 53N',
+            16054 => 'UTM zone 54N',
+            16055 => 'UTM zone 55N',
+            16056 => 'UTM zone 56N',
+            16057 => 'UTM zone 57N',
+            16058 => 'UTM zone 58N',
+            16059 => 'UTM zone 59N',
+            16060 => 'UTM zone 60N',
+            16101 => 'UTM zone 1S',
+            16102 => 'UTM zone 2S',
+            16103 => 'UTM zone 3S',
+            16104 => 'UTM zone 4S',
+            16105 => 'UTM zone 5S',
+            16106 => 'UTM zone 6S',
+            16107 => 'UTM zone 7S',
+            16108 => 'UTM zone 8S',
+            16109 => 'UTM zone 9S',
+            16110 => 'UTM zone 10S',
+            16111 => 'UTM zone 11S',
+            16112 => 'UTM zone 12S',
+            16113 => 'UTM zone 13S',
+            16114 => 'UTM zone 14S',
+            16115 => 'UTM zone 15S',
+            16116 => 'UTM zone 16S',
+            16117 => 'UTM zone 17S',
+            16118 => 'UTM zone 18S',
+            16119 => 'UTM zone 19S',
+            16120 => 'UTM zone 20S',
+            16121 => 'UTM zone 21S',
+            16122 => 'UTM zone 22S',
+            16123 => 'UTM zone 23S',
+            16124 => 'UTM zone 24S',
+            16125 => 'UTM zone 25S',
+            16126 => 'UTM zone 26S',
+            16127 => 'UTM zone 27S',
+            16128 => 'UTM zone 28S',
+            16129 => 'UTM zone 29S',
+            16130 => 'UTM zone 30S',
+            16131 => 'UTM zone 31S',
+            16132 => 'UTM zone 32S',
+            16133 => 'UTM zone 33S',
+            16134 => 'UTM zone 34S',
+            16135 => 'UTM zone 35S',
+            16136 => 'UTM zone 36S',
+            16137 => 'UTM zone 37S',
+            16138 => 'UTM zone 38S',
+            16139 => 'UTM zone 39S',
+            16140 => 'UTM zone 40S',
+            16141 => 'UTM zone 41S',
+            16142 => 'UTM zone 42S',
+            16143 => 'UTM zone 43S',
+            16144 => 'UTM zone 44S',
+            16145 => 'UTM zone 45S',
+            16146 => 'UTM zone 46S',
+            16147 => 'UTM zone 47S',
+            16148 => 'UTM zone 48S',
+            16149 => 'UTM zone 49S',
+            16150 => 'UTM zone 50S',
+            16151 => 'UTM zone 51S',
+            16152 => 'UTM zone 52S',
+            16153 => 'UTM zone 53S',
+            16154 => 'UTM zone 54S',
+            16155 => 'UTM zone 55S',
+            16156 => 'UTM zone 56S',
+            16157 => 'UTM zone 57S',
+            16158 => 'UTM zone 58S',
+            16159 => 'UTM zone 59S',
+            16160 => 'UTM zone 60S',
+            16200 => 'Gauss Kruger zone 0',
+            16201 => 'Gauss Kruger zone 1',
+            16202 => 'Gauss Kruger zone 2',
+            16203 => 'Gauss Kruger zone 3',
+            16204 => 'Gauss Kruger zone 4',
+            16205 => 'Gauss Kruger zone 5',
+            17348 => 'Map Grid of Australia 48',
+            17349 => 'Map Grid of Australia 49',
+            17350 => 'Map Grid of Australia 50',
+            17351 => 'Map Grid of Australia 51',
+            17352 => 'Map Grid of Australia 52',
+            17353 => 'Map Grid of Australia 53',
+            17354 => 'Map Grid of Australia 54',
+            17355 => 'Map Grid of Australia 55',
+            17356 => 'Map Grid of Australia 56',
+            17357 => 'Map Grid of Australia 57',
+            17358 => 'Map Grid of Australia 58',
+            17448 => 'Australian Map Grid 48',
+            17449 => 'Australian Map Grid 49',
+            17450 => 'Australian Map Grid 50',
+            17451 => 'Australian Map Grid 51',
+            17452 => 'Australian Map Grid 52',
+            17453 => 'Australian Map Grid 53',
+            17454 => 'Australian Map Grid 54',
+            17455 => 'Australian Map Grid 55',
+            17456 => 'Australian Map Grid 56',
+            17457 => 'Australian Map Grid 57',
+            17458 => 'Australian Map Grid 58',
+            18031 => 'Argentina 1',
+            18032 => 'Argentina 2',
+            18033 => 'Argentina 3',
+            18034 => 'Argentina 4',
+            18035 => 'Argentina 5',
+            18036 => 'Argentina 6',
+            18037 => 'Argentina 7',
+            18051 => 'Colombia 3W',
+            18052 => 'Colombia Bogota',
+            18053 => 'Colombia 3E',
+            18054 => 'Colombia 6E',
+            18072 => 'Egypt Red Belt',
+            18073 => 'Egypt Purple Belt',
+            18074 => 'Extended Purple Belt',
+            18141 => 'New Zealand North Island Nat Grid',
+            18142 => 'New Zealand South Island Nat Grid',
+            19900 => 'Bahrain Grid',
+            19905 => 'Netherlands E Indies Equatorial',
+            19912 => 'RSO Borneo',
+            19926 => 'Stereo 70',
+            32767 => 'User Defined',
+        },
+    },
+    3075 => {
+        Name => 'ProjCoordTrans',
+        PrintConv => {
+            # geo_ctrans
+            1 => 'Transverse Mercator',
+            2 => 'Transverse Mercator Modified Alaska',
+            3 => 'Oblique Mercator',
+            4 => 'Oblique Mercator Laborde',
+            5 => 'Oblique Mercator Rosenmund',
+            6 => 'Oblique Mercator Spherical',   # not advisable
+            7 => 'Mercator',
+            8 => 'Lambert Conf Conic 2SP',
+            9 => 'Lambert Conf Conic 1SP',
+            10 => 'Lambert Azim Equal Area',
+            11 => 'Albers Equal Area',
+            12 => 'Azimuthal Equidistant',
+            13 => 'Equidistant Conic',
+            14 => 'Stereographic',
+            15 => 'Polar Stereographic',
+            16 => 'Oblique Stereographic',   # not advisable
+            17 => 'Equirectangular',
+            18 => 'Cassini Soldner',
+            19 => 'Gnomonic',
+            20 => 'Miller Cylindrical',
+            21 => 'Orthographic',
+            22 => 'Polyconic',
+            23 => 'Robinson',
+            24 => 'Sinusoidal',
+            25 => 'VanDerGrinten',
+            26 => 'New Zealand Map Grid',
+            27 => 'Transverse Mercator South Orientated',
+            28 => 'Cylindrical Equal Area',
+            32767 => 'User Defined',
+        },
+    },
+    3076 => {
+        Name => 'ProjLinearUnits',
+        SeparateTable => 'Units',
+        PrintConv => \%epsg_units,
+    },
+    3077 => 'ProjLinearUnitSize',
+    3078 => 'ProjStdParallel1',
+    3079 => 'ProjStdParallel2',
+    3080 => 'ProjNatOriginLong',
+    3081 => 'ProjNatOriginLat',
+    3082 => 'ProjFalseEasting',
+    3083 => 'ProjFalseNorthing',
+    3084 => 'ProjFalseOriginLong',
+    3085 => 'ProjFalseOriginLat',
+    3086 => 'ProjFalseOriginEasting',
+    3087 => 'ProjFalseOriginNorthing',
+    3088 => 'ProjCenterLong',
+    3089 => 'ProjCenterLat',
+    3090 => 'ProjCenterEasting',
+    3091 => 'ProjCenterNorthing',
+    3092 => 'ProjScaleAtNatOrigin',
+    3093 => 'ProjScaleAtCenter',
+    3094 => 'ProjAzimuthAngle',
+    3095 => 'ProjStraightVertPoleLong',
+    3096 => 'ProjRectifiedGridAngle',
+    4096 => {
+        Name => 'VerticalCSType',
+        PrintConv => {
+            # epsg_vertcs
+            5001 => 'Airy 1830 ellipsoid',
+            5002 => 'Airy Modified 1849 ellipsoid',
+            5003 => 'ANS ellipsoid',
+            5004 => 'Bessel 1841 ellipsoid',
+            5005 => 'Bessel Modified ellipsoid',
+            5006 => 'Bessel Namibia ellipsoid',
+            5007 => 'Clarke 1858 ellipsoid',
+            5008 => 'Clarke 1866 ellipsoid',
+            5010 => 'Clarke 1880 Benoit ellipsoid',
+            5011 => 'Clarke 1880 IGN ellipsoid',
+            5012 => 'Clarke 1880 RGS ellipsoid',
+            5013 => 'Clarke 1880 Arc ellipsoid',
+            5014 => 'Clarke 1880 SGA 1922 ellipsoid',
+            5015 => 'Everest 1830 1937 Adjustment ellipsoid',
+            5016 => 'Everest 1830 1967 Definition ellipsoid',
+            5017 => 'Everest 1830 1975 Definition ellipsoid',
+            5018 => 'Everest 1830 Modified ellipsoid',
+            5019 => 'GRS 1980 ellipsoid',
+            5020 => 'Helmert 1906 ellipsoid',
+            5021 => 'INS ellipsoid',
+            5022 => 'International 1924 ellipsoid',
+            5023 => 'International 1967 ellipsoid',
+            5024 => 'Krassowsky 1940 ellipsoid',
+            5025 => 'NWL 9D ellipsoid',
+            5026 => 'NWL 10D ellipsoid',
+            5027 => 'Plessis 1817 ellipsoid',
+            5028 => 'Struve 1860 ellipsoid',
+            5029 => 'War Office ellipsoid',
+            5030 => 'WGS 84 ellipsoid',
+            5031 => 'GEM 10C ellipsoid',
+            5032 => 'OSU86F ellipsoid',
+            5033 => 'OSU91A ellipsoid',
+            5101 => 'Newlyn',
+            5102 => 'North American Vertical Datum 1929',
+            5103 => 'North American Vertical Datum 1988',
+            5104 => 'Yellow Sea 1956',
+            5105 => 'Baltic Sea',
+            5106 => 'Caspian Sea',
+            32767 => 'User Defined',
+        },
+    },
+    4097 => 'VerticalCitation',
+    4098 => {
+        Name => 'VerticalDatum',
+        PrintConv => {
+            1 => 'Vertical Datum Base',
+            32767 => 'User Defined',
+        },
+    },
+    4099 => {
+        Name => 'VerticalUnits',
+        SeparateTable => 'Units',
+        PrintConv => \%epsg_units,
+    },
+);
+
+#------------------------------------------------------------------------------
+# Inputs: 0) ExifTool object reference
+#         1) tag table reference
+sub ProcessGeoTiff($)
+{
+    my ($exifTool) = @_;
+    my $dirData = $exifTool->GetValue('GeoTiffDirectory', 'ValueConv') or return;
+    my $doubleData = $exifTool->GetValue('GeoTiffDoubleParams', 'ValueConv');
+    my $asciiData = $exifTool->GetValue('GeoTiffAsciiParams', 'ValueConv');
+    my $verbose = $exifTool->Options('Verbose');
+    my @double;
+
+    # restore or original EXIF byte order setting
+    my $byteOrder = $exifTool->{EXIF_BYTE_ORDER};
+    $byteOrder and SetByteOrder($byteOrder);
+    if (length($$dirData) >= 8 and
+        length($$dirData) >= 8 * (Get16u($dirData,6) + 1))
+    {
+        my $version    = Get16u($dirData,0);
+        my $revision   = Get16u($dirData,2);
+        my $minorRev   = Get16u($dirData,4);
+        my $numEntries = Get16u($dirData,6);
+    
+        if ($verbose) {
+            $exifTool->{INDENT} .= '| ';
+            $exifTool->VerboseDir('GeoTiff',$numEntries);
+        }
+        # generate version number tag (not a real GeoTiff tag)
+        my $tagTable = Image::ExifTool::GetTagTable("Image::ExifTool::GeoTiff::Main");
+        my $tagInfo = $exifTool->GetTagInfo($tagTable, 1);
+        $tagInfo and $exifTool->FoundTag($tagInfo,"$version.$revision.$minorRev");
+    
+        my $i;
+        for ($i=0; $i<$numEntries; ++$i) {
+            my $pt = 8 * ($i + 1);
+            my $tag    = Get16u($dirData, $pt);
+            $tagInfo   = $exifTool->GetTagInfo($tagTable, $tag) or next;
+            my $loc    = Get16u($dirData, $pt+2);
+            my $count  = Get16u($dirData, $pt+4);
+            my $offset = Get16u($dirData, $pt+6);
+            my $format = $geoTiffFormat{$loc};
+            my ($val, $dataPt);
+            if ($format eq 'double') {          # in the double parms
+                $dataPt = $doubleData;
+                $offset *= 8;
+                $val = Image::ExifTool::ReadValue($dataPt, $offset, $format,
+                                                  $count, length($$doubleData)-$offset);
+            } elsif ($format eq 'string') {     # in the ASCII parms
+                $dataPt = $asciiData;
+                $val = substr($$dataPt, $offset, $count);
+                $val =~ s/(\0|\|)$//;   # remove trailing terminator (NULL or '|')
+            } elsif ($format eq 'int16u') {     # use the offset as the value
+                $dataPt = $dirData;
+                $val = $offset;
+                $offset = $pt+6;
+            } else {
+                $exifTool->Warn("Unknown GeoTiff location: $loc");
+                next;
+            }
+            $verbose and $exifTool->VerboseInfo($tag, $tagInfo,
+                'Table'  => $tagTable,
+                'Index'  => $i,
+                'Value'  => $val,
+                'DataPt' => $dataPt,
+                'Start'  => $offset,
+                'Format' => $format,
+                'Count'  => $count,
+                'Size'   => $count * Image::ExifTool::FormatSize($format),
+            );
+            $exifTool->FoundTag($tagInfo, $val);
+        }
+        if ($verbose) {
+            $exifTool->{INDENT} =~ s/..$//;
+        }
+    } else {
+        $exifTool->Warn('Bad GeoTIFF directory');
+    }
+    # must delete these tags once we've processed this information
+    # (to avoid re-processing if another EXIF directory is found)
+    $exifTool->DeleteTag('GeoTiffDirectory');
+    $exifTool->DeleteTag('GeoTiffDoubleParams');
+    $exifTool->DeleteTag('GeoTiffAsciiParams');
+}
+
+
+1;  #end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::GeoTiff - Read GeoTiff meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+GeoTiff meta information.  GeoTiff information is used in images to specify
+exact geometric mappings used to transform the image to real world
+coordinates.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item ftp://ftp.remotesensing.org/geotiff/libgeotiff/libgeotiff-1.1.4.tar.gz
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/GeoTiff Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/HP.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/HP.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/HP.pm	(revision 20131)
@@ -0,0 +1,176 @@
+#------------------------------------------------------------------------------
+# File:         HP.pm
+#
+# Description:  Hewlett-Packard maker notes tags
+#
+# Revisions:    2007-05-03 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::HP;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.01';
+
+sub ProcessHP($$$);
+
+# HP EXIF-format maker notes (or is it Vivitar?)
+%Image::ExifTool::HP::Main = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        These tables list tags found in the maker notes of some Hewlett-Packard
+        camera models.
+        
+        The first table lists tags found in the EXIF-format maker notes of the
+        PhotoSmart 720 (also used by the Vivitar ViviCam 3705, 3705B and 3715).
+    },
+    0x0e00 => {
+        Name => 'PrintIM',
+        Description => 'Print Image Matching',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+);
+
+# other types of HP maker notes
+%Image::ExifTool::HP::Type2 = (
+    PROCESS_PROC => \&ProcessHP,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags are used by the PhotoSmart E427.',
+   'PreviewImage' => {
+        Name => 'PreviewImage',
+        ValueConv => '$self->ValidateImage(\$val,$tag)',
+    },
+   'Serial Number' => 'SerialNumber',
+   'Lens Shading'  => 'LensShading',
+);
+
+%Image::ExifTool::HP::Type4 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags are used by the PhotoSmart M627.',
+    0x0c => {
+        Name => 'MaxAperture',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+    },
+    0x10 => {
+        Name => 'ExposureTime',
+        Format => 'int32u',
+        ValueConv => '$val / 1e6',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    0x14 => {
+        Name => 'CameraDateTime',
+        Groups => { 2 => 'Time' },
+        Format => 'string[20]',
+    },
+    0x34 => {
+        Name => 'ISO',
+        Format => 'int16u',
+    },
+    0x5c => {
+        Name => 'SerialNumber',
+        Format => 'string[26]',
+        RawConv => '$val =~ s/^SERIAL NUMBER:// ? $val : undef',
+    },
+);
+
+%Image::ExifTool::HP::Type6 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags are used by the PhotoSmart M425, M525 and M527.',
+    0x0c => {
+        Name => 'FNumber',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+    },
+    0x10 => {
+        Name => 'ExposureTime',
+        Format => 'int32u',
+        ValueConv => '$val / 1e6',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    0x14 => {
+        Name => 'CameraDateTime',
+        Groups => { 2 => 'Time' },
+        Format => 'string[20]',
+    },
+    0x34 => {
+        Name => 'ISO',
+        Format => 'int16u',
+    },
+    0x58 => {
+        Name => 'SerialNumber',
+        Format => 'string[26]',
+        RawConv => '$val =~ s/^SERIAL NUMBER:// ? $val : undef',
+    },
+);
+
+#------------------------------------------------------------------------------
+# Process HP maker notes
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+sub ProcessHP($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataLen = $$dirInfo{DataLen};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || $dataLen - $dirStart;
+
+    # look for known text-type tags
+    if ($dirStart or $dirLen != length($$dataPt)) {
+        my $buff = substr($$dataPt, $dirStart, $dirLen);
+        $dataPt = \$buff;
+    }
+    my $tagID;
+    # brute-force scan for PreviewImage
+    if ($$tagTablePtr{PreviewImage} and $$dataPt =~ /(\xff\xd8\xff\xdb.*\xff\xd9)/gs) {
+        $exifTool->HandleTag($tagTablePtr, 'PreviewImage', $1);
+        # truncate preview to speed subsequent tag scans
+        my $buff = substr($$dataPt, 0, pos($$dataPt)-length($1));
+        $dataPt = \$buff;
+    }
+    # scan for other tag ID's
+    foreach $tagID (sort(TagTableKeys($tagTablePtr))) {
+        next if $tagID eq 'PreviewImage';
+        next unless $$dataPt =~ /$tagID:\s*([\x20-\x7f]+)/i;
+        $exifTool->HandleTag($tagTablePtr, $tagID, $1);
+    }
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::HP - Hewlett-Packard maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+Hewlett-Packard maker notes.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/HP Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/HTML.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/HTML.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/HTML.pm	(revision 20131)
@@ -0,0 +1,462 @@
+#------------------------------------------------------------------------------
+# File:         HTML.pm
+#
+# Description:  Read HTML meta information
+#
+# Revisions:    01/30/2007 - P. Harvey Created
+#
+# References:   1) http://www.w3.org/TR/html4/
+#               2) http://www.daisy.org/publications/specifications/daisy_202.html
+#               3) http://vancouver-webpages.com/META/metatags.detail.html
+#               4) http://www.html-reference.com/META.htm
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::HTML;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT_OK);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::PostScript;
+use Image::ExifTool::XMP qw(EscapeXML UnescapeXML);
+require Exporter;
+
+$VERSION = '1.03';
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(EscapeHTML UnescapeHTML);
+
+# HTML 4 character entity references
+my %entityNum = (
+    'quot'   => 34,   'eth'    => 240,  'lsquo'  => 8216,
+    'amp'    => 38,   'ntilde' => 241,  'rsquo'  => 8217,
+    'apos'   => 39,   'ograve' => 242,  'sbquo'  => 8218,
+    'lt'     => 60,   'oacute' => 243,  'ldquo'  => 8220,
+    'gt'     => 62,   'ocirc'  => 244,  'rdquo'  => 8221,
+    'nbsp'   => 160,  'otilde' => 245,  'bdquo'  => 8222,
+    'iexcl'  => 161,  'ouml'   => 246,  'dagger' => 8224,
+    'cent'   => 162,  'divide' => 247,  'Dagger' => 8225,
+    'pound'  => 163,  'oslash' => 248,  'bull'   => 8226,
+    'curren' => 164,  'ugrave' => 249,  'hellip' => 8230,
+    'yen'    => 165,  'uacute' => 250,  'permil' => 8240,
+    'brvbar' => 166,  'ucirc'  => 251,  'prime'  => 8242,
+    'sect'   => 167,  'uuml'   => 252,  'Prime'  => 8243,
+    'uml'    => 168,  'yacute' => 253,  'lsaquo' => 8249,
+    'copy'   => 169,  'thorn'  => 254,  'rsaquo' => 8250,
+    'ordf'   => 170,  'yuml'   => 255,  'oline'  => 8254,
+    'laquo'  => 171,  'OElig'  => 338,  'frasl'  => 8260,
+    'not'    => 172,  'oelig'  => 339,  'euro'   => 8364,
+    'shy'    => 173,  'Scaron' => 352,  'image'  => 8465,
+    'reg'    => 174,  'scaron' => 353,  'weierp' => 8472,
+    'macr'   => 175,  'Yuml'   => 376,  'real'   => 8476,
+    'deg'    => 176,  'fnof'   => 402,  'trade'  => 8482,
+    'plusmn' => 177,  'circ'   => 710,  'alefsym'=> 8501,
+    'sup2'   => 178,  'tilde'  => 732,  'larr'   => 8592,
+    'sup3'   => 179,  'Alpha'  => 913,  'uarr'   => 8593,
+    'acute'  => 180,  'Beta'   => 914,  'rarr'   => 8594,
+    'micro'  => 181,  'Gamma'  => 915,  'darr'   => 8595,
+    'para'   => 182,  'Delta'  => 916,  'harr'   => 8596,
+    'middot' => 183,  'Epsilon'=> 917,  'crarr'  => 8629,
+    'cedil'  => 184,  'Zeta'   => 918,  'lArr'   => 8656,
+    'sup1'   => 185,  'Eta'    => 919,  'uArr'   => 8657,
+    'ordm'   => 186,  'Theta'  => 920,  'rArr'   => 8658,
+    'raquo'  => 187,  'Iota'   => 921,  'dArr'   => 8659,
+    'frac14' => 188,  'Kappa'  => 922,  'hArr'   => 8660,
+    'frac12' => 189,  'Lambda' => 923,  'forall' => 8704,
+    'frac34' => 190,  'Mu'     => 924,  'part'   => 8706,
+    'iquest' => 191,  'Nu'     => 925,  'exist'  => 8707,
+    'Agrave' => 192,  'Xi'     => 926,  'empty'  => 8709,
+    'Aacute' => 193,  'Omicron'=> 927,  'nabla'  => 8711,
+    'Acirc'  => 194,  'Pi'     => 928,  'isin'   => 8712,
+    'Atilde' => 195,  'Rho'    => 929,  'notin'  => 8713,
+    'Auml'   => 196,  'Sigma'  => 931,  'ni'     => 8715,
+    'Aring'  => 197,  'Tau'    => 932,  'prod'   => 8719,
+    'AElig'  => 198,  'Upsilon'=> 933,  'sum'    => 8721,
+    'Ccedil' => 199,  'Phi'    => 934,  'minus'  => 8722,
+    'Egrave' => 200,  'Chi'    => 935,  'lowast' => 8727,
+    'Eacute' => 201,  'Psi'    => 936,  'radic'  => 8730,
+    'Ecirc'  => 202,  'Omega'  => 937,  'prop'   => 8733,
+    'Euml'   => 203,  'alpha'  => 945,  'infin'  => 8734,
+    'Igrave' => 204,  'beta'   => 946,  'ang'    => 8736,
+    'Iacute' => 205,  'gamma'  => 947,  'and'    => 8743,
+    'Icirc'  => 206,  'delta'  => 948,  'or'     => 8744,
+    'Iuml'   => 207,  'epsilon'=> 949,  'cap'    => 8745,
+    'ETH'    => 208,  'zeta'   => 950,  'cup'    => 8746,
+    'Ntilde' => 209,  'eta'    => 951,  'int'    => 8747,
+    'Ograve' => 210,  'theta'  => 952,  'there4' => 8756,
+    'Oacute' => 211,  'iota'   => 953,  'sim'    => 8764,
+    'Ocirc'  => 212,  'kappa'  => 954,  'cong'   => 8773,
+    'Otilde' => 213,  'lambda' => 955,  'asymp'  => 8776,
+    'Ouml'   => 214,  'mu'     => 956,  'ne'     => 8800,
+    'times'  => 215,  'nu'     => 957,  'equiv'  => 8801,
+    'Oslash' => 216,  'xi'     => 958,  'le'     => 8804,
+    'Ugrave' => 217,  'omicron'=> 959,  'ge'     => 8805,
+    'Uacute' => 218,  'pi'     => 960,  'sub'    => 8834,
+    'Ucirc'  => 219,  'rho'    => 961,  'sup'    => 8835,
+    'Uuml'   => 220,  'sigmaf' => 962,  'nsub'   => 8836,
+    'Yacute' => 221,  'sigma'  => 963,  'sube'   => 8838,
+    'THORN'  => 222,  'tau'    => 964,  'supe'   => 8839,
+    'szlig'  => 223,  'upsilon'=> 965,  'oplus'  => 8853,
+    'agrave' => 224,  'phi'    => 966,  'otimes' => 8855,
+    'aacute' => 225,  'chi'    => 967,  'perp'   => 8869,
+    'acirc'  => 226,  'psi'    => 968,  'sdot'   => 8901,
+    'atilde' => 227,  'omega'  => 969,  'lceil'  => 8968,
+    'auml'   => 228,  'thetasym'=>977,  'rceil'  => 8969,
+    'aring'  => 229,  'upsih'  => 978,  'lfloor' => 8970,
+    'aelig'  => 230,  'piv'    => 982,  'rfloor' => 8971,
+    'ccedil' => 231,  'ensp'   => 8194, 'lang'   => 9001,
+    'egrave' => 232,  'emsp'   => 8195, 'rang'   => 9002,
+    'eacute' => 233,  'thinsp' => 8201, 'loz'    => 9674,
+    'ecirc'  => 234,  'zwnj'   => 8204, 'spades' => 9824,
+    'euml'   => 235,  'zwj'    => 8205, 'clubs'  => 9827,
+    'igrave' => 236,  'lrm'    => 8206, 'hearts' => 9829,
+    'iacute' => 237,  'rlm'    => 8207, 'diams'  => 9830,
+    'icirc'  => 238,  'ndash'  => 8211,
+    'iuml'   => 239,  'mdash'  => 8212,
+);
+my %entityName; # look up entity names by number (built as necessary)
+
+# HTML info
+# (tag ID's are case insensitive and must be all lower case in tables)
+%Image::ExifTool::HTML::Main = (
+    GROUPS => { 2 => 'Document' },
+    NOTES => q{
+        Meta information extracted from the header of HTML and XHTML files.  This is
+        a mix of information found in the C<META> elements and the C<TITLE> element.
+    },
+    dc => {
+        Name => 'DC',
+        SubDirectory => { TagTable => 'Image::ExifTool::HTML::dc' },
+    },
+    ncc => {
+        Name => 'NCC',
+        SubDirectory => { TagTable => 'Image::ExifTool::HTML::ncc' },
+    },
+    prod => {
+        Name => 'Prod',
+        SubDirectory => { TagTable => 'Image::ExifTool::HTML::prod' },
+    },
+    vw96 => {
+        Name => 'VW96',
+        SubDirectory => { TagTable => 'Image::ExifTool::HTML::vw96' },
+    },
+   'http-equiv' => {
+        Name => 'HTTP-equiv',
+        SubDirectory => { TagTable => 'Image::ExifTool::HTML::equiv' },
+    },
+    abstract        => { },
+    author          => { },
+    classification  => { },
+    copyright       => { },
+    description     => { },
+    distribution    => { },
+   'doc-class'      => { Name => 'DocClass' },
+   'doc-rights'     => { Name => 'DocRights' },
+   'doc-type'       => { Name => 'DocType' },
+    formatter       => { },
+    generator       => { },
+    googlebot       => { Name => 'GoogleBot' },
+    keywords        => { List => 1 },
+    mssmarttagspreventparsing => { Name => 'NoMSSmartTags' },
+    owner           => { },
+    progid          => { Name => 'ProgID' },
+    rating          => { },
+    refresh         => { },
+   'resource-type'  => { Name => 'ResourceType' },
+   'revisit-after'  => { Name => 'RevisitAfter' },
+    robots          => { List => 1 },
+    title           => { Notes => "the only extracted tag which isn't from an HTML META element" },
+);
+
+# ref 2
+%Image::ExifTool::HTML::dc = (
+    GROUPS => { 1 => 'HTML-dc', 2 => 'Document' },
+    NOTES => 'Dublin Core schema tags (also used in XMP).',
+    contributor => { Groups => { 2 => 'Author' }, List => 'Bag' },
+    coverage    => { },
+    creator     => { Groups => { 2 => 'Author' }, List => 'Seq' },
+    date        => {
+        Groups => { 2 => 'Time'   },
+        List => 'Seq',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    description => { },
+   'format'     => { },
+    identifier  => { },
+    language    => { List => 'Bag' },
+    publisher   => { Groups => { 2 => 'Author' }, List => 'Bag' },
+    relation    => { List => 'Bag' },
+    rights      => { Groups => { 2 => 'Author' } },
+    source      => { Groups => { 2 => 'Author' } },
+    subject     => { List => 'Bag' },
+    title       => { },
+    type        => { List => 'Bag' },
+);
+
+# ref 2
+%Image::ExifTool::HTML::ncc = (
+    GROUPS => { 1 => 'HTML-ncc', 2 => 'Document' },
+    charset         => { },
+    depth           => { },
+    files           => { },
+    footnotes       => { },
+    generator       => { },
+    kbytesize       => { Name => 'KByteSize' },
+    maxpagenormal   => { Name => 'MaxPageNormal' },
+    multimediatype  => { Name => 'MultimediaType' },
+    narrator        => { },
+    pagefront       => { Name => 'PageFront' },
+    pagenormal      => { Name => 'PageNormal' },
+    pagespecial     => { Name => 'PageSpecial' },
+    prodnotes       => { Name => 'ProdNotes' },
+    producer        => { },
+    produceddate    => { Name => 'ProducedDate', Groups => { 2 => 'Time' } }, # yyyy-mm-dd
+    revision        => { },
+    revisiondate    => { Name => 'RevisionDate', Groups => { 2 => 'Time' } },
+    setinfo         => { Name => 'SetInfo' },
+    sidebars        => { },
+    sourcedate      => { Name => 'SourceDate', Groups => { 2 => 'Time' } },
+    sourceedition   => { Name => 'SourceEdition' },
+    sourcepublisher => { Name => 'SourcePublisher' },
+    sourcerights    => { Name => 'SourceRights' },
+    sourcetitle     => { Name => 'SourceTitle' },
+    tocitems        => { Name => 'TOCItems' },
+    totaltime       => { Name => 'Duration' }, # hh:mm:ss
+);
+
+# ref 3
+%Image::ExifTool::HTML::vw96 = (
+    GROUPS => { 1 => 'HTML-vw96', 2 => 'Document' },
+    objecttype      => { Name => 'ObjectType' },
+);
+
+# ref 2
+%Image::ExifTool::HTML::prod = (
+    GROUPS => { 1 => 'HTML-prod', 2 => 'Document' },
+    reclocation     => { Name => 'RecLocation' },
+    recengineer     => { Name => 'RecEngineer' },
+);
+
+# ref 3/4
+%Image::ExifTool::HTML::equiv = (
+    GROUPS => { 1 => 'HTTP-equiv', 2 => 'Document' },
+    NOTES => 'These tags have a family 1 group name of "HTTP-equiv".',
+   'cache-control'       => { Name => 'CacheControl' },
+   'content-disposition' => { Name => 'ContentDisposition' },
+   'content-language'    => { Name => 'ContentLanguage' },
+   'content-script-type' => { Name => 'ContentScriptType' },
+   'content-style-type'  => { Name => 'ContentStyleType' },
+   'content-type'        => { Name => 'ContentType' },
+   'default-style'       => { Name => 'DefaultStyle' },
+    expires              => { },
+   'ext-cache'           => { Name => 'ExtCache' },
+    imagetoolbar         => { Name => 'ImageToolbar' },
+    lotus                => { },
+   'page-enter'          => { Name => 'PageEnter' },
+   'page-exit'           => { Name => 'PageExit' },
+   'pics-label'          => { Name => 'PicsLabel' },
+    pragma               => { },
+    refresh              => { },
+   'reply-to'            => { Name => 'ReplyTo' },
+   'set-cookie'          => { Name => 'SetCookie' },
+   'site-enter'          => { Name => 'SiteEnter' },
+   'site-exit'           => { Name => 'SiteExit' },
+    vary                 => { },
+   'window-target'       => { Name => 'WindowTarget' },
+);
+
+#------------------------------------------------------------------------------
+# Convert single UTF-8 character to HTML character reference
+# Inputs: 0) UTF-8 character sequence
+# Returns: HML character reference (ie. "&quot;");
+# Note: Must be called via EscapeHTML to load name lookup
+sub EscapeChar($)
+{
+    my $ch = shift;
+    my ($val) = ($] >= 5.006001) ? unpack('U0U',$ch) : UnpackUTF8($ch);
+    return '?' unless defined $val;
+    return "&$entityName{$val};" if $entityName{$val};
+    return sprintf('&#x%x;',$val);
+}
+
+#------------------------------------------------------------------------------
+# Escape any special characters for HTML
+# Inputs: 0) UTF-8 string to be escaped
+# Returns: escaped string
+sub EscapeHTML($)
+{
+    my $str = shift;
+    # escape XML characters
+    $str = EscapeXML($str);
+    # escape other special characters if they exist
+    if ($str =~ /[\x80-\xff]/) {
+        # generate entity name lookup if necessary
+        unless (%entityName) {
+            local $_;
+            foreach (keys %entityNum) {
+                $entityName{$entityNum{$_}} = $_;
+            }
+            delete $entityName{39};  # 'apos' is not valid HTML
+        }
+        # supress warnings
+        local $SIG{'__WARN__'} = sub { 1 };
+        # escape any non-ascii characters for HTML
+        $str =~ s/([\xc2-\xf7][\x80-\xbf]+)/EscapeChar($1)/sge;
+    }
+    return $str;
+}
+
+#------------------------------------------------------------------------------
+# Unescape all HTML character references
+# Inputs: 0) string to be unescaped
+# Returns: unescaped string
+sub UnescapeHTML($)
+{
+    return UnescapeXML(shift, \%entityNum);
+}
+
+#------------------------------------------------------------------------------
+# Extract information from a HTML file
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid HTML file
+sub ProcessHTML($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->Options('Verbose');
+    my ($buff, $err);
+
+    # validate HTML or XHTML file
+    $raf->Read($buff, 256) or return 0;
+    $buff =~ /^<(!DOCTYPE HTML|HTML|\?xml)/i or return 0;
+    $buff =~ /<(!DOCTYPE )?HTML/i or return 0 if $1 eq '?xml';
+    $exifTool->SetFileType();
+
+    $raf->Seek(0,0) or $exifTool->Warn('Seek error'), return 1;
+
+    my $oldsep = Image::ExifTool::PostScript::SetInputRecordSeparator($raf);
+    $oldsep or $exifTool->Warn('Invalid HTML data'), return 1;
+
+    # extract header information
+    my $doc;
+    while ($raf->ReadLine($buff)) {
+        if (not defined $doc) {
+            # look for 'head' element
+            next unless $buff =~ /<head\b/ig;
+            $doc = substr($buff, pos($buff));
+            next;
+        }
+        $doc .= $buff;
+        last if $buff =~ m{</head>}i;
+    }
+
+    # process all elements in header
+    my $tagTablePtr = GetTagTable('Image::ExifTool::HTML::Main');
+    for (;;) {
+        last unless $doc =~ m{<([\w:.-]+)(.*?)>}sg;
+        my ($tagName, $attrs) = ($1, $2);
+        my $tag = lc($tagName);
+        my ($val, $grp);
+        unless ($attrs =~ m{/$}) {  # self-contained XHTML tags end in '/>'
+            # look for element close
+            my $pos = pos($doc);
+            my $close = "</$tagName>";
+            # the following doesn't work on Solaris Perl 5.6.1 due to Perl bug:
+            # if ($doc =~ m{(.*?)</$tagName>}sg) {
+            #     $val = $1;
+            if ($doc =~ m{$close}sg) {
+                $val = substr($doc, $pos, pos($doc)-$pos-length($close));
+            } else {
+                pos($doc) = $pos;
+                next unless $tag eq 'meta'; # META tags don't need to be closed
+            }
+        }
+        my $table = $tagTablePtr;
+        # parse HTML META element
+        if ($tag eq 'meta') {
+            undef $tag;
+            # tag name is in NAME or HTTP-EQUIV attribute
+            if ($attrs =~ /name=['"]?([\w:.-]+)/si) {
+                $tagName = $1;
+            } elsif ($attrs =~ /http-equiv=['"]?([\w:.-]+)/si) {
+                $tagName = "HTTP-equiv.$1";
+            } else {
+                next;   # no name
+            }
+            $tag = lc($tagName);
+            # tag value is in CONTENT attribute
+            $val = $2 if $attrs =~ /content=(['"])(.*?)\1/si;
+            next unless $tag and defined $val;
+            # isolate group name (separator is '.' in HTML, but ':' in ref 2)
+            if ($tag =~ /^([\w-]+)[:.]([\w-]+)/) {
+                ($grp, $tag) = ($1, $2);
+                my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $grp);
+                if ($tagInfo and $$tagInfo{SubDirectory}) {
+                    $table = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                } else {
+                    $tag = "$grp.$tag";
+                }
+            }
+        } else {
+            # the only non-META element we process is TITLE
+            next unless $tag eq 'title';
+        }
+        unless ($$table{$tag}) {
+            my $name = $tagName;
+            $name =~ s/\W+(\w)/\u$1/sg;
+            my $info = { Name => $name, Groups => { 0 => 'HTML' } };
+            $info->{Groups}->{1} = ($grp eq 'http-equiv' ? 'HTTP-equiv' : "HTML-$grp") if $grp;
+            Image::ExifTool::AddTagToTable($table, $tag, $info);
+            $exifTool->VPrint(0, "  [adding $tag '$tagName']\n");
+        }
+        $val =~ s{\s*$/\s*}{ }sg;   # replace linefeeds and indenting spaces
+        $val = UnescapeHTML($val);  # unescape HTML character references
+        $exifTool->HandleTag($table, $tag, $val);
+    }
+    $/ = $oldsep;   # restore original separator
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::HTML - Read HTML meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to extract
+meta information from HTML documents.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.w3.org/TR/html4/>
+
+=item L<http://www.daisy.org/publications/specifications/daisy_202.html>
+
+=item L<http://vancouver-webpages.com/META/metatags.detail.html>
+
+=item L<http://www.html-reference.com/META.htm>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/HTML Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/HtmlDump.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/HtmlDump.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/HtmlDump.pm	(revision 20131)
@@ -0,0 +1,683 @@
+#------------------------------------------------------------------------------
+# File:         HtmlDump.pm
+#
+# Description:  Dump information in hex to HTML page
+#
+# Revisions:    12/05/2005 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::HtmlDump;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool;    # only for FinishTiffDump()
+
+$VERSION = '1.17';
+
+sub DumpTable($$$;$$$$);
+sub Open($$$;@);
+sub Write($@);
+
+my ($bkgStart, $bkgEnd, $bkgSpan);
+
+my $htmlHeader1 = <<_END_PART_1_;
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
+ "http://www.w3.org/TR/1998/REC-html40-19980424/loose.dtd">
+<html>
+<head>
+<title>
+_END_PART_1_
+
+# Note: Don't change font-weight style because it can affect line height
+my $htmlHeader2 = <<_END_PART_2_;
+</title>
+<style type="text/css">
+<!--
+/* character style ID's */
+.D { color: #000000 } /* default color */
+.V { color: #ff0000 } /* duplicate block 1 */
+.W { color: #004400 } /* normal block 1 */
+.X { color: #ff4488 } /* duplicate block 2 */
+.Y { color: #448844 } /* normal block 2 */
+.U { color: #cc8844 } /* unused data block */
+.H { color: #0000ff } /* highlighted tag name */
+.F { color: #aa00dd } /* actual offset differs */
+.M { text-decoration: underline } /* maker notes data */
+/* table styles */
+table.dump {
+  border-top: 1px solid gray;
+  border-bottom: 1px solid gray;
+}
+table.dump td { padding: .2em .3em }
+td.c2 {
+  border-left: 1px solid gray;
+  border-right: 1px solid gray;
+}
+pre   { margin: 0 }
+table { font-size: .9em }
+body  { color: black; background: white }
+-->
+</style>
+<script language="JavaScript" type="text/JavaScript">
+<!-- Begin
+var t = new Array;
+var mspan = new Array;
+function GetElementsByClass(classname, tagname) {
+  var found = new Array();
+  var list = document.getElementsByTagName(tagname);
+  var len = list.length;
+  for (var i=0, j=0; i<len; ++i) {
+    var classes = list[i].className.split(' ');
+    for (var k=0; k<classes.length; ++k) {
+      if (classes[k] == classname) {
+        found[j++] = list[i];
+        break;
+      }
+    }
+  }
+  delete list;
+  return found;
+}
+function high(e,on) {
+  var targ;
+  if (e.target) targ = e.target;
+  else if (e.srcElement) targ = e.srcElement;
+  if (targ.nodeType == 3) targ = targ.parentNode; // defeat Safari bug
+  if (!targ.name) targ = targ.parentNode; // go up another level if necessary
+  if (targ.name && document.getElementsByName) {
+    var col;
+    var tip;
+    if (on) {
+      col = "#ffcc99";
+      if (targ.name.substring(0,1) == 't') {
+        var index = parseInt(targ.name.substring(1));
+        tip = t[index];
+        if (tip) delete t[index];
+      }
+    } else {
+      col = "transparent";
+    }
+    // highlight anchor elements with the same name and add tool tip
+    var list = document.getElementsByName(targ.name);
+    for (var i=0; i<list.length; ++i) {
+      list[i].style.background = col;
+      if (tip) list[i].title += tip;
+    }
+    // use class name to highlight span elements if necessary
+    for (var i=0; i<mspan.length; ++i) {
+      if (mspan[i] != targ.name) continue;
+      list = GetElementsByClass(targ.name, 'span');
+      for (var j=0; j<list.length; ++j) {
+        list[j].style.background = col;
+      }
+      break;
+    }
+  }
+}
+_END_PART_2_
+
+my $htmlHeader3 = q[
+// End --->
+</script></head>
+<body><noscript><b class=V>--&gt;
+Enable JavaScript for active highlighting and information tool tips!
+</b></noscript><table class=dump cellspacing=0 cellpadding=2>
+<tr><td valign='top'><pre>];
+
+my $preMouse = q(<pre onmouseover="high(event,1)" onmouseout="high(event,0)">);
+
+#------------------------------------------------------------------------------
+# New - create new HtmlDump object
+# Inputs: 0) reference to HtmlDump object or HtmlDump class name
+sub new
+{
+    local $_;
+    my $that = shift;
+    my $class = ref($that) || $that || 'Image::ExifTool::HtmlDump';
+    return bless { Block => {}, TipNum => 0 }, $class;
+}
+
+#------------------------------------------------------------------------------
+# Add information to dump
+# Inputs: 0) HTML dump hash ref, 1) absolute offset in file, 2) data size,
+#         3) comment string, 4) tool tip (or SAME to use previous tip),
+#         5) bit flags (see below), 6) true to use same tooltip as last call
+# Bits: 0x01 - print at start of line
+#       0x02 - print red address
+#       0x04 - maker notes data ('M'-class span)
+#       0x08 - limit block length
+# Notes: Block will be shown in 'unused' color if comment string begins with '['
+sub Add($$$$;$$)
+{
+    my ($self, $start, $size, $msg, $tip, $flag, $sameTip) = @_;
+    my $block = $$self{Block};
+    $$block{$start} or $$block{$start} = [ ];
+    if ($tip and $tip eq 'SAME') {
+        $tip = '';
+    } else {
+        $tip = defined $tip ? '\n' . $tip : '';
+        my $m = $msg;
+        $m =~ s/<.*?>//g;       # remove html format codes
+        $tip = "$m$tip";        # add msg as first line in tooltip
+        # add size if not already done
+        $tip .= "\\n($size bytes)" unless $tip =~ /\\nSize:/;
+        ++$self->{TipNum};
+    }
+    push @{$$block{$start}}, [ $size, $msg, $tip, $flag, $self->{TipNum} ];
+}
+
+#------------------------------------------------------------------------------
+# Print dump information to HTML page
+# Inputs: 0) Dump information hash reference, 1) source file RAF reference,
+#         2) data pointer, 3) data position, 4) output file or scalar reference,
+#         5) limit level (1-3), 6) title
+# Returns: non-zero if useful output was generated
+sub Print($$;$$$$$)
+{
+    local $_;
+    my ($self, $raf, $dataPt, $dataPos, $outfile, $level, $title) = @_;
+    my ($i, $buff, $rtnVal);
+    my $block = $$self{Block};
+    $dataPos = 0 unless $dataPos;
+    $outfile = \*STDOUT unless ref $outfile;
+    $title = 'HtmlDump' unless $title;
+    $level or $level = 0;
+    my $tell = $raf->Tell();
+    my @starts = sort { $a <=> $b } keys %$block;
+    my $pos = 0;
+    my $dataEnd = $dataPos + ($dataPt ? length($$dataPt) : 0);
+    # initialize member variables
+    $$self{Open} = [];
+    $$self{Closed} = [];
+    $$self{TipList} = [];
+    $$self{MSpanList} = [];
+    $$self{Cols} = [ '', '', '', '' ];  # text columns
+    # set dump size limits (limits are 4x smaller if bit 0x08 set in flags)
+    if ($level <= 1) {
+        $$self{Limit} = 1024;
+    } elsif ($level <= 2) {
+        $$self{Limit} = 16384;
+    } else {
+        delete $$self{Limit};   # no limit
+    }
+    # pre-initialize open/closed hashes for all columns
+    for ($i=0; $i<4; ++$i) {
+        $self->{Open}->[$i] = { ID => [ ], Element => { } };
+        $self->{Closed}->[$i] = { ID => [ ], Element => { } };
+    }
+    $bkgStart = $bkgEnd = 0;
+    $bkgSpan = '';
+    my $index = 0;  # initialize tooltip index
+    my @names;
+    for ($i=0; $i<@starts; ++$i) {
+        my $start = $starts[$i];
+        my $bytes = $start - $pos;
+        if ($bytes > 0) {
+            if ($pos >= $dataPos and $pos + $bytes <= $dataEnd) {
+                $buff = substr($$dataPt, $pos-$dataPos, $bytes);
+            } else {
+                $buff = '';
+                $raf->Seek($pos, 0) and $raf->Read($buff, $bytes);
+            }
+            if (length $buff) {
+                my $str = ($bytes > 1) ? "unused $bytes bytes" : 'pad byte';
+                $self->DumpTable($pos-$dataPos, \$buff, "[$str]", "t$index", 0x108);
+                ++$index;
+            }
+            $pos = $start;  # dumped unused data up to the start of this block
+        }
+        my $parms;
+        my $parmList = $$block{$start};
+        foreach $parms (@$parmList) {
+            my ($len, $msg, $tip, $flag, $tipNum) = @$parms;
+            next unless $len > 0;
+            $flag = 0 unless defined $flag;
+            # generate same name for all blocks indexed by this tooltip
+            my $name = $names[$tipNum];
+            my $idx = $index;
+            if ($name) {
+                # get index from existing ID
+                $idx = substr($name, 1);
+            } else {
+                $name = $names[$tipNum] = "t$index";
+                ++$index;
+            }
+            if ($flag == 4) {
+                $bkgStart = $start - $dataPos;
+                $bkgEnd = $bkgStart + $len;
+                $bkgSpan = "<span class='$name M'>";
+                push @{$self->{MSpanList}}, $name;
+                next;
+            }
+            $tip and $self->{TipList}->[$idx] = $tip;
+            my $end = $start + $len;
+            if ($start >= $dataPos and $end <= $dataEnd) {
+                $buff = substr($$dataPt, $start-$dataPos, $len);
+            } else {
+                $buff = '';
+                $raf->Seek($start, 0) and $raf->Read($buff, $len);
+            }
+            next unless length $buff;
+            # set flag to continue this line if next block is contiguous
+            if ($i+1 < @starts and $parms eq $$parmList[-1] and
+                ($end == $starts[$i+1] or ($end < $starts[$i+1] and $end >= $pos)))
+            {
+                my $nextFlag = $block->{$starts[$i+1]}->[0]->[3] || 0;
+                $flag |= 0x100 unless $flag & 0x01 or $nextFlag & 0x01;
+            }
+            $self->DumpTable($start-$dataPos, \$buff, $msg, $name,
+                             $flag, $pos-$dataPos);
+            $pos = $end if $pos < $end;
+        }
+    }
+    $self->Open('','');     # close all open elements
+    $raf->Seek($tell,0);
+
+    # write output HTML file
+    Write($outfile, $htmlHeader1, $title);
+    if ($self->{Cols}->[0]) {
+        Write($outfile, $htmlHeader2);
+        my $mspan = \@{$$self{MSpanList}};
+        for ($i=0; $i<@$mspan; ++$i) {
+            Write($outfile, qq(mspan[$i] = "$$mspan[$i]";\n));
+        }
+        my $tips = \@{$$self{TipList}};
+        for ($i=0; $i<@$tips; ++$i) {
+            Write($outfile, qq(t[$i] = "$$tips[$i]";\n)) if defined $$tips[$i];
+        }
+        delete $$self{TipList};
+        Write($outfile, $htmlHeader3, $self->{Cols}->[0]);
+        Write($outfile, '</pre></td><td valign="top">',
+                        $preMouse, $self->{Cols}->[1]);
+        Write($outfile, '</pre></td><td class=c2 valign="top">',
+                        $preMouse, $self->{Cols}->[2]);
+        Write($outfile, '</pre></td><td valign="top">',
+                        $preMouse, $self->{Cols}->[3]);
+        Write($outfile, "</pre></td></tr></table>\n");
+        $rtnVal = 1;
+    } else {
+        Write($outfile, "$title</title></head><body>\n",
+                        "No EXIF or TIFF information found in image\n");
+    }
+    Write($outfile, "</body></html>\n");
+    for ($i=0; $i<4; ++$i) {
+        $self->{Cols}->[$i] = '';   # free memory
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Open or close a specified html element
+# Inputs: 0) HtmlDump object ref, 1) element id, 2) element string,
+#         3-N) list of column numbers (empty for all columns)
+# - element id may be '' to close all elements
+# - element string may be '' to close element by ID (or 0 to close without reopening)
+# - element id and string may both be 1 to reopen temporarily closed elements
+sub Open($$$;@)
+{
+    my ($self, $id, $element, @colNums) = @_;
+
+    # loop through specified columns
+    @colNums or @colNums = (0 .. $#{$self->{Open}});
+    my $col;
+    foreach $col (@colNums) {
+        # get information about open elements in this column
+        my $opHash = $self->{Open}->[$col];
+        my $opElem = $$opHash{Element};
+        if ($element) {
+            # next if already open
+            next if $$opElem{$id} and $$opElem{$id} eq $element;
+        } elsif ($id and not $$opElem{$id}) {
+            # next if already closed and nothing to reopen
+            next unless $element eq '' and @{$self->{Closed}->[$col]->{ID}};
+        }
+        my $opID = $$opHash{ID};
+        my $clHash = $self->{Closed}->[$col];
+        my $clID = $$clHash{ID};
+        my $clElem = $$clHash{Element};
+        # get reference to output column list (use temp list if available)
+        my $cols = $$self{TmpCols} || $$self{Cols};
+        # close everything down to this element if necessary
+        if ($$opElem{$id} or not $id) {
+            while (@$opID) {
+                my $tid = pop @$opID;
+                my $e = $$opElem{$tid};
+                $e =~ s/^<(\S+).*/<\/$1>/s;
+                $$cols[$col] .= $e;
+                if ($id eq $tid or not $id) {
+                    delete $$opElem{$tid};
+                    last if $id;
+                    next;
+                }
+                # add this to the temporarily closed list
+                # (because we really didn't want to close it)
+                push @$clID, $tid;
+                $$clElem{$tid} = $$opElem{$tid};
+                delete $$opElem{$tid};
+            }
+            unless ($id) {
+                # forget all temporarily closed elements
+                $clID = $$clHash{ID} = [ ];
+                $clElem = $$clHash{Element} = { };
+            }
+        } elsif ($$clElem{$id}) {
+            # delete from the list of temporarily closed elements
+            delete $$clElem{$id};
+            @$clID = grep !/^$id$/, @$clID;
+        }
+        next if $element eq '0'; # 0 = don't reopen temporarily closed elements
+
+        # re-open temporarily closed elements
+        while (@$clID) {
+            my $tid = pop @$clID;
+            $$cols[$col] .= $$clElem{$tid};
+            push @$opID, $tid;
+            $$opElem{$tid} = $$clElem{$tid};
+            delete $$clElem{$tid};
+        }
+        # open specified element
+        if ($element and $element ne '1') {
+            $$cols[$col] .= $element;
+            push @$opID, $id;
+            $$opElem{$id} = $element;
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# Dump a block of data in HTML table form
+# Inputs: 0) HtmlDump object ref, 1) data position, 2) block pointer,
+#         3) message, 4) object name, 5) flag, 6) data end position
+sub DumpTable($$$;$$$$)
+{
+    my ($self, $pos, $blockPt, $msg, $name, $flag, $endPos) = @_;
+    my $len = length $$blockPt;
+    $endPos = 0 unless $endPos;
+    my ($f0, $dblRef, $id);
+    if (($endPos and $pos < $endPos) or $flag & 0x02) {
+        # display double-reference addresses in red
+        $f0 = "<span class=V>";
+        $dblRef = 1 if $endPos and $pos < $endPos;
+    } else {
+        $f0 = '';
+    }
+    my @c = ('','','','');
+    $$self{TmpCols} = \@c;
+    if ($name) {
+        if ($msg and $msg =~ /^\[/) {
+            $id = 'U';
+        } else {
+            if ($$self{A}) {
+                $id = 'X';
+                $$self{A} = 0;
+            } else {
+                $id = 'V';
+                $$self{A} = 1;
+            }
+            ++$id unless $dblRef;
+        }
+        $name = qq{<a name=$name class=$id>};
+        $msg and $msg = "$name$msg</a>";
+    } else {
+        $name = '';
+    }
+    # use base-relative offsets from now on
+    my $cols = 0;
+    my $p = $pos;
+    if ($$self{Cont}) {
+        $cols = $pos & 0x0f;
+        $c[1] .= ($cols == 8) ? '  ' : ' ';
+    } else {
+        my $addr = $pos < 0 ? sprintf("-%.4x",-$pos) : sprintf("%5.4x",$pos);
+        $self->Open('fgd', $f0, 0);
+        $self->Open('fgd', '', 3);
+        $c[0] .= "$addr";
+        $p -= $pos & 0x0f unless $flag & 0x01;
+        if ($p < $pos) {
+            $self->Open('bkg', '', 1, 2); # don't underline white space
+            $cols = $pos - $p;
+            my $n = 3 * $cols;
+            ++$n if $cols > 7;
+            $c[1] .= ' ' x $n;
+            $c[2] .= ' ' x $cols;
+            $p = $pos;
+        }
+    }
+    # loop through each column of hex numbers
+    for (;;) {
+        $self->Open('bkg', ($p>=$bkgStart and $p<$bkgEnd) ? $bkgSpan : '', 1, 2);
+        $self->Open('a', $name, 1, 2);
+        my $ch = substr($$blockPt,$p-$pos,1);
+        $c[1] .= sprintf("%.2x", ord($ch));
+        # make the character HTML-friendly
+        $ch =~ tr/\x00-\x1f\x7f-\xff/./;
+        $ch =~ s/&/&amp;/g;
+        $ch =~ s/>/&gt;/g;
+        $ch =~ s/</&lt;/g;
+        $c[2] .= $ch;
+        ++$p;
+        ++$cols;
+        # close necessary elements
+        if ($p >= $bkgEnd) {
+            # close without reopening if closing anchor later
+            my $arg = ($p - $pos >= $len) ? 0 : '';
+            $self->Open('bkg', $arg, 1, 2);
+        }
+        if ($dblRef and $p >= $endPos) {
+            $dblRef = 0;
+            ++$id;
+            $name =~ s/class=\w\b/class=$id/;
+            $f0 = '';
+            $self->Open('fgd', $f0, 0);
+        }
+        if ($p - $pos >= $len) {
+            $self->Open('a', '', 1, 2);     # close our anchor
+            last;
+        }
+        if ($cols < 16) {
+            $c[1] .= ($cols == 8 ? '  ' : ' ');
+            next;
+        } elsif ($flag & 0x01 and $cols < $len) {
+            $c[1] .= ' ';
+            next;   # put it all on one line
+        }
+        unless ($$self{Msg}) {
+            $c[3] .= $msg;
+            $msg = '';
+        }
+        $_ .= "\n" foreach @c;  # add CR to all lines
+        $$self{Msg} = 0;
+        # limit data length if specified
+        if ($$self{Limit}) {
+            my $div = ($flag & 0x08) ? 4 : 1;
+            my $lim = $$self{Limit} / (2 * $div) - 16;
+            if ($p - $pos > $lim and $len - $p + $pos > $lim) {
+                my $n = ($len - $p + $pos - $lim) & ~0x0f;
+                if ($n > 16) { # (no use just cutting out one line)
+                    $self->Open('bkg', '', 1, 2); # no underline
+                    my $note = "[snip $n bytes]";
+                    $note = (' ' x (24-length($note)/2)) . $note;
+                    $c[0] .= "  ...\n";
+                    $c[1] .= $note . (' ' x (48-length($note))) . "\n";
+                    $c[2] .= "     [snip]     \n";
+                    $c[3] .= "\n";
+                    $p += $n;
+                }
+            }
+        }
+        $c[0] .= ($p < 0 ? sprintf("-%.4x",-$p) : sprintf("%5.4x",$p));
+        $cols = 0;
+    }
+    if ($msg) {
+        $msg = " $msg" if $$self{Msg};
+        $c[3] .= $msg;
+    }
+    if ($flag & 0x100 and $cols < 16) {    # continue on same line?
+        $$self{Cont} = 1;
+        $$self{Msg} = 1 if $msg;
+    } else {
+        $_ .= "\n" foreach @c;
+        $$self{Msg} = 0;
+        $$self{Cont} = 0;
+    }
+    # add temporary column data to our real columns
+    my $i;
+    for ($i=0; $i<4; ++$i) {
+        $self->{Cols}->[$i] .= $c[$i];
+    }
+    delete $$self{TmpCols};
+}
+
+#------------------------------------------------------------------------------
+# Finish dumping of TIFF image data
+# Inputs: 0) HtmlDump object ref, 1) ExifTool object ref, 2) length of file
+# (this really belongs in Image::ExifTool::Exif, but is placed here so it
+#  is only compiled when needed)
+sub FinishTiffDump($$$)
+{
+    my ($self, $exifTool, $size) = @_;
+    my ($tag, $key, $start, $blockInfo, $i);
+
+    # list of all indirectly referenced TIFF data tags
+    my %offsetPair = (
+        StripOffsets      => 'StripByteCounts',
+        TileOffsets       => 'TileByteCounts',
+        FreeOffsets       => 'FreeByteCounts',
+        ThumbnailOffset   => 'ThumbnailLength',
+        PreviewImageStart => 'PreviewImageLength',
+        JpgFromRawStart   => 'JpgFromRawLength',
+        OtherImageStart   => 'OtherImageLength',
+        ImageOffset       => 'ImageByteCount',
+        AlphaOffset       => 'AlphaByteCount',
+    );
+
+    # add TIFF data to html dump
+    foreach $tag (keys %offsetPair) {
+        my $info = $exifTool->GetInfo($tag);
+        next unless %$info;
+        foreach $key (%$info) {
+            my $name = Image::ExifTool::GetTagName($key);
+            my $grp1 = $exifTool->GetGroup($key, 1);
+            my $info2 = $exifTool->GetInfo($offsetPair{$tag}, { Group1 => $grp1 });
+            next unless %$info2;
+            my ($key2) = keys %$info2;
+            my $offsets = $$info{$key};
+            my $byteCounts = $$info2{$key2};
+            # (long lists may be SCALAR references)
+            my @offsets = split ' ', (ref $offsets ? $$offsets : $offsets);
+            my @byteCounts = split ' ', (ref $byteCounts ? $$byteCounts : $byteCounts);
+            my $num = scalar @offsets;
+            my $li = 0;
+            my $padBytes = 0;
+            for ($i=0; @offsets and @byteCounts; ++$i) {
+                my $offset = shift @offsets;
+                my $byteCount = shift @byteCounts;
+                my $end = $offset + $byteCount;
+                if (@offsets and @byteCounts) {
+                    # show data as contiguous if only normal pad bytes between blocks
+                    if ($end & 0x01 and $end + 1 == $offsets[0]) {
+                        $end += 1;
+                        ++$padBytes;    # count them
+                    }
+                    if ($end == $offsets[0]) {
+                        # combine these two blocks
+                        $byteCounts[0] += $offsets[0] - $offset;
+                        $offsets[0] = $offset;
+                        next;
+                    }
+                }
+                my $msg = $exifTool->GetGroup($key, 1) . ':' . $tag;
+                $msg =~ s/(Offsets?|Start)$/ /;
+                if ($num > 1) {
+                    $msg .= "$li-" if $li != $i;
+                    $msg .= "$i ";
+                    $li = $i + 1;
+                }
+                $msg .= "data";
+                my $tip = "Size: $byteCount bytes";
+                $tip .= ", incl. $padBytes pad bytes" if $padBytes;
+                $self->Add($offset, $byteCount, "($msg)", $tip, 0x08);
+            }
+        }
+    }
+    # find offset of last dumped information, and dump any unknown trailer
+    my $last = 0;
+    my $block = $$self{Block};
+    foreach $start (keys %$block) {
+        foreach $blockInfo (@{$$block{$start}}) {
+            my $end = $start + $$blockInfo[0];
+            $last = $end if $last < $end;
+        }
+    }
+    my $diff = $size - $last;
+    if ($diff > 0 and ($last or $exifTool->Options('Unknown'))) {
+        if ($diff > 1 or $size & 0x01) {
+            $self->Add($last, $diff, "[unknown data]", "Size: $diff bytes", 0x08);
+        } else {
+            $self->Add($last, $diff, "[trailing pad byte]", undef, 0x08);
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# utility routine to write to file or memory
+# Inputs: 0) file or scalar reference, 1-N) list of stuff to write
+# Returns: true on success
+sub Write($@)
+{
+    my $outfile = shift;
+    if (UNIVERSAL::isa($outfile,'GLOB')) {
+        return print $outfile @_;
+    } elsif (ref $outfile eq 'SCALAR') {
+        $$outfile .= join('', @_);
+        return 1;
+    }
+    return 0;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::HtmlDump - Dump information in hex to HTML page
+
+=head1 SYNOPSIS
+
+    use Image::ExifTool::HtmlDump;
+    my $dump = new Image::ExifTool::HtmlDump;
+    $dump->Add($start, $size, $comment);
+    $dump->Print($dumpInfo, $raf, $dataPt, $dataPos, $outfile);
+
+=head1 DESCRIPTION
+
+This module contains code used to generate an HTML-based hex dump of
+information for debugging purposes.  This is code is called when the
+ExifTool 'HtmlDump' option is used.
+
+Currently, only EXIF and TIFF information is dumped.
+
+=head1 BUGS
+
+Due to a memory allocation bug in ActivePerl 5.8.x for Windows, this code
+may run extremely slowly when processing large files with this version of
+Perl.
+
+An HTML 4 compliant browser is needed to properly display the generated HTML
+page, but note that some of these browsers (like Mozilla) may not properly
+display linefeeds in the tool tips.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/ICC_Profile.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/ICC_Profile.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/ICC_Profile.pm	(revision 20131)
@@ -0,0 +1,836 @@
+#------------------------------------------------------------------------------
+# File:         ICC_Profile.pm
+#
+# Description:  Read ICC Profile meta information
+#
+# Revisions:    11/16/04 - P. Harvey Created
+#
+# References:   1) http://www.color.org/icc_specs2.html (ICC.1:2003-09)
+#               2) http://www.color.org/icc_specs2.html (ICC.1:2001-04)
+#               3) http://developer.apple.com/documentation/GraphicsImaging/Reference/ColorSync_Manager/ColorSync_Manager.pdf
+#               4) http://www.color.org/privatetag2007-01.pdf
+#
+# Notes:        The ICC profile information is different: the format of each
+#               tag is embedded in the information instead of in the directory
+#               structure. This makes things a bit more complex because I need
+#               an extra level of logic to decode the variable-format tags.
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::ICC_Profile;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.13';
+
+sub ProcessICC($$);
+sub ProcessICC_Profile($$$);
+sub WriteICC_Profile($$;$);
+sub ValidateICC($);
+
+# illuminant type definitions
+my %illuminantType = (
+    1 => 'D50',
+    2 => 'D65',
+    3 => 'D93',
+    4 => 'F2',
+    5 => 'D55',
+    6 => 'A',
+    7 => 'Equi-Power (E)',
+    8 => 'F8',
+);
+my %profileClass = (
+    scnr => 'Input Device Profile',
+    mntr => 'Display Device Profile',
+    prtr => 'Output Device Profile',
+   'link'=> 'DeviceLink Profile',
+    spac => 'ColorSpace Conversion Profile',
+    abst => 'Abstract Profile',
+    nmcl => 'NamedColor Profile',
+);
+
+# ICC_Profile tag table
+%Image::ExifTool::ICC_Profile::Main = (
+    GROUPS => { 2 => 'Image' },
+    PROCESS_PROC => \&ProcessICC_Profile,
+    WRITE_PROC => \&WriteICC_Profile,
+    NOTES => q{
+        ICC profile information is used in many different file types including JPEG,
+        TIFF, PDF, PostScript, Photoshop, PNG, MIFF, PICT, QuickTime and some RAW
+        formats.  While the tags listed below are not individually writable, the
+        entire profile itself can be accessed via the extra 'ICC_Profile' tag, but
+        this tag is neither extracted nor written unless specified explicitly.
+    },
+    A2B0 => 'AToB0',
+    A2B1 => 'AToB1',
+    A2B2 => 'AToB2',
+    bXYZ => 'BlueMatrixColumn', # (called BlueColorant in ref 2)
+    bTRC => {
+        Name => 'BlueTRC',
+        Description => 'Blue Tone Reproduction Curve',
+    },
+    B2A0 => 'BToA0',
+    B2A1 => 'BToA1',
+    B2A2 => 'BToA2',
+    calt => {
+        Name => 'CalibrationDateTime',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    targ => 'CharTarget',
+    chad => 'ChromaticAdaptation',
+    chrm => {
+        Name => 'Chromaticity',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Chromaticity',
+            Validate => '$type eq "chrm"',
+        },
+    },
+    clro => 'ColorantOrder',
+    clrt => {
+        Name => 'ColorantTable',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::ColorantTable',
+            Validate => '$type eq "clrt"',
+        },
+    },
+    cprt => 'ProfileCopyright',
+    crdi => 'CRDInfo', #2
+    dmnd => {
+        Name => 'DeviceMfgDesc',
+        Groups => { 2 => 'Camera' },
+    },
+    dmdd => {
+        Name => 'DeviceModelDesc',
+        Groups => { 2 => 'Camera' },
+    },
+    devs => {
+        Name => 'DeviceSettings', #2
+        Groups => { 2 => 'Camera' },
+    },
+    gamt => 'Gamut',
+    kTRC => {
+        Name => 'GrayTRC',
+        Description => 'Gray Tone Reproduction Curve',
+    },
+    gXYZ => 'GreenMatrixColumn', # (called GreenColorant in ref 2)
+    gTRC => {
+        Name => 'GreenTRC',
+        Description => 'Green Tone Reproduction Curve',
+    },
+    lumi => 'Luminance',
+    meas => {
+        Name => 'Measurement',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Measurement',
+            Validate => '$type eq "meas"',
+        },
+    },
+    bkpt => 'MediaBlackPoint',
+    wtpt => 'MediaWhitePoint',
+    ncol => 'NamedColor', #2
+    ncl2 => 'NamedColor2',
+    resp => 'OutputResponse',
+    pre0 => 'Preview0',
+    pre1 => 'Preview1',
+    pre2 => 'Preview2',
+    desc => 'ProfileDescription',
+    pseq => 'ProfileSequenceDesc',
+    psd0 => 'PostScript2CRD0', #2
+    psd1 => 'PostScript2CRD1', #2
+    psd2 => 'PostScript2CRD2', #2
+    ps2s => 'PostScript2CSA', #2
+    ps2i => 'PS2RenteringIntent', #2
+    rXYZ => 'RedMatrixColumn', # (called RedColorant in ref 2)
+    rTRC => {
+        Name => 'RedTRC',
+        Description => 'Red Tone Reproduction Curve',
+    },
+    scrd => 'ScreeningDesc',
+    scrn => 'Screening',
+   'bfd '=> {
+        Name => 'UCRBG',
+        Description => 'Under Color Removal & Black Gen.',
+    },
+    tech => {
+        Name => 'Technology',
+        PrintConv => {
+            fscn => 'Film Scanner',
+            dcam => 'Digital Camera',
+            rscn => 'Reflective Scanner',
+            ijet => 'Ink Jet Printer',
+            twax => 'Thermal Wax Printer',
+            epho => 'Electrophotographic Printer',
+            esta => 'Electrostatic Printer',
+            dsub => 'Dye Sublimation Printer',
+            rpho => 'Photographic Paper Printer',
+            fprn => 'Film Writer',
+            vidm => 'Video Monitor',
+            vidc => 'Video Camera',
+            pjtv => 'Projection Television',
+           'CRT '=> 'Cathode Ray Tube Display',
+           'PMD '=> 'Passive Matrix Display',
+           'AMD '=> 'Active Matrix Display',
+            KPCD => 'Photo CD',
+            imgs => 'Photo Image Setter',
+            grav => 'Gravure',
+            offs => 'Offset Lithography',
+            silk => 'Silkscreen',
+            flex => 'Flexography',
+        },
+    },
+    vued => 'ViewingCondDesc',
+    view => {
+        Name => 'ViewingConditions',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::ViewingConditions',
+            Validate => '$type eq "view"',
+        },
+    },
+    # ColorSync custom tags (ref 3)
+    psvm => 'PS2CRDVMSize',
+    vcgt => 'VideoCardGamma',
+    mmod => 'MakeAndModel',
+    dscm => 'ProfileDescriptionML',
+    ndin => 'NativeDisplayInfo',
+    
+    # Microsoft custom tags (ref http://msdn2.microsoft.com/en-us/library/ms536870.aspx)
+    MS00 => 'WCSProfiles',
+
+    # the following entry represents the ICC profile header, and doesn't
+    # exist as a tag in the directory.  It is only in this table to provide
+    # a link so ExifTool can locate the header tags
+    Header => {
+        Name => 'ProfileHeader',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Header',
+        },
+    },
+);
+
+# ICC profile header definition
+%Image::ExifTool::ICC_Profile::Header = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'ICC_Profile', 1 => 'ICC-header', 2 => 'Image' },
+    4 => {
+        Name => 'ProfileCMMType',
+        Format => 'string[4]',
+    },
+    8 => {
+        Name => 'ProfileVersion',
+        Format => 'int16s',
+        PrintConv => '($val >> 8).".".(($val & 0xf0)>>4).".".($val & 0x0f)',
+    },
+    12 => {
+        Name => 'ProfileClass',
+        Format => 'string[4]',
+        PrintConv => \%profileClass,
+    },
+    16 => {
+        Name => 'ColorSpaceData',
+        Format => 'string[4]',
+    },
+    20 => {
+        Name => 'ProfileConnectionSpace',
+        Format => 'string[4]',
+    },
+    24 => {
+        Name => 'ProfileDateTime',
+        Groups => { 2 => 'Time' },
+        Format => 'int16u[6]',
+        ValueConv => 'sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%.2d",split(" ",$val));',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    36 => {
+        Name => 'ProfileFileSignature',
+        Format => 'string[4]',
+    },
+    40 => {
+        Name => 'PrimaryPlatform',
+        Format => 'string[4]',
+        PrintConv => {
+            'APPL' => 'Apple Computer Inc.',
+            'MSFT' => 'Microsoft Corporation',
+            'SGI ' => 'Silicon Graphics Inc.',
+            'SUNW' => 'Sun Microsystems Inc.',
+            'TGNT' => 'Taligent Inc.',
+        },
+    },
+    44 => {
+        Name => 'CMMFlags',
+        Format => 'int32u',
+        PrintConv => q[
+            ($val & 0x01 ? "Embedded, " : "Not Embedded, ") .
+            ($val & 0x02 ? "Not Independent" : "Independent")
+        ],
+    },
+    48 => {
+        Name => 'DeviceManufacturer',
+        Format => 'string[4]',
+    },
+    52 => {
+        Name => 'DeviceModel',
+        Format => 'string[4]',
+    },
+    56 => {
+        Name => 'DeviceAttributes',
+        Format => 'int32u[2]',
+        PrintConv => q[
+            my @v = split ' ', $val;
+            ($v[1] & 0x01 ? "Transparency, " : "Reflective, ") .
+            ($v[1] & 0x02 ? "Matte, " : "Glossy, ") .
+            ($v[1] & 0x04 ? "Negative, " : "Positive, ") .
+            ($v[1] & 0x08 ? "B&W" : "Color");
+        ],
+    },
+    64 => {
+        Name => 'RenderingIntent',
+        Format => 'int32u',
+        PrintConv => {
+            0 => 'Perceptual',
+            1 => 'Media-Relative Colorimetric',
+            2 => 'Saturation',
+            3 => 'ICC-Absolute Colorimetric',
+        },
+    },
+    68 => {
+        Name => 'ConnectionSpaceIlluminant',
+        Format => 'fixed32s[3]',  # xyz
+    },
+    80 => {
+        Name => 'ProfileCreator',
+        Format => 'string[4]',
+    },
+    84 => {
+        Name => 'ProfileID',
+        Format => 'int8u[16]',
+        PrintConv => 'Image::ExifTool::ICC_Profile::HexID($val)',
+    },
+);
+
+# viewingConditionsType (view) definition
+%Image::ExifTool::ICC_Profile::ViewingConditions = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'ICC_Profile', 1 => 'ICC-view', 2 => 'Image' },
+    8 => {
+        Name => 'ViewingCondIlluminant',
+        Format => 'fixed32s[3]',   # xyz
+    },
+    20 => {
+        Name => 'ViewingCondSurround',
+        Format => 'fixed32s[3]',   # xyz
+    },
+    32 => {
+        Name => 'ViewingCondIlluminantType',
+        Format => 'int32u',
+        PrintConv => \%illuminantType,
+    },
+);
+
+# measurementType (meas) definition
+%Image::ExifTool::ICC_Profile::Measurement = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'ICC_Profile', 1 => 'ICC-meas', 2 => 'Image' },
+    8 => {
+        Name => 'MeasurementObserver',
+        Format => 'int32u',
+        PrintConv => {
+            1 => 'CIE 1931',
+            2 => 'CIE 1964',
+        },
+    },
+    12 => {
+        Name => 'MeasurementBacking',
+        Format => 'fixed32s[3]',   # xyz
+    },
+    24 => {
+        Name => 'MeasurementGeometry',
+        Format => 'int32u',
+        PrintConv => {
+            1 => '0/45 or 45/0',
+            2 => '0/d or d/0',
+        },
+    },
+    28 => {
+        Name => 'MeasurementFlare',
+        Format => 'fixed32u',
+        PrintConv => '$val*100 . "%"',  # change into a percent
+    },
+    32 => {
+        Name => 'MeasurementIlluminant',
+        Format => 'int32u',
+        PrintConv => \%illuminantType,
+    },
+);
+
+# chromaticity (chrm) definition
+%Image::ExifTool::ICC_Profile::Chromaticity = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'ICC_Profile', 1 => 'ICC-chrm', 2 => 'Image' },
+    8 => {
+        Name => 'ChromaticityChannels',
+        Format => 'int16u',
+    },
+    10 => {
+        Name => 'ChromaticityColorant',
+        Format => 'int16u',
+        PrintConv => {
+            1 => 'ITU-R BT.709',
+            2 => 'SMPTE RP145-1994',
+            3 => 'EBU Tech.3213-E',
+            4 => 'P22',
+        },
+    },
+    # include definitions for 4 channels -- if there are
+    # fewer then the ProcessBinaryData logic won't print them.
+    # If there are more, oh well.
+    12 => {
+        Name => 'ChromaticityChannel1',
+        Format => 'fixed32u[2]',
+    },
+    20 => {
+        Name => 'ChromaticityChannel2',
+        Format => 'fixed32u[2]',
+    },
+    28 => {
+        Name => 'ChromaticityChannel3',
+        Format => 'fixed32u[2]',
+    },
+    36 => {
+        Name => 'ChromaticityChannel4',
+        Format => 'fixed32u[2]',
+    },
+);
+
+# colorantTable (clrt) definition
+%Image::ExifTool::ICC_Profile::ColorantTable = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'ICC_Profile', 1 => 'ICC-clrt', 2 => 'Image' },
+    8 => {
+        Name => 'ColorantCount',
+        Format => 'int32u',
+    },
+    # include definitions for 3 colorants -- if there are
+    # fewer then the ProcessBinaryData logic won't print them.
+    # If there are more, oh well.
+    12 => {
+        Name => 'Colorant1Name',
+        Format => 'string[32]',
+    },
+    44 => {
+        Name => 'Colorant1Coordinates',
+        Format => 'int16u[3]',
+    },
+    50 => {
+        Name => 'Colorant2Name',
+        Format => 'string[32]',
+    },
+    82 => {
+        Name => 'Colorant2Coordinates',
+        Format => 'int16u[3]',
+    },
+    88 => {
+        Name => 'Colorant3Name',
+        Format => 'string[32]',
+    },
+    120 => {
+        Name => 'Colorant3Coordinates',
+        Format => 'int16u[3]',
+    },
+);
+
+
+#------------------------------------------------------------------------------
+# print ICC Profile ID in hex
+# Inputs: 1) string of numbers
+# Returns: string of hex digits
+sub HexID($)
+{
+    my $val = shift;
+    my @vals = split(' ', $val);
+    # return a simple zero if no MD5 done
+    return 0 unless grep(!/^0/, @vals);
+    $val = '';
+    foreach (@vals) { $val .= sprintf("%.2x",$_); }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# get formatted value from ICC tag (which has the type embedded)
+# Inputs: 0) data reference, 1) offset to tag data, 2) tag data size
+# Returns: Formatted value or undefined if format not supported
+# Notes: The following types are handled by BinaryTables:
+#  chromaticityType, colorantTableType, measurementType, viewingConditionsType
+# The following types are not currently handled (most are large tables):
+#  curveType, lut16Type, lut8Type, lutAtoBType, lutBtoAType, namedColor2Type,
+#  parametricCurveType, profileSeqDescType, responseCurveSet16Type
+sub FormatICCTag($$$)
+{
+    my ($dataPt, $offset, $size) = @_;
+
+    my $type;
+    if ($size >= 8) {
+        # get data type from start of tag data
+        $type = substr($$dataPt, $offset, 4);
+    } else {
+        $type = 'err';
+    }
+    # colorantOrderType
+    if ($type eq 'clro' and $size >= 12) {
+        my $num = Get32u($dataPt, $offset+8);
+        if ($size >= $num + 12) {
+            my $pos = $offset + 12;
+            return join(' ',unpack("x$pos c$num", $$dataPt));
+        }
+    }
+    # dataType
+    if ($type eq 'data' and $size >= 12) {
+        my $form = Get32u($dataPt, $offset+8);
+        # format 0 is ASCII data
+        $form == 0 and return substr($$dataPt, $offset+12, $size-12);
+        # binary data and other data types treat as binary (ie. don't format)
+    }
+    # dateTimeType
+    if ($type eq 'dtim' and $size >= 20) {
+        return sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%.2d",
+               Get16u($dataPt, $offset+8),  Get16u($dataPt, $offset+10),
+               Get16u($dataPt, $offset+12), Get16u($dataPt, $offset+14),
+               Get16u($dataPt, $offset+16), Get16u($dataPt, $offset+18));
+    }
+    # multiLocalizedUnicodeType (replaces textDescriptionType of ref 2)
+    if ($type eq 'mluc' and $size >= 28) {
+        # take first language in list (pray that it is ascii)
+        my $len = Get32u($dataPt, $offset + 20);
+        my $pos = Get32u($dataPt, $offset + 24);
+        if ($size >= $pos + $len) {
+            my $str = substr($$dataPt, $offset + $pos, $len);
+            $str =~ tr/\x00-\x1f\x80-\xff//d; # remove control characters and non-ascii
+            return $str;
+        }
+    }
+    # s15Fixed16ArrayType
+    if ($type eq 'sf32') {
+        return ReadValue($dataPt,$offset+8,'fixed32s',($size-8)/4,$size-8);
+    }
+    # signatureType
+    if ($type eq 'sig ' and $size >= 12) {
+        return substr($$dataPt, $offset+8, 4);
+    }
+    # textType
+    $type eq 'text' and return substr($$dataPt, $offset+8, $size-8);
+    # textDescriptionType (ref 2, replaced by multiLocalizedUnicodeType)
+    if ($type eq 'desc' and $size >= 12) {
+        my $len = Get32u($dataPt, $offset+8);
+        if ($size >= $len + 12) {
+            my $str = substr($$dataPt, $offset+12, $len);
+            $str =~ s/\0.*//s;   # truncate at null terminator
+            return $str;
+        }
+    }
+    # u16Fixed16ArrayType
+    if ($type eq 'uf32') {
+        return ReadValue($dataPt,$offset+8,'fixed32u',($size-8)/4,$size-8);
+    }
+    # uInt32ArrayType
+    if ($type eq 'ui32') {
+        return ReadValue($dataPt,$offset+8,'int32u',($size-8)/4,$size-8);
+    }
+    # uInt64ArrayType
+    if ($type eq 'ui64') {
+        return ReadValue($dataPt,$offset+8,'int64u',($size-8)/8,$size-8);
+    }
+    # uInt8ArrayType
+    if ($type eq 'ui08') {
+        return ReadValue($dataPt,$offset+8,'int8u',$size-8,$size-8);
+    }
+    # XYZType
+    if ($type eq 'XYZ ') {
+        my $str = '';
+        my $pos;
+        for ($pos=8; $pos+12<=$size; $pos+=12) {
+            $str and $str .= ', ';
+            $str .= ReadValue($dataPt,$offset+$pos,'fixed32s',3,$size-$pos);
+        }
+        return $str;
+    }
+    return undef;   # data type is not supported
+}
+
+#------------------------------------------------------------------------------
+# Write ICC profile file
+# Inputs: 0) ExifTool object reference, 1) Reference to directory information
+# Returns: 1 on success, 0 if this wasn't a valid ICC file,
+#          or -1 if a write error occurred
+sub WriteICC($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    # first make sure this is a valid ICC file (or no file at all)
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+    return 0 if $raf->Read($buff, 24) and ValidateICC(\$buff);
+    # now write the new ICC
+    $buff = WriteICC_Profile($exifTool, $dirInfo);
+    if (defined $buff and length $buff) {
+        Write($$dirInfo{OutFile}, $buff) or return -1;
+    } else {
+        $exifTool->Error('No ICC information to write');
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Write ICC data record
+# Inputs: 0) ExifTool object reference, 1) source dirInfo reference,
+#         2) tag table reference
+# Returns: ICC data block (may be empty if no ICC data)
+# Notes: Increments ExifTool CHANGED flag if changed
+sub WriteICC_Profile($$;$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    $exifTool or return 1;    # allow dummy access
+    my $dirName = $$dirInfo{DirName} || 'ICC_Profile';
+    # (don't write AsShotICCProfile or CurrentICCProfile here)
+    return undef unless $dirName eq 'ICC_Profile';
+    my $newValueHash = $exifTool->GetNewValueHash($Image::ExifTool::Extra{$dirName});
+    return undef unless Image::ExifTool::IsOverwriting($newValueHash);
+    my $val = Image::ExifTool::GetNewValues($newValueHash);
+    $val = '' unless defined $val;
+    ++$exifTool->{CHANGED};
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Validate ICC data
+# Inputs: 0) ICC data reference
+# Returns: error string or undef on success
+sub ValidateICC($)
+{
+    my $valPtr = shift;
+    my $err;
+    length($$valPtr) < 24 and return 'Invalid ICC profile';
+    $profileClass{substr($$valPtr, 12, 4)} or $err = 'profile class';
+    my $col = substr($$valPtr, 16, 4); # ColorSpaceData
+    my $con = substr($$valPtr, 20, 4); # ConnectionSpace
+    my $match = '(XYZ |Lab |Luv |YCbr|Yxy |RGB |GRAY|HSV |HLS |CMYK|CMY |[2-9A-F]CLR)';
+    $col =~ /$match/ or $err = 'color space';
+    $con =~ /$match/ or $err = 'connection space';
+    return $err ? "Invalid ICC profile (bad $err)" : undef;
+}
+
+#------------------------------------------------------------------------------
+# Process ICC profile file
+# Inputs: 0) ExifTool object reference, 1) Reference to directory information
+# Returns: 1 if this was an ICC file
+sub ProcessICC($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+    $raf->Read($buff, 24) == 24 or return 0;
+    # check to see if this is a valid ICC profile file
+    return 0 if ValidateICC(\$buff);
+    $exifTool->SetFileType();
+    # read the profile
+    my $size = unpack('N', $buff);
+    if ($size < 128 or $size & 0x80000000) {
+        $exifTool->Error("Bad ICC Profile length ($size)");
+        return 1;
+    }
+    $raf->Seek(0, 0);
+    unless ($raf->Read($buff, $size)) {
+        $exifTool->Error('Truncated ICC profile');
+        return 1;
+    }
+    my %dirInfo = (
+        DataPt => \$buff,
+        DataLen => $size,
+        DirStart => 0,
+        DirLen => $size,
+    );
+    my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
+    return ProcessICC_Profile($exifTool, \%dirInfo, $tagTablePtr);
+}
+
+#------------------------------------------------------------------------------
+# Process ICC_Profile APP13 record
+# Inputs: 0) ExifTool object reference, 1) Reference to directory information
+#         2) Tag table reference (undefined to read ICC file)
+# Returns: 1 on success
+sub ProcessICC_Profile($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart};
+    my $dirLen = $$dirInfo{DirLen};
+    my $verbose = $exifTool->Options('Verbose');
+    my $raf;
+
+    # extract binary ICC_Profile data block if binary mode or requested
+    if ($exifTool->{OPTIONS}->{Binary} or $exifTool->{REQ_TAG_LOOKUP}->{icc_profile} and
+        # (don't extract from AsShotICCProfile or CurrentICCProfile)
+        (not $$dirInfo{Name} or $$dirInfo{Name} eq 'ICC_Profile'))
+    {
+        $exifTool->FoundTag('ICC_Profile', substr($$dataPt, $dirStart, $dirLen));
+    }
+
+    SetByteOrder('MM');     # ICC_Profile is always big-endian
+
+    # check length of table
+    my $len = Get32u($dataPt, $dirStart);
+    if ($len != $dirLen or $len < 128) {
+        $exifTool->Warn("Bad length ICC_Profile (length $len)");
+        return 0 if $len < 128 or $dirLen < $len;
+    }
+    my $pos = $dirStart + 128;  # position at start of table
+    my $numEntries = Get32u($dataPt, $pos);
+    if ($numEntries < 1 or $numEntries >= 0x100
+        or $numEntries * 12 + 132 > $dirLen)
+    {
+        $exifTool->Warn("Bad ICC_Profile table ($numEntries entries)");
+        return 0;
+    }
+
+    if ($verbose) {
+        $exifTool->VerboseDir('ICC_Profile', $numEntries, $dirLen);
+        my $fakeInfo = { Name=>'ProfileHeader', SubDirectory => { } };
+        $exifTool->VerboseInfo(undef, $fakeInfo);
+    }
+    # increment ICC dir count
+    my $dirCount = $exifTool->{DIR_COUNT}->{ICC} = ($exifTool->{DIR_COUNT}->{ICC} || 0) + 1;
+    $exifTool->{SET_GROUP1} = '+' . $dirCount if $dirCount > 1;
+    # process the header block
+    my %subdirInfo = (
+        Name     => 'ProfileHeader',
+        DataPt   => $dataPt,
+        DataLen  => $$dirInfo{DataLen},
+        DirStart => $dirStart,
+        DirLen   => 128,
+        Parent   => $$dirInfo{DirName},
+    );
+    my $newTagTable = GetTagTable('Image::ExifTool::ICC_Profile::Header');
+    $exifTool->ProcessDirectory(\%subdirInfo, $newTagTable);
+
+    $pos += 4;    # skip item count
+    my $index;
+    for ($index=0; $index<$numEntries; ++$index) {
+        my $tagID  = substr($$dataPt, $pos, 4);
+        my $offset = Get32u($dataPt, $pos + 4);
+        my $size   = Get32u($dataPt, $pos + 8);
+        $pos += 12;
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+        # unknown tags aren't generated automatically by GetTagInfo()
+        # if the tagID's aren't numeric, so we must do this manually:
+        if (not $tagInfo and $exifTool->{OPTIONS}->{Unknown}) {
+            $tagInfo = { Unknown => 1 };
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tagID, $tagInfo);
+        }
+        next unless defined $tagInfo;
+
+        if ($offset + $size > $dirLen) {
+            $exifTool->Warn("Bad ICC_Profile table (truncated)");
+            last;
+        }
+        my $valuePtr = $dirStart + $offset;
+
+        my $subdir = $$tagInfo{SubDirectory};
+        # format the value unless this is a subdirectory
+        my $value;
+        $value = FormatICCTag($dataPt, $valuePtr, $size) unless $subdir;
+        my $fmt;
+        $fmt = substr($$dataPt, $valuePtr, 4) if $size > 4;
+        $verbose and $exifTool->VerboseInfo($tagID, $tagInfo,
+            Table  => $tagTablePtr,
+            Index  => $index,
+            Value  => $value,
+            DataPt => $dataPt,
+            Size   => $size,
+            Start  => $valuePtr,
+            Format => "type '$fmt'",
+        );
+        if ($subdir) {
+            my $name = $$tagInfo{Name};
+            undef $newTagTable;
+            if ($$subdir{TagTable}) {
+                $newTagTable = GetTagTable($$subdir{TagTable});
+                unless ($newTagTable) {
+                    warn "Unknown tag table $$subdir{TagTable}\n";
+                    next;
+                }
+            } else {
+                warn "Must specify TagTable for SubDirectory $name\n";
+                next;
+            }
+            %subdirInfo = (
+                Name     => $name,
+                DataPt   => $dataPt,
+                DataPos  => $$dirInfo{DataPos},
+                DataLen  => $$dirInfo{DataLen},
+                DirStart => $valuePtr,
+                DirLen   => $size,
+                Parent   => $$dirInfo{DirName},
+            );
+            my $type = substr($$dataPt, $valuePtr, 4);
+            #### eval Validate ($type)
+            if (defined $$subdir{Validate} and not eval $$subdir{Validate}) {
+                $exifTool->Warn("Invalid $name data");
+            } else {
+                $exifTool->ProcessDirectory(\%subdirInfo, $newTagTable, $$subdir{ProcessProc});
+            }
+        } elsif (defined $value) {
+            $exifTool->FoundTag($tagInfo, $value);
+        } else {
+            $value = substr($$dataPt, $valuePtr, $size);
+            # treat unsupported formats as binary data
+            my $oldValueConv = $$tagInfo{ValueConv};
+            $$tagInfo{ValueConv} = '\$val' unless defined $$tagInfo{ValueConv};
+            $exifTool->FoundTag($tagInfo, $value);
+        }
+    }
+    delete $exifTool->{SET_GROUP1};
+    return 1;
+}
+
+
+1; # end
+
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::ICC_Profile - Read ICC Profile meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains the definitions to read information from ICC profiles.
+ICC (International Color Consortium) profiles are used to translate color
+data created on one device into another device's native color space.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.color.org/icc_specs2.html>
+
+=item L<http://developer.apple.com/documentation/GraphicsImaging/Reference/ColorSync_Manager/ColorSync_Manager.pdf>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/ICC_Profile Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/ID3.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/ID3.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/ID3.pm	(revision 20131)
@@ -0,0 +1,957 @@
+#------------------------------------------------------------------------------
+# File:         ID3.pm
+#
+# Description:  Read ID3 meta information
+#
+# Revisions:    09/12/2005 - P. Harvey Created
+#
+# References:   1) http://www.id3.org/
+#               2) http://www.mp3-tech.org/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::ID3;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.11';
+
+sub ProcessID3v2($$$);
+sub ProcessPrivate($$$);
+
+# audio formats that we process after an ID3v2 header (in order)
+my @audioFormats = qw(APE MPC FLAC OGG MP3);
+
+# audio formats where the processing proc is in a different module
+my %audioModule = (
+    MP3 => 'ID3',
+    OGG => 'Vorbis',
+);
+
+my %warnedOnce;     # hash of warnings we issued
+
+# This table is just for documentation purposes
+%Image::ExifTool::ID3::Main = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, # (not really)
+    NOTES => q{
+        ExifTool extracts ID3 information from MP3, MPEG, AIFF, OGG, FLAC, APE and
+        RealAudio files.
+    },
+    ID3v1 => {
+        Name => 'ID3v1',
+        SubDirectory => { TagTable => 'Image::ExifTool::ID3::v1' },
+    },
+    ID3v22 => {
+        Name => 'ID3v2_2',
+        SubDirectory => { TagTable => 'Image::ExifTool::ID3::v2_2' },
+    },
+    ID3v23 => {
+        Name => 'ID3v2_3',
+        SubDirectory => { TagTable => 'Image::ExifTool::ID3::v2_3' },
+    },
+    ID3v24 => {
+        Name => 'ID3v2_4',
+        SubDirectory => { TagTable => 'Image::ExifTool::ID3::v2_4' },
+    },
+);
+
+# Mapping for ID3v1 Genre numbers
+my %genre = (
+      0 => 'Blues',
+      1 => 'Classic Rock',
+      2 => 'Country',
+      3 => 'Dance',
+      4 => 'Disco',
+      5 => 'Funk',
+      6 => 'Grunge',
+      7 => 'Hip-Hop',
+      8 => 'Jazz',
+      9 => 'Metal',
+     10 => 'New Age',
+     11 => 'Oldies',
+     12 => 'Other',
+     13 => 'Pop',
+     14 => 'R&B',
+     15 => 'Rap',
+     16 => 'Reggae',
+     17 => 'Rock',
+     18 => 'Techno',
+     19 => 'Industrial',
+     20 => 'Alternative',
+     21 => 'Ska',
+     22 => 'Death Metal',
+     23 => 'Pranks',
+     24 => 'Soundtrack',
+     25 => 'Euro-Techno',
+     26 => 'Ambient',
+     27 => 'Trip-Hop',
+     28 => 'Vocal',
+     29 => 'Jazz+Funk',
+     30 => 'Fusion',
+     31 => 'Trance',
+     32 => 'Classical',
+     33 => 'Instrumental',
+     34 => 'Acid',
+     35 => 'House',
+     36 => 'Game',
+     37 => 'Sound Clip',
+     38 => 'Gospel',
+     39 => 'Noise',
+     40 => 'AlternRock',
+     41 => 'Bass',
+     42 => 'Soul',
+     43 => 'Punk',
+     44 => 'Space',
+     45 => 'Meditative',
+     46 => 'Instrumental Pop',
+     47 => 'Instrumental Rock',
+     48 => 'Ethnic',
+     49 => 'Gothic',
+     50 => 'Darkwave',
+     51 => 'Techno-Industrial',
+     52 => 'Electronic',
+     53 => 'Pop-Folk',
+     54 => 'Eurodance',
+     55 => 'Dream',
+     56 => 'Southern Rock',
+     57 => 'Comedy',
+     58 => 'Cult',
+     59 => 'Gangsta',
+     60 => 'Top 40',
+     61 => 'Christian Rap',
+     62 => 'Pop/Funk',
+     63 => 'Jungle',
+     64 => 'Native American',
+     65 => 'Cabaret',
+     66 => 'New Wave',
+     67 => 'Psychadelic',
+     68 => 'Rave',
+     69 => 'Showtunes',
+     70 => 'Trailer',
+     71 => 'Lo-Fi',
+     72 => 'Tribal',
+     73 => 'Acid Punk',
+     74 => 'Acid Jazz',
+     75 => 'Polka',
+     76 => 'Retro',
+     77 => 'Musical',
+     78 => 'Rock & Roll',
+     79 => 'Hard Rock',
+     # The following genres are Winamp extensions
+     80 => 'Folk',
+     81 => 'Folk-Rock',
+     82 => 'National Folk',
+     83 => 'Swing',
+     84 => 'Fast Fusion',
+     85 => 'Bebob',
+     86 => 'Latin',
+     87 => 'Revival',
+     88 => 'Celtic',
+     89 => 'Bluegrass',
+     90 => 'Avantgarde',
+     91 => 'Gothic Rock',
+     92 => 'Progressive Rock',
+     93 => 'Psychedelic Rock',
+     94 => 'Symphonic Rock',
+     95 => 'Slow Rock',
+     96 => 'Big Band',
+     97 => 'Chorus',
+     98 => 'Easy Listening',
+     99 => 'Acoustic',
+    100 => 'Humour',
+    101 => 'Speech',
+    102 => 'Chanson',
+    103 => 'Opera',
+    104 => 'Chamber Music',
+    105 => 'Sonata',
+    106 => 'Symphony',
+    107 => 'Booty Bass',
+    108 => 'Primus',
+    109 => 'Porn Groove',
+    110 => 'Satire',
+    111 => 'Slow Jam',
+    112 => 'Club',
+    113 => 'Tango',
+    114 => 'Samba',
+    115 => 'Folklore',
+    116 => 'Ballad',
+    117 => 'Power Ballad',
+    118 => 'Rhythmic Soul',
+    119 => 'Freestyle',
+    120 => 'Duet',
+    121 => 'Punk Rock',
+    122 => 'Drum Solo',
+    123 => 'Acapella',
+    124 => 'Euro-House',
+    125 => 'Dance Hall',
+    255 => 'None',
+    # ID3v2 adds some text short forms...
+    CR  => 'Cover',
+    RX  => 'Remix',
+);
+
+# Tags for ID3v1
+%Image::ExifTool::ID3::v1 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 1 => 'ID3v1', 2 => 'Audio' },
+    PRIORITY => 0,  # let ID3v2 tags replace these if they come later
+    3 => {
+        Name => 'Title',
+        Format => 'string[30]',
+        ValueConv => 'Image::ExifTool::Latin2Charset($self,$val)',
+    },
+    33 => {
+        Name => 'Artist',
+        Groups => { 2 => 'Author' },
+        Format => 'string[30]',
+        ValueConv => 'Image::ExifTool::Latin2Charset($self,$val)',
+    },
+    63 => {
+        Name => 'Album',
+        Format => 'string[30]',
+        ValueConv => 'Image::ExifTool::Latin2Charset($self,$val)',
+    },
+    93 => {
+        Name => 'Year',
+        Groups => { 2 => 'Time' },
+        Format => 'string[4]',
+    },
+    97 => {
+        Name => 'Comment',
+        Format => 'string[30]',
+        ValueConv => 'Image::ExifTool::Latin2Charset($self,$val)',
+    },
+    127 => {
+        Name => 'Genre',
+        Notes => 'CR and RX are ID3v2 only',
+        Format => 'int8u',
+        PrintConv => \%genre,
+    },
+);
+
+# Tags for ID2v2.2
+%Image::ExifTool::ID3::v2_2 = (
+    PROCESS_PROC => \&Image::ExifTool::ID3::ProcessID3v2,
+    GROUPS => { 1 => 'ID3v2_2', 2 => 'Audio' },
+    NOTES => q{
+ExifTool extracts mainly text-based tags from ID3v2 information.  The tags
+in the tables below are those extracted by ExifTool, and don't represent a
+complete list of available ID3v2 tags.
+
+ID3 version 2.2 tags.  (These are the tags written by iTunes 5.0.)
+    },
+    CNT => 'PlayCounter',
+    COM => 'Comment',
+    IPL => 'InvolvedPeople',
+    PIC => {
+        Name => 'Picture',
+        Binary => 1,
+    },
+  # POP => 'Popularimeter',
+    TAL => 'Album',
+    TBP => 'BeatsPerMinute',
+    TCM => 'Composer',
+    TCO =>{
+        Name => 'Genre',
+        Notes => 'uses same lookup table as ID3v1 Genre',
+        PrintConv => 'Image::ExifTool::ID3::PrintGenre($val)',
+    },
+    TCP => 'Compilation', # not part of spec, but used by iTunes
+    TCR => { Name => 'Copyright', Groups => { 2 => 'Author' } },
+    TDA => { Name => 'Date', Groups => { 2 => 'Time' } },
+    TDY => 'PlaylistDelay',
+    TEN => 'EncodedBy',
+    TFT => 'FileType',
+    TIM => { Name => 'Time', Groups => { 2 => 'Time' } },
+    TKE => 'InitialKey',
+    TLA => 'Language',
+    TLE => 'Length',
+    TMT => 'Media',
+    TOA => { Name => 'OriginalArtist', Groups => { 2 => 'Author' } },
+    TOF => 'OriginalFilename',
+    TOL => 'OriginalLyricist',
+    TOR => 'OriginalReleaseYear',
+    TOT => 'OriginalAlbum',
+    TP1 => { Name => 'Artist', Groups => { 2 => 'Author' } },
+    TP2 => 'Band',
+    TP3 => 'Conductor',
+    TP4 => 'InterpretedBy',
+    TPA => 'PartOfSet',
+    TPB => 'Publisher',
+    TRC => 'ISRC', # (international standard recording code)
+    TRD => 'RecordingDates',
+    TRK => 'Track',
+    TSI => 'Size',
+    TSS => 'EncoderSettings',
+    TT1 => 'Grouping',
+    TT2 => 'Title',
+    TT3 => 'Subtitle',
+    TXT => 'Lyricist',
+    TXX => 'UserDefinedText',
+    TYE => { Name => 'Year', Groups => { 2 => 'Time' } },
+    ULT => 'Lyrics',
+    WAF => 'FileRUL',
+    WAR => { Name => 'ArtistURL', Groups => { 2 => 'Author' } },
+    WAS => 'SourceURL',
+    WCM => 'CommercialURL',
+    WCP => { Name => 'CopyrightURL', Groups => { 2 => 'Author' } },
+    WPB => 'PublisherURL',
+    WXX => 'UserDefinedURL',
+);
+
+# tags common to ID3v2.3 and ID3v2.4
+my %id3v2_common = (
+  # AENC => 'AudioEncryption', # Owner, preview start, preview length, encr data
+    APIC => {
+        Name => 'Picture',
+        Binary => 1,
+    },
+    COMM => 'Comment',
+  # COMR => 'Commercial',
+  # ENCR => 'EncryptionMethod',
+  # ETCO => 'EventTimingCodes',
+  # GEOB => 'GeneralEncapsulatedObject',
+  # GRID => 'GroupIdentification',
+  # LINK => 'LinkedInformation',
+    MCDI => { Name => 'MusicCDIdentifier', Binary => 1 },
+  # MLLT => 'MPEGLocationLookupTable',
+  # OWNE => 'Ownership', # enc(1), _price, 00, _date(8), Seller
+    PCNT => 'PlayCounter',
+  # POPM => 'Popularimeter', # _email, 00, rating(1), counter(4-N)
+  # POSS => 'PostSynchronization',
+    PRIV => {
+        Name => 'Private',
+        SubDirectory => { TagTable => 'Image::ExifTool::ID3::Private' },
+    },
+  # RBUF => 'RecommendedBufferSize',
+  # RVRB => 'Reverb',
+  # SYLT => 'SynchronizedLyricText',
+  # SYTC => 'SynchronizedTempoCodes',
+    TALB => 'Album',
+    TBPM => 'BeatsPerMinute',
+    TCOM => 'Composer',
+    TCON =>{
+        Name => 'Genre',
+        Notes => 'uses same lookup table as ID3v1 Genre',
+        PrintConv => 'Image::ExifTool::ID3::PrintGenre($val)',
+    },
+    TCOP => { Name => 'Copyright', Groups => { 2 => 'Author' } },
+    TDLY => 'PlaylistDelay',
+    TENC => 'EncodedBy',
+    TEXT => 'Lyricist',
+    TFLT => 'FileType',
+    TIT1 => 'Grouping',
+    TIT2 => 'Title',
+    TIT3 => 'Subtitle',
+    TKEY => 'InitialKey',
+    TLAN => 'Language',
+    TLEN => {
+        Name => 'Length',
+        ValueConv => '$val / 1000',
+        PrintConv => '"$val sec"',
+    },
+    TMED => 'Media',
+    TOAL => 'OriginalAlbum',
+    TOFN => 'OriginalFilename',
+    TOLY => 'OriginalLyricist',
+    TOPE => { Name => 'OriginalArtist', Groups => { 2 => 'Author' } },
+    TOWN => 'FileOwner',
+    TPE1 => { Name => 'Artist', Groups => { 2 => 'Author' } },
+    TPE2 => 'Band',
+    TPE3 => 'Conductor',
+    TPE4 => 'InterpretedBy',
+    TPOS => 'PartOfSet',
+    TPUB => 'Publisher',
+    TRCK => 'Track',
+    TRSN => 'InternetRadioStationName',
+    TRSO => 'InternetRadioStationOwner',
+    TSRC => 'ISRC', # (international standard recording code)
+    TSSE => 'EncoderSettings',
+    TXXX => 'UserDefinedText',
+  # UFID => 'UniqueFileID',
+    USER => 'TermsOfUse',
+    USLT => 'Lyrics',
+    WCOM => 'CommercialURL',
+    WCOP => 'CopyrightURL',
+    WOAF => 'FileRUL',
+    WOAR => { Name => 'ArtistURL', Groups => { 2 => 'Author' } },
+    WOAS => 'SourceURL',
+    WORS => 'InternetRadioStationURL',
+    WPAY => 'PaymentURL',
+    WPUB => 'PublisherURL',
+    WXXX => 'UserDefinedURL',
+);
+
+# Tags for ID3v2.3 (http://www.id3.org/id3v2.3.0)
+%Image::ExifTool::ID3::v2_3 = (
+    PROCESS_PROC => \&Image::ExifTool::ID3::ProcessID3v2,
+    GROUPS => { 1 => 'ID3v2_3', 2 => 'Audio' },
+    NOTES => 'ID3 version 2.3 tags',
+    %id3v2_common,  # include common tags
+  # EQUA => 'Equalization',
+    IPLS => 'InvolvedPeople',
+  # RVAD => 'RelativeVolumeAdjustment',
+    TDAT => { Name => 'Date', Groups => { 2 => 'Time' } },
+    TIME => { Name => 'Time', Groups => { 2 => 'Time' } },
+    TORY => 'OriginalReleaseYear',
+    TRDA => 'RecordingDates',
+    TSIZ => 'Size',
+    TYER => { Name => 'Year', Groups => { 2 => 'Time' } },
+);
+
+# Tags for ID3v2.4 (http://www.id3.org/id3v2.4.0-frames)
+%Image::ExifTool::ID3::v2_4 = (
+    PROCESS_PROC => \&Image::ExifTool::ID3::ProcessID3v2,
+    GROUPS => { 1 => 'ID3v2_4', 2 => 'Audio' },
+    NOTES => 'ID3 version 2.4 tags',
+    %id3v2_common,  # include common tags
+  # EQU2 => 'Equalization',
+  # RVA2 => 'RelativeVolumeAdjustment',
+  # SEEK => 'Seek',
+  # SIGN => 'Signature',
+    TDEN => { Name => 'EncodingTime',       Groups => { 2 => 'Time' } },
+    TDOR => { Name => 'OriginalReleaseTime',Groups => { 2 => 'Time' } },
+    TDRC => { Name => 'RecordingTime',      Groups => { 2 => 'Time' } },
+    TDRL => { Name => 'ReleaseTime',        Groups => { 2 => 'Time' } },
+    TDTG => { Name => 'TaggingTime',        Groups => { 2 => 'Time' } },
+    TIPL => 'InvolvedPeople',
+    TMCL => 'MusicianCredits',
+    TMOO => 'Mood',
+    TPRO => 'ProducedNotice',
+    TSOA => 'AlbumSortOrder',
+    TSOP => 'PerformerSortOrder',
+    TSOT => 'TitleSortOrder',
+    TSST => 'SetSubtitle',
+);
+
+# ID3 PRIV tags (ref PH)
+%Image::ExifTool::ID3::Private = (
+    PROCESS_PROC => \&Image::ExifTool::ID3::ProcessPrivate,
+    GROUPS => { 1 => 'ID3', 2 => 'Audio' },
+    NOTES => 'ID3 private (PRIV) tags.',
+    XMP => {
+        SubDirectory => {
+            DirName => 'XMP',
+            TagTable => 'Image::ExifTool::XMP::Main',
+        },
+    },
+    PeakValue => {
+        ValueConv => 'length($val)==4 ? unpack("V",$val) : \$val',
+    },
+    AverageLevel => {
+        ValueConv => 'length($val)==4 ? unpack("V",$val) : \$val',
+    },
+);
+
+# can't share tagInfo hashes between two tables, so we must make
+# copies of the necessary hashes
+{
+    my $tag;
+    foreach $tag (keys %id3v2_common) {
+        next unless ref $id3v2_common{$tag} eq 'HASH';
+        my %tagInfo = %{$id3v2_common{$tag}};
+        $Image::ExifTool::ID3::v2_4{$tag} = \%tagInfo;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Process ID3 PRIV data
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+sub ProcessPrivate($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my ($tag, $start);
+    if ($$dataPt =~ /^(.*?)\0/) {
+        $tag = $1;
+        $start = length($tag) + 1;
+    } else {
+        $tag = '';
+        $start = 0;
+    }
+    unless ($$tagTablePtr{$tag}) {
+        $tag =~ tr{/ }{_}d; # translate '/' to '_' and remove spaces
+        $tag = 'private' unless $tag =~ /^[-\w]{1,24}$/;
+        unless ($$tagTablePtr{$tag}) {
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tag,
+                { Name => ucfirst($tag), Binary => 1 });
+        }
+    }
+    my $key = $exifTool->HandleTag($tagTablePtr, $tag, undef,
+        Size  => length($$dataPt) - $start,
+        Start => $start,
+        DataPt => $dataPt,
+    );
+    # set group1 name
+    $exifTool->SetGroup1($key, $$exifTool{ID3_Ver}) if $key;
+}
+
+#------------------------------------------------------------------------------
+# Print ID3v2 Genre
+# Inputs: TCON or TCO frame data
+# Returns: Content type with decoded genre numbers
+sub PrintGenre($)
+{
+    my $val = shift;
+    # make sure that %genre has an entry for all numbers we are interested in
+    # (genre numbers are in brackets for ID3v2.2 and v2.3)
+    while ($val =~ /\((\d+)\)/g) {
+        $genre{$1} or $genre{$1} = "Unknown ($1)";
+    }
+    # (genre numbers are separated by nulls in ID3v2.4,
+    #  but nulls are converted to '/' by DecodeString())
+    while ($val =~ /(?:^|\/)(\d+)/g) {
+        $genre{$1} or $genre{$1} = "Unknown ($1)";
+    }
+    $val =~ s/\((\d+)\)/\($genre{$1}\)/g;
+    $val =~ s/(^|\/)(\d+)/$1$genre{$2}/g;
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Decode ID3 string
+# Inputs: 0) ExifTool object reference, 1) string beginning with encoding byte
+# Returns: Decoded string in scalar context, or list of strings in list context
+sub DecodeString($$)
+{
+    my ($exifTool, $val) = @_;
+    return '' unless length $val;
+    my $enc = unpack('C', $val);
+    $val = substr($val, 1); # remove encoding byte
+    my @vals;
+    if ($enc == 0) {        # ISO 8859-1
+        $val =~ s/\0+$//;   # remove any null padding
+        $val = $exifTool->Latin2Charset($val);
+        @vals = split "\0", $val;
+    } elsif ($enc == 3) {   # UTF-8
+        $val =~ s/\0+$//;
+        $val = $exifTool->UTF82Charset($val);
+        @vals = split "\0", $val;
+    } elsif ($enc == 1 or $enc == 2) {  # UTF-16 with BOM, or UTF-16BE
+        my $bom = "\xfe\xff";
+        my %order = ( "\xfe\xff" => 'MM', "\xff\xfe", => 'II' );
+        for (;;) {
+            my $v;
+            # split string at null terminators on word boundaries
+            if ($val =~ s/((..)*?)\0\0//) {
+                $v = $1;
+            } else {
+                last unless length $val > 1;
+                $v = $val;
+                $val = '';
+            }
+            $bom = $1 if $v =~ s/^(\xfe\xff|\xff\xfe)//;
+            push @vals, $exifTool->Unicode2Charset($v, $order{$bom});
+        }
+    } else {
+        $val =~ s/\0+$//;
+        return "<Unknown encoding $enc> $val";
+    }
+    return @vals if wantarray;
+    return join('/',@vals);
+}
+
+#------------------------------------------------------------------------------
+# Issue one warning of each type
+# Inputs: 0) ExifTool object reference, 1) warning
+sub WarnOnce($$)
+{
+    my ($exifTool, $warn) = @_;
+    unless ($warnedOnce{$warn}) {
+        $warnedOnce{$warn} = 1;
+        $exifTool->Warn($warn);
+    }
+}
+#------------------------------------------------------------------------------
+# Process ID3v2 information
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+sub ProcessID3v2($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt  = $$dirInfo{DataPt};
+    my $offset  = $$dirInfo{DirStart};
+    my $size    = $$dirInfo{DirLen};
+    my $vers    = $$dirInfo{Version};
+    my $verbose = $exifTool->Options('Verbose');
+    my $len;    # frame data length
+
+    $verbose and $exifTool->VerboseDir($tagTablePtr->{GROUPS}->{1}, 0, $size);
+    undef %warnedOnce;
+
+    for (;;$offset+=$len) {
+        my ($id, $flags, $hi);
+        if ($vers < 0x0300) {
+            # version 2.2 frame header is 6 bytes
+            last if $offset + 6 > $size;
+            ($id, $hi, $len) = unpack("x${offset}a3Cn",$$dataPt);
+            last if $id eq "\0\0\0";
+            $len += $hi << 16;
+            $offset += 6;
+        } else {
+            # version 2.3/2.4 frame header is 10 bytes
+            last if $offset + 10 > $size;
+            ($id, $len, $flags) = unpack("x${offset}a4Nn",$$dataPt);
+            last if $id eq "\0\0\0\0";
+            $offset += 10;
+        }
+        last if $offset + $len > $size;
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $id);
+        unless ($tagInfo) {
+            next unless $verbose or $exifTool->Options('Unknown');
+            $id =~ tr/-A-Za-z0-9_//dc;
+            $id = 'unknown' unless length $id;
+            unless ($$tagTablePtr{$id}) {
+                $tagInfo = { Name => "ID3_$id", Binary => 1 };
+                Image::ExifTool::AddTagToTable($tagTablePtr, $id, $tagInfo);
+            }
+        }
+        # decode v2.3 and v2.4 flags
+        my %flags;
+        if ($flags) {
+            if ($vers < 0x0400) {
+                # version 2.3 flags
+                $flags & 0x80 and $flags{Compress} = 1;
+                $flags & 0x40 and $flags{Encrypt}  = 1;
+                $flags & 0x20 and $flags{GroupID}  = 1;
+            } else {
+                # version 2.4 flags
+                $flags & 0x40 and $flags{GroupID}  = 1;
+                $flags & 0x08 and $flags{Compress} = 1;
+                $flags & 0x04 and $flags{Encrypt}  = 1;
+                $flags & 0x02 and $flags{Unsync}   = 1;
+                $flags & 0x01 and $flags{DataLen}  = 1;
+            }
+        }
+        if ($flags{Encrypt}) {
+            WarnOnce($exifTool, 'Encrypted frames currently not supported');
+            next;
+        }
+        # extract the value
+        my $val = substr($$dataPt, $offset, $len);
+
+        # handle the flags
+        if ($flags{Unsync}) {
+            # reverse the unsynchronization
+            $val =~ s/\xff\x00/\xff/g;
+        }
+        if ($flags{GroupID}) {
+            length($val) >= 1 or $exifTool->Warn("Short $id frame"), next;
+            # ignore the grouping identity byte
+            $val = substr($val, 1);
+        }
+        if ($flags{DataLen} or $flags{Compress}) {
+            length($val) >= 4 or $exifTool->Warn("Short $id frame"), next;
+            # ignore data length word
+            $val = substr($val, 4);
+        }
+        if ($flags{Compress}) {
+            if (eval 'require Compress::Zlib') {
+                my $inflate = Compress::Zlib::inflateInit();
+                my ($buff, $stat);
+                $inflate and ($buff, $stat) = $inflate->inflate($val);
+                if ($inflate and $stat == Compress::Zlib::Z_STREAM_END()) {
+                    $val = $buff;
+                } else {
+                    $exifTool->Warn("Error inflating $id frame");
+                    next;
+                }
+            } else {
+                WarnOnce($exifTool,'Install Compress::Zlib to decode compressed frames');
+                next;
+            }
+        }
+        $verbose and $exifTool->VerboseInfo($id, $tagInfo,
+            Table   => $tagTablePtr,
+            Value   => $val,
+            DataPt  => $dataPt,
+            DataPos => $$dirInfo{DataPos},
+            Size    => $len,
+            Start   => $offset,
+        );
+        next unless $tagInfo;
+#
+# decode data in this frame
+#
+        my $valLen = length($val);  # actual value length (after decompression, etc)
+        if ($id =~ /^(TXX|TXXX)$/) {
+            # two encoded strings separated by a null
+            my @vals = DecodeString($exifTool, $val);
+            foreach (0..1) { $vals[$_] = '' unless defined $vals[$_]; }
+            ($val = "($vals[0]) $vals[1]") =~ s/^\(\) //;
+        } elsif ($id =~ /^T/ or $id =~ /^(IPL|IPLS)$/) {
+            $val = DecodeString($exifTool, $val);
+        } elsif ($id =~ /^(WXX|WXXX)$/) {
+            # one encoded string and one Latin string separated by a null
+            my $enc = unpack('C', $val);
+            my $url;
+            if ($enc == 1 or $enc == 2) {
+                ($val, $url) = ($val =~ /^(.(?:..)*?)\0\0(.*)/);
+            } else {
+                ($val, $url) = ($val =~ /^(..*?)\0(.*)/);
+            }
+            unless (defined $val and defined $url) {
+                $exifTool->Warn("Invalid $id frame value");
+                next;
+            }               
+            $val = DecodeString($exifTool, $val);
+            $url =~ s/\0.*//;
+            $val = length($val) ? "($val) $url" : $url;
+        } elsif ($id =~ /^W/) {
+            $val =~ s/\0.*//;   # truncate at null
+        } elsif ($id =~ /^(COM|COMM|ULT|USLT)$/) {
+            $valLen > 4 or $exifTool->Warn("Short $id frame"), next;
+            substr($val, 1, 3) = '';    # remove language code
+            my @vals = DecodeString($exifTool, $val);
+            foreach (0..1) { $vals[$_] = '' unless defined $vals[$_]; }
+            $val = length($vals[0]) ? "($vals[0]) $vals[1]" : $vals[1];
+        } elsif ($id eq 'USER') {
+            $valLen > 4 or $exifTool->Warn('Short USER frame'), next;
+            substr($val, 1, 3) = '';    # remove language code
+            $val = DecodeString($exifTool, $val);
+        } elsif ($id =~ /^(CNT|PCNT)$/) {
+            $valLen >= 4 or $exifTool->Warn("Short $id frame"), next;
+            my $cnt = unpack('N', $val);
+            my $i;
+            for ($i=4; $i<$valLen; ++$i) {
+                $cnt = $cnt * 256 + unpack("x${i}C", $val);
+            }
+            $val = $cnt;
+        } elsif ($id =~ /^(PIC|APIC)$/) {
+            $valLen >= 4 or $exifTool->Warn("Short $id frame"), next;
+            my $enc = unpack('C', $val);
+            my $hdr = ($id eq 'PIC') ? '.{5}.*?\0' : '..*?\0..*?\0';
+            # remove header (encoding, image format or MIME type, picture type, description)
+            $val =~ s/$hdr//s or $exifTool->Warn("Invalid $id frame"), next;
+            $enc and $val =~ s/^\0//;   # remove 2nd terminator if Unicode encoding
+        } elsif ($id eq 'PRIV') {
+            # save version number to set group1 name for tag later
+            $exifTool->{ID3_Ver} = $tagTablePtr->{GROUPS}->{1};
+            $exifTool->HandleTag($tagTablePtr, $id, $val);
+            next;
+        } elsif (not $$tagInfo{Binary}) {
+            $exifTool->Warn("Don't know how to handle $id frame");
+            next;
+        }
+        $exifTool->FoundTag($tagInfo, $val);
+    }
+    undef %warnedOnce;
+}
+
+#------------------------------------------------------------------------------
+# Extract ID3 information from an audio file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this file didn't contain ID3 information
+# - also processes audio data if any ID3 information was found
+# - sets ExifTool DONE_ID3 to 1 when called, or to 2 if an ID3v1 trailer exists
+sub ProcessID3($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    
+    return 0 if $exifTool->{DONE_ID3};  # avoid infinite recursion
+    $exifTool->{DONE_ID3} = 1;
+
+    # allow this to be called with either RAF or DataPt
+    my $raf = $$dirInfo{RAF} || new File::RandomAccess($$dirInfo{DataPt});
+    my ($buff, %id3Header, %id3Trailer, $hBuff, $tBuff, $tBuffPos, $tagTablePtr);
+    my $rtnVal = 0;
+    my $hdrEnd = 0;
+
+    # read first 3 bytes of file
+    $raf->Seek(0, 0);
+    return 0 unless $raf->Read($buff, 3) == 3;
+#
+# identify ID3v2 header
+#
+    while ($buff =~ /^ID3/) {
+        $rtnVal = 1;
+        $raf->Read($hBuff, 7) == 7 or $exifTool->Warn('Short ID3 header'), last;
+        my ($vers, $flags, $size) = unpack('nCN', $hBuff);
+        $size & 0x80808080 and $exifTool->Warn('Invalid ID3 header'), last;
+        my $verStr = sprintf("2.%d.%d", $vers >> 8, $vers & 0xff);
+        if ($vers >= 0x0500) {
+            $exifTool->Warn("Unsupported ID3 version: $verStr");
+            last;
+        }
+        $size =  ($size & 0x0000007f) |
+                (($size & 0x00007f00) >> 1) |
+                (($size & 0x007f0000) >> 2) |
+                (($size & 0x7f000000) >> 3);
+        unless ($raf->Read($hBuff, $size) == $size) {
+            $exifTool->Warn('Truncated ID3 data');
+            last;
+        }
+        if ($flags & 0x80) {
+            # reverse the unsynchronization
+            $hBuff =~ s/\xff\x00/\xff/g;
+        }
+        my $pos = 10;
+        if ($flags & 0x40) {
+            # skip the extended header
+            $size >= 4 or $exifTool->Warn('Bad ID3 extended header'), last;
+            my $len = unpack('N', $hBuff);
+            if ($len > length($hBuff) - 4) {
+                $exifTool->Warn('Truncated ID3 extended header');
+                last;
+            }
+            $hBuff = substr($hBuff, $len + 4);
+            $pos += $len + 4;
+        }
+        if ($flags & 0x10) {
+            # ignore v2.4 footer (10 bytes long)
+            $raf->Seek(10, 1);
+        }
+        %id3Header = (
+            DataPt   => \$hBuff,
+            DataPos  => $pos,
+            DirStart => 0,
+            DirLen   => length($hBuff),
+            Version  => $vers,
+            DirName  => "ID3v$verStr",
+        );
+        if ($vers >= 0x0400) {
+            $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v2_4');
+        } elsif ($vers >= 0x0300) {
+            $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v2_3');
+        } else {
+            $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v2_2');
+        }
+        $hdrEnd = $raf->Tell();
+        last;
+    }
+#
+# read ID3v1 trailer if it exists
+#
+    if ($raf->Seek(-128, 2) and $raf->Read($tBuff, 128) == 128 and $tBuff =~ /^TAG/) {
+        $exifTool->{DONE_ID3} = 2;  # set to 2 as flag that trailer exists
+        %id3Trailer = (
+            DataPt   => \$tBuff,
+            DataPos  => $raf->Tell() - 128,
+            DirStart => 0,
+            DirLen   => length($tBuff),
+        );
+        $rtnVal = 1;
+    }
+#
+# process the the information
+#
+    if ($rtnVal) {
+        # first process audio data if it exists
+        if ($$dirInfo{RAF}) {
+            my $type = $exifTool->{FILE_TYPE};  # save file type
+            # check current file type first
+            my @types = grep /^$type$/, @audioFormats;
+            push @types, grep(!/^$type$/, @audioFormats);
+            my $oldType = $exifTool->{FILE_TYPE};
+            foreach $type (@types) {
+                # seek to end of ID3 header
+                $raf->Seek($hdrEnd, 0);
+                # set type for this file if we are successful
+                $exifTool->{FILE_TYPE} = $type;
+                my $module = $audioModule{$type} || $type;
+                require "Image/ExifTool/$module.pm" or next;
+                my $func = "Image::ExifTool::${module}::Process$type";
+                # process the file
+                no strict 'refs';
+                &$func($exifTool, $dirInfo) and last;
+                use strict 'refs';
+            }
+            $exifTool->{FILE_TYPE} = $type;     # restore original file type
+        }
+        # set file type to MP3 if we didn't find audio data
+        $exifTool->SetFileType('MP3') unless $exifTool->{VALUE}->{FileType};
+        # process ID3v2 header if it exists
+        if (%id3Header) {
+            $exifTool->VPrint(0, "$id3Header{DirName}:\n");
+            $exifTool->ProcessDirectory(\%id3Header, $tagTablePtr);
+        }
+        # process ID3v1 trailer if it exists
+        if (%id3Trailer) {
+            $exifTool->VPrint(0, "ID3v1:\n");
+            SetByteOrder('MM');
+            $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v1');
+            $exifTool->ProcessDirectory(\%id3Trailer, $tagTablePtr);
+        }
+    }
+    # return file pointer to start of file to read audio data if necessary
+    $raf->Seek(0, 0);
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Extract ID3 information from an MP3 audio file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid MP3 file
+sub ProcessMP3($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+
+    # must first check for leading/trailing ID3 information
+    unless ($exifTool->{DONE_ID3}) {
+        require Image::ExifTool::ID3;
+        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
+    }
+    my $raf = $$dirInfo{RAF};
+    my $rtnVal = 0;
+    my $buff;
+#
+# extract information from first audio/video frame headers
+# (if found in the first 256 bytes)
+#
+    if ($raf->Read($buff, 256)) {
+        require Image::ExifTool::MPEG;
+        if ($buff =~ /\0\0\x01(\xb3|\xc0)/) {
+            # look for A/V headers in first 64kB
+            my $buf2;
+            $raf->Read($buf2, 65280) and $buff .= $buf2;
+            $rtnVal = 1 if Image::ExifTool::MPEG::ProcessMPEGAudioVideo($exifTool, \$buff);
+        } else {
+            # look for audio frame sync in first 256 bytes
+            $rtnVal = 1 if Image::ExifTool::MPEG::ProcessMPEGAudio($exifTool, \$buff);
+        }
+    }
+    return $rtnVal;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::ID3 - Read ID3 meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to extract ID3
+information from audio files.  ID3 information is found in MP3 and various
+other types of audio files.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.id3.org/>
+
+=item L<http://www.mp3-tech.org/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/ID3 Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/IPTC.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/IPTC.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/IPTC.pm	(revision 20131)
@@ -0,0 +1,1104 @@
+#------------------------------------------------------------------------------
+# File:         IPTC.pm
+#
+# Description:  Read IPTC meta information
+#
+# Revisions:    Jan. 08/03 - P. Harvey Created
+#               Feb. 05/04 - P. Harvey Added support for records other than 2
+#
+# References:   1) http://www.iptc.org/IIM/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::IPTC;
+
+use strict;
+use vars qw($VERSION $AUTOLOAD %iptcCharset);
+
+$VERSION = '1.23';
+
+%iptcCharset = (
+    "\x1b%G"  => 'UTF8',
+   # don't translate these (at least until we handle ISO 2022 shift codes)
+   # because the sets are only designated and not invoked 
+   # "\x1b,A"  => 'Latin',  # G0 = ISO 8859-1 (similar to Latin1, but codes 0x80-0x9f are missing)
+   # "\x1b-A"  => 'Latin',  # G1     "
+   # "\x1b.A"  => 'Latin',  # G2
+   # "\x1b/A"  => 'Latin',  # G3
+);
+
+sub ProcessIPTC($$$);
+sub WriteIPTC($$$);
+sub CheckIPTC($$$);
+sub PrintCodedCharset($);
+sub PrintInvCodedCharset($);
+
+my %fileFormat = (
+    0 => 'No ObjectData',
+    1 => 'IPTC-NAA Digital Newsphoto Parameter Record',
+    2 => 'IPTC7901 Recommended Message Format',
+    3 => 'Tagged Image File Format (Adobe/Aldus Image data)',
+    4 => 'Illustrator (Adobe Graphics data)',
+    5 => 'AppleSingle (Apple Computer Inc)',
+    6 => 'NAA 89-3 (ANPA 1312)',
+    7 => 'MacBinary II',
+    8 => 'IPTC Unstructured Character Oriented File Format (UCOFF)',
+    9 => 'United Press International ANPA 1312 variant',
+    10 => 'United Press International Down-Load Message',
+    11 => 'JPEG File Interchange (JFIF)',
+    12 => 'Photo-CD Image-Pac (Eastman Kodak)',
+    13 => 'Bit Mapped Graphics File [.BMP] (Microsoft)',
+    14 => 'Digital Audio File [.WAV] (Microsoft & Creative Labs)',
+    15 => 'Audio plus Moving Video [.AVI] (Microsoft)',
+    16 => 'PC DOS/Windows Executable Files [.COM][.EXE]',
+    17 => 'Compressed Binary File [.ZIP] (PKWare Inc)',
+    18 => 'Audio Interchange File Format AIFF (Apple Computer Inc)',
+    19 => 'RIFF Wave (Microsoft Corporation)',
+    20 => 'Freehand (Macromedia/Aldus)',
+    21 => 'Hypertext Markup Language [.HTML] (The Internet Society)',
+    22 => 'MPEG 2 Audio Layer 2 (Musicom), ISO/IEC',
+    23 => 'MPEG 2 Audio Layer 3, ISO/IEC',
+    24 => 'Portable Document File [.PDF] Adobe',
+    25 => 'News Industry Text Format (NITF)',
+    26 => 'Tape Archive [.TAR]',
+    27 => 'Tidningarnas Telegrambyra NITF version (TTNITF DTD)',
+    28 => 'Ritzaus Bureau NITF version (RBNITF DTD)',
+    29 => 'Corel Draw [.CDR]',
+);
+
+# main IPTC tag table
+# Note: ALL entries in main IPTC table (except PROCESS_PROC) must be SubDirectory
+# entries, each specifying a TagTable.
+%Image::ExifTool::IPTC::Main = (
+    GROUPS => { 2 => 'Image' },
+    PROCESS_PROC => \&ProcessIPTC,
+    WRITE_PROC => \&WriteIPTC,
+    1 => {
+        Name => 'IPTCEnvelope',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::IPTC::EnvelopeRecord',
+        },
+    },
+    2 => {
+        Name => 'IPTCApplication',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::IPTC::ApplicationRecord',
+        },
+    },
+    3 => {
+        Name => 'IPTCNewsPhoto',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::IPTC::NewsPhoto',
+        },
+    },
+    7 => {
+        Name => 'IPTCPreObjectData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::IPTC::PreObjectData',
+        },
+    },
+    8 => {
+        Name => 'IPTCObjectData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::IPTC::ObjectData',
+        },
+    },
+    9 => {
+        Name => 'IPTCPostObjectData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::IPTC::PostObjectData',
+        },
+    },
+);
+
+# Record 1 -- EnvelopeRecord
+%Image::ExifTool::IPTC::EnvelopeRecord = (
+    GROUPS => { 2 => 'Other' },
+    WRITE_PROC => \&WriteIPTC,
+    CHECK_PROC => \&CheckIPTC,
+    WRITABLE => 1,
+    0 => {
+        Name => 'EnvelopeRecordVersion',
+        Format => 'int16u',
+    },
+    5 => {
+        Name => 'Destination',
+        Flags => 'List',
+        Groups => { 2 => 'Location' },
+        Format => 'string[0,1024]',
+    },
+    20 => {
+        Name => 'FileFormat',
+        Groups => { 2 => 'Image' },
+        Format => 'int16u',
+        PrintConv => \%fileFormat,
+    },
+    22 => {
+        Name => 'FileVersion',
+        Groups => { 2 => 'Image' },
+        Format => 'int16u',
+    },
+    30 => {
+        Name => 'ServiceIdentifier',
+        Format => 'string[0,10]',
+    },
+    40 => {
+        Name => 'EnvelopeNumber',
+        Format => 'digits[8]',
+    },
+    50 => {
+        Name => 'ProductID',
+        Flags => 'List',
+        Format => 'string[0,32]',
+    },
+    60 => {
+        Name => 'EnvelopePriority',
+        Format => 'digits[1]',
+    },
+    70 => {
+        Name => 'DateSent',
+        Groups => { 2 => 'Time' },
+        Format => 'digits[8]',
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
+        ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
+    },
+    80 => {
+        Name => 'TimeSent',
+        Groups => { 2 => 'Time' },
+        Format => 'string[11]',
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
+        ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
+    },
+    90 => {
+        Name => 'CodedCharacterSet',
+        Notes => q{
+            values are entered in the form "ESC X Y[, ...]".  The escape sequence for
+            UTF-8 character coding is "ESC % G", but this is displayed as "UTF8" for
+            convenience.  Either string may be used when writing.  The value of this tag
+            affects the decoding of string values in the Application and NewsPhoto
+            records
+        },
+        Format => 'string[0,32]',
+        # convert ISO 2022 escape sequences to a more readable format
+        PrintConv => \&PrintCodedCharset,
+        PrintConvInv => \&PrintInvCodedCharset,
+    },
+    100 => {
+        Name => 'UniqueObjectName',
+        Format => 'string[14,80]',
+    },
+    120 => {
+        Name => 'ARMIdentifier',
+        Format => 'int16u',
+    },
+    122 => {
+        Name => 'ARMVersion',
+        Format => 'int16u',
+    },
+);
+
+# Record 2 -- ApplicationRecord
+%Image::ExifTool::IPTC::ApplicationRecord = (
+    GROUPS => { 2 => 'Other' },
+    WRITE_PROC => \&WriteIPTC,
+    CHECK_PROC => \&CheckIPTC,
+    WRITABLE => 1,
+    0 => {
+        Name => 'ApplicationRecordVersion',
+        Format => 'int16u',
+    },
+    3 => {
+        Name => 'ObjectTypeReference',
+        Format => 'string[3,67]',
+    },
+    4 => {
+        Name => 'ObjectAttributeReference',
+        Flags => 'List',
+        Format => 'string[4,68]',
+    },
+    5 => {
+        Name => 'ObjectName',
+        Format => 'string[0,64]',
+    },
+    7 => {
+        Name => 'EditStatus',
+        Format => 'string[0,64]',
+    },
+    8 => {
+        Name => 'EditorialUpdate',
+        Format => 'digits[2]',
+    },
+    10 => {
+        Name => 'Urgency',
+        Format => 'digits[1]',
+    },
+    12 => {
+        Name => 'SubjectReference',
+        Flags => 'List',
+        Format => 'string[13,236]',
+    },
+    15 => {
+        Name => 'Category',
+        Format => 'string[0,3]',
+    },
+    20 => {
+        Name => 'SupplementalCategories',
+        Flags => 'List',
+        Format => 'string[0,32]',
+    },
+    22 => {
+        Name => 'FixtureIdentifier',
+        Format => 'string[0,32]',
+    },
+    25 => {
+        Name => 'Keywords',
+        Flags => 'List',
+        Format => 'string[0,64]',
+    },
+    26 => {
+        Name => 'ContentLocationCode',
+        Flags => 'List',
+        Groups => { 2 => 'Location' },
+        Format => 'string[3]',
+    },
+    27 => {
+        Name => 'ContentLocationName',
+        Flags => 'List',
+        Groups => { 2 => 'Location' },
+        Format => 'string[0,64]',
+    },
+    30 => {
+        Name => 'ReleaseDate',
+        Groups => { 2 => 'Time' },
+        Format => 'digits[8]',
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
+        ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
+    },
+    35 => {
+        Name => 'ReleaseTime',
+        Groups => { 2 => 'Time' },
+        Format => 'string[11]',
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
+        ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
+    },
+    37 => {
+        Name => 'ExpirationDate',
+        Groups => { 2 => 'Time' },
+        Format => 'digits[8]',
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
+        ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
+    },
+    38 => {
+        Name => 'ExpirationTime',
+        Groups => { 2 => 'Time' },
+        Format => 'string[11]',
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
+        ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
+    },
+    40 => {
+        Name => 'SpecialInstructions',
+        Format => 'string[0,256]',
+    },
+    42 => {
+        Name => 'ActionAdvised',
+        Format => 'digits[2]',
+        PrintConv => {
+            '' => '',
+            '01' => 'Object Kill',
+            '02' => 'Object Replace',
+            '03' => 'Ojbect Append',
+            '04' => 'Object Reference',
+        },
+    },
+    45 => {
+        Name => 'ReferenceService',
+        Flags => 'List',
+        Format => 'string[0,10]',
+    },
+    47 => {
+        Name => 'ReferenceDate',
+        Groups => { 2 => 'Time' },
+        Flags => 'List',
+        Format => 'digits[8]',
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
+        ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
+    },
+    50 => {
+        Name => 'ReferenceNumber',
+        Flags => 'List',
+        Format => 'digits[8]',
+    },
+    55 => {
+        Name => 'DateCreated',
+        Groups => { 2 => 'Time' },
+        Format => 'digits[8]',
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
+        ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
+    },
+    60 => {
+        Name => 'TimeCreated',
+        Groups => { 2 => 'Time' },
+        Format => 'string[11]',
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
+        ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
+    },
+    62 => {
+        Name => 'DigitalCreationDate',
+        Groups => { 2 => 'Time' },
+        Format => 'digits[8]',
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
+        ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
+    },
+    63 => {
+        Name => 'DigitalCreationTime',
+        Groups => { 2 => 'Time' },
+        Format => 'string[11]',
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
+        ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
+    },
+    65 => {
+        Name => 'OriginatingProgram',
+        Format => 'string[0,32]',
+    },
+    70 => {
+        Name => 'ProgramVersion',
+        Format => 'string[0,10]',
+    },
+    75 => {
+        Name => 'ObjectCycle',
+        Format => 'string[1]',
+        PrintConv => {
+            'a' => 'Morning',
+            'p' => 'Evening',
+            'b' => 'Both Morning and Evening',
+        },
+    },
+    80 => {
+        Name => 'By-line',
+        Flags => 'List',
+        Format => 'string[0,32]',
+        Groups => { 2 => 'Author' },
+    },
+    85 => {
+        Name => 'By-lineTitle',
+        Flags => 'List',
+        Format => 'string[0,32]',
+        Groups => { 2 => 'Author' },
+    },
+    90 => {
+        Name => 'City',
+        Format => 'string[0,32]',
+        Groups => { 2 => 'Location' },
+    },
+    92 => {
+        Name => 'Sub-location',
+        Format => 'string[0,32]',
+        Groups => { 2 => 'Location' },
+    },
+    95 => {
+        Name => 'Province-State',
+        Format => 'string[0,32]',
+        Groups => { 2 => 'Location' },
+    },
+    100 => {
+        Name => 'Country-PrimaryLocationCode',
+        Format => 'string[3]',
+        Groups => { 2 => 'Location' },
+    },
+    101 => {
+        Name => 'Country-PrimaryLocationName',
+        Format => 'string[0,64]',
+        Groups => { 2 => 'Location' },
+    },
+    103 => {
+        Name => 'OriginalTransmissionReference',
+        Format => 'string[0,32]',
+    },
+    105 => {
+        Name => 'Headline',
+        Format => 'string[0,256]',
+    },
+    110 => {
+        Name => 'Credit',
+        Groups => { 2 => 'Author' },
+        Format => 'string[0,32]',
+    },
+    115 => {
+        Name => 'Source',
+        Groups => { 2 => 'Author' },
+        Format => 'string[0,32]',
+    },
+    116 => {
+        Name => 'CopyrightNotice',
+        Groups => { 2 => 'Author' },
+        Format => 'string[0,128]',
+    },
+    118 => {
+        Name => 'Contact',
+        Flags => 'List',
+        Groups => { 2 => 'Author' },
+        Format => 'string[0,128]',
+    },
+    120 => {
+        Name => 'Caption-Abstract',
+        Format => 'string[0,2000]',
+    },
+    121 => { # (format not certain)
+        Name => 'LocalCaption',
+        Format => 'string[0,256]',
+        Notes => q{
+            I haven't found a reference for the format of tags 121, 184-188 and
+            225-232, so I have just make them writable as strings with
+            reasonable length.  Beware that if this is wrong, other utilities
+            won't be able to read these tags as written by ExifTool.
+        },
+    },
+    122 => {
+        Name => 'Writer-Editor',
+        Flags => 'List',
+        Groups => { 2 => 'Author' },
+        Format => 'string[0,32]',
+    },
+    125 => {
+        Name => 'RasterizedCaption',
+        Format => 'string[7360]',
+        Binary => 1,
+    },
+    130 => {
+        Name => 'ImageType',
+        Groups => { 2 => 'Image' },
+        Format => 'string[2]',
+    },
+    131 => {
+        Name => 'ImageOrientation',
+        Groups => { 2 => 'Image' },
+        Format => 'string[1]',
+        PrintConv => {
+            P => 'Portrait',
+            L => 'Landscape',
+            S => 'Square',
+        },
+    },
+    135 => {
+        Name => 'LanguageIdentifier',
+        Format => 'string[2,3]',
+    },
+    150 => {
+        Name => 'AudioType',
+        Format => 'string[2]',
+        PrintConv => {
+            '1A' => 'Mono Actuality',
+            '2A' => 'Stereo Actuality',
+            '1C' => 'Mono Question and Answer Session',
+            '2C' => 'Stereo Question and Answer Session',
+            '1M' => 'Mono Music',
+            '2M' => 'Stereo Music',
+            '1Q' => 'Mono Response to a Question',
+            '2Q' => 'Stereo Response to a Question',
+            '1R' => 'Mono Raw Sound',
+            '2R' => 'Stereo Raw Sound',
+            '1S' => 'Mono Scener',
+            '2S' => 'Stereo Scener',
+            '0T' => 'Text Only',
+            '1V' => 'Mono Voicer',
+            '2V' => 'Stereo Voicer',
+            '1W' => 'Mono Wrap',
+            '2W' => 'Stereo Wrap',
+        },
+    },
+    151 => {
+        Name => 'AudioSamplingRate',
+        Format => 'digits[6]',
+    },
+    152 => {
+        Name => 'AudioSamplingResolution',
+        Format => 'digits[2]',
+    },
+    153 => {
+        Name => 'AudioDuration',
+        Format => 'digits[6]',
+    },
+    154 => {
+        Name => 'AudioOutcue',
+        Format => 'string[0,64]',
+    },
+    184 => { # (format not certain)
+        Name => 'JobID',
+        Format => 'string[0,64]',
+    },
+    185 => { # (format not certain)
+        Name => 'MasterDocumentID',
+        Format => 'string[0,256]',
+    },
+    186 => { # (format not certain)
+        Name => 'ShortDocumentID',
+        Format => 'string[0,64]',
+    },
+    187 => { # (format not certain)
+        Name => 'UniqueDocumentID',
+        Format => 'string[0,128]',
+    },
+    188 => { # (format not certain)
+        Name => 'OwnerID',
+        Format => 'string[0,128]',
+    },
+    200 => {
+        Name => 'ObjectPreviewFileFormat',
+        Groups => { 2 => 'Image' },
+        Format => 'int16u',
+        PrintConv => \%fileFormat,
+    },
+    201 => {
+        Name => 'ObjectPreviewFileVersion',
+        Groups => { 2 => 'Image' },
+        Format => 'int16u',
+    },
+    202 => {
+        Name => 'ObjectPreviewData',
+        Groups => { 2 => 'Image' },
+        Format => 'string[0,256000]',
+        Binary => 1,
+    },
+    221 => {
+        Name => 'Prefs',
+        Groups => { 2 => 'Image' },
+        Format => 'string[0,64]',
+        Notes => 'PhotoMechanic preferences',
+        PrintConv => q{
+            $val =~ s[\s*(\d+):\s*(\d+):\s*(\d+):\s*(\S*)]
+                     [Tagged:$1, ColorClass:$2, Rating:$3, FrameNum:$4];
+            return $val;
+        },
+        PrintConvInv => q{
+            $val =~ s[Tagged:\s*(\d+).*ColorClass:\s*(\d+).*Rating:\s*(\d+).*FrameNum:\s*(\S*)]
+                     [$1:$2:$3:$4]is;
+            return $val;
+        },
+    },
+    225 => { # (format not certain)
+        Name => 'ClassifyState',
+        Format => 'string[0,64]',
+    },
+    228 => { # (format not certain)
+        Name => 'SimilarityIndex',
+        Format => 'string[0,32]',
+    },
+    230 => { # (format not certain)
+        Name => 'DocumentNotes',
+        Format => 'string[0,1024]',
+    },
+    231 => { # (format not certain)
+        Name => 'DocumentHistory',
+        Format => 'string[0,256]',
+    },
+    232 => { # (format not certain)
+        Name => 'ExifCameraInfo',
+        Format => 'string[0,4096]',
+    },
+);
+
+# Record 3 -- News photo
+%Image::ExifTool::IPTC::NewsPhoto = (
+    GROUPS => { 2 => 'Image' },
+    WRITE_PROC => \&WriteIPTC,
+    CHECK_PROC => \&CheckIPTC,
+    WRITABLE => 1,
+    0 => {
+        Name => 'NewsPhotoVersion',
+        Format => 'int16u',
+    },
+    10 => {
+        Name => 'IPTCPictureNumber',
+        Format => 'string[16]',
+        Notes => '4 numbers: 1-Manufacturer ID, 2-Equipment ID, 3-Date, 4-Sequence',
+        PrintConv => 'Image::ExifTool::IPTC::ConvertPictureNumber($val)',
+        PrintConvInv => 'Image::ExifTool::IPTC::InvConvertPictureNumber($val)',
+    },
+    20 => {
+        Name => 'IPTCImageWidth',
+        Format => 'int16u',
+    },
+    30 => {
+        Name => 'IPTCImageHeight',
+        Format => 'int16u',
+    },
+    40 => {
+        Name => 'IPTCPixelWidth',
+        Format => 'int16u',
+    },
+    50 => {
+        Name => 'IPTCPixelHeight',
+        Format => 'int16u',
+    },
+    55 => {
+        Name => 'SupplementalType',
+        Format => 'int8u',
+        PrintConv => {
+            0 => 'Main Image',
+            1 => 'Reduced Resolution Image',
+            2 => 'Logo',
+            3 => 'Rasterized Caption',
+        },
+    },
+    60 => {
+        Name => 'ColorRepresentation',
+        Format => 'int16u',
+        PrintHex => 1,
+        PrintConv => {
+            0x000 => 'No Image, Single Frame',
+            0x100 => 'Monochrome, Single Frame',
+            0x300 => '3 Components, Single Frame',
+            0x301 => '3 Components, Frame Sequential in Multiple Objects',
+            0x302 => '3 Components, Frame Sequential in One Object',
+            0x303 => '3 Components, Line Sequential',
+            0x304 => '3 Components, Pixel Sequential',
+            0x305 => '3 Components, Special Interleaving',
+            0x400 => '4 Components, Single Frame',
+            0x401 => '4 Components, Frame Sequential in Multiple Objects',
+            0x402 => '4 Components, Frame Sequential in One Object',
+            0x403 => '4 Components, Line Sequential',
+            0x404 => '4 Components, Pixel Sequential',
+            0x405 => '4 Components, Special Interleaving',
+        },
+    },
+    64 => {
+        Name => 'InterchangeColorSpace',
+        Format => 'int8u',
+        PrintConv => {
+            1 => 'X,Y,Z CIE',
+            2 => 'RGB SMPTE',
+            3 => 'Y,U,V (K) (D65)',
+            4 => 'RGB Device Dependent',
+            5 => 'CMY (K) Device Dependent',
+            6 => 'Lab (K) CIE',
+            7 => 'YCbCr',
+            8 => 'sRGB',
+        },
+    },
+    65 => {
+        Name => 'ColorSequence',
+        Format => 'int8u',
+    },
+    66 => {
+        Name => 'ICC_Profile',
+        # ...could add SubDirectory support to read into this (if anybody cares)
+        Writable => 0,
+        Binary => 1,
+    },
+    70 => {
+        Name => 'ColorCalibrationMatrix',
+        Writable => 0,
+        Binary => 1,
+    },
+    80 => {
+        Name => 'LookupTable',
+        Writable => 0,
+        Binary => 1,
+    },
+    84 => {
+        Name => 'NumIndexEntries',
+        Format => 'int16u',
+    },
+    85 => {
+        Name => 'ColorPalette',
+        Writable => 0,
+        Binary => 1,
+    },
+    86 => {
+        Name => 'IPTCBitsPerSample',
+        Format => 'int8u',
+    },
+    90 => {
+        Name => 'SampleStructure',
+        Format => 'int8u',
+        PrintConv => {
+            0 => 'OrthogonalConstangSampling',
+            1 => 'Orthogonal4-2-2Sampling',
+            2 => 'CompressionDependent',
+        },
+    },
+    100 => {
+        Name => 'ScanningDirection',
+        Format => 'int8u',
+        PrintConv => {
+            0 => 'L-R, Top-Bottom',
+            1 => 'R-L, Top-Bottom',
+            2 => 'L-R, Bottom-Top',
+            3 => 'R-L, Bottom-Top',
+            4 => 'Top-Bottom, L-R',
+            5 => 'Bottom-Top, L-R',
+            6 => 'Top-Bottom, R-L',
+            7 => 'Bottom-Top, R-L',
+        },
+    },
+    102 => {
+        Name => 'IPTCImageRotation',
+        Format => 'int8u',
+        PrintConv => {
+            0 => 0,
+            1 => 90,
+            2 => 180,
+            3 => 270,
+        },
+    },
+    110 => {
+        Name => 'DataCompressionMethod',
+        Format => 'int32u',
+    },
+    120 => {
+        Name => 'QuantizationMethod',
+        Format => 'int8u',
+        PrintConv => {
+            0 => 'Linear Reflectance/Transmittance',
+            1 => 'Linear Density',
+            2 => 'IPTC Ref B',
+            3 => 'Linear Dot Percent',
+            4 => 'AP Domestic Analogue',
+            5 => 'Compression Method Specific',
+            6 => 'Color Space Specific',
+            7 => 'Gamma Compensated',
+        },
+    },
+    125 => {
+        Name => 'EndPoints',
+        Writable => 0,
+        Binary => 1,
+    },
+    130 => {
+        Name => 'ExcursionTolerance',
+        Format => 'int8u',
+        PrintConv => {
+            0 => 'Not Allowed',
+            1 => 'Allowed',
+        },
+    },
+    135 => {
+        Name => 'BitsPerComponent',
+        Format => 'int8u',
+    },
+    140 => {
+        Name => 'MaximumDensityRange',
+        Format => 'int16u',
+    },
+    145 => {
+        Name => 'GammaCompensatedValue',
+        Format => 'int16u',
+    },
+);
+
+# Record 7 -- Pre-object Data
+%Image::ExifTool::IPTC::PreObjectData = (
+    # (not actually writable, but used in BuildTagLookup to recognize IPTC tables)
+    WRITE_PROC => \&WriteIPTC,
+    10 => {
+        Name => 'SizeMode',
+        Format => 'int8u',
+        PrintConv => {
+            0 => 'Size Not Known',
+            1 => 'Size Known',
+        },
+    },
+    20 => {
+        Name => 'MaxSubfileSize',
+        Format => 'int32u',
+    },
+    90 => {
+        Name => 'ObjectSizeAnnounced',
+        Format => 'int32u',
+    },
+    95 => {
+        Name => 'MaximumObjectSize',
+        Format => 'int32u',
+    },
+);
+
+# Record 8 -- ObjectData
+%Image::ExifTool::IPTC::ObjectData = (
+    WRITE_PROC => \&WriteIPTC,
+    10 => {
+        Name => 'SubFile',
+        Flags => 'List',
+        Binary => 1,
+    },
+);
+
+# Record 9 -- PostObjectData
+%Image::ExifTool::IPTC::PostObjectData = (
+    WRITE_PROC => \&WriteIPTC,
+    10 => {
+        Name => 'ConfirmedObjectSize',
+        Format => 'int32u',
+    },
+);
+
+
+#------------------------------------------------------------------------------
+# AutoLoad our writer routines when necessary
+#
+sub AUTOLOAD
+{
+    return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
+}
+
+#------------------------------------------------------------------------------
+# Print conversion for CodedCharacterSet
+# Inputs: 0) value
+sub PrintCodedCharset($)
+{
+    my $val = shift;
+    return $iptcCharset{$val} if $iptcCharset{$val};
+    $val =~ s/(.)/ $1/g;
+    $val =~ s/ \x1b/, ESC/g;
+    $val =~ s/^,? //;
+    return $val;
+}
+        
+#------------------------------------------------------------------------------
+# Handle CodedCharacterSet
+# Inputs: 0) ExifTool ref, 1) CodedCharacterSet value
+# Returns: external character set if translation required (or 'bad' if unknown)
+sub HandleCodedCharset($$)
+{
+    my ($exifTool, $val) = @_;
+    my $xlat = $exifTool->Options('Charset');
+    if ($iptcCharset{$val}) {
+        # no need to translate if destination is the same
+        undef $xlat if $xlat eq $iptcCharset{$val};
+    } elsif ($val =~ /^\x1b\x25/) {
+        # some unknown character set involked
+        $xlat = 'bad';  # flag unsupported coding
+    } else {
+        # translate all other codes as Latin
+        undef $xlat if $xlat eq 'Latin';
+    }
+    return $xlat;
+}
+
+#------------------------------------------------------------------------------
+# Encode or decode coded string
+# Inputs: 0) ExifTool ref, 1) value ptr, 2) destination charset ('Latin','UTF8' or 'bad')
+#         3) flag set to decode (read) value from IPTC
+# Updates value on return
+sub TranslateCodedString($$$$)
+{
+    my ($exifTool, $valPtr, $xlatPtr, $read) = @_;
+    my $escaped;
+    if ($$xlatPtr eq 'bad') {
+        $exifTool->Warn('Some IPTC characters not converted (unsupported CodedCharacterSet)');
+        undef $$xlatPtr;
+    } elsif ($$xlatPtr eq 'Latin' xor $read) {
+        # don't yet support reading ISO 2022 shifted character sets
+        if (not $read or $$valPtr !~ /[\x14\x15\x1b]/) {
+            # convert from Latin to UTF-8
+            my $val = Image::ExifTool::Latin2Unicode($$valPtr,'n');
+            $$valPtr = Image::ExifTool::Unicode2UTF8($val,'n');
+        } elsif (not $$exifTool{WarnShift2022}) {
+            $exifTool->Warn('Some IPTC characters not converted (ISO 2022 shifting not supported)');
+            $$exifTool{WarnShift2022} = 1;
+        }
+    } else {
+        # convert from UTF-8 to Latin
+        my $val = Image::ExifTool::UTF82Unicode($$valPtr,'n',$exifTool);
+        $$valPtr = Image::ExifTool::Unicode2Latin($val,'n',$exifTool);
+    }
+}
+
+#------------------------------------------------------------------------------
+# get IPTC info
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+#         2) reference to tag table
+# Returns: 1 on success, 0 otherwise
+sub ProcessIPTC($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $pos = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || 0;
+    my $dirEnd = $pos + $dirLen;
+    my $verbose = $exifTool->Options('Verbose');
+    my $success = 0;
+    my (%listTags, $lastRec, $recordPtr, $recordName);
+
+    # begin by assuming IPTC is Latin (so no translation if Charset is Latin)
+    my $xlat = $exifTool->Options('Charset');
+    undef $xlat if $xlat eq 'Latin';
+    
+    $verbose and $dirInfo and $exifTool->VerboseDir('IPTC', 0, $$dirInfo{DirLen});
+    if ($tagTablePtr eq \%Image::ExifTool::IPTC::Main) {
+        my $dirCount = ($exifTool->{DIR_COUNT}->{IPTC} || 0) + 1;
+        $exifTool->{DIR_COUNT}->{IPTC} = $dirCount;
+        $exifTool->{SET_GROUP1} = '+' . $dirCount if $dirCount > 1;
+    }
+    # quick check for improperly byte-swapped IPTC
+    if ($dirLen >= 4 and substr($$dataPt, $pos, 1) ne "\x1c" and
+                         substr($$dataPt, $pos + 3, 1) eq "\x1c")
+    {
+        $exifTool->Warn('IPTC data was improperly byte-swapped');
+        my $newData = pack('N*', unpack('V*', substr($$dataPt, $pos, $dirLen) . "\0\0\0"));
+        $dataPt = \$newData;
+        $pos = 0;
+        $dirEnd = $pos + $dirLen;
+        # NOTE: MUST NOT access $dirInfo DataPt, DirStart or DataLen after this!
+    }
+    while ($pos + 5 <= $dirEnd) {
+        my $buff = substr($$dataPt, $pos, 5);
+        my ($id, $rec, $tag, $len) = unpack("CCCn", $buff);
+        unless ($id == 0x1c) {
+            unless ($id) {
+                # scan the rest of the data an give warning unless all zeros
+                # (iMatch pads the IPTC block with nulls for some reason)
+                my $remaining = substr($$dataPt, $pos, $dirEnd - $pos);
+                last unless $remaining =~ /[^\0]/;
+            }
+            $exifTool->Warn(sprintf('Bad IPTC data tag (marker 0x%x)',$id));
+            last;
+        }
+        if (not defined $lastRec or $lastRec != $rec) {
+            my $tableInfo = $tagTablePtr->{$rec};
+            unless ($tableInfo) {
+                $exifTool->Warn("Unrecognized IPTC record: $rec");
+                last;   # stop now because we're probably reading garbage
+            }
+            my $tableName = $tableInfo->{SubDirectory}->{TagTable};
+            unless ($tableName) {
+                $exifTool->Warn("No table for IPTC record $rec!");
+                last;   # this shouldn't happen
+            }
+            $recordName = $$tableInfo{Name};
+            $recordPtr = Image::ExifTool::GetTagTable($tableName);
+            $exifTool->VPrint(0,$$exifTool{INDENT},"-- $recordName record --\n");
+            $lastRec = $rec;
+        }
+        $pos += 5;      # step to after field header
+        # handle extended IPTC entry if necessary
+        if ($len & 0x8000) {
+            my $n = $len & 0x7fff; # get num bytes in length field
+            if ($pos + $n > $dirEnd or $n > 8) {
+                $exifTool->VPrint(0, "Invalid extended IPTC entry (tag $tag)\n");
+                $success = 0;
+                last;
+            }
+            # determine length (a big-endian, variable sized int)
+            for ($len = 0; $n; ++$pos, --$n) {
+                $len = $len * 256 + ord(substr($$dataPt, $pos, 1));
+            }
+        }
+        if ($pos + $len > $dirEnd) {
+            $exifTool->VPrint(0, "Invalid IPTC entry (tag $tag, len $len)\n");
+            $success = 0;
+            last;
+        }
+        my $val = substr($$dataPt, $pos, $len);
+
+        # add tagInfo for all unknown tags:
+        unless ($$recordPtr{$tag}) {
+            # - no Format so format is auto-detected
+            # - no Name so name is generated automatically with decimal tag number
+            Image::ExifTool::AddTagToTable($recordPtr, $tag, { Unknown => 1 });
+        }
+
+        my $tagInfo = $exifTool->GetTagInfo($recordPtr, $tag);
+        my $format;
+        $format = $$tagInfo{Format} if $tagInfo;
+        # use logic to determine format if not specified
+        unless ($format) {
+            $format = 'int' if $len <= 4 and $len != 3 and $val =~ /[\0-\x08]/;
+        }
+        if ($format) {
+            if ($format =~ /^int/) {
+                if ($len <= 8) {    # limit integer conversion to 8 bytes long
+                    $val = 0;
+                    my $i;
+                    for ($i=0; $i<$len; ++$i) {
+                        $val = $val * 256 + ord(substr($$dataPt, $pos+$i, 1));
+                    }
+                }
+            } elsif ($format =~ /^string/) {
+                if ($rec == 1) {
+                    # handle CodedCharacterSet tag
+                    $xlat = HandleCodedCharset($exifTool, $val) if $tag == 90;
+                # translate characters if necessary and special characters exist
+                } elsif ($xlat and $rec < 7 and $val =~ /[\x80-\xff]/) {
+                    # translate to specified character set
+                    TranslateCodedString($exifTool, \$val, \$xlat, 1);
+                }
+            } elsif ($format !~ /^digits/) {
+                warn("Invalid IPTC format: $format");
+            }
+        }
+        $verbose and $exifTool->VerboseInfo($tag, $tagInfo,
+            Table   => $tagTablePtr,
+            Value   => $val,
+            DataPt  => $dataPt,
+            DataPos => $$dirInfo{DataPos},
+            Size    => $len,
+            Start   => $pos,
+            Extra   => ", $recordName record",
+        );
+        # prevent adding tags to list from another IPTC directory
+        if ($tagInfo) {
+            if ($$tagInfo{List}) {
+                $exifTool->{NO_LIST} = 1 unless $listTags{$tagInfo};
+                $listTags{$tagInfo} = 1;    # list the next one we see
+            }
+            $exifTool->FoundTag($tagInfo, $val);
+        }
+        delete $exifTool->{NO_LIST};
+        $success = 1;
+
+        $pos += $len;   # increment to next field
+    }
+    delete $exifTool->{SET_GROUP1};
+    return $success;
+}
+
+1; # end
+
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::IPTC - Read IPTC meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+IPTC (International Press Telecommunications Council) meta information in
+image files.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.iptc.org/IIM/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/IPTC Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/JPEG.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/JPEG.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/JPEG.pm	(revision 20131)
@@ -0,0 +1,327 @@
+#------------------------------------------------------------------------------
+# File:         JPEG.pm
+#
+# Description:  Definitions for uncommon JPEG segments
+#
+# Revisions:    10/06/2006 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::JPEG;
+use strict;
+use vars qw($VERSION);
+
+$VERSION = '1.07';
+
+# (this main JPEG table is for documentation purposes only)
+%Image::ExifTool::JPEG::Main = (
+    NOTES => 'This table lists information extracted by ExifTool from JPEG images.',
+    APP0 => [{
+        Name => 'JFIF',
+        Condition => '$$valPt =~ /^JFIF\0/',
+        SubDirectory => { TagTable => 'Image::ExifTool::JFIF::Main' },
+      }, {
+        Name => 'JFXX',
+        Condition => '$$valPt =~ /^JFXX\0\x10/',
+        SubDirectory => { TagTable => 'Image::ExifTool::JFIF::Extension' },
+      }, {
+        Name => 'CIFF',
+        Condition => '$$valPt =~ /^(II|MM).{4}HEAPJPGM/s',
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonRaw::Main' },
+    }],
+    APP1 => [{
+        Name => 'EXIF',
+        Condition => '$$valPt =~ /^Exif\0/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Exif::Main' },
+      }, {
+        Name => 'XMP',
+        Condition => '$$valPt =~ /^http/ or $$valPt =~ /<exif:/',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
+    }],
+    APP2 => [{
+        Name => 'ICC_Profile',
+        Condition => '$$valPt =~ /^ICC_PROFILE\0/',
+        SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' },
+      }, {
+        Name => 'FPXR',
+        Condition => '$$valPt =~ /^FPXR\0/',
+        SubDirectory => { TagTable => 'Image::ExifTool::FlashPix::Main' },
+    }],
+    APP3 => {
+        Name => 'Meta',
+        Condition => '$$valPt =~ /^(Meta|META|Exif)\0\0/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Kodak::Meta' },
+    },
+    APP5 => {
+        Name => 'RMETA',
+        Condition => '$$valPt =~ /^RMETA\0/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Ricoh::RMETA' },
+    },
+    APP6 => {
+        Name => 'EPPIM',
+        Condition => '$$valPt =~ /^EPPIM\0/',
+        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::EPPIM' },
+    },
+    APP8 => {
+        Name => 'SPIFF',
+        Condition => '$$valPt =~ /^SPIFF\0/',
+        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::SPIFF' },
+    },
+    APP10 => {
+        Name => 'Comment',
+        Condition => '$$valPt =~ /^UNICODE\0/',
+        Notes => 'PhotoStudio Unicode comment',
+    },
+    APP12 => [{
+        Name => 'PictureInfo',
+        Condition => '$$valPt =~ /(\[picture info\]|Type=)/',
+        SubDirectory => { TagTable => 'Image::ExifTool::APP12::PictureInfo' },
+      }, {
+        Name => 'Ducky',
+        Condition => '$$valPt =~ /^Ducky/',
+        SubDirectory => { TagTable => 'Image::ExifTool::APP12::Ducky' },
+    }],
+    APP13 => [{
+        Name => 'Photoshop',
+        Condition => '$$valPt =~ /^(Photoshop 3.0\0|Adobe_Photoshop2.5)/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::Main' },
+    }, {
+        Name => 'Adobe_CM',
+        Condition => '$$valPt =~ /^Adobe_CM/',
+        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::AdobeCM' },
+    }],
+    APP14 => {
+        Name => 'Adobe',
+        Condition => '$$valPt =~ /^Adobe/',
+        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::Adobe' },
+    },
+    APP15 => {
+        Name => 'GraphicConverter',
+        Condition => '$$valPt =~ /^Q\s*(\d+)/',
+        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::GraphConv' },
+    },
+    COM => {
+        Name => 'Comment',
+        # note: flag as writable for documentation, but it won't show up
+        # in the TagLookup as writable because there is no WRITE_PROC
+        Writable => '1',
+    },
+    SOF => {
+        Name => 'StartOfFrame',
+        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::SOF' },
+    },
+    Trailer => [{
+        Name => 'AFCP',
+        Condition => '$$valPt =~ /AXS(!|\*).{8}$/s',
+        SubDirectory => { TagTable => 'Image::ExifTool::AFCP::Main' },
+      }, {
+        Name => 'CanonVRD',
+        Condition => '$$valPt =~ /CANON OPTIONAL DATA\0.{44}$/s',
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::Main' },
+      }, {
+        Name => 'FotoStation',
+        Condition => '$$valPt =~ /\xa1\xb2\xc3\xd4$/',
+        SubDirectory => { TagTable => 'Image::ExifTool::FotoStation::Main' },
+      }, {
+        Name => 'PhotoMechanic',
+        Condition => '$$valPt =~ /cbipcbbl$/',
+        SubDirectory => { TagTable => 'Image::ExifTool::PhotoMechanic::Main' },
+      }, {
+        Name => 'MIE',
+        Condition => q{
+            $$valPt =~ /~\0\x04\0zmie~\0\0\x06.{4}[\x10\x18]\x04$/s or
+            $$valPt =~ /~\0\x04\0zmie~\0\0\x0a.{8}[\x10\x18]\x08$/s
+        },
+        SubDirectory => { TagTable => 'Image::ExifTool::MIE::Main' },
+      }, {
+        Name => 'PreviewImage',
+        Condition => '$$valPt =~ /^\xff\xd8\xff/',
+        Writable => 1,  # (for docs only)
+    }],
+);
+
+# EPPIM APP6 (Toshiba PrintIM) segment (ref PH, from PDR-M700 samples)
+%Image::ExifTool::JPEG::EPPIM = (
+    GROUPS => { 0 => 'APP6', 1 => 'EPPIM', 2 => 'Image' },
+    NOTES => q{
+        APP6 is used in by the Toshiba PDR-M700 to store a TIFF structure containing
+        PrintIM information.
+    },
+    0xc4a5 => {
+        Name => 'PrintIM',
+        # must set Writable here so this tag will be saved with MakerNotes option
+        Writable => 'undef',
+        Description => 'Print Image Matching',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+);
+
+# SPIFF APP8 segment.  Refs:
+# 1) http://www.fileformat.info/format/spiff/
+# 2) http://www.jpeg.org/public/spiff.pdf
+%Image::ExifTool::JPEG::SPIFF = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'APP8', 1 => 'SPIFF', 2 => 'Image' },
+    NOTES => q{
+        This information is found in APP8 of SPIFF-style JPEG images (the "official"
+        yet rarely used JPEG file format standard: Still Picture Interchange File
+        Format).
+    },
+    0 => {
+        Name => 'SPIFFVersion',
+        Format => 'int8u[2]',
+        PrintConv => '$val =~ tr/ /./; $val',
+    },
+    2 => {
+        Name => 'ProfileID',
+        PrintConv => {
+            0 => 'Not Specified',
+            1 => 'Continuous-tone Base',
+            2 => 'Continuous-tone Progressive',
+            3 => 'Bi-level Facsimile',
+            4 => 'Continuous-tone Facsimile',
+        },
+    },
+    3 => 'ColorComponents',
+    6 => {
+        Name => 'ImageHeight',
+        Notes => q{
+            at index 4 in specification, but there are 2 extra bytes here in my only
+            SPIFF sample, version 1.2
+        },
+        Format => 'int32u',
+    },
+    10 => {
+        Name => 'ImageWidth',
+        Format => 'int32u',
+    },
+    14 => {
+        Name => 'ColorSpace',
+        PrintConv => {
+            0 => 'Bi-level',
+            1 => 'YCbCr, ITU-R BT 709, video',
+            2 => 'No color space specified',
+            3 => 'YCbCr, ITU-R BT 601-1, RGB',
+            4 => 'YCbCr, ITU-R BT 601-1, video',
+            8 => 'Gray-scale',
+            9 => 'PhotoYCC',
+            10 => 'RGB',
+            11 => 'CMY',
+            12 => 'CMYK',
+            13 => 'YCCK',
+            14 => 'CIELab',
+        },
+    },
+    15 => 'BitsPerSample',
+    16 => {
+        Name => 'Compression',
+        PrintConv => {
+            0 => 'Uncompressed, interleaved, 8 bits per sample',
+            1 => 'Modified Huffman',
+            2 => 'Modified READ',
+            3 => 'Modified Modified READ',
+            4 => 'JBIG',
+            5 => 'JPEG',
+        },
+    },
+    17 => {
+        Name => 'ResolutionUnit',
+        PrintConv => {
+            0 => 'None',
+            1 => 'inches',
+            2 => 'cm',
+        },
+    },
+    18 => {
+        Name => 'YResolution',
+        Format => 'int32u',
+    },
+    22 => {
+        Name => 'XResolution',
+        Format => 'int32u',
+    },
+);
+
+# AdobeCM APP13 (no references)
+%Image::ExifTool::JPEG::AdobeCM = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'APP13', 1 => 'AdobeCM', 2 => 'Image' },
+    NOTES => q{
+        The "Adobe_CM" APP13 segment presumably contains color management
+        information, but the meaning of the data is currently unknown.  If anyone
+        has an idea about what this means, please let me know.
+    },
+    FORMAT => 'int16u',
+    0 => 'AdobeCMType',
+);
+
+# Adobe APP14 refs:
+# http://partners.adobe.com/public/developer/en/ps/sdk/5116.DCT_Filter.pdf
+# http://java.sun.com/j2se/1.5.0/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html#color
+%Image::ExifTool::JPEG::Adobe = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'APP14', 1 => 'Adobe', 2 => 'Image' },
+    NOTES => 'The "Adobe" APP14 segment stores image encoding information for DCT filters.',
+    FORMAT => 'int16u',
+    0 => 'DCTEncodeVersion',
+    1 => {
+        Name => 'APP14Flags0',
+        PrintConv => { BITMASK => {
+            15 => 'Encoded with Blend=1 downsampling'
+        } },
+    },
+    2 => {
+        Name => 'APP14Flags1',
+        PrintConv => { BITMASK => { } },
+    },
+    3 => {
+        Name => 'ColorTransform',
+        Format => 'int8u',
+        PrintConv => {
+            0 => 'Unknown (RGB or CMYK)',
+            1 => 'YCbCr',
+            2 => 'YCCK',
+        },
+    },
+);
+
+# GraphicConverter APP15 (ref PH)
+%Image::ExifTool::JPEG::GraphConv = (
+    GROUPS => { 0 => 'APP15', 1 => 'GraphConv', 2 => 'Image' },
+    NOTES => 'APP15 is used by GraphicConverter to store JPEG quality.',
+    'Q' => 'Quality',
+);
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::JPEG - Definitions for uncommon JPEG segments
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool for some
+uncommon JPEG segments.  For speed reasons, definitions for more common JPEG
+segments are included in the Image::ExifTool module itself.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/JPEG Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/JVC.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/JVC.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/JVC.pm	(revision 20131)
@@ -0,0 +1,126 @@
+#------------------------------------------------------------------------------
+# File:         JVC.pm
+#
+# Description:  JVC EXIF maker notes tags
+#
+# Revisions:    12/21/2005  - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::JVC;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.01';
+
+sub ProcessJVCText($$$);
+
+# JVC EXIF-based maker notes
+%Image::ExifTool::JVC::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'JVC EXIF maker note tags.',
+    #0x0001 - almost always '2', but '3' for GR-DV700 samples
+    0x0002 => 'CPUVersions', #PH
+    0x0003 => { #PH
+        Name => 'Quality',
+        PrintConv => {
+            0 => 'Low',
+            1 => 'Normal',
+            2 => 'Fine',
+        },
+    },
+);
+
+# JVC text-based maker notes
+%Image::ExifTool::JVC::Text = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessJVCText,
+    NOTES => 'JVC/Victor text-based maker note tags.',
+    VER => 'MakerNoteVersion', #PH
+    QTY => { #PH
+        Name => 'Quality',
+        PrintConv => {
+            STND => 'Normal',
+            STD  => 'Normal',
+            FINE => 'Fine',
+        },
+    },
+);
+
+#------------------------------------------------------------------------------
+# Process JVC text-based maker notes
+# Inputs: 0) ExifTool object reference
+#         1) Reference to directory information hash
+#         2) Pointer to tag table for this directory
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+sub ProcessJVCText($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dataLen = $$dirInfo{DataLen};
+    my $dirLen = $$dirInfo{DirLen} || $dataLen - $dirStart;
+    my $verbose = $exifTool->Options('Verbose');
+
+    my $data = substr($$dataPt, $dirStart, $dirLen);
+    # validate text maker notes
+    unless ($data =~ /^VER:/) {
+        $exifTool->Warn('Bad JVC text maker notes');
+        return 0;
+    }
+    my $pos = 0;
+    while ($data =~ m/([A-Z]+):(.{3,4})/sg) {
+        my ($tag, $val) = ($1, $2);
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        $exifTool->VerboseInfo($tag, $tagInfo,
+            Table  => $tagTablePtr,
+            Value  => $val,
+        ) if $verbose;
+        unless ($tagInfo) {
+            next unless $exifTool->{OPTIONS}->{Unknown};
+            $tagInfo = {
+                Name => "JVC_Text_$tag",
+                Unknown => 1,
+                PrintConv => 'length($val) > 60 ? substr($val,0,55) . "[...]" : $val',
+            };
+            # add tag information to table
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        $exifTool->FoundTag($tagInfo, $val);
+    }
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::JVC - JVC EXIF maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains routines used by Image::ExifTool to interpret JVC maker
+notes.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/JVC Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Jpeg2000.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Jpeg2000.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Jpeg2000.pm	(revision 20131)
@@ -0,0 +1,624 @@
+#------------------------------------------------------------------------------
+# File:         Jpeg2000.pm
+#
+# Description:  Read JPEG 2000 meta information
+#
+# Revisions:    02/11/2005 - P. Harvey Created
+#               06/22/2007 - PH Added write support (EXIF, IPTC and XMP only)
+#
+# References:   1) http://www.jpeg.org/public/fcd15444-2.pdf
+#               2) ftp://ftp.remotesensing.org/jpeg2000/fcd15444-1.pdf
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Jpeg2000;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.12';
+
+sub ProcessJpeg2000Box($$$);
+
+my %resolutionUnit = (
+    -3 => 'km',
+    -2 => '100 m',
+    -1 => '10 m',
+     0 => 'm',
+     1 => '10 cm',
+     2 => 'cm',
+     3 => 'mm',
+     4 => '0.1 mm',
+     5 => '0.01 mm',
+     6 => 'um',
+);
+
+# map of where information is written in JPEG2000 image
+my %jp2Map = (
+    IPTC         => 'UUID-IPTC',
+    IFD0         => 'UUID-EXIF',
+    XMP          => 'UUID-XMP',
+  # jp2h         => 'JP2',  (not yet functional)
+  # ICC_Profile  => 'jp2h', (not yet functional)
+    IFD1         => 'IFD0',
+    EXIF         => 'IFD0', # to write EXIF as a block
+    ExifIFD      => 'IFD0',
+    GPS          => 'IFD0',
+    SubIFD       => 'IFD0',
+    GlobParamIFD => 'IFD0',
+    PrintIM      => 'IFD0',
+    InteropIFD   => 'ExifIFD',
+    MakerNotes   => 'ExifIFD',
+);
+
+# UUID's for writable UUID directories (by tag name)
+my %uuid = (
+    'UUID-EXIF'   => 'JpgTiffExif->JP2',
+    'UUID-IPTC'   => "\x33\xc7\xa4\xd2\xb8\x1d\x47\x23\xa0\xba\xf1\xa3\xe0\x97\xad\x38",
+    'UUID-XMP'    => "\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac",
+  # (can't yet write GeoJP2 information)
+  # 'UUID-GeoJP2' => "\xb1\x4b\xf8\xbd\x08\x3d\x4b\x43\xa5\xae\x8c\xd7\xd5\xa6\xce\x03",
+);
+
+# JPEG 2000 "box" (ie. segment) names
+%Image::ExifTool::Jpeg2000::Main = (
+    GROUPS => { 2 => 'Image' },
+    PROCESS_PROC => \&ProcessJpeg2000Box,
+    WRITE_PROC => \&ProcessJpeg2000Box,
+    NOTES => q{
+        The tags below are extracted from JPEG 2000 images, however ExifTool
+        currently writes only EXIF, IPTC and XMP tags in these images.
+    },
+   'jP  ' => 'JP2Signature', # (ref 1)
+   "jP\x1a\x1a" => 'JP2Signature', # (ref 2)
+    prfl => 'Profile',
+    ftyp => { Name => 'FileType', Priority => 0 },
+    rreq => 'ReaderRequirements',
+    jp2h => {
+        Name => 'JP2Header',
+        SubDirectory => { },
+    },
+        # JP2Header sub boxes...
+        ihdr => {
+            Name => 'ImageHeader',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Jpeg2000::ImageHeader',
+            },
+        },
+        bpcc => 'BitsPerComponent',
+        colr => [
+            {
+                Name => 'ICC_Profile',
+                Condition => '$$valPt =~ /^(\x02|\x03)/',
+                SubDirectory => {
+                    TagTable => 'Image::ExifTool::ICC_Profile::Main',
+                    Start => '$valuePtr + 3',
+                },
+            },
+            {
+                Name => 'Colorspace',
+                Condition => '$$valPt =~ /^\x01/',
+                Format => 'binary',
+                ValueConv => 'unpack("x3N", $val)',
+                PrintConv => {
+                    16 => 'sRGB',
+                    17 => 'Grayscale',
+                    18 => 'sYCC',
+                },
+            },
+            {
+                Name => 'ColorSpecification',
+                Binary => 1,
+            },
+        ],
+        pclr => 'Palette',
+        cdef => 'ComponentDefinition',
+       'res '=> {
+            Name => 'Resolution',
+            SubDirectory => { },
+        },
+            # Resolution sub boxes...
+            resc => {
+                Name => 'CaptureResolution',
+                SubDirectory => {
+                    TagTable => 'Image::ExifTool::Jpeg2000::CaptureResolution',
+                },
+            },
+            resd => {
+                Name => 'DisplayResolution',
+                SubDirectory => {
+                    TagTable => 'Image::ExifTool::Jpeg2000::DisplayResolution',
+                },
+            },
+    jpch => {
+        Name => 'CodestreamHeader',
+        SubDirectory => { },
+    },
+        # CodestreamHeader sub boxes...
+       'lbl '=> {
+            Name => 'Label',
+            Format => 'string',
+        },
+        cmap => 'ComponentMapping',
+        roid => 'ROIDescription',
+    jplh => {
+        Name => 'CompositingLayerHeader',
+        SubDirectory => { },
+    },
+        # CompositingLayerHeader sub boxes...
+        cgrp => 'ColorGroup',
+        opct => 'Opacity',
+        creg => 'CodestreamRegistration',
+    dtbl => 'DataReference',
+    ftbl => {
+        Name => 'FragmentTable',
+        Subdirectory => { },
+    },
+        # FragmentTable sub boxes...
+        flst => 'FragmentList',
+    cref => 'Cross-Reference',
+    mdat => 'MediaData',
+    comp => 'Composition',
+    copt => 'CompositionOptions',
+    inst => 'InstructionSet',
+    asoc => 'Association',
+    nlst => 'NumberList',
+    bfil => 'BinaryFilter',
+    drep => 'DesiredReproductions',
+        # DesiredReproductions sub boxes...
+        gtso => 'GraphicsTechnologyStandardOutput',
+    chck => 'DigitalSignature',
+    mp7b => 'MPEG7Binary',
+    free => 'Free',
+    jp2c => 'ContiguousCodestream',
+    jp2i => {
+        Name => 'IntellectualProperty',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::XMP::Main',
+        },
+    },
+   'xml '=> {
+        Name => 'XML',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::XMP::Main',
+        },
+    },
+    uuid => [
+        {
+            Name => 'UUID-EXIF',
+            Condition => '$$valPt=~/^JpgTiffExif->JP2/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Exif::Main',
+                ProcessProc => \&Image::ExifTool::ProcessTIFF,
+                WriteProc => \&Image::ExifTool::WriteTIFF,
+                Start => '$valuePtr + 16',
+            },
+        },
+        {
+            Name => 'UUID-IPTC',
+            Condition => '$$valPt=~/^\x33\xc7\xa4\xd2\xb8\x1d\x47\x23\xa0\xba\xf1\xa3\xe0\x97\xad\x38/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::IPTC::Main',
+                Start => '$valuePtr + 16',
+            },
+        },
+        {
+            Name => 'UUID-XMP',
+            # ref http://www.adobe.com/products/xmp/pdfs/xmpspec.pdf
+            Condition => '$$valPt=~/^\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::XMP::Main',
+                Start => '$valuePtr + 16',
+            },
+        },
+        {
+            Name => 'UUID-GeoJP2',
+            # ref http://www.remotesensing.org/jpeg2000/
+            Condition => '$$valPt=~/^\xb1\x4b\xf8\xbd\x08\x3d\x4b\x43\xa5\xae\x8c\xd7\xd5\xa6\xce\x03/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Exif::Main',
+                ProcessProc => \&Image::ExifTool::ProcessTIFF,
+                Start => '$valuePtr + 16',
+            },
+        },
+        {
+            Name => 'UUID-Unknown',
+        },
+    ],
+    uinf => {
+        Name => 'UUIDInfo',
+        SubDirectory => { },
+    },
+        # UUIDInfo sub boxes...
+        ulst => 'UUIDList',
+       'url '=> {
+            Name => 'URL',
+            Format => 'string',
+        },
+);
+
+%Image::ExifTool::Jpeg2000::ImageHeader = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'ImageHeight',
+        Format => 'int32u',
+    },
+    4 => {
+        Name => 'ImageWidth',
+        Format => 'int32u',
+    },
+    8 => {
+        Name => 'NumberOfComponents',
+        Format => 'int16u',
+    },
+    10 => {
+        Name => 'BitsPerComponent',
+        PrintConv => q{
+            $val == 0xff and return 'Variable';
+            my $sign = ($val & 0x80) ? 'Signed' : 'Unsigned';
+            return (($val & 0x7f) + 1) . " Bits, $sign";
+        },
+    },
+    11 => {
+        Name => 'Compression',
+        PrintConv => {
+            0 => 'Uncompressed',
+            1 => 'Modified Huffman',
+            2 => 'Modified READ',
+            3 => 'Modified Modified READ',
+            4 => 'JBIG',
+            5 => 'JPEG',
+            6 => 'JPEG-LS',
+            7 => 'JPEG 2000',
+            8 => 'JBIG2',
+        },
+    },
+);
+
+%Image::ExifTool::Jpeg2000::CaptureResolution = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    FORMAT => 'int8s',
+    0 => {
+        Name => 'CaptureYResolution',
+        Format => 'rational32u',
+    },
+    4 => {
+        Name => 'CaptureXResolution',
+        Format => 'rational32u',
+    },
+    8 => {
+        Name => 'CaptureYResolutionUnit',
+        SeparateTable => 'ResolutionUnit',
+        PrintConv => \%resolutionUnit,
+    },
+    9 => {
+        Name => 'CaptureXResolutionUnit',
+        SeparateTable => 'ResolutionUnit',
+        PrintConv => \%resolutionUnit,
+    },
+);
+
+%Image::ExifTool::Jpeg2000::DisplayResolution = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    FORMAT => 'int8s',
+    0 => {
+        Name => 'DisplayYResolution',
+        Format => 'rational32u',
+    },
+    4 => {
+        Name => 'DisplayXResolution',
+        Format => 'rational32u',
+    },
+    8 => {
+        Name => 'DisplayYResolutionUnit',
+        SeparateTable => 'ResolutionUnit',
+        PrintConv => \%resolutionUnit,
+    },
+    9 => {
+        Name => 'DisplayXResolutionUnit',
+        SeparateTable => 'ResolutionUnit',
+        PrintConv => \%resolutionUnit,
+    },
+);
+
+#------------------------------------------------------------------------------
+# Create new JPEG 2000 boxes when writing
+# (Currently only supports adding certain UUID boxes)
+# Inputs: 0) ExifTool object ref, 1) Output file or scalar ref
+# Returns: 1 on success
+sub CreateNewBoxes($$)
+{
+    my ($exifTool, $outfile) = @_;
+    my $addDirs = $$exifTool{AddJp2Dirs};
+    delete $$exifTool{AddJp2Dirs};
+    my $dirName;
+    foreach $dirName (sort keys %$addDirs) {
+        next unless $uuid{$dirName};
+        my $tagInfo;
+        foreach $tagInfo (@{$Image::ExifTool::Jpeg2000::Main{uuid}}) {
+            next unless $$tagInfo{Name} eq $dirName;
+            my $subdir = $$tagInfo{SubDirectory};
+            my $tagTable = GetTagTable($$subdir{TagTable});
+            my %dirInfo = (
+                DirName => $dirName,
+                Parent => 'JP2',
+            );
+            my $newdir = $exifTool->WriteDirectory(\%dirInfo, $tagTable, $$subdir{WriteProc});
+            if (defined $newdir and length $newdir) {
+                my $boxhdr = pack('N', length($newdir) + 24) . 'uuid' . $uuid{$dirName};
+                Write($outfile, $boxhdr, $newdir) or return 0;
+                last;
+            }
+        }
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process JPEG 2000 box
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) Pointer to tag table
+# Returns: 1 on success when reading, or -1 on write error
+#          (or JP2 box or undef when writing from buffer)
+sub ProcessJpeg2000Box($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataLen = $$dirInfo{DataLen};
+    my $dataPos = $$dirInfo{DataPos};
+    my $dirLen = $$dirInfo{DirLen} || 0;
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $raf = $$dirInfo{RAF};
+    my $outfile = $$dirInfo{OutFile};
+    my $dirEnd = $dirStart + $dirLen;
+    my ($err, $outBuff, $verbose);
+
+    if ($outfile) {
+        unless ($raf) {
+            # buffer output to be used for return value
+            $outBuff = '';
+            $outfile = \$outBuff;
+        }
+    } else {
+        # (must not set verbose flag when writing!)
+        $verbose = $exifTool->{OPTIONS}->{Verbose};
+    }
+    # loop through all contained boxes
+    my ($pos, $boxLen);
+    for ($pos=$dirStart; ; $pos+=$boxLen) {
+        my ($boxID, $buff, $valuePtr);
+        if ($raf) {
+            $dataPos = $raf->Tell();
+            my $n = $raf->Read($buff,8);
+            unless ($n == 8) {
+                $n and $err = '', last;
+                if ($outfile) {
+                    CreateNewBoxes($exifTool, $outfile) or $err = 1;
+                }
+                last;
+            }
+            $dataPt = \$buff;
+            $dirLen = 8;
+            $pos = 0;
+        } elsif ($pos >= $dirEnd - 8) {
+            $err = '' unless $pos == $dirEnd;
+            last;
+        }
+        $boxLen = unpack("x$pos N",$$dataPt);
+        $boxID = substr($$dataPt, $pos+4, 4);
+        $pos += 8;
+        if ($boxLen == 1) {
+            if (not $raf and $pos < $dirLen - 8) {
+                $err = 'JPEG 2000 format error';
+            } else {
+                $err = "Can't currently handle huge JPEG 2000 boxes";
+            }
+            last;
+        } elsif ($boxLen == 0) {
+            if ($raf) {
+                if ($outfile) {
+                    CreateNewBoxes($exifTool, $outfile) or $err = 1;
+                    # copy over the rest of the file
+                    Write($outfile, $$dataPt) or $err = 1;
+                    while ($raf->Read($buff, 65536)) {
+                        Write($outfile, $buff) or $err = 1;
+                    }
+                }
+                last;   # (ignore the rest of the file when reading)
+            }
+            $boxLen = $dirLen - $pos;
+        } else {
+            $boxLen -= 8;
+        }
+        $boxLen < 0 and $err = 'Invalid JPEG 2000 box length', last;
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $boxID);
+        unless (defined $tagInfo or $verbose) {
+            # no need to process this box
+            if ($raf) {
+                if ($outfile) {
+                    Write($outfile, $$dataPt) or $err = 1;
+                    $raf->Read($buff,$boxLen) == $boxLen or $err = '', last;
+                    Write($outfile, $buff) or $err = 1;
+                } else {
+                    $raf->Seek($boxLen, 1) or $err = 'Seek error', last;
+                }
+            } elsif ($outfile) {
+                Write($outfile, substr($$dataPt, $pos-8, $boxLen+8)) or $err = '', last;
+            }
+            next;
+        }
+        if ($raf) {
+            # read the box data
+            $dataPos = $raf->Tell();
+            $raf->Read($buff,$boxLen) == $boxLen or $err = '', last;
+            $valuePtr = 0;
+            $dataLen = $boxLen;
+        } elsif ($boxLen + $pos > $dirStart + $dirLen) {
+            $err = '';
+            last;
+        } else {
+            $valuePtr = $pos;
+        }
+        if (defined $tagInfo and not $tagInfo) {
+            # GetTagInfo() required the value for a Condition
+            my $tmpVal = substr($$dataPt, $valuePtr, $boxLen < 48 ? $boxLen : 48);
+            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $boxID, \$tmpVal);
+        }
+        # delete all UUID boxes if deleting all information
+        if ($outfile and $boxID eq 'uuid' and $exifTool->{DEL_GROUP}->{'*'}) {
+            $exifTool->VPrint(0, "  Deleting $$tagInfo{Name}\n");
+            ++$exifTool->{CHANGED};
+            next;
+        }
+        if ($verbose) {
+            $exifTool->VerboseInfo($boxID, $tagInfo,
+                Table  => $tagTablePtr,
+                DataPt => $dataPt,
+                Size   => $boxLen,
+                Start  => $valuePtr,
+            );
+            next unless $tagInfo;
+        }
+        if ($$tagInfo{SubDirectory}) {
+            my $subdir = $$tagInfo{SubDirectory};
+            my $subdirStart = $valuePtr;
+            if (defined $$subdir{Start}) {
+                #### eval Start ($valuePtr)
+                $subdirStart = eval($$subdir{Start});
+            }
+            my $subdirLen = $boxLen - ($subdirStart - $valuePtr);
+            my %subdirInfo = (
+                Parent => 'JP2',
+                DataPt => $dataPt,
+                DataPos => $dataPos,
+                DataLen => $dataLen,
+                DirStart => $subdirStart,
+                DirLen => $subdirLen,
+                DirName => $$tagInfo{Name},
+                OutFile => $outfile,
+                Base => $dataPos + $subdirStart,
+            );
+            my $subTable = GetTagTable($$subdir{TagTable}) || $tagTablePtr;
+            if ($outfile) {
+                # remove this directory from our create list
+                delete $exifTool->{AddJp2Dirs}->{$$tagInfo{Name}};
+                my $newdir;
+                # only edit writable UUID boxes
+                if ($uuid{$$tagInfo{Name}}) {
+                    $newdir = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
+                    next if defined $newdir and not length $newdir; # next if deleting the box
+                }
+                # use old box data if not changed
+                defined $newdir or $newdir = substr($$dataPt, $subdirStart, $subdirLen);
+                my $prefixLen = $subdirStart - $valuePtr;
+                my $boxhdr = pack('N', length($newdir) + 8 + $prefixLen) . $boxID;
+                $boxhdr .= substr($$dataPt, $valuePtr, $prefixLen) if $prefixLen;
+                Write($outfile, $boxhdr, $newdir) or $err = 1;
+            } elsif (not $exifTool->ProcessDirectory(\%subdirInfo, $subTable, $$subdir{ProcessProc})) {
+                if ($subTable eq $tagTablePtr) {
+                    $err = 'JPEG 2000 format error';
+                } else {
+                    $err = "Unrecognized $$tagInfo{Name} box";
+                }
+                last;
+            }
+        } elsif ($$tagInfo{Format} and not $outfile) {
+            # only save tag values if Format was specified
+            my $val = ReadValue($dataPt, $valuePtr, $$tagInfo{Format}, undef, $boxLen);
+            $exifTool->FoundTag($tagInfo, $val) if defined $val;
+        } elsif ($outfile) {
+            my $boxhdr = pack('N', $boxLen + 8) . $boxID;
+            Write($outfile, $boxhdr, substr($$dataPt, $valuePtr, $boxLen)) or $err = 1;
+        }
+    }
+    if (defined $err) {
+        $err or $err = 'Truncated JPEG 2000 box';
+        if ($outfile) {
+            $exifTool->Error($err) unless $err eq '1';
+            return $raf ? -1 : undef;
+        }
+        $exifTool->Warn($err);
+    }
+    return $outBuff if $outfile and not $raf;
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Read/write meta information from a JPEG 2000 image
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid JPEG 2000 file, or -1 on write error
+sub ProcessJP2($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $outfile = $$dirInfo{OutFile};
+    my $rtnVal = 0;
+    my $hdr;
+
+    # check to be sure this is a valid JPG2000 file
+    return 0 unless $raf->Read($hdr,12) == 12;
+    return 0 unless $hdr eq "\x00\x00\x00\x0cjP  \x0d\x0a\x87\x0a" or     # (ref 1)
+                    $hdr eq "\x00\x00\x00\x0cjP\x1a\x1a\x0d\x0a\x87\x0a"; # (ref 2)
+
+    if ($outfile) {
+        Write($outfile, $hdr) or return -1;
+        $exifTool->InitWriteDirs(\%jp2Map);
+        # save list of directories to create
+        my %addDirs = %{$$exifTool{ADD_DIRS}};
+        $$exifTool{AddJp2Dirs} = \%addDirs;
+    } else {
+        $exifTool->SetFileType();
+    }
+    SetByteOrder('MM'); # JPEG 2000 files are big-endian
+    my %dirInfo = (
+        RAF => $raf,
+        DirName => 'JP2',
+        OutFile => $$dirInfo{OutFile},
+    );
+    my $tagTablePtr = GetTagTable('Image::ExifTool::Jpeg2000::Main');
+    return $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Jpeg2000 - Read JPEG 2000 meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to read JPEG 2000
+files.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.jpeg.org/public/fcd15444-2.pdf>
+
+=item L<ftp://ftp.remotesensing.org/jpeg2000/fcd15444-1.pdf>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Jpeg2000 Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Kodak.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Kodak.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Kodak.pm	(revision 20131)
@@ -0,0 +1,1129 @@
+#------------------------------------------------------------------------------
+# File:         Kodak.pm
+#
+# Description:  Kodak EXIF maker notes and APP3 "Meta" tags
+#
+# Revisions:    03/28/2005  - P. Harvey Created
+#
+# References:   1) http://search.cpan.org/dist/Image-MetaData-JPEG/
+#               2) http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html
+#
+# Notes:        There really isn't much public information about Kodak formats.
+#               The only source I could find was Image::MetaData::JPEG, which
+#               didn't provide information about decoding the tag values.  So
+#               this module represents a lot of work downloading sample images
+#               (about 100MB worth!), and testing with my daughter's CX4200.
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Kodak;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.10';
+
+sub ProcessKodakIFD($$$);
+sub WriteKodakIFD($$$);
+
+# Kodak type 1 maker notes (ref 1)
+%Image::ExifTool::Kodak::Main = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    NOTES => q{
+        The table below contains the most common set of Kodak tags.  The following
+        Kodak camera models have been tested and found to use these tags: C360,
+        C663, C875, CX6330, CX6445, CX7330, CX7430, CX7525, CX7530, DC4800, DC4900,
+        DX3500, DX3600, DX3900, DX4330, DX4530, DX4900, DX6340, DX6440, DX6490,
+        DX7440, DX7590, DX7630, EasyShare-One, LS420, LS443, LS633, LS743, LS753,
+        V530, V550, V570, V603, V610, V705, Z650, Z700, Z710, Z730, Z740, Z760 and
+        Z7590.
+    },
+    WRITABLE => 1,
+    FIRST_ENTRY => 8,
+    0x00 => {
+        Name => 'KodakModel',
+        Format => 'string[8]',
+    },
+    0x09 => {
+        Name => 'Quality',
+        PrintConv => { #PH
+            1 => 'Fine',
+            2 => 'Normal',
+        },
+    },
+    0x0a => {
+        Name => 'BurstMode',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x0c => {
+        Name => 'KodakImageWidth',
+        Format => 'int16u',
+    },
+    0x0e => {
+        Name => 'KodakImageHeight',
+        Format => 'int16u',
+    },
+    0x10 => {
+        Name => 'YearCreated',
+        Groups => { 2 => 'Time' },
+        Format => 'int16u',
+    },
+    0x12 => {
+        Name => 'MonthDayCreated',
+        Groups => { 2 => 'Time' },
+        Format => 'int8u[2]',
+        ValueConv => 'sprintf("%.2d:%.2d",split(" ", $val))',
+        ValueConvInv => '$val=~tr/:./ /;$val',
+    },
+    0x14 => {
+        Name => 'TimeCreated',
+        Groups => { 2 => 'Time' },
+        Format => 'int8u[4]',
+        Shift => 'Time',
+        ValueConv => 'sprintf("%.2d:%.2d:%.2d.%.2d",split(" ", $val))',
+        ValueConvInv => '$val=~tr/:./ /;$val',
+    },
+    0x18 => {
+        Name => 'BurstMode2',
+        Format => 'int16u',
+        Unknown => 1, # not sure about this tag (or other 'Unknown' tags)
+    },
+    0x1b => {
+        Name => 'ShutterMode',
+        PrintConv => { #PH
+            0 => 'Auto',
+            8 => 'Aperture Priority',
+            32 => 'Manual?',
+        },
+    },
+    0x1c => {
+        Name => 'MeteringMode',
+        PrintConv => { #PH
+            0 => 'Multi-pattern',
+            1 => 'Center-Weighted',
+            2 => 'Spot',
+        },
+    },
+    0x1d => 'SequenceNumber',
+    0x1e => {
+        Name => 'FNumber',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => 'int($val * 100 + 0.5)',
+    },
+    0x20 => {
+        Name => 'ExposureTime',
+        Format => 'int32u',
+        ValueConv => '$val / 1e5',
+        ValueConvInv => '$val * 1e5',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x24 => {
+        Name => 'ExposureCompensation',
+        Format => 'int16s',
+        ValueConv => '$val / 1000',
+        ValueConvInv => '$val * 1000',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => 'eval $val',
+    },
+    0x26 => {
+        Name => 'VariousModes',
+        Format => 'int16u',
+        Unknown => 1,
+    },
+    0x28 => {
+        Name => 'Distance1',
+        Format => 'int32u',
+        Unknown => 1,
+    },
+    0x2c => {
+        Name => 'Distance2',
+        Format => 'int32u',
+        Unknown => 1,
+    },
+    0x30 => {
+        Name => 'Distance3',
+        Format => 'int32u',
+        Unknown => 1,
+    },
+    0x34 => {
+        Name => 'Distance4',
+        Format => 'int32u',
+        Unknown => 1,
+    },
+    0x38 => {
+        Name => 'FocusMode',
+        PrintConv => {
+            0 => 'Normal',
+            2 => 'Macro',
+        },
+    },
+    0x3a => {
+        Name => 'VariousModes2',
+        Format => 'int16u',
+        Unknown => 1,
+    },
+    0x3c => {
+        Name => 'PanoramaMode',
+        Format => 'int16u',
+        Unknown => 1,
+    },
+    0x3e => {
+        Name => 'SubjectDistance',
+        Format => 'int16u',
+        Unknown => 1,
+    },
+    0x40 => {
+        Name => 'WhiteBalance',
+        Priority => 0,
+        PrintConv => { #PH
+            0 => 'Auto',
+            1 => 'Flash?',
+            2 => 'Tungsten',
+            3 => 'Daylight',
+        },
+    },
+    0x5c => {
+        Name => 'FlashMode',
+        Flags => 'PrintHex',
+        # various models express this number differently
+        PrintConv => { #PH
+            0x00 => 'Auto',
+            0x01 => 'Fill Flash',
+            0x02 => 'Off',
+            0x03 => 'Red-Eye',
+            0x10 => 'Fill Flash',
+            0x20 => 'Off',
+            0x40 => 'Red-Eye?',
+        },
+    },
+    0x5d => {
+        Name => 'FlashFired',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    0x5e => {
+        Name => 'ISOSetting',
+        Format => 'int16u',
+        PrintConv => '$val ? $val : "Auto"',
+        PrintConvInv => '$val=~/^\d+$/ ? $val : 0',
+    },
+    0x60 => {
+        Name => 'ISO',
+        Format => 'int16u',
+    },
+    0x62 => {
+        Name => 'TotalZoom',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+    },
+    0x64 => {
+        Name => 'DateTimeStamp',
+        Format => 'int16u',
+        PrintConv => '$val ? "Mode $val" : "Off"',
+        PrintConvInv => '$val=~tr/0-9//dc; $val ? $val : 0',
+    },
+    0x66 => {
+        Name => 'ColorMode',
+        Format => 'int16u',
+        Flags => 'PrintHex',
+        # various models express this number differently
+        PrintConv => { #PH
+            0x01 => 'B&W',
+            0x02 => 'Sepia',
+            0x03 => 'B&W Yellow Filter',
+            0x04 => 'B&W Red Filter',
+            0x20 => 'Saturated Color',
+            0x40 => 'Neutral Color',
+            0x100 => 'Saturated Color',
+            0x200 => 'Neutral Color',
+            0x2000 => 'B&W',
+            0x4000 => 'Sepia',
+        },
+    },
+    0x68 => {
+        Name => 'DigitalZoom',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+    },
+    0x6b => {
+        Name => 'Sharpness',
+        Format => 'int8s',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+);
+
+# Kodak type 2 maker notes (ref PH)
+%Image::ExifTool::Kodak::Type2 = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    NOTES => q{
+        These tags are used by the Kodak DC220, DC260, DC265 and DC290,
+        Hewlett-Packard PhotoSmart 618, C500 and C912, Pentax EI-200 and EI-2000,
+        and Minolta EX1500Z.
+    },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    0x08 => {
+        Name => 'KodakMaker',
+        Format => 'string[32]',
+    },
+    0x28 => {
+        Name => 'KodakModel',
+        Format => 'string[32]',
+    },
+    0x6c => {
+        Name => 'KodakImageWidth',
+        Format => 'int32u',
+    },
+    0x70 => {
+        Name => 'KodakImageHeight',
+        Format => 'int32u',
+    },
+);
+
+# Kodak type 3 maker notes (ref PH)
+%Image::ExifTool::Kodak::Type3 = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    NOTES => 'These tags are used by the DC240, DC280, DC3400 and DC5000.',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    0x0c => {
+        Name => 'YearCreated',
+        Groups => { 2 => 'Time' },
+        Format => 'int16u',
+    },
+    0x0e => {
+        Name => 'MonthDayCreated',
+        Groups => { 2 => 'Time' },
+        Format => 'int8u[2]',
+        ValueConv => 'sprintf("%.2d:%.2d",split(" ", $val))',
+        ValueConvInv => '$val=~tr/:./ /;$val',
+    },
+    0x10 => {
+        Name => 'TimeCreated',
+        Groups => { 2 => 'Time' },
+        Format => 'int8u[4]',
+        Shift => 'Time',
+        ValueConv => 'sprintf("%2d:%.2d:%.2d.%.2d",split(" ", $val))',
+        ValueConvInv => '$val=~tr/:./ /;$val',
+    },
+    0x1e => {
+        Name => 'OpticalZoom',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+    },
+    0x37 => {
+        Name => 'Sharpness',
+        Format => 'int8s',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    0x38 => {
+        Name => 'ExposureTime',
+        Format => 'int32u',
+        ValueConv => '$val / 1e5',
+        ValueConvInv => '$val * 1e5',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x3c => {
+        Name => 'FNumber',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => 'int($val * 100 + 0.5)',
+    },
+    0x4e => {
+        Name => 'ISO',
+        Format => 'int16u',
+    },
+);
+
+# Kodak type 4 maker notes (ref PH)
+%Image::ExifTool::Kodak::Type4 = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    NOTES => 'These tags are used by the DC200 and DC215.',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    0x20 => {
+        Name => 'OriginalFileName',
+        Format => 'string[12]',
+    },
+);
+
+# Kodak type 5 maker notes (ref PH)
+%Image::ExifTool::Kodak::Type5 = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    NOTES => q{
+        These tags are used by the CX4200, CX4210, CX4230, CX4300, CX4310, CX6200
+        and CX6230.
+    },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    0x14 => {
+        Name => 'ExposureTime',
+        Format => 'int32u',
+        ValueConv => '$val / 1e5',
+        ValueConvInv => '$val * 1e5',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x1a => {
+        Name => 'WhiteBalance',
+        PrintConv => {
+            1 => 'Daylight',
+            2 => 'Flash',
+            3 => 'Tungsten',
+        },
+    },
+    0x1c => {
+        Name => 'FNumber',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => 'int($val * 100 + 0.5)',
+    },
+    0x1e => {
+        Name => 'ISO',
+        Format => 'int16u',
+    },
+    0x20 => {
+        Name => 'OpticalZoom',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+    },
+    0x22 => {
+        Name => 'DigitalZoom',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+    },
+    0x27 => {
+        Name => 'FlashMode',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'On',
+            2 => 'Off',
+            3 => 'Red-Eye',
+        },
+    },
+    0x2a => {
+        Name => 'ImageRotated',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    0x2b => {
+        Name => 'Macro',
+        PrintConv => { 0 => 'On', 1 => 'Off' },
+    },
+);
+
+# Kodak type 6 maker notes (ref PH)
+%Image::ExifTool::Kodak::Type6 = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    NOTES => 'These tags are used by the DX3215 and DX3700.',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    0x10 => {
+        Name => 'ExposureTime',
+        Format => 'int32u',
+        ValueConv => '$val / 1e5',
+        ValueConvInv => '$val * 1e5',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x14 => {
+        Name => 'ISOSetting',
+        Format => 'int32u',
+        Unknown => 1,
+    },
+    0x18 => {
+        Name => 'FNumber',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => 'int($val * 100 + 0.5)',
+    },
+    0x1a => {
+        Name => 'ISO',
+        Format => 'int16u',
+    },
+    0x1c => {
+        Name => 'OpticalZoom',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+    },
+    0x1e => {
+        Name => 'DigitalZoom',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+    },
+    0x22 => {
+        Name => 'Flash',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'No Flash',
+            1 => 'Fired',
+        },
+    },
+);
+
+# Kodak type 7 maker notes (ref PH)
+%Image::ExifTool::Kodak::Type7 = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        The maker notes of models such as the C340, C433, CC533, LS755, V803 and
+        V1003 seem to start with the camera serial number.  The C310, C315, C330,
+        C643, C743, CD33, CD43, CX7220 and CX7300 maker notes are also decoded using
+        this table, although the strings for these cameras don't conform to the
+        usual Kodak serial number format, and instead have the model name followed
+        by 8 digits.
+    },
+    0 => { # (not confirmed)
+        Name => 'SerialNumber',
+        Format => 'string[16]',
+        ValueConv => '$val=~s/\s+$//; $val', # remove trailing whitespace
+        ValueConvInv => '$val',
+    },
+);
+
+# Kodak IFD-format maker notes (ref PH)
+%Image::ExifTool::Kodak::IFD = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        Newer Kodak models such as the P712, P850, P880, Z612 and Z712 use standard
+        TIFF IFD format for the maker notes.  There is a large amount of information
+        stored in these maker notes (with apparently much duplication), but
+        relatively few tags have so far been decoded.
+    },
+    0xfc00 => {
+        Name => 'SubIFD0',
+        Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::SubIFD0',
+            Start => '$val',
+        },
+    },
+    # SubIFD1 and higher data is preceded by a TIFF byte order mark to indicate
+    # the byte ordering used
+    0xfc01 => {
+        Name => 'SubIFD1',
+        Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::SubIFD1',
+            Start => '$val',
+            Base => '$start',
+        },
+    },
+    0xfc02 => {
+        Name => 'SubIFD2',
+        Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::SubIFD2',
+            Start => '$val',
+            Base => '$start',
+        },
+    },
+    0xfc03 => {
+        Name => 'SubIFD3',
+        Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::SubIFD3',
+            Start => '$val',
+            Base => '$start',
+        },
+    },
+    # (SubIFD4 has the pointer zeroed in my samples, but support it
+    # in case it is used by future models -- ignored if pointer is zero)
+    0xfc04 => {
+        Name => 'SubIFD4',
+        Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::SubIFD4',
+            Start => '$val',
+            Base => '$start',
+        },
+    },
+    0xfc05 => {
+        Name => 'SubIFD5',
+        Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::SubIFD5',
+            Start => '$val',
+            Base => '$start',
+        },
+    },
+    0xff00 => {
+        Name => 'CameraInfo',
+        Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::CameraInfo',
+            Start => '$val',
+        },
+    },
+);
+
+# Kodak SubIFD0 tags (ref PH)
+%Image::ExifTool::Kodak::SubIFD0 = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'SubIFD0 through SubIFD5 tags are used by the Z612 and Z712.',
+    0xfa02 => {
+        Name => 'SceneMode',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Sport',
+            3 => 'Portrait',
+            4 => 'Landscape',
+            6 => 'Beach',
+            7 => 'Night Portrait',
+            8 => 'Night Landscape',
+            9 => 'Snow',
+            10 => 'Text',
+            11 => 'Fireworks',
+            12 => 'Macro',
+            13 => 'Museum',
+            16 => 'Children',
+            17 => 'Program',
+            18 => 'Aperture Priority',
+            19 => 'Shutter Priority',
+            20 => 'Manual',
+            25 => 'Back Light',
+            28 => 'Candlelight',
+            29 => 'Sunset',
+            31 => 'Panorama Left-Right',
+            32 => 'Panorama Right-Left',
+            33 => 'Smart Scene',
+            34 => 'High ISO',
+        },
+    },
+    # 0xfa04 - values: 0 (normally), 2 (panorama shots)
+    # 0xfa0f - values: 0 (normally), 1 (macro?)
+    # 0xfa11 - some sort of FNumber (x 100)
+    0xfa19 => {
+        Name => 'SerialNumber', # (verified with Z712 - PH)
+        Writable => 'string',
+    },
+    0xfa1d => {
+        Name => 'KodakImageWidth',
+        Writable => 'int16u',
+    },
+    0xfa1e => {
+        Name => 'KodakImageHeight',
+        Writable => 'int16u',
+    },
+    0xfa20 => {
+        Name => 'SensorWidth',
+        Writable => 'int16u',
+    },
+    0xfa21 => {
+        Name => 'SensorHeight',
+        Writable => 'int16u',
+    },
+    0xfa23 => {
+        Name => 'FNumber',
+        Writable => 'int16u',
+        Priority => 0,
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+    },
+    0xfa24 => {
+        Name => 'ExposureTime',
+        Writable => 'int32u',
+        Priority => 0,
+        ValueConv => '$val / 1e5',
+        ValueConvInv => '$val * 1e5',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0xfa2e => {
+        Name => 'ISO',
+        Writable => 'int16u',
+        Priority => 0,
+    },
+    0xfa3d => {
+        Name => 'OpticalZoom',
+        Writable => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+        PrintConv => 'sprintf("%.2f",$val)',
+        PrintConvInv => '$val=~s/ ?x//; $val',
+    },
+    0xfa46 => {
+        Name => 'ISO',
+        Writable => 'int16u',
+        Priority => 0,
+    },
+    # 0xfa4c - related to focal length (1=wide, 32=full zoom)
+    0xfa51 => {
+        Name => 'KodakImageWidth',
+        Writable => 'int16u',
+    },
+    0xfa52 => {
+        Name => 'KodakImageHeight',
+        Writable => 'int16u',
+    },
+    0xfa54 => {
+        Name => 'ThumbnailWidth',
+        Writable => 'int16u',
+    },
+    0xfa55 => {
+        Name => 'ThumbnailHeight',
+        Writable => 'int16u',
+    },
+    0xfa57 => {
+        Name => 'PreviewWidth',
+        Writable => 'int16u',
+    },
+    0xfa58 => {
+        Name => 'PreviewHeight',
+        Writable => 'int16u',
+    },
+);
+
+# Kodak SubIFD1 tags (ref PH)
+%Image::ExifTool::Kodak::SubIFD1 = (
+    PROCESS_PROC => \&ProcessKodakIFD,
+    WRITE_PROC => \&WriteKodakIFD,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x0027 => {
+        Name => 'ISO',
+        Writable => 'int16u',
+        Priority => 0,
+    },
+    0x0028 => {
+        Name => 'ISO',
+        Writable => 'int16u',
+        Priority => 0,
+    },
+);
+
+my %sceneModeUsed = (
+    0 => 'Program',
+    2 => 'Aperture Priority',
+    3 => 'Shutter Priority',
+    4 => 'Manual',
+    5 => 'Portrait',
+    6 => 'Sport',
+    7 => 'Children',
+    8 => 'Museum',
+    10 => 'High ISO',
+    11 => 'Text',
+    12 => 'Macro',
+    13 => 'Back Light',
+    16 => 'Landscape',
+    17 => 'Night Landscape',
+    18 => 'Night Portrait',
+    19 => 'Snow',
+    20 => 'Beach',
+    21 => 'Fireworks',
+    22 => 'Sunset',
+    23 => 'Candlelight',
+    28 => 'Panorama',
+);
+
+# Kodak SubIFD2 tags (ref PH)
+%Image::ExifTool::Kodak::SubIFD2 = (
+    PROCESS_PROC => \&ProcessKodakIFD,
+    WRITE_PROC => \&WriteKodakIFD,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x6002 => {
+        Name => 'SceneModeUsed',
+        Writable => 'int32u',
+        PrintConv => \%sceneModeUsed,
+    },
+    0x6006 => {
+        Name => 'OpticalZoom',
+        Writable => 'int32u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+        PrintConv => 'sprintf("%.2f",$val)',
+        PrintConvInv => '$val=~s/ ?x//; $val',
+    },
+    # 0x6009 - some sort of FNumber (x 100)
+    0x6103 => {
+        Name => 'MaxAperture',
+        Writable => 'int32u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+    },
+    0xf002 => {
+        Name => 'SceneModeUsed',
+        Writable => 'int32u',
+        PrintConv => \%sceneModeUsed,
+    },
+    0xf006 => {
+        Name => 'OpticalZoom',
+        Writable => 'int32u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+        PrintConv => 'sprintf("%.2f",$val)',
+        PrintConvInv => '$val=~s/ ?x//; $val',
+    },
+    # 0xf009 - some sort of FNumber (x 100)
+    0xf103 => {
+        Name => 'FNumber',
+        Writable => 'int32u',
+        Priority => 0,
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+    },
+    0xf104 => {
+        Name => 'ExposureTime',
+        Writable => 'int32u',
+        Priority => 0,
+        ValueConv => '$val / 1e6',
+        ValueConvInv => '$val * 1e6',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0xf105 => {
+        Name => 'ISO',
+        Writable => 'int32u',
+        Priority => 0,
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+    },
+);
+
+# Kodak SubIFD3 tags (ref PH)
+%Image::ExifTool::Kodak::SubIFD3 = (
+    PROCESS_PROC => \&ProcessKodakIFD,
+    WRITE_PROC => \&WriteKodakIFD,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x1000 => {
+        Name => 'OpticalZoom',
+        Writable => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+        PrintConv => 'sprintf("%.2f",$val)',
+        PrintConvInv => '$val=~s/ ?x//; $val',
+    },
+    # 0x1002 - related to focal length (1=wide, 32=full zoom)
+    # 0x1006 - pictures remaining? (gradually decreases as pictures are taken)
+);
+
+# Kodak SubIFD4 tags (ref PH)
+%Image::ExifTool::Kodak::SubIFD4 = (
+    PROCESS_PROC => \&ProcessKodakIFD,
+    WRITE_PROC => \&WriteKodakIFD,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+);
+
+# Kodak SubIFD5 tags (ref PH)
+%Image::ExifTool::Kodak::SubIFD5 = (
+    PROCESS_PROC => \&ProcessKodakIFD,
+    WRITE_PROC => \&WriteKodakIFD,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x000f => {
+        Name => 'OpticalZoom',
+        Writable => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+        PrintConv => 'sprintf("%.2f",$val)',
+        PrintConvInv => '$val=~s/ ?x//; $val',
+    },
+);
+
+# Decoded from P712, P850 and P880 samples (ref PH)
+%Image::ExifTool::Kodak::CameraInfo = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags are used by the  P712, P850 and P880.',
+    0xf900 => {
+        Name => 'SensorWidth',
+        Writable => 'int16u',
+        Notes => 'effective sensor size',
+    },
+    0xf901 => {
+        Name => 'SensorHeight',
+        Writable => 'int16u',
+    },
+    0xf902 => {
+        Name => 'BayerPattern',
+        Writable => 'string',
+    },
+    0xf903 => {
+        Name => 'SensorFullWidth',
+        Writable => 'int16u',
+        Notes => 'includes black border?',
+    },
+    0xf904 => {
+        Name => 'SensorFullHeight',
+        Writable => 'int16u',
+    },
+    0xf907 => {
+        Name => 'KodakImageWidth',
+        Writable => 'int16u',
+    },
+    0xf908 => {
+        Name => 'KodakImageHeight',
+        Writable => 'int16u',
+    },
+    0xfa00 => {
+        Name => 'KodakInfoType',
+        Writable => 'string',
+    },
+    0xfa04 => {
+        Name => 'SerialNumber', # (unverified)
+        Writable => 'string',
+    },
+    0xfd04 => {
+        Name => 'FNumber',
+        Writable => 'int16u',
+        Priority => 0,
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+    },
+    0xfd05 => {
+        Name => 'ExposureTime',
+        Writable => 'int32u',
+        Priority => 0,
+        ValueConv => '$val / 1e6',
+        ValueConvInv => '$val * 1e6',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0xfd06 => {
+        Name => 'ISO',
+        Writable => 'int16u',
+        Priority => 0,
+    },
+);
+
+# treat unknown maker notes as binary data (allows viewing with -U)
+%Image::ExifTool::Kodak::Unknown = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FIRST_ENTRY => 0,
+);
+
+# Kodak APP3 "Meta" tags (ref 2)
+%Image::ExifTool::Kodak::Meta = (
+    GROUPS => { 0 => 'Meta', 1 => 'MetaIFD', 2 => 'Image'},
+    NOTES => q{
+        These tags are found in the APP3 "Meta" segment of JPEG images from Kodak
+        cameras such as the DC280, DC3400, DC5000 and MC3.  The structure of this
+        segment is similar to the APP1 "Exif" segment, but a different set of tags
+        is used.
+    },
+    0xc350 => 'FilmProductCode',
+    0xc351 => 'ImageSourceEK',
+    0xc352 => 'CaptureConditionsPAR',
+    0xc353 => {
+        Name => 'CameraOwner',
+        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+    },
+    0xc354 => {
+        Name => 'SerialNumber',
+        Groups => { 2 => 'Camera' },
+    },
+    0xc355 => 'UserSelectGroupTitle',
+    0xc356 => 'DealerIDNumber',
+    0xc357 => 'CaptureDeviceFID',
+    0xc358 => 'EnvelopeNumber',
+    0xc359 => 'FrameNumber',
+    0xc35a => 'FilmCategory',
+    0xc35b => 'FilmGencode',
+    0xc35c => 'ModelAndVersion',
+    0xc35d => 'FilmSize',
+    0xc35e => 'SBA_RGBShifts',
+    0xc35f => 'SBAInputImageColorspace',
+    0xc360 => 'SBAInputImageBitDepth',
+    0xc361 => 'SBAExposureRecord',
+    0xc362 => 'UserAdjSBA_RGBShifts',
+    0xc363 => 'ImageRotationStatus',
+    0xc364 => 'RollGuidElements',
+    0xc365 => 'MetadataNumber',
+    0xc366 => 'EditTagArray',
+    0xc367 => 'Magnification',
+    0xc36c => 'NativeXResolution',
+    0xc36d => 'NativeYResolution',
+    0xc36e => {
+        Name => 'KodakEffectsIFD',
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::SpecialEffects',
+            Start => '$val',
+        },
+    },
+    0xc36f => {
+        Name => 'KodakBordersIFD',
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Borders',
+            Start => '$val',
+        },
+    },
+    0xc37a => 'NativeResolutionUnit',
+    0xc418 => 'SourceImageDirectory',
+    0xc419 => 'SourceImageFileName',
+    0xc41a => 'SourceImageVolumeName',
+    0xc46c => 'PrintQuality',
+    0xc46e => 'ImagePrintStatus',
+);
+
+# Kodak APP3 "Meta" Special Effects sub-IFD (ref 2)
+%Image::ExifTool::Kodak::SpecialEffects = (
+    GROUPS => { 0 => 'Meta', 1 => 'KodakEffectsIFD', 2 => 'Image'},
+    0 => 'DigitalEffectsVersion',
+    1 => {
+        Name => 'DigitalEffectsName',
+        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+    },
+    2 => 'DigitalEffectsType',
+);
+
+# Kodak APP3 "Meta" Borders sub-IFD (ref 2)
+%Image::ExifTool::Kodak::Borders = (
+    GROUPS => { 0 => 'Meta', 1 => 'KodakBordersIFD', 2 => 'Image'},
+    0 => 'BordersVersion',
+    1 => {
+        Name => 'BorderName',
+        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+    },
+    2 => 'BorderID',
+    3 => 'BorderLocation',
+    4 => 'BorderType',
+    8 => 'WatermarkType',
+);
+
+# Kodak composite tags
+%Image::ExifTool::Kodak::Composite = (
+    DateCreated => {
+        Groups => { 2 => 'Time' },
+        Require => {
+            0 => 'Kodak:YearCreated',
+            1 => 'Kodak:MonthDayCreated',
+        },
+        ValueConv => '"$val[0]:$val[1]"',
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::Kodak');
+
+#------------------------------------------------------------------------------
+# Process Kodak IFD (with leading byte order mark)
+# Inputs: 0) ExifTool object ref, 1) dirInfo hash ref, 2) tag table ref
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+sub ProcessKodakIFD($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    return 1 if $dirStart <= 0 or $dirStart + 2 > $$dirInfo{DataLen};
+    my $byteOrder = substr(${$$dirInfo{DataPt}}, $dirStart, 2);
+    return 1 unless Image::ExifTool::SetByteOrder($byteOrder);
+    $$dirInfo{DirStart} += 2;   # skip byte order mark
+    $$dirInfo{DirLen} -= 2;
+    if ($exifTool->{HTML_DUMP}) {
+        my $base = $$dirInfo{Base} + $$dirInfo{DataPos};
+        $exifTool->HtmlDump($dirStart+$base, 2, "Byte Order Mark");
+    }
+    return Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
+}
+
+#------------------------------------------------------------------------------
+# Write Kodak IFD (with leading byte order mark)
+# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref
+# Returns: Exif data block (may be empty if no Exif data) or undef on error
+sub WriteKodakIFD($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    return '' if $dirStart <= 0 or $dirStart + 2 > $$dirInfo{DataLen};
+    my $byteOrder = substr(${$$dirInfo{DataPt}}, $dirStart, 2);
+    return '' unless Image::ExifTool::SetByteOrder($byteOrder);
+    $$dirInfo{DirStart} += 2;   # skip byte order mark
+    $$dirInfo{DirLen} -= 2;
+    my $buff = Image::ExifTool::Exif::WriteExif($exifTool, $dirInfo, $tagTablePtr);
+    return $buff unless defined $buff and length $buff;
+    # apply one-time fixup for length of byte order mark
+    if ($$dirInfo{Fixup}) {
+        $dirInfo->{Fixup}->{Shift} += 2;
+        $$dirInfo{Fixup}->ApplyFixup(\$buff);
+        delete $$dirInfo{Fixup};
+    }
+    return Image::ExifTool::GetByteOrder() . $buff;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Kodak - Kodak EXIF maker notes and APP3 "Meta" tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to
+interpret Kodak maker notes EXIF meta information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<Image::MetaData::JPEG|Image::MetaData::JPEG>
+
+=item L<http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html>
+
+=item (...plus lots of testing with my daughter's CX4200!)
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Kodak Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/KyoceraRaw.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/KyoceraRaw.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/KyoceraRaw.pm	(revision 20131)
@@ -0,0 +1,171 @@
+#------------------------------------------------------------------------------
+# File:         KyoceraRaw.pm
+#
+# Description:  Read Kyocera RAW meta information
+#
+# Revisions:    02/17/2006 - P. Harvey Created
+#
+# References:   1) http://www.cybercom.net/~dcoffin/dcraw/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::KyoceraRaw;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess);
+
+$VERSION = '1.00';
+
+sub ProcessRAW($$);
+
+# utility to reverse order of characters in a string
+sub ReverseString($) { pack('C*',reverse unpack('C*',shift)) }
+
+# Contax N Digital tags (ref PH)
+%Image::ExifTool::KyoceraRaw::Main = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Tags for Kyocera Contax N Digital RAW images.',
+    0x01 => {
+        Name => 'FirmwareVersion',
+        Format => 'string[10]',
+        ValueConv => \&ReverseString,
+    },
+    0x0c => {
+        Name => 'Model',
+        Format => 'string[12]',
+        ValueConv => \&ReverseString,
+    },
+    0x19 => { #1
+        Name => 'Make',
+        Format => 'string[7]',
+        ValueConv => \&ReverseString,
+    },
+    0x21 => { #1
+        Name => 'DateTimeOriginal',
+        Groups => { 2 => 'Time' },
+        Format => 'string[20]',
+        ValueConv => \&ReverseString,
+    },
+    0x34 => {
+        Name => 'ISO',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        PrintConv => {
+            7 => 25,
+            8 => 32,
+            9 => 40,
+            10 => 50,
+            11 => 64,
+            12 => 80,
+            13 => 100,
+            14 => 125,
+            15 => 160,
+            16 => 200,
+            17 => 250,
+            18 => 320,
+            19 => 400,
+        },
+    },
+    0x38 => {
+        Name => 'ExposureTime',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '2**($val / 8) / 16000',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    0x3c => { #1
+        Name => 'WB_RGGBLevels',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u[4]',
+    },
+    0x58 => {
+        Name => 'FNumber',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '2**($val/16)',
+        PrintConv => 'sprintf("%.2g",$val)',
+    },
+    0x68 => {
+        Name => 'MaxAperture',
+        Format => 'int32u',
+        ValueConv => '2**($val/16)',
+        PrintConv => 'sprintf("%.2g",$val)',
+    },
+    0x70 => {
+        Name => 'FocalLength',
+        Format => 'int32u',
+        PrintConv => '"${val}mm"',
+    },
+    0x7c => {
+        Name => 'Lens',
+        Format => 'string[32]',
+    },
+);
+
+#------------------------------------------------------------------------------
+# Extract information from Kyocera RAW image
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 if this was a valid Kyocera RAW image
+sub ProcessRAW($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $size = 156; # size of header
+    my $buff;
+
+    $raf->Read($buff, $size) == $size or return 0;
+    # validate Make string ('KYOCERA' reversed)
+    substr($buff, 0x19, 7) eq 'ARECOYK' or return 0;
+    $exifTool->SetFileType();
+    SetByteOrder('MM');
+    my %dirInfo = (
+        DataPt => \$buff,
+        DataPos => 0,
+        DataLen => $size,
+        DirStart => 0,
+        DirLen => $size,
+    );
+    my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::KyoceraRaw::Main');
+    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::KyoceraRaw - Read Kyocera RAW meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read
+meta information from Kyocera Contax N Digital RAW images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.cybercom.net/~dcoffin/dcraw/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/KyoceraRaw Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Leaf.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Leaf.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Leaf.pm	(revision 20131)
@@ -0,0 +1,514 @@
+#------------------------------------------------------------------------------
+# File:         Leaf.pm
+#
+# Description:  Read Creo Leaf EXIF meta information
+#
+# Revisions:    09/28/2005  - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Leaf;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.01';
+
+sub ProcessLeaf($$$);
+
+%Image::ExifTool::Leaf::Main = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Camera' },
+    NOTES => q{
+These tags are found in .MOS images from Leaf digital camera backs as
+written by Creo Leaf Capture.  They exist within the Leaf-specific directory
+structure of EXIF tag 0x8606. The tables below list observed Leaf tags,
+however ExifTool will extract any tags found in the Leaf directories even if
+they don't appear in these tables.
+    },
+    icc_camera_profile => {
+        Name => 'ICC_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+        },
+    },
+    icc_rgb_ws_profile => {
+        Name => 'RGB_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+        },
+    },
+    camera_profile => {
+        Name => 'CameraProfile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::CameraProfile',
+        },
+    },
+    JPEG_preview_data => {
+        %Image::ExifTool::previewImageTagInfo,
+    },
+    JPEG_preview_info => 'PreviewInfo',
+    icc_camera_to_tone_space_flow => {
+        Name => 'ToneSpaceFlow',
+        Description => 'ICC To Tone Space Flow',
+        Format => 'int16u',
+    },
+    icc_camera_to_tone_matrix => {
+        Name => 'ToneMatrix',
+        Description => 'ICC To Tone Matrix',
+        Format => 'int8u',
+        Binary => 1,
+    },
+    PDA_histogram_data => {
+        Name => 'PDAHistogram',
+        Binary => 1,
+    },
+    pattern_ratation_angle => {
+        Name => 'PatternAngle',
+        Description => 'Pattern Rotation Angle',
+        Format => 'int16u',
+        Notes => '"ratation" is not a typo',
+    },
+    back_serial_number => {
+        Name => 'BackSerial',
+        Description => 'Back Serial Number',
+        PrintConv => '$val =~ s/ .*//; $val',
+    },
+    image_offset => { Format => 'int16u' },
+);
+
+%Image::ExifTool::Leaf::CameraProfile = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Camera' },
+    CamProf_version => 'CameraProfileVersion',
+    CamProf_name    => 'CameraName',
+    CamProf_type    => 'CameraType',
+    CamProf_back_type => 'CameraBackType',
+    CamProf_back_type => {
+        Name => 'CameraBackType',
+    },
+    CamProf_capture_profile => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::CaptureProfile',
+        },
+    },
+    CamProf_image_profile => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::ImageProfile',
+        },
+    },
+);
+
+%Image::ExifTool::Leaf::CaptureProfile = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Image' },
+    CaptProf_version        => {},
+    CaptProf_name           => {},
+    CaptProf_type           => {},
+    CaptProf_back_type      => {},
+    CaptProf_serial_number  => {
+        Name => 'CaptureSerial',
+        Description => 'Capture Serial Number',
+        PrintConv => '$val =~ s/ .*//; $val',
+    },
+    CaptProf_image_offset       => {},
+    CaptProf_luminance_consts   => {},
+    CaptProf_xy_offset_info     => 'XYOffsetInfo',
+    CaptProf_color_matrix       => {},
+    CaptProf_reconstruction_type=> {},
+    CaptProf_image_fields       => {},
+    CaptProf_image_bounds       => {},
+    CaptProf_number_of_planes   => {},
+    CaptProf_raw_data_rotation  => {},
+    CaptProf_color_averages     => {},
+    CaptProf_mosaic_pattern     => {},
+    CaptProf_dark_correction_type=>{},
+    CaptProf_right_dark_rect    => {},
+    CaptProf_left_dark_rect     => {},
+    CaptProf_center_dark_rect   => {},
+    CaptProf_CCD_rect           => {},
+    CaptProf_CCD_valid_rect     => {},
+    CaptProf_CCD_video_rect     => {},
+);
+
+%Image::ExifTool::Leaf::ImageProfile = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Image' },
+    ImgProf_version         => {},
+    ImgProf_name            => {},
+    ImgProf_type            => {},
+    ImgProf_back_type       => {},
+    ImgProf_shoot_setup => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::ShootSetup',
+        },
+    },
+    ImgProf_image_status    => {},
+    ImgProf_rotation_angle  => {},
+);
+
+%Image::ExifTool::Leaf::ShootSetup = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Image' },
+    ShootObj_version        => {},
+    ShootObj_name           => {},
+    ShootObj_type           => {},
+    ShootObj_back_type      => {},
+    ShootObj_capture_setup => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::CaptureSetup',
+        },
+    },
+    ShootObj_color_setup => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::ColorSetup',
+        },
+    },
+    ShootObj_save_setup => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::SaveSetup',
+        },
+    },
+    ShootObj_camera_setup => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::CameraSetup',
+        },
+    },
+    ShootObj_look_header => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::LookHeader',
+        },
+    },
+);
+
+%Image::ExifTool::Leaf::CaptureSetup = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Image' },
+    CaptureObj_version      => {},
+    CaptureObj_name         => {},
+    CaptureObj_type         => {},
+    CaptureObj_back_type    => {},
+    CaptureObj_neutals => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::Neutrals',
+        },
+    },
+    CaptureObj_selection => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::Selection',
+        },
+    },
+    CaptureObj_tone_curve => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::ToneCurve',
+        },
+    },
+    CaptureObj_sharpness => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Leaf::Sharpness',
+        },
+    },
+    CaptureObj_single_quality => {},
+    CaptureObj_Multi_quality  => {},
+);
+
+%Image::ExifTool::Leaf::Neutrals = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Image' },
+    NeutObj_version         => {},
+    NeutObj_name            => {},
+    NeutObj_type            => {},
+    NeutObj_back_type       => {},
+    NeutObj_neutrals        => {},
+    NeutObj_color_casts     => {},
+    NeutObj_shadow_end_points    => {},
+    NeutObj_highlight_end_points => {},
+);
+
+%Image::ExifTool::Leaf::Selection = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Image' },
+    SelObj_version          => {},
+    SelObj_name             => {},
+    SelObj_type             => {},
+    SelObj_back_type        => {},
+    SelObj_rect             => {},
+    SelObj_resolution       => {},
+    SelObj_scale            => {},
+    SelObj_locks            => {},
+    SelObj_orientation      => {},
+);
+
+%Image::ExifTool::Leaf::ToneCurve = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Image' },
+    ToneObj_version         => {},
+    ToneObj_name            => {},
+    ToneObj_type            => {},
+    ToneObj_back_type       => {},
+    ToneObj_npts            => {},
+    ToneObj_tones           => {},
+    ToneObj_gamma           => {},
+);
+
+%Image::ExifTool::Leaf::Sharpness = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Image' },
+    SharpObj_version        => {},
+    SharpObj_name           => {},
+    SharpObj_type           => {},
+    SharpObj_back_type      => {},
+    SharpObj_sharp_method   => {},
+    SharpObj_data_len       => {},
+    SharpObj_sharp_info     => {},
+);
+
+%Image::ExifTool::Leaf::ColorSetup = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Image' },
+    ColorObj_version        => {},
+    ColorObj_name           => {},
+    ColorObj_type           => {},
+    ColorObj_back_type      => {},
+    ColorObj_has_ICC        => {},
+    ColorObj_input_profile  => {},
+    ColorObj_output_profile => {},
+    ColorObj_color_mode     => {},
+    ColorObj_color_type     => {},
+);
+
+%Image::ExifTool::Leaf::SaveSetup = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Other' },
+    SaveObj_version         => {},
+    SaveObj_name            => {},
+    SaveObj_type            => {},
+    SaveObj_back_type       => {},
+    SaveObj_leaf_auto_active=> {},
+    SaveObj_leaf_hot_folder => {},
+    SaveObj_leaf_output_file_type => {},
+    SaveObj_leaf_auto_base_name   => {},
+    SaveObj_leaf_save_selection   => {},
+    SaveObj_leaf_open_proc_HDR    => {},
+    SaveObj_std_auto_active       => {},
+    SaveObj_std_hot_folder        => {},
+    SaveObj_std_output_file_type  => {},
+    SaveObj_std_output_color_mode => {},
+    SaveObj_std_output_bit_depth  => {},
+    SaveObj_std_base_name         => {},
+    SaveObj_std_save_selection    => {},
+    SaveObj_std_oxygen            => {},
+    SaveObj_std_open_in_photoshop => {},
+    SaveObj_std_scaled_output     => {},
+    SaveObj_std_sharpen_output    => {},
+);
+
+%Image::ExifTool::Leaf::CameraSetup = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Camera' },
+    CameraObj_version       => {},
+    CameraObj_name          => {},
+    CameraObj_type          => {},
+    CameraObj_back_type     => {},
+    CameraObj_ISO_speed     => {},
+    CameraObj_strobe        => {},
+    CameraObj_camera_type   => {},
+    CameraObj_lens_type     => {},
+    CameraObj_lens_ID       => {},
+);
+
+%Image::ExifTool::Leaf::LookHeader = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Other' },
+    LookHead_version        => {},
+    LookHead_name           => {},
+    LookHead_type           => {},
+    LookHead_back_type      => {},
+);
+
+# tag table for any unknown Leaf directories
+%Image::ExifTool::Leaf::Unknown = (
+    PROCESS_PROC => \&ProcessLeaf,
+    GROUPS => { 0 => 'Leaf', 2 => 'Unknown' },
+);
+
+# table for Leaf SubIFD entries
+%Image::ExifTool::Leaf::SubIFD = (
+    GROUPS => { 0 => 'EXIF', 1 => 'LeafSubIFD', 2 => 'Image'},
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    NOTES => q{
+Leaf also writes a TIFF-format sub-IFD inside IFD0 of a MOS image.  No tags
+in this sub-IFD are currently known, except for tag 0x8606 which really
+shouldn't be here anyway (so it doesn't appear in the table below) because
+it duplicates a reference to the same data of tag 0x8606 in IFD0.
+    },
+);
+
+# prepare Leaf tables by generating tag 'Name' and table 'NOTES'
+{
+    my @tableList = ( 'Image::ExifTool::Leaf::Main' );
+    my ($tag, %doneTable);
+    # keep prefix in tag name of common tags
+    my %keepPrefix = ( Version=>1, Name=>1, Type=>1, BackType=>1 );
+    while (@tableList) {
+        my $table = shift @tableList;
+        next if $doneTable{$table};
+        my $prefix = ($table =~ /::Main$/) ? undef : '';
+        $doneTable{$table} = 1;
+        no strict 'refs';
+        $table = \%$table;
+        use strict 'refs';
+        foreach $tag (keys %$table) {
+            my $tagInfo = $$table{$tag};
+            next unless ref $tagInfo eq 'HASH';
+            next if $tag eq 'GROUPS';
+            if (defined $prefix and not $prefix) {
+                ($prefix = $tag) =~ s/_.*//;
+            }
+            unless ($$tagInfo{Name}) {
+                my $name;
+                ($name = $tag) =~ s/_(.)/\U$1/g;
+                if ($prefix) {
+                    $name =~ s/^$prefix//;
+                    $name = $prefix . $name if $keepPrefix{$name};
+                }
+                $$tagInfo{Name} = ucfirst($name);
+            }
+            next unless $$tagInfo{SubDirectory};
+            my $subTable = $tagInfo->{SubDirectory}->{TagTable};
+            next unless $subTable =~ /::Leaf::/;
+            push @tableList, $subTable;
+        }
+        next unless $prefix;
+        $$table{NOTES} = "All B<Tag ID>'s in the following table have a " .
+                         "leading '${prefix}_' which\nhas been removed.\n";
+    }
+}
+
+#------------------------------------------------------------------------------
+# Process Leaf information
+# Inputs: 0) ExifTool object reference
+#         1) Reference to directory information hash
+#         2) Pointer to tag table for this directory
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+sub ProcessLeaf($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || $$dirInfo{DataLen} - $dirStart;
+    my $dirEnd = $dirStart + $dirLen;
+    my $verbose = $exifTool->Options('Verbose');
+    my $pos = $dirStart;
+    my $hdrLen = 52;    # header length for PKTS information
+    my $success;
+
+    $verbose and $exifTool->VerboseDir('Leaf');
+    for (;;) {
+        last if $pos + $hdrLen > $dirEnd;
+        my $header = substr($$dataPt, $pos, $hdrLen);
+        last unless substr($header, 0, 4) eq 'PKTS';
+        $success = 1;
+        my $size = Get32u(\$header, 48);
+        $pos += $hdrLen;
+        if ($pos + $size > $dirEnd) {
+            $exifTool->Warn('Truncated Leaf data');
+            last;
+        }
+        my $tag = substr($header, 8, 40);
+        $tag =~ s/\0.*//;
+        next unless $tag;
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        # generate tag info for unknown tags
+        my $val;
+        if ($tagInfo and $$tagInfo{Format}) {
+            $val = ReadValue($dataPt, $pos, $$tagInfo{Format}, undef, $size);
+        } else {
+            $val = substr($$dataPt, $pos, $size);
+        }
+        unless ($tagInfo) {
+            my $name = ucfirst($tag);
+            $name =~ s/_(.)/\U$1/g;
+            if ($val =~ /^PKTS\0\0\0\x01/) {
+                # also unpack unknown directories
+                $tagInfo = {
+                    Name => $name,
+                    SubDirectory => { TagTable => 'Image::ExifTool::Leaf::Unknown' },
+                };
+            } elsif ($tagTablePtr ne \%Image::ExifTool::Leaf::Main or
+                     $exifTool->Options('Unknown'))
+            {
+                $tagInfo = {
+                    Name => $name,
+                    Writable => 0,
+                    PrintConv => 'length($val) > 60 ? substr($val,0,55) . "[...]" : $val',
+                };
+                # make tags in main table unknown because they tend to be binary
+                $$tagInfo{Unknown} = 1 if $tagTablePtr eq \%Image::ExifTool::Leaf::Main;
+            }
+            $tagInfo and Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        if ($verbose) {
+            $exifTool->VerboseInfo($tag, $tagInfo,
+                Table   => $tagTablePtr,
+                Value   => $val,
+                DataPt  => $dataPt,
+                DataPos => $$dirInfo{DataPos},
+                Size    => $size,
+                Start   => $pos,
+            );
+        }
+        if ($tagInfo) {
+            if ($$tagInfo{SubDirectory}) {
+                my %subdirInfo = (
+                    DataPt => $dataPt,
+                    DirLen => $size,
+                    DirStart => $pos,
+                    DataPos => $$dirInfo{DataPos},
+                    DirName => 'Leaf PKTS',
+                );
+                my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                $exifTool->ProcessDirectory(\%subdirInfo, $subTable);
+            } else {
+                $val =~ tr/\n/ /;   # remove newlines from value
+                $exifTool->FoundTag($tagInfo, $val);
+            }
+        }
+        $pos += $size;
+    }
+    $success or $exifTool->Warn('Bad format Leaf data');
+    return $success;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Leaf - Read Creo Leaf EXIF meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+meta information from Leaf digital camera backs written by Creo Leaf
+Capture.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Leaf Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/MIE.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/MIE.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/MIE.pm	(revision 20131)
@@ -0,0 +1,2518 @@
+#------------------------------------------------------------------------------
+# File:         MIE.pm
+#
+# Description:  Read/write MIE meta information
+#
+# Revisions:    11/18/2005 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::MIE;
+
+use strict;
+use vars qw($VERSION %tableDefaults);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+use Image::ExifTool::GPS;
+
+$VERSION = '1.15';
+
+sub ProcessMIE($$);
+sub ProcessMIEGroup($$$);
+sub WriteMIEGroup($$$);
+sub CheckMIE($$$);
+sub GetLangInfo($$);
+
+# local variables
+my $hasZlib;        # 1=Zlib available, 0=no Zlib
+my %mieCode;        # reverse lookup for MIE format names
+my $doneMieMap;     # flag indicating we added user-defined groups to %mieMap
+
+# MIE format codes
+my %mieFormat = (
+    0x00 => 'undef',
+    0x10 => 'MIE',
+    0x18 => 'MIE',
+    0x20 => 'string', # ASCII (ISO 8859-1)
+    0x28 => 'utf8',
+    0x29 => 'utf16',
+    0x2a => 'utf32',
+    0x30 => 'string_list',
+    0x38 => 'utf8_list',
+    0x39 => 'utf16_list',
+    0x3a => 'utf32_list',
+    0x40 => 'int8u',
+    0x41 => 'int16u',
+    0x42 => 'int32u',
+    0x43 => 'int64u',
+    0x48 => 'int8s',
+    0x49 => 'int16s',
+    0x4a => 'int32s',
+    0x4b => 'int64s',
+    0x52 => 'rational32u',
+    0x53 => 'rational64u',
+    0x5a => 'rational32s',
+    0x5b => 'rational64s',
+    0x61 => 'fixed16u',
+    0x62 => 'fixed32u',
+    0x69 => 'fixed16s',
+    0x6a => 'fixed32s',
+    0x72 => 'float',
+    0x73 => 'double',
+    0x80 => 'free',
+);
+
+# map of MIE directory locations
+my %mieMap = (
+   'MIE-Meta'       => 'MIE',
+   'MIE-Audio'      => 'MIE-Meta',
+   'MIE-Camera'     => 'MIE-Meta',
+   'MIE-Doc'        => 'MIE-Meta',
+   'MIE-Geo'        => 'MIE-Meta',
+   'MIE-Image'      => 'MIE-Meta',
+   'MIE-MakerNotes' => 'MIE-Meta',
+   'MIE-Preview'    => 'MIE-Meta',
+   'MIE-Thumbnail'  => 'MIE-Meta',
+   'MIE-Video'      => 'MIE-Meta',
+   'MIE-Flash'      => 'MIE-Camera',
+   'MIE-Lens'       => 'MIE-Camera',
+   'MIE-Orient'     => 'MIE-Camera',
+   'MIE-Extender'   => 'MIE-Lens',
+   'MIE-GPS'        => 'MIE-Geo',
+   'MIE-UTM'        => 'MIE-Geo',
+    EXIF            => 'MIE-Meta',
+    XMP             => 'MIE-Meta',
+    IPTC            => 'MIE-Meta',
+    ICC_Profile     => 'MIE-Meta',
+    ID3             => 'MIE-Meta',
+    IFD0            => 'EXIF',
+    IFD1            => 'IFD0',
+    ExifIFD         => 'IFD0',
+    GPS             => 'IFD0',
+    SubIFD          => 'IFD0',
+    GlobParamIFD    => 'IFD0',
+    PrintIM         => 'IFD0',
+    InteropIFD      => 'ExifIFD',
+    MakerNotes      => 'ExifIFD',
+);
+
+# convenience variables for common tagInfo entries
+my %binaryConv = (
+    Writable => 'undef',
+    Binary => 1,
+);
+my %dateInfo = (
+    Groups => { 2 => 'Time' },
+    Shift => 'Time',
+    PrintConv => '$self->ConvertDateTime($val)',
+    PrintConvInv => '$val',
+);
+my %noYes = ( 0 => 'No', 1 => 'Yes' );
+my %offOn = ( 0 => 'Off', 1 => 'On' );
+
+# default entries for MIE tag tables
+%tableDefaults = (
+    PROCESS_PROC => \&ProcessMIE,
+    WRITE_PROC   => \&ProcessMIE,
+    CHECK_PROC   => \&CheckMIE,
+    LANG_INFO    => \&GetLangInfo,
+    WRITABLE     => 'string',
+    PREFERRED    => 1,
+);
+
+# MIE info
+%Image::ExifTool::MIE::Main = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Main' },
+    WRITE_GROUP => 'MIE-Main',
+    NOTES => q{
+        MIE is a flexible format which may be used as a stand-alone meta information
+        format, for encapsulation of other files and information, or as a trailer
+        appended to other file formats.  The tables below represent currently
+        defined MIE tags, however ExifTool will also extract any other information
+        present in a MIE file.
+
+        When writing MIE information, some special features are supported:
+
+        1) String values may be written as ASCII (ISO 8859-1) or UTF-8.  ExifTool
+        automatically detects the presence of wide characters and treats the string
+        appropriately. Internally, UTF-8 text may be converted to UTF-16 or UTF-32
+        and stored in this format in the file if it is more compact.
+
+        2) All MIE string-value tags support localized text.  Localized values are
+        written by adding a language/country code to the tag name in the form
+        C<TAG-xx_YY>, where C<TAG> is the tag name, C<xx> is a 2-character lower
+        case ISO 639-1 language code, and C<YY> is a 2-character upper case ISO
+        3166-1 alpha 2 country code (ie. C<Title-en_US>).  But as usual, the user
+        interface is case-insensitive, and ExifTool will write the correct case to
+        the file.
+
+        3) Some numerical MIE tags allow units of measurement to be specified.  For
+        these tags, units may be added in brackets immediately following the value
+        (ie. C<55(mi/h)>).  If no units are specified, the default units are
+        written.
+    },
+   '0Type' => {
+        Name => 'SubfileType',
+        Notes => q{
+            Currently defined types are ACR, AI, AIFF, APE, ARW, ASF, AVI, BMP, CR2,
+            CRW, DCM, DNG, EPS, ERF, FLAC, FPX, GIF, ICC, JNG, JP2, JPEG, MIE, MIFF MNG,
+            MOS, MOV, MP3, MP4, MPC, MPEG, MRW, NEF, OGG, ORF, PBM, PDF, PEF, PGM, PICT,
+            PNG, PPM, PS, PSD, QTIF, RA, RAF, RAW, RIFF, RM, SR2, SRF, SWF, TIFF, VRD,
+            WAV, WDP, WMA, WMV, X3F and XMP.  Other types should use the common file
+            extension.
+        },
+    },
+   '0Vers' => {
+        Name => 'MIEVersion',
+        Notes => 'version 1.1 is assumed if not specified',
+    },
+   '1Directory' => { Name => 'SubfileDirectory' },
+   '1Name'      => { Name => 'SubfileName' },
+   '2MIME'      => { Name => 'SubfileMIMEType' },
+    Meta => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Meta',
+            DirName => 'MIE-Meta',
+        },
+    },
+    data => {
+        Name => 'SubfileData',
+        Notes => 'the subfile data',
+        %binaryConv,
+    },
+    rsrc => {
+        Name => 'SubfileResource',
+        Notes => 'subfile resource fork if it exists',
+        %binaryConv,
+    },
+    zmd5 => {
+        Name => 'MD5Digest',
+        Notes => q{
+            16-byte MD5 digest written in binary form or as a 32-character hex-encoded
+            ASCII string. Value is an MD5 digest of the entire 0MIE group as it would be
+            with the digest value itself set to all null bytes
+        },
+    },
+    zmie => {
+        Name => 'TrailerSignature',
+        Writable => 'undef',
+        Notes => q{
+            used as the last element in the main "0MIE" group to identify a MIE trailer
+            when appended to another type of file.  ExifTool will create this tag if set
+            to any value, but always with an empty data block
+        },
+        ValueConvInv => '""',   # data block must be empty
+    },
+);
+
+# MIE meta information group
+%Image::ExifTool::MIE::Meta = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Meta', 2 => 'Image' },
+    WRITE_GROUP => 'MIE-Meta',
+    Audio => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Audio',
+            DirName => 'MIE-Audio',
+        },
+    },
+    Camera => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Camera',
+            DirName => 'MIE-Camera',
+        },
+    },
+    Document => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Doc',
+            DirName => 'MIE-Doc',
+        },
+    },
+    EXIF => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+            WriteProc => \&Image::ExifTool::WriteTIFF,
+        },
+    },
+    Geo => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Geo',
+            DirName => 'MIE-Geo',
+        },
+    },
+    ICCProfile  => {
+        Name => 'ICC_Profile',
+        SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' },
+    },
+    ID3  => { SubDirectory => { TagTable => 'Image::ExifTool::ID3::Main' } },
+    IPTC => { SubDirectory => { TagTable => 'Image::ExifTool::IPTC::Main' } },
+    Image => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Image',
+            DirName => 'MIE-Image',
+        },
+    },
+    MakerNotes => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::MakerNotes',
+            DirName => 'MIE-MakerNotes',
+        },
+    },
+    Preview => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Preview',
+            DirName => 'MIE-Preview',
+        },
+    },
+    Thumbnail => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Thumbnail',
+            DirName => 'MIE-Thumbnail',
+        },
+    },
+    Video => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Video',
+            DirName => 'MIE-Video',
+        },
+    },
+    XMP => { SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' } },
+);
+
+# MIE document information
+%Image::ExifTool::MIE::Doc = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Doc', 2 => 'Document' },
+    WRITE_GROUP => 'MIE-Doc',
+    NOTES => 'Information describing the main document, image or file.',
+    Author      => { Groups => { 2 => 'Author' } },
+    Comment     => { },
+    Contributors=> { Groups => { 2 => 'Author' }, List => 1 },
+    Copyright   => { Groups => { 2 => 'Author' } },
+    CreateDate  => { %dateInfo },
+    EMail       => { Groups => { 2 => 'Author' } },
+    Keywords    => { List => 1 },
+    ModifyDate  => { %dateInfo },
+    OriginalDate=> { Name => 'DateTimeOriginal', %dateInfo },
+    Phone       => { Name => 'PhoneNumber', Groups => { 2 => 'Author' } },
+    References  => { List => 1 },
+    Software    => { },
+    Title       => { },
+    URL         => { },
+);
+
+# MIE geographic information
+%Image::ExifTool::MIE::Geo = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Geo', 2 => 'Location' },
+    WRITE_GROUP => 'MIE-Geo',
+    NOTES => 'Information related to geographic location.',
+    Address     => { },
+    City        => { },
+    Country     => { },
+    GPS => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::GPS',
+            DirName => 'MIE-GPS',
+        },
+    },
+    PostalCode  => { },
+    State       => { Notes => 'state or province' },
+    UTM => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::UTM',
+            DirName => 'MIE-UTM',
+        },
+    },
+);
+
+# MIE GPS information
+%Image::ExifTool::MIE::GPS = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-GPS', 2 => 'Location' },
+    WRITE_GROUP => 'MIE-GPS',
+    Altitude   => {
+        Name => 'GPSAltitude',
+        Writable => 'rational64s',
+        Units => [ qw(m ft) ],
+        Notes => q{'m' above sea level unless 'ft' specified},
+    },
+    Bearing => {
+        Name => 'GPSDestBearing',
+        Writable => 'rational64s',
+        Units => [ qw(deg deg{mag}) ],
+        Notes => q{'deg' CW from true north unless 'deg{mag}' specified},
+    },
+    Datum   => { Name => 'GPSMapDatum', Notes => 'WGS-84 assumed if not specified' },
+    Differential => {
+        Name => 'GPSDifferential',
+        Writable => 'int8u',
+        PrintConv => {
+            0 => 'No Correction',
+            1 => 'Differential Corrected',
+        },
+    },
+    Distance => {
+        Name => 'GPSDestDistance',
+        Writable => 'rational64s',
+        Units => [ qw(km mi nmi) ],
+        Notes => q{'km' unless 'mi' or 'nmi' specified},
+    },
+    Heading  => {
+        Name => 'GPSTrack',
+        Writable => 'rational64s',
+        Units => [ qw(deg deg{mag}) ],
+        Notes => q{'deg' CW from true north unless 'deg{mag}' specified},
+    },
+    Latitude => {
+        Name => 'GPSLatitude',
+        Writable => 'rational64s',
+        Count => -1,
+        Notes => q{
+            1 to 3 numbers: degrees, minutes then seconds.  South latitudes are stored
+            as all negative numbers, but may be entered as positive numbers with a
+            trailing 'S' for convenience.  For example, these are all equivalent: "-40
+            -30", "-40.5", "40 30 0.00 S"
+        },
+        ValueConv    => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
+        ValueConvInv => 'Image::ExifTool::GPS::ToDMS($self, $val, 0)',
+        PrintConv    => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
+        PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
+    },
+    Longitude => {
+        Name => 'GPSLongitude',
+        Writable => 'rational64s',
+        Count => -1,
+        Notes => q{
+            1 to 3 numbers: degrees, minutes then seconds.  West longitudes are
+            negative, but may be entered as positive numbers with a trailing 'W'
+        },
+        ValueConv    => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
+        ValueConvInv => 'Image::ExifTool::GPS::ToDMS($self, $val, 0)',
+        PrintConv    => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
+        PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
+    },
+    MeasureMode => {
+        Name => 'GPSMeasureMode',
+        Writable => 'int8u',
+        PrintConv => { 2 => '2-D', 3 => '3-D' },
+    },
+    Satellites => 'GPSSatellites',
+    Speed => {
+        Name => 'GPSSpeed',
+        Writable => 'rational64s',
+        Units => [ qw(km/h mi/h m/s kn) ],
+        Notes => q{'km/h' unless 'mi/h', 'm/s' or 'kn' specified},
+    },
+    DateTime => { Name => 'GPSDateTime', %dateInfo },
+);
+
+# MIE UTM information
+%Image::ExifTool::MIE::UTM = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-UTM', 2 => 'Location' },
+    WRITE_GROUP => 'MIE-UTM',
+    Datum    => { Name => 'UTMMapDatum', Notes => 'WGS-84 assumed if not specified' },
+    Easting  => { Name => 'UTMEasting' },
+    Northing => { Name => 'UTMNorthing' },
+    Zone     => { Name => 'UTMZone', Writable => 'int8s' },
+);
+
+# MIE image information
+%Image::ExifTool::MIE::Image = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Image', 2 => 'Image' },
+    WRITE_GROUP => 'MIE-Image',
+   '0Type'          => { Name => 'FullSizeImageType', Notes => 'JPEG if not specified' },
+   '1Name'          => { Name => 'FullSizeImageName' },
+    BitDepth        => { Name => 'BitDepth', Writable => 'int16u' },
+    ColorSpace      => { Notes => 'standard ColorSpace values are "sRGB" and "Adobe RGB"' },
+    Components      => {
+        Name => 'ComponentsConfiguration',
+        Notes => 'string composed of R, G, B, Y, Cb and Cr',
+    },
+    Compression     => { Name => 'CompressionRatio', Writable => 'rational32u' },
+    ImageSize       => {
+        Writable => 'int16u',
+        Count => -1,
+        Notes => '2 or 3 values, for number of XY or XYZ pixels',
+        PrintConv => '$val=~tr/ /x/;$val',
+        PrintConvInv => '$val=~tr/x/ /;$val',
+    },
+    Resolution      => {
+        Writable => 'rational64u',
+        Units => [ qw(/in /cm /deg /arcmin /arcsec), '' ],
+        Count => -1,
+        Notes => q{
+            1 to 3 values.  A single value for equal resolution in all directions, or
+            separate X, Y and Z values if necessary.  Units are '/in' unless '/cm',
+            '/deg', '/arcmin', '/arcsec' or '' specified
+        },
+        PrintConv => '$val=~tr/ /x/;$val',
+        PrintConvInv => '$val=~tr/x/ /;$val',
+    },
+    data => {
+        Name => 'FullSizeImage',
+        %binaryConv,
+        ValueConv => '$self->ValidateImage(\$val,$tag)',
+        ValueConvInv => '$val',
+    },
+);
+
+# MIE preview image
+%Image::ExifTool::MIE::Preview = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Preview', 2 => 'Image' },
+    WRITE_GROUP => 'MIE-Preview',
+   '0Type'  => { Name => 'PreviewImageType', Notes => 'JPEG if not specified' },
+   '1Name'  => { Name => 'PreviewImageName' },
+    ImageSize => {
+        Name => 'PreviewImageSize',
+        Writable => 'int16u',
+        Count => -1,
+        Notes => '2 or 3 values, for number of XY or XYZ pixels',
+        PrintConv => '$val=~tr/ /x/;$val',
+        PrintConvInv => '$val=~tr/x/ /;$val',
+    },
+    data => {
+        Name => 'PreviewImage',
+        %binaryConv,
+        ValueConv => '$self->ValidateImage(\$val,$tag)',
+        ValueConvInv => '$val',
+    },
+);
+
+# MIE thumbnail image
+%Image::ExifTool::MIE::Thumbnail = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Thumbnail', 2 => 'Image' },
+    WRITE_GROUP => 'MIE-Thumbnail',
+   '0Type'  => { Name => 'ThumbnailImageType', Notes => 'JPEG if not specified' },
+   '1Name'  => { Name => 'ThumbnailImageName' },
+    ImageSize => {
+        Name => 'ThumbnailImageSize',
+        Writable => 'int16u',
+        Count => -1,
+        Notes => '2 or 3 values, for number of XY or XYZ pixels',
+        PrintConv => '$val=~tr/ /x/;$val',
+        PrintConvInv => '$val=~tr/x/ /;$val',
+    },
+    data => {
+        Name => 'ThumbnailImage',
+        %binaryConv,
+        ValueConv => '$self->ValidateImage(\$val,$tag)',
+        ValueConvInv => '$val',
+    },
+);
+
+# MIE audio information
+%Image::ExifTool::MIE::Audio = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Audio', 2 => 'Audio' },
+    WRITE_GROUP => 'MIE-Audio',
+    NOTES => q{
+        For the Audio group (and any other group containing a 'data' element), tags
+        refer to the contained data if present, otherwise they refer to the main
+        SubfileData.  The C<0Type> and C<1Name> elements should exist only if C<data>
+        is present.
+    },
+   '0Type'      => { Name => 'RelatedAudioFileType', Notes => 'MP3 if not specified' },
+   '1Name'      => { Name => 'RelatedAudioFileName' },
+    SampleBits  => { Writable => 'int16u' },
+    Channels    => { Writable => 'int8u' },
+    Compression => { Name => 'AudioCompression' },
+    Duration    => { Writable => 'rational64u' },
+    SampleRate  => { Writable => 'int32u' },
+    data        => { Name => 'RelatedAudioFile', %binaryConv },
+);
+
+# MIE video information
+%Image::ExifTool::MIE::Video = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Video', 2 => 'Video' },
+    WRITE_GROUP => 'MIE-Video',
+   '0Type'      => { Name => 'RelatedVideoFileType', Notes => 'MOV if not specified' },
+   '1Name'      => { Name => 'RelatedVideoFileName' },
+    Codec       => { },
+    Duration    => { Writable => 'rational64u' },
+    data        => { Name => 'RelatedVideoFile', %binaryConv },
+);
+
+# MIE camera information
+%Image::ExifTool::MIE::Camera = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Camera', 2 => 'Camera' },
+    WRITE_GROUP => 'MIE-Camera',
+    Brightness      => { Writable => 'int8s' },
+    ColorTemperature=> { Writable => 'int32u' },
+    ColorBalance    => {
+        Writable => 'rational64u',
+        Count => 3,
+        Notes => 'RGB scaling factors',
+    },
+    Contrast        => { Writable => 'int8s' },
+    DigitalZoom     => { Writable => 'rational64u' },
+    ExposureComp    => { Name => 'ExposureCompensation', Writable => 'rational64s' },
+    ExposureMode    => { },
+    ExposureTime    => {
+        Writable => 'rational64u',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    Flash => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Flash',
+            DirName => 'MIE-Flash',
+        },
+    },
+    FirmwareVersion => { },
+    FocusMode       => { },
+    ISO             => { Writable => 'int16u' },
+    ISOSetting      => {
+        Writable => 'int16u',
+        Notes => '0 = Auto, otherwise manual ISO speed setting',
+    },
+    ImageNumber     => { Writable => 'int32u' },
+    ImageQuality    => { Notes => 'Economy, Normal, Fine, Super Fine or Raw' },
+    ImageStabilization => { Writable => 'int8u', %offOn },
+    Lens => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Lens',
+            DirName => 'MIE-Lens',
+        },
+    },
+    Make            => { },
+    MeasuredEV      => { Writable => 'rational64s' },
+    Model           => { },
+    OwnerName       => { },
+    Orientation     => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Orient',
+            DirName => 'MIE-Orient',
+        },
+    },
+    Saturation      => { Writable => 'int8s' },
+    SensorSize      => {
+        Writable => 'rational64u',
+        Count => 2,
+        Notes => 'width and height of active sensor area in mm',
+    },
+    SerialNumber    => { },
+    Sharpness       => { Writable => 'int8s' },
+    ShootingMode    => { },
+);
+
+# Camera orientation information
+%Image::ExifTool::MIE::Orient = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Orient', 2 => 'Camera' },
+    WRITE_GROUP => 'MIE-Orient',
+    NOTES => 'These tags describe the camera orientation.',
+    Azimuth     => {
+        Writable => 'rational64s',
+        Units => [ qw(deg deg{mag}) ],
+        Notes => q{'deg' CW from true north unless 'deg{mag}' specified},
+    },
+    Declination => { Writable => 'rational64s' },
+    Elevation   => { Writable => 'rational64s' },
+    RightAscension => { Writable => 'rational64s' },
+    Rotation => {
+        Writable => 'rational64s',
+        Notes => 'CW rotation angle of camera about lens axis',
+    },
+);
+
+# MIE camera lens information
+%Image::ExifTool::MIE::Lens = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Lens', 2 => 'Camera' },
+    WRITE_GROUP => 'MIE-Lens',
+    NOTES => q{
+        All recorded lens parameters (focal length, aperture, etc) include the
+        effects of the extender if present.
+    },
+    Extender => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MIE::Extender',
+            DirName => 'MIE-Extender',
+        },
+    },
+    FNumber         => { Writable => 'rational64u' },
+    FocalLength     => { Writable => 'rational64u', Notes => 'all focal lengths in mm' },
+    FocusDistance   => {
+        Writable => 'rational64u',
+        Units => [ qw(m ft) ],
+        Notes => q{'m' unless 'ft' specified},
+    },
+    Make            => { Name => 'LensMake' },
+    MaxAperture     => { Writable => 'rational64u' },
+    MaxApertureAtMaxFocal => { Writable => 'rational64u' },
+    MaxFocalLength  => { Writable => 'rational64u' },
+    MinAperture     => { Writable => 'rational64u' },
+    MinFocalLength  => { Writable => 'rational64u' },
+    Model           => { Name => 'LensModel' },
+    OpticalZoom     => { Writable => 'rational64u' },
+    SerialNumber    => { Name => 'LensSerialNumber' },
+);
+
+# MIE lens extender information
+%Image::ExifTool::MIE::Extender = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Extender', 2 => 'Camera' },
+    WRITE_GROUP => 'MIE-Extender',
+    Magnification   => { Name => 'ExtenderMagnification', Writable => 'rational64s' },
+    Make            => { Name => 'ExtenderMake' },
+    Model           => { Name => 'ExtenderModel' },
+    SerialNumber    => { Name => 'ExtenderSerialNumber' },
+);
+
+# MIE camera flash information
+%Image::ExifTool::MIE::Flash = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-Flash', 2 => 'Camera' },
+    WRITE_GROUP => 'MIE-Flash',
+    ExposureComp    => { Name => 'FlashExposureComp', Writable => 'rational64s' },
+    Fired           => { Name => 'FlashFired', Writable => 'int8u', PrintConv => \%noYes },
+    GuideNumber     => { Name => 'FlashGuideNumber' },
+    Make            => { Name => 'FlashMake' },
+    Mode            => { Name => 'FlashMode' },
+    Model           => { Name => 'FlashModel' },
+    SerialNumber    => { Name => 'FlashSerialNumber' },
+    Type            => { Name => 'FlashType', Notes => '"Internal" or "External"' },
+);
+
+# MIE maker notes information
+%Image::ExifTool::MIE::MakerNotes = (
+    %tableDefaults,
+    GROUPS => { 1 => 'MIE-MakerNotes' },
+    WRITE_GROUP => 'MIE-MakerNotes',
+    NOTES => q{
+        MIE maker notes are contained within separate groups for each manufacturer
+        to avoid name conflicts.  Currently no specific manufacturer information has
+        been defined.
+    },
+    Canon       => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
+    Casio       => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
+    FujiFilm    => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
+    Kodak       => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
+    KonicaMinolta=>{ SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
+    Nikon       => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
+    Olympus     => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
+    Panasonic   => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
+    Pentax      => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
+    Ricoh       => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
+    Sigma       => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
+    Sony        => { SubDirectory => { TagTable => 'Image::ExifTool::MIE::Unknown' } },
+);
+
+%Image::ExifTool::MIE::Unknown = (
+    PROCESS_PROC => \&ProcessMIE,
+    GROUPS => { 1 => 'MIE-Unknown' },
+);
+
+#------------------------------------------------------------------------------
+# Add user-defined MIE groups to %mieMap
+# Inputs: none;  Returns: nothing, but sets $doneMieMap flag
+sub UpdateMieMap()
+{
+    $doneMieMap = 1;    # set flag so we only do this once
+    return unless %Image::ExifTool::UserDefined;
+    my ($tableName, @tables, %doneTable, $tagID);
+    # get list of top-level MIE tables with user-defined tags
+    foreach $tableName (keys %Image::ExifTool::UserDefined) {
+        next unless $tableName =~ /^Image::ExifTool::MIE::/;
+        my $userTable = $Image::ExifTool::UserDefined{$tableName};
+        my $tagTablePtr = GetTagTable($tableName) or next;
+        # copy the WRITE_GROUP from the actual table
+        $$userTable{WRITE_GROUP} = $$tagTablePtr{WRITE_GROUP};
+        # add to list of tables to process
+        $doneTable{$tableName} = 1;
+        push @tables, [$tableName, $userTable];
+    }
+    # recursively add all user-defined groups to MIE map
+    while (@tables) {
+        my ($tableName, $tagTablePtr) = @{shift @tables};
+        my $parent = $$tagTablePtr{WRITE_GROUP};
+        $parent or warn("No WRITE_GROUP for $tableName\n"), next;
+        $mieMap{$parent} or warn("$parent is not in MIE map\n"), next;
+        foreach $tagID (TagTableKeys($tagTablePtr)) {
+            my $tagInfo = $$tagTablePtr{$tagID};
+            next unless ref $tagInfo eq 'HASH' and $$tagInfo{SubDirectory};
+            my $subTableName = $tagInfo->{SubDirectory}->{TagTable};
+            my $subTablePtr = GetTagTable($subTableName) or next;
+            # only care about MIE tables
+            next unless $$subTablePtr{PROCESS_PROC} and
+                        $$subTablePtr{PROCESS_PROC} eq \&ProcessMIE;
+            my $group = $$subTablePtr{WRITE_GROUP};
+            $group or warn("No WRITE_GROUP for $subTableName\n"), next;
+            if ($mieMap{$group} and $mieMap{$group} ne $parent) {
+                warn("$group already has different parent ($mieMap{$group})\n"), next;
+            }
+            $mieMap{$group} = $parent;  # add to map
+            # process tables within this one too
+            $doneTable{$subTableName} and next;
+            $doneTable{$subTableName} = 1;
+            push @tables, [$subTableName, $subTablePtr];
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# Get localized version of tagInfo hash
+# Inputs: 0) tagInfo hash ref, 1) locale code (ie. "en_CA")
+# Returns: new tagInfo hash ref, or undef if invalid
+sub GetLangInfo($$)
+{
+    my ($tagInfo, $langCode) = @_;
+    # check for properly formatted language code
+    return undef unless $langCode =~ /^[a-z]{2}([-_])[A-Z]{2}$/;
+    # use '_' as a separator, but recognize '_' or '-'
+    $langCode =~ tr/-/_/ if $1 eq '-';
+    # can only set locale on string types
+    return undef if $$tagInfo{Writable} and $$tagInfo{Writable} ne 'string';
+    return Image::ExifTool::GetLangInfo($tagInfo, $langCode);
+}
+
+#------------------------------------------------------------------------------
+# return true if we have Zlib::Compress
+# Inputs: 0) ExifTool object ref, 1) verb for what you want to do with the info
+# Returns: 1 if Zlib available, 0 otherwise
+sub HasZlib($$)
+{
+    unless (defined $hasZlib) {
+        $hasZlib = eval 'require Compress::Zlib';
+        unless ($hasZlib) {
+            $hasZlib = 0;
+            $_[0]->Warn("Install Compress::Zlib to $_[1] compressed information");
+        }
+    }
+    return $hasZlib;
+}
+
+#------------------------------------------------------------------------------
+# Get format code for MIE group element with current byte order
+# Inputs: 0) [optional] true to convert result to chr()
+# Returns: format code
+sub MIEGroupFormat(;$)
+{
+    my $chr = shift;
+    my $format = GetByteOrder() eq 'MM' ? 0x10 : 0x18;
+    return $chr ? chr($format) : $format;
+}
+
+#------------------------------------------------------------------------------
+# Does a string contain valid UTF-8 characters?
+# Inputs: 0) string
+# Returns: 0=regular ASCII, -1=invalid UTF-8, 1=valid UTF-8 with maximum 16-bit
+#          wide characters, 2=valid UTF-8 requiring 32-bit wide characters
+# Notes: Changes current string position
+sub IsUTF8($)
+{
+    my $rtnVal = 0;
+    pos($_[0]) = 0; # start at beginning of string
+    for (;;) {
+        last unless $_[0] =~ /([\x80-\xff])/g;
+        my $ch = ord($1);
+        # minimum lead byte for 2-byte sequence is 0xc2 (overlong sequences
+        # not allowed), 0xf8-0xfd are restricted by RFC 3629 (no 5 or 6 byte
+        # sequences), and 0xfe and 0xff are not valid in UTF-8 strings
+        return -1 if $ch < 0xc2 or $ch >= 0xf8;
+        # determine number of bytes remaining in sequence
+        my $n = 1;
+        $n += ($ch >= 0xf0) ? 2 : 1 if $ch >= 0xe0;
+        return -1 unless $_[0] =~ /\G[\x80-\xbf]{$n}/g;
+        # character code is greater than 0xffff if more than 2 extra bytes were
+        # required in the UTF-8 character
+        $rtnVal |= ($n > 2) ? 2 : 1;
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# ReadValue() with added support for UTF formats (utf8, utf16 and utf32)
+# Inputs: 0) data reference, 1) value offset, 2) format string,
+#         3) number of values (or undef to use all data)
+#         4) valid data length relative to offset
+# Returns: converted value, or undefined if data isn't there
+#          or list of values in list context
+sub ReadMIEValue($$$$$)
+{
+    my ($dataPt, $offset, $format, $count, $size) = @_;
+    my $val;
+    if ($format =~ /^utf(8|16|32)/) {
+        if ($1 == 8) {
+            # return UTF8 string
+            $val = substr($$dataPt, $offset, $size);
+        } else {
+            # convert to UTF8
+            my $fmt;
+            if (GetByteOrder() eq 'MM') {
+                $fmt = ($1 == 16) ? 'n' : 'N';
+            } else {
+                $fmt = ($1 == 16) ? 'v' : 'V';
+            }
+            my @unpk = unpack("x$offset$fmt$size",$$dataPt);
+            if ($] >= 5.006001) {
+                $val = pack('C0U*', @unpk);
+            } else {
+                $val = Image::ExifTool::PackUTF8(@unpk);
+            }
+        }
+        # truncate at null unless this is a list
+        $val =~ s/\0.*//s unless $format =~ /_list$/;
+        return $val;
+    } else {
+        # don't modify string lists
+        $format = 'undef' if $format eq 'string_list' or $format eq 'free';
+        return ReadValue($dataPt, $offset, $format, $count, $size);
+    }
+}
+
+#------------------------------------------------------------------------------
+# validate raw values for writing
+# Inputs: 0) ExifTool object ref, 1) tagInfo hash ref, 2) raw value ref
+# Returns: error string or undef (and possibly changes value) on success
+sub CheckMIE($$$)
+{
+    my ($exifTool, $tagInfo, $valPtr) = @_;
+    my $format = $$tagInfo{Writable} || $tagInfo->{Table}->{WRITABLE};
+    my $err;
+
+    return 'No writable format' if not $format or $format eq '1';
+    # handle units if supported by this tag
+    my $ulist = $$tagInfo{Units};
+    if ($ulist and $$valPtr =~ /(.*)\((.*)\)$/) {
+        my ($val, $units) = ($1, $2);
+        ($units) = grep /^$units$/i, @$ulist;
+        defined $units or return 'Allowed units: (' . join('|', @$ulist) . ')';
+        $err = Image::ExifTool::CheckValue(\$val, $format, $$tagInfo{Count});
+        # add units back onto value
+        $$valPtr = "$val($units)" unless $err;
+    } elsif ($format !~ /^(utf|string|undef)/ and $$valPtr =~ /\)$/) {
+        return 'Units not supported';
+    } else {
+        $err = Image::ExifTool::CheckValue($valPtr, $format, $$tagInfo{Count});
+    }
+    return $err;
+}
+
+#------------------------------------------------------------------------------
+# Rewrite a MIE directory
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) tag table ptr
+# Returns: undef on success, otherwise error message (empty message if nothing to write)
+sub WriteMIEGroup($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $outfile = $$dirInfo{OutFile};
+    my $dirName = $$dirInfo{DirName};
+    my $toWrite = $$dirInfo{ToWrite} || '';
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->Options('Verbose');
+    my $optCompress = $exifTool->Options('Compress');
+    my $out = $exifTool->Options('TextOut');
+    my ($msg, $err, $ok, $sync, $delGroup);
+    my $tag = '';
+    my $deletedTag = '';
+
+    # count each MIE directory found and make name for this specific instance
+    my ($grp1, %isWriting);
+    my $cnt = $exifTool->{MIE_COUNT};
+    my $grp = $tagTablePtr->{GROUPS}->{1};
+    my $n = $$cnt{'MIE-Main'} || 0;
+    if ($grp eq 'MIE-Main') {
+        $$cnt{$grp} = ++$n;
+        ($grp1 = $grp) =~ s/MIE-/MIE$n-/;
+    } else {
+        ($grp1 = $grp) =~ s/MIE-/MIE$n-/;
+        my $m = $$cnt{$grp1} = ($$cnt{$grp1} || 0) + 1;
+        $isWriting{"$grp$m"} = 1;   # ie. 'MIE-Doc2'
+        $isWriting{$grp1} = 1;      # ie. 'MIE1-Doc'
+        $grp1 .= $m;
+    }
+    # build lookup for all valid group names for this MIE group
+    $isWriting{$grp} = 1;           # ie. 'MIE-Doc'
+    $isWriting{$grp1} = 1;          # ie. 'MIE1-Doc2'
+    $isWriting{"MIE$n"} = 1;        # ie. 'MIE1'
+
+    # determine if we are deleting this group
+    if (%{$exifTool->{DEL_GROUP}}) {
+        $delGroup = 1 if $exifTool->{DEL_GROUP}->{MIE} or
+                         $exifTool->{DEL_GROUP}->{$grp} or
+                         $exifTool->{DEL_GROUP}->{$grp1} or
+                         $exifTool->{DEL_GROUP}->{"MIE$n"};
+    }
+
+    # prepare lookups and lists for writing
+    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+    my ($addDirs, $editDirs) = $exifTool->GetAddDirHash($tagTablePtr, $dirName);
+    my @editTags = sort keys %$newTags, keys %$editDirs;
+    $verbose and print $out $raf ? 'Writing' : 'Creating', " $grp1:\n";
+
+    # loop through elements in MIE group
+    MieElement: for (;;) {
+        my ($format, $tagLen, $valLen, $units, $oldHdr, $buff);
+        my $lastTag = $tag;
+        if ($raf) {
+            # read first 4 bytes of element header
+            my $n = $raf->Read($oldHdr, 4);
+            if ($n != 4) {
+                last if $n or defined $sync;
+                undef $raf; # all done reading
+                $ok = 1;
+            }
+        }
+        if ($raf) {
+            ($sync, $format, $tagLen, $valLen) = unpack('aC3', $oldHdr);
+            $sync eq '~' or $msg = 'Invalid sync byte', last;
+
+            # read tag name
+            if ($tagLen) {
+                $raf->Read($tag, $tagLen) == $tagLen or last;
+                $oldHdr .= $tag;    # add tag to element header
+                $exifTool->Warn("MIE tag '$tag' out of sequence") if $tag lt $lastTag;
+                # separate units from tag name if they exist
+                $units = $1 if $tag =~ s/\((.*)\)$//;
+            } else {
+                $tag = '';
+            }
+
+            # get multi-byte value length if necessary
+            if ($valLen > 252) {
+                # calculate number of bytes in extended DataLength
+                my $n = 1 << (256 - $valLen);
+                $raf->Read($buff, $n) == $n or last;
+                $oldHdr .= $buff;   # add to old header
+                my $fmt = 'int' . ($n * 8) . 'u';
+                $valLen = ReadValue(\$buff, 0, $fmt, 1, $n);
+                if ($valLen > 0x7fffffff) {
+                    $msg = "Can't write $tag (DataLength > 2GB not yet supported)";
+                    last;
+                }
+            }
+            # don't rewrite free bytes or information in deleted groups
+            if ($format eq 0x80 or ($delGroup and $tagLen and ($format & 0xf0) != 0x10)) {
+                $raf->Seek($valLen, 1) or $msg = 'Seek error', last;
+                if ($verbose > 1) {
+                    my $free = ($format eq 0x80) ? ' free' : '';
+                    print $out "    - $grp1:$tag ($valLen$free bytes)\n";
+                }
+                ++$exifTool->{CHANGED} if $delGroup;
+                next;
+            }
+        } else {
+            # no more elements to read
+            $tagLen = $valLen = 0;
+            $tag = '';
+        }
+#
+# write necessary new tags and process directories
+#
+        while (@editTags) {
+            last if $tagLen and $editTags[0] gt $tag;
+            # we are writing the new tag now
+            my ($newVal, $writable, $oldVal, $newFormat, $compress);
+            my $newTag = shift @editTags;
+            my $newInfo = $$editDirs{$newTag};
+            if ($newInfo) {
+                # create the new subdirectory or rewrite existing non-MIE directory
+                my $subTablePtr = GetTagTable($newInfo->{SubDirectory}->{TagTable});
+                unless ($subTablePtr) {
+                    $exifTool->Warn("No tag table for $newTag $$newInfo{Name}");
+                    next;
+                }
+                my %subdirInfo;
+                my $isMieGroup = ($$subTablePtr{WRITE_PROC} and
+                                  $$subTablePtr{WRITE_PROC} eq \&ProcessMIE);
+
+                if ($newTag eq $tag) {
+                    # make sure that either both or neither old and new tags are MIE groups
+                    if ($isMieGroup xor ($format & 0xf3) == 0x10) {
+                        $exifTool->Warn("Tag '$tag' not expected type");
+                        next;   # don't write our new tag
+                    }
+                    # uncompress existing directory into $oldVal since we are editing it
+                    if ($format & 0x04) {
+                        last unless HasZlib($exifTool, 'edit');
+                        $raf->Read($oldVal, $valLen) == $valLen or last MieElement;
+                        my $stat;
+                        my $inflate = Compress::Zlib::inflateInit();
+                        $inflate and ($oldVal, $stat) = $inflate->inflate($oldVal);
+                        unless ($inflate and $stat == Compress::Zlib::Z_STREAM_END()) {
+                            $msg = "Error inflating $tag";
+                            last MieElement;
+                        }
+                        $compress = 1;
+                        $valLen = length $oldVal;    # uncompressed value length
+                    }
+                } else {
+                    # don't create this directory unless necessary
+                    next unless $$addDirs{$newTag};
+                }
+
+                if ($isMieGroup) {
+                    my $hdr;
+                    if ($newTag eq $tag) {
+                        # rewrite existing directory later unless it was compressed
+                        last unless $compress;
+                        # rewrite directory to '$newVal'
+                        $newVal = '';
+                        %subdirInfo = (
+                            OutFile => \$newVal,
+                            RAF => new File::RandomAccess(\$oldVal),
+                        );
+                    } elsif ($optCompress and not $$dirInfo{IsCompressed}) {
+                        # write to memory so we can compress the new MIE group
+                        $compress = 1;
+                        %subdirInfo = (
+                            OutFile => \$newVal,
+                        );
+                    } else {
+                        $hdr = '~' . MIEGroupFormat(1) . chr(length($newTag)) .
+                               "\0" . $newTag;
+                        %subdirInfo = (
+                            OutFile => $outfile,
+                            ToWrite => $toWrite . $hdr,
+                        );
+                    }
+                    $subdirInfo{DirName} = $newInfo->{SubDirectory}->{DirName} || $newTag;
+                    $subdirInfo{Parent} = $dirName;
+                    # don't compress elements of an already compressed group
+                    $subdirInfo{IsCompressed} = 1;
+                    $msg = WriteMIEGroup($exifTool, \%subdirInfo, $subTablePtr);
+                    last MieElement if $msg;
+                    # message is defined but empty if nothing was written
+                    if (defined $msg) {
+                        undef $msg; # not a problem if nothing was written
+                        next;
+                    } elsif (not $compress) {
+                        # group was written already
+                        $toWrite = '';
+                        next;
+                    }
+                    $writable = 'undef';
+                    $newFormat = MIEGroupFormat();
+                } else {
+                    if ($newTag eq $tag) {
+                        unless ($compress) {
+                            # read and edit existing directory
+                            $raf->Read($oldVal, $valLen) == $valLen or last MieElement;
+                        }
+                        %subdirInfo = (
+                            DataPt => \$oldVal,
+                            DataLen => $valLen,
+                            DirName => $$newInfo{Name},
+                            DataPos => $raf->Tell() - $valLen,
+                            DirStart => 0,
+                            DirLen => $valLen,
+                        );
+                    }
+                    $subdirInfo{Parent} = $dirName;
+                    my $writeProc = $newInfo->{SubDirectory}->{WriteProc};
+                    $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTablePtr, $writeProc);
+                    if (defined $newVal) {
+                        if ($newVal eq '') {
+                            next MieElement if $newTag eq $tag; # deleting the directory
+                            next;       # not creating the new directory
+                        }
+                    } else {
+                        next unless defined $oldVal;
+                        $newVal = $oldVal;  # just copy over the old directory
+                    }
+                    $writable = 'undef';
+                    $newFormat = 0x00;  # all other directories are 'undef' format
+                }
+            } else {
+
+                # get the new tag information
+                $newInfo = $$newTags{$newTag};
+                my $newValueHash = $exifTool->GetNewValueHash($newInfo);
+                my @newVals;
+
+                # write information only to specified group
+                my $writeGroup = $$newValueHash{WriteGroup};
+                last unless $isWriting{$writeGroup};
+
+                # if tag existed, must decide if we want to overwrite the value
+                if ($newTag eq $tag) {
+                    my $isOverwriting;
+                    my $isList = $$newInfo{List};
+                    if ($isList) {
+                        $isOverwriting = -1;    # force processing list elements individually
+                    } else {
+                        $isOverwriting = Image::ExifTool::IsOverwriting($newValueHash);
+                        last unless $isOverwriting;
+                    }
+                    my ($val, $cmpVal);
+                    if ($isOverwriting < 0 or $verbose > 1) {
+                        # check to be sure we can uncompress the value if necessary
+                        HasZlib($exifTool, 'edit') or last if $format & 0x04;
+                        # read the old value
+                        $raf->Read($oldVal, $valLen) == $valLen or last MieElement;
+                        # uncompress if necessary
+                        if ($format & 0x04) {
+                            my $stat;
+                            my $inflate = Compress::Zlib::inflateInit();
+                            # must save original compressed value in case we decide
+                            # not to overwrite it later
+                            $cmpVal = $oldVal;
+                            $inflate and ($oldVal, $stat) = $inflate->inflate($oldVal);
+                            unless ($inflate and $stat == Compress::Zlib::Z_STREAM_END()) {
+                                $msg = "Error inflating $tag";
+                                last MieElement;
+                            }
+                            $valLen = length $oldVal;    # update value length
+                        }
+                        # convert according to specified format
+                        my $formatStr = $mieFormat{$format & 0xfb} || 'undef';
+                        $val = ReadMIEValue(\$oldVal, 0, $formatStr, undef, $valLen);
+                        if ($isOverwriting < 0 and defined $val) {
+                            # handle list values individually
+                            if ($isList) {
+                                my (@vals, $v);
+                                if ($formatStr =~ /_list$/) {
+                                    @vals = split "\0", $val;
+                                } else {
+                                    @vals = $val;
+                                }
+                                # keep any list items that we aren't overwriting
+                                foreach $v (@vals) {
+                                    next if Image::ExifTool::IsOverwriting($newValueHash, $v);
+                                    push @newVals, $v;
+                                }
+                            } else {
+                                # test to see if we really want to overwrite the value
+                                $isOverwriting = Image::ExifTool::IsOverwriting($newValueHash, $val);
+                            }
+                        }
+                    }
+                    if ($isOverwriting) {
+                        # skip the old value if we didn't read it already
+                        unless (defined $oldVal) {
+                            $raf->Seek($valLen, 1) or $msg = 'Seek error';
+                        }
+                        if ($verbose > 1) {
+                            $val .= "($units)" if defined $units;
+                            $val = $exifTool->Printable($val);
+                            print $out "    - $grp1:$$newInfo{Name} = '$val'\n";
+                        }
+                        $deletedTag = $tag;     # remember that we deleted this tag
+                        ++$exifTool->{CHANGED}; # we deleted the old value
+                    } else {
+                        if (defined $oldVal) {
+                            # write original compressed value
+                            $oldVal = $cmpVal if defined $cmpVal;
+                        } else {
+                            $raf->Read($oldVal, $valLen) == $valLen or last MieElement;
+                        }
+                        # write the old value now
+                        Write($outfile, $toWrite, $oldHdr, $oldVal) or $err = 1;
+                        $toWrite = '';
+                    }
+                    unless (@newVals) {
+                        # unshift the new tag info to write it later
+                        unshift @editTags, $newTag;
+                        next MieElement;    # get next element from file
+                    }
+                } else {
+                    # write new value if creating, or if List and list existed, or
+                    # if tag was previously deleted
+                    next unless Image::ExifTool::IsCreating($newValueHash) or
+                        ($newTag eq $lastTag and ($$newInfo{List} or $deletedTag eq $lastTag));
+                }
+                # get the new value to write (undef to delete)
+                push @newVals, Image::ExifTool::GetNewValues($newValueHash);
+                next unless @newVals;
+                $writable = $$newInfo{Writable} || $$tagTablePtr{WRITABLE};
+                if ($writable eq 'string') {
+                    # join multiple values into a single string
+                    $newVal = join "\0", @newVals;
+                    # write string as UTF-8,16 or 32 if value contains valid UTF-8 codes
+                    my $isUTF8 = IsUTF8($newVal);
+                    if ($isUTF8 > 0) {
+                        $writable = 'utf8';
+                        # write UTF-16 or UTF-32 if it is more compact
+                        # (only if Perl version is 5.6.1 or greater)
+                        if ($] >= 5.006001) {
+                            # pack with current byte order
+                            my $pk = (GetByteOrder() eq 'MM') ? 'n' : 'v';
+                            $pk = uc($pk) if $isUTF8 > 1;
+                            # translate to utf16 or utf32
+                            my $tmp = pack("$pk*",unpack('U0U*',$newVal));
+                            if (length $tmp < length $newVal) {
+                                $newVal = $tmp;
+                                $writable = ($isUTF8 > 1) ? 'utf32' : 'utf16';
+                            }
+                        }
+                    }
+                    # write as a list if we have multiple values
+                    $writable .= '_list' if @newVals > 1;
+                } else {
+                    # should only be one element in the list
+                    $newVal = shift @newVals;
+                }
+                $newFormat = $mieCode{$writable};
+                unless (defined $newFormat) {
+                    $msg = "Bad format '$writable' for $$newInfo{Name}";
+                    next MieElement;
+                }
+            }
+
+            # write the new or edited element
+            while (defined $newFormat) {
+                my $valPt = \$newVal;
+                # remove units from value and add to tag name if supported by this tag
+                if ($$newInfo{Units}) {
+                    my $val2;
+                    if ($$valPt =~ /(.*)\((.*)\)$/) {
+                        $val2 = $1;
+                        $newTag .= "($2)";
+                    } else {
+                        $val2 = $$valPt;
+                        # add default units
+                        my $ustr = '(' . $newInfo->{Units}->[0] . ')';
+                        $newTag .= $ustr;
+                        $$valPt .= $ustr;
+                    }
+                    $valPt = \$val2;
+                }
+                # convert value if necessary
+                if ($writable !~ /^(utf|string|undef)/) {
+                    my $val3 = WriteValue($$valPt, $writable, $$newInfo{Count});
+                    defined $val3 or $exifTool->Warn("Error writing $newTag"), last;
+                    $valPt = \$val3;
+                }
+                my $len = length $$valPt;
+                # compress value before writing if required
+                if (($compress or $optCompress) and not $$dirInfo{IsCompressed} and
+                    HasZlib($exifTool, 'write'))
+                {
+                    my $deflate = Compress::Zlib::deflateInit();
+                    my $val4;
+                    if ($deflate) {
+                        $val4 = $deflate->deflate($$valPt);
+                        $val4 .= $deflate->flush() if defined $val4;
+                    }
+                    if (defined $val4) {
+                        my $len4 = length $val4;
+                        my $saved = $len - $len4;
+                        # only use compressed data if it is smaller
+                        if ($saved > 0) {
+                            $verbose and print $out "  [$newTag compression saved $saved bytes]\n";
+                            $newFormat |= 0x04; # set compressed bit
+                            $len = $len4;       # set length
+                            $valPt = \$val4;    # set value pointer
+                        } elsif ($verbose) {
+                            print $out "  [$newTag compression saved $saved bytes -- written uncompressed]\n";
+                        }
+                    } else {
+                        $exifTool->Warn("Error deflating $newTag (written uncompressed)");
+                    }
+                }
+                # calculate the DataLength code
+                my $extLen;
+                if ($len < 253) {
+                    $extLen = '';
+                } elsif ($len < 65536) {
+                    $extLen = Set16u($len);
+                    $len = 255;
+                } elsif ($len <= 0x7fffffff) {
+                    $extLen = Set32u($len);
+                    $len = 254;
+                } else {
+                    $exifTool->Warn("Can't write $newTag (DataLength > 2GB not yet suppported)");
+                    last; # don't write this tag
+                }
+                # write this element (with leading MIE group element if not done already)
+                my $hdr = $toWrite . '~' . chr($newFormat) . chr(length $newTag);
+                Write($outfile, $hdr, chr($len), $newTag, $extLen, $$valPt) or $err = 1;
+                $toWrite = '';
+                if ($verbose > 1 and not $$editDirs{$newTag}) {
+                    $newVal = $exifTool->Printable($newVal);
+                    print $out "    + $grp1:$$newInfo{Name} = '$newVal'\n";
+                }
+                ++$exifTool->{CHANGED};
+                last;   # didn't want to loop anyway
+            }
+            next MieElement if defined $oldVal;
+        }
+#
+# rewrite existing element or descend into uncompressed MIE group
+#
+        # all done this MIE group if we reached the terminator element
+        unless ($tagLen) {
+            # skip over existing terminator data (if any)
+            last if $valLen and not $raf->Seek($valLen, 1);
+            $ok = 1;
+            # write group terminator if necessary
+            unless ($toWrite) {
+                # write end-of-group terminator element
+                my $term = "~\0\0\0";
+                unless ($$dirInfo{Parent}) {
+                    # write extended terminator for file-level group
+                    my $len = ref $outfile eq 'SCALAR' ? length($$outfile) : tell $outfile;
+                    $len += 10; # include length of terminator itself
+                    if ($len and $len <= 0x7fffffff) {
+                        $term = "~\0\0\x06" . Set32u($len) . MIEGroupFormat(1) . "\x04";
+                    }
+                }
+                Write($outfile, $term) or $err = 1;
+            }
+            last;
+        }
+
+        # descend into existing uncompressed MIE group
+        if ($format == 0x10 or $format == 0x18) {
+            my ($subTablePtr, $dirName);
+            my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+            if ($tagInfo and $$tagInfo{SubDirectory}) {
+                $dirName = $tagInfo->{SubDirectory}->{DirName};
+                my $subTable = $tagInfo->{SubDirectory}->{TagTable};
+                $subTablePtr = $subTable ? GetTagTable($subTable) : $tagTablePtr;
+            } else {
+                $subTablePtr = GetTagTable('Image::ExifTool::MIE::Unknown');
+            }
+            my $hdr = '~' . chr($format) . chr(length $tag) . "\0" . $tag;
+            my %subdirInfo = (
+                DirName => $dirName || $tag,
+                RAF     => $raf,
+                ToWrite => $toWrite . $hdr,
+                OutFile => $outfile,
+                Parent  => $dirName,
+                IsCompressed => $$dirInfo{IsCompressed},
+            );
+            my $oldOrder = GetByteOrder();
+            SetByteOrder($format & 0x08 ? 'II' : 'MM');
+            $msg = WriteMIEGroup($exifTool, \%subdirInfo, $subTablePtr);
+            SetByteOrder($oldOrder);
+            last if $msg;
+            if (defined $msg) {
+                undef $msg; # no problem if nothing written
+            } else {
+                $toWrite = '';
+            }
+            next;
+        }
+        # just copy existing element
+        my $oldVal;
+        $raf->Read($oldVal, $valLen) == $valLen or last;
+        if ($toWrite) {
+            Write($outfile, $toWrite) or $err = 1;
+            $toWrite = '';
+        }
+        Write($outfile, $oldHdr, $oldVal) or $err = 1;
+    }
+    # return error message
+    if ($err) {
+        $msg = 'Error writing file';
+    } elsif (not $ok and not $msg) {
+        $msg = 'Unexpected end of file';
+    } elsif (not $msg and $toWrite) {
+        $msg = '';  # flag for nothing written
+        $verbose and print $out "Deleted $grp1 (empty)\n";
+    }
+    return $msg;
+}
+
+#------------------------------------------------------------------------------
+# Process MIE directory
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) tag table ref
+# Returns: undef on success, or error message if there was a problem
+# Notes: file pointer is positioned at the MIE end on entry
+sub ProcessMIEGroup($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my ($msg, $buff, $ok, $oldIndent, $mime);
+    my $lastTag = '';
+
+    # get group 1 names: $grp doesn't have numbers (ie. 'MIE-Doc'),
+    # and $grp1 does (ie. 'MIE1-Doc1')
+    my $cnt = $exifTool->{MIE_COUNT};
+    my $grp1 = $tagTablePtr->{GROUPS}->{1};
+    my $n = $$cnt{'MIE-Main'} || 0;
+    if ($grp1 eq 'MIE-Main') {
+        $$cnt{$grp1} = ++$n;
+        $grp1 =~ s/MIE-/MIE$n-/ if $n > 1;
+    } else {
+        $grp1 =~ s/MIE-/MIE$n-/ if $n > 1;
+        $$cnt{$grp1} = ($$cnt{$grp1} || 0) + 1;
+        $grp1 .= $$cnt{$grp1} if $$cnt{$grp1} > 1;
+    }
+    # set group1 name for all tags extracted from this group
+    $exifTool->{SET_GROUP1} = $grp1;
+
+    if ($verbose) {
+        $oldIndent = $exifTool->{INDENT};
+        $exifTool->{INDENT} .= '| ';
+        $exifTool->VerboseDir($grp1);
+    }
+
+    # process all MIE elements
+    for (;;) {
+        $raf->Read($buff, 4) == 4 or last;
+        my ($sync, $format, $tagLen, $valLen) = unpack('aC3', $buff);
+        $sync eq '~' or $msg = 'Invalid sync byte', last;
+
+        # read tag name
+        my ($tag, $units);
+        if ($tagLen) {
+            $raf->Read($tag, $tagLen) == $tagLen or last;
+            $exifTool->Warn("MIE tag '$tag' out of sequence") if $tag lt $lastTag;
+            $lastTag = $tag;
+            # separate units from tag name if they exist
+            $units = $1 if $tag =~ s/\((.*)\)$//;
+        } else {
+            $tag = '';
+        }
+
+        # get multi-byte value length if necessary
+        if ($valLen > 252) {
+            my $n = 1 << (256 - $valLen);
+            $raf->Read($buff, $n) == $n or last;
+            my $fmt = 'int' . ($n * 8) . 'u';
+            $valLen = ReadValue(\$buff, 0, $fmt, 1, $n);
+            if ($valLen > 0x7fffffff) {
+                $msg = "Can't read $tag (DataLength > 2GB not yet supported)";
+                last;
+            }
+        }
+
+        # all done if we reached the group terminator
+        unless ($tagLen) {
+            # skip over terminator data block
+            $ok = 1 unless $valLen and not $raf->Seek($valLen, 1);
+            last;
+        }
+
+        # get tag information hash unless this is free space
+        my ($tagInfo, $value);
+        while ($format != 0x80) {
+            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+            last if $tagInfo;
+            # extract tags with locale code
+            if ($tag =~ /\W/) {
+                if ($tag =~ /^(\w+)-([a-z]{2}_[A-Z]{2})$/) {
+                    my ($baseTag, $langCode) = ($1, $2);
+                    $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $baseTag);
+                    $tagInfo = GetLangInfo($tagInfo, $langCode) if $tagInfo;
+                    last if $tagInfo;
+                } else {
+                    $exifTool->Warn('Invalid MIE tag name');
+                    last;
+                }
+            }
+            # extract unknown tags if specified
+            $tagInfo = {
+                Name => $tag,
+                Writable => 0,
+                PrintConv => 'length($val) > 60 ? substr($val,0,55) . "[...]" : $val',
+            };
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            last;
+        }
+
+        # read value and uncompress if necessary
+        my $formatStr = $mieFormat{$format & 0xfb} || 'undef';
+        if ($tagInfo or ($formatStr eq 'MIE' and $format & 0x04)) {
+            $raf->Read($value, $valLen) == $valLen or last;
+            if ($format & 0x04) {
+                if ($verbose) {
+                    print $out "$$exifTool{INDENT}\[Tag '$tag' $valLen bytes compressed]\n";
+                }
+                next unless HasZlib($exifTool, 'decode');
+                my $stat;
+                my $inflate = Compress::Zlib::inflateInit();
+                $inflate and ($value, $stat) = $inflate->inflate($value);
+                unless ($inflate and $stat == Compress::Zlib::Z_STREAM_END()) {
+                    $exifTool->Warn("Error inflating $tag");
+                    next;
+                }
+                $valLen = length $value;
+            }
+        }
+
+        # process this tag
+        if ($formatStr eq 'MIE') {
+            # process MIE directory
+            my ($subTablePtr, $dirName);
+            if ($tagInfo and $$tagInfo{SubDirectory}) {
+                $dirName = $tagInfo->{SubDirectory}->{DirName};
+                my $subTable = $tagInfo->{SubDirectory}->{TagTable};
+                $subTablePtr = $subTable ? GetTagTable($subTable) : $tagTablePtr;
+            } else {
+                $subTablePtr = GetTagTable('Image::ExifTool::MIE::Unknown');
+            }
+            if ($verbose) {
+                my $order = ', byte order ' . GetByteOrder();
+                $exifTool->VerboseInfo($tag, $tagInfo, Size => $valLen, Extra => $order);
+            }
+            my %subdirInfo = (
+                DirName => $dirName || $tag,
+                RAF => $raf,
+                Parent => $$dirInfo{DirName},
+            );
+            # read from uncompressed data instead if necessary
+            $subdirInfo{RAF} = new File::RandomAccess(\$value) if $format & 0x04;
+
+            my $oldOrder = GetByteOrder();
+            SetByteOrder($format & 0x08 ? 'II' : 'MM');
+            $msg = ProcessMIEGroup($exifTool, \%subdirInfo, $subTablePtr);
+            SetByteOrder($oldOrder);
+            $exifTool->{SET_GROUP1} = $grp1;    # restore this group1 name
+            last if $msg;
+        } else {
+            # process MIE data format types
+            if ($tagInfo) {
+                # extract tag value
+                my $val = ReadMIEValue(\$value, 0, $formatStr, undef, $valLen);
+                unless (defined $val) {
+                    $exifTool->Warn("Error reading $tag value");
+                    $val = '<err>';
+                }
+                # save type or mime type
+                $mime = $val if $tag eq '0Type' or $tag eq '2MIME';
+                if ($verbose) {
+                    my $count;
+                    my $s = Image::ExifTool::FormatSize($formatStr);
+                    if ($s and $formatStr !~ /^(utf|string|undef)/) {
+                        $count = $valLen / $s;
+                    }
+                    $exifTool->VerboseInfo($lastTag, $tagInfo,
+                        DataPt => \$value,
+                        DataPos => $raf->Tell() - $valLen,
+                        Size => $valLen,
+                        Format => $formatStr,
+                        Value => $val,
+                        Count => $count,
+                    );
+                }
+                if ($$tagInfo{SubDirectory}) {
+                    my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                    my %subdirInfo = (
+                        DirName => $$tagInfo{Name},
+                        DataPt => \$value,
+                        DataPos => $raf->Tell() - $valLen,
+                        DataLen => $valLen,
+                        DirStart => 0,
+                        DirLen => $valLen,
+                    );
+                    my $processProc = $tagInfo->{SubDirectory}->{ProcessProc};
+                    delete $exifTool->{SET_GROUP1};
+                    $exifTool->ProcessDirectory(\%subdirInfo, $subTablePtr, $processProc);
+                    $exifTool->{SET_GROUP1} = $grp1;
+                } elsif ($formatStr =~ /_list$/) {
+                    # split list value into separate strings
+                    my @vals = split "\0", $val;
+                    $exifTool->FoundTag($tagInfo, \@vals);
+                } else {
+                    # add units to value if specified
+                    $val .= "($units)" if defined $units;
+                    $exifTool->FoundTag($tagInfo, $val);
+                }
+            } else {
+                # skip over unknown information or free bytes
+                $raf->Seek($valLen, 1) or $msg = 'Seek error', last;
+                $verbose and $exifTool->VerboseInfo($tag, undef, Size => $valLen);
+            }
+        }
+    }
+    # modify MIME type if necessary
+    $mime and not $$dirInfo{Parent} and $exifTool->ModifyMimeType($mime);
+
+    $ok or $msg or $msg = 'Unexpected end of file';
+    $verbose and $exifTool->{INDENT} = $oldIndent;
+    return $msg;
+}
+
+#------------------------------------------------------------------------------
+# Read/write a MIE file
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid MIE file, or -1 on write error
+# - process as a trailer if "Trailer" flag set in dirInfo
+sub ProcessMIE($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    return 1 unless defined $exifTool;
+    my $raf = $$dirInfo{RAF};
+    my $outfile = $$dirInfo{OutFile};
+    my ($buff, $err, $msg, $pos, $end, $isCreating);
+    my $numDocs = 0;
+#
+# process as a trailer (from end of file) if specified
+#
+    if ($$dirInfo{Trailer}) {
+        my $offset = $$dirInfo{Offset} || 0;    # offset from end of file
+        $raf->Seek(-10 - $offset, 2) or return 0;
+        for (;;) {
+            # read and validate last 10 bytes
+            $raf->Read($buff, 10) == 10 or last;
+            last unless $buff =~ /~\0\0\x06.{4}(\x10|\x18)(\x04)$/s or
+                        $buff =~ /(\x10|\x18)(\x08)$/s;
+            SetByteOrder($1 eq "\x10" ? 'MM' : 'II');
+            my $len = ($2 eq "\x04") ? Get32u(\$buff, 4) : Get64u(\$buff);
+            my $curPos = $raf->Tell() or last;
+            last if $len < 12 or $len > $curPos;
+            # validate element header if 8-byte offset was used
+            if ($2 eq "\x08") {
+                last if $len < 14;
+                $raf->Seek($curPos - 14, 0) and $raf->Read($buff, 4) or last;
+                last unless $buff eq "~\0\0\x0a";
+            }
+            # looks like a good group, so remember start position
+            $pos = $curPos - $len;
+            $end = $curPos unless $end;
+            # seek to 10 bytes from end of previous group
+            $raf->Seek($pos - 10, 0) or last;
+        }
+        # seek to start of first MIE group
+        return 0 unless defined $pos and $raf->Seek($pos, 0);
+        # update DataPos and DirLen for ProcessTrailers()
+        $$dirInfo{DataPos} = $pos;
+        $$dirInfo{DirLen} = $end - $pos;
+        if ($outfile and $exifTool->{DEL_GROUP}->{MIE}) {
+            # delete the trailer
+            $exifTool->VPrint(0,"  Deleting MIE trailer\n");
+            ++$exifTool->{CHANGED};
+            return 1;
+        } elsif ($exifTool->Options('Verbose') or $exifTool->{HTML_DUMP}) {
+            $exifTool->DumpTrailer($dirInfo);
+        }
+    }
+#
+# loop through all documents in MIE file
+#
+    for (;;) {
+        # look for "0MIE" group element
+        my $num = $raf->Read($buff, 8);
+        if ($num == 8) {
+            # verify file identifier
+            if ($buff =~ /^~(\x10|\x18)\x04(.)0MIE/) {
+                SetByteOrder($1 eq "\x10" ? 'MM' : 'II');
+                my $len = ord($2);
+                # skip extended DataLength if it exists
+                if ($len > 252 and not $raf->Seek(1 << (256 - $len), 1)) {
+                    $msg = 'Seek error';
+                    last;
+                }
+            } else {
+                return 0 unless $numDocs;   # not a MIE file
+                if ($buff =~ /^~/) {
+                    $msg = 'Non-standard file-level MIE element';
+                } else {
+                    $msg = 'Invalid MIE file-level data';
+                }
+            }
+        } elsif ($numDocs) {
+            last unless $num;   # OK, all done with file
+            $msg = 'Truncated MIE element header';
+        } else {
+            return 0 if $num or not $outfile;
+            # we have the ability to create a MIE file from scratch
+            $buff = ''; # start from nothing
+            SetByteOrder('MM'); # write big-endian
+            $isCreating = 1;
+        }
+        if ($msg) {
+            last if $$dirInfo{Trailer}; # allow other trailers after MIE
+            if ($outfile) {
+                $exifTool->Error($msg);
+            } else {
+                $exifTool->Warn($msg);
+            }
+            last;
+        }
+        # this is a new MIE document -- increment document count
+        unless ($numDocs) {
+            # this is a valid MIE file (unless a trailer on another file)
+            $exifTool->SetFileType() unless $exifTool->{VALUE}->{FileType};
+            $exifTool->{NO_LIST} = 1;   # handle lists ourself
+            $exifTool->{MIE_COUNT} = { };
+            undef $hasZlib;
+        }
+        ++$numDocs;
+
+        # process the MIE groups recursively, beginning with the main MIE group
+        my $tagTablePtr = GetTagTable('Image::ExifTool::MIE::Main');
+
+        my %subdirInfo = (
+            DirName => 'MIE',
+            RAF => $raf,
+            OutFile => $outfile,
+            # don't define Parent so WriteMIEGroup() writes extended terminator
+        );
+        if ($outfile) {
+            # generate lookup for MIE format codes if not done already
+            unless (%mieCode) {
+                foreach (keys %mieFormat) {
+                    $mieCode{$mieFormat{$_}} = $_;
+                }
+            }
+            # update %mieMap with user-defined MIE groups
+            UpdateMieMap() unless $doneMieMap;
+            # initialize write directories, with MIE tags taking priority
+            $exifTool->InitWriteDirs(\%mieMap, 'MIE');
+            $subdirInfo{ToWrite} = '~' . MIEGroupFormat(1) . "\x04\xfe0MIE\0\0\0\0";
+            $msg = WriteMIEGroup($exifTool, \%subdirInfo, $tagTablePtr);
+            if ($msg) {
+                $exifTool->Error($msg);
+                $err = 1;
+                last;
+            } elsif (defined $msg and $isCreating) {
+                $exifTool->Error('Nothing to write');
+                last;
+            }
+        } else {
+            $msg = ProcessMIEGroup($exifTool, \%subdirInfo, $tagTablePtr);
+            if ($msg) {
+                $exifTool->Warn($msg);
+                last;
+            }
+        }
+    }
+    delete $exifTool->{NO_LIST};
+    delete $exifTool->{MIE_COUNT};
+    delete $exifTool->{SET_GROUP1};
+    return $err ? -1 : 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::MIE - Read/write MIE meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to read and write
+information in MIE files.
+
+=head1 WHAT IS MIE?
+
+MIE stands for "Meta Information Encapsulation".  The MIE format is an
+extensible, dedicated meta information format which supports storage of
+binary as well as textual meta information.  MIE can be used to encapsulate
+meta information from many sources and bundle it together with any type of
+file.
+
+=head2 Features
+
+Below is very subjective score card comparing the features of a number of
+common file and meta information formats, and comparing them to MIE.  The
+following features are rated for each format with a score of 0 to 10:
+
+  1) Extensible (can incorporate user-defined information).
+  2) Meaningful tag ID's (hint to meaning of unknown information).
+  3) Sequential read/write ability (streamable).
+  4) Hierarchical information structure.
+  5) Easy to implement reader/writer/editor.
+  6) Order of information well defined.
+  7) Large data lengths supported: >64kB (+5) and >4GB (+5).
+  8) Localized text strings.
+  9) Multiple documents in a single file.
+ 10) Compact format doesn't squander disk space or bandwidth.
+ 11) Compressed meta information supported.
+ 12) Relocatable data elements (ie. no fixed offsets).
+ 13) Binary meta information (+7) with variable byte order (+3).
+ 14) Mandatory tags not required (an unecessary complication).
+ 15) Append information to end of file without editing.
+
+                          Feature number                   Total
+     Format  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   Score
+     ------ ---------------------------------------------  -----
+     MIE    10 10 10 10 10 10 10 10 10 10 10 10 10 10 10    150
+     PDF    10 10  0 10  0  0 10  0 10 10 10  0  7 10 10     97
+     PNG    10 10 10  0  8  0  5 10  0 10 10 10  0 10  0     93
+     XMP    10 10 10 10  2  0 10 10 10  0  0 10  0 10  0     92
+     AIFF    0  5 10 10 10  0  5  0  0 10  0 10  7 10  0     77
+     RIFF    0  5 10 10 10  0  5  0  0 10  0 10  7 10  0     77
+     JPEG   10  0 10  0 10  0  0  0  0 10  0 10  7 10  0     67
+     EPS    10 10 10  0  0  0 10  0 10  0  0  5  0 10  0     65
+     CIFF    0  0  0 10 10  0  5  0  0 10  0 10 10 10  0     65
+     TIFF    0  0  0 10  5 10  5  0 10 10  0  0 10  0  0     60
+     EXIF    0  0  0 10  5 10  0  0  0 10  0  0 10  0  0     45
+     IPTC    0  0 10  0  8  0  0  0  0 10  0 10  7  0  0     45
+
+By design, MIE ranks highest by a significant margin.  Other formats with
+reasonable scores are PDF, PNG and XMP, but each has significant weak
+points.  What may be surprising is that TIFF, EXIF and IPTC rank so low.
+
+As well as scoring high in all these features, the MIE format has the unique
+ability to encapsulate any other type of file, and provides a non-invasive
+method of adding meta information to a file.  The meta information is
+logically separated from the original file data, which is extremely
+important because meta information is routinely lost when files are edited.
+
+Also, the MIE format supports multiple files by simple concatenation,
+enabling all kinds of wonderful features such as linear databases, edit
+histories or non-intrusive file updates.  This ability can also be leveraged
+to allow MIE-format trailers to be added to some other file types.
+
+=head1 MIE 1.1 FORMAT SPECIFICATION (2007-01-21)
+
+=head2 File Structure
+
+A MIE file consists of a series of MIE elements.  A MIE element may contain
+either data or a group of MIE elements, providing a hierarchical format for
+storing data.  Each MIE element is identified by a human-readable tag name,
+and may store data from zero to 2^64-1 bytes in length.
+
+=head2 File Signature
+
+The first element in the MIE file must be an uncompressed MIE group element
+with a tag name of "0MIE".  This restriction allows the first 8 bytes of a
+MIE file to be used to identify a MIE format file.  The following table
+lists the two possible initial byte sequences for a MIE-format file (the
+first for big-endian, and the second for little-endian byte ordering):
+
+    Byte Number:      0    1    2    3    4    5    6    7
+
+    C Characters:     ~ \x10 \x04    ?    0    M    I    E
+        or            ~ \x18 \x04    ?    0    M    I    E
+
+    Hexadecimal:     7e   10   04    ?   30   4d   49   45
+        or           7e   18   04    ?   30   4d   49   45
+
+    Decimal:        126   16    4    ?   48   77   73   69
+        or          126   24    4    ?   48   77   73   69
+
+Note that byte 1 may have one of the two possible values (0x10 or 0x18), and
+byte 3 may have any value (0x00 to 0xff).
+
+=head2 Element Structure
+
+    1 byte  SyncByte = 0x7e (decimal 126, character '~')
+    1 byte  FormatCode (see below)
+    1 byte  TagLength (T)
+    1 byte  DataLength (gives D if DataLength < 253)
+    T bytes TagName (T given by TagLength)
+    2 bytes DataLength2 [exists only if DataLength == 255 (0xff)]
+    4 bytes DataLength4 [exists only if DataLength == 254 (0xfe)]
+    8 bytes DataLength8 [exists only if DataLength == 253 (0xfd)]
+    D bytes DataBlock (D given by DataLength)
+
+The minimum element length is 4 bytes (for a group terminator).  The maximum
+DataBlock size is 2^64-1 bytes.  TagLength and DataLength are unsigned
+integers, and the byte ordering for multi-byte DataLength fields is
+specified by the containing MIE group element.  The SyncByte is byte
+aligned, so no padding is added to align on an N-byte boundary.
+
+=head3 FormatCode
+
+The format code is a bitmask that defines the format of the data:
+
+    7654 3210
+    ++++ ----  FormatType
+    ---- +---  TypeModifier
+    ---- -+--  Compressed
+    ---- --++  FormatSize
+
+=over 4
+
+=item FormatType (bitmask 0xf0):
+
+    0x00 - other (or unknown) data
+    0x10 - MIE group
+    0x20 - text string
+    0x30 - list of null-separated text strings
+    0x40 - integer
+    0x50 - rational
+    0x60 - fixed point
+    0x70 - floating point
+    0x80 - free space
+
+=item TypeModifier (bitmask 0x08):
+
+Modifies the meaning of certain FormatTypes (0x00-0x60):
+
+    0x08 - other data sensitive to MIE group byte order
+    0x18 - MIE group with little-endian byte ordering
+    0x28 - UTF encoded text string
+    0x38 - UTF encoded text string list
+    0x48 - signed integer
+    0x58 - signed rational (denominator is always unsigned)
+    0x68 - signed fixed-point
+
+=item Compressed (bitmask 0x04):
+
+If this bit is set, the data block is compressed using Zlib deflate.  An
+entire MIE group may be compressed, with the exception of file-level groups.
+
+=item FormatSize (bitmask 0x03):
+
+Gives the byte size of each data element:
+
+    0x00 - 8 bits  (1 byte)
+    0x01 - 16 bits (2 bytes)
+    0x02 - 32 bits (4 bytes)
+    0x03 - 64 bits (8 bytes)
+
+The number of bytes in a single value for this format is given by
+2**FormatSize (or 1 << FormatSize).  The number of values is the data length
+divided by this number of bytes.  It is an error if the data length is not
+an even multiple of the format size in bytes.
+
+=back
+
+The following is a list of all currently defined MIE FormatCode values for
+uncompressed data (add 0x04 to each value for compressed data):
+
+    0x00 - other data (insensitive to MIE group byte order) (1)
+    0x01 - other 16-bit data (may be byte swapped)
+    0x02 - other 32-bit data (may be byte swapped)
+    0x03 - other 64-bit data (may be byte swapped)
+    0x08 - other data (sensitive to MIE group byte order) (1)
+    0x10 - MIE group with big-endian values (1)
+    0x18 - MIE group with little-endian values (1)
+    0x20 - ASCII (ISO 8859-1) string (2,3)
+    0x28 - UTF-8 string (2,3,4)
+    0x29 - UTF-16 string (2,3,4)
+    0x2a - UTF-32 string (2,3,4)
+    0x30 - ASCII (ISO 8859-1) string list (3,5)
+    0x38 - UTF-8 string list (3,4,5)
+    0x39 - UTF-16 string list (3,4,5)
+    0x3a - UTF-32 string list (3,4,5)
+    0x40 - unsigned 8-bit integer
+    0x41 - unsigned 16-bit integer
+    0x42 - unsigned 32-bit integer
+    0x43 - unsigned 64-bit integer (6)
+    0x48 - signed 8-bit integer
+    0x49 - signed 16-bit integer
+    0x4a - signed 32-bit integer
+    0x4b - signed 64-bit integer (6)
+    0x52 - unsigned 32-bit rational (16-bit numerator then denominator) (7)
+    0x53 - unsigned 64-bit rational (32-bit numerator then denominator) (7)
+    0x5a - signed 32-bit rational (denominator is unsigned) (7)
+    0x5b - signed 64-bit rational (denominator is unsigned) (7)
+    0x61 - unsigned 16-bit fixed-point (high 8 bits is integer part) (8)
+    0x62 - unsigned 32-bit fixed-point (high 16 bits is integer part) (8)
+    0x69 - signed 16-bit fixed-point (high 8 bits is signed integer) (8)
+    0x6a - signed 32-bit fixed-point (high 16 bits is signed integer) (8)
+    0x72 - 32-bit IEEE float (not recommended for portability reasons)
+    0x73 - 64-bit IEEE double (not recommended for portability reasons) (6)
+    0x80 - free space (value data does not contain useful information)
+
+Notes:
+
+=over 4
+
+=item 1.
+
+The byte ordering specified by the MIE group TypeModifier applies to the MIE
+group element as well as all elements within the group.  Data for all
+FormatCodes except 0x08 (other data, sensitive to byte order) may be
+transferred between MIE groups with different byte order by byte swapping
+the uncompressed data according to the specified data format.  The following
+list illustrates the byte-swapping pattern, based on FormatSize, for all
+format types except rational (FormatType 0x50).
+
+      FormatSize              Change in Byte Sequence
+    --------------      -----------------------------------
+    0x00 (8 bits)       0 1 2 3 4 5 6 7 --> 0 1 2 3 4 5 6 7 (no change)
+    0x01 (16 bits)      0 1 2 3 4 5 6 7 --> 1 0 3 2 5 4 7 6
+    0x02 (32 bits)      0 1 2 3 4 5 6 7 --> 3 2 1 0 7 6 5 4
+    0x03 (64 bits)      0 1 2 3 4 5 6 7 --> 7 6 5 4 3 2 1 0
+
+Rational values consist of two integers, so they are swapped as the next
+lower FormatSize.  For example, a 32-bit rational (FormatSize 0x02, and
+FormatCode 0x52 or 0x5a) is swapped as two 16-bit values (ie. as if it had
+FormatSize 0x01).
+
+=item 2.
+
+The TagName of a string element may have an 6-character suffix to indicate a
+specific locale. (ie. "Title-en_US", or "Keywords-de_DE").
+
+=item 3.
+
+Text strings are not normally null terminated, however they may be padded
+with one or more null characters to the end of the data block to allow
+strings to be edited within fixed-length data blocks.  Newlines in the text
+are indicated by a single LF (0x0a) character.
+
+=item 4.
+
+UTF strings must not begin with a byte order mark (BOM) since the byte order
+and byte size are specified by the MIE format.  If a BOM is found, it should
+be treated as a zero-width non-breaking space.
+
+=item 5.
+
+A list of text strings separated by null characters.  These lists must not
+be null padded or null terminated, since this would be interpreted as
+additional zero-length strings.  For ASCII and UTF-8 strings, the null
+character is a single zero (0x00) byte.  For UTF-16 or UTF-32 strings, the
+null character is 2 or 4 zero bytes respectively.
+
+=item 6.
+
+64-bit integers and doubles are subject to the specified byte ordering for
+both 32-bit words and bytes within these words.  For instance, the high
+order byte is always the first byte if big-endian, and the eighth byte if
+little-endian.  This means that some swapping is always necessary for these
+values on systems where the byte order differs from the word order (ie. some
+ARM systems), regardless of the endian-ness of the stored values.
+
+=item 7.
+
+Rational values are treated as two separate integers.  The numerator always
+comes first regardless of the byte ordering.  In a signed rational value,
+only the numerator is signed.  The denominator of all rational values is
+unsigned (ie. a signed 32-bit rational of 0x80000000/0x80000000 evaluates to
+-1, not +1).
+
+=item 8.
+
+32-bit fixed point values are converted to floating point by treating them
+as an integer and dividing by an appropriate value.  ie)
+
+    16-bit fixed value = 16-bit integer value / 256.0
+    32-bit fixed value = 32-bit integer value / 65536.0
+
+=back
+
+=head3 TagLength
+
+Gives the length of the TagName string.  Any value between 0 and 255 is
+valid, but the TagLength of 0 is valid only for the MIE group terminator.
+
+=head3 DataLength
+
+DataLength is an unsigned byte that gives the number of bytes in the data
+block.  A value between 0 and 252 gives the data length directly, and
+numbers from 253 to 255 are reserved for extended DataLength codes.  Codes
+of 255, 254 and 253 indicate that the element contains an additional 2, 4 or
+8 byte unsigned integer representing the data length.
+
+    0-252      - length of data block
+    255 (0xff) - use DataLength2
+    254 (0xfe) - use DataLength4
+    253 (0xfd) - use DataLength8
+
+A DataLength of zero is valid for any element except a compressed MIE group.
+A zero DataLength for an uncompressed MIE group indicates that the group
+length is unknown.  For other elements, a zero length indicates there is no
+associated data.  A terminator element must have a DataLength of 0, 6 or 10,
+and may not use an extended DataLength.
+
+=head3 TagName
+
+The TagName string is 0 to 255 bytes long, and is composed of the ASCII
+characters A-Z, a-z, 0-9 and underline ('_').  Also, a dash ('-') is used to
+separate the language/country code in the TagName of a localized text
+string, and a units string (possibly containing other ASCII characters) may
+be appear in brackets at the end of the TagName.  The TagName string is NOT
+null terminated.  A MIE element with a tag string of zero length is reserved
+for the group terminator.
+
+MIE elements are sorted alphabetically by TagName within each group.
+Multiple elements with the same TagName are allowed, even within the same
+group.
+
+TagNames should be meaningful.  Case is significant.  Words should be
+lowercase with an uppercase first character, and acronyms should be all
+upper case.  The underline ("_") is provided to allow separation of two
+acronyms or two numbers, but it shouldn't be used unless necessary.  No
+separation is necessary between an acronym and a word (ie. "ISOSetting").
+
+All TagNames should start with an uppercase letter.  An exception to this
+rule allows tags to begin with a digit (0-9) if they must come before other
+tags in the sort order, or a lowercase letter (a-z) if they must come after.
+For instance, the '0Type' element begins with a digit so it comes before,
+and the 'data' element begins with a lowercase letter so that it comes after
+meta information tags in the main "0MIE" group.
+
+Tag names for localized text strings have an 6-character suffix with the
+following format:  The first character is a dash ('-'), followed by a
+2-character lower case ISO 639-1 language code, then an underline ('_'), and
+ending with a 2-character upper case ISO 3166-1 alpha 2 country code.  (ie.
+"-en_US", "-en_GB", "-de_DE" or "-fr_FR".  Note that "GB", and not "UK" is
+the code for Great Britain, although "UK" should be recognized for
+compatibility reasons.)  The suffix is included when sorting the tags
+alphabetically, so the default locale (with no tag-name suffix) always comes
+first.  If the country is unknown or not applicable, a country code of "XX"
+should be used.
+
+Tags with numerical values may allow units of measurement to be specified.
+The units string is stored in brackets at the end of the tag name, and is
+composed of zero or more ASCII characters in the range 0x21 to 0x7d,
+excluding the bracket characters 0x28 and 0x29.  (ie. "Resolution(/cm)" or
+"SpecificHeat(J/kg.K)".)  See L<Image::ExifTool::MIEUnits> for details. Unit
+strings are not localized, and may not be used in combination with localized
+text strings.
+
+Sets of tags which would require a common prefix should be added in a
+separate MIE group instead of adding the prefix to all tag names.  For
+example, instead of these TagName's:
+
+    ExternalFlashType
+    ExternalFlashSerialNumber
+    ExternalFlashFired
+
+one would instead designate a separate "ExternalFlash" MIE group to contain
+the following elements:
+
+    Type
+    SerialNumber
+    Fired
+
+=head3 DataLength2/4/8
+
+These extended DataLength fields exist only if DataLength is 255, 254 or
+253, and are respectively 2, 4 or 8 byte unsigned integers giving the data
+block length.  One of these values must be used if the data block is larger
+than 252 bytes, but they may be used if desired for smaller blocks too
+(although this may add a few unnecessary bytes to the MIE element).
+
+=head3 DataBlock
+
+The data value for the MIE element.  The format of the data is given by the
+FormatCode.  For MIE group elements, the data includes all contained
+elements and the group terminator.
+
+=head2 MIE groups
+
+All MIE data elements must be contained within a group.  A group begins with
+a MIE group element, and ends with a group terminator.  Groups may be nested
+in a hierarchy to arbitrary depth.
+
+A MIE group element is identified by a format code of 0x10 (big endian byte
+ordering) or 0x18 (little endian).  The group terminator is distinguished by
+a zero TagLength (it is the only element allowed to have a zero TagLength),
+and has a FormatCode of 0x00.
+
+The MIE group element is permitted to have a zero DataLength only if the
+data is uncompressed.  This special value indicates that the group length is
+unknown (otherwise the minimum value for DataLength is 4, corresponding the
+the minimum group size which includes a terminator of at least 4 bytes). If
+DataLength is zero, all elements in the group must be parsed until the group
+terminator is found.  If non-zero, DataLength includes the length of all
+elements contained within the group, including the group terminator.  Use of
+a non-zero DataLength is encouraged because it allows readers quickly skip
+over entire MIE groups.  For compressed groups DataLength must be non-zero,
+and is the length of the compressed group data (which includes the
+compressed group terminator).
+
+=head3 Group Terminator
+
+The group terminator has a FormatCode and TagLength of zero.  The terminator
+DataLength must be 0, 6 or 10 bytes, and extended DataLength codes may not
+be used.  With a zero DataLength, the byte sequence for a terminator is "7e
+00 00 00" (hex).  With a DataLength of 6 or 10 bytes, the terminator data
+block contains information about the length and byte ordering of the
+preceding group.  This additional information is recommended for file-level
+groups, and is used in multi-document MIE files and MIE trailers to allow
+the file to be scanned backwards from the end.  (This may also allow some
+documents to be recovered if part of the file is corrupted.)  The structure
+of this optional terminator data block is as follows:
+
+    4 or 8 bytes  GroupLength (unsigned integer)
+    1 byte        ByteOrder (0x10 or 0x18, same as MIE group)
+    1 byte        GroupLengthSize (0x04 or 0x08)
+
+The ByteOrder and GroupLengthSize values give the byte ordering and size of
+the GroupLength integer.  The GroupLength value is the total length of the
+entire MIE group ending with this terminator, including the opening MIE
+group element and the terminator itself.
+
+=head3 File-level MIE groups
+
+File-level MIE groups may NOT be compressed.
+
+All elements in a MIE file are contained within a special group with a
+TagName of "0MIE".  The purpose of the "OMIE" group is to provide a unique
+signature at the start of the file, and to encapsulate information allowing
+files to be easily combined.  The "0MIE" group must be terminated like any
+other group, but it is recommended that the terminator of a file-level group
+include the optional data block (defined above) to provide information about
+the group length and byte order.
+
+It is valid to have more than one "0MIE" group at the file level, allowing
+multiple documents in a single MIE file.  Furthermore, the MIE structure
+enables multi-document files to be generated by simply concatenating two or
+more MIE files.
+
+=head2 Scanning Backwards through a MIE File
+
+The steps below give an algorithm to quickly locate the last document in a
+MIE file:
+
+=over 4
+
+=item 1.
+
+Read the last 10 bytes of the file.  (Note that a valid MIE file may be as
+short as 12 bytes long, but a file this length contains only an an empty MIE
+group.)
+
+=item 2.
+
+If the last byte of the file is zero, then it is not possible to scan
+backward through the file, so the file must be scanned from the beginning.
+Otherwise, proceed to the next step.
+
+=item 3.
+
+If the last byte is 4 or 8, the terminator contains information about the
+byte ordering and length of the group.  Otherwise, stop here because this
+isn't a valid MIE file.
+
+=item 4.
+
+The next-to-last byte must be either 0x10 indicating big-endian byte
+ordering or 0x18 for little-endian ordering, otherwise this isn't a valid
+MIE file.
+
+=item 5.
+
+The value of the preceding 4 or 8 bytes gives the length of the complete
+file-level MIE group (GroupLength).  This length includes both the leading
+MIE group element and the terminator element itself.  The value is an
+unsigned integer with a byte length given in step 3), and a byte order from
+step 4).  From the current file position (at the end of the data read in
+step 1), seek backward by this number of bytes to find the start of the MIE
+group element for this document.
+
+=back
+
+This algorithm may be repeated again beginning at this point in the file to
+locate the next-to-last document, etc.
+
+The table below lists all 5 valid patterns for the last 14 bytes of a
+file-level MIE group, with all numbers in hex.  The comments indicate the
+length and byte ordering of GroupLength (xx) if available:
+
+  ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 7e 00 00 00  - (no GroupLength)
+  ?? ?? ?? ?? 7e 00 00 06 xx xx xx xx 10 04  - 4 bytes, big endian
+  ?? ?? ?? ?? 7e 00 00 06 xx xx xx xx 18 04  - 4 bytes, little endian
+  7e 00 00 0a xx xx xx xx xx xx xx xx 10 08  - 8 bytes, big endian
+  7e 00 00 0a xx xx xx xx xx xx xx xx 18 08  - 8 bytes, little endian
+
+=head2 Trailer Signature
+
+The MIE format may be used for trailer information appended to other types
+of files.  When this is done, a signature must appear at the end of the main
+MIE group to uniquely identify the MIE format trailer.  To achieve this, a
+"zmie" trailer signature is written as the last element in the main "0MIE"
+group.  This element has a FormatCode of 0, a TagLength of 4, a DataLength
+of 0, and a TagName of "zmie".  With this signature, the hex byte sequence
+"7e 00 04 00 7a 6d 69 65" appears immediately before the final group
+terminator, and the last 22 bytes of the trailer correspond to one of the
+following 4 patterns (where the trailer length is given by "xx", as above):
+
+  ?? ?? ?? ?? 7e 00 04 00 7a 6d 69 65 7e 00 00 06 xx xx xx xx 10 04
+  ?? ?? ?? ?? 7e 00 04 00 7a 6d 69 65 7e 00 00 06 xx xx xx xx 18 04
+  7e 00 04 00 7a 6d 69 65 7e 00 00 0a xx xx xx xx xx xx xx xx 10 08
+  7e 00 04 00 7a 6d 69 65 7e 00 00 0a xx xx xx xx xx xx xx xx 18 08
+
+Note that the zero-DataLength terminator may not be used here because the
+trailer length must be known for seeking backwards from the end of the file.
+
+Multiple trailers may be appended to the same file using this technique.
+
+=head2 MIE Data Values
+
+MIE data values for a given tag are usually not restricted to a specific
+FormatCode.  Any value may be represented in any appropriate format,
+including numbers represented in string (ASCII or UTF) form.
+
+It is preferred that closely related values with the same format are written
+to a single tag instead of using multiple tags.  This improves localization
+of like values and decreases MIE element overhead.  For instance, instead of
+separate ImageWidth and ImageHeight tags, a single ImageSize tag is defined.
+
+Tags which may take on a discrete set of values should have meaningful
+values if possible.  This improves the extensibility of the format and
+allows a more reasonable interpretation of unrecognized values.
+
+=head3 Numerical Representation
+
+Integer and floating point numbers may be represented in binary or string
+form.  In string form, integers are a series of digits with an optional
+leading sign (ie. "[+|-]DDDDDD"), and multiple values are separated by a
+single space character (ie. "23 128 -32").  Floating point numbers are
+similar but may also contain a decimal point and/or a signed exponent with a
+leading 'e' character (ie. "[+|-]DD[.DDDDDD][e(+|-)EEE]").  The string "inf"
+is used to represent infinity.  One advantage of numerical strings is that
+they can have an arbitrarily high precision because the possible number of
+significant digits is virtually unlimited.
+
+Note that numerical values may have associated units of measurement which
+are specified in the L</TagName> string.
+
+=head3 Date/Time Format
+
+All MIE dates are strings in the form "YYYY:mm:dd HH:MM:SS.ss+HH:MM".  The
+fractional seconds (".ss") are optional, and if included may contain any
+number of significant digits (unlike all other fields which are a fixed
+number of digits and must be padded with leading zeros if necessary).  The
+timezone ("+HH:MM" or "-HH:MM") is recommended but not required.  If not
+given, the local system timezone is assumed.
+
+=head2 MIME Type
+
+The basic MIME type for a MIE file is "application/x-mie", however the
+specific MIME type depends on the type of subfile, and is obtained by adding
+"x-mie-" to the MIME type of the subfile.  For example, with a subfile of
+type "image/jpeg", the MIE file MIME type is "image/x-mie-jpeg".  But note
+that the "x-" is not duplicated if the subfile MIME type already starts with
+"x-".  So a subfile with MIME type "image/x-raw" is contained within a MIE
+file of type "image/x-mie-raw", not "image/x-mie-x-raw".  In the case of
+multiple documents in a MIE file, the MIME type is taken from the first
+document.  Regardless of the subfile type, all MIE-format files should have
+a filename extension of ".MIE".
+
+=head2 Levels of Support
+
+Basic MIE reader/writer applications may choose not to provide support for
+some advanced features of the MIE format.  Features which may not be
+supported by all software are:
+
+=over 4
+
+=item Compression
+
+Software not supporting compression must ignore compressed elements and
+groups, but should be able to process the remaining information.
+
+=item Large data lengths
+
+Some software may limit the maximum size of a MIE group or element.
+Historically, a limit of 2GB may be imposed by some systems.  However,
+8-byte data lengths should be supported by all applications provided the
+value doesn't exceed the system limit.  (ie. For systems with a 2GB limit,
+8-byte data lengths should be supported if the upper 17 bits are all zero.)
+If a data length above the system limit is encountered, it may be necessary
+for the application to stop processing if it can not seek to the next
+element in the file.
+
+=back
+
+=head1 EXAMPLES
+
+This section gives examples for working with MIE information using ExifTool.
+
+=head2 Encapsulating Information with Data in a MIE File
+
+The following command encapsulates any file recognized by ExifTool inside a
+MIE file, and initializes MIE tags from information within the file:
+
+    exiftool -o new.mie -tagsfromfile FILE '-mie:all<all' \
+        '-subfilename<filename' '-subfiletype<filetype' \
+        '-subfilemimetype<mimetype' '-subfiledata<=FILE'
+
+where C<FILE> is the name of the file.
+
+For unrecognized files, this command may be used:
+
+    exiftool -o new.mie -subfilename=FILE -subfiletype=TYPE \
+        -subfilemimetype=MIME '-subfiledata<=FILE'
+
+where C<TYPE> and C<MIME> represent the source file type and MIME type
+respectively.
+
+=head2 Adding a MIE Trailer to a File
+
+The MIE format may also be used to store information in a trailer appended
+to another type of file.  Beware that trailers may not be compatible with
+all file formats, but JPEG and TIFF are two formats where additional trailer
+information doesn't create any problems for normal parsing of the file.
+Also note that this technique has the disadvantage that trailer information
+is commonly lost if the file is subsequently edited by other software.
+
+Creating a MIE trailer with ExifTool is a two-step process since ExifTool
+can't currently be used to add a MIE trailer directly.  The example below
+illustrates the steps for adding a MIE trailer with a small preview image
+(C<small.jpg>) to a destination JPEG image (C<dst.jpg>).
+
+Step 1) Create a MIE file with a TrailerSignature containing the desired
+information:
+
+    exiftool -o new.mie -trailersignature=1 -tagsfromfile small.jpg \
+        '-previewimagetype<filetype' '-previewimagesize<imagesize' \
+        '-previewimagename<filename' '-previewimage<=small.jpg'
+
+Step 2) Append the MIE information to another file.  In Unix, this can be
+done with the 'cat' command:
+
+    cat new.mie >> dst.jpg
+
+Once added, ExifTool may be used to edit or delete a MIE trailer in a JPEG
+or TIFF image.
+
+=head2 Multiple MIE Documents in a Single File
+
+The MIE specification allows multiple MIE documents (or trailers) to exist
+in a single file.  A file like this may be created by simply concatenating
+MIE documents.  ExifTool may be used to access information in a specific
+document by adding a copy number to the MIE group name.  For example:
+
+    # write the Author tag in the second MIE document
+    exiftool -mie2:author=phil test.mie
+
+    # delete the first MIE document from a file
+    exiftool -mie1:all= test.mie
+
+=head2 Units of Measurement
+
+Some MIE tags allow values to be specified in different units of
+measurement.  In the MIE file format these units are combined with the tag
+name, but when using ExifTool they are specified in brackets after the
+value:
+
+    exiftool -mie:gpsaltitude='7500(ft)' test.mie
+
+If no units are provided, the default units are written.
+
+=head2 Localized Text
+
+Localized text values are accessed by adding a language/country code to the
+tag name.  For example:
+
+    exiftool -comment-en_us='this is a comment' test.mie
+
+=head1 REVISIONS
+
+  2007-01-21 - Specified LF character (0x0a) for text newline sequence
+  2007-01-19 - Specified ISO 8859-1 character set for extended ASCII codes
+  2007-01-01 - Improved wording of Step 5 for scanning backwards in MIE file
+  2006-12-30 - Added EXAMPLES section and note about UTF BOM
+  2006-12-20 - MIE 1.1:  Changed meaning of TypeModifier bit (0x08) for
+               unknown data (FormatType 0x00), and documented byte swapping
+  2006-12-14 - MIE 1.0:  Added Data Values and Numerical Representations
+               sections, and added ability to specify units in tag names
+  2006-11-09 - Added Levels of Support section
+  2006-11-03 - Added Trailer Signature
+  2005-11-18 - Original specification created
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.  The MIE format itself is also
+copyright Phil Harvey, and is covered by the same free-use license.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://owl.phy.queensu.ca/~phil/exiftool/MIE1.1-20070121.pdf>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/MIE Tags>, L<Image::ExifTool::MIEUnits>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/MIEUnits.pod
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/MIEUnits.pod	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/MIEUnits.pod	(revision 20131)
@@ -0,0 +1,377 @@
+
+=head1 NAME
+
+Image::ExifTool::MIEUnits - MIE units documentation
+
+=head1 DESCRIPTION
+
+The MIE format allows units of measurement to be specified in brackets at
+the end of a MIE tag name (ie. "Volume(m3)"). This document describes the
+standard MIE units abbreviations.
+
+=head1 SYNTAX
+
+The units string may contain any ASCII characters in the range 0x21 ('!') to
+0x7d ('}'), excepting the bracket characters (0x28 and 0x29).  An empty
+string is allowed, and indicates a dimensionless value.  L<Standard
+units|/STANDARD UNITS> should be used where possible.  In the standard
+units, an underline ('_') is used to indicate a subscript, and multiple
+words may be separated with a hyphen ('-').
+
+Exponents should be positive, and require no separator (ie. "m2" for square
+meters).  L<Prefixes|/PREFIXES> may be added to the standard units (ie.
+"cm") except when the resulting name conflicts with another standard unit.
+
+Multiplication is indicated by '.', and division by '/'.  Reciprocal units
+(ie. the multiplicative inverse) are obtained through division rather than
+the use of negative exponents (ie. "/in", not "in-1").  In MIE units,
+multiplication has precedence over division, so everything to the right of a
+'/' is in the denominator.  (See L</EXAMPLES> for a few examples.)
+
+Below is a table summarizing the special characters used in MIE units
+strings.
+
+  .           multiplication
+  /           division (used for negative exponents)
+  -           word separator
+  _           subscript
+  {}          annotation
+  []          used to avoid name conflicts if necessary
+  0-9         exponentiation
+
+=head1 STANDARD UNITS
+
+              dimensionless
+  [G]         Newtonian constant of gravitation (unclassified)
+  [g]         standard acceleration of free fall (acceleration)
+  [h]         Planck constant (action)
+  [k]         Boltzmann constant (unclassified)
+  {cfu}       colony forming units (number)
+  {rbc}       red blood cell count (number)
+  {tbl}       tablets (number)
+  {tot}       particles total count (number)
+  %           percent (fraction)
+  10^N        the number ten for arbitrary powers (number)
+  A           Ampere (electric current)
+  a           year (time)
+  a_g         mean Gregorian year (time)
+  a_j         mean Julian year (time)
+  a_t         tropical year (time)
+  acr         acre, U.S. (area)
+  acr_br      acre, British (area)
+  Ao          Angstrom (length)
+  APL-U       APL unit (biologic activity of anticardiolipin IgA)
+  ar          are (area)
+  arb-U       arbitrary unit (arbitrary)
+  arcmin      minute of arc (plane angle)
+  arcsec      second of arc (plane angle)
+  atm         standard atmosphere (pressure)
+  att         technical atmosphere (pressure)
+  AU          astronomic unit (length)
+  b           barn (action area)
+  B           bel (level)
+  B-kW        bel kilowatt (power level)
+  B-mV        bel millivolt (electric potential level)
+  B-SPL       bel sound pressure (pressure level)
+  B-uV        bel microvolt (electric potential level)
+  B-V         bel volt (electric potential level)
+  B-W         bel watt (power level)
+  bar         bar (pressure)
+  bbl         barrel (fluid volume)
+  Bd          baud (signal transmission rate)
+  bdsk-U      Bodansky unit (biologic activity of phosphatase)
+  beth-U      Bethesda unit (biologic activity of factor VIII inhibitor)
+  bf          board foot (volume)
+  Bi          Biot (electric current)
+  bit         bit (amount of information)
+  Bq          Becquerel (radioactivity)
+  Btu         British thermal unit (energy)
+  Btu_39      British thermal unit at 39 degF (energy)
+  Btu_59      British thermal unit at 59 degF (energy)
+  Btu_60      British thermal unit at 60 degF (energy)
+  Btu_IT      international table British thermal unit (energy)
+  Btu_m       mean British thermal unit (energy)
+  Btu_th      thermochemical British thermal unit (energy)
+  bu          bushel, U.S. (dry volume)
+  bu_br       bushel, British (volume)
+  By          byte (amount of information)
+  C           Coulomb (electric charge)
+  c           velocity of light (velocity)
+  cal         calorie (energy)
+  Cal         nutrition label Calories (energy)
+  cal_15      calorie at 15 degC (energy)
+  cal_20      calorie at 20 degC (energy)
+  cal_IT      international table calorie (energy)
+  cal_m       mean calorie (energy)
+  cal_th      thermochemical calorie (energy)
+  car_Au      carat of gold alloys (mass fraction)
+  car_m       metric carat (mass)
+  cd          candela (luminous intensity)
+  Cel         degree Celsius (temperature)
+  Ch          Charriere (gauge of catheters)
+  ch          Gunter's chain, U.S. (length)
+  ch_br       Gunter's chain, British (length)
+  Ci          Curie (radioactivity)
+  cicero      cicero (length)
+  circ        circle (plane angle)
+  cml         circular mil, international (area)
+  cr          cord, international (volume)
+  crd_us      cord, U.S. (fluid volume)
+  cup_us      cup (volume)
+  d           day (time)
+  deg         degree (plane angle)
+  deg{mag}    degree from magnetic north (plane angle)
+  degF        degree Fahrenheit (temperature)
+  didot       didot (length)
+  diop        diopter (refraction of a lens)
+  dpt         dry pint, U.S. (dry volume)
+  dqt         dry quart, U.S. (dry volume)
+  dr          dram (mass)
+  dr_ap       dram, apothecary (mass)
+  drp         drop (volume)
+  dye-U       Dye unit (biologic activity of amylase)
+  dyn         dyne (force)
+  e           elementary charge (electric charge)
+  eps_0       permittivity of vacuum (electric permittivity)
+  eq          equivalents (amount of substance)
+  erg         erg (energy)
+  eV          electronvolt (energy)
+  F           Farad (electric capacitance)
+  fdr         fluid dram, U.S. (fluid volume)
+  fdr_br      fluid dram, British (volume)
+  foz         fluid ounce, U.S. (fluid volume)
+  foz_br      fluid ounce, British (volume)
+  ft          foot, international (length)
+  ft_br       foot, British (length)
+  ft_us       foot, U.S. (length)
+  fth         fathom, international (length)
+  fth_br      fathom, British (length)
+  fth_us      fathom, U.S. (length)
+  fur         furlong, U.S. (length)
+  G           Gauss (magnetic flux density)
+  g           gram (mass)
+  g.m/{H-B}   gram meter per heartbeat (prop. to ventricular stroke work)
+  g%          gram percent (mass fraction)
+  Gal         Gal (acceleration)
+  gal         gallon, U.S. (fluid volume)
+  gal_br      gallon, British (volume)
+  gal_wi      historical winchester gallon (dry volume)
+  Gb          Gilbert (magnetic tension)
+  gf          gram-force (force)
+  gil         gill, U.S. (fluid volume)
+  gil_br      gill, British (volume)
+  gon         gon (plane angle)
+  GPL-U       GPL unit (biologic activity of anticardiolipin IgG)
+  gr          grain (mass)
+  Gy          Gray (energy dose)
+  H           Henry (inductance)
+  h           hour (time)
+  hd          hand, international (height of horses)
+  hnsf-U      Hounsfield unit (x-ray attenuation)
+  HP          horsepower (power)
+  hp_C        homeopathic potency of centesimal series (homeopathic potency)
+  hp_X        homeopathic potency of decimal series (homeopathic potency)
+  HPF         high power field (view area in microscope)
+  Hz          Herz (frequency)
+  in          inch, international (length)
+  in_br       inch, British (length)
+  in_us       inch, U.S. (length)
+  in-H2O      inch of water column (pressure)
+  in-Hg       inch of mercury column (pressure)
+  iU          international unit (arbitrary)
+  J           Joule (energy)
+  K           Kelvin (temperature)
+  ka-U        King-Armstrong unit (biologic activity of phosphatase)
+  kat         katal (catalytic activity)
+  kg{wet-tis} kilogram of wet tissue (mass)
+  kn          knot, international (velocity)
+  kn_br       knot, British (velocity)
+  knk-U       Kunkel unit (arbitrary biologic activity)
+  Ky          Kayser (lineic number)
+  l           liter (volume)
+  L           liter (volume)
+  lb          pound (mass)
+  lb_ap       pound, apothecary (mass)
+  lb_tr       pound, troy (mass)
+  lbf         pound force (force)
+  lcwt        long hunderdweight (mass)
+  ligne       ligne (length)
+  lk          link for Gunter's chain, U.S. (length)
+  lk_br       link for Gunter's chain, British (length)
+  lm          lumen (luminous flux)
+  Lmb         Lambert (brightness)
+  lne         line (length)
+  LPF         low power field (view area in microscope)
+  lton        long ton (mass)
+  lx          lux (illuminance)
+  ly          light-year (length)
+  m           meter (length)
+  m_e         electron mass (mass)
+  m_p         proton mass (mass)
+  m-H2O       meter of water column (pressure)
+  m-Hg        meter of mercury column (pressure)
+  mclg-U      Mac Lagan unit (arbitrary biologic activity)
+  mesh        mesh, international (lineic number)
+  MET         metabolic equivalent (metabolic cost of physical activity)
+  mg{creat}   milligram of creatinine (mass)
+  mho         mho (electric conductance)
+  mi          mile, international (statute mile) (length)
+  mi_br       mile, British (length)
+  mi_us       mile, U.S. (length)
+  mil         mil, international (length)
+  mil_us      mil, U.S. (length)
+  min         minute (time)
+  min_br      minim, British (volume)
+  min_us      minim, U.S. (fluid volume)
+  mo          month (time)
+  mo_g        mean Gregorian month (time)
+  mo_j        mean Julian month (time)
+  mo_s        synodal month (time)
+  mol         mole (amount of substance)
+  MPL-U       MPL unit (biologic activity of anticardiolipin IgM)
+  mu_0        permeability of vacuum (magnetic permeability)
+  Mx          Maxwell (flux of magnetic induction)
+  N           Newton (force)
+  nmi         nautical mile, international (length)
+  nmi_br      nautical mile, British (length)
+  Np          neper (level)
+  Oe          Oersted (magnetic field intensity)
+  Ohm         Ohm (electric resistance)
+  osm         osmole of dissolved particles (amount of substance)
+  oz          ounce (mass)
+  oz_ap       ounce, apothecary (mass)
+  oz_tr       ounce, troy (mass)
+  P           Poise (dynamic viscosity)
+  Pa          Pascal (pressure)
+  pc          parsec (length)
+  pc_br       pace (length)
+  pca         pica (length)
+  pca_pr      Printer's pica (length)
+  pH          pH (acidity)
+  ph          phot (illuminance)
+  pi          the number pi (number)
+  pied        pied (length)
+  pk          peck, U.S. (dry volume)
+  pk_br       peck, British (volume)
+  pnt         point (length)
+  pnt_pr      Printer's point (length)
+  pouce       pouce (length)
+  ppb         parts per billion (fraction)
+  ppm         parts per million (fraction)
+  ppth        parts per thousand (fraction)
+  pptr        parts per trillion (fraction)
+  PRU         peripheral vascular resistance unit (fluid resistance)
+  psi         pound per square inch (pressure)
+  pt          pint, U.S. (fluid volume)
+  pt_br       pint, British (volume)
+  pwt_tr      pennyweight (mass)
+  qt          quart, U.S. (fluid volume)
+  qt_br       quart, British (volume)
+  R           Roentgen (ion dose)
+  rad         radian (plane angle)
+  RAD         radiation absorbed dose (energy dose)
+  rch         Ramden's chain, U.S. (length)
+  rd          rod, U.S. (length)
+  rd_br       rod, British (length)
+  REM         radiation equivalent man (dose equivalent)
+  rlk_us      link for Ramden's chain (length)
+  s           second (time)
+  S           Siemens (electric conductance)
+  sb          stilb (lum. intensity density)
+  sc_ap       scruple, apothecary (mass)
+  sct         section (area)
+  scwt        short hundredweight (mass)
+  smgy-U      Somogyi unit (biologic activity of amylase)
+  sph         spere (solid angle)
+  sr          streadian (solid angle)
+  st          stere (volume)
+  St          Stokes (kinematic viscosity)
+  ston        short ton (mass)
+  stone       stone (mass)
+  Sv          Sievert (dose equivalent)
+  Sv-U        Svedberg unit (sedimentation coefficient)
+  T           Tesla (magnetic flux density)
+  t           tonne (mass)
+  tb-U        tuberculin unit (biologic activity of tuberculin)
+  tbs         tablespoon, U.S. (volume)
+  todd-U      Todd unit (biologic activity antistreptolysin O)
+  tsp         teaspoon, U.S. (volume)
+  twp         township (area)
+  u           unified atomic mass unit (mass)
+  U           Unit (catalytic activity)
+  USP-U       U.S. Pharmacopeia unit (arbitrary)
+  V           Volt (electric potential)
+  W           Watt (power)
+  Wb          Weber (magnetic flux)
+  wk          week (time)
+  yd          yard, international (length)
+  yd_br       yard, British (length)
+  yd_us       yard, U.S. (length)
+
+=head1 PREFIXES
+
+Standard SI prefixes:
+
+  y           yocto (10^-24)
+  z           zepto (10^-21)
+  a           atto  (10^-18)
+  f           femto (10^-15)
+  p           pico  (10^-12)
+  n           nano  (10^-9)
+  u           micro (10^-6)
+  m           milli (10^-3)
+  c           centi (10^-2)
+  d           deci  (10^-1)
+  da          deka  (10)
+  h           hecto (10^2)
+  k           kilo  (10^3)
+  G           giga  (10^9)
+  M           mega  (10^6)
+  T           tera  (10^12)
+  P           peta  (10^15)
+  E           exa   (10^18)
+  Z           zetta (10^21)
+  Y           yotta (10^24)
+
+Binary power prefixes:
+
+  Ki          kibi  (2^10)
+  Mi          mebi  (2^20)
+  Gi          gibi  (2^30)
+  Ti          tebi  (2^40)
+
+=head1 EXAMPLES
+
+A few examples of combined units strings:
+
+  /cm3        per cubic centimeter
+  in2         square inches
+  kg.m/s2     Newtons (N)
+  m3/kg.s2    units of [G]
+  10^100      googols
+
+=head1 HISTORY
+
+  2006-12-14 - PH Created
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://aurora.regenstrief.org/UCUM/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::MIE(3pm)|Image::ExifTool::MIE>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/MIFF.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/MIFF.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/MIFF.pm	(revision 20131)
@@ -0,0 +1,283 @@
+#------------------------------------------------------------------------------
+# File:         MIFF.pm
+#
+# Description:  Read Magick Image File Format meta information
+#
+# Revisions:    06/10/2005 - P. Harvey Created
+#
+# References:   1) http://www.imagemagick.org/script/miff.php
+#               2) http://www.cs.uni.edu/Help/ImageMagick/www/miff.html
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::MIFF;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.03';
+
+# MIFF chunks
+%Image::ExifTool::MIFF::Main = (
+    GROUPS => { 2 => 'Image' },
+    NOTES => q{
+The MIFF format allows aribrary tag names to be used.  Only the standard tag
+names are listed below, however ExifTool will decode any tags found in the
+image.
+    },
+   'background-color' => 'BackgroundColor',
+   'blue-primary' => 'BluePrimary',
+   'border-color' => 'BorderColor',
+   'matt-color' => 'MattColor',
+    class => 'Class',
+    colors => 'Colors',
+    colorspace => 'Colorspace',
+    columns => 'ImageWidth',
+    compression => 'Compression',
+    delay => 'Delay',
+    depth => 'Depth',
+    dispose => 'Dispose',
+    gamma => 'Gamma',
+   'green-primary' => 'GreenPrimary',
+    id => 'ID',
+    iterations => 'Iterations',
+    label => 'Label',
+    matte => 'Matte',
+    montage => 'Montage',
+    packets => 'Packets',
+    page => 'Page',
+    # profile tags.  Note the SubDirectory is not used by ProcessMIFF(),
+    # but is inserted for documentation purposes only
+   'profile-APP1' => [
+        # [this list is just for the sake of the documentation]
+        {
+            Name => 'APP1_Profile',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Exif::Main',
+            },
+        },
+        {
+            Name => 'APP1_Profile',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::XMP::Main',
+            },
+        },
+    ],
+   'profile-exif' => { # haven't seen this, but it would make sense - PH
+        Name => 'EXIF_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+        },
+    },
+   'profile-icc' => {
+        Name => 'ICC_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+        },
+    },
+   'profile-iptc' => {
+        Name => 'IPTC_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Photoshop::Main',
+        },
+    },
+   'profile-xmp' => { # haven't seen this, but it would make sense - PH
+        Name => 'XMP_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::XMP::Main',
+        },
+    },
+   'red-primary' => 'RedPrimary',
+   'rendering-intent' => 'RenderingIntent',
+    resolution => 'Resolution',
+    rows => 'ImageHeight',
+    scene => 'Scene',
+    signature => 'Signature',
+    units => 'Units',
+   'white-point' => 'WhitePoint',
+);
+
+#------------------------------------------------------------------------------
+# Extract meta information from a MIFF image
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid MIFF image
+sub ProcessMIFF($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->{OPTIONS}->{Verbose};
+    my ($hdr, $buff);
+
+    # validate the MIFF file (note: MIFF files _may_ begin with other
+    # characters, but this starting sequence is strongly suggested.)
+    return 0 unless $raf->Read($hdr, 14) == 14;
+    return 0 unless $hdr eq 'id=ImageMagick';
+    $exifTool->SetFileType();   # set the FileType tag
+
+    # set end-of-line character sequence to read to end of the TEXT
+    # section for new-type MIFF files (text ends with Colon+Ctrl-Z)
+    # Old MIFF files end with Colon+Linefeed, so this will likely
+    # slurp those entire files, which will be slower, but will work
+    # OK except that the profile information won't be decoded
+    my $oldsep = $/;
+    $/ = ":\x1a";
+
+    my $mode = '';
+    my @profiles;
+    if ($raf->ReadLine($buff)) {
+        chomp $buff;    # remove end-of-line chars
+        my $tagTablePtr = GetTagTable('Image::ExifTool::MIFF::Main');
+        my @entries = split ' ', $buff;
+        unshift @entries, $hdr; # put the ID back in
+        my ($tag, $val);
+        foreach (@entries) {
+            if ($mode eq 'com') {
+                $mode = '' if /\}$/;
+                next;
+            } elsif (/^\{/) {
+                $mode = 'com';  # read to the end of the comment
+                next;
+            }
+            if ($mode eq 'val') {
+                $val .= " $_";  # join back together with a space
+                next unless /\}$/;
+                $mode = '';
+                $val =~ s/(^\{|\}$)//g; # remove braces
+            } elsif (/(.+)=(.+)/) {
+                ($tag, $val) = ($1, $2);
+                if ($val =~ /^\{/) {
+                    $mode = 'val';      # read to the end of the value data
+                    next;
+                }
+            } elsif (/^:/) {
+                # this could be the end of an old-style MIFF file
+                last;
+            } else {
+                # something we don't recognize -- stop parsing here
+                $exifTool->Warn('Unrecognized MIFF data');
+                last;
+            }
+            my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+            unless ($tagInfo) {
+                $tagInfo = { Name => $tag };
+                Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            }
+            $verbose and $exifTool->VerboseInfo($tag, $tagInfo,
+                Table  => $tagTablePtr,
+                DataPt => \$val,
+            );
+            # handle profile tags specially
+            if ($tag =~ /^profile-(.*)/) {
+                push @profiles, [$1, $val];
+            } else {
+                $exifTool->FoundTag($tagInfo, $val);
+            }
+        }
+    }
+    $/ = $oldsep;   # restore separator to original value
+
+    # process profile information
+    foreach (@profiles) {
+        my ($type, $len) = @{$_};
+        unless ($len =~ /^\d+$/) {
+            $exifTool->Warn("Invalid length for $type profile");
+            last;   # don't try to read the rest
+        }
+        unless ($raf->Read($buff, $len) == $len) {
+            $exifTool->Warn("Error reading $type profile ($len bytes)");
+            next;
+        }
+        my $processed = 0;
+        my %dirInfo = (
+            Parent   => 'PNG',
+            DataPt   => \$buff,
+            DataPos  => $raf->Tell() - $len,
+            DataLen  => $len,
+            DirStart => 0,
+            DirLen   => $len,
+        );
+        if ($type eq 'icc') {
+            # ICC Profile information
+            my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
+            $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        } elsif ($type eq 'iptc') {
+            if ($buff =~ /^8BIM/) {
+                # Photoshop information
+                my $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
+                $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            }
+        # I haven't seen 'exif' or 'xmp' profile types yet, but I have seen them
+        # in newer PNG files so presumably they are possible here as well - PH
+        } elsif ($type eq 'APP1' or $type eq 'exif' or $type eq 'xmp') {
+            if ($buff =~ /^$Image::ExifTool::exifAPP1hdr/) {
+                # APP1 EXIF
+                my $hdrLen = length($Image::ExifTool::exifAPP1hdr);
+                $dirInfo{DirStart} += $hdrLen;
+                $dirInfo{DirLen} -= $hdrLen;
+                # use the usual position for EXIF data: 12 bytes from start of file
+                # (this may be wrong, but I can't see where the PNG stores this information)
+                $dirInfo{Base} = 12; # this is the usual value
+                $processed = $exifTool->ProcessTIFF(\%dirInfo);
+            } elsif ($buff =~ /^$Image::ExifTool::xmpAPP1hdr/) {
+                # APP1 XMP
+                my $hdrLen = length($Image::ExifTool::xmpAPP1hdr);
+                my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
+                $dirInfo{DirStart} += $hdrLen;
+                $dirInfo{DirLen} -= $hdrLen;
+                $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            }
+        }
+        unless ($processed) {
+            $exifTool->Warn("Unknown MIFF $type profile data");
+            if ($verbose) {
+                $exifTool->VerboseDir($type, 0, $len);
+                Image::ExifTool::HexDump(\$buff, undef,
+                    Out => $exifTool->Options('TextOut')
+                ) if $verbose > 2;
+             }
+         }
+    }
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::MIFF - Read Magick Image File Format meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to read MIFF
+(Magick Image File Format) images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.imagemagick.org/script/miff.php>
+
+=item L<http://www.cs.uni.edu/Help/ImageMagick/www/miff.html>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/MIFF Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/MNG.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/MNG.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/MNG.pm	(revision 20131)
@@ -0,0 +1,684 @@
+#------------------------------------------------------------------------------
+# File:         MNG.pm
+#
+# Description:  MNG and JNG meta information tags
+#
+# Revisions:    06/23/2005 - P. Harvey Created
+#
+# References:   1) http://www.libpng.org/pub/mng/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::MNG;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.00';
+
+# MNG chunks
+%Image::ExifTool::MNG::Main = (
+    GROUPS => { 2 => 'Image' },
+    NOTES => q{
+        This table contains definitions for tags found in MNG and JNG images.  MNG
+        is a superset of PNG and JNG, so a MNG image may contain any of these tags
+        as well as any PNG tags.  Conversely, only some of these tags are valid for
+        JNG images.
+    },
+    BACK => {
+        Name => 'Background',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::Background' },
+    },
+    BASI => {
+        Name => 'BasisObject',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::BasisObject' },
+    },
+    CLIP => {
+        Name => 'ClipObjects',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::ClipObjects' },
+    },
+    CLON => {
+        Name => 'CloneObject',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::CloneObject' },
+    },
+    DBYK => {
+        Name => 'DropByKeyword',
+        Binary => 1,
+    },
+    DEFI => {
+        Name => 'DefineObject',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::DefineObject' },
+    },
+    DHDR => {
+        Name => 'DeltaPNGHeader',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::DeltaPNGHeader' },
+    },
+    DISC => {
+        Name => 'DiscardObjects',
+        ValueConv => 'join(" ",unpack("n*",$val))',
+    },
+    DROP => {
+        Name => 'DropChunks',
+        ValueConv => 'join(" ",$val=~/..../g)',
+    },
+#   ENDL
+    eXPi => {
+        Name => 'ExportImage',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::ExportImage' },
+    },
+    fPRI => {
+        Name => 'FramePriority',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::FramePriority' },
+    },
+    FRAM => {
+        Name => 'Frame',
+        Binary => 1,
+    },
+#   IJNG
+#   IPNG
+#   JDAA (JNG)
+#   JDAT (JNG)
+    JHDR => { # (JNG)
+        Name => 'JNGHeader',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::JNGHeader' },
+    },
+#   JSEP (JNG)
+    LOOP => {
+        Name => 'Loop',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::Loop' },
+    },
+    MAGN => {
+        Name => 'MagnifyObject',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::MagnifyObject' },
+    },
+#   MEND
+    MHDR => {
+        Name => 'MNGHeader',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::MNGHeader' },
+    },
+    MOVE => {
+        Name => 'MoveObjects',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::MoveObjects' },
+    },
+    nEED => {
+        Name => 'ResourcesNeeded',
+        Binary => 1,
+    },
+    ORDR => {
+        Name => 'OrderingRestrictions',
+        Binary => 1,
+    },
+    PAST => {
+        Name => 'PasteImage',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::PasteImage' },
+    },
+    pHYg => {
+        Name => 'GlobalPixelSize',
+        SubDirectory => { TagTable => 'Image::ExifTool::PNG::PhysicalPixel' },
+    },
+    PPLT => {
+        Name => 'PartialPalette',
+        Binary => 1,
+    },
+    PROM => {
+        Name => 'PromoteParent',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::PromoteParent' },
+    },
+    SAVE => {
+        Name => 'SaveObjects',
+        Binary => 1,
+    },
+    SEEK => {
+        Name => 'SeekPoint',
+        ValueConv => '$val=~s/\0.*//s; $val',
+    },
+    SHOW => {
+        Name => 'ShowObjects',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::ShowObjects' },
+    },
+    TERM => {
+        Name => 'TerminationAction',
+        SubDirectory => { TagTable => 'Image::ExifTool::MNG::TerminationAction' },
+    },
+);
+
+# MNG MHDR chunk
+%Image::ExifTool::MNG::MNGHeader = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    FORMAT => 'int32u',
+    0 => 'ImageWidth',
+    1 => 'ImageHeight',
+    2 => 'TicksPerSecond',
+    3 => 'NominalLayerCount',
+    4 => 'NominalFrameCount',
+    5 => 'NominalPlayTime',
+    6 => {
+        Name => 'SimplicityProfile',
+        PrintConv => 'sprintf("0x%.8x", $val)',
+    },
+);
+
+# MNG BASI chunk
+%Image::ExifTool::MNG::BasisObject = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'ImageWidth',
+        Format => 'int32u',
+    },
+    4 => {
+        Name => 'ImageHeight',
+        Format => 'int32u',
+    },
+    8 => 'BitDepth',
+    9 => {
+        Name => 'ColorType',
+        RawConv => '$Image::ExifTool::PNG::colorType = $val',
+        PrintConv => {
+            0 => 'Grayscale',
+            2 => 'RGB',
+            3 => 'Palette',
+            4 => 'Grayscale with Alpha',
+            6 => 'RGB with Alpha',
+        },
+    },
+    10 => {
+        Name => 'Compression',
+        PrintConv => { 0 => 'Deflate/Inflate' },
+    },
+    11 => {
+        Name => 'Filter',
+        PrintConv => { 0 => 'Adaptive' },
+    },
+    12 => {
+        Name => 'Interlace',
+        PrintConv => { 0 => 'Noninterlaced', 1 => 'Adam7 Interlace' },
+    },
+    13 => {
+        Name => 'RedSample',
+        Format => 'int32u',
+    },
+    17 => {
+        Name => 'GreenSample',
+        Format => 'int32u',
+    },
+    21 => {
+        Name => 'BlueSample',
+        Format => 'int32u',
+    },
+    25 => {
+        Name => 'AlphaSample',
+        Format => 'int32u',
+    },
+    26 => 'Viewable',
+);
+
+# MNG LOOP chunk
+%Image::ExifTool::MNG::Loop = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => 'NestLevel',
+    1 => {
+        Name => 'IterationCount',
+        Format => 'int32u',
+    },
+    5 => {
+        Name => 'TerminationCondition',
+        PrintConv => {
+            0 => 'Deterministic, not cacheable',
+            1 => 'Decoder discretion, not cacheable',
+            2 => 'User discretion, not cacheable',
+            3 => 'External signal, not cacheable',
+            4 => 'Deterministic, cacheable',
+            5 => 'Decoder discretion, cacheable',
+            6 => 'User discretion, cacheable',
+            7 => 'External signal, cacheable',
+        },
+    },
+    6 => {
+        Name => 'IterationMinMax',
+        Format => 'int32u[2]',
+    },
+    14 => {
+        Name => 'SignalNumber',
+        Format => 'int32u',
+    },
+);
+
+# MNG DEFI chunk
+%Image::ExifTool::MNG::DefineObject = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'ObjectID',
+        Format => 'int16u',
+    },
+    2 => 'DoNotShow',
+    3 => 'ConcreteFlag',
+    4 => {
+        Name => 'XYLocation',
+        Format => 'int32u[2]',
+    },
+    12 => {
+        Name => 'ClippingBoundary',
+        Format => 'int32u[4]',
+    },
+);
+
+# MNG CLON chunk
+%Image::ExifTool::MNG::CloneObject = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'SourceID',
+        Format => 'int16u',
+    },
+    2 => {
+        Name => 'CloneID',
+        Format => 'int16u',
+    },
+    4 => {
+        Name => 'CloneType',
+        PrintConv => { 0 => 'Full', 1 => 'Parital', 2 => 'Renumber object' },
+    },
+    5 => 'DoNotShow',
+    6 => 'ConcreteFlag',
+    7 => {
+        Name => 'LocalDeltaType',
+        PrintConv => { 0 => 'Absolute', 1 => 'Relative' },
+    },
+    8 => {
+        Name => 'DeltaXY',
+        Format => 'int32u[2]',
+    },
+);
+
+# MNG PAST chunk
+%Image::ExifTool::MNG::PasteImage = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'DestinationID',
+        Format => 'int16u',
+    },
+    2 => {
+        Name => 'TargetDeltaType',
+        PrintConv => { 0 => 'Absolute', 1 => 'Relative' },
+    },
+    3 => {
+        Name => 'TargetXY',
+        Format => 'int32u[2]',
+    },
+    11 => {
+        Name => 'SourceID',
+        Format => 'int16u',
+    },
+    13 => {
+        Name => 'CompositionMode',
+        PrintConv => { 0 => 'Over', 1 => 'Replace', 2 => 'Under' },
+    },
+    14 => {
+        Name => 'Orientation',
+        PrintConv => {
+            0 => 'Same as source',
+            2 => 'Flipped left-right, then up-down',
+            4 => 'Flipped left-right',
+            6 => 'Flipped up-down',
+            8 => 'Tiled',
+        },
+    },
+    15 => {
+        Name => 'OffsetOrigin',
+        PrintConv => { 0 => 'Desination Origin', 1 => 'Target Origin' },
+    },
+    16 => {
+        Name => 'OffsetXY',
+        Format => 'int32u[2]',
+    },
+    24 => {
+        Name => 'BoundaryOrigin',
+        PrintConv => { 0 => 'Desination Origin', 1 => 'Target Origin' },
+    },
+    25 => {
+        Name => 'PastClippingBoundary',
+        Format => 'int32u[4]',
+    },
+);
+
+my %magMethod = (
+    0 => 'No Magnification',
+    1 => 'Pixel Replication',
+    2 => 'Linear Interpolation',
+    3 => 'Closest Pixel',
+    4 => 'Color Linear Interpolation and Alpha Closest Pixel',
+    5 => 'Color Closest Pixel and Alpha Linear Interpolation',
+);
+
+# MNG MAGN chunk
+%Image::ExifTool::MNG::MagnifyObject = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'FirstObjectID',
+        Format => 'int16u',
+    },
+    2 => {
+        Name => 'LastObjectID',
+        Format => 'int16u',
+    },
+    4 => {
+        Name => 'XMethod',
+        PrintConv => \%magMethod,
+    },
+    5 => {
+        Name => 'XMag',
+        Format => 'int16u',
+    },
+    7 => {
+        Name => 'YMag',
+        Format => 'int16u',
+    },
+    9 => {
+        Name => 'LeftMag',
+        Format => 'int16u',
+    },
+    11 => {
+        Name => 'RightMag',
+        Format => 'int16u',
+    },
+    13 => {
+        Name => 'TopMag',
+        Format => 'int16u',
+    },
+    15 => {
+        Name => 'BottomMag',
+        Format => 'int16u',
+    },
+    17 => {
+        Name => 'YMethod',
+        PrintConv => \%magMethod,
+    },
+);
+
+# MNG TERM chunk
+%Image::ExifTool::MNG::TerminationAction = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'TerminationAction',
+        PrintConv => {
+            0 => 'Show Last Frame',
+            1 => 'Display Nothing',
+            2 => 'Show First Frame',
+            3 => 'Repeat Sequence',
+        },
+    },
+    1 => {
+        Name => 'IterationEndAction',
+        PrintConv => {
+            0 => 'Show Last Frame',
+            1 => 'Display Nothing',
+            2 => 'Show First Frame',
+        },
+    },
+    2 => {
+        Name => 'Delay',
+        Format => 'int32u',
+    },
+    6 => {
+        Name => 'IterationMax',
+        Format => 'int32u',
+    },
+);
+
+# MNG BACK chunk
+%Image::ExifTool::MNG::Background = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'BackgroundColor',
+        Format => 'int16u[3]',
+    },
+    6 => {
+        Name => 'MandatoryBackground',
+        PrintConv => {
+            0 => 'Color and Image Advisory',
+            1 => 'Color Mandatory, Image Advisory',
+            2 => 'Color Advisory, Image Mandatory',
+            3 => 'Color and Image Mandatory',
+        },
+    },
+    7 => {
+        Name => 'BackgroundImageID',
+        Format => 'int16u',
+    },
+    9 => {
+        Name => 'BackgroundTiling',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+);
+
+# MNG MOVE chunk
+%Image::ExifTool::MNG::MoveObjects = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'FirstObject',
+        Format => 'int16u',
+    },
+    2 => {
+        Name => 'LastObject',
+        Format => 'int16u',
+    },
+    4 => {
+        Name => 'DeltaType',
+        PrintConv => { 0 => 'Absolute', 1 => 'Relative' },
+    },
+    5 => {
+        Name => 'DeltaXY',
+        Format => 'int32u[2]',
+    },
+);
+
+# MNG CLIP chunk
+%Image::ExifTool::MNG::ClipObjects = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'FirstObject',
+        Format => 'int16u',
+    },
+    2 => {
+        Name => 'LastObject',
+        Format => 'int16u',
+    },
+    4 => {
+        Name => 'DeltaType',
+        PrintConv => { 0 => 'Absolute', 1 => 'Relative' },
+    },
+    5 => {
+        Name => 'ClipBoundary',
+        Format => 'int32u[4]',
+    },
+);
+
+# MNG SHOW chunk
+%Image::ExifTool::MNG::ShowObjects = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'FirstObject',
+        Format => 'int16u',
+    },
+    2 => {
+        Name => 'LastObject',
+        Format => 'int16u',
+    },
+    4 => 'ShowMode',
+);
+
+# MNG eXPI chunk
+%Image::ExifTool::MNG::ExportImage = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'SnapshotID',
+        Format => 'int16u',
+    },
+    2 => {
+        Name => 'SnapshotName',
+        Format => 'string',
+    },
+);
+
+# MNG fPRI chunk
+%Image::ExifTool::MNG::FramePriority = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'DeltaType',
+        PrintConv => { 0 => 'Absolute', 1 => 'Relative' },
+    },
+    2 => 'Priority',
+);
+
+# MNG DHDR chunk
+%Image::ExifTool::MNG::DeltaPNGHeader = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'ObjectID',
+        Format => 'int16u',
+    },
+    2 => {
+        Name => 'ImageType',
+        PrintConv => {
+            0 => 'Unspecified',
+            1 => 'PNG',
+            2 => 'JNG',
+        },
+    },
+    3 => {
+        Name => 'DeltaType',
+        PrintConv => {
+            0 => 'Full Replacement',
+            1 => 'Pixel Addition',
+            2 => 'Alpha Addition',
+            3 => 'Color Addition',
+            4 => 'Pixel Replacement',
+            5 => 'Alpha Replacement',
+            6 => 'Color Replacement',
+            7 => 'No Change',
+        },
+    },
+    4 => {
+        Name => 'BlockSize',
+        Format => 'int32u[2]',
+    },
+    12 => {
+        Name => 'BlockLocation',
+        Format => 'int32u[2]',
+    },
+);
+
+# MNG PROM chunk
+%Image::ExifTool::MNG::PromoteParent = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => 'NewColorType',
+    1 => 'NewBitDepth',
+    2 => {
+        Name => 'FillMethod',
+        PrintConv => { 0 => 'Bit Replication', 1 => 'Zero Fill' },
+    },
+);
+
+# JNG JHDR chunk
+%Image::ExifTool::MNG::JNGHeader = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'ImageWidth',
+        Format => 'int32u',
+    },
+    4 => {
+        Name => 'ImageHeight',
+        Format => 'int32u',
+    },
+    8 => {
+        Name => 'ColorType',
+        PrintConv => {
+            8 => 'Gray',
+            10 => 'Color',
+            12 => 'Gray Alpha',
+            14 => 'Color Alpha',
+        },
+    },
+    9 => 'BitDepth',
+    10 => {
+        Name => 'Compression',
+        PrintConv => { 8 => 'Huffman-coded baseline JPEG' },
+    },
+    11 => {
+        Name => 'Interlace',
+        PrintConv => { 0 => 'Sequential', 8 => 'Progressive' },
+    },
+    12 => 'AlphaBitDepth',
+    13 => {
+        Name => 'AlphaCompression',
+        PrintConv => {
+            0 => 'MNG Grayscale IDAT',
+            8 => 'JNG 8-bit Grayscale JDAA',
+        },
+    },
+    14 => {
+        Name => 'AlphaFilter',
+        PrintConv => { 0 => 'Adaptive MNG (N/A for JPEG)' },
+    },
+    15 => {
+        Name => 'AlphaInterlace',
+        PrintConv => { 0 => 'Noninterlaced' },
+    },
+);
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::MNG - MNG and JNG meta information tags
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read MNG
+(Multi-image Network Graphics) and JNG (JPEG Network Graphics) images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.libpng.org/pub/mng/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/MNG Tags>,
+L<Image::ExifTool::TagNames/PNG Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/MPC.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/MPC.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/MPC.pm	(revision 20131)
@@ -0,0 +1,156 @@
+#------------------------------------------------------------------------------
+# File:         MPC.pm
+#
+# Description:  Read Musepack audio meta information
+#
+# Revisions:    11/14/2006 - P. Harvey Created
+#
+# References:   1) http://www.musepack.net/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::MPC;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::FLAC;
+
+$VERSION = '1.00';
+
+# MPC metadata blocks
+%Image::ExifTool::MPC::Main = (
+    PROCESS_PROC => \&Image::ExifTool::FLAC::ProcessBitStream,
+    GROUPS => { 2 => 'Audio' },
+    NOTES => q{
+        Tags used in Musepack (MPC) audio files.  ExifTool also extracts ID3 and APE
+        information from these files.
+    },
+    'Bit032-063' => 'TotalFrames',
+    'Bit080-081' => {
+        Name => 'SampleRate',
+        PrintConv => {
+            0 => 44100,
+            1 => 48000,
+            2 => 37800,
+            3 => 32000,
+        },
+    },
+    'Bit084-087' => {
+        Name => 'Quality',
+        PrintConv => {
+             1 => 'Unstable/Experimental',
+             5 => '0',
+             6 => '1',
+             7 => '2 (Telephone)',
+             8 => '3 (Thumb)',
+             9 => '4 (Radio)',
+            10 => '5 (Standard)',
+            11 => '6 (Xtreme)',
+            12 => '7 (Insane)',
+            13 => '8 (BrainDead)',
+            14 => '9',
+            15 => '10',
+       },
+    },
+    'Bit088-093' => 'MaxBand',
+    'Bit096-111' => 'ReplayGainTrackPeak',
+    'Bit112-127' => 'ReplayGainTrackGain',
+    'Bit128-143' => 'ReplayGainAlbumPeak',
+    'Bit144-159' => 'ReplayGainAlbumGain',
+    'Bit179' => {
+        Name => 'FastSeek',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    'Bit191' => {
+        Name => 'Gapless',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    'Bit216-223' => {
+        Name => 'EncoderVersion',
+        PrintConv => '$val =~ s/(\d)(\d)(\d)$/$1.$2.$3/; $val',
+    },
+);
+
+#------------------------------------------------------------------------------
+# Extract information from an MPC file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# - Just looks for MPC trailer if FileType is already set
+# Returns: 1 on success, 0 if this wasn't a valid MPC file
+sub ProcessMPC($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+
+    # must first check for leading ID3 information
+    unless ($exifTool->{DONE_ID3}) {
+        require Image::ExifTool::ID3;
+        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
+    }
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+
+    # check MPC signature
+    $raf->Read($buff, 32) == 32 and $buff =~ /^MP\+(.)/s or return 0;
+    my $vers = ord($1) & 0x0f;
+    $exifTool->SetFileType();
+
+    # extract audio information (currently only from version 7 MPC files)
+    if ($vers == 0x07) {
+        SetByteOrder('II');
+        my $pos = $raf->Tell() - 32;
+        if ($exifTool->Options('Verbose')) {
+            $exifTool->VPrint(0, "MPC Header (32 bytes):\n");
+            $exifTool->VerboseDump(\$buff, DataPos => $pos);
+        }
+        my $tagTablePtr = GetTagTable('Image::ExifTool::MPC::Main');
+        my %dirInfo = ( DataPt => \$buff, DataPos => $pos );
+        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+    } else {
+        $exifTool->Warn('Audio info not currently extracted from this version MPC file');
+    } 
+
+    # process APE trailer if it exists
+    require Image::ExifTool::APE;
+    Image::ExifTool::APE::ProcessAPE($exifTool, $dirInfo);
+
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::MPC - Read Musepack audio meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to extract meta
+information from Musepack (MPC) audio files.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.musepack.net/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/MPC Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/MPEG.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/MPEG.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/MPEG.pm	(revision 20131)
@@ -0,0 +1,520 @@
+#------------------------------------------------------------------------------
+# File:         MPEG.pm
+#
+# Description:  Read MPEG-1 and MPEG-2 meta information
+#
+# Revisions:    05/11/2006 - P. Harvey Created
+#
+# References:   1) http://www.mp3-tech.org/
+#               2) http://www.getid3.org/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::MPEG;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.04';
+
+%Image::ExifTool::MPEG::Audio = (
+    GROUPS => { 2 => 'Audio' },
+    'Bit11-12' => {
+        Name => 'MPEGAudioVersion',
+        RawConv => '$self->{MPEG_Vers} = $val',
+        PrintConv => {
+            0 => 2.5,
+            2 => 2,
+            3 => 1,
+        },
+    },
+    'Bit13-14' => {
+        Name => 'AudioLayer',
+        RawConv => '$self->{MPEG_Layer} = $val',
+        PrintConv => {
+            1 => 3,
+            2 => 2,
+            3 => 1,
+        },
+    },
+    # Bit 15 indicates CRC protection
+    'Bit16-19' => [
+        {
+            Name => 'AudioBitrate',
+            Condition => '$self->{MPEG_Vers} == 3 and $self->{MPEG_Layer} == 3',
+            Notes => 'version 1, layer 1',
+            PrintConv => {
+                0 => 'free',
+                1 => 32000,
+                2 => 64000,
+                3 => 96000,
+                4 => 128000,
+                5 => 160000,
+                6 => 192000,
+                7 => 224000,
+                8 => 256000,
+                9 => 288000,
+                10 => 320000,
+                11 => 352000,
+                12 => 384000,
+                13 => 416000,
+                14 => 448000,
+            },
+        },
+        {
+            Name => 'AudioBitrate',
+            Condition => '$self->{MPEG_Vers} == 3 and $self->{MPEG_Layer} == 2',
+            Notes => 'version 1, layer 2',
+            PrintConv => {
+                0 => 'free',
+                1 => 32000,
+                2 => 48000,
+                3 => 56000,
+                4 => 64000,
+                5 => 80000,
+                6 => 96000,
+                7 => 112000,
+                8 => 128000,
+                9 => 160000,
+                10 => 192000,
+                11 => 224000,
+                12 => 256000,
+                13 => 320000,
+                14 => 384000,
+            },
+        },
+        {
+            Name => 'AudioBitrate',
+            Condition => '$self->{MPEG_Vers} == 3 and $self->{MPEG_Layer} == 1',
+            Notes => 'version 1, layer 3',
+            PrintConv => {
+                0 => 'free',
+                1 => 32000,
+                2 => 40000,
+                3 => 48000,
+                4 => 56000,
+                5 => 64000,
+                6 => 80000,
+                7 => 96000,
+                8 => 112000,
+                9 => 128000,
+                10 => 160000,
+                11 => 192000,
+                12 => 224000,
+                13 => 256000,
+                14 => 320000,
+            },
+        },
+        {
+            Name => 'AudioBitrate',
+            Condition => '$self->{MPEG_Vers} != 3 and $self->{MPEG_Layer} == 3',
+            Notes => 'version 2 or 2.5, layer 1',
+            PrintConv => {
+                0 => 'free',
+                1 => 32000,
+                2 => 48000,
+                3 => 56000,
+                4 => 64000,
+                5 => 80000,
+                6 => 96000,
+                7 => 112000,
+                8 => 128000,
+                9 => 144000,
+                10 => 160000,
+                11 => 176000,
+                12 => 192000,
+                13 => 224000,
+                14 => 256000,
+            },
+        },
+        {
+            Name => 'AudioBitrate',
+            Condition => '$self->{MPEG_Vers} != 3 and $self->{MPEG_Layer}',
+            Notes => 'version 2 or 2.5, layer 2 or 3',
+            PrintConv => {
+                0 => 'free',
+                1 => 8000,
+                2 => 16000,
+                3 => 24000,
+                4 => 32000,
+                5 => 40000,
+                6 => 48000,
+                7 => 56000,
+                8 => 64000,
+                9 => 80000,
+                10 => 96000,
+                11 => 112000,
+                12 => 128000,
+                13 => 144000,
+                14 => 160000,
+            },
+        },
+    ],
+    'Bit20-21' => [
+        {
+            Name => 'SampleRate',
+            Condition => '$self->{MPEG_Vers} == 3',
+            Notes => 'version 1',
+            PrintConv => {
+                0 => 44100,
+                1 => 48000,
+                2 => 32000,
+            },
+        },
+        {
+            Name => 'SampleRate',
+            Condition => '$self->{MPEG_Vers} == 2',
+            Notes => 'version 2',
+            PrintConv => {
+                0 => 22050,
+                1 => 24000,
+                2 => 16000,
+            },
+        },
+        {
+            Name => 'SampleRate',
+            Condition => '$self->{MPEG_Vers} == 0',
+            Notes => 'version 2.5',
+            PrintConv => {
+                0 => 11025,
+                1 => 12000,
+                2 => 8000,
+            },
+        },
+    ],
+    # Bit 22 - padding flag
+    # Bit 23 - private bit
+    'Bit24-25' => {
+        Name => 'ChannelMode',
+        PrintConv => {
+            0 => 'Stereo',
+            1 => 'Joint Stereo',
+            2 => 'Dual Channel',
+            3 => 'Single Channel',
+        },
+    },
+    'Bit26' => {
+        Name => 'MSStereo',
+        Condition => '$self->{MPEG_Layer} == 1',
+        Notes => 'layer 3',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    'Bit27' => {
+        Name => 'IntensityStereo',
+        Condition => '$self->{MPEG_Layer} == 1',
+        Notes => 'layer 3',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    'Bit26-27' => {
+        Name => 'ModeExtension',
+        Condition => '$self->{MPEG_Layer} > 1',
+        Notes => 'layer 1 or 2',
+        PrintConv => {
+            0 => 'Bands 4-31',
+            1 => 'Bands 8-31',
+            2 => 'Bands 12-31',
+            3 => 'Bands 16-31',
+        },
+    },
+    'Bit28'    => {
+        Name => 'CopyrightFlag',
+        PrintConv => {
+            0 => 'False',
+            1 => 'True',
+        },
+    },
+    'Bit29'    => {
+        Name => 'OriginalMedia',
+        PrintConv => {
+            0 => 'False',
+            1 => 'True',
+        },
+    },
+    'Bit30-31' => {
+        Name => 'Emphasis',
+        PrintConv => {
+            0 => 'None',
+            1 => '50/15 ms',
+            2 => 'reserved',
+            3 => 'CCIT J.17',
+        },
+    },
+);
+
+%Image::ExifTool::MPEG::Video = (
+    GROUPS => { 2 => 'Video' },
+    'Bit00-11' => 'ImageWidth',
+    'Bit12-23' => 'ImageHeight',
+    'Bit24-27' => {
+        Name => 'AspectRatio',
+        ValueConv => {
+            1 => 1,
+            2 => 0.6735,
+            3 => 0.7031,
+            4 => 0.7615,
+            5 => 0.8055,
+            6 => 0.8437,
+            7 => 0.8935,
+            8 => 0.9157,
+            9 => 0.9815,
+            10 => 1.0255,
+            11 => 1.0695,
+            12 => 1.0950,
+            13 => 1.1575,
+            14 => 1.2015,
+        },
+        PrintConv => {
+            1      => '1:1',
+            0.6735 => '0.6735',
+            0.7031 => '16:9, 625 line, PAL',
+            0.7615 => '0.7615',
+            0.8055 => '0.8055',
+            0.8437 => '16:9, 525 line, NTSC',
+            0.8935 => '0.8935',
+            0.9157 => '4:3, 625 line, PAL, CCIR601',
+            0.9815 => '0.9815',
+            1.0255 => '1.0255',
+            1.0695 => '1.0695',
+            1.0950 => '4:3, 525 line, NTSC, CCIR601',
+            1.1575 => '1.1575',
+            1.2015 => '1.2015',
+        },
+    },
+    'Bit28-31' => {
+        Name => 'FrameRate',
+        ValueConv => {
+            1 => 23.976,
+            2 => 24,
+            3 => 25,
+            4 => 29.97,
+            5 => 30,
+            6 => 50,
+            7 => 59.94,
+            8 => 60,
+        },
+        PrintConv => '"$val fps"',
+    },
+    'Bit32-49' => {
+        Name => 'VideoBitrate',
+        ValueConv => '$val eq 0x3ffff ? "Variable" : $val * 400',
+    },
+    # these tags not very interesting
+    #'Bit50'    => 'MarkerBit',
+    #'Bit51-60' => 'VBVBufferSize',
+    #'Bit61'    => 'ConstrainedParamFlag',
+    #'Bit62'    => 'IntraQuantMatrixFlag',
+);
+
+# composite tags
+%Image::ExifTool::MPEG::Composite = (
+    Duration => {
+        Groups => { 2 => 'Video' },
+        Require => {
+            0 => 'FileSize',
+        },
+        Desire => {
+            1 => 'MPEG:AudioBitrate',
+            2 => 'MPEG:VideoBitrate',
+        },
+        # calculate duration as file size divided by total bitrate
+        # (note: this is only approximate!)
+        ValueConv => q{
+            return undef unless $val[1] or $val[2];
+            return undef if $prt[1] and not $prt[1] =~ /^\d+$/;
+            return undef if $val[2] and not $val[2] =~ /^\d+$/;
+            return (8 * $val[0]) / (($prt[1]||0) + ($val[2]||0));
+        },
+        PrintConv => q{
+            my $h = int($val / 3600);
+            my $m = int($val / 60 - $h * 60);
+            my $s = $val - $h * 3600 - $m * 60;
+            return sprintf("%d:%.2d:%05.2f (approx)",$h,$m,$s);
+        },
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::MPEG');
+
+
+#------------------------------------------------------------------------------
+# Process information in an MPEG audio or video frame header
+# Inputs: 0) ExifTool object ref, 1) tag table ref, 2-N) list of 32-bit data words
+sub ProcessFrameHeader($$@)
+{
+    my ($exifTool, $tagTablePtr, @data) = @_;
+    my $tag;
+    foreach $tag (sort keys %$tagTablePtr) {
+        next unless $tag =~ /^Bit(\d{2})-?(\d{2})?/;
+        my ($b1, $b2) = ($1, $2 || $1);
+        my $index = int($b1 / 32);
+        my $word = $data[$index];
+        my $mask = 0;
+        foreach (0 .. ($b2 - $b1)) {
+            $mask += (1 << $_);
+        }
+        my $val = ($word >> (31 + 32*$index - $b2)) & $mask;
+        $exifTool->HandleTag($tagTablePtr, $tag, $val);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Read MPEG audio frame header
+# Inputs: 0) ExifTool object reference, 1) Reference to audio data
+# Returns: 1 on success, 0 if no audio header was found
+sub ProcessMPEGAudio($$)
+{
+    my ($exifTool, $buffPt) = @_;
+    my $word;
+
+    for (;;) {
+        # find frame sync
+        return 0 unless $$buffPt =~ m{(\xff.{3})}sg;
+        $word = unpack('N', $1);    # get audio frame header word
+        unless (($word & 0xffe00000) == 0xffe00000) {
+            pos($$buffPt) = pos($$buffPt) - 2;  # next possible location for frame sync
+            next;
+        }
+        # validate header as much as possible
+        if (($word & 0x180000) == 0x080000 or   # 01 is a reserved version ID
+            ($word & 0x060000) == 0x000000 or   # 00 is a reserved layer description
+            ($word & 0x00f000) == 0x00f000 or   # 1111 is a bad bitrate index
+            ($word & 0x000600) == 0x000600 or   # 11 is a reserved sampling frequency
+            ($word & 0x000003) == 0x000002)     # 10 is a reserved emphasis
+        {
+            return 0;   # invalid frame header
+        }
+        last;
+    }
+    # set file type if not done already
+    $exifTool->SetFileType() unless $exifTool->{VALUE}->{FileType};
+
+    my $tagTablePtr = GetTagTable('Image::ExifTool::MPEG::Audio');
+    ProcessFrameHeader($exifTool, $tagTablePtr, $word);
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Read MPEG video frame header
+# Inputs: 0) ExifTool object reference, 1) Reference to video data
+# Returns: 1 on success, 0 if no video header was found
+sub ProcessMPEGVideo($$)
+{
+    my ($exifTool, $buffPt) = @_;
+
+    return 0 unless length $$buffPt >= 4;
+    my ($w1, $w2) = unpack('N2', $$buffPt);
+    # validate as much as possible
+    if (($w1 & 0x000000f0) == 0x00000000 or     # 0000 is a forbidden aspect ratio
+        ($w1 & 0x000000f0) == 0x000000f0 or     # 1111 is a reserved aspect ratio
+        ($w1 & 0x0000000f) == 0 or              # frame rate must be 1-8
+        ($w1 & 0x0000000f) > 8)
+    {
+        return 0;
+    }
+    # set file type if not done already
+    $exifTool->SetFileType('MPEG') unless $exifTool->{VALUE}->{FileType};
+
+    my $tagTablePtr = GetTagTable('Image::ExifTool::MPEG::Video');
+    ProcessFrameHeader($exifTool, $tagTablePtr, $w1, $w2);
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Read MPEG audio and video frame headers
+# Inputs: 0) ExifTool object reference, 1) Reference to audio/video data
+# Returns: 1 on success, 0 if no video header was found
+sub ProcessMPEGAudioVideo($$)
+{
+    my ($exifTool, $buffPt) = @_;
+    my %found;
+    my $rtnVal = 0;
+    my %proc = ( audio => \&ProcessMPEGAudio, video => \&ProcessMPEGVideo );
+
+    delete $exifTool->{AudioBitrate};
+    delete $exifTool->{VideoBitrate};
+
+    while ($$buffPt =~ /\0\0\x01(\xb3|\xc0)/g) {
+        my $type = $1 eq "\xb3" ? 'video' : 'audio';
+        next if $found{$type};
+        my $len = length($$buffPt) - pos($$buffPt);
+        last if $len < 4;
+        $len > 256 and $len = 256;
+        my $dat = substr($$buffPt, pos($$buffPt), $len);
+        # process MPEG audio or video
+        if (&{$proc{$type}}($exifTool, \$dat)) {
+            $rtnVal = 1;
+            $found{$type} = 1;
+            # done if we found audio and video
+            last if scalar(keys %found) == 2;
+        }
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Read information frame an MPEG file
+# Inputs: 0) ExifTool object reference, 1) Directory information reference
+# Returns: 1 on success, 0 if this wasn't a valid MPEG file
+sub ProcessMPEG($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+
+    $raf->Read($buff, 4) == 4 or return 0;
+    return 0 unless $buff =~ /^\0\0\x01[\xb0-\xbf]/;
+    $exifTool->SetFileType();
+
+    $raf->Seek(0,0);
+    $raf->Read($buff, 65536*4) or return 0;
+
+    return ProcessMPEGAudioVideo($exifTool, \$buff);
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::MPEG - Read MPEG-1 and MPEG-2 meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read MPEG-1
+and MPEG-2 audio/video files.
+
+=head1 NOTES
+
+Since ISO charges money for the official MPEG specification, this module is
+based on unofficial sources which may be incomplete, inaccurate or outdated.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.mp3-tech.org/>
+
+=item L<http://www.getid3.org/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/MPEG Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/MakerNotes.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/MakerNotes.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/MakerNotes.pm	(revision 20131)
@@ -0,0 +1,1060 @@
+#------------------------------------------------------------------------------
+# File:         MakerNotes.pm
+#
+# Description:  Read and write EXIF maker notes
+#
+# Revisions:    11/11/2004 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::MakerNotes;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess);
+use Image::ExifTool::Exif;
+
+sub ProcessUnknown($$$);
+
+$VERSION = '1.34';
+
+my $debug;          # set to 1 to enabled debugging code
+
+# conditional list of maker notes
+# Notes:
+# - This is NOT a normal tag table!
+# - All byte orders are now specified because we can now
+#   write maker notes into a file with different byte ordering!
+# - Put these in alphabetical order to make TagNames documentation nicer.
+@Image::ExifTool::MakerNotes::Main = (
+    # decide which MakerNotes to use (based on camera make/model)
+    {
+        Name => 'MakerNoteCanon',
+        # (starts with an IFD)
+        Condition => '$self->{CameraMake} =~ /^Canon/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::Main',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteCasio',
+        # do negative lookahead assertion just to get tags
+        # in a nice order for documentation
+        # (starts with an IFD)
+        Condition => '$self->{CameraMake}=~/^CASIO(?! COMPUTER CO.,LTD)/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Casio::Main',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteCasio2',
+        # (starts with "QVC\0")
+        Condition => '$self->{CameraMake}=~/^CASIO COMPUTER CO.,LTD/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Casio::Type2',
+            Start => '$valuePtr + 6',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        # The Fuji programmers really botched this one up,
+        # but with a bit of work we can still read this directory
+        Name => 'MakerNoteFujiFilm',
+        # (starts with "FUJIFILM" -- also used by some Leica, Minolta and Sharp models)
+        Condition => '$$valPt =~ /^FUJIFILM/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FujiFilm::Main',
+            # there is an 8-byte maker tag (FUJIFILM) we must skip over
+            OffsetPt => '$valuePtr+8',
+            # the pointers are relative to the subdirectory start
+            # (before adding the offsetPt) - PH
+            Base => '$start',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteHP',  # PhotoSmart 720 (also Vivitar 3705, 3705B and 3715)
+        Condition => '$$valPt =~ /^(Hewlett-Packard|Vivitar)/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::HP::Main',
+            ProcessProc => \&ProcessUnknown,
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteHP2', # PhotoSmart E427
+        Condition => q{
+            $self->{CameraMake} =~ /^Hewlett-Packard/ and
+            $$valPt !~ /^.{8}Hewlett-Packard/s and
+            $$valPt !~ /^IIII/ and $$valPt =~ /^\d{3}.\0/s
+        },
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::HP::Type2',
+            Start => '$valuePtr',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteHP4', # PhotoSmart M627
+        Condition => '$$valPt =~ /^IIII\x04\0/',
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::HP::Type4',
+            Start => '$valuePtr',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteHP6', # PhotoSmart M425, M525 and M527
+        Condition => '$$valPt =~ /^IIII\x06\0/',
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::HP::Type6',
+            Start => '$valuePtr',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteJVC',
+        Condition => '$$valPt=~/^JVC /',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::JVC::Main',
+            Start => '$valuePtr + 4',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteJVCText',
+        Condition => '$self->{CameraMake}=~/^(JVC|Victor)/ and $$valPt=~/^VER:/',
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::JVC::Text',
+        },
+    },
+    {
+        Name => 'MakerNoteKodak1a',
+        Condition => '$self->{CameraMake}=~/^EASTMAN KODAK/ and $$valPt=~/^KDK INFO/',
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Main',
+            Start => '$valuePtr + 8',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteKodak1b',
+        Condition => '$self->{CameraMake}=~/^EASTMAN KODAK/ and $$valPt=~/^KDK/',
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Main',
+            Start => '$valuePtr + 8',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    {
+        # used by various Kodak, HP, Pentax and Minolta models
+        Name => 'MakerNoteKodak2',
+        Condition => q{
+            $$valPt =~ /^.{8}Eastman Kodak/s or
+            $$valPt =~ /^\x01\0[\0\x01]\0\0\0\x04\0[a-zA-Z]{4}/
+        },
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Type2',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    {
+        # not much to key on here, but we know the
+        # upper byte of the year should be 0x07:
+        Name => 'MakerNoteKodak3',
+        Condition => '$self->{CameraMake}=~/^EASTMAN KODAK/ and $$valPt=~/^.{12}\x07/s',
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Type3',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteKodak4',
+        Condition => '$self->{CameraMake}=~/^Eastman Kodak/ and $$valPt=~/^.{41}JPG/s',
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Type4',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteKodak5',
+        Condition => q{
+            $self->{CameraMake}=~/^EASTMAN KODAK/ and
+            ($self->{CameraModel}=~/CX(4200|4230|4300|4310|6200|6230)/ or
+            # try to pick up similar models we haven't tested yet
+            $$valPt=~/^\0(\x1a\x18|\x3a\x08|\x59\xf8|\x14\x80)\0/)
+        },
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Type5',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteKodak6a',
+        Condition => q{
+            $self->{CameraMake}=~/^EASTMAN KODAK/ and
+            $self->{CameraModel}=~/DX3215/
+        },
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Type6',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteKodak6b',
+        Condition => q{
+            $self->{CameraMake}=~/^EASTMAN KODAK/ and
+            $self->{CameraModel}=~/DX3700/
+        },
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Type6',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteKodak7',
+        # look for something that looks like a serial number
+        # (confirmed serial numbers have the format KXXXX########, but we also
+        #  accept other strings from sample images that may be serial numbers)
+        Condition => q{
+            $self->{CameraMake}=~/Kodak/i and
+            $$valPt =~ /^[CK][A-Z\d]{3} ?[A-Z\d]{1,2}\d{2}[A-Z\d]\d{4}[ \0]/
+        },
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Type7',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteKodakIFD',
+        # look for reasonable number of entries and check
+        # format and count of first IFD entry
+        Condition => q{
+            $self->{CameraMake}=~/Kodak/i and
+            ($$valPt =~ /^\0[\x02-\x7f]..\0[\x01-\x0c]\0\0/s or
+             $$valPt =~ /^[\x02-\x7f]\0..[\x01-\x0c]\0..\0\0/s)
+        },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::IFD',
+            ProcessProc => \&ProcessUnknown,
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteKodakUnknown',
+        Condition => '$self->{CameraMake}=~/Kodak/i',
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Unknown',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteKyocera',
+        # (starts with "KYOCERA")
+        Condition => '$self->{CameraMake}=~/^KYOCERA/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Unknown::Main',
+            Start => '$valuePtr + 22',
+            Base => '$start + 2',
+            EntryBased => 1,
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteMinolta',
+        Condition => q{
+            $self->{CameraMake}=~/^(Konica Minolta|Minolta)/i and
+            $$valPt !~ /^(MINOL|CAMER|MLY0|KC|\+M\+M|\xd7)/
+        },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Minolta::Main',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        # the DiMAGE E323 (MINOL) and E500 (CAMER), and some models
+        # of Mustek, Pentax, Ricoh and Vivitar (CAMER).
+        Name => 'MakerNoteMinolta2',
+        Condition => '$$valPt =~ /^(MINOL|CAMER)\0/ and $$self{OlympusCAMER} = 1',
+        SubDirectory => {
+            # these models use Olympus tags in the range 0x200-0x221 plus 0xf00
+            TagTable => 'Image::ExifTool::Olympus::Main',
+            Start => '$valuePtr + 8',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        # /^MLY0/ - DiMAGE G400, G500, G530, G600
+        # /^KC/   - Revio KD-420Z, DiMAGE E203
+        # /^+M+M/ - DiMAGE E201
+        # /^\xd7/ - DiMAGE RD3000
+        Name => 'MakerNoteMinolta3',
+        Condition => '$self->{CameraMake} =~ /^(Konica Minolta|Minolta)/i',
+        Notes => 'not EXIF-based',
+        Binary => 1,
+        NotIFD => 1,
+    },
+    {
+        # this maker notes starts with a standard TIFF header at offset 0x0a
+        Name => 'MakerNoteNikon',
+        Condition => '$self->{CameraMake}=~/^NIKON/i and $$valPt=~/^Nikon\x00\x02/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::Main',
+            Start => '$valuePtr + 18',
+            Base => '$start - 8',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        # older Nikon maker notes
+        Name => 'MakerNoteNikon2',
+        Condition => '$self->{CameraMake}=~/^NIKON/ and $$valPt=~/^Nikon\x00\x01/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::Type2',
+            Start => '$valuePtr + 8',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    {
+        # headerless Nikon maker notes
+        Name => 'MakerNoteNikon3',
+        Condition => '$self->{CameraMake}=~/^NIKON/i',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::Main',
+            ByteOrder => 'Unknown', # most are little-endian, but D1 is big
+        },
+    },
+    {
+        Name => 'MakerNoteOlympus',
+        # (if Make is 'SEIKO EPSON CORP.', starts with "EPSON\0")
+        # (if Make is 'OLYMPUS OPTICAL CO.,LTD' or 'OLYMPUS CORPORATION',
+        #  starts with "OLYMP\0")
+        Condition => '$$valPt =~ /^(OLYMP|EPSON)\0/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::Main',
+            Start => '$valuePtr + 8',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteOlympus2',
+        # new Olympus maker notes start with "OLYMPUS\0"
+        Condition => '$$valPt =~ /^OLYMPUS\0/ and $$self{OlympusType2} = 1',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::Main',
+            Start => '$valuePtr + 12',
+            Base => '$start - 12',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteLeica',
+        # (starts with "LEICA\0")
+        Condition => '$self->{CameraMake} =~ /^LEICA/',
+        SubDirectory => {
+            # Leica uses the same format as Panasonic
+            TagTable => 'Image::ExifTool::Panasonic::Main',
+            Start => '$valuePtr + 8',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNotePanasonic',
+        # (starts with "Panasonic\0")
+        Condition => '$self->{CameraMake} =~ /^Panasonic/ and $$valPt!~/^MKE/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Panasonic::Main',
+            Start => '$valuePtr + 12',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNotePanasonic2',
+        # (starts with "Panasonic\0")
+        Condition => '$self->{CameraMake} =~ /^Panasonic/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Panasonic::Type2',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    {
+        Name => 'MakerNotePentax',
+        # (starts with "AOC\0", but so does MakerNotePentax3)
+        # (also used by some Samsung models)
+        Condition => q{
+            $$valPt=~/^AOC\0/ and
+            $self->{CameraModel} !~ /^PENTAX Optio ?[34]30RS\s*$/
+        },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::Main',
+            # process as Unknown maker notes because the start offset and
+            # byte ordering are so variable
+            ProcessProc => \&ProcessUnknown,
+            # offsets can be totally whacky for Pentax maker notes,
+            # so attempt to fix the offset base if possible
+            FixBase => 1,
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNotePentax2',
+        # (starts with an IFD)
+        # Casio-like maker notes used only by the Optio 330 and 430
+        Condition => '$self->{CameraMake}=~/^Asahi/ and $$valPt!~/^AOC\0/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::Type2',
+            ProcessProc => \&ProcessUnknown,
+            FixBase => 1,
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNotePentax3',
+        # (starts with "AOC\0", like the more common Pentax maker notes)
+        # Casio maker notes used only by the Optio 330RS and 430RS
+        Condition => '$self->{CameraMake}=~/^Asahi/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Casio::Type2',
+            ProcessProc => \&ProcessUnknown,
+            FixBase => 1,
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNotePentax4',
+        # (starts with 3 or 4 digits)
+        # HP2-like text-based maker notes used by Optio E20
+        Condition => '$self->{CameraMake}=~/^PENTAX/ and $$valPt=~/^\d{3}/',
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::Type4',
+            Start => '$valuePtr',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    {
+        Name => 'MakerNoteRicoh',
+        Condition => '$self->{CameraMake}=~/^RICOH/ and $$valPt=~/^Ricoh/i',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Ricoh::Main',
+            Start => '$valuePtr + 8',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteRicohText',
+        Condition => '$self->{CameraMake}=~/^RICOH/',
+        NotIFD => 1,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Ricoh::Text',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        # PreviewImage (Samsung Digimax plus some other types of cameras)
+        %Image::ExifTool::previewImageTagInfo,
+        Condition => '$$valPt =~ /^\xff\xd8\xff\xdb/',
+        Notes => 'Samsung preview image',
+    },
+    {
+        Name => 'MakerNoteSanyo',
+        # (starts with "SANYO\0")
+        Condition => '$self->{CameraMake}=~/^SANYO/ and $self->{CameraModel} !~ /^(C4|J\d|S\d)\b/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sanyo::Main',
+            Validate => '$val =~ /^SANYO/',
+            Start => '$valuePtr + 8',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteSanyoC4',
+        # The C4 offsets are wrong by 12, so they must be fixed
+        Condition => '$self->{CameraMake}=~/^SANYO/ and $self->{CameraModel} =~ /^C4\b/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sanyo::Main',
+            Validate => '$val =~ /^SANYO/',
+            Start => '$valuePtr + 8',
+            FixBase => 1,
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteSanyoPatch',
+        # The J1, J2, J4, S1, S3 and S4 offsets are completely screwy
+        Condition => '$self->{CameraMake}=~/^SANYO/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sanyo::Main',
+            Validate => '$val =~ /^SANYO/',
+            Start => '$valuePtr + 8',
+            ByteOrder => 'Unknown',
+            FixOffsets => 'Image::ExifTool::Sanyo::FixOffsets($valuePtr, $valEnd, $size, $tagID, $wFlag)',
+        },
+    },
+    {
+        Name => 'MakerNoteSigma',
+        # (starts with "SIGMA\0")
+        Condition => '$self->{CameraMake}=~/^(SIGMA|FOVEON)/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sigma::Main',
+            Validate => '$val =~ /^(SIGMA|FOVEON)/',
+            Start => '$valuePtr + 10',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteSony',
+        # (starts with "SONY DSC \0" or "SONY CAM \0")
+        Condition => '$self->{CameraMake}=~/^SONY/ and $self->{TIFF_TYPE}!~/^(SRF|SR2|DNG)$/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sony::Main',
+            # validate the maker note because this is sometimes garbage
+            Validate => 'defined($val) and $val =~ /^SONY (DSC|CAM)/',
+            Start => '$valuePtr + 12',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteSonySRF',
+        Condition => '$self->{CameraMake}=~/^SONY/ and $$valPt =~ /^\x01\x00/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sony::SRF',
+            Start => '$valuePtr',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteSonySR2',
+        Condition => '$self->{CameraMake}=~/^SONY/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sony::Main',
+            Start => '$valuePtr',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteUnknown',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Unknown::Main',
+            ProcessProc => \&ProcessUnknown,
+            ByteOrder => 'Unknown',
+        },
+    },
+);
+
+# insert writable properties so we can write our maker notes
+my $tagInfo;
+foreach $tagInfo (@Image::ExifTool::MakerNotes::Main) {
+    $$tagInfo{Writable} = 'undef';
+    $$tagInfo{WriteGroup} = 'ExifIFD';
+    $$tagInfo{Groups} = { 1 => 'MakerNotes' };
+    next unless $$tagInfo{SubDirectory};
+    # set up this tag so we can write it
+    $$tagInfo{ValueConv} = '\$val';
+    $$tagInfo{ValueConvInv} = '$val';
+    $$tagInfo{MakerNotes} = 1;
+}
+
+#------------------------------------------------------------------------------
+# Get normal offset of value data from end of maker note IFD
+# Inputs: 0) ExifTool object reference
+# Returns: Array: 0) relative flag (undef for no change)
+#                 1) normal offset from end of IFD to first value (empty if unknown)
+#                 2-N) other possible offsets used by some models
+# Notes: Directory size should be validated before calling this routine
+sub GetMakerNoteOffset($)
+{
+    my $exifTool = shift;
+    # figure out where we expect the value data based on camera type
+    my $make = $exifTool->{CameraMake};
+    my $model = $exifTool->{CameraModel};
+    my ($relative, @offsets);
+
+    # normally value data starts 4 bytes after end of directory, so this is the default
+    if ($make =~ /^Canon/) {
+        push @offsets, ($model =~ /\b(20D|350D|REBEL XT|Kiss Digital N)\b/) ? 6 : 4;
+        # some Canon models (FV-M30, Optura50, Optura60) leave 24 unused bytes
+        # at the end of the IFD (2 spare IFD entries?)
+        push @offsets, 28 if $model =~ /\b(FV\b|OPTURA)/;
+    } elsif ($make =~ /^KYOCERA/) {
+        push @offsets, 12;
+    } elsif ($make =~ /^OLYMPUS/ and $model =~ /^E-(1|300|330)\b/) {
+        push @offsets, 16;
+    } elsif ($make =~ /^OLYMPUS/ and
+        # these Olympus models are just weird
+        $model =~ /^(C2500L|C-1Z?|C-5000Z|X-2|C720UZ|C725UZ|C150|C2Z|E-10|E-20|FerrariMODEL2003|u20D|u10D)\b/)
+    {
+        # no expected offset --> determine offset empirically via FixBase()
+    } elsif ($make =~ /^(Panasonic|SONY|JVC)\b/) {
+        push @offsets, 0;
+    } elsif ($make eq 'FUJIFILM') {
+        # some models have offset of 6, so allow that too (A345,A350,A360,A370)
+        push @offsets, 4, 6;
+    } elsif ($make =~ /^TOSHIBA/) {
+        # similar to Canon, can also have 24 bytes of padding
+        push @offsets, 0, 24;
+    } elsif ($make =~ /^PENTAX/) {
+        push @offsets, 4;
+        # the Pentax addressing mode is determined automatically, but
+        # sometimes the algorithm gets it wrong, but Pentax always uses
+        # absolute addressing, so force it to be absolute
+        $relative = 0;
+    } elsif ($make =~ /^Konica Minolta/i) {
+        # patch for DiMAGE X50, Xg, Z2 and Z10
+        push @offsets, 4, -16;
+    } elsif ($make =~ /^Minolta/) {
+        # patch for DiMAGE 7, X20 and Z1
+        push @offsets, 4, -8, -12;
+    } else {
+        push @offsets, 4;   # the normal offset
+    }
+    return ($relative, @offsets);
+}
+
+#------------------------------------------------------------------------------
+# Get hash of value offsets / block sizes
+# Inputs: 0) Data pointer, 1) offset to start of directory
+# Returns: 0) hash reference: keys are offsets, values are block sizes
+#          1) same thing, but with keys adjusted for value-based offsets
+# Notes: Directory size should be validated before calling this routine
+# - calculates MIN and MAX offsets in entry-based hash
+sub GetValueBlocks($$)
+{
+    my ($dataPt, $dirStart) = @_;
+    my $numEntries = Get16u($dataPt, $dirStart);
+    my ($index, $valPtr, %valBlock, %valBlkAdj, $end);
+    for ($index=0; $index<$numEntries; ++$index) {
+        my $entry = $dirStart + 2 + 12 * $index;
+        my $format = Get16u($dataPt, $entry+2);
+        last if $format < 1 or $format > 13;
+        my $count = Get32u($dataPt, $entry+4);
+        my $size = $count * $Image::ExifTool::Exif::formatSize[$format];
+        next if $size <= 4;
+        $valPtr = Get32u($dataPt, $entry+8);
+        # save location and size of longest block at this offset
+        unless (defined $valBlock{$valPtr} and $valBlock{$valPtr} > $size) {
+            $valBlock{$valPtr} = $size;
+        }
+        # adjust for case of value-based offsets
+        $valPtr += 12 * $index;
+        unless (defined $valBlkAdj{$valPtr} and $valBlkAdj{$valPtr} > $size) {
+            $valBlkAdj{$valPtr} = $size;
+            my $end = $valPtr + $size;
+            if (defined $valBlkAdj{MIN}) {
+                # save minimum only if it has a value of 12 or greater
+                $valBlkAdj{MIN} = $valPtr if $valBlkAdj{MIN} < 12 or $valBlkAdj{MIN} > $valPtr;
+                $valBlkAdj{MAX} = $end if $valBlkAdj{MAX} > $end;
+            } else {
+                $valBlkAdj{MIN} = $valPtr;
+                $valBlkAdj{MAX} = $end;
+            }
+        }
+    }
+    return(\%valBlock, \%valBlkAdj);
+}
+
+#------------------------------------------------------------------------------
+# Fix base for value offsets in maker notes IFD (if necessary)
+# Inputs: 0) ExifTool object ref, 1) DirInfo hash ref
+# Return: amount of base shift (and $dirInfo Base and DataPos are updated,
+#         FixedBy is set if offsets fixed, and Relative or EntryBased may be set)
+sub FixBase($$)
+{
+    local $_;
+    my ($exifTool, $dirInfo) = @_;
+    # don't fix base if fixing offsets individually or if we don't want to fix them
+    return 0 if $$dirInfo{FixOffsets} or $$dirInfo{NoFixBase};
+
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{DataPos};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $entryBased = $$dirInfo{EntryBased};
+    my $dirName = $$dirInfo{DirName};
+    my $fixBase = $exifTool->Options('FixBase');
+    my $setBase = (defined $fixBase and $fixBase ne '') ? 1 : 0;
+    my ($fix, $fixedBy);
+#
+# handle special case of Canon maker notes with TIFF trailer containing original offset
+#
+    if ($$exifTool{CameraMake} =~ /^Canon/ and $$dirInfo{DirLen} > 8) {
+        my $trailerPos = $dirStart + $$dirInfo{DirLen} - 8;
+        my $trailer = substr($$dataPt, $trailerPos, 8);
+        if ($trailer =~ /^(II\x2a\0|MM\0\x2a)/ and  # check for TIFF trailer
+            substr($trailer,0,2) eq GetByteOrder()) # validate byte ordering
+        {
+            if ($$exifTool{HTML_DUMP}) {
+                my $filePos = ($$dirInfo{Base} || 0) + $dataPos + $trailerPos;
+                $exifTool->HtmlDump($filePos, 8, '[Canon MakerNote trailer]')
+            }
+            if ($setBase) {
+                $fix = $fixBase;
+            } else {
+                my $oldOffset = Get32u(\$trailer, 4);
+                my $newOffset = $dirStart + $dataPos;
+                $fix = $newOffset - $oldOffset;
+                return 0 unless $fix;
+            }
+            $exifTool->Warn("Adjusted $dirName base by $fix", 1);
+            $$dirInfo{FixedBy} = $fix;
+            $$dirInfo{Base} += $fix;
+            $$dirInfo{DataPos} -= $fix;
+            return $fix;
+        }
+    }
+#
+# analyze value offsets to see if they need fixing.  The first task is to
+# determine the minimum valid offset used (this is tricky, because we have
+# to weed out bad offsets written by some cameras)
+#
+    # get hash of value block positions
+    my ($valBlock, $valBlkAdj) = GetValueBlocks($dataPt, $dirStart);
+    return 0 unless %$valBlock;
+
+    my $ifdLen = 2 + 12 * Get16u($$dirInfo{DataPt}, $dirStart);
+    my $ifdEnd = $dirStart + $ifdLen;
+    my ($relative, @offsets) = GetMakerNoteOffset($exifTool);
+    my $makeDiff = $offsets[0];
+    my $verbose = $exifTool->Options('Verbose');
+    my ($diff, $shift);
+
+    # calculate expected minimum value offset
+    my $expected = $dataPos + $ifdEnd + (defined $makeDiff ? $makeDiff : 4);
+    $debug and print "$expected expected\n";
+
+    # get sorted list of value offsets
+    my @valPtrs = sort { $a <=> $b } keys %$valBlock;
+    my $minPt = $valPtrs[0];    # if life were simple, this would be it
+
+    # zero our counters
+    my ($countNeg12, $countZero, $countOverlap) = (0, 0, 0);
+    my ($valPtr, $last);
+    foreach $valPtr (@valPtrs) {
+        printf("%d - %d (%d)\n", $valPtr, $valPtr + $$valBlock{$valPtr},
+               $valPtr - ($last || 0)) if $debug;
+        if (defined $last) {
+            my $diff = $valPtr - $last;
+            if ($diff == 0 or $diff == 1) {
+                ++$countZero;
+            } elsif ($diff == -12 and not $entryBased) {
+                # you get this when value offsets are relative to the IFD entry
+                ++$countNeg12;
+            } elsif ($diff < 0) {
+                # any other negative difference indicates overlapping values
+                ++$countOverlap if $valPtr; # (but ignore zero value pointers)
+            } elsif ($diff >= $ifdLen) {
+                # ignore previous minimum if we took a jump to near the expected value
+                # (some values can be stored before the IFD)
+                $minPt = $valPtr if abs($valPtr - $expected) <= 4;
+            }
+            # an offset less than 12 is surely garbage, so ignore it
+            $minPt = $valPtr if $minPt < 12;
+        }
+        $last = $valPtr + $$valBlock{$valPtr};
+    }
+    # could this IFD be using entry-based offsets?
+    if ((($countNeg12 > $countZero and $$valBlkAdj{MIN} >= $ifdLen - 2) or
+         ($$valBlkAdj{MIN} == $ifdLen - 2 or $$valBlkAdj{MIN} == $ifdLen + 2)
+        ) and $$valBlkAdj{MAX} <= $$dirInfo{DirLen}-2)
+    {
+        # looks like these offsets are entry-based, so use the offsets
+        # which have been correcting for individual entry position
+        $entryBased = 1;
+        $verbose and $exifTool->Warn("$dirName offsets are entry-based");
+    } else {
+        # calculate difference from normal
+        $diff = ($minPt - $dataPos) - $ifdEnd;
+        $shift = 0;
+        $countOverlap and $exifTool->Warn("Overlapping $dirName values",1);
+        if ($entryBased) {
+            $exifTool->Warn("$dirName offsets do NOT look entry-based");
+            undef $entryBased;
+            undef $relative;
+        }
+    }
+#
+# handle entry-based offsets
+#
+    if ($entryBased) {
+        $debug and print "--> entry-based!\n";
+        # most of my entry-based samples have first value immediately
+        # after last IFD entry (ie. no padding or next IFD pointer)
+        $makeDiff = 0;
+        push @offsets, 4;   # but some do have a next IFD pointer
+        # corrected entry-based offsets are relative to start of first entry
+        my $expected = 12 * Get16u($$dirInfo{DataPt}, $dirStart);
+        $diff = $$valBlkAdj{MIN} - $expected;
+        # set up directory to read values with entry-based offsets
+        # (ignore everything and set base to start of first entry)
+        $shift = $dataPos + $dirStart + 2;
+        $$dirInfo{Base} += $shift;
+        $$dirInfo{DataPos} -= $shift;
+        $$dirInfo{EntryBased} = 1;
+        $$dirInfo{Relative} = 1;    # entry-based offsets are relative
+        delete $$dirInfo{FixBase};  # no automatic base fix
+        undef $fixBase unless $setBase;
+    }
+#
+# return without doing shift if offsets look OK
+#
+    unless ($setBase) {
+        # don't try to fix offsets for whacky cameras
+        return $shift unless defined $makeDiff;
+        # normal value data starts 4 bytes after IFD, but allow 0 or 4...
+        return $shift if $diff == 0 or $diff == 4;
+        # also check for allowed make-specific differences
+        foreach (@offsets) {
+            return $shift if $diff == $_;
+        }
+    }
+#
+# apply the fix, or issue a warning
+#
+    # use default padding of 4 bytes unless already specified
+    $makeDiff = 4 unless defined $makeDiff;
+    $fix = $makeDiff - $diff;   # assume standard diff for this make
+
+    if ($$dirInfo{FixBase}) {
+        # set flag if offsets are relative (base is at or above directory start)
+        if ($dataPos - $fix + $dirStart <= 0) {
+            $$dirInfo{Relative} = (defined $relative) ? $relative : 1;
+        }
+        if ($setBase) {
+            $fixedBy = $fixBase;
+            $fix += $fixBase;
+        }
+    } elsif (defined $fixBase) {
+        $fix = $fixBase if $fixBase ne '';
+        $fixedBy = $fix;
+    } else {
+        # print warning unless difference looks reasonable
+        if ($diff < 0 or $diff > 16 or ($diff & 0x01)) {
+            $exifTool->Warn("Possibly incorrect maker notes offsets (fix by $fix?)",1);
+        }
+        # don't do the fix (but we already adjusted base if entry-based)
+        return $shift;
+    }
+    if (defined $fixedBy) {
+        $exifTool->Warn("Adjusted $dirName base by $fixedBy",1);
+        $$dirInfo{FixedBy} = $fixedBy;
+    }
+    $$dirInfo{Base} += $fix;
+    $$dirInfo{DataPos} -= $fix;
+    return $fix + $shift;
+}
+
+#------------------------------------------------------------------------------
+# Find start of IFD in unknown maker notes
+# Inputs: 0) reference to directory information
+# Returns: offset to IFD on success, undefined otherwise
+# - dirInfo may contain TagInfo reference for tag associated with directory
+# - on success, updates DirStart, DirLen, Base and DataPos in dirInfo
+# - also sets Relative flag in dirInfo if offsets are relative to IFD
+# Note: Changes byte ordering!
+sub LocateIFD($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $size = $$dirInfo{DirLen} || ($$dirInfo{DataLen} - $dirStart);
+    my $tagInfo = $$dirInfo{TagInfo};
+    my $ifdOffsetPos;
+    # the IFD should be within the first 32 bytes
+    # (Kyocera sets the current record at 22 bytes)
+    my ($firstTry, $lastTry) = (0, 32);
+
+    # make sure Base and DataPos are defined
+    $$dirInfo{Base} or $$dirInfo{Base} = 0;
+    $$dirInfo{DataPos} or $$dirInfo{DataPos} = 0;
+#
+# use tag information (if provided) to determine directory location
+#
+    if ($tagInfo and $$tagInfo{SubDirectory}) {
+        my $subdir = $$tagInfo{SubDirectory};
+        unless ($$subdir{ProcessProc} and $$subdir{ProcessProc} eq \&ProcessUnknown) {
+            # look for the IFD at the "Start" specified in our SubDirectory information
+            my $valuePtr = $dirStart;
+            my $newStart = $dirStart;
+            if (defined $$subdir{Start}) {
+                #### eval Start ($valuePtr)
+                $newStart = eval($$subdir{Start});
+            }
+            if ($$subdir{Base}) {
+                # calculate subdirectory start relative to $base for eval
+                my $start = $newStart + $$dirInfo{DataPos};
+                #### eval Base ($start)
+                my $baseShift = eval($$subdir{Base});
+                # shift directory base (note: we may do this again below
+                # if an OffsetPt is defined, but that doesn't matter since
+                # the base shift is relative to DataPos, which we set too)
+                $$dirInfo{Base} += $baseShift;
+                $$dirInfo{DataPos} -= $baseShift;
+                # this is a relative directory if Base depends on $start
+                $$dirInfo{Relative} = 1 if $$subdir{Base} =~ /\$start\b/;
+            }
+            # add offset to the start of the directory if necessary
+            if ($$subdir{OffsetPt}) {
+                if ($$subdir{ByteOrder} =~ /^Little/i) {
+                    SetByteOrder('II');
+                } elsif ($$subdir{ByteOrder} =~ /^Big/i) {
+                    SetByteOrder('MM');
+                } else {
+                    warn "Can't have variable byte ordering for SubDirectories using OffsetPt\n";
+                    return undef;
+                }
+                #### eval OffsetPt ($valuePtr)
+                $ifdOffsetPos = eval($$subdir{OffsetPt}) - $dirStart;
+            }
+            # pinpoint position to look for this IFD
+            $firstTry = $lastTry = $newStart - $dirStart;
+        }
+    }
+#
+# scan for something that looks like an IFD
+#
+    if ($size >= 14 + $firstTry) {  # minimum size for an IFD
+        my $offset;
+IFD_TRY: for ($offset=$firstTry; $offset<=$lastTry; $offset+=2) {
+            last if $offset + 14 > $size;    # 14 bytes is minimum size for an IFD
+            my $pos = $dirStart + $offset;
+#
+# look for a standard TIFF header (Nikon uses it, others may as well),
+#
+            if (SetByteOrder(substr($$dataPt, $pos, 2)) and
+                Get16u($dataPt, $pos + 2) == 0x2a)
+            {
+                $ifdOffsetPos = 4;
+            }
+            if (defined $ifdOffsetPos) {
+                # get pointer to IFD
+                my $ptr = Get32u($dataPt, $pos + $ifdOffsetPos);
+                if ($ptr >= $ifdOffsetPos + 4 and $ptr + $offset + 14 <= $size) {
+                    # shift directory start and shorten dirLen accordingly
+                    $$dirInfo{DirStart} += $ptr + $offset;
+                    $$dirInfo{DirLen} -= $ptr + $offset;
+                    # shift pointer base to the start of the TIFF header
+                    my $shift = $$dirInfo{DataPos} + $dirStart + $offset;
+                    $$dirInfo{Base} += $shift;
+                    $$dirInfo{DataPos} -= $shift;
+                    $$dirInfo{Relative} = 1;   # set "relative offsets" flag
+                    return $ptr + $offset;
+                }
+                undef $ifdOffsetPos;
+            }
+#
+# look for a standard IFD (starts with 2-byte entry count)
+#
+            my $num = Get16u($dataPt, $pos);
+            next unless $num;
+            # number of entries in an IFD should be between 1 and 255
+            if (!($num & 0xff)) {
+                # lower byte is zero -- byte order could be wrong
+                ToggleByteOrder();
+                $num >>= 8;
+            } elsif ($num & 0xff00) {
+                # upper byte isn't zero -- not an IFD
+                next;
+            }
+            my $bytesFromEnd = $size - ($offset + 2 + 12 * $num);
+            if ($bytesFromEnd < 4) {
+                next unless $bytesFromEnd == 2 or $bytesFromEnd == 0;
+            }
+            # do a quick validation of all format types
+            my $index;
+            for ($index=0; $index<$num; ++$index) {
+                my $entry = $pos + 2 + 12 * $index;
+                my $format = Get16u($dataPt, $entry+2);
+                my $count = Get32u($dataPt, $entry+4);
+                # allow everything to be zero if not first entry
+                # because some manufacturers pad with null entries
+                next unless $format or $count or $index == 0;
+                # (would like to verify tag ID, but some manufactures don't
+                #  sort entries in order of tag ID so we don't have much of
+                #  a handle to verify this field)
+                # verify format
+                next IFD_TRY if $format < 1 or $format > 13;
+                # count must be reasonable (can't test for zero count because
+                # cameras like the 1DmkIII use this value)
+                next IFD_TRY if $count & 0xff000000;
+            }
+            $$dirInfo{DirStart} += $offset;    # update directory start
+            $$dirInfo{DirLen} -= $offset;
+            return $offset;   # success!!
+        }
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Process unknown maker notes assuming it is in EXIF IFD format
+# Inputs: 0) ExifTool object reference, 1) reference to directory information
+#         2) pointer to tag table
+# Returns: 1 on success, and updates $dirInfo if necessary for new directory
+sub ProcessUnknown($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $success = 0;
+
+    my $loc = LocateIFD($exifTool, $dirInfo);
+    if (defined $loc) {
+        $exifTool->{UnknownByteOrder} = GetByteOrder();
+        if ($exifTool->Options('Verbose') > 1) {
+            my $out = $exifTool->Options('TextOut');
+            my $indent = $exifTool->{INDENT};
+            $indent =~ s/\| $/  /;
+            printf $out "${indent}Found IFD at offset 0x%.4x in maker notes:\n",
+                    $$dirInfo{DirStart} + $$dirInfo{DataPos} + $$dirInfo{Base};
+        }
+        $success = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
+    } else {
+        $exifTool->{UnknownByteOrder} = ''; # indicates we tried but didn't set byte order
+        $exifTool->Warn("Unrecognized $$dirInfo{DirName}");
+    }
+    return $success;
+}
+
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::MakerNotes - Read and write EXIF maker notes
+
+=head1 SYNOPSIS
+
+This module is required by Image::ExifTool.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+maker notes in EXIF information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames(3pm)|Image::ExifTool::TagNames>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Minolta.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Minolta.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Minolta.pm	(revision 20131)
@@ -0,0 +1,1401 @@
+#------------------------------------------------------------------------------
+# File:         Minolta.pm
+#
+# Description:  Minolta EXIF maker notes tags
+#
+# Revisions:    04/06/2004 - P. Harvey Created
+#               09/09/2005 - P. Harvey Added ability to write MRW files
+#
+# References:   1) http://www.dalibor.cz/minolta/makernote.htm
+#               2) Jay Al-Saadi private communication (testing with A2)
+#               3) Shingo Noguchi, PhotoXP (http://www.daifukuya.com/photoxp/)
+#               4) Niels Kristian Bech Jensen private communication
+#               5) http://www.cybercom.net/~dcoffin/dcraw/
+#               6) Pedro Corte-Real private communication
+#               7) ExifTool forum post by bronek (http://www.cpanforum.com/posts/1118)
+#               8) http://www.chauveau-central.net/mrw-format/
+#               9) CPAN Forum post by 'geve' (http://www.cpanforum.com/threads/2168)
+#              10) http://homepage3.nifty.com/kamisaka/makernote/makernote_km.htm
+#              11) http://www.dyxum.com/dforum/forum_posts.asp?TID=6371&PN=1 and
+#                  http://www.dyxum.com/dAdmin/lenses/MakerNoteList_Public.asp?stro=makr
+#              12) http://www.minolta-forum.de/forum/index.php?showtopic=14914
+#              13) http://www.mhohner.de/minolta/lenses.php
+#              14) Jeffery Small private communication (tests with 7D)
+#              15) http://homepage3.nifty.com/kamisaka/makernote/makernote_sony.htm
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Minolta;
+
+use strict;
+use vars qw($VERSION %minoltaLensIDs %minoltaColorMode);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.33';
+
+# lens ID numbers (ref 3)
+%minoltaLensIDs = (
+    0 => 'Minolta AF 28-85mm F3.5-4.5',
+    1 => 'Minolta AF 80-200mm F2.8 HS-APO G',
+    2 => 'Minolta AF 28-70mm F2.8 G',
+    3 => 'Minolta AF 28-80mm F4-5.6',
+    5 => 'Minolta AF 35-70mm F3.5-4.5',
+    6 => 'Minolta AF 24-85mm F3.5-4.5 [New]',
+    # 7 => 'AF 100-400mm F4.5-6.7 (D)', ??
+    7 => 'Minolta AF 100-300mm F4.5-5.6 APO [New]',
+    8 => 'Minolta AF 70-210mm F4.5-5.6',
+    9 => 'Minolta AF 50mm F3.5 Macro',
+    10 => 'Minolta AF 28-105mm F3.5-4.5 [New]',
+    11 => 'Minolta AF 300mm F4 HS-APO G',
+    12 => 'Minolta AF 100mm F2.8 Soft Focus',
+    13 => 'Minolta AF 75-300mm F4.5-5.6',
+    14 => 'Minolta AF 100-400mm F4.5-6.7 APO',
+    15 => 'Minolta AF 400mm F4.5 HS-APO G',
+    16 => 'Minolta AF 17-35mm F3.5 G',
+    17 => 'Minolta AF 20-35mm F3.5-4.5',
+    18 => 'Minolta AF 28-80mm F3.5-5.6 II',
+    19 => 'Minolta AF 35mm F1.4',
+    20 => 'Minolta STF 135mm F2.8 [T4.5]',
+    22 => 'Minolta AF 35-80mm F4-5.6',
+    23 => 'Minolta AF 200mm F4 G APO Macro',
+    24 => 'Minolta AF 24-105mm F3.5-4.5 (D)', # or Sigma 18-50mm F2.8 or Sigma 17-70mm F2.8-4.5 (D)',
+    25 => 'Minolta AF 100-300mm F4.5-5.6 (D)',
+    27 => 'Minolta AF 85mm F1.4 G',
+    28 => 'Minolta AF 100mm F2.8 Macro (D)',
+    29 => 'Minolta AF 75-300mm F4.5-5.6 (D)',
+    30 => 'Minolta AF 28-80mm F3.5-5.6 (D)', # or Sigma AF 12-24mm F4.5-5.6 EX DG',
+    31 => 'Minolta AF 50mm F2.8 Macro (D) or AF 50mm F3.5 Macro',
+    # 32 => 'AF 100-400mm F4.5-6.7 (D) x1.5', ??
+    32 => 'Minolta AF 300mm F2.8 G',
+    33 => 'Minolta AF 70-200mm F2.8 G (D) SSM',
+    35 => 'Minolta AF 85mm F1.4 G (D) Limited',
+    36 => 'Minolta AF 28-100mm F3.5-5.6 (D)',
+    38 => 'KonicaMinolta AF 17-35mm F2.8-4 (D)',
+    39 => 'Minolta AF 28-75mm F2.8 (D)',
+    40 => 'KonicaMinolta or Sony AF DT 18-70mm F3.5-5.6 (D)',
+    41 => 'Minolta AF DT 11-18mm F4.5-5.6 (D)',
+    42 => 'Minolta AF DT 18-200mm F3.5-6.3 (D)',
+    43 => 'Minolta AF 35mm F1.4 G',
+    44 => 'Minolta AF 50mm F1.4',
+    45 => 'Carl Zeiss Planar T* 85mm F1.4 ZA',
+    46 => 'Carl Zeiss Vario-Sonnar T* DT 16-80mm F3.5-4.5 ZA',
+    47 => 'Carl Zeiss Sonnar T* 135mm F1.8 ZA',
+    128 => 'Tamron 18-200, 28-300 or 80-300mm F3.5-6.3',
+    129 => 'Tamron 200-400mm F5.6 LD', #12
+    138 => 'Soligor 19-35mm F3.5-4.5', #11
+    25501 => 'Minolta AF 50mm F1.7', #7
+    25511 => 'Minolta AF 35-70mm F4', # or Sigma UC AF 28-70mm F3.5-4.5 or Sigma M-AF 70-200mm F2.8 EX Aspherical', #/12/12
+    25521 => 'Minolta AF 28-85mm F3.5-4.5 [New]', # or Tokina 19-35mm F3.5-4.5 or Tokina 28-70mm F2.8 AT-X', #3/7
+    25531 => 'Minolta AF 28-135mm F4-4.5',
+    25541 => 'Minolta AF 35-105mm F3.5-4.5', #13
+    25551 => 'Minolta AF 70-210mm F4 Macro', # or Sigma 70-210mm F4-5.6 APO or Sigma M-AF 70-200mm F2.8 EX APO', #7/6
+    25561 => 'Minolta AF 135mm F2.8',
+    25571 => 'Minolta AF 28mm F2.8',
+    25581 => 'Minolta AF 24-50mm F4',
+    25601 => 'Minolta AF 100-200mm F4.5',
+    25611 => 'Minolta AF 75-300mm F4.5-5.6', #13 # or Sigma 70-300mm F4-5.6 or Sigma 300mm F4 APO Macro', #12/3/7
+    25621 => 'Minolta AF 50mm F1.4 [New]', #13
+    25631 => 'Minolta AF 300mm F2.8 G',
+    25641 => 'Minolta AF 50mm F2.8 Macro',
+    25651 => 'Minolta AF 600mm F4',
+    25661 => 'Minolta AF 24mm F2.8',
+    25721 => 'Minolta AF 500mm F8 Reflex',
+    25781 => 'Minolta AF 16mm F2.8 Fisheye', # or Sigma 8mm F4 Fisheye or Sigma 14mm F3.5',
+    25791 => 'Minolta AF 20mm F2.8',
+    25811 => 'Minolta AF 100mm F2.8 Macro New', # or Tamron 90mm F2.8 Macro or Sigma 180mm F5.6 Macro',
+    25858 => 'Minolta AF 35-105mm F3.5-4.5 New', # or Tamron 24-135mm F3.5-5.6',
+    25881 => 'Minolta AF 70-210mm F3.5-4.5',
+    25891 => 'Minolta AF 80-200 F2.8 APO', # or Tokina 80-200mm F2.8',
+    25911 => 'Minolta AF 35mm F1.4', #(from Sony list)
+    25921 => 'Minolta AF 85mm F1.4 G (D)',
+    25931 => 'Minolta AF 200mm F2.8 G APO',
+    25941 => 'Minolta AF 3X-1X F1.7-2.8 Macro',
+    25961 => 'Minolta AF 28mm F2',
+    25971 => 'Minolta AF 35mm F2',
+    25981 => 'Minolta AF 100mm F2',
+    26041 => 'Minolta AF 80-200mm F4.5-5.6',
+    26051 => 'Minolta AF 35-80mm F4-5.6', #(from Sony list)
+    26061 => 'Minolta AF 100-300mm F4.5-5.6 (D)',
+    26071 => 'Minolta AF 35-80mm F4-5.6', #13
+    26081 => 'Minolta AF 300mm F2.8 G',
+    26091 => 'Minolta AF 600mm F4 HS-APO G',
+    26121 => 'Minolta AF 200mm F2.8 G HS-APO',
+    26131 => 'Minolta AF 50mm F1.7 New',
+    26151 => 'Minolta AF 28-105mm F3.5-4.5 Power Zoom',
+    26161 => 'Minolta AF 35-200mm F4.5-5.6 Power Zoom',
+    26181 => 'Minolta AF 28-80mm F4-5.6 Power Zoom',
+    26191 => 'Minolta AF 80-200mm F4.5-5.6 Power Zoom',
+    26201 => 'Minolta AF 28-70mm F2.8 G', #11
+    26211 => 'Minolta AF 100-300mm F4.5-5.6 Power Zoom',
+    26241 => 'Minolta AF 35-80mm F4-5.6 Power Zoom',
+    26281 => 'Minolta AF 80-200mm F2.8 G', #11
+    26291 => 'Minolta AF 85mm F1.4 New',
+    26311 => 'Minolta AF 100-300mm F4.5-5.6 APO', #11
+    26321 => 'Minolta AF 24-50mm F4 New',
+    26381 => 'Minolta AF 50mm F2.8 Macro New',
+    26391 => 'Minolta AF 100mm F2.8 Macro',
+    26411 => 'Minolta AF 20mm F2.8 New',
+    26421 => 'Minolta AF 24mm F2.8 New',
+    26441 => 'Minolta AF 100-400mm F4.5-6.7 APO', #11
+    26621 => 'Minolta AF 50mm F1.4 New',
+    26671 => 'Minolta AF 35mm F2 New',
+    26681 => 'Minolta AF 28mm F2 New',
+    26721 => 'Minolta AF 24-105mm F3.5-4.5 (D)', #11
+    45741 => 'Minolta AF 200mm F2.8 G x2', # or Tokina 300mm F2.8 x2',
+);
+
+%minoltaColorMode = (
+    0 => 'Natural color',
+    1 => 'Black & White',
+    2 => 'Vivid color',
+    3 => 'Solarization',
+    4 => 'Adobe RGB',
+    5 => 'Sepia', #10
+    9 => 'Natural', #10
+    12 => 'Portrait', #10
+    13 => 'Natural sRGB',
+    14 => 'Natural+ sRGB',
+    15 => 'Landscape', #10
+    16 => 'Evening', #10
+    17 => 'Night Scene', #10
+    18 => 'Night Portrait', #10
+);
+
+# Minolta tag table
+%Image::ExifTool::Minolta::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x0000 => {
+        Name => 'MakerNoteVersion',
+        Writable => 'undef',
+        Count => 4,
+    },
+    0x0001 => {
+        Name => 'MinoltaCameraSettingsOld',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Minolta::CameraSettings',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    0x0003 => {
+        Name => 'MinoltaCameraSettings',
+        # These camera settings are different for the DiMAGE X31
+        Condition => '$self->{CameraModel} ne "DiMAGE X31"',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Minolta::CameraSettings',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    0x0004 => { #8
+        Name => 'MinoltaCameraSettings7D',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Minolta::CameraSettings7D',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    # it appears that image stabilization is on if this tag exists (ref 2),
+    # but it is an 8kB binary data block!
+    0x0018 => {
+        Name => 'ImageStabilization',
+        Condition => '$self->{CameraModel} =~ /^DiMAGE (A1|A2|X1)$/',
+        Notes => q{
+            a block of binary data which exists in DiMAGE A2 (and A1/X1?) images only if
+            image stabilization is enabled
+        },
+        ValueConv => '"On"',
+    },
+    0x0040 => {
+        Name => 'CompressedImageSize',
+        Writable => 'int32u',
+    },
+    0x0081 => {
+        # JPEG preview found in DiMAGE 7 images
+        %Image::ExifTool::previewImageTagInfo,
+        Permanent => 1,     # don't add this to a file
+    },
+    0x0088 => {
+        Name => 'PreviewImageStart',
+        Flags => 'IsOffset',
+        OffsetPair => 0x0089, # point to associated byte count
+        DataTag => 'PreviewImage',
+        Writable => 'int32u',
+        Protected => 2,
+    },
+    0x0089 => {
+        Name => 'PreviewImageLength',
+        OffsetPair => 0x0088, # point to associated offset
+        DataTag => 'PreviewImage',
+        Writable => 'int32u',
+        Protected => 2,
+    },
+    0x0100 => { #10 (needs verification - PH)
+        Name => 'SceneMode',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Portrait',
+            2 => 'Text',
+            3 => 'Night Scene',
+            4 => 'Evening Scene',
+            5 => 'Sports',
+            6 => 'Landscape',
+            9 => 'Super Macro',
+        },
+    },
+    0x0101 => [
+        {
+            Name => 'ColorMode',
+            Condition => '$self->{CameraMake} !~ /^SONY/',
+            Priority => 0, # Other ColorMode is more reliable for A2
+            Writable => 'int32u',
+            PrintConv => \%minoltaColorMode,
+        },
+        { #15
+            Name => 'ColorMode',
+            Writable => 'int32u',
+            Notes => 'Sony DSLR-A100',
+            PrintConv => {
+                0 => 'Standard',
+                1 => 'Vivid', #PH
+                2 => 'Portrait',
+                3 => 'Landscape',
+                4 => 'Sunset',
+                5 => 'Night Scene',
+                6 => 'B&W',
+                7 => 'Adobe RGB',
+            },
+        },
+    ],
+    0x0102 => {
+        Name => 'MinoltaQuality',
+        Writable => 'int32u',
+        # PrintConv strings conform with Minolta reference manual (ref 4)
+        # (note that Minolta calls an uncompressed TIFF image "Super fine")
+        PrintConv => {
+            0 => 'Raw',
+            1 => 'Super Fine',
+            2 => 'Fine',
+            3 => 'Standard',
+            4 => 'Economy',
+            5 => 'Extra fine',
+        },
+    },
+    # (0x0103 is the same as 0x0102 above) -- this is true for some
+    # cameras (A2/7Hi), but not others - PH
+    0x0103 => [
+        {
+            Name => 'MinoltaQuality',
+            Writable => 'int32u',
+            Condition => '$self->{CameraModel} =~ /^DiMAGE (A2|7Hi)$/',
+            Notes => 'quality for DiMAGE A2/7Hi',
+            Priority => 0, # lower priority because this doesn't work for A200
+            PrintConv => { #4
+                0 => 'Raw',
+                1 => 'Super Fine',
+                2 => 'Fine',
+                3 => 'Standard',
+                4 => 'Economy',
+                5 => 'Extra fine',
+            },
+        },
+        { #PH
+            Name => 'MinoltaImageSize',
+            Writable => 'int32u',
+            Condition => '$self->{CameraModel} !~ /^DiMAGE A200$/',
+            Notes => 'image size for other models except A200',
+            PrintConv => {
+                1 => '1600x1200',
+                2 => '1280x960',
+                3 => '640x480',
+                5 => '2560x1920',
+                6 => '2272x1704',
+                7 => '2048x1536',
+            },
+        },
+    ],
+    0x0104 => { #14
+        Name => 'FlashExposureComp',
+        Description => 'Flash Exposure Compensation',
+        Writable => 'rational64s',
+    },
+# needs verification:
+#    0x0105 => { #10
+#        Name => 'Teleconverter',
+#        PrintConv => {
+#            0 => 'None',
+#            72 => 'Minolta AF 2x APO (D)',
+#            80 => 'Minolta AF 2x APO II',
+#            136 => 'Minolta AF 1.4x APO (D)',
+#            144 => 'Minolta AF 1.4x APO II',
+#        },
+#    },
+    0x0107 => { #8
+        Name => 'ImageStabilization',
+        Writable => 'int32u',
+        PrintConv => {
+            1 => 'Off',
+            5 => 'On',
+        },
+    },
+    0x010a => {
+        Name => 'ZoneMatching',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'ISO Setting Used',
+            1 => 'High Key',
+            2 => 'Low Key',
+        },
+    },
+    0x010b => {
+        Name => 'ColorTemperature',
+        Writable => 'int32u',
+    },
+    0x010c => { #3 (Alpha 7)
+        Name => 'LensID',
+        Writable => 'int32u',
+        PrintConv => \%minoltaLensIDs,
+    },
+    # 0x010e - WhiteBalance according to ref #10
+    0x0113 => { #PH
+        Name => 'ImageStabilization',
+        Condition => '$self->{CameraModel} eq "DSLR-A100"',
+        Notes => 'valid for Sony A100 only',
+        Writable => 'int32u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x0114 => [
+        { #8
+            Name => 'MinoltaCameraSettings5D',
+            Condition => '$self->{CameraModel} =~ /^(DYNAX 5D|MAXXUM 5D|ALPHA SWEET)/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Minolta::CameraSettings5D',
+                ByteOrder => 'BigEndian',
+            },
+        },
+        { #PH
+            Name => 'MinoltaCameraSettingsA100',
+            Condition => '$self->{CameraModel} eq "DSLR-A100"',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Minolta::CameraSettingsA100',
+                ByteOrder => 'BigEndian', # required because order differs for ARW and JPG images
+            },
+        },
+    ],
+    0x0e00 => {
+        Name => 'PrintIM',
+        Description => 'Print Image Matching',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+    0x0f00 => {
+        Name => 'MinoltaCameraSettings2',
+        Writable => 0,
+    },
+);
+
+%Image::ExifTool::Minolta::CameraSettings = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    PRIORITY => 0, # not as reliable as other tags
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        There is some variability in CameraSettings information between different
+        models (and sometimes even between different firmware versions), so this
+        information may not be as reliable as it should be.  Because of this, tags
+        in the following tables are set to lower priority to prevent them from
+        superceeding the values of same-named tags in other locations when duplicate
+        tags are disabled.
+    },
+    1 => {
+        Name => 'ExposureMode',
+        PrintConv => {
+            0 => 'Program',
+            1 => 'Aperture Priority',
+            2 => 'Shutter Priority',
+            3 => 'Manual',
+        },
+    },
+    2 => {
+        Name => 'FlashMode',
+        PrintConv => {
+            0 => 'Fill flash',
+            1 => 'Red-eye reduction',
+            2 => 'Rear flash sync',
+            3 => 'Wireless',
+        },
+    },
+    3 => {
+        Name => 'WhiteBalance',
+        PrintConv => 'Image::ExifTool::Minolta::ConvertWhiteBalance($val)',
+    },
+    4 => {
+        Name => 'MinoltaImageSize',
+        PrintConv => {
+            0 => 'Full',
+            1 => '1600x1200',
+            2 => '1280x960',
+            3 => '640x480',
+            6 => '2080x1560', #PH (A2)
+            7 => '2560x1920', #PH (A2)
+            8 => '3264x2176', #PH (A2)
+        },
+    },
+    5 => {
+        Name => 'MinoltaQuality',
+        PrintConv => { #4
+            0 => 'Raw',
+            1 => 'Super Fine',
+            2 => 'Fine',
+            3 => 'Standard',
+            4 => 'Economy',
+            5 => 'Extra Fine',
+        },
+    },
+    6 => {
+        Name => 'DriveMode',
+        PrintConv => {
+            0 => 'Single',
+            1 => 'Continuous',
+            2 => 'Self-timer',
+            4 => 'Bracketing',
+            5 => 'Interval',
+            6 => 'UHS continuous',
+            7 => 'HS continuous',
+        },
+    },
+    7 => {
+        Name => 'MeteringMode',
+        PrintConv => {
+            0 => 'Multi-segment',
+            1 => 'Center weighted',
+            2 => 'Spot',
+        },
+    },
+    8 => {
+        Name => 'ISO',
+        ValueConv => '2 ** (($val-48)/8) * 100',
+        ValueConvInv => '48 + 8*log($val/100)/log(2)',
+        PrintConv => 'int($val + 0.5)',
+        PrintConvInv => '$val',
+    },
+    9 => {
+        Name => 'ExposureTime',
+        ValueConv => '2 ** ((48-$val)/8)',
+        ValueConvInv => '48 - 8*log($val)/log(2)',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    10 => {
+        Name => 'FNumber',
+        ValueConv => '2 ** (($val-8)/16)',
+        ValueConvInv => '8 + 16*log($val)/log(2)',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    11 => {
+        Name => 'MacroMode',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    12 => {
+        Name => 'DigitalZoom',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Electronic magnification',
+            2 => '2x',
+        },
+    },
+    13 => {
+        Name => 'ExposureCompensation',
+        ValueConv => '$val/3 - 2',
+        ValueConvInv => '($val + 2) * 3',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => 'eval $val',
+    },
+    14 => {
+        Name => 'BracketStep',
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '2/3 EV',
+            2 => '1 EV',
+        },
+    },
+    16 => 'IntervalLength',
+    17 => 'IntervalNumber',
+    18 => {
+        Name => 'FocalLength',
+        ValueConv => '$val / 256',
+        ValueConvInv => '$val * 256',
+        PrintConv => 'sprintf("%.1fmm",$val)',
+        PrintConvInv => '$val=~s/mm$//;$val',
+    },
+    19 => {
+        Name => 'FocusDistance',
+        ValueConv => '$val / 1000',
+        ValueConvInv => '$val * 1000',
+        PrintConv => '$val ? "$val m" : "inf"',
+        PrintConvInv => '$val eq "inf" ? 0 : $val =~ s/\s*m$//, $val',
+    },
+    20 => {
+        Name => 'FlashFired',
+        PrintConv => {
+            0 => 'No',
+            1 => 'Yes',
+        },
+    },
+    21 => {
+        Name => 'MinoltaDate',
+        Groups => { 2 => 'Time' },
+        Shift => 'Time',
+        ValueConv => 'sprintf("%4d:%.2d:%.2d",$val>>16,($val&0xff00)>>8,$val&0xff)',
+        ValueConvInv => 'my @a=($val=~/(\d+):(\d+):(\d+)/); @a ? ($a[0]<<16)+($a[1]<<8)+$a[2] : undef',
+    },
+    22 => {
+        Name => 'MinoltaTime',
+        Groups => { 2 => 'Time' },
+        Shift => 'Time',
+        ValueConv => 'sprintf("%.2d:%.2d:%.2d",$val>>16,($val&0xff00)>>8,$val&0xff)',
+        ValueConvInv => 'my @a=($val=~/(\d+):(\d+):(\d+)/); @a ? ($a[0]<<16)+($a[1]<<8)+$a[2] : undef',
+    },
+    23 => {
+        Name => 'MaxAperture',
+        ValueConv => '2 ** (($val-8)/16)',
+        ValueConvInv => '8 + 16*log($val)/log(2)',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    26 => {
+        Name => 'FileNumberMemory',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    27 => 'LastFileNumber',
+    28 => {
+        Name => 'ColorBalanceRed',
+        ValueConv => '$val / 256',
+        ValueConvInv => '$val * 256',
+    },
+    29 => {
+        Name => 'ColorBalanceGreen',
+        ValueConv => '$val / 256',
+        ValueConvInv => '$val * 256',
+    },
+    30 => {
+        Name => 'ColorBalanceBlue',
+        ValueConv => '$val / 256',
+        ValueConvInv => '$val * 256',
+    },
+    31 => {
+        Name => 'Saturation',
+        ValueConv => '$val - ($self->{CameraModel}=~/DiMAGE A2/ ? 5 : 3)',
+        ValueConvInv => '$val + ($self->{CameraModel}=~/DiMAGE A2/ ? 5 : 3)',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    32 => {
+        Name => 'Contrast',
+        ValueConv => '$val - ($self->{CameraModel}=~/DiMAGE A2/ ? 5 : 3)',
+        ValueConvInv => '$val + ($self->{CameraModel}=~/DiMAGE A2/ ? 5 : 3)',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    33 => {
+        Name => 'Sharpness',
+        PrintConv => {
+            0 => 'Hard',
+            1 => 'Normal',
+            2 => 'Soft',
+        },
+    },
+    34 => {
+        Name => 'SubjectProgram',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Portrait',
+            2 => 'Text',
+            3 => 'Night portrait',
+            4 => 'Sunset',
+            5 => 'Sports action',
+        },
+    },
+    35 => {
+        Name => 'FlashExposureComp',
+        Description => 'Flash Exposure Compensation',
+        ValueConv => '($val - 6) / 3',
+        ValueConvInv => '$val * 3 + 6',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => 'eval $val',
+    },
+    36 => {
+        Name => 'ISOSetting',
+        PrintConv => {
+            0 => 100,
+            1 => 200,
+            2 => 400,
+            3 => 800,
+            4 => 'Auto',
+            5 => 64,
+        },
+    },
+    37 => {
+        Name => 'MinoltaModelID',
+        PrintConv => {
+            0 => 'DiMAGE 7, X1, X21 or X31',
+            1 => 'DiMAGE 5',
+            2 => 'DiMAGE S304',
+            3 => 'DiMAGE S404',
+            4 => 'DiMAGE 7i',
+            5 => 'DiMAGE 7Hi',
+            6 => 'DiMAGE A1',
+            7 => 'DiMAGE A2 or S414',
+        },
+    },
+    38 => {
+        Name => 'IntervalMode',
+        PrintConv => {
+            0 => 'Still Image',
+            1 => 'Time-lapse Movie',
+        },
+    },
+    39 => {
+        Name => 'FolderName',
+        PrintConv => {
+            0 => 'Standard Form',
+            1 => 'Data Form',
+        },
+    },
+    40 => {
+        Name => 'ColorMode',
+        PrintConv => {
+            0 => 'Natural color',
+            1 => 'Black & White',
+            2 => 'Vivid color',
+            3 => 'Solarization',
+            4 => 'Adobe RGB',
+        },
+    },
+    41 => {
+        Name => 'ColorFilter',
+        ValueConv => '$val - ($self->{CameraModel}=~/DiMAGE A2/ ? 5 : 3)',
+        ValueConvInv => '$val + ($self->{CameraModel}=~/DiMAGE A2/ ? 5 : 3)',
+    },
+    42 => 'BWFilter',
+    43 => {
+        Name => 'InternalFlash',
+        PrintConv => {
+            0 => 'No',
+            1 => 'Fired',
+        },
+    },
+    44 => {
+        Name => 'Brightness',
+        ValueConv => '$val/8 - 6',
+        ValueConvInv => '($val + 6) * 8',
+    },
+    45 => 'SpotFocusPointX',
+    46 => 'SpotFocusPointY',
+    47 => {
+        Name => 'WideFocusZone',
+        PrintConv => {
+            0 => 'No zone',
+            1 => 'Center zone (horizontal orientation)',
+            2 => 'Center zone (vertical orientation)',
+            3 => 'Left zone',
+            4 => 'Right zone',
+        },
+    },
+    48 => {
+        Name => 'FocusMode',
+        PrintConv => {
+            0 => 'AF',
+            1 => 'MF',
+        },
+    },
+    49 => {
+        Name => 'FocusArea',
+        PrintConv => {
+            0 => 'Wide Focus (normal)',
+            1 => 'Spot Focus',
+        },
+    },
+    50 => {
+        Name => 'DECPosition',
+        PrintConv => {
+            0 => 'Exposure',
+            1 => 'Contrast',
+            2 => 'Saturation',
+            3 => 'Filter',
+        },
+    },
+    # 7Hi only:
+    51 => {
+        Name => 'ColorProfile',
+        Condition => '$self->{CameraModel} eq "DiMAGE 7Hi"',
+        Notes => 'DiMAGE 7Hi only',
+        PrintConv => {
+            0 => 'Not Embedded',
+            1 => 'Embedded',
+        },
+    },
+    # (the following may be entry 51 for other models?)
+    52 => {
+        Name => 'DataImprint',
+        Condition => '$self->{CameraModel} eq "DiMAGE 7Hi"',
+        Notes => 'DiMAGE 7Hi only',
+        PrintConv => {
+            0 => 'None',
+            1 => 'YYYY/MM/DD',
+            2 => 'MM/DD/HH:MM',
+            3 => 'Text',
+            4 => 'Text + ID#',
+        },
+    },
+    63 => { #9
+        Name => 'FlashMetering',
+        PrintConv => {
+            0 => 'ADI (Advanced Distance Integration)',
+            1 => 'Pre-flash TTL',
+            2 => 'Manual flash control',
+        },
+    },
+);
+
+# Camera settings used by the 7D (ref 8)
+%Image::ExifTool::Minolta::CameraSettings7D = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    PRIORITY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    0x00 => {
+        Name => 'ExposureMode',
+        PrintConv => {
+            0 => 'Program',
+            1 => 'Aperture Priority',
+            2 => 'Shutter Priority',
+            3 => 'Manual',
+            4 => 'Auto?',
+            5 => 'Program-shift A',
+            6 => 'Program-shift S',
+        },
+    },
+    0x02 => { #PH
+        Name => 'MinoltaImageSize',
+        PrintConv => {
+            0 => 'Large',
+            1 => 'Medium',
+            2 => 'Small',
+        },
+    },
+    0x03 => {
+        Name => 'MinoltaQuality',
+        PrintConv => {
+            0 => 'RAW',
+            16 => 'Fine', #PH
+            32 => 'Normal', #PH
+            34 => 'RAW+JPEG',
+            48 => 'Economy', #PH
+        },
+    },
+    0x04 => {
+        Name => 'WhiteBalance',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Daylight',
+            2 => 'Shade',
+            3 => 'Cloudy',
+            4 => 'Tungsten',
+            5 => 'Fluorescent',
+            0x100 => 'Kelvin',
+            0x200 => 'Manual',
+        },
+    },
+    0x0e => {
+        Name => 'FocusMode',
+        PrintConv => {
+            0 => 'Single-shot AF',
+            1 => 'Continuous AF',
+            3 => 'Automatic AF',
+            4 => 'Manual',
+        },
+    },
+    0x10 => {
+        Name => 'AFPoints',
+        PrintConv => { BITMASK => {
+            0 => 'Center',
+            1 => 'Top',
+            2 => 'Top-Right',
+            3 => 'Right',
+            4 => 'Bottom-Right',
+            5 => 'Bottom',
+            6 => 'Bottom-Left',
+            7 => 'Left',
+            8 => 'Top-Left',
+        } },
+    },
+    0x15 => {
+        Name => 'Flash',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+# needs verification:
+#    0x16 => { #10
+#        Name => 'FlashMode',
+#        PrintConv => {
+#            0 => 'Normal',
+#            1 => 'Red-eye reduction',
+#            2 => 'Rear flash sync',
+#        },
+#    },
+    0x1c => {
+        Name => 'ISOSetting',
+        PrintConv => {
+            0 => 'Auto', #10
+            1 => 100,
+            3 => 200,
+            4 => 400,
+            5 => 800,
+            6 => 1600,
+            7 => 3200,
+        },
+    },
+    0x1e => {
+        Name => 'ExposureCompensation',
+        Format => 'int16s',
+        ValueConv => '$val / 24',
+        ValueConvInv => '$val * 24',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x25 => {
+        Name => 'ColorSpace',
+        PrintConv => {
+            0 => 'Natural sRGB',
+            1 => 'Natural+ sRGB',
+            4 => 'Adobe RGB',
+        },
+    },
+    0x26 => {
+        Name => 'Sharpness',
+        ValueConv => '$val - 10',
+        ValueConvInv => '$val + 10',
+    },
+    0x27 => {
+        Name => 'Contrast',
+        ValueConv => '$val - 10',
+        ValueConvInv => '$val + 10',
+    },
+    0x28 => {
+        Name => 'Saturation',
+        ValueConv => '$val - 10',
+        ValueConvInv => '$val + 10',
+    },
+    0x2d => 'FreeMemoryCardImages',
+    0x3f => {
+        Format => 'int16s',
+        Name => 'ColorTemperature',
+        ValueConv => '$val * 100',
+        ValueConvInv => '$val / 100',
+    },
+# needs verification:
+#    0x40 => { #10
+#        Name => 'HueAdjustment',
+#        Unknown => 1,
+#        ValueConv => '$val - 10',
+#        ValueConvInv => '$val + 10',
+#    },
+    0x46 => {
+        Name => 'Rotation',
+        PrintConv => {
+            72 => 'Horizontal (normal)',
+            76 => 'Rotate 90 CW',
+            82 => 'Rotate 270 CW',
+        },
+    },
+    0x47 => {
+        Name => 'FNumber',
+        ValueConv => '2 ** (($val-8)/16)',
+        ValueConvInv => '8 + 16*log($val)/log(2)',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x48 => {
+        Name => 'ExposureTime',
+        ValueConv => '2 ** ((48-$val)/8)',
+        ValueConvInv => '48 - 8*log($val)/log(2)',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x4a => 'FreeMemoryCardImages',
+    0x5e => {
+        Name => 'ImageNumber',
+        Notes => q{
+            this information may appear at index 98 (0x62), depending on firmware
+            version
+        },
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0x60 => {
+        Name => 'NoiseReduction',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x62 => {
+        Name => 'ImageNumber2',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0x71 => {
+        Name => 'ImageStabilization',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x75 => {
+        Name => 'ZoneMatchingOn',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+);
+
+# Camera settings used by the 5D (ref 8)
+%Image::ExifTool::Minolta::CameraSettings5D = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    PRIORITY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    0x0a => {
+        Name => 'ExposureMode',
+        PrintConv => {
+            0 => 'Program',
+            1 => 'Aperture Priority',
+            2 => 'Shutter Priority',
+            3 => 'Manual',
+            4 => 'Auto?',
+            4131 => 'Connected Copying?',
+        },
+    },
+    0x0c => { #PH
+        Name => 'MinoltaImageSize',
+        PrintConv => {
+            0 => 'Large',
+            1 => 'Medium',
+            2 => 'Small',
+        },
+    },
+    0x0d => {
+        Name => 'MinoltaQuality',
+        PrintConv => {
+            0 => 'RAW',
+            16 => 'Fine', #PH
+            32 => 'Normal', #PH
+            34 => 'RAW+JPEG',
+            48 => 'Economy', #PH
+        },
+    },
+    0x0e => {
+        Name => 'WhiteBalance',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Daylight',
+            2 => 'Cloudy',
+            3 => 'Shade',
+            4 => 'Tungsten',
+            5 => 'Fluorescent',
+            6 => 'Flash',
+            0x100 => 'Kelvin',
+            0x200 => 'Manual',
+        },
+    },
+    # 0x0f-0x11 something to do with WB RGB levels as shot? (PH)
+    # 0x12-0x17 RGB levels for other WB modes (with G missing)? (PH)
+    0x1f => { #PH
+        Name => 'Flash',
+        PrintConv => {
+            0 => 'Did not fire',
+            1 => 'Fired',
+        },
+    },
+# needs verification:
+#    0x20 => { #10
+#        Name => 'FlashMode',
+#        PrintConv => {
+#            0 => 'Normal',
+#            1 => 'Red-eye reduction',
+#            2 => 'Rear flash sync',
+#        },
+#    },
+    0x25 => {
+        Name => 'MeteringMode',
+        PrintConv => {
+            0 => 'Multi-segment',
+            1 => 'Center weighted',
+            2 => 'Spot',
+        },
+    },
+    0x26 => {
+        Name => 'ISOSetting',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 100,
+            3 => 200,
+            4 => 400,
+            5 => 800,
+            6 => 1600,
+            7 => 3200,
+            8 => '200 (Zone Matching High)',
+            10 => '80 (Zone Matching Low)',
+        },
+    },
+# looks wrong:
+#    0x28 => { #10
+#        Name => 'ExposureCompensation',
+#        ValueConv => '$val / 24',
+#        ValueConvInv => '$val * 24',
+#    },
+# needs verification:
+#    0x2f => { #10
+#        Name => 'ColorSpace',
+#        PrintConv => {
+#            0 => 'Natural sRGB',
+#            1 => 'Natural+ sRGB',
+#            2 => 'Monochrome',
+#            4 => 'Adobe RGB (ICC)',
+#            5 => 'Adobe RGB',
+#        },
+#    },
+    0x30 => {
+        Name => 'Sharpness',
+        ValueConv => '$val - 10',
+        ValueConvInv => '$val + 10',
+    },
+    0x31 => {
+        Name => 'Contrast',
+        ValueConv => '$val - 10',
+        ValueConvInv => '$val + 10',
+    },
+    0x32 => {
+        Name => 'Saturation',
+        ValueConv => '$val - 10',
+        ValueConvInv => '$val + 10',
+    },
+    0x35 => { #PH
+        Name => 'ExposureTime',
+        ValueConv => '2 ** ((48-$val)/8)',
+        ValueConvInv => '48 - 8*log($val)/log(2)',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x36 => { #PH
+        Name => 'FNumber',
+        ValueConv => '2 ** (($val-8)/16)',
+        ValueConvInv => '8 + 16*log($val)/log(2)',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x37 => 'FreeMemoryCardImages',
+    # 0x38 definitely not related to exposure comp as in ref 8 (PH)
+    0x49 => { #PH
+        Name => 'ColorTemperature',
+        Format => 'int16s',
+        ValueConv => '$val * 100',
+        ValueConvInv => '$val / 100',
+    },
+# needs verification:
+#    0x4a => { #10
+#        Name => 'HueAdjustment',
+#        ValueConv => '$val - 10',
+#        ValueConvInv => '$val + 10',
+#    },
+    0x50 => {
+        Name => 'Rotation',
+        PrintConv => {
+            72 => 'Horizontal (normal)',
+            76 => 'Rotate 90 CW',
+            82 => 'Rotate 270 CW',
+        },
+    },
+    0x53 => {
+        Name => 'ExposureCompensation',
+        ValueConv => '$val / 100 - 3',
+        ValueConvInv => '($val + 3) * 100',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x54 => 'FreeMemoryCardImages',
+# needs verification:
+#    0x65 => { #10
+#        Name => 'Rotation',
+#        PrintConv => {
+#            0 => 'Horizontal (normal)',
+#            1=> 'Rotate 90 CW',
+#            2 => 'Rotate 270 CW',
+#        },
+#    },
+    # 0x66 maybe program mode or some setting like this? (PH)
+    0x6e => { #10
+        Name => 'ColorTemperature',
+        Format => 'int16s',
+        ValueConv => '$val * 100',
+        ValueConvInv => '$val / 100',
+    },
+# needs verification:
+#    0x71 => { #10
+#        Name => 'PictureFinish',
+#        PrintConv => {
+#            0 => 'Natural',
+#            1 => 'Natural+',
+#            2 => 'Portrait',
+#            3 => 'Wind Scene',
+#            4 => 'Evening Scene',
+#            5 => 'Night Scene',
+#            6 => 'Night Portrait',
+#            7 => 'Monochrome',
+#            8 => 'Adobe RGB',
+#            9 => 'Adobe RGB (ICC)',
+#        },
+#    },
+    # 0x95 FlashStrength? (PH)
+    # 0xa4 similar information to 0x27, except with different values
+    0xae => {
+        Name => 'ImageNumber',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0xb0 => {
+        Name => 'NoiseReduction',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0xbd => {
+        Name => 'ImageStabilization',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+);
+
+# Camera settings used by the Sony DSLR-A100 (ref PH)
+%Image::ExifTool::Minolta::CameraSettingsA100 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    NOTES => 'Camera settings information for the Sony DSLR-A100.',
+    WRITABLE => 1,
+    PRIORITY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    0x00 => { #15
+        Name => 'ExposureMode',
+        PrintHex => 1,
+        PrintConv => {
+            0 => 'Program',
+            1 => 'Aperture Priority',
+            2 => 'Shutter Priority',
+            3 => 'Manual',
+            4 => 'Auto',
+            0x1013 => 'Portrait',
+            0x1053 => 'Landscape',
+        },
+    },
+    0x01 => { #15
+        Name => 'ExposureCompensation',
+        ValueConv => '$val / 100 - 3',
+        ValueConvInv => 'int(($val + 3) * 100 + 0.5)',
+    },
+    # 0x09 some sort of APEX value (ref 15)
+    0x0b => { #15
+        Name => 'WhiteBalance',
+        PrintHex => 1,
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Daylight',
+            2 => 'Cloudy',
+            3 => 'Shade',
+            4 => 'Tungsten',
+            5 => 'Fluorescent',
+            6 => 'Flash',
+            0x100 => 'Kelvin',
+            0x200 => 'Manual',
+        },
+    },
+    # 0x12 => 'MeteringMode' (ref 15)
+    # 0x13 => 'ISO' (ref 15)
+    # 0x14 => 'ZoneMatching' (ref 15)
+    # 0x15 => 'DynamicRangeOptimizer' (ref 15)
+    0x16 => { #15
+        Name => 'ColorMode',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Vivid',
+            2 => 'Portrait',
+            3 => 'Landscape',
+            4 => 'Sunset',
+            5 => 'Night Scene',
+            7 => 'B&W',
+            8 => 'Adobe RGB',
+        },
+    },
+    # 0x17 => 'ColorSpace' (ref 15)
+    0x18 => { #15
+        Name => 'Sharpness',
+        ValueConv => '$val - 10',
+        ValueConvInv => '$val + 10',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    0x19 => { #15
+        Name => 'Contrast',
+        ValueConv => '$val - 10',
+        ValueConvInv => '$val + 10',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    0x1a => { #15
+        Name => 'Saturation',
+        ValueConv => '$val - 10',
+        ValueConvInv => '$val + 10',
+        PrintConv => 'Image::ExifTool::Exif::PrintParameter($val)',
+        PrintConvInv => '$val=~/normal/i ? 0 : $val',
+    },
+    0x1e => { #PH
+        Name => 'DriveMode',
+        PrintConv => {
+            0 => 'Single Frame',
+            1 => 'Continuous',
+            2 => 'Self-Timer',
+            3 => 'Continuous Bracketing',
+            4 => 'Single-Frame Bracketing',
+            5 => 'White Balance Bracketing',
+        },
+    },
+    0x3f => { #PH
+        Name => 'NoiseReduction',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x5a => { #15
+        Name => 'Rotation',
+        PrintConv => {
+            0 => 'Horizontal (Normal)',
+            1 => 'Rotate 270 CW',
+            2 => 'Rotate 90 CW',
+        },
+    },
+    0x5e => { #15
+        Name => 'ColorTemperature',
+        ValueConv => '$val * 100',
+        ValueConvInv => '$val / 100',
+    },
+    0x87 => { #15
+        Name => 'ImageStabilization',
+        Writable => 'int32u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+);
+
+# basic Minolta white balance lookup
+my %minoltaWhiteBalance = (
+    0 => 'Auto',
+    1 => 'Daylight',
+    2 => 'Cloudy',
+    3 => 'Tungsten',
+    5 => 'Custom',
+    7 => 'Fluorescent',
+    8 => 'Fluorescent 2',
+    11 => 'Custom 2',
+    12 => 'Custom 3',
+    # the following come from tests with the A2 (ref 2)
+    0x0800000 => 'Auto',
+    0x1800000 => 'Daylight',
+    0x2800000 => 'Cloudy',
+    0x3800000 => 'Tungsten',
+    0x4800000 => 'Flash',
+    0x5800000 => 'Fluorescent',
+    0x6800000 => 'Shade',
+    0x7800000 => 'Custom1',
+    0x8800000 => 'Custom2',
+    0x9800000 => 'Custom3',
+);
+
+#------------------------------------------------------------------------------
+# PrintConv for Minolta white balance
+sub ConvertWhiteBalance($)
+{
+    my $val = shift;
+    my $printConv = $minoltaWhiteBalance{$val};
+    unless (defined $printConv) {
+        if ($val & 0xffff0000) {
+            # the A2 values can be shifted by += 3 settings, where
+            # each setting adds or subtracts 0x0010000 (ref 2)
+            my $type = ($val & 0xff000000) + 0x800000;
+            if ($minoltaWhiteBalance{$type}) {
+                $printConv = $minoltaWhiteBalance{$type} .
+                             sprintf("%+.8g", ($val - $type) / 0x10000);
+            } else {
+                $printConv = sprintf("Unknown (0x%x)", $val);
+            }
+        } else {
+            $printConv = sprintf("Unknown ($val)");
+        }
+    }
+    return $printConv;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Minolta - Minolta EXIF maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+Minolta and Konica-Minolta maker notes in EXIF information, and to read
+and write Minolta RAW (MRW) images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.dalibor.cz/minolta/makernote.htm>
+
+=item L<http://www.cybercom.net/~dcoffin/dcraw/>
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Jay Al-Saadi, Niels Kristian Bech Jensen, Shingo Noguchi, Pedro
+Corte-Real and Jeffery Small for the information they provided.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Minolta Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/MinoltaRaw.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/MinoltaRaw.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/MinoltaRaw.pm	(revision 20131)
@@ -0,0 +1,359 @@
+#------------------------------------------------------------------------------
+# File:         MinoltaRaw.pm
+#
+# Description:  Read/write Konica-Minolta RAW (MRW) meta information
+#
+# Revisions:    03/11/2006 - P. Harvey Split out from Minolta.pm
+#
+# References:   1) http://www.cybercom.net/~dcoffin/dcraw/
+#               2) http://www.chauveau-central.net/mrw-format/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::MinoltaRaw;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.02';
+
+# Minolta MRW tags
+%Image::ExifTool::MinoltaRaw::Main = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags are used in Minolta RAW format (MRW) images.',
+    "\0TTW" => {
+        Name => 'MinoltaTTW',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            # this EXIF information starts with a TIFF header
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+            WriteProc => \&Image::ExifTool::WriteTIFF,
+        },
+    },
+    "\0PRD" => {
+        Name => 'MinoltaPRD',
+        SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::PRD' },
+    },
+    "\0WBG" => {
+        Name => 'MinoltaWBG',
+        SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::WBG' },
+    },
+    "\0RIF" => {
+        Name => 'MinoltaRIF',
+        SubDirectory => { TagTable => 'Image::ExifTool::MinoltaRaw::RIF' },
+    },
+);
+
+# Minolta MRW PRD information (ref 2)
+%Image::ExifTool::MinoltaRaw::PRD = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    0 => {
+        Name => 'FirmwareID',
+        Format => 'string[8]',
+    },
+    8 => {
+        Name => 'SensorHeight',
+        Format => 'int16u',
+    },
+    10 => {
+        Name => 'SensorWidth',
+        Format => 'int16u',
+    },
+    12 => {
+        Name => 'ImageHeight',
+        Format => 'int16u',
+    },
+    14 => {
+        Name => 'ImageWidth',
+        Format => 'int16u',
+    },
+    16 => {
+        Name => 'RawDepth',
+        Format => 'int8u',
+    },
+    17 => {
+        Name => 'BitDepth',
+        Format => 'int8u',
+    },
+    18 => {
+        Name => 'StorageMethod',
+        Format => 'int8u',
+        PrintConv => {
+            82 => 'Padded',
+            89 => 'Linear',
+        },
+    },
+    23 => {
+        Name => 'BayerPattern',
+        Format => 'int8u',
+        PrintConv => {
+            1 => 'RGGB',
+            4 => 'GBRG',
+        },
+    },
+);
+
+# Minolta MRW WBG information (ref 2)
+%Image::ExifTool::MinoltaRaw::WBG = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    0 => {
+        Name => 'WBScale',
+        Format => 'int8u[4]',
+    },
+    4 => {
+        Name => 'WBLevels',
+        Format => 'int16u[4]',
+    },
+);
+
+# Minolta MRW RIF information (ref 2)
+%Image::ExifTool::MinoltaRaw::RIF = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    FIRST_ENTRY => 0,
+    1 => {
+        Name => 'Saturation',
+        Format => 'int8s',
+    },
+    2 => {
+        Name => 'Contrast',
+        Format => 'int8s',
+    },
+    3 => {
+        Name => 'Sharpness',
+        Format => 'int8s',
+    },
+    4 => {
+        Name => 'WBMode',
+        PrintConv => 'Image::ExifTool::MinoltaRaw::ConvertWBMode($val)',
+    },
+    5 => {
+        Name => 'ProgramMode',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Portrait',
+            2 => 'Text',
+            3 => 'Night Portrait',
+            4 => 'Sunset',
+            5 => 'Sports',
+        },
+    },
+    6 => {
+        Name => 'ISOSetting',
+        ValueConv => '2 ** (($val-48)/8) * 100',
+        ValueConvInv => '48 + 8*log($val/100)/log(2)',
+        PrintConv => 'int($val + 0.5)',
+        PrintConvInv => '$val',
+    },
+    7 => {
+        Name => 'ColorMode',
+        PrintHex => 1,
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Black & White',
+            2 => 'Vivid color',
+            3 => 'Solarization',
+            4 => 'Adobe RGB',
+            13 => 'Natural sRGB',
+            14 => 'Natural+ sRGB',
+            0x84 => 'Adobe RGB', # what does the high bit mean?
+        },
+    },
+    56 => {
+        Name => 'ColorFilter',
+        Format => 'int8s',
+    },
+    57 => 'BWFilter',
+    58 => {
+        Name => 'ZoneMatching',
+        PrintConv => {
+            0 => 'ISO Setting Used',
+            1 => 'High Key',
+            2 => 'Low Key',
+        },
+    },
+    59 => {
+        Name => 'Hue',
+        Format => 'int8s',
+    },
+    60 => {
+        Name => 'ColorTemperature',
+        ValueConv => '$val * 100',
+        ValueConvInv => '$val / 100',
+    },
+);
+
+#------------------------------------------------------------------------------
+# PrintConv for WBMode
+sub ConvertWBMode($)
+{
+    my $val = shift;
+    my %mrwWB = (
+        0 => 'Auto',
+        1 => 'Daylight',
+        2 => 'Cloudy',
+        3 => 'Tungsten',
+        4 => 'Flash/Fluorescent',
+        5 => 'Fluorescent',
+        6 => 'Shade',
+        7 => 'User 1',
+        8 => 'User 2',
+        9 => 'User 3',
+        10 => 'Temperature',
+    );
+    my $lo = $val & 0x0f;
+    my $wbstr = $mrwWB{$lo} || "Unknown ($lo)";
+    my $hi = $val >> 4;
+    $wbstr .= ' (' . ($hi - 8) . ')' if $hi >= 6 and $hi <=12;
+    return $wbstr;
+}
+
+#------------------------------------------------------------------------------
+# Read or write Minolta MRW file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid MRW file, or -1 on write error
+sub ProcessMRW($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $outfile = $$dirInfo{OutFile};
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my ($data, $err, $outBuff);
+
+    $raf->Read($data,8) == 8 or return 0;
+    $data =~ /^\0MRM/ or return 0;
+    $exifTool->SetFileType() unless $exifTool->{VALUE}->{FileType};
+    SetByteOrder('MM');
+    my $tagTablePtr = GetTagTable('Image::ExifTool::MinoltaRaw::Main');
+    if ($outfile) {
+        $exifTool->InitWriteDirs('TIFF'); # use same write dirs as TIFF
+        $outBuff = '';
+    }
+    my $offset = Get32u(\$data, 4) + 8;
+    my $pos = 8;
+    my $rtnVal = 1;
+    $verbose and printf $out "  [MRW Data Offset: 0x%x]\n", $offset;
+    # loop through MRW segments (ref 1)
+    while ($pos < $offset) {
+        $raf->Read($data,8) == 8 or $err = 1, last;
+        $pos += 8;
+        my $tag = substr($data, 0, 4);
+        my $len = Get32u(\$data, 4);
+        if ($verbose) {
+            print $out "MRW ",$exifTool->Printable($tag)," segment ($len bytes):\n";
+            if ($verbose > 2) {
+                $raf->Read($data,$len) == $len and $raf->Seek($pos,0) or $err = 1, last;
+                my %parms = (Addr => $pos, Out => $out);
+                $parms{MaxLen} = 96 unless $verbose > 3;
+                Image::ExifTool::HexDump(\$data,undef,%parms);
+            }
+        }
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        if ($tagInfo and $$tagInfo{SubDirectory}) {
+            my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+            my $buff;
+            $raf->Read($buff, $len) == $len or $err = 1, last;
+            my %subdirInfo = (
+                DataPt => \$buff,
+                DataLen => $len,
+                DataPos => $pos,
+                DirStart => 0,
+                DirLen => $len,
+                DirName => $$tagInfo{Name},
+                Parent => 'MRW',
+                NoTiffEnd => 1, # no end-of-TIFF check
+            );
+            if ($outfile) {
+                my $writeProc = $tagInfo->{SubDirectory}->{WriteProc};
+                my $val = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
+                if (defined $val and length $val) {
+                    # pad to an even 4 bytes (can't hurt, and it seems to be the standard)
+                    $val .= "\0" x (4 - (length($val) & 0x03)) if length($val) & 0x03;
+                    $outBuff .= $tag . Set32u(length $val) . $val;
+                } elsif (not defined $val) {
+                    $outBuff .= $data . $buff;  # copy over original information
+                }
+            } else {
+                my $processProc = $tagInfo->{SubDirectory}->{ProcessProc};
+                $exifTool->ProcessDirectory(\%subdirInfo, $subTable, $processProc);
+            }
+        } elsif ($outfile) {
+            # add this segment to the output buffer
+            my $buff;
+            $raf->Read($buff, $len) == $len or $err = 1, last;
+            $outBuff .= $data . $buff;
+        } else {
+            # skip this segment
+            $raf->Seek($pos+$len, 0) or $err = 1, last;
+        }
+        $pos += $len;
+    }
+    $pos == $offset or $err = 1;    # meta information length check
+
+    if ($outfile) {
+        # write the file header then the buffered meta information
+        Write($outfile, "\0MRM", Set32u(length $outBuff), $outBuff) or $rtnVal = -1;
+        # copy over image data
+        while ($raf->Read($outBuff, 65536)) {
+            Write($outfile, $outBuff) or $rtnVal = -1;
+        }
+    }
+    $err and $exifTool->Error("MRW format error");
+    return $rtnVal;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::MinoltaRaw - Read/write Konica-Minolta RAW (MRW) information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read and
+write Konica-Minolta RAW (MRW) images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.cybercom.net/~dcoffin/dcraw/>
+
+=item L<http://www.chauveau-central.net/mrw-format/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/MinoltaRaw Tags>,
+L<Image::ExifTool::Minolta(3pm)|Image::ExifTool::Minolta>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Nikon.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Nikon.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Nikon.pm	(revision 20131)
@@ -0,0 +1,1714 @@
+#------------------------------------------------------------------------------
+# File:         Nikon.pm
+#
+# Description:  Nikon EXIF maker notes tags
+#
+# Revisions:    12/09/2003 - P. Harvey Created
+#               05/17/2004 - P. Harvey Added information from Joseph Heled
+#               09/21/2004 - P. Harvey Changed tag 2 to ISOUsed & added PrintConv
+#               12/01/2004 - P. Harvey Added default PRINT_CONV
+#               12/06/2004 - P. Harvey Added SceneMode
+#               01/01/2005 - P. Harvey Decode preview image and preview IFD
+#               03/35/2005 - T. Christiansen additions
+#               05/10/2005 - P. Harvey Decode encrypted lens data
+#
+# References:   1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
+#               2) Joseph Heled private communication (tests with D70)
+#               3) Thomas Walter private communication (tests with Coolpix 5400)
+#               4) http://www.cybercom.net/~dcoffin/dcraw/
+#               5) Brian Ristuccia private communication (tests with D70)
+#               6) Danek Duvall private communication (tests with D70)
+#               7) Tom Christiansen private communication (tests with D70)
+#               8) Robert Rottmerhusen private communication
+#               9) http://members.aol.com/khancock/pilot/nbuddy/
+#              10) Werner Kober private communication (D2H, D2X, D100, D70, D200)
+#              11) http://www.rottmerhusen.com/objektives/lensid/thirdparty.html
+#              12) http://libexif.sourceforge.net/internals/mnote-olympus-tag_8h-source.html
+#              13) Roger Larsson private communication (tests with D200)
+#              14) http://homepage3.nifty.com/kamisaka/makernote/makernote_nikon.htm
+#              15) http://tomtia.plala.jp/DigitalCamera/MakerNote/index.asp
+#              16) Jeffrey Friedl private communication (D200 with firmware update)
+#              17) http://www.wohlberg.net/public/software/photo/nstiffexif/
+#              18) Anonymous user private communication (D70, D200, D2x)
+#              19) Jens Duttke private communication
+#              20) Bruce Stevens private communication
+#              21) Vladimir Sauta private communication (D80)
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Nikon;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.76';
+
+# nikon lens ID numbers (ref 8/11)
+my %nikonLensIDs = (
+    Notes => q{
+        The Nikon LensID is constructed as a Composite tag from the raw hex values
+        of 8 other tags: LensIDNumber, LensFStops, MinFocalLength, MaxFocalLength,
+        MaxApertureAtMinFocal, MaxApertureAtMaxFocal, MCUVersion and LensType, in
+        that order.  (source:
+        L<http://www.rottmerhusen.com/objektives/lensid/thirdparty.html>)
+    },
+    # (hex digits must be uppercase in keys below)
+    '01 58 50 50 14 14 02 00' => 'AF Nikkor 50mm f/1.8',
+    '01 00 00 00 00 00 02 00' => 'AF Teleconverter TC-16A 1.6x',
+    '01 00 00 00 00 00 08 00' => 'AF Teleconverter TC-16A 1.6x',
+    '02 42 44 5C 2A 34 02 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5',
+    '02 42 44 5C 2A 34 08 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5',
+    '03 48 5C 81 30 30 02 00' => 'AF Zoom-Nikkor 70-210mm f/4',
+    '04 48 3C 3C 24 24 03 00' => 'AF Nikkor 28mm f/2.8',
+    '05 54 50 50 0C 0C 04 00' => 'AF Nikkor 50mm f/1.4',
+    '06 54 53 53 24 24 06 00' => 'AF Micro-Nikkor 55mm f/2.8',
+    '07 40 3C 62 2C 34 03 00' => 'AF Zoom-Nikkor 28-85mm f/3.5-4.5',
+    '08 40 44 6A 2C 34 04 00' => 'AF Zoom-Nikkor 35-105mm f/3.5-4.5',
+    '09 48 37 37 24 24 04 00' => 'AF Nikkor 24mm f/2.8',
+    '0A 48 8E 8E 24 24 03 00' => 'AF Nikkor 300mm f/2.8 IF-ED',
+    '0B 48 7C 7C 24 24 05 00' => 'AF Nikkor 180mm f/2.8 IF-ED',
+    '0D 40 44 72 2C 34 07 00' => 'AF Zoom-Nikkor 35-135mm f/3.5-4.5',
+    '0E 48 5C 81 30 30 05 00' => 'AF Zoom-Nikkor 70-210mm f/4',
+    '0F 58 50 50 14 14 05 00' => 'AF Nikkor 50mm f/1.8 N',
+    '10 48 8E 8E 30 30 08 00' => 'AF Nikkor 300mm f/4 IF-ED',
+    '11 48 44 5C 24 24 08 00' => 'AF Zoom-Nikkor 35-70mm f/2.8',
+    '12 48 5C 81 30 3C 09 00' => 'AF Nikkor 70-210mm f/4-5.6',
+    '13 42 37 50 2A 34 0B 00' => 'AF Zoom-Nikkor 24-50mm f/3.3-4.5',
+    '14 48 60 80 24 24 0B 00' => 'AF Zoom-Nikkor 80-200mm f/2.8 ED',
+    '15 4C 62 62 14 14 0C 00' => 'AF Nikkor 85mm f/1.8',
+    '17 3C A0 A0 30 30 11 00' => 'Nikkor 500mm f/4 P',
+    '18 40 44 72 2C 34 0E 00' => 'AF Zoom-Nikkor 35-135mm f/3.5-4.5 N',
+    '1A 54 44 44 18 18 11 00' => 'AF Nikkor 35mm f/2',
+    '1B 44 5E 8E 34 3C 10 00' => 'AF Zoom-Nikkor 75-300mm f/4.5-5.6',
+    '1C 48 30 30 24 24 12 00' => 'AF Nikkor 20mm f/2.8',
+    '1D 42 44 5C 2A 34 12 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5 N',
+    '1E 54 56 56 24 24 13 00' => 'AF Micro-Nikkor 60mm f/2.8',
+    '1F 54 6A 6A 24 24 14 00' => 'AF Micro-Nikkor 105mm f/2.8',
+    '20 48 60 80 24 24 15 00' => 'AF Zoom-Nikkor ED 80-200mm f/2.8',
+    '21 40 3C 5C 2C 34 16 00' => 'AF Zoom-Nikkor 28-70mm f/3.5-4.5',
+    '22 48 72 72 18 18 16 00' => 'AF DC-Nikkor 135mm f/2',
+    '24 48 60 80 24 24 1A 02' => 'AF Zoom-Nikkor ED 80-200mm f/2.8D',
+    '25 48 44 5C 24 24 1B 02' => 'AF Zoom-Nikkor 35-70mm f/2.8D',
+    '25 48 44 5C 24 24 52 02' => 'AF Zoom-Nikkor 35-70mm f/2.8D N',
+    '27 48 8E 8E 24 24 F2 02' => 'AF-I Nikkor 300mm f/2.8D IF-ED',
+    '27 48 8E 8E 24 24 1D 02' => 'AF-I Nikkor 300mm f/2.8D IF-ED',
+    '28 3C A6 A6 30 30 1D 02' => 'AF-I Nikkor 600mm f/4D IF-ED',
+    '2A 54 3C 3C 0C 0C 26 02' => 'AF Nikkor 28mm f/1.4D',
+    '2C 48 6A 6A 18 18 27 02' => 'AF DC-Nikkor 105mm f/2D',
+    '2D 48 80 80 30 30 21 02' => 'AF Micro-Nikkor 200mm f/4D IF-ED',
+    '2E 48 5C 82 30 3C 28 02' => 'AF Nikkor 70-210mm f/4-5.6D',
+    '2F 48 30 44 24 24 29 02' => 'AF Zoom-Nikkor 20-35mm f/2.8(IF)',
+    '31 54 56 56 24 24 25 02' => 'AF Micro-Nikkor 60mm f/2.8D',
+    '32 54 6A 6A 24 24 35 02' => 'AF Micro-Nikkor 105mm f/2.8D',
+    '33 48 2D 2D 24 24 31 02' => 'AF Nikkor 18mm f/2.8D',
+    '34 48 29 29 24 24 32 02' => 'AF Fisheye Nikkor 16mm f/2.8D',
+    '36 48 37 37 24 24 34 02' => 'AF Nikkor 24mm f/2.8D',
+    '37 48 30 30 24 24 36 02' => 'AF Nikkor 20mm f/2.8D',
+    '38 4C 62 62 14 14 37 02' => 'AF Nikkor 85mm f/1.8D',
+    '3B 48 44 5C 24 24 3A 02' => 'AF Zoom-Nikkor 35-70mm f/2.8D N',
+    '3D 3C 44 60 30 3C 3E 02' => 'AF Zoom-Nikkor 35-80mm f/4-5.6D',
+    '3E 48 3C 3C 24 24 3D 02' => 'AF Nikkor 28mm f/2.8D',
+    '41 48 7C 7C 24 24 43 02' => 'AF Nikkor 180mm f/2.8D IF-ED',
+    '42 54 44 44 18 18 44 02' => 'AF Nikkor 35mm f/2D',
+    '43 54 50 50 0C 0C 46 02' => 'AF Nikkor 50mm f/1.4D',
+    '46 3C 44 60 30 3C 49 02' => 'AF Zoom-Nikkor 35-80mm f/4-5.6D N',
+    '47 42 37 50 2A 34 4A 02' => 'AF Zoom-Nikkor 24-50mm f/3.3-4.5D',
+    '48 48 8E 8E 24 24 4B 02' => 'AF-S Nikkor 300mm f/2.8D IF-ED',
+    '4A 54 62 62 0C 0C 4D 02' => 'AF Nikkor 85mm f/1.4D IF',
+    '4C 40 37 6E 2C 3C 4F 02' => 'AF Zoom-Nikkor 24-120mm f/3.5-5.6D IF',
+    '4D 40 3C 80 2C 3C 62 02' => 'AF Zoom-Nikkor 28-200mm f/3.5-5.6D IF',
+    '4E 48 72 72 18 18 51 02' => 'AF DC-Nikkor 135mm f/2D',
+    '4F 40 37 5C 2C 3C 53 06' => 'IX-Nikkor 24-70mm f/3.5-5.6',
+    '53 48 60 80 24 24 60 02' => 'AF Zoom-Nikkor 80-200mm f/2.8D ED',
+    '54 44 5C 7C 34 3C 58 02' => 'AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED',
+    '56 48 5C 8E 30 3C 5A 02' => 'AF Zoom-Nikkor 70-300mm f/4-5.6D ED',
+    '59 48 98 98 24 24 5D 02' => 'AF-S Nikkor 400mm f/2.8D IF-ED',
+    '5A 3C 3E 56 30 3C 5E 06' => 'IX-Nikkor 30-60mm f/4-5.6',
+    '5D 48 3C 5C 24 24 63 02' => 'AF-S Zoom-Nikkor 28-70mm f/2.8D IF-ED',
+    '5E 48 60 80 24 24 64 02' => 'AF-S Zoom-Nikkor 80-200mm f/2.8D IF-ED',
+    '5F 40 3C 6A 2C 34 65 02' => 'AF Zoom-Nikkor 28-105mm f/3.5-4.5D IF',
+    '60 40 3C 60 2C 3C 66 02' => 'AF Zoom-Nikkor 28-80mm f/3.5-5.6D', #(http://www.exif.org/forum/topic.asp?TOPIC_ID=16)
+    '61 44 5E 86 34 3C 67 02' => 'AF Zoom-Nikkor 75-240mm f/4.5-5.6D',
+    '63 48 2B 44 24 24 68 02' => 'AF-S Nikkor 17-35mm f/2.8D IF-ED',
+    '64 00 62 62 24 24 6A 02' => 'PC Micro-Nikkor 85mm f/2.8D',
+    '65 44 60 98 34 3C 6B 0A' => 'AF VR Zoom-Nikkor 80-400mm f/4.5-5.6D ED',
+    '66 40 2D 44 2C 34 6C 02' => 'AF Zoom-Nikkor 18-35mm f/3.5-4.5D IF-ED',
+    '67 48 37 62 24 30 6D 02' => 'AF Zoom-Nikkor 24-85mm f/2.8-4D IF',
+    '68 42 3C 60 2A 3C 6E 06' => 'AF Zoom-Nikkor 28-80mm f/3.3-5.6G',
+    '69 48 5C 8E 30 3C 6F 06' => 'AF Zoom-Nikkor 70-300mm f/4-5.6G',
+    '6A 48 8E 8E 30 30 70 02' => 'AF-S Nikkor 300mm f/4D IF-ED',
+    '6B 48 24 24 24 24 71 02' => 'AF Nikkor ED 14mm f/2.8D',
+    '6D 48 8E 8E 24 24 73 02' => 'AF-S Nikkor 300mm f/2.8D IF-ED II',
+    '6E 48 98 98 24 24 74 02' => 'AF-S Nikkor 400mm f/2.8D IF-ED II',
+    '6F 3C A0 A0 30 30 75 02' => 'AF-S Nikkor 500mm f/4D IF-ED',
+    '70 3C A6 A6 30 30 76 02' => 'AF-S Nikkor 600mm f/4D IF-ED',
+    '72 48 4C 4C 24 24 77 00' => 'Nikkor 45mm f/2.8 P',
+    '74 40 37 62 2C 34 78 06' => 'AF-S Zoom-Nikkor 24-85mm f/3.5-4.5G IF-ED',
+    '75 40 3C 68 2C 3C 79 06' => 'AF Zoom-Nikkor 28-100mm f/3.5-5.6G',
+    '76 58 50 50 14 14 7A 02' => 'AF Nikkor 50mm f/1.8D',
+    '77 48 5C 80 24 24 7B 0E' => 'AF-S VR Zoom-Nikkor 70-200mm f/2.8G IF-ED',
+    '78 40 37 6E 2C 3C 7C 0E' => 'AF-S VR Zoom-Nikkor 24-120mm f/3.5-5.6G IF-ED',
+    '79 40 3C 80 2C 3C 7F 06' => 'AF Zoom-Nikkor 28-200mm f/3.5-5.6G IF-ED',
+    '7A 3C 1F 37 30 30 7E 06' => 'AF-S DX Zoom-Nikkor 12-24mm f/4G IF-ED',
+    '7B 48 80 98 30 30 80 0E' => 'AF-S VR Zoom-Nikkor 200-400mm f/4G IF-ED',
+    '7D 48 2B 53 24 24 82 06' => 'AF-S DX Zoom-Nikkor 17-55mm f/2.8G IF-ED',
+    '7F 40 2D 5C 2C 34 84 06' => 'AF-S DX Zoom-Nikkor 18-70mm f/3.5-4.5G IF-ED',
+    '80 48 1A 1A 24 24 85 06' => 'AF DX Fisheye-Nikkor 10.5mm f/2.8G ED',
+    '81 54 80 80 18 18 86 0E' => 'AF-S VR Nikkor 200mm f/2G IF-ED',
+    '82 48 8E 8E 24 24 87 0E' => 'AF-S VR Nikkor 300mm f/2.8G IF-ED',
+    '89 3C 53 80 30 3C 8B 06' => 'AF-S DX Zoom-Nikkor 55-200mm f/4-5.6G ED',
+    '8A 54 6A 6A 24 24 8C 0E' => 'AF-S VR Micro-Nikkor 105mm f/2.8G IF-ED', #10
+    '8B 40 2D 80 2C 3C FD 0E' => 'AF-S DX VR Zoom-Nikkor 18-200mm f/3.5-5.6G IF-ED', #21
+    '8B 40 2D 80 2C 3C 8D 0E' => 'AF-S DX VR Zoom-Nikkor 18-200mm f/3.5-5.6G IF-ED',
+    '8C 40 2D 53 2C 3C 8E 06' => 'AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED',
+    '8D 44 5C 8E 34 3C 8F 0E' => 'AF-S VR Zoom-Nikkor 70-300mm f/4.5-5.6G IF-ED', #10
+    '8F 40 2D 72 2C 3C 91 06' => 'AF-S DX Zoom-Nikkor 18-135mm f/3.5-5.6G IF-ED',
+    '90 3B 53 80 30 3C 92 0E' => 'AF-S DX VR Zoom-Nikkor 55-200mm f/4-5.6G IF-ED',
+    '93 48 37 5C 24 24 95 06' => 'AF-S Nikkor 24-70 f/2.8G ED',
+    '94 40 2D 53 2C 3C 96 06' => 'AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED II', #10 (D40)
+    '96 48 98 98 24 24 98 0E' => 'AF-S Nikkor 400mm f/2.8G ED VR',
+    '98 3C A6 A6 30 30 9A 0E' => 'AF-S Nikkor 600mm f/4G ED VR',
+#
+    '06 3F 68 68 2C 2C 06 00' => 'Cosina 100mm f/3.5 Macro',
+#
+    '26 48 11 11 30 30 1C 02' => 'Sigma 8mm F4 EX Circular Fisheye',
+    '79 40 11 11 2C 2C 1C 06' => 'Sigma 8mm F3.5 EX', #19
+    '48 3C 19 31 30 3C 4B 06' => 'Sigma 10-20mm F4-5.6 EX DC HSM',
+    '48 38 1F 37 34 3C 4B 06' => 'Sigma 12-24mm F4.5-5.6 EX Aspherical DG HSM',
+    '02 3F 24 24 2C 2C 02 00' => 'Sigma 14mm F3.5',
+    '48 48 24 24 24 24 4B 02' => 'Sigma 14mm F2.8 EX ASPHERICAL HSM',
+    '26 48 27 27 24 24 1C 02' => 'Sigma 15mm F2.8 EX Diagonal Fish-Eye',
+    '26 40 27 3F 2C 34 1C 02' => 'Sigma 15-30mm F3.5-4.5 EX Aspherical DG DF',
+    '48 48 2B 44 24 30 4B 06' => 'Sigma 17-35mm F2.8-4 EX DG  Aspherical HSM',
+    '26 54 2B 44 24 30 1C 02' => 'Sigma 17-35mm F2.8-4 EX ASPHERICAL',
+    '7F 48 2B 5C 24 34 1C 06' => 'Sigma 17-70mm F2.8-4.5 DC MACRO Asp. IF',
+    '26 48 2D 50 24 24 1C 06' => 'Sigma 18-50mm F2.8 EX DC',
+    '26 40 2D 50 2C 3C 1C 06' => 'Sigma 18-50mm F3.5-5.6 DC',
+    '7A 40 2D 50 2C 3C 4B 06' => 'Sigma 18-50mm F3.5-5.6 DC HSM',
+    '26 40 2D 70 2B 3C 1C 06' => 'Sigma 18-125mm F3.5-5.6 DC',
+    '26 40 2D 80 2C 40 1C 06' => 'Sigma 18-200mm F3.5-6.3 DC',
+    '26 58 31 31 14 14 1C 02' => 'Sigma 20mm F1.8 EX Aspherical DG DF RF',
+    '26 58 37 37 14 14 1C 02' => 'Sigma 24mm F1.8 EX Aspherical DG DF MACRO',
+    '02 46 37 37 25 25 02 00' => 'Sigma 24mm F2.8 Macro',
+    '26 48 37 56 24 24 1C 02' => 'Sigma 24-60mm F2.8 EX DG',
+    '26 54 37 5C 24 24 1C 02' => 'Sigma 24-70mm F2.8 EX DG Macro',
+    '67 54 37 5C 24 24 1C 02' => 'Sigma 24-70mm F2.8 EX DG Macro',
+    '26 40 37 5C 2C 3C 1C 02' => 'Sigma 24-70mm F3.5-5.6 ASPHERICAL HF',
+    '26 54 37 73 24 34 1C 02' => 'Sigma 24-135mm F2.8-4.5',
+    '26 58 3C 3C 14 14 1C 02' => 'Sigma 28mm F1.8 EX DG DF',
+    '26 48 3C 5C 24 24 1C 06' => 'Sigma 28-70mm F2.8 EX DG',
+    '26 48 3C 5C 24 30 1C 02' => 'Sigma 28-70mm F2.8-4 HIGH SPEED ZOOM',
+    '02 46 3C 5C 25 25 02 00' => 'Sigma 28-70mm F2.8',
+    '02 3F 3C 5C 2D 35 02 00' => 'Sigma 28-70mm F3.5-4.5 UC',
+    '26 40 3C 60 2C 3C 1C 02' => 'Sigma 28-80mm F3.5-5.6 Mini Zoom Macro II Aspherical',
+    '26 3E 3C 6A 2E 3C 1C 02' => 'Sigma 28-105mm F3.8-5.6 UC-III ASPHERICAL IF',
+    '26 40 3C 80 2C 3C 1C 02' => 'Sigma 28-200mm F3.5-5.6 Compact Aspherical Hyperzoom Macro',
+    '26 40 3C 80 2B 3C 1C 02' => 'Sigma 28-200mm F3.5-5.6 Compact Aspherical Hyperzoom Macro',
+    '26 41 3C 8E 2C 40 1C 02' => 'Sigma 28-300mm F3.5-6.3 DG MACRO',
+    '26 40 3C 8E 2C 40 1C 02' => 'Sigma 28-300mm F3.5-6.3 Macro',
+    '48 54 3E 3E 0C 0C 4B 06' => 'Sigma 30mm F1.4 EX DC HSM',
+    '02 40 44 73 2B 36 02 00' => 'Sigma 35-135mm F3.5-4.5 a',
+    '32 54 50 50 24 24 35 02' => 'Sigma 50mm F2.8 EX DG Macro',
+    '7A 47 50 76 24 24 4B 06' => 'Sigma APO 50-150mm F2.8 EX DC HSM',
+    '48 3C 50 A0 30 40 4B 02' => 'Sigma 50-500mm F4-6.3 EX APO RF HSM',
+    '26 3C 54 80 30 3C 1C 06' => 'Sigma 55-200mm F4-5.6 DC',
+    '7A 3B 53 80 30 3C 4B 06' => 'Sigma 55-200mm F4-5.6 DC HSM',
+    '79 48 5C 5C 24 24 1C 06' => 'Sigma 70mm F2.8 EX DG Macro', #19
+    '48 54 5C 80 24 24 4B 02' => 'Sigma 70-200mm F2.8 EX APO IF HSM',
+    '02 46 5C 82 25 25 02 00' => 'Sigma 70-210mm F2.8 APO', #19
+    '26 3C 5C 82 30 3C 1C 02' => 'Sigma 70-210mm F4-5.6 UC-II',
+    '26 3C 5C 8E 30 3C 1C 02' => 'Sigma 70-300mm F4-5.6 DG MACRO',
+    '56 3C 5C 8E 30 3C 1C 02' => 'Sigma 70-300mm F4-5.6 APO Macro Super II',
+    '02 37 5E 8E 35 3D 02 00' => 'Sigma 75-300mm F4.5-5.6 APO',
+    '02 48 65 65 24 24 02 00' => 'Sigma 90mm F2.8 Macro',
+    '77 44 61 98 34 3C 7B 0E' => 'Sigma 80-400mm f4.5-5.6 EX OS',
+    '48 48 68 8E 30 30 4B 02' => 'Sigma 100-300mm F4 EX IF HSM',
+    '48 54 6F 8E 24 24 4B 02' => 'Sigma APO 120-300mm F2.8 EX DG HSM',
+    '26 44 73 98 34 3C 1C 02' => 'Sigma 135-400mm F4.5-5.6 APO Aspherical',
+    '48 48 76 76 24 24 4B 06' => 'Sigma 150mm F2.8 EX DG APO Macro HSM',
+    '48 4C 7C 7C 2C 2C 4B 02' => 'Sigma 180mm F3.5 EX DG Macro', #19
+    '26 40 7B A0 34 40 1C 02' => 'Sigma APO 170-500mm F5-6.3 ASPHERICAL RF',
+    '48 4C 7D 7D 2C 2C 4B 02' => 'Sigma APO MACRO 180mm F3.5 EX DG HSM',
+    '48 54 8E 8E 24 24 4B 02' => 'Sigma APO 300mm F2.8 EX DG HSM',
+    '26 48 8E 8E 30 30 1C 02' => 'Sigma APO TELE MACRO 300mm F4',
+    '48 3C 8E B0 3C 3C 4B 02' => 'Sigma APO 300-800 F5.6 EX DG HSM',
+    '02 2F 98 98 3D 3D 02 00' => 'Sigma 400mm F5.6 APO',
+    '02 37 A0 A0 34 34 02 00' => 'Sigma APO 500mm F4.5', #20
+#
+    '03 43 5C 81 35 35 02 00' => 'Soligor AF C/D ZOOM UMCS 70-210mm 1:4.5',
+#
+    '00 40 18 2B 2C 34 00 06' => 'Tokina AT-X 107 DX Fish-Eye - AF 10-17mm F3.5-4.5',
+    '00 3C 1F 37 30 30 00 06' => 'Tokina AT-X 124 AF PRO DX - AF 12-24mm F4',
+    '00 48 29 50 24 24 00 06' => 'Tokina AT-X 165 PRO DX - AF 16-50mm F2.8',
+    '00 40 2B 2B 2C 2C 00 02' => 'Tokina AT-X 17 AF PRO - AF 17mm F3.5',
+    '25 48 3C 5C 24 24 1B 02' => 'Tokina AT-X 287 AF PRO SV 28-70mm F2.8',
+    '00 48 3C 60 24 24 00 02' => 'Tokina AT-X 280 AF PRO 28-80mm F2.8 ASPHERICAL',
+    '00 48 50 72 24 24 00 06' => 'Tokina AT-X 535 PRO DX - AF 50-135mm F2.8',
+    '14 54 60 80 24 24 0B 00' => 'Tokina AT-X 828 AF 80-200mm F2.8',
+    '24 44 60 98 34 3C 1A 02' => 'Tokina AT-X 840 AF II 80-400mm F4.5-5.6',
+    '00 44 60 98 34 3C 00 02' => 'Tokina AT-X 840D 80-400mm F4.5-5.6', #PH
+    '00 54 68 68 24 24 00 02' => 'Tokina AT-X M100 PRO D - 100mm F2.8',
+    '14 48 68 8E 30 30 0B 00' => 'Tokina AT-X 340 AF II 100-300mm F4',
+    '00 54 8E 8E 24 24 00 02' => 'Tokina AT-X 300 AF PRO 300mm F2.8',
+#
+    '00 36 1C 2D 34 3C 00 06' => 'Tamron SP AF11-18mm f/4.5-5.6 Di II LD Aspherical (IF)',
+    '07 46 2B 44 24 30 03 02' => 'Tamron SP AF17-35mm f/2.8-4 Di LD Aspherical (IF)',
+    '00 53 2B 50 24 24 00 06' => 'Tamron SP AF17-50mm f/2.8 (A16)', #PH
+    '00 3F 2D 80 2B 40 00 06' => 'Tamron AF18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF)',
+    '00 3F 2D 80 2C 40 00 06' => 'Tamron AF18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro',
+    '07 40 2F 44 2C 34 03 02' => 'Tamron AF19-35mm f/3.5-4.5 N',
+    '07 40 30 45 2D 35 03 02' => 'Tamron AF19-35mm f/3.5-4.5',
+    '00 49 30 48 22 2B 00 02' => 'Tamron SP AF20-40mm f/2.7-3.5',
+    '0E 4A 31 48 23 2D 0E 02' => 'Tamron SP AF20-40mm f/2.7-3.5',
+    '45 41 37 72 2C 3C 48 02' => 'Tamron SP AF24-135mm f/3.5-5.6 AD Aspherical (IF) Macro',
+    '33 54 3C 5E 24 24 62 02' => 'Tamron SP AF28-75mm f/2.8 XR Di LD Aspherical (IF) Macro',
+    '10 3D 3C 60 2C 3C D2 02' => 'Tamron AF28-80mm f/3.5-5.6 Aspherical',
+    '45 3D 3C 60 2C 3C 48 02' => 'Tamron AF28-80mm f/3.5-5.6 Aspherical',
+    '00 48 3C 6A 24 24 00 02' => 'Tamron SP AF28-105mm f/2.8',
+    '0B 3E 3D 7F 2F 3D 0E 02' => 'Tamron AF28-200mm f/3.8-5.6D',
+    '0B 3E 3D 7F 2F 3D 0E 00' => 'Tamron AF28-200mm f/3.8-5.6',
+    '4D 41 3C 8E 2B 40 62 02' => 'Tamron AF28-300mm f/3.5-6.3 XR Di LD Aspherical (IF)',
+    '4D 41 3C 8E 2C 40 62 02' => 'Tamron AF28-300mm f/3.5-6.3D',
+    '69 48 5C 8E 30 3C 6F 02' => 'Tamron AF70-300mm f/4-5.6 LD Macro 1:2',
+    '32 53 64 64 24 24 35 02' => 'Tamron SP AF90mm f/2.8 Di 1:1 Macro',
+    '00 4C 7C 7C 2C 2C 00 02' => 'Tamron SP AF180mm f/3.5 Di Model B01',
+    '20 3C 80 98 3D 3D 1E 02' => 'Tamron AF200-400mm f/5.6 LD IF',
+    '00 3E 80 A0 38 3F 00 02' => 'Tamron SP AF200-500mm f/5-6.3 Di LD (IF)',
+    '00 3F 80 A0 38 3F 00 02' => 'Tamron SP AF200-500mm f/5-6.3 Di',
+#
+    '00 00 00 00 00 00 00 01' => 'Manual Lens No CPU',
+    '1E 5D 64 64 20 20 13 00' => 'Unknown 90mm f/2.5',
+    '2F 40 30 44 2C 34 29 02' => 'Unknown 20-35mm f/3.5-4.5D',
+    '12 3B 68 8D 3D 43 09 02' => 'Unknown 100-290mm f/5.6-6.7',
+);
+
+# Nikon maker note tags
+%Image::ExifTool::Nikon::Main = (
+    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikon,
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PRINT_CONV => 'Image::ExifTool::Nikon::FormatString($val)',
+    0x0001 => { #2
+        # the format differs for different models.  for D70, this is a string '0210',
+        # but for the E775 it is binary: "\x00\x01\x00\x00"
+        Name => 'MakerNoteVersion',
+        Writable => 'undef',
+        Count => 4,
+        # convert to string if binary
+        ValueConv => '$_=$val; /^[\x00-\x09]/ and $_=join("",unpack("CCCC",$_)); $_',
+        ValueConvInv => '$val',
+        PrintConv => '$_=$val;s/^(\d{2})/$1\./;s/^0//;$_',
+        PrintConvInv => '$_=$val;s/\.//;"0$_"',
+    },
+    0x0002 => {
+        # this is the ISO actually used by the camera
+        # (may be different than ISO setting if auto)
+        Name => 'ISO',
+        Writable => 'int16u',
+        Count => 2,
+        Priority => 0,  # the EXIF ISO is more reliable
+        Groups => { 2 => 'Image' },
+        # first number is 1 for "Hi ISO" modes (H0.3, H0.7 and H1.0 on D80) - PH
+        PrintConv => '$_=$val;s/^0 //;s/^1 (\d+)/Hi $1/;$_',
+        PrintConvInv => '$_=$val;/^\d+/ ? "0 $_" : (s/Hi ?//i ? "1 $_" : $_)',
+    },
+    0x0003 => { Name => 'ColorMode',    Writable => 'string' },
+    0x0004 => { Name => 'Quality',      Writable => 'string' },
+    0x0005 => { Name => 'WhiteBalance', Writable => 'string' },
+    0x0006 => { Name => 'Sharpness',    Writable => 'string' },
+    0x0007 => { Name => 'FocusMode',    Writable => 'string' },
+    0x0008 => { Name => 'FlashSetting', Writable => 'string' },
+    # FlashType shows 'Built-in,TTL' when builtin flash fires,
+    # and 'Optional,TTL' when external flash is used (ref 2)
+    0x0009 => { #2
+        Name => 'FlashType',
+        Writable => 'string',
+        Count => 13,
+    },
+    0x000b => { Name => 'WhiteBalanceFineTune', Writable => 'int16s' }, #2
+    0x000c => {
+        Name => 'ColorBalance1',
+        Writable => 'rational64u',
+        Count => 4,
+    },
+    0x000d => { #15
+        Name => 'ProgramShift',
+        Writable => 'undef',
+        Count => 4,
+        ValueConv => 'my ($a,$b,$c)=unpack("c3",$val); $c ? $a*($b/$c) : 0',
+        ValueConvInv => q{
+            my $a = int($val*6 + ($val>0 ? 0.5 : -0.5));
+            $a<-128 or $a>127 ? undef : pack("c4",$a,1,6,0);
+        },
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x000e => {
+        Name => 'ExposureDifference',
+        Writable => 'undef',
+        Count => 4,
+        ValueConv => 'my ($a,$b,$c)=unpack("c3",$val); $c ? $a*($b/$c) : 0',
+        ValueConvInv => q{
+            my $a = int($val*12 + ($val>0 ? 0.5 : -0.5));
+            $a<-128 or $a>127 ? undef : pack("c4",$a,1,12,0);
+        },
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    },
+    0x000f => { Name => 'ISOSelection', Writable => 'string' }, #2
+    0x0010 => {
+        Name => 'DataDump',
+        Writable => 0,
+        Binary => 1,
+    },
+    0x0011 => {
+        Name => 'NikonPreview',
+        Groups => { 1 => 'NikonPreview', 2 => 'Image' },
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::PreviewImage',
+            Start => '$val',
+        },
+    },
+    0x0012 => { #2
+        Name => 'FlashExposureComp',
+        Description => 'Flash Exposure Compensation',
+        Writable => 'undef',
+        Count => 4,
+        ValueConv => 'my ($a,$b,$c)=unpack("c3",$val); $c ? $a*($b/$c) : 0',
+        ValueConvInv => q{
+            my $a = int($val*6 + ($val>0 ? 0.5 : -0.5));
+            $a<-128 or $a>127 ? undef : pack("c4",$a,1,6,0);
+        },
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => 'eval $val',
+    },
+    # D70 - another ISO tag
+    0x0013 => { #2
+        Name => 'ISOSetting',
+        Writable => 'int16u',
+        Count => 2,
+        PrintConv => '$_=$val;s/^0 //;$_',
+        PrintConvInv => '"0 $val"',
+    },
+    # D70 Image boundary?? top x,y bot-right x,y
+    0x0016 => { #2
+        Name => 'ImageBoundary',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x0018 => { #5
+        Name => 'FlashExposureBracketValue',
+        Writable => 'undef',
+        Count => 4,
+        ValueConv => 'my ($a,$b,$c)=unpack("c3",$val); $c ? $a*($b/$c) : 0',
+        ValueConvInv => q{
+            my $a = int($val*6 + ($val>0 ? 0.5 : -0.5));
+            $a<-128 or $a>127 ? undef : pack("c4",$a,1,6,0);
+        },
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0019 => { #5
+        Name => 'ExposureBracketValue',
+        Writable => 'rational64s',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x001a => { #PH
+        Name => 'ImageProcessing',
+        Writable => 'string',
+    },
+    0x001b => { #15
+        Name => 'CropHiSpeed',
+        Writable => 'int16u',
+        Count => 7,
+        PrintConv => q{
+            my @a = split ' ', $val;
+            return "Unknown ($val)" unless @a == 7;
+            $a[0] = $a[0] ? "On" : "Off";
+            return "$a[0] ($a[1]x$a[2] cropped to $a[3]x$a[4] at pixel $a[5],$a[6])";
+        }
+    },
+    0x001d => { #4
+        Name => 'SerialNumber',
+        Writable => 0,
+        Notes => 'Not writable because this value is used as a key to decrypt other information',
+        RawConv => '$self->{NikonInfo}->{SerialNumber} = $val',
+    },
+    0x001e => { #14
+        Name => 'ColorSpace',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'sRGB',
+            2 => 'Adobe RGB',
+        },
+    },
+    0x0020 => { #16
+        Name => 'ImageAuthentication',
+        Writable => 'int8u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x0080 => { Name => 'ImageAdjustment',  Writable => 'string' },
+    0x0081 => { Name => 'ToneComp',         Writable => 'string' }, #2
+    0x0082 => { Name => 'AuxiliaryLens',    Writable => 'string' },
+    0x0083 => {
+        Name => 'LensType',
+        Writable => 'int8u',
+        # credit to Tom Christiansen (ref 7) for figuring this out...
+        PrintConv => q[$_ = $val ? Image::ExifTool::DecodeBits($val,
+            {
+                0 => 'MF',
+                1 => 'D',
+                2 => 'G',
+                3 => 'VR',
+            }) : 'AF';
+            # remove commas and change "D G" to just "G"
+            s/,//g; s/\bD G\b/G/; $_
+        ],
+        PrintConvInv => q[
+            my $bits = 0;
+            $bits |= 0x01 if $val =~ /\bMF\b/i;
+            $bits |= 0x02 if $val =~ /\bD\b/i;
+            $bits |= 0x06 if $val =~ /\bG\b/i;
+            $bits |= 0x08 if $val =~ /\bVR\b/i;
+            return $bits;
+        ],
+    },
+    0x0084 => { #2
+        Name => "Lens",
+        Writable => 'rational64u',
+        Count => 4,
+        # short focal, long focal, aperture at short focal, aperture at long focal
+        PrintConv => q{
+            $val =~ tr/,/./;    # in case locale is whacky
+            my ($a,$b,$c,$d) = split ' ', $val;
+            ($a==$b ? $a : "$a-$b") . "mm f/" . ($c==$d ? $c : "$c-$d")
+        },
+        PrintConvInv => '$_=$val; tr/a-z\///d; s/(^|\s)([0-9.]+)(?=\s|$)/$1$2-$2/g; s/-/ /g; $_',
+    },
+    0x0085 => {
+        Name => 'ManualFocusDistance',
+        Writable => 'rational64u',
+    },
+    0x0086 => {
+        Name => 'DigitalZoom',
+        Writable => 'rational64u',
+    },
+    0x0087 => { #5
+        Name => 'FlashMode',
+        Writable => 'int8u',
+        PrintConv => {
+            0 => 'Did Not Fire',
+            1 => 'Fired, Manual', #14
+            7 => 'Fired, External', #14
+            8 => 'Fired, Commander Mode',
+            9 => 'Fired, TTL Mode',
+        },
+    },
+    0x0088 => {
+        Name => 'AFInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::AFInfo',
+        },
+    },
+    0x0089 => { #5
+        Name => 'ShootingMode',
+        Writable => 'int16u',
+        # credit to Tom Christiansen (ref 7) for figuring this out...
+        # The (new?) bit 5 seriously complicates our life here: after firmwareB's
+        # 1.03, bit 5 turns on when you ask for BUT DO NOT USE the long-range
+        # noise reduction feature, probably because even not using it, it still
+        # slows down your drive operation to 50% (1.5fps max not 3fps).  But no
+        # longer does !$val alone indicate single-frame operation. - TC
+        PrintConv => q[
+            $_ = '';
+            unless ($val & 0x87) {
+                return 'Single-Frame' unless $val;
+                $_ = 'Single-Frame, ';
+            }
+            return $_ . Image::ExifTool::DecodeBits($val,
+            {
+                0 => 'Continuous',
+                1 => 'Delay',
+                2 => 'PC Control',
+                4 => 'Exposure Bracketing',
+                5 => 'Unused LE-NR Slowdown',
+                6 => 'White-Balance Bracketing',
+                7 => 'IR Control',
+            });
+        ],
+    },
+    0x008a => { #15
+        Name => 'AutoBracketRelease',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Auto Release',
+            2 => 'Manual Release',
+        },
+    },
+    0x008b => { #8
+        Name => 'LensFStops',
+        ValueConv => 'my ($a,$b,$c)=unpack("C3",$val); $c ? $a*($b/$c) : 0',
+        ValueConvInv => 'my $a=int($val*12+0.5);$a<256 ? pack("C4",$a,1,12,0) : undef',
+        PrintConv => 'sprintf("%.2f", $val)',
+        PrintConvInv => '$val',
+        Writable => 'undef',
+        Count => 4,
+    },
+    0x008c => {
+        Name => 'NEFCurve1',
+        Writable => 0,
+        Binary => 1,
+    },
+    0x008d => { Name => 'ColorHue' ,        Writable => 'string' }, #2
+    # SceneMode takes on the following values: PORTRAIT, PARTY/INDOOR, NIGHT PORTRAIT,
+    # BEACH/SNOW, LANDSCAPE, SUNSET, NIGHT SCENE, MUSEUM, FIREWORKS, CLOSE UP, COPY,
+    # BACK LIGHT, PANORAMA ASSIST, SPORT, DAWN/DUSK
+    0x008f => { Name => 'SceneMode',        Writable => 'string' }, #2
+    # LightSource shows 3 values COLORED SPEEDLIGHT NATURAL.
+    # (SPEEDLIGHT when flash goes. Have no idea about difference between other two.)
+    0x0090 => { Name => 'LightSource',      Writable => 'string' }, #2
+    0x0091 => [ #18
+        {
+            Condition => '$$valPt =~ /^02/',
+            Name => 'ShotInfo',
+            Writable => 0, # can't yet write encrypted data
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfo',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 4,
+                DecryptLen => 0x24e,
+            },
+        },
+        {
+            Name => 'ShotInfo',
+            Writable => 0,
+            Unknown => 1, # no tags known so don't process unless necessary
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfo',
+                DirOffset => 4,
+            },
+        },
+    ],
+    0x0092 => { #2
+        Name => 'HueAdjustment',
+        Writable => 'int16s',
+    },
+# this doesn't look right:
+#    0x0093 => { #15
+#        Name => 'SaturationAdjustment',
+#        Writable => 'int16s',
+#    },
+    0x0094 => { Name => 'Saturation',       Writable => 'int16s' },
+    0x0095 => { Name => 'NoiseReduction',   Writable => 'string' },
+    0x0096 => {
+        Name => 'NEFCurve2',
+        Writable => 0,
+        Binary => 1,
+    },
+    0x0097 => [ #4
+        {
+            Condition => '$$valPt =~ /^0100/', # (D100)
+            Name => 'ColorBalance0100',
+            SubDirectory => {
+                Start => '$valuePtr + 72',
+                TagTable => 'Image::ExifTool::Nikon::ColorBalance1',
+            },
+        },
+        {
+            Condition => '$$valPt =~ /^0102/', # (D2H)
+            Name => 'ColorBalance0102',
+            SubDirectory => {
+                Start => '$valuePtr + 10',
+                TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
+            },
+        },
+        {
+            Condition => '$$valPt =~ /^0103/', # (D70)
+            Name => 'ColorBalance0103',
+            # D70:  at file offset 'tag-value + base + 20', 4 16 bits numbers,
+            # v[0]/v[1] , v[2]/v[3] are the red/blue multipliers.
+            SubDirectory => {
+                Start => '$valuePtr + 20',
+                TagTable => 'Image::ExifTool::Nikon::ColorBalance3',
+            },
+        },
+        {
+            Condition => '$$valPt =~ /^0205/', # (D50)
+            Name => 'ColorBalance0205',
+            Writable => 0, # can't yet write encrypted data
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 4,
+                DecryptLen => 22, # 284 bytes encrypted, but don't need to decrypt it all
+                DirOffset => 14,
+            },
+        },
+        {
+            Condition => '$$valPt =~ /^02/', # (D2X=0204,D2Hs=0206,D200=0207,D40=0208)
+            Name => 'ColorBalance02',
+            Writable => 0, # can't yet write encrypted data
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 284,
+                DecryptLen => 14, # 324 bytes encrypted, but don't need to decrypt it all
+                DirOffset => 6,
+            },
+        },
+        {
+            Name => 'ColorBalanceUnknown',
+            Writable => 0,
+        },
+    ],
+    0x0098 => [
+        { #8
+            Condition => '$$valPt =~ /^0100/', # D100, D1X - PH
+            Name => 'LensData0100',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::LensData00',
+            },
+        },
+        { #8
+            Condition => '$$valPt =~ /^0101/', # D70, D70s - PH
+            Name => 'LensData0101',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::LensData01',
+            },
+        },
+        # note: this information is encrypted if the version is 02xx
+        { #8
+            # 0201 - D200, D2Hs, D2X and D2Xs
+            # 0202 - D40, D40X and D80
+            # 0203 - D300
+            Condition => '$$valPt =~ /^020[1-3]/',
+            Name => 'LensData0201',
+            Writable => 0, # can't yet write encrypted data
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::LensData01',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 4,
+            },
+        },
+        {
+            Name => 'LensDataUnknown',
+            Writable => 0,
+        },
+    ],
+    0x0099 => { #2/15
+        Name => 'RawImageCenter',
+        Writable => 'int16u',
+        Count => 2,
+    },
+    0x009a => { #10
+        Name => 'SensorPixelSize',
+        Writable => 'rational64u',
+        Count => 2,
+        PrintConv => '$val=~s/ / x /;"$val um"',
+        PrintConvInv => '$val=~tr/a-zA-Z/ /;$val',
+    },
+    # 0x009c - observed values: "", "TWO-SHOT" - PH
+    0x00a0 => { Name => 'SerialNumber',     Writable => 'string' }, #2
+    0x00a2 => { # size of compressed image data plus EOI segment (ref 10)
+        Name => 'ImageDataSize',
+        Writable => 'int32u',
+    },
+    0x00a5 => { #15
+        Name => 'ImageCount',
+        Writable => 'int32u',
+    },
+    0x00a6 => { #15
+        Name => 'DeletedImageCount',
+        Writable => 'int32u',
+    },
+    # the sum of 0xa5 and 0xa6 is equal to 0xa7 ShutterCount (D2X,D2Hs,D2H,D200, ref 10)
+    0x00a7 => { # Number of shots taken by camera so far (ref 2)
+        Name => 'ShutterCount',
+        Writable => 0,
+        Notes => 'Not writable because this value is used as a key to decrypt other information',
+        RawConv => '$self->{NikonInfo}->{ShutterCount} = $val',
+    },
+    0x00a9 => { #2
+        Name => 'ImageOptimization',
+        Writable => 'string',
+        Count => 16,
+    },
+    0x00aa => { Name => 'Saturation',       Writable => 'string' }, #2
+    0x00ab => { Name => 'VariProgram',      Writable => 'string' }, #2
+    0x00ac => { Name => 'ImageStabilization',Writable=> 'string' }, #14
+    0x00ad => { Name => 'AFResponse',       Writable => 'string' }, #14
+    0x00b0 => { #PH
+        Name => 'MultiExposure',
+        Condition => '$$valPt =~ /^0100/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::MultiExposure',
+        },
+    },
+    0x00b1 => { #14/PH/19 (D80)
+        Name => 'HighISONoiseReduction',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Minimal', # for high ISO (>800) when setting is "Off"
+            2 => 'Low',     # Low,Normal,High take effect for ISO > 400
+            4 => 'Normal',
+            6 => 'High',
+        },
+    },
+    # 0x00b2 (string: 'Normal', 0xc3's, 0xff's or 0x20's)
+    0x0e00 => {
+        Name => 'PrintIM',
+        Description => 'Print Image Matching',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+    # 0x0e01 I don't know what this is, but in D70 NEF files produced by Nikon
+    # Capture, the data for this tag extends 4 bytes past the end of the maker notes.
+    # Very odd.  I hope these 4 bytes aren't useful because they will get lost by any
+    # utility that blindly copies the maker notes (not ExifTool) - PH
+    0x0e01 => {
+        Name => 'NikonCaptureData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCapture::Main',
+        },
+    },
+    0x0e09 => { #12
+        Name => 'NikonCaptureVersion',
+        Writable => 'string',
+    },
+    # 0x0e0e is in D70 Nikon Capture files (not out-of-the-camera D70 files) - PH
+    0x0e0e => { #PH
+        Name => 'NikonCaptureOffsets',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::CaptureOffsets',
+            Validate => '$val =~ /^0100/',
+            Start => '$valuePtr + 4',
+        },
+    },
+    0x0e10 => { #17
+        Name => 'NikonScanIFD',
+        Groups => { 1 => 'NikonScan', 2 => 'Image' },
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::Scan',
+            Start => '$val',
+        },
+    },
+    # 0x0e13 - some sort of edit history written by Nikon Capture
+);
+
+# NikonScan IFD entries (ref 17)
+%Image::ExifTool::Nikon::Scan = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITE_GROUP => 'NikonScan',
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'NikonScan', 2 => 'Image' },
+    NOTES => 'This information is written by the Nikon Scan software.',
+    0x02 => { Name => 'FilmType',    Writable => 'string', },
+    0x40 => { Name => 'MultiSample', Writable => 'string' },
+    0x41 => { Name => 'BitDepth',    Writable => 'int16u' },
+    0x50 => {
+        Name => 'MasterGain',
+        Writable => 'rational64s',
+        PrintConv => 'sprintf("%.2f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x51 => {
+        Name => 'ColorGain',
+        Writable => 'rational64s',
+        Count => 3,
+        PrintConv => 'sprintf("%.2f %.2f %.2f",split(" ",$val))',
+        PrintConvInv => '$val',
+    },
+    0x100 => { Name => 'DigitalICE', Writable => 'string' },
+    0x110 => {
+        Name => 'ROCInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::ROC' },
+    },
+    0x120 => {
+        Name => 'GEMInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::GEM' },
+    },
+);
+
+# ref 17
+%Image::ExifTool::Nikon::ROC = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int32u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'NikonScan', 2 => 'Image' },
+    0 => {
+        Name => 'DigitalROC',
+        ValueConv => '$val / 10',
+        ValueConvInv => 'int($val * 10)',
+    },
+);
+
+# ref 17
+%Image::ExifTool::Nikon::GEM = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int32u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'NikonScan', 2 => 'Image' },
+    0 => {
+        Name => 'DigitalGEM',
+        ValueConv => '$val<95 ? $val/20-1 : 4',
+        ValueConvInv => '$val == 4 ? 95 : int(($val + 1) * 20)',
+    },
+);
+
+# Nikon AF information (ref 13)
+%Image::ExifTool::Nikon::AFInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0 => {
+        Name => 'AFAreaMode',
+        PrintConv => {
+            0 => 'Single Area',
+            1 => 'Dynamic Area',
+            2 => 'Dynamic Area, Closest Subject',
+            3 => 'Group Dynamic',
+            4 => 'Single Area (wide)',
+            5 => 'Dynamic Area (wide)',
+        },
+    },
+    1 => {
+        Name => 'AFPoint',
+        Notes => 'in some focus modes this value is not meaningful',
+        PrintConv => {
+            0 => 'Center',
+            1 => 'Top',
+            2 => 'Bottom',
+            3 => 'Left',
+            4 => 'Right',
+            5 => 'Upper-left',
+            6 => 'Upper-right',
+            7 => 'Lower-left',
+            8 => 'Lower-right',
+            9 => 'Far Left',
+            10 => 'Far Right',
+        },
+    },
+    2 => {
+        Name => 'AFPointsInFocus',
+        Format => 'int16u',
+        PrintConv => {
+            BITMASK => {
+                0 => 'Center',
+                1 => 'Top',
+                2 => 'Bottom',
+                3 => 'Left',
+                4 => 'Right',
+                5 => 'Upper-left',
+                6 => 'Upper-right',
+                7 => 'Lower-left',
+                8 => 'Lower-right',
+                9 => 'Far Left',
+                10 => 'Far Right',
+            },
+        },
+    },
+);
+
+# ref PH
+%Image::ExifTool::Nikon::CaptureOffsets = (
+    PROCESS_PROC => \&ProcessNikonCaptureOffsets,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    1 => 'IFD0_Offset',
+    2 => 'PreviewIFD_Offset',
+    3 => 'SubIFD_Offset',
+);
+
+# ref 4
+%Image::ExifTool::Nikon::ColorBalance1 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0 => {
+        Name => 'WB_RBGGLevels',
+        Format => 'int16u[4]',
+        Protected => 1,
+    },
+);
+
+# ref 4
+%Image::ExifTool::Nikon::ColorBalance2 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        This information is encrypted for most camera models, and if encrypted is
+        not currently writable by exiftool.
+    },
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0 => {
+        Name => 'WB_RGGBLevels',
+        Format => 'int16u[4]',
+        Protected => 1,
+    },
+);
+
+# ref 4
+%Image::ExifTool::Nikon::ColorBalance3 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0 => {
+        Name => 'WB_RGBGLevels',
+        Format => 'int16u[4]',
+        Protected => 1,
+    },
+);
+
+%Image::ExifTool::Nikon::Type2 = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x0003 => 'Quality',
+    0x0004 => 'ColorMode',
+    0x0005 => 'ImageAdjustment',
+    0x0006 => 'CCDSensitivity',
+    0x0007 => 'WhiteBalance',
+    0x0008 => 'Focus',
+    0x000A => 'DigitalZoom',
+    0x000B => 'Converter',
+);
+
+# these are standard EXIF tags, but they are duplicated here so we
+# can change some names to extract the Nikon preview separately
+%Image::ExifTool::Nikon::PreviewImage = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'NikonPreview', 2 => 'Image'},
+    0x103 => {
+        Name => 'Compression',
+        PrintConv => \%Image::ExifTool::Exif::compression,
+        Priority => 0,
+    },
+    0x11a => {
+        Name => 'XResolution',
+        Priority => 0,
+    },
+    0x11b => {
+        Name => 'YResolution',
+        Priority => 0,
+    },
+    0x128 => {
+        Name => 'ResolutionUnit',
+        PrintConv => {
+            1 => 'None',
+            2 => 'inches',
+            3 => 'cm',
+        },
+        Priority => 0,
+    },
+    0x201 => {
+        Name => 'PreviewImageStart',
+        Flags => [ 'IsOffset', 'Permanent' ],
+        OffsetPair => 0x202, # point to associated byte count
+        DataTag => 'PreviewImage',
+        Writable => 'int32u',
+        WriteGroup => 'NikonPreview',
+        Protected => 2,
+    },
+    0x202 => {
+        Name => 'PreviewImageLength',
+        Flags => 'Permanent' ,
+        OffsetPair => 0x201, # point to associated offset
+        DataTag => 'PreviewImage',
+        Writable => 'int32u',
+        WriteGroup => 'NikonPreview',
+        Protected => 2,
+    },
+    0x213 => {
+        Name => 'YCbCrPositioning',
+        PrintConv => {
+            1 => 'Centered',
+            2 => 'Co-sited',
+        },
+        Priority => 0,
+    },
+);
+
+# these are duplicated enough times to make it worthwhile to define them centrally
+my %nikonApertureConversions = (
+    ValueConv => '2**($val/24)',
+    ValueConvInv => '$val>0 ? 24*log($val)/log(2) : 0',
+    PrintConv => 'sprintf("%.1f",$val)',
+    PrintConvInv => '$val',
+);
+
+my %nikonFocalConversions = (
+    ValueConv => '5 * 2**($val/24)',
+    ValueConvInv => '$val>0 ? 24*log($val/5)/log(2) : 0',
+    PrintConv => 'sprintf("%.1fmm",$val)',
+    PrintConvInv => '$val=~s/\s*mm$//;$val',
+);
+
+# Version 100 Nikon lens data
+%Image::ExifTool::Nikon::LensData00 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    NOTES => 'This structure is used by the D100, and D1X with firmware version 1.1.',
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x00 => {
+        Name => 'LensDataVersion',
+        Format => 'undef[4]',
+    },
+    0x06 => { #8
+        Name => 'LensIDNumber',
+        Notes => 'see LensID values below',
+    },
+    0x07 => { #8
+        Name => 'LensFStops',
+        ValueConv => '$val / 12',
+        ValueConvInv => '$val * 12',
+        PrintConv => 'sprintf("%.2f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x08 => { #8/9
+        Name => 'MinFocalLength',
+        %nikonFocalConversions,
+    },
+    0x09 => { #8/9
+        Name => 'MaxFocalLength',
+        %nikonFocalConversions,
+    },
+    0x0a => { #8
+        Name => 'MaxApertureAtMinFocal',
+        %nikonApertureConversions,
+    },
+    0x0b => { #8
+        Name => 'MaxApertureAtMaxFocal',
+        %nikonApertureConversions,
+    },
+    0x0c => 'MCUVersion', #8
+);
+
+# Nikon lens data (note: needs decrypting if LensDataVersion is 020x)
+%Image::ExifTool::Nikon::LensData01 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        Nikon encrypts the LensData information below if LensDataVersion is 0201 or
+        higher, but  the decryption algorithm is known so the information can be
+        extracted.  It isn't yet writable, however, because the encryption adds
+        complications which make writing more difficult.
+    },
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x00 => {
+        Name => 'LensDataVersion',
+        Format => 'string[4]',
+    },
+    0x04 => { #8
+        Name => 'ExitPupilPosition',
+        ValueConv => '$val ? 2048 / $val : $val',
+        ValueConvInv => '$val ? 2048 / $val : $val',
+        PrintConv => 'sprintf("%.1fmm",$val)',
+        PrintConvInv => '$val=~s/ ?mm$//; $val',
+    },
+    0x05 => { #8
+        Name => 'AFAperture',
+        %nikonApertureConversions,
+    },
+    0x08 => { #8
+        Name => 'FocusPosition',
+        PrintConv => 'sprintf("0x%02x", $val)',
+        PrintConvInv => '$val',
+    },
+    0x09 => { #8/9
+        # With older AF lenses this does not work... (ref 13)
+        # ie) AF Nikkor 50mm f/1.4 => 48 (0x30)
+        # AF Zoom-Nikkor 35-105mm f/3.5-4.5 => @35mm => 15 (0x0f), @105mm => 141 (0x8d)
+        Notes => 'this focus distance is approximate, and not very accurate for some lenses',
+        Name => 'FocusDistance',
+        ValueConv => '0.01 * 10**($val/40)', # in m
+        ValueConvInv => '$val>0 ? 40*log($val*100)/log(10) : 0',
+        PrintConv => '$val ? sprintf("%.2f m",$val) : "inf"',
+        PrintConvInv => '$val eq "inf" ? 0 : $val =~ s/\s*m$//, $val',
+    },
+    0x0a => { #8/9
+        Name => 'FocalLength',
+        Priority => 0,
+        %nikonFocalConversions,
+    },
+    0x0b => { #8
+        Name => 'LensIDNumber',
+        Notes => 'see LensID values below',
+    },
+    0x0c => { #8
+        Name => 'LensFStops',
+        ValueConv => '$val / 12',
+        ValueConvInv => '$val * 12',
+        PrintConv => 'sprintf("%.2f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x0d => { #8/9
+        Name => 'MinFocalLength',
+        %nikonFocalConversions,
+    },
+    0x0e => { #8/9
+        Name => 'MaxFocalLength',
+        %nikonFocalConversions,
+    },
+    0x0f => { #8
+        Name => 'MaxApertureAtMinFocal',
+        %nikonApertureConversions,
+    },
+    0x10 => { #8
+        Name => 'MaxApertureAtMaxFocal',
+        %nikonApertureConversions,
+    },
+    0x11 => 'MCUVersion', #8
+    0x12 => { #8
+        Name => 'EffectiveMaxAperture',
+        %nikonApertureConversions,
+    },
+);
+
+# information encrypted in some cameras - ref 18
+%Image::ExifTool::Nikon::ShotInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 0 ],
+    NOTES => q{
+        This information is encrypted for ShotInfoVersion 02xx, and some tags are
+        only valid for specific versions.
+    },
+    0x00 => {
+        Name => 'ShotInfoVersion',
+        RawConv => '$$self{ShotInfoVersion} = $val',
+        Format => 'string[4]',
+    },
+    0x66 => {
+        Name => 'VR_0x66',
+        Condition => '$$self{ShotInfoVersion} =~ /^(0204)$/',
+        Format => 'int8u',
+        Unknown => 1,
+        Notes => 'D2X, D2Xs (unverified)',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On (normal)',
+            2 => 'On (active)',
+        },
+    },
+    # 6a, 6e not correct for 0103 (D70), 0207 (D200)
+    0x6a => {
+        Name => 'ShutterCount',
+        Condition => '$$self{ShotInfoVersion} =~ /^(0204)$/',
+        Format => 'int32u',
+        Priority => 0,
+        Notes => 'D2X, D2Xs',
+    },
+    0x6e => {
+        Name => 'DeletedImageCount',
+        Condition => '$$self{ShotInfoVersion} =~ /^(0204)$/',
+        Format => 'int32u',
+        Priority => 0,
+        Notes => 'D2X, D2Xs',
+    },
+    0x75 => { #19
+        Name => 'VibrationReduction',
+        Condition => '$$self{ShotInfoVersion} =~ /^(0207)$/',
+        Format => 'int8u',
+        Notes => 'D200',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On (1)',
+            2 => 'On (2)',
+        },
+    },
+    0x82 => { # educated guess, needs verification
+        Name => 'VibrationReduction',
+        Condition => '$$self{ShotInfoVersion} =~ /^(0204)$/',
+        Format => 'int8u',
+        Notes => 'D2X, D2Xs',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    0x157 => { #19
+        Name => 'ShutterCount',
+        Condition => '$$self{ShotInfoVersion} =~ /^(0205)$/',
+        Format => 'undef[2]',
+        Priority => 0,
+        Notes => 'D50',
+        # treat as a 2-byte big-endian integer
+        ValueConv => 'unpack("n", $val)',
+        ValueConvInv => 'pack("n",$val)',
+    },
+    0x1ae => { #19
+        Name => 'VibrationReduction',
+        Condition => '$$self{ShotInfoVersion} =~ /^(0205)$/',
+        Format => 'int8u',
+        Notes => 'D50',
+        PrintHex => 1,
+        PrintConv => {
+            0x00 => 'n/a',
+            0x0c => 'Off',
+            0x0f => 'On',
+        },
+    },
+    0x24a => { #19
+        Name => 'ShutterCount',
+        Condition => '$$self{ShotInfoVersion} =~ /^(0208)$/',
+        Format => 'int32u',
+        Priority => 0,
+        Notes => 'D80',
+    },
+    0x24e => { #19
+        Name => 'VibrationReduction',
+        Condition => '$$self{ShotInfoVersion} =~ /^(0208)$/',
+        Notes => 'D80',
+        PrintHex => 1,
+        PrintConv => {
+            0x00 => 'Off, Horizontal',
+            0x01 => 'Off, Rotated 270 CW',
+            0x02 => 'Off, Rotated 90 CW',
+            0x03 => 'Off, Rotated 180',
+            0x18 => 'On, Horizontal',
+            0x19 => 'On, Rotated 270 CW',
+            0x1a => 'On, Rotated 90 CW',
+            0x1b => 'On, Rotated 180',
+        },
+    },
+    # note: DecryptLen currently set to 0x24e
+);
+
+# Multi exposure / image overlay information (ref PH)
+%Image::ExifTool::Nikon::MultiExposure = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    FORMAT => 'int32u',
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0 => {
+        Name => 'MultiExposureVersion',
+        Format => 'string[4]',
+    },
+    1 => {
+        Name => 'MultiExposureMode',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Multiple Exposure',
+            2 => 'Image Overlay',
+        },
+    },
+    2 => 'MultiExposureShots',
+    3 => {
+        Name => 'MultiExposureAutoGain',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+);
+
+# tags in Nikon QuickTime videos (PH - observations with Coolpix S3)
+# (note: very similar to information in Pentax videos)
+%Image::ExifTool::Nikon::MOV = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        This information is found in Nikon QT video images, and is very similar to
+        information found in Pentax MOV videos.
+    },
+    0x00 => {
+        Name => 'Make',
+        Format => 'string[5]',
+        PrintConv => 'ucfirst(lc($val))',
+    },
+    0x18 => {
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Format => 'string[8]',
+    },
+    0x26 => {
+        Name => 'ExposureTime',
+        Format => 'int32u',
+        ValueConv => '$val ? 10 / $val : 0',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    0x2a => {
+        Name => 'FNumber',
+        Format => 'int32u',
+        ValueConv => '$val * 0.1',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x32 => {
+        Name => 'ExposureCompensation',
+        Format => 'int32s',
+        ValueConv => '$val * 0.1',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x44 => {
+        Name => 'WhiteBalance',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Daylight',
+            2 => 'Shade',
+            3 => 'Fluorescent', #2
+            4 => 'Tungsten',
+            5 => 'Manual',
+        },
+    },
+    0x48 => {
+        Name => 'FocalLength',
+        Writable => 'int32u',
+        ValueConv => '$val * 0.1',
+        PrintConv => 'sprintf("%.1fmm",$val)',
+    },
+    0xaf => {
+        Name => 'Software',
+        Format => 'string[16]',
+    },
+    0xdf => { # (this is a guess ... could also be offset 0xdb)
+        Name => 'ISO',
+        Format => 'int16u',
+    },
+);
+
+
+# Nikon composite tags
+%Image::ExifTool::Nikon::Composite = (
+    GROUPS => { 2 => 'Camera' },
+    LensSpec => {
+        Description => 'Lens',
+        Require => {
+            0 => 'Nikon:Lens',
+            1 => 'Nikon:LensType',
+        },
+        ValueConv => '"$val[0] $val[1]"',
+        PrintConv => '"$prt[0] $prt[1]"',
+    },
+    LensID => {
+        SeparateTable => 'Nikon LensID',    # print values in a separate table
+        Require => {
+            0 => 'Nikon:LensIDNumber',
+            1 => 'LensFStops',
+            2 => 'MinFocalLength',
+            3 => 'MaxFocalLength',
+            4 => 'MaxApertureAtMinFocal',
+            5 => 'MaxApertureAtMaxFocal',
+            6 => 'MCUVersion',
+            7 => 'Nikon:LensType',
+        },
+        # construct lens ID string as per ref 11
+        ValueConv => 'uc(join(" ",(unpack("H*",pack("C*",@raw)) =~ /../g)))',
+        PrintConv => \%nikonLensIDs,
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::Nikon');
+
+
+#------------------------------------------------------------------------------
+# Clean up formatting of string values
+# Inputs: 0) string value
+# Returns: formatted string value
+# - removes trailing spaces and changes case to something more sensible
+sub FormatString($)
+{
+    my $str = shift;
+    # limit string length (can be very long for some unknown tags)
+    if (length($str) > 60) {
+        $str = substr($str,0,55) . "[...]";
+    } else {
+        $str =~ s/\s+$//;   # remove trailing white space and null terminator
+        # Don't change case of hyphenated strings (like AF-S) or non-words (no vowels)
+        unless ($str =~ /-/ or $str !~ /[AEIOUY]/) {
+            # change all letters but the first to lower case
+            $str =~ s/([A-Z]{1})([A-Z]+)/$1\L$2/g;
+        }
+    }
+    return $str;
+}
+
+#------------------------------------------------------------------------------
+# decoding tables from ref 4
+my @xlat = (
+  [ 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
+    0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
+    0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
+    0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
+    0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
+    0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
+    0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
+    0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
+    0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
+    0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
+    0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
+    0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
+    0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
+    0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
+    0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
+    0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 ],
+  [ 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
+    0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
+    0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
+    0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
+    0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
+    0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
+    0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
+    0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
+    0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
+    0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
+    0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
+    0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
+    0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
+    0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
+    0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
+    0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f ]
+);
+
+# decrypt Nikon data block (ref 4)
+# Inputs: 0) reference to data block, 1) serial number key, 2) shutter count key
+#         4) optional start offset (default 0)
+#         5) optional number of bytes to decode (default to the end of the data)
+# Returns: Decrypted data block
+sub Decrypt($$$;$$)
+{
+    my ($dataPt, $serial, $count, $start, $len) = @_;
+    $start or $start = 0;
+    my $end = $len ? $start + $len : length($$dataPt);
+    my $i;
+    my $key = 0;
+    for ($i=0; $i<4; ++$i) {
+        $key ^= ($count >> ($i*8)) & 0xff;
+    }
+    my $ci = $xlat[0][$serial & 0xff];
+    my $cj = $xlat[1][$key];
+    my $ck = 0x60;
+    my @data = unpack('C*',$$dataPt);
+    for ($i=$start; $i<$end; ++$i) {
+        $cj = ($cj + $ci * $ck) & 0xff;
+        $ck = ($ck + 1) & 0xff;
+        $data[$i] ^= $cj;
+    }
+    return pack('C*',@data);
+}
+
+#------------------------------------------------------------------------------
+# process Nikon Encrypted data block
+# Inputs: 0) ExifTool object reference, 1) reference to directory information
+#         2) pointer to tag table
+# Returns: 1 on success
+sub ProcessNikonEncrypted($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    # get the encrypted directory data
+    my $buff = substr(${$$dirInfo{DataPt}}, $$dirInfo{DirStart}, $$dirInfo{DirLen});
+    # save it until we have enough information to decrypt it later
+    push @{$exifTool->{NikonInfo}->{Encrypted}}, [ $tagTablePtr, $buff, $$dirInfo{TagInfo}];
+    if ($exifTool->Options('Verbose')) {
+        my $indent = substr($exifTool->{INDENT}, 0, -2);
+        $exifTool->VPrint(0, $indent, "[$dirInfo->{TagInfo}->{Name} directory to be decrypted later]\n");
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# process Nikon Capture Offsets IFD (ref PH)
+# Inputs: 0) ExifTool object reference, 1) reference to directory information
+#         2) pointer to tag table
+# Returns: 1 on success
+# Notes: This isn't a normal IFD, but is close...
+sub ProcessNikonCaptureOffsets($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart};
+    my $dirLen = $$dirInfo{DirLen};
+    my $success = 0;
+    return 0 unless $dirLen > 2;
+    my $count = Get16u($dataPt, $dirStart);
+    return 0 unless $count and $count * 12 + 2 <= $dirLen;
+    if ($exifTool->Options('Verbose')) {
+        $exifTool->VerboseDir('NikonCaptureOffsets', $count);
+    }
+    my $index;
+    for ($index=0; $index<$count; ++$index) {
+        my $pos = $dirStart + 12 * $index + 2;
+        my $tagID = Get32u($dataPt, $pos);
+        my $value = Get32u($dataPt, $pos + 4);
+        $exifTool->HandleTag($tagTablePtr, $tagID, $value,
+            Index  => $index,
+            DataPt => $dataPt,
+            Start  => $pos,
+            Size   => 12,
+        ) and $success = 1;
+    }
+    return $success;
+}
+
+#------------------------------------------------------------------------------
+# Process Nikon Makernotes directory
+# Inputs: 0) ExifTool object reference
+#         1) Reference to directory information hash
+#         2) Pointer to tag table for this directory
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+sub ProcessNikon($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $verbose = $exifTool->Options('Verbose');
+    my $nikonInfo = $exifTool->{NikonInfo} = { };
+    my @encrypted;  # list to save encrypted data
+    $$nikonInfo{Encrypted} = \@encrypted;
+    my $rtnVal = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
+    # process any encrypted information we found
+    my $encryptedDir;
+    if (@encrypted) {
+        my $serial = $exifTool->{NikonInfo}->{SerialNumber} || 0;
+        my $count = $exifTool->{NikonInfo}->{ShutterCount};
+        unless (defined $count) {
+            $exifTool->Warn("Can't decrypt Nikon information (no ShutterCount key)");
+            undef @encrypted;
+        }
+        foreach $encryptedDir (@encrypted) {
+            my ($subTablePtr, $data, $tagInfo) = @$encryptedDir;
+            my ($start, $len, $offset);
+            if ($tagInfo and $$tagInfo{SubDirectory}) {
+                $start = $tagInfo->{SubDirectory}->{DecryptStart};
+                # may decrypt only part of the information to save time
+                if ($verbose < 3 and $exifTool->Options('Unknown') < 2) {
+                    $len = $tagInfo->{SubDirectory}->{DecryptLen};
+                }
+                $offset = $tagInfo->{SubDirectory}->{DirOffset};
+            }
+            $start or $start = 0;
+            if (defined $offset) {
+                # offset, if specified, is releative to start of encrypted data
+                $offset += $start;
+            } else {
+                $offset = 0;
+            }
+            my $maxLen = length($data) - $start;
+            if ($len) {
+                $len = $maxLen if $len > $maxLen;
+            } else {
+                $len = $maxLen;
+            }
+            # use fixed serial numbers if no good serial number found
+            unless ($serial =~ /^\d+$/) {
+                if ($exifTool->{CameraModel} =~ /\bD50$/) {
+                    $serial = 0x22; # D50 (ref 8)
+                } else {
+                    $serial = 0x60; # D200 (ref 10), D40X (ref PH)
+                }
+            }
+            $data = Decrypt(\$data, $serial, $count, $start, $len);
+            my %subdirInfo = (
+                DataPt   => \$data,
+                DirStart => $offset,
+                DirLen   => length($data) - $offset,
+            );
+            if ($verbose > 2) {
+                $exifTool->VerboseDir("Decrypted $$tagInfo{Name}");
+                my %parms = (
+                    Prefix => $exifTool->{INDENT},
+                    Out => $exifTool->Options('TextOut'),
+                );
+                $parms{MaxLen} = 96 unless $verbose > 3;
+                Image::ExifTool::HexDump(\$data, undef, %parms);
+            }
+            # process the decrypted information
+            $exifTool->ProcessBinaryData(\%subdirInfo, $subTablePtr);
+        }
+    }
+    delete $exifTool->{NikonInfo};
+    return $rtnVal;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Nikon - Nikon EXIF maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+Nikon maker notes in EXIF information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html>
+
+=item L<http://www.cybercom.net/~dcoffin/dcraw/>
+
+=item L<http://members.aol.com/khancock/pilot/nbuddy/>
+
+=item L<http://www.rottmerhusen.com/objektives/lensid/thirdparty.html>
+
+=item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_nikon.htm>
+
+=item L<http://www.wohlberg.net/public/software/photo/nstiffexif/>
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Joseph Heled, Thomas Walter, Brian Ristuccia, Danek Duvall, Tom
+Christiansen, Robert Rottmerhusen, Werner Kober, Roger Larsson and Jens
+Duttke for their help figuring out some Nikon tags, and Bruce Stevens for
+his additions to the LensID list.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Nikon Tags>,
+L<Image::ExifTool::TagNames/NikonCapture Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/NikonCapture.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/NikonCapture.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/NikonCapture.pm	(revision 20131)
@@ -0,0 +1,677 @@
+#------------------------------------------------------------------------------
+# File:         NikonCapture.pm
+#
+# Description:  Read/write Nikon Capture information
+#
+# Revisions:    11/08/2005 - P. Harvey Created
+#
+# References:   1) http://www.cybercom.net/~dcoffin/dcraw/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::NikonCapture;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.02';
+
+# common print conversions
+my %offOn = ( 0 => 'Off', 1 => 'On' );
+my %noYes = ( 0 => 'No', 1 => 'Yes' );
+my %unsharpColor = (
+    0 => 'RGB',
+    1 => 'Red',
+    2 => 'Green',
+    3 => 'Blue',
+    4 => 'Yellow',
+    5 => 'Magenta',
+    6 => 'Cyan',
+);
+
+# Nikon Capture data (ref PH)
+%Image::ExifTool::NikonCapture::Main = (
+    PROCESS_PROC => \&ProcessNikonCapture,
+    WRITE_PROC => \&WriteNikonCapture,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    NOTES => q{
+        This information is written by the Nikon Capture software in tag 0x0e01 of
+        the maker notes of NEF images.
+    },
+    0x008ae85e => {
+        Name => 'LCHEditor',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0x0c89224b => {
+        Name => 'ColorAberrationControl',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0x2175eb78 => {
+        Name => 'D-LightingHQ',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0x2fc08431 => {
+        Name => 'StraightenAngle',
+        Writable => 'double',
+    },
+    0x374233e0 => {
+        Name => 'CropData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCapture::CropData',
+        },
+    },
+    0x3cfc73c6 => {
+        Name => 'RedEyeData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCapture::RedEyeData',
+        },
+    },
+    0x5f0e7d23 => {
+        Name => 'ColorBooster',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0x6a6e36b6 => {
+        Name => 'D-LightingHQSelected',
+        Writable => 'int8u',
+        PrintConv => \%noYes,
+    },
+    0x753dcbc0 => {
+        Name => 'NoiseReduction',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0x76a43200 => {
+        Name => 'UnsharpMask',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0x76a43201 => {
+        Name => 'Curves',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0x76a43202 => {
+        Name => 'ColorBalanceAdj',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0x76a43203 => {
+        Name => 'AdvancedRaw',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0x76a43204 => {
+        Name => 'WhiteBalanceAdj',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0x76a43205 => {
+        Name => 'VignetteControl',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0x76a43206 => {
+        Name => 'FlipHorizontal',
+        Writable => 'int8u',
+        PrintConv => \%noYes,
+    },
+    0x76a43207 => { # rotation angle in degrees
+        Name => 'Rotation',
+        Writable => 'int16u',
+    },
+    0x84589434 => {
+        Name => 'BrightnessData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCapture::Brightness',
+        },
+    },
+    0x890ff591 => {
+        Name => 'D-LightingHQData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCapture::DLightingHQ',
+        },
+    },
+    0x926f13e0 => {
+        Name => 'NoiseReductionData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCapture::NoiseReduction',
+        },
+    },
+    0x9ef5f6e0 => {
+        Name => 'IPTCData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::IPTC::Main',
+        },
+    },
+    0xab5eca5e => {
+        Name => 'PhotoEffects',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0xac6bd5c0 => {
+        Name => 'VignetteControlIntensity',
+        Writable => 'int16s',
+    },
+    0xb0384e1e => {
+        Name => 'PhotoEffectsData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCapture::PhotoEffects',
+        },
+    },
+    0xb999a36f => {
+        Name => 'ColorBoostData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCapture::ColorBoost',
+        },
+    },
+    0xbf3c6c20 => {
+        Name => 'WBAdjData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCapture::WBAdjData',
+        },
+    },
+    0xce5554aa => {
+        Name => 'D-LightingHS',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+    0xe37b4337 => {
+        Name => 'D-LightingHSData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCapture::DLightingHS',
+        },
+    },
+    0xe42b5161 => {
+        Name => 'UnsharpData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCapture::UnsharpData',
+        },
+    },
+    0xfe443a45 => {
+        Name => 'ImageDustOff',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
+);
+
+%Image::ExifTool::NikonCapture::UnsharpData = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0 => 'UnsharpCount',
+    19 => { Name => 'Unsharp1Color', Format => 'int16u', PrintConv => \%unsharpColor },
+    23 => { Name => 'Unsharp1Intensity', Format => 'int16u' },
+    25 => { Name => 'Unsharp1HaloWidth', Format => 'int16u' },
+    27 => 'Unsharp1Threshold',
+    46 => { Name => 'Unsharp2Color', Format => 'int16u', PrintConv => \%unsharpColor },
+    50 => { Name => 'Unsharp2Intensity', Format => 'int16u' },
+    52 => { Name => 'Unsharp2HaloWidth', Format => 'int16u' },
+    54 => 'Unsharp2Threshold',
+    73 => { Name => 'Unsharp3Color', Format => 'int16u', PrintConv => \%unsharpColor },
+    77 => { Name => 'Unsharp3Intensity', Format => 'int16u' },
+    79 => { Name => 'Unsharp3HaloWidth', Format => 'int16u' },
+    81 => 'Unsharp3Threshold',
+    100 => { Name => 'Unsharp4Color', Format => 'int16u', PrintConv => \%unsharpColor },
+    104 => { Name => 'Unsharp4Intensity', Format => 'int16u' },
+    106 => { Name => 'Unsharp4HaloWidth', Format => 'int16u' },
+    108 => 'Unsharp4Threshold',
+    # there could be more, but I grow bored of this... :P
+);
+
+%Image::ExifTool::NikonCapture::DLightingHS = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0 => 'D-LightingHSAdjustment',
+    1 => 'D-LightingHSColorBoost',
+);
+
+%Image::ExifTool::NikonCapture::DLightingHQ = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0 => 'D-LightingHSShadow',
+    1 => 'D-LightingHSHighlight',
+    2 => 'D-LightingHSColorBoost',
+);
+
+%Image::ExifTool::NikonCapture::ColorBoost = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0 => {
+        Name => 'ColorBoostType',
+        PrintConv => {
+            0 => 'Nature',
+            1 => 'People',
+        },
+    },
+    1 => {
+        Name => 'ColorBoostLevel',
+        Format => 'int32u',
+    },
+);
+
+%Image::ExifTool::NikonCapture::WBAdjData = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0x00 => {
+        Name => 'WBAdjRedBalance',
+        Format => 'double',
+    },
+    0x08 => {
+        Name => 'WBAdjBlueBalance',
+        Format => 'double',
+    },
+    0x10 => {
+        Name => 'WBAdjMode',
+        PrintConv => {
+            1 => 'Use Gray Point',
+            2 => 'Recorded Value',
+            3 => 'Use Temperature',
+            4 => 'Calculate Automatically'
+        },
+    },
+    0x15 => {
+        Name => 'WBAdjLighting',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Incandescent',
+            2 => 'Daylight',
+            3 => 'Standard Fluorescent',
+            4 => 'High Color Rendering Fluorescent',
+            5 => 'Flash',
+        },
+    },
+    0x18 => {
+        Name => 'WBAdjTemperature',
+        Format => 'int16u',
+    },
+);
+
+%Image::ExifTool::NikonCapture::PhotoEffects = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0 => {
+        Name => 'PhotoEffectsType',
+        PrintConv => {
+            0 => 'None',
+            1 => 'B&W',
+            2 => 'Sepia',
+            3 => 'Tinted',
+        },
+    },
+    4 => {
+        Name => 'PhotoEffectsRed',
+        Format => 'int16s',
+    },
+    6 => {
+        Name => 'PhotoEffectsGreen',
+        Format => 'int16s',
+    },
+    8 => {
+        Name => 'PhotoEffectsBlue',
+        Format => 'int16s',
+    },
+);
+
+%Image::ExifTool::NikonCapture::Brightness = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0 => {
+        Name => 'BrightnessAdj',
+        Format => 'double',
+        ValueConv => '$val * 50',
+        ValueConvInv => '$val / 50',
+    },
+    8 => {
+        Name => 'EnhanceDarkTones',
+        PrintConv => \%offOn,
+    },
+);
+
+%Image::ExifTool::NikonCapture::NoiseReduction = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    4 => {
+        Name => 'EdgeNoiseReduction',
+        PrintConv => \%offOn,
+    },
+    5 => {
+        Name => 'ColorMoireReduction',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'Medium',
+            3 => 'High',
+        },
+    },
+    9 => {
+        Name => 'NoiseReductionIntensity',
+        Format => 'int32u',
+    },
+    13 => {
+        Name => 'NoiseReductionSharpness',
+        Format => 'int32u',
+    },
+    17 => {
+        Name => 'NoiseReductionMethod',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Faster',
+            1 => 'Better Quality',
+        },
+    },
+);
+
+%Image::ExifTool::NikonCapture::CropData = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0x1e => {
+        Name => 'CropLeft',
+        Format => 'double',
+        ValueConv => '$val / 2',
+        ValueConvInv => '$val * 2',
+    },
+    0x26 => {
+        Name => 'CropTop',
+        Format => 'double',
+        ValueConv => '$val / 2',
+        ValueConvInv => '$val * 2',
+    },
+    0x2e => {
+        Name => 'CropRight',
+        Format => 'double',
+        ValueConv => '$val / 2',
+        ValueConvInv => '$val * 2',
+    },
+    0x36 => {
+        Name => 'CropBottom',
+        Format => 'double',
+        ValueConv => '$val / 2',
+        ValueConvInv => '$val * 2',
+    },
+    0x8e => {
+        Name => 'OutputWidthInches',
+        Format => 'double',
+    },
+    0x96 => {
+        Name => 'OutputHeightInches',
+        Format => 'double',
+    },
+    0x9e => {
+        Name => 'ScaledResolution',
+        Format => 'double',
+    },
+    0xae => {
+        Name => 'SourceResolution',
+        Format => 'double',
+        ValueConv => '$val / 2',
+        ValueConvInv => '$val * 2',
+    },
+    0xb6 => {
+        Name => 'OutputResolution',
+        Format => 'double',
+    },
+    0xbe => {
+        Name => 'CropOutputScale',
+        Format => 'double',
+    },
+    0xc6 => {
+        Name => 'OutputWidth',
+        Format => 'double',
+    },
+    0xce => {
+        Name => 'OutputHeight',
+        Format => 'double',
+    },
+    0xd6 => {
+        Name => 'OutputPixels',
+        Format => 'double',
+    },
+);
+
+%Image::ExifTool::NikonCapture::RedEyeData = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0 => {
+        Name => 'RedEyeCorrection',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Automatic',
+            2 => 'Click on Eyes',
+        },
+    },
+);
+
+#------------------------------------------------------------------------------
+# write Nikon Capture data (ref 1)
+# Inputs: 0) ExifTool object reference, 1) reference to directory information
+#         2) pointer to tag table
+# Returns: 1 on success
+sub WriteNikonCapture($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    $exifTool or return 1;    # allow dummy access to autoload this package
+
+    # no need to edit this information unless necessary
+    unless ($exifTool->{EDIT_DIRS}->{MakerNotes} or $exifTool->{EDIT_DIRS}->{IPTC}) {
+        return undef;
+    }
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart};
+    my $dirLen = $$dirInfo{DirLen};
+    my $dirEnd = $dirStart + $dirLen;
+    if ($dirLen < 22) {
+        $exifTool->Warn('Short Nikon Capture Data',1);
+        return undef;
+    }
+    # make sure the capture data is properly contained
+    SetByteOrder('II');
+    my $tagID = Get32u($dataPt, $dirStart);
+    my $size = Get32u($dataPt, $dirStart + 18);
+    unless ($tagID == 0x7a86a940 and $size + 18 == $dirLen) {
+        $exifTool->Warn('Unrecognized Nikon Capture Data header');
+        return undef;
+    }
+    my $outBuff = '';
+    my $pos;
+    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+
+    # loop through all entries in the Nikon Capture data
+    for ($pos=$dirStart+22; $pos+22<$dirEnd; $pos+=22+$size) {
+        $tagID = Get32u($dataPt, $pos);
+        $size = Get32u($dataPt, $pos + 18) - 4;
+        last if $size < 0 or $pos + 22 + $size > $dirEnd;
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+        if ($tagInfo) {
+            my $newVal;
+            if ($$tagInfo{SubDirectory}) {
+                # rewrite the subdirectory
+                my %subdirInfo = (
+                    DataPt => $dataPt,
+                    DirStart => $pos + 22,
+                    DirLen => $size,
+                );
+                my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                # ignore minor errors in IPTC since there is typically trailing garbage
+                my $oldSetting = $exifTool->Options('IgnoreMinorErrors');
+                $$tagInfo{Name} =~ /IPTC/ and $exifTool->Options(IgnoreMinorErrors => 1);
+                # rewrite the directory
+                $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+                # restore our original options
+                $exifTool->Options(IgnoreMinorErrors => $oldSetting);
+            } elsif ($$newTags{$tagID}) {
+                # get new value for this tag if we are writing it
+                my $format = $$tagInfo{Format} || $$tagInfo{Writable};
+                my $oldVal = ReadValue($dataPt,$pos+22,$format,1,$size);
+                my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+                if (Image::ExifTool::IsOverwriting($newValueHash, $oldVal)) {
+                    my $val = $exifTool->GetNewValues($tagInfo);
+                    $newVal = WriteValue($val, $$tagInfo{Writable}) if defined $val;
+                    if (defined $newVal and length $newVal) {
+                        ++$exifTool->{CHANGED};
+                    } else {
+                        undef $newVal;
+                        $exifTool->Warn("Can't delete $$tagInfo{Name}");
+                    }
+                }
+            }
+            if (defined $newVal) {
+                next unless length $newVal; # don't write zero length information
+                # write the new value
+                $outBuff .= substr($$dataPt, $pos, 18);
+                $outBuff .= Set32u(length($newVal) + 4);
+                $outBuff .= $newVal;
+                next;
+            }
+        }
+        # rewrite the existing information
+        $outBuff .= substr($$dataPt, $pos, 22 + $size);
+    }
+    unless ($pos == $dirEnd) {
+        $exifTool->Warn('Nikon Capture Data improperly terminated',1);
+        return undef;
+    }
+    # add the header and return the new directory
+    return substr($$dataPt, $dirStart, 18) .
+           Set32u(length($outBuff) + 4) .
+           $outBuff;
+}
+
+#------------------------------------------------------------------------------
+# process Nikon Capture data (ref 1)
+# Inputs: 0) ExifTool object reference, 1) reference to directory information
+#         2) pointer to tag table
+# Returns: 1 on success
+sub ProcessNikonCapture($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart};
+    my $dirLen = $$dirInfo{DirLen};
+    my $dirEnd = $dirStart + $dirLen;
+    my $verbose = $exifTool->Options('Verbose');
+    my $success = 0;
+    SetByteOrder('II');
+    $verbose and $exifTool->VerboseDir('NikonCapture', 0, $dirLen);
+    my $pos;
+    for ($pos=$dirStart+22; $pos+22<$dirEnd; ) {
+        my $tagID = Get32u($dataPt, $pos);
+        my $size = Get32u($dataPt, $pos + 18) - 4;
+        $pos += 22;
+        last if $size < 0 or $pos + $size > $dirEnd;
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+        if ($tagInfo or $verbose) {
+            my ($format, $value);
+            # (note that Writable will be 0 for Unknown tags)
+            $tagInfo and $format = ($$tagInfo{Format} || $$tagInfo{Writable});
+            # generate a reasonable default format type for short values
+            if (not $format and ($size == 1 or $size == 2 or $size == 4)) {
+                $format = 'int' . ($size * 8) . 'u';
+            }
+            if ($format) {
+                $value = ReadValue($dataPt,$pos,$format,1,$size);
+            } elsif ($size == 1) {
+                $value = substr($$dataPt, $pos, $size);
+            }
+            $exifTool->HandleTag($tagTablePtr, $tagID, $value,
+                DataPt => $dataPt,
+                Start  => $pos,
+                Size   => $size,
+            ) and $success = 1;
+        }
+        $pos += $size;
+    }
+    return $success;
+}
+
+1;  # end
+
+=head1 NAME
+
+Image::ExifTool::NikonCapture - Read/write Nikon Capture information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains routines to read and write Nikon Capture information in
+the maker notes of NEF images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.cybercom.net/~dcoffin/dcraw/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/NikonCapture Tags>,
+L<Image::ExifTool::TagNames/Nikon Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Olympus.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Olympus.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Olympus.pm	(revision 20131)
@@ -0,0 +1,2404 @@
+#------------------------------------------------------------------------------
+# File:         Olympus.pm
+#
+# Description:  Olympus/Epson EXIF maker notes tags
+#
+# Revisions:    12/09/2003 - P. Harvey Created
+#               11/11/2004 - P. Harvey Added Epson support
+#
+# References:   1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html
+#               2) http://www.cybercom.net/~dcoffin/dcraw/
+#               3) http://www.ozhiker.com/electronics/pjmt/jpeg_info/olympus_mn.html
+#               4) Markku Hnninen private communication (tests with E-1)
+#               5) Rmi Guyomarch from http://forums.dpreview.com/forums/read.asp?forum=1022&message=12790396
+#               6) Frank Ledwon private communication (tests with E/C-series cameras)
+#               7) Michael Meissner private communication
+#               8) Shingo Noguchi, PhotoXP (http://www.daifukuya.com/photoxp/)
+#               9) Mark Dapoz private communication
+#              10) Lilo Huang private communication (E-330)
+#              11) http://olypedia.de/Olympus_Makernotes
+#              12) Ioannis Panagiotopoulos private communication (E-510)
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Olympus;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::Exif;
+use Image::ExifTool::APP12;
+
+$VERSION = '1.40';
+
+my %offOn = ( 0 => 'Off', 1 => 'On' );
+
+%Image::ExifTool::Olympus::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+#
+# Tags 0x0000 through 0x0103 are the same as Konica/Minolta cameras (ref 3)
+#
+    0x0000 => {
+        Name => 'MakerNoteVersion',
+        Writable => 'undef',
+    },
+    0x0001 => {
+        Name => 'MinoltaCameraSettingsOld',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Minolta::CameraSettings',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    0x0003 => {
+        Name => 'MinoltaCameraSettings',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Minolta::CameraSettings',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    0x0040 => {
+        Name => 'CompressedImageSize',
+        Writable => 'int32u',
+    },
+    0x0081 => {
+        Name => 'PreviewImageData',
+        Binary => 1,
+        Writable => 0,
+    },
+    0x0088 => {
+        Name => 'PreviewImageStart',
+        Flags => 'IsOffset',
+        OffsetPair => 0x0089, # point to associated byte count
+        DataTag => 'PreviewImage',
+        Writable => 0,
+        Protected => 2,
+    },
+    0x0089 => {
+        Name => 'PreviewImageLength',
+        OffsetPair => 0x0088, # point to associated offset
+        DataTag => 'PreviewImage',
+        Writable => 0,
+        Protected => 2,
+    },
+    0x0100 => {
+        Name => 'ThumbnailImage',
+        Writable => 'undef',
+        WriteCheck => '$self->CheckImage(\$val)',
+        Binary => 1,
+    },
+    0x0101 => {
+        Name => 'ColorMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Natural color',
+            1 => 'Black&white',
+            2 => 'Vivid color',
+            3 => 'Solarization',
+            4 => 'Adobe RGB',
+        },
+    },
+    0x0102 => {
+        Name => 'MinoltaQuality',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Raw',
+            1 => 'Superfine',
+            2 => 'Fine',
+            3 => 'Normal',
+            4 => 'Economy',
+            5 => 'Extra fine',
+        },
+    },
+    # (0x0103 is the same as 0x0102 above)
+    0x0103 => {
+        Name => 'MinoltaQuality',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Raw',
+            1 => 'Superfine',
+            2 => 'Fine',
+            3 => 'Normal',
+            4 => 'Economy',
+            5 => 'Extra fine',
+        },
+    },
+    0x0104 => { #11
+        Name => 'BodyFirmwareVersion',
+        Writable => 'string',
+    },
+#
+# end Konica/Minolta tags
+#
+    0x0200 => {
+        Name => 'SpecialMode',
+        Notes => q{
+            3 numbers: 1. Shooting mode: 0=Normal, 2=Fast, 3=Panorama;
+            2. Sequence Number; 3. Panorama Direction: 1=Left-Right,
+            2=Right-Left, 3=Bottom-Top, 4=Top-Bottom
+        },
+        Writable => 'int32u',
+        Count => 3,
+        PrintConv => sub { #3
+            my $val = shift;
+            my @v = split ' ', $val;
+            return $val unless @v >= 3;
+            my @v0 = ('Normal','Unknown (1)','Fast','Panorama');
+            my @v2 = ('(none)','Left to Right','Right to Left','Bottom to Top','Top to Bottom');
+            $val = $v0[$v[0]] || "Unknown ($v[0])";
+            $val .= ", Sequence: $v[1]";
+            $val .= ', Panorama: ' . ($v2[$v[2]] || "Unknown ($v[2])");
+            return $val;
+        },
+    },
+    0x0201 => {
+        Name => 'Quality',
+        Writable => 'int16u',
+        Notes => q{
+            Quality values are decoded based on the CameraType tag. All types
+            represent SQ, HQ and SHQ as sequential integers, but in general
+            SX-type cameras start with a value of 0 for SQ while others start
+            with 1
+        },
+        # These values are different for different camera types
+        # (can't have Condition based on CameraType because it isn't known
+        #  when this tag is extracted)
+        PrintConv => sub {
+            my ($val, $self) = @_;
+            my %t1 = ( # all SX camera types except SX151
+                0 => 'SQ (Low)',
+                1 => 'HQ (Normal)',
+                2 => 'SHQ (Fine)',
+                6 => 'RAW', #PH - C5050WZ
+            );
+            my %t2 = ( # all other types
+                1 => 'SQ (Low)',
+                2 => 'HQ (Normal)',
+                3 => 'SHQ (Fine)',
+                4 => 'RAW',
+                5 => 'Medium-Fine', #PH
+                6 => 'Small-Fine', #PH
+                33 => 'Uncompressed', #PH - C2100Z
+            );
+            my $conv = $self->{CameraType} =~ /^SX(?!151\b)/ ? \%t1 : \%t2;
+            return $$conv{$val} ? $$conv{$val} : "Unknown ($val)";
+        },
+        # (no PrintConvInv because we don't know CameraType at write time)
+    },
+    0x0202 => {
+        Name => 'Macro',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'Super Macro', #6
+        },
+    },
+    0x0203 => { #6
+        Name => 'BWMode',
+        Description => 'Black & White Mode',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x0204 => {
+        Name => 'DigitalZoom',
+        Writable => 'rational64u',
+        PrintConv => '$val=~/\./ or $val.=".0"; $val',
+        PrintConvInv => '$val',
+    },
+    0x0205 => { #6
+        Name => 'FocalPlaneDiagonal',
+        Writable => 'rational64u',
+        PrintConv => '"$val mm"',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
+    },
+    0x0206 => { #6
+        Name => 'LensDistortionParams',
+        Writable => 'int16s',
+        Count => 6,
+    },
+    0x0207 => { #PH (was incorrectly FirmwareVersion, ref 1,3)
+        Name => 'CameraType',
+        Writable => 'string',
+        DataMember => 'CameraType',
+        RawConv => '$self->{CameraType} = $val',
+    },
+    0x0208 => {
+        Name => 'TextInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::TextInfo',
+        },
+    },
+    0x0209 => {
+        Name => 'CameraID',
+        Format => 'string', # this really should have been a string
+    },
+    0x020b => { #PH
+        Name => 'EpsonImageWidth',
+        Writable => 'int16u',
+    },
+    0x020c => { #PH
+        Name => 'EpsonImageHeight',
+        Writable => 'int16u',
+    },
+    0x020d => { #PH
+        Name => 'EpsonSoftware',
+        Writable => 'string',
+    },
+    0x0280 => { #PH
+        %Image::ExifTool::previewImageTagInfo,
+        Notes => 'found in ERF and JPG images from some Epson models',
+        Format => 'undef',
+        Writable => 'int8u',
+    },
+    0x0300 => { #6
+        Name => 'PreCaptureFrames',
+        Writable => 'int16u',
+    },
+    0x0301 => { #11
+        Name => 'WhiteBoard',
+        Writable => 'int16u',
+    },
+    0x0302 => { #6
+        Name => 'OneTouchWB',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On (Preset)',
+        },
+    },
+    0x0303 => { #11
+        Name => 'WhiteBalanceBracket',
+        Writable => 'int16u',
+    },
+    0x0304 => { #11
+        Name => 'WhiteBalanceBias',
+        Writable => 'int16u',
+    },
+   # 0x0305 => 'PrintMaching', ? #11
+    0x0403 => { #11
+        Name => 'SceneMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Standard',
+            2 => 'Auto',
+            4 => 'Portrait',
+            5 => 'Landscape+Portrait',
+            6 => 'Landscape',
+            7 => 'Night Scene',
+            8 => 'Night+Portrait',
+            9 => 'Sport',
+            10 => 'Self Portrait',
+            11 => 'Indoor',
+            12 => 'Beach&Snow',
+            13 => 'Beach',
+            14 => 'Snow',
+            15 => 'Self Portrait+Self Timer',
+            16 => 'Sunset',
+            17 => 'Cuisine',
+            18 => 'Documents',
+            19 => 'Candle',
+            20 => 'Fireworks',
+            21 => 'Available Light',
+            22 => 'Vivid',
+            23 => 'Underwater Wide1',
+            24 => 'Underwater Macro',
+            25 => 'Museum',
+            26 => 'Behind Glass',
+            27 => 'Auction',
+            28 => 'Shoot&Select1',
+            29 => 'Shoot&Select2',
+            30 => 'Underwater Wide2',
+            31 => 'Digital Image Stabilization',
+            32 => 'Face Portrait',
+            33 => 'Pet',
+        },
+    },
+    0x0404 => { #PH (D595Z, C7070WZ)
+        Name => 'SerialNumber',
+        Writable => 'string',
+    },
+    0x0405 => { #11
+        Name => 'Firmware',
+        Writable => 'string',
+    },
+    0x0e00 => {
+        Name => 'PrintIM',
+        Description => 'Print Image Matching',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+    0x0f00 => {
+        Name => 'DataDump',
+        Writable => 0,
+        Binary => 1,
+    },
+    0x0f01 => { #6
+        Name => 'DataDump2',
+        Writable => 0,
+        Binary => 1,
+    },
+    0x1000 => { #6
+        Name => 'ShutterSpeedValue',
+        Writable => 'rational64s',
+        Priority => 0,
+        ValueConv => 'abs($val)<100 ? 1/(2**$val) : 0',
+        ValueConvInv => '$val>0 ? -log($val)/log(2) : -100',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x1001 => { #6
+        Name => 'ISOValue',
+        Writable => 'rational64s',
+        Priority => 0,
+        ValueConv => '100 * 2 ** ($val - 5)',
+        ValueConvInv => '$val>0 ? log($val/100)/log(2)+5 : 0',
+        PrintConv => 'int($val * 100 + 0.5) / 100',
+        PrintConvInv => '$val',
+    },
+    0x1002 => { #6
+        Name => 'ApertureValue',
+        Writable => 'rational64s',
+        Priority => 0,
+        ValueConv => '2 ** ($val / 2)',
+        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x1003 => { #6
+        Name => 'BrightnessValue',
+        Writable => 'rational64s',
+        Priority => 0,
+    },
+    0x1004 => { #3
+        Name => 'FlashMode',
+        Writable => 'int16u',
+        PrintConv => {
+            2 => 'On', #PH
+            3 => 'Off', #PH
+        },
+    },
+    0x1005 => { #6
+        Name => 'FlashDevice',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Internal',
+            4 => 'External',
+            5 => 'Internal + External',
+        },
+    },
+    0x1006 => { #6
+        Name =>'ExposureCompensation',
+        Writable => 'rational64s',
+    },
+    0x1007 => { #6
+        Name => 'SensorTemperature',
+        Writable => 'int16s',
+    },
+    0x1008 => { #6
+        Name => 'LensTemperature',
+        Writable => 'int16s',
+    },
+    0x1009 => { #11
+        Name => 'LightCondition',
+        Writable => 'int16u',
+    },
+    0x100a => { #11
+        Name => 'FocusRange',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Macro',
+        },
+    },
+    0x100b => { #6
+        Name => 'FocusMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Manual',
+        },
+    },
+    0x100c => { #6
+        Name => 'ManualFocusDistance',
+        Writable => 'rational64u',
+        PrintConv => '"$val mm"', #11
+        PrintConvInv => '$val=~s/\s*mm$//; $val',
+    },
+    0x100d => { #6
+        Name => 'ZoomStepCount',
+        Writable => 'int16u',
+    },
+    0x100e => { #6
+        Name => 'FocusStepCount',
+        Writable => 'int16u',
+    },
+    0x100f => { #6
+        Name => 'Sharpness',
+        Writable => 'int16u',
+        Priority => 0,
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Hard',
+            2 => 'Soft',
+        },
+    },
+    0x1010 => { #6
+        Name => 'FlashChargeLevel',
+        Writable => 'int16u',
+    },
+    0x1011 => { #3
+        Name => 'ColorMatrix',
+        Writable => 'int16u',
+        Format => 'int16s',
+        Count => 9,
+    },
+    0x1012 => { #3
+        Name => 'BlackLevel',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x1013 => { #11
+        Name => 'ColorTemperatureBG',
+        Writable => 'int16u',
+        Unknown => 1, # (doesn't look like a temperature)
+    },
+    0x1014 => { #11
+        Name => 'ColorTemperatureRG',
+        Writable => 'int16u',
+        Unknown => 1, # (doesn't look like a temperature)
+    },
+    0x1015 => { #6
+        Name => 'WBMode',
+        Writable => 'int16u',
+        Count => 2,
+        PrintConv => {
+            '1'   => 'Auto',
+            '1 0' => 'Auto',
+            '1 2' => 'Auto (2)',
+            '1 4' => 'Auto (4)',
+            '2 2' => '3000 Kelvin',
+            '2 3' => '3700 Kelvin',
+            '2 4' => '4000 Kelvin',
+            '2 5' => '4500 Kelvin',
+            '2 6' => '5500 Kelvin',
+            '2 7' => '6500 Kelvin',
+            '2 8' => '7500 Kelvin',
+            '3 0' => 'One-touch',
+        },
+    },
+    0x1017 => { #2
+        Name => 'RedBalance',
+        Writable => 'int16u',
+        Count => 2,
+        ValueConv => '$val=~s/ .*//; $val / 256',
+        ValueConvInv => '$val*=256;"$val 64"',
+    },
+    0x1018 => { #2
+        Name => 'BlueBalance',
+        Writable => 'int16u',
+        Count => 2,
+        ValueConv => '$val=~s/ .*//; $val / 256',
+        ValueConvInv => '$val*=256;"$val 64"',
+    },
+    0x1019 => { #11
+        Name => 'ColorMatrixNumber',
+        Writable => 'int16u',
+    },
+    # 0x101a is same as CameraID ("OLYMPUS DIGITAL CAMERA") for C2500L - PH
+    0x101a => { #3
+        Name => 'SerialNumber',
+        Writable => 'string',
+    },
+    0x101b => { #11
+        Name => 'ExternalFlashAE1_0',
+        Writable => 'int32u',
+        Unknown => 1, # (what are these?)
+    },
+    0x101c => { #11
+        Name => 'ExternalFlashAE2_0',
+        Writable => 'int32u',
+        Unknown => 1,
+    },
+    0x101d => { #11
+        Name => 'InternalFlashAE1_0',
+        Writable => 'int32u',
+        Unknown => 1,
+    },
+    0x101e => { #11
+        Name => 'InternalFlashAE2_0',
+        Writable => 'int32u',
+        Unknown => 1,
+    },
+    0x101f => { #11
+        Name => 'ExternalFlashAE1',
+        Writable => 'int32u',
+        Unknown => 1,
+    },
+    0x1020 => { #11
+        Name => 'ExternalFlashAE2',
+        Writable => 'int32u',
+        Unknown => 1,
+    },
+    0x1021 => { #11
+        Name => 'InternalFlashAE1',
+        Writable => 'int32u',
+        Unknown => 1,
+    },
+    0x1022 => { #11
+        Name => 'InternalFlashAE2',
+        Writable => 'int32u',
+        Unknown => 1,
+    },
+    0x1023 => { #6
+        Name => 'FlashExposureComp',
+        Writable => 'rational64s',
+    },
+    0x1024 => { #11
+        Name => 'InternalFlashTable',
+        Writable => 'int16u',
+    },
+    0x1025 => { #11
+        Name => 'ExternalFlashGValue',
+        Writable => 'rational64s',
+    },
+    0x1026 => { #6
+        Name => 'ExternalFlashBounce',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'No',
+            1 => 'Yes',
+        },
+    },
+    0x1027 => { #6
+        Name => 'ExternalFlashZoom',
+        Writable => 'int16u',
+    },
+    0x1028 => { #6
+        Name => 'ExternalFlashMode',
+        Writable => 'int16u',
+    },
+    0x1029 => { #3
+        Name => 'Contrast',
+        Writable => 'int16u',
+        PrintConv => { #PH (works with E1)
+            0 => 'High',
+            1 => 'Normal',
+            2 => 'Low',
+        },
+    },
+    0x102a => { #3
+        Name => 'SharpnessFactor',
+        Writable => 'int16u',
+    },
+    0x102b => { #3
+        Name => 'ColorControl',
+        Writable => 'int16u',
+        Count => 6,
+    },
+    0x102c => { #3
+        Name => 'ValidBits',
+        Writable => 'int16u',
+        Count => 2,
+    },
+    0x102d => { #3
+        Name => 'CoringFilter',
+        Writable => 'int16u',
+    },
+    0x102e => { #PH
+        Name => 'OlympusImageWidth',
+        Writable => 'int32u',
+    },
+    0x102f => { #PH
+        Name => 'OlympusImageHeight',
+        Writable => 'int32u',
+    },
+    0x1030 => { #11
+        Name => 'SceneDetect',
+        Writable => 'int16u',
+    },
+    0x1031 => { #11
+        Name => 'SceneArea',
+        Writable => 'int32u',
+        Count => 8,
+        Unknown => 1, # (numbers don't make much sense?)
+    },
+    # 0x1032 HAFFINAL? #11
+    0x1033 => { #11
+        Name => 'SceneDetectArea',
+        Writable => 'int32u',
+        Count => 720,
+        Binary => 1,
+        Unknown => 1, # (but what does it mean?)
+    },
+    0x1034 => { #3
+        Name => 'CompressionRatio',
+        Writable => 'rational64u',
+    },
+    0x1035 => { #6
+        Name => 'PreviewImageValid',
+        Writable => 'int32u',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    0x1036 => { #6
+        Name => 'PreviewImageStart',
+        Flags => 'IsOffset',
+        OffsetPair => 0x1037, # point to associated byte count
+        DataTag => 'PreviewImage',
+        Writable => 'int32u',
+        Protected => 2,
+    },
+    0x1037 => { #6
+        Name => 'PreviewImageLength',
+        OffsetPair => 0x1036, # point to associated offset
+        DataTag => 'PreviewImage',
+        Writable => 'int32u',
+        Protected => 2,
+    },
+    0x1038 => { #11
+        Name => 'AFResult',
+        Writable => 'int16u',
+    },
+    0x1039 => { #6
+        Name => 'CCDScanMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Interlaced',
+            1 => 'Progressive',
+        },
+    },
+    0x103a => { #6
+        Name => 'NoiseReduction',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    0x103b => { #6
+        Name => 'InfinityLensStep',
+        Writable => 'int16u',
+    },
+    0x103c => { #6
+        Name => 'NearLensStep',
+        Writable => 'int16u',
+    },
+    0x103d => { #11
+        Name => 'LightValueCenter',
+        Writable => 'rational64s',
+    },
+    0x103e => { #11
+        Name => 'LightValuePeriphery',
+        Writable => 'rational64s',
+    },
+    0x103f => { #11
+        Name => 'FieldCount',
+        Writable => 'int16u',
+        Unknown => 1, # (but what does it mean?)
+    },
+#
+# Olympus really screwed up the format of the following subdirectories (for the
+# E-1 and E-300 anyway). Not only is the subdirectory value data not included in
+# the size, but also the count is 2 bytes short for the subdirectory itself
+# (presumably the Olympus programmers forgot about the 2-byte entry count at the
+# start of the subdirectory).  This mess is straightened out and these subdirs
+# are written properly when ExifTool rewrites the file.  (This problem has been
+# fixed in the new-style MakerNoteOlympus2 maker notes since a standard SubIFD
+# offset value is used.) - PH
+#
+    0x2010 => [ #PH
+        {
+            Name => 'Equipment',
+            Condition => 'not $$self{OlympusType2}',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::Equipment',
+                ByteOrder => 'Unknown',
+            },
+        },
+        {
+            Name => 'Equipment2',
+            Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
+            Flags => 'SubIFD',
+            FixFormat => 'ifd',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::Equipment',
+                Start => '$val',
+            },
+        },
+    ],
+    0x2020 => [ #PH
+        {
+            Name => 'CameraSettings',
+            Condition => 'not $$self{OlympusType2}',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::CameraSettings',
+                ByteOrder => 'Unknown',
+            },
+        },
+        {
+            Name => 'CameraSettings2',
+            Groups => { 1 => 'MakerNotes' },
+            Flags => 'SubIFD',
+            FixFormat => 'ifd',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::CameraSettings',
+                Start => '$val',
+            },
+        },
+    ],
+    0x2030 => [ #PH
+        {
+            Name => 'RawDevelopment',
+            Condition => 'not $$self{OlympusType2}',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::RawDevelopment',
+                ByteOrder => 'Unknown',
+            },
+        },
+        {
+            Name => 'RawDevelopment2',
+            Groups => { 1 => 'MakerNotes' },
+            Flags => 'SubIFD',
+            FixFormat => 'ifd',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::RawDevelopment',
+                Start => '$val',
+            },
+        },
+    ],
+    0x2031 => [ #11
+        {
+            Name => 'RawDev2',
+            Condition => 'not $$self{OlympusType2}',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::RawDevelopment2',
+                ByteOrder => 'Unknown',
+            },
+        },
+        {
+            Name => 'RawDev2_2',
+            Groups => { 1 => 'MakerNotes' },
+            Flags => 'SubIFD',
+            FixFormat => 'ifd',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::RawDevelopment2',
+                Start => '$val',
+            },
+        },
+    ],
+    0x2040 => [ #PH
+        {
+            Name => 'ImageProcessing',
+            Condition => 'not $$self{OlympusType2}',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::ImageProcessing',
+                ByteOrder => 'Unknown',
+            },
+        },
+        {
+            Name => 'ImageProcessing2',
+            Groups => { 1 => 'MakerNotes' },
+            Flags => 'SubIFD',
+            FixFormat => 'ifd',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::ImageProcessing',
+                Start => '$val',
+            },
+        },
+    ],
+    0x2050 => [ #PH
+        {
+            Name => 'FocusInfo',
+            Condition => 'not ($$self{OlympusType2} or $$self{OlympusCAMER})',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::FocusInfo',
+                ByteOrder => 'Unknown',
+            },
+        },
+        {
+            Name => 'FocusInfo2',
+            Condition => 'not $$self{OlympusCAMER}',
+            Groups => { 1 => 'MakerNotes' },
+            Flags => 'SubIFD',
+            FixFormat => 'ifd',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::FocusInfo',
+                Start => '$val',
+            },
+        },
+        {
+            # ASCII-based camera parameters if makernotes starts with "CAMER\0"
+            Name => 'CameraParameters',
+            Writable => 'undef',
+            Binary => 1,
+        },
+    ],
+    0x2100 => { #11
+        Name => 'Olympus2100',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::FETags',
+            ByteOrder => 'Unknown',
+        },
+    },
+    0x2200 => { #11
+        Name => 'Olympus2200',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::FETags',
+            ByteOrder => 'Unknown',
+        },
+    },
+    0x2300 => { #11
+        Name => 'Olympus2300',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::FETags',
+            ByteOrder => 'Unknown',
+        },
+    },
+    0x2400 => { #11
+        Name => 'Olympus2400',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::FETags',
+            ByteOrder => 'Unknown',
+        },
+    },
+    0x2500 => { #11
+        Name => 'Olympus2500',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::FETags',
+            ByteOrder => 'Unknown',
+        },
+    },
+    0x2600 => { #11
+        Name => 'Olympus2600',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::FETags',
+            ByteOrder => 'Unknown',
+        },
+    },
+    0x2700 => { #11
+        Name => 'Olympus2700',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::FETags',
+            ByteOrder => 'Unknown',
+        },
+    },
+    0x2800 => { #11
+        Name => 'Olympus2800',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::FETags',
+            ByteOrder => 'Unknown',
+        },
+    },
+    0x2900 => { #11
+        Name => 'Olympus2900',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::FETags',
+            ByteOrder => 'Unknown',
+        },
+    },
+    0x3000 => [
+        { #6
+            Name => 'RawInfo',
+            Condition => 'not $$self{OlympusType2}',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::RawInfo',
+                ByteOrder => 'Unknown',
+            },
+        },
+        { #PH
+            Name => 'RawInfo2',
+            Groups => { 1 => 'MakerNotes' },
+            Flags => 'SubIFD',
+            FixFormat => 'ifd',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::RawInfo',
+                Start => '$val',
+            },
+        },
+    ],
+);
+
+# TextInfo tags
+%Image::ExifTool::Olympus::TextInfo = (
+    PROCESS_PROC => \&Image::ExifTool::APP12::ProcessAPP12,
+    NOTES => q{
+        This information is in text format (similar to APP12 information, but with
+        spaces instead of linefeeds).  Below are tags which have been observed, but
+        any information found here will be extracted, even if the tag is not listed.
+    },
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Olympus', 2 => 'Image' },
+    Resolution => { },
+    Type => {
+        Name => 'CameraType',
+        Groups => { 2 => 'Camera' },
+        DataMember => 'CameraType',
+        RawConv => '$self->{CameraType} = $val',
+    },
+);
+
+# Olympus Equipment IFD
+%Image::ExifTool::Olympus::Equipment = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x000 => { #PH
+        Name => 'EquipmentVersion',
+        Writable => 'undef',
+        Count => 4,
+    },
+    0x100 => { #6
+        Name => 'CameraType2',
+        Writable => 'string',
+        Count => 6,
+    },
+    0x101 => { #PH
+        Name => 'SerialNumber',
+        Writable => 'string',
+        Count => 32,
+        PrintConv => '$val=~s/\s+$//;$val',
+        PrintConvInv => 'pack("A31",$val)', # pad with spaces to 31 chars
+    },
+    0x102 => { #6
+        Name => 'InternalSerialNumber',
+        Notes => '16 digits: 0-3=model, 4=year, 5-6=month, 8-12=unit number',
+        Writable => 'string',
+        Count => 32,
+    },
+    0x103 => { #6
+        Name => 'FocalPlaneDiagonal',
+        Writable => 'rational64u',
+        PrintConv => '"$val mm"',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
+    },
+    0x104 => { #6
+        Name => 'BodyFirmwareVersion',
+        Writable => 'int32u',
+        PrintConv => '$val=sprintf("%x",$val);$val=~s/(.{3})$/\.$1/;$val',
+        PrintConvInv => '$val=sprintf("%.3f",$val);$val=~s/\.//;hex($val)',
+    },
+    0x201 => { #6
+        Name => 'LensType',
+        Writable => 'int8u',
+        Count => 6,
+        Notes => '6 numbers: 1. Make, 2. Unknown, 3. Model, 4. Release, 5-6. Unknown',
+        PrintConv => 'Image::ExifTool::Olympus::PrintLensInfo($val,"Lens")',
+    },
+    # apparently the first 3 digits of the lens s/n give the type (ref 4):
+    # 010 = 50macro
+    # 040 = EC-14
+    # 050 = 14-54
+    # 060 = 50-200
+    # 080 = EX-25
+    # 101 = FL-50
+    0x202 => { #PH
+        Name => 'LensSerialNumber',
+        Writable => 'string',
+        Count => 32,
+        PrintConv => '$val=~s/\s+$//;$val',
+        PrintConvInv => 'pack("A31",$val)', # pad with spaces to 31 chars
+    },
+    0x204 => { #6
+        Name => 'LensFirmwareVersion',
+        Writable => 'int32u',
+        PrintConv => '$val=sprintf("%x",$val);$val=~s/(.{3})$/\.$1/;$val',
+        PrintConvInv => '$val=sprintf("%.3f",$val);$val=~s/\.//;hex($val)',
+    },
+    0x205 => { #11
+        Name => 'MaxApertureAtMinFocal',
+        Writable => 'int16u',
+        ValueConv => '$val ? sqrt(2)**($val/256) : 0',
+        ValueConvInv => '$val>0 ? int(512*log($val)/log(2)+0.5) : 0',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x206 => { #5
+        Name => 'MaxApertureAtMaxFocal',
+        Writable => 'int16u',
+        ValueConv => '$val ? sqrt(2)**($val/256) : 0',
+        ValueConvInv => '$val>0 ? int(512*log($val)/log(2)+0.5) : 0',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x207 => { #PH
+        Name => 'MinFocalLength',
+        Writable => 'int16u',
+    },
+    0x208 => { #PH
+        Name => 'MaxFocalLength',
+        Writable => 'int16u',
+    },
+    0x20a => { #9
+        Name => 'MaxApertureAtCurrentFocal',
+        Writable => 'int16u',
+        ValueConv => '$val ? sqrt(2)**($val/256) : 0',
+        ValueConvInv => '$val>0 ? int(512*log($val)/log(2)+0.5) : 0',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x20b => { #11
+        Name => 'LensProperties',
+        Writable => 'int16u',
+        PrintConv => 'sprintf("0x%x",$val)',
+        PrintConvInv => '$val',
+    },
+    0x301 => { #6
+        Name => 'Extender',
+        Writable => 'int8u',
+        Count => 6,
+        Notes => '6 numbers: 1. Make, 2. Unknown, 3. Model, 4. Release, 5-6. Unknown.',
+        PrintConv => 'Image::ExifTool::Olympus::PrintLensInfo($val,"Extender")',
+    },
+    0x302 => { #4
+        Name => 'ExtenderSerialNumber',
+        Writable => 'string',
+        Count => 32,
+    },
+    0x303 => { #9
+        Name => 'ExtenderModel',
+        Writable => 'string',
+    },
+    0x304 => { #6
+        Name => 'ExtenderFirmwareVersion',
+        Writable => 'int32u',
+        PrintConv => '$val=sprintf("%x",$val);$val=~s/(.{3})$/\.$1/;$val',
+        PrintConvInv => '$val=sprintf("%.3f",$val);$val=~s/\.//;hex($val)',
+    },
+    0x1000 => { #6
+        Name => 'FlashType',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'None',
+            2 => 'Simple E-System',
+            3 => 'E-System',
+        },
+    },
+    0x1001 => { #6
+        Name => 'FlashModel',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'None',
+            1 => 'FL-20',
+            2 => 'FL-50',
+            3 => 'RF-11',
+            4 => 'TF-22',
+            5 => 'FL-36',
+        },
+    },
+    0x1002 => { #6
+        Name => 'FlashFirmwareVersion',
+        Writable => 'int32u',
+        PrintConv => '$val=sprintf("%x",$val);$val=~s/(.{3})$/\.$1/;$val',
+        PrintConvInv => '$val=sprintf("%.3f",$val);$val=~s/\.//;hex($val)',
+    },
+    0x1003 => { #4
+        Name => 'FlashSerialNumber',
+        Writable => 'string',
+        Count => 32,
+    },
+);
+
+# Olympus camera settings IFD
+%Image::ExifTool::Olympus::CameraSettings = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x000 => { #PH
+        Name => 'CameraSettingsVersion',
+        Writable => 'undef',
+        Count => 4,
+    },
+    0x100 => { #6
+        Name => 'PreviewImageValid',
+        Writable => 'int32u',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    0x101 => { #PH
+        Name => 'PreviewImageStart',
+        Flags => 'IsOffset',
+        OffsetPair => 0x102,
+        DataTag => 'PreviewImage',
+        Writable => 'int32u',
+        Protected => 2,
+    },
+    0x102 => { #PH
+        Name => 'PreviewImageLength',
+        OffsetPair => 0x101,
+        DataTag => 'PreviewImage',
+        Writable => 'int32u',
+        Protected => 2,
+    },
+    0x200 => { #4
+        Name => 'ExposureMode',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Manual',
+            2 => 'Program', #6
+            3 => 'Aperture-priority AE',
+            4 => 'Shutter speed priority AE',
+            5 => 'Program-shift', #6
+        }
+    },
+    0x201 => { #6
+        Name => 'AELock',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    0x202 => { #PH/4
+        Name => 'MeteringMode',
+        Writable => 'int16u',
+        PrintConv => {
+            2 => 'Center Weighted',
+            3 => 'Spot',
+            5 => 'ESP',
+            261 => 'Pattern+AF', #6
+            515 => 'Spot+Highlight control', #6
+            1027 => 'Spot+Shadow control', #6
+        },
+    },
+    0x300 => { #6
+        Name => 'MacroMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'Super Macro', #11
+        },
+    },
+    0x301 => { #6
+        Name => 'FocusMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Single AF',
+            1 => 'Sequential shooting AF',
+            2 => 'Continuous AF',
+            3 => 'Multi AF',
+            10 => 'MF',
+        },
+    },
+    0x302 => { #6
+        Name => 'FocusProcess',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'AF Not Used',
+            1 => 'AF Used',
+        },
+    },
+    0x303 => { #6
+        Name => 'AFSearch',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Not Ready',
+            1 => 'Ready',
+        },
+    },
+    0x304 => { #PH/4
+        Name => 'AFAreas',
+        Format => 'int32u',
+        Count => 64,
+        PrintConv => 'Image::ExifTool::Olympus::PrintAFAreas($val)',
+    },
+    0x400 => { #6
+        Name => 'FlashMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            BITMASK => {
+                0 => 'On',
+                1 => 'Fill-in',
+                2 => 'Red-eye',
+                3 => 'Slow-sync',
+                4 => 'Forced On',
+                5 => '2nd Curtain',
+            },
+        },
+    },
+    0x401 => { #6
+        Name => 'FlashExposureCompensation',
+        Writable => 'rational64s',
+    },
+    0x500 => { #6
+        Name => 'WhiteBalance2',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Auto',
+            16 => '7500K (Fine Weather with Shade)',
+            17 => '6000K (Cloudy)',
+            18 => '5300K (Fine Weather)',
+            20 => '3000K (Tungsten light)',
+            21 => '3600K (Tungsten light-like)',
+            33 => '6600K (Daylight fluorescent)',
+            34 => '4500K (Neutral white fluorescent)',
+            35 => '4000K (Cool white fluorescent)',
+            48 => '3600K (Tungsten light-like)',
+            256 => 'Custom WB 1',
+            257 => 'Custom WB 2',
+            258 => 'Custom WB 3',
+            259 => 'Custom WB 4',
+            512 => 'Custom WB 5400K',
+            513 => 'Custom WB 2900K',
+            514 => 'Custom WB 8000K',
+        },
+    },
+    0x501 => { #PH/4
+        Name => 'WhiteBalanceTemperature',
+        Writable => 'int16u',
+        PrintConv => '$val ? $val : "Auto"',
+        PrintConvInv => '$val=~/^\d+$/ ? $val : 0',
+    },
+    0x502 => {  #PH/4
+        Name => 'WhiteBalanceBracket',
+        Writable => 'int16s',
+    },
+    0x503 => { #PH/4/6
+        Name => 'CustomSaturation',
+        Writable => 'int16s',
+        Count => 3,
+        Notes => '3 numbers: 1. CS Value, 2. Min, 3. Max',
+        PrintConv => q{
+            my ($a,$b,$c)=split ' ',$val;
+            if ($self->{CameraModel} =~ /^E-1\b/) {
+                $a-=$b; $c-=$b;
+                return "CS$a (min CS0, max CS$c)";
+            } else {
+                return "$a (min $b, max $c)";
+            }
+        },
+    },
+    0x504 => { #PH/4
+        Name => 'ModifiedSaturation',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'CM1 (Red Enhance)',
+            2 => 'CM2 (Green Enhance)',
+            3 => 'CM3 (Blue Enhance)',
+            4 => 'CM4 (Skin Tones)',
+        },
+    },
+    0x505 => { #PH/4
+        Name => 'ContrastSetting',
+        Writable => 'int16s',
+        Count => 3,
+        Notes => 'value, min, max',
+        PrintConv => 'my @v=split " ",$val; "$v[0] (min $v[1], max $v[2])"',
+        PrintConvInv => '$val=~tr/-0-9 //dc;$val',
+    },
+    0x506 => { #PH/4
+        Name => 'SharpnessSetting',
+        Writable => 'int16s',
+        Count => 3,
+        Notes => 'value, min, max',
+        PrintConv => 'my @v=split " ",$val; "$v[0] (min $v[1], max $v[2])"',
+        PrintConvInv => '$val=~tr/-0-9 //dc;$val',
+    },
+    0x507 => { #PH/4
+        Name => 'ColorSpace',
+        Writable => 'int16u',
+        PrintConv => { #6
+            0 => 'sRGB',
+            1 => 'Adobe RGB',
+            2 => 'Pro Photo RGB',
+        },
+    },
+    0x509 => { #6
+        Name => 'SceneMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Standard',
+            6 => 'Auto', #6
+            7 => 'Sport',
+            8 => 'Portrait',
+            9 => 'Landscape+Portrait',
+            10 => 'Landscape',
+            11 => 'Night Scene',
+            13 => 'Panorama', #6
+            16 => 'Landscape+Portrait', #6
+            17 => 'Night+Portrait',
+            19 => 'Fireworks',
+            20 => 'Sunset',
+            22 => 'Macro',
+            25 => 'Documents',
+            26 => 'Museum',
+            28 => 'Beach&Snow',
+            30 => 'Candle',
+            35 => 'Underwater Wide1', #6
+            36 => 'Underwater Macro', #6
+            39 => 'High Key',
+            40 => 'Digital Image Stabilization', #6
+            44 => 'Underwater Wide2', #6
+            45 => 'Low Key', #6
+            46 => 'Children', #6
+            48 => 'Nature Macro', #6
+        },
+    },
+    0x50a => { #PH/4/6
+        Name => 'NoiseReduction',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Noise Reduction',
+            2 => 'Noise Filter',
+            3 => 'Noise Reduction + Noise Filter',
+            4 => 'Noise Filter (ISO Boost)', #6
+            5 => 'Noise Reduction + Noise Filter (ISO Boost)', #6
+        },
+    },
+    0x50b => { #6
+        Name => 'DistortionCorrection',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x50c => { #PH/4
+        Name => 'ShadingCompensation',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x50d => { #PH/4
+        Name => 'CompressionFactor',
+        Writable => 'rational64u',
+    },
+    0x50f => { #6
+        Name => 'Gradation',
+        Writable => 'int16s',
+        Count => 3,
+        PrintConv => {
+           '-1 -1 1' => 'Low Key',
+            '0 -1 1' => 'Normal',
+            '1 -1 1' => 'High Key',
+        },
+    },
+    0x520 => { #6
+        Name => 'PictureMode',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Vivid',
+            2 => 'Natural',
+            3 => 'Muted',
+            256 => 'Monotone',
+            512 => 'Sepia',
+        },
+    },
+    0x521 => { #6
+        Name => 'PictureModeSaturation',
+        Writable => 'int16s',
+        Count => 3,
+        Notes => 'value, min, max',
+        PrintConv => 'my @v=split " ",$val; "$v[0] (min $v[1], max $v[2])"',
+        PrintConvInv => '$val=~tr/-0-9 //dc;$val',
+    },
+    0x522 => { #6
+        Name => 'PictureModeHue',
+        Writable => 'int16s',
+        Unknown => 1, # (needs verification)
+    },
+    0x523 => { #6
+        Name => 'PictureModeContrast',
+        Writable => 'int16s',
+        Count => 3,
+        Notes => 'value, min, max',
+        PrintConv => 'my @v=split " ",$val; "$v[0] (min $v[1], max $v[2])"',
+        PrintConvInv => '$val=~tr/-0-9 //dc;$val',
+    },
+    0x524 => { #6
+        Name => 'PictureModeSharpness',
+        # verified as the Sharpness setting in the Picture Mode menu for the E-410
+        Writable => 'int16s',
+        Count => 3,
+        Notes => 'value, min, max',
+        PrintConv => 'my @v=split " ",$val; "$v[0] (min $v[1], max $v[2])"',
+        PrintConvInv => '$val=~tr/-0-9 //dc;$val',
+    },
+    0x525 => { #6
+        Name => 'PictureModeBWFilter',
+        Writable => 'int16s',
+        PrintConv => {
+            0 => 'n/a',
+            1 => 'Neutral',
+            2 => 'Yellow',
+            3 => 'Orange',
+            4 => 'Red',
+            5 => 'Green',
+        },
+    },
+    0x526 => { #6
+        Name => 'PictureModeTone',
+        Writable => 'int16s',
+        PrintConv => {
+            0 => 'n/a',
+            1 => 'Neutral',
+            2 => 'Sepia',
+            3 => 'Blue',
+            4 => 'Purple',
+            5 => 'Green',
+        },
+    },
+    0x527 => { #12
+        Name => 'NoiseFilter',
+        Writable => 'int16s',
+        Count => 3,
+        PrintConv => {
+           '-2 -2 1' => 'Off',
+           '-1 -2 1' => 'Low',
+           '0 -2 1' => 'Standard',
+           '1 -2 1' => 'High',
+        },
+    },
+    0x600 => { #PH/4
+        Name => 'DriveMode',
+        Writable => 'int16u',
+        Count => -1,
+        Notes => '2 or 3 numbers: 1. Mode, 2. Shot number, 3. Mode bits',
+        PrintConv => q{
+            my ($a,$b,$c) = split ' ',$val;
+            return 'Single Shot' unless $a;
+            if ($a == 5 and defined $c) {
+                $a = DecodeBits($c, { #6
+                    0 => 'AE',
+                    1 => 'WB',
+                    2 => 'FL',
+                    3 => 'MF',
+                }) . ' Bracketing';
+                $a =~ s/, /+/g;
+            } else {
+                my %a = (
+                    1 => 'Continuous Shooting',
+                    2 => 'Exposure Bracketing',
+                    3 => 'White Balance Bracketing',
+                    4 => 'Exposure+WB Bracketing', #6
+                );
+                $a = $a{$a} || "Unknown ($a)";
+            }
+            return "$a, Shot $b";
+        },
+    },
+    0x601 => { #6
+        Name => 'PanoramaMode',
+        Writable => 'int16u',
+        Notes => '2 numbers: 1. Mode, 2. Shot number',
+        PrintConv => q{
+            my ($a,$b) = split ' ',$val;
+            return 'Off' unless $a;
+            my %a = (
+                1 => 'Left to right',
+                2 => 'Right to left',
+                3 => 'Bottom to top',
+                4 => 'Top to bottom',
+            );
+            return ($a{$a} || "Unknown ($a)") . ', Shot ' . $b;
+        },
+    },
+    0x603 => { #PH/4
+        Name => 'ImageQuality2',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'SQ',
+            2 => 'HQ',
+            3 => 'SHQ',
+            4 => 'RAW',
+        },
+    },
+    0x901 => { #PH (u770SW)
+        # 2 numbers: 1st looks like meters above sea level, 2nd is usually 3x the 1st (feet?)
+        Name => 'ManometerReading',
+        Writable => 'int32s',
+        Count => 2,
+    },
+);
+
+# Olympus RAW processing IFD (ref 6)
+%Image::ExifTool::Olympus::RawDevelopment = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x000 => { #PH
+        Name => 'RawDevVersion',
+        Writable => 'undef',
+        Count => 4,
+    },
+    0x100 => {
+        Name => 'RawDevExposureBiasValue',
+        Writable => 'rational64s',
+    },
+    0x101 => {
+        Name => 'RawDevWhiteBalanceValue',
+        Writable => 'int16u',
+    },
+    0x102 => {
+        Name => 'RawDevWBFineAdjustment',
+        Writable => 'int16s',
+    },
+    0x103 => {
+        Name => 'RawDevGrayPoint',
+        Writable => 'int16u',
+        Count => 3,
+    },
+    0x104 => {
+        Name => 'RawDevSaturationEmphasis',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x105 => {
+        Name => 'RawDevMemoryColorEmphasis',
+        Writable => 'int16u',
+    },
+    0x106 => {
+        Name => 'RawDevContrastValue',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x107 => {
+        Name => 'RawDevSharpnessValue',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x108 => {
+        Name => 'RawDevColorSpace',
+        Writable => 'int16u',
+        PrintConv => { #11
+            0 => 'sRGB',
+            1 => 'Adobe RGB',
+            2 => 'Pro Photo RGB',
+        },
+    },
+    0x109 => {
+        Name => 'RawDevEngine',
+        Writable => 'int16u',
+        PrintConv => { #11
+            0 => 'High Speed',
+            1 => 'High Function',
+            2 => 'Advanced High Speed',
+            3 => 'Advanced High Function',
+        },
+    },
+    0x10a => {
+        Name => 'RawDevNoiseReduction',
+        Writable => 'int16u',
+        PrintConv => { #11
+            BITMASK => {
+                0 => 'Noise Reduction',
+                1 => 'Noise Filter',
+                2 => 'ISO Boost',
+            },
+        },
+    },
+    0x10b => {
+        Name => 'RawDevEditStatus',
+        Writable => 'int16u',
+        PrintConv => { #11
+            0 => 'Original',
+            1 => 'Edited (Landscape)',
+            6 => 'Edited (Portrait)',
+            8 => 'Edited (Portrait)',
+        },
+    },
+    0x10c => {
+        Name => 'RawDevSettings',
+        Writable => 'int16u',
+        PrintConv => { #11
+            BITMASK => {
+                0 => 'WB Color Temp',
+                2 => 'WB Gray Point',
+                3 => 'Saturation',
+                4 => 'Contrast',
+                5 => 'Sharpness',
+                6 => 'Color Space',
+                7 => 'High Function',
+                8 => 'Noise Reduction',
+            },
+        },
+    },
+);
+
+# Olympus RAW processing B IFD (ref 11)
+%Image::ExifTool::Olympus::RawDevelopment2 = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x000 => {
+        Name => 'RawDevVersion',
+        Writable => 'undef',
+        Count => 4,
+    },
+    0x100 => {
+        Name => 'RawDevExposureBiasValue',
+        Writable => 'rational64s',
+    },
+    0x101 => {
+        Name => 'RawDevWhiteBalance',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Color Temperature',
+            2 => 'Gray Point',
+        },
+    },
+    0x102 => {
+        Name => 'RawDevWhiteBalanceValue',
+        Writable => 'int16u',
+    },
+    0x103 => {
+        Name => 'RawDevWBFineAdjustment',
+        Writable => 'int16s',
+    },
+    0x104 => {
+        Name => 'RawDevGrayPoint',
+        Writable => 'int16u',
+        Count => 3,
+    },
+    0x105 => {
+        Name => 'RawDevContrastValue',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x106 => {
+        Name => 'RawDevSharpnessValue',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x107 => {
+        Name => 'RawDevSaturationEmphasis',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x108 => {
+        Name => 'RawDevMemoryColorEmphasis',
+        Writable => 'int16u',
+    },
+    0x109 => {
+        Name => 'RawDevColorSpace',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'sRGB',
+            1 => 'Adobe RGB',
+            2 => 'Pro Photo RGB',
+        },
+    },
+    0x10a => {
+        Name => 'RawDevNoiseReduction',
+        Writable => 'int16u',
+        PrintConv => {
+            BITMASK => {
+                0 => 'Noise Reduction',
+                1 => 'Noise Filter',
+                2 => 'ISO Boost',
+            },
+        },
+    },
+    0x10b => {
+        Name => 'RawDevEngine',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'High Speed',
+            1 => 'High Function',
+        },
+    },
+    0x10c => {
+        Name => 'RawDevPictureMode',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Vivid',
+            2 => 'Natural',
+            3 => 'Muted',
+            256 => 'Monotone',
+            512 => 'Sepia',
+        },
+    },
+    0x10d => {
+        Name => 'RawDevPMSaturation',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x10e => {
+        Name => 'RawDevPMContrast',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x10f => {
+        Name => 'RawDevPMSharpness',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x110 => {
+        Name => 'RawDevPM_BWFilter',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Neutral',
+            2 => 'Yellow',
+            3 => 'Orange',
+            4 => 'Red',
+            5 => 'Green',
+        },
+    },
+    0x111 => {
+        Name => 'RawDevPMPictureTone',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Neutral',
+            2 => 'Sepia',
+            3 => 'Blue',
+            4 => 'Purple',
+            5 => 'Green',
+        },
+    },
+    0x112 => {
+        Name => 'RawDevGradation',
+        Writable => 'int16s',
+        Count => 3,
+    },
+);
+
+# Olympus Image processing IFD
+%Image::ExifTool::Olympus::ImageProcessing = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x000 => { #PH
+        Name => 'ImageProcessingVersion',
+        Writable => 'undef',
+        Count => 4,
+    },
+    0x100 => { #6
+        Name => 'WB_RBLevels',
+        Writable => 'int16u',
+        Count => 2,
+    },
+    0x200 => { #6
+        Name => 'ColorMatrix',
+        Writable => 'int16u',
+        Format => 'int16s',
+        Count => 9,
+    },
+    0x300 => { #PH/4
+        Name => 'SmoothingParameter1',
+        Writable => 'int16u',
+    },
+    0x310 => { #PH/4
+        Name => 'SmoothingParameter2',
+        Writable => 'int16u',
+    },
+    0x600 => { #PH/4
+        Name => 'SmoothingThresholds',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x610 => { #PH/4
+        Name => 'SmoothingThreshold2',
+        Writable => 'int16u',
+    },
+    0x611 => { #4/6
+        Name => 'ValidBits',
+        Writable => 'int16u',
+        Count => 2,
+    },
+    0x614 => { #PH
+        Name => 'OlympusImageWidth2',
+        Writable => 'int32u',
+    },
+    0x615 => { #PH
+        Name => 'OlympusImageHeight2',
+        Writable => 'int32u',
+    },
+    # 0x1010-0x1012 are the processing options used in camera or in
+    # Olympus software, which 0x050a-0x050c are in-camera only (ref 6)
+    0x1010 => { #PH/4
+        Name => 'NoiseReduction2',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Noise Filter',
+            2 => 'Noise Reduction',
+            3 => 'Noise Reduction + Noise Filter', #6
+            4 => 'Noise Filter (ISO Boost)', #6
+            5 => 'Noise Reduction + Noise Filter (ISO Boost)', #6
+        },
+    },
+    0x1011 => { #6
+        Name => 'DistortionCorrection2',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    0x1012 => { #PH/4
+        Name => 'ShadingCompensation2',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x1103 => { #PH
+        Name => 'UnknownBlock',
+        Writable => 'undef',
+        Notes => 'unknown 142kB block in ORF images, not copied to JPEG images',
+        # 'Drop' because too large for APP1 in JPEG images
+        Flags => [ 'Unknown', 'Binary', 'Drop' ],
+    },
+);
+
+# Olympus Focus Info IFD
+%Image::ExifTool::Olympus::FocusInfo = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x000 => { #PH
+        Name => 'FocusInfoVersion',
+        Writable => 'undef',
+        Count => 4,
+    },
+    0x209 => { #PH/4
+        Name => 'AutoFocus',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+        Unknown => 1, #6
+    },
+    0x300 => { #6
+        Name => 'ZoomStepCount',
+        Writable => 'int16u',
+    },
+    0x301 => { #11
+        Name => 'FocusStepCount',
+        Writable => 'int16u',
+    },
+    0x305 => { #4
+        Name => 'FocusDistance',
+        Writable => 'rational64u',
+        # this rational value looks like it is in mm when the denominator is
+        # 1 (E-1), and cm when denominator is 10 (E-300), so if we ignore the
+        # denominator we are consistently in mm - PH
+        Format => 'int32u',
+        Count => 2,
+        ValueConv => q{
+            my ($a,$b) = split ' ',$val;
+            return 0 if $a == 0xffffffff;
+            return $a / 1000;
+        },
+        ValueConvInv => q{
+            return '4294967295 1' unless $val;
+            $val = int($val * 1000 + 0.5);
+            return "$val 1";
+        },
+        PrintConv => '$val ? "$val m" : "inf"',
+        PrintConvInv => '$val eq "inf" ? 0 : $val=~s/\s*m$//, $val',
+    },
+    0x308 => { #11
+        Name => 'AFPoint',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Left',
+            1 => 'Center (1)',
+            2 => 'Right',
+            3 => 'Center (3)',
+            255 => 'None',
+        },
+    },
+    # 0x31a Continuous AF parameters?
+    # 0x1200-0x1209 Flash information:
+    0x1201 => { #6
+        Name => 'ExternalFlash',
+        Writable => 'int16u',
+        Count => 2,
+        PrintConv => {
+            '0 0' => 'Off',
+            '1 0' => 'On',
+        },
+    },
+    0x1203 => { #11
+        Name => 'ExternalFlashGuideNumber',
+        Writable => 'rational64s',
+        Unknown => 1, # (needs verification)
+    },
+    0x1204 => { #11(reversed)/7
+        Name => 'ExternalFlashBounce',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Bounce or Off',
+            1 => 'Direct',
+        },
+    },
+    0x1205 => { #11 (ref converts to mm using table)
+        Name => 'ExternalFlashZoom',
+        Writable => 'rational64u',
+    },
+    0x1208 => { #6
+        Name => 'InternalFlash',
+        Writable => 'int16u',
+        Count => -1,
+        PrintConv => {
+            '0'   => 'Off',
+            '1'   => 'On',
+            '0 0' => 'Off',
+            '1 0' => 'On',
+        },
+    },
+    0x1209 => { #6
+        Name => 'ManualFlash',
+        Writable => 'int16u',
+        Count => 2,
+        Notes => '2 numbers: 1. 0=Off, 1=On, 2. Flash strength',
+        PrintConv => q{
+            my ($a,$b) = split ' ',$val;
+            return 'Off' unless $a;
+            $b = ($b == 1) ? 'Full' : "1/$b";
+            return "On ($b strength)";
+        },
+    },
+    0x1500 => { #6
+        Name => 'SensorTemperature',
+        Writable => 'int16s',
+    },
+    0x1600 => { # ref http://fourthirdsphoto.com/vbb/showpost.php?p=107607&postcount=15
+        Name => 'ImageStabilization',
+        Writable => 'undef',
+        # if the first 4 bytes are non-zero, then bit 0x01 of byte 44
+        # gives the stabilization mode
+        PrintConv => q{
+            $val =~ /^\0{4}/ ? 'Off' : 'On, ' .
+            (unpack('x44C',$val) & 0x01 ? 'Mode 1' : 'Mode 2')
+        },
+    },
+    # 0x102a same as Subdir4-0x300
+);
+
+# Olympus raw information tags (ref 6)
+%Image::ExifTool::Olympus::RawInfo = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    NOTES => 'These tags are found only in ORF images of some models (ie. C8080WZ).',
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x000 => {
+        Name => 'RawInfoVersion',
+        Writable => 'undef',
+        Count => 4,
+    },
+    0x100 => {
+        Name => 'WB_RBLevelsUsed',
+        Writable => 'int16',
+        Count => 2,
+    },
+    0x110 => {
+        Name => 'WB_RBLevelsAuto',
+        Writable => 'int16',
+        Count => 2,
+    },
+    0x120 => {
+        Name => 'WB_RBLevelsShade',
+        Writable => 'int16',
+        Count => 2,
+    },
+    0x121 => {
+        Name => 'WB_RBLevelsCloudy',
+        Writable => 'int16',
+        Count => 2,
+    },
+    0x122 => {
+        Name => 'WB_RBLevelsFineWeather',
+        Writable => 'int16',
+        Count => 2,
+    },
+    0x123 => {
+        Name => 'WB_RBLevelsTungsten',
+        Writable => 'int16',
+        Count => 2,
+    },
+    0x124 => {
+        Name => 'WB_RBLevelsEveningSunlight',
+        Writable => 'int16',
+        Count => 2,
+    },
+    0x130 => {
+        Name => 'WB_RBLevelsDaylightFluor',
+        Writable => 'int16',
+        Count => 2,
+    },
+    0x131 => {
+        Name => 'WB_RBLevelsDayWhiteFluor',
+        Writable => 'int16',
+        Count => 2,
+    },
+    0x132 => {
+        Name => 'WB_RBLevelsCoolWhiteFluor',
+        Writable => 'int16',
+        Count => 2,
+    },
+    0x133 => {
+        Name => 'WB_RBLevelsWhiteFluorescent',
+        Writable => 'int16',
+        Count => 2,
+    },
+    0x200 => {
+        Name => 'ColorMatrix2',
+        Format => 'int16s',
+        Writable => 'int16u',
+        Count => 9,
+    },
+    # 0x240 => 'ColorMatrixDefault', ?
+    # 0x250 => 'ColorMatrixSaturation', ?
+    # 0x251 => 'ColorMatrixHue', ?
+    # 0x252 => 'ColorMatrixContrast', ?
+    # 0x300 => sharpness-related
+    # 0x301 => list of sharpness-related values
+    0x310 => {
+        Name => 'CoringFilter',
+        Writable => 'int16u',
+    },
+    0x311 => {
+        Name => 'CoringValues',
+        Writable => 'int16u',
+        Count => 11,
+    },
+    0x600 => {
+        Name => 'BlackLevel2',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x601 => {
+        Name => 'YCbCrCoefficients',
+        Notes => 'stored as int16u[6], but extracted as rational32u[3]',
+        Format => 'rational32u',
+    },
+    0x611 => {
+        Name => 'ValidPixelDepth',
+        Writable => 'int16u',
+        Count => 2,
+    },
+    0x612 => { #11
+        Name => 'StartOffsetX',
+        Writable => 'int16u',
+    },
+    0x613 => { #11
+        Name => 'StartOffsetY',
+        Writable => 'int16u',
+    },
+    0x614 => {
+        Name => 'FinalImageWidth',
+        Writable => 'int32u',
+    },
+    0x615 => {
+        Name => 'FinalImageHeight',
+        Writable => 'int32u',
+    },
+    0x1000 => {
+        Name => 'LightSource',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Unknown',
+            16 => 'Shade',
+            17 => 'Cloudy',
+            18 => 'Fine Weather',
+            20 => 'Tungsten (incandescent)',
+            22 => 'Evening Sunlight',
+            33 => 'Daylight Fluorescent (D 5700 - 7100K)',
+            34 => 'Day White Fluorescent (N 4600 - 5400K)',
+            35 => 'Cool White Fluorescent (W 3900 - 4500K)',
+            36 => 'White Fluorescent (WW 3200 - 3700K)',
+            256 => 'One Touch White Balance',
+            512 => 'Custom 1-4',
+        },
+    },
+    # the following 5 tags all have 3 values: val, min, max
+    0x1001 => {
+        Name => 'WhiteBalanceComp',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x1010 => {
+        Name => 'SaturationSetting',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x1011 => {
+        Name => 'HueSetting',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x1012 => {
+        Name => 'ContrastSetting',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x1013 => {
+        Name => 'SharpnessSetting',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    # settings written by Camedia Master 4.x
+    0x2000 => {
+        Name => 'CMExposureCompensation',
+        Writable => 'rational64s',
+    },
+    0x2001 => {
+        Name => 'CMWhiteBalance',
+        Writable => 'int16u',
+    },
+    0x2002 => {
+        Name => 'CMWhiteBalanceComp',
+        Writable => 'int16s',
+    },
+    0x2010 => {
+        Name => 'CMWhiteBalanceGrayPoint',
+        Writable => 'int16u',
+        Count => 3,
+    },
+    0x2020 => {
+        Name => 'CMSaturation',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x2021 => {
+        Name => 'CMHue',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x2022 => {
+        Name => 'CMContrast',
+        Writable => 'int16s',
+        Count => 3,
+    },
+    0x2023 => {
+        Name => 'CMSharpness',
+        Writable => 'int16s',
+        Count => 3,
+    },
+);
+
+# Tags found only in some FE models
+%Image::ExifTool::Olympus::FETags = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        Some FE models write a large number of tags here, but most of this
+        information remains unknown.
+    },
+    0x0100 => {
+        Name => 'BodyFirmwareVersion',
+        Writable => 'string',
+    },
+);
+
+# Olympus composite tags
+%Image::ExifTool::Olympus::Composite = (
+    GROUPS => { 2 => 'Camera' },
+    ExtenderStatus => {
+        Notes => q{
+            Olympus cameras have the quirk that they may retain the extender settings
+            after the extender is removed until the camera is powered off.  This tag is
+            an attempt to represent the actual status of the extender.
+        },
+        Require => {
+            0 => 'Olympus:Extender',
+            1 => 'Olympus:LensType',
+            2 => 'MaxApertureValue',
+        },
+        ValueConv => 'Image::ExifTool::Olympus::ExtenderStatus($val[0],$prt[1],$val[2])',
+        PrintConv => {
+            0 => 'Not attached',
+            1 => 'Attached',
+            2 => 'Removed',
+        },
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::Olympus');
+
+
+#------------------------------------------------------------------------------
+# Determine if the extender (EX-25/EC-14) was really attached (ref 9)
+# Inputs: 0) Extender, 1) LensType string, 2) MaxApertureAtMaxFocal
+# Returns: 0=not attached, 1=attached, 2=could have been removed
+# Notes: Olympus has a bug in the in-camera firmware which results in the
+# extender information being cached and written into the EXIF data even after
+# the extender has been removed.  You must power cycle the camera to prevent it
+# from writing the cached extender information into the EXIF data.
+sub ExtenderStatus($$$)
+{
+    my ($extender, $lensType, $maxAperture) = @_;
+    my @info = split ' ', $extender;
+    # validate that extender identifier is reasonable
+    return 0 unless @info >= 4 and $info[2];
+    # if it's not an EC-14 (id 0 4) then assume it was really attached
+    # (other extenders don't seem to affect the reported max aperture)
+    return 1 if "$info[0] $info[2]" ne "0 4";
+    # get the maximum aperture for this lens (in $1)
+    $lensType =~ / F(\d+(.\d+)?)/ or return 1;
+    # If the maximum aperture at the maximum focal length is greater than the
+    # known max/max aperture of the lens, then the extender must be attached
+    return ($maxAperture - $1 > 0.2) ? 1 : 2;
+}
+
+#------------------------------------------------------------------------------
+# Print lens information (ref 6)
+# Inputs: 0) Lens info (string of integers: Make, Unknown, Model, Release, ...)
+#         1) 'Lens' or 'Extender'
+sub PrintLensInfo($$)
+{
+    my ($val, $type) = @_;
+    my @info = split ' ', $val;
+    return "Unknown ($val)" unless @info >= 4;
+    return 'None' unless $info[2];
+    my %make = (
+        0 => 'Olympus',
+        1 => 'Sigma',
+        2 => 'Leica',
+        3 => 'Leica',
+    );
+    my %model = (
+        Lens => {
+            # Olympus lenses (key is "make model" with optional "release")
+            '0 1 0' => 'Zuiko Digital ED 50mm F2.0 Macro',
+            '0 1 1' => 'Zuiko Digital 40-150mm F3.5-4.5', #8
+            '0 2'   => 'Zuiko Digital ED 150mm F2.0',
+            '0 3'   => 'Zuiko Digital ED 300mm F2.8',
+            '0 5 0' => 'Zuiko Digital 14-54mm F2.8-3.5',
+            '0 5 1' => 'Zuiko Digital Pro ED 90-250mm F2.8', #9
+            '0 6 0' => 'Zuiko Digital ED 50-200mm F2.8-3.5',
+            '0 6 1' => 'Zuiko Digital ED 8mm F3.5 Fisheye', #9
+            '0 7 0' => 'Zuiko Digital 11-22mm F2.8-3.5',
+            '0 7 1' => 'Zuiko Digital 18-180mm F3.5-6.3', #6
+            '0 21'  => 'Zuiko Digital ED 7-14mm F4.0',
+            '0 23'  => 'Zuiko Digital Pro ED 35-100mm F2.0', #7
+            '0 24'  => 'Zuiko Digital 14-45mm F3.5-5.6',
+            '0 32'  => 'Zuiko Digital 35mm F3.5 Macro', #9
+            '0 34'  => 'Zuiko Digital 17.5-45mm F3.5-5.6', #9
+            '0 35'  => 'Zuiko Digital ED 14-42mm F3.5-5.6', #PH
+            '0 36'  => 'Zuiko Digital ED 40-150mm F4.0-5.6', #PH
+            # Sigma lenses
+            '1 1'   => '18-50mm F3.5-5.6', #8
+            '1 2'   => '55-200mm F4.0-5.6 DC',
+            '1 3'   => '18-125mm F3.5-5.6 DC',
+            '1 4'   => '18-125mm F3.5-5.6', #7
+            '1 5'   => '30mm F1.4', #10
+            '1 7'   => '105mm F2.8 DG', #PH
+            '1 8'   => '150mm F2.8 DG HSM', #PH
+            '1 17'  => '135-400mm F4.5-5.6 DG ASP APO RF', #11
+            '1 18'  => '300-800mm F5.6 EX DG APO', #11
+            # Leica lenses (ref 11)
+            '2 1'   => 'D Vario Elmarit 14-50mm, F2.8-3.5 Asph.',
+            '2 2'   => 'D Summilux 25mm, F1.4 Asph.',
+            '3 1'   => 'D Vario Elmarit 14-50mm, F2.8-3.5 Asph.',
+            '3 2'   => 'D Summilux 25mm, F1.4 Asph.',
+        },
+        Extender => {
+            # Olympus extenders
+            '0 4'   => 'Zuiko Digital EC-14 1.4x Teleconverter',
+            '0 8'   => 'EX-25 Extension Tube',
+        },
+    );
+    my %release = (
+        0 => '', # production
+        1 => ' (pre-release)',
+    );
+    my $make = $make{$info[0]} || "Unknown Make ($info[0])";
+    my $str = "$info[0] $info[2]";
+    my $rel = $release{$info[3]};
+    my $model = $model{$type}->{"$str $info[3]"};
+    if ($model) {
+        $rel = '';  # don't print release if it is used to differentiate models
+    } else {
+        $rel = " Unknown Release ($info[3])" unless defined $rel;
+        $model = $model{$type}->{$str} || "Unknown Model ($str)";
+    }
+    return "$make $model$rel";
+}
+
+#------------------------------------------------------------------------------
+# Print AF points
+# Inputs: 0) AF point data (string of integers)
+# Notes: I'm just guessing that the 2nd and 4th bytes are the Y coordinates,
+# and that more AF points will show up in the future (derived from E-1 images,
+# and the E-1 uses just one of 3 possible AF points, all centered in Y) - PH
+sub PrintAFAreas($)
+{
+    my $val = shift;
+    my @points = split ' ', $val;
+    my %afPointNames = (
+        0x36794285 => 'Left',
+        0x79798585 => 'Center',
+        0xBD79C985 => 'Right',
+    );
+    $val = '';
+    my $pt;
+    foreach $pt (@points) {
+        next unless $pt;
+        $val and $val .= ', ';
+        $afPointNames{$pt} and $val .= $afPointNames{$pt} . ' ';
+        my @coords = unpack('C4',pack('N',$pt));
+        $val .= "($coords[0],$coords[1])-($coords[2],$coords[3])";
+    }
+    $val or $val = 'none';
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Process ORF file
+# Inputs: 0) ExifTool object reference, 1) directory information reference
+# Returns: 1 if this looked like a valid ORF file, 0 otherwise
+sub ProcessORF($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    return $exifTool->ProcessTIFF($dirInfo);
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Olympus - Olympus/Epson maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+Olympus or Epson maker notes in EXIF information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html>
+
+=item L<http://www.cybercom.net/~dcoffin/dcraw/>
+
+=item L<http://www.ozhiker.com/electronics/pjmt/jpeg_info/olympus_mn.html>
+
+=item L<http://olypedia.de/Olympus_Makernotes>
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Markku Hanninen, Remi Guyomarch, Frank Ledwon, Michael Meissner,
+Mark Dapoz and Ioannis Panagiotopoulos for their help figuring out some
+Olympus tags, and Lilo Huang for adding to the LensType list.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Olympus Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/PDF.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/PDF.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/PDF.pm	(revision 20131)
@@ -0,0 +1,1294 @@
+#------------------------------------------------------------------------------
+# File:         PDF.pm
+#
+# Description:  Read PDF meta information
+#
+# Revisions:    07/11/05 - P. Harvey Created
+#               07/25/05 - P. Harvey Add support for encrypted documents
+#
+# References:   1) http://partners.adobe.com/public/developer/pdf/index_reference.html
+#               2) http://www.cr0.net:8040/code/crypto/rc4/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::PDF;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+require Exporter;
+
+$VERSION = '1.10';
+
+sub LocateObject($$);
+sub FetchObject($$$$);
+sub ExtractObject($$;$$);
+sub ReadToNested($;$);
+sub ProcessDict($$$$;$);
+
+my %warnedOnce;     # hash of warnings we issued
+my %streamObjs;     # hash of stream objects
+my %fetched;        # dicts fetched in verbose mode (to avoid cyclical recursion)
+my $lastFetched;    # last fetched object reference (used for decryption)
+my $cryptInfo;      # encryption object reference (plus additional information)
+
+# tags in main PDF directories
+%Image::ExifTool::PDF::Main = (
+    Info => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::Info',
+        },
+    },
+    Root => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::Root',
+        },
+    },
+);
+
+# tags in PDF Info directory
+%Image::ExifTool::PDF::Info = (
+    GROUPS => { 2 => 'Image' },
+    EXTRACT_UNKNOWN => 1, # extract all unknown tags in this directory
+    NOTES => q{
+        As well as the tags listed below, the PDF specification allows for
+        user-defined tags to exist in the Info dictionary.  These tags, which should
+        have corresponding XMP-pdfx entries in the PDF Metadata, are also extracted
+        by ExifTool.
+    },
+    Title       => { },
+    Author      => { Groups => { 2 => 'Author' } },
+    Subject     => { },
+    Keywords    => { List => 1 },  # this is a list of tokens
+    Creator     => { },
+    Producer    => { },
+    CreationDate => {
+        Name => 'CreateDate',
+        Groups => { 2 => 'Time' },
+        ValueConv => 'Image::ExifTool::PDF::ConvertPDFDate($self, $val)',
+    },
+    ModDate => {
+        Name => 'ModifyDate',
+        Groups => { 2 => 'Time' },
+        ValueConv => 'Image::ExifTool::PDF::ConvertPDFDate($self, $val)',
+    },
+    Trapped => {
+        # remove leading '/' from '/True' or '/False'
+        ValueConv => '$val=~s{^/}{}; $val',
+    },
+);
+
+# tags in the PDF Root document catalog
+%Image::ExifTool::PDF::Root = (
+    NOTES => 'This is the PDF document catalog.',
+    Metadata => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::Metadata',
+        },
+    },
+    Pages => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::Pages',
+        },
+    },
+);
+
+# tags in PDF Pages directory
+%Image::ExifTool::PDF::Pages = (
+    GROUPS => { 2 => 'Image' },
+    Count => 'PageCount',
+    Kids => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::Kids',
+        },
+    },
+);
+
+# tags in PDF Kids directory
+%Image::ExifTool::PDF::Kids = (
+    Metadata => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::Metadata',
+        },
+    },
+    PieceInfo => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::PieceInfo',
+        },
+    },
+    Resources => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::Resources',
+        },
+    },
+);
+
+# tags in PDF Resources directory
+%Image::ExifTool::PDF::Resources = (
+    ColorSpace => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::ColorSpace',
+        },
+    },
+);
+
+# tags in PDF ColorSpace directory
+%Image::ExifTool::PDF::ColorSpace = (
+    DefaultRGB => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::DefaultRGB',
+        },
+    },
+);
+
+# tags in PDF DefaultRGB directory
+%Image::ExifTool::PDF::DefaultRGB = (
+    ICCBased => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::ICCBased',
+        },
+    },
+);
+
+# tags in PDF ICCBased directory
+%Image::ExifTool::PDF::ICCBased = (
+    stream => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+        },
+    },
+);
+
+# tags in PDF PieceInfo directory
+%Image::ExifTool::PDF::PieceInfo = (
+    AdobePhotoshop => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::AdobePhotoshop',
+        },
+    },
+);
+
+# tags in PDF AdobePhotoshop directory
+%Image::ExifTool::PDF::AdobePhotoshop = (
+    Private => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::Private',
+        },
+    },
+);
+
+# tags in PDF Private directory
+%Image::ExifTool::PDF::Private = (
+    ImageResources => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PDF::ImageResources',
+        },
+    },
+);
+
+# tags in PDF ImageResources directory
+%Image::ExifTool::PDF::ImageResources = (
+    stream => {
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Photoshop::Main',
+        },
+    },
+);
+
+# tags in PDF Metadata directory
+%Image::ExifTool::PDF::Metadata = (
+    GROUPS => { 2 => 'Image' },
+    XML_stream => { # this is the stream for a Subtype /XML dictionary (not a real tag)
+        Name => 'XMP',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::XMP::Main',
+        },
+    },
+);
+
+# unknown tags for use in verbose option
+%Image::ExifTool::PDF::Unknown = (
+    GROUPS => { 2 => 'Unknown' },
+);
+
+#------------------------------------------------------------------------------
+# Issue one warning of each type
+# Inputs: 0) ExifTool object reference, 1) warning
+sub WarnOnce($$)
+{
+    my ($exifTool, $warn) = @_;
+    unless ($warnedOnce{$warn}) {
+        $warnedOnce{$warn} = 1;
+        $exifTool->Warn($warn);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Set PDF format error warning
+# Inputs: 0) ExifTool object reference, 1) error string
+# Returns: 1
+sub PDFErr($$)
+{
+    my ($exifTool, $str) = @_;
+    $exifTool->Warn("PDF format error ($str)");
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Convert from PDF to EXIF-style date/time
+# Inputs: 0) ExifTool object reference,
+#         1) PDF date/time string (D:yyyymmddhhmmss+hh'mm')
+# Returns: EXIF date string (yyyy:mm:dd hh:mm:ss+hh:mm)
+sub ConvertPDFDate($$)
+{
+    my ($exifTool, $date) = @_;
+    # remove optional 'D:' prefix
+    $date =~ s/^D://;
+    # fill in default values if necessary
+    #              yyyymmddhhmmss
+    my $default = '00000101000000';
+    if (length $date < length $default) {
+        $date .= substr($default, length $date);
+    }
+    $date =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(.*)/ or return $date;
+    $date = "$1:$2:$3 $4:$5:$6";
+    if ($7) {
+        my @t = split /'/, $7;
+        $date .= $t[0];
+        $date .= ':' . ($t[1] || 0) if $t[0] ne 'Z';
+    }
+    return $exifTool->ConvertDateTime($date);
+}
+
+#------------------------------------------------------------------------------
+# Locate an object in the XRref tables
+# Inputs: 0) XRef reference, 1) object reference string
+# Returns: offset to object in file, or undefined on error
+sub LocateObject($$)
+{
+    my ($xref, $ref) = @_;
+    return undef unless $xref;
+    return $$xref{$ref} if $$xref{$ref};
+    # get the object number
+    return undef unless $ref =~ /^(\d+)/;
+    my $objNum = $1;
+#
+# scan our XRef stream dictionaries for this object
+#
+    return undef unless $$xref{dicts};
+    my $dict;
+    foreach $dict (@{$$xref{dicts}}) {
+        # quick check to see if the object is in the range for this xref stream
+        next if $objNum >= $$dict{Size};
+        my $index = $$dict{Index};
+        next if $objNum < $$index[0];
+        # scan the tables for the specified object
+        my $size = $$dict{entry_size};
+        my $num = scalar(@$index) / 2;
+        my $tot = 0;
+        my $i;
+        for ($i=0; $i<$num; ++$i) {
+            my $start = $$index[$i*2];
+            my $count = $$index[$i*2+1];
+            # table is in ascending order, so quit if we have passed the object
+            last if $objNum >= $start + $count;
+            if ($objNum >= $start) {
+                my $offset = $size * ($objNum - $start + $tot);
+                last if $offset + $size > length $$dict{stream};
+                my @c = unpack("x$offset C$size", $$dict{stream});
+                # extract values from this table entry
+                # (can be 1, 2, 3, 4, etc.. bytes per value)
+                my (@t, $j, $k, $ref2);
+                my $w = $$dict{W};
+                for ($j=0; $j<3; ++$j) {
+                    # use default value if W entry is 0 (as per spec)
+                    $$w[$j] or $t[$j] = ($j ? 1 : 0), next;
+                    $t[$j] = shift(@c);
+                    for ($k=1; $k < $$w[$j]; ++$k) {
+                        $t[$j] = 256 * $t[$j] + shift(@c);
+                    }
+                }
+                if ($t[0] == 1) {
+                    # normal object reference: use "o g R" as hash ref
+                    # (o = object number, g = generation number)
+                    $ref2 = "$objNum $t[2] R";
+                    # xref is offset of object from start
+                    $$xref{$ref2} = $t[1];
+                } elsif ($t[0] == 2) {
+                    # compressed object reference:
+                    $ref2 = "$objNum 0 R";
+                    # xref is object index and stream object reference
+                    $$xref{$ref2} = "I$t[2] $t[1] 0 R";
+                } else {
+                    last;
+                }
+                return $$xref{$ref} if $ref eq $ref2;
+            }
+            $tot += $count;
+        }
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Fetch indirect object from file (from inside a stream if required)
+# Inputs: 0) ExifTool object reference, 1) object reference string, 2) xref lookup,
+# Returns: object data or undefined on error
+sub FetchObject($$$$)
+{
+    my ($exifTool, $ref, $xref, $tag) = @_;
+    $lastFetched = $ref;    # save this for decoding if necessary
+    my $offset = LocateObject($xref, $ref);
+    unless ($offset) {
+        $exifTool->Warn("Bad $tag reference");
+        return undef;
+    }
+    my ($data, $obj);
+    if ($offset =~ s/^I(\d+) //) {
+        my $index = $1; # object index in stream
+        my ($objNum) = split ' ', $ref; # save original object number
+        $ref = $offset; # now a reference to the containing stream object
+        my $obj = $streamObjs{$ref};
+        unless ($obj) {
+            # don't try to load the same object stream twice
+            return undef if defined $obj;
+            $streamObjs{$ref} = '';
+            # load the parent object stream
+            $obj = FetchObject($exifTool, $ref, $xref, $tag);
+            # make sure it contains everything we need
+            return undef unless defined $obj and ref($obj) eq 'HASH';
+            return undef unless $$obj{First} and $$obj{N};
+            return undef unless DecodeStream($exifTool, $obj);
+            # add a special 'table' entry to this dictionary which contains
+            # the list of object number/offset pairs from the stream header
+            my $num = $$obj{N} * 2;
+            my @table = split ' ', $$obj{stream}, $num;
+            return undef unless @table == $num;
+            # remove everything before first object in stream
+            $$obj{stream} = substr($$obj{stream}, $$obj{First});
+            $table[$num-1] =~ s/^(\d+).*/$1/;  # trim excess from last number
+            $$obj{table} = \@table;
+            # save the object stream so we don't have to re-load it later
+            $streamObjs{$ref} = $obj;
+        }
+        # verify that we have the specified object
+        my $i = 2 * $index;
+        my $table = $$obj{table};
+        unless ($index < $$obj{N} and $$table[$i] == $objNum) {
+            $exifTool->Warn("Bad index for stream object $tag");
+            return undef;
+        }
+        # extract the object at the specified index in the stream
+        # (offsets in table are in sequential order, so we can subract from
+        #  the next offset to get the object length)
+        $offset = $$table[$i + 1];
+        my $len = ($$table[$i + 3] || length($$obj{stream})) - $offset;
+        $data = substr($$obj{stream}, $offset, $len);
+        return ExtractObject($exifTool, \$data);
+    }
+    my $raf = $exifTool->{RAF};
+    $raf->Seek($offset, 0) or $exifTool->Warn("Bad $tag offset"), return undef;
+    # verify that we are reading the expected object
+    $raf->ReadLine($data) or $exifTool->Warn("Error reading $tag data"), return undef;
+    ($obj = $ref) =~ s/R/obj/;
+    unless ($data =~ s/^$obj//) {
+        $exifTool->Warn("$tag object ($obj) not found at $offset");
+        return undef;
+    }
+    return ExtractObject($exifTool, \$data, $raf, $xref);
+}
+
+#------------------------------------------------------------------------------
+# Extract PDF object from combination of buffered data and file
+# Inputs: 0) ExifTool object reference, 1) data reference,
+#         2) optional raf reference, 3) optional xref table
+# Returns: converted PDF object or undef on error
+#          a) dictionary object --> hash reference
+#          b) array object --> array reference
+#          c) indirect reference --> scalar reference
+#          d) string, name, integer, boolean, null --> scalar value
+# - updates $$dataPt on return to contain unused data
+# - creates two bogus entries ('stream' and 'tags') in dictionaries to represent
+#   the stream data and a list of the tags (not including 'stream' and 'tags')
+#   in their original order
+sub ExtractObject($$;$$)
+{
+    my ($exifTool, $dataPt, $raf, $xref) = @_;
+    my (@tags, $data, $objData);
+    my $dict = { };
+    my $delim;
+
+    for (;;) {
+        if ($$dataPt =~ /^\s*(<{1,2}|\[|\()/) {
+            $delim = $1;
+            $objData = ReadToNested($dataPt, $raf);
+            return undef unless defined $objData;
+            last;
+        } elsif ($$dataPt =~ s{^\s*(\S[^[(/<>\s]*)\s*}{}) {
+#
+# extract boolean, numerical, string, name, null object or indirect reference
+#
+            $objData = $1;
+            # look for an indirect reference
+            if ($objData =~ /^\d+$/ and $$dataPt =~ s/^(\d+)\s+R//) {
+                $objData .= "$1 R";
+                $objData = \$objData;   # return scalar reference
+            }
+            return $objData;    # return simple scalar or scalar reference
+        }
+        $raf and $raf->ReadLine($data) or return undef;
+        $$dataPt .= $data;
+    }
+#
+# extract literal string
+#
+    if ($delim eq '(') {
+        $objData = $1 if $objData =~ /.*?\((.*)\)/s;    # remove brackets
+        # decode escape sequences in literal strings
+        while ($objData =~ /\\(.)/sg) {
+            my $n = pos($objData) - 2;
+            my $c = $1;
+            my $r;
+            if ($c =~ /[0-7]/) {
+                # get up to 2 more octal digits
+                $c .= $1 if $objData =~ /\G([0-7]{1,2})/g;
+                # convert octal escape code
+                $r = chr(oct($c) & 0xff);
+            } elsif ($c eq "\x0d") {
+                # the string is continued if the line ends with '\'
+                # (also remove "\x0d\x0a")
+                $c .= $1 if $objData =~ /\G(\x0a)/g;
+                $r = '';
+            } elsif ($c eq "\x0a") {
+                # (also remove "\x0a\x0d")
+                $c .= $1 if $objData =~ /\G(\x0d)/g;
+                $r = '';
+            } else {
+                # convert escaped characters
+                ($r = $c) =~ tr/nrtbf/\n\r\t\b\f/;
+            }
+            substr($objData, $n, length($c)+1) = $r;
+            # contine search after this character
+            pos($objData) = $n + length($r);
+        }
+        Decrypt(\$objData) if $cryptInfo;
+        # convert from UTF-16 (big endian) to UTF-8 or Latin if necessary
+        if ($objData =~ s/^\xfe\xff//) {
+            $objData = $exifTool->Unicode2Charset($objData, 'MM');
+        }
+        return $objData;
+#
+# extract hex string
+#
+    } elsif ($delim eq '<') {
+        # decode hex data
+        $objData =~ tr/0-9A-Fa-f//dc;
+        $objData .= '0' if length($objData) & 0x01; # (by the spec)
+        $objData = pack('H*', $objData);
+        Decrypt(\$objData) if $cryptInfo;
+        return $objData;
+#
+# extract array
+#
+    } elsif ($delim eq '[') {
+        $objData =~ /.*?\[(.*)\]/s or return;    # remove brackets
+        my $data = $1;
+        my @list;
+        for (;;) {
+            last unless $data =~ m{\s*(\S[^[(/<>\s]*)}sg;
+            my $val = $1;
+            if ($val =~ /^(<{1,2}|\[|\()/) {
+                my $pos = pos($data) - length($val);
+                # nested dict, array, literal string or hex string
+                my $buff = substr($data, $pos);
+                $val = ReadToNested(\$buff);
+                last unless defined $val;
+                pos($data) = $pos + length($val);
+                $val = ExtractObject($exifTool, \$val);
+            } elsif ($val =~ /^\d/) {
+                my $pos = pos($data);
+                if ($data =~ /\G\s+(\d+)\s+R/g) {
+                    $val = \ "$val $1 R";   # make a reference
+                } else {
+                    pos($data) = $pos;
+                }
+            }
+            push @list, $val;
+        }
+        return \@list;
+    }
+#
+# extract dictionary
+#
+    # Note: entries are not necessarily separated by whitespace (doh!)
+    # ie) "/Tag/Name", "/Tag(string)", "/Tag[array]", etc are legal!
+    # Also, they may be separated by a comment (ie. "/Tag%comment\nValue"),
+    # but comments have already been removed
+    while ($objData =~ m{(\s*)/([^/[\]()<>{}\s]+)\s*(\S[^[(/<>\s]*)}sg) {
+        my $tag = $2;
+        my $val = $3;
+        if ($val =~ /^(<{1,2}|\[|\()/) {
+            # nested dict, array, literal string or hex string
+            $objData = substr($objData, pos($objData)-length($val));
+            $val = ReadToNested(\$objData, $raf);
+            last unless defined $val;
+            $val = ExtractObject($exifTool, \$val);
+            pos($objData) = 0;
+        } elsif ($val =~ /^\d/) {
+            my $pos = pos($objData);
+            if ($objData =~ /\G\s+(\d+)\s+R/g) {
+                $val = \ "$val $1 R";   # make a reference
+            } else {
+                pos($objData) = $pos;
+            }
+        }
+        if ($$dict{$tag}) {
+            # duplicate dictionary entries are not allowed
+            $exifTool->Warn("Duplicate $tag entry in dictionary (ignored)");
+        } else {
+            # save the entry
+            push @tags, $tag;
+            $$dict{$tag} = $val;
+        }
+    }
+    return undef unless @tags;
+    $$dict{tags} = \@tags;
+    return $dict unless $raf;   # direct objects can not have streams
+#
+# extract the stream object
+#
+    # dictionary must specify stream Length
+    my $length = $$dict{Length} or return $dict;
+    if (ref $length) {
+        $length = $$length;
+        my $oldpos = $raf->Tell();
+        # get the location of the object specifying the length
+        my $offset = LocateObject($xref, $length) or return $dict;
+        $raf->Seek($offset, 0) or $exifTool->Warn("Bad Length offset"), return $dict;
+        # verify that we are reading the expected object
+        $raf->ReadLine($data) or $exifTool->Warn("Error reading Length data"), return $dict;
+        $length =~ s/R/obj/;
+        unless ($data =~ /^$length/) {
+            $exifTool->Warn("Length object ($length) not found at $offset");
+            return $dict;
+        }
+        $raf->ReadLine($data) or $exifTool->Warn("Error reading stream Length"), return $dict;
+        $data =~ /(\d+)/ or $exifTool->Warn("Stream length not found"), return $dict;
+        $length = $1;
+        $raf->Seek($oldpos, 0); # restore position to start of stream
+    }
+    # extract the trailing stream data
+    for (;;) {
+        # find the stream token
+        if ($$dataPt =~ /(\S+)/) {
+            last unless $1 eq 'stream';
+            # read an extra line because it may contain our \x0a
+            $$dataPt .= $data if $raf->ReadLine($data);
+            # remove our stream header
+            $$dataPt =~ s/^.*stream(\x0a|\x0d\x0a)//s;
+            my $more = $length - length($$dataPt);
+            if ($more > 0) {
+                unless ($raf->Read($data, $more) == $more) {
+                    $exifTool->Warn("Error reading stream data");
+                    $$dataPt = '';
+                    return $dict;
+                }
+                $$dict{stream} = $$dataPt . $data;
+                $$dataPt = '';
+            } elsif ($more < 0) {
+                $$dict{stream} = substr($$dataPt, 0, $length);
+                $$dataPt = substr($$dataPt, $length);
+            } else {
+                $$dict{stream} = $$dataPt;
+                $$dataPt = '';
+            }
+            last;
+        }
+        $raf->ReadLine($data) or last;
+        $$dataPt .= $data;
+    }
+    return $dict;
+}
+
+#------------------------------------------------------------------------------
+# Read to nested delimiter
+# Inputs: 0) data reference, 1) optional raf reference
+# Returns: data up to and including matching delimiter (or undef on error)
+# - updates data reference with trailing data
+# - unescapes characters in literal strings
+sub ReadToNested($;$)
+{
+    my ($dataPt, $raf) = @_;
+    # matching closing delimiters
+    my %closingDelim = (
+        '<<' => '>>',
+        '('  => ')',
+        '['  => ']',
+        '<'  => '>',
+    );
+    my @delim = ('');   # closing delimiter list, most deeply nested first
+    pos($$dataPt) = 0;  # begin at start of data
+    for (;;) {
+        unless ($$dataPt =~ /(\\*)(\(|\)|<{1,2}|>{1,2}|\[|\]|%)/g) {
+            # must read some more data
+            my $buff;
+            last unless $raf and $raf->ReadLine($buff);
+            $$dataPt .= $buff;
+            pos($$dataPt) = length($$dataPt) - length($buff);
+            next;
+        }
+        # are we in a literal string?
+        if ($delim[0] eq ')') {
+            # ignore escaped delimiters (preceeded by odd number of \'s)
+            next if length($1) & 0x01;
+            # ignore all delimiters but unescaped braces
+            next unless $2 eq '(' or $2 eq ')';
+        } elsif ($2 eq '%') {
+            # ignore the comment
+            my $pos = pos($$dataPt) - 1;
+            # remove everything from '%' up to but not including newline
+            $$dataPt =~ /.*/g;
+            my $end = pos($$dataPt);
+            $$dataPt = substr($$dataPt, 0, $pos) . substr($$dataPt, $end);
+            pos($$dataPt) = $pos;
+            next;
+        }
+        if ($closingDelim{$2}) {
+            # push the corresponding closing delimiter
+            unshift @delim, $closingDelim{$2};
+            next;
+        }
+        unless ($2 eq $delim[0]) {
+            # handle the case where we find a ">>>" and interpret it
+            # as ">> >" instead of "> >>"
+            next unless $2 eq '>>' and $delim[0] eq '>';
+            pos($$dataPt) = pos($$dataPt) - 1;
+        }
+        my $delim = shift @delim;   # remove from nesting list
+        next if $delim[0];          # keep going if we have more nested delimiters
+        my $pos = pos($$dataPt);
+        my $buff = substr($$dataPt, 0, $pos);
+        $$dataPt = substr($$dataPt, $pos);
+        return $buff;   # success!
+    }
+    return undef;   # didn't find matching delimiter
+}
+
+#------------------------------------------------------------------------------
+# Decode filtered stream
+# Inputs: 0) ExifTool object reference, 1) dictionary reference
+# Returns: true if stream has been decoded OK
+sub DecodeStream($$)
+{
+    my ($exifTool, $dict) = @_;
+
+    return 0 unless $$dict{stream}; # no stream to decode
+    # apply decryption first if required
+    if ($cryptInfo and not $$dict{decrypted}) {
+        $$dict{decrypted} = 1;
+        if ($$cryptInfo{meta} or ($$dict{Type} and $$dict{Type} ne '/Metadata')) {
+            Decrypt(\$$dict{stream});
+        }
+    }
+    return 1 unless $$dict{Filter};
+    if ($$dict{Filter} eq '/FlateDecode') {
+        if (eval 'require Compress::Zlib') {
+            my $inflate = Compress::Zlib::inflateInit();
+            my ($buff, $stat);
+            $inflate and ($buff, $stat) = $inflate->inflate($$dict{stream});
+            if ($inflate and $stat == Compress::Zlib::Z_STREAM_END()) {
+                $$dict{stream} = $buff;
+                # move Filter to prevent double decoding
+                $$dict{oldFilter} = $$dict{Filter};
+                $$dict{Filter} = '';
+            } else {
+                $exifTool->Warn('Error inflating stream');
+                return 0;
+            }
+        } else {
+            WarnOnce($exifTool,'Install Compress::Zlib to decode filtered streams');
+            return 0;
+        }
+#
+# apply anti-predictor if necessary
+#
+        return 1 unless $$dict{DecodeParms};
+        my $pre = $dict->{DecodeParms}->{Predictor};
+        return 1 unless $pre and $pre != 1;
+        if ($pre != 12) {
+            # currently only support 'up' prediction
+            WarnOnce($exifTool,"FlateDecode Predictor $pre not currently supported");
+            return 0;
+        }
+        my $cols = $dict->{DecodeParms}->{Columns};
+        unless ($cols) {
+            # currently only support 'up' prediction
+            WarnOnce($exifTool,'No Columns for decoding stream');
+            return 0;
+        }
+        my @bytes = unpack('C*', $$dict{stream});
+        my @pre = (0) x $cols;  # initialize predictor array
+        my $buff = '';
+        while (@bytes > $cols) {
+            unless (($_ = shift @bytes) == 2) {
+                WarnOnce($exifTool, "Unsupported PNG filter $_");
+                return 0;
+            }
+            foreach (@pre) {
+                $_ = ($_ + shift(@bytes)) & 0xff;
+            }
+            $buff .= pack('C*', @pre);
+        }
+        $$dict{stream} = $buff;
+    } else {
+        WarnOnce($exifTool, "Unsupported Filter $$dict{Filter}");
+        return 0;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Initialize state for RC4 en/decryption (ref 2)
+# Inputs: 0) RC4 key string
+# Returns: RC4 key hash reference
+sub RC4Init($)
+{
+    my @key = unpack('C*', shift);
+    my @state = (0 .. 255);
+    my ($i, $j) = (0, 0);
+    while ($i < 256) {
+        my $st = $state[$i];
+        $j = ($j + $st + $key[$i % scalar(@key)]) & 0xff;
+        $state[$i++] = $state[$j];
+        $state[$j] = $st;
+    }
+    return { State => \@state, XY => [ 0, 0 ] };
+}
+
+#------------------------------------------------------------------------------
+# Apply RC4 en/decryption (ref 2)
+# Inputs: 0) data reference, 1) RC4 key hash reference or RC4 key string
+# - can call this method directly with a key string, or with with the key
+#   reference returned by RC4Init
+# - RC4 is a symmetric algorithm, so encryption is the same as decryption
+sub RC4Crypt($$)
+{
+    my ($dataPt, $key) = @_;
+    $key = RC4Init($key) unless ref $key eq 'HASH';
+    my $state = $$key{State};
+    my ($x, $y) = @{$$key{XY}};
+
+    my @data = unpack('C*', $$dataPt);
+    foreach (@data) {
+         $x = ($x + 1) & 0xff;
+         my $stx = $$state[$x];
+         $y = ($stx + $y) & 0xff;
+         my $sty = $$state[$x] = $$state[$y];
+         $$state[$y] = $stx;
+         $_ ^= $$state[($stx + $sty) & 0xff];
+     }
+     $$key{XY} = [ $x, $y ];
+     $$dataPt = pack('C*', @data);
+}
+
+#------------------------------------------------------------------------------
+# Initialize decryption
+# Inputs: 0) ExifTool object reference, 1) Encrypt dictionary reference,
+#         2) ID from file trailer dictionary
+# Returns: error string or undef on success
+sub DecryptInit($$$)
+{
+    my ($exifTool, $encrypt, $id) = @_;
+    unless ($encrypt and ref $encrypt eq 'HASH') {
+        return 'Error loading Encrypt object';
+    }
+    my $filt = $$encrypt{Filter};
+    unless ($filt and $filt =~ s/^\///) {
+        return 'Encrypt dictionary has no Filter!';
+    }
+    my $ver = $$encrypt{V} || 0;
+    my $rev = $$encrypt{R} || 0;
+    $exifTool->FoundTag('Encryption', "$filt v$ver.$rev");
+    unless ($$encrypt{Filter} eq '/Standard') {
+        $$encrypt{Filter} =~ s/^\///;
+        return "PDF '$$encrypt{Filter}' encryption not currently supported";
+    }
+    unless ($$encrypt{O} and $$encrypt{P} and $$encrypt{U}) {
+        return 'Incomplete Encrypt specification';
+    }
+    unless ($ver == 1 or $ver == 2) {
+        return "Encryption algorithm $ver currently not supported";
+    }
+    $id or return "Can't decrypt (no document ID)";
+    unless (eval 'require Digest::MD5') {
+        return 'Install Digest::MD5 to extract encrypted information';
+    }
+    # calculate file-level en/decryption key
+    my $pad = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08".
+              "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
+    my $key = $pad . $$encrypt{O} . pack('V', $$encrypt{P}) . $id;
+    my $rep = 1;
+    $$encrypt{meta} = 1; # set flag that Metadata is encrypted
+    if ($rev >= 3) {
+        # in rev 4 (not yet supported), metadata streams may not be encrypted
+        if ($$encrypt{EncryptMetadata} and $$encrypt{EncryptMetadata} =~ /false/i) {
+            delete $$encrypt{meta};     # Meta data isn't encrypted after all
+            $key .= "\xff\xff\xff\xff"; # must add this if metadata not encrypted
+        }
+        $rep += 50; # repeat MD5 50 more times if revision is 3 or greater
+    }
+    my ($len, $i);
+    if ($ver == 1) {
+        $len = 5;
+    } else {
+        $len = $$encrypt{Length} || 40;
+        $len >= 40 or return 'Bad Encrypt Length';
+        $len = int($len / 8);
+    }
+    for ($i=0; $i<$rep; ++$i) {
+        $key = substr(Digest::MD5::md5($key), 0, $len);
+    }
+    # decrypt U to see if a user password is required
+    my $dat;
+    if ($rev >= 3) {
+        $dat = Digest::MD5::md5($pad . $id);
+        RC4Crypt(\$dat, $key);
+        for ($i=1; $i<=19; ++$i) {
+            my @key = unpack('C*', $key);
+            foreach (@key) { $_ ^= $i; }
+            RC4Crypt(\$dat, pack('C*', @key));
+        }
+        $dat .= substr($$encrypt{U}, 16);
+    } else {
+        $dat = $pad;
+        RC4Crypt(\$dat, $key);
+    }
+    $dat eq $$encrypt{U} or return 'Document is password encrypted';
+    $$encrypt{key} = $key;  # save the file-level encryption key
+    $cryptInfo = $encrypt;  # save a reference to the Encrypt object
+    return undef;           # success!
+}
+
+#------------------------------------------------------------------------------
+# Decrypt data
+# Inputs: 0) data reference
+sub Decrypt($)
+{
+    my $dataPt = shift;
+    my $key = $$cryptInfo{key};
+    my $len = length($key) + 5;
+    return unless $lastFetched =~ /^(I\d+ )?(\d+) (\d+)/;
+    $key .= substr(pack('V', $2), 0, 3) . substr(pack('V', $3), 0, 2);
+    $len = 16 if $len > 16;
+    $key = substr(Digest::MD5::md5($key), 0, $len);
+    RC4Crypt($dataPt, $key);
+}
+
+#------------------------------------------------------------------------------
+# Process PDF dictionary extract tag values
+# Inputs: 0) ExifTool object reference, 1) tag table reference
+#         2) dictionary reference, 3) cross-reference table reference,
+#         4) nesting depth
+sub ProcessDict($$$$;$)
+{
+    my ($exifTool, $tagTablePtr, $dict, $xref, $nesting) = @_;
+    my $verbose = $exifTool->Options('Verbose');
+    my @tags = @{$$dict{tags}};
+    my $index = 0;
+    my $next;
+
+    $nesting = ($nesting || 0) + 1;
+    if ($nesting > 50) {
+        WarnOnce($exifTool, 'Nesting too deep (directory ignored)');
+        return;
+    }
+#
+# extract information from all tags in the dictionary
+#
+    for (;;) {
+        my ($tag, $tagInfo);
+        if (@tags) {
+            $tag = shift @tags;
+        } elsif (defined $next and not $next) {
+            $tag = 'Next';
+            $next = 1;
+        } else {
+            last;
+        }
+        if ($$tagTablePtr{$tag}) {
+            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        }
+        my $val = $$dict{$tag};
+        if ($verbose) {
+            my ($val2, $extra);
+            if (ref $val eq 'SCALAR') {
+                $extra = ", indirect object ($$val)";
+                if ($fetched{$$val}) {
+                    $val2 = "ref($$val)";
+                } elsif ($tag eq 'Next' and not $next) {
+                    # handle 'Next' links after all others
+                    $next = 0;
+                    next;
+                } else {
+                    $fetched{$$val} = 1;
+                    $val = FetchObject($exifTool, $$val, $xref, $tag);
+                    $val2 = '<err>' unless defined $val;
+                }
+            } elsif (ref $val eq 'HASH') {
+                $extra = ', direct dictionary';
+            } elsif (ref $val eq 'ARRAY') {
+                $extra = ', direct array of ' . scalar(@$val) . ' objects';
+            } else {
+                $extra = ', direct object';
+            }
+            my $isSubdir;
+            if (ref $val eq 'HASH') {
+                $isSubdir = 1;
+            } elsif (ref $val eq 'ARRAY') {
+                # recurse into objects in arrays only if they are lists of
+                # dictionaries or indirect objects which could be dictionaries
+                $isSubdir = 1 if @$val;
+                foreach (@$val) {
+                    next if ref $_ eq 'HASH' or ref $_ eq 'SCALAR';
+                    undef $isSubdir;
+                    last;
+                }
+            }
+            if ($isSubdir) {
+                # create bogus subdirectory to recurse into this dict
+                $tagInfo or $tagInfo = {
+                    Name => $tag,
+                    SubDirectory => {
+                        TagTable => 'Image::ExifTool::PDF::Unknown',
+                    },
+                };
+            } elsif (ref $val eq 'ARRAY') {
+                my @list = @$val;
+                foreach (@list) {
+                    $_ = "ref($$_)" if ref $_ eq 'SCALAR';
+                }
+                $val2 = '[' . join(',',@list) . ']';
+            }
+            $exifTool->VerboseInfo($tag, $tagInfo,
+                Value => $val2 || $val,
+                Extra => $extra,
+                Index => $index++,
+            );
+        }
+        unless ($tagInfo) {
+            # add any tag found in Info directory to table
+            next unless $$tagTablePtr{EXTRACT_UNKNOWN};
+            $tagInfo = { Name => $tag };
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        unless ($$tagInfo{SubDirectory}) {
+            # convert from UTF-16 (big endian) to UTF-8 or Latin if necessary
+            # unless this is binary data (hex-encoded strings would not have been converted)
+            if ($val =~ s/^\xfe\xff// and not $$tagInfo{Binary}) {
+                $val = $exifTool->Unicode2Charset($val, 'MM');
+            }
+            if ($$tagInfo{List}) {
+                # separate tokens in comma or whitespace delimited lists
+                my @values = ($val =~ /,/) ? split /,+\s*/, $val : split ' ', $val;
+                foreach $val (@values) {
+                    $exifTool->FoundTag($tagInfo, $val);
+                }
+            } else {
+                # a tag value
+                $exifTool->FoundTag($tagInfo, $val);
+            }
+            next;
+        }
+        # process the subdirectory
+        my @subDicts;
+        if (ref $val eq 'ARRAY') {
+            @subDicts = @{$val};
+        } else {
+            @subDicts = ( $val );
+        }
+        # loop through all values of this tag
+        for (;;) {
+            my $subDict = shift @subDicts or last;
+            if (ref $subDict eq 'SCALAR') {
+                # load dictionary via an indirect reference
+                $fetched{$$subDict} = 1;
+                $subDict = FetchObject($exifTool, $$subDict, $xref, $tag);
+                $subDict or $exifTool->Warn("Error reading $tag object"), next;
+            }
+            if (ref $subDict eq 'ARRAY') {
+                # convert array of key/value pairs to a hash
+                next if @$subDict < 2;
+                my %hash = ( tags => [] );
+                while (@$subDict >= 2) {
+                    my $key = shift @$subDict;
+                    $key =~ s/^\///;
+                    push @{$hash{tags}}, $key;
+                    $hash{$key} = shift @$subDict;
+                }
+                $subDict = \%hash;
+            } else {
+                next unless ref $subDict eq 'HASH';
+            }
+            my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+            if (not $verbose) {
+                ProcessDict($exifTool, $subTablePtr, $subDict, $xref, $nesting);
+            } elsif ($next) {
+                # handle 'Next' links at this level to avoid deep recursion
+                undef $next;
+                $index = 0;
+                $tagTablePtr = $subTablePtr;
+                $dict = $subDict;
+                @tags = @{$$subDict{tags}};
+                $exifTool->VerboseDir($tag, scalar(@tags));
+            } else {
+                my $oldIndent = $exifTool->{INDENT};
+                my $oldDir = $exifTool->{DIR_NAME};
+                $exifTool->{INDENT} .= '| ';
+                $exifTool->{DIR_NAME} = $tag;
+                $exifTool->VerboseDir($tag, scalar(@{$$subDict{tags}}));
+                ProcessDict($exifTool, $subTablePtr, $subDict, $xref, $nesting);
+                $exifTool->{INDENT} = $oldIndent;
+                $exifTool->{DIR_NAME} = $oldDir;
+            }
+        }
+    }
+#
+# extract information from stream object if it exists
+#
+    return unless $$dict{stream};
+    my $tag = 'stream';
+    # add Subtype (if it exists) to stream name and remove leading '/'
+    ($tag = "$$dict{Subtype}_$tag") =~ s/^\/// if $$dict{Subtype};
+    return unless $$tagTablePtr{$tag};
+    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+    # decode stream if necessary
+    DecodeStream($exifTool, $dict) or return;
+    # extract information from stream
+    my %dirInfo = (
+        DataPt => \$$dict{stream},
+        DataLen => length $$dict{stream},
+        DirStart => 0,
+        DirLen => length $$dict{stream},
+        Parent => 'PDF',
+    );
+    my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+    unless ($exifTool->ProcessDirectory(\%dirInfo, $subTablePtr)) {
+        $exifTool->Warn("Error processing $$tagInfo{Name} information");
+    }
+}
+
+#------------------------------------------------------------------------------
+# Extract information from PDF file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 0 if not a PDF file, 1 on success, otherwise a negative error number
+sub ReadPDF($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->Options('Verbose');
+    my ($data, $encrypt, $id);
+#
+# validate PDF file
+#
+    $raf->Read($data, 4) == 4 or return 0;
+    $data eq '%PDF' or return 0;
+    $exifTool->SetFileType();   # set the FileType tag
+    my $tagTablePtr = GetTagTable('Image::ExifTool::PDF::Main');
+#
+# read the xref tables referenced from startxref at the end of the file
+#
+    my @xrefOffsets;
+    $raf->Seek(0, 2) or return -2;
+    # the %%EOF must occur within the last 1024 bytes of the file (PDF spec, appendix H)
+    my $len = $raf->Tell();
+    $len = 1024 if $len > 1024;
+    $raf->Seek(-$len, 2) or return -2;
+    $raf->Read($data, $len) == $len or return -3;
+    $data =~ /.*startxref(\x0d\x0a|\x0a\x0a|\x0d|\x0a)(\d+)\1%%EOF/s or return -4;
+    $/ = $1;    # set input record separator
+    push @xrefOffsets, $2;
+    my (%xref, @mainDicts, %loaded);
+    while (@xrefOffsets) {
+        my $offset = shift @xrefOffsets;
+        next if $loaded{$offset};   # avoid infinite recursion
+        unless ($raf->Seek($offset, 0)) {
+            %loaded or return -5;
+            $exifTool->Warn('Bad offset for secondary xref table');
+            next;
+        }
+        unless ($raf->ReadLine($data)) {
+            %loaded or return -6;
+            $exifTool->Warn('Bad offset for secondary xref table');
+            next;
+        }
+        my $loadXRefStream;
+        if ($data eq "xref$/") {
+            # load xref table
+            for (;;) {
+                $raf->ReadLine($data) or return -6;
+                last if $data eq "trailer$/";
+                my ($start, $num) = $data =~ /(\d+)\s+(\d+)/;
+                $num or return -4;
+                my $i;
+                for ($i=0; $i<$num; ++$i) {
+                    $raf->Read($data, 20) == 20 or return -6;
+                    $data =~ /^(\d{10}) (\d{5}) (f|n)/ or return -4;
+                    next if $3 eq 'f';  # ignore free entries
+                    # save the object offset keyed by its reference
+                    my $ref = ($start + $i) . ' ' . int($2) . ' R';
+                    $xref{$ref} = int($1);
+                }
+            }
+            %xref or return -4;
+            $data = '';
+        } elsif ($data =~ s/^(\d+)\s+(\d+)\s+obj//) {
+            # this is a PDF-1.5 cross-reference stream dictionary
+            $loadXRefStream = 1;
+        } else {
+            %loaded or return -4;
+            $exifTool->Warn('Invalid secondary xref table');
+            next;
+        }
+        my $mainDict = ExtractObject($exifTool, \$data, $raf, \%xref);
+        unless ($mainDict) {
+            %loaded or return -8;
+            $exifTool->Warn('Error loading secondary dictionary');
+            next;
+        }
+        if ($loadXRefStream) {
+            # decode and save our XRef stream from PDF-1.5 file
+            # (parse it later as required to avoid wasting time)
+            if ($$mainDict{Type} eq '/XRef' and $$mainDict{W} and
+                @{$$mainDict{W}} > 2 and $$mainDict{Size} and
+                DecodeStream($exifTool, $mainDict))
+            {
+                # create Index entry if it doesn't exist
+                $$mainDict{Index} or $$mainDict{Index} = [ 0, $$mainDict{Size} ];
+                # create 'entry_size' entry for internal use
+                my $w = $$mainDict{W};
+                my $size = 0;
+                foreach (@$w) { $size += $_; }
+                $$mainDict{entry_size} = $size;
+                # save this stream dictionary to use later if required
+                $xref{dicts} = [] unless $xref{dicts};
+                push @{$xref{dicts}}, $mainDict;
+            } else {
+                %loaded or return -9;
+                $exifTool->Warn('Invalid xref stream in secondary dictionary');
+            }
+        }
+        $loaded{$offset} = 1;
+        # load XRef stream in hybrid file if it exists
+        push @xrefOffsets, $$mainDict{XRefStm} if $$mainDict{XRefStm};
+        $encrypt = $$mainDict{Encrypt} if $$mainDict{Encrypt};
+        if ($$mainDict{ID} and ref $$mainDict{ID} eq 'ARRAY') {
+            $id = $mainDict->{ID}->[0];
+        }
+        push @mainDicts, $mainDict;
+        # load previous xref table if it exists
+        push @xrefOffsets, $$mainDict{Prev} if $$mainDict{Prev};
+    }
+#
+# extract encryption information if necessary
+#
+    if ($encrypt) {
+        if (ref $encrypt eq 'SCALAR') {
+            $encrypt = FetchObject($exifTool, $$encrypt, \%xref, 'Encrypt');
+        }
+        # generate Encryption tag information
+        my $err = DecryptInit($exifTool, $encrypt, $id);
+        $err and $exifTool->Warn($err), return -1;
+    }
+#
+# extract the information beginning with each of the main dictionaries
+#
+    my $dict;
+    foreach $dict (@mainDicts) {
+        if ($verbose) {
+            my $n = scalar(@{$$dict{tags}});
+            $exifTool->VPrint(0, "PDF dictionary with $n entries:\n");
+        }
+        ProcessDict($exifTool, $tagTablePtr, $dict, \%xref);
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# ReadPDF() warning strings for each error return value
+my %pdfWarning = (
+    # -1 is reserved as error return value with no associated warning
+    -2 => 'Error seeking in file',
+    -3 => 'Error reading file',
+    -4 => 'Invalid xref table',
+    -5 => 'Invalid xref offset',
+    -6 => 'Error reading xref table',
+    -7 => 'Error reading trailer',
+    -8 => 'Error reading main dictionary',
+    -9 => 'Invalid xref stream in main dictionary',
+);
+
+#------------------------------------------------------------------------------
+# Extract information from PDF file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 if this was a valid PDF file
+sub ProcessPDF($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+
+    my $oldsep = $/;
+    my $result = ReadPDF($exifTool, $dirInfo);
+    $/ = $oldsep;   # restore input record separator in case it was changed
+    if ($result < 0) {
+        $exifTool->Warn($pdfWarning{$result}) if $pdfWarning{$result};
+        $result = 1;
+    }
+    # clean up and return
+    undef %warnedOnce;
+    undef %streamObjs;
+    undef %fetched;
+    undef $cryptInfo;
+    return $result;
+}
+
+1; # end
+
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::PDF - Read PDF meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This code reads meta information from PDF (Adobe Portable Document Format)
+files.  It supports object streams introduced in PDF-1.5 but only with a
+limited set of Filter and Predictor algorithms, and it decodes encrypted
+information but only with a limited number of algorithms.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://partners.adobe.com/public/developer/pdf/index_reference.html>
+
+=item L<http://www.cr0.net:8040/code/crypto/rc4/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/PDF Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/PICT.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/PICT.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/PICT.pm	(revision 20131)
@@ -0,0 +1,1260 @@
+#------------------------------------------------------------------------------
+# File:         PICT.pm
+#
+# Description:  Read PICT meta information
+#
+# Revisions:    10/10/2005 - P. Harvey Created
+#
+# Notes:        Extraction of PICT opcodes is still experimental
+#
+# - size difference in PixPat color table?? (imagemagick reads only 1 long per entry)
+# - other differences in the way imagemagick reads 16-bit images
+#
+# References:   1) http://developer.apple.com/documentation/mac/QuickDraw/QuickDraw-2.html
+#               2) http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqImageCompMgr.a.htm
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::PICT;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.03';
+
+sub ReadPictValue($$$;$);
+
+my ($vers, $extended);  # PICT version number, and extended flag
+my ($verbose, $out, $indent); # used in verbose mode
+
+# ranges of reserved opcodes.
+# opcodes at the start of each range must be defined in the tag table
+my @reserved = (
+    0x0017 => 0x0019, 0x0024 => 0x0027, 0x0035 => 0x0037, 0x003d => 0x003f,
+    0x0045 => 0x0047, 0x004d => 0x004f, 0x0055 => 0x0057, 0x005d => 0x005f,
+    0x0065 => 0x0067, 0x006d => 0x006f, 0x0075 => 0x0077, 0x007d => 0x007f,
+    0x0085 => 0x0087, 0x008d => 0x008f, 0x0092 => 0x0097, 0x00a2 => 0x00af,
+    0x00b0 => 0x00cf, 0x00d0 => 0x00fe, 0x0100 => 0x01ff, 0x0300 => 0x0bfe,
+    0x0c01 => 0x7eff, 0x7f00 => 0x7fff, 0x8000 => 0x80ff, 0x8100 => 0x81ff,
+    0x8201 => 0xffff,
+);
+
+# Apple data structures in PICT images
+my %structs = (
+    Arc => [
+        rect => 'Rect',
+        startAng => 'int16s',
+        arcAng => 'int16s',
+    ],
+    BitMap => [
+        # (no baseAddr)
+        rowBytes => 'int16u',
+        bounds => 'Rect',
+    ],
+    # BitsRect data for PICT version 1
+    BitsRect1 => [
+        bitMap => 'BitMap',
+        srcRect => 'Rect',
+        dstRect => 'Rect',
+        mode => 'int16u',
+        dataSize => 'int16u',
+        bitData => 'binary[$val{dataSize}]',
+    ],
+    # BitsRect data for PICT version 2
+    BitsRect2 => [
+        pixMap => 'PixMap',
+        colorTable => 'ColorTable',
+        srcRect => 'Rect',
+        dstRect => 'Rect',
+        mode => 'int16u',
+        pixData => \ 'GetPixData($val{pixMap}, $raf)',
+    ],
+    # BitsRgn data for PICT version 1
+    BitsRgn1 => [
+        bitMap => 'BitMap',
+        srcRect => 'Rect',
+        dstRect => 'Rect',
+        mode => 'int16u',
+        maskRgn => 'Rgn',
+        dataSize => 'int16u',
+        bitData => 'binary[$val{dataSize}]',
+    ],
+    # BitsRgn data for PICT version 2
+    BitsRgn2 => [
+        pixMap => 'PixMap',
+        colorTable => 'ColorTable',
+        srcRect => 'Rect',
+        dstRect => 'Rect',
+        mode => 'int16u',
+        maskRgn => 'Rgn',
+        pixData => \ 'GetPixData($val{pixMap}, $raf)',
+    ],
+    ColorSpec => [
+        value => 'int16u',
+        rgb => 'RGBColor',
+    ],
+    ColorTable => [
+        ctSeed => 'int32u',
+        ctFlags => 'int16u',
+        ctSize => 'int16u',
+        ctTable => 'ColorSpec[$val{ctSize}+1]',
+    ],
+    # http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqImageCompMgr.a.htm
+    CompressedQuickTime => [
+        size => 'int32u',   # size NOT including size word
+        version => 'int16u',
+        matrix => 'int32u[9]',
+        matteSize => 'int32u',
+        matteRect => 'Rect',
+        mode => 'int16u',
+        srcRect => 'Rect',
+        accuracy => 'int32u',
+        maskSize => 'int32u',
+        matteDescr => 'Int32uData[$val{matteSize} ? 1 : 0]',
+        matteData => 'int8u[$val{matteSize}]',
+        maskRgn => 'int8u[$val{maskSize}]',
+        imageDescr => 'ImageDescription',
+        # size should be $val{imageDescr}->{dataSize}, but this is unreliable
+        imageData => q{binary[$val{size} - 68 - $val{maskSize} - $val{imageDescr}->{size} -
+                    ($val{matteSize} ? $val{mattSize} + $val{matteDescr}->{size} : 0)]
+        },
+    ],
+    DirectBitsRect => [
+        baseAddr => 'int32u',
+        pixMap => 'PixMap',
+        srcRect => 'Rect',
+        dstRect => 'Rect',
+        mode => 'int16u',
+        pixData => \ 'GetPixData($val{pixMap}, $raf)',
+    ],
+    DirectBitsRgn => [
+        baseAddr => 'int32u',
+        pixMap => 'PixMap',
+        srcRect => 'Rect',
+        dstRect => 'Rect',
+        mode => 'int16u',
+        maskRgn => 'Rgn',
+        pixData => \ 'GetPixData($val{pixMap}, $raf)',
+    ],
+    # http://developer.apple.com/technotes/qd/qd_01.html
+    FontName => [
+        size => 'int16u',   # size NOT including size word
+        oldFontID => 'int16u',
+        nameLen => 'int8u',
+        fontName => 'string[$val{nameLen}]',
+        padding => 'binary[$val{size} - $val{nameLen} - 3]',
+    ],
+    # http://developer.apple.com/documentation/QuickTime/APIREF/imagedescription.htm
+    ImageDescription => [
+        size => 'int32u',   # size INCLUDING size word
+        cType => 'string[4]',
+        res1 => 'int32u',
+        res2 => 'int16u',
+        dataRefIndex => 'int16u',
+        version => 'int16u',
+        revision => 'int16u',
+        vendor => 'string[4]',
+        temporalQuality => 'int32u',
+        quality => 'int32u',
+        width => 'int16u',
+        height => 'int16u',
+        hRes => 'fixed32u',
+        vRes => 'fixed32u',
+        dataSize => 'int32u',
+        frameCount => 'int16u',
+        nameLen => 'int8u',
+        compressor => 'string[31]',
+        depth => 'int16u',
+        clutID => 'int16u',
+        clutData => 'binary[$val{size}-86]',
+    ],
+    Int8uText => [
+        val => 'int8u',
+        count => 'int8u',
+        text => 'string[$val{count}]',
+    ],
+    Int8u2Text => [
+        val => 'int8u[2]',
+        count => 'int8u',
+        text => 'string[$val{count}]',
+    ],
+    Int16Data => [
+        size => 'int16u',   # size NOT including size word
+        data => 'int8u[$val{size}]',
+    ],
+    Int32uData => [
+        size => 'int32u',   # size NOT including size word
+        data => 'int8u[$val{size}]',
+    ],
+    LongComment => [
+        kind => 'int16u',
+        size => 'int16u',   # size of data only
+        data => 'binary[$val{size}]',
+    ],
+    PixMap => [
+        # Note: does not contain baseAddr
+        # (except for DirectBits opcodes in which it is loaded separately)
+        rowBytes => 'int16u',
+        bounds => 'Rect',
+        pmVersion => 'int16u',
+        packType => 'int16u',
+        packSize => 'int32u',
+        hRes => 'fixed32s',
+        vRes => 'fixed32s',
+        pixelType => 'int16u',
+        pixelSize => 'int16u',
+        cmpCount => 'int16u',
+        cmpSize => 'int16u',
+        planeBytes => 'int32u',
+        pmTable => 'int32u',
+        pmReserved => 'int32u',
+    ],
+    PixPat => [
+        patType => 'int16u',    # 1 = non-dithered, 2 = dithered
+        pat1Data => 'int8u[8]',
+        # dithered PixPat has RGB entry
+        RGB => 'RGBColor[$val{patType} == 2 ? 1 : 0]',
+        # non-dithered PixPat has other stuff instead
+        nonDithered=> 'PixPatNonDithered[$val{patType} == 2 ? 0 : 1]',
+    ],
+    PixPatNonDithered => [
+        pixMap => 'PixMap',
+        colorTable => 'ColorTable',
+        pixData => \ 'GetPixData($val{pixMap}, $raf)',
+    ],
+    Point => [
+        v => 'int16s',
+        h => 'int16s',
+    ],
+    PointText => [
+        txLoc => 'Point',
+        count => 'int8u',
+        text => 'string[$val{count}]',
+    ],
+    Polygon => [
+        polySize => 'int16u',
+        polyBBox => 'Rect',
+        polyPoints => 'int16u[($val{polySize}-10)/2]',
+    ],
+    Rect => [
+        topLeft => 'Point',
+        botRight => 'Point',
+    ],
+    RGBColor => [
+        red => 'int16u',
+        green => 'int16u',
+        blue => 'int16u',
+    ],
+    Rgn => [
+        rgnSize => 'int16u',
+        rgnBBox => 'Rect',
+        data => 'int8u[$val{rgnSize}-10]',
+    ],
+    ShortLine => [
+        pnLoc => 'Point',
+        dh => 'int8s',
+        dv => 'int8s',
+    ],
+    # http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqImageCompMgr.a.htm
+    UncompressedQuickTime => [
+        size => 'int32u',   # size NOT including size word
+        version => 'int16u',
+        matrix => 'int32u[9]',
+        matteSize => 'int32u',
+        matteRect => 'Rect',
+        matteDescr => 'Int32uData[$val{matteSize} ? 1 : 0]',
+        matteData => 'binary[$val{matteSize}]',
+        subOpcodeData => q{
+            binary[ $val{size} - 50 -
+                    ($val{matteSize} ? $val{mattSize} + $val{matteDescr}->{size} : 0)]
+        },
+    ],
+);
+
+# PICT image opcodes
+%Image::ExifTool::PICT::Main = (
+    PROCESS_PROC => 0,  # set this to zero to omit tags from lookup
+    NOTES => q{
+The PICT format contains no true meta information, except for the possible
+exception of the LongComment opcode.  By default, only ImageWidth,
+ImageHeight and X/YResolution are extracted from a PICT image.  Tags in the
+following table represent image opcodes.  Extraction of these tags is
+experimental, and is only enabled with the Verbose or Unknown options.
+    },
+    0x0000 => {
+        Name => 'Nop',
+        Description => 'No Operation',
+        Format => 'null',
+    },
+    0x0001 => {
+        Name => 'ClipRgn',
+        Description => 'Clipping Region',
+        Format => 'Rgn',
+    },
+    0x0002 => {
+        Name => 'BkPat',
+        Description => 'Background Pattern',
+        Format => 'int8u[8]',
+    },
+    0x0003 => {
+        Name => 'TxFont',
+        Description => 'Font Number',
+        Format => 'int16u',
+    },
+    0x0004 => {
+        Name => 'TxFace',
+        Description => 'Text Font Style',
+        Format => 'int8u',
+    },
+    0x0005 => {
+        Name => 'TxMode',
+        Description => 'Text Source Mode',
+        Format => 'int16u',
+    },
+    0x0006 => {
+        Name => 'SpExtra',
+        Description => 'Extra Space',
+        Format => 'fixed32s',
+    },
+    0x0007 => {
+        Name => 'PnSize',
+        Description => 'Pen Size',
+        Format => 'Point',
+    },
+    0x0008 => {
+        Name => 'PnMode',
+        Description => 'Pen Mode',
+        Format => 'int16u',
+    },
+    0x0009 => {
+        Name => 'PnPat',
+        Description => 'Pen Pattern',
+        Format => 'int8u[8]',
+    },
+    0x000a => {
+        Name => 'FillPat',
+        Description => 'Fill Pattern',
+        Format => 'int8u[8]',
+    },
+    0x000b => {
+        Name => 'OvSize',
+        Description => 'Oval Size',
+        Format => 'Point',
+    },
+    0x000c => {
+        Name => 'Origin',
+        Format => 'Point',
+    },
+    0x000d => {
+        Name => 'TxSize',
+        Description => 'Text Size',
+        Format => 'int16u',
+    },
+    0x000e => {
+        Name => 'FgColor',
+        Description => 'Foreground Color',
+        Format => 'int32u',
+    },
+    0x000f => {
+        Name => 'BkColor',
+        Description => 'Background Color',
+        Format => 'int32u',
+    },
+    0x0010 => {
+        Name => 'TxRatio',
+        Description => 'Text Ratio',
+        Format => 'Rect',
+    },
+    0x0011 => {
+        Name => 'VersionOp',
+        Description => 'Version',
+        Format => 'int8u',
+    },
+    0x0012 => {
+        Name => 'BkPixPat',
+        Description => 'Background Pixel Pattern',
+        Format => 'PixPat',
+    },
+    0x0013 => {
+        Name => 'PnPixPat',
+        Description => 'Pen Pixel Pattern',
+        Format => 'PixPat',
+    },
+    0x0014 => {
+        Name => 'FillPixPat',
+        Description => 'Fill Pixel Pattern',
+        Format => 'PixPat',
+    },
+    0x0015 => {
+        Name => 'PnLocHFrac',
+        Description => 'Fractional Pen Position',
+        Format => 'int16u',
+    },
+    0x0016 => {
+        Name => 'ChExtra',
+        Description => 'Added Width for NonSpace Characters',
+        Format => 'int16u',
+    },
+    0x0017 => {
+        Name => 'Reserved',
+        Format => 'Unknown',
+    },
+    0x001a => {
+        Name => 'RGBFgCol',
+        Description => 'Foreground Color',
+        Format => 'RGBColor',
+    },
+    0x001b => {
+        Name => 'RGBBkCol',
+        Description => 'Background Color',
+        Format => 'RGBColor',
+    },
+    0x001c => {
+        Name => 'HiliteMode',
+        Description => 'Highlight Mode Flag',
+        Format => 'null',
+    },
+    0x001d => {
+        Name => 'HiliteColor',
+        Description => 'Highlight Color',
+        Format => 'RGBColor',
+    },
+    0x001e => {
+        Name => 'DefHilite',
+        Description => 'Use Default Highlight Color',
+        Format => 'null',
+    },
+    0x001f => {
+        Name => 'OpColor',
+        Format => 'RGBColor',
+    },
+    0x0020 => {
+        Name => 'Line',
+        Format => 'Rect',
+    },
+    0x0021 => {
+        Name => 'LineFrom',
+        Format => 'Point',
+    },
+    0x0022 => {
+        Name => 'ShortLine',
+        Format => 'ShortLine',
+    },
+    0x0023 => {
+        Name => 'ShortLineFrom',
+        Format => 'int8u[2]',
+    },
+    0x0024 => {
+        Name => 'Reserved',
+        Format => 'Int16Data',
+    },
+    0x0028 => {
+        Name => 'LongText',
+        Format => 'PointText',
+    },
+    0x0029 => {
+        Name => 'DHText',
+        Format => 'Int8uText',
+    },
+    0x002a => {
+        Name => 'DVText',
+        Format => 'Int8uText',
+    },
+    0x002b => {
+        Name => 'DHDVText',
+        Format => 'Int8u2Text',
+    },
+    0x002c => {
+        Name => 'FontName',
+        Format => 'FontName',
+    },
+    0x002d => {
+        Name => 'LineJustify',
+        Format => 'int8u[10]',
+    },
+    0x002e => {
+        Name => 'GlyphState',
+        Format => 'int8u[8]',
+    },
+    0x002f => {
+        Name => 'Reserved',
+        Format => 'Int16Data',
+    },
+    0x0030 => {
+        Name => 'FrameRect',
+        Format => 'Rect',
+    },
+    0x0031 => {
+        Name => 'PaintRect',
+        Format => 'Rect',
+    },
+    0x0032 => {
+        Name => 'EraseRect',
+        Format => 'Rect',
+    },
+    0x0033 => {
+        Name => 'InvertRect',
+        Format => 'Rect',
+    },
+    0x0034 => {
+        Name => 'FillRect',
+        Format => 'Rect',
+    },
+    0x0035 => {
+        Name => 'Reserved',
+        Format => 'Rect',
+    },
+    0x0038 => {
+        Name => 'FrameSameRect',
+        Format => 'null',
+    },
+    0x0039 => {
+        Name => 'PaintSameRect',
+        Format => 'null',
+    },
+    0x003a => {
+        Name => 'EraseSameRect',
+        Format => 'null',
+    },
+    0x003b => {
+        Name => 'InvertSameRect',
+        Format => 'null',
+    },
+    0x003c => {
+        Name => 'FillSameRect',
+        Format => 'null',
+    },
+    0x003d => {
+        Name => 'Reserved',
+        Format => 'null',
+    },
+    0x0040 => {
+        Name => 'FrameRRect',
+        Format => 'Rect',
+    },
+    0x0041 => {
+        Name => 'PaintRRect',
+        Format => 'Rect',
+    },
+    0x0042 => {
+        Name => 'EraseRRect',
+        Format => 'Rect',
+    },
+    0x0043 => {
+        Name => 'InvertRRect',
+        Format => 'Rect',
+    },
+    0x0044 => {
+        Name => 'FillRRect',
+        Format => 'Rect',
+    },
+    0x0045 => {
+        Name => 'Reserved',
+        Format => 'Rect',
+    },
+    0x0048 => {
+        Name => 'FrameSameRRect',
+        Format => 'null',
+    },
+    0x0049 => {
+        Name => 'PaintSameRRect',
+        Format => 'null',
+    },
+    0x004a => {
+        Name => 'EraseSameRRect',
+        Format => 'null',
+    },
+    0x004b => {
+        Name => 'InvertSameRRect',
+        Format => 'null',
+    },
+    0x004c => {
+        Name => 'FillSameRRect',
+        Format => 'null',
+    },
+    0x004d => {
+        Name => 'Reserved',
+        Format => 'null',
+    },
+    0x0050 => {
+        Name => 'FrameOval',
+        Format => 'Rect',
+    },
+    0x0051 => {
+        Name => 'PaintOval',
+        Format => 'Rect',
+    },
+    0x0052 => {
+        Name => 'EraseOval',
+        Format => 'Rect',
+    },
+    0x0053 => {
+        Name => 'InvertOval',
+        Format => 'Rect',
+    },
+    0x0054 => {
+        Name => 'FillOval',
+        Format => 'Rect',
+    },
+    0x0055 => {
+        Name => 'Reserved',
+        Format => 'Rect',
+    },
+    0x0058 => {
+        Name => 'FrameSameOval',
+        Format => 'null',
+    },
+    0x0059 => {
+        Name => 'PaintSameOval',
+        Format => 'null',
+    },
+    0x005a => {
+        Name => 'EraseSameOval',
+        Format => 'null',
+    },
+    0x005b => {
+        Name => 'InvertSameOval',
+        Format => 'null',
+    },
+    0x005c => {
+        Name => 'FillSameOval',
+        Format => 'null',
+    },
+    0x005d => {
+        Name => 'Reserved',
+        Format => 'null',
+    },
+    0x0060 => {
+        Name => 'FrameArc',
+        Format => 'Arc',
+    },
+    0x0061 => {
+        Name => 'PaintArc',
+        Format => 'Arc',
+    },
+    0x0062 => {
+        Name => 'EraseArc',
+        Format => 'Arc',
+    },
+    0x0063 => {
+        Name => 'InvertArc',
+        Format => 'Arc',
+    },
+    0x0064 => {
+        Name => 'FillArc',
+        Format => 'Arc',
+    },
+    0x0065 => {
+        Name => 'Reserved',
+        Format => 'Arc',
+    },
+    0x0068 => {
+        Name => 'FrameSameArc',
+        Format => 'Point',
+    },
+    0x0069 => {
+        Name => 'PaintSameArc',
+        Format => 'Point',
+    },
+    0x006a => {
+        Name => 'EraseSameArc',
+        Format => 'Point',
+    },
+    0x006b => {
+        Name => 'InvertSameArc',
+        Format => 'Point',
+    },
+    0x006c => {
+        Name => 'FillSameArc',
+        Format => 'Point',
+    },
+    0x006d => {
+        Name => 'Reserved',
+        Format => 'int32u',
+    },
+    0x0070 => {
+        Name => 'FramePoly',
+        Format => 'Polygon',
+    },
+    0x0071 => {
+        Name => 'PaintPoly',
+        Format => 'Polygon',
+    },
+    0x0072 => {
+        Name => 'ErasePoly',
+        Format => 'Polygon',
+    },
+    0x0073 => {
+        Name => 'InvertPoly',
+        Format => 'Polygon',
+    },
+    0x0074 => {
+        Name => 'FillPoly',
+        Format => 'Polygon',
+    },
+    0x0075 => {
+        Name => 'Reserved',
+        Format => 'Polygon',
+    },
+    0x0078 => {
+        Name => 'FrameSamePoly',
+        Format => 'null',
+    },
+    0x0079 => {
+        Name => 'PaintSamePoly',
+        Format => 'null',
+    },
+    0x007a => {
+        Name => 'EraseSamePoly',
+        Format => 'null',
+    },
+    0x007b => {
+        Name => 'InvertSamePoly',
+        Format => 'null',
+    },
+    0x007c => {
+        Name => 'FillSamePoly',
+        Format => 'null',
+    },
+    0x007d => {
+        Name => 'Reserved',
+        Format => 'null',
+    },
+    0x0080 => {
+        Name => 'FrameRgn',
+        Format => 'Rgn',
+    },
+    0x0081 => {
+        Name => 'PaintRgn',
+        Format => 'Rgn',
+    },
+    0x0082 => {
+        Name => 'EraseRgn',
+        Format => 'Rgn',
+    },
+    0x0083 => {
+        Name => 'InvertRgn',
+        Format => 'Rgn',
+    },
+    0x0084 => {
+        Name => 'FillRgn',
+        Format => 'Rgn',
+    },
+    0x0085 => {
+        Name => 'Reserved',
+        Format => 'Rgn',
+    },
+    0x0088 => {
+        Name => 'FrameSameRgn',
+        Format => 'null',
+    },
+    0x0089 => {
+        Name => 'PaintSameRgn',
+        Format => 'null',
+    },
+    0x008a => {
+        Name => 'EraseSameRgn',
+        Format => 'null',
+    },
+    0x008b => {
+        Name => 'InvertSameRgn',
+        Format => 'null',
+    },
+    0x008c => {
+        Name => 'FillSameRgn',
+        Format => 'null',
+    },
+    0x008d => {
+        Name => 'Reserved',
+        Format => 'null',
+    },
+    0x0090 => {
+        Name => 'BitsRect',
+        Description => 'CopyBits with Clipped Rectangle',
+        Format => 'BitsRect#',  # (version-dependent format)
+    },
+    0x0091 => {
+        Name => 'BitsRgn',
+        Description => 'CopyBits with Clipped Region',
+        Format => 'BitsRgn#',   # (version-dependent format)
+    },
+    0x0092 => {
+        Name => 'Reserved',
+        Format => 'Int16Data',
+    },
+    0x0098 => {
+        Name => 'PackBitsRect',
+        Description => 'Packed CopyBits with Clipped Rectangle',
+        Format => 'BitsRect#',  # (version-dependent format)
+    },
+    0x0099 => {
+        Name => 'PackBitsRgn',
+        Description => 'Packed CopyBits with Clipped Region',
+        Format => 'BitsRgn#',   # (version-dependent format)
+    },
+    0x009a => {
+        Name => 'DirectBitsRect',
+        Format => 'DirectBitsRect',
+    },
+    0x009b => {
+        Name => 'DirectBitsRgn',
+        Format => 'DirectBitsRgn',
+    },
+    0x009c => {
+        Name => 'Reserved',
+        Format => 'Int16Data',
+    },
+    0x009d => {
+        Name => 'Reserved',
+        Format => 'Int16Data',
+    },
+    0x009e => {
+        Name => 'Reserved',
+        Format => 'Int16Data',
+    },
+    0x009f => {
+        Name => 'Reserved',
+        Format => 'Int16Data',
+    },
+    0x00a0 => {
+        Name => 'ShortComment',
+        Format => 'int16u',
+    },
+    0x00a1 => [
+        # this list for documentation only [not currently extracted]
+        {
+            # (not actually a full Photohop IRB record it appears, but it does start
+            #  with '8BIM', and does contain resolution information at offset 0x0a)
+            Name => 'LongComment',  # kind = 498
+            Format => 'LongComment',
+            SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::Main' },
+        },
+        {
+            Name => 'LongComment',  # kind = 224
+            Format => 'LongComment',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::ICC_Profile::Main',
+                Start => '$valuePtr + 4',
+            },
+        },
+    ],
+    0x00a2 => {
+        Name => 'Reserved',
+        Format => 'Int16Data',
+    },
+    0x00b0 => {
+        Name => 'Reserved',
+        Format => 'null',
+    },
+    0x00d0 => {
+        Name => 'Reserved',
+        Format => 'Int32uData',
+    },
+    0x00ff => {
+        Name => 'OpEndPic',
+        Description => 'End of picture',
+        Format => 'null', # 2 for version 2!?
+    },
+    0x0100 => {
+        Name => 'Reserved',
+        Format => 'int16u',
+    },
+    0x0200 => {
+        Name => 'Reserved',
+        Format => 'int32u',
+    },
+    0x02ff => {
+        Name => 'Version',
+        Description => 'Version number of picture',
+        Format => 'int16u',
+    },
+    0x0300 => {
+        Name => 'Reserved',
+        Format => 'int16u',
+    },
+    0x0bff => {
+        Name => 'Reserved',
+        Format => 'int8u[22]',
+    },
+    0x0c00 => {
+        Name => 'HeaderOp',
+        Format => 'int16u[12]',
+    },
+    0x0c01 => {
+        Name => 'Reserved',
+        Format => 'int8u[24]',
+    },
+    0x7f00 => {
+        Name => 'Reserved',
+        Format => 'int8u[254]',
+    },
+    0x8000 => {
+        Name => 'Reserved',
+        Format => 'null',
+    },
+    0x8100 => {
+        Name => 'Reserved',
+        Format => 'Int32uData',
+    },
+    0x8200 => {
+        Name => 'CompressedQuickTime',
+        Format => 'CompressedQuickTime',
+    },
+    0x8201 => {
+        Name => 'UncompressedQuickTime',
+        Format => 'Int32uData',
+    },
+    0xffff => {
+        Name => 'Reserved',
+        Format => 'Int32uData',
+    },
+);
+
+# picture comment 'kind' codes
+# http://developer.apple.com/technotes/qd/qd_10.html
+my %commentKind = (
+    150 => 'TextBegin',
+    151 => 'TextEnd',
+    152 => 'StringBegin',
+    153 => 'StringEnd',
+    154 => 'TextCenter',
+    155 => 'LineLayoutOff',
+    156 => 'LineLayoutOn',
+    157 => 'ClientLineLayout',
+    160 => 'PolyBegin',
+    161 => 'PolyEnd',
+    163 => 'PolyIgnore',
+    164 => 'PolySmooth',
+    165 => 'PolyClose',
+    180 => 'DashedLine',
+    181 => 'DashedStop',
+    182 => 'SetLineWidth',
+    190 => 'PostScriptBegin',
+    191 => 'PostScriptEnd',
+    192 => 'PostScriptHandle',
+    193 => 'PostScriptFile',
+    194 => 'TextIsPostScript',
+    195 => 'ResourcePS',
+    196 => 'PSBeginNoSave',
+    197 => 'SetGrayLevel',
+    200 => 'RotateBegin',
+    201 => 'RotateEnd',
+    202 => 'RotateCenter',
+    210 => 'FormsPrinting',
+    211 => 'EndFormsPrinting',
+    224 => '<ICC Profile>',
+    498 => '<Photoshop Data>',
+    1000 => 'BitMapThinningOff',
+    1001 => 'BitMapThinningOn',
+);
+
+#------------------------------------------------------------------------------
+# Get PixData data
+# Inputs: 0) reference to PixMap, 1) RAF reference
+# Returns: reference to PixData or undef on error
+sub GetPixData($$)
+{
+    my ($pixMap, $raf) = @_;
+    my $packType = $pixMap->{packType};
+    my $rowBytes = $pixMap->{rowBytes} & 0x3fff;    # remove flags bits
+    my $height = $pixMap->{bounds}->{botRight}->{v} -
+                 $pixMap->{bounds}->{topLeft}->{v};
+    my ($data, $size, $buff, $i);
+
+    if ($packType == 1 or $rowBytes < 8) {  # unpacked data
+        $size = $rowBytes * $height;
+        return undef unless $raf->Read($data, $size) == $size;
+    } elsif ($packType == 2) {              # pad byte dropped
+        $size = int($rowBytes * $height * 3 / 4 + 0.5);
+        return undef unless $raf->Read($data, $size) == $size;
+    } else {
+        $data = '';
+        for ($i=0; $i<$height; ++$i) {
+            if ($rowBytes > 250) {
+                $raf->Read($buff,2) == 2 or return undef;
+                $size = unpack('n',$buff);
+            } else {
+                $raf->Read($buff,1) == 1 or return undef;
+                $size = unpack('C',$buff);
+            }
+            $data .= $buff;
+            $raf->Read($buff,$size) == $size or return undef;
+            $data .= $buff;
+        }
+    }
+    return \$data;
+}
+
+#------------------------------------------------------------------------------
+# Read value from PICT file
+# Inputs: 0) RAF reference, 1) tag, 2) format, 3) optional count
+# Returns: value, reference to structure hash, or undef on error
+sub ReadPictValue($$$;$)
+{
+    my ($raf, $tag, $format, $count) = @_;
+    return undef unless $format;
+    unless (defined $count) {
+        if ($format =~ /(.+)\[(.+)\]/s) {
+            $format = $1;
+            $count = $2;
+        } else {
+            $count = 1; # count undefined: assume 1
+        }
+    }
+    my $cntStr = ($count == 1) ? '' : "[$count]";
+    # no size if count is 0
+    my $size = $count ? Image::ExifTool::FormatSize($format) : 0;
+    if (defined $size or $format eq 'null') {
+        my $val;
+        if ($size) {
+            my $buff;
+            $size *= $count;
+            $raf->Read($buff, $size) == $size or return undef;
+            $val = ReadValue(\$buff, 0, $format, $count, $size);
+        } else {
+            $val = '';
+        }
+        if ($verbose) {
+            print $out "${indent}$tag ($format$cntStr)";
+            if ($size) {
+                if (not defined $val) {
+                    print $out " = <undef>\n";
+                } elsif ($format eq 'binary') {
+                    print $out " = <binary data>\n";
+                    if ($verbose > 2) {
+                        my %parms = ( Out => $out );
+                        $parms{MaxLen} = 96 if $verbose < 4;
+                        Image::ExifTool::HexDump(\$val, undef, %parms);
+                    }
+                } else {
+                    print $out " = $val\n";
+                }
+            } else {
+                print $out "\n";
+            }
+        }
+        return \$val if $format eq 'binary' and defined $val;
+        return $val;
+    }
+    $verbose and print $out "${indent}$tag ($format$cntStr):\n";
+    my $struct = $structs{$format} or return undef;
+    my ($c, @vals);
+    for ($c=0; $c<$count; ++$c) {
+        my (%val, $i);
+        for ($i=0; ; $i+=2) {
+            my $tag = $$struct[$i] or last;
+            my $fmt = $$struct[$i+1];
+            my ($cnt, $val);
+            $indent .= '  ';
+            if (ref $fmt) {
+                $val = eval $$fmt;
+                $@ and warn $@;
+                if ($verbose and defined $val) {
+                    printf $out "${indent}$tag (binary[%d]) = <binary data>\n",length($$val);
+                    if ($verbose > 2) {
+                        my %parms = ( Out => $out );
+                        $parms{MaxLen} = 96 if $verbose < 4;
+                        Image::ExifTool::HexDump($val, undef, %parms);
+                    }
+                }
+            } elsif ($fmt =~ /(.+)\[(.+)\]/s) {
+                $fmt = $1;
+                $cnt = eval $2;
+                $@ and warn $@;
+                $val = ReadPictValue($raf, $tag, $fmt, $cnt);
+            } else {
+                $val = ReadPictValue($raf, $tag, $fmt);
+            }
+            $indent = substr($indent, 2);
+            return undef unless defined $val;
+            $val{$tag} = $val;
+        }
+        return \%val if $count == 1;
+        push @vals, \%val;
+    }
+    return \@vals;
+}
+
+#------------------------------------------------------------------------------
+# Extract meta information from a PICT image
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid PICT image
+sub ProcessPICT($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    $verbose = $exifTool->Options('Verbose');
+    $out = $exifTool->Options('TextOut');
+    $indent = '';
+    my ($buff, $tried, @hdr, $op, $hRes, $vRes);
+
+    # recognize both PICT files and PICT resources (PICT files have a
+    # 512-byte header that we ignore, but PICT resources do not)
+    for (;;) {
+        $raf->Read($buff, 12) == 12 or return 0;
+        @hdr = unpack('x2n5', $buff);
+        $op = pop @hdr;
+        # check for PICT version 1 format
+        if ($op eq 0x1101) {
+            $vers = 1;
+            undef $extended;
+            last;
+        }
+        # check for PICT version 2 format
+        if ($op eq 0x0011) {
+            $raf->Read($buff, 28) == 28 or return 0;
+            if ($buff =~ /^\x02\xff\x0c\x00\xff\xff/) {
+                $vers = 2;
+                undef $extended;
+                last;
+            }
+            if ($buff =~ /^\x02\xff\x0c\x00\xff\xfe/) {
+                $vers = 2;
+                $extended = 1;
+                ($hRes, $vRes) = unpack('x8N2', $buff);
+                last;
+            }
+        }
+        return 0 if $tried;
+        $tried = 1;
+        $raf->Seek(512, 0) or return 0;
+    }
+    # make the bounding rect signed
+    foreach (@hdr) {
+        $_ >= 0x8000 and $_ -= 0x10000;
+    }
+    my $w = $hdr[3] - $hdr[1];
+    my $h = $hdr[2] - $hdr[0];
+    return 0 unless $w > 0 and $h > 0;
+
+    SetByteOrder('MM');
+
+    if ($extended) {
+        # extended version 2 pictures contain resolution information
+        # and image bounds are in 72-dpi equivalent units
+        $hRes = GetFixed32s(\$buff, 8);
+        $vRes = GetFixed32s(\$buff, 12);
+        return 0 unless $hRes and $vRes;
+        $w = int($w * $hRes / 72 + 0.5);
+        $h = int($h * $vRes / 72 + 0.5);
+    }
+    $exifTool->SetFileType();
+    $exifTool->FoundTag('ImageWidth', $w);
+    $exifTool->FoundTag('ImageHeight', $h);
+    $exifTool->FoundTag('XResolution', $hRes) if $hRes;
+    $exifTool->FoundTag('YResolution', $vRes) if $vRes;
+
+    # don't extract image opcodes unless verbose
+    return 1 unless $verbose or $exifTool->Options('Unknown');
+
+    $verbose and printf $out "PICT version $vers%s\n", $extended ? ' extended' : '';
+
+    my $tagTablePtr = GetTagTable('Image::ExifTool::PICT::Main');
+
+    my $success;
+    for (;;) {
+        if ($vers == 1) {
+            $raf->Read($buff, 1) == 1 or last;
+            $op = ord($buff);
+        } else {
+            # must start version 2 opcode on an even byte
+            $raf->Read($buff, 1) if $raf->Tell() & 0x01;
+            $raf->Read($buff, 2) == 2 or last;
+            $op = unpack('n', $buff);
+        }
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $op);
+        unless ($tagInfo) {
+            my $i;
+            # search for reserved tag info
+            for ($i=0; $i<scalar(@reserved); $i+=2) {
+                next unless $op >= $reserved[$i];
+                last if $op > $reserved[$i+1];
+                $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $reserved[$i]);
+                last;
+            }
+            last unless $tagInfo;
+        }
+        if ($op eq 0xff) {
+            $verbose and print $out "End of picture\n";
+            $success = 1;
+            last;
+        }
+        my $format = $$tagInfo{Format};
+        unless ($format) {
+            $exifTool->Warn("Missing format for $$tagInfo{Name}");
+            last;
+        }
+        # replace version number for version-dependent formats
+        $format =~ s/#$/$vers/;
+        my $wid = $vers * 2;
+        $verbose and printf $out "Tag 0x%.${wid}x, ", $op;
+        my $val = ReadPictValue($raf, $$tagInfo{Name}, $format);
+        unless (defined $val) {
+            $exifTool->Warn("Error reading $$tagInfo{Name} information");
+            last;
+        }
+        if (ref $val eq 'HASH') {
+            # extract JPEG image from CompressedQuickTime imageData
+            if ($$tagInfo{Name} eq 'CompressedQuickTime' and
+                ref $val->{imageDescr} eq 'HASH' and
+                $val->{imageDescr}->{compressor} and
+                $val->{imageDescr}->{compressor} eq 'Photo - JPEG' and
+                ref $val->{imageData} eq 'SCALAR' and
+                $exifTool->ValidateImage($val->{imageData}, 'PreviewImage'))
+            {
+                $exifTool->FoundTag('PreviewImage', $val->{imageData});
+            }
+        } else {
+            # $exifTool->FoundTag($tagInfo, $val);
+        }
+    }
+    $success or $exifTool->Warn('End of picture not found');
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::PICT - Read PICT meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to read PICT
+(Apple Picture) images.
+
+=head1 NOTES
+
+Extraction of PICT opcodes is experimental, and is only enabled with the
+Verbose or the Unknown option.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://developer.apple.com/documentation/mac/QuickDraw/QuickDraw-2.html>
+
+=item L<http://developer.apple.com/documentation/QuickTime/INMAC/QT/iqImageCompMgr.a.htm>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/PICT Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/PNG.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/PNG.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/PNG.pm	(revision 20131)
@@ -0,0 +1,941 @@
+#------------------------------------------------------------------------------
+# File:         PNG.pm
+#
+# Description:  Read and write PNG meta information
+#
+# Revisions:    06/10/2005 - P. Harvey Created
+#               06/23/2005 - P. Harvey Added MNG and JNG support
+#               09/16/2005 - P. Harvey Added write support
+#
+# References:   1) http://www.libpng.org/pub/png/spec/1.2/
+#               2) http://www.faqs.org/docs/png/
+#               3) http://www.libpng.org/pub/mng/
+#               4) http://www.libpng.org/pub/png/spec/register/
+#
+# Notes:        I haven't found a sample PNG image with a 'iTXt' chunk, so
+#               this part of the code is still untested.
+#
+#               Writing meta information in PNG images is a pain in the butt
+#               for a number of reasons:  One biggie is that you have to
+#               decompress then decode the ASCII/hex profile information before
+#               you can edit it, then you have to ASCII/hex-encode, recompress
+#               and calculate a CRC before you can write it out again.  gaaaak.
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::PNG;
+
+use strict;
+use vars qw($VERSION $AUTOLOAD);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.15';
+
+sub ProcessPNG_tEXt($$$);
+sub ProcessPNG_iTXt($$$);
+sub ProcessPNG_Compressed($$$);
+sub CalculateCRC($;$$$);
+sub HexEncode($);
+sub AddChunks($$);
+sub Add_iCCP($$);
+
+my $noCompressLib;
+
+# look up for file type, header chunk and end chunk, based on file signature
+my %pngLookup = (
+    "\x89PNG\r\n\x1a\n" => ['PNG', 'IHDR', 'IEND' ],
+    "\x8aMNG\r\n\x1a\n" => ['MNG', 'MHDR', 'MEND' ],
+    "\x8bJNG\r\n\x1a\n" => ['JNG', 'JHDR', 'IEND' ],
+);
+
+# color type of current image
+$Image::ExifTool::PNG::colorType = -1;
+
+# PNG chunks
+%Image::ExifTool::PNG::Main = (
+    WRITE_PROC => \&Image::ExifTool::DummyWriteProc,
+    GROUPS => { 2 => 'Image' },
+    bKGD => {
+        Name => 'BackgroundColor',
+        ValueConv => 'join(" ",unpack(length($val) < 2 ? "C" : "n*", $val))',
+    },
+    cHRM => {
+        Name => 'PrimaryChromaticities',
+        SubDirectory => { TagTable => 'Image::ExifTool::PNG::PrimaryChromaticities' },
+    },
+    fRAc => {
+        Name => 'FractalParameters',
+        Binary => 1,
+    },
+    gAMA => {
+        Name => 'Gamma',
+        ValueConv => 'my $a=unpack("N",$val);$a ? int(1e9/$a+0.5)/1e4 : $val',
+    },
+    gIFg => {
+        Name => 'GIFGraphicControlExtension',
+        Binary => 1,
+    },
+    gIFt => {
+        Name => 'GIFPlainTextExtension',
+        Binary => 1,
+    },
+    gIFx => {
+        Name => 'GIFApplicationExtension',
+        Binary => 1,
+    },
+    hIST => {
+        Name => 'PaletteHistogram',
+        Binary => 1,
+    },
+    iCCP => {
+        Name => 'ICC_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+            ProcessProc => \&ProcessPNG_Compressed,
+        },
+    },
+#   IDAT
+#   IEND
+    IHDR => {
+        Name => 'ImageHeader',
+        SubDirectory => { TagTable => 'Image::ExifTool::PNG::ImageHeader' },
+    },
+    iTXt => {
+        Name => 'InternationalText',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PNG::TextualData',
+            ProcessProc => \&ProcessPNG_iTXt,
+        },
+    },
+    oFFs => {
+        Name => 'ImageOffset',
+        ValueConv => q{
+            my @a = unpack("NNC",$val);
+            $a[2] = ($a[2] ? "microns" : "pixels");
+            return "$a[0], $a[1] ($a[2])";
+        },
+    },
+    pCAL => {
+        Name => 'PixelCalibration',
+        Binary => 1,
+    },
+    pHYs => {
+        Name => 'PhysicalPixel',
+        SubDirectory => { TagTable => 'Image::ExifTool::PNG::PhysicalPixel' },
+    },
+    PLTE => {
+        Name => 'Palette',
+        ValueConv => 'length($val) <= 3 ? join(" ",unpack("C*",$val)) : \$val',
+    },
+    sBIT => {
+        Name => 'SignificantBits',
+        ValueConv => 'join(" ",unpack("C*",$val))',
+    },
+    sPLT => {
+        Name => 'SuggestedPalette',
+        Binary => 1,
+        PrintConv => 'split("\0",$$val,1)', # extract palette name
+    },
+    sRGB => {
+        Name => 'SRGBRendering',
+        ValueConv => 'unpack("C",$val)',
+        PrintConv => {
+            0 => 'Perceptual',
+            1 => 'Relative Colorimetric',
+            2 => 'Saturation',
+            3 => 'Absolute Colorimetric',
+        },
+    },
+    tEXt => {
+        Name => 'TextualData',
+        SubDirectory => { TagTable => 'Image::ExifTool::PNG::TextualData' },
+    },
+    tIME => {
+        Name => 'ModifyDate',
+        Groups => { 2 => 'Time' },
+        Writable => 1,
+        Shift => 'Time',
+        ValueConv => 'sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%.2d", unpack("nC5", $val))',
+        ValueConvInv => q{
+            my @a = ($val=~/^(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)/);
+            @a == 6 or warn('Invalid date'), return undef;
+            return pack('nC5', @a);
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$val',
+    },
+    tRNS => {
+        Name => 'Transparency',
+        ValueConv => q{
+            return \$val if length($val) > 6;
+            join(" ",unpack($Image::ExifTool::PNG::colorType == 3 ? "C*" : "n*", $val));
+        },
+    },
+    tXMP => {
+        Name => 'XMP',
+        Notes => 'obsolete location specified by older XMP draft',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
+    },
+    zTXt => {
+        Name => 'CompressedText',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PNG::TextualData',
+            ProcessProc => \&ProcessPNG_Compressed,
+        },
+    },
+);
+
+# PNG IHDR chunk
+%Image::ExifTool::PNG::ImageHeader = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'ImageWidth',
+        Format => 'int32u',
+    },
+    4 => {
+        Name => 'ImageHeight',
+        Format => 'int32u',
+    },
+    8 => 'BitDepth',
+    9 => {
+        Name => 'ColorType',
+        RawConv => '$Image::ExifTool::PNG::colorType = $val',
+        PrintConv => {
+            0 => 'Grayscale',
+            2 => 'RGB',
+            3 => 'Palette',
+            4 => 'Grayscale with Alpha',
+            6 => 'RGB with Alpha',
+        },
+    },
+    10 => {
+        Name => 'Compression',
+        PrintConv => { 0 => 'Deflate/Inflate' },
+    },
+    11 => {
+        Name => 'Filter',
+        PrintConv => { 0 => 'Adaptive' },
+    },
+    12 => {
+        Name => 'Interlace',
+        PrintConv => { 0 => 'Noninterlaced', 1 => 'Adam7 Interlace' },
+    },
+);
+
+# PNG cHRM chunk
+%Image::ExifTool::PNG::PrimaryChromaticities = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    FORMAT => 'int32u',
+    0 => { Name => 'WhitePointX', ValueConv => '$val / 100000' },
+    1 => { Name => 'WhitePointY', ValueConv => '$val / 100000' },
+    2 => { Name => 'RedX',        ValueConv => '$val / 100000' },
+    3 => { Name => 'RedY',        ValueConv => '$val / 100000' },
+    4 => { Name => 'GreenX',      ValueConv => '$val / 100000' },
+    5 => { Name => 'GreenY',      ValueConv => '$val / 100000' },
+    6 => { Name => 'BlueX',       ValueConv => '$val / 100000' },
+    7 => { Name => 'BlueY',       ValueConv => '$val / 100000' },
+);
+
+# PNG pHYs chunk
+%Image::ExifTool::PNG::PhysicalPixel = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'PixelsPerUnitX',
+        Format => 'int32u',
+    },
+    4 => {
+        Name => 'PixelsPerUnitY',
+        Format => 'int32u',
+    },
+    8 => {
+        Name => 'PixelUnits',
+        PrintConv => { 0 => 'Unknown', 1 => 'Meters' },
+    },
+);
+
+my %unreg = ( Notes => 'unregistered' );
+
+# Tags for PNG tEXt zTXt and iTXt chunks
+# (NOTE: ValueConv is set dynamically, so don't set it here!)
+%Image::ExifTool::PNG::TextualData = (
+    PROCESS_PROC => \&ProcessPNG_tEXt,
+    WRITE_PROC => \&Image::ExifTool::DummyWriteProc,
+    WRITABLE => 'string',
+    PREFERRED => 1, # always add these tags when writing
+    GROUPS => { 2 => 'Image' },
+    NOTES => q{
+The PNG TextualData format allows aribrary tag names to be used.  The tags
+listed below are the only ones that can be written (unless new user-defined
+tags are added via the configuration file), however ExifTool will extract
+any other TextualData tags that are found.
+
+The information for the TextualData tags may be stored as tEXt, zTXt or iTXt
+chunks in the PNG image.  ExifTool will read and edit tags in their original
+form, but tEXt chunks are written by default when creating new tags.
+Compressed zTXt chunks are written only if Compress::Zlib is available, and
+only for profile information or when the -z (Compress) option is specified.
+
+Some of the tags below are not registered as part of the PNG specification,
+but are included here because they are generated by other software such as
+ImageMagick.
+    },
+    Title       => { },
+    Author      => { Groups => { 2 => 'Author' } },
+    Description => { },
+    Copyright   => { Groups => { 2 => 'Author' } },
+   'Creation Time' => {
+        Name => 'CreationTime',
+        Groups => { 2 => 'Time' },
+        Shift => 'Time',
+    },
+    Software    => { },
+    Disclaimer  => { },
+    # change name to differentiate from ExifTool Warning
+    Warning     => { Name => 'PNGWarning', },
+    Source      => { },
+    Comment     => { },
+#
+# The following tags are not part of the original PNG specification,
+# but are written by ImageMagick and other software
+#
+    Artist      => { %unreg, Groups => { 2 => 'Author' } },
+    Document    => { %unreg },
+    Label       => { %unreg },
+    Make        => { %unreg, Groups => { 2 => 'Camera' } },
+    Model       => { %unreg, Groups => { 2 => 'Camera' } },
+    TimeStamp   => { %unreg, Groups => { 2 => 'Time' }, Shift => 'Time' },
+    URL         => { %unreg },
+   'XML:com.adobe.xmp' => {
+        Name => 'XMP',
+        Notes => q{
+            location according to the XMP specification -- this is where ExifTool will
+            add a new XMP chunk if the image didn't already contain XMP
+        },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::XMP::Main',
+        },
+    },
+   'Raw profile type APP1' => [
+        {
+            # EXIF table must come first because we key on this in ProcessProfile()
+            # (No condition because this is just for BuildTagLookup)
+            Name => 'APP1_Profile',
+            SubDirectory => {
+                TagTable=>'Image::ExifTool::Exif::Main',
+                ProcessProc => \&ProcessProfile,
+            },
+        },
+        {
+            Name => 'APP1_Profile',
+            SubDirectory => {
+                TagTable=>'Image::ExifTool::XMP::Main',
+                ProcessProc => \&ProcessProfile,
+            },
+        },
+    ],
+   'Raw profile type exif' => {
+        Name => 'EXIF_Profile',
+        SubDirectory => {
+            TagTable=>'Image::ExifTool::Exif::Main',
+            ProcessProc => \&ProcessProfile,
+        },
+    },
+   'Raw profile type icc' => {
+        Name => 'ICC_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+            ProcessProc => \&ProcessProfile,
+        },
+    },
+   'Raw profile type icm' => {
+        Name => 'ICC_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+            ProcessProc => \&ProcessProfile,
+        },
+    },
+   'Raw profile type iptc' => {
+        Name => 'IPTC_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Photoshop::Main',
+            ProcessProc => \&ProcessProfile,
+        },
+    },
+   'Raw profile type xmp' => {
+        Name => 'XMP_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::XMP::Main',
+            ProcessProc => \&ProcessProfile,
+        },
+    },
+);
+
+#------------------------------------------------------------------------------
+# AutoLoad our writer routines when necessary
+#
+sub AUTOLOAD
+{
+    return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
+}
+
+#------------------------------------------------------------------------------
+# Found a PNG tag -- extract info from subdirectory or decompress data if necessary
+# Inputs: 0) ExifTool object reference, 1) Pointer to tag table,
+#         2) Tag ID, 3) Tag value, 4) [optional] compressed data flag:
+#            0=not compressed, 1=unknown compression, 2-N=compression with type N-2
+#         5) optional output buffer reference
+# Returns: 1 on success
+sub FoundPNG($$$$;$$)
+{
+    my ($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff) = @_;
+    my ($wasCompressed, $deflateErr);
+    return 0 unless defined $val;
+#
+# First, uncompress data if requested
+#
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag) ||
+                  # (some software forgets to capitalize first letter)
+                  $exifTool->GetTagInfo($tagTablePtr, ucfirst($tag));
+
+    if ($compressed and $compressed > 1) {
+        if ($compressed == 2) { # Inflate/Deflate compression
+            if (eval 'require Compress::Zlib') {
+                my ($v2, $stat);
+                my $inflate = Compress::Zlib::inflateInit();
+                $inflate and ($v2, $stat) = $inflate->inflate($val);
+                if ($inflate and $stat == Compress::Zlib::Z_STREAM_END()) {
+                    $val = $v2;
+                    $compressed = 0;
+                    $wasCompressed = 1;
+                } else {
+                    $deflateErr = "Error inflating $tag";
+                }
+            } elsif (not $noCompressLib) {
+                $noCompressLib = 1;
+                my $verb = $outBuff ? 'write' : 'decode';
+                $deflateErr = "Install Compress::Zlib to $verb compressed information";
+            } else {
+                $deflateErr = '';   # flag deflate error but no warning
+            }
+        } else {
+            $compressed -= 2;
+            $deflateErr = "Unknown compression method $compressed for $tag";
+        }
+        if ($compressed and $verbose and $tagInfo and $$tagInfo{SubDirectory}) {
+            $exifTool->VerboseDir("Unable to decompress $$tagInfo{Name}", 0, length($val));
+        }
+        $exifTool->Warn($deflateErr) if $deflateErr and not $outBuff;
+    }
+#
+# extract information from subdirectory if available
+#
+    if ($tagInfo) {
+        my $tagName = $$tagInfo{Name};
+        my $processed;
+        if ($$tagInfo{SubDirectory} and not $compressed) {
+            my $len = length $val;
+            if ($verbose and $exifTool->{INDENT} ne '  ') {
+                if ($wasCompressed and $verbose > 2) {
+                    my $name = $tagName;
+                    $wasCompressed and $name = "Decompressed $name";
+                    $exifTool->VerboseDir($name, 0, $len);
+                    my %parms = ( Prefix => $exifTool->{INDENT}, Out => $out );
+                    $parms{MaxLen} = 96 unless $verbose > 3;
+                    Image::ExifTool::HexDump(\$val, undef, %parms);
+                }
+                # don't indent next directory (since it is really the same data)
+                $exifTool->{INDENT} =~ s/..$//;
+            }
+            my $subdir = $$tagInfo{SubDirectory};
+            my $processProc = $$subdir{ProcessProc};
+            # nothing more to do if writing and subdirectory is not writable
+            my $subTable = GetTagTable($$subdir{TagTable});
+            return 1 if $outBuff and not $$subTable{WRITE_PROC};
+            my %subdirInfo = (
+                DataPt => \$val,
+                DirStart => 0,
+                DataLen => $len,
+                DirLen => $len,
+                DirName => $tagName,
+                TagInfo => $tagInfo,
+                ReadOnly => 1, # (only used by WriteXMP)
+                OutBuff => $outBuff,
+            );
+            # no need to re-decompress if already done
+            undef $processProc if $wasCompressed and $processProc eq \&ProcessPNG_Compressed;
+            # rewrite this directory if necessary (but always process TextualData normally)
+            if ($outBuff and not $processProc and $subTable ne \%Image::ExifTool::PNG::TextualData) {
+                return 1 unless $exifTool->{EDIT_DIRS}->{$tagName};
+                $$outBuff = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+                # if this was an XMP directory, we must make it read-only
+                $tagName eq 'XMP' and Image::ExifTool::XMP::ValidateXMP(\$outBuff,'r');
+                delete $exifTool->{ADD_DIRS}->{$tagName};
+            } else {
+                $processed = $exifTool->ProcessDirectory(\%subdirInfo, $subTable, $processProc);
+            }
+            $compressed = 1;    # pretend this is compressed since it is binary data
+        }
+        if ($outBuff) {
+            my $writable = $tagInfo->{Writable};
+            if ($writable or ($$tagTablePtr{WRITABLE} and
+                not defined $writable and not $$tagInfo{SubDirectory}))
+            {
+                # write new value for this tag if necessary
+                my ($isOverwriting, $newVal);
+                if ($exifTool->{DEL_GROUP}->{PNG}) {
+                    # remove this tag now, but keep in ADD_PNG list to add back later
+                    $isOverwriting = 1;
+                } else {
+                    # remove this from the list of PNG tags to add
+                    delete $exifTool->{ADD_PNG}->{$tag};
+                    # (also handle case of tEXt tags written with lowercase first letter)
+                    delete $exifTool->{ADD_PNG}->{ucfirst($tag)};
+                    my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+                    $isOverwriting = Image::ExifTool::IsOverwriting($newValueHash);
+                    if (defined $deflateErr) {
+                        $newVal = Image::ExifTool::GetNewValues($newValueHash);
+                        # can only write tag now if unconditionally deleting it
+                        if ($isOverwriting > 0 and not defined $newVal) {
+                            $val = '<deflate error>';
+                        } else {
+                            $isOverwriting = 0; # can't rewrite this compressed text
+                            $exifTool->Warn($deflateErr) if $deflateErr;
+                        }
+                    } else {
+                        if ($isOverwriting < 0) {
+                            $isOverwriting = Image::ExifTool::IsOverwriting($newValueHash, $val);
+                        }
+                        # (must get new value after IsOverwriting() in case it was shifted)
+                        $newVal = Image::ExifTool::GetNewValues($newValueHash);
+                    }
+                }
+                if ($isOverwriting) {
+                    $$outBuff =  (defined $newVal) ? $newVal : '';
+                    ++$exifTool->{CHANGED};
+                    if ($verbose > 1) {
+                        print $out "    - PNG:$tagName = '",$exifTool->Printable($val),"'\n";
+                        print $out "    + PNG:$tagName = '",$exifTool->Printable($newVal),"'\n" if defined $newVal;
+                    }
+                }
+            }
+            if ($$outBuff) {
+                if ($wasCompressed) {
+                    # re-compress the output data
+                    my $deflate;
+                    if (eval 'require Compress::Zlib') {
+                        my $deflate = Compress::Zlib::deflateInit();
+                        if ($deflate) {
+                            $$outBuff = $deflate->deflate($$outBuff);
+                            $$outBuff .= $deflate->flush() if defined $$outBuff;
+                        } else {
+                            undef $$outBuff;
+                        }
+                    }
+                    $$outBuff or $exifTool->Warn("PNG:$tagName not written (compress error)");
+                } elsif ($exifTool->Options('Compress')) {
+                    $exifTool->Warn("PNG:$tagName not compressed (uncompressed tag existed)", 1);
+                }
+            }
+            return 1;
+        }
+        return 1 if $processed;
+    } else {
+        my $name;
+        ($name = $tag) =~ s/\s+(.)/\u$1/g;   # remove white space from tag name
+        $tagInfo = { Name => $name };
+        # make unknown profiles binary data type
+        $$tagInfo{ValueConv} = '\$val' if $tag =~ /^Raw profile type /;
+        Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+    }
+#
+# store this tag information
+#
+    if ($verbose) {
+        # temporarily remove subdirectory so it isn't printed in verbose information
+        # since we aren't decoding it anyway;
+        my $subdir = $$tagInfo{SubDirectory};
+        delete $$tagInfo{SubDirectory};
+        $exifTool->VerboseInfo($tag, $tagInfo,
+            Table  => $tagTablePtr,
+            DataPt => \$val,
+        );
+        $$tagInfo{SubDirectory} = $subdir if $subdir;
+    }
+    # set the RawConv dynamically depending on whether this is binary or not
+    my $delRawConv;
+    if ($compressed and not defined $$tagInfo{ValueConv}) {
+        $$tagInfo{RawConv} = '\$val';
+        $delRawConv = 1;
+    }
+    $exifTool->FoundTag($tagInfo, $val);
+    delete $$tagInfo{RawConv} if $delRawConv;
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process encoded PNG profile information
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table
+# Returns: 1 on success
+sub ProcessProfile($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $tagInfo = $$dirInfo{TagInfo};
+    my $outBuff = $$dirInfo{OutBuff};
+    my $tagName = $$tagInfo{Name};
+
+    # ImageMagick 5.3.6 writes profiles with the following headers:
+    # "\nICC Profile\n", "\nIPTC profile\n", "\n\xaa\x01{generic prof\n"
+    # and "\ngeneric profile\n"
+    return 0 unless $$dataPt =~ /^\n(.*?)\n\s*(\d+)\n(.*)/s;
+    my ($profileType, $len) = ($1, $2);
+    # data is encoded in hex, so change back to binary
+    my $buff = pack('H*', join('',split(' ',$3)));
+    my $actualLen = length $buff;
+    if ($len ne $actualLen) {
+        $exifTool->Warn("$tagName is wrong size (should be $len bytes but is $actualLen)");
+        $len = $actualLen;
+    }
+    my $verbose = $exifTool->Options('Verbose');
+    if ($verbose) {
+        if ($verbose > 2) {
+            $exifTool->VerboseDir("Decoded $tagName", 0, $len);
+            my %parms = (
+                Prefix => $exifTool->{INDENT},
+                Out => $exifTool->Options('TextOut'),
+            );
+            $parms{MaxLen} = 96 unless $verbose > 3;
+            Image::ExifTool::HexDump(\$buff, undef, %parms);
+        }
+        # don't indent next directory (since it is really the same data)
+        $exifTool->{INDENT} =~ s/..$//;
+    }
+    my %dirInfo = (
+        Parent   => 'PNG',
+        DataPt   => \$buff,
+        DataLen  => $len,
+        DirStart => 0,
+        DirLen   => $len,
+        Base     => 0,
+        OutFile  => $outBuff,
+    );
+    my $processed = 0;
+    my $oldChanged = $exifTool->{CHANGED};
+    my $exifTable = GetTagTable('Image::ExifTool::Exif::Main');
+    my $editDirs = $exifTool->{EDIT_DIRS};
+    my $addDirs = $exifTool->{ADD_DIRS};
+    if ($tagTablePtr ne $exifTable) {
+        # process non-EXIF and non-APP1 profile as-is
+        if ($outBuff) {
+            # no need to rewrite this if not editing tags in this directory
+            my $dir = $tagName;
+            $dir =~ s/_Profile// unless $dir =~ /^ICC/;
+            return 1 unless $$editDirs{$dir};
+            $$outBuff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+            delete $$addDirs{$dir};
+        } else {
+            $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        }
+    } elsif ($buff =~ /^$Image::ExifTool::exifAPP1hdr/) {
+        # APP1 EXIF information
+        return 1 if $outBuff and not $$editDirs{IFD0};
+        my $hdrLen = length($Image::ExifTool::exifAPP1hdr);
+        $dirInfo{DirStart} += $hdrLen;
+        $dirInfo{DirLen} -= $hdrLen;
+        $processed = $exifTool->ProcessTIFF(\%dirInfo);
+        if ($outBuff) {
+            if ($$outBuff) {
+                $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff;
+            } else {
+                $$outBuff = '' if $processed;
+            }
+            delete $$addDirs{IFD0};
+        }
+    } elsif ($buff =~ /^$Image::ExifTool::xmpAPP1hdr/) {
+        # APP1 XMP information
+        my $hdrLen = length($Image::ExifTool::xmpAPP1hdr);
+        my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
+        $dirInfo{DirStart} += $hdrLen;
+        $dirInfo{DirLen} -= $hdrLen;
+        if ($outBuff) {
+            return 1 unless $$editDirs{XMP};
+            $$outBuff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+            $$outBuff and $$outBuff = $Image::ExifTool::xmpAPP1hdr . $$outBuff;
+            delete $$addDirs{XMP};
+        } else {
+            $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        }
+    } elsif ($buff =~ /^(MM\0\x2a|II\x2a\0)/) {
+        # TIFF information (haven't seen this, but what the heck...)
+        return 1 if $outBuff and not $$editDirs{IFD0};
+        $processed = $exifTool->ProcessTIFF(\%dirInfo);
+        if ($outBuff) {
+            if ($$outBuff) {
+                $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff;
+            } else {
+                $$outBuff = '' if $processed;
+            }
+            delete $$addDirs{IFD0};
+        }
+    } else {
+        my $profName = $profileType;
+        $profName =~ tr/\x00-\x1f\x7f-\xff/./;
+        $exifTool->Warn("Unknown raw profile '$profName'");
+    }
+    if ($outBuff and $$outBuff) {
+        if ($exifTool->{CHANGED} != $oldChanged) {
+            my $hdr = sprintf("\n%s\n%8d\n", $profileType, length($$outBuff));
+            # hex encode the data
+            $$outBuff = $hdr . HexEncode($outBuff);
+        } else {
+            undef $$outBuff;
+        }
+    }
+    return $processed;
+}
+
+#------------------------------------------------------------------------------
+# Process PNG compressed zTXt or iCCP chunk
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table
+# Returns: 1 on success
+sub ProcessPNG_Compressed($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($tag, $val) = split /\0/, ${$$dirInfo{DataPt}}, 2;
+    return 0 unless defined $val;
+    # set compressed to 2 + compression method to decompress the data
+    my $compressed = 2 + unpack('C', $val);
+    my $hdr = $tag . "\0" . substr($val, 0, 1);
+    $val = substr($val, 1); # remove compression method byte
+    # use the PNG chunk tag instead of the embedded tag name for iCCP chunks
+    if ($$dirInfo{TagInfo} and $$dirInfo{TagInfo}->{Name} eq 'ICC_Profile') {
+        $tag = 'iCCP';
+        $tagTablePtr = \%Image::ExifTool::PNG::Main;
+    }
+    my $outBuff = $$dirInfo{OutBuff};
+    my $rtnVal = FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff);
+    # add header back onto this chunk if we are writing
+    $$outBuff = $hdr . $$outBuff if $outBuff and $$outBuff;
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Process PNG tEXt chunk
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table
+# Returns: 1 on success
+sub ProcessPNG_tEXt($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($tag, $val) = split /\0/, ${$$dirInfo{DataPt}}, 2;
+    my $outBuff = $$dirInfo{OutBuff};
+    my $rtnVal = FoundPNG($exifTool, $tagTablePtr, $tag, $val, undef, $outBuff);
+    # add header back onto this chunk if we are writing
+    $$outBuff = $tag . "\0" . $$outBuff if $outBuff and $$outBuff;
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Process PNG iTXt chunk
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table
+# Returns: 1 on success
+sub ProcessPNG_iTXt($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($tag, $dat) = split /\0/, ${$$dirInfo{DataPt}}, 2;
+    return 0 unless defined $dat and length($dat) >= 4;
+    my ($compressed, $meth) = unpack('CC', $dat);
+    my ($lang, $trans, $val) = split /\0/, substr($dat, 2), 3;
+    # set compressed flag so we will decompress it in FoundPNG()
+    $compressed and $compressed = 2 + $meth;
+    my $outBuff = $$dirInfo{OutBuff};
+    my $rtnVal = FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff);
+    if ($outBuff and $$outBuff) {
+        $$outBuff = $tag . "\0" . substr($dat, 0, 2) . "$lang\0$trans\0" . $$outBuff;
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Extract meta information from a PNG image
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid PNG image, or -1 on write error
+sub ProcessPNG($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $outfile = $$dirInfo{OutFile};
+    my $raf = $$dirInfo{RAF};
+    my $datChunk = '';
+    my $datCount = 0;
+    my $datBytes = 0;
+    my ($sig, $err, $ok);
+
+    # check to be sure this is a valid PNG/MNG/JNG image
+    return 0 unless $raf->Read($sig,8) == 8 and $pngLookup{$sig};
+    if ($outfile) {
+        Write($outfile, $sig) or $err = 1 if $outfile;
+        # can only add tags in Main and TextualData tables
+        $exifTool->{ADD_PNG} = $exifTool->GetNewTagInfoHash(
+            \%Image::ExifTool::PNG::Main,
+            \%Image::ExifTool::PNG::TextualData);
+        # initialize with same directories as JPEG, but PNG tags take priority
+        $exifTool->InitWriteDirs('JPEG','PNG');
+    }
+    my ($fileType, $hdrChunk, $endChunk) = @{$pngLookup{$sig}};
+    $exifTool->SetFileType($fileType);  # set the FileType tag
+    SetByteOrder('MM'); # PNG files are big-endian
+    my $tagTablePtr = GetTagTable('Image::ExifTool::PNG::Main');
+    my $mngTablePtr;
+    if ($fileType ne 'PNG') {
+        $mngTablePtr = GetTagTable('Image::ExifTool::MNG::Main');
+    }
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my ($hbuf, $dbuf, $cbuf, $foundHdr);
+
+    # process the PNG/MNG/JNG chunks
+    undef $noCompressLib;
+    for (;;) {
+        $raf->Read($hbuf,8) == 8 or $exifTool->Warn("Truncated $fileType image"), last;
+        my ($len, $chunk) = unpack('Na4',$hbuf);
+        $len > 0x7fffffff and $exifTool->Warn("Invalid $fileType box size"), last;
+        if ($verbose) {
+            # don't dump image data chunks in verbose mode (only give count instead)
+            if ($datCount and $chunk ne $datChunk) {
+                my $s = $datCount > 1 ? 's' : '';
+                print $out "$fileType $datChunk ($datCount chunk$s, total $datBytes bytes)\n";
+                $datCount = $datBytes = 0;
+                $datChunk = '';
+            }
+            if ($chunk =~ /^(IDAT|JDAT|JDAA)$/) {
+                $datChunk = $chunk;
+                $datCount++;
+                $datBytes += $len;
+            }
+        }
+        if ($outfile) {
+            if ($chunk eq 'IEND') {
+                # add any new chunks immediately before the IEND chunk
+                AddChunks($exifTool, $outfile) or $err = 1;
+            } elsif ($chunk eq 'PLTE' or $chunk eq 'IDAT') {
+                # iCCP chunk must come before PLTE and IDAT
+                # (ignore errors -- will add later as text profile if this fails)
+                Add_iCCP($exifTool, $outfile);
+            }
+        }
+        if ($chunk eq $endChunk) {
+            if ($outfile) {
+                # copy over the rest of the file if necessary
+                Write($outfile, $hbuf) or $err = 1;
+                while ($raf->Read($hbuf, 65536)) {
+                    Write($outfile, $hbuf) or $err = 1;
+                }
+            }
+            $verbose and print $out "$fileType $chunk (end of image)\n";
+            $ok = 1;
+            last;
+        }
+        # read chunk data and CRC
+        unless ($raf->Read($dbuf,$len)==$len and $raf->Read($cbuf, 4)==4) {
+            $exifTool->Warn("Corrupted $fileType image");
+            last;
+        }
+        unless ($foundHdr) {
+            if ($chunk eq $hdrChunk) {
+                $foundHdr = 1;
+            } else {
+                $exifTool->Warn("$fileType image did not start with $hdrChunk");
+                last;
+            }
+        }
+        if ($verbose) {
+            # check CRC when in verbose mode (since we don't care about speed)
+            my $crc = CalculateCRC(\$hbuf, undef, 4);
+            $crc = CalculateCRC(\$dbuf, $crc);
+            $crc == unpack('N',$cbuf) or $exifTool->Warn("Bad CRC for $chunk chunk");
+            if ($datChunk) {
+                Write($outfile, $hbuf, $dbuf, $cbuf) or $err = 1 if $outfile;
+                next;
+            }
+            print $out "$fileType $chunk ($len bytes):\n";
+            if ($verbose > 2) {
+                my %dumpParms = ( Out => $out );
+                $dumpParms{MaxLen} = 96 if $verbose <= 4;
+                Image::ExifTool::HexDump(\$dbuf, undef, %dumpParms);
+            }
+        }
+        # only extract information from chunks in our tables
+        my ($theBuff, $outBuff);
+        $outBuff = \$theBuff if $outfile;
+        if ($$tagTablePtr{$chunk}) {
+            FoundPNG($exifTool, $tagTablePtr, $chunk, $dbuf, undef, $outBuff);
+        } elsif ($mngTablePtr and $$mngTablePtr{$chunk}) {
+            FoundPNG($exifTool, $mngTablePtr, $chunk, $dbuf, undef, $outBuff);
+        }
+        if ($outfile) {
+            if ($theBuff) {
+                $hbuf = pack('Na4',length($theBuff), $chunk);
+                $dbuf = $theBuff;
+                my $crc = CalculateCRC(\$hbuf, undef, 4);
+                $crc = CalculateCRC(\$dbuf, $crc);
+                $cbuf = pack('N', $crc);
+            } elsif (defined $theBuff) {
+                next;   # empty if we deleted the information
+            }
+            Write($outfile, $hbuf, $dbuf, $cbuf) or $err = 1;
+        }
+    }
+    return -1 if $outfile and ($err or not $ok);
+    return 1;   # this was a valid PNG/MNG/JNG image
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::PNG - Read and write PNG meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to read and
+write PNG (Portable Network Graphics), MNG (Multi-image Network Graphics)
+and JNG (JPEG Network Graphics) images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.libpng.org/pub/png/spec/1.2/>
+
+=item L<http://www.faqs.org/docs/png/>
+
+=item L<http://www.libpng.org/pub/mng/>
+
+=item L<http://www.libpng.org/pub/png/spec/register/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/PNG Tags>,
+L<Image::ExifTool::TagNames/MNG Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/PPM.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/PPM.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/PPM.pm	(revision 20131)
@@ -0,0 +1,171 @@
+#------------------------------------------------------------------------------
+# File:         PPM.pm
+#
+# Description:  Read and write PPM meta information
+#
+# Revisions:    09/03/2005 - P. Harvey Created
+#
+# References:   1) http://netpbm.sourceforge.net/doc/ppm.html
+#               2) http://netpbm.sourceforge.net/doc/pgm.html
+#               3) http://netpbm.sourceforge.net/doc/pbm.html
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::PPM;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.04';
+
+#------------------------------------------------------------------------------
+# Read or write information in a PPM/PGM/PBM image
+# Inputs: 0) ExifTool object reference, 1) Directory information reference
+# Returns: 1 on success, 0 if this wasn't a valid PPM file, -1 on write error
+sub ProcessPPM($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $outfile = $$dirInfo{OutFile};
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my ($buff, $num, $type, %info);
+#
+# read as much of the image as necessary to extract the header and comments
+#
+    for (;;) {
+        if (defined $buff) {
+            # need to read some more data
+            my $tmp;
+            return 0 unless $raf->Read($tmp, 1024);
+            $buff .= $tmp;
+        } else {
+            return 0 unless $raf->Read($buff, 1024);
+        }
+        # verify this is a valid PPM file
+        return 0 unless $buff =~ /^P([1-6])\s+/g;
+        $num = $1;
+        # note: may contain comments starting with '#'
+        if ($buff =~ /\G#/gc) {
+            # must read more if we are in the middle of a comment
+            next unless $buff =~ /\G ?(.*\n(#.*\n)*)\s*/g;
+            $info{Comment} = $1;
+            next if $buff =~ /\G#/gc;
+        } else {
+            delete $info{Comment};
+        }
+        next unless $buff =~ /\G(\S+)\s+(\S+)\s/g;
+        $info{ImageWidth} = $1;
+        $info{ImageHeight} = $2;
+        $type = [qw{PPM PBM PGM}]->[$num % 3];
+        last if $type eq 'PBM'; # (no MaxVal for PBM images)
+        if ($buff =~ /\G\s*#/gc) {
+            next unless $buff =~ /\G ?(.*\n(#.*\n)*)\s*/g;
+            $info{Comment} = '' unless exists $info{Comment};
+            $info{Comment} .= $1;
+            next if $buff =~ /\G#/gc;
+        }
+        next unless $buff =~ /\G(\S+)\s/g;
+        $info{MaxVal} = $1;
+        last;
+    }
+    # validate numerical values
+    foreach (keys %info) {
+        next if $_ eq 'Comment';
+        return 0 unless $info{$_} =~ /^\d+$/;
+    }
+    if (defined $info{Comment}) {
+        $info{Comment} =~ s/^# ?//mg;   # remove "# " at the start of each line
+        $info{Comment} =~ s/\n$//;      # remove trailing newline
+    }
+    $exifTool->SetFileType($type);
+    my $len = pos($buff);
+#
+# rewrite the file if requested
+#
+    if ($outfile) {
+        my $newValueHash;
+        my $newComment = $exifTool->GetNewValues('Comment', \$newValueHash);
+        my $oldComment = $info{Comment};
+        if (Image::ExifTool::IsOverwriting($newValueHash, $oldComment)) {
+            ++$exifTool->{CHANGED};
+            if ($verbose > 1) {
+                print $out "    - Comment = '$oldComment'\n" if defined $oldComment;
+                print $out "    + Comment = '$newComment'\n" if defined $newComment;
+            }
+        } else {
+            $newComment = $oldComment;  # use existing comment
+        }
+        my $hdr = "P$num\n";
+        if (defined $newComment) {
+            $newComment =~ s/\n/\n# /g;
+            $hdr .= "# $newComment\n";
+        }
+        $hdr .= "$info{ImageWidth} $info{ImageHeight}\n";
+        $hdr .= "$info{MaxVal}\n" if $type ne 'PBM';
+        # write header and start of image
+        Write($outfile, $hdr, substr($buff, $len)) or return -1;
+        # copy over the rest of the image
+        while ($raf->Read($buff, 0x10000)) {
+            Write($outfile, $buff) or return -1;
+        }
+        return 1;
+    }
+#
+# save extracted information
+#
+    if ($verbose > 2) {
+        print $out "$type header ($len bytes):\n";
+        Image::ExifTool::HexDump(\$buff, $len, Out => $out);
+    }
+    my $tag;
+    foreach $tag (qw{Comment ImageWidth ImageHeight MaxVal}) {
+        $exifTool->FoundTag($tag, $info{$tag}) if defined $info{$tag};
+    }
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::PPM - Read and write PPM meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read and
+write PPM (Portable Pixel Map), PGM (Portable Gray Map) and PBM (Portable
+BitMap) images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://netpbm.sourceforge.net/doc/ppm.html>
+
+=item L<http://netpbm.sourceforge.net/doc/pgm.html>
+
+=item L<http://netpbm.sourceforge.net/doc/pbm.html>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/PPM Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Panasonic.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Panasonic.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Panasonic.pm	(revision 20131)
@@ -0,0 +1,626 @@
+#------------------------------------------------------------------------------
+# File:         Panasonic.pm
+#
+# Description:  Panasonic/Leica maker notes tags
+#
+# Revisions:    11/10/2004 - P. Harvey Created
+#
+# References:   1) http://www.compton.nu/panasonic.html (based on FZ10)
+#               2) Derived from DMC-FZ3 samples from dpreview.com
+#               3) http://johnst.org/sw/exiftags/
+#               4) Tels (http://bloodgate.com/) private communication (tests with FZ5)
+#               5) CPAN forum post by 'hardloaf' (http://www.cpanforum.com/threads/2183)
+#               6) http://www.cybercom.net/~dcoffin/dcraw/
+#               7) http://homepage3.nifty.com/kamisaka/makernote/makernote_pana.htm
+#               8) Marcel Coenen private communication (DMC-FZ50)
+#               9) http://forums.dpreview.com/forums/read.asp?forum=1033&message=22756430
+#              10) Jens Duttke private communication (TZ3,FZ30,FZ50)
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Panasonic;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.26';
+
+sub ProcessPanasonicType2($$$);
+
+# conversions for ShootingMode and SceneMode
+my %shootingMode = (
+    1  => 'Normal',
+    2  => 'Portrait',
+    3  => 'Scenery',
+    4  => 'Sports',
+    5  => 'Night Portrait',
+    6  => 'Program',
+    7  => 'Aperture Priority',
+    8  => 'Shutter Priority',
+    9  => 'Macro',
+    11 => 'Manual',
+    12 => 'Movie Preview', #PH (LZ6)
+    13 => 'Panning',
+    14 => 'Simple', #PH (LZ6)
+    18 => 'Fireworks',
+    19 => 'Party',
+    20 => 'Snow',
+    21 => 'Night Scenery',
+    22 => 'Food', #7
+    23 => 'Baby', #10
+    24 => 'Soft Skin', #PH (LZ6)
+    25 => 'Candlelight', #PH (LZ6)
+    26 => 'Starry Night', #PH (LZ6)
+    27 => 'High Sensitivity', #7 (LZ6)
+    29 => 'Underwater', #7
+    30 => 'Beach', #PH (LZ6)
+    31 => 'Aerial Photo', #PH (LZ6)
+    32 => 'Sunset', #PH (LZ6)
+    33 => 'Pet', #10
+    34 => 'Intelligent ISO', #PH (LZ6)
+);
+
+%Image::ExifTool::Panasonic::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITABLE => 1,
+    0x01 => {
+        Name => 'ImageQuality',
+        Writable => 'int16u',
+        PrintConv => {
+            2 => 'High',
+            3 => 'Normal',
+            6 => 'Very High', #3 (Leica)
+            7 => 'Raw', #3 (Leica)
+            9 => 'Motion Picture', #PH (LZ6)
+        },
+    },
+    0x02 => {
+        Name => 'FirmwareVersion',
+        Writable => 'undef',
+        Notes => q{
+            for some camera models such as the FZ30 this may be an internal production
+            reference number and not the actual firmware version
+        }, # (ref http://www.stevesforums.com/forums/view_topic.php?id=87764&forum_id=23&)
+        # (can be either binary or ascii -- add decimal points if binary)
+        ValueConv => '$val=~/[\0-\x2f]/ ? join(" ",unpack("C*",$val)) : $val',
+        ValueConvInv => q{
+            $val =~ /(\d+ ){3}\d+/ and $val = pack('C*',split(' ', $val));
+            length($val) == 4 or warn "Version must be 4 numbers\n";
+            return $val;
+        },
+        PrintConv => '$val=~tr/ /./; $val',
+        PrintConvInv => '$val=~tr/./ /; $val',
+    },
+    0x03 => {
+        Name => 'WhiteBalance',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Auto',
+            2 => 'Daylight',
+            3 => 'Cloudy',
+            4 => 'Halogen',
+            5 => 'Manual',
+            8 => 'Flash',
+            10 => 'Black & White', #3 (Leica)
+            11 => 'Manual', #PH (FZ8)
+        },
+    },
+    0x07 => {
+        Name => 'FocusMode',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Auto',
+            2 => 'Manual',
+            4 => 'Auto, Focus button', #4
+            5 => 'Auto, Continuous', #4
+        },
+    },
+    0x0f => {
+        Name => 'AFMode',
+        Writable => 'int8u',
+        Count => 2,
+        PrintConv => { #PH
+            '0 1'   => 'Spot Mode On', # (maybe 9-area for some cameras?)
+            '0 16'  => 'Spot Mode Off or 3-area (high speed)', # (FZ8 is 3-area)
+            '1 0'   => 'Spot Focusing', # (FZ8)
+            '1 1'   => '5-area', # (FZ8)
+            '16'    => 'Normal?', # (only AFMode for DMC-LC20)
+            '16 0'  => '1-area', # (FZ8)
+            '16 16' => '1-area (high speed)', # (FZ8)
+            '32 0'  => '3-area (auto)?', # (DMC-L1 guess)
+            '32 1'  => '3-area (left)?', # (DMC-L1 guess)
+            '32 2'  => '3-area (center)?', # (DMC-L1 guess)
+            '32 3'  => '3-area (right)?', # (DMC-L1 guess)
+        },
+    },
+    0x1a => {
+        Name => 'ImageStabilization',
+        Writable => 'int16u',
+        PrintConv => {
+            2 => 'On, Mode 1',
+            3 => 'Off',
+            4 => 'On, Mode 2',
+        },
+    },
+    0x1c => {
+        Name => 'MacroMode',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'On',
+            2 => 'Off',
+            0x101 => 'Tele-Macro', #7
+        },
+    },
+    0x1f => {
+        Name => 'ShootingMode',
+        Writable => 'int16u',
+        PrintConv => \%shootingMode,
+    },
+    0x20 => {
+        Name => 'Audio',
+        Writable => 'int16u',
+        PrintConv => { 1 => 'Yes', 2 => 'No' },
+    },
+    0x21 => { #2
+        Name => 'DataDump',
+        Writable => 0,
+        Binary => 1,
+    },
+    # 0x22 - normally 0, but 2 for 'Simple' ShootingMode in LZ6 sample - PH
+    0x23 => {
+        Name => 'WhiteBalanceBias',
+        Format => 'int16s',
+        Writable => 'int16s',
+        ValueConv => '$val / 3',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        ValueConvInv => '$val * 3',
+        PrintConvInv => 'eval $val',
+    },
+    0x24 => {
+        Name => 'FlashBias',
+        Format => 'int16s',
+        Writable => 'int16s',
+    },
+    0x25 => { #PH
+        Name => 'InternalSerialNumber',
+        Writable => 'undef',
+        Count => 16,
+        Notes => q{
+            this number is unique, and contains the date of manufacture, but is not the
+            same as the number printed on the camera body
+        },
+        PrintConv => q{
+            return $val unless $val=~/^([A-Z]\d{2})(\d{2})(\d{2})(\d{2})(\d{4})/;
+            my $yr = $2 + ($2 < 70 ? 2000 : 1900);
+            return "($1) $yr:$3:$4 no. $5";
+        },
+        PrintConvInv => '$_=$val; tr/A-Z0-9//dc; s/(.{3})(19|20)/$1/; $_',
+    },
+    0x26 => { #PH
+        Name => 'PanasonicExifVersion',
+        Writable => 'undef',
+    },
+    # 0x27 - values: 0 (LZ6,FX10K)
+    0x28 => {
+        Name => 'ColorEffect',
+        Writable => 'int16u',
+        # FX30 manual: (ColorMode) natural, vivid, cool, warm, b/w, sepia
+        PrintConv => {
+            1 => 'Off',
+            2 => 'Warm',
+            3 => 'Cool',
+            4 => 'Black & White',
+            5 => 'Sepia',
+        },
+    },
+    0x29 => { #10
+        Name => 'TimeSincePowerOn',
+        Writable => 'int32u',
+        Notes => q{
+            time in 1/100 sec from when the camera was powered on to when the image is
+            written to memory card
+        },
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+        PrintConv => sub { # convert to format "[DD days ]HH:MM:SS.ss"
+            my $val = shift;
+            my $str = '';
+            if ($val >= 24 * 3600) {
+                my $d = int($val / (24 * 3600));
+                $str .= "$d days ";
+                $val -= $d * 24 * 3600;
+            }
+            my $h = int($val / 3600);
+            $val -= $h * 3600;
+            my $m = int($val / 60);
+            $val -= $m * 60;
+            my $s = int($val);
+            my $f = 100 * ($val - int($val));
+            return sprintf("%s%.2d:%.2d:%.2d.%.2d",$str,$h,$m,$s,$f);
+        },
+        PrintConvInv => sub {
+            my $val = shift;
+            my @vals = ($val =~ /\d+(?:\.\d*)?/g);
+            my $sec = 0;
+            $sec += 24 * 3600 * shift(@vals) if @vals > 3;
+            $sec += 3600 * shift(@vals) if @vals > 2;
+            $sec += 60 * shift(@vals) if @vals > 1;
+            $sec += shift(@vals) if @vals;
+            return $sec;
+        },
+    },
+    0x2a => { #4
+        Name => 'BurstMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low/High Quality',
+            2 => 'Infinite',
+        },
+    },
+    0x2b => { #4
+        Name => 'SequenceNumber',
+        Writable => 'int32u',
+    },
+    0x2c => {
+        Name => 'Contrast',
+        Flags => 'PrintHex',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Low',
+            2 => 'High',
+            # 3 - observed with LZ6 in "Aerial Photo" mode - PH
+            # 5 - observed with FX10 in "Underwater" mode - PH
+            0x100 => 'Low',
+            0x110 => 'Normal',
+            0x120 => 'High',
+        }
+    },
+    0x2d => {
+        Name => 'NoiseReduction',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Low',
+            2 => 'High',
+        },
+    },
+    0x2e => { #4
+        Name => 'SelfTimer',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Off',
+            2 => '10s',
+            3 => '2s',
+        },
+    },
+    # 0x2f - values: 1 (LZ6,FX10K)
+    0x30 => { #7
+        Name => 'Rotation',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Horizontal (normal)',
+            6 => 'Rotate 90 CW', #PH (ref 7 gives 270 CW)
+            8 => 'Rotate 270 CW', #PH (ref 7 gives 90 CW)
+        },
+    },
+    # 0x31 - values: 1-5 some sort of mode? (changes with FOC-L) (PH/10)
+    0x32 => { #7
+        Name => 'ColorMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Natural',
+            # 2 => observed in LZ6 for some shooting modes
+        },
+    },
+    0x33 => { #10
+        Name => 'BabyAge',
+        Writable => 'string',
+        Notes => 'or pet age', #PH
+        PrintConv => '$val eq "9999:99:99 00:00:00" ? "(not set)" : $val',
+        PrintConvInv => '$val =~ /^\d/ ? $val : "9999:99:99 00:00:00"',
+    },
+    0x34 => { #7/PH
+        Name => 'OpticalZoomMode',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Standard',
+            2 => 'EX Optics',
+        },
+    },
+    0x35 => { #9
+        Name => 'ConversionLens',
+        Writable => 'int16u',
+        PrintConv => { #PH (unconfirmed)
+            1 => 'Off',
+            2 => 'Wide',
+            3 => 'Telephoto',
+            4 => 'Macro',
+        },
+    },
+    0x36 => { #8
+        Name => 'TravelDay',
+        Writable => 'int16u',
+        PrintConv => '$val == 65535 ? "n/a" : $val',
+        PrintConvInv => '$val =~ /(\d+)/ ? $1 : $val',
+    },
+    # 0x37 - values: 0,1,2 (LZ6, 0 for movie preview) and 257 (FX10K)
+    # 0x38 - values: 0,1,2 (LZ6, same as 0x37) and 1,2 (FX10K)
+    0x3a => {
+        Name => 'WorldTimeLocation',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Home',
+            2 => 'Destination',
+        },
+    },
+    # 0x3b - values: 1 (LZ6, FX10K)
+    0x3c => { #PH
+        Name => 'ProgramISO',
+        Writable => 'int16u',
+        PrintConv => '$val == 65535 ? "n/a" : $val',
+        PrintConvInv => '$val eq "n/a" ? 65535 : $val',
+    },
+    # 0x40 Chroma? (ref 7)
+    0x42 => { #7 (DMC-L1)
+        Name => 'FilmMode',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Standard (color)',
+            2 => 'Dynamic (color)',
+            3 => 'Nature (color)',
+            4 => 'Smooth (color)',
+            5 => 'Standard (B&W)',
+            6 => 'Dynamic (B&W)',
+            7 => 'Smooth (B&W)',
+            # 8 => 'My Film 1'? (from owner manual)
+            # 9 => 'My Film 2'?
+        },
+    },
+    0x46 => { #PH/10
+        Name => 'WBAdjustAB',
+        Format => 'int16s',
+        Writable => 'int16u',
+        Notes => 'positive is a shift toward blue',
+    },
+    0x47 => { #PH/10
+        Name => 'WBAdjustGM',
+        Format => 'int16s',
+        Writable => 'int16u',
+        Notes => 'positive is a shift toward green',
+    },
+    0x51 => {
+        Name => 'LensType',
+        Writable => 'string',
+    },
+    0x52 => { #7 (DMC-L1)
+        Name => 'LensSerialNumber',
+        Writable => 'string',
+    },
+    0x53 => { #7 (DMC-L1)
+        Name => 'AccessoryType',
+        Writable => 'string',
+    },
+    0x0e00 => {
+        Name => 'PrintIM',
+        Description => 'Print Image Matching',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+    0x8000 => { #PH
+        Name => 'MakerNoteVersion',
+        Format => 'undef',
+    },
+    0x8001 => { #7/PH/10
+        Name => 'SceneMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0  => 'Off',
+            %shootingMode,
+        },
+    },
+    # 0x8002 - values: 1,2 related to focus? (PH/10)
+    # 0x8003 - values: 1,2 related to focus? (PH/10)
+    0x8004 => { #PH/10
+        Name => 'WBRedLevel',
+        Writable => 'int16u',
+    },
+    0x8005 => { #PH/10
+        Name => 'WBGreenLevel',
+        Writable => 'int16u',
+    },
+    0x8006 => { #PH/10
+        Name => 'WBBlueLevel',
+        Writable => 'int16u',
+    },
+    # 0x8007 - values: 1,2
+    0x8010 => { #PH
+        Name => 'BabyAge',
+        Writable => 'string',
+        Notes => 'or pet age',
+        PrintConv => '$val eq "9999:99:99 00:00:00" ? "(not set)" : $val',
+        PrintConvInv => '$val =~ /^\d/ ? $val : "9999:99:99 00:00:00"',
+    },
+);
+
+# Type 2 tags (ref PH)
+%Image::ExifTool::Panasonic::Type2 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    FIRST_ENTRY => 0,
+    FORMAT => 'int16u',
+    NOTES => q{
+        This type of maker notes is used by models such as the NV-DS65, PV-D2002,
+        PV-DC3000, PV-DV203, PV-DV401, PV-DV702, PV-L2001, PV-SD4090, PV-SD5000 and
+        iPalm.
+    },
+    0 => {
+        Name => 'MakerNoteType',
+        Format => 'string[4]',
+    },
+    # seems to vary inversely with amount of light, so I'll call it 'Gain' - PH
+    # (minimum is 16, maximum is 136.  Value is 0 for pictures captured from video)
+    3 => 'Gain',
+);
+
+# Tags found in Panasonic RAW images
+%Image::ExifTool::Panasonic::Raw = (
+    GROUPS => { 0 => 'EXIF', 1 => 'IFD0', 2 => 'Image'},
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITE_GROUP => 'IFD0',   # default write group
+    NOTES => 'These tags are found in IFD0 of Panasonic RAW images.',
+    0x01 => {
+        Name => 'PanasonicRawVersion',
+        Writable => 'undef',
+    },
+    0x02 => 'SensorWidth', #5/PH
+    0x03 => 'SensorHeight', #5/PH
+    0x04 => 'SensorTopBorder', #10
+    0x05 => 'SensorLeftBorder', #10
+    0x06 => 'ImageHeight', #5/PH
+    0x07 => 'ImageWidth', #5/PH
+    0x11 => { #10
+        Name => 'RedBalance',
+        Writable => 'int16u',
+        ValueConv => '$val / 256',
+        ValueConvInv => 'int($val * 256 + 0.5)',
+        Notes => 'found in Digilux 2 RAW images',
+    },
+    0x12 => { #10
+        Name => 'BlueBalance',
+        Writable => 'int16u',
+        ValueConv => '$val / 256',
+        ValueConvInv => 'int($val * 256 + 0.5)',
+    },
+    0x17 => { #5
+        Name => 'ISO',
+        Writable => 'int16u',
+    },
+    0x24 => { #6
+        Name => 'WBRedLevel',
+        Writable => 'int16u',
+    },
+    0x25 => { #6
+        Name => 'WBGreenLevel',
+        Writable => 'int16u',
+    },
+    0x26 => { #6
+        Name => 'WBBlueLevel',
+        Writable => 'int16u',
+    },
+    0x10f => {
+        Name => 'Make',
+        Groups => { 2 => 'Camera' },
+        Writable => 'string',
+        DataMember => 'CameraMake',
+        # save this value as an ExifTool member variable
+        RawConv => '$self->{CameraMake} = $val',
+    },
+    0x110 => {
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Groups => { 2 => 'Camera' },
+        Writable => 'string',
+        DataMember => 'CameraModel',
+        # save this value as an ExifTool member variable
+        RawConv => '$self->{CameraModel} = $val',
+    },
+    0x111 => {
+        Name => 'StripOffsets',
+        Flags => 'IsOffset',
+        OffsetPair => 0x117,  # point to associated byte counts
+        ValueConv => 'length($val) > 32 ? \$val : $val',
+    },
+    0x112 => {
+        Name => 'Orientation',
+        Writable => 'int16u',
+        PrintConv => \%Image::ExifTool::Exif::orientation,
+        Priority => 0,  # so IFD1 doesn't take precedence
+    },
+    0x116 => {
+        Name => 'RowsPerStrip',
+        Priority => 0,
+    },
+    0x117 => {
+        Name => 'StripByteCounts',
+        OffsetPair => 0x111,   # point to associated offset
+        ValueConv => 'length($val) > 32 ? \$val : $val',
+    },
+    0x8769 => {
+        Name => 'ExifOffset',
+        Groups => { 1 => 'ExifIFD' },
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            DirName => 'ExifIFD',
+            Start => '$val',
+        },
+    },
+    0x8825 => {
+        Name => 'GPSInfo',
+        Groups => { 1 => 'GPS' },
+        Flags => 'SubIFD',
+        SubDirectory => {
+            DirName => 'GPS',
+            TagTable => 'Image::ExifTool::GPS::Main',
+            Start => '$val',
+        },
+    },
+);
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Panasonic - Panasonic/Leica maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+Panasonic and Leica maker notes in EXIF information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.compton.nu/panasonic.html>
+
+=item L<http://johnst.org/sw/exiftags/>
+
+=item L<http://www.cybercom.net/~dcoffin/dcraw/>
+
+=item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_pana.htm>
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Tels for the information he provided on decoding some tags, and to
+Marcel Coenen and Jens Duttke for their contributions.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Panasonic Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Pentax.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Pentax.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Pentax.pm	(revision 20131)
@@ -0,0 +1,1810 @@
+#------------------------------------------------------------------------------
+# File:         Pentax.pm
+#
+# Description:  Pentax/Asahi EXIF maker notes tags
+#
+# Revisions:    11/25/2003 - P. Harvey Created
+#               02/10/2004 - P. Harvey Completely re-done
+#               02/16/2004 - W. Smith Updated (see ref 3)
+#               11/10/2004 - P. Harvey Added support for Asahi cameras
+#               01/10/2005 - P. Harvey Added NikonLens with values from ref 4
+#               03/30/2005 - P. Harvey Added new tags from ref 5
+#               10/04/2005 - P. Harvey Added MOV tags
+#
+# References:   1) Image::MakerNotes::Pentax
+#               2) http://johnst.org/sw/exiftags/ (Asahi cameras)
+#               3) Wayne Smith private communication (Optio 550)
+#               4) http://kobe1995.jp/~kaz/astro/istD.html
+#               5) John Francis (http://www.panix.com/~johnf/raw/index.html) (ist-D/ist-DS)
+#               6) http://www.cybercom.net/~dcoffin/dcraw/
+#               7) Douglas O'Brien private communication (*istD, K10D)
+#               8) Denis Bourez private communication
+#               9) Kazumichi Kawabata private communication
+#              10) David Buret private communication (*istD)
+#              11) http://forums.dpreview.com/forums/read.asp?forum=1036&message=17465929
+#              12) Derby Chang private communication
+#              13) http://homepage3.nifty.com/kamisaka/makernote/makernote_pentax.htm
+#              14) Ger Vermeulen private communication (Optio S6)
+#              15) Barney Garrett private communication (Samsung GX-1S)
+#              16) Axel Kellner private communication (K10D)
+#              17) Cvetan Ivanov private communication (K100D)
+#              18) http://www.gvsoft.homedns.org/exif/makernote-pentax-type3.html
+#              19) Jens Duttke private communication
+#
+# Notes:        See POD documentation at the bottom of this file
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Pentax;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::Exif;
+use Image::ExifTool::HP;
+
+$VERSION = '1.61';
+
+sub CryptShutterCount($$);
+
+# pentax lens type codes (ref 4)
+my %pentaxLensType = (
+    '0 0' => 'M-42 or No Lens', #17
+    '1 0' => 'K,M Lens',
+    '2 0' => 'A Series Lens', #7 (from smc PENTAX-A 400mm F5.6)
+    '3 0' => 'SIGMA',
+    '3 17' => 'smc PENTAX-FA SOFT 85mm F2.8',
+    '3 18' => 'smc PENTAX-F 1.7X AF ADAPTER',
+    '3 19' => 'smc PENTAX-F 24-50mm F4',
+    '3 20' => 'smc PENTAX-F 35-80mm F4-5.6',
+    '3 21' => 'smc PENTAX-F 80-200mm F4.7-5.6',
+    '3 22' => 'smc PENTAX-F FISH-EYE 17-28mm F3.5-4.5',
+    '3 23' => 'smc PENTAX-F 100-300mm F4.5-5.6',
+    '3 24' => 'smc PENTAX-F 35-135mm F3.5-4.5',
+    '3 25' => 'smc PENTAX-F 35-105mm F4-5.6 or SIGMA or Tokina',
+    # or '3 25' => SIGMA AF 28-300 F3.5-5.6 DL IF', #11
+    # or '3 25' => 'Tokina 80-200mm F2.8 ATX-Pro', #12
+    # or '3 25' => 'SIGMA 55-200mm F4-5.6 DC', #19
+    '3 26' => 'smc PENTAX-F* 250-600mm F5.6 ED[IF]',
+    '3 27' => 'smc PENTAX-F 28-80mm F3.5-4.5',
+    '3 28' => 'smc PENTAX-F 35-70mm F3.5-4.5',
+    # or '3 28' => 'Tokina 19-35mm F3.5-4.5 AF', #12
+    '3 29' => 'PENTAX-F 28-80mm F3.5-4.5 or SIGMA AF 18-125mm F3.5-5.6 DC', #11 (sigma)
+    '3 30' => 'PENTAX-F 70-200mm F4-5.6',
+    '3 31' => 'smc PENTAX-F 70-210mm F4-5.6',
+    # or '3 31' => 'Tokina AF 730 75-300mm F4.5-5.6',
+    '3 32' => 'smc PENTAX-F 50mm F1.4',
+    '3 33' => 'smc PENTAX-F 50mm F1.7',
+    '3 34' => 'smc PENTAX-F 135mm F2.8 [IF]',
+    '3 35' => 'smc PENTAX-F 28mm F2.8',
+    '3 36' => 'SIGMA 20mm F1.8 EX DG ASPHERICAL RF',
+    '3 38' => 'smc PENTAX-F* 300mm F4.5 ED[IF]',
+    '3 39' => 'smc PENTAX-F* 600mm F4 ED[IF]',
+    '3 40' => 'smc PENTAX-F MACRO 100mm F2.8',
+    '3 41' => 'smc PENTAX-F MACRO 50mm F2.8 or Sigma 50mm F2,8 MACRO', #4,16
+    #'3 44' => 'SIGMA 17-70mm F2.8-4.5 DC MACRO', (Bart Hickman)
+    #'3 44' => 'SIGMA 18-50mm F3.5-5.6 DC, 12-24mm F4.5 EX DG or Tamron 35-90mm F4 AF', #4,12,12
+    #'3 44' => 'SIGMA AF 10-20mm F4-5.6 EX DC', #19
+    '3 44' => 'Tamron 35-90mm F4 AF or various SIGMA models', #4,12,Bart,19
+    '3 46' => 'SIGMA APO 70-200mm F2.8 EX',
+    '3 50' => 'smc PENTAX-FA 28-70mm F4 AL',
+    '3 51' => 'SIGMA 28mm F1.8 EX DG ASPHERICAL MACRO',
+    '3 52' => 'smc PENTAX-FA 28-200mm F3.8-5.6 AL[IF]',
+    # or '3 52' => 'Tamron AF LD 28-200mm F3.8-5.6 (IF) Aspherical (171D), #19
+    '3 53' => 'smc PENTAX-FA 28-80mm F3.5-5.6 AL',
+    '3 247' => 'smc PENTAX-DA FISH-EYE 10-17mm F3.5-4.5 ED[IF]',
+    '3 248' => 'smc PENTAX-DA 12-24mm F4 ED AL[IF]',
+    '3 250' => 'smc PENTAX-DA 50-200mm F4-5.6 ED',
+    '3 251' => 'smc PENTAX-DA 40mm F2.8 Limited',
+    '3 252' => 'smc PENTAX-DA 18-55mm F3.5-5.6 AL',
+    '3 253' => 'smc PENTAX-DA 14mm F2.8 ED[IF]',
+    '3 254' => 'smc PENTAX-DA 16-45mm F4 ED AL',
+    '3 255' => 'SIGMA',
+    # '3 255' => 'SIGMA 18-200mm F3.5-6.3 DC', #8
+    # '3 255' => 'SIGMA DL-II 35-80mm F4-5.6', #12
+    # '3 255' => 'SIGMA DL Zoom 75-300mm F4-5.6', #12
+    # '3 255' => 'SIGMA DF EX Aspherical 28-70mm F2.8', #12
+    # '3 255' => 'SIGMA AF Tele 400mm F5.6 Multi-coated', #19
+    '4 1' => 'smc PENTAX-FA SOFT 28mm F2.8',
+    '4 2' => 'smc PENTAX-FA 80-320mm F4.5-5.6',
+    '4 3' => 'smc PENTAX-FA 43mm F1.9 Limited',
+    '4 6' => 'smc PENTAX-FA 35-80mm F4-5.6',
+    '4 12' => 'smc PENTAX-FA 50mm F1.4', #17
+    '4 15' => 'smc PENTAX-FA 28-105mm F4-5.6 [IF]',
+    '4 16' => 'TAMRON AF 80-210mm F4-5.6 (178D)', #13
+    '4 19' => 'TAMRON SP AF 90mm F2.8 (172E)',
+    '4 20' => 'smc PENTAX-FA 28-80mm F3.5-5.6',
+    '4 22' => 'TOKINA 28-80mm F3.5-5.6', #13
+    '4 23' => 'smc PENTAX-FA 20-35mm F4 AL',
+    '4 24' => 'smc PENTAX-FA 77mm F1.8 Limited',
+    '4 25' => 'TAMRON SP AF 14mm F2.8', #13
+    '4 26' => 'smc PENTAX-FA MACRO 100mm F3.5',
+    '4 27' => 'TAMRON AF28-300mm F/3.5-6.3 LD Aspherical[IF] MACRO (285D)',
+    '4 28' => 'smc PENTAX-FA 35mm F2 AL',
+    '4 29' => 'TAMRON AF 28-200mm F/3.8-5.6 LD Super II MACRO (371D)', #19
+    '4 34' => 'smc PENTAX-FA 24-90mm F3.5-4.5 AL[IF]',
+    '4 35' => 'smc PENTAX-FA 100-300mm F4.7-5.8',
+    '4 36' => 'TAMRON AF70-300mm F/4-5.6 LD MACRO', # both 572D and A17 (Di) - ref 19
+    '4 37' => 'TAMRON SP AF 24-135mm F3.5-5.6 AD AL (190D)', #13
+    '4 38' => 'smc PENTAX-FA 28-105mm F3.2-4.5 AL[IF]',
+    '4 39' => 'smc PENTAX-FA 31mm F1.8AL Limited',
+    '4 41' => 'TAMRON AF 28-200mm Super Zoom F3.8-5.6 Aspherical XR [IF] MACRO (A03)',
+    '4 43' => 'smc PENTAX-FA 28-90mm F3.5-5.6',
+    '4 44' => 'smc PENTAX-FA J 75-300mm F4.5-5.8 AL',
+    '4 45' => 'TAMRON 28-300mm F3.5-6.3 Ultra zoom XR',
+    '4 46' => 'smc PENTAX-FA J 28-80mm F3.5-5.6 AL',
+    '4 47' => 'smc PENTAX-FA J 18-35mm F4-5.6 AL',
+    '4 49' => 'TAMRON SP AF 28-75mm F2.8 XR Di (A09)',
+    '4 51' => 'smc PENTAX-D FA 50mm F2.8 MACRO',
+    '4 52' => 'smc PENTAX-D FA 100mm F2.8 MACRO',
+    '4 244' => 'smc PENTAX-DA 21mm F3.2 AL Limited', #9
+    '4 245' => 'Schneider D-XENON 50-200mm', #15
+    '4 246' => 'Schneider D-XENON 18-55mm', #15
+    '4 247' => 'smc PENTAX-DA 10-17mm F3.5-4.5 ED [IF] Fisheye zoom', #10
+    '4 248' => 'smc PENTAX-DA 12-24mm F4 ED AL [IF]', #10
+    '4 249' => 'TAMRON XR DiII 18-200mm F3.5-6.3 (A14)',
+    '4 250' => 'smc PENTAX-DA 50-200mm F4-5.6 ED', #8
+    '4 251' => 'smc PENTAX-DA 40mm F2.8 Limited', #9
+    '4 252' => 'smc PENTAX-DA 18-55mm F3.5-5.6 AL', #8
+    '4 253' => 'smc PENTAX-DA 14mm F2.8 ED[IF]',
+    '4 254' => 'smc PENTAX-DA 16-45mm F4 ED AL',
+    '5 1' => 'smc PENTAX-FA* 24mm F2 AL[IF]',
+    '5 2' => 'smc PENTAX-FA 28mm F2.8 AL',
+    '5 3' => 'smc PENTAX-FA 50mm F1.7',
+    '5 4' => 'smc PENTAX-FA 50mm F1.4',
+    '5 5' => 'smc PENTAX-FA* 600mm F4 ED[IF]',
+    '5 6' => 'smc PENTAX-FA* 300mm F4.5 ED[IF]',
+    '5 7' => 'smc PENTAX-FA 135mm F2.8 [IF]',
+    '5 8' => 'smc PENTAX-FA MACRO 50mm F2.8',
+    '5 9' => 'smc PENTAX-FA MACRO 100mm F2.8',
+    '5 10' => 'smc PENTAX-FA* 85mm F1.4 [IF]',
+    '5 11' => 'smc PENTAX-FA* 200mm F2.8 ED[IF]',
+    '5 12' => 'smc PENTAX-FA 28-80mm F3.5-4.7',
+    '5 13' => 'smc PENTAX-FA 70-200mm F4-5.6',
+    '5 14' => 'smc PENTAX-FA* 250-600mm F5.6 ED[IF]',
+    '5 15' => 'smc PENTAX-FA 28-105mm F4-5.6',
+    '5 16' => 'smc PENTAX-FA 100-300mm F4.5-5.6',
+    '6 1' => 'smc PENTAX-FA* 85mm F1.4[IF]',
+    '6 2' => 'smc PENTAX-FA* 200mm F2.8 ED[IF]',
+    '6 3' => 'smc PENTAX-FA* 300mm F2.8 ED[IF]',
+    '6 4' => 'smc PENTAX-FA* 28-70mm F2.8 AL',
+    '6 5' => 'smc PENTAX-FA* 80-200mm F2.8 ED[IF]',
+    '6 6' => 'smc PENTAX-FA* 28-70mm F2.8 AL',
+    '6 7' => 'smc PENTAX-FA* 80-200mm F2.8 ED[IF]',
+    '6 8' => 'smc PENTAX-FA 28-70mm F4AL',
+    '6 9' => 'smc PENTAX-FA 20mm F2.8',
+    '6 10' => 'smc PENTAX-FA* 400mm F5.6 ED[IF]',
+    '6 13' => 'smc PENTAX-FA* 400mm F5.6 ED[IF]',
+    '6 14' => 'smc PENTAX-FA* MACRO 200mm F4 ED[IF]',
+    '7 0' => 'smc PENTAX-DA 21mm F3.2 AL Limited', #13
+    '7 238' => 'TAMRON AF 18-250mm F3.5-6.3 Di II LD Aspherical [IF] MACRO', #19
+    '7 243' => 'smc PENTAX-DA 70mm F2.4 Limited', #PH (K10D)
+    '7 244' => 'smc PENTAX-DA 21mm F3.2 AL Limited', #16
+    '8 241' => 'smc PENTAX-DA* 50-135mm F2.8 ED [IF] SDM', #19
+    '8 242' => 'smc PENTAX-DA* 16-50mm F2.8 ED AL [IF] SDM', #19
+);
+
+# Pentax model ID codes (PH)
+my %pentaxModelID = (
+    0x0000d => 'Optio 330/430',
+    0x12926 => 'Optio 230',
+    0x12958 => 'Optio 330GS',
+    0x12962 => 'Optio 450/550',
+    0x1296c => 'Optio S',
+    0x12994 => '*ist D',
+    0x129b2 => 'Optio 33L',
+    0x129bc => 'Optio 33LF',
+    0x129c6 => 'Optio 33WR/43WR/555',
+    0x129d5 => 'Optio S4',
+    0x12a02 => 'Optio MX',
+    0x12a0c => 'Optio S40',
+    0x12a16 => 'Optio S4i',
+    0x12a34 => 'Optio 30',
+    0x12a52 => 'Optio S30',
+    0x12a66 => 'Optio 750Z',
+    0x12a70 => 'Optio SV',
+    0x12a75 => 'Optio SVi',
+    0x12a7a => 'Optio X',
+    0x12a8e => 'Optio S5i',
+    0x12a98 => 'Optio S50',
+    0x12aa2 => '*ist DS',
+    0x12ab6 => 'Optio MX4',
+    0x12ac0 => 'Optio S5n',
+    0x12aca => 'Optio WP',
+    0x12afc => 'Optio S55',
+    0x12b10 => 'Optio S5z',
+    0x12b1a => '*ist DL',
+    0x12b24 => 'Optio S60',
+    0x12b2e => 'Optio S45',
+    0x12b38 => 'Optio S6',
+    0x12b4c => 'Optio WPi', #13
+    0x12b56 => 'BenQ DC X600',
+    0x12b60 => '*ist DS2',
+    0x12b62 => 'Samsung GX-1S',
+    0x12b6a => 'Optio A10',
+    0x12b7e => '*ist DL2',
+    0x12b80 => 'Samsung GX-1L',
+    0x12b9c => 'K100D',
+    0x12b9d => 'K110D',
+    0x12ba2 => 'K100D Super', #19
+    0x12bb0 => 'Optio T10/T20',
+    0x12be2 => 'Optio W10',
+    0x12bf6 => 'Optio M10',
+    0x12c1e => 'K10D',
+    0x12c20 => 'Samsung GX10',
+    0x12c28 => 'Optio S7',
+    0x12c2d => 'Optio L20',
+    0x12c32 => 'Optio M20',
+    0x12c3c => 'Optio W20',
+    0x12c46 => 'Optio A20',
+    0x12c8c => 'Optio M30',
+    0x12c78 => 'Optio E30',
+    0x12c82 => 'Optio T30',
+    0x12c96 => 'Optio W30',
+    0x12ca0 => 'Optio A30',
+    0x12cb4 => 'Optio E40',
+    0x12cbe => 'Optio M40',
+    0x12cc8 => 'Optio Z10',
+    0x12cdc => 'Optio S10',
+    0x12ce6 => 'Optio A40',
+    0x12cf0 => 'Optio V10',
+);
+
+# Pentax city codes - (PH, Optio WP)
+my %pentaxCities = (
+    0 => 'Pago Pago',
+    1 => 'Honolulu',
+    2 => 'Anchorage',
+    3 => 'Vancouver',
+    4 => 'San Fransisco',
+    5 => 'Los Angeles',
+    6 => 'Calgary',
+    7 => 'Denver',
+    8 => 'Mexico City',
+    9 => 'Chicago',
+    10 => 'Miami',
+    11 => 'Toronto',
+    12 => 'New York',
+    13 => 'Santiago',
+    14 => 'Caracus',
+    15 => 'Halifax',
+    16 => 'Buenos Aires',
+    17 => 'Sao Paulo',
+    18 => 'Rio de Janeiro',
+    19 => 'Madrid',
+    20 => 'London',
+    21 => 'Paris',
+    22 => 'Milan',
+    23 => 'Rome',
+    24 => 'Berlin',
+    25 => 'Johannesburg',
+    26 => 'Istanbul',
+    27 => 'Cairo',
+    28 => 'Jerusalem',
+    29 => 'Moscow',
+    30 => 'Jeddah',
+    31 => 'Tehran',
+    32 => 'Dubai',
+    33 => 'Karachi',
+    34 => 'Kabul',
+    35 => 'Male',
+    36 => 'Delhi',
+    37 => 'Colombo',
+    38 => 'Kathmandu',
+    39 => 'Dacca',
+    40 => 'Yangon',
+    41 => 'Bangkok',
+    42 => 'Kuala Lumpur',
+    43 => 'Vientiane',
+    44 => 'Singapore',
+    45 => 'Phnom Penh',
+    46 => 'Ho Chi Minh',
+    47 => 'Jakarta',
+    48 => 'Hong Kong',
+    49 => 'Perth',
+    50 => 'Beijing',
+    51 => 'Shanghai',
+    52 => 'Manila',
+    53 => 'Taipei',
+    54 => 'Seoul',
+    55 => 'Adelaide',
+    56 => 'Tokyo',
+    57 => 'Guam',
+    58 => 'Sydney',
+    59 => 'Noumea',
+    60 => 'Wellington',
+    61 => 'Auckland',
+    62 => 'Lima',
+    63 => 'Dakar',
+    64 => 'Algiers',
+    65 => 'Helsinki',
+    66 => 'Athens',
+    67 => 'Nairobi',
+    68 => 'Amsterdam',
+    69 => 'Stockholm',
+    70 => 'Lisbon', #14
+);
+
+%Image::ExifTool::Pentax::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITABLE => 1,
+    0x0000 => { #5
+        Name => 'PentaxVersion',
+        Writable => 'int8u',
+        Count => 4,
+        PrintConv => '$val=~tr/ /./; $val',
+        PrintConvInv => '$val=~tr/./ /; $val',
+    },
+    0x0001 => { #PH
+        Name => 'PentaxModelType',
+        Writable => 'int16u',
+        # (values of 0-5 seem to group models into 6 categories, ref 13)
+    },
+    0x0002 => { #PH
+        Name => 'PreviewImageSize',
+        Groups => { 2 => 'Image' },
+        Writable => 'int16u',
+        Count => 2,
+        PrintConv => '$val =~ tr/ /x/; $val',
+    },
+    0x0003 => { #PH
+        Name => 'PreviewImageLength',
+        OffsetPair => 0x0004, # point to associated offset
+        DataTag => 'PreviewImage',
+        Groups => { 2 => 'Image' },
+        Writable => 'int32u',
+        Protected => 2,
+    },
+    0x0004 => { #PH
+        Name => 'PreviewImageStart',
+        IsOffset => 2,  # code to use original base
+        Protected => 2,
+        OffsetPair => 0x0003, # point to associated byte count
+        DataTag => 'PreviewImage',
+        Groups => { 2 => 'Image' },
+        Writable => 'int32u',
+    },
+    0x0005 => { #13
+        Name => 'PentaxModelID',
+        Writable => 'int32u',
+        PrintHex => 1,
+        SeparateTable => 1,
+        PrintConv => \%pentaxModelID,
+    },
+    0x0006 => { #5
+        # Note: Year is int16u in MM byte ordering regardless of EXIF byte order
+        Name => 'Date',
+        Groups => { 2 => 'Time' },
+        Writable => 'undef',
+        Count => 4,
+        Shift => 'Time',
+        DataMember => 'PentaxDate',
+        RawConv => '$$self{PentaxDate} = $val', # save to decrypt ShutterCount
+        ValueConv => 'length($val)==4 ? sprintf("%.4d:%.2d:%.2d",unpack("nC2",$val)) : "Unknown ($val)"',
+        ValueConvInv => 'my @v=split /:/, $val;pack("nC2",$v[0],$v[1],$v[2])',
+    },
+    0x0007 => { #5
+        Name => 'Time',
+        Groups => { 2 => 'Time' },
+        Writable => 'undef',
+        Count => 3,
+        Shift => 'Time',
+        DataMember => 'PentaxTime',
+        RawConv => '$$self{PentaxTime} = $val', # save to decrypt ShutterCount
+        ValueConv => 'length($val)>=3 ? sprintf("%.2d:%.2d:%.2d",unpack("C3",$val)) : "Unknown ($val)"',
+        ValueConvInv => 'pack("C3",split(/:/,$val))',
+    },
+    0x0008 => { #2
+        Name => 'Quality',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Good',
+            1 => 'Better',
+            2 => 'Best',
+            3 => 'TIFF', #5
+            4 => 'RAW', #5
+        },
+    },
+    0x0009 => { #3
+        Name => 'PentaxImageSize',
+        Groups => { 2 => 'Image' },
+        Writable => 'int16u',
+        PrintConv => {
+            0 => '640x480',
+            1 => 'Full', #PH - this can mean 2048x1536 or 2240x1680 or ... ?
+            2 => '1024x768',
+            3 => '1280x960', #PH (Optio WP)
+            4 => '1600x1200',
+            5 => '2048x1536',
+            8 => '2560x1920 or 2304x1728', #PH (Optio WP) or #14
+            9 => '3072x2304', #PH (Optio M30)
+            10 => '3264x2448', #13
+            19 => '320x240', #PH (Optio WP)
+            20 => '2288x1712', #13
+            21 => '2592x1944',
+            22 => '2304x1728 or 2592x1944', #2 or #14
+            23 => '3056x2296', #13
+            25 => '2816x2212 or 2816x2112', #13 or #14
+            27 => '3648x2736', #PH (Optio A20)
+            '0 0' => '2304x1728', #13
+            '4 0' => '1600x1200', #PH (Optio MX4)
+            '5 0' => '2048x1536', #13
+            '8 0' => '2560x1920', #13
+            '32 2' => '960x640', #7
+            '33 2' => '1152x768', #7
+            '34 2' => '1536x1024', #7
+            '35 1' => '2400x1600', #7
+            '36 0' => '3008x2008 or 3040x2024',  #PH
+            '37 0' => '3008x2000', #13
+        },
+    },
+    # 0x000a - (See note below)
+    0x000b => { #3
+        Name => 'PictureMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Program', #PH
+            2 => 'Program AE', #13
+            3 => 'Manual', #13
+            5 => 'Portrait',
+            6 => 'Landscape',
+            8 => 'Sport', #PH
+            9 => 'Night Scene',
+            11 => 'Soft', #PH
+            12 => 'Surf & Snow',
+            13 => 'Sunset or Candlelight', #14 (Candlelight)
+            14 => 'Autumn',
+            15 => 'Macro',
+            17 => 'Fireworks',
+            18 => 'Text',
+            19 => 'Panorama', #PH
+            30 => 'Self Portrait', #PH
+            31 => 'Illustrations', #13
+            33 => 'Digital Filter', #13
+            37 => 'Museum', #PH
+            38 => 'Food', #PH
+            40 => 'Green Mode', #PH
+            49 => 'Light Pet', #PH
+            50 => 'Dark Pet', #PH
+            51 => 'Medium Pet', #PH
+            53 => 'Underwater', #PH
+            54 => 'Candlelight', #PH
+            55 => 'Natural Skin Tone', #PH
+            56 => 'Synchro Sound Record', #PH
+            58 => 'Frame Composite', #14
+            '0 0' => 'Auto', #13
+            '0 2' => 'Program AE', #13
+            '5 2' => 'Portrait', #13
+            '6 2' => 'Landscape', #13
+            '9 1' => 'Night Scene', #13
+            '13 1' => 'Candlelight', #13
+            '15 1' => 'Macro', #13
+            '255 0' => 'Digital Filter?', #13
+        },
+    },
+    0x000c => { #PH
+        Name => 'FlashMode',
+        Writable => 'int16u',
+        PrintHex => 1,
+        ValueConv => '$val=~s/ .*//; $val', # ignore 2nd value
+        PrintConv => {
+            0x000 => 'Auto, Did not fire',
+            0x001 => 'Off',
+            0x003 => 'Auto, Did not fire, Red-eye reduction',
+            0x100 => 'Auto, Fired',
+            0x102 => 'On',
+            0x103 => 'Auto, Fired, Red-eye reduction',
+            0x104 => 'On, Red-eye reduction',
+            0x105 => 'On, Wireless',
+            0x108 => 'On, Soft',
+            0x109 => 'On, Slow-sync',
+            0x10a => 'On, Slow-sync, Red-eye reduction',
+            0x10b => 'On, Trailing-curtain Sync',
+        },
+    },
+    0x000d => [ #2
+        {
+            Condition => '$self->{CameraMake} =~ /^PENTAX/',
+            Name => 'FocusMode',
+            Notes => 'Pentax models',
+            Writable => 'int16u',
+            PrintConv => { #PH
+                0 => 'Normal',
+                1 => 'Macro',
+                2 => 'Infinity',
+                3 => 'Manual',
+                5 => 'Pan Focus',
+                16 => 'AF-S', #17
+                17 => 'AF-C', #17
+            },
+        },
+        {
+            Name => 'FocusMode',
+            Writable => 'int16u',
+            Notes => 'Asahi models',
+            PrintConv => { #2
+                0 => 'Normal',
+                1 => 'Macro (1)',
+                2 => 'Macro (2)',
+                3 => 'Infinity',
+            },
+        },
+    ],
+    0x000e => { #7
+        Name => 'AFPointSelected',
+        Writable => 'int16u',
+        PrintConv => {
+            0xffff => 'Auto',
+            0xfffe => 'Fixed Center',
+            1 => 'Upper-left',
+            2 => 'Top',
+            3 => 'Upper-right',
+            4 => 'Left',
+            5 => 'Mid-left',
+            6 => 'Center',
+            7 => 'Mid-right',
+            8 => 'Right',
+            9 => 'Lower-left',
+            10 => 'Bottom',
+            11 => 'Lower-right',
+        },
+    },
+    0x000f => { #PH
+        Name => 'AFPointsInFocus',
+        Writable => 'int16u',
+        PrintHex => 1,
+        PrintConv => {
+            0xffff => 'None',
+            0 => 'Fixed Center or Multiple', #PH/14
+            1 => 'Top-left',
+            2 => 'Top-center',
+            3 => 'Top-right',
+            4 => 'Left',
+            5 => 'Center',
+            6 => 'Right',
+            7 => 'Bottom-left',
+            8 => 'Bottom-center',
+            9 => 'Bottom-right',
+        },
+    },
+    0x0010 => { #PH
+        Name => 'FocusPosition',
+        Writable => 'int16u',
+        Notes => 'related to focus distance but affected by focal length',
+    },
+    0x0012 => { #PH
+        Name => 'ExposureTime',
+        Writable => 'int32u',
+        Priority => 0,
+        ValueConv => '$val * 1e-5',
+        ValueConvInv => '$val * 1e5',
+        # value may be 0xffffffff in Bulb mode (ref 19)
+        PrintConv => '$val > 42949 ? "Unknown (Bulb)" : Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => '$val=~/(unknown|bulb)/i ? $val : eval $val',
+    },
+    0x0013 => { #PH
+        Name => 'FNumber',
+        Writable => 'int16u',
+        Priority => 0,
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    # ISO Tag - Entries confirmed by W. Smith 12 FEB 04
+    0x0014 => {
+        Name => 'ISO',
+        Writable => 'int16u',
+        Priority => 0,
+        PrintConv => {
+            3 => 50, #(NC=Not Confirmed)
+            4 => 64,
+            5 => 80, #(NC)
+            6 => 100,
+            7 => 125, #PH
+            8 => 160, #PH
+            9 => 200,
+            10 => 250, #(NC)
+            11 => 320, #PH
+            12 => 400,
+            13 => 500, #(NC)
+            14 => 640, #(NC)
+            15 => 800,
+            16 => 1000, #(NC)
+            17 => 1250, #(NC)
+            18 => 1600, #PH
+            21 => 3200, #(NC)
+            50 => 50, #PH
+            100 => 100, #PH
+            200 => 200, #PH
+            400 => 400, #PH
+            800 => 800, #PH
+            1600 => 1600, #PH
+            3200 => 3200, #PH
+            # have seen 268 for ISO 1600 on K10D - PH
+        },
+    },
+    # 0x0015 - Related to measured EV? ranges from -2 to 6 if interpreted as signed int (PH)
+    0x0016 => { #PH
+        Name => 'ExposureCompensation',
+        Writable => 'int16u',
+        ValueConv => '($val - 50) / 10',
+        ValueConvInv => 'int($val * 10 + 50.5)',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => 'eval $val',
+    },
+    0x0017 => { #3
+        Name => 'MeteringMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Multi Segment',
+            1 => 'Center Weighted',
+            2 => 'Spot',
+        },
+    },
+    0x0018 => { #PH
+        Name => 'AutoBracketing',
+        Writable => 'int16u',
+        Count => -1,
+        Notes => q{
+            one or two numbers: exposure bracket step in EV, then extended bracket if
+            available.  Extended bracket values are printed as 'WB-BA', 'WB-GM',
+            'Saturation', 'Sharpness' or 'Contrast' followed by '+1', '+2' or '+3' for
+            step size
+        },
+        ValueConv => sub {
+            my @v = split(' ', shift);
+            if ($v[0] < 10) {
+                $v[0] /= 3;     # 1=.3ev, 2=.7, 3=1...
+            } else {
+                $v[0] -= 9.5;   # 10=.5ev, 11=1.5...
+            }
+            return "@v";
+        },
+        ValueConvInv => sub {
+            my @v = split(' ', shift);
+            if (abs($v[0]-int($v[0])-.5) > 0.05) {
+                $v[0] = int($v[0] * 3 + 0.5);
+            } else {
+                $v[0] = int($v[0] + 10);
+            }
+            return "@v";
+        },
+        PrintConv => sub {
+            my @v = split(' ', shift);
+            $v[0] = sprintf('%.1f', $v[0]) if $v[0];
+            if ($v[1]) {
+                my %s = (1=>'WB-BA',2=>'WB-GM',3=>'Saturation',4=>'Sharpness',5=>'Contrast');
+                my $t = $v[1] >> 8;
+                $v[1] = sprintf('%s+%d', $s{$t} || "Unknown($t)", $v[1] & 0xff);
+            } elsif (defined $v[1]) {
+                $v[1] = 'No Extended Bracket',
+            }
+            return join(' EV, ', @v);
+        },
+        PrintConvInv => sub {
+            my @v = split(/, ?/, shift);
+            $v[0] =~ s/ ?EV//i;
+            if ($v[1]) {
+                my %s = ('WB-BA'=>1,'WB-GM'=>2,Saturation=>3,Sharpness=>4,Contrast=>5);
+                if ($v[1] =~ /^No\b/i) {
+                    $v[1] = 0;
+                } elsif ($v[1] =~ /Unknown\((\d+)\)\+(\d+)/i) {
+                    $v[1] = ($1 << 8) + $2;
+                } elsif ($v[1] =~ /([\w-]+)\+(\d+)/ and $s{$1}) {
+                    $v[1] = ($s{$1} << 8) + $2;
+                } else {
+                    warn "Bad extended bracket\n";
+                }
+            }
+            return "@v";
+        },
+    },
+    0x0019 => { #3
+        Name => 'WhiteBalance',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Daylight',
+            2 => 'Shade',
+            3 => 'Fluorescent', #2
+            4 => 'Tungsten',
+            5 => 'Manual',
+            6 => 'DaylightFluorescent', #13
+            7 => 'DaywhiteFluorescent', #13
+            8 => 'WhiteFluorescent', #13
+            9 => 'Flash', #13
+            10 => 'Cloudy', #13
+            65534 => 'Unknown', #13
+            65535 => 'User Selected', #13
+        },
+    },
+    0x001a => { #5
+        Name => 'WhiteBalanceMode',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Auto (Daylight)',
+            2 => 'Auto (Shade)',
+            3 => 'Auto (Flash)',
+            4 => 'Auto (Tungsten)',
+            7 => 'Auto (DaywhiteFluorescent)', #17 (K100D guess)
+            8 => 'Auto (WhiteFluorescent)', #17 (K100D guess)
+            10 => 'Auto (Cloudy)', #17 (K100D guess)
+            0xffff => 'User-Selected',
+            0xfffe => 'Preset (Fireworks?)', #PH
+            # 0xfffd observed in K100D (ref 17)
+        },
+    },
+    0x001b => { #6
+        Name => 'BlueBalance',
+        Writable => 'int16u',
+        ValueConv => '$val / 256',
+        ValueConvInv => 'int($val * 256 + 0.5)',
+    },
+    0x001c => { #6
+        Name => 'RedBalance',
+        Writable => 'int16u',
+        ValueConv => '$val / 256',
+        ValueConvInv => 'int($val * 256 + 0.5)',
+    },
+    0x001d => [
+        # Would be nice if there was a general way to determine units for FocalLength...
+        {
+            # Optio 30, 33WR, 43WR, 450, 550, 555, 750Z, X
+            Name => 'FocalLength',
+            Condition => '$self->{CameraModel} =~ /^PENTAX Optio (30|33WR|43WR|450|550|555|750Z|X)\b/',
+            Writable => 'int32u',
+            Priority => 0,
+            ValueConv => '$val / 10',
+            ValueConvInv => '$val * 10',
+            PrintConv => 'sprintf("%.1fmm",$val)',
+            PrintConvInv => '$val=~s/mm//;$val',
+        },
+        {
+            # K100D, Optio 230, 330GS, 33L, 33LF, A10, M10, MX, MX4, S, S30,
+            # S4, S4i, S5i, S5n, S5z, S6, S45, S50, S55, S60, SV, Svi, W10, WP,
+            # *ist D, DL, DL2, DS, DS2
+            # (Note: the Optio S6 seems to report the minimum focal length - PH)
+            Name => 'FocalLength',
+            Writable => 'int32u',
+            Priority => 0,
+            ValueConv => '$val / 100',
+            ValueConvInv => '$val * 100',
+            PrintConv => 'sprintf("%.1fmm",$val)',
+            PrintConvInv => '$val=~s/mm//;$val',
+        },
+    ],
+    0x001e => { #3
+        Name => 'DigitalZoom',
+        Writable => 'int16u',
+        ValueConv => '$val / 100', #14
+        ValueConvInv => '$val * 100', #14
+    },
+    0x001f => {
+        Name => 'Saturation',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Low', #PH
+            1 => 'Normal', #PH
+            2 => 'High', #PH
+            3 => 'Med Low', #2
+            4 => 'Med High', #2
+            5 => 'Very Low', #(NC)
+            6 => 'Very High', #(NC)
+            # the *istD has pairs of values - PH
+            '0 0' => 'Low',
+            '1 0' => 'Normal',
+            '2 0' => 'High',
+        },
+    },
+    0x0020 => {
+        Name => 'Contrast',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Low', #PH
+            1 => 'Normal', #PH
+            2 => 'High', #PH
+            3 => 'Med Low', #2
+            4 => 'Med High', #2
+            5 => 'Very Low', #PH
+            6 => 'Very High', #(NC)
+            # the *istD has pairs of values - PH
+            '0 0' => 'Low',
+            '1 0' => 'Normal',
+            '2 0' => 'High',
+        },
+    },
+    0x0021 => {
+        Name => 'Sharpness',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Soft', #PH
+            1 => 'Normal', #PH
+            2 => 'Hard', #PH
+            3 => 'Med Soft', #2
+            4 => 'Med Hard', #2
+            5 => 'Very Soft', #(NC)
+            6 => 'Very Hard', #(NC)
+            # the *istD has pairs of values - PH
+            '0 0' => 'Soft',
+            '1 0' => 'Normal',
+            '2 0' => 'Hard',
+        },
+    },
+    0x0022 => { #PH
+        Name => 'WorldTimeLocation',
+        Groups => { 2 => 'Time' },
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Hometown',
+            1 => 'Destination',
+        },
+    },
+    0x0023 => { #PH
+        Name => 'HometownCity',
+        Groups => { 2 => 'Time' },
+        Writable => 'int16u',
+        SeparateTable => 'City',
+        PrintConv => \%pentaxCities,
+    },
+    0x0024 => { #PH
+        Name => 'DestinationCity',
+        Groups => { 2 => 'Time' },
+        Writable => 'int16u',
+        SeparateTable => 'City',
+        PrintConv => \%pentaxCities,
+    },
+    0x0025 => { #PH
+        Name => 'HometownDST',
+        Groups => { 2 => 'Time' },
+        Writable => 'int16u',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    0x0026 => { #PH
+        Name => 'DestinationDST',
+        Groups => { 2 => 'Time' },
+        Writable => 'int16u',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    # 0x0027 - could be a 5-byte string software version number for the Optio 550,
+    #          but the offsets are wacky so it is hard to tell (PH)
+    0x0029 => { #5
+        Name => 'FrameNumber',
+        Writable => 'int32u',
+    },
+    # 0x002b - definitely exposure related somehow (PH)
+    0x0032 => { #13
+        Name => 'ImageProcessing',
+        Writable => 'undef',
+        Format => 'int8u',
+        Count => 4,
+        PrintConv => {
+            '0 0' => 'Unprocessed', #PH
+            '0 0 0 0' => 'Unprocessed',
+            '0 0 0 4' => 'Digital Filter',
+            '2 0 0 0' => 'Cropped', #PH
+            '4 0 0 0' => 'Color Filter',
+            '16 0 0 0' => 'Frame Synthesis?',
+        },
+    },
+    # and "\0\0\0\x04" for Digital filter (ref 13)
+    # and "\x04\0\0\0" for Color filter (ref 13) (PH - digital or color filter, K10D)
+    0x0033 => { #PH (K110D/K100D)
+        Name => 'PictureMode',
+        Writable => 'int8u',
+        Count => 3,
+        PrintConv => {
+            # Program dial modes
+            '0 0 0'  => 'Program', # K110D
+            '0 4 0'  => 'Standard', #13
+            '0 5 0'  => 'Portrait', # K110D
+            '0 6 0'  => 'Landscape', # K110D
+            '0 7 0'  => 'Macro', # K110D
+            '0 8 0'  => 'Sport', # K110D
+            '0 9 0'  => 'Night Scene Portrait', # K110D
+            '0 10 0' => 'No Flash', # K110D
+            # SCN modes (menu-selected)
+            '0 11 0' => 'Night Scene', # K100D
+            '0 12 0' => 'Surf & Snow', # K100D
+            '0 13 0' => 'Text', # K100D
+            '0 14 0' => 'Sunset', # K100D
+            '0 15 0' => 'Kids', # K100D
+            '0 16 0' => 'Pet', # K100D
+            '0 17 0' => 'Candlelight', # K100D
+            '0 18 0' => 'Museum', # K100D
+            # AUTO PICT modes (auto-selected)
+            '1 4 0'  => 'Auto PICT (Standard)', #13
+            '1 5 0'  => 'Auto PICT (Portrait)', #7 (K100D)
+            '1 6 0'  => 'Auto PICT (Landscape)', # K110D
+            '1 7 0'  => 'Auto PICT (Macro)', #13
+            '1 8 0'  => 'Auto PICT (Sport)', #13
+            # Manual dial modes
+            '2 0 0'  => 'Program AE', #13
+            '3 0 0'  => 'Green Mode', #16
+            '4 0 0'  => 'Shutter Speed Priority', # K110D
+            '5 0 0'  => 'Aperture Priority', # K110D
+            '8 0 0'  => 'Manual', # K110D
+            '9 0 0'  => 'Bulb', # K110D
+            # *istD modes (ref 7)
+            '2 0 1'  => 'Program AE', # 'User Program AE' according to ref 16
+            '2 1 1'  => 'Hi-speed Program',
+            '2 2 1'  => 'DOF Program',
+            '2 3 1'  => 'MTF Program',
+            '3 0 1'  => 'Green Mode',
+            '4 0 1'  => 'Shutter Speed Priority',
+            '5 0 1'  => 'Aperture Priority',
+            '6 0 1'  => 'Program Tv Shift',
+            '7 0 1'  => 'Program Av Shift',
+            '8 0 1'  => 'Manual',
+            '9 0 1'  => 'Bulb',
+            '10 0 1' => 'Aperture Priority (Off-Auto-Aperture)',
+            '11 0 1' => 'Manual (Off-Auto-Aperture)',
+            '12 0 1' => 'Bulb (Off-Auto-Aperture)',
+            # K10D modes (ref 16)
+            '13 0 0' => 'Shutter & Aperture Priority AE',
+            '13 0 1' => 'Shutter & Aperture Priority AE (1)', #PH guess
+            '15 0 0' => 'Sensitivity Priority AE',
+            '15 0 1' => 'Sensitivity Priority AE (1)',
+            '16 0 0' => 'Flash X-Sync Speed AE',
+            '16 0 1' => 'Flash X-Sync Speed AE (1)', #PH guess
+            # other modes
+            '0 0 1'  => 'Program', #17 (K100D)
+        },
+    },
+    0x0034 => { #7/PH
+        Name => 'DriveMode',
+        Writable => 'int8u',
+        Count => 4,
+        PrintConv => {
+            '0 0 0 0' => 'Single-frame',
+            '1 0 0 0' => 'Continuous',
+            '0 1 0 0' => 'Self-timer (12 sec)',
+            '0 2 0 0' => 'Self-timer (2 sec)',
+            '0 0 1 0' => 'Remote Control?', # needs validation
+            '0 0 0 1' => 'Multiple Exposure',
+        },
+    },
+    0x0037 => { #13
+        Name => 'ColorSpace',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'sRGB',
+            1 => 'Adobe RGB',
+        },
+    },
+    0x0038 => { #5 (PEF only)
+        Name => 'ImageAreaOffset',
+        Writable => 'int16u',
+        Count => 2,
+    },
+    0x0039 => { #PH
+        Name => 'RawImageSize',
+        Writable => 'int16u',
+        Count => 2,
+        PrintConv => '$_=$val;s/ /x/;$_',
+    },
+    0x003c => { #7/PH
+        Name => 'AFPointsInFocus',
+        # not writable because I'm not decoding these 4 bytes fully:
+        # Nibble pattern: XSSSYUUU
+        # X = unknown (AF focused flag?, 0 or 1)
+        # SSS = selected AF point bitmask (0x000 or 0x7ff if unused)
+        # Y = unknown (observed 0,6,7,b,e, always 0 if SSS is 0x000 or 0x7ff)
+        # UUU = af points used
+        Format => 'int32u',
+        Notes => '*istD only',
+        ValueConv => '$val & 0x7ff', # ignore other bits for now
+        PrintConv => { BITMASK => {
+            0 => 'Upper-left',
+            1 => 'Top',
+            2 => 'Upper-right',
+            3 => 'Left',
+            4 => 'Mid-left',
+            5 => 'Center',
+            6 => 'Mid-right',
+            7 => 'Right',
+            8 => 'Lower-left',
+            9 => 'Bottom',
+            10 => 'Lower-right',
+        } },
+    },
+    # 0x003d = 8192 (PH, K10D)
+    0x003f => { #PH
+        Name => 'LensType',
+        Writable => 'int8u',
+        Count => 2,
+        SeparateTable => 1,
+        ValueConv => '$val=~s/^(\d+ \d+) 0$/$1/; $val',
+        ValueConvInv => '$val',
+        PrintConv => \%pentaxLensType,
+    },
+    # 0x0041 - increments for each cropped pic (PH)
+    #          (DigitalFilter according to ref 5)
+    0x0047 => { #PH
+        Name => 'CameraTemperature',
+        Writable => 'int8s',
+        PrintConv => '"$val C"',
+        PrintConvInv => '$val=~s/ ?c$//i; $val',
+    },
+    0x0049 => { #13
+        Name => 'NoiseReduction',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x004d => { #PH
+        Name => 'FlashExposureComp',
+        Writable => 'int32s',
+        ValueConv => '$val / 256',
+        ValueConvInv => 'int($val * 256 + ($val > 0 ? 0.5 : -0.5))',
+        PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
+        PrintConvInv => '$val',
+    },
+    0x004f => { #PH
+        Name => 'ImageTone',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Natural',
+            1 => 'Bright',
+        },
+    },
+    0x005c => { #PH
+        Name => 'ShakeReductionInfo',
+        Format => 'undef',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::SRInfo',
+        },
+    },
+    0x005d => { #19/PH
+        # (used by all Pentax DSLR's except *istD and *istDS - PH)
+        # The lowest decrypted values observed are 246 for the first image from a
+        # brand new K10D, and 209 for one of the first 20 images from a new K10D,
+        # so either there are ~200 test images shot in the factory, or there is an
+        # offset of ~200 which is applied to this value before encryption
+        Name => 'ShutterCount',
+        Writable => 'undef',
+        Count => 4,
+        Notes => 'raw value is a big-endian 4-byte integer, encrypted using Date and Time',
+        RawConv => 'length($val) == 4 ? unpack("N",$val) : undef',
+        RawConvInv => q{
+            my $val = Image::ExifTool::Pentax::CryptShutterCount($val,$self);
+            return pack('N', $val);
+        },
+        ValueConv => \&CryptShutterCount,
+        ValueConvInv => '$val',
+    },
+    0x0200 => { #5
+        Name => 'BlackPoint',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x0201 => { #5
+        Name => 'WhitePoint',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    # 0x0205 - Also stores PictureMode (PH)
+    0x0206 => { #PH
+        Name => 'AEInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::AEInfo',
+        },
+    },
+    0x0207 => { #PH
+        Name => 'LensInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::LensInfo',
+        },
+    },
+    0x0208 => { #PH
+        Name => 'FlashInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::FlashInfo',
+        },
+    },
+    0x0209 => {
+        Name => 'AEMeteringSegments',
+        Format => 'int8u',
+        Count => 16,
+        Notes => q{
+            measurements from each of the 16 AE metering segments, converted to LV
+        },
+        # metering segment locations (ref 19):
+        # +-------------------------+
+        # |           14            |
+        # |    +---+---+---+---+    |
+        # |    | 5 | 3/1\ 2| 4 |    |
+        # |  +-+-+-+-+ - +-+-+-+-+  |
+        # +--+ 9 | 7 ||0|| 6 | 8 +--+
+        # |  +-+-+-+-+ - +-+-+-+-+  |
+        # |    |13 |11\ /10|12 |    |
+        # |    +---+---+---+---+    |
+        # |           15            |
+        # +-------------------------+
+        # convert to approximate LV equivalent (PH):
+        ValueConv => q{
+            my @a;
+            foreach (split ' ', $val) { push @a, $_ / 8 - 6; }
+            return join(' ', @a);
+        },
+        ValueConvInv => q{
+            my @a;
+            foreach (split ' ', $val) { push @a, int(($_ + 6) * 8 + 0.5); }
+            return join(' ', @a);
+        },
+        PrintConv => q{
+            my @a;
+            foreach (split ' ', $val) { push @a, sprintf('%.1f', $_); }
+            return join(' ', @a);
+        },
+        PrintConvInv => '$val',
+    },
+    0x020a => {
+        Name => 'FlashADump',
+        Flags => ['Unknown','Binary'],
+    },
+    0x020b => {
+        Name => 'FlashBDump',
+        Flags => ['Unknown','Binary'],
+    },
+    0x020d => { #PH
+        Name => 'WB_RGGBLevelsDaylight',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x020e => { #PH
+        Name => 'WB_RGGBLevelsShade',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x020f => { #PH
+        Name => 'WB_RGGBLevelsCloudy',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x0210 => { #PH
+        Name => 'WB_RGGBLevelsTungsten',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x0211 => { #PH
+        Name => 'WB_RGGBLevelsFluorescentD',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x0212 => { #PH
+        Name => 'WB_RGGBLevelsFluorescentN',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x0213 => { #PH
+        Name => 'WB_RGGBLevelsFluorescentW',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x0214 => { #PH
+        Name => 'WB_RGGBLevelsFlash',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x0215 => { #PH
+        Name => 'CameraInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::CameraInfo',
+        },
+    },
+    0x0216 => { #PH
+        Name => 'BatteryInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::BatteryInfo',
+        },
+    },
+    0x021f => { #19
+        Name => 'AFInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::AFInfo',
+        },
+    },
+    0x03fe => { #PH
+        Name => 'DataDump',
+        Writable => 0,
+        PrintConv => '\$val',
+    },
+    0x0402 => { #5
+        Name => 'ToneCurve',
+        PrintConv => '\$val',
+    },
+    0x0403 => { #5
+        Name => 'ToneCurves',
+        PrintConv => '\$val',
+    },
+    0x0e00 => {
+        Name => 'PrintIM',
+        Description => 'Print Image Matching',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+);
+
+# shake reduction information (ref PH)
+%Image::ExifTool::Pentax::SRInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    NOTES => 'Shake reduction information.',
+    0 => {
+        Name => 'SRResult',
+        PrintConv => { #PH/19
+            0 => 'Not stabilized',
+            BITMASK => {
+                0 => 'Stabilized',
+                6 => 'Not ready',
+            },
+        },
+    },
+    1 => {
+        Name => 'ShakeReduction',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    2 => {
+        Name => 'SR_SWSToSWRTime',
+        # SWS=photometering switch, SWR=shutter release switch
+        # (from http://www.patentstorm.us/patents/6597867-description.html)
+        Notes => q{
+            time from when the shutter button was half pressed to when the shutter was
+            released
+        },
+    },
+);
+
+# auto-exposure information (ref PH)
+%Image::ExifTool::Pentax::AEInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    0 => {
+        Name => 'AEExposureTime',
+        Notes => 'val = 24 * 2**((32-raw)/8)',
+        ValueConv => '24*exp(-($val-32)*log(2)/8)',
+        ValueConvInv => '-log($val/24)*8/log(2)+32',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    1 => {
+        Name => 'AEAperture',
+        Notes => 'val = (2**((raw-4)/16)) / 16',
+        # (same as val=2**((raw-68)/16), but 68 isn't a nice power of 2)
+        ValueConv => 'exp(($val-4)*log(2)/16)/16',
+        ValueConvInv => 'log($val*16)*16/log(2)+4',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    2 => {
+        Name => 'AE_ISO',
+        Notes => 'val = 100 * 2**((raw-32)/8)',
+        ValueConv => '100*exp(($val-32)*log(2)/8)',
+        ValueConvInv => 'log($val/100)*8/log(2)+32',
+        PrintConv => 'int($val + 0.5)',
+        PrintConvInv => '$val',
+    },
+    3 => {
+        Name => 'AEXv',
+        Notes => 'val = (raw-64)/8',
+        ValueConv => '($val-64)/8',
+        ValueConvInv => '$val * 8 + 64',
+    },
+    4 => {
+        Name => 'AEBXv',
+        Format => 'int8s',
+        Notes => 'val = raw / 8',
+        ValueConv => '$val/8',
+        ValueConvInv => '$val * 8',
+    },
+    5 => {
+        Name => 'AEFlashTv',
+        Notes => 'val = 24 * 2**((32-raw)/8)',
+        ValueConv => '24*exp(-($val-32)*log(2)/8)', #19
+        ValueConvInv => '-log($val/24)*8/log(2)+32',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    6 => {
+        Name => 'AEProgramMode',
+        PrintConv => {
+            0 => 'Manual/Program AE',
+            1 => 'Aperture Priority/Bulb',
+            2 => 'Shutter Speed Priority',
+            3 => 'Program',
+            35 => 'Standard',
+            43 => 'Portrait',
+            51 => 'Landscape',
+            59 => 'Macro',
+            67 => 'Sport',
+            75 => 'Night Scene Portrait',
+            83 => 'No Flash',
+            91 => 'Night Scene',
+            99 => 'Surf & Snow',
+            107 => 'Text',
+            115 => 'Sunset',
+            123 => 'Kids',
+            131 => 'Pet',
+            139 => 'Candlelight',
+            147 => 'Museum',
+        },
+    },
+    7 => {
+        Name => 'AEExtra',
+        Unknown => 1,
+    },
+);
+
+# lens information (ref PH)
+%Image::ExifTool::Pentax::LensInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    # (must decode focus distance!)
+    0 => {
+        Name => 'LensType',
+        Format => 'int8u[4]',
+        Priority => 0,
+        Notes => q{
+            for most models the first 2 bytes are LensType, but for the K10D the
+            decoding is a bit different
+        },
+        # this is a bit funny and needs testing with more lenses on the K10D
+        ValueConv => q{
+            my @v = split(' ',$val);
+            if ($v[0] & 0xf0 or $$self{CameraModel} =~ /^PENTAX K10D\b/) {
+                $v[0] &= 0x0f;
+                $v[1] = GetByteOrder() eq 'MM' ? $v[2] * 256 + $v[3] : $v[3] * 256 + $v[2];
+            }
+            return "$v[0] $v[1]";
+        },
+        PrintConv => \%pentaxLensType,
+        SeparateTable => 1,
+    },
+    4 => {
+        Condition => '$$self{CameraModel} !~ /K10D/',
+        Name => 'LensCodes',
+        Format => 'int8u[16]',
+        Notes => 'all models but the K10D',
+    },
+    5 => {
+        Condition => '$$self{CameraModel} =~ /K10D/',
+        Name => 'LensCodes',
+        Format => 'int8u[16]',
+        Notes => 'K10D only',
+    },
+);
+
+# flash information (ref PH)
+%Image::ExifTool::Pentax::FlashInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    0 => 'FlashStatus',
+    1 => {
+        Name => 'FlashModeCode',
+        PrintConv => {
+            149 => 'On, Wireless', # K10D
+            192 => 'On', # K10D
+            193 => 'On, Red-eye reduction', # *istDS2, K10D
+            194 => 'Auto, Fired', # K100D, K110D
+            200 => 'On, Slow-sync', # K10D
+            201 => 'On, Slow-sync, Red-eye reduction', # K10D
+            202 => 'On, Trailing-curtain Sync', # K10D
+            240 => 'Off (240)', # *istD, *istDS, K100D, K10D
+            241 => 'Off (241)', # *istDL
+            242 => 'Off (242)', # *istDS, *istDL2, K100D, K110D
+            244 => 'Off (244)', # K100D, K110D (either "Auto, Did not fire" or "Off")
+        },
+    },
+    2 => 'ExternalFlashMode',
+    3 => 'InternalFlashMagni',
+    4 => 'TTL_DA_AUp',
+    5 => 'TTL_DA_ADown',
+    6 => 'TTL_DA_BUp',
+    7 => 'TTL_DA_BDown',
+    # ? => 'ExternalFlashMagniA',
+    # ? => 'ExternalFlashMagniB',
+);
+
+# camera manufacture information (ref PH)
+%Image::ExifTool::Pentax::CameraInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    FORMAT => 'int32u',
+    0 => {
+        Name => 'PentaxModelID',
+        Priority => 0, # (Optio SVi uses incorrect Optio SV ID here)
+        SeparateTable => 1,
+        PrintConv => \%pentaxModelID,
+    },
+    1 => {
+        Name => 'ManufactureDate',
+        ValueConv => q{
+            $val =~ /^(\d{4})(\d{2})(\d{2})$/ and return "$1:$2:$3";
+            # Optio A10 and A20 leave "200" off the year
+            $val =~ /^(\d)(\d{2})(\d{2})$/ and return "200$1:$2:$3";
+            return "Unknown ($val)";
+        },
+        ValueConvInv => '$val=~tr/0-9//dc; $val',
+    },
+    2 => {
+        Name => 'ModelRevision',
+        Format => 'int32u[2]',
+        ValueConv => '$val=~tr/ /./; $val',
+        ValueConvInv => '$val=~tr/./ /; $val',
+    },
+    4 => 'InternalSerialNumber',
+);
+
+# battery information (ref PH)
+%Image::ExifTool::Pentax::BatteryInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    0 => {
+        Name => 'BatteryType',
+        ValueConv => '$val & 0x7f',
+        ValueConvInv => '$val | 0x80',  # (not sure what this bit means)
+    },
+    1 => {
+        Name => 'BatteryBodyGripStates',
+        Notes => 'body and grip battery state',
+        ValueConv => '($val >> 4) . " " . ($val & 0x0f)',
+        ValueConvInv => 'my @a=split(" ",$val); ($a[0] << 4) + $a[1]',
+    },
+    # internal and grip battery voltage Analogue to Digital measurements,
+    # open circuit and under load
+    2 => 'BatteryADBodyNoLoad',
+    3 => 'BatteryADBodyLoad',
+    4 => 'BatteryADGripNoLoad',
+    5 => 'BatteryADGripLoad',
+);
+
+# auto focus information (ref 19)
+%Image::ExifTool::Pentax::AFInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    0x0b => {
+        Name => 'AFPointsInFocus',
+        Notes => q{
+            may report two points in focus even though a single AFPoint has been
+            selected, in which case the selected AFPoint is the first reported
+        },
+        PrintConv => {
+            0 => 'None',
+            1 => 'Lower-left, Bottom',
+            2 => 'Bottom',
+            3 => 'Lower-right, Bottom',
+            4 => 'Mid-left, Center',
+            5 => 'Center (horizontal)', #PH (K10D)
+            6 => 'Mid-right, Center',
+            7 => 'Upper-left, Top',
+            8 => 'Top',
+            9 => 'Upper-right, Top',
+            10 => 'Right',
+            11 => 'Lower-left, Mid-left',
+            12 => 'Upper-left, Mid-left',
+            13 => 'Bottom, Center',
+            14 => 'Top, Center',
+            15 => 'Lower-right, Mid-right',
+            16 => 'Upper-right, Mid-right',
+            17 => 'Left',
+            18 => 'Mid-left',
+            19 => 'Center (vertical)', #PH (K10D)
+            20 => 'Mid-right',
+        },
+    },
+);
+
+# tags in Pentax QuickTime videos (PH - tests with Optio WP)
+# (note: very similar to information in Nikon videos)
+%Image::ExifTool::Pentax::MOV = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'This information is found in Pentax MOV video images.',
+    0x00 => {
+        Name => 'Make',
+        Format => 'string[6]',
+        PrintConv => 'ucfirst(lc($val))',
+    },
+    0x26 => {
+        Name => 'ExposureTime',
+        Format => 'int32u',
+        ValueConv => '$val ? 10 / $val : 0',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    0x2a => {
+        Name => 'FNumber',
+        Format => 'int32u',
+        ValueConv => '$val / 10',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x32 => {
+        Name => 'ExposureCompensation',
+        Format => 'int32s',
+        ValueConv => '$val / 10',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x44 => {
+        Name => 'WhiteBalance',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Daylight',
+            2 => 'Shade',
+            3 => 'Fluorescent', #2
+            4 => 'Tungsten',
+            5 => 'Manual',
+        },
+    },
+    0x48 => {
+        Name => 'FocalLength',
+        Writable => 'int32u',
+        ValueConv => '$val / 10',
+        PrintConv => 'sprintf("%.1fmm",$val)',
+    },
+    0xaf => {
+        Name => 'ISO',
+        Format => 'int16u',
+    },
+);
+
+# Pentax type 2 (Casio-like) maker notes (ref 1)
+%Image::ExifTool::Pentax::Type2 = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITABLE => 'int16u',
+    NOTES => q{
+        These tags are used by the Pentax Optio 330 and 430, and are similar to the
+        tags used by Casio.
+    },
+    0x0001 => {
+        Name => 'RecordingMode',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Night Scene',
+            2 => 'Manual',
+        },
+    },
+    0x0002 => {
+        Name => 'Quality',
+        PrintConv => {
+            0 => 'Good',
+            1 => 'Better',
+            2 => 'Best',
+        },
+    },
+    0x0003 => {
+        Name => 'FocusMode',
+        PrintConv => {
+            2 => 'Custom',
+            3 => 'Auto',
+        },
+    },
+    0x0004 => {
+        Name => 'FlashMode',
+        PrintConv => {
+            1 => 'Auto',
+            2 => 'On',
+            4 => 'Off',
+            6 => 'Red-eye reduction',
+        },
+    },
+    # Casio 0x0005 is FlashIntensity
+    # Casio 0x0006 is ObjectDistance
+    0x0007 => {
+        Name => 'WhiteBalance',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Daylight',
+            2 => 'Shade',
+            3 => 'Tungsten',
+            4 => 'Fluorescent',
+            5 => 'Manual',
+        },
+    },
+    0x000a => {
+        Name => 'DigitalZoom',
+        Writable => 'int32u',
+    },
+    0x000b => {
+        Name => 'Sharpness',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Soft',
+            2 => 'Hard',
+        },
+    },
+    0x000c => {
+        Name => 'Contrast',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Low',
+            2 => 'High',
+        },
+    },
+    0x000d => {
+        Name => 'Saturation',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Low',
+            2 => 'High',
+        },
+    },
+    0x0014 => {
+        Name => 'ISO',
+        Priority => 0,
+        PrintConv => {
+            10 => 100,
+            16 => 200,
+            50 => 50, #PH
+            100 => 100, #PH
+            200 => 200, #PH
+            400 => 400, #PH
+            800 => 800, #PH
+            1600 => 1600, #PH
+            3200 => 3200, #PH
+        },
+    },
+    0x0017 => {
+        Name => 'ColorFilter',
+        PrintConv => {
+            1 => 'Full',
+            2 => 'Black & White',
+            3 => 'Sepia',
+        },
+    },
+    # Casio 0x0018 is AFPoint
+    # Casio 0x0019 is FlashIntensity
+    0x0e00 => {
+        Name => 'PrintIM',
+        Description => 'Print Image Matching',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+    0x1000 => {
+        Name => 'HometownCityCode',
+        Writable => 'undef',
+        Count => 4,
+    },
+    0x1001 => { #PH
+        Name => 'DestinationCityCode',
+        Writable => 'undef',
+        Count => 4,
+    },
+);
+
+# ASCII-based maker notes of Optio E20 - PH
+%Image::ExifTool::Pentax::Type4 = (
+    PROCESS_PROC => \&Image::ExifTool::HP::ProcessHP,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        The following few tags are extracted from the wealth of information
+        available in maker notes of the Optio E20.  These maker notes are stored as
+        ASCII text in a format very similar to some HP models.
+    },
+   'F/W Version' => 'FirmwareVersion',
+);
+
+#------------------------------------------------------------------------------
+# Encrypt or decrypt Pentax ShutterCount (symmetrical encryption) - PH
+# Inputs: 0) shutter count value, 1) ExifTool object ref
+# Returns: Encrypted or decrypted ShutterCount
+sub CryptShutterCount($$)
+{
+    my ($val, $exifTool) = @_;
+    # Pentax Date and Time values are used in the encryption
+    return undef unless $$exifTool{PentaxDate} and $$exifTool{PentaxTime} and
+        length($$exifTool{PentaxDate})==4 and length($$exifTool{PentaxTime})>=3;
+    # get Date and Time as integers (after padding Time with a null byte)
+    my $date = unpack('N', $$exifTool{PentaxDate});
+    my $time = unpack('N', $$exifTool{PentaxTime} . "\0");
+    return $val ^ $date ^ (0xffffffff - $time);
+}
+
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Pentax - Pentax/Asahi maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+Pentax and Asahi maker notes in EXIF information.
+
+=head1 NOTES
+
+I couldn't find a good source for Pentax maker notes information, but I've
+managed to discover a fair bit of information by analyzing sample pictures
+from the Optio 330, Optio 550, Optio S, *istD, *istDs, and through tests
+with my own Optio WP, and with help provided by other ExifTool users (see
+L<ACKNOWLEDGEMENTS>).
+
+The Pentax maker notes are stored in standard EXIF format, but the offsets
+used for some of their cameras are wacky.  The Optio 330 gives the offset
+relative to the offset of the tag in the directory, the Optio WP uses a base
+offset in the middle of nowhere, and the Optio 550 uses different (and
+totally illogical) bases for different menu entries.  Very weird.  (It
+wouldn't surprise me if Pentax can't read their own maker notes!)  Luckily,
+there are only a few entries in the maker notes which are large enough to
+require offsets, so this doesn't affect much useful information.  ExifTool
+attempts to make sense of this fiasco by making an assumption about where
+the information should be stored to deduce the correct offsets.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<Image::MakerNotes::Pentax|Image::MakerNotes::Pentax>
+
+=item L<http://johnst.org/sw/exiftags/> (Asahi models)
+
+=item L<http://kobe1995.jp/~kaz/astro/istD.html>
+
+=item L<http://www.cybercom.net/~dcoffin/dcraw/>
+
+=item (...plus lots of testing with my Optio WP and K10D!)
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Wayne Smith, John Francis, Douglas O'Brien Cvetan Ivanov and Jens
+Duttke for help figuring out some Pentax tags, Denis Bourez, Kazumichi
+Kawabata, David Buret, Barney Garrett and Axel Kellner for adding to the
+LensType list, and Ger Vermeulen for contributing print conversion values
+for some tags.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Pentax Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>,
+L<Image::Info(3pm)|Image::Info>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/PhotoMechanic.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/PhotoMechanic.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/PhotoMechanic.pm	(revision 20131)
@@ -0,0 +1,257 @@
+#------------------------------------------------------------------------------
+# File:         PhotoMechanic.pm
+#
+# Description:  Read/write Camera Bits Photo Mechanic information
+#
+# Revisions:    10/28/2006 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::PhotoMechanic;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+use Image::ExifTool::IPTC;
+use Image::ExifTool::XMP;
+
+$VERSION = '1.00';
+
+sub ProcessPhotoMechanic($$);
+
+# color class names
+my %colorClasses = (
+    0 => '0 (None)',
+    1 => '1 (Winner)',
+    2 => '2 (Winner alt)',
+    3 => '3 (Superior)',
+    4 => '4 (Superior alt)',
+    5 => '5 (Typical)',
+    6 => '6 (Typical alt)',
+    7 => '7 (Extras)',
+    8 => '8 (Trash)',
+);
+
+# main tag table IPTC-format records in PhotoMechanic trailer
+%Image::ExifTool::PhotoMechanic::Main = (
+    GROUPS => { 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::IPTC::ProcessIPTC,
+    WRITE_PROC => \&Image::ExifTool::IPTC::WriteIPTC,
+    NOTES => q{
+        The Photo Mechanic trailer contains data in an IPTC-format structure, with
+        soft edit information stored under record number 2.
+    },
+    2 => {
+        Name => 'SoftEdit',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PhotoMechanic::SoftEdit',
+        },
+    },
+);
+
+# rawCrop coordinate conversions
+my %rawCropConv = (
+    ValueConv => '$val / 655.36',
+    ValueConvInv => 'int($val * 655.36 + 0.5)',
+    PrintConv => 'sprintf("%.3f%%",$val)',
+    PrintConvInv => '$val=~tr/ %//d; $val',
+);
+
+# Record 2 -- PhotoMechanic soft edit information
+%Image::ExifTool::PhotoMechanic::SoftEdit = (
+    GROUPS => { 2 => 'Image' },
+    WRITE_PROC => \&Image::ExifTool::IPTC::WriteIPTC,
+    CHECK_PROC => \&Image::ExifTool::IPTC::CheckIPTC,
+    WRITABLE => 1,
+    FORMAT => 'int32s',
+    209 => {
+        Name => 'RawCropLeft',
+        %rawCropConv,
+    },
+    210 => {
+        Name => 'RawCropTop',
+        %rawCropConv,
+    },
+    211 => {
+        Name => 'RawCropRight',
+        %rawCropConv,
+    },
+    212 => {
+        Name => 'RawCropBottom',
+        %rawCropConv,
+    },
+    213 => 'ConstrainedCropWidth',
+    214 => 'ConstrainedCropHeight',
+    215 => 'FrameNum',
+    216 => {
+        Name => 'Rotation',
+        PrintConv => {
+            0 => '0',
+            1 => '90',
+            2 => '180',
+            3 => '270',
+        },
+    },
+    217 => 'CropLeft',
+    218 => 'CropTop',
+    219 => 'CropRight',
+    220 => 'CropBottom',
+    221 => {
+        Name => 'Tagged',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    222 => {
+        Name => 'ColorClass',
+        PrintConv => \%colorClasses,
+    },
+    223 => 'Rating',
+);
+
+# PhotoMechanic XMP properties
+%Image::ExifTool::PhotoMechanic::XMP = (
+    GROUPS => { 0 => 'XMP', 1 => 'XMP-photomech', 2 => 'Image' },
+    NAMESPACE => { photomechanic => 'http://ns.camerabits.com/photomechanic/1.0/' },
+    WRITE_PROC => \&Image::ExifTool::XMP::WriteXMP,
+    WRITABLE => 'string',
+    NOTES => q{
+        Below is a list of the observed PhotoMechanic XMP tags.  The actual
+        namespace prefix is "photomechanic" but ExifTool shortens this in
+        the "XMP-photomech" family 1 group name.
+    },
+    CountryCode => { Avoid => 1, Groups => { 2 => 'Location' } },
+    EditStatus  => { },
+    Prefs       => {
+        PrintConv => q{
+            $val =~ s[\s*(\d+):\s*(\d+):\s*(\d+):\s*(\S*)]
+                     [Tagged:$1, ColorClass:$2, Rating:$3, FrameNum:$4];
+            return $val;
+        },
+        PrintConvInv => q{
+            $val =~ s[Tagged:\s*(\d+).*ColorClass:\s*(\d+).*Rating:\s*(\d+).*FrameNum:\s*(\S*)]
+                     [$1:$2:$3:$4]is;
+            return $val;
+        },
+    },
+    TimeCreated => {
+        Avoid => 1,
+        Groups => { 2 => 'Time' },
+        Shift => 'Time',
+        ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
+        ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
+    },
+);
+
+#------------------------------------------------------------------------------
+# Read/write PhotoMechanic information in a file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this file didn't contain PhotoMechanic information
+# - updates DataPos to point to start of PhotoMechanic information
+# - updates DirLen to trailer length
+sub ProcessPhotoMechanic($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $offset = $$dirInfo{Offset} || 0;
+    my $outfile = $$dirInfo{OutFile};
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my $rtnVal = 0;
+    my ($buff, $footer);
+
+    for (;;) {
+        # read and validate trailer footer (last 12 bytes)
+        last unless $raf->Seek(-12-$offset, 2) and $raf->Read($footer, 12) == 12;
+        last unless $footer =~ /cbipcbbl$/;
+        my $size = unpack('N', $footer);
+    
+        if ($size & 0x80000000 or not $raf->Seek(-$size-12, 1)) {
+            $exifTool->Warn('Bad PhotoMechanic trailer');
+            last;
+        }
+        unless ($raf->Read($buff, $size) == $size) {
+            $exifTool->Warn('Error reading PhotoMechanic trailer');
+            last;
+        }
+        $rtnVal = 1;    # we read the trailer successfully
+
+        # set variables returned in dirInfo hash
+        $$dirInfo{DataPos} = $raf->Tell() - $size;
+        $$dirInfo{DirLen} = $size + 12;
+    
+        my %dirInfo = (
+            DataPt => \$buff,
+            DataPos => $$dirInfo{DataPos},
+            DirStart => 0,
+            DirLen => $size,
+            Parent => 'PhotoMechanic',
+        );
+        my $tagTablePtr = GetTagTable('Image::ExifTool::PhotoMechanic::Main');
+        if (not $outfile) {
+            # extract trailer information
+            $exifTool->DumpTrailer($dirInfo) if $verbose or $exifTool->{HTML_DUMP};
+            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        } elsif ($exifTool->{DEL_GROUP}->{PhotoMechanic}) {
+            # delete the trailer
+            $verbose and printf $out "  Deleting PhotoMechanic trailer\n";
+            ++$exifTool->{CHANGED};
+        } else {
+            # rewrite the trailer
+            my $newPt;
+            my $newBuff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+            if (defined $newBuff) {
+                $newPt = \$newBuff; # write out the modified trailer
+                my $pad = 0x800 - length($newBuff);
+                if ($pad > 0 and not $exifTool->Options('Compact')) {
+                    # pad out to 2kB like PhotoMechanic does
+                    $newBuff .= "\0" x $pad;
+                }
+                # generate new footer
+                $footer = pack('N', length($$newPt)) . 'cbipcbbl';
+            } else {
+                $newPt = \$buff;    # just copy existing trailer
+            }
+            # write out the trailer
+            Write($outfile, $$newPt, $footer) or $rtnVal = -1;
+        }
+        last;
+    }
+    return $rtnVal;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::PhotoMechanic - Read/write Photo Mechanic information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read and
+write information written by the Camera Bits Photo Mechanic software.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 ACKNOWLEDGEMENTS
+
+Many thanks to the great support provided by Camera Bits, and in particular
+for the valuable exchanges with Kirk Baker.  Based on this experience, I can
+say that the technical support offered by Camera Bits is second to none.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/PhotoMechanic Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Photoshop.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Photoshop.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Photoshop.pm	(revision 20131)
@@ -0,0 +1,545 @@
+#------------------------------------------------------------------------------
+# File:         Photoshop.pm
+#
+# Description:  Read/write Photoshop IRB meta information
+#
+# Revisions:    02/06/04 - P. Harvey Created
+#               02/25/04 - P. Harvey Added hack for problem with old photoshops
+#               10/04/04 - P. Harvey Added a bunch of tags (ref Image::MetaData::JPEG)
+#                          but left most of them commented out until I have enough
+#                          information to write PrintConv routines for them to
+#                          display something useful
+#               07/08/05 - P. Harvey Added support for reading PSD files
+#               01/07/06 - P. Harvey Added PSD write support
+#               11/04/06 - P. Harvey Added handling of resource name
+#
+# References:   1) http://www.fine-view.com/jp/lab/doc/ps6ffspecsv2.pdf
+#               2) http://www.ozhiker.com/electronics/pjmt/jpeg_info/irb_jpeg_qual.html
+#               3) Matt Mueller private communication (tests with PS CS2)
+#               4) http://www.fileformat.info/format/psd/egff.htm
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Photoshop;
+
+use strict;
+use vars qw($VERSION $AUTOLOAD);
+use Image::ExifTool qw(:DataAccess);
+
+$VERSION = '1.32';
+
+sub ProcessPhotoshop($$$);
+sub WritePhotoshop($$$);
+
+# map of where information is stored in PSD image
+my %psdMap = (
+    IPTC         => 'Photoshop',
+    XMP          => 'Photoshop',
+    EXIFInfo     => 'Photoshop',
+    IFD0         => 'EXIFInfo',
+    IFD1         => 'IFD0',
+    ICC_Profile  => 'Photoshop',
+    ExifIFD      => 'IFD0',
+    GPS          => 'IFD0',
+    SubIFD       => 'IFD0',
+    GlobParamIFD => 'IFD0',
+    PrintIM      => 'IFD0',
+    InteropIFD   => 'ExifIFD',
+    MakerNotes   => 'ExifIFD',
+);
+
+# Photoshop APP13 tag table
+# (set Unknown flag for information we don't want to display normally)
+%Image::ExifTool::Photoshop::Main = (
+    GROUPS => { 2 => 'Image' },
+    PROCESS_PROC => \&ProcessPhotoshop,
+    WRITE_PROC => \&WritePhotoshop,
+    0x03e8 => { Unknown => 1, Name => 'Photoshop2Info' },
+    0x03e9 => { Unknown => 1, Name => 'MacintoshPrintInfo' },
+    0x03ea => { Unknown => 1, Name => 'XMLData' }, #PH
+    0x03eb => { Unknown => 1, Name => 'Photoshop2ColorTable' },
+    0x03ed => {
+        Name => 'ResolutionInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Photoshop::Resolution',
+        },
+    },
+    0x03ee => {
+        Name => 'AlphaChannelsNames',
+        PrintConv => 'Image::ExifTool::Photoshop::ConvertPascalString($val)',
+    },
+    0x03ef => { Unknown => 1, Name => 'DisplayInfo' },
+    0x03f0 => { Unknown => 1, Name => 'PStringCaption' },
+    0x03f1 => { Unknown => 1, Name => 'BorderInformation' },
+    0x03f2 => { Unknown => 1, Name => 'BackgroundColor' },
+    0x03f3 => { Unknown => 1, Name => 'PrintFlags' },
+    0x03f4 => { Unknown => 1, Name => 'BW_HalftoningInfo' },
+    0x03f5 => { Unknown => 1, Name => 'ColorHalftoningInfo' },
+    0x03f6 => { Unknown => 1, Name => 'DuotoneHalftoningInfo' },
+    0x03f7 => { Unknown => 1, Name => 'BW_TransferFunc' },
+    0x03f8 => { Unknown => 1, Name => 'ColorTransferFuncs' },
+    0x03f9 => { Unknown => 1, Name => 'DuotoneTransferFuncs' },
+    0x03fa => { Unknown => 1, Name => 'DuotoneImageInfo' },
+    0x03fb => { Unknown => 1, Name => 'EffectiveBW' },
+    0x03fc => { Unknown => 1, Name => 'ObsoletePhotoshopTag1' },
+    0x03fd => { Unknown => 1, Name => 'EPSOptions' },
+    0x03fe => { Unknown => 1, Name => 'QuickMaskInfo' },
+    0x03ff => { Unknown => 1, Name => 'ObsoletePhotoshopTag2' },
+    0x0400 => { Unknown => 1, Name => 'LayerStateInfo' },
+    0x0401 => { Unknown => 1, Name => 'WorkingPath' },
+    0x0402 => { Unknown => 1, Name => 'LayersGroupInfo' },
+    0x0403 => { Unknown => 1, Name => 'ObsoletePhotoshopTag3' },
+    0x0404 => {
+        Name => 'IPTCData',
+        SubDirectory => {
+            DirName => 'IPTC',
+            TagTable => 'Image::ExifTool::IPTC::Main',
+        },
+    },
+    0x0405 => { Unknown => 1, Name => 'RawImageMode' },
+    0x0406 => { #2
+        Name => 'JPEG_Quality',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Photoshop::JPEG_Quality',
+        },
+    },
+    0x0408 => { Unknown => 1, Name => 'GridGuidesInfo' },
+    0x0409 => {
+        Name => 'PhotoshopBGRThumbnail',
+        Notes => 'this is a JPEG image, but in BGR format instead of RGB',
+        ValueConv => 'my $img=substr($val,0x1c);$self->ValidateImage(\$img,$tag)',
+    },
+    0x040a => {
+        Name => 'CopyrightFlag',
+        Writable => 'int8u',
+        Groups => { 2 => 'Author' },
+        ValueConv => 'join(" ",unpack("C*", $val))',
+        ValueConvInv => 'pack("C*",split(" ",$val))',
+        PrintConv => { #3
+            0 => 'False',
+            1 => 'True',
+        },
+    },
+    0x040b => {
+        Name => 'URL',
+        Writable => 'string',
+        Groups => { 2 => 'Author' },
+    },
+    0x040c => {
+        Name => 'PhotoshopThumbnail',
+        ValueConv => 'my $img=substr($val,0x1c);$self->ValidateImage(\$img,$tag)',
+    },
+    0x040d => {
+        Name => 'GlobalAngle',
+        Writable => 'int32u',
+        ValueConv => 'unpack("N",$val)',
+        ValueConvInv => 'pack("N",$val)',
+    },
+    0x040e => { Unknown => 1, Name => 'ColorSamplersResource' },
+    0x040f => {
+        Name => 'ICC_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+        },
+    },
+    0x0410 => { Unknown => 1, Name => 'Watermark' },
+    0x0411 => { Unknown => 1, Name => 'ICC_Untagged' },
+    0x0412 => { Unknown => 1, Name => 'EffectsVisible' },
+    0x0413 => { Unknown => 1, Name => 'SpotHalftone' },
+    0x0414 => { Unknown => 1, Name => 'IDsBaseValue', Description => "ID's Base Value" },
+    0x0415 => { Unknown => 1, Name => 'UnicodeAlphaNames' },
+    0x0416 => { Unknown => 1, Name => 'IndexedColourTableCount' },
+    0x0417 => { Unknown => 1, Name => 'TransparentIndex' },
+    0x0419 => {
+        Name => 'GlobalAltitude',
+        Writable => 'int32u',
+        ValueConv => 'unpack("N",$val)',
+        ValueConvInv => 'pack("N",$val)',
+    },
+    0x041a => { Unknown => 1, Name => 'Slices' },
+    0x041b => { Unknown => 1, Name => 'WorkflowURL' },
+    0x041c => { Unknown => 1, Name => 'JumpToXPEP' },
+    0x041d => { Unknown => 1, Name => 'AlphaIdentifiers' },
+    0x041e => { Unknown => 1, Name => 'URL_List' },
+    0x0421 => { Unknown => 1, Name => 'VersionInfo' },
+    0x0422 => {
+        Name => 'EXIFInfo', #PH (Found in EPS and PSD files)
+        SubDirectory => {
+            TagTable=> 'Image::ExifTool::Exif::Main',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+            WriteProc => \&Image::ExifTool::WriteTIFF,
+        },
+    },
+    0x0424 => {
+        Name => 'XMP',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::XMP::Main',
+        },
+    },
+    # 0x07d0-0x0bb6 Path information
+    0x0bb7 => { Unknown => 1, Name => 'ClippingPathName' },
+    0x2710 => { Unknown => 1, Name => 'PrintFlagsInfo' },
+);
+
+# Photoshop JPEG quality record (ref 2)
+%Image::ExifTool::Photoshop::JPEG_Quality = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int16s',
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'PhotoshopQuality',
+        Writable => 1,
+        PrintConv => '$val + 4',
+        PrintConvInv => '$val - 4',
+    },
+    1 => {
+        Name => 'PhotoshopFormat',
+        PrintConv => {
+            0x0000 => 'Standard',
+            0x0001 => 'Optimised',
+            0x0101 => 'Progressive',
+        },
+    },
+    2 => {
+        Name => 'ProgressiveScans',
+        PrintConv => {
+            1 => '3 Scans',
+            2 => '4 Scans',
+            3 => '5 Scans',
+        },
+    },
+);
+
+# Photoshop resolution information #PH
+%Image::ExifTool::Photoshop::Resolution = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    WRITABLE => 1,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'XResolution',
+        Format => 'int32u',
+        Priority => 0,
+        ValueConv => '$val / 0x10000',
+        ValueConvInv => 'int($val * 0x10000 + 0.5)',
+        PrintConv => 'int($val * 100 + 0.5) / 100',
+        PrintConvInv => '$val',
+    },
+    2 => {
+        Name => 'DisplayedUnitsX',
+        PrintConv => {
+            1 => 'inches',
+            2 => 'cm',
+        },
+    },
+    4 => {
+        Name => 'YResolution',
+        Format => 'int32u',
+        Priority => 0,
+        ValueConv => '$val / 0x10000',
+        ValueConvInv => 'int($val * 0x10000 + 0.5)',
+        PrintConv => 'int($val * 100 + 0.5) / 100',
+        PrintConvInv => '$val',
+    },
+    6 => {
+        Name => 'DisplayedUnitsY',
+        PrintConv => {
+            1 => 'inches',
+            2 => 'cm',
+        },
+    },
+);
+
+# Photoshop PSD file header
+%Image::ExifTool::Photoshop::Header = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int16u',
+    GROUPS => { 2 => 'Image' },
+    NOTES => 'This information is found in the PSD file header.',
+    6 => 'NumChannels',
+    7 => { Name => 'ImageHeight', Format => 'int32u' },
+    9 => { Name => 'ImageWidth', Format => 'int32u' },
+    11 => 'BitDepth',
+    12 => {
+        Name => 'ColorMode',
+        PrintConv => {
+            0 => 'Bitmap',
+            1 => 'Grayscale',
+            2 => 'Indexed',
+            3 => 'RGB',
+            4 => 'CMYK',
+            7 => 'Multichannel',
+            8 => 'Duotone',
+            9 => 'Lab',
+        },
+    },
+);
+
+# tags for unknown resource types
+%Image::ExifTool::Photoshop::Unknown = (
+    GROUPS => { 2 => 'Unknown' },
+);
+
+#------------------------------------------------------------------------------
+# AutoLoad our writer routines when necessary
+#
+sub AUTOLOAD
+{
+    return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
+}
+
+#------------------------------------------------------------------------------
+# Convert pascal string(s) to something we can use
+# Inputs: 1) Pascal string data
+# Returns: Strings, concatenated with ', '
+sub ConvertPascalString($)
+{
+    my $inStr = shift;
+    my $outStr = '';
+    my $len = length($inStr);
+    my $i=0;
+    while ($i < $len) {
+        my $n = ord(substr($inStr, $i, 1));
+        last if $i + $n >= $len;
+        $i and $outStr .= ', ';
+        $outStr .= substr($inStr, $i+1, $n);
+        $i += $n + 1;
+    }
+    return $outStr;
+}
+
+#------------------------------------------------------------------------------
+# Process Photoshop APP13 record
+# Inputs: 0) ExifTool object reference, 1) Reference to directory information
+#         2) Tag table reference
+# Returns: 1 on success
+sub ProcessPhotoshop($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $pos = $$dirInfo{DirStart};
+    my $dirEnd = $pos + $$dirInfo{DirLen};
+    my $verbose = $exifTool->Options('Verbose');
+    my $success = 0;
+
+    SetByteOrder('MM');     # Photoshop is always big-endian
+    $verbose and $exifTool->VerboseDir('Photoshop', 0, $$dirInfo{DirLen});
+
+    # scan through resource blocks:
+    # Format: 0) Type, 4 bytes - '8BIM' (or the rare 'PHUT', 'DCSR' or 'AgHg')
+    #         1) TagID,2 bytes
+    #         2) Name, pascal string padded to even no. bytes
+    #         3) Size, 4 bytes - N
+    #         4) Data, N bytes
+    while ($pos + 8 < $dirEnd) {
+        my $type = substr($$dataPt, $pos, 4);
+        my ($ttPtr, $extra, $val, $name);
+        if ($type eq '8BIM') {
+            $ttPtr = $tagTablePtr;
+        } elsif ($type =~ /^(PHUT|DCSR|AgHg)$/) {
+            $ttPtr = Image::ExifTool::GetTagTable('Image::ExifTool::Photoshop::Unknown');
+        } else {
+            $type =~ s/([^\w])/sprintf("\\x%.2x",ord($1))/ge;
+            $exifTool->Warn(qq{Bad Photoshop IRB resource "$type"});
+            last;
+        }
+        my $tag = Get16u($dataPt, $pos + 4);
+        $pos += 6;  # point to start of name
+        my $nameLen = Get8u($dataPt, $pos);
+        my $namePos = ++$pos;
+        # skip resource block name (pascal string, padded to an even # of bytes)
+        $pos += $nameLen;
+        ++$pos unless $nameLen & 0x01;
+        if ($pos + 4 > $dirEnd) {
+            $exifTool->Warn("Bad Photoshop resource block");
+            last;
+        }
+        my $size = Get32u($dataPt, $pos);
+        $pos += 4;
+        if ($size + $pos > $dirEnd) {
+            $exifTool->Warn("Bad Photoshop resource data size $size");
+            last;
+        }
+        $success = 1;
+        if ($nameLen) {
+            $name = substr($$dataPt, $namePos, $nameLen);
+            $extra = qq{, Name="$name"};
+        } else {
+            $name = '';
+        }
+        my $tagInfo = $exifTool->GetTagInfo($ttPtr, $tag);
+        # append resource name to value if requested (braced by "/#...#/")
+        if ($tagInfo and defined $$tagInfo{SetResourceName} and
+            $$tagInfo{SetResourceName} eq '1' and $name !~ m{/#})
+        {
+            $val = substr($$dataPt, $pos, $size) . '/#' . $name . '#/';
+        }
+        $exifTool->HandleTag($ttPtr, $tag, $val,
+            TagInfo => $tagInfo,
+            Extra   => $extra,
+            DataPt  => $dataPt,
+            DataPos => $$dirInfo{DataPos},
+            Size    => $size,
+            Start   => $pos,
+            Parent  => $$dirInfo{DirName},
+        );
+        $size += 1 if $size & 0x01; # size is padded to an even # bytes
+        $pos += $size;
+    }
+    return $success;
+}
+
+#------------------------------------------------------------------------------
+# extract information from Photoshop PSD file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 if this was a valid PSD file, -1 on write error
+sub ProcessPSD($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $outfile = $$dirInfo{OutFile};
+    my ($data, $err, $tagTablePtr);
+
+    $raf->Read($data, 30) == 30 or return 0;
+    $data =~ /^8BPS\0\x01/ or return 0;
+    SetByteOrder('MM');
+    $exifTool->SetFileType();    # set the FileType tag
+    my %dirInfo = (
+        DataPt => \$data,
+        DirStart => 0,
+        DirName => 'PSD',
+    );
+    my $len = Get32u(\$data, 26);
+    if ($outfile) {
+        Write($outfile, $data) or $err = 1;
+        $raf->Read($data, $len) == $len or return -1;
+        Write($outfile, $data) or $err = 1; # write color mode data
+        # initialize map of where things are written
+        $exifTool->InitWriteDirs(\%psdMap);
+    } else {
+        # process the header
+        $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Photoshop::Header');
+        $dirInfo{DirLen} = 30;
+        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        $raf->Seek($len, 1) or $err = 1;    # skip over color mode data
+    }
+    $raf->Read($data, 4) == 4 or $err = 1;
+    $len = Get32u(\$data, 0);
+    $raf->Read($data, $len) == $len or $err = 1;
+    $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Photoshop::Main');
+    $dirInfo{DirLen} = $len;
+    my $rtnVal = 1;
+    if ($outfile) {
+        # rewrite IRB resources
+        $data = WritePhotoshop($exifTool, \%dirInfo, $tagTablePtr);
+        if ($data) {
+            $len = Set32u(length $data);
+            Write($outfile, $len, $data) or $err = 1;
+            # look for trailer and edit if necessary
+            my $trailInfo = Image::ExifTool::IdentifyTrailer($raf);
+            if ($trailInfo) {
+                my $tbuf = '';
+                $$trailInfo{OutFile} = \$tbuf;  # rewrite trailer(s)
+                # rewrite all trailers to buffer
+                if ($exifTool->ProcessTrailers($trailInfo)) {
+                    my $copyBytes = $$trailInfo{DataPos} - $raf->Tell();
+                    if ($copyBytes >= 0) {
+                        # copy remaining PSD file up to start of trailer
+                        while ($copyBytes) {
+                            my $n = ($copyBytes > 65536) ? 65536 : $copyBytes;
+                            $raf->Read($data, $n) == $n or $err = 1;
+                            Write($outfile, $data) or $err = 1;
+                            $copyBytes -= $n;
+                        }
+                        # write the trailer (or not)
+                        $exifTool->WriteTrailerBuffer($trailInfo, $outfile) or $err = 1;
+                    } else {
+                        $exifTool->Warn('Overlapping trailer');
+                        undef $trailInfo;
+                    }
+                } else {
+                    undef $trailInfo;
+                }
+            }
+            unless ($trailInfo) {
+                # copy over the rest of the file
+                while ($raf->Read($data, 65536)) {
+                    Write($outfile, $data) or $err = 1;
+                }
+            }
+        } else {
+            $err = 1;
+        }
+        $rtnVal = -1 if $err;
+    } elsif ($err) {
+        $exifTool->Warn('File format error');
+    } else {
+        ProcessPhotoshop($exifTool, \%dirInfo, $tagTablePtr);
+        # process trailers if they exist
+        my $trailInfo = Image::ExifTool::IdentifyTrailer($raf);
+        $exifTool->ProcessTrailers($trailInfo) if $trailInfo;
+    }
+    return $rtnVal;
+}
+
+1; # end
+
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Photoshop - Read/write Photoshop IRB meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+Photoshop writes its own format of meta information called a Photoshop IRB
+resource which is located in the APP13 record of JPEG files.  This module
+contains the definitions to read this information.
+
+=head1 NOTES
+
+Photoshop IRB blocks may have an associated resource name.  These names are
+usually just an empty string, but if not empty they are displayed in the
+verbose level 2 (or greater) output.  A special C<SetResourceName> flag may
+be set to '1' in the tag information hash to cause the resource name to be
+appended to the value when extracted.  If this is done, the returned value
+has the form "VALUE/#NAME#/".  When writing, the writer routine looks for
+this syntax (if C<SetResourceName> is defined), and and uses the embedded
+name to set the name of the new resource.  This allows the resource names to
+be preserved when copying Photoshop information via user-defined tags.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.fine-view.com/jp/lab/doc/ps6ffspecsv2.pdf>
+
+=item L<http://www.ozhiker.com/electronics/pjmt/jpeg_info/irb_jpeg_qual.html>
+
+=item L<http://www.fileformat.info/format/psd/egff.htm>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Photoshop Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>,
+L<Image::MetaData::JPEG(3pm)|Image::MetaData::JPEG>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/PostScript.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/PostScript.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/PostScript.pm	(revision 20131)
@@ -0,0 +1,401 @@
+#------------------------------------------------------------------------------
+# File:         PostScript.pm
+#
+# Description:  Read PostScript meta information
+#
+# Revisions:    07/08/05 - P. Harvey Created
+#
+# References:   1) http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf
+#               2) http://partners.adobe.com/public/developer/en/ps/5001.DSC_Spec.pdf
+#               3) http://partners.adobe.com/public/developer/en/illustrator/sdk/AI7FileFormat.pdf
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::PostScript;
+
+use strict;
+use vars qw($VERSION $AUTOLOAD);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.19';
+
+sub WritePS($$);
+sub CheckPS($$$);
+
+# PostScript tag table
+%Image::ExifTool::PostScript::Main = (
+    WRITE_PROC => \&WritePS,
+    CHECK_PROC => \&CheckPS,
+    PREFERRED => 1, # always add these tags when writing
+    GROUPS => { 2 => 'Image' },
+    # Note: Make all of these tags priority 0 since the first one found at
+    # the start of the file should take priority (in case multiples exist)
+    Author      => { Priority => 0, Groups => { 2 => 'Author' }, Writable => 'string' },
+    BoundingBox => { Priority => 0 },
+    Copyright   => { Priority => 0, Writable => 'string' }, #2
+    CreationDate => {
+        Name => 'CreateDate',
+        Priority => 0,
+        Groups => { 2 => 'Time' },
+        Writable => 'string',
+    },
+    Creator     => { Priority => 0, Writable => 'string' },
+    ImageData   => { Priority => 0 },
+    For         => { Priority => 0, Writable => 'string', Notes => 'for whom the document was prepared'},
+    Keywords    => { Priority => 0, Writable => 'string' },
+    ModDate => {
+        Name => 'ModifyDate',
+        Priority => 0,
+        Groups => { 2 => 'Time' },
+        Writable => 'string',
+    },
+    Pages       => { Priority => 0 },
+    Routing     => { Priority => 0, Writable => 'string' }, #2
+    Subject     => { Priority => 0, Writable => 'string' },
+    Title       => { Priority => 0, Writable => 'string' },
+    Version     => { Priority => 0, Writable => 'string' }, #2
+    # these subdirectories for documentation only
+    BeginPhotoshop => {
+        Name => 'PhotoshopData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Photoshop::Main',
+        },
+    },
+    BeginICCProfile => {
+        Name => 'ICC_Profile',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+        },
+    },
+    begin_xml_packet => {
+        Name => 'XMP',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::XMP::Main',
+        },
+    },
+    TIFFPreview => {
+        Binary => 1,
+        Notes => q{
+            not a real tag ID, but used to represent the TIFF preview extracted from DOS
+            EPS images
+        },
+    },
+);
+
+# composite tags
+%Image::ExifTool::PostScript::Composite = (
+    GROUPS => { 2 => 'Image' },
+    # BoundingBox is in points, not pixels,
+    # but use it anyway if ImageData is not available
+    ImageWidth => {
+        Desire => {
+            0 => 'PostScript:ImageData',
+            1 => 'PostScript:BoundingBox',
+        },
+        ValueConv => 'Image::ExifTool::PostScript::ImageSize(\@val, 0)',
+    },
+    ImageHeight => {
+        Desire => {
+            0 => 'PostScript:ImageData',
+            1 => 'PostScript:BoundingBox',
+        },
+        ValueConv => 'Image::ExifTool::PostScript::ImageSize(\@val, 1)',
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::PostScript');
+
+#------------------------------------------------------------------------------
+# AutoLoad our writer routines when necessary
+#
+sub AUTOLOAD
+{
+    return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
+}
+
+#------------------------------------------------------------------------------
+# Get image width or height
+# Inputs: 0) value list ref (ImageData, BoundingBox), 1) true to get height
+sub ImageSize($$)
+{
+    my ($vals, $getHeight) = @_;
+    my ($w, $h);
+    if ($$vals[0] and $$vals[0] =~ /^(\d+) (\d+)/) {
+        ($w, $h) = ($1, $2);
+    } elsif ($$vals[1] and $$vals[1] =~ /^(\d+) (\d+) (\d+) (\d+)/) {
+        ($w, $h) = ($3 - $1, $4 - $2);
+    }
+    return $getHeight ? $h : $w;
+}
+
+#------------------------------------------------------------------------------
+# Set PostScript format error warning
+# Inputs: 0) ExifTool object reference, 1) error string
+# Returns: 1
+sub PSErr($$)
+{
+    my ($exifTool, $str) = @_;
+    # set file type if not done already
+    $exifTool->SetFileType('PS') unless $exifTool->GetValue('FileType');
+    $exifTool->Warn("PostScript format error ($str)");
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# set $/ according to the current file
+# Inputs: 0) RAF reference
+# Returns: Original separator or undefined if on error
+sub SetInputRecordSeparator($)
+{
+    my $raf = shift;
+    my $oldsep = $/;
+    my $pos = $raf->Tell(); # save current position
+    my $data;
+    $raf->Read($data,256) or return undef;
+    my ($a, $d) = (999,999);
+    $a = pos($data), pos($data) = 0 if $data =~ /\x0a/g;
+    $d = pos($data) if $data =~ /\x0d/g;
+    my $diff = $a - $d;
+    if ($diff eq 1) {
+        $/ = "\x0d\x0a";
+    } elsif ($diff eq -1) {
+        $/ = "\x0a\x0d";
+    } elsif ($diff > 0) {
+        $/ = "\x0d";
+    } elsif ($diff < 0) {
+        $/ = "\x0a";
+    } else {
+        return undef;       # error
+    }
+    $raf->Seek($pos, 0);    # restore original position
+    return $oldsep;
+}
+
+#------------------------------------------------------------------------------
+# Extract information from EPS, PS or AI file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 if this was a valid PostScript file
+sub ProcessPS($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my ($data, $dos);
+#
+# determine if this is a postscript file
+#
+    $raf->Read($data, 4) == 4 or return 0;
+    # accept either ASCII or DOS binary postscript file format
+    return 0 unless $data =~ /^(%!PS|%!Ad|\xc5\xd0\xd3\xc6)/;
+    if ($data =~ /^%!Ad/) {
+        # I've seen PS files start with "%!Adobe-PS"...
+        return 0 unless $raf->Read($data, 6) == 6 and $data eq "obe-PS";
+    } elsif ($data =~ /^\xc5\xd0\xd3\xc6/) {
+        # process DOS binary file header
+        # - save DOS header then seek ahead and check PS header
+        $raf->Read($dos, 26) == 26 or return 0;
+        SetByteOrder('II');
+        unless ($raf->Seek(Get32u(\$dos, 0), 0) and
+                $raf->Read($data, 4) == 4 and $data eq '%!PS')
+        {
+            return PSErr($exifTool, 'invalid header');
+        }
+    }
+#
+# set the newline type based on the first newline found in the file
+#
+    my $oldsep = SetInputRecordSeparator($raf);
+    $oldsep or return PSErr($exifTool, 'invalid PS data');
+
+    # set file type (PostScript or EPS)
+    $raf->ReadLine($data) or return 0;
+    $exifTool->SetFileType($data =~ /EPSF/ ? 'EPS' : 'PS');
+#
+# extract TIFF information from DOS header
+#
+    my $tagTablePtr = GetTagTable('Image::ExifTool::PostScript::Main');
+    if ($dos) {
+        my $base = Get32u(\$dos, 16);
+        if ($base) {
+            my $pos = $raf->Tell();
+            # extract the TIFF preview
+            my $len = Get32u(\$dos, 20);
+            my $val = $exifTool->ExtractBinary($base, $len, 'TIFFPreview');
+            if (defined $val and $val =~ /^(MM\0\x2a|II\x2a\0|Binary)/) {
+                $exifTool->HandleTag($tagTablePtr, 'TIFFPreview', $val);
+            } else {
+                $exifTool->Warn('Bad TIFF preview image');
+            }
+            # extract information from TIFF in DOS header
+            # (set Parent to '' to avoid setting FileType tag again)
+            my %dirInfo = (
+                Parent => '',
+                RAF => $raf,
+                Base => $base,
+            );
+            $exifTool->ProcessTIFF(\%dirInfo) or $exifTool->Warn('Bad embedded TIFF');
+            # position file pointer to extract PS information
+            $raf->Seek($pos, 0);
+        }
+    }
+#
+# parse the postscript
+#
+    my ($buff, $mode, $endToken);
+    my (@lines, $altnl);
+    if ($/ eq "\x0d") {
+        $altnl = "\x0a";
+    } else {
+        $/ = "\x0a";        # end on any LF (even if DOS CR+LF)
+        $altnl = "\x0d";
+    }
+    for (;;) {
+        if (@lines) {
+            $data = shift @lines;
+        } else {
+            $raf->ReadLine($data) or last;
+            # check for alternate newlines as efficiently as possible
+            if ($data =~ /$altnl/) {
+                # split into separate lines
+                @lines = split /$altnl/, $data, -1;
+                $data = shift @lines;
+                if (@lines == 1 and $lines[0] eq $/) {
+                    # handle case of DOS newline data inside file using Unix newlines
+                    $data .= $lines[0];
+                    undef @lines;
+                }
+            }
+        }
+        if ($mode) {
+            if (not $endToken) {
+                $buff .= $data;
+                next unless $data =~ m{<\?xpacket end=.(w|r).\?>($/|$)};
+            } elsif ($data !~ /^$endToken/i) {
+                if ($mode eq 'XMP') {
+                    $buff .= $data;
+                } elsif ($mode eq 'Document') {
+                    # ignore embedded documents 
+                } else {
+                    # data is ASCII-hex encoded
+                    $data =~ tr/0-9A-Fa-f//dc;  # remove all but hex characters
+                    $buff .= pack('H*', $data); # translate from hex
+                }
+                next;
+            }
+        } elsif ($data =~ /^(%{1,2})(Begin)(_xml_packet|Photoshop|ICCProfile|Binary)/i) {
+            # the beginning of a data block
+            my %modeLookup = (
+                _xml_packet => 'XMP',
+                iccprofile  => 'ICC_Profile',
+                photoshop   => 'Photoshop',
+            );
+            $mode = $modeLookup{lc($3)};
+            unless ($mode or @lines) {
+                # skip binary data
+                $raf->Seek($1, 1) or last if $data =~ /^%{1,2}BeginBinary:\s*(\d+)/i;
+                next;
+            }
+            $buff = '';
+            $endToken = $1 . ($2 eq 'begin' ? 'end' : 'End') . $3;
+            next;
+        } elsif ($data =~ /^(%{1,2})(Begin)(Document)/i) {
+            $mode = 'Document';
+            next;
+        } elsif ($data =~ /^<\?xpacket begin=.{7,13}W5M0MpCehiHzreSzNTczkc9d/) {
+            # pick up any stray XMP data
+            $mode = 'XMP';
+            $buff = $data;
+            undef $endToken;    # no end token (just look for xpacket end)
+            # XMP could be contained in a single line (if newlines are different)
+            next unless $data =~ m{<\?xpacket end=.(w|r).\?>($/|$)};
+        } elsif ($data =~ /^%%?(\w+): ?(.*)/s and $$tagTablePtr{$1}) {
+            my ($tag, $val) = ($1, $2);
+            # only allow 'ImageData' to have single leading '%'
+            next unless $data =~ /^%%/ or $1 eq 'ImageData';
+            # extract information from PostScript tags in comments
+            $val =~ s/\x0d*\x0a*$//;        # remove trailing CR, LF or CR/LF
+            if ($val =~ s/^\((.*)\)$/$1/) { # remove brackets if necessary
+                $val =~ s/\) \(/, /g;       # convert contained brackets too
+            }
+            $exifTool->HandleTag($tagTablePtr, $tag, $val);
+            next;
+        } else {
+            next;
+        }
+        # extract information from buffered data
+        if ($mode ne 'Document'){
+            my %dirInfo = (
+                DataPt => \$buff,
+                DataLen => length $buff,
+                DirStart => 0,
+            	DirLen => length $buff,
+            	Parent => 'PostScript',
+            );
+            my $subTablePtr = GetTagTable("Image::ExifTool::${mode}::Main");
+            unless ($exifTool->ProcessDirectory(\%dirInfo, $subTablePtr)) {
+                $exifTool->Warn("Error processing $mode information in PostScript file");
+            }
+            undef $buff;
+        }
+        undef $mode;
+    }
+    $/ = $oldsep;   # restore original separator
+    $mode and $mode ne 'Document' and PSErr($exifTool, "unterminated $mode data");
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Extract information from EPS file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 if this was a valid PostScript file
+sub ProcessEPS($$)
+{
+    return ProcessPS($_[0],$_[1]);
+}
+
+1; # end
+
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::PostScript - Read PostScript meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This code reads meta information from EPS (Encapsulated PostScript), PS
+(PostScript) and AI (Adobe Illustrator) files.
+
+=head1 NOTES
+
+Currently doesn't handle continued lines ("%+" syntax).
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf>
+
+=item L<http://partners.adobe.com/public/developer/en/ps/5001.DSC_Spec.pdf>
+
+=item L<http://partners.adobe.com/public/developer/en/illustrator/sdk/AI7FileFormat.pdf>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/PostScript Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/PrintIM.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/PrintIM.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/PrintIM.pm	(revision 20131)
@@ -0,0 +1,108 @@
+#------------------------------------------------------------------------------
+# File:         PrintIM.pm
+#
+# Description:  Read PrintIM meta information
+#
+# Revisions:    04/07/2004  - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::PrintIM;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess);
+
+$VERSION = '1.03';
+
+sub ProcessPrintIM($$$);
+
+# PrintIM table (is this proprietary? I can't find any documentation on this)
+%Image::ExifTool::PrintIM::Main = (
+    PROCESS_PROC => \&ProcessPrintIM,
+    GROUPS => { 0 => 'PrintIM', 1 => 'PrintIM', 2 => 'Printing' },
+    PRINT_CONV => 'sprintf("0x%.8x", $val)',
+    TAG_PREFIX => 'PrintIM',
+);
+
+
+#------------------------------------------------------------------------------
+# Process PrintIM IFD
+# Inputs: 0) ExifTool object reference, 1) reference to directory information
+#         2) pointer to tag table
+# Returns: 1 on success
+sub ProcessPrintIM($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $offset = $$dirInfo{DirStart};
+    my $size = $$dirInfo{DirLen};
+    my $verbose = $exifTool->Options('Verbose');
+
+    unless ($size > 15) {
+        $exifTool->Warn('Bad PrintIM data');
+        return 0;
+    }
+    my $header = substr($$dataPt, $offset, 7);
+    unless ($header eq 'PrintIM') {
+        $exifTool->Warn('Invalid PrintIM header');
+        return 0;
+    }
+    # check size of PrintIM block
+    my $num = Get16u($dataPt, $offset + 14);
+    if ($size < 16 + $num * 6) {
+        # size is too big, maybe byte ordering is wrong
+        ToggleByteOrder();
+        $num = Get16u($dataPt, $offset + 14);
+        if ($size < 16 + $num * 6) {
+            $exifTool->Warn('Bad PrintIM size');
+            return 0;
+        }
+    }
+    $verbose and $exifTool->VerboseDir('PrintIM', $num);
+    my $n;
+    for ($n=0; $n<$num; ++$n) {
+        my $pos = $offset + 16 + $n * 6;
+        my $tag = Get16u($dataPt, $pos);
+        my $val = Get32u($dataPt, $pos + 2);
+        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            Index  => $n,
+            DataPt => $dataPt,
+            Size   => 4,
+            Start  => $pos + 2,
+        );
+    }
+    return 1;
+}
+
+
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::PrintIM - Read PrintIM meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+Print Image Matching meta information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/PrintIM Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/QuickTime.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/QuickTime.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/QuickTime.pm	(revision 20131)
@@ -0,0 +1,739 @@
+#------------------------------------------------------------------------------
+# File:         QuickTime.pm
+#
+# Description:  Read QuickTime, MP4 and M4A meta information
+#
+# Revisions:    10/04/2005 - P. Harvey Created
+#               12/19/2005 - P. Harvey Added MP4 support
+#               09/22/2006 - P. Harvey Added M4A support
+#
+# References:   1) http://developer.apple.com/documentation/QuickTime/
+#               2) http://search.cpan.org/dist/MP4-Info-1.04/
+#               3) http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt
+#               4) http://wiki.multimedia.cx/index.php?title=Apple_QuickTime
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::QuickTime;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.12';
+
+sub FixWrongFormat($);
+sub ProcessMOV($$;$);
+
+# information for time/date-based tags (time zero is Jan 1, 1904)
+my %timeInfo = (
+    Groups => { 2 => 'Time' },
+    # Note: This value will be in UTC if generated by a system that is aware of the time zone
+    ValueConv => 'ConvertUnixTime($val - ((66 * 365 + 17) * 24 * 3600))',
+    PrintConv => '$self->ConvertDateTime($val)',
+);
+# information for duration tags
+my %durationInfo = (
+    ValueConv => '$self->{TimeScale} ? $val / $self->{TimeScale} : $val',
+    PrintConv => '$self->{TimeScale} ? sprintf("%.2fs", $val) : $val',
+);
+
+# QuickTime atoms
+%Image::ExifTool::QuickTime::Main = (
+    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    NOTES => q{
+        These tags are used in QuickTime MOV and MP4 videos, and QTIF images.  Tags
+        with a question mark after their name are not extracted unless the Unknown
+        option is set.
+    },
+    free => { Unknown => 1, Binary => 1 },
+    skip => { Unknown => 1, Binary => 1 },
+    wide => { Unknown => 1, Binary => 1 },
+    ftyp => { #MP4
+        Name => 'FrameType',
+        Unknown => 1,
+        Notes => 'MP4 only',
+        Binary => 1,
+    },
+    pnot => {
+        Name => 'Preview',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Preview' },
+    },
+    PICT => {
+        Name => 'PreviewPICT',
+        Binary => 1,
+    },
+    moov => {
+        Name => 'Movie',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Movie' },
+    },
+    mdat => { Unknown => 1, Binary => 1 },
+);
+
+# atoms used in QTIF files
+%Image::ExifTool::QuickTime::ImageFile = (
+    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
+    GROUPS => { 2 => 'Image' },
+    NOTES => 'Tags used in QTIF QuickTime Image Files.',
+    idsc => {
+        Name => 'ImageDescription',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ImageDesc' },
+    },
+    idat => {
+        Name => 'ImageData',
+        Binary => 1,
+    },
+    iicc => {
+        Name => 'ICC_Profile',
+        SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' },
+    },
+);
+
+# image description data block
+%Image::ExifTool::QuickTime::ImageDesc = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    4 => { Name => 'CompressorID',  Format => 'string[4]' },
+    20 => { Name => 'VendorID',     Format => 'string[4]' },
+    28 => { Name => 'Quality',      Format => 'int32u' },
+    32 => { Name => 'ImageWidth',   Format => 'int16u' },
+    34 => { Name => 'ImageHeight',  Format => 'int16u' },
+    36 => { Name => 'XResolution',  Format => 'int32u' },
+    40 => { Name => 'YResolution',  Format => 'int32u' },
+    48 => { Name => 'FrameCount',   Format => 'int16u' },
+    50 => { Name => 'NameLength',   Format => 'int8u' },
+    51 => { Name => 'Compressor',   Format => 'string[$val{46}]' },
+    82 => { Name => 'BitDepth',     Format => 'int16u' },
+);
+
+# preview data block
+%Image::ExifTool::QuickTime::Preview = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    FORMAT => 'int16u',
+    0 => {
+        Name => 'PreviewDate',
+        Format => 'int32u',
+        %timeInfo,
+    },
+    2 => 'PreviewVersion',
+    3 => {
+        Name => 'PreviewAtomType',
+        Format => 'string[4]',
+    },
+    5 => 'PreviewAtomIndex',
+);
+
+# movie atoms
+%Image::ExifTool::QuickTime::Movie = (
+    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    mvhd => {
+        Name => 'MovieHeader',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::MovieHdr' },
+    },
+    trak => {
+        Name => 'Track',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Track' },
+    },
+    udta => {
+        Name => 'UserData',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::UserData' },
+    },
+);
+
+# movie header data block
+%Image::ExifTool::QuickTime::MovieHdr = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    FORMAT => 'int32u',
+    0 => { Name => 'Version', Format => 'int8u' },
+    1 => {
+        Name => 'CreateDate',
+        %timeInfo,
+    },
+    2 => {
+        Name => 'ModifyDate',
+        %timeInfo,
+    },
+    3 => {
+        Name => 'TimeScale',
+        RawConv => '$self->{TimeScale} = $val',
+    },
+    4 => { Name => 'Duration', %durationInfo },
+    5 => {
+        Name => 'PreferredRate',
+        ValueConv => '$val / 0x10000',
+    },
+    6 => {
+        Name => 'PreferredVolume',
+        Format => 'int16u',
+        ValueConv => '$val / 256',
+        PrintConv => 'sprintf("%.2f%%", $val * 100)',
+    },
+    18 => { Name => 'PreviewTime',      %durationInfo },
+    19 => { Name => 'PreviewDuration',  %durationInfo },
+    20 => { Name => 'PosterTime',       %durationInfo },
+    21 => { Name => 'SelectionTime',    %durationInfo },
+    22 => { Name => 'SelectionDuration',%durationInfo },
+    23 => { Name => 'CurrentTime',      %durationInfo },
+    24 => 'NextTrackID',
+);
+
+# track atoms
+%Image::ExifTool::QuickTime::Track = (
+    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    tkhd => {
+        Name => 'TrackHeader',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TrackHdr' },
+    },
+    udta => {
+        Name => 'UserData',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::UserData' },
+    },
+    mdia => { #MP4
+        Name => 'Media',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Media' },
+    },
+);
+
+# track header data block
+%Image::ExifTool::QuickTime::TrackHdr = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 1 => 'Track#', 2 => 'Video' },
+    FORMAT => 'int32u',
+    0 => {
+        Name => 'TrackVersion',
+        Format => 'int8u',
+        Priority => 0,
+    },
+    1 => {
+        Name => 'TrackCreateDate',
+        Priority => 0,
+        %timeInfo,
+    },
+    2 => {
+        Name => 'TrackModifyDate',
+        Priority => 0,
+        %timeInfo,
+    },
+    3 => {
+        Name => 'TrackID',
+        Priority => 0,
+    },
+    5 => {
+        Name => 'TrackDuration',
+        Priority => 0,
+        %durationInfo,
+    },
+    8 => {
+        Name => 'TrackLayer',
+        Format => 'int16u',
+        Priority => 0,
+    },
+    9 => {
+        Name => 'TrackVolume',
+        Format => 'int16u',
+        Priority => 0,
+        ValueConv => '$val / 256',
+        PrintConv => 'sprintf("%.2f%%", $val * 100)',
+    },
+    19 => {
+        Name => 'ImageWidth',
+        Priority => 0,
+        RawConv => \&FixWrongFormat,
+    },
+    20 => {
+        Name => 'ImageHeight',
+        Priority => 0,
+        RawConv => \&FixWrongFormat,
+    },
+);
+
+# user data atoms
+%Image::ExifTool::QuickTime::UserData = (
+    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    NOTES => q{
+        Tag ID's beginning with the copyright symbol (hex 0xa9) are multi-language
+        text, but ExifTool only extracts the text from the first language in the
+        record.  ExifTool will extract any multi-language user data tags found, even
+        if they don't exist in this table.
+    },
+    "\xa9cpy" => 'Copyright',
+    "\xa9day" => 'CreateDate',
+    "\xa9dir" => 'Director',
+    "\xa9ed1" => 'Edit1',
+    "\xa9ed2" => 'Edit2',
+    "\xa9ed3" => 'Edit3',
+    "\xa9ed4" => 'Edit4',
+    "\xa9ed5" => 'Edit5',
+    "\xa9ed6" => 'Edit6',
+    "\xa9ed7" => 'Edit7',
+    "\xa9ed8" => 'Edit8',
+    "\xa9ed9" => 'Edit9',
+    "\xa9fmt" => 'Format',
+    "\xa9inf" => 'Information',
+    "\xa9prd" => 'Producer',
+    "\xa9prf" => 'Performers',
+    "\xa9req" => 'Requirements',
+    "\xa9src" => 'Source',
+    "\xa9wrt" => 'Writer',
+    name => 'Name',
+    WLOC => {
+        Name => 'WindowLocation',
+        Format => 'int16u',
+    },
+    LOOP => {
+        Name => 'LoopStyle',
+        Format => 'int32u',
+        PrintConv => {
+            1 => 'Normal',
+            2 => 'Palindromic',
+        },
+    },
+    SelO => {
+        Name => 'PlaySelection',
+        Format => 'int8u',
+    },
+    AllF => {
+        Name => 'PlayAllFrames',
+        Format => 'int8u',
+    },
+    meta => {
+        Name => 'Meta',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::QuickTime::Meta',
+            HasVersion => 1, # must skip 4-byte version number header
+        },
+    },
+   'ptv '=> {
+        Name => 'PrintToVideo',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Video' },
+    },
+    # hnti => 'HintInfo',
+    # hinf => 'HintTrackInfo',
+    TAGS => [
+        {
+            # these tags were initially discovered in a Pentax movie, but
+            # seem very similar to those used by Nikon
+            Name => 'PentaxTags',
+            Condition => '$$valPt =~ /^PENTAX DIGITAL CAMERA\0/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Pentax::MOV',
+                ByteOrder => 'LittleEndian',
+            },
+        },
+        {
+            Name => 'NikonTags',
+            Condition => '$$valPt =~ /^NIKON DIGITAL CAMERA\0/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::MOV',
+                ByteOrder => 'LittleEndian',
+            },
+        },
+        {
+            Name => 'SanyoMOV',
+            Condition => q{
+                $$valPt =~ /^SANYO DIGITAL CAMERA\0/ and
+                $self->{VALUE}->{FileType} eq "MOV"
+            },
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Sanyo::MOV',
+                ByteOrder => 'LittleEndian',
+            },
+        },
+        {
+            Name => 'SanyoMP4',
+            Condition => q{
+                $$valPt =~ /^SANYO DIGITAL CAMERA\0/ and
+                $self->{VALUE}->{FileType} eq "MP4"
+            },
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Sanyo::MP4',
+                ByteOrder => 'LittleEndian',
+            },
+        },
+        {
+            Name => 'UnknownTags',
+            Unknown => 1,
+            Binary => 1
+        },
+    ],
+);
+
+# meta atoms
+%Image::ExifTool::QuickTime::Meta = (
+    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    ilst => {
+        Name => 'InfoList',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::QuickTime::InfoList',
+            HasData => 1, # process atoms as containers with 'data' elements
+        },
+    },
+);
+
+# info list atoms
+# -> these atoms are unique, and contain one or more 'data' atoms
+%Image::ExifTool::QuickTime::InfoList = (
+    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
+    GROUPS => { 2 => 'Audio' },
+    "\xa9ART" => 'Artist',
+    "\xa9alb" => 'Album',
+    "\xa9cmt" => 'Comment',
+    "\xa9com" => 'Composer',
+    "\xa9day" => 'Year',
+    "\xa9des" => 'Description', #4
+    "\xa9gen" => 'Genre',
+    "\xa9grp" => 'Grouping',
+    "\xa9lyr" => 'Lyrics',
+    "\xa9nam" => 'Title',
+    "\xa9too" => 'Encoder',
+    "\xa9trk" => 'Track',
+    "\xa9wrt" => 'Composer',
+    '----' => {
+        Name => 'iTunesInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::iTunesInfo' },
+    },
+    aART => 'AlbumArtist',
+    apid => 'AppleStoreID',
+    auth => 'Author',
+    covr => 'CoverArt',
+    cpil => {
+        Name => 'Compilation',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    cprt => 'Copyright',
+    disk => {
+        Name => 'DiskNumber',
+        ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
+    },
+    dscp => 'Description',
+    gnre => 'Genre',
+    perf => 'Performer',
+    pgap => {
+        Name => 'PlayGap',
+        PrintConv => {
+            0 => 'Insert Gap',
+            1 => 'No Gap',
+        },
+    },
+    rtng => 'Rating', # int
+    titl => 'Title',
+    tmpo => 'BeatsPerMinute', # int
+    trkn => {
+        Name => 'TrackNumber',
+        ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
+    },
+);
+
+# info list atoms
+%Image::ExifTool::QuickTime::iTunesInfo = (
+    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
+    GROUPS => { 2 => 'Audio' },
+);
+
+# print to video data block
+%Image::ExifTool::QuickTime::Video = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    0 => {
+        Name => 'DisplaySize',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Double Size',
+            2 => 'Half Size',
+            3 => 'Full Screen',
+            4 => 'Current Size',
+        },
+    },
+    6 => {
+        Name => 'SlideShow',
+        PrintConv => {
+            0 => 'No',
+            1 => 'Yes',
+        },
+    },
+);
+
+# MP4 media
+%Image::ExifTool::QuickTime::Media = (
+    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    NOTES => 'MP4 only (most tags unknown because ISO charges for the specification).',
+    minf => {
+        Name => 'Minf',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Minf' },
+    },
+);
+
+%Image::ExifTool::QuickTime::Minf = (
+    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    NOTES => 'MP4 only (most tags unknown because ISO charges for the specification).',
+    dinf => {
+        Name => 'Dinf',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Dinf' },
+    },
+    stbl => {
+        Name => 'Stbl',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Stbl' },
+    },
+);
+
+%Image::ExifTool::QuickTime::Stbl = (
+    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    NOTES => 'MP4 only (most tags unknown because ISO charges for the specification).',
+);
+
+%Image::ExifTool::QuickTime::Dinf = (
+    PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    NOTES => 'MP4 only (most tags unknown because ISO charges for the specification).',
+);
+
+#------------------------------------------------------------------------------
+# Fix incorrect format for ImageWidth/Height as written by Pentax
+sub FixWrongFormat($)
+{
+    my $val = shift;
+    return undef unless $val;
+    if ($val & 0xffff0000) {
+        $val = unpack('n',pack('N',$val));
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Process a QuickTime atom
+# Inputs: 0) ExifTool object reference, 1) directory information reference
+#         2) optional tag table reference
+# Returns: 1 on success
+sub ProcessMOV($$;$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $dataPt = $$dirInfo{DataPt};
+    my $verbose = $exifTool->Options('Verbose');
+    my $dataPos = $$dirInfo{Base} || 0;
+    my ($buff, $tag, $size, $track);
+
+    # more convenient to package data as a RandomAccess file
+    $raf or $raf = new File::RandomAccess($dataPt);
+    # skip leading 4-byte version number if necessary
+    ($raf->Read($buff,4) == 4 and $dataPos += 4) or return 0 if $$dirInfo{HasVersion};
+    # read size/tag name atom header
+    $raf->Read($buff,8) == 8 or return 0;
+    $dataPos += 8;
+    $tagTablePtr or $tagTablePtr = GetTagTable('Image::ExifTool::QuickTime::Main');
+    ($size, $tag) = unpack('Na4', $buff);
+    if ($dataPt) {
+        $verbose and $exifTool->VerboseDir($$dirInfo{DirName});
+    } else {
+        # check on file type if called with a RAF
+        $$tagTablePtr{$tag} or return 0;
+        if ($tag eq 'ftyp') {
+            # read ahead 4 bytes to see if this is an M4A file
+            my $ftyp = 'MP4';
+            if ($raf->Read($buff, 4) == 4) {
+                $raf->Seek(-4, 1);
+                $ftyp = 'M4A' if $buff eq 'M4A ';
+            }
+            $exifTool->SetFileType($ftyp);  # MP4 or M4A
+        } else {
+            $exifTool->SetFileType();       # MOV
+        }
+        SetByteOrder('MM');
+    }
+    for (;;) {
+        if ($size < 8) {
+            last if $size == 0;
+            $size == 1 or $exifTool->Warn('Invalid atom size'), last;
+            $raf->Read($buff, 8) == 8 or last;
+            $dataPos += 8;
+            my ($hi, $lo) = unpack('NN', $buff);
+            if ($hi or $lo > 0x7fffffff) {
+                $exifTool->Warn('End of processing at large atom');
+                last;
+            }
+            $size = $lo;
+        }
+        $size -= 8;
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        # generate tagInfo if Unknown option set
+        if (not defined $tagInfo and ($exifTool->{OPTIONS}->{Unknown} or
+            $tag =~ /^\xa9/))
+        {
+            my $name = $tag;
+            $name =~ s/([\x00-\x1f\x7f-\xff])/'x'.unpack('H*',$1)/eg;
+            if ($name =~ /^xa9(.*)/) {
+                $tagInfo = {
+                    Name => "UserData_$1",
+                    Description => "User Data $1",
+                };
+            } else {
+                $tagInfo = {
+                    Name => "Unknown_$name",
+                    Description => "Unknown $name",
+                    Unknown => 1,
+                    Binary => 1,
+                };
+            }
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        # load values only if associated with a tag (or verbose) and < 16MB long
+        if ((defined $tagInfo or $verbose) and $size < 0x1000000) {
+            my $val;
+            unless ($raf->Read($val, $size) == $size) {
+                $exifTool->Warn("Truncated '$tag' data");
+                last;
+            }
+            # use value to get tag info if necessary
+            $tagInfo or $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag, \$val);
+            my $hasData = ($$dirInfo{HasData} and $val =~ /^\0...data\0/s);
+            if ($verbose and not $hasData) {
+                $exifTool->VerboseInfo($tag, $tagInfo,
+                    Value => $val,
+                    DataPt => \$val,
+                    DataPos => $dataPos,
+                );
+            }
+            if ($tagInfo) {
+                my $subdir = $$tagInfo{SubDirectory};
+                if ($subdir) {
+                    my %dirInfo = (
+                        DataPt => \$val,
+                        DirStart => 0,
+                        DirLen => $size,
+                        DirName => $$tagInfo{Name},
+                        HasData => $$subdir{HasData},
+                        HasVersion => $$subdir{HasVersion},
+                        # Base needed for IsOffset tags in binary data
+                        Base => $dataPos,
+                    );
+                    if ($$subdir{ByteOrder} and $$subdir{ByteOrder} =~ /^Little/) {
+                        SetByteOrder('II');
+                    }
+                    if ($$tagInfo{Name} eq 'Track') {
+                        $track or $track = 0;
+                        $exifTool->{SET_GROUP1} = 'Track' . (++$track);
+                    }
+                    my $subTable = GetTagTable($$subdir{TagTable});
+                    $exifTool->ProcessDirectory(\%dirInfo, $subTable);
+                    delete $exifTool->{SET_GROUP1};
+                    SetByteOrder('MM');
+                } elsif ($hasData) {
+                    # handle atoms containing 'data' tags
+                    my $pos = 0;
+                    for (;;) {
+                        last if $pos + 16 > $size;
+                        my ($len, $type, $flags) = unpack("x${pos}Na4N", $val);
+                        last if $pos + $len > $size;
+                        my $value;
+                        if ($type eq 'data' and $len >= 16) {
+                            $pos += 16;
+                            $len -= 16;
+                            $value = substr($val, $pos, $len);
+                            # format flags: 0x0=binary, 0x1=text, 0xd=image, 0x15=boolean 
+                            if ($flags == 0x0015) {
+                                $value = $len ? ReadValue(\$value, $len-1, 'int8u', 1, 1) : '';
+                            } elsif ($flags != 0x01 and not $$tagInfo{ValueConv}) {
+                                # make binary data a scalar reference unless a ValueConv exists
+                                my $buf = $value;
+                                $value = \$buf;
+                            }
+                        }
+                        $exifTool->VerboseInfo($tag, $tagInfo,
+                            Value => ref $value ? $$value : $value,
+                            DataPt => \$val,
+                            DataPos => $dataPos,
+                            Start => $pos,
+                            Size => $len,
+                            Extra => sprintf(", Type='$type', Flags=0x%x",$flags)
+                        ) if $verbose;
+                        $exifTool->FoundTag($tagInfo, $value) if defined $value;
+                        $pos += $len;
+                    }
+                } else {
+                    if ($tag =~ /^\xa9/) {
+                        # parse international text to extract first string
+                        my $len = unpack('n', $val);
+                        # $len should include 4 bytes for length and type words,
+                        # but Pentax forgets to add these in, so allow for this
+                        $len += 4 if $len == $size - 4;
+                        $val = substr($val, 4, $len - 4) if $len <= $size;
+                    } elsif ($$tagInfo{Format}) {
+                        $val = ReadValue(\$val, 0, $$tagInfo{Format}, $$tagInfo{Count}, length($val));
+                    }
+                    $exifTool->FoundTag($tagInfo, $val);
+                }
+            }
+        } else {
+            $raf->Seek($size, 1) or $exifTool->Warn("Truncated '$tag' data"), last;
+        }
+        $raf->Read($buff, 8) == 8 or last;
+        $dataPos += $size + 8;
+        ($size, $tag) = unpack('Na4', $buff);
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process a QuickTime Image File
+# Inputs: 0) ExifTool object reference, 1) directory information reference
+# Returns: 1 on success
+sub ProcessQTIF($$)
+{
+    my $table = GetTagTable('Image::ExifTool::QuickTime::ImageFile');
+    return ProcessMOV($_[0], $_[1], $table);
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::QuickTime - Read QuickTime and MP4 meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to extract
+information from QuickTime and MP4 video, and M4A audio files.
+
+=head1 BUGS
+
+The MP4 support is rather pathetic since the specification documentation is
+not freely available (yes, ISO sucks).
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://developer.apple.com/documentation/QuickTime/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/QuickTime Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/README
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/README	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/README	(revision 20131)
@@ -0,0 +1,561 @@
+--------------------------------------------------------------------------------
+File:         Image/ExifTool/README
+
+Description:  ExifTool support modules documentation
+
+The ExifTool support modules are loaded by ExifTool to interpret various formats
+of meta information.
+
+The tables in these files are used as lookups based on the tag ID values.  The
+hash keys are the tag IDs (in decimal or hexadecimal if the ID is numerical as
+with EXIF tables, or the tag name if the ID is ASCII as with XMP tables).  In
+the case of a BinaryData table, the IDs are numerical and specify offsets into
+the binary data block.  The corresponding hash value provides information about
+the tag (explained later).
+
+Twenty-one special keys (PROCESS_PROC, WRITE_PROC, CHECK_PROC, GROUPS, FORMAT,
+FIRST_ENTRY, TAG_PREFIX, PRINT_CONV, DID_TAG_ID, WRITABLE, NOTES, IS_OFFSET,
+EXTRACT_UNKNOWN, NAMESPACE, PREFERRED, PARENT, PRIORITY, WRITE_GROUP, LANG_INFO,
+VARS and DATAMEMBER) are used to provide additional information about a table.
+The special keys have names that are all capitalized to avoid possible conflicts
+with tag keys.  Below is an explanation of the meaning of each special key:
+
+  PROCESS_PROC : Reference to a function used to process the directory for this
+  table.  If PROCESS_PROC is not given, \&Image::ExifTool::Exif::ProcessExif is
+  assumed.  If PROCESS_PROC is set to 0, the tags are not added to the lookup.
+  The process proc returns 1 on success or 0 on failure, and takes 3 arguments:
+  0) reference to the ExifTool object, 1) reference to a directory information
+  hash (with the following entries:), 2) reference to the tag table hash.
+
+    Name        - Tag name for this SubDirectory entry (for verbose messages)
+    Base        - Base offset for pointers from start of file
+    DataPt      - Reference to data block containing directory (may be undef)
+    DataPos     - Position of data block within file (relative to Base)
+    DataLen     - Length of data block in bytes
+    DirStart    - Offset to start of directory from start of data block
+    DirLen      - Length of directory data within block
+    DirName     - Name of this directory
+    OutFile     - Output file or scalar reference
+    Parent      - Name of parent directory
+    RAF         - Reference to File::RandomAccess object if available
+    NewDataPos  - File position of new data (write proc only)
+    Fixup       - Reference to hash of offset fixups (used in EXIF writing only)
+    FixBase     - Flag set to attempt to fix base offsets
+    FixOffsets  - Evaluated for each value pointer to patch maker note offsets
+    LastIFD     - Used by WriteExif() to return offset of last IFD written
+    ImageData   - Used by WriteExif() to avoid buffering large image data blocks
+
+  WRITE_PROC : Reference to a function to write all new tags for this directory.
+  The write proc returns the new directory data or undefined on error.  It takes
+  the same arguments as the process proc above except that the second argument
+  (reference to directory information hash) is optional, and if specified gives
+  information about the source directory for tags to be copied to the output.
+
+  CHECK_PROC : Reference to a function which validates Raw values for writing.
+  The function takes three arguments: 0) ExifTool object reference, 1) tagInfo
+  reference, 2) value reference, and returns undefined (and possibly modifies
+  the input value) if successful, or an error message if there was a format
+  problem.
+
+  GROUPS : A hash lookup for the default group names for all entries in this
+  table. If not specified, the Group 0 and 1 names will be set automatically
+  according to the name of the module.
+
+  FORMAT : Specifies the default tag Format and corresponding pointer increment
+  for entries in a BinaryData table, and defaults to 'int8u' if not specified.
+  The possible values of FORMAT are:
+
+    int8s       - Signed 8-bit integer                    (EXIF 'SBYTE')
+    int8u       - Unsigned 8-bit integer                  (EXIF 'BYTE')
+    int16s      - Signed 16-bit integer                   (EXIF 'SSHORT')
+    int16u      - Unsigned 16-bit integer                 (EXIF 'SHORT')
+    int32s      - Signed 32-bit integer                   (EXIF 'SLONG')
+    int32u      - Unsigned 32-bit integer                 (EXIF 'LONG')
+    int64s      - Signed 64-bit integer                   (BigTIFF 'SLONG8')
+    int64u      - Unsigned 64-bit integer                 (BigTIFF 'LONG8')
+    rational32s - Rational consisting of 2 int16s values
+    rational32u - Rational consisting of 2 int16u values
+    rational64s - Rational consisting of 2 int32s values  (EXIF 'SRATIONAL')
+    rational64u - Rational consisting of 2 int32u values  (EXIF 'RATIONAL')
+    fixed16s    - Signed 16-bit fixed point value
+    fixed16u    - Unsigned 16-bit fixed point value
+    fixed32s    - Signed 32-bit fixed point value
+    fixed32u    - Unsigned 32-bit fixed point value
+    float       - 32-bit IEEE floating point value        (EXIF 'FLOAT')
+    double      - 64-bit IEEE floating point value        (EXIF 'DOUBLE')
+    extended    - 80-bit extended floating float
+    ifd         - Unsigned 32-bit integer sub-IFD pointer (EXIF 'IFD')
+    ifd8        - Unsigned 64-bit integer sub-IFD pointer (BigTIFF 'IFD8')
+    string      - Series of 8-bit ASCII characters        (EXIF 'ASCII')
+    undef       - Undefined-format binary data            (EXIF 'UNDEFINED')
+    binary      - Binary data
+
+  FIRST_ENTRY : Specifies the index for the first tag entry in a binary table.
+  This value is only used if the Unknown option is set to 2 or higher, and
+  allows the binary data to be scanned for unknown tag entries.
+
+  TAG_PREFIX : Prefix for names of unknown tags.
+
+  PRINT_CONV : Default print conversion tags where PrintConv isn't specified.
+
+  DID_TAG_ID : Used by GetTagID() as a flag to indicate that TagID's have been
+  defined for all tags in this table.  This may be set in the table definition
+  to prevent GetTagID() from assigning TagID's.
+
+  WRITABLE : Indicates that all tags in this table are writable.  This is the
+  same as setting the Writable flag for each individual tag in the table, except
+  for SubDirectory tags which are not made Writable.
+
+  NOTES : Notes to introduce the table in the TagNames documentation.  Pod
+  formatting codes B<> and C<> may be used in this text.
+
+  IS_OFFSET : Reference to list of TagID's representing offsets for binary
+  data tables only.  Not used for EXIF tables.
+
+  EXTRACT_UNKNOWN : Used in PDF tables to specify a directory where all unknown
+  tags should be extracted.
+
+  NAMESPACE : Namespace prefix for tags in the XMP table.  If this isn't a
+  standard (pre-defined) namespace, then the URI must be defined as well.  To do
+  this, the NAMESPACE value is a reference to either a list or a hash, where the
+  first element (or hash key) is the namespace prefix and and the second element
+  (or hash value) is the URI.
+
+  PREFERRED : Set to true if the tags in this table should always be added when
+  writing information.  Overrides the order specified by SetNewGroups().  When
+  this feature is used, it may also be desireable to specify a preferred group
+  when calling InitWriteDirs() to write these tags; this avoids creating other
+  directories for tags which are already being creating in the preferred group.
+
+  PARENT : Used internally to store the parent table name of a user-defined tag
+  table so the appropriate module can be loaded as required.
+
+  PRIORITY : Default Priority for all tags in this table.
+
+  WRITE_GROUP : Default WriteGroup for all tags in the table.
+
+  LANG_INFO : Code reference to a routine which returns a reference to a
+  language-specific tag information hash.  The routine takes two arguments: a
+  reference to the non-specific tagInfo hash, and the language code. Used only
+  in tables which support tag name language extensions (ie. MIE and XMP).
+
+  VARS : Hash used to store additional parameters.  Individual modules may use
+  this to store any parameters they want.  The following additional parameters
+  have been defined, and may be used by any module:
+
+    INDEX - Use "Index" instead of "Tag ID" for column heading in tag name docs.
+
+    NO_ID - Avoid printing "Tag ID" column in tag name documentation.
+
+  DATAMEMBER : BinaryData tables only.  A reference to a list of tag ID's which
+  must be extracted as data members when writing.
+
+The remaining entries in a tag table are the tag IDs with their associated
+information.  The information may exist in one of three forms:  1) A simple
+scalar which is the name of the tag, 2) A reference to a hash of information
+describing this tag, or 3) a reference to a list of hashes which contain
+Condition expressions allowing the appropriate hash to be selected to suit the
+conditions.  The following is a description of possible hash entries.  All
+entries are optional, except for the tag Name which is required if the tag ID is
+numerical.
+
+  Name          : The tag name.  Tag names need not be unique.  If they aren't
+                  unique, duplicate tags overwrite values of previous tags
+                  unless the Duplicates option is set or the new tag has lower
+                  Priority.  With Duplicates set, to allow multiple tags with
+                  the same name to exist in the tag information hash, the key of
+                  the previous tag is changed to the form "TagName (N)", where N
+                  starts at 1 and increments for subsequent duplicate tags.  A
+                  tag name should start with an uppercase letter, and contain
+                  only the charcters in the set [A-Za-z0-9_-].
+
+  Description   : A more readable description of tag name.  If a tag doesn't
+                  specify a Description, then the tag Name is used instead, with
+                  spaces inserted between the words.
+
+  Notes         : Notes for this tag in the HTML TagNames documentation.
+
+  Groups        : Hash lookup for group names for this tag.
+
+  Format        : Only valid for BinaryData, EXIF and IPTC tables. For a Binary
+                  or EXIF table, this gives the format that is used to convert
+                  the binary data, and is one of the FORMAT types specified
+                  above. For BinaryData tables, the format may have a size in
+                  trailing brackets which is a perl expression to be evaluated.
+                  The expression may access any of the previous table entries
+                  through a %val hash, or the data size via $size. For example,
+                  'string[$val{3}]' defines a string with length given by the
+                  table entry with tag index '3'. If not specified, the format
+                  of an EXIF entry is taken from the EXIF information, and the
+                  format of a BinaryData entry is taken from the FORMAT
+                  specified for the table (or int8u if FORMAT is not specified).
+
+  Count         : Used when writing EXIF information to specify the number
+                  values to write, or the number of characters in a fixed-length
+                  string.  A value of -1 indicates that the count is variable
+                  and should be determined by the number of values provided.
+                  Note that this count that corresponds to the specified Format,
+                  so if a different-sized Writable format is defined, the actual
+                  count written to the file will be different.
+
+  Flags         : Flags to specify characteristics for this tag.  May be a
+                  simple scalar flag name, a reference to a list of flag names,
+                  or a reference to a hash of flag/value pairs. If not a hash
+                  reference, the flag value is set to 1. Flags are expanded for
+                  faster access at run time into members of the tagInfo hash,
+                  and may be written directly as members if desired. The
+                  available flag names are:
+
+                  'Avoid' - avoid creating this tag if possible.
+
+                  'Binary' - set to 1 for binary data.  This has the same effect
+                  as setting ValueConv to '\$val', but it it a bit cleaner and
+                  avoids dummy ValueConvInv entries for writable tags.  Has no
+                  effect if ValueConv is defined for the tag.
+
+                  'DataMember' - name of exiftool data member associated with
+                  this tag if it should be stored as a special data member when
+                  writing information.  Necessary only if the value of the tag
+                  affects other written information.  Currently only used for
+                  tags in EXIF tables.
+
+                  'DataTag' - associated tag name containing data for offset or
+                  byte count tags.
+
+                  'Drop' - set to 1 for tags that should be excluded when
+                  rebuilding maker notes when copying all tags.
+
+                  'EntryBased' - set to 1 if the offset for this value is based
+                  on the IFD entry position.  This allows individual values to
+                  be entry-based even though some others aren't (as with the
+                  Casio PrintIM information).
+
+                  'IsOffset' - flag set if the tag represents an offset to some
+                  data, and causes value will be adjusted to an absolute file
+                  offset.  If set to 2, the offset base of the parent directory
+                  is used even if the base changes for the current directory
+                  (only some maker notes are this messed up).
+
+                  'List' - indicates that duplicate entries of this tag are
+                  allowed, and will be accumulated in a list.  Note that for XMP
+                  information, 3 different types of lists are supported and the
+                  List value specifies the type: 'Bag', 'Seq' or 'Alt'.
+
+                  'MakerNotes' - set if this tag is maker note data.
+
+                  'NotIFD' - set for 'MakerNotes' tags only if the data is not
+                  in standard EXIF IFD format.
+                  
+                  'OffsetPair' - set if the tag represents half of an offset/
+                  byte count pair.  Data for these tags must be handled
+                  separately.  Value is the tagID for the paired tag.
+
+                  'Permanent' - flag indicates that a tag is permanent, and
+                  can't be added or deleted from the file.  By default, all
+                  MakerNotes tags are permanent unless otherwise specified.
+
+                  'PrintHex' - specifies that unknown PrintConv values should
+                  be printed in hex (ie. 'Unknown (0x0)')
+
+                  'Priority' - gives the priority of this tag while reading.  If
+                  set to zero, this tag will not override the value of previous
+                  tags with the same name.  If the priority is greater than
+                  zero, this tag won't be overridden by subsequent tags unless
+                  their priority is equal to or greater than this priority.  A
+                  special feature is that Priority 0 tags are automatically
+                  incremented to Priority 1 if they exist in the IFD of the full
+                  resolution image (as determined by SubFileType).
+
+                  'Protected' - bit mask to protect tags from writing:
+                  Bit 0x01 indicates an 'unsafe' tag, which is not set via
+                  SetNewValuesFromFile() unless specified explicitly.
+                  Bit 0x02 indicates a 'protected' tag, which should not be set
+                  directly by the user.
+
+                  'SeparateTable' - set to list PrintConv values in a separate
+                  table in the HTML documentation.  Value is 1 for a table name
+                  of 'Module TagName', or 'TAG' for 'Module TAG', or 'MODULE
+                  TAG' to fully specify the table name.
+
+                  'SetResourceName' - [Photoshop tags only] set to 1 to append
+                  resource name to the extracted value (ie. 'VALUE/#NAME#/').
+                  Also allows resource name to be appended when writing new
+                  values.  May be set to any value other than 1 for a default
+                  resource name to use when writing if an appended name is not
+                  provided.
+
+                  'SubIFD' - used in writing to determine that the tag specifies
+                  an offset to a sub-IFD.  When this flag is set, the Group1
+                  name gives the name of the IFD.
+
+                  'Unknown' - this is an unknown tag (only extracted when the
+                  Unknown option is set).
+
+  RawConv       : Used to convert the Raw value at extraction time (while the
+                  image file is still open, unlike ValueConv and PrintConv below
+                  which are done later only if the value is requested).  May be
+                  a scalar expression using $val (the Raw tag value), $self (the
+                  current ExifTool object) and $tag (the tag name), or a code
+                  reference with $val and $self as arguments.  For Composite
+                  tags, $val is a reference to a hash of component tag names,
+                  and @val may be used to access the Raw values of these tags.
+                  The returned value may be a scalar which is used as the new
+                  Raw value, a scalar reference to a binary data value, a hash
+                  reference for Composite tags, an ARRAY reference for a list of
+                  values, or undefined to indicate that the tag should be
+                  ignored.  Also, RawConv may generate Warning or Error tags,
+                  while ValueConv and PrintConv may not. Note: RawConv should
+                  only be used if necessary (in general, only if the tag may be
+                  ignored).  It is preferable to use ValueConv instead of
+                  RawConv because ValueConv is only executed if the tag value is
+                  requested, while RawConv is executed for all extracted tags.
+
+  ValueConv     : Used to convert the Raw value to a useable form. May be a hash
+                  reference to act as a lookup table, a scalar which is
+                  evaluated as a Perl expression, or a code reference to a
+                  subroutine.  May also be a list reference, in which case the
+                  value is split at whitespace into a list of values and each
+                  value is converted by the associated entry in the ValueConv
+                  list.  If a hash reference is used and the Raw value doesn't
+                  appear as one of the keys, then the converted value is set to
+                  "Unknown (X)", where X is the Raw value (unless a special
+                  'BITMASK' key exists, in which case the hash referenced by
+                  'BITMASK' is used to decode individual value bits).  In an
+                  expression, $self is a reference to the current ExifTool
+                  object, $val is the Raw value, and $tag is the tag name.  The
+                  subroutine takes 2 arguments: the Raw value and a reference to
+                  the current ExifTool object.  The expression or subroutine is
+                  evaluated when and if the tag value is requested (ie. only
+                  after all extraction is complete), so if necessary at this
+                  time the values of all other tags are available via calls to
+                  $self->GetValue("Tag","Raw"). (Note: In theory, types other
+                  than "Raw" may be accessed, but they are slower and may lead
+                  to cyclical dependencies so they should be avoided). When
+                  evaluated, the expression or subroutine returns a scalar for
+                  the converted value, or a scalar reference to a binary data
+                  value (see the 'Binary' flag).  The return value should always
+                  be defined -- use RawConv instead to return undef if it is
+                  necessary to test the value for validity, otherwise an undef
+                  tag may hide a previously defined value when the Duplicates
+                  option is not enabled.  Composite tags which Require or Desire
+                  other tags may access the ValueConv, PrintConv and Raw values
+                  of these tags through the elements of the @val, @prt and @raw
+                  lists respectively (only if there was no RawConv or returned a
+                  hash reference).  For these tags, $val may be used in an
+                  expression to represent $val[0], and the first argument passed
+                  for a code reference is a reference to @val.  If ValueConv is
+                  not specified, the Raw value is not converted.
+
+  PrintConv     : This entry is similar to ValueConv above, except that it is
+                  used to further convert the tag value to a human readable
+                  form.  It can be either a hash lookup, a scalar Perl
+                  expression, a code reference or a list reference.  In this
+                  expression, $self, $val and $tag may be used as with
+                  ValueConv, but if ValueConv was defined then $val is the
+                  ValueConv value instead of the Raw value.  The returned value
+                  should always be defined.  Note that the print conversion is
+                  only done if the PrintConv option is enabled (which it is by
+                  default), and if the result of the ValueConv is not a scalar
+                  reference.  If it is a list reference, then the converted
+                  values are joined by '; ' in the output string.
+
+  RawConvInv    : The inverse of RawConv.  This should only be used in very rare
+                  situations when the raw value can not be predetermined.
+                  Unlike the other inverse conversions which are applied in
+                  SetNewValue(), this conversion is applied in WriteInfo() as
+                  the file is being written.  This is important because it means
+                  that FILE_TYPE and any DataMember tags ocurring before this
+                  tag in the file are available.  Beware that if the return
+                  value is not defined, the tag will be deleted unless there is
+                  specific logic to avoid this (currently, only EXIF and Binary
+                  data directories handle this case).
+
+  ValueConvInv  : The inverse of ValueConv.  Only necessary for Writable tags
+                  when ValueConv is specified (except WriteAlso tags).  Note
+                  that DataMember tags may NOT be used in the inverse
+                  conversions because these conversions are done before the
+                  input file is parsed. Instead, a Condition or RawConvInv must
+                  be used.
+
+  PrintConvInv  : The inverse of PrintConv.  Only necessary if for Writable tags
+                  when PrintConv is specified (unless WriteAlso is used).
+
+  Condition     : If given, specifies scalar which is evaluated as a Perl
+                  expression at extraction time to decide whether the tag is
+                  valid.  If used in a list of alternate tag definitions, the
+                  first list entry with a true condition is taken.  If no
+                  condition exists, then a 'true' condition is assumed.  The
+                  expression may use $self to access the ExifTool object, and
+                  $oldVal to access the previous Raw value of the tag (if it
+                  exists).  The first 48 bytes of the raw data value are
+                  accessible through the reference $valPt for EXIF and Jpeg2000
+                  tags only.  EXIF tags may also reference the format string and
+                  value count through $format and $count.  Note that if the
+                  value is writable and $valPt is used, the tag must have a
+                  Format (unless 'undef' or 'string'), and a Count (unless 1 or
+                  length of the 'undef' or 'string'), so the raw data may be
+                  generated for evaluating the Condition.
+
+  Require       : [Composite tags only] A hash reference specifying the tags
+                  required to calculate the composite tag value.  The hash
+                  values are the names of the required tags, and the keys
+                  specify the indices where the tag values are stored in the
+                  @val list used in the ValueConv and/or PrintConv expression.
+                  The composite value is only calculated if the values for all
+                  Require'd tags are defined.  Require and Desire tag names may
+                  be prefixed by an optional group family 0 or 1 name followed
+                  by a colon.  Case IS significant.  A special feature allows
+                  a scalar tag name to be used instead of the hash reference
+                  when only the 0th tag is defined.  For example, the following
+                  two definitions are equivalent:
+
+                        Require => { 0 => 'XMP:Title' },
+                        Require => 'XMP:Title',
+
+  Desire        : [Composite tags only] This is the same as Require except that
+                  the value is still calculated even if the specified tags don't
+                  exist.  Beware that the elements of @val, @prt and @raw may be
+                  undefined for Desire'd tags.  Both Require and Desire may
+                  exist together, however be sure to specify unique keys for
+                  each tag since they are used as indices into the @val, @prt
+                  and @raw lists common to both Require'd and Desire'd tags.
+
+  Shift         : [Writable tags only] Specifies type of shift to apply if this
+                  value may be shifted.  Set to 'Time' for shifting date/time
+                  tags.
+
+  Writable      : Indicates this tag can be written (or not written if value is
+                  set to zero), and for EXIF-type tables gives format for
+                  writing.  Writable may be set to 1 for MakerNotes information
+                  because the existing format is always used, however providing
+                  a format is desireable because it is used in validating the
+                  value.  For EXIF tables, the Writable flag may be different
+                  than the Format flag, in which case Format is used for
+                  converting the binary value and Writable specifies the format
+                  code written to the EXIF IFD.  For SubDirectories in EXIF
+                  information, this flag is only defined if the SubDirectory is
+                  writable as a block, or if the SubDirectory can not be edited
+                  (in which case Writable is set to 0).
+
+  WriteAlso     : Used for writable tag to specify other tags to write when this
+                  tag is written.  The value is a hash reference.  The hash keys
+                  are the names of the tags to write, and the values are
+                  evaluated to obtain the ValueConv values of each tag (or undef
+                  to delete the tag).  In the eval, $val may be used as the Raw
+                  value of the parent tag.  This will write Protected tags that
+                  aren't directly writable (Protected bit 0x02 set).
+
+  WriteCheck    : If given, specifies a scalar which is evaluated as a Perl
+                  expression for a one-time validatation the value being
+                  written.  The expression has access to 3 variables: $val is
+                  the value to be written, $self is the ExifTool object, and
+                  $tagInfo is the tag information hash reference.  It returns an
+                  error string or undef if the value is good.
+
+  WriteCondition: [Writable EXIF tags only] Specifies a condition to be
+                  evaluated before the tag can be written to a specific file.
+                  The condition may use $self to reference the ExifTool object,
+                  and returns true if it is OK for writing. Unlike WriteCheck
+                  which is done only once when the new value is set, this
+                  condition is evaluated before the information is written in
+                  each file.
+
+  WriteGroup    : [Required for writable EXIF tags] Specifies the IFD where the
+                  information gets written by default.
+
+  OffsetPair    : Used in EXIF table to specify the tagID for the corresponding
+                  offset or length tag.
+
+  DataTag       : Used in EXIF table to specify the tag name of the data
+                  associated with offset/length tags.
+
+  Struct        : [XMP tags only] Used by XMP writer code to specify name of XMP
+                  structure so the PropertyPath can be determined.
+
+  Units         : [MIE tags only] Reference to a list of valid units strings.
+                  The default units are the first item in the list.
+
+  TagID         : [reserved] This entry is used internally by GetTagID() to
+                  cache tag ID numbers for speed.
+
+  Table         : [reserved] Reference to parent tag table.
+
+  PropertyPath  : [reserved] Used internally by XMP writer to save property path
+                  name.
+
+  Module        : [reserved] Used internally to store module name for writable
+                  Composite tags.
+
+  LangCode      : [reserved] Used internally to indicate language code for
+                  alternate language tags (MIE and XMP only)
+
+  SubDirectory {  If it exists, this specifies the start of a new subdirectory.
+                  It contains a collection of variables which specify the type
+                  and location of the subdirectory.  These variables are
+                  described below:
+
+     TagTable   : Specifies the name of the tag table lookup for the new
+                  subdirectory.  If not specified, the parent tag table is used.
+
+     Start      : The offset to the start of the subdirectory relative to the
+                  current Base.  This is a Perl expression which may use
+                  $valuePtr to represent the location of the tag value in the
+                  file, or $val for the value itself.  If not specified, a Start
+                  of '$valuePtr' is assumed.
+
+     OffsetPt   : If specified, this is a Perl expression that gives the
+                  position of a 32-bit word in the current directory that is
+                  added to the Start position to get the position of the new
+                  subdirectory.  The expression should use the position of the
+                  current tag ($valuePtr).
+
+     Base       : This specifies the base offset for all pointers in the
+                  subdirectory.  This need not be specified if the offset is the
+                  same as the current directory, which is normally the case.
+                  May use $start to represent the subdirectory start location
+                  relative to the current base.  If this is defined, the
+                  automatic validation of base offsets is disabled for maker
+                  notes directories.
+
+     EntryBased : Flag indicating that the offsets are based on the indidual
+                  directory entry position, so offsets are incremented by 12
+                  times the corresponding entry index.
+
+     MaxSubdirs : Maximum number of subdirectories specified by the current tag
+                  (if the tag specifies multiple values).  If not specified, the
+                  tag value ($val) is used as-is.  If MaxSubdirs is specified,
+                  then one subdirectory is parsed for each value found up to the
+                  maximum number specified.
+
+     ByteOrder  : Specifies byte ordering if different than than the rest of the
+                  file.  Must be either BigEndian, LittleEndian or Unknown.  If
+                  Unknown is specified, the byte order will be determined from
+                  the directory count (however, this can not be done if OffsetPt
+                  is specified).
+
+     Validate   : If given, specifies Perl expression which is used to validate
+                  the subdirectory data.  The following variables may be used in
+                  the expression: $val (value of the tag), $dirData (reference
+                  to directory data), $subdirStart (offset to subdirectory
+                  start) and $size (size of subdirectory).
+
+     ProcessProc: If given, specifies processing procedure used to decode this
+                  subdirectory data.  This overrides the default procedure
+                  specified by PROCESS_PROC in the tag table.
+
+     DirName    : Name of this subdirectory.  If not specified, the name is
+                  taken from the tag name.  DirName is important because it is
+                  used when writing to compare against names in the directory
+                  map to determine which directories need to be edited.
+
+     FixBase    : Flag set if base offsets should be fixed.  Used to add a
+                  constant to maker notes offsets to fix damage done by some
+                  image editing utilities. (maker notes only)
+
+     FixOffsets : Expression to evaluate for each value pointer to patch
+                  problems with some EXIF maker note offsets.  May access the
+                  following variables: $valuePtr, $valEnd, $size, $tagID and
+                  $wFlag.  May return undef when writing to ignore the entry.
+  }
+
+--------------------------------------------------------------------------------
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/RIFF.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/RIFF.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/RIFF.pm	(revision 20131)
@@ -0,0 +1,618 @@
+#------------------------------------------------------------------------------
+# File:         RIFF.pm
+#
+# Description:  Read RIFF/WAV/AVI meta information
+#
+# Revisions:    09/14/2005 - P. Harvey Created
+#
+# References:   1) http://www.exif.org/Exif2-2.PDF
+#               2) http://www.vlsi.fi/datasheets/vs1011.pdf
+#               3) http://www.music-center.com.br/spec_rif.htm
+#               4) http://www.codeproject.com/audio/wavefiles.asp
+#               5) http://msdn.microsoft.com/archive/en-us/directx9_c/directx/htm/avirifffilereference.asp
+#               6) http://research.microsoft.com/invisible/tests/riff.h.htm
+#               7) http://www.onicos.com/staff/iz/formats/wav.html
+#               8) http://graphics.cs.uni-sb.de/NMM/dist-0.9.1/Docs/Doxygen/html/mmreg_8h-source.html
+#               9) http://developers.videolan.org/vlc/vlc/doc/doxygen/html/codecs_8h-source.html
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::RIFF;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.10';
+
+# type of current stream
+$Image::ExifTool::RIFF::streamType = '';
+
+my %riffEncoding = ( #2
+    0x01 => 'Microsoft PCM',
+    0x02 => 'Microsoft ADPCM',
+    0x03 => 'Microsoft IEEE float',
+    0x04 => 'Compaq VSELP', #4
+    0x05 => 'IBM CVSD', #4
+    0x06 => 'Microsoft a-Law',
+    0x07 => 'Microsoft u-Law',
+    0x08 => 'Microsoft DTS', #4
+    0x09 => 'DRM', #4
+    0x0a => 'WMA 9 Speech', #9
+    0x10 => 'OKI-ADPCM',
+    0x11 => 'Intel IMA/DVI-ADPCM',
+    0x12 => 'Videologic Mediaspace ADPCM', #4
+    0x13 => 'Sierra ADPCM', #4
+    0x14 => 'Antex G.723 ADPCM', #4
+    0x15 => 'DSP Solutions DIGISTD',
+    0x16 => 'DSP Solutions DIGIFIX',
+    0x17 => 'Dialoic OKI ADPCM', #6
+    0x18 => 'Media Vision ADPCM', #6
+    0x19 => 'HP CU', #7
+    0x20 => 'Yamaha ADPCM', #6
+    0x21 => 'SONARC Speech Compression', #6
+    0x22 => 'DSP Group True Speech', #6
+    0x23 => 'Echo Speech Corp.', #6
+    0x24 => 'Virtual Music Audiofile AF36', #6
+    0x25 => 'Audio Processing Tech.', #6
+    0x26 => 'Virtual Music Audiofile AF10', #6
+    0x27 => 'Aculab Prosody 1612', #7
+    0x28 => 'Merging Tech. LRC', #7
+    0x30 => 'Dolby AC2',
+    0x31 => 'Microsoft GSM610',
+    0x32 => 'MSN Audio', #6
+    0x33 => 'Antex ADPCME', #6
+    0x34 => 'Control Resources VQLPC', #6
+    0x35 => 'DSP Solutions DIGIREAL', #6
+    0x36 => 'DSP Solutions DIGIADPCM', #6
+    0x37 => 'Control Resources CR10', #6
+    0x38 => 'Natural MicroSystems VBX ADPCM', #6
+    0x39 => 'Crystal Semiconductor IMA ADPCM', #6
+    0x3a => 'Echo Speech ECHOSC3', #6
+    0x3b => 'Rockwell ADPCM',
+    0x3c => 'Rockwell DIGITALK',
+    0x3d => 'Xebec Multimedia', #6
+    0x40 => 'Antex G.721 ADPCM',
+    0x41 => 'Antex G.728 CELP',
+    0x42 => 'Microsoft MSG723', #7
+    0x45 => 'ITU-T G.726', #9
+    0x50 => 'Microsoft MPEG',
+    0x51 => 'RT23 or PAC', #7
+    0x52 => 'InSoft RT24', #4
+    0x53 => 'InSoft PAC', #4
+    0x55 => 'MP3',
+    0x59 => 'Cirrus', #7
+    0x60 => 'Cirrus Logic', #6
+    0x61 => 'ESS Tech. PCM', #6
+    0x62 => 'Voxware Inc.', #6
+    0x63 => 'Canopus ATRAC', #6
+    0x64 => 'APICOM G.726 ADPCM',
+    0x65 => 'APICOM G.722 ADPCM',
+    0x66 => 'Microsoft DSAT', #6
+    0x67 => 'Micorsoft DSAT DISPLAY', #6
+    0x69 => 'Voxware Byte Aligned', #7
+    0x70 => 'Voxware AC8', #7
+    0x71 => 'Voxware AC10', #7
+    0x72 => 'Voxware AC16', #7
+    0x73 => 'Voxware AC20', #7
+    0x74 => 'Voxware MetaVoice', #7
+    0x75 => 'Voxware MetaSound', #7
+    0x76 => 'Voxware RT29HW', #7
+    0x77 => 'Voxware VR12', #7
+    0x78 => 'Voxware VR18', #7
+    0x79 => 'Voxware TQ40', #7
+    0x80 => 'Soundsoft', #6
+    0x81 => 'Voxware TQ60', #7
+    0x82 => 'Microsoft MSRT24', #7
+    0x83 => 'AT&T G.729A', #7
+    0x84 => 'Motion Pixels MVI MV12', #7
+    0x85 => 'DataFusion G.726', #7
+    0x86 => 'DataFusion GSM610', #7
+    0x88 => 'Iterated Systems Audio', #7
+    0x89 => 'Onlive', #7
+    0x91 => 'Siemens SBC24', #7
+    0x92 => 'Sonic Foundry Dolby AC3 APDIF', #7
+    0x93 => 'MediaSonic G.723', #8
+    0x94 => 'Aculab Prosody 8kbps', #8
+    0x97 => 'ZyXEL ADPCM', #7,
+    0x98 => 'Philips LPCBB', #7
+    0x99 => 'Studer Professional Audio Packed', #7
+    0xa0 => 'Malden PhonyTalk', #8
+    0x100 => 'Rhetorex ADPCM', #6
+    0x101 => 'IBM u-Law', #3
+    0x102 => 'IBM a-Law', #3
+    0x103 => 'IBM ADPCM', #3
+    0x111 => 'Vivo G.723', #7
+    0x112 => 'Vivo Siren', #7
+    0x123 => 'Digital G.723', #7
+    0x125 => 'Sanyo LD ADPCM', #8
+    0x130 => 'Sipro Lab ACEPLNET', #8
+    0x131 => 'Sipro Lab ACELP4800', #8
+    0x132 => 'Sipro Lab ACELP8V3', #8
+    0x133 => 'Sipro Lab G.729', #8
+    0x134 => 'Sipro Lab G.729A', #8
+    0x135 => 'Sipro Lab Kelvin', #8
+    0x140 => 'Dictaphone G.726 ADPCM', #8
+    0x150 => 'Qualcomm PureVoice', #8
+    0x151 => 'Qualcomm HalfRate', #8
+    0x155 => 'Ring Zero Systems TUBGSM', #8
+    0x160 => 'Microsoft Audio1', #8
+    0x200 => 'Creative Labs ADPCM', #6
+    0x202 => 'Creative Labs FASTSPEECH8', #6
+    0x203 => 'Creative Labs FASTSPEECH10', #6
+    0x210 => 'UHER ADPCM', #8
+    0x220 => 'Quarterdeck Corp.', #6
+    0x230 => 'I-Link VC', #8
+    0x240 => 'Aureal Semiconductor Raw Sport', #8
+    0x250 => 'Interactive Products HSX', #8
+    0x251 => 'Interactive Products RPELP', #8
+    0x260 => 'Consistent CS2', #8
+    0x270 => 'Sony SCX', #8
+    0x300 => 'Fujitsu FM TOWNS SND', #6
+    0x400 => 'Brooktree Digital', #6
+    0x450 => 'QDesign Music', #8
+    0x680 => 'AT&T VME VMPCM', #7
+    0x681 => 'AT&T TCP', #8
+    0x1000 => 'Olivetti GSM', #6
+    0x1001 => 'Olivetti ADPCM', #6
+    0x1002 => 'Olivetti CELP', #6
+    0x1003 => 'Olivetti SBC', #6
+    0x1004 => 'Olivetti OPR', #6
+    0x1100 => 'Lernout & Hauspie', #6
+    0x1400 => 'Norris Comm. Inc.', #6
+    0x1401 => 'ISIAudio', #7
+    0x1500 => 'AT&T Soundspace Music Compression', #7
+    0x2000 => 'FAST Multimedia DVM', #7
+    0xfffe => 'Extensible', #7
+    0xffff => 'Development', #4
+);
+
+# RIFF info
+%Image::ExifTool::RIFF::Main = (
+    PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks,
+    NOTES => q{
+        Windows WAV and AVI files are RIFF format files.  Meta information embedded
+        in two types of RIFF C<LIST> chunks: C<INFO> and C<exif>.  As well, some
+        information about the audio content is extracted from the C<fmt > chunk.
+    },
+   'fmt ' => {
+        Name => 'AudioFormat',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::AudioFormat' },
+    },
+    LIST_INFO => {
+        Name => 'Info',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Info' },
+    },
+    LIST_exif => {
+        Name => 'Exif',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Exif' },
+    },
+    LIST_hdrl => { # AVI header LIST chunk
+        Name => 'Hdrl',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Hdrl' },
+    },
+);
+
+# Format and Audio Stream Format chunk data
+%Image::ExifTool::RIFF::AudioFormat = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Audio' },
+    FORMAT => 'int16u',
+    0 => {
+        Name => 'Encoding',
+        PrintHex => 1,
+        PrintConv => \%riffEncoding,
+    },
+    1 => 'NumChannels',
+    2 => {
+        Name => 'SampleRate',
+        Format => 'int32u',
+    },
+    4 => {
+        Name => 'AvgBytesPerSec',
+        Format => 'int32u',
+    },
+   # uninteresting
+   # 6 => 'BlockAlignment',
+    7 => 'BitsPerSample',
+);
+
+# Sub chunks of INFO LIST chunk
+%Image::ExifTool::RIFF::Info = (
+    PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks,
+    GROUPS => { 2 => 'Audio' },
+    IARL => 'ArchivalLocation',
+    IART => { Name => 'Artist',    Groups => { 2 => 'Author' } },
+    ICMS => 'Commissioned',
+    ICMT => 'Comment',
+    ICOP => { Name => 'Copyright', Groups => { 2 => 'Author' } },
+    ICRD => {
+        Name => 'DateCreated',
+        Groups => { 2 => 'Time' },
+        ValueConv => '$_=$val; s/-/:/g; s/\0.*//s; $_',
+    },
+    ICRP => 'Cropped',
+    IDIM => 'Dimensions',
+    IDPI => 'DotsPerInch',
+    IENG => 'Engineer',
+    IGNR => 'Genre',
+    IKEY => 'Keywords',
+    ILGT => 'Lightness',
+    IMED => 'Medium',
+    INAM => 'Title',
+    IPLT => 'NumColors',
+    IPRD => 'Product',
+    ISBJ => 'Subject',
+    ISFT => 'Software',
+    ISHP => 'Sharpness',
+    ISRC => 'Source',
+    ISRF => 'SourceForm',
+    ITCH => 'Technician',
+);
+
+# Sub chunks of EXIF LIST chunk
+%Image::ExifTool::RIFF::Exif = (
+    PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks,
+    GROUPS => { 2 => 'Audio' },
+    ever => 'ExifVersion',
+    erel => 'RelatedImageFile',
+    etim => { Name => 'TimeCreated', Groups => { 2 => 'Time' } },
+    ecor => { Name => 'Make',        Groups => { 2 => 'Camera' } },
+    emdl => { Name => 'Model',       Groups => { 2 => 'Camera' } },
+    emnt => { Name => 'MakerNotes',  Binary => 1 },
+    eucm => {
+        Name => 'UserComment',
+        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+    },
+);
+
+# Sub chunks of hdrl LIST chunk
+%Image::ExifTool::RIFF::Hdrl = (
+    PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks,
+    GROUPS => { 2 => 'Image' },
+    avih => {
+        Name => 'AVIHeader',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::AVIHeader' },
+    },
+    IDIT => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Groups => { 2 => 'Time' },
+        ValueConv => 'Image::ExifTool::RIFF::ConvertRIFFDate($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    ISMP => 'TimeCode',
+    LIST_strl => {
+        Name => 'Stream',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Stream' },
+    },
+);
+
+%Image::ExifTool::RIFF::AVIHeader = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 0,
+    0 => {
+        Name => 'FrameRate',
+        ValueConv => '$val ? 1e6 / $val : undef',
+        PrintConv => 'int($val * 1000 + 0.5) / 1000',
+    },
+    1 => {
+        Name => 'MaxDataRate',
+        PrintConv => 'sprintf("%.4g kB/s",$val / 1024)',
+    },
+  # 2 => 'PaddingGranularity',
+  # 3 => 'Flags',
+    4 => 'FrameCount',
+  # 5 => 'InitialFrames',
+    6 => 'StreamCount',
+  # 7 => 'SuggestedBufferSize',
+    8 => 'ImageWidth',
+    9 => 'ImageHeight',
+);
+
+%Image::ExifTool::RIFF::Stream = (
+    PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks,
+    GROUPS => { 2 => 'Image' },
+    strh => {
+        Name => 'StreamHeader',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::StreamHeader' },
+    },
+    strn => 'StreamName',
+    strd => { #PH
+        Name => 'StreamData',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::StreamData' },
+    },
+    strf => [
+        {
+            Name => 'AudioFormat',
+            Condition => '$Image::ExifTool::RIFF::streamType eq "auds"',
+            SubDirectory => { TagTable => 'Image::ExifTool::RIFF::AudioFormat' },
+        },
+        {
+            Name => 'VideoFormat',
+            Condition => '$Image::ExifTool::RIFF::streamType eq "vids"',
+            SubDirectory => { TagTable => 'Image::ExifTool::BMP::Main' },
+        },
+    ],
+);
+
+%Image::ExifTool::RIFF::StreamHeader = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 0,
+    0 => {
+        Name => 'StreamType',
+        Format => 'string[4]',
+        RawConv => '$Image::ExifTool::RIFF::streamType = $val',
+        PrintConv => {
+            auds => 'Audio',
+            mids => 'MIDI',
+            txts => 'Text',
+            vids => 'Video',
+        },
+    },
+    1 => {
+        Name => 'Codec',
+        Format => 'string[4]',
+    },
+  # 2 => 'StreamFlags',
+  # 3 => 'StreamPriority',
+  # 3.5 => 'Language',
+  # 4 => 'InitialFrames',
+  # 5 => 'Scale',
+  # 6 => 'Rate',
+  # 7 => 'Start',
+  # 8 => 'Length',
+  # 9 => 'SuggestedBufferSize',
+    10 => 'Quality',
+    11 => {
+        Name => 'SampleSize',
+        PrintConv => '$val ? "$val byte" . ($val==1 ? "" : "s") : "Variable"',
+    },
+  # 12 => { Name => 'Frame', Format => 'int16u[4]' },
+);
+
+%Image::ExifTool::RIFF::StreamData = ( #PH
+    PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessStreamData,
+    GROUPS => { 2 => 'Video' },
+    NOTES => 'This chunk contains EXIF information in FujiFilm F30 AVI files.',
+    AVIF => {
+        Name => 'AVIF',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            DirName => 'IFD0',
+            Start => 8,
+            ByteOrder => 'II',
+        },
+    },
+);
+
+# RIFF composite tags
+%Image::ExifTool::RIFF::Composite = (
+    Duration => {
+        Require => {
+            0 => 'FrameRate',
+            1 => 'FrameCount',
+        },
+        ValueConv => '$val[0] ? $val[1] / $val[0] : undef',
+        PrintConv => 'sprintf("%.2fs",$val)',
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::RIFF');
+
+
+#------------------------------------------------------------------------------
+# Convert RIFF date to EXIF format
+my %monthNum = (
+    Jan=>1, Feb=>2, Mar=>3, Apr=>4, May=>5, Jun=>6,
+    Jul=>7, Aug=>8, Sep=>9, Oct=>10,Nov=>11,Dec=>12
+);
+sub ConvertRIFFDate($)
+{
+    my $val = shift;
+    my @part = split ' ', $val;
+    my $mon;
+    if (@part >= 5 and $mon = $monthNum{ucfirst(lc($part[1]))}) {
+        # the standard AVI date format (ie. "Mon Mar 10 15:04:43 2003")
+        $val = sprintf("%.4d:%.2d:%.2d %s", $part[4],
+                       $mon, $part[2], $part[3]);
+    } elsif ($val =~ m{(\d{4})/\s*(\d+)/\s*(\d+)/?\s+(\d+):\s*(\d+)\s*(P?)}) {
+        # but the Casio QV-3EX writes dates like "2001/ 1/27  1:42PM",
+        # and the Casio EX-Z30 writes "2005/11/28/ 09:19"... doh!
+        $val = sprintf("%.4d:%.2d:%.2d %.2d:%.2d:00",$1,$2,$3,$4+($6?12:0),$5);
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Process stream data
+# Inputs: 0) ExifTool object ref, 1) dirInfo reference, 2) tag table ref
+# Returns: 1 on success
+sub ProcessStreamData($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $start = $$dirInfo{DirStart};
+    my $size = $$dirInfo{DirLen};
+    return 0 if $size < 4;
+    if ($exifTool->Options('Verbose')) {
+        $exifTool->VerboseDir($$dirInfo{DirName}, 0, $size);
+    }
+    my $tag = substr($$dataPt, $start, 4);
+    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+    my $subdir = $$tagInfo{SubDirectory};
+    if ($subdir) {
+        my $offset = $$subdir{Start} || 0;
+        my $baseShift = $$dirInfo{DataPos} + $$dirInfo{DirStart} + $offset;
+        my %subdirInfo = (
+            DataPt  => $dataPt,
+            DataPos => $$dirInfo{DataPos} - $baseShift,
+            Base    => ($$dirInfo{Base} || 0) + $baseShift,
+            DataLen => $$dirInfo{DataLen},
+            DirStart=> $$dirInfo{DirStart} + $offset,
+            DirLen  => $$dirInfo{DirLen} - $offset,
+            DirName => $$subdir{DirName},
+            Parent  => $$dirInfo{DirName},
+        );
+        # (we could set FIRST_EXIF_POS to $subdirInfo{Base} here to make
+        #  htmlDump offsets relative to EXIF base if we wanted...)
+        my $subTable = GetTagTable($$subdir{TagTable});
+        $exifTool->ProcessDirectory(\%subdirInfo, $subTable);
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process RIFF chunks
+# Inputs: 0) ExifTool object reference, 1) directory information reference
+#         2) tag table reference
+# Returns: 1 on success
+sub ProcessChunks($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $start = $$dirInfo{DirStart};
+    my $size = $$dirInfo{DirLen};
+    my $end = $start + $size;
+
+    if ($exifTool->Options('Verbose')) {
+        $exifTool->VerboseDir($$dirInfo{DirName}, 0, $size);
+    }
+    while ($start + 8 < $end) {
+        my $tag = substr($$dataPt, $start, 4);
+        my $len = Get32u($dataPt, $start + 4);
+        $start += 8;
+        if ($start + $len > $end) {
+            $exifTool->Warn("Bad $tag chunk");
+            return 0;
+        }
+        if ($tag eq 'LIST' and $len >= 4) {
+            $tag .= '_' . substr($$dataPt, $start, 4);
+            $len -= 4;
+            $start += 4;
+        }
+        $exifTool->HandleTag($tagTablePtr, $tag, undef,
+            DataPt => $dataPt,
+            DataPos => $$dirInfo{DataPos},
+            Start => $start,
+            Size => $len,
+        );
+        ++$len if $len & 0x01;  # must account for padding if odd number of bytes
+        $start += $len;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Extract information from a RIFF file
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid RIFF file
+sub ProcessRIFF($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my ($buff, $err);
+    my %types = ( 'WAVE' => 'WAV', 'AVI ' => 'AVI' );
+
+    # verify this is a valid RIFF file
+    return 0 unless $raf->Read($buff, 12) == 12;
+    return 0 unless $buff =~ /^RIFF....(.{4})/s;
+    $exifTool->SetFileType($types{$1}); # set type to 'WAV', 'AVI' or 'RIFF'
+    $Image::ExifTool::RIFF::streamType = '';    # initialize stream type
+    SetByteOrder('II');
+    my $tagTablePtr = GetTagTable('Image::ExifTool::RIFF::Main');
+    my $pos = 12;
+#
+# Read chunks in RIFF image until we get to the 'data' chunk
+#
+    for (;;) {
+        $raf->Read($buff, 8) == 8 or $err=1, last;
+        $pos += 8;
+        my ($tag, $len) = unpack('a4V', $buff);
+        # special case: construct new tag name from specific LIST type
+        if ($tag eq 'LIST') {
+            $raf->Read($buff, 4) == 4 or $err=1, last;
+            $pos += 4;
+            $tag .= "_$buff";
+            $len -= 4;  # already read 4 bytes (the LIST type)
+        }
+        $exifTool->VPrint(0, "RIFF '$tag' chunk ($len bytes of data):\n");
+        # stop when we hit the audio data or AVI index or AVI movie data
+        if ($tag eq 'data' or $tag eq 'idx1' or $tag eq 'LIST_movi') {
+            $exifTool->VPrint(0, "(end of parsing)\n");
+            last;
+        }
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        # RIFF chunks are padded to an even number of bytes
+        my $len2 = $len + ($len & 0x01);
+        if ($tagInfo and $$tagInfo{SubDirectory}) {
+            $raf->Read($buff, $len2) == $len2 or $err=1, last;
+            my %dirInfo = (
+                DataPt => \$buff,
+                DataPos => $pos,
+                DirStart => 0,
+                DirLen => $len,
+            );
+            my $tagTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        } else {
+            $raf->Seek($len2, 1) or $err=1, last;
+        }
+        $pos += $len2;
+    }
+    $err and $exifTool->Warn('Error reading RIFF file (corrupted?)');
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::RIFF - Read RIFF/WAV/AVI meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to extract
+information from RIFF-based (Resource Interchange File Format) files,
+including Windows WAV audio and AVI video files.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.exif.org/Exif2-2.PDF>
+
+=item L<http://www.vlsi.fi/datasheets/vs1011.pdf>
+
+=item L<http://www.music-center.com.br/spec_rif.htm>
+
+=item L<http://www.codeproject.com/audio/wavefiles.asp>
+
+=item L<http://msdn.microsoft.com/archive/en-us/directx9_c/directx/htm/avirifffilereference.asp>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/RIFF Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Real.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Real.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Real.pm	(revision 20131)
@@ -0,0 +1,731 @@
+#------------------------------------------------------------------------------
+# File:         Real.pm
+#
+# Description:  Read Real audio/video meta information
+#
+# Revisions:    05/16/2006 - P. Harvey Created
+#
+# References:   1) http://www.getid3.org/
+#               2) https://common.helixcommunity.org/nonav/2003/HCS_SDK_r5/htmfiles/rmff.htm
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Real;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Canon;
+
+$VERSION = '1.01';
+
+sub ProcessRealMeta($$$);
+sub ProcessRealProperties($$$);
+
+# Real property types (ref PH)
+my %propertyType = (
+    0 => 'int32u',
+    2 => 'string',
+);
+
+# Real Metadata property types
+my %metadataFormat = (
+    1 => 'string',  # text
+    2 => 'string',  # text list
+    3 => 'flag',    # 1 or 4 byte integer
+    4 => 'int32u',  # 4-byte integer
+    5 => 'undef',   # binary data
+    6 => 'string',  # URL
+    7 => 'string',  # date
+    8 => 'string',  # file name
+    9 =>  undef,    # grouping
+    10 => undef,    # reference
+);
+
+# Real Metadata property flag bit descriptions
+my %metadataFlag = (
+    0 => 'Read Only',
+    1 => 'Private',
+    2 => 'Type Descriptor',
+);
+
+
+# tags used in RealMedia (RM, RV and RMVB) files
+%Image::ExifTool::Real::Media = (
+    GROUPS => { 2 => 'Video' },
+    NOTES => q{
+        These B<Tag ID>'s are Chunk ID's used in RealMedia and RealVideo (RM, RV and
+        RMVB) files.
+    },
+    CONT => { SubDirectory => { TagTable => 'Image::ExifTool::Real::ContentDescr' } },
+    MDPR => { SubDirectory => { TagTable => 'Image::ExifTool::Real::MediaProps' } },
+    PROP => { SubDirectory => { TagTable => 'Image::ExifTool::Real::Properties' } },
+    RJMD => { SubDirectory => { TagTable => 'Image::ExifTool::Real::Metadata' } },
+);
+
+# pseudo-tags used in RealAudio (RA) files
+%Image::ExifTool::Real::Audio = (
+    GROUPS => { 2 => 'Audio' },
+    NOTES => q{
+        Tags in the following table reference information extracted from various
+        versions of RealAudio (RA) files.
+    },
+    '.ra3' => { Name => 'RA3', SubDirectory => { TagTable => 'Image::ExifTool::Real::AudioV3' } },
+    '.ra4' => { Name => 'RA4', SubDirectory => { TagTable => 'Image::ExifTool::Real::AudioV4' } },
+    '.ra5' => { Name => 'RA5', SubDirectory => { TagTable => 'Image::ExifTool::Real::AudioV5' } },
+);
+
+# pseudo-tags used in RealMedia Metafiles and RealMedia Plug-in Metafiles (RAM and RPM)
+%Image::ExifTool::Real::Metafile = (
+    GROUPS => { 2 => 'Video' },
+    NOTES => q{
+        Tags representing information extracted from Real Audio Metafile and
+        RealMedia Plug-in Metafile (RAM and RPM) files.
+    },
+    txt => 'Text',
+    url => 'URL',
+);
+
+%Image::ExifTool::Real::Properties = (
+    GROUPS => { 1 => 'Real-PROP', 2 => 'Video' },
+    PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData,
+    FORMAT => 'int32u',
+    0  => 'MaxBitRate',
+    1  => 'AvgBitRate',
+    2  => 'MaxPacketSize',
+    3  => 'AvgPacketSize',
+    4  => 'NumPackets',
+    5 => { Name => 'Duration',      ValueConv => '$val / 1000' },
+    6 => { Name => 'Preroll',       ValueConv => '$val / 1000' },
+    7 => { Name => 'IndexOffset',   Unknown => 1 },
+    8 => { Name => 'DataOffset',    Unknown => 1 },
+    9 => { Name => 'NumStreams',    Format => 'int16u' },
+    10 => {
+        Name => 'Flags',
+        Format => 'int16u',
+        PrintConv => { BITMASK => {
+            0 => 'Allow Recording',
+            1 => 'Perfect Play',
+            2 => 'Live',
+            3 => 'Allow Download', #PH (from rmeditor dump)
+        } },
+    },
+);
+
+%Image::ExifTool::Real::MediaProps = (
+    GROUPS => { 1 => 'Real-MDPR', 2 => 'Video' },
+    PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData,
+    FORMAT => 'int32u',
+    PRIORITY => 0,  # first stream takes priority
+    0  => { Name => 'StreamNumber',  Format => 'int16u' },
+    1  => { Name => 'StreamMaxBitRate' },
+    2  => { Name => 'StreamAvgBitRate' },
+    3  => { Name => 'StreamMaxPacketSize' },
+    4  => { Name => 'StreamAvgPacketSize' },
+    5  => { Name => 'StreamStartTime' },
+    6  => { Name => 'StreamPreroll',       ValueConv => '$val / 1000' },
+    7  => { Name => 'StreamDuration',      FValueConv => '$val / 1000' },
+    8  => { Name => 'StreamNameLen', Format => 'int8u', Unknown => 1 },
+    9  => { Name => 'StreamName',    Format => 'string[$val{8}]' },
+    10 => { Name => 'StreamMimeLen', Format => 'int8u', Unknown => 1 },
+    11 => {
+        Name => 'StreamMimeType',
+        Format => 'string[$val{10}]',
+        RawConv => '$self->{RealStreamMime} = $val',
+    },
+    12 => { Name => 'FileInfoLen', Unknown => 1 },
+    13 => {
+        Name => 'FileInfoLen2',
+        # if this condition fails, subsequent tags will not be processed
+        Condition => '$self->{RealStreamMime} eq "logical-fileinfo"',
+        Unknown => 1,
+    },
+    14 => {
+        Name => 'FileInfoVersion',
+        Format => 'int16u',
+    },
+    15 => {
+        Name => 'PhysicalStreams',
+        Format => 'int16u',
+        Unknown => 1,
+    },
+    16 => {
+        Name => 'PhysicalStreamNumbers',
+        Format => 'int16u[$val{15}]',
+        Unknown => 1,
+    },
+    17 => {
+        Name => 'DataOffsets',
+        Format => 'int32u[$val{15}]',
+        Unknown => 1,
+    },
+    18 => {
+        Name => 'NumRules',
+        Format => 'int16u',
+        Unknown => 1,
+    },
+    19 => {
+        Name => 'PhysicalStreamNumberMap',
+        Format => 'int16u[$val{18}]',
+        Unknown => 1,
+    },
+    20 => {
+        Name => 'NumProperties',
+        Format => 'int16u',
+        Unknown => 1,
+    },
+    21 => {
+        Name => 'FileInfoProperties',
+        Format => 'undef[$val{13}-$val{15}*6-$val{18}*2-12]',
+        SubDirectory => { TagTable => 'Image::ExifTool::Real::FileInfo' },
+    },
+);
+
+# Observed FileInfo properties (ref PH)
+%Image::ExifTool::Real::FileInfo = (
+    GROUPS => { 1 => 'Real-MDPR', 2 => 'Video' },
+    PROCESS_PROC => \&ProcessRealProperties,
+    NOTES => q{
+        The following tags have been observed in the FileInfo properties, but any
+        other existing information will also be extracted.
+    },
+    Indexable       => { PrintConv => { 0 => 'False', 1 => 'True' } },
+    Keywords        => { },
+    Description     => { },
+   'File ID'        => { Name => 'FileID' },
+   'Content Rating' => {
+        Name => 'ContentRating',
+        PrintConv => {
+            0 => 'No Rating',
+            1 => 'All Ages',
+            2 => 'Older Children',
+            3 => 'Younger Teens',
+            4 => 'Older Teens',
+            5 => 'Adult Supervision Recommended',
+            6 => 'Adults Only',
+        },
+    },
+    Audiences       => { },
+    audioMode       => { Name => 'AudioMode' },
+   'Creation Date'  => {
+        Name => 'CreateDate',
+        Groups => { 2 => 'Time' },
+        ValueConv => q{
+            $val =~ m{(\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+)} ?
+            sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%.2d",$3,$2,$1,$4,$5,$6) : $val
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+   'Generated By'   => { Name => 'Software' },
+   'Modification Date' => {
+        Name => 'ModifyDate',
+        Groups => { 2 => 'Time' },
+        ValueConv => q{
+            $val =~ m{(\d+)/(\d+)/(\d+)\s+(\d+):(\d+):(\d+)} ?
+            sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%.2d",$3,$2,$1,$4,$5,$6) : $val
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+   'Target Audiences' => { Name => 'TargetAudiences' },
+   'Audio Format'   => { Name => 'AudioFormat' },
+   'Video Quality'  => { Name => 'VideoQuality' },
+    videoMode       => { Name => 'VideoMode' },
+);
+
+%Image::ExifTool::Real::ContentDescr = (
+    GROUPS => { 1 => 'Real-CONT', 2 => 'Video' },
+    PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData,
+    FORMAT => 'int16u',
+    0 => { Name => 'TitleLen',      Unknown => 1 },
+    1 => { Name => 'Title',         Format => 'string[$val{0}]' },
+    2 => { Name => 'AuthorLen',     Unknown => 1 },
+    3 => { Name => 'Author',        Format => 'string[$val{2}]', Groups => { 2 => 'Author' } },
+    4 => { Name => 'CopyrightLen',  Unknown => 1 },
+    5 => { Name => 'Copyright',     Format => 'string[$val{4}]', Groups => { 2 => 'Author' } },
+    6 => { Name => 'CommentLen',    Unknown => 1 },
+    7 => { Name => 'Comment',       Format => 'string[$val{6}]' },
+);
+
+# Real RJMD meta information (ref PH)
+%Image::ExifTool::Real::Metadata = (
+    GROUPS => { 1 => 'Real-RJMD', 2 => 'Video' },
+    PROCESS_PROC => \&ProcessRealMeta,
+    NOTES => q{
+        The tags below represent information which has been observed in the Real
+        Metadata format, but ExifTool will extract any information it finds in this
+        format.  (As far as I can tell from the referenced documentation, string
+        values should be plain text, but this is not the case for the only sample
+        file I have been able to obtain containing this information.  These tags
+        could also be split into separate sub-directories, but this will wait until
+        I have better documentation or a more complete set of samples.)
+    },
+   'Album/Name'     => 'AlbumName',
+   'Track/Category' => 'TrackCategory',
+   'Track/Comments' => 'TrackComments',
+   'Track/Lyrics'   => 'TrackLyrics',
+);
+
+%Image::ExifTool::Real::AudioV3 = (
+    GROUPS => { 1 => 'Real-RA3', 2 => 'Audio' },
+    PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData,
+    FORMAT => 'int8u',
+    0  => { Name => 'Channels',       Format => 'int16u' },
+    1  => { Name => 'Unknown',        Format => 'int16u[3]', Unknown => 1 },
+    2  => { Name => 'BytesPerMinute', Format => 'int16u' },
+    3  => { Name => 'AudioBytes',     Format => 'int32u' },
+    4  => { Name => 'TitleLen',       Unknown => 1 },
+    5  => { Name => 'Title',          Format => 'string[$val{4}]' },
+    6  => { Name => 'ArtistLen',      Unknown => 1 },
+    7  => { Name => 'Artist',         Format => 'string[$val{6}]', Groups => { 2 => 'Author' } },
+    8  => { Name => 'CopyrightLen',   Unknown => 1 },
+    9  => { Name => 'Copyright',      Format => 'string[$val{8}]', Groups => { 2 => 'Author' } },
+    10 => { Name => 'CommentLen',     Unknown => 1 },
+    11 => { Name => 'Comment',        Format => 'string[$val{10}]' },
+);
+
+%Image::ExifTool::Real::AudioV4 = (
+    GROUPS => { 1 => 'Real-RA4', 2 => 'Audio' },
+    PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData,
+    FORMAT => 'int16u',
+    0  => { Name => 'FourCC1',        Format => 'undef[4]', Unknown => 1 },
+    1  => { Name => 'AudioFileSize',  Format => 'int32u',   Unknown => 1 },
+    2  => { Name => 'Version2',       Unknown => 1 },
+    3  => { Name => 'HeaderSize',     Format => 'int32u',   Unknown => 1 },
+    4  => { Name => 'CodecFlavorID',  Unknown => 1 },
+    5  => { Name => 'CodedFrameSize', Format => 'int32u',   Unknown => 1 },
+    6  => { Name => 'AudioBytes',     Format => 'int32u' },
+    7  => { Name => 'BytesPerMinute', Format => 'int32u' },
+    8  => { Name => 'Unknown',        Format => 'int32u',   Unknown => 1 },
+    9  => { Name => 'SubPacketH',     Unknown => 1 },
+    10 => 'AudioFrameSize',
+    11 => { Name => 'SubPacketSize',  Unknown => 1 },
+    12 => { Name => 'Unknown',        Unknown => 1 },
+    13 => 'SampleRate',
+    14 => { Name => 'Unknown',        Unknown => 1 },
+    15 => 'BitsPerSample',
+    16 => 'Channels',
+    17 => { Name => 'FourCC2Len',     Format => 'int8u',    Unknown => 1 },
+    18 => { Name => 'FourCC2',        Format => 'undef[4]', Unknown => 1 },
+    19 => { Name => 'FourCC3Len',     Format => 'int8u',    Unknown => 1 },
+    20 => { Name => 'FourCC3',        Format => 'undef[4]', Unknown => 1 },
+    21 => { Name => 'Unknown',        Format => 'int8u',    Unknown => 1 },
+    22 => { Name => 'Unknown',        Unknown => 1 },
+    23 => { Name => 'TitleLen',       Format => 'int8u',    Unknown => 1 },
+    24 => { Name => 'Title',          Format => 'string[$val{23}]' },
+    25 => { Name => 'ArtistLen',      Format => 'int8u',    Unknown => 1 },
+    26 => { Name => 'Artist',         Format => 'string[$val{25}]', Groups => { 2 => 'Author' } },
+    27 => { Name => 'CopyrightLen',   Format => 'int8u',    Unknown => 1 },
+    28 => { Name => 'Copyright',      Format => 'string[$val{27}]', Groups => { 2 => 'Author' } },
+    29 => { Name => 'CommentLen',     Format => 'int8u',    Unknown => 1 },
+    30 => { Name => 'Comment',        Format => 'string[$val{29}]' },
+);
+
+%Image::ExifTool::Real::AudioV5 = (
+    GROUPS => { 1 => 'Real-RA5', 2 => 'Audio' },
+    PROCESS_PROC => \&Image::ExifTool::Canon::ProcessSerialData,
+    FORMAT => 'int16u',
+    0  => { Name => 'FourCC1',        Format => 'undef[4]', Unknown => 1 },
+    1  => { Name => 'AudioFileSize',  Format => 'int32u',   Unknown => 1 },
+    2  => { Name => 'Version2',       Unknown => 1 },
+    3  => { Name => 'HeaderSize',     Format => 'int32u',   Unknown => 1 },
+    4  => { Name => 'CodecFlavorID',  Unknown => 1 },
+    5  => { Name => 'CodedFrameSize', Format => 'int32u',   Unknown => 1 },
+    6  => { Name => 'AudioBytes',     Format => 'int32u' },
+    7  => { Name => 'BytesPerMinute', Format => 'int32u' },
+    8  => { Name => 'Unknown',        Format => 'int32u',   Unknown => 1 },
+    9  => { Name => 'SubPacketH',     Unknown => 1 },
+    10 => { Name => 'FrameSize',      Unknown => 1 },
+    11 => { Name => 'SubPacketSize',  Unknown => 1 },
+    12 => 'SampleRate',
+    13 => { Name => 'SampleRate2',    Unknown => 1 },
+    14 => { Name => 'BitsPerSample',  Format => 'int32u' },
+    15 => 'Channels',
+    16 => { Name => 'Genr',           Format => 'int32u',   Unknown => 1 },
+    17 => { Name => 'FourCC3',        Format => 'undef[4]', Unknown => 1 },
+);
+
+#------------------------------------------------------------------------------
+# Process Real NameValueProperties
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessRealProperties($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirLen = $$dirInfo{DirLen};
+    my $pos = $$dirInfo{DirStart};
+    my $verbose = $exifTool->Options('Verbose');
+
+    $verbose and $exifTool->VerboseDir('RealProperties', undef, $dirLen);
+
+    while ($pos + 6 <= $dirLen) {
+
+        # get property size and version
+        my ($size, $vers) = unpack("x${pos}Nn", $$dataPt);
+        last if $size < 6;
+        unless ($vers == 0) {
+            $pos += $size;
+            next;
+        }
+        $pos += 6;
+
+        my $tagLen = unpack("x${pos}C", $$dataPt);
+        ++$pos;
+
+        last if $pos + $tagLen > $dirLen;
+        my $tag = substr($$dataPt, $pos, $tagLen);
+        $pos += $tagLen;
+
+        last if $pos + 6 > $dirLen;
+        my ($type, $valLen) = unpack("x${pos}Nn", $$dataPt);
+        $pos += 6;
+
+        last if $pos + $valLen > $dirLen;
+        my $format = $propertyType{$type} || 'undef';
+        my $count = int($valLen / Image::ExifTool::FormatSize($format));
+        my $val = ReadValue($dataPt, $pos, $format, $count, $dirLen-$pos);
+
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        unless ($tagInfo) {
+            my $tagName;
+            ($tagName = $tag) =~ s/\s+//g;
+            next unless $tagName =~ /^\w+$/;    # ignore crazy names
+            $tagInfo = { Name => ucfirst($tagName) };
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        if ($verbose) {
+            $exifTool->VerboseInfo($tag, $tagInfo,
+                Table  => $tagTablePtr,
+                Value  => $val,
+                DataPt => $dataPt,
+                Size   => $valLen,
+                Start  => $pos,
+                Addr   => $pos + $$dirInfo{DataPos},
+                Format => $format,
+                Count  => $count,
+            );
+        }
+        $exifTool->FoundTag($tagInfo, $val);
+        $pos += $valLen;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process Real metadata properties
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessRealMeta($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{DataPos};
+    my $pos = $$dirInfo{DirStart};
+    my $dirEnd = $pos + $$dirInfo{DirLen};
+    my $verbose = $exifTool->Options('Verbose');
+    my $prefix = $$dirInfo{Prefix} || '';
+    $prefix and $prefix .= '/';
+
+    $verbose and $exifTool->VerboseDir('RealMetadata', undef, $$dirInfo{DirLen});
+
+    for (;;) {
+        last if $pos + 28 > $dirEnd;
+        # extract fixed-position metadata structure members
+        my ($size, $type, $flags, $valuePos, $subPropPos, $numSubProps, $nameLen)
+            = unpack("x${pos}N7", $$dataPt);
+        # make pointers relative to data start
+        $valuePos += $pos;
+        $subPropPos += $pos;
+        # validate what we have read so far
+        last if $pos + $size > $dirEnd;
+        last if $pos + 28 + $nameLen > $dirEnd;
+        last if $valuePos <  $pos + 28 + $nameLen;
+        last if $valuePos + 4 > $dirEnd;
+        my $tag = substr($$dataPt, $pos + 28, $nameLen);
+        $tag =~ s/\0.*//s;  # truncate at null
+        $tag = $prefix . $tag;
+        my $valueLen = unpack("x${valuePos}N", $$dataPt);
+        $valuePos += 4; # point at value itself
+        last if $valuePos + $valueLen > $dirEnd;
+
+        my $format = $metadataFormat{$type};
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        unless ($tagInfo) {
+            my $tagName = $tag;
+            $tagName =~ tr/A-Za-z0-9//dc;
+            $tagInfo = { Name => ucfirst($tagName) };
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        if ($verbose) {
+            $format = 'undef' unless defined $format;
+            $flags = Image::ExifTool::DecodeBits($flags, \%metadataFlag);
+        }
+        if ($valueLen and $format) {
+            # (a flag can be 1 or 4 bytes)
+            if ($format eq 'flag') {
+                $format = ($valueLen == 4) ? 'int32u' : 'int8u';
+            } elsif ($type == 7 and $tagInfo) {
+                # add PrintConv and ValueConv for "date" type
+                $$tagInfo{ValueConv} or $$tagInfo{ValueConv} = q{
+                    $val =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/ ?
+                    sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%.2d",$1,$2,$3,$4,$5,$6) :
+                    $val;
+                };
+                $$tagInfo{PrintConv} or $$tagInfo{PrintConv} = '$self->ConvertDateTime($val)';
+            }
+            my $count = int($valueLen / Image::ExifTool::FormatSize($format));
+            my $val = ReadValue($dataPt, $valuePos, $format, $count, $dirEnd-$valuePos);
+            $exifTool->HandleTag($tagTablePtr, $tag, $val,
+                DataPt => $dataPt,
+                DataPos => $dataPos,
+                Start => $valuePos,
+                Size => $valueLen,
+                Format => "type=$type, flags=$flags",
+            );
+        }
+        # extract sub-properties
+        if ($numSubProps) {
+            my $dirStart = $valuePos + $valueLen + $numSubProps * 8;
+            my %dirInfo = (
+                DataPt => $dataPt,
+                DataPos => $dataPos,
+                DirStart => $dirStart,
+                DirLen => $pos + $size - $dirStart,
+                Prefix => $tag,
+            );
+            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        }
+        $pos += $size;  # step to next Metadata structure
+    }
+    unless ($pos == $dirEnd) {
+        $exifTool->Warn('Format error in Real Metadata');
+        return 0;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Read information frame a Real file
+# Inputs: 0) ExifTool object reference, 1) Directory information reference
+# Returns: 1 on success, 0 if this wasn't a valid Real file
+sub ProcessReal($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my ($buff, $tag, $vers, $extra, @mimeTypes, %dirCount);
+
+    $raf->Read($buff, 8) == 8 or return 0;
+    $buff =~ m{^(\.RMF|\.ra\xfd|pnm://|rtsp://|http://)} or return 0;
+
+    my ($type, $tagTablePtr);
+    if ($1 eq '.RMF') {
+        $tagTablePtr = GetTagTable('Image::ExifTool::Real::Media');
+        $type = 'RM';
+    } elsif ($1 eq ".ra\xfd") {
+        $tagTablePtr = GetTagTable('Image::ExifTool::Real::Audio');
+        $type = 'RA';
+    } else {
+        $tagTablePtr = GetTagTable('Image::ExifTool::Real::Metafile');
+        my $ext = $exifTool->{FILE_EXT};
+        $type = ($ext and $ext eq 'RPM') ? 'RPM' : 'RAM';
+        require Image::ExifTool::PostScript;
+        my $oldSep = Image::ExifTool::PostScript::SetInputRecordSeparator($raf);
+        $raf->Seek(0,0);
+        while ($raf->ReadLine($buff)) {
+            last if length $buff > 256;
+            next unless $buff ;
+            chomp $buff;
+            if ($type) {
+                # must be a Real file type if protocol is http
+                return 0 if $buff =~ /^http/ and $buff !~ /\.(ra|rm|rv|rmvb|smil)$/i;
+                $exifTool->SetFileType($type);
+                undef $type;
+            }
+            # save URL or Text from RAM file
+            my $tag = $buff =~ m{^[a-z]{3,4}://} ? 'url' : 'txt';
+            $exifTool->HandleTag($tagTablePtr, $tag, $buff);
+        }
+        $/ = $oldSep if $oldSep;
+        return 1;
+    }
+
+    $exifTool->SetFileType($type);
+    SetByteOrder('MM');
+    my $verbose = $exifTool->Options('Verbose');
+#
+# Process RealAudio file
+#
+    if ($type eq 'RA') {
+        ($vers, $extra) = unpack('x4nn', $buff);
+        $tag = ".ra$vers";
+        my $fpos = $raf->Tell();
+        unless ($raf->Read($buff, 512)) {
+            $exifTool->Warn('Error reading audio header');
+            return 1;
+        }
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        if ($verbose > 2) {
+            $exifTool->VerboseInfo($tag, $tagInfo, DataPt => \$buff, DataPos => $fpos);
+        }
+        if ($tagInfo) {
+            my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+            my %dirInfo = (
+                DataPt   => \$buff,
+                DataPos  => $fpos,
+                DirLen   => length $buff,
+                DirStart => 0,
+            );
+            $exifTool->ProcessDirectory(\%dirInfo, $subTablePtr);
+        } else {
+            $exifTool->Warn('Unsupported RealAudio version');
+        }
+        return 1;
+    }
+#
+# Process RealMedia file
+#
+    # skip the rest of the RM header
+    my $size = unpack('x4N', $buff);
+    unless ($raf->Seek($size - 8, 1)) {
+        $exifTool->Warn('Error seeking in file');
+        return 0;
+    }
+
+    # Process RealMedia chunks
+    for (;;) {
+        $raf->Read($buff, 10) == 10 or last;
+        ($tag, $size, $vers) = unpack('a4Nn', $buff);
+        last if $tag eq "\0\0\0\0";
+        if ($verbose) {
+            $exifTool->VPrint(0, "$tag chunk ($size bytes):\n");
+        } else {
+            last if $tag eq 'DATA'; # stop normal parsing at DATA tag
+        }
+        if ($size & 0x80000000) {
+            $exifTool->Warn('Bad chunk header');
+            last;
+        }
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        if ($tagInfo and $$tagInfo{SubDirectory}) {
+            my $fpos = $raf->Tell();
+            unless ($raf->Read($buff, $size-10) == $size-10) {
+                $exifTool->Warn("Error reading $tag chunk");
+                last;
+            }
+            if ($verbose > 2) {
+                $exifTool->VerboseInfo($tag, $tagInfo, DataPt => \$buff, DataPos => $fpos);
+            }
+            my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+            my %dirInfo = (
+                DataPt   => \$buff,
+                DataPos  => $fpos,
+                DirLen   => length $buff,
+                DirStart => 0,
+            );
+            if ($dirCount{$tag}) {
+                $exifTool->{SET_GROUP1} = '+' . ++$dirCount{$tag};
+            } else {
+                $dirCount{$tag} = 1;
+            }
+            $exifTool->ProcessDirectory(\%dirInfo, $subTablePtr);
+            delete $exifTool->{SET_GROUP1};
+            # keep track of stream MIME types
+            my $mime = $exifTool->{RealStreamMime};
+            if ($mime) {
+                delete $exifTool->{RealStreamMime};
+                $mime =~ s/\0.*//s;
+                push @mimeTypes, $mime unless $mime =~ /^logical-/;
+            }
+        } else {
+            unless ($raf->Seek($size-10, 1)) {
+                $exifTool->Warn('Error seeking in file');
+                last;
+            }
+        }
+    }
+    # override MIMEType with stream MIME type if we only have one stream
+    if (@mimeTypes == 1 and length $mimeTypes[0]) {
+        $exifTool->{VALUE}->{MIMEType} = $mimeTypes[0];
+        $verbose and $exifTool->VPrint(0, "  MIMEType = $mimeTypes[0]\n");
+    }
+#
+# Process footer containing Real metadata and ID3 information
+#
+    if ($raf->Seek(-140, 2) and $raf->Read($buff, 12) == 12 and $buff =~ /^RMJE/) {
+        my $metaSize = unpack('x8N', $buff);
+        if ($raf->Seek(-$metaSize-12, 1) and
+            $raf->Read($buff, $metaSize) == $metaSize and
+            $buff =~ /^RJMD/)
+        {
+            my %dirInfo = (
+                DataPt => \$buff,
+                DataPos => $raf->Tell() - $metaSize,
+                DirStart => 8,
+                DirLen => length($buff) - 8,
+            );
+            my $tagTablePtr = GetTagTable('Image::ExifTool::Real::Metadata');
+            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        } else {
+            $exifTool->Warn('Bad metadata footer');
+        }
+        if ($raf->Seek(-128, 2) and $raf->Read($buff, 128) == 128 and $buff =~ /^TAG/) {
+            $exifTool->VPrint(0, "ID3v1:\n");
+            my %dirInfo = (
+                DataPt => \$buff,
+                DirStart => 0,
+                DirLen => length($buff),
+            );
+            my $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v1');
+            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        }
+    }
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Real - Read Real audio/video meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains the routines required by Image::ExifTool to read meta
+information in RealAudio (RA), RealMedia (RM, RV and RMVB) and RealMedia
+Metafile (RAM and RPM) files.
+
+=head1 NOTES
+
+There must be a bug in the software that wrote the Metadata used in the test
+file t/images/Real.rm because the TrackLyricsDataSize word is written
+little-endian, but the Real format is big-endian.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.getid3.org/>
+
+=item L<https://common.helixcommunity.org/nonav/2003/HCS_SDK_r5/htmfiles/rmff.htm>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Real Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Ricoh.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Ricoh.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Ricoh.pm	(revision 20131)
@@ -0,0 +1,439 @@
+#------------------------------------------------------------------------------
+# File:         Ricoh.pm
+#
+# Description:  Ricoh EXIF maker notes tags
+#
+# Revisions:    03/28/2005 - P. Harvey Created
+#
+# References:   1) http://www.ozhiker.com/electronics/pjmt/jpeg_info/ricoh_mn.html
+#               2) http://homepage3.nifty.com/kamisaka/makernote/makernote_ricoh.htm
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Ricoh;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.05';
+
+sub ProcessRicohText($$$);
+sub ProcessRicohRMETA($$$);
+
+%Image::ExifTool::Ricoh::Main = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    NOTES => 'These tags are used by Ricoh Caplio camera models.',
+    0x0001 => { Name => 'MakerNoteType',    Writable => 'string' },
+    0x0002 => { Name => 'MakerNoteVersion', Writable => 'string' },
+    0x0e00 => {
+        Name => 'PrintIM',
+        Writable => 0,
+        Description => 'Print Image Matching',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+    0x1001 => {
+        Name => 'ImageInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Ricoh::ImageInfo',
+        },
+    },
+    0x1003 => {
+        Name => 'Sharpness',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Sharp',
+            1 => 'Normal',
+            2 => 'Soft',
+        },
+    },
+    0x2001 => [
+        {
+            Name => 'RicohSubdir',
+            Condition => '$self->{CameraModel} !~ /^Caplio RR1\b/',
+            SubDirectory => {
+                Validate => '$val =~ /^\[Ricoh Camera Info\]/',
+                TagTable => 'Image::ExifTool::Ricoh::Subdir',
+                Start => '$valuePtr + 20',
+                ByteOrder => 'BigEndian',
+            },
+        },
+        {
+            Name => 'RicohRR1Subdir',
+            SubDirectory => {
+                Validate => '$val =~ /^\[Ricoh Camera Info\]/',
+                TagTable => 'Image::ExifTool::Ricoh::Subdir',
+                Start => '$valuePtr + 20',
+                ByteOrder => 'BigEndian',
+                # the Caplio RR1 uses a different base address -- doh!
+                Base => '$start-20',
+            },
+        },
+    ],
+);
+
+# Ricoh image info (ref 2)
+%Image::ExifTool::Ricoh::ImageInfo = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    PRIORITY => 0,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    IS_OFFSET => [ 28 ],   # tag 28 is 'IsOffset'
+    0 => {
+        Name => 'RicohImageWidth',
+        Format => 'int16u',
+    },
+    2 => {
+        Name => 'RicohImageHeight',
+        Format => 'int16u',
+    },
+    6 => {
+        Name => 'RicohDate',
+        Groups => { 2 => 'Time' },
+        Format => 'int8u[7]',
+        # (what an insane way to encode the date)
+        ValueConv => q{
+            sprintf("%.2x%.2x:%.2x:%.2x %.2x:%.2x:%.2x",
+                    split(' ', $val));
+        },
+        ValueConvInv => q{
+            my @vals = ($val =~ /(\d{1,2})/g);
+            push @vals, 0 if @vals < 7;
+            join(' ', map(hex, @vals));
+        },
+    },
+    28 => {
+        Name => 'PreviewImageStart',
+        Format => 'int16u',
+        Flags => 'IsOffset',
+        OffsetPair => 30,   # associated byte count tagID
+        DataTag => 'PreviewImage',
+        Protected => 2,
+    },
+    30 => {
+        Name => 'PreviewImageLength',
+        Format => 'int16u',
+        OffsetPair => 28,   # point to associated offset
+        DataTag => 'PreviewImage',
+        Protected => 2,
+    },
+    32 => {
+        Name => 'FlashMode',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto', #PH
+            2 => 'On',
+        },
+    },
+    33 => {
+        Name => 'Macro',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    34 => {
+        Name => 'Sharpness',
+        PrintConv => {
+            0 => 'Sharp',
+            1 => 'Normal',
+            2 => 'Soft',
+        },
+    },
+    38 => {
+        Name => 'WhiteBalance',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Daylight',
+            2 => 'Cloudy',
+            3 => 'Tungsten',
+            4 => 'Fluorescent',
+            # 5 (One Pushes, flake setting?)
+            # 7 (details setting?)
+        },
+    },
+    39 => {
+        Name => 'ISOSetting',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 64,
+            2 => 100,
+            4 => 200,
+            6 => 400,
+            7 => 800,
+            8 => 1600,
+        },
+    },
+    40 => {
+        Name => 'Saturation',
+        PrintConv => {
+            0 => 'High',
+            1 => 'Normal',
+            2 => 'Low',
+            3 => 'None (B&W)',
+        },
+    },
+);
+
+# NOTE: this subdir is not currently writable because the offsets would require
+# special code to handle the funny start location and base offset
+%Image::ExifTool::Ricoh::Subdir = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    0x0004 => { Name => 'RicohDateTime1', Groups => { 2 => 'Time' } }, #PH
+    0x0005 => { Name => 'RicohDateTime2', Groups => { 2 => 'Time' } }, #PH
+    # 0x000E ProductionNumber? (ref 2)
+);
+
+# Ricoh text-type maker notes (PH)
+%Image::ExifTool::Ricoh::Text = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PROCESS_PROC => \&ProcessRicohText,
+    NOTES => q{
+        Ricoh RDC models such as the RDC-i700, RDC-5000, RDC-6000, RDC-7 and
+        RDC-4300 use a text-based format for their maker notes instead of the IFD
+        format used by the Caplio models.  Below is a list of known tags in this
+        information.
+    },
+    Rev => 'Revision',
+    Rv => 'Revision',
+    Rg => 'RedGain',
+    Gg => 'GreenGain',
+    Bg => 'BlueGain',
+);
+
+%Image::ExifTool::Ricoh::RMETA = (
+    GROUPS => { 0 => 'APP5', 1 => 'RMETA', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::Ricoh::ProcessRicohRMETA,
+    NOTES => q{
+        The Ricoh Caplio Pro G3 has the ability to add custom fields to the APP5
+        "RMETA" segment of JPEG images.  While only a few observed tags have been
+        defined below, ExifTool will extract any information found here.
+    },
+    'Sign type' => { Name => 'SignType', PrintConv => {
+        1 => 'Directional',
+        2 => 'Warning',
+        3 => 'Information',
+    } },
+    Location => { PrintConv => {
+        1 => 'Verge',
+        2 => 'Gantry',
+        3 => 'Central reservation',
+        4 => 'Roundabout',
+    } },
+    Lit => { PrintConv => {
+        1 => 'Yes',
+        2 => 'No',
+    } },
+    Condition => { PrintConv => {
+        1 => 'Good',
+        2 => 'Fair',
+        3 => 'Poor',
+        4 => 'Damaged',
+    } },
+    Azimuth => { PrintConv => {
+        1 => 'N',
+        2 => 'NNE',
+        3 => 'NE',
+        4 => 'ENE',
+        5 => 'E',
+        6 => 'ESE',
+        7 => 'SE',
+        8 => 'SSE',
+        9 => 'S',
+        10 => 'SSW',
+        11 => 'SW',
+        12 => 'WSW',
+        13 => 'W',
+        14 => 'WNW',
+        15 => 'NW',
+        16 => 'NNW',
+    } },
+);
+
+#------------------------------------------------------------------------------
+# Process Ricoh text-based maker notes
+# Inputs: 0) ExifTool object reference
+#         1) Reference to directory information hash
+#         2) Pointer to tag table for this directory
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+sub ProcessRicohText($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataLen = $$dirInfo{DataLen};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || $dataLen - $dirStart;
+    my $verbose = $exifTool->Options('Verbose');
+
+    my $data = substr($$dataPt, $dirStart, $dirLen);
+    return 1 if $data =~ /^\0/;     # blank Ricoh maker notes
+    # validate text maker notes
+    unless ($data =~ /^(Rev|Rv)/) {
+        $exifTool->Warn('Bad Ricoh maker notes');
+        return 0;
+    }
+    my $pos = 0;
+    while ($data =~ m/([A-Z][a-z]{1,2})([0-9A-F]+);/sg) {
+        my $tag = $1;
+        my $val = $2;
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        if ($verbose) {
+            $exifTool->VerboseInfo($tag, $tagInfo,
+                Table  => $tagTablePtr,
+                Value  => $val,
+            );
+        }
+        unless ($tagInfo) {
+            next unless $exifTool->{OPTIONS}->{Unknown};
+            $tagInfo = {
+                Name => "Ricoh_Text_$tag",
+                Unknown => 1,
+                PrintConv => 'length($val) > 60 ? substr($val,0,55) . "[...]" : $val',
+            };
+            # add tag information to table
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        $exifTool->FoundTag($tagInfo, $val);
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process Ricoh APP5 RMETA information
+# Inputs: 0) ExifTool object reference
+#         1) Reference to directory information hash
+#         2) Pointer to tag table for this directory
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+sub ProcessRicohRMETA($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart};
+    my $dataLen = length($$dataPt);
+    my $verbose = $exifTool->Options('Verbose');
+
+    $dataLen > 6 or $exifTool->Warn('Truncated Ricoh RMETA data'), return 0;
+    my $byteOrder = substr($$dataPt, $dirStart, 2);
+    SetByteOrder($byteOrder) or $exifTool->Warn('Bad Ricoh RMETA data'), return 0;
+    my (@tags, @vals, @nums, $valPos);
+    my $pos = $dirStart + 6;
+    while ($pos <= $dataLen - 4) {
+        my $type = Get16u($dataPt, $pos);
+        my $size = Get16u($dataPt, $pos + 2);
+        $pos += 4;
+        $size -= 2;
+        if ($size < 0 or $pos + $size > $dataLen) {
+            $exifTool->Warn('Corrupted Ricoh RMETA data');
+            last;
+        }
+        if ($type eq 1) {
+            # save the tag names
+            my $tags = substr($$dataPt, $pos, $size);
+            $tags =~ s/\0+$//;  # remove trailing nulls
+            @tags = split /\0/, $tags;
+        } elsif ($type eq 2) {
+            # save the ASCII tag values
+            my $vals = substr($$dataPt, $pos, $size);
+            $vals =~ s/\0+$//;
+            @vals = split /\0/, $vals;
+            $valPos = $pos; # save position of first ASCII value
+        } elsif ($type eq 3) {
+            # save the numerical tag values
+            my $nums = substr($$dataPt, $pos, $size);
+            @nums = unpack($byteOrder eq 'MM' ? 'n*' : 'v*', $nums);
+        } elsif ($type eq 0) {
+            $pos += 2;  # why 2 extra bytes?
+        }
+        $pos += $size;
+    }
+    if (@tags or @vals) {
+        if (@tags != @vals) {
+            my ($nt, $nv) = (scalar(@tags), scalar(@vals));
+            $exifTool->Warn("Number of tags ($nt) and values ($nv) differs in Ricoh RMETA");
+        }
+        # find next tag in null-delimited list
+        # unpack numerical values from block of int16u values
+        my ($tag, $name, $val);
+        foreach $tag (@tags) {
+            $val = shift @vals;
+            last unless defined $val;
+            ($name = $tag) =~ s/\b([a-z])/\U$1/gs;  # make capitalize all words
+            $name =~ s/ (\w)/\U$1/g;                # remove special characters
+            $name = 'RMETA_Unknown' unless length($name);
+            my $num = shift @nums;
+            my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+            if ($tagInfo) {
+                # make sure print conversion is defined
+                $$tagInfo{PrintConv} = { } unless $$tagInfo{PrintConv};
+            } else {
+                # create tagInfo hash
+                $tagInfo = { Name => $name, PrintConv => { } };
+                Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            }
+            # use string value directly if no numerical value
+            $num = $val unless defined $num;
+            # add conversion for this value (replacing any existing entry)
+            $tagInfo->{PrintConv}->{$num} = $val;
+            if ($verbose) {
+                $exifTool->VerboseInfo($tag, $tagInfo,
+                    Table   => $tagTablePtr,
+                    Value   => $num,
+                    DataPt  => $dataPt,
+                    DataPos => $$dirInfo{DataPos},
+                    Start   => $valPos,
+                    Size    => length($val),
+                );
+            }
+            $exifTool->FoundTag($tagInfo, $num);
+            $valPos += length($val) + 1;
+        }
+    }
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Ricoh - Ricoh EXIF maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to
+interpret Ricoh maker notes EXIF meta information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.ozhiker.com/electronics/pjmt/jpeg_info/ricoh_mn.html>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Ricoh Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Sanyo.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Sanyo.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Sanyo.pm	(revision 20131)
@@ -0,0 +1,377 @@
+#------------------------------------------------------------------------------
+# File:         Sanyo.pm
+#
+# Description:  Sanyo EXIF maker notes tags
+#
+# Revisions:    04/06/2004  - P. Harvey Created
+#
+# Reference:    http://www.exif.org/makernotes/SanyoMakerNote.html
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Sanyo;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.10';
+
+my %offOn = (
+    0 => 'Off',
+    1 => 'On',
+);
+
+%Image::ExifTool::Sanyo::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x00ff => {
+        # this is an absolute offset in the JPG file... odd - PH
+        Name => 'MakerNoteOffset',
+        Writable => 'int32u',
+    },
+    0x0100 => {
+        Name => 'SanyoThumbnail',
+        Writable => 'undef',
+        WriteCheck => '$self->CheckImage(\$val)',
+        ValueConv => '$self->ValidateImage(\$val,$tag)',
+        ValueConvInv => '$val',
+    },
+    0x0200 => {
+        Name => 'SpecialMode',
+        Writable => 'int32u',
+        Count => 3,
+    },
+    0x0201 => {
+        Name => 'SanyoQuality',
+        Flags => 'PrintHex',
+        Writable => 'int16u',
+        PrintConv => {
+            0x0000 => 'Normal/Very Low',
+            0x0001 => 'Normal/Low',
+            0x0002 => 'Normal/Medium Low',
+            0x0003 => 'Normal/Medium',
+            0x0004 => 'Normal/Medium High',
+            0x0005 => 'Normal/High',
+            0x0006 => 'Normal/Very High',
+            0x0007 => 'Normal/Super High',
+            0x0100 => 'Fine/Very Low',
+            0x0101 => 'Fine/Low',
+            0x0102 => 'Fine/Medium Low',
+            0x0103 => 'Fine/Medium',
+            0x0104 => 'Fine/Medium High',
+            0x0105 => 'Fine/High',
+            0x0106 => 'Fine/Very High',
+            0x0107 => 'Fine/Super High',
+            0x0200 => 'Super Fine/Very Low',
+            0x0201 => 'Super Fine/Low',
+            0x0202 => 'Super Fine/Medium Low',
+            0x0203 => 'Super Fine/Medium',
+            0x0204 => 'Super Fine/Medium High',
+            0x0205 => 'Super Fine/High',
+            0x0206 => 'Super Fine/Very High',
+            0x0207 => 'Super Fine/Super High',
+        },
+    },
+    0x0202 => {
+        Name => 'Macro',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Macro',
+            2 => 'View',
+            3 => 'Manual',
+        },
+    },
+    0x0204 => {
+        Name => 'DigitalZoom',
+        Writable => 'rational64u',
+    },
+    0x0207 => 'SoftwareVersion',
+    0x0208 => 'PictInfo',
+    0x0209 => 'CameraID',
+    0x020e => {
+        Name => 'SequentialShot',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Standard',
+            2 => 'Best',
+            3 => 'Adjust Exposure',
+        },
+    },
+    0x020f => {
+        Name => 'WideRange',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x0210 => {
+        Name => 'ColorAdjustmentMode',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x0213 => {
+        Name => 'QuickShot',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x0214 => {
+        Name => 'SelfTimer',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x0216 => {
+        Name => 'VoiceMemo',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x0217 => {
+        Name => 'RecordShutterRelease',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Record while down',
+            1 => 'Press start, press stop',
+        },
+    },
+    0x0218 => {
+        Name => 'FlickerReduce',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x0219 => {
+        Name => 'OpticalZoomOn',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x021b => {
+        Name => 'DigitalZoomOn',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x021d => {
+        Name => 'LightSourceSpecial',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x021e => {
+        Name => 'Resaved',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'No',
+            1 => 'Yes',
+        },
+    },
+    0x021f => {
+        Name => 'SceneSelect',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Sport',
+            2 => 'TV',
+            3 => 'Night',
+            4 => 'User 1',
+            5 => 'User 2',
+            6 => 'Lamp', #PH
+        },
+    },
+    0x0223 => {
+        Name => 'ManualFocusDistance',
+        Writable => 'rational64u',
+    },
+    0x0224 => {
+        Name => 'SequenceShotInterval',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => '5 frames/sec',
+            1 => '10 frames/sec',
+            2 => '15 frames/sec',
+            3 => '20 frames/sec',
+        },
+    },
+    0x0225 => {
+        Name => 'FlashMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Force',
+            2 => 'Disabled',
+            3 => 'Red eye',
+        },
+    },
+    0x0e00 => {
+        Name => 'PrintIM',
+        Description => 'Print Image Matching',
+        Writable => 0,
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+    0x0f00 => {
+        Name => 'DataDump',
+        Writable => 0,
+        Binary => 1,
+    },
+);
+
+# tags in Sanyo MOV videos (PH - observations from an E6 sample)
+# (note: very similar to information in Nikon/Pentax videos)
+%Image::ExifTool::Sanyo::MOV = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        This information is found in Sanyo MOV video images, and is very similar to
+        information found in Pentax MOV and Nikon QT videos.
+    },
+    0x00 => {
+        Name => 'Make',
+        Format => 'string[5]',
+        PrintConv => 'ucfirst(lc($val))',
+    },
+    0x18 => {
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Format => 'string[8]',
+    },
+    0x26 => {
+        Name => 'ExposureTime',
+        Format => 'int32u',
+        ValueConv => '$val ? 10 / $val : 0',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    0x2a => {
+        Name => 'FNumber',
+        Format => 'int32u',
+        ValueConv => '$val * 0.1',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x32 => {
+        Name => 'ExposureCompensation',
+        Format => 'int32s',
+        ValueConv => '$val * 0.1',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x44 => {
+        Name => 'WhiteBalance',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Daylight',
+            2 => 'Shade',
+            3 => 'Fluorescent', #2
+            4 => 'Tungsten',
+            5 => 'Manual',
+        },
+    },
+    0x48 => {
+        Name => 'FocalLength',
+        Writable => 'int32u',
+        ValueConv => '$val * 0.1',
+        PrintConv => 'sprintf("%.1fmm",$val)',
+    },
+);
+
+# tags in Sanyo MP4 videos (PH - from C4, C5 and HD1A samples)
+# (there is still a lot more information here that could be decoded!)
+%Image::ExifTool::Sanyo::MP4 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'This information is found in Sanyo MP4 video images.',
+    0x00 => {
+        Name => 'Make',
+        Format => 'string[5]',
+        PrintConv => 'ucfirst(lc($val))',
+    },
+    0x18 => {
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Format => 'string[8]',
+    },
+    # (0x2e has values 0x31, 0x33 and 0x3c in my samples, but
+    # some of the shutter speeds should be around 1/500 or so)
+    0x32 => {
+        Name => 'FNumber',
+        Format => 'int32u',
+        ValueConv => '$val / 10',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x6a => {
+        Name => 'ISO',
+        Format => 'int32u',
+    },
+# (these tags are shifted by +1 byte for the C4 compared to the HD1A, so we can't use them)
+#     0xfe => {
+#         Name => 'ThumbnailLength',
+#         Format => 'int32u',
+#     },
+#     0x102 => {
+#         Name => 'ThumbnailOffset',
+#         IsOffset => 1,
+#         Format => 'int32u',
+#         RawConv => '$val + 0xf2',
+#     },
+    # so instead, look for the JPEG header using brute force...
+    0x800 => {
+        Name => 'ThumbnailImage',
+        Notes => 'position varies',
+        Format => 'undef[$size - 0x800]',
+        ValueConv => '$val=~s/.*(?=\xff\xd8\xff\xc4)//; $self->ValidateImage(\$val,$tag)',
+    },
+);
+
+#------------------------------------------------------------------------------
+# Patch incorrect offsets in J1, J2, J4, S1, S3 and S4 maker notes
+# Inputs: 0) valuePtr, 1) end of previous value, 2) value size, 3) tag ID, 4) write flag
+sub FixOffsets($$$$;$)
+{
+    my ($valuePtr, $valEnd, $size, $tagID, $wFlag) = @_;
+    # ignore existing offsets and calculate reasonable values instead
+    if ($tagID == 0x100) {
+        # just ignore the SanyoThumbnail when writing (pointer is garbage)
+        $_[0] = undef if $wFlag;
+    } else {
+        $_[0] = $valEnd;    # set value pointer to next logical location
+        ++$size if $size & 0x01;
+        $_[1] += $size;     # update end-of-value pointer
+    }
+}
+
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Sanyo - Sanyo EXIF maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+Sanyo maker notes in EXIF information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.exif.org/makernotes/SanyoMakerNote.html>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Sanyo Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Shift.pl
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Shift.pl	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Shift.pl	(revision 20131)
@@ -0,0 +1,574 @@
+#------------------------------------------------------------------------------
+# File:         Shift.pl
+#
+# Description:  ExifTool time shifting routines
+#
+# Revisions:    10/28/2005 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool;
+
+use strict;
+
+sub ShiftTime($$$;$);
+
+#------------------------------------------------------------------------------
+# apply shift to value in new value hash
+# Inputs: 0) shift type, 1) shift string, 2) value to shift, 3) new value hash ref
+# Returns: error string or undef on success and updates value in new value hash
+sub ApplyShift($$$;$)
+{
+    my ($func, $shift, $val, $newValueHash) = @_;
+
+    # get shift direction from first character in shift string
+    $shift =~ s/^(\+|-)// or return 'Bad shift string (no sign)';
+    my $pre = $1;
+    my $dir = ($pre eq '+') ? 1 : -1;
+    my $tagInfo = $$newValueHash{TagInfo};
+    my $tag = $$tagInfo{Name};
+    my $self = $$newValueHash{Self};    # (used in eval)
+    my $shiftOffset;
+    if ($$newValueHash{ShiftOffset}) {
+        $shiftOffset = $$newValueHash{ShiftOffset};
+    } else {
+        $shiftOffset = $$newValueHash{ShiftOffset} = { };
+    }
+
+    # initialize handler for eval warnings
+    local $SIG{'__WARN__'} = \&SetWarning;
+    SetWarning(undef);
+
+    # shift is applied to ValueConv value, so we must ValueConv-Shift-ValueConvInv
+    my ($type, $err);
+    foreach $type ('ValueConv','Shift','ValueConvInv') {
+        if ($type eq 'Shift') {
+            #### eval ShiftXxx function
+            $err = eval "Shift$func(\$val, \$shift, \$dir, \$shiftOffset)";
+        } elsif ($$tagInfo{$type}) {
+            my $conv = $$tagInfo{$type};
+            if (ref $conv eq 'CODE') {
+                $val = &$conv($val, $self);
+            } else {
+                return "Can't handle $type for $tag in ApplyShift()" if ref $$tagInfo{$type};
+                #### eval ValueConv/ValueConvInv ($val, $self)
+                $val = eval $$tagInfo{$type};
+            }
+        } else {
+            next;
+        }
+        # handle errors
+        $err and return $err;
+        $@ and SetWarning($@);
+        GetWarning() and return CleanWarning();
+    }
+    # update value in new value hash
+    $newValueHash->{Value} = [ $val ];
+    return undef;   # success
+}
+
+#------------------------------------------------------------------------------
+# Check date/time shift
+# Inputs: 0) shift type, 1) shift string (without sign)
+# Returns: updated shift string, or undef on error (and may update shift)
+sub CheckShift($$)
+{
+    my ($type, $shift) = @_;
+    my $err;
+    if ($type eq 'Time') {
+        return "No shift direction" unless $shift =~ s/^(\+|-)//;
+        # do a test shift to validate the shift string
+        my $testTime = '2005:11:02 09:00:13.25-04:00';
+        $err = ShiftTime($testTime, $shift, $1 eq '+' ? 1 : -1);
+    } else {
+        $err = "Unknown shift type ($type)";
+    }
+    return $err;
+}
+
+#------------------------------------------------------------------------------
+# return the number of days in a month
+# Inputs: 0) month number (Jan=1, may be outside range), 1) year
+# Returns: number of days in month
+sub DaysInMonth($$)
+{
+    my ($mon, $year) = @_;
+    my @days = (31,28,31,30,31,30,31,31,30,31,30,31);
+    # adjust to the range [0,11]
+    while ($mon < 1)  { $mon += 12; --$year; }
+    while ($mon > 12) { $mon -= 12; ++$year; }
+    # return standard number of days unless february on a leap year
+    return $days[$mon-1] unless $mon == 2 and not $year % 4;
+    # leap years don't occur on even centuries except every 400 years
+    return 29 if $year % 100 or not $year % 400;
+    return 28;
+}
+
+#------------------------------------------------------------------------------
+# split times into corresponding components: YYYY MM DD hh mm ss tzh tzm
+# Inputs: 0) date/time or shift string 1) reference to list for returned components
+#         2) optional reference to list of time components (if shift string)
+# Returns: true on success
+# Returned components are 0-Y, 1-M, 2-D, 3-hr, 4-min, 5-sec, 6-tzhr, 7-tzmin
+sub SplitTime($$;$)
+{
+    my ($val, $vals, $time) = @_;
+    # insert zeros if missing in shift string
+    if ($time) {
+        $val =~ s/(^|[-+:\s]):/${1}0:/g;
+        $val =~ s/:([:\s]|$)/:0$1/g;
+    }
+    # change dashes to colons in date (for XMP dates)
+    if ($val =~ s/^(\d{4})-(\d{2})-(\d{2})/$1:$2:$3/) {
+        $val =~ tr/T/ /;    # change 'T' separator to ' '
+    }
+    # add space before timezone to split it into a separate word
+    $val =~ s/(\+|-)/ $1/;
+    my @words = split ' ', $val;
+    my $err = 1;
+    my @v;
+    for (;;) {
+        my $word = shift @words;
+        last unless defined $word;
+        # split word into separate numbers (allow decimal points but no signs)
+        my @vals = $word =~ /(?=\d|\.\d)\d*(?:\.\d*)?/g or last;
+        if ($word =~ /^(\+|-)/) {
+            # this is the timezone
+            (defined $v[6] or @vals > 2) and $err = 1, last;
+            my $sign = ($1 ne '-') ? 1 : -1;
+            # apply sign to both minutes and seconds
+            $v[6] = $sign * shift(@vals);
+            $v[7] = $sign * (shift(@vals) || 0);
+        } elsif ((@words and $words[0] =~ /^\d+/) or # there is a time word to follow
+            (not $time and $vals[0] =~ /^\d{3}/) or # first value is year (3 or more digits)
+            ($time and not defined $$time[3] and not defined $v[0])) # we don't have a time
+        {
+            # this is a date (must come first)
+            (@v or @vals > 3) and $err = 1, last;
+            not $time and @vals != 3 and $err = 1, last;
+            $v[2] = pop(@vals);     # take day first if only one specified
+            $v[1] = pop(@vals) || 0;
+            $v[0] = pop(@vals) || 0;
+        } else {
+            # this is a time (can't come after timezone)
+            (defined $v[3] or defined $v[6] or @vals > 3) and $err = 1, last;
+            not $time and @vals != 3 and $err = 1, last;
+            $v[3] = shift(@vals);   # take hour first if only one specified
+            $v[4] = shift(@vals) || 0;
+            $v[5] = shift(@vals) || 0;
+        }
+        $err = 0;
+    }
+    return 0 if $err or not @v;
+    if ($time) {
+        # zero any required shift entries which aren't yet defined
+        $v[0] = $v[1] = $v[2] = 0 if defined $$time[0] and not defined $v[0];
+        $v[3] = $v[4] = $v[5] = 0 if defined $$time[3] and not defined $v[3];
+        $v[6] = $v[7] = 0 if defined $$time[6] and not defined $v[6];
+    }
+    @$vals = @v;    # return split time components
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# shift date/time by components
+# Inputs: 0) split date/time list ref, 1) split shift list ref,
+#         2) shift direction, 3) reference to output list of shifted components
+#         4) number of decimal points in seconds
+# Returns: error string or undef on success
+sub ShiftComponents($$$$$)
+{
+    my ($time, $shift, $dir, $toTime, $dec) = @_;
+    # min/max for Y, M, D, h, m, s
+    my @min = (    0, 1, 1, 0, 0, 0);
+    my @max = (10000,12,28,24,60,60);
+    my $i;
+#
+# apply the shift
+#
+    my $c = 0;
+    for ($i=0; $i<@$time; ++$i) {
+        my $v = ($$time[$i] || 0) + $dir * ($$shift[$i] || 0) + $c;
+        # handle fractional values by propagating remainders downwards
+        if ($v != int($v) and $i < 5) {
+            my $iv = int($v);
+            $c = ($v - $iv) * $max[$i+1];
+            $v = $iv;
+        } else {
+            $c = 0;
+        }
+        $$toTime[$i] = $v;
+    }
+    # round off seconds to the required number of decimal points
+    my $sec = $$toTime[5];
+    if (defined $sec and $sec != int($sec)) {
+        my $mult = 10 ** $dec;
+        $$toTime[5] = int($sec * $mult + 0.5 * ($sec <=> 0)) / $mult;
+    }
+#
+# handle overflows, starting with least significant number first (seconds)
+#
+    $c = 0;
+    for ($i=5; $i>=0; $i--) {
+        defined $$time[$i] or $c = 0, next;
+        # apply shift and adjust for previous overflow
+        my $v = $$toTime[$i] + $c;
+        $c = 0; # set carry to zero
+        # adjust for over/underflow
+        my ($min, $max) = ($min[$i], $max[$i]);
+        if ($v < $min) {
+            if ($i == 2) {  # 2 = day of month
+                do {
+                    # add number of days in previous month
+                    --$c;
+                    my $mon = $$toTime[$i-1] + $c;
+                    $v += DaysInMonth($mon, $$toTime[$i-2]);
+                } while ($v < 1);
+            } else {
+                my $fc = ($v - $min) / $max;
+                # carry ($c) must be largest integer equal to or less than $fc
+                $c = int($fc);
+                --$c if $c > $fc;
+                $v -= $c * $max;
+            }
+        } elsif ($v >= $max + $min) {
+            if ($i == 2) {
+                for (;;) {
+                    # test against number of days in current month
+                    my $mon = $$toTime[$i-1] + $c;
+                    my $days = DaysInMonth($mon, $$toTime[$i-2]);
+                    last if $v <= $days;
+                    $v -= $days;
+                    ++$c;
+                    last if $v <= 28;
+                }
+            } else {
+                my $fc = ($v - $max - $min) / $max;
+                # carry ($c) must be smallest integer greater than $fc
+                $c = int($fc);
+                ++$c if $c <= $fc;
+                $v -= $c * $max;
+            }
+        }
+        $$toTime[$i] = $v;  # save the new value
+    }
+    # handle overflows in timezone
+    if (defined $$toTime[6]) {
+        my $m = $$toTime[6] * 60 + $$toTime[7];
+        $m += 0.5 * ($m <=> 0);     # avoid round-off errors
+        $$toTime[6] = int($m / 60);
+        $$toTime[7] = int($m - $$toTime[6] * 60);
+    }
+    return undef;   # success
+}
+
+#------------------------------------------------------------------------------
+# Shift date/time string
+# Inputs: 0) date/time string, 1) shift string, 2) shift direction (+1 or -1)
+#         3) reference to ShiftOffset hash (with Date, DateTime, Time, Timezone keys)
+# Returns: error string or undef on success and date/time string is updated
+sub ShiftTime($$$;$)
+{
+    local $_;
+    my ($val, $shift, $dir, $shiftOffset) = @_;
+    my (@time, @shift, @toTime, $mode, $needShiftOffset, $dec);
+#
+# figure out what we are dealing with (time, date or date/time)
+#
+    SplitTime($val, \@time) or return "Invalid time string ($val)";
+    if (defined $time[0]) {
+        $mode = defined $time[3] ? 'DateTime' : 'Date';
+    } elsif (defined $time[3]) {
+        $mode = 'Time';
+    }
+    # get number of digits after the seconds decimal point
+    if (defined $time[5] and $time[5] =~ /\.(\d+)/) {
+        $dec = length($1);
+    } else {
+        $dec = 0;
+    }
+    if ($shiftOffset) {
+        $needShiftOffset = 1 unless defined $$shiftOffset{$mode};
+        $needShiftOffset = 1 if defined $time[6] and not defined $$shiftOffset{Timezone};
+    } else {
+        $needShiftOffset = 1;
+    }
+    if ($needShiftOffset) {
+#
+# apply date/time shift the hard way
+#
+        SplitTime($shift, \@shift, \@time) or return "Invalid shift string ($shift)";
+
+        # change 'Z' timezone to '+00:00' only if necessary
+        if (@shift > 6 and @time <= 6) {
+            $time[6] = $time[7] = 0 if $val =~ s/Z$/\+00:00/;
+        }
+        my $err = ShiftComponents(\@time, \@shift, $dir, \@toTime, $dec);
+        $err and return $err;
+#
+# calculate and save the shift offsets for next time
+#
+        if ($shiftOffset) {
+            if (defined $time[0] or defined $time[3]) {
+                my @tm1 = (0, 0, 0, 1, 0, 2000);
+                my @tm2 = (0, 0, 0, 1, 0, 2000);
+                if (defined $time[0]) {
+                    @tm1[3..5] = reverse @time[0..2];
+                    @tm2[3..5] = reverse @toTime[0..2];
+                    --$tm1[4]; # month should start from 0
+                    --$tm2[4];
+                }
+                my $diff = 0;
+                if (defined $time[3]) {
+                    @tm1[0..2] = reverse @time[3..5];
+                    @tm2[0..2] = reverse @toTime[3..5];
+                    # handle fractional seconds separately
+                    $diff = $tm2[0] - int($tm2[0]) - ($tm1[0] - int($tm1[0]));
+                    $tm1[0] = int($tm1[0]);
+                    $tm2[0] = int($tm2[0]);
+                }
+                eval q{
+                    require Time::Local;
+                    $diff += Time::Local::timegm(@tm2) - Time::Local::timegm(@tm1);
+                };
+                # not a problem if we failed here since we'll just try again next time,
+                # so don't return error message
+                unless (@$) {
+                    my $mode;
+                    if (defined $time[0]) {
+                        $mode = defined $time[3] ? 'DateTime' : 'Date';
+                    } else {
+                        $mode = 'Time';
+                    }
+                    $$shiftOffset{$mode} = $diff;
+                }
+            }
+            if (defined $time[6]) {
+                $$shiftOffset{Timezone} = ($toTime[6] - $time[6]) * 60 +
+                                           $toTime[7] - $time[7];
+            }
+        }
+
+    } else {
+#
+# apply shift from previously calculated offsets
+#
+        if ($$shiftOffset{Timezone} and @time <= 6) {
+            # change 'Z' timezone to '+00:00' only if necessary
+            $time[6] = $time[7] = 0 if $val =~ s/Z$/\+00:00/;
+        }
+        # apply the previous date/time shift if necessary
+        if ($mode) {
+            my @tm = (0, 0, 0, 1, 0, 2000);
+            if (defined $time[0]) {
+                @tm[3..5] = reverse @time[0..2];
+                --$tm[4]; # month should start from 0
+            }
+            @tm[0..2] = reverse @time[3..5] if defined $time[3];
+            # save fractional seconds
+            my $frac = $tm[0] - int($tm[0]);
+            $tm[0] = int($tm[0]);
+            my $tm;
+            eval q{
+                require Time::Local;
+                $tm = Time::Local::timegm(@tm) + $frac;
+            };
+            $@ and return CleanWarning($@);
+            $tm += $$shiftOffset{$mode};    # apply the shift
+            $tm < 0 and return 'Shift results in negative time';
+            # strip off fractional seconds after rounding to desired precision
+            # (only round if the result isn't integral)
+            $frac = $tm - int($tm);
+            if ($frac) {
+                # round off to required number of decimal points
+                my $tmf = $tm + 0.5 * 10 ** (-$dec);
+                $tm = int($tmf);
+                $frac = $tm - $tmf;
+            }
+            @tm = gmtime($tm);
+            @toTime = reverse @tm[0..5];
+            $toTime[0] += 1900;
+            ++$toTime[1];
+            $toTime[5] += $frac;    # add the fractional seconds back in
+        }
+        # apply the previous timezone shift if necessary
+        if (defined $time[6]) {
+            my $m = $time[6] * 60 + $time[7];
+            $m += $$shiftOffset{Timezone};
+            $m += 0.5 * ($m <=> 0);     # avoid round-off errors
+            $toTime[6] = int($m / 60);
+            $toTime[7] = int($m - $toTime[6] * 60);
+        }
+    }
+#
+# insert shifted time components back into original string
+#
+    my ($i, $err);
+    for ($i=0; $i<@toTime; ++$i) {
+        next unless defined $time[$i] and defined $toTime[$i];
+        my ($v, $d, $s);
+        if ($i != 6) {  # not timezone hours
+            last unless $val =~ /((?=\d|\.\d)\d*(\.\d*)?)/g;
+            next if $toTime[$i] == $time[$i];
+            $v = $1;    # value
+            $d = $2;    # decimal part of value
+            $s = '';    # no sign
+        } else {
+            last if $time[$i] == $toTime[$i] and $time[$i+1] == $toTime[$i+1];
+            last unless $val =~ /((?:\+|-)(?=\d|\.\d)\d*(\.\d*)?)/g;
+            $v = $1;
+            $d = $2;
+            if ($toTime[6] >= 0 and $toTime[7] >= 0) {
+                $s = '+';
+            } else {
+                $s = '-';
+                $toTime[6] = -$toTime[6];
+                $toTime[7] = -$toTime[7];
+            }
+        }
+        my $nv = $toTime[$i];
+        my $pos = pos $val;
+        my $len = length $v;
+        my $sig = $len - length $s;
+        my $dec = $d ? length($d) - 1 : 0;
+        my $newNum = sprintf($dec ? "$s%0$sig.${dec}f" : "$s%0${sig}d", $nv);
+        length($newNum) != $len and $err = 1;
+        substr($val, $pos - $len, $len) = $newNum;
+        pos($val) = $pos;
+    }
+    $err and return "Error packing shifted time ($val)";
+    $_[0] = $val;   # return shifted value
+    return undef;   # success!
+}
+
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Shift.pl - ExifTool time shifting routines
+
+=head1 DESCRIPTION
+
+This module contains routines used by ExifTool to shift date and time
+values.
+
+=head1 DETAILS
+
+Time shifts are applied to standard EXIF-formatted date/time values (ie.
+C<2005:03:14 18:55:00>).  Date-only and time-only values may also be
+shifted, and an optional timezone (ie. C<-05:00>) is also supported.  Here
+are some general rules and examples to explain how shift strings are
+interpreted:
+
+Date-only values are shifted using the following formats:
+
+    'Y:M:D'     - shift date by 'Y' years, 'M' months and 'D' days
+    'M:D'       - shift months and days only
+    'D'         - shift specified number of days
+
+Time-only values are shifted using the following formats:
+
+    'h:m:s'     - shift time by 'h' hours, 'm' minutes and 's' seconds
+    'h:m'       - shift hours and minutes only
+    'h'         - shift specified number of hours
+
+Timezone shifts are specified in the following formats:
+
+    '+h:m'      - shift timezone by 'h' hours and 'm' minutes
+    '-h:m'      - negative shift of timezone hours and minutes
+    '+h'        - shift timezone hours only
+    '-h'        - negative shift of timezone hours only
+
+A valid shift value consists of one or two arguments, separated by a space.
+If only one is provided, it is assumed to be a time shift when applied to a
+time-only or a date/time value, or a date shift when applied to a date-only
+value.  For example:
+
+    '7'         - shift by 1 hour if applied to a time or date/time
+                  value, or by one day if applied to a date value
+    '2:0'       - shift 2 hours (time, date/time), or 2 months (date)
+    '5:0:0'     - shift 5 hours (time, date/time), or 5 years (date)
+    '0:0:1'     - shift 1 sec (time, date/time), or 1 day (date)
+
+If two arguments are given, the date shift is first, followed by the time
+shift:
+
+    '3:0:0 0'         - shift date by 3 years
+    '0 15:30'         - shift time by 15 hours and 30 minutes
+    '1:0:0 0:0:0+5:0' - shift date by 1 year and timezone by 5 hours
+
+A date shift is simply ignored if applied to a time value or visa versa.
+
+Numbers specified in shift fields may contain a decimal point:
+
+    '1.5'       - 1 hour 30 minutes (time, date/time), or 1 day (date)
+    '2.5 0'     - 2 days 12 hours (date/time), 12 hours (time) or
+                  2 days (date)
+
+And to save typing, a zero is assumed for any missing numbers:
+
+    '1::'       - shift by 1 hour (time, date/time) or 1 year (date)
+    '26:: 0'    - shift date by 26 years
+    '+:30       - shift timezone by 30 minutes
+
+Below are some specific examples applied to real date and/or time values
+('Dir' is the applied shift direction: '+' is positive, '-' is negative):
+
+     Original Value         Shift   Dir    Shifted Value
+    ---------------------  -------  ---  ---------------------
+    '20:30:00'             '5'       +   '01:30:00'
+    '2005:01:27'           '5'       +   '2005:02:01'
+    '11:54:00'             '2.5 0'   -   '23:54:00'
+    '2005:11:02'           '2.5 0'   -   '2005:10:31'
+    '2005:11:02 11:54:00'  '2.5 0'   -   '2005:10:30 23:54:00'
+    '2004:02:28 08:00:00'  '1 1.3'   +   '2004:02:29 09:18:00'
+    '07:00:00'             '-5'      +   '07:00:00'
+    '07:00:00+01:00'       '-5'      +   '07:00:00-04:00'
+    '07:00:00Z'            '+2:30'   -   '07:00:00-02:30'
+    '1970:01:01'           '35::'    +   '2005:01:01'
+    '2005:01:01'           '400'     +   '2006:02:05'
+    '10:00:00.00'          '::1.33'  +   '09:59:58.67'
+
+=head1 NOTES
+
+The format of the original date/time value is not changed when the time
+shift is applied.  This means that the length of the date/time string will
+not change, and only the numbers in the string will be modified.  The only
+exception to this rule is that a 'Z' timezone is changed to '+00:00'
+notation if a timezone shift is applied.  A timezone will not be added to
+the date/time string.
+
+=head1 TRICKY
+
+This module is perhaps more complicated than it needs to be because it is
+designed to be very flexible in the way time shifts are specified and
+applied...
+
+The ability to shift dates by Y years, M months, etc, is somewhat
+contradictory to the goal of maintaining a constant shift for all time
+values when applying a batch shift.  This is because shifting by 1 month can
+be equivalent to anything from 28 to 31 days, and 1 year can be 365 or 366
+days, depending on the starting date.
+
+The inconsistency is handled by shifting the first tag found with the actual
+specified shift, then calculating the equivalent time difference in seconds
+for this shift and applying this difference to subsequent tags in a batch
+conversion.  So if it works as designed, the behaviour should be both
+intuitive and mathematically correct, and the user shouldn't have to worry
+about details such as this (in keeping with Perl's "do the right thing"
+philosophy).
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Shortcuts.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Shortcuts.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Shortcuts.pm	(revision 20131)
@@ -0,0 +1,254 @@
+#------------------------------------------------------------------------------
+# File:         Shortcuts.pm
+#
+# Description:  ExifTool shortcut tags
+#
+# Revisions:    02/07/2004 - P. Harvey Moved out of Exif.pm
+#               09/15/2004 - P. Harvey Added D70Boring from Greg Troxel
+#               01/11/2005 - P. Harvey Added Canon20D from Christian Koller
+#               03/03/2005 - P. Harvey Added user defined shortcuts
+#               03/26/2005 - P. Harvey Added Nikon from Tom Christiansen
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Shortcuts;
+
+use strict;
+use vars qw($VERSION);
+
+$VERSION = '1.16';
+
+# this is a special table used to define command-line shortcuts
+%Image::ExifTool::Shortcuts::Main = (
+    # this shortcut allows the three common date/time tags to be shifted at once
+    AllDates => [
+        'DateTimeOriginal',
+        'CreateDate',
+        'ModifyDate',
+    ],
+    # This is a shortcut to some common information which is useful in most images
+    Common => [
+        'FileName',
+        'FileSize',
+        'Model',
+        'DateTimeOriginal',
+        'ImageSize',
+        'Quality',
+        'FocalLength',
+        'ShutterSpeed',
+        'Aperture',
+        'ISO',
+        'WhiteBalance',
+        'Flash',
+    ],
+    # This shortcut provides the same information as the Canon utilities
+    Canon => [
+        'FileName',
+        'Model',
+        'DateTimeOriginal',
+        'ShootingMode',
+        'ShutterSpeed',
+        'Aperture',
+        'MeteringMode',
+        'ExposureCompensation',
+        'ISO',
+        'Lens',
+        'FocalLength',
+        'ImageSize',
+        'Quality',
+        'FlashOn',
+        'FlashType',
+        'ConditionalFEC',
+        'RedEyeReduction',
+        'ShutterCurtainHack',
+        'WhiteBalance',
+        'FocusMode',
+        'Contrast',
+        'Sharpness',
+        'Saturation',
+        'ColorTone',
+        'FileSize',
+        'FileNumber',
+        'DriveMode',
+        'OwnerName',
+        'SerialNumber',
+    ],
+    # courtesy of Christian Koller
+    Canon20D => [
+        'FileName',
+        'Model',
+        'DateTimeOriginal',
+        'ShootingMode',
+        'ShutterSpeedValue', #changed for 20D
+        'ApertureValue', #changed for 20D
+        'MeteringMode',
+        'ExposureCompensation',
+        'ISO',
+        'Lens',
+        'FocalLength',
+        #'ImageSize', #wrong in CR2
+        'ExifImageWidth', #instead
+        'ExifImageLength', #instead
+        'Quality',
+        'FlashOn',
+        'FlashType',
+        'ConditionalFEC',
+        'RedEyeReduction',
+        'ShutterCurtainHack',
+        'WhiteBalance',
+        'FocusMode',
+        'Contrast',
+        'Sharpness',
+        'Saturation',
+        'ColorTone',
+        'ColorSpace', # new
+        'LongExposureNoiseReduction', #new
+        'FileSize',
+        'FileNumber',
+        'DriveMode',
+        'OwnerName',
+        'SerialNumber',
+    ],
+    Nikon => [
+        'Model',
+        'SubSecDateTimeOriginal',
+        'ShutterCount',
+        'LensSpec',
+        'FocalLength',
+        'ImageSize',
+        'ShutterSpeed',
+        'Aperture',
+        'ISO',
+        'NoiseReduction',
+        'ExposureProgram',
+        'ExposureCompensation',
+        'WhiteBalance',
+        'WhiteBalanceFineTune',
+        'ShootingMode',
+        'Quality',
+        'MeteringMode',
+        'FocusMode',
+        'ImageOptimization',
+        'ToneComp',
+        'ColorHue',
+        'ColorSpace',
+        'HueAdjustment',
+        'Saturation',
+        'Sharpness',
+        'Flash',
+        'FlashMode',
+        'FlashExposureComp',
+    ],
+    # This shortcut may be useful when copying tags between files to either
+    # copy the maker notes as a block or prevent it from being copied
+    MakerNotes => [
+        'MakerNotes',   # (for RIFF MakerNotes)
+        'MakerNoteCanon',
+        'MakerNoteCasio',
+        'MakerNoteCasio2',
+        'MakerNoteFujiFilm',
+        'MakerNoteHP',
+        'MakerNoteHP2',
+        'MakerNoteHP4',
+        'MakerNoteHP6',
+        'MakerNoteJVC',
+        'MakerNoteJVCText',
+        'MakerNoteKodak1a',
+        'MakerNoteKodak1b',
+        'MakerNoteKodak2',
+        'MakerNoteKodak3',
+        'MakerNoteKodak4',
+        'MakerNoteKodak5',
+        'MakerNoteKodak6a',
+        'MakerNoteKodak6b',
+        'MakerNoteKodak7',
+        'MakerNoteKodakIFD',
+        'MakerNoteKodakUnknown',
+        'MakerNoteKyocera',
+        'MakerNoteMinolta',
+        'MakerNoteMinolta2',
+        'MakerNoteMinolta3',
+        'MakerNoteNikon',
+        'MakerNoteNikon2',
+        'MakerNoteNikon3',
+        'MakerNoteOlympus',
+        'MakerNoteOlympus2',
+        'MakerNoteLeica',
+        'MakerNotePanasonic',
+        'MakerNotePanasonic2',
+        'MakerNotePentax',
+        'MakerNotePentax2',
+        'MakerNotePentax3',
+        'MakerNotePentax4',
+        'MakerNoteRicoh',
+        'MakerNoteRicohText',
+        'MakerNoteSanyo',
+        'MakerNoteSanyoC4',
+        'MakerNoteSanyoPatch',
+        'MakerNoteSigma',
+        'MakerNoteSony',
+        'MakerNoteSonySRF',
+        'MakerNoteSonySR2',
+        'MakerNoteUnknown',
+    ],
+);
+
+# load user-defined shortcuts if available
+if (defined %Image::ExifTool::Shortcuts::UserDefined) {
+    my $shortcut;
+    foreach $shortcut (keys %Image::ExifTool::Shortcuts::UserDefined) {
+        my $val = $Image::ExifTool::Shortcuts::UserDefined{$shortcut};
+        # also allow simple aliases
+        $val = [ $val ] unless ref $val eq 'ARRAY';
+        # save the user-defined shortcut or alias
+        $Image::ExifTool::Shortcuts::Main{$shortcut} = $val;
+    }
+}
+
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Shortcuts - ExifTool shortcut tags
+
+=head1 SYNOPSIS
+
+This module is required by Image::ExifTool.
+
+=head1 DESCRIPTION
+
+This module contains definitions for tag name shortcuts used by
+Image::ExifTool.  You can customize this file to add your own shortcuts.
+
+Individual users may also add their own shortcuts to the .ExifTool_config
+file in their home directory (or the directory specified by the
+EXIFTOOL_HOME environment variable).  The shortcuts are defined in a hash
+called %Image::ExifTool::Shortcuts::UserDefined.  The keys of the hash are
+the shortcut names, and the elements are either tag names or references to
+lists of tag names.
+
+An example shortcut definition in .ExifTool_config:
+
+    %Image::ExifTool::Shortcuts::UserDefined = (
+        MyShortcut => ['createdate','exif:exposuretime','aperture'],
+        MyAlias => 'FocalLengthIn35mmFormat',
+    );
+
+In this example, MyShortcut is a shortcut for the CreateDate,
+EXIF:ExposureTime and Aperture tags, and MyAlias is a shortcut for
+FocalLengthIn35mmFormat.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Sigma.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Sigma.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Sigma.pm	(revision 20131)
@@ -0,0 +1,245 @@
+#------------------------------------------------------------------------------
+# File:         Sigma.pm
+#
+# Description:  Sigma/Foveon EXIF maker notes tags
+#
+# Revisions:    04/06/2004 - P. Harvey Created
+#               02/20/2007 - PH added SD14 tags
+#
+# Reference:    http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Sigma;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.04';
+
+%Image::ExifTool::Sigma::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 'string',
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x0002 => 'SerialNumber',
+    0x0003 => 'DriveMode',
+    0x0004 => 'ResolutionMode',
+    0x0005 => 'AFMode',
+    0x0006 => 'FocusSetting',
+    0x0007 => 'WhiteBalance',
+    0x0008 => {
+        Name => 'ExposureMode',
+        PrintConv => { #PH
+            A => 'Aperture-priority AE',
+            M => 'Manual',
+            P => 'Program AE',
+            S => 'Shutter speed priority AE',
+        },
+    },
+    0x0009 => {
+        Name => 'MeteringMode',
+        PrintConv => { #PH
+            A => 'Average',
+            C => 'Center-weighted average',
+            8 => 'Multi-segment',
+        },
+    },
+    0x000a => 'Lens',
+    0x000b => 'ColorSpace',
+    0x000c => [
+        {
+            Name => 'ExposureCompensation',
+            Condition => '$$self{CameraModel} !~ /SD14$/',
+            ValueConv => '$val =~ s/Expo:\s*//, $val',
+            ValueConvInv => 'IsFloat($val) ? sprintf("Expo:%+.1f",$val) : undef',
+        },
+        { #PH
+            Name => 'UnknownCompensation',
+            Writable => 'rational64s',
+            Unknown => 1,
+        },
+    ],
+    0x000d => [
+        {
+            Name => 'Contrast',
+            Condition => '$$self{CameraModel} !~ /SD14$/',
+            ValueConv => '$val =~ s/Cont:\s*//, $val',
+            ValueConvInv => 'IsFloat($val) ? sprintf("Cont:%+.1f",$val) : undef',
+        },
+        { #PH
+            Name => 'Contrast',
+            Writable => 'rational64s',
+        },
+    ],
+    0x000e => [
+        {
+            Name => 'Shadow',
+            Condition => '$$self{CameraModel} !~ /SD14$/',
+            ValueConv => '$val =~ s/Shad:\s*//, $val',
+            ValueConvInv => 'IsFloat($val) ? sprintf("Shad:%+.1f",$val) : undef',
+        },
+        { #PH
+            Name => 'Shadow',
+            Writable => 'rational64s',
+        },
+    ],
+    0x000f => [
+        {
+            Name => 'Highlight',
+            Condition => '$$self{CameraModel} !~ /SD14$/',
+            ValueConv => '$val =~ s/High:\s*//, $val',
+            ValueConvInv => 'IsFloat($val) ? sprintf("High:%+.1f",$val) : undef',
+        },
+        { #PH
+            Name => 'Highlight',
+            Writable => 'rational64s',
+        },
+    ],
+    0x0010 => [
+        {
+            Name => 'Saturation',
+            Condition => '$$self{CameraModel} !~ /SD14$/',
+            ValueConv => '$val =~ s/Satu:\s*//, $val',
+            ValueConvInv => 'IsFloat($val) ? sprintf("Satu:%+.1f",$val) : undef',
+        },
+        { #PH
+            Name => 'Saturation',
+            Writable => 'rational64s',
+        },
+    ],
+    0x0011 => [
+        {
+            Name => 'Sharpness',
+            Condition => '$$self{CameraModel} !~ /SD14$/',
+            ValueConv => '$val =~ s/Shar:\s*//, $val',
+            ValueConvInv => 'IsFloat($val) ? sprintf("Shar:%+.1f",$val) : undef',
+        },
+        { #PH
+            Name => 'Sharpness',
+            Writable => 'rational64s',
+        },
+    ],
+    0x0012 => [
+        {
+            Name => 'X3FillLight',
+            Condition => '$$self{CameraModel} !~ /SD14$/',
+            ValueConv => '$val =~ s/Fill:\s*//, $val',
+            ValueConvInv => 'IsFloat($val) ? sprintf("Fill:%+.1f",$val) : undef',
+        },
+        { #PH
+            Name => 'X3FillLight',
+            Writable => 'rational64s',
+        },
+    ],
+    0x0014 => [
+        {
+            Name => 'ColorAdjustment',
+            Condition => '$$self{CameraModel} !~ /SD14$/',
+            ValueConv => '$val =~ s/CC:\s*//, $val',
+            ValueConvInv => 'IsInt($val) ? "CC:$val" : undef',
+        },
+        { #PH
+            Name => 'ColorAdjustment',
+            Writable => 'rational64s',
+            Count => 3,
+        },
+    ],
+    0x0015 => 'AdjustmentMode',
+    0x0016 => {
+        Name => 'Quality',
+        ValueConv => '$val =~ s/Qual:\s*//, $val',
+        ValueConvInv => 'IsInt($val) ? "Qual:$val" : undef',
+    },
+    0x0017 => 'Firmware',
+    0x0018 => 'Software',
+    0x0019 => 'AutoBracket',
+    # 0x001a - int32u: 1884 to 2016
+    # 0x001b - int32u: 20688 to 45335
+    # 0x001c - int16u[2]: "640 480"
+    0x001d => { #PH
+        Name => 'MakerNoteVersion',
+        Format => 'undef',
+    },
+    # 0x001e - int16u: 0
+    # 0x001f - string: ""
+    # 0x0020-21 - string: " "
+    0x0022 => { #PH
+        Name => 'AdjustmentMode',
+        Priority => 0,
+        Unknown => 1,
+    },
+    # 0x0023 - string: 10, 131, 150, 152, 169
+    # 0x0024-25 - string: ""
+    # 0x0026-2e - int32u: 0
+    # 0x002f - int32u: 0, 1
+    0x0030 => 'LensApertureRange', #PH
+    0x0031 => { #PH
+        Name => 'FNumber',
+        Writable => 'rational64u',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0032 => { #PH
+        Name => 'ExposureTime',
+        Writable => 'rational64u',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    # 0x0033 - string: "3909" to "12337687"
+    # 0x0034 - int32u: 0,1,2,3 or 4 (possibly AFPoint?)
+    0x0035 => { #PH
+        Name => 'ExposureCompensation',
+        Writable => 'rational64s',
+    },
+    # 0x0036 - string: "                    "
+    # 0x0037-39 - string: ""
+    0x003a => { #PH (guess!)
+        Name => 'FlashExposureComp',
+        Writable => 'rational64s',
+    },
+    0x003b => { #PH (how is this different from other Firmware?)
+        Name => 'Firmware',
+        Priority => 0,
+    },
+    0x003c => 'WhiteBalance', #PH
+);
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Sigma - Sigma/Foveon EXIF maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to interpret
+Sigma and Foveon maker notes in EXIF information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Sigma Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/SigmaRaw.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/SigmaRaw.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/SigmaRaw.pm	(revision 20131)
@@ -0,0 +1,474 @@
+#------------------------------------------------------------------------------
+# File:         SigmaRaw.pm
+#
+# Description:  Read Sigma/Foveon RAW (X3F) meta information
+#
+# Revisions:    10/16/2005 - P. Harvey Created
+#
+# References:   1) http://www.x3f.info/technotes/FileDocs/X3F_Format.pdf
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::SigmaRaw;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.03';
+
+sub ProcessX3FHeader($$$);
+sub ProcessX3FDirectory($$$);
+sub ProcessX3FProperties($$$);
+
+# main X3F sections (plus header stuff)
+%Image::ExifTool::SigmaRaw::Main = (
+    PROCESS_PROC => \&ProcessX3FDirectory,
+    NOTES => 'These tags are used in Sigma and Foveon RAW (.X3F) images.',
+    Header => {
+        SubDirectory => { TagTable => 'Image::ExifTool::SigmaRaw::Header' },
+    },
+    HeaderExt => {
+        SubDirectory => { TagTable => 'Image::ExifTool::SigmaRaw::HeaderExt' },
+    },
+    PROP => {
+        Name => 'Properties',
+        SubDirectory => { TagTable => 'Image::ExifTool::SigmaRaw::Properties' },
+    },
+    IMAG => {
+        Name => 'PreviewImage',
+        Binary => 1,
+    },
+    IMA2 => {
+        Name => 'PreviewImage',
+        Binary => 1,
+    },
+);
+
+# common X3F header structure
+%Image::ExifTool::SigmaRaw::Header = (
+    PROCESS_PROC => \&ProcessX3FHeader,
+    FORMAT => 'int32u',
+    1 => {
+        Name => 'FileVersion',
+        ValueConv => '($val >> 16) . "." . ($val & 0xffff)',
+    },
+    7 => 'ImageWidth',
+    8 => 'ImageHeight',
+    9 => 'Rotation',
+    10 => {
+        Name => 'WhiteBalance',
+        Format => 'string[32]',
+    },
+);
+
+# extended header tags
+%Image::ExifTool::SigmaRaw::HeaderExt = (
+    GROUPS => { 2 => 'Camera' },
+    NOTES => 'Extended header data found in version 2.1 and 2.2 files',
+    0 => 'Unused',
+    1 => { Name => 'ExposureAdjust',PrintConv => 'sprintf("%.2f",$val)' },
+    2 => { Name => 'Contrast',      PrintConv => 'sprintf("%.2f",$val)' },
+    3 => { Name => 'Shadow',        PrintConv => 'sprintf("%.2f",$val)' },
+    4 => { Name => 'Highlight',     PrintConv => 'sprintf("%.2f",$val)' },
+    5 => { Name => 'Saturation',    PrintConv => 'sprintf("%.2f",$val)' },
+    6 => { Name => 'Sharpness',     PrintConv => 'sprintf("%.2f",$val)' },
+    7 => { Name => 'RedAdjust',     PrintConv => 'sprintf("%.2f",$val)' },
+    8 => { Name => 'GreenAdjust',   PrintConv => 'sprintf("%.2f",$val)' },
+    9 => { Name => 'BlueAdjust',    PrintConv => 'sprintf("%.2f",$val)' },
+   10 => { Name => 'X3FillLight',   PrintConv => 'sprintf("%.2f",$val)' },
+);
+
+# PROP tags
+%Image::ExifTool::SigmaRaw::Properties = (
+    PROCESS_PROC => \&ProcessX3FProperties,
+    GROUPS => { 2 => 'Camera' },
+    AEMODE => {
+        Name => 'MeteringMode',
+        PrintConv => {
+            8 => '8-segment',
+            C => 'Center-weighted average',
+            A => 'Average',
+        },
+    },
+    AFAREA      => 'AFArea', # observed: CENTER_V
+    AFINFOCUS   => 'AFInFocus', # observed: H
+    AFMODE      => 'FocusMode',
+    AP_DESC     => 'ApertureDisplayed',
+    APERTURE => {
+        Name => 'FNumber',
+        Groups => { 2 => 'Image' },
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    BRACKET     => 'BracketShot',
+    BURST       => 'BurstShot',
+    CAMMANUF    => 'Make',
+    CAMMODEL    => 'Model',
+    CAMNAME     => 'CameraName',
+    CAMSERIAL   => 'SerialNumber',
+    COLORSPACE  => 'ColorSpace', # observed: sRGB
+    DRIVE => {
+        Name => 'DriveMode',
+        PrintConv => {
+            SINGLE => 'Single Shot',
+            MULTI  => 'Multi Shot',
+            '2S'   => '2-sec Timer',
+            '10S'  => '10-sec Timer',
+            UP     => 'Mirror Up',
+            AB     => 'Auto Bracket',
+            OFF    => 'Off',
+        },
+    },
+    EVAL_STATE  => 'EvalState', # observed: POST-EXPOSURE
+    EXPCOMP => {
+        Name => 'ExposureCompensation',
+        Groups => { 2 => 'Image' },
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    EXPNET => {
+        Name => 'NetExposureCompensation',
+        Groups => { 2 => 'Image' },
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    EXPTIME => {
+        Name => 'IntegrationTime',
+        Groups => { 2 => 'Image' },
+        ValueConv => '$val * 1e-6', # convert from usec
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    FIRMVERS    => 'FirmwareVersion',
+    FLASH => {
+        Name => 'FlashMode',
+        PrintConv => 'ucfirst(lc($val))',
+    },
+    FLASHEXPCOMP=> 'FlashExpComp',
+    FLASHPOWER  => 'FlashPower',
+    FLASHTTLMODE=> 'FlashTTLMode', # observed: ON
+    FLASHTYPE   => 'FlashType', # observed: NONE
+    FLENGTH => {
+        Name => 'FocalLength',
+        PrintConv => 'sprintf("%.1fmm",$val)',
+    },
+    FLEQ35MM    => 'FocalLengthIn35mmFormat',
+    FOCUS => {
+        Name => 'Focus',
+        PrintConv => {
+            AF => 'Auto-focus Locked',
+           'NO LOCK' => "Auto-focus Didn't Lock",
+            M => 'Manual',
+        },
+    },
+    IMAGERBOARDID => 'ImagerBoardID',
+    IMAGERTEMP  => 'SensorTemperature',
+    ISO         => 'ISO',
+    LENSARANGE  => 'LensApertureRange',
+    LENSFRANGE  => 'LensFocalRange',
+    LENSMODEL   => 'LensID',
+    PMODE => {
+        Name => 'ExposureProgram',
+        PrintConv => {
+            P => 'Program',
+            A => 'Aperture Priority',
+            S => 'Shutter Priority',
+            M => 'Manual',
+        },
+    },
+    RESOLUTION => {
+        Name => 'Quality',
+        PrintConv => {
+            LOW => 'Low',
+            MED => 'Medium',
+            HI  => 'High',
+        },
+    },
+    SENSORID    => 'SensorID',
+    SH_DESC     => 'ShutterSpeedDisplayed',
+    SHUTTER => {
+        Name => 'ExposureTime',
+        Groups => { 2 => 'Image' },
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    TIME => {
+        Name => 'DateTimeOriginal',
+        Groups => { 2 => 'Time' },
+        Description => 'Date/Time Original',
+        ValueConv => 'ConvertUnixTime($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    WB_DESC     => 'WhiteBalance',
+    VERSION_BF  => 'VersionBF',
+);
+
+#------------------------------------------------------------------------------
+# Extract null-terminated unicode string from list of characters
+# Inputs: 0) ExifTool object ref, 1) list ref, 2) position in list
+# Returns: Converted string
+sub ExtractUnicodeString($$$)
+{
+    my ($exifTool, $chars, $pos) = @_;
+    my $i;
+    for ($i=$pos; $i<@$chars; ++$i) {
+        last unless $$chars[$i];
+    }
+    my $buff = pack('v*',@$chars[$pos..$i-1]);
+    my $val = $exifTool->Unicode2Charset($buff, 'II');
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Process an X3F header
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) tag table ref
+# Returns: 1 on success
+sub ProcessX3FHeader($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $verbose = $exifTool->Options('Verbose');
+
+    # process the static header structure first
+    $exifTool->ProcessBinaryData($dirInfo, $tagTablePtr);
+
+    # process extended data if available
+    if ($$dirInfo{DirLen} >= 232) {
+        $verbose and $exifTool->VerboseDir('X3F HeaderExt', 32);
+        $tagTablePtr = GetTagTable('Image::ExifTool::SigmaRaw::HeaderExt');
+        my $dataPt = $$dirInfo{DataPt};
+        my @vals = unpack('x72C32V32', $$dataPt);
+        my $i;
+        my $unused = 0;
+        for ($i=0; $i<32; ++$i) {
+            $vals[$i] or ++$unused, next;
+            my $val = $vals[$i+32];
+            # convert value 0x40000000 => 2 ** 1, 0x3f800000 => 2 ** 0, 0x3f000000 => 2 ** -1
+            if ($val) {
+                my $sign;
+                if ($val & 0x80000000) {
+                    $sign = -1;
+                    $val &= 0x7fffffff;
+                } else {
+                    $sign = 1;
+                }
+                $val = $sign * 2 ** (($val - 0x3f800000) / 0x800000);
+            }
+            $exifTool->HandleTag($tagTablePtr, $vals[$i], $val,
+                Index => $i,
+                DataPt => $dataPt,
+                Start => 104 + $i * 4,
+                Size => 4,
+            );
+        }
+        $exifTool->VPrint(0, "$exifTool->{INDENT}($unused entries unused)\n");
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process an X3F properties
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) tag table ref
+# Returns: 1 on success
+sub ProcessX3FProperties($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $size = length($$dataPt);
+    my $verbose = $exifTool->Options('Verbose');
+    my $unknown = $exifTool->Options('Unknown');
+
+    unless ($size >= 24 and $$dataPt =~ /^SECp/) {
+        $exifTool->Warn('Bad properties header');
+        return 0;
+    }
+    my ($entries, $fmt, $len) = unpack('x8V2x4V', $$dataPt);
+    unless ($size >= 24 + 8 * $entries + $len) {
+        $exifTool->Warn('Truncated Property directory');
+        return 0;
+    }
+    $verbose and $exifTool->VerboseDir('Properties', $entries);
+    $fmt == 0 or $exifTool->Warn("Unsupported character format $fmt"), return 0;
+    my $charPos = 24 + 8 * $entries;
+    my @chars = unpack('v*',substr($$dataPt, $charPos, $len * 2));
+    my $index;
+    for ($index=0; $index<$entries; ++$index) {
+        my ($namePos, $valPos) = unpack('V2',substr($$dataPt, $index*8 + 24, 8));
+        if ($namePos >= @chars or $valPos >= @chars) {
+            $exifTool->Warn('Bad Property pointer');
+            return 0;
+        }
+        my $tag = ExtractUnicodeString($exifTool, \@chars, $namePos);
+        my $val = ExtractUnicodeString($exifTool, \@chars, $valPos);
+        if (not $$tagTablePtr{$tag} and $unknown and $tag =~ /^\w+$/) {
+            my $tagInfo = {
+                Name => "SigmaRaw_$tag",
+                Description => Image::ExifTool::MakeDescription('SigmaRaw', $tag),
+                Unknown => 1,
+                Writable => 0,  # can't write unknown tags
+            };
+            # add tag information to table
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        
+        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            Index => $index,
+            DataPt => $dataPt,
+            Start => $charPos + 2 * $valPos,
+            Size => 2 * (length($val) + 1),
+        );
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process an X3F directory
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) tag table ref
+# Returns: error string or undef on success
+sub ProcessX3FDirectory($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->Options('Verbose');
+
+    $raf->Seek($$dirInfo{DirStart}, 0) or return 'Error seeking to directory start';
+
+    # parse the X3F directory structure
+    my ($buff, $ver, $entries, $index);
+    $raf->Read($buff, 12) == 12 or return 'Truncated X3F image';
+    $buff =~ /^SECd/ or return 'Bad section header';
+    ($ver, $entries) = unpack('x4V2', $buff);
+    $verbose and $exifTool->VerboseDir('X3F Subsection', $entries);
+    my $dir;
+    $raf->Read($dir, $entries * 12) == $entries * 12 or return 'Truncated X3F directory';
+    for ($index=0; $index<$entries; ++$index) {
+        my $pos = $index * 12;
+        my ($offset, $len, $tag) = unpack("x${pos}V2a4", $dir);
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        if ($verbose) {
+            $exifTool->VPrint(0, "$exifTool->{INDENT}$index) $tag Subsection ($len bytes):\n");
+            if ($verbose > 2) {
+                $raf->Seek($offset, 0) or return 'Error seeking';
+                my $n = $verbose > 3 ? $len : 64;
+                $n = $len if $n > $len;
+                $raf->Read($buff, $n) == $n or return 'Truncated image';
+                Image::ExifTool::HexDump(\$buff, undef,
+                    Prefix => $exifTool->{INDENT},
+                    Out => $exifTool->Options('TextOut'),
+                );
+            }
+        }
+        next unless $tagInfo;
+        $raf->Seek($offset, 0) or return "Error seeking for $$tagInfo{Name}";
+        if  ($$tagInfo{Name} eq 'PreviewImage') {
+            # check image header to see if this is a JPEG preview image
+            $raf->Read($buff, 28) == 28 or return 'Error reading PreviewImage header';
+            # igore all image data but JPEG compressed (type 18)
+            next unless $buff =~ /^SECi.{4}\x02\0\0\0\x12/s;
+            $len -= 28;
+        }
+        $raf->Read($buff, $len) == $len or return "Error reading $$tagInfo{Name} data";
+        my $subdir = $$tagInfo{SubDirectory};
+        if ($subdir) {
+            my %dirInfo = ( DataPt => \$buff );
+            my $subTable = GetTagTable($$subdir{TagTable});
+            $exifTool->ProcessDirectory(\%dirInfo, $subTable);
+        } else {
+            $exifTool->FoundTag($tagInfo, $buff);
+        }
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Extract information from a Sigma raw (X3F) image
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid X3F image
+sub ProcessX3F($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+
+    return 0 unless $raf->Read($buff, 40) == 40;
+    return 0 unless $buff =~ /^FOVb/;
+
+    SetByteOrder('II');
+    $exifTool->SetFileType();
+
+    # check version number
+    my $ver = unpack('x4V',$buff);
+    $ver = ($ver >> 16) . '.' . ($ver & 0xffff);
+    if ($ver >= 3) {
+        $exifTool->Warn("Can't read version $ver X3F image");
+        return 1;
+    }
+    # read version 2.1/2.2 extended header
+    if ($ver > 2) {
+        my $buf2;
+        unless ($raf->Read($buf2, 192) == 192) {
+            $exifTool->Warn('Error reading extended header');
+            return 1;
+        }
+        $buff .= $buf2;
+    }
+    # process header information
+    my $tagTablePtr = GetTagTable('Image::ExifTool::SigmaRaw::Main');
+    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, 'Header');
+    my $subdir = GetTagTable('Image::ExifTool::SigmaRaw::Header');
+    my %dirInfo = (
+        DataPt => \$buff,
+        DirStart => 0,
+        DirLen => length($buff),
+    );
+    $exifTool->ProcessDirectory(\%dirInfo, $subdir);
+    # read the directory pointer
+    $raf->Seek(-4, 2);
+    unless ($raf->Read($buff, 4) == 4) {
+        $exifTool->Warn('Error reading X3F dir pointer');
+        return 1;
+    }
+    my $offset = unpack('V', $buff);
+    %dirInfo = (
+        RAF => $raf,
+        DirStart => $offset,
+    );
+    # process the X3F subsections
+    my $err = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+    $err and $exifTool->Warn($err);
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::SigmaRaw - Read Sigma/Foveon RAW (X3F) meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read
+Sigma and Foveon X3F images.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.x3f.info/technotes/FileDocs/X3F_Format.pdf>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/SigmaRaw Tags>,
+L<Image::ExifTool::Sigma(3pm)|Image::ExifTool::Sigma>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Sony.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Sony.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Sony.pm	(revision 20131)
@@ -0,0 +1,421 @@
+#------------------------------------------------------------------------------
+# File:         Sony.pm
+#
+# Description:  Sony EXIF Maker Notes tags
+#
+# Revisions:    04/06/2004  - P. Harvey Created
+#
+# References:   1) http://www.cybercom.net/~dcoffin/dcraw/
+#               2) http://homepage3.nifty.com/kamisaka/makernote/makernote_sony.htm
+#               3) Thomas Bodenmann private communication
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Sony;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+use Image::ExifTool::Minolta;
+
+$VERSION = '1.10';
+
+sub ProcessSRF($$$);
+sub ProcessSR2($$$);
+
+my %sonyLensIDs;    # filled in based on Minolta LensID's
+
+%Image::ExifTool::Sony::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x0e00 => {
+        Name => 'PrintIM',
+        Description => 'Print Image Matching',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+    # 0xb020 string with observed values "Standard", "None" and "Real"
+    0xb021 => { #2
+        Name => 'ColorTemperature',
+        PrintConv => '$val ? $val : "Auto"',
+    },
+    0xb023 => { #PH (A100)
+        Name => 'SceneMode',
+        PrintConv => {
+            0 => 'Manual (P,A,S or M)',
+            1 => 'Portrait',
+            4 => 'Sunset',
+            5 => 'Sports',
+            6 => 'Landscape',
+            8 => 'Macro',
+            16 => 'Auto',
+            17 => 'Night Portrait',
+        },
+    },
+    0xb024 => { #PH (A100)
+        Name => 'ZoneMatching',
+        PrintConv => {
+            0 => 'ISO Setting Used',
+            1 => 'High Key',
+            2 => 'Low Key',
+        },
+    },
+    0xb025 => { #PH (A100)
+        Name => 'DynamicRangeOptimizer',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Standard',
+            2 => 'Advanced',
+        },
+    },
+    0xb026 => { #PH (A100)
+        Name => 'ImageStabilization',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0xb027 => { #2
+        Name => 'LensID',
+        PrintConv => \%sonyLensIDs,
+    },
+    0xb028 => { #2
+        # (used by the DSLR-A100)
+        Name => 'MinoltaMakerNote',
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Minolta::Main',
+            Start => '$val',
+        },
+    },
+    0xb029 => { #2
+        Name => 'ColorMode',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Vivid',
+            2 => 'Portrait',
+            3 => 'Landscape',
+            4 => 'Sunset',
+            5 => 'Night Scene',
+            6 => 'B&W',
+            7 => 'Adobe RGB',
+        },
+    },
+    0xb040 => { #2
+        Name => 'Macro',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0xb041 => { #2
+        Name => 'ExposureMode',
+        PrintConv => {
+            0 => 'Auto',
+            5 => 'Landscape',
+            6 => 'Program',
+            7 => 'Aperture Priority',
+            8 => 'Shutter Priority',
+            9 => 'Night Scene',
+            15 => 'Manual',
+        },
+    },
+    0xb047 => { #2
+        Name => 'Quality',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Fine',
+        },
+    },
+    0xb04e => { #2
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+);
+
+# tag table for Sony RAW Format
+%Image::ExifTool::Sony::SRF = (
+    PROCESS_PROC => \&ProcessSRF,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'SRF#', 2 => 'Camera' },
+    NOTES => q{
+        The maker notes in SRF (Sony Raw Format) images contain 7 IFD's (with family
+        1 group names SRF0 through SRF6).  SRF0 through SRF5 use these Sony tags,
+        while SRF6 uses standard EXIF tags.  All information other than SRF0 is
+        encrypted, but thanks to Dave Coffin the decryption algorithm is known.
+    },
+    0 => {
+        Name => 'SRF2_Key',
+        Notes => 'key to decrypt maker notes from the start of SRF2',
+        RawConv => '$self->{SRF2_Key} = $val',
+    },
+    1 => {
+        Name => 'DataKey',
+        Notes => 'key to decrypt the rest of the file from the end of the maker notes',
+        RawConv => '$self->{SRFDataKey} = $val',
+    },
+);
+
+# tag table for Sony RAW 2 Format Private IFD (ref 1)
+%Image::ExifTool::Sony::SR2Private = (
+    PROCESS_PROC => \&ProcessSR2,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'SR2', 2 => 'Camera' },
+    NOTES => q{
+        The SR2 format uses the DNGPrivateData tag to reference a private IFD
+        containing these tags.
+    },
+    0x7200 => {
+        Name => 'SR2SubIFDOffset',
+        # (adjusting offset messes up calculations for AdobeSR2 in DNG images)
+        # Flags => 'IsOffset',
+        OffsetPair => 0x7201,
+        RawConv => '$self->{SR2SubIFDOffset} = $val',
+    },
+    0x7201 => {
+        Name => 'SR2SubIFDLength',
+        OffsetPair => 0x7200,
+        RawConv => '$self->{SR2SubIFDLength} = $val',
+    },
+    0x7221 => {
+        Name => 'SR2SubIFDKey',
+        Format => 'int32u',
+        Notes => 'key to decrypt SR2SubIFD',
+        RawConv => '$self->{SR2SubIFDKey} = $val',
+    },
+);
+
+%Image::ExifTool::Sony::SR2SubIFD = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'SR2', 2 => 'Camera' },
+    NOTES => 'Tags in the encrypted SR2SubIFD',
+    0x7303 => 'WB_GRBGLevels', #1
+    0x74c0 => { #PH
+        Name => 'SR2DataIFD',
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sony::SR2DataIFD',
+            Start => '$val',
+            MaxSubdirs => 6,
+        },
+    },
+    0x74a0 => 'MaxApertureAtMaxFocal', #PH
+    0x74a1 => 'MaxApertureAtMinFocal', #PH
+);
+
+%Image::ExifTool::Sony::SR2DataIFD = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'SR2', 2 => 'Camera' },
+    0x7770 => 'ColorMode', #PH
+);
+
+# fill in Sony LensID lookup based on Minolta values
+{
+    my $id;
+    foreach $id (keys %Image::ExifTool::Minolta::minoltaLensIDs) {
+        # higher numbered lenses are missing last digit of ID
+        my $sonyID = ($id < 10000) ? $id : int($id / 10);
+        $sonyLensIDs{$sonyID} = $Image::ExifTool::Minolta::minoltaLensIDs{$id};
+    }
+}
+
+#------------------------------------------------------------------------------
+# decrypt Sony data (ref 1)
+# Inputs: 0) data reference, 1) start offset, 2) data length, 3) decryption key
+# Returns: nothing (original data buffer is updated with decrypted data)
+sub Decrypt($$$$)
+{
+    my ($dataPt, $start, $len, $key) = @_;
+    my ($i, $j, @pad);
+    my $words = $len / 4;
+
+    for ($i=0; $i<4; ++$i) {
+        my $lo = ($key & 0xffff) * 0x0edd + 1;
+        my $hi = ($key >> 16) * 0x0edd + ($key & 0xffff) * 0x02e9 + ($lo >> 16);
+        $pad[$i] = $key = (($hi & 0xffff) << 16) + ($lo & 0xffff);
+    }
+    $pad[3] = ($pad[3] << 1 | ($pad[0]^$pad[2]) >> 31) & 0xffffffff;
+    for ($i=4; $i<0x7f; ++$i) {
+        $pad[$i] = (($pad[$i-4]^$pad[$i-2]) << 1 |
+                    ($pad[$i-3]^$pad[$i-1]) >> 31) & 0xffffffff;
+    }
+    my @data = unpack("x$start N$words", $$dataPt);
+    for ($i=0x7f,$j=0; $j<$words; ++$i,++$j) {
+        $data[$j] ^= $pad[$i & 0x7f] = $pad[($i+1) & 0x7f] ^ $pad[($i+65) & 0x7f];
+    }
+    substr($$dataPt, $start, $words*4) = pack('N*', @data);
+}
+
+#------------------------------------------------------------------------------
+# Process SRF maker notes
+# Inputs: 0) ExifTool object reference, 1) reference to directory information
+#         2) pointer to tag table
+# Returns: 1 on success
+sub ProcessSRF($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirLen = $$dirInfo{DirLen};
+    my $start = $$dirInfo{DirStart};
+    my $verbose = $exifTool->Options('Verbose');
+
+    # process IFD chain
+    my ($ifd, $success);
+    for ($ifd=0; ; ) {
+        my $srf = $$dirInfo{DirName} = "SRF$ifd";
+        my $srfTable = $tagTablePtr;
+        # SRF6 uses standard EXIF tags
+        $srfTable = GetTagTable('Image::ExifTool::Exif::Main') if $ifd == 6;
+        $exifTool->{SET_GROUP1} = $srf;
+        $success = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $srfTable);
+        delete $exifTool->{SET_GROUP1};
+        last unless $success;
+#
+# get pointer to next IFD
+#
+        my $count = Get16u($dataPt, $$dirInfo{DirStart});
+        my $dirEnd = $$dirInfo{DirStart} + 2 + $count * 12;
+        last if $dirEnd + 4 > length($$dataPt);
+        my $nextIFD = Get32u($dataPt, $dirEnd);
+        last unless $nextIFD;
+        $nextIFD -= $$dirInfo{DataPos}; # adjust for position of makernotes data
+        $$dirInfo{DirStart} = $nextIFD;
+#
+# decrypt next IFD data if necessary
+#
+        ++$ifd;
+        my ($key, $len);
+        if ($ifd == 1) {
+            # get the key to decrypt IFD1
+            my $cp = $start + 0x8ddc;    # why?
+            my $ip = $cp + 4 * unpack("x$cp C", $$dataPt);
+            $key = unpack("x$ip N", $$dataPt);
+            $len = $cp + $nextIFD;  # decrypt up to $cp
+        } elsif ($ifd == 2) {
+            # get the key to decrypt IFD2
+            $key = $exifTool->{SRF2_Key};
+            $len = length($$dataPt) - $nextIFD; # decrypt rest of maker notes
+        } else {
+            next;   # no decryption needed
+        }
+        # decrypt data
+        Decrypt($dataPt, $nextIFD, $len, $key) if defined $key;
+        next unless $verbose > 2;
+        # display decrypted data in verbose mode
+        $exifTool->VerboseDir("Decrypted SRF$ifd", 0, $nextIFD + $len);
+        my %parms = (
+            Prefix => "$exifTool->{INDENT}  ",
+            Start => $nextIFD,
+            DataPos => $$dirInfo{DataPos},
+            Out => $exifTool->Options('TextOut'),
+        );
+        $parms{MaxLen} = 96 unless $verbose > 3;
+        Image::ExifTool::HexDump($dataPt, $len, %parms);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Process SR2 data
+# Inputs: 0) ExifTool object reference, 1) reference to directory information
+#         2) pointer to tag table
+# Returns: 1 on success
+sub ProcessSR2($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{DataPos};
+    my $dataLen = $$dirInfo{DataLen} || length $$dataPt;
+    my $dirLen = $$dirInfo{DirLen};
+    my $verbose = $exifTool->Options('Verbose');
+    my $result = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
+    return $result unless $result;
+    my $offset = $exifTool->{SR2SubIFDOffset};
+    my $length = $exifTool->{SR2SubIFDLength};
+    my $key = $exifTool->{SR2SubIFDKey};
+    my $raf = $$dirInfo{RAF};
+    my $base = $$dirInfo{Base} || 0;
+    if ($offset and $length and defined $key) {
+        my $buff;
+        # read encrypted SR2SubIFD from file
+        if (($raf and $raf->Seek($offset+$base, 0) and
+                $raf->Read($buff, $length) == $length) or
+            # or read from data (when processing Adobe DNGPrivateData)
+            ($offset - $dataPos >= 0 and $offset - $dataPos + $length < $dataLen and 
+                ($buff = substr($$dataPt, $offset - $dataPos, $length))))
+        {
+            Decrypt(\$buff, 0, $length, $key);
+            # display decrypted data in verbose mode
+            if ($verbose > 2) {
+                $exifTool->VerboseDir("Decrypted SR2SubIFD", 0, $length);
+                my %parms = (
+                    Out => $exifTool->{OPTIONS}->{TextOut},
+                    Prefix => $exifTool->{INDENT},
+                    Addr => $offset + $base,
+                );
+                $parms{MaxLen} = 96 unless $verbose > 3;
+                Image::ExifTool::HexDump(\$buff, $length, %parms);
+            }
+            my %dirInfo = (
+                Base => $base,
+                DataPt => \$buff,
+                DataLen => length $buff,
+                DirStart => 0,
+                DirName => 'SR2SubIFD',
+                DataPos => $offset,
+            );
+            my $subTable = Image::ExifTool::GetTagTable('Image::ExifTool::Sony::SR2SubIFD');
+            $result = $exifTool->ProcessDirectory(\%dirInfo, $subTable);
+
+        } else {
+            $exifTool->Warn('Error reading SR2 data');
+        }
+    }
+    delete $exifTool->{SR2SubIFDOffset};
+    delete $exifTool->{SR2SubIFDLength};
+    delete $exifTool->{SR2SubIFDKey};
+    return $result;
+}
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Sony - Sony EXIF maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to
+interpret Sony maker notes EXIF meta information.
+
+=head1 NOTES
+
+The Sony maker notes use the standard EXIF IFD structure, but unfortunately
+the entries are large blocks of binary data for which I can find no
+documentation.  You can use "exiftool -v3" to dump these blocks in hex.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.cybercom.net/~dcoffin/dcraw/>
+
+=item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_sony.htm>
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Thomas Bodenmann for providing information about the LensID's.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Sony Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/TagLookup.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/TagLookup.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/TagLookup.pm	(revision 20131)
@@ -0,0 +1,3875 @@
+#------------------------------------------------------------------------------
+# File:         TagLookup.pm
+#
+# Description:  Fast lookup for ExifTool tags
+#
+# Notes:        This lookup is used to look up tag names for writing
+#
+# Revisions:    12/31/2004  - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::TagLookup;
+
+use strict;
+require Exporter;
+
+use vars qw($VERSION @ISA @EXPORT_OK);
+use Image::ExifTool qw(:Utils);
+
+$VERSION = '1.04';
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(FindTagInfo TagExists);
+
+#
+# Note: the lists below were generated by Image::ExifTool::BuildTagLookup
+#
+
+#++++ Begin automatically generated code ++++
+
+# list of tables containing writable tags
+my @tableList = (
+	'Image::ExifTool::APP12::Ducky',
+	'Image::ExifTool::Canon::CameraInfo',
+	'Image::ExifTool::Canon::CameraInfo1DmkIII',
+	'Image::ExifTool::Canon::CameraInfo2',
+	'Image::ExifTool::Canon::CameraSettings',
+	'Image::ExifTool::Canon::ColorBalance',
+	'Image::ExifTool::Canon::ColorBalance1',
+	'Image::ExifTool::Canon::ColorBalance2',
+	'Image::ExifTool::Canon::ColorBalance3',
+	'Image::ExifTool::Canon::ColorInfo',
+	'Image::ExifTool::Canon::ColorInfoD30',
+	'Image::ExifTool::Canon::FaceDetect1',
+	'Image::ExifTool::Canon::FaceDetect2',
+	'Image::ExifTool::Canon::FileInfo',
+	'Image::ExifTool::Canon::Flags',
+	'Image::ExifTool::Canon::FocalLength',
+	'Image::ExifTool::Canon::Main',
+	'Image::ExifTool::Canon::ModifiedInfo',
+	'Image::ExifTool::Canon::MyColors',
+	'Image::ExifTool::Canon::Panorama',
+	'Image::ExifTool::Canon::PreviewImageInfo',
+	'Image::ExifTool::Canon::Processing',
+	'Image::ExifTool::Canon::ShotInfo',
+	'Image::ExifTool::CanonCustom::Functions10D',
+	'Image::ExifTool::CanonCustom::Functions1D',
+	'Image::ExifTool::CanonCustom::Functions2',
+	'Image::ExifTool::CanonCustom::Functions20D',
+	'Image::ExifTool::CanonCustom::Functions30D',
+	'Image::ExifTool::CanonCustom::Functions350D',
+	'Image::ExifTool::CanonCustom::Functions400D',
+	'Image::ExifTool::CanonCustom::Functions5D',
+	'Image::ExifTool::CanonCustom::FunctionsD30',
+	'Image::ExifTool::CanonCustom::PersonalFuncValues',
+	'Image::ExifTool::CanonCustom::PersonalFuncs',
+	'Image::ExifTool::CanonRaw::ExposureInfo',
+	'Image::ExifTool::CanonRaw::FlashInfo',
+	'Image::ExifTool::CanonRaw::ImageFormat',
+	'Image::ExifTool::CanonRaw::ImageInfo',
+	'Image::ExifTool::CanonRaw::Main',
+	'Image::ExifTool::CanonRaw::MakeModel',
+	'Image::ExifTool::CanonRaw::RawJpgInfo',
+	'Image::ExifTool::CanonRaw::TimeStamp',
+	'Image::ExifTool::CanonVRD::Ver1',
+	'Image::ExifTool::CanonVRD::Ver2',
+	'Image::ExifTool::Casio::Main',
+	'Image::ExifTool::Casio::Type2',
+	'Image::ExifTool::Composite',
+	'Image::ExifTool::DNG::AdobeData',
+	'Image::ExifTool::Exif::Main',
+	'Image::ExifTool::Extra',
+	'Image::ExifTool::FotoStation::Main',
+	'Image::ExifTool::FotoStation::SoftEdit',
+	'Image::ExifTool::FujiFilm::Main',
+	'Image::ExifTool::GPS::Main',
+	'Image::ExifTool::IPTC::ApplicationRecord',
+	'Image::ExifTool::IPTC::EnvelopeRecord',
+	'Image::ExifTool::IPTC::NewsPhoto',
+	'Image::ExifTool::JFIF::Main',
+	'Image::ExifTool::Kodak::CameraInfo',
+	'Image::ExifTool::Kodak::Main',
+	'Image::ExifTool::Kodak::SubIFD0',
+	'Image::ExifTool::Kodak::SubIFD1',
+	'Image::ExifTool::Kodak::SubIFD2',
+	'Image::ExifTool::Kodak::SubIFD3',
+	'Image::ExifTool::Kodak::SubIFD5',
+	'Image::ExifTool::Kodak::Type2',
+	'Image::ExifTool::Kodak::Type3',
+	'Image::ExifTool::Kodak::Type4',
+	'Image::ExifTool::Kodak::Type7',
+	'Image::ExifTool::MIE::Audio',
+	'Image::ExifTool::MIE::Camera',
+	'Image::ExifTool::MIE::Doc',
+	'Image::ExifTool::MIE::Extender',
+	'Image::ExifTool::MIE::Flash',
+	'Image::ExifTool::MIE::GPS',
+	'Image::ExifTool::MIE::Geo',
+	'Image::ExifTool::MIE::Image',
+	'Image::ExifTool::MIE::Lens',
+	'Image::ExifTool::MIE::Main',
+	'Image::ExifTool::MIE::Orient',
+	'Image::ExifTool::MIE::Preview',
+	'Image::ExifTool::MIE::Thumbnail',
+	'Image::ExifTool::MIE::UTM',
+	'Image::ExifTool::MIE::Video',
+	'Image::ExifTool::Minolta::CameraSettings',
+	'Image::ExifTool::Minolta::CameraSettings5D',
+	'Image::ExifTool::Minolta::CameraSettings7D',
+	'Image::ExifTool::Minolta::CameraSettingsA100',
+	'Image::ExifTool::Minolta::Main',
+	'Image::ExifTool::MinoltaRaw::PRD',
+	'Image::ExifTool::MinoltaRaw::RIF',
+	'Image::ExifTool::MinoltaRaw::WBG',
+	'Image::ExifTool::Nikon::AFInfo',
+	'Image::ExifTool::Nikon::ColorBalance1',
+	'Image::ExifTool::Nikon::ColorBalance2',
+	'Image::ExifTool::Nikon::ColorBalance3',
+	'Image::ExifTool::Nikon::GEM',
+	'Image::ExifTool::Nikon::LensData00',
+	'Image::ExifTool::Nikon::Main',
+	'Image::ExifTool::Nikon::MultiExposure',
+	'Image::ExifTool::Nikon::PreviewImage',
+	'Image::ExifTool::Nikon::ROC',
+	'Image::ExifTool::Nikon::Scan',
+	'Image::ExifTool::Nikon::Type2',
+	'Image::ExifTool::NikonCapture::Brightness',
+	'Image::ExifTool::NikonCapture::ColorBoost',
+	'Image::ExifTool::NikonCapture::CropData',
+	'Image::ExifTool::NikonCapture::DLightingHQ',
+	'Image::ExifTool::NikonCapture::DLightingHS',
+	'Image::ExifTool::NikonCapture::Main',
+	'Image::ExifTool::NikonCapture::NoiseReduction',
+	'Image::ExifTool::NikonCapture::PhotoEffects',
+	'Image::ExifTool::NikonCapture::RedEyeData',
+	'Image::ExifTool::NikonCapture::UnsharpData',
+	'Image::ExifTool::NikonCapture::WBAdjData',
+	'Image::ExifTool::Olympus::CameraSettings',
+	'Image::ExifTool::Olympus::Equipment',
+	'Image::ExifTool::Olympus::FETags',
+	'Image::ExifTool::Olympus::FocusInfo',
+	'Image::ExifTool::Olympus::ImageProcessing',
+	'Image::ExifTool::Olympus::Main',
+	'Image::ExifTool::Olympus::RawDevelopment',
+	'Image::ExifTool::Olympus::RawDevelopment2',
+	'Image::ExifTool::Olympus::RawInfo',
+	'Image::ExifTool::PNG::Main',
+	'Image::ExifTool::PNG::TextualData',
+	'Image::ExifTool::Panasonic::Main',
+	'Image::ExifTool::Panasonic::Raw',
+	'Image::ExifTool::Pentax::AEInfo',
+	'Image::ExifTool::Pentax::AFInfo',
+	'Image::ExifTool::Pentax::BatteryInfo',
+	'Image::ExifTool::Pentax::CameraInfo',
+	'Image::ExifTool::Pentax::FlashInfo',
+	'Image::ExifTool::Pentax::LensInfo',
+	'Image::ExifTool::Pentax::Main',
+	'Image::ExifTool::Pentax::SRInfo',
+	'Image::ExifTool::Pentax::Type2',
+	'Image::ExifTool::PhotoMechanic::SoftEdit',
+	'Image::ExifTool::PhotoMechanic::XMP',
+	'Image::ExifTool::Photoshop::JPEG_Quality',
+	'Image::ExifTool::Photoshop::Main',
+	'Image::ExifTool::Photoshop::Resolution',
+	'Image::ExifTool::PostScript::Main',
+	'Image::ExifTool::Ricoh::ImageInfo',
+	'Image::ExifTool::Ricoh::Main',
+	'Image::ExifTool::Sanyo::Main',
+	'Image::ExifTool::Sigma::Main',
+	'Image::ExifTool::Sony::Main',
+	'Image::ExifTool::XMP::DICOM',
+	'Image::ExifTool::XMP::Lightroom',
+	'Image::ExifTool::XMP::MediaPro',
+	'Image::ExifTool::XMP::Microsoft',
+	'Image::ExifTool::XMP::aux',
+	'Image::ExifTool::XMP::cc',
+	'Image::ExifTool::XMP::crs',
+	'Image::ExifTool::XMP::dc',
+	'Image::ExifTool::XMP::dex',
+	'Image::ExifTool::XMP::exif',
+	'Image::ExifTool::XMP::iptcCore',
+	'Image::ExifTool::XMP::pdf',
+	'Image::ExifTool::XMP::photoshop',
+	'Image::ExifTool::XMP::tiff',
+	'Image::ExifTool::XMP::xmp',
+	'Image::ExifTool::XMP::xmpBJ',
+	'Image::ExifTool::XMP::xmpDM',
+	'Image::ExifTool::XMP::xmpMM',
+	'Image::ExifTool::XMP::xmpPLUS',
+	'Image::ExifTool::XMP::xmpRights',
+	'Image::ExifTool::XMP::xmpTPg',
+);
+
+# lookup for all writable tags
+my %tagLookup = (
+	'abspeakaudiofilepath' => { 164 => 'absPeakAudioFilePath' },
+	'accessorytype' => { 126 => 0x53 },
+	'actionadvised' => { 54 => 0x2a },
+	'activearea' => { 48 => 0xc68d },
+	'addaspectratioinfo' => { 25 => 0x80e },
+	'addoriginaldecisiondata' => { 25 => 0x80f, 26 => 0x11, 27 => 0x13, 30 => 0x14 },
+	'address' => { 75 => 'Address' },
+	'adjustmentmode' => { 146 => [0x15,0x22] },
+	'advancedraw' => { 109 => 0x76a43203 },
+	'advisory' => { 162 => 'Advisory' },
+	'ae_iso' => { 128 => 0x2 },
+	'aeaperture' => { 128 => 0x1 },
+	'aebautocancel' => { 25 => 0x104 },
+	'aebbracketvalue' => { 22 => 0x11 },
+	'aebsequence' => { 23 => 0x9, 24 => 0x9, 25 => 0x105, 26 => 0x8, 27 => 0x9, 30 => 0x9, 31 => 0x7 },
+	'aebshotcount' => { 25 => 0x106 },
+	'aebxv' => { 128 => 0x4 },
+	'aeexposuretime' => { 128 => 0x0 },
+	'aeextra' => { 128 => 0x7 },
+	'aeflashtv' => { 128 => 0x5 },
+	'aelock' => { 115 => 0x201 },
+	'aemeteringsegments' => { 134 => 0x209 },
+	'aeprogrammode' => { 128 => 0x6 },
+	'aesetting' => { 4 => 0x21 },
+	'aexv' => { 128 => 0x3 },
+	'afareamode' => { 92 => 0x0 },
+	'afareas' => { 115 => 0x304 },
+	'afassist' => { 23 => 0x5, 31 => 0x5 },
+	'afassistbeam' => { 25 => 0x50e, 26 => 0x4, 27 => 0x5, 28 => 0x4, 29 => 0x4, 30 => 0x5 },
+	'afduringliveview' => { 25 => 0x511 },
+	'afexpansionwithselectedpoint' => { 25 => 0x508 },
+	'afmicroadjustment' => { 25 => 0x507 },
+	'afmode' => { 126 => 0xf, 146 => 0x5 },
+	'afonaelockbuttonswitch' => { 25 => 0x702 },
+	'afpoint' => { 4 => 0x13, 44 => 0x18, 92 => 0x1, 118 => 0x308 },
+	'afpointactivationarea' => { 24 => 0x11, 30 => 0x11 },
+	'afpointautoselection' => { 25 => 0x50b },
+	'afpointbrightness' => { 25 => 0x50d },
+	'afpointdisplayduringfocus' => { 25 => 0x50c },
+	'afpointillumination' => { 24 => 0xa },
+	'afpointregistration' => { 23 => 0x7 },
+	'afpoints' => { 86 => 0x10 },
+	'afpointselected' => { 134 => 0xe },
+	'afpointselection' => { 24 => 0xb },
+	'afpointselectionmethod' => { 25 => 0x50f, 26 => 0xc, 27 => 0xd, 30 => 0xd },
+	'afpointsinfocus' => { 22 => 0xe, 92 => 0x2, 129 => 0xb, 134 => [0xf,0x3c] },
+	'afpointsinfocus5d' => { 1 => 0x38 },
+	'afpointspotmetering' => { 24 => 0xd },
+	'afresponse' => { 98 => 0xad },
+	'afresult' => { 120 => 0x1038 },
+	'afsearch' => { 115 => 0x303 },
+	'aiservoimagepriority' => { 25 => 0x503 },
+	'aiservotrackingmethod' => { 25 => 0x504 },
+	'aiservotrackingsensitivity' => { 24 => 0x14, 25 => 0x502 },
+	'album' => { 164 => 'album' },
+	'alreadyapplied' => { 154 => 'AlreadyApplied' },
+	'alttapename' => { 164 => 'altTapeName' },
+	'alttimecodetimeformat' => { 164 => 'altTimecodeTimeFormat' },
+	'alttimecodetimevalue' => { 164 => 'altTimecodeTimeValue' },
+	'antialiasstrength' => { 48 => 0xc632 },
+	'aperturerange' => { 25 => 0x10d },
+	'aperturevalue' => { 48 => 0x9202, 120 => 0x1002, 157 => 'ApertureValue' },
+	'applicationrecordversion' => { 54 => 0x0 },
+	'applyshootingmeteringmode' => { 25 => 0x10e },
+	'armidentifier' => { 55 => 0x78 },
+	'armversion' => { 55 => 0x7a },
+	'artist' => { 48 => 0x13b, 125 => 'Artist', 161 => 'Artist', 164 => 'artist' },
+	'asshoticcprofile' => { 48 => 0xc68f },
+	'asshotpreprofilematrix' => { 48 => 0xc690 },
+	'asshotwhitexy' => { 48 => 0xc629 },
+	'assistbuttonfunction' => { 23 => 0xd },
+	'audio' => { 126 => 0x20 },
+	'audiochanneltype' => { 164 => 'audioChannelType' },
+	'audiocompression' => { 69 => 'Compression' },
+	'audiocompressor' => { 164 => 'audioCompressor' },
+	'audioduration' => { 54 => 0x99 },
+	'audiomoddate' => { 164 => 'audioModDate' },
+	'audiooutcue' => { 54 => 0x9a },
+	'audiosamplerate' => { 164 => 'audioSampleRate' },
+	'audiosampletype' => { 164 => 'audioSampleType' },
+	'audiosamplingrate' => { 54 => 0x97 },
+	'audiosamplingresolution' => { 54 => 0x98 },
+	'audiotype' => { 54 => 0x96 },
+	'author' => { 71 => 'Author', 125 => 'Author', 142 => 'Author', 159 => 'Author' },
+	'authorsposition' => { 160 => 'AuthorsPosition' },
+	'autobracket' => { 146 => 0x19 },
+	'autobracketing' => { 52 => 0x1100, 134 => 0x18 },
+	'autobracketrelease' => { 98 => 0x8a },
+	'autobrightness' => { 154 => 'AutoBrightness' },
+	'autocontrast' => { 154 => 'AutoContrast' },
+	'autoexposure' => { 154 => 'AutoExposure' },
+	'autoexposurebracketing' => { 22 => 0x10 },
+	'autofocus' => { 118 => 0x209 },
+	'autoiso' => { 22 => 0x1, 45 => 0x3008 },
+	'autorotate' => { 22 => 0x1b },
+	'autoshadows' => { 154 => 'AutoShadows' },
+	'auxiliarylens' => { 98 => 0x82 },
+	'avsettingwithoutlens' => { 25 => 0x707 },
+	'avvalue' => { 34 => 0x2 },
+	'azimuth' => { 79 => 'Azimuth' },
+	'babyage' => { 126 => [0x8010,0x33] },
+	'baseiso' => { 22 => 0x2, 38 => 0x101c },
+	'baselineexposure' => { 48 => 0xc62a },
+	'baselinenoise' => { 48 => 0xc62b },
+	'baselinesharpness' => { 48 => 0xc62c },
+	'baseurl' => { 162 => 'BaseURL' },
+	'batteryadbodyload' => { 130 => 0x3 },
+	'batteryadbodynoload' => { 130 => 0x2 },
+	'batteryadgripload' => { 130 => 0x5 },
+	'batteryadgripnoload' => { 130 => 0x4 },
+	'batterybodygripstates' => { 130 => 0x1 },
+	'batterytype' => { 130 => 0x0 },
+	'bayergreensplit' => { 48 => 0xc62d },
+	'bayerpattern' => { 58 => 0xf902, 89 => 0x17 },
+	'beatspliceparamsriseindecibel' => { 164 => 'beatSpliceParamsRiseInDecibel' },
+	'beatspliceparamsriseintimeduration' => { 164 => 'beatSpliceParamsRiseInTimeDuration' },
+	'beatspliceparamsusefilebeatsmarker' => { 164 => 'beatSpliceParamsUseFileBeatsMarker' },
+	'bestqualityscale' => { 48 => 0xc65c },
+	'bestshotmode' => { 45 => 0x3007 },
+	'bitdepth' => { 76 => 'BitDepth', 89 => 0x11, 102 => 0x41 },
+	'bitspercomponent' => { 56 => 0x87 },
+	'bitspersample' => { 48 => 0x102, 161 => 'BitsPerSample' },
+	'blacklevel' => { 120 => 0x1012 },
+	'blacklevel2' => { 123 => 0x600 },
+	'blackpoint' => { 134 => 0x200 },
+	'bluebalance' => { 120 => 0x1018, 127 => 0x12, 134 => 0x1b },
+	'bluecurvelimits' => { 42 => 0x1fe },
+	'bluecurvepoints' => { 42 => 0x1d4 },
+	'bluehue' => { 154 => 'BlueHue' },
+	'bluesaturation' => { 154 => 'BlueSaturation' },
+	'blurwarning' => { 52 => 0x1300 },
+	'bodyfirmwareversion' => { 116 => 0x104, 117 => 0x100, 120 => 0x104 },
+	'bracketmode' => { 13 => 0x3 },
+	'bracketsequence' => { 45 => 0x301d },
+	'bracketshotnumber' => { 13 => 0x5 },
+	'bracketstep' => { 84 => 0xe },
+	'bracketvalue' => { 13 => 0x4 },
+	'brightness' => { 48 => 0xfe53, 70 => 'Brightness', 84 => 0x2c, 154 => 'Brightness' },
+	'brightnessadj' => { 42 => 0x114, 104 => 0x0 },
+	'brightnessvalue' => { 48 => 0x9203, 120 => 0x1003, 157 => 'BrightnessValue' },
+	'bulbduration' => { 22 => 0x18 },
+	'burstmode' => { 59 => 0xa, 126 => 0x2a },
+	'burstmode2' => { 59 => 0x18 },
+	'buttonfunctioncontroloff' => { 25 => 0x70a },
+	'bwfilter' => { 84 => 0x2a, 90 => 0x39 },
+	'bwmode' => { 120 => 0x203 },
+	'by-line' => { 54 => 0x50 },
+	'by-linetitle' => { 54 => 0x55 },
+	'calibrationilluminant1' => { 48 => 0xc65a },
+	'calibrationilluminant2' => { 48 => 0xc65b },
+	'cameraid' => { 120 => 0x209, 145 => 0x209 },
+	'cameraiso' => { 4 => 0x10 },
+	'cameraparameters' => { 120 => 0x2050 },
+	'cameraprofile' => { 154 => 'CameraProfile' },
+	'cameraprofiledigest' => { 154 => 'CameraProfileDigest' },
+	'cameraserialnumber' => { 48 => 0xc62f, 151 => 'CameraSerialNumber' },
+	'camerasettingsversion' => { 115 => 0x0 },
+	'cameratemperature' => { 134 => 0x47 },
+	'cameratype' => { 22 => 0x1a, 120 => 0x207 },
+	'cameratype2' => { 116 => 0x100 },
+	'canonexposuremode' => { 4 => 0x14 },
+	'canonfiledescription' => { 38 => 0x805 },
+	'canonfilelength' => { 16 => 0xe },
+	'canonfirmwareversion' => { 16 => 0x7, 38 => 0x80b },
+	'canonflashinfo' => { 38 => 0x1028 },
+	'canonflashmode' => { 4 => 0x4 },
+	'canonimagesize' => { 4 => 0xa },
+	'canonimagetype' => { 16 => 0x6, 38 => 0x815 },
+	'canonmodelid' => { 16 => 0x10, 38 => 0x1834 },
+	'canonvrd' => { 49 => 'CanonVRD' },
+	'caption-abstract' => { 54 => 0x78 },
+	'captionwriter' => { 160 => 'CaptionWriter' },
+	'casioimagesize' => { 45 => 0x9 },
+	'catalogsets' => { 150 => 'CatalogSets' },
+	'category' => { 54 => 0xf, 160 => 'Category' },
+	'ccdscanmode' => { 120 => 0x1039 },
+	'ccdsensitivity' => { 103 => 0x6 },
+	'celllength' => { 48 => 0x109 },
+	'cellwidth' => { 48 => 0x108 },
+	'certificate' => { 167 => 'Certificate' },
+	'cfapattern' => { 48 => 0xa302 },
+	'cfapatterncolumns' => { 157 => 'CFAPatternColumns' },
+	'cfapatternrows' => { 157 => 'CFAPatternRows' },
+	'cfapatternvalues' => { 157 => 'CFAPatternValues' },
+	'channels' => { 69 => 'Channels' },
+	'checkmark' => { 42 => 0x26a },
+	'chromablurradius' => { 48 => 0xc631 },
+	'chromaticaberrationb' => { 154 => 'ChromaticAberrationB' },
+	'chromaticaberrationr' => { 154 => 'ChromaticAberrationR' },
+	'chrominancenoisereduction' => { 43 => 0xbc },
+	'chrominancenr_tiff_jpeg' => { 43 => 0xc0 },
+	'city' => { 54 => 0x5a, 75 => 'City', 160 => 'City' },
+	'clarity' => { 154 => 'Clarity' },
+	'classifystate' => { 54 => 0xe1 },
+	'cmcontrast' => { 123 => 0x2022 },
+	'cmexposurecompensation' => { 123 => 0x2000 },
+	'cmhue' => { 123 => 0x2021 },
+	'cmsaturation' => { 123 => 0x2020 },
+	'cmsharpness' => { 123 => 0x2023 },
+	'cmwhitebalance' => { 123 => 0x2001 },
+	'cmwhitebalancecomp' => { 123 => 0x2002 },
+	'cmwhitebalancegraypoint' => { 123 => 0x2010 },
+	'codec' => { 83 => 'Codec' },
+	'codedcharacterset' => { 55 => 0x5a },
+	'coloraberrationcontrol' => { 109 => 0xc89224b },
+	'coloradjustment' => { 146 => 0x14 },
+	'coloradjustmentmode' => { 145 => 0x210 },
+	'colorantsa' => { 168 => 'ColorantsA' },
+	'colorantsb' => { 168 => 'ColorantsB' },
+	'colorantsblack' => { 168 => 'ColorantsBlack' },
+	'colorantsblue' => { 168 => 'ColorantsBlue' },
+	'colorantscyan' => { 168 => 'ColorantsCyan' },
+	'colorantsgreen' => { 168 => 'ColorantsGreen' },
+	'colorantsl' => { 168 => 'ColorantsL' },
+	'colorantsmagenta' => { 168 => 'ColorantsMagenta' },
+	'colorantsmode' => { 168 => 'ColorantsMode' },
+	'colorantsred' => { 168 => 'ColorantsRed' },
+	'colorantsswatchname' => { 168 => 'ColorantsSwatchName' },
+	'colorantstype' => { 168 => 'ColorantsType' },
+	'colorantsyellow' => { 168 => 'ColorantsYellow' },
+	'colorbalance' => { 70 => 'ColorBalance' },
+	'colorbalance1' => { 98 => 0xc },
+	'colorbalanceadj' => { 109 => 0x76a43202 },
+	'colorbalanceblue' => { 84 => 0x1e },
+	'colorbalancegreen' => { 84 => 0x1d },
+	'colorbalancered' => { 84 => 0x1c },
+	'colorbooster' => { 109 => 0x5f0e7d23 },
+	'colorboostlevel' => { 105 => 0x1 },
+	'colorboosttype' => { 105 => 0x0 },
+	'colorclass' => { 137 => 0xde },
+	'colorcontrol' => { 120 => 0x102b },
+	'coloreffect' => { 126 => 0x28 },
+	'colorfilter' => { 44 => 0x17, 84 => 0x29, 90 => 0x38, 136 => 0x17 },
+	'colorgain' => { 102 => 0x51 },
+	'colorhue' => { 9 => 0x2, 98 => 0x8d },
+	'colormatrix' => { 10 => 0xa, 119 => 0x200, 120 => 0x1011 },
+	'colormatrix2' => { 123 => 0x200 },
+	'colormatrixnumber' => { 120 => 0x1019 },
+	'colormode' => { 45 => 0x3015, 52 => 0x1210, 59 => 0x66, 84 => 0x28, 87 => 0x16, 88 => 0x101, 90 => 0x7, 98 => 0x3, 103 => 0x4, 120 => 0x101, 126 => 0x32, 147 => 0xb029, 160 => 'ColorMode' },
+	'colormoirereduction' => { 110 => 0x5 },
+	'colornoisereduction' => { 154 => 'ColorNoiseReduction' },
+	'colorplanes' => { 51 => 0x2 },
+	'colorprofile' => { 84 => 0x33 },
+	'colorrepresentation' => { 56 => 0x3c },
+	'colorsequence' => { 56 => 0x41 },
+	'colorspace' => { 9 => 0x3, 16 => 0xb4, 38 => 0x10b4, 48 => 0xa001, 76 => 'ColorSpace', 86 => 0x25, 98 => 0x1e, 115 => 0x507, 134 => 0x37, 146 => 0xb, 157 => 'ColorSpace' },
+	'colortempasshot' => { 6 => 0x1d, 7 => 0x1c, 8 => 0x43 },
+	'colortempauto' => { 6 => 0x22, 7 => 0x26, 8 => 0x48 },
+	'colortempcloudy' => { 6 => 0x31, 7 => 0x35, 8 => 0x5c },
+	'colortempcustom' => { 8 => 0x84 },
+	'colortempcustom1' => { 6 => 0x45 },
+	'colortempcustom2' => { 6 => 0x4a },
+	'colortempdaylight' => { 6 => 0x27, 7 => 0x2b, 8 => 0x52 },
+	'colortemperature' => { 10 => 0x9, 16 => 0xae, 21 => 0x9, 38 => 0x10ae, 52 => 0x1005, 70 => 'ColorTemperature', 85 => [0x6e,0x49], 86 => 0x3f, 87 => 0x5e, 88 => 0x10b, 90 => 0x3c },
+	'colortemperaturebg' => { 120 => 0x1013 },
+	'colortemperaturerg' => { 120 => 0x1014 },
+	'colortempflash' => { 6 => 0x40, 7 => 0x49, 8 => 0x70 },
+	'colortempfluorescent' => { 6 => 0x3b, 7 => 0x3f, 8 => 0x66 },
+	'colortempkelvin' => { 7 => 0x44, 8 => 0x6b },
+	'colortempmeasured' => { 8 => 0x4d },
+	'colortemppc1' => { 7 => 0x94, 8 => 0x75 },
+	'colortemppc2' => { 7 => 0x99, 8 => 0x7a },
+	'colortemppc3' => { 7 => 0x9e, 8 => 0x7f },
+	'colortempshade' => { 6 => 0x2c, 7 => 0x30, 8 => 0x57 },
+	'colortemptungsten' => { 6 => 0x36, 7 => 0x3a, 8 => 0x61 },
+	'colortempunknown' => { 7 => 0x21 },
+	'colortempunknown10' => { 7 => 0x76 },
+	'colortempunknown11' => { 7 => 0x7b },
+	'colortempunknown12' => { 7 => 0x80 },
+	'colortempunknown13' => { 7 => 0x85 },
+	'colortempunknown14' => { 7 => 0x8a },
+	'colortempunknown15' => { 7 => 0x8f },
+	'colortempunknown16' => { 7 => 0xa3 },
+	'colortempunknown2' => { 7 => 0x4e },
+	'colortempunknown3' => { 7 => 0x53 },
+	'colortempunknown4' => { 7 => 0x58 },
+	'colortempunknown5' => { 7 => 0x5d },
+	'colortempunknown6' => { 7 => 0x62 },
+	'colortempunknown7' => { 7 => 0x67 },
+	'colortempunknown8' => { 7 => 0x6c },
+	'colortempunknown9' => { 7 => 0x71 },
+	'colortone' => { 4 => 0x2a },
+	'colortoneadj' => { 42 => 0x11e },
+	'colortonefaithful' => { 1 => 0x107 },
+	'colortonelandscape' => { 1 => 0x105 },
+	'colortoneneutral' => { 1 => 0x106 },
+	'colortoneportrait' => { 1 => 0x104 },
+	'colortonestandard' => { 1 => 0x103 },
+	'colortoneuserdef1' => { 1 => 0x109 },
+	'colortoneuserdef2' => { 1 => 0x10a },
+	'colortoneuserdef3' => { 1 => 0x10b },
+	'comment' => { 0 => 0x2, 49 => 'Comment', 71 => 'Comment', 125 => 'Comment' },
+	'componentsconfiguration' => { 48 => 0x9101, 76 => 'Components', 157 => 'ComponentsConfiguration' },
+	'componentversion' => { 38 => 0x80c },
+	'composer' => { 164 => 'composer' },
+	'compressedbitsperpixel' => { 48 => 0x9102, 157 => 'CompressedBitsPerPixel' },
+	'compressedimagesize' => { 88 => 0x40, 120 => 0x40 },
+	'compression' => { 48 => 0x103, 161 => 'Compression' },
+	'compressionfactor' => { 115 => 0x50d },
+	'compressionratio' => { 76 => 'Compression', 120 => 0x1034 },
+	'constrainedcropheight' => { 42 => 0x266, 137 => 0xd6 },
+	'constrainedcropwidth' => { 42 => 0x262, 137 => 0xd5 },
+	'contact' => { 54 => 0x76 },
+	'contentlocationcode' => { 54 => 0x1a },
+	'contentlocationname' => { 54 => 0x1b },
+	'continuousdrive' => { 4 => 0x5 },
+	'continuousshootingspeed' => { 25 => 0x610 },
+	'continuousshotlimit' => { 25 => 0x611 },
+	'contrast' => { 4 => 0xd, 44 => 0xc, 45 => [0x3012,0x20], 48 => [0xa408,0xfe54], 52 => 0x1004, 70 => 'Contrast', 84 => 0x20, 85 => 0x31, 86 => 0x27, 87 => 0x19, 90 => 0x2, 120 => 0x1029, 126 => 0x2c, 134 => 0x20, 136 => 0xc, 146 => 0xd, 154 => 'Contrast', 157 => 'Contrast' },
+	'contrastadj' => { 42 => 0x115 },
+	'contrastfaithful' => { 1 => 0xec },
+	'contrastlandscape' => { 1 => 0xea },
+	'contrastmonochrome' => { 1 => 0xed },
+	'contrastneutral' => { 1 => 0xeb },
+	'contrastportrait' => { 1 => 0xe9 },
+	'contrastsetting' => { 115 => 0x505, 123 => 0x1012 },
+	'contraststandard' => { 1 => 0xe8 },
+	'contrastuserdef1' => { 1 => 0xee },
+	'contrastuserdef2' => { 1 => 0xef },
+	'contrastuserdef3' => { 1 => 0xf0 },
+	'contributedmediaduration' => { 164 => 'contributedMediaDuration' },
+	'contributedmediamanaged' => { 164 => 'contributedMediaManaged' },
+	'contributedmediapath' => { 164 => 'contributedMediaPath' },
+	'contributedmediastarttime' => { 164 => 'contributedMediaStartTime' },
+	'contributedmediatrack' => { 164 => 'contributedMediaTrack' },
+	'contributedmediawebstatement' => { 164 => 'contributedMediaWebStatement' },
+	'contributor' => { 155 => 'contributor' },
+	'contributors' => { 71 => 'Contributors' },
+	'conversionlens' => { 126 => 0x35 },
+	'converter' => { 48 => 0xfe4d, 103 => 0xb },
+	'converttograyscale' => { 154 => 'ConvertToGrayscale' },
+	'copyright' => { 0 => 0x3, 48 => 0x8298, 71 => 'Copyright', 125 => 'Copyright', 142 => 'Copyright', 161 => 'Copyright', 164 => 'copyright' },
+	'copyrightflag' => { 140 => 0x40a },
+	'copyrightnotice' => { 54 => 0x74 },
+	'coringfilter' => { 120 => 0x102d, 123 => 0x310 },
+	'coringvalues' => { 123 => 0x311 },
+	'country' => { 75 => 'Country', 160 => 'Country' },
+	'country-primarylocationcode' => { 54 => 0x64 },
+	'country-primarylocationname' => { 54 => 0x65 },
+	'countrycode' => { 138 => 'CountryCode', 158 => 'CountryCode' },
+	'coverage' => { 155 => 'coverage' },
+	'crc32' => { 156 => 'crc32' },
+	'createdate' => { 48 => 0x9004, 71 => 'CreateDate', 142 => 'CreationDate', 162 => 'CreateDate' },
+	'creationdate' => { 159 => 'CreationDate' },
+	'creationtime' => { 125 => 'Creation Time' },
+	'creator' => { 142 => 'Creator', 155 => 'creator', 159 => 'Creator' },
+	'creatorcontactinfociadrcity' => { 158 => 'CreatorContactInfoCiAdrCity' },
+	'creatorcontactinfociadrctry' => { 158 => 'CreatorContactInfoCiAdrCtry' },
+	'creatorcontactinfociadrextadr' => { 158 => 'CreatorContactInfoCiAdrExtadr' },
+	'creatorcontactinfociadrpcode' => { 158 => 'CreatorContactInfoCiAdrPcode' },
+	'creatorcontactinfociadrregion' => { 158 => 'CreatorContactInfoCiAdrRegion' },
+	'creatorcontactinfociemailwork' => { 158 => 'CreatorContactInfoCiEmailWork' },
+	'creatorcontactinfocitelwork' => { 158 => 'CreatorContactInfoCiTelWork' },
+	'creatorcontactinfociurlwork' => { 158 => 'CreatorContactInfoCiUrlWork' },
+	'creatortool' => { 162 => 'CreatorTool' },
+	'credit' => { 54 => 0x6e, 160 => 'Credit' },
+	'creditlinereq' => { 166 => 'CreditLineReq' },
+	'cropactive' => { 42 => 0x244 },
+	'cropangle' => { 154 => 'CropAngle' },
+	'cropaspectratio' => { 42 => 0x260 },
+	'cropbottom' => { 51 => 0x9, 106 => 0x36, 137 => 0xdc, 154 => 'CropBottom' },
+	'cropheight' => { 42 => 0x24c, 154 => 'CropHeight' },
+	'crophispeed' => { 98 => 0x1b },
+	'cropleft' => { 42 => 0x246, 51 => 0x6, 106 => 0x1e, 137 => 0xd9, 154 => 'CropLeft' },
+	'cropoutputscale' => { 106 => 0xbe },
+	'cropright' => { 51 => 0x8, 106 => 0x2e, 137 => 0xdb, 154 => 'CropRight' },
+	'croprotation' => { 51 => 0xb },
+	'croptop' => { 42 => 0x248, 51 => 0x7, 106 => 0x26, 137 => 0xda, 154 => 'CropTop' },
+	'cropunits' => { 154 => 'CropUnits' },
+	'cropwidth' => { 42 => 0x24a, 154 => 'CropWidth' },
+	'currenticcprofile' => { 48 => 0xc691 },
+	'currentpreprofilematrix' => { 48 => 0xc692 },
+	'curves' => { 109 => 0x76a43201 },
+	'customrendered' => { 48 => 0xa401, 157 => 'CustomRendered' },
+	'customsaturation' => { 115 => 0x503 },
+	'd-lightinghq' => { 109 => 0x2175eb78 },
+	'd-lightinghqselected' => { 109 => 0x6a6e36b6 },
+	'd-lightinghs' => { 109 => 0xce5554aa },
+	'd-lightinghsadjustment' => { 108 => 0x0 },
+	'd-lightinghscolorboost' => { 107 => 0x2, 108 => 0x1 },
+	'd-lightinghshighlight' => { 107 => 0x1 },
+	'd-lightinghsshadow' => { 107 => 0x0 },
+	'datacompressionmethod' => { 56 => 0x6e },
+	'dataimprint' => { 84 => 0x34 },
+	'date' => { 134 => 0x6, 155 => 'date' },
+	'dateacquired' => { 151 => 'DateAcquired' },
+	'datecreated' => { 54 => 0x37, 160 => 'DateCreated' },
+	'datesent' => { 55 => 0x46 },
+	'datestampmode' => { 16 => 0x1c },
+	'datetime' => { 161 => 'DateTime' },
+	'datetimedigitized' => { 157 => 'DateTimeDigitized' },
+	'datetimeoriginal' => { 41 => 0x0, 48 => 0x9003, 71 => 'OriginalDate', 157 => 'DateTimeOriginal' },
+	'datetimestamp' => { 59 => 0x64 },
+	'declination' => { 79 => 'Declination' },
+	'decposition' => { 84 => 0x32 },
+	'defaultcroporigin' => { 48 => 0xc61f },
+	'defaultcropsize' => { 48 => 0xc620 },
+	'defaultscale' => { 48 => 0xc61e },
+	'defringe' => { 154 => 'Defringe' },
+	'deletedimagecount' => { 98 => 0xa6 },
+	'derivedfromdocumentid' => { 165 => 'DerivedFromDocumentID' },
+	'derivedfrominstanceid' => { 165 => 'DerivedFromInstanceID' },
+	'derivedfrommanager' => { 165 => 'DerivedFromManager' },
+	'derivedfrommanagervariant' => { 165 => 'DerivedFromManagerVariant' },
+	'derivedfrommanageto' => { 165 => 'DerivedFromManageTo' },
+	'derivedfrommanageui' => { 165 => 'DerivedFromManageUI' },
+	'derivedfromrenditionclass' => { 165 => 'DerivedFromRenditionClass' },
+	'derivedfromrenditionparams' => { 165 => 'DerivedFromRenditionParams' },
+	'derivedfromversionid' => { 165 => 'DerivedFromVersionID' },
+	'description' => { 125 => 'Description', 155 => 'description' },
+	'destination' => { 55 => 0x5 },
+	'destinationcity' => { 134 => 0x24 },
+	'destinationcitycode' => { 136 => 0x1001 },
+	'destinationdst' => { 134 => 0x26 },
+	'developmentdynamicrange' => { 52 => 0x1403 },
+	'devicesettingdescriptioncolumns' => { 157 => 'DeviceSettingDescriptionColumns' },
+	'devicesettingdescriptionrows' => { 157 => 'DeviceSettingDescriptionRows' },
+	'devicesettingdescriptionsettings' => { 157 => 'DeviceSettingDescriptionSettings' },
+	'dialdirectiontvav' => { 25 => 0x706 },
+	'digitalcreationdate' => { 54 => 0x3e },
+	'digitalcreationtime' => { 54 => 0x3f },
+	'digitalgain' => { 21 => 0xb },
+	'digitalgem' => { 96 => 0x0 },
+	'digitalice' => { 102 => 0x100 },
+	'digitalroc' => { 101 => 0x0 },
+	'digitalzoom' => { 4 => 0xc, 44 => 0xa, 59 => 0x68, 70 => 'DigitalZoom', 84 => 0xc, 98 => 0x86, 103 => 0xa, 120 => 0x204, 134 => 0x1e, 136 => 0xa, 145 => 0x204 },
+	'digitalzoomon' => { 145 => 0x21b },
+	'digitalzoomratio' => { 48 => 0xa404, 157 => 'DigitalZoomRatio' },
+	'directory' => { 49 => 'Directory' },
+	'disclaimer' => { 125 => 'Disclaimer' },
+	'displayaperture' => { 4 => 0x23 },
+	'displayedunitsx' => { 141 => 0x2 },
+	'displayedunitsy' => { 141 => 0x6 },
+	'distance1' => { 59 => 0x28 },
+	'distance2' => { 59 => 0x2c },
+	'distance3' => { 59 => 0x30 },
+	'distance4' => { 59 => 0x34 },
+	'distortioncorrection' => { 115 => 0x50b },
+	'distortioncorrection2' => { 119 => 0x1011 },
+	'dngbackwardversion' => { 48 => 0xc613 },
+	'dnglensinfo' => { 48 => 0xc630 },
+	'dngversion' => { 48 => 0xc612 },
+	'document' => { 125 => 'Document' },
+	'documenthistory' => { 54 => 0xe7 },
+	'documentid' => { 165 => 'DocumentID' },
+	'documentname' => { 48 => 0x10d },
+	'documentnotes' => { 54 => 0xe6 },
+	'dotrange' => { 48 => 0x150 },
+	'drivemode' => { 84 => 0x6, 87 => 0x1e, 115 => 0x600, 134 => 0x34, 146 => 0x3 },
+	'duration' => { 69 => 'Duration', 83 => 'Duration', 164 => 'duration' },
+	'dynamicrange' => { 52 => 0x1400 },
+	'dynamicrangemax' => { 42 => 0x7c },
+	'dynamicrangemin' => { 42 => 0x7a },
+	'dynamicrangesetting' => { 52 => 0x1402 },
+	'easymode' => { 4 => 0xb },
+	'edgenoisereduction' => { 110 => 0x4 },
+	'editorialupdate' => { 54 => 0x8 },
+	'editstatus' => { 54 => 0x7, 138 => 'EditStatus' },
+	'elevation' => { 79 => 'Elevation' },
+	'email' => { 71 => 'EMail' },
+	'engineer' => { 164 => 'engineer' },
+	'enhancedarktones' => { 104 => 0x8 },
+	'enhancement' => { 44 => 0x16, 45 => 0x3016 },
+	'envelopenumber' => { 55 => 0x28 },
+	'envelopepriority' => { 55 => 0x3c },
+	'enveloperecordversion' => { 55 => 0x0 },
+	'epsonimageheight' => { 120 => 0x20c },
+	'epsonimagewidth' => { 120 => 0x20b },
+	'epsonsoftware' => { 120 => 0x20d },
+	'equipmentinstitution' => { 148 => 'EquipmentInstitution' },
+	'equipmentmanufacturer' => { 148 => 'EquipmentManufacturer' },
+	'equipmentversion' => { 116 => 0x0 },
+	'ettlii' => { 25 => 0x304, 26 => 0xd, 27 => 0xe, 28 => 0x7, 29 => 0x7, 30 => 0xe },
+	'event' => { 150 => 'Event' },
+	'excursiontolerance' => { 56 => 0x82 },
+	'exifbyteorder' => { 49 => 'ExifByteOrder' },
+	'exifcamerainfo' => { 54 => 0xe8 },
+	'exifimagelength' => { 48 => 0xa003, 157 => 'PixelYDimension' },
+	'exifimagewidth' => { 48 => 0xa002, 157 => 'PixelXDimension' },
+	'exifversion' => { 48 => 0x9000, 157 => 'ExifVersion' },
+	'expirationdate' => { 54 => 0x25 },
+	'expirationtime' => { 54 => 0x26 },
+	'exposure' => { 48 => 0xfe51, 154 => 'Exposure' },
+	'exposurebracketvalue' => { 98 => 0x19 },
+	'exposurecompensation' => { 22 => 0x6, 34 => 0x0, 48 => 0x9204, 59 => 0x24, 70 => 'ExposureComp', 84 => 0xd, 85 => 0x53, 86 => 0x1e, 87 => 0x1, 120 => 0x1006, 134 => 0x16, 146 => [0xc,0x35], 157 => 'ExposureBiasValue' },
+	'exposuredifference' => { 98 => 0xe },
+	'exposureindex' => { 48 => 0xa215, 157 => 'ExposureIndex' },
+	'exposurelevelincrements' => { 23 => 0x6, 24 => 0x6, 25 => 0x101, 26 => 0x5, 27 => 0x6, 28 => 0x5, 29 => 0x5, 30 => 0x6, 31 => 0x4 },
+	'exposuremode' => { 48 => 0xa402, 70 => 'ExposureMode', 84 => 0x1, 85 => 0xa, 86 => 0x0, 87 => 0x0, 115 => 0x200, 146 => 0x8, 157 => 'ExposureMode' },
+	'exposuremodeinmanual' => { 25 => 0x10b },
+	'exposureprogram' => { 48 => 0x8822, 157 => 'ExposureProgram' },
+	'exposuretime' => { 1 => 0x4, 2 => 0x4, 3 => 0x6, 22 => 0x16, 48 => 0x829a, 58 => 0xfd05, 59 => 0x20, 60 => 0xfa24, 62 => 0xf104, 66 => 0x38, 70 => 'ExposureTime', 84 => 0x9, 85 => 0x35, 86 => 0x48, 134 => 0x12, 146 => 0x32, 157 => 'ExposureTime' },
+	'exposurewarning' => { 52 => 0x1302 },
+	'extender' => { 116 => 0x301 },
+	'extenderfirmwareversion' => { 116 => 0x304 },
+	'extendermagnification' => { 72 => 'Magnification' },
+	'extendermake' => { 72 => 'Make' },
+	'extendermodel' => { 72 => 'Model', 116 => 0x303 },
+	'extenderserialnumber' => { 72 => 'SerialNumber', 116 => 0x302 },
+	'externalflash' => { 118 => 0x1201 },
+	'externalflashae1' => { 120 => 0x101f },
+	'externalflashae1_0' => { 120 => 0x101b },
+	'externalflashae2' => { 120 => 0x1020 },
+	'externalflashae2_0' => { 120 => 0x101c },
+	'externalflashbounce' => { 118 => 0x1204, 120 => 0x1026 },
+	'externalflashguidenumber' => { 118 => 0x1203 },
+	'externalflashgvalue' => { 120 => 0x1025 },
+	'externalflashmode' => { 120 => 0x1028, 132 => 0x2 },
+	'externalflashzoom' => { 118 => 0x1205, 120 => 0x1027 },
+	'face0position' => { 11 => 0x8 },
+	'face1position' => { 11 => 0xa },
+	'face2position' => { 11 => 0xc },
+	'face3position' => { 11 => 0xe },
+	'face4position' => { 11 => 0x10 },
+	'face5position' => { 11 => 0x12 },
+	'face6position' => { 11 => 0x14 },
+	'face7position' => { 11 => 0x16 },
+	'face8position' => { 11 => 0x18 },
+	'facedetectframeheight' => { 11 => 0x4 },
+	'facedetectframewidth' => { 11 => 0x3 },
+	'facesdetected' => { 11 => 0x2, 12 => 0x2 },
+	'ffid' => { 156 => 'ffid' },
+	'fieldcount' => { 120 => 0x103f },
+	'filedatarate' => { 164 => 'fileDataRate' },
+	'fileformat' => { 36 => 0x0, 55 => 0x14 },
+	'filemodifydate' => { 49 => 'FileModifyDate' },
+	'filename' => { 49 => 'FileName' },
+	'filenumber' => { 2 => 0x172, 13 => 0x1, 16 => 0x8, 38 => 0x1817 },
+	'filenumbermemory' => { 84 => 0x1a },
+	'filesource' => { 48 => 0xa300, 52 => 0x8000, 157 => 'FileSource' },
+	'fileversion' => { 55 => 0x16 },
+	'fillflashautoreduction' => { 23 => 0xe, 24 => 0xe, 31 => 0xa },
+	'filllight' => { 154 => 'FillLight' },
+	'fillorder' => { 48 => 0x10a },
+	'filmmode' => { 52 => 0x1401, 126 => 0x42 },
+	'filmtype' => { 102 => 0x2 },
+	'filter' => { 45 => 0x3017 },
+	'filtereffect' => { 13 => 0xe },
+	'filtereffectmonochrome' => { 1 => 0xff },
+	'finalimageheight' => { 123 => 0x615 },
+	'finalimagewidth' => { 123 => 0x614 },
+	'finderdisplayduringexposure' => { 24 => 0x1 },
+	'firmware' => { 120 => 0x405, 146 => [0x17,0x3b], 152 => 'Firmware' },
+	'firmwaredate' => { 45 => 0x2001 },
+	'firmwareid' => { 89 => 0x0 },
+	'firmwarerevision' => { 1 => 0xa4, 16 => 0x1e },
+	'firmwareversion' => { 70 => 'FirmwareVersion', 126 => 0x2 },
+	'fixtureidentifier' => { 54 => 0x16 },
+	'flash' => { 48 => 0x9209, 85 => 0x1f, 86 => 0x15 },
+	'flashactivity' => { 4 => 0x1c },
+	'flashadump' => { 134 => 0x20a },
+	'flashbdump' => { 134 => 0x20b },
+	'flashbias' => { 126 => 0x24 },
+	'flashbits' => { 4 => 0x1d },
+	'flashchargelevel' => { 120 => 0x1010 },
+	'flashcompensation' => { 152 => 'FlashCompensation' },
+	'flashdevice' => { 120 => 0x1005 },
+	'flashdistance' => { 45 => 0x2034 },
+	'flashenergy' => { 48 => 0xa20b, 157 => 'FlashEnergy' },
+	'flashexposurebracketvalue' => { 98 => 0x18 },
+	'flashexposurecomp' => { 22 => 0xf, 73 => 'ExposureComp', 84 => 0x23, 88 => 0x104, 98 => 0x12, 120 => 0x1023, 134 => 0x4d, 146 => 0x3a },
+	'flashexposurecompensation' => { 115 => 0x401 },
+	'flashfired' => { 59 => 0x5d, 73 => 'Fired', 84 => 0x14, 157 => 'FlashFired' },
+	'flashfiring' => { 25 => 0x306, 26 => 0x6, 27 => 0x7, 30 => 0x7 },
+	'flashfirmwareversion' => { 116 => 0x1002 },
+	'flashfunction' => { 157 => 'FlashFunction' },
+	'flashguidenumber' => { 22 => 0xd, 35 => 0x0, 73 => 'GuideNumber' },
+	'flashintensity' => { 44 => [0x19,0x5] },
+	'flashmake' => { 73 => 'Make' },
+	'flashmanufacturer' => { 151 => 'FlashManufacturer' },
+	'flashmetering' => { 84 => 0x3f },
+	'flashmode' => { 44 => 0x4, 59 => 0x5c, 73 => 'Mode', 84 => 0x2, 98 => 0x87, 115 => 0x400, 120 => 0x1004, 134 => 0xc, 136 => 0x4, 143 => 0x20, 145 => 0x225, 157 => 'FlashMode' },
+	'flashmodecode' => { 132 => 0x1 },
+	'flashmodel' => { 73 => 'Model', 116 => 0x1001, 151 => 'FlashModel' },
+	'flashoutput' => { 22 => 0x21 },
+	'flashpixversion' => { 48 => 0xa000, 157 => 'FlashpixVersion' },
+	'flashredeyemode' => { 157 => 'FlashRedEyeMode' },
+	'flashreturn' => { 157 => 'FlashReturn' },
+	'flashserialnumber' => { 73 => 'SerialNumber', 116 => 0x1003 },
+	'flashsetting' => { 98 => 0x8 },
+	'flashstatus' => { 132 => 0x0 },
+	'flashstrength' => { 52 => 0x1011 },
+	'flashsyncspeedav' => { 23 => 0x3, 25 => 0x10f, 26 => 0x2, 27 => 0x3, 28 => 0x2, 29 => 0x2, 30 => 0x3, 31 => 0x6 },
+	'flashthreshold' => { 35 => 0x1 },
+	'flashtype' => { 73 => 'Type', 98 => 0x9, 116 => 0x1000 },
+	'flickerreduce' => { 145 => 0x218 },
+	'fliphorizontal' => { 109 => 0x76a43206 },
+	'fnumber' => { 1 => 0x3, 2 => 0x3, 3 => 0x5, 22 => 0x15, 48 => 0x829d, 58 => 0xfd04, 59 => 0x1e, 60 => 0xfa23, 62 => 0xf103, 66 => 0x3c, 77 => 'FNumber', 84 => 0xa, 85 => 0x36, 86 => 0x47, 134 => 0x13, 146 => 0x31, 157 => 'FNumber' },
+	'focallength' => { 1 => 0x9, 2 => 0x1d, 15 => 0x1, 45 => 0x1d, 48 => 0x920a, 77 => 'FocalLength', 84 => 0x12, 134 => 0x1d, 157 => 'FocalLength' },
+	'focallengthin35mmformat' => { 48 => 0xa405, 157 => 'FocalLengthIn35mmFilm' },
+	'focalplanediagonal' => { 116 => 0x103, 120 => 0x205 },
+	'focalplaneresolutionunit' => { 48 => 0xa210, 157 => 'FocalPlaneResolutionUnit' },
+	'focalplanexresolution' => { 48 => 0xa20e, 157 => 'FocalPlaneXResolution' },
+	'focalplanexsize' => { 15 => 0x2 },
+	'focalplaneyresolution' => { 48 => 0xa20f, 157 => 'FocalPlaneYResolution' },
+	'focalplaneysize' => { 15 => 0x3 },
+	'focaltype' => { 1 => 0x2d, 15 => 0x0 },
+	'focalunits' => { 4 => 0x19 },
+	'focus' => { 103 => 0x8 },
+	'focusarea' => { 84 => 0x31 },
+	'focuscontinuous' => { 4 => 0x20 },
+	'focusdistance' => { 77 => 'FocusDistance', 84 => 0x13, 118 => 0x305 },
+	'focusdistancelower' => { 22 => 0x14 },
+	'focusdistanceupper' => { 22 => 0x13 },
+	'focusinfoversion' => { 118 => 0x0 },
+	'focusingscreen' => { 24 => 0x0, 25 => 0x80b, 30 => 0x0 },
+	'focusmode' => { 4 => 0x7, 44 => 0x3, 45 => [0x3003,0xd], 52 => 0x1021, 59 => 0x38, 70 => 'FocusMode', 84 => 0x30, 86 => 0xe, 98 => 0x7, 115 => 0x301, 120 => 0x100b, 126 => 0x7, 134 => 0xd, 136 => 0x3 },
+	'focuspixel' => { 52 => 0x1023 },
+	'focusposition' => { 134 => 0x10 },
+	'focusprocess' => { 115 => 0x302 },
+	'focusrange' => { 4 => 0x12, 120 => 0x100a },
+	'focussetting' => { 146 => 0x6 },
+	'focusstepcount' => { 118 => 0x301, 120 => 0x100e },
+	'focuswarning' => { 52 => 0x1301 },
+	'foldername' => { 84 => 0x27 },
+	'fontschildfontfiles' => { 168 => 'FontsChildFontFiles' },
+	'fontscomposite' => { 168 => 'FontsComposite' },
+	'fontsfontface' => { 168 => 'FontsFontFace' },
+	'fontsfontfamily' => { 168 => 'FontsFontFamily' },
+	'fontsfontfilename' => { 168 => 'FontsFontFileName' },
+	'fontsfontname' => { 168 => 'FontsFontName' },
+	'fontsfonttype' => { 168 => 'FontsFontType' },
+	'fontsversionstring' => { 168 => 'FontsVersionString' },
+	'for' => { 142 => 'For' },
+	'format' => { 155 => 'format' },
+	'framenum' => { 137 => 0xd7 },
+	'framenumber' => { 52 => 0x8003, 134 => 0x29 },
+	'freebytes' => { 38 => 0x1 },
+	'freememorycardimages' => { 85 => [0x37,0x54], 86 => [0x2d,0x4a] },
+	'fujiflashmode' => { 52 => 0x1010 },
+	'fullsizeimage' => { 76 => 'data' },
+	'fullsizeimagename' => { 76 => '1Name' },
+	'fullsizeimagetype' => { 76 => '0Type' },
+	'gaincontrol' => { 48 => 0xa407, 157 => 'GainControl' },
+	'gamma' => { 48 => 0xa500 },
+	'gammacompensatedvalue' => { 56 => 0x91 },
+	'genre' => { 164 => 'genre' },
+	'globalaltitude' => { 140 => 0x419 },
+	'globalangle' => { 140 => 0x40d },
+	'gpsaltitude' => { 53 => 0x6, 74 => 'Altitude', 157 => 'GPSAltitude' },
+	'gpsaltituderef' => { 53 => 0x5, 157 => 'GPSAltitudeRef' },
+	'gpsareainformation' => { 53 => 0x1c, 157 => 'GPSAreaInformation' },
+	'gpsdatestamp' => { 53 => 0x1d },
+	'gpsdatetime' => { 74 => 'DateTime' },
+	'gpsdestbearing' => { 53 => 0x18, 74 => 'Bearing', 157 => 'GPSDestBearing' },
+	'gpsdestbearingref' => { 53 => 0x17, 157 => 'GPSDestBearingRef' },
+	'gpsdestdistance' => { 53 => 0x1a, 74 => 'Distance', 157 => 'GPSDestDistance' },
+	'gpsdestdistanceref' => { 53 => 0x19, 157 => 'GPSDestDistanceRef' },
+	'gpsdestlatitude' => { 53 => 0x14, 157 => 'GPSDestLatitude' },
+	'gpsdestlatituderef' => { 53 => 0x13 },
+	'gpsdestlongitude' => { 53 => 0x16, 157 => 'GPSDestLongitude' },
+	'gpsdestlongituderef' => { 53 => 0x15 },
+	'gpsdifferential' => { 53 => 0x1e, 74 => 'Differential', 157 => 'GPSDifferential' },
+	'gpsdop' => { 53 => 0xb, 157 => 'GPSDOP' },
+	'gpsimgdirection' => { 53 => 0x11, 157 => 'GPSImgDirection' },
+	'gpsimgdirectionref' => { 53 => 0x10, 157 => 'GPSImgDirectionRef' },
+	'gpslatitude' => { 53 => 0x2, 74 => 'Latitude', 157 => 'GPSLatitude' },
+	'gpslatituderef' => { 53 => 0x1 },
+	'gpslongitude' => { 53 => 0x4, 74 => 'Longitude', 157 => 'GPSLongitude' },
+	'gpslongituderef' => { 53 => 0x3 },
+	'gpsmapdatum' => { 53 => 0x12, 74 => 'Datum', 157 => 'GPSMapDatum' },
+	'gpsmeasuremode' => { 53 => 0xa, 74 => 'MeasureMode', 157 => 'GPSMeasureMode' },
+	'gpsprocessingmethod' => { 53 => 0x1b, 157 => 'GPSProcessingMethod' },
+	'gpssatellites' => { 53 => 0x8, 74 => 'Satellites', 157 => 'GPSSatellites' },
+	'gpsspeed' => { 53 => 0xd, 74 => 'Speed', 157 => 'GPSSpeed' },
+	'gpsspeedref' => { 53 => 0xc, 157 => 'GPSSpeedRef' },
+	'gpsstatus' => { 53 => 0x9, 157 => 'GPSStatus' },
+	'gpstimestamp' => { 53 => 0x7, 157 => 'GPSTimeStamp' },
+	'gpstrack' => { 53 => 0xf, 74 => 'Heading', 157 => 'GPSTrack' },
+	'gpstrackref' => { 53 => 0xe, 157 => 'GPSTrackRef' },
+	'gpsversionid' => { 53 => 0x0, 157 => 'GPSVersionID' },
+	'gradation' => { 115 => 0x50f },
+	'grayresponseunit' => { 48 => 0x122 },
+	'greencurvelimits' => { 42 => 0x1c4 },
+	'greencurvepoints' => { 42 => 0x19a },
+	'greenhue' => { 154 => 'GreenHue' },
+	'greensaturation' => { 154 => 'GreenSaturation' },
+	'halftonehints' => { 48 => 0x141 },
+	'hascrop' => { 154 => 'HasCrop' },
+	'hassettings' => { 154 => 'HasSettings' },
+	'headline' => { 54 => 0x69, 160 => 'Headline' },
+	'hierarchicalsubject' => { 149 => 'hierarchicalSubject' },
+	'highisonoisereduction' => { 25 => 0x202, 98 => 0xb1 },
+	'highlight' => { 146 => 0xf },
+	'highlightrecovery' => { 154 => 'HighlightRecovery' },
+	'highlighttonepriority' => { 25 => 0x203 },
+	'history' => { 160 => 'History' },
+	'historyaction' => { 165 => 'HistoryAction' },
+	'historyinstanceid' => { 165 => 'HistoryInstanceID' },
+	'historyparameters' => { 165 => 'HistoryParameters' },
+	'historysoftwareagent' => { 165 => 'HistorySoftwareAgent' },
+	'historywhen' => { 165 => 'HistoryWhen' },
+	'hometowncity' => { 45 => 0x3006, 134 => 0x23 },
+	'hometowncitycode' => { 136 => 0x1000 },
+	'hometowndst' => { 134 => 0x25 },
+	'hostcomputer' => { 48 => 0x13c },
+	'hue' => { 90 => 0x3b },
+	'hueadjustment' => { 98 => 0x92 },
+	'hueadjustmentaqua' => { 154 => 'HueAdjustmentAqua' },
+	'hueadjustmentblue' => { 154 => 'HueAdjustmentBlue' },
+	'hueadjustmentgreen' => { 154 => 'HueAdjustmentGreen' },
+	'hueadjustmentmagenta' => { 154 => 'HueAdjustmentMagenta' },
+	'hueadjustmentorange' => { 154 => 'HueAdjustmentOrange' },
+	'hueadjustmentpurple' => { 154 => 'HueAdjustmentPurple' },
+	'hueadjustmentred' => { 154 => 'HueAdjustmentRed' },
+	'hueadjustmentyellow' => { 154 => 'HueAdjustmentYellow' },
+	'huesetting' => { 123 => 0x1011 },
+	'icc_profile' => { 49 => 'ICC_Profile' },
+	'iccprofilename' => { 160 => 'ICCProfile' },
+	'identifier' => { 155 => 'identifier', 162 => 'Identifier' },
+	'imageadjustment' => { 98 => 0x80, 103 => 0x5 },
+	'imageareaoffset' => { 134 => 0x38 },
+	'imageauthentication' => { 98 => 0x20 },
+	'imageboundary' => { 98 => 0x16 },
+	'imagecount' => { 98 => 0xa5 },
+	'imagedatasize' => { 98 => 0xa2 },
+	'imagedescription' => { 48 => 0x10e, 161 => 'ImageDescription' },
+	'imagedustoff' => { 109 => 0xfe443a45 },
+	'imageheight' => { 48 => 0x101, 89 => 0xc, 161 => 'ImageLength' },
+	'imagehistory' => { 48 => 0x9213 },
+	'imagenumber' => { 1 => 0xd0, 48 => 0x9211, 70 => 'ImageNumber', 85 => 0xae, 86 => 0x5e, 152 => 'ImageNumber' },
+	'imagenumber2' => { 86 => 0x62 },
+	'imageoptimization' => { 98 => 0xa9 },
+	'imageorientation' => { 54 => 0x83 },
+	'imageprocessing' => { 98 => 0x1a, 134 => 0x32 },
+	'imageprocessingversion' => { 119 => 0x0 },
+	'imagequality' => { 70 => 'ImageQuality', 126 => 0x1 },
+	'imagequality2' => { 115 => 0x603 },
+	'imagesize' => { 76 => 'ImageSize' },
+	'imagesourcedata' => { 48 => 0x935c },
+	'imagestabilization' => { 4 => 0x22, 45 => 0x3020, 70 => 'ImageStabilization', 85 => 0xbd, 86 => 0x71, 87 => 0x87, 88 => [0x18,0x107,0x113], 98 => 0xac, 118 => 0x1600, 126 => 0x1a },
+	'imagetone' => { 134 => 0x4f },
+	'imagetype' => { 54 => 0x82 },
+	'imageuniqueid' => { 48 => 0xa420, 157 => 'ImageUniqueID' },
+	'imagewidth' => { 48 => 0x100, 89 => 0xe, 161 => 'ImageWidth' },
+	'incrementaltemperature' => { 154 => 'IncrementalTemperature' },
+	'incrementaltint' => { 154 => 'IncrementalTint' },
+	'infinitylensstep' => { 120 => 0x103b },
+	'infobuttonwhenshooting' => { 25 => 0x409 },
+	'inkset' => { 48 => 0x14c },
+	'instanceid' => { 165 => 'InstanceID' },
+	'instructions' => { 160 => 'Instructions' },
+	'instrument' => { 164 => 'instrument' },
+	'intellectualgenre' => { 158 => 'IntellectualGenre' },
+	'interchangecolorspace' => { 56 => 0x40 },
+	'internalflash' => { 84 => 0x2b, 118 => 0x1208 },
+	'internalflashae1' => { 120 => 0x1021 },
+	'internalflashae1_0' => { 120 => 0x101d },
+	'internalflashae2' => { 120 => 0x1022 },
+	'internalflashae2_0' => { 120 => 0x101e },
+	'internalflashmagni' => { 132 => 0x3 },
+	'internalflashtable' => { 120 => 0x1024 },
+	'internalserialnumber' => { 16 => 0x96, 52 => 0x10, 116 => 0x102, 126 => 0x25, 131 => 0x4 },
+	'interopindex' => { 48 => 0x1 },
+	'interopversion' => { 48 => 0x2 },
+	'intervallength' => { 84 => 0x10 },
+	'intervalmode' => { 84 => 0x26 },
+	'intervalnumber' => { 84 => 0x11 },
+	'introtime' => { 164 => 'introTime' },
+	'iptc-naa' => { 48 => 0x83bb },
+	'iptcbitspersample' => { 56 => 0x56 },
+	'iptcimageheight' => { 56 => 0x1e },
+	'iptcimagerotation' => { 56 => 0x66 },
+	'iptcimagewidth' => { 56 => 0x14 },
+	'iptcpicturenumber' => { 56 => 0xa },
+	'iptcpixelheight' => { 56 => 0x32 },
+	'iptcpixelwidth' => { 56 => 0x28 },
+	'iso' => { 1 => 0x6, 2 => 0x6, 3 => 0x0, 44 => 0x14, 45 => [0x3014,0x14], 48 => 0x8827, 58 => 0xfd06, 59 => 0x60, 60 => [0xfa2e,0xfa46], 61 => [0x27,0x28], 62 => 0xf105, 66 => 0x4e, 70 => 'ISO', 84 => 0x8, 98 => 0x2, 127 => 0x17, 134 => 0x14, 136 => 0x14, 157 => 'ISOSpeedRatings' },
+	'isoexpansion' => { 25 => 0x103, 26 => 0x7, 27 => 0x8, 30 => 0x8 },
+	'isoselection' => { 98 => 0xf },
+	'isosetting' => { 59 => 0x5e, 70 => 'ISOSetting', 84 => 0x24, 85 => 0x26, 86 => 0x1c, 90 => 0x6, 98 => 0x13, 143 => 0x27 },
+	'isospeedexpansion' => { 24 => 0x3 },
+	'isospeedincrements' => { 25 => 0x102 },
+	'isospeedrange' => { 25 => 0x103 },
+	'isovalue' => { 120 => 0x1001 },
+	'jobid' => { 54 => 0xb8 },
+	'jobrefid' => { 163 => 'JobRefId' },
+	'jobrefname' => { 163 => 'JobRefName' },
+	'jobrefurl' => { 163 => 'JobRefUrl' },
+	'jpgfromraw' => { 38 => 0x2007, 46 => 'JpgFromRaw' },
+	'jpgfromrawlength' => { 48 => [0x117,0x202] },
+	'jpgfromrawstart' => { 48 => [0x111,0x201] },
+	'key' => { 164 => 'key' },
+	'keywords' => { 54 => 0x19, 71 => 'Keywords', 142 => 'Keywords', 159 => 'Keywords' },
+	'kodakimageheight' => { 58 => 0xf908, 59 => 0xe, 60 => [0xfa1e,0xfa52], 65 => 0x70 },
+	'kodakimagewidth' => { 58 => 0xf907, 59 => 0xc, 60 => [0xfa1d,0xfa51], 65 => 0x6c },
+	'kodakinfotype' => { 58 => 0xfa00 },
+	'kodakmaker' => { 65 => 0x8 },
+	'kodakmodel' => { 59 => 0x0, 65 => 0x28 },
+	'label' => { 125 => 'Label', 162 => 'Label' },
+	'language' => { 155 => 'language' },
+	'languageidentifier' => { 54 => 0x87 },
+	'lastfilenumber' => { 84 => 0x1b },
+	'lastkeywordiptc' => { 151 => 'LastKeywordIPTC' },
+	'lastkeywordxmp' => { 151 => 'LastKeywordXMP' },
+	'lasturl' => { 165 => 'LastURL' },
+	'lcddisplayatpoweron' => { 29 => 0xa },
+	'lcddisplayreturntoshoot' => { 30 => 0x12 },
+	'lcdilluminationduringbulb' => { 25 => 0x408 },
+	'lcdpanels' => { 24 => 0x8 },
+	'lcheditor' => { 109 => 0x8ae85e },
+	'legacyiptcdigest' => { 160 => 'LegacyIPTCDigest' },
+	'lens' => { 48 => 0xfdea, 98 => 0x84, 146 => 0xa, 152 => 'Lens' },
+	'lensafstopbutton' => { 23 => 0x11, 24 => 0x13, 25 => 0x506, 26 => 0x10, 27 => 0x12, 30 => 0x13, 31 => 0x9 },
+	'lensaperturerange' => { 146 => 0x30 },
+	'lenscodes' => { 133 => [0x4,0x5] },
+	'lensdataversion' => { 97 => 0x0 },
+	'lensdistortionparams' => { 120 => 0x206 },
+	'lensdrivenoaf' => { 25 => 0x505 },
+	'lensfirmwareversion' => { 116 => 0x204 },
+	'lensfstops' => { 97 => 0x7, 98 => 0x8b },
+	'lensid' => { 88 => 0x10c },
+	'lensidnumber' => { 97 => 0x6 },
+	'lensinfo' => { 152 => 'LensInfo' },
+	'lensmake' => { 77 => 'Make' },
+	'lensmanufacturer' => { 151 => 'LensManufacturer' },
+	'lensmodel' => { 77 => 'Model', 151 => 'LensModel' },
+	'lensproperties' => { 116 => 0x20b },
+	'lensserialnumber' => { 77 => 'SerialNumber', 116 => 0x202, 126 => 0x52 },
+	'lenstemperature' => { 120 => 0x1008 },
+	'lenstype' => { 1 => 0xd, 4 => 0x16, 16 => 0x95, 98 => 0x83, 116 => 0x201, 126 => 0x51, 133 => 0x0, 134 => 0x3f },
+	'license' => { 153 => 'license' },
+	'licensetype' => { 156 => 'licensetype' },
+	'lightcondition' => { 120 => 0x1009 },
+	'lightsource' => { 48 => 0x9208, 98 => 0x90, 123 => 0x1000, 157 => 'LightSource' },
+	'lightsourcespecial' => { 145 => 0x21d },
+	'lightvaluecenter' => { 120 => 0x103d },
+	'lightvalueperiphery' => { 120 => 0x103e },
+	'linearresponselimit' => { 48 => 0xc62e },
+	'liveviewexposuresimulation' => { 25 => 0x810 },
+	'localcaption' => { 54 => 0x79 },
+	'localizedcameramodel' => { 48 => 0xc615 },
+	'location' => { 150 => 'Location', 158 => 'Location' },
+	'lockmicrophonebutton' => { 25 => 0x709 },
+	'logcomment' => { 164 => 'logComment' },
+	'longexposurenoisereduction' => { 25 => 0x201, 26 => 0x1, 27 => 0x2, 28 => 0x1, 29 => 0x1, 30 => 0x2, 31 => 0x1 },
+	'longfocal' => { 1 => 0x13, 2 => 0x115, 4 => 0x17 },
+	'loop' => { 164 => 'loop' },
+	'luminanceadjustmentaqua' => { 154 => 'LuminanceAdjustmentAqua' },
+	'luminanceadjustmentblue' => { 154 => 'LuminanceAdjustmentBlue' },
+	'luminanceadjustmentgreen' => { 154 => 'LuminanceAdjustmentGreen' },
+	'luminanceadjustmentmagenta' => { 154 => 'LuminanceAdjustmentMagenta' },
+	'luminanceadjustmentorange' => { 154 => 'LuminanceAdjustmentOrange' },
+	'luminanceadjustmentpurple' => { 154 => 'LuminanceAdjustmentPurple' },
+	'luminanceadjustmentred' => { 154 => 'LuminanceAdjustmentRed' },
+	'luminanceadjustmentyellow' => { 154 => 'LuminanceAdjustmentYellow' },
+	'luminancenoisereduction' => { 43 => 0xbe },
+	'luminancesmoothing' => { 154 => 'LuminanceSmoothing' },
+	'macro' => { 52 => 0x1020, 120 => 0x202, 143 => 0x21, 145 => 0x202 },
+	'macromode' => { 4 => 0x1, 84 => 0xb, 115 => 0x300, 126 => 0x1c },
+	'magnifiedview' => { 27 => 0x11, 29 => 0x9 },
+	'make' => { 39 => 0x0, 48 => 0x10f, 70 => 'Make', 125 => 'Make', 127 => 0x10f, 161 => 'Make' },
+	'makernote' => { 157 => 'MakerNote' },
+	'makernotecanon' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotecasio' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotecasio2' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotefujifilm' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotehp' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotehp2' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotehp4' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotehp6' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotejvc' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotejvctext' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotekodak1a' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotekodak1b' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotekodak2' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotekodak3' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotekodak4' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotekodak5' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotekodak6a' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotekodak6b' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotekodak7' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotekodakifd' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotekodakunknown' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotekyocera' => { 47 => 'MakN', 48 => 0x927c },
+	'makernoteleica' => { 47 => 'MakN', 48 => 0x927c },
+	'makernoteminolta' => { 47 => 'MakN', 48 => 0x927c },
+	'makernoteminolta2' => { 47 => 'MakN', 48 => 0x927c },
+	'makernoteminolta3' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotenikon' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotenikon2' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotenikon3' => { 47 => 'MakN', 48 => 0x927c },
+	'makernoteoffset' => { 145 => 0xff },
+	'makernoteolympus' => { 47 => 'MakN', 48 => 0x927c },
+	'makernoteolympus2' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotepanasonic' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotepanasonic2' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotepentax' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotepentax2' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotepentax3' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotepentax4' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotericoh' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotericohtext' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotesafety' => { 48 => 0xc635 },
+	'makernotesanyo' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotesanyoc4' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotesanyopatch' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotesigma' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotesony' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotesonysr2' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotesonysrf' => { 47 => 'MakN', 48 => 0x927c },
+	'makernotetype' => { 144 => 0x1 },
+	'makernoteunknown' => { 47 => 'MakN', 48 => 0x927c },
+	'makernoteversion' => { 88 => 0x0, 98 => 0x1, 120 => 0x0, 126 => 0x8000, 144 => 0x2, 146 => 0x1d },
+	'managedfromdocumentid' => { 165 => 'ManagedFromDocumentID' },
+	'managedfrominstanceid' => { 165 => 'ManagedFromInstanceID' },
+	'managedfrommanager' => { 165 => 'ManagedFromManager' },
+	'managedfrommanagervariant' => { 165 => 'ManagedFromManagerVariant' },
+	'managedfrommanageto' => { 165 => 'ManagedFromManageTo' },
+	'managedfrommanageui' => { 165 => 'ManagedFromManageUI' },
+	'managedfromrenditionclass' => { 165 => 'ManagedFromRenditionClass' },
+	'managedfromrenditionparams' => { 165 => 'ManagedFromRenditionParams' },
+	'managedfromversionid' => { 165 => 'ManagedFromVersionID' },
+	'manager' => { 165 => 'Manager' },
+	'managervariant' => { 165 => 'ManagerVariant' },
+	'manageto' => { 165 => 'ManageTo' },
+	'manageui' => { 165 => 'ManageUI' },
+	'manometerreading' => { 115 => 0x901 },
+	'manualflash' => { 118 => 0x1209 },
+	'manualflashoutput' => { 4 => 0x29 },
+	'manualfocusdistance' => { 98 => 0x85, 120 => 0x100c, 145 => 0x223 },
+	'manualtv' => { 24 => 0x5, 25 => 0x705 },
+	'manufacturedate' => { 131 => 0x1 },
+	'marked' => { 167 => 'Marked' },
+	'markerscomment' => { 164 => 'markersComment' },
+	'markersduration' => { 164 => 'markersDuration' },
+	'markerslocation' => { 164 => 'markersLocation' },
+	'markersname' => { 164 => 'markersName' },
+	'markersstarttime' => { 164 => 'markersStartTime' },
+	'markerstarget' => { 164 => 'markersTarget' },
+	'markerstype' => { 164 => 'markersType' },
+	'maskedareas' => { 48 => 0xc68e },
+	'masterdocumentid' => { 54 => 0xb9 },
+	'mastergain' => { 102 => 0x50 },
+	'maxaperture' => { 4 => 0x1a, 62 => 0x6103, 77 => 'MaxAperture', 84 => 0x17 },
+	'maxapertureatcurrentfocal' => { 116 => 0x20a },
+	'maxapertureatmaxfocal' => { 52 => 0x1407, 77 => 'MaxApertureAtMaxFocal', 97 => 0xb, 116 => 0x206 },
+	'maxapertureatminfocal' => { 52 => 0x1406, 97 => 0xa, 116 => 0x205 },
+	'maxaperturevalue' => { 48 => 0x9205, 157 => 'MaxApertureValue' },
+	'maxfocallength' => { 52 => 0x1405, 77 => 'MaxFocalLength', 97 => 0x9, 116 => 0x208 },
+	'maximumdensityrange' => { 56 => 0x8c },
+	'maxpagesizeh' => { 168 => 'MaxPageSizeH' },
+	'maxpagesizeunit' => { 168 => 'MaxPageSizeUnit' },
+	'maxpagesizew' => { 168 => 'MaxPageSizeW' },
+	'maxsamplevalue' => { 48 => 0x119 },
+	'mcuversion' => { 97 => 0xc },
+	'md5digest' => { 78 => 'zmd5' },
+	'measuredev' => { 22 => 0x3, 38 => 0x1814, 70 => 'MeasuredEV' },
+	'menubuttondisplayposition' => { 23 => 0xb, 26 => 0xa, 27 => 0xb, 30 => 0xb },
+	'menubuttonreturn' => { 31 => 0xb },
+	'metadatadate' => { 162 => 'MetadataDate' },
+	'metadatamoddate' => { 164 => 'metadataModDate' },
+	'meteringmode' => { 4 => 0x11, 48 => 0x9207, 59 => 0x1c, 84 => 0x7, 85 => 0x25, 115 => 0x202, 134 => 0x17, 146 => 0x9, 157 => 'MeteringMode' },
+	'mieversion' => { 78 => '0Vers' },
+	'minaperture' => { 4 => 0x1b, 77 => 'MinAperture' },
+	'minfocallength' => { 52 => 0x1404, 77 => 'MinFocalLength', 97 => 0x8, 116 => 0x207 },
+	'minoltadate' => { 84 => 0x15 },
+	'minoltaimagesize' => { 84 => 0x4, 85 => 0xc, 86 => 0x2, 88 => 0x103 },
+	'minoltamodelid' => { 84 => 0x25 },
+	'minoltaquality' => { 84 => 0x5, 85 => 0xd, 86 => 0x3, 88 => [0x102,0x103], 120 => [0x102,0x103] },
+	'minoltatime' => { 84 => 0x16 },
+	'minsamplevalue' => { 48 => 0x118 },
+	'mirrorlockup' => { 23 => 0xc, 24 => 0xc, 25 => 0x60f, 26 => 0xb, 27 => 0xc, 28 => 0x6, 29 => 0x6, 30 => 0xc, 31 => 0x3 },
+	'moddate' => { 159 => 'ModDate' },
+	'model' => { 39 => 0x6, 48 => 0x110, 70 => 'Model', 125 => 'Model', 127 => 0x110, 161 => 'Model' },
+	'modelrevision' => { 131 => 0x2 },
+	'modifiedcolortemp' => { 17 => 0x9 },
+	'modifieddigitalgain' => { 17 => 0xb },
+	'modifiedparamflag' => { 14 => 0x1 },
+	'modifiedpicturestyle' => { 17 => 0xa },
+	'modifiedsaturation' => { 115 => 0x504 },
+	'modifiedsensorbluelevel' => { 17 => 0x5 },
+	'modifiedsensorredlevel' => { 17 => 0x4 },
+	'modifiedsharpness' => { 17 => 0x2 },
+	'modifiedsharpnessfreq' => { 17 => 0x3 },
+	'modifiedtonecurve' => { 17 => 0x1 },
+	'modifiedwhitebalance' => { 17 => 0x8 },
+	'modifiedwhitebalanceblue' => { 17 => 0x7 },
+	'modifiedwhitebalancered' => { 17 => 0x6 },
+	'modifydate' => { 48 => 0x132, 71 => 'ModifyDate', 124 => 'tIME', 142 => 'ModDate', 162 => 'ModifyDate' },
+	'moirefilter' => { 48 => 0xfe58 },
+	'monochromecontrast' => { 43 => 0x78 },
+	'monochromefiltereffect' => { 43 => 0x74 },
+	'monochromelinear' => { 43 => 0x7a },
+	'monochromesharpness' => { 43 => 0x7c },
+	'monochrometoningeffect' => { 43 => 0x76 },
+	'monthdaycreated' => { 59 => 0x12, 66 => 0xe },
+	'multiexposureautogain' => { 99 => 0x3 },
+	'multiexposuremode' => { 99 => 0x1 },
+	'multiexposureshots' => { 99 => 0x2 },
+	'multiexposureversion' => { 99 => 0x0 },
+	'multisample' => { 102 => 0x40 },
+	'mycolormode' => { 18 => 0x2 },
+	'nativedigest' => { 157 => 'NativeDigest', 161 => 'NativeDigest' },
+	'ndfilter' => { 22 => 0x1c },
+	'nearlensstep' => { 120 => 0x103c },
+	'newsphotoversion' => { 56 => 0x0 },
+	'nickname' => { 162 => 'Nickname' },
+	'nikoncaptureversion' => { 98 => 0xe09 },
+	'noisefilter' => { 115 => 0x527 },
+	'noisereduction' => { 13 => 0x8, 85 => 0xb0, 86 => 0x60, 87 => 0x3f, 98 => 0x95, 109 => 0x753dcbc0, 115 => 0x50a, 120 => 0x103a, 126 => 0x2d, 134 => 0x49 },
+	'noisereduction2' => { 119 => 0x1010 },
+	'noisereductionintensity' => { 110 => 0x9 },
+	'noisereductionmethod' => { 110 => 0x11 },
+	'noisereductionsharpness' => { 110 => 0xd },
+	'npages' => { 168 => 'NPages' },
+	'nullrecord' => { 38 => 0x0 },
+	'numberofbeats' => { 164 => 'numberOfBeats' },
+	'numindexentries' => { 56 => 0x54 },
+	'objectattributereference' => { 54 => 0x4 },
+	'objectcycle' => { 54 => 0x4b },
+	'objectdistance' => { 44 => 0x6, 45 => 0x2022 },
+	'objectname' => { 54 => 0x5 },
+	'objectpreviewdata' => { 54 => 0xca },
+	'objectpreviewfileformat' => { 54 => 0xc8 },
+	'objectpreviewfileversion' => { 54 => 0xc9 },
+	'objecttypereference' => { 54 => 0x3 },
+	'oecfcolumns' => { 157 => 'OECFColumns' },
+	'oecfnames' => { 157 => 'OECFNames' },
+	'oecfrows' => { 157 => 'OECFRows' },
+	'oecfvalues' => { 157 => 'OECFValues' },
+	'offsetschema' => { 48 => 0xea1d },
+	'oldsubfiletype' => { 48 => 0xff },
+	'olympusimageheight' => { 120 => 0x102f },
+	'olympusimageheight2' => { 119 => 0x615 },
+	'olympusimagewidth' => { 120 => 0x102e },
+	'olympusimagewidth2' => { 119 => 0x614 },
+	'onetouchwb' => { 120 => 0x302 },
+	'opticalzoom' => { 60 => 0xfa3d, 62 => [0x6006,0xf006], 63 => 0x1000, 64 => 0xf, 66 => 0x1e, 77 => 'OpticalZoom' },
+	'opticalzoomcode' => { 22 => 0xa },
+	'opticalzoommode' => { 126 => 0x34 },
+	'opticalzoomon' => { 145 => 0x219 },
+	'ordernumber' => { 52 => 0x8002 },
+	'orientation' => { 48 => 0x112, 127 => 0x112, 161 => 'Orientation' },
+	'originaldecisiondata' => { 16 => 0x83 },
+	'originalfilename' => { 38 => 0x816, 67 => 0x20 },
+	'originalimageheight' => { 51 => 0x1 },
+	'originalimagewidth' => { 51 => 0x0 },
+	'originalrawfiledata' => { 48 => 0xc68c },
+	'originalrawfilename' => { 48 => 0xc68b },
+	'originaltransmissionreference' => { 54 => 0x67 },
+	'originatingprogram' => { 54 => 0x41 },
+	'os' => { 156 => 'os' },
+	'outcue' => { 164 => 'outCue' },
+	'outputheight' => { 106 => 0xce },
+	'outputheightinches' => { 106 => 0x96 },
+	'outputpixels' => { 106 => 0xd6 },
+	'outputresolution' => { 106 => 0xb6 },
+	'outputwidth' => { 106 => 0xc6 },
+	'outputwidthinches' => { 106 => 0x8e },
+	'owner' => { 167 => 'Owner' },
+	'ownerid' => { 54 => 0xbc },
+	'ownername' => { 16 => 0x9, 38 => 0x810, 48 => 0xfde8, 70 => 'OwnerName', 152 => 'OwnerName' },
+	'pagename' => { 48 => 0x11d },
+	'pagenumber' => { 48 => 0x129 },
+	'panasonicexifversion' => { 126 => 0x26 },
+	'panasonicrawversion' => { 127 => 0x1 },
+	'panoramadirection' => { 19 => 0x5 },
+	'panoramaframe' => { 19 => 0x2 },
+	'panoramamode' => { 59 => 0x3c, 115 => 0x601 },
+	'parametricdarks' => { 154 => 'ParametricDarks' },
+	'parametrichighlights' => { 154 => 'ParametricHighlights' },
+	'parametrichighlightsplit' => { 154 => 'ParametricHighlightSplit' },
+	'parametriclights' => { 154 => 'ParametricLights' },
+	'parametricmidtonesplit' => { 154 => 'ParametricMidtoneSplit' },
+	'parametricshadows' => { 154 => 'ParametricShadows' },
+	'parametricshadowsplit' => { 154 => 'ParametricShadowSplit' },
+	'patientid' => { 148 => 'PatientID' },
+	'patientsbirthdate' => { 148 => 'PatientDOB' },
+	'patientsname' => { 148 => 'PatientName' },
+	'patientssex' => { 148 => 'PatientSex' },
+	'pdfversion' => { 159 => 'PDFVersion' },
+	'pentaximagesize' => { 134 => 0x9 },
+	'pentaxmodelid' => { 131 => 0x0, 134 => 0x5 },
+	'pentaxmodeltype' => { 134 => 0x1 },
+	'pentaxversion' => { 134 => 0x0 },
+	'people' => { 150 => 'People' },
+	'pf0customfuncregistration' => { 33 => 0x1 },
+	'pf10retainprogramshift' => { 33 => 0xb },
+	'pf13drivepriority' => { 33 => 0xe },
+	'pf14disablefocussearch' => { 33 => 0xf },
+	'pf15disableafassistbeam' => { 33 => 0x10 },
+	'pf16autofocuspointshoot' => { 33 => 0x11 },
+	'pf17disableafpointsel' => { 33 => 0x12 },
+	'pf18enableautoafpointsel' => { 33 => 0x13 },
+	'pf19continuousshootspeed' => { 33 => 0x14 },
+	'pf19shootingspeedhigh' => { 32 => 0xa },
+	'pf19shootingspeedlow' => { 32 => 0x9 },
+	'pf1disableshootingmodes' => { 33 => 0x2 },
+	'pf1value' => { 32 => 0x1 },
+	'pf20limitcontinousshots' => { 33 => 0x15 },
+	'pf20maxcontinousshots' => { 32 => 0xb },
+	'pf21enablequietoperation' => { 33 => 0x16 },
+	'pf23felocktime' => { 32 => 0xd },
+	'pf23postreleasetime' => { 32 => 0xe },
+	'pf23settimerlengths' => { 33 => 0x18 },
+	'pf23shutterbuttontime' => { 32 => 0xc },
+	'pf24lightlcdduringbulb' => { 33 => 0x19 },
+	'pf25aemode' => { 32 => 0xf },
+	'pf25afmode' => { 32 => 0x12 },
+	'pf25afpointsel' => { 32 => 0x13 },
+	'pf25colormatrix' => { 32 => 0x17 },
+	'pf25defaultclearsettings' => { 33 => 0x1a },
+	'pf25drivemode' => { 32 => 0x11 },
+	'pf25imagesize' => { 32 => 0x14 },
+	'pf25meteringmode' => { 32 => 0x10 },
+	'pf25parameters' => { 32 => 0x16 },
+	'pf25wbmode' => { 32 => 0x15 },
+	'pf26shortenreleaselag' => { 33 => 0x1b },
+	'pf27reversedialrotation' => { 33 => 0x1c },
+	'pf27value' => { 32 => 0x18 },
+	'pf28noquickdialexpcomp' => { 33 => 0x1d },
+	'pf29quickdialswitchoff' => { 33 => 0x1e },
+	'pf2disablemeteringmodes' => { 33 => 0x3 },
+	'pf2value' => { 32 => 0x2 },
+	'pf30enlargementmode' => { 33 => 0x1f },
+	'pf31originaldecisiondata' => { 33 => 0x20 },
+	'pf3manualexposuremetering' => { 33 => 0x4 },
+	'pf3value' => { 32 => 0x3 },
+	'pf4exposuretimelimits' => { 33 => 0x5 },
+	'pf4exposuretimemax' => { 32 => 0x5 },
+	'pf4exposuretimemin' => { 32 => 0x4 },
+	'pf5aperturelimits' => { 33 => 0x6 },
+	'pf5aperturemax' => { 32 => 0x7 },
+	'pf5aperturemin' => { 32 => 0x6 },
+	'pf6presetshootingmodes' => { 33 => 0x7 },
+	'pf7bracketcontinuousshoot' => { 33 => 0x8 },
+	'pf8bracketshots' => { 32 => 0x8 },
+	'pf8setbracketshots' => { 33 => 0x9 },
+	'pf9changebracketsequence' => { 33 => 0xa },
+	'phonenumber' => { 71 => 'Phone' },
+	'photoeffect' => { 4 => 0x28 },
+	'photoeffects' => { 109 => 0xab5eca5e },
+	'photoeffectsblue' => { 111 => 0x8 },
+	'photoeffectsgreen' => { 111 => 0x6 },
+	'photoeffectsred' => { 111 => 0x4 },
+	'photoeffectstype' => { 111 => 0x0 },
+	'photometricinterpretation' => { 48 => 0x106, 161 => 'PhotometricInterpretation' },
+	'photoshopquality' => { 139 => 0x0 },
+	'pictinfo' => { 145 => 0x208 },
+	'picturemode' => { 52 => 0x1031, 115 => 0x520, 134 => [0xb,0x33] },
+	'picturemodebwfilter' => { 115 => 0x525 },
+	'picturemodecontrast' => { 115 => 0x523 },
+	'picturemodehue' => { 115 => 0x522 },
+	'picturemodesaturation' => { 115 => 0x521 },
+	'picturemodesharpness' => { 115 => 0x524 },
+	'picturemodetone' => { 115 => 0x526 },
+	'picturestyle' => { 1 => 0x6c, 2 => 0x86, 21 => 0xa, 43 => 0x4 },
+	'planarconfiguration' => { 48 => 0x11c, 161 => 'PlanarConfiguration' },
+	'platenames' => { 168 => 'PlateNames' },
+	'pngwarning' => { 125 => 'Warning' },
+	'postalcode' => { 75 => 'PostalCode' },
+	'precaptureframes' => { 120 => 0x300 },
+	'predictor' => { 48 => 0x13d },
+	'prefs' => { 54 => 0xdd, 138 => 'Prefs' },
+	'preservedfilename' => { 165 => 'PreservedFileName' },
+	'previewfocalplanexresolution' => { 20 => 0x6 },
+	'previewfocalplaneyresolution' => { 20 => 0x8 },
+	'previewheight' => { 60 => 0xfa58 },
+	'previewimage' => { 45 => 0x2000, 46 => 'PreviewImage', 47 => 'MakN', 48 => 0x927c, 50 => 0x4, 80 => 'data', 88 => 0x81, 120 => 0x280 },
+	'previewimageheight' => { 20 => 0x4 },
+	'previewimagelength' => { 20 => 0x2, 45 => 0x3, 48 => [0x117,0x202], 88 => 0x89, 100 => 0x202, 115 => 0x102, 120 => 0x1037, 134 => 0x3, 143 => 0x1e },
+	'previewimagename' => { 80 => '1Name' },
+	'previewimagesize' => { 45 => 0x2, 80 => 'ImageSize', 134 => 0x2 },
+	'previewimagestart' => { 20 => 0x5, 45 => 0x4, 48 => [0x111,0x201], 88 => 0x88, 100 => 0x201, 115 => 0x101, 120 => 0x1036, 134 => 0x4, 143 => 0x1c },
+	'previewimagetype' => { 80 => '0Type' },
+	'previewimagevalid' => { 115 => 0x100, 120 => 0x1035 },
+	'previewimagewidth' => { 20 => 0x3 },
+	'previewquality' => { 20 => 0x1 },
+	'previewwidth' => { 60 => 0xfa57 },
+	'primarychromaticities' => { 48 => 0x13f, 161 => 'PrimaryChromaticities' },
+	'printim' => { 48 => 0xc4a5 },
+	'privatertkinfo' => { 149 => 'privateRTKInfo' },
+	'processingsoftware' => { 48 => 0xb },
+	'producer' => { 159 => 'Producer' },
+	'productid' => { 55 => 0x32 },
+	'programiso' => { 126 => 0x3c },
+	'programmode' => { 90 => 0x5 },
+	'programshift' => { 98 => 0xd },
+	'programversion' => { 54 => 0x46 },
+	'projectrefpath' => { 164 => 'projectRefPath' },
+	'projectreftype' => { 164 => 'projectRefType' },
+	'province-state' => { 54 => 0x5f },
+	'publisher' => { 155 => 'publisher' },
+	'pulldown' => { 164 => 'pullDown' },
+	'quality' => { 0 => 0x1, 4 => 0x3, 44 => 0x2, 45 => 0x3002, 52 => 0x1000, 59 => 0x9, 98 => 0x4, 103 => 0x3, 120 => 0x201, 134 => 0x8, 136 => 0x2, 146 => 0x16 },
+	'qualitymode' => { 45 => 0x8 },
+	'quantizationmethod' => { 56 => 0x78 },
+	'quickcontroldialinmeter' => { 25 => 0x703 },
+	'quickshot' => { 145 => 0x213 },
+	'rasterizedcaption' => { 54 => 0x7d },
+	'rating' => { 48 => 0x4746, 137 => 0xdf, 156 => 'rating', 162 => 'Rating' },
+	'ratingpercent' => { 48 => 0x4749, 151 => 'Rating' },
+	'rawandjpgrecording' => { 23 => 0x8 },
+	'rawbrightnessadj' => { 42 => 0x38 },
+	'rawcoloradj' => { 42 => 0x2e },
+	'rawcolortoneadj' => { 43 => 0x1a },
+	'rawcontrastadj' => { 43 => 0x1e },
+	'rawcropbottom' => { 137 => 0xd4 },
+	'rawcropleft' => { 137 => 0xd1 },
+	'rawcropright' => { 137 => 0xd3 },
+	'rawcroptop' => { 137 => 0xd2 },
+	'rawcustomsaturation' => { 42 => 0x30 },
+	'rawcustomtone' => { 42 => 0x34 },
+	'rawdatauniqueid' => { 48 => 0xc65d },
+	'rawdepth' => { 89 => 0x10 },
+	'rawdevcolorspace' => { 121 => 0x108, 122 => 0x109 },
+	'rawdevcontrastvalue' => { 121 => 0x106, 122 => 0x105 },
+	'rawdeveditstatus' => { 121 => 0x10b },
+	'rawdevengine' => { 121 => 0x109, 122 => 0x10b },
+	'rawdevexposurebiasvalue' => { 121 => 0x100, 122 => 0x100 },
+	'rawdevgradation' => { 122 => 0x112 },
+	'rawdevgraypoint' => { 121 => 0x103, 122 => 0x104 },
+	'rawdevmemorycoloremphasis' => { 121 => 0x105, 122 => 0x108 },
+	'rawdevnoisereduction' => { 121 => 0x10a, 122 => 0x10a },
+	'rawdevpicturemode' => { 122 => 0x10c },
+	'rawdevpm_bwfilter' => { 122 => 0x110 },
+	'rawdevpmcontrast' => { 122 => 0x10e },
+	'rawdevpmpicturetone' => { 122 => 0x111 },
+	'rawdevpmsaturation' => { 122 => 0x10d },
+	'rawdevpmsharpness' => { 122 => 0x10f },
+	'rawdevsaturationemphasis' => { 121 => 0x104, 122 => 0x107 },
+	'rawdevsettings' => { 121 => 0x10c },
+	'rawdevsharpnessvalue' => { 121 => 0x107, 122 => 0x106 },
+	'rawdevversion' => { 121 => 0x0, 122 => 0x0 },
+	'rawdevwbfineadjustment' => { 121 => 0x102, 122 => 0x103 },
+	'rawdevwhitebalance' => { 122 => 0x101 },
+	'rawdevwhitebalancevalue' => { 121 => 0x101, 122 => 0x102 },
+	'rawfile' => { 48 => 0xfe4c },
+	'rawfilename' => { 154 => 'RawFileName' },
+	'rawhighlightpoint' => { 43 => 0x24 },
+	'rawimagecenter' => { 98 => 0x99 },
+	'rawimagesize' => { 134 => 0x39 },
+	'rawinfoversion' => { 123 => 0x0 },
+	'rawjpgheight' => { 40 => 0x4 },
+	'rawjpgquality' => { 13 => 0x6, 40 => 0x1 },
+	'rawjpgsize' => { 13 => 0x7, 40 => 0x2 },
+	'rawjpgwidth' => { 40 => 0x3 },
+	'rawlinear' => { 43 => 0x20 },
+	'rawsaturationadj' => { 43 => 0x1c },
+	'rawshadowpoint' => { 43 => 0x26 },
+	'rawsharpnessadj' => { 43 => 0x22 },
+	'recordid' => { 38 => 0x1804 },
+	'recordingmode' => { 44 => 0x1, 136 => 0x1 },
+	'recordmode' => { 4 => 0x9, 45 => 0x3000 },
+	'recordshutterrelease' => { 145 => 0x217 },
+	'redbalance' => { 120 => 0x1017, 127 => 0x11, 134 => 0x1c },
+	'redcurvelimits' => { 42 => 0x18a },
+	'redcurvepoints' => { 42 => 0x160 },
+	'redeyecorrection' => { 112 => 0x0 },
+	'redhue' => { 154 => 'RedHue' },
+	'redsaturation' => { 154 => 'RedSaturation' },
+	'referenceblackwhite' => { 48 => 0x214, 161 => 'ReferenceBlackWhite' },
+	'referencedate' => { 54 => 0x2f },
+	'referencenumber' => { 54 => 0x32 },
+	'references' => { 71 => 'References' },
+	'referenceservice' => { 54 => 0x2d },
+	'relatedaudiofile' => { 69 => 'data' },
+	'relatedaudiofilename' => { 69 => '1Name' },
+	'relatedaudiofiletype' => { 69 => '0Type' },
+	'relatedimagefileformat' => { 48 => 0x1000 },
+	'relatedimagelength' => { 48 => 0x1002 },
+	'relatedimagewidth' => { 48 => 0x1001 },
+	'relatedsoundfile' => { 48 => 0xa004, 157 => 'RelatedSoundFile' },
+	'relatedvideofile' => { 83 => 'data' },
+	'relatedvideofilename' => { 83 => '1Name' },
+	'relatedvideofiletype' => { 83 => '0Type' },
+	'relation' => { 155 => 'relation' },
+	'relativepeakaudiofilepath' => { 164 => 'relativePeakAudioFilePath' },
+	'relativetimestamp' => { 164 => 'relativeTimestamp' },
+	'releasedate' => { 54 => 0x1e, 164 => 'releaseDate' },
+	'releasesetting' => { 38 => 0x1016 },
+	'releasetime' => { 54 => 0x23 },
+	'renditionclass' => { 165 => 'RenditionClass' },
+	'renditionofdocumentid' => { 165 => 'RenditionOfDocumentID' },
+	'renditionofinstanceid' => { 165 => 'RenditionOfInstanceID' },
+	'renditionofmanager' => { 165 => 'RenditionOfManager' },
+	'renditionofmanagervariant' => { 165 => 'RenditionOfManagerVariant' },
+	'renditionofmanageto' => { 165 => 'RenditionOfManageTo' },
+	'renditionofmanageui' => { 165 => 'RenditionOfManageUI' },
+	'renditionofrenditionclass' => { 165 => 'RenditionOfRenditionClass' },
+	'renditionofrenditionparams' => { 165 => 'RenditionOfRenditionParams' },
+	'renditionofversionid' => { 165 => 'RenditionOfVersionID' },
+	'renditionparams' => { 165 => 'RenditionParams' },
+	'resampleparamsquality' => { 164 => 'resampleParamsQuality' },
+	'resaved' => { 145 => 0x21e },
+	'resolution' => { 76 => 'Resolution' },
+	'resolutionmode' => { 146 => 0x4 },
+	'resolutionunit' => { 48 => 0x128, 57 => 0x2, 161 => 'ResolutionUnit' },
+	'reuseallowed' => { 166 => 'ReuseAllowed' },
+	'revision' => { 156 => 'revision' },
+	'rgbcurvelimits' => { 42 => 0x238 },
+	'rgbcurvepoints' => { 42 => 0x20e },
+	'ricohdate' => { 143 => 0x6 },
+	'ricohimageheight' => { 143 => 0x2 },
+	'ricohimagewidth' => { 143 => 0x0 },
+	'rightascension' => { 79 => 'RightAscension' },
+	'rights' => { 155 => 'rights' },
+	'romoperationmode' => { 38 => 0x80d },
+	'rotation' => { 3 => 0x17, 37 => 0x3, 42 => 0x26e, 51 => 0x4, 79 => 'Rotation', 85 => 0x50, 86 => 0x46, 87 => 0x5a, 109 => 0x76a43207, 126 => 0x30, 137 => 0xd8 },
+	'routing' => { 142 => 'Routing' },
+	'rowsperstrip' => { 48 => 0x116 },
+	'safetyshift' => { 25 => 0x108 },
+	'safetyshiftinavortv' => { 23 => 0x10, 24 => 0x10, 26 => 0xf, 27 => 0x10, 30 => 0x10 },
+	'samplebits' => { 69 => 'SampleBits' },
+	'samplerate' => { 69 => 'SampleRate' },
+	'samplesperpixel' => { 48 => 0x115, 161 => 'SamplesPerPixel' },
+	'samplestructure' => { 56 => 0x5a },
+	'sanyoquality' => { 145 => 0x201 },
+	'sanyothumbnail' => { 145 => 0x100 },
+	'saturation' => { 4 => 0xe, 9 => 0x1, 44 => 0xd, 45 => [0x3013,0x1f], 48 => [0xa409,0xfe55], 52 => 0x1003, 70 => 'Saturation', 84 => 0x1f, 85 => 0x32, 86 => 0x28, 87 => 0x1a, 90 => 0x1, 98 => [0x94,0xaa], 134 => 0x1f, 136 => 0xd, 143 => 0x28, 146 => 0x10, 154 => 'Saturation', 157 => 'Saturation' },
+	'saturationadj' => { 42 => 0x116 },
+	'saturationadjustmentaqua' => { 154 => 'SaturationAdjustmentAqua' },
+	'saturationadjustmentblue' => { 154 => 'SaturationAdjustmentBlue' },
+	'saturationadjustmentgreen' => { 154 => 'SaturationAdjustmentGreen' },
+	'saturationadjustmentmagenta' => { 154 => 'SaturationAdjustmentMagenta' },
+	'saturationadjustmentorange' => { 154 => 'SaturationAdjustmentOrange' },
+	'saturationadjustmentpurple' => { 154 => 'SaturationAdjustmentPurple' },
+	'saturationadjustmentred' => { 154 => 'SaturationAdjustmentRed' },
+	'saturationadjustmentyellow' => { 154 => 'SaturationAdjustmentYellow' },
+	'saturationfaithful' => { 1 => 0xfe },
+	'saturationlandscape' => { 1 => 0xfc },
+	'saturationneutral' => { 1 => 0xfd },
+	'saturationportrait' => { 1 => 0xfb },
+	'saturationsetting' => { 123 => 0x1010 },
+	'saturationstandard' => { 1 => 0xfa },
+	'saturationuserdef1' => { 1 => 0x100 },
+	'saturationuserdef2' => { 1 => 0x101 },
+	'saturationuserdef3' => { 1 => 0x102 },
+	'saveid' => { 165 => 'SaveID' },
+	'scaledresolution' => { 106 => 0x9e },
+	'scaletype' => { 164 => 'scaleType' },
+	'scanningdirection' => { 56 => 0x64 },
+	'scene' => { 158 => 'Scene', 164 => 'scene' },
+	'scenearea' => { 120 => 0x1031 },
+	'scenecapturetype' => { 48 => 0xa406, 157 => 'SceneCaptureType' },
+	'scenedetect' => { 120 => 0x1030 },
+	'scenedetectarea' => { 120 => 0x1033 },
+	'scenemode' => { 60 => 0xfa02, 88 => 0x100, 98 => 0x8f, 115 => 0x509, 120 => 0x403, 126 => 0x8001 },
+	'scenemodeused' => { 62 => [0x6002,0xf002] },
+	'sceneselect' => { 145 => 0x21f },
+	'scenetype' => { 48 => 0xa301, 157 => 'SceneType' },
+	'securityclassification' => { 48 => 0x9212 },
+	'selectableafpoint' => { 25 => 0x509 },
+	'self-timer' => { 4 => 0x2 },
+	'self-timer2' => { 22 => 0x1d },
+	'selftimer' => { 45 => 0x3001, 126 => 0x2e, 145 => 0x214 },
+	'selftimermode' => { 48 => 0x882b },
+	'selftimertime' => { 38 => 0x1806 },
+	'seminfo' => { 48 => 0x8546 },
+	'sensingmethod' => { 48 => 0xa217, 157 => 'SensingMethod' },
+	'sensorbluelevel' => { 21 => 0x5 },
+	'sensorcleaning' => { 31 => 0xd },
+	'sensorfullheight' => { 58 => 0xf904 },
+	'sensorfullwidth' => { 58 => 0xf903 },
+	'sensorheight' => { 58 => 0xf901, 60 => 0xfa21, 89 => 0x8 },
+	'sensorpixelsize' => { 98 => 0x9a },
+	'sensorredlevel' => { 21 => 0x4 },
+	'sensorsize' => { 70 => 'SensorSize' },
+	'sensortemperature' => { 118 => 0x1500, 120 => 0x1007 },
+	'sensorwidth' => { 58 => 0xf900, 60 => 0xfa20, 89 => 0xa },
+	'sequencenumber' => { 22 => 0x9, 45 => 0x301c, 52 => 0x1101, 59 => 0x1d, 126 => 0x2b },
+	'sequenceshotinterval' => { 145 => 0x224 },
+	'sequentialshot' => { 145 => 0x20e },
+	'serialnumber' => { 16 => 0xc, 38 => 0x180b, 48 => 0xfde9, 58 => 0xfa04, 60 => 0xfa19, 68 => 0x0, 70 => 'SerialNumber', 98 => 0xa0, 116 => 0x101, 120 => [0x404,0x101a], 146 => 0x2, 152 => 'SerialNumber' },
+	'serialnumberformat' => { 16 => 0x15, 38 => 0x183b },
+	'seriesdatetime' => { 148 => 'SeriesDateTime' },
+	'seriesdescription' => { 148 => 'SeriesDescription' },
+	'seriesmodality' => { 148 => 'SeriesModality' },
+	'seriesnumber' => { 148 => 'SeriesNumber' },
+	'serviceidentifier' => { 55 => 0x1e },
+	'setbuttoncrosskeysfunc' => { 28 => 0x0, 29 => 0x0 },
+	'setbuttonfunction' => { 23 => 0x1, 31 => 0xc },
+	'setbuttonwhenshooting' => { 25 => 0x704 },
+	'setfunctionwhenshooting' => { 26 => 0x0, 27 => 0x1, 30 => 0x1 },
+	'shadingcompensation' => { 115 => 0x50c },
+	'shadingcompensation2' => { 119 => 0x1012 },
+	'shadow' => { 146 => 0xe },
+	'shadows' => { 48 => 0xfe52, 154 => 'Shadows' },
+	'shadowscale' => { 48 => 0xc633 },
+	'shadowtint' => { 154 => 'ShadowTint' },
+	'shakereduction' => { 135 => 0x1 },
+	'sharpendetail' => { 154 => 'SharpenDetail' },
+	'sharpenedgemasking' => { 154 => 'SharpenEdgeMasking' },
+	'sharpenradius' => { 154 => 'SharpenRadius' },
+	'sharpness' => { 4 => 0xf, 21 => 0x2, 44 => 0xb, 45 => [0x3011,0x21], 48 => [0xa40a,0xfe56], 52 => 0x1001, 59 => 0x6b, 66 => 0x37, 70 => 'Sharpness', 84 => 0x21, 85 => 0x30, 86 => 0x26, 87 => 0x18, 90 => 0x3, 98 => 0x6, 120 => 0x100f, 134 => 0x21, 136 => 0xb, 143 => 0x22, 144 => 0x1003, 146 => 0x11, 154 => 'Sharpness', 157 => 'Sharpness' },
+	'sharpnessfactor' => { 120 => 0x102a },
+	'sharpnessfaithful' => { 1 => 0xf5 },
+	'sharpnessfrequency' => { 21 => 0x3 },
+	'sharpnesslandscape' => { 1 => 0xf3 },
+	'sharpnessmonochrome' => { 1 => 0xf6 },
+	'sharpnessneutral' => { 1 => 0xf4 },
+	'sharpnessportrait' => { 1 => 0xf2 },
+	'sharpnesssetting' => { 115 => 0x506, 123 => 0x1013 },
+	'sharpnessstandard' => { 1 => 0xf1 },
+	'sharpnessuserdef1' => { 1 => 0xf7 },
+	'sharpnessuserdef2' => { 1 => 0xf8 },
+	'sharpnessuserdef3' => { 1 => 0xf9 },
+	'shootingmode' => { 70 => 'ShootingMode', 98 => 0x89, 126 => 0x1f },
+	'shortdescription' => { 156 => 'shortdescription' },
+	'shortdocumentid' => { 54 => 0xba },
+	'shortfocal' => { 1 => 0x11, 2 => 0x113, 4 => 0x18 },
+	'shortownername' => { 1 => 0xac },
+	'shortreleasetimelag' => { 25 => 0x80d },
+	'shotdate' => { 164 => 'shotDate' },
+	'shotlocation' => { 164 => 'shotLocation' },
+	'shotname' => { 164 => 'shotName' },
+	'shutter-aelock' => { 23 => 0x4, 26 => 0x3, 27 => 0x4, 28 => 0x3, 29 => 0x3, 30 => 0x4, 31 => 0x2 },
+	'shutteraelbutton' => { 24 => 0x4 },
+	'shutterbuttonafonbutton' => { 25 => 0x701 },
+	'shuttercount' => { 2 => 0x176, 13 => 0x1, 134 => 0x5d },
+	'shuttercurtainsync' => { 23 => 0xf, 24 => 0xf, 25 => 0x305, 26 => 0xe, 27 => 0xf, 28 => 0x8, 29 => 0x8, 30 => 0xf, 31 => 0x8 },
+	'shuttermode' => { 59 => 0x1b },
+	'shutterreleasemethod' => { 38 => 0x1010 },
+	'shutterreleasenocfcard' => { 23 => 0x2, 24 => 0x2, 31 => 0xf },
+	'shutterreleasetiming' => { 38 => 0x1011 },
+	'shutterspeedrange' => { 25 => 0x10c },
+	'shutterspeedvalue' => { 48 => 0x9201, 120 => 0x1000, 157 => 'ShutterSpeedValue' },
+	'sidecarforextension' => { 160 => 'SidecarForExtension' },
+	'similarityindex' => { 54 => 0xe4 },
+	'slowshutter' => { 22 => 0x8 },
+	'slowsync' => { 52 => 0x1030 },
+	'smoothingparameter1' => { 119 => 0x300 },
+	'smoothingparameter2' => { 119 => 0x310 },
+	'smoothingthreshold2' => { 119 => 0x610 },
+	'smoothingthresholds' => { 119 => 0x600 },
+	'smoothness' => { 48 => 0xfe57 },
+	'software' => { 48 => 0x131, 71 => 'Software', 125 => 'Software', 146 => 0x18, 161 => 'Software' },
+	'softwareversion' => { 145 => 0x207 },
+	'source' => { 54 => 0x73, 125 => 'Source', 155 => 'source', 156 => 'source', 160 => 'Source' },
+	'sourceresolution' => { 106 => 0xae },
+	'spatialfrequencyresponsecolumns' => { 157 => 'SpatialFrequencyResponseColumns' },
+	'spatialfrequencyresponsenames' => { 157 => 'SpatialFrequencyResponseNames' },
+	'spatialfrequencyresponserows' => { 157 => 'SpatialFrequencyResponseRows' },
+	'spatialfrequencyresponsevalues' => { 157 => 'SpatialFrequencyResponseValues' },
+	'speakerplacement' => { 164 => 'speakerPlacement' },
+	'specialinstructions' => { 54 => 0x28 },
+	'specialmode' => { 120 => 0x200, 145 => 0x200 },
+	'spectralsensitivity' => { 48 => 0x8824, 157 => 'SpectralSensitivity' },
+	'splittoningbalance' => { 154 => 'SplitToningBalance' },
+	'splittoninghighlighthue' => { 154 => 'SplitToningHighlightHue' },
+	'splittoninghighlightsaturation' => { 154 => 'SplitToningHighlightSaturation' },
+	'splittoningshadowhue' => { 154 => 'SplitToningShadowHue' },
+	'splittoningshadowsaturation' => { 154 => 'SplitToningShadowSaturation' },
+	'spotfocuspointx' => { 84 => 0x2d },
+	'spotfocuspointy' => { 84 => 0x2e },
+	'spotmeterlinktoafpoint' => { 25 => 0x107 },
+	'sr_swstoswrtime' => { 135 => 0x2 },
+	'srresult' => { 135 => 0x0 },
+	'startoffsetx' => { 123 => 0x612 },
+	'startoffsety' => { 123 => 0x613 },
+	'starttimecodetimeformat' => { 164 => 'startTimecodeTimeFormat' },
+	'starttimecodetimevalue' => { 164 => 'startTimecodeTimeValue' },
+	'state' => { 75 => 'State', 160 => 'State' },
+	'status' => { 150 => 'Status' },
+	'storagemethod' => { 89 => 0x12 },
+	'straightenangle' => { 109 => 0x2fc08431 },
+	'stretchmode' => { 164 => 'stretchMode' },
+	'studydatetime' => { 148 => 'StudyDateTime' },
+	'studydescription' => { 148 => 'StudyDescription' },
+	'studyid' => { 148 => 'StudyID' },
+	'studyphysician' => { 148 => 'StudyPhysician' },
+	'sub-location' => { 54 => 0x5c },
+	'subfiledata' => { 78 => 'data' },
+	'subfiledirectory' => { 78 => '1Directory' },
+	'subfilemimetype' => { 78 => '2MIME' },
+	'subfilename' => { 78 => '1Name' },
+	'subfileresource' => { 78 => 'rsrc' },
+	'subfiletype' => { 48 => 0xfe, 78 => '0Type' },
+	'subject' => { 142 => 'Subject', 155 => 'subject', 159 => 'Subject' },
+	'subjectarea' => { 157 => 'SubjectArea' },
+	'subjectcode' => { 158 => 'SubjectCode' },
+	'subjectdistance' => { 48 => 0x9206, 59 => 0x3e, 157 => 'SubjectDistance' },
+	'subjectdistancerange' => { 48 => 0xa40c, 157 => 'SubjectDistanceRange' },
+	'subjectlocation' => { 48 => [0x9214,0xa214], 157 => 'SubjectLocation' },
+	'subjectprogram' => { 84 => 0x22 },
+	'subjectreference' => { 54 => 0xc },
+	'subsectime' => { 48 => 0x9290 },
+	'subsectimedigitized' => { 48 => 0x9292 },
+	'subsectimeoriginal' => { 48 => 0x9291 },
+	'superimposeddisplay' => { 23 => 0xa, 25 => 0x510, 26 => 0x9, 27 => 0xa, 30 => 0xa, 31 => 0xe },
+	'supplementalcategories' => { 54 => 0x14, 160 => 'SupplementalCategories' },
+	'supplementaltype' => { 56 => 0x37 },
+	'switchtoregisteredafpoint' => { 24 => 0x12, 25 => 0x50a },
+	'tagged' => { 137 => 0xdd },
+	'tapename' => { 164 => 'tapeName' },
+	'targetaperture' => { 22 => 0x4 },
+	'targetcompressionratio' => { 36 => 0x1 },
+	'targetdistancesetting' => { 38 => 0x1807 },
+	'targetexposuretime' => { 22 => 0x5 },
+	'targetimagetype' => { 38 => 0x100a },
+	'temperature' => { 154 => 'Temperature' },
+	'tempo' => { 164 => 'tempo' },
+	'thresholding' => { 48 => 0x107 },
+	'thumbnailfilename' => { 38 => 0x817 },
+	'thumbnailheight' => { 60 => 0xfa55 },
+	'thumbnailimage' => { 38 => 0x2008, 46 => 'ThumbnailImage', 50 => 0x3, 81 => 'data', 120 => 0x100 },
+	'thumbnailimagename' => { 81 => '1Name' },
+	'thumbnailimagesize' => { 81 => 'ImageSize' },
+	'thumbnailimagetype' => { 81 => '0Type' },
+	'thumbnaillength' => { 48 => 0x202 },
+	'thumbnailoffset' => { 48 => 0x201 },
+	'thumbnailsformat' => { 162 => 'ThumbnailsFormat' },
+	'thumbnailsheight' => { 162 => 'ThumbnailsHeight' },
+	'thumbnailsimage' => { 162 => 'ThumbnailsImage' },
+	'thumbnailswidth' => { 162 => 'ThumbnailsWidth' },
+	'thumbnailwidth' => { 60 => 0xfa54 },
+	'tilelength' => { 48 => 0x143 },
+	'tilewidth' => { 48 => 0x142 },
+	'time' => { 134 => 0x7 },
+	'timecreated' => { 54 => 0x3c, 59 => 0x14, 66 => 0x10, 138 => 'TimeCreated' },
+	'timerlength' => { 25 => 0x80c },
+	'timescaleparamsframeoverlappingpercentage' => { 164 => 'timeScaleParamsFrameOverlappingPercentage' },
+	'timescaleparamsframesize' => { 164 => 'timeScaleParamsFrameSize' },
+	'timescaleparamsquality' => { 164 => 'timeScaleParamsQuality' },
+	'timesent' => { 55 => 0x50 },
+	'timesignature' => { 164 => 'timeSignature' },
+	'timesincepoweron' => { 126 => 0x29 },
+	'timestamp' => { 1 => 0x11c, 2 => 0x45e, 125 => 'TimeStamp' },
+	'timezonecode' => { 41 => 0x1 },
+	'timezoneinfo' => { 41 => 0x2 },
+	'timezoneoffset' => { 48 => 0x882a },
+	'tint' => { 154 => 'Tint' },
+	'title' => { 71 => 'Title', 125 => 'Title', 142 => 'Title', 155 => 'title', 159 => 'Title' },
+	'tonecomp' => { 98 => 0x81 },
+	'tonecurve' => { 21 => 0x1, 134 => 0x402, 154 => 'ToneCurve' },
+	'tonecurveactive' => { 42 => 0x110 },
+	'tonecurvename' => { 154 => 'ToneCurveName' },
+	'tonecurveproperty' => { 42 => 0x3c },
+	'tonecurves' => { 134 => 0x403 },
+	'toningeffect' => { 13 => 0xf },
+	'toningeffectmonochrome' => { 1 => 0x108 },
+	'totalzoom' => { 59 => 0x62 },
+	'tracknumber' => { 164 => 'trackNumber' },
+	'trailersignature' => { 78 => 'zmie' },
+	'transferfunction' => { 161 => 'TransferFunction' },
+	'transmissionreference' => { 160 => 'TransmissionReference' },
+	'travelday' => { 126 => 0x36 },
+	'ttl_da_adown' => { 132 => 0x5 },
+	'ttl_da_aup' => { 132 => 0x4 },
+	'ttl_da_bdown' => { 132 => 0x7 },
+	'ttl_da_bup' => { 132 => 0x6 },
+	'tvvalue' => { 34 => 0x1 },
+	'type' => { 155 => 'type' },
+	'uniquecameramodel' => { 48 => 0xc614 },
+	'uniquedocumentid' => { 54 => 0xbb },
+	'uniqueobjectname' => { 55 => 0x64 },
+	'unknownblock' => { 119 => 0x1103 },
+	'unknowncompensation' => { 146 => 0xc },
+	'unsharp1color' => { 113 => 0x13 },
+	'unsharp1halowidth' => { 113 => 0x19 },
+	'unsharp1intensity' => { 113 => 0x17 },
+	'unsharp1threshold' => { 113 => 0x1b },
+	'unsharp2color' => { 113 => 0x2e },
+	'unsharp2halowidth' => { 113 => 0x34 },
+	'unsharp2intensity' => { 113 => 0x32 },
+	'unsharp2threshold' => { 113 => 0x36 },
+	'unsharp3color' => { 113 => 0x49 },
+	'unsharp3halowidth' => { 113 => 0x4f },
+	'unsharp3intensity' => { 113 => 0x4d },
+	'unsharp3threshold' => { 113 => 0x51 },
+	'unsharp4color' => { 113 => 0x64 },
+	'unsharp4halowidth' => { 113 => 0x6a },
+	'unsharp4intensity' => { 113 => 0x68 },
+	'unsharp4threshold' => { 113 => 0x6c },
+	'unsharpcount' => { 113 => 0x0 },
+	'unsharpmask' => { 109 => 0x76a43200 },
+	'urgency' => { 54 => 0xa, 160 => 'Urgency' },
+	'url' => { 71 => 'URL', 125 => 'URL', 140 => 0x40b },
+	'usablemeteringmodes' => { 25 => 0x10a },
+	'usableshootingmodes' => { 25 => 0x109 },
+	'usageterms' => { 167 => 'UsageTerms' },
+	'usercomment' => { 38 => 0x805, 48 => 0x9286, 157 => 'UserComment' },
+	'userdef1picturestyle' => { 1 => 0x10c },
+	'userdef2picturestyle' => { 1 => 0x10e },
+	'userdef3picturestyle' => { 1 => 0x110 },
+	'userfields' => { 150 => 'UserFields' },
+	'usmlenselectronicmf' => { 24 => 0x7, 25 => 0x501 },
+	'utmeasting' => { 82 => 'Easting' },
+	'utmmapdatum' => { 82 => 'Datum' },
+	'utmnorthing' => { 82 => 'Northing' },
+	'utmzone' => { 82 => 'Zone' },
+	'validbits' => { 119 => 0x611, 120 => 0x102c },
+	'validpixeldepth' => { 123 => 0x611 },
+	'variousmodes' => { 59 => 0x26 },
+	'variousmodes2' => { 59 => 0x3a },
+	'variprogram' => { 98 => 0xab },
+	'version' => { 52 => 0x0, 142 => 'Version', 154 => 'Version' },
+	'versionid' => { 165 => 'VersionID' },
+	'versionscomments' => { 165 => 'VersionsComments' },
+	'versionseventaction' => { 165 => 'VersionsEventAction' },
+	'versionseventinstanceid' => { 165 => 'VersionsEventInstanceID' },
+	'versionseventparameters' => { 165 => 'VersionsEventParameters' },
+	'versionseventsoftwareagent' => { 165 => 'VersionsEventSoftwareAgent' },
+	'versionseventwhen' => { 165 => 'VersionsEventWhen' },
+	'versionsmodifier' => { 165 => 'VersionsModifier' },
+	'versionsmodifydate' => { 165 => 'VersionsModifyDate' },
+	'versionsversion' => { 165 => 'VersionsVersion' },
+	'vibrance' => { 154 => 'Vibrance' },
+	'videoalphamode' => { 164 => 'videoAlphaMode' },
+	'videoalphapremultiplecolora' => { 164 => 'videoAlphaPremultipleColorA' },
+	'videoalphapremultiplecolorb' => { 164 => 'videoAlphaPremultipleColorB' },
+	'videoalphapremultiplecolorblack' => { 164 => 'videoAlphaPremultipleColorBlack' },
+	'videoalphapremultiplecolorblue' => { 164 => 'videoAlphaPremultipleColorBlue' },
+	'videoalphapremultiplecolorcyan' => { 164 => 'videoAlphaPremultipleColorCyan' },
+	'videoalphapremultiplecolorgreen' => { 164 => 'videoAlphaPremultipleColorGreen' },
+	'videoalphapremultiplecolorl' => { 164 => 'videoAlphaPremultipleColorL' },
+	'videoalphapremultiplecolormagenta' => { 164 => 'videoAlphaPremultipleColorMagenta' },
+	'videoalphapremultiplecolormode' => { 164 => 'videoAlphaPremultipleColorMode' },
+	'videoalphapremultiplecolorred' => { 164 => 'videoAlphaPremultipleColorRed' },
+	'videoalphapremultiplecolorswatchname' => { 164 => 'videoAlphaPremultipleColorSwatchName' },
+	'videoalphapremultiplecolortype' => { 164 => 'videoAlphaPremultipleColorType' },
+	'videoalphapremultiplecoloryellow' => { 164 => 'videoAlphaPremultipleColorYellow' },
+	'videoalphaunityistransparent' => { 164 => 'videoAlphaUnityIsTransparent' },
+	'videocolorspace' => { 164 => 'videoColorSpace' },
+	'videocompressor' => { 164 => 'videoCompressor' },
+	'videofieldorder' => { 164 => 'videoFieldOrder' },
+	'videoframerate' => { 164 => 'videoFrameRate' },
+	'videoframesizeh' => { 164 => 'videoFrameSizeH' },
+	'videoframesizeunit' => { 164 => 'videoFrameSizeUnit' },
+	'videoframesizew' => { 164 => 'videoFrameSizeW' },
+	'videomoddate' => { 164 => 'videoModDate' },
+	'videopixelaspectratio' => { 164 => 'videoPixelAspectRatio' },
+	'videopixeldepth' => { 164 => 'videoPixelDepth' },
+	'viewinfoduringexposure' => { 25 => 0x407 },
+	'vignetteamount' => { 154 => 'VignetteAmount' },
+	'vignettecontrol' => { 109 => 0x76a43205 },
+	'vignettecontrolintensity' => { 109 => 0xac6bd5c0 },
+	'vignettemidpoint' => { 154 => 'VignetteMidpoint' },
+	'voicememo' => { 145 => 0x216 },
+	'vrdoffset' => { 16 => 0xd0 },
+	'wb_rbgglevels' => { 93 => 0x0 },
+	'wb_rblevels' => { 119 => 0x100 },
+	'wb_rblevelsauto' => { 123 => 0x110 },
+	'wb_rblevelscloudy' => { 123 => 0x121 },
+	'wb_rblevelscoolwhitefluor' => { 123 => 0x132 },
+	'wb_rblevelsdaylightfluor' => { 123 => 0x130 },
+	'wb_rblevelsdaywhitefluor' => { 123 => 0x131 },
+	'wb_rblevelseveningsunlight' => { 123 => 0x124 },
+	'wb_rblevelsfineweather' => { 123 => 0x122 },
+	'wb_rblevelsshade' => { 123 => 0x120 },
+	'wb_rblevelstungsten' => { 123 => 0x123 },
+	'wb_rblevelsused' => { 123 => 0x100 },
+	'wb_rblevelswhitefluorescent' => { 123 => 0x133 },
+	'wb_rgbglevels' => { 95 => 0x0 },
+	'wb_rggblevels' => { 94 => 0x0 },
+	'wb_rggblevelsasshot' => { 6 => 0x19, 7 => 0x18, 8 => 0x3f },
+	'wb_rggblevelsauto' => { 5 => 0x0, 6 => 0x1e, 7 => 0x22, 8 => 0x44 },
+	'wb_rggblevelscloudy' => { 5 => 0xc, 6 => 0x2d, 7 => 0x31, 8 => 0x58, 134 => 0x20f },
+	'wb_rggblevelscustom' => { 5 => 0x1c, 8 => 0x80 },
+	'wb_rggblevelscustom1' => { 6 => 0x41 },
+	'wb_rggblevelscustom2' => { 6 => 0x46 },
+	'wb_rggblevelsdaylight' => { 5 => 0x4, 6 => 0x23, 7 => 0x27, 8 => 0x4e, 134 => 0x20d },
+	'wb_rggblevelsflash' => { 5 => 0x18, 6 => 0x3c, 7 => 0x45, 8 => 0x6c, 134 => 0x214 },
+	'wb_rggblevelsfluorescent' => { 5 => 0x14, 6 => 0x37, 7 => 0x3b, 8 => 0x62 },
+	'wb_rggblevelsfluorescentd' => { 134 => 0x211 },
+	'wb_rggblevelsfluorescentn' => { 134 => 0x212 },
+	'wb_rggblevelsfluorescentw' => { 134 => 0x213 },
+	'wb_rggblevelskelvin' => { 5 => 0x20, 7 => 0x40, 8 => 0x67 },
+	'wb_rggblevelsmeasured' => { 8 => 0x49 },
+	'wb_rggblevelspc1' => { 7 => 0x90, 8 => 0x71 },
+	'wb_rggblevelspc2' => { 7 => 0x95, 8 => 0x76 },
+	'wb_rggblevelspc3' => { 7 => 0x9a, 8 => 0x7b },
+	'wb_rggblevelsshade' => { 5 => 0x8, 6 => 0x28, 7 => 0x2c, 8 => 0x53, 134 => 0x20e },
+	'wb_rggblevelstungsten' => { 5 => 0x10, 6 => 0x32, 7 => 0x36, 8 => 0x5d, 134 => 0x210 },
+	'wb_rggblevelsunknown' => { 7 => 0x1d },
+	'wb_rggblevelsunknown10' => { 7 => 0x72 },
+	'wb_rggblevelsunknown11' => { 7 => 0x77 },
+	'wb_rggblevelsunknown12' => { 7 => 0x7c },
+	'wb_rggblevelsunknown13' => { 7 => 0x81 },
+	'wb_rggblevelsunknown14' => { 7 => 0x86 },
+	'wb_rggblevelsunknown15' => { 7 => 0x8b },
+	'wb_rggblevelsunknown16' => { 7 => 0x9f },
+	'wb_rggblevelsunknown2' => { 7 => 0x4a },
+	'wb_rggblevelsunknown3' => { 7 => 0x4f },
+	'wb_rggblevelsunknown4' => { 7 => 0x54 },
+	'wb_rggblevelsunknown5' => { 7 => 0x59 },
+	'wb_rggblevelsunknown6' => { 7 => 0x5e },
+	'wb_rggblevelsunknown7' => { 7 => 0x63 },
+	'wb_rggblevelsunknown8' => { 7 => 0x68 },
+	'wb_rggblevelsunknown9' => { 7 => 0x6d },
+	'wbadjbluebalance' => { 114 => 0x8 },
+	'wbadjcolortemp' => { 42 => 0x1a },
+	'wbadjlighting' => { 114 => 0x15 },
+	'wbadjmode' => { 114 => 0x10 },
+	'wbadjredbalance' => { 114 => 0x0 },
+	'wbadjrgblevels' => { 42 => 0x8 },
+	'wbadjtemperature' => { 114 => 0x18 },
+	'wbadjustab' => { 126 => 0x46 },
+	'wbadjustgm' => { 126 => 0x47 },
+	'wbbluelevel' => { 126 => 0x8006, 127 => 0x26 },
+	'wbbracketmode' => { 13 => 0x9 },
+	'wbbracketvalueab' => { 13 => 0xc },
+	'wbbracketvaluegm' => { 13 => 0xd },
+	'wbfinetuneactive' => { 42 => 0x24 },
+	'wbfinetunesaturation' => { 42 => 0x28 },
+	'wbfinetunetone' => { 42 => 0x2c },
+	'wbgreenlevel' => { 126 => 0x8005, 127 => 0x25 },
+	'wblevels' => { 91 => 0x4 },
+	'wbmediaimagesizesetting' => { 25 => 0x708 },
+	'wbmode' => { 90 => 0x4, 120 => 0x1015 },
+	'wbredlevel' => { 126 => 0x8004, 127 => 0x24 },
+	'wbscale' => { 91 => 0x0 },
+	'wbshiftab' => { 21 => 0xc },
+	'wbshiftgm' => { 21 => 0xd },
+	'webstatement' => { 167 => 'WebStatement' },
+	'whitebalance' => { 21 => 0x8, 22 => 0x7, 44 => 0x7, 45 => [0x19,0x2012], 48 => [0xa403,0xfe4e], 52 => 0x1002, 59 => 0x40, 84 => 0x3, 85 => 0xe, 86 => 0x4, 87 => 0xb, 98 => 0x5, 103 => 0x7, 126 => 0x3, 134 => 0x19, 136 => 0x7, 143 => 0x26, 146 => [0x3c,0x7], 154 => 'WhiteBalance', 157 => 'WhiteBalance' },
+	'whitebalance2' => { 115 => 0x500 },
+	'whitebalanceadj' => { 42 => 0x18, 109 => 0x76a43204 },
+	'whitebalancebias' => { 45 => 0x2011, 120 => 0x304, 126 => 0x23 },
+	'whitebalanceblue' => { 21 => 0x7 },
+	'whitebalancebracket' => { 115 => 0x502, 120 => 0x303 },
+	'whitebalancecomp' => { 123 => 0x1001 },
+	'whitebalancefinetune' => { 98 => 0xb },
+	'whitebalancemode' => { 134 => 0x1a },
+	'whitebalancered' => { 21 => 0x6 },
+	'whitebalancetemperature' => { 115 => 0x501 },
+	'whiteboard' => { 120 => 0x301 },
+	'whitepoint' => { 48 => 0x13e, 134 => 0x201, 161 => 'WhitePoint' },
+	'widefocuszone' => { 84 => 0x2f },
+	'widerange' => { 145 => 0x20f },
+	'workcolorspace' => { 42 => 0x270 },
+	'worldtimelocation' => { 126 => 0x3a, 134 => 0x22 },
+	'writer-editor' => { 54 => 0x7a },
+	'x3filllight' => { 146 => 0x12 },
+	'xmp' => { 49 => 'XMP' },
+	'xpauthor' => { 48 => 0x9c9d },
+	'xpcomment' => { 48 => 0x9c9c },
+	'xpkeywords' => { 48 => 0x9c9e },
+	'xposition' => { 48 => 0x11e },
+	'xpsubject' => { 48 => 0x9c9f },
+	'xptitle' => { 48 => 0x9c9b },
+	'xresolution' => { 48 => 0x11a, 57 => 0x3, 141 => 0x0, 161 => 'XResolution' },
+	'xyresolution' => { 51 => 0x3 },
+	'ycbcrcoefficients' => { 48 => 0x211, 161 => 'YCbCrCoefficients' },
+	'ycbcrpositioning' => { 48 => 0x213, 161 => 'YCbCrPositioning' },
+	'ycbcrsubsampling' => { 48 => 0x212, 161 => 'YCbCrSubSampling' },
+	'yearcreated' => { 59 => 0x10, 66 => 0xc },
+	'yposition' => { 48 => 0x11f },
+	'yresolution' => { 48 => 0x11b, 57 => 0x5, 141 => 0x4, 161 => 'YResolution' },
+	'zonematching' => { 88 => 0x10a, 90 => 0x3a },
+	'zonematchingon' => { 86 => 0x75 },
+	'zoomsourcewidth' => { 4 => 0x24 },
+	'zoomstepcount' => { 118 => 0x300, 120 => 0x100d },
+	'zoomtargetwidth' => { 4 => 0x25 },
+);
+
+# lookup for non-writable tags to check if the name exists
+my %tagExists = (
+	'abstract' => 1,
+	'adobe' => 1,
+	'adobe_cm' => 1,
+	'adobecmtype' => 1,
+	'adobecrw' => 1,
+	'adobemrw' => 1,
+	'adobephotoshop' => 1,
+	'adoberaf' => 1,
+	'adobesr2' => 1,
+	'advancedcontentencryption' => 1,
+	'advancedmutualexcl' => 1,
+	'aeinfo' => 1,
+	'afaperture' => 1,
+	'afarea' => 1,
+	'afareaheight' => 1,
+	'afareaheights' => 1,
+	'afareawidth' => 1,
+	'afareawidths' => 1,
+	'afareaxpositions' => 1,
+	'afareaypositions' => 1,
+	'afcp' => 1,
+	'afcp_iptc' => 1,
+	'afimageheight' => 1,
+	'afimagewidth' => 1,
+	'afinfo' => 1,
+	'afinfocus' => 1,
+	'afinfosize' => 1,
+	'afpointsinfocus1d' => 1,
+	'afpointsselected' => 1,
+	'albumartist' => 1,
+	'albumcoverurl' => 1,
+	'albumname' => 1,
+	'albumsortorder' => 1,
+	'albumtitle' => 1,
+	'aliaslayermetadata' => 1,
+	'alphabitdepth' => 1,
+	'alphabytecount' => 1,
+	'alphachannelsnames' => 1,
+	'alphacompression' => 1,
+	'alphadatadiscard' => 1,
+	'alphafilter' => 1,
+	'alphaidentifiers' => 1,
+	'alphainterlace' => 1,
+	'alphaoffset' => 1,
+	'alphasample' => 1,
+	'analogbalance' => 1,
+	'annotation' => 1,
+	'annotations' => 1,
+	'aperture' => 1,
+	'aperturedisplayed' => 1,
+	'apeversion' => 1,
+	'app14flags0' => 1,
+	'app14flags1' => 1,
+	'app1_profile' => 1,
+	'applestoreid' => 1,
+	'applicationnotes' => 1,
+	'appversion' => 1,
+	'archivallocation' => 1,
+	'artistlen' => 1,
+	'artisturl' => 1,
+	'asfleakybucketpairs' => 1,
+	'asfpacketcount' => 1,
+	'asfsecurityobjectssize' => 1,
+	'aspectratio' => 1,
+	'aspectratiox' => 1,
+	'aspectratioy' => 1,
+	'asshotneutral' => 1,
+	'association' => 1,
+	'atob0' => 1,
+	'atob1' => 1,
+	'atob2' => 1,
+	'audiences' => 1,
+	'audiobitrate' => 1,
+	'audiobytes' => 1,
+	'audiochannels' => 1,
+	'audiocodecdescription' => 1,
+	'audiocodecid' => 1,
+	'audiocodecname' => 1,
+	'audiodelay' => 1,
+	'audioencoding' => 1,
+	'audiofilesize' => 1,
+	'audiofileurl' => 1,
+	'audioformat' => 1,
+	'audioframesize' => 1,
+	'audioinfo' => 1,
+	'audiolayer' => 1,
+	'audiomode' => 1,
+	'audiosamplebits' => 1,
+	'audiosamplesize' => 1,
+	'audiosize' => 1,
+	'audiosourceurl' => 1,
+	'audiostream' => 1,
+	'authorlen' => 1,
+	'authorship' => 1,
+	'authorurl' => 1,
+	'aux' => 1,
+	'averagelevel' => 1,
+	'avgbitrate' => 1,
+	'avgbytespersec' => 1,
+	'avgpacketsize' => 1,
+	'avif' => 1,
+	'aviheader' => 1,
+	'background' => 1,
+	'backgroundcolor' => 1,
+	'backgroundcolorindicator' => 1,
+	'backgroundcolorvalue' => 1,
+	'backgroundimageid' => 1,
+	'backgroundtiling' => 1,
+	'backlight' => 1,
+	'backserial' => 1,
+	'badfaxlines' => 1,
+	'band' => 1,
+	'bandwidthsharing' => 1,
+	'bannerimage' => 1,
+	'bannerimagedata' => 1,
+	'bannerimagetype' => 1,
+	'bannerimageurl' => 1,
+	'basisobject' => 1,
+	'batteryinfo' => 1,
+	'batterylevel' => 1,
+	'beatsperminute' => 1,
+	'binaryfilter' => 1,
+	'bitrate' => 1,
+	'bitratemutualexclusion' => 1,
+	'bitsperextendedrunlength' => 1,
+	'bitsperrunlength' => 1,
+	'blackleveldeltah' => 1,
+	'blackleveldeltav' => 1,
+	'blacklevelrepeatdim' => 1,
+	'blocklocation' => 1,
+	'blocksize' => 1,
+	'blocksizemax' => 1,
+	'blocksizemin' => 1,
+	'blocksperframe' => 1,
+	'blueadjust' => 1,
+	'bluegain' => 1,
+	'bluematrixcolumn' => 1,
+	'blueprimary' => 1,
+	'bluesample' => 1,
+	'bluetrc' => 1,
+	'bluex' => 1,
+	'bluey' => 1,
+	'bordercolor' => 1,
+	'borderid' => 1,
+	'borderinformation' => 1,
+	'borderlocation' => 1,
+	'bordername' => 1,
+	'bordersversion' => 1,
+	'bordertype' => 1,
+	'bottommag' => 1,
+	'boundaryorigin' => 1,
+	'boundingbox' => 1,
+	'bracketshot' => 1,
+	'brightnessdata' => 1,
+	'broadcast' => 1,
+	'btoa0' => 1,
+	'btoa1' => 1,
+	'btoa2' => 1,
+	'bufferaverage' => 1,
+	'burstshot' => 1,
+	'bw_halftoninginfo' => 1,
+	'bw_transferfunc' => 1,
+	'bytes' => 1,
+	'bytesperminute' => 1,
+	'cachecontrol' => 1,
+	'cachedimageheight' => 1,
+	'cachedimagewidth' => 1,
+	'calibrationdatetime' => 1,
+	'camera' => 1,
+	'camerabacktype' => 1,
+	'cameracalibration1' => 1,
+	'cameracalibration2' => 1,
+	'cameradatetime' => 1,
+	'camerainfo' => 1,
+	'cameraname' => 1,
+	'cameraobjbacktype' => 1,
+	'cameraobject' => 1,
+	'cameraobjname' => 1,
+	'cameraobjtype' => 1,
+	'cameraobjversion' => 1,
+	'cameraowner' => 1,
+	'cameraprofileversion' => 1,
+	'camerasettings' => 1,
+	'camerasettings2' => 1,
+	'camerasetup' => 1,
+	'cameraspecification' => 1,
+	'can_skip_backward' => 1,
+	'can_skip_forward' => 1,
+	'canon' => 1,
+	'canon_afinfo2_0x000d' => 1,
+	'canon_afinfo_0x000b' => 1,
+	'canonafinfo' => 1,
+	'canonafinfo2' => 1,
+	'canoncamerainfo' => 1,
+	'canoncamerainfo1dmkiii' => 1,
+	'canoncamerainfo2' => 1,
+	'canoncamerainfounknown16' => 1,
+	'canoncamerainfounknown32' => 1,
+	'canoncamerainfounknown8' => 1,
+	'canoncamerasettings' => 1,
+	'canoncolorinfo1' => 1,
+	'canoncolorinfo2' => 1,
+	'canonfileinfo' => 1,
+	'canonflags' => 1,
+	'canonfocallength' => 1,
+	'canonimageheight' => 1,
+	'canonimagewidth' => 1,
+	'canonpanorama' => 1,
+	'canonrawmakemodel' => 1,
+	'canonshotinfo' => 1,
+	'canseektoend' => 1,
+	'captiontext' => 1,
+	'captprofbacktype' => 1,
+	'captprofname' => 1,
+	'captproftype' => 1,
+	'captprofversion' => 1,
+	'captureconditionspar' => 1,
+	'capturedevicefid' => 1,
+	'captureobjbacktype' => 1,
+	'captureobjname' => 1,
+	'captureobjtype' => 1,
+	'captureobjversion' => 1,
+	'captureprofile' => 1,
+	'captureresolution' => 1,
+	'captureserial' => 1,
+	'capturesetup' => 1,
+	'capturexresolution' => 1,
+	'capturexresolutionunit' => 1,
+	'captureyresolution' => 1,
+	'captureyresolutionunit' => 1,
+	'casio' => 1,
+	'cc' => 1,
+	'ccdrect' => 1,
+	'ccdvalidrect' => 1,
+	'ccdvideorect' => 1,
+	'centerdarkrect' => 1,
+	'cfalayout' => 1,
+	'cfapattern2' => 1,
+	'cfaplanecolor' => 1,
+	'cfarepeatpatterndim' => 1,
+	'channelmode' => 1,
+	'charcount' => 1,
+	'charcountwithspaces' => 1,
+	'charset' => 1,
+	'chartarget' => 1,
+	'chromaticadaptation' => 1,
+	'chromaticity' => 1,
+	'chromaticitychannel1' => 1,
+	'chromaticitychannel2' => 1,
+	'chromaticitychannel3' => 1,
+	'chromaticitychannel4' => 1,
+	'chromaticitychannels' => 1,
+	'chromaticitycolorant' => 1,
+	'ciff' => 1,
+	'circleofconfusion' => 1,
+	'class' => 1,
+	'classification' => 1,
+	'cleanfaxdata' => 1,
+	'clipboundary' => 1,
+	'clipobjects' => 1,
+	'clippath' => 1,
+	'clippingboundary' => 1,
+	'clippingpathname' => 1,
+	'cloneid' => 1,
+	'cloneobject' => 1,
+	'clonetype' => 1,
+	'cmmflags' => 1,
+	'codecflavorid' => 1,
+	'codeclist' => 1,
+	'codedframesize' => 1,
+	'codepage' => 1,
+	'codestreamheader' => 1,
+	'codestreamregistration' => 1,
+	'codingmethods' => 1,
+	'colorant1coordinates' => 1,
+	'colorant1name' => 1,
+	'colorant2coordinates' => 1,
+	'colorant2name' => 1,
+	'colorant3coordinates' => 1,
+	'colorant3name' => 1,
+	'colorantcount' => 1,
+	'colorantorder' => 1,
+	'coloranttable' => 1,
+	'coloraverages' => 1,
+	'colorbalance0100' => 1,
+	'colorbalance0102' => 1,
+	'colorbalance0103' => 1,
+	'colorbalance02' => 1,
+	'colorbalance0205' => 1,
+	'colorbalance2' => 1,
+	'colorbalance3' => 1,
+	'colorbalanceunknown' => 1,
+	'colorbitdepth' => 1,
+	'colorboostdata' => 1,
+	'colorbw' => 1,
+	'colorcalibrationmatrix' => 1,
+	'colorcasts' => 1,
+	'colorcharacterization' => 1,
+	'colorcomponents' => 1,
+	'colorgroup' => 1,
+	'colorhalftoninginfo' => 1,
+	'colorinfo' => 1,
+	'colorinfod30' => 1,
+	'colormap' => 1,
+	'colormatrix1' => 1,
+	'colorobjbacktype' => 1,
+	'colorobjname' => 1,
+	'colorobjtype' => 1,
+	'colorobjversion' => 1,
+	'colorpalette' => 1,
+	'colorresponseunit' => 1,
+	'colors' => 1,
+	'colorsamplersresource' => 1,
+	'colorsetup' => 1,
+	'colorspacedata' => 1,
+	'colorspecification' => 1,
+	'colortable' => 1,
+	'colortransferfuncs' => 1,
+	'colortransform' => 1,
+	'colortwistmatrix' => 1,
+	'colortype' => 1,
+	'commentlen' => 1,
+	'comments' => 1,
+	'commenttime' => 1,
+	'commercialurl' => 1,
+	'commissioned' => 1,
+	'common' => 1,
+	'company' => 1,
+	'compatibility' => 1,
+	'compilation' => 1,
+	'compobj' => 1,
+	'compobjusertype' => 1,
+	'compobjusertypelen' => 1,
+	'componentbitdepth' => 1,
+	'componentdefinition' => 1,
+	'componentmapping' => 1,
+	'compositinglayerheader' => 1,
+	'composition' => 1,
+	'compositionmode' => 1,
+	'compositionoptions' => 1,
+	'compressed' => 1,
+	'compressedtext' => 1,
+	'compressionlevel' => 1,
+	'compressiontype' => 1,
+	'compressor' => 1,
+	'compressorid' => 1,
+	'concreteflag' => 1,
+	'condition' => 1,
+	'conditionalfec' => 1,
+	'conductor' => 1,
+	'confirmedobjectsize' => 1,
+	'connectionspaceilluminant' => 1,
+	'consecutivebadfaxlines' => 1,
+	'cont' => 1,
+	'containerformat' => 1,
+	'contake' => 1,
+	'contentbranding' => 1,
+	'contentdescription' => 1,
+	'contentdescriptionnotes' => 1,
+	'contentdisposition' => 1,
+	'contentdistributor' => 1,
+	'contentencryption' => 1,
+	'contentgroupdescription' => 1,
+	'contentlanguage' => 1,
+	'contentrating' => 1,
+	'contentscripttype' => 1,
+	'contentstyletype' => 1,
+	'contenttype' => 1,
+	'contiguouscodestream' => 1,
+	'contrastadjustment' => 1,
+	'copyrightlen' => 1,
+	'copyrighturl' => 1,
+	'coverart' => 1,
+	'coverartmimetype' => 1,
+	'cpuversions' => 1,
+	'crdinfo' => 1,
+	'creatingapplication' => 1,
+	'creatingtransform' => 1,
+	'creationpathvector' => 1,
+	'cropdata' => 1,
+	'cropped' => 1,
+	'cross-reference' => 1,
+	'crs' => 1,
+	'cuepoint' => 1,
+	'currentbitrate' => 1,
+	'currenttime' => 1,
+	'currentuser' => 1,
+	'customfunctions10d' => 1,
+	'customfunctions1d' => 1,
+	'customfunctions2' => 1,
+	'customfunctions20d' => 1,
+	'customfunctions30d' => 1,
+	'customfunctions350d' => 1,
+	'customfunctions400d' => 1,
+	'customfunctions5d' => 1,
+	'customfunctionsd30' => 1,
+	'customfunctionsd60' => 1,
+	'customfunctionsunknown' => 1,
+	'd-lightinghqdata' => 1,
+	'd-lightinghsdata' => 1,
+	'darkcorrectiontype' => 1,
+	'data' => 1,
+	'datacreatedate' => 1,
+	'datadump' => 1,
+	'datadump2' => 1,
+	'datakey' => 1,
+	'datalen' => 1,
+	'datamodifydate' => 1,
+	'dataobject' => 1,
+	'dataobjectid' => 1,
+	'dataobjectstatus' => 1,
+	'dataobjecttitle' => 1,
+	'dataoffset' => 1,
+	'dataoffsets' => 1,
+	'datapackets' => 1,
+	'datareference' => 1,
+	'datasize' => 1,
+	'datatype' => 1,
+	'datetimecreated' => 1,
+	'dc' => 1,
+	'dctencodeversion' => 1,
+	'dealeridnumber' => 1,
+	'decimationmethod' => 1,
+	'decimationprefilterwidth' => 1,
+	'decode' => 1,
+	'decodertable' => 1,
+	'defaultdisplayheight' => 1,
+	'defaultdisplaywidth' => 1,
+	'defaultimagecolor' => 1,
+	'defaultrgb' => 1,
+	'defaultstyle' => 1,
+	'defineobject' => 1,
+	'delay' => 1,
+	'deltapngheader' => 1,
+	'deltatype' => 1,
+	'deltaxy' => 1,
+	'depth' => 1,
+	'desiredreproductions' => 1,
+	'destinationid' => 1,
+	'deviceattributes' => 1,
+	'devicemanufacturer' => 1,
+	'devicemfgdesc' => 1,
+	'devicemodel' => 1,
+	'devicemodeldesc' => 1,
+	'devicesettingdescription' => 1,
+	'devicesettings' => 1,
+	'dex' => 1,
+	'dicom' => 1,
+	'dictionary' => 1,
+	'digitaleffectsname' => 1,
+	'digitaleffectstype' => 1,
+	'digitaleffectsversion' => 1,
+	'digitalimagebroker' => 1,
+	'digitalsignature' => 1,
+	'dimensions' => 1,
+	'dinf' => 1,
+	'director' => 1,
+	'discardobjects' => 1,
+	'disknumber' => 1,
+	'displayinfo' => 1,
+	'displayresolution' => 1,
+	'displaysize' => 1,
+	'displayunits' => 1,
+	'displayxresolution' => 1,
+	'displayxresolutionunit' => 1,
+	'displayyresolution' => 1,
+	'displayyresolutionunit' => 1,
+	'dispose' => 1,
+	'distribution' => 1,
+	'dngadobedata' => 1,
+	'dngpentaxdata' => 1,
+	'dngprivatedata' => 1,
+	'docclass' => 1,
+	'docrights' => 1,
+	'doctype' => 1,
+	'documentinfo' => 1,
+	'dof' => 1,
+	'donotshow' => 1,
+	'dotsperinch' => 1,
+	'drm' => 1,
+	'drm_contentid' => 1,
+	'drm_drmheader' => 1,
+	'drm_drmheader_contentdistributor' => 1,
+	'drm_drmheader_contentid' => 1,
+	'drm_drmheader_individualizedversion' => 1,
+	'drm_drmheader_keyid' => 1,
+	'drm_drmheader_licenseacqurl' => 1,
+	'drm_drmheader_subscriptioncontentid' => 1,
+	'drm_individualizedversion' => 1,
+	'drm_keyid' => 1,
+	'drm_lasignaturecert' => 1,
+	'drm_lasignaturelicsrvcert' => 1,
+	'drm_lasignatureprivkey' => 1,
+	'drm_lasignaturerootcert' => 1,
+	'drm_licenseacqurl' => 1,
+	'drm_v1licenseacqurl' => 1,
+	'dropbykeyword' => 1,
+	'dropchunks' => 1,
+	'ducky' => 1,
+	'duotonehalftoninginfo' => 1,
+	'duotoneimageinfo' => 1,
+	'duotonetransferfuncs' => 1,
+	'dustremovaldata' => 1,
+	'dvdid' => 1,
+	'dynamicrangeoptimizer' => 1,
+	'edit1' => 1,
+	'edit2' => 1,
+	'edit3' => 1,
+	'edit4' => 1,
+	'edit5' => 1,
+	'edit6' => 1,
+	'edit7' => 1,
+	'edit8' => 1,
+	'edit9' => 1,
+	'edittagarray' => 1,
+	'effectivebw' => 1,
+	'effectivemaxaperture' => 1,
+	'effectsvisible' => 1,
+	'emphasis' => 1,
+	'encodedby' => 1,
+	'encodedusing' => 1,
+	'encoder' => 1,
+	'encodersettings' => 1,
+	'encoderversion' => 1,
+	'encoding' => 1,
+	'encodingprocess' => 1,
+	'encodingsettings' => 1,
+	'encodingtime' => 1,
+	'encryption' => 1,
+	'endpoints' => 1,
+	'eppim' => 1,
+	'epsoptions' => 1,
+	'equipment' => 1,
+	'equipment2' => 1,
+	'error' => 1,
+	'errorcorrection' => 1,
+	'errorcorrectiontype' => 1,
+	'evalstate' => 1,
+	'events' => 1,
+	'exif' => 1,
+	'exif_profile' => 1,
+	'exifinfo' => 1,
+	'exifinformation' => 1,
+	'exifoffset' => 1,
+	'exiftoolversion' => 1,
+	'exitpupilposition' => 1,
+	'expires' => 1,
+	'exportimage' => 1,
+	'exposureadjust' => 1,
+	'exposureinfo' => 1,
+	'extcache' => 1,
+	'extendedcontentdescr' => 1,
+	'extendedcontentencryption' => 1,
+	'extendedstreamprops' => 1,
+	'extenderstatus' => 1,
+	'extensionclassid' => 1,
+	'extensioncreatedate' => 1,
+	'extensiondescription' => 1,
+	'extensionmodifydate' => 1,
+	'extensionname' => 1,
+	'extensionpersistence' => 1,
+	'extensions' => 1,
+	'extrasamples' => 1,
+	'facedetect1' => 1,
+	'facedetect2' => 1,
+	'fastseek' => 1,
+	'faxprofile' => 1,
+	'faxrecvparams' => 1,
+	'faxrecvtime' => 1,
+	'faxsubaddress' => 1,
+	'fileid' => 1,
+	'fileinfolen' => 1,
+	'fileinfolen2' => 1,
+	'fileinfoproperties' => 1,
+	'fileinfoversion' => 1,
+	'fileowner' => 1,
+	'fileproperties' => 1,
+	'filerul' => 1,
+	'files' => 1,
+	'filesize' => 1,
+	'filesizebytes' => 1,
+	'filetype' => 1,
+	'fillmethod' => 1,
+	'filmbrand' => 1,
+	'filmcategory' => 1,
+	'filmframenumber' => 1,
+	'filmgencode' => 1,
+	'filmproductcode' => 1,
+	'filmrollnumber' => 1,
+	'filmsize' => 1,
+	'filtering' => 1,
+	'finalframeblocks' => 1,
+	'firstobject' => 1,
+	'firstobjectid' => 1,
+	'flags' => 1,
+	'flashexpcomp' => 1,
+	'flashinfo' => 1,
+	'flashon' => 1,
+	'flashpixstreamfieldoffset' => 1,
+	'flashpixstreampathname' => 1,
+	'flashpower' => 1,
+	'flashttlmode' => 1,
+	'flashversion' => 1,
+	'focallength35efl' => 1,
+	'focusinfo' => 1,
+	'focusinfo2' => 1,
+	'focuspos' => 1,
+	'footnotes' => 1,
+	'formatter' => 1,
+	'formatversion' => 1,
+	'formatversiontime' => 1,
+	'fotostation' => 1,
+	'fourcc1' => 1,
+	'fourcc2' => 1,
+	'fourcc2len' => 1,
+	'fourcc3' => 1,
+	'fourcc3len' => 1,
+	'fpxr' => 1,
+	'fractalparameters' => 1,
+	'fragmentlist' => 1,
+	'fragmenttable' => 1,
+	'frame' => 1,
+	'framecount' => 1,
+	'framepriority' => 1,
+	'framerate' => 1,
+	'framesize' => 1,
+	'framesizemax' => 1,
+	'framesizemin' => 1,
+	'frametype' => 1,
+	'free' => 1,
+	'freebytecounts' => 1,
+	'freeoffsets' => 1,
+	'fujifilm' => 1,
+	'fujilayout' => 1,
+	'gain' => 1,
+	'gamut' => 1,
+	'gapless' => 1,
+	'gdalmetadata' => 1,
+	'gdalnodata' => 1,
+	'geminfo' => 1,
+	'generator' => 1,
+	'genr' => 1,
+	'genreid' => 1,
+	'geo' => 1,
+	'geogangularunits' => 1,
+	'geogangularunitsize' => 1,
+	'geogazimuthunits' => 1,
+	'geogcitation' => 1,
+	'geogellipsoid' => 1,
+	'geoggeodeticdatum' => 1,
+	'geoginvflattening' => 1,
+	'geoglinearunits' => 1,
+	'geoglinearunitsize' => 1,
+	'geogprimemeridian' => 1,
+	'geogprimemeridianlong' => 1,
+	'geographictype' => 1,
+	'geogsemimajoraxis' => 1,
+	'geogsemiminoraxis' => 1,
+	'geotiffasciiparams' => 1,
+	'geotiffdirectory' => 1,
+	'geotiffdoubleparams' => 1,
+	'geotiffversion' => 1,
+	'gifapplicationextension' => 1,
+	'gifgraphiccontrolextension' => 1,
+	'gifplaintextextension' => 1,
+	'globalinfo' => 1,
+	'globalparametersifd' => 1,
+	'globalpixelsize' => 1,
+	'googlebot' => 1,
+	'gps' => 1,
+	'gpsinfo' => 1,
+	'gpsposition' => 1,
+	'graphicconverter' => 1,
+	'graphicstechnologystandardoutput' => 1,
+	'grayresponsecurve' => 1,
+	'graytrc' => 1,
+	'greenadjust' => 1,
+	'greengain' => 1,
+	'greenmatrixcolumn' => 1,
+	'greenprimary' => 1,
+	'greensample' => 1,
+	'greentrc' => 1,
+	'greenx' => 1,
+	'greeny' => 1,
+	'gridguidesinfo' => 1,
+	'groupcaption' => 1,
+	'grouping' => 1,
+	'groupmutualexclusion' => 1,
+	'gtcitation' => 1,
+	'gtmodeltype' => 1,
+	'gtrastertype' => 1,
+	'hasarbitrarydatastream' => 1,
+	'hasattachedimages' => 1,
+	'hasaudio' => 1,
+	'hascuepoints' => 1,
+	'hasfiletransferstream' => 1,
+	'hasicc' => 1,
+	'hasimage' => 1,
+	'haskeyframes' => 1,
+	'hasmetadata' => 1,
+	'hasscript' => 1,
+	'hasvideo' => 1,
+	'hcusage' => 1,
+	'hdrl' => 1,
+	'header' => 1,
+	'headerext' => 1,
+	'headerextension' => 1,
+	'headersize' => 1,
+	'headingpairs' => 1,
+	'heightresolution' => 1,
+	'hiddenslides' => 1,
+	'highlightendpoints' => 1,
+	'http-equiv' => 1,
+	'hyperfocaldistance' => 1,
+	'hyperlinkbase' => 1,
+	'hyperlinks' => 1,
+	'hyperlinkschanged' => 1,
+	'icc_untagged' => 1,
+	'iccbased' => 1,
+	'id' => 1,
+	'id3' => 1,
+	'id3v1' => 1,
+	'id3v2_2' => 1,
+	'id3v2_3' => 1,
+	'id3v2_4' => 1,
+	'identification' => 1,
+	'idsbasevalue' => 1,
+	'ifd0_offset' => 1,
+	'image' => 1,
+	'imagebounds' => 1,
+	'imagebytecount' => 1,
+	'imagecolorindicator' => 1,
+	'imagecolorvalue' => 1,
+	'imagedata' => 1,
+	'imagedatadiscard' => 1,
+	'imagedepth' => 1,
+	'imagefields' => 1,
+	'imageformat' => 1,
+	'imageheader' => 1,
+	'imageid' => 1,
+	'imageinfo' => 1,
+	'imagelayer' => 1,
+	'imagelength' => 1,
+	'imageoffset' => 1,
+	'imageprintstatus' => 1,
+	'imageprocessing2' => 1,
+	'imageprofile' => 1,
+	'imageprops' => 1,
+	'imagerboardid' => 1,
+	'imageresources' => 1,
+	'imagerotated' => 1,
+	'imagerotationstatus' => 1,
+	'imagesourceek' => 1,
+	'imagestatus' => 1,
+	'imagetoolbar' => 1,
+	'imgprofbacktype' => 1,
+	'imgprofname' => 1,
+	'imgproftype' => 1,
+	'imgprofversion' => 1,
+	'index' => 1,
+	'indexable' => 1,
+	'indexed' => 1,
+	'indexedcolourtablecount' => 1,
+	'indexoffset' => 1,
+	'indexparameters' => 1,
+	'info' => 1,
+	'infolist' => 1,
+	'information' => 1,
+	'initialkey' => 1,
+	'inknames' => 1,
+	'inputdataobjectlist' => 1,
+	'inputprofile' => 1,
+	'instructionset' => 1,
+	'integrationtime' => 1,
+	'intellectualproperty' => 1,
+	'intellectualpropertynotes' => 1,
+	'intensitystereo' => 1,
+	'intergraphflagregisters' => 1,
+	'intergraphmatrix' => 1,
+	'intergraphpacketdata' => 1,
+	'interlace' => 1,
+	'internationaltext' => 1,
+	'internetradiostationname' => 1,
+	'internetradiostationowner' => 1,
+	'internetradiostationurl' => 1,
+	'interopoffset' => 1,
+	'interpretedby' => 1,
+	'involvedpeople' => 1,
+	'iptc' => 1,
+	'iptc_profile' => 1,
+	'iptcapplication' => 1,
+	'iptccore' => 1,
+	'iptcdata' => 1,
+	'iptcenvelope' => 1,
+	'iptcnewsphoto' => 1,
+	'iptcobjectdata' => 1,
+	'iptcpostobjectdata' => 1,
+	'iptcpreobjectdata' => 1,
+	'is_protected' => 1,
+	'is_trusted' => 1,
+	'isospeed' => 1,
+	'isrc' => 1,
+	'isrcnumber' => 1,
+	'isvbr' => 1,
+	'it8header' => 1,
+	'iterationcount' => 1,
+	'iterationendaction' => 1,
+	'iterationmax' => 1,
+	'iterationminmax' => 1,
+	'iterations' => 1,
+	'itunesinfo' => 1,
+	'jfif' => 1,
+	'jfifversion' => 1,
+	'jfxx' => 1,
+	'jngheader' => 1,
+	'jp2header' => 1,
+	'jp2signature' => 1,
+	'jpeg_quality' => 1,
+	'jpegactables' => 1,
+	'jpegdctables' => 1,
+	'jpeglosslesspredictors' => 1,
+	'jpegpointtransforms' => 1,
+	'jpegproc' => 1,
+	'jpegqtables' => 1,
+	'jpegrestartinterval' => 1,
+	'jpegtables' => 1,
+	'jumptoxpep' => 1,
+	'kbytesize' => 1,
+	'keyframepositions' => 1,
+	'keyframestimes' => 1,
+	'kids' => 1,
+	'kodak' => 1,
+	'kodakbordersifd' => 1,
+	'kodakeffectsifd' => 1,
+	'konicaminolta' => 1,
+	'languagelist' => 1,
+	'lastkeyframetime' => 1,
+	'lastmodifier' => 1,
+	'lastobject' => 1,
+	'lastobjectid' => 1,
+	'lastprinted' => 1,
+	'lastsavedby' => 1,
+	'lasttimestamp' => 1,
+	'layersgroupinfo' => 1,
+	'layerstateinfo' => 1,
+	'leafautoactive' => 1,
+	'leafautobasename' => 1,
+	'leafdata' => 1,
+	'leafhotfolder' => 1,
+	'leafopenprochdr' => 1,
+	'leafoutputfiletype' => 1,
+	'leafsaveselection' => 1,
+	'leafsubifd' => 1,
+	'leftdarkrect' => 1,
+	'leftmag' => 1,
+	'length' => 1,
+	'lens35efl' => 1,
+	'lensdata0100' => 1,
+	'lensdata0101' => 1,
+	'lensdata0201' => 1,
+	'lensdataunknown' => 1,
+	'lensfocalrange' => 1,
+	'lensshading' => 1,
+	'lensspec' => 1,
+	'lightness' => 1,
+	'lights' => 1,
+	'lightvalue' => 1,
+	'linearizationtable' => 1,
+	'lines' => 1,
+	'linksuptodate' => 1,
+	'lit' => 1,
+	'localdeltatype' => 1,
+	'localeindicator' => 1,
+	'lockedpropertylist' => 1,
+	'locks' => 1,
+	'lookheadbacktype' => 1,
+	'lookheader' => 1,
+	'lookheadname' => 1,
+	'lookheadtype' => 1,
+	'lookheadversion' => 1,
+	'lookuptable' => 1,
+	'loopstyle' => 1,
+	'lotus' => 1,
+	'lr' => 1,
+	'luminance' => 1,
+	'luminanceconsts' => 1,
+	'lyricist' => 1,
+	'lyrics' => 1,
+	'lyrics_synchronised' => 1,
+	'macintoshprintinfo' => 1,
+	'magnification' => 1,
+	'magnifyobject' => 1,
+	'makeandmodel' => 1,
+	'makernotes' => 1,
+	'mandatorybackground' => 1,
+	'marker' => 1,
+	'markerid' => 1,
+	'mattcolor' => 1,
+	'matte' => 1,
+	'matteing' => 1,
+	'maxband' => 1,
+	'maxbitrate' => 1,
+	'maxdatarate' => 1,
+	'maximumbitrate' => 1,
+	'maximumimageindex' => 1,
+	'maximumobjectsize' => 1,
+	'maximumoperationindex' => 1,
+	'maximumtransformindex' => 1,
+	'maxjpegtableindex' => 1,
+	'maxpacketsize' => 1,
+	'maxpagenormal' => 1,
+	'maxsubfilesize' => 1,
+	'maxval' => 1,
+	'mcdi' => 1,
+	'mdat' => 1,
+	'mdcolortable' => 1,
+	'mdfiletag' => 1,
+	'mdfileunits' => 1,
+	'mdlabname' => 1,
+	'mdpr' => 1,
+	'mdprepdate' => 1,
+	'mdpreptime' => 1,
+	'mdsampleinfo' => 1,
+	'mdscalepixel' => 1,
+	'measuredinfo' => 1,
+	'measurement' => 1,
+	'measurementbacking' => 1,
+	'measurementflare' => 1,
+	'measurementgeometry' => 1,
+	'measurementilluminant' => 1,
+	'measurementobserver' => 1,
+	'media' => 1,
+	'mediablackpoint' => 1,
+	'mediaclassprimaryid' => 1,
+	'mediaclasssecondaryid' => 1,
+	'mediacredits' => 1,
+	'mediadata' => 1,
+	'mediaindex' => 1,
+	'mediaisdelay' => 1,
+	'mediaisfinale' => 1,
+	'mediaislive' => 1,
+	'mediaispremiere' => 1,
+	'mediaisrepeat' => 1,
+	'mediaissap' => 1,
+	'mediaisstereo' => 1,
+	'mediaissubtitled' => 1,
+	'mediaistape' => 1,
+	'medianetworkaffiliation' => 1,
+	'mediaoriginalbroadcastdatetime' => 1,
+	'mediaoriginalchannel' => 1,
+	'mediapro' => 1,
+	'mediastationcallsign' => 1,
+	'mediastationname' => 1,
+	'mediawhitepoint' => 1,
+	'medium' => 1,
+	'meta' => 1,
+	'metadata' => 1,
+	'metadatacreator' => 1,
+	'metadatalibrary' => 1,
+	'metadatanumber' => 1,
+	'microsoft' => 1,
+	'mie' => 1,
+	'mimetype' => 1,
+	'minf' => 1,
+	'minimumbitrate' => 1,
+	'minoltacamerasettings' => 1,
+	'minoltacamerasettings2' => 1,
+	'minoltacamerasettings5d' => 1,
+	'minoltacamerasettings7d' => 1,
+	'minoltacamerasettingsa100' => 1,
+	'minoltacamerasettingsold' => 1,
+	'minoltamakernote' => 1,
+	'minoltaprd' => 1,
+	'minoltarif' => 1,
+	'minoltattw' => 1,
+	'minoltawbg' => 1,
+	'minpacketsize' => 1,
+	'mmclips' => 1,
+	'mngheader' => 1,
+	'modeextension' => 1,
+	'model2' => 1,
+	'modelandversion' => 1,
+	'modeltiepoint' => 1,
+	'modeltransform' => 1,
+	'modenumber' => 1,
+	'modifiedby' => 1,
+	'modifiedinfo' => 1,
+	'montage' => 1,
+	'mood' => 1,
+	'mosaicpattern' => 1,
+	'moveobjects' => 1,
+	'movie' => 1,
+	'movieheader' => 1,
+	'mpeg7binary' => 1,
+	'mpegaudioversion' => 1,
+	'msstereo' => 1,
+	'multiexposure' => 1,
+	'multimediatype' => 1,
+	'multiquality' => 1,
+	'musiccdidentifier' => 1,
+	'musiciancredits' => 1,
+	'mycolors' => 1,
+	'name' => 1,
+	'namedcolor' => 1,
+	'namedcolor2' => 1,
+	'namelength' => 1,
+	'narrator' => 1,
+	'nativedisplayinfo' => 1,
+	'nativeresolutionunit' => 1,
+	'nativexresolution' => 1,
+	'nativeyresolution' => 1,
+	'ncc' => 1,
+	'nefcurve1' => 1,
+	'nefcurve2' => 1,
+	'nestlevel' => 1,
+	'netexposurecompensation' => 1,
+	'neutals' => 1,
+	'neutobjbacktype' => 1,
+	'neutobjname' => 1,
+	'neutobjtype' => 1,
+	'neutobjversion' => 1,
+	'neutrals' => 1,
+	'newbitdepth' => 1,
+	'newcolortype' => 1,
+	'nexttrackid' => 1,
+	'nikon' => 1,
+	'nikoncapturedata' => 1,
+	'nikoncaptureoffsets' => 1,
+	'nikonpreview' => 1,
+	'nikonscanifd' => 1,
+	'nikontags' => 1,
+	'noise' => 1,
+	'noisereductiondata' => 1,
+	'nominalbitrate' => 1,
+	'nominalframecount' => 1,
+	'nominallayercount' => 1,
+	'nominalplaytime' => 1,
+	'nomssmarttags' => 1,
+	'notes' => 1,
+	'npts' => 1,
+	'nsc_address' => 1,
+	'nsc_description' => 1,
+	'nsc_email' => 1,
+	'nsc_name' => 1,
+	'nsc_phone' => 1,
+	'numafpoints' => 1,
+	'numberlist' => 1,
+	'numberofcomponents' => 1,
+	'numberofframes' => 1,
+	'numberofinks' => 1,
+	'numberofplanes' => 1,
+	'numberofresolutions' => 1,
+	'numchannels' => 1,
+	'numcolors' => 1,
+	'numimportantcolors' => 1,
+	'numpackets' => 1,
+	'numproperties' => 1,
+	'numrules' => 1,
+	'numsampleframes' => 1,
+	'numstreams' => 1,
+	'objectid' => 1,
+	'objectsizeannounced' => 1,
+	'objecttype' => 1,
+	'obsoletephotoshoptag1' => 1,
+	'obsoletephotoshoptag2' => 1,
+	'obsoletephotoshoptag3' => 1,
+	'oceapplicationselector' => 1,
+	'oceidnumber' => 1,
+	'oceimagelogic' => 1,
+	'ocescanjobdesc' => 1,
+	'offsetorigin' => 1,
+	'offsetxy' => 1,
+	'olympus' => 1,
+	'olympus2100' => 1,
+	'olympus2200' => 1,
+	'olympus2300' => 1,
+	'olympus2400' => 1,
+	'olympus2500' => 1,
+	'olympus2600' => 1,
+	'olympus2700' => 1,
+	'olympus2800' => 1,
+	'olympus2900' => 1,
+	'opacity' => 1,
+	'operation' => 1,
+	'operationclassid' => 1,
+	'operationid' => 1,
+	'operationnumber' => 1,
+	'opiproxy' => 1,
+	'optimalbitrate' => 1,
+	'opto-electricconvfactor' => 1,
+	'orderingrestrictions' => 1,
+	'organization' => 1,
+	'originalalbum' => 1,
+	'originalalbumtitle' => 1,
+	'originalartist' => 1,
+	'originaldocumentsize' => 1,
+	'originalimagebroker' => 1,
+	'originallyricist' => 1,
+	'originalmedia' => 1,
+	'originalmedium' => 1,
+	'originalrawcreator' => 1,
+	'originalrawfiletype' => 1,
+	'originalrawimage' => 1,
+	'originalrawresource' => 1,
+	'originalreleasetime' => 1,
+	'originalreleaseyear' => 1,
+	'originalscannedimagesize' => 1,
+	'originalthmcreator' => 1,
+	'originalthmfiletype' => 1,
+	'originalthmimage' => 1,
+	'originalthmresource' => 1,
+	'othercodecdescription' => 1,
+	'othercodecname' => 1,
+	'otherimage' => 1,
+	'otherimagelength' => 1,
+	'otherimagestart' => 1,
+	'outputdataobjectlist' => 1,
+	'outputprofile' => 1,
+	'outputresponse' => 1,
+	'packets' => 1,
+	'padding' => 1,
+	'page' => 1,
+	'pagecount' => 1,
+	'pageenter' => 1,
+	'pageexit' => 1,
+	'pagefront' => 1,
+	'pagenormal' => 1,
+	'pages' => 1,
+	'pagespecial' => 1,
+	'palette' => 1,
+	'palettehistogram' => 1,
+	'panasonic' => 1,
+	'paragraphs' => 1,
+	'parameter' => 1,
+	'parentalrating' => 1,
+	'parentalratingreason' => 1,
+	'partialpalette' => 1,
+	'partofset' => 1,
+	'pastclippingboundary' => 1,
+	'pasteimage' => 1,
+	'patternangle' => 1,
+	'paymenturl' => 1,
+	'pcscitation' => 1,
+	'pdahistogram' => 1,
+	'pdf' => 1,
+	'peakbitrate' => 1,
+	'peakvalue' => 1,
+	'pentax' => 1,
+	'pentaxtags' => 1,
+	'performer' => 1,
+	'performers' => 1,
+	'performersortorder' => 1,
+	'period' => 1,
+	'perpicturenotes' => 1,
+	'personalfunctions' => 1,
+	'personalfunctionvalues' => 1,
+	'photoeffectsdata' => 1,
+	'photomech' => 1,
+	'photomechanic' => 1,
+	'photoshop' => 1,
+	'photoshop2colortable' => 1,
+	'photoshop2info' => 1,
+	'photoshopbgrthumbnail' => 1,
+	'photoshopdata' => 1,
+	'photoshopformat' => 1,
+	'photoshopsettings' => 1,
+	'photoshopthumbnail' => 1,
+	'physicalpixel' => 1,
+	'physicalstreamnumbermap' => 1,
+	'physicalstreamnumbers' => 1,
+	'physicalstreams' => 1,
+	'picslabel' => 1,
+	'picture' => 1,
+	'pictureinfo' => 1,
+	'pieceinfo' => 1,
+	'pixelaspectratio' => 1,
+	'pixelcalibration' => 1,
+	'pixelformat' => 1,
+	'pixelintensityrange' => 1,
+	'pixellive' => 1,
+	'pixelscale' => 1,
+	'pixelspermeterx' => 1,
+	'pixelspermetery' => 1,
+	'pixelsperunitx' => 1,
+	'pixelsperunity' => 1,
+	'pixelunits' => 1,
+	'places' => 1,
+	'planes' => 1,
+	'playallframes' => 1,
+	'playcounter' => 1,
+	'playduration' => 1,
+	'playgap' => 1,
+	'playlistdelay' => 1,
+	'playselection' => 1,
+	'postertime' => 1,
+	'postscript2crd0' => 1,
+	'postscript2crd1' => 1,
+	'postscript2crd2' => 1,
+	'postscript2csa' => 1,
+	'pragma' => 1,
+	'preferredrate' => 1,
+	'preferredvolume' => 1,
+	'preroll' => 1,
+	'presentationtarget' => 1,
+	'preview' => 1,
+	'preview0' => 1,
+	'preview1' => 1,
+	'preview2' => 1,
+	'previewatomindex' => 1,
+	'previewatomtype' => 1,
+	'previewdate' => 1,
+	'previewdescription' => 1,
+	'previewduration' => 1,
+	'previewifd_offset' => 1,
+	'previewimagedata' => 1,
+	'previewimageinfo' => 1,
+	'previewinfo' => 1,
+	'previewmimetype' => 1,
+	'previewpict' => 1,
+	'previewtime' => 1,
+	'previewtype' => 1,
+	'previewversion' => 1,
+	'primaryafpoint' => 1,
+	'primaryplatform' => 1,
+	'printflags' => 1,
+	'printflagsinfo' => 1,
+	'printquality' => 1,
+	'printtovideo' => 1,
+	'priority' => 1,
+	'private' => 1,
+	'proccessinginfo' => 1,
+	'prod' => 1,
+	'prodnotes' => 1,
+	'produceddate' => 1,
+	'producednotice' => 1,
+	'product' => 1,
+	'profile' => 1,
+	'profileclass' => 1,
+	'profilecmmtype' => 1,
+	'profileconnectionspace' => 1,
+	'profilecopyright' => 1,
+	'profilecreator' => 1,
+	'profiledatetime' => 1,
+	'profiledescription' => 1,
+	'profiledescriptionml' => 1,
+	'profilefilesignature' => 1,
+	'profileheader' => 1,
+	'profileid' => 1,
+	'profilesequencedesc' => 1,
+	'profiletype' => 1,
+	'profileversion' => 1,
+	'progid' => 1,
+	'progressivescans' => 1,
+	'projazimuthangle' => 1,
+	'projcentereasting' => 1,
+	'projcenterlat' => 1,
+	'projcenterlong' => 1,
+	'projcenternorthing' => 1,
+	'projcoordtrans' => 1,
+	'projectedcstype' => 1,
+	'projection' => 1,
+	'projfalseeasting' => 1,
+	'projfalsenorthing' => 1,
+	'projfalseorigineasting' => 1,
+	'projfalseoriginlat' => 1,
+	'projfalseoriginlong' => 1,
+	'projfalseoriginnorthing' => 1,
+	'projlinearunits' => 1,
+	'projlinearunitsize' => 1,
+	'projnatoriginlat' => 1,
+	'projnatoriginlong' => 1,
+	'projrectifiedgridangle' => 1,
+	'projscaleatcenter' => 1,
+	'projscaleatnatorigin' => 1,
+	'projstdparallel1' => 1,
+	'projstdparallel2' => 1,
+	'projstraightvertpolelong' => 1,
+	'promoteparent' => 1,
+	'promotionurl' => 1,
+	'prop' => 1,
+	'properties' => 1,
+	'propertysetidcodes' => 1,
+	'propertysetpathname' => 1,
+	'propertyvectorelements' => 1,
+	'protect' => 1,
+	'protectiontype' => 1,
+	'provider' => 1,
+	'providercopyright' => 1,
+	'providerrating' => 1,
+	'providerstyle' => 1,
+	'ps2crdvmsize' => 1,
+	'ps2renteringintent' => 1,
+	'pstringcaption' => 1,
+	'publisherurl' => 1,
+	'quickmaskinfo' => 1,
+	'ra3' => 1,
+	'ra4' => 1,
+	'ra5' => 1,
+	'radiostationname' => 1,
+	'radiostationowner' => 1,
+	'rasterpadding' => 1,
+	'rawdata' => 1,
+	'rawdatarotation' => 1,
+	'rawdev2' => 1,
+	'rawdev2_2' => 1,
+	'rawdevelopment' => 1,
+	'rawdevelopment2' => 1,
+	'rawimagefullsize' => 1,
+	'rawimagemode' => 1,
+	'rawinfo' => 1,
+	'rawinfo2' => 1,
+	'rawjpginfo' => 1,
+	'readerrequirements' => 1,
+	'recengineer' => 1,
+	'reclocation' => 1,
+	'reconstructiontype' => 1,
+	'recordingdates' => 1,
+	'recordingtime' => 1,
+	'rect' => 1,
+	'rectangleofinterest' => 1,
+	'redadjust' => 1,
+	'redeyedata' => 1,
+	'redeyereduction' => 1,
+	'redgain' => 1,
+	'redmatrixcolumn' => 1,
+	'redprimary' => 1,
+	'redsample' => 1,
+	'redtrc' => 1,
+	'reductionmatrix1' => 1,
+	'reductionmatrix2' => 1,
+	'redx' => 1,
+	'redy' => 1,
+	'refresh' => 1,
+	'relatedimagefile' => 1,
+	'renderingintent' => 1,
+	'replaygainalbumgain' => 1,
+	'replaygainalbumpeak' => 1,
+	'replaygaintrackgain' => 1,
+	'replaygaintrackpeak' => 1,
+	'replyto' => 1,
+	'requirements' => 1,
+	'reserved1' => 1,
+	'resolutioninfo' => 1,
+	'resources' => 1,
+	'resourcesneeded' => 1,
+	'resourcetype' => 1,
+	'resultaspectratio' => 1,
+	'revisiondate' => 1,
+	'revisionnumber' => 1,
+	'revisitafter' => 1,
+	'rgb_profile' => 1,
+	'ricoh' => 1,
+	'ricohdatetime1' => 1,
+	'ricohdatetime2' => 1,
+	'ricohrr1subdir' => 1,
+	'ricohsubdir' => 1,
+	'rightdarkrect' => 1,
+	'rightmag' => 1,
+	'rjmd' => 1,
+	'rmeta' => 1,
+	'robots' => 1,
+	'rocinfo' => 1,
+	'roidescription' => 1,
+	'rollguidelements' => 1,
+	'root' => 1,
+	'rotationangle' => 1,
+	'sampleformat' => 1,
+	'samplerate2' => 1,
+	'samplesize' => 1,
+	'sanyomov' => 1,
+	'sanyomp4' => 1,
+	'saveobjbacktype' => 1,
+	'saveobjects' => 1,
+	'saveobjname' => 1,
+	'saveobjtype' => 1,
+	'saveobjversion' => 1,
+	'savesetup' => 1,
+	'sba_rgbshifts' => 1,
+	'sbaexposurerecord' => 1,
+	'sbainputimagebitdepth' => 1,
+	'sbainputimagecolorspace' => 1,
+	'scale' => 1,
+	'scalecrop' => 1,
+	'scalefactor35efl' => 1,
+	'scandate' => 1,
+	'scannermake' => 1,
+	'scannermodel' => 1,
+	'scannerpixelsize' => 1,
+	'scannerserialnumber' => 1,
+	'scanoperatorid' => 1,
+	'scansoftware' => 1,
+	'scansoftwarerevisiondate' => 1,
+	'screening' => 1,
+	'screeningdesc' => 1,
+	'screennail' => 1,
+	'scriptcommand' => 1,
+	'security' => 1,
+	'seekable' => 1,
+	'seekpoint' => 1,
+	'selection' => 1,
+	'selectionduration' => 1,
+	'selectiontime' => 1,
+	'selobjbacktype' => 1,
+	'selobjname' => 1,
+	'selobjtype' => 1,
+	'selobjversion' => 1,
+	'sendduration' => 1,
+	'sensorbottomborder' => 1,
+	'sensorid' => 1,
+	'sensorinfo' => 1,
+	'sensorleftborder' => 1,
+	'sensorrightborder' => 1,
+	'sensortopborder' => 1,
+	'serviceorganizationname' => 1,
+	'setcookie' => 1,
+	'setinfo' => 1,
+	'setsubtitle' => 1,
+	'shadowendpoints' => 1,
+	'shakereductioninfo' => 1,
+	'shareddoc' => 1,
+	'shareduserrating' => 1,
+	'sharpinfo' => 1,
+	'sharpmethod' => 1,
+	'sharpnessapproximation' => 1,
+	'sharpnessfreqtable' => 1,
+	'sharpnesstable' => 1,
+	'sharpobjbacktype' => 1,
+	'sharpobjname' => 1,
+	'sharpobjtype' => 1,
+	'sharpobjversion' => 1,
+	'shootingrecord' => 1,
+	'shootobjbacktype' => 1,
+	'shootobjname' => 1,
+	'shootobjtype' => 1,
+	'shootobjversion' => 1,
+	'shootsetup' => 1,
+	'shotinfo' => 1,
+	'shotinfoversion' => 1,
+	'showmode' => 1,
+	'showobjects' => 1,
+	'shuttercurtainhack' => 1,
+	'shutterspeed' => 1,
+	'shutterspeeddisplayed' => 1,
+	'sidebars' => 1,
+	'sigma' => 1,
+	'signalnumber' => 1,
+	'signature' => 1,
+	'signature_name' => 1,
+	'significantbits' => 1,
+	'signtype' => 1,
+	'simpleindex' => 1,
+	'simplicityprofile' => 1,
+	'singlequality' => 1,
+	'site' => 1,
+	'siteenter' => 1,
+	'siteexit' => 1,
+	'size' => 1,
+	'sizemode' => 1,
+	'skip' => 1,
+	'slices' => 1,
+	'slides' => 1,
+	'slideshow' => 1,
+	'smaxsamplevalue' => 1,
+	'sminsamplevalue' => 1,
+	'snapshotid' => 1,
+	'snapshotname' => 1,
+	'softedit' => 1,
+	'softwarerelease' => 1,
+	'sony' => 1,
+	'sourcedate' => 1,
+	'sourceedition' => 1,
+	'sourceform' => 1,
+	'sourceid' => 1,
+	'sourceimagedirectory' => 1,
+	'sourceimagefilename' => 1,
+	'sourceimagevolumename' => 1,
+	'sourcepublisher' => 1,
+	'sourcerights' => 1,
+	'sourcetitle' => 1,
+	'sourceurl' => 1,
+	'spatialfrequencyresponse' => 1,
+	'spatialorientation' => 1,
+	'specialeffectsopticalfilter' => 1,
+	'spiff' => 1,
+	'spiffversion' => 1,
+	'spothalftone' => 1,
+	'sr2dataifd' => 1,
+	'sr2private' => 1,
+	'sr2subifdkey' => 1,
+	'sr2subifdlength' => 1,
+	'sr2subifdoffset' => 1,
+	'srf2_key' => 1,
+	'srgbrendering' => 1,
+	'stamptoolcount' => 1,
+	'startofframe' => 1,
+	'stbl' => 1,
+	'stdautoactive' => 1,
+	'stdbasename' => 1,
+	'stdhotfolder' => 1,
+	'stdopeninphotoshop' => 1,
+	'stdoutputbitdepth' => 1,
+	'stdoutputcolormode' => 1,
+	'stdoutputfiletype' => 1,
+	'stdoxygen' => 1,
+	'stdsaveselection' => 1,
+	'stdscaledoutput' => 1,
+	'stdsharpenoutput' => 1,
+	'stereo' => 1,
+	'stonits' => 1,
+	'storage-streampathname' => 1,
+	'stream' => 1,
+	'streamavgbitrate' => 1,
+	'streamavgpacketsize' => 1,
+	'streambitrateprops' => 1,
+	'streamcount' => 1,
+	'streamdata' => 1,
+	'streamduration' => 1,
+	'streamheader' => 1,
+	'streaminfo' => 1,
+	'streammaxbitrate' => 1,
+	'streammaxpacketsize' => 1,
+	'streammimelen' => 1,
+	'streammimetype' => 1,
+	'streamname' => 1,
+	'streamnamelen' => 1,
+	'streamnumber' => 1,
+	'streampreroll' => 1,
+	'streamprioritization' => 1,
+	'streamproperties' => 1,
+	'streamstarttime' => 1,
+	'streamtype' => 1,
+	'streamtypeinfo' => 1,
+	'stridable' => 1,
+	'stripbytecounts' => 1,
+	'stripoffsets' => 1,
+	'striprowcounts' => 1,
+	'strobe' => 1,
+	'strobetime' => 1,
+	'subfile' => 1,
+	'subifd' => 1,
+	'subifd0' => 1,
+	'subifd1' => 1,
+	'subifd2' => 1,
+	'subifd3' => 1,
+	'subifd4' => 1,
+	'subifd5' => 1,
+	'subifd_offset' => 1,
+	'subimagecolor' => 1,
+	'subimagehdr' => 1,
+	'subimageheight' => 1,
+	'subimageicc_profile' => 1,
+	'subimagenumericalformat' => 1,
+	'subimageresolutions' => 1,
+	'subimagetilecount' => 1,
+	'subimagetileheight' => 1,
+	'subimagetilewidth' => 1,
+	'subimagewidth' => 1,
+	'subpacketh' => 1,
+	'subpacketsize' => 1,
+	'subscriptioncontentid' => 1,
+	'subsecdatetimeoriginal' => 1,
+	'subtitle' => 1,
+	'subtitledescription' => 1,
+	'suggestedpalette' => 1,
+	'summaryinfo' => 1,
+	't4options' => 1,
+	't6options' => 1,
+	'taggingtime' => 1,
+	'targetaudiences' => 1,
+	'targetdeltatype' => 1,
+	'targetprinter' => 1,
+	'targetxy' => 1,
+	'technician' => 1,
+	'technology' => 1,
+	'template' => 1,
+	'terminationaction' => 1,
+	'terminationcondition' => 1,
+	'termsofuse' => 1,
+	'testtarget' => 1,
+	'text' => 1,
+	'textinfo' => 1,
+	'textualdata' => 1,
+	'things' => 1,
+	'thumbnail' => 1,
+	'thumbnailclip' => 1,
+	'tickspersecond' => 1,
+	'tiff' => 1,
+	'tiff-epstandardid' => 1,
+	'tiffpreview' => 1,
+	'tilebytecounts' => 1,
+	'tiledepth' => 1,
+	'tileoffsets' => 1,
+	'timecode' => 1,
+	'timecodeindex' => 1,
+	'timecodeindexparms' => 1,
+	'timeoffset' => 1,
+	'timescale' => 1,
+	'titlelen' => 1,
+	'titleofparts' => 1,
+	'titlesortorder' => 1,
+	'tocitems' => 1,
+	'tonecurvematching' => 1,
+	'tonecurvetable' => 1,
+	'tonematrix' => 1,
+	'toneobjbacktype' => 1,
+	'toneobjname' => 1,
+	'toneobjtype' => 1,
+	'toneobjversion' => 1,
+	'tones' => 1,
+	'tonespaceflow' => 1,
+	'toolname' => 1,
+	'toolversion' => 1,
+	'topmag' => 1,
+	'totaledittime' => 1,
+	'totalframes' => 1,
+	'totalsamples' => 1,
+	'track' => 1,
+	'trackcategory' => 1,
+	'trackcomments' => 1,
+	'trackcreatedate' => 1,
+	'trackduration' => 1,
+	'trackheader' => 1,
+	'trackid' => 1,
+	'tracklayer' => 1,
+	'tracklyrics' => 1,
+	'trackmodifydate' => 1,
+	'trackversion' => 1,
+	'trackvolume' => 1,
+	'transferrange' => 1,
+	'transfomation' => 1,
+	'transform' => 1,
+	'transformcreatedate' => 1,
+	'transformedimagetitle' => 1,
+	'transformmodifydate' => 1,
+	'transformnodeid' => 1,
+	'transformtitle' => 1,
+	'transparency' => 1,
+	'transparencyindicator' => 1,
+	'transparentindex' => 1,
+	'trapped' => 1,
+	'typeoforiginal' => 1,
+	'ucrbg' => 1,
+	'uncompressed' => 1,
+	'unicodealphanames' => 1,
+	'uniquefileidentifier' => 1,
+	'units' => 1,
+	'unknown' => 1,
+	'unknownblock1' => 1,
+	'unknownblock2' => 1,
+	'unknowntags' => 1,
+	'unsharpdata' => 1,
+	'unused' => 1,
+	'url_list' => 1,
+	'usedextensionnumbers' => 1,
+	'useradjsba_rgbshifts' => 1,
+	'userdata' => 1,
+	'userdefinedid' => 1,
+	'userdefinedtext' => 1,
+	'userdefinedurl' => 1,
+	'userselectgrouptitle' => 1,
+	'userweburl' => 1,
+	'usingtransforms' => 1,
+	'utm' => 1,
+	'uuid-exif' => 1,
+	'uuid-geojp2' => 1,
+	'uuid-iptc' => 1,
+	'uuid-unknown' => 1,
+	'uuid-xmp' => 1,
+	'uuidinfo' => 1,
+	'uuidlist' => 1,
+	'validafpoints' => 1,
+	'vary' => 1,
+	'vbrpeak' => 1,
+	'vendor' => 1,
+	'vendorid' => 1,
+	'version2' => 1,
+	'versionbf' => 1,
+	'versioninfo' => 1,
+	'versionyear' => 1,
+	'verticalcitation' => 1,
+	'verticalcstype' => 1,
+	'verticaldatum' => 1,
+	'verticalunits' => 1,
+	'vibrationreduction' => 1,
+	'video' => 1,
+	'videobitrate' => 1,
+	'videocardgamma' => 1,
+	'videoclosedcaptioning' => 1,
+	'videocodecdescription' => 1,
+	'videocodecid' => 1,
+	'videocodecname' => 1,
+	'videoencoding' => 1,
+	'videoformat' => 1,
+	'videoheight' => 1,
+	'videomode' => 1,
+	'videoquality' => 1,
+	'videosize' => 1,
+	'videowidth' => 1,
+	'viewable' => 1,
+	'viewingconddesc' => 1,
+	'viewingcondilluminant' => 1,
+	'viewingcondilluminanttype' => 1,
+	'viewingconditions' => 1,
+	'viewingcondsurround' => 1,
+	'visibleoutputs' => 1,
+	'vorbiscomment' => 1,
+	'vorbisversion' => 1,
+	'vr_0x66' => 1,
+	'vrd1' => 1,
+	'vrd2' => 1,
+	'vrdstamptool' => 1,
+	'vrdversion' => 1,
+	'vw96' => 1,
+	'wangannotation' => 1,
+	'warning' => 1,
+	'watermark' => 1,
+	'watermarktype' => 1,
+	'wb_grbglevels' => 1,
+	'wb_grgblevels' => 1,
+	'wbadjdata' => 1,
+	'wcsprofiles' => 1,
+	'whitebalancematching' => 1,
+	'whitebalancetable' => 1,
+	'whitelevel' => 1,
+	'whitepointx' => 1,
+	'whitepointy' => 1,
+	'wide' => 1,
+	'widthresolution' => 1,
+	'windowlocation' => 1,
+	'windowtarget' => 1,
+	'wmadrcaveragereference' => 1,
+	'wmadrcaveragetarget' => 1,
+	'wmadrcpeakreference' => 1,
+	'wmadrcpeaktarget' => 1,
+	'wmcollectiongroupid' => 1,
+	'wmcollectionid' => 1,
+	'wmcontentid' => 1,
+	'wordcount' => 1,
+	'workflowurl' => 1,
+	'workingpath' => 1,
+	'writer' => 1,
+	'xclippathunits' => 1,
+	'xmag' => 1,
+	'xmethod' => 1,
+	'xml' => 1,
+	'xmldata' => 1,
+	'xmp_profile' => 1,
+	'xmpbj' => 1,
+	'xmpdm' => 1,
+	'xmpmm' => 1,
+	'xmpplus' => 1,
+	'xmprights' => 1,
+	'xmptpg' => 1,
+	'xylocation' => 1,
+	'xyoffsetinfo' => 1,
+	'yclippathunits' => 1,
+	'year' => 1,
+	'ylevel' => 1,
+	'ymag' => 1,
+	'ymethod' => 1,
+	'ytarget' => 1,
+	'zoom' => 1,
+	'zoompos' => 1,
+);
+
+# module names for writable Composite tags
+my %compositeModules = (
+	'jpgfromraw' => 'Image::ExifTool::Exif',
+	'previewimage' => 'Image::ExifTool::Exif',
+	'thumbnailimage' => 'Image::ExifTool::Exif',
+);
+
+#++++ End automatically generated code ++++
+
+# insert any user-defined tags into our tag lookup
+if (defined %Image::ExifTool::UserDefined) {
+    my ($table, %tableNum, $tagID);
+    my $tnum = 0; # make hash lookup to get table numbers
+    foreach $table (@tableList) {
+        $tableNum{$table} = $tnum++;
+    }
+    my @userTables = sort keys %Image::ExifTool::UserDefined;
+    while (@userTables) {
+        my $table = shift @userTables;
+        $tnum = $tableNum{$table};
+        unless ($tnum) {
+            $tnum = scalar @tableList;
+            push @tableList, $table;
+        }
+        my $userTable = $Image::ExifTool::UserDefined{$table};
+        foreach $tagID (Image::ExifTool::TagTableKeys($userTable)) {
+            my $newInfo = $$userTable{$tagID};
+            if (ref $newInfo eq 'HASH') {
+                $$newInfo{Name} or $$newInfo{Name} = ucfirst($tagID);
+            } else {
+                $newInfo = $$userTable{$tagID} = { Name => $newInfo };
+            }
+            my $lcTag = lc($$newInfo{Name});
+            # add to lookup even though we don't know it is writable
+            # (to save speed by not having to load the module)
+            my $lookup = $tagLookup{$lcTag};
+            $lookup or $lookup = $tagLookup{$lcTag} = { };
+            if ($$lookup{$tnum}) {
+                my $le = $$lookup{$tnum};
+                my @ids = (ref $le eq 'ARRAY') ? @{$le} : ( $le );
+                # only add new tag ID if it didn't already exist
+                next if grep /^$tagID$/, @ids;
+                push @ids, $tagID;
+                $$lookup{$tnum} = \@ids;
+            } else {
+                $$lookup{$tnum} = $tagID;
+            }
+            # add any new subdirectory tables
+            next unless $$newInfo{SubDirectory};
+            my $subTable = $newInfo->{SubDirectory}->{TagTable};
+            next unless $subTable and not defined $tableNum{$subTable};
+            next if $Image::ExifTool::UserDefined{$subTable};
+            no strict 'refs';
+            next unless defined %$subTable;
+            $Image::ExifTool::UserDefined{$subTable} = \%$subTable;
+            push @userTables, $subTable;
+            # save parent table name so we can load it when necessary
+            $$subTable{PARENT} = $table;
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# Return true if the tag exists
+# Inputs: 0) tag name (case insensitive)
+# Returns: true if tag exists
+sub TagExists($)
+{
+    my $tag = lc($_[0]);
+    return 1 if $tagExists{$tag} or $tagLookup{$tag};
+    return 0;
+}
+
+#------------------------------------------------------------------------------
+# Find information for writable tags (case insensitive)
+# Inputs: 0) tag name (case insensitive)
+# Returns: Scalar context: tag info or false if none found
+#          List context: list of all matching tagInfo hashes
+sub FindTagInfo($)
+{
+    local $_;
+    my $tag = shift;
+    my $lcTag = lc($tag);
+    my ($tableNum, @tagInfoList);
+    my $lookup = $tagLookup{$lcTag};
+    if ($lookup) {
+        foreach $tableNum (keys %$lookup) {
+            my $table = GetTagTable($tableList[$tableNum]);
+            my $tagID = $$lookup{$tableNum};
+            my @tagIDs;
+            if (ref $tagID eq 'ARRAY') {
+                @tagIDs = @$tagID;
+            } else {
+                push @tagIDs, $tagID;
+            }
+            foreach $tagID (@tagIDs) {
+                my @infoList = GetTagInfoList($table,$tagID);
+                unless (@infoList) {
+                    my $reload;
+                    # call write proc if it exists in case it adds tags to the table
+                    my $writeProc = $table->{WRITE_PROC};
+                    $reload = 1 if $writeProc and &$writeProc();
+                    # load module with composite tag if necessary
+                    my $compMod = $compositeModules{$lcTag};
+                    $reload = 1 if $compMod and eval "require $compMod";
+                    @infoList = GetTagInfoList($table,$tagID) if $reload;
+                }
+                if (@infoList == 1) {
+                    push @tagInfoList, @infoList;
+                } elsif (@infoList > 1) {
+                    my $tagInfo;
+                    # must check tag list in case tags have different names
+                    foreach $tagInfo (@infoList) {
+                        next unless $lcTag eq lc($$tagInfo{Name});
+                        push @tagInfoList, $tagInfo;
+                    }
+                }
+            }
+        }
+    }
+    if (wantarray) {
+        return @tagInfoList;
+    } else {
+        return $tagInfoList[0];
+    }
+}
+
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::TagLookup - Fast lookup for ExifTool tags
+
+=head1 SYNOPSIS
+
+This module is required by Image::ExifTool for writing tags.
+
+=head1 DESCRIPTION
+
+Provides a fast, case insensitive lookup for tag names.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool(3pm)|Image::ExifTool>,
+L<Image::ExifTool::BuildTagLookup(3pm)|Image::ExifTool::BuildTagLookup>,
+L<Image::ExifTool::TagNames(3pm)|Image::ExifTool::TagNames>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/TagNames.pod
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/TagNames.pod	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/TagNames.pod	(revision 20131)
@@ -0,0 +1,10834 @@
+
+=head1 NAME
+
+Image::ExifTool::TagNames - ExifTool tag name documentation
+
+=head1 DESCRIPTION
+
+This document contains a complete list of ExifTool tag names, organized into
+tables based on information type.  Tag names are used to indicate the
+specific meta information that is extracted or written in an image.
+
+=head1 TAG TABLES
+
+The tables listed below give the names of all tags recognized by ExifTool.
+
+B<Tag ID>, B<Index> or B<Sequence> is given in the first column of each
+table.  A B<Tag ID> is the computer-readable equivalent of a tag name, and
+is the identifier that is actually stored in the file.  An B<Index> refers
+to the location of a value when found at a fixed position within a data
+block, and B<Sequence> gives the order of values for a serial data stream.
+
+A B<Tag Name> is the handle by which the information is accessed in
+ExifTool.  In some instances, more than one name may correspond to a single
+tag ID.  In these cases, the actual name used depends on the context in
+which the information is found.  Case is not significant for tag names.  A
+question mark after a tag name indicates that the information is either not
+understood, not verified, or not very useful -- these tags are not extracted
+by ExifTool unless the Unknown (-u) option is enabled.  Be aware that some
+tag names are different than the descriptions printed out by default when
+extracting information with exiftool.  To see the tag names instead of the
+descriptions, use C<exiftool -s>.
+
+The B<Writable> column indicates whether the tag is writable by ExifTool.
+Anything but an C<N> in this column means the tag is writable.  A C<Y>
+indicates writable information that is either unformatted or written using
+the existing format.  Other expressions give details about the information
+format, and vary depending on the general type of information.  The format
+name may be followed by a number in square brackets to indicate the number
+of values written, or the number of characters in a fixed-length string
+(including a null terminator which is added if required).
+
+An asterisk (C<*>) after an entry in the B<Writable> column indicates a
+"protected" tag which is not writable directly, but is set via a Composite
+tag.  A tilde (C<~>) indicates a tag this is only writable when print
+conversion is disabled (by setting PrintConv to 0, or using the -n option).
+A slash (C</>) indicates an "avoided" tag that is not created unless the
+group is specified (due to name conflicts with other tags).  An exclamation
+point (C<!>) indicates a tag that is considered unsafe to write under normal
+circumstances.  These "unsafe" tags are not set when calling
+SetNewValuesFromFile() or when using the exiftool -TagsFromFile option
+unless specified explicitly, and care should be taken when editing them
+manually since they may affect the way an image is rendered.  A plus sign
+(C<+>) indicates a "list" tag which supports multiple instances.
+
+The HTML version of these tables also list possible B<Values> for
+discrete-valued tags, as well as B<Notes> for some tags.
+
+B<Note>: If you are familiar with common meta-information tag names, you may
+find that some ExifTool tag names are different than expected.  The usual
+reason for this is to make the tag names more consistent across different
+types of meta information.  To determine a tag name, either consult this
+documentation or run C<exiftool -s> on a file containing the information in
+question.
+
+=head2 JPEG Tags
+
+This table lists information extracted by ExifTool from JPEG images.
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  'APP0'       JFIF                             JFIF
+               JFXX                             JFIF Extension
+               CIFF                             CanonRaw
+  'APP1'       EXIF                             EXIF
+               XMP                              XMP
+  'APP2'       ICC_Profile                      ICC_Profile
+               FPXR                             FlashPix
+  'APP3'       Meta                             Kodak Meta
+  'APP5'       RMETA                            Ricoh RMETA
+  'APP6'       EPPIM                            JPEG EPPIM
+  'APP8'       SPIFF                            JPEG SPIFF
+  'APP10'      Comment                          N
+  'APP12'      PictureInfo                      APP12 PictureInfo
+               Ducky                            APP12 Ducky
+  'APP13'      Photoshop                        Photoshop
+               Adobe_CM                         JPEG AdobeCM
+  'APP14'      Adobe                            JPEG Adobe
+  'APP15'      GraphicConverter                 JPEG GraphConv
+  'COM'        Comment                          Y
+  'SOF'        StartOfFrame                     JPEG SOF
+  'Trailer'    AFCP                             AFCP
+               CanonVRD                         CanonVRD
+               FotoStation                      FotoStation
+               PhotoMechanic                    PhotoMechanic
+               MIE                              MIE
+               PreviewImage                     Y
+
+=head3 JPEG EPPIM Tags
+
+APP6 is used in by the Toshiba PDR-M700 to store a TIFF structure containing
+PrintIM information.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0xc4a5   PrintIM                              PrintIM
+
+=head3 JPEG SPIFF Tags
+
+This information is found in APP8 of SPIFF-style JPEG images (the "official"
+yet rarely used JPEG file format standard: Still Picture Interchange File
+Format).
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    SPIFFVersion                         N
+      2    ProfileID                            N
+      3    ColorComponents                      N
+      6    ImageHeight                          N
+     10    ImageWidth                           N
+     14    ColorSpace                           N
+     15    BitsPerSample                        N
+     16    Compression                          N
+     17    ResolutionUnit                       N
+     18    YResolution                          N
+     22    XResolution                          N
+
+=head3 JPEG AdobeCM Tags
+
+The "Adobe_CM" APP13 segment presumably contains color management
+information, but the meaning of the data is currently unknown.  If anyone
+has an idea about what this means, please let me know.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    AdobeCMType                          N
+
+=head3 JPEG Adobe Tags
+
+The "Adobe" APP14 segment stores image encoding information for DCT filters.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    DCTEncodeVersion                     N
+      1    APP14Flags0                          N
+      2    APP14Flags1                          N
+      3    ColorTransform                       N
+
+=head3 JPEG GraphConv Tags
+
+APP15 is used by GraphicConverter to store JPEG quality.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'Q'      Quality                              N
+
+=head3 JPEG SOF Tags
+
+This information is extracted from the JPEG Start Of Frame segment.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  BitsPerSample                                 N
+  ColorComponents                               N
+  EncodingProcess                               N
+  ImageHeight                                   N
+  ImageWidth                                    N
+  YCbCrSubSampling                              N
+
+=head2 EXIF Tags
+
+EXIF stands for "Exchangeable Image File Format".  This type of information
+is formatted according to the TIFF specification, and may be found in JPG,
+TIFF, PNG, MIFF and WDP images, as well as many TIFF-based RAW images.
+
+The EXIF meta information is organized into different Image File Directories
+(IFD's) within an image.  The names of these IFD's correspond to the
+ExifTool family 1 group names.  When writing EXIF information, the default
+B<Group> listed below is used unless another group is specified.
+
+Also listed in the table below are TIFF, DNG, WDP and other tags which are
+not part of the EXIF specification, but may co-exist with EXIF tags in some
+images.
+
+  Tag ID   Tag Name                  Group      Writable
+  ------   --------                  -----      --------
+  0x0001   InteropIndex              InteropIFD string!
+  0x0002   InteropVersion            InteropIFD undef!
+  0x000b   ProcessingSoftware        IFD0       string
+  0x00fe   SubfileType               IFD0       int32u!
+  0x00ff   OldSubfileType            IFD0       int16u!
+  0x0100   ImageWidth                IFD0       int32u!
+  0x0101   ImageHeight               IFD0       int32u!
+  0x0102   BitsPerSample             IFD0       int16u[n]!
+  0x0103   Compression               IFD0       int16u!
+  0x0106   PhotometricInterpretation IFD0       int16u!
+  0x0107   Thresholding              IFD0       int16u!
+  0x0108   CellWidth                 IFD0       int16u!
+  0x0109   CellLength                IFD0       int16u!
+  0x010a   FillOrder                 IFD0       int16u!
+  0x010d   DocumentName              IFD0       string
+  0x010e   ImageDescription          IFD0       string
+  0x010f   Make                      IFD0       string
+  0x0110   Model                     IFD0       string
+  0x0111   StripOffsets              -          N
+           PreviewImageStart         IFD0       int32u*
+           PreviewImageStart         SubIFD1    int32u*
+           JpgFromRawStart           SubIFD2    int32u*
+  0x0112   Orientation               IFD0       int16u
+  0x0115   SamplesPerPixel           IFD0       int16u!
+  0x0116   RowsPerStrip              IFD0       int32u!
+  0x0117   StripByteCounts           -          N
+           PreviewImageLength        IFD0       int32u*
+           PreviewImageLength        SubIFD1    int32u*
+           JpgFromRawLength          SubIFD2    int32u*
+  0x0118   MinSampleValue            IFD0       int16u
+  0x0119   MaxSampleValue            IFD0       int16u
+  0x011a   XResolution               IFD0       rational64u
+  0x011b   YResolution               IFD0       rational64u
+  0x011c   PlanarConfiguration       IFD0       int16u!
+  0x011d   PageName                  IFD0       string
+  0x011e   XPosition                 IFD0       rational64u
+  0x011f   YPosition                 IFD0       rational64u
+  0x0120   FreeOffsets               -          N
+  0x0121   FreeByteCounts            -          N
+  0x0122   GrayResponseUnit          IFD0       int16u
+  0x0123   GrayResponseCurve         -          N
+  0x0124   T4Options                 -          N
+  0x0125   T6Options                 -          N
+  0x0128   ResolutionUnit            IFD0       int16u
+  0x0129   PageNumber                IFD0       int16u[2]
+  0x012c   ColorResponseUnit         -          N
+  0x012d   TransferFunction          -          N
+  0x0131   Software                  IFD0       string
+  0x0132   ModifyDate                IFD0       string
+  0x013b   Artist                    IFD0       string
+  0x013c   HostComputer              IFD0       string
+  0x013d   Predictor                 IFD0       int16u!
+  0x013e   WhitePoint                IFD0       rational64u[2]
+  0x013f   PrimaryChromaticities     IFD0       rational64u[6]
+  0x0140   ColorMap                  -          N
+  0x0141   HalftoneHints             IFD0       int16u[2]
+  0x0142   TileWidth                 IFD0       int32u!
+  0x0143   TileLength                IFD0       int32u!
+  0x0144   TileOffsets               -          N
+  0x0145   TileByteCounts            -          N
+  0x0146   BadFaxLines               -          N
+  0x0147   CleanFaxData              -          N
+  0x0148   ConsecutiveBadFaxLines    -          N
+  0x014a   SubIFD                    -          EXIF
+  0x014c   InkSet                    IFD0       int16u
+  0x014d   InkNames                  -          N
+  0x014e   NumberofInks              -          N
+  0x0150   DotRange                  IFD0       string
+  0x0151   TargetPrinter             -          N
+  0x0152   ExtraSamples              -          N
+  0x0153   SampleFormat              -          N
+  0x0154   SMinSampleValue           -          N
+  0x0155   SMaxSampleValue           -          N
+  0x0156   TransferRange             -          N
+  0x0157   ClipPath                  -          N
+  0x0158   XClipPathUnits            -          N
+  0x0159   YClipPathUnits            -          N
+  0x015a   Indexed                   -          N
+  0x015b   JPEGTables                -          N
+  0x015f   OPIProxy                  -          N
+  0x0190   GlobalParametersIFD       -          EXIF
+  0x0191   ProfileType               -          N
+  0x0192   FaxProfile                -          N
+  0x0193   CodingMethods             -          N
+  0x0194   VersionYear               -          N
+  0x0195   ModeNumber                -          N
+  0x01b1   Decode                    -          N
+  0x01b2   DefaultImageColor         -          N
+  0x0200   JPEGProc                  -          N
+  0x0201   ThumbnailOffset           IFD1       int32u*
+           PreviewImageStart         MakerNotes int32u*
+           JpgFromRawStart           SubIFD     int32u*
+           JpgFromRawStart           IFD2       int32u*
+           OtherImageStart           -          N
+  0x0202   ThumbnailLength           IFD1       int32u*
+           PreviewImageLength        MakerNotes int32u*
+           JpgFromRawLength          SubIFD     int32u*
+           JpgFromRawLength          IFD2       int32u*
+           OtherImageLength          -          N
+  0x0203   JPEGRestartInterval       -          N
+  0x0205   JPEGLosslessPredictors    -          N
+  0x0206   JPEGPointTransforms       -          N
+  0x0207   JPEGQTables               -          N
+  0x0208   JPEGDCTables              -          N
+  0x0209   JPEGACTables              -          N
+  0x0211   YCbCrCoefficients         IFD0       rational64u[3]!
+  0x0212   YCbCrSubSampling          IFD0       int16u[2]!
+  0x0213   YCbCrPositioning          IFD0       int16u!
+  0x0214   ReferenceBlackWhite       IFD0       rational64u[6]
+  0x022f   StripRowCounts            -          N
+  0x02bc   ApplicationNotes          -          XMP
+  0x1000   RelatedImageFileFormat    InteropIFD string!
+  0x1001   RelatedImageWidth         InteropIFD int16u!
+  0x1002   RelatedImageLength        InteropIFD int16u!
+  0x4746   Rating                    IFD0       int16u/
+  0x4749   RatingPercent             IFD0       int16u/
+  0x800d   ImageID                   -          N
+  0x80a4   WangAnnotation            -          N
+  0x80e3   Matteing                  -          N
+  0x80e4   DataType                  -          N
+  0x80e5   ImageDepth                -          N
+  0x80e6   TileDepth                 -          N
+  0x827d   Model2                    -          N
+  0x828d   CFARepeatPatternDim       -          N
+  0x828e   CFAPattern2               -          N
+  0x828f   BatteryLevel              -          N
+  0x8298   Copyright                 IFD0       string
+  0x829a   ExposureTime              ExifIFD    rational64u
+  0x829d   FNumber                   ExifIFD    rational64u
+  0x82a5   MDFileTag                 -          N
+  0x82a6   MDScalePixel              -          N
+  0x82a7   MDColorTable              -          N
+  0x82a8   MDLabName                 -          N
+  0x82a9   MDSampleInfo              -          N
+  0x82aa   MDPrepDate                -          N
+  0x82ab   MDPrepTime                -          N
+  0x82ac   MDFileUnits               -          N
+  0x830e   PixelScale                -          N
+  0x83bb   IPTC-NAA                  IFD0       IPTC
+  0x847e   IntergraphPacketData      -          N
+  0x847f   IntergraphFlagRegisters   -          N
+  0x8480   IntergraphMatrix          -          N
+  0x8482   ModelTiePoint             -          N
+  0x84e0   Site                      -          N
+  0x84e1   ColorSequence             -          N
+  0x84e2   IT8Header                 -          N
+  0x84e3   RasterPadding             -          N
+  0x84e4   BitsPerRunLength          -          N
+  0x84e5   BitsPerExtendedRunLength  -          N
+  0x84e6   ColorTable                -          N
+  0x84e7   ImageColorIndicator       -          N
+  0x84e8   BackgroundColorIndicator  -          N
+  0x84e9   ImageColorValue           -          N
+  0x84ea   BackgroundColorValue      -          N
+  0x84eb   PixelIntensityRange       -          N
+  0x84ec   TransparencyIndicator     -          N
+  0x84ed   ColorCharacterization     -          N
+  0x84ee   HCUsage                   -          N
+  0x8546   SEMInfo                   IFD0       string
+  0x8568   AFCP_IPTC                 -          IPTC
+  0x85d8   ModelTransform            -          N
+  0x8606   LeafData                  -          Leaf
+  0x8649   PhotoshopSettings         -          Photoshop
+  0x8769   ExifOffset                -          EXIF
+  0x8773   ICC_Profile               -          ICC_Profile
+  0x87ac   ImageLayer                -          N
+  0x87af   GeoTiffDirectory          -          N
+  0x87b0   GeoTiffDoubleParams       -          N
+  0x87b1   GeoTiffAsciiParams        -          N
+  0x8822   ExposureProgram           ExifIFD    int16u
+  0x8824   SpectralSensitivity       ExifIFD    string
+  0x8825   GPSInfo                   -          GPS
+  0x8827   ISO                       ExifIFD    int16u
+  0x8828   Opto-ElectricConvFactor   -          N
+  0x8829   Interlace                 -          N
+  0x882a   TimeZoneOffset            ExifIFD    int16s[n]
+  0x882b   SelfTimerMode             ExifIFD    int16u
+  0x885c   FaxRecvParams             -          N
+  0x885d   FaxSubAddress             -          N
+  0x885e   FaxRecvTime               -          N
+  0x888a   LeafSubIFD                -          Leaf SubIFD
+  0x9000   ExifVersion               ExifIFD    undef
+  0x9003   DateTimeOriginal          ExifIFD    string
+  0x9004   CreateDate                ExifIFD    string
+  0x9101   ComponentsConfiguration   ExifIFD    undef
+  0x9102   CompressedBitsPerPixel    ExifIFD    rational64u
+  0x9201   ShutterSpeedValue         ExifIFD    rational64s
+  0x9202   ApertureValue             ExifIFD    rational64u
+  0x9203   BrightnessValue           ExifIFD    rational64s
+  0x9204   ExposureCompensation      ExifIFD    rational64s
+  0x9205   MaxApertureValue          ExifIFD    rational64u
+  0x9206   SubjectDistance           ExifIFD    rational64u
+  0x9207   MeteringMode              ExifIFD    int16u
+  0x9208   LightSource               ExifIFD    int16u
+  0x9209   Flash                     ExifIFD    int16u
+  0x920a   FocalLength               ExifIFD    rational64u
+  0x920b   FlashEnergy               -          N
+  0x920c   SpatialFrequencyResponse  -          N
+  0x920d   Noise                     -          N
+  0x920e   FocalPlaneXResolution     -          N
+  0x920f   FocalPlaneYResolution     -          N
+  0x9210   FocalPlaneResolutionUnit  -          N
+  0x9211   ImageNumber               ExifIFD    int32u
+  0x9212   SecurityClassification    ExifIFD    string
+  0x9213   ImageHistory              ExifIFD    string
+  0x9214   SubjectLocation           ExifIFD    int16u[4]
+  0x9215   ExposureIndex             -          N
+  0x9216   TIFF-EPStandardID         -          N
+  0x9217   SensingMethod             -          N
+  0x923f   StoNits                   -          N
+  0x927c   MakerNoteCanon            ExifIFD    Canon
+           MakerNoteCasio            ExifIFD    Casio
+           MakerNoteCasio2           ExifIFD    Casio Type2
+           MakerNoteFujiFilm         ExifIFD    FujiFilm
+           MakerNoteHP               ExifIFD    HP
+           MakerNoteHP2              ExifIFD    HP Type2
+           MakerNoteHP4              ExifIFD    HP Type4
+           MakerNoteHP6              ExifIFD    HP Type6
+           MakerNoteJVC              ExifIFD    JVC
+           MakerNoteJVCText          ExifIFD    JVC Text
+           MakerNoteKodak1a          ExifIFD    Kodak
+           MakerNoteKodak1b          ExifIFD    Kodak
+           MakerNoteKodak2           ExifIFD    Kodak Type2
+           MakerNoteKodak3           ExifIFD    Kodak Type3
+           MakerNoteKodak4           ExifIFD    Kodak Type4
+           MakerNoteKodak5           ExifIFD    Kodak Type5
+           MakerNoteKodak6a          ExifIFD    Kodak Type6
+           MakerNoteKodak6b          ExifIFD    Kodak Type6
+           MakerNoteKodak7           ExifIFD    Kodak Type7
+           MakerNoteKodakIFD         ExifIFD    Kodak IFD
+           MakerNoteKodakUnknown     ExifIFD    Kodak Unknown
+           MakerNoteKyocera          ExifIFD    Unknown
+           MakerNoteMinolta          ExifIFD    Minolta
+           MakerNoteMinolta2         ExifIFD    Olympus
+           MakerNoteMinolta3         ExifIFD    undef
+           MakerNoteNikon            ExifIFD    Nikon
+           MakerNoteNikon2           ExifIFD    Nikon Type2
+           MakerNoteNikon3           ExifIFD    Nikon
+           MakerNoteOlympus          ExifIFD    Olympus
+           MakerNoteOlympus2         ExifIFD    Olympus
+           MakerNoteLeica            ExifIFD    Panasonic
+           MakerNotePanasonic        ExifIFD    Panasonic
+           MakerNotePanasonic2       ExifIFD    Panasonic Type2
+           MakerNotePentax           ExifIFD    Pentax
+           MakerNotePentax2          ExifIFD    Pentax Type2
+           MakerNotePentax3          ExifIFD    Casio Type2
+           MakerNotePentax4          ExifIFD    Pentax Type4
+           MakerNoteRicoh            ExifIFD    Ricoh
+           MakerNoteRicohText        ExifIFD    Ricoh Text
+           PreviewImage              ExifIFD    undef
+           MakerNoteSanyo            ExifIFD    Sanyo
+           MakerNoteSanyoC4          ExifIFD    Sanyo
+           MakerNoteSanyoPatch       ExifIFD    Sanyo
+           MakerNoteSigma            ExifIFD    Sigma
+           MakerNoteSony             ExifIFD    Sony
+           MakerNoteSonySRF          ExifIFD    Sony SRF
+           MakerNoteSonySR2          ExifIFD    Sony
+           MakerNoteUnknown          ExifIFD    Unknown
+  0x9286   UserComment               ExifIFD    undef
+  0x9290   SubSecTime                ExifIFD    string
+  0x9291   SubSecTimeOriginal        ExifIFD    string
+  0x9292   SubSecTimeDigitized       ExifIFD    string
+  0x935c   ImageSourceData           IFD0       undef
+  0x9c9b   XPTitle                   IFD0       int8u
+  0x9c9c   XPComment                 IFD0       int8u
+  0x9c9d   XPAuthor                  IFD0       int8u
+  0x9c9e   XPKeywords                IFD0       int8u
+  0x9c9f   XPSubject                 IFD0       int8u
+  0xa000   FlashpixVersion           ExifIFD    undef
+  0xa001   ColorSpace                ExifIFD    int16u
+  0xa002   ExifImageWidth            ExifIFD    int16u
+  0xa003   ExifImageLength           ExifIFD    int16u
+  0xa004   RelatedSoundFile          ExifIFD    string
+  0xa005   InteropOffset             -          EXIF
+  0xa20b   FlashEnergy               ExifIFD    rational64u[n]
+  0xa20c   SpatialFrequencyResponse  -          N
+  0xa20d   Noise                     -          N
+  0xa20e   FocalPlaneXResolution     ExifIFD    rational64u
+  0xa20f   FocalPlaneYResolution     ExifIFD    rational64u
+  0xa210   FocalPlaneResolutionUnit  ExifIFD    int16u
+  0xa211   ImageNumber               -          N
+  0xa212   SecurityClassification    -          N
+  0xa213   ImageHistory              -          N
+  0xa214   SubjectLocation           ExifIFD    int16u[2]
+  0xa215   ExposureIndex             ExifIFD    rational64u
+  0xa216   TIFF-EPStandardID         -          N
+  0xa217   SensingMethod             ExifIFD    int16u
+  0xa300   FileSource                ExifIFD    undef
+  0xa301   SceneType                 ExifIFD    undef
+  0xa302   CFAPattern                ExifIFD    undef
+  0xa401   CustomRendered            ExifIFD    int16u
+  0xa402   ExposureMode              ExifIFD    int16u
+  0xa403   WhiteBalance              ExifIFD    int16u
+  0xa404   DigitalZoomRatio          ExifIFD    rational64u
+  0xa405   FocalLengthIn35mmFormat   ExifIFD    int16u
+  0xa406   SceneCaptureType          ExifIFD    int16u
+  0xa407   GainControl               ExifIFD    int16u
+  0xa408   Contrast                  ExifIFD    int16u
+  0xa409   Saturation                ExifIFD    int16u
+  0xa40a   Sharpness                 ExifIFD    int16u
+  0xa40b   DeviceSettingDescription  -          N
+  0xa40c   SubjectDistanceRange      ExifIFD    int16u
+  0xa420   ImageUniqueID             ExifIFD    string
+  0xa480   GDALMetadata              -          N
+  0xa481   GDALNoData                -          N
+  0xa500   Gamma                     ExifIFD    rational64u
+  0xbc01   PixelFormat               -          N
+  0xbc02   Transfomation             -          N
+  0xbc03   Uncompressed              -          N
+  0xbc04   ImageType                 -          N
+  0xbc80   ImageWidth                -          N
+  0xbc81   ImageHeight               -          N
+  0xbc82   WidthResolution           -          N
+  0xbc83   HeightResolution          -          N
+  0xbcc0   ImageOffset               -          N
+  0xbcc1   ImageByteCount            -          N
+  0xbcc2   AlphaOffset               -          N
+  0xbcc3   AlphaByteCount            -          N
+  0xbcc4   ImageDataDiscard          -          N
+  0xbcc5   AlphaDataDiscard          -          N
+  0xc427   OceScanjobDesc            -          N
+  0xc428   OceApplicationSelector    -          N
+  0xc429   OceIDNumber               -          N
+  0xc42a   OceImageLogic             -          N
+  0xc44f   Annotations               -          N
+  0xc4a5   PrintIM                   IFD0       PrintIM
+  0xc612   DNGVersion                IFD0       int8u[4]
+  0xc613   DNGBackwardVersion        IFD0       int8u[4]
+  0xc614   UniqueCameraModel         IFD0       string
+  0xc615   LocalizedCameraModel      IFD0       string
+  0xc616   CFAPlaneColor             -          N
+  0xc617   CFALayout                 -          N
+  0xc618   LinearizationTable        -          N
+  0xc619   BlackLevelRepeatDim       -          N
+  0xc61a   BlackLevel                -          N
+  0xc61b   BlackLevelDeltaH          -          N
+  0xc61c   BlackLevelDeltaV          -          N
+  0xc61d   WhiteLevel                -          N
+  0xc61e   DefaultScale              SubIFD     rational64u[2]
+  0xc61f   DefaultCropOrigin         SubIFD     int32u[2]
+  0xc620   DefaultCropSize           SubIFD     int32u[2]
+  0xc621   ColorMatrix1              -          N
+  0xc622   ColorMatrix2              -          N
+  0xc623   CameraCalibration1        -          N
+  0xc624   CameraCalibration2        -          N
+  0xc625   ReductionMatrix1          -          N
+  0xc626   ReductionMatrix2          -          N
+  0xc627   AnalogBalance             -          N
+  0xc628   AsShotNeutral             -          N
+  0xc629   AsShotWhiteXY             IFD0       rational64u[2]
+  0xc62a   BaselineExposure          IFD0       rational64s
+  0xc62b   BaselineNoise             IFD0       rational64u
+  0xc62c   BaselineSharpness         IFD0       rational64u
+  0xc62d   BayerGreenSplit           SubIFD     int32u
+  0xc62e   LinearResponseLimit       IFD0       rational64u
+  0xc62f   CameraSerialNumber        IFD0       string
+  0xc630   DNGLensInfo               IFD0       rational64u[4]
+  0xc631   ChromaBlurRadius          SubIFD     rational64u
+  0xc632   AntiAliasStrength         SubIFD     rational64u
+  0xc633   ShadowScale               IFD0       rational64u
+  0xc634   SR2Private                -          Sony SR2Private
+           DNGAdobeData              -          DNG AdobeData
+           DNGPentaxData             -          Pentax
+           DNGPrivateData            -          N
+  0xc635   MakerNoteSafety           IFD0       int16u
+  0xc65a   CalibrationIlluminant1    IFD0       int16u
+  0xc65b   CalibrationIlluminant2    IFD0       int16u
+  0xc65c   BestQualityScale          SubIFD     rational64u
+  0xc65d   RawDataUniqueID           IFD0       int8u[16]
+  0xc660   AliasLayerMetadata        -          N
+  0xc68b   OriginalRawFileName       IFD0       string
+  0xc68c   OriginalRawFileData       IFD0       DNG OriginalRaw
+  0xc68d   ActiveArea                SubIFD     int32u[4]
+  0xc68e   MaskedAreas               SubIFD     int32u[4]
+  0xc68f   AsShotICCProfile          IFD0       ICC_Profile
+  0xc690   AsShotPreProfileMatrix    IFD0       rational64s[n]!
+  0xc691   CurrentICCProfile         IFD0       ICC_Profile
+  0xc692   CurrentPreProfileMatrix   IFD0       rational64s[n]!
+  0xea1d   OffsetSchema              ExifIFD    int32s
+  0xfde8   OwnerName                 ExifIFD    string/
+  0xfde9   SerialNumber              ExifIFD    string/
+  0xfdea   Lens                      ExifIFD    string/
+  0xfe4c   RawFile                   ExifIFD    string/
+  0xfe4d   Converter                 ExifIFD    string/
+  0xfe4e   WhiteBalance              ExifIFD    string/
+  0xfe51   Exposure                  ExifIFD    string/
+  0xfe52   Shadows                   ExifIFD    string/
+  0xfe53   Brightness                ExifIFD    string/
+  0xfe54   Contrast                  ExifIFD    string/
+  0xfe55   Saturation                ExifIFD    string/
+  0xfe56   Sharpness                 ExifIFD    string/
+  0xfe57   Smoothness                ExifIFD    string/
+  0xfe58   MoireFilter               ExifIFD    string/
+
+=head2 IPTC Tags
+
+IPTC stands for "International Press Telecommunications Council".  This is
+an older meta information format that is slowly being phased out in favor of
+XMP.  IPTC information may be embedded in JPG, TIFF, PNG, MIFF, PS, PDF, PSD
+and DNG images.
+
+The IPTC specification dictates a length for ASCII (C<string> or C<digits>)
+values.  These lengths are given in square brackets after the B<Writable>
+format name.  For tags where a range of lengths is allowed, the minimum and
+maximum lengths are separated by a comma within the brackets.  IPTC strings
+are not null terminated.
+
+IPTC information is separated into different records, each of which has its
+own set of tags.
+
+  Record   Tag Name                             Writable
+  ------   --------                             --------
+      1    IPTCEnvelope                         IPTC EnvelopeRecord
+      2    IPTCApplication                      IPTC ApplicationRecord
+      3    IPTCNewsPhoto                        IPTC NewsPhoto
+      7    IPTCPreObjectData                    IPTC PreObjectData
+      8    IPTCObjectData                       IPTC ObjectData
+      9    IPTCPostObjectData                   IPTC PostObjectData
+
+=head3 IPTC EnvelopeRecord Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+      0    EnvelopeRecordVersion                int16u
+      5    Destination                          string[0,1024]+
+     20    FileFormat                           int16u
+     22    FileVersion                          int16u
+     30    ServiceIdentifier                    string[0,10]
+     40    EnvelopeNumber                       digits[8]
+     50    ProductID                            string[0,32]+
+     60    EnvelopePriority                     digits[1]
+     70    DateSent                             digits[8]
+     80    TimeSent                             string[11]
+     90    CodedCharacterSet                    string[0,32]
+    100    UniqueObjectName                     string[14,80]
+    120    ARMIdentifier                        int16u
+    122    ARMVersion                           int16u
+
+=head3 IPTC ApplicationRecord Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+      0    ApplicationRecordVersion             int16u
+      3    ObjectTypeReference                  string[3,67]
+      4    ObjectAttributeReference             string[4,68]+
+      5    ObjectName                           string[0,64]
+      7    EditStatus                           string[0,64]
+      8    EditorialUpdate                      digits[2]
+     10    Urgency                              digits[1]
+     12    SubjectReference                     string[13,236]+
+     15    Category                             string[0,3]
+     20    SupplementalCategories               string[0,32]+
+     22    FixtureIdentifier                    string[0,32]
+     25    Keywords                             string[0,64]+
+     26    ContentLocationCode                  string[3]+
+     27    ContentLocationName                  string[0,64]+
+     30    ReleaseDate                          digits[8]
+     35    ReleaseTime                          string[11]
+     37    ExpirationDate                       digits[8]
+     38    ExpirationTime                       string[11]
+     40    SpecialInstructions                  string[0,256]
+     42    ActionAdvised                        digits[2]
+     45    ReferenceService                     string[0,10]+
+     47    ReferenceDate                        digits[8]+
+     50    ReferenceNumber                      digits[8]+
+     55    DateCreated                          digits[8]
+     60    TimeCreated                          string[11]
+     62    DigitalCreationDate                  digits[8]
+     63    DigitalCreationTime                  string[11]
+     65    OriginatingProgram                   string[0,32]
+     70    ProgramVersion                       string[0,10]
+     75    ObjectCycle                          string[1]
+     80    By-line                              string[0,32]+
+     85    By-lineTitle                         string[0,32]+
+     90    City                                 string[0,32]
+     92    Sub-location                         string[0,32]
+     95    Province-State                       string[0,32]
+    100    Country-PrimaryLocationCode          string[3]
+    101    Country-PrimaryLocationName          string[0,64]
+    103    OriginalTransmissionReference        string[0,32]
+    105    Headline                             string[0,256]
+    110    Credit                               string[0,32]
+    115    Source                               string[0,32]
+    116    CopyrightNotice                      string[0,128]
+    118    Contact                              string[0,128]+
+    120    Caption-Abstract                     string[0,2000]
+    121    LocalCaption                         string[0,256]
+    122    Writer-Editor                        string[0,32]+
+    125    RasterizedCaption                    string[7360]
+    130    ImageType                            string[2]
+    131    ImageOrientation                     string[1]
+    135    LanguageIdentifier                   string[2,3]
+    150    AudioType                            string[2]
+    151    AudioSamplingRate                    digits[6]
+    152    AudioSamplingResolution              digits[2]
+    153    AudioDuration                        digits[6]
+    154    AudioOutcue                          string[0,64]
+    184    JobID                                string[0,64]
+    185    MasterDocumentID                     string[0,256]
+    186    ShortDocumentID                      string[0,64]
+    187    UniqueDocumentID                     string[0,128]
+    188    OwnerID                              string[0,128]
+    200    ObjectPreviewFileFormat              int16u
+    201    ObjectPreviewFileVersion             int16u
+    202    ObjectPreviewData                    string[0,256000]
+    221    Prefs                                string[0,64]
+    225    ClassifyState                        string[0,64]
+    228    SimilarityIndex                      string[0,32]
+    230    DocumentNotes                        string[0,1024]
+    231    DocumentHistory                      string[0,256]
+    232    ExifCameraInfo                       string[0,4096]
+
+=head3 IPTC NewsPhoto Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+      0    NewsPhotoVersion                     int16u
+     10    IPTCPictureNumber                    string[16]
+     20    IPTCImageWidth                       int16u
+     30    IPTCImageHeight                      int16u
+     40    IPTCPixelWidth                       int16u
+     50    IPTCPixelHeight                      int16u
+     55    SupplementalType                     int8u
+     60    ColorRepresentation                  int16u
+     64    InterchangeColorSpace                int8u
+     65    ColorSequence                        int8u
+     66    ICC_Profile                          N
+     70    ColorCalibrationMatrix               N
+     80    LookupTable                          N
+     84    NumIndexEntries                      int16u
+     85    ColorPalette                         N
+     86    IPTCBitsPerSample                    int8u
+     90    SampleStructure                      int8u
+    100    ScanningDirection                    int8u
+    102    IPTCImageRotation                    int8u
+    110    DataCompressionMethod                int32u
+    120    QuantizationMethod                   int8u
+    125    EndPoints                            N
+    130    ExcursionTolerance                   int8u
+    135    BitsPerComponent                     int8u
+    140    MaximumDensityRange                  int16u
+    145    GammaCompensatedValue                int16u
+
+=head3 IPTC PreObjectData Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+     10    SizeMode                             N
+     20    MaxSubfileSize                       N
+     90    ObjectSizeAnnounced                  N
+     95    MaximumObjectSize                    N
+
+=head3 IPTC ObjectData Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+     10    SubFile                              N+
+
+=head3 IPTC PostObjectData Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+     10    ConfirmedObjectSize                  N
+
+=head2 XMP Tags
+
+XMP stands for "Extensible Metadata Platform", an XML/RDF-based metadata
+format which is being pushed by Adobe.  Information in this format can be
+embedded in many different image file types including JPG, JP2, TIFF, PNG,
+MIFF, PS, PDF, PSD and DNG, as well as audio file formats supporting ID3v2
+information.
+
+The XMP B<Tag ID>'s aren't listed because in most cases they are identical
+to the B<Tag Name>.
+
+All XMP information is stored as character strings.  The B<Writable> column
+specifies the information format:  C<integer> is a string of digits
+(possibly beginning with a '+' or '-'), C<real> is a floating point number,
+C<rational> is two C<integer> strings separated by a '/' character, C<date>
+is a date/time string in the format "YYYY:MM:DD HH:MM:SS[+/-HH:MM]",
+C<boolean> is either "True" or "False", and C<lang-alt> is a list of string
+alternatives in different languages.
+
+Individual languages for C<lang-alt> tags are accessed by suffixing the tag
+name with a '-', followed by an RFC 3066 language code (ie. "XMP:Title-fr",
+or "Rights-en-US").  A C<lang-alt> tag with no language code accesses the
+"x-default" language, but causes other languages to be deleted when writing.
+The "x-default" language code may be specified when writing a new value to
+write only the default language, but note that all languages are still
+deleted if "x-default" tag is deleted.  When reading, "x-default" is not
+specified.
+
+The XMP tags are organized according to schema B<Namespace> in the following
+tables.  Note that a few of the longer namespace prefixes given below have
+been shortened for convenience (since the family 1 group names are derived
+from these by adding a leading "XMP-").  In cases where a tag name exists in
+more than one namespace, less common namespaces are avoided when writing.
+However, any namespace may be written by specifying a family 1 group name
+for the tag, ie) XMP-exif:Contrast or XMP-crs:Contrast.
+
+ExifTool will extract XMP information even if it is not listed in these
+tables.  For example, the C<pdfx> namespace doesn't have a predefined set of
+tag names because it is used to store application-defined PDF information,
+but this information is extracted by ExifTool anyway.
+
+  Namespace                                     Writable
+  ---------                                     --------
+  aux                                           XMP aux
+  cc                                            XMP cc
+  crs                                           XMP crs
+  dc                                            XMP dc
+  dex                                           XMP dex
+  DICOM                                         XMP DICOM
+  exif                                          XMP exif
+  iptcCore                                      XMP iptcCore
+  lr                                            XMP Lightroom
+  mediapro                                      XMP MediaPro
+  microsoft                                     XMP Microsoft
+  pdf                                           XMP pdf
+  photomech                                     PhotoMechanic XMP
+  photoshop                                     XMP photoshop
+  PixelLive                                     XMP PixelLive
+  tiff                                          XMP tiff
+  xmp                                           XMP xmp
+  xmpBJ                                         XMP xmpBJ
+  xmpDM                                         XMP xmpDM
+  xmpMM                                         XMP xmpMM
+  xmpPLUS                                       XMP xmpPLUS
+  xmpRights                                     XMP xmpRights
+  xmpTPg                                        XMP xmpTPg
+
+=head3 XMP aux Tags
+
+Photoshop Auxiliary schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Firmware                                      string
+  FlashCompensation                             rational
+  ImageNumber                                   string
+  Lens                                          string
+  LensInfo                                      string
+  OwnerName                                     string
+  SerialNumber                                  string
+
+=head3 XMP cc Tags
+
+Creative Commons schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  License                                       string
+
+=head3 XMP crs Tags
+
+Photoshop Camera Raw Schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AlreadyApplied                                boolean
+  AutoBrightness                                boolean
+  AutoContrast                                  boolean
+  AutoExposure                                  boolean
+  AutoShadows                                   boolean
+  BlueHue                                       integer
+  BlueSaturation                                integer
+  Brightness                                    integer
+  CameraProfile                                 string
+  CameraProfileDigest                           string
+  ChromaticAberrationB                          integer
+  ChromaticAberrationR                          integer
+  Clarity                                       integer
+  ColorNoiseReduction                           integer
+  Contrast                                      integer/
+  ConvertToGrayscale                            boolean
+  CropAngle                                     real
+  CropBottom                                    real
+  CropHeight                                    real
+  CropLeft                                      real
+  CropRight                                     real
+  CropTop                                       real
+  CropUnits                                     integer
+  CropWidth                                     real
+  Defringe                                      integer
+  Exposure                                      real
+  FillLight                                     integer
+  GreenHue                                      integer
+  GreenSaturation                               integer
+  HasCrop                                       boolean
+  HasSettings                                   boolean
+  HighlightRecovery                             integer
+  HueAdjustmentAqua                             integer
+  HueAdjustmentBlue                             integer
+  HueAdjustmentGreen                            integer
+  HueAdjustmentMagenta                          integer
+  HueAdjustmentOrange                           integer
+  HueAdjustmentPurple                           integer
+  HueAdjustmentRed                              integer
+  HueAdjustmentYellow                           integer
+  IncrementalTemperature                        integer
+  IncrementalTint                               integer
+  LuminanceAdjustmentAqua                       integer
+  LuminanceAdjustmentBlue                       integer
+  LuminanceAdjustmentGreen                      integer
+  LuminanceAdjustmentMagenta                    integer
+  LuminanceAdjustmentOrange                     integer
+  LuminanceAdjustmentPurple                     integer
+  LuminanceAdjustmentRed                        integer
+  LuminanceAdjustmentYellow                     integer
+  LuminanceSmoothing                            integer
+  ParametricDarks                               integer
+  ParametricHighlights                          integer
+  ParametricHighlightSplit                      integer
+  ParametricLights                              integer
+  ParametricMidtoneSplit                        integer
+  ParametricShadows                             integer
+  ParametricShadowSplit                         integer
+  RawFileName                                   string
+  RedHue                                        integer
+  RedSaturation                                 integer
+  Saturation                                    integer/
+  SaturationAdjustmentAqua                      integer
+  SaturationAdjustmentBlue                      integer
+  SaturationAdjustmentGreen                     integer
+  SaturationAdjustmentMagenta                   integer
+  SaturationAdjustmentOrange                    integer
+  SaturationAdjustmentPurple                    integer
+  SaturationAdjustmentRed                       integer
+  SaturationAdjustmentYellow                    integer
+  Shadows                                       integer
+  ShadowTint                                    integer
+  SharpenDetail                                 integer
+  SharpenEdgeMasking                            integer
+  SharpenRadius                                 real
+  Sharpness                                     integer/
+  SplitToningBalance                            integer
+  SplitToningHighlightHue                       integer
+  SplitToningHighlightSaturation                integer
+  SplitToningShadowHue                          integer
+  SplitToningShadowSaturation                   integer
+  Temperature                                   integer
+  Tint                                          integer
+  ToneCurve                                     string+
+  ToneCurveName                                 string
+  Version                                       string
+  Vibrance                                      integer
+  VignetteAmount                                integer
+  VignetteMidpoint                              integer
+  WhiteBalance                                  string/
+
+=head3 XMP dc Tags
+
+Dublin Core schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Contributor                                   string+
+  Coverage                                      string
+  Creator                                       string+
+  Date                                          date+
+  Description                                   lang-alt
+  Format                                        string
+  Identifier                                    string
+  Language                                      string+
+  Publisher                                     string+
+  Relation                                      string+
+  Rights                                        lang-alt
+  Source                                        string
+  Subject                                       string+
+  Title                                         lang-alt
+  Type                                          string+
+
+=head3 XMP dex Tags
+
+Description Explorer schema tags.  These tags are not very common.  The
+Source and Rating tags are avoided when writing due to name conflicts with
+other XMP tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CRC32                                         integer
+  FFID                                          string
+  LicenseType                                   string
+  OS                                            integer
+  Rating                                        string/
+  Revision                                      string
+  ShortDescription                              lang-alt
+  Source                                        string/
+
+=head3 XMP DICOM Tags
+
+DICOM schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  EquipmentInstitution                          string
+  EquipmentManufacturer                         string
+  PatientsBirthDate                             date
+  PatientID                                     string
+  PatientsName                                  string
+  PatientsSex                                   string
+  SeriesDateTime                                date
+  SeriesDescription                             string
+  SeriesModality                                string
+  SeriesNumber                                  string
+  StudyDateTime                                 date
+  StudyDescription                              string
+  StudyID                                       string
+  StudyPhysician                                string
+
+=head3 XMP exif Tags
+
+EXIF schema for EXIF tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  ApertureValue                                 rational
+  BrightnessValue                               rational
+  CFAPatternColumns                             integer
+  CFAPatternRows                                integer
+  CFAPatternValues                              integer+
+  ColorSpace                                    integer
+  ComponentsConfiguration                       integer+
+  CompressedBitsPerPixel                        rational
+  Contrast                                      integer
+  CustomRendered                                integer
+  DateTimeDigitized                             date
+  DateTimeOriginal                              date
+  DeviceSettingDescriptionColumns               integer
+  DeviceSettingDescriptionRows                  integer
+  DeviceSettingDescriptionSettings              string+
+  DigitalZoomRatio                              rational
+  ExifVersion                                   string
+  ExposureCompensation                          rational
+  ExposureIndex                                 rational
+  ExposureMode                                  integer
+  ExposureProgram                               integer
+  ExposureTime                                  rational
+  FileSource                                    integer
+  FlashEnergy                                   rational
+  FlashFired                                    boolean
+  FlashFunction                                 boolean
+  FlashMode                                     integer
+  FlashpixVersion                               string
+  FlashRedEyeMode                               boolean
+  FlashReturn                                   integer
+  FNumber                                       rational
+  FocalLength                                   rational
+  FocalLengthIn35mmFormat                       integer
+  FocalPlaneResolutionUnit                      integer
+  FocalPlaneXResolution                         rational
+  FocalPlaneYResolution                         rational
+  GainControl                                   integer
+  GPSAltitude                                   rational
+  GPSAltitudeRef                                integer
+  GPSAreaInformation                            string
+  GPSDestBearing                                rational
+  GPSDestBearingRef                             string
+  GPSDestDistance                               rational
+  GPSDestDistanceRef                            string
+  GPSDestLatitude                               string
+  GPSDestLongitude                              string
+  GPSDifferential                               integer
+  GPSDOP                                        rational
+  GPSImgDirection                               rational
+  GPSImgDirectionRef                            string
+  GPSLatitude                                   string
+  GPSLongitude                                  string
+  GPSMapDatum                                   string
+  GPSMeasureMode                                integer
+  GPSProcessingMethod                           string
+  GPSSatellites                                 string
+  GPSSpeed                                      rational
+  GPSSpeedRef                                   string
+  GPSStatus                                     string
+  GPSTimeStamp                                  date
+  GPSTrack                                      rational
+  GPSTrackRef                                   string
+  GPSVersionID                                  string
+  ImageUniqueID                                 string
+  ISO                                           integer+
+  LightSource                                   string
+  MakerNote                                     string
+  MaxApertureValue                              rational
+  MeteringMode                                  integer
+  NativeDigest                                  string
+  OECFColumns                                   integer
+  OECFNames                                     string+
+  OECFRows                                      integer
+  OECFValues                                    rational+
+  ExifImageWidth                                integer
+  ExifImageLength                               integer
+  RelatedSoundFile                              string
+  Saturation                                    integer
+  SceneCaptureType                              integer
+  SceneType                                     integer
+  SensingMethod                                 integer
+  Sharpness                                     integer
+  ShutterSpeedValue                             rational
+  SpatialFrequencyResponseColumns               integer
+  SpatialFrequencyResponseNames                 string+
+  SpatialFrequencyResponseRows                  integer
+  SpatialFrequencyResponseValues                rational+
+  SpectralSensitivity                           string
+  SubjectArea                                   integer+
+  SubjectDistance                               rational
+  SubjectDistanceRange                          integer
+  SubjectLocation                               integer+
+  UserComment                                   lang-alt
+  WhiteBalance                                  integer
+
+=head3 XMP iptcCore Tags
+
+IPTC Core schema tags.  The actual IPTC Core namespace schema prefix is
+"Iptc4xmpCore", which is the prefix recorded in the file, but ExifTool
+shortens this for the "XMP-iptcCore" family 1 group name.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CountryCode                                   string
+  CreatorContactInfoCiAdrCity                   string
+  CreatorContactInfoCiAdrCtry                   string
+  CreatorContactInfoCiAdrExtadr                 string
+  CreatorContactInfoCiAdrPcode                  string
+  CreatorContactInfoCiAdrRegion                 string
+  CreatorContactInfoCiEmailWork                 string
+  CreatorContactInfoCiTelWork                   string
+  CreatorContactInfoCiUrlWork                   string
+  IntellectualGenre                             string
+  Location                                      string
+  Scene                                         string+
+  SubjectCode                                   string+
+
+=head3 XMP Lightroom Tags
+
+Adobe Lightroom "lr" schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  HierarchicalSubject                           string+
+  PrivateRTKInfo                                string
+
+=head3 XMP MediaPro Tags
+
+IView MediaPro schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CatalogSets                                   string+
+  Event                                         string
+  Location                                      string/
+  People                                        string+
+  Status                                        string
+  UserFields                                    string+
+
+=head3 XMP Microsoft Tags
+
+Microsoft Photo schema tags.  This is likely not a complete list, but
+represents tags which have been observed in sample images.  The actual
+namespace prefix is "MicrosoftPhoto", but ExifTool shortens this to
+"XMP-microsoft" in the family 1 group name.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CameraSerialNumber                            string
+  DateAcquired                                  date
+  FlashManufacturer                             string
+  FlashModel                                    string
+  LastKeywordIPTC                               string+
+  LastKeywordXMP                                string+
+  LensManufacturer                              string
+  LensModel                                     string
+  RatingPercent                                 string
+
+=head3 XMP pdf Tags
+
+Adobe PDF schema tags.  The official XMP specification defines only
+Keywords, PDFVersion and Producer.  The other tags are included because they
+have been observed in PDF files, but Creator, Subject and Title are avoided
+when writing due to name conflicts with XMP-dc tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Author                                        string
+  CreationDate                                  date
+  Creator                                       string/
+  Keywords                                      string
+  ModDate                                       date
+  PDFVersion                                    string
+  Producer                                      string
+  Subject                                       string/
+  Title                                         string/
+
+=head3 XMP photoshop Tags
+
+Adobe Photoshop schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AuthorsPosition                               string
+  CaptionWriter                                 string
+  Category                                      string
+  City                                          string
+  ColorMode                                     string
+  Country                                       string
+  Credit                                        string
+  DateCreated                                   date
+  Headline                                      string
+  History                                       string
+  ICCProfileName                                string
+  Instructions                                  string
+  LegacyIPTCDigest                              string
+  SidecarForExtension                           string
+  Source                                        string/
+  State                                         string
+  SupplementalCategories                        string+
+  TransmissionReference                         string
+  Urgency                                       integer
+
+=head3 XMP PixelLive Tags
+
+PixelLive schema tags.  These tags are not writable becase they are very
+uncommon and I haven't been able to locate a reference which gives the
+namespace URI.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Author                                        N
+  Comments                                      N
+  Copyright                                     N
+  Date                                          N
+  Genre                                         N
+  Title                                         N
+
+=head3 XMP tiff Tags
+
+EXIF schema for TIFF tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Artist                                        string
+  BitsPerSample                                 integer+
+  Compression                                   integer
+  Copyright                                     lang-alt
+  DateTime                                      date
+  ImageDescription                              lang-alt
+  ImageHeight                                   integer
+  ImageWidth                                    integer
+  Make                                          string
+  Model                                         string
+  NativeDigest                                  string
+  Orientation                                   integer
+  PhotometricInterpretation                     integer
+  PlanarConfiguration                           integer
+  PrimaryChromaticities                         rational+
+  ReferenceBlackWhite                           rational+
+  ResolutionUnit                                integer
+  SamplesPerPixel                               integer
+  Software                                      string
+  TransferFunction                              integer+
+  WhitePoint                                    rational+
+  XResolution                                   rational
+  YCbCrCoefficients                             rational+
+  YCbCrPositioning                              integer
+  YCbCrSubSampling                              string
+  YResolution                                   rational
+
+=head3 XMP xmp Tags
+
+XMP Basic schema tags.  If the older "xap", "xapBJ", "xapMM" or "xapRights"
+namespace prefixes are found, they are translated to the newer "xmp",
+"xmpBJ", "xmpMM" and "xmpRights" prefixes for use in family 1 group names.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Advisory                                      string+
+  BaseURL                                       string
+  CreateDate                                    date
+  CreatorTool                                   string
+  Identifier                                    string/+
+  Label                                         string
+  MetadataDate                                  date
+  ModifyDate                                    date
+  Nickname                                      string
+  Rating                                        integer
+  ThumbnailsFormat                              string+
+  ThumbnailsHeight                              string+
+  ThumbnailsImage                               N+
+  ThumbnailsWidth                               string+
+
+=head3 XMP xmpBJ Tags
+
+XMP Basic Job Ticket schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  JobRefId                                      string+
+  JobRefName                                    string+
+  JobRefUrl                                     string+
+
+=head3 XMP xmpDM Tags
+
+XMP Dynamic Media schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AbsPeakAudioFilePath                          string
+  Album                                         string
+  AltTapeName                                   string
+  AltTimecodeTimeFormat                         string
+  AltTimecodeTimeValue                          string
+  Artist                                        string/
+  AudioChannelType                              string
+  AudioCompressor                               string
+  AudioModDate                                  date
+  AudioSampleRate                               integer
+  AudioSampleType                               string
+  BeatSpliceParamsRiseInDecibel                 real
+  BeatSpliceParamsRiseInTimeDuration            string
+  BeatSpliceParamsUseFileBeatsMarker            boolean
+  Composer                                      string
+  ContributedMediaDuration                      string+
+  ContributedMediaManaged                       boolean+
+  ContributedMediaPath                          string+
+  ContributedMediaStartTime                     string+
+  ContributedMediaTrack                         string+
+  ContributedMediaWebStatement                  string+
+  Copyright                                     string/
+  Duration                                      string
+  Engineer                                      string
+  FileDataRate                                  rational
+  Genre                                         string
+  Instrument                                    string
+  IntroTime                                     string
+  Key                                           string
+  LogComment                                    string
+  Loop                                          boolean
+  MarkersComment                                string+
+  MarkersDuration                               string+
+  MarkersLocation                               string+
+  MarkersName                                   string+
+  MarkersStartTime                              string+
+  MarkersTarget                                 string+
+  MarkersType                                   string+
+  MetadataModDate                               date
+  NumberOfBeats                                 real
+  OutCue                                        string
+  ProjectRefPath                                string
+  ProjectRefType                                string
+  PullDown                                      string
+  RelativePeakAudioFilePath                     string
+  RelativeTimestamp                             string
+  ReleaseDate                                   date
+  ResampleParamsQuality                         string
+  ScaleType                                     string
+  Scene                                         string/
+  ShotDate                                      date
+  ShotLocation                                  string
+  ShotName                                      string
+  SpeakerPlacement                              string
+  StartTimecodeTimeFormat                       string
+  StartTimecodeTimeValue                        string
+  StretchMode                                   string
+  TapeName                                      string
+  Tempo                                         real
+  TimeScaleParamsFrameOverlappingPercentage     real
+  TimeScaleParamsFrameSize                      real
+  TimeScaleParamsQuality                        string
+  TimeSignature                                 string
+  TrackNumber                                   integer
+  VideoAlphaMode                                string
+  VideoAlphaPremultipleColorA                   integer
+  VideoAlphaPremultipleColorB                   integer
+  VideoAlphaPremultipleColorBlack               real
+  VideoAlphaPremultipleColorBlue                integer
+  VideoAlphaPremultipleColorCyan                real
+  VideoAlphaPremultipleColorGreen               integer
+  VideoAlphaPremultipleColorL                   real
+  VideoAlphaPremultipleColorMagenta             real
+  VideoAlphaPremultipleColorMode                string
+  VideoAlphaPremultipleColorRed                 integer
+  VideoAlphaPremultipleColorSwatchName          string
+  VideoAlphaPremultipleColorType                string
+  VideoAlphaPremultipleColorYellow              real
+  VideoAlphaUnityIsTransparent                  boolean
+  VideoColorSpace                               string
+  VideoCompressor                               string
+  VideoFieldOrder                               string
+  VideoFrameRate                                string
+  VideoFrameSizeH                               real
+  VideoFrameSizeUnit                            string
+  VideoFrameSizeW                               real
+  VideoModDate                                  date
+  VideoPixelAspectRatio                         rational
+  VideoPixelDepth                               string
+
+=head3 XMP xmpMM Tags
+
+XMP Media Management schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  DerivedFromDocumentID                         string
+  DerivedFromInstanceID                         string
+  DerivedFromManager                            string
+  DerivedFromManagerVariant                     string
+  DerivedFromManageTo                           string
+  DerivedFromManageUI                           string
+  DerivedFromRenditionClass                     string
+  DerivedFromRenditionParams                    string
+  DerivedFromVersionID                          string
+  DocumentID                                    string
+  HistoryAction                                 string+
+  HistoryInstanceID                             string+
+  HistoryParameters                             string+
+  HistorySoftwareAgent                          string+
+  HistoryWhen                                   date+
+  InstanceID                                    string
+  LastURL                                       string
+  ManagedFromDocumentID                         string
+  ManagedFromInstanceID                         string
+  ManagedFromManager                            string
+  ManagedFromManagerVariant                     string
+  ManagedFromManageTo                           string
+  ManagedFromManageUI                           string
+  ManagedFromRenditionClass                     string
+  ManagedFromRenditionParams                    string
+  ManagedFromVersionID                          string
+  Manager                                       string
+  ManagerVariant                                string
+  ManageTo                                      string
+  ManageUI                                      string
+  PreservedFileName                             string
+  RenditionClass                                string
+  RenditionOfDocumentID                         string
+  RenditionOfInstanceID                         string
+  RenditionOfManager                            string
+  RenditionOfManagerVariant                     string
+  RenditionOfManageTo                           string
+  RenditionOfManageUI                           string
+  RenditionOfRenditionClass                     string
+  RenditionOfRenditionParams                    string
+  RenditionOfVersionID                          string
+  RenditionParams                               string
+  SaveID                                        integer
+  VersionID                                     string
+  VersionsComments                              string+
+  VersionsEventAction                           string+
+  VersionsEventInstanceID                       string+
+  VersionsEventParameters                       string+
+  VersionsEventSoftwareAgent                    string+
+  VersionsEventWhen                             date+
+  VersionsModifier                              string+
+  VersionsModifyDate                            date+
+  VersionsVersion                               string+
+
+=head3 XMP xmpPLUS Tags
+
+XMP Picture Licensing Universal System (PLUS) schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CreditLineReq                                 boolean
+  ReuseAllowed                                  boolean
+
+=head3 XMP xmpRights Tags
+
+XMP Rights Management schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Certificate                                   string
+  Marked                                        boolean
+  Owner                                         string+
+  UsageTerms                                    lang-alt
+  WebStatement                                  string
+
+=head3 XMP xmpTPg Tags
+
+XMP Paged-Text schema tags.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  ColorantsA                                    integer+
+  ColorantsB                                    integer+
+  ColorantsBlack                                real+
+  ColorantsBlue                                 integer+
+  ColorantsCyan                                 real+
+  ColorantsGreen                                integer+
+  ColorantsL                                    real+
+  ColorantsMagenta                              real+
+  ColorantsMode                                 string+
+  ColorantsRed                                  integer+
+  ColorantsSwatchName                           string+
+  ColorantsType                                 string+
+  ColorantsYellow                               real+
+  FontsChildFontFiles                           string+
+  FontsComposite                                boolean+
+  FontsFontFace                                 string+
+  FontsFontFamily                               string+
+  FontsFontFileName                             string+
+  FontsFontName                                 string+
+  FontsFontType                                 string+
+  FontsVersionString                            string+
+  MaxPageSizeH                                  real
+  MaxPageSizeUnit                               string
+  MaxPageSizeW                                  real
+  NPages                                        integer
+  PlateNames                                    string+
+
+=head2 GPS Tags
+
+These GPS tags are part of the EXIF standard, and are stored in a separate
+IFD within the EXIF information.
+
+ExifTool is very flexible about the input format when writing lat/long
+coordinates, and will accept from 1 to 3 floating point numbers (for decimal
+degrees, degrees and minutes, or degrees, minutes and seconds) separated by
+just about anything, and will format them properly according to the EXIF
+specification.
+
+Some GPS tags have values which are fixed-length strings. For these, the
+indicated string lengths include a null terminator which is added
+automatically by ExifTool.  Remember that the descriptive values are used
+when writing (ie. 'Above Sea Level', not '0') unless the print conversion is
+disabled (with '-n' on the command line, or the PrintConv option in the
+API).
+
+When adding GPS information to an image, it is important to set all of the
+following tags: GPSLatitude, GPSLatitudeRef, GPSLongitude, GPSLongitudeRef,
+GPSAltitude and GPSAltitudeRef.  ExifTool will write the required
+GPSVersionID tag automatically if new a GPS IFD is added to an image.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   GPSVersionID                         int8u[4]
+  0x0001   GPSLatitudeRef                       string[2]
+  0x0002   GPSLatitude                          rational64u[3]
+  0x0003   GPSLongitudeRef                      string[2]
+  0x0004   GPSLongitude                         rational64u[3]
+  0x0005   GPSAltitudeRef                       int8u
+  0x0006   GPSAltitude                          rational64u
+  0x0007   GPSTimeStamp                         rational64u[3]
+  0x0008   GPSSatellites                        string
+  0x0009   GPSStatus                            string[2]
+  0x000a   GPSMeasureMode                       string[2]
+  0x000b   GPSDOP                               rational64u
+  0x000c   GPSSpeedRef                          string[2]
+  0x000d   GPSSpeed                             rational64u
+  0x000e   GPSTrackRef                          string[2]
+  0x000f   GPSTrack                             rational64u
+  0x0010   GPSImgDirectionRef                   string[2]
+  0x0011   GPSImgDirection                      rational64u
+  0x0012   GPSMapDatum                          string
+  0x0013   GPSDestLatitudeRef                   string[2]
+  0x0014   GPSDestLatitude                      rational64u[3]
+  0x0015   GPSDestLongitudeRef                  string[2]
+  0x0016   GPSDestLongitude                     rational64u[3]
+  0x0017   GPSDestBearingRef                    string[2]
+  0x0018   GPSDestBearing                       rational64u
+  0x0019   GPSDestDistanceRef                   string[2]
+  0x001a   GPSDestDistance                      rational64u
+  0x001b   GPSProcessingMethod                  undef
+  0x001c   GPSAreaInformation                   undef
+  0x001d   GPSDateStamp                         string[11]
+  0x001e   GPSDifferential                      int16u
+
+=head2 GeoTiff Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   GeoTiffVersion                       N
+  0x0400   GTModelType                          N
+  0x0401   GTRasterType                         N
+  0x0402   GTCitation                           N
+  0x0800   GeographicType                       N
+  0x0801   GeogCitation                         N
+  0x0802   GeogGeodeticDatum                    N
+  0x0803   GeogPrimeMeridian                    N
+  0x0804   GeogLinearUnits                      N
+  0x0805   GeogLinearUnitSize                   N
+  0x0806   GeogAngularUnits                     N
+  0x0807   GeogAngularUnitSize                  N
+  0x0808   GeogEllipsoid                        N
+  0x0809   GeogSemiMajorAxis                    N
+  0x080a   GeogSemiMinorAxis                    N
+  0x080b   GeogInvFlattening                    N
+  0x080c   GeogAzimuthUnits                     N
+  0x080d   GeogPrimeMeridianLong                N
+  0x0c00   ProjectedCSType                      N
+  0x0c01   PCSCitation                          N
+  0x0c02   Projection                           N
+  0x0c03   ProjCoordTrans                       N
+  0x0c04   ProjLinearUnits                      N
+  0x0c05   ProjLinearUnitSize                   N
+  0x0c06   ProjStdParallel1                     N
+  0x0c07   ProjStdParallel2                     N
+  0x0c08   ProjNatOriginLong                    N
+  0x0c09   ProjNatOriginLat                     N
+  0x0c0a   ProjFalseEasting                     N
+  0x0c0b   ProjFalseNorthing                    N
+  0x0c0c   ProjFalseOriginLong                  N
+  0x0c0d   ProjFalseOriginLat                   N
+  0x0c0e   ProjFalseOriginEasting               N
+  0x0c0f   ProjFalseOriginNorthing              N
+  0x0c10   ProjCenterLong                       N
+  0x0c11   ProjCenterLat                        N
+  0x0c12   ProjCenterEasting                    N
+  0x0c13   ProjCenterNorthing                   N
+  0x0c14   ProjScaleAtNatOrigin                 N
+  0x0c15   ProjScaleAtCenter                    N
+  0x0c16   ProjAzimuthAngle                     N
+  0x0c17   ProjStraightVertPoleLong             N
+  0x0c18   ProjRectifiedGridAngle               N
+  0x1000   VerticalCSType                       N
+  0x1001   VerticalCitation                     N
+  0x1002   VerticalDatum                        N
+  0x1003   VerticalUnits                        N
+
+=head2 ICC_Profile Tags
+
+ICC profile information is used in many different file types including JPEG,
+TIFF, PDF, PostScript, Photoshop, PNG, MIFF, PICT, QuickTime and some RAW
+formats.  While the tags listed below are not individually writable, the
+entire profile itself can be accessed via the extra 'ICC_Profile' tag, but
+this tag is neither extracted nor written unless specified explicitly.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'A2B0'   AToB0                                N
+  'A2B1'   AToB1                                N
+  'A2B2'   AToB2                                N
+  'B2A0'   BToA0                                N
+  'B2A1'   BToA1                                N
+  'B2A2'   BToA2                                N
+  'Header' ProfileHeader                        ICC_Profile Header
+  'MS00'   WCSProfiles                          N
+  'bTRC'   BlueTRC                              N
+  'bXYZ'   BlueMatrixColumn                     N
+  'bfd '   UCRBG                                N
+  'bkpt'   MediaBlackPoint                      N
+  'calt'   CalibrationDateTime                  N
+  'chad'   ChromaticAdaptation                  N
+  'chrm'   Chromaticity                         ICC_Profile Chromaticity
+  'clro'   ColorantOrder                        N
+  'clrt'   ColorantTable                        ICC_Profile ColorantTable
+  'cprt'   ProfileCopyright                     N
+  'crdi'   CRDInfo                              N
+  'desc'   ProfileDescription                   N
+  'devs'   DeviceSettings                       N
+  'dmdd'   DeviceModelDesc                      N
+  'dmnd'   DeviceMfgDesc                        N
+  'dscm'   ProfileDescriptionML                 N
+  'gTRC'   GreenTRC                             N
+  'gXYZ'   GreenMatrixColumn                    N
+  'gamt'   Gamut                                N
+  'kTRC'   GrayTRC                              N
+  'lumi'   Luminance                            N
+  'meas'   Measurement                          ICC_Profile Measurement
+  'mmod'   MakeAndModel                         N
+  'ncl2'   NamedColor2                          N
+  'ncol'   NamedColor                           N
+  'ndin'   NativeDisplayInfo                    N
+  'pre0'   Preview0                             N
+  'pre1'   Preview1                             N
+  'pre2'   Preview2                             N
+  'ps2i'   PS2RenteringIntent                   N
+  'ps2s'   PostScript2CSA                       N
+  'psd0'   PostScript2CRD0                      N
+  'psd1'   PostScript2CRD1                      N
+  'psd2'   PostScript2CRD2                      N
+  'pseq'   ProfileSequenceDesc                  N
+  'psvm'   PS2CRDVMSize                         N
+  'rTRC'   RedTRC                               N
+  'rXYZ'   RedMatrixColumn                      N
+  'resp'   OutputResponse                       N
+  'scrd'   ScreeningDesc                        N
+  'scrn'   Screening                            N
+  'targ'   CharTarget                           N
+  'tech'   Technology                           N
+  'vcgt'   VideoCardGamma                       N
+  'view'   ViewingConditions                    ICC_Profile ViewingConditions
+  'vued'   ViewingCondDesc                      N
+  'wtpt'   MediaWhitePoint                      N
+
+=head3 ICC_Profile Header Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      4    ProfileCMMType                       N
+      8    ProfileVersion                       N
+     12    ProfileClass                         N
+     16    ColorSpaceData                       N
+     20    ProfileConnectionSpace               N
+     24    ProfileDateTime                      N
+     36    ProfileFileSignature                 N
+     40    PrimaryPlatform                      N
+     44    CMMFlags                             N
+     48    DeviceManufacturer                   N
+     52    DeviceModel                          N
+     56    DeviceAttributes                     N
+     64    RenderingIntent                      N
+     68    ConnectionSpaceIlluminant            N
+     80    ProfileCreator                       N
+     84    ProfileID                            N
+
+=head3 ICC_Profile Chromaticity Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      8    ChromaticityChannels                 N
+     10    ChromaticityColorant                 N
+     12    ChromaticityChannel1                 N
+     20    ChromaticityChannel2                 N
+     28    ChromaticityChannel3                 N
+     36    ChromaticityChannel4                 N
+
+=head3 ICC_Profile ColorantTable Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      8    ColorantCount                        N
+     12    Colorant1Name                        N
+     44    Colorant1Coordinates                 N
+     50    Colorant2Name                        N
+     82    Colorant2Coordinates                 N
+     88    Colorant3Name                        N
+    120    Colorant3Coordinates                 N
+
+=head3 ICC_Profile Measurement Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      8    MeasurementObserver                  N
+     12    MeasurementBacking                   N
+     24    MeasurementGeometry                  N
+     28    MeasurementFlare                     N
+     32    MeasurementIlluminant                N
+
+=head3 ICC_Profile ViewingConditions Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      8    ViewingCondIlluminant                N
+     20    ViewingCondSurround                  N
+     32    ViewingCondIlluminantType            N
+
+=head2 PrintIM Tags
+
+The format of the PrintIM information is known, however no PrintIM tags have
+been decoded.  Use the Unknown (-u) option to extract PrintIM information.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head2 Photoshop Tags
+
+Photoshop tags are found in PSD files, as well as inside embedded Photoshop
+information in many other file types (JPEG, TIFF, PDF, PNG to name a few).
+
+Many Photoshop tags are marked as Unknown (indicated by a question mark
+after the tag name) because the information they provide is not very useful
+under normal circumstances (and because Adobe denied my application for
+their file format documentation -- apparently open source software is too
+big a concept for them).  These unknown tags are not extracted unless the
+Unknown (-u) option is used.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x03e8   Photoshop2Info?                      N
+  0x03e9   MacintoshPrintInfo?                  N
+  0x03ea   XMLData?                             N
+  0x03eb   Photoshop2ColorTable?                N
+  0x03ed   ResolutionInfo                       Photoshop Resolution
+  0x03ee   AlphaChannelsNames                   N
+  0x03ef   DisplayInfo?                         N
+  0x03f0   PStringCaption?                      N
+  0x03f1   BorderInformation?                   N
+  0x03f2   BackgroundColor?                     N
+  0x03f3   PrintFlags?                          N
+  0x03f4   BW_HalftoningInfo?                   N
+  0x03f5   ColorHalftoningInfo?                 N
+  0x03f6   DuotoneHalftoningInfo?               N
+  0x03f7   BW_TransferFunc?                     N
+  0x03f8   ColorTransferFuncs?                  N
+  0x03f9   DuotoneTransferFuncs?                N
+  0x03fa   DuotoneImageInfo?                    N
+  0x03fb   EffectiveBW?                         N
+  0x03fc   ObsoletePhotoshopTag1?               N
+  0x03fd   EPSOptions?                          N
+  0x03fe   QuickMaskInfo?                       N
+  0x03ff   ObsoletePhotoshopTag2?               N
+  0x0400   LayerStateInfo?                      N
+  0x0401   WorkingPath?                         N
+  0x0402   LayersGroupInfo?                     N
+  0x0403   ObsoletePhotoshopTag3?               N
+  0x0404   IPTCData                             IPTC
+  0x0405   RawImageMode?                        N
+  0x0406   JPEG_Quality                         Photoshop JPEG_Quality
+  0x0408   GridGuidesInfo?                      N
+  0x0409   PhotoshopBGRThumbnail                N
+  0x040a   CopyrightFlag                        int8u
+  0x040b   URL                                  string
+  0x040c   PhotoshopThumbnail                   N
+  0x040d   GlobalAngle                          int32u
+  0x040e   ColorSamplersResource?               N
+  0x040f   ICC_Profile                          ICC_Profile
+  0x0410   Watermark?                           N
+  0x0411   ICC_Untagged?                        N
+  0x0412   EffectsVisible?                      N
+  0x0413   SpotHalftone?                        N
+  0x0414   IDsBaseValue?                        N
+  0x0415   UnicodeAlphaNames?                   N
+  0x0416   IndexedColourTableCount?             N
+  0x0417   TransparentIndex?                    N
+  0x0419   GlobalAltitude                       int32u
+  0x041a   Slices?                              N
+  0x041b   WorkflowURL?                         N
+  0x041c   JumpToXPEP?                          N
+  0x041d   AlphaIdentifiers?                    N
+  0x041e   URL_List?                            N
+  0x0421   VersionInfo?                         N
+  0x0422   EXIFInfo                             EXIF
+  0x0424   XMP                                  XMP
+  0x0bb7   ClippingPathName?                    N
+  0x2710   PrintFlagsInfo?                      N
+
+=head3 Photoshop Resolution Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    XResolution                          int32u
+      2    DisplayedUnitsX                      int16u
+      4    YResolution                          int32u
+      6    DisplayedUnitsY                      int16u
+
+=head3 Photoshop JPEG_Quality Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    PhotoshopQuality                     int16s
+      1    PhotoshopFormat                      N
+      2    ProgressiveScans                     N
+
+=head3 Photoshop Header Tags
+
+This information is found in the PSD file header.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      6    NumChannels                          N
+      7    ImageHeight                          N
+      9    ImageWidth                           N
+     11    BitDepth                             N
+     12    ColorMode                            N
+
+=head2 Canon Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   CanonCameraSettings                  Canon CameraSettings
+  0x0002   CanonFocalLength                     Canon FocalLength
+  0x0003   CanonFlashInfo?                      N
+  0x0004   CanonShotInfo                        Canon ShotInfo
+  0x0005   CanonPanorama                        Canon Panorama
+  0x0006   CanonImageType                       string
+  0x0007   CanonFirmwareVersion                 string
+  0x0008   FileNumber                           int32u
+  0x0009   OwnerName                            string
+  0x000a   ColorInfoD30                         Canon ColorInfoD30
+  0x000c   SerialNumber                         int32u
+  0x000d   CanonCameraInfo                      Canon CameraInfo
+           CanonCameraInfo1DmkIII               Canon CameraInfo1DmkIII
+           CanonCameraInfo2                     Canon CameraInfo2
+           CanonCameraInfoUnknown32             Canon CameraInfoUnknown32
+           CanonCameraInfoUnknown16             Canon CameraInfoUnknown16
+           CanonCameraInfoUnknown8              Canon CameraInfoUnknown8
+  0x000e   CanonFileLength                      int32u
+  0x000f   CustomFunctions1D                    CanonCustom Functions1D
+           CustomFunctions5D                    CanonCustom Functions5D
+           CustomFunctions10D                   CanonCustom Functions10D
+           CustomFunctions20D                   CanonCustom Functions20D
+           CustomFunctions30D                   CanonCustom Functions30D
+           CustomFunctions350D                  CanonCustom Functions350D
+           CustomFunctions400D                  CanonCustom Functions400D
+           CustomFunctionsD30                   CanonCustom FunctionsD30
+           CustomFunctionsD60                   CanonCustom FunctionsD30
+           CustomFunctionsUnknown               CanonCustom FuncsUnknown
+  0x0010   CanonModelID                         int32u
+  0x0012   CanonAFInfo                          Canon AFInfo
+  0x0015   SerialNumberFormat                   int32u
+  0x001c   DateStampMode                        int16u
+  0x001d   MyColors                             Canon MyColors
+  0x001e   FirmwareRevision                     int32u
+  0x0024   FaceDetect1                          Canon FaceDetect1
+  0x0025   FaceDetect2                          Canon FaceDetect2
+  0x0026   CanonAFInfo2                         Canon AFInfo2
+  0x0083   OriginalDecisionData                 int32u
+  0x0090   CustomFunctions1D                    CanonCustom Functions1D
+  0x0091   PersonalFunctions                    CanonCustom PersonalFuncs
+  0x0092   PersonalFunctionValues               CanonCustom PersonalFuncValues
+  0x0093   CanonFileInfo                        Canon FileInfo
+  0x0094   AFPointsInFocus1D                    N
+  0x0095   LensType                             string
+  0x0096   InternalSerialNumber                 string
+  0x0097   DustRemovalData                      N
+  0x0099   CustomFunctions2                     CanonCustom Functions2
+  0x00a0   ProccessingInfo                      Canon Processing
+  0x00a1   ToneCurveTable                       N
+  0x00a2   SharpnessTable                       N
+  0x00a3   SharpnessFreqTable                   N
+  0x00a4   WhiteBalanceTable                    N
+  0x00a9   ColorBalance                         Canon ColorBalance
+  0x00ae   ColorTemperature                     int16u
+  0x00b0   CanonFlags                           Canon Flags
+  0x00b1   ModifiedInfo                         Canon ModifiedInfo
+  0x00b2   ToneCurveMatching                    N
+  0x00b3   WhiteBalanceMatching                 N
+  0x00b4   ColorSpace                           int16u
+  0x00b6   PreviewImageInfo                     Canon PreviewImageInfo
+  0x00d0   VRDOffset                            int32u*
+  0x00e0   SensorInfo                           Canon SensorInfo
+  0x4001   ColorBalance1                        Canon ColorBalance1
+           ColorBalance2                        Canon ColorBalance2
+           ColorBalance3                        Canon ColorBalance3
+           ColorBalanceUnknown                  N
+  0x4002   UnknownBlock1?                       N
+  0x4003   ColorInfo                            Canon ColorInfo
+  0x4005   UnknownBlock2?                       N
+  0x4008   BlackLevel?                          N
+
+=head3 Canon CameraSettings Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    MacroMode                            int16s
+      2    Self-timer                           int16s
+      3    Quality                              int16s
+      4    CanonFlashMode                       int16s
+      5    ContinuousDrive                      int16s
+      7    FocusMode                            int16s
+      9    RecordMode                           int16s
+     10    CanonImageSize                       int16s
+     11    EasyMode                             int16s
+     12    DigitalZoom                          int16s
+     13    Contrast                             int16s
+     14    Saturation                           int16s
+     15    Sharpness                            int16s
+     16    CameraISO                            int16s
+     17    MeteringMode                         int16s
+     18    FocusRange                           int16s
+     19    AFPoint                              int16s
+     20    CanonExposureMode                    int16s
+     22    LensType                             int16s
+     23    LongFocal                            int16u
+     24    ShortFocal                           int16u
+     25    FocalUnits                           int16s
+     26    MaxAperture                          int16s
+     27    MinAperture                          int16s
+     28    FlashActivity                        int16s
+     29    FlashBits                            int16s
+     32    FocusContinuous                      int16s
+     33    AESetting                            int16s
+     34    ImageStabilization                   int16s
+     35    DisplayAperture                      int16s
+     36    ZoomSourceWidth                      int16s
+     37    ZoomTargetWidth                      int16s
+     40    PhotoEffect                          int16s
+     41    ManualFlashOutput                    int16s
+     42    ColorTone                            int16s
+
+=head3 Canon FocalLength Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    FocalType                            int16u
+      1    FocalLength                          int16u
+      2    FocalPlaneXSize                      int16u
+      3    FocalPlaneYSize                      int16u
+
+=head3 Canon ShotInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    AutoISO                              int16s
+      2    BaseISO                              int16s
+      3    MeasuredEV                           int16s
+      4    TargetAperture                       int16s
+      5    TargetExposureTime                   int16s
+      6    ExposureCompensation                 int16s
+      7    WhiteBalance                         int16s
+      8    SlowShutter                          int16s
+      9    SequenceNumber                       int16s
+     10    OpticalZoomCode                      int16s
+     13    FlashGuideNumber                     int16s
+     14    AFPointsInFocus                      int16s
+     15    FlashExposureComp                    int16s
+     16    AutoExposureBracketing               int16s
+     17    AEBBracketValue                      int16s
+     19    FocusDistanceUpper                   int16s
+     20    FocusDistanceLower                   int16s
+     21    FNumber                              int16s
+     22    ExposureTime                         int16s
+     24    BulbDuration                         int16s
+     26    CameraType                           int16s
+     27    AutoRotate                           int16s
+     28    NDFilter                             int16s
+     29    Self-timer2                          int16s
+     33    FlashOutput                          int16s
+
+=head3 Canon Panorama Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      2    PanoramaFrame                        int16s
+      5    PanoramaDirection                    int16s
+
+=head3 Canon ColorInfoD30 Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      9    ColorTemperature                     int16s
+     10    ColorMatrix                          int16s
+
+=head3 Canon CameraInfo Tags
+
+Information in the "CameraInfo" records is tricky to decode because the
+encodings are very different than in other Canon records (even sometimes
+switching endianness between values within a single camera), plus there is
+considerable variation in format from model to model. The table below is
+common to the 1D, 1DS, 1DmkII, 1DSmkII and 5D, but individual tags may not
+be valid for all these models.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      3    FNumber                              int8u
+      4    ExposureTime                         int8u
+      6    ISO                                  int8u
+      9    FocalLength                          int16u
+     13    LensType                             int8u
+     17    ShortFocal                           int16u
+     19    LongFocal                            int16u
+     45    FocalType                            int8u
+     56    AFPointsInFocus5D                    undef[2]
+    108    PictureStyle                         int16u
+    164    FirmwareRevision                     string[8]
+    172    ShortOwnerName                       string[16]
+    208    ImageNumber                          int16u
+    232    ContrastStandard                     int8s
+    233    ContrastPortrait                     int8s
+    234    ContrastLandscape                    int8s
+    235    ContrastNeutral                      int8s
+    236    ContrastFaithful                     int8s
+    237    ContrastMonochrome                   int8s
+    238    ContrastUserDef1                     int8s
+    239    ContrastUserDef2                     int8s
+    240    ContrastUserDef3                     int8s
+    241    SharpnessStandard                    int8s
+    242    SharpnessPortrait                    int8s
+    243    SharpnessLandscape                   int8s
+    244    SharpnessNeutral                     int8s
+    245    SharpnessFaithful                    int8s
+    246    SharpnessMonochrome                  int8s
+    247    SharpnessUserDef1                    int8s
+    248    SharpnessUserDef2                    int8s
+    249    SharpnessUserDef3                    int8s
+    250    SaturationStandard                   int8s
+    251    SaturationPortrait                   int8s
+    252    SaturationLandscape                  int8s
+    253    SaturationNeutral                    int8s
+    254    SaturationFaithful                   int8s
+    255    FilterEffectMonochrome               int8s
+    256    SaturationUserDef1                   int8s
+    257    SaturationUserDef2                   int8s
+    258    SaturationUserDef3                   int8s
+    259    ColorToneStandard                    int8s
+    260    ColorTonePortrait                    int8s
+    261    ColorToneLandscape                   int8s
+    262    ColorToneNeutral                     int8s
+    263    ColorToneFaithful                    int8s
+    264    ToningEffectMonochrome               int8s
+    265    ColorToneUserDef1                    int8s
+    266    ColorToneUserDef2                    int8s
+    267    ColorToneUserDef3                    int8s
+    268    UserDef1PictureStyle                 int16u
+    270    UserDef2PictureStyle                 int16u
+    272    UserDef3PictureStyle                 int16u
+    284    TimeStamp                            int32u
+
+=head3 Canon CameraInfo1DmkIII Tags
+
+CameraInfo tags valid for the EOS 1D Mark III.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      3    FNumber                              int8u
+      4    ExposureTime                         int8u
+      6    ISO                                  int8u
+     29    FocalLength                          int16u
+    134    PictureStyle                         int8u
+    275    ShortFocal                           int16u
+    277    LongFocal                            int16u
+    370    FileNumber                           int32u
+    374    ShutterCount                         int32u
+   1118    TimeStamp                            int32u
+
+=head3 Canon CameraInfo2 Tags
+
+These tags used by a number of newer PowerShot models.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ISO                                  int32s
+      5    FNumber                              int32s
+      6    ExposureTime                         int32s
+     23    Rotation                             int32s
+
+=head3 Canon CameraInfoUnknown32 Tags
+
+Unknown CameraInfo tags are divided into 3 tables based on format size.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+  [no tags known]
+
+=head3 Canon CameraInfoUnknown16 Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+  [no tags known]
+
+=head3 Canon CameraInfoUnknown8 Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+  [no tags known]
+
+=head3 Canon AFInfo Tags
+
+Auto-focus information used by many older Canon models.  The values in this
+record are sequential, and some have variable sizes based on the value of
+NumAFPoints (which may be 1,5,7,9,15,45 or 53).  The AFArea coordinates are
+given in a system where the image has dimensions given by AFImageWidth and
+AFImageHeight, and 0,0 is the image center. The direction of the Y axis
+depends on the camera model, with positive Y upwards for EOS models, but
+apparently downwards for PowerShot models.
+
+  Sequence Tag Name                             Writable
+  -------- --------                             --------
+      0    NumAFPoints                          N
+      1    ValidAFPoints                        N
+      2    CanonImageWidth                      N
+      3    CanonImageHeight                     N
+      4    AFImageWidth                         N
+      5    AFImageHeight                        N
+      6    AFAreaWidth                          N
+      7    AFAreaHeight                         N
+      8    AFAreaXPositions                     N
+      9    AFAreaYPositions                     N
+     10    AFPointsInFocus                      N
+     11    PrimaryAFPoint                       N
+           Canon_AFInfo_0x000b?                 N
+     12    PrimaryAFPoint                       N
+
+=head3 Canon MyColors Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      2    MyColorMode                          int16u
+
+=head3 Canon FaceDetect1 Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      2    FacesDetected                        int16u
+      3    FaceDetectFrameWidth                 int16u
+      4    FaceDetectFrameHeight                int16u
+      8    Face0Position                        int16s[2]
+     10    Face1Position                        int16s[2]
+     12    Face2Position                        int16s[2]
+     14    Face3Position                        int16s[2]
+     16    Face4Position                        int16s[2]
+     18    Face5Position                        int16s[2]
+     20    Face6Position                        int16s[2]
+     22    Face7Position                        int16s[2]
+     24    Face8Position                        int16s[2]
+
+=head3 Canon FaceDetect2 Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      2    FacesDetected                        int8u
+
+=head3 Canon AFInfo2 Tags
+
+Newer version of the AFInfo record containing much of the same information
+(and coordinate confusion) as the older version.  In this record, values of
+9 and 45 have been observed for NumAFPoints.
+
+  Sequence Tag Name                             Writable
+  -------- --------                             --------
+      0    AFInfoSize?                          N
+      1    AFMode                               N
+      2    NumAFPoints                          N
+      3    ValidAFPoints                        N
+      4    CanonImageWidth                      N
+      5    CanonImageWidth                      N
+      6    AFImageWidth                         N
+      7    AFImageHeight                        N
+      8    AFAreaWidths                         N
+      9    AFAreaHeights                        N
+     10    AFAreaXPositions                     N
+     11    AFAreaYPositions                     N
+     12    AFPointsInFocus                      N
+     13    AFPointsSelected                     N
+           Canon_AFInfo2_0x000d?                N
+     14    PrimaryAFPoint                       N
+
+=head3 Canon FileInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    FileNumber                           int32u
+           ShutterCount                         int32u
+      3    BracketMode                          int16s
+      4    BracketValue                         int16s
+      5    BracketShotNumber                    int16s
+      6    RawJpgQuality                        int16s
+      7    RawJpgSize                           int16s
+      8    NoiseReduction                       int16s
+      9    WBBracketMode                        int16s
+     12    WBBracketValueAB                     int16s
+     13    WBBracketValueGM                     int16s
+     14    FilterEffect                         int16s
+     15    ToningEffect                         int16s
+
+=head3 Canon Processing Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    ToneCurve                            int16s
+      2    Sharpness                            int16s
+      3    SharpnessFrequency                   int16s
+      4    SensorRedLevel                       int16s
+      5    SensorBlueLevel                      int16s
+      6    WhiteBalanceRed                      int16s
+      7    WhiteBalanceBlue                     int16s
+      8    WhiteBalance                         int16s
+      9    ColorTemperature                     int16s
+     10    PictureStyle                         int16s
+     11    DigitalGain                          int16s
+     12    WBShiftAB                            int16s
+     13    WBShiftGM                            int16s
+
+=head3 Canon ColorBalance Tags
+
+This table is used by the 10D and 300D.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    WB_RGGBLevelsAuto                    int16u[4]
+      4    WB_RGGBLevelsDaylight                int16u[4]
+      8    WB_RGGBLevelsShade                   int16u[4]
+     12    WB_RGGBLevelsCloudy                  int16u[4]
+     16    WB_RGGBLevelsTungsten                int16u[4]
+     20    WB_RGGBLevelsFluorescent             int16u[4]
+     24    WB_RGGBLevelsFlash                   int16u[4]
+     28    WB_RGGBLevelsCustom                  int16u[4]
+     32    WB_RGGBLevelsKelvin                  int16u[4]
+
+=head3 Canon Flags Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    ModifiedParamFlag                    int16s
+
+=head3 Canon ModifiedInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    ModifiedToneCurve                    int16s
+      2    ModifiedSharpness                    int16s
+      3    ModifiedSharpnessFreq                int16s
+      4    ModifiedSensorRedLevel               int16s
+      5    ModifiedSensorBlueLevel              int16s
+      6    ModifiedWhiteBalanceRed              int16s
+      7    ModifiedWhiteBalanceBlue             int16s
+      8    ModifiedWhiteBalance                 int16s
+      9    ModifiedColorTemp                    int16s
+     10    ModifiedPictureStyle                 int16s
+     11    ModifiedDigitalGain                  int16s
+
+=head3 Canon PreviewImageInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    PreviewQuality                       int32u
+      2    PreviewImageLength                   int32u*
+      3    PreviewImageWidth                    int32u
+      4    PreviewImageHeight                   int32u
+      5    PreviewImageStart                    int32u*
+      6    PreviewFocalPlaneXResolution         rational64s
+      8    PreviewFocalPlaneYResolution         rational64s
+
+=head3 Canon SensorInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    SensorWidth                          N
+      2    SensorHeight                         N
+      5    SensorLeftBorder                     N
+      6    SensorTopBorder                      N
+      7    SensorRightBorder                    N
+      8    SensorBottomBorder                   N
+
+=head3 Canon ColorBalance1 Tags
+
+This table is used by the 20D and 350D.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+     25    WB_RGGBLevelsAsShot                  int16u[4]
+     29    ColorTempAsShot                      int16u
+     30    WB_RGGBLevelsAuto                    int16u[4]
+     34    ColorTempAuto                        int16u
+     35    WB_RGGBLevelsDaylight                int16u[4]
+     39    ColorTempDaylight                    int16u
+     40    WB_RGGBLevelsShade                   int16u[4]
+     44    ColorTempShade                       int16u
+     45    WB_RGGBLevelsCloudy                  int16u[4]
+     49    ColorTempCloudy                      int16u
+     50    WB_RGGBLevelsTungsten                int16u[4]
+     54    ColorTempTungsten                    int16u
+     55    WB_RGGBLevelsFluorescent             int16u[4]
+     59    ColorTempFluorescent                 int16u
+     60    WB_RGGBLevelsFlash                   int16u[4]
+     64    ColorTempFlash                       int16u
+     65    WB_RGGBLevelsCustom1                 int16u[4]
+     69    ColorTempCustom1                     int16u
+     70    WB_RGGBLevelsCustom2                 int16u[4]
+     74    ColorTempCustom2                     int16u
+
+=head3 Canon ColorBalance2 Tags
+
+This table is used by the 1DmkII and 1DSmkII.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+     24    WB_RGGBLevelsAsShot                  int16u[4]
+     28    ColorTempAsShot                      int16u
+     29    WB_RGGBLevelsUnknown?                int16u[4]
+     33    ColorTempUnknown?                    int16u
+     34    WB_RGGBLevelsAuto                    int16u[4]
+     38    ColorTempAuto                        int16u
+     39    WB_RGGBLevelsDaylight                int16u[4]
+     43    ColorTempDaylight                    int16u
+     44    WB_RGGBLevelsShade                   int16u[4]
+     48    ColorTempShade                       int16u
+     49    WB_RGGBLevelsCloudy                  int16u[4]
+     53    ColorTempCloudy                      int16u
+     54    WB_RGGBLevelsTungsten                int16u[4]
+     58    ColorTempTungsten                    int16u
+     59    WB_RGGBLevelsFluorescent             int16u[4]
+     63    ColorTempFluorescent                 int16u
+     64    WB_RGGBLevelsKelvin                  int16u[4]
+     68    ColorTempKelvin                      int16u
+     69    WB_RGGBLevelsFlash                   int16u[4]
+     73    ColorTempFlash                       int16u
+     74    WB_RGGBLevelsUnknown2?               int16u[4]
+     78    ColorTempUnknown2?                   int16u
+     79    WB_RGGBLevelsUnknown3?               int16u[4]
+     83    ColorTempUnknown3?                   int16u
+     84    WB_RGGBLevelsUnknown4?               int16u[4]
+     88    ColorTempUnknown4?                   int16u
+     89    WB_RGGBLevelsUnknown5?               int16u[4]
+     93    ColorTempUnknown5?                   int16u
+     94    WB_RGGBLevelsUnknown6?               int16u[4]
+     98    ColorTempUnknown6?                   int16u
+     99    WB_RGGBLevelsUnknown7?               int16u[4]
+    103    ColorTempUnknown7?                   int16u
+    104    WB_RGGBLevelsUnknown8?               int16u[4]
+    108    ColorTempUnknown8?                   int16u
+    109    WB_RGGBLevelsUnknown9?               int16u[4]
+    113    ColorTempUnknown9?                   int16u
+    114    WB_RGGBLevelsUnknown10?              int16u[4]
+    118    ColorTempUnknown10?                  int16u
+    119    WB_RGGBLevelsUnknown11?              int16u[4]
+    123    ColorTempUnknown11?                  int16u
+    124    WB_RGGBLevelsUnknown12?              int16u[4]
+    128    ColorTempUnknown12?                  int16u
+    129    WB_RGGBLevelsUnknown13?              int16u[4]
+    133    ColorTempUnknown13?                  int16u
+    134    WB_RGGBLevelsUnknown14?              int16u[4]
+    138    ColorTempUnknown14?                  int16u
+    139    WB_RGGBLevelsUnknown15?              int16u[4]
+    143    ColorTempUnknown15?                  int16u
+    144    WB_RGGBLevelsPC1                     int16u[4]
+    148    ColorTempPC1                         int16u
+    149    WB_RGGBLevelsPC2                     int16u[4]
+    153    ColorTempPC2                         int16u
+    154    WB_RGGBLevelsPC3                     int16u[4]
+    158    ColorTempPC3                         int16u
+    159    WB_RGGBLevelsUnknown16?              int16u[4]
+    163    ColorTempUnknown16?                  int16u
+
+=head3 Canon ColorBalance3 Tags
+
+This table is used by the 1DmkIIN, 5D, 30D and 400D.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+     63    WB_RGGBLevelsAsShot                  int16u[4]
+     67    ColorTempAsShot                      int16u
+     68    WB_RGGBLevelsAuto                    int16u[4]
+     72    ColorTempAuto                        int16u
+     73    WB_RGGBLevelsMeasured                int16u[4]
+     77    ColorTempMeasured                    int16u
+     78    WB_RGGBLevelsDaylight                int16u[4]
+     82    ColorTempDaylight                    int16u
+     83    WB_RGGBLevelsShade                   int16u[4]
+     87    ColorTempShade                       int16u
+     88    WB_RGGBLevelsCloudy                  int16u[4]
+     92    ColorTempCloudy                      int16u
+     93    WB_RGGBLevelsTungsten                int16u[4]
+     97    ColorTempTungsten                    int16u
+     98    WB_RGGBLevelsFluorescent             int16u[4]
+    102    ColorTempFluorescent                 int16u
+    103    WB_RGGBLevelsKelvin                  int16u[4]
+    107    ColorTempKelvin                      int16u
+    108    WB_RGGBLevelsFlash                   int16u[4]
+    112    ColorTempFlash                       int16u
+    113    WB_RGGBLevelsPC1                     int16u[4]
+    117    ColorTempPC1                         int16u
+    118    WB_RGGBLevelsPC2                     int16u[4]
+    122    ColorTempPC2                         int16u
+    123    WB_RGGBLevelsPC3                     int16u[4]
+    127    ColorTempPC3                         int16u
+    128    WB_RGGBLevelsCustom                  int16u[4]
+    132    ColorTempCustom                      int16u
+
+=head3 Canon ColorInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    Saturation                           int16s
+      2    ColorHue                             int16s
+      3    ColorSpace                           int16s
+
+=head2 CanonCustom Tags
+
+=head3 CanonCustom Functions1D Tags
+
+These custom functions are used by all 1D models up to but not including the
+Mark III.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+      0    FocusingScreen                       int8u
+      1    FinderDisplayDuringExposure          int8u
+      2    ShutterReleaseNoCFCard               int8u
+      3    ISOSpeedExpansion                    int8u
+      4    ShutterAELButton                     int8u
+      5    ManualTv                             int8u
+      6    ExposureLevelIncrements              int8u
+      7    USMLensElectronicMF                  int8u
+      8    LCDPanels                            int8u
+      9    AEBSequence                          int8u
+     10    AFPointIllumination                  int8u
+     11    AFPointSelection                     int8u
+     12    MirrorLockup                         int8u
+     13    AFPointSpotMetering                  int8u
+     14    FillFlashAutoReduction               int8u
+     15    ShutterCurtainSync                   int8u
+     16    SafetyShiftInAvOrTv                  int8u
+     17    AFPointActivationArea                int8u
+     18    SwitchToRegisteredAFPoint            int8u
+     19    LensAFStopButton                     int8u
+     20    AIServoTrackingSensitivity           int8u
+
+=head3 CanonCustom Functions5D Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+      0    FocusingScreen                       int8u
+      1    SetFunctionWhenShooting              int8u
+      2    LongExposureNoiseReduction           int8u
+      3    FlashSyncSpeedAv                     int8u
+      4    Shutter-AELock                       int8u
+      5    AFAssistBeam                         int8u
+      6    ExposureLevelIncrements              int8u
+      7    FlashFiring                          int8u
+      8    ISOExpansion                         int8u
+      9    AEBSequence                          int8u
+     10    SuperimposedDisplay                  int8u
+     11    MenuButtonDisplayPosition            int8u
+     12    MirrorLockup                         int8u
+     13    AFPointSelectionMethod               int8u
+     14    ETTLII                               int8u
+     15    ShutterCurtainSync                   int8u
+     16    SafetyShiftInAvOrTv                  int8u
+     17    AFPointActivationArea                int8u
+     18    LCDDisplayReturnToShoot              int8u
+     19    LensAFStopButton                     int8u
+     20    AddOriginalDecisionData              int8u
+
+=head3 CanonCustom Functions10D Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+      1    SetButtonFunction                    int8u
+      2    ShutterReleaseNoCFCard               int8u
+      3    FlashSyncSpeedAv                     int8u
+      4    Shutter-AELock                       int8u
+      5    AFAssist                             int8u
+      6    ExposureLevelIncrements              int8u
+      7    AFPointRegistration                  int8u
+      8    RawAndJpgRecording                   int8u
+      9    AEBSequence                          int8u
+     10    SuperimposedDisplay                  int8u
+     11    MenuButtonDisplayPosition            int8u
+     12    MirrorLockup                         int8u
+     13    AssistButtonFunction                 int8u
+     14    FillFlashAutoReduction               int8u
+     15    ShutterCurtainSync                   int8u
+     16    SafetyShiftInAvOrTv                  int8u
+     17    LensAFStopButton                     int8u
+
+=head3 CanonCustom Functions20D Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+      0    SetFunctionWhenShooting              int8u
+      1    LongExposureNoiseReduction           int8u
+      2    FlashSyncSpeedAv                     int8u
+      3    Shutter-AELock                       int8u
+      4    AFAssistBeam                         int8u
+      5    ExposureLevelIncrements              int8u
+      6    FlashFiring                          int8u
+      7    ISOExpansion                         int8u
+      8    AEBSequence                          int8u
+      9    SuperimposedDisplay                  int8u
+     10    MenuButtonDisplayPosition            int8u
+     11    MirrorLockup                         int8u
+     12    AFPointSelectionMethod               int8u
+     13    ETTLII                               int8u
+     14    ShutterCurtainSync                   int8u
+     15    SafetyShiftInAvOrTv                  int8u
+     16    LensAFStopButton                     int8u
+     17    AddOriginalDecisionData              int8u
+
+=head3 CanonCustom Functions30D Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+      1    SetFunctionWhenShooting              int8u
+      2    LongExposureNoiseReduction           int8u
+      3    FlashSyncSpeedAv                     int8u
+      4    Shutter-AELock                       int8u
+      5    AFAssistBeam                         int8u
+      6    ExposureLevelIncrements              int8u
+      7    FlashFiring                          int8u
+      8    ISOExpansion                         int8u
+      9    AEBSequence                          int8u
+     10    SuperimposedDisplay                  int8u
+     11    MenuButtonDisplayPosition            int8u
+     12    MirrorLockup                         int8u
+     13    AFPointSelectionMethod               int8u
+     14    ETTLII                               int8u
+     15    ShutterCurtainSync                   int8u
+     16    SafetyShiftInAvOrTv                  int8u
+     17    MagnifiedView                        int8u
+     18    LensAFStopButton                     int8u
+     19    AddOriginalDecisionData              int8u
+
+=head3 CanonCustom Functions350D Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+      0    SetButtonCrossKeysFunc               int8u
+      1    LongExposureNoiseReduction           int8u
+      2    FlashSyncSpeedAv                     int8u
+      3    Shutter-AELock                       int8u
+      4    AFAssistBeam                         int8u
+      5    ExposureLevelIncrements              int8u
+      6    MirrorLockup                         int8u
+      7    ETTLII                               int8u
+      8    ShutterCurtainSync                   int8u
+
+=head3 CanonCustom Functions400D Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+      0    SetButtonCrossKeysFunc               int8u
+      1    LongExposureNoiseReduction           int8u
+      2    FlashSyncSpeedAv                     int8u
+      3    Shutter-AELock                       int8u
+      4    AFAssistBeam                         int8u
+      5    ExposureLevelIncrements              int8u
+      6    MirrorLockup                         int8u
+      7    ETTLII                               int8u
+      8    ShutterCurtainSync                   int8u
+      9    MagnifiedView                        int8u
+     10    LCDDisplayAtPowerOn                  int8u
+
+=head3 CanonCustom FunctionsD30 Tags
+
+Custom functions for the EOS-D30 and D60.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+      1    LongExposureNoiseReduction           int8u
+      2    Shutter-AELock                       int8u
+      3    MirrorLockup                         int8u
+      4    ExposureLevelIncrements              int8u
+      5    AFAssist                             int8u
+      6    FlashSyncSpeedAv                     int8u
+      7    AEBSequence                          int8u
+      8    ShutterCurtainSync                   int8u
+      9    LensAFStopButton                     int8u
+     10    FillFlashAutoReduction               int8u
+     11    MenuButtonReturn                     int8u
+     12    SetButtonFunction                    int8u
+     13    SensorCleaning                       int8u
+     14    SuperimposedDisplay                  int8u
+     15    ShutterReleaseNoCFCard               int8u
+
+=head3 CanonCustom FuncsUnknown Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head3 CanonCustom PersonalFuncs Tags
+
+Personal function settings for the EOS-1D.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    PF0CustomFuncRegistration            int16u
+      2    PF1DisableShootingModes              int16u
+      3    PF2DisableMeteringModes              int16u
+      4    PF3ManualExposureMetering            int16u
+      5    PF4ExposureTimeLimits                int16u
+      6    PF5ApertureLimits                    int16u
+      7    PF6PresetShootingModes               int16u
+      8    PF7BracketContinuousShoot            int16u
+      9    PF8SetBracketShots                   int16u
+     10    PF9ChangeBracketSequence             int16u
+     11    PF10RetainProgramShift               int16u
+     14    PF13DrivePriority                    int16u
+     15    PF14DisableFocusSearch               int16u
+     16    PF15DisableAFAssistBeam              int16u
+     17    PF16AutoFocusPointShoot              int16u
+     18    PF17DisableAFPointSel                int16u
+     19    PF18EnableAutoAFPointSel             int16u
+     20    PF19ContinuousShootSpeed             int16u
+     21    PF20LimitContinousShots              int16u
+     22    PF21EnableQuietOperation             int16u
+     24    PF23SetTimerLengths                  int16u
+     25    PF24LightLCDDuringBulb               int16u
+     26    PF25DefaultClearSettings             int16u
+     27    PF26ShortenReleaseLag                int16u
+     28    PF27ReverseDialRotation              int16u
+     29    PF28NoQuickDialExpComp               int16u
+     30    PF29QuickDialSwitchOff               int16u
+     31    PF30EnlargementMode                  int16u
+     32    PF31OriginalDecisionData             int16u
+
+=head3 CanonCustom PersonalFuncValues Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    PF1Value                             int16u
+      2    PF2Value                             int16u
+      3    PF3Value                             int16u
+      4    PF4ExposureTimeMin                   int16u
+      5    PF4ExposureTimeMax                   int16u
+      6    PF5ApertureMin                       int16u
+      7    PF5ApertureMax                       int16u
+      8    PF8BracketShots                      int16u
+      9    PF19ShootingSpeedLow                 int16u
+     10    PF19ShootingSpeedHigh                int16u
+     11    PF20MaxContinousShots                int16u
+     12    PF23ShutterButtonTime                int16u
+     13    PF23FELockTime                       int16u
+     14    PF23PostReleaseTime                  int16u
+     15    PF25AEMode                           int16u
+     16    PF25MeteringMode                     int16u
+     17    PF25DriveMode                        int16u
+     18    PF25AFMode                           int16u
+     19    PF25AFPointSel                       int16u
+     20    PF25ImageSize                        int16u
+     21    PF25WBMode                           int16u
+     22    PF25Parameters                       int16u
+     23    PF25ColorMatrix                      int16u
+     24    PF27Value                            int16u
+
+=head3 CanonCustom Functions2 Tags
+
+Beginning with the EOS 1D Mark III, Canon finally created a set of custom
+function tags which are consistent across models.  The EOS 1D Mark III has
+57 custom function tags divided into four main groups: 1. Exposure
+(0x0101-0x010f), 2. Image (0x0201-0x0203), Flash Exposure (0x0304-0x0306)
+and Display (0x0407-0x0409), 3. Auto Focus (0x0501-0x050e) and Drive
+(0x060f-0x0611), and 4. Operation (0x0701-0x070a) and Others
+(0x080b-0x0810).  The table below lists tags used by the EOS 1D Mark III, as
+well as newer values and tags used by the EOS 40D.  It is expected that
+future models will re-use some of these tags (possibly with minor value
+changes), as well as defining additional new tags of their own.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0101   ExposureLevelIncrements              int32s
+  0x0102   ISOSpeedIncrements                   int32s
+  0x0103   ISOExpansion                         int32s
+           ISOSpeedRange                        int32s[3]
+  0x0104   AEBAutoCancel                        int32s
+  0x0105   AEBSequence                          int32s
+  0x0106   AEBShotCount                         int32s
+  0x0107   SpotMeterLinkToAFPoint               int32s
+  0x0108   SafetyShift                          int32s
+  0x0109   UsableShootingModes                  int32s[2]
+  0x010a   UsableMeteringModes                  int32s[2]
+  0x010b   ExposureModeInManual                 int32s
+  0x010c   ShutterSpeedRange                    int32s[3]
+  0x010d   ApertureRange                        int32s[3]
+  0x010e   ApplyShootingMeteringMode            int32s[8]
+  0x010f   FlashSyncSpeedAv                     int32s
+  0x0201   LongExposureNoiseReduction           int32s
+  0x0202   HighISONoiseReduction                int32s
+  0x0203   HighlightTonePriority                int32s
+  0x0304   ETTLII                               int32s
+  0x0305   ShutterCurtainSync                   int32s
+  0x0306   FlashFiring                          int32s
+  0x0407   ViewInfoDuringExposure               int32s
+  0x0408   LCDIlluminationDuringBulb            int32s
+  0x0409   InfoButtonWhenShooting               int32s
+  0x0501   USMLensElectronicMF                  int32s
+  0x0502   AIServoTrackingSensitivity           int32s
+  0x0503   AIServoImagePriority                 int32s
+  0x0504   AIServoTrackingMethod                int32s
+  0x0505   LensDriveNoAF                        int32s
+  0x0506   LensAFStopButton                     int32s
+  0x0507   AFMicroadjustment                    int32s[5]
+  0x0508   AFExpansionWithSelectedPoint         int32s
+  0x0509   SelectableAFPoint                    int32s
+  0x050a   SwitchToRegisteredAFPoint            int32s
+  0x050b   AFPointAutoSelection                 int32s
+  0x050c   AFPointDisplayDuringFocus            int32s
+  0x050d   AFPointBrightness                    int32s
+  0x050e   AFAssistBeam                         int32s
+  0x050f   AFPointSelectionMethod               int32s
+  0x0510   SuperimposedDisplay                  int32s
+  0x0511   AFDuringLiveView                     int32s
+  0x060f   MirrorLockup                         int32s
+  0x0610   ContinuousShootingSpeed              int32s[3]
+  0x0611   ContinuousShotLimit                  int32s[2]
+  0x0701   ShutterButtonAFOnButton              int32s
+  0x0702   AFOnAELockButtonSwitch               int32s
+  0x0703   QuickControlDialInMeter              int32s
+  0x0704   SetButtonWhenShooting                int32s
+  0x0705   ManualTv                             int32s
+  0x0706   DialDirectionTvAv                    int32s
+  0x0707   AvSettingWithoutLens                 int32s
+  0x0708   WBMediaImageSizeSetting              int32s
+  0x0709   LockMicrophoneButton                 int32s
+  0x070a   ButtonFunctionControlOff             int32s
+  0x080b   FocusingScreen                       int32s
+  0x080c   TimerLength                          int32s[4]
+  0x080d   ShortReleaseTimeLag                  int32s
+  0x080e   AddAspectRatioInfo                   int32s
+  0x080f   AddOriginalDecisionData              int32s
+  0x0810   LiveViewExposureSimulation           int32s
+
+=head2 Casio Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   RecordingMode                        int16u
+  0x0002   Quality                              int16u
+  0x0003   FocusMode                            int16u
+  0x0004   FlashMode                            int16u
+  0x0005   FlashIntensity                       int16u
+  0x0006   ObjectDistance                       int32u
+  0x0007   WhiteBalance                         int16u
+  0x000a   DigitalZoom                          int32u
+  0x000b   Sharpness                            int16u
+  0x000c   Contrast                             int16u
+  0x000d   Saturation                           int16u
+  0x0014   ISO                                  int16u
+  0x0016   Enhancement                          int16u
+  0x0017   ColorFilter                          int16u
+  0x0018   AFPoint                              int16u
+  0x0019   FlashIntensity                       int16u
+  0x0e00   PrintIM                              PrintIM
+
+=head3 Casio Type2 Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0002   PreviewImageSize                     int16u[2]
+  0x0003   PreviewImageLength                   int32u*
+  0x0004   PreviewImageStart                    int32u*
+  0x0008   QualityMode                          int16u
+  0x0009   CasioImageSize                       int16u
+  0x000d   FocusMode                            int16u
+  0x0014   ISO                                  int16u
+  0x0019   WhiteBalance                         int16u
+  0x001d   FocalLength                          rational64u
+  0x001f   Saturation                           int16u
+  0x0020   Contrast                             int16u
+  0x0021   Sharpness                            int16u
+  0x0e00   PrintIM                              PrintIM
+  0x2000   PreviewImage                         undef
+  0x2001   FirmwareDate                         string[18]
+  0x2011   WhiteBalanceBias                     int16u[2]
+  0x2012   WhiteBalance                         int16u
+  0x2022   ObjectDistance                       int32u
+  0x2034   FlashDistance                        int16u
+  0x3000   RecordMode                           int16u
+  0x3001   SelfTimer                            int16u
+  0x3002   Quality                              int16u
+  0x3003   FocusMode                            int16u
+  0x3006   HometownCity                         string
+  0x3007   BestShotMode                         int16u
+  0x3008   AutoISO                              int16u
+  0x3011   Sharpness                            undef[2]
+  0x3012   Contrast                             undef[2]
+  0x3013   Saturation                           undef[2]
+  0x3014   ISO                                  int16u
+  0x3015   ColorMode                            int16u
+  0x3016   Enhancement                          int16u
+  0x3017   Filter                               int16u
+  0x301c   SequenceNumber                       int16u
+  0x301d   BracketSequence                      int16u[2]
+  0x3020   ImageStabilization                   int16u
+
+=head2 FujiFilm Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   Version                              undef
+  0x0010   InternalSerialNumber                 string
+  0x1000   Quality                              string
+  0x1001   Sharpness                            int16u
+  0x1002   WhiteBalance                         int16u
+  0x1003   Saturation                           int16u
+  0x1004   Contrast                             int16u
+  0x1005   ColorTemperature                     int16u
+  0x1010   FujiFlashMode                        int16u
+  0x1011   FlashStrength                        rational64s
+  0x1020   Macro                                int16u
+  0x1021   FocusMode                            int16u
+  0x1023   FocusPixel                           int16u[2]
+  0x1030   SlowSync                             int16u
+  0x1031   PictureMode                          int16u
+  0x1100   AutoBracketing                       int16u
+  0x1101   SequenceNumber                       int16u
+  0x1210   ColorMode                            int16u
+  0x1300   BlurWarning                          int16u
+  0x1301   FocusWarning                         int16u
+  0x1302   ExposureWarning                      int16u
+  0x1400   DynamicRange                         int16u
+  0x1401   FilmMode                             int16u
+  0x1402   DynamicRangeSetting                  int16u
+  0x1403   DevelopmentDynamicRange              int16u
+  0x1404   MinFocalLength                       rational64s
+  0x1405   MaxFocalLength                       rational64s
+  0x1406   MaxApertureAtMinFocal                rational64s
+  0x1407   MaxApertureAtMaxFocal                rational64s
+  0x8000   FileSource                           string
+  0x8002   OrderNumber                          int32u
+  0x8003   FrameNumber                          int16u
+
+=head3 FujiFilm RAF Tags
+
+Tags extracted from FujiFilm RAF-format information.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0100   RawImageFullSize                     N
+  0x0121   RawImageSize                         N
+  0x0130   FujiLayout                           N
+  0x2ff0   WB_GRGBLevels                        N
+
+=head2 HP Tags
+
+These tables list tags found in the maker notes of some Hewlett-Packard
+camera models.
+
+The first table lists tags found in the EXIF-format maker notes of the
+PhotoSmart 720 (also used by the Vivitar ViviCam 3705, 3705B and 3715).
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0e00   PrintIM                              PrintIM
+
+=head3 HP Type2 Tags
+
+These tags are used by the PhotoSmart E427.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Lens Shading'       LensShading              N
+  'PreviewImage'       PreviewImage             N
+  'Serial Number'      SerialNumber             N
+
+=head3 HP Type4 Tags
+
+These tags are used by the PhotoSmart M627.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+     12    MaxAperture                          N
+     16    ExposureTime                         N
+     20    CameraDateTime                       N
+     52    ISO                                  N
+     92    SerialNumber                         N
+
+=head3 HP Type6 Tags
+
+These tags are used by the PhotoSmart M425, M525 and M527.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+     12    FNumber                              N
+     16    ExposureTime                         N
+     20    CameraDateTime                       N
+     52    ISO                                  N
+     88    SerialNumber                         N
+
+=head2 JVC Tags
+
+JVC EXIF maker note tags.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0002   CPUVersions                          N
+  0x0003   Quality                              N
+
+=head3 JVC Text Tags
+
+JVC/Victor text-based maker note tags.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'QTY'    Quality                              N
+  'VER'    MakerNoteVersion                     N
+
+=head2 Kodak Tags
+
+The Kodak maker notes aren't in standard IFD format, and the format varies
+frequently with different models.  Some information has been decoded, but
+much of the Kodak information remains unknown.
+
+The table below contains the most common set of Kodak tags.  The following
+Kodak camera models have been tested and found to use these tags: C360,
+C663, C875, CX6330, CX6445, CX7330, CX7430, CX7525, CX7530, DC4800, DC4900,
+DX3500, DX3600, DX3900, DX4330, DX4530, DX4900, DX6340, DX6440, DX6490,
+DX7440, DX7590, DX7630, EasyShare-One, LS420, LS443, LS633, LS743, LS753,
+V530, V550, V570, V603, V610, V705, Z650, Z700, Z710, Z730, Z740, Z760 and
+Z7590.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    KodakModel                           string[8]
+      9    Quality                              int8u
+     10    BurstMode                            int8u
+     12    KodakImageWidth                      int16u
+     14    KodakImageHeight                     int16u
+     16    YearCreated                          int16u
+     18    MonthDayCreated                      int8u[2]
+     20    TimeCreated                          int8u[4]
+     24    BurstMode2?                          int16u
+     27    ShutterMode                          int8u
+     28    MeteringMode                         int8u
+     29    SequenceNumber                       int8u
+     30    FNumber                              int16u
+     32    ExposureTime                         int32u
+     36    ExposureCompensation                 int16s
+     38    VariousModes?                        int16u
+     40    Distance1?                           int32u
+     44    Distance2?                           int32u
+     48    Distance3?                           int32u
+     52    Distance4?                           int32u
+     56    FocusMode                            int8u
+     58    VariousModes2?                       int16u
+     60    PanoramaMode?                        int16u
+     62    SubjectDistance?                     int16u
+     64    WhiteBalance                         int8u
+     92    FlashMode                            int8u
+     93    FlashFired                           int8u
+     94    ISOSetting                           int16u
+     96    ISO                                  int16u
+     98    TotalZoom                            int16u
+    100    DateTimeStamp                        int16u
+    102    ColorMode                            int16u
+    104    DigitalZoom                          int16u
+    107    Sharpness                            int8s
+
+=head3 Kodak Type2 Tags
+
+These tags are used by the Kodak DC220, DC260, DC265 and DC290,
+Hewlett-Packard PhotoSmart 618, C500 and C912, Pentax EI-200 and EI-2000,
+and Minolta EX1500Z.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      8    KodakMaker                           string[32]
+     40    KodakModel                           string[32]
+    108    KodakImageWidth                      int32u
+    112    KodakImageHeight                     int32u
+
+=head3 Kodak Type3 Tags
+
+These tags are used by the DC240, DC280, DC3400 and DC5000.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+     12    YearCreated                          int16u
+     14    MonthDayCreated                      int8u[2]
+     16    TimeCreated                          int8u[4]
+     30    OpticalZoom                          int16u
+     55    Sharpness                            int8s
+     56    ExposureTime                         int32u
+     60    FNumber                              int16u
+     78    ISO                                  int16u
+
+=head3 Kodak Type4 Tags
+
+These tags are used by the DC200 and DC215.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+     32    OriginalFileName                     string[12]
+
+=head3 Kodak Type5 Tags
+
+These tags are used by the CX4200, CX4210, CX4230, CX4300, CX4310, CX6200
+and CX6230.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+     20    ExposureTime                         int32u
+     26    WhiteBalance                         int8u
+     28    FNumber                              int16u
+     30    ISO                                  int16u
+     32    OpticalZoom                          int16u
+     34    DigitalZoom                          int16u
+     39    FlashMode                            int8u
+     42    ImageRotated                         int8u
+     43    Macro                                int8u
+
+=head3 Kodak Type6 Tags
+
+These tags are used by the DX3215 and DX3700.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+     16    ExposureTime                         int32u
+     20    ISOSetting?                          int32u
+     24    FNumber                              int16u
+     26    ISO                                  int16u
+     28    OpticalZoom                          int16u
+     30    DigitalZoom                          int16u
+     34    Flash                                int16u
+
+=head3 Kodak Type7 Tags
+
+The maker notes of models such as the C340, C433, CC533, LS755, V803 and
+V1003 seem to start with the camera serial number.  The C310, C315, C330,
+C643, C743, CD33, CD43, CX7220 and CX7300 maker notes are also decoded using
+this table, although the strings for these cameras don't conform to the
+usual Kodak serial number format, and instead have the model name followed
+by 8 digits.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    SerialNumber                         string[16]
+
+=head3 Kodak IFD Tags
+
+Newer Kodak models such as the P712, P850, P880, Z612 and Z712 use standard
+TIFF IFD format for the maker notes.  There is a large amount of information
+stored in these maker notes (with apparently much duplication), but
+relatively few tags have so far been decoded.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0xfc00   SubIFD0                              Kodak SubIFD0
+  0xfc01   SubIFD1                              Kodak SubIFD1
+  0xfc02   SubIFD2                              Kodak SubIFD2
+  0xfc03   SubIFD3                              Kodak SubIFD3
+  0xfc04   SubIFD4                              Kodak SubIFD4
+  0xfc05   SubIFD5                              Kodak SubIFD5
+  0xff00   CameraInfo                           Kodak CameraInfo
+
+=head3 Kodak SubIFD0 Tags
+
+SubIFD0 through SubIFD5 tags are used by the Z612 and Z712.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0xfa02   SceneMode                            int16u
+  0xfa19   SerialNumber                         string
+  0xfa1d   KodakImageWidth                      int16u
+  0xfa1e   KodakImageHeight                     int16u
+  0xfa20   SensorWidth                          int16u
+  0xfa21   SensorHeight                         int16u
+  0xfa23   FNumber                              int16u
+  0xfa24   ExposureTime                         int32u
+  0xfa2e   ISO                                  int16u
+  0xfa3d   OpticalZoom                          int16u
+  0xfa46   ISO                                  int16u
+  0xfa51   KodakImageWidth                      int16u
+  0xfa52   KodakImageHeight                     int16u
+  0xfa54   ThumbnailWidth                       int16u
+  0xfa55   ThumbnailHeight                      int16u
+  0xfa57   PreviewWidth                         int16u
+  0xfa58   PreviewHeight                        int16u
+
+=head3 Kodak SubIFD1 Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0027   ISO                                  int16u
+  0x0028   ISO                                  int16u
+
+=head3 Kodak SubIFD2 Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x6002   SceneModeUsed                        int32u
+  0x6006   OpticalZoom                          int32u
+  0x6103   MaxAperture                          int32u
+  0xf002   SceneModeUsed                        int32u
+  0xf006   OpticalZoom                          int32u
+  0xf103   FNumber                              int32u
+  0xf104   ExposureTime                         int32u
+  0xf105   ISO                                  int32u
+
+=head3 Kodak SubIFD3 Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x1000   OpticalZoom                          int16u
+
+=head3 Kodak SubIFD4 Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head3 Kodak SubIFD5 Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x000f   OpticalZoom                          int16u
+
+=head3 Kodak CameraInfo Tags
+
+These tags are used by the  P712, P850 and P880.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0xf900   SensorWidth                          int16u
+  0xf901   SensorHeight                         int16u
+  0xf902   BayerPattern                         string
+  0xf903   SensorFullWidth                      int16u
+  0xf904   SensorFullHeight                     int16u
+  0xf907   KodakImageWidth                      int16u
+  0xf908   KodakImageHeight                     int16u
+  0xfa00   KodakInfoType                        string
+  0xfa04   SerialNumber                         string
+  0xfd04   FNumber                              int16u
+  0xfd05   ExposureTime                         int32u
+  0xfd06   ISO                                  int16u
+
+=head3 Kodak Unknown Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+  [no tags known]
+
+=head3 Kodak Meta Tags
+
+These tags are found in the APP3 "Meta" segment of JPEG images from Kodak
+cameras such as the DC280, DC3400, DC5000 and MC3.  The structure of this
+segment is similar to the APP1 "Exif" segment, but a different set of tags
+is used.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0xc350   FilmProductCode                      N
+  0xc351   ImageSourceEK                        N
+  0xc352   CaptureConditionsPAR                 N
+  0xc353   CameraOwner                          N
+  0xc354   SerialNumber                         N
+  0xc355   UserSelectGroupTitle                 N
+  0xc356   DealerIDNumber                       N
+  0xc357   CaptureDeviceFID                     N
+  0xc358   EnvelopeNumber                       N
+  0xc359   FrameNumber                          N
+  0xc35a   FilmCategory                         N
+  0xc35b   FilmGencode                          N
+  0xc35c   ModelAndVersion                      N
+  0xc35d   FilmSize                             N
+  0xc35e   SBA_RGBShifts                        N
+  0xc35f   SBAInputImageColorspace              N
+  0xc360   SBAInputImageBitDepth                N
+  0xc361   SBAExposureRecord                    N
+  0xc362   UserAdjSBA_RGBShifts                 N
+  0xc363   ImageRotationStatus                  N
+  0xc364   RollGuidElements                     N
+  0xc365   MetadataNumber                       N
+  0xc366   EditTagArray                         N
+  0xc367   Magnification                        N
+  0xc36c   NativeXResolution                    N
+  0xc36d   NativeYResolution                    N
+  0xc36e   KodakEffectsIFD                      Kodak SpecialEffects
+  0xc36f   KodakBordersIFD                      Kodak Borders
+  0xc37a   NativeResolutionUnit                 N
+  0xc418   SourceImageDirectory                 N
+  0xc419   SourceImageFileName                  N
+  0xc41a   SourceImageVolumeName                N
+  0xc46c   PrintQuality                         N
+  0xc46e   ImagePrintStatus                     N
+
+=head3 Kodak SpecialEffects Tags
+
+The Kodak SpecialEffects and Borders tags are found in sub-IFD's within the
+Kodak JPEG APP3 "Meta" segment.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   DigitalEffectsVersion                N
+  0x0001   DigitalEffectsName                   N
+  0x0002   DigitalEffectsType                   N
+
+=head3 Kodak Borders Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   BordersVersion                       N
+  0x0001   BorderName                           N
+  0x0002   BorderID                             N
+  0x0003   BorderLocation                       N
+  0x0004   BorderType                           N
+  0x0008   WatermarkType                        N
+
+=head2 Leaf Tags
+
+These tags are found in .MOS images from Leaf digital camera backs as
+written by Creo Leaf Capture.  They exist within the Leaf-specific directory
+structure of EXIF tag 0x8606. The tables below list observed Leaf tags,
+however ExifTool will extract any tags found in the Leaf directories even if
+they don't appear in these tables.
+
+  Tag ID                          Tag Name      Writable
+  ------                          --------      --------
+  'JPEG_preview_data'             PreviewImage  undef
+  'JPEG_preview_info'             PreviewInfo   N
+  'PDA_histogram_data'            PDAHistogram  N
+  'back_serial_number'            BackSerial    N
+  'camera_profile'                CameraProfile Leaf CameraProfile
+  'icc_camera_profile'            ICC_Profile   ICC_Profile
+  'icc_camera_to_tone_matrix'     ToneMatrix    N
+  'icc_camera_to_tone_space_flow' ToneSpaceFlow N
+  'icc_rgb_ws_profile'            RGB_Profile   ICC_Profile
+  'image_offset'                  ImageOffset   N
+  'pattern_ratation_angle'        PatternAngle  N
+
+=head3 Leaf CameraProfile Tags
+
+All B<Tag ID>'s in the following table have a leading 'CamProf_' which
+has been removed.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'back_type'          CameraBackType           N
+  'capture_profile'    CaptureProfile           Leaf CaptureProfile
+  'image_profile'      ImageProfile             Leaf ImageProfile
+  'name'               CameraName               N
+  'type'               CameraType               N
+  'version'            CameraProfileVersion     N
+
+=head3 Leaf CaptureProfile Tags
+
+All B<Tag ID>'s in the following table have a leading 'CaptProf_' which
+has been removed.
+
+  Tag ID                 Tag Name               Writable
+  ------                 --------               --------
+  'CCD_rect'             CCDRect                N
+  'CCD_valid_rect'       CCDValidRect           N
+  'CCD_video_rect'       CCDVideoRect           N
+  'back_type'            CaptProfBackType       N
+  'center_dark_rect'     CenterDarkRect         N
+  'color_averages'       ColorAverages          N
+  'color_matrix'         ColorMatrix            N
+  'dark_correction_type' DarkCorrectionType     N
+  'image_bounds'         ImageBounds            N
+  'image_fields'         ImageFields            N
+  'image_offset'         ImageOffset            N
+  'left_dark_rect'       LeftDarkRect           N
+  'luminance_consts'     LuminanceConsts        N
+  'mosaic_pattern'       MosaicPattern          N
+  'name'                 CaptProfName           N
+  'number_of_planes'     NumberOfPlanes         N
+  'raw_data_rotation'    RawDataRotation        N
+  'reconstruction_type'  ReconstructionType     N
+  'right_dark_rect'      RightDarkRect          N
+  'serial_number'        CaptureSerial          N
+  'type'                 CaptProfType           N
+  'version'              CaptProfVersion        N
+  'xy_offset_info'       XYOffsetInfo           N
+
+=head3 Leaf ImageProfile Tags
+
+All B<Tag ID>'s in the following table have a leading 'ImgProf_' which
+has been removed.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'back_type'          ImgProfBackType          N
+  'image_status'       ImageStatus              N
+  'name'               ImgProfName              N
+  'rotation_angle'     RotationAngle            N
+  'shoot_setup'        ShootSetup               Leaf ShootSetup
+  'type'               ImgProfType              N
+  'version'            ImgProfVersion           N
+
+=head3 Leaf ShootSetup Tags
+
+All B<Tag ID>'s in the following table have a leading 'ShootObj_' which
+has been removed.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'back_type'          ShootObjBackType         N
+  'camera_setup'       CameraSetup              Leaf CameraSetup
+  'capture_setup'      CaptureSetup             Leaf CaptureSetup
+  'color_setup'        ColorSetup               Leaf ColorSetup
+  'look_header'        LookHeader               Leaf LookHeader
+  'name'               ShootObjName             N
+  'save_setup'         SaveSetup                Leaf SaveSetup
+  'type'               ShootObjType             N
+  'version'            ShootObjVersion          N
+
+=head3 Leaf CameraSetup Tags
+
+All B<Tag ID>'s in the following table have a leading 'CameraObj_' which
+has been removed.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'ISO_speed'          ISOSpeed                 N
+  'back_type'          CameraObjBackType        N
+  'camera_type'        CameraType               N
+  'lens_ID'            LensID                   N
+  'lens_type'          LensType                 N
+  'name'               CameraObjName            N
+  'strobe'             Strobe                   N
+  'type'               CameraObjType            N
+  'version'            CameraObjVersion         N
+
+=head3 Leaf CaptureSetup Tags
+
+All B<Tag ID>'s in the following table have a leading 'CaptureObj_' which
+has been removed.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Multi_quality'      MultiQuality             N
+  'back_type'          CaptureObjBackType       N
+  'name'               CaptureObjName           N
+  'neutals'            Neutals                  Leaf Neutrals
+  'selection'          Selection                Leaf Selection
+  'sharpness'          Sharpness                Leaf Sharpness
+  'single_quality'     SingleQuality            N
+  'tone_curve'         ToneCurve                Leaf ToneCurve
+  'type'               CaptureObjType           N
+  'version'            CaptureObjVersion        N
+
+=head3 Leaf Neutrals Tags
+
+All B<Tag ID>'s in the following table have a leading 'NeutObj_' which
+has been removed.
+
+  Tag ID                 Tag Name               Writable
+  ------                 --------               --------
+  'back_type'            NeutObjBackType        N
+  'color_casts'          ColorCasts             N
+  'highlight_end_points' HighlightEndPoints     N
+  'name'                 NeutObjName            N
+  'neutrals'             Neutrals               N
+  'shadow_end_points'    ShadowEndPoints        N
+  'type'                 NeutObjType            N
+  'version'              NeutObjVersion         N
+
+=head3 Leaf Selection Tags
+
+All B<Tag ID>'s in the following table have a leading 'SelObj_' which
+has been removed.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'back_type'          SelObjBackType           N
+  'locks'              Locks                    N
+  'name'               SelObjName               N
+  'orientation'        Orientation              N
+  'rect'               Rect                     N
+  'resolution'         Resolution               N
+  'scale'              Scale                    N
+  'type'               SelObjType               N
+  'version'            SelObjVersion            N
+
+=head3 Leaf Sharpness Tags
+
+All B<Tag ID>'s in the following table have a leading 'SharpObj_' which
+has been removed.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'back_type'          SharpObjBackType         N
+  'data_len'           DataLen                  N
+  'name'               SharpObjName             N
+  'sharp_info'         SharpInfo                N
+  'sharp_method'       SharpMethod              N
+  'type'               SharpObjType             N
+  'version'            SharpObjVersion          N
+
+=head3 Leaf ToneCurve Tags
+
+All B<Tag ID>'s in the following table have a leading 'ToneObj_' which
+has been removed.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'back_type'          ToneObjBackType          N
+  'gamma'              Gamma                    N
+  'name'               ToneObjName              N
+  'npts'               Npts                     N
+  'tones'              Tones                    N
+  'type'               ToneObjType              N
+  'version'            ToneObjVersion           N
+
+=head3 Leaf ColorSetup Tags
+
+All B<Tag ID>'s in the following table have a leading 'ColorObj_' which
+has been removed.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'back_type'          ColorObjBackType         N
+  'color_mode'         ColorMode                N
+  'color_type'         ColorType                N
+  'has_ICC'            HasICC                   N
+  'input_profile'      InputProfile             N
+  'name'               ColorObjName             N
+  'output_profile'     OutputProfile            N
+  'type'               ColorObjType             N
+  'version'            ColorObjVersion          N
+
+=head3 Leaf LookHeader Tags
+
+All B<Tag ID>'s in the following table have a leading 'LookHead_' which
+has been removed.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'back_type'          LookHeadBackType         N
+  'name'               LookHeadName             N
+  'type'               LookHeadType             N
+  'version'            LookHeadVersion          N
+
+=head3 Leaf SaveSetup Tags
+
+All B<Tag ID>'s in the following table have a leading 'SaveObj_' which
+has been removed.
+
+  Tag ID                  Tag Name              Writable
+  ------                  --------              --------
+  'back_type'             SaveObjBackType       N
+  'leaf_auto_active'      LeafAutoActive        N
+  'leaf_auto_base_name'   LeafAutoBaseName      N
+  'leaf_hot_folder'       LeafHotFolder         N
+  'leaf_open_proc_HDR'    LeafOpenProcHDR       N
+  'leaf_output_file_type' LeafOutputFileType    N
+  'leaf_save_selection'   LeafSaveSelection     N
+  'name'                  SaveObjName           N
+  'std_auto_active'       StdAutoActive         N
+  'std_base_name'         StdBaseName           N
+  'std_hot_folder'        StdHotFolder          N
+  'std_open_in_photoshop' StdOpenInPhotoshop    N
+  'std_output_bit_depth'  StdOutputBitDepth     N
+  'std_output_color_mode' StdOutputColorMode    N
+  'std_output_file_type'  StdOutputFileType     N
+  'std_oxygen'            StdOxygen             N
+  'std_save_selection'    StdSaveSelection      N
+  'std_scaled_output'     StdScaledOutput       N
+  'std_sharpen_output'    StdSharpenOutput      N
+  'type'                  SaveObjType           N
+  'version'               SaveObjVersion        N
+
+=head3 Leaf SubIFD Tags
+
+Leaf also writes a TIFF-format sub-IFD inside IFD0 of a MOS image.  No tags
+in this sub-IFD are currently known, except for tag 0x8606 which really
+shouldn't be here anyway (so it doesn't appear in the table below) because
+it duplicates a reference to the same data of tag 0x8606 in IFD0.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head2 Minolta Tags
+
+These tags are used by Minolta and Konica/Minolta cameras.  Minolta doesn't
+make things easy for decoders because the meaning of some tags and the
+location where some information is stored is different for different camera
+models.  (Take MinoltaQuality for example, which may be located in 5
+different places.)
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   MakerNoteVersion                     undef[4]
+  0x0001   MinoltaCameraSettingsOld             Minolta CameraSettings
+  0x0003   MinoltaCameraSettings                Minolta CameraSettings
+  0x0004   MinoltaCameraSettings7D              Minolta CameraSettings7D
+  0x0018   ImageStabilization                   N
+  0x0040   CompressedImageSize                  int32u
+  0x0081   PreviewImage                         undef
+  0x0088   PreviewImageStart                    int32u*
+  0x0089   PreviewImageLength                   int32u*
+  0x0100   SceneMode                            Y
+  0x0101   ColorMode                            int32u
+  0x0102   MinoltaQuality                       int32u
+  0x0103   MinoltaQuality                       int32u
+           MinoltaImageSize                     int32u
+  0x0104   FlashExposureComp                    rational64s
+  0x0107   ImageStabilization                   int32u
+  0x010a   ZoneMatching                         int32u
+  0x010b   ColorTemperature                     int32u
+  0x010c   LensID                               int32u
+  0x0113   ImageStabilization                   int32u
+  0x0114   MinoltaCameraSettings5D              Minolta CameraSettings5D
+           MinoltaCameraSettingsA100            Minolta CameraSettingsA100
+  0x0e00   PrintIM                              PrintIM
+  0x0f00   MinoltaCameraSettings2               N
+
+=head3 Minolta CameraSettings Tags
+
+There is some variability in CameraSettings information between different
+models (and sometimes even between different firmware versions), so this
+information may not be as reliable as it should be.  Because of this, tags
+in the following tables are set to lower priority to prevent them from
+superceeding the values of same-named tags in other locations when duplicate
+tags are disabled.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    ExposureMode                         int32u
+      2    FlashMode                            int32u
+      3    WhiteBalance                         int32u~
+      4    MinoltaImageSize                     int32u
+      5    MinoltaQuality                       int32u
+      6    DriveMode                            int32u
+      7    MeteringMode                         int32u
+      8    ISO                                  int32u
+      9    ExposureTime                         int32u
+     10    FNumber                              int32u
+     11    MacroMode                            int32u
+     12    DigitalZoom                          int32u
+     13    ExposureCompensation                 int32u
+     14    BracketStep                          int32u
+     16    IntervalLength                       int32u
+     17    IntervalNumber                       int32u
+     18    FocalLength                          int32u
+     19    FocusDistance                        int32u
+     20    FlashFired                           int32u
+     21    MinoltaDate                          int32u
+     22    MinoltaTime                          int32u
+     23    MaxAperture                          int32u
+     26    FileNumberMemory                     int32u
+     27    LastFileNumber                       int32u
+     28    ColorBalanceRed                      int32u
+     29    ColorBalanceGreen                    int32u
+     30    ColorBalanceBlue                     int32u
+     31    Saturation                           int32u
+     32    Contrast                             int32u
+     33    Sharpness                            int32u
+     34    SubjectProgram                       int32u
+     35    FlashExposureComp                    int32u
+     36    ISOSetting                           int32u
+     37    MinoltaModelID                       int32u
+     38    IntervalMode                         int32u
+     39    FolderName                           int32u
+     40    ColorMode                            int32u
+     41    ColorFilter                          int32u
+     42    BWFilter                             int32u
+     43    InternalFlash                        int32u
+     44    Brightness                           int32u
+     45    SpotFocusPointX                      int32u
+     46    SpotFocusPointY                      int32u
+     47    WideFocusZone                        int32u
+     48    FocusMode                            int32u
+     49    FocusArea                            int32u
+     50    DECPosition                          int32u
+     51    ColorProfile                         int32u
+     52    DataImprint                          int32u
+     63    FlashMetering                        int32u
+
+=head3 Minolta CameraSettings7D Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ExposureMode                         int16u
+      2    MinoltaImageSize                     int16u
+      3    MinoltaQuality                       int16u
+      4    WhiteBalance                         int16u
+     14    FocusMode                            int16u
+     16    AFPoints                             int16u
+     21    Flash                                int16u
+     28    ISOSetting                           int16u
+     30    ExposureCompensation                 int16s
+     37    ColorSpace                           int16u
+     38    Sharpness                            int16u
+     39    Contrast                             int16u
+     40    Saturation                           int16u
+     45    FreeMemoryCardImages                 int16u
+     63    ColorTemperature                     int16s
+     70    Rotation                             int16u
+     71    FNumber                              int16u
+     72    ExposureTime                         int16u
+     74    FreeMemoryCardImages                 int16u
+     94    ImageNumber                          int16u
+     96    NoiseReduction                       int16u
+     98    ImageNumber2                         int16u
+    113    ImageStabilization                   int16u
+    117    ZoneMatchingOn                       int16u
+
+=head3 Minolta CameraSettings5D Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+     10    ExposureMode                         int16u
+     12    MinoltaImageSize                     int16u
+     13    MinoltaQuality                       int16u
+     14    WhiteBalance                         int16u
+     31    Flash                                int16u
+     37    MeteringMode                         int16u
+     38    ISOSetting                           int16u
+     48    Sharpness                            int16u
+     49    Contrast                             int16u
+     50    Saturation                           int16u
+     53    ExposureTime                         int16u
+     54    FNumber                              int16u
+     55    FreeMemoryCardImages                 int16u
+     73    ColorTemperature                     int16s
+     80    Rotation                             int16u
+     83    ExposureCompensation                 int16u
+     84    FreeMemoryCardImages                 int16u
+    110    ColorTemperature                     int16s
+    174    ImageNumber                          int16u
+    176    NoiseReduction                       int16u
+    189    ImageStabilization                   int16u
+
+=head3 Minolta CameraSettingsA100 Tags
+
+Camera settings information for the Sony DSLR-A100.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ExposureMode                         int16u
+      1    ExposureCompensation                 int16u
+     11    WhiteBalance                         int16u
+     22    ColorMode                            int16u
+     24    Sharpness                            int16u
+     25    Contrast                             int16u
+     26    Saturation                           int16u
+     30    DriveMode                            int16u
+     63    NoiseReduction                       int16u
+     90    Rotation                             int16u
+     94    ColorTemperature                     int16u
+    135    ImageStabilization                   int32u[0.5]
+
+=head2 Nikon Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   MakerNoteVersion                     undef[4]
+  0x0002   ISO                                  int16u[2]
+  0x0003   ColorMode                            string
+  0x0004   Quality                              string
+  0x0005   WhiteBalance                         string
+  0x0006   Sharpness                            string
+  0x0007   FocusMode                            string
+  0x0008   FlashSetting                         string
+  0x0009   FlashType                            string[13]
+  0x000b   WhiteBalanceFineTune                 int16s
+  0x000c   ColorBalance1                        rational64u[4]
+  0x000d   ProgramShift                         undef[4]
+  0x000e   ExposureDifference                   undef[4]
+  0x000f   ISOSelection                         string
+  0x0010   DataDump                             N
+  0x0011   NikonPreview                         Nikon PreviewImage
+  0x0012   FlashExposureComp                    undef[4]
+  0x0013   ISOSetting                           int16u[2]
+  0x0016   ImageBoundary                        int16u[4]
+  0x0018   FlashExposureBracketValue            undef[4]
+  0x0019   ExposureBracketValue                 rational64s
+  0x001a   ImageProcessing                      string
+  0x001b   CropHiSpeed                          int16u[7]~
+  0x001d   SerialNumber                         N
+  0x001e   ColorSpace                           int16u
+  0x0020   ImageAuthentication                  int8u
+  0x0080   ImageAdjustment                      string
+  0x0081   ToneComp                             string
+  0x0082   AuxiliaryLens                        string
+  0x0083   LensType                             int8u
+  0x0084   Lens                                 rational64u[4]
+  0x0085   ManualFocusDistance                  rational64u
+  0x0086   DigitalZoom                          rational64u
+  0x0087   FlashMode                            int8u
+  0x0088   AFInfo                               Nikon AFInfo
+  0x0089   ShootingMode                         int16u~
+  0x008a   AutoBracketRelease                   int16u
+  0x008b   LensFStops                           undef[4]
+  0x008c   NEFCurve1                            N
+  0x008d   ColorHue                             string
+  0x008f   SceneMode                            string
+  0x0090   LightSource                          string
+  0x0091   ShotInfo                             Nikon ShotInfo
+           ShotInfo?                            Nikon ShotInfo
+  0x0092   HueAdjustment                        int16s
+  0x0094   Saturation                           int16s
+  0x0095   NoiseReduction                       string
+  0x0096   NEFCurve2                            N
+  0x0097   ColorBalance0100                     Nikon ColorBalance1
+           ColorBalance0102                     Nikon ColorBalance2
+           ColorBalance0103                     Nikon ColorBalance3
+           ColorBalance0205                     Nikon ColorBalance2
+           ColorBalance02                       Nikon ColorBalance2
+           ColorBalanceUnknown                  N
+  0x0098   LensData0100                         Nikon LensData00
+           LensData0101                         Nikon LensData01
+           LensData0201                         Nikon LensData01
+           LensDataUnknown                      N
+  0x0099   RawImageCenter                       int16u[2]
+  0x009a   SensorPixelSize                      rational64u[2]
+  0x00a0   SerialNumber                         string
+  0x00a2   ImageDataSize                        int32u
+  0x00a5   ImageCount                           int32u
+  0x00a6   DeletedImageCount                    int32u
+  0x00a7   ShutterCount                         N
+  0x00a9   ImageOptimization                    string[16]
+  0x00aa   Saturation                           string
+  0x00ab   VariProgram                          string
+  0x00ac   ImageStabilization                   string
+  0x00ad   AFResponse                           string
+  0x00b0   MultiExposure                        Nikon MultiExposure
+  0x00b1   HighISONoiseReduction                int16u
+  0x0e00   PrintIM                              PrintIM
+  0x0e01   NikonCaptureData                     NikonCapture
+  0x0e09   NikonCaptureVersion                  string
+  0x0e0e   NikonCaptureOffsets                  Nikon CaptureOffsets
+  0x0e10   NikonScanIFD                         Nikon Scan
+
+=head3 Nikon PreviewImage Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0103   Compression                          N
+  0x011a   XResolution                          N
+  0x011b   YResolution                          N
+  0x0128   ResolutionUnit                       N
+  0x0201   PreviewImageStart                    int32u*
+  0x0202   PreviewImageLength                   int32u*
+  0x0213   YCbCrPositioning                     N
+
+=head3 Nikon AFInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    AFAreaMode                           int8u
+      1    AFPoint                              int8u
+      2    AFPointsInFocus                      int16u
+
+=head3 Nikon ShotInfo Tags
+
+This information is encrypted for ShotInfoVersion 02xx, and some tags are
+only valid for specific versions.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ShotInfoVersion                      N
+    102    VR_0x66?                             N
+    106    ShutterCount                         N
+    110    DeletedImageCount                    N
+    117    VibrationReduction                   N
+    130    VibrationReduction                   N
+    343    ShutterCount                         N
+    430    VibrationReduction                   N
+    586    ShutterCount                         N
+    590    VibrationReduction                   N
+
+=head3 Nikon ColorBalance1 Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    WB_RBGGLevels                        int16u[4]!
+
+=head3 Nikon ColorBalance2 Tags
+
+This information is encrypted for most camera models, and if encrypted is
+not currently writable by exiftool.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    WB_RGGBLevels                        int16u[4]!
+
+=head3 Nikon ColorBalance3 Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    WB_RGBGLevels                        int16u[4]!
+
+=head3 Nikon LensData00 Tags
+
+This structure is used by the D100, and D1X with firmware version 1.1.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    LensDataVersion                      undef[4]
+      6    LensIDNumber                         int8u
+      7    LensFStops                           int8u
+      8    MinFocalLength                       int8u
+      9    MaxFocalLength                       int8u
+     10    MaxApertureAtMinFocal                int8u
+     11    MaxApertureAtMaxFocal                int8u
+     12    MCUVersion                           int8u
+
+=head3 Nikon LensData01 Tags
+
+Nikon encrypts the LensData information below if LensDataVersion is 0201 or
+higher, but  the decryption algorithm is known so the information can be
+extracted.  It isn't yet writable, however, because the encryption adds
+complications which make writing more difficult.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    LensDataVersion                      N
+      4    ExitPupilPosition                    N
+      5    AFAperture                           N
+      8    FocusPosition                        N
+      9    FocusDistance                        N
+     10    FocalLength                          N
+     11    LensIDNumber                         N
+     12    LensFStops                           N
+     13    MinFocalLength                       N
+     14    MaxFocalLength                       N
+     15    MaxApertureAtMinFocal                N
+     16    MaxApertureAtMaxFocal                N
+     17    MCUVersion                           N
+     18    EffectiveMaxAperture                 N
+
+=head3 Nikon MultiExposure Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    MultiExposureVersion                 string[4]
+      1    MultiExposureMode                    int32u
+      2    MultiExposureShots                   int32u
+      3    MultiExposureAutoGain                int32u
+
+=head3 Nikon CaptureOffsets Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   IFD0_Offset                          N
+  0x0002   PreviewIFD_Offset                    N
+  0x0003   SubIFD_Offset                        N
+
+=head3 Nikon Scan Tags
+
+This information is written by the Nikon Scan software.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0002   FilmType                             string
+  0x0040   MultiSample                          string
+  0x0041   BitDepth                             int16u
+  0x0050   MasterGain                           rational64s
+  0x0051   ColorGain                            rational64s[3]
+  0x0100   DigitalICE                           string
+  0x0110   ROCInfo                              Nikon ROC
+  0x0120   GEMInfo                              Nikon GEM
+
+=head3 Nikon ROC Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    DigitalROC                           int32u
+
+=head3 Nikon GEM Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    DigitalGEM                           int32u
+
+=head3 Nikon Type2 Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0003   Quality                              Y
+  0x0004   ColorMode                            Y
+  0x0005   ImageAdjustment                      Y
+  0x0006   CCDSensitivity                       Y
+  0x0007   WhiteBalance                         Y
+  0x0008   Focus                                Y
+  0x000a   DigitalZoom                          Y
+  0x000b   Converter                            Y
+
+=head3 Nikon MOV Tags
+
+This information is found in Nikon QT video images, and is very similar to
+information found in Pentax MOV videos.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    Make                                 N
+     24    Model                                N
+     38    ExposureTime                         N
+     42    FNumber                              N
+     50    ExposureCompensation                 N
+     68    WhiteBalance                         N
+     72    FocalLength                          N
+    175    Software                             N
+    223    ISO                                  N
+
+=head2 NikonCapture Tags
+
+This information is written by the Nikon Capture software in tag 0x0e01 of
+the maker notes of NEF images.
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  0x8ae85e     LCHEditor                        int8u
+  0xc89224b    ColorAberrationControl           int8u
+  0x2175eb78   D-LightingHQ                     int8u
+  0x2fc08431   StraightenAngle                  double
+  0x374233e0   CropData                         NikonCapture CropData
+  0x3cfc73c6   RedEyeData                       NikonCapture RedEyeData
+  0x5f0e7d23   ColorBooster                     int8u
+  0x6a6e36b6   D-LightingHQSelected             int8u
+  0x753dcbc0   NoiseReduction                   int8u
+  0x76a43200   UnsharpMask                      int8u
+  0x76a43201   Curves                           int8u
+  0x76a43202   ColorBalanceAdj                  int8u
+  0x76a43203   AdvancedRaw                      int8u
+  0x76a43204   WhiteBalanceAdj                  int8u
+  0x76a43205   VignetteControl                  int8u
+  0x76a43206   FlipHorizontal                   int8u
+  0x76a43207   Rotation                         int16u
+  0x84589434   BrightnessData                   NikonCapture Brightness
+  0x890ff591   D-LightingHQData                 NikonCapture DLightingHQ
+  0x926f13e0   NoiseReductionData               NikonCapture NoiseReduction
+  0x9ef5f6e0   IPTCData                         IPTC
+  0xab5eca5e   PhotoEffects                     int8u
+  0xac6bd5c0   VignetteControlIntensity         int16s
+  0xb0384e1e   PhotoEffectsData                 NikonCapture PhotoEffects
+  0xb999a36f   ColorBoostData                   NikonCapture ColorBoost
+  0xbf3c6c20   WBAdjData                        NikonCapture WBAdjData
+  0xce5554aa   D-LightingHS                     int8u
+  0xe37b4337   D-LightingHSData                 NikonCapture DLightingHS
+  0xe42b5161   UnsharpData                      NikonCapture UnsharpData
+  0xfe443a45   ImageDustOff                     int8u
+
+=head3 NikonCapture CropData Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+     30    CropLeft                             double
+     38    CropTop                              double
+     46    CropRight                            double
+     54    CropBottom                           double
+    142    OutputWidthInches                    double
+    150    OutputHeightInches                   double
+    158    ScaledResolution                     double
+    174    SourceResolution                     double
+    182    OutputResolution                     double
+    190    CropOutputScale                      double
+    198    OutputWidth                          double
+    206    OutputHeight                         double
+    214    OutputPixels                         double
+
+=head3 NikonCapture RedEyeData Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    RedEyeCorrection                     int8u
+
+=head3 NikonCapture Brightness Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    BrightnessAdj                        double
+      8    EnhanceDarkTones                     int8u
+
+=head3 NikonCapture DLightingHQ Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    D-LightingHSShadow                   int32u
+      1    D-LightingHSHighlight                int32u
+      2    D-LightingHSColorBoost               int32u
+
+=head3 NikonCapture NoiseReduction Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      4    EdgeNoiseReduction                   int8u
+      5    ColorMoireReduction                  int8u
+      9    NoiseReductionIntensity              int32u
+     13    NoiseReductionSharpness              int32u
+     17    NoiseReductionMethod                 int16u
+
+=head3 NikonCapture PhotoEffects Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    PhotoEffectsType                     int8u
+      4    PhotoEffectsRed                      int16s
+      6    PhotoEffectsGreen                    int16s
+      8    PhotoEffectsBlue                     int16s
+
+=head3 NikonCapture ColorBoost Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ColorBoostType                       int8u
+      1    ColorBoostLevel                      int32u
+
+=head3 NikonCapture WBAdjData Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    WBAdjRedBalance                      double
+      8    WBAdjBlueBalance                     double
+     16    WBAdjMode                            int8u
+     21    WBAdjLighting                        int8u
+     24    WBAdjTemperature                     int16u
+
+=head3 NikonCapture DLightingHS Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    D-LightingHSAdjustment               int32u
+      1    D-LightingHSColorBoost               int32u
+
+=head3 NikonCapture UnsharpData Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    UnsharpCount                         int8u
+     19    Unsharp1Color                        int16u
+     23    Unsharp1Intensity                    int16u
+     25    Unsharp1HaloWidth                    int16u
+     27    Unsharp1Threshold                    int8u
+     46    Unsharp2Color                        int16u
+     50    Unsharp2Intensity                    int16u
+     52    Unsharp2HaloWidth                    int16u
+     54    Unsharp2Threshold                    int8u
+     73    Unsharp3Color                        int16u
+     77    Unsharp3Intensity                    int16u
+     79    Unsharp3HaloWidth                    int16u
+     81    Unsharp3Threshold                    int8u
+    100    Unsharp4Color                        int16u
+    104    Unsharp4Intensity                    int16u
+    106    Unsharp4HaloWidth                    int16u
+    108    Unsharp4Threshold                    int8u
+
+=head2 Olympus Tags
+
+Tags 0x0000 through 0x0103 are used by some older Olympus cameras, and are
+the same as Konica/Minolta tags.  The Olympus tags are also used for Epson
+and Agfa cameras.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   MakerNoteVersion                     undef
+  0x0001   MinoltaCameraSettingsOld             Minolta CameraSettings
+  0x0003   MinoltaCameraSettings                Minolta CameraSettings
+  0x0040   CompressedImageSize                  int32u
+  0x0081   PreviewImageData                     N
+  0x0088   PreviewImageStart                    N
+  0x0089   PreviewImageLength                   N
+  0x0100   ThumbnailImage                       undef
+  0x0101   ColorMode                            int16u
+  0x0102   MinoltaQuality                       int16u
+  0x0103   MinoltaQuality                       int16u
+  0x0104   BodyFirmwareVersion                  string
+  0x0200   SpecialMode                          int32u[3]~
+  0x0201   Quality                              int16u~
+  0x0202   Macro                                int16u
+  0x0203   BWMode                               int16u
+  0x0204   DigitalZoom                          rational64u
+  0x0205   FocalPlaneDiagonal                   rational64u
+  0x0206   LensDistortionParams                 int16s[6]
+  0x0207   CameraType                           string
+  0x0208   TextInfo                             Olympus TextInfo
+  0x0209   CameraID                             string
+  0x020b   EpsonImageWidth                      int16u
+  0x020c   EpsonImageHeight                     int16u
+  0x020d   EpsonSoftware                        string
+  0x0280   PreviewImage                         int8u
+  0x0300   PreCaptureFrames                     int16u
+  0x0301   WhiteBoard                           int16u
+  0x0302   OneTouchWB                           int16u
+  0x0303   WhiteBalanceBracket                  int16u
+  0x0304   WhiteBalanceBias                     int16u
+  0x0403   SceneMode                            int16u
+  0x0404   SerialNumber                         string
+  0x0405   Firmware                             string
+  0x0e00   PrintIM                              PrintIM
+  0x0f00   DataDump                             N
+  0x0f01   DataDump2                            N
+  0x1000   ShutterSpeedValue                    rational64s
+  0x1001   ISOValue                             rational64s
+  0x1002   ApertureValue                        rational64s
+  0x1003   BrightnessValue                      rational64s
+  0x1004   FlashMode                            int16u
+  0x1005   FlashDevice                          int16u
+  0x1006   ExposureCompensation                 rational64s
+  0x1007   SensorTemperature                    int16s
+  0x1008   LensTemperature                      int16s
+  0x1009   LightCondition                       int16u
+  0x100a   FocusRange                           int16u
+  0x100b   FocusMode                            int16u
+  0x100c   ManualFocusDistance                  rational64u
+  0x100d   ZoomStepCount                        int16u
+  0x100e   FocusStepCount                       int16u
+  0x100f   Sharpness                            int16u
+  0x1010   FlashChargeLevel                     int16u
+  0x1011   ColorMatrix                          int16u[9]
+  0x1012   BlackLevel                           int16u[4]
+  0x1013   ColorTemperatureBG?                  int16u
+  0x1014   ColorTemperatureRG?                  int16u
+  0x1015   WBMode                               int16u[2]
+  0x1017   RedBalance                           int16u[2]
+  0x1018   BlueBalance                          int16u[2]
+  0x1019   ColorMatrixNumber                    int16u
+  0x101a   SerialNumber                         string
+  0x101b   ExternalFlashAE1_0?                  int32u
+  0x101c   ExternalFlashAE2_0?                  int32u
+  0x101d   InternalFlashAE1_0?                  int32u
+  0x101e   InternalFlashAE2_0?                  int32u
+  0x101f   ExternalFlashAE1?                    int32u
+  0x1020   ExternalFlashAE2?                    int32u
+  0x1021   InternalFlashAE1?                    int32u
+  0x1022   InternalFlashAE2?                    int32u
+  0x1023   FlashExposureComp                    rational64s
+  0x1024   InternalFlashTable                   int16u
+  0x1025   ExternalFlashGValue                  rational64s
+  0x1026   ExternalFlashBounce                  int16u
+  0x1027   ExternalFlashZoom                    int16u
+  0x1028   ExternalFlashMode                    int16u
+  0x1029   Contrast                             int16u
+  0x102a   SharpnessFactor                      int16u
+  0x102b   ColorControl                         int16u[6]
+  0x102c   ValidBits                            int16u[2]
+  0x102d   CoringFilter                         int16u
+  0x102e   OlympusImageWidth                    int32u
+  0x102f   OlympusImageHeight                   int32u
+  0x1030   SceneDetect                          int16u
+  0x1031   SceneArea?                           int32u[8]
+  0x1033   SceneDetectArea?                     int32u[720]
+  0x1034   CompressionRatio                     rational64u
+  0x1035   PreviewImageValid                    int32u
+  0x1036   PreviewImageStart                    int32u*
+  0x1037   PreviewImageLength                   int32u*
+  0x1038   AFResult                             int16u
+  0x1039   CCDScanMode                          int16u
+  0x103a   NoiseReduction                       int16u
+  0x103b   InfinityLensStep                     int16u
+  0x103c   NearLensStep                         int16u
+  0x103d   LightValueCenter                     rational64s
+  0x103e   LightValuePeriphery                  rational64s
+  0x103f   FieldCount?                          int16u
+  0x2010   Equipment                            Olympus Equipment
+           Equipment2                           Olympus Equipment
+  0x2020   CameraSettings                       Olympus CameraSettings
+           CameraSettings2                      Olympus CameraSettings
+  0x2030   RawDevelopment                       Olympus RawDevelopment
+           RawDevelopment2                      Olympus RawDevelopment
+  0x2031   RawDev2                              Olympus RawDevelopment2
+           RawDev2_2                            Olympus RawDevelopment2
+  0x2040   ImageProcessing                      Olympus ImageProcessing
+           ImageProcessing2                     Olympus ImageProcessing
+  0x2050   FocusInfo                            Olympus FocusInfo
+           FocusInfo2                           Olympus FocusInfo
+           CameraParameters                     undef
+  0x2100   Olympus2100                          Olympus FE
+  0x2200   Olympus2200                          Olympus FE
+  0x2300   Olympus2300                          Olympus FE
+  0x2400   Olympus2400                          Olympus FE
+  0x2500   Olympus2500                          Olympus FE
+  0x2600   Olympus2600                          Olympus FE
+  0x2700   Olympus2700                          Olympus FE
+  0x2800   Olympus2800                          Olympus FE
+  0x2900   Olympus2900                          Olympus FE
+  0x3000   RawInfo                              Olympus RawInfo
+           RawInfo2                             Olympus RawInfo
+
+=head3 Olympus TextInfo Tags
+
+This information is in text format (similar to APP12 information, but with
+spaces instead of linefeeds).  Below are tags which have been observed, but
+any information found here will be extracted, even if the tag is not listed.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Resolution'         Resolution               N
+  'Type'               CameraType               N
+
+=head3 Olympus Equipment Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   EquipmentVersion                     undef[4]
+  0x0100   CameraType2                          string[6]
+  0x0101   SerialNumber                         string[32]
+  0x0102   InternalSerialNumber                 string[32]
+  0x0103   FocalPlaneDiagonal                   rational64u
+  0x0104   BodyFirmwareVersion                  int32u
+  0x0201   LensType                             int8u[6]~
+  0x0202   LensSerialNumber                     string[32]
+  0x0204   LensFirmwareVersion                  int32u
+  0x0205   MaxApertureAtMinFocal                int16u
+  0x0206   MaxApertureAtMaxFocal                int16u
+  0x0207   MinFocalLength                       int16u
+  0x0208   MaxFocalLength                       int16u
+  0x020a   MaxApertureAtCurrentFocal            int16u
+  0x020b   LensProperties                       int16u
+  0x0301   Extender                             int8u[6]~
+  0x0302   ExtenderSerialNumber                 string[32]
+  0x0303   ExtenderModel                        string
+  0x0304   ExtenderFirmwareVersion              int32u
+  0x1000   FlashType                            int16u
+  0x1001   FlashModel                           int16u
+  0x1002   FlashFirmwareVersion                 int32u
+  0x1003   FlashSerialNumber                    string[32]
+
+=head3 Olympus CameraSettings Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   CameraSettingsVersion                undef[4]
+  0x0100   PreviewImageValid                    int32u
+  0x0101   PreviewImageStart                    int32u*
+  0x0102   PreviewImageLength                   int32u*
+  0x0200   ExposureMode                         int16u
+  0x0201   AELock                               int16u
+  0x0202   MeteringMode                         int16u
+  0x0300   MacroMode                            int16u
+  0x0301   FocusMode                            int16u
+  0x0302   FocusProcess                         int16u
+  0x0303   AFSearch                             int16u
+  0x0304   AFAreas                              int32u[64]~
+  0x0400   FlashMode                            int16u
+  0x0401   FlashExposureCompensation            rational64s
+  0x0500   WhiteBalance2                        int16u
+  0x0501   WhiteBalanceTemperature              int16u
+  0x0502   WhiteBalanceBracket                  int16s
+  0x0503   CustomSaturation                     int16s[3]~
+  0x0504   ModifiedSaturation                   int16u
+  0x0505   ContrastSetting                      int16s[3]
+  0x0506   SharpnessSetting                     int16s[3]
+  0x0507   ColorSpace                           int16u
+  0x0509   SceneMode                            int16u
+  0x050a   NoiseReduction                       int16u
+  0x050b   DistortionCorrection                 int16u
+  0x050c   ShadingCompensation                  int16u
+  0x050d   CompressionFactor                    rational64u
+  0x050f   Gradation                            int16s[3]
+  0x0520   PictureMode                          int16u
+  0x0521   PictureModeSaturation                int16s[3]
+  0x0522   PictureModeHue?                      int16s
+  0x0523   PictureModeContrast                  int16s[3]
+  0x0524   PictureModeSharpness                 int16s[3]
+  0x0525   PictureModeBWFilter                  int16s
+  0x0526   PictureModeTone                      int16s
+  0x0527   NoiseFilter                          int16s[3]
+  0x0600   DriveMode                            int16u[n]~
+  0x0601   PanoramaMode                         int16u~
+  0x0603   ImageQuality2                        int16u
+  0x0901   ManometerReading                     int32s[2]
+
+=head3 Olympus RawDevelopment Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   RawDevVersion                        undef[4]
+  0x0100   RawDevExposureBiasValue              rational64s
+  0x0101   RawDevWhiteBalanceValue              int16u
+  0x0102   RawDevWBFineAdjustment               int16s
+  0x0103   RawDevGrayPoint                      int16u[3]
+  0x0104   RawDevSaturationEmphasis             int16s[3]
+  0x0105   RawDevMemoryColorEmphasis            int16u
+  0x0106   RawDevContrastValue                  int16s[3]
+  0x0107   RawDevSharpnessValue                 int16s[3]
+  0x0108   RawDevColorSpace                     int16u
+  0x0109   RawDevEngine                         int16u
+  0x010a   RawDevNoiseReduction                 int16u
+  0x010b   RawDevEditStatus                     int16u
+  0x010c   RawDevSettings                       int16u
+
+=head3 Olympus RawDevelopment2 Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   RawDevVersion                        undef[4]
+  0x0100   RawDevExposureBiasValue              rational64s
+  0x0101   RawDevWhiteBalance                   int16u
+  0x0102   RawDevWhiteBalanceValue              int16u
+  0x0103   RawDevWBFineAdjustment               int16s
+  0x0104   RawDevGrayPoint                      int16u[3]
+  0x0105   RawDevContrastValue                  int16s[3]
+  0x0106   RawDevSharpnessValue                 int16s[3]
+  0x0107   RawDevSaturationEmphasis             int16s[3]
+  0x0108   RawDevMemoryColorEmphasis            int16u
+  0x0109   RawDevColorSpace                     int16u
+  0x010a   RawDevNoiseReduction                 int16u
+  0x010b   RawDevEngine                         int16u
+  0x010c   RawDevPictureMode                    int16u
+  0x010d   RawDevPMSaturation                   int16s[3]
+  0x010e   RawDevPMContrast                     int16s[3]
+  0x010f   RawDevPMSharpness                    int16s[3]
+  0x0110   RawDevPM_BWFilter                    int16u
+  0x0111   RawDevPMPictureTone                  int16u
+  0x0112   RawDevGradation                      int16s[3]
+
+=head3 Olympus ImageProcessing Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   ImageProcessingVersion               undef[4]
+  0x0100   WB_RBLevels                          int16u[2]
+  0x0200   ColorMatrix                          int16u[9]
+  0x0300   SmoothingParameter1                  int16u
+  0x0310   SmoothingParameter2                  int16u
+  0x0600   SmoothingThresholds                  int16u[4]
+  0x0610   SmoothingThreshold2                  int16u
+  0x0611   ValidBits                            int16u[2]
+  0x0614   OlympusImageWidth2                   int32u
+  0x0615   OlympusImageHeight2                  int32u
+  0x1010   NoiseReduction2                      int16u
+  0x1011   DistortionCorrection2                int16u
+  0x1012   ShadingCompensation2                 int16u
+  0x1103   UnknownBlock?                        undef
+
+=head3 Olympus FocusInfo Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   FocusInfoVersion                     undef[4]
+  0x0209   AutoFocus?                           int16u
+  0x0300   ZoomStepCount                        int16u
+  0x0301   FocusStepCount                       int16u
+  0x0305   FocusDistance                        rational64u
+  0x0308   AFPoint                              int16u
+  0x1201   ExternalFlash                        int16u[2]
+  0x1203   ExternalFlashGuideNumber?            rational64s
+  0x1204   ExternalFlashBounce                  int16u
+  0x1205   ExternalFlashZoom                    rational64u
+  0x1208   InternalFlash                        int16u[n]
+  0x1209   ManualFlash                          int16u[2]~
+  0x1500   SensorTemperature                    int16s
+  0x1600   ImageStabilization                   undef~
+
+=head3 Olympus FE Tags
+
+Some FE models write a large number of tags here, but most of this
+information remains unknown.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0100   BodyFirmwareVersion                  string
+
+=head3 Olympus RawInfo Tags
+
+These tags are found only in ORF images of some models (ie. C8080WZ).
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   RawInfoVersion                       undef[4]
+  0x0100   WB_RBLevelsUsed                      int16[2]
+  0x0110   WB_RBLevelsAuto                      int16[2]
+  0x0120   WB_RBLevelsShade                     int16[2]
+  0x0121   WB_RBLevelsCloudy                    int16[2]
+  0x0122   WB_RBLevelsFineWeather               int16[2]
+  0x0123   WB_RBLevelsTungsten                  int16[2]
+  0x0124   WB_RBLevelsEveningSunlight           int16[2]
+  0x0130   WB_RBLevelsDaylightFluor             int16[2]
+  0x0131   WB_RBLevelsDayWhiteFluor             int16[2]
+  0x0132   WB_RBLevelsCoolWhiteFluor            int16[2]
+  0x0133   WB_RBLevelsWhiteFluorescent          int16[2]
+  0x0200   ColorMatrix2                         int16u[9]
+  0x0310   CoringFilter                         int16u
+  0x0311   CoringValues                         int16u[11]
+  0x0600   BlackLevel2                          int16u[4]
+  0x0601   YCbCrCoefficients                    N
+  0x0611   ValidPixelDepth                      int16u[2]
+  0x0612   StartOffsetX                         int16u
+  0x0613   StartOffsetY                         int16u
+  0x0614   FinalImageWidth                      int32u
+  0x0615   FinalImageHeight                     int32u
+  0x1000   LightSource                          int16u
+  0x1001   WhiteBalanceComp                     int16s[3]
+  0x1010   SaturationSetting                    int16s[3]
+  0x1011   HueSetting                           int16s[3]
+  0x1012   ContrastSetting                      int16s[3]
+  0x1013   SharpnessSetting                     int16s[3]
+  0x2000   CMExposureCompensation               rational64s
+  0x2001   CMWhiteBalance                       int16u
+  0x2002   CMWhiteBalanceComp                   int16s
+  0x2010   CMWhiteBalanceGrayPoint              int16u[3]
+  0x2020   CMSaturation                         int16s[3]
+  0x2021   CMHue                                int16s[3]
+  0x2022   CMContrast                           int16s[3]
+  0x2023   CMSharpness                          int16s[3]
+
+=head2 Panasonic Tags
+
+Panasonic tags are also used for Leica cameras.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   ImageQuality                         int16u
+  0x0002   FirmwareVersion                      undef
+  0x0003   WhiteBalance                         int16u
+  0x0007   FocusMode                            int16u
+  0x000f   AFMode                               int8u[2]
+  0x001a   ImageStabilization                   int16u
+  0x001c   MacroMode                            int16u
+  0x001f   ShootingMode                         int16u
+  0x0020   Audio                                int16u
+  0x0021   DataDump                             N
+  0x0023   WhiteBalanceBias                     int16s
+  0x0024   FlashBias                            int16s
+  0x0025   InternalSerialNumber                 undef[16]
+  0x0026   PanasonicExifVersion                 undef
+  0x0028   ColorEffect                          int16u
+  0x0029   TimeSincePowerOn                     int32u
+  0x002a   BurstMode                            int16u
+  0x002b   SequenceNumber                       int32u
+  0x002c   Contrast                             int16u
+  0x002d   NoiseReduction                       int16u
+  0x002e   SelfTimer                            int16u
+  0x0030   Rotation                             int16u
+  0x0032   ColorMode                            int16u
+  0x0033   BabyAge                              string
+  0x0034   OpticalZoomMode                      int16u
+  0x0035   ConversionLens                       int16u
+  0x0036   TravelDay                            int16u
+  0x003a   WorldTimeLocation                    int16u
+  0x003c   ProgramISO                           int16u
+  0x0042   FilmMode                             int16u
+  0x0046   WBAdjustAB                           int16u
+  0x0047   WBAdjustGM                           int16u
+  0x0051   LensType                             string
+  0x0052   LensSerialNumber                     string
+  0x0053   AccessoryType                        string
+  0x0e00   PrintIM                              PrintIM
+  0x8000   MakerNoteVersion                     undef
+  0x8001   SceneMode                            int16u
+  0x8004   WBRedLevel                           int16u
+  0x8005   WBGreenLevel                         int16u
+  0x8006   WBBlueLevel                          int16u
+  0x8010   BabyAge                              string
+
+=head3 Panasonic Type2 Tags
+
+This type of maker notes is used by models such as the NV-DS65, PV-D2002,
+PV-DC3000, PV-DV203, PV-DV401, PV-DV702, PV-L2001, PV-SD4090, PV-SD5000 and
+iPalm.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    MakerNoteType                        N
+      3    Gain                                 N
+
+=head3 Panasonic Raw Tags
+
+These tags are found in IFD0 of Panasonic RAW images.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   PanasonicRawVersion                  undef
+  0x0002   SensorWidth                          N
+  0x0003   SensorHeight                         N
+  0x0004   SensorTopBorder                      N
+  0x0005   SensorLeftBorder                     N
+  0x0006   ImageHeight                          N
+  0x0007   ImageWidth                           N
+  0x0011   RedBalance                           int16u
+  0x0012   BlueBalance                          int16u
+  0x0017   ISO                                  int16u
+  0x0024   WBRedLevel                           int16u
+  0x0025   WBGreenLevel                         int16u
+  0x0026   WBBlueLevel                          int16u
+  0x010f   Make                                 string
+  0x0110   Model                                string
+  0x0111   StripOffsets                         N
+  0x0112   Orientation                          int16u
+  0x0116   RowsPerStrip                         N
+  0x0117   StripByteCounts                      N
+  0x8769   ExifOffset                           EXIF
+  0x8825   GPSInfo                              GPS
+
+=head2 Pentax Tags
+
+The Pentax tags are also used in Asahi cameras.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   PentaxVersion                        int8u[4]
+  0x0001   PentaxModelType                      int16u
+  0x0002   PreviewImageSize                     int16u[2]~
+  0x0003   PreviewImageLength                   int32u*
+  0x0004   PreviewImageStart                    int32u*
+  0x0005   PentaxModelID                        int32u
+  0x0006   Date                                 undef[4]
+  0x0007   Time                                 undef[3]
+  0x0008   Quality                              int16u
+  0x0009   PentaxImageSize                      int16u
+  0x000b   PictureMode                          int16u
+  0x000c   FlashMode                            N
+  0x000d   FocusMode                            int16u
+  0x000e   AFPointSelected                      int16u
+  0x000f   AFPointsInFocus                      int16u
+  0x0010   FocusPosition                        int16u
+  0x0012   ExposureTime                         int32u
+  0x0013   FNumber                              int16u
+  0x0014   ISO                                  int16u
+  0x0016   ExposureCompensation                 int16u
+  0x0017   MeteringMode                         int16u
+  0x0018   AutoBracketing                       int16u[n]
+  0x0019   WhiteBalance                         int16u
+  0x001a   WhiteBalanceMode                     int16u
+  0x001b   BlueBalance                          int16u
+  0x001c   RedBalance                           int16u
+  0x001d   FocalLength                          int32u
+  0x001e   DigitalZoom                          int16u
+  0x001f   Saturation                           int16u
+  0x0020   Contrast                             int16u
+  0x0021   Sharpness                            int16u
+  0x0022   WorldTimeLocation                    int16u
+  0x0023   HometownCity                         int16u
+  0x0024   DestinationCity                      int16u
+  0x0025   HometownDST                          int16u
+  0x0026   DestinationDST                       int16u
+  0x0029   FrameNumber                          int32u
+  0x0032   ImageProcessing                      undef[4]
+  0x0033   PictureMode                          int8u[3]
+  0x0034   DriveMode                            int8u[4]
+  0x0037   ColorSpace                           int16u
+  0x0038   ImageAreaOffset                      int16u[2]
+  0x0039   RawImageSize                         int16u[2]~
+  0x003c   AFPointsInFocus                      N
+  0x003f   LensType                             int8u[2]
+  0x0047   CameraTemperature                    int8s
+  0x0049   NoiseReduction                       int16u
+  0x004d   FlashExposureComp                    int32s
+  0x004f   ImageTone                            int16u
+  0x005c   ShakeReductionInfo                   Pentax SRInfo
+  0x005d   ShutterCount                         undef[4]
+  0x0200   BlackPoint                           int16u[4]
+  0x0201   WhitePoint                           int16u[4]
+  0x0206   AEInfo                               Pentax AEInfo
+  0x0207   LensInfo                             Pentax LensInfo
+  0x0208   FlashInfo                            Pentax FlashInfo
+  0x0209   AEMeteringSegments                   int8u[16]
+  0x020a   FlashADump?                          Y
+  0x020b   FlashBDump?                          Y
+  0x020d   WB_RGGBLevelsDaylight                int16u[4]
+  0x020e   WB_RGGBLevelsShade                   int16u[4]
+  0x020f   WB_RGGBLevelsCloudy                  int16u[4]
+  0x0210   WB_RGGBLevelsTungsten                int16u[4]
+  0x0211   WB_RGGBLevelsFluorescentD            int16u[4]
+  0x0212   WB_RGGBLevelsFluorescentN            int16u[4]
+  0x0213   WB_RGGBLevelsFluorescentW            int16u[4]
+  0x0214   WB_RGGBLevelsFlash                   int16u[4]
+  0x0215   CameraInfo                           Pentax CameraInfo
+  0x0216   BatteryInfo                          Pentax BatteryInfo
+  0x021f   AFInfo                               Pentax AFInfo
+  0x03fe   DataDump                             N
+  0x0402   ToneCurve                            Y~
+  0x0403   ToneCurves                           Y~
+  0x0e00   PrintIM                              PrintIM
+
+=head3 Pentax SRInfo Tags
+
+Shake reduction information.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    SRResult                             int8u
+      1    ShakeReduction                       int8u
+      2    SR_SWSToSWRTime                      int8u
+
+=head3 Pentax AEInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    AEExposureTime                       int8u
+      1    AEAperture                           int8u
+      2    AE_ISO                               int8u
+      3    AEXv                                 int8u
+      4    AEBXv                                int8s
+      5    AEFlashTv                            int8u
+      6    AEProgramMode                        int8u
+      7    AEExtra?                             int8u
+
+=head3 Pentax LensInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    LensType                             N
+      4    LensCodes                            int8u[16]
+      5    LensCodes                            int8u[16]
+
+=head3 Pentax FlashInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    FlashStatus                          int8u
+      1    FlashModeCode                        int8u
+      2    ExternalFlashMode                    int8u
+      3    InternalFlashMagni                   int8u
+      4    TTL_DA_AUp                           int8u
+      5    TTL_DA_ADown                         int8u
+      6    TTL_DA_BUp                           int8u
+      7    TTL_DA_BDown                         int8u
+
+=head3 Pentax CameraInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    PentaxModelID                        int32u
+      1    ManufactureDate                      int32u
+      2    ModelRevision                        int32u[2]
+      4    InternalSerialNumber                 int32u
+
+=head3 Pentax BatteryInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    BatteryType                          int8u
+      1    BatteryBodyGripStates                int8u
+      2    BatteryADBodyNoLoad                  int8u
+      3    BatteryADBodyLoad                    int8u
+      4    BatteryADGripNoLoad                  int8u
+      5    BatteryADGripLoad                    int8u
+
+=head3 Pentax AFInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+     11    AFPointsInFocus                      int8u
+
+=head3 Pentax Type2 Tags
+
+These tags are used by the Pentax Optio 330 and 430, and are similar to the
+tags used by Casio.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   RecordingMode                        int16u
+  0x0002   Quality                              int16u
+  0x0003   FocusMode                            int16u
+  0x0004   FlashMode                            int16u
+  0x0007   WhiteBalance                         int16u
+  0x000a   DigitalZoom                          int32u
+  0x000b   Sharpness                            int16u
+  0x000c   Contrast                             int16u
+  0x000d   Saturation                           int16u
+  0x0014   ISO                                  int16u
+  0x0017   ColorFilter                          int16u
+  0x0e00   PrintIM                              PrintIM
+  0x1000   HometownCityCode                     undef[4]
+  0x1001   DestinationCityCode                  undef[4]
+
+=head3 Pentax Type4 Tags
+
+The following few tags are extracted from the wealth of information
+available in maker notes of the Optio E20.  These maker notes are stored as
+ASCII text in a format very similar to some HP models.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'F/W Version'        FirmwareVersion          N
+
+=head3 Pentax MOV Tags
+
+This information is found in Pentax MOV video images.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    Make                                 N
+     38    ExposureTime                         N
+     42    FNumber                              N
+     50    ExposureCompensation                 N
+     68    WhiteBalance                         N
+     72    FocalLength                          N
+    175    ISO                                  N
+
+=head2 Ricoh Tags
+
+These tags are used by Ricoh Caplio camera models.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   MakerNoteType                        string
+  0x0002   MakerNoteVersion                     string
+  0x0e00   PrintIM                              PrintIM
+  0x1001   ImageInfo                            Ricoh ImageInfo
+  0x1003   Sharpness                            int32u
+  0x2001   RicohSubdir                          Ricoh Subdir
+           RicohRR1Subdir                       Ricoh Subdir
+
+=head3 Ricoh ImageInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    RicohImageWidth                      int16u
+      2    RicohImageHeight                     int16u
+      6    RicohDate                            int8u[7]
+     28    PreviewImageStart                    int16u*
+     30    PreviewImageLength                   int16u*
+     32    FlashMode                            int8u
+     33    Macro                                int8u
+     34    Sharpness                            int8u
+     38    WhiteBalance                         int8u
+     39    ISOSetting                           int8u
+     40    Saturation                           int8u
+
+=head3 Ricoh Subdir Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0004   RicohDateTime1                       N
+  0x0005   RicohDateTime2                       N
+
+=head3 Ricoh Text Tags
+
+Ricoh RDC models such as the RDC-i700, RDC-5000, RDC-6000, RDC-7 and
+RDC-4300 use a text-based format for their maker notes instead of the IFD
+format used by the Caplio models.  Below is a list of known tags in this
+information.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'Bg'     BlueGain                             N
+  'Gg'     GreenGain                            N
+  'Rev'    Revision                             N
+  'Rg'     RedGain                              N
+  'Rv'     Revision                             N
+
+=head3 Ricoh RMETA Tags
+
+The Ricoh Caplio Pro G3 has the ability to add custom fields to the APP5
+"RMETA" segment of JPEG images.  While only a few observed tags have been
+defined below, ExifTool will extract any information found here.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Azimuth'            Azimuth                  N
+  'Condition'          Condition                N
+  'Lit'                Lit                      N
+  'Location'           Location                 N
+  'Sign type'          SignType                 N
+
+=head2 Sanyo Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x00ff   MakerNoteOffset                      int32u
+  0x0100   SanyoThumbnail                       undef
+  0x0200   SpecialMode                          int32u[3]
+  0x0201   SanyoQuality                         int16u
+  0x0202   Macro                                int16u
+  0x0204   DigitalZoom                          rational64u
+  0x0207   SoftwareVersion                      Y
+  0x0208   PictInfo                             Y
+  0x0209   CameraID                             Y
+  0x020e   SequentialShot                       int16u
+  0x020f   WideRange                            int16u
+  0x0210   ColorAdjustmentMode                  int16u
+  0x0213   QuickShot                            int16u
+  0x0214   SelfTimer                            int16u
+  0x0216   VoiceMemo                            int16u
+  0x0217   RecordShutterRelease                 int16u
+  0x0218   FlickerReduce                        int16u
+  0x0219   OpticalZoomOn                        int16u
+  0x021b   DigitalZoomOn                        int16u
+  0x021d   LightSourceSpecial                   int16u
+  0x021e   Resaved                              int16u
+  0x021f   SceneSelect                          int16u
+  0x0223   ManualFocusDistance                  rational64u
+  0x0224   SequenceShotInterval                 int16u
+  0x0225   FlashMode                            int16u
+  0x0e00   PrintIM                              PrintIM
+  0x0f00   DataDump                             N
+
+=head3 Sanyo MOV Tags
+
+This information is found in Sanyo MOV video images, and is very similar to
+information found in Pentax MOV and Nikon QT videos.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    Make                                 N
+     24    Model                                N
+     38    ExposureTime                         N
+     42    FNumber                              N
+     50    ExposureCompensation                 N
+     68    WhiteBalance                         N
+     72    FocalLength                          N
+
+=head3 Sanyo MP4 Tags
+
+This information is found in Sanyo MP4 video images.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    Make                                 N
+     24    Model                                N
+     50    FNumber                              N
+    106    ISO                                  N
+   2048    ThumbnailImage                       N
+
+=head2 Sigma Tags
+
+These tags are used in Sigma/Foveon cameras.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0002   SerialNumber                         string
+  0x0003   DriveMode                            string
+  0x0004   ResolutionMode                       string
+  0x0005   AFMode                               string
+  0x0006   FocusSetting                         string
+  0x0007   WhiteBalance                         string
+  0x0008   ExposureMode                         string
+  0x0009   MeteringMode                         string
+  0x000a   Lens                                 string
+  0x000b   ColorSpace                           string
+  0x000c   ExposureCompensation                 string
+           UnknownCompensation?                 rational64s
+  0x000d   Contrast                             string
+           Contrast                             rational64s
+  0x000e   Shadow                               string
+           Shadow                               rational64s
+  0x000f   Highlight                            string
+           Highlight                            rational64s
+  0x0010   Saturation                           string
+           Saturation                           rational64s
+  0x0011   Sharpness                            string
+           Sharpness                            rational64s
+  0x0012   X3FillLight                          string
+           X3FillLight                          rational64s
+  0x0014   ColorAdjustment                      string
+           ColorAdjustment                      rational64s[3]
+  0x0015   AdjustmentMode                       string
+  0x0016   Quality                              string
+  0x0017   Firmware                             string
+  0x0018   Software                             string
+  0x0019   AutoBracket                          string
+  0x001d   MakerNoteVersion                     string
+  0x0022   AdjustmentMode?                      string
+  0x0030   LensApertureRange                    string
+  0x0031   FNumber                              rational64u
+  0x0032   ExposureTime                         rational64u
+  0x0035   ExposureCompensation                 rational64s
+  0x003a   FlashExposureComp                    rational64s
+  0x003b   Firmware                             string
+  0x003c   WhiteBalance                         string
+
+=head2 Sony Tags
+
+The maker notes in images from current Sony camera models contain a wealth
+of information, but very little is known about these tags.  Use the ExifTool
+Unknown (-u) or Verbose (-v) options to see information about the unknown
+tags.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0e00   PrintIM                              PrintIM
+  0xb021   ColorTemperature                     N
+  0xb023   SceneMode                            N
+  0xb024   ZoneMatching                         N
+  0xb025   DynamicRangeOptimizer                N
+  0xb026   ImageStabilization                   N
+  0xb027   LensID                               N
+  0xb028   MinoltaMakerNote                     Minolta
+  0xb029   ColorMode                            int32u
+  0xb040   Macro                                N
+  0xb041   ExposureMode                         N
+  0xb047   Quality                              N
+  0xb04e   LongExposureNoiseReduction           N
+
+=head3 Sony SRF Tags
+
+The maker notes in SRF (Sony Raw Format) images contain 7 IFD's (with family
+1 group names SRF0 through SRF6).  SRF0 through SRF5 use these Sony tags,
+while SRF6 uses standard EXIF tags.  All information other than SRF0 is
+encrypted, but thanks to Dave Coffin the decryption algorithm is known.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   SRF2_Key                             N
+  0x0001   DataKey                              N
+
+=head3 Sony SR2Private Tags
+
+The SR2 format uses the DNGPrivateData tag to reference a private IFD
+containing these tags.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x7200   SR2SubIFDOffset                      N
+  0x7201   SR2SubIFDLength                      N
+  0x7221   SR2SubIFDKey                         N
+
+=head3 Sony SR2SubIFD Tags
+
+Tags in the encrypted SR2SubIFD
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x7303   WB_GRBGLevels                        N
+  0x74a0   MaxApertureAtMaxFocal                N
+  0x74a1   MaxApertureAtMinFocal                N
+  0x74c0   SR2DataIFD                           Sony SR2DataIFD
+
+=head3 Sony SR2DataIFD Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x7770   ColorMode                            N
+
+=head2 Unknown Tags
+
+The following tags are decoded in unsupported maker notes.  Use the Unknown
+(-u) option to display other unknown tags.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0e00   PrintIM                              PrintIM
+
+=head2 DNG Tags
+
+The main DNG tags are found in the EXIF table.  The tables below define only
+information found within structures of these main DNG tag values.
+
+=head3 DNG AdobeData Tags
+
+This information is found in the "Adobe" DNGPrivateData.
+
+The maker notes ('MakN') are processed by ExifTool, but some information may
+have been lost by the Adobe DNG Converter.  This is because the Adobe DNG
+Converter (as of version 3.3) doesn't properly handle information referenced
+from inside the maker notes that lies outside the original maker notes
+block, and this information is lost when only the maker note block is copied
+to the DNG image.   While this isn't a big problem for most camera makes, it
+is serious for some makes like Olympus.
+
+The CRW data is from DNG-converted CRW images, but it has been restructured
+to a proprietary Adobe format (which results in a loss of the original
+hierarchical information structure, and creates extra work for everyone else
+who wants to use this information).
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'CRW '   AdobeCRW                             CanonRaw
+  'MRW '   AdobeMRW                             MinoltaRaw
+  'MakN'   MakerNoteCanon                       Canon
+           MakerNoteCasio                       Casio
+           MakerNoteCasio2                      Casio Type2
+           MakerNoteFujiFilm                    FujiFilm
+           MakerNoteHP                          HP
+           MakerNoteHP2                         HP Type2
+           MakerNoteHP4                         HP Type4
+           MakerNoteHP6                         HP Type6
+           MakerNoteJVC                         JVC
+           MakerNoteJVCText                     JVC Text
+           MakerNoteKodak1a                     Kodak
+           MakerNoteKodak1b                     Kodak
+           MakerNoteKodak2                      Kodak Type2
+           MakerNoteKodak3                      Kodak Type3
+           MakerNoteKodak4                      Kodak Type4
+           MakerNoteKodak5                      Kodak Type5
+           MakerNoteKodak6a                     Kodak Type6
+           MakerNoteKodak6b                     Kodak Type6
+           MakerNoteKodak7                      Kodak Type7
+           MakerNoteKodakIFD                    Kodak IFD
+           MakerNoteKodakUnknown                Kodak Unknown
+           MakerNoteKyocera                     Unknown
+           MakerNoteMinolta                     Minolta
+           MakerNoteMinolta2                    Olympus
+           MakerNoteMinolta3                    undef
+           MakerNoteNikon                       Nikon
+           MakerNoteNikon2                      Nikon Type2
+           MakerNoteNikon3                      Nikon
+           MakerNoteOlympus                     Olympus
+           MakerNoteOlympus2                    Olympus
+           MakerNoteLeica                       Panasonic
+           MakerNotePanasonic                   Panasonic
+           MakerNotePanasonic2                  Panasonic Type2
+           MakerNotePentax                      Pentax
+           MakerNotePentax2                     Pentax Type2
+           MakerNotePentax3                     Casio Type2
+           MakerNotePentax4                     Pentax Type4
+           MakerNoteRicoh                       Ricoh
+           MakerNoteRicohText                   Ricoh Text
+           PreviewImage                         undef
+           MakerNoteSanyo                       Sanyo
+           MakerNoteSanyoC4                     Sanyo
+           MakerNoteSanyoPatch                  Sanyo
+           MakerNoteSigma                       Sigma
+           MakerNoteSony                        Sony
+           MakerNoteSonySRF                     Sony SRF
+           MakerNoteSonySR2                     Sony
+           MakerNoteUnknown                     Unknown
+  'RAF '   AdobeRAF?                            N
+  'SR2 '   AdobeSR2                             Sony SR2Private
+
+=head3 DNG OriginalRaw Tags
+
+This table defines tags extracted from the DNG OriginalRawFileData
+information.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   OriginalRawImage                     N
+  0x0001   OriginalRawResource                  N
+  0x0002   OriginalRawFileType                  N
+  0x0003   OriginalRawCreator                   N
+  0x0004   OriginalTHMImage                     N
+  0x0005   OriginalTHMResource                  N
+  0x0006   OriginalTHMFileType                  N
+  0x0007   OriginalTHMCreator                   N
+
+=head2 CanonRaw Tags
+
+These tags apply to CRW-format Canon RAW files and information in the APP0
+"CIFF" segment of JPEG images.  When writing CanonRaw/CIFF information, the
+length of the information is preserved (and the new information is truncated
+or padded as required) unless B<Writable> is C<resize>. Currently, only
+JpgFromRaw and ThumbnailImage are allowed to change size.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   NullRecord                           undef
+  0x0001   FreeBytes                            undef
+  0x0032   CanonColorInfo1                      N
+  0x0805   CanonFileDescription                 string[32]
+           UserComment                          string[256]
+  0x080a   CanonRawMakeModel                    CanonRaw MakeModel
+  0x080b   CanonFirmwareVersion                 string[32]
+  0x080c   ComponentVersion                     string
+  0x080d   ROMOperationMode                     string[8]
+  0x0810   OwnerName                            string[32]
+  0x0815   CanonImageType                       string[32]
+  0x0816   OriginalFileName                     string[32]
+  0x0817   ThumbnailFileName                    string[32]
+  0x100a   TargetImageType                      int16u
+  0x1010   ShutterReleaseMethod                 int16u
+  0x1011   ShutterReleaseTiming                 int16u
+  0x1016   ReleaseSetting                       int16u
+  0x101c   BaseISO                              int16u
+  0x1028   CanonFlashInfo?                      int16u[4]
+  0x1029   CanonFocalLength                     Canon FocalLength
+  0x102a   CanonShotInfo                        Canon ShotInfo
+  0x102c   CanonColorInfo2                      N
+  0x102d   CanonCameraSettings                  Canon CameraSettings
+  0x1031   SensorInfo                           Canon SensorInfo
+  0x1033   CustomFunctions10D                   CanonCustom Functions10D
+           CustomFunctionsD30                   CanonCustom FunctionsD30
+           CustomFunctionsD60                   CanonCustom FunctionsD30
+           CustomFunctionsUnknown               CanonCustom FuncsUnknown
+  0x1038   CanonAFInfo                          Canon AFInfo
+  0x1093   CanonFileInfo                        Canon FileInfo
+  0x10a9   ColorBalance                         Canon ColorBalance
+  0x10ae   ColorTemperature                     int16u
+  0x10b4   ColorSpace                           int16u
+  0x10b5   RawJpgInfo                           CanonRaw RawJpgInfo
+  0x1803   ImageFormat                          CanonRaw ImageFormat
+  0x1804   RecordID                             int32u
+  0x1806   SelfTimerTime                        int32u
+  0x1807   TargetDistanceSetting                float
+  0x180b   SerialNumber                         int32u
+  0x180e   TimeStamp                            CanonRaw TimeStamp
+  0x1810   ImageInfo                            CanonRaw ImageInfo
+  0x1813   FlashInfo                            CanonRaw FlashInfo
+  0x1814   MeasuredEV                           float
+  0x1817   FileNumber                           int32u
+  0x1818   ExposureInfo                         CanonRaw ExposureInfo
+  0x1834   CanonModelID                         int32u
+  0x1835   DecoderTable                         N
+  0x183b   SerialNumberFormat                   int32u
+  0x2005   RawData                              N
+  0x2007   JpgFromRaw                           resize
+  0x2008   ThumbnailImage                       resize
+  0x2804   ImageDescription                     CanonRaw
+  0x2807   CameraObject                         CanonRaw
+  0x3002   ShootingRecord                       CanonRaw
+  0x3003   MeasuredInfo                         CanonRaw
+  0x3004   CameraSpecification                  CanonRaw
+  0x300a   ImageProps                           CanonRaw
+  0x300b   ExifInformation                      CanonRaw
+
+=head3 CanonRaw MakeModel Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    Make                                 string[6]
+      6    Model                                string[$size-6]
+
+=head3 CanonRaw RawJpgInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    RawJpgQuality                        int16u
+      2    RawJpgSize                           int16u
+      3    RawJpgWidth                          int16u
+      4    RawJpgHeight                         int16u
+
+=head3 CanonRaw ImageFormat Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    FileFormat                           int32u
+      1    TargetCompressionRatio               float
+
+=head3 CanonRaw TimeStamp Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    DateTimeOriginal                     int32u
+      1    TimeZoneCode                         int32s
+      2    TimeZoneInfo                         int32u
+
+=head3 CanonRaw ImageInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ImageWidth                           N
+      1    ImageHeight                          N
+      2    PixelAspectRatio                     N
+      3    Rotation                             int32s
+      4    ComponentBitDepth                    N
+      5    ColorBitDepth                        N
+      6    ColorBW                              N
+
+=head3 CanonRaw FlashInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    FlashGuideNumber                     float
+      1    FlashThreshold                       float
+
+=head3 CanonRaw ExposureInfo Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ExposureCompensation                 float
+      1    TvValue                              float
+      2    AvValue                              float
+
+=head2 MinoltaRaw Tags
+
+These tags are used in Minolta RAW format (MRW) images.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  "\0PRD"  MinoltaPRD                           MinoltaRaw PRD
+  "\0RIF"  MinoltaRIF                           MinoltaRaw RIF
+  "\0TTW"  MinoltaTTW                           EXIF
+  "\0WBG"  MinoltaWBG                           MinoltaRaw WBG
+
+=head3 MinoltaRaw PRD Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    FirmwareID                           string[8]
+      8    SensorHeight                         int16u
+     10    SensorWidth                          int16u
+     12    ImageHeight                          int16u
+     14    ImageWidth                           int16u
+     16    RawDepth                             int8u
+     17    BitDepth                             int8u
+     18    StorageMethod                        int8u
+     23    BayerPattern                         int8u
+
+=head3 MinoltaRaw RIF Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    Saturation                           int8s
+      2    Contrast                             int8s
+      3    Sharpness                            int8s
+      4    WBMode                               int8u~
+      5    ProgramMode                          int8u
+      6    ISOSetting                           int8u
+      7    ColorMode                            int8u
+     56    ColorFilter                          int8s
+     57    BWFilter                             int8u
+     58    ZoneMatching                         int8u
+     59    Hue                                  int8s
+     60    ColorTemperature                     int8u
+
+=head3 MinoltaRaw WBG Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    WBScale                              int8u[4]
+      4    WBLevels                             int16u[4]
+
+=head2 KyoceraRaw Tags
+
+Tags for Kyocera Contax N Digital RAW images.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    FirmwareVersion                      N
+     12    Model                                N
+     25    Make                                 N
+     33    DateTimeOriginal                     N
+     52    ISO                                  N
+     56    ExposureTime                         N
+     60    WB_RGGBLevels                        N
+     88    FNumber                              N
+    104    MaxAperture                          N
+    112    FocalLength                          N
+    124    Lens                                 N
+
+=head2 SigmaRaw Tags
+
+These tags are used in Sigma and Foveon RAW (.X3F) images.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Header'             Header                   SigmaRaw Header
+  'HeaderExt'          HeaderExt                SigmaRaw HeaderExt
+  'IMA2'               PreviewImage             N
+  'IMAG'               PreviewImage             N
+  'PROP'               Properties               SigmaRaw Properties
+
+=head3 SigmaRaw Header Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   FileVersion                          N
+  0x0007   ImageWidth                           N
+  0x0008   ImageHeight                          N
+  0x0009   Rotation                             N
+  0x000a   WhiteBalance                         N
+
+=head3 SigmaRaw HeaderExt Tags
+
+Extended header data found in version 2.1 and 2.2 files
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   Unused                               N
+  0x0001   ExposureAdjust                       N
+  0x0002   Contrast                             N
+  0x0003   Shadow                               N
+  0x0004   Highlight                            N
+  0x0005   Saturation                           N
+  0x0006   Sharpness                            N
+  0x0007   RedAdjust                            N
+  0x0008   GreenAdjust                          N
+  0x0009   BlueAdjust                           N
+  0x000a   X3FillLight                          N
+
+=head3 SigmaRaw Properties Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'AEMODE'             MeteringMode             N
+  'AFAREA'             AFArea                   N
+  'AFINFOCUS'          AFInFocus                N
+  'AFMODE'             FocusMode                N
+  'APERTURE'           FNumber                  N
+  'AP_DESC'            ApertureDisplayed        N
+  'BRACKET'            BracketShot              N
+  'BURST'              BurstShot                N
+  'CAMMANUF'           Make                     N
+  'CAMMODEL'           Model                    N
+  'CAMNAME'            CameraName               N
+  'CAMSERIAL'          SerialNumber             N
+  'COLORSPACE'         ColorSpace               N
+  'DRIVE'              DriveMode                N
+  'EVAL_STATE'         EvalState                N
+  'EXPCOMP'            ExposureCompensation     N
+  'EXPNET'             NetExposureCompensation  N
+  'EXPTIME'            IntegrationTime          N
+  'FIRMVERS'           FirmwareVersion          N
+  'FLASH'              FlashMode                N
+  'FLASHEXPCOMP'       FlashExpComp             N
+  'FLASHPOWER'         FlashPower               N
+  'FLASHTTLMODE'       FlashTTLMode             N
+  'FLASHTYPE'          FlashType                N
+  'FLENGTH'            FocalLength              N
+  'FLEQ35MM'           FocalLengthIn35mmFormat  N
+  'FOCUS'              Focus                    N
+  'IMAGERBOARDID'      ImagerBoardID            N
+  'IMAGERTEMP'         SensorTemperature        N
+  'ISO'                ISO                      N
+  'LENSARANGE'         LensApertureRange        N
+  'LENSFRANGE'         LensFocalRange           N
+  'LENSMODEL'          LensID                   N
+  'PMODE'              ExposureProgram          N
+  'RESOLUTION'         Quality                  N
+  'SENSORID'           SensorID                 N
+  'SHUTTER'            ExposureTime             N
+  'SH_DESC'            ShutterSpeedDisplayed    N
+  'TIME'               DateTimeOriginal         N
+  'VERSION_BF'         VersionBF                N
+  'WB_DESC'            WhiteBalance             N
+
+=head2 JFIF Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    JFIFVersion                          N
+      2    ResolutionUnit                       int8u
+      3    XResolution                          int16u
+      5    YResolution                          int16u
+
+=head3 JFIF Extension Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0010   ThumbnailImage                       N
+
+=head2 FlashPix Tags
+
+The FlashPix file format, introduced in 1996, was developed by Kodak,
+Hewlett-Packard and Microsoft.  Internally the FPX file structure mimics
+that of an old DOS disk with fixed-sized "sectors" (usually 512 bytes) and a
+"file allocation table" (FAT).  No wonder the format never became popular.
+
+However, some of the structures used in FlashPix streams are part of the
+EXIF specification, and are still being used in the APP2 FPXR segment of
+JPEG images by some Kodak and Hewlett-Packard digital cameras.
+
+ExifTool extracts FlashPix information from both FPX images and the APP2
+FPXR segment of JPEG images.  As well, FlashPix information is extracted
+from DOC, XLS and PPT (Microsoft Word, Excel and PowerPoint) documents since
+the FlashPix file format is closely related to the formats of these files.
+
+  Tag ID                           Tag Name     Writable
+  ------                           --------     --------
+  "\x01CompObj"                    CompObj      FlashPix CompObj
+  "\x05Audio Info"                 AudioInfo    FlashPix AudioInfo
+  "\x05Data Object"                DataObject   FlashPix DataObject
+  "\x05DocumentSummaryInformation" DocumentInfo FlashPix DocumentInfo
+  "\x05Extension List"             Extensions   FlashPix Extensions
+  "\x05Global Info"                GlobalInfo   FlashPix GlobalInfo
+  "\x05Image Contents"             Image        FlashPix Image
+  "\x05Image Info"                 ImageInfo    FlashPix ImageInfo
+  "\x05Operation"                  Operation    FlashPix Operation
+  "\x05Screen Nail"                ScreenNail   N
+  "\x05SummaryInformation"         SummaryInfo  FlashPix SummaryInfo
+  "\x05Transform"                  Transform    FlashPix Transform
+  'Audio Stream'                   AudioStream  N
+  'Current User'                   CurrentUser  N
+  'ICC Profile 0001'               ICC_Profile  ICC_Profile
+  'Subimage 0000 Header'           SubimageHdr  FlashPix SubimageHdr
+
+=head3 FlashPix CompObj Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    CompObjUserTypeLen                   N
+      1    CompObjUserType                      N
+
+=head3 FlashPix AudioInfo Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head3 FlashPix DataObject Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  0x10000      DataObjectID                     N
+  0x10002      LockedPropertyList               N
+  0x10003      DataObjectTitle                  N
+  0x10004      LastModifier                     N
+  0x10005      RevisionNumber                   N
+  0x10006      DataCreateDate                   N
+  0x10007      DataModifyDate                   N
+  0x10008      CreatingApplication              N
+  0x10100      DataObjectStatus                 N
+  0x10101      CreatingTransform                N
+  0x10102      UsingTransforms                  N
+  0x10000000   CachedImageHeight                N
+  0x10000001   CachedImageWidth                 N
+
+=head3 FlashPix DocumentInfo Tags
+
+The DocumentSummaryInformation property set includes a UserDefined property
+set for which only the Hyperlinks and HyperlinkBase tags are pre-defined.
+However, ExifTool will also extract any other information found in the
+UserDefined properties.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  0x0002               Category                 N
+  0x0003               PresentationTarget       N
+  0x0004               Bytes                    N
+  0x0005               Lines                    N
+  0x0006               Paragraphs               N
+  0x0007               Slides                   N
+  0x0008               Notes                    N
+  0x0009               HiddenSlides             N
+  0x000a               MMClips                  N
+  0x000b               ScaleCrop                N
+  0x000c               HeadingPairs             N
+  0x000d               TitleOfParts             N
+  0x000e               Manager                  N
+  0x000f               Company                  N
+  0x0010               LinksUpToDate            N
+  0x0011               CharCountWithSpaces      N
+  0x0013               SharedDoc                N
+  0x0016               HyperlinksChanged        N
+  0x0017               AppVersion               N
+  '_PID_HLINKS'        Hyperlinks               N
+  '_PID_LINKBASE'      HyperlinkBase            N
+
+=head3 FlashPix Extensions Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  0x0001       ExtensionName                    N
+  0x0002       ExtensionClassID                 N
+  0x0003       ExtensionPersistence             N
+  0x0004       ExtensionCreateDate              N
+  0x0005       ExtensionModifyDate              N
+  0x0006       CreatingApplication              N
+  0x0007       ExtensionDescription             N
+  0x1000       Storage-StreamPathname           N
+  0x2000       FlashPixStreamPathname           N
+  0x2001       FlashPixStreamFieldOffset        N
+  0x3000       PropertySetPathname              N
+  0x3001       PropertySetIDCodes               N
+  0x3002       PropertyVectorElements           N
+  0x4000       SubimageResolutions              N
+  0x10000000   UsedExtensionNumbers             N
+
+=head3 FlashPix GlobalInfo Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x10002  LockedPropertyList                   N
+  0x10003  TransformedImageTitle                N
+  0x10004  LastModifier                         N
+  0x10100  VisibleOutputs                       N
+  0x10101  MaximumImageIndex                    N
+  0x10102  MaximumTransformIndex                N
+  0x10103  MaximumOperationIndex                N
+
+=head3 FlashPix Image Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  0x1000000    NumberOfResolutions              N
+  0x1000002    ImageWidth                       N
+  0x1000003    ImageHeight                      N
+  0x1000004    DefaultDisplayHeight             N
+  0x1000005    DefaultDisplayWidth              N
+  0x1000006    DisplayUnits                     N
+  0x2000000    SubimageWidth                    N
+  0x2000001    SubimageHeight                   N
+  0x2000002    SubimageColor                    N
+  0x2000003    SubimageNumericalFormat          N
+  0x2000004    DecimationMethod                 N
+  0x2000005    DecimationPrefilterWidth         N
+  0x2000007    SubimageICC_Profile              N
+  0x3000001    JPEGTables                       N
+  0x3000002    MaxJPEGTableIndex                N
+
+=head3 FlashPix ImageInfo Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  0x21000000   FileSource                       N
+  0x21000001   SceneType                        N
+  0x21000002   CreationPathVector               N
+  0x21000003   SoftwareRelease                  N
+  0x21000004   UserDefinedID                    N
+  0x21000005   SharpnessApproximation           N
+  0x22000000   Copyright                        N
+  0x22000001   OriginalImageBroker              N
+  0x22000002   DigitalImageBroker               N
+  0x22000003   Authorship                       N
+  0x22000004   IntellectualPropertyNotes        N
+  0x23000000   TestTarget                       N
+  0x23000002   GroupCaption                     N
+  0x23000003   CaptionText                      N
+  0x23000004   People                           N
+  0x23000007   Things                           N
+  0x2300000a   DateTimeOriginal                 N
+  0x2300000b   Events                           N
+  0x2300000c   Places                           N
+  0x2300000f   ContentDescriptionNotes          N
+  0x24000000   Make                             N
+  0x24000001   Model                            N
+  0x24000002   SerialNumber                     N
+  0x25000000   CreateDate                       N
+  0x25000001   ExposureTime                     N
+  0x25000002   FNumber                          N
+  0x25000003   ExposureProgram                  N
+  0x25000004   BrightnessValue                  N
+  0x25000005   ExposureCompensation             N
+  0x25000006   SubjectDistance                  N
+  0x25000007   MeteringMode                     N
+  0x25000008   LightSource                      N
+  0x25000009   FocalLength                      N
+  0x2500000a   MaxApertureValue                 N
+  0x2500000b   Flash                            N
+  0x2500000c   FlashEnergy                      N
+  0x2500000d   FlashReturn                      N
+  0x2500000e   BackLight                        N
+  0x2500000f   SubjectLocation                  N
+  0x25000010   ExposureIndex                    N
+  0x25000011   SpecialEffectsOpticalFilter      N
+  0x25000012   PerPictureNotes                  N
+  0x26000000   SensingMethod                    N
+  0x26000001   FocalPlaneXResolution            N
+  0x26000002   FocalPlaneYResolution            N
+  0x26000003   FocalPlaneResolutionUnit         N
+  0x26000004   SpatialFrequencyResponse         N
+  0x26000005   CFAPattern                       N
+  0x26000007   ISO                              N
+  0x26000008   Opto-ElectricConvFactor          N
+  0x27000000   FilmBrand                        N
+  0x27000001   FilmCategory                     N
+  0x27000002   FilmSize                         N
+  0x27000003   FilmRollNumber                   N
+  0x27000004   FilmFrameNumber                  N
+  0x28000000   ScannerMake                      N
+  0x28000001   ScannerModel                     N
+  0x28000002   ScannerSerialNumber              N
+  0x28000003   ScanSoftware                     N
+  0x28000004   ScanSoftwareRevisionDate         N
+  0x28000005   ServiceOrganizationName          N
+  0x28000006   ScanOperatorID                   N
+  0x28000008   ScanDate                         N
+  0x28000009   ModifyDate                       N
+  0x2800000a   ScannerPixelSize                 N
+  0x29000000   OriginalScannedImageSize         N
+  0x29000001   OriginalDocumentSize             N
+  0x29000002   OriginalMedium                   N
+  0x29000003   TypeOfOriginal                   N
+
+=head3 FlashPix Operation Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x10000  OperationID                          N
+
+=head3 FlashPix SummaryInfo Tags
+
+The Dictionary, CodePage and LocalIndicator tags are common to all FlashPix
+property tables, even though they are only listed in the SummaryInfo table.
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  0x0000       Dictionary                       N
+  0x0001       CodePage                         N
+  0x0002       Title                            N
+  0x0003       Subject                          N
+  0x0004       Author                           N
+  0x0005       Keywords                         N
+  0x0006       Comments                         N
+  0x0007       Template                         N
+  0x0008       LastSavedBy                      N
+  0x0009       RevisionNumber                   N
+  0x000a       TotalEditTime                    N
+  0x000b       LastPrinted                      N
+  0x000c       CreateDate                       N
+  0x000d       ModifyDate                       N
+  0x000e       PageCount                        N
+  0x000f       WordCount                        N
+  0x0010       CharCount                        N
+  0x0011       ThumbnailClip                    N
+  0x0012       Software                         N
+  0x0013       Security                         N
+  0x80000000   LocaleIndicator                  N
+
+=head3 FlashPix Transform Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  0x10000      TransformNodeID                  N
+  0x10001      OperationClassID                 N
+  0x10002      LockedPropertyList               N
+  0x10003      TransformTitle                   N
+  0x10004      LastModifier                     N
+  0x10005      RevisionNumber                   N
+  0x10006      TransformCreateDate              N
+  0x10007      TransformModifyDate              N
+  0x10008      CreatingApplication              N
+  0x10100      InputDataObjectList              N
+  0x10101      OutputDataObjectList             N
+  0x10102      OperationNumber                  N
+  0x10000000   ResultAspectRatio                N
+  0x10000001   RectangleOfInterest              N
+  0x10000002   Filtering                        N
+  0x10000003   SpatialOrientation               N
+  0x10000004   ColorTwistMatrix                 N
+  0x10000005   ContrastAdjustment               N
+
+=head3 FlashPix SubimageHdr Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      1    SubimageWidth                        N
+      2    SubimageHeight                       N
+      3    SubimageTileCount                    N
+      4    SubimageTileWidth                    N
+      5    SubimageTileHeight                   N
+      6    NumChannels                          N
+
+=head2 APP12 Tags
+
+=head3 APP12 PictureInfo Tags
+
+The JPEG APP12 "Picture Info" segment was used by some older cameras, and
+contains ASCII-based meta information.  Below are some tags which have been
+observed Agfa and Polaroid images, however ExifTool will extract information
+from any tags found in this segment.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Aperture'           Aperture                 N
+  'ColorMode'          ColorMode                N
+  'ConTake'            ConTake                  N
+  'ExpBias'            ExposureCompensation     N
+  'FNumber'            FNumber                  N
+  'FWare'              FirmwareVersion          N
+  'Flash'              Flash                    N
+  'FocusMode'          FocusMode                N
+  'FocusPos'           FocusPos                 N
+  'ID'                 ID                       N
+  'ImageSize'          ImageSize                N
+  'LightS'             LightS                   N
+  'Macro'              Macro                    N
+  'Protect'            Protect                  N
+  'Quality'            Quality                  N
+  'Resolution'         Resolution               N
+  'Serial#'            SerialNumber             N
+  'Shutter'            ExposureTime             N
+  'StrobeTime'         StrobeTime               N
+  'TimeDate'           DateTimeOriginal         N
+  'Type'               CameraType               N
+  'Version'            Version                  N
+  'Ytarget'            YTarget                  N
+  'Zoom'               Zoom                     N
+  'ZoomPos'            ZoomPos                  N
+  'shtr'               ExposureTime             N
+  'ylevel'             YLevel                   N
+
+=head3 APP12 Ducky Tags
+
+Photoshop uses the JPEG APP12 "Ducky" segment to store some information in
+"Save for Web" images.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   Quality                              int32u/
+  0x0002   Comment                              string/
+  0x0003   Copyright                            string/
+
+=head2 AFCP Tags
+
+AFCP stands for AXS File Concatenation Protocol, and is a poorly designed
+protocol for appending information to the end of files.  This can be used as
+an auxiliary technique to store IPTC information in images, but is
+incompatible with some file formats.
+
+ExifTool will read and write (but not create) AFCP IPTC information in JPEG
+images, but not other image formats.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'IPTC'   IPTC                                 IPTC
+  'Nail'   ThumbnailImage                       N
+  'PrVw'   PreviewImage                         N
+  'TEXT'   Text                                 N
+
+=head2 CanonVRD Tags
+
+Canon Digital Photo Professional writes VRD (Recipe Data) information as a
+trailer record to JPEG, TIFF, CRW and CR2 images, or as a stand-alone VRD
+file. The tags listed below represent information found in this record.  The
+complete VRD data record may be accessed as a block using the Extra
+'CanonVRD' tag, but this tag is not extracted or copied unless specified
+explicitly.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    VRD1                                 CanonVRD Ver1
+      1    VRDStampTool                         CanonVRD StampTool
+      2    VRD2                                 CanonVRD Ver2
+
+=head3 CanonVRD Ver1 Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      2    VRDVersion                           N
+      8    WBAdjRGBLevels                       int16u[3]
+     24    WhiteBalanceAdj                      int16u
+     26    WBAdjColorTemp                       int16u
+     36    WBFineTuneActive                     int16u
+     40    WBFineTuneSaturation                 int16u
+     44    WBFineTuneTone                       int16u
+     46    RawColorAdj                          int16u
+     48    RawCustomSaturation                  int32s
+     52    RawCustomTone                        int32s
+     56    RawBrightnessAdj                     int32s
+     60    ToneCurveProperty                    int16u
+    122    DynamicRangeMin                      int16u
+    124    DynamicRangeMax                      int16u
+    272    ToneCurveActive                      int16u
+    276    BrightnessAdj                        int8s
+    277    ContrastAdj                          int8s
+    278    SaturationAdj                        int16s
+    286    ColorToneAdj                         int32s
+    352    RedCurvePoints                       int16u[21]
+    394    RedCurveLimits                       int16u[4]
+    410    GreenCurvePoints                     int16u[21]
+    452    GreenCurveLimits                     int16u[4]
+    468    BlueCurvePoints                      int16u[21]
+    510    BlueCurveLimits                      int16u[4]
+    526    RGBCurvePoints                       int16u[21]
+    568    RGBCurveLimits                       int16u[4]
+    580    CropActive                           int16u
+    582    CropLeft                             int16u
+    584    CropTop                              int16u
+    586    CropWidth                            int16u
+    588    CropHeight                           int16u
+    608    CropAspectRatio                      int16u
+    610    ConstrainedCropWidth                 float
+    614    ConstrainedCropHeight                float
+    618    CheckMark                            int16u
+    622    Rotation                             int16u
+    624    WorkColorSpace                       int16u
+
+=head3 CanonVRD StampTool Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    StampToolCount                       N
+
+=head3 CanonVRD Ver2 Tags
+
+Tags added in DPP version 2.0 and later.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      4    PictureStyle                         int16u
+     26    RawColorToneAdj                      int16s
+     28    RawSaturationAdj                     int16s
+     30    RawContrastAdj                       int16s
+     32    RawLinear                            int16u
+     34    RawSharpnessAdj                      int16s
+     36    RawHighlightPoint                    int16s
+     38    RawShadowPoint                       int16s
+    116    MonochromeFilterEffect               int16s
+    118    MonochromeToningEffect               int16s
+    120    MonochromeContrast                   int16s
+    122    MonochromeLinear                     int16u
+    124    MonochromeSharpness                  int16s
+    188    ChrominanceNoiseReduction            int16u
+    190    LuminanceNoiseReduction              int16u
+    192    ChrominanceNR_TIFF_JPEG              int16u
+
+=head2 FotoStation Tags
+
+The following tables define information found in the FotoWare FotoStation
+trailer.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   IPTC                                 IPTC
+  0x0002   SoftEdit                             FotoStation SoftEdit
+  0x0003   ThumbnailImage                       Y
+  0x0004   PreviewImage                         Y
+
+=head3 FotoStation SoftEdit Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    OriginalImageWidth                   int32s
+      1    OriginalImageHeight                  int32s
+      2    ColorPlanes                          int32s
+      3    XYResolution                         int32s
+      4    Rotation                             int32s
+      6    CropLeft                             int32s
+      7    CropTop                              int32s
+      8    CropRight                            int32s
+      9    CropBottom                           int32s
+     11    CropRotation                         int32s
+
+=head2 PhotoMechanic Tags
+
+The Photo Mechanic trailer contains data in an IPTC-format structure, with
+soft edit information stored under record number 2.
+
+  Record   Tag Name                             Writable
+  ------   --------                             --------
+      2    SoftEdit                             PhotoMechanic SoftEdit
+
+=head3 PhotoMechanic SoftEdit Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+    209    RawCropLeft                          int32s
+    210    RawCropTop                           int32s
+    211    RawCropRight                         int32s
+    212    RawCropBottom                        int32s
+    213    ConstrainedCropWidth                 int32s
+    214    ConstrainedCropHeight                int32s
+    215    FrameNum                             int32s
+    216    Rotation                             int32s
+    217    CropLeft                             int32s
+    218    CropTop                              int32s
+    219    CropRight                            int32s
+    220    CropBottom                           int32s
+    221    Tagged                               int32s
+    222    ColorClass                           int32s
+    223    Rating                               int32s
+
+=head3 PhotoMechanic XMP Tags
+
+Below is a list of the observed PhotoMechanic XMP tags.  The actual
+namespace prefix is "photomechanic" but ExifTool shortens this in
+the "XMP-photomech" family 1 group name.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'CountryCode'        CountryCode              string/
+  'EditStatus'         EditStatus               string
+  'Prefs'              Prefs                    string
+  'TimeCreated'        TimeCreated              string/
+
+=head2 MIE Tags
+
+MIE is a flexible format which may be used as a stand-alone meta information
+format, for encapsulation of other files and information, or as a trailer
+appended to other file formats.  The tables below represent currently
+defined MIE tags, however ExifTool will also extract any other information
+present in a MIE file.
+
+When writing MIE information, some special features are supported:
+
+1) String values may be written as ASCII (ISO 8859-1) or UTF-8.  ExifTool
+automatically detects the presence of wide characters and treats the string
+appropriately. Internally, UTF-8 text may be converted to UTF-16 or UTF-32
+and stored in this format in the file if it is more compact.
+
+2) All MIE string-value tags support localized text.  Localized values are
+written by adding a language/country code to the tag name in the form
+C<TAG-xx_YY>, where C<TAG> is the tag name, C<xx> is a 2-character lower
+case ISO 639-1 language code, and C<YY> is a 2-character upper case ISO
+3166-1 alpha 2 country code (ie. C<Title-en_US>).  But as usual, the user
+interface is case-insensitive, and ExifTool will write the correct case to
+the file.
+
+3) Some numerical MIE tags allow units of measurement to be specified.  For
+these tags, units may be added in brackets immediately following the value
+(ie. C<55(mi/h)>).  If no units are specified, the default units are
+written.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  '0Type'              SubfileType              string
+  '0Vers'              MIEVersion               string
+  '1Directory'         SubfileDirectory         string
+  '1Name'              SubfileName              string
+  '2MIME'              SubfileMIMEType          string
+  'Meta'               Meta                     MIE Meta
+  'data'               SubfileData              undef
+  'rsrc'               SubfileResource          undef
+  'zmd5'               MD5Digest                string
+  'zmie'               TrailerSignature         undef
+
+=head3 MIE Meta Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Audio'              Audio                    MIE Audio
+  'Camera'             Camera                   MIE Camera
+  'Document'           Document                 MIE Doc
+  'EXIF'               EXIF                     EXIF
+  'Geo'                Geo                      MIE Geo
+  'ICCProfile'         ICC_Profile              ICC_Profile
+  'ID3'                ID3                      ID3
+  'IPTC'               IPTC                     IPTC
+  'Image'              Image                    MIE Image
+  'MakerNotes'         MakerNotes               MIE MakerNotes
+  'Preview'            Preview                  MIE Preview
+  'Thumbnail'          Thumbnail                MIE Thumbnail
+  'Video'              Video                    MIE Video
+  'XMP'                XMP                      XMP
+
+=head3 MIE Audio Tags
+
+For the Audio group (and any other group containing a 'data' element), tags
+refer to the contained data if present, otherwise they refer to the main
+SubfileData.  The C<0Type> and C<1Name> elements should exist only if C<data>
+is present.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  '0Type'              RelatedAudioFileType     string
+  '1Name'              RelatedAudioFileName     string
+  'Channels'           Channels                 int8u
+  'Compression'        AudioCompression         string
+  'Duration'           Duration                 rational64u
+  'SampleBits'         SampleBits               int16u
+  'SampleRate'         SampleRate               int32u
+  'data'               RelatedAudioFile         undef
+
+=head3 MIE Camera Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Brightness'         Brightness               int8s
+  'ColorBalance'       ColorBalance             rational64u[3]
+  'ColorTemperature'   ColorTemperature         int32u
+  'Contrast'           Contrast                 int8s
+  'DigitalZoom'        DigitalZoom              rational64u
+  'ExposureComp'       ExposureCompensation     rational64s
+  'ExposureMode'       ExposureMode             string
+  'ExposureTime'       ExposureTime             rational64u
+  'FirmwareVersion'    FirmwareVersion          string
+  'Flash'              Flash                    MIE Flash
+  'FocusMode'          FocusMode                string
+  'ISO'                ISO                      int16u
+  'ISOSetting'         ISOSetting               int16u
+  'ImageNumber'        ImageNumber              int32u
+  'ImageQuality'       ImageQuality             string
+  'ImageStabilization' ImageStabilization       int8u
+  'Lens'               Lens                     MIE Lens
+  'Make'               Make                     string
+  'MeasuredEV'         MeasuredEV               rational64s
+  'Model'              Model                    string
+  'Orientation'        Orientation              MIE Orient
+  'OwnerName'          OwnerName                string
+  'Saturation'         Saturation               int8s
+  'SensorSize'         SensorSize               rational64u[2]
+  'SerialNumber'       SerialNumber             string
+  'Sharpness'          Sharpness                int8s
+  'ShootingMode'       ShootingMode             string
+
+=head3 MIE Flash Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'ExposureComp'       FlashExposureComp        rational64s
+  'Fired'              FlashFired               int8u
+  'GuideNumber'        FlashGuideNumber         string
+  'Make'               FlashMake                string
+  'Mode'               FlashMode                string
+  'Model'              FlashModel               string
+  'SerialNumber'       FlashSerialNumber        string
+  'Type'               FlashType                string
+
+=head3 MIE Lens Tags
+
+All recorded lens parameters (focal length, aperture, etc) include the
+effects of the extender if present.
+
+  Tag ID                  Tag Name              Writable
+  ------                  --------              --------
+  'Extender'              Extender              MIE Extender
+  'FNumber'               FNumber               rational64u
+  'FocalLength'           FocalLength           rational64u
+  'FocusDistance'         FocusDistance         rational64u
+  'Make'                  LensMake              string
+  'MaxAperture'           MaxAperture           rational64u
+  'MaxApertureAtMaxFocal' MaxApertureAtMaxFocal rational64u
+  'MaxFocalLength'        MaxFocalLength        rational64u
+  'MinAperture'           MinAperture           rational64u
+  'MinFocalLength'        MinFocalLength        rational64u
+  'Model'                 LensModel             string
+  'OpticalZoom'           OpticalZoom           rational64u
+  'SerialNumber'          LensSerialNumber      string
+
+=head3 MIE Extender Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Magnification'      ExtenderMagnification    rational64s
+  'Make'               ExtenderMake             string
+  'Model'              ExtenderModel            string
+  'SerialNumber'       ExtenderSerialNumber     string
+
+=head3 MIE Orient Tags
+
+These tags describe the camera orientation.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Azimuth'            Azimuth                  rational64s
+  'Declination'        Declination              rational64s
+  'Elevation'          Elevation                rational64s
+  'RightAscension'     RightAscension           rational64s
+  'Rotation'           Rotation                 rational64s
+
+=head3 MIE Doc Tags
+
+Information describing the main document, image or file.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Author'             Author                   string
+  'Comment'            Comment                  string
+  'Contributors'       Contributors             string+
+  'Copyright'          Copyright                string
+  'CreateDate'         CreateDate               string
+  'EMail'              EMail                    string
+  'Keywords'           Keywords                 string+
+  'ModifyDate'         ModifyDate               string
+  'OriginalDate'       DateTimeOriginal         string
+  'Phone'              PhoneNumber              string
+  'References'         References               string+
+  'Software'           Software                 string
+  'Title'              Title                    string
+  'URL'                URL                      string
+
+=head3 MIE Geo Tags
+
+Information related to geographic location.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Address'            Address                  string
+  'City'               City                     string
+  'Country'            Country                  string
+  'GPS'                GPS                      MIE GPS
+  'PostalCode'         PostalCode               string
+  'State'              State                    string
+  'UTM'                UTM                      MIE UTM
+
+=head3 MIE GPS Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Altitude'           GPSAltitude              rational64s
+  'Bearing'            GPSDestBearing           rational64s
+  'DateTime'           GPSDateTime              string
+  'Datum'              GPSMapDatum              string
+  'Differential'       GPSDifferential          int8u
+  'Distance'           GPSDestDistance          rational64s
+  'Heading'            GPSTrack                 rational64s
+  'Latitude'           GPSLatitude              rational64s[n]
+  'Longitude'          GPSLongitude             rational64s[n]
+  'MeasureMode'        GPSMeasureMode           int8u
+  'Satellites'         GPSSatellites            string
+  'Speed'              GPSSpeed                 rational64s
+
+=head3 MIE UTM Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  'Datum'      UTMMapDatum                      string
+  'Easting'    UTMEasting                       string
+  'Northing'   UTMNorthing                      string
+  'Zone'       UTMZone                          int8s
+
+=head3 MIE Image Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  '0Type'              FullSizeImageType        string
+  '1Name'              FullSizeImageName        string
+  'BitDepth'           BitDepth                 int16u
+  'ColorSpace'         ColorSpace               string
+  'Components'         ComponentsConfiguration  string
+  'Compression'        CompressionRatio         rational32u
+  'ImageSize'          ImageSize                int16u[n]
+  'Resolution'         Resolution               rational64u[n]
+  'data'               FullSizeImage            undef
+
+=head3 MIE MakerNotes Tags
+
+MIE maker notes are contained within separate groups for each manufacturer
+to avoid name conflicts.  Currently no specific manufacturer information has
+been defined.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Canon'              Canon                    MIE Unknown
+  'Casio'              Casio                    MIE Unknown
+  'FujiFilm'           FujiFilm                 MIE Unknown
+  'Kodak'              Kodak                    MIE Unknown
+  'KonicaMinolta'      KonicaMinolta            MIE Unknown
+  'Nikon'              Nikon                    MIE Unknown
+  'Olympus'            Olympus                  MIE Unknown
+  'Panasonic'          Panasonic                MIE Unknown
+  'Pentax'             Pentax                   MIE Unknown
+  'Ricoh'              Ricoh                    MIE Unknown
+  'Sigma'              Sigma                    MIE Unknown
+  'Sony'               Sony                     MIE Unknown
+
+=head3 MIE Unknown Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head3 MIE Preview Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  '0Type'              PreviewImageType         string
+  '1Name'              PreviewImageName         string
+  'ImageSize'          PreviewImageSize         int16u[n]
+  'data'               PreviewImage             undef
+
+=head3 MIE Thumbnail Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  '0Type'              ThumbnailImageType       string
+  '1Name'              ThumbnailImageName       string
+  'ImageSize'          ThumbnailImageSize       int16u[n]
+  'data'               ThumbnailImage           undef
+
+=head3 MIE Video Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  '0Type'      RelatedVideoFileType             string
+  '1Name'      RelatedVideoFileName             string
+  'Codec'      Codec                            string
+  'Duration'   Duration                         rational64u
+  'data'       RelatedVideoFile                 undef
+
+=head2 ID3 Tags
+
+ExifTool extracts ID3 information from MP3, MPEG, AIFF, OGG, FLAC, APE and
+RealAudio files.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+  'ID3v1'  ID3v1                                ID3 v1
+  'ID3v22' ID3v2_2                              ID3 v2_2
+  'ID3v23' ID3v2_3                              ID3 v2_3
+  'ID3v24' ID3v2_4                              ID3 v2_4
+
+=head3 ID3 v1 Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      3    Title                                N
+     33    Artist                               N
+     63    Album                                N
+     93    Year                                 N
+     97    Comment                              N
+    127    Genre                                N
+
+=head3 ID3 v2_2 Tags
+
+ExifTool extracts mainly text-based tags from ID3v2 information.  The tags
+in the tables below are those extracted by ExifTool, and don't represent a
+complete list of available ID3v2 tags.
+
+ID3 version 2.2 tags.  (These are the tags written by iTunes 5.0.)
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'CNT'    PlayCounter                          N
+  'COM'    Comment                              N
+  'IPL'    InvolvedPeople                       N
+  'PIC'    Picture                              N
+  'TAL'    Album                                N
+  'TBP'    BeatsPerMinute                       N
+  'TCM'    Composer                             N
+  'TCO'    Genre                                N
+  'TCP'    Compilation                          N
+  'TCR'    Copyright                            N
+  'TDA'    Date                                 N
+  'TDY'    PlaylistDelay                        N
+  'TEN'    EncodedBy                            N
+  'TFT'    FileType                             N
+  'TIM'    Time                                 N
+  'TKE'    InitialKey                           N
+  'TLA'    Language                             N
+  'TLE'    Length                               N
+  'TMT'    Media                                N
+  'TOA'    OriginalArtist                       N
+  'TOF'    OriginalFilename                     N
+  'TOL'    OriginalLyricist                     N
+  'TOR'    OriginalReleaseYear                  N
+  'TOT'    OriginalAlbum                        N
+  'TP1'    Artist                               N
+  'TP2'    Band                                 N
+  'TP3'    Conductor                            N
+  'TP4'    InterpretedBy                        N
+  'TPA'    PartOfSet                            N
+  'TPB'    Publisher                            N
+  'TRC'    ISRC                                 N
+  'TRD'    RecordingDates                       N
+  'TRK'    Track                                N
+  'TSI'    Size                                 N
+  'TSS'    EncoderSettings                      N
+  'TT1'    Grouping                             N
+  'TT2'    Title                                N
+  'TT3'    Subtitle                             N
+  'TXT'    Lyricist                             N
+  'TXX'    UserDefinedText                      N
+  'TYE'    Year                                 N
+  'ULT'    Lyrics                               N
+  'WAF'    FileRUL                              N
+  'WAR'    ArtistURL                            N
+  'WAS'    SourceURL                            N
+  'WCM'    CommercialURL                        N
+  'WCP'    CopyrightURL                         N
+  'WPB'    PublisherURL                         N
+  'WXX'    UserDefinedURL                       N
+
+=head3 ID3 v2_3 Tags
+
+ID3 version 2.3 tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'APIC'   Picture                              N
+  'COMM'   Comment                              N
+  'IPLS'   InvolvedPeople                       N
+  'MCDI'   MusicCDIdentifier                    N
+  'PCNT'   PlayCounter                          N
+  'PRIV'   Private                              ID3 Private
+  'TALB'   Album                                N
+  'TBPM'   BeatsPerMinute                       N
+  'TCOM'   Composer                             N
+  'TCON'   Genre                                N
+  'TCOP'   Copyright                            N
+  'TDAT'   Date                                 N
+  'TDLY'   PlaylistDelay                        N
+  'TENC'   EncodedBy                            N
+  'TEXT'   Lyricist                             N
+  'TFLT'   FileType                             N
+  'TIME'   Time                                 N
+  'TIT1'   Grouping                             N
+  'TIT2'   Title                                N
+  'TIT3'   Subtitle                             N
+  'TKEY'   InitialKey                           N
+  'TLAN'   Language                             N
+  'TLEN'   Length                               N
+  'TMED'   Media                                N
+  'TOAL'   OriginalAlbum                        N
+  'TOFN'   OriginalFilename                     N
+  'TOLY'   OriginalLyricist                     N
+  'TOPE'   OriginalArtist                       N
+  'TORY'   OriginalReleaseYear                  N
+  'TOWN'   FileOwner                            N
+  'TPE1'   Artist                               N
+  'TPE2'   Band                                 N
+  'TPE3'   Conductor                            N
+  'TPE4'   InterpretedBy                        N
+  'TPOS'   PartOfSet                            N
+  'TPUB'   Publisher                            N
+  'TRCK'   Track                                N
+  'TRDA'   RecordingDates                       N
+  'TRSN'   InternetRadioStationName             N
+  'TRSO'   InternetRadioStationOwner            N
+  'TSIZ'   Size                                 N
+  'TSRC'   ISRC                                 N
+  'TSSE'   EncoderSettings                      N
+  'TXXX'   UserDefinedText                      N
+  'TYER'   Year                                 N
+  'USER'   TermsOfUse                           N
+  'USLT'   Lyrics                               N
+  'WCOM'   CommercialURL                        N
+  'WCOP'   CopyrightURL                         N
+  'WOAF'   FileRUL                              N
+  'WOAR'   ArtistURL                            N
+  'WOAS'   SourceURL                            N
+  'WORS'   InternetRadioStationURL              N
+  'WPAY'   PaymentURL                           N
+  'WPUB'   PublisherURL                         N
+  'WXXX'   UserDefinedURL                       N
+
+=head3 ID3 Private Tags
+
+ID3 private (PRIV) tags.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'AverageLevel'       AverageLevel             N
+  'PeakValue'          PeakValue                N
+  'XMP'                XMP                      XMP
+
+=head3 ID3 v2_4 Tags
+
+ID3 version 2.4 tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'APIC'   Picture                              N
+  'COMM'   Comment                              N
+  'MCDI'   MusicCDIdentifier                    N
+  'PCNT'   PlayCounter                          N
+  'PRIV'   Private                              ID3 Private
+  'TALB'   Album                                N
+  'TBPM'   BeatsPerMinute                       N
+  'TCOM'   Composer                             N
+  'TCON'   Genre                                N
+  'TCOP'   Copyright                            N
+  'TDEN'   EncodingTime                         N
+  'TDLY'   PlaylistDelay                        N
+  'TDOR'   OriginalReleaseTime                  N
+  'TDRC'   RecordingTime                        N
+  'TDRL'   ReleaseTime                          N
+  'TDTG'   TaggingTime                          N
+  'TENC'   EncodedBy                            N
+  'TEXT'   Lyricist                             N
+  'TFLT'   FileType                             N
+  'TIPL'   InvolvedPeople                       N
+  'TIT1'   Grouping                             N
+  'TIT2'   Title                                N
+  'TIT3'   Subtitle                             N
+  'TKEY'   InitialKey                           N
+  'TLAN'   Language                             N
+  'TLEN'   Length                               N
+  'TMCL'   MusicianCredits                      N
+  'TMED'   Media                                N
+  'TMOO'   Mood                                 N
+  'TOAL'   OriginalAlbum                        N
+  'TOFN'   OriginalFilename                     N
+  'TOLY'   OriginalLyricist                     N
+  'TOPE'   OriginalArtist                       N
+  'TOWN'   FileOwner                            N
+  'TPE1'   Artist                               N
+  'TPE2'   Band                                 N
+  'TPE3'   Conductor                            N
+  'TPE4'   InterpretedBy                        N
+  'TPOS'   PartOfSet                            N
+  'TPRO'   ProducedNotice                       N
+  'TPUB'   Publisher                            N
+  'TRCK'   Track                                N
+  'TRSN'   InternetRadioStationName             N
+  'TRSO'   InternetRadioStationOwner            N
+  'TSOA'   AlbumSortOrder                       N
+  'TSOP'   PerformerSortOrder                   N
+  'TSOT'   TitleSortOrder                       N
+  'TSRC'   ISRC                                 N
+  'TSSE'   EncoderSettings                      N
+  'TSST'   SetSubtitle                          N
+  'TXXX'   UserDefinedText                      N
+  'USER'   TermsOfUse                           N
+  'USLT'   Lyrics                               N
+  'WCOM'   CommercialURL                        N
+  'WCOP'   CopyrightURL                         N
+  'WOAF'   FileRUL                              N
+  'WOAR'   ArtistURL                            N
+  'WOAS'   SourceURL                            N
+  'WORS'   InternetRadioStationURL              N
+  'WPAY'   PaymentURL                           N
+  'WPUB'   PublisherURL                         N
+  'WXXX'   UserDefinedURL                       N
+
+=head2 Jpeg2000 Tags
+
+The tags below are extracted from JPEG 2000 images, however ExifTool
+currently writes only EXIF, IPTC and XMP tags in these images.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'asoc'   Association                          N
+  'bfil'   BinaryFilter                         N
+  'bpcc'   BitsPerComponent                     N
+  'cdef'   ComponentDefinition                  N
+  'cgrp'   ColorGroup                           N
+  'chck'   DigitalSignature                     N
+  'cmap'   ComponentMapping                     N
+  'colr'   ICC_Profile                          ICC_Profile
+           Colorspace                           N
+           ColorSpecification                   N
+  'comp'   Composition                          N
+  'copt'   CompositionOptions                   N
+  'cref'   Cross-Reference                      N
+  'creg'   CodestreamRegistration               N
+  'drep'   DesiredReproductions                 N
+  'dtbl'   DataReference                        N
+  'flst'   FragmentList                         N
+  'free'   Free                                 N
+  'ftbl'   FragmentTable                        N
+  'ftyp'   FileType                             N
+  'gtso'   GraphicsTechnologyStandardOutput     N
+  'ihdr'   ImageHeader                          Jpeg2000 ImageHeader
+  'inst'   InstructionSet                       N
+  'jP  '   JP2Signature                         N
+  'jp2c'   ContiguousCodestream                 N
+  'jp2h'   JP2Header                            Jpeg2000
+  'jp2i'   IntellectualProperty                 XMP
+  'jpch'   CodestreamHeader                     Jpeg2000
+  'jplh'   CompositingLayerHeader               Jpeg2000
+  'lbl '   Label                                N
+  'mdat'   MediaData                            N
+  'mp7b'   MPEG7Binary                          N
+  'nlst'   NumberList                           N
+  'opct'   Opacity                              N
+  'pclr'   Palette                              N
+  'prfl'   Profile                              N
+  'res '   Resolution                           Jpeg2000
+  'resc'   CaptureResolution                    Jpeg2000 CaptureResolution
+  'resd'   DisplayResolution                    Jpeg2000 DisplayResolution
+  'roid'   ROIDescription                       N
+  'rreq'   ReaderRequirements                   N
+  'uinf'   UUIDInfo                             Jpeg2000
+  'ulst'   UUIDList                             N
+  'url '   URL                                  N
+  'uuid'   UUID-EXIF                            EXIF
+           UUID-IPTC                            IPTC
+           UUID-XMP                             XMP
+           UUID-GeoJP2                          EXIF
+           UUID-Unknown                         N
+  'xml '   XML                                  XMP
+
+=head3 Jpeg2000 ImageHeader Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ImageHeight                          N
+      4    ImageWidth                           N
+      8    NumberOfComponents                   N
+     10    BitsPerComponent                     N
+     11    Compression                          N
+
+=head3 Jpeg2000 CaptureResolution Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    CaptureYResolution                   N
+      4    CaptureXResolution                   N
+      8    CaptureYResolutionUnit               N
+      9    CaptureXResolutionUnit               N
+
+=head3 Jpeg2000 DisplayResolution Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    DisplayYResolution                   N
+      4    DisplayXResolution                   N
+      8    DisplayYResolutionUnit               N
+      9    DisplayXResolutionUnit               N
+
+=head2 BMP Tags
+
+There really isn't much meta information in a BMP file as such, just a bit
+of image related information.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      4    ImageWidth                           N
+      8    ImageHeight                          N
+     12    Planes                               N
+     14    BitDepth                             N
+     16    Compression                          N
+     20    ImageLength                          N
+     24    PixelsPerMeterX                      N
+     28    PixelsPerMeterY                      N
+     32    NumColors                            N
+     36    NumImportantColors                   N
+
+=head2 PICT Tags
+
+The PICT format contains no true meta information, except for the possible
+exception of the LongComment opcode.  By default, only ImageWidth,
+ImageHeight and X/YResolution are extracted from a PICT image.  Tags in the
+following table represent image opcodes.  Extraction of these tags is
+experimental, and is only enabled with the Verbose or Unknown options.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   Nop                                  N
+  0x0001   ClipRgn                              N
+  0x0002   BkPat                                N
+  0x0003   TxFont                               N
+  0x0004   TxFace                               N
+  0x0005   TxMode                               N
+  0x0006   SpExtra                              N
+  0x0007   PnSize                               N
+  0x0008   PnMode                               N
+  0x0009   PnPat                                N
+  0x000a   FillPat                              N
+  0x000b   OvSize                               N
+  0x000c   Origin                               N
+  0x000d   TxSize                               N
+  0x000e   FgColor                              N
+  0x000f   BkColor                              N
+  0x0010   TxRatio                              N
+  0x0011   VersionOp                            N
+  0x0012   BkPixPat                             N
+  0x0013   PnPixPat                             N
+  0x0014   FillPixPat                           N
+  0x0015   PnLocHFrac                           N
+  0x0016   ChExtra                              N
+  0x0017   Reserved                             N
+  0x001a   RGBFgCol                             N
+  0x001b   RGBBkCol                             N
+  0x001c   HiliteMode                           N
+  0x001d   HiliteColor                          N
+  0x001e   DefHilite                            N
+  0x001f   OpColor                              N
+  0x0020   Line                                 N
+  0x0021   LineFrom                             N
+  0x0022   ShortLine                            N
+  0x0023   ShortLineFrom                        N
+  0x0024   Reserved                             N
+  0x0028   LongText                             N
+  0x0029   DHText                               N
+  0x002a   DVText                               N
+  0x002b   DHDVText                             N
+  0x002c   FontName                             N
+  0x002d   LineJustify                          N
+  0x002e   GlyphState                           N
+  0x002f   Reserved                             N
+  0x0030   FrameRect                            N
+  0x0031   PaintRect                            N
+  0x0032   EraseRect                            N
+  0x0033   InvertRect                           N
+  0x0034   FillRect                             N
+  0x0035   Reserved                             N
+  0x0038   FrameSameRect                        N
+  0x0039   PaintSameRect                        N
+  0x003a   EraseSameRect                        N
+  0x003b   InvertSameRect                       N
+  0x003c   FillSameRect                         N
+  0x003d   Reserved                             N
+  0x0040   FrameRRect                           N
+  0x0041   PaintRRect                           N
+  0x0042   EraseRRect                           N
+  0x0043   InvertRRect                          N
+  0x0044   FillRRect                            N
+  0x0045   Reserved                             N
+  0x0048   FrameSameRRect                       N
+  0x0049   PaintSameRRect                       N
+  0x004a   EraseSameRRect                       N
+  0x004b   InvertSameRRect                      N
+  0x004c   FillSameRRect                        N
+  0x004d   Reserved                             N
+  0x0050   FrameOval                            N
+  0x0051   PaintOval                            N
+  0x0052   EraseOval                            N
+  0x0053   InvertOval                           N
+  0x0054   FillOval                             N
+  0x0055   Reserved                             N
+  0x0058   FrameSameOval                        N
+  0x0059   PaintSameOval                        N
+  0x005a   EraseSameOval                        N
+  0x005b   InvertSameOval                       N
+  0x005c   FillSameOval                         N
+  0x005d   Reserved                             N
+  0x0060   FrameArc                             N
+  0x0061   PaintArc                             N
+  0x0062   EraseArc                             N
+  0x0063   InvertArc                            N
+  0x0064   FillArc                              N
+  0x0065   Reserved                             N
+  0x0068   FrameSameArc                         N
+  0x0069   PaintSameArc                         N
+  0x006a   EraseSameArc                         N
+  0x006b   InvertSameArc                        N
+  0x006c   FillSameArc                          N
+  0x006d   Reserved                             N
+  0x0070   FramePoly                            N
+  0x0071   PaintPoly                            N
+  0x0072   ErasePoly                            N
+  0x0073   InvertPoly                           N
+  0x0074   FillPoly                             N
+  0x0075   Reserved                             N
+  0x0078   FrameSamePoly                        N
+  0x0079   PaintSamePoly                        N
+  0x007a   EraseSamePoly                        N
+  0x007b   InvertSamePoly                       N
+  0x007c   FillSamePoly                         N
+  0x007d   Reserved                             N
+  0x0080   FrameRgn                             N
+  0x0081   PaintRgn                             N
+  0x0082   EraseRgn                             N
+  0x0083   InvertRgn                            N
+  0x0084   FillRgn                              N
+  0x0085   Reserved                             N
+  0x0088   FrameSameRgn                         N
+  0x0089   PaintSameRgn                         N
+  0x008a   EraseSameRgn                         N
+  0x008b   InvertSameRgn                        N
+  0x008c   FillSameRgn                          N
+  0x008d   Reserved                             N
+  0x0090   BitsRect                             N
+  0x0091   BitsRgn                              N
+  0x0092   Reserved                             N
+  0x0098   PackBitsRect                         N
+  0x0099   PackBitsRgn                          N
+  0x009a   DirectBitsRect                       N
+  0x009b   DirectBitsRgn                        N
+  0x009c   Reserved                             N
+  0x009d   Reserved                             N
+  0x009e   Reserved                             N
+  0x009f   Reserved                             N
+  0x00a0   ShortComment                         N
+  0x00a1   LongComment                          Photoshop
+                                                ICC_Profile
+  0x00a2   Reserved                             N
+  0x00b0   Reserved                             N
+  0x00d0   Reserved                             N
+  0x00ff   OpEndPic                             N
+  0x0100   Reserved                             N
+  0x0200   Reserved                             N
+  0x02ff   Version                              N
+  0x0300   Reserved                             N
+  0x0bff   Reserved                             N
+  0x0c00   HeaderOp                             N
+  0x0c01   Reserved                             N
+  0x7f00   Reserved                             N
+  0x8000   Reserved                             N
+  0x8100   Reserved                             N
+  0x8200   CompressedQuickTime                  N
+  0x8201   UncompressedQuickTime                N
+  0xffff   Reserved                             N
+
+=head2 PNG Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'IHDR'   ImageHeader                          PNG ImageHeader
+  'PLTE'   Palette                              N
+  'bKGD'   BackgroundColor                      N
+  'cHRM'   PrimaryChromaticities                PNG PrimaryChromaticities
+  'fRAc'   FractalParameters                    N
+  'gAMA'   Gamma                                N
+  'gIFg'   GIFGraphicControlExtension           N
+  'gIFt'   GIFPlainTextExtension                N
+  'gIFx'   GIFApplicationExtension              N
+  'hIST'   PaletteHistogram                     N
+  'iCCP'   ICC_Profile                          ICC_Profile
+  'iTXt'   InternationalText                    PNG TextualData
+  'oFFs'   ImageOffset                          N
+  'pCAL'   PixelCalibration                     N
+  'pHYs'   PhysicalPixel                        PNG PhysicalPixel
+  'sBIT'   SignificantBits                      N
+  'sPLT'   SuggestedPalette                     N
+  'sRGB'   SRGBRendering                        N
+  'tEXt'   TextualData                          PNG TextualData
+  'tIME'   ModifyDate                           Y
+  'tRNS'   Transparency                         N
+  'tXMP'   XMP                                  XMP
+  'zTXt'   CompressedText                       PNG TextualData
+
+=head3 PNG ImageHeader Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ImageWidth                           N
+      4    ImageHeight                          N
+      8    BitDepth                             N
+      9    ColorType                            N
+     10    Compression                          N
+     11    Filter                               N
+     12    Interlace                            N
+
+=head3 PNG PrimaryChromaticities Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    WhitePointX                          N
+      1    WhitePointY                          N
+      2    RedX                                 N
+      3    RedY                                 N
+      4    GreenX                               N
+      5    GreenY                               N
+      6    BlueX                                N
+      7    BlueY                                N
+
+=head3 PNG TextualData Tags
+
+The PNG TextualData format allows aribrary tag names to be used.  The tags
+listed below are the only ones that can be written (unless new user-defined
+tags are added via the configuration file), however ExifTool will extract
+any other TextualData tags that are found.
+
+The information for the TextualData tags may be stored as tEXt, zTXt or iTXt
+chunks in the PNG image.  ExifTool will read and edit tags in their original
+form, but tEXt chunks are written by default when creating new tags.
+Compressed zTXt chunks are written only if Compress::Zlib is available, and
+only for profile information or when the -z (Compress) option is specified.
+
+Some of the tags below are not registered as part of the PNG specification,
+but are included here because they are generated by other software such as
+ImageMagick.
+
+  Tag ID                  Tag Name              Writable
+  ------                  --------              --------
+  'Artist'                Artist                string
+  'Author'                Author                string
+  'Comment'               Comment               string
+  'Copyright'             Copyright             string
+  'Creation Time'         CreationTime          string
+  'Description'           Description           string
+  'Disclaimer'            Disclaimer            string
+  'Document'              Document              string
+  'Label'                 Label                 string
+  'Make'                  Make                  string
+  'Model'                 Model                 string
+  'Raw profile type APP1' APP1_Profile          EXIF
+                                                XMP
+  'Raw profile type exif' EXIF_Profile          EXIF
+  'Raw profile type icc'  ICC_Profile           ICC_Profile
+  'Raw profile type icm'  ICC_Profile           ICC_Profile
+  'Raw profile type iptc' IPTC_Profile          Photoshop
+  'Raw profile type xmp'  XMP_Profile           XMP
+  'Software'              Software              string
+  'Source'                Source                string
+  'TimeStamp'             TimeStamp             string
+  'Title'                 Title                 string
+  'URL'                   URL                   string
+  'Warning'               PNGWarning            string
+  'XML:com.adobe.xmp'     XMP                   XMP
+
+=head3 PNG PhysicalPixel Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    PixelsPerUnitX                       N
+      4    PixelsPerUnitY                       N
+      8    PixelUnits                           N
+
+=head2 MNG Tags
+
+This table contains definitions for tags found in MNG and JNG images.  MNG
+is a superset of PNG and JNG, so a MNG image may contain any of these tags
+as well as any PNG tags.  Conversely, only some of these tags are valid for
+JNG images.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'BACK'   Background                           MNG Background
+  'BASI'   BasisObject                          MNG BasisObject
+  'CLIP'   ClipObjects                          MNG ClipObjects
+  'CLON'   CloneObject                          MNG CloneObject
+  'DBYK'   DropByKeyword                        N
+  'DEFI'   DefineObject                         MNG DefineObject
+  'DHDR'   DeltaPNGHeader                       MNG DeltaPNGHeader
+  'DISC'   DiscardObjects                       N
+  'DROP'   DropChunks                           N
+  'FRAM'   Frame                                N
+  'JHDR'   JNGHeader                            MNG JNGHeader
+  'LOOP'   Loop                                 MNG Loop
+  'MAGN'   MagnifyObject                        MNG MagnifyObject
+  'MHDR'   MNGHeader                            MNG MNGHeader
+  'MOVE'   MoveObjects                          MNG MoveObjects
+  'ORDR'   OrderingRestrictions                 N
+  'PAST'   PasteImage                           MNG PasteImage
+  'PPLT'   PartialPalette                       N
+  'PROM'   PromoteParent                        MNG PromoteParent
+  'SAVE'   SaveObjects                          N
+  'SEEK'   SeekPoint                            N
+  'SHOW'   ShowObjects                          MNG ShowObjects
+  'TERM'   TerminationAction                    MNG TerminationAction
+  'eXPi'   ExportImage                          MNG ExportImage
+  'fPRI'   FramePriority                        MNG FramePriority
+  'nEED'   ResourcesNeeded                      N
+  'pHYg'   GlobalPixelSize                      PNG PhysicalPixel
+
+=head3 MNG Background Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    BackgroundColor                      N
+      6    MandatoryBackground                  N
+      7    BackgroundImageID                    N
+      9    BackgroundTiling                     N
+
+=head3 MNG BasisObject Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ImageWidth                           N
+      4    ImageHeight                          N
+      8    BitDepth                             N
+      9    ColorType                            N
+     10    Compression                          N
+     11    Filter                               N
+     12    Interlace                            N
+     13    RedSample                            N
+     17    GreenSample                          N
+     21    BlueSample                           N
+     25    AlphaSample                          N
+     26    Viewable                             N
+
+=head3 MNG ClipObjects Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    FirstObject                          N
+      2    LastObject                           N
+      4    DeltaType                            N
+      5    ClipBoundary                         N
+
+=head3 MNG CloneObject Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    SourceID                             N
+      2    CloneID                              N
+      4    CloneType                            N
+      5    DoNotShow                            N
+      6    ConcreteFlag                         N
+      7    LocalDeltaType                       N
+      8    DeltaXY                              N
+
+=head3 MNG DefineObject Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ObjectID                             N
+      2    DoNotShow                            N
+      3    ConcreteFlag                         N
+      4    XYLocation                           N
+     12    ClippingBoundary                     N
+
+=head3 MNG DeltaPNGHeader Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ObjectID                             N
+      2    ImageType                            N
+      3    DeltaType                            N
+      4    BlockSize                            N
+     12    BlockLocation                        N
+
+=head3 MNG JNGHeader Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ImageWidth                           N
+      4    ImageHeight                          N
+      8    ColorType                            N
+      9    BitDepth                             N
+     10    Compression                          N
+     11    Interlace                            N
+     12    AlphaBitDepth                        N
+     13    AlphaCompression                     N
+     14    AlphaFilter                          N
+     15    AlphaInterlace                       N
+
+=head3 MNG Loop Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    NestLevel                            N
+      1    IterationCount                       N
+      5    TerminationCondition                 N
+      6    IterationMinMax                      N
+     14    SignalNumber                         N
+
+=head3 MNG MagnifyObject Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    FirstObjectID                        N
+      2    LastObjectID                         N
+      4    XMethod                              N
+      5    XMag                                 N
+      7    YMag                                 N
+      9    LeftMag                              N
+     11    RightMag                             N
+     13    TopMag                               N
+     15    BottomMag                            N
+     17    YMethod                              N
+
+=head3 MNG MNGHeader Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ImageWidth                           N
+      1    ImageHeight                          N
+      2    TicksPerSecond                       N
+      3    NominalLayerCount                    N
+      4    NominalFrameCount                    N
+      5    NominalPlayTime                      N
+      6    SimplicityProfile                    N
+
+=head3 MNG MoveObjects Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    FirstObject                          N
+      2    LastObject                           N
+      4    DeltaType                            N
+      5    DeltaXY                              N
+
+=head3 MNG PasteImage Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    DestinationID                        N
+      2    TargetDeltaType                      N
+      3    TargetXY                             N
+     11    SourceID                             N
+     13    CompositionMode                      N
+     14    Orientation                          N
+     15    OffsetOrigin                         N
+     16    OffsetXY                             N
+     24    BoundaryOrigin                       N
+     25    PastClippingBoundary                 N
+
+=head3 MNG PromoteParent Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    NewColorType                         N
+      1    NewBitDepth                          N
+      2    FillMethod                           N
+
+=head3 MNG ShowObjects Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    FirstObject                          N
+      2    LastObject                           N
+      4    ShowMode                             N
+
+=head3 MNG TerminationAction Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    TerminationAction                    N
+      1    IterationEndAction                   N
+      2    Delay                                N
+      6    IterationMax                         N
+
+=head3 MNG ExportImage Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    SnapshotID                           N
+      2    SnapshotName                         N
+
+=head3 MNG FramePriority Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    DeltaType                            N
+      2    Priority                             N
+
+=head2 MIFF Tags
+
+The MIFF format allows aribrary tag names to be used.  Only the standard tag
+names are listed below, however ExifTool will decode any tags found in the
+image.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'background-color'   BackgroundColor          N
+  'blue-primary'       BluePrimary              N
+  'border-color'       BorderColor              N
+  'class'              Class                    N
+  'colors'             Colors                   N
+  'colorspace'         Colorspace               N
+  'columns'            ImageWidth               N
+  'compression'        Compression              N
+  'delay'              Delay                    N
+  'depth'              Depth                    N
+  'dispose'            Dispose                  N
+  'gamma'              Gamma                    N
+  'green-primary'      GreenPrimary             N
+  'id'                 ID                       N
+  'iterations'         Iterations               N
+  'label'              Label                    N
+  'matt-color'         MattColor                N
+  'matte'              Matte                    N
+  'montage'            Montage                  N
+  'packets'            Packets                  N
+  'page'               Page                     N
+  'profile-APP1'       APP1_Profile             EXIF
+                                                XMP
+  'profile-exif'       EXIF_Profile             EXIF
+  'profile-icc'        ICC_Profile              ICC_Profile
+  'profile-iptc'       IPTC_Profile             Photoshop
+  'profile-xmp'        XMP_Profile              XMP
+  'red-primary'        RedPrimary               N
+  'rendering-intent'   RenderingIntent          N
+  'resolution'         Resolution               N
+  'rows'               ImageHeight              N
+  'scene'              Scene                    N
+  'signature'          Signature                N
+  'units'              Units                    N
+  'white-point'        WhitePoint               N
+
+=head2 PDF Tags
+
+The tags listed in the PDF tables below are those which are used by ExifTool
+to extract meta information, but they are only a small fraction of the total
+number of available PDF tags.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'Info'   Info                                 PDF Info
+  'Root'   Root                                 PDF Root
+
+=head3 PDF Info Tags
+
+As well as the tags listed below, the PDF specification allows for
+user-defined tags to exist in the Info dictionary.  These tags, which should
+have corresponding XMP-pdfx entries in the PDF Metadata, are also extracted
+by ExifTool.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Author'             Author                   N
+  'CreationDate'       CreateDate               N
+  'Creator'            Creator                  N
+  'Keywords'           Keywords                 N+
+  'ModDate'            ModifyDate               N
+  'Producer'           Producer                 N
+  'Subject'            Subject                  N
+  'Title'              Title                    N
+  'Trapped'            Trapped                  N
+
+=head3 PDF Root Tags
+
+This is the PDF document catalog.
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  'Metadata'   Metadata                         PDF Metadata
+  'Pages'      Pages                            PDF Pages
+
+=head3 PDF Metadata Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'XML_stream'         XMP                      XMP
+
+=head3 PDF Pages Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'Count'  PageCount                            N
+  'Kids'   Kids                                 PDF Kids
+
+=head3 PDF Kids Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Metadata'           Metadata                 PDF Metadata
+  'PieceInfo'          PieceInfo                PDF PieceInfo
+  'Resources'          Resources                PDF Resources
+
+=head3 PDF PieceInfo Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'AdobePhotoshop'     AdobePhotoshop           PDF AdobePhotoshop
+
+=head3 PDF AdobePhotoshop Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  'Private'    Private                          PDF Private
+
+=head3 PDF Private Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'ImageResources'     ImageResources           PDF ImageResources
+
+=head3 PDF ImageResources Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'stream' Stream                               Photoshop
+
+=head3 PDF Resources Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'ColorSpace'         ColorSpace               PDF ColorSpace
+
+=head3 PDF ColorSpace Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'DefaultRGB'         DefaultRGB               PDF DefaultRGB
+
+=head3 PDF DefaultRGB Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  'ICCBased'   ICCBased                         PDF ICCBased
+
+=head3 PDF ICCBased Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'stream' Stream                               ICC_Profile
+
+=head2 PostScript Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Author'             Author                   string
+  'BeginICCProfile'    ICC_Profile              ICC_Profile
+  'BeginPhotoshop'     PhotoshopData            Photoshop
+  'BoundingBox'        BoundingBox              N
+  'Copyright'          Copyright                string
+  'CreationDate'       CreateDate               string
+  'Creator'            Creator                  string
+  'For'                For                      string
+  'ImageData'          ImageData                N
+  'Keywords'           Keywords                 string
+  'ModDate'            ModifyDate               string
+  'Pages'              Pages                    N
+  'Routing'            Routing                  string
+  'Subject'            Subject                  string
+  'TIFFPreview'        TIFFPreview              N
+  'Title'              Title                    string
+  'Version'            Version                  string
+  'begin_xml_packet'   XMP                      XMP
+
+=head2 Vorbis Tags
+
+ExifTool extracts the following Vorbis information from Ogg files.  As well
+as this, ExifTool also extracts FLAC and ID3 information from Ogg files.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   Identification                       Vorbis Identification
+  0x0003   Comments                             Vorbis Comments
+
+=head3 Vorbis Identification Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    VorbisVersion                        N
+      4    AudioChannels                        N
+      5    SampleRate                           N
+      9    MaximumBitrate                       N
+     13    NominalBitrate                       N
+     17    MinimumBitrate                       N
+
+=head3 Vorbis Comments Tags
+
+The tags below are only some common tags found in the Vorbis comments of Ogg
+Vorbis and Ogg FLAC audio files, however ExifTool will extract values from
+any tag found, even if not listed here.
+
+  Tag ID                  Tag Name              Writable
+  ------                  --------              --------
+  'ALBUM'                 Album                 N
+  'ARTIST'                Artist                N+
+  'COMMENT'               Comment               N
+  'CONTACT'               Contact               N+
+  'COPYRIGHT'             Copyright             N
+  'COVERART'              CoverArt              N
+  'COVERARTMIME'          CoverArtMIMEType      N
+  'DATE'                  Date                  N
+  'DESCRIPTION'           Description           N
+  'ENCODED_BY'            EncodedBy             N
+  'ENCODED_USING'         EncodedUsing          N
+  'GENRE'                 Genre                 N
+  'ISRC'                  ISRCNumber            N
+  'LICENSE'               License               N
+  'LOCATION'              Location              N
+  'ORGANIZATION'          Organization          N
+  'PERFORMER'             Performer             N+
+  'REPLAYGAIN_ALBUM_GAIN' ReplayGainAlbumGain   N
+  'REPLAYGAIN_ALBUM_PEAK' ReplayGainAlbumPeak   N
+  'REPLAYGAIN_TRACK_GAIN' ReplayGainTrackGain   N
+  'REPLAYGAIN_TRACK_PEAK' ReplayGainTrackPeak   N
+  'TITLE'                 Title                 N
+  'TRACKNUMBER'           TrackNumber           N
+  'VERSION'               Version               N
+  'vendor'                Vendor                N
+
+=head2 FLAC Tags
+
+Free Lossless Audio Codec (FLAC) meta information.  ExifTool also extracts
+ID3 information from these files.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   StreamInfo                           FLAC StreamInfo
+  0x0004   VorbisComment                        Vorbis Comments
+
+=head3 FLAC StreamInfo Tags
+
+FLAC is big-endian, so bit 0 is the high-order bit in this table.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Bit000-015'         BlockSizeMin             N
+  'Bit016-031'         BlockSizeMax             N
+  'Bit032-055'         FrameSizeMin             N
+  'Bit056-079'         FrameSizeMax             N
+  'Bit080-099'         SampleRate               N
+  'Bit100-102'         Channels                 N
+  'Bit103-107'         BitsPerSample            N
+  'Bit108-143'         TotalSamples             N
+
+=head2 APE Tags
+
+Tags found in Monkey's Audio (APE) information.  Only a few common tags are
+listed below, but ExifTool will extract any tag found.  ExifTool supports
+APEv1 and APEv2 tags, as well as ID3 information in APE files.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Album'              Album                    N
+  'Artist'             Artist                   N
+  'Genre'              Genre                    N
+  'Title'              Title                    N
+  'Tool Name'          ToolName                 N
+  'Tool Version'       ToolVersion              N
+  'Track'              Track                    N
+  'Year'               Year                     N
+
+=head3 APE NewHeader Tags
+
+APE MAC audio header for version 3.98 or later.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    CompressionLevel                     N
+      2    BlocksPerFrame                       N
+      4    FinalFrameBlocks                     N
+      6    TotalFrames                          N
+      8    BitsPerSample                        N
+      9    Channels                             N
+     10    SampleRate                           N
+
+=head3 APE OldHeader Tags
+
+APE MAC audio header for version 3.97 or earlier.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    APEVersion                           N
+      1    CompressionLevel                     N
+      3    Channels                             N
+      4    SampleRate                           N
+     10    TotalFrames                          N
+     12    FinalFrameBlocks                     N
+
+=head2 MPC Tags
+
+Tags used in Musepack (MPC) audio files.  ExifTool also extracts ID3 and APE
+information from these files.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Bit032-063'         TotalFrames              N
+  'Bit080-081'         SampleRate               N
+  'Bit084-087'         Quality                  N
+  'Bit088-093'         MaxBand                  N
+  'Bit096-111'         ReplayGainTrackPeak      N
+  'Bit112-127'         ReplayGainTrackGain      N
+  'Bit128-143'         ReplayGainAlbumPeak      N
+  'Bit144-159'         ReplayGainAlbumGain      N
+  'Bit179'             FastSeek                 N
+  'Bit191'             Gapless                  N
+  'Bit216-223'         EncoderVersion           N
+
+=head2 MPEG Tags
+
+The MPEG format doesn't specify any file-level meta information.  In lieu of
+this, information is extracted from the first audio and video frame headers
+in the file.
+
+=head3 MPEG Audio Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  'Bit11-12'   MPEGAudioVersion                 N
+  'Bit13-14'   AudioLayer                       N
+  'Bit16-19'   AudioBitrate                     N
+  'Bit20-21'   SampleRate                       N
+  'Bit24-25'   ChannelMode                      N
+  'Bit26'      MSStereo                         N
+  'Bit26-27'   ModeExtension                    N
+  'Bit27'      IntensityStereo                  N
+  'Bit28'      CopyrightFlag                    N
+  'Bit29'      OriginalMedia                    N
+  'Bit30-31'   Emphasis                         N
+
+=head3 MPEG Video Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  'Bit00-11'   ImageWidth                       N
+  'Bit12-23'   ImageHeight                      N
+  'Bit24-27'   AspectRatio                      N
+  'Bit28-31'   FrameRate                        N
+  'Bit32-49'   VideoBitrate                     N
+
+=head2 QuickTime Tags
+
+These tags are used in QuickTime MOV and MP4 videos, and QTIF images.  Tags
+with a question mark after their name are not extracted unless the Unknown
+option is set.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'PICT'   PreviewPICT                          N
+  'free'   Free?                                N
+  'ftyp'   FrameType?                           N
+  'mdat'   Mdat?                                N
+  'moov'   Movie                                QuickTime Movie
+  'pnot'   Preview                              QuickTime Preview
+  'skip'   Skip?                                N
+  'wide'   Wide?                                N
+
+=head3 QuickTime Movie Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'mvhd'   MovieHeader                          QuickTime MovieHdr
+  'trak'   Track                                QuickTime Track
+  'udta'   UserData                             QuickTime UserData
+
+=head3 QuickTime MovieHdr Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    Version                              N
+      1    CreateDate                           N
+      2    ModifyDate                           N
+      3    TimeScale                            N
+      4    Duration                             N
+      5    PreferredRate                        N
+      6    PreferredVolume                      N
+     18    PreviewTime                          N
+     19    PreviewDuration                      N
+     20    PosterTime                           N
+     21    SelectionTime                        N
+     22    SelectionDuration                    N
+     23    CurrentTime                          N
+     24    NextTrackID                          N
+
+=head3 QuickTime Track Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'mdia'   Media                                QuickTime Media
+  'tkhd'   TrackHeader                          QuickTime TrackHdr
+  'udta'   UserData                             QuickTime UserData
+
+=head3 QuickTime Media Tags
+
+MP4 only (most tags unknown because ISO charges for the specification).
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'minf'   Minf                                 QuickTime Minf
+
+=head3 QuickTime Minf Tags
+
+MP4 only (most tags unknown because ISO charges for the specification).
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'dinf'   Dinf                                 QuickTime Dinf
+  'stbl'   Stbl                                 QuickTime Stbl
+
+=head3 QuickTime Dinf Tags
+
+MP4 only (most tags unknown because ISO charges for the specification).
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head3 QuickTime Stbl Tags
+
+MP4 only (most tags unknown because ISO charges for the specification).
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head3 QuickTime TrackHdr Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    TrackVersion                         N
+      1    TrackCreateDate                      N
+      2    TrackModifyDate                      N
+      3    TrackID                              N
+      5    TrackDuration                        N
+      8    TrackLayer                           N
+      9    TrackVolume                          N
+     19    ImageWidth                           N
+     20    ImageHeight                          N
+
+=head3 QuickTime UserData Tags
+
+Tag ID's beginning with the copyright symbol (hex 0xa9) are multi-language
+text, but ExifTool only extracts the text from the first language in the
+record.  ExifTool will extract any multi-language user data tags found, even
+if they don't exist in this table.
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  'AllF'       PlayAllFrames                    N
+  'LOOP'       LoopStyle                        N
+  'SelO'       PlaySelection                    N
+  'TAGS'       PentaxTags                       Pentax MOV
+               NikonTags                        Nikon MOV
+               SanyoMOV                         Sanyo MOV
+               SanyoMP4                         Sanyo MP4
+               UnknownTags?                     N
+  'WLOC'       WindowLocation                   N
+  'meta'       Meta                             QuickTime Meta
+  'name'       Name                             N
+  'ptv '       PrintToVideo                     QuickTime Video
+  "\xa9cpy"    Copyright                        N
+  "\xa9day"    CreateDate                       N
+  "\xa9dir"    Director                         N
+  "\xa9ed1"    Edit1                            N
+  "\xa9ed2"    Edit2                            N
+  "\xa9ed3"    Edit3                            N
+  "\xa9ed4"    Edit4                            N
+  "\xa9ed5"    Edit5                            N
+  "\xa9ed6"    Edit6                            N
+  "\xa9ed7"    Edit7                            N
+  "\xa9ed8"    Edit8                            N
+  "\xa9ed9"    Edit9                            N
+  "\xa9fmt"    Format                           N
+  "\xa9inf"    Information                      N
+  "\xa9prd"    Producer                         N
+  "\xa9prf"    Performers                       N
+  "\xa9req"    Requirements                     N
+  "\xa9src"    Source                           N
+  "\xa9wrt"    Writer                           N
+
+=head3 QuickTime Meta Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'ilst'   InfoList                             QuickTime InfoList
+
+=head3 QuickTime InfoList Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  '----'       iTunesInfo                       QuickTime iTunesInfo
+  'aART'       AlbumArtist                      N
+  'apid'       AppleStoreID                     N
+  'auth'       Author                           N
+  'covr'       CoverArt                         N
+  'cpil'       Compilation                      N
+  'cprt'       Copyright                        N
+  'disk'       DiskNumber                       N
+  'dscp'       Description                      N
+  'gnre'       Genre                            N
+  'perf'       Performer                        N
+  'pgap'       PlayGap                          N
+  'rtng'       Rating                           N
+  'titl'       Title                            N
+  'tmpo'       BeatsPerMinute                   N
+  'trkn'       TrackNumber                      N
+  "\xa9ART"    Artist                           N
+  "\xa9alb"    Album                            N
+  "\xa9cmt"    Comment                          N
+  "\xa9com"    Composer                         N
+  "\xa9day"    Year                             N
+  "\xa9des"    Description                      N
+  "\xa9gen"    Genre                            N
+  "\xa9grp"    Grouping                         N
+  "\xa9lyr"    Lyrics                           N
+  "\xa9nam"    Title                            N
+  "\xa9too"    Encoder                          N
+  "\xa9trk"    Track                            N
+  "\xa9wrt"    Composer                         N
+
+=head3 QuickTime iTunesInfo Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head3 QuickTime Video Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    DisplaySize                          N
+      6    SlideShow                            N
+
+=head3 QuickTime Preview Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    PreviewDate                          N
+      2    PreviewVersion                       N
+      3    PreviewAtomType                      N
+      5    PreviewAtomIndex                     N
+
+=head3 QuickTime ImageFile Tags
+
+Tags used in QTIF QuickTime Image Files.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'idat'   ImageData                            N
+  'idsc'   ImageDescription                     QuickTime ImageDesc
+  'iicc'   ICC_Profile                          ICC_Profile
+
+=head3 QuickTime ImageDesc Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      4    CompressorID                         N
+     20    VendorID                             N
+     28    Quality                              N
+     32    ImageWidth                           N
+     34    ImageHeight                          N
+     36    XResolution                          N
+     40    YResolution                          N
+     48    FrameCount                           N
+     50    NameLength                           N
+     51    Compressor                           N
+     82    BitDepth                             N
+
+=head2 Flash Tags
+
+The information below is extracted from the header of SWF (Shockwave Flash)
+files.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Compressed'         Compressed               N
+  'Duration'           Duration                 N
+  'FlashVersion'       FlashVersion             N
+  'FrameCount'         FrameCount               N
+  'FrameRate'          FrameRate                N
+  'ImageHeight'        ImageHeight              N
+  'ImageWidth'         ImageWidth               N
+
+=head3 Flash FLV Tags
+
+Information is extracted from the following packets in FLV (Flash Video)
+files.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0008   Audio                                Flash Audio
+  0x0009   Video                                Flash Video
+  0x0012   Meta                                 Flash Meta
+
+=head3 Flash Audio Tags
+
+Information extracted from the Flash Audio header.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'Bit0-3' AudioEncoding                        N
+  'Bit4-5' AudioSampleRate                      N
+  'Bit6'   AudioSampleBits                      N
+  'Bit7'   AudioChannels                        N
+
+=head3 Flash Video Tags
+
+Information extracted from the Flash Video header.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'Bit4-7' VideoEncoding                        N
+
+=head3 Flash Meta Tags
+
+Below are a few observed FLV Meta tags, but ExifTool will attempt to extract
+information from any tag found.
+
+  Tag ID                   Tag Name             Writable
+  ------                   --------             --------
+  'audiocodecid'           AudioCodecID         N
+  'audiodatarate'          AudioBitrate         N
+  'audiodelay'             AudioDelay           N
+  'audiosamplerate'        AudioSampleRate      N
+  'audiosamplesize'        AudioSampleSize      N
+  'audiosize'              AudioSize            N
+  'canSeekToEnd'           CanSeekToEnd         N
+  'creationdate'           CreateDate           N
+  'cuePoints'              CuePoint             Flash CuePoint
+  'datasize'               DataSize             N
+  'duration'               Duration             N
+  'filesize'               FileSizeBytes        N
+  'framerate'              FrameRate            N
+  'hasAudio'               HasAudio             N
+  'hasCuePoints'           HasCuePoints         N
+  'hasKeyframes'           HasKeyFrames         N
+  'hasMetadata'            HasMetadata          N
+  'hasVideo'               HasVideo             N
+  'height'                 ImageHeight          N
+  'keyframesFilepositions' KeyFramePositions    N
+  'keyframesTimes'         KeyFramesTimes       N
+  'lastkeyframetimestamp'  LastKeyFrameTime     N
+  'lasttimestamp'          LastTimeStamp        N
+  'metadatacreator'        MetadataCreator      N
+  'metadatadate'           MetadataDate         N
+  'stereo'                 Stereo               N
+  'videocodecid'           VideoCodecID         N
+  'videodatarate'          VideoBitrate         N
+  'videosize'              VideoSize            N
+  'width'                  ImageWidth           N
+
+=head3 Flash CuePoint Tags
+
+These tag names are added to the CuePoint name to generate complete tag
+names like "CuePoint0Name".
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'name'               Name                     N
+  'parameters'         Parameter                Flash Parameter
+  'time'               Time                     N
+  'type'               Type                     N
+
+=head3 Flash Parameter Tags
+
+There are no pre-defined parameter tags, but ExifTool will extract any
+existing parameters, with tag names like "CuePoint0ParameterXxx".
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head2 Real Tags
+
+ExifTool recognizes three basic types of Real audio/video files: 1)
+RealMedia (RM, RV and RMVB), 2) RealAudio (RA), and 3) Real Metafile (RAM
+and RPM).
+
+=head3 Real Media Tags
+
+These B<Tag ID>'s are Chunk ID's used in RealMedia and RealVideo (RM, RV and
+RMVB) files.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'CONT'   CONT                                 Real ContentDescr
+  'MDPR'   MDPR                                 Real MediaProps
+  'PROP'   PROP                                 Real Properties
+  'RJMD'   RJMD                                 Real Metadata
+
+=head3 Real ContentDescr Tags
+
+  Sequence Tag Name                             Writable
+  -------- --------                             --------
+      0    TitleLen?                            N
+      1    Title                                N
+      2    AuthorLen?                           N
+      3    Author                               N
+      4    CopyrightLen?                        N
+      5    Copyright                            N
+      6    CommentLen?                          N
+      7    Comment                              N
+
+=head3 Real MediaProps Tags
+
+  Sequence Tag Name                             Writable
+  -------- --------                             --------
+      0    StreamNumber                         N
+      1    StreamMaxBitRate                     N
+      2    StreamAvgBitRate                     N
+      3    StreamMaxPacketSize                  N
+      4    StreamAvgPacketSize                  N
+      5    StreamStartTime                      N
+      6    StreamPreroll                        N
+      7    StreamDuration                       N
+      8    StreamNameLen?                       N
+      9    StreamName                           N
+     10    StreamMimeLen?                       N
+     11    StreamMimeType                       N
+     12    FileInfoLen?                         N
+     13    FileInfoLen2?                        N
+     14    FileInfoVersion                      N
+     15    PhysicalStreams?                     N
+     16    PhysicalStreamNumbers?               N
+     17    DataOffsets?                         N
+     18    NumRules?                            N
+     19    PhysicalStreamNumberMap?             N
+     20    NumProperties?                       N
+     21    FileInfoProperties                   Real FileInfo
+
+=head3 Real FileInfo Tags
+
+The following tags have been observed in the FileInfo properties, but any
+other existing information will also be extracted.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Audiences'          Audiences                N
+  'Audio Format'       AudioFormat              N
+  'Content Rating'     ContentRating            N
+  'Creation Date'      CreateDate               N
+  'Description'        Description              N
+  'File ID'            FileID                   N
+  'Generated By'       Software                 N
+  'Indexable'          Indexable                N
+  'Keywords'           Keywords                 N
+  'Modification Date'  ModifyDate               N
+  'Target Audiences'   TargetAudiences          N
+  'Video Quality'      VideoQuality             N
+  'audioMode'          AudioMode                N
+  'videoMode'          VideoMode                N
+
+=head3 Real Properties Tags
+
+  Sequence Tag Name                             Writable
+  -------- --------                             --------
+      0    MaxBitRate                           N
+      1    AvgBitRate                           N
+      2    MaxPacketSize                        N
+      3    AvgPacketSize                        N
+      4    NumPackets                           N
+      5    Duration                             N
+      6    Preroll                              N
+      7    IndexOffset?                         N
+      8    DataOffset?                          N
+      9    NumStreams                           N
+     10    Flags                                N
+
+=head3 Real Metadata Tags
+
+The tags below represent information which has been observed in the Real
+Metadata format, but ExifTool will extract any information it finds in this
+format.  (As far as I can tell from the referenced documentation, string
+values should be plain text, but this is not the case for the only sample
+file I have been able to obtain containing this information.  These tags
+could also be split into separate sub-directories, but this will wait until
+I have better documentation or a more complete set of samples.)
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Album/Name'         AlbumName                N
+  'Track/Category'     TrackCategory            N
+  'Track/Comments'     TrackComments            N
+  'Track/Lyrics'       TrackLyrics              N
+
+=head3 Real Audio Tags
+
+Tags in the following table reference information extracted from various
+versions of RealAudio (RA) files.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  '.ra3'   RA3                                  Real AudioV3
+  '.ra4'   RA4                                  Real AudioV4
+  '.ra5'   RA5                                  Real AudioV5
+
+=head3 Real AudioV3 Tags
+
+  Sequence Tag Name                             Writable
+  -------- --------                             --------
+      0    Channels                             N
+      1    Unknown?                             N
+      2    BytesPerMinute                       N
+      3    AudioBytes                           N
+      4    TitleLen?                            N
+      5    Title                                N
+      6    ArtistLen?                           N
+      7    Artist                               N
+      8    CopyrightLen?                        N
+      9    Copyright                            N
+     10    CommentLen?                          N
+     11    Comment                              N
+
+=head3 Real AudioV4 Tags
+
+  Sequence Tag Name                             Writable
+  -------- --------                             --------
+      0    FourCC1?                             N
+      1    AudioFileSize?                       N
+      2    Version2?                            N
+      3    HeaderSize?                          N
+      4    CodecFlavorID?                       N
+      5    CodedFrameSize?                      N
+      6    AudioBytes                           N
+      7    BytesPerMinute                       N
+      8    Unknown?                             N
+      9    SubPacketH?                          N
+     10    AudioFrameSize                       N
+     11    SubPacketSize?                       N
+     12    Unknown?                             N
+     13    SampleRate                           N
+     14    Unknown?                             N
+     15    BitsPerSample                        N
+     16    Channels                             N
+     17    FourCC2Len?                          N
+     18    FourCC2?                             N
+     19    FourCC3Len?                          N
+     20    FourCC3?                             N
+     21    Unknown?                             N
+     22    Unknown?                             N
+     23    TitleLen?                            N
+     24    Title                                N
+     25    ArtistLen?                           N
+     26    Artist                               N
+     27    CopyrightLen?                        N
+     28    Copyright                            N
+     29    CommentLen?                          N
+     30    Comment                              N
+
+=head3 Real AudioV5 Tags
+
+  Sequence Tag Name                             Writable
+  -------- --------                             --------
+      0    FourCC1?                             N
+      1    AudioFileSize?                       N
+      2    Version2?                            N
+      3    HeaderSize?                          N
+      4    CodecFlavorID?                       N
+      5    CodedFrameSize?                      N
+      6    AudioBytes                           N
+      7    BytesPerMinute                       N
+      8    Unknown?                             N
+      9    SubPacketH?                          N
+     10    FrameSize?                           N
+     11    SubPacketSize?                       N
+     12    SampleRate                           N
+     13    SampleRate2?                         N
+     14    BitsPerSample                        N
+     15    Channels                             N
+     16    Genr?                                N
+     17    FourCC3?                             N
+
+=head3 Real Metafile Tags
+
+Tags representing information extracted from Real Audio Metafile and
+RealMedia Plug-in Metafile (RAM and RPM) files.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'txt'    Text                                 N
+  'url'    URL                                  N
+
+=head2 RIFF Tags
+
+Windows WAV and AVI files are RIFF format files.  Meta information embedded
+in two types of RIFF C<LIST> chunks: C<INFO> and C<exif>.  As well, some
+information about the audio content is extracted from the C<fmt > chunk.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'LIST_INFO'          Info                     RIFF Info
+  'LIST_exif'          Exif                     RIFF Exif
+  'LIST_hdrl'          Hdrl                     RIFF Hdrl
+  'fmt '               AudioFormat              RIFF AudioFormat
+
+=head3 RIFF Info Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'IARL'   ArchivalLocation                     N
+  'IART'   Artist                               N
+  'ICMS'   Commissioned                         N
+  'ICMT'   Comment                              N
+  'ICOP'   Copyright                            N
+  'ICRD'   DateCreated                          N
+  'ICRP'   Cropped                              N
+  'IDIM'   Dimensions                           N
+  'IDPI'   DotsPerInch                          N
+  'IENG'   Engineer                             N
+  'IGNR'   Genre                                N
+  'IKEY'   Keywords                             N
+  'ILGT'   Lightness                            N
+  'IMED'   Medium                               N
+  'INAM'   Title                                N
+  'IPLT'   NumColors                            N
+  'IPRD'   Product                              N
+  'ISBJ'   Subject                              N
+  'ISFT'   Software                             N
+  'ISHP'   Sharpness                            N
+  'ISRC'   Source                               N
+  'ISRF'   SourceForm                           N
+  'ITCH'   Technician                           N
+
+=head3 RIFF Exif Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'ecor'   Make                                 N
+  'emdl'   Model                                N
+  'emnt'   MakerNotes                           N
+  'erel'   RelatedImageFile                     N
+  'etim'   TimeCreated                          N
+  'eucm'   UserComment                          N
+  'ever'   ExifVersion                          N
+
+=head3 RIFF Hdrl Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'IDIT'               DateTimeOriginal         N
+  'ISMP'               TimeCode                 N
+  'LIST_strl'          Stream                   RIFF Stream
+  'avih'               AVIHeader                RIFF AVIHeader
+
+=head3 RIFF Stream Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'strd'   StreamData                           RIFF StreamData
+  'strf'   AudioFormat                          RIFF AudioFormat
+           VideoFormat                          BMP
+  'strh'   StreamHeader                         RIFF StreamHeader
+  'strn'   StreamName                           N
+
+=head3 RIFF StreamData Tags
+
+This chunk contains EXIF information in FujiFilm F30 AVI files.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'AVIF'   AVIF                                 EXIF
+
+=head3 RIFF AudioFormat Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    Encoding                             N
+      1    NumChannels                          N
+      2    SampleRate                           N
+      4    AvgBytesPerSec                       N
+      7    BitsPerSample                        N
+
+=head3 RIFF StreamHeader Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    StreamType                           N
+      1    Codec                                N
+     10    Quality                              N
+     11    SampleSize                           N
+
+=head3 RIFF AVIHeader Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    FrameRate                            N
+      1    MaxDataRate                          N
+      4    FrameCount                           N
+      6    StreamCount                          N
+      8    ImageWidth                           N
+      9    ImageHeight                          N
+
+=head2 AIFF Tags
+
+Only the tags decoded by ExifTool are listed in this table.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  '(c) '   Copyright                            N
+  'ANNO'   Annotation                           N
+  'AUTH'   Author                               N
+  'COMM'   Common                               AIFF Common
+  'COMT'   Comment                              AIFF Comment
+  'FVER'   FormatVersion                        AIFF FormatVers
+  'ID3 '   ID3                                  ID3
+  'NAME'   Name                                 N
+
+=head3 AIFF Common Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    NumChannels                          N
+      1    NumSampleFrames                      N
+      3    SampleSize                           N
+      4    SampleRate                           N
+      9    CompressionType                      N
+
+=head3 AIFF Comment Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   CommentTime                          N
+  0x0001   MarkerID                             N
+  0x0002   Comment                              N
+
+=head3 AIFF FormatVers Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    FormatVersionTime                    N
+
+=head2 ASF Tags
+
+ASF format is used by Windows WMA and WMV files.  Tag ID's aren't listed
+because they are huge 128-bit GUID's that would ruin the formatting of this
+table.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  SimpleIndex                                   N
+  TimecodeIndex                                 N
+  Header                                        ASF Header
+  Data                                          N
+  Index                                         N
+  MediaIndex                                    N
+
+=head3 ASF Header Tags
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Padding                                       N
+  ScriptCommand                                 N
+  ContentBranding                               ASF ContentBranding
+  ContentEncryption                             N
+  DigitalSignature                              N
+  ExtendedContentEncryption                     N
+  HeaderExtension                               ASF HeaderExtension
+  ContentDescription                            ASF ContentDescr
+  ErrorCorrection                               N
+  StreamBitrateProps                            N
+  CodecList                                     ASF CodecList
+  FileProperties                                ASF FileProperties
+  StreamProperties                              ASF StreamProperties
+  ExtendedContentDescr                          ASF ExtendedDescr
+  BitrateMutualExclusion                        N
+  Marker                                        N
+
+=head3 ASF ContentBranding Tags
+
+  Tag Name                                      Writable
+  --------                                      --------
+  BannerImageType                               N
+  BannerImage                                   N
+  BannerImageURL                                N
+  CopyrightURL                                  N
+
+=head3 ASF HeaderExtension Tags
+
+  Tag Name                                      Writable
+  --------                                      --------
+  ExtendedStreamProps                           N
+  AdvancedContentEncryption                     N
+  MetadataLibrary                               ASF Metadata
+  TimecodeIndexParms                            N
+  Compatibility                                 N
+  LanguageList                                  N
+  AdvancedMutualExcl                            N
+  BandwidthSharing                              N
+  Reserved1                                     N
+  Metadata                                      ASF Metadata
+  GroupMutualExclusion                          N
+  StreamPrioritization                          N
+  IndexParameters                               N
+
+=head3 ASF Metadata Tags
+
+  Tag Name                                      Writable
+  --------                                      --------
+  [no tags known]
+
+=head3 ASF ContentDescr Tags
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Title                                         N
+  Author                                        N
+  Copyright                                     N
+  Description                                   N
+  Rating                                        N
+
+=head3 ASF CodecList Tags
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AudioCodecDescription                         N
+  AudioCodecName                                N
+  OtherCodecDescription                         N
+  OtherCodecName                                N
+  VideoCodecDescription                         N
+  VideoCodecName                                N
+
+=head3 ASF FileProperties Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    FileID                               N
+     16    FileSize                             N
+     24    CreationDate                         N
+     32    DataPackets                          N
+     40    PlayDuration                         N
+     48    SendDuration                         N
+     56    Preroll                              N
+     64    Flags                                N
+     68    MinPacketSize                        N
+     72    MaxPacketSize                        N
+     76    MaxBitrate                           N
+
+=head3 ASF StreamProperties Tags
+
+Tags with index 54 and greater are conditional based on the StreamType.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    StreamType                           N
+     16    ErrorCorrectionType                  N
+     32    TimeOffset                           N
+     48    StreamNumber                         N
+     54    AudioCodecID                         N
+           ImageWidth                           N
+     56    AudioChannels                        N
+     58    AudioSampleRate                      N
+           ImageHeight                          N
+
+=head3 ASF ExtendedDescr Tags
+
+  Tag Name                                      Writable
+  --------                                      --------
+  ASFLeakyBucketPairs                           N
+  ASFPacketCount                                N
+  ASFSecurityObjectsSize                        N
+  AlbumArtist                                   N
+  AlbumCoverURL                                 N
+  AlbumTitle                                    N
+  AspectRatioX                                  N
+  AspectRatioY                                  N
+  AudioFileURL                                  N
+  AudioSourceURL                                N
+  Author                                        N
+  AuthorURL                                     N
+  AverageLevel                                  N
+  BannerImageData                               N
+  BannerImageType                               N
+  BannerImageURL                                N
+  BeatsPerMinute                                N
+  Bitrate                                       N
+  Broadcast                                     N
+  BufferAverage                                 N
+  Can_Skip_Backward                             N
+  Can_Skip_Forward                              N
+  Category                                      N
+  Codec                                         N
+  Composer                                      N
+  Conductor                                     N
+  ContainerFormat                               N
+  ContentDistributor                            N
+  ContentGroupDescription                       N
+  Copyright                                     N
+  CopyrightURL                                  N
+  CurrentBitrate                                N
+  DRM                                           N
+  DRM_ContentID                                 N
+  DRM_DRMHeader                                 N
+  DRM_DRMHeader_ContentDistributor              N
+  DRM_DRMHeader_ContentID                       N
+  DRM_DRMHeader_IndividualizedVersion           N
+  DRM_DRMHeader_KeyID                           N
+  DRM_DRMHeader_LicenseAcqURL                   N
+  DRM_DRMHeader_SubscriptionContentID           N
+  DRM_IndividualizedVersion                     N
+  DRM_KeyID                                     N
+  DRM_LASignatureCert                           N
+  DRM_LASignatureLicSrvCert                     N
+  DRM_LASignaturePrivKey                        N
+  DRM_LASignatureRootCert                       N
+  DRM_LicenseAcqURL                             N
+  DRM_V1LicenseAcqURL                           N
+  DVDID                                         N
+  Description                                   N
+  Director                                      N
+  Duration                                      N
+  EncodedBy                                     N
+  EncodingSettings                              N
+  EncodingTime                                  N
+  FileSize                                      N
+  Genre                                         N
+  GenreID                                       N
+  HasArbitraryDataStream                        N
+  HasAttachedImages                             N
+  HasAudio                                      N
+  HasFileTransferStream                         N
+  HasImage                                      N
+  HasScript                                     N
+  HasVideo                                      N
+  ISRC                                          N
+  InitialKey                                    N
+  IsVBR                                         N
+  Is_Protected                                  N
+  Is_Trusted                                    N
+  Language                                      N
+  Lyrics                                        N
+  Lyrics_Synchronised                           N
+  MCDI                                          N
+  MediaClassPrimaryID                           N
+  MediaClassSecondaryID                         N
+  MediaCredits                                  N
+  MediaIsDelay                                  N
+  MediaIsFinale                                 N
+  MediaIsLive                                   N
+  MediaIsPremiere                               N
+  MediaIsRepeat                                 N
+  MediaIsSAP                                    N
+  MediaIsStereo                                 N
+  MediaIsSubtitled                              N
+  MediaIsTape                                   N
+  MediaNetworkAffiliation                       N
+  MediaOriginalBroadcastDateTime                N
+  MediaOriginalChannel                          N
+  MediaStationCallSign                          N
+  MediaStationName                              N
+  ModifiedBy                                    N
+  Mood                                          N
+  NSC_Address                                   N
+  NSC_Description                               N
+  NSC_Email                                     N
+  NSC_Name                                      N
+  NSC_Phone                                     N
+  NumberOfFrames                                N
+  OptimalBitrate                                N
+  OriginalAlbumTitle                            N
+  OriginalArtist                                N
+  OriginalFilename                              N
+  OriginalLyricist                              N
+  OriginalReleaseTime                           N
+  OriginalReleaseYear                           N
+  ParentalRating                                N
+  ParentalRatingReason                          N
+  PartOfSet                                     N
+  PeakBitrate                                   N
+  PeakValue                                     N
+  Period                                        N
+  Picture                                       ASF Preview
+  PlaylistDelay                                 N
+  Producer                                      N
+  PromotionURL                                  N
+  ProtectionType                                N
+  Provider                                      N
+  ProviderCopyright                             N
+  ProviderRating                                N
+  ProviderStyle                                 N
+  Publisher                                     N
+  RadioStationName                              N
+  RadioStationOwner                             N
+  Rating                                        N
+  Seekable                                      N
+  SharedUserRating                              N
+  Signature_Name                                N
+  StreamTypeInfo                                N
+  Stridable                                     N
+  SubTitle                                      N
+  SubTitleDescription                           N
+  SubscriptionContentID                         N
+  Text                                          N
+  Title                                         N
+  ToolName                                      N
+  ToolVersion                                   N
+  Track                                         N
+  TrackNumber                                   N
+  UniqueFileIdentifier                          N
+  UserWebURL                                    N
+  VBRPeak                                       N
+  VideoClosedCaptioning                         N
+  VideoFrameRate                                N
+  VideoHeight                                   N
+  VideoWidth                                    N
+  WMADRCAverageReference                        N
+  WMADRCAverageTarget                           N
+  WMADRCPeakReference                           N
+  WMADRCPeakTarget                              N
+  WMCollectionGroupID                           N
+  WMCollectionID                                N
+  WMContentID                                   N
+  Writer                                        N
+  Year                                          N
+
+=head3 ASF Preview Tags
+
+  Tag Name                                      Writable
+  --------                                      --------
+  PreviewType                                   N
+  PreviewMimeType                               N
+  PreviewDescription                            N
+  PreviewImage                                  N
+
+=head2 DICOM Tags
+
+The DICOM format is based on the ACR-NEMA specification, but adds a file
+header and a number of new tags.  ExifTool will extract information from
+either type of file.  The Tag ID's in the following table are the tag group
+and element numbers in hexadecimal, as given in the DICOM specification.
+
+  Tag ID     Tag Name                           Writable
+  ------     --------                           --------
+  0002,0000  FileMetaInfoGroupLength            N
+  0002,0001  FileMetaInfoVersion                N
+  0002,0002  MediaStorageSOPClassUID            N
+  0002,0003  MediaStorageSOPInstanceUID         N
+  0002,0010  TransferSyntaxUID                  N
+  0002,0012  ImplementationClassUID             N
+  0002,0013  ImplementationVersionName          N
+  0002,0016  SourceApplicationEntityTitle       N
+  0002,0100  PrivateInformationCreatorUID       N
+  0002,0102  PrivateInformation                 N
+  0004,1130  FileSetID                          N
+  0004,1141  FileSetDescriptorFileID            N
+  0004,1142  SpecificCharacterSetOfFile         N
+  0004,1200  FirstDirectoryRecordOffset         N
+  0004,1202  LastDirectoryRecordOffset          N
+  0004,1212  FileSetConsistencyFlag             N
+  0004,1220  DirectoryRecordSequence            N
+  0004,1400  OffsetOfNextDirectoryRecord        N
+  0004,1410  RecordInUseFlag                    N
+  0004,1420  LowerLevelDirectoryEntityOffset    N
+  0004,1430  DirectoryRecordType                N
+  0004,1432  PrivateRecordUID                   N
+  0004,1500  ReferencedFileID                   N
+  0004,1504  MRDRDirectoryRecordOffset          N
+  0004,1510  ReferencedSOPClassUIDInFile        N
+  0004,1511  ReferencedSOPInstanceUIDInFile     N
+  0004,1512  ReferencedTransferSyntaxUIDInFile  N
+  0004,151A  ReferencedRelatedSOPClassUIDInFile N
+  0004,1600  NumberOfReferences                 N
+  0008,0000  IdentifyingGroupLength             N
+  0008,0001  LengthToEnd                        N
+  0008,0005  SpecificCharacterSet               N
+  0008,0008  ImageType                          N
+  0008,0010  RecognitionCode                    N
+  0008,0012  InstanceCreationDate               N
+  0008,0013  InstanceCreationTime               N
+  0008,0014  InstanceCreatorUID                 N
+  0008,0016  SOPClassUID                        N
+  0008,0018  SOPInstanceUID                     N
+  0008,001A  RelatedGeneralSOPClassUID          N
+  0008,001B  OriginalSpecializedSOPClassUID     N
+  0008,0020  StudyDate                          N
+  0008,0021  SeriesDate                         N
+  0008,0022  AcquisitionDate                    N
+  0008,0023  ContentDate                        N
+  0008,0024  OverlayDate                        N
+  0008,0025  CurveDate                          N
+  0008,002A  AcquisitionDatetime                N
+  0008,0030  StudyTime                          N
+  0008,0031  SeriesTime                         N
+  0008,0032  AcquisitionTime                    N
+  0008,0033  ContentTime                        N
+  0008,0034  OverlayTime                        N
+  0008,0035  CurveTime                          N
+  0008,0040  DataSetType                        N
+  0008,0041  DataSetSubtype                     N
+  0008,0042  NuclearMedicineSeriesType          N
+  0008,0050  AccessionNumber                    N
+  0008,0052  Query-RetrieveLevel                N
+  0008,0054  RetrieveAETitle                    N
+  0008,0056  InstanceAvailability               N
+  0008,0058  FailedSOPInstanceUIDList           N
+  0008,0060  Modality                           N
+  0008,0061  ModalitiesInStudy                  N
+  0008,0062  SOPClassesInStudy                  N
+  0008,0064  ConversionType                     N
+  0008,0068  PresentationIntentType             N
+  0008,0070  Manufacturer                       N
+  0008,0080  InstitutionName                    N
+  0008,0081  InstitutionAddress                 N
+  0008,0082  InstitutionCodeSequence            N
+  0008,0090  ReferringPhysiciansName            N
+  0008,0092  ReferringPhysiciansAddress         N
+  0008,0094  ReferringPhysiciansTelephoneNumber N
+  0008,0096  ReferringPhysicianIDSequence       N
+  0008,0100  CodeValue                          N
+  0008,0102  CodingSchemeDesignator             N
+  0008,0103  CodingSchemeVersion                N
+  0008,0104  CodeMeaning                        N
+  0008,0105  MappingResource                    N
+  0008,0106  ContextGroupVersion                N
+  0008,0107  ContextGroupLocalVersion           N
+  0008,010B  ContextGroupExtensionFlag          N
+  0008,010C  CodingSchemeUID                    N
+  0008,010D  ContextGroupExtensionCreatorUID    N
+  0008,010F  ContextIdentifier                  N
+  0008,0110  CodingSchemeIDSequence             N
+  0008,0112  CodingSchemeRegistry               N
+  0008,0114  CodingSchemeExternalID             N
+  0008,0115  CodingSchemeName                   N
+  0008,0116  ResponsibleOrganization            N
+  0008,0201  TimezoneOffsetFromUTC              N
+  0008,1000  NetworkID                          N
+  0008,1010  StationName                        N
+  0008,1030  StudyDescription                   N
+  0008,1032  ProcedureCodeSequence              N
+  0008,103E  SeriesDescription                  N
+  0008,1040  InstitutionalDepartmentName        N
+  0008,1048  PhysicianOfRecord                  N
+  0008,1049  PhysicianOfRecordIDSequence        N
+  0008,1050  PerformingPhysiciansName           N
+  0008,1052  PerformingPhysicianIDSequence      N
+  0008,1060  NameOfPhysicianReadingStudy        N
+  0008,1062  PhysicianReadingStudyIDSequence    N
+  0008,1070  OperatorsName                      N
+  0008,1072  OperatorIDSequence                 N
+  0008,1080  AdmittingDiagnosesDescription      N
+  0008,1084  AdmittingDiagnosesCodeSequence     N
+  0008,1090  ManufacturersModelName             N
+  0008,1100  ReferencedResultsSequence          N
+  0008,1110  ReferencedStudySequence            N
+  0008,1111  ReferencedProcedureStepSequence    N
+  0008,1115  ReferencedSeriesSequence           N
+  0008,1120  ReferencedPatientSequence          N
+  0008,1125  ReferencedVisitSequence            N
+  0008,1130  ReferencedOverlaySequence          N
+  0008,113A  ReferencedWaveformSequence         N
+  0008,1140  ReferencedImageSequence            N
+  0008,1145  ReferencedCurveSequence            N
+  0008,114A  ReferencedInstanceSequence         N
+  0008,1150  ReferencedSOPClassUID              N
+  0008,1155  ReferencedSOPInstanceUID           N
+  0008,115A  SOPClassesSupported                N
+  0008,1160  ReferencedFrameNumber              N
+  0008,1195  TransactionUID                     N
+  0008,1197  FailureReason                      N
+  0008,1198  FailedSOPSequence                  N
+  0008,1199  ReferencedSOPSequence              N
+  0008,1200  OtherReferencedStudiesSequence     N
+  0008,1250  RelatedSeriesSequence              N
+  0008,2110  LossyImageCompression              N
+  0008,2111  DerivationDescription              N
+  0008,2112  SourceImageSequence                N
+  0008,2120  StageName                          N
+  0008,2122  StageNumber                        N
+  0008,2124  NumberOfStages                     N
+  0008,2127  ViewName                           N
+  0008,2128  ViewNumber                         N
+  0008,2129  NumberOfEventTimers                N
+  0008,212A  NumberOfViewsInStage               N
+  0008,2130  EventElapsedTime                   N
+  0008,2132  EventTimerName                     N
+  0008,2142  StartTrim                          N
+  0008,2143  StopTrim                           N
+  0008,2144  RecommendedDisplayFrameRate        N
+  0008,2200  TransducerPosition                 N
+  0008,2204  TransducerOrientation              N
+  0008,2208  AnatomicStructure                  N
+  0008,2218  AnatomicRegionSequence             N
+  0008,2220  AnatomicRegionModifierSequence     N
+  0008,2228  PrimaryAnatomicStructureSequence   N
+  0008,2229  AnatomicStructureOrRegionSequence  N
+  0008,2230  AnatomicStructureModifierSequence  N
+  0008,2240  TransducerPositionSequence         N
+  0008,2242  TransducerPositionModifierSequence N
+  0008,2244  TransducerOrientationSequence      N
+  0008,2246  TransducerOrientationModifierSeq   N
+  0008,3001  AlternateRepresentationSequence    N
+  0008,4000  IdentifyingComments                N
+  0008,9007  FrameType                          N
+  0008,9092  ReferencedImageEvidenceSequence    N
+  0008,9121  ReferencedRawDataSequence          N
+  0008,9123  CreatorVersionUID                  N
+  0008,9124  DerivationImageSequence            N
+  0008,9154  SourceImageEvidenceSequence        N
+  0008,9205  PixelPresentation                  N
+  0008,9206  VolumetricProperties               N
+  0008,9207  VolumeBasedCalculationTechnique    N
+  0008,9208  ComplexImageComponent              N
+  0008,9209  AcquisitionContrast                N
+  0008,9215  DerivationCodeSequence             N
+  0008,9237  GrayscalePresentationStateSequence N
+  0010,0000  PatientGroupLength                 N
+  0010,0010  PatientsName                       N
+  0010,0020  PatientID                          N
+  0010,0021  IssuerOfPatientID                  N
+  0010,0030  PatientsBirthDate                  N
+  0010,0032  PatientsBirthTime                  N
+  0010,0040  PatientsSex                        N
+  0010,0050  PatientsInsurancePlanCodeSequence  N
+  0010,0101  PatientsPrimaryLanguageCodeSeq     N
+  0010,0102  PatientsPrimaryLanguageCodeModSeq  N
+  0010,1000  OtherPatientIDs                    N
+  0010,1001  OtherPatientNames                  N
+  0010,1005  PatientsBirthName                  N
+  0010,1010  PatientsAge                        N
+  0010,1020  PatientsSize                       N
+  0010,1030  PatientsWeight                     N
+  0010,1040  PatientsAddress                    N
+  0010,1050  InsurancePlanIdentification        N
+  0010,1060  PatientsMothersBirthName           N
+  0010,1080  MilitaryRank                       N
+  0010,1081  BranchOfService                    N
+  0010,1090  MedicalRecordLocator               N
+  0010,2000  MedicalAlerts                      N
+  0010,2110  ContrastAllergies                  N
+  0010,2150  CountryOfResidence                 N
+  0010,2152  RegionOfResidence                  N
+  0010,2154  PatientsTelephoneNumbers           N
+  0010,2160  EthnicGroup                        N
+  0010,2180  Occupation                         N
+  0010,21A0  SmokingStatus                      N
+  0010,21B0  AdditionalPatientHistory           N
+  0010,21C0  PregnancyStatus                    N
+  0010,21D0  LastMenstrualDate                  N
+  0010,21F0  PatientsReligiousPreference        N
+  0010,4000  PatientComments                    N
+  0012,0010  ClinicalTrialSponsorName           N
+  0012,0020  ClinicalTrialProtocolID            N
+  0012,0021  ClinicalTrialProtocolName          N
+  0012,0030  ClinicalTrialSiteID                N
+  0012,0031  ClinicalTrialSiteName              N
+  0012,0040  ClinicalTrialSubjectID             N
+  0012,0042  ClinicalTrialSubjectReadingID      N
+  0012,0050  ClinicalTrialTimePointID           N
+  0012,0051  ClinicalTrialTimePointDescription  N
+  0012,0060  ClinicalTrialCoordinatingCenter    N
+  0018,0000  AcquisitionGroupLength             N
+  0018,0010  Contrast-BolusAgent                N
+  0018,0012  Contrast-BolusAgentSequence        N
+  0018,0014  Contrast-BolusAdministrationRoute  N
+  0018,0015  BodyPartExamined                   N
+  0018,0020  ScanningSequence                   N
+  0018,0021  SequenceVariant                    N
+  0018,0022  ScanOptions                        N
+  0018,0023  MRAcquisitionType                  N
+  0018,0024  SequenceName                       N
+  0018,0025  AngioFlag                          N
+  0018,0026  InterventionDrugInformationSeq     N
+  0018,0027  InterventionDrugStopTime           N
+  0018,0028  InterventionDrugDose               N
+  0018,0029  InterventionDrugSequence           N
+  0018,002A  AdditionalDrugSequence             N
+  0018,0030  Radionuclide                       N
+  0018,0031  Radiopharmaceutical                N
+  0018,0032  EnergyWindowCenterline             N
+  0018,0033  EnergyWindowTotalWidth             N
+  0018,0034  InterventionDrugName               N
+  0018,0035  InterventionDrugStartTime          N
+  0018,0036  InterventionSequence               N
+  0018,0037  TherapyType                        N
+  0018,0038  InterventionStatus                 N
+  0018,0039  TherapyDescription                 N
+  0018,003A  InterventionDescription            N
+  0018,0040  CineRate                           N
+  0018,0050  SliceThickness                     N
+  0018,0060  KVP                                N
+  0018,0070  CountsAccumulated                  N
+  0018,0071  AcquisitionTerminationCondition    N
+  0018,0072  EffectiveDuration                  N
+  0018,0073  AcquisitionStartCondition          N
+  0018,0074  AcquisitionStartConditionData      N
+  0018,0075  AcquisitionEndConditionData        N
+  0018,0080  RepetitionTime                     N
+  0018,0081  EchoTime                           N
+  0018,0082  InversionTime                      N
+  0018,0083  NumberOfAverages                   N
+  0018,0084  ImagingFrequency                   N
+  0018,0085  ImagedNucleus                      N
+  0018,0086  EchoNumber                         N
+  0018,0087  MagneticFieldStrength              N
+  0018,0088  SpacingBetweenSlices               N
+  0018,0089  NumberOfPhaseEncodingSteps         N
+  0018,0090  DataCollectionDiameter             N
+  0018,0091  EchoTrainLength                    N
+  0018,0093  PercentSampling                    N
+  0018,0094  PercentPhaseFieldOfView            N
+  0018,0095  PixelBandwidth                     N
+  0018,1000  DeviceSerialNumber                 N
+  0018,1004  PlateID                            N
+  0018,1010  SecondaryCaptureDeviceID           N
+  0018,1011  HardcopyCreationDeviceID           N
+  0018,1012  DateOfSecondaryCapture             N
+  0018,1014  TimeOfSecondaryCapture             N
+  0018,1016  SecondaryCaptureDeviceManufacturer N
+  0018,1017  HardcopyDeviceManufacturer         N
+  0018,1018  SecondaryCaptureDeviceModelName    N
+  0018,1019  SecondaryCaptureDeviceSoftwareVers N
+  0018,101A  HardcopyDeviceSoftwareVersion      N
+  0018,101B  HardcopyDeviceModelName            N
+  0018,1020  SoftwareVersion                    N
+  0018,1022  VideoImageFormatAcquired           N
+  0018,1023  DigitalImageFormatAcquired         N
+  0018,1030  ProtocolName                       N
+  0018,1040  Contrast-BolusRoute                N
+  0018,1041  Contrast-BolusVolume               N
+  0018,1042  Contrast-BolusStartTime            N
+  0018,1043  Contrast-BolusStopTime             N
+  0018,1044  Contrast-BolusTotalDose            N
+  0018,1045  SyringeCounts                      N
+  0018,1046  ContrastFlowRate                   N
+  0018,1047  ContrastFlowDuration               N
+  0018,1048  Contrast-BolusIngredient           N
+  0018,1049  Contrast-BolusConcentration        N
+  0018,1050  SpatialResolution                  N
+  0018,1060  TriggerTime                        N
+  0018,1061  TriggerSourceOrType                N
+  0018,1062  NominalInterval                    N
+  0018,1063  FrameTime                          N
+  0018,1064  FramingType                        N
+  0018,1065  FrameTimeVector                    N
+  0018,1066  FrameDelay                         N
+  0018,1067  ImageTriggerDelay                  N
+  0018,1068  MultiplexGroupTimeOffset           N
+  0018,1069  TriggerTimeOffset                  N
+  0018,106A  SynchronizationTrigger             N
+  0018,106C  SynchronizationChannel             N
+  0018,106E  TriggerSamplePosition              N
+  0018,1070  RadiopharmaceuticalRoute           N
+  0018,1071  RadiopharmaceuticalVolume          N
+  0018,1072  RadiopharmaceuticalStartTime       N
+  0018,1073  RadiopharmaceuticalStopTime        N
+  0018,1074  RadionuclideTotalDose              N
+  0018,1075  RadionuclideHalfLife               N
+  0018,1076  RadionuclidePositronFraction       N
+  0018,1077  RadiopharmaceuticalSpecActivity    N
+  0018,1080  BeatRejectionFlag                  N
+  0018,1081  LowRRValue                         N
+  0018,1082  HighRRValue                        N
+  0018,1083  IntervalsAcquired                  N
+  0018,1084  IntervalsRejected                  N
+  0018,1085  PVCRejection                       N
+  0018,1086  SkipBeats                          N
+  0018,1088  HeartRate                          N
+  0018,1090  CardiacNumberOfImages              N
+  0018,1094  TriggerWindow                      N
+  0018,1100  ReconstructionDiameter             N
+  0018,1110  DistanceSourceToDetector           N
+  0018,1111  DistanceSourceToPatient            N
+  0018,1114  EstimatedRadiographicMagnification N
+  0018,1120  Gantry-DetectorTilt                N
+  0018,1121  Gantry-DetectorSlew                N
+  0018,1130  TableHeight                        N
+  0018,1131  TableTraverse                      N
+  0018,1134  TableMotion                        N
+  0018,1135  TableVerticalIncrement             N
+  0018,1136  TableLateralIncrement              N
+  0018,1137  TableLongitudinalIncrement         N
+  0018,1138  TableAngle                         N
+  0018,113A  TableType                          N
+  0018,1140  RotationDirection                  N
+  0018,1141  AngularPosition                    N
+  0018,1142  RadialPosition                     N
+  0018,1143  ScanArc                            N
+  0018,1144  AngularStep                        N
+  0018,1145  CenterOfRotationOffset             N
+  0018,1146  RotationOffset                     N
+  0018,1147  FieldOfViewShape                   N
+  0018,1149  FieldOfViewDimensions              N
+  0018,1150  ExposureTime                       N
+  0018,1151  XRayTubeCurrent                    N
+  0018,1152  Exposure                           N
+  0018,1153  ExposureInMicroAmpSec              N
+  0018,1154  AveragePulseWidth                  N
+  0018,1155  RadiationSetting                   N
+  0018,1156  RectificationType                  N
+  0018,115A  RadiationMode                      N
+  0018,115E  ImageAreaDoseProduct               N
+  0018,1160  FilterType                         N
+  0018,1161  TypeOfFilters                      N
+  0018,1162  IntensifierSize                    N
+  0018,1164  ImagerPixelSpacing                 N
+  0018,1166  Grid                               N
+  0018,1170  GeneratorPower                     N
+  0018,1180  Collimator-GridName                N
+  0018,1181  CollimatorType                     N
+  0018,1182  FocalDistance                      N
+  0018,1183  XFocusCenter                       N
+  0018,1184  YFocusCenter                       N
+  0018,1190  FocalSpot                          N
+  0018,1191  AnodeTargetMaterial                N
+  0018,11A0  BodyPartThickness                  N
+  0018,11A2  CompressionForce                   N
+  0018,1200  DateOfLastCalibration              N
+  0018,1201  TimeOfLastCalibration              N
+  0018,1210  ConvolutionKernel                  N
+  0018,1240  Upper-LowerPixelValues             N
+  0018,1242  ActualFrameDuration                N
+  0018,1243  CountRate                          N
+  0018,1244  PreferredPlaybackSequencing        N
+  0018,1250  ReceiveCoilName                    N
+  0018,1251  TransmitCoilName                   N
+  0018,1260  PlateType                          N
+  0018,1261  PhosphorType                       N
+  0018,1300  ScanVelocity                       N
+  0018,1301  WholeBodyTechnique                 N
+  0018,1302  ScanLength                         N
+  0018,1310  AcquisitionMatrix                  N
+  0018,1312  InPlanePhaseEncodingDirection      N
+  0018,1314  FlipAngle                          N
+  0018,1315  VariableFlipAngleFlag              N
+  0018,1316  SAR                                N
+  0018,1318  DB-Dt                              N
+  0018,1400  AcquisitionDeviceProcessingDescr   N
+  0018,1401  AcquisitionDeviceProcessingCode    N
+  0018,1402  CassetteOrientation                N
+  0018,1403  CassetteSize                       N
+  0018,1404  ExposuresonPlate                   N
+  0018,1405  RelativeXRayExposure               N
+  0018,1450  ColumnAngulation                   N
+  0018,1460  TomoLayerHeight                    N
+  0018,1470  TomoAngle                          N
+  0018,1480  TomoTime                           N
+  0018,1490  TomoType                           N
+  0018,1491  TomoClass                          N
+  0018,1495  NumberOfTomosynthesisSourceImages  N
+  0018,1500  PositionerMotion                   N
+  0018,1508  PositionerType                     N
+  0018,1510  PositionerPrimaryAngle             N
+  0018,1511  PositionerSecondaryAngle           N
+  0018,1520  PositionerPrimaryAngleIncrement    N
+  0018,1521  PositionerSecondaryAngleIncrement  N
+  0018,1530  DetectorPrimaryAngle               N
+  0018,1531  DetectorSecondaryAngle             N
+  0018,1600  ShutterShape                       N
+  0018,1602  ShutterLeftVerticalEdge            N
+  0018,1604  ShutterRightVerticalEdge           N
+  0018,1606  ShutterUpperHorizontalEdge         N
+  0018,1608  ShutterLowerHorizontalEdge         N
+  0018,1610  CenterOfCircularShutter            N
+  0018,1612  RadiusOfCircularShutter            N
+  0018,1620  VerticesOfPolygonalShutter         N
+  0018,1622  ShutterPresentationValue           N
+  0018,1623  ShutterOverlayGroup                N
+  0018,1700  CollimatorShape                    N
+  0018,1702  CollimatorLeftVerticalEdge         N
+  0018,1704  CollimatorRightVerticalEdge        N
+  0018,1706  CollimatorUpperHorizontalEdge      N
+  0018,1708  CollimatorLowerHorizontalEdge      N
+  0018,1710  CenterOfCircularCollimator         N
+  0018,1712  RadiusOfCircularCollimator         N
+  0018,1720  VerticesOfPolygonalCollimator      N
+  0018,1800  AcquisitionTimeSynchronized        N
+  0018,1801  TimeSource                         N
+  0018,1802  TimeDistributionProtocol           N
+  0018,1803  NTPSourceAddress                   N
+  0018,2001  PageNumberVector                   N
+  0018,2002  FrameLabelVector                   N
+  0018,2003  FramePrimaryAngleVector            N
+  0018,2004  FrameSecondaryAngleVector          N
+  0018,2005  SliceLocationVector                N
+  0018,2006  DisplayWindowLabelVector           N
+  0018,2010  NominalScannedPixelSpacing         N
+  0018,2020  DigitizingDeviceTransportDirection N
+  0018,2030  RotationOfScannedFilm              N
+  0018,3100  IVUSAcquisition                    N
+  0018,3101  IVUSPullbackRate                   N
+  0018,3102  IVUSGatedRate                      N
+  0018,3103  IVUSPullbackStartFrameNumber       N
+  0018,3104  IVUSPullbackStopFrameNumber        N
+  0018,3105  LesionNumber                       N
+  0018,4000  AcquisitionComments                N
+  0018,5000  OutputPower                        N
+  0018,5010  TransducerData                     N
+  0018,5012  FocusDepth                         N
+  0018,5020  ProcessingFunction                 N
+  0018,5021  PostprocessingFunction             N
+  0018,5022  MechanicalIndex                    N
+  0018,5024  BoneThermalIndex                   N
+  0018,5026  CranialThermalIndex                N
+  0018,5027  SoftTissueThermalIndex             N
+  0018,5028  SoftTissueFocusThermalIndex        N
+  0018,5029  SoftTissueSurfaceThermalIndex      N
+  0018,5030  DynamicRange                       N
+  0018,5040  TotalGain                          N
+  0018,5050  DepthOfScanField                   N
+  0018,5100  PatientPosition                    N
+  0018,5101  ViewPosition                       N
+  0018,5104  ProjectionEponymousNameCodeSeq     N
+  0018,5210  ImageTransformationMatrix          N
+  0018,5212  ImageTranslationVector             N
+  0018,6000  Sensitivity                        N
+  0018,6011  SequenceOfUltrasoundRegions        N
+  0018,6012  RegionSpatialFormat                N
+  0018,6014  RegionDataType                     N
+  0018,6016  RegionFlags                        N
+  0018,6018  RegionLocationMinX0                N
+  0018,601A  RegionLocationMinY0                N
+  0018,601C  RegionLocationMaxX1                N
+  0018,601E  RegionLocationMaxY1                N
+  0018,6020  ReferencePixelX0                   N
+  0018,6022  ReferencePixelY0                   N
+  0018,6024  PhysicalUnitsXDirection            N
+  0018,6026  PhysicalUnitsYDirection            N
+  0018,6028  ReferencePixelPhysicalValueX       N
+  0018,602A  ReferencePixelPhysicalValueY       N
+  0018,602C  PhysicalDeltaX                     N
+  0018,602E  PhysicalDeltaY                     N
+  0018,6030  TransducerFrequency                N
+  0018,6031  TransducerType                     N
+  0018,6032  PulseRepetitionFrequency           N
+  0018,6034  DopplerCorrectionAngle             N
+  0018,6036  SteeringAngle                      N
+  0018,6038  DopplerSampleVolumeXPositionUL     N
+  0018,6039  DopplerSampleVolumeXPosition       N
+  0018,603A  DopplerSampleVolumeYPositionUL     N
+  0018,603B  DopplerSampleVolumeYPosition       N
+  0018,603C  TMLinePositionX0UL                 N
+  0018,603D  TMLinePositionX0                   N
+  0018,603E  TMLinePositionY0UL                 N
+  0018,603F  TMLinePositionY0                   N
+  0018,6040  TMLinePositionX1UL                 N
+  0018,6041  TMLinePositionX1                   N
+  0018,6042  TMLinePositionY1UL                 N
+  0018,6043  TMLinePositionY1                   N
+  0018,6044  PixelComponentOrganization         N
+  0018,6046  PixelComponentMask                 N
+  0018,6048  PixelComponentRangeStart           N
+  0018,604A  PixelComponentRangeStop            N
+  0018,604C  PixelComponentPhysicalUnits        N
+  0018,604E  PixelComponentDataType             N
+  0018,6050  NumberOfTableBreakPoints           N
+  0018,6052  TableOfXBreakPoints                N
+  0018,6054  TableOfYBreakPoints                N
+  0018,6056  NumberOfTableEntries               N
+  0018,6058  TableOfPixelValues                 N
+  0018,605A  TableOfParameterValues             N
+  0018,6060  RWaveTimeVector                    N
+  0018,7000  DetectorConditionsNominalFlag      N
+  0018,7001  DetectorTemperature                N
+  0018,7004  DetectorType                       N
+  0018,7005  DetectorConfiguration              N
+  0018,7006  DetectorDescription                N
+  0018,7008  DetectorMode                       N
+  0018,700A  DetectorID                         N
+  0018,700C  DateOfLastDetectorCalibration      N
+  0018,700E  TimeOfLastDetectorCalibration      N
+  0018,7010  DetectorExposuresSinceCalibration  N
+  0018,7011  DetectorExposuresSinceManufactured N
+  0018,7012  DetectorTimeSinceLastExposure      N
+  0018,7014  DetectorActiveTime                 N
+  0018,7016  DetectorActiveOffsetFromExposure   N
+  0018,701A  DetectorBinning                    N
+  0018,7020  DetectorElementPhysicalSize        N
+  0018,7022  DetectorElementSpacing             N
+  0018,7024  DetectorActiveShape                N
+  0018,7026  DetectorActiveDimensions           N
+  0018,7028  DetectorActiveOrigin               N
+  0018,702A  DetectorManufacturerName           N
+  0018,702B  DetectorManufacturersModelName     N
+  0018,7030  FieldOfViewOrigin                  N
+  0018,7032  FieldOfViewRotation                N
+  0018,7034  FieldOfViewHorizontalFlip          N
+  0018,7040  GridAbsorbingMaterial              N
+  0018,7041  GridSpacingMaterial                N
+  0018,7042  GridThickness                      N
+  0018,7044  GridPitch                          N
+  0018,7046  GridAspectRatio                    N
+  0018,7048  GridPeriod                         N
+  0018,704C  GridFocalDistance                  N
+  0018,7050  FilterMaterial                     N
+  0018,7052  FilterThicknessMinimum             N
+  0018,7054  FilterThicknessMaximum             N
+  0018,7060  ExposureControlMode                N
+  0018,7062  ExposureControlModeDescription     N
+  0018,7064  ExposureStatus                     N
+  0018,7065  PhototimerSetting                  N
+  0018,8150  ExposureTimeInMicroSec             N
+  0018,8151  XRayTubeCurrentInMicroAmps         N
+  0018,9004  ContentQualification               N
+  0018,9005  PulseSequenceName                  N
+  0018,9006  MRImagingModifierSequence          N
+  0018,9008  EchoPulseSequence                  N
+  0018,9009  InversionRecovery                  N
+  0018,9010  FlowCompensation                   N
+  0018,9011  MultipleSpinEcho                   N
+  0018,9012  MultiPlanarExcitation              N
+  0018,9014  PhaseContrast                      N
+  0018,9015  TimeOfFlightContrast               N
+  0018,9016  Spoiling                           N
+  0018,9017  SteadyStatePulseSequence           N
+  0018,9018  EchoPlanarPulseSequence            N
+  0018,9019  TagAngleFirstAxis                  N
+  0018,9020  MagnetizationTransfer              N
+  0018,9021  T2Preparation                      N
+  0018,9022  BloodSignalNulling                 N
+  0018,9024  SaturationRecovery                 N
+  0018,9025  SpectrallySelectedSuppression      N
+  0018,9026  SpectrallySelectedExcitation       N
+  0018,9027  SpatialPreSaturation               N
+  0018,9028  Tagging                            N
+  0018,9029  OversamplingPhase                  N
+  0018,9030  TagSpacingFirstDimension           N
+  0018,9032  GeometryOfKSpaceTraversal          N
+  0018,9033  SegmentedKSpaceTraversal           N
+  0018,9034  RectilinearPhaseEncodeReordering   N
+  0018,9035  TagThickness                       N
+  0018,9036  PartialFourierDirection            N
+  0018,9037  CardiacSynchronizationTechnique    N
+  0018,9041  ReceiveCoilManufacturerName        N
+  0018,9042  MRReceiveCoilSequence              N
+  0018,9043  ReceiveCoilType                    N
+  0018,9044  QuadratureReceiveCoil              N
+  0018,9045  MultiCoilDefinitionSequence        N
+  0018,9046  MultiCoilConfiguration             N
+  0018,9047  MultiCoilElementName               N
+  0018,9048  MultiCoilElementUsed               N
+  0018,9049  MRTransmitCoilSequence             N
+  0018,9050  TransmitCoilManufacturerName       N
+  0018,9051  TransmitCoilType                   N
+  0018,9052  SpectralWidth                      N
+  0018,9053  ChemicalShiftReference             N
+  0018,9054  VolumeLocalizationTechnique        N
+  0018,9058  MRAcquisitionFrequencyEncodeSteps  N
+  0018,9059  Decoupling                         N
+  0018,9060  DecoupledNucleus                   N
+  0018,9061  DecouplingFrequency                N
+  0018,9062  DecouplingMethod                   N
+  0018,9063  DecouplingChemicalShiftReference   N
+  0018,9064  KSpaceFiltering                    N
+  0018,9065  TimeDomainFiltering                N
+  0018,9066  NumberOfZeroFills                  N
+  0018,9067  BaselineCorrection                 N
+  0018,9069  ParallelReductionFactorInPlane     N
+  0018,9070  CardiacRRIntervalSpecified         N
+  0018,9073  AcquisitionDuration                N
+  0018,9074  FrameAcquisitionDatetime           N
+  0018,9075  DiffusionDirectionality            N
+  0018,9076  DiffusionGradientDirectionSequence N
+  0018,9077  ParallelAcquisition                N
+  0018,9078  ParallelAcquisitionTechnique       N
+  0018,9079  InversionTimes                     N
+  0018,9080  MetaboliteMapDescription           N
+  0018,9081  PartialFourier                     N
+  0018,9082  EffectiveEchoTime                  N
+  0018,9083  MetaboliteMapCodeSequence          N
+  0018,9084  ChemicalShiftSequence              N
+  0018,9085  CardiacSignalSource                N
+  0018,9087  DiffusionBValue                    N
+  0018,9089  DiffusionGradientOrientation       N
+  0018,9090  VelocityEncodingDirection          N
+  0018,9091  VelocityEncodingMinimumValue       N
+  0018,9093  NumberOfKSpaceTrajectories         N
+  0018,9094  CoverageOfKSpace                   N
+  0018,9095  SpectroscopyAcquisitionPhaseRows   N
+  0018,9098  TransmitterFrequency               N
+  0018,9100  ResonantNucleus                    N
+  0018,9101  FrequencyCorrection                N
+  0018,9103  MRSpectroscopyFOV-GeometrySequence N
+  0018,9104  SlabThickness                      N
+  0018,9105  SlabOrientation                    N
+  0018,9106  MidSlabPosition                    N
+  0018,9107  MRSpatialSaturationSequence        N
+  0018,9112  MRTimingAndRelatedParametersSeq    N
+  0018,9114  MREchoSequence                     N
+  0018,9115  MRModifierSequence                 N
+  0018,9117  MRDiffusionSequence                N
+  0018,9118  CardiacTriggerSequence             N
+  0018,9119  MRAveragesSequence                 N
+  0018,9125  MRFOV-GeometrySequence             N
+  0018,9126  VolumeLocalizationSequence         N
+  0018,9127  SpectroscopyAcquisitionDataColumns N
+  0018,9147  DiffusionAnisotropyType            N
+  0018,9151  FrameReferenceDatetime             N
+  0018,9152  MRMetaboliteMapSequence            N
+  0018,9155  ParallelReductionFactorOutOfPlane  N
+  0018,9159  SpectroscopyOutOfPlanePhaseSteps   N
+  0018,9166  BulkMotionStatus                   N
+  0018,9168  ParallelReductionFactSecondInPlane N
+  0018,9169  CardiacBeatRejectionTechnique      N
+  0018,9170  RespiratoryMotionCompTechnique     N
+  0018,9171  RespiratorySignalSource            N
+  0018,9172  BulkMotionCompensationTechnique    N
+  0018,9173  BulkMotionSignalSource             N
+  0018,9174  ApplicableSafetyStandardAgency     N
+  0018,9175  ApplicableSafetyStandardDescr      N
+  0018,9176  OperatingModeSequence              N
+  0018,9177  OperatingModeType                  N
+  0018,9178  OperatingMode                      N
+  0018,9179  SpecificAbsorptionRateDefinition   N
+  0018,9180  GradientOutputType                 N
+  0018,9181  SpecificAbsorptionRateValue        N
+  0018,9182  GradientOutput                     N
+  0018,9183  FlowCompensationDirection          N
+  0018,9184  TaggingDelay                       N
+  0018,9195  ChemicalShiftsMinIntegrateLimitHz  N
+  0018,9196  ChemicalShiftsMaxIntegrateLimitHz  N
+  0018,9197  MRVelocityEncodingSequence         N
+  0018,9198  FirstOrderPhaseCorrection          N
+  0018,9199  WaterReferencedPhaseCorrection     N
+  0018,9200  MRSpectroscopyAcquisitionType      N
+  0018,9214  RespiratoryCyclePosition           N
+  0018,9217  VelocityEncodingMaximumValue       N
+  0018,9218  TagSpacingSecondDimension          N
+  0018,9219  TagAngleSecondAxis                 N
+  0018,9220  FrameAcquisitionDuration           N
+  0018,9226  MRImageFrameTypeSequence           N
+  0018,9227  MRSpectroscopyFrameTypeSequence    N
+  0018,9231  MRAcqPhaseEncodingStepsInPlane     N
+  0018,9232  MRAcqPhaseEncodingStepsOutOfPlane  N
+  0018,9234  SpectroscopyAcqPhaseColumns        N
+  0018,9236  CardiacCyclePosition               N
+  0018,9239  SpecificAbsorptionRateSequence     N
+  0018,9240  RFEchoTrainLength                  N
+  0018,9241  GradientEchoTrainLength            N
+  0018,9295  ChemicalShiftsMinIntegrateLimitPPM N
+  0018,9296  ChemicalShiftsMaxIntegrateLimitPPM N
+  0018,9301  CTAcquisitionTypeSequence          N
+  0018,9302  AcquisitionType                    N
+  0018,9303  TubeAngle                          N
+  0018,9304  CTAcquisitionDetailsSequence       N
+  0018,9305  RevolutionTime                     N
+  0018,9306  SingleCollimationWidth             N
+  0018,9307  TotalCollimationWidth              N
+  0018,9308  CTTableDynamicsSequence            N
+  0018,9309  TableSpeed                         N
+  0018,9310  TableFeedPerRotation               N
+  0018,9311  SpiralPitchFactor                  N
+  0018,9312  CTGeometrySequence                 N
+  0018,9313  DataCollectionCenterPatient        N
+  0018,9314  CTReconstructionSequence           N
+  0018,9315  ReconstructionAlgorithm            N
+  0018,9316  ConvolutionKernelGroup             N
+  0018,9317  ReconstructionFieldOfView          N
+  0018,9318  ReconstructionTargetCenterPatient  N
+  0018,9319  ReconstructionAngle                N
+  0018,9320  ImageFilter                        N
+  0018,9321  CTExposureSequence                 N
+  0018,9322  ReconstructionPixelSpacing         N
+  0018,9323  ExposureModulationType             N
+  0018,9324  EstimatedDoseSaving                N
+  0018,9325  CTXRayDetailsSequence              N
+  0018,9326  CTPositionSequence                 N
+  0018,9327  TablePosition                      N
+  0018,9328  ExposureTimeInMilliSec             N
+  0018,9329  CTImageFrameTypeSequence           N
+  0018,9330  XRayTubeCurrentInMilliAmps         N
+  0018,9332  ExposureInMilliAmpSec              N
+  0018,9333  ConstantVolumeFlag                 N
+  0018,9334  FluoroscopyFlag                    N
+  0018,9335  SourceToDataCollectionCenterDist   N
+  0018,9337  Contrast-BolusAgentNumber          N
+  0018,9338  Contrast-BolusIngredientCodeSeq    N
+  0018,9340  ContrastAdministrationProfileSeq   N
+  0018,9341  Contrast-BolusUsageSequence        N
+  0018,9342  Contrast-BolusAgentAdministered    N
+  0018,9343  Contrast-BolusAgentDetected        N
+  0018,9344  Contrast-BolusAgentPhase           N
+  0018,9345  CTDIvol                            N
+  0018,A001  ContributingEquipmentSequence      N
+  0018,A002  ContributionDateTime               N
+  0018,A003  ContributionDescription            N
+  0020,0000  RelationshipGroupLength            N
+  0020,000D  StudyInstanceUID                   N
+  0020,000E  SeriesInstanceUID                  N
+  0020,0010  StudyID                            N
+  0020,0011  SeriesNumber                       N
+  0020,0012  AcquisitionNumber                  N
+  0020,0013  InstanceNumber                     N
+  0020,0014  IsotopeNumber                      N
+  0020,0015  PhaseNumber                        N
+  0020,0016  IntervalNumber                     N
+  0020,0017  TimeSlotNumber                     N
+  0020,0018  AngleNumber                        N
+  0020,0019  ItemNumber                         N
+  0020,0020  PatientOrientation                 N
+  0020,0022  OverlayNumber                      N
+  0020,0024  CurveNumber                        N
+  0020,0026  LookupTableNumber                  N
+  0020,0030  ImagePosition                      N
+  0020,0032  ImagePositionPatient               N
+  0020,0035  ImageOrientation                   N
+  0020,0037  ImageOrientationPatient            N
+  0020,0050  Location                           N
+  0020,0052  FrameOfReferenceUID                N
+  0020,0060  Laterality                         N
+  0020,0062  ImageLaterality                    N
+  0020,0070  ImageGeometryType                  N
+  0020,0080  MaskingImage                       N
+  0020,0100  TemporalPositionIdentifier         N
+  0020,0105  NumberOfTemporalPositions          N
+  0020,0110  TemporalResolution                 N
+  0020,0200  SynchronizationFrameOfReferenceUID N
+  0020,1000  SeriesInStudy                      N
+  0020,1001  AcquisitionsInSeries               N
+  0020,1002  ImagesInAcquisition                N
+  0020,1004  AcquisitionsInStudy                N
+  0020,1020  Reference                          N
+  0020,1040  PositionReferenceIndicator         N
+  0020,1041  SliceLocation                      N
+  0020,1070  OtherStudyNumbers                  N
+  0020,1200  NumberOfPatientRelatedStudies      N
+  0020,1202  NumberOfPatientRelatedSeries       N
+  0020,1204  NumberOfPatientRelatedInstances    N
+  0020,1206  NumberOfStudyRelatedSeries         N
+  0020,1208  NumberOfStudyRelatedInstances      N
+  0020,1209  NumberOfSeriesRelatedInstances     N
+  0020,31xx  SourceImageIDs                     N
+  0020,3401  ModifyingDeviceID                  N
+  0020,3402  ModifiedImageID                    N
+  0020,3403  ModifiedImageDate                  N
+  0020,3404  ModifyingDeviceManufacturer        N
+  0020,3405  ModifiedImageTime                  N
+  0020,3406  ModifiedImageDescription           N
+  0020,4000  ImageComments                      N
+  0020,5000  OriginalImageIdentification        N
+  0020,5002  OriginalImageIdentNomenclature     N
+  0020,9056  StackID                            N
+  0020,9057  InStackPositionNumber              N
+  0020,9071  FrameAnatomySequence               N
+  0020,9072  FrameLaterality                    N
+  0020,9111  FrameContentSequence               N
+  0020,9113  PlanePositionSequence              N
+  0020,9116  PlaneOrientationSequence           N
+  0020,9128  TemporalPositionIndex              N
+  0020,9153  TriggerDelayTime                   N
+  0020,9156  FrameAcquisitionNumber             N
+  0020,9157  DimensionIndexValues               N
+  0020,9158  FrameComments                      N
+  0020,9161  ConcatenationUID                   N
+  0020,9162  InconcatenationNumber              N
+  0020,9163  InconcatenationTotalNumber         N
+  0020,9164  DimensionOrganizationUID           N
+  0020,9165  DimensionIndexPointer              N
+  0020,9167  FunctionalGroupPointer             N
+  0020,9213  DimensionIndexPrivateCreator       N
+  0020,9221  DimensionOrganizationSequence      N
+  0020,9222  DimensionIndexSequence             N
+  0020,9228  ConcatenationFrameOffsetNumber     N
+  0020,9238  FunctionalGroupPrivateCreator      N
+  0022,0001  LightPathFilterPassThroughWavelen  N
+  0022,0002  LightPathFilterPassBand            N
+  0022,0003  ImagePathFilterPassThroughWavelen  N
+  0022,0004  ImagePathFilterPassBand            N
+  0022,0005  PatientEyeMovementCommanded        N
+  0022,0006  PatientEyeMovementCommandCodeSeq   N
+  0022,0007  SphericalLensPower                 N
+  0022,0008  CylinderLensPower                  N
+  0022,0009  CylinderAxis                       N
+  0022,000A  EmmetropicMagnification            N
+  0022,000B  IntraOcularPressure                N
+  0022,000C  HorizontalFieldOfView              N
+  0022,000D  PupilDilated                       N
+  0022,000E  DegreeOfDilation                   N
+  0022,0010  StereoBaselineAngle                N
+  0022,0011  StereoBaselineDisplacement         N
+  0022,0012  StereoHorizontalPixelOffset        N
+  0022,0013  StereoVerticalPixelOffset          N
+  0022,0014  StereoRotation                     N
+  0022,0015  AcquisitionDeviceTypeCodeSequence  N
+  0022,0016  IlluminationTypeCodeSequence       N
+  0022,0017  LightPathFilterTypeStackCodeSeq    N
+  0022,0018  ImagePathFilterTypeStackCodeSeq    N
+  0022,0019  LensesCodeSequence                 N
+  0022,001A  ChannelDescriptionCodeSequence     N
+  0022,001B  RefractiveStateSequence            N
+  0022,001C  MydriaticAgentCodeSequence         N
+  0022,001D  RelativeImagePositionCodeSequence  N
+  0022,0020  StereoPairsSequence                N
+  0022,0021  LeftImageSequence                  N
+  0022,0022  RightImageSequence                 N
+  0028,0000  ImagePresentationGroupLength       N
+  0028,0002  SamplesPerPixel                    N
+  0028,0003  SamplesPerPixelUsed                N
+  0028,0004  PhotometricInterpretation          N
+  0028,0005  ImageDimensions                    N
+  0028,0006  PlanarConfiguration                N
+  0028,0008  NumberOfFrames                     N
+  0028,0009  FrameIncrementPointer              N
+  0028,000A  FrameDimensionPointer              N
+  0028,0010  Rows                               N
+  0028,0011  Columns                            N
+  0028,0012  Planes                             N
+  0028,0014  UltrasoundColorDataPresent         N
+  0028,0030  PixelSpacing                       N
+  0028,0031  ZoomFactor                         N
+  0028,0032  ZoomCenter                         N
+  0028,0034  PixelAspectRatio                   N
+  0028,0040  ImageFormat                        N
+  0028,0050  ManipulatedImage                   N
+  0028,0051  CorrectedImage                     N
+  0028,0060  CompressionCode                    N
+  0028,0100  BitsAllocated                      N
+  0028,0101  BitsStored                         N
+  0028,0102  HighBit                            N
+  0028,0103  PixelRepresentation                N
+  0028,0104  SmallestValidPixelValue            N
+  0028,0105  LargestValidPixelValue             N
+  0028,0106  SmallestImagePixelValue            N
+  0028,0107  LargestImagePixelValue             N
+  0028,0108  SmallestPixelValueInSeries         N
+  0028,0109  LargestPixelValueInSeries          N
+  0028,0110  SmallestImagePixelValueInPlane     N
+  0028,0111  LargestImagePixelValueInPlane      N
+  0028,0120  PixelPaddingValue                  N
+  0028,0200  ImageLocation                      N
+  0028,0300  QualityControlImage                N
+  0028,0301  BurnedInAnnotation                 N
+  0028,1040  PixelIntensityRelationship         N
+  0028,1041  PixelIntensityRelationshipSign     N
+  0028,1050  WindowCenter                       N
+  0028,1051  WindowWidth                        N
+  0028,1052  RescaleIntercept                   N
+  0028,1053  RescaleSlope                       N
+  0028,1054  RescaleType                        N
+  0028,1055  WindowCenterAndWidthExplanation    N
+  0028,1080  GrayScale                          N
+  0028,1090  RecommendedViewingMode             N
+  0028,1100  GrayLookupTableDescriptor          N
+  0028,1101  RedPaletteColorTableDescriptor     N
+  0028,1102  GreenPaletteColorTableDescriptor   N
+  0028,1103  BluePaletteColorTableDescriptor    N
+  0028,1199  PaletteColorTableUID               N
+  0028,1200  GrayLookupTableData                N
+  0028,1201  RedPaletteColorTableData           N
+  0028,1202  GreenPaletteColorTableData         N
+  0028,1203  BluePaletteColorTableData          N
+  0028,1221  SegmentedRedColorTableData         N
+  0028,1222  SegmentedGreenColorTableData       N
+  0028,1223  SegmentedBlueColorTableData        N
+  0028,1300  ImplantPresent                     N
+  0028,1350  PartialView                        N
+  0028,1351  PartialViewDescription             N
+  0028,2110  LossyImageCompression              N
+  0028,2112  LossyImageCompressionRatio         N
+  0028,2114  LossyImageCompressionMethod        N
+  0028,3000  ModalityLUTSequence                N
+  0028,3002  LUTDescriptor                      N
+  0028,3003  LUTExplanation                     N
+  0028,3004  ModalityLUTType                    N
+  0028,3006  LUTData                            N
+  0028,3010  VOILUTSequence                     N
+  0028,3110  SoftcopyVOILUTSequence             N
+  0028,4000  ImagePresentationComments          N
+  0028,5000  BiPlaneAcquisitionSequence         N
+  0028,6010  RepresentativeFrameNumber          N
+  0028,6020  FrameNumbersOfInterestFOI          N
+  0028,6022  FrameOfInterestDescription         N
+  0028,6023  FrameOfInterestType                N
+  0028,6030  MaskPointers                       N
+  0028,6040  RWavePointer                       N
+  0028,6100  MaskSubtractionSequence            N
+  0028,6101  MaskOperation                      N
+  0028,6102  ApplicableFrameRange               N
+  0028,6110  MaskFrameNumbers                   N
+  0028,6112  ContrastFrameAveraging             N
+  0028,6114  MaskSubPixelShift                  N
+  0028,6120  TIDOffset                          N
+  0028,6190  MaskOperationExplanation           N
+  0028,9001  DataPointRows                      N
+  0028,9002  DataPointColumns                   N
+  0028,9003  SignalDomainColumns                N
+  0028,9099  LargestMonochromePixelValue        N
+  0028,9108  DataRepresentation                 N
+  0028,9110  PixelMeasuresSequence              N
+  0028,9132  FrameVOILUTSequence                N
+  0028,9145  PixelValueTransformationSequence   N
+  0028,9235  SignalDomainRows                   N
+  0032,0000  StudyGroupLength                   N
+  0032,000A  StudyStatusID                      N
+  0032,000C  StudyPriorityID                    N
+  0032,0012  StudyIDIssuer                      N
+  0032,0032  StudyVerifiedDate                  N
+  0032,0033  StudyVerifiedTime                  N
+  0032,0034  StudyReadDate                      N
+  0032,0035  StudyReadTime                      N
+  0032,1000  ScheduledStudyStartDate            N
+  0032,1001  ScheduledStudyStartTime            N
+  0032,1010  ScheduledStudyStopDate             N
+  0032,1011  ScheduledStudyStopTime             N
+  0032,1020  ScheduledStudyLocation             N
+  0032,1021  ScheduledStudyLocationAETitle      N
+  0032,1030  ReasonForStudy                     N
+  0032,1031  RequestingPhysicianIDSequence      N
+  0032,1032  RequestingPhysician                N
+  0032,1033  RequestingService                  N
+  0032,1040  StudyArrivalDate                   N
+  0032,1041  StudyArrivalTime                   N
+  0032,1050  StudyCompletionDate                N
+  0032,1051  StudyCompletionTime                N
+  0032,1055  StudyComponentStatusID             N
+  0032,1060  RequestedProcedureDescription      N
+  0032,1064  RequestedProcedureCodeSequence     N
+  0032,1070  RequestedContrastAgent             N
+  0032,4000  StudyComments                      N
+  0038,0004  ReferencedPatientAliasSequence     N
+  0038,0008  VisitStatusID                      N
+  0038,0010  AdmissionID                        N
+  0038,0011  IssuerOfAdmissionID                N
+  0038,0016  RouteOfAdmissions                  N
+  0038,001A  ScheduledAdmissionDate             N
+  0038,001B  ScheduledAdmissionTime             N
+  0038,001C  ScheduledDischargeDate             N
+  0038,001D  ScheduledDischargeTime             N
+  0038,001E  ScheduledPatientInstitResidence    N
+  0038,0020  AdmittingDate                      N
+  0038,0021  AdmittingTime                      N
+  0038,0030  DischargeDate                      N
+  0038,0032  DischargeTime                      N
+  0038,0040  DischargeDiagnosisDescription      N
+  0038,0044  DischargeDiagnosisCodeSequence     N
+  0038,0050  SpecialNeeds                       N
+  0038,0300  CurrentPatientLocation             N
+  0038,0400  PatientsInstitutionResidence       N
+  0038,0500  PatientState                       N
+  0038,4000  VisitComments                      N
+  003A,0004  WaveformOriginality                N
+  003A,0005  NumberOfWaveformChannels           N
+  003A,0010  NumberOfWaveformSamples            N
+  003A,001A  SamplingFrequency                  N
+  003A,0020  MultiplexGroupLabel                N
+  003A,0200  ChannelDefinitionSequence          N
+  003A,0202  WaveformChannelNumber              N
+  003A,0203  ChannelLabel                       N
+  003A,0205  ChannelStatus                      N
+  003A,0208  ChannelSourceSequence              N
+  003A,0209  ChannelSourceModifiersSequence     N
+  003A,020A  SourceWaveformSequence             N
+  003A,020C  ChannelDerivationDescription       N
+  003A,0210  ChannelSensitivity                 N
+  003A,0211  ChannelSensitivityUnitsSequence    N
+  003A,0212  ChannelSensitivityCorrectionFactor N
+  003A,0213  ChannelBaseline                    N
+  003A,0214  ChannelTimeSkew                    N
+  003A,0215  ChannelSampleSkew                  N
+  003A,0218  ChannelOffset                      N
+  003A,021A  WaveformBitsStored                 N
+  003A,0220  FilterLowFrequency                 N
+  003A,0221  FilterHighFrequency                N
+  003A,0222  NotchFilterFrequency               N
+  003A,0223  NotchFilterBandwidth               N
+  003A,0300  MultiplexAudioChannelsDescrCodeSeq N
+  003A,0301  ChannelIdentificationCode          N
+  003A,0302  ChannelMode                        N
+  0040,0001  ScheduledStationAETitle            N
+  0040,0002  ScheduledProcedureStepStartDate    N
+  0040,0003  ScheduledProcedureStepStartTime    N
+  0040,0004  ScheduledProcedureStepEndDate      N
+  0040,0005  ScheduledProcedureStepEndTime      N
+  0040,0006  ScheduledPerformingPhysiciansName  N
+  0040,0007  ScheduledProcedureStepDescription  N
+  0040,0008  ScheduledProtocolCodeSequence      N
+  0040,0009  ScheduledProcedureStepID           N
+  0040,000A  StageCodeSequence                  N
+  0040,000B  ScheduledPerformingPhysicianIDSeq  N
+  0040,0010  ScheduledStationName               N
+  0040,0011  ScheduledProcedureStepLocation     N
+  0040,0012  PreMedication                      N
+  0040,0020  ScheduledProcedureStepStatus       N
+  0040,0100  ScheduledProcedureStepSequence     N
+  0040,0220  ReferencedNonImageCompositeSOPSeq  N
+  0040,0241  PerformedStationAETitle            N
+  0040,0242  PerformedStationName               N
+  0040,0243  PerformedLocation                  N
+  0040,0244  PerformedProcedureStepStartDate    N
+  0040,0245  PerformedProcedureStepStartTime    N
+  0040,0250  PerformedProcedureStepEndDate      N
+  0040,0251  PerformedProcedureStepEndTime      N
+  0040,0252  PerformedProcedureStepStatus       N
+  0040,0253  PerformedProcedureStepID           N
+  0040,0254  PerformedProcedureStepDescription  N
+  0040,0255  PerformedProcedureTypeDescription  N
+  0040,0260  PerformedProtocolCodeSequence      N
+  0040,0270  ScheduledStepAttributesSequence    N
+  0040,0275  RequestAttributesSequence          N
+  0040,0280  CommentsOnPerformedProcedureStep   N
+  0040,0281  ProcStepDiscontinueReasonCodeSeq   N
+  0040,0293  QuantitySequence                   N
+  0040,0294  Quantity                           N
+  0040,0295  MeasuringUnitsSequence             N
+  0040,0296  BillingItemSequence                N
+  0040,0300  TotalTimeOfFluoroscopy             N
+  0040,0301  TotalNumberOfExposures             N
+  0040,0302  EntranceDose                       N
+  0040,0303  ExposedArea                        N
+  0040,0306  DistanceSourceToEntrance           N
+  0040,0307  DistanceSourceToSupport            N
+  0040,030E  ExposureDoseSequence               N
+  0040,0310  CommentsOnRadiationDose            N
+  0040,0312  XRayOutput                         N
+  0040,0314  HalfValueLayer                     N
+  0040,0316  OrganDose                          N
+  0040,0318  OrganExposed                       N
+  0040,0320  BillingProcedureStepSequence       N
+  0040,0321  FilmConsumptionSequence            N
+  0040,0324  BillingSuppliesAndDevicesSequence  N
+  0040,0330  ReferencedProcedureStepSequence    N
+  0040,0340  PerformedSeriesSequence            N
+  0040,0400  CommentsOnScheduledProcedureStep   N
+  0040,0440  ProtocolContextSequence            N
+  0040,0441  ContentItemModifierSequence        N
+  0040,050A  SpecimenAccessionNumber            N
+  0040,0550  SpecimenSequence                   N
+  0040,0551  SpecimenIdentifier                 N
+  0040,0555  AcquisitionContextSequence         N
+  0040,0556  AcquisitionContextDescription      N
+  0040,059A  SpecimenTypeCodeSequence           N
+  0040,06FA  SlideIdentifier                    N
+  0040,071A  ImageCenterPointCoordinatesSeq     N
+  0040,072A  XOffsetInSlideCoordinateSystem     N
+  0040,073A  YOffsetInSlideCoordinateSystem     N
+  0040,074A  ZOffsetInSlideCoordinateSystem     N
+  0040,08D8  PixelSpacingSequence               N
+  0040,08DA  CoordinateSystemAxisCodeSequence   N
+  0040,08EA  MeasurementUnitsCodeSequence       N
+  0040,1001  RequestedProcedureID               N
+  0040,1002  ReasonForRequestedProcedure        N
+  0040,1003  RequestedProcedurePriority         N
+  0040,1004  PatientTransportArrangements       N
+  0040,1005  RequestedProcedureLocation         N
+  0040,1006  PlacerOrderNumber-Procedure        N
+  0040,1007  FillerOrderNumber-Procedure        N
+  0040,1008  ConfidentialityCode                N
+  0040,1009  ReportingPriority                  N
+  0040,100A  ReasonForRequestedProcedureCodeSeq N
+  0040,1010  NamesOfIntendedRecipientsOfResults N
+  0040,1011  IntendedRecipientsOfResultsIDSeq   N
+  0040,1101  PersonIdentificationCodeSequence   N
+  0040,1102  PersonsAddress                     N
+  0040,1103  PersonsTelephoneNumbers            N
+  0040,1400  RequestedProcedureComments         N
+  0040,2001  ReasonForImagingServiceRequest     N
+  0040,2004  IssueDateOfImagingServiceRequest   N
+  0040,2005  IssueTimeOfImagingServiceRequest   N
+  0040,2006  PlacerOrderNum-ImagingServiceReq   N
+  0040,2007  FillerOrderNum-ImagingServiceReq   N
+  0040,2008  OrderEnteredBy                     N
+  0040,2009  OrderEnterersLocation              N
+  0040,2010  OrderCallbackPhoneNumber           N
+  0040,2016  PlacerOrderNum-ImagingServiceReq   N
+  0040,2017  FillerOrderNum-ImagingServiceReq   N
+  0040,2400  ImagingServiceRequestComments      N
+  0040,3001  ConfidentialityOnPatientDataDescr  N
+  0040,4001  GenPurposeScheduledProcStepStatus  N
+  0040,4002  GenPurposePerformedProcStepStatus  N
+  0040,4003  GenPurposeSchedProcStepPriority    N
+  0040,4004  SchedProcessingApplicationsCodeSeq N
+  0040,4005  SchedProcedureStepStartDateAndTime N
+  0040,4006  MultipleCopiesFlag                 N
+  0040,4007  PerformedProcessingAppsCodeSeq     N
+  0040,4009  HumanPerformerCodeSequence         N
+  0040,4010  SchedProcStepModificationDateTime  N
+  0040,4011  ExpectedCompletionDateAndTime      N
+  0040,4015  ResultingGenPurposePerfProcStepSeq N
+  0040,4016  RefGenPurposeSchedProcStepSeq      N
+  0040,4018  ScheduledWorkitemCodeSequence      N
+  0040,4019  PerformedWorkitemCodeSequence      N
+  0040,4020  InputAvailabilityFlag              N
+  0040,4021  InputInformationSequence           N
+  0040,4022  RelevantInformationSequence        N
+  0040,4023  RefGenPurSchedProcStepTransUID     N
+  0040,4025  ScheduledStationNameCodeSequence   N
+  0040,4026  ScheduledStationClassCodeSequence  N
+  0040,4027  SchedStationGeographicLocCodeSeq   N
+  0040,4028  PerformedStationNameCodeSequence   N
+  0040,4029  PerformedStationClassCodeSequence  N
+  0040,4030  PerformedStationGeogLocCodeSeq     N
+  0040,4031  RequestedSubsequentWorkItemCodeSeq N
+  0040,4032  NonDICOMOutputCodeSequence         N
+  0040,4033  OutputInformationSequence          N
+  0040,4034  ScheduledHumanPerformersSequence   N
+  0040,4035  ActualHumanPerformersSequence      N
+  0040,4036  HumanPerformersOrganization        N
+  0040,4037  HumanPerformersName                N
+  0040,8302  EntranceDoseInMilliGy              N
+  0040,9096  RealWorldValueMappingSequence      N
+  0040,9210  LUTLabel                           N
+  0040,9211  RealWorldValueLastValueMapped      N
+  0040,9212  RealWorldValueLUTData              N
+  0040,9216  RealWorldValueFirstValueMapped     N
+  0040,9224  RealWorldValueIntercept            N
+  0040,9225  RealWorldValueSlope                N
+  0040,A010  RelationshipType                   N
+  0040,A027  VerifyingOrganization              N
+  0040,A030  VerificationDateTime               N
+  0040,A032  ObservationDateTime                N
+  0040,A040  ValueType                          N
+  0040,A043  ConceptNameCodeSequence            N
+  0040,A050  ContinuityOfContent                N
+  0040,A073  VerifyingObserverSequence          N
+  0040,A075  VerifyingObserverName              N
+  0040,A088  VerifyingObserverIdentCodeSequence N
+  0040,A0B0  ReferencedWaveformChannels         N
+  0040,A120  DateTime                           N
+  0040,A121  Date                               N
+  0040,A122  Time                               N
+  0040,A123  PersonName                         N
+  0040,A124  UID                                N
+  0040,A130  TemporalRangeType                  N
+  0040,A132  ReferencedSamplePositions          N
+  0040,A136  ReferencedFrameNumbers             N
+  0040,A138  ReferencedTimeOffsets              N
+  0040,A13A  ReferencedDatetime                 N
+  0040,A160  TextValue                          N
+  0040,A168  ConceptCodeSequence                N
+  0040,A170  PurposeOfReferenceCodeSequence     N
+  0040,A180  AnnotationGroupNumber              N
+  0040,A195  ModifierCodeSequence               N
+  0040,A300  MeasuredValueSequence              N
+  0040,A301  NumericValueQualifierCodeSequence  N
+  0040,A30A  NumericValue                       N
+  0040,A360  PredecessorDocumentsSequence       N
+  0040,A370  ReferencedRequestSequence          N
+  0040,A372  PerformedProcedureCodeSequence     N
+  0040,A375  CurrentRequestedProcEvidenceSeq    N
+  0040,A385  PertinentOtherEvidenceSequence     N
+  0040,A491  CompletionFlag                     N
+  0040,A492  CompletionFlagDescription          N
+  0040,A493  VerificationFlag                   N
+  0040,A504  ContentTemplateSequence            N
+  0040,A525  IdenticalDocumentsSequence         N
+  0040,A730  ContentSequence                    N
+  0040,B020  AnnotationSequence                 N
+  0040,DB00  TemplateIdentifier                 N
+  0040,DB06  TemplateVersion                    N
+  0040,DB07  TemplateLocalVersion               N
+  0040,DB0B  TemplateExtensionFlag              N
+  0040,DB0C  TemplateExtensionOrganizationUID   N
+  0040,DB0D  TemplateExtensionCreatorUID        N
+  0040,DB73  ReferencedContentItemIdentifier    N
+  0050,0004  CalibrationImage                   N
+  0050,0010  DeviceSequence                     N
+  0050,0014  DeviceLength                       N
+  0050,0016  DeviceDiameter                     N
+  0050,0017  DeviceDiameterUnits                N
+  0050,0018  DeviceVolume                       N
+  0050,0019  InterMarkerDistance                N
+  0050,0020  DeviceDescription                  N
+  0054,0010  EnergyWindowVector                 N
+  0054,0011  NumberOfEnergyWindows              N
+  0054,0012  EnergyWindowInformationSequence    N
+  0054,0013  EnergyWindowRangeSequence          N
+  0054,0014  EnergyWindowLowerLimit             N
+  0054,0015  EnergyWindowUpperLimit             N
+  0054,0016  RadiopharmaceuticalInformationSeq  N
+  0054,0017  ResidualSyringeCounts              N
+  0054,0018  EnergyWindowName                   N
+  0054,0020  DetectorVector                     N
+  0054,0021  NumberOfDetectors                  N
+  0054,0022  DetectorInformationSequence        N
+  0054,0030  PhaseVector                        N
+  0054,0031  NumberOfPhases                     N
+  0054,0032  PhaseInformationSequence           N
+  0054,0033  NumberOfFramesInPhase              N
+  0054,0036  PhaseDelay                         N
+  0054,0038  PauseBetweenFrames                 N
+  0054,0039  PhaseDescription                   N
+  0054,0050  RotationVector                     N
+  0054,0051  NumberOfRotations                  N
+  0054,0052  RotationInformationSequence        N
+  0054,0053  NumberOfFramesInRotation           N
+  0054,0060  RRIntervalVector                   N
+  0054,0061  NumberOfRRIntervals                N
+  0054,0062  GatedInformationSequence           N
+  0054,0063  DataInformationSequence            N
+  0054,0070  TimeSlotVector                     N
+  0054,0071  NumberOfTimeSlots                  N
+  0054,0072  TimeSlotInformationSequence        N
+  0054,0073  TimeSlotTime                       N
+  0054,0080  SliceVector                        N
+  0054,0081  NumberOfSlices                     N
+  0054,0090  AngularViewVector                  N
+  0054,0100  TimeSliceVector                    N
+  0054,0101  NumberOfTimeSlices                 N
+  0054,0200  StartAngle                         N
+  0054,0202  TypeOfDetectorMotion               N
+  0054,0210  TriggerVector                      N
+  0054,0211  NumberOfTriggersInPhase            N
+  0054,0220  ViewCodeSequence                   N
+  0054,0222  ViewModifierCodeSequence           N
+  0054,0300  RadionuclideCodeSequence           N
+  0054,0302  AdministrationRouteCodeSequence    N
+  0054,0304  RadiopharmaceuticalCodeSequence    N
+  0054,0306  CalibrationDataSequence            N
+  0054,0308  EnergyWindowNumber                 N
+  0054,0400  ImageID                            N
+  0054,0410  PatientOrientationCodeSequence     N
+  0054,0412  PatientOrientationModifierCodeSeq  N
+  0054,0414  PatientGantryRelationshipCodeSeq   N
+  0054,0500  SliceProgressionDirection          N
+  0054,1000  SeriesType                         N
+  0054,1001  Units                              N
+  0054,1002  CountsSource                       N
+  0054,1004  ReprojectionMethod                 N
+  0054,1100  RandomsCorrectionMethod            N
+  0054,1101  AttenuationCorrectionMethod        N
+  0054,1102  DecayCorrection                    N
+  0054,1103  ReconstructionMethod               N
+  0054,1104  DetectorLinesOfResponseUsed        N
+  0054,1105  ScatterCorrectionMethod            N
+  0054,1200  AxialAcceptance                    N
+  0054,1201  AxialMash                          N
+  0054,1202  TransverseMash                     N
+  0054,1203  DetectorElementSize                N
+  0054,1210  CoincidenceWindowWidth             N
+  0054,1220  SecondaryCountsType                N
+  0054,1300  FrameReferenceTime                 N
+  0054,1310  PrimaryCountsAccumulated           N
+  0054,1311  SecondaryCountsAccumulated         N
+  0054,1320  SliceSensitivityFactor             N
+  0054,1321  DecayFactor                        N
+  0054,1322  DoseCalibrationFactor              N
+  0054,1323  ScatterFractionFactor              N
+  0054,1324  DeadTimeFactor                     N
+  0054,1330  ImageIndex                         N
+  0054,1400  CountsIncluded                     N
+  0054,1401  DeadTimeCorrectionFlag             N
+  0060,3000  HistogramSequence                  N
+  0060,3002  HistogramNumberOfBins              N
+  0060,3004  HistogramFirstBinValue             N
+  0060,3006  HistogramLastBinValue              N
+  0060,3008  HistogramBinWidth                  N
+  0060,3010  HistogramExplanation               N
+  0060,3020  HistogramData                      N
+  0070,0001  GraphicAnnotationSequence          N
+  0070,0002  GraphicLayer                       N
+  0070,0003  BoundingBoxAnnotationUnits         N
+  0070,0004  AnchorPointAnnotationUnits         N
+  0070,0005  GraphicAnnotationUnits             N
+  0070,0006  UnformattedTextValue               N
+  0070,0008  TextObjectSequence                 N
+  0070,0009  GraphicObjectSequence              N
+  0070,0010  BoundingBoxTopLeftHandCorner       N
+  0070,0011  BoundingBoxBottomRightHandCorner   N
+  0070,0012  BoundingBoxTextHorizJustification  N
+  0070,0014  AnchorPoint                        N
+  0070,0015  AnchorPointVisibility              N
+  0070,0020  GraphicDimensions                  N
+  0070,0021  NumberOfGraphicPoints              N
+  0070,0022  GraphicData                        N
+  0070,0023  GraphicType                        N
+  0070,0024  GraphicFilled                      N
+  0070,0041  ImageHorizontalFlip                N
+  0070,0042  ImageRotation                      N
+  0070,0052  DisplayedAreaTopLeftHandCorner     N
+  0070,0053  DisplayedAreaBottomRightHandCorner N
+  0070,005A  DisplayedAreaSelectionSequence     N
+  0070,0060  GraphicLayerSequence               N
+  0070,0062  GraphicLayerOrder                  N
+  0070,0066  GraphicLayerRecDisplayGraysclValue N
+  0070,0067  GraphicLayerRecDisplayRGBValue     N
+  0070,0068  GraphicLayerDescription            N
+  0070,0080  ContentLabel                       N
+  0070,0081  ContentDescription                 N
+  0070,0082  PresentationCreationDate           N
+  0070,0083  PresentationCreationTime           N
+  0070,0084  ContentCreatorsName                N
+  0070,0100  PresentationSizeMode               N
+  0070,0101  PresentationPixelSpacing           N
+  0070,0102  PresentationPixelAspectRatio       N
+  0070,0103  PresentationPixelMagRatio          N
+  0070,0306  ShapeType                          N
+  0070,0308  RegistrationSequence               N
+  0070,0309  MatrixRegistrationSequence         N
+  0070,030A  MatrixSequence                     N
+  0070,030C  FrameOfRefTransformationMatrixType N
+  0070,030D  RegistrationTypeCodeSequence       N
+  0070,030F  FiducialDescription                N
+  0070,0310  FiducialIdentifier                 N
+  0070,0311  FiducialIdentifierCodeSequence     N
+  0070,0312  ContourUncertaintyRadius           N
+  0070,0314  UsedFiducialsSequence              N
+  0070,0318  GraphicCoordinatesDataSequence     N
+  0070,031A  FiducialUID                        N
+  0070,031C  FiducialSetSequence                N
+  0070,031E  FiducialSequence                   N
+  0088,0130  StorageMediaFileSetID              N
+  0088,0140  StorageMediaFileSetUID             N
+  0088,0200  IconImageSequence                  N
+  0088,0904  TopicTitle                         N
+  0088,0906  TopicSubject                       N
+  0088,0910  TopicAuthor                        N
+  0088,0912  TopicKeyWords                      N
+  0100,0410  SOPInstanceStatus                  N
+  0100,0420  SOPAuthorizationDateAndTime        N
+  0100,0424  SOPAuthorizationComment            N
+  0100,0426  AuthorizationEquipmentCertNumber   N
+  0400,0005  MACIDNumber                        N
+  0400,0010  MACCalculationTransferSyntaxUID    N
+  0400,0015  MACAlgorithm                       N
+  0400,0020  DataElementsSigned                 N
+  0400,0100  DigitalSignatureUID                N
+  0400,0105  DigitalSignatureDateTime           N
+  0400,0110  CertificateType                    N
+  0400,0115  CertificateOfSigner                N
+  0400,0120  Signature                          N
+  0400,0305  CertifiedTimestampType             N
+  0400,0310  CertifiedTimestamp                 N
+  0400,0500  EncryptedAttributesSequence        N
+  0400,0510  EncryptedContentTransferSyntaxUID  N
+  0400,0520  EncryptedContent                   N
+  0400,0550  ModifiedAttributesSequence         N
+  2000,0010  NumberOfCopies                     N
+  2000,001E  PrinterConfigurationSequence       N
+  2000,0020  PrintPriority                      N
+  2000,0030  MediumType                         N
+  2000,0040  FilmDestination                    N
+  2000,0050  FilmSessionLabel                   N
+  2000,0060  MemoryAllocation                   N
+  2000,0061  MaximumMemoryAllocation            N
+  2000,0062  ColorImagePrintingFlag             N
+  2000,0063  CollationFlag                      N
+  2000,0065  AnnotationFlag                     N
+  2000,0067  ImageOverlayFlag                   N
+  2000,0069  PresentationLUTFlag                N
+  2000,006A  ImageBoxPresentationLUTFlag        N
+  2000,00A0  MemoryBitDepth                     N
+  2000,00A1  PrintingBitDepth                   N
+  2000,00A2  MediaInstalledSequence             N
+  2000,00A4  OtherMediaAvailableSequence        N
+  2000,00A8  SupportedImageDisplayFormatSeq     N
+  2000,0500  ReferencedFilmBoxSequence          N
+  2000,0510  ReferencedStoredPrintSequence      N
+  2010,0010  ImageDisplayFormat                 N
+  2010,0030  AnnotationDisplayFormatID          N
+  2010,0040  FilmOrientation                    N
+  2010,0050  FilmSizeID                         N
+  2010,0052  PrinterResolutionID                N
+  2010,0054  DefaultPrinterResolutionID         N
+  2010,0060  MagnificationType                  N
+  2010,0080  SmoothingType                      N
+  2010,00A6  DefaultMagnificationType           N
+  2010,00A7  OtherMagnificationTypesAvailable   N
+  2010,00A8  DefaultSmoothingType               N
+  2010,00A9  OtherSmoothingTypesAvailable       N
+  2010,0100  BorderDensity                      N
+  2010,0110  EmptyImageDensity                  N
+  2010,0120  MinDensity                         N
+  2010,0130  MaxDensity                         N
+  2010,0140  Trim                               N
+  2010,0150  ConfigurationInformation           N
+  2010,0152  ConfigurationInformationDescr      N
+  2010,0154  MaximumCollatedFilms               N
+  2010,015E  Illumination                       N
+  2010,0160  ReflectedAmbientLight              N
+  2010,0376  PrinterPixelSpacing                N
+  2010,0500  ReferencedFilmSessionSequence      N
+  2010,0510  ReferencedImageBoxSequence         N
+  2010,0520  ReferencedBasicAnnotationBoxSeq    N
+  2020,0010  ImagePosition                      N
+  2020,0020  Polarity                           N
+  2020,0030  RequestedImageSize                 N
+  2020,0040  RequestedDecimate-CropBehavior     N
+  2020,0050  RequestedResolutionID              N
+  2020,00A0  RequestedImageSizeFlag             N
+  2020,00A2  Decimate-CropResult                N
+  2020,0110  BasicGrayscaleImageSequence        N
+  2020,0111  BasicColorImageSequence            N
+  2020,0130  ReferencedImageOverlayBoxSequence  N
+  2020,0140  ReferencedVOILUTBoxSequence        N
+  2030,0010  AnnotationPosition                 N
+  2030,0020  TextString                         N
+  2040,0010  ReferencedOverlayPlaneSequence     N
+  2040,0011  ReferencedOverlayPlaneGroups       N
+  2040,0020  OverlayPixelDataSequence           N
+  2040,0060  OverlayMagnificationType           N
+  2040,0070  OverlaySmoothingType               N
+  2040,0072  OverlayOrImageMagnification        N
+  2040,0074  MagnifyToNumberOfColumns           N
+  2040,0080  OverlayForegroundDensity           N
+  2040,0082  OverlayBackgroundDensity           N
+  2040,0090  OverlayMode                        N
+  2040,0100  ThresholdDensity                   N
+  2040,0500  ReferencedImageBoxSequence         N
+  2050,0010  PresentationLUTSequence            N
+  2050,0020  PresentationLUTShape               N
+  2050,0500  ReferencedPresentationLUTSequence  N
+  2100,0010  PrintJobID                         N
+  2100,0020  ExecutionStatus                    N
+  2100,0030  ExecutionStatusInfo                N
+  2100,0040  CreationDate                       N
+  2100,0050  CreationTime                       N
+  2100,0070  Originator                         N
+  2100,0140  Destination                        N
+  2100,0160  OwnerID                            N
+  2100,0170  NumberOfFilms                      N
+  2100,0500  ReferencedPrintJobSequence         N
+  2110,0010  PrinterStatus                      N
+  2110,0020  PrinterStatusInfo                  N
+  2110,0030  PrinterName                        N
+  2110,0099  PrintQueueID                       N
+  2120,0010  QueueStatus                        N
+  2120,0050  PrintJobDescriptionSequence        N
+  2120,0070  ReferencedPrintJobSequence         N
+  2130,0010  PrintManagementCapabilitiesSeq     N
+  2130,0015  PrinterCharacteristicsSequence     N
+  2130,0030  FilmBoxContentSequence             N
+  2130,0040  ImageBoxContentSequence            N
+  2130,0050  AnnotationContentSequence          N
+  2130,0060  ImageOverlayBoxContentSequence     N
+  2130,0080  PresentationLUTContentSequence     N
+  2130,00A0  ProposedStudySequence              N
+  2130,00C0  OriginalImageSequence              N
+  2200,0001  LabelFromInfoExtractedFromInstance N
+  2200,0002  LabelText                          N
+  2200,0003  LabelStyleSelection                N
+  2200,0004  MediaDisposition                   N
+  2200,0005  BarcodeValue                       N
+  2200,0006  BarcodeSymbology                   N
+  2200,0007  AllowMediaSplitting                N
+  2200,0008  IncludeNonDICOMObjects             N
+  2200,0009  IncludeDisplayApplication          N
+  2200,000A  SaveCompInstancesAfterMediaCreate  N
+  2200,000B  TotalNumberMediaPiecesCreated      N
+  2200,000C  RequestedMediaApplicationProfile   N
+  2200,000D  ReferencedStorageMediaSequence     N
+  2200,000E  FailureAttributes                  N
+  2200,000F  AllowLossyCompression              N
+  2200,0020  RequestPriority                    N
+  3002,0002  RTImageLabel                       N
+  3002,0003  RTImageName                        N
+  3002,0004  RTImageDescription                 N
+  3002,000A  ReportedValuesOrigin               N
+  3002,000C  RTImagePlane                       N
+  3002,000D  XRayImageReceptorTranslation       N
+  3002,000E  XRayImageReceptorAngle             N
+  3002,0010  RTImageOrientation                 N
+  3002,0011  ImagePlanePixelSpacing             N
+  3002,0012  RTImagePosition                    N
+  3002,0020  RadiationMachineName               N
+  3002,0022  RadiationMachineSAD                N
+  3002,0024  RadiationMachineSSD                N
+  3002,0026  RTImageSID                         N
+  3002,0028  SourceToReferenceObjectDistance    N
+  3002,0029  FractionNumber                     N
+  3002,0030  ExposureSequence                   N
+  3002,0032  MetersetExposure                   N
+  3002,0034  DiaphragmPosition                  N
+  3002,0040  FluenceMapSequence                 N
+  3002,0041  FluenceDataSource                  N
+  3002,0042  FluenceDataScale                   N
+  3004,0001  DVHType                            N
+  3004,0002  DoseUnits                          N
+  3004,0004  DoseType                           N
+  3004,0006  DoseComment                        N
+  3004,0008  NormalizationPoint                 N
+  3004,000A  DoseSummationType                  N
+  3004,000C  GridFrameOffsetVector              N
+  3004,000E  DoseGridScaling                    N
+  3004,0010  RTDoseROISequence                  N
+  3004,0012  DoseValue                          N
+  3004,0014  TissueHeterogeneityCorrection      N
+  3004,0040  DVHNormalizationPoint              N
+  3004,0042  DVHNormalizationDoseValue          N
+  3004,0050  DVHSequence                        N
+  3004,0052  DVHDoseScaling                     N
+  3004,0054  DVHVolumeUnits                     N
+  3004,0056  DVHNumberOfBins                    N
+  3004,0058  DVHData                            N
+  3004,0060  DVHReferencedROISequence           N
+  3004,0062  DVHROIContributionType             N
+  3004,0070  DVHMinimumDose                     N
+  3004,0072  DVHMaximumDose                     N
+  3004,0074  DVHMeanDose                        N
+  3006,0002  StructureSetLabel                  N
+  3006,0004  StructureSetName                   N
+  3006,0006  StructureSetDescription            N
+  3006,0008  StructureSetDate                   N
+  3006,0009  StructureSetTime                   N
+  3006,0010  ReferencedFrameOfReferenceSequence N
+  3006,0012  RTReferencedStudySequence          N
+  3006,0014  RTReferencedSeriesSequence         N
+  3006,0016  ContourImageSequence               N
+  3006,0020  StructureSetROISequence            N
+  3006,0022  ROINumber                          N
+  3006,0024  ReferencedFrameOfReferenceUID      N
+  3006,0026  ROIName                            N
+  3006,0028  ROIDescription                     N
+  3006,002A  ROIDisplayColor                    N
+  3006,002C  ROIVolume                          N
+  3006,0030  RTRelatedROISequence               N
+  3006,0033  RTROIRelationship                  N
+  3006,0036  ROIGenerationAlgorithm             N
+  3006,0038  ROIGenerationDescription           N
+  3006,0039  ROIContourSequence                 N
+  3006,0040  ContourSequence                    N
+  3006,0042  ContourGeometricType               N
+  3006,0044  ContourSlabThickness               N
+  3006,0045  ContourOffsetVector                N
+  3006,0046  NumberOfContourPoints              N
+  3006,0048  ContourNumber                      N
+  3006,0049  AttachedContours                   N
+  3006,0050  ContourData                        N
+  3006,0080  RTROIObservationsSequence          N
+  3006,0082  ObservationNumber                  N
+  3006,0084  ReferencedROINumber                N
+  3006,0085  ROIObservationLabel                N
+  3006,0086  RTROIIdentificationCodeSequence    N
+  3006,0088  ROIObservationDescription          N
+  3006,00A0  RelatedRTROIObservationsSequence   N
+  3006,00A4  RTROIInterpretedType               N
+  3006,00A6  ROIInterpreter                     N
+  3006,00B0  ROIPhysicalPropertiesSequence      N
+  3006,00B2  ROIPhysicalProperty                N
+  3006,00B4  ROIPhysicalPropertyValue           N
+  3006,00C0  FrameOfReferenceRelationshipSeq    N
+  3006,00C2  RelatedFrameOfReferenceUID         N
+  3006,00C4  FrameOfReferenceTransformType      N
+  3006,00C6  FrameOfReferenceTransformMatrix    N
+  3006,00C8  FrameOfReferenceTransformComment   N
+  3008,0010  MeasuredDoseReferenceSequence      N
+  3008,0012  MeasuredDoseDescription            N
+  3008,0014  MeasuredDoseType                   N
+  3008,0016  MeasuredDoseValue                  N
+  3008,0020  TreatmentSessionBeamSequence       N
+  3008,0022  CurrentFractionNumber              N
+  3008,0024  TreatmentControlPointDate          N
+  3008,0025  TreatmentControlPointTime          N
+  3008,002A  TreatmentTerminationStatus         N
+  3008,002B  TreatmentTerminationCode           N
+  3008,002C  TreatmentVerificationStatus        N
+  3008,0030  ReferencedTreatmentRecordSequence  N
+  3008,0032  SpecifiedPrimaryMeterset           N
+  3008,0033  SpecifiedSecondaryMeterset         N
+  3008,0036  DeliveredPrimaryMeterset           N
+  3008,0037  DeliveredSecondaryMeterset         N
+  3008,003A  SpecifiedTreatmentTime             N
+  3008,003B  DeliveredTreatmentTime             N
+  3008,0040  ControlPointDeliverySequence       N
+  3008,0042  SpecifiedMeterset                  N
+  3008,0044  DeliveredMeterset                  N
+  3008,0048  DoseRateDelivered                  N
+  3008,0050  TreatmentSummaryCalcDoseRefSeq     N
+  3008,0052  CumulativeDoseToDoseReference      N
+  3008,0054  FirstTreatmentDate                 N
+  3008,0056  MostRecentTreatmentDate            N
+  3008,005A  NumberOfFractionsDelivered         N
+  3008,0060  OverrideSequence                   N
+  3008,0062  OverrideParameterPointer           N
+  3008,0064  MeasuredDoseReferenceNumber        N
+  3008,0066  OverrideReason                     N
+  3008,0070  CalculatedDoseReferenceSequence    N
+  3008,0072  CalculatedDoseReferenceNumber      N
+  3008,0074  CalculatedDoseReferenceDescription N
+  3008,0076  CalculatedDoseReferenceDoseValue   N
+  3008,0078  StartMeterset                      N
+  3008,007A  EndMeterset                        N
+  3008,0080  ReferencedMeasuredDoseReferenceSeq N
+  3008,0082  ReferencedMeasuredDoseReferenceNum N
+  3008,0090  ReferencedCalculatedDoseRefSeq     N
+  3008,0092  ReferencedCalculatedDoseRefNumber  N
+  3008,00A0  BeamLimitingDeviceLeafPairsSeq     N
+  3008,00B0  RecordedWedgeSequence              N
+  3008,00C0  RecordedCompensatorSequence        N
+  3008,00D0  RecordedBlockSequence              N
+  3008,00E0  TreatmentSummaryMeasuredDoseRefSeq N
+  3008,0100  RecordedSourceSequence             N
+  3008,0105  SourceSerialNumber                 N
+  3008,0110  TreatmentSessionAppSetupSeq        N
+  3008,0116  ApplicationSetupCheck              N
+  3008,0120  RecordedBrachyAccessoryDeviceSeq   N
+  3008,0122  ReferencedBrachyAccessoryDeviceNum N
+  3008,0130  RecordedChannelSequence            N
+  3008,0132  SpecifiedChannelTotalTime          N
+  3008,0134  DeliveredChannelTotalTime          N
+  3008,0136  SpecifiedNumberOfPulses            N
+  3008,0138  DeliveredNumberOfPulses            N
+  3008,013A  SpecifiedPulseRepetitionInterval   N
+  3008,013C  DeliveredPulseRepetitionInterval   N
+  3008,0140  RecordedSourceApplicatorSequence   N
+  3008,0142  ReferencedSourceApplicatorNumber   N
+  3008,0150  RecordedChannelShieldSequence      N
+  3008,0152  ReferencedChannelShieldNumber      N
+  3008,0160  BrachyControlPointDeliveredSeq     N
+  3008,0162  SafePositionExitDate               N
+  3008,0164  SafePositionExitTime               N
+  3008,0166  SafePositionReturnDate             N
+  3008,0168  SafePositionReturnTime             N
+  3008,0200  CurrentTreatmentStatus             N
+  3008,0202  TreatmentStatusComment             N
+  3008,0220  FractionGroupSummarySequence       N
+  3008,0223  ReferencedFractionNumber           N
+  3008,0224  FractionGroupType                  N
+  3008,0230  BeamStopperPosition                N
+  3008,0240  FractionStatusSummarySequence      N
+  3008,0250  TreatmentDate                      N
+  3008,0251  TreatmentTime                      N
+  300A,0002  RTPlanLabel                        N
+  300A,0003  RTPlanName                         N
+  300A,0004  RTPlanDescription                  N
+  300A,0006  RTPlanDate                         N
+  300A,0007  RTPlanTime                         N
+  300A,0009  TreatmentProtocols                 N
+  300A,000A  TreatmentIntent                    N
+  300A,000B  TreatmentSites                     N
+  300A,000C  RTPlanGeometry                     N
+  300A,000E  PrescriptionDescription            N
+  300A,0010  DoseReferenceSequence              N
+  300A,0012  DoseReferenceNumber                N
+  300A,0013  DoseReferenceUID                   N
+  300A,0014  DoseReferenceStructureType         N
+  300A,0015  NominalBeamEnergyUnit              N
+  300A,0016  DoseReferenceDescription           N
+  300A,0018  DoseReferencePointCoordinates      N
+  300A,001A  NominalPriorDose                   N
+  300A,0020  DoseReferenceType                  N
+  300A,0021  ConstraintWeight                   N
+  300A,0022  DeliveryWarningDose                N
+  300A,0023  DeliveryMaximumDose                N
+  300A,0025  TargetMinimumDose                  N
+  300A,0026  TargetPrescriptionDose             N
+  300A,0027  TargetMaximumDose                  N
+  300A,0028  TargetUnderdoseVolumeFraction      N
+  300A,002A  OrganAtRiskFullVolumeDose          N
+  300A,002B  OrganAtRiskLimitDose               N
+  300A,002C  OrganAtRiskMaximumDose             N
+  300A,002D  OrganAtRiskOverdoseVolumeFraction  N
+  300A,0040  ToleranceTableSequence             N
+  300A,0042  ToleranceTableNumber               N
+  300A,0043  ToleranceTableLabel                N
+  300A,0044  GantryAngleTolerance               N
+  300A,0046  BeamLimitingDeviceAngleTolerance   N
+  300A,0048  BeamLimitingDeviceToleranceSeq     N
+  300A,004A  BeamLimitingDevicePositionTol      N
+  300A,004C  PatientSupportAngleTolerance       N
+  300A,004E  TableTopEccentricAngleTolerance    N
+  300A,0051  TableTopVerticalPositionTolerance  N
+  300A,0052  TableTopLongitudinalPositionTol    N
+  300A,0053  TableTopLateralPositionTolerance   N
+  300A,0055  RTPlanRelationship                 N
+  300A,0070  FractionGroupSequence              N
+  300A,0071  FractionGroupNumber                N
+  300A,0072  FractionGroupDescription           N
+  300A,0078  NumberOfFractionsPlanned           N
+  300A,0079  NumberFractionPatternDigitsPerDay  N
+  300A,007A  RepeatFractionCycleLength          N
+  300A,007B  FractionPattern                    N
+  300A,0080  NumberOfBeams                      N
+  300A,0082  BeamDoseSpecificationPoint         N
+  300A,0084  BeamDose                           N
+  300A,0086  BeamMeterset                       N
+  300A,00A0  NumberOfBrachyApplicationSetups    N
+  300A,00A2  BrachyAppSetupDoseSpecPoint        N
+  300A,00A4  BrachyApplicationSetupDose         N
+  300A,00B0  BeamSequence                       N
+  300A,00B2  TreatmentMachineName               N
+  300A,00B3  PrimaryDosimeterUnit               N
+  300A,00B4  SourceAxisDistance                 N
+  300A,00B6  BeamLimitingDeviceSequence         N
+  300A,00B8  RTBeamLimitingDeviceType           N
+  300A,00BA  SourceToBeamLimitingDeviceDistance N
+  300A,00BC  NumberOfLeaf-JawPairs              N
+  300A,00BE  LeafPositionBoundaries             N
+  300A,00C0  BeamNumber                         N
+  300A,00C2  BeamName                           N
+  300A,00C3  BeamDescription                    N
+  300A,00C4  BeamType                           N
+  300A,00C6  RadiationType                      N
+  300A,00C7  HighDoseTechniqueType              N
+  300A,00C8  ReferenceImageNumber               N
+  300A,00CA  PlannedVerificationImageSequence   N
+  300A,00CC  ImagingDeviceSpecificAcqParams     N
+  300A,00CE  TreatmentDeliveryType              N
+  300A,00D0  NumberOfWedges                     N
+  300A,00D1  WedgeSequence                      N
+  300A,00D2  WedgeNumber                        N
+  300A,00D3  WedgeType                          N
+  300A,00D4  WedgeID                            N
+  300A,00D5  WedgeAngle                         N
+  300A,00D6  WedgeFactor                        N
+  300A,00D8  WedgeOrientation                   N
+  300A,00DA  SourceToWedgeTrayDistance          N
+  300A,00E0  NumberOfCompensators               N
+  300A,00E1  MaterialID                         N
+  300A,00E2  TotalCompensatorTrayFactor         N
+  300A,00E3  CompensatorSequence                N
+  300A,00E4  CompensatorNumber                  N
+  300A,00E5  CompensatorID                      N
+  300A,00E6  SourceToCompensatorTrayDistance    N
+  300A,00E7  CompensatorRows                    N
+  300A,00E8  CompensatorColumns                 N
+  300A,00E9  CompensatorPixelSpacing            N
+  300A,00EA  CompensatorPosition                N
+  300A,00EB  CompensatorTransmissionData        N
+  300A,00EC  CompensatorThicknessData           N
+  300A,00ED  NumberOfBoli                       N
+  300A,00EE  CompensatorType                    N
+  300A,00F0  NumberOfBlocks                     N
+  300A,00F2  TotalBlockTrayFactor               N
+  300A,00F4  BlockSequence                      N
+  300A,00F5  BlockTrayID                        N
+  300A,00F6  SourceToBlockTrayDistance          N
+  300A,00F8  BlockType                          N
+  300A,00F9  AccessoryCode                      N
+  300A,00FA  BlockDivergence                    N
+  300A,00FB  BlockMountingPosition              N
+  300A,00FC  BlockNumber                        N
+  300A,00FE  BlockName                          N
+  300A,0100  BlockThickness                     N
+  300A,0102  BlockTransmission                  N
+  300A,0104  BlockNumberOfPoints                N
+  300A,0106  BlockData                          N
+  300A,0107  ApplicatorSequence                 N
+  300A,0108  ApplicatorID                       N
+  300A,0109  ApplicatorType                     N
+  300A,010A  ApplicatorDescription              N
+  300A,010C  CumulativeDoseReferenceCoefficient N
+  300A,010E  FinalCumulativeMetersetWeight      N
+  300A,0110  NumberOfControlPoints              N
+  300A,0111  ControlPointSequence               N
+  300A,0112  ControlPointIndex                  N
+  300A,0114  NominalBeamEnergy                  N
+  300A,0115  DoseRateSet                        N
+  300A,0116  WedgePositionSequence              N
+  300A,0118  WedgePosition                      N
+  300A,011A  BeamLimitingDevicePositionSequence N
+  300A,011C  Leaf-JawPositions                  N
+  300A,011E  GantryAngle                        N
+  300A,011F  GantryRotationDirection            N
+  300A,0120  BeamLimitingDeviceAngle            N
+  300A,0121  BeamLimitingDeviceRotateDirection  N
+  300A,0122  PatientSupportAngle                N
+  300A,0123  PatientSupportRotationDirection    N
+  300A,0124  TableTopEccentricAxisDistance      N
+  300A,0125  TableTopEccentricAngle             N
+  300A,0126  TableTopEccentricRotateDirection   N
+  300A,0128  TableTopVerticalPosition           N
+  300A,0129  TableTopLongitudinalPosition       N
+  300A,012A  TableTopLateralPosition            N
+  300A,012C  IsocenterPosition                  N
+  300A,012E  SurfaceEntryPoint                  N
+  300A,0130  SourceToSurfaceDistance            N
+  300A,0134  CumulativeMetersetWeight           N
+  300A,0180  PatientSetupSequence               N
+  300A,0182  PatientSetupNumber                 N
+  300A,0184  PatientAdditionalPosition          N
+  300A,0190  FixationDeviceSequence             N
+  300A,0192  FixationDeviceType                 N
+  300A,0194  FixationDeviceLabel                N
+  300A,0196  FixationDeviceDescription          N
+  300A,0198  FixationDevicePosition             N
+  300A,01A0  ShieldingDeviceSequence            N
+  300A,01A2  ShieldingDeviceType                N
+  300A,01A4  ShieldingDeviceLabel               N
+  300A,01A6  ShieldingDeviceDescription         N
+  300A,01A8  ShieldingDevicePosition            N
+  300A,01B0  SetupTechnique                     N
+  300A,01B2  SetupTechniqueDescription          N
+  300A,01B4  SetupDeviceSequence                N
+  300A,01B6  SetupDeviceType                    N
+  300A,01B8  SetupDeviceLabel                   N
+  300A,01BA  SetupDeviceDescription             N
+  300A,01BC  SetupDeviceParameter               N
+  300A,01D0  SetupReferenceDescription          N
+  300A,01D2  TableTopVerticalSetupDisplacement  N
+  300A,01D4  TableTopLongitudinalSetupDisplace  N
+  300A,01D6  TableTopLateralSetupDisplacement   N
+  300A,0200  BrachyTreatmentTechnique           N
+  300A,0202  BrachyTreatmentType                N
+  300A,0206  TreatmentMachineSequence           N
+  300A,0210  SourceSequence                     N
+  300A,0212  SourceNumber                       N
+  300A,0214  SourceType                         N
+  300A,0216  SourceManufacturer                 N
+  300A,0218  ActiveSourceDiameter               N
+  300A,021A  ActiveSourceLength                 N
+  300A,0222  SourceEncapsulationNomThickness    N
+  300A,0224  SourceEncapsulationNomTransmission N
+  300A,0226  SourceIsotopeName                  N
+  300A,0228  SourceIsotopeHalfLife              N
+  300A,022A  ReferenceAirKermaRate              N
+  300A,022C  AirKermaRateReferenceDate          N
+  300A,022E  AirKermaRateReferenceTime          N
+  300A,0230  ApplicationSetupSequence           N
+  300A,0232  ApplicationSetupType               N
+  300A,0234  ApplicationSetupNumber             N
+  300A,0236  ApplicationSetupName               N
+  300A,0238  ApplicationSetupManufacturer       N
+  300A,0240  TemplateNumber                     N
+  300A,0242  TemplateType                       N
+  300A,0244  TemplateName                       N
+  300A,0250  TotalReferenceAirKerma             N
+  300A,0260  BrachyAccessoryDeviceSequence      N
+  300A,0262  BrachyAccessoryDeviceNumber        N
+  300A,0263  BrachyAccessoryDeviceID            N
+  300A,0264  BrachyAccessoryDeviceType          N
+  300A,0266  BrachyAccessoryDeviceName          N
+  300A,026A  BrachyAccessoryDeviceNomThickness  N
+  300A,026C  BrachyAccessoryDevNomTransmission  N
+  300A,0280  ChannelSequence                    N
+  300A,0282  ChannelNumber                      N
+  300A,0284  ChannelLength                      N
+  300A,0286  ChannelTotalTime                   N
+  300A,0288  SourceMovementType                 N
+  300A,028A  NumberOfPulses                     N
+  300A,028C  PulseRepetitionInterval            N
+  300A,0290  SourceApplicatorNumber             N
+  300A,0291  SourceApplicatorID                 N
+  300A,0292  SourceApplicatorType               N
+  300A,0294  SourceApplicatorName               N
+  300A,0296  SourceApplicatorLength             N
+  300A,0298  SourceApplicatorManufacturer       N
+  300A,029C  SourceApplicatorWallNomThickness   N
+  300A,029E  SourceApplicatorWallNomTrans       N
+  300A,02A0  SourceApplicatorStepSize           N
+  300A,02A2  TransferTubeNumber                 N
+  300A,02A4  TransferTubeLength                 N
+  300A,02B0  ChannelShieldSequence              N
+  300A,02B2  ChannelShieldNumber                N
+  300A,02B3  ChannelShieldID                    N
+  300A,02B4  ChannelShieldName                  N
+  300A,02B8  ChannelShieldNominalThickness      N
+  300A,02BA  ChannelShieldNominalTransmission   N
+  300A,02C8  FinalCumulativeTimeWeight          N
+  300A,02D0  BrachyControlPointSequence         N
+  300A,02D2  ControlPointRelativePosition       N
+  300A,02D4  ControlPoint3DPosition             N
+  300A,02D6  CumulativeTimeWeight               N
+  300A,02E0  CompensatorDivergence              N
+  300A,02E1  CompensatorMountingPosition        N
+  300A,02E2  SourceToCompensatorDistance        N
+  300C,0002  ReferencedRTPlanSequence           N
+  300C,0004  ReferencedBeamSequence             N
+  300C,0006  ReferencedBeamNumber               N
+  300C,0007  ReferencedReferenceImageNumber     N
+  300C,0008  StartCumulativeMetersetWeight      N
+  300C,0009  EndCumulativeMetersetWeight        N
+  300C,000A  ReferencedBrachyAppSetupSeq        N
+  300C,000C  ReferencedBrachyAppSetupNumber     N
+  300C,000E  ReferencedSourceNumber             N
+  300C,0020  ReferencedFractionGroupSequence    N
+  300C,0022  ReferencedFractionGroupNumber      N
+  300C,0040  ReferencedVerificationImageSeq     N
+  300C,0042  ReferencedReferenceImageSequence   N
+  300C,0050  ReferencedDoseReferenceSequence    N
+  300C,0051  ReferencedDoseReferenceNumber      N
+  300C,0055  BrachyReferencedDoseReferenceSeq   N
+  300C,0060  ReferencedStructureSetSequence     N
+  300C,006A  ReferencedPatientSetupNumber       N
+  300C,0080  ReferencedDoseSequence             N
+  300C,00A0  ReferencedToleranceTableNumber     N
+  300C,00B0  ReferencedBolusSequence            N
+  300C,00C0  ReferencedWedgeNumber              N
+  300C,00D0  ReferencedCompensatorNumber        N
+  300C,00E0  ReferencedBlockNumber              N
+  300C,00F0  ReferencedControlPointIndex        N
+  300E,0002  ApprovalStatus                     N
+  300E,0004  ReviewDate                         N
+  300E,0005  ReviewTime                         N
+  300E,0008  ReviewerName                       N
+  4000,0000  TextGroupLength                    N
+  4000,0010  Arbitrary                          N
+  4000,4000  TextComments                       N
+  4008,0040  ResultsID                          N
+  4008,0042  ResultsIDIssuer                    N
+  4008,0050  ReferencedInterpretationSequence   N
+  4008,0100  InterpretationRecordedDate         N
+  4008,0101  InterpretationRecordedTime         N
+  4008,0102  InterpretationRecorder             N
+  4008,0103  ReferenceToRecordedSound           N
+  4008,0108  InterpretationTranscriptionDate    N
+  4008,0109  InterpretationTranscriptionTime    N
+  4008,010A  InterpretationTranscriber          N
+  4008,010B  InterpretationText                 N
+  4008,010C  InterpretationAuthor               N
+  4008,0111  InterpretationApproverSequence     N
+  4008,0112  InterpretationApprovalDate         N
+  4008,0113  InterpretationApprovalTime         N
+  4008,0114  PhysicianApprovingInterpretation   N
+  4008,0115  InterpretationDiagnosisDescription N
+  4008,0117  InterpretationDiagnosisCodeSeq     N
+  4008,0118  ResultsDistributionListSequence    N
+  4008,0119  DistributionName                   N
+  4008,011A  DistributionAddress                N
+  4008,0200  InterpretationID                   N
+  4008,0202  InterpretationIDIssuer             N
+  4008,0210  InterpretationTypeID               N
+  4008,0212  InterpretationStatusID             N
+  4008,0300  Impressions                        N
+  4008,4000  ResultsComments                    N
+  4FFE,0001  MACParametersSequence              N
+  50xx,0005  CurveDimensions                    N
+  50xx,0010  NumberOfPoints                     N
+  50xx,0020  TypeOfData                         N
+  50xx,0022  CurveDescription                   N
+  50xx,0030  AxisUnits                          N
+  50xx,0040  AxisLabels                         N
+  50xx,0103  DataValueRepresentation            N
+  50xx,0104  MinimumCoordinateValue             N
+  50xx,0105  MaximumCoordinateValue             N
+  50xx,0106  CurveRange                         N
+  50xx,0110  CurveDataDescriptor                N
+  50xx,0112  CoordinateStartValue               N
+  50xx,0114  CoordinateStepValue                N
+  50xx,1001  CurveActivationLayer               N
+  50xx,2000  AudioType                          N
+  50xx,2002  AudioSampleFormat                  N
+  50xx,2004  NumberOfChannels                   N
+  50xx,2006  NumberOfSamples                    N
+  50xx,2008  SampleRate                         N
+  50xx,200A  TotalTime                          N
+  50xx,200C  AudioSampleData                    N
+  50xx,200E  AudioComments                      N
+  50xx,2500  CurveLabel                         N
+  50xx,2600  ReferencedOverlaySequence          N
+  50xx,2610  ReferencedOverlayGroup             N
+  50xx,3000  CurveData                          N
+  5200,9229  SharedFunctionalGroupsSequence     N
+  5200,9230  PerFrameFunctionalGroupsSequence   N
+  5400,0100  WaveformSequence                   N
+  5400,0110  ChannelMinimumValue                N
+  5400,0112  ChannelMaximumValue                N
+  5400,1004  WaveformBitsAllocated              N
+  5400,1006  WaveformSampleInterpretation       N
+  5400,100A  WaveformPaddingValue               N
+  5400,1010  WaveformData                       N
+  5600,0010  FirstOrderPhaseCorrectionAngle     N
+  5600,0020  SpectroscopyData                   N
+  6000,0000  OverlayGroupLength                 N
+  60xx,0010  OverlayRows                        N
+  60xx,0011  OverlayColumns                     N
+  60xx,0012  OverlayPlanes                      N
+  60xx,0015  NumberOfFramesInOverlay            N
+  60xx,0022  OverlayDescription                 N
+  60xx,0040  OverlayType                        N
+  60xx,0045  OverlaySubtype                     N
+  60xx,0050  OverlayOrigin                      N
+  60xx,0051  ImageFrameOrigin                   N
+  60xx,0052  OverlayPlaneOrigin                 N
+  60xx,0060  CompressionCode                    N
+  60xx,0100  OverlayBitsAllocated               N
+  60xx,0102  OverlayBitPosition                 N
+  60xx,0110  OverlayFormat                      N
+  60xx,0200  OverlayLocation                    N
+  60xx,1001  OverlayActivationLayer             N
+  60xx,1100  OverlayDescriptorGray              N
+  60xx,1101  OverlayDescriptorRed               N
+  60xx,1102  OverlayDescriptorGreen             N
+  60xx,1103  OverlayDescriptorBlue              N
+  60xx,1200  OverlaysGray                       N
+  60xx,1201  OverlaysRed                        N
+  60xx,1202  OverlaysGreen                      N
+  60xx,1203  OverlaysBlue                       N
+  60xx,1301  ROIArea                            N
+  60xx,1302  ROIMean                            N
+  60xx,1303  ROIStandardDeviation               N
+  60xx,1500  OverlayLabel                       N
+  60xx,3000  OverlayData                        N
+  60xx,4000  OverlayComments                    N
+  7FE0,0000  PixelDataGroupLength               N
+  7FE0,0010  PixelData                          N
+  FFFA,FFFA  DigitalSignaturesSequence          N
+  FFFC,FFFC  DataSetTrailingPadding             N
+  FFFE,E000  StartOfItem                        N
+  FFFE,E00D  EndOfItems                         N
+  FFFE,E0DD  EndOfSequence                      N
+
+=head2 HTML Tags
+
+Meta information extracted from the header of HTML and XHTML files.  This is
+a mix of information found in the C<META> elements and the C<TITLE> element.
+
+  Tag ID                      Tag Name          Writable
+  ------                      --------          --------
+  'abstract'                  Abstract          N
+  'author'                    Author            N
+  'classification'            Classification    N
+  'copyright'                 Copyright         N
+  'dc'                        DC                HTML dc
+  'description'               Description       N
+  'distribution'              Distribution      N
+  'doc-class'                 DocClass          N
+  'doc-rights'                DocRights         N
+  'doc-type'                  DocType           N
+  'formatter'                 Formatter         N
+  'generator'                 Generator         N
+  'googlebot'                 GoogleBot         N
+  'http-equiv'                HTTP-equiv        HTML equiv
+  'keywords'                  Keywords          N+
+  'mssmarttagspreventparsing' NoMSSmartTags     N
+  'ncc'                       NCC               HTML ncc
+  'owner'                     Owner             N
+  'prod'                      Prod              HTML prod
+  'progid'                    ProgID            N
+  'rating'                    Rating            N
+  'refresh'                   Refresh           N
+  'resource-type'             ResourceType      N
+  'revisit-after'             RevisitAfter      N
+  'robots'                    Robots            N+
+  'title'                     Title             N
+  'vw96'                      VW96              HTML vw96
+
+=head3 HTML dc Tags
+
+Dublin Core schema tags (also used in XMP).
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'contributor'        Contributor              N+
+  'coverage'           Coverage                 N
+  'creator'            Creator                  N+
+  'date'               Date                     N+
+  'description'        Description              N
+  'format'             Format                   N
+  'identifier'         Identifier               N
+  'language'           Language                 N+
+  'publisher'          Publisher                N+
+  'relation'           Relation                 N+
+  'rights'             Rights                   N
+  'source'             Source                   N
+  'subject'            Subject                  N+
+  'title'              Title                    N
+  'type'               Type                     N+
+
+=head3 HTML equiv Tags
+
+These tags have a family 1 group name of "HTTP-equiv".
+
+  Tag ID                Tag Name                Writable
+  ------                --------                --------
+  'cache-control'       CacheControl            N
+  'content-disposition' ContentDisposition      N
+  'content-language'    ContentLanguage         N
+  'content-script-type' ContentScriptType       N
+  'content-style-type'  ContentStyleType        N
+  'content-type'        ContentType             N
+  'default-style'       DefaultStyle            N
+  'expires'             Expires                 N
+  'ext-cache'           ExtCache                N
+  'imagetoolbar'        ImageToolbar            N
+  'lotus'               Lotus                   N
+  'page-enter'          PageEnter               N
+  'page-exit'           PageExit                N
+  'pics-label'          PicsLabel               N
+  'pragma'              Pragma                  N
+  'refresh'             Refresh                 N
+  'reply-to'            ReplyTo                 N
+  'set-cookie'          SetCookie               N
+  'site-enter'          SiteEnter               N
+  'site-exit'           SiteExit                N
+  'vary'                Vary                    N
+  'window-target'       WindowTarget            N
+
+=head3 HTML ncc Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'charset'            Charset                  N
+  'depth'              Depth                    N
+  'files'              Files                    N
+  'footnotes'          Footnotes                N
+  'generator'          Generator                N
+  'kbytesize'          KByteSize                N
+  'maxpagenormal'      MaxPageNormal            N
+  'multimediatype'     MultimediaType           N
+  'narrator'           Narrator                 N
+  'pagefront'          PageFront                N
+  'pagenormal'         PageNormal               N
+  'pagespecial'        PageSpecial              N
+  'prodnotes'          ProdNotes                N
+  'produceddate'       ProducedDate             N
+  'producer'           Producer                 N
+  'revision'           Revision                 N
+  'revisiondate'       RevisionDate             N
+  'setinfo'            SetInfo                  N
+  'sidebars'           Sidebars                 N
+  'sourcedate'         SourceDate               N
+  'sourceedition'      SourceEdition            N
+  'sourcepublisher'    SourcePublisher          N
+  'sourcerights'       SourceRights             N
+  'sourcetitle'        SourceTitle              N
+  'tocitems'           TOCItems                 N
+  'totaltime'          Duration                 N
+
+=head3 HTML prod Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'recengineer'        RecEngineer              N
+  'reclocation'        RecLocation              N
+
+=head3 HTML vw96 Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'objecttype'         ObjectType               N
+
+=head2 Extra Tags
+
+The extra tags represent information found in the image but not associated
+with any other tag group.  The three writable "pseudo" tags (Filename,
+Directory and FileModifyDate) may be written without the need to rewrite the
+file since their values are not contained within the file data.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CanonVRD                                      Y!
+  Comment                                       Y
+  Directory                                     Y!
+  EXIF                                          N
+  Encryption                                    N
+  Error                                         N
+  ExifByteOrder                                 Y
+  ExifToolVersion                               N
+  FileModifyDate                                Y
+  FileName                                      Y!
+  FileSize                                      N
+  FileType                                      N
+  ICC_Profile                                   Y!
+  ImageHeight                                   N
+  ImageWidth                                    N
+  MIMEType                                      N
+  MaxVal                                        N
+  Warning                                       N
+  XMP                                           Y
+  XResolution                                   N
+  YResolution                                   N
+
+=head2 Composite Tags
+
+The values of the composite tags are derived from the values of other tags.
+These are convenience tags which are calculated after all other information
+is extracted.
+
+  Tag Name             Derived From             Writable
+  --------             ------------             --------
+  Aperture             FNumber                  N
+                       ApertureValue
+  BlueBalance          WB_RGGBLevels            N
+                       WB_RGBGLevels
+                       WB_RBGGLevels
+                       WB_GRBGLevels
+                       WB_GRGBLevels
+                       WB_RBLevels
+                       WBBlueLevel
+                       WBGreenLevel
+  CFAPattern           CFARepeatPatternDim      N
+                       CFAPattern2
+  CircleOfConfusion    ScaleFactor35efl         N
+  ConditionalFEC       FlashExposureComp        N
+                       FlashBits
+  DOF                  FocusDistance            N
+                       FocalLength
+                       Aperture
+                       CircleOfConfusion
+  DateCreated          Kodak:YearCreated        N
+                       Kodak:MonthDayCreated
+  DateTimeCreated      DateCreated              N
+                       TimeCreated
+  DateTimeOriginal     DateTimeCreated          N
+  DigitalZoom          Canon:ZoomSourceWidth    N
+                       Canon:ZoomTargetWidth
+                       Canon:DigitalZoom
+  DriveMode            ContinuousDrive          N
+                       Self-timer
+  Duration             FLAC:SampleRate          N
+                       FLAC:Channels
+                       FLAC:TotalSamples
+  Duration             FileSize                 N
+                       MPEG:AudioBitrate
+                       MPEG:VideoBitrate
+  Duration             FrameRate                N
+                       FrameCount
+  ExtenderStatus       Olympus:Extender         N
+                       Olympus:LensType
+                       MaxApertureValue
+  FlashOn              FlashBits                N
+                       Flash
+  FlashType            FlashBits                N
+  FocalLength35efl     FocalLength              N
+                       ScaleFactor35efl
+  GPSDateTime          GPSDateStamp             N
+                       GPSTimeStamp
+  GPSLatitude          GPS:GPSLatitude          N
+                       GPS:GPSLatitudeRef
+  GPSLatitudeRef       XMP:GPSLatitude          N
+  GPSLongitude         GPS:GPSLongitude         N
+                       GPS:GPSLongitudeRef
+  GPSLongitudeRef      XMP:GPSLongitude         N
+  GPSPosition          GPSLatitude              N
+                       GPSLongitude
+  HyperfocalDistance   FocalLength              N
+                       Aperture
+                       CircleOfConfusion
+  ISO                  Canon:CameraISO          N
+                       Canon:BaseISO
+                       Canon:AutoISO
+  ImageHeight          PostScript:ImageData     N
+                       PostScript:BoundingBox
+  ImageSize            ImageWidth               N
+                       ImageHeight
+  ImageWidth           PostScript:ImageData     N
+                       PostScript:BoundingBox
+  JpgFromRaw           JpgFromRawStart          Y
+                       JpgFromRawLength
+  Lens                 ShortFocal               N
+                       LongFocal
+  Lens35efl            ShortFocal               N
+                       LongFocal
+                       Lens
+                       ScaleFactor35efl
+  LensID               Nikon:LensIDNumber       N
+                       LensFStops
+                       MinFocalLength
+                       MaxFocalLength
+                       MaxApertureAtMinFocal
+                       MaxApertureAtMaxFocal
+                       MCUVersion
+                       Nikon:LensType
+  LensSpec             Nikon:Lens               N
+                       Nikon:LensType
+  LightValue           Aperture                 N
+                       ShutterSpeed
+                       ISO
+  OtherImage           OtherImageStart          N
+                       OtherImageLength
+  PreviewImage         PreviewImageStart        Y
+                       PreviewImageLength
+                       PreviewImageValid
+                       PreviewImageStart (1)
+                       PreviewImageLength (1)
+  PreviewImageSize     PreviewImageWidth        N
+                       PreviewImageHeight
+  PreviewImage         ScreenNail               N
+  RedBalance           WB_RGGBLevels            N
+                       WB_RGBGLevels
+                       WB_RBGGLevels
+                       WB_GRBGLevels
+                       WB_GRGBLevels
+                       WB_RBLevels
+                       WBRedLevel
+                       WBGreenLevel
+  RedEyeReduction      CanonFlashMode           N
+                       FlashBits
+  ScaleFactor35efl     FocalLength              N
+                       FocalLengthIn35mmFormat
+                       Composite:DigitalZoom
+                       FocalPlaneDiagonal
+                       FocalPlaneXSize
+                       FocalPlaneYSize
+                       FocalPlaneResolutionUnit
+                       FocalPlaneXResolution
+                       FocalPlaneYResolution
+                       CanonImageWidth
+                       CanonImageHeight
+                       ExifImageWidth
+                       ExifImageLength
+                       ImageWidth
+                       ImageHeight
+  ShootingMode         CanonExposureMode        N
+                       EasyMode
+  ShutterCurtainHack   FlashBits                N
+                       ShutterCurtainSync
+  ShutterSpeed         ExposureTime             N
+                       ShutterSpeedValue
+                       BulbDuration
+  SubSecDateTimeOriginal DateTimeOriginal       N
+                       SubSecTimeOriginal
+  ThumbnailImage       ThumbnailOffset          Y
+                       ThumbnailLength
+  WB_RGGBLevels        Canon:WhiteBalance       N
+                       WB_RGGBLevelsAsShot
+                       WB_RGGBLevelsAuto
+                       WB_RGGBLevelsDaylight
+                       WB_RGGBLevelsCloudy
+                       WB_RGGBLevelsTungsten
+                       WB_RGGBLevelsFluorescent
+                       WB_RGGBLevelsFlash
+                       WB_RGGBLevelsCustom
+                       WB_RGGBLevelsShade
+                       WB_RGGBLevelsKelvin
+
+=head2 Shortcuts Tags
+
+Shortcut tags are convenience tags that represent one or more other tag
+names.  They are used like regular tags to read and write the information
+for a specified set of tags.
+
+The shortcut tags below have been pre-defined, but user-defined shortcuts
+may be added via the %Image::ExifTool::Shortcuts::UserDefined lookup in the
+~/.ExifTool_config file.  See the Image::ExifTool::Shortcuts documentation
+for more details.
+
+  Tag Name             Refers To                Writable
+  --------             ---------                --------
+  AllDates             DateTimeOriginal         Y
+                       CreateDate
+                       ModifyDate
+  Canon                FileName                 Y
+                       Model
+                       DateTimeOriginal
+                       ShootingMode
+                       ShutterSpeed
+                       Aperture
+                       MeteringMode
+                       ExposureCompensation
+                       ISO
+                       Lens
+                       FocalLength
+                       ImageSize
+                       Quality
+                       FlashOn
+                       FlashType
+                       ConditionalFEC
+                       RedEyeReduction
+                       ShutterCurtainHack
+                       WhiteBalance
+                       FocusMode
+                       Contrast
+                       Sharpness
+                       Saturation
+                       ColorTone
+                       FileSize
+                       FileNumber
+                       DriveMode
+                       OwnerName
+                       SerialNumber
+  Canon20D             FileName                 Y
+                       Model
+                       DateTimeOriginal
+                       ShootingMode
+                       ShutterSpeedValue
+                       ApertureValue
+                       MeteringMode
+                       ExposureCompensation
+                       ISO
+                       Lens
+                       FocalLength
+                       ExifImageWidth
+                       ExifImageLength
+                       Quality
+                       FlashOn
+                       FlashType
+                       ConditionalFEC
+                       RedEyeReduction
+                       ShutterCurtainHack
+                       WhiteBalance
+                       FocusMode
+                       Contrast
+                       Sharpness
+                       Saturation
+                       ColorTone
+                       ColorSpace
+                       LongExposureNoiseReduction
+                       FileSize
+                       FileNumber
+                       DriveMode
+                       OwnerName
+                       SerialNumber
+  Common               FileName                 Y
+                       FileSize
+                       Model
+                       DateTimeOriginal
+                       ImageSize
+                       Quality
+                       FocalLength
+                       ShutterSpeed
+                       Aperture
+                       ISO
+                       WhiteBalance
+                       Flash
+  MakerNotes           MakerNotes               Y
+                       MakerNoteCanon
+                       MakerNoteCasio
+                       MakerNoteCasio2
+                       MakerNoteFujiFilm
+                       MakerNoteHP
+                       MakerNoteHP2
+                       MakerNoteHP4
+                       MakerNoteHP6
+                       MakerNoteJVC
+                       MakerNoteJVCText
+                       MakerNoteKodak1a
+                       MakerNoteKodak1b
+                       MakerNoteKodak2
+                       MakerNoteKodak3
+                       MakerNoteKodak4
+                       MakerNoteKodak5
+                       MakerNoteKodak6a
+                       MakerNoteKodak6b
+                       MakerNoteKodak7
+                       MakerNoteKodakIFD
+                       MakerNoteKodakUnknown
+                       MakerNoteKyocera
+                       MakerNoteMinolta
+                       MakerNoteMinolta2
+                       MakerNoteMinolta3
+                       MakerNoteNikon
+                       MakerNoteNikon2
+                       MakerNoteNikon3
+                       MakerNoteOlympus
+                       MakerNoteOlympus2
+                       MakerNoteLeica
+                       MakerNotePanasonic
+                       MakerNotePanasonic2
+                       MakerNotePentax
+                       MakerNotePentax2
+                       MakerNotePentax3
+                       MakerNotePentax4
+                       MakerNoteRicoh
+                       MakerNoteRicohText
+                       MakerNoteSanyo
+                       MakerNoteSanyoC4
+                       MakerNoteSanyoPatch
+                       MakerNoteSigma
+                       MakerNoteSony
+                       MakerNoteSonySRF
+                       MakerNoteSonySR2
+                       MakerNoteUnknown
+  Nikon                Model                    Y
+                       SubSecDateTimeOriginal
+                       ShutterCount
+                       LensSpec
+                       FocalLength
+                       ImageSize
+                       ShutterSpeed
+                       Aperture
+                       ISO
+                       NoiseReduction
+                       ExposureProgram
+                       ExposureCompensation
+                       WhiteBalance
+                       WhiteBalanceFineTune
+                       ShootingMode
+                       Quality
+                       MeteringMode
+                       FocusMode
+                       ImageOptimization
+                       ToneComp
+                       ColorHue
+                       ColorSpace
+                       HueAdjustment
+                       Saturation
+                       Sharpness
+                       Flash
+                       FlashMode
+                       FlashExposureComp
+
+=head1 NOTES
+
+This document generated automatically by
+L<Image::ExifTool::BuildTagLookup|Image::ExifTool::BuildTagLookup>.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Unknown.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Unknown.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Unknown.pm	(revision 20131)
@@ -0,0 +1,66 @@
+#------------------------------------------------------------------------------
+# File:         Unknown.pm
+#
+# Description:  Unknown EXIF maker notes tags
+#
+# Revisions:    04/07/2004  - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Unknown;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.13';
+
+# Unknown maker notes
+%Image::ExifTool::Unknown::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'MakerUnknown', 2 => 'Camera' },
+
+    # this seems to be a common fixture, so look for it in unknown maker notes
+    0x0e00 => {
+        Name => 'PrintIM',
+        Description => 'Print Image Matching',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PrintIM::Main',
+        },
+    },
+);
+
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Unknown - Unknown EXIF maker notes tags
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+Image::ExifTool has definitions for the maker notes from many manufacturers,
+however information can sometimes be extracted from unknown manufacturers if
+the maker notes are in standard IFD format.  This module contains the
+definitions necessary for Image::ExifTool to read the maker notes from
+unknown manufacturers.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Unknown Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Vorbis.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Vorbis.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Vorbis.pm	(revision 20131)
@@ -0,0 +1,353 @@
+#------------------------------------------------------------------------------
+# File:         Vorbis.pm
+#
+# Description:  Read Ogg Vorbis meta information
+#
+# Revisions:    11/10/2006 - P. Harvey Created
+#
+# References:   1) http://www.xiph.org/vorbis/doc/
+#               2) http://flac.sourceforge.net/ogg_mapping.html
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Vorbis;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.01';
+
+my $MAX_PACKETS = 2;    # maximum packets to scan from each stream at start of file
+
+sub ProcessComments($$$);
+sub DecodeCoverArt($);
+
+# Vorbis comment tags
+%Image::ExifTool::Vorbis::Main = (
+    NOTES => q{
+        ExifTool extracts the following Vorbis information from Ogg files.  As well
+        as this, ExifTool also extracts FLAC and ID3 information from Ogg files.
+    },
+    1 => {
+        Name => 'Identification',
+        SubDirectory => { TagTable => 'Image::ExifTool::Vorbis::Identification' },
+    },
+    3 => {
+        Name => 'Comments',
+        SubDirectory => { TagTable => 'Image::ExifTool::Vorbis::Comments' },
+    },
+);
+
+%Image::ExifTool::Vorbis::Identification = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Audio' },
+    0 => {
+        Name => 'VorbisVersion',
+        Format => 'int32u',
+    },
+    4 => 'AudioChannels',
+    5 => {
+        Name => 'SampleRate',
+        Format => 'int32u',
+    },
+    9 => {
+        Name => 'MaximumBitrate',
+        Format => 'int32u',
+        RawConv => '$val || undef',
+    },
+    13 => {
+        Name => 'NominalBitrate',
+        Format => 'int32u',
+        RawConv => '$val || undef',
+    },
+    17 => {
+        Name => 'MinimumBitrate',
+        Format => 'int32u',
+        RawConv => '$val || undef',
+    },
+);
+
+%Image::ExifTool::Vorbis::Comments = (
+    PROCESS_PROC => \&ProcessComments,
+    GROUPS => { 2 => 'Audio' },
+    NOTES => q{
+        The tags below are only some common tags found in the Vorbis comments of Ogg
+        Vorbis and Ogg FLAC audio files, however ExifTool will extract values from
+        any tag found, even if not listed here.
+    },
+    vendor    => { Notes => 'from comment header' },
+    TITLE     => { Name => 'Title' },
+    VERSION   => { Name => 'Version' },
+    ALBUM     => { Name => 'Album' },
+    TRACKNUMBER=>{ Name => 'TrackNumber' },
+    ARTIST    => { Name => 'Artist',       Groups => { 2 => 'Author' }, List => 1 },
+    PERFORMER => { Name => 'Performer',    Groups => { 2 => 'Author' }, List => 1 },
+    COPYRIGHT => { Name => 'Copyright',    Groups => { 2 => 'Author' } },
+    LICENSE   => { Name => 'License',      Groups => { 2 => 'Author' } },
+    ORGANIZATION=>{Name => 'Organization', Groups => { 2 => 'Author' } },
+    DESCRIPTION=>{ Name => 'Description' },
+    GENRE     => { Name => 'Genre' },
+    DATE      => { Name => 'Date',         Groups => { 2 => 'Time' } },
+    LOCATION  => { Name => 'Location',     Groups => { 2 => 'Location' } },
+    CONTACT   => { Name => 'Contact',      Groups => { 2 => 'Author' }, List => 1 },
+    ISRC      => { Name => 'ISRCNumber' },
+    COVERARTMIME => { Name => 'CoverArtMIMEType' },
+    COVERART  => {
+        Name => 'CoverArt',
+        Notes => 'base64-encoded image',
+        ValueConv => q{
+            require Image::ExifTool::XMP;
+            Image::ExifTool::XMP::DecodeBase64($val);
+        },
+    },
+    REPLAYGAIN_TRACK_PEAK => { Name => 'ReplayGainTrackPeak' },
+    REPLAYGAIN_TRACK_GAIN => { Name => 'ReplayGainTrackGain' },
+    REPLAYGAIN_ALBUM_PEAK => { Name => 'ReplayGainAlbumPeak' },
+    REPLAYGAIN_ALBUM_GAIN => { Name => 'ReplayGainAlbumGain' },
+    # observed in "Xiph.Org libVorbis I 20020717" ogg:
+    ENCODED_USING => { Name => 'EncodedUsing' },
+    ENCODED_BY  => { Name => 'EncodedBy' },
+    COMMENT     => { Name => 'Comment' },
+);
+
+#------------------------------------------------------------------------------
+# Process Vorbis Comments
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success, otherwise returns 0 and sets a Warning
+sub ProcessComments($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{DataPos};
+    my $pos = $$dirInfo{DirStart} || 0;
+    my $end = $$dirInfo{DirLen} ? $pos + $$dirInfo{DirLen} : length $$dataPt;
+    my ($num, $index);
+
+    SetByteOrder('II');
+    for (;;) {
+        last if $pos + 4 > $end;
+        my $len = Get32u($dataPt, $pos);
+        last if $pos + 4 + $len > $end;
+        my $start = $pos + 4;
+        my $buff = substr($$dataPt, $start, $len);
+        $pos = $start + $len;
+        my ($tag, $val);
+        if (defined $num) {
+            $buff =~ /(.*?)=(.*)/s or last;
+            ($tag, $val) = ($1, $2);
+        } else {
+            $tag = 'vendor';
+            $val = $buff;
+            $num = ($pos + 4 < $end) ? Get32u($dataPt, $pos) : 0;
+            $exifTool->VPrint(0, "  + [Vorbis comments with $num entries]\n");
+            $pos += 4;
+        }
+        # add tag to table unless it exists already
+        unless ($$tagTablePtr{$tag}) {
+            my $name = ucfirst(lc($tag));
+            # remove invalid characters in tag name and capitalize following letters
+            $name =~ s/[^\w-]+(.?)/\U$1/sg;
+            $name =~ s/([a-z0-9])_([a-z])/$1\U$2/g;
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name });
+        }
+        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            Index   => $index,
+            DataPt  => $dataPt,
+            DataPos => $dataPos,
+            Start   => $start,
+            Size    => $len,
+        );
+        # all done if this was our last tag
+        $num-- or return 1;
+        $index = (defined $index) ? $index + 1 : 0;
+    }
+    $exifTool->Warn('Format error in Vorbis comments');
+    return 0;
+}
+
+#------------------------------------------------------------------------------
+# Process Ogg packet
+# Inputs: 0) ExifTool object ref, 1) data ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessPacket($$$)
+{
+    my ($exifTool, $dataPt, $tagTablePtr) = @_;
+    if ($$dataPt =~ /^(.)vorbis/s) {
+        my $tag = ord($1);
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        return 0 unless $tagInfo and $$tagInfo{SubDirectory};
+        my %dirInfo = (
+            DataPt => $dataPt,
+            DirName => $$tagInfo{Name},
+            DirStart => 7,
+        );
+        my $table = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+        return $exifTool->ProcessDirectory(\%dirInfo, $table);
+    }
+    return 0;
+}
+
+#------------------------------------------------------------------------------
+# Extract information from an Ogg Vorbis or Ogg FLAC file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid Ogg Vorbis file
+sub ProcessOGG($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+
+    # must first check for leading/trailing ID3 information
+    unless ($exifTool->{DONE_ID3}) {
+        require Image::ExifTool::ID3;
+        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
+    }
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my ($success, $page, $packets, $streams) = (0,0,0,0);
+    my ($buff, $tagTablePtr, $flag, $stream, %val, $numFlac);
+
+    for (;;) {
+        # must read ahead to next page to see if it is a continuation
+        # (this code would be a lot simpler if the continuation flag
+        #  was on the leading instead of the trailing page!)
+        if ($raf and $raf->Read($buff, 28) == 28) {
+            # validate magic number
+            unless ($buff =~ /^OggS/) {
+                $success and $exifTool->Warn('Lost synchronization');
+                last;
+            }
+            unless ($success) {
+                # set file type and initialize on first page
+                $success = 1;
+                $exifTool->SetFileType();
+                SetByteOrder('II');
+                $tagTablePtr = GetTagTable('Image::ExifTool::Vorbis::Main');
+            }
+            $flag = Get8u(\$buff, 5);       # page flag
+            $stream = Get32u(\$buff, 14);   # stream serial number
+            ++$streams if $flag & 0x02;     # count start-of-stream pages
+            ++$packets unless $flag & 0x01; # keep track of packet count
+        } else {
+            # all done unless we have to process our last packet
+            last unless %val;
+            ($stream) = sort keys %val;     # take a stream
+            $flag = 0;                      # no continuation
+            undef $raf;                     # flag for done reading
+        }
+
+        if (defined $numFlac) {
+            # stop to process FLAC headers if we hit the end of file
+            last unless $raf;
+            --$numFlac; # one less header packet to read
+        } else {
+            # can finally process previous packet from this stream
+            # unless this is a continuation page
+            if (defined $val{$stream} and not $flag & 0x01) {
+                ProcessPacket($exifTool, \$val{$stream}, $tagTablePtr);
+                delete $val{$stream};
+                # only read the first $MAX_PACKETS packets from each stream
+                if ($packets > $MAX_PACKETS * $streams or not defined $raf) {
+                    last unless %val;   # all done (success!)
+                    next;               # process remaining stream(s)
+                }
+            }
+            # stop processing Ogg Vorbis if we have scanned enough packets
+            last if $packets > $MAX_PACKETS * $streams and not %val;
+        }
+
+        # continue processing the current page
+        my $pageNum = Get32u(\$buff, 18);   # page sequence number
+        my $nseg = Get8u(\$buff, 26);       # number of segments
+        # calculate total data length
+        my $dataLen = Get8u(\$buff, 27);
+        if ($nseg) {
+            $raf->Read($buff, $nseg-1) == $nseg-1 or last;
+            my @segs = unpack('C*', $buff);
+            # could check that all these (but the last) are 255...
+            foreach (@segs) { $dataLen += $_ }
+        }
+        if (defined $page) {
+            if ($page == $pageNum) {
+                ++$page;
+            } else {
+                $exifTool->Warn('Missing page(s) in Ogg file');
+                undef $page;
+            }
+        }
+        # read page data
+        $raf->Read($buff, $dataLen) == $dataLen or last;
+        if ($verbose > 1) {
+            printf $out "Page %d, stream 0x%x, flag 0x%x (%d bytes)\n",
+                   $pageNum, $stream, $flag, $dataLen;
+            $exifTool->VerboseDump(\$buff, DataPos => $raf->Tell() - $dataLen);
+        }
+        if (defined $val{$stream}) {
+            $val{$stream} .= $buff;     # add this continuation page
+        } elsif (not $flag & 0x01) {    # ignore remaining pages of a continued packet
+            # ignore the first page of any packet we aren't parsing
+            if ($buff =~ /^(.)vorbis/s and $$tagTablePtr{ord($1)}) {
+                $val{$stream} = $buff;      # save this page
+            } elsif ($buff =~ /^\x7fFLAC..(..)/s) {
+                $numFlac = unpack('n',$1);
+                $val{$stream} = substr($buff, 9);
+            }
+        }
+        if (defined $numFlac) {
+            # stop to process FLAC headers if we have them all
+            last if $numFlac <= 0;
+        } elsif (defined $val{$stream} and $flag & 0x04) {
+            # process Ogg Vorbis packet now if end-of-stream bit is set
+            ProcessPacket($exifTool, \$val{$stream}, $tagTablePtr);
+            delete $val{$stream};
+        }
+    }
+    if (defined $numFlac and defined $val{$stream}) {
+        # process FLAC headers as if it was a complete FLAC file
+        require Image::ExifTool::FLAC;
+        my %dirInfo = ( RAF => new File::RandomAccess(\$val{$stream}) );
+        Image::ExifTool::FLAC::ProcessFLAC($exifTool, \%dirInfo);
+    }
+    return $success;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Vorbis - Read Ogg Vorbis meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to extract meta
+information from Ogg Vorbis and Ogg FLAC audio files.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.xiph.org/vorbis/doc/>
+
+=item L<http://flac.sourceforge.net/ogg_mapping.html>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Vorbis Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/WriteCanonRaw.pl
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/WriteCanonRaw.pl	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/WriteCanonRaw.pl	(revision 20131)
@@ -0,0 +1,606 @@
+#------------------------------------------------------------------------------
+# File:         WriteCanonRaw.pl
+#
+# Description:  Write Canon RAW (CRW and CR2) meta information
+#
+# Revisions:    01/25/2005 - P. Harvey Created
+#------------------------------------------------------------------------------
+package Image::ExifTool::CanonRaw;
+
+use strict;
+use vars qw($VERSION $AUTOLOAD %crwTagFormat);
+use Image::ExifTool::Fixup;
+
+# mappings to from RAW tagID to MakerNotes tagID
+# (Note: upper two bits of RawTagID are zero)
+my %mapRawTag = (
+  # RawTagID => Canon TagID
+    0x080b => 0x07, # CanonFirmwareVersion
+    0x0810 => 0x09, # OwnerName
+    0x0815 => 0x06, # CanonImageType
+    0x1028 => 0x03, # (unknown if no tag name specified)
+    0x1029 => 0x02, # FocalLength
+    0x102a => 0x04, # CanonShotInfo
+    0x102d => 0x01, # CanonCameraSettings
+    0x1033 => 0x0f, # CanonCustomFunctions (only verified for 10D)
+    0x1038 => 0x12, # CanonAFInfo
+    0x1039 => 0x13,
+    0x1093 => 0x93,
+    0x10a8 => 0xa8,
+    0x10a9 => 0xa9, # WhiteBalanceTable
+    0x10aa => 0xaa,
+    0x10ae => 0xae, # ColorTemperature
+    0x10b4 => 0xb4, # ColorSpace
+    0x10b5 => 0xb5,
+    0x10c0 => 0xc0,
+    0x10c1 => 0xc1,
+    0x180b => 0x0c, # SerialNumber
+    0x1817 => 0x08, # FileNumber
+    0x1834 => 0x10,
+    0x183b => 0x15,
+);
+# translation from Rotation to Orientation values
+my %mapRotation = (
+    0 => 1,
+    90 => 6,
+    180 => 3,
+    270 => 8,
+);
+
+
+#------------------------------------------------------------------------------
+# Initialize buffers for building MakerNotes from RAW data
+# Inputs: 0) ExifTool object reference
+sub InitMakerNotes($)
+{
+    my $exifTool = shift;
+    $exifTool->{MAKER_NOTE_INFO} = {
+        Entries => { },     # directory entries keyed by tagID
+        ValBuff => "\0\0\0\0", # value data buffer (start with zero nextIFD pointer)
+        FixupTags => { },   # flags for tags with data in value buffer
+    };
+}
+
+#------------------------------------------------------------------------------
+# Build maker notes from CanonRaw information
+# Inputs: 0) ExifTool object reference, 1) raw tag ID, 2) reference to tagInfo
+#         3) reference to value, 4) format name, 5) count
+# Notes: This will build the directory in the order the tags are found in the CRW
+# file, which isn't sequential (but Canon's version isn't sequential either...)
+sub BuildMakerNotes($$$$$$)
+{
+    my ($exifTool, $rawTag, $tagInfo, $valuePt, $formName, $count) = @_;
+
+    my $tagID = $mapRawTag{$rawTag} || return;
+    $formName or warn(sprintf "No format for tag 0x%x!\n",$rawTag), return;
+    # special case: ignore user comment because it gets saved in EXIF
+    # (and has the same raw tagID as CanonFileDescription)
+    return if $tagInfo and $$tagInfo{Name} eq 'UserComment';
+    my $tagType = ($rawTag >> 8) & 0x38;
+    my $format = $Image::ExifTool::Exif::formatNumber{$formName};
+    my $fsiz = $Image::ExifTool::Exif::formatSize[$format];
+    my $size = length($$valuePt);
+    my $value;
+    if ($count and $size != $count * $fsiz) {
+        if ($size < $count * $fsiz) {
+            warn sprintf("Value too short for raw tag 0x%x\n",$rawTag);
+            return;
+        }
+        # shorten value appropriately
+        $size = $count * $fsiz;
+        $value = substr($$valuePt, 0, $size);
+    } else {
+        $count = $size / $fsiz;
+        $value = $$valuePt;
+    }
+    my $offsetVal;
+    my $makerInfo = $exifTool->{MAKER_NOTE_INFO};
+    if ($size > 4) {
+        my $len = length $makerInfo->{ValBuff};
+        $offsetVal = Set32u($len);
+        $makerInfo->{ValBuff} .= $value;
+        # pad to an even number of bytes
+        $size & 0x01 and $makerInfo->{ValBuff} .= "\0";
+        # set flag indicating that this tag needs a fixup
+        $makerInfo->{FixupTags}->{$tagID} = 1;
+    } else {
+        $offsetVal = $value;
+        $size < 4 and $offsetVal .= "\0" x (4 - $size);
+    }
+    $makerInfo->{Entries}->{$tagID} = Set16u($tagID) . Set16u($format) .
+                                      Set32u($count) . $offsetVal;
+}
+
+#------------------------------------------------------------------------------
+# Finish building and save MakerNotes
+# Inputs: 0) ExifTool object reference
+sub SaveMakerNotes($)
+{
+    my $exifTool = shift;
+    # save maker notes
+    my $makerInfo = $exifTool->{MAKER_NOTE_INFO};
+    delete $exifTool->{MAKER_NOTE_INFO};
+    my $dirEntries = $makerInfo->{Entries};
+    my $numEntries = scalar(keys %$dirEntries);
+    my $fixup = new Image::ExifTool::Fixup;
+    return unless $numEntries;
+    # build the MakerNotes directory
+    my $makerNotes = Set16u($numEntries);
+    my $tagID;
+    # write the entries in proper tag order (even though Canon doesn't do this...)
+    foreach $tagID (sort { $a <=> $b } keys %$dirEntries) {
+        $makerNotes .= $$dirEntries{$tagID};
+        next unless $makerInfo->{FixupTags}->{$tagID};
+        # add fixup for this pointer
+        $fixup->AddFixup(length($makerNotes) - 4);
+    }
+    # save position of maker notes for pointer fixups
+    $fixup->{Shift} += length($makerNotes);
+    $exifTool->{MAKER_NOTE_FIXUP} = $fixup;
+    $exifTool->{MAKER_NOTE_BYTE_ORDER} = GetByteOrder();
+    # add value data
+    $makerNotes .= $makerInfo->{ValBuff};
+    # get MakerNotes tag info
+    my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Exif::Main');
+    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, 0x927c);
+    # save the MakerNotes
+    $exifTool->FoundTag($tagInfo, $makerNotes);
+    # save the garbage collection some work later
+    delete $makerInfo->{Entries};
+    delete $makerInfo->{ValBuff};
+    delete $makerInfo->{FixupTags};
+    # also generate Orientation tag since Rotation isn't transferred from RAW info
+    my $rotation = $exifTool->GetValue('Rotation', 'ValueConv');
+    if (defined $rotation and defined $mapRotation{$rotation}) {
+        $tagInfo = $exifTool->GetTagInfo($tagTablePtr, 0x112);
+        $exifTool->FoundTag($tagInfo, $mapRotation{$rotation});
+    }
+}
+
+#------------------------------------------------------------------------------
+# Check CanonRaw information
+# Inputs: 0) ExifTool object reference, 1) tagInfo hash reference,
+#         2) raw value reference
+# Returns: error string or undef (and may change value) on success
+sub CheckCanonRaw($$$)
+{
+    my ($exifTool, $tagInfo, $valPtr) = @_;
+    Image::ExifTool::GenerateTagIDs($$tagInfo{Table});
+    my $tagName = $$tagInfo{Name};
+    if ($tagName eq 'JpgFromRaw' or $tagName eq 'ThumbnailImage') {
+        unless ($$valPtr =~ /^\xff\xd8/ or $exifTool->Options('IgnoreMinorErrors')) {
+            return '[minor] Not a valid image';
+        }
+    } else {
+        my $format = $$tagInfo{Format};
+        my $count = $$tagInfo{Count};
+        unless ($format) {
+            my $tagType = ($$tagInfo{TagID} >> 8) & 0x38;
+            $format = $crwTagFormat{$tagType};
+        }
+        $format and return Image::ExifTool::CheckValue($valPtr, $format, $count);
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Write CR2 file
+# Inputs: 0) ExifTool ref, 1) dirInfo reference (must have read first 16 bytes)
+#         2) tag table reference
+# Returns: true on success
+sub WriteCR2($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt} or return 0;
+    my $raf = $$dirInfo{RAF} or return 0;
+    my $outfile = $$dirInfo{OutFile} or return 0;
+
+    # check CR2 signature
+    return 0 if $$dataPt !~ /^.{8}CR\x02\0/s and
+        $exifTool->Error("Unsupported Canon RAW file. May cause problems if rewritten", 1);
+    # CR2 has a 16-byte header
+    $$dirInfo{NewDataPos} = 16;
+    my $newData = $exifTool->WriteDirectory($dirInfo, $tagTablePtr);
+    return 0 unless defined $newData;
+    unless ($$dirInfo{LastIFD}) {
+        $exifTool->Error("CR2 image IFD may not be deleted");
+        return 0;
+    }
+
+    if (length($newData)) {
+        # build 16 byte header for Canon RAW file
+        my $header = substr($$dataPt, 0, 16);
+        # set IFD0 pointer (may not be 16 if edited by PhotoMechanic)
+        Set32u(16, \$header, 4);
+        # last 4 bytes of header is pointer to last IFD
+        Set32u($$dirInfo{LastIFD}, \$header, 12);
+        Write($outfile, $header, $newData) or return 0;
+        undef $newData;     # free memory
+
+        # copy over image data now if necessary
+        if (ref $$dirInfo{ImageData}) {
+            $exifTool->CopyImageData($$dirInfo{ImageData}, $outfile) or return 0;
+            delete $$dirInfo{ImageData};
+        }
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Write CanonRaw (CRW) information
+# Inputs: 0) ExifTool object reference, 1) source dirInfo reference,
+#         2) tag table reference
+# Returns: true on sucess
+# Notes: Increments ExifTool CHANGED flag for each tag changed This routine is
+# different from all of the other write routines because Canon RAW files are
+# designed well!  So it isn't necessary to buffer the data in memory before
+# writing it out.  Therefore this routine doesn't return the directory data as
+# the rest of the Write routines do.  Instead, it writes to the dirInfo
+# Outfile on the fly --> much faster, efficient, and less demanding on memory!
+sub WriteCanonRaw($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    $exifTool or return 1;    # allow dummy access to autoload this package
+    my $blockStart = $$dirInfo{DirStart};
+    my $blockSize = $$dirInfo{DirLen};
+    my $raf = $$dirInfo{RAF} or return 0;
+    my $outfile = $$dirInfo{OutFile} or return 0;
+    my $outPos = $$dirInfo{OutPos} or return 0;
+    my $outBase = $outPos;
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my ($buff, $tagInfo);
+
+    # 4 bytes at end of block give directory position within block
+    $raf->Seek($blockStart+$blockSize-4, 0) or return 0;
+    $raf->Read($buff, 4) == 4 or return 0;
+    my $dirOffset = Get32u(\$buff,0) + $blockStart;
+    $raf->Seek($dirOffset, 0) or return 0;
+    $raf->Read($buff, 2) == 2 or return 0;
+    my $entries = Get16u(\$buff,0);             # get number of entries in directory
+    # read the directory (10 bytes per entry)
+    $raf->Read($buff, 10 * $entries) == 10 * $entries or return 0;
+    my $newDir = '';
+
+    # get hash of new information keyed by tagID
+    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+
+    # generate list of tags to add or delete (currently, we only allow JpgFromRaw
+    # and ThumbnailImage, to be added or deleted from the root CanonRaw directory)
+    my (@addTags, %delTag);
+    if ($$dirInfo{Nesting} == 0) {
+        my $tagID;
+        foreach $tagID (keys %$newTags) {
+            my $permanent = $newTags->{$tagID}->{Permanent};
+            push(@addTags, $tagID) if defined($permanent) and not $permanent;
+        }
+    }
+
+    my $index;
+    for ($index=0; ; ++$index) {
+        my ($pt, $tag, $size, $valuePtr, $ptr, $value);
+        if ($index<$entries) {
+            $pt = 10 * $index;
+            $tag = Get16u(\$buff, $pt);
+            $size = Get32u(\$buff, $pt+2);
+            $valuePtr = Get32u(\$buff, $pt+6);
+            $ptr = $valuePtr + $blockStart;        # all pointers relative to block start
+        }
+        # add any required new tags
+        # NOTE: can't currently add tags where value is stored in directory
+        if (@addTags and (not defined($tag) or $tag >= $addTags[0])) {
+            my $addTag = shift @addTags;
+            $tagInfo = $$newTags{$addTag};
+            my $newVal = $exifTool->GetNewValues($tagInfo);
+            if (defined $newVal) {
+                # add new directory entry
+                $newDir .= Set16u($addTag) . Set32u(length($newVal)) .
+                           Set32u($outPos - $outBase);
+                # write new value data
+                Write($outfile, $newVal) or return 0;
+                $outPos += length($newVal);     # update current position
+                $verbose > 1 and print $out "    + CanonRaw:$$tagInfo{Name}\n";
+                ++$exifTool->{CHANGED};
+            }
+            # set flag to delete this tag if found later
+            $delTag{$addTag} = 1;
+        }
+        last unless defined $tag;           # all done if no more directory entries
+        return 0 if $tag & 0x8000;      # top bit should not be set
+        my $tagID = $tag & 0x3fff;          # get tag ID
+        my $tagType = ($tag >> 8) & 0x38;   # get tag type
+        my $valueInDir = ($tag & 0x4000);   # flag for value in directory
+
+        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr,$tagID);
+        my $format = $crwTagFormat{$tagType};
+        my ($count, $subdir);
+        if ($tagInfo) {
+            $subdir = $$tagInfo{SubDirectory};
+            $format = $$tagInfo{Format} if $$tagInfo{Format};
+            $count = $$tagInfo{Count};
+        }
+        if ($valueInDir) {
+            $size = 8;
+            $value = substr($buff, $pt+2, $size);
+            # set count to 1 by default for normal values in directory
+            $count = 1 if not defined $count and $format and
+                          $format ne 'string' and not $subdir;
+        } else {
+            if ($tagType==0x28 or $tagType==0x30) {
+                # this type of tag specifies a raw subdirectory
+                my $name;
+                $tagInfo and $name = $$tagInfo{Name};
+                $name or $name = sprintf("CanonRaw_0x%.4x", $tagID);
+                my %subdirInfo = (
+                    DirName  => $name,
+                    DataLen  => 0,
+                    DirStart => $ptr,
+                    DirLen   => $size,
+                    Nesting  => $$dirInfo{Nesting} + 1,
+                    RAF      => $raf,
+                    Parent   => $$dirInfo{DirName},
+                    OutFile  => $outfile,
+                    OutPos   => $outPos,
+                );
+                my $result = $exifTool->WriteDirectory(\%subdirInfo, $tagTablePtr);
+                return 0 unless $result;
+                # set size and pointer for this new directory
+                $size = $subdirInfo{OutPos} - $outPos;
+                $valuePtr = $outPos - $outBase;
+                $outPos = $subdirInfo{OutPos};
+            } else {
+                # verify that the value data is within this block
+                $valuePtr + $size <= $blockSize or return 0;
+                # read value from file
+                $raf->Seek($ptr, 0) or return 0;
+                $raf->Read($value, $size) == $size or return 0;
+            }
+        }
+        # set count from tagInfo count if necessary
+        if ($format and not $count) {
+            # set count according to format and size
+            my $fnum = $Image::ExifTool::Exif::formatNumber{$format};
+            my $fsiz = $Image::ExifTool::Exif::formatSize[$fnum];
+            $count = int($size / $fsiz);
+        }
+        # edit subdirectory if necessary
+        if ($tagInfo) {
+            if ($subdir and $$subdir{TagTable}) {
+                my $name = $$tagInfo{Name};
+                my $newTagTable = Image::ExifTool::GetTagTable($$subdir{TagTable});
+                return 0 unless $newTagTable;
+                my $subdirStart = 0;
+                #### eval Start ()
+                $subdirStart = eval $$subdir{Start} if $$subdir{Start};
+                my $dirData = \$value;
+                my %subdirInfo = (
+                    Name     => $name,
+                    DataPt   => $dirData,
+                    DataLen  => $size,
+                    DirStart => $subdirStart,
+                    DirLen   => $size - $subdirStart,
+                    Nesting  => $$dirInfo{Nesting} + 1,
+                    RAF      => $raf,
+                    Parent   => $$dirInfo{DirName},
+                );
+                #### eval Validate ($dirData, $subdirStart, $size)
+                if (defined $$subdir{Validate} and not eval $$subdir{Validate}) {
+                    $exifTool->Warn("Invalid $name data");
+                } else {
+                    $subdir = $exifTool->WriteDirectory(\%subdirInfo, $newTagTable);
+                    if (defined $subdir and length $subdir) {
+                        if ($subdirStart) {
+                            # add header before data directory
+                            $value = substr($value, 0, $subdirStart) . $subdir;
+                        } else {
+                            $value = $subdir;
+                        }
+                    }
+                }
+            } elsif ($$newTags{$tagID}) {
+                if ($delTag{$tagID}) {
+                    $verbose > 1 and print $out "    - CanonRaw:$$tagInfo{Name}\n";
+                    ++$exifTool->{CHANGED};
+                    next;   # next since we already added this tag
+                }
+                my $oldVal;
+                if ($format) {
+                    $oldVal = ReadValue(\$value, 0, $format, $count, $size);
+                } else {
+                    $oldVal = $value;
+                }
+                my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+                if (Image::ExifTool::IsOverwriting($newValueHash, $oldVal)) {
+                    my $newVal = Image::ExifTool::GetNewValues($newValueHash);
+                    my $verboseVal;
+                    $verboseVal = $newVal if $verbose > 1;
+                    # convert to specified format if necessary
+                    if (defined $newVal and $format) {
+                        $newVal = WriteValue($newVal, $format, $count);
+                    }
+                    if (defined $newVal) {
+                        $value = $newVal;
+                        ++$exifTool->{CHANGED};
+                        if ($verbose > 1) {
+                            my $oldStr = $exifTool->Printable($oldVal);
+                            my $newStr = $exifTool->Printable($verboseVal);
+                            print $out "    - CanonRaw:$$tagInfo{Name} = '$oldStr'\n";
+                            print $out "    + CanonRaw:$$tagInfo{Name} = '$newStr'\n";
+                        }
+                    }
+                }
+            }
+        }
+        if ($valueInDir) {
+            my $len = length $value;
+            if ($len < 8) {
+                # pad with original garbage in case it contained something useful
+                $value .= substr($buff, $pt+2+8-$len, 8-$len);
+            } elsif ($len > 8) {   # this shouldn't happen
+                warn "Value too long! -- trucated\n";
+                $value = substr($value, 0, 8);
+            }
+            # create new directory entry
+            $newDir .= Set16u($tag) . $value;
+            next;   # all done this entry
+        }
+        if (defined $value) {
+            # don't allow value to change length unless Writable is 'resize'
+            my $writable = $$tagInfo{Writable};
+            my $diff = length($value) - $size;
+            if ($diff) {
+                if ($writable and $writable eq 'resize') {
+                    $size += $diff; # allow size to change
+                } elsif ($diff > 0) {
+                    $value .= ("\0" x $diff);
+                } else {
+                    $value = substr($value, 0, $size);
+                }
+            }
+            # pad value if necessary to align on even-byte boundary (as per CIFF spec)
+            $value .= "\0" if $size & 0x01;
+            $valuePtr = $outPos - $outBase;
+            # write out value data
+            Write($outfile, $value) or return 0;
+            $outPos += length($value);  # update current position in outfile
+        }
+        # create new directory entry
+        $newDir .= Set16u($tag) . Set32u($size) . Set32u($valuePtr);
+    }
+    # add the directory counts and offset to the directory start,
+    $entries = length($newDir) / 10;
+    $newDir = Set16u($entries) . $newDir . Set32u($outPos - $outBase);
+    # write directory data
+    Write($outfile, $newDir) or return 0;
+
+    # update current output file position in dirInfo
+    $$dirInfo{OutPos} = $outPos + length($newDir);
+    # save outfile directory start (needed for rewriting VRD trailer)
+    $$dirInfo{OutDirStart} = $outPos - $outBase;
+
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# write Canon RAW (CRW) file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid CRW file,
+#          or -1 if a write error occurred
+sub WriteCRW($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    my $outfile = $$dirInfo{OutFile};
+    my $raf = $$dirInfo{RAF};
+    my $rtnVal = 0;
+    my ($buff, $err, $sig);
+
+    $raf->Read($buff,2) == 2    or return 0;
+    SetByteOrder($buff)         or return 0;
+    $raf->Read($buff,4) == 4    or return 0;
+    $raf->Read($sig,8) == 8     or return 0;   # get file signature
+    $sig =~ /^HEAP(CCDR|JPGM)/  or return 0;   # validate signature
+    my $type = $1;
+    my $hlen = Get32u(\$buff, 0);   # get header length
+
+    if ($exifTool->{DEL_GROUP}->{MakerNotes}) {
+        if ($type eq 'CCDR') {
+            $exifTool->Error("Can't delete Makernotes group in CRW file");
+            return 0;
+        } else {
+            ++$exifTool->{CHANGED};
+            return 1;
+        }
+    }
+
+    # write header
+    $raf->Seek(0, 0)            or return 0;
+    $raf->Read($buff, $hlen) == $hlen or return 0;
+    Write($outfile, $buff) or $err = 1;
+
+    $raf->Seek(0, 2)            or return 0;   # seek to end of file
+    my $filesize = $raf->Tell() or return 0;
+
+    # build directory information for main raw directory
+    my %dirInfo = (
+        DataLen  => 0,
+        DirStart => $hlen,
+        DirLen   => $filesize - $hlen,
+        Nesting  => 0,
+        RAF      => $raf,
+        Parent   => 'CRW',
+        OutFile  => $outfile,
+        OutPos   => $hlen,
+    );
+    # process the raw directory
+    my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::CanonRaw::Main');
+    my $success = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+
+    my $trailPt;
+    while ($success) {
+        # check to see if trailer(s) exist(s)
+        my $trailInfo = Image::ExifTool::IdentifyTrailer($raf) or last;
+        # rewrite the trailer(s)
+        $buff = '';
+        $$trailInfo{OutFile} = \$buff;
+        $success = $exifTool->ProcessTrailers($trailInfo) or last;
+        $trailPt = $$trailInfo{OutFile};
+        # nothing to write if trailers were deleted
+        undef $trailPt if length($$trailPt) < 4;
+        last;
+    }
+    if ($success) {
+        # add CanonVRD trailer if writing as a block
+        $trailPt = $exifTool->AddNewTrailers($trailPt,'CanonVRD');
+        # write trailer
+        if ($trailPt) {
+            # must append DirStart pointer to end of trailer
+            my $newDirStart = Set32u($dirInfo{OutDirStart});
+            my $len = length $$trailPt;
+            my $pad = ($len & 0x01) ? ' ' : ''; # add pad byte if necessary
+            Write($outfile, $pad, substr($$trailPt,0,$len-4), $newDirStart) or $err = 1;
+        }
+        $rtnVal = $err ? -1 : 1;
+    } else {
+        $exifTool->Error('Error rewriting CRW file');
+    }
+    return $rtnVal;
+}
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::WriteCanonRaw.pl - Write Canon RAW (CRW and CR2) information
+
+=head1 SYNOPSIS
+
+These routines are autoloaded by Image::ExifTool::CanonRaw.
+
+=head1 DESCRIPTION
+
+This file contains routines used by ExifTool to write Canon CRW and CR2
+files and metadata.
+
+=head1 NOTES
+
+The CRW format is a pleasure to work with.  All pointer offsets are relative
+to the start of the data for each directory.  If TIFF/EXIF had implemented
+pointers in this way, it would be MUCH easier to read and write TIFF/JPEG
+files, and would lead to far fewer problems with corrupted metadata.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::CanonRaw(3pm)|Image::ExifTool::CanonRaw>,
+L<Image::ExifTool(3pm)|Image::ExifTool>,
+L<http://owl.phy.queensu.ca/~phil/exiftool/canon_raw.html>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/WriteExif.pl
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/WriteExif.pl	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/WriteExif.pl	(revision 20131)
@@ -0,0 +1,2488 @@
+#------------------------------------------------------------------------------
+# File:         WriteExif.pl
+#
+# Description:  Write EXIF meta information
+#
+# Revisions:    12/13/2004 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Exif;
+
+use strict;
+use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber
+            %lightSource %compression %photometricInterpretation %orientation);
+
+use Image::ExifTool::Fixup;
+
+sub InsertWritableProperties($$;$);
+
+# some information may be stored in different IFD's with the same meaning.
+# Use this lookup to decide when we should delete information that is stored
+# in another IFD when we write it to the preferred IFD.
+my %crossDelete = (
+    ExifIFD => 'IFD0',
+    IFD0    => 'ExifIFD',
+);
+
+# mandatory tag default values
+my %mandatory = (
+    IFD0 => {
+        0x011a => 72,       # XResolution
+        0x011b => 72,       # YResolution
+        0x0128 => 2,        # Resolution unit (inches)
+        0x0213 => 1,        # YCbCrPositioning (centered)
+      # 0x8769 => ????,     # ExifOffset
+    },
+    IFD1 => {
+        0x0103 => 6,        # Compression (JPEG)
+        0x011a => 72,       # XResolution
+        0x011b => 72,       # YResolution
+        0x0128 => 2,        # Resolution unit (inches)
+    },
+    ExifIFD => {
+        0x9000 => '0220',   # ExifVersion
+        0x9101 => "\1\2\3\0", # ComponentsConfiguration
+        0xa000 => '0100',   # FlashpixVersion
+        0xa001 => 0xffff,   # ColorSpace (uncalibrated)
+      # 0xa002 => ????,     # ExifImageWidth
+      # 0xa003 => ????,     # ExifImageLength
+    },
+    GPS => {
+        0x0000 => '2 2 0 0',# GPSVersionID
+    },
+    InteropIFD => {
+        0x0002 => '0100',   # InteropVersion
+    },
+);
+
+# The main EXIF table is unique because the tags from this table may appear
+# in many different directories.  For this reason, we introduce a
+# "WriteGroup" member to the tagInfo that tells us the preferred location
+# for writing each tag.  Here is the lookup for Writable flag (format)
+# and WriteGroup for all writable tags
+# - WriteGroup is ExifIFD unless otherwise specified
+# - Protected is 1 if the tag shouldn't be copied with SetNewValuesFromFile()
+my %writeTable = (
+    0x0001 => {             # InteropIndex
+        Protected => 1,
+        Writable => 'string',
+        WriteGroup => 'InteropIFD',
+    },
+    0x0002 => {             # InteropVersion
+        Protected => 1,
+        Writable => 'undef',
+        WriteGroup => 'InteropIFD',
+    },
+    0x000b => {             # ProcessingSoftware
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x00fe => {             # SubfileType
+        Protected => 1,
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+    },
+    0x00ff => {             # OldSubfileType
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x0100 => {             # ImageWidth
+        Protected => 1,
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+    },
+    0x0101 => {             # ImageHeigth
+        Protected => 1,
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+    },
+    0x0102 => {             # BitsPerSample
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Count => -1, # can be 1 or 3: -1 means 'variable'
+    },
+    0x0103 => {             # Compression
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x0106 => {             # PhotometricInterpretation
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x0107 => {             # Thresholding
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x0108 => {             # CellWidth
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x0109 => {             # CellLength
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x010a => {             # FillOrder
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x010d => {             # DocumentName
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x010e => {             # ImageDescription
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x010f => {             # Make
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x0110 => {             # Model
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x0112 => {             # Orientation
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x0115 => {             # SamplesPerPixel
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x0116 => {             # RowsPerStrip
+        Protected => 1,
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+    },
+    0x0118 => {             # MinSampleValue
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x0119 => {             # MaxSampleValue
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x011a => {             # XResolution
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+    },
+    0x011b => {             # YResolution
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+    },
+    0x011c => {             # PlanarConfiguration
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x011d => {             # PageName
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x011e => {             # XPosition
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+    },
+    0x011f => {             # YPosition
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+    },
+    0x0122 => {             # GrayResponseUnit
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x0128 => {             # ResolutionUnit
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x0129 => {             # PageNumber
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Count => 2,
+    },
+    0x0131 => {             # Software
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x0132 => {             # ModifyDate
+        Writable => 'string',
+        Shift => 'Time',
+        WriteGroup => 'IFD0',
+        PrintConvInv => 'Image::ExifTool::Exif::ExifDateTime($val)', 
+    },
+    0x013b => {             # Artist
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x013c => {             # HostComputer
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x013d => {             # Predictor
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x013e => {             # WhitePoint
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 2,
+    },
+    0x013f => {             # PrimaryChromaticities
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 6,
+    },
+    0x0141 => {             # HalftoneHints
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Count => 2,
+    },
+    0x0142 => {             # TileWidth
+        Protected => 1,
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+    },
+    0x0143 => {             # TileLength
+        Protected => 1,
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+    },
+    0x014c => {             # InkSet
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x0150 => {             # TargetPrinter
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x013c => {             # HostComputer
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x0211 => {             # YCbCrCoefficients
+        Protected => 1,
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 3,
+    },
+    0x0212 => {             # YCbCrSubSampling
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Count => 2,
+    },
+    0x0213 => {             # YCbCrPositioning
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x0214 => {             # ReferenceBlackWhite
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 6,
+    },
+    0x1000 => {             # RelatedImageFileFormat
+        Protected => 1,
+        Writable => 'string',
+        WriteGroup => 'InteropIFD',
+    },
+    0x1001 => {             # RelatedImageWidth
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'InteropIFD',
+    },
+    0x1002 => {             # RelatedImageLength (is really the height)
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'InteropIFD',
+    },
+    0x4746 => {             # Rating (MicrosoftPhoto)
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Avoid => 1,
+    },
+    0x4749 => {             # RatingPercent (MicrosoftPhoto)
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Avoid => 1,
+    },
+    0x8298 => {             # Copyright
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+#
+# Most of the tags below this belong in the ExifIFD...
+#
+    0x829a => {             # ExposureTime
+        Writable => 'rational64u',
+        PrintConvInv => 'eval $val',
+    },
+    0x829d => {             # FNumber
+        Writable => 'rational64u',
+        PrintConvInv => '$val',
+    },
+    0x83bb => {             # IPTC-NAA
+        # this should actually be written as 'undef' (see
+        # http://www.awaresystems.be/imaging/tiff/tifftags/iptc.html),
+        # but Photoshop writes it as int32u and Nikon Capture won't read
+        # anything else, so we do the same thing here...  Doh!
+        Format => 'undef',      # convert binary values as undef
+        Writable => 'int32u',   # but write int32u format code in IFD
+        WriteGroup => 'IFD0',
+    },
+    0x8546 => {             # SEMInfo
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x8822 => 'int16u',     # ExposureProgram
+    0x8824 => 'string',     # SpectralSensitivity
+    0x8827 => 'int16u',     # ISO
+    0x882a => {             # TimeZoneOffset
+        Writable => 'int16s',
+        Count => -1, # can be 1 or 2
+        Notes => q{
+            1 or 2 values: 1. The time zone offset of DateTimeOriginal from GMT in
+            hours, 2. If present, the time zone offset of ModifyDate
+        },
+    },
+    0x882b => 'int16u',     # SelfTimerMode
+    0x9000 => 'undef',      # ExifVersion
+    0x9003 => {             # DateTimeOriginal
+        Writable => 'string',
+        Shift => 'Time',
+        PrintConvInv => 'Image::ExifTool::Exif::ExifDateTime($val)', 
+    },
+    0x9004 => {             # CreateDate
+        Writable => 'string',
+        Shift => 'Time',
+        PrintConvInv => 'Image::ExifTool::Exif::ExifDateTime($val)', 
+    },
+    0x9101 => {             # ComponentsConfiguration
+        Writable => 'undef',
+        PrintConv => '$_=$val;s/\0.*//s;tr/\x01-\x06/YXWRGB/;s/X/Cb/g;s/W/Cr/g;$_',
+        PrintConvInv => q{
+            $_=uc($val); s/CR/W/g; s/CB/X/g;
+            return undef if /[^YXWRGB]/;
+            tr/YXWRGB/\x01-\x06/;
+            return $_ . "\0";
+        },
+    },
+    0x9102 => 'rational64u',# CompressedBitsPerPixel
+    0x9201 => {             # ShutterSpeedValue
+        Writable => 'rational64s',
+        ValueConvInv => '$val>0 ? -log($val)/log(2) : -100',
+        # do eval to convert things like '1/100'
+        PrintConvInv => 'eval $val',
+    },
+    0x9202 => {             # ApertureValue
+        Writable => 'rational64u',
+        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
+        PrintConvInv => '$val',
+    },
+    0x9203 => 'rational64s',# BrightnessValue
+    0x9204 => {             # ExposureCompensation
+        Writable => 'rational64s',
+        # do eval to convert things like '+2/3'
+        PrintConvInv => 'eval $val',
+    },
+    0x9205 => {             # MaxApertureValue
+        Writable => 'rational64u',
+        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
+        PrintConvInv => '$val',
+    },
+    0x9206 => {             # SubjectDistance
+        Writable => 'rational64u',
+        PrintConvInv => '$val=~s/\s*m$//;$val',
+    },
+    0x9207 => 'int16u',     # MeteringMode
+    0x9208 => 'int16u',     # LightSource
+    0x9209 => 'int16u',     # Flash
+    0x920a => {             # FocalLength
+        Writable => 'rational64u',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
+    },
+    0x9211 => 'int32u',     # ImageNumber
+    0x9212 => 'string',     # SecurityClassification
+    0x9213 => 'string',     # ImageHistory
+    0x9214 => {             # SubjectLocation
+        Writable => 'int16u',
+        Count => 4,  # write this SubjectLocation with 4 and the other with 2 values
+    },
+#    0x927c => 'undef',      # MakerNotes
+    0x9286 => {             # UserComment (string that starts with "ASCII\0\0\0")
+        Writable => 'undef',
+        PrintConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
+    },
+    0x9290 => 'string',     # SubSecTime
+    0x9291 => 'string',     # SubSecTimeOriginal
+    0x9292 => 'string',     # SubSecTimeDigitized
+    0x935c => {             # ImageSourceData
+        Writable => 'undef',
+        WriteGroup => 'IFD0',
+    },
+#    0x9928 => 'undef',      # Opto-ElectricConversionFactor
+    0x9c9b => {             # XPTitle
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Notes => q{
+            tags 0x9c9b-0x9c9f are used by Windows Explorer; special characters
+            in these values are converted to UTF-8 by default, or Windows Latin1
+            with the -L option. XPTitle is ignored by Windows Explorer if
+            ImageDescription exists
+        },
+        ValueConvInv => '$self->Charset2Unicode($val,"II") . "\0\0"',
+    },
+    0x9c9c => {             # XPComment
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        ValueConvInv => '$self->Charset2Unicode($val,"II") . "\0\0"',
+    },
+    0x9c9d => {             # XPAuthor
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Notes => 'ignored by Windows Explorer if Artist exists',
+        ValueConvInv => '$self->Charset2Unicode($val,"II") . "\0\0"',
+    },
+    0x9c9e => {             # XPKeywords
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        ValueConvInv => '$self->Charset2Unicode($val,"II") . "\0\0"',
+    },
+    0x9c9f => {             # XPSubject
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        ValueConvInv => '$self->Charset2Unicode($val,"II") . "\0\0"',
+    },
+    0xa000 => 'undef',      # FlashpixVersion
+    0xa001 => 'int16u',     # ColorSpace
+    0xa002 => 'int16u',     # ExifImageWidth (could also be int32u)
+    0xa003 => 'int16u',     # ExifImageLength (could also be int32u)
+    0xa004 => 'string',     # RelatedSoundFile
+    0xa20b => {             # FlashEnergy
+        Writable => 'rational64u',
+        Count => -1, # 1 or 2 (ref 12)
+    },
+#    0xa20c => 'undef',      # SpatialFrequencyResponse
+    0xa20e => 'rational64u',# FocalPlaneXResolution
+    0xa20f => 'rational64u',# FocalPlaneYResolution
+    0xa210 => 'int16u',     # FocalPlaneResolutionUnit
+    0xa214 => {             # SubjectLocation
+        Writable => 'int16u',
+        Count => 2,
+    },
+    0xa215 => 'rational64u',# ExposureIndex
+    0xa217 => 'int16u',     # SensingMethod
+    0xa300 => {             # FileSource
+        Writable => 'undef',
+        ValueConvInv => 'chr($val)',
+        PrintConvInv => 3,
+    },
+    0xa301 => {             # SceneType
+        Writable => 'undef',
+        ValueConvInv => 'chr($val)',
+    },
+    0xa302 => {             # CFAPattern
+        Writable => 'undef',
+        PrintConvInv => 'Image::ExifTool::Exif::GetCFAPattern($val)',
+    },
+    0xa401 => 'int16u',     # CustomRendered
+    0xa402 => 'int16u',     # ExposureMode
+    0xa403 => 'int16u',     # WhiteBalance
+    0xa404 => 'rational64u',# DigitalZoomRatio
+    0xa405 => {             # FocalLengthIn35mmFormat
+        Writable => 'int16u',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
+    },
+    0xa406 => 'int16u',     # SceneCaptureType
+    0xa407 => 'int16u',     # GainControl
+    0xa408 => {             # Contrast
+        Writable => 'int16u',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertParameter($val)',
+    },
+    0xa409 => {             # Saturation
+        Writable => 'int16u',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertParameter($val)',
+    },
+    0xa40a => {             # Sharpness
+        Writable => 'int16u',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertParameter($val)',
+    },
+#    0xa40b => 'undef',      # DeviceSettingDescription
+    0xa40c => 'int16u',     # SubjectDistanceRange
+    0xa420 => 'string',     # ImageUniqueID
+    0xa500 => 'rational64u',# Gamma
+    0xc4a5 => {             # PrintIM
+        Writable => 'undef',
+        WriteGroup => 'IFD0',
+    },
+#
+# DNG stuff (back in IFD0)
+#
+    0xc612 => {             # DNGVersion
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Count => 4,
+    },
+    0xc613 => {             # DNGBackwardVersion
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Count => 4,
+    },
+    0xc614 => {             # UniqueCameraModel
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0xc615 => {             # LocalizedCameraModel
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+        PrintConvInv => '$val',
+    },
+    0xc61e => {             # DefaultScale
+        Writable => 'rational64u',
+        WriteGroup => 'SubIFD',
+        Count => 2,
+    },
+    0xc61f => {             # DefaultCropOrigin
+        Writable => 'int32u',
+        WriteGroup => 'SubIFD',
+        Count => 2,
+    },
+    0xc620 => {             # DefaultCropSize
+        Writable => 'int32u',
+        WriteGroup => 'SubIFD',
+        Count => 2,
+    },
+    0xc629 => {             # AsShotWhiteXY
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 2,
+    },
+    0xc62a => {             # BaselineExposure
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+    },
+    0xc62b => {             # BaselineNoise
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+    },
+    0xc62c => {             # BaselineSharpness
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+    },
+    0xc62d => {             # BayerGreenSplit
+        Writable => 'int32u',
+        WriteGroup => 'SubIFD',
+    },
+    0xc62e => {             # LinearResponseLimit
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+    },
+    0xc62f => {             # CameraSerialNumber
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0xc630 => {             # DNGLensInfo
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 4,
+        PrintConvInv => '$_=$val;s/(-|mm f)/ /g;$_',
+    },
+    0xc631 => {             # ChromaBlurRadius
+        Writable => 'rational64u',
+        WriteGroup => 'SubIFD',
+    },
+    0xc632 => {             # AntiAliasStrength
+        Writable => 'rational64u',
+        WriteGroup => 'SubIFD',
+    },
+    0xc633 => {             # ShadowScale
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+    },
+    0xc635 => {             # MakerNoteSafety
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0xc65a => {             # CalibrationIlluminant1
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0xc65b => {             # CalibrationIlluminant2
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0xc65c => {             # BestQualityScale
+        Writable => 'rational64u',
+        WriteGroup => 'SubIFD',
+    },
+    0xc65d => {             # RawDataUniqueID
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Count => 16,
+        ValueConvInv => 'pack("H*",$val)',
+    },
+    0xc68b => {             # OriginalRawFileName
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0xc68c => {             # OriginalRawFileData (a writable directory)
+        Writable => 'undef',
+        WriteGroup => 'IFD0',
+    },
+    0xc68d => {             # ActiveArea
+        Writable => 'int32u',
+        WriteGroup => 'SubIFD',
+        Count => 4,
+    },
+    0xc68e => {             # MaskedAreas
+        Writable => 'int32u',
+        WriteGroup => 'SubIFD',
+        Count => 4,
+    },
+    0xc68f => {             # AsShotICCProfile
+        Writable => 'undef',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        WriteCheck => q{
+            require Image::ExifTool::ICC_Profile;
+            return Image::ExifTool::ICC_Profile::ValidateICC(\$val);
+        },
+    },
+    0xc690 => {             # AsShotPreProfileMatrix
+        Writable => 'rational64s',
+        Count => -1,
+        WriteGroup => 'IFD0',
+        Protected => 1,
+    },
+    0xc691 => {             # CurrentICCProfile
+        Writable => 'undef',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        WriteCheck => q{
+            require Image::ExifTool::ICC_Profile;
+            return Image::ExifTool::ICC_Profile::ValidateICC(\$val);
+        },
+    },
+    0xc692 => {             # CurrentPreProfileMatrix
+        Writable => 'rational64s',
+        Count => -1,
+        WriteGroup => 'IFD0',
+        Protected => 1,
+    },
+    0xea1d => {             # OffsetSchema
+        Writable => 'int32s',
+    },
+    # tags produced by Photoshop Camera RAW
+    # (avoid creating these tags unless there is no other option)
+    0xfde8 => {
+        Name => 'OwnerName',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Owner's Name: $val"},
+        Notes => q{
+            tags 0xfde8-0xfe58 are generated by Photoshop Camera RAW -- some
+            names are the same as other EXIF tags, but ExifTool will avoid
+            writing these unless they already exist in the file
+        },
+    },
+    0xfde9 => {
+        Name => 'SerialNumber',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Serial Number: $val"},
+    },
+    0xfdea => {
+        Name => 'Lens',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Lens: $val"},
+    },
+    0xfe4c => {
+        Name => 'RawFile',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Raw File: $val"},
+    },
+    0xfe4d => {
+        Name => 'Converter',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Converter: $val"},
+    },
+    0xfe4e => {
+        Name => 'WhiteBalance',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"White Balance: $val"},
+    },
+    0xfe51 => {
+        Name => 'Exposure',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Exposure: $val"},
+    },
+    0xfe52 => {
+        Name => 'Shadows',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Shadows: $val"},
+    },
+    0xfe53 => {
+        Name => 'Brightness',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Brightness: $val"},
+    },
+    0xfe54 => {
+        Name => 'Contrast',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Contrast: $val"},
+    },
+    0xfe55 => {
+        Name => 'Saturation',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Saturation: $val"},
+    },
+    0xfe56 => {
+        Name => 'Sharpness',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Sharpness: $val"},
+    },
+    0xfe57 => {
+        Name => 'Smoothness',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Smoothness: $val"},
+    },
+    0xfe58 => {
+        Name => 'MoireFilter',
+        Avoid => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/.*: //;$val',
+        ValueConvInv => q{"Moire Filter: $val"},
+    },
+);
+
+# insert our writable properties into main EXIF tag table
+InsertWritableProperties('Image::ExifTool::Exif::Main', \%writeTable, \&CheckExif);
+
+#------------------------------------------------------------------------------
+# Change date/time string to standard EXIF formatting
+# Inputs: 0) Date/Time string
+# Returns: formatted date/time string (or undef and issues warning on error)
+sub ExifDateTime($)
+{
+    my $val = shift;
+    my $rtnVal;
+    if ($val =~ /(\d{4})/g) {           # get YYYY
+        my $yr = $1;
+        my @a = ($val =~ /\d{2}/g);     # get MM, DD, and maybe hh, mm, ss
+        if (@a >= 2) {
+            push @a, '00' while @a < 5; # add hh, mm, ss if not given
+            # construct properly formatted date/time string
+            $rtnVal = "$yr:$a[0]:$a[1] $a[2]:$a[3]:$a[4]";
+        }
+    }
+    $rtnVal or warn "Improperly formatted date/time\n";
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Get binary CFA Pattern from a text string
+# Inputs: CFA pattern string (ie. '[Blue,Green][Green,Red]')
+# Returns: Binary CFA data or prints warning and returns undef on error
+sub GetCFAPattern($)
+{
+    my $val = shift;
+    my @rows = split /\]\s*\[/, $val;
+    @rows or warn("Rows not properly bracketed by '[]'\n"), return undef;
+    my @cols = split /,/, $rows[0];
+    @cols or warn("Colors not separated by ','\n"), return undef;
+    my $ny = @cols;
+    my $rtnVal = Set16u(scalar(@rows)) . Set16u(scalar(@cols));
+    my %cfaLookup = (red=>0, green=>1, blue=>2, cyan=>3, magenta=>4, yellow=>5, white=>6);
+    my $row;
+    foreach $row (@rows) {
+        @cols = split /,/, $row;
+        @cols == $ny or warn("Inconsistent number of colors in each row\n"), return undef;
+        foreach (@cols) {
+            tr/ \]\[//d;    # remove remaining brackets and any spaces
+            my $c = $cfaLookup{lc($_)};
+            defined $c or warn("Unknown color '$_'\n"), return undef;
+            $rtnVal .= Set8u($c);
+        }
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# validate raw values for writing
+# Inputs: 0) ExifTool object reference, 1) tagInfo hash reference,
+#         2) raw value reference
+# Returns: error string or undef (and possibly changes value) on success
+sub CheckExif($$$)
+{
+    my ($exifTool, $tagInfo, $valPtr) = @_;
+    my $format = $$tagInfo{Format} || $$tagInfo{Writable} || $tagInfo->{Table}->{WRITABLE};
+    if (not $format or $format eq '1') {
+        if ($tagInfo->{Groups}->{0} eq 'MakerNotes') {
+            return undef;   # OK to have no format for makernotes
+        } else {
+            return 'No writable format';
+        }
+    }
+    return Image::ExifTool::CheckValue($valPtr, $format, $$tagInfo{Count});
+}
+
+#------------------------------------------------------------------------------
+# encode exif ASCII/Unicode text from UTF8 or Latin
+# Inputs: 0) ExifTool ref, 1) text string
+# Returns: encoded string
+sub EncodeExifText($$)
+{
+    my ($exifTool, $val) = @_;
+    # does the string contain special characters?
+    if ($val =~ /[\x80-\xff]/) {
+        return "UNICODE\0" . $exifTool->Charset2Unicode($val);
+    } else {
+        return "ASCII\0\0\0$val";
+    }
+}
+
+#------------------------------------------------------------------------------
+# insert writable properties into main tag table
+# Inputs: 0) tag table name, 1) reference to writable properties
+#         2) [optional] CHECK_PROC reference
+sub InsertWritableProperties($$;$)
+{
+    my ($tableName, $writeTablePtr, $checkProc) = @_;
+    my $tag;
+    my $tagTablePtr = GetTagTable($tableName);
+    $checkProc and $tagTablePtr->{CHECK_PROC} = $checkProc;
+    foreach $tag (keys %$writeTablePtr) {
+        my $writeInfo = $$writeTablePtr{$tag};
+        my @infoList = GetTagInfoList($tagTablePtr, $tag);
+        if (@infoList) {
+            my $tagInfo;
+            foreach $tagInfo (@infoList) {
+                if (ref $writeInfo) {
+                    my $key;
+                    foreach $key (%$writeInfo) {
+                        $$tagInfo{$key} = $$writeInfo{$key};
+                    }
+                } else {
+                    $$tagInfo{Writable} = $writeInfo;
+                }
+            }
+        } else {
+            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $writeInfo);
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# rebuild maker notes to properly contain all value data
+# (some manufacturers put value data outside maker notes!!)
+# Inputs: 0) ExifTool object reference, 1) tag table reference,
+#         2) dirInfo reference
+# Returns: new maker note data (and creates MAKER_NOTE_FIXUP), or undef on error
+sub RebuildMakerNotes($$$)
+{
+    my ($exifTool, $tagTablePtr, $dirInfo) = @_;
+    my $dirStart = $$dirInfo{DirStart};
+    my $dirLen = $$dirInfo{DirLen};
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{DataPos} || 0;
+    my $rtnValue;
+    my %subdirInfo = %$dirInfo;
+
+    delete $exifTool->{MAKER_NOTE_FIXUP};
+
+    # don't need to rebuild text or binary-data maker notes
+    my $tagInfo = $$dirInfo{TagInfo};
+    my $subdir = $$tagInfo{SubDirectory};
+    my $proc = $$subdir{ProcessProc} || $$tagTablePtr{PROCESS_PROC} || \&ProcessExif;
+    if (($proc ne \&ProcessExif and $$tagInfo{Name} =~ /Text/) or
+         $proc eq \&Image::ExifTool::ProcessBinaryData)
+    {
+        return substr($$dataPt, $dirStart, $dirLen);
+    }
+    my $saveOrder = GetByteOrder();
+    my $loc = Image::ExifTool::MakerNotes::LocateIFD($exifTool,\%subdirInfo);
+    if (defined $loc) {
+        my $makerFixup = $subdirInfo{Fixup} = new Image::ExifTool::Fixup;
+        # create new exiftool object to rewrite the directory without changing it
+        my $newTool = new Image::ExifTool;
+        # don't copy over preview image
+        $newTool->SetNewValue(PreviewImage => '');
+        # copy all transient members over in case they are used for writing
+        # (CameraMake, CameraModel, etc)
+        foreach (grep /[a-z]/, keys %$exifTool) {
+            $$newTool{$_} = $$exifTool{$_};
+        }
+        # fix base offsets if specified
+        $newTool->Options(FixBase => $exifTool->Options('FixBase'));
+        # set FILE_TYPE to JPEG so PREVIEW_INFO will be generated
+        $newTool->{FILE_TYPE} = 'JPEG';
+        # drop any large tags
+        $newTool->{DROP_TAGS} = 1;
+        # rewrite maker notes
+        $rtnValue = $newTool->WriteDirectory(\%subdirInfo, $tagTablePtr);
+        if (defined $rtnValue and length $rtnValue) {
+            # add the dummy preview image if necessary
+            if ($newTool->{PREVIEW_INFO}) {
+                $makerFixup->SetMarkerPointers(\$rtnValue, 'PreviewImage', length($rtnValue));
+                $rtnValue .= $newTool->{PREVIEW_INFO}->{Data};
+                delete $newTool->{PREVIEW_INFO};
+            }
+            # add makernote header
+            $loc and $rtnValue = substr($$dataPt, $dirStart, $loc) . $rtnValue;
+            # adjust fixup for shift in start position
+            $makerFixup->{Start} += $loc;
+            # shift offsets according to original position of maker notes,
+            # and relative to the makernotes Base
+            $makerFixup->{Shift} += $dataPos + $dirStart +
+                                    $$dirInfo{Base} - $subdirInfo{Base};
+            # repair incorrect offsets if offsets were fixed
+            $makerFixup->{Shift} += $subdirInfo{FixedBy} || 0;
+            # fix up pointers to the specified offset
+            $makerFixup->ApplyFixup(\$rtnValue);
+        }
+        # save fixup information unless offsets were relative
+        unless ($subdirInfo{Relative}) {
+            # set shift so offsets are all relative to start of maker notes
+            $makerFixup->{Shift} -= $dataPos + $dirStart;
+            $exifTool->{MAKER_NOTE_FIXUP} = $makerFixup;    # save fixup for later
+        }
+    }
+    SetByteOrder($saveOrder);
+
+    return $rtnValue;
+}
+
+#------------------------------------------------------------------------------
+# Sort IFD directory entries
+# Inputs: 0) data reference, 1) directory start, 2) number of entries
+sub SortIFD($$$)
+{
+    my ($dataPt, $dirStart, $numEntries) = @_;
+    my ($index, %entries);
+    # split the directory into separate entries
+    my ($padding, $newDir) = ('','');
+    for ($index=0; $index<$numEntries; ++$index) {
+        my $entry = $dirStart + 2 + 12 * $index;
+        my $tagID = Get16u($dataPt, $entry);
+        my $entryData = substr($$dataPt, $entry, 12);
+        # silly software can pad directories with zero entries -- put these at the end
+        $tagID = 0x10000 unless $tagID or $index == 0;
+        # add new entry (allow for duplicate tag ID's, which shouldn't normally happen)
+        $entries{$tagID} or $entries{$tagID} = '';
+        $entries{$tagID} .= $entryData;
+    }
+    # sort the directory entries
+    my @sortedTags = sort { $a <=> $b } keys %entries;
+    foreach (@sortedTags) {
+        $newDir .= $entries{$_};
+    }
+    # replace original directory with new, sorted one
+    substr($$dataPt, $dirStart + 2, 12 * $numEntries) = $newDir . $padding;
+}
+
+#------------------------------------------------------------------------------
+# Validate IFD entries (strict validation to test possible chained IFD's)
+# Inputs: 0) dirInfo ref (must have RAF set), 1) optional DirStart
+# Returns: true if IFD looks OK
+sub ValidateIFD($;$)
+{
+    my ($dirInfo, $dirStart) = @_;
+    my $raf = $$dirInfo{RAF} or return 0;
+    my $base = $$dirInfo{Base};
+    $dirStart = $$dirInfo{DirStart} || 0 unless defined $dirStart;
+    my $offset = $dirStart + ($$dirInfo{DataPos} || 0);
+    my ($buff, $index);
+    $raf->Seek($offset + $base, 0) and $raf->Read($buff,2) == 2 or return 0;
+    my $numEntries = Get16u(\$buff,0);
+    $numEntries > 1 and $numEntries < 64 or return 0;
+    my $len = 12 * $numEntries;
+    $raf->Read($buff, $len) == $len or return 0;
+    my $lastID = -1;
+    for ($index=0; $index<$numEntries; ++$index) {
+        my $entry = 12 * $index;
+        my $tagID = Get16u(\$buff, $entry);
+        $tagID > $lastID or return 0;
+        my $format = Get16u(\$buff, $entry+2);
+        $format > 0 and $format <= 13 or return 0;
+        my $count = Get32u(\$buff, $entry+4);
+        $count > 0 or return 0;
+        $lastID = $tagID;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Update TIFF_END member if defined
+# Inputs: 0) ExifTool ref, 1) end of valid TIFF data
+sub UpdateTiffEnd($$)
+{
+    my ($exifTool, $end) = @_;
+    if (defined $exifTool->{TIFF_END} and
+        $exifTool->{TIFF_END} < $end)
+    {
+        $exifTool->{TIFF_END} = $end;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Handle error while writing EXIF
+# Inputs: 0) ExifTool ref, 1) error string, 2) flag set for minor error
+# Returns: undef on fatal error, or '' if minor error is ignored
+sub ExifErr($$$)
+{
+    my ($exifTool, $errStr, $minor) = @_;
+    return undef if $exifTool->Error($errStr, $minor);
+    return '';
+}
+
+#------------------------------------------------------------------------------
+# Write EXIF directory
+# Inputs: 0) ExifTool object reference, 1) source dirInfo reference,
+#         2) tag table reference
+# Returns: Exif data block (may be empty if no Exif data) or undef on error
+# Notes: Increments ExifTool CHANGED flag for each tag changed.  Also updates
+#        TIFF_END if defined with location of end of original TIFF image.
+# Returns IFD data in the following order:
+#   1. IFD0 directory followed by its data
+#   2. SubIFD directory followed by its data, thumbnail and image
+#   3. GlobalParameters, EXIF, GPS, Interop IFD's each with their data
+#   4. IFD1,IFD2,... directories each followed by their data
+#   5. Thumbnail and/or image data for each IFD, with IFD0 image last
+sub WriteExif($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    $exifTool or return 1;    # allow dummy access to autoload this package
+    my $dataPt = $$dirInfo{DataPt};
+    unless ($dataPt) {
+        my $emptyData = '';
+        $dataPt = \$emptyData;
+    }
+    my $dataPos = $$dirInfo{DataPos} || 0;
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dataLen = $$dirInfo{DataLen} || length($$dataPt);
+    my $dirLen = $$dirInfo{DirLen} || ($dataLen - $dirStart);
+    my $base = $$dirInfo{Base} || 0;
+    my $firstBase = $base;
+    my $raf = $$dirInfo{RAF};
+    my $dirName = $$dirInfo{DirName} || 'unknown';
+    my $fixup = $$dirInfo{Fixup} || new Image::ExifTool::Fixup;
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my (@offsetInfo, %xDelete);
+    my $newData = '';   # initialize buffer to receive new directory data
+    my ($nextIfdPos, %offsetData, $inMakerNotes);
+    my $deleteAll = 0;
+
+    # allow multiple IFD's in IFD0-IFD1-IFD2... chain
+    $$dirInfo{Multi} = 1 if $dirName eq 'IFD0' or $dirName eq 'SubIFD';
+    $inMakerNotes = 1 if $tagTablePtr->{GROUPS}->{0} eq 'MakerNotes';
+    my $ifd;
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# loop through each IFD
+#
+    for ($ifd=0; ; ++$ifd) {  # loop through multiple IFD's
+
+        # loop through new values and accumulate all information for this IFD
+        my (%set, $tagInfo);
+        my $tableGroup = $tagTablePtr->{GROUPS}->{0};
+        my $wrongDir = $crossDelete{$dirName};
+        foreach $tagInfo ($exifTool->GetNewTagInfoList($tagTablePtr)) {
+            my $tagID = $$tagInfo{TagID};
+            # evaluate conditional lists now if necessary
+            if (ref $tagTablePtr->{$tagID} eq 'ARRAY' or $$tagInfo{Condition}) {
+                my $curInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+                if (defined $curInfo and not $curInfo) {
+                    # need value to evaluate the condition
+                    my ($val) = $exifTool->GetNewValues($tagInfo);
+                    # must convert to binary for evaluating in Condition
+                    if ($$tagInfo{Format} and defined $val) {
+                        $val = WriteValue($val, $$tagInfo{Format}, $$tagInfo{Count});
+                    }
+                    if (defined $val) {
+                        $curInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$val,
+                                        $$tagInfo{Format} || 'undef', $$tagInfo{Count} || 1);
+                    }
+                }
+                # don't set this tag unless valid for the current condition
+                next unless defined $curInfo and $curInfo eq $tagInfo;
+            }
+            if ($$tagInfo{WriteCondition}) {
+                my $self = $exifTool;   # set $self to be used in eval
+                #### eval WriteCondition ($self)
+                unless (eval $$tagInfo{WriteCondition}) {
+                    $@ and warn $@;
+                    next;
+                }
+            }
+            my $newValueHash = $exifTool->GetNewValueHash($tagInfo, $dirName);
+            unless ($newValueHash) {
+                next unless $wrongDir;
+                # delete stuff from the wrong directory if setting somewhere else
+                $newValueHash = $exifTool->GetNewValueHash($tagInfo, $wrongDir);
+                next unless Image::ExifTool::IsOverwriting($newValueHash);
+                # don't cross delete if specifically deleting from the other directory
+                my $val = Image::ExifTool::GetNewValues($newValueHash);
+                next if not defined $val and $newValueHash->{WantGroup} and
+                        lc($newValueHash->{WantGroup}) eq lc($wrongDir);
+                # remove this tag if found in this IFD
+                $xDelete{$tagID} = 1;
+            }
+            $set{$tagID} = $tagInfo;
+        }
+        # save pointer to start of this IFD within the newData
+        my $newStart = length($newData);
+        my @subdirs;    # list of subdirectory data and tag table pointers
+        # determine if directory is contained within our data
+        my $mustRead;
+        if ($dirStart < 0 or $dirStart > $dataLen-2) {
+            $mustRead = 1;
+        } elsif ($dirLen > 2) {
+            my $len = 2 + 12 * Get16u($dataPt, $dirStart);
+            $mustRead = 1 if $dirStart + $len > $dataLen;
+        }
+        # read IFD from file if necessary
+        if ($raf and $mustRead) {
+            # read the count of entries in this IFD
+            my $offset = $dirStart + $dataPos;
+            my ($buff, $buf2);
+            unless ($raf->Seek($offset + $base, 0) and $raf->Read($buff,2) == 2) {
+                return ExifErr($exifTool, "Bad IFD or truncated file in $dirName", $inMakerNotes);
+            }
+            my $len = 12 * Get16u(\$buff,0);
+            # (also read next IFD pointer if available)
+            unless ($raf->Read($buf2, $len+4) >= $len) {
+                return ExifErr($exifTool, "Error reading $dirName", $inMakerNotes);
+            }
+            $buff .= $buf2;
+            # make copy of dirInfo since we're going to modify it
+            my %newDirInfo = %$dirInfo;
+            $dirInfo = \%newDirInfo;
+            # update directory parameters for the newly loaded IFD
+            $dataPt = $$dirInfo{DataPt} = \$buff;
+            $dirStart = $$dirInfo{DirStart} = 0;
+            $dataPos = $$dirInfo{DataPos} = $offset;
+            $dataLen = $$dirInfo{DataLen} = length $buff;
+            $dirLen = $$dirInfo{DirLen} = $dataLen;
+            # only account for nextIFD pointer if we are going to use it
+            $len += 4 if $dataLen==$len+6 and ($$dirInfo{Multi} or $buff =~ /\0{4}$/);
+            UpdateTiffEnd($exifTool, $offset+$base+2+$len);
+        }
+        my ($len, $numEntries);
+        if ($dirStart + 4 < $dataLen) {
+            $numEntries = Get16u($dataPt, $dirStart);
+            $len = 2 + 12 * $numEntries;
+            if ($dirStart + $len > $dataLen) {
+                return ExifErr($exifTool, "Truncated $dirName directory", $inMakerNotes);
+            }
+            # sort entries if necessary (but not in maker notes IFDs)
+            unless ($inMakerNotes) {
+                my $index;
+                my $lastID = -1;
+                for ($index=0; $index<$numEntries; ++$index) {
+                    my $tagID = Get16u($dataPt, $dirStart + 2 + 12 * $index);
+                    # check for proper sequence (but ignore null entries at end)
+                    if ($tagID < $lastID and $tagID) {
+                        SortIFD($dataPt, $dirStart, $numEntries);
+                        $exifTool->Warn("Entries in $dirName were out of sequence. Fixed.");
+                        last;
+                    }
+                    $lastID = $tagID;
+                }
+            }
+        } else {
+            $numEntries = $len = 0;
+        }
+
+        # fix base offsets
+        if ($dirName eq 'MakerNotes' and $$dirInfo{Parent} eq 'ExifIFD' and
+            Image::ExifTool::MakerNotes::FixBase($exifTool, $dirInfo))
+        {
+            # update local variables from fixed values
+            $base = $$dirInfo{Base};
+            $dataPos = $$dirInfo{DataPos};
+        }
+
+        # initialize variables to handle mandatory tags
+        my $mandatory = $mandatory{$dirName};
+        my $allMandatory;
+        if ($mandatory) {
+            # use X/Y resolution values from JFIF if available
+            if ($dirName eq 'IFD0' and defined $$exifTool{JFIFYResolution}) {
+                my %ifd0Vals = %$mandatory;
+                $ifd0Vals{0x011a} = $$exifTool{JFIFXResolution};
+                $ifd0Vals{0x011b} = $$exifTool{JFIFYResolution};
+                $ifd0Vals{0x0128} = $$exifTool{JFIFResolutionUnit} + 1;
+                $mandatory = \%ifd0Vals;
+            }
+            $allMandatory = 0;  # initialize to zero
+            # add mandatory tags if creating a new directory
+            unless ($numEntries) {
+                foreach (keys %$mandatory) {
+                    $set{$_} or $set{$_} = $$tagTablePtr{$_};
+                }
+            }
+        } else {
+            undef $deleteAll;   # don't remove directory (no mandatory entries)
+        }
+        my ($addDirs, @newTags);
+        if ($inMakerNotes) {
+            $addDirs = { };
+        } else {
+            # get a hash of directories we will be writing in this one
+            $addDirs = $exifTool->GetAddDirHash($tagTablePtr, $dirName);
+            # make a union of tags & dirs (can set whole dirs, like MakerNotes)
+            my %allTags = %set;
+            foreach (keys %$addDirs) {
+                $allTags{$_} = $$addDirs{$_};
+            }
+            # make sorted list of new tags to be added
+            @newTags = sort { $a <=> $b } keys(%allTags);
+        }
+        my $dirBuff = '';   # buffer for directory data
+        my $valBuff = '';   # buffer for value data
+        my @valFixups;      # list of fixups for offsets in valBuff
+        # fixup for offsets in dirBuff
+        my $dirFixup = new Image::ExifTool::Fixup;
+        my $entryBasedFixup;
+        my $index = 0;
+        my $lastTagID = -1;
+        my ($oldInfo, $oldFormat, $oldFormName, $oldCount, $oldSize, $oldValue);
+        my ($readFormat, $readFormName, $readCount); # format for reading old value(s)
+        my ($entry, $valueDataPt, $valueDataPos, $valueDataLen, $valuePtr, $valEnd);
+        my $oldID = -1;
+        my $newID = -1;
+#..............................................................................
+# loop through entries in new directory
+#
+Entry:  for (;;) {
+
+            if (defined $oldID and $oldID == $newID) {
+#
+# read next entry from existing directory
+#
+                if ($index < $numEntries) {
+                    $entry = $dirStart + 2 + 12 * $index;
+                    $oldID = Get16u($dataPt, $entry);
+                    $readFormat = $oldFormat = Get16u($dataPt, $entry+2);
+                    $readCount = $oldCount = Get32u($dataPt, $entry+4);
+                    if ($oldFormat < 1 or $oldFormat > 13) {
+                        # don't write out null directory entry
+                        unless ($oldFormat or $oldCount or not $index) {
+                            ++$index;
+                            $newID = $oldID;    # pretend we wrote this
+                            # must keep same directory size to avoid messing up our fixed offsets
+                            $dirBuff .= ("\0" x 12) if $$dirInfo{FixBase};
+                            next;
+                        }
+                        return ExifErr($exifTool, "Bad format ($oldFormat) for $dirName entry $index", $inMakerNotes);
+                    }
+                    $readFormName = $oldFormName = $formatName[$oldFormat];
+                    $valueDataPt = $dataPt;
+                    $valueDataPos = $dataPos;
+                    $valueDataLen = $dataLen;
+                    $valuePtr = $entry + 8;
+                    $oldSize = $oldCount * $formatSize[$oldFormat];
+                    # must try direct method first so we will get unknown tags too
+                    # (this is necessary so we don't miss a tag we want to Drop)
+                    $oldInfo = $$tagTablePtr{$oldID};
+                    if (ref $oldInfo ne 'HASH' or $$oldInfo{Condition}) {
+                        $oldInfo = $exifTool->GetTagInfo($tagTablePtr, $oldID);
+                    }
+                    my $readFromFile;
+                    if ($oldSize > 4) {
+                        $valuePtr = Get32u($dataPt, $valuePtr);
+                        # fix valuePtr if necessary
+                        if ($$dirInfo{FixOffsets}) {
+                            $valEnd or $valEnd = $dataPos + $dirStart + 2 + 12 * $numEntries + 4;
+                            my ($tagID, $size, $wFlag) = ($oldID, $oldSize, 1);
+                            #### eval FixOffsets($valuePtr, $valEnd, $size, $tagID, $wFlag)
+                            eval $$dirInfo{FixOffsets};
+                            unless (defined $valuePtr) {
+                                unless ($$exifTool{DROP_TAGS}) {
+                                    my $tagStr = $oldInfo ? $$oldInfo{Name} : sprintf("tag 0x%x",$oldID);
+                                    return undef if $exifTool->Error("Bad $dirName directory pointer for $tagStr", $inMakerNotes);
+                                }
+                                goto DropTag;
+                            }
+                        }
+                        # convert offset to pointer in $$dataPt
+                        if ($$dirInfo{EntryBased} or (ref $$tagTablePtr{$oldID} eq 'HASH' and
+                            $tagTablePtr->{$oldID}->{EntryBased}))
+                        {
+                            $valuePtr += $entry;
+                        } else {
+                            $valuePtr -= $dataPos;
+                        }
+                        # get value by seeking in file if we are allowed
+                        if ($valuePtr < 0 or $valuePtr+$oldSize > $dataLen) {
+                            my ($pos, $tagStr, $invalidPreview);
+                            if ($oldInfo) {
+                                $tagStr = $$oldInfo{Name};
+                            } elsif (defined $oldInfo) {
+                                my $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $oldID, \ '', $oldFormName, $oldCount);
+                                $tagStr = $$tmpInfo{Name} if $tmpInfo;
+                            }
+                            $tagStr or $tagStr = sprintf("tag 0x%x",$oldID);
+                            # allow PreviewImage to run outside EXIF segment
+                            if (not $raf and $tagStr eq 'PreviewImage') {
+                                $raf = $exifTool->{RAF};
+                                if ($raf) {
+                                    $pos = $raf->Tell();
+                                } else {
+                                    $invalidPreview = 1;
+                                }
+                            }
+                            if ($raf) {
+                                my $success = ($raf->Seek($base + $valuePtr + $dataPos, 0) and
+                                               $raf->Read($oldValue, $oldSize) == $oldSize);
+                                if (defined $pos) {
+                                    $raf->Seek($pos, 0);
+                                    undef $raf;
+                                    unless ($success and $oldValue =~ /^(\xff\xd8\xff|.\xd8\xff\xdb)/s) {
+                                        $exifTool->Error("Bad PreviewImage pointer in $dirName", 1);
+                                        $invalidPreview = 1;
+                                        $success = 1;   # continue writing directory
+                                    }
+                                }
+                                unless ($success) {
+                                    return undef if $exifTool->Error("Error reading value for $dirName entry $index", $inMakerNotes);
+                                    goto DropTag;
+                                }
+                            } elsif (not $invalidPreview) {
+                                return undef if $exifTool->Error("Bad $dirName directory pointer for $tagStr", $inMakerNotes);
+                                goto DropTag;
+                            }
+                            if ($invalidPreview) {
+                                $oldValue = 'none';     # flag for missing preview
+                                $oldSize = length $oldValue;
+                                $valuePtr = 0;
+                            } else {
+                                UpdateTiffEnd($exifTool, $base+$valuePtr+$dataPos+$oldSize);
+                            }
+                            # update pointers for value just read from file
+                            $valueDataPt = \$oldValue;
+                            $valueDataPos = $valuePtr + $dataPos;
+                            $valueDataLen = $oldSize;
+                            $valuePtr = 0;
+                            $readFromFile = 1;
+                        }
+                    }
+                    # read value if we haven't already
+                    $oldValue = substr($$valueDataPt, $valuePtr, $oldSize) unless $readFromFile;
+                    # get tagInfo using value if necessary
+                    if (defined $oldInfo and not $oldInfo) {
+                        $oldInfo = $exifTool->GetTagInfo($tagTablePtr, $oldID, \$oldValue, $oldFormName, $oldCount);
+                    }
+                    # override format we use to read the value if specified
+                    if ($oldInfo) {
+                        if ($$oldInfo{Drop} and $$exifTool{DROP_TAGS}) {
+                            # don't rewrite this tag
+DropTag:                    ++$index;
+                            $oldID = $newID;
+                            next;
+                        }
+                        if ($$oldInfo{Format}) {
+                            $readFormName = $$oldInfo{Format};
+                            $readFormat = $formatNumber{$readFormName};
+                            unless ($readFormat) {
+                                # we aren't reading in a standard EXIF format, so rewrite in old format
+                                $readFormName = $oldFormName;
+                                $readFormat = $oldFormat;
+                            }
+                            # adjust number of items to read if format size changed
+                            $readCount = $oldSize / $formatSize[$readFormat];
+                        }
+                    }
+                    if ($oldID <= $lastTagID and not $inMakerNotes) {
+                        my $str = $oldInfo ? "$$oldInfo{Name} tag" : sprintf('tag 0x%x',$oldID);
+                        if ($oldID == $lastTagID) {
+                            $exifTool->Warn("Duplicate $str in $dirName");;
+                        } else {
+                            $exifTool->Warn("\u$str out of sequence in $dirName");
+                        }
+                    }
+                    $lastTagID = $oldID;
+                    ++$index;               # increment index for next time
+                } else {
+                    undef $oldID;           # no more existing entries
+                }
+            }
+#
+# write out all new tags, up to and including this one
+#
+            $newID = $newTags[0];
+            my $isNew;  # -1=tag is old, 0=tag same as existing, 1=tag is new
+            if (not defined $oldID) {
+                last unless defined $newID;
+                $isNew = 1;
+            } elsif (not defined $newID) {
+                # maker notes will have no new tags defined
+                if ($set{$oldID}) {
+                    $newID = $oldID;
+                    $isNew = 0;
+                } else {
+                    $isNew = -1;
+                }
+            } else {
+                $isNew = $oldID <=> $newID;
+            }
+            my $newInfo = $oldInfo;
+            my $newFormat = $oldFormat;
+            my $newFormName = $oldFormName;
+            my $newCount = $oldCount;
+            my $ifdFormName;
+            my $newValue;
+            my $newValuePt = $isNew >= 0 ? \$newValue : \$oldValue;
+            my $isOverwriting;
+
+            if ($isNew >= 0) {
+                # add, edit or delete this tag
+                shift @newTags; # remove from list
+                if ($set{$newID}) {
+#
+# set the new tag value (or 'next' if deleting tag)
+#
+                    $newInfo = $set{$newID};
+                    $newCount = $$newInfo{Count};
+                    my ($val, $newVal);
+                    my $newValueHash = $exifTool->GetNewValueHash($newInfo, $dirName);
+                    if ($isNew > 0) {
+                        # don't create new entry unless requested
+                        if ($newValueHash) {
+                            next unless Image::ExifTool::IsCreating($newValueHash);
+                            $isOverwriting = Image::ExifTool::IsOverwriting($newValueHash);
+                        } else {
+                            next if $xDelete{$newID};       # don't create if cross deleting
+                            $newVal = $$mandatory{$newID};  # get value for mandatory tag
+                            $isOverwriting = 1;
+                        }
+                        # convert using new format
+                        if ($$newInfo{Format}) {
+                            $newFormName = $$newInfo{Format};
+                            # use Writable flag to specify IFD format code
+                            $ifdFormName = $$newInfo{Writable};
+                        } else {
+                            $newFormName = $$newInfo{Writable};
+                            unless ($newFormName) {
+                                warn("No format for $dirName $$newInfo{Name}\n");
+                                next;
+                            }
+                        }
+                        $newFormat = $formatNumber{$newFormName};
+                    } elsif ($newValueHash or $xDelete{$newID}) {
+                        unless ($newValueHash) {
+                            $newValueHash = $exifTool->GetNewValueHash($newInfo, $wrongDir);
+                        }
+                        # read value
+                        $val = ReadValue(\$oldValue, 0, $readFormName, $readCount, $oldSize);
+                        if ($$newInfo{Format}) {
+                            $newFormName = $$newInfo{Format};
+                            # override existing format if necessary
+                            $ifdFormName = $$newInfo{Writable};
+                            $ifdFormName = $oldFormName unless $ifdFormName and $ifdFormName ne '1';
+                            $newFormat = $formatNumber{$newFormName};
+                        }
+                        if ($inMakerNotes and $readFormName ne 'string' and $readFormName ne 'undef') {
+                            # keep same size in maker notes unless string or binary
+                            $newCount = $oldCount * $formatSize[$oldFormat] / $formatSize[$newFormat];
+                        }
+                        $isOverwriting = Image::ExifTool::IsOverwriting($newValueHash, $val);
+                    }
+                    if ($isOverwriting) {
+                        $newVal = Image::ExifTool::GetNewValues($newValueHash) unless defined $newVal;
+                        # value undefined if deleting this tag
+                        # (also delete tag if cross-deleting and this isn't a date/time shift)
+                        if (not defined $newVal or ($xDelete{$newID} and not defined $$newValueHash{Shift})) {
+                            if ($$newInfo{RawConvInv} and defined $$newValueHash{Value}) {
+                                goto NoOverwrite;   # error in RawConvInv, so rewrite existing tag
+                            }
+                            unless ($isNew) {
+                                ++$exifTool->{CHANGED};
+                                $val = $exifTool->Printable($val);
+                                $verbose > 1 and print $out "    - $dirName:$$newInfo{Name} = '$val'\n";
+                            }
+                            next;
+                        }
+                        if (length $newVal) {
+                            if ($newCount and $newCount < 0) {
+                                # set count to number of values if variable
+                                my @vals = split ' ',$newVal;
+                                $newCount = @vals;
+                            }
+                            # convert to binary format
+                            $newValue = WriteValue($newVal, $newFormName, $newCount);
+                            unless (defined $newValue) {
+                                $exifTool->Warn("Error writing $dirName:$$newInfo{Name}");
+                                goto NoOverwrite;
+                            }
+                        } else {
+                            $exifTool->Warn("Can't write zero length $$newInfo{Name} in $tagTablePtr->{GROUPS}->{1}");
+                            goto NoOverwrite;
+                        }
+                        if ($isNew >= 0) {
+                            $newCount = length($newValue) / $formatSize[$newFormat];
+                            ++$exifTool->{CHANGED};
+                            if ($verbose > 1) {
+                                $val = $exifTool->Printable($val);
+                                $newVal = $exifTool->Printable($newVal);
+                                print $out "    - $dirName:$$newInfo{Name} = '$val'\n" unless $isNew;
+                                my $str = $newValueHash ? '' : ' (mandatory)';
+                                print $out "    + $dirName:$$newInfo{Name} = '$newVal'$str\n";
+                            }
+                        }
+                    } else {
+NoOverwrite:            next if $isNew > 0;
+                        $isNew = -1;        # rewrite existing tag
+                    }
+                    # set format for EXIF IFD if different than conversion format
+                    if ($ifdFormName) {
+                        $newFormName = $ifdFormName;
+                        $newFormat = $formatNumber{$newFormName};
+                    }
+
+                } elsif ($isNew > 0) {
+#
+# create new subdirectory
+#
+                    $newInfo = $$addDirs{$newID} or warn('internal error'), next;
+                    # make sure we don't try to generate a new MakerNotes directory
+                    # or a SubIFD
+                    next if $$newInfo{MakerNotes} or $$newInfo{Name} eq 'SubIFD';
+                    my $subTable;
+                    if ($newInfo->{SubDirectory}->{TagTable}) {
+                        $subTable = GetTagTable($newInfo->{SubDirectory}->{TagTable});
+                    } else {
+                        $subTable = $tagTablePtr;
+                    }
+                    # create empty source directory
+                    my %sourceDir = (
+                        Parent => $dirName,
+                        Fixup => new Image::ExifTool::Fixup,
+                    );
+                    $sourceDir{DirName} = $newInfo->{Groups}->{1} if $$newInfo{SubIFD};
+                    $newValue = $exifTool->WriteDirectory(\%sourceDir, $subTable);
+                    # only add new directory if it isn't empty
+                    next unless defined $newValue and length($newValue);
+                    # set the fixup start location
+                    if ($$newInfo{SubIFD}) {
+                        # subdirectory is referenced by an offset in value buffer
+                        my $subdir = $newValue;
+                        $newValue = Set32u(0xfeedf00d);
+                        push @subdirs, {
+                            DataPt => \$subdir,
+                            Table => $subTable,
+                            Fixup => $sourceDir{Fixup},
+                            Offset => length($dirBuff) + 8,
+                            Where => 'dirBuff',
+                        };
+                        $newFormName = 'int32u';
+                        $newFormat = $formatNumber{$newFormName};
+                    } else {
+                        # subdirectory goes directly into value buffer
+                        $sourceDir{Fixup}->{Start} += length($valBuff);
+                        # use Writable to set format, otherwise 'undef'
+                        $newFormName = $$newInfo{Writable};
+                        unless ($newFormName and $formatNumber{$newFormName}) {
+                            $newFormName = 'undef';
+                        }
+                        $newFormat = $formatNumber{$newFormName};
+                        push @valFixups, $sourceDir{Fixup};
+                    }
+                } elsif ($$newInfo{Format} and $$newInfo{Writable} and $$newInfo{Writable} ne '1') {
+                    # use specified write format
+                    $newFormName = $$newInfo{Writable};
+                    $newFormat = $formatNumber{$newFormName};
+                }
+            }
+            if ($isNew < 0) {
+                # just rewrite existing tag
+                $newID = $oldID;
+                $newValue = $oldValue;
+                $newFormat = $oldFormat; # (just in case it changed)
+                $newFormName = $oldFormName;
+            }
+            if ($newInfo) {
+#
+# load necessary data for this tag (thumbnail image, etc)
+#
+                if ($$newInfo{DataTag} and $isNew >= 0) {
+                    my $dataTag = $$newInfo{DataTag};
+                    # load data for this tag
+                    unless (defined $offsetData{$dataTag}) {
+                        $offsetData{$dataTag} = $exifTool->GetNewValues($dataTag);
+                        my $err;
+                        if (defined $offsetData{$dataTag}) {
+                            if ($exifTool->{FILE_TYPE} eq 'JPEG' and
+                                $dataTag ne 'PreviewImage' and length($offsetData{$dataTag}) > 60000)
+                            {
+                                delete $offsetData{$dataTag};
+                                $err = "$dataTag not written (too large for JPEG segment)";
+                            }
+                        } else {
+                            $err = "$dataTag not found";
+                        }
+                        if ($err) {
+                            $exifTool->Warn($err) if $$newInfo{IsOffset};
+                            delete $set{$newID};    # remove from list of tags we are setting
+                            next;
+                        }
+                    }
+                }
+#
+# write maker notes
+#
+                if ($$newInfo{MakerNotes}) {
+                    # don't write new makernotes if we are deleting this group
+                    if ($exifTool->{DEL_GROUP}->{MakerNotes} and
+                        ($exifTool->{DEL_GROUP}->{MakerNotes} != 2 or $isNew <= 0))
+                    {
+                        if ($isNew <= 0) {
+                            ++$exifTool->{CHANGED};
+                            $verbose and print $out "  Deleting MakerNotes\n";
+                        }
+                        next;
+                    }
+                    my $saveOrder = GetByteOrder();
+                    if ($isNew >= 0 and $set{$newID}) {
+                        # we are writing a whole new maker note block
+                        # --> add fixup information if necessary
+                        my $newValueHash = $exifTool->GetNewValueHash($newInfo, $dirName);
+                        if ($newValueHash and $newValueHash->{MAKER_NOTE_FIXUP}) {
+                            # must clone fixup because we will be shifting it
+                            my $makerFixup = $newValueHash->{MAKER_NOTE_FIXUP}->Clone();
+                            my $valLen = length($valBuff);
+                            $makerFixup->{Start} += $valLen;
+                            push @valFixups, $makerFixup;
+                        }
+                    } else {
+                        # update maker notes if possible
+                        my %subdirInfo = (
+                            Base => $base,
+                            DataPt => $valueDataPt,
+                            DataPos => $valueDataPos,
+                            DataLen => $valueDataLen,
+                            DirStart => $valuePtr,
+                            DirLen => $oldSize,
+                            DirName => 'MakerNotes',
+                            Parent => $dirName,
+                            TagInfo => $newInfo,
+                            RAF => $raf,
+                        );
+                        if ($$newInfo{SubDirectory}) {
+                            my $sub = $$newInfo{SubDirectory};
+                            $subdirInfo{FixBase} = 1 if $$sub{FixBase};
+                            $subdirInfo{FixOffsets} = $$sub{FixOffsets};
+                            $subdirInfo{EntryBased} = $$sub{EntryBased};
+                            $subdirInfo{NoFixBase} = 1 if $$sub{Base};
+                        }
+                        # get the proper tag table for these maker notes
+                        my $subTable;
+                        if ($oldInfo and $oldInfo->{SubDirectory}) {
+                            $subTable = $oldInfo->{SubDirectory}->{TagTable};
+                            $subTable and $subTable = Image::ExifTool::GetTagTable($subTable);
+                        } else {
+                            $exifTool->Warn('Internal problem getting maker notes tag table');
+                        }
+                        $subTable or $subTable = $tagTablePtr;
+                        my $subdir;
+                        # look for IFD-style maker notes
+                        my $loc = Image::ExifTool::MakerNotes::LocateIFD($exifTool,\%subdirInfo);
+                        if (defined $loc) {
+                            # we need fixup data for this subdirectory
+                            $subdirInfo{Fixup} = new Image::ExifTool::Fixup;
+                            # rewrite maker notes
+                            $subdir = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+                        } elsif ($$subTable{PROCESS_PROC} and
+                                 $$subTable{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData)
+                        {
+                            my $sub = $oldInfo->{SubDirectory};
+                            if (defined $$sub{Start}) {
+                                #### eval Start ($valuePtr)
+                                my $start = eval $$sub{Start};
+                                $loc = $start - $valuePtr;
+                                $subdirInfo{DirStart} = $start;
+                                $subdirInfo{DirLen} -= $loc;
+                            } else {
+                                $loc = 0;
+                            }
+                            # rewrite maker notes
+                            $subdir = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+                        } else {
+                            $exifTool->Warn('Maker notes could not be parsed',1);
+                        }
+                        if (defined $subdir) {
+                            next unless length $subdir;
+                            my $valLen = length($valBuff);
+                            # restore existing header and substitute the new
+                            # maker notes for the old value
+                            $newValue = substr($oldValue, 0, $loc) . $subdir;
+                            my $makerFixup = $subdirInfo{Fixup};
+                            my $previewInfo = $exifTool->{PREVIEW_INFO};
+                            if ($subdirInfo{Relative}) {
+                                # apply a one-time fixup to $loc since offsets are relative
+                                $makerFixup->{Start} += $loc;
+                                # shift all offsets to be relative to new base
+                                my $baseShift = $valueDataPos + $valuePtr + $base - $subdirInfo{Base};
+                                $makerFixup->{Shift} += $baseShift;
+                                $makerFixup->ApplyFixup(\$newValue);
+                                if ($previewInfo) {
+                                    # remove all but PreviewImage fixup (since others shouldn't change)
+                                    foreach (keys %{$makerFixup->{Pointers}}) {
+                                        /_PreviewImage$/ or delete $makerFixup->{Pointers}->{$_};
+                                    }
+                                    # zero pointer so we can see how it gets shifted later
+                                    $makerFixup->SetMarkerPointers(\$newValue, 'PreviewImage', 0);
+                                    # set the pointer to the start of the EXIF information
+                                    # add preview image fixup to list of value fixups
+                                    $makerFixup->{Start} += $valLen;
+                                    push @valFixups, $makerFixup;
+                                    $previewInfo->{BaseShift} = $baseShift;
+                                    $previewInfo->{Relative} = 1;
+                                }
+                            } elsif (not defined $subdirInfo{Relative}) {
+                                # don't shift anything if relative flag set to zero (Pentax patch)
+                                my $baseShift = $base - $subdirInfo{Base};
+                                $makerFixup->{Start} += $valLen + $loc;
+                                $makerFixup->{Shift} += $baseShift;
+                                push @valFixups, $makerFixup;
+                                if ($previewInfo and not $previewInfo->{NoBaseShift}) {
+                                    $previewInfo->{BaseShift} = $baseShift;
+                                }
+                            }
+                            $newValuePt = \$newValue;   # write new value
+                        }
+                    }
+                    SetByteOrder($saveOrder);
+
+                # process existing subdirectory unless we are overwriting it entirely
+                } elsif ($$newInfo{SubDirectory} and $isNew <= 0 and not $isOverwriting
+                    # don't edit directory if Writable is set to 0
+                    and (not defined $$newInfo{Writable} or $$newInfo{Writable}))
+                {
+
+                    my $subdir = $$newInfo{SubDirectory};
+                    if ($$newInfo{SubIFD}) {
+#
+# rewrite existing sub IFD's
+#
+                        my $subdirName = $newInfo->{Groups}->{1} || $$newInfo{Name};
+                        # must handle sub-IFD's specially since the values
+                        # are actually offsets to subdirectories
+                        unless ($readCount) {   # can't have zero count
+                            return undef if $exifTool->Error("$dirName entry $index has zero count", 1);
+                            next;
+                        }
+                        my $writeCount = 0;
+                        my $i;
+                        $newValue = '';    # reset value because we regenerate it below
+                        for ($i=0; $i<$readCount; ++$i) {
+                            my $off = $i * $formatSize[$readFormat];
+                            my $pt = Image::ExifTool::ReadValue($valueDataPt, $valuePtr + $off,
+                                            $readFormName, 1, $oldSize - $off);
+                            my $subdirStart = $pt - $dataPos;
+                            my $subdirBase = $base;
+                            if ($$subdir{Base}) {
+                                my $start = $subdirStart + $valueDataPos;
+                                #### eval Base ($start)
+                                $subdirBase += eval $$subdir{Base};
+                            }
+                            my %subdirInfo = (
+                                Base => $subdirBase,
+                                DataPt => $dataPt,
+                                DataPos => $dataPos - $subdirBase + $base,
+                                DataLen => $dataLen,
+                                DirStart => $subdirStart,
+                                DirName => $subdirName . ($i ? $i : ''),
+                                Parent => $dirName,
+                                Fixup => new Image::ExifTool::Fixup,
+                                RAF => $raf,
+                            );
+                            # read IFD from file if necessary
+                            if ($subdirStart < 0 or $subdirStart + 2 > $dataLen) {
+                                my ($buff, $buf2, $subSize);
+                                unless ($raf and $raf->Seek($pt + $base, 0) and
+                                        $raf->Read($buff,2) == 2 and
+                                        $subSize = 12 * Get16u(\$buff, 0) and
+                                        $raf->Read($buf2,$subSize+4) >= $subSize)
+                                {
+                                    if (defined $subSize and not $subSize) {
+                                        return undef if $exifTool->Error("$subdirName IFD has zero entries", 1);
+                                        next Entry;
+                                    }
+                                    return undef if $exifTool->Error("Can't read $subdirName data", $inMakerNotes);
+                                    next Entry;
+                                }
+                                $buff .= $buf2;
+                                # change subdirectory information to data we just read
+                                $subdirInfo{DataPt} = \$buff;
+                                $subdirInfo{DirStart} = 0;
+                                $subdirInfo{DataPos} = $pt;
+                                $subdirInfo{DataLen} = length $buff;
+                                # only account for nextIFD pointer if we will use it
+                                $subSize += 4 if length($buff)==$subSize+6 and 
+                                    ($$newInfo{Name} eq 'SubIFD' or $buff =~ /\0{4}$/);
+                                UpdateTiffEnd($exifTool, $pt+$base+2+$subSize);
+                            }
+                            my $subTable = $tagTablePtr;
+                            if ($$subdir{TagTable}) {
+                                $subTable = GetTagTable($$subdir{TagTable});
+                            }
+                            my $subdirData = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+                            return undef unless defined $subdirData;
+                            next unless length($subdirData);
+                            # temporarily set value to subdirectory index
+                            # (will set to actual offset later when we know what it is)
+                            $newValue .= Set32u(0xfeedf00d);
+                            my ($offset, $where);
+                            if ($readCount > 1) {
+                                $offset = length($valBuff) + $i * 4;
+                                $where = 'valBuff';
+                            } else {
+                                $offset = length($dirBuff) + 8;
+                                $where = 'dirBuff';
+                            }
+                            # add to list of subdirectories we will append later
+                            push @subdirs, {
+                                DataPt => \$subdirData,
+                                Table => $subTable,
+                                Fixup => $subdirInfo{Fixup},
+                                Offset => $offset,
+                                Where => $where,
+                            };
+                            ++$writeCount;  # count number of subdirs written
+                        }
+                        next unless length $newValue;
+                        # must change location of subdir offset if we deleted
+                        # a directory and only one remains
+                        if ($writeCount < $readCount and $writeCount == 1) {
+                            $subdirs[-1]->{Where} = 'dirBuff';
+                            $subdirs[-1]->{Offset} = length($dirBuff) + 8;
+                        }
+                        # set new format to int32u for IFD
+                        $newFormName = $$newInfo{FixFormat} || 'int32u';
+                        $newFormat = $formatNumber{$newFormName};
+                        $newValuePt = \$newValue;
+
+                    } elsif ((not defined $$subdir{Start} or
+                             $$subdir{Start} =~ /\$valuePtr/) and
+                             $$subdir{TagTable})
+                    {
+#
+# rewrite other existing subdirectories ('$valuePtr' type only)
+#
+                        # set subdirectory Start and Base
+                        my $subdirStart = $valuePtr;
+                        if ($$subdir{Start}) {
+                            #### eval Start ($valuePtr)
+                            $subdirStart = eval $$subdir{Start};
+                            # must adjust directory size if start changed
+                            $oldSize -= $subdirStart - $valuePtr;
+                        }
+                        my $subdirBase = $base;
+                        if ($$subdir{Base}) {
+                            my $start = $subdirStart + $valueDataPos;
+                            #### eval Base ($start)
+                            $subdirBase += eval $$subdir{Base};
+                        }
+                        my $subFixup = new Image::ExifTool::Fixup;
+                        my %subdirInfo = (
+                            Base => $subdirBase,
+                            DataPt => $valueDataPt,
+                            DataPos => $valueDataPos - $subdirBase + $base,
+                            DataLen => $valueDataLen,
+                            DirStart => $subdirStart,
+                            DirName => $$subdir{DirName},
+                            DirLen => $oldSize,
+                            Parent => $dirName,
+                            Fixup => $subFixup,
+                            RAF => $raf,
+                        );
+                        my $subTable = GetTagTable($$subdir{TagTable});
+                        $newValue = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+                        if (defined $newValue) {
+                            my $hdrLen = $subdirStart - $valuePtr;
+                            if ($hdrLen) {
+                                $newValue = substr($$valueDataPt, $valuePtr, $hdrLen) . $newValue;
+                                $subFixup->{Start} += $hdrLen;
+                            }
+                            $newValuePt = \$newValue;
+                        }
+                        unless (defined $$newValuePt) {
+                            $exifTool->Error("Error writing $dirName:$$newInfo{Name}");
+                            return undef;
+                        }
+                        next unless length $$newValuePt;
+                        if ($subFixup->{Pointers} and $subdirInfo{Base} == $base) {
+                            $subFixup->{Start} += length $valBuff;
+                            push @valFixups, $subFixup;
+                        } else {
+                            # apply fixup in case we added a header ($hdrLen above)
+                            $subFixup->ApplyFixup(\$newValue);
+                        }
+                    }
+
+                } elsif ($$newInfo{OffsetPair}) {
+#
+# keep track of offsets
+#
+                    my $dataTag = $$newInfo{DataTag} || '';
+                    if ($dataTag eq 'CanonVRD') {
+                        # must decide now if we will write CanonVRD information
+                        my $hasVRD;
+                        if ($exifTool->{NEW_VALUE}->{$Image::ExifTool::Extra{CanonVRD}}) {
+                            # adding or deleting as a block
+                            $hasVRD = $exifTool->GetNewValues('CanonVRD') ? 1 : 0;
+                        } elsif ($exifTool->{DEL_GROUP}->{CanonVRD} or
+                                 $exifTool->{DEL_GROUP}->{Trailer})
+                        {
+                            $hasVRD = 0;    # deleting as a group
+                        } else {
+                            $hasVRD = ($$newValuePt ne "\0\0\0\0");
+                        }
+                        if ($hasVRD) {
+                            # add a fixup, and set this offset later
+                            $dirFixup->AddFixup(length($dirBuff) + 8, $dataTag);
+                        } else {
+                            # there is (or will soon be) no VRD information, so set pointer to zero
+                            $newValue = "\0" x length($$newValuePt);
+                            $newValuePt = \$newValue;
+                        }
+                    } else {
+                        my $offsetInfo = $offsetInfo[$ifd];
+                        # save original values (for updating TIFF_END later)
+                        my @vals;
+                        if ($isNew <= 0) {
+                            @vals = ReadValue(\$oldValue, 0, $readFormName, $readCount, $oldSize);
+                        }
+                        # only support int32 pointers (for now)
+                        if ($formatSize[$newFormat] != 4 and $$newInfo{IsOffset}) {
+                            die "Internal error (Offset not int32)" if $isNew > 0;
+                            die "Wrong count!" if $newCount != $readCount;
+                            # change to int32
+                            $newFormName = 'int32u';
+                            $newFormat = $formatNumber{$newFormName};
+                            $newValue = WriteValue(join(' ',@vals), $newFormName, $newCount);
+                            die "Internal error writing offsets\n" unless defined $newValue;
+                        }
+                        $offsetInfo or $offsetInfo = $offsetInfo[$ifd] = { };
+                        # save location of valuePtr in new directory
+                        # (notice we add 10 instead of 8 for valuePtr because
+                        # we will put a 2-byte count at start of directory later)
+                        my $ptr = $newStart + length($dirBuff) + 10;
+                        $newCount or $newCount = 1; # make sure count is set for offsetInfo
+                        # save value pointer and value count for each tag
+                        $offsetInfo->{$newID} = [$newInfo, $ptr, $newCount, \@vals, $newFormat];
+                    }
+
+                } elsif ($$newInfo{DataMember}) {
+
+                    # save any necessary data members (CameraMake, CameraModel)
+                    $exifTool->{$$newInfo{DataMember}} = $$newValuePt;
+                }
+            }
+#
+# write out the directory entry
+#
+            my $newSize = length($$newValuePt);
+            my $fsize = $formatSize[$newFormat];
+            my $offsetVal;
+            $newCount = int(($newSize + $fsize - 1) / $fsize);  # set proper count
+            if ($newSize > 4) {
+                # zero-pad to an even number of bytes (required by EXIF standard)
+                # and make sure we are a multiple of the format size
+                while ($newSize & 0x01 or $newSize < $newCount * $fsize) {
+                    $$newValuePt .= "\0";
+                    ++$newSize;
+                }
+                my $entryBased;
+                if ($$dirInfo{EntryBased} or ($newInfo and $$newInfo{EntryBased})) {
+                    $entryBased = 1;
+                    $offsetVal = Set32u(length($valBuff) - length($dirBuff));
+                } else {
+                    $offsetVal = Set32u(length $valBuff);
+                }
+                my $dataTag;
+                if ($newInfo and $$newInfo{DataTag}) {
+                    $dataTag = $$newInfo{DataTag};
+                    if ($dataTag eq 'PreviewImage' and $exifTool->{FILE_TYPE} eq 'JPEG') {
+                        # hold onto the PreviewImage until we can determine if it fits
+                        $exifTool->{PREVIEW_INFO} or $exifTool->{PREVIEW_INFO} = { };
+                        $exifTool->{PREVIEW_INFO}->{Data} = $$newValuePt;
+                        if ($$newInfo{Name} eq 'PreviewImage') {
+                            $exifTool->{PREVIEW_INFO}->{IsValue} = 1;
+                        }
+                        if ($$newInfo{IsOffset} and $$newInfo{IsOffset} eq '2') {
+                            $exifTool->{PREVIEW_INFO}->{NoBaseShift} = 1;
+                        }
+                        $$newValuePt = '';
+                    }
+                }
+                $valBuff .= $$newValuePt;       # add value data to buffer
+                # must save a fixup pointer for every pointer in the directory
+                if ($entryBased) {
+                    $entryBasedFixup or $entryBasedFixup = new Image::ExifTool::Fixup;
+                    $entryBasedFixup->AddFixup(length($dirBuff) + 8, $dataTag);
+                } else {
+                    $dirFixup->AddFixup(length($dirBuff) + 8, $dataTag);
+                }
+            } else {
+                $offsetVal = $$newValuePt;      # save value in offset if 4 bytes or less
+                # must pad value with zeros if less than 4 bytes
+                $newSize < 4 and $offsetVal .= "\0" x (4 - $newSize);
+            }
+            # write the directory entry
+            $dirBuff .= Set16u($newID) . Set16u($newFormat) .
+                        Set32u($newCount) . $offsetVal;
+            # update flag to keep track of mandatory tags
+            while (defined $allMandatory) {
+                if (defined $$mandatory{$newID}) {
+                    # values must correspond to mandatory values
+                    my $mandVal = WriteValue($$mandatory{$newID}, $newFormName, $newCount);
+                    if (defined $mandVal and $mandVal eq $$newValuePt) {
+                        ++$allMandatory;        # count mandatory tags
+                        last;
+                    }
+                }
+                undef $deleteAll;
+                undef $allMandatory;
+            }
+        }
+#..............................................................................
+# write directory counts and nextIFD pointer and add value data to end of IFD
+#
+        # calculate number of entries in new directory
+        my $newEntries = length($dirBuff) / 12;
+        # delete entire directory if only mandatory tags remain
+        if ($newEntries < $numEntries and $allMandatory) {
+            $newEntries = 0;
+            $dirBuff = '';
+            $valBuff = '';
+            undef $dirFixup;    # no fixups in this directory
+            ++$deleteAll if defined $deleteAll;
+            $verbose > 1 and print $out "    - $allMandatory mandatory tag(s)\n";
+        }
+        if ($ifd and not $newEntries) {
+            $verbose and print $out "  Deleting IFD1\n";
+            last;   # don't write IFD1 if empty
+        }
+        # apply one-time fixup for entry-based offsets
+        if ($entryBasedFixup) {
+            $entryBasedFixup->{Shift} = length($dirBuff) + 4;
+            $entryBasedFixup->ApplyFixup(\$dirBuff);
+            undef $entryBasedFixup;
+        }
+        # add directory entry count to start of IFD and next IFD pointer to end
+        # (temporarily set next IFD pointer to zero)
+        $newData .= Set16u($newEntries) . $dirBuff . Set32u(0);
+        # get position of value data in newData
+        my $valPos = length($newData);
+        # go back now and set next IFD pointer if this isn't the first IFD
+        if ($nextIfdPos) {
+            # set offset to next IFD
+            Set32u($newStart, \$newData, $nextIfdPos);
+            $fixup->AddFixup($nextIfdPos,'NextIFD');    # add fixup for this offset in newData
+        }
+        # remember position of 'next IFD' pointer so we can set it next time around
+        $nextIfdPos = $valPos - 4;
+        # add value data after IFD
+        $newData .= $valBuff;
+#
+# add any subdirectories, adding fixup information
+#
+        if (@subdirs) {
+            my $subdir;
+            foreach $subdir (@subdirs) {
+                my $pos = length($newData);    # position of subdirectory in data
+                my $subdirFixup = $subdir->{Fixup};
+                $subdirFixup->{Start} += $pos;
+                $fixup->AddFixup($subdirFixup);
+                $newData .= ${$subdir->{DataPt}};   # add subdirectory to our data
+                undef ${$subdir->{DataPt}};         # free memory now
+                # set the pointer
+                my $offset = $subdir->{Offset};
+                # if offset is in valBuff, it was added to the end of dirBuff
+                # (plus 4 bytes for nextIFD pointer)
+                $offset += length($dirBuff) + 4 if $subdir->{Where} eq 'valBuff';
+                $offset += $newStart + 2;           # get offset in newData
+                # check to be sure we got the right offset
+                unless (Get32u(\$newData, $offset) == 0xfeedf00d) {
+                    $exifTool->Error("Internal error while rewriting $dirName");
+                    return undef;
+                }
+                # set the offset to the subdirectory data
+                Set32u($pos, \$newData, $offset);
+                $fixup->AddFixup($offset);  # add fixup for this offset in newData
+            }
+        }
+        # add fixup for all offsets in directory according to value data position
+        # (which is at the end of this directory)
+        if ($dirFixup) {
+            $dirFixup->{Start} = $newStart + 2;
+            $dirFixup->{Shift} = $valPos - $dirFixup->{Start};
+            $fixup->AddFixup($dirFixup);
+        }
+        # add valueData fixups, adjusting for position of value data
+        my $valFixup;
+        foreach $valFixup (@valFixups) {
+            $valFixup->{Start} += $valPos;
+            $fixup->AddFixup($valFixup);
+        }
+        # stop if no next IFD pointer
+        last unless $$dirInfo{Multi};  # stop unless scanning for multiple IFD's
+        my $offset;
+        if ($dirStart + $len + 4 <= $dataLen) {
+            $offset = Get32u($dataPt, $dirStart + $len);
+        } else {
+            $offset = 0;
+        }
+        if ($offset) {
+            # continue with next IFD
+            $dirStart = $offset - $dataPos;
+        } else {
+            # create IFD1 if necessary
+            last unless $dirName eq 'IFD0' and $exifTool->{ADD_DIRS}->{'IFD1'};
+            $verbose and print $out "  Creating IFD1\n";
+            my $ifd1 = "\0" x 2;  # empty IFD1 data (zero entry count)
+            $dataPt = \$ifd1;
+            $dirStart = 0;
+            $dirLen = $dataLen = 2;
+        }
+        # increment IFD name
+        $dirName =~ s/(\d+)$//;
+        $dirName .= ($1 || 0) + 1;
+        $exifTool->{DIR_NAME} = $dirName;
+        next unless $offset;
+
+        # guard against writing the same directory twice
+        my $addr = $offset + $base;
+        if ($exifTool->{PROCESSED}->{$addr}) {
+            $exifTool->Error("$dirName pointer references previous $exifTool->{PROCESSED}->{$addr} directory", 1);
+            last;
+        }
+        $exifTool->{PROCESSED}->{$addr} = $dirName;
+
+        if ($dirName eq 'SubIFD1' and not ValidateIFD($dirInfo, $dirStart)) {
+            if ($exifTool->{TIFF_TYPE} eq 'TIFF') {
+                $exifTool->Error('Ignored bad IFD linked from SubIFD', 1);
+            } elsif ($verbose) {
+                $exifTool->Warn('Ignored bad IFD linked from SubIFD');
+            }
+            last;   # don't write bad IFD
+        }
+        if ($exifTool->{DEL_GROUP}->{$dirName}) {
+            $verbose and print $out "  Deleting $dirName\n";
+            $raf and $exifTool->Error("Deleting $dirName also deletes subsequent" .
+                                      " IFD's and possibly image data", 1);
+            ++$exifTool->{CHANGED};
+            if ($exifTool->{DEL_GROUP}->{$dirName} == 2 and
+                $exifTool->{ADD_DIRS}->{$dirName})
+            {
+                my $emptyIFD = "\0" x 2;    # start with empty IFD
+                $dataPt = \$emptyIFD;
+                $dirStart = 0;
+                $dirLen = $dataLen = 2;
+            } else {
+                last;   # don't write this IFD (or any subsequent IFD)
+            }
+        } else {
+            $verbose and print $out "  Rewriting $dirName\n";
+        }
+    }
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    # do our fixups now so we can more easily calculate offsets below
+    $fixup->ApplyFixup(\$newData);
+#
+# copy over image data for IFD's, starting with the last IFD first
+#
+    my @imageData; # image data blocks if requested
+    my $blockSize = 0;  # total size of blocks to copy later
+    if (@offsetInfo) {
+        my @writeLater;  # write image data last
+        for ($ifd=$#offsetInfo; $ifd>=-1; --$ifd) {
+            # build list of offsets to process
+            my @offsetList;
+            if ($ifd >= 0) {
+                my $offsetInfo = $offsetInfo[$ifd] or next;
+                my $tagID;
+                # loop through all tags in reverse order so we save thumbnail
+                # data before main image data if both exist in the same IFD
+                foreach $tagID (reverse sort keys %$offsetInfo) {
+                    my $tagInfo = $offsetInfo->{$tagID}->[0];
+                    next unless $$tagInfo{IsOffset}; # handle byte counts with offsets
+                    my $sizeInfo = $offsetInfo->{$$tagInfo{OffsetPair}};
+                    $sizeInfo or $exifTool->Error("No size tag for $dirName:$$tagInfo{Name}"), next;
+                    my $dataTag = $$tagInfo{DataTag};
+                    # write TIFF image data (strips or tiles) later if requested
+                    if ($raf and defined $_[1]->{ImageData} and
+                        ($tagID == 0x111 or $tagID == 0x144) and
+                        (not defined $dataTag or not defined $offsetData{$dataTag}))
+                    {
+                        push @writeLater, [ $offsetInfo->{$tagID}, $sizeInfo ];
+                    } else {
+                        push @offsetList, [ $offsetInfo->{$tagID}, $sizeInfo ];
+                    }
+                }
+            } else {
+                last unless @writeLater;
+                @offsetList = @writeLater;
+            }
+            my $offsetPair;
+            foreach $offsetPair (@offsetList) {
+                my ($tagInfo, $offsets, $count, $oldOffset) = @{$$offsetPair[0]};
+                my ($cntInfo, $byteCounts, $count2, $oldSize, $format) = @{$$offsetPair[1]};
+                # must be the same number of offset and byte count values
+                unless ($count == $count2) {
+                    $exifTool->Error("Offset/byteCounts disagree on count for $$tagInfo{Name}");
+                    return undef;
+                }
+                my $formatStr = $formatName[$format];
+                # follow pointer to value data if necessary
+                $count > 1 and $offsets = Get32u(\$newData, $offsets);
+                my $n = $count * $formatSize[$format];
+                $n > 4 and $byteCounts = Get32u(\$newData, $byteCounts);
+                if ($byteCounts < 0 or $byteCounts + $n > length($newData)) {
+                    $exifTool->Error("Error reading $$tagInfo{Name} byte counts");
+                    return undef;
+                }
+                # get offset base and data pos (abnormal for some preview images)
+                my ($dbase, $dpos);
+                if ($$tagInfo{IsOffset} eq '2') {
+                    $dbase = $firstBase;
+                    $dpos = $dataPos + $base - $firstBase;
+                } else {
+                    $dbase = $base;
+                    $dpos = $dataPos;
+                }
+                # transfer the data referenced by all offsets of this tag
+                for ($n=0; $n<$count; ++$n) {
+                    my $oldEnd;
+                    if (@$oldOffset and @$oldSize) {
+                        # calculate end offset of this block
+                        $oldEnd = $$oldOffset[$n] + $$oldSize[$n];
+                        # update TIFF_END as if we read this data from file
+                        UpdateTiffEnd($exifTool, $oldEnd + $dbase);
+                    }
+                    my $offsetPos = $offsets + $n * 4;
+                    my $byteCountPos = $byteCounts + $n * $formatSize[$format];
+                    my $size = ReadValue(\$newData, $byteCountPos, $formatStr, 1, 4);
+                    my $offset = Get32u(\$newData, $offsetPos) - $dpos;
+                    my $buff;
+                    # look for 'feed' code to use our new data
+                    if ($size == 0xfeedfeed) {
+                        my $dataTag = $$tagInfo{DataTag};
+                        unless (defined $dataTag) {
+                            $exifTool->Error("No DataTag defined for $$tagInfo{Name}");
+                            return undef;
+                        }
+                        unless (defined $offsetData{$dataTag}) {
+                            $exifTool->Error("Internal error (no $dataTag)");
+                            return undef;
+                        }
+                        if ($count > 1) {
+                            $exifTool->Error("Can't modify $$tagInfo{Name} with count $count");
+                            return undef;
+                        }
+                        $buff = $offsetData{$dataTag};
+                        if ($formatSize[$format] != 4) {
+                            $exifTool->Error("$$cntInfo{Name} is not int32");
+                            return undef;
+                        }
+                        # set the data size
+                        $size = length($buff);
+                        Set32u($size, \$newData, $byteCountPos);
+                    } elsif ($ifd < 0) {
+                        # pad if necessary (but don't pad contiguous image blocks)
+                        my $pad = 0;
+                        ++$pad if $size & 0x01 and ($n+1 >= $count or not $oldEnd or
+                                  $oldEnd != $$oldOffset[$n+1]);
+                        # preserve original image padding if specified
+                        if ($_[1]->{PreserveImagePadding} and $n+1 < $count and
+                            $oldEnd and $$oldOffset[$n+1] > $oldEnd)
+                        {
+                            $pad = $$oldOffset[$n+1] - $oldEnd;
+                        }
+                        # copy data later
+                        push @imageData, [$offset+$dbase+$dpos, $size, $pad];
+                        $size += $pad; # account for pad byte if necessary
+                        # return ImageData list
+                        $_[1]->{ImageData} = \@imageData;
+                    } elsif ($offset >= 0 and $offset+$size <= $dataLen) {
+                        # take data from old dir data buffer
+                        $buff = substr($$dataPt, $offset, $size);
+                    } elsif ($raf and $raf->Seek($offset+$dbase+$dpos,0) and
+                             $raf->Read($buff,$size) == $size)
+                    {
+                        # data read OK
+                    } elsif ($$tagInfo{Name} eq 'ThumbnailOffset' and $offset>=0 and $offset<$dataLen) {
+                        # Grrr.  The Canon 350D writes the thumbnail with an incorrect byte count
+                        my $diff = $offset + $size - $dataLen;
+                        $exifTool->Warn("ThumbnailImage runs outside EXIF data by $diff bytes (truncated)",1);
+                        # set the size to the available data
+                        $size -= $diff;
+                        unless (WriteValue($size, $formatStr, 1, \$newData, $byteCountPos)) {
+                            warn 'Internal error writing thumbnail size';
+                        }
+                        # get the truncated image
+                        $buff = substr($$dataPt, $offset, $size);
+                    } elsif ($$tagInfo{Name} eq 'PreviewImageStart' and $exifTool->{FILE_TYPE} eq 'JPEG') {
+                        # try to load the preview image using the specified offset
+                        undef $buff;
+                        my $r = $exifTool->{RAF};
+                        if ($r and not $raf) {
+                            my $tell = $r->Tell();
+                            # read and validate
+                            undef $buff unless $r->Seek($offset+$base+$dataPos,0) and
+                                               $r->Read($buff,$size) == $size and
+                                               $buff =~ /^.\xd8\xff[\xc4\xdb\xe0-\xef]/;
+                            $r->Seek($tell, 0) or $exifTool->Error('Seek error'), return undef;
+                        }
+                        $buff = 'LOAD' unless defined $buff;    # flag indicating we must load PreviewImage
+                    } else {
+                        my $dataName = $$tagInfo{DataTag} || $$tagInfo{Name};
+                        return undef if $exifTool->Error("Error reading $dataName data in $dirName", $inMakerNotes);
+                        $buff = '';
+                    }
+                    if ($$tagInfo{Name} eq 'PreviewImageStart' and $exifTool->{FILE_TYPE} eq 'JPEG') {
+                        # hold onto the PreviewImage until we can determine if it fits
+                        $exifTool->{PREVIEW_INFO} or $exifTool->{PREVIEW_INFO} = { };
+                        $exifTool->{PREVIEW_INFO}->{Data} = $buff;
+                        if ($$tagInfo{IsOffset} and $$tagInfo{IsOffset} eq '2') {
+                            $exifTool->{PREVIEW_INFO}->{NoBaseShift} = 1;
+                        }
+                        $buff = '';
+                    }
+                    # update offset accordingly and add to end of new data
+                    Set32u(length($newData)+$blockSize, \$newData, $offsetPos);
+                    # add a pointer to fix up this offset value (marked with DataTag name)
+                    $fixup->AddFixup($offsetPos, $$tagInfo{DataTag});
+                    if ($ifd >= 0) {
+                        $buff .= "\0" if $size & 0x01;  # must be even size
+                        $newData .= $buff;      # add this strip to the data
+                    } else {
+                        $blockSize += $size;    # keep track of total size
+                    }
+                }
+            }
+        }
+    }
+#
+# apply final shift to new data position if this is the top level IFD
+#
+    unless ($$dirInfo{Fixup}) {
+        my $newDataPos = $$dirInfo{NewDataPos} || 0;
+        # adjust CanonVRD offset to point to end of regular TIFF if necessary
+        # (NOTE: This will be incorrect if multiple trailers exist,
+        #  but it is unlikely that it could ever be correct in this case anyway)
+        $fixup->SetMarkerPointers(\$newData, 'CanonVRD', length($newData) + $blockSize);
+        if ($newDataPos) {
+            $fixup->{Shift} += $newDataPos;
+            $fixup->ApplyFixup(\$newData);
+        }
+        # save fixup for PreviewImage in JPEG file if necessary
+        my $previewInfo = $exifTool->{PREVIEW_INFO};
+        if ($previewInfo) {
+            my $pt = \$previewInfo->{Data}; # image data or 'LOAD' flag
+            # now that we know the size of the EXIF data, first test to see if our new image fits
+            # inside the EXIF segment (remember about the TIFF and EXIF headers: 8+6 bytes)
+            if (($$pt ne 'LOAD' and length($$pt) + length($newData) + 14 <= 0xfffd) or
+                $previewInfo->{IsShort}) # must fit in this segment if using short pointers
+            {
+                # It fits! (or must exist in EXIF segment), so fixup the
+                # PreviewImage pointers and stuff the preview image in here
+                my $newPos = length($newData) + ($newDataPos || 0);
+                $newPos += ($previewInfo->{BaseShift} || 0);
+                if ($previewInfo->{Relative}) {
+                    # calculate our base by looking at how far the pointer got shifted
+                    $newPos -= $fixup->GetMarkerPointers(\$newData, 'PreviewImage');
+                }
+                $fixup->SetMarkerPointers(\$newData, 'PreviewImage', $newPos);
+                $newData .= $$pt;
+                delete $exifTool->{PREVIEW_INFO};   # done with our preview data
+                $exifTool->{DEL_PREVIEW} = 1;       # set flag to delete old preview
+            } else {
+                # Doesn't fit, or we still don't know, so save fixup information
+                # and put the preview at the end of the file
+                $previewInfo->{Fixup} or $previewInfo->{Fixup} = new Image::ExifTool::Fixup;
+                $previewInfo->{Fixup}->AddFixup($fixup);
+            }
+        } else {
+            # delete both IFD0 and IFD1 if only mandatory tags remain
+            $newData = '' if defined $newData and $deleteAll;
+        }
+        # save location of last IFD for use in Canon RAW header
+        if ($newDataPos == 16) {
+            my @ifdPos = $fixup->GetMarkerPointers(\$newData,'NextIFD');
+            $_[1]->{LastIFD} = pop @ifdPos;
+        }
+    }
+    # return empty string if no entries in directory
+    # (could be up to 10 bytes and still be empty)
+    $newData = '' if defined $newData and length($newData) < 12;
+
+    return $newData;    # return our directory data
+}
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::WriteExif.pl - Write EXIF meta information
+
+=head1 SYNOPSIS
+
+This file is autoloaded by Image::ExifTool::Exif.
+
+=head1 DESCRIPTION
+
+This file contains routines to write EXIF metadata.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::Exif(3pm)|Image::ExifTool::Exif>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/WriteIPTC.pl
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/WriteIPTC.pl	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/WriteIPTC.pl	(revision 20131)
@@ -0,0 +1,564 @@
+#------------------------------------------------------------------------------
+# File:         WriteIPTC.pl
+#
+# Description:  Write IPTC meta information
+#
+# Revisions:    12/15/2004 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::IPTC;
+
+use strict;
+
+# mandatory IPTC tags for each record
+my %mandatory = (
+    1 => {
+        0  => 4,        # EnvelopeRecordVersion
+    },
+    2 => {
+        0  => 4,        # ApplicationRecordVersion
+    },
+    3 => {
+        0  => 4,        # NewsPhotoVersion
+    },
+);
+
+# manufacturer strings for IPTCPictureNumber
+my %manufacturer = (
+    1 => 'Associated Press, USA',
+    2 => 'Eastman Kodak Co, USA',
+    3 => 'Hasselblad Electronic Imaging, Sweden',
+    4 => 'Tecnavia SA, Switzerland',
+    5 => 'Nikon Corporation, Japan',
+    6 => 'Coatsworth Communications Inc, Canada',
+    7 => 'Agence France Presse, France',
+    8 => 'T/One Inc, USA',
+    9 => 'Associated Newspapers, UK',
+    10 => 'Reuters London',
+    11 => 'Sandia Imaging Systems Inc, USA',
+    12 => 'Visualize, Spain',
+);
+
+my %iptcCharsetInv = ( 'UTF8' => "\x1b%G" );
+
+# ISO 2022 Character Coding Notes
+# -------------------------------
+# Character set designation: (0x1b I F, or 0x1b I I F)
+# Initial character 0x1b (ESC)
+# Intermediate character I:
+#   0x28 ('(') - G0, 94 chars
+#   0x29 (')') - G1, 94 chars
+#   0x2a ('*') - G2, 94 chars
+#   0x2b ('+') - G3, 94 chars
+#   0x2c (',') - G1, 96 chars
+#   0x2d ('-') - G2, 96 chars
+#   0x2e ('.') - G3, 96 chars
+#   0x24 I ('$I') - multiple byte graphic sets (I from above)
+#   I 0x20 ('I ') - dynamically redefinable character sets
+# Final character:
+#   0x30 - 0x3f = private character set
+#   0x40 - 0x7f = standardized character set
+# Character set invocation:
+#   G0 : SI = 0x15
+#   G1 : SO = 0x14,             LS1R = 0x1b 0x7e ('~')
+#   G2 : LS2 = 0x1b 0x6e ('n'), LS2R = 0x1b 0x7d ('}')
+#   G3 : LS3 = 0x1b 0x6f ('o'), LS3R = 0x1b 0x7c ('|')
+#   (the locking shift "R" codes shift into 0x80-0xff space)
+# Single character invocation:
+#   G2 : SS2 = 0x1b 0x8e (or 0x4e in 7-bit)
+#   G3 : SS3 = 0x1b 0x8f (or 0x4f in 7-bit)
+# Control chars (designated and invoked)
+#   C0 : 0x1b 0x21 F (0x21 = '!')
+#   C1 : 0x1b 0x22 F (0x22 = '"')
+# Complete codes (control+graphics, designated and involked)
+#   0x1b 0x25 F   (0x25 = '%')
+#   0x1b 0x25 I F
+#   0x1b 0x25 0x47 ("\x1b%G") - UTF-8
+#   0x1b 0x25 0x40 ("\x1b%@") - return to ISO 2022
+# -------------------------------
+
+#------------------------------------------------------------------------------
+# Inverse print conversion for CodedCharacterSet
+# Inputs: 0) value
+sub PrintInvCodedCharset($)
+{
+    my $val = shift;
+    my $code = $iptcCharsetInv{uc($val)};
+    unless ($code) {
+        if (($code = $val) =~ s/ESC /\x1b/g) {  # translate ESC chars
+            $code =~ s/, \x1b/\x1b/g;   # remove comma separators
+            $code =~ tr/ //d;           # remove spaces
+        } else {
+            warn "Bad syntax (use 'UTF8' or 'ESC X Y[, ...]')\n";
+        }
+    }
+    return $code;
+}
+
+#------------------------------------------------------------------------------
+# validate raw values for writing
+# Inputs: 0) ExifTool object reference, 1) tagInfo hash reference,
+#         2) raw value reference
+# Returns: error string or undef (and possibly changes value) on success
+sub CheckIPTC($$$)
+{
+    my ($exifTool, $tagInfo, $valPtr) = @_;
+    my $format = $$tagInfo{Format} || $tagInfo->{Table}->{FORMAT} || '';
+    if ($format =~ /^int(\d+)/) {
+        my $bytes = int(($1 || 0) / 8);
+        if ($bytes ne 1 and $bytes ne 2 and $bytes ne 4) {
+            return "Can't write $bytes-byte integer";
+        }
+        my $val = $$valPtr;
+        unless (Image::ExifTool::IsInt($val)) {
+            return 'Not an integer' unless Image::ExifTool::IsHex($val);
+            $val = $$valPtr = hex($val);
+        }
+        my $n;
+        for ($n=0; $n<$bytes; ++$n) { $val >>= 8; }
+        return "Value too large for $bytes-byte format" if $val;
+    } elsif ($format =~ /^(string|digits)\[?(\d+),?(\d*)\]?$/) {
+        my ($fmt, $minlen, $maxlen) = ($1, $2, $3);
+        my $len = length $$valPtr;
+        if ($fmt eq 'digits') {
+            return 'Non-numeric characters in value' unless $$valPtr =~ /^\d+$/;
+            # left pad with zeros if necessary
+            $$valPtr = ('0' x ($len - $minlen)) . $$valPtr if $len < $minlen;
+        }
+        if ($minlen) {
+            $maxlen or $maxlen = $minlen;
+            return "String too short (minlen is $minlen)" if $len < $minlen;
+            return "String too long (maxlen is $maxlen)" if $len > $maxlen;
+        }
+    } else {
+        return "Bad IPTC Format ($format)";
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# format IPTC data for writing
+# Inputs: 0) ExifTool object ref, 1) tagInfo pointer,
+#         2) value reference (changed if necessary),
+#         3) reference to character set for translation (changed if necessary)
+#         4) record number, 5) flag set to read value (instead of write)
+sub FormatIPTC($$$$$;$)
+{
+    my ($exifTool, $tagInfo, $valPtr, $xlatPtr, $rec, $read) = @_;
+    return unless $$tagInfo{Format};
+    if ($$tagInfo{Format} =~ /^int(\d+)/) {
+        if ($read) {
+            my $len = length($$valPtr);
+            if ($len <= 8) {    # limit integer conversion to 8 bytes long
+                my $val = 0;
+                my $i;
+                for ($i=0; $i<$len; ++$i) {
+                    $val = $val * 256 + ord(substr($$valPtr, $i, 1));
+                }
+                $$valPtr = $val;
+            }
+        } else {
+            my $len = int(($1 || 0) / 8);
+            if ($len == 1) {        # 1 byte
+                $$valPtr = chr($$valPtr);
+            } elsif ($len == 2) {   # 2-byte integer
+                $$valPtr = pack('n', $$valPtr);
+            } else {                # 4-byte integer
+                $$valPtr = pack('N', $$valPtr);
+            }
+        }
+    } elsif ($$tagInfo{Format} =~ /^string/) {
+        if ($rec == 1) {
+            if ($$tagInfo{Name} eq 'CodedCharacterSet') {
+                $$xlatPtr = HandleCodedCharset($exifTool, $$valPtr);
+            }
+        } elsif ($$xlatPtr and $rec < 7 and $$valPtr =~ /[\x80-\xff]/) {
+            TranslateCodedString($exifTool, $valPtr, $xlatPtr, $read);
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# generate IPTC-format date
+# Inputs: 0) EXIF-format date string (YYYY:MM:DD) or date/time string
+# Returns: IPTC-format date string (YYYYMMDD), or undef on error
+sub IptcDate($)
+{
+    my $val = shift;
+    $val =~ s/.*(\d{4}):?(\d{2}):?(\d{2}).*/$1$2$3/ or undef $val;
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# generate IPTC-format time
+# Inputs: 0) EXIF-format time string (HH:MM:SS[+/-HH:MM]) or date/time string
+# Returns: IPTC-format time string (HHMMSS+HHMM), or undef on error
+sub IptcTime($)
+{
+    my $val = shift;
+    if ($val =~ /\s*\b(\d{1,2}):?(\d{1,2}):?(\d{1,2})(\S*)\s*$/) {
+        $val = sprintf("%.2d%.2d%.2d",$1,$2,$3);
+        my $tz = $4;
+        if ($tz =~ /([+-]\d{1,2}):?(\d{1,2})/) {
+            $val .= sprintf("%+.2d%.2d",$1,$2);
+        } else {
+            $val .= '+0000';    # don't know the time zone
+        }
+    } else {
+        undef $val;     # time format error
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Convert picture number
+# Inputs: 0) value
+# Returns: Converted value
+sub ConvertPictureNumber($)
+{
+    my $val = shift;
+    if ($val eq "\0" x 16) {
+        $val = 'Unknown';
+    } elsif (length $val >= 16) {
+        my @vals = unpack('nNA8n', $val);
+        $val = $vals[0];
+        my $manu = $manufacturer{$val};
+        $val .= " ($manu)" if $manu;
+        $val .= ', equip ' . $vals[1];
+        $vals[2] =~ s/(\d{4})(\d{2})(\d{2})/$1:$2:$3/;
+        $val .= ", $vals[2], no. $vals[3]";
+    } else {
+        $val = '<format error>'
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Inverse picture number conversion
+# Inputs: 0) value
+# Returns: Converted value (or undef on error)
+sub InvConvertPictureNumber($)
+{
+    my $val = shift;
+    $val =~ s/\(.*\)//g;    # remove manufacturer description
+    $val =~ tr/://d;        # remove date separators
+    $val =~ tr/0-9/ /c;     # turn remaining non-numbers to spaces
+    my @vals = split ' ', $val;
+    if (@vals >= 4) {
+        $val = pack('nNA8n', @vals);
+    } elsif ($val =~ /unknown/i) {
+        $val = "\0" x 16;
+    } else {
+        undef $val;
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Write IPTC data record
+# Inputs: 0) ExifTool object reference, 1) source dirInfo reference,
+#         2) tag table reference
+# Returns: IPTC data block (may be empty if no IPTC data)
+# Notes: Increments ExifTool CHANGED flag for each tag changed
+sub WriteIPTC($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    $exifTool or return 1;    # allow dummy access to autoload this package
+    my $dataPt = $$dirInfo{DataPt};
+    unless ($dataPt) {
+        my $emptyData = '';
+        $dataPt = \$emptyData;
+    }
+    my $start = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen};
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my ($tagInfo, %iptcInfo, $tag);
+
+    # begin by assuming IPTC is coded in Latin unless otherwise specified
+    my $xlat = $exifTool->Options('Charset');
+    undef $xlat if $xlat eq 'Latin';
+
+    # make sure our dataLen is defined (note: allow zero length directory)
+    unless (defined $dirLen) {
+        my $dataLen = $$dirInfo{DataLen};
+        $dataLen = length($$dataPt) unless defined $dataLen;
+        $dirLen = $dataLen - $start;
+    }
+    # quick check for improperly byte-swapped IPTC
+    if ($dirLen >= 4 and substr($$dataPt, $start, 1) ne "\x1c" and
+                         substr($$dataPt, $start + 3, 1) eq "\x1c")
+    {
+        $exifTool->Warn('IPTC data was improperly byte-swapped');
+        my $newData = pack('N*', unpack('V*', substr($$dataPt, $start, $dirLen) . "\0\0\0"));
+        $dataPt = \$newData;
+        $start = 0;
+        # NOTE: MUST NOT access $dirInfo DataPt, DirStart or DataLen after this!
+    }
+    # generate lookup so we can find the record numbers
+    my %recordNum;
+    foreach $tag (Image::ExifTool::TagTableKeys($tagTablePtr)) {
+        $tagInfo = $tagTablePtr->{$tag};
+        $$tagInfo{SubDirectory} or next;
+        my $table = $tagInfo->{SubDirectory}->{TagTable} or next;
+        my $subTablePtr = Image::ExifTool::GetTagTable($table);
+        $recordNum{$subTablePtr} = $tag;
+        Image::ExifTool::GenerateTagIDs($subTablePtr);
+    }
+
+    # loop through new values and accumulate all IPTC information
+    # into lists based on their IPTC record type
+    foreach $tagInfo ($exifTool->GetNewTagInfoList()) {
+        my $table = $$tagInfo{Table};
+        my $record = $recordNum{$table};
+        # ignore tags we aren't writing to this directory
+        next unless defined $record;
+        $iptcInfo{$record} = [] unless defined $iptcInfo{$record};
+        push @{$iptcInfo{$record}}, $tagInfo;
+    }
+
+    # get sorted list of records used.  Might as well be organized and
+    # write our records in order of record number first, then tag number
+    my @recordList = sort { $a <=> $b } keys %iptcInfo;
+    my ($record, %set);
+    foreach $record (@recordList) {
+        # sort tagInfo lists by tagID
+        @{$iptcInfo{$record}} = sort { $$a{TagID} <=> $$b{TagID} } @{$iptcInfo{$record}};
+        # build hash of all tagIDs to set
+        foreach $tagInfo (@{$iptcInfo{$record}}) {
+            $set{$record}->{$$tagInfo{TagID}} = $tagInfo;
+        }
+    }
+    # run through the old IPTC data, inserting our records in
+    # sequence and deleting existing records where necessary
+    # (the IPTC specification states that records must occur in
+    # numerical order, but tags within records need not be ordered)
+    my $pos = $start;
+    my $tail = $pos;        # old data written up to this point
+    my $dirEnd = $start + $dirLen;
+    my $newData = '';
+    my $lastRec = -1;
+    my $lastRecPos = 0;
+    my $allMandatory = 0;
+    my %foundRec;           # found flags: 0x01-existed before, 0x02-deleted, 0x04-created
+
+    for (;;$tail=$pos) {
+        # get next IPTC record from input directory
+        my ($id, $rec, $tag, $len, $valuePtr);
+        if ($pos + 5 <= $dirEnd) {
+            my $buff = substr($$dataPt, $pos, 5);
+            ($id, $rec, $tag, $len) = unpack("CCCn", $buff);
+            if ($id == 0x1c) {
+                if ($rec < $lastRec) {
+                    return undef if $exifTool->Warn("IPTC doesn't conform to spec: Records out of sequence", 1);
+                }
+                # handle extended IPTC entry if necessary
+                $pos += 5;      # step to after field header
+                if ($len & 0x8000) {
+                    my $n = $len & 0x7fff;  # get num bytes in length field
+                    if ($pos + $n <= $dirEnd and $n <= 8) {
+                        # determine length (a big-endian, variable sized int)
+                        for ($len = 0; $n; ++$pos, --$n) {
+                            $len = $len * 256 + ord(substr($$dataPt, $pos, 1));
+                        }
+                    } else {
+                        $len = $dirEnd;     # invalid length
+                    }
+                }
+                $valuePtr = $pos;
+                $pos += $len;   # step $pos to next entry
+                # make sure we don't go past the end of data
+                # (this can only happen if original data is bad)
+                $pos = $dirEnd if $pos > $dirEnd;
+            } else {
+                undef $rec;
+            }
+        }
+        if (not defined $rec or $rec != $lastRec) {
+            # write out all our records that come before this one
+            for (;;) {
+                my $newRec = $recordList[0];
+                if (not defined $newRec or $newRec != $lastRec) {
+                    # handle mandatory tags in last record unless it was empty
+                    if (length $newData > $lastRecPos) {
+                        if ($allMandatory > 1) {
+                            # entire lastRec contained mandatory tags, and at least one tag
+                            # was deleted, so delete entire record unless we specifically
+                            # added a mandatory tag
+                            my $num = 0;
+                            foreach (keys %{$foundRec{$lastRec}}) {
+                                my $code = $foundRec{$lastRec}->{$_};
+                                $num = 0, last if $code & 0x04;
+                                ++$num if ($code & 0x03) == 0x01;
+                            }
+                            if ($num) {
+                                $newData = substr($newData, 0, $lastRecPos);
+                                $verbose > 1 and print $out "    - $num mandatory tags\n";
+                            }
+                        } elsif ($mandatory{$lastRec} and
+                                 $tagTablePtr eq \%Image::ExifTool::IPTC::Main)
+                        {
+                            # add required mandatory tags
+                            my $mandatory = $mandatory{$lastRec};
+                            my ($mandTag, $subTablePtr);
+                            foreach $mandTag (sort { $a <=> $b } keys %$mandatory) {
+                                next if $foundRec{$lastRec}->{$mandTag};
+                                unless ($subTablePtr) {
+                                    $tagInfo = $tagTablePtr->{$lastRec};
+                                    $tagInfo and $$tagInfo{SubDirectory} or warn("WriteIPTC: Internal error 1\n"), next;
+                                    $tagInfo->{SubDirectory}->{TagTable} or next;
+                                    $subTablePtr = Image::ExifTool::GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                                }
+                                $tagInfo = $subTablePtr->{$mandTag} or warn("WriteIPTC: Internal error 2\n"), next;
+                                my $value = $mandatory->{$mandTag};
+                                $verbose > 1 and print $out "    + IPTC:$$tagInfo{Name} = '$value' (mandatory)\n";
+                                # apply necessary format conversions
+                                FormatIPTC($exifTool, $tagInfo, \$value, \$xlat, $lastRec);
+                                $len = length $value;
+                                # generate our new entry
+                                my $entry = pack("CCCn", 0x1c, $lastRec, $mandTag, length($value));
+                                $newData .= $entry . $value;    # add entry to new IPTC data
+                                ++$exifTool->{CHANGED};
+                            }
+                        }
+                    }
+                    last unless defined $newRec;
+                    $lastRec = $newRec;
+                    $lastRecPos = length $newData;
+                    $allMandatory = 1;
+                }
+                $tagInfo = ${$iptcInfo{$newRec}}[0];
+                my $newTag = $$tagInfo{TagID};
+                # compare current entry with entry next in line to write out
+                # (write out our tags in numerical order even though
+                # this isn't required by the IPTC spec)
+                last if defined $rec and $rec <= $newRec;
+                my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+                # only add new values if...
+                my ($doSet, @values);
+                my $found = $foundRec{$newRec}->{$newTag} || 0;
+                if ($found & 0x02) {
+                    # ...tag existed before and was deleted
+                    $doSet = 1;
+                } elsif ($$tagInfo{List}) {
+                    # ...tag is List and it existed before or we are creating it
+                    $doSet = 1 if $found or Image::ExifTool::IsCreating($newValueHash);
+                } else {
+                    # ...tag didn't exist before and we are creating it
+                    $doSet = 1 if not $found and Image::ExifTool::IsCreating($newValueHash);
+                }
+                if ($doSet) {
+                    @values = Image::ExifTool::GetNewValues($newValueHash);
+                    @values and $foundRec{$newRec}->{$newTag} = $found | 0x04;
+                    # write tags for each value in list
+                    my $value;
+                    foreach $value (@values) {
+                        $verbose > 1 and print $out "    + IPTC:$$tagInfo{Name} = '$value'\n";
+                        # reset allMandatory flag if a non-mandatory tag is written
+                        if ($allMandatory) {
+                            my $mandatory = $mandatory{$newRec};
+                            $allMandatory = 0 unless $mandatory and $mandatory->{$newTag};
+                        }
+                        # apply necessary format conversions
+                        FormatIPTC($exifTool, $tagInfo, \$value, \$xlat, $newRec);
+                        # (note: IPTC string values are NOT null terminated)
+                        $len = length $value;
+                        # generate our new entry
+                        my $entry = pack("CCC", 0x1c, $newRec, $newTag);
+                        if ($len <= 0x7fff) {
+                            $entry .= pack("n", $len);
+                        } else {
+                            # extended dataset tag
+                            $entry .= pack("nN", 0x8004, $len);
+                        }
+                        $newData .= $entry . $value;    # add entry to new IPTC data
+                        ++$exifTool->{CHANGED};
+                    }
+                }
+                # remove this tagID from the sorted write list
+                shift @{$iptcInfo{$newRec}};
+                shift @recordList unless @{$iptcInfo{$newRec}};
+            }
+            # all done if no more records to write
+            last unless defined $rec;
+            # update last record variables
+            $lastRec = $rec;
+            $lastRecPos = length $newData;
+            $allMandatory = 1;
+        }
+        # set flag indicating we found this tag
+        $foundRec{$rec}->{$tag} = 1;
+        # write out this record unless we are setting it with a new value
+        $tagInfo = $set{$rec}->{$tag};
+        if ($tagInfo) {
+            my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+            $len = $pos - $valuePtr;
+            my $val = substr($$dataPt, $valuePtr, $len);
+            my $oldXlat = $xlat;
+            FormatIPTC($exifTool, $tagInfo, \$val, \$xlat, $rec, 1);
+            if (Image::ExifTool::IsOverwriting($newValueHash, $val)) {
+                $xlat = $oldXlat;   # don't change translation (not writing this value)
+                $verbose > 1 and print $out "    - IPTC:$$tagInfo{Name} = '$val'\n";
+                ++$exifTool->{CHANGED};
+                # set deleted flag to indicate we found and deleted this tag
+                $foundRec{$rec}->{$tag} |= 0x02;
+                # set allMandatory flag to 2 indicating a tag was removed
+                $allMandatory and ++$allMandatory;
+                next;
+            }
+        } elsif ($rec == 1 and $tag == 90) {
+            # handle CodedCharacterSet tag
+            my $val = substr($$dataPt, $valuePtr, $pos - $valuePtr);
+            $xlat = HandleCodedCharset($exifTool, $val);
+        }
+        # reset allMandatory flag if a non-mandatory tag is written
+        if ($allMandatory) {
+            my $mandatory = $mandatory{$rec};
+            unless ($mandatory and $mandatory->{$tag}) {
+                $allMandatory = 0;
+            }
+        }
+        # write out the record
+        $newData .= substr($$dataPt, $tail, $pos-$tail);
+    }
+    # make sure the rest of the data is zero
+    if ($tail < $dirEnd) {
+        my $trailer = substr($$dataPt, $tail, $dirEnd-$tail);
+        if ($trailer =~ /[^\0]/) {
+            return undef if $exifTool->Warn('Unrecognized data in IPTC trailer', 1);
+        }
+    }
+    return $newData;
+}
+
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::WriteIPTC.pl - Write IPTC meta information
+
+=head1 SYNOPSIS
+
+This file is autoloaded by Image::ExifTool::IPTC.
+
+=head1 DESCRIPTION
+
+This file contains routines to write IPTC metadata, plus a few other
+seldom-used routines.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::IPTC(3pm)|Image::ExifTool::IPTC>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/WritePNG.pl
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/WritePNG.pl	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/WritePNG.pl	(revision 20131)
@@ -0,0 +1,294 @@
+#------------------------------------------------------------------------------
+# File:         WritePNG.pl
+#
+# Description:  Write PNG meta information
+#
+# Revisions:    09/16/2005 - P. Harvey Created
+#
+# References:   1) http://www.libpng.org/pub/png/spec/1.2/
+#------------------------------------------------------------------------------
+package Image::ExifTool::PNG;
+
+use strict;
+
+#------------------------------------------------------------------------------
+# Calculate CRC or update running CRC (ref 1)
+# Inputs: 0) data reference, 1) running crc to update (undef intially)
+#         2) data position (undef for 0), 3) data length (undef for all data),
+# Returns: updated CRC
+my @crcTable;
+sub CalculateCRC($;$$$)
+{
+    my ($dataPt, $crc, $pos, $len) = @_;
+    $crc = 0 unless defined $crc;
+    $pos = 0 unless defined $pos;
+    $len = length($$dataPt) - $pos unless defined $len;
+    $crc ^= 0xffffffff;         # undo 1's complement
+    # build lookup table unless done already
+    unless (@crcTable) {
+        my ($c, $n, $k);
+        for ($n=0; $n<256; ++$n) {
+            for ($k=0, $c=$n; $k<8; ++$k) {
+                $c = ($c & 1) ? 0xedb88320 ^ ($c >> 1) : $c >> 1;
+            }
+            $crcTable[$n] = $c;
+        }
+    }
+    # calculate the CRC
+    foreach (unpack("x${pos}C$len", $$dataPt)) {
+        $crc = $crcTable[($crc^$_) & 0xff] ^ ($crc >> 8);
+    }
+    return $crc ^ 0xffffffff;   # return 1's complement
+}
+
+#------------------------------------------------------------------------------
+# Encode data in ASCII Hex
+# Inputs: 0) input data reference
+# Returns: Hex-encoded data (max 72 chars per line)
+sub HexEncode($)
+{
+    my $dataPt = shift;
+    my $len = length($$dataPt);
+    my $hex = '';
+    my $pos;
+    for ($pos = 0; $pos < $len; $pos += 36) {
+        my $n = $len - $pos;
+        $n > 36 and $n = 36;
+        $hex .= unpack('H*',substr($$dataPt,$pos,$n)) . "\n";
+    }
+    return $hex;
+}
+
+#------------------------------------------------------------------------------
+# Write profile to tEXt or zTXt chunk (zTXt if Zlib is available)
+# Inputs: 0) outfile, 1) Raw profile type, 2) data ref
+#         3) profile header type (undef if not a text profile)
+# Returns: 1 on success
+sub WriteProfile($$$;$)
+{
+    my ($outfile, $rawType, $dataPt, $profile) = @_;
+    my ($buff, $prefix, $chunk, $deflate);
+    if (eval 'require Compress::Zlib') {
+        $deflate = Compress::Zlib::deflateInit();
+    }
+    if (not defined $profile) {
+        # write ICC profile as compressed iCCP chunk if possible
+        return 0 unless $deflate;
+        $buff = $deflate->deflate($$dataPt);
+        return 0 unless defined $buff;
+        $buff .= $deflate->flush();
+        my %rawTypeChunk = ( icm => 'iCCP' );
+        $chunk = $rawTypeChunk{$rawType} or return 0;
+        $prefix = "$rawType\0\0";
+        $dataPt = \$buff;
+    } else {
+        # write as ASCII-hex encoded profile in tEXt or zTXt chunk
+        my $txtHdr = sprintf("\n$profile profile\n%8d\n", length($$dataPt));
+        $buff = $txtHdr . HexEncode($dataPt);
+        $chunk = 'tEXt';         # write as tEXt if deflate not available
+        $prefix = "Raw profile type $rawType\0";
+        $dataPt = \$buff;
+        # write profile as zTXt chunk if possible
+        if ($deflate) {
+            my $buf2 = $deflate->deflate($buff);
+            if (defined $buf2) {
+                $dataPt = \$buf2;
+                $buf2 .= $deflate->flush();
+                $chunk = 'zTXt';
+                $prefix .= "\0";    # compression type byte (0=deflate)
+            }
+        }
+    }
+    my $hdr = pack('Na4', length($prefix) + length($$dataPt), $chunk) . $prefix;
+    my $crc = CalculateCRC(\$hdr, undef, 4);
+    $crc = CalculateCRC($dataPt, $crc);
+    return Write($outfile, $hdr, $$dataPt, pack('N',$crc));
+}
+
+#------------------------------------------------------------------------------
+# Add iCCP to the PNG image if necessary (must come before PLTE and IDAT)
+# Inputs: 0) ExifTool object ref, 1) output file or scalar ref
+# Returns: true on success
+sub Add_iCCP($$)
+{
+    my ($exifTool, $outfile) = @_;
+    if ($exifTool->{ADD_DIRS}->{ICC_Profile}) {
+        # write new ICC data
+        my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
+        my %dirInfo = ( Parent => 'PNG', DirName => 'ICC_Profile' );
+        my $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+        if (defined $buff and length $buff and WriteProfile($outfile, 'icm', \$buff)) {
+            $exifTool->VPrint(0, "Created ICC profile\n");
+            delete $exifTool->{ADD_DIRS}->{ICC_Profile}; # don't add it again
+        }
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Add any outstanding new chunks to the PNG image
+# Inputs: 0) ExifTool object ref, 1) output file or scalar ref
+# Returns: true on success
+sub AddChunks($$)
+{
+    my ($exifTool, $outfile) = @_;
+    # write any outstanding PNG tags
+    my $addTags = $exifTool->{ADD_PNG};
+    delete $exifTool->{ADD_PNG};
+    my ($tag, $dir, $err, $tagTablePtr);
+
+    foreach $tag (sort keys %$addTags) {
+        my $tagInfo = $$addTags{$tag};
+        my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+        # (always create native PNG information, so don't check IsCreating())
+        next unless Image::ExifTool::IsOverwriting($newValueHash) > 0;
+        my $val = Image::ExifTool::GetNewValues($newValueHash);
+        if (defined $val) {
+            my $data;
+            if ($$tagInfo{Table} eq \%Image::ExifTool::PNG::TextualData) {
+                $data = "tEXt$tag\0$val";
+            } else {
+                $data = "$tag$val";
+            }
+            # write as compressed zTXt if specified
+            if ($exifTool->Options('Compress')) {
+                my $warn;
+                if (eval 'require Compress::Zlib') {
+                    my $buff;
+                    my $deflate = Compress::Zlib::deflateInit();
+                    $buff = $deflate->deflate($val) if $deflate;
+                    if (defined $buff) {
+                        $buff .= $deflate->flush();
+                        # only write as zTXt if it actually saves space
+                        if (length($buff) < length($val) - 1) {
+                            $data = "zTXt$tag\0\0$buff";
+                        } else {
+                            $warn = 'uncompressed data is smaller';
+                        }
+                    } else {
+                        $warn = 'deflate error';
+                    }
+                } else {
+                    $warn = 'Compress::Zlib not available'; 
+                }
+                $warn and $exifTool->Warn("PNG:$$tagInfo{Name} not compressed ($warn)", 1);
+            }
+            my $hdr = pack('N', length($data) - 4);
+            my $cbuf = pack('N', CalculateCRC(\$data, undef));
+            Write($outfile, $hdr, $data, $cbuf) or $err = 1;
+            $exifTool->VPrint(1, "    + PNG:$$tagInfo{Name} = '",$exifTool->Printable($val),"'\n");
+            ++$exifTool->{CHANGED};
+        }
+    }
+    $addTags = { };     # prevent from adding tags again
+    # create any necessary directories
+    foreach $dir (sort keys %{$exifTool->{ADD_DIRS}}) {
+        my $buff;
+        my %dirInfo = (
+            Parent => 'PNG',
+            DirName => $dir,
+        );
+        if ($dir eq 'IFD0') {
+            $exifTool->VPrint(0, "Creating EXIF profile:\n");
+            $exifTool->{TIFF_TYPE} = 'APP1';
+            $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main');
+            # use specified byte ordering or ordering from maker notes if set
+            my $byteOrder = $exifTool->Options('ByteOrder') ||
+                $exifTool->GetNewValues('ExifByteOrder') || $exifTool->{MAKER_NOTE_BYTE_ORDER} || 'MM';
+            unless (SetByteOrder($byteOrder)) {
+                warn "Invalid byte order '$byteOrder'\n";
+                $byteOrder = $exifTool->{MAKER_NOTE_BYTE_ORDER} || 'MM';
+                SetByteOrder($byteOrder);
+            }
+            $dirInfo{NewDataPos} = 8,   # new data will come after TIFF header
+            $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+            if (defined $buff and length $buff) {
+                my $tiffHdr = $byteOrder . Set16u(42) . Set32u(8);
+                $buff = $Image::ExifTool::exifAPP1hdr . $tiffHdr . $buff;
+                WriteProfile($outfile, 'APP1', \$buff, 'generic') or $err = 1;
+            }
+        } elsif ($dir eq 'XMP') {
+            $exifTool->VPrint(0, "Creating XMP iTXt chunk:\n");
+            $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
+            $dirInfo{ReadOnly} = 1;
+            $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+            if (defined $buff and length $buff and
+                # the packet is read-only (because of CRC)
+                Image::ExifTool::XMP::ValidateXMP(\$buff, 'r'))
+            {
+                # (previously, XMP was created as a non-standard XMP profile chunk)
+                # $buff = $Image::ExifTool::xmpAPP1hdr . $buff;
+                # WriteProfile($outfile, 'APP1', \$buff, 'generic') or $err = 1;
+                # (but now write XMP iTXt chunk according to XMP specification)
+                $buff = "iTXtXML:com.adobe.xmp\0\0\0\0\0" . $buff;
+                my $hdr = pack('N', length($buff) - 4);
+                my $cbuf = pack('N', CalculateCRC(\$buff, undef));
+                Write($outfile, $hdr, $buff, $cbuf) or $err = 1;
+            }
+        } elsif ($dir eq 'IPTC') {
+            $exifTool->VPrint(0, "Creating IPTC profile:\n");
+            # write new IPTC data
+            $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
+            $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+            if (defined $buff and length $buff) {
+                WriteProfile($outfile, 'iptc', \$buff, 'IPTC') or $err = 1;
+            }
+        } elsif ($dir eq 'ICC_Profile') {
+            $exifTool->VPrint(0, "Creating ICC profile:\n");
+            # write new ICC data (only done if we couldn't create iCCP chunk)
+            $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
+            $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+            if (defined $buff and length $buff) {
+                WriteProfile($outfile, 'icm', \$buff, 'ICC') or $err = 1;
+                $exifTool->Warn('Wrote ICC as generic profile (no Compress::Zlib)');
+            }
+        }
+    }
+    $exifTool->{ADD_DIRS} = { };    # prevent from adding dirs again
+    return not $err;
+}
+
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::WritePNG.pl - Write PNG meta information
+
+=head1 SYNOPSIS
+
+These routines are autoloaded by Image::ExifTool::PNG.
+
+=head1 DESCRIPTION
+
+This file contains routines to write PNG metadata.
+
+=head1 NOTES
+
+Compress::Zlib is required to write compressed text.
+
+Existing text tags are always rewritten in their original form (compressed
+zTXt, uncompressed tEXt or internation iTXt), so pre-existing compressed
+information can only be modified if Compress::Zlib is available.
+
+Newly created textual information is written in uncompressed tEXt form by
+default, or as compressed zTXt if the Compress option is used and
+Compress::Zlib is available (but only if the resulting compressed data is
+smaller than the original text, which isn't always the case for short text
+strings).
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::PNG(3pm)|Image::ExifTool::PNG>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/WritePhotoshop.pl
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/WritePhotoshop.pl	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/WritePhotoshop.pl	(revision 20131)
@@ -0,0 +1,239 @@
+#------------------------------------------------------------------------------
+# File:         WritePhotoshop.pl
+#
+# Description:  Write Photoshop IRB meta information
+#
+# Revisions:    12/17/2004 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Photoshop;
+
+use strict;
+
+#------------------------------------------------------------------------------
+# Strip resource name from value prepare resource name for writing into IRB
+# Inputs: 0) tagInfo ref, 1) resource name (padded pascal string), 2) new value ref
+# Returns: none (updates name and value if necessary)
+sub SetResourceName($$$)
+{
+    my ($tagInfo, $name, $valPt) = @_;
+    my $setName = $$tagInfo{SetResourceName};
+    if (defined $setName) {
+        # extract resource name from value
+        if ($$valPt =~ m{.*/#(.{0,255})#/$}s) {
+            $name = $1;
+            # strip name from value
+            $$valPt = substr($$valPt, 0, -4 - length($name));
+        } elsif ($setName eq '1') {
+            return;     # use old name
+        } else {
+            $name = $setName;
+        }
+        # convert to padded pascal string
+        $name = chr(length $name) . $name;
+        $name .= "\0" if length($name) & 0x01;
+        $_[1] = $name;  # return new name
+    }
+}
+
+#------------------------------------------------------------------------------
+# Write Photoshop IRB resource
+# Inputs: 0) ExifTool object reference, 1) source dirInfo reference,
+#         2) tag table reference
+# Returns: IRB resource data (may be empty if no Photoshop data)
+# Notes: Increments ExifTool CHANGED flag for each tag changed
+sub WritePhotoshop($$$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    $exifTool or return 1;    # allow dummy access to autoload this package
+    my $dataPt = $$dirInfo{DataPt};
+    unless ($dataPt) {
+        my $emptyData = '';
+        $dataPt = \$emptyData;
+    }
+    my $start = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $start);
+    my $dirEnd = $start + $dirLen;
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my $newData = '';
+
+    # make a hash of new tag info, keyed on tagID
+    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+
+    my ($addDirs, $editDirs) = $exifTool->GetAddDirHash($tagTablePtr);
+
+    SetByteOrder('MM');     # Photoshop is always big-endian
+#
+# rewrite existing tags in the old directory, deleting ones as necessary
+# (the Photoshop directory entries aren't in any particular order)
+#
+    # Format: 0) Type, 4 bytes - '8BIM' (or the rare 'PHUT', 'DCSR' or 'AgHg')
+    #         1) TagID,2 bytes
+    #         2) Name, pascal string padded to even no. bytes
+    #         3) Size, 4 bytes - N
+    #         4) Data, N bytes
+    my ($pos, $value, $size, $tagInfo, $tagID);
+    for ($pos=$start; $pos+8<$dirEnd; $pos+=$size) {
+        # each entry must be on same even byte boundary as directory start
+        ++$pos if ($pos ^ $start) & 0x01;
+        my $type = substr($$dataPt, $pos, 4);
+        if ($type !~ /^(8BIM|PHUT|DCSR|AgHg)$/) {
+            $exifTool->Error("Bad Photoshop IRB resource");
+            undef $newData;
+            last;
+        }
+        $tagID = Get16u($dataPt, $pos + 4);
+        # get resource block name (pascal string padded to an even # of bytes)
+        my $namelen = 1 + Get8u($dataPt, $pos + 6);
+        ++$namelen if $namelen & 0x01;
+        if ($pos + $namelen + 10 > $dirEnd) {
+            $exifTool->Error("Bad APP13 resource block");
+            undef $newData;
+            last;
+        }
+        my $name = substr($$dataPt, $pos + 6, $namelen);
+        $size = Get32u($dataPt, $pos + 6 + $namelen);
+        $pos += $namelen + 10;
+        if ($size + $pos > $dirEnd) {
+            $exifTool->Error("Bad APP13 resource data size $size");
+            undef $newData;
+            last;
+        }
+        if ($$newTags{$tagID} and $type eq '8BIM') {
+            $tagInfo = $$newTags{$tagID};
+            delete $$newTags{$tagID};
+            my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+            # check to see if we are overwriting this tag
+            $value = substr($$dataPt, $pos, $size);
+            if (Image::ExifTool::IsOverwriting($newValueHash, $value)) {
+                $verbose > 1 and print $out "    - Photoshop:$$tagInfo{Name} = '$value'\n";
+                $value = Image::ExifTool::GetNewValues($newValueHash);
+                ++$exifTool->{CHANGED};
+                next unless defined $value;     # next if tag is being deleted
+                # set resource name if necessary
+                SetResourceName($tagInfo, $name, \$value);
+                $verbose > 1 and print $out "    + Photoshop:$$tagInfo{Name} = '$value'\n";
+            }
+        } else {
+            if ($type eq '8BIM') {
+                $tagInfo = $$editDirs{$tagID};
+                unless ($tagInfo) {
+                    # process subdirectory anyway if writable (except EXIF to avoid recursion)
+                    # --> this allows IPTC to be processed if found here in TIFF images
+                    my $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+                    if ($tmpInfo and $$tmpInfo{SubDirectory} and
+                        $tmpInfo->{SubDirectory}->{TagTable} ne 'Image::ExifTool::Exif::Main')
+                    {
+                        my $table = Image::ExifTool::GetTagTable($tmpInfo->{SubDirectory}->{TagTable});
+                        $tagInfo = $tmpInfo if $$table{WRITE_PROC};
+                    }
+                }
+            }
+            if ($tagInfo) {
+                $$addDirs{$tagID} and delete $$addDirs{$tagID};
+                my %subdirInfo = (
+                    DataPt => $dataPt,
+                    DirStart => $pos,
+                    DataLen => $dirLen,
+                    DirLen => $size,
+                    Parent => $$dirInfo{DirName},
+                );
+                my $subTable = Image::ExifTool::GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                my $writeProc = $tagInfo->{SubDirectory}->{WriteProc};
+                my $newValue = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
+                if (defined $newValue) {
+                    next unless length $newValue;   # remove subdirectory entry
+                    $value = $newValue;
+                    SetResourceName($tagInfo, $name, \$value);
+                } else {
+                    $value = substr($$dataPt, $pos, $size); # rewrite old directory
+                }
+            } else {
+                $value = substr($$dataPt, $pos, $size);
+            }
+        }
+        my $newSize = length $value;
+        # write this directory entry
+        $newData .= $type . Set16u($tagID) . $name . Set32u($newSize) . $value;
+        $newData .= "\0" if $newSize & 0x01;    # must null pad to even byte
+    }
+#
+# write any remaining entries we didn't find in the old directory
+# (might as well write them in numerical tag order)
+#
+    my @tagsLeft = sort { $a <=> $b } keys(%$newTags), keys(%$addDirs);
+    foreach $tagID (@tagsLeft) {
+        my $name = "\0\0";
+        if ($$newTags{$tagID}) {
+            $tagInfo = $$newTags{$tagID};
+            my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+            $value = Image::ExifTool::GetNewValues($newValueHash);
+            next unless defined $value;     # next if tag is being deleted
+            # don't add this tag unless specified
+            next unless Image::ExifTool::IsCreating($newValueHash);
+            $verbose > 1 and print $out "    + Photoshop:$$tagInfo{Name} = '$value'\n";
+            ++$exifTool->{CHANGED};
+        } else {
+            $tagInfo = $$addDirs{$tagID};
+            # create new directory
+            my %subdirInfo = (
+                Parent => $$dirInfo{DirName},
+            );
+            my $subTable = Image::ExifTool::GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+            my $writeProc = $tagInfo->{SubDirectory}->{WriteProc};
+            $value = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
+            next unless $value;
+        }
+        # set resource name if necessary
+        SetResourceName($tagInfo, $name, \$value);
+        $size = length($value);
+        # write the new directory entry
+        $newData .= '8BIM' . Set16u($tagID) . $name . Set32u($size) . $value;
+        $newData .= "\0" if $size & 0x01;   # must null pad to even numbered byte
+        ++$exifTool->{CHANGED};
+    }
+    return $newData;
+}
+
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::WritePhotoshop.pl - Write Photoshop IRB meta information
+
+=head1 SYNOPSIS
+
+This file is autoloaded by Image::ExifTool::Photoshop.
+
+=head1 DESCRIPTION
+
+This file contains routines to write Photoshop metadata.
+
+=head1 NOTES
+
+Photoshop IRB blocks may have an associated resource name.  By default, the
+existing name is preserved when rewriting a resource, and an empty name is
+used when creating a new resource.  However, a different resource name may
+be specified by defining a C<SetResourceName> entry in the tag information
+hash.  With this defined, a new resource name may be appended to the value
+in the form "VALUE/#NAME#/" (the slashes and hashes are literal).  If
+C<SetResourceName> is anything other than '1', the value is used as a
+default resource name, and applied if no appended name is provided.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::Photoshop(3pm)|Image::ExifTool::Photoshop>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/WritePostScript.pl
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/WritePostScript.pl	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/WritePostScript.pl	(revision 20131)
@@ -0,0 +1,743 @@
+#------------------------------------------------------------------------------
+# File:         WritePostScript.pl
+#
+# Description:  Write PostScript meta information
+#
+# Revisions:    03/03/2006 - P. Harvey Created
+#
+# References:   (see references in PostScript.pm, plus:)
+#               1) http://www.adobe.com/products/postscript/pdfs/PLRM.pdf
+#               2) http://www-cdf.fnal.gov/offline/PostScript/PLRM2.pdf
+#               3) http://partners.adobe.com/public/developer/en/acrobat/sdk/pdf/pdf_creation_apis_and_specs/pdfmarkReference.pdf
+#               4) http://www.npes.org/standards/Tools/DCS20Spec.pdf
+#
+# Notes:        (see NOTES in POD doc below)
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::PostScript;
+
+use strict;
+
+# Structure of a DSC PS/EPS document:
+#
+#   %!PS-Adobe-3.0     [plus " EPSF-3.0" for EPS]
+#     <comments>
+#   %%EndComments      [optional]
+#   %%BeginXxxx
+#     <stuff to ignore>
+#   %%EndXxxx
+#   %%BeginProlog
+#     <prolog stuff>
+#   %%EndProlog
+#   %%BeginSetup
+#     <setup stuff>
+#   %%EndSetup
+#   %ImageData x x x x  [written by Photoshop]
+#   %BeginPhotoshop: xxxx
+#     <ascii-hex IRB information>
+#   %EndPhotosop
+#   %%BeginICCProfile: (name) <num> <type>
+#     <ICC Profile info>
+#   %%EndICCProfile
+#   %begin_xml_code
+#     <postscript code to define and read the XMP stream object>
+#   %begin_xml_packet: xxxx
+#     <XMP data>
+#   %end_xml_packet
+#     <postscript code to add XMP stream to dictionary>
+#   %end_xml_code
+#   %%Page: x x         [PS only (optional?)]
+#     <graphics commands>
+#   %%PageTrailer
+#   %%Trailer
+#     <a bit more code to bracket EPS content for distiller>
+#   %%EOF
+
+# map of where information is stored in PS image
+my %psMap = (
+    XMP          => 'PostScript',
+    Photoshop    => 'PostScript',
+    IPTC         => 'Photoshop',
+    EXIFInfo     => 'Photoshop',
+    IFD0         => 'EXIFInfo',
+    IFD1         => 'IFD0',
+    ICC_Profile  => 'PostScript',
+    ExifIFD      => 'IFD0',
+    GPS          => 'IFD0',
+    SubIFD       => 'IFD0',
+    GlobParamIFD => 'IFD0',
+    PrintIM      => 'IFD0',
+    InteropIFD   => 'ExifIFD',
+    MakerNotes   => 'ExifIFD',
+);
+
+
+#------------------------------------------------------------------------------
+# Check PS tag value
+# Inputs: 0) ExifTool object ref, 1) tag info ref, 2) value ref
+# Returns: undef on success, or error string
+sub CheckPS($$$)
+{
+    my ($exifTool, $tagInfo, $valPt) = @_;
+    # parentheses must be balanced (or escaped)
+    my $n = 0;
+    pos($$valPt) = 0;
+    while ($$valPt =~ /(\(|\))/g) {
+        $n += ($1 eq '(') ? 1 : -1;
+        last if $n < 0;
+    }
+    return 'Unmatched parentheses' unless $n == 0;
+    return undef;   # success
+}
+
+#------------------------------------------------------------------------------
+# Write XMP directory to file, with begin/end tokens if necessary
+# Inputs: 0) outfile ref, 1) flags hash ref, 2-N) data to write
+# Returns: true on success
+sub WriteXMPDir($$@)
+{
+    my $outfile = shift;
+    my $flags = shift;
+    my $success = 1;
+    Write($outfile, "%begin_xml_code$/") or $success = 0 unless $$flags{WROTE_BEGIN};
+    Write($outfile, @_) or $success = 0;
+    Write($outfile, "%end_xml_code$/") or $success = 0 unless $$flags{WROTE_BEGIN};
+    return $success;
+}
+
+#------------------------------------------------------------------------------
+# Write a directory inside a PS document
+# Inputs: 0) ExifTool object ref, 1) output file reference,
+#         2) Directory name, 3) data reference, 4) flags hash ref
+# Returns: 0=error, 1=nothing written, 2=dir written ok
+sub WritePSDirectory($$$$$)
+{
+    my ($exifTool, $outfile, $dirName, $dataPt, $flags) = @_;
+    my $success = 2;
+    my $len = $dataPt ? length($$dataPt) : 0;
+    my $create = $len ? 0 : 1;
+    my %dirInfo = (
+        DataPt => $dataPt,
+        DataLen => $len,
+        DirStart => 0,
+        DirLen => $len,
+        DirName => $dirName,
+        Parent => 'PostScript',
+    );
+    # Note: $$flags{WROTE_BEGIN} may be 1 for XMP (it is always 0 for
+    # other dirs, but if 1, the begin/end markers were already written)
+#
+# prepare necessary postscript code to support embedded XMP
+#
+    my ($beforeXMP, $afterXMP, $reportedLen);
+    if ($dirName eq 'XMP' and $len) {
+        # isolate the XMP
+        pos($$dataPt) = 0;
+        unless ($$dataPt =~ /(.*)(<\?xpacket begin=.{7,13}W5M0MpCehiHzreSzNTczkc9d)/sg) {
+            $exifTool->Warn('No XMP packet start');
+            return WriteXMPDir($outfile, $flags, $$dataPt);
+        }
+        $beforeXMP = $1;
+        my $xmp = $2;
+        my $p1 = pos($$dataPt);
+        unless ($$dataPt =~ m{<\?xpacket end=.(w|r).\?>}sg) {
+            $exifTool->Warn('No XMP packet end');
+            return WriteXMPDir($outfile, $flags, $$dataPt);
+        }
+        my $p2 = pos($$dataPt);
+        $xmp .= substr($$dataPt, $p1, $p2-$p1);
+        $afterXMP = substr($$dataPt, $p2);
+        # determine if we can adjust the XMP size
+        if ($beforeXMP =~ /%begin_xml_packet: (\d+)/s) {
+            $reportedLen = $1;
+            my @matches= ($beforeXMP =~ /\b$reportedLen\b/sg);
+            undef $reportedLen unless @matches == 2;
+        }
+        # must edit in place if we can't reliably change the XMP length
+        $dirInfo{InPlace} = 1 unless $reportedLen;
+        # process XMP only
+        $dirInfo{DataLen} = $dirInfo{DirLen} = length $xmp;
+        $dirInfo{DataPt} = \$xmp;
+    }
+    my $tagTablePtr = GetTagTable("Image::ExifTool::${dirName}::Main");
+    my $val = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+    if (defined $val) {
+        $dataPt = \$val;    # use modified directory
+        $len = length $val;
+    } elsif ($dirName eq 'XMP') {
+        return 1 unless $len;
+        # just write the original XMP
+        return WriteXMPDir($outfile, $flags, $$dataPt);
+    }
+    unless ($len) {
+        return 1 if $create or $dirName ne 'XMP';   # nothing to create
+        # it would be really difficult to delete the XMP,
+        # so instead we write a blank XMP record
+        $val = <<EMPTY_XMP;
+<?xpacket begin='ï»¿' id='W5M0MpCehiHzreSzNTczkc9d'?>
+<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool $Image::ExifTool::VERSION'>
+</x:xmpmeta>
+EMPTY_XMP
+        $val .= ((' ' x 100) . "\n") x 24 unless $exifTool->Options('Compact');
+        $val .= q{<?xpacket end='w'?>};
+        $dataPt = \$val;
+        $len = length $val;
+    }
+#
+# write XMP directory
+#
+    if ($dirName eq 'XMP') {
+        if ($create) {
+            # create necessary PS/EPS code to support XMP
+            $beforeXMP = <<HDR_END;
+/pdfmark where {pop true} {false} ifelse
+/currentdistillerparams where {pop currentdistillerparams
+/CoreDistVersion get 5000 ge } {false} ifelse
+and not {userdict /pdfmark /cleartomark load put} if
+[/NamespacePush pdfmark
+[/_objdef {exiftool_metadata_stream} /type /stream /OBJ pdfmark
+[{exiftool_metadata_stream} 2 dict begin /Type /Metadata def
+  /Subtype /XML def currentdict end /PUT pdfmark
+/MetadataString $len string def % exact length of metadata
+/TempString 100 string def
+/ConsumeMetadata {
+currentfile TempString readline pop pop
+currentfile MetadataString readstring pop pop
+} bind def
+ConsumeMetadata
+%begin_xml_packet: $len
+HDR_END
+            # note: use q() to get necessary linefeed before %end_xml_packet
+            $afterXMP = q(
+%end_xml_packet
+[{exiftool_metadata_stream} MetadataString /PUT pdfmark
+);
+            if ($$flags{EPS}) {
+                $afterXMP .= <<EPS_AFTER;
+[/Document 1 dict begin
+  /Metadata {exiftool_metadata_stream} def currentdict end /BDC pdfmark
+[/NamespacePop pdfmark
+EPS_AFTER
+                # write this at end of file
+                $$flags{TRAILER} = "[/EMC pdfmark$/";
+            } else { # PS
+                $afterXMP .= <<PS_AFTER;
+[{Catalog} {exiftool_metadata_stream} /Metadata pdfmark
+[/NamespacePop pdfmark
+PS_AFTER
+            }
+            $beforeXMP =~ s{\n}{$/}sg;  # use proper newline characters
+            $afterXMP =~ s{\n}{$/}sg;
+        } else {
+            # replace xmp size in PS code
+            $reportedLen and $beforeXMP =~ s/\b$reportedLen\b/$len/sg;
+        }
+        WriteXMPDir($outfile, $flags, $beforeXMP, $$dataPt, $afterXMP) or $success = 0;
+#
+# Write Photoshop or ICC_Profile directory
+#
+    } elsif ($dirName eq 'Photoshop' or $dirName eq 'ICC_Profile') {
+        my ($startToken, $endToken);
+        if ($dirName eq 'Photoshop') {
+            $startToken = "%BeginPhotoshop: $len";
+            $endToken = '%EndPhotoshop';
+        } else {
+            $startToken = '%%BeginICCProfile: (Photoshop Profile) -1 Hex';
+            $endToken = '%%EndICCProfile';
+        }
+        Write($outfile, $startToken, $/) or $success = 0;
+        # write as an ASCII-hex comment
+        my $i;
+        my $wid = 32;
+        for ($i=0; $i<$len; $i+=$wid) {
+            $wid > $len-$i and $wid = $len-$i;
+            my $dat = substr($$dataPt, $i, $wid);
+            Write($outfile, "% ", uc(unpack('H*',$dat)), $/) or $success = 0;
+        }
+        Write($outfile, $endToken, $/) or $success = 0;
+    } else {
+        $exifTool->Warn("Can't write PS directory $dirName");
+    }
+    undef $val;
+    return $success;
+}
+
+#------------------------------------------------------------------------------
+# Write new tags information in comments section
+# Inputs: 0) ExifTool object ref, 1) output file ref, 2) reference to new tag hash
+# Returns: true on success
+sub WriteNewTags($$$)
+{
+    my ($exifTool, $outfile, $newTags) = @_;
+    my $success = 1;
+    my $tag;
+
+    # get XMP hint and remove from tags hash
+    my $xmpHint = $$newTags{XMP_HINT};
+    delete $$newTags{XMP_HINT};
+
+    foreach $tag (sort keys %$newTags) {
+        my $tagInfo = $$newTags{$tag};
+        my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+        next unless Image::ExifTool::IsCreating($newValueHash);
+        my $val = Image::ExifTool::GetNewValues($newValueHash);
+        if ($exifTool->Options('Verbose') > 1) {
+            my $out = $exifTool->Options('TextOut');
+            print $out "    + PostScript:$$tagInfo{Name} = '$val'\n";
+        }
+        $val =~ /^\d+$/ or $val = "($val)"; # add brackets around strings
+        my $buff = "%%$tag: $val$/";
+        if (length $buff > 255) {
+            $exifTool->Warn("Value for too long for $tag");
+        } else {
+            Write($outfile, $buff) or $success = 0;
+            ++$exifTool->{CHANGED};
+        }
+    }
+    # write XMP hint if necessary
+    Write($outfile, "%ADO_ContainsXMP: MainFirst$/") or $success = 0 if $xmpHint;
+
+    %$newTags = ();     # all done with new tags
+    return $success;
+}
+
+#------------------------------------------------------------------------------
+# check to be sure we haven't read past end of PS data in DOS-style file
+# Inputs: 0) RAF ref, 1) pointer to end of PS, 2) data
+# - modifies data and sets RAF to EOF if end of PS is reached
+sub CheckPSEnd($$$)
+{
+    my $pos = $_[0]->Tell();
+    if ($pos >= $_[1]) {
+        $_[0]->Seek(0, 2);   # seek to end of file so we can't read any more
+        $_[2] = substr($_[2], 0, length($_[2]) - $pos + $_[1]) if $pos > $_[1];
+    }
+}
+
+#------------------------------------------------------------------------------
+# Split into lines ending in any CR, LF or CR+LF combination
+# (this is annoying, and could be avoided if EPS files didn't mix linefeeds!)
+# Inputs: 0) data pointer, 1) reference to lines array
+# Notes: Updates data to contain next line and fills list with remaining lines
+sub SplitLine($$)
+{
+    my ($dataPt, $lines) = @_;
+    for (;;) {
+        my $endl;
+        # find the position of the first LF (\x0a)
+        $endl = pos($$dataPt), pos($$dataPt) = 0 if $$dataPt =~ /\x0a/g;
+        if ($$dataPt =~ /\x0d/g) { # find the first CR (\x0d)
+            if (defined $endl) {
+                # (remember, CR+LF is a DOS newline...)
+                $endl = pos($$dataPt) if pos($$dataPt) < $endl - 1;
+            } else {
+                $endl = pos($$dataPt);
+            }
+        } elsif (not defined $endl) {
+            push @$lines, $$dataPt;
+            last;
+        }
+        # split into separate lines
+        if (length $$dataPt == $endl) {
+            push @$lines, $$dataPt;
+            last;
+        } else {
+            push @$lines, substr($$dataPt, 0, $endl);
+            $$dataPt = substr($$dataPt, $endl);
+        }
+    }
+    $$dataPt = shift @$lines;   # set $$dataPt to first line
+}
+
+#------------------------------------------------------------------------------
+# Write PS file
+# Inputs: 0) ExifTool object reference, 1) source dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid PS file,
+#          or -1 if a write error occurred
+sub WritePS($$)
+{
+    my ($exifTool, $dirInfo) = @_;
+    $exifTool or return 1;    # allow dummy access to autoload this package
+    my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::PostScript::Main');
+    my $raf = $$dirInfo{RAF};
+    my $outfile = $$dirInfo{OutFile};
+    my $verbose = $exifTool->Options('Verbose');
+    my $out = $exifTool->Options('TextOut');
+    my ($data, $buff, %flags, $err, $mode, $endToken);
+    my ($dos, $psStart, $psEnd, $psNewStart, $xmpHint);
+
+    $raf->Read($data, 4) == 4 or return 0;
+    return 0 unless $data =~ /^(%!PS|%!Ad|\xc5\xd0\xd3\xc6)/;
+
+    if ($data =~ /^%!Ad/) {
+        # I've seen PS files start with "%!Adobe-PS"...
+        return 0 unless $raf->Read($buff, 6) == 6 and $buff eq "obe-PS";
+        $data .= $buff;
+
+    } elsif ($data =~ /^\xc5\xd0\xd3\xc6/) {
+#
+# process DOS binary PS files
+#
+        # save DOS header then seek ahead and check PS header
+        $raf->Read($dos, 26) == 26 or return 0;
+        $dos = $data . $dos;
+        SetByteOrder('II');
+        $psStart = Get32u(\$dos, 4);
+        unless ($raf->Seek($psStart, 0) and
+                $raf->Read($data, 4) == 4 and $data eq '%!PS')
+        {
+            $exifTool->Error('Invalid PS header');
+            return 1;
+        }
+        $psEnd = $psStart + Get32u(\$dos, 8);
+        my $base = Get32u(\$dos, 20);
+        Set16u(0xffff, \$dos, 28);  # ignore checksum
+        if ($base) {
+            my %dirInfo = (
+                Parent => 'PS',
+                RAF => $raf,
+                Base => $base,
+                NoTiffEnd => 1, # no end-of-TIFF check
+            );
+            $buff = $exifTool->WriteTIFF(\%dirInfo);
+            SetByteOrder('II'); # (WriteTIFF may change this)
+            if ($buff) {
+                $buff = substr($buff, $base);   # remove header written by WriteTIFF()
+            } else {
+                # error rewriting TIFF, so just copy over original data
+                my $len = Get32u(\$dos, 24);
+                unless ($raf->Seek($base, 0) and $raf->Read($buff, $len) == $len) {
+                    $exifTool->Error('Error reading embedded TIFF');
+                    return 1;
+                }
+                $exifTool->Warn('Bad embedded TIFF');
+            }
+            Set32u(0, \$dos, 12);                   # zero metafile pointer
+            Set32u(0, \$dos, 16);                   # zero metafile length
+            Set32u(length($dos), \$dos, 20);        # set TIFF pointer
+            Set32u(length($buff), \$dos, 24);       # set TIFF length
+        } elsif (($base = Get32u(\$dos, 12)) != 0) {
+            # copy over metafile section
+            my $len = Get32u(\$dos, 16);
+            unless ($raf->Seek($base, 0) and $raf->Read($buff, $len) == $len) {
+                $exifTool->Error('Error reading metafile section');
+                return 1;
+            }
+            Set32u(length($dos), \$dos, 12);        # set metafile pointer
+        } else {
+            $buff = '';
+        }
+        $psNewStart = length($dos) + length($buff);
+        Set32u($psNewStart, \$dos, 4);  # set pointer to start of PS
+        Write($outfile, $dos, $buff) or $err = 1;
+        $raf->Seek($psStart + 4, 0);    # seek back to where we were
+    }
+#
+# rewrite PostScript data
+#
+    my $oldsep = SetInputRecordSeparator($raf);
+    unless ($oldsep and $raf->ReadLine($buff)) {
+        $exifTool->Error('Invalid PostScript data');
+        return 1;
+    }
+    $data .= $buff;
+    unless ($data =~ /^%!PS-Adobe-3.(0|1)/) {
+        if ($exifTool->Error("Document does not conform to DSC spec. Metadata may be unreadable by other apps", 1)) {
+            return 1;
+        }
+    }
+    Write($outfile, $data) or $err = 1;
+    $flags{EPS} = 1 if $data =~ /EPSF/;
+
+    # get hash of new information keyed by tagID and directories to add/edit
+    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+
+    # figure out which directories we need to write (PostScript takes priority)
+    $exifTool->InitWriteDirs(\%psMap, 'PostScript');
+    my $addDirs = $exifTool->{ADD_DIRS};
+    my $editDirs = $exifTool->{EDIT_DIRS};
+    my %doneDir;
+
+    # set XMP hint flag (1 for adding, 0 for deleting, undef for no change)
+    $xmpHint = 1 if $$addDirs{XMP};
+    $xmpHint = 0 if $exifTool->{DEL_GROUP}->{XMP};
+    $$newTags{XMP_HINT} = $xmpHint if $xmpHint;  # add special tag to newTags list
+
+    my @lines;
+    my $altnl = ($/ eq "\x0d") ? "\x0a" : "\x0d";
+
+    for (;;) {
+        if (@lines) {
+            $data = shift @lines;
+        } else {
+            $raf->ReadLine($data) or last;
+            $dos and CheckPSEnd($raf, $psEnd, $data);
+            # split line if it contains other newline sequences
+            SplitLine(\$data, \@lines) if $data =~ /$altnl/;
+        }
+        if ($endToken) {
+            # look for end token
+            if ($data =~ m/^$endToken\s*$/is) {
+                undef $endToken;
+                # found end: process this information
+                if ($mode) {
+                    $doneDir{$mode} and $exifTool->Error("Multiple $mode directories", 1);
+                    $doneDir{$mode} = 1;
+                    WritePSDirectory($exifTool, $outfile, $mode, \$buff, \%flags) or $err = 1;
+                    # write end token if we wrote the begin token
+                    Write($outfile, $data) or $err = 1 if $flags{WROTE_BEGIN};
+                    undef $buff;
+                } else {
+                    Write($outfile, $data) or $err = 1;
+                }
+            } else {
+                # buffer data in current begin/end block
+                if (not defined $mode) {
+                    # pick up XMP in unrecognized blocks for editing in place
+                    if ($data =~ /^<\?xpacket begin=.{7,13}W5M0MpCehiHzreSzNTczkc9d/ and
+                        $$editDirs{XMP})
+                    {
+                        $buff = $data;
+                        $mode = 'XMP';
+                    } else {
+                        Write($outfile, $data) or $err = 1;
+                    }
+                } elsif ($mode eq 'XMP') {
+                    $buff .= $data;
+                } else {
+                    # data is ASCII-hex encoded
+                    $data =~ tr/0-9A-Fa-f//dc;  # remove all but hex characters
+                    $buff .= pack('H*', $data); # translate from hex
+                }
+            }
+            next;
+        } elsif ($data =~ m{^(%{1,2})(Begin)(?!Object:)(.*?)[:\x0d\x0a]}i) {
+            # comments section is over... write any new tags now
+            WriteNewTags($exifTool, $outfile, $newTags) or $err = 1 if %$newTags;
+            undef $xmpHint;
+            # the beginning of a data block (can only write XMP and Photoshop)
+            my %modeLookup = (
+                _xml_code => 'XMP',
+                photoshop => 'Photoshop',
+                iccprofile => 'ICC_Profile',
+            );
+            $verbose > 1 and print $out "$2$3\n";
+            $endToken = $1 . ($2 eq 'begin' ? 'end' : 'End') . $3;
+            $mode = $modeLookup{lc($3)};
+            if ($mode and $$editDirs{$mode}) {
+                $buff = '';     # initialize buffer for this block
+                $flags{WROTE_BEGIN} = 0;
+            } else {
+                undef $mode;    # not editing this directory
+                Write($outfile, $data) or $err = 1;
+                $flags{WROTE_BEGIN} = 1;
+            }
+            next;
+        } elsif ($data =~ /^%%(?!Page:|PlateFile:|BeginObject:)(\w+): ?(.*)/s) {
+            # rewrite information from PostScript tags in comments
+            my ($tag, $val) = ($1, $2);
+            if ($$newTags{$tag}) {
+                my $tagInfo = $$newTags{$tag};
+                next unless ref $tagInfo;
+                delete $$newTags{$tag}; # write it then forget it
+                $val =~ s/\x0d*\x0a*$//;        # remove trailing CR, LF or CR/LF
+                if ($val =~ s/^\((.*)\)$/$1/) { # remove brackets if necessary
+                    $val =~ s/\) \(/, /g;       # convert contained brackets too
+                }
+                my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+                if (Image::ExifTool::IsOverwriting($newValueHash, $val)) {
+                    $verbose > 1 and print $out "    - PostScript:$$tagInfo{Name} = '$val'\n";
+                    $val = Image::ExifTool::GetNewValues($newValueHash);
+                    ++$exifTool->{CHANGED};
+                    next unless defined $val;   # next if tag is being deleted
+                    $verbose > 1 and print $out "    + PostScript:$$tagInfo{Name} = '$val'\n";
+                    $val =~ /^\d+$/ or $val = "($val)"; # add brackets around strings
+                    $buff = "%%$tag: $val$/";
+                    if (length $buff > 255) {
+                        # lines in PS documents must be less than 256 characters
+                        # (don't yet support continuation with %%+ comment)
+                        $exifTool->Warn("Value for too long for $tag");
+                    } else {
+                        $data = $buff;  # write the new value
+                    }
+                }
+            }
+        # (note: Adobe InDesign doesn't put colon after %ADO_ContainsXMP -- doh!)
+        } elsif (defined $xmpHint and $data =~ m{^%ADO_ContainsXMP:? ?(.+?)[\x0d\x0a]*$}s) {
+            # change the XMP hint if necessary
+            if ($xmpHint) {
+                $data = "%ADO_ContainsXMP: MainFirst$/" if $1 eq 'NoMain';
+            } else {
+                $data = "%ADO_ContainsXMP: NoMain$/";
+            }
+            # delete XMP hint flags
+            delete $$newTags{XMP_HINT};
+            undef $xmpHint;
+        } else {
+            # look for end of comments section
+            if (%$newTags and ($data !~ /^%\S/ or
+                $data =~ /^%(%EndComments|%Page:|%PlateFile:|%BeginObject:|.*BeginLayer)/))
+            {
+                # write new tags at end of comments section
+                WriteNewTags($exifTool, $outfile, $newTags) or $err = 1;
+                undef $xmpHint;
+            }
+            # look for start of drawing commands (AI uses "%AI5_BeginLayer",
+            # and Helios uses "%%BeginObject:")
+            if ($data =~ /^%(%Page:|%PlateFile:|%BeginObject:|.*BeginLayer)/ or
+                $data !~ m{^(%.*|\s*)$}s)
+            {
+                # we have reached the first page or drawing command, so create necessary
+                # directories and copy the rest of the file, then all done
+                my $dir;
+                my $plateFile = ($data =~ /^%%PlateFile:/);
+                # create Photoshop first, then XMP if necessary
+                foreach $dir (qw{Photoshop ICC_Profile XMP}) {
+                    next unless $$editDirs{$dir} and not $doneDir{$dir};
+                    if ($plateFile) {
+                        # PlateFile comments may contain offsets so we can't edit these files!
+                        $exifTool->Warn("Can only edit PostScript information DCS Plate files");
+                        last;
+                    }
+                    next unless $$addDirs{$dir} or $dir eq 'XMP';
+                    $flags{WROTE_BEGIN} = 0;
+                    WritePSDirectory($exifTool, $outfile, $dir, undef, \%flags) or $err = 1;
+                    $doneDir{$dir} = 1;
+                }
+                # copy rest of file
+                if ($flags{TRAILER}) {
+                    # write trailer before %%EOF
+                    for (;;) {
+                        Write($outfile, $data) or $err = 1;
+                        if (@lines) {
+                            $data = shift @lines;
+                        } else {
+                            $raf->ReadLine($data) or undef($data), last;
+                            $dos and CheckPSEnd($raf, $psEnd, $data);
+                            if ($data =~ /[\x0d\x0a]%%EOF\b/g) {
+                                # split data before "%%EOF"
+                                # (necessary if data contains other newline sequences)
+                                my $pos = pos($data) - 5;
+                                push @lines, substr($data, $pos);
+                                $data = substr($data, 0, $pos);
+                            }
+                        }
+                        last if $data =~ /^%%EOF\b/;
+                    }
+                    Write($outfile, $flags{TRAILER}) or $err = 1;
+                }
+                # simply copy the rest of the file if any data is left
+                if (defined $data) {
+                    Write($outfile, $data) or $err = 1;
+                    Write($outfile, @lines) or $err = 1 if @lines;
+                    while ($raf->Read($data, 65536)) {
+                        $dos and CheckPSEnd($raf, $psEnd, $data);
+                        Write($outfile, $data) or $err = 1;
+                    }
+                }
+                last;   # all done!
+            }
+        }
+        # write new information or copy existing line
+        Write($outfile, $data) or $err = 1;
+    }
+    if ($dos and not $err) {
+        # must go back and set length of PS section in DOS header (very dumb design)
+        if (ref $outfile eq 'SCALAR') {
+            Set32u(length($$outfile) - $psNewStart, $outfile, 8);
+        } else {
+            my $pos = tell $outfile;
+            unless (seek($outfile, 8, 0) and
+                    print $outfile Set32u($pos - $psNewStart) and
+                    seek($outfile, $pos, 0))
+            {
+                $exifTool->Error("Can't write DOS-style PS files in non-seekable stream");
+                $err = 1;
+            }
+        }
+    }
+    # issue warning if we couldn't write any information
+    unless ($err) {
+        my (@notDone, $dir);
+        delete $$newTags{XMP_HINT};
+        push @notDone, 'PostScript' if %$newTags;
+        foreach $dir (qw{Photoshop ICC_Profile XMP}) {
+            push @notDone, $dir if $$editDirs{$dir} and not $doneDir{$dir};
+        }
+        @notDone and $exifTool->Warn("Couldn't write ".join('/',@notDone).' information');
+    }
+    $endToken and $exifTool->Error("File missing $endToken");
+    return $err ? -1 : 1;
+}
+
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::WritePostScript.pl - Write PostScript meta information
+
+=head1 SYNOPSIS
+
+This file is autoloaded by Image::ExifTool::PostScript.
+
+=head1 DESCRIPTION
+
+This file contains routines to write meta information in PostScript
+documents.  Six forms of meta information may be written:
+
+    1) PostScript comments (Adobe DSC specification)
+    2) XMP information embedded in a document-level XMP stream
+    3) EXIF information embedded in a Photoshop record
+    4) IPTC information embedded in a PhotoShop record
+    5) ICC_Profile information embedded in an ICCProfile record
+    6) TIFF information embedded in DOS-style binary header
+
+=head1 NOTES
+
+Currently, information is written only in the outter-level document.
+
+Photoshop will discard meta information in a PostScript document if it has
+to rasterize the image, and it will rasterize anything that doesn't contain
+the Photoshop-specific 'ImageData' tag.  So don't expect Photoshop to read
+any meta information added to EPS images that it didn't create.
+
+The following two acronyms may be confusing since they are so similar and
+have different meanings with respect to PostScript documents:
+
+    DSC = Document Structuring Conventions
+    DCS = Desktop Color Separation
+
+=head1 REFERENCES
+
+See references in L<PostScript.pm|Image::ExifTool::PostScript>, plus:
+
+=over 4
+
+=item L<http://www.adobe.com/products/postscript/pdfs/PLRM.pdf>
+
+=item L<http://www-cdf.fnal.gov/offline/PostScript/PLRM2.pdf>
+
+=item L<http://partners.adobe.com/public/developer/en/acrobat/sdk/pdf/pdf_creation_apis_and_specs/pdfmarkReference.pdf>
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Tim Kordick for his help testing the EPS writer.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::PostScript(3pm)|Image::ExifTool::PostScript>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/WriteXMP.pl
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/WriteXMP.pl	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/WriteXMP.pl	(revision 20131)
@@ -0,0 +1,1026 @@
+#------------------------------------------------------------------------------
+# File:         WriteXMP.pl
+#
+# Description:  Write XMP meta information
+#
+# Revisions:    12/19/2004 - P. Harvey Created
+#------------------------------------------------------------------------------
+package Image::ExifTool::XMP;
+
+use strict;
+use Image::ExifTool qw(:DataAccess :Utils);
+
+sub CheckXMP($$$);
+sub SetPropertyPath($$;$$);
+sub CaptureXMP($$$;$);
+
+my $debug = 0;
+
+# XMP structures (each structure is similar to a tag table so we can
+# recurse through them in SetPropertyPath() as if they were tag tables)
+my %xmpStruct = (
+    ResourceRef => {
+        NAMESPACE => 'stRef',
+        InstanceID      => { },
+        DocumentID      => { },
+        VersionID       => { },
+        RenditionClass  => { },
+        RenditionParams => { },
+        Manager         => { },
+        ManagerVariant  => { },
+        ManageTo        => { },
+        ManageUI        => { },
+    },
+    ResourceEvent => {
+        NAMESPACE => 'stEvt',
+        action          => { },
+        instanceID      => { },
+        parameters      => { },
+        softwareAgent   => { },
+        when            => { },
+    },
+    JobRef => {
+        NAMESPACE => 'stJob',
+        name        => { },
+        id          => { },
+        url         => { },
+    },
+    Version => {
+        NAMESPACE => 'stVer',
+        comments    => { },
+        event       => { Struct => 'ResourceEvent' },
+        modifyDate  => { },
+        modifier    => { },
+        version     => { },
+    },
+    Thumbnail => {
+        NAMESPACE => 'xapGImg',
+        height      => { },
+        width       => { },
+       'format'     => { },
+        image       => { },
+    },
+    IdentifierScheme => {
+        NAMESPACE => 'xmpidq',
+        Scheme      => { }, # qualifier for xmp:Identifier only
+    },
+    Dimensions => {
+        NAMESPACE => 'stDim',
+        w           => { },
+        h           => { },
+        unit        => { },
+    },
+    Colorant => {
+        NAMESPACE => 'xapG',
+        swatchName  => { },
+        mode        => { },
+        type        => { },
+        cyan        => { },
+        magenta     => { },
+        yellow      => { },
+        black       => { },
+        red         => { },
+        green       => { },
+        blue        => { },
+        L           => { },
+        A           => { },
+        B           => { },
+    },
+    Font => {
+        NAMESPACE => 'stFnt',
+        fontName    => { },
+        fontFamily  => { },
+        fontFace    => { },
+        fontType    => { },
+        versionString => { },
+        composite   => { },
+        fontFileName=> { },
+        childFontFiles=> { List => 'Seq' },
+    },
+    # the following stuctures are different:  They don't have
+    # their own namespaces -- instead they use the parent namespace
+    Flash => {
+        NAMESPACE => 'exif',
+        Fired       => { },
+        Return      => { },
+        Mode        => { },
+        Function    => { },
+        RedEyeMode  => { },
+    },
+    OECF => {
+        NAMESPACE => 'exif',
+        Columns     => { },
+        Rows        => { },
+        Names       => { },
+        Values      => { },
+    },
+    CFAPattern => {
+        NAMESPACE => 'exif',
+        Columns     => { },
+        Rows        => { },
+        Values      => { },
+    },
+    DeviceSettings => {
+        NAMESPACE => 'exif',
+        Columns     => { },
+        Rows        => { },
+        Settings    => { },
+    },
+    # Iptc4xmpCore structures
+    ContactInfo => {
+        NAMESPACE => 'Iptc4xmpCore',
+        CiAdrCity   => { },
+        CiAdrCtry   => { },
+        CiAdrExtadr => { },
+        CiAdrPcode  => { },
+        CiAdrRegion => { },
+        CiEmailWork => { },
+        CiTelWork   => { },
+        CiUrlWork   => { },
+    },
+    # Dynamic Media structures
+    BeatSpliceStretch => {
+        NAMESPACE => 'xmpDM',
+        useFileBeatsMarker  => { },
+        riseInDecibel       => { },
+        riseInTimeDuration  => { },
+    },
+    Marker => {
+        NAMESPACE => 'xmpDM',
+        startTime   => { },
+        duration    => { },
+        comment     => { },
+        name        => { },
+        location    => { },
+        target      => { },
+        type        => { },
+    },
+    Media => {
+        NAMESPACE => 'xmpDM',
+        path        => { },
+        track       => { },
+        startTime   => { },
+        duration    => { },
+        managed     => { },
+        webStatement=> { },
+    },
+    ProjectLink => {
+        NAMESPACE => 'xmpDM',
+        type        => { },
+        path        => { },
+    },
+    ResampleStretch => {
+        NAMESPACE => 'xmpDM',
+        quality     => { },
+    },
+    Time => {
+        NAMESPACE => 'xmpDM',
+        value       => { },
+        scale       => { },
+    },
+    Timecode => {
+        NAMESPACE => 'xmpDM',
+        timeValue   => { },
+        timeFormat  => { },
+    },
+    TimeScaleStretch => {
+        NAMESPACE => 'xmpDM',
+        quality     => { },
+        frameSize   => { },
+        frameOverlappingPercentage => { },
+    },
+);
+
+# Lookup to translate our namespace prefixes into URI's.  This list need
+# not be complete, but it must contain an entry for each namespace prefix
+# (NAMESPACE) for writable tags in the XMP tables or the table above
+my %nsURI = (
+    aux       => 'http://ns.adobe.com/exif/1.0/aux/',
+    cc        => 'http://web.resource.org/cc/',
+    crs       => 'http://ns.adobe.com/camera-raw-settings/1.0/',
+    crss      => 'http://ns.adobe.com/camera-raw-saved-settings/1.0/',
+    dc        => 'http://purl.org/dc/elements/1.1/',
+    exif      => 'http://ns.adobe.com/exif/1.0/',
+    iX        => 'http://ns.adobe.com/iX/1.0/',
+    pdf       => 'http://ns.adobe.com/pdf/1.3/',
+    pdfx      => 'http://ns.adobe.com/pdfx/1.3/',
+    photoshop => 'http://ns.adobe.com/photoshop/1.0/',
+    rdf       => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
+    rdfs      => 'http://www.w3.org/2000/01/rdf-schema#',
+    stDim     => 'http://ns.adobe.com/xap/1.0/sType/Dimensions#',
+    stEvt     => 'http://ns.adobe.com/xap/1.0/sType/ResourceEvent#',
+    stFnt     => 'http://ns.adobe.com/xap/1.0/sType/Font#',
+    stJob     => 'http://ns.adobe.com/xap/1.0/sType/Job#',
+    stRef     => 'http://ns.adobe.com/xap/1.0/sType/ResourceRef#',
+    stVer     => 'http://ns.adobe.com/xap/1.0/sType/Version#',
+    tiff      => 'http://ns.adobe.com/tiff/1.0/',
+   'x'        => 'adobe:ns:meta/',
+    xapG      => 'http://ns.adobe.com/xap/1.0/g/',
+    xapGImg   => 'http://ns.adobe.com/xap/1.0/g/img/',
+    xmp       => 'http://ns.adobe.com/xap/1.0/',
+    xmpBJ     => 'http://ns.adobe.com/xap/1.0/bj/',
+    xmpDM     => 'http://ns.adobe.com/xmp/1.0/DynamicMedia/',
+    xmpMM     => 'http://ns.adobe.com/xap/1.0/mm/',
+    xmpRights => 'http://ns.adobe.com/xap/1.0/rights/',
+    xmpTPg    => 'http://ns.adobe.com/xap/1.0/t/pg/',
+    xmpidq    => 'http://ns.adobe.com/xmp/Identifier/qual/1.0/',
+    xmpPLUS   => 'http://ns.adobe.com/xap/1.0/PLUS/',
+    dex       => 'http://ns.optimasc.com/dex/1.0/',
+    mediapro  => 'http://ns.iview-multimedia.com/mediapro/1.0/',
+    Iptc4xmpCore => 'http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/',
+    MicrosoftPhoto => 'http://ns.microsoft.com/photo/1.0',
+    lr        => 'http://ns.adobe.com/lightroom/1.0/',
+    DICOM     => 'http://ns.adobe.com/DICOM/',
+);
+
+my $x_toolkit = "x:xmptk='Image::ExifTool $Image::ExifTool::VERSION'";
+my $rdfDesc = 'rdf:Description';
+#
+# packet/xmp/rdf headers and trailers
+#
+my $pktOpen = "<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'?>\n";
+my $xmlOpen = "<?xml version='1.0' encoding='UTF-8'?>\n";
+my $xmpOpen = "<x:xmpmeta xmlns:x='$nsURI{x}' $x_toolkit>\n";
+my $rdfOpen = "<rdf:RDF xmlns:rdf='$nsURI{rdf}'>\n";
+my $rdfClose = "</rdf:RDF>\n";
+my $xmpClose = "</x:xmpmeta>\n";
+my $pktCloseW =  "<?xpacket end='w'?>"; # writable by default
+my $pktCloseR =  "<?xpacket end='r'?>";
+
+# Update XMP tag tables when this library is loaded:
+# - generate all TagID's (required when writing)
+# - generate PropertyPath for structure elements
+# - add necessary inverse conversion routines
+{
+    my $mainTable = GetTagTable('Image::ExifTool::XMP::Main');
+    GenerateTagIDs($mainTable);
+    my ($mainTag, $ns, $tag);
+    foreach $mainTag (keys %$mainTable) {
+        my $mainInfo = $mainTable->{$mainTag};
+        next unless ref $mainInfo eq 'HASH' and $mainInfo->{SubDirectory};
+        my $table = GetTagTable($mainInfo->{SubDirectory}->{TagTable});
+        $$table{WRITE_PROC} = \&WriteXMP;   # set WRITE_PROC for all tables
+        GenerateTagIDs($table);
+        $table->{CHECK_PROC} = \&CheckXMP;  # add our write check routine
+        foreach $tag (TagTableKeys($table)) {
+            my $tagInfo = $$table{$tag};
+            next unless ref $tagInfo eq 'HASH';
+            # must set PropertyPath now for all tags that are Struct elements
+            # (normal tags will get set later if they are actually written)
+            SetPropertyPath($table, $tag) if $$tagInfo{Struct};
+            my $format = $$tagInfo{Writable};
+            next unless $format and $format eq 'date';
+            # add dummy conversion for dates (for now...)
+            $$tagInfo{PrintConvInv} = '$val' unless $$tagInfo{PrintConvInv};
+            $$tagInfo{ValueConvInv} = '$val' unless $$tagInfo{ValueConvInv};
+        }
+        # add new namespace if NAMESPACE is ns/uri pair
+        next unless ref $$table{NAMESPACE};
+        my $nsRef = $$table{NAMESPACE};
+        # recognize as either a list or hash
+        if (ref $nsRef eq 'ARRAY') {
+            $ns = $$nsRef[0];
+            $nsURI{$ns} = $$nsRef[1];
+        } else { # must be a hash
+            ($ns) = keys %$nsRef;
+            $nsURI{$ns} = $$nsRef{$ns};
+        }
+        $$table{NAMESPACE} = $ns;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Validate XMP packet and set read or read/write mode
+# Inputs: 0) XMP data reference, 1) 'r' = read only, 'w' or undef = read/write
+# Returns: true if XMP is good (and adds packet header/trailer if necessary)
+sub ValidateXMP($;$)
+{
+    my ($xmpPt, $mode) = @_;
+    unless ($$xmpPt =~ /^\0*<\0*\?\0*x\0*p\0*a\0*c\0*k\0*e\0*t/) {
+        return '' unless $$xmpPt =~ /^<x(mp)?:xmpmeta/;
+        # add required xpacket header/trailer
+        $$xmpPt = $pktOpen . $$xmpPt . $pktCloseW;
+    }
+    $mode = 'w' unless $mode;
+    my $end = substr($$xmpPt, -32, 32);
+    # check for proper xpacket trailer and set r/w mode if necessary
+    return '' unless $end =~ s/(e\0*n\0*d\0*=\0*['"]\0*)([rw])(\0*['"]\0*\?\0*>)/$1$mode$3/;
+    substr($$xmpPt, -32, 32) = $end if $2 ne $mode;
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Check XMP values for validity and format accordingly
+# Inputs: 0) ExifTool object reference, 1) tagInfo hash reference,
+#         2) raw value reference
+# Returns: error string or undef (and may change value) on success
+sub CheckXMP($$$)
+{
+    my ($exifTool, $tagInfo, $valPtr) = @_;
+    # convert value from Latin if necessary
+    if ($exifTool->{OPTIONS}->{Charset} eq 'Latin' and $$valPtr =~ /[\x80-\xff]/) {
+        # convert from Latin to UTF-8
+        my $val = Image::ExifTool::Latin2Unicode($$valPtr,'n');
+        $$valPtr = Image::ExifTool::Unicode2UTF8($val,'n');
+    }
+    my $format = $tagInfo->{Writable};
+    # if no format specified, value is a simple string
+    return undef unless $format and $format ne 'string';
+    if ($format eq 'rational' or $format eq 'real') {
+        # make sure the value is a valid floating point number
+        Image::ExifTool::IsFloat($$valPtr) or return 'Not a floating point number';
+        if ($format eq 'rational') {
+            $$valPtr = join('/', Image::ExifTool::Rationalize($$valPtr));
+        }
+    } elsif ($format eq 'integer') {
+        # make sure the value is integer
+        if (Image::ExifTool::IsInt($$valPtr)) {
+            # no conversion required (converting to 'int' would remove leading '+')
+        } elsif (Image::ExifTool::IsHex($$valPtr)) {
+            $$valPtr = hex($$valPtr);
+        } else {
+            return 'Not an integer';
+        }
+    } elsif ($format eq 'date') {
+        if ($$valPtr =~ /(\d{4}):(\d{2}):(\d{2}) (\d{2}:\d{2}(?::\d{2}(?:\.\d*)?)?)(.*)/) {
+            my ($y, $m, $d, $t, $tz) = ($1, $2, $3, $4, $5);
+            # use 'Z' for timezone unless otherwise specified
+            $tz = 'Z' unless $tz and $tz =~ /([+-]\d{2}:\d{2})/;
+            $$valPtr = "$y-$m-${d}T$t$tz";
+        } elsif ($$valPtr =~ /^\s*\d{4}(:\d{2}){0,2}\s*$/) {
+            # this is just a date (YYYY, YYYY-MM or YYYY-MM-DD)
+            $$valPtr =~ tr/:/-/;
+        } elsif ($$valPtr =~ /^\s*(\d{2}:\d{2}:\d{2})(.*)\s*$/) {
+            # this is just a time
+            my ($t, $tz) = ($1, $2);
+            $tz = 'Z' unless $tz and $tz =~ /([+-]\d{2}:\d{2})/;
+            $$valPtr = "$t$tz";
+        } else {
+            return "Invalid date or time format (should be YYYY:MM:DD HH:MM:SS[+/-HH:MM])";
+        }
+    } elsif ($format eq 'lang-alt') {
+        # nothing to do
+    } elsif ($format eq 'boolean') {
+        if (not $$valPtr or $$valPtr =~ /false/i or $$valPtr =~ /^no$/i) {
+            $$valPtr = 'False';
+        } else {
+            $$valPtr = 'True';
+        }
+    } elsif ($format eq '1') {
+        # this is the entire XMP data block
+        return 'Invalid XMP data' unless ValidateXMP($valPtr);
+    } else {
+        return "Unknown XMP format: $format";
+    }
+    return undef;   # success!
+}
+
+#------------------------------------------------------------------------------
+# Get PropertyPath for specified tagInfo
+# Inputs: 0) tagInfo reference
+# Returns: PropertyPath string
+sub GetPropertyPath($)
+{
+    my $tagInfo = shift;
+    unless ($$tagInfo{PropertyPath}) {
+        SetPropertyPath($$tagInfo{Table}, $$tagInfo{TagID});
+    }
+    return $$tagInfo{PropertyPath};
+}
+
+#------------------------------------------------------------------------------
+# Set PropertyPath for specified tag (also for any structure elements)
+# Inputs: 0) tagTable reference, 1) tagID, 2) structure reference (or undef),
+#         3) property list up to this point (or undef), 4) true if tag is a list
+sub SetPropertyPath($$;$$)
+{
+    my ($tagTablePtr, $tagID, $structPtr, $propList) = @_;
+    my $table = $structPtr || $tagTablePtr;
+    my $tagInfo = $$table{$tagID};
+    my $ns = $$table{NAMESPACE};
+    # don't override existing main table entry if already set by a Struct
+    return if not $structPtr and $$tagInfo{PropertyPath};
+    $ns or warn("No namespace for $tagID\n"), return;
+    my (@propList, $listType);
+    $propList and @propList = @$propList;
+    push @propList, "$ns:$tagID";
+    # lang-alt lists are handled specially, signified by Writable='lang-alt'
+    if ($$tagInfo{Writable} and $$tagInfo{Writable} eq 'lang-alt') {
+        $listType = 'Alt';
+        # remove language code from property path if it exists
+        $propList[-1] =~ s/-$$tagInfo{LangCode}$// if $$tagInfo{LangCode};
+    } else {
+        $listType = $$tagInfo{List};
+    }
+    # add required properties if this is a list
+    push @propList, "rdf:$listType", 'rdf:li 000' if $listType and $listType ne '1';
+    # set PropertyPath for all elements of this structure if necessary
+    if ($$tagInfo{Struct}) {
+        my $struct = $xmpStruct{$$tagInfo{Struct}};
+        $struct or warn("No XMP $$tagInfo{Struct} structure!\n"), return;
+        my $tag;
+        foreach $tag (keys %$struct) {
+            next if $tag eq 'NAMESPACE';
+            SetPropertyPath($tagTablePtr, $tag, $struct, \@propList);
+        }
+    }
+    # use tagInfo for combined tag name if this was a Struct
+    if ($structPtr) {
+        my $tagName = GetXMPTagID(\@propList);
+        $$tagTablePtr{$tagName} or warn("Tag $tagName not found!\n"), return;
+        $tagInfo = $$tagTablePtr{$tagName};
+        # must check again for List's at this level
+        if ($$tagInfo{Writable} and $$tagInfo{Writable} eq 'lang-alt') {
+            $listType = 'Alt';
+        } else {
+            $listType = $$tagInfo{List};
+        }
+        push @propList, "rdf:$listType", 'rdf:li 000' if $listType and $listType ne '1';
+    }
+    # set property path for tagInfo in main table
+    $$tagInfo{PropertyPath} = join '/', @propList;
+}
+
+#------------------------------------------------------------------------------
+# Save XMP property name/value for rewriting
+# Inputs: 0) ExifTool object reference
+#         1) reference to array of XMP property path (last is current property)
+#         2) property value, 3) optional reference to hash of property attributes
+sub CaptureXMP($$$;$)
+{
+    my ($exifTool, $propList, $val, $attrs) = @_;
+    return unless defined $val and @$propList > 2;
+    if ($$propList[0] =~ /^x:x(a|m)pmeta$/ and
+        $$propList[1] eq 'rdf:RDF' and
+        $$propList[2] =~ /$rdfDesc( |$)/)
+    {
+        # no properties to save yet if this is just the description
+        return unless @$propList > 3;
+        # save information about this property
+        my $capture = $exifTool->{XMP_CAPTURE};
+        my $path = join('/', @$propList[3..$#$propList]);
+        if (defined $$capture{$path}) {
+            $exifTool->{XMP_ERROR} = "Duplicate XMP property: $path";
+        } else {
+            $$capture{$path} = [$val, $attrs || { }];
+        }
+    } else {
+        $exifTool->{XMP_ERROR} = 'Improperly enclosed XMP property: ' . join('/',@$propList);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Save information about resource containing blank node with nodeID
+# Inputs: 0) reference to blank node information hash
+#         1) reference to property list
+#         2) property value
+#         3) [optional] reference to attribute hash
+# Notes: This routine and ProcessBlankInfo() are also used for reading information, but
+#        are uncommon so are put in this file to reduce compile time for the common case
+sub SaveBlankInfo($$$;$)
+{
+    my ($blankInfo, $propListPt, $val, $attrs) = @_;
+
+    my $propPath = join '/', @$propListPt;
+    my @ids = ($propPath =~ m{ #([^ /]*)}g);
+    my $id;
+    # split the property path at each nodeID
+    foreach $id (@ids) {
+        my ($pre, $prop, $post) = ($propPath =~ m{^(.*?)/([^/]*) #$id((/.*)?)$});
+        defined $pre or warn("internal error parsing nodeID's"), next;
+        # the element with the nodeID should be in the path prefix for subject
+        # nodes and the path suffix for object nodes
+        unless ($prop eq $rdfDesc) {
+            if ($post) {
+                $post = "/$prop$post";
+            } else {
+                $pre = "$pre/$prop";
+            }
+        }
+        $blankInfo->{Prop}->{$id}->{Pre}->{$pre} = 1;
+        if ((defined $post and length $post) or (defined $val and length $val)) {
+            # save the property value and attributes for each unique path suffix
+            $blankInfo->{Prop}->{$id}->{Post}->{$post} = [ $val, $attrs, $propPath ];
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# Process blank-node information
+# Inputs: 0) ExifTool object ref, 1) tag table ref,
+#         2) blank node information hash ref, 3) flag set for writing
+sub ProcessBlankInfo($$$;$)
+{
+    my ($exifTool, $tagTablePtr, $blankInfo, $isWriting) = @_;
+    $exifTool->VPrint(1, "  [Elements with nodeID set:]\n") unless $isWriting;
+    my ($id, $pre, $post);
+    # handle each nodeID separately
+    foreach $id (sort keys %{$$blankInfo{Prop}}) {
+        my $path = $blankInfo->{Prop}->{$id};
+        # flag all resource names so we can warn later if some are unused
+        my %unused;
+        foreach $post (keys %{$path->{Post}}) {
+            $unused{$post} = 1;
+        }
+        # combine property paths for all possible paths through this node
+        foreach $pre (sort keys %{$path->{Pre}}) {
+            # there will be no description for the object of a blank node
+            next unless $pre =~ m{/$rdfDesc/};
+            foreach $post (sort keys %{$path->{Post}}) {
+                my @propList = split m{/}, "$pre$post";
+                my ($val, $attrs) = @{$path->{Post}->{$post}};
+                if ($isWriting) {
+                    CaptureXMP($exifTool, \@propList, $val, $attrs);
+                } else {
+                    FoundXMP($exifTool, $tagTablePtr, \@propList, $val);
+                }
+                delete $unused{$post};
+            }
+        }
+        # save information from unused properties (if RDF is malformed like f-spot output)
+        if (%unused) {
+            $exifTool->Options('Verbose') and $exifTool->Warn('An XMP resource is about nothing');
+            foreach $post (sort keys %unused) {
+                my ($val, $attrs, $propPath) = @{$path->{Post}->{$post}};
+                my @propList = split m{/}, $propPath;
+                if ($isWriting) {
+                    CaptureXMP($exifTool, \@propList, $val, $attrs);
+                } else {
+                    FoundXMP($exifTool, $tagTablePtr, \@propList, $val);
+                }
+            }
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# Convert path to namespace used in file (this is a pain, but the XMP
+# spec only suggests 'preferred' namespace prefixes...)
+# Inputs: 0) ExifTool object reference, 1) property path
+# Returns: conforming property path
+sub ConformPathToNamespace($$)
+{
+    my ($exifTool, $path) = @_;
+    my @propList = split('/',$path);
+    my ($prop, $newKey);
+    my $nsUsed = $exifTool->{XMP_NS};
+    foreach $prop (@propList) {
+        my ($ns, $tag) = $prop =~ /(.+?):(.*)/;
+        next if $$nsUsed{$ns};
+        my $uri = $nsURI{$ns};
+        unless ($uri) {
+            warn "No URI for namepace prefix $ns!\n";
+            next;
+        }
+        my $ns2;
+        foreach $ns2 (keys %$nsUsed) {
+            next unless $$nsUsed{$ns2} eq $uri;
+            # use the existing namespace prefix instead of ours
+            $prop = "$ns2:$tag";
+            last;
+        }
+    }
+    return join('/',@propList);
+}
+
+#------------------------------------------------------------------------------
+# sort tagInfo hash references by tag name
+sub ByTagName
+{
+    return $$a{Name} cmp $$b{Name};
+}
+
+#------------------------------------------------------------------------------
+# Write XMP information
+# Inputs: 0) ExifTool object reference, 1) source dirInfo reference,
+#         2) [optional] tag table reference
+# Returns: with tag table: new XMP data (may be empty if no XMP data) or undef on error
+#          without tag table: 1 on success, 0 if not valid XMP file, -1 on write error
+# Notes: May set dirInfo InPlace flag to rewrite with specified DirLen
+#        May set dirInfo ReadOnly flag to write as read-only XMP ('r' mode and no padding)
+sub WriteXMP($$;$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    $exifTool or return 1;    # allow dummy access to autoload this package
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my (%capture, %nsUsed, $xmpErr, $uuid);
+    my $changed = 0;
+    my $xmpFile = (not $tagTablePtr);   # this is an XMP data file if no $tagTablePtr
+    my $preferred = $xmpFile;   # write XMP as preferred if this is an XMP file
+    my $verbose = $exifTool->Options('Verbose');
+#
+# extract existing XMP information into %capture hash
+#
+    # define hash in ExifTool object to capture XMP information (also causes
+    # CaptureXMP() instead of FoundXMP() to be called from ParseXMPElement())
+    #
+    # The %capture hash is keyed on the complete property path beginning after
+    # rdf:RDF/rdf:Description/.  The values are array references with the
+    # following entries: 0) value, 1) attribute hash reference.
+    $exifTool->{XMP_CAPTURE} = \%capture;
+    $exifTool->{XMP_NS} = \%nsUsed;
+
+    if ($dataPt or $xmpFile) {
+        delete $exifTool->{XMP_ERROR};
+        delete $exifTool->{XMP_UUID};
+        # extract all existing XMP information (to the XMP_CAPTURE hash)
+        my $success = ProcessXMP($exifTool, $dirInfo, $tagTablePtr);
+        # don't continue if there is nothing to parse or if we had a parsing error
+        unless ($success and not $exifTool->{XMP_ERROR}) {
+            my $err = $exifTool->{XMP_ERROR} || 'Error parsing XMP';
+            # may ignore this error only if we were successful
+            if ($xmpFile) {
+                my $raf = $$dirInfo{RAF};
+                # allow empty XMP data so we can create something from nothing
+                if ($success or not $raf->Seek(0,2) or $raf->Tell()) {
+                    # no error message if not an XMP file
+                    return 0 unless $exifTool->{XMP_ERROR};
+                    if ($exifTool->Error($err, $success)) {
+                        delete $exifTool->{XMP_CAPTURE};
+                        return 0;
+                    }
+                }
+            } else {
+                if ($exifTool->Warn($err, $success)) {
+                    delete $exifTool->{XMP_CAPTURE};
+                    return undef;
+                }
+            }
+        }
+        $uuid = $exifTool->{XMP_UUID} || '';
+        delete $exifTool->{XMP_ERROR};
+        delete $exifTool->{XMP_UUID};
+    } else {
+        $uuid = '';
+    }
+#
+# add, delete or change information as specified
+#
+    # get hash of all information we want to change
+    # (sorted by tag name so alternate languages come last)
+    my @tagInfoList = sort ByTagName $exifTool->GetNewTagInfoList();
+    my $tagInfo;
+    foreach $tagInfo (@tagInfoList) {
+        next unless $exifTool->GetGroup($tagInfo, 0) eq 'XMP';
+        my $tag = $tagInfo->{TagID};
+        my $path = GetPropertyPath($tagInfo);
+        unless ($path) {
+            $exifTool->Warn("Can't write XMP:$tag (namespace unknown)");
+            next;
+        }
+        # change our property path namespace prefixes to conform
+        # to the ones used in this file
+        $path = ConformPathToNamespace($exifTool, $path);
+        # find existing property
+        my $capList = $capture{$path};
+        # MicrosoftPhoto screws up the case of some tags, so test for this
+        unless ($capList) {
+            my ($path2) = grep /^\Q$path\E$/i, keys %capture;
+            $path2 and $capList = $capture{$path = $path2};
+        }
+        my $newValueHash = $exifTool->GetNewValueHash($tagInfo);
+        my $overwrite = Image::ExifTool::IsOverwriting($newValueHash);
+        my $writable = $$tagInfo{Writable} || '';
+        my (%attrs, $deleted, $added);
+        # delete existing entry if necessary
+        if ($capList) {
+            # take attributes from old values if they exist
+            %attrs = %{$capList->[1]};
+            if ($overwrite) {
+                my ($delPath, @matchingPaths, $oldLang, $delLang);
+                # check to see if this is an indexed list item
+                if ($path =~ / /) {
+                    my $pathPattern;
+                    ($pathPattern = $path) =~ s/ 000/ \\d\{3\}/g;
+                    @matchingPaths = sort grep(/^$pathPattern$/, keys %capture);
+                } else {
+                    push @matchingPaths, $path;
+                }
+                foreach $path (@matchingPaths) {
+                    my ($val, $attrs) = @{$capture{$path}};
+                    if ($overwrite < 0) {
+                        # only overwrite specific values
+                        next unless Image::ExifTool::IsOverwriting($newValueHash, $val);
+                    }
+                    if ($writable eq 'lang-alt') {
+                        # get original language code (lc for comparisons)
+                        $oldLang = lc($$attrs{'xml:lang'} || 'x-default');
+                        # delete all if deleting "x-default" or writing with no LangCode
+                        # (XMP spec requires x-default language exist and be first in list)
+                        if ($oldLang eq 'x-default' and not ($newValueHash->{Value} or
+                            ($$tagInfo{LangCode} and $$tagInfo{LangCode} ne 'x-default')))
+                        {
+                            $delLang = 1;   # delete all languages
+                            $overwrite = 1; # force overwrite
+                        }
+                        if ($$tagInfo{LangCode} and not $delLang) {
+                            # only overwrite specified language
+                            next unless lc($$tagInfo{LangCode}) eq $oldLang;
+                        }
+                    }
+                    if ($verbose > 1) {
+                        my $grp = $exifTool->GetGroup($tagInfo, 1);
+                        my $tagName = $$tagInfo{Name};
+                        $tagName =~ s/-$$tagInfo{LangCode}$// if $$tagInfo{LangCode};
+                        $tagName .= '-' . $$attrs{'xml:lang'} if $$attrs{'xml:lang'};
+                        $exifTool->VPrint(1, "    - $grp:$tagName = '$val'\n");
+                    }
+                    # save attributes and path from first deleted property
+                    # so we can replace it exactly
+                    unless ($delPath) {
+                        %attrs = %$attrs;
+                        $delPath = $path;
+                    }
+                    delete $capture{$path};
+                    ++$changed;
+                }
+                next unless $delPath or $$tagInfo{List} or $oldLang;
+                if ($delPath) {
+                    $path = $delPath;
+                    $deleted = 1;
+                } else {
+                    # don't change tag if we couldn't delete old copy
+                    # unless this is a list or an lang-alt tag
+                    next unless $$tagInfo{List} or $oldLang;
+                    $path =~ m/ (\d{3})/g or warn "Internal error: no list index!\n", next;
+                    $added = $1;
+                }
+            } elsif ($path =~ m/ (\d{3})/g) {
+                $added = $1;
+            }
+            if (defined $added) {
+                # add to end of list
+                my $pos = pos($path) - 3;
+                for (;;) {
+                    substr($path, $pos, 3) = ++$added;
+                    last unless $capture{$path};
+                }
+            }
+        }
+        # check to see if we want to create this tag
+        # (create non-avoided tags in XMP data files by default)
+        my $isCreating = (Image::ExifTool::IsCreating($newValueHash) or
+                          ($preferred and not $$tagInfo{Avoid} and
+                            not defined $$newValueHash{Shift}));
+
+        # don't add new values unless...
+            # ...tag existed before and was deleted, or we added it to a list
+        next unless $deleted or defined $added or
+            # ...tag didn't exist before and we are creating it
+            (not $capList and $isCreating);
+
+        # get list of new values (all done if no new values specified)
+        my @newValues = Image::ExifTool::GetNewValues($newValueHash) or next;
+
+        # set language attribute for lang-alt lists
+        if ($writable eq 'lang-alt') {
+            $attrs{'xml:lang'} = $$tagInfo{LangCode} || 'x-default';
+            # must generate x-default entry as first entry if it didn't exist
+            unless ($capList or lc($attrs{'xml:lang'}) eq 'x-default') {
+                my $newValue = EscapeXML($newValues[0]);
+                $capture{$path} = [ $newValue, { %attrs, 'xml:lang' => 'x-default' } ];
+                if ($verbose > 1) {
+                    my $tagName = $$tagInfo{Name};
+                    $tagName =~ s/-$$tagInfo{LangCode}$/-x-default/;
+                    my $grp = $exifTool->GetGroup($tagInfo, 1);
+                    $exifTool->VPrint(1, "    + $grp:$tagName = '$newValue'\n");
+                }
+                $path =~ s/ 000/ 001/ or warn "Internal error: no list index!\n", next;
+            }
+        }
+        
+        # add new value(s) to %capture hash
+        for (;;) {
+            my $newValue = EscapeXML(shift @newValues);
+            $capture{$path} = [ $newValue, \%attrs ];
+            if ($verbose > 1) {
+                my $grp = $exifTool->GetGroup($tagInfo, 1);
+                $exifTool->VPrint(1, "    + $grp:$$tagInfo{Name} = '$newValue'\n");
+            }
+            ++$changed;
+            last unless @newValues;
+            $path =~ m/ (\d{3})/g or warn("Internal error: no list index!\n"), next;
+            my $listIndex = $1;
+            my $pos = pos($path) - 3;
+            for (;;) {
+                substr($path, $pos, 3) = ++$listIndex;
+                last unless $capture{$path};
+            }
+            $capture{$path} and warn("Too many entries in XMP list!\n"), next;
+        }
+    }
+    # remove the ExifTool members we created
+    delete $exifTool->{XMP_CAPTURE};
+    delete $exifTool->{XMP_NS};
+
+    # return now if we didn't change anything
+    unless ($changed) {
+        return undef unless $xmpFile;   # just rewrite original XMP
+        # get DataPt again because it may have been set by ProcessXMP
+        $dataPt = $$dirInfo{DataPt};
+        unless (defined $dataPt) {
+            $exifTool->Error("Nothing to write");
+            return 1;
+        }
+        return 1 if Write($$dirInfo{OutFile}, $$dataPt);
+        return -1;
+    }
+#
+# write out the new XMP information
+#
+    # start writing the XMP data
+    my $newData = '';
+    if ($$exifTool{XMP_NO_XPACKET}) {
+        # write BOM if flag is set
+        $newData .= "\xef\xbb\xbf" if $$exifTool{XMP_NO_XPACKET} == 2;
+    } else {
+        $newData .= $pktOpen;
+    }
+    $newData .= $xmlOpen if $$exifTool{XMP_IS_XML};
+    $newData .= $xmpOpen . $rdfOpen;
+
+    # initialize current property path list
+    my @curPropList;
+    my (%nsCur, $prop, $n);
+    my @pathList = sort keys %capture;
+
+    while (@pathList) {
+        my $path = shift @pathList;
+        my @propList = split('/',$path); # get property list
+        # must open/close rdf:Description too
+        unshift @propList, $rdfDesc;
+        # make sure we have defined all necessary namespaces
+        my (%nsNew, $newDesc);
+        foreach $prop (@propList) {
+            $prop =~ /(.*):/ or next;
+            $1 eq 'rdf' and next;   # rdf namespace already defined
+            my $nsNew = $nsUsed{$1};
+            unless ($nsNew) {
+                $nsNew = $nsURI{$1}; # we must have added a namespace
+                unless ($nsNew) {
+                    $xmpErr = "Undefined XMP namespace: $1";
+                    next;
+                }
+            }
+            $nsNew{$1} = $nsNew;
+            # need a new description if any new namespaces
+            $newDesc = 1 unless $nsCur{$1};
+        }
+        my $closeTo = 0;
+        if ($newDesc) {
+            # look forward to see if we will want to also open other namespaces
+            # (this is necessary to keep lists from being broken if a property
+            #  introduces a new namespace; plus it improves formatting)
+            my ($path2, $ns2);
+            foreach $path2 (@pathList) {
+                my @ns2s = ($path2 =~ m{(?:^|/)([^/]+?):}g);
+                my $opening = 0;
+                foreach $ns2 (@ns2s) {
+                    next if $ns2 eq 'rdf';
+                    $nsNew{$ns2} and ++$opening, next;
+                    last unless $opening and $nsURI{$ns2};
+                    # also open this namespace
+                    $nsNew{$ns2} = $nsURI{$ns2};
+                }
+                last unless $opening;
+            }
+        } else {
+            # find first property where the current path differs from the new path
+            for ($closeTo=0; $closeTo<@curPropList; ++$closeTo) {
+                last unless $closeTo < @propList;
+                last unless $propList[$closeTo] eq $curPropList[$closeTo];
+            }
+        }
+        # close out properties down to the common base path
+        while (@curPropList > $closeTo) {
+            ($prop = pop @curPropList) =~ s/ .*//;
+            $newData .= (' ' x scalar(@curPropList)) . " </$prop>\n";
+        }
+        if ($newDesc) {
+            # open the new description
+            $prop = $rdfDesc;
+            %nsCur = %nsNew;            # save current namespaces
+            $newData .= "\n <$prop rdf:about='$uuid'";
+            foreach (sort keys %nsCur) {
+                $newData .= "\n  xmlns:$_='$nsCur{$_}'";
+            }
+            $newData .= ">\n";
+            push @curPropList, $prop;
+        }
+        # loop over all values for this new property
+        my $capList = $capture{$path};
+        my ($val, $attrs) = @$capList;
+        $debug and print "$path = $val\n";
+        # open new properties
+        my $attr;
+        for ($n=@curPropList; $n<$#propList; ++$n) {
+            $prop = $propList[$n];
+            push @curPropList, $prop;
+            # remove list index if it exists
+            $prop =~ s/ .*//;
+            $attr = '';
+            if ($prop ne $rdfDesc and $propList[$n+1] !~ /^rdf:/) {
+                # need parseType='Resource' to avoid new 'rdf:Description'
+                $attr = " rdf:parseType='Resource'";
+            }
+            $newData .= (' ' x scalar(@curPropList)) . "<$prop$attr>\n";
+        }
+        my $prop2 = pop @propList;   # get new property name
+        $prop2 =~ s/ .*//;  # remove list index if it exists
+        $newData .= (' ' x scalar(@curPropList)) . " <$prop2";
+        # print out attributes
+        foreach $attr (sort keys %$attrs) {
+            my $attrVal = $$attrs{$attr};
+            my $quot = ($attrVal =~ /'/) ? '"' : "'";
+            $newData .= " $attr=$quot$attrVal$quot";
+        }
+        $newData .= ">$val</$prop2>\n";
+    }
+    # close off any open elements
+    while ($prop = pop @curPropList) {
+        $prop =~ s/ .*//;   # remove list index if it exists
+        $newData .= (' ' x scalar(@curPropList)) . " </$prop>\n";
+    }
+#
+# clean up, close out the XMP, and return our data
+#
+    # remove the ExifTool members we created
+    delete $exifTool->{XMP_CAPTURE};
+    delete $exifTool->{XMP_NS};
+
+    $newData .= $rdfClose . $xmpClose;
+
+    # (the XMP standard recommends writing 2k-4k of white space before the
+    # packet trailer, with a newline every 100 characters)
+    unless ($$exifTool{XMP_NO_XPACKET}) {
+        my $pad = (' ' x 100) . "\n";
+        if ($$dirInfo{InPlace}) {
+            # pad to specified DirLen
+            my $dirLen = $$dirInfo{DirLen} || length $$dataPt;
+            my $len = length($newData) + length($pktCloseW);
+            if ($len > $dirLen) {
+                $exifTool->Warn('Not enough room to edit XMP in place');
+                return undef;
+            }
+            my $num = int(($dirLen - $len) / length($pad));
+            if ($num) {
+                $newData .= $pad x $num;
+                $len += length($pad) * $num;
+            }
+            $len < $dirLen and $newData .= (' ' x ($dirLen - $len - 1)) . "\n";
+        } elsif (not $exifTool->Options('Compact') and
+                 not $xmpFile and not $$dirInfo{ReadOnly})
+        {
+            $newData .= $pad x 24;
+        }
+        $newData .= ($$dirInfo{ReadOnly} ? $pktCloseR : $pktCloseW);
+    }
+    # return empty data if no properties exist
+    $newData = '' unless %capture or $$dirInfo{InPlace};
+
+    if ($xmpErr) {
+        if ($xmpFile) {
+            $exifTool->Error($xmpErr);
+            return -1;
+        }
+        $exifTool->Warn($xmpErr);
+        return undef;
+    }
+    $exifTool->{CHANGED} += $changed;
+    $debug > 1 and $newData and print $newData,"\n";
+    return $newData unless $xmpFile;
+    return 1 if Write($$dirInfo{OutFile}, $newData);
+    return -1;
+}
+
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::WriteXMP.pl - Write XMP meta information
+
+=head1 SYNOPSIS
+
+These routines are autoloaded by Image::ExifTool::XMP.
+
+=head1 DESCRIPTION
+
+This file contains routines to write XMP metadata.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::XMP(3pm)|Image::ExifTool::XMP>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/Writer.pl
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/Writer.pl	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/Writer.pl	(revision 20131)
@@ -0,0 +1,4506 @@
+#------------------------------------------------------------------------------
+# File:         Writer.pl
+#
+# Description:  ExifTool write routines
+#
+# Notes:        Also contains some less used ExifTool functions
+#
+# URL:          http://owl.phy.queensu.ca/~phil/exiftool/
+#
+# Revisions:    12/16/2004 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool;
+
+use strict;
+
+use Image::ExifTool::TagLookup qw(FindTagInfo TagExists);
+use Image::ExifTool::Fixup;
+
+sub AssembleRational($$@);
+sub LastInList($);
+sub CreateDirectory($);
+sub RemoveNewValueHash($$$);
+sub RemoveNewValuesForGroup($$);
+
+my $loadedAllTables;    # flag indicating we loaded all tables
+
+# the following is a road map of where we write each directory
+# in the different types of files.
+my %tiffMap = (
+    IFD0         => 'TIFF',
+    IFD1         => 'IFD0',
+    XMP          => 'IFD0',
+    ICC_Profile  => 'IFD0',
+    ExifIFD      => 'IFD0',
+    GPS          => 'IFD0',
+    SubIFD       => 'IFD0',
+    GlobParamIFD => 'IFD0',
+    PrintIM      => 'IFD0',
+    IPTC         => 'IFD0',
+    Photoshop    => 'IFD0',
+    InteropIFD   => 'ExifIFD',
+    MakerNotes   => 'ExifIFD',
+);
+my %jpegMap = (
+    JFIF         => 'APP0',
+    CIFF         => 'APP0',
+    IFD0         => 'APP1',
+    XMP          => 'APP1',
+    ICC_Profile  => 'APP2',
+    FlashPix     => 'APP2',
+    Meta         => 'APP3',
+    MetaIFD      => 'Meta',
+    RMETA        => 'APP5',
+    Ducky        => 'APP12',
+    Photoshop    => 'APP13',
+    IFD1         => 'IFD0',
+    EXIF         => 'IFD0', # to write EXIF as a block
+    ExifIFD      => 'IFD0',
+    GPS          => 'IFD0',
+    SubIFD       => 'IFD0',
+    GlobParamIFD => 'IFD0',
+    PrintIM      => 'IFD0',
+    IPTC         => 'Photoshop',
+    InteropIFD   => 'ExifIFD',
+    MakerNotes   => ['ExifIFD', 'CIFF'], # (first parent is the default)
+    Comment      => 'COM',
+);
+my %dirMap = (
+    JPEG => \%jpegMap,
+    TIFF => \%tiffMap,
+    ORF  => \%tiffMap,
+    RAW  => \%tiffMap,
+);
+
+# groups we are allowed to delete
+# Notes:
+# 1) these names must either exist in %dirMap, or be translated in InitWriteDirs())
+# 2) any dependencies must be added to %excludeGroups
+my @delGroups = qw(
+    AFCP CanonVRD CIFF Ducky EXIF ExifIFD File FlashPix FotoStation GlobParamIFD
+    GPS ICC_Profile IFD0 IFD1 InteropIFD IPTC JFIF MakerNotes Meta MetaIFD MIE
+    PhotoMechanic Photoshop PNG PrintIM RMETA SubIFD Trailer XMP
+);
+# other group names of new tag values to remove when deleting an entire group
+my %removeGroups = (
+    IFD0    => [ 'EXIF', 'MakerNotes' ],
+    EXIF    => [ 'MakerNotes' ],
+    ExifIFD => [ 'MakerNotes', 'InteropIFD' ],
+    Trailer => [ 'CanonVRD' ], #(because we can add back CanonVRD as a block)
+);
+# related family 0/1 groups in @delGroups (and not already in %jpegMap)
+# that must be removed from delete list when excluding a group
+my %excludeGroups = (
+    EXIF         => [ qw(IFD0 IFD1 ExifIFD GPS MakerNotes GlobParamIFD InteropIFD PrintIM SubIFD) ],
+    IFD0         => [ 'EXIF' ],
+    IFD1         => [ 'EXIF' ],
+    ExifIFD      => [ 'EXIF' ],
+    GPS          => [ 'EXIF' ],
+    MakerNotes   => [ 'EXIF' ],
+    InteropIFD   => [ 'EXIF' ],
+    GlobParamIFD => [ 'EXIF' ],
+    PrintIM      => [ 'EXIF' ],
+    CIFF         => [ 'MakerNotes' ],
+    # technically correct, but very uncommon and not a good reason to avoid deleting trailer
+  # IPTC         => [ qw(AFCP FotoStation Trailer) ],
+    AFCP         => [ 'Trailer' ],
+    FotoStation  => [ 'Trailer' ],
+    CanonVRD     => [ 'Trailer' ],
+    PhotoMechanic=> [ 'Trailer' ],
+    MIE          => [ 'Trailer' ],
+);
+# group names to translate for writing
+my %translateWriteGroup = (
+    EXIF => 'ExifIFD',
+    File => 'Comment',
+    MIE  => 'MIE',
+);
+# names of valid EXIF directories:
+my %exifDirs = (
+    gps          => 'GPS',
+    exififd      => 'ExifIFD',
+    subifd       => 'SubIFD',
+    globparamifd => 'GlobParamIFD',
+    interopifd   => 'InteropIFD',
+    makernotes   => 'MakerNotes',
+);
+# min/max values for integer formats
+my %intRange = (
+    'int8u'  => [0, 0xff],
+    'int8s'  => [-0x80, 0x7f],
+    'int16u' => [0, 0xffff],
+    'int16s' => [-0x8000, 0x7fff],
+    'int32u' => [0, 0xffffffff],
+    'int32s' => [-0x80000000, 0x7fffffff],
+);
+my $maxSegmentLen = 0xfffd; # maximum length of data in a JPEG segment
+
+# value separators when conversion list is used (in SetNewValue)
+my %listSep = ( PrintConv => '; ?', ValueConv => ' ' );
+
+#------------------------------------------------------------------------------
+# Set tag value
+# Inputs: 0) ExifTool object reference
+#         1) tag key, tag name, or '*' (optionally prefixed by group name),
+#            or undef to reset all previous SetNewValue() calls
+#         2) new value (scalar, scalar ref or list ref), or undef to delete tag
+#         3-N) Options:
+#           Type => PrintConv, ValueConv or Raw - specifies value type
+#           AddValue => true to add to list of existing values instead of overwriting
+#           DelValue => true to delete this existing value value from a list
+#           Group => family 0 or 1 group name (case insensitive)
+#           Replace => 0, 1 or 2 - overwrite previous new values (2=reset)
+#           Protected => bitmask to write tags with specified protections
+#           Shift => undef, 0, +1 or -1 - shift value if possible
+#           NoShortcut => true to prevent looking up shortcut tags
+#           CreateGroups => [internal use] createGroups hash ref from related tags
+# Returns: number of tags set (plus error string in list context)
+# Notes: For tag lists (like Keywords), call repeatedly with the same tag name for
+#        each value in the list.  Internally, the new information is stored in
+#        the following members of the $self->{NEW_VALUE}->{$tagInfo} hash:
+#           TagInfo - tag info ref
+#           DelValue - list ref for values to delete
+#           Value - list ref for values to add
+#           IsCreating - must be set for the tag to be added.  otherwise just
+#                        changed if it already exists
+#           CreateGroups - hash of all family 0 group names where tag may be created
+#           WriteGroup - group name where information is being written (correct case)
+#           WantGroup - group name as specified in call to function (case insensitive)
+#           Next - pointer to next newValueHash (if more than one)
+#           Self - ExifTool object reference
+#           Shift - shift value
+#           MAKER_NOTE_FIXUP - pointer to fixup if necessary for a maker note value
+sub SetNewValue($;$$%)
+{
+    local $_;
+    my ($self, $tag, $value, %options) = @_;
+    my ($err, $tagInfo);
+    my $verbose = $self->Options('Verbose');
+    my $out = $self->Options('TextOut');
+    my $protected = $options{Protected} || 0;
+    my $numSet = 0;
+    unless (defined $tag) {
+        # remove any existing set values
+        delete $self->{NEW_VALUE};
+        $self->{DEL_GROUP} = { };
+        $verbose > 1 and print $out "Cleared new values\n";
+        return 1;
+    }
+    # allow value to be scalar or list reference
+    if (ref $value) {
+        if (ref $value eq 'ARRAY') {
+            foreach (@$value) {
+                my ($n, $e) = SetNewValue($self, $tag, $_, %options);
+                $err = $e if $e;
+                $numSet += $n;
+                delete $options{Replace}; # don't replace earlier values in list
+            }
+ReturnNow:  return ($numSet, $err) if wantarray;
+            $err and warn "$err\n";
+            return $numSet;
+        } elsif (ref $value eq 'SCALAR') {
+            $value = $$value;
+        }
+    }
+    # make sure the Perl UTF-8 flag is OFF for the value if perl 5.6 or greater
+    # (otherwise our byte manipulations get corrupted!!)
+    if ($] >= 5.006 and defined $value) {
+        if (eval 'require Encode; Encode::is_utf8($value)' or $@) {
+            $value = pack('C*', unpack('C*', $value));
+        }
+    }
+    # set group name in options if specified
+    if ($tag =~ /(.+?):(.+)/) {
+        $options{Group} = $1 if $1 ne '*' and lc($1) ne 'all';
+        $tag = $2;
+    }
+    # ignore leading family number if 0 or 1 specified
+    if ($options{Group} and $options{Group} =~ /^(\d+)(.*)/ and $1 < 2) {
+        $options{Group} = $2;
+    }
+#
+# get list of tags we want to set
+#
+    my $wantGroup = $options{Group};
+    $tag =~ s/ .*//;    # convert from tag key to tag name if necessary
+    my @matchingTags = FindTagInfo($tag);
+    until (@matchingTags) {
+        if ($tag eq '*' or lc($tag) eq 'all') {
+            # set groups to delete
+            if (defined $value) {
+                $err = "Can't set value for all tags";
+            } else {
+                my (@del, $grp);
+                my $remove = ($options{Replace} and $options{Replace} > 1);
+                if ($wantGroup) {
+                    @del = grep /^$wantGroup$/i, @delGroups;
+                    # remove associated groups when excluding from mass delete
+                    if (@del and $remove) {
+                        # remove associated groups in other family
+                        push @del, @{$excludeGroups{$del[0]}} if $excludeGroups{$del[0]};
+                        # remove upstream groups according to JPEG map
+                        my $dirName = $del[0];
+                        my @dirNames;
+                        for (;;) {
+                            my $parent = $jpegMap{$dirName};
+                            if (ref $parent) {
+                                push @dirNames, @$parent;
+                                $parent = pop @dirNames;
+                            }
+                            $dirName = $parent || shift @dirNames or last;
+                            push @del, $dirName;    # exclude this too
+                        }
+                    }
+                    # allow MIE groups to be deleted by number
+                    push @del, uc($wantGroup) if $wantGroup =~ /^MIE\d+$/i;
+                } else {
+                    # push all groups plus '*', except IFD1 and a few others
+                    push @del, (grep !/^(IFD1|SubIFD|InteropIFD|GlobParamIFD)$/, @delGroups), '*';
+                }
+                if (@del) {
+                    ++$numSet;
+                    my @donegrps;
+                    foreach $grp (@del) {
+                        if ($remove) {
+                            exists $self->{DEL_GROUP}->{$grp} or next;
+                            delete $self->{DEL_GROUP}->{$grp};
+                        } else {
+                            $self->{DEL_GROUP}->{$grp} = 1;
+                            # remove all of this group from previous new values
+                            $self->RemoveNewValuesForGroup($grp);
+                        }
+                        push @donegrps, $grp;
+                    }
+                    if ($verbose > 1 and @donegrps) {
+                        @donegrps = sort @donegrps;
+                        my $msg = $remove ? 'Excluding from deletion' : 'Deleting tags in';
+                        print $out "  $msg: @donegrps\n";
+                    }
+                } else {
+                    $err = "Not a deletable group: $wantGroup";
+                }
+            }
+        } else {
+            my $origTag = $tag;
+            my $langCode;
+            # allow language suffix of form "-en_CA" or "-<rfc3066>" on tag name
+            if ($tag =~ /^(\w+)-([a-z]{2})(_[a-z]{2})$/i or # MIE
+                $tag =~ /^(\w+)-([a-z]{2,3}|[xi])(-[a-z\d]{2,8}(-[a-z\d]{1,8})*)?$/i) # XMP
+            {
+                $tag = $1;
+                $langCode = lc($2);
+                $langCode .= (length($3) == 3 ? uc($3) : lc($3)) if $3;
+                my @newMatches = FindTagInfo($tag);
+                foreach $tagInfo (@newMatches) {
+                    # only allow language codes in tables which support them
+                    next unless $$tagInfo{Table};
+                    my $langInfoProc = $tagInfo->{Table}->{LANG_INFO} or next;
+                    my $langInfo = &$langInfoProc($tagInfo, $langCode);
+                    push @matchingTags, $langInfo if $langInfo;
+                }
+                last if @matchingTags;
+            } else {
+                # look for a shortcut or alias
+                require Image::ExifTool::Shortcuts;
+                my ($match) = grep /^\Q$tag\E$/i, keys %Image::ExifTool::Shortcuts::Main;
+                undef $err;
+                if ($match and not $options{NoShortcut}) {
+                    if (@{$Image::ExifTool::Shortcuts::Main{$match}} == 1) {
+                        $tag = $Image::ExifTool::Shortcuts::Main{$match}->[0];
+                        @matchingTags = FindTagInfo($tag);
+                        last if @matchingTags;
+                    } else {
+                        $options{NoShortcut} = 1;
+                        foreach $tag (@{$Image::ExifTool::Shortcuts::Main{$match}}) {
+                            my ($n, $e) = $self->SetNewValue($tag, $value, %options);
+                            $numSet += $n;
+                            $e and $err = $e;
+                        }
+                        undef $err if $numSet;  # no error if any set successfully
+                        goto ReturnNow; # all done
+                    }
+                }
+            }
+            if (not TagExists($tag)) {
+                $err = "Tag '$origTag' does not exist";
+                $err .= ' or has a bad language code' if $origTag =~ /-/;
+            } elsif ($langCode) {
+                $err = "Tag '$tag' does not support alternate languages";
+            } elsif ($wantGroup) {
+                $err = "Sorry, $wantGroup:$origTag doesn't exist or isn't writable";
+            } else {
+                $err = "Sorry, $origTag is not writable";
+            }
+            $verbose > 2 and print $out "$err\n";
+        }
+        goto ReturnNow; # all done
+    }
+    # get group name that we're looking for
+    my $foundMatch = 0;
+    my ($ifdName, $mieGroup);
+    if ($wantGroup) {
+        # set $ifdName if this group is a valid IFD or SubIFD name
+        if ($wantGroup =~ /^IFD(\d+)$/i) {
+            $ifdName = "IFD$1";
+        } elsif ($wantGroup =~ /^SubIFD(\d+)$/i) {
+            $ifdName = "SubIFD$1";
+        } elsif ($wantGroup =~ /^MIE(\d*-?)(\w+)$/i) {
+            $mieGroup = "MIE$1" . ucfirst(lc($2));
+        } else {
+            $ifdName = $exifDirs{lc($wantGroup)};
+            if ($wantGroup =~ /^XMP\b/i) {
+                # must load XMP table to set group1 names
+                my $table = GetTagTable('Image::ExifTool::XMP::Main');
+                my $writeProc = $table->{WRITE_PROC};
+                $writeProc and &$writeProc();
+            }
+        }
+    }
+#
+# determine the groups for all tags found, and the tag with
+# the highest priority group
+#
+    my (@tagInfoList, %writeGroup, %preferred, %tagPriority, $avoid, $wasProtected);
+    my $highestPriority = -1;
+    foreach $tagInfo (@matchingTags) {
+        $tag = $tagInfo->{Name};    # set tag so warnings will use proper case
+        my ($writeGroup, $priority);
+        if ($wantGroup) {
+            my $lcWant = lc($wantGroup);
+            # only set tag in specified group
+            $writeGroup = $self->GetGroup($tagInfo, 0);
+            unless (lc($writeGroup) eq $lcWant) {
+                if ($writeGroup eq 'EXIF') {
+                    next unless $ifdName;
+                    $writeGroup = $ifdName;  # write to the specified IFD
+                } elsif ($writeGroup eq 'MIE') {
+                    next unless $mieGroup;
+                    $writeGroup = $mieGroup; # write to specific MIE group
+                    # set specific write group with document number if specified
+                    if ($writeGroup =~ /^MIE\d+$/ and $tagInfo->{Table}->{WRITE_GROUP}) {
+                        $writeGroup = $tagInfo->{Table}->{WRITE_GROUP};
+                        $writeGroup =~ s/^MIE/$mieGroup/;
+                    }
+                } else {
+                    # allow group1 name to be specified
+                    my $grp1 = $self->GetGroup($tagInfo, 1);
+                    unless ($grp1 and lc($grp1) eq $lcWant) {
+                        # must also check group1 name directly in case it is different
+                        $grp1 = $tagInfo->{Groups}->{1};
+                        next unless $grp1 and lc($grp1) eq $lcWant;
+                    }
+                }
+            }
+            $priority = 1000;   # highest priority since group was specified
+        }
+        ++$foundMatch;
+        # must do a dummy call to the write proc to autoload write package
+        # before checking Writable flag
+        my $table = $tagInfo->{Table};
+        my $writeProc = $table->{WRITE_PROC};
+        # load parent table if this was a user-defined table
+        if ($table->{PARENT}) {
+            my $parent = GetTagTable($table->{PARENT});
+            $writeProc = $parent->{WRITE_PROC} unless $writeProc;
+        }
+        next unless $writeProc and &$writeProc();
+        # must still check writable flags in case of UserDefined tags
+        my $writable = $tagInfo->{Writable};
+        next unless $writable or ($table->{WRITABLE} and
+            not defined $writable and not $$tagInfo{SubDirectory});
+        # don't write tag if protected
+        if ($tagInfo->{Protected}) {
+            my $prot = $tagInfo->{Protected} & ~$protected;
+            if ($prot) {
+                my %lkup = ( 1=>'unsafe', 2=>'protected', 3=>'unsafe and protected');
+                $wasProtected = $lkup{$prot};
+                next;
+            }
+        }
+        # set specific write group (if we didn't already)
+        if (not $writeGroup or $translateWriteGroup{$writeGroup}) {
+            # use default write group
+            $writeGroup = $tagInfo->{WriteGroup} || $tagInfo->{Table}->{WRITE_GROUP};
+            # use group 0 name if no WriteGroup specified
+            my $group0 = $self->GetGroup($tagInfo, 0);
+            $writeGroup or $writeGroup = $group0;
+            # get priority for this group
+            unless ($priority) {
+                $priority = $self->{WRITE_PRIORITY}->{lc($writeGroup)};
+                unless ($priority) {
+                    $priority = $self->{WRITE_PRIORITY}->{lc($group0)} || 0;
+                }
+            }
+        }
+        $tagPriority{$tagInfo} = $priority;
+        if ($priority > $highestPriority) {
+            $highestPriority = $priority;
+            %preferred = ( $tagInfo => 1 );
+            $avoid = 0;
+            ++$avoid if $$tagInfo{Avoid};
+        } elsif ($priority == $highestPriority) {
+            # create all tags with highest priority
+            $preferred{$tagInfo} = 1;
+            ++$avoid if $$tagInfo{Avoid};
+        }
+        push @tagInfoList, $tagInfo;
+        $writeGroup{$tagInfo} = $writeGroup;
+    }
+    # don't create tags with priority 0 if group priorities are set
+    if ($highestPriority == 0 and %{$self->{WRITE_PRIORITY}}) {
+        undef %preferred;
+    }
+    # avoid creating tags with 'Avoid' flag set if there are other alternatives
+    if ($avoid and %preferred) {
+        if ($avoid < scalar(keys %preferred)) {
+            # just remove the 'Avoid' tags since there are other preferred tags
+            foreach $tagInfo (@tagInfoList) {
+                delete $preferred{$tagInfo} if $$tagInfo{Avoid};
+            }
+        } elsif ($highestPriority < 1000) {
+            # look for another priority tag to create instead
+            my $nextHighest = 0;
+            my @nextBestTags;
+            foreach $tagInfo (@tagInfoList) {
+                my $priority = $tagPriority{$tagInfo} or next;
+                next if $priority == $highestPriority;
+                next if $priority < $nextHighest;
+                next if $$tagInfo{Avoid} or $$tagInfo{Permanent};
+                next if $writeGroup{$tagInfo} eq 'MakerNotes';
+                if ($nextHighest < $priority) {
+                    $nextHighest = $priority;
+                    undef @nextBestTags;
+                }
+                push @nextBestTags, $tagInfo;
+            }
+            if (@nextBestTags) {
+                # change our preferred tags to the next best tags
+                undef %preferred;
+                foreach $tagInfo (@nextBestTags) {
+                    $preferred{$tagInfo} = 1;
+                }
+            }
+        }
+    }
+#
+# generate new value hash for each tag
+#
+    my ($prioritySet, $createGroups);
+    # sort tag info list in reverse order of priority (higest number last)
+    # so we get the highest priority error message in the end
+    @tagInfoList = sort { $tagPriority{$a} <=> $tagPriority{$b} } @tagInfoList;
+    # loop through all valid tags to find the one(s) to write
+    SetTagLoop: foreach $tagInfo (@tagInfoList) {
+        my $writeGroup = $writeGroup{$tagInfo};
+        my $permanent = $$tagInfo{Permanent};
+        $writeGroup eq 'MakerNotes' and $permanent = 1 unless defined $permanent;
+        my $wgrp1;
+        if ($writeGroup eq 'MakerNotes' or $writeGroup eq 'XMP') {
+            $wgrp1 = $self->GetGroup($tagInfo, 1);
+        } else {
+            $wgrp1 = $writeGroup;
+        }
+        $tag = $tagInfo->{Name};    # get proper case for tag name
+        my $shift = $options{Shift};
+        if (defined $shift) {
+            if ($tagInfo->{Shift}) {
+                unless ($shift) {
+                    # set shift according to AddValue/DelValue
+                    $shift = 1 if $options{AddValue};
+                    $shift = -1 if $options{DelValue};
+                }
+            } elsif ($shift) {
+                $err = "$wgrp1:$tag is not shiftable";
+                $verbose > 2 and print $out "$err\n";
+                next;
+            }
+        }
+        my $val = $value;
+        if (defined $val) {
+            # check to make sure this is a List or Shift tag if adding
+            if ($options{AddValue} and not ($shift or $tagInfo->{List})) {
+                $err = "Can't add $wgrp1:$tag (not a List type)";
+                $verbose > 2 and print $out "$err\n";
+                next;
+            }
+        } else {
+            # can't delete permanent tags, so set value to empty string instead
+            $val = '' if $permanent;
+        }
+        # convert the value
+        my $type;
+        if ($shift) {
+            # add '+' or '-' prefix to indicate shift direction
+            $val = ($shift > 0 ? '+' : '-') . $val;
+            # check the shift for validity
+            require 'Image/ExifTool/Shift.pl';
+            my $err2 = CheckShift($tagInfo->{Shift}, $val);
+            if ($err2) {
+                $err = "$err2 for $wgrp1:$tag";
+                $verbose > 2 and print $out "$err\n";
+                next;
+            }
+        } else {
+            $type = $options{Type};
+            $type or $type = $self->Options('PrintConv') ? 'PrintConv' : 'ValueConv';
+        }
+Conv:   while (defined $val and not $shift) {
+            my $conv = $tagInfo->{$type};
+            my $convInv = $tagInfo->{"${type}Inv"};
+            my (@valList, $index, $convList, $convInvList);
+            # handle conversion lists
+            if (ref $conv eq 'ARRAY' or ref $convInv eq 'ARRAY') {
+                @valList = split /$listSep{$type}/, $val;
+                $val = $valList[$index = 0];
+                if (ref $conv eq 'ARRAY') {
+                    $convList = $conv;
+                    $conv = $$conv[0];
+                }
+                if (ref $convInv eq 'ARRAY') {
+                    $convInvList = $convInv;
+                    $convInv = $$convInv[0];
+                }
+            }
+            # loop through multiple values if necessary
+            for (;;) {
+                if ($convInv) {
+                    # capture eval warnings too
+                    local $SIG{'__WARN__'} = \&SetWarning;
+                    undef $evalWarning;
+                    if (ref($convInv) eq 'CODE') {
+                        $val = &$convInv($val, $self);
+                    } else {
+                        #### eval PrintConvInv/ValueConvInv ($val, $self)
+                        $val = eval $convInv;
+                        $@ and $evalWarning = $@;
+                    }
+                    if ($evalWarning) {
+                        $err = CleanWarning() . " in $wgrp1:$tag (${type}Inv)";
+                        $verbose > 2 and print $out "$err\n";
+                        undef $val;
+                        last Conv;
+                    } elsif (not defined $val) {
+                        $err = "Error converting value for $wgrp1:$tag (${type}Inv)";
+                        $verbose > 2 and print $out "$err\n";
+                        last Conv;
+                    }
+                } elsif ($conv) {
+                    if (ref $conv eq 'HASH') {
+                        my $multi;
+                        if ($$conv{BITMASK}) {
+                            my $lookupBits = $$conv{BITMASK};
+                            my ($val2, $err2) = EncodeBits($val, $lookupBits);
+                            if ($err2) {
+                                # ok, try matching a straight value
+                                ($val, $multi) = ReverseLookup($val, $conv);
+                                unless (defined $val) {
+                                    $err = "Can't encode $wgrp1:$tag ($err2)";
+                                    $verbose > 2 and print $out "$err\n";
+                                    last Conv;
+                                }
+                            } elsif (defined $val2) {
+                                $val = $val2;
+                            } else {
+                                delete $$conv{BITMASK};
+                                ($val, $multi) = ReverseLookup($val, $conv);
+                                $$conv{BITMASK} = $lookupBits;
+                            }
+                        } else {
+                            ($val, $multi) = ReverseLookup($val, $conv);
+                        }
+                        unless (defined $val) {
+                            $err = "Can't convert $wgrp1:$tag (" .
+                                   ($multi ? 'matches more than one' : 'not in') . " $type)";
+                            $verbose > 2 and print $out "$err\n";
+                            last Conv;
+                        }
+                    } elsif (not $$tagInfo{WriteAlso}) {
+                        $err = "Can't convert value for $wgrp1:$tag (no ${type}Inv)";
+                        $verbose > 2 and print $out "$err\n";
+                        undef $val;
+                        last Conv;
+                    }
+                }
+                last unless @valList;
+                $valList[$index] = $val;
+                if (++$index >= @valList) {
+                    $val = join ' ', @valList;
+                    last;
+                }
+                $conv = $$convList[$index] if $convList;
+                $convInv = $$convInvList[$index] if $convInvList;
+                $val = $valList[$index];
+            }
+            # cycle through PrintConv, ValueConv
+            if ($type eq 'PrintConv') {
+                $type = 'ValueConv';
+            } else {
+                # validate the value with WriteCheck and CHECK_PROC if they exist
+                my $err2;
+                if ($tagInfo->{WriteCheck}) {
+                    #### eval WriteCheck ($self, $tagInfo, $val)
+                    $err2 = eval $tagInfo->{WriteCheck};
+                    $@ and warn($@), $err2 = 'Error evaluating WriteCheck';
+                }
+                unless ($err2) {
+                    my $table = $tagInfo->{Table};
+                    if ($table and $table->{CHECK_PROC} and not $$tagInfo{RawConvInv}) {
+                        my $checkProc = $table->{CHECK_PROC};
+                        $err2 = &$checkProc($self, $tagInfo, \$val);
+                    }
+                }
+                if ($err2) {
+                    $err = "$err2 for $wgrp1:$tag";
+                    $verbose > 2 and print $out "$err\n";
+                    undef $val; # value was invalid
+                }
+                last;
+            }
+        }
+        if (not defined $val and defined $value) {
+            # if value conversion failed, we must still add a NEW_VALUE
+            # entry for this tag it it was a DelValue
+            next unless $options{DelValue};
+            $val = 'xxx never delete xxx';
+        }
+        $self->{NEW_VALUE} or $self->{NEW_VALUE} = { };
+        if ($options{Replace}) {
+            # delete the previous new value
+            $self->GetNewValueHash($tagInfo, $writeGroup, 'delete');
+            # also delete related tag previous new values
+            if ($$tagInfo{WriteAlso}) {
+                my $wtag;
+                foreach $wtag (keys %{$$tagInfo{WriteAlso}}) {
+                    my ($n,$e) = $self->SetNewValue($wtag, undef, Replace=>2);
+                    $numSet += $n;
+                }
+            }
+            $options{Replace} == 2 and ++$numSet, next;
+        }
+
+        # set value in NEW_VALUE hash
+        if (defined $val) {
+            # we are editing this tag, so create a NEW_VALUE hash entry
+            my $newValueHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create');
+            $newValueHash->{WantGroup} = $wantGroup;
+            # save maker note information if writing maker notes
+            if ($$tagInfo{MakerNotes}) {
+                $newValueHash->{MAKER_NOTE_FIXUP} = $self->{MAKER_NOTE_FIXUP};
+            }
+            if ($options{DelValue} or $options{AddValue} or $shift) {
+                # flag any AddValue or DelValue by creating the DelValue list
+                $newValueHash->{DelValue} or $newValueHash->{DelValue} = [ ];
+                if ($shift) {
+                    # add shift value to list
+                    $newValueHash->{Shift} = $val;
+                } elsif ($options{DelValue}) {
+                    # don't create if we are replacing a specific value
+                    $newValueHash->{IsCreating} = 0 unless $val eq '';
+                    # add delete value to list
+                    push @{$newValueHash->{DelValue}}, $val;
+                    if ($verbose > 1) {
+                        my $verb = $permanent ? 'Replacing' : 'Deleting';
+                        my $fromList = $tagInfo->{List} ? ' from list' : '';
+                        print $out "$verb $wgrp1:$tag$fromList if value is '$val'\n";
+                    }
+                }
+            }
+            # set priority flag to add only the high priority info
+            # (will only create the priority tag if it doesn't exist,
+            #  others get changed only if they already exist)
+            if ($preferred{$tagInfo} or $tagInfo->{Table}->{PREFERRED}) {
+                if ($permanent or $shift) {
+                    # don't create permanent or Shift-ed tag but define IsCreating
+                    # so we know that it is the preferred tag
+                    $newValueHash->{IsCreating} = 0;
+                } elsif (not ($newValueHash->{DelValue} and @{$newValueHash->{DelValue}}) or
+                         # also create tag if any DelValue value is empty ('')
+                         grep(/^$/,@{$newValueHash->{DelValue}}))
+                {
+                    $newValueHash->{IsCreating} = 1;
+                    # add to hash of groups where this tag is being created
+                    $createGroups or $createGroups = $options{CreateGroups} || { };
+                    $$createGroups{$self->GetGroup($tagInfo, 0)} = 1;
+                    $newValueHash->{CreateGroups} = $createGroups;
+                }
+            }
+            if (%{$self->{DEL_GROUP}} and $newValueHash->{IsCreating}) {
+                my ($grp, @grps);
+                foreach $grp (keys %{$self->{DEL_GROUP}}) {
+                    next if $self->{DEL_GROUP}->{$grp} == 2;
+                    # set flag indicating tags were written after this group was deleted
+                    $self->{DEL_GROUP}->{$grp} = 2;
+                    push @grps, $grp;
+                }
+                if ($verbose > 1 and @grps) {
+                    @grps = sort @grps;
+                    print $out "  Writing new tags after deleting groups: @grps\n";
+                }
+            }
+            if ($shift or not $options{DelValue}) {
+                $newValueHash->{Value} or $newValueHash->{Value} = [ ];
+                if ($tagInfo->{List}) {
+                    # we can write a list of entries
+                    push @{$newValueHash->{Value}}, $val;
+                } else {
+                    # not a List tag -- overwrite existing value
+                    $newValueHash->{Value}->[0] = $val;
+                }
+                if ($verbose > 1) {
+                    my $ifExists = $newValueHash->{IsCreating} ? '' : ' if tag exists';
+                    my $verb = ($shift ? 'Shifting' : ($options{AddValue} ? 'Adding' : 'Writing'));
+                    print $out "$verb $wgrp1:$tag$ifExists\n";
+                }
+            }
+        } elsif ($permanent) {
+            $err = "Can't delete $tag";
+            $verbose > 1 and print $out "$err\n";
+            next;
+        } elsif ($options{AddValue} or $options{DelValue}) {
+            $verbose > 1 and print $out "Adding/Deleting nothing does nothing\n";
+            next;
+        } else {
+            # create empty new value hash entry to delete this tag
+            $self->GetNewValueHash($tagInfo, $writeGroup, 'delete');
+            my $newValueHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create');
+            $newValueHash->{WantGroup} = $wantGroup;
+            $verbose > 1 and print $out "Deleting $wgrp1:$tag\n";
+        }
+        ++$numSet;
+        $prioritySet = 1 if $preferred{$tagInfo};
+        # also write related tags
+        my $writeAlso = $$tagInfo{WriteAlso};
+        if ($writeAlso) {
+            my $wtag;
+            foreach $wtag (keys %$writeAlso) {
+                #### eval WriteAlso ($val)
+                my $v = eval $writeAlso->{$wtag};
+                $@ and warn($@), next;
+                my ($n,$e) = $self->SetNewValue($wtag, $v, Type => 'ValueConv',
+                                                Protected => $protected | 0x02,
+                                                CreateGroups => $createGroups);
+                print $out "Not writing $wtag ($e)\n" if $e and $verbose > 1;
+                $numSet += $n;
+            }
+        }
+    }
+    # print warning if we couldn't set our priority tag
+    if ($err and not $prioritySet) {
+        warn "$err\n" unless wantarray;
+    } elsif (not $numSet) {
+        my $pre = $wantGroup ? "$wantGroup:" : '';
+        if ($wasProtected) {
+            $err = "Tag '$pre$tag' is $wasProtected for writing";
+        } elsif ($foundMatch) {
+            $err = "Sorry, $pre$tag is not writable";
+        } else {
+            $err = "Tag '$pre$tag' does not exist";
+        }
+        $verbose > 2 and print $out "$err\n";
+        warn "$err\n" unless wantarray;
+    } elsif ($err and not $verbose) {
+        undef $err;
+    }
+    return ($numSet, $err) if wantarray;
+    return $numSet;
+}
+
+#------------------------------------------------------------------------------
+# set new values from information in specified file
+# Inputs: 0) ExifTool object reference, 1) source file name or reference, etc
+#         2) List of tags to set (or all if none specified)
+# Returns: Hash of information set successfully (includes Warning or Error messages)
+# Notes: Tag names may contain group prefix and/or leading '-' to exclude from copy,
+#        and the tag name '*' may be used to represent all tags in a group.
+#        Also, a tag name may end with '>DSTTAG' to copy the information to a
+#        different tag, or a tag with a specified group.  (Also allow 'DSTTAG<TAG'.)
+sub SetNewValuesFromFile($$;@)
+{
+    my ($self, $srcFile, @setTags) = @_;
+
+    # expand shortcuts
+    @setTags and ExpandShortcuts(\@setTags);
+    my $srcExifTool = new Image::ExifTool;
+    my $options = $self->{OPTIONS};
+    # set options for our extraction tool
+    $srcExifTool->Options(
+        MakerNotes  => 1,
+        Binary      => 1,
+        Duplicates  => 1,
+        List        => 1,
+        StrictDate  => 1,
+        FixBase     => $$options{FixBase},
+        DateFormat  => $$options{DateFormat},
+        PrintConv   => $$options{PrintConv},
+        Composite   => $$options{Composite},
+        MissingTagValue   => $$options{MissingTagValue},
+        IgnoreMinorErrors => $$options{IgnoreMinorErrors},
+    );
+    # get all tags from source file (including MakerNotes block)
+    my $info = $srcExifTool->ImageInfo($srcFile);
+    return $info if $info->{Error} and $info->{Error} eq 'Error opening file';
+    delete $srcExifTool->{VALUE}->{Error};  # delete so we can check this later
+
+    # sort tags in reverse order so we get priority tag last
+    my @tags = reverse sort keys %$info;
+    my $tag;
+#
+# simply transfer all tags from source image if no tags specified
+#
+    unless (@setTags) {
+        # transfer maker note information to this object
+        $self->{MAKER_NOTE_FIXUP} = $srcExifTool->{MAKER_NOTE_FIXUP};
+        $self->{MAKER_NOTE_BYTE_ORDER} = $srcExifTool->{MAKER_NOTE_BYTE_ORDER};
+        foreach $tag (@tags) {
+            # don't try to set Warning's or Error's
+            next if $tag =~ /^Warning\b/ or $tag =~ /^Error\b/;
+            # set value for this tag
+            my ($n, $e) = $self->SetNewValue($tag, $info->{$tag}, Replace => 1);
+            # delete this tag if we could't set it
+            $n or delete $info->{$tag};
+        }
+        return $info;
+    }
+#
+# transfer specified tags in the proper order
+#
+    # 1) loop through input list of tags to set, and build @setList
+    my (@setList, $set, %setMatches);
+    foreach (@setTags) {
+        $tag = lc($_);  # change tag name to all lower case
+        my ($fam, $grp, $dst, $dstGrp, $dstTag, $expr, $opt);
+        # handle redirection to another tag
+        if ($tag =~ /(.+?)\s*(>|<)\s*(.+)/) {
+            $dstGrp = '';
+            if ($2 eq '>') {
+                ($tag, $dstTag) = ($1, $3);
+                # flag add and delete (ie. '+<' and '-<') redirections
+                $opt = $1 if $tag =~ s/\s*([-+])$// or $dstTag =~ s/^([-+])\s*//;
+            } else {
+                ($tag, $dstTag) = ($3, $1);
+                $opt = $1 if $dstTag =~ s/\s*([-+])$//;
+                # handle expressions
+                if ($tag =~ /\$/) {
+                    $tag = $_;  # restore original case
+                    # recover leading whitespace (except for initial single space)
+                    # and flag expression by starting with '@'
+                    $tag =~ s/(.+?)\s*(>|<) ?/\@/;
+                    $expr = 1;  # flag this expression
+                } else {
+                    $opt = $1 if $tag =~ s/^([-+])\s*//;
+                }
+            }
+            # translate '+' and '-' to appropriate SetNewValue option
+            $opt and $opt = { '+' => 'AddValue', '-' => 'DelValue' }->{$opt};
+            $dstTag =~ s/\ball\b/\*/g;       # replace 'all' with '*'
+            ($dstGrp, $dstTag) = ($1, $2) if $dstTag =~ /(.+?):(.+)/;
+            # ignore leading family number
+            $dstGrp = $2 if $dstGrp =~ /^(\d+)(.*)/ and $1 < 2;
+        }
+        $tag =~ s/\ball\b/\*/g unless $expr; # replace 'all' with '*'
+        my $isExclude = ($tag =~ s/^-//);
+        if ($tag =~ /^([\w-]+?|\*):(.+)/) {
+            ($grp, $tag) = ($1, $2);
+            # separate leading family number
+            ($fam, $grp) = ($1, $2) if $grp =~ /^(\d+)(.+)/ and $1 < 2;
+        } else {
+            $grp = '';  # flag for don't care about group
+        }
+        # redirect, exclude or set this tag (Note: $grp is '' if we don't care)
+        if ($dstTag) {
+            # redirect this tag
+            $isExclude and return { Error => "Can't redirect excluded tag" };
+            if ($tag eq '*' and $dstTag ne '*') {
+                return { Error => "Can't redirect from all tags to one tag" };
+            }
+            # set destination group the same as source if necessary
+            $dstGrp = $grp if $dstGrp eq '*' and $grp;
+            # write to specified destination group/tag
+            $dst = [ $dstGrp, $dstTag ];
+        } elsif ($isExclude) {
+            # implicitly assume '*' if first entry is an exclusion
+            unshift @setList, [ undef, '*', '*', [ '', '*' ] ] unless @setList;
+            # exclude this tag by leaving $dst undefined
+        } else {
+            # copy to same group/tag
+            $dst = [ $grp, $tag ];
+        }
+        $grp or $grp = '*';     # use '*' for any group
+        # save in reverse order so we don't set tags before an exclude
+        unshift @setList, [ $fam, $grp, $tag, $dst, $opt ];
+    }
+    # 2) initialize lists of matching tags for each condition
+    foreach $set (@setList) {
+        $$set[3] and $setMatches{$$set[3]} = [ ];
+    }
+    # 3) loop through all tags in source image and save tags matching each condition
+    my %rtnInfo;
+    foreach $tag (@tags) {
+        # don't try to set Warning's or Error's
+        if ($tag =~ /^Warning\b/ or $tag =~ /^Error\b/) {
+            $rtnInfo{$tag} = $info->{$tag};
+            next;
+        }
+        my @dstList;
+        # only set specified tags
+        my $lcTag = lc(GetTagName($tag));
+        my @grp;
+        foreach $set (@setList) {
+            # check first for matching tag
+            next unless $$set[2] eq $lcTag or $$set[2] eq '*';
+            # then check for matching group
+            unless ($$set[1] eq '*') {
+                # get lower case group names if not done already
+                @grp or @grp = map(lc, $srcExifTool->GetGroup($tag));
+                # handle leading family number
+                if (defined $$set[0]) {
+                    next unless $$set[1] eq $grp[$$set[0]];
+                } else {
+                    next unless $$set[1] eq $grp[0] or $$set[1] eq $grp[1];
+                }
+            }
+            last unless $$set[3];   # all done if we hit an exclude
+            # add to the list of tags matching this condition
+            push @{$setMatches{$set}}, $tag;
+        }
+    }
+    # 4) loop through each condition in original order, setting new tag values
+    foreach $set (reverse @setList) {
+        # handle expressions
+        if ($$set[2] =~ s/^\@//) {
+            my $val = $srcExifTool->InsertTagValues(\@tags, $$set[2], 'Error');
+            unless (defined $val) {
+                # return warning if one of the tags didn't exist
+                $tag = NextTagKey(\%rtnInfo, 'Warning');
+                $rtnInfo{$tag} = $srcExifTool->GetValue('Error');
+                delete $srcExifTool->{VALUE}->{Error};
+                next;
+            }
+            my ($dstGrp, $dstTag) = @{$$set[3]};
+            my %opts = ( Protected => 1, Replace => 1 );
+            # add or delete value if specified
+            $opts{$$set[4]} = 1 if $$set[4];
+            $opts{Group} = $dstGrp if $dstGrp;
+            my @rtnVals = $self->SetNewValue($dstTag, $val, %opts);
+            $rtnInfo{$dstTag} = $val if $rtnVals[0]; # tag was set successfully
+            next;
+        }
+        foreach $tag (@{$setMatches{$set}}) {
+            my (@values, %opts, $val, $noWarn);
+            # get all values for this tag
+            if (ref $info->{$tag} eq 'ARRAY') {
+                @values = @{$info->{$tag}};
+            } elsif (ref $info->{$tag} eq 'SCALAR') {
+                @values = ( ${$info->{$tag}} );
+            } else {
+                @values = ( $info->{$tag} );
+            }
+            my ($dstGrp, $dstTag) = @{$$set[3]};
+            if ($dstGrp) {
+                if ($dstGrp eq '*') {
+                    $dstGrp = $srcExifTool->GetGroup($tag, 1);
+                    $noWarn = 1;    # don't warn on wildcard destinations
+                }
+                $opts{Group} = $dstGrp;
+            }
+            # transfer maker note information if setting this tag
+            if ($srcExifTool->{TAG_INFO}->{$tag}->{MakerNotes}) {
+                $self->{MAKER_NOTE_FIXUP} = $srcExifTool->{MAKER_NOTE_FIXUP};
+                $self->{MAKER_NOTE_BYTE_ORDER} = $srcExifTool->{MAKER_NOTE_BYTE_ORDER};
+            }
+            if ($dstTag eq '*') {
+                $dstTag = $tag;
+                $noWarn = 1;
+            }
+            # add or delete value if specified
+            $opts{$$set[4]} = 1 if $$set[4];
+            # allow protected tags to be copied if specified explicitly
+            $opts{Protected} = 1 unless $$set[2] eq '*';
+            $opts{Replace} = 1;     # replace the first value found
+            # set all values for this tag
+            foreach $val (@values) {
+                my ($rtn, $wrn) = $self->SetNewValue($dstTag, $val, %opts);
+                if ($wrn and not $noWarn) {
+                    # return this warning
+                    $rtnInfo{NextTagKey(\%rtnInfo, 'Warning')} = $wrn;
+                    $noWarn = 1;
+                }
+                last unless $rtn;
+                $rtnInfo{$tag} = $info->{$tag}; # tag was set successfully
+                $opts{Replace} = 0;
+            }
+        }
+    }
+    return \%rtnInfo;   # return information that we set
+}
+
+#------------------------------------------------------------------------------
+# Get new value(s) for tag
+# Inputs: 0) ExifTool object reference, 1) tag key, tag name, or tagInfo hash ref
+#         2) optional pointer to return new value hash reference (not part of public API)
+#    or   0) new value hash reference (not part of public API)
+# Returns: List of new Raw values (list may be empty if tag is being deleted)
+# Notes: 1) Preferentially returns new value from Extra table if writable Extra tag exists
+# 2) Must call AFTER IsOverwriting() returns 1 to get proper value for shifted times
+sub GetNewValues($;$$)
+{
+    local $_;
+    my $newValueHash;
+    if (ref $_[0] eq 'HASH') {
+        $newValueHash = shift;
+    } else {
+        my ($self, $tag, $newValueHashPt) = @_;
+        if ($self->{NEW_VALUE}) {
+            my $tagInfo;
+            if (ref $tag) {
+                $newValueHash = $self->GetNewValueHash($tag);
+            } elsif (defined($tagInfo = $Image::ExifTool::Extra{$tag}) and
+                     $$tagInfo{Writable})
+            {
+                $newValueHash = $self->GetNewValueHash($tagInfo);
+            } else {
+                my @tagInfoList = FindTagInfo($tag);
+                # choose the one that we are creating
+                foreach $tagInfo (@tagInfoList) {
+                    my $nvh = $self->GetNewValueHash($tagInfo) or next;
+                    $newValueHash = $nvh;
+                    last if defined $newValueHash->{IsCreating};
+                }
+            }
+        }
+        # return new value hash if requested
+        $newValueHashPt and $$newValueHashPt = $newValueHash;
+    }
+    if ($newValueHash and $newValueHash->{Value}) {
+        my $vals = $newValueHash->{Value};
+        # do inverse raw conversion if necessary
+        if ($newValueHash->{TagInfo}->{RawConvInv}) {
+            my $tagInfo = $$newValueHash{TagInfo};
+            my $conv = $$tagInfo{RawConvInv};
+            my $self = $newValueHash->{Self};
+            my ($val, $checkProc);
+            my $table = $tagInfo->{Table};
+            $checkProc = $$table{CHECK_PROC} if $table;
+            local $SIG{'__WARN__'} = \&SetWarning;
+            undef $evalWarning;
+            foreach $val (@$vals) {
+                if (ref($conv) eq 'CODE') {
+                    $val = &$conv($val, $self);
+                } else {
+                    #### eval RawConvInv ($self, $val)
+                    $val = eval $conv;
+                    $@ and $evalWarning = $@;
+                }
+                if ($evalWarning) {
+                    my $err = CleanWarning() . " in $$tagInfo{Name} (RawConvInv)";
+                    $self->Warn($err);
+                    @$vals = ();
+                    last;
+                }
+                # must check value now
+                next unless $checkProc;
+                my $err = &$checkProc($self, $tagInfo, \$val);
+                if ($err or not defined $val) {
+                    $err or $err = 'Error generating raw value';
+                    $self->Warn("$err for $$tagInfo{Name}");
+                    @$vals = ();
+                    last;
+                }
+            }
+        }
+        # return our value(s)
+        if (wantarray) {
+            return @$vals;
+        } else {
+            return $$vals[0];
+        }
+    }
+    return () if wantarray;  # return empty list
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Return the total number of new values set
+# Inputs: 0) ExifTool object reference
+# Returns: Scalar context) Number of new values that have been set
+#          List context) Number of new values, number of "pseudo" values
+# ("pseudo" values are those which don't require rewriting the file to change)
+sub CountNewValues($)
+{
+    my $self = shift;
+    my $newVal = $self->{NEW_VALUE};
+    my $num = 0;
+    $num += scalar keys %$newVal if $newVal;
+    $num += scalar keys %{$self->{DEL_GROUP}};
+    return $num unless wantarray;
+    my $pseudo = 0;
+    if ($newVal) {
+        my $tag;
+        # (Note: all "pseudo" tags must be found in Extra table)
+        foreach $tag (qw{FileName Directory FileModifyDate}) {
+            ++$pseudo if defined $$newVal{$Image::ExifTool::Extra{$tag}};
+        }
+    }
+    return ($num, $pseudo);
+}
+
+#------------------------------------------------------------------------------
+# Save new values for subsequent restore
+# Inputs: 0) ExifTool object reference
+sub SaveNewValues($)
+{
+    my $self = shift;
+    my $newValues = $self->{NEW_VALUE};
+    my $key;
+    foreach $key (keys %$newValues) {
+        my $newValueHash = $$newValues{$key};
+        while ($newValueHash) {
+            $newValueHash->{Save} = 1;  # set Save flag
+            $newValueHash = $newValueHash->{Next};
+        }
+    }
+    # initialize hash for saving overwritten new values
+    $self->{SAVE_NEW_VALUE} = { };
+}
+
+#------------------------------------------------------------------------------
+# Restore new values to last saved state
+# Inputs: 0) ExifTool object reference
+# Notes: Restores saved new values, but currently doesn't restore them in the
+# orginal order, so there may be some minor side-effects when restoring tags
+# with overlapping groups. ie) XMP:Identifier, XMP-dc:Identifier
+sub RestoreNewValues($)
+{
+    my $self = shift;
+    my $newValues = $self->{NEW_VALUE};
+    my $savedValues = $self->{SAVE_NEW_VALUE};
+    my $key;
+    # 1) remove any new values which don't have the Save flag set
+    if ($newValues) {
+        my @keys = keys %$newValues;
+        foreach $key (@keys) {
+            my $lastHash;
+            my $newValueHash = $$newValues{$key};
+            while ($newValueHash) {
+                if ($newValueHash->{Save}) {
+                    $lastHash = $newValueHash;
+                } else {
+                    # remove this entry from the list
+                    if ($lastHash) {
+                        $lastHash->{Next} = $newValueHash->{Next};
+                    } elsif ($newValueHash->{Next}) {
+                        $$newValues{$key} = $newValueHash->{Next};
+                    } else {
+                        delete $$newValues{$key};
+                    }
+                }
+                $newValueHash = $newValueHash->{Next};
+            }
+        }
+    }
+    # 2) restore saved new values
+    if ($savedValues) {
+        $newValues or $newValues = $self->{NEW_VALUE} = { };
+        foreach $key (keys %$savedValues) {
+            if ($$newValues{$key}) {
+                # add saved values to end of list
+                my $newValueHash = LastInList($$newValues{$key});
+                $newValueHash->{Next} = $$savedValues{$key};
+            } else {
+                $$newValues{$key} = $$savedValues{$key};
+            }
+        }
+        $self->{SAVE_NEW_VALUE} = { };  # reset saved new values
+    }
+}
+
+#------------------------------------------------------------------------------
+# Set file modification time from FileModifyDate tag
+# Inputs: 0) ExifTool object reference, 1) file name or file ref
+#         2) modify time (-M) of original file (needed for time shift)
+# Returns: 1=time changed OK, 0=nothing done, -1=error setting time
+#          (and increments CHANGED flag if time was changed)
+sub SetFileModifyDate($$;$)
+{
+    my ($self, $file, $originalTime) = @_;
+    my $newValueHash;
+    my $val = $self->GetNewValues('FileModifyDate', \$newValueHash);
+    return 0 unless defined $val;
+    my $isOverwriting = IsOverwriting($newValueHash);
+    return 0 unless $isOverwriting;
+    if ($isOverwriting < 0) {  # are we shifting time?
+        # use original time of this file if not specified
+        $originalTime = -M $file unless defined $originalTime;
+        return 0 unless defined $originalTime;
+        return 0 unless IsOverwriting($newValueHash, $^T - $originalTime*(24*3600));
+        $val = $newValueHash->{Value}->[0]; # get shifted value
+    }
+    unless (utime($val, $val, $file)) {
+        $self->Warn('Error setting FileModifyDate');
+        return -1;
+    }
+    ++$self->{CHANGED};
+    $self->VPrint(1, "    + FileModifyDate = '$val'\n");
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Change file name and/or directory from FileName and Directory tags
+# Inputs: 0) ExifTool object reference, 1) current file name (including path)
+#         2) New name (or undef to build from FileName and Directory tags)
+# Returns: 1=name changed OK, 0=nothing changed, -1=error changing name
+#          (and increments CHANGED flag if filename changed)
+# Notes: Will not overwrite existing file.  Creates directories as necessary.
+sub SetFileName($$;$)
+{
+    my ($self, $file, $newName) = @_;
+    my ($newValueHash, $doName, $doDir);
+    # determine the new file name
+    unless (defined $newName) {
+        my $filename = $self->GetNewValues('FileName', \$newValueHash);
+        $doName = 1 if defined $filename and IsOverwriting($newValueHash, $file);
+        my $dir = $self->GetNewValues('Directory', \$newValueHash);
+        $doDir = 1 if defined $dir and IsOverwriting($newValueHash, $file);
+        return 0 unless $doName or $doDir;  # nothing to do
+        if ($doName) {
+            $newName = GetNewFileName($file, $filename);
+            $newName = GetNewFileName($newName, $dir) if $doDir;
+        } else {
+            $newName = GetNewFileName($file, $dir);
+        }
+    }
+    if (-e $newName) {
+        # don't replace existing file
+        $self->Warn("File '$newName' already exists");
+        return -1;
+    }
+    # create directory for new file if necessary
+    my $result;
+    if (($result = CreateDirectory($newName)) != 0) {
+        if ($result < 0) {
+            $self->Warn("Error creating directory for '$newName'");
+            return -1;
+        }
+        $self->VPrint(0, "Created directory for '$newName'");
+    }
+    # attempt to rename the file
+    unless (rename $file, $newName) {
+        # renaming didn't work, so copy the file instead
+        unless (open EXIFTOOL_SFN_IN, $file) {
+            $self->Warn("Error opening '$file'");
+            return -1;
+        }
+        unless (open EXIFTOOL_SFN_OUT, ">$newName") {
+            close EXIFTOOL_SFN_IN;
+            $self->Warn("Error creating '$newName'");
+            return -1;
+        }
+        binmode EXIFTOOL_SFN_IN;
+        binmode EXIFTOOL_SFN_OUT;
+        my ($buff, $err);
+        while (read EXIFTOOL_SFN_IN, $buff, 65536) {
+            print EXIFTOOL_SFN_OUT $buff or $err = 1;
+        }
+        close EXIFTOOL_SFN_OUT or $err = 1;
+        close EXIFTOOL_SFN_IN;
+        if ($err) {
+            unlink $newName;    # erase bad output file
+            $self->Warn("Error writing '$newName'");
+            return -1;
+        }
+        # preserve modification time
+        my $modTime = $^T - (-M $file) * (24 * 3600);
+        my $accTime = $^T - (-A $file) * (24 * 3600);
+        utime($accTime, $modTime, $newName);
+        # remove the original file
+        unlink $file or $self->Warn('Error removing old file');
+    }
+    ++$self->{CHANGED};
+    $self->VPrint(1, "    + FileName = '$newName'\n");
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Write information back to file
+# Inputs: 0) ExifTool object reference,
+#         1) input filename, file ref, or scalar ref (or '' or undef to create from scratch)
+#         2) output filename, file ref, or scalar ref (or undef to edit in place)
+#         3) optional output file type (required only if input file is not specified
+#            and output file is a reference)
+# Returns: 1=file written OK, 2=file written but no changes made, 0=file write error
+sub WriteInfo($$;$$)
+{
+    local $_;
+    my ($self, $infile, $outfile, $outType) = @_;
+    my (@fileTypeList, $fileType, $tiffType);
+    my ($inRef, $outRef, $closeIn, $closeOut, $outPos, $outBuff, $eraseIn);
+    my $oldRaf = $self->{RAF};
+    my $rtnVal = 1;
+
+    # initialize member variables
+    $self->Init();
+
+    # first, save original file modify date if necessary
+    # (do this now in case we are modifying file in place and shifting date)
+    my ($newValueHash, $originalTime);
+    my $fileModifyDate =  $self->GetNewValues('FileModifyDate', \$newValueHash);
+    if (defined $fileModifyDate and IsOverwriting($newValueHash) < 0 and
+        defined $infile and ref $infile ne 'SCALAR')
+    {
+        $originalTime = -M $infile;
+    }
+#
+# do quick in-place change of file dir/name or date if that is all we are doing
+#
+    if (not defined $outfile and defined $infile) {
+        my $newFileName =  $self->GetNewValues('FileName', \$newValueHash);
+        my ($numNew, $numPseudo) = $self->CountNewValues();
+        if ($numNew == $numPseudo) {
+            $rtnVal = 2;
+            if (defined $fileModifyDate and (not ref $infile or UNIVERSAL::isa($infile,'GLOB'))) {
+                $self->SetFileModifyDate($infile) > 0 and $rtnVal = 1;
+            }
+            if (defined $newFileName and not ref $infile) {
+                $self->SetFileName($infile) > 0 and $rtnVal = 1;
+            }
+            return $rtnVal;
+        } elsif (defined $newFileName and length $newFileName) {
+            # can't simply rename file, so just set the output name if new FileName
+            # --> in this case, must erase original copy
+            if (ref $infile) {
+                $outfile = $newFileName;
+                # can't delete original
+            } elsif (IsOverwriting($newValueHash, $infile)) {
+                $outfile = GetNewFileName($infile, $newFileName);
+                $eraseIn = 1; # delete original                
+            }
+        }
+    }
+#
+# set up input file
+#
+    if (ref $infile) {
+        $inRef = $infile;
+        if (UNIVERSAL::isa($inRef,'GLOB')) {
+            seek($inRef, 0, 0); # make sure we are at the start of the file
+        } elsif (eval 'require Encode; Encode::is_utf8($$inRef)') {
+            # convert image data from UTF-8 to character stream if necessary
+            if (defined $outfile) {
+                my $buff = pack('C*', unpack('U0U*', $$inRef));
+                $inRef = \$buff;
+            } else {
+                $$inRef = pack('C*', unpack('U0U*', $$inRef));
+            }
+        }
+    } elsif (defined $infile and $infile ne '') {
+        if (open(EXIFTOOL_FILE2, defined $outfile ? $infile : "+<$infile")) {
+            $fileType = GetFileType($infile);
+            $tiffType = GetFileExtension($infile);
+            $self->VPrint(0, "Rewriting $infile...\n");
+            $inRef = \*EXIFTOOL_FILE2;
+            $closeIn = 1;   # we must close the file since we opened it
+        } else {
+            my $forUpdate = (defined $outfile ? '' : ' for update');
+            $self->Error("Error opening file$forUpdate");
+            return 0;
+        }
+    } elsif (not defined $outfile) {
+        $self->Error("WriteInfo(): Must specify infile or outfile\n");
+        return 0;
+    } else {
+        # create file from scratch
+        $outType = GetFileType($outfile) unless $outType or ref $outfile;
+        if (CanCreate($outType)) {
+            $fileType = $tiffType = $outType;   # use output file type if no input file
+            $infile = "$fileType file";         # make bogus file name
+            $self->VPrint(0, "Creating $infile...\n");
+            $inRef = \ '';      # set $inRef to reference to empty data
+        } elsif ($outType) {
+            $self->Error("Can't create $outType files");
+            return 0;
+        } else {
+            $self->Error("Can't create file (unknown type)");
+            return 0;
+        }
+    }
+    if ($fileType) {
+        @fileTypeList = ( $fileType );
+    } else {
+        @fileTypeList = @fileTypes;
+        $tiffType = 'TIFF';
+    }
+#
+# set up output file
+#
+    if (ref $outfile) {
+        $outRef = $outfile;
+        if (UNIVERSAL::isa($outRef,'GLOB')) {
+            binmode($outRef);
+            $outPos = tell($outRef);
+        } else {
+            # initialize our output buffer if necessary
+            defined $$outRef or $$outRef = '';
+            $outPos = length($$outRef);
+        }
+    } elsif (not defined $outfile) {
+        # editing in place, so write to memory first
+        $outBuff = '';
+        $outRef = \$outBuff;
+        $outPos = 0;
+    } elsif (-e $outfile) {
+        $self->Error("File already exists: $outfile");
+        $rtnVal = 0;
+    } elsif (open(EXIFTOOL_OUTFILE, ">$outfile")) {
+        $outRef = \*EXIFTOOL_OUTFILE;
+        $closeOut = 1;  # we must close $outRef
+        binmode($outRef);
+        $outPos = 0;
+    } else {
+        $self->Error("Error creating file: $outfile");
+        $rtnVal = 0;
+    }
+#
+# write the file
+#
+    if ($rtnVal) {
+        # create random access file object
+        my $raf = new File::RandomAccess($inRef);
+        # patch for Windows command shell pipe
+        $raf->{TESTED} = -1 if not ref $infile and ($infile eq '-' or $infile =~ /\|$/);
+       # $raf->Debug() and warn "  RAF debugging enabled!\n";
+        my $inPos = $raf->Tell();
+        $raf->BinMode();
+        $self->{RAF} = $raf;
+        my %dirInfo = (
+            RAF => $raf,
+            OutFile => $outRef,
+        );
+        for (;;) {
+            my $type = shift @fileTypeList;
+            # save file type in member variable
+            $dirInfo{Parent} = $self->{FILE_TYPE} = $type;
+            # determine which directories we must write for this file type
+            $self->InitWriteDirs($type);
+            if ($type eq 'JPEG') {
+                $rtnVal = $self->WriteJPEG(\%dirInfo);
+            } elsif ($type eq 'TIFF') {
+                # disallow writing of some TIFF-based RAW images:
+                if ($tiffType =~ /^(SRF|SR2|ARW|RAW|DCR|K25)$/) {
+                    $fileType = $tiffType;
+                    undef $rtnVal;
+                } else {
+                    $dirInfo{Parent} = $tiffType;
+                    $rtnVal = $self->ProcessTIFF(\%dirInfo);
+                }
+            } elsif ($type eq 'GIF') {
+                require Image::ExifTool::GIF;
+                $rtnVal = Image::ExifTool::GIF::ProcessGIF($self,\%dirInfo);
+            } elsif ($type eq 'CRW') {
+                require Image::ExifTool::CanonRaw;
+                $rtnVal = Image::ExifTool::CanonRaw::WriteCRW($self, \%dirInfo);
+            } elsif ($type eq 'MRW') {
+                require Image::ExifTool::MinoltaRaw;
+                $rtnVal = Image::ExifTool::MinoltaRaw::ProcessMRW($self, \%dirInfo);
+            } elsif ($type eq 'ORF') {
+                $rtnVal = $self->ProcessTIFF(\%dirInfo);
+            } elsif ($type eq 'PNG') {
+                require Image::ExifTool::PNG;
+                $rtnVal = Image::ExifTool::PNG::ProcessPNG($self, \%dirInfo);
+            } elsif ($type eq 'MIE') {
+                require Image::ExifTool::MIE;
+                $rtnVal = Image::ExifTool::MIE::ProcessMIE($self, \%dirInfo);
+            } elsif ($type eq 'XMP') {
+                require Image::ExifTool::XMP;
+                $rtnVal = Image::ExifTool::XMP::WriteXMP($self, \%dirInfo);
+            } elsif ($type eq 'PPM') {
+                require Image::ExifTool::PPM;
+                $rtnVal = Image::ExifTool::PPM::ProcessPPM($self, \%dirInfo);
+            } elsif ($type eq 'PSD') {
+                require Image::ExifTool::Photoshop;
+                $rtnVal = Image::ExifTool::Photoshop::ProcessPSD($self, \%dirInfo);
+            } elsif ($type eq 'EPS' or $type eq 'PS') {
+                require Image::ExifTool::PostScript;
+                $rtnVal = Image::ExifTool::PostScript::WritePS($self, \%dirInfo);
+            } elsif ($type eq 'ICC') {
+                require Image::ExifTool::ICC_Profile;
+                $rtnVal = Image::ExifTool::ICC_Profile::WriteICC($self, \%dirInfo);
+            } elsif ($type eq 'VRD') {
+                require Image::ExifTool::CanonVRD;
+                $rtnVal = Image::ExifTool::CanonVRD::ProcessVRD($self, \%dirInfo);
+            } elsif ($type eq 'JP2') {
+                require Image::ExifTool::Jpeg2000;
+                $rtnVal = Image::ExifTool::Jpeg2000::ProcessJP2($self, \%dirInfo);
+            } elsif ($type eq 'RAW') {
+                $rtnVal = $self->ProcessTIFF(\%dirInfo);
+            } else {
+                undef $rtnVal;  # flag that we don't write this type of file
+            }
+            # all done unless we got the wrong type
+            last if $rtnVal;
+            last unless @fileTypeList;
+            # seek back to original position in files for next try
+            unless ($raf->Seek($inPos, 0)) {
+                $self->Error('Error seeking in file');
+                last;
+            }
+            if (UNIVERSAL::isa($outRef,'GLOB')) {
+                seek($outRef, 0, $outPos);
+            } else {
+                $$outRef = substr($$outRef, 0, $outPos);
+            }
+        }
+        # print file format errors
+        unless ($rtnVal) {
+            if ($fileType and defined $rtnVal) {
+                $self->{VALUE}->{Error} or $self->Error('Format error in file');
+            } elsif ($fileType) {
+                $self->Error("ExifTool does not yet support writing of $fileType files");
+            } else {
+                $self->Error('ExifTool does not support writing of this type of file');
+            }
+            $rtnVal = 0;
+        }
+       # $raf->Close(); # only used to force debug output
+    }
+    # don't return success code if any error occurred
+    $rtnVal = 0 if $rtnVal > 0 and $self->{VALUE}->{Error};
+
+    # rewrite original file in place if required
+    if (defined $outBuff) {
+        if ($rtnVal <= 0 or not $self->{CHANGED}) {
+            # nothing changed, so no need to write $outBuff
+        } elsif (UNIVERSAL::isa($inRef,'GLOB')) {
+            my $len = length($outBuff);
+            my $size;
+            $rtnVal = -1 unless
+                seek($inRef, 0, 2) and          # seek to the end of file
+                ($size = tell $inRef) >= 0 and  # get the file size
+                seek($inRef, 0, 0) and          # seek back to the start
+                print $inRef $outBuff and       # write the new data
+                ($len >= $size or               # if necessary:
+                eval 'truncate($inRef, $len)'); #  shorten output file
+        } else {
+            $$inRef = $outBuff;                 # replace original data
+        }
+        $outBuff = '';  # free memory but leave $outBuff defined
+    }
+    # close input file if we opened it
+    if ($closeIn) {
+        # errors on input file are significant if we edited the file in place
+        $rtnVal and $rtnVal = -1 unless close($inRef) or not defined $outBuff;
+        if ($eraseIn and $rtnVal > 0) {
+            # erase input file if renaming while editing information in place
+            unlink $infile or $self->Warn('Error erasing original file');
+        }
+    }
+    # close output file if we created it
+    if ($closeOut) {
+        # close file and set $rtnVal to -1 if there was an error
+        $rtnVal and $rtnVal = -1 unless close($outRef);
+        # erase the output file if we weren't successful
+        $rtnVal > 0 or unlink $outfile;
+    }
+    # set FileModifyDate if requested (and if possible!)
+    if (defined $fileModifyDate and $rtnVal > 0 and
+        ($closeOut or ($closeIn and defined $outBuff)))
+    {
+        $self->SetFileModifyDate($closeOut ? $outfile : $infile, $originalTime);
+    }
+    # check for write error and set appropriate error message and return value
+    if ($rtnVal < 0) {
+        $self->Error('Error writing output file');
+        $rtnVal = 0;    # return 0 on failure
+    } elsif ($rtnVal > 0) {
+        ++$rtnVal unless $self->{CHANGED};
+    }
+    # set things back to the way they were
+    $self->{RAF} = $oldRaf;
+
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Get list of all available tags for specified group
+# Inputs: 0) optional group name
+# Returns: tag list (sorted alphabetically)
+# Notes: Can't get tags for specific IFD
+sub GetAllTags(;$)
+{
+    local $_;
+    my $group = shift;
+    my (%allTags, $exifTool);
+
+    $group and $exifTool = new Image::ExifTool;
+    LoadAllTables();    # first load all our tables
+    my @tableNames = ( keys %allTables );
+
+    # loop through all tables and save tag names to %allTags hash
+    while (@tableNames) {
+        my $table = GetTagTable(pop @tableNames);
+        my $tagID;
+        foreach $tagID (TagTableKeys($table)) {
+            my @infoArray = GetTagInfoList($table,$tagID);
+            my $tagInfo;
+            foreach $tagInfo (@infoArray) {
+                my $tag = $$tagInfo{Name} || die "no name for tag!\n";
+                # don't list subdirectories unless they are writable
+                next unless $$tagInfo{Writable} or not $$tagInfo{SubDirectory};
+                if ($group) {
+                    my @groups = $exifTool->GetGroup($tagInfo);
+                    next unless grep /^$group$/i, @groups;
+                }
+                $allTags{$tag} = 1;
+            }
+        }
+    }
+    return sort keys %allTags;
+}
+
+#------------------------------------------------------------------------------
+# Get list of all writable tags
+# Inputs: 0) optional group name
+# Returns: tag list (sorted alphbetically)
+sub GetWritableTags(;$)
+{
+    local $_;
+    my $group = shift;
+    my (%writableTags, $exifTool);
+
+    $group and $exifTool = new Image::ExifTool;
+    LoadAllTables();
+    my @tableNames = keys %allTables;
+
+    while (@tableNames) {
+        my $tableName = pop @tableNames;
+        my $table = GetTagTable($tableName);
+        # attempt to load Write tables if autoloaded
+        my @path = split(/::/,$tableName);
+        if (@path > 3) {
+            my $i = $#path - 1;
+            $path[$i] = "Write$path[$i]";   # add 'Write' before class name
+            my $module = join('::',@path[0..($#path-1)]);
+            eval "require $module"; # (fails silently if nothing loaded)
+        }
+        my $tagID;
+        foreach $tagID (TagTableKeys($table)) {
+            my @infoArray = GetTagInfoList($table,$tagID);
+            my $tagInfo;
+            foreach $tagInfo (@infoArray) {
+                my $tag = $$tagInfo{Name} || die "no name for tag!\n";
+                my $writable = $$tagInfo{Writable};
+                next unless $writable or ($table->{WRITABLE} and
+                    not defined $writable and not $$tagInfo{SubDirectory});
+                if ($group) {
+                    my @groups = $exifTool->GetGroup($tagInfo);
+                    next unless grep /^$group$/i, @groups;
+                }
+                $writableTags{$tag} = 1;
+            }
+        }
+    }
+    return sort keys %writableTags;
+}
+
+#------------------------------------------------------------------------------
+# Get list of all group names
+# Inputs: 1) Group family number
+# Returns: List of group names (sorted alphabetically)
+sub GetAllGroups($)
+{
+    local $_;
+    my $family = shift || 0;
+
+    LoadAllTables();    # first load all our tables
+
+    my @tableNames = ( keys %allTables );
+
+    # loop through all tag tables and get all group names
+    my %allGroups;
+    while (@tableNames) {
+        my $table = GetTagTable(pop @tableNames);
+        my $defaultGroup;
+        $defaultGroup = $table->{GROUPS}->{$family} if $table->{GROUPS};
+        $allGroups{$defaultGroup} = 1 if defined $defaultGroup;
+        foreach (TagTableKeys($table)) {
+            my @infoArray = GetTagInfoList($table,$_);
+            my ($tagInfo, $groups, $group);
+            if ($groups = $$table{GROUPS} and $group = $$groups{$family}) {
+                $allGroups{$group} = 1;
+            }
+            foreach $tagInfo (@infoArray) {
+                if ($groups = $$tagInfo{Groups} and $group = $$groups{$family}) {
+                    $allGroups{$group} = 1;
+                }
+            }
+        }
+    }
+    return sort keys %allGroups;
+}
+
+#------------------------------------------------------------------------------
+# get priority group list for new values
+# Inputs: 0) ExifTool object reference
+# Returns: List of group names
+sub GetNewGroups($)
+{
+    my $self = shift;
+    return @{$self->{WRITE_GROUPS}};
+}
+
+#------------------------------------------------------------------------------
+# Get list of all deletable group names
+# Returns: List of group names (sorted alphabetically)
+sub GetDeleteGroups()
+{
+    return sort @delGroups;
+}
+
+#==============================================================================
+# Functions below this are not part of the public API
+
+#------------------------------------------------------------------------------
+# convert tag names to values in a string (ie. "${EXIF:ISO}x $$" --> "100x $")
+# Inputs: 0) ExifTool object ref, 1) reference to list of found tags
+#         2) string with embedded tag names, 3) Options:
+#               undef    - set missing tags to '',
+#              'Error'   - issue minor error on missing tag (and return undef),
+#              'Warn'    - issue minor warning on missing tag (and return undef),
+#               Hash ref - hash for return of tag/value pairs
+# Returns: string with embedded tag values (or '$info{TAGNAME}' entries with Hash ref option)
+# Notes: tag names are not case sensitive, uses MissingTagValue option if set
+sub InsertTagValues($$$;$)
+{
+    my ($self, $foundTags, $line, $opt) = @_;
+    my $rtnStr = '';
+    while ($line =~ /(.*?)\$(\{?[\w-]+|\$)(.*)/s) {
+        my (@tags, $pre, $var, $group, $family, $val, $tg, @vals);
+        ($pre, $var, $line) = ($1, $2, $3);
+        # "$$" represents a "$" symbol
+        if ($var eq '$') {
+            $rtnStr .= "$pre$var";
+            next;
+        }
+        # check to see if this is a group name
+        if ($line =~ /^:([\w-]+)(.*)/s) {
+            $group = $var;
+            ($var, $line) = ($1, $2);
+            $line =~ s/^\}// if $group =~ s/^\{//;
+            $var = "$group:$var";
+        } else {
+            $line =~ s/^\}// if $var =~ s/^\{//;
+        }
+        push @tags, $var;
+        ExpandShortcuts(\@tags);
+        @tags or $rtnStr .= $pre, next;
+
+        for (;;) {
+            my $tag = shift @tags;
+            my ($group, $family);
+            if ($tag =~ /(.+?)(\d+)?:(.+)/) {
+                ($group, $family, $tag) = ($1, $2, $3);
+                $group = '*' if lc($group) eq 'all';
+                # find the specified tag
+                my @matches = grep /^$tag(\s|$)/i, @$foundTags;
+                foreach $tg (@matches) {
+                    if ($group ne '*') {
+                        my @groups = $self->GetGroup($tg, $family);
+                        my ($grp) = grep /^$group$/i, @groups;
+                        next unless defined $grp;
+                    }
+                    if (defined $val and $tg =~ / \((\d+)\)$/) {
+                        # take the most recently extracted tag
+                        my $tagNum = $1;
+                        next if $tag !~ / \((\d+)\)$/ or $1 > $tagNum;
+                    }
+                    $val = $self->GetValue($tg);
+                    $tag = $tg;
+                    last unless $tag =~ / /;    # all done if we got our best match
+                }
+            } else {
+                # remove trailing bracket if we had a leading one
+                $val = $self->GetValue($tag);
+                unless (defined $val) {
+                    # check for tag name with different case
+                    ($tg) = grep /^$tag$/i, @$foundTags;
+                    if (defined $tg) {
+                        $val = $self->GetValue($tg);
+                        $tag = $tg;
+                    }
+                }
+            }
+            if (ref $val eq 'ARRAY') {
+                $val = join(', ', @$val);
+            } elsif (ref $val eq 'SCALAR') {
+                $val = $$val;
+            } elsif (not defined $val) {
+                last unless @tags;
+                next;
+            }
+            last unless @tags;
+            push @vals, $val;
+            undef $val;
+        }
+        if (@vals) {
+            push @vals, $val if defined $val;
+            $val = join '', @vals;
+        }
+        unless (defined $val or ref $opt) {
+            $val = $self->{OPTIONS}->{MissingTagValue};
+            unless (defined $val) {
+                no strict 'refs';
+                return undef if $opt and &$opt($self, "Tag '$var' not defined", 1);
+                $val = '';
+            }
+        }
+        if (ref $opt eq 'HASH') {
+            $rtnStr .= "$pre\$info{'$var'}";
+            $$opt{$var} = $val;
+        } else {
+            $rtnStr .= "$pre$val";
+        }
+    }
+    return $rtnStr . $line;
+}
+
+#------------------------------------------------------------------------------
+# Is specified tag writable
+# Inputs: 0) tag name, case insensitive (optional group name currently ignored)
+# Returns: 0=exists but not writable, 1=writable, undef=doesn't exist
+sub IsWritable($)
+{
+    my $tag = shift;
+    $tag =~ s/^(.+)://; # ignore group name
+    my @tagInfo = FindTagInfo($tag);
+    return undef unless @tagInfo;
+    my $tagInfo;
+    foreach $tagInfo (@tagInfo) {
+        return 1 if $$tagInfo{Writable} or $tagInfo->{Table}->{WRITABLE};
+    }
+    return 0;
+}
+
+#------------------------------------------------------------------------------
+# Create directory for specified file
+# Inputs: 0) complete file name including path
+# Returns: 1 = directory created, 0 = nothing done, -1 = error
+sub CreateDirectory($)
+{
+    local $_;
+    my $file = shift;
+    my $rtnVal = 0;
+    my $dir;
+    ($dir = $file) =~ s/[^\/]*$//;  # remove filename from path specification
+    if ($dir and not -d $dir) {
+        my @parts = split /\//, $dir;
+        $dir = '';
+        foreach (@parts) {
+            $dir .= $_;
+            if (length $dir and not -d $dir) {
+                # create directory since it doesn't exist
+                mkdir($dir, 0777) or return -1;
+                $rtnVal = 1;
+            }
+            $dir .= '/';
+        }
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Get new file name
+# Inputs: 0) existing name, 1) new name
+# Returns: new file path name
+sub GetNewFileName($$)
+{
+    my ($oldName, $newName) = @_;
+    my ($dir, $name) = ($oldName =~ m{(.*/)(.*)});
+    ($dir, $name) = ('', $oldName) unless defined $dir;
+    if ($newName =~ m{/$}) {
+        $newName = "$newName$name"; # change dir only
+    } elsif ($newName !~ m{/}) {
+        $newName = "$dir$newName";  # change name only if newname doesn't specify dir
+    }                               # else change dir and name
+    return $newName;
+}
+
+#------------------------------------------------------------------------------
+# Reverse hash lookup
+# Inputs: 0) value, 1) hash reference
+# Returns: Hash key or undef if not found (plus flag for multiple matches in list context)
+sub ReverseLookup($$)
+{
+    my ($val, $conv) = @_;
+    my $multi;
+    if ($val =~ /^Unknown\s*\((.+)\)$/i) {
+        $val = $1;    # was unknown
+        if ($val =~ /^0x([\da-fA-F]+)$/) {
+            $val = hex($val);   # convert hex value
+        }
+    } else {
+        my @patterns = (
+            "^\Q$val\E\$",      # exact match
+            "^(?i)\Q$val\E\$",  # case-insensitive
+            "^(?i)\Q$val\E",    # beginning of string
+            "(?i)\Q$val\E",     # substring
+        );
+        my ($pattern, $found, $matches);
+        foreach $pattern (@patterns) {
+            $matches = scalar grep /$pattern/, values(%$conv);
+            next unless $matches;
+            # multiple matches are bad unless they were exact
+            last if $matches > 1 and $pattern !~ /\$$/;
+            foreach (sort keys %$conv) {
+                if ($$conv{$_} =~ /$pattern/) {
+                    $val = $_;
+                    $found = 1;
+                    last;
+                }
+            }
+            last;
+        }
+        unless ($found) {
+            undef $val;
+            $multi = 1 if $matches > 1;
+        }
+    }
+    if (wantarray) {
+        return ($val, $multi);
+    } else {
+        return $val;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Return true if we are deleting or overwriting the specified tag
+# Inputs: 0) new value hash reference
+#         2) optional tag value if deleting specific values
+# Returns: >0 - tag should be deleted
+#          =0 - the tag should be preserved
+#          <0 - not sure, we need the value to know
+sub IsOverwriting($;$)
+{
+    my ($newValueHash, $value) = @_;
+    return 0 unless $newValueHash;
+    # overwrite regardless if no DelValues specified
+    return 1 unless $newValueHash->{DelValue};
+    # apply time shift if necessary
+    if (defined $newValueHash->{Shift}) {
+        return -1 unless defined $value;
+        my $type = $newValueHash->{TagInfo}->{Shift};
+        my $shift = $newValueHash->{Shift};
+        require 'Image/ExifTool/Shift.pl';
+        my $err = ApplyShift($type, $shift, $value, $newValueHash);
+        if ($err) {
+            my $tag = $newValueHash->{TagInfo}->{Name};
+            $newValueHash->{Self}->Warn("$err when shifting $tag");
+            return 0;
+        }
+        # don't bother overwriting if value is the same
+        return 0 if $value eq $newValueHash->{Value}->[0];
+        return 1;
+    }
+    # never overwrite if DelValue list exists but is empty
+    return 0 unless @{$newValueHash->{DelValue}};
+    # return "don't know" if we don't have a value to test
+    return -1 unless defined $value;
+    # return 1 if value matches a DelValue
+    my $val;
+    foreach $val (@{$newValueHash->{DelValue}}) {
+        return 1 if $value eq $val;
+    }
+    return 0;
+}
+
+#------------------------------------------------------------------------------
+# Return true if we are creating the specified tag even if it didn't exist before
+# Inputs: 0) new value hash reference
+# Returns: true if we should add the tag
+sub IsCreating($)
+{
+    return $_[0]->{IsCreating};
+}
+
+#------------------------------------------------------------------------------
+# Get write group for specified tag
+# Inputs: 0) new value hash reference
+# Returns: Write group name
+sub GetWriteGroup($)
+{
+    return $_[0]->{WriteGroup};
+}
+
+#------------------------------------------------------------------------------
+# Get new value hash for specified tagInfo/writeGroup
+# Inputs: 0) ExifTool object reference, 1) reference to tag info hash
+#         2) Write group name, 3) Options: 'delete' or 'create'
+# Returns: new value hash reference for specified write group
+#          (or first new value hash in linked list if write group not specified)
+sub GetNewValueHash($$;$$)
+{
+    my ($self, $tagInfo, $writeGroup, $opts) = @_;
+    my $newValueHash = $self->{NEW_VALUE}->{$tagInfo};
+
+    my %opts;   # quick lookup for options
+    $opts and $opts{$opts} = 1;
+    $writeGroup = '' unless defined $writeGroup;
+
+    if ($writeGroup) {
+        # find the new value in the list with the specified write group
+        while ($newValueHash and $newValueHash->{WriteGroup} ne $writeGroup) {
+            $newValueHash = $newValueHash->{Next};
+        }
+    }
+    # remove this entry if deleting, or if creating a new entry and
+    # this entry is marked with "Save" flag
+    if (defined $newValueHash and ($opts{'delete'} or
+        ($opts{'create'} and $newValueHash->{Save})))
+    {
+        $self->RemoveNewValueHash($newValueHash, $tagInfo);
+        undef $newValueHash;
+    }
+    if (not defined $newValueHash and $opts{'create'}) {
+        # create a new entry
+        $newValueHash = {
+            TagInfo => $tagInfo,
+            WriteGroup => $writeGroup,
+            Self => $self,
+        };
+        # add entry to our NEW_VALUE hash
+        if ($self->{NEW_VALUE}->{$tagInfo}) {
+            # add to end of linked list
+            my $lastHash = LastInList($self->{NEW_VALUE}->{$tagInfo});
+            $lastHash->{Next} = $newValueHash;
+        } else {
+            $self->{NEW_VALUE}->{$tagInfo} = $newValueHash;
+        }
+    }
+    return $newValueHash;
+}
+
+#------------------------------------------------------------------------------
+# Load all tag tables
+sub LoadAllTables()
+{
+    unless ($loadedAllTables) {
+        # load all of our non-referenced tables (first our modules)
+        my $table;
+        foreach $table (@loadAllTables) {
+            my $tableName = "Image::ExifTool::$table";
+            $tableName .= '::Main' unless $table =~ /:/;
+            GetTagTable($tableName);
+        }
+        # (then our special tables)
+        GetTagTable('Image::ExifTool::Extra');
+        GetTagTable('Image::ExifTool::Composite');
+        # recursively load all tables referenced by the current tables
+        my @tableNames = ( keys %allTables );
+        my %pushedTables;
+        while (@tableNames) {
+            $table = GetTagTable(shift @tableNames);
+            # call write proc if it exists in case it adds tags to the table
+            my $writeProc = $table->{WRITE_PROC};
+            $writeProc and &$writeProc();
+            # recursively scan through tables in subdirectories
+            foreach (TagTableKeys($table)) {
+                my @infoArray = GetTagInfoList($table,$_);
+                my $tagInfo;
+                foreach $tagInfo (@infoArray) {
+                    my $subdir = $$tagInfo{SubDirectory} or next;
+                    my $tableName = $$subdir{TagTable} or next;
+                    # next if table already loaded or queued for loading
+                    next if $allTables{$tableName} or $pushedTables{$tableName};
+                    push @tableNames, $tableName;   # must scan this one too
+                    $pushedTables{$tableName} = 1;
+                }
+            }
+        }
+        $loadedAllTables = 1;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Remove new value hash from linked list (and save if necessary)
+# Inputs: 0) ExifTool object reference, 1) new value hash ref, 2) tagInfo ref
+sub RemoveNewValueHash($$$)
+{
+    my ($self, $newValueHash, $tagInfo) = @_;
+    my $firstHash = $self->{NEW_VALUE}->{$tagInfo};
+    if ($newValueHash eq $firstHash) {
+        # remove first entry from linked list
+        if ($newValueHash->{Next}) {
+            $self->{NEW_VALUE}->{$tagInfo} = $newValueHash->{Next};
+        } else {
+            delete $self->{NEW_VALUE}->{$tagInfo};
+        }
+    } else {
+        # find the list element pointing to this hash
+        $firstHash = $firstHash->{Next} while $firstHash->{Next} ne $newValueHash;
+        # remove from linked list
+        $firstHash->{Next} = $newValueHash->{Next};
+    }
+    # save the existing entry if necessary
+    if ($newValueHash->{Save}) {
+        my $saveHash = $self->{SAVE_NEW_VALUE};
+        # add to linked list of saved new value hashes
+        $newValueHash->{Next} = $saveHash->{$tagInfo};
+        $saveHash->{$tagInfo} = $newValueHash;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Remove all new value entries for specified group
+# Inputs: 0) ExifTool object reference, 1) group name
+sub RemoveNewValuesForGroup($$)
+{
+    my ($self, $group) = @_;
+
+    return unless $self->{NEW_VALUE};
+
+    # make list of all groups we must remove
+    my @groups = ( $group );
+    push @groups, @{$removeGroups{$group}} if $removeGroups{$group};
+
+    my ($out, @keys, $hashKey);
+    $out = $self->{OPTIONS}->{TextOut} if $self->{OPTIONS}->{Verbose} > 1;
+
+    # loop though all new values, and remove any in this group
+    @keys = keys %{$self->{NEW_VALUE}};
+    foreach $hashKey (@keys) {
+        my $newValueHash = $self->{NEW_VALUE}->{$hashKey};
+        # loop through each entry in linked list
+        for (;;) {
+            my $nextHash = $newValueHash->{Next};
+            my $tagInfo = $newValueHash->{TagInfo};
+            my $grp0 = $self->GetGroup($tagInfo, 0);
+            my $wgrp = $newValueHash->{WriteGroup};
+            if (grep /^($grp0|$wgrp)$/, @groups) {
+                $out and print $out "Removed new value for $wgrp:$$tagInfo{Name}\n";
+                # remove from linked list
+                $self->RemoveNewValueHash($newValueHash, $tagInfo);
+            }
+            $newValueHash = $nextHash or last;
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# Get list of tagInfo hashes for all new data
+# Inputs: 0) ExifTool object reference, 1) optional tag table pointer
+# Returns: list of tagInfo hashes
+sub GetNewTagInfoList($;$)
+{
+    my ($self, $tagTablePtr) = @_;
+    my @tagInfoList;
+    if ($self->{NEW_VALUE}) {
+        my $hashKey;
+        foreach $hashKey (keys %{$self->{NEW_VALUE}}) {
+            my $tagInfo = $self->{NEW_VALUE}->{$hashKey}->{TagInfo};
+            next if $tagTablePtr and $tagTablePtr ne $tagInfo->{Table};
+            push @tagInfoList, $tagInfo;
+        }
+    }
+    return @tagInfoList;
+}
+
+#------------------------------------------------------------------------------
+# Get hash of tagInfo references keyed on tagID for a specific table
+# Inputs: 0) ExifTool object reference, 1-N) tag table pointers
+# Returns: hash reference
+sub GetNewTagInfoHash($@)
+{
+    my $self = shift;
+    my (%tagInfoHash, $hashKey);
+    while ($self->{NEW_VALUE}) {
+        my $tagTablePtr = shift || last;
+        GenerateTagIDs($tagTablePtr);  # make sure IDs are generated
+        foreach $hashKey (keys %{$self->{NEW_VALUE}}) {
+            my $tagInfo = $self->{NEW_VALUE}->{$hashKey}->{TagInfo};
+            next if $tagTablePtr and $tagTablePtr ne $tagInfo->{Table};
+            $tagInfoHash{$$tagInfo{TagID}} = $tagInfo;
+        }
+    }
+    return \%tagInfoHash;
+}
+
+#------------------------------------------------------------------------------
+# Get a tagInfo/tagID hash for subdirectories we need to add
+# Inputs: 0) ExifTool object reference, 1) parent tag table reference
+#         2) parent directory name (taken from GROUP0 of tag table if not defined)
+# Returns: Reference to Hash of subdirectory tagInfo references keyed by tagID
+#          (plus Reference to edit directory hash in list context)
+sub GetAddDirHash($$;$)
+{
+    my ($self, $tagTablePtr, $parent) = @_;
+    $parent or $parent = $tagTablePtr->{GROUPS}->{0};
+    my $tagID;
+    my %addDirHash;
+    my %editDirHash;
+    my $addDirs = $self->{ADD_DIRS};
+    my $editDirs = $self->{EDIT_DIRS};
+    foreach $tagID (TagTableKeys($tagTablePtr)) {
+        my @infoArray = GetTagInfoList($tagTablePtr,$tagID);
+        my $tagInfo;
+        foreach $tagInfo (@infoArray) {
+            next unless $$tagInfo{SubDirectory};
+            # get name for this sub directory
+            # (take directory name from SubDirectory DirName if it exists,
+            #  otherwise Group0 name of SubDirectory TagTable or tag Group1 name)
+            my $dirName = $tagInfo->{SubDirectory}->{DirName};
+            unless ($dirName) {
+                # use tag name for directory name and save for next time
+                $dirName = $$tagInfo{Name};
+                $tagInfo->{SubDirectory}->{DirName} = $dirName;
+            }
+            # save this directory information if we are writing it
+            if ($$editDirs{$dirName} and $$editDirs{$dirName} eq $parent) {
+                $editDirHash{$tagID} = $tagInfo;
+                $addDirHash{$tagID} = $tagInfo if $$addDirs{$dirName};
+            }
+        }
+    }
+    if (wantarray) {
+        return (\%addDirHash, \%editDirHash);
+    } else {
+        return \%addDirHash;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Get localized version of tagInfo hash (used by MIE and XMP)
+# Inputs: 0) tagInfo hash ref, 1) locale code (ie. "en_CA" for MIE)
+# Returns: new tagInfo hash ref, or undef if invalid
+# - sets LangCode member in new tagInfo
+sub GetLangInfo($$)
+{
+    my ($tagInfo, $langCode) = @_;
+    # make a new tagInfo hash for this locale
+    my $table = $$tagInfo{Table};
+    Image::ExifTool::GenerateTagIDs($table);
+    my $tagID = $$tagInfo{TagID} . '-' . $langCode;
+    my $langInfo = $$table{$tagID};
+    unless ($langInfo) {
+        # make a new tagInfo entry for this locale
+        $langInfo = {
+            %$tagInfo,
+            Name => $$tagInfo{Name} . '-' . $langCode,
+            Description => Image::ExifTool::MakeDescription($$tagInfo{Name}) .
+                           " ($langCode)",
+            LangCode => $langCode,
+        };
+        AddTagToTable($table, $tagID, $langInfo);
+    }
+    return $langInfo;
+}
+
+#------------------------------------------------------------------------------
+# initialize ADD_DIRS and EDIT_DIRS hashes for all directories that need
+# need to be created or will have tags changed in them
+# Inputs: 0) ExifTool object reference, 1) file type string (or map hash ref)
+#         2) preferred family 0 group name for creating tags
+sub InitWriteDirs($$;$)
+{
+    my ($self, $fileType, $preferredGroup) = @_;
+    my $editDirs = $self->{EDIT_DIRS} = { };
+    my $addDirs = $self->{ADD_DIRS} = { };
+    my $fileDirs = $dirMap{$fileType};
+    unless ($fileDirs) {
+        return unless ref $fileType eq 'HASH';
+        $fileDirs = $fileType;
+    }
+    my @tagInfoList = $self->GetNewTagInfoList();
+    my $tagInfo;
+    foreach $tagInfo (@tagInfoList) {
+        my $newValueHash = $self->GetNewValueHash($tagInfo);
+        for (;;) {
+            # are we creating this tag? (otherwise just deleting or editing it)
+            my $isCreating = $newValueHash->{IsCreating};
+            # tag belongs to directory specified by WriteGroup, or by
+            # the Group0 name if WriteGroup not defined
+            my $dirName = $newValueHash->{WriteGroup};
+            # remove MIE copy number(s) if they exist
+            if ($dirName =~ /^MIE\d*(-[a-z]+)?\d*$/i) {
+                $dirName = 'MIE' . ($1 || '');
+            }
+            my @dirNames;
+            while ($dirName) {
+                my $parent = $$fileDirs{$dirName};
+                if (ref $parent) {
+                    push @dirNames, reverse @$parent;
+                    $parent = pop @dirNames;
+                }
+                $$editDirs{$dirName} = $parent;
+                # (if another group is taking priority, only create
+                # directory if specifically adding tags to this group
+                # or if this tag isn't being added to the priority group
+                if ($isCreating and (not $preferredGroup or
+                    $preferredGroup eq $self->GetGroup($tagInfo, 0) or not
+                    $newValueHash->{CreateGroups}->{$preferredGroup}))
+                {
+                    $$addDirs{$dirName} = $parent;
+                }
+                $dirName = $parent || shift @dirNames
+            }
+            last unless $newValueHash->{Next};
+            # cycle through all hashes in linked list
+            $newValueHash = $newValueHash->{Next};
+        }
+    }
+    if (%{$self->{DEL_GROUP}}) {
+        # add delete groups to list of edited groups
+        foreach (keys %{$self->{DEL_GROUP}}) {
+            my $dirName = $_;
+            # translate necessary group 0 names
+            $dirName = $translateWriteGroup{$dirName} if $translateWriteGroup{$dirName};
+            my @dirNames;
+            while ($dirName) {
+                my $parent = $$fileDirs{$dirName};
+                if (ref $parent) {
+                    push @dirNames, reverse @$parent;
+                    $parent = pop @dirNames;
+                }
+                $$editDirs{$dirName} = $parent;
+                $dirName = $parent || shift @dirNames
+            }
+        }
+    }
+    # special case to edit JFIF to get resolutions if editing EXIF information
+    if ($$editDirs{IFD0} and $$fileDirs{JFIF}) {
+        $$editDirs{JFIF} = 'IFD1';
+        $$editDirs{APP0} = undef;
+    }
+  
+    if ($self->{OPTIONS}->{Verbose}) {
+        my $out = $self->{OPTIONS}->{TextOut};
+        print $out "  Editing tags in: ";
+        foreach (sort keys %$editDirs) { print $out "$_ "; }
+        print $out "\n";
+        return unless $self->{OPTIONS}->{Verbose} > 1;
+        print $out "  Creating tags in: ";
+        foreach (sort keys %$addDirs) { print $out "$_ "; }
+        print $out "\n";
+    }
+}
+
+#------------------------------------------------------------------------------
+# Write an image directory
+# Inputs: 0) ExifTool object reference, 1) source directory information reference
+#         2) tag table reference, 3) optional reference to writing procedure
+# Returns: New directory data or undefined on error
+sub WriteDirectory($$$;$)
+{
+    my ($self, $dirInfo, $tagTablePtr, $writeProc) = @_;
+
+    $tagTablePtr or return undef;
+    my $out;
+    $out = $self->{OPTIONS}->{TextOut} if $self->{OPTIONS}->{Verbose};
+    # set directory name from default group0 name if not done already
+    my $dirName = $$dirInfo{DirName};
+    my $grp0 = $tagTablePtr->{GROUPS}->{0};
+    $dirName or $dirName = $$dirInfo{DirName} = $grp0;
+    if (%{$self->{DEL_GROUP}}) {
+        my $delGroup = $self->{DEL_GROUP};
+        # delete entire directory if specified
+        my $grp1 = $dirName;
+        my $delFlag = ($$delGroup{$grp0} or $$delGroup{$grp1});
+        if ($delFlag) {
+            unless ($self->{FILE_TYPE} =~ /^(JPEG|PNG|JP2)$/) {
+                # restrict delete logic to prevent entire tiff image from being killed
+                # (don't allow IFD0 to be deleted, and delete only ExifIFD if EXIF specified)
+                if ($grp1 eq 'IFD0') {
+                    my $type = $self->{TIFF_TYPE} || $self->{FILE_TYPE};
+                    $$delGroup{IFD0} and $self->Warn("Can't delete IFD0 from $type image",1);
+                    undef $grp1;
+                } elsif ($grp0 eq 'EXIF' and $$delGroup{$grp0}) {
+                    undef $grp1 unless $$delGroup{$grp1} or $grp1 eq 'ExifIFD';
+                }
+            }
+            if ($grp1) {
+                if ($$dirInfo{DataPt} or $$dirInfo{RAF}) {
+                    ++$self->{CHANGED};
+                    $out and print $out "  Deleting $grp1\n";
+                    # can no longer validate TIFF_END if deleting an entire IFD
+                    delete $self->{TIFF_END} if $dirName =~ /IFD/;
+                }
+                if ($delFlag == 2 and $self->{ADD_DIRS}->{$grp1}) {
+                    # create new empty directory
+                    my $data = '';
+                    my %dirInfo = (
+                        DirName => $$dirInfo{DirName},
+                        DirStart => 0,
+                        DirLen => 0,
+                        NewDataPos => $$dirInfo{NewDataPos},
+                        Fixup => $$dirInfo{Fixup},
+                    );
+                    $dirInfo = \%dirInfo;
+                } else {
+                    return '';
+                }
+            }
+        }
+    }
+    # copy or delete new directory as a block if specified
+    my $tagInfo = $Image::ExifTool::Extra{$dirName};
+    if ($tagInfo and $self->{NEW_VALUE}->{$tagInfo}) {
+        my $newVal = GetNewValues($self->{NEW_VALUE}->{$tagInfo});
+        if (defined $newVal and length $newVal) {
+            $out and print $out "  Writing $dirName as a block\n";
+            ++$self->{CHANGED};
+            return $newVal;
+        } else {
+            $out and print $out "  Deleting $dirName as a block\n";
+            ++$self->{CHANGED};
+            return '';
+        }
+    }
+    # use default proc from tag table if no proc specified
+    $writeProc or $writeProc = $$tagTablePtr{WRITE_PROC} or return undef;
+    # guard against writing the same directory twice
+    if (defined $$dirInfo{DataPt} and defined $$dirInfo{DirStart} and defined $$dirInfo{DataPos}) {
+        my $addr = $$dirInfo{DirStart} + $$dirInfo{DataPos} + ($$dirInfo{Base}||0);
+        if ($self->{PROCESSED}->{$addr}) {
+            if ($self->Error("$dirName pointer references previous $self->{PROCESSED}->{$addr} directory", 1)) {
+                return undef;
+            } else {
+                $self->Warn("Deleting duplicate $dirName directory");
+                $out and print $out "  Deleting $dirName\n";
+                return '';  # delete the duplicate directory
+            }
+        }
+        $self->{PROCESSED}->{$addr} = $dirName;
+    }
+    # be sure the tag ID's are generated, because the write proc will need them
+    GenerateTagIDs($tagTablePtr);
+    my $oldDir = $self->{DIR_NAME};
+    if ($out and (not defined $oldDir or $oldDir ne $dirName)) {
+        my $verb = ($$dirInfo{DataPt} or $$dirInfo{DirLen}) ? 'Rewriting' : 'Creating';
+        print $out "  $verb $dirName\n";
+    }
+    my $saveOrder = GetByteOrder();
+    my $oldChanged = $self->{CHANGED};
+    $self->{DIR_NAME} = $dirName;
+    my $newData = &$writeProc($self, $dirInfo, $tagTablePtr);
+    $self->{DIR_NAME} = $oldDir;
+    $self->{CHANGED} = $oldChanged unless defined $newData; # nothing changed if error occurred
+    SetByteOrder($saveOrder);
+    print $out "  Deleting $dirName\n" if $out and defined $newData and not length $newData;
+    return $newData;
+}
+
+#------------------------------------------------------------------------------
+# Uncommon utility routines to for reading binary data values
+# Inputs: 0) data reference, 1) offset into data
+sub Get64s($$)
+{
+    my ($dataPt, $pos) = @_;
+    my $pt = GetByteOrder() eq 'MM' ? 0 : 4;    # get position of high word
+    my $hi = Get32s($dataPt, $pos + $pt);       # preserve sign bit of high word
+    my $lo = Get32u($dataPt, $pos + 4 - $pt);
+    return $hi * 4294967296 + $lo;
+}
+sub Get64u($$)
+{
+    my ($dataPt, $pos) = @_;
+    my $pt = GetByteOrder() eq 'MM' ? 0 : 4;    # get position of high word
+    my $hi = Get32u($dataPt, $pos + $pt);       # (unsigned this time)
+    my $lo = Get32u($dataPt, $pos + 4 - $pt);
+    return $hi * 4294967296 + $lo;
+}
+# Decode extended 80-bit float used by Apple SANE and Intel 8087
+# (note: different than the IEEE standard 80-bit float)
+sub GetExtended($$)
+{
+    my ($dataPt, $pos) = @_;
+    my $pt = GetByteOrder() eq 'MM' ? 0 : 2;    # get position of exponent
+    my $exp = Get16u($dataPt, $pos + $pt);
+    my $sig = Get64u($dataPt, $pos + 2 - $pt);  # get significand as int64u
+    my $sign = $exp & 0x8000 ? -1 : 1;
+    $exp = ($exp & 0x7fff) - 16383 - 63; # (-63 to fractionalize significand)
+    return $sign * $sig * 2 ** $exp;
+}
+
+#------------------------------------------------------------------------------
+# Dump data in hex and ASCII to console
+# Inputs: 0) data reference, 1) length or undef, 2-N) Options:
+# Options: Start => offset to start of data (default=0)
+#          Addr => address to print for data start (default=DataPos+Start)
+#          DataPos => address of start of data
+#          Width => width of printout (bytes, default=16)
+#          Prefix => prefix to print at start of line (default='')
+#          MaxLen => maximum length to dump
+#          Out => output file reference
+sub HexDump($;$%)
+{
+    my $dataPt = shift;
+    my $len    = shift;
+    my %opts   = @_;
+    my $start  = $opts{Start}  || 0;
+    my $addr   = $opts{Addr};
+    my $wid    = $opts{Width}  || 16;
+    my $prefix = $opts{Prefix} || '';
+    my $out    = $opts{Out}    || \*STDOUT;
+    my $maxLen = $opts{MaxLen};
+    my $datLen = length($$dataPt) - $start;
+    my $more;
+
+    $addr = $start + ($opts{DataPos} || 0) unless defined $addr;
+    if (not defined $len) {
+        $len = $datLen;
+    } elsif ($len > $datLen) {
+        print $out "$prefix    Warning: Attempted dump outside data\n";
+        print $out "$prefix    ($len bytes specified, but only $datLen available)\n";
+        $len = $datLen;
+    }
+    if ($maxLen and $len > $maxLen) {
+        # print one line less to allow for $more line below
+        $maxLen = int(($maxLen - 1) / $wid) * $wid;
+        $more = $len - $maxLen;
+        $len = $maxLen;
+    }
+    my $format = sprintf("%%-%ds", $wid * 3);
+    my $i;
+    for ($i=0; $i<$len; $i+=$wid) {
+        $wid > $len-$i and $wid = $len-$i;
+        printf $out "$prefix%8.4x: ", $addr+$i;
+        my $dat = substr($$dataPt, $i+$start, $wid);
+        my $s = join(' ',(unpack('H*',$dat) =~ /../g));
+        printf $out $format, $s;
+        $dat =~ tr /\x00-\x1f\x7f-\xff/./;
+        print $out "[$dat]\n";
+    }
+    $more and printf $out "$prefix    [snip $more bytes]\n";
+}
+
+#------------------------------------------------------------------------------
+# Print verbose tag information
+# Inputs: 0) ExifTool object reference, 1) tag ID
+#         2) tag info reference (or undef)
+#         3-N) extra parms:
+# Parms: Index => Index of tag in menu (starting at 0)
+#        Value => Tag value
+#        DataPt => reference to value data block
+#        DataPos => location of data block in file
+#        Size => length of value data within block
+#        Format => value format string
+#        Count => number of values
+#        Extra => Extra Verbose=2 information to put after tag number
+#        Table => Reference to tag table
+#        --> plus any of these HexDump() options: Start, Addr, Width
+sub VerboseInfo($$$%)
+{
+    my ($self, $tagID, $tagInfo, %parms) = @_;
+    my $verbose = $self->{OPTIONS}->{Verbose};
+    my $out = $self->{OPTIONS}->{TextOut};
+    my ($tag, $tagDesc, $line, $hexID);
+
+    # generate hex number if tagID is numerical
+    if (defined $tagID) {
+        $tagID =~ /^\d+$/ and $hexID = sprintf("0x%.4x", $tagID);
+    } else {
+        $tagID = 'Unknown';
+    }
+    # get tag name
+    if ($tagInfo and $$tagInfo{Name}) {
+        $tag = $$tagInfo{Name};
+    } else {
+        my $prefix;
+        $prefix = $parms{Table}->{TAG_PREFIX} if $parms{Table};
+        if ($prefix or $hexID) {
+            $prefix = 'Unknown' unless $prefix;
+            $tag = $prefix . '_' . ($hexID ? $hexID : $tagID);
+        } else {
+            $tag = $tagID;
+        }
+    }
+    my $dataPt = $parms{DataPt};
+    my $size = $parms{Size};
+    $size = length $$dataPt unless defined $size or not $dataPt;
+    my $indent = $self->{INDENT};
+
+    # Level 1: print tag/value information
+    $line = $indent;
+    my $index = $parms{Index};
+    if (defined $index) {
+        $line .= $index . ') ';
+        $line .= ' ' if $index < 10;
+        $indent .= '    '; # indent everything else to align with tag name
+    }
+    $line .= $tag;
+    if ($tagInfo and $$tagInfo{SubDirectory}) {
+        $line .= ' (SubDirectory) -->';
+    } elsif (defined $parms{Value}) {
+        $line .= ' = ' . $self->Printable($parms{Value});
+    } elsif ($dataPt) {
+        my $start = $parms{Start} || 0;
+        $line .= ' = ' . $self->Printable(substr($$dataPt,$start,$size));
+    }
+    print $out "$line\n";
+
+    # Level 2: print detailed information about the tag
+    if ($verbose > 1 and ($parms{Extra} or $parms{Format} or
+        $parms{DataPt} or defined $size or $tagID =~ /\//))
+    {
+        $line = $indent;
+        $line .= '- Tag ' . ($hexID ? $hexID : "'$tagID'");
+        $line .= $parms{Extra} if defined $parms{Extra};
+        my $format = $parms{Format};
+        if ($format or defined $size) {
+            $line .= ' (';
+            if (defined $size) {
+                $line .= "$size bytes";
+                $line .= ', ' if $format;
+            }
+            if ($format) {
+                $line .= $format;
+                $line .= '['.$parms{Count}.']' if $parms{Count};
+            }
+            $line .= ')';
+        }
+        $line .= ':' if $verbose > 2 and $parms{DataPt};
+        print $out "$line\n";
+    }
+
+    # Level 3: do hex dump of value
+    if ($verbose > 2 and $parms{DataPt}) {
+        $parms{Out} = $out;
+        $parms{Prefix} = $indent;
+        # limit dump length unless verbose > 3
+        $parms{MaxLen} = 96 unless $verbose > 3;
+        HexDump($dataPt, $size, %parms);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Dump trailer information
+# Inputs: 0) ExifTool object ref, 1) dirInfo hash (RAF, DirName, DataPos, DirLen)
+# Notes: Restores current file position before returning
+sub DumpTrailer($$)
+{
+    my ($self, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $curPos = $raf->Tell();
+    my $trailer = $$dirInfo{DirName} || 'Unknown';
+    my $pos = $$dirInfo{DataPos};
+    my $verbose = $self->{OPTIONS}->{Verbose};
+    my $htmlDump = $self->{HTML_DUMP};
+    my ($buff, $buf2);
+    my $size = $$dirInfo{DirLen};
+    $pos = $curPos unless defined $pos;
+
+    # get full trailer size if not specified
+    for (;;) {
+        unless ($size) {
+            $raf->Seek(0, 2) or last;
+            $size = $raf->Tell() - $pos;
+            last unless $size;
+        }
+        $raf->Seek($pos, 0) or last;
+        if ($htmlDump) {
+            my $num = $raf->Read($buff, $size) or return;
+            my $desc = "$trailer trailer";
+            $desc = "[$desc]" if $trailer eq 'Unknown';
+            $self->HtmlDump($pos, $num, $desc, undef, 0x08);
+            last;
+        }
+        my $out = $self->{OPTIONS}->{TextOut};
+        printf $out "$trailer trailer (%d bytes at offset 0x%.4x):\n", $size, $pos;
+        last unless $verbose > 2;
+        my $num = $size;    # number of bytes to read
+        # limit size if not very verbose
+        if ($verbose < 5) {
+            my $limit = $verbose < 4 ? 96 : 512;
+            $num = $limit if $num > $limit;
+        }
+        $raf->Read($buff, $num) == $num or return;
+        # read the end of the trailer too if not done already
+        if ($size > 2 * $num) {
+            $raf->Seek($pos + $size - $num, 0);
+            $raf->Read($buf2, $num);
+        } elsif ($size > $num) {
+            $raf->Seek($pos + $num, 0);
+            $raf->Read($buf2, $size - $num);
+            $buff .= $buf2;
+            undef $buf2;
+        }
+        HexDump(\$buff, undef, Addr => $pos, Out => $out);
+        if (defined $buf2) {
+            print "    [snip ", $size - $num * 2, " bytes]\n";
+            HexDump(\$buf2, undef, Addr => $pos + $size - $num, Out => $out);
+        }
+        last;
+    }
+    $raf->Seek($curPos, 0);
+}
+
+#------------------------------------------------------------------------------
+# Dump unknown trailer information
+# Inputs: 0) ExifTool ref, 1) dirInfo ref (with RAF, DataPos and DirLen defined)
+# Notes: changes dirInfo elements
+sub DumpUnknownTrailer($$)
+{
+    my ($self, $dirInfo) = @_;
+    my $pos = $$dirInfo{DataPos};
+    my $endPos = $pos + $$dirInfo{DirLen};
+    # account for preview image trailer
+    my $prePos = $self->{VALUE}->{PreviewImageStart};
+    my $preLen = $self->{VALUE}->{PreviewImageLength};
+    if ($prePos and $preLen and $prePos + $preLen > $pos) {
+        # dump data before preview image
+        if ($prePos > $pos) {
+            $$dirInfo{DirName} = 'Unknown';
+            $$dirInfo{DirLen}  = $prePos - $pos;
+            $self->DumpTrailer($dirInfo);
+        }
+        # dump preview image if verbose (it is htmlDump'd by ExtractImage)
+        if ($self->{OPTIONS}->{Verbose}) {
+            $$dirInfo{DirName} = 'PreviewImage';
+            $$dirInfo{DataPos} = $prePos;
+            $$dirInfo{DirLen}  = $preLen;
+            $self->DumpTrailer($dirInfo);
+        }
+        return if $prePos + $preLen >= $endPos;
+        # set dirInfo for remaining unknown data
+        $$dirInfo{DataPos} = $prePos + $preLen;
+        $$dirInfo{DirLen} = $endPos - $$dirInfo{DataPos};
+    }
+    # dump unknown trailer
+    $$dirInfo{DirName} = 'Unknown';
+    $self->DumpTrailer($dirInfo);
+}
+
+#------------------------------------------------------------------------------
+# Find last element in linked list
+# Inputs: 0) element in list
+# Returns: Last element in list
+sub LastInList($)
+{
+    my $element = shift;
+    while ($element->{Next}) {
+        $element = $element->{Next};
+    }
+    return $element;
+}
+
+#------------------------------------------------------------------------------
+# Print verbose directory information
+# Inputs: 0) ExifTool object reference, 1) directory name or dirInfo ref
+#         2) number of entries in directory (or 0 if unknown)
+#         3) optional size of directory in bytes
+sub VerboseDir($$;$$)
+{
+    my ($self, $name, $entries, $size) = @_;
+    return unless $self->{OPTIONS}->{Verbose};
+    if (ref $name eq 'HASH') {
+        $size = $$name{DirLen} unless $size;
+        $name = $$name{Name} || $$name{DirName};
+    }
+    my $indent = substr($self->{INDENT}, 0, -2);
+    my $out = $self->{OPTIONS}->{TextOut};
+    my $str;
+    if ($entries) {
+        $str = " with $entries entries";
+    } elsif ($size) {
+        $str = ", $size bytes";
+    } else {
+        $str = '';
+    }
+    print $out "$indent+ [$name directory$str]\n";
+}
+
+#------------------------------------------------------------------------------
+# Pack Unicode numbers into UTF8 string
+# Inputs: 0-N) list of Unicode numbers
+# Returns: Packed UTF-8 string
+sub PackUTF8(@)
+{
+    my @out;
+    while (@_) {
+        my $ch = pop;
+        unshift(@out, $ch), next if $ch < 0x80;
+        unshift(@out, 0x80 | ($ch & 0x3f));
+        $ch >>= 6;
+        unshift(@out, 0xc0 | $ch), next if $ch < 0x20;
+        unshift(@out, 0x80 | ($ch & 0x3f));
+        $ch >>= 6;
+        unshift(@out, 0xe0 | $ch), next if $ch < 0x10;
+        unshift(@out, 0x80 | ($ch & 0x3f));
+        $ch >>= 6;
+        unshift(@out, 0xf0 | ($ch & 0x07));
+    }
+    return pack('C*', @out);
+}
+
+#------------------------------------------------------------------------------
+# Unpack numbers from UTF8 string
+# Inputs: 0) UTF-8 string
+# Returns: List of Unicode numbers (sets $evalWarning on error)
+sub UnpackUTF8($)
+{
+    my (@out, $pos);
+    pos($_[0]) = $pos = 0;  # start at beginning of string
+    for (;;) {
+        my ($ch, $newPos, $val, $byte);
+        if ($_[0] =~ /([\x80-\xff])/g) {
+            $ch = ord($1);
+            $newPos = pos($_[0]) - 1;
+        } else {
+            $newPos = length $_[0];
+        }
+        # unpack 7-bit characters
+        my $len = $newPos - $pos;
+        push @out, unpack("x${pos}C$len",$_[0]) if $len;
+        last unless defined $ch;
+        $pos = $newPos + 1;
+        # minimum lead byte for 2-byte sequence is 0xc2 (overlong sequences
+        # not allowed), 0xf8-0xfd are restricted by RFC 3629 (no 5 or 6 byte
+        # sequences), and 0xfe and 0xff are not valid in UTF-8 strings
+        if ($ch < 0xc2 or $ch >= 0xf8) {
+            push @out, ord('?');    # invalid UTF-8
+            $evalWarning = 'Bad UTF-8';
+            next;
+        }
+        # decode 2, 3 and 4-byte sequences
+        my $n = 1;
+        if ($ch < 0xe0) {
+            $val = $ch & 0x1f;      # 2-byte sequence
+        } elsif ($ch < 0xf0) {
+            $val = $ch & 0x0f;      # 3-byte sequence
+            ++$n;
+        } else {
+            $val = $ch & 0x07;      # 4-byte sequence
+            $n += 2;
+        }
+        unless ($_[0] =~ /\G([\x80-\xbf]{$n})/g) {
+            pos($_[0]) = $pos;      # restore position
+            push @out, ord('?');    # invalid UTF-8
+            $evalWarning = 'Bad UTF-8';
+            next;
+        }
+        foreach $byte (unpack 'C*', $1) {
+            $val = ($val << 6) | ($byte & 0x3f);
+        }
+        push @out, $val;    # save Unicode character value
+        $pos += $n;         # position at end of UTF-8 character
+    }
+    return @out;
+}
+
+#------------------------------------------------------------------------------
+# Convert Unicode characters to Windows Latin1 (cp1252)
+# Inputs: 0) 16-bit Unicode character string, 1) unpack format
+#         3) optional ExifTool ref to set warning on encoding error
+# Returns: 8-bit Windows Latin1 encoded string (truncates at null terminator)
+my %unicode2latin = (
+    0x20ac => 0x80,  0x0160 => 0x8a,  0x2013 => 0x96,
+    0x201a => 0x82,  0x2039 => 0x8b,  0x2014 => 0x97,
+    0x0192 => 0x83,  0x0152 => 0x8c,  0x02dc => 0x98,
+    0x201e => 0x84,  0x017d => 0x8e,  0x2122 => 0x99,
+    0x2026 => 0x85,  0x2018 => 0x91,  0x0161 => 0x9a,
+    0x2020 => 0x86,  0x2019 => 0x92,  0x203a => 0x9b,
+    0x2021 => 0x87,  0x201c => 0x93,  0x0153 => 0x9c,
+    0x02c6 => 0x88,  0x201d => 0x94,  0x017e => 0x9e,
+    0x2030 => 0x89,  0x2022 => 0x95,  0x0178 => 0x9f,
+);
+sub Unicode2Latin($$;$)
+{
+    my ($val, $fmt) = @_;
+    my @uni = unpack("$fmt*",$val);
+    foreach (@uni) {
+        next if $_ <= 0xff;
+        $_ = $unicode2latin{$_};
+        next if $_;
+        $_ = ord('?');  # set to '?'
+        my $self = $_[2];
+        if ($self and not $$self{LatinWarning}) {
+            $self->Warn('Some character(s) could not be encoded in Latin');
+            $$self{LatinWarning} = 1;
+        }
+    }
+    # repack as a Latin string
+    my $outVal = pack('C*', @uni);
+    $outVal =~ s/\0.*//s;    # truncate at null terminator
+    return $outVal;
+}
+
+#------------------------------------------------------------------------------
+# Convert Windows Latin1 characters to Unicode
+# Inputs: 0) 8-bit Windows Latin1 character string (cp1252), 1) unpack format
+# Returns: 16-bit Unicode character string
+my %latin2unicode;
+sub Latin2Unicode($$)
+{
+    # create reverse lookup table if necessary
+    unless (%latin2unicode) {
+        foreach (keys %unicode2latin) {
+            $latin2unicode{$unicode2latin{$_}} = $_;
+        }
+    }
+    my ($val, $fmt) = @_;
+    my @latin = unpack('C*', $val);
+    foreach (@latin) {
+        $_ = $latin2unicode{$_} if $latin2unicode{$_};
+    }
+    # repack as a 16-bit unicode string
+    my $outVal = pack("$fmt*", @latin);
+    return $outVal;
+}
+
+#------------------------------------------------------------------------------
+# Convert Unicode characters to UTF-8
+# Inputs: 0) Unicode character string, 1) Unicode character format (n,v,N,V)
+# Returns: UTF-8 encoded string (truncates at null terminator)
+sub Unicode2UTF8($$)
+{
+    my ($val, $fmt) = @_;
+    my $outVal;
+    if ($] >= 5.006001) {
+        # let Perl do it
+        $outVal = pack('C0U*',unpack("$fmt*",$val));
+    } else {
+        # do it ourself
+        $outVal = PackUTF8(unpack("$fmt*",$val));
+    }
+    $outVal =~ s/\0.*//s;    # truncate at null terminator
+    return $outVal;
+}
+
+#------------------------------------------------------------------------------
+# Convert UTF-8 encoded string to Unicode string
+# Input: 0) UTF-8 string, 1) Unicode format, 2) optional ExifTool ref for warnings
+# Returns: Unicode character string in specified format
+sub UTF82Unicode($$;$)
+{
+    my ($str, $fmt, $exifTool) = @_;
+    undef $evalWarning;
+    if ($] >= 5.006001) {
+        # handle warnings from malformed UTF-8
+        local $SIG{'__WARN__'} = \&SetWarning;
+        # repack UTF-8 string in specified format
+        $str = pack("$fmt*", unpack('U0U*',$str));
+    } else {
+        # do it ourself
+        $str = pack("$fmt*", UnpackUTF8($str));
+    }
+    if ($evalWarning and $exifTool and not $$exifTool{WarnBadUTF8}) {
+        $exifTool->Warn('Malformed UTF-8 character(s)');
+        $$exifTool{WarnBadUTF8} = 1;
+    }
+    return $str;
+}
+
+#------------------------------------------------------------------------------
+# Convert 16-bit unicode character string to 8-bit (Latin or UTF-8)
+# Inputs: 0) ExifTool ref, 1) 16-bit unicode string (in specified byte order)
+#         2) Optional byte order (current byte order used if not specified)
+# Returns: 8-bit character string (truncates at null terminator)
+my %unpackShort = ( 'II' => 'v', 'MM' => 'n' );
+sub Unicode2Charset($$;$) {
+    my ($self, $val, $byteOrder) = @_;
+    # check for (and remove) byte order mark and set byte order accordingly if it exists
+    $val =~ s/^(\xff\xfe|\xfe\xff)// and $byteOrder = ($1 eq "\xff\xfe") ? 'MM' : 'II';
+    my $fmt = $unpackShort{$byteOrder || GetByteOrder()};
+    # convert to Latin if specified or if no UTF-8 support in this Perl version
+    if ($self->Options('Charset') eq 'Latin') {
+        return Unicode2Latin($val, $fmt, $self);
+    } else {
+        return Unicode2UTF8($val, $fmt);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Convert 8-bit character string to 16-bit unicode
+# Inputs: 0) ExifTool ref, 1) Latin or UTF-8 string, 2) optional byte order
+# Returns: 16-bit unicode character string (in specified byte order)
+sub Charset2Unicode($$;$)
+{
+    my ($self, $val, $byteOrder) = @_;
+    my $fmt = $unpackShort{$byteOrder || GetByteOrder()};
+    if ($self->Options('Charset') eq 'Latin') {
+        return Latin2Unicode($val, $fmt);
+    } else {
+        return UTF82Unicode($val, $fmt, $self);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Assemble a continuing fraction into a rational value
+# Inputs: 0) numerator, 1) denominator
+#         2-N) list of fraction denominators, deepest first
+# Returns: numerator, denominator (in list context)
+sub AssembleRational($$@)
+{
+    @_ < 3 and return @_;
+    my ($num, $denom, $frac) = splice(@_, 0, 3);
+    return AssembleRational($frac*$num+$denom, $num, @_);
+}
+
+#------------------------------------------------------------------------------
+# Convert a floating point number into a rational
+# Inputs: 0) floating point number, 1) optional maximum value (defaults to 0x7fffffff)
+# Returns: numerator, denominator (in list context)
+# Notes: these routines were a bit tricky, but fun to write!
+sub Rationalize($;$)
+{
+    my $val = shift;
+    # Note: Just testing "if $val" doesn't work because '0.0' is true!  (ugghh!)
+    return (0, 1) if $val == 0;
+    my $sign = $val < 0 ? ($val = -$val, -1) : 1;
+    my ($num, $denom, @fracs);
+    my $frac = $val;
+    my $maxInt = shift || 0x7fffffff;
+    for (;;) {
+        my ($n, $d) = AssembleRational(int($frac + 0.5), 1, @fracs);
+        if ($n > $maxInt or $d > $maxInt) {
+            last if defined $num;
+            return ($sign, $maxInt) if $val < 1;
+            return ($sign * $maxInt, 1);
+        }
+        ($num, $denom) = ($n, $d);      # save last good values
+        my $err = ($n/$d-$val) / $val;  # get error of this rational
+        last if abs($err) < 1e-8;       # all done if error is small
+        my $int = int($frac);
+        unshift @fracs, $int;
+        last unless $frac -= $int;
+        $frac = 1 / $frac;
+    }
+    return ($num * $sign, $denom);
+}
+
+#------------------------------------------------------------------------------
+# Utility routines to for writing binary data values
+# Inputs: 0) value, 1) data ref, 2) offset
+# Notes: prototype is (@) so values can be passed from list if desired
+sub Set16s(@)
+{
+    my $val = shift;
+    $val < 0 and $val += 0x10000;
+    return Set16u($val, @_);
+}
+sub Set32s(@)
+{
+    my $val = shift;
+    $val < 0 and $val += 0xffffffff, ++$val;
+    return Set32u($val, @_);
+}
+sub SetRational64u(@) {
+    my ($numer,$denom) = Rationalize($_[0],0xffffffff);
+    my $val = Set32u($numer) . Set32u($denom);
+    $_[1] and substr(${$_[1]}, $_[2], length($val)) = $val;
+    return $val;
+}
+sub SetRational64s(@) {
+    my ($numer,$denom) = Rationalize($_[0]);
+    my $val = Set32s($numer) . Set32u($denom);
+    $_[1] and substr(${$_[1]}, $_[2], length($val)) = $val;
+    return $val;
+}
+sub SetRational32u(@) {
+    my ($numer,$denom) = Rationalize($_[0],0xffff);
+    my $val = Set16u($numer) . Set16u($denom);
+    $_[1] and substr(${$_[1]}, $_[2], length($val)) = $val;
+    return $val;
+}
+sub SetRational32s(@) {
+    my ($numer,$denom) = Rationalize($_[0],0xffff);
+    my $val = Set16s($numer) . Set16u($denom);
+    $_[1] and substr(${$_[1]}, $_[2], length($val)) = $val;
+    return $val;
+}
+sub SetFixed16u(@) {
+    my $val = int(shift() * 0x100 + 0.5);
+    return Set16u($val, @_);
+}
+sub SetFixed16s(@) {
+    my $val = shift;
+    return Set16s(int($val * 0x100 + ($val < 0 ? -0.5 : 0.5)), @_);
+}
+sub SetFixed32u(@) {
+    my $val = int(shift() * 0x10000 + 0.5);
+    return Set32u($val, @_);
+}
+sub SetFixed32s(@) {
+    my $val = shift;
+    return Set32s(int($val * 0x10000 + ($val < 0 ? -0.5 : 0.5)), @_);
+}
+sub SetFloat(@) {
+    my $val = SwapBytes(pack('f',$_[0]), 4);
+    $_[1] and substr(${$_[1]}, $_[2], length($val)) = $val;
+    return $val;
+}
+sub SetDouble(@) {
+    # swap 32-bit words (ARM quirk) and bytes if necessary
+    my $val = SwapBytes(SwapWords(pack('d',$_[0])), 8);
+    $_[1] and substr(${$_[1]}, $_[2], length($val)) = $val;
+    return $val;
+}
+#------------------------------------------------------------------------------
+# hash lookups for writing binary data values
+my %writeValueProc = (
+    int8s => \&Set8s,
+    int8u => \&Set8u,
+    int16s => \&Set16s,
+    int16u => \&Set16u,
+    int32s => \&Set32s,
+    int32u => \&Set32u,
+    rational32s => \&SetRational32s,
+    rational32u => \&SetRational32u,
+    rational64s => \&SetRational64s,
+    rational64u => \&SetRational64u,
+    fixed16u => \&SetFixed16u,
+    fixed16s => \&SetFixed16s,
+    fixed32u => \&SetFixed32u,
+    fixed32s => \&SetFixed32s,
+    float => \&SetFloat,
+    double => \&SetDouble,
+    ifd => \&Set32u,
+);
+# verify that we can write floats on this platform
+{
+    my %writeTest = (
+        float =>  [ -3.14159, 'c0490fd0' ],
+        double => [ -3.14159, 'c00921f9f01b866e' ],
+    );
+    my $format;
+    my $oldOrder = GetByteOrder();
+    SetByteOrder('MM');
+    foreach $format (keys %writeTest) {
+        my ($val, $hex) = @{$writeTest{$format}};
+        # add floating point entries if we can write them
+        next if unpack('H*', &{$writeValueProc{$format}}($val)) eq $hex;
+        delete $writeValueProc{$format};    # we can't write them
+    }
+    SetByteOrder($oldOrder);
+}
+
+#------------------------------------------------------------------------------
+# write binary data value (with current byte ordering)
+# Inputs: 0) value, 1) format string
+#         2) optional number of values (1 or string length if not specified)
+#         3) optional data reference, 4) value offset
+# Returns: packed value (and sets value in data) or undef on error
+sub WriteValue($$;$$$$)
+{
+    my ($val, $format, $count, $dataPt, $offset) = @_;
+    my $proc = $writeValueProc{$format};
+    my $packed;
+
+    if ($proc) {
+        my @vals = split(' ',$val);
+        if ($count) {
+            $count = @vals if $count < 0;
+        } else {
+            $count = 1;   # assume 1 if count not specified
+        }
+        $packed = '';
+        while ($count--) {
+            $val = shift @vals;
+            return undef unless defined $val;
+            # validate numerical formats
+            if ($format =~ /^int/) {
+                return undef unless IsInt($val) or IsHex($val);
+            } else {
+                return undef unless IsFloat($val);
+            }
+            $packed .= &$proc($val);
+        }
+    } elsif ($format eq 'string' or $format eq 'undef') {
+        $format eq 'string' and $val .= "\0";   # null-terminate strings
+        if ($count and $count > 0) {
+            my $diff = $count - length($val);
+            if ($diff) {
+                #warn "wrong string length!\n";
+                # adjust length of string to match specified count
+                if ($diff < 0) {
+                    if ($format eq 'string') {
+                        return undef unless $count;
+                        $val = substr($val, 0, $count - 1) . "\0";
+                    } else {
+                        $val = substr($val, 0, $count);
+                    }
+                } else {
+                    $val .= "\0" x $diff;
+                }
+            }
+        } else {
+            $count = length($val);
+        }
+        $dataPt and substr($$dataPt, $offset, $count) = $val;
+        return $val;
+    } else {
+        warn "Sorry, Can't write $format values on this platform\n";
+        return undef;
+    }
+    $dataPt and substr($$dataPt, $offset, length($packed)) = $packed;
+    return $packed;
+}
+
+#------------------------------------------------------------------------------
+# Encode bit mask (the inverse of DecodeBits())
+# Inputs: 0) value to encode, 1) Reference to hash for encoding (or undef)
+#         2) optional number of bits per word (defaults to 32), 3) total bits
+# Returns: bit mask or undef on error (plus error string in list context)
+sub EncodeBits($$;$$)
+{
+    my ($val, $lookup, $bits, $num) = @_;
+    $bits or $bits = 32;
+    $num or $num = $bits;
+    my $words = int(($num + $bits - 1) / $bits);
+    my @outVal = (0) x $words;
+    if ($val ne '(none)') {
+        my @vals = split /\s*,\s*/, $val;
+        foreach $val (@vals) {
+            my $bit;
+            if ($lookup) {
+                $bit = ReverseLookup($val, $lookup);
+                unless (defined $bit) {
+                    if ($val =~ /\[(\d+)\]/) { # numerical bit specification
+                        $bit = $1;
+                    } else {
+                        # don't return error string unless more than one value
+                        return undef unless @vals > 1 and wantarray;
+                        return (undef, "no match for '$val'");
+                    }
+                }
+            } else {
+                $bit = $val;
+            }
+            return (undef, 'bit number too high') if $bit >= $num;
+            my $word = int($bit / $bits);
+            $outVal[$word] |= (1 << ($bit - $word * $bits));
+        }
+    }
+    return "@outVal";
+}
+
+#------------------------------------------------------------------------------
+# get current position in output file
+# Inputs: 0) file or scalar reference
+# Returns: Current position or -1 on error
+sub Tell($)
+{
+    my $outfile = shift;
+    if (UNIVERSAL::isa($outfile,'GLOB')) {
+        return tell($outfile);
+    } else {
+        return length($$outfile);
+    }
+}
+
+#------------------------------------------------------------------------------
+# write to file or memory
+# Inputs: 0) file or scalar reference, 1-N) list of stuff to write
+# Returns: true on success
+sub Write($@)
+{
+    my $outfile = shift;
+    if (UNIVERSAL::isa($outfile,'GLOB')) {
+        return print $outfile @_;
+    } elsif (ref $outfile eq 'SCALAR') {
+        $$outfile .= join('', @_);
+        return 1;
+    }
+    return 0;
+}
+
+#------------------------------------------------------------------------------
+# Read/rewrite trailer information (including multiple trailers)
+# Inputs: 0) ExifTool object ref, 1) DirInfo ref:
+# - requires RAF and DirName
+# - OutFile is a scalar reference for writing
+# - scans from current file position if ScanForAFCP is set
+# Returns: 1 if trailer was processed or couldn't be processed (or written OK)
+#          0 if trailer was recognized but offsets need fixing (or write error)
+# - DirName, DirLen, DataPos, Offset, Fixup and OutFile are updated
+# - preserves current file position and byte order
+sub ProcessTrailers($$)
+{
+    my ($self, $dirInfo) = @_;
+    my $dirName = $$dirInfo{DirName};
+    my $outfile = $$dirInfo{OutFile};
+    my $offset = $$dirInfo{Offset} || 0;
+    my $fixup = $$dirInfo{Fixup};
+    my $raf = $$dirInfo{RAF};
+    my $pos = $raf->Tell();
+    my $byteOrder = GetByteOrder();
+    my $success = 1;
+
+    for (;;) { # loop through all trailers
+        require "Image/ExifTool/$dirName.pm";
+        my $proc = "Image::ExifTool::${dirName}::Process$dirName";
+        my $outBuff;
+        if ($outfile) {
+            # write to local buffer so we can add trailer in proper order later
+            $$outfile and $$dirInfo{OutFile} = \$outBuff, $outBuff = '';
+            # must generate new fixup if necessary so we can shift
+            # the old fixup separately after we prepend this trailer
+            delete $$dirInfo{Fixup};
+        }
+        delete $$dirInfo{DirLen};       # reset trailer length
+        $$dirInfo{Offset} = $offset;    # set offset from end of file
+        $$dirInfo{Trailer} = 1;         # set Trailer flag in case proc cares
+
+        # read or write this trailer
+        # (proc takes Offset as offset from end of trailer to end of file,
+        #  and returns DataPos and DirLen, and Fixup if applicable)
+        no strict 'refs';
+        my $result = &$proc($self, $dirInfo);
+        use strict 'refs';
+
+        if ($outfile) {
+            if ($result > 0) {
+                if ($outBuff) {
+                    # write trailers to OutFile in original order
+                    $$outfile = $outBuff . $$outfile;
+                    # must adjust old fixup start if it exists
+                    $$fixup{Start} += length($outBuff) if $fixup;
+                    $outBuff = '';      # free memory
+                }
+                if ($fixup) {
+                    # add new fixup information if any
+                    $fixup->AddFixup($$dirInfo{Fixup}) if $$dirInfo{Fixup};
+                } else {
+                    $fixup = $$dirInfo{Fixup};  # save fixup
+                }
+            } else {
+                $success = 0 if $self->Error("Error rewriting $dirName trailer", 1);
+                last;
+            }
+        } elsif ($result < 0) {
+            # can't continue if we must scan for this trailer
+            $success = 0;
+            last;
+        }
+        last unless $result > 0 and $$dirInfo{DirLen};
+        # look for next trailer
+        $offset += $$dirInfo{DirLen};
+        my $nextTrail = IdentifyTrailer($raf, $offset) or last;
+        $dirName = $$dirInfo{DirName} = $$nextTrail{DirName};
+        $raf->Seek($pos, 0);
+    }
+    SetByteOrder($byteOrder);       # restore original byte order
+    $raf->Seek($pos, 0);            # restore original file position
+    $$dirInfo{OutFile} = $outfile;  # restore original outfile
+    $$dirInfo{Offset} = $offset;    # return offset to start of first trailer
+    $$dirInfo{Fixup} = $fixup;      # return fixup information
+    return $success;
+}
+
+#------------------------------------------------------------------------------
+# Write trailer buffer to file (applying fixups if necessary)
+# Inputs: 0) ExifTool object ref, 1) trailer dirInfo ref, 2) output file ref
+# Returns: 1 on success
+sub WriteTrailerBuffer($$$)
+{
+    my ($self, $trailInfo, $outfile) = @_;
+    if ($self->{DEL_GROUP}->{Trailer}) {
+        $self->VPrint(0, "  Deleting trailer ($$trailInfo{Offset} bytes)\n");
+        ++$self->{CHANGED};
+        return 1;
+    }
+    my $pos = Tell($outfile);
+    my $trailPt = $$trailInfo{OutFile};
+    # apply fixup if necessary (AFCP requires this)
+    if ($$trailInfo{Fixup}) {
+        if ($pos > 0) {
+            # shift offsets to final AFCP location and write it out
+            $trailInfo->{Fixup}->{Shift} += $pos;
+            $trailInfo->{Fixup}->ApplyFixup($trailPt);
+        } else {
+            $self->Error("Can't get file position for trailer offset fixup",1);
+        }
+    }
+    return Write($outfile, $$trailPt);
+}
+
+#------------------------------------------------------------------------------
+# Add trailers as a block
+# Inputs: 0) ExifTool object ref, 1) [optional] trailer data raf,
+#         1 or 2-N) trailer types to add (or none to add all)
+# Returns: new trailer ref, or undef
+# - increments CHANGED if trailer was added
+sub AddNewTrailers($;@)
+{
+    my ($self, @types) = @_;
+    my $trailPt;
+    ref $types[0] and $trailPt = shift @types;
+    $types[0] or shift @types; # (in case undef data ref is passed)
+    # add all possible trailers if none specified (currently only CanonVRD)
+    @types or @types = qw(CanonVRD);
+    # add trailers as a block
+    my $type;
+    foreach $type (@types) {
+        next unless $self->{NEW_VALUE}->{$Image::ExifTool::Extra{$type}};
+        my $val = $self->GetNewValues($type) or next;
+        my $verb = $trailPt ? 'Writing' : 'Adding';
+        $self->VPrint(0, "  $verb $type as a block\n");
+        if ($trailPt) {
+            $$trailPt .= $val;
+        } else {
+            $trailPt = \$val;
+        }
+        ++$$self{CHANGED};
+    }
+    return $trailPt;
+}
+
+#------------------------------------------------------------------------------
+# Write segment, splitting up into multiple segments if necessary
+# Inputs: 0) file or scalar reference, 1) segment marker
+#         2) segment header, 3) segment data ref, 4) segment type
+# Returns: number of segments written, or 0 on error
+sub WriteMultiSegment($$$$;$)
+{
+    my ($outfile, $marker, $header, $dataPt, $type) = @_;
+    $type or $type = '';
+    my $len = length($$dataPt);
+    my $hdr = "\xff" . chr($marker);
+    my $count = 0;
+    my $maxLen = $maxSegmentLen - length($header);
+    $maxLen -= 2 if $type eq 'ICC'; # leave room for segment counters
+    my $num = int(($len + $maxLen - 1) / $maxLen);  # number of segments to write
+    my $n;
+    # write data, splitting into multiple segments if necessary
+    # (each segment gets its own header)
+    for ($n=0; $n<$len; $n+=$maxLen) {
+        ++$count;
+        my $size = $len - $n;
+        $size > $maxLen and $size = $maxLen;
+        my $buff = substr($$dataPt,$n,$size);
+        $size += length($header);
+        if ($type eq 'ICC') {
+            $buff = pack('CC', $count, $num) . $buff;
+            $size += 2;
+        }
+        # write the new segment with appropriate header
+        my $segHdr = $hdr . pack('n', $size + 2);
+        Write($outfile, $segHdr, $header, $buff) or return 0;
+    }
+    return $count;
+}
+
+#------------------------------------------------------------------------------
+# WriteJPEG : Write JPEG image
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid JPEG file, or -1 if
+#          an output file was specified and a write error occurred
+sub WriteJPEG($$)
+{
+    my ($self, $dirInfo) = @_;
+    my $outfile = $$dirInfo{OutFile};
+    my $raf = $$dirInfo{RAF};
+    my ($ch,$s,$length);
+    my $verbose = $self->{OPTIONS}->{Verbose};
+    my $out = $self->{OPTIONS}->{TextOut};
+    my $rtnVal = 0;
+    my ($err, %doneDir);
+    my %dumpParms = ( Out => $out );
+    my ($writeBuffer, $oldOutfile); # used to buffer writing until PreviewImage position is known
+
+    # check to be sure this is a valid JPG file
+    return 0 unless $raf->Read($s,2) == 2 and $s eq "\xff\xd8";
+    $dumpParms{MaxLen} = 128 unless $verbose > 3;
+
+    delete $self->{PREVIEW_INFO};   # reset preview information
+    delete $self->{DEL_PREVIEW};    # reset flag to delete preview
+
+    Write($outfile, $s) or $err = 1;
+    # figure out what segments we need to write for the tags we have set
+    my $addDirs = $self->{ADD_DIRS};
+    my $editDirs = $self->{EDIT_DIRS};
+    my $delGroup = $self->{DEL_GROUP};
+
+    # set input record separator to 0xff (the JPEG marker) to make reading quicker
+    my $oldsep = $/;
+    $/ = "\xff";
+#
+# pre-scan image to determine if any create-able segment already exists
+#
+    my $pos = $raf->Tell();
+    my ($marker, @dirOrder, %dirCount);
+    Prescan: for (;;) {
+        # read up to next marker (JPEG markers begin with 0xff)
+        $raf->ReadLine($s) or last;
+        # JPEG markers can be padded with unlimited 0xff's
+        for (;;) {
+            $raf->Read($ch, 1) or last Prescan;
+            $marker = ord($ch);
+            last unless $marker == 0xff;
+        }
+        # SOS signifies end of meta information
+        if ($marker == 0xda) {
+            push(@dirOrder, 'SOS');
+            $dirCount{SOS} = 1;
+            last;
+        }
+        my $dirName;
+        # handle SOF markers: SOF0-SOF15, except DHT(0xc4), JPGA(0xc8) and DAC(0xcc)
+        if (($marker & 0xf0) == 0xc0 and ($marker == 0xc0 or $marker & 0x03)) {
+            last unless $raf->Seek(7, 1);
+        # read data for all markers except stand-alone
+        # markers 0x00, 0x01 and 0xd0-0xd7 (NULL, TEM, RST0-RST7)
+        } elsif ($marker!=0x00 and $marker!=0x01 and ($marker<0xd0 or $marker>0xd7)) {
+            # read record length word
+            last unless $raf->Read($s, 2) == 2;
+            my $len = unpack('n',$s);   # get data length
+            last unless defined($len) and $len >= 2;
+            $len -= 2;  # subtract size of length word
+            if (($marker & 0xf0) == 0xe0) {  # is this an APP segment?
+                my $n = $len < 64 ? $len : 64;
+                $raf->Read($s, $n) == $n or last;
+                $len -= $n;
+                if ($marker == 0xe0) {
+                    $s =~ /^JFIF\0/        and $dirName = 'JFIF';
+                    $s =~ /^JFXX\0\x10/    and $dirName = 'JFXX';
+                } elsif ($marker == 0xe1) {
+                    $s =~ /^$exifAPP1hdr/  and $dirName = 'IFD0';
+                    $s =~ /^$xmpAPP1hdr/   and $dirName = 'XMP';
+                } elsif ($marker == 0xe2) {
+                    $s =~ /^ICC_PROFILE\0/ and $dirName = 'ICC_Profile';
+                } elsif ($marker == 0xec) {
+                    $s =~ /^Ducky/         and $dirName = 'Ducky';
+                } elsif ($marker == 0xed) {
+                    $s =~ /^$psAPP13hdr/   and $dirName = 'Photoshop';
+                }
+                # initialize doneDir as a flag that the directory exists
+                # (unless we are deleting it anyway)
+                $doneDir{$dirName} = 0 if defined $dirName and not $$delGroup{$dirName};
+            }
+            $raf->Seek($len, 1) or last;
+        }
+        $dirName or $dirName = JpegMarkerName($marker);
+        $dirCount{$dirName} = ($dirCount{$dirName} || 0) + 1;
+        push @dirOrder, $dirName;
+    }
+    unless ($marker and $marker == 0xda) {
+        $self->Error('Corrupted JPEG image');
+        return 1;
+    }
+    $raf->Seek($pos, 0) or $self->Error('Seek error'), return 1;
+#
+# re-write the image
+#
+    my ($combinedSegData, $segPos);
+    # read through each segment in the JPEG file
+    Marker: for (;;) {
+
+        # read up to next marker (JPEG markers begin with 0xff)
+        my $segJunk;
+        $raf->ReadLine($segJunk) or $segJunk = '';
+        # remove the 0xff but write the rest of the junk up to this point
+        chomp($segJunk);
+        Write($outfile, $segJunk) if length $segJunk;
+        # JPEG markers can be padded with unlimited 0xff's
+        for (;;) {
+            $raf->Read($ch, 1) or $self->Error('Format error'), return 1;
+            $marker = ord($ch);
+            last unless $marker == 0xff;
+        }
+        # read the segment data
+        my $segData;
+        # handle SOF markers: SOF0-SOF15, except DHT(0xc4), JPGA(0xc8) and DAC(0xcc)
+        if (($marker & 0xf0) == 0xc0 and ($marker == 0xc0 or $marker & 0x03)) {
+            last unless $raf->Read($segData, 7) == 7;
+        # read data for all markers except stand-alone
+        # markers 0x00, 0x01 and 0xd0-0xd7 (NULL, TEM, RST0-RST7)
+        } elsif ($marker!=0x00 and $marker!=0x01 and ($marker<0xd0 or $marker>0xd7)) {
+            # read record length word
+            last unless $raf->Read($s, 2) == 2;
+            my $len = unpack('n',$s);   # get data length
+            last unless defined($len) and $len >= 2;
+            $segPos = $raf->Tell();
+            $len -= 2;  # subtract size of length word
+            last unless $raf->Read($segData, $len) == $len;
+        }
+        # initialize variables for this segment
+        my $hdr = "\xff" . chr($marker);    # segment header
+        my $markerName = JpegMarkerName($marker);
+        my $dirName = shift @dirOrder;      # get directory name
+#
+# create all segments that must come before this one
+# (nothing comes before SOI or after SOS)
+#
+        while ($markerName ne 'SOI') {
+            if (exists $$addDirs{JFIF} and not defined $doneDir{JFIF}) {
+                $doneDir{JFIF} = 1;
+                if ($verbose) {
+                    print $out "Creating APP0:\n";
+                    print $out "  Creating JFIF with default values\n";
+                }
+                my $jfif = "\x01\x02\x01\0\x48\0\x48\0\0";
+                SetByteOrder('MM');
+                my $tagTablePtr = GetTagTable('Image::ExifTool::JFIF::Main');
+                my %dirInfo = (
+                    DataPt   => \$jfif,
+                    DirStart => 0,
+                    DirLen   => length $jfif,
+                );
+                my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                if (defined $newData and length $newData) {
+                    my $app0hdr = "\xff\xe0" . pack('n', length($newData) + 7);
+                    Write($outfile,$app0hdr,"JFIF\0",$newData) or $err = 1;
+                }
+            }
+            # don't create anything before APP0 or APP1 EXIF (containing IFD0)
+            last if $markerName eq 'APP0' or $dirCount{IFD0};
+            # EXIF information must come immediately after APP0
+            if (exists $$addDirs{IFD0} and not defined $doneDir{IFD0}) {
+                $doneDir{IFD0} = 1;
+                $verbose and print $out "Creating APP1:\n";
+                # write new EXIF data
+                $self->{TIFF_TYPE} = 'APP1';
+                my $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main');
+                # use specified byte ordering or ordering from maker notes if set
+                my $byteOrder = $self->Options('ByteOrder') ||
+                    $self->GetNewValues('ExifByteOrder') || $self->{MAKER_NOTE_BYTE_ORDER} || 'MM';
+                unless (SetByteOrder($byteOrder)) {
+                    warn "Invalid byte order '$byteOrder'\n";
+                    $byteOrder = $self->{MAKER_NOTE_BYTE_ORDER} || 'MM';
+                    SetByteOrder($byteOrder);
+                }
+                my %dirInfo = (
+                    NewDataPos => 8,    # new data will come after TIFF header
+                    DirName => 'IFD0',
+                    Parent  => $markerName,
+                );
+                my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                if (defined $buff and length $buff) {
+                    my $tiffHdr = $byteOrder . Set16u(42) . Set32u(8); # standard TIFF header
+                    my $size = length($buff) + length($tiffHdr) + length($exifAPP1hdr);
+                    if ($size <= $maxSegmentLen) {
+                        # switch to buffered output if required
+                        if ($self->{PREVIEW_INFO} and not $oldOutfile) {
+                            $writeBuffer = '';
+                            $oldOutfile = $outfile;
+                            $outfile = \$writeBuffer;
+                            # account for segment,EXIF and TIFF headers
+                            $self->{PREVIEW_INFO}->{Fixup}->{Start} += 18;
+                        }
+                        # write the new segment with appropriate header
+                        my $app1hdr = "\xff\xe1" . pack('n', $size + 2);
+                        Write($outfile,$app1hdr,$exifAPP1hdr,$tiffHdr,$buff) or $err = 1;
+                    } else {
+                        delete $self->{PREVIEW_INFO};
+                        $self->Warn("EXIF APP1 segment too large! ($size bytes)");
+                    }
+                }
+            }
+            # APP13 Photoshop segment next
+            last if $dirCount{Photoshop};
+            if (exists $$addDirs{Photoshop} and not defined $doneDir{Photoshop}) {
+                $doneDir{Photoshop} = 1;
+                $verbose and print $out "Creating APP13:\n";
+                # write new APP13 Photoshop record to memory
+                my $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
+                my %dirInfo = (
+                    Parent => $markerName,
+                );
+                my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                if (defined $buff and length $buff) {
+                    WriteMultiSegment($outfile, 0xed, $psAPP13hdr, \$buff) or $err = 1;
+                    ++$self->{CHANGED};
+                }
+            }
+            # then APP1 XMP segment
+            last if $dirCount{XMP};
+            if (exists $$addDirs{XMP} and not defined $doneDir{XMP}) {
+                $doneDir{XMP} = 1;
+                $verbose and print $out "Creating APP1:\n";
+                # write new XMP data
+                my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
+                my %dirInfo = (
+                    Parent   => $markerName,
+                );
+                my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                if (defined $buff and length $buff) {
+                    my $size = length($buff) + length($xmpAPP1hdr);
+                    if ($size <= $maxSegmentLen) {
+                        # write the new segment with appropriate header
+                        my $app1hdr = "\xff\xe1" . pack('n', $size + 2);
+                        Write($outfile, $app1hdr, $xmpAPP1hdr, $buff) or $err = 1;
+                    } else {
+                        $self->Warn("XMP APP1 segment too large! ($size bytes)");
+                    }
+                }
+            }
+            # then APP2 ICC_Profile segment
+            last if $dirCount{ICC_Profile};
+            if (exists $$addDirs{ICC_Profile} and not defined $doneDir{ICC_Profile}) {
+                $doneDir{ICC_Profile} = 1;
+                next if $$delGroup{ICC_Profile} and $$delGroup{ICC_Profile} != 2;
+                $verbose and print $out "Creating APP2:\n";
+                # write new ICC_Profile data
+                my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
+                my %dirInfo = (
+                    Parent   => $markerName,
+                );
+                my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                if (defined $buff and length $buff) {
+                    WriteMultiSegment($outfile, 0xe2, "ICC_PROFILE\0", \$buff, 'ICC') or $err = 1;
+                    ++$self->{CHANGED};
+                }
+            }
+            # then APP12 Ducky segment
+            last if $dirCount{Ducky};
+            if (exists $$addDirs{Ducky} and not defined $doneDir{Ducky}) {
+                $doneDir{Ducky} = 1;
+                $verbose and print $out "Creating APP12 Ducky:\n";
+                # write new Ducky segment data
+                my $tagTablePtr = GetTagTable('Image::ExifTool::APP12::Ducky');
+                my %dirInfo = (
+                    Parent   => $markerName,
+                );
+                my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                if (defined $buff and length $buff) {
+                    my $size = length($buff) + 5;
+                    if ($size <= $maxSegmentLen) {
+                        # write the new segment with appropriate header
+                        my $app12hdr = "\xff\xec" . pack('n', $size + 2);
+                        Write($outfile, $app12hdr, 'Ducky', $buff) or $err = 1;
+                    } else {
+                        $self->Warn("APP12 Ducky segment too large! ($size bytes)");
+                    }
+                }
+            }
+            # finally, COM segment
+            last if $dirCount{COM};
+            if (exists $$addDirs{COM} and not defined $doneDir{COM}) {
+                $doneDir{COM} = 1;
+                next if $$delGroup{File} and $$delGroup{File} != 2;
+                my $newComment = $self->GetNewValues('Comment');
+                if (defined $newComment and length($newComment)) {
+                    $verbose and print $out "Creating COM:\n";
+                    $verbose > 1 and print $out "    + Comment = '$newComment'\n";
+                    WriteMultiSegment($outfile, 0xfe, '', \$newComment) or $err = 1;
+                    ++$self->{CHANGED};
+                }
+            }
+            last;   # didn't want to loop anyway
+        }
+        # decrement counter for this directory since we are about to process it
+        --$dirCount{$dirName};
+#
+# rewrite existing segments
+#
+        # handle SOF markers: SOF0-SOF15, except DHT(0xc4), JPGA(0xc8) and DAC(0xcc)
+        if (($marker & 0xf0) == 0xc0 and ($marker == 0xc0 or $marker & 0x03)) {
+            $verbose and print $out "JPEG $markerName:\n";
+            Write($outfile, $hdr, $segData) or $err = 1;
+            next;
+        } elsif ($marker == 0xda) {             # SOS
+            $verbose and print $out "JPEG SOS\n";
+            # write SOS segment
+            $s = pack('n', length($segData) + 2);
+            Write($outfile, $hdr, $s, $segData) or $err = 1;
+            my ($buff, $endPos, $trailInfo);
+            my $delPreview = $self->{DEL_PREVIEW};
+            $trailInfo = IdentifyTrailer($raf) unless $$delGroup{Trailer};
+            unless ($oldOutfile or $delPreview or $trailInfo or $$delGroup{Trailer}) {
+                # blindly copy the rest of the file
+                while ($raf->Read($buff, 65536)) {
+                    Write($outfile, $buff) or $err = 1, last;
+                }
+                $rtnVal = 1;  # success unless we have a file write error
+                last;         # all done
+            }
+            # write the rest of the image (as quickly as possible) up to the EOI
+            my $endedWithFF;
+            for (;;) {
+                my $n = $raf->Read($buff, 65536) or last Marker;
+                if (($endedWithFF and $buff =~ m/^\xd9/sg) or
+                    $buff =~ m/\xff\xd9/sg)
+                {
+                    $rtnVal = 1; # the JPEG is OK
+                    # write up to the EOI
+                    my $pos = pos($buff);
+                    Write($outfile, substr($buff, 0, $pos)) or $err = 1;
+                    $buff = substr($buff, $pos);
+                    last;
+                }
+                unless ($n == 65536) {
+                    $self->Error('JPEG EOI marker not found');
+                    last Marker;
+                }
+                Write($outfile, $buff) or $err = 1;
+                $endedWithFF = substr($buff, 65535, 1) eq "\xff" ? 1 : 0;
+            }
+            # remember position of last data copied
+            $endPos = $raf->Tell() - length($buff);
+            # rewrite trailers if they exist
+            if ($trailInfo) {
+                my $tbuf = '';
+                $raf->Seek(-length($buff), 1);  # seek back to just after EOI
+                $$trailInfo{OutFile} = \$tbuf;  # rewrite the trailer
+                $$trailInfo{ScanForAFCP} = 1;   # scan if necessary
+                $self->ProcessTrailers($trailInfo) or undef $trailInfo;
+            }
+            if ($oldOutfile) {
+                # locate preview image and fix up preview offsets
+                if (length($buff) < 1024) { # make sure we have at least 1kB of trailer
+                    my $buf2;
+                    $buff .= $buf2 if $raf->Read($buf2, 1024);
+                }
+                # get new preview image position (subtract 10 for segment and EXIF headers)
+                my $newPos = length($$outfile) - 10;
+                my $junkLen;
+                # adjust position if image isn't at the start (ie. Olympus E-1/E-300)
+                if ($buff =~ m/(\xff\xd8\xff.|.\xd8\xff\xdb)/sg) {
+                    $junkLen = pos($buff) - 4;
+                    $newPos += $junkLen;
+                }
+                # fix up the preview offsets to point to the start of the new image
+                my $previewInfo = $self->{PREVIEW_INFO};
+                delete $self->{PREVIEW_INFO};
+                my $fixup = $previewInfo->{Fixup};
+                $newPos += ($previewInfo->{BaseShift} || 0);
+                if ($previewInfo->{Relative}) {
+                    # adjust for our base by looking at how far the pointer got shifted
+                    $newPos -= $fixup->GetMarkerPointers($outfile, 'PreviewImage');
+                }
+                $fixup->SetMarkerPointers($outfile, 'PreviewImage', $newPos);
+                # clean up and write the buffered data
+                $outfile = $oldOutfile;
+                undef $oldOutfile;
+                Write($outfile, $writeBuffer) or $err = 1;
+                undef $writeBuffer;
+                # write preview image
+                if ($previewInfo->{Data} ne 'LOAD') {
+                    # write any junk that existed before the preview image
+                    Write($outfile, substr($buff,0,$junkLen)) or $err = 1 if $junkLen;
+                    # write the saved preview image
+                    Write($outfile, $previewInfo->{Data}) or $err = 1;
+                    delete $previewInfo->{Data};
+                    # (don't increment CHANGED because we could be rewriting existing preview)
+                    $delPreview = 1;    # remove old preview
+                }
+            }
+            # copy over preview image if necessary
+            unless ($delPreview) {
+                my $extra;
+                if ($trailInfo) {
+                    # copy everything up to start of first processed trailer
+                    $extra = $$trailInfo{DataPos} - $endPos;
+                } else {
+                    # copy everything up to end of file
+                    $raf->Seek(0, 2) or $err = 1;
+                    $extra = $raf->Tell() - $endPos;
+                }
+                if ($extra > 0) {
+                    if ($$delGroup{Trailer}) {
+                        $verbose and print $out "  Deleting unknown trailer ($extra bytes)\n";
+                        ++$self->{CHANGED};
+                    } else {
+                        # copy over unknown trailer
+                        $verbose and print $out "  Preserving unknown trailer ($extra bytes)\n";
+                        $raf->Seek($endPos, 0) or $err = 1;
+                        while ($extra) {
+                            my $n = $extra < 65536 ? $extra : 65536;
+                            $raf->Read($buff, $n) == $n or $err = 1, last;
+                            Write($outfile, $buff) or $err = 1, last;
+                            $extra -= $n;
+                        }
+                    }
+                }
+            }
+            # write trailer if necessary
+            if ($trailInfo) {
+                $self->WriteTrailerBuffer($trailInfo, $outfile) or $err = 1;
+                undef $trailInfo;
+            }
+            last;   # all done parsing file
+
+        } elsif ($marker==0x00 or $marker==0x01 or ($marker>=0xd0 and $marker<=0xd7)) {
+            $verbose and $marker and print $out "JPEG $markerName:\n";
+            # handle stand-alone markers 0x00, 0x01 and 0xd0-0xd7 (NULL, TEM, RST0-RST7)
+            Write($outfile, $hdr) or $err = 1;
+            next;
+        }
+        #
+        # NOTE: A 'next' statement after this point will cause $$segDataPt
+        #       not to be written if there is an output file, so in this case
+        #       the $self->{CHANGED} flags must be updated
+        #
+        my $segDataPt = \$segData;
+        $length = length($segData);
+        if ($verbose) {
+            print $out "JPEG $markerName ($length bytes):\n";
+            if ($verbose > 2 and $markerName =~ /^APP/) {
+                HexDump($segDataPt, undef, %dumpParms);
+            }
+        }
+        my ($segType, $del);
+        # rewrite this segment only if we are changing a tag which
+        # is contained in its directory (or deleting '*', in which
+        # case we need to identify the segment type)
+        while (exists $$editDirs{$markerName} or $$delGroup{'*'}) {
+            my $oldChanged = $self->{CHANGED};
+            if ($marker == 0xe0) {              # APP0 (JFIF, CIFF)
+                if ($$segDataPt =~ /^JFIF\0/) {
+                    $segType = 'JFIF';
+                    $$delGroup{JFIF} and $del = 1, last;
+                    SetByteOrder('MM');
+                    my $tagTablePtr = GetTagTable('Image::ExifTool::JFIF::Main');
+                    my %dirInfo = (
+                        DataPt   => $segDataPt,
+                        DataPos  => $segPos,
+                        DataLen  => $length,
+                        DirStart => 5,     # directory starts after identifier
+                        DirLen   => $length-5,
+                        Parent   => $markerName,
+                    );
+                    my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                    if (defined $newData and length $newData) {
+                        $$segDataPt = "JFIF\0" . $newData;
+                    }
+                } elsif ($$segDataPt =~ /^JFXX\0\x10/) {
+                    $segType = 'JFXX';
+                    $$delGroup{JFIF} and $del = 1;
+                } elsif ($$segDataPt =~ /^(II|MM).{4}HEAPJPGM/s) {
+                    $segType = 'CIFF';
+                    $$delGroup{CIFF} and $del = 1, last;
+                    my $newData = '';
+                    my %dirInfo = (
+                        RAF => new File::RandomAccess($segDataPt),
+                        OutFile => \$newData,
+                    );
+                    require Image::ExifTool::CanonRaw;
+                    if (Image::ExifTool::CanonRaw::WriteCRW($self, \%dirInfo) > 0) {
+                        if (length $newData) {
+                            $$segDataPt = $newData;
+                        } else {
+                            undef $segDataPt;
+                            $del = 1;   # delete this segment
+                        }
+                    }
+                }
+            } elsif ($marker == 0xe1) {         # APP1 (EXIF, XMP)
+                # check for EXIF data
+                if ($$segDataPt =~ /^$exifAPP1hdr/) {
+                    $segType = 'EXIF';
+                    $doneDir{IFD0} and $self->Warn('Multiple APP1 EXIF segments');
+                    $doneDir{IFD0} = 1;
+                    last unless $$editDirs{IFD0};
+                    # write new EXIF data to memory
+                    my $buff = $exifAPP1hdr; # start with APP1 EXIF header
+                    # rewrite EXIF as if this were a TIFF file in memory
+                    my %dirInfo = (
+                        DataPt => $segDataPt,
+                        DataPos => $segPos,
+                        DirStart => 6,
+                        Base => $segPos + 6,
+                        OutFile => \$buff,
+                        Parent => $markerName,
+                    );
+                    my $result = $self->ProcessTIFF(\%dirInfo);
+                    $segDataPt = \$buff;
+                    unless ($result > 0) { # check for problems writing the EXIF
+                        last Marker unless $self->Options('IgnoreMinorErrors');
+                        $$segDataPt = $exifAPP1hdr . $self->{EXIF_DATA}; # restore original EXIF
+                        $self->{CHANGED} = $oldChanged;
+                    }
+                    # switch to buffered output if required
+                    if ($self->{PREVIEW_INFO} and not $oldOutfile) {
+                        $writeBuffer = '';
+                        $oldOutfile = $outfile;
+                        $outfile = \$writeBuffer;
+                        # must account for segment, EXIF and TIFF headers
+                        $self->{PREVIEW_INFO}->{Fixup}->{Start} += 18;
+                    }
+                    # delete segment if IFD contains no entries
+                    $del = 1 unless length($$segDataPt) > length($exifAPP1hdr);
+                # check for XMP data
+                } elsif ($$segDataPt =~ /^$xmpAPP1hdr/) {
+                    $segType = 'XMP';
+                    $doneDir{XMP} and $self->Warn('Multiple APP1 XMP segments');
+                    $doneDir{XMP} = 1;
+                    last unless $$editDirs{XMP};
+                    my $start = length $xmpAPP1hdr;
+                    my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
+                    my %dirInfo = (
+                        Base     => 0,
+                        DataPt   => $segDataPt,
+                        DataPos  => $segPos,
+                        DataLen  => $length,
+                        DirStart => $start,
+                        DirLen   => $length - $start,
+                        Parent   => $markerName,
+                    );
+                    my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                    if (defined $newData) {
+                        undef $$segDataPt;  # free the old buffer
+                        # add header to new segment unless empty
+                        $newData = $xmpAPP1hdr . $newData if length $newData;
+                        $segDataPt = \$newData;
+                    } else {
+                        $self->{CHANGED} = $oldChanged;
+                    }
+                    $del = 1 unless length $$segDataPt;
+                }
+            } elsif ($marker == 0xe2) {         # APP2 (ICC Profile, FPXR)
+                if ($$segDataPt =~ /^ICC_PROFILE\0/) {
+                    $segType = 'ICC_Profile';
+                    $$delGroup{ICC_Profile} and $del = 1, last;
+                    # must concatenate blocks of profile
+                    my $block_num = ord(substr($$segDataPt, 12, 1));
+                    my $blocks_tot = ord(substr($$segDataPt, 13, 1));
+                    $combinedSegData = '' if $block_num == 1;
+                    unless (defined $combinedSegData) {
+                        $self->Warn('APP2 ICC_Profile segments out of sequence');
+                        next Marker;
+                    }
+                    $combinedSegData .= substr($$segDataPt, 14);
+                    # continue accumulating segments unless this is the last
+                    next Marker unless $block_num == $blocks_tot;
+                    $doneDir{ICC_Profile} and $self->Warn('Multiple ICC_Profile records');
+                    $doneDir{ICC_Profile} = 1;
+                    $segDataPt = \$combinedSegData;
+                    $length = length $combinedSegData;
+                    my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
+                    my %dirInfo = (
+                        DataPt   => $segDataPt,
+                        DataPos  => $segPos + 14,
+                        DataLen  => $length,
+                        DirStart => 0,
+                        DirLen   => $length,
+                        Parent   => $markerName,
+                    );
+                    my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                    if (defined $newData) {
+                        undef $$segDataPt;  # free the old buffer
+                        $segDataPt = \$newData;
+                    }
+                    length $$segDataPt or $del = 1, last;
+                    # write as ICC multi-segment
+                    WriteMultiSegment($outfile, $marker, "ICC_PROFILE\0", $segDataPt, 'ICC') or $err = 1;
+                    undef $combinedSegData;
+                    undef $$segDataPt;
+                    next Marker;
+                } elsif ($$segDataPt =~ /^FPXR\0/) {
+                    $segType = 'FPXR';
+                    $$delGroup{FlashPix} and $del = 1;
+                }
+            } elsif ($marker == 0xe3) {         # APP3 (Kodak Meta)
+                if ($$segDataPt =~ /^(Meta|META|Exif)\0\0/) {
+                    $segType = 'Kodak Meta';
+                    $$delGroup{Meta} and $del = 1;
+                }
+            } elsif ($marker == 0xe5) {         # APP5 (Ricoh RMETA)
+                if ($$segDataPt =~ /^RMETA\0/) {
+                    $segType = 'Ricoh RMETA';
+                    $$delGroup{RMETA} and $del = 1;
+                }
+            } elsif ($marker == 0xec) {         # APP12 (Ducky)
+                if ($$segDataPt =~ /^Ducky/) {
+                    $segType = 'Ducky';
+                    $$delGroup{Ducky} and $del = 1, last;
+                    $doneDir{Ducky} and $self->Warn('Multiple APP12 Ducky segments');
+                    $doneDir{Ducky} = 1;
+                    last unless $$editDirs{Ducky};
+                    my $tagTablePtr = GetTagTable('Image::ExifTool::APP12::Ducky');
+                    my %dirInfo = (
+                        DataPt   => $segDataPt,
+                        DataPos  => $segPos,
+                        DataLen  => $length,
+                        DirStart => 5,     # directory starts after identifier
+                        DirLen   => $length-5,
+                        Parent   => $markerName,
+                    );
+                    my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                    if (defined $newData) {
+                        undef $$segDataPt;  # free the old buffer
+                        # add header to new segment unless empty
+                        $newData = 'Ducky' . $newData if length $newData;
+                        $segDataPt = \$newData;
+                    } else {
+                        $self->{CHANGED} = $oldChanged;
+                    }
+                    $del = 1 unless length $$segDataPt;
+                }
+            } elsif ($marker == 0xed) {         # APP13 (Photoshop)
+                if ($$segDataPt =~ /^$psAPP13hdr/) {
+                    $segType = 'Photoshop';
+                    # add this data to the combined data if it exists
+                    if (defined $combinedSegData) {
+                        $combinedSegData .= substr($$segDataPt,length($psAPP13hdr));
+                        $segDataPt = \$combinedSegData;
+                        $length = length $combinedSegData;  # update length
+                    }
+                    # peek ahead to see if the next segment is photoshop data too
+                    if ($dirOrder[0] eq 'Photoshop') {
+                        # initialize combined data if necessary
+                        $combinedSegData = $$segDataPt unless defined $combinedSegData;
+                        next Marker;    # get the next segment to combine
+                    }
+                    $doneDir{Photoshop} and $self->Warn('Multiple Photoshop records');
+                    $doneDir{Photoshop} = 1;
+                    # process APP13 Photoshop record
+                    my $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
+                    my %dirInfo = (
+                        DataPt   => $segDataPt,
+                        DataPos  => $segPos,
+                        DataLen  => $length,
+                        DirStart => 14,     # directory starts after identifier
+                        DirLen   => $length-14,
+                        Parent   => $markerName,
+                    );
+                    my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                    if (defined $newData) {
+                        undef $$segDataPt;  # free the old buffer
+                        $segDataPt = \$newData;
+                    } else {
+                        $self->{CHANGED} = $oldChanged;
+                    }
+                    length $$segDataPt or $del = 1, last;
+                    # write as multi-segment
+                    WriteMultiSegment($outfile, $marker, $psAPP13hdr, $segDataPt) or $err = 1;
+                    undef $combinedSegData;
+                    undef $$segDataPt;
+                    next Marker;
+                }
+            } elsif ($marker == 0xfe) {         # COM (JPEG comment)
+                my $newComment;
+                unless ($doneDir{COM}) {
+                    $doneDir{COM} = 1;
+                    unless ($$delGroup{File} and $$delGroup{File} != 2) {
+                        my $tagInfo = $Image::ExifTool::Extra{Comment};
+                        my $newValueHash = $self->GetNewValueHash($tagInfo);
+                        if (IsOverwriting($newValueHash, $segData) or $$delGroup{File}) {
+                            $newComment = GetNewValues($newValueHash);
+                        } else {
+                            delete $$editDirs{COM}; # we aren't editing COM after all
+                            last;
+                        }
+                    }
+                }
+                $verbose > 1 and print $out "    - Comment = '$$segDataPt'\n";
+                if (defined $newComment and length $newComment) {
+                    # write out the comments
+                    $verbose > 1 and print $out "    + Comment = '$newComment'\n";
+                    WriteMultiSegment($outfile, 0xfe, '', \$newComment) or $err = 1;
+                } else {
+                    $verbose and print $out "  Deleting COM segment\n";
+                }
+                ++$self->{CHANGED};     # increment the changed flag
+                undef $segDataPt;       # don't write existing comment
+            }
+            last;   # didn't want to loop anyway
+        }
+        # delete necessary segments (including unknown segments if deleting all)
+        if ($del or ($$delGroup{'*'} and not $segType and $marker>=0xe0 and $marker<=0xef)) {
+            $segType = 'unknown' unless $segType;
+            $verbose and print $out "  Deleting $markerName $segType segment\n";
+            ++$self->{CHANGED};
+            next Marker;
+        }
+        # write out this segment if $segDataPt is still defined
+        if (defined $segDataPt) {
+            # write the data for this record (the data could have been
+            # modified, so recalculate the length word)
+            my $size = length($$segDataPt);
+            if ($size > $maxSegmentLen) {
+                $self->Error("$markerName segment too large! ($size bytes)");
+                $err = 1;
+            } else {
+                $s = pack('n', length($$segDataPt) + 2);
+                Write($outfile, $hdr, $s, $$segDataPt) or $err = 1;
+            }
+            undef $$segDataPt;  # free the buffer
+        }
+    }
+    # if oldOutfile is still set, there was an error copying the JPEG
+    $oldOutfile and return 0;
+    if ($rtnVal) {
+        # add any new trailers we are creating
+        my $trailPt = $self->AddNewTrailers();
+        Write($outfile, $$trailPt) or $err = 1 if $trailPt;
+    }
+    $/ = $oldsep;     # restore separator to original value
+    # set return value to -1 if we only had a write error
+    $rtnVal = -1 if $rtnVal and $err;
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Validate an image for writing
+# Inputs: 0) ExifTool object reference, 1) raw value reference
+# Returns: error string or undef on success
+sub CheckImage($$)
+{
+    my ($self, $valPtr) = @_;
+    if (length($$valPtr) and $$valPtr!~/^\xff\xd8/ and not
+        $self->Options('IgnoreMinorErrors'))
+    {
+        return '[minor] Not a valid image';
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# check a value for validity
+# Inputs: 0) value reference, 1) format string, 2) optional count
+# Returns: error string, or undef on success
+# Notes: May modify value (if a count is specified for a string, it is null-padded
+# to the specified length, and floating point values are rounded to integer if required)
+sub CheckValue($$;$)
+{
+    my ($valPtr, $format, $count) = @_;
+    my (@vals, $n);
+
+    if ($format eq 'string' or $format eq 'undef') {
+        return undef unless $count and $count > 0;
+        my $len = length($$valPtr);
+        if ($format eq 'string') {
+            $len >= $count and return 'String too long';
+        } else {
+            $len > $count and return 'Data too long';
+        }
+        if ($len < $count) {
+            $$valPtr .= "\0" x ($count - $len);
+        }
+        return undef;
+    }
+    if ($count and $count != 1) {
+        @vals = split(' ',$$valPtr);
+        $count < 0 and ($count = @vals or return undef);
+    } else {
+        $count = 1;
+        @vals = ( $$valPtr );
+    }
+    return "Too many values specified ($count required)" if @vals > $count;
+    return "Not enough values specified ($count required)" if @vals < $count;
+    my $val;
+    for ($n=0; $n<$count; ++$n) {
+        $val = shift @vals;
+        if ($format =~ /^int/) {
+            # make sure the value is integer
+            unless (IsInt($val)) {
+                if (IsHex($val)) {
+                    $val = $$valPtr = hex($val);
+                } else {
+                    # round single floating point values to the nearest integer
+                    return 'Not an integer' unless IsFloat($val) and $count == 1;
+                    $val = $$valPtr = int($val + ($val < 0 ? -0.5 : 0.5));
+                }
+            }
+            my $rng = $intRange{$format} or return "Bad int format: $format";
+            return "Value below $format minimum" if $val < $$rng[0];
+            # (allow 0xfeedfeed code as value for 16-bit pointers)
+            return "Value above $format maximum" if $val > $$rng[1] and $val != 0xfeedfeed;
+        } elsif ($format =~ /^rational/ or $format eq 'float' or $format eq 'double') {
+            # make sure the value is a valid floating point number
+            return 'Not a floating point number' unless IsFloat($val);
+            if ($format =~ /^rational\d+u$/ and $val < 0) {
+                return 'Must be a positive number';
+            }
+        }
+    }
+    return undef;   # success!
+}
+
+#------------------------------------------------------------------------------
+# check new value for binary data block
+# Inputs: 0) ExifTool object ref, 1) tagInfo hash ref, 2) raw value ref
+# Returns: error string or undef (and may modify value) on success
+sub CheckBinaryData($$$)
+{
+    my ($self, $tagInfo, $valPtr) = @_;
+    my $format = $$tagInfo{Format};
+    unless ($format) {
+        my $table = $$tagInfo{Table};
+        if ($table and $$table{FORMAT}) {
+            $format = $$table{FORMAT};
+        } else {
+            # use default 'int8u' unless specified
+            $format = 'int8u';
+        }
+    }
+    my $count;
+    if ($format =~ /(.*)\[(.*)\]/) {
+        $format = $1;
+        $count = $2;
+        # can't evaluate $count now because we don't know $size yet
+        undef $count if $count =~ /\$size/;
+    }
+    return CheckValue($valPtr, $format, $count);
+}
+
+#------------------------------------------------------------------------------
+# copy image data from one file to another
+# Inputs: 0) ExifTool object reference
+#         1) reference to list of image data [ position, size, pad bytes ]
+#         2) output file ref
+# Returns: true on success
+sub CopyImageData($$$)
+{
+    my ($self, $imageDataBlocks, $outfile) = @_;
+    my $raf = $self->{RAF};
+    my ($dataBlock, $buff, $err);
+    foreach $dataBlock (@$imageDataBlocks) {
+        my ($pos, $size, $pad) = @$dataBlock;
+        $raf->Seek($pos, 0) or $err = 'read', last;
+        while ($size) {
+            # copy in blocks of 64kB or smaller
+            my $n = $size > 65536 ? 65536 : $size;
+            $raf->Read($buff, $n) == $n or $err = 'read', last;
+            Write($outfile, $buff) or $err = 'writ', last;
+            $size -= $n;
+        }
+        # pad if necessary
+        Write($outfile, "\0" x $pad) or $err = 'writ' if $pad;
+        last if $err;
+    }
+    if ($err) {
+        $self->Error("Error ${err}ing image data");
+        return 0;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# write to binary data block
+# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref
+# Returns: Binary data block or undefined on error
+sub WriteBinaryData($$$)
+{
+    my ($self, $dirInfo, $tagTablePtr) = @_;
+    $self or return 1;    # allow dummy access to autoload this package
+
+    # get default format ('int8u' unless specified)
+    my $defaultFormat = $$tagTablePtr{FORMAT} || 'int8u';
+    my $increment = FormatSize($defaultFormat);
+    unless ($increment) {
+        warn "Unknown format $defaultFormat\n";
+        return undef;
+    }
+    # extract data members first if necessary
+    if ($$tagTablePtr{DATAMEMBER}) {
+        $$dirInfo{DataMember} = $$tagTablePtr{DATAMEMBER};
+        $self->ProcessBinaryData($dirInfo, $tagTablePtr);
+        delete $$dirInfo{DataMember};
+    }
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $dirStart;
+    my $newData = substr($$dataPt, $dirStart, $dirLen) or return undef;
+    my $dirName = $$dirInfo{DirName};
+    my $verbose = $self->Options('Verbose');
+    my $tagInfo;
+    $dataPt = \$newData;
+    foreach $tagInfo ($self->GetNewTagInfoList($tagTablePtr)) {
+        my $tagID = $tagInfo->{TagID};
+        # must check to be sure this tagInfo applies (ie. evaluate the condition!)
+        my $writeInfo = $self->GetTagInfo($tagTablePtr, $tagID);
+        next unless $writeInfo and $writeInfo eq $tagInfo;
+        my $count = 1;
+        my $format = $$tagInfo{Format};
+        if ($format) {
+            if ($format =~ /(.*)\[(.*)\]/) {
+                $format = $1;
+                $count = $2;
+                my $size = $dirLen; # used in eval
+                # evaluate count to allow count to be based on previous values
+                #### eval Format size (%val, $size)
+                $count = eval $count;
+                $@ and warn($@), next;
+            }
+        } else {
+            $format = $defaultFormat;
+        }
+        my $entry = $tagID * $increment;        # relative offset of this entry
+        my $val = ReadValue($dataPt, $entry, $format, $count, $dirLen-$entry);
+        next unless defined $val;
+        my $newValueHash = $self->GetNewValueHash($tagInfo);
+        next unless IsOverwriting($newValueHash, $val);
+        my $newVal = GetNewValues($newValueHash);
+        next unless defined $newVal;    # can't delete from a binary table
+        # set the size
+        if ($$tagInfo{DataTag} and not $$tagInfo{IsOffset}) {
+            warn 'Internal error' unless $newVal == 0xfeedfeed;
+            my $data = $self->GetNewValues($$tagInfo{DataTag});
+            $newVal = length($data) if defined $data;
+        }
+        my $rtnVal = WriteValue($newVal, $format, $count, $dataPt, $entry);
+        if (defined $rtnVal) {
+            if ($verbose > 1) {
+                my $out = $self->{OPTIONS}->{TextOut};
+                print $out "    - $dirName:$$tagInfo{Name} = '$val'\n";
+                print $out "    + $dirName:$$tagInfo{Name} = '$newVal'\n";
+            }
+            ++$self->{CHANGED};
+        }
+    }
+    # add necessary fixups for any offsets
+    if ($tagTablePtr->{IS_OFFSET} and $$dirInfo{Fixup}) {
+        my $fixup = $$dirInfo{Fixup};
+        my $tagID;
+        foreach $tagID (@{$tagTablePtr->{IS_OFFSET}}) {
+            $tagInfo = $self->GetTagInfo($tagTablePtr, $tagID) or next;
+            my $entry = $tagID * $increment;    # (no offset to dirStart for new dir data)
+            next unless $entry <= $dirLen - 4;
+            # (Ricoh has 16-bit preview image offsets, so can't just assume int32u)
+            my $format = $$tagInfo{Format} || $$tagTablePtr{FORMAT} || 'int32u';
+            $fixup->AddFixup($entry, $$tagInfo{DataTag}, $format);
+            # handle the preview image now if this is a JPEG file
+            next unless $self->{FILE_TYPE} eq 'JPEG' and $$tagInfo{DataTag} and
+                $$tagInfo{DataTag} eq 'PreviewImage' and defined $$tagInfo{OffsetPair};
+            my $offset = ReadValue($dataPt, $entry, $format, 1, $dirLen-$entry);
+            $entry = $$tagInfo{OffsetPair} * $increment;
+            my $size = ReadValue($dataPt, $entry, $format, 1, $dirLen-$entry);
+            my $previewInfo = $self->{PREVIEW_INFO};
+            $previewInfo or $previewInfo = $self->{PREVIEW_INFO} = { };
+            # set flag indicating we are using short pointers
+            $previewInfo->{IsShort} = 1 unless $format eq 'int32u';
+            $previewInfo->{Data} = $self->GetNewValues('PreviewImage');
+            unless (defined $previewInfo->{Data}) {
+                if ($offset >= 0 and $offset + $size <= $$dirInfo{DataLen}) {
+                    $previewInfo->{Data} = substr(${$$dirInfo{DataPt}},$offset,$size);
+                } else {
+                    $previewInfo->{Data} = 'LOAD'; # flag to load preview later
+                }
+            }
+        }
+    }
+    return $newData;
+}
+
+#------------------------------------------------------------------------------
+# Write TIFF as a directory
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: New directory data or undefined on error
+sub WriteTIFF($$$)
+{
+    my ($self, $dirInfo, $tagTablePtr) = @_;
+    my $buff;
+    $$dirInfo{OutFile} = \$buff;
+    return $buff if $self->ProcessTIFF($dirInfo, $tagTablePtr) > 0;
+    return undef;
+}
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Writer.pl - ExifTool routines for writing meta information
+
+=head1 SYNOPSIS
+
+These routines are autoloaded by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains ExifTool write routines and other infrequently
+used routines.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/ExifTool/XMP.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/ExifTool/XMP.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/ExifTool/XMP.pm	(revision 20131)
@@ -0,0 +1,2291 @@
+#------------------------------------------------------------------------------
+# File:         XMP.pm
+#
+# Description:  Read XMP meta information
+#
+# Revisions:    11/25/2003 - P. Harvey Created
+#               10/28/2004 - P. Harvey Major overhaul to conform with XMP spec
+#               02/27/2005 - P. Harvey Also read UTF-16 and UTF-32 XMP
+#               08/30/2005 - P. Harvey Split tag tables into separate namespaces
+#               10/24/2005 - P. Harvey Added ability to parse .XMP files
+#               08/25/2006 - P. Harvey Added ability to handle blank nodes
+#               08/22/2007 - P. Harvey Added ability to handle alternate language tags
+#
+# References:   1) http://www.adobe.com/products/xmp/pdfs/xmpspec.pdf
+#               2) http://www.w3.org/TR/rdf-syntax-grammar/  (20040210)
+#               3) http://www.portfoliofaq.com/pfaq/v7mappings.htm
+#               4) http://www.iptc.org/IPTC4XMP/
+#               5) http://creativecommons.org/technology/xmp
+#               6) http://www.optimasc.com/products/fileid/xmp-extensions.pdf
+#               7) Lou Salkind private communication
+#               8) http://partners.adobe.com/public/developer/en/xmp/sdk/XMPspecification.pdf
+#
+# Notes:      - I am handling property qualifiers as if they were separate
+#               properties (with no associated namespace).
+#
+#             - Currently, there is no special treatment of the following
+#               properties which could potentially affect the extracted
+#               information: xml:base, rdf:parseType (note that parseType
+#               Literal isn't allowed by the XMP spec).
+#
+#             - The family 2 group names will be set to 'Unknown' for any XMP
+#               tags not found in the XMP or Exif tag tables.
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::XMP;
+
+use strict;
+use vars qw($VERSION $AUTOLOAD @ISA @EXPORT_OK);
+use Image::ExifTool qw(:Utils);
+use Image::ExifTool::Exif;
+require Exporter;
+
+$VERSION = '1.78';
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(EscapeXML UnescapeXML);
+
+sub ProcessXMP($$;$);
+sub WriteXMP($$;$);
+sub ParseXMPElement($$$;$$$);
+sub DecodeBase64($);
+sub SaveBlankInfo($$$;$);
+sub ProcessBlankInfo($$$;$);
+sub ValidateXMP($;$);
+sub UnescapeChar($$);
+
+# conversions for GPS coordinates
+sub ToDegrees
+{
+    require Image::ExifTool::GPS;
+    Image::ExifTool::GPS::ToDegrees($_[0], 1);
+}
+my %latConv = (
+    ValueConv    => \&ToDegrees,
+    RawConv => 'require Image::ExifTool::GPS; $val', # to load Composite tags and routines
+    ValueConvInv => q{
+        require Image::ExifTool::GPS;
+        Image::ExifTool::GPS::ToDMS($self, $val, 2, "N");
+    },
+    PrintConv    => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
+    PrintConvInv => \&ToDegrees,
+);
+my %longConv = (
+    ValueConv    => \&ToDegrees,
+    RawConv => 'require Image::ExifTool::GPS; $val',
+    ValueConvInv => q{
+        require Image::ExifTool::GPS;
+        Image::ExifTool::GPS::ToDMS($self, $val, 2, "E");
+    },
+    PrintConv    => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
+    PrintConvInv => \&ToDegrees,
+);
+my %dateTimeInfo = (
+    Groups => { 2 => 'Time'   },
+    Writable => 'date',
+    Shift => 'Time',
+    PrintConv => '$self->ConvertDateTime($val)',
+);
+
+# XMP namespaces which we don't want to contribute to generated EXIF tag names
+my %ignoreNamespace = ( 'x'=>1, 'rdf'=>1, 'xmlns'=>1, 'xml'=>1);
+
+# translate XMP namespaces when reading
+my %xlatNamespace = (
+    # shorten ugly IPTC Core namespace prefix
+    'Iptc4xmpCore' => 'iptcCore',
+    'photomechanic'=> 'photomech',
+    'MicrosoftPhoto' => 'microsoft',
+    # also translate older 'xap...' prefixes to 'xmp...'
+    'xap'          => 'xmp',
+    'xapBJ'        => 'xmpBJ',
+    'xapMM'        => 'xmpMM',
+    'xapRights'    => 'xmpRights',
+);
+
+# these are the attributes that we handle for properties that contain
+# sub-properties.  Attributes for simple properties are easy, and we
+# just copy them over.  These are harder since we don't store attributes
+# for properties without simple values.  (maybe this will change...)
+my %recognizedAttrs = (
+    'x:xaptk' => 1,
+    'x:xmptk' => 1,
+    'rdf:about' => 1,
+    'rdf:parseType' => 1,
+    'rdf:nodeID' => 1,
+);
+
+# main XMP tag table
+%Image::ExifTool::XMP::Main = (
+    GROUPS => { 2 => 'Unknown' },
+    PROCESS_PROC => \&ProcessXMP,
+    WRITE_PROC => \&WriteXMP,
+    dc => {
+        Name => 'dc', # (otherwise generated name would be 'Dc')
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::dc' },
+    },
+    xmp => {
+        Name => 'xmp',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmp' },
+    },
+    xmpDM => {
+        Name => 'xmpDM',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmpDM' },
+    },
+    xmpRights => {
+        Name => 'xmpRights',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmpRights' },
+    },
+    xmpMM => {
+        Name => 'xmpMM',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmpMM' },
+    },
+    xmpBJ => {
+        Name => 'xmpBJ',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmpBJ' },
+    },
+    xmpTPg => {
+        Name => 'xmpTPg',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmpTPg' },
+    },
+    pdf => {
+        Name => 'pdf',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::pdf' },
+    },
+    photoshop => {
+        Name => 'photoshop',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::photoshop' },
+    },
+    crs => {
+        Name => 'crs',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::crs' },
+    },
+    # crss - it would be difficult to add the ability to write this
+    aux => {
+        Name => 'aux',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::aux' },
+    },
+    tiff => {
+        Name => 'tiff',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::tiff' },
+    },
+    exif => {
+        Name => 'exif',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::exif' },
+    },
+    iptcCore => {
+        Name => 'iptcCore',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::iptcCore' },
+    },
+    PixelLive => {
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::PixelLive' },
+    },
+    xmpPLUS => {
+        Name => 'xmpPLUS',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::xmpPLUS' },
+    },
+    cc => {
+        Name => 'cc',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::cc' },
+    },
+    dex => {
+        Name => 'dex',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::dex' },
+    },
+    photomech => {
+        Name => 'photomech',
+        SubDirectory => { TagTable => 'Image::ExifTool::PhotoMechanic::XMP' },
+    },
+    mediapro => {
+        Name => 'mediapro',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::MediaPro' },
+    },
+    microsoft => {
+        Name => 'microsoft',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Microsoft' },
+    },
+    lr => {
+        Name => 'lr',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Lightroom' },
+    },
+    DICOM => {
+        Name => 'DICOM',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::DICOM' },
+    },
+);
+
+#
+# Tag tables for all XMP schemas:
+#
+# Writable - only need to define this for writable tags if not plain text
+#            (boolean, integer, rational, real, date or lang-alt)
+# List - XMP list type (Bag, Seq or Alt, or set to 1 for elements in Struct lists)
+#
+# (Note that family 1 group names are generated from the property namespace, not
+#  the group1 names below which exist so the groups will appear in the list.)
+#
+my %xmpTableDefaults = (
+    WRITE_PROC => \&WriteXMP,
+    WRITABLE => 'string',
+    LANG_INFO => \&GetLangInfo,
+);
+
+# Dublin Core schema properties (dc)
+%Image::ExifTool::XMP::dc = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-dc', 2 => 'Other' },
+    NAMESPACE => 'dc',
+    NOTES => 'Dublin Core schema tags.',
+    contributor => { Groups => { 2 => 'Author' }, List => 'Bag' },
+    coverage    => { },
+    creator     => { Groups => { 2 => 'Author' }, List => 'Seq' },
+    date        => { %dateTimeInfo, List => 'Seq' },
+    description => { Groups => { 2 => 'Image'  }, Writable => 'lang-alt' },
+   'format'     => { Groups => { 2 => 'Image'  } },
+    identifier  => { Groups => { 2 => 'Image'  } },
+    language    => { List => 'Bag' },
+    publisher   => { Groups => { 2 => 'Author' }, List => 'Bag' },
+    relation    => { List => 'Bag' },
+    rights      => { Groups => { 2 => 'Author' }, Writable => 'lang-alt' },
+    source      => { Groups => { 2 => 'Author' } },
+    subject     => { Groups => { 2 => 'Image'  }, List => 'Bag' },
+    title       => { Groups => { 2 => 'Image'  }, Writable => 'lang-alt' },
+    type        => { Groups => { 2 => 'Image'  }, List => 'Bag' },
+);
+
+# XMP Basic schema properties (xmp, xap)
+%Image::ExifTool::XMP::xmp = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-xmp', 2 => 'Image' },
+    NAMESPACE => 'xmp',
+    NOTES => q{
+        XMP Basic schema tags.  If the older "xap", "xapBJ", "xapMM" or "xapRights"
+        namespace prefixes are found, they are translated to the newer "xmp",
+        "xmpBJ", "xmpMM" and "xmpRights" prefixes for use in family 1 group names.
+    },
+    Advisory    => { List => 'Bag' },
+    BaseURL     => { },
+    CreateDate  => { %dateTimeInfo },
+    CreatorTool => { },
+    Identifier  => { Avoid => 1, List => 'Bag' },
+    Label       => { },
+    MetadataDate=> { %dateTimeInfo },
+    ModifyDate  => { %dateTimeInfo },
+    Nickname    => { },
+    Rating      => { Writable => 'integer' },
+    Thumbnails  => {
+        SubDirectory => { },
+        Struct => 'Thumbnail',
+        List => 'Alt',
+    },
+    ThumbnailsHeight    => { List => 1 },
+    ThumbnailsWidth     => { List => 1 },
+    ThumbnailsFormat    => { List => 1 },
+    ThumbnailsImage     => {
+        # Eventually may want to handle this like a normal thumbnail image
+        # -- but not yet!  (need to write EncodeBase64() routine....)
+        # Name => 'ThumbnailImage',
+        List => 1,
+        # translate Base64-encoded thumbnail
+        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
+    },
+);
+
+# XMP Rights Management schema properties (xmpRights, xapRights)
+%Image::ExifTool::XMP::xmpRights = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-xmpRights', 2 => 'Author' },
+    NAMESPACE => 'xmpRights',
+    NOTES => 'XMP Rights Management schema tags.',
+    Certificate     => { },
+    Marked          => { Writable => 'boolean' },
+    Owner           => { List => 'Bag' },
+    UsageTerms      => { Writable => 'lang-alt' },
+    WebStatement    => { },
+);
+
+# XMP Media Management schema properties (xmpMM, xapMM)
+%Image::ExifTool::XMP::xmpMM = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-xmpMM', 2 => 'Other' },
+    NAMESPACE => 'xmpMM',
+    NOTES => 'XMP Media Management schema tags.',
+    DerivedFrom     => {
+        SubDirectory => { },
+        Struct => 'ResourceRef',
+    },
+    DerivedFromInstanceID       => { },
+    DerivedFromDocumentID       => { },
+    DerivedFromVersionID        => { },
+    DerivedFromRenditionClass   => { },
+    DerivedFromRenditionParams  => { },
+    DerivedFromManager          => { },
+    DerivedFromManagerVariant   => { },
+    DerivedFromManageTo         => { },
+    DerivedFromManageUI         => { },
+    DocumentID      => { },
+    History         => {
+        SubDirectory => { },
+        Struct => 'ResourceEvent',
+        List => 'Seq',
+    },
+    # we treat these like list items since History is a list
+    HistoryAction           => { List => 1 },
+    HistoryInstanceID       => { List => 1 },
+    HistoryParameters       => { List => 1 },
+    HistorySoftwareAgent    => { List => 1 },
+    HistoryWhen             => { List => 1, %dateTimeInfo },
+    InstanceID      => { }, #PH (CS3)
+    ManagedFrom     => { SubDirectory => { }, Struct => 'ResourceRef' },
+    ManagedFromInstanceID       => { },
+    ManagedFromDocumentID       => { },
+    ManagedFromVersionID        => { },
+    ManagedFromRenditionClass   => { },
+    ManagedFromRenditionParams  => { },
+    ManagedFromManager          => { },
+    ManagedFromManagerVariant   => { },
+    ManagedFromManageTo         => { },
+    ManagedFromManageUI         => { },
+    Manager         => { Groups => { 2 => 'Author' } },
+    ManageTo        => { Groups => { 2 => 'Author' } },
+    ManageUI        => { },
+    ManagerVariant  => { },
+    PreservedFileName => { },   # undocumented
+    RenditionClass  => { },
+    RenditionParams => { },
+    VersionID       => { },
+    Versions        => {
+        SubDirectory => { },
+        Struct => 'Version',
+        List => 'Seq',
+    },
+    VersionsComments    => { List => 1 },   # we treat these like list items
+    VersionsEvent       => { SubDirectory => { }, Struct => 'ResourceEvent' },
+    VersionsEventAction         => { List => 1 },
+    VersionsEventInstanceID     => { List => 1 },
+    VersionsEventParameters     => { List => 1 },
+    VersionsEventSoftwareAgent  => { List => 1 },
+    VersionsEventWhen           => { List => 1, %dateTimeInfo },
+    VersionsModifyDate          => { List => 1, %dateTimeInfo },
+    VersionsModifier            => { List => 1 },
+    VersionsVersion             => { List => 1 },
+    LastURL                     => { },
+    RenditionOf         => { SubDirectory => { }, Struct => 'ResourceRef' },
+    RenditionOfInstanceID       => { },
+    RenditionOfDocumentID       => { },
+    RenditionOfVersionID        => { },
+    RenditionOfRenditionClass   => { },
+    RenditionOfRenditionParams  => { },
+    RenditionOfManager          => { },
+    RenditionOfManagerVariant   => { },
+    RenditionOfManageTo         => { },
+    RenditionOfManageUI         => { },
+    SaveID          => { Writable => 'integer' },
+);
+
+# XMP Basic Job Ticket schema properties (xmpBJ, xapBJ)
+%Image::ExifTool::XMP::xmpBJ = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-xmpBJ', 2 => 'Other' },
+    NAMESPACE => 'xmpBJ',
+    NOTES => 'XMP Basic Job Ticket schema tags.',
+    # Note: JobRef is a List of structures.  To accomplish this, we set the XMP
+    # List=>'Bag', but since SubDirectory is defined, this tag isn't writable
+    # directly.  Then we need to set List=>1 for the members so the Writer logic
+    # will allow us to add list elements.
+    JobRef => {
+        SubDirectory => { },
+        Struct => 'JobRef',
+        List => 'Bag',
+    },
+    JobRefName  => { List => 1 },   # we treat these like list items
+    JobRefId    => { List => 1 },
+    JobRefUrl   => { List => 1 },
+);
+
+# XMP Paged-Text schema properties (xmpTPg)
+%Image::ExifTool::XMP::xmpTPg = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-xmpTPg', 2 => 'Image' },
+    NAMESPACE => 'xmpTPg',
+    NOTES => 'XMP Paged-Text schema tags.',
+    MaxPageSize => { SubDirectory => { }, Struct => 'Dimensions' },
+    MaxPageSizeW    => { Writable => 'real' },
+    MaxPageSizeH    => { Writable => 'real' },
+    MaxPageSizeUnit => { },
+    NPages      => { Writable => 'integer' },
+    Fonts       => {
+        SubDirectory => { },
+        Struct => 'Font',
+        List => 'Bag',
+    },
+    FontsFontName       => { List => 1 },
+    FontsFontFamily     => { List => 1 },
+    FontsFontFace       => { List => 1 },
+    FontsFontType       => { List => 1 },
+    FontsVersionString  => { List => 1 },
+    FontsComposite      => { List => 1, Writable => 'boolean' },
+    FontsFontFileName   => { List => 1 },
+    FontsChildFontFiles => { List => 1 },
+    Colorants   => {
+        SubDirectory => { },
+        Struct => 'Colorant',
+        List => 'Seq',
+    },
+    ColorantsSwatchName => { List => 1 },
+    ColorantsMode       => { List => 1 },
+    ColorantsType       => { List => 1 },
+    ColorantsCyan       => { List => 1, Writable => 'real' },
+    ColorantsMagenta    => { List => 1, Writable => 'real' },
+    ColorantsYellow     => { List => 1, Writable => 'real' },
+    ColorantsBlack      => { List => 1, Writable => 'real' },
+    ColorantsRed        => { List => 1, Writable => 'integer' },
+    ColorantsGreen      => { List => 1, Writable => 'integer' },
+    ColorantsBlue       => { List => 1, Writable => 'integer' },
+    ColorantsL          => { List => 1, Writable => 'real' },
+    ColorantsA          => { List => 1, Writable => 'integer' },
+    ColorantsB          => { List => 1, Writable => 'integer' },
+    PlateNames  => { List => 'Seq' },
+);
+
+# XMP Dynamic Media schema properties (xmpDM)
+%Image::ExifTool::XMP::xmpDM = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-xmpDM', 2 => 'Image' },
+    NAMESPACE => 'xmpDM',
+    NOTES => 'XMP Dynamic Media schema tags.',
+    projectRef => {
+        SubDirectory => { },
+        Struct => 'ProjectLink',
+    },
+    projectRefType      => { },
+    projectRefPath      => { },
+    videoFrameRate      => { },
+    videoFrameSize => {
+        SubDirectory => { },
+        Struct => 'Dimensions',
+    },
+    videoFrameSizeW     => { Writable => 'real' },
+    videoFrameSizeH     => { Writable => 'real' },
+    videoFrameSizeUnit  => { },
+    videoPixelAspectRatio => { Writable => 'rational' },
+    videoPixelDepth     => { },
+    videoColorSpace     => { },
+    videoAlphaMode      => { },
+    videoAlphaPremultipleColor => {
+        SubDirectory => { },
+        Struct => 'Colorant',
+    },
+    videoAlphaPremultipleColorSwatchName => { },
+    videoAlphaPremultipleColorMode       => { },
+    videoAlphaPremultipleColorType       => { },
+    videoAlphaPremultipleColorCyan       => { Writable => 'real' },
+    videoAlphaPremultipleColorMagenta    => { Writable => 'real' },
+    videoAlphaPremultipleColorYellow     => { Writable => 'real' },
+    videoAlphaPremultipleColorBlack      => { Writable => 'real' },
+    videoAlphaPremultipleColorRed        => { Writable => 'integer' },
+    videoAlphaPremultipleColorGreen      => { Writable => 'integer' },
+    videoAlphaPremultipleColorBlue       => { Writable => 'integer' },
+    videoAlphaPremultipleColorL          => { Writable => 'real' },
+    videoAlphaPremultipleColorA          => { Writable => 'integer' },
+    videoAlphaPremultipleColorB          => { Writable => 'integer' },
+    videoAlphaUnityIsTransparent => { Writable => 'boolean' },
+    videoCompressor     => { },
+    videoFieldOrder     => { },
+    pullDown            => { },
+    audioSampleRate     => { Writable => 'integer' },
+    audioSampleType     => { },
+    audioChannelType    => { },
+    audioCompressor     => { },
+    speakerPlacement    => { },
+    fileDataRate        => { Writable => 'rational' },
+    tapeName            => { },
+    altTapeName         => { },
+    startTimecode => {
+        SubDirectory => { },
+        Struct => 'Timecode',
+    },
+    startTimecodeTimeValue  => { },
+    startTimecodeTimeFormat => { },
+    altTimecode => {
+        SubDirectory => { },
+        Struct => 'Timecode',
+    },
+    altTimecodeTimeValue    => { },
+    altTimecodeTimeFormat   => { },
+    duration            => { },
+    scene               => { Avoid => 1 },
+    shotName            => { },
+    shotDate            => { %dateTimeInfo },
+    shotLocation        => { },
+    logComment          => { },
+    markers => {
+        SubDirectory => { },
+        Struct => 'Marker',
+        List => 'Seq',
+    },
+    markersStartTime    => { List => 1 },
+    markersDuration     => { List => 1 },
+    markersComment      => { List => 1 },
+    markersName         => { List => 1 },
+    markersLocation     => { List => 1 },
+    markersTarget       => { List => 1 },
+    markersType         => { List => 1 },
+    contributedMedia => {
+        SubDirectory => { },
+        Struct => 'Media',
+        List => 'Bag',
+    },
+    contributedMediaPath         => { List => 1 },
+    contributedMediaTrack        => { List => 1 },
+    contributedMediaStartTime    => { List => 1 },
+    contributedMediaDuration     => { List => 1 },
+    contributedMediaManaged      => { List => 1, Writable => 'boolean' },
+    contributedMediaWebStatement => { List => 1 },
+    absPeakAudioFilePath => { },
+    relativePeakAudioFilePath => { },
+    videoModDate    => { %dateTimeInfo },
+    audioModDate    => { %dateTimeInfo },
+    metadataModDate => { %dateTimeInfo },
+    artist          => { Avoid => 1, Groups => { 2 => 'Author' } },
+    album           => { },
+    trackNumber     => { Writable => 'integer' },
+    genre           => { },
+    copyright       => { Avoid => 1, Groups => { 2 => 'Author' } },
+    releaseDate     => { %dateTimeInfo },
+    composer        => { Groups => { 2 => 'Author' } },
+    engineer        => { },
+    tempo           => { Writable => 'real' },
+    instrument      => { },
+    introTime       => { },
+    outCue          => { },
+    relativeTimestamp => { },
+    loop            => { Writable => 'boolean' },
+    numberOfBeats   => { Writable => 'real' },
+    key             => { },
+    stretchMode     => { },
+    timeScaleParams => {
+        SubDirectory => { },
+        Struct => 'TimeScaleStretch',
+    },
+    timeScaleParamsQuality  => { },
+    timeScaleParamsFrameSize=> { Writable => 'real' },
+    timeScaleParamsFrameOverlappingPercentage => { Writable => 'real' },
+    resampleParams => {
+        SubDirectory => { },
+        Struct => 'ResampleStretch',
+    },
+    resampleParamsQuality   => { },
+    beatSpliceParams => {
+        SubDirectory => { },
+        Struct => 'BeatSpliceStretch',
+    },
+    beatSpliceParamsUseFileBeatsMarker => { Writable => 'boolean' },
+    beatSpliceParamsRiseInDecibel      => { Writable => 'real' },
+    beatSpliceParamsRiseInTimeDuration => { },
+    timeSignature   => { },
+    scaleType       => { },
+);
+
+# PDF schema properties (pdf)
+%Image::ExifTool::XMP::pdf = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-pdf', 2 => 'Image' },
+    NAMESPACE => 'pdf',
+    NOTES => q{
+        Adobe PDF schema tags.  The official XMP specification defines only
+        Keywords, PDFVersion and Producer.  The other tags are included because they
+        have been observed in PDF files, but Creator, Subject and Title are avoided
+        when writing due to name conflicts with XMP-dc tags.
+    },
+    Author      => { Groups => { 2 => 'Author' } }, #PH
+    ModDate     => { %dateTimeInfo }, #PH
+    CreationDate=> { %dateTimeInfo }, #PH
+    Creator     => { Groups => { 2 => 'Author' }, Avoid => 1 },
+    Subject     => { Avoid => 1 },
+    Title       => { Avoid => 1 },
+    Keywords    => { },
+    PDFVersion  => { },
+    Producer    => { Groups => { 2 => 'Author' } },
+);
+
+# Photoshop schema properties (photoshop)
+%Image::ExifTool::XMP::photoshop = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-photoshop', 2 => 'Image' },
+    NAMESPACE => 'photoshop',
+    NOTES => 'Adobe Photoshop schema tags.',
+    AuthorsPosition => { Groups => { 2 => 'Author' } },
+    CaptionWriter   => { Groups => { 2 => 'Author' } },
+    Category        => { },
+    City            => { Groups => { 2 => 'Location' } },
+    Country         => { Groups => { 2 => 'Location' } },
+    ColorMode       => { }, #PH
+    Credit          => { Groups => { 2 => 'Author' } },
+    DateCreated     => { %dateTimeInfo },
+    History         => { }, #PH (CS3)
+    Headline        => { },
+    Instructions    => { },
+    ICCProfile      => { Name => 'ICCProfileName' }, #PH
+    LegacyIPTCDigest=> { }, #PH
+    SidecarForExtension => { }, #PH (CS3)
+    Source          => { Groups => { 2 => 'Author' }, Avoid => 1 },
+    State           => { Groups => { 2 => 'Location' } },
+    # the documentation doesn't show this as a 'Bag', but that's the
+    # way Photoshop7.0 writes it - PH
+    SupplementalCategories  => { List => 'Bag' },
+    TransmissionReference   => { },
+    Urgency         => { Writable => 'integer' },
+);
+
+# Photoshop Camera Raw Schema properties (crs) - (ref 8,PH)
+%Image::ExifTool::XMP::crs = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-crs', 2 => 'Image' },
+    NAMESPACE => 'crs',
+    NOTES => 'Photoshop Camera Raw Schema tags.',
+    AlreadyApplied  => { Writable => 'boolean' }, #PH (written by LightRoom beta 4.1)
+    AutoBrightness  => { Writable => 'boolean' },
+    AutoContrast    => { Writable => 'boolean' },
+    AutoExposure    => { Writable => 'boolean' },
+    AutoShadows     => { Writable => 'boolean' },
+    BlueHue         => { Writable => 'integer' },
+    BlueSaturation  => { Writable => 'integer' },
+    Brightness      => { Writable => 'integer' },
+    CameraProfile   => { },
+    ChromaticAberrationB=> { Writable => 'integer' },
+    ChromaticAberrationR=> { Writable => 'integer' },
+    ColorNoiseReduction => { Writable => 'integer' },
+    Contrast        => { Writable => 'integer', Avoid => 1 },
+    CropTop         => { Writable => 'real' },
+    CropLeft        => { Writable => 'real' },
+    CropBottom      => { Writable => 'real' },
+    CropRight       => { Writable => 'real' },
+    CropAngle       => { Writable => 'real' },
+    CropWidth       => { Writable => 'real' },
+    CropHeight      => { Writable => 'real' },
+    CropUnits => {
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'pixels',
+            1 => 'inches',
+            2 => 'cm',
+        },
+    },
+    Exposure        => { Writable => 'real' },
+    GreenHue        => { Writable => 'integer' },
+    GreenSaturation => { Writable => 'integer' },
+    HasCrop         => { Writable => 'boolean' },
+    HasSettings     => { Writable => 'boolean' },
+    LuminanceSmoothing  => { Writable => 'integer' },
+    RawFileName     => { },
+    RedHue          => { Writable => 'integer' },
+    RedSaturation   => { Writable => 'integer' },
+    Saturation      => { Writable => 'integer', Avoid => 1 },
+    Shadows         => { Writable => 'integer' },
+    ShadowTint      => { Writable => 'integer' },
+    Sharpness       => { Writable => 'integer', Avoid => 1 },
+    Temperature     => { Writable => 'integer' },
+    Tint            => { Writable => 'integer' },
+    ToneCurve       => { List => 'Seq' },
+    ToneCurveName => {
+        PrintConv => {
+            Linear           => 'Linear',
+           'Medium Contrast' => 'Medium Contrast',
+           'Strong Contrast' => 'Strong Contrast',
+            Custom           => 'Custom',
+        },
+    },
+    Version         => { },
+    VignetteAmount  => { Writable => 'integer' },
+    VignetteMidpoint=> { Writable => 'integer' },
+    WhiteBalance    => {
+        Avoid => 1,
+        PrintConv => {
+           'As Shot'    => 'As Shot',
+            Auto        => 'Auto',
+            Daylight    => 'Daylight',
+            Cloudy      => 'Cloudy',
+            Shade       => 'Shade',
+            Tungsten    => 'Tungsten',
+            Fluorescent => 'Fluorescent',
+            Flash       => 'Flash',
+            Custom      => 'Custom',
+        },
+    },
+    # new tags observed in Adobe Lightroom output - PH
+    CameraProfileDigest         => { },
+    Clarity                     => { Writable => 'integer' },
+    ConvertToGrayscale          => { Writable => 'boolean' },
+    Defringe                    => { Writable => 'integer' },
+    FillLight                   => { Writable => 'integer' },
+    HighlightRecovery           => { Writable => 'integer' },
+    HueAdjustmentAqua           => { Writable => 'integer' },
+    HueAdjustmentBlue           => { Writable => 'integer' },
+    HueAdjustmentGreen          => { Writable => 'integer' },
+    HueAdjustmentMagenta        => { Writable => 'integer' },
+    HueAdjustmentOrange         => { Writable => 'integer' },
+    HueAdjustmentPurple         => { Writable => 'integer' },
+    HueAdjustmentRed            => { Writable => 'integer' },
+    HueAdjustmentYellow         => { Writable => 'integer' },
+    IncrementalTemperature      => { Writable => 'integer' },
+    IncrementalTint             => { Writable => 'integer' },
+    LuminanceAdjustmentAqua     => { Writable => 'integer' },
+    LuminanceAdjustmentBlue     => { Writable => 'integer' },
+    LuminanceAdjustmentGreen    => { Writable => 'integer' },
+    LuminanceAdjustmentMagenta  => { Writable => 'integer' },
+    LuminanceAdjustmentOrange   => { Writable => 'integer' },
+    LuminanceAdjustmentPurple   => { Writable => 'integer' },
+    LuminanceAdjustmentRed      => { Writable => 'integer' },
+    LuminanceAdjustmentYellow   => { Writable => 'integer' },
+    ParametricDarks             => { Writable => 'integer' },
+    ParametricHighlights        => { Writable => 'integer' },
+    ParametricHighlightSplit    => { Writable => 'integer' },
+    ParametricLights            => { Writable => 'integer' },
+    ParametricMidtoneSplit      => { Writable => 'integer' },
+    ParametricShadows           => { Writable => 'integer' },
+    ParametricShadowSplit       => { Writable => 'integer' },
+    SaturationAdjustmentAqua    => { Writable => 'integer' },
+    SaturationAdjustmentBlue    => { Writable => 'integer' },
+    SaturationAdjustmentGreen   => { Writable => 'integer' },
+    SaturationAdjustmentMagenta => { Writable => 'integer' },
+    SaturationAdjustmentOrange  => { Writable => 'integer' },
+    SaturationAdjustmentPurple  => { Writable => 'integer' },
+    SaturationAdjustmentRed     => { Writable => 'integer' },
+    SaturationAdjustmentYellow  => { Writable => 'integer' },
+    SharpenDetail               => { Writable => 'integer' },
+    SharpenEdgeMasking          => { Writable => 'integer' },
+    SharpenRadius               => { Writable => 'real' },
+    SplitToningBalance          => { Writable => 'integer' },
+    SplitToningHighlightHue     => { Writable => 'integer' },
+    SplitToningHighlightSaturation => { Writable => 'integer' },
+    SplitToningShadowHue        => { Writable => 'integer' },
+    SplitToningShadowSaturation => { Writable => 'integer' },
+    Vibrance                    => { Writable => 'integer' },
+);
+
+# Tiff schema properties (tiff)
+%Image::ExifTool::XMP::tiff = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-tiff', 2 => 'Image' },
+    NAMESPACE => 'tiff',
+    NOTES => 'EXIF schema for TIFF tags.',
+    ImageWidth  => { Writable => 'integer' },
+    ImageLength => {
+        Name => 'ImageHeight',
+        Writable => 'integer',
+    },
+    BitsPerSample => { Writable => 'integer', List => 'Seq' },
+    Compression => {
+        Writable => 'integer',
+        PrintConv => \%Image::ExifTool::Exif::compression,
+    },
+    PhotometricInterpretation => {
+        Writable => 'integer',
+        PrintConv => \%Image::ExifTool::Exif::photometricInterpretation,
+    },
+    Orientation => {
+        Writable => 'integer',
+        PrintConv => \%Image::ExifTool::Exif::orientation,
+    },
+    SamplesPerPixel => { Writable => 'integer' },
+    PlanarConfiguration => {
+        Writable => 'integer',
+        PrintConv => {
+            1 => 'Chunky',
+            2 => 'Planar',
+        },
+    },
+    YCbCrSubSampling => {
+        PrintConv => {
+            '1 1' => 'YCbCr4:4:4',
+            '2 1' => 'YCbCr4:2:2',
+            '2 2' => 'YCbCr4:2:0',
+            '4 1' => 'YCbCr4:1:1',
+            '4 2' => 'YCbCr4:1:0',
+            '1 2' => 'YCbCr4:4:0',
+        },
+    },
+    YCbCrPositioning => {
+        Writable => 'integer',
+        PrintConv => {
+            1 => 'Centered',
+            2 => 'Co-sited',
+        },
+    },
+    XResolution => { Writable => 'rational' },
+    YResolution => { Writable => 'rational' },
+    ResolutionUnit => {
+        Writable => 'integer',
+        PrintConv => {
+            1 => 'None',
+            2 => 'inches',
+            3 => 'cm',
+        },
+    },
+    TransferFunction      => { Writable => 'integer',  List => 'Seq' },
+    WhitePoint            => { Writable => 'rational', List => 'Seq' },
+    PrimaryChromaticities => { Writable => 'rational', List => 'Seq' },
+    YCbCrCoefficients     => { Writable => 'rational', List => 'Seq' },
+    ReferenceBlackWhite   => { Writable => 'rational', List => 'Seq' },
+    DateTime => {
+        Description => 'Date/Time Modified',
+        %dateTimeInfo,
+    },
+    ImageDescription => { Writable => 'lang-alt' },
+    Make  => { Groups => { 2 => 'Camera' } },
+    Model => {
+        Description => 'Camera Model Name',
+        Groups => { 2 => 'Camera' },
+    },
+    Software  => { },
+    Artist    => { Groups => { 2 => 'Author' } },
+    Copyright => {
+        Groups => { 2 => 'Author' },
+        Writable => 'lang-alt',
+    },
+    NativeDigest => { }, #PH
+);
+
+# Exif schema properties (exif)
+%Image::ExifTool::XMP::exif = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-exif', 2 => 'Image' },
+    NAMESPACE => 'exif',
+    NOTES => 'EXIF schema for EXIF tags.',
+    ExifVersion     => { },
+    FlashpixVersion => { },
+    ColorSpace => {
+        Writable => 'integer',
+        PrintConv => {
+            1 => 'sRGB',
+            2 => 'Adobe RGB',
+            0xffff => 'Uncalibrated',
+            0xffffffff => 'Uncalibrated',
+        },
+    },
+    ComponentsConfiguration => {
+        List => 'Seq',
+        Writable => 'integer',
+        PrintConv => {
+            0 => '.',
+            1 => 'Y',
+            2 => 'Cb',
+            3 => 'Cr',
+            4 => 'R',
+            5 => 'G',
+            6 => 'B',
+        },
+    },
+    CompressedBitsPerPixel => {
+        Writable => 'rational',
+    },
+    PixelXDimension => {
+        Name => 'ExifImageWidth',
+        Writable => 'integer',
+    },
+    PixelYDimension => {
+        Name => 'ExifImageLength',
+        Writable => 'integer',
+    },
+    MakerNote => { },
+    UserComment => {
+        Writable => 'lang-alt',
+    },
+    RelatedSoundFile => { },
+    DateTimeOriginal => {
+        Description => 'Date/Time Original',
+        %dateTimeInfo,
+    },
+    DateTimeDigitized => {
+        Description => 'Date/Time Digitized',
+        %dateTimeInfo,
+    },
+    ExposureTime => {
+        Writable => 'rational',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'eval $val',
+    },
+    FNumber => {
+        Writable => 'rational',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    ExposureProgram => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            1 => 'Manual',
+            2 => 'Program AE',
+            3 => 'Aperture-priority AE',
+            4 => 'Shutter speed priority AE',
+            5 => 'Creative (Slow speed)',
+            6 => 'Action (High speed)',
+            7 => 'Portrait',
+            8 => 'Landscape',
+        },
+    },
+    SpectralSensitivity => {
+        Groups => { 2 => 'Camera' },
+    },
+    ISOSpeedRatings => {
+        Name => 'ISO',
+        Writable => 'integer',
+        List => 'Seq',
+    },
+    OECF => {
+        Name => 'Opto-ElectricConvFactor',
+        Groups => { 2 => 'Camera' },
+        SubDirectory => { },
+        Struct => 'OECF',
+    },
+    OECFColumns => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+    },
+    OECFRows => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+    },
+    OECFNames => {
+        Groups => { 2 => 'Camera' },
+        List => 'Seq',
+    },
+    OECFValues => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational',
+        List => 'Seq',
+    },
+    ShutterSpeedValue => {
+        Writable => 'rational',
+        ValueConv => 'abs($val)<100 ? 1/(2**$val) : 0',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        ValueConvInv => '$val>0 ? -log($val)/log(2) : 0',
+        # do eval to convert things like '1/100'
+        PrintConvInv => 'eval $val',
+    },
+    ApertureValue => {
+        Writable => 'rational',
+        ValueConv => 'sqrt(2) ** $val',
+        PrintConv => 'sprintf("%.1f",$val)',
+        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
+        PrintConvInv => '$val',
+    },
+    BrightnessValue => {
+        Writable => 'rational',
+    },
+    ExposureBiasValue => {
+        Name => 'ExposureCompensation',
+        Writable => 'rational',
+        PrintConv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => '$val',
+    },
+    MaxApertureValue => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational',
+        ValueConv => 'sqrt(2) ** $val',
+        PrintConv => 'sprintf("%.1f",$val)',
+        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
+        PrintConvInv => '$val',
+    },
+    SubjectDistance => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational',
+        PrintConv => '$val eq "inf" ? $val : "$val m"',
+        PrintConvInv => '$val=~s/\s*m$//;$val',
+    },
+    MeteringMode => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            1 => 'Average',
+            2 => 'Center-weighted average',
+            3 => 'Spot',
+            4 => 'Multi-spot',
+            5 => 'Multi-segment',
+            6 => 'Partial',
+            255 => 'Other',
+        },
+    },
+    LightSource => {
+        Groups => { 2 => 'Camera' },
+        PrintConv =>  \%Image::ExifTool::Exif::lightSource,
+    },
+    Flash => {
+        Groups => { 2 => 'Camera' },
+        SubDirectory => { },
+        Struct => 'Flash',
+    },
+    FlashFired => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'boolean',
+    },
+    FlashReturn => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'No return detection',
+            2 => 'Return not detected',
+            3 => 'Return detected',
+        },
+    },
+    FlashMode => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'On',
+            2 => 'Off',
+            3 => 'Auto',
+        },
+    },
+    FlashFunction => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'boolean',
+    },
+    FlashRedEyeMode => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'boolean',
+    },
+    FocalLength=> {
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational',
+        PrintConv => 'sprintf("%.1fmm",$val)',
+        PrintConvInv => '$val=~s/mm$//;$val',
+    },
+    SubjectArea => {
+        Writable => 'integer',
+        List => 'Seq',
+    },
+    FlashEnergy => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational',
+    },
+    SpatialFrequencyResponse => {
+        Groups => { 2 => 'Camera' },
+        SubDirectory => { },
+        Struct => 'OECF',
+    },
+    SpatialFrequencyResponseColumns => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+    },
+    SpatialFrequencyResponseRows => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+    },
+    SpatialFrequencyResponseNames => {
+        Groups => { 2 => 'Camera' },
+        List => 'Seq',
+    },
+    SpatialFrequencyResponseValues => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational',
+        List => 'Seq',
+    },
+    FocalPlaneXResolution => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational',
+    },
+    FocalPlaneYResolution => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational',
+    },
+    FocalPlaneResolutionUnit => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            1 => 'None', # (not standard EXIF)
+            2 => 'inches',
+            3 => 'cm',
+            4 => 'mm',   # (not standard EXIF)
+            5 => 'um',   # (not standard EXIF)
+        },
+    },
+    SubjectLocation => {
+        Writable => 'integer',
+        List => 'Seq',
+    },
+    ExposureIndex => {
+        Writable => 'rational',
+    },
+    SensingMethod => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            1 => 'Not defined',
+            2 => 'One-chip color area',
+            3 => 'Two-chip color area',
+            4 => 'Three-chip color area',
+            5 => 'Color sequential area',
+            7 => 'Trilinear',
+            8 => 'Color sequential linear',
+        },
+    },
+    FileSource => {
+        Writable => 'integer',
+        PrintConv => {
+            1 => 'Film Scanner',
+            2 => 'Reflection Print Scanner',
+            3 => 'Digital Camera',
+        }
+    },
+    SceneType  => { Writable => 'integer', PrintConv => { 1 => 'Directly photographed' } },
+    CFAPattern => {
+        SubDirectory => { },
+        Struct => 'CFAPattern',
+    },
+    CFAPatternColumns   => { Writable => 'integer' },
+    CFAPatternRows      => { Writable => 'integer' },
+    CFAPatternValues    => { List => 'Seq', Writable => 'integer' },
+    CustomRendered => {
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Custom',
+        },
+    },
+    ExposureMode => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Manual',
+            2 => 'Auto bracket',
+        },
+    },
+    WhiteBalance => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Manual',
+        },
+    },
+    DigitalZoomRatio => { Writable => 'rational' },
+    FocalLengthIn35mmFilm => {
+        Name => 'FocalLengthIn35mmFormat',
+        Writable => 'integer',
+        Groups => { 2 => 'Camera' },
+    },
+    SceneCaptureType => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Landscape',
+            2 => 'Portrait',
+            3 => 'Night',
+        },
+    },
+    GainControl => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Low gain up',
+            2 => 'High gain up',
+            3 => 'Low gain down',
+            4 => 'High gain down',
+        },
+    },
+    Contrast => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Low',
+            2 => 'High',
+        },
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertParameter($val)',
+    },
+    Saturation => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Low',
+            2 => 'High',
+        },
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertParameter($val)',
+    },
+    Sharpness => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Soft',
+            2 => 'Hard',
+        },
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertParameter($val)',
+    },
+    DeviceSettingDescription => {
+        Groups => { 2 => 'Camera' },
+        SubDirectory => { },
+        Struct => 'DeviceSettings',
+    },
+    DeviceSettingDescriptionColumns => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+    },
+    DeviceSettingDescriptionRows => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+    },
+    DeviceSettingDescriptionSettings => {
+        Groups => { 2 => 'Camera' },
+        List => 'Seq',
+    },
+    SubjectDistanceRange => {
+        Groups => { 2 => 'Camera' },
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'Macro',
+            2 => 'Close',
+            3 => 'Distant',
+        },
+    },
+    ImageUniqueID   => { },
+    GPSVersionID    => { Groups => { 2 => 'Location' } },
+    GPSLatitude     => { Groups => { 2 => 'Location' }, %latConv },
+    GPSLongitude    => { Groups => { 2 => 'Location' }, %longConv },
+    GPSAltitudeRef  => {
+        Groups => { 2 => 'Location' },
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'Above Sea Level',
+            1 => 'Below Sea Level',
+        },
+    },
+    GPSAltitude => {
+        Groups => { 2 => 'Location' },
+        Writable => 'rational',
+        PrintConv => '$val eq "inf" ? $val : "$val m"',
+        PrintConvInv => '$val=~s/\s*m$//;$val',
+    },
+    GPSTimeStamp    => { %dateTimeInfo },
+    GPSSatellites   => { Groups => { 2 => 'Location' } },
+    GPSStatus => {
+        Groups => { 2 => 'Location' },
+        PrintConv => {
+            A => 'Measurement In Progress',
+            V => 'Measurement Interoperability',
+        },
+    },
+    GPSMeasureMode => {
+        Groups => { 2 => 'Location' },
+        Writable => 'integer',
+        PrintConv => {
+            2 => '2-Dimensional',
+            3 => '3-Dimensional',
+        },
+    },
+    GPSDOP => {
+        Groups => { 2 => 'Location' },
+        Writable => 'rational',
+    },
+    GPSSpeedRef => {
+        Groups => { 2 => 'Location' },
+        PrintConv => {
+            K => 'km/h',
+            M => 'mph',
+            N => 'knots',
+        },
+    },
+    GPSSpeed => {
+        Groups => { 2 => 'Location' },
+        Writable => 'rational',
+    },
+    GPSTrackRef => {
+        Groups => { 2 => 'Location' },
+        PrintConv => {
+            M => 'Magnetic North',
+            T => 'True North',
+        },
+    },
+    GPSTrack => {
+        Groups => { 2 => 'Location' },
+        Writable => 'rational',
+    },
+    GPSImgDirectionRef => {
+        PrintConv => {
+            M => 'Magnetic North',
+            T => 'True North',
+        },
+    },
+    GPSImgDirection => {
+        Groups => { 2 => 'Location' },
+        Writable => 'rational',
+    },
+    GPSMapDatum     => { Groups => { 2 => 'Location' } },
+    GPSDestLatitude => { Groups => { 2 => 'Location' }, %latConv },
+    GPSDestLongitude=> { Groups => { 2 => 'Location' }, %longConv },
+    GPSDestBearingRef => {
+        Groups => { 2 => 'Location' },
+        PrintConv => {
+            M => 'Magnetic North',
+            T => 'True North',
+        },
+    },
+    GPSDestBearing => {
+        Groups => { 2 => 'Location' },
+        Writable => 'rational',
+    },
+    GPSDestDistanceRef => {
+        Groups => { 2 => 'Location' },
+        PrintConv => {
+            K => 'Kilometers',
+            M => 'Miles',
+            N => 'Nautical Miles',
+        },
+    },
+    GPSDestDistance => {
+        Groups => { 2 => 'Location' },
+        Writable => 'rational',
+    },
+    GPSProcessingMethod => { Groups => { 2 => 'Location' } },
+    GPSAreaInformation  => { Groups => { 2 => 'Location' } },
+    GPSDifferential => {
+        Groups => { 2 => 'Location' },
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'No Correction',
+            1 => 'Differential Corrected',
+        },
+    },
+    NativeDigest => { }, #PH
+);
+
+# Auxiliary schema properties (aux) - not fully documented
+%Image::ExifTool::XMP::aux = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-aux', 2 => 'Camera' },
+    NAMESPACE => 'aux',
+    NOTES => 'Photoshop Auxiliary schema tags.',
+    Firmware        => { }, #7
+    FlashCompensation => { Writable => 'rational' }, #7
+    ImageNumber     => { }, #7
+    LensInfo        => { }, #7
+    Lens            => { },
+    OwnerName       => { }, #7
+    SerialNumber    => { },
+);
+
+# IPTC Core schema properties (Iptc4xmpCore)
+%Image::ExifTool::XMP::iptcCore = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-iptcCore', 2 => 'Author' },
+    NAMESPACE => 'Iptc4xmpCore',
+    NOTES => q{
+        IPTC Core schema tags.  The actual IPTC Core namespace schema prefix is
+        "Iptc4xmpCore", which is the prefix recorded in the file, but ExifTool
+        shortens this for the "XMP-iptcCore" family 1 group name.
+    },
+    CountryCode         => { Groups => { 2 => 'Location' } },
+    CreatorContactInfo => {
+        SubDirectory => { },
+        Struct => 'ContactInfo',
+    },
+    CreatorContactInfoCiAdrCity   => { Description => 'Creator City' },
+    CreatorContactInfoCiAdrCtry   => { Description => 'Creator Country' },
+    CreatorContactInfoCiAdrExtadr => { Description => 'Creator Address' },
+    CreatorContactInfoCiAdrPcode  => { Description => 'Creator Postal Code' },
+    CreatorContactInfoCiAdrRegion => { Description => 'Creator Region' },
+    CreatorContactInfoCiEmailWork => { Description => 'Creator Work Email' },
+    CreatorContactInfoCiTelWork   => { Description => 'Creator Work Telephone' },
+    CreatorContactInfoCiUrlWork   => { Description => 'Creator Work URL' },
+    IntellectualGenre   => { Groups => { 2 => 'Other' } },
+    Location            => { Groups => { 2 => 'Location' } },
+    Scene               => { Groups => { 2 => 'Other' }, List => 'Bag' },
+    SubjectCode         => { Groups => { 2 => 'Other' }, List => 'Bag' },
+);
+
+# PixelLive schema properties (PixelLive) (ref 3)
+%Image::ExifTool::XMP::PixelLive = (
+    GROUPS => { 1 => 'XMP-PixelLive', 2 => 'Image' },
+    NAMESPACE => 'PixelLive',
+    WRITE_PROC => \&WriteXMP,
+    NOTES => q{
+        PixelLive schema tags.  These tags are not writable becase they are very
+        uncommon and I haven't been able to locate a reference which gives the
+        namespace URI.
+    },
+    AUTHOR    => { Name => 'Author',   Avoid => 1, Groups => { 2 => 'Author'} },
+    COMMENTS  => { Name => 'Comments', Avoid => 1 },
+    COPYRIGHT => { Name => 'Copyright',Avoid => 1, Groups => { 2 => 'Author'} },
+    DATE      => { Name => 'Date',     Avoid => 1, Groups => { 2 => 'Time'} },
+    GENRE     => { Name => 'Genre',    Avoid => 1 },
+    TITLE     => { Name => 'Title',    Avoid => 1 },
+);
+
+# Picture Licensing Universal System schema properties (xmpPLUS)
+%Image::ExifTool::XMP::xmpPLUS = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-xmpPLUS', 2 => 'Author' },
+    NAMESPACE => 'xmpPLUS',
+    NOTES => 'XMP Picture Licensing Universal System (PLUS) schema tags.',
+    CreditLineReq   => { Writable => 'boolean' },
+    ReuseAllowed    => { Writable => 'boolean' },
+);
+
+# Creative Commons schema properties (cc) (ref 5)
+%Image::ExifTool::XMP::cc = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-cc', 2 => 'Author' },
+    NAMESPACE => 'cc',
+    NOTES => 'Creative Commons schema tags.',
+    license => { },
+);
+
+# Description Explorer schema properties (dex) (ref 6)
+%Image::ExifTool::XMP::dex = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-dex', 2 => 'Image' },
+    NAMESPACE => 'dex',
+    NOTES => q{
+        Description Explorer schema tags.  These tags are not very common.  The
+        Source and Rating tags are avoided when writing due to name conflicts with
+        other XMP tags.
+    },
+    crc32       => { Name => 'CRC32', Writable => 'integer' },
+    source      => { Avoid => 1 },
+    shortdescription => {
+        Name => 'ShortDescription',
+        Writable => 'lang-alt',
+    },
+    licensetype => {
+        Name => 'LicenseType',
+        PrintConv => {
+            unknown        => 'Unknown',
+            shareware      => 'Shareware',
+            freeware       => 'Freeware',
+            adware         => 'Adware',
+            demo           => 'Demo',
+            commercial     => 'Commercial',
+           'public domain' => 'Public Domain',
+           'open source'   => 'Open Source',
+        },
+    },
+    revision    => { },
+    rating      => { Avoid => 1 },
+    os          => { Name => 'OS', Writable => 'integer' },
+    ffid        => { Name => 'FFID' },
+);
+
+# IView MediaPro schema properties (mediapro) (ref PH)
+%Image::ExifTool::XMP::MediaPro = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-mediapro', 2 => 'Image' },
+    NAMESPACE => 'mediapro',
+    NOTES => 'IView MediaPro schema tags.',
+    Event       => { },
+    Location    => {
+        Avoid => 1,
+        Groups => { 2 => 'Location' },
+        Notes => 'avoided due to conflict with XMP-iptcCore:Location',
+    },
+    Status      => { },
+    People      => { List => 'Bag' },
+    UserFields  => { List => 'Bag' },
+    CatalogSets => { List => 'Bag' },
+);
+
+# Microsoft Photo schema properties (MicrosoftPhoto) (ref PH)
+%Image::ExifTool::XMP::Microsoft = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-microsoft', 2 => 'Image' },
+    NAMESPACE => 'MicrosoftPhoto',
+    NOTES => q{
+        Microsoft Photo schema tags.  This is likely not a complete list, but
+        represents tags which have been observed in sample images.  The actual
+        namespace prefix is "MicrosoftPhoto", but ExifTool shortens this to
+        "XMP-microsoft" in the family 1 group name.
+    },
+    CameraSerialNumber => { },
+    DateAcquired       => { %dateTimeInfo },
+    FlashManufacturer  => { },
+    FlashModel         => { },
+    LastKeywordIPTC    => { List => 'Bag' },
+    LastKeywordXMP     => { List => 'Bag' },
+    LensManufacturer   => { },
+    LensModel          => { },
+    Rating => {
+        Name => 'RatingPercent',
+        Notes => q{
+            normal Rating values of 1,2,3,4 and 5 stars correspond to RatingPercent
+            values of 1,25,50,75 and 99 respectively
+        },
+    },
+);
+
+# Adobe Lightroom schema properties (lr) (ref PH)
+%Image::ExifTool::XMP::Lightroom = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-lr', 2 => 'Image' },
+    NAMESPACE => 'lr',
+    NOTES => 'Adobe Lightroom "lr" schema tags.',
+    privateRTKInfo => { },
+    hierarchicalSubject => { List => 'Bag' },
+);
+
+# DICOM schema properties (DICOM) (ref PH, written by CS3)
+%Image::ExifTool::XMP::DICOM = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-DICOM', 2 => 'Image' },
+    NAMESPACE => 'DICOM',
+    NOTES => 'DICOM schema tags.',
+    # change some tag names to correspond with DICOM tags
+    PatientName             => { Name => 'PatientsName' },
+    PatientID               => { },
+    PatientSex              => { Name => 'PatientsSex' },
+    PatientDOB              => {
+        Name => 'PatientsBirthDate',
+        %dateTimeInfo,
+    },
+    StudyID                 => { },
+    StudyPhysician          => { },
+    StudyDateTime           => { %dateTimeInfo },
+    StudyDescription        => { },
+    SeriesNumber            => { },
+    SeriesModality          => { },
+    SeriesDateTime          => { %dateTimeInfo },
+    SeriesDescription       => { },
+    EquipmentInstitution    => { },
+    EquipmentManufacturer   => { },
+);
+
+# table to add tags in other namespaces
+%Image::ExifTool::XMP::other = (
+    GROUPS => { 2 => 'Unknown' },
+    LANG_INFO => \&GetLangInfo,
+);
+
+# Composite XMP tags
+%Image::ExifTool::XMP::Composite = (
+    # get latitude/logitude reference from XMP lat/long tags
+    # (used to set EXIF GPS position from XMP tags)
+    GPSLatitudeRef => {
+        Require => {
+            0 => 'XMP:GPSLatitude',
+        },
+        ValueConv => '$val[0] < 0 ? "S" : "N"',
+        PrintConv => {
+            N => 'North',
+            S => 'South',
+        },
+    },
+    GPSLongitudeRef => {
+        Require => {
+            0 => 'XMP:GPSLongitude',
+        },
+        ValueConv => '$val[0] < 0 ? "W" : "E"',
+        PrintConv => {
+            E => 'East',
+            W => 'West',
+        },
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::XMP');
+
+#------------------------------------------------------------------------------
+# AutoLoad our writer routines when necessary
+#
+sub AUTOLOAD
+{
+    return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
+}
+
+#------------------------------------------------------------------------------
+# Escape necessary XML characters in UTF-8 string
+# Inputs: 0) string to be escaped
+# Returns: escaped string
+my %charName = ('"'=>'quot', '&'=>'amp', "'"=>'#39', '<'=>'lt', '>'=>'gt');
+sub EscapeXML($)
+{
+    my $str = shift;
+    $str =~ s/([&><'"])/&$charName{$1};/sg; # escape necessary XML characters
+    return $str;
+}
+
+#------------------------------------------------------------------------------
+# Unescape XML character references (entities and numerical)
+# Inputs: 0) string to be unescaped
+#         1) optional hash reference to convert entity names to numbers
+# Returns: unescaped string
+my %charNum = ('quot'=>34, 'amp'=>38, 'apos'=>39, 'lt'=>60, 'gt'=>62);
+sub UnescapeXML($;$)
+{
+    my ($str, $conv) = @_;
+    $conv = \%charNum unless $conv;
+    $str =~ s/&(#?\w+);/UnescapeChar($1,$conv)/sge;
+    return $str;
+}
+
+#------------------------------------------------------------------------------
+# Convert XML character reference to UTF-8
+# Inputs: 0) XML character reference stripped of the '&' and ';' (ie. 'quot', '#34', '#x22')
+#         1) hash reference for looking up character numbers by name
+# Returns: UTF-8 equivalent (or original character on conversion error)
+sub UnescapeChar($$)
+{
+    my ($ch, $conv) = @_;
+    my $val = $$conv{$ch};
+    unless (defined $val) {
+        if ($ch =~ /^#x([0-9a-fA-F]+)$/) {
+            $val = hex($1);
+        } elsif ($ch =~ /^#(\d+)$/) {
+            $val = $1;
+        } else {
+            return "&$ch;"; # should issue a warning here?
+        }
+    }
+    if ($val < 0x80) {
+        return chr($val);   # simple ASCII
+    } elsif ($] >= 5.006001) {
+        return pack('C0U', $val);
+    } else {
+        return Image::ExifTool::PackUTF8($val);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Utility routine to decode a base64 string
+# Inputs: 0) base64 string
+# Returns:   reference to decoded data
+sub DecodeBase64($)
+{
+    local($^W) = 0; # unpack('u',...) gives bogus warning in 5.00[123]
+    my $str = shift;
+
+    # truncate at first unrecognized character (base 64 data
+    # may only contain A-Z, a-z, 0-9, +, /, =, or white space)
+    $str =~ s/[^A-Za-z0-9+\/= \t\n\r\f].*//;
+    # translate to uucoded and remove padding and white space
+    $str =~ tr/A-Za-z0-9+\/= \t\n\r\f/ -_/d;
+
+    # convert the data to binary in chunks
+    my $chunkSize = 60;
+    my $uuLen = pack('c', 32 + $chunkSize * 3 / 4); # calculate length byte
+    my $dat = '';
+    my ($i, $substr);
+    # loop through the whole chunks
+    my $len = length($str) - $chunkSize;
+    for ($i=0; $i<=$len; $i+=$chunkSize) {
+        $substr = substr($str, $i, $chunkSize);     # get a chunk of the data
+        $dat .= unpack('u', $uuLen . $substr);      # decode it
+    }
+    $len += $chunkSize;
+    # handle last partial chunk if necessary
+    if ($i < $len) {
+        $uuLen = pack('c', 32 + ($len-$i) * 3 / 4); # recalculate length
+        $substr = substr($str, $i, $len-$i);        # get the last partial chunk
+        $dat .= unpack('u', $uuLen . $substr);      # decode it
+    }
+    return \$dat;
+}
+
+#------------------------------------------------------------------------------
+# Generate a name for this XMP tag
+# Inputs: 0) reference to tag property name list
+# Returns: tagID and outtermost interesting namespace
+sub GetXMPTagID($)
+{
+    my $props = shift;
+    my ($tag, $prop, $namespace);
+    foreach $prop (@$props) {
+        # split name into namespace and property name
+        # (Note: namespace can be '' for property qualifiers)
+        my ($ns, $nm) = ($prop =~ /(.*?):(.*)/) ? ($1, $2) : ('', $prop);
+        $nm =~ s/ .*//;     # remove nodeID if it exists
+        if ($ignoreNamespace{$ns}) {
+            # special case: don't ignore rdf numbered items
+            next unless $prop =~ /^rdf:(_\d+)$/;
+            $tag .= $1;
+        } else {
+            # all uppercase is ugly, so convert it
+            if ($nm !~ /[a-z]/) {
+                my $xlatNS = $xlatNamespace{$ns} || $ns;
+                my $info = $Image::ExifTool::XMP::Main{$xlatNS};
+                my $table;
+                if (ref $info eq 'HASH' and $info->{SubDirectory}) {
+                    $table = GetTagTable($info->{SubDirectory}->{TagTable});
+                }
+                unless ($table and $table->{$nm}) {
+                    $nm = lc($nm);
+                    $nm =~ s/_([a-z])/\u$1/g;
+                }
+            }
+            if (defined $tag) {
+                $tag .= ucfirst($nm);       # add to tag name
+            } else {
+                $tag = $nm;
+            }
+        }
+        # save namespace of first property to contribute to tag name
+        $namespace = $ns unless defined $namespace;
+    }
+    if (wantarray) {
+        return ($tag, $namespace);
+    } else {
+        return $tag;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Get localized version of tagInfo hash
+# Inputs: 0) tagInfo hash ref, 1) language code (ie. "x-default")
+# Returns: new tagInfo hash ref, or undef if invalid
+sub GetLangInfo($$)
+{
+    my ($tagInfo, $langCode) = @_;
+    # only allow alternate language tags in lang-alt lists
+    return undef unless $$tagInfo{Writable} and $$tagInfo{Writable} eq 'lang-alt';
+    $langCode =~ tr/_/-/;   # RFC 3066 specifies '-' as a separator
+    return Image::ExifTool::GetLangInfo($tagInfo, $langCode);
+}
+
+#------------------------------------------------------------------------------
+# Get standard case for language code
+# Inputs: 0) Language code
+# Returns: Language code in standard case
+sub StandardLangCase($)
+{
+    my $lang = shift;
+    # make 2nd subtag uppercase only if it is 2 letters
+    return lc($1) . uc($2) . lc($3) if $lang =~ /^([a-z]{2,3}|[xi])(-[a-z]{2})\b(.*)/i;
+    return lc($lang);
+}
+
+#------------------------------------------------------------------------------
+# Scan for XMP in a file
+# Inputs: 0) ExifTool object ref, 1) RAF reference
+# Returns: 1 if xmp was found, 0 otherwise
+# Notes: Currently only recognizes UTF8-encoded XMP
+sub ScanForXMP($$)
+{
+    my ($exifTool, $raf) = @_;
+    my ($buff, $xmp);
+    my $lastBuff = '';
+
+    $exifTool->VPrint(0,"Scanning for XMP\n");
+    for (;;) {
+        defined $buff or $raf->Read($buff, 65536) or return 0;
+        unless (defined $xmp) {
+            $lastBuff .= $buff;
+            unless ($lastBuff =~ /(<\?xpacket begin=)/g) {
+                # must keep last 15 bytes to match 16-byte "xpacket begin" string
+                $lastBuff = length($buff) <= 15 ? $buff : substr($buff, -15);
+                undef $buff;
+                next;
+            }
+            $xmp = $1;
+            $buff = substr($lastBuff, pos($lastBuff));
+        }
+        $xmp .= $buff;
+        my $pos = length($xmp) - length($buff) - 18; # 18 is length("<xpacket end...")-1
+        pos($xmp) = $pos if $pos > 0;
+        if ($xmp =~ /<\?xpacket end=['"][wr]['"]\?>/g) {
+            $xmp = substr($xmp, 0, pos($xmp));
+            # XMP is not valid if it contains null bytes
+            pos($xmp) = 0;
+            last unless $xmp =~ /\0/g;
+            my $null = pos $xmp;
+            while ($xmp =~ /\0/g) {
+                $null = pos($xmp);
+            }
+            # re-parse beginning after last null byte
+            $buff = substr($xmp, $null);
+            $lastBuff = '';
+            undef $xmp;
+        } else {
+            undef $buff;
+        }
+    }
+    unless ($exifTool->{VALUE}->{FileType}) {
+        $exifTool->{FILE_TYPE} = $exifTool->{FILE_EXT};
+        $exifTool->SetFileType('<unknown file containing XMP>');
+    }
+    my %dirInfo = (
+        DataPt => \$xmp,
+        DirLen => length $xmp,
+        DataLen => length $xmp,
+    );
+    ProcessXMP($exifTool, \%dirInfo);
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# We found an XMP property name/value
+# Inputs: 0) ExifTool object ref, 1) Pointer to tag table
+#         2) reference to array of XMP property names (last is current property)
+#         3) property value, 4) xml:lang attribute (or undef)
+# Returns: 1 if valid tag was found
+sub FoundXMP($$$$;$)
+{
+    local $_;
+    my ($exifTool, $tagTablePtr, $props, $val, $lang) = @_;
+
+    my ($tag, $namespace) = GetXMPTagID($props);
+    return 0 unless $tag;   # ignore things that aren't valid tags
+
+    # translate namespace if necessary
+    $namespace = $xlatNamespace{$namespace} if $xlatNamespace{$namespace};
+    my $info = $tagTablePtr->{$namespace};
+    my $table;
+    if ($info) {
+        $table = $info->{SubDirectory}->{TagTable} or warn "Missing TagTable for $tag!\n";
+    } else {
+        $table = 'Image::ExifTool::XMP::other';
+    }
+    # change pointer to the table for this namespace
+    $tagTablePtr = GetTagTable($table);
+
+    # look up this tag in the appropriate table
+    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+
+    unless ($tagInfo) {
+        if ($exifTool->{OPTIONS}->{Verbose}) {
+            my $group1 = $namespace ? "XMP-$namespace" : $tagTablePtr->{GROUPS}->{1};
+            $exifTool->VPrint(0, $exifTool->{INDENT}, "[adding $group1:$tag]\n");
+        }
+        # construct tag information for this unknown tag
+        $tagInfo = { Name => ucfirst($tag), WasAdded => 1 };
+        # make this a List type if necessary and not lang-alt
+        $$tagInfo{List} = $1 if @$props > 2 and not $lang and
+            $$props[-1] =~ /^rdf:li \d+$/ and $$props[-2] =~ /^rdf:(Bag|Seq|Alt)/;
+        Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+    }
+    if (defined $lang and lc($lang) ne 'x-default') {
+        $lang = StandardLangCase($lang);
+        my $langInfo = GetLangInfo($tagInfo, $lang);
+        $tagInfo = $langInfo if $langInfo;
+    }
+    if ($exifTool->{OPTIONS}->{Charset} ne 'UTF8' and $val =~ /[\x80-\xff]/) {
+        # convert from UTF-8 to specified characterset
+        $val = $exifTool->UTF82Charset($val);
+    }
+    # convert rational and date values to a more sensible format
+    my $fmt = $$tagInfo{Writable};
+    my $new = $$tagInfo{WasAdded};
+    if ($fmt or $new) {
+        if (($new or $fmt eq 'rational') and $val =~ m{^(-?\d+)/(-?\d+)$}) {
+            $val = $1 / $2 if $2;       # calculate quotient
+        } elsif ($new or $fmt eq 'date') {
+            if ($val =~ /^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}:\d{2})(:\d{2})?(\S*)$/) {
+                my $s = $5 || ':00';        # seconds may be missing
+                $val = "$1:$2:$3 $4$s$6";   # convert back to EXIF time format
+            } elsif ($fmt and $fmt eq 'date' and $val =~ /^(\d{4})(-\d{2}){0,2}/) {
+                $val =~ tr/-/:/;
+            }
+        }
+    }
+    $tag = $exifTool->FoundTag($tagInfo, UnescapeXML($val));
+    $exifTool->SetGroup1($tag, "XMP-$namespace") if $namespace;
+
+    if ($exifTool->Options('Verbose')) {
+        my $tagID = join('/',@$props);
+        $exifTool->VerboseInfo($tagID, $tagInfo, Value=>$val);
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Recursively parse nested XMP data element
+# Inputs: 0) ExifTool object reference
+#         1) Pointer to tag table
+#         2) reference to XMP data
+#         3) start of xmp element
+#         4) reference to array of enclosing XMP property names (undef if none)
+#         5) reference to blank node information hash
+# Returns: Number of contained XMP elements
+sub ParseXMPElement($$$;$$$)
+{
+    my ($exifTool, $tagTablePtr, $dataPt, $start, $propListPt, $blankInfo) = @_;
+    my $count = 0;
+    my $isWriting = $exifTool->{XMP_CAPTURE};
+    $start or $start = 0;
+    $propListPt or $propListPt = [ ];
+
+    my $processBlankInfo;
+    # create empty blank node information hash if necessary
+    $blankInfo or $blankInfo = $processBlankInfo = { Prop => { } };
+    # keep track of current nodeID at this nesting level
+    my $oldNodeID = $$blankInfo{NodeID};
+
+    pos($$dataPt) = $start;
+    Element: for (;;) {
+        # reset nodeID before processing each element
+        my $nodeID = $$blankInfo{NodeID} = $oldNodeID;
+        # get next element
+        last unless $$dataPt =~ m/<([\w:-]+)(.*?)>/sg;
+        my ($prop, $attrs) = ($1, $2);
+        my $val = '';
+        # only look for closing token if this is not an empty element
+        # (empty elements end with '/', ie. <a:b/>)
+        if ($attrs !~ s/\/$//) {
+            my $nesting = 1;
+            for (;;) {
+# this match fails with perl 5.6.2 (perl bug!), but it works without
+# the '(.*?)', so do it the hard way instead...
+#                $$dataPt =~ m/(.*?)<\/$prop>/sg or last Element;
+#                my $val2 = $1;
+                my $pos = pos($$dataPt);
+                $$dataPt =~ m/<\/$prop>/sg or last Element;
+                my $len = pos($$dataPt) - $pos - length($prop) - 3;
+                my $val2 = substr($$dataPt, $pos, $len);
+                # increment nesting level for each contained similar opening token
+                ++$nesting while $val2 =~ m/<$prop\b.*?(\/?)>/sg and $1 ne '/';
+                $val .= $val2;
+                --$nesting or last;
+                $val .= "</$prop>";
+            }
+        }
+        if ($prop eq 'rdf:li') {
+            # add index to list items so we can keep them in order
+            # (this also enables us to keep structure elements grouped properly
+            # for lists of structures, like JobRef)
+            $prop .= sprintf(' %.3d', $count);
+        } elsif ($prop eq 'rdf:Description') {
+            # trim comments and whitespace from rdf:Description properties only
+            $val =~ s/<!--.*?-->//g;
+            $val =~ s/^\s*(.*)\s*$/$1/;
+        } elsif ($prop eq 'xmp:xmpmeta') {
+            # patch MicrosoftPhoto unconformity
+            $prop = 'x:xmpmeta';
+        }
+
+        # extract property attributes
+        my (%attrs, @attrs);
+        while ($attrs =~ m/(\S+?)=(['"])(.*?)\2/sg) {
+            push @attrs, $1;    # preserve order
+            $attrs{$1} = $3;
+        }
+
+        # add nodeID to property path (with leading ' #') if it exists
+        if (defined $attrs{'rdf:nodeID'}) {
+            $nodeID = $$blankInfo{NodeID} = $attrs{'rdf:nodeID'};
+            delete $attrs{'rdf:nodeID'};
+            $prop .= ' #' . $nodeID;
+        }
+
+        # push this property name onto our hierarchy list
+        push @$propListPt, $prop;
+
+        # handle properties inside element attributes (RDF shorthand format):
+        # (attributes take the form a:b='c' or a:b="c")
+        my ($shortName, $shorthand, $ignored);
+        foreach $shortName (@attrs) {
+            my $propName = $shortName;
+            my ($ns, $name);
+            if ($propName =~ /(.*?):(.*)/) {
+                $ns = $1;   # specified namespace
+                $name = $2;
+            } elsif ($prop =~ /(\S*?):/) {
+                $ns = $1;   # assume same namespace as parent
+                $name = $propName;
+                $propName = "$ns:$name";    # generate full property name
+            } else {
+                # a property qualifier is the only property name that may not
+                # have a namespace, and a qualifier shouldn't have attributes,
+                # but what the heck, let's allow this anyway
+                $ns = '';
+                $name = $propName;
+            }
+            if ($isWriting) {
+                # keep track of our namespaces when writing
+                if ($ns eq 'xmlns') {
+                    unless ($name eq 'x' or $name eq 'iX') {
+                        my $nsUsed = $exifTool->{XMP_NS};
+                        $$nsUsed{$name} = $attrs{$shortName} unless defined $$nsUsed{$name};
+                    }
+                    next;
+                } elsif ($recognizedAttrs{$propName}) {
+                    # save UUID to use same ID when writing
+                    if ($propName eq 'rdf:about') {
+                        if (not $exifTool->{XMP_UUID}) {
+                            $exifTool->{XMP_UUID} = $attrs{$shortName};
+                        } elsif ($exifTool->{XMP_UUID} ne $attrs{$shortName}) {
+                            $exifTool->Error("Multiple XMP UUID's not handled", 1);
+                        }
+                    }
+                    next;
+                }
+            }
+            if ($ignoreNamespace{$ns}) {
+                $ignored = $propName;
+                next;
+            }
+            my $shortVal = $attrs{$shortName};
+            delete $attrs{$shortName};  # don't re-use this attribute
+            push @$propListPt, $propName;
+            # save this shorthand XMP property
+            if (defined $nodeID) {
+                SaveBlankInfo($blankInfo, $propListPt, $shortVal);
+            } elsif ($isWriting) {
+                CaptureXMP($exifTool, $propListPt, $shortVal);
+            } else {
+                FoundXMP($exifTool, $tagTablePtr, $propListPt, $shortVal);
+            }
+            pop @$propListPt;
+            $shorthand = 1;
+        }
+        if ($isWriting) {
+            if (ParseXMPElement($exifTool, $tagTablePtr, \$val, 0, $propListPt, $blankInfo)) {
+                # undefine value since we found more properties within this one
+                undef $val;
+                # set an error on any ignored attributes here, because they will be lost
+                $exifTool->{XMP_ERROR} = "Can't handle XMP attribute '$ignored'" if $ignored;
+            }
+            if (defined $val and (length $val or not $shorthand)) {
+                if (defined $nodeID) {
+                    SaveBlankInfo($blankInfo, $propListPt, $val, \%attrs);
+                } else {
+                    CaptureXMP($exifTool, $propListPt, $val, \%attrs);
+                }
+            }
+        } else {
+            # if element value is empty, take value from 'resource' attribute
+            # (preferentially) or 'about' attribute (if no 'resource')
+            $val = $2 if $val eq '' and ($attrs =~ /\bresource=(['"])(.*?)\1/ or
+                                         $attrs =~ /\babout=(['"])(.*?)\1/);
+
+            # look for additional elements contained within this one
+            if (!ParseXMPElement($exifTool, $tagTablePtr, \$val, 0, $propListPt, $blankInfo)) {
+                # there are no contained elements, so this must be a simple property value
+                # (unless we already extracted shorthand values from this element)
+                if (length $val or not $shorthand) {
+                    if (defined $nodeID) {
+                        SaveBlankInfo($blankInfo, $propListPt, $val);
+                    } else {
+                        FoundXMP($exifTool, $tagTablePtr, $propListPt, $val, $attrs{'xml:lang'});
+                    }
+                }
+            }
+        }
+        pop @$propListPt;
+        ++$count;
+    }
+#
+# process resources referenced by blank nodeID's
+#
+    if ($processBlankInfo and %{$$blankInfo{Prop}}) {
+        ProcessBlankInfo($exifTool, $tagTablePtr, $blankInfo, $isWriting);
+        %$blankInfo = ();   # free some memory
+    }
+    return $count;  # return the number of elements found at this level
+}
+
+#------------------------------------------------------------------------------
+# Process XMP data
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table
+# Returns: 1 on success
+sub ProcessXMP($$;$)
+{
+    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen};
+    my $dataLen = $$dirInfo{DataLen};
+    my $rtnVal = 0;
+    my $bom = 0;
+    my ($buff, $fmt, $isXML);
+
+    # read information from XMP file if necessary
+    unless ($dataPt) {
+        my $raf = $$dirInfo{RAF} or return 0;
+        $raf->Read($buff, 128) or return 0;
+        my ($buf2, $double);
+        ($buf2 = $buff) =~ tr/\0//d;    # cheap conversion to UTF-8
+        # check to see if this is XMP format
+        # - CS2 writes .XMP files without the "xpacket begin"
+        unless ($buf2 =~ /^(<\?xpacket begin=|<x(mp)?:xmpmeta)/) {
+            # also recognize XML files (and .XMP files with BOM)
+            if ($buf2 =~ /^(\xfe\xff)(<\?xml|<x(mp)?:xmpmeta)/g) {
+                $fmt = 'n';     # UTF-16 or 32 MM with BOM
+            } elsif ($buf2 =~ /^(\xff\xfe)(<\?xml|<x(mp)?:xmpmeta)/g) {
+                $fmt = 'v';     # UTF-16 or 32 II with BOM
+            } elsif ($buf2 =~ /^(\xef\xbb\xbf)?(<\?xml|<x(mp)?:xmpmeta)/g) {
+                $fmt = 0;       # UTF-8 with BOM or unknown encoding without BOM
+            } elsif ($buf2 =~ /^(\xfe\xff|\xff\xfe|\xef\xbb\xbf)(<\?xpacket begin=)/g) {
+                $double = $1;   # double-encoded UTF
+            } else {
+                return 0;       # not XMP or XML
+            }
+            $bom = 1 if $1;
+            if ($2 eq '<?xml') {
+                return 0 unless $buf2 =~ /<x(mp)?:xmpmeta/;
+                $isXML = 1;
+            }
+            if ($buff =~ /^\0\0/) {
+                $fmt = 'N';     # UTF-32 MM with or without BOM
+            } elsif ($buff =~ /^..\0\0/) {
+                $fmt = 'V';     # UTF-32 II with or without BOM
+            } elsif (not $fmt) {
+                if ($buff =~ /^\0/) {
+                    $fmt = 'n'; # UTF-16 MM without BOM
+                } elsif ($buff =~ /^.\0/) {
+                    $fmt = 'v'; # UTF-16 II without BOM
+                }
+            }
+        }
+        $raf->Seek(0, 2) or return 0;
+        my $size = $raf->Tell() or return 0;
+        $raf->Seek(0, 0) or return 0;
+        $raf->Read($buff, $size) == $size or return 0;
+        # decode the first layer of double-encoded UTF text
+        if ($double) {
+            $buff = substr($buff, length $double);  # remove leading BOM
+            Image::ExifTool::SetWarning(undef);     # clear old warning
+            local $SIG{'__WARN__'} = \&Image::ExifTool::SetWarning;
+            my $tmp;
+            # assume that character data has been re-encoded in UTF, so re-pack
+            # as characters and look for warnings indicating a false assumption
+            if ($double eq "\xef\xbb\xbf") {
+                $tmp = Image::ExifTool::UTF82Unicode($buff, 'C');
+            } else {
+                my $fmt = ($double eq "\xfe\xff") ? 'n' : 'v';
+                $tmp = pack('C*', unpack("$fmt*",$buff));
+            }
+            if (Image::ExifTool::GetWarning()) {
+                $exifTool->Warn('Superfluous BOM at start of XMP');
+            } else {
+                $exifTool->Warn('XMP is double UTF-encoded');
+                $buff = $tmp;   # use the decoded XMP
+            }
+            $size = length $buff;
+        }
+        $dataPt = \$buff;
+        $dirStart = 0;
+        $dirLen = $dataLen = $size;
+        $exifTool->SetFileType();
+    }
+   
+    # take substring if necessary
+    if ($dataLen != $dirStart + $dirLen) {
+        $buff = substr($$dataPt, $dirStart, $dirLen);
+        $dataPt = \$buff;
+        $dirStart = 0;
+    }
+    if ($exifTool->{REQ_TAG_LOOKUP}->{xmp}) {
+        $exifTool->FoundTag('XMP', substr($$dataPt, $dirStart, $dirLen));
+    }
+    if ($exifTool->Options('Verbose') and not $exifTool->{XMP_CAPTURE}) {
+        $exifTool->VerboseDir('XMP', 0, $dirLen);
+    }
+#
+# convert UTF-16 or UTF-32 encoded XMP to UTF-8 if necessary
+#
+    my $begin = '<?xpacket begin=';
+    pos($$dataPt) = $dirStart;
+    delete $$exifTool{XMP_IS_XML};
+    if ($isXML) {
+        $$exifTool{XMP_IS_XML} = 1;
+        $$exifTool{XMP_NO_XPACKET} = 1 + $bom;
+    } elsif ($$dataPt =~ /\G\Q$begin\E/gc) {
+        delete $$exifTool{XMP_NO_XPACKET};
+    } elsif ($$dataPt =~ /<x(mp)?:xmpmeta/gc) {
+        $$exifTool{XMP_NO_XPACKET} = 1 + $bom;
+    } else {
+        delete $$exifTool{XMP_NO_XPACKET};
+        # check for UTF-16 encoding (insert one \0 between characters)
+        $begin = join "\0", split //, $begin;
+        if ($$dataPt =~ /\G(\0)?\Q$begin\E\0./g) {
+            # validate byte ordering by checking for U+FEFF character
+            if ($1) {
+                # should be big-endian since we had a leading \0
+                $fmt = 'n' if $$dataPt =~ /\G\xfe\xff/g;
+            } else {
+                $fmt = 'v' if $$dataPt =~ /\G\0\xff\xfe/g;
+            }
+        } else {
+            # check for UTF-32 encoding (with three \0's between characters)
+            $begin =~ s/\0/\0\0\0/g;
+            # must reset pos because it was killed by previous unsuccessful //g match
+            pos($$dataPt) = $dirStart;
+            if ($$dataPt !~ /\G(\0\0\0)?\Q$begin\E\0\0\0./g) {
+                $fmt = 0;   # set format to zero as indication we didn't find encoded XMP
+            } elsif ($1) {
+                # should be big-endian
+                $fmt = 'N' if $$dataPt =~ /\G\0\0\xfe\xff/g;
+            } else {
+                $fmt = 'V' if $$dataPt =~ /\G\0\0\0\xff\xfe\0\0/g;
+            }
+        }
+        defined $fmt or $exifTool->Warn('XMP character encoding error');
+    }
+    if ($fmt) {
+        # translate into UTF-8
+        if ($] >= 5.006001) {
+            $buff = pack('C0U*', unpack("x$dirStart$fmt*",$$dataPt));
+        } else {
+            $buff = Image::ExifTool::PackUTF8(unpack("x$dirStart$fmt*",$$dataPt));
+        }
+        $dataPt = \$buff;
+        $dirStart = 0;
+    }
+    # avoid scanning for XMP later in case ScanForXMP is set
+    $$exifTool{FoundXMP} = 1;
+
+    # parse the XMP
+    $tagTablePtr or $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
+    $rtnVal = 1 if ParseXMPElement($exifTool, $tagTablePtr, $dataPt, $dirStart);
+
+    # return DataPt if successful in case we want it for writing
+    $$dirInfo{DataPt} = $dataPt if $rtnVal and $$dirInfo{RAF};
+
+    return $rtnVal;
+}
+
+
+1;  #end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::XMP - Read XMP meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+XMP stands for Extensible Metadata Platform.  It is a format based on XML
+that Adobe developed for embedding metadata information in image files.
+This module contains the definitions required by Image::ExifTool to read XMP
+information.
+
+=head1 AUTHOR
+
+Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
+
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 REFERENCES
+
+=over 4
+
+=item L<http://www.adobe.com/products/xmp/pdfs/xmpspec.pdf>
+
+=item L<http://www.w3.org/TR/rdf-syntax-grammar/>
+
+=item L<http://www.portfoliofaq.com/pfaq/v7mappings.htm>
+
+=item L<http://www.iptc.org/IPTC4XMP/>
+
+=item L<http://creativecommons.org/technology/xmp>
+
+=item L<http://www.optimasc.com/products/fileid/xmp-extensions.pdf>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/XMP Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Image/Size.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Image/Size.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Image/Size.pm	(revision 20131)
@@ -0,0 +1,1140 @@
+###############################################################################
+#
+# This file copyright (c) 2000 by Randy J. Ray, all rights reserved
+#
+# Copying and distribution are permitted under the terms of the Artistic
+# License as distributed with Perl versions 5.005 and later.
+#
+###############################################################################
+#
+# Once upon a time, this code was lifted almost verbatim from wwwis by Alex
+# Knowles, alex@ed.ac.uk. Since then, even I barely recognize it. It has
+# contributions, fixes, additions and enhancements from all over the world.
+#
+# See the file README for change history.
+#
+###############################################################################
+
+package Image::Size;
+
+# require 5.6.0;
+require 5.006_000;
+
+use strict;
+use bytes;
+use Cwd ();
+use File::Spec ();
+use Symbol ();
+use AutoLoader 'AUTOLOAD';
+require Exporter;
+
+our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $revision, $VERSION, $NO_CACHE,
+     $GIF_BEHAVIOR, %PCD_MAP, $PCD_SCALE, $read_in, $last_pos);
+
+BEGIN
+{
+
+    @ISA         = qw(Exporter);
+    @EXPORT      = qw(imgsize);
+    @EXPORT_OK   = qw(imgsize html_imgsize attr_imgsize $NO_CACHE $PCD_SCALE
+                      $GIF_BEHAVIOR);
+    %EXPORT_TAGS = ('all' => [ @EXPORT_OK ]);
+
+    $VERSION = "3.01";
+
+    # Default behavior for GIFs is to return the "screen" size
+    $GIF_BEHAVIOR = 0;
+
+}
+
+# This allows people to specifically request that the cache not be used
+$NO_CACHE = 0;
+
+# Package lexicals - invisible to outside world, used only in imgsize
+#
+# Cache of files seen, and mapping of patterns to the sizing routine
+my %cache = ();
+my %type_map = ( '^GIF8[7,9]a'              => \&gifsize,
+                 "^\xFF\xD8"                => \&jpegsize,
+                 "^\x89PNG\x0d\x0a\x1a\x0a" => \&pngsize,
+                 "^P[1-7]"                  => \&ppmsize, # also XVpics
+                 '\#define\s+\S+\s+\d+'     => \&xbmsize,
+                 '\/\* XPM \*\/'            => \&xpmsize,
+                 '^MM\x00\x2a'              => \&tiffsize,
+                 '^II\x2a\x00'              => \&tiffsize,
+                 '^BM'                      => \&bmpsize,
+                 '^8BPS'                    => \&psdsize,
+                 '^PCD_OPA'                 => \&pcdsize,
+                 '^FWS'                     => \&swfsize,
+                 '^CWS'                     => \&swfmxsize,
+                 "^\x8aMNG\x0d\x0a\x1a\x0a" => \&mngsize);
+# Kodak photo-CDs are weird. Don't ask me why, you really don't want details.
+%PCD_MAP = ( 'base/16' => [ 192,  128  ],
+             'base/4'  => [ 384,  256  ],
+             'base'    => [ 768,  512  ],
+             'base4'   => [ 1536, 1024 ],
+             'base16'  => [ 3072, 2048 ],
+             'base64'  => [ 6144, 4096 ] );
+# Default scale for PCD images
+$PCD_SCALE = 'base';
+
+#
+# These are lexically-scoped anonymous subroutines for reading the three
+# types of input streams. When the input to imgsize() is typed, then the
+# lexical "read_in" is assigned one of these, thus allowing the individual
+# routines to operate on these streams abstractly.
+#
+
+my $read_io = sub {
+    my $handle = shift;
+    my ($length, $offset) = @_;
+
+    if (defined($offset) && ($offset != $last_pos))
+    {
+        $last_pos = $offset;
+        return '' if (! seek($handle, $offset, 0));
+    }
+
+    my ($data, $rtn) = ('', 0);
+    $rtn = read $handle, $data, $length;
+    $data = '' unless ($rtn);
+    $last_pos = tell $handle;
+
+    $data;
+};
+
+my $read_buf = sub {
+    my $buf = shift;
+    my ($length, $offset) = @_;
+
+    if (defined($offset) && ($offset != $last_pos))
+    {
+        $last_pos = $offset;
+        return '' if ($last_pos > length($$buf));
+    }
+
+    my $data = substr($$buf, $last_pos, $length);
+    $last_pos += length($data);
+
+    $data;
+};
+
+sub imgsize
+{
+    my $stream = shift;
+
+    my ($handle, $header);
+    my ($x, $y, $id, $mtime, @list);
+    # These only used if $stream is an existant open FH
+    my ($save_pos, $need_restore) = (0, 0);
+    # This is for when $stream is a locally-opened file
+    my $need_close = 0;
+    # This will contain the file name, if we got one
+    my $file_name = undef;
+
+    $header = '';
+
+    if (ref($stream) eq "SCALAR")
+    {
+        $handle = $stream;
+        $read_in = $read_buf;
+        $header = substr(($$handle || ''), 0, 256);
+    }
+    elsif (ref $stream)
+    {
+        #
+        # I no longer require $stream to be in the IO::* space. So I'm assuming
+        # you don't hose yourself by passing a ref that can't do fileops. If
+        # you do, you fix it.
+        #
+        $handle = $stream;
+        $read_in = $read_io;
+        $save_pos = tell $handle;
+        $need_restore = 1;
+
+        #
+        # First alteration (didn't wait long, did I?) to the existant handle:
+        #
+        # assist dain-bramaged operating systems -- SWD
+        # SWD: I'm a bit uncomfortable with changing the mode on a file
+        # that something else "owns" ... the change is global, and there
+        # is no way to reverse it.
+        # But image files ought to be handled as binary anyway.
+        #
+        binmode($handle);
+        seek($handle, 0, 0);
+        read $handle, $header, 256;
+        seek($handle, 0, 0);
+    }
+    else
+    {
+        unless ($NO_CACHE)
+        {
+            $stream = File::Spec->catfile(Cwd::cwd(),$stream)
+                unless File::Spec->file_name_is_absolute($stream);
+            $mtime = (stat $stream)[9];
+            if (-e "$stream" and exists $cache{$stream})
+            {
+                @list = split(/,/, $cache{$stream}, 4);
+
+                # Don't return the cache if the file is newer.
+                return @list[1 .. 3] unless ($list[0] < $mtime);
+                # In fact, clear it
+                delete $cache{$stream};
+            }
+        }
+
+        #first try to open the stream
+        $handle = Symbol::gensym();
+        open($handle, "< $stream") or
+            return (undef, undef, "Can't open image file $stream: $!");
+
+        $need_close = 1;
+        # assist dain-bramaged operating systems -- SWD
+        binmode($handle);
+        read $handle, $header, 256;
+        seek($handle, 0, 0);
+        $read_in = $read_io;
+        $file_name = $stream;
+    }
+    $last_pos = 0;
+
+    #
+    # Oh pessimism... set the values of $x and $y to the error condition. If
+    # the grep() below matches the data to one of the known types, then the
+    # called subroutine will override these...
+    #
+    $id = "Data stream is not a known image file format";
+    $x  = undef;
+    $y  = undef;
+
+    grep($header =~ /$_/ && (($x, $y, $id) = &{$type_map{$_}}($handle)),
+         keys %type_map);
+
+    #
+    # Added as an afterthought: I'm probably not the only one who uses the
+    # same shaded-sphere image for several items on a bulleted list:
+    #
+    $cache{$stream} = join(',', $mtime, $x, $y, $id)
+        unless ($NO_CACHE or (ref $stream) or (! defined $x));
+
+    #
+    # If we were passed an existant file handle, we need to restore the
+    # old filepos:
+    #
+    seek($handle, $save_pos, 0) if $need_restore;
+    # ...and if we opened the file ourselves, we need to close it
+    close($handle) if $need_close;
+
+    #
+    # Image::Magick operates on file names.
+    #
+    if ($file_name && ! defined($x) && ! defined($y)) {
+        ($x, $y, $id) = imagemagick_size($file_name);
+    }
+
+
+    # results:
+    return (wantarray) ? ($x, $y, $id) : ();
+}
+
+sub imagemagick_size {
+    my $module_name;
+    # First see if we have already loaded Graphics::Magick or Image::Magick
+    # If so, just use whichever one is already loaded.
+    if (exists $INC{'Graphics/Magick.pm'}) {
+        $module_name = 'Graphics::Magick';
+    }
+    elsif (exists $INC{'Image/Magick.pm'}) {
+        $module_name = 'Image::Magick';
+    }
+
+    # If neither are already loaded, try loading either one.
+    elsif ( _load_magick_module('Graphics::Magick') ) {
+       $module_name = 'Graphics::Magick';
+    }
+    elsif ( _load_magick_module('Image::Magick') ) {
+       $module_name = 'Image::Magick';
+    }
+
+    if ($module_name) {
+        my ($file_name) = @_;
+        my $img = $module_name->new();
+        my $x = $img->Read($file_name);
+        # Image::Magick error handling is a bit weird, see
+        # <http://www.simplesystems.org/ImageMagick/www/perl.html#erro>
+        if("$x") {
+            return (undef, undef, "$x");
+        } else {
+            return ($img->Get('width', 'height', 'format'));
+        }
+
+    }
+    else {
+        return (undef, undef, "Data stream is not a known image file format");
+    }
+}
+
+# load Graphics::Magick or Image::Magick if one is not already loaded. 
+sub _load_magick_module {
+    my $module_name = shift;
+    eval {
+        local $SIG{__DIE__};
+        require $module_name;
+    };
+    return !$@;
+}
+
+
+sub html_imgsize
+{
+    my @args = imgsize(@_);
+
+    # Use lowercase and quotes so that it works with xhtml.
+    return ((defined $args[0]) ?
+            sprintf('width="%d" height="%d"', @args) :
+            undef);
+}
+
+sub attr_imgsize
+{
+    my @args = imgsize(@_);
+
+    return ((defined $args[0]) ?
+            (('-width', '-height', @args)[0, 2, 1, 3]) :
+            undef);
+}
+
+# This used only in gifsize:
+sub img_eof
+{
+    my $stream = shift;
+
+    return ($last_pos >= length($$stream)) if (ref($stream) eq "SCALAR");
+
+    eof $stream;
+}
+
+# Simple converter-routine used by SWF and CWS code
+sub _bin2int { unpack("N", pack("B32", substr("0" x 32 . shift, -32))); }
+
+=head1 NAME
+
+Image::Size - read the dimensions of an image in several popular formats
+
+=head1 SYNOPSIS
+
+    use Image::Size;
+    # Get the size of globe.gif
+    ($globe_x, $globe_y) = imgsize("globe.gif");
+    # Assume X=60 and Y=40 for remaining examples
+
+    use Image::Size 'html_imgsize';
+    # Get the size as 'width="X" height="Y"' for HTML generation
+    $size = html_imgsize("globe.gif");
+    # $size == 'width="60" height="40"'
+
+    use Image::Size 'attr_imgsize';
+    # Get the size as a list passable to routines in CGI.pm
+    @attrs = attr_imgsize("globe.gif");
+    # @attrs == ('-width', 60, '-height', 40)
+
+    use Image::Size;
+    # Get the size of an in-memory buffer
+    ($buf_x, $buf_y) = imgsize(\$buf);
+    # Assuming that $buf was the data, imgsize() needed a reference to a scalar
+
+=head1 DESCRIPTION
+
+The B<Image::Size> library is based upon the C<wwwis> script written by
+Alex Knowles I<(alex@ed.ac.uk)>, a tool to examine HTML and add 'width' and
+'height' parameters to image tags. The sizes are cached internally based on
+file name, so multiple calls on the same file name (such as images used
+in bulleted lists, for example) do not result in repeated computations.
+
+B<Image::Size> provides three interfaces for possible import:
+
+=over
+
+=item imgsize(I<stream>)
+
+Returns a three-item list of the X and Y dimensions (width and height, in
+that order) and image type of I<stream>. Errors are noted by undefined
+(B<undef>) values for the first two elements, and an error string in the third.
+The third element can be (and usually is) ignored, but is useful when
+sizing data whose type is unknown.
+
+=item html_imgsize(I<stream>)
+
+Returns the width and height (X and Y) of I<stream> pre-formatted as a single
+string C<'width="X" height="Y"'> suitable for addition into generated HTML IMG
+tags. If the underlying call to C<imgsize> fails, B<undef> is returned. The
+format returned is dually suited to both HTML and XHTML.
+
+=item attr_imgsize(I<stream>)
+
+Returns the width and height of I<stream> as part of a 4-element list useful
+for routines that use hash tables for the manipulation of named parameters,
+such as the Tk or CGI libraries. A typical return value looks like
+C<("-width", X, "-height", Y)>. If the underlying call to C<imgsize> fails,
+B<undef> is returned.
+
+=back
+
+By default, only C<imgsize()> is exported. Any one or combination of the three
+may be explicitly imported, or all three may be with the tag B<:all>.
+
+=head2 Input Types
+
+The sort of data passed as I<stream> can be one of three forms:
+
+=over
+
+=item string
+
+If an ordinary scalar (string) is passed, it is assumed to be a file name
+(either absolute or relative to the current working directory of the
+process) and is searched for and opened (if found) as the source of data.
+Possible error messages (see DIAGNOSTICS below) may include file-access
+problems.
+
+=item scalar reference
+
+If the passed-in stream is a scalar reference, it is interpreted as pointing
+to an in-memory buffer containing the image data.
+
+        # Assume that &read_data gets data somewhere (WWW, etc.)
+        $img = &read_data;
+        ($x, $y, $id) = imgsize(\$img);
+        # $x and $y are dimensions, $id is the type of the image
+
+=item Open file handle
+
+The third option is to pass in an open filehandle (such as an object of
+the C<IO::File> class, for example) that has already been associated with
+the target image file. The file pointer will necessarily move, but will be
+restored to its original position before subroutine end.
+
+        # $fh was passed in, is IO::File reference:
+        ($x, $y, $id) = imgsize($fh);
+        # Same as calling with filename, but more abstract.
+
+=back
+
+=head2 Recognized Formats
+
+Image::Size natively understands and sizes data in the following formats:
+
+=over 4
+
+=item GIF
+
+=item JPG
+
+=item XBM
+
+=item XPM
+
+=item PPM family (PPM/PGM/PBM)
+
+=item XV thumbnails
+
+=item PNG
+
+=item MNG
+
+=item TIF
+
+=item BMP
+
+=item PSD (Adobe PhotoShop)
+
+=item SWF (ShockWave/Flash)
+
+=item CWS (FlashMX, compressed SWF, Flash 6)
+
+=item PCD (Kodak PhotoCD, see notes below)
+
+=back
+
+Additionally, if the B<Image::Magick> module is present, the file types
+supported by it are also supported by Image::Size.  See also L<"CAVEATS">.
+
+When using the C<imgsize> interface, there is a third, unused value returned
+if the programmer wishes to save and examine it. This value is the identity of
+the data type, expressed as a 2-3 letter abbreviation as listed above. This is
+useful when operating on open file handles or in-memory data, where the type
+is as unknown as the size.  The two support routines ignore this third return
+value, so those wishing to use it must use the base C<imgsize> routine.
+
+Note that when the B<Image::Magick> fallback is used (for all non-natively
+supported files), the data type identity comes directly from the 'format'
+parameter reported by B<Image::Magick>, so it may not meet the 2-3 letter
+abbreviation format.  For example, a WBMP file might be reported as
+'Wireless Bitmap (level 0) image' in this case.
+
+=head2 Information Cacheing and C<$NO_CACHE>
+
+When a filename is passed to any of the sizing routines, the default behavior
+of the library is to cache the resulting information. The modification-time of
+the file is also recorded, to determine whether the cache should be purged and
+updated. This was originally added due to the fact that a number of CGI
+applications were using this library to generate attributes for pages that
+often used the same graphical element many times over.
+
+However, the cacheing can lead to problems when the files are generated
+dynamically, at a rate that exceeds the resolution of the modification-time
+value on the filesystem. Thus, the optionally-importable control variable
+C<$NO_CACHE> has been introduced. If this value is anything that evaluates to a
+non-false value (be that the value 1, any non-null string, etc.) then the
+cacheing is disabled until such time as the program re-enables it by setting
+the value to false.
+
+The parameter C<$NO_CACHE> may be imported as with the B<imgsize> routine, and
+is also imported when using the import tag B<C<:all>>. If the programmer
+chooses not to import it, it is still accessible by the fully-qualified package
+name, B<$Image::Size::NO_CACHE>.
+
+=head2 Sizing PhotoCD Images
+
+With version 2.95, support for the Kodak PhotoCD image format is
+included. However, these image files are not quite like the others. One file
+is the source of the image in any of a range of pre-set resolutions (all with
+the same aspect ratio). Supporting this here is tricky, since there is nothing
+inherent in the file to limit it to a specific resolution.
+
+The library addresses this by using a scale mapping, and requiring the user
+(you) to specify which scale is preferred for return. Like the C<$NO_CACHE>
+setting described earlier, this is an importable scalar variable that may be
+used within the application that uses B<Image::Size>. This parameter is called
+C<$PCD_SCALE>, and is imported by the same name. It, too, is also imported
+when using the tag B<C<:all>> or may be referenced as
+B<$Image::Size::PCD_SCALE>.
+
+The parameter should be set to one of the following values:
+
+        base/16
+        base/4
+        base
+        base4
+        base16
+        base64
+
+Note that not all PhotoCD disks will have included the C<base64>
+resolution. The actual resolutions are not listed here, as they are constant
+and can be found in any documentation on the PCD format. The value of
+C<$PCD_SCALE> is treated in a case-insensitive manner, so C<base> is the same
+as C<Base> or C<BaSe>. The default scale is set to C<base>.
+
+Also note that the library makes no effort to read enough of the PCD file to
+verify that the requested resolution is available. The point of this library
+is to read as little as necessary so as to operate efficiently. Thus, the only
+real difference to be found is in whether the orientation of the image is
+portrait or landscape. That is in fact all that the library extracts from the
+image file.
+
+=head2 Controlling Behavior with GIF Images
+
+GIF images present a sort of unusual situation when it comes to reading size.
+Because GIFs can be a series of sub-images to be isplayed as an animated
+sequence, what part does the user want to get the size for?
+
+When dealing with GIF files, the user may control the behavior by setting the
+global value B<$Image::Size::GIF_BEHAVIOR>. Like the PCD setting, this may
+be imported when loading the library. Three values are recognized by the
+GIF-handling code:
+
+=over 4
+
+=item 0
+
+This is the default value. When this value is chosen, the returned dimensions
+are those of the "screen". The "screen" is the display area that the GIF
+declares in the first data block of the file. No sub-images will be greater
+than this in size; if they are, the specification dictates that they be
+cropped to fit within the box.
+
+This is also the fastest method for sizing the GIF, as it reads the least
+amount of data from the image stream.
+
+=item 1
+
+If this value is set, then the size of the first sub-image within the GIF is
+returned. For plain (non-animated) GIF files, this would be the same as the
+screen (though it doesn't have to be, strictly-speaking).
+
+When the first image descriptor block is read, the code immediately returns,
+making this only slightly-less efficient than the previous setting.
+
+=item 2
+
+If this value is chosen, then the code loops through all the sub-images of the
+animated GIF, and returns the dimensions of the largest of them.
+
+This option requires that the full GIF image be read, in order to ensure that
+the largest is found.
+
+=back
+
+Any value outside this range will produce an error in the GIF code before any
+image data is read.
+
+The value of dimensions other than the view-port ("screen") is dubious.
+However, some users have asked for that functionality.
+
+=head1 DIAGNOSTICS
+
+The base routine, C<imgsize>, returns B<undef> as the first value in its list
+when an error has occured. The third element contains a descriptive
+error message.
+
+The other two routines simply return B<undef> in the case of error.
+
+=head1 MORE EXAMPLES
+
+The B<attr_imgsize> interface is also well-suited to use with the Tk
+extension:
+
+    $image = $widget->Photo(-file => $img_path, attr_imgsize($img_path));
+
+Since the C<Tk::Image> classes use dashed option names as C<CGI> does, no
+further translation is needed.
+
+This package is also well-suited for use within an Apache web server context.
+File sizes are cached upon read (with a check against the modified time of
+the file, in case of changes), a useful feature for a B<mod_perl> environment
+in which a child process endures beyond the lifetime of a single request.
+Other aspects of the B<mod_perl> environment cooperate nicely with this
+module, such as the ability to use a sub-request to fetch the full pathname
+for a file within the server space. This complements the HTML generation
+capabilities of the B<CGI> module, in which C<CGI::img> wants a URL but
+C<attr_imgsize> needs a file path:
+
+    # Assume $Q is an object of class CGI, $r is an Apache request object.
+    # $imgpath is a URL for something like "/img/redball.gif".
+    $r->print($Q->img({ -src => $imgpath,
+                        attr_imgsize($r->lookup_uri($imgpath)->filename) }));
+
+The advantage here, besides not having to hard-code the server document root,
+is that Apache passes the sub-request through the usual request lifecycle,
+including any stages that would re-write the URL or otherwise modify it.
+
+=head1 CAVEATS
+
+Caching of size data can only be done on inputs that are file names. Open
+file handles and scalar references cannot be reliably transformed into a
+unique key for the table of cache data. Buffers could be cached using the
+MD5 module, and perhaps in the future I will make that an option. I do not,
+however, wish to lengthen the dependancy list by another item at this time.
+
+As B<Image::Magick> operates on file names, not handles, the use of it is
+restricted to cases where the input to C<imgsize> is provided as file name.
+
+=head1 SEE ALSO
+
+The B<Image::Magick> and B<Image::Info> Perl modules at CPAN.
+
+=head1 AUTHORS
+
+Perl module interface by Randy J. Ray I<(rjray@blackperl.com)>, original
+image-sizing code by Alex Knowles I<(alex@ed.ac.uk)> and Andrew Tong
+I<(werdna@ugcs.caltech.edu)>, used with their joint permission.
+
+Some bug fixes submitted by Bernd Leibing I<(bernd.leibing@rz.uni-ulm.de)>.
+PPM/PGM/PBM sizing code contributed by Carsten Dominik
+I<(dominik@strw.LeidenUniv.nl)>. Tom Metro I<(tmetro@vl.com)> re-wrote the JPG
+and PNG code, and also provided a PNG image for the test suite. Dan Klein
+I<(dvk@lonewolf.com)> contributed a re-write of the GIF code.  Cloyce Spradling
+I<(cloyce@headgear.org)> contributed TIFF sizing code and test images. Aldo
+Calpini I<(a.calpini@romagiubileo.it)> suggested support of BMP images (which
+I I<really> should have already thought of :-) and provided code to work
+with. A patch to allow html_imgsize to produce valid output for XHTML, as
+well as some documentation fixes was provided by Charles Levert
+I<(charles@comm.polymtl.ca)>. The ShockWave/Flash support was provided by
+Dmitry Dorofeev I<(dima@yasp.com)>. Though I neglected to take note of who
+supplied the PSD (PhotoShop) code, a bug was identified by Alex Weslowski
+<aweslowski@rpinteractive.com>, who also provided a test image. PCD support
+was adapted from a script made available by Phil Greenspun, as guided to my
+attention by Matt Mueller I<mueller@wetafx.co.nz>. A thorough read of the
+documentation and source by Philip Newton I<Philip.Newton@datenrevision.de>
+found several typos and a small buglet. Ville Skyttä I<(ville.skytta@iki.fi)>
+provided the MNG and the Image::Magick fallback code.
+
+=cut
+
+1;
+
+__END__
+
+###########################################################################
+# Subroutine gets the size of the specified GIF
+###########################################################################
+sub gifsize
+{
+    my $stream = shift;
+
+    my ($cmapsize, $buf, $sh, $sw, $h, $w, $x, $y, $type);
+
+    my $gif_blockskip = sub {
+        my ($skip, $type) = @_;
+        my ($lbuf);
+
+        &$read_in($stream, $skip);        # Skip header (if any)
+        while (1)
+        {
+            if (&img_eof($stream))
+            {
+                return (undef, undef,
+                        "Invalid/Corrupted GIF (at EOF in GIF $type)");
+            }
+            $lbuf = &$read_in($stream, 1);        # Block size
+            last if ord($lbuf) == 0;     # Block terminator
+            &$read_in($stream, ord($lbuf));  # Skip data
+        }
+    };
+
+    return (undef, undef,
+            'Out-of-range value for $Image::Size::GIF_BEHAVIOR: ' .
+            $Image::Size::GIF_BEHAVIOR)
+        if ($Image::Size::GIF_BEHAVIOR > 2);
+
+    # Skip over the identifying string, since we already know this is a GIF
+    $type = &$read_in($stream, 6);
+    if (length($buf = &$read_in($stream, 7)) != 7 )
+    {
+        return (undef, undef, "Invalid/Corrupted GIF (bad header)");
+    }
+    ($sw, $sh, $x) = unpack("vv C", $buf);
+    if ($Image::Size::GIF_BEHAVIOR == 0)
+    {
+        return ($sw, $sh, 'GIF');
+    }
+
+    if ($x & 0x80)
+    {
+        $cmapsize = 3 * (2**(($x & 0x07) + 1));
+        if (! &$read_in($stream, $cmapsize))
+        {
+            return (undef, undef,
+                    "Invalid/Corrupted GIF (global color map too small?)");
+        }
+    }
+
+    # Before we start this loop, set $sw and $sh to 0s and use them to track
+    # the largest sub-image in the overall GIF.
+    $sw = $sh = 0;
+
+  FINDIMAGE:
+    while (1)
+    {
+        if (&img_eof($stream))
+        {
+            # At this point, if we haven't returned then the user wants the
+            # largest of the sub-images. So, if $sh and $sw are still 0s, then
+            # we didn't see even one Image Descriptor block. Otherwise, return
+            # those two values.
+            if ($sw and $sh)
+            {
+                return ($sw, $sh, 'GIF');
+            }
+            else
+            {
+                return (undef, undef,
+                        "Invalid/Corrupted GIF (no Image Descriptors)");
+            }
+        }
+        $buf = &$read_in($stream, 1);
+        ($x) = unpack("C", $buf);
+        if ($x == 0x2c)
+        {
+            # Image Descriptor (GIF87a, GIF89a 20.c.i)
+            if (length($buf = &$read_in($stream, 8)) != 8)
+            {
+                return (undef, undef,
+                        "Invalid/Corrupted GIF (missing image header?)");
+            }
+            ($x, $y) = unpack("x4 vv", $buf);
+            return ($x, $y, 'GIF') if ($Image::Size::GIF_BEHAVIOR == 1);
+            if ($x > $sw and $y > $sh)
+            {
+                $sw = $x;
+                $sh = $y;
+            }
+        }
+        if ($x == 0x21)
+        {
+            # Extension Introducer (GIF89a 23.c.i, could also be in GIF87a)
+            $buf = &$read_in($stream, 1);
+            ($x) = unpack("C", $buf);
+            if ($x == 0xF9)
+            {
+                # Graphic Control Extension (GIF89a 23.c.ii)
+                &$read_in($stream, 6);    # Skip it
+                next FINDIMAGE;       # Look again for Image Descriptor
+            }
+            elsif ($x == 0xFE)
+            {
+                # Comment Extension (GIF89a 24.c.ii)
+                &$gif_blockskip(0, "Comment");
+                next FINDIMAGE;       # Look again for Image Descriptor
+            }
+            elsif ($x == 0x01)
+            {
+                # Plain Text Label (GIF89a 25.c.ii)
+                &$gif_blockskip(13, "text data");
+                next FINDIMAGE;       # Look again for Image Descriptor
+            }
+            elsif ($x == 0xFF)
+            {
+                # Application Extension Label (GIF89a 26.c.ii)
+                &$gif_blockskip(12, "application data");
+                next FINDIMAGE;       # Look again for Image Descriptor
+            }
+            else
+            {
+                return (undef, undef,
+                        sprintf("Invalid/Corrupted GIF (Unknown " .
+                                "extension %#x)", $x));
+            }
+        }
+        else
+        {
+            return (undef, undef,
+                    sprintf("Invalid/Corrupted GIF (Unknown code %#x)",
+                            $x));
+        }
+    }
+}
+
+sub xbmsize
+{
+    my $stream = shift;
+
+    my $input;
+    my ($x, $y, $id) = (undef, undef, "Could not determine XBM size");
+
+    $input = &$read_in($stream, 1024);
+    if ($input =~ /^\#define\s*\S*\s*(\d+)\s*\n\#define\s*\S*\s*(\d+)/si)
+    {
+        ($x, $y) = ($1, $2);
+        $id = 'XBM';
+    }
+
+    ($x, $y, $id);
+}
+
+# Added by Randy J. Ray, 30 Jul 1996
+# Size an XPM file by looking for the "X Y N W" line, where X and Y are
+# dimensions, N is the total number of colors defined, and W is the width of
+# a color in the ASCII representation, in characters. We only care about X & Y.
+sub xpmsize
+{
+    my $stream = shift;
+
+    my $line;
+    my ($x, $y, $id) = (undef, undef, "Could not determine XPM size");
+
+    while ($line = &$read_in($stream, 1024))
+    {
+        next unless ($line =~ /"\s*(\d+)\s+(\d+)(\s+\d+\s+\d+){1,2}\s*"/s);
+        ($x, $y) = ($1, $2);
+        $id = 'XPM';
+        last;
+    }
+
+    ($x, $y, $id);
+}
+
+
+# pngsize : gets the width & height (in pixels) of a png file
+# cor this program is on the cutting edge of technology! (pity it's blunt!)
+#
+# Re-written and tested by tmetro@vl.com
+sub pngsize
+{
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef, "could not determine PNG size");
+    my ($offset, $length);
+
+    # Offset to first Chunk Type code = 8-byte ident + 4-byte chunk length + 1
+    $offset = 12; $length = 4;
+    if (&$read_in($stream, $length, $offset) eq 'IHDR')
+    {
+        # IHDR = Image Header
+        $length = 8;
+        ($x, $y) = unpack("NN", &$read_in($stream, $length));
+        $id = 'PNG';
+    }
+
+    ($x, $y, $id);
+}
+
+# mngsize: gets the width and height (in pixels) of an MNG file.
+# See <URL:http://www.libpng.org/pub/mng/spec/> for the specification.
+#
+# Basically a copy of pngsize.
+sub mngsize
+{
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef, "could not determine MNG size");
+    my ($offset, $length);
+
+    # Offset to first Chunk Type code = 8-byte ident + 4-byte chunk length + 1
+    $offset = 12; $length = 4;
+    if (&$read_in($stream, $length, $offset) eq 'MHDR')
+    {
+        # MHDR = Image Header
+        $length = 8;
+        ($x, $y) = unpack("NN", &$read_in($stream, $length));
+        $id = 'MNG';
+    }
+
+    ($x, $y, $id);
+}
+
+# jpegsize: gets the width and height (in pixels) of a jpeg file
+# Andrew Tong, werdna@ugcs.caltech.edu           February 14, 1995
+# modified slightly by alex@ed.ac.uk
+# and further still by rjray@blackperl.com
+# optimization and general re-write from tmetro@vl.com
+sub jpegsize
+{
+    my $stream = shift;
+
+    my $MARKER      = "\xFF";       # Section marker.
+
+    my $SIZE_FIRST  = 0xC0;         # Range of segment identifier codes
+    my $SIZE_LAST   = 0xC3;         #  that hold size info.
+
+    my ($x, $y, $id) = (undef, undef, "could not determine JPEG size");
+
+    my ($marker, $code, $length);
+    my $segheader;
+
+    # Dummy read to skip header ID
+    &$read_in($stream, 2);
+    while (1)
+    {
+        $length = 4;
+        $segheader = &$read_in($stream, $length);
+
+        # Extract the segment header.
+        ($marker, $code, $length) = unpack("a a n", $segheader);
+
+        # Verify that it's a valid segment.
+        if ($marker ne $MARKER)
+        {
+            # Was it there?
+            $id = "JPEG marker not found";
+            last;
+        }
+        elsif ((ord($code) >= $SIZE_FIRST) && (ord($code) <= $SIZE_LAST))
+        {
+            # Segments that contain size info
+            $length = 5;
+            ($y, $x) = unpack("xnn", &$read_in($stream, $length));
+            $id = 'JPG';
+            last;
+        }
+        else
+        {
+            # Dummy read to skip over data
+            &$read_in($stream, ($length - 2));
+        }
+    }
+
+    ($x, $y, $id);
+}
+
+# ppmsize: gets data on the PPM/PGM/PBM family.
+#
+# Contributed by Carsten Dominik <dominik@strw.LeidenUniv.nl>
+sub ppmsize
+{
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef,
+                        "Unable to determine size of PPM/PGM/PBM data");
+    my $n;
+
+    my $header = &$read_in($stream, 1024);
+
+    # PPM file of some sort
+    $header =~ s/^\#.*//mg;
+    ($n, $x, $y) = ($header =~ /^(P[1-6])\s+(\d+)\s+(\d+)/s);
+    $id = "PBM" if $n eq "P1" || $n eq "P4";
+    $id = "PGM" if $n eq "P2" || $n eq "P5";
+    $id = "PPM" if $n eq "P3" || $n eq "P6";
+    if ($n eq 'P7')
+    {
+        # John Bradley's XV thumbnail pics (thanks to inwap@jomis.Tymnet.COM)
+        $id = 'XV';
+        ($x, $y) = ($header =~ /IMGINFO:(\d+)x(\d+)/s);
+    }
+
+    ($x, $y, $id);
+}
+
+# tiffsize: size a TIFF image
+#
+# Contributed by Cloyce Spradling <cloyce@headgear.org>
+sub tiffsize {
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef, "Unable to determine size of TIFF data");
+
+    my $endian = 'n';           # Default to big-endian; I like it better
+    my $header = &$read_in($stream, 4);
+    $endian = 'v' if ($header =~ /II\x2a\x00/o); # little-endian
+
+    # Set up an association between data types and their corresponding
+    # pack/unpack specification.  Don't take any special pains to deal with
+    # signed numbers; treat them as unsigned because none of the image
+    # dimensions should ever be negative.  (I hope.)
+    my @packspec = ( undef,     # nothing (shouldn't happen)
+                     'C',       # BYTE (8-bit unsigned integer)
+                     undef,     # ASCII
+                     $endian,   # SHORT (16-bit unsigned integer)
+                     uc($endian), # LONG (32-bit unsigned integer)
+                     undef,     # RATIONAL
+                     'c',       # SBYTE (8-bit signed integer)
+                     undef,     # UNDEFINED
+                     $endian,   # SSHORT (16-bit unsigned integer)
+                     uc($endian), # SLONG (32-bit unsigned integer)
+                     );
+
+    my $offset = &$read_in($stream, 4, 4); # Get offset to IFD
+    $offset = unpack(uc($endian), $offset); # Fix it so we can use it
+
+    my $ifd = &$read_in($stream, 2, $offset); # Get number of directory entries
+    my $num_dirent = unpack($endian, $ifd); # Make it useful
+    $offset += 2;
+    $num_dirent = $offset + ($num_dirent * 12); # Calc. maximum offset of IFD
+
+    # Do all the work
+    $ifd = '';
+    my $tag = 0;
+    my $type = 0;
+    while (!defined($x) || !defined($y)) {
+        $ifd = &$read_in($stream, 12, $offset); # Get first directory entry
+        last if (($ifd eq '') || ($offset > $num_dirent));
+        $offset += 12;
+        $tag = unpack($endian, $ifd); # ...and decode its tag
+        $type = unpack($endian, substr($ifd, 2, 2)); # ...and the data type
+        # Check the type for sanity.
+        next if (($type > @packspec+0) || (!defined($packspec[$type])));
+        if ($tag == 0x0100) {   # ImageWidth (x)
+            # Decode the value
+            $x = unpack($packspec[$type], substr($ifd, 8, 4));
+        } elsif ($tag == 0x0101) {      # ImageLength (y)
+            # Decode the value
+            $y = unpack($packspec[$type], substr($ifd, 8, 4));
+        }
+    }
+
+    # Decide if we were successful or not
+    if (defined($x) && defined($y)) {
+        $id = 'TIF';
+    } else {
+        $id = '';
+        $id = 'ImageWidth ' if (!defined($x));
+        if (!defined ($y)) {
+            $id .= 'and ' if ($id ne '');
+            $id .= 'ImageLength ';
+        }
+        $id .= 'tag(s) could not be found';
+    }
+
+    ($x, $y, $id);
+}
+
+# bmpsize: size a Windows-ish BitMaP image
+#
+# Adapted from code contributed by Aldo Calpini <a.calpini@romagiubileo.it>
+sub bmpsize
+{
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef, "Unable to determine size of BMP data");
+    my ($buffer);
+
+    $buffer = &$read_in($stream, 26);
+    ($x, $y) = unpack("x18VV", $buffer);
+    $id = 'BMP' if (defined $x and defined $y);
+
+    ($x, $y, $id);
+}
+
+# psdsize: determine the size of a PhotoShop save-file (*.PSD)
+sub psdsize
+{
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef, "Unable to determine size of PSD data");
+    my ($buffer);
+
+    $buffer = &$read_in($stream, 26);
+    ($y, $x) = unpack("x14NN", $buffer);
+    $id = 'PSD' if (defined $x and defined $y);
+
+    ($x, $y, $id);
+}
+
+# swfsize: determine size of ShockWave/Flash files. Adapted from code sent by
+# Dmitry Dorofeev <dima@yasp.com>
+sub swfsize
+{
+    my $image  = shift;
+    my $header = &$read_in($image, 33);
+
+    my $ver = _bin2int(unpack 'B8', substr($header, 3, 1));
+    my $bs = unpack 'B133', substr($header, 8, 17);
+    my $bits = _bin2int(substr($bs, 0, 5));
+    my $x = int(_bin2int(substr($bs, 5+$bits, $bits))/20);
+    my $y = int(_bin2int(substr($bs, 5+$bits*3, $bits))/20);
+
+    return ($x, $y, 'SWF');
+}
+
+# Suggested by Matt Mueller <mueller@wetafx.co.nz>, and based on a piece of
+# sample Perl code by a currently-unknown author. Credit will be placed here
+# once the name is determined.
+sub pcdsize
+{
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef, "Unable to determine size of PCD data");
+    my $buffer = &$read_in($stream, 0xf00);
+
+    # Second-tier sanity check
+    return ($x, $y, $id) unless (substr($buffer, 0x800, 3) eq 'PCD');
+
+    my $orient = ord(substr($buffer, 0x0e02, 1)) & 1; # Clear down to one bit
+    ($x, $y) = @{$Image::Size::PCD_MAP{lc $Image::Size::PCD_SCALE}}
+        [($orient ? (0, 1) : (1, 0))];
+
+    return ($x, $y, 'PCD');
+}
+
+# swfmxsize: determine size of compressed ShockWave/Flash MX files. Adapted
+# from code sent by Victor Kuriashkin <victor@yasp.com>
+sub swfmxsize
+{
+    require Compress::Zlib;
+
+    my ($image) = @_;
+    my $header = &$read_in($image, 1058);
+    my $ver = _bin2int(unpack 'B8', substr($header, 3, 1));
+
+    my ($d, $status) = Compress::Zlib::inflateInit();
+    $header = $d->inflate(substr($header, 8, 1024));
+
+    my $bs = unpack 'B133', substr($header, 0, 9);
+    my $bits = _bin2int(substr($bs, 0, 5));
+    my $x = int(_bin2int(substr($bs, 5+$bits, $bits))/20);
+    my $y = int(_bin2int(substr($bs, 5+$bits*3, $bits))/20);
+
+    return ($x, $y, 'CWS');
+}
Index: /gsdl/stable/perllib/cpan/MARC/Batch.pm
===================================================================
--- /gsdl/stable/perllib/cpan/MARC/Batch.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/MARC/Batch.pm	(revision 20131)
@@ -0,0 +1,155 @@
+package MARC::Batch;
+
+=head1 NAME
+
+MARC::Batch - Perl module for handling files of MARC::Record objects
+
+=cut
+
+use strict;
+use integer;
+eval 'use warnings' if $] >= 5.006;
+
+=head1 VERSION
+
+Version 1.10
+
+    $Id$
+
+=cut
+
+use vars '$VERSION'; $VERSION = '1.10';
+
+=head1 SYNOPSIS
+
+MARC::Batch hides all the file handling of files of C<MARC::Record>s.
+C<MARC::Record> still does the file I/O, but C<MARC::Batch> handles the
+multiple-file aspects.
+
+    use MARC::Batch;
+
+    my $batch = new MARC::Batch( 'USMARC', @files );
+    while ( my $marc = $batch->next ) {
+	print $marc->subfield(245,"a"), "\n";
+    }
+
+=head1 EXPORT
+
+None.  Everything is a class method.
+
+=head1 METHODS
+
+=head2 new( $type, [@files] )
+
+Create a C<MARC::Batch> object that will process C<@files>.
+
+C<$type> must be either "USMARC" or "MicroLIF".  If you want to specify 
+"MARC::File::USMARC" or "MARC::File::MicroLIF", that's OK, too.
+
+=cut
+
+sub new {
+    my $class = shift;
+    my $type = shift;
+
+    my $marcclass = ($type =~ /^MARC::File/) ? $type : "MARC::File::$type";
+
+    eval "require $marcclass";
+    die $@ if $@;
+
+    my @files = @_;
+
+    my $self = {
+	filelist =>	[@files],
+	filestack =>	[@files],
+	filename =>	undef,
+	marcclass =>	$marcclass,
+	file =>		undef,
+    };
+
+    bless $self, $class;
+
+    return $self;
+} # new()
+
+
+=head2 next()
+
+Read the next record from the files.  If the current file is at EOF, close
+it and open the next one.
+
+=cut
+
+sub next {
+    my $self = shift;
+
+    # If we have an open file, just use it and go.
+    if ( $self->{file} ) {
+	my $rec = $self->{file}->next();
+	return $rec if $rec;
+    }
+
+    $self->{file} = undef;
+
+    # Get the next file off the stack, if there is one
+    $self->{filename} = shift @{$self->{filestack}} or return undef;
+
+    # Instantiate a filename for it
+    my $marcclass = $self->{marcclass};
+    $self->{file} = $marcclass->in( $self->{filename} ) or return undef;
+
+    return $self->{file}->next();
+}
+
+=head2 filename()
+
+Returns the currently open filename
+
+=cut
+
+sub filename {
+    my $self = shift;
+
+    return $self->{filename};
+}
+
+=head2 warnings() 
+
+Returns any warnings that have accumulated while processing a particular 
+batch file. As a side effect the warning buffer will be cleared.
+
+=cut
+
+sub warnings {
+    my $self = shift;
+    my $file = $self->{file}; 
+    return(undef) if !$file;
+    return ($file->warnings());
+}
+
+
+1;
+
+__END__
+
+=head1 RELATED MODULES
+
+L<MARC::Record>, L<MARC::Lint>
+
+=head1 TODO
+
+None yet.  Send me your ideas and needs.
+
+=head1 LICENSE
+
+This code may be distributed under the same terms as Perl itself. 
+
+Please note that these modules are not products of or supported by the
+employers of the various contributors to the code.
+
+=head1 AUTHOR
+
+Andy Lester, E<lt>marc@petdance.comE<gt> or E<lt>alester@flr.follett.comE<gt>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/MARC/Field.pm
===================================================================
--- /gsdl/stable/perllib/cpan/MARC/Field.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/MARC/Field.pm	(revision 20131)
@@ -0,0 +1,487 @@
+package MARC::Field;
+
+use strict;
+use integer;
+eval 'use warnings' if $] >= 5.006;
+
+use constant SUBFIELD_INDICATOR => "\x1F";
+use constant END_OF_FIELD       => "\x1E";
+
+use vars qw( $ERROR );
+
+=head1 NAME
+
+MARC::Field - Perl extension for handling MARC fields
+
+=head1 VERSION
+
+Version 1.10
+
+    $Id$
+
+=cut
+
+use vars '$VERSION'; $VERSION = '1.10';
+
+=head1 SYNOPSIS
+
+  use MARC::Field;
+
+  my $field = 
+  	MARC::Field->new( 
+		245, '1', '0',
+			'a' => 'Raccoons and ripe corn / ',
+			'c' => 'Jim Arnosky.'
+		);
+  $field->add_subfields( "a", "1st ed." );
+
+=head1 DESCRIPTION
+
+Defines MARC fields for use in the MARC::Record module.  I suppose
+you could use them on their own, but that wouldn't be very interesting.
+
+=head1 EXPORT
+
+None by default.  Any errors are stored in C<$MARC::Field::ERROR>, which
+C<$MARC::Record> usually bubbles up to C<$MARC::Record::ERROR>.
+
+=head1 METHODS
+
+=head2 C<new(tag,indicator1,indicator2,code,data[,code,data...])>
+
+  my $record = 
+  	MARC::Field->new( 
+		245, '1', '0',
+			'a' => 'Raccoons and ripe corn / ',
+			'c' => 'Jim Arnosky.'
+		);
+
+=cut
+
+sub new($) {
+	my $class = shift;
+	$class = ref($class) || $class;
+
+	my $tagno = shift;
+	($tagno =~ /^\d\d\d$/)
+		or return _gripe( "Tag \"$tagno\" is not a valid tag number." );
+
+	my $self = bless {
+		_tag => $tagno,
+		_warnings => [],
+		}, $class;
+	
+	if ( $tagno < 10 ) { 
+		$self->{_data} = shift;
+	} else {
+		for my $indcode ( qw( _ind1 _ind2 ) ) {
+			my $indicator = shift;
+			if ( $indicator !~ /^[0-9 ]$/ ) {
+				$self->_warn( "Invalid indicator \"$indicator\" forced to blank" ) unless ($indicator eq "");
+				$indicator = " ";
+			}
+			$self->{$indcode} = $indicator;
+		} # for
+		
+		(@_ >= 2)
+			or return _gripe( "Field $tagno must have at least one subfield" );
+
+		# Normally, we go thru add_subfields(), but internally we can cheat
+		$self->{_subfields} = [@_];
+	}
+
+	return $self;
+} # new()
+
+=head2 C<clone()>
+
+Makes a copy of the field.  Note that this is not just the same as saying
+
+    my $newfield = $field;
+
+since that just makes a copy of the reference.  To get a new object, you must
+
+    my $newfield = $field->clone;
+
+=cut
+
+sub clone {
+    my $self = shift;
+
+    my $tagno = $self->tag;
+
+    my $clone = 
+	bless {
+	    _tag => $tagno,
+	    _warnings => [],
+	}, ref($self);
+
+    if ( $tagno < 10 ) {
+	$clone->{_data} = $self->{_data};
+    } else {
+	$clone->{_ind1} = $self->{_ind1};
+	$clone->{_ind2} = $self->{_ind2};
+	$clone->{_subfields} = [@{$self->{_subfields}}]; 
+    }
+
+    return $clone;
+}
+
+=head2 C<update()>
+
+Allows you to change the values of the field. You can update indicators
+and subfields like this:
+
+  $field->update( ind2 => '4', a => 'The ballad of Abe Lincoln');
+
+The amount of items modified will be returned to you as a result of the
+method call.
+
+If you want to update a field that has no indicators or subfields (000-009)
+just call update() with one argument, the string that you would like to 
+set the field to. 
+
+  $field = $record->field( '003' );
+  $field->update('IMchF');
+
+Note: when doing subfield updates be aware that C<update()> will only 
+update the first occurrence. If you need to do anything more complicated
+you need to create a new field and use C<replace_with()>. 
+
+=cut
+
+sub update {
+
+  my $self = shift;
+
+  ## tags 000 - 009 don't have indicators or subfields
+  if ( $self->tag() < 10 ) {
+    $self->{_data} = shift;
+    return(1);
+  }
+  
+  ## otherwise we need to update subfields and indicators
+  my @data = @{$self->{_subfields}}; 
+  my $changes = 0;
+
+  while ( @_ ) {
+
+    my $arg = shift;
+    my $val = shift;
+
+    ## indicator update
+    if ($arg =~ /^ind[12]$/) {
+      $self->{"_$arg"} = $val;
+      $changes++;
+    }
+    ## subfield update
+    else {
+      for (my $i=0; $i<@data; $i=$i+2) {
+	if ($data[$i] eq $arg) {
+	  $data[$i+1] = $val;
+	  $changes++;
+	  last;
+	}
+      }
+    }
+
+  }
+
+  ## synchronize our subfields 
+  $self->{_subfields} = \@data;
+  return($changes);
+
+}
+
+=head2 C<replace_with()> 
+
+Allows you to replace an existing field with a new one. You need to pass 
+C<replace()> a MARC::Field object to replace the existing field with. For 
+example:
+
+  $field = $record->field('245');
+  my $new_field = new MARC::Field('245','0','4','The ballad of Abe Lincoln.');
+  $field->replace_with($new_field);
+
+=cut 
+
+sub replace_with {
+
+  my ($self,$new) = @_;
+  ref($new) =~ /^MARC::Field$/ 
+    or return _gripe("Must pass a MARC::Field object");
+
+  %$self = %$new;
+    
+}
+
+
+=head2 C<tag()>
+
+Returns the three digit tag for the field.
+
+=cut
+
+sub tag {
+	my $self = shift;
+	return $self->{_tag};
+}
+
+=head2 C<indicator(indno)>
+
+Returns the specified indicator.  Returns C<undef> and sets 
+C<$MARC::Field::ERROR> if the I<indno> is not 1 or 2, or if 
+the tag doesn't have indicators.
+
+=cut
+
+sub indicator($) {
+	my $self = shift;
+	my $indno = shift;
+
+	($self->tag >= 10)
+		or return _gripe( "Fields below 010 do not have indicators" );
+
+	if ( $indno == 1 ) {
+		return $self->{_ind1};
+	} elsif ( $indno == 2 ) {
+		return $self->{_ind2};
+	} else {
+		return _gripe( "Indicator number must be 1 or 2" );
+	}
+}
+
+
+
+=head2 C<subfield(code)>
+
+Returns the text from the first subfield matching the subfield code.
+If no matching subfields are found, C<undef> is returned.
+
+If the tag is less than an 010, C<undef> is returned and
+C<$MARC::Field::ERROR> is set.
+
+=cut
+
+sub subfield {
+	my $self = shift;
+	my $code_wanted = shift;
+
+	($self->tag >= 10)
+		or return _gripe( "Fields below 010 do not have subfields" );
+
+	my @data = @{$self->{_subfields}};
+	while ( defined( my $code = shift @data ) ) {
+		return shift @data if ( $code eq $code_wanted );
+		shift @data;
+	}
+
+	return undef;
+}
+
+=head2 C<subfields()>
+
+Returns all the subfields in the field.  What's returned is a list of 
+lists, where the inner list is a subfield code and the subfield data. 
+
+For example, this might be the subfields from a 245 field:
+
+	[
+	  [ 'a', 'Perl in a nutshell :' ],
+	  [ 'b', 'A desktop quick reference.' ],
+	]
+
+=cut
+
+sub subfields {
+	my $self = shift;
+
+	($self->tag >= 10)
+		or return _gripe( "Fields below 010 do not have subfields" );
+
+	my @list;
+	my @data = @{$self->{_subfields}};
+	while ( defined( my $code = shift @data ) ) {
+		push( @list, [$code, shift @data] );
+	}
+	return @list;
+}
+
+sub _gripe(@) {
+	$ERROR = join( "", @_ );
+
+	warn $ERROR;
+
+	return undef;
+}
+
+=head2 C<data()>
+
+Returns the data part of the field, if the tag number is less than 10.
+
+=cut
+
+sub data($) {
+	my $self = shift;
+
+	($self->{_tag} < 10)
+		or return _gripe( "data() is only for tags less than 10" );
+		
+	my $data = shift;
+	$self->{_data} = $data if defined( $data );
+
+	return $self->{_data};
+}
+
+=head2 C<add_subfields(code,text[,code,text ...])>
+
+Adds subfields to the end of the subfield list.
+
+Returns the number of subfields added, or C<undef> if there was an error.
+
+=cut
+
+sub add_subfields(@) {
+	my $self = shift;
+
+	($self->{_tag} >= 10)
+		or return _gripe( "Subfields are only for tags >= 10" );
+
+	push( @{$self->{_subfields}}, @_ );
+	return @_/2;
+}
+
+=head2 C<as_string()>
+
+Returns a string of all subfields run together, without the tag number.
+
+=cut
+
+sub as_string() {
+	my $self = shift;
+
+	return $self->{_data} if $self->tag < 10;
+
+	my @subs;
+
+	my @subdata = @{$self->{_subfields}};
+	while ( @subdata ) {
+		my $code = shift @subdata;
+		my $text = shift @subdata;
+		push( @subs, $text );
+	} # for
+
+	return join( " ", @subs );
+}
+
+
+=head2 C<as_formatted()>
+
+Returns a pretty string for printing in a MARC dump.
+
+=cut
+
+sub as_formatted() {
+	my $self = shift;
+
+	my @lines;
+
+	if ( $self->tag < 10 ) {
+		push( @lines, sprintf( "%03d     %s", $self->{_tag}, $self->{_data} ) );
+	} else {
+		my $hanger = sprintf( "%03d %1.1s%1.1s", $self->{_tag}, $self->{_ind1}, $self->{_ind2} );
+
+		my @subdata = @{$self->{_subfields}};
+		while ( @subdata ) {
+			my $code = shift @subdata;
+			my $text = shift @subdata;
+			push( @lines, sprintf( "%-6.6s _%1.1s%s", $hanger, $code, $text ) );
+			$hanger = "";
+		} # for
+	}
+
+
+
+	return join( "\n", @lines );
+}
+
+
+=head2 C<as_usmarc()>
+
+Returns a string for putting into a USMARC file.  It's really only
+useful by C<MARC::Record::as_usmarc()>.
+
+=cut
+
+sub as_usmarc() {
+	my $self = shift;
+
+	# Tags < 010 are pretty easy
+	if ( $self->tag < 10 ) {
+		return $self->data . END_OF_FIELD;
+	} else {
+		my @subs;
+		my @subdata = @{$self->{_subfields}};
+		while ( @subdata ) {
+			push( @subs, join( "", SUBFIELD_INDICATOR, shift @subdata, shift @subdata ) );
+		} # while
+
+		return join( "", 
+			$self->indicator(1),
+			$self->indicator(2),
+			@subs,
+			END_OF_FIELD,
+			);
+	}
+}
+
+=head2 C<warnings()>
+
+Returns the warnings that were created when the record was read.
+These are things like "Invalid indicators converted to blanks".
+
+The warnings are items that you might be interested in, or might
+not.  It depends on how stringently you're checking data.  If
+you're doing some grunt data analysis, you probably don't care.
+
+=cut
+
+sub warnings() {
+	my $self = shift;
+
+	return @{$self->{_warnings}};
+}
+
+# NOTE: _warn is an object method
+sub _warn($) {
+	my $self = shift;
+
+	push( @{$self->{_warnings}}, join( "", @_ ) );
+}
+
+1;
+
+__END__
+
+=head1 SEE ALSO
+
+See the "SEE ALSO" section for L<MARC::Record>.
+
+=head1 TODO
+
+See the "TODO" section for L<MARC::Record>.
+
+=cut
+
+=head1 LICENSE
+
+This code may be distributed under the same terms as Perl itself. 
+
+Please note that these modules are not products of or supported by the
+employers of the various contributors to the code.
+
+=head1 AUTHOR
+
+Andy Lester, E<lt>marc@petdance.comE<gt> or E<lt>alester@flr.follett.comE<gt>
+
+=cut
Index: /gsdl/stable/perllib/cpan/MARC/File.pm
===================================================================
--- /gsdl/stable/perllib/cpan/MARC/File.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/MARC/File.pm	(revision 20131)
@@ -0,0 +1,202 @@
+package MARC::File;
+
+=head1 NAME
+
+MARC::File - Base class for files of MARC records
+
+=cut
+
+use strict;
+use integer;
+eval 'use warnings' if $] >= 5.006;
+
+use vars qw( $ERROR );
+
+=head1 VERSION
+
+Version 1.10
+
+    $Id$
+
+=cut
+
+use vars '$VERSION'; $VERSION = '1.10';
+
+=head1 SYNOPSIS
+
+    use MARC::File::USMARC;
+
+    my $file = MARC::File::USMARC->in( $filename );
+    
+    while ( my $marc = $file->next() ) {
+	# Do something
+    }
+    $file->close();
+    undef $file;
+
+=head1 EXPORT
+
+None.  
+
+=head1 METHODS
+
+=head2 in()
+
+Opens a file for input.
+
+=cut
+
+sub in {
+    my $class = shift;
+    my $filename = shift;
+
+    my $self = {
+	filename => $filename,
+	_warnings => [],
+    };
+
+    bless $self, $class;
+
+    my $fh = eval { local *FH; open( FH, $filename ) or die; *FH{IO}; };
+
+    if ( $@ ) {
+	undef $self;
+	$MARC::File::ERROR = "Couldn't open $filename: $@";
+    } else {
+	$self->{fh} = $fh;
+    }
+	
+
+    return $self;
+} # new()
+
+sub out {
+    die "Not yet written";
+}
+
+=head2 next()
+
+Reads the next record from the file handle passed in. 
+
+=cut
+
+sub next {
+    my $self = shift;
+    my $rec = $self->_next();
+    return $rec ? $self->decode($rec) : undef;
+}
+
+=head2 skip()
+
+Skips over the next record in the file.  Same as C<next()>,
+without the overhead of parsing a record you're going to throw away
+anyway.
+
+Returns 1 or undef.
+
+=cut
+
+sub skip {
+    my $self = shift;
+
+    my $rec = $self->_next();
+
+    return $rec ? 1 : undef;
+}
+
+=head2 warnings()
+
+Simlilar to MARC::Record and MARC::Batch, warnings() will return any 
+warnings that have accumulated while processing this file; and as a 
+side-effect will clear the warnings buffer.
+
+=cut 
+
+sub warnings {
+    my $self = shift;
+    my @warnings = @{ $self->{_warnings} };
+    $self->{_warnings} = [];
+    return(@warnings);
+}
+
+sub close {
+    my $self = shift;
+
+    close( $self->{fh} );
+    delete $self->{fh};
+    delete $self->{filename};
+
+    return;
+}
+
+sub _unimplemented() {
+    my $self = shift;
+    my $method = shift;
+
+    warn "Method $method must be overridden";
+}
+
+sub write   { $_[0]->_unimplemented("write"); }
+sub decode  { $_[0]->_unimplemented("decode"); }
+
+# NOTE: _warn must be called as an object method
+
+sub _warn {
+    my ($self,$warning) = @_;
+    push( @{ $self->{_warnings} }, $warning );
+    return(undef);
+}
+
+# NOTE: _gripe can be called as an object method, or not.  Your choice.
+sub _gripe(@) {
+    my @parms = @_;
+    if ( @parms ) {
+	my $self = shift @parms;
+
+	if ( ref($self) =~ /^MARC::File/ ) {
+	    push( @parms, " at byte ", tell($self->{fh}) ) if $self->{fh};
+	    push( @parms, " in file ", $self->{filename} ) if $self->{filename};
+	} else {
+	    unshift( @parms, $self );
+	}
+
+	$ERROR = join( "", @parms );
+	warn $ERROR;
+    }
+
+    return(undef);
+}
+
+1;
+
+__END__
+
+=head1 RELATED MODULES
+
+L<MARC::Record>
+
+=head1 TODO
+
+=over 4
+
+=item * C<out()> method
+
+We only handle files for input right now.
+
+=back
+
+=cut
+
+=head1 LICENSE
+
+This code may be distributed under the same terms as Perl itself. 
+
+Please note that these modules are not products of or supported by the
+employers of the various contributors to the code.
+
+=head1 AUTHOR
+
+Andy Lester, E<lt>marc@petdance.comE<gt> or E<lt>alester@flr.follett.comE<gt>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/MARC/File/MicroLIF.pm
===================================================================
--- /gsdl/stable/perllib/cpan/MARC/File/MicroLIF.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/MARC/File/MicroLIF.pm	(revision 20131)
@@ -0,0 +1,128 @@
+package MARC::File::MicroLIF;
+
+=head1 NAME
+
+MARC::File::MicroLIF - MicroLIF-specific file handling
+
+=cut
+
+use strict;
+use integer;
+eval 'use warnings' if $] >= 5.006;
+
+use vars qw( $ERROR );
+
+=head1 VERSION
+
+Version 1.10
+
+    $Id$
+
+=cut
+
+use vars '$VERSION'; $VERSION = '1.10';
+
+use MARC::File;
+use vars qw( @ISA ); @ISA = qw( MARC::File );
+
+use MARC::Record qw( LEADER_LEN );
+
+=head1 SYNOPSIS
+
+    use MARC::File::MicroLIF;
+
+    my $file = MARC::File::MicroLIF::in( $filename );
+    
+    while ( my $marc = $file->next() ) {
+	# Do something
+    }
+    $file->close();
+    undef $file;
+
+=head1 EXPORT
+
+None.  
+
+=head1 METHODS
+
+=cut
+
+sub _next {
+    my $self = shift;
+
+    my $fh = $self->{fh};
+
+    local $/ = "`\n";
+    
+    my $lifrec = <$fh>;
+
+    return $lifrec;
+}
+
+sub decode {
+    my $text = shift;
+    $text = shift if (ref($text)||$text) =~ /^MARC::File/; # Handle being called as a method
+
+    my $marc = MARC::Record->new();
+
+    my @lines = split( /\n/, $text );
+    for my $line ( @lines ) {
+	# Ignore the file header if the calling program hasn't already dealt with it
+	next if $line =~ /^HDR/;
+
+	($line =~ s/^(\d\d\d|LDR)//) or
+	return $marc->_gripe( "Invalid tag number: ", substr( $line, 0, 3 ) );
+	my $tagno = $1;
+
+	($line =~ s/\^$//) or $marc->_warn( "Tag $tagno is missing a trailing caret." );
+
+	if ( $tagno eq "LDR" ) {
+	    $marc->leader( substr( $line, 0, LEADER_LEN ) );
+	} elsif ( $tagno < 10 ) {
+	    $marc->add_fields( $tagno, $line );
+	} else {
+	    $line =~ s/^(.)(.)//;
+	    my ($ind1,$ind2) = ($1,$2);
+	    my @subfields;
+	    my @subfield_data_pairs = split( /_(?=[a-z0-9])/, $line );
+	    shift @subfield_data_pairs; # Leading _ makes an empty pair
+	    for my $pair ( @subfield_data_pairs ) {
+		my ($subfield,$data) = (substr( $pair, 0, 1 ), substr( $pair, 1 ));
+		push( @subfields, $subfield, $data );
+	    }
+	    $marc->add_fields( $tagno, $ind1, $ind2, @subfields );
+	}
+    } # for
+
+    return $marc;
+}
+
+1;
+
+__END__
+
+=head1 TODO
+
+=over 4
+
+=item * Squawks about the final field missing a caret
+
+=back
+
+=head1 RELATED MODULES
+
+L<MARC::File>
+
+=head1 LICENSE
+
+This code may be distributed under the same terms as Perl itself. 
+
+Please note that these modules are not products of or supported by the
+employers of the various contributors to the code.
+
+=head1 AUTHOR
+
+Andy Lester, E<lt>marc@petdance.comE<gt> or E<lt>alester@flr.follett.comE<gt>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/MARC/File/USMARC.pm
===================================================================
--- /gsdl/stable/perllib/cpan/MARC/File/USMARC.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/MARC/File/USMARC.pm	(revision 20131)
@@ -0,0 +1,287 @@
+package MARC::File::USMARC;
+
+=head1 NAME
+
+MARC::File::USMARC - USMARC-specific file handling
+
+=cut
+
+use strict;
+use integer;
+eval 'use bytes'    if $] >= 5.006;
+eval 'use warnings' if $] >= 5.006;
+
+use vars qw( $ERROR );
+
+=head1 VERSION
+
+Version 1.10
+
+    $Id$
+
+=cut
+
+use vars '$VERSION'; $VERSION = '1.10';
+
+use MARC::File;
+use vars qw( @ISA ); @ISA = qw( MARC::File );
+
+use MARC::Record qw( LEADER_LEN );
+use constant SUBFIELD_INDICATOR	    => "\x1F";
+use constant END_OF_FIELD	    => "\x1E";
+use constant END_OF_RECORD	    => "\x1D";
+use constant DIRECTORY_ENTRY_LEN    => 12;
+
+=head1 SYNOPSIS
+
+    use MARC::File::USMARC;
+
+    my $file = MARC::File::USMARC::in( $filename );
+    
+    while ( my $marc = $file->next() ) {
+	# Do something
+    }
+    $file->close();
+    undef $file;
+
+=head1 EXPORT
+
+None.  
+
+=head1 METHODS
+
+=for internal
+
+Internal function to get the next raw record out of a file.
+
+=cut
+
+sub _next {
+    my $self = shift;
+
+    my $fh = $self->{fh};
+
+    my $reclen;
+    return undef if eof($fh);
+
+    local $/ = END_OF_RECORD;
+    my $usmarc = <$fh>;
+
+    if ( length($usmarc) < 5 ) {
+	$self->_warn( "Couldn't find record length" );
+	return $self->_next();
+    }
+
+    $reclen = substr($usmarc,0,5);
+
+    if ( $reclen !~ /^\d{5}$/ or $reclen != length($usmarc) ) {
+	$self->_warn( "Invalid record length \"$reclen\"" );
+	return $self->_next();
+    }
+
+    return $usmarc;
+}
+
+=head2 decode()
+
+Constructor for handling data from a USMARC file.  This function takes care of all
+the tag directory parsing & mangling.
+
+Any warnings or coercions can be checked in the C<warnings()> function.
+
+=cut
+
+sub decode {
+    my $text = shift;
+    $text = shift if (ref($text)||$text) =~ /^MARC::File/;
+
+    my $marc = MARC::Record->new();
+
+    # Check for an all-numeric record length
+    ($text =~ /^(\d{5})/)
+	or return $marc->_warn( "Record length \"", substr( $text, 0, 5 ), "\" is not numeric" );
+
+    my $reclen = $1;
+    ($reclen == length($text))
+	or return $marc->_gripe( "Invalid record length: Leader says $reclen bytes, but it's actually ", length( $text ) );
+
+    $marc->leader( substr( $text, 0, LEADER_LEN ) );
+    my @fields = split( END_OF_FIELD, substr( $text, LEADER_LEN ) );
+    my $dir = shift @fields or return $marc->_warn( "No directory found" );
+
+    (length($dir) % 12 == 0)
+	or return $marc->_gripe( "Invalid directory length" );
+    my $nfields = length($dir)/12;
+
+    my $finalfield = pop @fields;
+    # Check for the record terminator, and ignore it
+    ($finalfield eq END_OF_RECORD)
+    	or $marc->_gripe( "Invalid record terminator: \"$finalfield\"" );
+
+    # Walk thru the directories, and shift off the fields while we're at it
+    # Shouldn't be any non-digits anywhere in any directory entry
+    my @directory = unpack( "A3 A4 A5" x $nfields, $dir );
+    my @bad = grep /\D/, @directory;
+    if ( @bad ) { 
+	return $marc->_gripe( "Non-numeric entries in the tag directory: ", join( ", ", map { "\"$_\"" } @bad ) );
+    }
+
+    my $databytesused = 0;
+    while ( @directory ) {
+	my $tagno = shift @directory;
+	my $len = shift @directory;
+	my $offset = shift @directory;
+	my $tagdata = shift @fields;
+	warn "Specs: ", join( "|", $tagno, $len, $offset, $tagdata ), "\n" if $MARC::Record::DEBUG;
+
+	# Check directory validity
+	($tagno =~ /^\d\d\d$/)
+	    or return $marc->_gripe( "Invalid field number in directory: \"$tagno\"" );
+
+	($len == length($tagdata) + 1)
+	    or $marc->_warn( "Invalid length in the directory for tag $tagno" );
+
+	($offset == $databytesused)
+	    or $marc->_warn( "Directory offsets are out of whack" );
+	$databytesused += $len;
+
+	if ( $tagno < 10 ) {
+	    $marc->add_fields( $tagno, $tagdata )
+		or return undef; # We're relying on add_fields() having set $MARC::Record::ERROR
+	} else {
+	    my @subfields = split( SUBFIELD_INDICATOR, $tagdata );
+	    my $indicators = shift @subfields
+		or return $marc->_gripe( "No subfields found." );
+	    my ($ind1,$ind2);
+	    if ( $indicators =~ /^([0-9 ])([0-9 ])$/ ) {
+		($ind1,$ind2) = ($1,$2);
+	    } else {
+		$marc->_warn( "Invalid indicators \"$indicators\" forced to blanks\n" );
+		($ind1,$ind2) = (" "," ");
+	    }
+
+	    # Split the subfield data into subfield name and data pairs
+	    my @subfield_data = map { (substr($_,0,1),substr($_,1)) } @subfields;
+	    $marc->add_fields( $tagno, $ind1, $ind2, @subfield_data )
+		or return undef;
+	}
+    } # while
+
+    # Once we're done, there shouldn't be any fields left over: They should all have shifted off.
+    (@fields == 0)
+    	or return $marc->_gripe( "I've got leftover fields that weren't in the directory" );
+
+    return $marc;
+}
+
+=head2 update_leader()
+
+If any changes get made to the MARC record, the first 5 bytes of the
+leader (the length) will be invalid.  This function updates the 
+leader with the correct length of the record as it would be if
+written out to a file.
+
+=cut
+
+sub update_leader() {
+	my $self = shift;
+
+	my (undef,undef,$reclen,$baseaddress) = $self->_build_tag_directory();
+
+	$self->_set_leader_lengths( $reclen, $baseaddress );
+}
+
+=head2 _build_tag_directory()
+
+Function for internal use only: Builds the tag directory that gets
+put in front of the data in a MARC record.
+
+Returns two array references, and two lengths: The tag directory, and the data fields themselves,
+the length of all data (including the Leader that we expect will be added),
+and the size of the Leader and tag directory.
+
+=cut
+
+sub _build_tag_directory {
+	my $marc = shift;
+	$marc = shift if (ref($marc)||$marc) =~ /^MARC::File/;
+	die "Wanted a MARC::Record but got a ", ref($marc) unless ref($marc) eq "MARC::Record";
+
+	my @fields;
+	my @directory;
+
+	my $dataend = 0;
+	for my $field ( $marc->fields() ) {
+		# Dump data into proper format
+		my $str = $field->as_usmarc;
+		push( @fields, $str );
+
+		# Create directory entry
+		my $len = length $str;
+		my $direntry = sprintf( "%03d%04d%05d", $field->tag, $len, $dataend );
+		push( @directory, $direntry );
+		$dataend += $len;
+	}
+
+	my $baseaddress = 
+		LEADER_LEN +    # better be 24
+		( @directory * DIRECTORY_ENTRY_LEN ) +
+				# all the directory entries
+		1;           	# end-of-field marker
+
+
+	my $total = 
+		$baseaddress +	# stuff before first field
+		$dataend + 	# Length of the fields
+		1;		# End-of-record marker
+
+
+
+	return (\@fields, \@directory, $total, $baseaddress);
+}
+
+=head2 encode()
+
+Returns a string of characters suitable for writing out to a USMARC file,
+including the leader, directory and all the fields.
+
+=cut
+
+sub encode() {
+    my $marc = shift;
+    $marc = shift if (ref($marc)||$marc) =~ /^MARC::File/;
+
+    my ($fields,$directory,$reclen,$baseaddress) = _build_tag_directory($marc);
+    $marc->set_leader_lengths( $reclen, $baseaddress );
+
+    # Glomp it all together
+    return join("",$marc->leader, @$directory, END_OF_FIELD, @$fields, END_OF_RECORD);
+}
+
+1;
+
+__END__
+
+=head1 RELATED MODULES
+
+L<MARC::Record>
+
+=head1 TODO
+
+Make some sort of autodispatch so that you don't have to explicitly
+specify the MARC::File::X subclass, sort of like how DBI knows to
+use DBD::Oracle or DBD::Mysql.
+
+=head1 LICENSE
+
+This code may be distributed under the same terms as Perl itself. 
+
+Please note that these modules are not products of or supported by the
+employers of the various contributors to the code.
+
+=head1 AUTHOR
+
+Andy Lester, E<lt>marc@petdance.comE<gt> or E<lt>alester@flr.follett.comE<gt>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/MARC/Lint.pm
===================================================================
--- /gsdl/stable/perllib/cpan/MARC/Lint.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/MARC/Lint.pm	(revision 20131)
@@ -0,0 +1,764 @@
+package MARC::Lint;
+
+use strict;
+use integer;
+eval 'use warnings' if $] >= 5.006;
+
+=head1 NAME
+
+MARC::Lint - Perl extension for checking validity of MARC records
+
+=head1 VERSION
+
+Version 1.10
+
+    $Id$
+
+=cut
+
+use vars '$VERSION'; $VERSION = '1.10';
+
+use MARC::Record;
+use MARC::Field;
+
+=head1 SYNOPSIS
+
+  use MARC::Record;
+  use MARC::Lint;
+
+  my $linter = new MARC::Lint;
+  my $filename = shift;
+
+  open( IN, "<", $filename ) or die "Couldn't open $filename: $!\n";
+  binmode( IN ); # for the Windows folks
+  while ( !eof(IN) ) {
+  	my $marc = MARC::Record::next_from_file( *IN );
+	die $MARC::Record::ERROR unless $marc;
+
+	$linter->check_record( $marc );
+
+
+	# Print the title tag
+	print $marc->subfield(245,"a"), "\n";
+
+	# Print the errors that were found
+	print join( "\n", $linter->warnings ), "\n";
+  } # while
+
+  close IN or die "Error closing $filename: $!\n";
+
+Given the following MARC record:
+
+	LDR 00000nam  22002538a 4500
+	100 14 _aWall, Larry.
+	110 1  _aO'Reilly & Associates.
+	245 90 _aProgramming Perl /
+               _aBig Book of Perl /
+               _cLarry Wall, Tom Christiansen & Jon Orwant.
+	250    _a3rd ed.
+	250    _a3rd ed.
+	260    _aCambridge, Mass. :
+	       _bO'Reilly,
+	       _r2000.
+	590 4  _aPersonally signed by Larry.
+	856 43 _uhttp://www.perl.com/
+
+the following errors are generated:
+
+	1XX: Only one 1XX tag is allowed, but I found 2 of them.
+	100: Indicator 2 must be blank
+	245: Indicator 1 must be 0 or 1
+	245: Subfield _a is not repeatable.
+	250: Field is not repeatable.
+	260: Subfield _r is not valid.
+	260: Must have a subfield _c.
+	590: Indicator 1 must be blank
+	856: Indicator 2 must be blank, 0, 1, 2 or 8
+
+=head1 DESCRIPTION
+
+Module for checking validity of MARC records.  99% of the users will want to do 
+something like is shown in the synopsis.  The other intrepid 1% will overload the
+C<MARC::Lint> module's methods and provide their own special field-level checking.
+
+What this means is that if you have certain requirements, such as making sure that
+all 952 tags have a certain call number in them, you can write a function that 
+checks for that, and still get all the benefits of the MARC::Lint framework.
+
+=head1 EXPORT
+
+None.  Everything is done through objects.
+
+=head1 METHODS
+
+=head2 C<new()>
+
+No parms needed.  The C<MARC::Lint> object is little more than a list of warnings 
+and a bunch of rules.
+
+=cut
+
+sub new() {
+	my $class = shift;
+	$class = ref($class) || $class;
+
+	my $self = {
+		_warnings => [],
+	};
+	bless $self, $class;
+
+	$self->_read_rules();
+
+	return $self;
+}
+
+=head2 C<warnings()>
+
+Returns a list of warnings found by C<check_record()> and its brethren.
+
+=cut
+
+sub warnings {
+	my $self = shift;
+
+	return wantarray ? @{$self->{_warnings}} : scalar @{$self->{_warnings}};
+}
+
+=head2 C<clear_warnings()>
+
+Clear the list of warnings for this linter object.  It's automatically called
+when you call C<check_record()>.
+
+=cut
+
+sub clear_warnings {
+	my $self = shift;
+
+	$self->{_warnings} = [];
+}
+
+=head2 C<warn(str[,str...])>
+
+Create a warning message, built from strings passed, like a C<print> statement.
+
+Typically, you'll leave this to C<check_record()>, but industrious programmers
+may want to do their own checking as well.
+
+=cut
+
+sub warn {
+	my $self = shift;
+
+	push( @{$self->{_warnings}}, join( "", @_ ) );
+
+	return undef;
+}
+
+=head2 C<check_record(marc)>
+
+Does all sorts of lint-like checks on the MARC record I<marc>, both on the record as a whole,
+and on the individual fields & subfields.
+
+=cut
+
+sub check_record {
+	my $self = shift;
+	my $marc = shift;
+
+	$self->clear_warnings();
+
+	(ref($marc) eq "MARC::Record")
+		or return $self->warn( "Must pass a MARC::Record object to check_record" );
+
+	if ( (my @_1xx = $marc->field( "1XX" )) > 1 ) {
+		$self->warn( "1XX: Only one 1XX tag is allowed, but I found ", scalar @_1xx, " of them." );
+	}
+
+	if ( not $marc->field( 245 ) ) {
+		$self->warn( "245: No 245 tag." );
+	}
+
+
+	my %field_seen;
+	my $rules = $self->{_rules};
+	for my $field ( $marc->fields ) {
+		my $tagno = $field->tag;
+		my $tagrules = $rules->{$tagno} or next;
+
+		if ( $tagrules->{NR} && $field_seen{$tagno} ) { 
+			$self->warn( "$tagno: Field is not repeatable." );
+		}
+
+		if ( $tagno >= 10 ) {
+			for my $ind ( 1..2 ) {
+				my $indvalue = $field->indicator($ind);
+				if ( not ($indvalue =~ $tagrules->{"ind$ind" . "_regex"}) ) {
+					$self->warn( 
+						"$tagno: Indicator $ind must be ", 
+						$tagrules->{"ind$ind" . "_desc"}, 
+						" but it's \"$indvalue\"" 
+					);
+				}
+			}
+			
+			my %sub_seen;
+			for my $subfield ( $field->subfields ) {
+				my ($code,$data) = @$subfield;
+
+				my $rule = $tagrules->{$code};
+				if ( not defined $rule ) {
+					$self->warn( "$tagno: Subfield _$code is not allowed." );
+				} elsif ( ($rule eq "NR") && $sub_seen{$code} ) {
+					$self->warn( "$tagno: Subfield _$code is not repeatable." );
+				}
+
+				if ( $data =~ /[\t\r\n]/ ) {
+					$self->warn( "$tagno: Subfield _$code has an invalid control character" );
+				}
+
+				++$sub_seen{$code};
+			}
+		}
+
+		# Check to see if a check_xxx() function exists, and call it on the field if it does
+		my $checker = "check_$tagno";
+		if ( $self->can( $checker ) ) {
+			$self->$checker( $field );
+		}
+
+		++$field_seen{$tagno};
+	} # for
+
+	return;
+}
+
+=head2 C<check_I<xxx>(field)>
+
+Various functions to check the different fields.  If the function doesn't exist, 
+then it doesn't get checked.
+
+=cut
+
+sub check_245 {
+	my $self = shift;
+	my $field = shift;
+
+	if ( not $field->subfield( "a" ) ) {
+		$self->warn( "245: Must have a subfield _a." );
+	}
+}
+
+sub check_260 {
+	my $self = shift;
+	my $field = shift;
+
+	if ( not $field->subfield( "c" ) ) {
+		$self->warn( "260: Must have a subfield _c." );
+	}
+}
+
+
+=head1 SEE ALSO
+
+Check the docs for L<MARC::Record>.  All software links are there.
+
+=head1 TODO
+
+=over 4
+
+=item * ISBN and ISSN checking
+
+We can check the 020 and 022 fields with the C<Business::ISBN> and 
+C<Business::ISSN> modules, respectively.
+
+=back
+
+=head1 LICENSE
+
+This code may be distributed under the same terms as Perl itself. 
+
+Please note that these modules are not products of or supported by the
+employers of the various contributors to the code.
+
+=head1 AUTHOR
+
+Andy Lester, E<lt>marc@petdance.comE<gt> or E<lt>alester@flr.follett.comE<gt>
+
+=cut
+
+# Used only to read the stuff from __DATA__
+sub _read_rules() {
+	my $self = shift;
+	
+	my $tell = tell(DATA);  # Stash the position so we can reset it for next time
+
+	local $/ = "";
+	while ( my $lines = <DATA> ) {
+		$lines =~ s/\s+$//;
+		my @keyvals = split( /\s+/, $lines );
+
+		my $tagno = shift @keyvals;
+		my $repeatable = shift @keyvals;
+		
+		my @tag_range = ($tagno);
+		if ( $tagno =~ /^(\d\d)X/ ) {
+			my $base = $1;
+			@tag_range = ( "${base}0" .. "${base}9" );
+		}
+
+		# Handle the ranges of tags.
+		for my $currtag ( @tag_range ) {
+			$self->_parse_tag_rules( $currtag, $repeatable, @keyvals );
+		} # for
+		# I guess I could just have multiple references to the same tag, but I'm not that worried about memory
+	} # while
+
+	seek( DATA, $tell, 0 );
+}
+
+sub _parse_tag_rules {
+	my $self = shift;
+	my $tagno = shift;
+	my $repeatable = shift;
+	my @keyvals = @_;
+
+	my $rules = ($self->{_rules}->{$tagno} ||= {});
+	$rules->{$repeatable} = $repeatable;
+
+	while ( @keyvals ) {
+		my $key = shift @keyvals;
+		my $val = shift @keyvals;
+		
+		$rules->{$key} = $val;
+
+		# Do magic for indicators
+		if ( $key =~ /^ind/ ) {
+			my $desc;
+			my $regex;
+			
+			if ( $val eq "blank" ) {
+				$desc = "blank";
+				$regex = qr/^ $/;
+			} else {
+				$desc = _nice_list($val);
+				$val =~ s/^b/ /;
+				$regex = qr/^[$val]$/;
+			}
+
+		$rules->{$key."_desc"} = $desc;
+		$rules->{$key."_regex"} = $regex;
+		} # if indicator
+	} # while
+}
+
+
+sub _nice_list($) {
+	my $str = shift;
+
+	if ( $str =~ s/(\d)-(\d)/$1 thru $2/ ) {
+		return $str;
+	}
+
+	my @digits = split( //, $str );
+	$digits[0] = "blank" if $digits[0] eq "b";
+	my $last = pop @digits;
+	return join( ", ", @digits ) . " or $last";
+}
+
+sub _ind_regex($) {
+	my $str = shift;
+
+	return qr/^ $/ if $str eq "blank";
+
+	return qr/^[$str]$/;
+}
+
+
+1;
+
+__DATA__
+010	NR
+ind1	blank
+ind2	blank
+a	NR
+z	NR
+
+016	R
+ind1	b7
+ind2	blank
+a	NR
+z	R
+2	NR
+
+020	R
+ind1	blank
+ind2	blank
+a	R
+c	R
+
+022	R
+ind1	blank
+ind2	blank
+a	NR
+
+040	NR
+ind1	blank
+ind2	blank
+a	NR
+c	NR
+d	R
+
+100	NR
+ind1	013
+ind2	blank
+a	NR
+q	NR
+b	R
+c	R
+d	NR
+e	R
+
+110	NR
+ind1	012
+ind2	blank
+a	NR
+b	R
+
+111	NR
+ind1	012
+ind2	blank
+a	NR
+n	R	
+d	NR
+c	NR
+e	R
+
+130	NR
+ind1	0-9
+ind2	blank
+a	NR
+n	R
+p	R
+h	NR
+l	NR
+k	R
+s	NR
+f	NR
+
+240	NR
+ind1	01
+ind2	0-9
+
+245	NR
+ind1	01
+ind2	0-9
+a	NR
+n	R
+p	R
+h	NR
+b	NR
+s	NR
+c	NR
+
+246	NR
+ind1	0123
+ind2	012345678
+a	NR
+h	NR
+b	NR
+n	R
+p	R
+i	NR
+f	NR
+
+250	NR
+ind1	blank
+ind2	blank
+a	NR
+b	NR
+
+260	NR
+ind1	blank
+ind2	blank
+a	R
+b	R
+c	R
+
+300	NR
+ind1	blank
+ind2	blank
+a	R
+b	NR
+c	R
+e	NR
+
+440	R
+ind1	blank
+ind2	0-9
+a	NR
+n	R
+p	R
+v	NR
+
+490	R
+ind1	01
+ind2	blank
+a	R
+v	R
+
+500	R
+ind1	blank
+ind2	blank
+a	NR
+
+504	R
+ind1	blank
+ind2	blank
+a	NR
+
+505	R
+ind1	0128
+ind2	b0
+a	NR
+g	R
+r	R
+t	R
+
+520	R
+ind1	b018
+ind2	blank
+a	R
+b	R
+
+521	R
+ind1	b012348
+ind2	blank
+a	R
+b	NR
+
+526	R
+ind1	08
+ind2	blank
+a	NR
+b	NR
+c	NR
+d	NR
+i	NR
+x	R
+z	R
+
+538	R
+ind1	blank
+ind2	blank
+a	NR
+
+546	R
+ind1	blank
+ind2	blank
+a	NR
+
+586	R
+ind1	b8
+ind2	blank
+a	NR
+
+59X	R
+ind1	blank
+ind2	blank
+a	NR
+
+600	R
+ind1	013
+ind2	012567
+a	NR
+q	NR
+b	R
+c	R
+d	NR
+t	NR
+v	R
+x	R
+y	R
+z	R
+2	NR
+
+610	R
+ind1	012
+ind2	012567
+a	NR
+b	R
+t	NR
+v	R
+x	R
+y	R
+z	R
+2	NR
+
+611	R
+ind1	012
+ind2	012567
+a	NR
+n	R
+d	NR
+c	NR
+v	R
+x	R
+y	R
+z	R
+2	NR
+
+630	R
+ind1	0-9
+ind2	012567
+a	NR
+n	R
+p	R
+l	NR
+k	R
+s	NR
+f	NR
+v	R
+x	R
+y	R
+z	R
+2	NR
+
+650	R
+ind1	blank
+ind2	012567
+a	NR
+v	R
+x	R
+y	R
+z	R
+2	NR
+
+651	R
+ind1	blank
+ind2	012567
+a	NR
+v	R
+x	R
+y	R
+z	R
+2	NR
+
+655	R
+ind1	blank
+ind2	7
+a	NR
+v	R
+x	R
+y	R
+z	R
+2	NR
+
+658	R
+ind1	blank
+ind2	blank
+a	NR
+b	R
+c	NR
+d	NR
+2	NR
+
+69X	R
+ind1	blank
+ind2	blank
+a	NR
+v	R
+x	R
+y	R
+z	R
+
+700	R
+ind1	013
+ind2	b2
+a	NR
+q	NR
+b	R
+c	R
+d	NR
+k	R
+t	NR
+e	R
+f	NR
+
+710	R
+ind1	012
+ind2	b2
+a	NR
+b	R
+e	R
+t	NR
+
+711	R
+ind1	012
+ind2	b2
+a	NR
+n	R
+d	NR
+c	NR
+t	NR
+e	R
+
+730	R
+ind1	0-9
+ind2	b2
+a	NR
+n	R
+p	R
+h	NR
+l	NR
+k	R
+s	NR
+f	NR
+
+740	R
+ind1	0-9
+ind2	b2
+a	NR
+h	NR
+n	R
+p	R
+
+
+800	R
+ind1	013
+ind2	blank
+a	NR
+q	NR
+b	NR
+c	R
+d	NR
+t	NR
+e	R
+v	NR
+
+852	R
+ind1	b01234568
+ind2	b012
+a	NR
+b	R
+h	NR
+i	R
+k	NR
+m	NR
+t	NR
+p	NR
+9	NR
+
+856	R
+ind1	b012347
+ind2	b0128
+a	R
+b	NR
+d	R
+f	R
+h	NR
+i	R
+u	R
+x	R
+z	R
+2	NR
+3	NR
Index: /gsdl/stable/perllib/cpan/MARC/Record.pm
===================================================================
--- /gsdl/stable/perllib/cpan/MARC/Record.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/MARC/Record.pm	(revision 20131)
@@ -0,0 +1,705 @@
+package MARC::Record;
+
+=head1 NAME
+
+MARC::Record - Perl extension for handling MARC records
+
+=cut
+
+use strict;
+use integer;
+eval 'use warnings' if $] >= 5.006;
+
+use vars qw( $ERROR );
+
+use MARC::Field;
+
+=head1 VERSION
+
+Version 1.10
+
+    $Id$
+
+=cut
+
+use vars '$VERSION'; $VERSION = '1.10';
+
+use Exporter;
+use vars qw( @ISA @EXPORTS @EXPORT_OK );
+@ISA = qw( Exporter );
+@EXPORTS = qw();
+@EXPORT_OK = qw( LEADER_LEN );
+
+use vars qw( $DEBUG ); $DEBUG = 0;
+
+use constant LEADER_LEN	=> 24;
+
+=head1 DESCRIPTION
+
+Module for handling MARC records as objects.  The file-handling stuff is
+in MARC::File::*.
+
+=head1 EXPORT
+
+None.  
+
+=head1 ERROR HANDLING
+
+Any errors generated are stored in C<$MARC::Record::ERROR>. 
+Warnings are kept with the record and accessible in the C<warnings()> method. 
+
+=head1 METHODS
+
+=head2 new()
+
+Base constructor for the class.  It just returns a completely empty record.
+To get real data, you'll need to populate it with fields, or use one of
+the MARC::File::* modules to read from a file.
+
+=cut
+
+sub new {
+    my $class = shift;
+    $class = ref($class) || $class; # Handle cloning
+    my $self = {
+	_leader => ' ' x 24,
+	_fields => [],
+	_warnings => [],
+    };
+    return bless $self, $class;
+} # new()
+
+
+
+
+=head2 fields()
+
+Returns a list of all the fields in the record. The list contains 
+a MARC::Field object for each field in the record.
+
+=cut
+
+sub fields() {
+    my $self = shift;
+    return @{$self->{_fields}};
+}
+
+=head2 field(tagspec(s))
+
+Returns a list of tags that match the field specifier, or in scalar
+context, just the first matching tag.
+
+The field specifier can be a simple number (i.e. "245"), or use the "X" 
+notation of wildcarding (i.e. subject tags are "6XX").
+
+=cut
+
+my %field_regex;
+
+sub field {
+    my $self = shift;
+    my @specs = @_;
+
+    my @list = ();
+    for my $tag ( @specs ) {
+	my $regex = $field_regex{ $tag };
+
+	# Compile & stash it if necessary
+	if ( not defined $regex ) {
+	    my $pattern = $tag;
+	    $pattern =~ s/X/\\d/g;
+	    $regex = qr/^$pattern$/;
+	    $field_regex{ $tag } = $regex;
+	} # not defined
+
+	for my $maybe ( $self->fields ) {
+	    if ( $maybe->tag =~ $regex ) {
+		return $maybe unless wantarray;
+
+		push( @list, $maybe );
+	    } # if
+	} # for $maybe
+    } # for $tag
+
+    return @list;
+}
+
+=head2 subfield(tag,subfield)
+
+Shortcut method for getting just a subfield for a tag.  These are equivalent:
+
+  my $title = $marc->field(245)->subfield("a");
+  my $title = $marc->subfield(245,"a");
+
+If either the field or subfield can't be found, C<undef> is returned.
+
+=cut
+
+sub subfield($$) {
+    my $self = shift;
+    my $tag = shift;
+    my $subfield = shift;
+
+    my $field = $self->field($tag) or return undef;
+    return $field->subfield($subfield);
+} # subfield()
+
+=head2 insert_grouped_field(C<$field>)
+
+Will insert the specified MARC::Field object into the record in 'grouped
+order' and return true (1) on success, and false (undef) on failure.
+For example, if a '650' field is inserted with insert_grouped_field()
+it will be inserted at the end of the 6XX group of tags. After some discussion
+on the perl4lib list it was descided that this is ordinarily what you will 
+want. If you would like to insert at a specific point in the record you can use 
+insert_fields_after() and insert_fields_before() methods which are described 
+below. 
+
+=cut 
+
+sub insert_grouped_field {
+    my ($self,$new) = @_;
+    _all_parms_are_fields($new) or return(_gripe('Argument must be MARC::Fieldobject'));
+
+    ## try to find the end of the field group and insert it there
+    my $limit = int($new->tag() / 100);
+    my $found = 0;
+    foreach my $field ($self->fields()) {
+	if ( int($field->tag() / 100) > $limit ) {
+	    $self->insert_field_before($field,$new);
+	    $found = 1;
+	    last;
+	}
+    }
+
+    ## if we couldn't find the end of the group, then we must not have 
+    ## any tags this high yet, so just append it
+    if (!$found) {
+	$self->append_fields($new); 
+    }
+
+    return(1);
+
+}
+
+=for internal
+
+=cut
+
+sub _all_parms_are_fields {
+    for ( @_ ) {
+	return 0 unless ref($_) eq 'MARC::Field';
+    }
+    return 1;
+}
+
+=head2 append_field(C<@fields>)
+
+Appends the field specified by C<$field> to the end of the record. 
+C<@fields> need to be MARC::Field objects.
+
+    my $field = MARC::Field->new('590','','','a' => 'My local note.');
+    $record->append_field($field);
+
+Returns the number of fields appended.
+
+=cut
+
+sub append_fields {
+    my $self = shift;
+
+    _all_parms_are_fields(@_) or return(_gripe('Arguments must be MARC::Field objects'));
+
+    push(@{ $self->{_fields} }, @_); 
+    return scalar @_;
+}
+
+=head2 insert_fields_before($before_field,@new_fields)
+
+Inserts the field specified by C<$new_field> before the field C<$before_field>.
+Returns the number of fields inserted, or undef on failures.
+Both C<$before_field> and all C<@new_fields> need to be MARC::Field objects.
+
+    my $before_field = $record->field('260');
+    my $new_field = MARC::Field->new('250','','','a' => '2nd ed.');
+    $record->insert_fields_before($before_field,$new_field);
+
+=cut
+
+sub insert_fields_before {
+    my $self = shift;
+
+    _all_parms_are_fields(@_) or return(_gripe('All arguments must be MARC::Field objects'));
+    my ($before,@new) = @_;
+
+    ## find position of $before
+    my $fields = $self->{_fields};
+    my $pos = 0;
+    foreach my $f (@$fields) {
+	last if ($f == $before);
+	$pos++;
+    }
+
+    ## insert before $before 
+    if ($pos >= @$fields) {
+	return(_gripe("Couldn't find field to insert before"));
+    }
+    splice(@$fields,$pos,0,@new);
+    return scalar @new;
+
+}
+
+=head2 insert_fields_after($after_field,@new_fields)
+
+Identical to L<insert_fields_before()>, but fields are added after C<$after_field>.
+
+=cut
+
+sub insert_fields_after {
+    my $self = shift;
+
+    _all_parms_are_fields(@_) or return(_gripe('All arguments must be MARC::Field objects'));
+    my ($after,@new) = @_;
+
+    ## find position of $after
+    my $fields = $self->{_fields};
+    my $pos = 0;
+    foreach my $f (@$fields) {
+	last if ($f == $after);
+	$pos++;
+    }
+
+    ## insert after $after
+    if ($pos+1 >= @$fields) { 
+	return(_gripe("Couldn't find field to insert after"));
+    }
+    splice(@$fields,$pos+1,0,@new);
+    return scalar @new;
+}
+
+=head2 delete_field(C<$field>)
+
+Deletes a field from the record.
+
+The field must have been retrieved from the record using the 
+C<field()> method.  For example, to delete a 526 tag if it exists:
+
+    my $tag526 = $marc->field( "526" );
+    if ( $tag526 ) {
+	$marc->delete_field( $tag526 );
+    }
+
+C<delete_field()> returns the number of fields that were deleted.
+This shouldn't be 0 unless you didn't get the tag properly.
+
+=cut
+
+sub delete_field {
+    my $self = shift;
+    my $deleter = shift;
+    my $list = $self->{_fields};
+
+    my $old_count = @$list;
+    @$list = grep { $_ != $deleter } @$list;
+    return $old_count - @$list;
+}
+
+=head2 as_usmarc()
+
+This is a wrapper around C<MARC::File::USMARC::encode()> for compatibility with
+older versions of MARC::Record.
+
+=cut
+
+sub as_usmarc() {
+    my $self = shift;
+
+    require MARC::File::USMARC;
+
+    return MARC::File::USMARC::encode( $self );
+}
+
+=head2 as_formatted()
+
+Returns a pretty string for printing in a MARC dump.
+
+=cut
+
+sub as_formatted() {
+    my $self = shift;
+	    
+    my @lines = ( "LDR " . ($self->{_leader} || "") );
+    for my $field ( @{$self->{_fields}} ) {
+	    push( @lines, $field->as_formatted() );
+    }
+
+    return join( "\n", @lines );
+} # as_formatted
+
+=head2 title()
+
+Returns the title from the 245 tag.
+Note that it is a string, not a MARC::Field record.
+
+=cut
+
+sub title() {
+    my $self = shift;
+
+    my $field = $self->field(245) or return "<no 245 tag found>";
+
+    return $field->as_string;
+}
+
+=head2 author()
+
+Returns the author from the 100, 110 or 111 tag.
+Note that it is a string, not a MARC::Field record.
+
+=cut
+
+sub author() {
+    my $self = shift;
+
+    for my $tag ( qw( 100 110 111 ) ) {
+	my $field = $self->field($tag);
+	return $field->as_string() if $field;
+    }
+
+    return "<No author tag found>";
+}
+
+=head2 leader([text])
+
+Returns the leader for the record.  Sets the leader if I<text> is defined.
+No error checking is done on the validity of the leader.
+
+=cut
+
+sub leader {
+    my $self = shift;
+    my $text = shift;
+
+    if ( defined $text ) {
+    	(length($text) eq 24)
+	    or $self->_warn( "Leader must be 24 bytes long" );
+	$self->{_leader} = $text;
+    } # set the leader
+
+    return $self->{_leader};
+} # leader()
+
+=head2 set_leader_lengths( $reclen, $baseaddr )
+
+Internal function for updating the leader's length and base address.
+
+=cut
+
+sub set_leader_lengths {
+    my $self = shift;
+    my $reclen = shift;
+    my $baseaddr = shift;
+    substr($self->{_leader},0,5)  = sprintf("%05d",$reclen);
+    substr($self->{_leader},12,5) = sprintf("%05d",$baseaddr);
+}
+
+=head2 clone( [field specs] )
+
+The C<clone()> method makes a copy of an existing MARC record and returns
+the new version.  Note that you cannot just say:
+
+    my $newmarc = $oldmarc;
+
+This just makes a copy of the reference, not a new object.  You must use
+the C<clone()> method like so:
+
+    my $newmarc = $oldmarc->clone;
+
+You can also specify field specs to filter down only a 
+certain subset of fields.  For instance, if you only wanted the
+title and ISBN tags from a record, you could do this:
+
+    my $small_marc = $marc->clone( 245, '020' );
+
+The order of the fields is preserved as it was in the original record.
+
+=cut
+
+sub clone {
+    my $self = shift;
+    my @keeper_tags = @_;
+
+    my $clone = $self->new();
+    $clone->{_leader} = $self->{_leader};
+
+    my $filtered = @keeper_tags ? [$self->field( @keeper_tags )] : undef;
+
+    for my $field ( $self->fields() ) {
+        if ( !$filtered || (grep {$field==$_} @$filtered ) ) {
+	    $clone->add_fields( $field->clone );
+        }
+    }
+
+    # XXX FIX THIS $clone->update_leader();
+
+    return $clone;
+}
+
+=head2 warnings()
+
+Returns the warnings that were created when the record was read.
+These are things like "Invalid indicators converted to blanks".
+
+The warnings are items that you might be interested in, or might
+not.  It depends on how stringently you're checking data.  If
+you're doing some grunt data analysis, you probably don't care.
+
+A side effect of calling warnings() is that the warning buffer will
+be cleared.
+
+=cut
+
+sub warnings() {
+    my $self = shift;
+    my @warnings = @{$self->{_warnings}};
+    $self->{_warnings} = []; 
+    return @warnings;
+}
+
+=head2 add_fields()
+
+C<add_fields()> is now deprecated, and users are encouraged to use C<append_field()>,
+C<insert_field_after()>, and C<insert_field_before()> since they do what you want 
+probably. It is still here though, for backwards compatability.
+
+C<add_fields()> adds MARC::Field objects to the end of the list.  Returns the 
+number of fields added, or C<undef> if there was an error.
+
+There are three ways of calling C<add_fields()> to add data to the record.
+
+=over 4
+
+=item 1 Create a MARC::Field object and add it
+
+  my $author = MARC::Field->new(
+	        100, "1", " ", a => "Arnosky, Jim."
+	        );
+  $marc->add_fields( $author );
+
+=item 2 Add the data fields directly, and let C<add_fields()> take care of the objectifying.
+
+  $marc->add_fields(
+        245, "1", "0",
+                a => "Raccoons and ripe corn /",
+                c => "Jim Arnosky.",
+        	);
+
+=item 3 Same as #2 above, but pass multiple fields of data in anonymous lists
+
+  $marc->add_fields(
+	[ 250, " ", " ", a => "1st ed." ],
+	[ 650, "1", " ", a => "Raccoons." ],
+	);
+
+=back
+
+=cut
+
+sub add_fields {
+    my $self = shift;
+
+    my $nfields = 0;
+    my $fields = $self->{_fields};
+
+    while ( my $parm = shift ) {
+	# User handed us a list of data (most common possibility)
+	if ( ref($parm) eq "" ) {
+	    my $field = MARC::Field->new( $parm, @_ )
+		    or return _gripe( $MARC::Field::ERROR );
+	    push( @$fields, $field );
+	    ++$nfields;
+	    last; # Bail out, we're done eating parms
+
+	# User handed us an object.
+	} elsif ( ref($parm) eq "MARC::Field" ) {
+	    push( @$fields, $parm );
+	    ++$nfields;
+
+	# User handed us an anonymous list of parms
+	} elsif ( ref($parm) eq "ARRAY" ) {
+	    my $field = MARC::Field->new(@$parm) 
+		or return _gripe( $MARC::Field::ERROR );
+	    push( @$fields, $field );
+	    ++$nfields;
+
+	} else {
+	    return _gripe( "Unknown parm of type", ref($parm), " passed to add_fields()" );
+	} # if
+
+    } # while
+
+    return $nfields;
+}
+
+=head2 new_from_usmarc( $marcblob )
+
+This is a wrapper around C<MARC::File::USMARC::decode()> for compatibility with
+older versions of MARC::Record.
+
+=cut
+
+sub new_from_usmarc {
+    my $blob = shift;
+    $blob = shift if (ref($blob) || ($blob eq "MARC::Record"));
+
+    require MARC::File::USMARC;
+
+    return MARC::File::USMARC::decode( $blob );
+}
+
+
+# NOTE: _warn is an object method
+sub _warn {
+    my $self = shift;
+
+    push( @{$self->{_warnings}}, join( "", @_ ) );
+}
+
+
+# NOTE: _gripe is NOT an object method
+sub _gripe {
+    $ERROR = join( "", @_ );
+
+    warn $ERROR;
+
+    return undef;
+}
+
+
+1;
+
+__END__
+
+=head1 DESIGN NOTES
+
+A brief discussion of why MARC::Record is done the way it is:
+
+=over 4
+
+=item * It's built for quick prototyping
+
+One of the areas Perl excels is in allowing the programmer to 
+create easy solutions quickly.  MARC::Record is designed along
+those same lines.  You want a program to dump all the 6XX
+tags in a file?  MARC::Record is your friend.
+
+=item * It's built for extensibility
+
+Currently, I'm using MARC::Record for analyzing bibliographic
+data, but who knows what might happen in the future?  MARC::Record
+needs to be just as adept at authority data, too.
+
+=item * It's designed around accessor methods
+
+I use method calls everywhere, and I expect calling programs to do
+the same, rather than accessing internal data directly.  If you
+access an object's hash fields on your own, future releases may
+break your code.
+
+=item * It's not built for speed
+
+One of the tradeoffs in using accessor methods is some overhead
+in the method calls.  Is this slow?  I don't know, I haven't measured.
+I would suggest that if you're a cycle junkie that you use
+Benchmark.pm to check to see where your bottlenecks are, and then
+decide if MARC::Record is for you.
+
+=back
+
+=head1 RELATED MODULES
+
+L<MARC::Record>, L<MARC::Lint>
+
+=head1 SEE ALSO
+
+=over 4
+
+=item * perl4lib (L<http://www.rice.edu/perl4lib/>)
+
+A mailing list devoted to the use of Perl in libraries.
+
+=item * Library Of Congress MARC pages (L<http://www.loc.gov/marc/>)
+
+The definitive source for all things MARC.
+
+
+=item * I<Understanding MARC Bibliographic> (L<http://lcweb.loc.gov/marc/umb/>)
+
+Online version of the free booklet.  An excellent overview of the MARC format.  Essential.
+
+
+=item * Tag Of The Month (L<http://www.tagofthemonth.com/>)
+
+Follett Software Company's
+(L<http://www.fsc.follett.com/>) monthly discussion of various MARC tags.
+
+=back
+
+=head1 TODO
+
+=over 4
+
+=item * Incorporate MARC.pm in the distribution.
+
+Combine MARC.pm and MARC::* into one distribution.
+
+=item * Podify MARC.pm
+
+=item * Allow regexes across the entire tag
+
+Imagine something like this:
+
+  my @sears_headings = $marc->tag_grep( /Sears/ );
+
+(from Mike O'Regan)
+
+=item * Insert a field in an arbitrary place in the record
+
+=item * Allow deleting a field
+
+  for my $field ( $record->field( "856" ) ) {
+	$record->delete_field( $field ) unless useful($field);
+	} # for
+
+(from Anne Highsmith hismith@tamu.edu)
+
+
+=item * Modifying an existing field
+
+=back
+
+=head1 IDEAS
+
+Ideas are things that have been considered, but nobody's actually asked for.
+
+=over 4
+
+=item * Create multiple output formats.
+
+These could be ASCII, XML, or MarcMaker.
+
+=back
+
+=head1 LICENSE
+
+This code may be distributed under the same terms as Perl itself. 
+
+Please note that these modules are not products of or supported by the
+employers of the various contributors to the code.
+
+=head1 AUTHOR
+
+Andy Lester, E<lt>marc@petdance.comE<gt> or E<lt>alester@flr.follett.comE<gt>
+
+=cut
+
Index: /gsdl/stable/perllib/cpan/MP3/Info.pm
===================================================================
--- /gsdl/stable/perllib/cpan/MP3/Info.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/MP3/Info.pm	(revision 20131)
@@ -0,0 +1,1563 @@
+package MP3::Info;
+use overload;
+use strict;
+use Carp;
+use Symbol;
+
+use vars qw(
+	@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION $REVISION
+	@mp3_genres %mp3_genres @winamp_genres %winamp_genres $try_harder
+	@t_bitrate @t_sampling_freq @frequency_tbl %v1_tag_fields
+	@v1_tag_names %v2_tag_names %v2_to_v1_names $AUTOLOAD
+	@mp3_info_fields
+);
+
+@ISA = 'Exporter';
+@EXPORT = qw(
+	set_mp3tag get_mp3tag get_mp3info remove_mp3tag
+	use_winamp_genres
+);
+@EXPORT_OK = qw(@mp3_genres %mp3_genres use_mp3_utf8);
+%EXPORT_TAGS = (
+	genres	=> [qw(@mp3_genres %mp3_genres)],
+	utf8	=> [qw(use_mp3_utf8)],
+	all	=> [@EXPORT, @EXPORT_OK]
+);
+
+# $Id$
+($REVISION) = ' $Revision$ ' =~ /\$Revision:\s+([^\s]+)/;
+$VERSION = '1.02';
+
+=pod
+
+=head1 NAME
+
+MP3::Info - Manipulate / fetch info from MP3 audio files
+
+=head1 SYNOPSIS
+
+	#!perl -w
+	use MP3::Info;
+	my $file = 'Pearls_Before_Swine.mp3';
+	set_mp3tag($file, 'Pearls Before Swine', q"77's",
+		'Sticks and Stones', '1990',
+		q"(c) 1990 77's LTD.", 'rock & roll');
+
+	my $tag = get_mp3tag($file) or die "No TAG info";
+	$tag->{GENRE} = 'rock';
+	set_mp3tag($file, $tag);
+
+	my $info = get_mp3info($file);
+	printf "$file length is %d:%d\n", $info->{MM}, $info->{SS};
+
+=cut
+
+{
+	my $c = -1;
+	# set all lower-case and regular-cased versions of genres as keys
+	# with index as value of each key
+	%mp3_genres = map {($_, ++$c, lc, $c)} @mp3_genres;
+
+	# do it again for winamp genres
+	$c = -1;
+	%winamp_genres = map {($_, ++$c, lc, $c)} @winamp_genres;
+}
+
+=pod
+
+	my $mp3 = new MP3::Info $file;
+	$mp3->title('Perls Before Swine');
+	printf "$file length is %s, title is %s\n",
+		$mp3->time, $mp3->title;
+
+
+=head1 DESCRIPTION
+
+=over 4
+
+=item $mp3 = MP3::Info-E<gt>new(FILE)
+
+OOP interface to the rest of the module.  The same keys
+available via get_mp3info and get_mp3tag are available
+via the returned object (using upper case or lower case;
+but note that all-caps "VERSION" will return the module
+version, not the MP3 version).
+
+Passing a value to one of the methods will set the value
+for that tag in the MP3 file, if applicable.
+
+=cut
+
+sub new {
+	my($pack, $file) = @_;
+
+	my $info = get_mp3info($file) or return undef;
+	my $tags = get_mp3tag($file) || { map { ($_ => undef) } @v1_tag_names };
+	my %self = (
+		FILE		=> $file,
+		TRY_HARDER	=> 0
+	);
+
+	@self{@mp3_info_fields, @v1_tag_names, 'file'} = (
+		@{$info}{@mp3_info_fields},
+		@{$tags}{@v1_tag_names},
+		$file
+	);
+
+	return bless \%self, $pack;
+}
+
+sub can {
+	my $self = shift;
+	return $self->SUPER::can(@_) unless ref $self;
+	my $name = uc shift;
+	return sub { $self->$name(@_) } if exists $self->{$name};
+	return undef;
+}
+
+sub AUTOLOAD {
+	my($self) = @_;
+	(my $name = uc $AUTOLOAD) =~ s/^.*://;
+
+	if (exists $self->{$name}) {
+		my $sub = exists $v1_tag_fields{$name}
+			? sub {
+				if (defined $_[1]) {
+					$_[0]->{$name} = $_[1];
+					set_mp3tag($_[0]->{FILE}, $_[0]);
+				}
+				return $_[0]->{$name};
+			}
+			: sub {
+				return $_[0]->{$name}
+			};
+
+		no strict 'refs';
+		*{$AUTOLOAD} = $sub;
+		goto &$AUTOLOAD;
+
+	} else {
+		carp(sprintf "No method '$name' available in package %s.",
+			__PACKAGE__);
+	}
+}
+
+sub DESTROY {
+
+}
+
+
+=item use_mp3_utf8([STATUS])
+
+Tells MP3::Info to (or not) return TAG info in UTF-8.
+TRUE is 1, FALSE is 0.  Default is FALSE.
+
+Will only be able to it on if Unicode::String is available.  ID3v2
+tags will be converted to UTF-8 according to the encoding specified
+in each tag; ID3v1 tags will be assumed Latin-1 and converted
+to UTF-8.
+
+Function returns status (TRUE/FALSE).  If no argument is supplied,
+or an unaccepted argument is supplied, function merely returns status.
+
+This function is not exported by default, but may be exported
+with the C<:utf8> or C<:all> export tag.
+
+=cut
+
+my $unicode_module = eval { require Unicode::String };
+my $UNICODE = 0;
+
+sub use_mp3_utf8 {
+	my($val) = @_;
+	if ($val == 1) {
+		$UNICODE = 1 if $unicode_module;
+	} elsif ($val == 0) {
+		$UNICODE = 0;
+	}
+	return $UNICODE;
+}
+
+=pod
+
+=item use_winamp_genres()
+
+Puts WinAmp genres into C<@mp3_genres> and C<%mp3_genres>
+(adds 68 additional genres to the default list of 80).
+This is a separate function because these are non-standard
+genres, but they are included because they are widely used.
+
+You can import the data structures with one of:
+
+	use MP3::Info qw(:genres);
+	use MP3::Info qw(:DEFAULT :genres);
+	use MP3::Info qw(:all);
+
+=cut
+
+sub use_winamp_genres {
+	%mp3_genres = %winamp_genres;
+	@mp3_genres = @winamp_genres;
+	return 1;
+}
+
+=pod
+
+=item remove_mp3tag (FILE [, VERSION, BUFFER])
+
+Can remove ID3v1 or ID3v2 tags.  VERSION should be C<1> for ID3v1,
+C<2> for ID3v2, and C<ALL> for both.
+
+For ID3v1, removes last 128 bytes from file if those last 128 bytes begin
+with the text 'TAG'.  File will be 128 bytes shorter.
+
+For ID3v2, removes ID3v2 tag.  Because an ID3v2 tag is at the
+beginning of the file, we rewrite the file after removing the tag data.
+The buffer for rewriting the file is 4MB.  BUFFER (in bytes) ca
+change the buffer size.
+
+Returns the number of bytes removed, or -1 if no tag removed,
+or undef if there is an error.
+
+=cut
+
+sub remove_mp3tag {
+	my($file, $version, $buf) = @_;
+	my($fh, $return);
+
+	$buf ||= 4096*1024;  # the bigger the faster
+	$version ||= 1;
+
+	if (not (defined $file && $file ne '')) {
+		$@ = "No file specified";
+		return undef;
+	}
+
+	if (not -s $file) {
+		$@ = "File is empty";
+		return undef;
+	}
+
+	if (ref $file) { # filehandle passed
+		$fh = $file;
+	} else {
+		$fh = gensym;
+		if (not open $fh, "+< $file\0") {
+			$@ = "Can't open $file: $!";
+			return undef;
+		}
+	}
+
+	binmode $fh;
+
+	if ($version eq 1 || $version eq 'ALL') {
+		seek $fh, -128, 2;
+		my $tell = tell $fh;
+		if (<$fh> =~ /^TAG/) {
+			truncate $fh, $tell or carp "Can't truncate '$file': $!";
+			$return += 128;
+		}
+	}
+
+	if ($version eq 2 || $version eq 'ALL') {
+		my $h = _get_v2head($fh);
+		if ($h) {
+			local $\;
+			seek $fh, 0, 2;
+			my $eof = tell $fh;
+			my $off = $h->{tag_size};
+
+			while ($off < $eof) {
+				seek $fh, $off, 0;
+				read $fh, my($bytes), $buf;
+				seek $fh, $off - $h->{tag_size}, 0;
+				print $fh $bytes;
+				$off += $buf;
+			}
+
+			truncate $fh, $eof - $h->{tag_size}
+				or carp "Can't truncate '$file': $!";
+			$return += $h->{tag_size};
+		}
+	}
+
+	_close($file, $fh);
+
+	return $return || -1;
+}
+
+
+=pod
+
+=item set_mp3tag (FILE, TITLE, ARTIST, ALBUM, YEAR, COMMENT, GENRE [, TRACKNUM])
+
+=item set_mp3tag (FILE, $HASHREF)
+
+Adds/changes tag information in an MP3 audio file.  Will clobber
+any existing information in file.
+
+Fields are TITLE, ARTIST, ALBUM, YEAR, COMMENT, GENRE.  All fields have
+a 30-byte limit, except for YEAR, which has a four-byte limit, and GENRE,
+which is one byte in the file.  The GENRE passed in the function is a
+case-insensitive text string representing a genre found in C<@mp3_genres>.
+
+Will accept either a list of values, or a hashref of the type
+returned by C<get_mp3tag>.
+
+If TRACKNUM is present (for ID3v1.1), then the COMMENT field can only be
+28 bytes.
+
+ID3v2 support may come eventually.  Note that if you set a tag on a file
+with ID3v2, the set tag will be for ID3v1[.1] only, and if you call
+C<get_mp3_tag> on the file, it will show you the (unchanged) ID3v2 tags,
+unless you specify ID3v1.
+
+=cut
+
+sub set_mp3tag {
+	my($file, $title, $artist, $album, $year, $comment, $genre, $tracknum) = @_;
+	my(%info, $oldfh, $ref, $fh);
+	local %v1_tag_fields = %v1_tag_fields;
+
+	# set each to '' if undef
+	for ($title, $artist, $album, $year, $comment, $tracknum, $genre,
+		(@info{@v1_tag_names}))
+		{$_ = defined() ? $_ : ''}
+
+	($ref) = (overload::StrVal($title) =~ /^(?:.*\=)?([^=]*)\((?:[^\(]*)\)$/)
+		if ref $title;
+	# populate data to hashref if hashref is not passed
+	if (!$ref) {
+		(@info{@v1_tag_names}) =
+			($title, $artist, $album, $year, $comment, $tracknum, $genre);
+
+	# put data from hashref into hashref if hashref is passed
+	} elsif ($ref eq 'HASH') {
+		%info = %$title;
+
+	# return otherwise
+	} else {
+		carp(<<'EOT');
+Usage: set_mp3tag (FILE, TITLE, ARTIST, ALBUM, YEAR, COMMENT, GENRE [, TRACKNUM])
+       set_mp3tag (FILE, $HASHREF)
+EOT
+		return undef;
+	}
+
+	if (not (defined $file && $file ne '')) {
+		$@ = "No file specified";
+		return undef;
+	}
+
+	if (not -s $file) {
+		$@ = "File is empty";
+		return undef;
+	}
+
+	# comment field length 28 if ID3v1.1
+	$v1_tag_fields{COMMENT} = 28 if $info{TRACKNUM};
+
+
+	# only if -w is on
+	if ($^W) {
+		# warn if fields too long
+		foreach my $field (keys %v1_tag_fields) {
+			$info{$field} = '' unless defined $info{$field};
+			if (length($info{$field}) > $v1_tag_fields{$field}) {
+				carp "Data too long for field $field: truncated to " .
+					 "$v1_tag_fields{$field}";
+			}
+		}
+
+		if ($info{GENRE}) {
+			carp "Genre `$info{GENRE}' does not exist\n"
+				unless exists $mp3_genres{$info{GENRE}};
+		}
+	}
+
+	if ($info{TRACKNUM}) {
+		$info{TRACKNUM} =~ s/^(\d+)\/(\d+)$/$1/;
+		unless ($info{TRACKNUM} =~ /^\d+$/ &&
+			$info{TRACKNUM} > 0 && $info{TRACKNUM} < 256) {
+			carp "Tracknum `$info{TRACKNUM}' must be an integer " .
+				"from 1 and 255\n" if $^W;
+			$info{TRACKNUM} = '';
+		}
+	}
+
+	if (ref $file) { # filehandle passed
+		$fh = $file;
+	} else {
+		$fh = gensym;
+		if (not open $fh, "+< $file\0") {
+			$@ = "Can't open $file: $!";
+			return undef;
+		}
+	}
+
+	binmode $fh;
+	$oldfh = select $fh;
+	seek $fh, -128, 2;
+	# go to end of file if no tag, beginning of file if tag
+	seek $fh, (<$fh> =~ /^TAG/ ? -128 : 0), 2;
+
+	# get genre value
+	$info{GENRE} = $info{GENRE} && exists $mp3_genres{$info{GENRE}} ?
+		$mp3_genres{$info{GENRE}} : 255;  # some default genre
+
+	local $\;
+	# print TAG to file
+	if ($info{TRACKNUM}) {
+		print pack "a3a30a30a30a4a28xCC", 'TAG', @info{@v1_tag_names};
+	} else {
+		print pack "a3a30a30a30a4a30C", 'TAG', @info{@v1_tag_names[0..4, 6]};
+	}
+
+	select $oldfh;
+
+	_close($file, $fh);
+
+	return 1;
+}
+
+=pod
+
+=item get_mp3tag (FILE [, VERSION, RAW_V2])
+
+Returns hash reference containing tag information in MP3 file.  The keys
+returned are the same as those supplied for C<set_mp3tag>, except in the
+case of RAW_V2 being set.
+
+If VERSION is C<1>, the information is taken from the ID3v1 tag (if present).
+If VERSION is C<2>, the information is taken from the ID3v2 tag (if present).
+If VERSION is not supplied, or is false, the ID3v1 tag is read if present, and
+then, if present, the ID3v2 tag information will override any existing ID3v1
+tag info.
+
+If RAW_V2 is C<1>, the raw ID3v2 tag data is returned, without any manipulation
+of text encoding.  The key name is the same as the frame ID (ID to name mappings
+are in the global %v2_tag_names).
+
+If RAW_V2 is C<2>, the ID3v2 tag data is returned, manipulating for Unicode if
+necessary, etc.  It also takes multiple values for a given key (such as comments)
+and puts them in an arrayref.
+
+If the ID3v2 version is older than ID3v2.2.0 or newer than ID3v2.4.0, it will
+not be read.
+
+Strings returned will be in Latin-1, unless UTF-8 is specified (L<use_mp3_utf8>),
+(unless RAW_V2 is C<1>).
+
+Also returns a TAGVERSION key, containing the ID3 version used for the returned
+data (if TAGVERSION argument is C<0>, may contain two versions).
+
+=cut
+
+sub get_mp3tag {
+	my($file, $ver, $raw_v2) = @_;
+	my($tag, $v1, $v2, $v2h, %info, @array, $fh);
+	$raw_v2 ||= 0;
+	$ver = !$ver ? 0 : ($ver == 2 || $ver == 1) ? $ver : 0;
+
+	if (not (defined $file && $file ne '')) {
+		$@ = "No file specified";
+		return undef;
+	}
+
+	if (not -s $file) {
+		$@ = "File is empty";
+		return undef;
+	}
+
+	if (ref $file) { # filehandle passed
+		$fh = $file;
+	} else {
+		$fh = gensym;
+		if (not open $fh, "< $file\0") {
+			$@ = "Can't open $file: $!";
+			return undef;
+		}
+	}
+
+	binmode $fh;
+
+	if ($ver < 2) {
+		seek $fh, -128, 2;
+		while(defined(my $line = <$fh>)) { $tag .= $line }
+
+		if ($tag =~ /^TAG/) {
+			$v1 = 1;
+			if (substr($tag, -3, 2) =~ /\000[^\000]/) {
+				(undef, @info{@v1_tag_names}) =
+					(unpack('a3a30a30a30a4a28', $tag),
+					ord(substr($tag, -2, 1)),
+					$mp3_genres[ord(substr $tag, -1)]);
+				$info{TAGVERSION} = 'ID3v1.1';
+			} else {
+				(undef, @info{@v1_tag_names[0..4, 6]}) =
+					(unpack('a3a30a30a30a4a30', $tag),
+					$mp3_genres[ord(substr $tag, -1)]);
+				$info{TAGVERSION} = 'ID3v1';
+			}
+			if ($UNICODE) {
+				for my $key (keys %info) {
+					next unless $info{$key};
+					my $u = Unicode::String::latin1($info{$key});
+					$info{$key} = $u->utf8;
+				}
+			}
+		} elsif ($ver == 1) {
+			_close($file, $fh);
+			$@ = "No ID3v1 tag found";
+			return undef;
+		}
+	}
+
+	($v2, $v2h) = _get_v2tag($fh);
+
+	unless ($v1 || $v2) {
+		_close($file, $fh);
+		$@ = "No ID3 tag found";
+		return undef;
+	}
+
+	if (($ver == 0 || $ver == 2) && $v2) {
+		if ($raw_v2 == 1 && $ver == 2) {
+			%info = %$v2;
+			$info{TAGVERSION} = $v2h->{version};
+		} else {
+			my $hash = $raw_v2 == 2 ? { map { ($_, $_) } keys %v2_tag_names } : \%v2_to_v1_names;
+			for my $id (keys %$hash) {
+				if (exists $v2->{$id}) {
+					if ($id =~ /^TCON?$/ && $v2->{$id} =~ /^.?\((\d+)\)/) {
+						$info{$hash->{$id}} = $mp3_genres[$1];
+					} else {
+						my $data1 = $v2->{$id};
+
+						# this is tricky ... if this is an arrayref,
+						# we want to only return one, so we pick the
+						# first one.  but if it is a comment, we pick
+						# the first one where the first charcter after
+						# the language is NULL and not an additional
+						# sub-comment, because that is most likely to be
+						# the user-supplied comment
+						if (ref $data1 && !$raw_v2) {
+							if ($id =~ /^COMM?$/) {
+								my($newdata) = grep /^(....\000)/, @{$data1};
+								$data1 = $newdata || $data1->[0];
+							} else {
+								$data1 = $data1->[0];
+							}
+						}
+
+						$data1 = [ $data1 ] if ! ref $data1;
+
+						for my $data (@$data1) {
+							$data =~ s/^(.)//; # strip first char (text encoding)
+							my $encoding = $1;
+							my $desc;
+							if ($id =~ /^COM[M ]?$/) {
+								$data =~ s/^(?:...)//;		# strip language
+								$data =~ s/^(.*?)\000+//;	# strip up to first NULL(s),
+												# for sub-comment
+								$desc = $1;
+							}
+
+							if ($UNICODE) {
+								if ($encoding eq "\001" || $encoding eq "\002") {  # UTF-16, UTF-16BE
+									my $u = Unicode::String::utf16($data);
+									$data = $u->utf8;
+									$data =~ s/^\xEF\xBB\xBF//;	# strip BOM
+								} elsif ($encoding eq "\000") {
+									my $u = Unicode::String::latin1($data);
+									$data = $u->utf8;
+								}
+							}
+
+							if ($raw_v2 == 2 && $desc) {
+								$data = { $desc => $data };
+							}
+
+							if ($raw_v2 == 2 && exists $info{$hash->{$id}}) {
+								if (ref $info{$hash->{$id}} eq 'ARRAY') {
+									push @{$info{$hash->{$id}}}, $data;
+								} else {
+									$info{$hash->{$id}} = [ $info{$hash->{$id}}, $data ];
+								}
+							} else {
+								$info{$hash->{$id}} = $data;
+							}
+						}
+					}
+				}
+			}
+			if ($ver == 0 && $info{TAGVERSION}) {
+				$info{TAGVERSION} .= ' / ' . $v2h->{version};
+			} else {
+				$info{TAGVERSION} = $v2h->{version};
+			}
+		}
+	}
+
+	unless ($raw_v2 && $ver == 2) {
+		foreach my $key (keys %info) {
+			if (defined $info{$key}) {
+				$info{$key} =~ s/\000+.*//g;
+				$info{$key} =~ s/\s+$//;
+			}
+		}
+
+		for (@v1_tag_names) {
+			$info{$_} = '' unless defined $info{$_};
+		}
+	}
+
+	if (keys %info && exists $info{GENRE} && ! defined $info{GENRE}) {
+		$info{GENRE} = '';
+	}
+
+	_close($file, $fh);
+
+	return keys %info ? {%info} : undef;
+}
+
+sub _get_v2tag {
+	my($fh) = @_;
+	my($off, $myseek, $myseek_22, $myseek_23, $v2, $h, $hlen, $num);
+	$h = {};
+
+	$v2 = _get_v2head($fh) or return;
+	if ($v2->{major_version} < 2) {
+		carp "This is $v2->{version}; " .
+		     "ID3v2 versions older than ID3v2.2.0 not supported\n"
+		     if $^W;
+		return;
+	}
+
+	if ($v2->{major_version} == 2) {
+		$hlen = 6;
+		$num = 3;
+	} else {
+		$hlen = 10;
+		$num = 4;
+	}
+
+	$myseek = sub {
+		seek $fh, $off, 0;
+		read $fh, my($bytes), $hlen;
+		return unless $bytes =~ /^([A-Z0-9]{$num})/
+			|| ($num == 4 && $bytes =~ /^(COM )/);  # stupid iTunes
+		my($id, $size) = ($1, $hlen);
+		my @bytes = reverse unpack "C$num", substr($bytes, $num, $num);
+		for my $i (0 .. ($num - 1)) {
+			$size += $bytes[$i] * 256 ** $i;
+		}
+		return($id, $size);
+	};
+
+	$off = $v2->{ext_header_size} + 10;
+
+	while ($off < $v2->{tag_size}) {
+		my($id, $size) = &$myseek or last;
+		seek $fh, $off + $hlen, 0;
+		read $fh, my($bytes), $size - $hlen;
+		if (exists $h->{$id}) {
+			if (ref $h->{$id} eq 'ARRAY') {
+				push @{$h->{$id}}, $bytes;
+			} else {
+				$h->{$id} = [$h->{$id}, $bytes];
+			}
+		} else {
+			$h->{$id} = $bytes;
+		}
+		$off += $size;
+	}
+
+	return($h, $v2);
+}
+
+
+=pod
+
+=item get_mp3info (FILE)
+
+Returns hash reference containing file information for MP3 file.
+This data cannot be changed.  Returned data:
+
+	VERSION		MPEG audio version (1, 2, 2.5)
+	LAYER		MPEG layer description (1, 2, 3)
+	STEREO		boolean for audio is in stereo
+
+	VBR		boolean for variable bitrate
+	BITRATE		bitrate in kbps (average for VBR files)
+	FREQUENCY	frequency in kHz
+	SIZE		bytes in audio stream
+
+	SECS		total seconds
+	MM		minutes
+	SS		leftover seconds
+	MS		leftover milliseconds
+	TIME		time in MM:SS
+
+	COPYRIGHT	boolean for audio is copyrighted
+	PADDING		boolean for MP3 frames are padded
+	MODE		channel mode (0 = stereo, 1 = joint stereo,
+			2 = dual channel, 3 = single channel)
+	FRAMES		approximate number of frames
+	FRAME_LENGTH	approximate length of a frame
+	VBR_SCALE	VBR scale from VBR header
+
+On error, returns nothing and sets C<$@>.
+
+=cut
+
+sub get_mp3info {
+	my($file) = @_;
+	my($off, $myseek, $byte, $eof, $h, $tot, $fh);
+
+	if (not (defined $file && $file ne '')) {
+		$@ = "No file specified";
+		return undef;
+	}
+
+	if (not -s $file) {
+		$@ = "File is empty";
+		return undef;
+	}
+
+	if (ref $file) { # filehandle passed
+		$fh = $file;
+	} else {
+		$fh = gensym;
+		if (not open $fh, "< $file\0") {
+			$@ = "Can't open $file: $!";
+			return undef;
+		}
+	}
+
+	$off = 0;
+	$tot = 4096;
+
+	$myseek = sub {
+		seek $fh, $off, 0;
+		read $fh, $byte, 4;
+	};
+
+	binmode $fh;
+	&$myseek;
+
+	if ($off == 0) {
+		if (my $id3v2 = _get_v2head($fh)) {
+			$tot += $off += $id3v2->{tag_size};
+			&$myseek;
+		}
+	}
+
+	$h = _get_head($byte);
+	until (_is_mp3($h)) {
+		$off++;
+		&$myseek;
+		$h = _get_head($byte);
+		if ($off > $tot && !$try_harder) {
+			_close($file, $fh);
+			$@ = "Couldn't find MP3 header (perhaps set " .
+			     '$MP3::Info::try_harder and retry)';
+			return undef;
+		}
+	}
+
+	my $vbr = _get_vbr($fh, $h, \$off);
+
+	seek $fh, 0, 2;
+	$eof = tell $fh;
+	seek $fh, -128, 2;
+	$off += 128 if <$fh> =~ /^TAG/ ? 1 : 0;
+
+	_close($file, $fh);
+
+	$h->{size} = $eof - $off;
+
+	return _get_info($h, $vbr);
+}
+
+sub _get_info {
+	my($h, $vbr) = @_;
+	my $i;
+
+	$i->{VERSION}	= $h->{IDR} == 2 ? 2 : $h->{IDR} == 3 ? 1 :
+				$h->{IDR} == 0 ? 2.5 : 0;
+	$i->{LAYER}	= 4 - $h->{layer};
+	$i->{VBR}	= defined $vbr ? 1 : 0;
+
+	$i->{COPYRIGHT}	= $h->{copyright} ? 1 : 0;
+	$i->{PADDING}	= $h->{padding_bit} ? 1 : 0;
+	$i->{STEREO}	= $h->{mode} == 3 ? 0 : 1;
+	$i->{MODE}	= $h->{mode};
+
+	$i->{SIZE}	= $vbr && $vbr->{bytes} ? $vbr->{bytes} : $h->{size};
+
+	my $mfs		= $h->{fs} / ($h->{ID} ? 144000 : 72000);
+	$i->{FRAMES}	= int($vbr && $vbr->{frames}
+				? $vbr->{frames}
+				: $i->{SIZE} / $h->{bitrate} / $mfs
+			  );
+
+	if ($vbr) {
+		$i->{VBR_SCALE}	= $vbr->{scale} if $vbr->{scale};
+		$h->{bitrate}	= $i->{SIZE} / $i->{FRAMES} * $mfs;
+		if (not $h->{bitrate}) {
+			$@ = "Couldn't determine VBR bitrate";
+			return undef;
+		}
+	}
+
+	$h->{'length'}	= ($i->{SIZE} * 8) / $h->{bitrate} / 10;
+	$i->{SECS}	= $h->{'length'} / 100;
+	$i->{MM}	= int $i->{SECS} / 60;
+	$i->{SS}	= int $i->{SECS} % 60;
+	$i->{MS}	= (($i->{SECS} - ($i->{MM} * 60) - $i->{SS}) * 1000);
+#	$i->{LF}	= ($i->{MS} / 1000) * ($i->{FRAMES} / $i->{SECS});
+#	int($i->{MS} / 100 * 75);  # is this right?
+	$i->{TIME}	= sprintf "%.2d:%.2d", @{$i}{'MM', 'SS'};
+
+	$i->{BITRATE}		= int $h->{bitrate};
+	# should we just return if ! FRAMES?
+	$i->{FRAME_LENGTH}	= int($h->{size} / $i->{FRAMES}) if $i->{FRAMES};
+	$i->{FREQUENCY}		= $frequency_tbl[3 * $h->{IDR} + $h->{sampling_freq}];
+
+	return $i;
+}
+
+sub _get_head {
+	my($byte) = @_;
+	my($bytes, $h);
+
+	$bytes = _unpack_head($byte);
+	@$h{qw(IDR ID layer protection_bit
+		bitrate_index sampling_freq padding_bit private_bit
+		mode mode_extension copyright original
+		emphasis version_index bytes)} = (
+		($bytes>>19)&3, ($bytes>>19)&1, ($bytes>>17)&3, ($bytes>>16)&1,
+		($bytes>>12)&15, ($bytes>>10)&3, ($bytes>>9)&1, ($bytes>>8)&1,
+		($bytes>>6)&3, ($bytes>>4)&3, ($bytes>>3)&1, ($bytes>>2)&1,
+		$bytes&3, ($bytes>>19)&3, $bytes
+	);
+
+	$h->{bitrate} = $t_bitrate[$h->{ID}][3 - $h->{layer}][$h->{bitrate_index}];
+	$h->{fs} = $t_sampling_freq[$h->{IDR}][$h->{sampling_freq}];
+
+	return $h;
+}
+
+sub _is_mp3 {
+	my $h = $_[0] or return undef;
+	return ! (	# all below must be false
+		 $h->{bitrate_index} == 0
+			||
+		 $h->{version_index} == 1
+			||
+		($h->{bytes} & 0xFFE00000) != 0xFFE00000
+			||
+		!$h->{fs}
+			||
+		!$h->{bitrate}
+			||
+		 $h->{bitrate_index} == 15
+			||
+		!$h->{layer}
+			||
+		 $h->{sampling_freq} == 3
+			||
+		 $h->{emphasis} == 2
+			||
+		!$h->{bitrate_index}
+			||
+		($h->{bytes} & 0xFFFF0000) == 0xFFFE0000
+			||
+		($h->{ID} == 1 && $h->{layer} == 3 && $h->{protection_bit} == 1)
+			||
+		($h->{mode_extension} != 0 && $h->{mode} != 1)
+	);
+}
+
+sub _get_vbr {
+	my($fh, $h, $roff) = @_;
+	my($off, $bytes, @bytes, $myseek, %vbr);
+
+	$off = $$roff;
+	@_ = ();	# closure confused if we don't do this
+
+	$myseek = sub {
+		my $n = $_[0] || 4;
+		seek $fh, $off, 0;
+		read $fh, $bytes, $n;
+		$off += $n;
+	};
+
+	$off += 4;
+
+	if ($h->{ID}) {	# MPEG1
+		$off += $h->{mode} == 3 ? 17 : 32;
+	} else {	# MPEG2
+		$off += $h->{mode} == 3 ? 9 : 17;
+	}
+
+	&$myseek;
+	return unless $bytes eq 'Xing';
+
+	&$myseek;
+	$vbr{flags} = _unpack_head($bytes);
+
+	if ($vbr{flags} & 1) {
+		&$myseek;
+		$vbr{frames} = _unpack_head($bytes);
+	}
+
+	if ($vbr{flags} & 2) {
+		&$myseek;
+		$vbr{bytes} = _unpack_head($bytes);
+	}
+
+	if ($vbr{flags} & 4) {
+		$myseek->(100);
+# Not used right now ...
+#		$vbr{toc} = _unpack_head($bytes);
+	}
+
+	if ($vbr{flags} & 8) { # (quality ind., 0=best 100=worst)
+		&$myseek;
+		$vbr{scale} = _unpack_head($bytes);
+	} else {
+		$vbr{scale} = -1;
+	}
+
+	$$roff = $off;
+	return \%vbr;
+}
+
+sub _get_v2head {
+	my $fh = $_[0] or return;
+	my($h, $bytes, @bytes);
+
+	# check first three bytes for 'ID3'
+	seek $fh, 0, 0;
+	read $fh, $bytes, 3;
+	return unless $bytes eq 'ID3';
+
+	# get version
+	read $fh, $bytes, 2;
+	$h->{version} = sprintf "ID3v2.%d.%d",
+		@$h{qw[major_version minor_version]} =
+			unpack 'c2', $bytes;
+
+	# get flags
+	read $fh, $bytes, 1;
+	if ($h->{major_version} == 2) {
+		@$h{qw[unsync compression]} =
+			(unpack 'b8', $bytes)[7, 6];
+		$h->{ext_header} = 0;
+		$h->{experimental} = 0;
+	} else {
+		@$h{qw[unsync ext_header experimental]} =
+			(unpack 'b8', $bytes)[7, 6, 5];
+	}
+
+	# get ID3v2 tag length from bytes 7-10
+	$h->{tag_size} = 10;	# include ID3v2 header size
+	read $fh, $bytes, 4;
+	@bytes = reverse unpack 'C4', $bytes;
+	foreach my $i (0 .. 3) {
+		# whoaaaaaa nellllllyyyyyy!
+		$h->{tag_size} += $bytes[$i] * 128 ** $i;
+	}
+
+	# get extended header size
+	$h->{ext_header_size} = 0;
+	if ($h->{ext_header}) {
+		$h->{ext_header_size} += 10;
+		read $fh, $bytes, 4;
+		@bytes = reverse unpack 'C4', $bytes;
+		for my $i (0..3) {
+			$h->{ext_header_size} += $bytes[$i] * 256 ** $i;
+		}
+	}
+
+	return $h;
+}
+
+sub _unpack_head {
+	unpack('l', pack('L', unpack('N', $_[0])));
+}
+
+sub _close {
+	my($file, $fh) = @_;
+	unless (ref $file) { # filehandle not passed
+		close $fh or carp "Problem closing '$file': $!";
+	}
+}
+
+BEGIN {
+	@mp3_genres = (
+		'Blues',
+		'Classic Rock',
+		'Country',
+		'Dance',
+		'Disco',
+		'Funk',
+		'Grunge',
+		'Hip-Hop',
+		'Jazz',
+		'Metal',
+		'New Age',
+		'Oldies',
+		'Other',
+		'Pop',
+		'R&B',
+		'Rap',
+		'Reggae',
+		'Rock',
+		'Techno',
+		'Industrial',
+		'Alternative',
+		'Ska',
+		'Death Metal',
+		'Pranks',
+		'Soundtrack',
+		'Euro-Techno',
+		'Ambient',
+		'Trip-Hop',
+		'Vocal',
+		'Jazz+Funk',
+		'Fusion',
+		'Trance',
+		'Classical',
+		'Instrumental',
+		'Acid',
+		'House',
+		'Game',
+		'Sound Clip',
+		'Gospel',
+		'Noise',
+		'AlternRock',
+		'Bass',
+		'Soul',
+		'Punk',
+		'Space',
+		'Meditative',
+		'Instrumental Pop',
+		'Instrumental Rock',
+		'Ethnic',
+		'Gothic',
+		'Darkwave',
+		'Techno-Industrial',
+		'Electronic',
+		'Pop-Folk',
+		'Eurodance',
+		'Dream',
+		'Southern Rock',
+		'Comedy',
+		'Cult',
+		'Gangsta',
+		'Top 40',
+		'Christian Rap',
+		'Pop/Funk',
+		'Jungle',
+		'Native American',
+		'Cabaret',
+		'New Wave',
+		'Psychadelic',
+		'Rave',
+		'Showtunes',
+		'Trailer',
+		'Lo-Fi',
+		'Tribal',
+		'Acid Punk',
+		'Acid Jazz',
+		'Polka',
+		'Retro',
+		'Musical',
+		'Rock & Roll',
+		'Hard Rock',
+	);
+
+	@winamp_genres = (
+		@mp3_genres,
+		'Folk',
+		'Folk-Rock',
+		'National Folk',
+		'Swing',
+		'Fast Fusion',
+		'Bebob',
+		'Latin',
+		'Revival',
+		'Celtic',
+		'Bluegrass',
+		'Avantgarde',
+		'Gothic Rock',
+		'Progressive Rock',
+		'Psychedelic Rock',
+		'Symphonic Rock',
+		'Slow Rock',
+		'Big Band',
+		'Chorus',
+		'Easy Listening',
+		'Acoustic',
+		'Humour',
+		'Speech',
+		'Chanson',
+		'Opera',
+		'Chamber Music',
+		'Sonata',
+		'Symphony',
+		'Booty Bass',
+		'Primus',
+		'Porn Groove',
+		'Satire',
+		'Slow Jam',
+		'Club',
+		'Tango',
+		'Samba',
+		'Folklore',
+		'Ballad',
+		'Power Ballad',
+		'Rhythmic Soul',
+		'Freestyle',
+		'Duet',
+		'Punk Rock',
+		'Drum Solo',
+		'Acapella',
+		'Euro-House',
+		'Dance Hall',
+		'Goa',
+		'Drum & Bass',
+		'Club-House',
+		'Hardcore',
+		'Terror',
+		'Indie',
+		'BritPop',
+		'Negerpunk',
+		'Polsk Punk',
+		'Beat',
+		'Christian Gangsta Rap',
+		'Heavy Metal',
+		'Black Metal',
+		'Crossover',
+		'Contemporary Christian',
+		'Christian Rock',
+		'Merengue',
+		'Salsa',
+		'Thrash Metal',
+		'Anime',
+		'JPop',
+		'Synthpop',
+	);
+
+	@t_bitrate = ([
+		[0, 32, 48, 56,  64,  80,  96, 112, 128, 144, 160, 176, 192, 224, 256],
+		[0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160],
+		[0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160]
+	],[
+		[0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448],
+		[0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 384],
+		[0, 32, 40, 48,  56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320]
+	]);
+
+	@t_sampling_freq = (
+		[11025, 12000,  8000],
+		[undef, undef, undef],	# reserved
+		[22050, 24000, 16000],
+		[44100, 48000, 32000]
+	);
+
+	@frequency_tbl = map { $_ ? eval "${_}e-3" : 0 }
+		map { @$_ } @t_sampling_freq;
+
+	@mp3_info_fields = qw(
+		VERSION
+		LAYER
+		STEREO
+		VBR
+		BITRATE
+		FREQUENCY
+		SIZE
+		SECS
+		MM
+		SS
+		MS
+		TIME
+		COPYRIGHT
+		PADDING
+		MODE
+		FRAMES
+		FRAME_LENGTH
+		VBR_SCALE
+	);
+
+	%v1_tag_fields =
+		(TITLE => 30, ARTIST => 30, ALBUM => 30, COMMENT => 30, YEAR => 4);
+
+	@v1_tag_names = qw(TITLE ARTIST ALBUM YEAR COMMENT TRACKNUM GENRE);
+
+	%v2_to_v1_names = (
+		# v2.2 tags
+		'TT2' => 'TITLE',
+		'TP1' => 'ARTIST',
+		'TAL' => 'ALBUM',
+		'TYE' => 'YEAR',
+		'COM' => 'COMMENT',
+		'TRK' => 'TRACKNUM',
+		'TCO' => 'GENRE', # not clean mapping, but ...
+		# v2.3 tags
+		'TIT2' => 'TITLE',
+		'TPE1' => 'ARTIST',
+		'TALB' => 'ALBUM',
+		'TYER' => 'YEAR',
+		'COMM' => 'COMMENT',
+		'TRCK' => 'TRACKNUM',
+		'TCON' => 'GENRE',
+	);
+
+	%v2_tag_names = (
+		# v2.2 tags
+		'BUF' => 'Recommended buffer size',
+		'CNT' => 'Play counter',
+		'COM' => 'Comments',
+		'CRA' => 'Audio encryption',
+		'CRM' => 'Encrypted meta frame',
+		'ETC' => 'Event timing codes',
+		'EQU' => 'Equalization',
+		'GEO' => 'General encapsulated object',
+		'IPL' => 'Involved people list',
+		'LNK' => 'Linked information',
+		'MCI' => 'Music CD Identifier',
+		'MLL' => 'MPEG location lookup table',
+		'PIC' => 'Attached picture',
+		'POP' => 'Popularimeter',
+		'REV' => 'Reverb',
+		'RVA' => 'Relative volume adjustment',
+		'SLT' => 'Synchronized lyric/text',
+		'STC' => 'Synced tempo codes',
+		'TAL' => 'Album/Movie/Show title',
+		'TBP' => 'BPM (Beats Per Minute)',
+		'TCM' => 'Composer',
+		'TCO' => 'Content type',
+		'TCR' => 'Copyright message',
+		'TDA' => 'Date',
+		'TDY' => 'Playlist delay',
+		'TEN' => 'Encoded by',
+		'TFT' => 'File type',
+		'TIM' => 'Time',
+		'TKE' => 'Initial key',
+		'TLA' => 'Language(s)',
+		'TLE' => 'Length',
+		'TMT' => 'Media type',
+		'TOA' => 'Original artist(s)/performer(s)',
+		'TOF' => 'Original filename',
+		'TOL' => 'Original Lyricist(s)/text writer(s)',
+		'TOR' => 'Original release year',
+		'TOT' => 'Original album/Movie/Show title',
+		'TP1' => 'Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group',
+		'TP2' => 'Band/Orchestra/Accompaniment',
+		'TP3' => 'Conductor/Performer refinement',
+		'TP4' => 'Interpreted, remixed, or otherwise modified by',
+		'TPA' => 'Part of a set',
+		'TPB' => 'Publisher',
+		'TRC' => 'ISRC (International Standard Recording Code)',
+		'TRD' => 'Recording dates',
+		'TRK' => 'Track number/Position in set',
+		'TSI' => 'Size',
+		'TSS' => 'Software/hardware and settings used for encoding',
+		'TT1' => 'Content group description',
+		'TT2' => 'Title/Songname/Content description',
+		'TT3' => 'Subtitle/Description refinement',
+		'TXT' => 'Lyricist/text writer',
+		'TXX' => 'User defined text information frame',
+		'TYE' => 'Year',
+		'UFI' => 'Unique file identifier',
+		'ULT' => 'Unsychronized lyric/text transcription',
+		'WAF' => 'Official audio file webpage',
+		'WAR' => 'Official artist/performer webpage',
+		'WAS' => 'Official audio source webpage',
+		'WCM' => 'Commercial information',
+		'WCP' => 'Copyright/Legal information',
+		'WPB' => 'Publishers official webpage',
+		'WXX' => 'User defined URL link frame',
+
+		# v2.3 tags
+		'AENC' => 'Audio encryption',
+		'APIC' => 'Attached picture',
+		'COMM' => 'Comments',
+		'COMR' => 'Commercial frame',
+		'ENCR' => 'Encryption method registration',
+		'EQUA' => 'Equalization',
+		'ETCO' => 'Event timing codes',
+		'GEOB' => 'General encapsulated object',
+		'GRID' => 'Group identification registration',
+		'IPLS' => 'Involved people list',
+		'LINK' => 'Linked information',
+		'MCDI' => 'Music CD identifier',
+		'MLLT' => 'MPEG location lookup table',
+		'OWNE' => 'Ownership frame',
+		'PCNT' => 'Play counter',
+		'POPM' => 'Popularimeter',
+		'POSS' => 'Position synchronisation frame',
+		'PRIV' => 'Private frame',
+		'RBUF' => 'Recommended buffer size',
+		'RVAD' => 'Relative volume adjustment',
+		'RVRB' => 'Reverb',
+		'SYLT' => 'Synchronized lyric/text',
+		'SYTC' => 'Synchronized tempo codes',
+		'TALB' => 'Album/Movie/Show title',
+		'TBPM' => 'BPM (beats per minute)',
+		'TCOM' => 'Composer',
+		'TCON' => 'Content type',
+		'TCOP' => 'Copyright message',
+		'TDAT' => 'Date',
+		'TDLY' => 'Playlist delay',
+		'TENC' => 'Encoded by',
+		'TEXT' => 'Lyricist/Text writer',
+		'TFLT' => 'File type',
+		'TIME' => 'Time',
+		'TIT1' => 'Content group description',
+		'TIT2' => 'Title/songname/content description',
+		'TIT3' => 'Subtitle/Description refinement',
+		'TKEY' => 'Initial key',
+		'TLAN' => 'Language(s)',
+		'TLEN' => 'Length',
+		'TMED' => 'Media type',
+		'TOAL' => 'Original album/movie/show title',
+		'TOFN' => 'Original filename',
+		'TOLY' => 'Original lyricist(s)/text writer(s)',
+		'TOPE' => 'Original artist(s)/performer(s)',
+		'TORY' => 'Original release year',
+		'TOWN' => 'File owner/licensee',
+		'TPE1' => 'Lead performer(s)/Soloist(s)',
+		'TPE2' => 'Band/orchestra/accompaniment',
+		'TPE3' => 'Conductor/performer refinement',
+		'TPE4' => 'Interpreted, remixed, or otherwise modified by',
+		'TPOS' => 'Part of a set',
+		'TPUB' => 'Publisher',
+		'TRCK' => 'Track number/Position in set',
+		'TRDA' => 'Recording dates',
+		'TRSN' => 'Internet radio station name',
+		'TRSO' => 'Internet radio station owner',
+		'TSIZ' => 'Size',
+		'TSRC' => 'ISRC (international standard recording code)',
+		'TSSE' => 'Software/Hardware and settings used for encoding',
+		'TXXX' => 'User defined text information frame',
+		'TYER' => 'Year',
+		'UFID' => 'Unique file identifier',
+		'USER' => 'Terms of use',
+		'USLT' => 'Unsychronized lyric/text transcription',
+		'WCOM' => 'Commercial information',
+		'WCOP' => 'Copyright/Legal information',
+		'WOAF' => 'Official audio file webpage',
+		'WOAR' => 'Official artist/performer webpage',
+		'WOAS' => 'Official audio source webpage',
+		'WORS' => 'Official internet radio station homepage',
+		'WPAY' => 'Payment',
+		'WPUB' => 'Publishers official webpage',
+		'WXXX' => 'User defined URL link frame',
+
+		# v2.4 additional tags
+		# note that we don't restrict tags from 2.3 or 2.4,
+		'ASPI' => 'Audio seek point index',
+		'EQU2' => 'Equalisation (2)',
+		'RVA2' => 'Relative volume adjustment (2)',
+		'SEEK' => 'Seek frame',
+		'SIGN' => 'Signature frame',
+		'TDEN' => 'Encoding time',
+		'TDOR' => 'Original release time',
+		'TDRC' => 'Recording time',
+		'TDRL' => 'Release time',
+		'TDTG' => 'Tagging time',
+		'TIPL' => 'Involved people list',
+		'TMCL' => 'Musician credits list',
+		'TMOO' => 'Mood',
+		'TPRO' => 'Produced notice',
+		'TSOA' => 'Album sort order',
+		'TSOP' => 'Performer sort order',
+		'TSOT' => 'Title sort order',
+		'TSST' => 'Set subtitle',
+
+		# grrrrrrr
+		'COM ' => 'Broken iTunes comments',
+	);
+}
+
+1;
+
+__END__
+
+=pod
+
+=back
+
+=head1 TROUBLESHOOTING
+
+If you find a bug, please send me a patch (see the project page in L<"SEE ALSO">).
+If you cannot figure out why it does not work for you, please put the MP3 file in
+a place where I can get it (preferably via FTP, or HTTP, or .Mac iDisk) and send me
+mail regarding where I can get the file, with a detailed description of the problem.
+
+If I download the file, after debugging the problem I will not keep the MP3 file
+if it is not legal for me to have it.  Just let me know if it is legal for me to
+keep it or not.
+
+
+=head1 TODO
+
+=over 4
+
+=item ID3v2 Support
+
+Still need to do more for reading tags, such as using Compress::Zlib to decompress
+compressed tags.  But until I see this in use more, I won't bother.  If something
+does not work properly with reading, follow the instructions above for
+troubleshooting.
+
+ID3v2 I<writing> is coming soon.
+
+=item Get data from scalar
+
+Instead of passing a file spec or filehandle, pass the
+data itself.  Would take some work, converting the seeks, etc.
+
+=item Padding bit ?
+
+Do something with padding bit.
+
+=item Test suite
+
+Test suite could use a bit of an overhaul and update.  Patches very welcome.
+
+=over 4
+
+=item *
+
+Revamp getset.t.  Test all the various get_mp3tag args.
+
+=item *
+
+Test Unicode.
+
+=item *
+
+Test OOP API.
+
+=item *
+
+Test error handling, check more for missing files, bad MP3s, etc.
+
+=back
+
+=item Other VBR
+
+Right now, only Xing VBR is supported.
+
+=back
+
+
+=head1 THANKS
+
+Edward Allen E<lt>allenej@c51844-a.spokn1.wa.home.comE<gt>,
+Vittorio Bertola E<lt>v.bertola@vitaminic.comE<gt>,
+Michael Blakeley E<lt>mike@blakeley.comE<gt>,
+Per Bolmstedt E<lt>tomten@kol14.comE<gt>,
+Tony Bowden E<lt>tony@tmtm.comE<gt>,
+Tom Brown E<lt>thecap@usa.netE<gt>,
+Sergio Camarena E<lt>scamarena@users.sourceforge.netE<gt>,
+Chris Dawson E<lt>cdawson@webiphany.comE<gt>,
+Luke Drumm E<lt>lukedrumm@mypad.comE<gt>,
+Kyle Farrell E<lt>kyle@cantametrix.comE<gt>,
+Jeffrey Friedl E<lt>jfriedl@yahoo.comE<gt>,
+brian d foy E<lt>comdog@panix.comE<gt>,
+Ben Gertzfield E<lt>che@debian.orgE<gt>,
+Brian Goodwin E<lt>brian@fuddmain.comE<gt>,
+Todd Hanneken E<lt>thanneken@hds.harvard.eduE<gt>,
+Todd Harris E<lt>harris@cshl.orgE<gt>,
+Woodrow Hill E<lt>asim@mindspring.comE<gt>,
+Kee Hinckley E<lt>nazgul@somewhere.comE<gt>,
+Roman Hodek E<lt>Roman.Hodek@informatik.uni-erlangen.deE<gt>,
+Peter Kovacs E<lt>kovacsp@egr.uri.eduE<gt>,
+Johann Lindvall,
+Peter Marschall E<lt>peter.marschall@mayn.deE<gt>,
+Trond Michelsen E<lt>mike@crusaders.noE<gt>,
+Dave O'Neill E<lt>dave@nexus.carleton.caE<gt>,
+Christoph Oberauer E<lt>christoph.oberauer@sbg.ac.atE<gt>,
+Jake Palmer E<lt>jake.palmer@db.comE<gt>,
+Andrew Phillips E<lt>asp@wasteland.orgE<gt>,
+David Reuteler E<lt>reuteler@visi.comE<gt>,
+John Ruttenberg E<lt>rutt@chezrutt.comE<gt>,
+Matthew Sachs E<lt>matthewg@zevils.comE<gt>,
+E<lt>scfc_de@users.sf.netE<gt>,
+Hermann Schwaerzler E<lt>Hermann.Schwaerzler@uibk.ac.atE<gt>,
+Chris Sidi E<lt>sidi@angband.orgE<gt>,
+Roland Steinbach E<lt>roland@support-system.comE<gt>,
+Stuart E<lt>schneis@users.sourceforge.netE<gt>,
+Jeffery Sumler E<lt>jsumler@mediaone.netE<gt>,
+Predrag Supurovic E<lt>mpgtools@dv.co.yuE<gt>,
+Bogdan Surdu E<lt>tim@go.roE<gt>,
+E<lt>tim@tim-landscheidt.deE<gt>,
+Pass F. B. Travis E<lt>pftravis@bellsouth.netE<gt>,
+Tobias Wagener E<lt>tobias@wagener.nuE<gt>,
+Ronan Waide E<lt>waider@stepstone.ieE<gt>,
+Andy Waite E<lt>andy@mailroute.comE<gt>,
+Ken Williams E<lt>ken@forum.swarthmore.eduE<gt>,
+Meng Weng Wong E<lt>mengwong@pobox.comE<gt>.
+
+
+=head1 AUTHOR AND COPYRIGHT
+
+Chris Nandor E<lt>pudge@pobox.comE<gt>, http://pudge.net/
+
+Copyright (c) 1998-2003 Chris Nandor.  All rights reserved.  This program is
+free software; you can redistribute it and/or modify it under the terms
+of the Artistic License, distributed with Perl.
+
+
+=head1 SEE ALSO
+
+=over 4
+
+=item MP3::Info Project Page
+
+	http://projects.pudge.net/
+
+=item mp3tools
+
+	http://www.zevils.com/linux/mp3tools/
+
+=item mpgtools
+
+	http://www.dv.co.yu/mpgscript/mpgtools.htm
+	http://www.dv.co.yu/mpgscript/mpeghdr.htm
+
+=item mp3tool
+
+	http://www.dtek.chalmers.se/~d2linjo/mp3/mp3tool.html
+
+=item ID3v2
+
+	http://www.id3.org/
+
+=item Xing Variable Bitrate
+
+	http://www.xingtech.com/support/partner_developer/mp3/vbr_sdk/
+
+=item MP3Ext
+
+	http://rupert.informatik.uni-stuttgart.de/~mutschml/MP3ext/
+
+=item Xmms
+
+	http://www.xmms.org/
+
+
+=back
+
+=head1 VERSION
+
+v1.02, Sunday, March 2, 2003
+
+=cut
Index: /gsdl/stable/perllib/cpan/Mail/Sendmail.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Mail/Sendmail.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Mail/Sendmail.pm	(revision 20131)
@@ -0,0 +1,802 @@
+package Mail::Sendmail;
+# Mail::Sendmail by Milivoj Ivkovic <mi\x40alma.ch>
+# see embedded POD documentation after __END__
+# or http://alma.ch/perl/mail.html
+
+=head1 NAME
+
+Mail::Sendmail v. 0.79 - Simple platform independent mailer
+
+=cut
+
+$VERSION = '0.79';
+
+# *************** Configuration you may want to change *******************
+# You probably want to set your SMTP server here (unless you specify it in
+# every script), and leave the rest as is. See pod documentation for details
+
+%mailcfg = (
+    # List of SMTP servers:
+    'smtp'    => [ qw( localhost ) ],
+    #'smtp'    => [ qw( mail.mydomain.com ) ], # example
+
+    'from'    => '', # default sender e-mail, used when no From header in mail
+
+    'mime'    => 1, # use MIME encoding by default
+
+    'retries' => 1, # number of retries on smtp connect failure
+    'delay'   => 1, # delay in seconds between retries
+
+    'tz'      => '', # only to override automatic detection
+    'port'    => 25, # change it if you always use a non-standard port
+    'debug'   => 0 # prints stuff to STDERR
+);
+
+# *******************************************************************
+
+require Exporter;
+use strict;
+use vars qw(
+            $VERSION
+            @ISA
+            @EXPORT
+            @EXPORT_OK
+            %mailcfg
+            $address_rx
+            $debug
+            $log
+            $error
+            $retry_delay
+            $connect_retries
+           );
+
+use Socket;
+use Time::Local; # for automatic time zone detection
+use Sys::Hostname; # for use of hostname in HELO
+
+# use MIME::QuotedPrint if available and configured in %mailcfg
+eval("use MIME::QuotedPrint");
+$mailcfg{'mime'} &&= (!$@);
+
+@ISA        = qw(Exporter);
+@EXPORT     = qw(&sendmail);
+@EXPORT_OK  = qw(
+                 %mailcfg
+                 time_to_date
+                 $address_rx
+                 $debug
+                 $log
+                 $error
+                );
+
+# regex for e-mail addresses where full=$1, user=$2, domain=$3
+# see pod documentation about this regex
+
+my $word_rx = '[\x21\x23-\x27\x2A-\x2B\x2D\x2F\w\x3D\x3F]+';
+my $user_rx = $word_rx         # valid chars
+             .'(?:\.' . $word_rx . ')*' # possibly more words preceded by a dot
+             ;
+my $dom_rx = '\w[-\w]*(?:\.\w[-\w]*)*'; # less valid chars in domain names
+my $ip_rx = '\[\d{1,3}(?:\.\d{1,3}){3}\]';
+
+$address_rx = '((' . $user_rx . ')\@(' . $dom_rx . '|' . $ip_rx . '))';
+; # v. 0.61
+
+sub time_to_date {
+    # convert a time() value to a date-time string according to RFC 822
+
+    my $time = $_[0] || time(); # default to now if no argument
+
+    my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
+    my @wdays  = qw(Sun Mon Tue Wed Thu Fri Sat);
+
+    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
+        = localtime($time);
+
+    my $TZ = $mailcfg{'tz'};
+    if ( $TZ eq "" ) {
+        # offset in hours
+        my $offset  = sprintf "%.1f", (timegm(localtime) - time) / 3600;
+        my $minutes = sprintf "%02d", abs( $offset - int($offset) ) * 60;
+        $TZ  = sprintf("%+03d", int($offset)) . $minutes;
+    }
+    return join(" ",
+                    ($wdays[$wday] . ','),
+                     $mday,
+                     $months[$mon],
+                     $year+1900,
+                     sprintf("%02d:%02d:%02d", $hour, $min, $sec),
+                     $TZ
+               );
+} # end sub time_to_date
+
+sub sendmail {
+
+    $error = '';
+    $log = "Mail::Sendmail v. $VERSION - "    . scalar(localtime()) . "\n";
+
+    my $CRLF = "\015\012";
+    local $/ = $CRLF;
+    local $\ = ''; # to protect us from outside settings
+    local $_;
+
+    my (%mail, $k,
+        $smtp, $server, $port, $connected, $localhost,
+        $fromaddr, $recip, @recipients, $to, $header,
+       );
+
+    # -------- a few internal subs ----------
+    sub fail {
+        # things to do before returning a sendmail failure
+        print STDERR @_ if $^W;
+        $error .= join(" ", @_) . "\n";
+        close S;
+        return 0;
+    }
+
+    sub socket_write {
+        my $i;
+        for $i (0..$#_) {
+            # accept references, so we don't copy potentially big data
+            my $data = ref($_[$i]) ? $_[$i] : \$_[$i];
+            if ($mailcfg{'debug'} > 5) {
+                if (length($$data) < 500) {
+                    print ">", $$data;
+                }
+                else {
+                    print "> [...", length($$data), " bytes sent ...]\n";
+                }
+            }
+            print(S $$data) || return 0;
+        }
+        1;
+    }
+
+    sub socket_read {
+        my $response; # for multi-line server responses
+        do {
+            chomp($_ = <S>);
+            print "<$_\n" if $mailcfg{'debug'} > 5;
+            if (/^[45]/ or !$_) {
+                return; # return false
+            }
+            $response .= $_;
+         } while (/^[\d]+-/);
+         return $response;
+    }
+    # -------- end of internal subs ----------
+
+    # all config keys to lowercase, to prevent typo errors
+    foreach $k (keys %mailcfg) {
+        if ($k =~ /[A-Z]/) {
+            $mailcfg{lc($k)} = $mailcfg{$k};
+        }
+    }
+
+    # redo mail hash, arranging keys case etc...
+    while (@_) {
+        $k = shift @_;
+        if (!$k and $^W) {
+            warn "Received false mail hash key: \'$k\'. Did you forget to put it in quotes?\n";
+        }
+
+        # arrange keys case
+        $k = ucfirst lc($k);
+
+        $k =~ s/\s*:\s*$//o; # kill colon (and possible spaces) at end, we add it later.
+        # uppercase also after "-", so people don't complain that headers case is different
+        # than in Outlook.
+        $k =~ s/-(.)/"-" . uc($1)/ge;
+        $mail{$k} = shift @_;
+    }
+
+    $smtp = $mail{'Smtp'} || $mail{'Server'};
+    unshift @{$mailcfg{'smtp'}}, $smtp if ($smtp and $mailcfg{'smtp'}->[0] ne $smtp);
+
+    # delete non-header keys, so we don't send them later as mail headers
+    # I like this syntax, but it doesn't seem to work with AS port 5.003_07:
+    # delete @mail{'Smtp', 'Server'};
+    # so instead:
+    delete $mail{'Smtp'}; delete $mail{'Server'};
+
+    $mailcfg{'port'} = $mail{'Port'} || $mailcfg{'port'} || 25;
+    delete $mail{'Port'};
+
+    {    # don't warn for undefined values below
+        local $^W = 0;
+        $mail{'Message'} = join("", $mail{'Message'}, $mail{'Body'}, $mail{'Text'});
+    }
+
+    # delete @mail{'Body', 'Text'};
+    delete $mail{'Body'}; delete $mail{'Text'};
+
+    # Extract 'From:' e-mail address to use as envelope sender
+
+    $fromaddr = $mail{'Sender'} || $mail{'From'} || $mailcfg{'from'};
+    delete $mail{'Sender'};
+    unless ($fromaddr =~ /$address_rx/) {
+        return fail("Bad or missing From address: \'$fromaddr\'");
+    }
+    $fromaddr = $1;
+
+    # add Date header if needed
+    $mail{Date} ||= time_to_date() ;
+    $log .= "Date: $mail{Date}\n";
+
+    # cleanup message, and encode if needed
+    $mail{'Message'} =~ s/\r\n/\n/go;     # normalize line endings, step 1 of 2 (next step after MIME encoding)
+
+    $mail{'Mime-Version'} ||= '1.0';
+    $mail{'Content-Type'} ||= 'text/plain; charset="iso-8859-1"';
+
+    unless ( $mail{'Content-Transfer-Encoding'}
+          || $mail{'Content-Type'} =~ /multipart/io )
+    {
+        if ($mailcfg{'mime'}) {
+            $mail{'Content-Transfer-Encoding'} = 'quoted-printable';
+            $mail{'Message'} = encode_qp($mail{'Message'});
+        }
+        else {
+            $mail{'Content-Transfer-Encoding'} = '8bit';
+            if ($mail{'Message'} =~ /[\x80-\xFF]/o) {
+                $error .= "MIME::QuotedPrint not present!\nSending 8bit characters, hoping it will come across OK.\n";
+                warn "MIME::QuotedPrint not present!\n",
+                     "Sending 8bit characters without encoding, hoping it will come across OK.\n"
+                     if $^W;
+            }
+        }
+    }
+
+    $mail{'Message'} =~ s/^\./\.\./gom;     # handle . as first character
+    $mail{'Message'} =~ s/\n/$CRLF/go; # normalize line endings, step 2.
+
+    # Get recipients
+    {    # don't warn for undefined values below
+        local $^W = 0;
+        $recip = join(", ", $mail{To}, $mail{Cc}, $mail{Bcc});
+    }
+
+    delete $mail{'Bcc'};
+
+    @recipients = ();
+    while ($recip =~ /$address_rx/go) {
+        push @recipients, $1;
+    }
+    unless (@recipients) {
+        return fail("No recipient!")
+    }
+
+    # get local hostname for polite HELO
+    $localhost = hostname() || 'localhost';
+
+    foreach $server ( @{$mailcfg{'smtp'}} ) {
+        # open socket needs to be inside this foreach loop on Linux,
+        # otherwise all servers fail if 1st one fails !??! why?
+        unless ( socket S, AF_INET, SOCK_STREAM, scalar(getprotobyname 'tcp') ) {
+            return fail("socket failed ($!)")
+        }
+
+        print "- trying $server\n" if $mailcfg{'debug'} > 1;
+
+        $server =~ s/\s+//go; # remove spaces just in case of a typo
+        # extract port if server name like "mail.domain.com:2525"
+        $port = ($server =~ s/:(\d+)$//o) ? $1 : $mailcfg{'port'};
+        $smtp = $server; # save $server for use outside foreach loop
+
+        my $smtpaddr = inet_aton $server;
+        unless ($smtpaddr) {
+            $error .= "$server not found\n";
+            next; # next server
+        }
+
+        my $retried = 0; # reset retries for each server
+        while ( ( not $connected = connect S, pack_sockaddr_in($port, $smtpaddr) )
+            and ( $retried < $mailcfg{'retries'} )
+              ) {
+            $retried++;
+            $error .= "connect to $server failed ($!)\n";
+            print "- connect to $server failed ($!)\n" if $mailcfg{'debug'} > 1;
+            print "retrying in $mailcfg{'delay'} seconds...\n" if $mailcfg{'debug'} > 1;
+            sleep $mailcfg{'delay'};
+        }
+
+        if ( $connected ) {
+            print "- connected to $server\n" if $mailcfg{'debug'} > 3;
+            last;
+        }
+        else {
+            $error .= "connect to $server failed\n";
+            print "- connect to $server failed, next server...\n" if $mailcfg{'debug'} > 1;
+            next; # next server
+        }
+    }
+
+    unless ( $connected ) {
+        return fail("connect to $smtp failed ($!) no (more) retries!")
+    };
+
+    {
+        local $^W = 0; # don't warn on undefined variables
+        # Add info to log variable
+        $log .= "Server: $smtp Port: $port\n"
+              . "From: $fromaddr\n"
+              . "Subject: $mail{Subject}\n"
+              . "To: ";
+    }
+
+    my($oldfh) = select(S); $| = 1; select($oldfh);
+
+    socket_read()
+        || return fail("Connection error from $smtp on port $port ($_)");
+    socket_write("HELO $localhost$CRLF")
+        || return fail("send HELO error");
+    socket_read()
+        || return fail("HELO error ($_)");
+    socket_write("MAIL FROM: <$fromaddr>$CRLF")
+        || return fail("send MAIL FROM: error");
+    socket_read()
+        || return fail("MAIL FROM: error ($_)");
+
+    foreach $to (@recipients) {
+        socket_write("RCPT TO: <$to>$CRLF")
+            || return fail("send RCPT TO: error");
+        socket_read()
+            || return fail("RCPT TO: error ($_)");
+        $log .= "$to\n    ";
+    }
+
+    # start data part
+
+    socket_write("DATA$CRLF")
+        || return fail("send DATA error");
+    socket_read()
+        || return fail("DATA error ($_)");
+
+    # print headers
+    foreach $header (keys %mail) {
+        next if $header eq "Message";
+        $mail{$header} =~ s/\s+$//o; # kill possible trailing garbage
+        socket_write("$header: $mail{$header}$CRLF")
+            || return fail("send $header: error");
+    };
+
+    #- test diconnecting from network here, to see what happens
+    #- print STDERR "DISCONNECT NOW!\n";
+    #- sleep 4;
+    #- print STDERR "trying to continue, expecting an error... \n";
+
+    # send message body (passed as a reference, in case it's big)
+    socket_write($CRLF, \$mail{'Message'}, "$CRLF.$CRLF")
+           || return fail("send message error");
+    socket_read()
+        || return fail("message transmission error ($_)");
+    $log .= "\nResult: $_";
+
+    # finish
+    socket_write("QUIT$CRLF")
+           || return fail("send QUIT error");
+    socket_read();
+    close S;
+
+    return 1;
+} # end sub sendmail
+
+1;
+__END__
+
+=head1 SYNOPSIS
+
+  use Mail::Sendmail;
+
+  %mail = ( To      => 'you@there.com',
+            From    => 'me@here.com',
+            Message => "This is a very short message"
+           );
+
+  sendmail(%mail) or die $Mail::Sendmail::error;
+
+  print "OK. Log says:\n", $Mail::Sendmail::log;
+
+=head1 DESCRIPTION
+
+Simple platform independent e-mail from your perl script. Only requires
+Perl 5 and a network connection.
+
+Mail::Sendmail contains mainly &sendmail, which takes a hash with the
+message to send and sends it. It is intended to be very easy to setup and
+use. See also L<"FEATURES"> below.
+
+=head1 INSTALLATION
+
+=over 4
+
+=item Best
+
+C<perl -MCPAN -e "install Mail::Sendmail">
+
+=item Traditional
+
+    perl Makefile.PL
+    make
+    make test
+    make install
+
+=item Manual
+
+Copy Sendmail.pm to Mail/ in your Perl lib directory.
+
+    (eg. c:\Perl\site\lib\Mail\
+     or  /usr/lib/perl5/site_perl/Mail/
+     or whatever it is on your system.
+     They are listed when you type C< perl -V >)
+
+=item ActivePerl's PPM
+
+ppm install --location=http://alma.ch/perl/ppm Mail-Sendmail
+
+But this way you don't get a chance to have a look at other files (Changes,
+Todo, test.pl, ...).
+
+=back
+
+At the top of Sendmail.pm, set your default SMTP server(s), unless you specify
+it with each message, or want to use the default (localhost).
+
+Install MIME::QuotedPrint. This is not required but strongly recommended.
+
+=head1 FEATURES
+
+Automatic time zone detection, Date: header, MIME quoted-printable encoding
+(if MIME::QuotedPrint installed), all of which can be overridden.
+
+Bcc: and Cc: support.
+
+Allows real names in From:, To: and Cc: fields
+
+Doesn't send an X-Mailer: header (unless you do), and allows you to send any
+header(s) you want.
+
+Configurable retries and use of alternate servers if your mail server is
+down
+
+Good plain text error reporting
+
+=head1 LIMITATIONS
+
+Headers are not encoded, even if they have accented characters.
+
+No suport for the SMTP AUTH extension.
+
+Since the whole message is in memory, it's not suitable for
+sending very big attached files.
+
+The SMTP server has to be set manually in Sendmail.pm or in your script,
+unless you have a mail server on localhost.
+
+Doesn't work on OpenVMS, I was told. Cannot test this myself.
+
+=head1 CONFIGURATION
+
+=over 4
+
+=item Default SMTP server(s)
+
+This is probably all you want to configure. It is usually done through
+I<$mailcfg{smtp}>, which you can edit at the top of the Sendmail.pm file.
+This is a reference to a list of SMTP servers. You can also set it from
+your script:
+
+C<unshift @{$Mail::Sendmail::mailcfg{'smtp'}} , 'my.mail.server';>
+
+Alternatively, you can specify the server in the I<%mail> hash you send
+from your script, which will do the same thing:
+
+C<$mail{smtp} = 'my.mail.server';>
+
+A future version will (hopefully) try to set useful defaults for you
+during the Makefile.PL.
+
+=item Other configuration settings
+
+See I<%mailcfg> under L<"DETAILS"> below for other configuration options.
+
+=back
+
+=head1 DETAILS
+
+=head2 sendmail()
+
+sendmail is the only thing exported to your namespace by default
+
+C<sendmail(%mail) || print "Error sending mail: $Mail::Sendmail::error\n";>
+
+It takes a hash containing the full message, with keys for all headers,
+body, and optionally for another non-default SMTP server and/or port.
+
+It returns 1 on success or 0 on error, and rewrites
+C<$Mail::Sendmail::error> and C<$Mail::Sendmail::log>.
+
+Keys are NOT case-sensitive.
+
+The colon after headers is not necessary.
+
+The Body part key can be called 'Body', 'Message' or 'Text'.
+
+The SMTP server key can be called 'Smtp' or 'Server'. If the connection to
+this one fails, the other ones in C<$mailcfg{smtp}> will still be tried.
+
+The following headers are added unless you specify them yourself:
+
+    Mime-Version: 1.0
+    Content-Type: 'text/plain; charset="iso-8859-1"'
+
+    Content-Transfer-Encoding: quoted-printable
+    or (if MIME::QuotedPrint not installed)
+    Content-Transfer-Encoding: 8bit
+
+    Date: [string returned by time_to_date()]
+
+If you wish to use an envelope sender address different than the
+From: address, set C<$mail{Sender}> in your %mail hash.
+
+The following are not exported by default, but you can still access them
+with their full name, or request their export on the use line like in:
+C<use Mail::Sendmail qw(sendmail $address_rx time_to_date);>
+
+=head2 Mail::Sendmail::time_to_date()
+
+convert time ( as from C<time()> ) to an RFC 822 compliant string for the
+Date header. See also L<"%Mail::Sendmail::mailcfg">.
+
+=head2 $Mail::Sendmail::error
+
+When you don't run with the B<-w> flag, the module sends no errors to
+STDERR, but puts anything it has to complain about in here. You should
+probably always check if it says something.
+
+=head2 $Mail::Sendmail::log
+
+A summary that you could write to a log file after each send
+
+=head2 $Mail::Sendmail::address_rx
+
+A handy regex to recognize e-mail addresses.
+
+A correct regex for valid e-mail addresses was written by one of the judges
+in the obfuscated Perl contest... :-) It is quite big. This one is an
+attempt to a reasonable compromise, and should accept all real-world
+internet style addresses. The domain part is required and comments or
+characters that would need to be quoted are not supported.
+
+  Example:
+    $rx = $Mail::Sendmail::address_rx;
+    if (/$rx/) {
+      $address=$1;
+      $user=$2;
+      $domain=$3;
+    }
+
+=head2 %Mail::Sendmail::mailcfg
+
+This hash contains all configuration options. You normally edit it once (if
+ever) in Sendmail.pm and forget about it, but you could also access it from
+your scripts. For readability, I'll assume you have imported it
+(with something like C<use Mail::Sendmail qw(sendmail %mailcfg)>).
+
+The keys are not case-sensitive: they are all converted to lowercase before
+use. Writing C<$mailcfg{Port} = 2525;> is OK: the default $mailcfg{port}
+(25) will be deleted and replaced with your new value of 2525.
+
+=over 4
+
+=item $mailcfg{smtp}
+
+C<$mailcfg{smtp} = [qw(localhost my.other.mail.server)];>
+
+This is a reference to a list of smtp servers, so if your main server is
+down, the module tries the next one. If one of your servers uses a special
+port, add it to the server name with a colon in front, to override the
+default port (like in my.special.server:2525).
+
+Default: localhost.
+
+=item $mailcfg{from}
+
+C<$mailcfg{from} = 'Mailing script me@mydomain.com';>
+
+From address used if you don't supply one in your script. Should not be of
+type 'user@localhost' since that may not be valid on the recipient's
+host.
+
+Default: undefined.
+
+=item $mailcfg{mime}
+
+C<$mailcfg{mime} = 1;>
+
+Set this to 0 if you don't want any automatic MIME encoding. You normally
+don't need this, the module should 'Do the right thing' anyway.
+
+Default: 1;
+
+=item $mailcfg{retries}
+
+C<$mailcfg{retries} = 1;>
+
+How many times should the connection to the same SMTP server be retried in
+case of a failure.
+
+Default: 1;
+
+=item $mailcfg{delay}
+
+C<$mailcfg{delay} = 1;>
+
+Number of seconds to wait between retries. This delay also happens before
+trying the next server in the list, if the retries for the current server
+have been exhausted. For CGI scripts, you want few retries and short delays
+to return with a results page before the http connection times out. For
+unattended scripts, you may want to use many retries and long delays to
+have a good chance of your mail being sent even with temporary failures on
+your network.
+
+Default: 1 (second);
+
+=item $mailcfg{tz}
+
+C<$mailcfg{tz} = '+0800';>
+
+Normally, your time zone is set automatically, from the difference between
+C<time()> and C<gmtime()>. This allows you to override automatic detection
+in cases where your system is confused (such as some Win32 systems in zones
+which do not use daylight savings time: see Microsoft KB article Q148681)
+
+Default: undefined (automatic detection at run-time).
+
+=item $mailcfg{port}
+
+C<$mailcfg{port} = 25;>
+
+Port used when none is specified in the server name.
+
+Default: 25.
+
+=item $mailcfg{debug}
+
+C<$mailcfg{debug} = 0;>
+
+Prints stuff to STDERR. Current maximum is 6, which prints the whole SMTP
+session, except data exceeding 500 bytes.
+
+Default: 0;
+
+=back
+
+=head2 $Mail::Sendmail::VERSION
+
+The package version number (you can not import this one)
+
+=head2 Configuration variables from previous versions
+
+The following global variables were used in version 0.74 for configuration.
+As from version 0.78_1, they are not supported anymore.
+Use the I<%mailcfg> hash if you need to access the configuration
+from your scripts.
+
+=over 4
+
+=item $Mail::Sendmail::default_smtp_server
+
+=item $Mail::Sendmail::default_smtp_port
+
+=item $Mail::Sendmail::default_sender
+
+=item $Mail::Sendmail::TZ
+
+=item $Mail::Sendmail::connect_retries
+
+=item $Mail::Sendmail::retry_delay
+
+=item $Mail::Sendmail::use_MIME
+
+=back
+
+=head1 ANOTHER EXAMPLE
+
+  use Mail::Sendmail;
+
+  print "Testing Mail::Sendmail version $Mail::Sendmail::VERSION\n";
+  print "Default server: $Mail::Sendmail::mailcfg{smtp}->[0]\n";
+  print "Default sender: $Mail::Sendmail::mailcfg{from}\n";
+
+  %mail = (
+      #To      => 'No to field this time, only Bcc and Cc',
+      #From    => 'not needed, use default',
+      Bcc     => 'Someone <him@there.com>, Someone else her@there.com',
+      # only addresses are extracted from Bcc, real names disregarded
+      Cc      => 'Yet someone else <xz@whatever.com>',
+      # Cc will appear in the header. (Bcc will not)
+      Subject => 'Test message',
+      'X-Mailer' => "Mail::Sendmail version $Mail::Sendmail::VERSION",
+  );
+
+
+  $mail{Smtp} = 'special_server.for-this-message-only.domain.com';
+  $mail{'X-custom'} = 'My custom additionnal header';
+  $mail{'mESSaGE : '} = "The message key looks terrible, but works.";
+  # cheat on the date:
+  $mail{Date} = Mail::Sendmail::time_to_date( time() - 86400 );
+
+  if (sendmail %mail) { print "Mail sent OK.\n" }
+  else { print "Error sending mail: $Mail::Sendmail::error \n" }
+
+  print "\n\$Mail::Sendmail::log says:\n", $Mail::Sendmail::log;
+ 
+Also see http://alma.ch/perl/Mail-Sendmail-FAQ.html for examples
+of HTML mail and sending attachments. 
+
+=head1 CHANGES
+
+Main changes since version 0.78:
+
+Added "/" (\x2F) as a valid character in mailbox part.
+
+Removed old configuration variables which are not used anymore
+since version 0.74.
+
+Added support for different envelope sender (through C<$mail{Sender}>)
+
+Changed case of headers: first character after "-" also uppercased
+
+Support for multi-line server responses
+
+Localized $\ and $_
+
+Some internal rewrites and documentation updates
+
+Fixed old bug of dot as 76th character on line disappearing.
+
+Fixed very old bug where port number was not extracted from
+stuff like 'my.server:2525'.
+
+Fixed time_to_date bug with negative half-hour zones (only Newfoundland?)
+
+Added seconds to date string
+
+Now uses Sys::Hostname to get the hostname for HELO. (This may break the
+module on some very old Win32 Perls where Sys::Hostname was broken)
+
+Enable full session output for debugging
+
+See the F<Changes> file for the full history. If you don't have it
+because you installed through PPM, you can also find the latest
+one on F<http://alma.ch/perl/scripts/Sendmail/Changes>.
+
+=head1 AUTHOR
+
+Milivoj Ivkovic <mi\x40alma.ch> ("\x40" is "@" of course)
+
+=head1 NOTES
+
+MIME::QuotedPrint is used by default on every message if available. It
+allows reliable sending of accented characters, and also takes care of
+too long lines (which can happen in HTML mails). It is available in the
+MIME-Base64 package at http://www.perl.com/CPAN/modules/by-module/MIME/ or
+through PPM.
+
+Look at http://alma.ch/perl/Mail-Sendmail-FAQ.html for additional
+info (CGI, examples of sending attachments, HTML mail etc...)
+
+You can use this module freely. (Someone complained this is too vague.
+So, more precisely: do whatever you want with it, but be warned that
+terrible things will happen to you if you use it badly, like for sending
+spam, or ...?)
+
+Thanks to the many users who sent me feedback, bug reports, suggestions, etc.
+And please excuse me if I forgot to answer your mail. I am not always reliabe
+in answering mail. I intend to set up a mailing list soon.
+
+Last revision: 06.02.2003. Latest version should be available on
+CPAN: F<http://www.cpan.org/modules/by-authors/id/M/MI/MIVKOVIC/>.
+
+=cut
Index: /gsdl/stable/perllib/cpan/Ogg/Vorbis/Header/PurePerl.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Ogg/Vorbis/Header/PurePerl.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Ogg/Vorbis/Header/PurePerl.pm	(revision 20131)
@@ -0,0 +1,674 @@
+package Ogg::Vorbis::Header::PurePerl;
+
+use 5.005;
+use strict;
+use warnings;
+
+use Fcntl qw/SEEK_END/;
+
+our $VERSION = '0.07';
+
+sub new 
+{
+    my $class = shift;
+    my $file = shift;
+
+    return load($class, $file);
+}
+
+sub load 
+{
+    my $class    = shift;
+    my $file     = shift;
+    my $from_new = shift;
+    my %data;
+    my $self;
+
+    # there must be a better way...
+    if ($class eq 'Ogg::Vorbis::Header::PurePerl')
+    {
+	$self = bless \%data, $class;
+    }
+    else
+    {
+	$self = $class;
+    }
+
+    if ($self->{'FILE_LOADED'})
+    {
+	return $self;
+    }
+
+    $self->{'FILE_LOADED'} = 1;
+
+    # check that the file exists and is readable
+    unless ( -e $file && -r _ )
+    {
+	warn "File does not exist or cannot be read.";
+	# file does not exist, can't do anything
+	return undef;
+    }
+    # open up the file
+    open FILE, $file;
+    # make sure dos-type systems can handle it...
+    binmode FILE;
+
+    $data{'filename'} = $file;
+    $data{'fileHandle'} = \*FILE;
+
+    _init(\%data);
+    _loadInfo(\%data);
+    _loadComments(\%data);
+    _calculateTrackLength(\%data);
+
+    close FILE;
+
+    return $self;
+}
+
+sub info 
+{
+    my $self = shift;
+    my $key = shift;
+
+    # if the user did not supply a key, return the entire hash
+    unless ($key)
+    {
+	return $self->{'INFO'};
+    }
+
+    # otherwise, return the value for the given key
+    return $self->{'INFO'}{lc $key};
+}
+
+sub comment_tags 
+{
+    my $self = shift;
+
+    return @{$self->{'COMMENT_KEYS'}};
+}
+
+sub comment 
+{
+    my $self = shift;
+    my $key = shift;
+
+    # if the user supplied key does not exist, return undef
+    unless($self->{'COMMENTS'}{lc $key})
+    {
+	return undef;
+    }
+
+    return @{$self->{'COMMENTS'}{lc $key}};
+}
+
+sub add_comments 
+{
+    warn "Ogg::Vorbis::Header::PurePerl add_comments() unimplemented.";
+}
+
+sub edit_comment 
+{
+    warn "Ogg::Vorbis::Header::PurePerl edit_comment() unimplemented.";
+}
+
+sub delete_comment 
+{
+    warn "Ogg::Vorbis::Header::PurePerl delete_comment() unimplemented.";
+}
+
+sub clear_comments 
+{
+    warn "Ogg::Vorbis::Header::PurePerl clear_comments() unimplemented.";
+}
+
+sub path 
+{
+    my $self = shift;
+
+    return $self->{'fileName'};
+}
+
+sub write_vorbis
+{
+    warn "Ogg::Vorbis::Header::PurePerl write_vorbis unimplemented.";
+}
+
+# "private" methods
+
+sub _init
+{
+    my $data = shift;
+    my $fh = $data->{'fileHandle'};
+    my $byteCount = 0;
+
+    # check the header to make sure this is actually an Ogg-Vorbis file
+    $byteCount = _checkHeader($data);
+
+    unless($byteCount)
+    {
+	# if it's not, we can't do anything
+	return undef;
+    }
+
+    $data->{'startInfoHeader'} = $byteCount;
+}
+
+sub _checkHeader
+{
+    my $data = shift;
+    my $fh = $data->{'fileHandle'};
+    my $buffer;
+    my $pageSegCount;
+    my $byteCount = 0; # stores how far into the file we've read,
+                       # so later reads into the file can skip right
+                       # past all of the header stuff
+
+    # check that the first four bytes are 'OggS'
+    read($fh, $buffer, 4);
+    if ($buffer ne 'OggS')
+    {
+	warn "This is not an Ogg bitstream (no OggS header).";
+	return undef;
+    }
+    $byteCount += 4;
+
+    # check the stream structure version (1 byte, should be 0x00)
+    read($fh, $buffer, 1);
+    if (ord($buffer) != 0x00)
+    {
+	warn "This is not an Ogg bitstream (invalid structure version).";
+	return undef;
+    }
+    $byteCount += 1;
+
+    # check the header type flag 
+    # This is a bitfield, so technically we should check all of the bits
+    # that could potentially be set. However, the only value this should
+    # possibly have at the beginning of a proper Ogg-Vorbis file is 0x02,
+    # so we just check for that. If it's not that, we go on anyway, but
+    # give a warning (this behavior may (should?) be modified in the future.
+    read($fh, $buffer, 1);
+    if (ord($buffer) != 0x02)
+    {
+	warn "Invalid header type flag (trying to go ahead anyway).";
+    }
+    $byteCount += 1;
+
+    # skip to the page_segments count
+    read($fh, $buffer, 20);
+    $byteCount += 20;
+    # we do nothing with this data
+
+    # read the number of page segments
+    read($fh, $buffer, 1);
+    $pageSegCount = ord($buffer);
+    $byteCount += 1;
+
+    # read $pageSegCount bytes, then throw 'em out
+    read($fh, $buffer, $pageSegCount);
+    $byteCount += $pageSegCount;
+
+    # check packet type. Should be 0x01 (for indentification header)
+    read($fh, $buffer, 1);
+    if (ord($buffer) != 0x01)
+    {
+	warn "Wrong vorbis header type, giving up.";
+	return undef;
+    }
+    $byteCount += 1;
+
+    # check that the packet identifies itself as 'vorbis'
+    read($fh, $buffer, 6);
+    if ($buffer ne 'vorbis')
+    {
+	warn "This does not appear to be a vorbis stream, giving up.";
+	return undef;
+    }
+    $byteCount += 6;
+
+    # at this point, we assume the bitstream is valid
+    return $byteCount;
+}
+
+sub _loadInfo
+{
+    my $data = shift;
+    my $start = $data->{'startInfoHeader'};
+    my $fh = $data->{'fileHandle'};
+    my $buffer;
+    my $byteCount = $start;
+    my %info;
+    
+    seek $fh, $start, 0;
+    
+    # read the vorbis version
+    read($fh, $buffer, 4);
+    $info{'version'} = _decodeInt($buffer);
+    $byteCount += 4;
+    
+    # read the number of audio channels
+    read($fh, $buffer, 1);
+    $info{'channels'} = ord($buffer);
+    $byteCount += 1;
+
+    # read the sample rate
+    read($fh, $buffer, 4);
+    $info{'rate'} = _decodeInt($buffer);
+    $byteCount += 4;
+    
+    # read the bitrate maximum
+    read($fh, $buffer, 4);
+    $info{'bitrate_upper'} = _decodeInt($buffer);
+    $byteCount += 4;
+
+    # read the bitrate nominal
+    read($fh, $buffer, 4);
+    $info{'bitrate_nominal'} = _decodeInt($buffer);
+    $byteCount += 4;
+
+    # read the bitrate minimal
+    read($fh, $buffer, 4);
+    $info{'bitrate_lower'} = _decodeInt($buffer);
+    $byteCount += 4;
+
+    # read the blocksize_0 and blocksize_1
+    read($fh, $buffer, 1);
+    # these are each 4 bit fields, whose actual value is 2 to the power
+    # of the value of the field
+    $info{'blocksize_0'} = 2 << ((ord($buffer) & 0xF0) >> 4);
+    $info{'blocksize_1'} = 2 << (ord($buffer) & 0x0F);
+    $byteCount += 1;
+
+    # read the framing_flag
+    read($fh, $buffer, 1);
+    $info{'framing_flag'} = ord($buffer);
+    $byteCount += 1;
+
+    # bitrate_window is -1 in the current version of vorbisfile
+    $info{'bitrate_window'} = -1;
+
+    $data->{'startCommentHeader'} = $byteCount;
+
+    $data->{'INFO'} = \%info;
+}
+
+sub _loadComments
+{
+    my $data = shift;
+    my $fh = $data->{'fileHandle'};
+    my $start = $data->{'startCommentHeader'};
+    my $buffer;
+    my $page_segments;
+    my $vendor_length;
+    my $user_comment_count;
+    my $byteCount = $start;
+    my %comments;
+
+    seek $fh, $start, 0;
+
+    # check that the first four bytes are 'OggS'
+    read($fh, $buffer, 4);
+    if ($buffer ne 'OggS')
+    {
+	warn "No comment header?";
+	return undef;
+    }
+    $byteCount += 4;
+
+    # skip over next ten bytes
+    read($fh, $buffer, 10);
+    $byteCount += 10;
+
+    # read the stream serial number
+    read($fh, $buffer, 4);
+    push @{$data->{'commentSerialNumber'}}, _decodeInt($buffer);
+    $byteCount += 4;
+
+    # read the page sequence number (should be 0x01)
+    read($fh, $buffer, 4);
+    if (_decodeInt($buffer) != 0x01)
+    {
+	warn "Comment header page sequence number is not 0x01: " + 
+	    _decodeInt($buffer);
+	warn "Going to keep going anyway.";
+    }
+    $byteCount += 4;
+
+    # and ignore the page checksum for now
+    read($fh, $buffer, 4);
+    $byteCount += 4;
+
+    # get the number of entries in the segment_table...
+    read($fh, $buffer, 1);
+    $page_segments = _decodeInt($buffer);
+    $byteCount += 1;
+    # then skip on past it
+    read($fh, $buffer, $page_segments);
+    $byteCount += $page_segments;
+
+    # check the header type (should be 0x03)
+    read($fh, $buffer, 1);
+    if (ord($buffer) != 0x03)
+    {
+	warn "Wrong header type: " . ord($buffer);
+    }    
+    $byteCount += 1;
+
+    # now we should see 'vorbis'
+    read($fh, $buffer, 6);
+    if ($buffer ne 'vorbis')
+    {
+	warn "Missing comment header. Should have found 'vorbis', found " .
+	    $buffer;
+    }
+    $byteCount += 6;
+
+    # get the vendor length
+    read($fh, $buffer, 4);
+    $vendor_length = _decodeInt($buffer);
+    $byteCount += 4;
+
+    # read in the vendor
+    read($fh, $buffer, $vendor_length);
+    $comments{'vendor'} = $buffer;
+    $byteCount += $vendor_length;
+
+    # read in the number of user comments
+    read($fh, $buffer, 4);
+    $user_comment_count = _decodeInt($buffer);
+    $byteCount += 4;
+
+    $data->{'COMMENT_KEYS'} = [];
+
+    # finally, read the comments
+    for (my $i = 0; $i < $user_comment_count; $i++)
+    {
+	# first read the length
+	read($fh, $buffer, 4);
+	my $comment_length = _decodeInt($buffer);
+	$byteCount += 4;
+
+	# then the comment itself
+	read($fh, $buffer, $comment_length);
+	$byteCount += $comment_length;
+
+	my ($key) = $buffer =~ /^([^=]+)/;
+	my ($value) = $buffer =~ /=(.*)$/;
+
+	push @{$comments{lc $key}}, $value;
+	push @{$data->{'COMMENT_KEYS'}}, lc $key;
+    }
+    
+    # read past the framing_bit
+    read($fh, $buffer, 1);
+    $byteCount += 1;
+
+    $data->{'INFO'}{'offset'} = $byteCount;
+
+    $data->{'COMMENTS'} = \%comments;
+}
+
+sub _calculateTrackLength
+{
+    my $data = shift;
+    my $fh = $data->{'fileHandle'};
+    my $buffer;
+    my $pageSize;
+    my $granule_position;
+
+    seek($fh,-8500,SEEK_END);  # that magic number is from vorbisfile.c
+    # in the constant CHUNKSIZE, which comes
+    # with the comment /* a shade over 8k;
+    # anyone using pages well over 8k gets
+    # what they deserve */
+
+    # we just keep looking through the headers until we get to the last one
+    # (there might be a couple of blocks here)
+    while(_findPage($fh))
+    {
+	# stream structure version - must be 0x00
+	read($fh, $buffer, 1);
+	if (ord($buffer) != 0x00)
+	{
+	    warn "Invalid stream structure version: " .
+		sprintf("%x", ord($buffer));
+	    return;
+ 	}
+
+ 	# header type flag
+ 	read($fh, $buffer, 1);
+ 	# we should check this, but for now we'll just ignore it
+
+ 	# absolute granule position - this is what we need!
+ 	read($fh, $buffer, 8);
+ 	$granule_position = _decodeInt($buffer);
+
+	# skip past stream_serial_number, page_sequence_number, and crc
+	read($fh, $buffer, 12);
+
+	# page_segments
+	read($fh, $buffer, 1);
+	my $page_segments = ord($buffer);
+
+	# reset pageSize
+	$pageSize = 0;
+	
+	# calculate approx. page size
+	for (my $i = 0; $i < $page_segments; $i++)
+	{
+	    read($fh, $buffer, 1);
+	    $pageSize += ord($buffer);
+	}
+
+	seek $fh, $pageSize, 1;
+    }
+
+    $data->{'INFO'}{'length'} = 
+	int($granule_position / $data->{'INFO'}{'rate'});
+}
+
+sub _findPage
+{
+    # search forward in the file for the 'OggS' page header
+    my $fh = shift;
+    my $char;
+    my $curStr = '';
+
+    while (read($fh, $char, 1))
+    {
+	$curStr = $char . $curStr;
+	$curStr = substr($curStr, 0, 4);
+
+	# we are actually looking for the string 'SggO' because we
+	# tack character on to our test string backwards, to make
+	# trimming it to 4 characters easier.
+	if ($curStr eq 'SggO')
+	{
+	    return 1;
+	}
+    }
+
+    return undef;
+}
+
+sub _decodeInt
+{
+    my $bytes = shift;
+    my $num = 0;
+    my @byteList = split //, $bytes;
+    my $numBytes = @byteList;
+    my $mult = 1;
+
+    for (my $i = 0; $i < $numBytes; $i ++)
+    {
+	$num += ord($byteList[$i]) * $mult;
+	$mult *= 256;
+    }
+
+    return $num;
+}
+
+sub _decodeInt5Bit
+{
+    my $byte = ord(shift);
+
+    $byte = $byte & 0xF8; # clear out the bottm 3 bits
+    $byte = $byte >> 3; # and shifted down to where it belongs
+
+    return $byte;
+}
+
+sub _decodeInt4Bit
+{
+    my $byte = ord(shift);
+
+    $byte = $byte & 0xFC; # clear out the bottm 4 bits
+    $byte = $byte >> 4; # and shifted down to where it belongs
+
+    return $byte;
+}
+
+sub _ilog
+{
+    my $x = shift;
+    my $ret = 0;
+
+    unless ($x > 0)
+    {
+	return 0;
+    }
+
+    while ($x > 0)
+    {
+	$ret++;
+	$x = $x >> 1;
+    }
+
+    return $ret;
+}
+
+1;
+__DATA__
+
+=head1 NAME
+
+Ogg::Vorbis::Header::PurePerl - An object-oriented interface to Ogg Vorbis
+information and comment fields, implemented entirely in Perl.  Intended to be 
+a drop in replacement for Ogg::Vobis::Header.
+
+Unlike Ogg::Vorbis::Header, this module will go ahead and fill in all of the
+information fields as soon as you construct the object.  In other words,
+the C<new> and C<load> constructors have identical behavior. 
+
+=head1 SYNOPSIS
+
+	use Ogg::Vorbis::Header::PurePerl;
+	my $ogg = Ogg::Vorbis::Header::PurePerl->new("song.ogg");
+	while (my ($k, $v) = each %{$ogg->info}) {
+		print "$k: $v\n";
+	}
+	foreach my $com ($ogg->comment_tags) {
+		print "$com: $_\n" foreach $ogg->comment($com);
+	}
+
+=head1 DESCRIPTION
+
+This module is intended to be a drop in replacement for Ogg::Vorbis::Header,
+implemented entirely in Perl.  It provides an object-oriented interface to
+Ogg Vorbis information and comment fields.  (NOTE: This module currently 
+supports only read operations).
+
+=head1 CONSTRUCTORS
+
+=head2 C<new ($filename)>
+
+Opens an Ogg Vorbis file, ensuring that it exists and is actually an
+Ogg Vorbis stream.  This method does not actually read any of the
+information or comment fields, and closes the file immediately. 
+
+=head2 C<load ([$filename])>
+
+Opens an Ogg Vorbis file, ensuring that it exists and is actually an
+Ogg Vorbis stream, then loads the information and comment fields.  This
+method can also be used without a filename to load the information
+and fields of an already constructed instance.
+
+=head1 INSTANCE METHODS
+
+=head2 C<info ([$key])>
+
+Returns a hashref containing information about the Ogg Vorbis file from
+the file's information header.  Hash fields are: version, channels, rate,
+bitrate_upper, bitrate_nominal, bitrate_lower, bitrate_window, and length.
+The bitrate_window value is not currently used by the vorbis codec, and 
+will always be -1.  
+
+The optional parameter, key, allows you to retrieve a single value from
+the object's hash.  Returns C<undef> if the key is not found.
+
+=head2 C<comment_tags ()>
+
+Returns an array containing the key values for the comment fields. 
+These values can then be passed to C<comment> to retrieve their values.
+
+=head2 C<comment ($key)>
+
+Returns an array of comment values associated with the given key.
+
+=head2 C<add_comments ($key, $value, [$key, $value, ...])>
+
+Unimplemented.
+
+=head2 C<edit_comment ($key, $value, [$num])>
+
+Unimplemented.
+
+=head2 C<delete_comment ($key, [$num])>
+
+Unimplemented.
+
+=head2 C<clear_comments ([@keys])>
+
+Unimplemented.
+
+=head2 C<write_vorbis ()>
+
+Unimplemented.
+
+=head2 C<path ()>
+
+Returns the path/filename of the file the object represents.
+
+=head1 NOTE
+
+This is ALPHA SOFTWARE.  It may very well be very broken.  Do not use it in
+a production environment.  You have been warned.
+
+=head1 ACKNOWLEDGEMENTS
+
+Dave Brown <cpan@dagbrown.com> made this module significantly faster
+at calculating the length of ogg files.
+
+Robert Moser II <rlmoser@earthlink.net> fixed a problem with files that
+have no comments.
+
+=head1 AUTHOR
+
+Andrew Molloy E<lt>amolloy@kaizolabs.comE<gt>
+
+=head1 COPYRIGHT
+
+Copyright (c) 2003, Andrew Molloy.  All Rights Reserved.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.  A copy of this license is included
+with this module (LICENSE.GPL).
+
+=head1 SEE ALSO
+
+L<Ogg::Vorbis::Header>, L<Ogg::Vorbis::Decoder>
+
+=cut
Index: /gsdl/stable/perllib/cpan/Sub/Override.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Sub/Override.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Sub/Override.pm	(revision 20131)
@@ -0,0 +1,302 @@
+package Sub::Override;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.08';
+
+my $_croak = sub {
+    local *__ANON__ = '__ANON__croak';
+    my ( $proto, $message ) = @_;
+    require Carp;
+    Carp::croak($message);
+};
+
+my $_validate_code_slot = sub {
+    local *__ANON__ = '__ANON__validate_code_slot';
+    my ( $self, $code_slot ) = @_;
+    no strict 'refs';
+    unless ( defined *{$code_slot}{CODE} ) {
+        $self->$_croak("Cannot replace non-existent sub ($code_slot)");
+    }
+    return $self;
+};
+
+my $_validate_sub_ref = sub {
+    local *__ANON__ = '__ANON__validate_sub_ref';
+    my ( $self, $sub_ref ) = @_;
+    unless ( 'CODE' eq ref $sub_ref ) {
+        $self->$_croak("($sub_ref) must be a code reference");
+    }
+    return $self;
+};
+
+my $_normalize_sub_name = sub {
+    local *__ANON__ = '__ANON__normalize_sub_name';
+    my ( $self, $subname ) = @_;
+    if ( ( $subname || '' ) =~ /^\w+$/ ) { # || "" for suppressing test warnings
+        my $package = do {
+            my $call_level = 0;
+            my $this_package;
+            while ( !$this_package || __PACKAGE__ eq $this_package ) {
+                ($this_package) = caller($call_level);
+                $call_level++;
+            }
+            $this_package;
+        };
+        $subname = "${package}::$subname";
+    }
+    return $subname;
+};
+
+sub new {
+    my $class = shift;
+    my $self = bless {}, $class;
+    $self->replace(@_) if @_;
+    return $self;
+}
+
+# because override() was a better name and this is what it should have been
+# called.
+*override = *replace{CODE};
+
+sub replace {
+    my ( $self, $sub_to_replace, $new_sub ) = @_;
+    $sub_to_replace = $self->$_normalize_sub_name($sub_to_replace);
+    $self->$_validate_code_slot($sub_to_replace)->$_validate_sub_ref($new_sub);
+    {
+        no strict 'refs';
+        $self->{$sub_to_replace} ||= *$sub_to_replace{CODE};
+        no warnings 'redefine';
+        *$sub_to_replace = $new_sub;
+    }
+    return $self;
+}
+
+sub restore {
+    my ( $self, $name_of_sub ) = @_;
+    $name_of_sub = $self->$_normalize_sub_name($name_of_sub);
+    if ( !$name_of_sub && 1 == keys %$self ) {
+        ($name_of_sub) = keys %$self;
+    }
+    $self->$_croak(
+        sprintf 'You must provide the name of a sub to restore: (%s)' => join
+          ', ' => sort keys %$self )
+      unless $name_of_sub;
+    $self->$_croak("Cannot restore a sub that was not replaced ($name_of_sub)")
+      unless exists $self->{$name_of_sub};
+    no strict 'refs';
+    no warnings 'redefine';
+    *$name_of_sub = delete $self->{$name_of_sub};
+    return $self;
+}
+
+sub DESTROY {
+    my $self = shift;
+    no strict 'refs';
+    no warnings 'redefine';
+    while ( my ( $sub_name, $sub_ref ) = each %$self ) {
+        *$sub_name = $sub_ref;
+    }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Sub::Override - Perl extension for easily overriding subroutines
+
+=head1 SYNOPSIS
+
+  use Sub::Override;
+
+  sub foo { 'original sub' };
+  print foo(); # prints 'original sub'
+
+  my $override = Sub::Override->new( foo => sub { 'overridden sub' } );
+  print foo(); # prints 'overridden sub'
+  $override->restore;
+  print foo(); # prints 'original sub'
+
+=head1 DESCRIPTION
+
+=head2 The Problem
+
+Sometimes subroutines need to be overridden.  In fact, your author does this
+constantly for tests.  Particularly when testing, using a Mock Object can be
+overkill when all you want to do is override one tiny, little function.
+
+Overriding a subroutine is often done with syntax similar to the following.
+
+ {
+   local *Some::sub = sub {'some behavior'};
+   # do something
+ }
+ # original subroutine behavior restored
+
+This has a few problems.
+
+ {
+   local *Get::some_feild = { 'some behavior' };
+   # do something
+ }
+
+In the above example, not only have we probably mispelled the subroutine name,
+but even if their had been a subroutine with that name, we haven't overridden
+it.  These two bugs can be subtle to detect.
+
+Further, if we're attempting to localize the effect by placing this code in a
+block, the entire construct is cumbersome.
+
+Hook::LexWrap also allows us to override sub behavior, but I can never remember
+the exact syntax.
+
+=head2 An easier way to replace subroutines
+
+Instead, C<Sub::Override> allows the programmer to simply name the sub to
+replace and to supply a sub to replace it with.
+
+  my $override = Sub::Override->new('Some::sub', sub {'new data'});
+
+  # which is equivalent to:
+  my $override = Sub::Override->new;
+  $override->replace('Some::sub', sub { 'new data' });
+
+You can replace multiple subroutines, if needed:
+
+  $override->replace('Some::sub1', sub { 'new data1' });
+  $override->replace('Some::sub2', sub { 'new data2' });
+  $override->replace('Some::sub3', sub { 'new data3' });
+
+If replacing the subroutine succeeds, the object is returned.  This allows the
+programmer to chain the calls, if this style of programming is preferred:
+
+  $override->replace('Some::sub1', sub { 'new data1' })
+           ->replace('Some::sub2', sub { 'new data2' })
+           ->replace('Some::sub3', sub { 'new data3' });
+
+A subroutine may be replaced as many times as desired.  This is most useful
+when testing how code behaves with multiple conditions.
+
+  $override->replace('Some::thing', sub { 0 });
+  is($object->foo, 'wibble', 'wibble is returned if Some::thing is false');
+
+  $override->replace('Some::thing', sub { 1 });
+  is($object->foo, 'puppies', 'puppies are returned if Some::thing is true');
+
+=head2 Restoring subroutines
+
+If the object falls out of scope, the original subs are restored.  However, if
+you need to restore a subroutine early, just use the restore method:
+
+  my $override = Sub::Override->new('Some::sub', sub {'new data'});
+  # do stuff
+  $override->restore;
+
+Which is somewhat equivalent to:
+
+  {
+    my $override = Sub::Override->new('Some::sub', sub {'new data'});
+    # do stuff
+  }
+
+If you have override more than one subroutine with an override object, you
+will have to explicitly name the subroutine you wish to restore:
+
+  $override->restore('This::sub');
+
+Note C<restore()> will always restore the original behavior of the subroutine
+no matter how many times you have overridden it.
+
+=head2 Which package is the subroutine in?
+
+Ordinarily, you want to fully qualify the subroutine by including the package
+name.  However, failure to fully qualify the subroutine name will assume the
+current package.
+
+  package Foo;
+  use Sub::Override;
+  sub foo { 23 };
+  my $override = Sub::Override->new( foo => sub { 42 } ); # assumes Foo::foo
+  print foo(); # prints 42
+  $override->restore;
+  print foo(); # prints 23
+
+=head1 METHODS
+
+=head2 new
+
+  my $sub = Sub::Override->new;
+  my $sub = Sub::Override->new($sub_name, $sub_ref);
+
+Creates a new C<Sub::Override> instance.  Optionally, you may override a 
+subroutine while creating a new object.
+
+=head2 replace
+
+ $sub->replace($sub_name, $sub_body);
+
+Temporarily replaces a subroutine with another subroutine.  Returns the
+instance, so chaining the method is allowed:
+
+ $sub->replace($sub_name, $sub_body)
+     ->replace($another_sub, $another_body);
+
+This method will C<croak> is the subroutine to be replaced does not exist.
+
+=head2 override
+
+ my $sub = Sub::Override->new;
+ $sub->override($sub_name, $sub_body);
+
+C<override> is an alternate name for C<replace>.  They are the same method.
+
+=cut
+
+=head2 restore
+
+ $sub->restore($sub_name);
+
+Restores the previous behavior of the subroutine.  This will happen
+automatically if the C<Sub::Override> object falls out of scope.
+
+=cut
+
+=head1 EXPORT
+
+None by default.
+
+=head1 BUGS
+
+Probably.  Tell me about 'em.
+
+=head1 SEE ALSO
+
+=over 4
+
+=item *
+Hook::LexWrap -- can also override subs, but with different capabilities
+
+=item *
+Test::MockObject -- use this if you need to alter an entire class
+
+=back
+
+=head1 AUTHOR
+
+Curtis "Ovid" Poe, C<< <ovid [at] cpan [dot] org> >>
+
+Reverse the name to email me.
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2004-2005 by Curtis "Ovid" Poe
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.8.2 or,
+at your option, any later version of Perl 5 you may have available.
+
+
+=cut
Index: /gsdl/stable/perllib/cpan/Sub/Uplevel.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Sub/Uplevel.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Sub/Uplevel.pm	(revision 20131)
@@ -0,0 +1,246 @@
+package Sub::Uplevel;
+
+use 5.006;
+
+use strict;
+use vars qw($VERSION @ISA @EXPORT);
+$VERSION = "0.14";
+
+# We have to do this so the CORE::GLOBAL versions override the builtins
+_setup_CORE_GLOBAL();
+
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(uplevel);
+
+=head1 NAME
+
+Sub::Uplevel - apparently run a function in a higher stack frame
+
+=head1 SYNOPSIS
+
+  use Sub::Uplevel;
+
+  sub foo {
+      print join " - ", caller;
+  }
+
+  sub bar {
+      uplevel 1, \&foo;
+  }
+
+  #line 11
+  bar();    # main - foo.plx - 11
+
+=head1 DESCRIPTION
+
+Like Tcl's uplevel() function, but not quite so dangerous.  The idea
+is just to fool caller().  All the really naughty bits of Tcl's
+uplevel() are avoided.
+
+B<THIS IS NOT THE SORT OF THING YOU WANT TO DO EVERYDAY>
+
+=over 4
+
+=item B<uplevel>
+
+  uplevel $num_frames, \&func, @args;
+
+Makes the given function think it's being executed $num_frames higher
+than the current stack level.  So when they use caller($frames) it
+will actually give caller($frames + $num_frames) for them.
+
+C<uplevel(1, \&some_func, @_)> is effectively C<goto &some_func> but
+you don't immediately exit the current subroutine.  So while you can't
+do this:
+
+    sub wrapper {
+        print "Before\n";
+        goto &some_func;
+        print "After\n";
+    }
+
+you can do this:
+
+    sub wrapper {
+        print "Before\n";
+        my @out = uplevel 1, &some_func;
+        print "After\n";
+        return @out;
+    }
+
+
+=cut
+
+our @Up_Frames; # uplevel stack
+
+sub uplevel {
+    my($num_frames, $func, @args) = @_;
+    
+    local @Up_Frames = ($num_frames, @Up_Frames );
+    return $func->(@args);
+}
+
+
+sub _setup_CORE_GLOBAL {
+    no warnings 'redefine';
+
+    *CORE::GLOBAL::caller = sub(;$) {
+        my $height = $_[0] || 0;
+
+        # shortcut if no uplevels have been called
+        # always add +1 to CORE::caller to skip this function's caller
+        return CORE::caller( $height + 1 ) if ! @Up_Frames;
+
+=begin _private
+
+So it has to work like this:
+
+    Call stack               Actual     uplevel 1
+CORE::GLOBAL::caller
+Carp::short_error_loc           0
+Carp::shortmess_heavy           1           0
+Carp::croak                     2           1
+try_croak                       3           2
+uplevel                         4            
+function_that_called_uplevel    5            
+caller_we_want_to_see           6           3
+its_caller                      7           4
+
+So when caller(X) winds up below uplevel(), it only has to use  
+CORE::caller(X+1) (to skip CORE::GLOBAL::caller).  But when caller(X)
+winds up no or above uplevel(), it's CORE::caller(X+1+uplevel+1).
+
+Which means I'm probably going to have to do something nasty like walk
+up the call stack on each caller() to see if I'm going to wind up   
+before or after Sub::Uplevel::uplevel().
+
+=end _private
+
+=begin _dagolden
+
+I found the description above a bit confusing.  Instead, this is the logic
+that I found clearer when CORE::GLOBAL::caller is invoked and we have to
+walk up the call stack:
+
+* if searching up to the requested height in the real call stack doesn't find
+a call to uplevel, then we can return the result at that height in the
+call stack
+
+* if we find a call to uplevel, we need to keep searching upwards beyond the
+requested height at least by the amount of upleveling requested for that
+call to uplevel (from the Up_Frames stack set during the uplevel call)
+
+* additionally, we need to hide the uplevel subroutine call, too, so we search
+upwards one more level for each call to uplevel
+
+* when we've reached the top of the search, we want to return that frame
+in the call stack, i.e. the requested height plus any uplevel adjustments
+found during the search
+
+=end _dagolden
+        
+=cut
+
+        my $saw_uplevel = 0;
+        my $adjust = 0;
+
+        # walk up the call stack to fight the right package level to return;
+        # look one higher than requested for each call to uplevel found
+        # and adjust by the amount found in the Up_Frames stack for that call
+
+        for ( my $up = 0; $up <= $height + $adjust; $up++ ) {
+            my @caller = CORE::caller($up + 1); 
+            if( defined $caller[0] && $caller[0] eq __PACKAGE__ ) {
+                # add one for each uplevel call seen
+                # and look into the uplevel stack for the offset
+                $adjust += 1 + $Up_Frames[$saw_uplevel];
+                $saw_uplevel++;
+            }
+        }
+
+        my @caller = CORE::caller($height + $adjust + 1);
+
+        if( wantarray ) {
+            if( !@_ ) {
+                @caller = @caller[0..2];
+            }
+            return @caller;
+        }
+        else {
+            return $caller[0];
+        }
+    }; # sub
+
+}
+
+=back
+
+=head1 EXAMPLE
+
+The main reason I wrote this module is so I could write wrappers
+around functions and they wouldn't be aware they've been wrapped.
+
+    use Sub::Uplevel;
+
+    my $original_foo = \&foo;
+
+    *foo = sub {
+        my @output = uplevel 1, $original_foo;
+        print "foo() returned:  @output";
+        return @output;
+    };
+
+If this code frightens you B<you should not use this module.>
+
+
+=head1 BUGS and CAVEATS
+
+Sub::Uplevel must be used as early as possible in your program's
+compilation.
+
+Well, the bad news is uplevel() is about 5 times slower than a normal
+function call.  XS implementation anyone?
+
+Blows over any CORE::GLOBAL::caller you might have (and if you do,
+you're just sick).
+
+
+=head1 HISTORY
+
+Those who do not learn from HISTORY are doomed to repeat it.
+
+The lesson here is simple:  Don't sit next to a Tcl programmer at the
+dinner table.
+
+
+=head1 THANKS
+
+Thanks to Brent Welch, Damian Conway and Robin Houston.
+
+
+=head1 AUTHORS
+
+David A Golden E<lt>dagolden@cpan.orgE<gt> (current maintainer)
+
+Michael G Schwern E<lt>schwern@pobox.comE<gt> (original author)
+
+=head1 LICENSE
+
+Copyright by Michael G Schwern, David A Golden
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+See http://www.perl.com/perl/misc/Artistic.html
+
+
+=head1 SEE ALSO
+
+PadWalker (for the similar idea with lexicals), Hook::LexWrap, 
+Tcl's uplevel() at http://www.scriptics.com/man/tcl8.4/TclCmd/uplevel.htm
+
+=cut
+
+
+1;
Index: /gsdl/stable/perllib/cpan/Test/Exception.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Test/Exception.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Test/Exception.pm	(revision 20131)
@@ -0,0 +1,432 @@
+use strict;
+use warnings;
+
+package Test::Exception;
+use Test::Builder;
+use Sub::Uplevel qw( uplevel );
+use base qw( Exporter );
+use Carp;
+
+our $VERSION = '0.24';
+our @EXPORT = qw(dies_ok lives_ok throws_ok lives_and);
+
+my $Tester = Test::Builder->new;
+
+sub import {
+    my $self = shift;
+    if ( @_ ) {
+        my $package = caller;
+        $Tester->exported_to( $package );
+        $Tester->plan( @_ );
+    };
+    $self->export_to_level( 1, $self, $_ ) foreach @EXPORT;
+}
+
+=head1 NAME
+
+Test::Exception - Test exception based code
+
+=head1 SYNOPSIS
+
+  use Test::More tests => 5;
+  use Test::Exception;
+
+  # or if you don't need Test::More
+
+  use Test::Exception tests => 5;
+
+  # then...
+
+  # Check that something died
+  dies_ok { $foo->method1 } 'expecting to die';
+
+  # Check that something did not die
+  lives_ok { $foo->method2 } 'expecting to live';
+
+  # Check that the stringified exception matches given regex
+  throws_ok { $foo->method3 } qr/division by zero/, 'zero caught okay';
+
+  # Check an exception of the given class (or subclass) is thrown
+  throws_ok { $foo->method4 } 'Error::Simple', 'simple error thrown';
+  
+  # all Test::Exceptions subroutines are guaranteed to preserve the state 
+  # of $@ so you can do things like this after throws_ok and dies_ok
+  like $@, 'what the stringified exception should look like';
+
+  # Check that a test runs without an exception
+  lives_and { is $foo->method, 42 } 'method is 42';
+  
+  # or if you don't like prototyped functions
+  
+  dies_ok( sub { $foo->method1 }, 'expecting to die' );
+  lives_ok( sub { $foo->method2 }, 'expecting to live' );
+  throws_ok( sub { $foo->method3 }, qr/division by zero/,
+      'zero caught okay' );
+  throws_ok( sub { $foo->method4 }, 'Error::Simple', 
+      'simple error thrown' );
+  lives_and( sub { is $foo->method, 42 }, 'method is 42' );
+
+
+=head1 DESCRIPTION
+
+This module provides a few convenience methods for testing exception based code. It is built with L<Test::Builder> and plays happily with L<Test::More> and friends.
+
+If you are not already familiar with L<Test::More> now would be the time to go take a look.
+
+You can specify the test plan when you C<use Test::Exception> in the same way as C<use Test::More>. See L<Test::More> for details.
+
+=cut
+
+
+sub _try_as_caller {
+    my $coderef = shift;
+    eval { uplevel 3, $coderef };
+    return $@;
+};
+
+
+sub _is_exception {
+    my $exception = shift;
+    return ref $exception || $exception ne '';
+};
+
+
+sub _exception_as_string {
+    my ( $prefix, $exception ) = @_;
+    return "$prefix normal exit" unless _is_exception( $exception );
+    my $class = ref $exception;
+    $exception = "$class ($exception)" 
+            if $class && "$exception" !~ m/^\Q$class/;
+    chomp $exception;
+    return "$prefix $exception";
+};
+
+
+=over 4
+
+=item B<dies_ok>
+
+Checks that a piece of code dies, rather than returning normally. For example:
+
+    sub div {
+        my ( $a, $b ) = @_;
+        return $a / $b;
+    };
+
+    dies_ok { div( 1, 0 ) } 'divide by zero detected';
+
+    # or if you don't like prototypes
+    dies_ok( sub { div( 1, 0 ) }, 'divide by zero detected' );
+
+A true value is returned if the test succeeds, false otherwise. On exit $@ is guaranteed to be the cause of death (if any).
+
+The test description is optional, but recommended. 
+
+=cut
+
+
+sub dies_ok (&;$) {
+    my ( $coderef, $description ) = @_;
+    my $exception = _try_as_caller( $coderef );
+    my $ok = $Tester->ok( _is_exception($exception), $description );
+    $@ = $exception;
+    return $ok;
+}
+
+
+=item B<lives_ok>
+
+Checks that a piece of code exits normally, and doesn't die. For example:
+
+    sub read_file {
+        my $file = shift;
+        local $/;
+        open my $fh, '<', $file or die "open failed ($!)\n";
+        $file = <FILE>;
+        return $file;
+    };
+
+    my $file;
+    lives_ok { $file = read_file('test.txt') } 'file read';
+
+    # or if you don't like prototypes
+    lives_ok( sub { $file = read_file('test.txt') }, 'file read' );
+
+Should a lives_ok() test fail it produces appropriate diagnostic messages. For example:
+
+    not ok 1 - file read
+    #     Failed test (test.t at line 15)
+    # died: open failed (No such file or directory)
+
+A true value is returned if the test succeeds, false otherwise. On exit $@ is guaranteed to be the cause of death (if any).
+
+The test description is optional, but recommended. 
+
+=cut
+
+sub lives_ok (&;$) {
+    my ( $coderef, $description ) = @_;
+    my $exception = _try_as_caller( $coderef );
+    my $ok = $Tester->ok( ! _is_exception( $exception ), $description );
+	$Tester->diag( _exception_as_string( "died:", $exception ) ) unless $ok;
+    $@ = $exception;
+    return $ok;
+}
+
+
+=item B<throws_ok>
+
+Tests to see that a specific exception is thrown. throws_ok() has two forms: 
+
+  throws_ok BLOCK REGEX, TEST_DESCRIPTION
+  throws_ok BLOCK CLASS, TEST_DESCRIPTION
+
+In the first form the test passes if the stringified exception matches the give regular expression. For example:
+
+    throws_ok { read_file( 'unreadable' ) } qr/No file/, 'no file';
+
+If your perl does not support C<qr//> you can also pass a regex-like string, for example:
+
+    throws_ok { read_file( 'unreadable' ) } '/No file/', 'no file';
+
+The second form of throws_ok() test passes if the exception is of the same class as the one supplied, or a subclass of that class. For example:
+
+    throws_ok { $foo->bar } "Error::Simple", 'simple error';
+
+Will only pass if the C<bar> method throws an Error::Simple exception, or a subclass of an Error::Simple exception.
+
+You can get the same effect by passing an instance of the exception you want to look for. The following is equivalent to the previous example:
+
+    my $SIMPLE = Error::Simple->new;
+    throws_ok { $foo->bar } $SIMPLE, 'simple error';
+
+Should a throws_ok() test fail it produces appropriate diagnostic messages. For example:
+
+    not ok 3 - simple error
+    #     Failed test (test.t at line 48)
+    # expecting: Error::Simple exception
+    # found: normal exit
+
+Like all other Test::Exception functions you can avoid prototypes by passing a subroutine explicitly:
+
+    throws_ok( sub {$foo->bar}, "Error::Simple", 'simple error' );
+
+A true value is returned if the test succeeds, false otherwise. On exit $@ is guaranteed to be the cause of death (if any).
+
+A description of the exception being checked is used if no optional test description is passed.
+
+=cut
+
+
+sub throws_ok (&$;$) {
+    my ( $coderef, $expecting, $description ) = @_;
+    croak "throws_ok: must pass exception class/object or regex" 
+        unless defined $expecting;
+    $description = _exception_as_string( "threw", $expecting )
+    	unless defined $description;
+    my $exception = _try_as_caller( $coderef );
+    my $regex = $Tester->maybe_regex( $expecting );
+    my $ok = $regex 
+        ? ( $exception =~ m/$regex/ ) 
+        : eval { 
+            $exception->isa( ref $expecting ? ref $expecting : $expecting ) 
+        };
+    $Tester->ok( $ok, $description );
+    unless ( $ok ) {
+        $Tester->diag( _exception_as_string( "expecting:", $expecting ) );
+        $Tester->diag( _exception_as_string( "found:", $exception ) );
+    };
+    $@ = $exception;
+    return $ok;
+};
+
+
+=item B<lives_and>
+
+Run a test that may throw an exception. For example, instead of doing:
+
+  my $file;
+  lives_ok { $file = read_file('answer.txt') } 'read_file worked';
+  is $file, "42", 'answer was 42';
+
+You can use lives_and() like this:
+
+  lives_and { is read_file('answer.txt'), "42" } 'answer is 42';
+  # or if you don't like prototypes
+  lives_and(sub {is read_file('answer.txt'), "42"}, 'answer is 42');
+
+Which is the same as doing
+
+  is read_file('answer.txt'), "42\n", 'answer is 42';
+
+unless C<read_file('answer.txt')> dies, in which case you get the same kind of error as lives_ok()
+
+  not ok 1 - answer is 42
+  #     Failed test (test.t at line 15)
+  # died: open failed (No such file or directory)
+
+A true value is returned if the test succeeds, false otherwise. On exit $@ is guaranteed to be the cause of death (if any).
+
+The test description is optional, but recommended.
+
+=cut
+
+sub lives_and (&;$) {
+    my ( $test, $description ) = @_;
+    {
+        local $Test::Builder::Level = $Test::Builder::Level + 1;
+        my $ok = \&Test::Builder::ok;
+        no warnings;
+        local *Test::Builder::ok = sub {
+            $_[2] = $description unless defined $_[2];
+            $ok->(@_);
+        };
+        use warnings;
+        eval { $test->() } and return 1;
+    };
+    my $exception = $@;
+    if ( _is_exception( $exception ) ) {
+        $Tester->ok( 0, $description );
+        $Tester->diag( _exception_as_string( "died:", $exception ) );
+    };
+    $@ = $exception;
+    return;
+}
+
+=back
+
+
+=head1 SKIPPING TEST::EXCEPTION TESTS
+
+Sometimes we want to use Test::Exception tests in a test suite, but don't want to force the user to have Test::Exception installed. One way to do this is to skip the tests if Test::Exception is absent. You can do this with code something like this:
+
+  use strict;
+  use warnings;
+  use Test::More;
+  
+  BEGIN {
+      eval "use Test::Exception";
+      plan skip_all => "Test::Exception needed" if $@;
+  }
+  
+  plan tests => 2;
+  # ... tests that need Test::Exception ...
+
+Note that we load Test::Exception in a C<BEGIN> block ensuring that the subroutine prototypes are in place before the rest of the test script is compiled.
+
+
+=head1 BUGS
+
+None known at the time of writing. 
+
+If you find any please let me know by e-mail, or report the problem with L<http://rt.cpan.org/>.
+
+
+=head1 COMMUNITY
+
+=over 4
+
+=item perl-qa
+
+If you are interested in testing using Perl I recommend you visit L<http://qa.perl.org/> and join the excellent perl-qa mailing list. See L<http://lists.perl.org/showlist.cgi?name=perl-qa> for details on how to subscribe.
+
+=item perlmonks
+
+You can find users of Test::Exception, including the module author, on  L<http://www.perlmonks.org/>. Feel free to ask questions on Test::Exception there.
+
+=item CPAN::Forum
+
+The CPAN Forum is a web forum for discussing Perl's CPAN modules.   The Test::Exception forum can be found at L<http://www.cpanforum.com/dist/Test-Exception>.
+
+=item AnnoCPAN
+
+AnnoCPAN is a web site that allows community annotations of Perl module documentation. The Test::Exception annotations can be found at L<http://annocpan.org/~ADIE/Test-Exception/>.
+
+=back
+
+
+=head1 TO DO
+
+If you think this module should do something that it doesn't (or does something that it shouldn't) please let me know.
+
+You can see my current to do list at L<http://adrianh.tadalist.com/lists/public/15421>, with an RSS feed of changes at L<http://adrianh.tadalist.com/lists/feed_public/15421>.
+
+
+=head1 ACKNOWLEDGMENTS
+
+Thanks to chromatic and Michael G Schwern for the excellent Test::Builder, without which this module wouldn't be possible.
+
+Thanks to 
+Adam Kennedy,
+Andy Lester, 
+Aristotle, 
+Ben Prew, 
+Cees Hek,
+chromatic, 
+Curt Sampson,
+David Golden, 
+David Wheeler, 
+Janek Schleicher,
+Jim Keenan, 
+Jos I. Boumans, 
+Jost Krieger,
+Mark Fowler, 
+Michael G Schwern, 
+Paul McCann,
+Perrin Harkins, 
+Peter Scott, 
+Rob Muhlestein 
+Scott R. Godin,
+Steve Purkis,
+Steve, 
+Tim Bunce,
+and various anonymous folk for comments, suggestions, bug reports and patches.
+
+
+=head1 AUTHOR
+
+Adrian Howard <adrianh@quietstars.com>
+
+If you can spare the time, please drop me a line if you find this module useful.
+
+
+=head1 SEE ALSO
+
+=over 4
+
+=item L<Test::Builder>
+
+Support module for building test libraries.
+
+=item L<Test::Simple> & L<Test::More>
+
+Basic utilities for writing tests.
+
+=item L<Test::Warn> & L<Test::NoWarnings>
+
+Modules to help test warnings.
+
+=item L<http://qa.perl.org/test-modules.html>
+
+Overview of some of the many testing modules available on CPAN.
+
+=item L<http://del.icio.us/tag/Test::Exception>
+
+Delicious links on Test::Exception.
+
+=item L<http://del.icio.us/tag/perl+testing>
+
+Delicious links on perl testing.
+
+=back
+
+
+=head1 LICENCE
+
+Copyright 2002-2006 Adrian Howard, All Rights Reserved.
+
+This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
+
+=cut
+
+1;
Index: /gsdl/stable/perllib/cpan/Win32/Shortcut.pm
===================================================================
--- /gsdl/stable/perllib/cpan/Win32/Shortcut.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/Win32/Shortcut.pm	(revision 20131)
@@ -0,0 +1,352 @@
+package Win32::Shortcut;
+#######################################################################
+#
+# Win32::Shortcut - Perl Module for Shell Link Interface
+# ^^^^^^^^^^^^^^^
+# This module creates an object oriented interface to the Win32
+# Shell Links (IShellLink interface).
+#
+# Version: 0.03 (07 Apr 1997)
+#
+#######################################################################
+
+require Exporter;       # to export the constants to the main:: space
+require DynaLoader;     # to dynuhlode the module.
+
+@ISA= qw( Exporter DynaLoader );
+@EXPORT = qw(
+    SW_SHOWMAXIMIZED
+    SW_SHOWMINNOACTIVE
+    SW_SHOWNORMAL
+);
+
+
+#######################################################################
+# This AUTOLOAD is used to 'autoload' constants from the constant()
+# XS function.  If a constant is not found then control is passed
+# to the AUTOLOAD in AutoLoader.
+#
+
+sub AUTOLOAD {
+    my($constname);
+    ($constname = $AUTOLOAD) =~ s/.*:://;
+    #reset $! to zero to reset any current errors.
+    local $! = 0;
+    my $val = constant($constname, @_ ? $_[0] : 0);
+    if ($! != 0) {
+
+    # [dada] This results in an ugly Autoloader error
+
+    #if ($! =~ /Invalid/) {
+    #    $AutoLoader::AUTOLOAD = $AUTOLOAD;
+    #    goto &AutoLoader::AUTOLOAD;
+    #} else {
+    
+    # [dada] ... I prefer this one :)
+
+        ($pack, $file, $line) = caller;
+        undef $pack; # [dada] and get rid of "used only once" warning...
+        die "Win32::Shortcut::$constname is not defined, used at $file line $line.";
+
+    #}
+    }
+    eval "sub $AUTOLOAD { $val }";
+    goto &$AUTOLOAD;
+}
+
+
+#######################################################################
+# STATIC OBJECT PROPERTIES
+#
+$VERSION = "0.03";
+
+#######################################################################
+# PUBLIC METHODS
+#
+
+#======== ### CLASS CONSTRUCTOR
+sub new {
+#========
+    my($class, $file) = @_;
+    my $self = {}; 
+    my $ilink = 0; 
+    my $ifile = 0;
+
+    ($ilink, $ifile) = _Instance();
+
+    if($ilink and $ifile) {
+        $self->{'ilink'} = $ilink;
+        $self->{'ifile'} = $ifile;
+        bless $self;
+        # Initialize properties
+        $self->{'File'}             = "";
+        $self->{'Path'}             = "";
+        $self->{'Arguments'}        = "";
+        $self->{'WorkingDirectory'} = "";
+        $self->{'Description'}      = "";
+        $self->{'ShowCmd'}          = 0;
+        $self->{'Hotkey'}           = 0;
+        $self->{'IconLocation'}     = "";
+        $self->{'IconNumber'}       = 0;
+
+        $self->Load($file) if $file;
+        
+    } else {
+        return undef;
+    }
+    $self;
+}  
+
+#=========
+sub Load {
+#=========
+    my($self, $file) = @_;
+    return undef unless ref($self);
+  
+    my $result = _Load($self->{'ilink'}, $self->{'ifile'}, $file);
+
+    if(defined($result)) {
+  
+        # fill the properties of $self
+        $self->{'File'} = $file;
+        $self->{'Path'} = _GetPath($self->{'ilink'}, $self->{'ifile'},0);
+        $self->{'ShortPath'} = _GetPath($self->{'ilink'}, $self->{'ifile'},1);
+        $self->{'Arguments'} = _GetArguments($self->{'ilink'}, $self->{'ifile'});
+        $self->{'WorkingDirectory'} = _GetWorkingDirectory($self->{'ilink'}, $self->{'ifile'});
+        $self->{'Description'} = _GetDescription($self->{'ilink'}, $self->{'ifile'});
+        $self->{'ShowCmd'} = _GetShowCmd($self->{'ilink'}, $self->{'ifile'});
+        $self->{'Hotkey'} = _GetHotkey($self->{'ilink'}, $self->{'ifile'});
+        ($self->{'IconLocation'},
+         $self->{'IconNumber'}) = _GetIconLocation($self->{'ilink'}, $self->{'ifile'});
+    }
+    return $result;
+}
+
+
+#========
+sub Set {
+#========
+    my($self, $path, $arguments, $dir, $description, $show, $hotkey, 
+       $iconlocation, $iconnumber) = @_;
+    return undef unless ref($self);
+
+    $self->{'Path'}             = $path;
+    $self->{'Arguments'}        = $arguments;
+    $self->{'WorkingDirectory'} = $dir;
+    $self->{'Description'}      = $description;
+    $self->{'ShowCmd'}          = $show;
+    $self->{'Hotkey'}           = $hotkey;
+    $self->{'IconLocation'}     = $iconlocation;
+    $self->{'IconNumber'}       = $iconnumber;
+    return 1;
+}
+
+
+#=========
+sub Save {
+#=========
+    my($self, $file) = @_;
+    return undef unless ref($self);
+
+    return undef if not $file and not $self->{'File'};
+    $file = $self->{'File'} if not $file;
+
+    _SetPath($self->{'ilink'}, $self->{'ifile'}, $self->{'Path'});
+    _SetArguments($self->{'ilink'}, $self->{'ifile'}, $self->{'Arguments'});
+    _SetWorkingDirectory($self->{'ilink'}, $self->{'ifile'}, $self->{'WorkingDirectory'});
+    _SetDescription($self->{'ilink'}, $self->{'ifile'}, $self->{'Description'});
+    _SetShowCmd($self->{'ilink'}, $self->{'ifile'}, $self->{'ShowCmd'});
+    _SetHotkey($self->{'ilink'}, $self->{'ifile'}, $self->{'Hotkey'});
+    _SetIconLocation($self->{'ilink'}, $self->{'ifile'},
+                     $self->{'IconLocation'}, $self->{'IconNumber'});
+
+    my $result = _Save($self->{'ilink'}, $self->{'ifile'}, $file);
+    return $result;
+}
+
+#============
+sub Resolve {
+#============
+    my($self, $flags) = @_;
+    return undef unless ref($self);
+    $flags = 1 unless defined($flags);
+    my $result = _Resolve($self->{'ilink'}, $self->{'ifile'}, $flags);
+    return $result;
+}
+
+
+#==========
+sub Close {
+#==========
+    my($self) = @_;
+    return undef unless ref($self);
+
+    my $result = _Release($self->{'ilink'}, $self->{'ifile'});
+    $self->{'released'} = 1;
+    return $result;
+}
+
+#=========
+sub Path {
+#=========
+    my($self, $value) = @_;
+    return undef unless ref($self);
+
+    if(not defined($value)) {
+        return $self->{'Path'};
+    } else {
+        $self->{'Path'} = $value;
+    }
+    return $self->{'Path'};
+}
+
+#==============
+sub ShortPath {
+#==============
+    my($self) = @_;
+    return undef unless ref($self);
+    return $self->{'ShortPath'};
+}
+
+#==============
+sub Arguments {
+#==============
+    my($self, $value) = @_;
+    return undef unless ref($self);
+
+    if(not defined($value)) {
+        return $self->{'Arguments'};
+    } else {
+        $self->{'Arguments'} = $value;
+    }
+    return $self->{'Arguments'};
+}
+
+#=====================
+sub WorkingDirectory {
+#=====================
+    my($self, $value) = @_;
+    return undef unless ref($self);
+
+    if(not defined($value)) {
+        return $self->{'WorkingDirectory'};
+    } else {
+        $self->{'WorkingDirectory'} = $value;
+    }
+    return $self->{'WorkingDirectory'};
+}
+
+
+#================
+sub Description {
+#================
+    my($self, $value) = @_;
+    return undef unless ref($self);
+
+    if(not defined($value)) {
+        return $self->{'Description'};
+    } else {
+        $self->{'Description'} = $value;
+    }
+    return $self->{'Description'};
+}
+
+#============
+sub ShowCmd {
+#============
+    my($self, $value) = @_;
+    return undef unless ref($self);
+
+    if(not defined($value)) {
+        return $self->{'ShowCmd'};
+    } else {
+        $self->{'ShowCmd'} = $value;
+    }
+    return $self->{'ShowCmd'};
+}
+
+#===========
+sub Hotkey {
+#===========
+    my($self, $value) = @_;
+    return undef unless ref($self);
+
+    if(not defined($value)) {
+        return $self->{'Hotkey'};
+    } else {
+        $self->{'Hotkey'} = $value;
+    }
+    return $self->{'Hotkey'};
+}
+
+#=================
+sub IconLocation {
+#=================
+    my($self, $value) = @_;
+    return undef unless ref($self);
+
+    if(not defined($value)) {
+        return $self->{'IconLocation'};
+    } else {
+        $self->{'IconLocation'} = $value;
+    }
+    return $self->{'IconLocation'};
+}
+
+#===============
+sub IconNumber {
+#===============
+    my($self, $value) = @_;
+    return undef unless ref($self);
+
+    if(not defined($value)) {
+        return $self->{'IconNumber'};
+    } else {
+        $self->{'IconNumber'} = $value;
+    }
+    return $self->{'IconNumber'};
+}
+
+#============
+sub Version {
+#============
+    # [dada] to get rid of the "used only once" warning...
+    return $VERSION;
+}
+
+
+#######################################################################
+# PRIVATE METHODS
+#
+
+#============ ### CLASS DESTRUCTOR
+sub DESTROY {
+#============
+    my($self) = @_;
+
+    if(not $self->{'released'}) {
+        _Release($self->{'ilink'}, $self->{'ifile'});
+    }
+}
+
+#======== ### PACKAGE DESTRUCTOR
+sub END { 
+#========
+    # print "Exiting...\n";
+    _Exit(); 
+}
+
+#######################################################################
+# dynamically load in the Shortcut.pll module.
+#
+
+bootstrap Win32::Shortcut;
+
+# Preloaded methods go here.
+
+#Currently Autoloading is not implemented in Perl for win32
+# Autoload methods go after __END__, and are processed by the autosplit program.
+
+1;
+__END__
+
Index: /gsdl/stable/perllib/cpan/XML/Rules.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/Rules.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/Rules.pm	(revision 20131)
@@ -0,0 +1,2084 @@
+package XML::Rules;
+
+use warnings;
+no warnings qw(uninitialized);
+use strict;
+use Carp;
+
+require Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT_OK = qw(paths2rules);
+
+use XML::Parser::Expat;
+
+=head1 NAME
+
+XML::Rules - parse XML and specify what and how to keep/process for individual tags
+
+=head1 VERSION
+
+Version 1.05
+
+=cut
+
+our $VERSION = '1.05';
+
+=head1 SYNOPSIS
+
+    use XML::Rules;
+
+	$xml = <<'*END*';
+	<doc>
+	 <person>
+	  <fname>...</fname>
+	  <lname>...</lname>
+	  <email>...</email>
+	  <address>
+	   <street>...</street>
+	   <city>...</city>
+	   <country>...</country>
+	   <bogus>...</bogus>
+	  </address>
+	  <phones>
+	   <phone type="home">123-456-7890</phone>
+	   <phone type="office">663-486-7890</phone>
+	   <phone type="fax">663-486-7000</phone>
+	  </phones>
+	 </person>
+	 <person>
+	  <fname>...</fname>
+	  <lname>...</lname>
+	  <email>...</email>
+	  <address>
+	   <street>...</street>
+	   <city>...</city>
+	   <country>...</country>
+	   <bogus>...</bogus>
+	  </address>
+	  <phones>
+	   <phone type="office">663-486-7891</phone>
+	  </phones>
+	 </person>
+	</doc>
+	*END*
+
+	@rules = (
+		_default => sub {$_[0] => $_[1]->{_content}},
+			# by default I'm only interested in the content of the tag, not the attributes
+		bogus => undef,
+			# let's ignore this tag and all inner ones as well
+		address => sub {address => "$_[1]->{street}, $_[1]->{city} ($_[1]->{country})"},
+			# merge the address into a single string
+		phone => sub {$_[1]->{type} => $_[1]->{_content}},
+			# let's use the "type" attribute as the key and the content as the value
+		phones => sub {delete $_[1]->{_content}; %{$_[1]}},
+			# remove the text content and pass along the type => content from the child nodes
+		person => sub { # lets print the values, all the data is readily available in the attributes
+			print "$_[1]->{lname}, $_[1]->{fname} <$_[1]->{email}>\n";
+			print "Home phone: $_[1]->{home}\n" if $_[1]->{home};
+			print "Office phone: $_[1]->{office}\n" if $_[1]->{office};
+			print "Fax: $_[1]->{fax}\n" if $_[1]->{fax};
+			print "$_[1]->{address}\n\n";
+			return; # the <person> tag is processed, no need to remember what it contained
+		},
+	);
+	$parser = XML::Rules->new(rules => \@rules);
+	$parser->parse( $xml);
+
+=head1 INTRODUCTION
+
+There are several ways to extract data from XML. One that's often used is to read the whole file and transform it into a huge maze of objects and then write code like
+
+	foreach my $obj ($XML->forTheLifeOfMyMotherGiveMeTheFirstChildNamed("Peter")->pleaseBeSoKindAndGiveMeAllChildrenNamedSomethingLike("Jane")) {
+		my $obj2 = $obj->sorryToKeepBotheringButINeedTheChildNamed("Theophile");
+		my $birth = $obj2->whatsTheValueOfAttribute("BirthDate");
+		print "Theophile was bort at $birth\n";
+	}
+
+I'm exagerating of course, but you probably know what I mean. You can of course shorten the path and call just one method ... that is if you spend the time to learn one more "cool" thing starting with X. XPath.
+
+You can also use XML::Simple and generate an almost equaly huge maze of hashes and arrays ... which may make the code more or less complex. In either case you need to have enough memory
+to store all that data, even if you only need a piece here and there.
+
+Another way to parse the XML is to create some subroutines that handle the start and end tags and the text and whatever else may appear in the XML. Some modules will let you specify just one for start tag, one for text and one for end tag, others will let you install different handlers for different tags. The catch is that you have to build your data structures yourself, you have to know where you are, what tag is just open and what is the parent and it's parent etc. so that you could add the attributes and especially the text to the right place. And the handlers have to do everything as their side effect. Does anyone remember what do they say about side efects? They make the code hard to debug, they tend to change the code into a maze of interdependent snippets of code.
+
+So what's the difference in the way XML::Rules works? At the first glance, not much. You can also specify subroutines to be called for the tags encountered while parsing the XML, just like the other even based XML parsers. The difference is that you do not have to rely on sideeffects if all you want is to store the value of a tag. You simply return whatever you need from the current tag and the module will add it at the right place in the data structure it builds and will provide it to the handlers for the parent tag. And if the parent tag does return that data again it will be passed to its parent and so forth. Until we get to the level at which it's convenient to handle all the data we accumulated from the twig.
+
+Do we want to keep just the content and access it in the parent tag handler under a specific name?
+
+	foo => sub {return 'foo' => $_[1]->{_content}}
+
+Do we want to ornament the content a bit and add it to the parent tag's content?
+
+	u => sub {return '_' . $_[1]->{_content} . '_'}
+	strong =>  sub {return '*' . $_[1]->{_content} . '*'}
+	uc =>  sub {return uc($_[1]->{_content})}
+
+Do we want to merge the attributes into a string and access the string from the parent tag under a specified name?
+
+	address => sub {return 'Address' => "Street: $_[1]->{street} $_[1]->{bldngNo}\nCity: $_[1]->{city}\nCountry: $_[1]->{country}\nPostal code: $_[1]->{zip}"}
+
+and in this case the $_[1]->{street} may either be an attribute of the <address> tag or it may be ther result of the handler (rule)
+
+	street => sub {return 'street' => $_[1]->{_content}}
+
+and thus come from a child tag <street>. You may also use the rules to convert codes to values
+
+	our %states = (
+	  AL => 'Alabama',
+	  AK => 'Alaska',
+	  ...
+	);
+	...
+	state => sub {return 'state' => $states{$_[1]->{_content}}; }
+
+ or
+
+	address => sub {
+		if (exists $_[1]->{id}) {
+			$sthFetchAddress->execute($_[1]->{id});
+			my $addr = $sthFetchAddress->fetchrow_hashref();
+			$sthFetchAddress->finish();
+			return 'address' => $addr;
+		} else {
+			return 'address' => $_[1];
+		}
+	}
+
+so that you do not have to care whether there was
+
+	<address id="147"/>
+
+or
+
+	<address><street>Larry Wall's St.</street><streetno>478</streetno><city>Core</city><country>The Programming Republic of Perl</country></address>
+
+At each level in the tree structure serialized as XML you can decide what to keep, what to throw away, what to transform and then just return the stuff you care about and it will be available to the handler at the next level.
+
+=head1 CONSTRUCTOR
+
+	my $parser = XML::Rules->new(
+		rules => \@rules,
+		[ start_rules => \@start_rules, ]
+		[ stripspaces => 0 / 1 / 2 / 3   +   0 / 4   +   0 / 8, ]
+		[ normalisespaces => 0 / 1, ]
+		[ style => 'parser' / 'filter', ]
+		[ ident => '  ', [reformat_all => 0 / 1] ],
+		[ encode => 'encoding specification', ]
+		[ output_encoding => 'encoding specification', ]
+		[ namespaces => \%namespace2alias_mapping, ]
+		# and optionaly parameters passed to XML::Parser::Expat
+	);
+
+Options passed to XML::Parser::Expat : ProtocolEncoding Namespaces NoExpand Stream_Delimiter ErrorContext ParseParamEnt Base
+
+The "stripspaces" controls the handling of whitespace. Please see the C<Whitespace handling> bellow.
+
+The "style" specifies whether you want to build a parser used to extract stuff from the XML or filter/modify the XML. If you specify
+style => 'filter' then all tags for which you do not specify a subroutine rule or that occure inside such a tag are copied to the output filehandle
+passed to the ->filter() or ->filterfile() methods.
+
+The "ident" specifies what character(s) to use to ident the tags when filtering, by default the tags are not formatted in any way. If the
+"reformat_all" is not set then this affects only the tags that have a rule and their subtags. And in case of subtags only those that were
+added into the attribute hash by their rules, not those left in the _content array!
+
+The "warnoverwrite" instructs XML::Rules to issue a warning whenever the rule cause a key in a tag's hash to be overwritten by new
+data produced by the rule of a subtag. This happens eg. if a tag is repeated and its rule doesn't expect it.
+
+The "encode" allows you to ask the module to run all data through Encode::encode( 'encoding_specification', ...)
+before being passed to the rules. Otherwise all data comes as UTF8.
+
+The "output_encoding" on the other hand specifies in what encoding is the resulting data going to be, the default is again UTF8.
+This means that if you specify
+
+	encode => 'windows-1250',
+	output_encoding => 'utf8',
+
+and the XML is in ISO-8859-2 (Latin2) then the filter will 1) convert the content and attributes of the tags you are not interested in from Latin2
+directly to utf8 and output and 2) convert the content and attributes of the tags you want to process from Latin2 to Windows-1250, let you mangle
+the data and then convert the results to utf8 for the output.
+
+The C<encode> and C<output_enconding> affects also the C<$parser->toXML(...)>, if they are different then the data are converted from
+one encoding to the other.
+
+=head2 The Rules
+
+The rules option may be either an arrayref or a hashref, the module doesn't care, but if you want to use regexps to specify the groups of tags to be handled
+by the same rule you should use the array ref. The rules array/hash is made of pairs in form
+
+	tagspecification => action
+
+where the tagspecification may be either a name of a tag, a string containing comma or pipe ( "|" ) delimited list of tag names
+or a string containing a regexp enclosed in // with optional parameters or a qr// compiled regular expressions. The tag names and tag name lists
+take precedence to the regexps, the regexps are (in case of arrayref only!!!) tested in the order in which they are specified.
+
+These rules are evaluated/executed whenever a tag if fully parsed including all the content and child tags and they may access the content and attributes of the
+specified tag plus the stuff produced by the rules evaluated for the child tags.
+
+The action may be either
+
+	an undef or empty string = ignore the tag and all its children
+	a subroutine reference = the subroutine will be called to handle the tag data&contents
+		sub { my ($tagname, $attrHash, $contexArray, $parentDataArray, $parser) = @_; ...}
+	'content' = only the content of the tag is preserved and added to
+		the parent tag's hash as an attribute named after the tag
+		sub { $_[0] => $_[1]->{_content}}
+	'content trim' = only the content of the tag is preserved, trimmed and added to
+		the parent tag's hash as an attribute named after the tag
+		sub { s/^\s+//,s/\s+$// for ($_[1]->{_content}); $_[0] => $_[1]->{_content}}
+	'content array' = only the content of the tag is preserved and pushed
+		to the array pointed to by the attribute
+		sub { '@' . $_[0] => $_[1]->{_content}}
+	'as is' = the tag's hash is added to the parent tag's hash
+		as an attribute named after the tag
+		sub { $_[0] => $_[1]}
+	'as is trim' = the tag's hash is added to the parent tag's hash
+		as an attribute named after the tag, the content is trimmed
+		sub { $_[0] => $_[1]}
+	'as array' = the tag's hash is pushed to the attribute named after the tag
+		in the parent tag's hash
+		sub { '@'.$_[0] => $_[1]}
+	'as array trim' = the tag's hash is pushed to the attribute named after the tag
+		in the parent tag's hash, the content is trimmed
+		sub { '@'.$_[0] => $_[1]}
+	'no content' = the _content is removed from the tag's hash and the hash
+		is added to the parent's hash into the attribute named after the tag
+		sub { delete $_[1]->{_content}; $_[0] => $_[1]}
+	'no content array' = similar to 'no content' except the hash is pushed
+		into the array referenced by the attribute
+	'as array no content' = same as 'no content array'
+	'pass' = the tag's hash is dissolved into the parent's hash,
+		that is all tag's attributes become the parent's attributes.
+		The _content is appended to the parent's _content.
+		sub { %{$_[0]}}
+	'pass no content' = the _content is removed and the hash is dissolved
+		into the parent's hash.
+		sub { delete $_[1]->{_content}; %{$_[0]}}
+	'pass without content' = same as 'pass no content'
+	'raw' = the [tagname => attrs] is pushed to the parent tag's _content.
+		You would use this style if you wanted to be able to print
+		the parent tag as XML preserving the whitespace or other textual content
+		sub { [$_[0] => $_[1]]}
+	'raw extended' = the [tagname => attrs] is pushed to the parent tag's _content
+		and the attrs are added to the parent's attribute hash with ":$tagname" as the key
+		sub { (':'.$_[0] => $_[1], [$_[0] => $_[1]])};
+	'raw extended array' = the [tagname => attrs] is pushed to the parent tag's _content
+		and the attrs are pushed to the parent's attribute hash with ":$tagname" as the key
+		sub { ('@:'.$_[0] => $_[1], [$_[0] => $_[1]])};
+	'by <attrname>' = uses the value of the specified attribute as the key when adding the
+		attribute hash into the parent tag's hash. You can specify more names, in that case
+		the first found is used.
+		sub {delete($_[1]->{name}) => $_[1]}
+	'content by <attrname>' = uses the value of the specified attribute as the key when adding the
+		tags content into the parent tag's hash. You can specify more names, in that case
+		the first found is used.
+		sub {$_[1]->{name} => $_[1]->{_content}}
+	'no content by <attrname>' = uses the value of the specified attribute as the key when adding the
+		attribute hash into the parent tag's hash. The content is dropped. You can specify more names,
+		in that case the first found is used.
+		sub {delete($_[1]->{_content}); delete($_[1]->{name}) => $_[1]}
+	'==...' = replace the tag by the specified string. That is the string will be added to
+		the parent tag's _content
+		sub { return '...' }
+	'=...' = replace the tag contents by the specified string and forget the attributes.
+		sub { return $_[0] => '...' }
+
+You may also add " no xmlns" at the end of all those predefined rules to strip the namespace
+alias from the $_[0] (tag name).
+
+The subroutines in the rules specification receive five parameters:
+
+	$rule->( $tag_name, \%attrs, \@context, \@parent_data, $parser)
+
+It's OK to destroy the first two parameters, but you should treat the other three as read only
+or at least treat them with care!
+
+	$tag_name = string containing the tag name
+	\%attrs = hash containing the attributes of the tag plus the _content key
+		containing the text content of the tag. If it's not a leaf tag it may
+		also contain the data returned by the rules invoked for the child tags.
+	\@context = an array containing the names of the tags enclosing the current
+		one. The parent tag name is the last element of the array.
+	\@parent_data = an array containing the hashes with the attributes
+		and content read&produced for the enclosing tags so far.
+		You may need to access this for example to find out the version
+		of the format specified as an attribute of the root tag. You may
+		safely add, change or delete attributes in the hashes, but all bets
+		are off if you change the number or type of elements of this array!
+	$parser = the parser object.
+
+The subroutine may decide to handle the data and return nothing or
+tweak the data as necessary and return just the relevant bits. It may also
+load more information from elsewhere based on the ids found in the XML
+and provide it to the rules of the ancestor tags as if it was part of the XML.
+
+The possible return values of the subroutines are:
+
+1) nothing or undef or "" - nothing gets added to the parent tag's hash
+
+2) a single string - if the parent's _content is a string then the one produced by this rule is appended to the parent's _content.
+If the parent's _content is an array, then the string is push()ed to the array.
+
+3) a single reference - if the parent's _content is a string then it's changed to an array containing the original string and this reference.
+If the parent's _content is an array, then the string is push()ed to the array.
+
+4) an even numbered list - it's a list of key & value pairs to be added to the parent's hash.
+
+The handling of the attributes may be changed by adding '@', '%', '+', '*' or '.' before the attribute name.
+
+Without any "sigil" the key & value is added to the hash overwriting any previous values.
+
+The values for the keys starting with '@' are push()ed to the arrays referenced by the key name
+without the @. If there already is an attribute of the same name then the value will be preserved and will become
+the first element in the array.
+
+The values for the keys starting with '%' have to be either hash or array references. The key&value pairs
+in the referenced hash or array will be added to the hash referenced by the key. This is nice for rows of tags like this:
+
+  <field name="foo" value="12"/>
+  <field name="bar" value="24"/>
+
+if you specify the rule as
+
+  field => sub { '%fields' => [$_[1]->{name} => $_[1]->{value}]}
+
+then the parent tag's has will contain
+
+  fields => {
+    foo => 12,
+	bar => 24,
+  }
+
+The values for the keys starting with '+' are added to the current value, the ones starting with '.' are
+appended to the current value and the ones starting with '*' multiply the current value.
+
+5) an odd numbered list - the last element is appended or push()ed to the parent's _content, the rest is handled as in the previous case.
+
+
+Since 0.19 it's possible to specify several actions for a tag if you need to do something different based on the path to the tag like this:
+
+	tagname => [
+		'tag/path' => action,
+		'/root/tag/path' => action,
+		'/root/*/path' => action,
+		qr{^root/ns:[^/]+/par$} => action,
+		default_action
+	],
+
+The path is matched against the list of parent tags joined by slashes.
+
+=head2 The Start Rules
+
+Apart from the normal rules that get invoked once the tag is fully parsed, including the contents and child tags, you may want to
+attach some code to the start tag to (optionaly) skip whole branches of XML or set up attributes and variables. You may set up
+the start rules either in a separate parameter to the constructor or in the rules=> by prepending the tag name(s) by ^.
+
+These rules are in form
+
+	tagspecification => undef / '' / 'skip'	--> skip the element, including child tags
+	tagspecification => 1 / 'handle'	--> handle the element, may be needed
+		if you specify the _default rule.
+	tagspecification => \&subroutine
+
+The subroutines receive the same parameters as for the "end tag" rules except of course the _content, but their return value is treated differently.
+If the subroutine returns a false value then the whole branch enclosed by the current tag is skipped, no data are stored and no rules are
+executed. You may modify the hash referenced by $attr.
+
+Both types of rules are free to store any data they want in $parser->{pad}. This property is NOT emptied
+after the parsing!
+
+=head2 Whitespace handling
+
+There are two options that affect the whitespace handling: stripspaces and normalisespaces. The normalisespaces is a simple flag that controls
+whether multiple spaces/tabs/newlines are collapsed into a single space or not. The stripspaces is more complex, it's a bit-mask,
+an ORed combination of the following options:
+
+	0 - don't remove whitespace around tags
+	    (around tags means before the opening tag and after the closing tag, not in the tag's content!)
+	1 - remove whitespace before tags whose rules did not return any text content
+	    (the rule specified for the tag caused the data of the tag to be ignored,
+		processed them already or added them as attributes to parent's \%attr)
+	2 - remove whitespace around tags whose rules did not return any text content
+	3 - remove whitespace around all tags
+
+	0 - remove only whitespace-only content
+	    (that is remove the whitespace around <foo/> in this case "<bar>   <foo/>   </bar>"
+		but not this one "<bar>blah   <foo/>  blah</bar>")
+	4 - remove trailing/leading whitespace
+	    (remove the whitespace in both cases above)
+
+	0 - don't trim content
+	8 - do trim content
+		(That is for "<foo>  blah   </foo>" only pass to the rule {_content => 'blah'})
+
+
+That is if you have a data oriented XML in which each tag contains either text content or subtags, but not both,
+you want to use stripspaces => 3 or stripspaces => 3|4. This will not only make sure you don't need to bother
+with the whitespace-only _content of the tags with subtags, but will also make sure you do not keep on wasting
+memory while parsing a huge XML and processing the "twigs". Without that option the parent tag of
+the repeated tag would keep on accumulating unneeded whitespace in its _content.
+
+=cut
+
+sub new {
+	my $class = shift;
+	my %params = @_;
+	croak "Please specify the rules=> for the parser!" unless $params{rules} and ref($params{rules});
+
+	my $self = {rules => {}, start_rules => {}};
+	bless $self, $class;
+
+	my @rules = (ref($params{rules}) eq 'HASH' ? %{$params{rules}} : @{$params{rules}}); # dereference and copy
+	delete $params{rules};
+
+	my @start_rules;
+	if ($params{start_rules} and ref($params{start_rules})) {
+		@start_rules = ref($params{start_rules}) eq 'HASH' ? %{$params{start_rules}} : @{$params{start_rules}}; # dereference and copy
+	};
+	delete $params{start_rules};
+
+	for (my $i=0; $i <= $#rules; $i+=2) {
+		next unless $rules[$i] =~ s/^\^//;
+		push @start_rules, splice( @rules, $i, 2);
+		$i-=2;
+	}
+
+	$self->_split_rules( \@rules, 'rules', 'as is');
+	$self->_split_rules( \@start_rules, 'start_rules', 'handle');
+
+	$self->{for_parser} = {};
+	{ # extract the params for the XML::Parser::Expat constructor
+		my @for_parser = grep exists($params{$_}), qw(ProtocolEncoding Namespaces NoExpand Stream_Delimiter ErrorContext ParseParamEnt Base);
+		if (@for_parser) {
+			@{$self->{for_parser}}{@for_parser} = @params{@for_parser};
+			delete @params{@for_parser};
+		}
+	}
+
+	$self->{namespaces} = delete($params{namespaces});
+	if (defined($self->{namespaces})) {
+		croak 'XML::Rules->new( ... , namespaces => ...HERE...) must be a hash reference!'
+			unless ref($self->{namespaces}) eq 'HASH';
+		$self->{xmlns_map} = {};
+	}
+
+	$self->{style} = delete($params{style}) || 'parser';
+
+	$self->{opt}{lc $_} = $params{$_} for keys %params;
+
+	delete $self->{opt}{encode} if $self->{opt}{encode} =~ /^utf-?8$/i;
+	delete $self->{opt}{output_encoding} if $self->{opt}{output_encoding} =~ /^utf-?8$/i;
+
+	for (qw(normalisespace normalizespace normalizespaces)) {
+		last if defined($self->{opt}{normalisespaces});
+		$self->{opt}{normalisespaces} = $self->{opt}{$_};
+		delete $self->{opt}{$_};
+	}
+	$self->{opt}{normalisespaces} = 0 unless(defined($self->{opt}{normalisespaces}));
+	$self->{opt}{stripspaces} = 0 unless(defined($self->{opt}{stripspaces}));
+
+	require 'Encode.pm' if $self->{opt}{encode};
+	require 'Encode.pm' if $self->{opt}{output_encoding};
+
+	return $self;
+}
+
+sub _split_rules {
+	my ($self, $rules, $type, $default) = @_;
+
+	$self->{$type}{_default} = $default unless exists($self->{$type}{_default});
+
+	while (@$rules) {
+		my ($tag, $code) = (shift(@$rules), shift(@$rules));
+
+		if (ref($code) eq 'ARRAY') {
+			for( my $i = 0; $i < $#$code; $i+=2) {
+				$code->[$i] = _xpath2re($code->[$i]);
+			}
+			push @$code, $self->{$type}{_default} if @$code % 2 == 0; # add the default type if there's even number of items (path => code, path => code)
+		}
+
+		if ($tag =~ m{^/([^/].*)/([imosx]*)$}) { # string with a '/regexp/'
+			if ($2) {
+				push @{$self->{$type.'_re'}}, qr/(?$2)$1/;
+			} else {
+				push @{$self->{$type.'_re'}}, qr/$1/;
+			}
+			push @{$self->{$type.'_re_code'}}, $code;
+		} elsif (ref($tag) eq 'Regexp') { # a qr// created regexp
+			push @{$self->{$type.'_re'}}, $tag;
+			push @{$self->{$type.'_re_code'}}, $code;
+		} elsif ($tag =~ /[,\|]/) { # a , or | separated list
+			if ($tag =~ s/^\^//) {
+				my @tags = split(/\s*[,\|]\s*/, $tag);
+				$self->{$type}{'^'.$_} = $code for (@tags);
+			} else {
+				my @tags = split(/\s*[,\|]\s*/, $tag);
+				$self->{$type}{$_} = $code for (@tags);
+			}
+		} else { # a single tag
+			$self->{$type}{$tag} = $code;
+		}
+	}
+}
+
+sub _xpath2re {
+	my $s = shift;
+	return $s if ref($s);
+	for ($s) {
+		s/([\.\[\]+{}\-])/\\$1/g;
+		s{\*}{.+}g;
+		s{^//}{}s;
+		s{^/}{^}s;
+	}
+	return qr{$s$};
+}
+
+sub skip_rest {
+	die "[XML::Rules] skip rest\n";
+}
+
+sub return_nothing {
+	die "[XML::Rules] return nothing\n";
+}
+
+sub _run {
+	my $self = shift;
+	my $string = shift;
+	$self->{parameters} = shift;
+
+	$self->{parser} = XML::Parser::Expat->new( %{$self->{for_parser}});
+
+	$self->{parser}->setHandlers(
+		Start => _Start($self),
+		End => _End($self),
+		Char => _Char($self),
+		XMLDecl => _XMLDecl($self),
+	);
+
+	$self->{data} = [];
+	$self->{context} = [];
+	$self->{_ltrim} = [0];
+
+	if (! eval {
+		$self->{parser}->parse($string) and 1;
+	}) {
+		my $err = $@;
+		undef $@;
+
+		if ($err =~ /^\[XML::Rules\] skip rest/) {
+			my (undef, $handler) = $self->{parser}->setHandlers(End => undef);
+			foreach my $tag (reverse @{$self->{context} = []}) {
+				$handler->( $self->{parser}, $tag);
+			}
+		} else {
+
+			delete $self->{normal_handlers};
+			delete $self->{ignore_handlers};
+			delete $self->{parameters};
+			$self->{parser}->release();
+
+			$self->{data} = [];
+			$self->{context} = [];
+
+			if ($err =~ /^\[XML::Rules\] return nothing/) {
+				return;
+			}
+
+			$err =~ s/at \S+Rules\.pm line \d+$//
+				and croak $err or die $err;
+		}
+	};
+
+	delete $self->{normal_handlers};
+	delete $self->{ignore_handlers};
+	$self->{parser}->release();
+
+	delete $self->{parameters};
+	my $data; # return the accumulated data, without keeping a copy inside the object
+	($data, $self->{data}) = ($self->{data}[0], undef);
+	if (!defined(wantarray()) or ! keys(%$data)) {
+		return;
+
+	} elsif (keys(%$data) == 1 and exists(${$data}{_content})) {
+		if (ref(${$data}{_content}) eq 'ARRAY' and @{${$data}{_content}} == 1) {
+			return ${${$data}{_content}}[0]
+		} else {
+			return ${$data}{_content}
+		}
+
+	} else {
+		return $data;
+	}
+}
+
+
+sub parsestring;
+*parsestring = \&parse;
+sub parse {
+	my $self = shift;
+	croak("This XML::Rules object may only be used as a filter!") if ($self->{style} eq 'filter');
+	$self->_run(@_);
+}
+
+sub parsefile {
+	my $self = shift;
+	croak("This XML::Rules object may only be used as a filter!") if ($self->{style} eq 'filter');
+	my $filename = shift;
+	open my $IN, '<', $filename or croak "Cannot open '$filename' for reading: $^E";
+	return $self->_run($IN, @_);
+}
+
+
+sub filterstring;
+*filterstring = \&filter;
+sub filter {
+	my $self = shift;
+	croak("This XML::Rules object may only be used as a parser!") unless ($self->{style} eq 'filter');
+
+	my $XML = shift;
+	$self->{FH} = shift || select(); # either passed or the selected filehandle
+	if (!ref($self->{FH})) {
+		if ($self->{FH} =~ /^main::(?:STDOUT|STDERR)$/) {
+			# yeah, select sometimes returns the name of the filehandle, not the filehandle itself. eg. "main::STDOUT"
+			no strict;
+			$self->{FH} = \*{$self->{FH}};
+		} else {
+			open my $FH, '>', $self->{FH} or croak(qq{Failed to open "$self->{FH}" for writing: $^E});
+			$self->{FH} = $FH;
+		}
+	} elsif (ref($self->{FH}) eq 'SCALAR') {
+		open my $FH, '>', $self->{FH};
+		$self->{FH} = $FH;
+	}
+	if ($self->{opt}{output_encoding}) {
+		print {$self->{FH}} qq{<?xml version="1.0" encoding="$self->{opt}{output_encoding}"?>\n};
+	} else {
+		print {$self->{FH}} qq{<?xml version="1.0"?>\n};
+	}
+	$self->_run($XML, @_);
+	print {$self->{FH}} "\n";
+	delete $self->{FH};
+}
+
+sub filterfile {
+	my $self = shift;
+	croak("This XML::Rules object may only be used as a parser!") unless ($self->{style} eq 'filter');
+
+	my $filename = shift;
+	open my $IN, '<', $filename or croak "Cannot open '$filename' for reading: $^E";
+
+	$self->{FH} = shift || select(); # either passed or the selected filehandle
+	if (!ref($self->{FH})) {
+		if ($self->{FH} =~ /^main::(?:STDOUT|STDERR)$/) {
+			# yeah, select sometimes returns the name of the filehandle, not the filehandle itself. eg. "main::STDOUT"
+			no strict;
+			$self->{FH} = \*{$self->{FH}};
+		} else {
+			open my $FH, '>', $self->{FH} or croak(qq{Failed to open "$self->{FH}" for writing: $^E});
+			$self->{FH} = $FH;
+		}
+	} elsif (ref($self->{FH}) eq 'SCALAR') {
+		open $self->{FH}, '>', $self->{FH};
+	}
+	if ($self->{opt}{output_encoding}) {
+		print {$self->{FH}} qq{<?xml version="1.0" encoding="$self->{opt}{output_encoding}"?>\n};
+	} else {
+		print {$self->{FH}} qq{<?xml version="1.0"?>\n};
+	}
+	$self->_run($IN, @_);
+	print {$self->{FH}} "\n";
+	delete $self->{FH};
+}
+
+sub _XMLDecl {
+	my $self = shift;
+	return sub {
+		my ( $Parser, $Version, $Encoding, $Standalone) = @_;
+		$self->{opt}{original_encoding} = $Encoding
+	}
+}
+
+=begin comment
+
+start tag
+	& 3 = 3 -> rtrim parent's _content
+	& 8 = 8 -> $ltrim = 1
+
+string content
+	$ltrim -> ltrim the string, if not completely whitespace set $ltrim  0
+
+end tag
+	& 8 = 8 -> rtrim own content
+	& 3 = 3 -> $ltrim = 1
+	empty_returned_content and & 3 in (1,2) -> rtrim parent content
+	empty_returned_content and & 3  = 2 -> $ltrim
+
+=end comment
+
+=cut
+
+sub _rtrim {
+	my ($self, $attr, $more) = @_;
+
+	if ($more) {
+		if (ref $attr->{_content}) {
+			if (!ref($attr->{_content}[-1])) {
+				$attr->{_content}[-1] =~ s/\s+$//s;
+				pop @{$attr->{_content}} if $attr->{_content}[-1] eq '';
+				delete $attr->{_content} unless @{$attr->{_content}};
+			}
+		} else {
+			$attr->{_content} =~ s/\s+$//s;
+			delete $attr->{_content} if $attr->{_content} eq '';
+		}
+	} else {
+		if (ref $attr->{_content}) {
+			if (!ref($attr->{_content}[-1]) and $attr->{_content}[-1] =~ /^\s*$/s) {
+				pop @{$attr->{_content}} ;
+				delete $attr->{_content} unless @{$attr->{_content}};
+			}
+		} else {
+			delete $attr->{_content} if $attr->{_content}  =~ /^\s*$/s;
+		}
+	}
+}
+
+sub _Start {
+	my $self = shift;
+	my $encode = $self->{opt}{encode};
+	my $output_encoding = $self->{opt}{output_encoding};
+	return sub {
+		my ( $Parser, $Element , %Attr) = @_;
+
+		if (($self->{opt}{stripspaces} & 3) == 3) {
+			#rtrim parent
+#print "rtrim parent content in _Start\n";
+			if ($self->{data}[-1] and $self->{data}[-1]{_content}) {
+				$self->_rtrim( $self->{data}[-1], ($self->{opt}{stripspaces} & 4));
+			}
+		}
+		if ($self->{opt}{stripspaces} & 8) {
+#print "ltrim own content in _Start\n";
+			push @{$self->{_ltrim}}, 2;
+		} else {
+			push @{$self->{_ltrim}}, 0;
+		}
+
+		if ($self->{namespaces}) {
+			my %restore;
+			if (exists $Attr{xmlns}) { # find the default namespace
+#print "Found a xmlns attribute in $Element!\n";
+				$restore{''} = $self->{xmlns_map}{''};
+				if (!exists($self->{namespaces}{ $Attr{xmlns} })) {
+					warn qq{Unexpected namespace "$Attr{xmlns}" found in the XML!\n} unless exists $self->{namespaces}{'*'};
+					delete $self->{xmlns_map}{''};
+					delete $restore{''} unless defined($restore{''});
+					delete($Attr{xmlns});
+				} else {
+					$self->{xmlns_map}{''} = $self->{namespaces}{ delete($Attr{xmlns}) };
+				}
+			}
+			foreach my $attr (keys %Attr) { # find the namespace aliases
+				next unless $attr =~ /^xmlns:(.*)$/;
+				$restore{$1} = $self->{xmlns_map}{$1};
+				if (!exists($self->{namespaces}{ $Attr{$attr} })) {
+					warn qq{Unexpected namespace "$Attr{$attr}" found in the XML!\n} unless exists $self->{namespaces}{'*'};
+					delete $self->{xmlns_map}{$1};
+					delete $restore{$1} unless defined($restore{$1});
+					delete($Attr{$attr});
+				} else {
+					$self->{xmlns_map}{$1} = $self->{namespaces}{ delete($Attr{$attr}) };
+				}
+			}
+			if (%restore) {
+				push @{$self->{xmlns_restore}}, \%restore;
+			} else {
+				push @{$self->{xmlns_restore}}, undef;
+			}
+
+			if (%{$self->{xmlns_map}}) {
+#print "About to map aliases for $Element\n";
+				# add or map the alias for the tag
+				if ($Element =~ /^([^:]+):(.*)$/) {
+#print "Mapping an alias $1 for tag $Element\n";
+					if (exists($self->{xmlns_map}{$1})) {
+						if ($self->{xmlns_map}{$1} eq '') {
+							$Element = $2 ;
+						} else {
+							$Element = $self->{xmlns_map}{$1} . ':' . $2 ;
+						}
+					}
+#print " -> $Element\n";
+				} elsif (defined($self->{xmlns_map}{''}) and $self->{xmlns_map}{''} ne '') { # no namespace alias in the tag and there's a default
+#print "Adding default alias $self->{xmlns_map}{''}:\n";
+					$Element = $self->{xmlns_map}{''} . ':' . $Element;
+#print " -> $Element\n";
+				}
+
+				# map the aliases for the attributes
+				foreach my $attr (keys %Attr) {
+					next unless $attr =~ /^([^:]+):(.*)$/; # there's an alias
+					next unless exists($self->{xmlns_map}{$1}); # and there's a mapping
+					if ($self->{xmlns_map}{$1} eq '') {
+						$Attr{$2} = delete($Attr{$attr}); # rename the attribute
+					} else {
+						$Attr{$self->{xmlns_map}{$1} . ':' . $2} = delete($Attr{$attr}); # rename the attribute
+					}
+				}
+			}
+		} # /of namespace handling
+
+
+		my ( $start_rule, $end_rule) = map {
+			if ($self->{$_}{$Element} and ref($self->{$_}{$Element}) ne 'ARRAY') {
+				$self->{$_}{$Element}
+			} else {
+				$self->_find_rule( $_, $Element, $self->{context})
+			}
+		} ( 'start_rules', 'rules');
+
+		if ($start_rule ne 'handle'
+		and (
+			!$start_rule
+			or $start_rule eq 'skip'
+			or !$start_rule->($Element,\%Attr, $self->{context}, $self->{data}, $self)
+			)
+		) {
+			# ignore the tag and the ones below
+			if (exists $self->{ignore_handlers}) {
+#print "SETHANDLERS!\n";
+				$Parser->setHandlers(@{$self->{ignore_handlers}})
+			} else {
+				$self->{ignore_handlers} = [
+					Start => _StartIgnore($self),
+					Char => undef,
+					End => _EndIgnore($self),
+				];
+#print "SETHANDLERS2\n";
+				$self->{normal_handlers} = [$Parser->setHandlers(@{$self->{ignore_handlers}})];
+			}
+			$self->{ignore_level}=1;
+
+		} else {
+			# process the tag and the ones below
+			if ($encode) {
+				foreach my $value (values %Attr) {
+					$value = Encode::encode( $encode, $value);
+				}
+			}
+
+			push @{$self->{context}}, $Element;
+			push @{$self->{data}}, \%Attr;
+			$self->{lastempty} = 0;
+
+			if ($self->{style} eq 'filter') {
+				$self->{in_interesting}++ if ref($end_rule) or $end_rule =~ /^=/s; # is this tag interesting?
+
+				if (! $self->{in_interesting}) { # it neither this tag not an acestor is interesting, just copy the tag
+#print "Start:R ".$Parser->recognized_string()."\n";
+#print "Start:O ".$Parser->original_string()."\n";
+#print "Start:R ".$Parser->recognized_string()."\n";
+#print "Start:O ".$Parser->original_string()."\n";
+					if (! $output_encoding) {
+						print {$self->{FH}} $Parser->recognized_string();
+					} elsif ($output_encoding eq $self->{opt}{original_encoding}) {
+						print {$self->{FH}} $Parser->original_string();
+					} else {
+						print {$self->{FH}} $self->toXML($Element, \%Attr, "don't close");
+					}
+				}
+			}
+
+		}
+	}
+}
+
+sub _find_rule {
+	my ($self, $type, $Element, $path) = @_;
+
+	if (exists($self->{$type.'_re'})) {
+		for(my $i = 0; $i < @{$self->{$type.'_re'}}; $i++) {
+			if ($Element =~ $self->{$type.'_re'}[$i]) {
+				$self->{$type}{$Element} = $self->{$type.'_re_code'}[$i];
+				last;
+			}
+		}
+	}
+	if (! exists $self->{$type}{$Element}) {
+		$self->{$type}{$Element} = $self->{$type}{_default};
+	}
+
+	if (ref $self->{$type}{$Element} eq 'ARRAY') {
+		$path = join( '/', @$path);
+		for(my $i=0; $i < $#{$self->{$type}{$Element}}; $i+=2) {
+			if ($path =~ $self->{$type}{$Element}[$i]) {
+				return $self->{$type}{$Element}[$i+1];
+			}
+		}
+		return $self->{$type}{$Element}[-1];
+	} else {
+		return $self->{$type}{$Element};
+	}
+}
+
+sub _Char {
+	my $self = shift;
+	my $encode = $self->{opt}{encode};
+	return sub {
+		my ( $Parser, $String) = @_;
+
+		if ($self->{style} eq 'filter' and ! $self->{in_interesting}) {
+			if (! $self->{opt}{output_encoding}) {
+				print {$self->{FH}} $Parser->recognized_string();
+			} elsif ($self->{opt}{output_encoding} eq $self->{opt}{original_encoding}) {
+				print {$self->{FH}} $Parser->original_string();
+			} else {
+				print {$self->{FH}} encode($self->{opt}{output_encoding}, $Parser->recognized_string());
+			}
+			return;
+		}
+
+		if ($encode) {
+			$String = Encode::encode( $encode, $String);
+		}
+
+		if ($self->{_ltrim}[-1]) {
+#print "ltrim in $self->{context}[-1] ($String)\n";
+			if ($self->{_ltrim}[-1] == 2) {
+				$String =~ s/^\s+//s;
+				return if $String eq '';
+			} else {
+				return if $String =~ /^\s*$/s;
+			}
+			$self->{_ltrim}[-1] = 0;
+#print "  ($String)\n";
+		}
+		$String =~ s/\s+/ /gs if ($self->{opt}{normalisespaces});
+
+		if (!exists $self->{data}[-1]{_content}) {
+			$self->{data}[-1]{_content} = $String;
+		} elsif (!ref $self->{data}[-1]{_content}) {
+			if ($self->{opt}{normalisespaces} and $self->{data}[-1]{_content} =~ /\s$/ and $String =~ /^\s/) {
+				$String =~ s/^\s+//s;
+			}
+			$self->{data}[-1]{_content} .= $String;
+		} else {
+			if (ref $self->{data}[-1]{_content}[-1]) {
+				push @{$self->{data}[-1]{_content}}, $String;
+			} else {
+				if ($self->{opt}{normalisespaces} and $self->{data}[-1]{_content}[-1] =~ /\s$/ and $String =~ /^\s/) {
+					$String =~ s/^\s+//s;
+				}
+				$self->{data}[-1]{_content}[-1] .= $String;
+			}
+		}
+	}
+}
+
+sub _End {
+	my $self = shift;
+	return sub {
+		my ( $Parser, $Element) = @_;
+		$Element = pop @{$self->{context}}; # the element name may have been mangled by XMLNS aliasing
+
+		if ($self->{opt}{stripspaces} & 8) {
+#print "rtrim own content\n";
+			if ($self->{data}[-1] and $self->{data}[-1]{_content}) {
+				$self->_rtrim( $self->{data}[-1], 1);
+			}
+		}
+		pop(@{$self->{_ltrim}});
+
+		if ($self->{namespaces}) {
+			if (my $restore = pop @{$self->{xmlns_restore}}) { # restore the old default namespace and/or alias mapping
+				while (my ($their, $our)  = each %$restore) {
+					if (defined($our)) {
+						$self->{xmlns_map}{$their} = $our;
+					} else {
+						delete $self->{xmlns_map}{$their};
+					}
+				}
+			}
+		}
+
+		my ($rule) = map {
+			if ($self->{$_}{$Element} and ref($self->{$_}{$Element}) ne 'ARRAY') {
+				$self->{$_}{$Element}
+			} else {
+				$self->_find_rule( $_, $Element, $self->{context})
+			}
+		} ('rules');
+
+		my $data = pop @{$self->{data}};
+
+		my @results;
+		if (ref $rule or $rule =~ /^=/s) {
+			if ($rule =~ /^==(.*)$/s) { # change the whole tag to a string
+				@results = ($1);
+			} elsif ($rule =~ /^=(.*)$/s) { # change the contents to a string
+				@results = ($Element => $1);
+			} else {
+				@results = $rule->($Element, $data, $self->{context}, $self->{data}, $self);
+			}
+
+			if ($self->{style} eq 'filter') {
+
+				$self->{in_interesting}--;
+				if (!$self->{in_interesting}) {
+					if (@{$self->{data}}) {
+						print {$self->{FH}} $self->escape_value($self->{data}[-1]{_content});
+						delete $self->{data}[-1]{_content};
+					}
+					my $base;
+					if ($self->{opt}{ident} ne '') {
+						$base = $self->{opt}{ident} x scalar(@{$self->{context}});
+					}
+					@results and $results[0] =~ s/^[\@%\+\*\.]//;
+					while (@results) {
+#use Data::Dumper;
+#print "\@results=".Dumper(\@results)."\n";
+						if (ref($results[0])) {
+							croak(ref($results[0]) . " not supported as the return value of a filter") unless ref($results[0]) eq 'ARRAY';
+							if (@{$results[0]} ==2 and ref($results[0][1]) eq 'HASH') {
+								print {$self->{FH}} $self->toXML(@{$results[0]}[0,1], 0, $self->{opt}{ident}, $base);
+							} else {
+								foreach my $item (@{$results[0]}) {
+									if (ref($item)) {
+										croak(ref($item) . " not supported in the return value of a filter") unless ref($item) eq 'ARRAY';
+										croak("Empty array not supported in the return value of a filter") unless @$item;
+										if (@$item <= 2) {
+											print {$self->{FH}} $self->toXML(@{$item}[0,1], 0, $self->{opt}{ident}, $base);
+										} else { # we suppose the 3rd and following elements are parameters to ->toXML()
+											print {$self->{FH}} $self->toXML(@$item);
+										}
+									} else {
+										print {$self->{FH}} $self->escape_value($item);
+									}
+								}
+							}
+							shift(@results);
+						} else {
+							if (@results == 1) {
+								print {$self->{FH}} $self->escape_value($results[0]);
+								@results = ();last;
+							} else {
+								print {$self->{FH}} $self->toXML(shift(@results), shift(@results), 0, $self->{opt}{ident}, $base);
+							}
+						}
+					}
+				}
+			}
+		} elsif ($self->{style} eq 'filter' and ! $self->{in_interesting}) {
+#print "End: \$Element=$Element; \$Parser->recognized_string()=".$Parser->recognized_string()."; \$Parser->original_string()=".$Parser->original_string()."\n";
+die "Unexpected \$data->{content}={$data->{_content}} in filter outside interesting nodes!\n" if $data->{_content} ne '';
+				if (! $self->{opt}{output_encoding}) {
+					print {$self->{FH}} $Parser->recognized_string();
+				} elsif ($self->{opt}{output_encoding} eq $self->{opt}{original_encoding}) {
+					print {$self->{FH}} $Parser->original_string();
+				} else {
+					print {$self->{FH}} encode($self->{opt}{output_encoding}, $Parser->recognized_string());
+				}
+#			print {$self->{FH}} $self->escape_value($data->{_content})."</$Element>";
+
+		} else { # a predefined rule
+
+			if ($rule =~ s/(?:^| )no xmlns$//) {
+				$Element =~ s/^\w+://;
+				$rule = 'as_is' if $rule eq '';
+			}
+
+			if ($rule eq '') {
+				@results = ();
+			} elsif ($rule eq 'content') {
+				@results = ($Element => $data->{_content});
+			} elsif ($rule eq 'content trim') {
+				s/^\s+//,s/\s+$// for ($data->{_content});
+				@results = ($Element => $data->{_content});
+			} elsif ($rule eq 'content array') {
+				@results = ('@'.$Element => $data->{_content});
+			} elsif ($rule eq 'as is') {
+				@results = ($Element => $data);
+			} elsif ($rule eq 'as is trim') {
+				s/^\s+//,s/\s+$// for ($data->{_content});
+				@results = ($Element => $data);
+			} elsif ($rule eq 'as array') {
+				@results = ('@'.$Element => $data);
+			} elsif ($rule eq 'as array trim') {
+				s/^\s+//,s/\s+$// for ($data->{_content});
+				@results = ('@'.$Element => $data);
+			} elsif ($rule eq 'no content') {
+				delete ${$data}{_content}; @results = ($Element => $data);
+			} elsif ($rule eq 'no content array' or $rule eq 'as array no content') {
+				delete ${$data}{_content}; @results = ('@' . $Element => $data);
+
+			} elsif ($rule eq 'pass') {
+				@results = (%$data);
+			} elsif ($rule eq 'pass trim') {
+				s/^\s+//,s/\s+$// for ($data->{_content});
+				@results = (%$data);
+			} elsif ($rule eq 'pass no content' or $rule eq 'pass without content') {
+				delete ${$data}{_content}; @results = (%$data);
+
+			} elsif ($rule eq 'raw') {
+				@results = [$Element => $data];
+
+			} elsif ($rule eq 'raw extended') {
+				@results = (':'.$Element => $data, [$Element => $data]);
+
+			} elsif ($rule eq 'raw extended array') {
+				@results = ('@:'.$Element => $data, [$Element => $data]);
+
+			} elsif ($rule =~ /^((?:no )?content )?by\s+(\S+)$/) {
+				my ($cnt,$attr) = ($1,$2);
+				if ($cnt eq 'no content ') {
+					delete $data->{_content};
+				}
+				if ($attr =~ /,/) {
+					my @attr = split /,/, $attr;
+					foreach (@attr) {
+						next unless exists ($data->{$_});
+						if ($cnt eq 'content ') {
+							@results = ($data->{$_} => $data->{_content})
+						} else {
+							@results = (delete $data->{$_} => $data)
+						}
+						last;
+					}
+				} else {
+					if ($cnt eq 'content ') {
+						@results = ($data->{$attr} => $data->{_content})
+					} else {
+						@results = (delete $data->{$attr} => $data);
+					}
+				}
+
+			} else {
+				croak "Unknown predefined rule '$rule'!";
+			}
+		}
+
+		if (! @results or (@results % 2 == 0) or $results[-1] eq '') {
+			if ($self->{opt}{stripspaces} & 3 and @{$self->{data}} and $self->{data}[-1]{_content}) { # stripping some spaces, it's not root and it did not return content
+#print "maybe stripping some spaces in $Element, it's not root and it did not return content\n";
+				if (($self->{opt}{stripspaces} & 3) < 3 and $self->{data}[-1]{_content}) {
+					# rtrim parent content
+#print "  yes, rtrim parent '$self->{data}[-1]{_content}'\n";
+					$self->_rtrim( $self->{data}[-1], ($self->{opt}{stripspaces} & 4));
+#print "  result '$self->{data}[-1]{_content}'\n";
+				}
+
+				$self->{_ltrim}[-1] = (($self->{opt}{stripspaces} & 4) ? 2 : 1)
+					if ($self->{opt}{stripspaces} & 3) == 2;
+			}
+		} else {
+			$self->{_ltrim}[-1] = 0;
+		}
+		if (($self->{opt}{stripspaces} & 3) == 3) {
+			$self->{_ltrim}[-1] = (($self->{opt}{stripspaces} & 4) ? 2 : 1);
+		}
+
+
+		return unless scalar(@results) or scalar(@results) == 1 and ($results[0] eq '' or !defined($results[0]));
+
+		@{$self->{data}} = ({}) unless @{$self->{data}}; # oops we are already closing the root tag! We do need there to be at least one hashref in $self->{data}
+
+		if (scalar(@results) % 2) {
+			# odd number of items, last is content
+			my $value = pop(@results);
+			_add_content( $self->{data}[-1], $value);
+		}
+
+		while (@results) {
+			my ($key, $value) = ( shift(@results), shift(@results));
+			if ($key eq '_content') {
+				_add_content( $self->{data}[-1], $value);
+			} elsif ($key =~ s/^\@//) {
+				if (exists($self->{data}[-1]{$key}) and ref($self->{data}[-1]{$key}) ne 'ARRAY') {
+					$self->{data}[-1]{$key} = [$self->{data}[-1]{$key}, $value];
+				} else {
+					push @{$self->{data}[-1]{$key}}, $value;
+				}
+			} elsif ($key =~ s/^\+//) {
+				if (exists($self->{data}[-1]{$key})) {
+					$self->{data}[-1]{$key} += $value;
+				} else {
+					$self->{data}[-1]{$key} = $value;
+				}
+			} elsif ($key =~ s/^\*//) {
+				if (exists($self->{data}[-1]{$key})) {
+					$self->{data}[-1]{$key} *= $value;
+				} else {
+					$self->{data}[-1]{$key} = $value;
+				}
+			} elsif ($key =~ s/^\.//) {
+				if (exists($self->{data}[-1]{$key})) {
+					$self->{data}[-1]{$key} .= $value;
+				} else {
+					$self->{data}[-1]{$key} = $value;
+				}
+			} elsif ($key =~ s/^\%//) {
+				if (exists($self->{data}[-1]{$key})) {
+					if (ref($value) eq 'HASH') {
+						%{$self->{data}[-1]{$key}} = (%{$self->{data}[-1]{$key}}, %$value);
+					} elsif (ref($value) eq 'ARRAY') {
+						%{$self->{data}[-1]{$key}} = (%{$self->{data}[-1]{$key}}, @$value);
+					} else {
+						croak "The value of the rule return \%$key must be a hash or array ref!";
+					}
+				} else {
+					if (ref($value) eq 'HASH') {
+						$self->{data}[-1]{$key} = $value;
+					} elsif (ref($value) eq 'ARRAY') {
+						$self->{data}[-1]{$key} = {@$value};
+					} else {
+						croak "The value of the rule return \%$key must be a hash or array ref!";
+					}
+				}
+			} else {
+				warn "The attribute '$key' already exists for tag $self->{context}[-1].\n  old value: $self->{data}[-1]{$key}\n  new value: $value\n"
+					if ($self->{opt}{warnoverwrite} and exists $self->{data}[-1]{$key} and $self->{data}[-1]{$key} ne $value);
+				$self->{data}[-1]{$key} = $value;
+			}
+		}
+	}
+}
+
+sub _StartIgnore {
+	my ($self) = shift;
+	return sub {
+		$self->{ignore_level}++
+	}
+}
+
+sub _EndIgnore {
+	my ($self) = shift;
+	return sub {
+		return if --$self->{ignore_level};
+
+		$self->{parser}->setHandlers(@{$self->{normal_handlers}})
+	}
+}
+
+sub _add_content {
+	my ($hash, $value) = @_;
+	if (ref($value)) {
+		if (ref($hash->{_content})) {
+			# both are refs, push to @_content
+			push @{$hash->{_content}}, $value;
+		} elsif (exists($hash->{_content})) {
+			# result is ref, _content is not -> convert to an arrayref containing old _content and result
+			$hash->{_content} = [ $hash->{_content}, $value]
+		} else {
+			# result is ref, _content is not present
+			$hash->{_content} = [ $value]
+		}
+	} else {
+		if (ref($hash->{_content})) {
+			# _content is an arrayref, value is a string
+			if (ref $hash->{_content}[-1]) {
+				# the last element is a ref -> push
+				push @{$hash->{_content}}, $value;
+			} else {
+				# the last element is a string -> concatenate
+				$hash->{_content}[-1] .= $value;
+			}
+		} else {
+			# neither is ref, concatenate
+			$hash->{_content} .= $value;
+		}
+	}
+}
+
+=head1 METHODS
+
+=head2 parse
+
+	$parser->parse( $string [, $parameters]);
+	$parser->parse( $IOhandle [, $parameters]);
+
+Parses the XML in the string or reads and parses the XML from the opened IO handle,
+executes the rules as it encounters the closing tags and returns the resulting structure.
+
+The scalar or reference passed as the second parameter to the parse() method is assigned to
+$parser->{parameters} for the parsing of the file or string. Once the XML is parsed the key is
+deleted. This means that the $parser does not retain a reference to the $parameters after the parsing.
+
+=head2 parsestring
+
+	$parser->parsestring( $string [, $parameters]);
+
+Just an alias to ->parse().
+
+=head2 parsefile
+
+	$parser->parsefile( $filename [, $parameters]);
+
+Opens the specified file and parses the XML and executes the rules as it encounters
+the closing tags and returns the resulting structure.
+
+
+=head2 filter
+
+	$parser->filter( $string);
+	$parser->filter( $string, $OutputIOhandle [, $parameters]);
+	$parser->filter( $InputIOhandle, $OutputIOhandle [, $parameters]);
+	$parser->filter( $string, $OutputFilename [, $parameters]);
+	$parser->filter( $InputIOhandle, $OutputFilename [, $parameters]);
+	$parser->filter( $string, $StringReference [, $parameters]);
+	$parser->filter( $InputIOhandle, $StringReference [, $parameters]);
+
+Parses the XML in the string or reads and parses the XML from the opened IO handle,
+copies the tags that do not have a subroutine rule specified and do not occure under such a tag,
+executes the specified rules and prints the results to select()ed filehandle, $OutputFilename or
+$OutputIOhandle or stores them in the scalar referenced by $StringReference.
+
+The scalar or reference passed as the third parameter to the filter() method is assigned to
+$parser->{parameters} for the parsing of the file or string. Once the XML is parsed the key is
+deleted. This means that the $parser does not retain a reference to the $parameters after the parsing.
+
+=head2 filterstring
+
+	$parser->filterstring( ...);
+
+Just an alias to ->filter().
+
+=head2 filterfile
+
+	$parser->filterfile( $filename, $OutputIOhandle [, $parameters]);
+	$parser->filterfile( $filename, $OutputFilename [, $parameters]);
+
+Parses the XML in the specified file, copies the tags that do not have a subroutine rule specified
+and do not occure under such a tag, executes the specified rules and prints the results to select()ed
+filehandle, $OutputFilename or $OutputIOhandle or stores them in the scalar
+referenced by $StringReference.
+
+The scalar or reference passed as the third parameter to the filter() method is assigned to
+$parser->{parameters} for the parsing of the file or string. Once the XML is parsed the key is
+deleted. This means that the $parser does not retain a reference to the $parameters after the parsing.
+
+=cut
+
+sub escape_value {
+	my($self, $data, $level) = @_;
+
+	return '' unless(defined($data) and $data ne '');
+
+	if ($self->{opt}{output_encoding} ne $self->{opt}{encode}) {
+		$data = Encode::decode( $self->{opt}{encode}, $data) if $self->{opt}{encode};
+		$data = Encode::encode( $self->{opt}{output_encoding}, $data) if $self->{opt}{output_encoding};
+	}
+
+	$data =~ s/&/&amp;/sg;
+	$data =~ s/</&lt;/sg;
+	$data =~ s/>/&gt;/sg;
+	$data =~ s/"/&quot;/sg;
+
+	$level = $self->{opt}->{numericescape} unless defined $level;
+	return $data unless $level;
+
+	return $self->_numeric_escape($data, $level);
+}
+
+sub _numeric_escape {
+  my($self, $data, $level) = @_;
+
+  use utf8; # required for 5.6
+
+  if($self->{opt}->{numericescape} eq '2') {
+    $data =~ s/([^\x00-\x7F])/'&#' . ord($1) . ';'/gse;
+  }
+  else {
+    $data =~ s/([^\x00-\xFF])/'&#' . ord($1) . ';'/gse;
+  }
+
+  return $data;
+}
+
+=head2 escape_value
+
+	$parser->escape_value( $data [, $numericescape])
+
+This method escapes the $data for inclusion in XML, the $numericescape may be 0, 1 or 2
+and controls whether to convert 'high' (non ASCII) characters to XML entities.
+
+0 - default: no numeric escaping (OK if you're writing out UTF8)
+
+1 - only characters above 0xFF are escaped (ie: characters in the 0x80-FF range are not escaped), possibly useful with ISO8859-1 output
+
+2 - all characters above 0x7F are escaped (good for plain ASCII output)
+
+You can also specify the default value in the constructor
+
+	my $parser = XML::Rules->new(
+		...
+		NumericEscape => 2,
+	);
+
+=cut
+
+sub ToXML;*ToXML=\&toXML;
+sub toXML {
+	my ($self, $tag, $attrs, $no_close, $ident, $base) = @_;
+
+	my $prefix = (defined ($ident) ? "\n$base" : '');
+
+	$attrs = undef if (ref $attrs eq 'HASH' and ! %{$attrs}); # ->toXML( $tagname, {}, ...)
+
+	if ($tag eq '') {
+		if (! ref($attrs)) { # ->toXML( '', $string_content, ...)
+			return $self->escape_value($attrs);
+		} elsif (ref($attrs) eq 'ARRAY') {
+			if (@$attrs) {
+				return join( '', map {
+					if (!ref($_)) {
+						$self->escape_value($_)
+					} elsif (ref($_) eq 'ARRAY' and @$_ == 2) {
+						$self->toXML($_->[0], $_->[1])
+					} else {
+						croak "The content in XML::Rules->ToXML( '', here) must be a string or an arrayref containing strings and two element arrayrefs!";
+					}
+				} @$attrs);
+			} else {
+				return "<$attrs/>"
+			}
+		}
+	}
+
+	if (! ref($attrs)) { # ->toXML( $tagname, $string_content, ...)
+		if ($no_close) {
+			return "<$tag>" . $self->escape_value($attrs);
+		} elsif (! defined $attrs) {
+			return "<$tag/>";
+		} else {
+			return "<$tag>" . $self->escape_value($attrs) . "</$tag>";
+		}
+	} elsif (ref($attrs) eq 'ARRAY') {
+		return join( $prefix, map $self->toXML($tag, $_, 0, $ident, $base), @$attrs);
+	}
+
+
+	my $content = $attrs->{_content};
+	my $result = "<$tag";
+	my $subtags = '';
+	foreach my $key (sort keys %$attrs) {
+		next if $key =~ /^:/ or $key eq '_content';
+		if (ref $attrs->{$key}) {
+			if (ref $attrs->{$key} eq 'ARRAY') {
+				if (@{$attrs->{$key}}) {
+					foreach my $subtag (@{$attrs->{$key}}) {
+						$subtags .= $prefix . $ident . $self->toXML($key, $subtag, 0, $ident, $base.$ident);
+					}
+				} else {
+					$subtags .= $prefix . $ident . "<$key/>";
+				}
+			} elsif (ref $attrs->{$key} eq 'HASH') {
+				$subtags .= $prefix . $ident . $self->toXML($key, $attrs->{$key}, 0, $ident, $base.$ident)
+			} else {
+				croak(ref($attrs->{$key}) . " attributes not supported in XML::Rules->toXML()!");
+			}
+		} else {
+			$result .= qq{ $key="} . $self->escape_value($attrs->{$key}) . qq{"};
+		}
+	}
+	if (! defined $content and $subtags eq '') {
+		if ($no_close) {
+			return $result.">";
+		} else {
+			return $result."/>";
+		}
+
+	} elsif (!ref($content)) { # content is a string, not an array of strings and subtags
+		if ($no_close) {
+			return "$result>$subtags" . $self->escape_value($content);
+		} elsif ($content eq '' and $subtags ne '') {
+			return "$result>$subtags$prefix</$tag>";
+		} else {
+			return "$result>$subtags" . $self->escape_value($content) ."</$tag>";
+		}
+
+	} elsif (ref($content) eq 'ARRAY') {
+		$result .= ">$subtags";
+		foreach my $snippet (@$content) {
+			if (!ref($snippet)) {
+				$result .= $self->escape_value($snippet);
+			} elsif (ref($snippet) eq 'ARRAY') {
+				if (@$snippet == 2) {
+					$result .= $self->toXML($snippet->[0], $snippet->[1]);
+				} else {
+					croak("Arrays in _content must be in format [\$tagname => \\\%attrs, ...] in XML::Rules->toXML()!");
+				}
+			} else {
+				croak(ref($snippet) . " not supported in _content in XML::Rules->toXML()!");
+			}
+		}
+		if ($no_close) {
+			return $result;
+		} else {
+			return $result."</$tag>";
+		}
+	} else {
+		croak(ref($content) . " _content not supported in XML::Rules->toXML()!");
+	}
+}
+
+sub parentsToXML {
+	my ($self, $level) = @_;
+	my $tag_names = $self->{context};
+	my $tag_attrs = $self->{data};
+
+	$level = scalar(@$tag_names) unless $level;
+
+	my $result = '';
+	for (my $i = -1; -$i <= $level; $i--) {
+		$result = $self->toXML( ${$tag_names}[$i], ${$tag_attrs}[$i], 1) . $result;
+	}
+	return $result;
+}
+
+sub closeParentsToXML {
+	my ($self, $level) = @_;
+	my $tag_names = $self->{context};
+
+	if ($level) {
+		return '</' . join( '></', (reverse(@{$tag_names}))[0..$level-1]) . '>';
+	} else {
+		return '</' . join( '></', reverse(@$tag_names)) . '>';
+	}
+}
+
+=head2 toXML / ToXML
+
+	$xml = $parser->toXML( $tagname, \%attrs[, $do_not_close, $ident, $base])
+
+You may use this method to convert the datastructures created by parsing the XML into the XML format.
+Not all data structures may be printed! I'll add more docs later, for now please do experiment.
+
+The $ident and $base, if defined, turn on and control the pretty-printing. The $ident specifies the character(s)
+used for one level of identation, the base contains the identation of the current tag. That is if you want to include the data inside of
+
+	<data>
+		<some>
+			<subtag>$here</subtag>
+		</some>
+	</data>
+
+you will call
+
+	$parser->toXML( $tagname, \%attrs, 0, "\t", "\t\t\t");
+
+The method does NOT validate that the $ident and $base are whitespace only, but of course if it's not you end up with invalid
+XML. Newlines are added only before the start tag and (if the tag has only child tags and no content) before the closing tag,
+but not after the closing tag! Newlines are added even if the $ident is an empty string.
+
+=head2 parentsToXML
+
+	$xml = $parser->parentsToXML( [$level])
+
+Prints all or only the topmost $level ancestor tags, including the attributes and content (parsed so far),
+but without the closing tags. You may use this to print the header of the file you are parsing,
+followed by calling toXML() on a structure you build and then by closeParentsToXML() to close
+the tags left opened by parentsToXML(). You most likely want to use the style => 'filter' option
+for the constructor instead.
+
+=head2 closeParentsToXML
+
+	$xml = $parser->closeParentsToXML( [$level])
+
+Prints the closing tags for all or the topmost $level ancestor tags of the one currently processed.
+
+=head2 paths2rules
+
+	my $parser = XML::Rules->new(
+		rules => paths2rules {
+			'/root/subtag/tag' => sub { ...},
+			'/root/othertag/tag' => sub {...},
+			'tag' => sub{ ... the default code for this tag ...},
+			...
+		}
+	);
+
+This helper function converts a hash of "somewhat xpath-like" paths and subs/rules into the format required by the module.
+Due to backwards compatibility and efficiency I can't directly support paths in the rules and the direct syntax for their
+specification is a bit awkward. So if you need the paths and not the regexps, you may use this helper instead of:
+
+	my $parser = XML::Rules->new(
+		rules => {
+			'tag' => [
+				'/root/subtag' => sub { ...},
+				'/root/othertag' => sub {...},
+				sub{ ... the default code for this tag ...},
+			],
+			...
+		}
+	);
+
+=cut
+
+sub paths2rules {
+	my ($paths) = @_;
+
+	my %rules;
+	while ( my ($tag, $val) = each %$paths) {
+
+		if ($tag =~ m{^(.*)/(.*)$}) {
+			my ($path, $tagname) = ($1, $2);
+
+			if (exists $rules{$tagname} and ref($rules{$tagname}) eq 'ARRAY') {
+				if (@{$rules{$tagname}} % 2) {
+					push @{$rules{$tagname}}, $path, $val;
+				} else {
+					splice @{$rules{$tagname}}, -1, 0, $path, $val;
+				}
+			} else {
+				$rules{$tagname} = [ $path => $val]
+			}
+
+		} elsif (exists $rules{$tag} and ref($rules{$tag}) eq 'ARRAY') {
+			push @{$rules{$tag}}, $val;
+		} else {
+			$rules{$tag} = $val
+		}
+	}
+
+	return \%rules;
+}
+
+=head2 return_nothing
+
+Stop parsing the XML, forget any data we already have and return from the $parser->parse().
+This is only supposed to be used within rules and may be called both as a method and as
+an ordinary function (it's not exported).
+
+=head2 skip_rest
+
+Stop parsing the XML and return whatever data we already have from the $parser->parse().
+The rules for the currently opened tags are evaluated as if the XML contained all
+the closing tags in the right order.
+
+These two work via raising an exception, the exception is caught within the $parser->parse() and do not propagate outside.
+It's also safe to raise any other exception within the rules, the exception will be caught as well, the internal state of the $parser object
+is cleaned and the exception is rethrown.
+
+=head2 inferRulesFromExample
+
+	Dumper(XML::Rules::inferRulesFromExample( $fileOrXML, $fileOrXML, $fileOrXML, ...)
+	Dumper(XML::Rules->inferRulesFromExample( $fileOrXML, $fileOrXML, $fileOrXML, ...)
+	Dumper($parser->inferRulesFromExample( $fileOrXML, $fileOrXML, $fileOrXML, ...)
+
+The subroutine parses the listed files and infers the rules that would produce the minimal, but complete datastructure.
+It finds out what tags may be repeated, whether they contain text content, attributes etc. You may want to give
+the subroutine several examples to make sure it knows about all possibilities. You should use this once and store
+the generated rules in your script or even take this as the basis of a more specific set of rules.
+
+=cut
+
+sub inferRulesFromExample {
+	shift(@_) if $_[0] eq 'XML::Rules' or ref($_[0]);
+	my @files = @_;
+
+	my %rules;
+
+	my $parser = XML::Rules->new(
+		namespaces => { '*' => ''},
+		rules => {
+			_default => sub {
+				my ($tag, $attrs, $context, $parent_data, $parser) = @_;
+				my $repeated = (exists $parent_data->[-1] and exists $parent_data->[-1]{$tag});
+				my $has_content = (exists $attrs->{_content});
+				my $has_children = grep ref($_) eq 'HASH', values %$attrs;
+				my $has_attr = grep {$_ ne '_content' and !ref($attrs->{$_})} keys %$attrs;
+
+				my $rule = do {
+					if ($repeated) {
+						if ($has_content) {
+							if ($has_attr or $has_children) {
+								'as array'
+							} else {
+								'content array'
+							}
+						} else {
+							if ($has_attr or $has_children) {
+								'as array no content'
+							} else {
+								'content array'
+							}
+						}
+					} else {
+						if ($has_content) {
+							if ($has_attr or $has_children) {
+								'as is'
+							} else {
+								'content'
+							}
+						} else {
+							if ($has_attr or $has_children) {
+								'no content'
+							} else {
+								'content'
+							}
+						}
+					}
+				};
+
+				if (not exists $rules{$tag}) {
+					$rules{$tag} = $rule
+				} elsif($rules{$tag} ne $rule) {
+					# we've already seen the tag and it had different type
+					if ($rules{$tag} eq 'raw extended array') {
+					} elsif ($rule eq 'raw extended array') {
+						$rules{$tag} = 'raw extended array';
+					} elsif ($rules{$tag} eq 'raw extended' and $rule =~ /array/
+						or $rule eq 'raw extended' and $rules{$tag} =~ /array/) {
+						$rules{$tag} = 'raw extended array'
+					} elsif ($rules{$tag} eq 'as array' or $rule eq 'as array') {
+						$rules{$tag} = 'as array'
+					} elsif ($rules{$tag} eq 'content array' and $rule eq 'content'
+						or $rule eq 'content array' and $rules{$tag} eq 'content') {
+						$rules{$tag} = 'content array'
+					} elsif ($rules{$tag} eq 'content array' and $rule eq 'as array no content'
+						or $rule eq 'content array' and $rules{$tag} eq 'as array no content') {
+						$rules{$tag} = 'as array'
+					} elsif ($rules{$tag} eq 'content array' and $rule eq 'as is'
+						or $rule eq 'content array' and $rules{$tag} eq 'as is') {
+						$rules{$tag} = 'as array'
+					} elsif ($rules{$tag} eq 'content array' and $rule eq 'no content'
+						or $rule eq 'content array' and $rules{$tag} eq 'no content') {
+						$rules{$tag} = 'as array'
+					} elsif ($rules{$tag} eq 'as array no content' and $rule eq 'as is'
+						or $rule eq 'as array no content' and $rules{$tag} eq 'as is') {
+						$rules{$tag} = 'as array'
+					} elsif ($rules{$tag} eq 'as array no content' and $rule eq 'content'
+						or $rule eq 'as array no content' and $rules{$tag} eq 'content') {
+						$rules{$tag} = 'as array'
+					} elsif ($rules{$tag} eq 'as array no content' and $rule eq 'no content'
+						or $rule eq 'as array no content' and $rules{$tag} eq 'no content') {
+						$rules{$tag} = 'as array no content'
+					} elsif ($rules{$tag} eq 'as is' and ($rule eq 'no content' or $rule eq 'content')
+						or $rule eq 'as is' and ($rules{$tag} eq 'no content' or $rules{$tag} eq 'content')) {
+						$rules{$tag} = 'as is'
+					} elsif ($rules{$tag} eq 'content' and $rule eq 'no content'
+						or $rule eq 'content' and $rules{$tag} eq 'no content') {
+						$rules{$tag} = 'as is'
+					} else {
+						die "Unexpected combination of rules: old=$rules{$tag}, new=$rule for tag $tag\n";
+					}
+				}
+
+				if ($has_content and $has_children) { # the tag contains both text content and subtags!, need to use the raw extended rules
+					foreach my $child (grep ref($attrs->{$_}) eq 'HASH', keys %$attrs) {
+						next if $rules{$child} =~ /^raw extended/;
+						if ($rules{$child} =~ /array/) {
+							$rules{$child} = 'raw extended array'
+						} else {
+							$rules{$child} = 'raw extended'
+						}
+					}
+				}
+				return $tag => {};
+			}
+		},
+		stripspaces => 7,
+	);
+
+	for (@files) {
+		eval {
+			if (! ref($_) and $_ !~ /\n/ and $_ !~ /^\s*</) {
+				$parser->parsefile($_);
+			} else {
+				$parser->parse($_);
+			}
+		} or croak "Error parsing $_: $@\n";
+	}
+
+	my %short_rules;
+	foreach my $tag (sort keys %rules) {
+		push @{$short_rules{$rules{$tag}}}, $tag
+	}
+
+	foreach my $tags (values %short_rules) {
+		$tags = join ',', @$tags;
+	}
+	%short_rules = reverse %short_rules;
+
+	return \%short_rules;
+}
+
+=head2 inferRulesFromDTD
+
+	Dumper(XML::Rules::inferRulesFromDTD( $DTDfile, [$enableExtended]))
+	Dumper(XML::Rules->inferRulesFromDTD( $DTDfile, [$enableExtended]))
+	Dumper($parser->inferRulesFromDTD( $DTDfile, [$enableExtended]))
+
+The subroutine parses the DTD and infers the rules that would produce the minimal, but complete datastructure.
+It finds out what tags may be repeated, whether they contain text content, attributes etc. You may use this
+each time you are about to parse the XML, once and store the generated rules in your script or even take this
+as the basis of a more specific set of rules.
+
+With the second parameter set to a true value, the tags included in a mixed content will use the "raw extended"
+or "raw extended array" types instead of just "raw". This makes sure the tag data both stay at the right place in
+the content and are accessible easily from the parent tag's atrribute hash.
+
+This subroutine requires the XML::DTDParser module!
+
+=cut
+
+sub inferRulesFromDTD {
+	require XML::DTDParser;
+
+	my ($DTDfile, $enable_extended) = @_;
+
+	my $DTD = XML::DTDParser::ParseDTDFile($DTDfile);
+
+	my $has_mixed = 0;
+	foreach my $tag (values %$DTD) {
+		$tag->{is_mixed} = (($tag->{content} and $tag->{children}) ? 1 : 0)
+		 and $has_mixed = 1;
+	}
+
+	my %settings;
+	foreach my $tagname (keys %$DTD) {
+		my $tag = $DTD->{$tagname};
+
+		my $repeated = ($tag->{option} =~ /^[+*]$/ ? 1 : 0);
+		my $has_content = $tag->{content};
+
+		my $in_mixed = grep {$DTD->{$_}{is_mixed}} @{$tag->{parent}};
+
+		if ($in_mixed) {
+			if ($enable_extended) {
+				if ($repeated) {
+					$settings{$tagname} = "raw extended array"
+				} else {
+					$settings{$tagname} = "raw extended"
+				}
+			} else {
+				$settings{$tagname} = "raw"
+			}
+		} else {
+			if (exists $DTD->{attributes} or exists $tag->{children}) {
+				my @ids ;
+				if (exists $DTD->{attributes}) {
+					@ids = grep {$DTD->{attributes}{$_}[0] eq 'ID' and $DTD->{attributes}{$_}[0] eq '#REQUIRED'} keys %{$DTD->{attributes}};
+				}
+				if (scalar(@ids) == 1) {
+					if ($has_content) {
+						$settings{$tagname} = "by $ids[0]"
+					} else {
+						$settings{$tagname} = "no content by $ids[0]"
+					}
+				} else {
+					if ($has_content) {
+						if ($repeated) {
+							$settings{$tagname} = "as array"
+						} else {
+							$settings{$tagname} = "as is"
+						}
+					} else {
+						if ($repeated) {
+							$settings{$tagname} = "as array no content"
+						} else {
+							$settings{$tagname} = "no content"
+						}
+					}
+				}
+			} elsif ($repeated) {
+				$settings{$tagname} = "content array"
+			} else {
+				$settings{$tagname} = "content array"
+			}
+		}
+	}
+
+#	use Data::Dumper;
+#	print Dumper(\%settings);
+
+	my %compressed;
+	{
+		my %tmp;
+		while (my ($tag, $option) = each %settings) {
+			push @{$tmp{$option}}, $tag;
+		}
+
+		while (my ($option, $tags) = each %tmp) {
+			$compressed{join ',', @$tags} = $option
+		}
+	}
+
+	if ($has_mixed) {
+		$compressed{"#stripspaces"} = 0;
+	} else {
+		$compressed{"#stripspaces"} = 7;
+	}
+
+	return \%compressed;
+}
+
+=head1 Properties
+
+=head2 parameters
+
+You can pass a parameter (scalar or reference) to the parse...() or filter...() methods, this parameter
+is later available to the rules as $parser->{parameters}. The module will never use this parameter for
+any other purpose so you are free to use it for any purposes provided that you expect it to be reset by
+each call to parse...() or filter...() first to the passed value and then, after the parsing is complete, to undef.
+
+=head2 pad
+
+The $parser->{pad} key is specificaly reserved by the module as a place where the module users can
+store their data. The module doesn't and will not use this key in any way, doesn't set or reset it under any
+circumstances. If you need to share some data between the rules and do not want to use the structure built
+by applying the rules you are free to use this key.
+
+You should refrain from modifying or accessing other properties of the XML::Rules object!
+
+=head1 Namespace support
+
+By default the module doesn't handle namespaces in any way, it doesn't check for
+xmlns or xmlns:alias attributes and it doesn't strip or mangle the namespace aliases
+in tag or attribute names. This means that if you know for sure what namespace
+aliases will be used you can set up rules for tags including the aliases and unless
+someone decides to use a different alias or makes use of the default namespace
+change your script will work.
+
+If you do specify any namespace to alias mapping in the constructor it does
+start processing the namespace stuff. The xmlns and xmlns:alias attributes
+are stripped from the datastructures and the aliases are transformed from
+whatever the XML author decided to use to whatever your namespace mapping
+specifies. Aliases are also added to all tags that belong to a default namespace.
+
+Assuming the constructor parameters contain
+
+	namespaces => {
+		'http://my.namespaces.com/foo' => 'foo',
+		'http://my.namespaces.com/bar' => 'bar',
+	}
+
+and the XML looks like this:
+
+	<root>
+		<Foo xmlns="http://my.namespaces.com/foo">
+			<subFoo>Hello world</subfoo>
+		</Foo>
+		<other xmlns:b="http://my.namespaces.com/bar">
+			<b:pub>
+				<b:name>NaRuzku</b:name>
+				<b:address>at any crossroads</b:address>
+				<b:desc>Fakt <b>desnej</b> pajzl.</b:desc>
+			</b:pub>
+		</other>
+	</root>
+
+then the rules wil be called as if the XML looked like this:
+
+	<root>
+		<foo:Foo>
+			<foo:subFoo>Hello world</foo:subfoo>
+		</foo:Foo>
+		<other>
+			<bar:pub>
+				<bar:name>NaRuzku</bar:name>
+				<bar:address>at any crossroads</bar:address>
+				<bar:desc>Fakt <b>desnej</b> pajzl.</bar:desc>
+			</bar:pub>
+		</other>
+	</root>
+
+
+This means that the namespace handling will only normalize the aliases used.
+
+It is possible to specify an empty alias, so eg. in case you are processing a SOAP XML
+and know the tags defined by SOAP do not colide with the tags in the enclosed XML
+you may simplify the parsing by removing all namespace aliases.
+
+If the XML references a namespace not present in the map you will get a warning
+and the alias used for that namespace will be left intact! If you do not want to get the warnings specify
+a namespace with URI "*".
+
+
+=head1 HOW TO USE
+
+You may view the module either as a XML::Simple on steriods and use it to build a data structure
+similar to the one produced by XML::Simple with the added benefit of being able
+to specify what tags or attributes to ignore, when to take just the content, what to store as an array etc.
+
+Or you could view it as yet another event based XML parser that differs from all the others only in one thing.
+It stores the data for you so that you do not have to use globals or closures and wonder where to attach
+the snippet of data you just received onto the structure you are building.
+
+You can use it in a way similar to XML::Twig with simplify(), specify the rules to transform the lower
+level tags into a XML::Simple like (simplify()ed) structure and then handle the structure in the rule for
+the tag(s) you'd specify in XML::Twig's twig_roots.
+
+=head1 Unrelated tricks
+
+If you need to parse a XML file without the top-most tag (something that each and any sane person would allow,
+but the XML comitee did not), you can parse
+
+  <!DOCTYPE doc [<!ENTITY real_doc SYSTEM "$the_file_name">]><doc>&real_doc;</doc>
+
+instead.
+
+=head1 AUTHOR
+
+Jan Krynicky, C<< <Jenda at CPAN.org> >>
+
+=head1 BUGS
+
+Please report any bugs or feature requests to
+C<bug-xml-rules at rt.cpan.org>, or through the web interface at
+L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=XML-Rules>.
+I will be notified, and then you'll automatically be notified of progress on
+your bug as I make changes.
+
+=head1 SUPPORT
+
+You can find documentation for this module with the perldoc command.
+
+    perldoc XML::Rules
+
+You can also look for information at:
+
+=over 4
+
+=item * AnnoCPAN: Annotated CPAN documentation
+
+L<http://annocpan.org/dist/XML-Rules>
+
+=item * CPAN Ratings
+
+L<http://cpanratings.perl.org/d/XML-Rules>
+
+=item * RT: CPAN's request tracker
+
+L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=XML-Rules>
+
+=item * Search CPAN
+
+L<http://search.cpan.org/dist/XML-Rules>
+
+=item * PerlMonks
+
+Please see L<http://www.perlmonks.org/?node_id=581313> or
+L<http://www.perlmonks.org/?node=XML::Rules> for discussion.
+
+=back
+
+=head1 SEE ALSO
+
+L<XML::Twig>, L<XML::LibXML>, L<XML::Pastor>
+
+=head1 ACKNOWLEDGEMENTS
+
+The escape_value() method is taken with minor changes from XML::Simple.
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 2006-2007 Jan Krynicky, all rights reserved.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=cut
+
+1; # End of XML::Rules
Index: /gsdl/stable/perllib/cpan/XML/XPath.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath.pm	(revision 20131)
@@ -0,0 +1,553 @@
+# $Id$
+
+package XML::XPath;
+
+use strict;
+use vars qw($VERSION $AUTOLOAD $revision);
+
+$VERSION = '1.13';
+
+$XML::XPath::Namespaces = 1;
+$XML::XPath::Debug = 0;
+
+use XML::XPath::XMLParser;
+use XML::XPath::Parser;
+use IO::File;
+
+# For testing
+#use Data::Dumper;
+#$Data::Dumper::Indent = 1;
+
+# Parameters for new()
+my @options = qw(
+        filename
+        parser
+        xml
+        ioref
+        context
+        );
+
+sub new {
+    my $proto = shift;
+    my $class = ref($proto) || $proto;
+
+    my(%args);
+    # Try to figure out what the user passed
+    if ($#_ == 0) { # passed a scalar
+        my $string = $_[0];
+        if ($string =~ m{<.*?>}s) { # it's an XML string
+            $args{'xml'} = $string;
+        } elsif (ref($string)) {    # read XML from file handle
+            $args{'ioref'} = $string;
+        } elsif ($string eq '-') {  # read XML from stdin
+            $args{'ioref'} = IO::File->new($string);
+        } else {                    # read XML from a file
+            $args{'filename'} = $string;
+        }
+    } else {        # passed a hash or hash reference
+        # just pass the parameters on to the XPath constructor
+        %args = ((ref($_[0]) eq "HASH") ? %{$_[0]} : @_);
+    }
+
+    if ($args{filename} && (!-e $args{filename} || !-r $args{filename})) {
+        die "Cannot open file '$args{filename}'";
+    }
+    my %hash = map(( "_$_" => $args{$_} ), @options);
+    $hash{path_parser} = XML::XPath::Parser->new();
+    return bless \%hash, $class;
+}
+
+sub find {
+    my $self = shift;
+    my $path = shift;
+    my $context = shift;
+    die "No path to find" unless $path;
+    
+    if (!defined $context) {
+        $context = $self->get_context;
+    }
+    if (!defined $context) {
+        # Still no context? Need to parse...
+        my $parser = XML::XPath::XMLParser->new(
+                filename => $self->get_filename,
+                xml => $self->get_xml,
+                ioref => $self->get_ioref,
+                parser => $self->get_parser,
+                );
+        $context = $parser->parse;
+        $self->set_context($context);
+#        warn "CONTEXT:\n", Data::Dumper->Dumpxs([$context], ['context']);
+    }
+    
+    my $parsed_path = $self->{path_parser}->parse($path);
+#    warn "\n\nPATH: ", $parsed_path->as_string, "\n\n";
+    
+#    warn "evaluating path\n";
+    return $parsed_path->evaluate($context);
+}
+
+# sub memsize {
+#     print STDERR @_, "\t";
+#     open(FH, '/proc/self/status');
+#     while(<FH>) {
+#         print STDERR $_ if /^VmSize/;
+#     }
+#     close FH;
+# }
+# 
+sub findnodes {
+    my $self = shift;
+    my ($path, $context) = @_;
+    
+    my $results = $self->find($path, $context);
+    
+    if ($results->isa('XML::XPath::NodeSet')) {
+        return wantarray ? $results->get_nodelist : $results;
+#        return $results->get_nodelist;
+    }
+    
+#    warn("findnodes returned a ", ref($results), " object\n") if $XML::XPath::Debug;
+    return wantarray ? () : XML::XPath::NodeSet->new();
+}
+
+sub matches {
+    my $self = shift;
+    my ($node, $path, $context) = @_;
+
+    my @nodes = $self->findnodes($path, $context);
+
+    if (grep { "$node" eq "$_" } @nodes) {
+        return 1;
+    }
+    return;
+}
+
+sub findnodes_as_string {
+    my $self = shift;
+    my ($path, $context) = @_;
+    
+    my $results = $self->find($path, $context);
+    
+    if ($results->isa('XML::XPath::NodeSet')) {
+        return join('', map { $_->toString } $results->get_nodelist);
+    }
+    elsif ($results->isa('XML::XPath::Node')) {
+        return $results->toString;
+    }
+    else {
+        return XML::XPath::Node::XMLescape($results->value);
+    }
+}
+
+sub findvalue {
+    my $self = shift;
+    my ($path, $context) = @_;
+    
+    my $results = $self->find($path, $context);
+    
+    if ($results->isa('XML::XPath::NodeSet')) {
+        return $results->to_literal;
+    }
+    
+    return $results;
+}
+
+sub exists
+{
+    my $self = shift;
+    my ($path, $context) = @_;
+    $path = '/' if (!defined $path);
+    my @nodeset = $self->findnodes($path, $context);
+    return 1 if (scalar( @nodeset ));
+    return 0;
+}
+
+sub getNodeAsXML {
+  my $self = shift;
+  my $node_path = shift;
+  $node_path = '/' if (!defined $node_path);
+  if (ref($node_path)) {
+    return $node_path->as_string();
+  } else {
+    return $self->findnodes_as_string($node_path);
+  }
+}
+
+sub getNodeText {
+  my $self = shift;
+  my $node_path = shift;
+  if (ref($node_path)) {
+    return $node_path->string_value();
+  } else {
+    return $self->findvalue($node_path);
+  }
+}
+
+sub setNodeText {
+  my $self = shift;
+  my($node_path, $new_text) = @_;
+  my $nodeset = $self->findnodes($node_path);
+  return undef if (!defined $nodeset); # could not find node
+  my @nodes = $nodeset->get_nodelist;
+  if ($#nodes < 0) {
+    if ($node_path =~ m|/@([^/]+)$|) {
+      # attribute not found, so try to create it
+      my $parent_path = $`;
+      my $attr = $1;
+      $nodeset = $self->findnodes($parent_path);
+      return undef if (!defined $nodeset); # could not find node
+      foreach my $node ($nodeset->get_nodelist) {
+        my $newnode = XML::XPath::Node::Attribute->new($attr, $new_text);
+        return undef if (!defined $newnode); # could not create new node
+        $node->appendAttribute($newnode);
+      }
+    } else {
+      return undef; # could not find node
+    }
+  }
+  foreach my $node (@nodes) {
+    if ($node->getNodeType == XML::XPath::Node::ATTRIBUTE_NODE) {
+      $node->setNodeValue($new_text);
+    } else {
+      foreach my $delnode ($node->getChildNodes()) {
+        $node->removeChild($delnode);
+      }
+      my $newnode = XML::XPath::Node::Text->new($new_text);
+      return undef if (!defined $newnode); # could not create new node
+      $node->appendChild($newnode);
+    }
+  }
+  return 1;
+}
+
+sub createNode {
+  my $self = shift;
+  my($node_path) = @_;
+  my $path_steps = $self->{path_parser}->parse($node_path);
+  my @path_steps = ();
+  foreach my $step (@{$path_steps->get_lhs()}) {
+    my $string = $step->as_string();
+    push(@path_steps, $string) if (defined $string && $string ne "");
+  }
+  my $prev_node = undef;
+  my $nodeset = undef;
+  my $nodes = undef;
+  my $p = undef;
+  my $test_path = "";
+  # Start with the deepest node, working up the path (right to left),
+  # trying to find a node that exists.
+  for ($p = $#path_steps; $p >= 0; $p--) {
+    my $path = $path_steps[$p];
+    $test_path = "(/" . join("/", @path_steps[0..$p]) . ")";
+    $nodeset = $self->findnodes($test_path);
+    return undef if (!defined $nodeset); # error looking for node
+    $nodes = $nodeset->size;
+    return undef if ($nodes > 1); # too many paths - path not specific enough
+    if ($nodes == 1) { # found a node -- need to create nodes below it
+      $prev_node = $nodeset->get_node(1);
+      last;
+    }
+  }
+  if (!defined $prev_node) {
+    my @root_nodes = $self->findnodes('/')->get_nodelist();
+    $prev_node = $root_nodes[0];
+  }
+  # We found a node that exists, or we'll start at the root.
+  # Create all lower nodes working left to right along the path.
+  for ($p++ ; $p <= $#path_steps; $p++) {
+    my $path = $path_steps[$p];
+    my $newnode = undef;
+    my($axis,$name) = ($path =~ /^(.*?)::(.*)$/);
+    if ($axis =~ /^child$/i) {
+      $newnode = XML::XPath::Node::Element->new($name);
+      return undef if (!defined $newnode); # could not create new node
+      $prev_node->appendChild($newnode);
+    } elsif ($axis =~ /^attribute$/i) {
+      $newnode = XML::XPath::Node::Attribute->new($name, "");
+      return undef if (!defined $newnode); # could not create new node
+      $prev_node->appendAttribute($newnode);
+    }
+    $prev_node = $newnode;
+  }
+  return $prev_node;
+}
+
+sub get_filename {
+    my $self = shift;
+    $self->{_filename};
+}
+
+sub set_filename {
+    my $self = shift;
+    $self->{_filename} = shift;
+}
+
+sub get_parser {
+    my $self = shift;
+    $self->{_parser};
+}
+
+sub set_parser {
+    my $self = shift;
+    $self->{_parser} = shift;
+}
+
+sub get_xml {
+    my $self = shift;
+    $self->{_xml};
+}
+
+sub set_xml {
+    my $self = shift;
+    $self->{_xml} = shift;
+}
+
+sub get_ioref {
+    my $self = shift;
+    $self->{_ioref};
+}
+
+sub set_ioref {
+    my $self = shift;
+    $self->{_ioref} = shift;
+}
+
+sub get_context {
+    my $self = shift;
+    $self->{_context};
+}
+
+sub set_context {
+    my $self = shift;
+    $self->{_context} = shift;
+}
+
+sub cleanup {
+    my $self = shift;
+    if ($XML::XPath::SafeMode) {
+        my $context = $self->get_context;
+        return unless $context;
+        $context->dispose;
+    }
+}
+
+sub set_namespace {
+    my $self = shift;
+    my ($prefix, $expanded) = @_;
+    $self->{path_parser}->set_namespace($prefix, $expanded);
+}
+
+sub clear_namespaces {
+    my $self = shift;
+    $self->{path_parser}->clear_namespaces();
+}
+
+1;
+__END__
+
+=head1 NAME
+
+XML::XPath - a set of modules for parsing and evaluating XPath statements
+
+=head1 DESCRIPTION
+
+This module aims to comply exactly to the XPath specification at
+http://www.w3.org/TR/xpath and yet allow extensions to be added in the
+form of functions. Modules such as XSLT and XPointer may need to do
+this as they support functionality beyond XPath.
+
+=head1 SYNOPSIS
+
+    use XML::XPath;
+    use XML::XPath::XMLParser;
+    
+    my $xp = XML::XPath->new(filename => 'test.xhtml');
+    
+    my $nodeset = $xp->find('/html/body/p'); # find all paragraphs
+    
+    foreach my $node ($nodeset->get_nodelist) {
+        print "FOUND\n\n", 
+            XML::XPath::XMLParser::as_string($node),
+            "\n\n";
+    }
+
+=head1 DETAILS
+
+There's an awful lot to all of this, so bear with it - if you stick it
+out it should be worth it. Please get a good understanding of XPath
+by reading the spec before asking me questions. All of the classes
+and parts herein are named to be synonimous with the names in the
+specification, so consult that if you don't understand why I'm doing
+something in the code.
+
+=head1 API
+
+The API of XML::XPath itself is extremely simple to allow you to get
+going almost immediately. The deeper API's are more complex, but you
+shouldn't have to touch most of that.
+
+=head2 new()
+
+This constructor follows the often seen named parameter method call.
+Parameters you can use are: filename, parser, xml, ioref and context.
+The filename parameter specifies an XML file to parse. The xml
+parameter specifies a string to parse, and the ioref parameter
+specifies an ioref to parse. The context option allows you to 
+specify a context node. The context node has to be in the format 
+of a node as specified in L<XML::XPath::XMLParser>. The 4 parameters
+filename, xml, ioref and context are mutually exclusive - you should
+only specify one (if you specify anything other than context, the
+context node is the root of your document).
+The parser option allows you to pass in an already prepared 
+XML::Parser object, to save you having to create more than one
+in your application (if, for example, you're doing more than just XPath).
+
+    my $xp = XML::XPath->new( context => $node );
+
+It is very much recommended that you use only 1 XPath object throughout 
+the life of your application. This is because the object (and it's sub-objects)
+maintain certain bits of state information that will be useful (such
+as XPath variables) to later calls to find(). It's also a good idea because
+you'll use less memory this way.
+
+=head2 I<nodeset> = find($path, [$context])
+
+The find function takes an XPath expression (a string) and returns either an
+XML::XPath::NodeSet object containing the nodes it found (or empty if
+no nodes matched the path), or one of XML::XPath::Literal (a string),
+XML::XPath::Number, or XML::XPath::Boolean. It should always return 
+something - and you can use ->isa() to find out what it returned. If you
+need to check how many nodes it found you should check $nodeset->size.
+See L<XML::XPath::NodeSet>. An optional second parameter of a context
+node allows you to use this method repeatedly, for example XSLT needs
+to do this.
+
+=head2 findnodes($path, [$context])
+
+Returns a list of nodes found by $path, optionally in context $context. 
+In scalar context returns an XML::XPath::NodeSet object.
+
+=head2 findnodes_as_string($path, [$context])
+
+Returns the nodes found reproduced as XML. The result is not guaranteed
+to be valid XML though.
+
+=head2 findvalue($path, [$context])
+
+Returns either a C<XML::XPath::Literal>, a C<XML::XPath::Boolean> or a
+C<XML::XPath::Number> object. If the path returns a NodeSet,
+$nodeset->to_literal is called automatically for you (and thus a
+C<XML::XPath::Literal> is returned). Note that
+for each of the objects stringification is overloaded, so you can just
+print the value found, or manipulate it in the ways you would a normal
+perl value (e.g. using regular expressions).
+
+=head2 exists($path, [$context])
+
+Returns true if the given path exists.
+
+=head2 matches($node, $path, [$context])
+
+Returns true if the node matches the path (optionally in context $context).
+
+=head2 getNodeText($path)
+
+Returns the text string for a particular XML node.  Returns a string,
+or undef if the node doesn't exist.
+
+=head2 setNodeText($path, $text)
+
+Sets the text string for a particular XML node.  The node can be an
+element or an attribute.  If the node to be set is an attribute, and
+the attribute node does not exist, it will be created automatically.
+
+=head2 createNode($path)
+
+Creates the node matching the path given.  If part of the path given, or
+all of the path do not exist, the necessary nodes will be created
+automatically.
+
+=head2 set_namespace($prefix, $uri)
+
+Sets the namespace prefix mapping to the uri.
+
+Normally in XML::XPath the prefixes in XPath node tests take their
+context from the current node. This means that foo:bar will always
+match an element <foo:bar> regardless of the namespace that the prefix
+foo is mapped to (which might even change within the document, resulting
+in unexpected results). In order to make prefixes in XPath node tests
+actually map to a real URI, you need to enable that via a call
+to the set_namespace method of your XML::XPath object.
+
+=head2 clear_namespaces()
+
+Clears all previously set namespace mappings.
+
+=head2 $XML::XPath::Namespaces
+
+Set this to 0 if you I<don't> want namespace processing to occur. This
+will make everything a little (tiny) bit faster, but you'll suffer for it,
+probably.
+
+=head1 Node Object Model
+
+See L<XML::XPath::Node>, L<XML::XPath::Node::Element>, 
+L<XML::XPath::Node::Text>, L<XML::XPath::Node::Comment>,
+L<XML::XPath::Node::Attribute>, L<XML::XPath::Node::Namespace>,
+and L<XML::XPath::Node::PI>.
+
+=head1 On Garbage Collection
+
+XPath nodes work in a special way that allows circular references, and 
+yet still lets Perl's reference counting garbage collector to clean up
+the nodes after use. This should be totally transparent to the user,
+with one caveat: B<If you free your tree before letting go of a sub-tree,
+consider that playing with fire and you may get burned>. What does this
+mean to the average user? Not much. Provided you don't free (or let go
+out of scope) either the tree you passed to XML::XPath->new, or if you
+didn't pass a tree, and passed a filename or IO-ref, then provided you
+don't let the XML::XPath object go out of scope before you let results
+of find() and its friends go out of scope, then you'll be fine. Even if
+you B<do> let the tree go out of scope before results, you'll probably
+still be fine. The only case where you may get stung is when the last
+part of your path/query is either an ancestor or parent axis. In that
+case the worst that will happen is you'll end up with a circular reference
+that won't get cleared until interpreter destruction time. You can get
+around that by explicitly calling $node->DESTROY on each of your result
+nodes, if you really need to do that.
+
+Mail me direct if that's not clear. Note that it's not doom and gloom. It's
+by no means perfect, but the worst that will happen is a long running process
+could leak memory. Most long running processes will therefore be able to
+explicitly be careful not to free the tree (or XML::XPath object) before
+freeing results. AxKit, an application that uses XML::XPath, does this and
+I didn't have to make any changes to the code - it's already sensible
+programming.
+
+If you I<really> don't want all this to happen, then set the variable
+$XML::XPath::SafeMode, and call $xp->cleanup() on the XML::XPath object
+when you're finished, or $tree->dispose() if you have a tree instead.
+
+=head1 Example
+
+Please see the test files in t/ for examples on how to use XPath.
+
+=head1 Support/Author
+
+This module is copyright 2000 AxKit.com Ltd. This is free
+software, and as such comes with NO WARRANTY. No dates are used in this
+module. You may distribute this module under the terms of either the
+Gnu GPL,  or the Artistic License (the same terms as Perl itself).
+
+For support, please subscribe to the Perl-XML mailing list at the URL 
+http://listserv.activestate.com/mailman/listinfo/perl-xml
+
+Matt Sergeant, matt@sergeant.org
+
+=head1 SEE ALSO
+
+L<XML::XPath::Literal>, L<XML::XPath::Boolean>, L<XML::XPath::Number>,
+L<XML::XPath::XMLParser>, L<XML::XPath::NodeSet>, L<XML::XPath::PerlSAX>,
+L<XML::XPath::Builder>.
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/Boolean.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Boolean.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Boolean.pm	(revision 20131)
@@ -0,0 +1,73 @@
+# $Id$
+
+package XML::XPath::Boolean;
+use XML::XPath::Number;
+use XML::XPath::Literal;
+use strict;
+
+use overload
+		'""' => \&value,
+		'<=>' => \&cmp;
+
+sub True {
+	my $class = shift;
+	my $val = 1;
+	bless \$val, $class;
+}
+
+sub False {
+	my $class = shift;
+	my $val = 0;
+	bless \$val, $class;
+}
+
+sub value {
+	my $self = shift;
+	$$self;
+}
+
+sub cmp {
+	my $self = shift;
+	my ($other, $swap) = @_;
+	if ($swap) {
+		return $other <=> $$self;
+	}
+	return $$self <=> $other;
+}
+
+sub to_number { XML::XPath::Number->new($_[0]->value); }
+sub to_boolean { $_[0]; }
+sub to_literal { XML::XPath::Literal->new($_[0]->value ? "true" : "false"); }
+
+sub string_value { return $_[0]->to_literal->value; }
+
+1;
+__END__
+
+=head1 NAME
+
+XML::XPath::Boolean - Boolean true/false values
+
+=head1 DESCRIPTION
+
+XML::XPath::Boolean objects implement simple boolean true/false objects.
+
+=head1 API
+
+=head2 XML::XPath::Boolean->True
+
+Creates a new Boolean object with a true value.
+
+=head2 XML::XPath::Boolean->False
+
+Creates a new Boolean object with a false value.
+
+=head2 value()
+
+Returns true or false.
+
+=head2 to_literal()
+
+Returns the string "true" or "false".
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/Builder.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Builder.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Builder.pm	(revision 20131)
@@ -0,0 +1,198 @@
+# $Id$
+
+package XML::XPath::Builder;
+
+use strict;
+
+# to get array index constants
+use XML::XPath::Node;
+use XML::XPath::Node::Element;
+use XML::XPath::Node::Attribute;
+use XML::XPath::Node::Namespace;
+use XML::XPath::Node::Text;
+use XML::XPath::Node::PI;
+use XML::XPath::Node::Comment;
+
+use vars qw/$xmlns_ns $xml_ns/;
+
+$xmlns_ns = "http://www.w3.org/2000/xmlns/";
+$xml_ns = "http://www.w3.org/XML/1998/namespace";
+
+sub new {
+    my $class = shift;
+    my $self = ($#_ == 0) ? { %{ (shift) } } : { @_ };
+
+    bless $self, $class;
+}
+
+sub start_document {
+    my $self = shift;
+
+    $self->{IdNames} = {};
+    $self->{InScopeNamespaceStack} = [ { 
+            '_Default' => undef,
+            'xmlns' => $xmlns_ns,
+            'xml' => $xml_ns,
+        } ];
+    
+    $self->{NodeStack} = [ ];
+    
+    my $document = XML::XPath::Node::Element->new();
+    my $newns = XML::XPath::Node::Namespace->new('xml', $xml_ns);
+    $document->appendNamespace($newns);
+    $self->{current} = $self->{DOC_Node} = $document;
+}
+
+sub end_document {
+    my $self = shift;
+    
+    return $self->{DOC_Node};
+}
+
+sub characters {
+    my $self = shift;
+    my $sarg = shift;
+    my $text = $sarg->{Data};
+    
+    my $parent = $self->{current};
+    
+    my $last = $parent->getLastChild;
+    if ($last && $last->isTextNode) {
+        # append to previous text node
+        $last->appendText($text);
+        return;
+    }
+    
+    my $node = XML::XPath::Node::Text->new($text);
+    $parent->appendChild($node, 1);
+}
+
+sub start_element {
+    my $self = shift;
+    my $sarg = shift;
+    my $tag  = $sarg->{'Name'};
+    my $attr = $sarg->{'Attributes'};
+
+    push @{ $self->{InScopeNamespaceStack} },
+         { %{ $self->{InScopeNamespaceStack}[-1] } };
+    $self->_scan_namespaces(@_);
+    
+    my ($prefix, $namespace) = $self->_namespace($tag);
+    
+    my $node = XML::XPath::Node::Element->new($tag, $prefix);
+    
+    foreach my $name (keys %$attr) {
+	my $value = $attr->{$name};
+
+        if ($name =~ /^xmlns(:(.*))?$/) {
+            # namespace node
+            my $prefix = $2 || '#default';
+#            warn "Creating NS node: $prefix = $value\n";
+            my $newns = XML::XPath::Node::Namespace->new($prefix, $value);
+            $node->appendNamespace($newns);
+        }
+        else {
+	    my ($prefix, $namespace) = $self->_namespace($name);
+            undef $namespace unless $prefix;
+
+            my $newattr = XML::XPath::Node::Attribute->new($name, $value, $prefix);
+            $node->appendAttribute($newattr, 1);
+            if (exists($self->{IdNames}{$tag}) && ($self->{IdNames}{$tag} eq $name)) {
+    #            warn "appending Id Element: $val for ", $node->getName, "\n";
+                $self->{DOC_Node}->appendIdElement($value, $node);
+            }
+        }
+    }
+        
+    $self->{current}->appendChild($node, 1);
+    $self->{current} = $node;
+}
+
+sub end_element {
+    my $self = shift;
+    $self->{current} = $self->{current}->getParentNode;
+}
+
+sub processing_instruction {
+    my $self = shift;
+    my $pi = shift;
+    my $node = XML::XPath::Node::PI->new($pi->{Target}, $pi->{Data});
+    $self->{current}->appendChild($node, 1);
+}
+
+sub comment {
+    my $self = shift;
+    my $comment = shift;
+    my $node = XML::XPath::Node::Comment->new($comment->{Data});
+    $self->{current}->appendChild($node, 1);
+}
+
+sub _scan_namespaces {
+    my ($self, %attributes) = @_;
+
+    while (my ($attr_name, $value) = each %attributes) {
+	if ($attr_name eq 'xmlns') {
+	    $self->{InScopeNamespaceStack}[-1]{'_Default'} = $value;
+	} elsif ($attr_name =~ /^xmlns:(.*)$/) {
+	    my $prefix = $1;
+	    $self->{InScopeNamespaceStack}[-1]{$prefix} = $value;
+	}
+    }
+}
+
+sub _namespace {
+    my ($self, $name) = @_;
+
+    my ($prefix, $localname) = split(/:/, $name);
+    if (!defined($localname)) {
+	if ($prefix eq 'xmlns') {
+	    return '', undef;
+	} else {
+	    return '', $self->{InScopeNamespaceStack}[-1]{'_Default'};
+	}
+    } else {
+	return $prefix, $self->{InScopeNamespaceStack}[-1]{$prefix};
+    }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+XML::XPath::Builder - SAX handler for building an XPath tree
+
+=head1 SYNOPSIS
+
+ use AnySAXParser;
+ use XML::XPath::Builder;
+
+ $builder = XML::XPath::Builder->new();
+ $parser = AnySAXParser->new( Handler => $builder );
+
+ $root_node = $parser->parse( Source => [SOURCE] );
+
+=head1 DESCRIPTION
+
+C<XML::XPath::Builder> is a SAX handler for building an XML::XPath
+tree.
+
+C<XML::XPath::Builder> is used by creating a new instance of
+C<XML::XPath::Builder> and providing it as the Handler for a SAX
+parser.  Calling `C<parse()>' on the SAX parser will return the
+root node of the tree built from that parse.
+
+=head1 AUTHOR
+
+Ken MacLeod, <ken@bitsko.slc.ut.us>
+
+=head1 SEE ALSO
+
+perl(1), XML::XPath(3)
+
+PerlSAX.pod in libxml-perl
+
+Extensible Markup Language (XML) <http://www.w3c.org/XML>
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/Expr.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Expr.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Expr.pm	(revision 20131)
@@ -0,0 +1,619 @@
+# $Id$
+
+package XML::XPath::Expr;
+use strict;
+
+sub new {
+    my $class = shift;
+    my ($pp) = @_;
+    bless { predicates => [], pp => $pp }, $class;
+}
+
+sub as_string {
+    my $self = shift;
+    local $^W; # Use of uninitialized value! grrr
+    my $string = "(" . $self->{lhs}->as_string;
+    $string .= " " . $self->{op} . " " if defined $self->{op};
+    $string .= $self->{rhs}->as_string if defined $self->{rhs};
+    $string .= ")";
+    foreach my $predicate (@{$self->{predicates}}) {
+        $string .= "[" . $predicate->as_string . "]";
+    }
+    return $string;
+}
+
+sub as_xml {
+    my $self = shift;
+    local $^W; # Use of uninitialized value! grrr
+    my $string;
+    if (defined $self->{op}) {
+        $string .= $self->op_xml();
+    }
+    else {
+        $string .= $self->{lhs}->as_xml();
+    }
+    foreach my $predicate (@{$self->{predicates}}) {
+        $string .= "<Predicate>\n" . $predicate->as_xml() . "</Predicate>\n";
+    }
+    return $string;
+}
+
+sub op_xml {
+    my $self = shift;
+    my $op = $self->{op};
+
+    my $tag;    
+    for ($op) {
+        /^or$/    && do {
+                    $tag = "Or";
+                };
+        /^and$/    && do {
+                    $tag = "And";
+                };
+        /^=$/    && do {
+                    $tag = "Equals";
+                };
+        /^!=$/    && do {
+                    $tag = "NotEquals";
+                };
+        /^<=$/    && do {
+                    $tag = "LessThanOrEquals";
+                };
+        /^>=$/    && do {
+                    $tag = "GreaterThanOrEquals";
+                };
+        /^>$/    && do {
+                    $tag = "GreaterThan";
+                };
+        /^<$/    && do {
+                    $tag = "LessThan";
+                };
+        /^\+$/    && do {
+                    $tag = "Plus";
+                };
+        /^-$/    && do {
+                    $tag = "Minus";
+                };
+        /^div$/    && do {
+                    $tag = "Div";
+                };
+        /^mod$/    && do {
+                    $tag = "Mod";
+                };
+        /^\*$/    && do {
+                    $tag = "Multiply";
+                };
+        /^\|$/    && do {
+                    $tag = "Union";
+                };
+    }
+    
+    return "<$tag>\n" . $self->{lhs}->as_xml() . $self->{rhs}->as_xml() . "</$tag>\n";
+}
+
+sub set_lhs {
+    my $self = shift;
+    $self->{lhs} = $_[0];
+}
+
+sub set_op {
+    my $self = shift;
+    $self->{op} = $_[0];
+}
+
+sub set_rhs {
+    my $self = shift;
+    $self->{rhs} = $_[0];
+}
+
+sub push_predicate {
+    my $self = shift;
+    
+    die "Only 1 predicate allowed on FilterExpr in W3C XPath 1.0"
+            if @{$self->{predicates}};
+    
+    push @{$self->{predicates}}, $_[0];
+}
+
+sub get_lhs { $_[0]->{lhs}; }
+sub get_rhs { $_[0]->{rhs}; }
+sub get_op { $_[0]->{op}; }
+
+sub evaluate {
+    my $self = shift;
+    my $node = shift;
+    
+    # If there's an op, result is result of that op.
+    # If no op, just resolve Expr
+    
+#    warn "Evaluate Expr: ", $self->as_string, "\n";
+    
+    my $results;
+    
+    if ($self->{op}) {
+        die ("No RHS of ", $self->as_string) unless $self->{rhs};
+        $results = $self->op_eval($node);
+    }
+    else {
+        $results = $self->{lhs}->evaluate($node);
+    }
+    
+    if (my @predicates = @{$self->{predicates}}) {
+        if (!$results->isa('XML::XPath::NodeSet')) {
+            die "Can't have predicates execute on object type: " . ref($results);
+        }
+        
+        # filter initial nodeset by each predicate
+        foreach my $predicate (@{$self->{predicates}}) {
+            $results = $self->filter_by_predicate($results, $predicate);
+        }
+    }
+    
+    return $results;
+}
+
+sub op_eval {
+    my $self = shift;
+    my $node = shift;
+    
+    my $op = $self->{op};
+    
+    for ($op) {
+        /^or$/    && do {
+                    return op_or($node, $self->{lhs}, $self->{rhs});
+                };
+        /^and$/    && do {
+                    return op_and($node, $self->{lhs}, $self->{rhs});
+                };
+        /^=$/    && do {
+                    return op_equals($node, $self->{lhs}, $self->{rhs});
+                };
+        /^!=$/    && do {
+                    return op_nequals($node, $self->{lhs}, $self->{rhs});
+                };
+        /^<=$/    && do {
+                    return op_le($node, $self->{lhs}, $self->{rhs});
+                };
+        /^>=$/    && do {
+                    return op_ge($node, $self->{lhs}, $self->{rhs});
+                };
+        /^>$/    && do {
+                    return op_gt($node, $self->{lhs}, $self->{rhs});
+                };
+        /^<$/    && do {
+                    return op_lt($node, $self->{lhs}, $self->{rhs});
+                };
+        /^\+$/    && do {
+                    return op_plus($node, $self->{lhs}, $self->{rhs});
+                };
+        /^-$/    && do {
+                    return op_minus($node, $self->{lhs}, $self->{rhs});
+                };
+        /^div$/    && do {
+                    return op_div($node, $self->{lhs}, $self->{rhs});
+                };
+        /^mod$/    && do {
+                    return op_mod($node, $self->{lhs}, $self->{rhs});
+                };
+        /^\*$/    && do {
+                    return op_mult($node, $self->{lhs}, $self->{rhs});
+                };
+        /^\|$/    && do {
+                    return op_union($node, $self->{lhs}, $self->{rhs});
+                };
+        
+        die "No such operator, or operator unimplemented in ", $self->as_string, "\n";
+    }
+}
+
+# Operators
+
+use XML::XPath::Boolean;
+
+sub op_or {
+    my ($node, $lhs, $rhs) = @_;
+    if($lhs->evaluate($node)->to_boolean->value) {
+        return XML::XPath::Boolean->True;
+    }
+    else {
+        return $rhs->evaluate($node)->to_boolean;
+    }
+}
+
+sub op_and {
+    my ($node, $lhs, $rhs) = @_;
+    if( ! $lhs->evaluate($node)->to_boolean->value ) {
+        return XML::XPath::Boolean->False;
+    }
+    else {
+        return $rhs->evaluate($node)->to_boolean;
+    }
+}
+
+sub op_equals {
+    my ($node, $lhs, $rhs) = @_;
+
+    my $lh_results = $lhs->evaluate($node);
+    my $rh_results = $rhs->evaluate($node);
+    
+    if ($lh_results->isa('XML::XPath::NodeSet') &&
+            $rh_results->isa('XML::XPath::NodeSet')) {
+        # True if and only if there is a node in the
+        # first set and a node in the second set such
+        # that the result of performing the comparison
+        # on the string-values of the two nodes is true.
+        foreach my $lhnode ($lh_results->get_nodelist) {
+            foreach my $rhnode ($rh_results->get_nodelist) {
+                if ($lhnode->string_value eq $rhnode->string_value) {
+                    return XML::XPath::Boolean->True;
+                }
+            }
+        }
+        return XML::XPath::Boolean->False;
+    }
+    elsif (($lh_results->isa('XML::XPath::NodeSet') ||
+            $rh_results->isa('XML::XPath::NodeSet')) &&
+            (!$lh_results->isa('XML::XPath::NodeSet') ||
+             !$rh_results->isa('XML::XPath::NodeSet'))) {
+        # (that says: one is a nodeset, and one is not a nodeset)
+        
+        my ($nodeset, $other);
+        if ($lh_results->isa('XML::XPath::NodeSet')) {
+            $nodeset = $lh_results;
+            $other = $rh_results;
+        }
+        else {
+            $nodeset = $rh_results;
+            $other = $lh_results;
+        }
+        
+        # True if and only if there is a node in the
+        # nodeset such that the result of performing
+        # the comparison on <type>(string_value($node))
+        # is true.
+        if ($other->isa('XML::XPath::Number')) {
+            foreach my $node ($nodeset->get_nodelist) {
+                if ($node->string_value == $other->value) {
+                    return XML::XPath::Boolean->True;
+                }
+            }
+        }
+        elsif ($other->isa('XML::XPath::Literal')) {
+            foreach my $node ($nodeset->get_nodelist) {
+                if ($node->string_value eq $other->value) {
+                    return XML::XPath::Boolean->True;
+                }
+            }
+        }
+        elsif ($other->isa('XML::XPath::Boolean')) {
+            if ($nodeset->to_boolean->value == $other->value) {
+                return XML::XPath::Boolean->True;
+            }
+        }
+
+        return XML::XPath::Boolean->False;
+    }
+    else { # Neither is a nodeset
+        if ($lh_results->isa('XML::XPath::Boolean') ||
+            $rh_results->isa('XML::XPath::Boolean')) {
+            # if either is a boolean
+            if ($lh_results->to_boolean->value == $rh_results->to_boolean->value) {
+                return XML::XPath::Boolean->True;
+            }
+            return XML::XPath::Boolean->False;
+        }
+        elsif ($lh_results->isa('XML::XPath::Number') ||
+                $rh_results->isa('XML::XPath::Number')) {
+            # if either is a number
+            local $^W; # 'number' might result in undef
+            if ($lh_results->to_number->value == $rh_results->to_number->value) {
+                return XML::XPath::Boolean->True;
+            }
+            return XML::XPath::Boolean->False;
+        }
+        else {
+            if ($lh_results->to_literal->value eq $rh_results->to_literal->value) {
+                return XML::XPath::Boolean->True;
+            }
+            return XML::XPath::Boolean->False;
+        }
+    }
+}
+
+sub op_nequals {
+    my ($node, $lhs, $rhs) = @_;
+    if (op_equals($node, $lhs, $rhs)->value) {
+        return XML::XPath::Boolean->False;
+    }
+    return XML::XPath::Boolean->True;
+}
+
+sub op_le {
+    my ($node, $lhs, $rhs) = @_;
+    op_gt($node, $rhs, $lhs);
+}
+
+sub op_ge {
+    my ($node, $lhs, $rhs) = @_;
+
+    my $lh_results = $lhs->evaluate($node);
+    my $rh_results = $rhs->evaluate($node);
+    
+    if ($lh_results->isa('XML::XPath::NodeSet') &&
+        $rh_results->isa('XML::XPath::NodeSet')) {
+
+        foreach my $lhnode ($lh_results->get_nodelist) {
+            foreach my $rhnode ($rh_results->get_nodelist) {
+                my $lhNum = XML::XPath::Number->new($lhnode->string_value);
+                my $rhNum = XML::XPath::Number->new($rhnode->string_value);
+                if ($lhNum->value >= $rhNum->value) {
+                    return XML::XPath::Boolean->True;
+                }
+            }
+        }
+        return XML::XPath::Boolean->False;
+    }
+    elsif (($lh_results->isa('XML::XPath::NodeSet') ||
+            $rh_results->isa('XML::XPath::NodeSet')) &&
+            (!$lh_results->isa('XML::XPath::NodeSet') ||
+             !$rh_results->isa('XML::XPath::NodeSet'))) {
+        # (that says: one is a nodeset, and one is not a nodeset)
+
+        my ($nodeset, $other);
+        my ($true, $false);
+        if ($lh_results->isa('XML::XPath::NodeSet')) {
+            $nodeset = $lh_results;
+            $other = $rh_results;
+            # we do this because unlike ==, these ops are direction dependant
+            ($false, $true) = (XML::XPath::Boolean->False, XML::XPath::Boolean->True);
+        }
+        else {
+            $nodeset = $rh_results;
+            $other = $lh_results;
+            # ditto above comment
+            ($true, $false) = (XML::XPath::Boolean->False, XML::XPath::Boolean->True);
+        }
+        
+        # True if and only if there is a node in the
+        # nodeset such that the result of performing
+        # the comparison on <type>(string_value($node))
+        # is true.
+        foreach my $node ($nodeset->get_nodelist) {
+            if ($node->to_number->value >= $other->to_number->value) {
+                return $true;
+            }
+        }
+        return $false;
+    }
+    else { # Neither is a nodeset
+        if ($lh_results->isa('XML::XPath::Boolean') ||
+            $rh_results->isa('XML::XPath::Boolean')) {
+            # if either is a boolean
+            if ($lh_results->to_boolean->to_number->value
+                    >= $rh_results->to_boolean->to_number->value) {
+                return XML::XPath::Boolean->True;
+            }
+        }
+        else {
+            if ($lh_results->to_number->value >= $rh_results->to_number->value) {
+                return XML::XPath::Boolean->True;
+            }
+        }
+        return XML::XPath::Boolean->False;
+    }
+}
+
+sub op_gt {
+    my ($node, $lhs, $rhs) = @_;
+
+    my $lh_results = $lhs->evaluate($node);
+    my $rh_results = $rhs->evaluate($node);
+    
+    if ($lh_results->isa('XML::XPath::NodeSet') &&
+        $rh_results->isa('XML::XPath::NodeSet')) {
+
+        foreach my $lhnode ($lh_results->get_nodelist) {
+            foreach my $rhnode ($rh_results->get_nodelist) {
+                my $lhNum = XML::XPath::Number->new($lhnode->string_value);
+                my $rhNum = XML::XPath::Number->new($rhnode->string_value);
+                if ($lhNum->value > $rhNum->value) {
+                    return XML::XPath::Boolean->True;
+                }
+            }
+        }
+        return XML::XPath::Boolean->False;
+    }
+    elsif (($lh_results->isa('XML::XPath::NodeSet') ||
+            $rh_results->isa('XML::XPath::NodeSet')) &&
+            (!$lh_results->isa('XML::XPath::NodeSet') ||
+             !$rh_results->isa('XML::XPath::NodeSet'))) {
+        # (that says: one is a nodeset, and one is not a nodeset)
+
+        my ($nodeset, $other);
+        my ($true, $false);
+        if ($lh_results->isa('XML::XPath::NodeSet')) {
+            $nodeset = $lh_results;
+            $other = $rh_results;
+            # we do this because unlike ==, these ops are direction dependant
+            ($false, $true) = (XML::XPath::Boolean->False, XML::XPath::Boolean->True);
+        }
+        else {
+            $nodeset = $rh_results;
+            $other = $lh_results;
+            # ditto above comment
+            ($true, $false) = (XML::XPath::Boolean->False, XML::XPath::Boolean->True);
+        }
+        
+        # True if and only if there is a node in the
+        # nodeset such that the result of performing
+        # the comparison on <type>(string_value($node))
+        # is true.
+        foreach my $node ($nodeset->get_nodelist) {
+            if ($node->to_number->value > $other->to_number->value) {
+                return $true;
+            }
+        }
+        return $false;
+    }
+    else { # Neither is a nodeset
+        if ($lh_results->isa('XML::XPath::Boolean') ||
+            $rh_results->isa('XML::XPath::Boolean')) {
+            # if either is a boolean
+            if ($lh_results->to_boolean->value > $rh_results->to_boolean->value) {
+                return XML::XPath::Boolean->True;
+            }
+        }
+        else {
+            if ($lh_results->to_number->value > $rh_results->to_number->value) {
+                return XML::XPath::Boolean->True;
+            }
+        }
+        return XML::XPath::Boolean->False;
+    }
+}
+
+sub op_lt {
+    my ($node, $lhs, $rhs) = @_;
+    op_gt($node, $rhs, $lhs);
+}
+
+sub op_plus {
+    my ($node, $lhs, $rhs) = @_;
+    my $lh_results = $lhs->evaluate($node);
+    my $rh_results = $rhs->evaluate($node);
+    
+    my $result =
+        $lh_results->to_number->value
+            +
+        $rh_results->to_number->value
+            ;
+    return XML::XPath::Number->new($result);
+}
+
+sub op_minus {
+    my ($node, $lhs, $rhs) = @_;
+    my $lh_results = $lhs->evaluate($node);
+    my $rh_results = $rhs->evaluate($node);
+    
+    my $result =
+        $lh_results->to_number->value
+            -
+        $rh_results->to_number->value
+            ;
+    return XML::XPath::Number->new($result);
+}
+
+sub op_div {
+    my ($node, $lhs, $rhs) = @_;
+    my $lh_results = $lhs->evaluate($node);
+    my $rh_results = $rhs->evaluate($node);
+
+    my $result = eval {
+        $lh_results->to_number->value
+            /
+        $rh_results->to_number->value
+            ;
+    };
+    if ($@) {
+        # assume divide by zero
+        # This is probably a terrible way to handle this! 
+        # Ah well... who wants to live forever...
+        return XML::XPath::Literal->new('Infinity');
+    }
+    return XML::XPath::Number->new($result);
+}
+
+sub op_mod {
+    my ($node, $lhs, $rhs) = @_;
+    my $lh_results = $lhs->evaluate($node);
+    my $rh_results = $rhs->evaluate($node);
+    
+    my $result =
+        $lh_results->to_number->value
+            %
+        $rh_results->to_number->value
+            ;
+    return XML::XPath::Number->new($result);
+}
+
+sub op_mult {
+    my ($node, $lhs, $rhs) = @_;
+    my $lh_results = $lhs->evaluate($node);
+    my $rh_results = $rhs->evaluate($node);
+    
+    my $result =
+        $lh_results->to_number->value
+            *
+        $rh_results->to_number->value
+            ;
+    return XML::XPath::Number->new($result);
+}
+
+sub op_union {
+    my ($node, $lhs, $rhs) = @_;
+    my $lh_result = $lhs->evaluate($node);
+    my $rh_result = $rhs->evaluate($node);
+    
+    if ($lh_result->isa('XML::XPath::NodeSet') &&
+            $rh_result->isa('XML::XPath::NodeSet')) {
+        my %found;
+        my $results = XML::XPath::NodeSet->new;
+        foreach my $lhnode ($lh_result->get_nodelist) {
+            $found{"$lhnode"}++;
+            $results->push($lhnode);
+        }
+        foreach my $rhnode ($rh_result->get_nodelist) {
+            $results->push($rhnode)
+                    unless exists $found{"$rhnode"};
+        }
+                $results->sort;
+        return $results;
+    }
+    die "Both sides of a union must be Node Sets\n";
+}
+
+sub filter_by_predicate {
+    my $self = shift;
+    my ($nodeset, $predicate) = @_;
+    
+    # See spec section 2.4, paragraphs 2 & 3:
+    # For each node in the node-set to be filtered, the predicate Expr
+    # is evaluated with that node as the context node, with the number
+    # of nodes in the node set as the context size, and with the
+    # proximity position of the node in the node set with respect to
+    # the axis as the context position.
+    
+    if (!ref($nodeset)) { # use ref because nodeset has a bool context
+        die "No nodeset!!!";
+    }
+    
+#    warn "Filter by predicate: $predicate\n";
+    
+    my $newset = XML::XPath::NodeSet->new();
+    
+    for(my $i = 1; $i <= $nodeset->size; $i++) {
+        # set context set each time 'cos a loc-path in the expr could change it
+        $self->{pp}->set_context_set($nodeset);
+        $self->{pp}->set_context_pos($i);
+        my $result = $predicate->evaluate($nodeset->get_node($i));
+        if ($result->isa('XML::XPath::Boolean')) {
+            if ($result->value) {
+                $newset->push($nodeset->get_node($i));
+            }
+        }
+        elsif ($result->isa('XML::XPath::Number')) {
+            if ($result->value == $i) {
+                $newset->push($nodeset->get_node($i));
+            }
+        }
+        else {
+            if ($result->to_boolean->value) {
+                $newset->push($nodeset->get_node($i));
+            }
+        }
+    }
+    
+    return $newset;
+}
+
+1;
Index: /gsdl/stable/perllib/cpan/XML/XPath/Function.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Function.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Function.pm	(revision 20131)
@@ -0,0 +1,392 @@
+# $Id$
+
+package XML::XPath::Function;
+use XML::XPath::Number;
+use XML::XPath::Literal;
+use XML::XPath::Boolean;
+use XML::XPath::NodeSet;
+use XML::XPath::Node::Attribute;
+use strict;
+
+sub new {
+    my $class = shift;
+    my ($pp, $name, $params) = @_;
+    bless { 
+        pp => $pp, 
+        name => $name, 
+        params => $params 
+        }, $class;
+}
+
+sub as_string {
+    my $self = shift;
+    my $string = $self->{name} . "(";
+    my $second;
+    foreach (@{$self->{params}}) {
+        $string .= "," if $second++;
+        $string .= $_->as_string;
+    }
+    $string .= ")";
+    return $string;
+}
+
+sub as_xml {
+    my $self = shift;
+    my $string = "<Function name=\"$self->{name}\"";
+    my $params = "";
+    foreach (@{$self->{params}}) {
+        $params .= "<Param>" . $_->as_string . "</Param>\n";
+    }
+    if ($params) {
+        $string .= ">\n$params</Function>\n";
+    }
+    else {
+        $string .= " />\n";
+    }
+    
+    return $string;
+}
+
+sub evaluate {
+    my $self = shift;
+    my $node = shift;
+    if ($node->isa('XML::XPath::NodeSet')) {
+        $node = $node->get_node(1);
+    }
+    my @params;
+    foreach my $param (@{$self->{params}}) {
+        my $results = $param->evaluate($node);
+        push @params, $results;
+    }
+    $self->_execute($self->{name}, $node, @params);
+}
+
+sub _execute {
+    my $self = shift;
+    my ($name, $node, @params) = @_;
+    $name =~ s/-/_/g;
+    no strict 'refs';
+    $self->$name($node, @params);
+}
+
+# All functions should return one of:
+# XML::XPath::Number
+# XML::XPath::Literal (string)
+# XML::XPath::NodeSet
+# XML::XPath::Boolean
+
+### NODESET FUNCTIONS ###
+
+sub last {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "last: function doesn't take parameters\n" if (@params);
+    return XML::XPath::Number->new($self->{pp}->get_context_size);
+}
+
+sub position {
+    my $self = shift;
+    my ($node, @params) = @_;
+    if (@params) {
+        die "position: function doesn't take parameters [ ", @params, " ]\n";
+    }
+    # return pos relative to axis direction
+    return XML::XPath::Number->new($self->{pp}->get_context_pos);
+}
+
+sub count {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "count: Parameter must be a NodeSet\n" unless $params[0]->isa('XML::XPath::NodeSet');
+    return XML::XPath::Number->new($params[0]->size);
+}
+
+sub id {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "id: Function takes 1 parameter\n" unless @params == 1;
+    my $results = XML::XPath::NodeSet->new();
+    if ($params[0]->isa('XML::XPath::NodeSet')) {
+        # result is the union of applying id() to the
+        # string value of each node in the nodeset.
+        foreach my $node ($params[0]->get_nodelist) {
+            my $string = $node->string_value;
+            $results->append($self->id($node, XML::XPath::Literal->new($string)));
+        }
+    }
+    else { # The actual id() function...
+        my $string = $self->string($node, $params[0]);
+        $_ = $string->value; # get perl scalar
+        my @ids = split; # splits $_
+        foreach my $id (@ids) {
+            if (my $found = $node->getElementById($id)) {
+                $results->push($found);
+            }
+        }
+    }
+    return $results;
+}
+
+sub local_name {
+    my $self = shift;
+    my ($node, @params) = @_;
+    if (@params > 1) {
+        die "name() function takes one or no parameters\n";
+    }
+    elsif (@params) {
+        my $nodeset = shift(@params);
+        $node = $nodeset->get_node(1);
+    }
+    
+    return XML::XPath::Literal->new($node->getLocalName);
+}
+
+sub namespace_uri {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "namespace-uri: Function not supported\n";
+}
+
+sub name {
+    my $self = shift;
+    my ($node, @params) = @_;
+    if (@params > 1) {
+        die "name() function takes one or no parameters\n";
+    }
+    elsif (@params) {
+        my $nodeset = shift(@params);
+        $node = $nodeset->get_node(1);
+    }
+    
+    return XML::XPath::Literal->new($node->getName);
+}
+
+### STRING FUNCTIONS ###
+
+sub string {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "string: Too many parameters\n" if @params > 1;
+    if (@params) {
+        return XML::XPath::Literal->new($params[0]->string_value);
+    }
+    
+    # TODO - this MUST be wrong! - not sure now. -matt
+    return XML::XPath::Literal->new($node->string_value);
+    # default to nodeset with just $node in.
+}
+
+sub concat {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "concat: Too few parameters\n" if @params < 2;
+    my $string = join('', map {$_->string_value} @params);
+    return XML::XPath::Literal->new($string);
+}
+
+sub starts_with {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "starts-with: incorrect number of params\n" unless @params == 2;
+    my ($string1, $string2) = ($params[0]->string_value, $params[1]->string_value);
+    if (substr($string1, 0, length($string2)) eq $string2) {
+        return XML::XPath::Boolean->True;
+    }
+    return XML::XPath::Boolean->False;
+}
+
+sub contains {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "starts-with: incorrect number of params\n" unless @params == 2;
+    my $value = $params[1]->string_value;
+    if ($params[0]->string_value =~ /(.*?)\Q$value\E(.*)/) {
+        # $1 and $2 stored for substring funcs below
+        # TODO: Fix this nasty implementation!
+        return XML::XPath::Boolean->True;
+    }
+    return XML::XPath::Boolean->False;
+}
+
+sub substring_before {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "starts-with: incorrect number of params\n" unless @params == 2;
+    if ($self->contains($node, @params)->value) {
+        return XML::XPath::Literal->new($1); # hope that works!
+    }
+    else {
+        return XML::XPath::Literal->new('');
+    }
+}
+
+sub substring_after {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "starts-with: incorrect number of params\n" unless @params == 2;
+    if ($self->contains($node, @params)->value) {
+        return XML::XPath::Literal->new($2);
+    }
+    else {
+        return XML::XPath::Literal->new('');
+    }
+}
+
+sub substring {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "substring: Wrong number of parameters\n" if (@params < 2 || @params > 3);
+    my ($str, $offset, $len);
+    $str = $params[0]->string_value;
+    $offset = $params[1]->value;
+    $offset--; # uses 1 based offsets
+    if (@params == 3) {
+        $len = $params[2]->value;
+    }
+    return XML::XPath::Literal->new(substr($str, $offset, $len));
+}
+
+sub string_length {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "string-length: Wrong number of params\n" if @params > 1;
+    if (@params) {
+        return XML::XPath::Number->new(length($params[0]->string_value));
+    }
+    else {
+        return XML::XPath::Number->new(
+                length($node->string_value)
+                );
+    }
+}
+
+sub normalize_space {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "normalize-space: Wrong number of params\n" if @params > 1;
+    my $str;
+    if (@params) {
+        $str = $params[0]->string_value;
+    }
+    else {
+        $str = $node->string_value;
+    }
+    $str =~ s/^\s*//;
+    $str =~ s/\s*$//;
+    $str =~ s/\s+/ /g;
+    return XML::XPath::Literal->new($str);
+}
+
+sub translate {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "translate: Wrong number of params\n" if @params != 3;
+    local $_ = $params[0]->string_value;
+    my $find = $params[1]->string_value;
+    my $repl = $params[2]->string_value;
+    eval "tr/\\Q$find\\E/\\Q$repl\\E/d, 1" or die $@;
+    return XML::XPath::Literal->new($_);
+}
+
+### BOOLEAN FUNCTIONS ###
+
+sub boolean {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "boolean: Incorrect number of parameters\n" if @params != 1;
+    return $params[0]->to_boolean;
+}
+
+sub not {
+    my $self = shift;
+    my ($node, @params) = @_;
+    $params[0] = $params[0]->to_boolean unless $params[0]->isa('XML::XPath::Boolean');
+    $params[0]->value ? XML::XPath::Boolean->False : XML::XPath::Boolean->True;
+}
+
+sub true {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "true: function takes no parameters\n" if @params > 0;
+    XML::XPath::Boolean->True;
+}
+
+sub false {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "true: function takes no parameters\n" if @params > 0;
+    XML::XPath::Boolean->False;
+}
+
+sub lang {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "lang: function takes 1 parameter\n" if @params != 1;
+    my $lang = $node->findvalue('(ancestor-or-self::*[@xml:lang]/@xml:lang)[last()]');
+    my $lclang = lc($params[0]->string_value);
+    # warn("Looking for lang($lclang) in $lang\n");
+    if (substr(lc($lang), 0, length($lclang)) eq $lclang) {
+        return XML::XPath::Boolean->True;
+    }
+    else {
+        return XML::XPath::Boolean->False;
+    }
+}
+
+### NUMBER FUNCTIONS ###
+
+sub number {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "number: Too many parameters\n" if @params > 1;
+    if (@params) {
+        if ($params[0]->isa('XML::XPath::Node')) {
+            return XML::XPath::Number->new(
+                    $params[0]->string_value
+                    );
+        }
+        return $params[0]->to_number;
+    }
+    
+    return XML::XPath::Number->new( $node->string_value );
+}
+
+sub sum {
+    my $self = shift;
+    my ($node, @params) = @_;
+    die "sum: Parameter must be a NodeSet\n" unless $params[0]->isa('XML::XPath::NodeSet');
+    my $sum = 0;
+    foreach my $node ($params[0]->get_nodelist) {
+        $sum += $self->number($node)->value;
+    }
+    return XML::XPath::Number->new($sum);
+}
+
+sub floor {
+    my $self = shift;
+    my ($node, @params) = @_;
+    require POSIX;
+    my $num = $self->number($node, @params);
+    return XML::XPath::Number->new(
+            POSIX::floor($num->value));
+}
+
+sub ceiling {
+    my $self = shift;
+    my ($node, @params) = @_;
+    require POSIX;
+    my $num = $self->number($node, @params);
+    return XML::XPath::Number->new(
+            POSIX::ceil($num->value));
+}
+
+sub round {
+    my $self = shift;
+    my ($node, @params) = @_;
+    my $num = $self->number($node, @params);
+    require POSIX;
+    return XML::XPath::Number->new(
+            POSIX::floor($num->value + 0.5)); # Yes, I know the spec says don't do this...
+}
+
+1;
Index: /gsdl/stable/perllib/cpan/XML/XPath/Literal.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Literal.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Literal.pm	(revision 20131)
@@ -0,0 +1,99 @@
+# $Id$
+
+package XML::XPath::Literal;
+use XML::XPath::Boolean;
+use XML::XPath::Number;
+use strict;
+
+use overload 
+		'""' => \&value,
+		'cmp' => \&cmp;
+
+sub new {
+	my $class = shift;
+	my ($string) = @_;
+	
+#	$string =~ s/&quot;/"/g;
+#	$string =~ s/&apos;/'/g;
+	
+	bless \$string, $class;
+}
+
+sub as_string {
+	my $self = shift;
+	my $string = $$self;
+	$string =~ s/'/&apos;/g;
+	return "'$string'";
+}
+
+sub as_xml {
+    my $self = shift;
+    my $string = $$self;
+    return "<Literal>$string</Literal>\n";
+}
+
+sub value {
+	my $self = shift;
+	$$self;
+}
+
+sub cmp {
+	my $self = shift;
+	my ($cmp, $swap) = @_;
+	if ($swap) {
+		return $cmp cmp $$self;
+	}
+	return $$self cmp $cmp;
+}
+
+sub evaluate {
+	my $self = shift;
+	$self;
+}
+
+sub to_boolean {
+	my $self = shift;
+	return (length($$self) > 0) ? XML::XPath::Boolean->True : XML::XPath::Boolean->False;
+}
+
+sub to_number { return XML::XPath::Number->new($_[0]->value); }
+sub to_literal { return $_[0]; }
+
+sub string_value { return $_[0]->value; }
+
+1;
+__END__
+
+=head1 NAME
+
+XML::XPath::Literal - Simple string values.
+
+=head1 DESCRIPTION
+
+In XPath terms a Literal is what we know as a string.
+
+=head1 API
+
+=head2 new($string)
+
+Create a new Literal object with the value in $string. Note that &quot; and
+&apos; will be converted to " and ' respectively. That is not part of the XPath
+specification, but I consider it useful. Note though that you have to go
+to extraordinary lengths in an XML template file (be it XSLT or whatever) to
+make use of this:
+
+	<xsl:value-of select="&quot;I'm feeling &amp;quot;sad&amp;quot;&quot;"/>
+
+Which produces a Literal of:
+
+	I'm feeling "sad"
+
+=head2 value()
+
+Also overloaded as stringification, simply returns the literal string value.
+
+=head2 cmp($literal)
+
+Returns the equivalent of perl's cmp operator against the given $literal.
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/LocationPath.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/LocationPath.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/LocationPath.pm	(revision 20131)
@@ -0,0 +1,61 @@
+# $Id$
+
+package XML::XPath::LocationPath;
+use XML::XPath::Root;
+use strict;
+
+sub new {
+	my $class = shift;
+	my $self = [];
+	bless $self, $class;
+}
+
+sub as_string {
+	my $self = shift;
+	my $string;
+	for (my $i = 0; $i < @$self; $i++) {
+		$string .= $self->[$i]->as_string;
+		$string .= "/" if $self->[$i+1];
+	}
+	return $string;
+}
+
+sub as_xml {
+    my $self = shift;
+    my $string = "<LocationPath>\n";
+    
+    for (my $i = 0; $i < @$self; $i++) {
+        $string .= $self->[$i]->as_xml;
+    }
+    
+    $string .= "</LocationPath>\n";
+    return $string;
+}
+
+sub set_root {
+	my $self = shift;
+	unshift @$self, XML::XPath::Root->new();
+}
+
+sub evaluate {
+	my $self = shift;
+	# context _MUST_ be a single node
+	my $context = shift;
+	die "No context" unless $context;
+	
+	# I _think_ this is how it should work :)
+	
+	my $nodeset = XML::XPath::NodeSet->new();
+	$nodeset->push($context);
+	
+	foreach my $step (@$self) {
+		# For each step
+		# evaluate the step with the nodeset
+		my $pos = 1;
+		$nodeset = $step->evaluate($nodeset);
+	}
+	
+	return $nodeset;
+}
+
+1;
Index: /gsdl/stable/perllib/cpan/XML/XPath/Node.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Node.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Node.pm	(revision 20131)
@@ -0,0 +1,592 @@
+# $Id$
+
+package XML::XPath::Node;
+
+use strict;
+use vars qw(@ISA @EXPORT $AUTOLOAD %EXPORT_TAGS @EXPORT_OK);
+use Exporter;
+use Carp;
+@ISA = ('Exporter');
+
+sub UNKNOWN_NODE () {0;}
+sub ELEMENT_NODE () {1;}
+sub ATTRIBUTE_NODE () {2;}
+sub TEXT_NODE () {3;}
+sub CDATA_SECTION_NODE () {4;}
+sub ENTITY_REFERENCE_NODE () {5;}
+sub ENTITY_NODE () {6;}
+sub PROCESSING_INSTRUCTION_NODE () {7;}
+sub COMMENT_NODE () {8;}
+sub DOCUMENT_NODE () {9;}
+sub DOCUMENT_TYPE_NODE () {10;}
+sub DOCUMENT_FRAGMENT_NODE () {11;}
+sub NOTATION_NODE () {12;}
+
+# Non core DOM stuff
+sub ELEMENT_DECL_NODE () {13;}
+sub ATT_DEF_NODE () {14;}
+sub XML_DECL_NODE () {15;}
+sub ATTLIST_DECL_NODE () {16;}
+sub NAMESPACE_NODE () {17;}
+
+# per-node constants
+
+# All
+sub node_parent () { 0; }
+sub node_pos () { 1; }
+sub node_global_pos () { 2; }
+
+# Element
+sub node_prefix () { 3; }
+sub node_children () { 4; }
+sub node_name () { 5; }
+sub node_attribs () { 6; }
+sub node_namespaces () { 7; }
+sub node_ids () { 8; }
+
+# Char
+sub node_text () { 3; }
+
+# PI
+sub node_target () { 3; }
+sub node_data () { 4; }
+
+# Comment
+sub node_comment () { 3; }
+
+# Attribute
+# sub node_prefix () { 3; }
+sub node_key () { 4; }
+sub node_value () { 5; }
+
+# Namespaces
+# sub node_prefix () { 3; }
+sub node_expanded () { 4; }
+
+@EXPORT = qw(
+    UNKNOWN_NODE
+    ELEMENT_NODE
+    ATTRIBUTE_NODE
+    TEXT_NODE
+    CDATA_SECTION_NODE
+    ENTITY_REFERENCE_NODE
+    ENTITY_NODE
+    PROCESSING_INSTRUCTION_NODE
+    COMMENT_NODE
+    DOCUMENT_NODE
+    DOCUMENT_TYPE_NODE
+    DOCUMENT_FRAGMENT_NODE
+    NOTATION_NODE
+    ELEMENT_DECL_NODE
+    ATT_DEF_NODE
+    XML_DECL_NODE
+    ATTLIST_DECL_NODE
+    NAMESPACE_NODE
+    );
+
+@EXPORT_OK = qw(
+            node_parent
+            node_pos
+            node_global_pos
+            node_prefix
+            node_children
+            node_name
+            node_attribs
+            node_namespaces
+            node_text
+            node_target
+            node_data
+            node_comment
+            node_key
+            node_value
+            node_expanded
+                        node_ids
+        );
+
+%EXPORT_TAGS = (
+    'node_keys' => [
+        qw(
+            node_parent
+            node_pos
+            node_global_pos
+            node_prefix
+            node_children
+            node_name
+            node_attribs
+            node_namespaces
+            node_text
+            node_target
+            node_data
+            node_comment
+            node_key
+            node_value
+            node_expanded
+                        node_ids
+        ), @EXPORT,
+    ],
+);
+
+
+my $global_pos = 0;
+
+sub nextPos {
+    my $class = shift;
+    return $global_pos += 5;
+}
+
+sub resetPos {
+    $global_pos = 0;
+}
+
+my %DecodeDefaultEntity =
+(
+ '"' => "&quot;",
+ ">" => "&gt;",
+ "<" => "&lt;",
+ "'" => "&apos;",
+ "&" => "&amp;"
+);
+
+sub XMLescape {
+    my ($str, $default) = @_;
+    return undef unless defined $str;
+    $default ||= '';
+    
+    if ($XML::XPath::EncodeUtf8AsEntity) {
+        $str =~ s/([\xC0-\xDF].|[\xE0-\xEF]..|[\xF0-\xFF]...)|([$default])|(]]>)/
+        defined($1) ? XmlUtf8Decode ($1) : 
+        defined ($2) ? $DecodeDefaultEntity{$2} : "]]&gt;" /egsx;
+    }
+    else {
+        $str =~ s/([$default])|(]]>)/
+        defined ($1) ? $DecodeDefaultEntity{$1} : ']]&gt;' /gsex;
+    }
+
+#?? could there be references that should not be expanded?
+# e.g. should not replace &#nn; &#xAF; and &abc;
+#    $str =~ s/&(?!($ReName|#[0-9]+|#x[0-9a-fA-F]+);)/&amp;/go;
+
+    $str;
+}
+
+#
+# Opposite of XmlUtf8Decode plus it adds prefix "&#" or "&#x" and suffix ";"
+# The 2nd parameter ($hex) indicates whether the result is hex encoded or not.
+#
+sub XmlUtf8Decode
+{
+    my ($str, $hex) = @_;
+    my $len = length ($str);
+    my $n;
+
+    if ($len == 2) {
+        my @n = unpack "C2", $str;
+        $n = (($n[0] & 0x3f) << 6) + ($n[1] & 0x3f);
+    }
+    elsif ($len == 3) {
+        my @n = unpack "C3", $str;
+        $n = (($n[0] & 0x1f) << 12) + (($n[1] & 0x3f) << 6) + 
+            ($n[2] & 0x3f);
+    }
+    elsif ($len == 4) {
+        my @n = unpack "C4", $str;
+        $n = (($n[0] & 0x0f) << 18) + (($n[1] & 0x3f) << 12) + 
+            (($n[2] & 0x3f) << 6) + ($n[3] & 0x3f);
+    }
+    elsif ($len == 1) {    # just to be complete...
+        $n = ord ($str);
+    }
+    else {
+        die "bad value [$str] for XmlUtf8Decode";
+    }
+    $hex ? sprintf ("&#x%x;", $n) : "&#$n;";
+}
+
+sub new {
+    my $class = shift;
+    no strict 'refs';
+    my $impl = $class . "Impl";
+    my $this = $impl->new(@_);
+    if ($XML::XPath::SafeMode) {
+        return $this;
+    }
+    my $self = \$this;
+    return bless $self, $class;
+}
+
+sub AUTOLOAD {
+    my $method = $AUTOLOAD;
+    $method =~ s/.*:://;
+#    warn "AUTOLOAD $method!\n";
+    no strict 'refs';
+    *{$AUTOLOAD} = sub { 
+        my $self = shift;
+        my $olderror = $@; # store previous exceptions
+        my $obj = eval { $$self };
+        if ($@) {
+            if ($@ =~ /Not a SCALAR reference/) {
+                croak("No such method $method in " . ref($self));
+            }
+            croak $@;
+        }
+        if ($obj) {
+            # make sure $@ propogates if this method call was the result
+            # of losing scope because of a die().
+            if ($method =~ /^(DESTROY|del_parent_link)$/) {
+                $obj->$method(@_);
+                $@ = $olderror if $olderror;
+                return;
+            }
+            return $obj->$method(@_);
+        }
+    };
+    goto &$AUTOLOAD;
+}
+
+package XML::XPath::NodeImpl;
+
+use vars qw/@ISA $AUTOLOAD/;
+@ISA = ('XML::XPath::Node');
+
+sub new {
+    die "Virtual base method";
+}
+
+sub getNodeType {
+    my $self = shift;
+    return XML::XPath::Node::UNKNOWN_NODE;
+}
+
+sub isElementNode {}
+sub isAttributeNode {}
+sub isNamespaceNode {}
+sub isTextNode {}
+sub isProcessingInstructionNode {}
+sub isPINode {}
+sub isCommentNode {}
+
+sub getNodeValue {
+    return;
+}
+
+sub getValue {
+    shift->getNodeValue(@_);
+}
+
+sub setNodeValue {
+    return;
+}
+
+sub setValue {
+    shift->setNodeValue(@_);
+}
+
+sub getParentNode {
+    my $self = shift;
+    return $self->[XML::XPath::Node::node_parent];
+}
+
+sub getRootNode {
+    my $self = shift;
+    while (my $parent = $self->getParentNode) {
+        $self = $parent;
+    }
+    return $self;
+}
+
+sub getElementById {
+    my $self = shift;
+    my ($id) = @_;
+#    warn "getElementById: $id\n";
+    my $root = $self->getRootNode;
+    my $node = $root->[XML::XPath::Node::node_ids]{$id};
+#    warn "returning node: ", $node->getName, "\n";
+    return $node;
+}
+
+sub getName { }
+sub getData { }
+
+sub getChildNodes {
+    return wantarray ? () : [];
+}
+
+sub getChildNode {
+    return;
+}
+
+sub getAttribute {
+    return;
+}
+
+sub getAttributes {
+    return wantarray ? () : [];
+}
+
+sub getAttributeNodes {
+    shift->getAttributes(@_);
+}
+
+sub getNamespaceNodes {
+    return wantarray ? () : [];
+}
+
+sub getNamespace {
+    return;
+}
+
+sub getLocalName {
+    return;
+}
+
+sub string_value { return; }
+
+sub get_pos {
+    my $self = shift;
+    return $self->[XML::XPath::Node::node_pos];
+}
+
+sub set_pos {
+    my $self = shift;
+    $self->[XML::XPath::Node::node_pos] = shift;
+}
+
+sub get_global_pos {
+    my $self = shift;
+    return $self->[XML::XPath::Node::node_global_pos];
+}
+
+sub set_global_pos {
+    my $self = shift;
+    $self->[XML::XPath::Node::node_global_pos] = shift;
+}
+
+sub renumber {
+    my $self = shift;
+    my $search = shift;
+    my $diff = shift;
+    
+    foreach my $node ($self->findnodes($search)) {
+        $node->set_global_pos(
+                $node->get_global_pos + $diff
+                );
+    }
+}
+    
+sub insertAfter {
+    my $self = shift;
+    my $newnode = shift;
+    my $posnode = shift;
+
+    my $pos_number = eval { $posnode->[XML::XPath::Node::node_children][-1]->get_global_pos() + 1; };
+    if (!defined $pos_number) {
+        $pos_number = $posnode->get_global_pos() + 1;
+    }
+    
+    eval {
+        if ($pos_number == 
+                $posnode->findnodes(
+                    'following::node()'
+                    )->get_node(1)->get_global_pos()) {
+            $posnode->renumber('following::node()', +5);
+        }
+    };
+    
+    my $pos = $posnode->get_pos;
+    
+    $newnode->setParentNode($self);
+    splice @{$self->[XML::XPath::Node::node_children]}, $pos + 1, 0, $newnode;
+    
+    for (my $i = $pos + 1; $i < @{$self->[XML::XPath::Node::node_children]}; $i++) {
+        $self->[XML::XPath::Node::node_children][$i]->set_pos($i);
+    }
+    
+    $newnode->set_global_pos($pos_number);
+}
+
+sub insertBefore {
+    my $self = shift;
+    my $newnode = shift;
+    my $posnode = shift;
+    
+    my $pos_number = ($posnode->getPreviousSibling() || $posnode->getParentNode)->get_global_pos();
+    if ($pos_number == $posnode->get_global_pos()) {
+        $posnode->renumber('self::node() | descendant::node() | following::node()', +5);
+    }
+    
+    my $pos = $posnode->get_pos;
+    
+    $newnode->setParentNode($self);
+    splice @{$self->[XML::XPath::Node::node_children]}, $pos, 0, $newnode;
+    
+    for (my $i = $pos; $i < @{$self->[XML::XPath::Node::node_children]}; $i++) {
+        $self->[XML::XPath::Node::node_children][$i]->set_pos($i);
+    }
+    
+    $newnode->set_global_pos($pos_number);
+}
+
+sub getPreviousSibling {
+    my $self = shift;
+    my $pos = $self->[XML::XPath::Node::node_pos];
+    return unless $self->[XML::XPath::Node::node_parent];
+    return $self->[XML::XPath::Node::node_parent]->getChildNode($pos);
+}
+
+sub getNextSibling {
+    my $self = shift;
+    my $pos = $self->[XML::XPath::Node::node_pos];
+    return unless $self->[XML::XPath::Node::node_parent];
+    return $self->[XML::XPath::Node::node_parent]->getChildNode($pos + 2);
+}
+
+sub setParentNode {
+    my $self = shift;
+    my $parent = shift;
+#    warn "SetParent of ", ref($self), " to ", $parent->[XML::XPath::Node::node_name], "\n";
+    $self->[XML::XPath::Node::node_parent] = $parent;
+}
+
+sub del_parent_link {
+    my $self = shift;
+    $self->[XML::XPath::Node::node_parent] = undef;
+}
+
+sub dispose {
+    my $self = shift;
+    foreach my $kid ($self->getChildNodes) {
+        $kid->dispose;
+    }
+    foreach my $kid ($self->getAttributeNodes) {
+        $kid->dispose;
+    }
+    foreach my $kid ($self->getNamespaceNodes) {
+        $kid->dispose;
+    }
+    $self->[XML::XPath::Node::node_parent] = undef;
+}
+
+sub to_number {
+    my $num = shift->string_value;
+    return XML::XPath::Number->new($num);
+}
+
+sub find {
+    my $node = shift;
+    my ($path) = @_;
+    my $xp = XML::XPath->new(); # new is v. lightweight
+    return $xp->find($path, $node);
+}
+
+sub findvalue {
+    my $node = shift;
+    my ($path) = @_;
+    my $xp = XML::XPath->new();
+    return $xp->findvalue($path, $node);
+}
+
+sub findnodes {
+    my $node = shift;
+    my ($path) = @_;
+    my $xp = XML::XPath->new();
+    return $xp->findnodes($path, $node);
+}
+
+sub matches {
+    my $node = shift;
+    my ($path, $context) = @_;
+    my $xp = XML::XPath->new();
+    return $xp->matches($node, $path, $context);
+}
+
+sub to_sax {
+    my $self = shift;
+    unshift @_, 'Handler' if @_ == 1;
+    my %handlers = @_;
+    
+    my $doch = $handlers{DocumentHandler} || $handlers{Handler};
+    my $dtdh = $handlers{DTDHandler} || $handlers{Handler};
+    my $enth = $handlers{EntityResolver} || $handlers{Handler};
+
+    $self->_to_sax ($doch, $dtdh, $enth);
+}
+
+sub DESTROY {}
+
+use Carp;
+
+sub _to_sax {
+    carp "_to_sax not implemented in ", ref($_[0]);
+}
+
+1;
+__END__
+
+=head1 NAME
+
+XML::XPath::Node - internal representation of a node
+
+=head1 API
+
+The Node API aims to emulate DOM to some extent, however the API
+isn't quite compatible with DOM. This is to ease transition from
+XML::DOM programming to XML::XPath. Compatibility with DOM may
+arise once XML::DOM gets namespace support.
+
+=head2 new
+
+Creates a new node. See the sub-classes for parameters to pass to new().
+
+=head2 getNodeType
+
+Returns one of ELEMENT_NODE, TEXT_NODE, COMMENT_NODE, ATTRIBUTE_NODE,
+PROCESSING_INSTRUCTION_NODE or NAMESPACE_NODE. UNKNOWN_NODE is returned
+if the sub-class doesn't implement getNodeType - but that means
+something is broken! The constants are exported by default from
+XML::XPath::Node. The constants have the same numeric value as the
+XML::DOM versions.
+
+=head2 getParentNode
+
+Returns the parent of this node, or undef if this is the root node. Note
+that the root node is the root node in terms of XPath - not the root
+element node.
+
+=head2 to_sax ( $handler | %handlers )
+
+Generates sax calls to the handler or handlers. See the PerlSAX docs for
+details (not yet implemented correctly).
+
+=head1 MORE INFO
+
+See the sub-classes for the meaning of the rest of the API:
+
+=over 4
+
+=item *
+
+L<XML::XPath::Node::Element>
+
+=item *
+
+L<XML::XPath::Node::Attribute>
+
+=item *
+
+L<XML::XPath::Node::Namespace>
+
+=item *
+
+L<XML::XPath::Node::Text>
+
+=item *
+
+L<XML::XPath::Node::Comment>
+
+=item *
+
+L<XML::XPath::Node::PI>
+
+=back
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/Node/Attribute.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Node/Attribute.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Node/Attribute.pm	(revision 20131)
@@ -0,0 +1,135 @@
+# $Id$
+
+package XML::XPath::Node::Attribute;
+
+use strict;
+use vars qw/@ISA/;
+
+@ISA = ('XML::XPath::Node');
+
+package XML::XPath::Node::AttributeImpl;
+
+use vars qw/@ISA/;
+@ISA = ('XML::XPath::NodeImpl', 'XML::XPath::Node::Attribute');
+use XML::XPath::Node ':node_keys';
+
+sub new {
+	my $class = shift;
+	my ($key, $val, $prefix) = @_;
+	
+        my $pos = XML::XPath::Node->nextPos;
+        
+        my @vals;
+        @vals[node_global_pos, node_prefix, node_key, node_value] =
+                ($pos, $prefix, $key, $val);
+	my $self = \@vals;
+        
+	bless $self, $class;
+	
+}
+
+sub getNodeType { ATTRIBUTE_NODE }
+
+sub isAttributeNode { 1; }
+
+sub getName {
+    my $self = shift;
+    $self->[node_key];
+}
+
+sub getLocalName {
+    my $self = shift;
+    my $local = $self->[node_key];
+    $local =~ s/.*://;
+    return $local;
+}
+
+sub getNodeValue {
+    my $self = shift;
+    $self->[node_value];
+}
+
+sub getData {
+    shift->getNodeValue(@_);
+}
+
+sub setNodeValue {
+    my $self = shift;
+    $self->[node_value] = shift;
+}
+
+sub getPrefix {
+	my $self = shift;
+	$self->[node_prefix];
+}
+
+sub string_value {
+	my $self = shift;
+	return $self->[node_value];
+}
+
+sub toString {
+	my $self = shift;
+	my $string = ' ';
+# 	if ($self->[node_prefix]) {
+# 		$string .= $self->[node_prefix] . ':';
+# 	}
+	$string .= join('',
+					$self->[node_key],
+					'="',
+					XML::XPath::Node::XMLescape($self->[node_value], '"&><'),
+					'"');
+	return $string;
+}
+
+sub getNamespace {
+    my $self = shift;
+    my ($prefix) = @_;
+    $prefix ||= $self->getPrefix;
+    if (my $parent = $self->getParentNode) {
+        return $parent->getNamespace($prefix);
+    }
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Attribute - a single attribute
+
+=head1 API
+
+=head2 new ( key, value, prefix )
+
+Create a new attribute node.
+
+=head2 getName
+
+Returns the key for the attribute
+
+=head2 getLocalName
+
+As getName above, but without namespace information
+
+=head2 getNodeValue / getData
+
+Returns the value
+
+=head2 setNodeValue
+
+Sets the value of the attribute node.
+
+=head2 getPrefix
+
+Returns the prefix
+
+=head2 getNamespace
+
+Return the namespace.
+
+=head2 toString
+
+Generates key="value", encoded correctly.
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/Node/Comment.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Node/Comment.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Node/Comment.pm	(revision 20131)
@@ -0,0 +1,91 @@
+# $Id$
+
+package XML::XPath::Node::Comment;
+
+use strict;
+use vars qw/@ISA/;
+
+@ISA = ('XML::XPath::Node');
+
+package XML::XPath::Node::CommentImpl;
+
+use vars qw/@ISA/;
+@ISA = ('XML::XPath::NodeImpl', 'XML::XPath::Node::Comment');
+use XML::XPath::Node ':node_keys';
+
+sub new {
+    my $class = shift;
+    my ($comment) = @_;
+    
+        my $pos = XML::XPath::Node->nextPos;
+        
+        my @vals;
+        @vals[node_global_pos, node_comment] =
+                ($pos, $comment);
+    my $self = \@vals;
+        
+    bless $self, $class;
+}
+
+sub getNodeType { COMMENT_NODE }
+
+sub isCommentNode { 1; }
+
+sub getNodeValue {
+    return shift->[node_comment];
+}
+
+sub getData {
+    shift->getNodeValue;
+}
+
+sub setNodeValue {
+    shift->[node_comment] = shift;
+}
+
+sub _to_sax {
+    my $self = shift;
+    my ($doch, $dtdh, $enth) = @_;
+    
+    $doch->comment( { Data => $self->getValue } );
+}
+
+sub comment_escape {
+    my $data = shift;
+    $data =~ s/--/&#45;&#45;/g;
+    return $data;
+}
+
+sub string_value {
+    my $self = shift;
+    return $self->[node_comment];
+}
+
+sub toString {
+    my $self = shift;
+    return '<!--' . comment_escape($self->[node_comment]) . '-->';
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Comment - an XML comment: <!--comment-->
+
+=head1 API
+
+=head2 new ( data )
+
+Create a new comment node.
+
+=head2 getValue / getData
+
+Returns the value in the comment
+
+=head2 toString
+
+Returns the comment with -- encoded as a numeric entity (if it
+exists in the comment text).
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/Node/Element.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Node/Element.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Node/Element.pm	(revision 20131)
@@ -0,0 +1,503 @@
+# $Id$
+
+package XML::XPath::Node::Element;
+
+use strict;
+use vars qw/@ISA/;
+
+@ISA = ('XML::XPath::Node');
+
+package XML::XPath::Node::ElementImpl;
+
+use vars qw/@ISA/;
+@ISA = ('XML::XPath::NodeImpl', 'XML::XPath::Node::Element');
+use XML::XPath::Node ':node_keys';
+
+sub new {
+    my $class = shift;
+    my ($tag, $prefix) = @_;
+        
+    my $pos = XML::XPath::Node->nextPos;
+
+    my @vals;
+    @vals[node_global_pos, node_prefix, node_children, node_name, node_attribs] =
+            ($pos, $prefix, [], $tag, []);
+        
+    my $self = \@vals;
+    bless $self, $class;
+}
+
+sub getNodeType { ELEMENT_NODE }
+
+sub isElementNode { 1; }
+
+sub appendChild {
+    my $self = shift;
+    my $newnode = shift;
+    if (shift) { # called from internal to XML::XPath
+#    warn "AppendChild $newnode to $self\n";
+        push @{$self->[node_children]}, $newnode;
+        $newnode->setParentNode($self);
+        $newnode->set_pos($#{$self->[node_children]});
+    }
+    else {
+        if (@{$self->[node_children]}) {
+            $self->insertAfter($newnode, $self->[node_children][-1]);
+        }
+        else {
+            my $pos_number = $self->get_global_pos() + 1;
+            
+            if (my $brother = $self->getNextSibling()) { # optimisation
+                if ($pos_number == $brother->get_global_pos()) {
+                    $self->renumber('following::node()', +5);
+                }
+            }
+            else {
+                eval {
+                    if ($pos_number == 
+                            $self->findnodes(
+                                'following::node()'
+                                )->get_node(1)->get_global_pos()) {
+                        $self->renumber('following::node()', +5);
+                    }
+                };
+            }
+            
+            push @{$self->[node_children]}, $newnode;
+            $newnode->setParentNode($self);
+            $newnode->set_pos($#{$self->[node_children]});
+            $newnode->set_global_pos($pos_number);
+        }
+    }
+}
+
+sub removeChild {
+    my $self = shift;
+    my $delnode = shift;
+    
+    my $pos = $delnode->get_pos;
+    
+#    warn "removeChild: $pos\n";
+    
+#    warn "children: ", scalar @{$self->[node_children]}, "\n";
+    
+#    my $node = $self->[node_children][$pos];
+#    warn "child at $pos is: $node\n";
+    
+    splice @{$self->[node_children]}, $pos, 1;
+    
+#    warn "children now: ", scalar @{$self->[node_children]}, "\n";
+    
+    for (my $i = $pos; $i < @{$self->[node_children]}; $i++) {
+#        warn "Changing pos of child: $i\n";
+        $self->[node_children][$i]->set_pos($i);
+    }
+    
+    $delnode->del_parent_link;
+    
+}
+
+sub appendIdElement {
+    my $self = shift;
+    my ($val, $element) = @_;
+#    warn "Adding '$val' to ID hash\n";
+    $self->[node_ids]{$val} = $element;
+}
+
+sub DESTROY {
+    my $self = shift;
+#    warn "DESTROY ELEMENT: ", $self->[node_name], "\n";
+#    warn "DESTROY ROOT\n" unless $self->[node_name];
+    
+    foreach my $kid ($self->getChildNodes) {
+        $kid && $kid->del_parent_link;
+    }
+    foreach my $attr ($self->getAttributeNodes) {
+        $attr && $attr->del_parent_link;
+    }
+    foreach my $ns ($self->getNamespaceNodes) {
+        $ns && $ns->del_parent_link;
+    }
+#     $self->[node_children] = undef;
+#     $self->[node_attribs] = undef;
+#     $self->[node_namespaces] = undef;
+}
+
+sub getName {
+    my $self = shift;
+    $self->[node_name];
+}
+
+sub getTagName {
+    shift->getName(@_);
+}
+
+sub getLocalName {
+    my $self = shift;
+    my $local = $self->[node_name];
+    $local =~ s/.*://;
+    return $local;
+}
+
+sub getChildNodes {
+    my $self = shift;
+    return wantarray ? @{$self->[node_children]} : $self->[node_children];
+}
+
+sub getChildNode {
+    my $self = shift;
+    my ($pos) = @_;
+    if ($pos < 1 || $pos > @{$self->[node_children]}) {
+        return;
+    }
+    return $self->[node_children][$pos - 1];
+}
+
+sub getFirstChild {
+    my $self = shift;
+    return unless @{$self->[node_children]};
+    return $self->[node_children][0];
+}
+
+sub getLastChild {
+    my $self = shift;
+    return unless @{$self->[node_children]};
+    return $self->[node_children][-1];
+}
+
+sub getAttributeNode {
+    my $self = shift;
+    my ($name) = @_;
+    my $attribs = $self->[node_attribs];
+    foreach my $attr (@$attribs) {
+        return $attr if $attr->getName eq $name;
+    }
+}
+
+sub getAttribute {
+    my $self = shift;
+    my $attr = $self->getAttributeNode(@_);
+    if ($attr) {
+        return $attr->getValue;
+    }
+}
+
+sub getAttributes {
+    my $self = shift;
+    if ($self->[node_attribs]) {
+        return wantarray ? @{$self->[node_attribs]} : $self->[node_attribs];
+    }
+    return wantarray ? () : [];
+}
+
+sub appendAttribute {
+    my $self = shift;
+    my $attribute = shift;
+    
+    if (shift) { # internal call
+        push @{$self->[node_attribs]}, $attribute;
+        $attribute->setParentNode($self);
+        $attribute->set_pos($#{$self->[node_attribs]});
+    }
+    else {
+        my $node_num;
+        if (@{$self->[node_attribs]}) {
+            $node_num = $self->[node_attribs][-1]->get_global_pos() + 1;
+        }
+        else {
+            $node_num = $self->get_global_pos() + 1;
+        }
+        
+        eval {
+            if (@{$self->[node_children]}) {
+                if ($node_num == $self->[node_children][-1]->get_global_pos()) {
+                    $self->renumber('descendant::node() | following::node()', +5);
+                }
+            }
+            elsif ($node_num == 
+                    $self->findnodes('following::node()')->get_node(1)->get_global_pos()) {
+                $self->renumber('following::node()', +5);
+            }
+        };
+        
+        push @{$self->[node_attribs]}, $attribute;
+        $attribute->setParentNode($self);
+        $attribute->set_pos($#{$self->[node_attribs]});
+        $attribute->set_global_pos($node_num);
+        
+    }
+}
+
+sub removeAttribute {
+    my $self = shift;
+    my $attrib = shift;
+    
+    if (!ref($attrib)) {
+        $attrib = $self->getAttributeNode($attrib);
+    }
+    
+    my $pos = $attrib->get_pos;
+    
+    splice @{$self->[node_attribs]}, $pos, 1;
+    
+    for (my $i = $pos; $i < @{$self->[node_attribs]}; $i++) {
+        $self->[node_attribs][$i]->set_pos($i);
+    }
+    
+    $attrib->del_parent_link;
+}
+
+sub setAttribute {
+    my $self = shift;
+    my ($name, $value) = @_;
+    
+    if (my $attrib = $self->getAttributeNode($name)) {
+        $attrib->setNodeValue($value);
+        return $attrib;
+    }
+    
+    my ($nsprefix) = ($name =~ /^($XML::XPath::Parser::NCName):($XML::XPath::Parser::NCName)$/o);
+    
+    if ($nsprefix && !$self->getNamespace($nsprefix)) {
+        die "No namespace matches prefix: $nsprefix";
+    }
+    
+    my $newnode = XML::XPath::Node::Attribute->new($name, $value, $nsprefix);
+    $self->appendAttribute($newnode);
+}
+
+sub setAttributeNode {
+    my $self = shift;
+    my ($node) = @_;
+    
+    if (my $attrib = $self->getAttributeNode($node->getName)) {
+        $attrib->setNodeValue($node->getValue);
+        return $attrib;
+    }
+    
+    my ($nsprefix) = ($node->getName() =~ /^($XML::XPath::Parser::NCName):($XML::XPath::Parser::NCName)$/o);
+    
+    if ($nsprefix && !$self->getNamespace($nsprefix)) {
+        die "No namespace matches prefix: $nsprefix";
+    }
+    
+    $self->appendAttribute($node);
+}
+
+sub getNamespace {
+    my $self = shift;
+    my ($prefix) = @_;
+    $prefix ||= $self->getPrefix || '#default';
+    my $namespaces = $self->[node_namespaces] || [];
+    foreach my $ns (@$namespaces) {
+        return $ns if $ns->getPrefix eq $prefix;
+    }
+    my $parent = $self->getParentNode;
+    
+    return $parent->getNamespace($prefix) if $parent;
+}
+
+sub getNamespaces {
+    my $self = shift;
+    if ($self->[node_namespaces]) {
+        return wantarray ? @{$self->[node_namespaces]} : $self->[node_namespaces];
+    }
+    return wantarray ? () : [];
+}
+
+sub getNamespaceNodes { goto &getNamespaces }
+
+sub appendNamespace {
+    my $self = shift;
+    my ($ns) = @_;
+    push @{$self->[node_namespaces]}, $ns;
+    $ns->setParentNode($self);
+    $ns->set_pos($#{$self->[node_namespaces]});
+}
+
+sub getPrefix {
+    my $self = shift;
+    $self->[node_prefix];
+}
+
+sub getExpandedName {
+    my $self = shift;
+    warn "Expanded name not implemented for ", ref($self), "\n";
+    return;
+}
+
+sub _to_sax {
+    my $self = shift;
+    my ($doch, $dtdh, $enth) = @_;
+    
+    my $tag = $self->getName;
+    my @attr;
+    
+    for my $attr ($self->getAttributes) {
+        push @attr, $attr->getName, $attr->getValue;
+    }
+    
+    my $ns = $self->getNamespace($self->[node_prefix]);
+    if ($ns) {
+        $doch->start_element( 
+                { 
+                Name => $tag,
+                Attributes => { @attr },
+                NamespaceURI => $ns->getExpanded,
+                Prefix => $ns->getPrefix,
+                LocalName => $self->getLocalName,
+                }
+            );
+    }
+    else {
+        $doch->start_element(
+                {
+                Name => $tag,
+                Attributes => { @attr },
+                }
+            );
+    }
+    
+    for my $kid ($self->getChildNodes) {
+        $kid->_to_sax($doch, $dtdh, $enth);
+    }
+    
+    if ($ns) {
+        $doch->end_element( 
+                {
+                Name => $tag,
+                NamespaceURI => $ns->getExpanded,
+                Prefix => $ns->getPrefix,
+                LocalName => $self->getLocalName
+                }
+            );
+    }
+    else {
+        $doch->end_element( { Name => $tag } );
+    }
+}
+
+sub string_value {
+    my $self = shift;
+    my $string = '';
+    foreach my $kid (@{$self->[node_children]}) {
+        if ($kid->getNodeType == ELEMENT_NODE
+                || $kid->getNodeType == TEXT_NODE) {
+            $string .= $kid->string_value;
+        }
+    }
+    return $string;
+}
+
+sub toString {
+    my $self = shift;
+    my $norecurse = shift;
+    my $string = '';
+    if (! $self->[node_name] ) {
+            # root node
+            return join('', map { $_->toString($norecurse) } @{$self->[node_children]});
+    }
+    $string .= "<" . $self->[node_name];
+    
+        $string .= join('', map { $_->toString } @{$self->[node_namespaces]});
+    
+        $string .= join('', map { $_->toString } @{$self->[node_attribs]});
+    
+    if (@{$self->[node_children]}) {
+        $string .= ">";
+
+        if (!$norecurse) {
+                        $string .= join('', map { $_->toString($norecurse) } @{$self->[node_children]});
+        }
+        
+        $string .= "</" . $self->[node_name] . ">";
+    }
+    else {
+        $string .= " />";
+    }
+    
+    return $string;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Element - an <element>
+
+=head1 API
+
+=head2 new ( name, prefix )
+
+Create a new Element node with name "name" and prefix "prefix". The name
+be "prefix:local" if prefix is defined. I know that sounds wierd, but it
+works ;-)
+
+=head2 getName
+
+Returns the name (including "prefix:" if defined) of this element.
+
+=head2 getLocalName
+
+Returns just the local part of the name (the bit after "prefix:").
+
+=head2 getChildNodes
+
+Returns the children of this element. In list context returns a list. In
+scalar context returns an array ref.
+
+=head2 getChildNode ( pos )
+
+Returns the child at position pos.
+
+=head2 appendChild ( childnode )
+
+Appends the child node to the list of current child nodes.
+
+=head2 getAttribute ( name )
+
+Returns the attribute node with key name.
+
+=head2 getAttributes / getAttributeNodes
+
+Returns the attribute nodes. In list context returns a list. In scalar
+context returns an array ref.
+
+=head2 appendAttribute ( attrib_node)
+
+Appends the attribute node to the list of attributes (XML::XPath stores
+attributes in order).
+
+=head2 getNamespace ( prefix )
+
+Returns the namespace node by the given prefix
+
+=head2 getNamespaces / getNamespaceNodes
+
+Returns the namespace nodes. In list context returns a list. In scalar
+context returns an array ref.
+
+=head2 appendNamespace ( ns_node )
+
+Appends the namespace node to the list of namespaces.
+
+=head2 getPrefix
+
+Returns the prefix of this element
+
+=head2 getExpandedName
+
+Returns the expanded name of this element (not yet implemented right).
+
+=head2 string_value
+
+For elements, the string_value is the concatenation of all string_values
+of all text-descendants of the element node in document order.
+
+=head2 toString ( [ norecurse ] )
+
+Output (and all children) the node to a string. Doesn't process children
+if the norecurse option is a true value.
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/Node/Namespace.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Node/Namespace.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Node/Namespace.pm	(revision 20131)
@@ -0,0 +1,99 @@
+# $Id$
+
+package XML::XPath::Node::Namespace;
+
+use strict;
+use vars qw/@ISA/;
+
+@ISA = ('XML::XPath::Node');
+
+package XML::XPath::Node::NamespaceImpl;
+
+use vars qw/@ISA/;
+@ISA = ('XML::XPath::NodeImpl', 'XML::XPath::Node::Namespace');
+use XML::XPath::Node ':node_keys';
+
+sub new {
+	my $class = shift;
+	my ($prefix, $expanded) = @_;
+	
+        my $pos = XML::XPath::Node->nextPos;
+        
+        my @vals;
+        @vals[node_global_pos, node_prefix, node_expanded] =
+                ($pos, $prefix, $expanded);
+	my $self = \@vals;
+        
+	bless $self, $class;
+}
+
+sub getNodeType { NAMESPACE_NODE }
+
+sub isNamespaceNode { 1; }
+
+sub getPrefix {
+	my $self = shift;
+	$self->[node_prefix];
+}
+
+sub getExpanded {
+	my $self = shift;
+	$self->[node_expanded];
+}
+
+sub getValue {
+	my $self = shift;
+	$self->[node_expanded];
+}
+
+sub getData {
+	my $self = shift;
+	$self->[node_expanded];
+}
+
+sub string_value {
+	my $self = shift;
+	$self->[node_expanded];
+}
+
+sub toString {
+	my $self = shift;
+	my $string = '';
+	return '' unless defined $self->[node_expanded];
+	if ($self->[node_prefix] eq '#default') {
+		$string .= ' xmlns="';
+	}
+	else {
+		$string .= ' xmlns:' . $self->[node_prefix] . '="';
+	}
+	$string .= XML::XPath::Node::XMLescape($self->[node_expanded], '"&<');
+	$string .= '"';
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Namespace - an XML namespace node
+
+=head1 API
+
+=head2 new ( prefix, expanded )
+
+Create a new namespace node, expanded is the expanded namespace URI.
+
+=head2 getPrefix
+
+Returns the prefix
+
+=head2 getExpanded
+
+Returns the expanded URI
+
+=head2 toString
+
+Returns a string that you can add to the list
+of attributes of an element: xmlns:prefix="expanded"
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/Node/PI.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Node/PI.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Node/PI.pm	(revision 20131)
@@ -0,0 +1,81 @@
+# $Id$
+
+package XML::XPath::Node::PI;
+
+use strict;
+use vars qw/@ISA/;
+
+@ISA = ('XML::XPath::Node');
+
+package XML::XPath::Node::PIImpl;
+
+use vars qw/@ISA/;
+@ISA = ('XML::XPath::NodeImpl', 'XML::XPath::Node::PI');
+use XML::XPath::Node ':node_keys';
+
+sub new {
+	my $class = shift;
+	my ($target, $data) = @_;
+	
+        my $pos = XML::XPath::Node->nextPos;
+        
+        my @vals;
+        @vals[node_global_pos, node_target, node_data] = 
+                ($pos, $target, $data);
+	my $self = \@vals;
+	bless $self, $class;
+}
+
+sub getNodeType { PROCESSING_INSTRUCTION_NODE }
+
+sub isPINode { 1; }
+sub isProcessingInstructionNode { 1; }
+
+sub getTarget {
+	my $self = shift;
+	$self->[node_target];
+}
+
+sub getData {
+	my $self = shift;
+	$self->[node_data];
+}
+
+sub _to_sax {
+	my $self = shift;
+	my ($doch, $dtdh, $enth) = @_;
+	# PI's not supported in PerlSAX 1
+}
+
+sub string_value {
+	my $self = shift;
+	return $self->[node_data];
+}
+
+sub toString {
+	my $self = shift;
+	return "<?" . $self->[node_target] . " " . XML::XPath::Node::XMLescape($self->[node_data], ">") . "?>";
+}
+
+1;
+__END__
+
+=head1 NAME
+
+PI - an XML processing instruction node
+
+=head1 API
+
+=head2 new ( target, data )
+
+Create a new PI node.
+
+=head2 getTarget
+
+Returns the target
+
+=head2 getData
+
+Returns the data
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/Node/Text.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Node/Text.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Node/Text.pm	(revision 20131)
@@ -0,0 +1,96 @@
+# $Id$
+
+package XML::XPath::Node::Text;
+
+use strict;
+use vars qw/@ISA/;
+
+@ISA = ('XML::XPath::Node');
+
+package XML::XPath::Node::TextImpl;
+
+use vars qw/@ISA/;
+@ISA = ('XML::XPath::NodeImpl', 'XML::XPath::Node::Text');
+use XML::XPath::Node ':node_keys';
+
+sub new {
+    my $class = shift;
+    my ($text) = @_;
+    
+        my $pos = XML::XPath::Node->nextPos;
+        
+        my @vals;
+        @vals[node_global_pos, node_text] = ($pos, $text);
+    my $self = \@vals;
+        
+    bless $self, $class;
+}
+
+sub getNodeType { TEXT_NODE }
+
+sub isTextNode { 1; }
+
+sub appendText {
+    my $self = shift;
+    my ($text) = @_;
+    $self->[node_text] .= $text;
+}
+
+sub getNodeValue {
+    my $self = shift;
+    $self->[node_text];
+}
+
+sub getData {
+    my $self = shift;
+    $self->[node_text];
+}
+
+sub setNodeValue {
+    my $self = shift;
+    $self->[node_text] = shift;
+}
+
+sub _to_sax {
+    my $self = shift;
+    my ($doch, $dtdh, $enth) = @_;
+    
+    $doch->characters( { Data => $self->getValue } );
+}
+
+sub string_value {
+    my $self = shift;
+    $self->[node_text];
+}
+
+sub toString {
+    my $self = shift;
+    XML::XPath::Node::XMLescape($self->[node_text], "<&");
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Text - an XML text node
+
+=head1 API
+
+=head2 new ( text )
+
+Create a new text node.
+
+=head2 getValue / getData
+
+Returns the text
+
+=head2 string_value
+
+Returns the text
+
+=head2 appendText ( text )
+
+Adds the given text string to this node.
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/NodeSet.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/NodeSet.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/NodeSet.pm	(revision 20131)
@@ -0,0 +1,184 @@
+# $Id$
+
+package XML::XPath::NodeSet;
+use strict;
+
+use XML::XPath::Boolean;
+
+use overload 
+		'""' => \&to_literal,
+                'bool' => \&to_boolean,
+        ;
+
+sub new {
+	my $class = shift;
+	bless [], $class;
+}
+
+sub sort {
+    my $self = CORE::shift;
+    @$self = CORE::sort { $a->get_global_pos <=> $b->get_global_pos } @$self;
+    return $self;
+}
+
+sub pop {
+	my $self = CORE::shift;
+	CORE::pop @$self;
+}
+
+sub push {
+	my $self = CORE::shift;
+	my (@nodes) = @_;
+	CORE::push @$self, @nodes;
+}
+
+sub append {
+	my $self = CORE::shift;
+	my ($nodeset) = @_;
+	CORE::push @$self, $nodeset->get_nodelist;
+}
+
+sub shift {
+	my $self = CORE::shift;
+	CORE::shift @$self;
+}
+
+sub unshift {
+	my $self = CORE::shift;
+	my (@nodes) = @_;
+	CORE::unshift @$self, @nodes;
+}
+
+sub prepend {
+	my $self = CORE::shift;
+	my ($nodeset) = @_;
+	CORE::unshift @$self, $nodeset->get_nodelist;
+}
+
+sub size {
+	my $self = CORE::shift;
+	scalar @$self;
+}
+
+sub get_node { # uses array index starting at 1, not 0
+	my $self = CORE::shift;
+	my ($pos) = @_;
+	$self->[$pos - 1];
+}
+
+sub getRootNode {
+    my $self = CORE::shift;
+    return $self->[0]->getRootNode;
+}
+
+sub get_nodelist {
+	my $self = CORE::shift;
+	@$self;
+}
+
+sub to_boolean {
+	my $self = CORE::shift;
+	return (@$self > 0) ? XML::XPath::Boolean->True : XML::XPath::Boolean->False;
+}
+
+sub string_value {
+	my $self = CORE::shift;
+	return '' unless @$self;
+	return $self->[0]->string_value;
+}
+
+sub to_literal {
+	my $self = CORE::shift;
+	return XML::XPath::Literal->new(
+			join('', map { $_->string_value } @$self)
+			);
+}
+
+sub to_number {
+	my $self = CORE::shift;
+	return XML::XPath::Number->new(
+			$self->to_literal
+			);
+}
+
+1;
+__END__
+
+=head1 NAME
+
+XML::XPath::NodeSet - a list of XML document nodes
+
+=head1 DESCRIPTION
+
+An XML::XPath::NodeSet object contains an ordered list of nodes. The nodes
+each take the same format as described in L<XML::XPath::XMLParser>.
+
+=head1 SYNOPSIS
+
+	my $results = $xp->find('//someelement');
+	if (!$results->isa('XML::XPath::NodeSet')) {
+		print "Found $results\n";
+		exit;
+	}
+	foreach my $context ($results->get_nodelist) {
+		my $newresults = $xp->find('./other/element', $context);
+		...
+	}
+
+=head1 API
+
+=head2 new()
+
+You will almost never have to create a new NodeSet object, as it is all
+done for you by XPath.
+
+=head2 get_nodelist()
+
+Returns a list of nodes. See L<XML::XPath::XMLParser> for the format of
+the nodes.
+
+=head2 string_value()
+
+Returns the string-value of the first node in the list.
+See the XPath specification for what "string-value" means.
+
+=head2 to_literal()
+
+Returns the concatenation of all the string-values of all
+the nodes in the list.
+
+=head2 get_node($pos)
+
+Returns the node at $pos. The node position in XPath is based at 1, not 0.
+
+=head2 size()
+
+Returns the number of nodes in the NodeSet.
+
+=head2 pop()
+
+Equivalent to perl's pop function.
+
+=head2 push(@nodes)
+
+Equivalent to perl's push function.
+
+=head2 append($nodeset)
+
+Given a nodeset, appends the list of nodes in $nodeset to the end of the
+current list.
+
+=head2 shift()
+
+Equivalent to perl's shift function.
+
+=head2 unshift(@nodes)
+
+Equivalent to perl's unshift function.
+
+=head2 prepend($nodeset)
+
+Given a nodeset, prepends the list of nodes in $nodeset to the front of
+the current list.
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/Number.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Number.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Number.pm	(revision 20131)
@@ -0,0 +1,87 @@
+# $Id$
+
+package XML::XPath::Number;
+use XML::XPath::Boolean;
+use XML::XPath::Literal;
+use strict;
+
+use overload
+        '""' => \&value,
+        '0+' => \&value,
+        '<=>' => \&cmp;
+
+sub new {
+    my $class = shift;
+    my $number = shift;
+    if ($number !~ /^\s*[+-]?(\d+(\.\d*)?|\.\d+)\s*$/) {
+        $number = undef;
+    }
+    else {
+        $number =~ s/^\s*(.*)\s*$/$1/;
+    }
+    bless \$number, $class;
+}
+
+sub as_string {
+    my $self = shift;
+    defined $$self ? $$self : 'NaN';
+}
+
+sub as_xml {
+    my $self = shift;
+    return "<Number>" . (defined($$self) ? $$self : 'NaN') . "</Number>\n";
+}
+
+sub value {
+    my $self = shift;
+    $$self;
+}
+
+sub cmp {
+    my $self = shift;
+    my ($other, $swap) = @_;
+    if ($swap) {
+        return $other <=> $$self;
+    }
+    return $$self <=> $other;
+}
+
+sub evaluate {
+    my $self = shift;
+    $self;
+}
+
+sub to_boolean {
+    my $self = shift;
+    return $$self ? XML::XPath::Boolean->True : XML::XPath::Boolean->False;
+}
+
+sub to_literal { XML::XPath::Literal->new($_[0]->as_string); }
+sub to_number { $_[0]; }
+
+sub string_value { return $_[0]->value }
+
+1;
+__END__
+
+=head1 NAME
+
+XML::XPath::Number - Simple numeric values.
+
+=head1 DESCRIPTION
+
+This class holds simple numeric values. It doesn't support -0, +/- Infinity,
+or NaN, as the XPath spec says it should, but I'm not hurting anyone I don't think.
+
+=head1 API
+
+=head2 new($num)
+
+Creates a new XML::XPath::Number object, with the value in $num. Does some
+rudimentary numeric checking on $num to ensure it actually is a number.
+
+=head2 value()
+
+Also as overloaded stringification. Returns the numeric value held.
+
+=cut
Index: /gsdl/stable/perllib/cpan/XML/XPath/Parser.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Parser.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Parser.pm	(revision 20131)
@@ -0,0 +1,821 @@
+# $Id$
+
+package XML::XPath::Parser;
+
+use strict;
+use vars qw/
+        $NCName 
+        $QName 
+        $NCWild
+        $QNWild
+        $NUMBER_RE 
+        $NODE_TYPE 
+        $AXIS_NAME 
+        %AXES 
+        $LITERAL
+        %CACHE/;
+
+use XML::XPath::XMLParser;
+use XML::XPath::Step;
+use XML::XPath::Expr;
+use XML::XPath::Function;
+use XML::XPath::LocationPath;
+use XML::XPath::Variable;
+use XML::XPath::Literal;
+use XML::XPath::Number;
+use XML::XPath::NodeSet;
+
+# Axis name to principal node type mapping
+%AXES = (
+        'ancestor' => 'element',
+        'ancestor-or-self' => 'element',
+        'attribute' => 'attribute',
+        'namespace' => 'namespace',
+        'child' => 'element',
+        'descendant' => 'element',
+        'descendant-or-self' => 'element',
+        'following' => 'element',
+        'following-sibling' => 'element',
+        'parent' => 'element',
+        'preceding' => 'element',
+        'preceding-sibling' => 'element',
+        'self' => 'element',
+        );
+
+$NCName = '([A-Za-z_][\w\\.\\-]*)';
+$QName = "($NCName:)?$NCName";
+$NCWild = "${NCName}:\\*";
+$QNWild = "\\*";
+$NODE_TYPE = '((text|comment|processing-instruction|node)\\(\\))';
+$AXIS_NAME = '(' . join('|', keys %AXES) . ')::';
+$NUMBER_RE = '\d+(\\.\d*)?|\\.\d+';
+$LITERAL = '\\"[^\\"]*\\"|\\\'[^\\\']*\\\'';
+
+sub new {
+    my $class = shift;
+    my $self = bless {}, $class;
+    debug("New Parser being created.\n");
+    $self->{context_set} = XML::XPath::NodeSet->new();
+    $self->{context_pos} = undef; # 1 based position in array context
+    $self->{context_size} = 0; # total size of context
+    $self->clear_namespaces();
+    $self->{vars} = {};
+    $self->{direction} = 'forward';
+    $self->{cache} = {};
+    return $self;
+}
+
+sub get_var {
+    my $self = shift;
+    my $var = shift;
+    $self->{vars}->{$var};
+}
+
+sub set_var {
+    my $self = shift;
+    my $var = shift;
+    my $val = shift;
+    $self->{vars}->{$var} = $val;
+}
+
+sub set_namespace {
+    my $self = shift;
+    my ($prefix, $expanded) = @_;
+    $self->{namespaces}{$prefix} = $expanded;
+}
+
+sub clear_namespaces {
+    my $self = shift;
+    $self->{namespaces} = {};
+}
+
+sub get_namespace {
+    my $self = shift;
+    my ($prefix, $node) = @_;
+    if (my $ns = $self->{namespaces}{$prefix}) {
+        return $ns;
+    }
+    if (my $nsnode = $node->getNamespace($prefix)) {
+        return $nsnode->getValue();
+    }
+}
+
+sub get_context_set { $_[0]->{context_set}; }
+sub set_context_set { $_[0]->{context_set} = $_[1]; }
+sub get_context_pos { $_[0]->{context_pos}; }
+sub set_context_pos { $_[0]->{context_pos} = $_[1]; }
+sub get_context_size { $_[0]->{context_set}->size; }
+sub get_context_node { $_[0]->{context_set}->get_node($_[0]->{context_pos}); }
+
+sub my_sub {
+    return (caller(1))[3];
+}
+
+sub parse {
+    my $self = shift;
+    my $path = shift;
+    if ($CACHE{$path}) {
+        return $CACHE{$path};
+    }
+    my $tokens = $self->tokenize($path);
+
+    $self->{_tokpos} = 0;
+    my $tree = $self->analyze($tokens);
+    
+    if ($self->{_tokpos} < scalar(@$tokens)) {
+        # didn't manage to parse entire expression - throw an exception
+        die "Parse of expression $path failed - junk after end of expression: $tokens->[$self->{_tokpos}]";
+    }
+    
+    $CACHE{$path} = $tree;
+    
+    debug("PARSED Expr to:\n", $tree->as_string, "\n") if $XML::XPath::Debug;
+    
+    return $tree;
+}
+
+sub tokenize {
+    my $self = shift;
+    my $path = shift;
+    study $path;
+    
+    my @tokens;
+    
+    debug("Parsing: $path\n");
+    
+    # Bug: We don't allow "'@' NodeType" which is in the grammar, but I think is just plain stupid.
+
+    while($path =~ m/\G
+        \s* # ignore all whitespace
+        ( # tokens
+            $LITERAL|
+            $NUMBER_RE| # Match digits
+            \.\.| # match parent
+            \.| # match current
+            ($AXIS_NAME)?$NODE_TYPE| # match tests
+            processing-instruction|
+            \@($NCWild|$QName|$QNWild)| # match attrib
+            \$$QName| # match variable reference
+            ($AXIS_NAME)?($NCWild|$QName|$QNWild)| # match NCName,NodeType,Axis::Test
+            \!=|<=|\-|>=|\/\/|and|or|mod|div| # multi-char seps
+            [,\+=\|<>\/\(\[\]\)]| # single char seps
+            (?<!(\@|\(|\[))\*| # multiply operator rules (see xpath spec)
+            (?<!::)\*|
+            $ # match end of query
+        )
+        \s* # ignore all whitespace
+        /gcxso) {
+
+        my ($token) = ($1);
+
+        if (length($token)) {
+            debug("TOKEN: $token\n");
+            push @tokens, $token;
+        }
+        
+    }
+    
+    if (pos($path) < length($path)) {
+        my $marker = ("." x (pos($path)-1));
+        $path = substr($path, 0, pos($path) + 8) . "...";
+        $path =~ s/\n/ /g;
+        $path =~ s/\t/ /g;
+        die "Query:\n",
+            "$path\n",
+            $marker, "^^^\n",
+            "Invalid query somewhere around here (I think)\n";
+    }
+    
+    return \@tokens;
+}
+
+sub analyze {
+    my $self = shift;
+    my $tokens = shift;
+    # lexical analysis
+    
+    return Expr($self, $tokens);
+}
+
+sub match {
+    my ($self, $tokens, $match, $fatal) = @_;
+    
+    $self->{_curr_match} = '';
+    return 0 unless $self->{_tokpos} < @$tokens;
+
+    local $^W;
+    
+#    debug ("match: $match\n");
+    
+    if ($tokens->[$self->{_tokpos}] =~ /^$match$/) {
+        $self->{_curr_match} = $tokens->[$self->{_tokpos}];
+        $self->{_tokpos}++;
+        return 1;
+    }
+    else {
+        if ($fatal) {
+            die "Invalid token: ", $tokens->[$self->{_tokpos}], "\n";
+        }
+        else {
+            return 0;
+        }
+    }
+}
+
+sub Expr {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    return OrExpr($self, $tokens);
+}
+
+sub OrExpr {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    my $expr = AndExpr($self, $tokens); 
+    while (match($self, $tokens, 'or')) {
+        my $or_expr = XML::XPath::Expr->new($self);
+        $or_expr->set_lhs($expr);
+        $or_expr->set_op('or');
+
+        my $rhs = AndExpr($self, $tokens);
+
+        $or_expr->set_rhs($rhs);
+        $expr = $or_expr;
+    }
+    
+    return $expr;
+}
+
+sub AndExpr {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    my $expr = EqualityExpr($self, $tokens);
+    while (match($self, $tokens, 'and')) {
+        my $and_expr = XML::XPath::Expr->new($self);
+        $and_expr->set_lhs($expr);
+        $and_expr->set_op('and');
+        
+        my $rhs = EqualityExpr($self, $tokens);
+        
+        $and_expr->set_rhs($rhs);
+        $expr = $and_expr;
+    }
+    
+    return $expr;
+}
+
+sub EqualityExpr {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    my $expr = RelationalExpr($self, $tokens);
+    while (match($self, $tokens, '!?=')) {
+        my $eq_expr = XML::XPath::Expr->new($self);
+        $eq_expr->set_lhs($expr);
+        $eq_expr->set_op($self->{_curr_match});
+        
+        my $rhs = RelationalExpr($self, $tokens);
+        
+        $eq_expr->set_rhs($rhs);
+        $expr = $eq_expr;
+    }
+    
+    return $expr;
+}
+
+sub RelationalExpr {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    my $expr = AdditiveExpr($self, $tokens);
+    while (match($self, $tokens, '(<|>|<=|>=)')) {
+        my $rel_expr = XML::XPath::Expr->new($self);
+        $rel_expr->set_lhs($expr);
+        $rel_expr->set_op($self->{_curr_match});
+        
+        my $rhs = AdditiveExpr($self, $tokens);
+        
+        $rel_expr->set_rhs($rhs);
+        $expr = $rel_expr;
+    }
+    
+    return $expr;
+}
+
+sub AdditiveExpr {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    my $expr = MultiplicativeExpr($self, $tokens);
+    while (match($self, $tokens, '[\\+\\-]')) {
+        my $add_expr = XML::XPath::Expr->new($self);
+        $add_expr->set_lhs($expr);
+        $add_expr->set_op($self->{_curr_match});
+        
+        my $rhs = MultiplicativeExpr($self, $tokens);
+        
+        $add_expr->set_rhs($rhs);
+        $expr = $add_expr;
+    }
+    
+    return $expr;
+}
+
+sub MultiplicativeExpr {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    my $expr = UnaryExpr($self, $tokens);
+    while (match($self, $tokens, '(\\*|div|mod)')) {
+        my $mult_expr = XML::XPath::Expr->new($self);
+        $mult_expr->set_lhs($expr);
+        $mult_expr->set_op($self->{_curr_match});
+        
+        my $rhs = UnaryExpr($self, $tokens);
+        
+        $mult_expr->set_rhs($rhs);
+        $expr = $mult_expr;
+    }
+    
+    return $expr;
+}
+
+sub UnaryExpr {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    if (match($self, $tokens, '-')) {
+        my $expr = XML::XPath::Expr->new($self);
+        $expr->set_lhs(XML::XPath::Number->new(0));
+        $expr->set_op('-');
+        $expr->set_rhs(UnaryExpr($self, $tokens));
+        return $expr;
+    }
+    else {
+        return UnionExpr($self, $tokens);
+    }
+}
+
+sub UnionExpr {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    my $expr = PathExpr($self, $tokens);
+    while (match($self, $tokens, '\\|')) {
+        my $un_expr = XML::XPath::Expr->new($self);
+        $un_expr->set_lhs($expr);
+        $un_expr->set_op('|');
+        
+        my $rhs = PathExpr($self, $tokens);
+        
+        $un_expr->set_rhs($rhs);
+        $expr = $un_expr;
+    }
+    
+    return $expr;
+}
+
+sub PathExpr {
+    my ($self, $tokens) = @_;
+
+    debug("in SUB\n");
+    
+    # PathExpr is LocationPath | FilterExpr | FilterExpr '//?' RelativeLocationPath
+    
+    # Since we are being predictive we need to find out which function to call next, then.
+        
+    # LocationPath either starts with "/", "//", ".", ".." or a proper Step.
+    
+    my $expr = XML::XPath::Expr->new($self);
+    
+    my $test = $tokens->[$self->{_tokpos}];
+    
+    # Test for AbsoluteLocationPath and AbbreviatedRelativeLocationPath
+    if ($test =~ /^(\/\/?|\.\.?)$/) {
+        # LocationPath
+        $expr->set_lhs(LocationPath($self, $tokens));
+    }
+    # Test for AxisName::...
+    elsif (is_step($self, $tokens)) {
+        $expr->set_lhs(LocationPath($self, $tokens));
+    }
+    else {
+        # Not a LocationPath
+        # Use FilterExpr instead:
+        
+        $expr = FilterExpr($self, $tokens);
+        if (match($self, $tokens, '//?')) {
+            my $loc_path = XML::XPath::LocationPath->new();
+            push @$loc_path, $expr;
+            if ($self->{_curr_match} eq '//') {
+                push @$loc_path, XML::XPath::Step->new($self, 'descendant-or-self', 
+                                        XML::XPath::Step::test_nt_node);
+            }
+            push @$loc_path, RelativeLocationPath($self, $tokens);
+            my $new_expr = XML::XPath::Expr->new($self);
+            $new_expr->set_lhs($loc_path);
+            return $new_expr;
+        }
+    }
+    
+    return $expr;
+}
+
+sub FilterExpr {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    my $expr = PrimaryExpr($self, $tokens);
+    while (match($self, $tokens, '\\[')) {
+        # really PredicateExpr...
+        $expr->push_predicate(Expr($self, $tokens));
+        match($self, $tokens, '\\]', 1);
+    }
+    
+    return $expr;
+}
+
+sub PrimaryExpr {
+    my ($self, $tokens) = @_;
+
+    debug("in SUB\n");
+    
+    my $expr = XML::XPath::Expr->new($self);
+    
+    if (match($self, $tokens, $LITERAL)) {
+        # new Literal with $self->{_curr_match}...
+        $self->{_curr_match} =~ m/^(["'])(.*)\1$/;
+        $expr->set_lhs(XML::XPath::Literal->new($2));
+    }
+    elsif (match($self, $tokens, $NUMBER_RE)) {
+        # new Number with $self->{_curr_match}...
+        $expr->set_lhs(XML::XPath::Number->new($self->{_curr_match}));
+    }
+    elsif (match($self, $tokens, '\\(')) {
+        $expr->set_lhs(Expr($self, $tokens));
+        match($self, $tokens, '\\)', 1);
+    }
+    elsif (match($self, $tokens, "\\\$$QName")) {
+        # new Variable with $self->{_curr_match}...
+        $self->{_curr_match} =~ /^\$(.*)$/;
+        $expr->set_lhs(XML::XPath::Variable->new($self, $1));
+    }
+    elsif (match($self, $tokens, $QName)) {
+        # check match not Node_Type - done in lexer...
+        # new Function
+        my $func_name = $self->{_curr_match};
+        match($self, $tokens, '\\(', 1);
+        $expr->set_lhs(
+                XML::XPath::Function->new(
+                    $self,
+                    $func_name,
+                    Arguments($self, $tokens)
+                )
+            );
+        match($self, $tokens, '\\)', 1);
+    }
+    else {
+        die "Not a PrimaryExpr at ", $tokens->[$self->{_tokpos}], "\n";
+    }
+    
+    return $expr;
+}
+
+sub Arguments {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    my @args;
+    
+    if($tokens->[$self->{_tokpos}] eq ')') {
+        return \@args;
+    }
+    
+    push @args, Expr($self, $tokens);
+    while (match($self, $tokens, ',')) {
+        push @args, Expr($self, $tokens);
+    }
+    
+    return \@args;
+}
+
+sub LocationPath {
+    my ($self, $tokens) = @_;
+
+    debug("in SUB\n");
+    
+    my $loc_path = XML::XPath::LocationPath->new();
+    
+    if (match($self, $tokens, '/')) {
+        # root
+        debug("SUB: Matched root\n");
+        push @$loc_path, XML::XPath::Root->new();
+        if (is_step($self, $tokens)) {
+            debug("Next is step\n");
+            push @$loc_path, RelativeLocationPath($self, $tokens);
+        }
+    }
+    elsif (match($self, $tokens, '//')) {
+        # root
+        push @$loc_path, XML::XPath::Root->new();
+        my $optimised = optimise_descendant_or_self($self, $tokens);
+        if (!$optimised) {
+            push @$loc_path, XML::XPath::Step->new($self, 'descendant-or-self',
+                                XML::XPath::Step::test_nt_node);
+            push @$loc_path, RelativeLocationPath($self, $tokens);
+        }
+        else {
+            push @$loc_path, $optimised, RelativeLocationPath($self, $tokens);
+        }
+    }
+    else {
+        push @$loc_path, RelativeLocationPath($self, $tokens);
+    }
+    
+    return $loc_path;
+}
+
+sub optimise_descendant_or_self {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    my $tokpos = $self->{_tokpos};
+    
+    # // must be followed by a Step.
+    if ($tokens->[$tokpos+1] && $tokens->[$tokpos+1] eq '[') {
+        # next token is a predicate
+        return;
+    }
+    elsif ($tokens->[$tokpos] =~ /^\.\.?$/) {
+        # abbreviatedStep - can't optimise.
+        return;
+    }                                                                                              
+    else {
+        debug("Trying to optimise //\n");
+        my $step = Step($self, $tokens);
+        if ($step->{axis} ne 'child') {
+            # can't optimise axes other than child for now...
+            $self->{_tokpos} = $tokpos;
+            return;
+        }
+        $step->{axis} = 'descendant';
+        $step->{axis_method} = 'axis_descendant';
+        $self->{_tokpos}--;
+        $tokens->[$self->{_tokpos}] = '.';
+        return $step;
+    }
+}
+
+sub RelativeLocationPath {
+    my ($self, $tokens) = @_;
+    
+    debug("in SUB\n");
+    
+    my @steps;
+    
+    push @steps, Step($self, $tokens);
+    while (match($self, $tokens, '//?')) {
+        if ($self->{_curr_match} eq '//') {
+            my $optimised = optimise_descendant_or_self($self, $tokens);
+            if (!$optimised) {
+                push @steps, XML::XPath::Step->new($self, 'descendant-or-self',
+                                        XML::XPath::Step::test_nt_node);
+            }
+            else {
+                push @steps, $optimised;
+            }
+        }
+        push @steps, Step($self, $tokens);
+        if (@steps > 1 && 
+                $steps[-1]->{axis} eq 'self' && 
+                $steps[-1]->{test} == XML::XPath::Step::test_nt_node) {
+            pop @steps;
+        }
+    }
+    
+    return @steps;
+}
+
+sub Step {
+    my ($self, $tokens) = @_;
+
+    debug("in SUB\n");
+    
+    if (match($self, $tokens, '\\.')) {
+        # self::node()
+        return XML::XPath::Step->new($self, 'self', XML::XPath::Step::test_nt_node);
+    }
+    elsif (match($self, $tokens, '\\.\\.')) {
+        # parent::node()
+        return XML::XPath::Step->new($self, 'parent', XML::XPath::Step::test_nt_node);
+    }
+    else {
+        # AxisSpecifier NodeTest Predicate(s?)
+        my $token = $tokens->[$self->{_tokpos}];
+        
+        debug("SUB: Checking $token\n");
+        
+        my $step;
+        if ($token eq 'processing-instruction') {
+            $self->{_tokpos}++;
+            match($self, $tokens, '\\(', 1);
+            match($self, $tokens, $LITERAL);
+            $self->{_curr_match} =~ /^["'](.*)["']$/;
+            $step = XML::XPath::Step->new($self, 'child',
+                                    XML::XPath::Step::test_nt_pi,
+                        XML::XPath::Literal->new($1));
+            match($self, $tokens, '\\)', 1);
+        }
+        elsif ($token =~ /^\@($NCWild|$QName|$QNWild)$/o) {
+            $self->{_tokpos}++;
+                        if ($token eq '@*') {
+                            $step = XML::XPath::Step->new($self,
+                                    'attribute',
+                                    XML::XPath::Step::test_attr_any,
+                                    '*');
+                        }
+                        elsif ($token =~ /^\@($NCName):\*$/o) {
+                            $step = XML::XPath::Step->new($self,
+                                    'attribute',
+                                    XML::XPath::Step::test_attr_ncwild,
+                                    $1);
+                        }
+                        elsif ($token =~ /^\@($QName)$/o) {
+                            $step = XML::XPath::Step->new($self,
+                                    'attribute',
+                                    XML::XPath::Step::test_attr_qname,
+                                    $1);
+                        }
+        }
+        elsif ($token =~ /^($NCName):\*$/o) { # ns:*
+            $self->{_tokpos}++;
+            $step = XML::XPath::Step->new($self, 'child', 
+                                XML::XPath::Step::test_ncwild,
+                                $1);
+        }
+        elsif ($token =~ /^$QNWild$/o) { # *
+            $self->{_tokpos}++;
+            $step = XML::XPath::Step->new($self, 'child', 
+                                XML::XPath::Step::test_any,
+                                $token);
+        }
+        elsif ($token =~ /^$QName$/o) { # name:name
+            $self->{_tokpos}++;
+            $step = XML::XPath::Step->new($self, 'child', 
+                                XML::XPath::Step::test_qname,
+                                $token);
+        }
+        elsif ($token eq 'comment()') {
+                    $self->{_tokpos}++;
+            $step = XML::XPath::Step->new($self, 'child',
+                            XML::XPath::Step::test_nt_comment);
+        }
+        elsif ($token eq 'text()') {
+            $self->{_tokpos}++;
+            $step = XML::XPath::Step->new($self, 'child',
+                    XML::XPath::Step::test_nt_text);
+        }
+        elsif ($token eq 'node()') {
+            $self->{_tokpos}++;
+            $step = XML::XPath::Step->new($self, 'child',
+                    XML::XPath::Step::test_nt_node);
+        }
+        elsif ($token eq 'processing-instruction()') {
+            $self->{_tokpos}++;
+            $step = XML::XPath::Step->new($self, 'child',
+                    XML::XPath::Step::test_nt_pi);
+        }
+        elsif ($token =~ /^$AXIS_NAME($NCWild|$QName|$QNWild|$NODE_TYPE)$/o) {
+                    my $axis = $1;
+                    $self->{_tokpos}++;
+                    $token = $2;
+            if ($token eq 'processing-instruction') {
+                match($self, $tokens, '\\(', 1);
+                match($self, $tokens, $LITERAL);
+                $self->{_curr_match} =~ /^["'](.*)["']$/;
+                $step = XML::XPath::Step->new($self, $axis,
+                                        XML::XPath::Step::test_nt_pi,
+                            XML::XPath::Literal->new($1));
+                match($self, $tokens, '\\)', 1);
+            }
+            elsif ($token =~ /^($NCName):\*$/o) { # ns:*
+                $step = XML::XPath::Step->new($self, $axis, 
+                                    (($axis eq 'attribute') ? 
+                                    XML::XPath::Step::test_attr_ncwild
+                                        :
+                                    XML::XPath::Step::test_ncwild),
+                                    $1);
+            }
+            elsif ($token =~ /^$QNWild$/o) { # *
+                $step = XML::XPath::Step->new($self, $axis, 
+                                    (($axis eq 'attribute') ?
+                                    XML::XPath::Step::test_attr_any
+                                        :
+                                    XML::XPath::Step::test_any),
+                                    $token);
+            }
+            elsif ($token =~ /^$QName$/o) { # name:name
+                $step = XML::XPath::Step->new($self, $axis, 
+                                    (($axis eq 'attribute') ?
+                                    XML::XPath::Step::test_attr_qname
+                                        :
+                                    XML::XPath::Step::test_qname),
+                                    $token);
+            }
+            elsif ($token eq 'comment()') {
+                $step = XML::XPath::Step->new($self, $axis,
+                                XML::XPath::Step::test_nt_comment);
+            }
+            elsif ($token eq 'text()') {
+                $step = XML::XPath::Step->new($self, $axis,
+                        XML::XPath::Step::test_nt_text);
+            }
+            elsif ($token eq 'node()') {
+                $step = XML::XPath::Step->new($self, $axis,
+                        XML::XPath::Step::test_nt_node);
+            }
+            elsif ($token eq 'processing-instruction()') {
+                $step = XML::XPath::Step->new($self, $axis,
+                        XML::XPath::Step::test_nt_pi);
+            }
+            else {
+                die "Shouldn't get here";
+            }
+        }
+        else {
+            die "token $token doesn't match format of a 'Step'\n";
+        }
+        
+        while (match($self, $tokens, '\\[')) {
+            push @{$step->{predicates}}, Expr($self, $tokens);
+            match($self, $tokens, '\\]', 1);
+        }
+        
+        return $step;
+    }
+}
+
+sub is_step {
+    my ($self, $tokens) = @_;
+    
+    my $token = $tokens->[$self->{_tokpos}];
+    
+    return unless defined $token;
+        
+    debug("SUB: Checking if '$token' is a step\n");
+    
+        local $^W;
+        
+    if ($token eq 'processing-instruction') {
+        return 1;
+    }
+    elsif ($token =~ /^\@($NCWild|$QName|$QNWild)$/o) {
+        return 1;
+    }
+    elsif ($token =~ /^($NCWild|$QName|$QNWild)$/o && $tokens->[$self->{_tokpos}+1] ne '(') {
+        return 1;
+    }
+    elsif ($token =~ /^$NODE_TYPE$/o) {
+        return 1;
+    }
+    elsif ($token =~ /^$AXIS_NAME($NCWild|$QName|$QNWild|$NODE_TYPE)$/o) {
+        return 1;
+    }
+    
+    debug("SUB: '$token' not a step\n");
+
+    return;
+}
+
+sub debug {
+    return unless $XML::XPath::Debug;
+    
+    my ($pkg, $file, $line, $sub) = caller(1);
+    
+    $sub =~ s/^$pkg\:://;
+    
+    while (@_) {
+        my $x = shift;
+        $x =~ s/\bPKG\b/$pkg/g;
+        $x =~ s/\bLINE\b/$line/g;
+        $x =~ s/\bSUB\b/$sub/g;
+        print STDERR $x;
+    }
+}
+
+1;
Index: /gsdl/stable/perllib/cpan/XML/XPath/PerlSAX.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/PerlSAX.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/PerlSAX.pm	(revision 20131)
@@ -0,0 +1,166 @@
+# $Id$
+
+package XML::XPath::PerlSAX;
+use XML::XPath::XMLParser;
+use strict;
+
+sub new {
+	my $class = shift;
+	my %args = @_;
+	bless \%args, $class;
+}
+
+sub parse {
+	my $self = shift;
+
+	die "XML::XPath::PerlSAX: parser instance ($self) already parsing\n"
+		if (defined $self->{ParseOptions});
+
+	# If there's one arg and it's an array ref, assume it's a node we're parsing
+	my $args;
+	if (@_ == 1 && ref($_[0]) =~ /^(text|comment|element|namespace|attribute|pi)$/) {
+#		warn "Parsing node\n";
+		my $node = shift;
+#		warn "PARSING: $node ", XML::XPath::XMLParser::as_string($node), "\n\n";
+		$args = { Source => { Node => $node } };
+	}
+	else {
+		$args = (@_ == 1) ? shift : { @_ };
+	}
+
+	my $parse_options = { %$self, %$args };
+	$self->{ParseOptions} = $parse_options;
+
+	# ensure that we have at least one source
+	if (!defined $parse_options->{Source} ||
+		!defined $parse_options->{Source}{Node}) {
+		die "XML::XPath::PerlSAX: no source defined for parse\n";
+	}
+
+	# assign default Handler to any undefined handlers
+	if (defined $parse_options->{Handler}) {
+		$parse_options->{DocumentHandler} = $parse_options->{Handler}
+			if (!defined $parse_options->{DocumentHandler});
+	}
+
+	# ensure that we have a DocumentHandler
+	if (!defined $parse_options->{DocumentHandler}) {
+		die "XML::XPath::PerlSAX: no Handler or DocumentHandler defined for parse\n";
+	}
+
+	# cache DocumentHandler in self for callbacks
+	$self->{DocumentHandler} = $parse_options->{DocumentHandler};
+
+	if ((ref($parse_options->{Source}{Node}) eq 'element') &&
+			!($parse_options->{Source}{Node}->[node_parent])) {
+		# Got root node
+		$self->{DocumentHandler}->start_document( { } );
+		$self->parse_node($parse_options->{Source}{Node});
+		return $self->{DocumentHandler}->end_document( { } );
+	}
+	else {
+		$self->parse_node($parse_options->{Source}{Node});
+	}
+
+	# clean up parser instance
+	delete $self->{ParseOptions};
+	delete $self->{DocumentHandler};
+
+}
+
+sub parse_node {
+	my $self = shift;
+	my $node = shift;
+#	warn "parse_node $node\n";
+	if (ref($node) eq 'element' && $node->[node_parent]) {
+		# bundle up attributes
+		my @attribs;
+		foreach my $attr (@{$node->[node_attribs]}) {
+			if ($attr->[node_prefix]) {
+				push @attribs, $attr->[node_prefix] . ":" . $attr->[node_key];
+			}
+			else {
+				push @attribs, $attr->[node_key];
+			}
+			push @attribs, $attr->[node_value];
+		}
+		
+		$self->{DocumentHandler}->start_element(
+				{ Name => $node->[node_name],
+				  Attributes => \@attribs,
+				}
+			);
+		foreach my $kid (@{$node->[node_children]}) {
+			$self->parse_node($kid);
+		}
+		$self->{DocumentHandler}->end_element(
+				{
+					Name => $node->[node_name],
+				}
+			);
+	}
+	elsif (ref($node) eq 'text') {
+		$self->{DocumentHandler}->characters($node->[node_text]);
+	}
+	elsif (ref($node) eq 'comment') {
+		$self->{DocumentHandler}->comment($node->[node_comment]);
+	}
+	elsif (ref($node) eq 'pi') {
+		$self->{DocumentHandler}->processing_instruction(
+				{
+					Target => $node->[node_target],
+					Data => $node->[node_data]
+				}
+			);
+	}
+	elsif (ref($node) eq 'element') { # root node
+		# just do kids
+		foreach my $kid (@{$node->[node_children]}) {
+			$self->parse_node($kid);
+		}
+	}
+	else {
+		die "Unknown node type: '", ref($node), "' ", scalar(@$node), "\n";
+	}
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+XML::XPath::PerlSAX - A PerlSAX event generator for my wierd node structure
+
+=head1 SYNOPSIS
+
+	use XML::XPath;
+	use XML::XPath::PerlSAX;
+	use XML::DOM::PerlSAX;
+	
+	my $xp = XML::XPath->new(filename => 'test.xhtml');
+	my $paras = $xp->find('/html/body/p');
+	
+	my $handler = XML::DOM::PerlSAX->new();
+	my $generator = XML::XPath::PerlSAX->new( Handler => $handler );
+	
+	foreach my $node ($paras->get_nodelist) {
+		my $domtree = $generator->parse($node);
+		# do something with $domtree
+	}
+
+=head1 DESCRIPTION
+
+This module generates PerlSAX events to pass to a PerlSAX handler such
+as XML::DOM::PerlSAX. It operates specifically on my wierd tree format.
+
+Unfortunately SAX doesn't seem to cope with namespaces, so these are
+lost completely. I believe SAX2 is doing namespaces.
+
+=head1 Other
+
+The XML::DOM::PerlSAX handler I tried was completely broken (didn't even
+compile before I patched it a bit), so I don't know how correct this
+is or how far it will work.
+
+This software may only be distributed as part of the XML::XPath package.
Index: /gsdl/stable/perllib/cpan/XML/XPath/Root.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Root.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Root.pm	(revision 20131)
@@ -0,0 +1,36 @@
+# $Id$
+
+package XML::XPath::Root;
+use strict;
+use XML::XPath::XMLParser;
+use XML::XPath::NodeSet;
+
+sub new {
+	my $class = shift;
+	my $self; # actually don't need anything here - just a placeholder
+	bless \$self, $class;
+}
+
+sub as_string {
+	# do nothing
+}
+
+sub as_xml {
+    return "<Root/>\n";
+}
+
+sub evaluate {
+	my $self = shift;
+	my $nodeset = shift;
+	
+#	warn "Eval ROOT\n";
+	
+	# must only ever occur on 1 node
+	die "Can't go to root on > 1 node!" unless $nodeset->size == 1;
+	
+	my $newset = XML::XPath::NodeSet->new();
+	$newset->push($nodeset->get_node(1)->getRootNode());
+	return $newset;
+}
+
+1;
Index: /gsdl/stable/perllib/cpan/XML/XPath/Step.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Step.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Step.pm	(revision 20131)
@@ -0,0 +1,519 @@
+# $Id$
+
+package XML::XPath::Step;
+use XML::XPath::Parser;
+use XML::XPath::Node;
+use strict;
+
+# the beginnings of using XS for this file...
+# require DynaLoader;
+# use vars qw/$VERSION @ISA/;
+# $VERSION = '1.0';
+# @ISA = qw(DynaLoader);
+# 
+# bootstrap XML::XPath::Step $VERSION;
+
+sub test_qname () { 0; } # Full name
+sub test_ncwild () { 1; } # NCName:*
+sub test_any () { 2; } # *
+
+sub test_attr_qname () { 3; } # @ns:attrib
+sub test_attr_ncwild () { 4; } # @nc:*
+sub test_attr_any () { 5; } # @*
+
+sub test_nt_comment () { 6; } # comment()
+sub test_nt_text () { 7; } # text()
+sub test_nt_pi () { 8; } # processing-instruction()
+sub test_nt_node () { 9; } # node()
+
+sub new {
+    my $class = shift;
+    my ($pp, $axis, $test, $literal) = @_;
+    my $axis_method = "axis_$axis";
+    $axis_method =~ tr/-/_/;
+    my $self = {
+        pp => $pp, # the XML::XPath::Parser class
+        axis => $axis,
+        axis_method => $axis_method,
+        test => $test,
+        literal => $literal,
+        predicates => [],
+        };
+    bless $self, $class;
+}
+
+sub as_string {
+    my $self = shift;
+    my $string = $self->{axis} . "::";
+
+    my $test = $self->{test};
+        
+    if ($test == test_nt_pi) {
+        $string .= 'processing-instruction(';
+        if ($self->{literal}->value) {
+            $string .= $self->{literal}->as_string;
+        }
+        $string .= ")";
+    }
+    elsif ($test == test_nt_comment) {
+        $string .= 'comment()';
+    }
+    elsif ($test == test_nt_text) {
+        $string .= 'text()';
+    }
+    elsif ($test == test_nt_node) {
+        $string .= 'node()';
+    }
+    elsif ($test == test_ncwild || $test == test_attr_ncwild) {
+        $string .= $self->{literal} . ':*';
+    }
+    else {
+        $string .= $self->{literal};
+    }
+    
+    foreach (@{$self->{predicates}}) {
+        next unless defined $_;
+        $string .= "[" . $_->as_string . "]";
+    }
+    return $string;
+}
+
+sub as_xml {
+    my $self = shift;
+    my $string = "<Step>\n";
+    $string .= "<Axis>" . $self->{axis} . "</Axis>\n";
+    my $test = $self->{test};
+    
+    $string .= "<Test>";
+    
+    if ($test == test_nt_pi) {
+        $string .= '<processing-instruction';
+        if ($self->{literal}->value) {
+            $string .= '>';
+            $string .= $self->{literal}->as_string;
+            $string .= '</processing-instruction>';
+        }
+        else {
+            $string .= '/>';
+        }
+    }
+    elsif ($test == test_nt_comment) {
+        $string .= '<comment/>';
+    }
+    elsif ($test == test_nt_text) {
+        $string .= '<text/>';
+    }
+    elsif ($test == test_nt_node) {
+        $string .= '<node/>';
+    }
+    elsif ($test == test_ncwild || $test == test_attr_ncwild) {
+        $string .= '<namespace-prefix>' . $self->{literal} . '</namespace-prefix>';
+    }
+    else {
+        $string .= '<nametest>' . $self->{literal} . '</nametest>';
+    }
+    
+    $string .= "</Test>\n";
+    
+    foreach (@{$self->{predicates}}) {
+        next unless defined $_;
+        $string .= "<Predicate>\n" . $_->as_xml() . "</Predicate>\n";
+    }
+    
+    $string .= "</Step>\n";
+    
+    return $string;
+}
+
+sub evaluate {
+    my $self = shift;
+    my $from = shift; # context nodeset
+    
+#    warn "Step::evaluate called with ", $from->size, " length nodeset\n";
+    
+    $self->{pp}->set_context_set($from);
+    
+    my $initial_nodeset = XML::XPath::NodeSet->new();
+    
+    # See spec section 2.1, paragraphs 3,4,5:
+    # The node-set selected by the location step is the node-set
+    # that results from generating an initial node set from the
+    # axis and node-test, and then filtering that node-set by
+    # each of the predicates in turn.
+    
+    # Make each node in the nodeset be the context node, one by one
+    for(my $i = 1; $i <= $from->size; $i++) {
+        $self->{pp}->set_context_pos($i);
+        $initial_nodeset->append($self->evaluate_node($from->get_node($i)));
+    }
+    
+#    warn "Step::evaluate initial nodeset size: ", $initial_nodeset->size, "\n";
+    
+    $self->{pp}->set_context_set(undef);
+
+    $initial_nodeset->sort;
+        
+    return $initial_nodeset;
+}
+
+# Evaluate the step against a particular node
+sub evaluate_node {
+    my $self = shift;
+    my $context = shift;
+    
+#    warn "Evaluate node: $self->{axis}\n";
+    
+#    warn "Node: ", $context->[node_name], "\n";
+    
+    my $method = $self->{axis_method};
+    
+    my $results = XML::XPath::NodeSet->new();
+    no strict 'refs';
+    eval {
+        $method->($self, $context, $results);
+    };
+    if ($@) {
+        die "axis $method not implemented [$@]\n";
+    }
+    
+#    warn("results: ", join('><', map {$_->string_value} @$results), "\n");
+    # filter initial nodeset by each predicate
+    foreach my $predicate (@{$self->{predicates}}) {
+        $results = $self->filter_by_predicate($results, $predicate);
+    }
+    
+    return $results;
+}
+
+sub axis_ancestor {
+    my $self = shift;
+    my ($context, $results) = @_;
+    
+    my $parent = $context->getParentNode;
+        
+    START:
+    return $results unless $parent;
+    if (node_test($self, $parent)) {
+        $results->push($parent);
+    }
+    $parent = $parent->getParentNode;
+    goto START;
+}
+
+sub axis_ancestor_or_self {
+    my $self = shift;
+    my ($context, $results) = @_;
+    
+    START:
+    return $results unless $context;
+    if (node_test($self, $context)) {
+        $results->push($context);
+    }
+    $context = $context->getParentNode;
+    goto START;
+}
+
+sub axis_attribute {
+    my $self = shift;
+    my ($context, $results) = @_;
+    
+    foreach my $attrib (@{$context->getAttributes}) {
+        if ($self->test_attribute($attrib)) {
+            $results->push($attrib);
+        }
+    }
+}
+
+sub axis_child {
+    my $self = shift;
+    my ($context, $results) = @_;
+    
+    foreach my $node (@{$context->getChildNodes}) {
+        if (node_test($self, $node)) {
+            $results->push($node);
+        }
+    }
+}
+
+sub axis_descendant {
+    my $self = shift;
+    my ($context, $results) = @_;
+
+    my @stack = $context->getChildNodes;
+
+    while (@stack) {
+        my $node = pop @stack;
+        if (node_test($self, $node)) {
+            $results->unshift($node);
+        }
+        push @stack, $node->getChildNodes;
+    }
+}
+
+sub axis_descendant_or_self {
+    my $self = shift;
+    my ($context, $results) = @_;
+    
+    my @stack = ($context);
+    
+    while (@stack) {
+        my $node = pop @stack;
+        if (node_test($self, $node)) {
+            $results->unshift($node);
+        }
+        push @stack, $node->getChildNodes;
+    }
+}
+
+sub axis_following {
+    my $self = shift;
+    my ($context, $results) = @_;
+    
+    START:
+
+    my $parent = $context->getParentNode;
+    return $results unless $parent;
+        
+    while ($context = $context->getNextSibling) {
+        axis_descendant_or_self($self, $context, $results);
+    }
+
+    $context = $parent;
+    goto START;
+}
+
+sub axis_following_sibling {
+    my $self = shift;
+    my ($context, $results) = @_;
+
+    while ($context = $context->getNextSibling) {
+        if (node_test($self, $context)) {
+            $results->push($context);
+        }
+    }
+}
+
+sub axis_namespace {
+    my $self = shift;
+    my ($context, $results) = @_;
+    
+    return $results unless $context->isElementNode;
+    foreach my $ns (@{$context->getNamespaces}) {
+        if ($self->test_namespace($ns)) {
+            $results->push($ns);
+        }
+    }
+}
+
+sub axis_parent {
+    my $self = shift;
+    my ($context, $results) = @_;
+    
+    my $parent = $context->getParentNode;
+    return $results unless $parent;
+    if (node_test($self, $parent)) {
+        $results->push($parent);
+    }
+}
+
+sub axis_preceding {
+    my $self = shift;
+    my ($context, $results) = @_;
+    
+    # all preceding nodes in document order, except ancestors
+    
+    START:
+
+    my $parent = $context->getParentNode;
+    return $results unless $parent;
+
+    while ($context = $context->getPreviousSibling) {
+        axis_descendant_or_self($self, $context, $results);
+    }
+    
+    $context = $parent;
+    goto START;
+}
+
+sub axis_preceding_sibling {
+    my $self = shift;
+    my ($context, $results) = @_;
+    
+    while ($context = $context->getPreviousSibling) {
+        if (node_test($self, $context)) {
+            $results->push($context);
+        }
+    }
+}
+
+sub axis_self {
+    my $self = shift;
+    my ($context, $results) = @_;
+    
+    if (node_test($self, $context)) {
+        $results->push($context);
+    }
+}
+    
+sub node_test {
+    my $self = shift;
+    my $node = shift;
+    
+    # if node passes test, return true
+    
+    my $test = $self->{test};
+
+    return 1 if $test == test_nt_node;
+        
+    if ($test == test_any) {
+        return 1 if $node->isElementNode && defined $node->getName;
+    }
+        
+    local $^W;
+
+    if ($test == test_ncwild) {
+        return unless $node->isElementNode;
+        my $match_ns = $self->{pp}->get_namespace($self->{literal}, $node);
+        if (my $node_nsnode = $node->getNamespace()) {
+            return 1 if $match_ns eq $node_nsnode->getValue;
+        }
+    }
+    elsif ($test == test_qname) {
+        return unless $node->isElementNode;
+        if ($self->{literal} =~ /:/) {
+            my ($prefix, $name) = split(':', $self->{literal}, 2);
+            my $match_ns = $self->{pp}->get_namespace($prefix, $node);
+            if (my $node_nsnode = $node->getNamespace()) {
+#                warn "match: '$self->{literal}' match NS: '$match_ns' got NS: '", $node_nsnode->getValue, "'\n";
+                return 1 if ($match_ns eq $node_nsnode->getValue) &&
+                        ($name eq $node->getLocalName);
+            }
+        }
+        else {
+#            warn "Node test: ", $node->getName, "\n";
+            return 1 if $node->getName eq $self->{literal};
+        }
+    }
+    elsif ($test == test_nt_text) {
+        return 1 if $node->isTextNode;
+    }
+    elsif ($test == test_nt_comment) {
+        return 1 if $node->isCommentNode;
+    }
+#     elsif ($test == test_nt_pi && !$self->{literal}) {
+#         warn "Unreachable code???";
+#         return 1 if $node->isPINode;
+#     }
+    elsif ($test == test_nt_pi) {
+        return unless $node->isPINode;
+        if (my $val = $self->{literal}->value) {
+            return 1 if $node->getTarget eq $val;
+        }
+        else {
+            return 1;
+        }
+    }
+    
+    return; # fallthrough returns false
+}
+
+sub test_attribute {
+    my $self = shift;
+    my $node = shift;
+    
+#    warn "test_attrib: '$self->{test}' against: ", $node->getName, "\n";
+#    warn "node type: $node->[node_type]\n";
+    
+    my $test = $self->{test};
+    
+    return 1 if ($test == test_attr_any) || ($test == test_nt_node);
+        
+    if ($test == test_attr_ncwild) {
+        my $match_ns = $self->{pp}->get_namespace($self->{literal}, $node);
+        if (my $node_nsnode = $node->getNamespace()) {
+            return 1 if $match_ns eq $node_nsnode->getValue;
+        }
+    }
+    elsif ($test == test_attr_qname) {
+        if ($self->{literal} =~ /:/) {
+            my ($prefix, $name) = split(':', $self->{literal}, 2);
+            my $match_ns = $self->{pp}->get_namespace($prefix, $node);
+            if (my $node_nsnode = $node->getNamespace()) {
+                return 1 if ($match_ns eq $node_nsnode->getValue) &&
+                        ($name eq $node->getLocalName);
+            }
+        }
+        else {
+            return 1 if $node->getName eq $self->{literal};
+        }
+    }
+    
+    return; # fallthrough returns false
+}
+
+sub test_namespace {
+    my $self = shift;
+    my $node = shift;
+    
+    # Not sure if this is correct. The spec seems very unclear on what
+    # constitutes a namespace test... bah!
+    
+    my $test = $self->{test};
+    
+    return 1 if $test == test_any; # True for all nodes of principal type
+    
+    if ($test == test_any) {
+        return 1;
+    }
+    elsif ($self->{literal} eq $node->getExpanded) {
+        return 1;
+    }
+    
+    return;
+}
+
+sub filter_by_predicate {
+    my $self = shift;
+    my ($nodeset, $predicate) = @_;
+    
+    # See spec section 2.4, paragraphs 2 & 3:
+    # For each node in the node-set to be filtered, the predicate Expr
+    # is evaluated with that node as the context node, with the number
+    # of nodes in the node set as the context size, and with the
+    # proximity position of the node in the node set with respect to
+    # the axis as the context position.
+    
+    if (!ref($nodeset)) { # use ref because nodeset has a bool context
+        die "No nodeset!!!";
+    }
+    
+#    warn "Filter by predicate: $predicate\n";
+    
+    my $newset = XML::XPath::NodeSet->new();
+    
+    for(my $i = 1; $i <= $nodeset->size; $i++) {
+        # set context set each time 'cos a loc-path in the expr could change it
+        $self->{pp}->set_context_set($nodeset);
+        $self->{pp}->set_context_pos($i);
+        my $result = $predicate->evaluate($nodeset->get_node($i));
+        if ($result->isa('XML::XPath::Boolean')) {
+            if ($result->value) {
+                $newset->push($nodeset->get_node($i));
+            }
+        }
+        elsif ($result->isa('XML::XPath::Number')) {
+            if ($result->value == $i) {
+                $newset->push($nodeset->get_node($i));
+            }
+        }
+        else {
+            if ($result->to_boolean->value) {
+                $newset->push($nodeset->get_node($i));
+            }
+        }
+    }
+    
+    return $newset;
+}
+
+1;
Index: /gsdl/stable/perllib/cpan/XML/XPath/Twig.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Twig.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Twig.pm	(revision 20131)
@@ -0,0 +1,10940 @@
+# $Id$
+#
+# Copyright (c) 1999-2004 Michel Rodriguez
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the same terms as Perl itself.
+#
+
+# This is created in the caller's space
+BEGIN
+{ sub ::PCDATA { '#PCDATA' } 
+  sub ::CDATA  { '#CDATA'  } 
+}
+
+
+######################################################################
+package XML::Twig;
+######################################################################
+
+require 5.004;
+use strict; 
+use UNIVERSAL qw( isa ) ;
+
+use vars qw($VERSION @ISA %valid_option);
+use Carp;
+
+#start-extract twig_global
+
+# constants: element types
+use constant (PCDATA  => '#PCDATA');
+use constant (CDATA   => '#CDATA');
+use constant (PI      => '#PI');
+use constant (COMMENT => '#COMMENT');
+use constant (ENT     => '#ENT');
+
+# element classes
+use constant (ELT     => '#ELT');
+use constant (TEXT    => '#TEXT');
+
+# element properties
+use constant (ASIS    => '#ASIS');
+use constant (EMPTY   => '#EMPTY');
+
+#end-extract twig_global
+
+# used in parseurl to set the buffer size to the same size as in XML::Parser::Expat
+use constant (BUFSIZE => 32768);
+
+
+# used to store the gi's
+my %gi2index;   # gi => index
+my @index2gi;   # list of gi's
+my $SPECIAL_GI; # first non-special gi;
+my %base_ent;   # base entity character => replacement
+
+# flag, set to true if the weaken sub is available
+use vars qw( $weakrefs);
+
+#start-extract twig_global
+my $REG_NAME       = q{(?:(?:[^\W\d]|[:#])(?:[\w.-]*:)?[\w.-]*)};     # xml name
+my $REG_NAME_W     = q{(?:(?:[^\W\d_]|[:#])(?:[\w.-]*:)?[\w.-]*|\*)}; # name or wildcard (* or '')
+my $REG_REGEXP     = q{(?:/(?:[^\\/]|\\.)*/[eimsox]*)};   # regexp
+my $REG_REGEXP_EXP = q{(?:(?:[^\\/]|\\.)*)};              # content of a regexp
+my $REG_REGEXP_MOD = q{(?:[eimso]*)};                     # regexp modifiers
+my $REG_MATCH      = q{[!=]~};                            # match (or not)
+my $REG_STRING     = q{(?:"(?:[^\\"]|\\.)*"|'(?:[^\\']|\\.)*')};  # string (simple or double quoted)
+my $REG_NUMBER     = q{(?:\d+(?:\.\d*)?|\.\d+)};          # number
+my $REG_VALUE      = qq{(?:$REG_STRING|$REG_NUMBER)};     # value
+my $REG_OP         = q{=|==|!=|>|<|>=|<=|eq|ne|lt|gt|le|ge}; # op
+
+#end-extract twig_global
+
+my $parser_version;
+my( $FB_HTMLCREF, $FB_XMLCREF);
+
+
+BEGIN
+{ 
+$VERSION = '3.15';
+
+use XML::Parser;
+my $needVersion = '2.23';
+$parser_version= $XML::Parser::VERSION;
+croak "need at least XML::Parser version $needVersion" unless $parser_version >= $needVersion;
+
+if( $] >= 5.008) 
+  { eval "use Encode qw( :fallback_all)";
+    $FB_XMLCREF  = 0x0400; # Encode::FB_XMLCREF;
+    $FB_HTMLCREF = 0x0200; #Encode::FB_HTMLCREF;
+  }
+
+# test whether we can use weak references
+# set local empty signal handler to trap error messages
+{ local $SIG{__DIE__};
+  if( eval 'require Scalar::Util') { import Scalar::Util qw(weaken); $weakrefs= 1; }
+  elsif( eval 'require WeakRef')   { import WeakRef; $weakrefs= 1;                 }
+  else                             { $weakrefs= 0;                                 } 
+}
+
+import XML::Twig::Elt;
+import XML::Twig::Entity;
+import XML::Twig::Entity_list;
+
+# used to store the gi's
+# should be set for each twig really, at least when there are several
+# the init ensures that special gi's are always the same
+
+# gi => index
+# do NOT use => or the constants become quoted!
+%XML::Twig::gi2index=( PCDATA, 0, CDATA, 1, PI, 2, COMMENT, 3, ENT, 4); 
+# list of gi's
+@XML::Twig::index2gi=( PCDATA, CDATA, PI, COMMENT, ENT);
+
+# gi's under this value are special 
+$XML::Twig::SPECIAL_GI= @XML::Twig::index2gi;
+
+%XML::Twig::base_ent= ( '>' => '&gt;', '<' => '&lt;', '&' => '&amp;', "'" => '&apos;', '"' => '&quot;',);
+
+# now set some aliases
+*find_nodes           = *get_xpath;               # same as XML::XPath
+*findnodes            = *get_xpath;               # same as XML::LibXML
+*getElementsByTagName = *descendants;
+*descendants_or_self  = *descendants;             # valid in XML::Twig, not in XML::Twig::Elt
+*find_by_tag_name     = *descendants;
+*getElementById       = *elt_id;
+*getEltById           = *elt_id;
+*toString             = *sprint;
+}
+
+@ISA = qw(XML::Parser);
+
+# fake gi's used in twig_handlers and start_tag_handlers
+my $ALL    = '_all_';     # the associated function is always called
+my $DEFAULT= '_default_'; # the function is called if no other handler has been
+
+# some defaults
+my $COMMENTS_DEFAULT= 'keep';
+my $PI_DEFAULT      = 'keep';
+
+
+# handlers used in regular mode
+my %twig_handlers=( Start      => \&_twig_start, 
+                    End        => \&_twig_end, 
+                    Char       => \&_twig_char, 
+                    Entity     => \&_twig_entity, 
+                    XMLDecl    => \&_twig_xmldecl, 
+                    Doctype    => \&_twig_doctype, 
+                    Element    => \&_twig_element, 
+                    Attlist    => \&_twig_attlist, 
+                    CdataStart => \&_twig_cdatastart, 
+                    CdataEnd   => \&_twig_cdataend, 
+                    Proc       => \&_twig_pi,
+                    Comment    => \&_twig_comment,
+                    Default    => \&_twig_default,
+      );
+
+# handlers used when twig_roots is used and we are outside of the roots
+my %twig_handlers_roots=
+  ( Start      => \&_twig_start_check_roots, 
+    End        => \&_twig_end_check_roots, 
+    Doctype    => \&_twig_doctype, 
+    Char       => undef, Entity     => undef, XMLDecl    => \&_twig_xmldecl, 
+    Element    => undef, Attlist    => undef, CdataStart => undef, 
+    CdataEnd   => undef, Proc       => undef, Comment    => undef, 
+    Proc       => \&_twig_pi_check_roots,
+    Default    =>  sub {}, # hack needed for XML::Parser 2.27
+  );
+
+# handlers used when twig_roots and print_outside_roots are used and we are
+# outside of the roots
+my %twig_handlers_roots_print_2_30=
+  ( Start      => \&_twig_start_check_roots_print, 
+    End        => \&_twig_end_check_roots_print, 
+    Char       => \&_twig_print, 
+    # I have no idea why I should not be using this handler!
+    Entity     => \&_twig_print_entity, 
+    XMLDecl    => \&_twig_print,
+    Doctype   =>  \&_twig_print_doctype, # because recognized_string is broken here
+    # Element    => \&_twig_print, Attlist    => \&_twig_print, 
+    CdataStart => \&_twig_print, CdataEnd   => \&_twig_print, 
+    Proc       => \&_twig_print, Comment    => \&_twig_print, 
+    Default    => \&_twig_print_check_doctype,
+  );
+
+# handlers used when twig_roots, print_outside_roots and keep_encoding are used
+# and we are outside of the roots
+my %twig_handlers_roots_print_original_2_30=
+  ( Start      => \&_twig_start_check_roots_print_original, 
+    End        => \&_twig_end_check_roots_print_original, 
+    Char       => \&_twig_print_original, 
+    # I have no idea why I should not be using this handler!
+    #Entity     => \&_twig_print_original, 
+    ExternEnt  => \&_twig_print_entity,
+    XMLDecl    => \&_twig_print_original, 
+    Doctype    => \&_twig_print_original_doctype,  # because original_string is broken here
+    Element    => \&_twig_print_original, Attlist   => \&_twig_print_original,
+    CdataStart => \&_twig_print_original, CdataEnd  => \&_twig_print_original,
+    Proc       => \&_twig_print_original, Comment   => \&_twig_print_original,
+    Default    => \&_twig_print_original_check_doctype, 
+  );
+
+# handlers used when twig_roots and print_outside_roots are used and we are
+# outside of the roots
+my %twig_handlers_roots_print_2_27=
+  ( Start      => \&_twig_start_check_roots_print, 
+    End        => \&_twig_end_check_roots_print, 
+    Char       => \&_twig_print, 
+    # I have no idea why I should not be using this handler!
+    #Entity     => \&_twig_print, 
+    XMLDecl    => \&_twig_print, Doctype    => \&_twig_print, 
+    CdataStart => \&_twig_print, CdataEnd   => \&_twig_print, 
+    Proc       => \&_twig_print, Comment    => \&_twig_print, 
+    Default    => \&_twig_print, 
+  );
+
+# handlers used when twig_roots, print_outside_roots and keep_encoding are used
+# and we are outside of the roots
+my %twig_handlers_roots_print_original_2_27=
+  ( Start      => \&_twig_start_check_roots_print_original, 
+    End        => \&_twig_end_check_roots_print_original, 
+    Char       => \&_twig_print_original, 
+    # for some reason original_string is wrong here 
+    # this can be a problem if the doctype includes non ascii characters
+    XMLDecl    => \&_twig_print, Doctype    => \&_twig_print,
+    # I have no idea why I should not be using this handler!
+    Entity     => \&_twig_print, 
+    #Element    => undef, Attlist   => undef,
+    CdataStart => \&_twig_print_original, CdataEnd  => \&_twig_print_original,
+    Proc       => \&_twig_print_original, Comment   => \&_twig_print_original,
+    Default    => \&_twig_print_default, #  _twig_print_original does not work
+  );
+
+
+my %twig_handlers_roots_print= $parser_version > 2.27 
+                               ? %twig_handlers_roots_print_2_30 
+                               : %twig_handlers_roots_print_2_27; 
+my %twig_handlers_roots_print_original= $parser_version > 2.27 
+                               ? %twig_handlers_roots_print_original_2_30 
+                               : %twig_handlers_roots_print_original_2_27; 
+
+
+# handlers used when the finish_print method has been called
+my %twig_handlers_finish_print=
+  ( Start      => \&_twig_print, 
+    End        => \&_twig_print_end, Char       => \&_twig_print, 
+    Entity     => \&_twig_print, XMLDecl    => \&_twig_print, 
+    Doctype    => \&_twig_print, Element    => \&_twig_print, 
+    Attlist    => \&_twig_print, CdataStart => \&_twig_print, 
+    CdataEnd   => \&_twig_print, Proc       => \&_twig_print, 
+    Comment    => \&_twig_print, Default    => \&_twig_print, 
+  );
+
+# handlers used when the finish_print method has been called and the keep_encoding
+# option is used
+my %twig_handlers_finish_print_original=
+  ( Start      => \&_twig_print_original, End      => \&_twig_print_end_original, 
+    Char       => \&_twig_print_original, Entity   => \&_twig_print_original, 
+    XMLDecl    => \&_twig_print_original, Doctype  => \&_twig_print_original, 
+    Element    => \&_twig_print_original, Attlist  => \&_twig_print_original, 
+    CdataStart => \&_twig_print_original, CdataEnd => \&_twig_print_original, 
+    Proc       => \&_twig_print_original, Comment  => \&_twig_print_original, 
+    Default    => \&_twig_print_original, 
+  );
+
+# handlers used whithin ignored elements
+my %twig_handlers_ignore=
+  ( Start      => \&_twig_ignore_start, 
+    End        => \&_twig_ignore_end, 
+    Char       => undef, Entity     => undef, XMLDecl    => undef, 
+    Doctype    => undef, Element    => undef, Attlist    => undef, 
+    CdataStart => undef, CdataEnd   => undef, Proc       => undef, 
+    Comment    => undef, Default    => undef,
+  );
+
+
+# those handlers are only used if the entities are NOT to be expanded
+my %twig_noexpand_handlers= ( Default => \&_twig_default );
+
+my @saved_default_handler;
+
+my $ID= 'id'; # default value, set by the Id argument
+
+# all allowed options
+%valid_option=
+    ( # XML::Twig options
+      TwigHandlers          => 1, Id                    => 1,
+      TwigRoots             => 1, TwigPrintOutsideRoots => 1,
+      StartTagHandlers      => 1, EndTagHandlers        => 1,
+      ForceEndTagHandlersUsage => 1,
+      DoNotChainHandlers    => 1,
+      IgnoreElts            => 1,
+      CharHandler           => 1, KeepEncoding          => 1,
+      ParseStartTag         => 1, KeepAttsOrder         => 1,
+      LoadDTD               => 1, DTDHandler            => 1,
+      DoNotOutputDTD        => 1, NoProlog              => 1,
+      ExpandExternalEnts    => 1,
+      DiscardSpaces         => 1, KeepSpaces            => 1, 
+      DiscardSpacesIn       => 1, KeepSpacesIn          => 1, 
+      PrettyPrint           => 1, EmptyTags             => 1, 
+      Comments              => 1, Pi                    => 1, 
+      OutputFilter          => 1, InputFilter           => 1,
+      OutputTextFilter      => 1, 
+      OutputEncoding        => 1, 
+      EltClass              => 1,
+      MapXmlns              => 1, KeepOriginalPrefix    => 1,
+      # XML::Parser options
+      ErrorContext          => 1, ProtocolEncoding      => 1,
+      Namespaces            => 1, NoExpand              => 1,
+      Stream_Delimiter      => 1, ParseParamEnt         => 1,
+      NoLWP                 => 1, Non_Expat_Options     => 1,
+      Xmlns                 => 1,
+    );
+
+# predefined input and output filters
+use vars qw( %filter);
+%filter= ( html       => \&html_encode,
+           safe       => \&safe_encode,
+           safe_hex   => \&safe_encode_hex,
+         );
+
+sub new
+  { my ($class, %args) = @_;
+    my $handlers;
+
+    # change all nice_perlish_names into nicePerlishNames
+    %args= _normalize_args( %args);
+
+    # check options
+    unless( $args{MoreOptions})
+      { foreach my $arg (keys %args)
+        { carp "invalid option $arg" unless $valid_option{$arg}; }
+      }
+     
+    # a twig is really an XML::Parser
+    # my $self= XML::Parser->new(%args);
+    my $self;
+    $self= XML::Parser->new(%args);   
+    
+    bless $self, $class;
+
+    if( exists $args{TwigHandlers})
+      { $handlers= $args{TwigHandlers};
+        $self->setTwigHandlers( $handlers);
+        delete $args{TwigHandlers};
+      }
+
+    # take care of twig-specific arguments
+    if( exists $args{StartTagHandlers})
+      { $self->setStartTagHandlers( $args{StartTagHandlers});
+        delete $args{StartTagHandlers};
+      }
+
+    if( exists $args{DoNotChainHandlers})
+      { $self->{twig_do_not_chain_handlers}=  $args{DoNotChainHandlers}; }
+
+    if(  exists $args{IgnoreElts})
+      { $self->setIgnoreEltsHandlers( $args{IgnoreElts});
+        delete $args{IgnoreElts};
+      }
+
+    $self->{twig_elt_class}= $args{EltClass} || 'XML::Twig::Elt';
+    if( exists( $args{EltClass})) { delete $args{EltClass}; }
+
+    if( exists( $args{MapXmlns}))
+      { $self->{twig_map_xmlns}=  $args{MapXmlns};
+        $self->{Namespaces}=1;
+        delete $args{MapXmlns};
+      }
+
+    if( exists( $args{KeepOriginalPrefix}))
+      { $self->{twig_keep_original_prefix}= $args{KeepOriginalPrefix};
+        delete $args{KeepOriginalPrefix};
+      }
+
+    $self->{twig_dtd_handler}= $args{DTDHandler};
+    delete $args{DTDHandler};
+
+    if( $args{CharHandler})
+      { $self->setCharHandler( $args{CharHandler});
+        delete $args{CharHandler};
+      }
+
+    if( $args{LoadDTD})
+      { $self->{twig_read_external_dtd}= 1;
+        delete $args{LoadDTD};
+      }
+      
+    if( $args{ExpandExternalEnts})
+      { $self->set_expand_external_entities( 1);
+        $self->{twig_read_external_dtd}= 1; # implied by ExpandExternalEnts
+        delete $args{LoadDTD};
+        delete $args{ExpandExternalEnts};
+      }
+
+    # deal with TwigRoots argument, a hash of elements for which
+    # subtrees will be built (and associated handlers)
+     
+    if( $args{TwigRoots})
+      { $self->setTwigRoots( $args{TwigRoots});
+        delete $args{TwigRoots}; 
+      }
+    
+    if( $args{EndTagHandlers})
+      { unless ($self->{twig_roots} || $args{ForceEndTagHandlersUsage})
+          { croak "you should not use EndTagHandlers without TwigRoots\n",
+                  "if you want to use it anyway, normally because you have ",
+                  "a start_tag_handlers that calls 'ignore' and you want to ",
+                  "call an ent_tag_handlers at the end of the element, then ",
+                  "pass 'force_end_tag_handlers_usage => 1' as an argument ",
+                  "to new";
+          }
+                  
+        $self->setEndTagHandlers( $args{EndTagHandlers});
+        delete $args{EndTagHandlers};
+      }
+      
+    if( $args{TwigPrintOutsideRoots})
+      { croak "cannot use TwigPrintOutsideRoots without TwigRoots"
+          unless( $self->{twig_roots});
+        # if the arg is a filehandle then store it
+        if( _is_fh( $args{TwigPrintOutsideRoots}) )
+          { $self->{twig_output_fh}= $args{TwigPrintOutsideRoots}; }
+        $self->{twig_default_print}= $args{TwigPrintOutsideRoots};
+      }
+
+    if( $args{PrettyPrint})
+      { $self->set_pretty_print( $args{PrettyPrint}); }
+
+    if( $args{EmptyTags})
+      { $self->set_empty_tag_style( $args{EmptyTags}); }
+
+    # space policy
+    if( $args{KeepSpaces})
+      { croak "cannot use both keep_spaces and discard_spaces" if( $args{DiscardSpaces});
+        croak "cannot use both keep_spaces and keep_spaces_in" if( $args{KeepSpacesIn});
+        $self->{twig_keep_spaces}=1;
+        delete $args{KeepSpaces}; 
+      }
+    if( $args{DiscardSpaces})
+      { croak "cannot use both discard_spaces and keep_spaces_in" if( $args{KeepSpacesIn});
+        $self->{twig_discard_spaces}=1; 
+        delete $args{DiscardSpaces}; 
+      }
+    if( $args{KeepSpacesIn})
+      { croak "cannot use both keep_spaces_in and discard_spaces_in" if( $args{DiscardSpacesIn});
+        $self->{twig_discard_spaces}=1; 
+        $self->{twig_keep_spaces_in}={}; 
+        my @tags= @{$args{KeepSpacesIn}}; 
+        foreach my $tag (@tags) { $self->{twig_keep_spaces_in}->{$tag}=1; } 
+        delete $args{KeepSpacesIn}; 
+      }
+    if( $args{DiscardSpacesIn})
+      { $self->{twig_keep_spaces}=1; 
+        $self->{twig_discard_spaces_in}={}; 
+        my @tags= @{$args{DiscardSpacesIn}};
+        foreach my $tag (@tags) { $self->{twig_discard_spaces_in}->{$tag}=1; } 
+        delete $args{DiscardSpacesIn}; 
+      }
+    # discard spaces by default 
+    $self->{twig_discard_spaces}= 1 unless(  $self->{twig_keep_spaces});
+
+    $args{Comments}||= $COMMENTS_DEFAULT;
+    if( $args{Comments} eq 'drop')       { $self->{twig_keep_comments}= 0;    }
+    elsif( $args{Comments} eq 'keep')    { $self->{twig_keep_comments}= 1;    }
+    elsif( $args{Comments} eq 'process') { $self->{twig_process_comments}= 1; }
+    else { croak "wrong value for comments argument: '$args{Comments}' (should be 'drop', 'keep' or 'process')"; }
+    delete $args{Comments};
+
+    $args{Pi}||= $PI_DEFAULT;
+    if( $args{Pi} eq 'drop')       { $self->{twig_keep_pi}= 0;    }
+    elsif( $args{Pi} eq 'keep')    { $self->{twig_keep_pi}= 1;    }
+    elsif( $args{Pi} eq 'process') { $self->{twig_process_pi}= 1; }
+    else { croak "wrong value for pi argument: '$args{Pi}' (should be 'drop', 'keep' or 'process')"; }
+    delete $args{Pi};
+
+    if( $args{KeepEncoding})
+      { $self->{twig_keep_encoding}= $args{KeepEncoding};
+        # set it in XML::Twig::Elt so print functions know what to do
+        $self->set_keep_encoding( 1); 
+        $self->{parse_start_tag}= $args{ParseStartTag} || \&_parse_start_tag; 
+        delete $args{ParseStartTag} if defined( $args{ParseStartTag}) ;
+        delete $args{KeepEncoding};
+        $self->{NoExpand}= 1;
+      }
+    else
+      { $self->set_keep_encoding( 0);  
+        $self->{parse_start_tag}= $args{ParseStartTag} if( $args{ParseStartTag}); 
+      }
+
+    if( $args{OutputFilter})
+      { $self->set_output_filter( $args{OutputFilter}); 
+        delete $args{OutputFilter};
+      }
+    else
+      { $self->set_output_filter( 0); }
+
+    if( $args{OutputTextFilter})
+      { $self->set_output_text_filter( $args{OutputTextFilter}); 
+        delete $args{OutputTextFilter};
+      }
+    else
+      { $self->set_output_text_filter( 0); }
+
+
+    if( exists $args{KeepAttsOrder})
+      { $self->{keep_atts_order}= $args{KeepAttsOrder};
+        if( eval 'require Tie::IxHash') 
+          { import Tie::IxHash; 
+            $self->set_keep_atts_order(  $self->{keep_atts_order}); 
+          }
+        else 
+          { carp "Tie::IxHash not available, option  keep_atts_order not allowed"; }
+      }
+    else
+      { $self->set_keep_atts_order( 0); }
+
+    if( my $output_encoding= $args{OutputEncoding})
+      { $self->set_output_encoding( $output_encoding);
+        delete $args{OutputFilter};
+      }
+
+    if( $args{InputFilter})
+      { $self->set_input_filter(  $args{InputFilter}); 
+        delete  $args{InputFilter}; 
+      }
+
+    if( exists $args{Id}) { $ID= $args{Id}; delete $args{ID}; }
+
+    if( $args{NoExpand})
+      { $self->setHandlers( %twig_noexpand_handlers);
+        $self->{twig_no_expand}=1;
+      }
+
+    if( $args{NoProlog})
+      { $self->{no_prolog}= 1; 
+        delete $args{NoProlog}; 
+      }
+
+    if( $args{DoNotOutputDTD})
+      { $self->{no_dtd_output}= 1; 
+        delete $args{DoNotOutputDTD}; 
+      }
+
+    # set handlers
+    if( $self->{twig_roots})
+      { if( $self->{twig_default_print})
+          { if( $self->{twig_keep_encoding})
+              { $self->setHandlers( %twig_handlers_roots_print_original); }
+            else
+              { $self->setHandlers( %twig_handlers_roots_print);  }
+          }
+        else
+          { $self->setHandlers( %twig_handlers_roots); }
+      }
+    else
+      { $self->setHandlers( %twig_handlers); }
+
+    # XML::Parser::Expat does not like these handler to be set. So in order to 
+    # use the various sets of handlers on XML::Parser or XML::Parser::Expat
+    # objects when needed, these ones have to be set only once, here, at 
+    # XML::Parser level
+    $self->setHandlers( Init => \&_twig_init, Final => \&_twig_final);
+
+    $self->{twig_entity_list}= XML::Twig::Entity_list->new; 
+
+    $self->{twig_id}= $ID; 
+    $self->{twig_stored_spaces}='';
+
+    $self->{twig}= $self;
+    weaken( $self->{twig}) if( $weakrefs);
+
+    return $self;
+  }
+
+
+sub parseurl
+  { my $t= shift;
+    return $t->_parseurl( 0, @_);
+  }
+
+sub safe_parseurl
+  { my $t= shift;
+    return $t->_parseurl( 1, @_);
+  }
+
+# I should really add extra options to allow better configuration of the 
+# LWP::UserAgent object
+# this method forks: 
+#   - the child gets the data and copies it to the pipe,
+#   - the parent reads the stream and sends it to XML::Parser
+# the data is cut it chunks the size of the XML::Parser::Expat buffer
+# the method returns the twig and the status
+sub _parseurl
+  { my( $t, $safe, $url, $agent)= @_;
+    pipe( README, WRITEME) or croak  "cannot create connected pipes: $!";
+    if( my $pid= fork)
+      { # parent code: parse the incoming file
+        close WRITEME; # no need to write
+        my $result= $safe ? $t->safe_parse( \*README) : $t->parse( \*README);
+        close README;
+        return $@ ? 0 : $t;
+      }
+    else
+     { # child
+        close README; # no need to read
+        require LWP;  # so we can get LWP::UserAgent and HTTP::Request
+        $|=1;
+        $agent    ||= LWP::UserAgent->new;
+        my $request  = HTTP::Request->new( GET => $url);
+        # _pass_url_content is called with chunks of data the same size as
+        # the XML::Parser buffer 
+        my $response = $agent->request( $request, 
+                         sub { _pass_url_content( \*WRITEME, @_); }, BUFSIZE);
+        $response->is_success or croak "$url ", $response->message;
+        close WRITEME;
+        CORE::exit(); # CORE is there for mod_perl (which redefines exit)
+      }
+  }
+
+# get the (hopefully!) XML data from the URL and 
+sub _pass_url_content
+  { my( $fh, $data, $response, $protocol)= @_;
+    print $fh $data;
+  }
+
+sub add_options
+  { my %args= map { $_, 1 } @_;
+    %args= _normalize_args( %args);
+    foreach (keys %args) { $valid_option{$_}++; } 
+  }
+
+sub _twig_store_internal_dtd
+  { 
+    my( $p, $string)= @_;
+    my $t= $p->{twig};
+    $string= $p->original_string() if( $t->{twig_keep_encoding});
+    $t->{twig_doctype}->{internal} .= $string;
+  }
+
+sub _twig_stop_storing_internal_dtd
+  { my $p= shift;
+    if( @saved_default_handler && defined $saved_default_handler[1])
+      { $p->setHandlers( @saved_default_handler); }
+    else
+      { my $t= $p->{twig};
+        $p->setHandlers( Default => undef);
+      }
+  }
+
+
+sub _normalize_args
+  { my %normalized_args;
+    while( my $key= shift )
+      { $key= join '', map { ucfirst } split /_/, $key;
+        #$key= "Twig".$key unless( substr( $key, 0, 4) eq 'Twig');
+        $normalized_args{$key}= shift ;
+      }
+    return %normalized_args;
+  }    
+
+sub _is_fh { return unless $_[0]; return isa( $_[0], 'GLOB') || isa( $_[0], 'IO::Scalar'); }
+
+sub _set_handler
+  { my( $handlers, $path, $handler)= @_;
+
+    $handlers ||= {}; # create the handlers struct if necessary
+
+    my $prev_handler= $handlers->{handlers}->{$path} || undef;
+
+       _set_gi_handler              ( $handlers, $path, $handler, $prev_handler)
+    || _set_path_handler            ( $handlers, $path, $handler, $prev_handler)
+    || _set_subpath_handler         ( $handlers, $path, $handler, $prev_handler)
+    || _set_attribute_handler       ( $handlers, $path, $handler, $prev_handler)
+    || _set_star_att_handler        ( $handlers, $path, $handler, $prev_handler)
+    || _set_star_att_regexp_handler ( $handlers, $path, $handler, $prev_handler)
+    || _set_string_handler          ( $handlers, $path, $handler, $prev_handler)
+    || _set_attribute_regexp_handler( $handlers, $path, $handler, $prev_handler)
+    || _set_string_regexp_handler   ( $handlers, $path, $handler, $prev_handler)
+    || _set_pi_handler              ( $handlers, $path, $handler, $prev_handler)
+    || croak "unrecognized expression in handler: '$path'";
+
+
+    # this both takes care of the simple (gi) handlers and store
+    # the handler code reference for other handlers
+    $handlers->{handlers}->{$path}= $handler;
+
+    return $prev_handler;
+  }
+
+
+sub _set_gi_handler
+  { my( $handlers, $path, $handler, $prev_handler)= @_;
+    if( $path =~ m{^\s*($REG_NAME)\s*$}o )
+      { my $gi= $1;
+        $handlers->{handlers}->{gi}->{$gi}= $handler; 
+        return 1;
+      }
+    else 
+      { return 0; }
+  }
+
+sub _set_path_handler
+  { my( $handlers, $path, $handler, $prev_handler)= @_;
+    if( $path=~ m{^\s*(?:/$REG_NAME)*/($REG_NAME)\s*$}o)
+      { # a full path has been defined
+        # update the path_handlers count, knowing that
+        # either the previous or the new handler can be undef
+        $handlers->{path_handlers}->{gi}->{$1}-- if( $prev_handler);
+        if( $handler)
+         { $handlers->{path_handlers}->{gi}->{$1}++;
+           $handlers->{path_handlers}->{path}->{$path}= $handler;
+         }
+        return 1;
+      }
+    else 
+      { return 0; }
+  }
+
+sub _set_subpath_handler
+  { my( $handlers, $path, $handler, $prev_handler)= @_;
+    if( $path=~ m{^\s*(?:$REG_NAME/)+($REG_NAME)\s*$}o)
+      { # a partial path has been defined
+        # $1 is the "final" gi
+        $handlers->{subpath_handlers}->{gi}->{$1}-- if( $prev_handler);
+        if( $handler)
+         { $handlers->{subpath_handlers}->{gi}->{$1}++;
+           $handlers->{subpath_handlers}->{path}->{$path}= $handler;
+         }
+        return 1;
+      }
+    else 
+      { return 0; }
+  }
+
+sub _set_attribute_handler
+  { my( $handlers, $path, $handler, $prev_handler)= @_;
+    # check for attribute conditions
+    if( $path=~ m{^\s*($REG_NAME)          # elt
+                 \s*\[\s*\@                #    [@
+                 ($REG_NAME)\s*            #      att
+                 (?:=\s*($REG_STRING)\s*)? #           = value (optional)         
+                 \]\s*$}xo)                #                             ]  
+      { my( $gi, $att, $val)= ($1, $2, $3);
+        $val= substr( $val, 1, -1) if( defined $val); # remove the quotes
+        if( $prev_handler)
+          { # replace or remove the previous handler
+            my $i=0; # so we can splice the array if need be
+            foreach my $exp ( @{$handlers->{attcond_handlers_exp}->{$gi}})
+             { if( ($exp->{att} eq $att) && ( _eq( $exp->{val}, $val)) )
+                 { if( $handler) # just replace the handler
+                     { $exp->{handler}= $handler; }
+                   else          # remove the handler
+                     { $handlers->{attcond_handlers}->{$gi}--;
+                       splice( @{$handlers->{attcond_handlers_exp}->{$gi}}, $i, 1);
+                       last;
+                     }
+                 }
+               $i++;
+             }
+          }
+        elsif( $handler)
+          { # new handler only
+            $handlers->{attcond_handlers}->{$gi}++;
+            my $exp={att => $att, val => $val, handler => $handler};
+            $handlers->{attcond_handlers_exp}->{$gi} ||= [];
+            push @{$handlers->{attcond_handlers_exp}->{$gi}}, $exp;
+          }
+        return 1;
+      }
+    else 
+      { return 0; }
+  }
+
+
+sub _set_attribute_regexp_handler
+  { my( $handlers, $path, $handler, $prev_handler)= @_;
+    # check for attribute regexp conditions
+    if( $path=~ m{^\s*($REG_NAME)     # elt
+                 \s*\[\s*\@           #    [@
+                 ($REG_NAME)          #      att
+                 \s*=~\s*             #          =~
+                 /($REG_REGEXP_EXP)/  #             /regexp/
+                 ($REG_REGEXP_MOD)    #                     mods
+                 \s*]\s*$}gxo)        #                         ] 
+      { my( $gi, $att, $regexp, $mods)= ($1, $2, $3, $4);
+        $regexp= qr/(?$mods:$regexp)/;
+        if( $prev_handler)
+          { # replace or remove the previous handler
+            my $i=0; # so we can splice the array if need be
+            foreach my $exp ( @{$handlers->{attregexp_handlers_exp}->{$gi}})
+             { if( ($exp->{att} eq $att) && ($exp->{regexp} eq $regexp) )
+                 { if( $handler) # just replace the handler
+                     { $exp->{handler}= $handler; }
+                   else          # remove the handler
+                     { $handlers->{attregexp_handlers}->{$gi}--;
+                       splice( @{$handlers->{attregexp_handlers_exp}->{$gi}}, $i, 1);
+                       last;
+                     }
+                 }
+               $i++;
+             }
+          }
+        elsif( $handler)
+          { # new handler only
+            $handlers->{attregexp_handlers}->{$gi}++;
+            my $exp={att => $att, regexp => $regexp, handler => $handler};
+            $handlers->{attregexp_handlers_exp}->{$gi} ||= [];
+            push @{$handlers->{attregexp_handlers_exp}->{$gi}}, $exp;
+          }
+        return 1;
+      }
+    else 
+      { return 0; }
+  }
+
+sub _set_string_handler
+  { my( $handlers, $path, $handler, $prev_handler)= @_;
+    # check for string conditions
+    if( $path=~/^\s*($REG_NAME)            # elt
+                 \s*\[\s*string            #    [string
+                 \s*\(\s*($REG_NAME)?\s*\) #           (sub_elt)
+                 \s*=\s*                   #                     =
+                 ($REG_STRING)             #                       "text" (or 'text')
+                 \s*\]\s*$/ox)             #                              ] 
+      { my( $gi, $sub_elt, $text)= ($1, $2, $3);
+        $text= substr( $text, 1, -1) if( defined $text); # remove the quotes
+        if( $prev_handler)
+          { # replace or remove the previous handler
+            my $i=0; # so we can splice the array if need be
+            foreach my $exp ( @{$handlers->{text_handlers_exp}->{$gi}})
+             { if( ($exp->{text} eq $text) &&
+                   ( !$exp->{sub_elt} || ($exp->{sub_elt} eq $sub_elt) )
+                 )
+                 { if( $handler) # just replace the handler
+                     { $exp->{handler}= $handler; }
+                   else          # remove the handler
+                     { $handlers->{text_handlers}->{$gi}--;
+                       splice( @{$handlers->{text_handlers_exp}->{$gi}}, $i, 1);
+                       last;
+                     }
+                 }
+               $i++;
+             }
+          }
+        elsif( $handler)
+          { # new handler only
+            $handlers->{text_handlers}->{$gi}++;
+            my $exp={sub_elt => $sub_elt, text => $text, handler => $handler};
+            $handlers->{text_handlers_exp}->{$gi} ||= [];
+            push @{$handlers->{text_handlers_exp}->{$gi}}, $exp;
+          }
+        return 1;
+      }
+    else 
+      { return 0; 
+      }
+  }
+
+
+sub _set_string_regexp_handler
+  { my( $handlers, $path, $handler, $prev_handler)= @_;
+    # check for string regexp conditions
+    if( $path=~m{^\s*($REG_NAME)        # (elt)
+                 \s*\[\s*string         #    [string
+                 \s*\(\s*($REG_NAME?)\) #           (sub_elt)
+                 \s*=~\s*               #              =~ 
+                 /($REG_REGEXP_EXP)/    #                 /(regexp)/
+                 \s*($REG_REGEXP_MOD)?  #                         (mods)
+                 \s*\]\s*$}ox)          #                             ]   (or ')
+      { my( $gi, $sub_elt, $regexp, $mods)= ($1, $2, $3, $4);
+        $mods||="";
+        $regexp= qr/(?$mods:$regexp)/;
+        if( $prev_handler)
+          { # replace or remove the previous handler
+            my $i=0; # so we can splice the array if need be
+            foreach my $exp ( @{$handlers->{regexp_handlers_exp}->{$gi}})
+             { if( ($exp->{regexp} eq $regexp) &&
+                   ( !$exp->{sub_elt} || ($exp->{sub_elt} eq $sub_elt) )
+                 )
+                 { if( $handler) # just replace the handler
+                     { $exp->{handler}= $handler;  
+                     }
+                   else          # remove the handler
+                     { $handlers->{regexp_handlers}->{$gi}--;
+                       splice( @{$handlers->{regexp_handlers_exp}->{$gi}}, $i, 1);
+                       last;
+                     }
+                 }
+               $i++;
+             }
+          }
+        elsif( $handler)
+          { # new handler only
+            $handlers->{regexp_handlers}->{$gi}++;
+            my $exp= {sub_elt => $sub_elt, regexp => $regexp, handler => $handler};
+            $handlers->{regexp_handlers_exp}->{$gi} ||= [];
+            push @{$handlers->{regexp_handlers_exp}->{$gi}}, $exp;
+          }
+        return 1;
+      }
+    else 
+      { return 0; 
+      }
+  }
+
+
+sub _set_star_att_handler
+  { my( $handlers, $path, $handler, $prev_handler)= @_;
+    # check for *[@att="val"] or *[@att] conditions
+    if( $path=~/^(?:\s*\*)?         # * (optional)
+                 \s*\[\s*\@         #    [@
+                 ($REG_NAME)        #      att
+                 (?:\s*=\s*         #         = 
+                 ($REG_STRING))?    #           string
+                     \s*\]\s*$/ox)  #                 ]  
+      { my( $att, $val)= ($1, $2);
+        $val= substr( $val, 1, -1) if( defined $val); # remove the quotes from the string
+        if( $prev_handler)
+          { # replace or remove the previous handler
+            my $i=0; # so we can splice the array if need be
+            foreach my $exp ( @{$handlers->{att_handlers_exp}->{$att}})
+             { if( ($exp->{att} eq $att) && ( !defined( $val) || _eq( $exp->{val}, $val) ) )
+                 { if( $handler) # just replace the handler
+                     { $exp->{handler}= $handler; }
+                   else          # remove the handler
+                     { splice( @{$handlers->{att_handlers_exp}->{$att}}, $i, 1);
+                   $handlers->{att_handlers}->{$att}--;
+                       last;
+                     }
+                 }
+               $i++;
+             }
+          }
+        elsif( $handler)
+          { # new handler only
+            $handlers->{att_handlers}->{$att}++;
+            my $exp={att => $att, val => $val, handler => $handler};
+            $handlers->{att_handlers_exp}->{$att} ||= [];
+            push @{$handlers->{att_handlers_exp}->{$att}}, $exp;
+          }
+        return 1;
+      }
+    else 
+      { return 0; 
+      }
+  }
+
+sub _set_star_att_regexp_handler
+  { my( $handlers, $path, $handler, $prev_handler)= @_;
+    # check for *[@att=~ /regexp/] conditions
+    if( $path=~ m{^(?:\s*\*)?             # * (optional)
+                   \s*\[\s*\@             #  [@
+                   ($REG_NAME)            #    att
+                   \s*=~\s*               #        =~ 
+                   /($REG_REGEXP_EXP)/    #           /(regexp)/
+                   \s*($REG_REGEXP_MOD)?  #                     (mods)
+                   \s*\]\s*$}ox)          #                           ]  
+      { my( $att, $regexp, $mods)= ($1, $2, $3);
+        $mods||="";
+        $regexp= qr/(?$mods:$regexp)/;
+        if( $prev_handler)
+          { # replace or remove the previous handler
+            my $i=0; # so we can splice the array if need be
+            foreach my $exp ( @{$handlers->{att_regexp_handlers_exp}->{$att}})
+             { if( $exp->{regexp} eq $regexp)
+                 { if( $handler) # just replace the handler
+                     { $exp->{handler}= $handler;  
+                     }
+                   else          # remove the handler
+                     { splice( @{$handlers->{att_regexp_handlers_exp}->{$att}}, $i, 1);
+                   $handlers->{att_regexp_handlers}--;
+                       last;
+                     }
+                 }
+               $i++;
+             }
+          }
+        elsif( $handler)
+          { # new handler only
+            my $exp= { regexp => $regexp, handler => $handler};
+            $handlers->{regexp_handlers_exp}->{$att} ||= [];
+            push @{$handlers->{att_regexp_handlers_exp}->{$att}}, $exp;
+            $handlers->{att_regexp_handlers}++;
+          }
+        return 1;
+      }
+    else 
+      { return 0; 
+      }
+  }
+
+
+sub _set_pi_handler
+  { my( $handlers, $path, $handler, $prev_handler)= @_;
+    # PI conditions ( '?target' => \&handler or '?' => \&handler
+    #             or '#PItarget' => \&handler or '#PI' => \&handler)
+    if( $path=~ /^\s*(?:\?|#PI)\s*(?:([^\s]*)\s*)$/)
+      { my $target= $1 || '';
+        # update the path_handlers count, knowing that
+        # either the previous or the new handler can be undef
+        $handlers->{pi_handlers}->{$1}= $handler;
+        return 1;
+      }
+    else 
+      { return 0; 
+      }
+  }
+
+# just like eq except that undef values do not trigger warnings
+sub _eq
+  { my( $val1, $val2)= @_;
+    if( !defined $val1) { return !defined $val2 }
+    if( !defined $val2) { return 0; }
+    return $val1 eq $val2;
+  }
+
+sub setCharHandler
+  { my( $t, $handler)= @_;
+    $t->{twig_char_handler}= $handler;
+  }
+
+
+sub _reset_handlers
+  { my $handlers= shift;
+    delete $handlers->{handlers};
+    delete $handlers->{path_handlers};
+    delete $handlers->{subpath_handlers};
+    $handlers->{attcond_handlers_exp}=[] if( $handlers->{attcond_handlers});
+    delete $handlers->{attcond_handlers};
+  }
+  
+sub _set_handlers
+  { my $handlers= shift || return;
+    my $set_handlers= {};
+    foreach my $path (keys %{$handlers})
+      { _set_handler( $set_handlers, $path, $handlers->{$path}); }
+    return $set_handlers;
+  }
+    
+
+sub setTwigHandler
+  { my( $t, $path, $handler)= @_;
+    $t->{twig_handlers} ||={};
+    return _set_handler( $t->{twig_handlers}, $path, $handler);
+  }
+
+sub setTwigHandlers
+  { my( $t, $handlers)= @_;
+    my $previous_handlers= $t->{twig_handlers} || undef;
+    _reset_handlers( $t->{twig_handlers});
+    $t->{twig_handlers}= _set_handlers( $handlers);
+    return $previous_handlers;
+  }
+
+sub setStartTagHandler
+  { my( $t, $path, $handler)= @_;
+    $t->{twig_starttag_handlers}||={};
+    return _set_handler( $t->{twig_starttag_handlers}, $path, $handler);
+  }
+
+sub setStartTagHandlers
+  { my( $t, $handlers)= @_;
+    my $previous_handlers= $t->{twig_starttag_handlers} || undef;
+    _reset_handlers( $t->{twig_starttag_handlers});
+    $t->{twig_starttag_handlers}= _set_handlers( $handlers);
+    return $previous_handlers;
+   }
+
+sub setIgnoreEltsHandler
+  { my( $t, $path, $action)= @_;
+    $t->{twig_ignore_elts_handlers}||={};
+    return _set_handler( $t->{twig_ignore_elts_handlers}, $path, $action );
+  }
+
+sub setIgnoreEltsHandlers
+  { my( $t, $handlers)= @_;
+    my $previous_handlers= $t->{twig_ignore_elts_handlers} || undef;
+    _reset_handlers( $t->{twig_ignore_elts_handlers});
+    $t->{twig_ignore_elts_handlers}= _set_handlers( $handlers);
+    return $previous_handlers;
+   }
+
+sub setEndTagHandler
+  { my( $t, $path, $handler)= @_;
+    $t->{twig_endtag_handlers}||={};
+    return _set_handler( $t->{twig_endtag_handlers}, $path,$handler);
+  }
+
+sub setEndTagHandlers
+  { my( $t, $handlers)= @_;
+    my $previous_handlers= $t->{twig_endtag_handlers} || undef;
+    _reset_handlers( $t->{twig_endtag_handlers});
+    $t->{twig_endtag_handlers}= _set_handlers( $handlers);
+    return $previous_handlers;
+   }
+
+# a little more complex: set the twig_handlers only if a code ref is given
+sub setTwigRoots
+  { my( $t, $handlers)= @_;
+    my $previous_roots= $t->{twig_roots} || undef;
+    _reset_handlers($t->{twig_roots});
+    $t->{twig_roots}= _set_handlers( $handlers);
+    foreach my $path (keys %{$handlers})
+      { $t->{twig_handlers}||= {};
+        _set_handler( $t->{twig_handlers}, $path, $handlers->{$path})
+          if( isa( $handlers->{$path}, 'CODE')); 
+      }
+    return $previous_roots;
+  }
+
+# just store the reference to the expat object in the twig
+sub _twig_init
+  { 
+    my $p= shift;
+    my $t=$p->{twig};
+    $t->{twig_parser}= $p; 
+    weaken( $t->{twig_parser}) if( $weakrefs);
+    $t->{twig_parsing}=1;
+    # in case they had been created by a previous parse
+    delete $t->{twig_dtd};
+    delete $t->{twig_doctype};
+    delete $t->{twig_xmldecl};
+    # if needed set the output filehandle
+    $t->_set_fh_to_twig_output_fh();
+  }
+
+# uses eval to catch the parser's death
+sub safe_parse
+  { my( $t, $str)= @_;
+    eval { $t->parse( $str); } ;
+    return $@ ? 0 : $t;
+  }
+
+sub safe_parsefile
+  { my( $t, $file)= @_;
+    eval { $t->parsefile( $file); } ;
+    return $@ ? 0 : $t;
+  }
+
+
+sub _add_or_discard_stored_spaces
+  { my $t= shift;
+    my %option= @_;
+    
+    if( $t->{twig_stored_spaces} || $option{force} || $t->{twig_preserve_space})
+      { if( $t->{twig_current}->is_pcdata)
+          { $t->{twig_current}->append_pcdata($t->{twig_stored_spaces}); }
+        else
+          { my $current_gi= $t->{twig_current}->gi;
+            unless( defined( $t->{twig_space_policy}->{$current_gi}))
+              { $t->{twig_space_policy}->{$current_gi}= _space_policy( $t, $current_gi); }
+
+            if( $t->{twig_space_policy}->{$current_gi} ||  $option{force} || $t->{twig_preserve_space})
+              { _insert_pcdata( $t, $t->{twig_stored_spaces} ); }
+
+            $t->{twig_stored_spaces}='';
+          }
+      }
+  }
+
+# the default twig handlers, which build the tree
+sub _twig_start
+  { 
+    my ($p, $gi, @att)= @_;
+    my $t=$p->{twig};
+
+    # empty the stored pcdata (space stored in case they are really part of 
+    # a pcdata element) or stored it if the space policy dictades so
+    # create a pcdata element with the spaces if need be
+    _add_or_discard_stored_spaces( $t);
+    my $parent= $t->{twig_current};
+
+    # if we were parsing PCDATA then we exit the pcdata
+    if( $t->{twig_in_pcdata})
+      { $t->{twig_in_pcdata}= 0;
+        delete $parent->{'twig_current'};
+        $parent= $parent->{parent};
+      }
+
+    # if we choose to keep the encoding then we need to parse the tag
+    if( my $func = $t->{parse_start_tag})
+      { ($gi, @att)= &$func($p->original_string); }
+    
+    # filter the input data if need be  
+    if( my $filter= $t->{twig_input_filter})
+      { $gi= $filter->( $gi);
+        @att= map { $filter->($_) } @att; 
+      }
+
+    if( $t->{twig_map_xmlns}) 
+      { 
+        foreach my $new_prefix ( $p->new_ns_prefixes)
+          { my $uri= $t->parser->expand_ns_prefix( $new_prefix);
+            # replace the prefix if it is mapped
+            if( !$t->{twig_keep_original_prefix} && (my $mapped_prefix= $t->{twig_map_xmlns}->{$uri}))
+              { $new_prefix= $mapped_prefix; }
+            # now put the namespace declaration back in the element
+            if( $new_prefix eq '#default')
+              { push @att, "xmlns" =>  $uri; } 
+            else
+              { push @att, "xmlns:$new_prefix" =>  $uri; } 
+          }
+
+        if( $t->{twig_keep_original_prefix})
+          { # things become more complex: we need to find the original prefix
+            # and store both prefixes
+            my $ns_info= $t->_ns_info( $gi);
+            my $map_att;
+            if( $ns_info->{mapped_prefix})
+              { $gi= "$ns_info->{mapped_prefix}:$gi";
+                $map_att->{$ns_info->{mapped_prefix}}= $ns_info->{prefix};
+              }
+            my $att_name=1;
+            foreach( @att) 
+              { if( $att_name) 
+                  { 
+                    my $ns_info= $t->_ns_info( $_);
+                    if( $ns_info->{mapped_prefix})
+                      { $_= "$ns_info->{mapped_prefix}:$_";
+                        $map_att->{$ns_info->{mapped_prefix}}= $ns_info->{prefix};
+                      }
+                    $att_name=0; 
+                  }
+                else           
+                  {  $att_name=1; }
+              }
+            push @att, '#original_gi', $map_att if( $map_att);
+          }
+        else
+          { $gi= $t->_replace_prefix( $gi); 
+            my $att_name=1;
+            foreach( @att) 
+              { if( $att_name) { $_= $t->_replace_prefix( $_); $att_name=0; }
+                else           {  $att_name=1; }
+              }
+          }
+      }
+
+    my $elt= $t->{twig_elt_class}->new( $gi);
+    $elt->set_atts( @att);
+ 
+    delete $parent->{'twig_current'} if( $parent);
+    $t->{twig_current}= $elt;
+    $elt->{'twig_current'}=1;
+
+    if( $parent)
+      { my $prev_sibling= $parent->{last_child};
+        if( $prev_sibling) 
+          { $prev_sibling->{next_sibling}=  $elt; 
+            $elt->set_prev_sibling( $prev_sibling);
+          }
+
+        $elt->set_parent( $parent);
+        $parent->{first_child}=  $elt unless( $parent->{first_child}); 
+        $parent->set_last_child( $elt);
+      }
+    else 
+      { # processing root
+        $t->set_root( $elt);
+        # call dtd handlerif need be
+        $t->{twig_dtd_handler}->($t, $t->{twig_dtd})
+          if( defined $t->{twig_dtd_handler});
+      
+        # set this so we can catch external entities
+        # (the handler was modified during DTD processing)
+        if( $t->{twig_default_print})
+          { $p->setHandlers( Default => \&_twig_print); }
+        elsif( $t->{twig_roots})
+          { $p->setHandlers( Default => sub { return }); }
+        else
+          { $p->setHandlers( Default => \&_twig_default); }
+      }
+   
+    $elt->{empty}=  $p->recognized_string=~ m{/\s*>$}s ? 1 : 0;
+
+    $elt->{extra_data}= $t->{extra_data} if( $t->{extra_data});
+    $t->{extra_data}='';
+
+    # if the element is ID-ed then store that info
+    my $id= $elt->{'att'}->{$ID};
+    if( $id) { $t->{twig_id_list}->{$id}= $elt; 
+               weaken( $t->{twig_id_list}->{$id}) if( $weakrefs);
+             }
+
+
+    # call user handler if need be
+    if( $t->{twig_starttag_handlers})
+      { # call all appropriate handlers
+        my @handlers= _handler( $t, $t->{twig_starttag_handlers}, $gi, $elt);
+    
+        local $_= $elt;
+    
+        foreach my $handler ( @handlers)
+          { $handler->($t, $elt) || last; }
+        # call _all_ handler if needed
+        if( my $all= $t->{twig_starttag_handlers}->{handlers}->{$ALL})
+          { $all->($t, $elt); }
+      }
+
+    # check if the tag is in the list of tags to be ignored
+    if( $t->{twig_ignore_elts_handlers})
+      { my @handlers= _handler( $t, $t->{twig_ignore_elts_handlers}, $gi, $elt);
+        # only the first handler counts, it contains the action (discard/print/string)
+        if( @handlers) { my $action= shift @handlers; $t->ignore( $action); }
+      }
+
+    if( $elt->{'att'}->{'xml:space'} && (  $elt->{'att'}->{'xml:space'} eq 'preserve')) { $t->{twig_preserve_space}++; }
+
+  }
+
+# extract prefix, local_name, uri, mapped_prefix from a name
+# will only work if called from a start or end tag handler
+sub _ns_info
+  { my( $t, $name)= @_;
+    my $ns_info={};
+    my $p= $t->parser;
+    $ns_info->{uri}= $p->namespace( $name); 
+    return $ns_info unless( $ns_info->{uri});
+
+    $ns_info->{prefix}= _a_proper_ns_prefix( $p, $ns_info->{uri});
+    $ns_info->{mapped_prefix}= $t->{twig_map_xmlns}->{$ns_info->{uri}} || $ns_info->{prefix};
+
+    return $ns_info;
+  }
+    
+sub _a_proper_ns_prefix
+  { my( $p, $uri)= @_;
+    foreach my $prefix ($p->current_ns_prefixes)
+      { if( $p->expand_ns_prefix( $prefix) eq $uri)
+          { return $prefix; }
+      }
+  }
+
+
+# the default function to parse a start tag (in keep_encoding mode)
+# can be overridden with the parse_start_tag method
+# only works for 1-byte character sets
+sub _parse_start_tag
+  { my $string= shift;
+    my( $gi, @atts);
+
+    # get the gi (between < and the first space, / or > character)
+    #if( $string=~ s{^<\s*([^\s>/]*)[\s>/]*}{}s)
+    if( $string=~ s{^<\s*($REG_NAME)[\s>/]}{}s)
+      { $gi= $1; }
+    else
+      { croak "error parsing tag '$string'"; }
+    while( $string=~ s{^([^\s=]*)\s*=\s*(["'])(.*?)\2\s*}{}s)
+      { push @atts, $1, $3; }
+    return $gi, @atts;
+  }
+
+sub set_root
+  { my( $t, $elt)= @_;
+    $t->{twig_root}= $elt;
+    $elt->{twig}= $t;
+    weaken(  $elt->{twig}) if( $weakrefs);
+  }
+
+sub _twig_end($$;@)
+  { 
+    my ($p, $gi)  = @_;
+    my $t=$p->{twig};
+
+    if( $t->{twig_map_xmlns}) { $gi= $t->_replace_prefix( $gi); }
+  
+    _add_or_discard_stored_spaces( $t);
+ 
+    # the new twig_current is the parent
+    my $elt= $t->{twig_current};
+    delete $elt->{'twig_current'};
+
+    # if we were parsing PCDATA then we exit the pcdata too
+    if( $t->{twig_in_pcdata})
+      { $t->{twig_in_pcdata}= 0;
+        $elt= $elt->{parent} if($elt->{parent});
+        delete $elt->{'twig_current'};
+      }
+
+    # parent is the new current element
+    my $parent= $elt->{parent};
+    $parent->{'twig_current'}=1 if( $parent);
+    $t->{twig_current}= $parent;
+
+    $elt->{extra_data_before_end_tag}= $t->{extra_data} if( $t->{extra_data}); 
+    $t->{extra_data}='';
+
+    if( $t->{twig_handlers})
+      { # look for handlers
+        my @handlers= _handler( $t, $t->{twig_handlers}, $gi, $elt);
+
+        local $_= $elt; # so we can use $_ in the handlers
+    
+        foreach my $handler ( @handlers)
+          { $handler->($t, $elt) || last; }
+        # call _all_ handler if needed
+        if( my $all= $t->{twig_handlers}->{handlers}->{$ALL})
+          { $all->($t, $elt); }
+      }
+
+    # if twig_roots is set for the element then set appropriate handler
+    if(  $t->{twig_root_depth} and ($p->depth == $t->{twig_root_depth}) )
+      { if( $t->{twig_default_print})
+          { # select the proper fh (and store the currently selected one)
+            $t->_set_fh_to_twig_output_fh(); 
+            if( $t->{twig_keep_encoding})
+              { $p->setHandlers( %twig_handlers_roots_print_original); }
+            else
+              { $p->setHandlers( %twig_handlers_roots_print); }
+          }
+        else
+          { $p->setHandlers( %twig_handlers_roots); }
+      }
+
+    if( $elt->{'att'}->{'xml:space'} && (  $elt->{'att'}->{'xml:space'} eq 'preserve')) { $t->{twig_preserve_space}--; }
+  }
+
+# return the list of handler that can be activated for an element 
+# (either of CODE ref's or 1's for twig_roots)
+
+sub _handler
+  { my( $t, $handlers, $gi, $elt)= @_;
+
+    my @found_handlers=();
+    my $found_handler;
+
+    # warning: $elt can be either 
+    # - a regular element
+    # - a ref to the attribute hash (when called for an element 
+    #   for which the XML::Twig::Elt has not been built, outside 
+    #   of the twig_roots)
+    # - a string (case of an entity in keep_encoding mode)
+
+    # check for an attribute expression with no gi
+    if( $handlers->{att_handlers})
+      { my %att_handlers= %{$handlers->{att_handlers_exp}};
+        foreach my $att ( keys %att_handlers)
+          { my $att_val;
+            # get the attribute value
+            if( ref $elt eq 'HASH')
+              { $att_val= $elt->{$att}; }     # $elt is the atts hash
+            elsif( isa( $elt,'XML::Twig::Elt'))
+              { $att_val= $elt->{'att'}->{$att}; }  # $elt is an element
+                if( defined $att_val)
+                  { my @cond= @{$handlers->{att_handlers_exp}->{$att}};
+                    foreach my $cond (@cond)
+                      {  # 2 cases: either there is a val and the att value should be equal to it
+                         #          or there is no val (condition was gi[@att]), just for the att to be defined 
+                    if( !defined $cond->{val} || ($att_val eq $cond->{val}) )  
+                      { push @found_handlers, $cond->{handler};}
+                  }
+              }
+          }
+      }
+
+    # check for an attribute regexp expression with no gi
+    if( $handlers->{att_regexp_handlers})
+      { my %att_handlers= %{$handlers->{att_regexp_handlers_exp}};
+        foreach my $att ( keys %att_handlers)
+          { my $att_val;
+            # get the attribute value
+            if( ref $elt eq 'HASH')
+              { $att_val= $elt->{$att}; }     # $elt is the atts hash
+            elsif( isa( $elt,'XML::Twig::Elt'))
+              { $att_val= $elt->{'att'}->{$att}; }  # $elt is an element
+
+            if( defined $att_val)
+              { my @cond= @{$handlers->{att_regexp_handlers_exp}->{$att}};
+                foreach my $cond (@cond)
+                  { if( $att_val=~ $cond->{regexp})  
+                      { push @found_handlers, $cond->{handler};}
+                  }
+              }
+          }
+      }
+
+    # check for a text expression
+    if( $handlers->{text_handlers}->{$gi})
+      { my @text_handlers= @{$handlers->{text_handlers_exp}->{$gi}};
+        foreach my $exp ( @text_handlers)
+          { if (!$exp->{sub_elt})
+              { push @found_handlers, $exp->{handler}
+                  if $elt->text eq $exp->{text};
+              }
+            else
+              { foreach my $child ($elt->children($exp->{sub_elt}))
+                  { if( $child->text eq $exp->{text})
+                      { push @found_handlers, $exp->{handler};
+                        last;
+                      }
+                  }
+              }
+          }
+      }
+
+    # check for a text regexp expression
+    if( $handlers->{regexp_handlers}->{$gi})
+      { my @regexp_handlers= @{$handlers->{regexp_handlers_exp}->{$gi}};
+        foreach my $exp ( @regexp_handlers)
+          { if( !$exp->{sub_elt})
+              { push @found_handlers, $exp->{handler}
+                  if $elt->text =~ $exp->{regexp};
+              }
+            else
+              { foreach my $child ($elt->children($exp->{sub_elt}))
+                  { if( $child->text =~ $exp->{regexp})
+                      { push @found_handlers, $exp->{handler};
+                        last;
+                      }
+                  }
+              }
+          }
+      }
+
+    # check for an attribute expression
+    if( $handlers->{attcond_handlers}->{$gi})
+      { my @attcond_handlers= @{$handlers->{attcond_handlers_exp}->{$gi}};
+        foreach my $exp ( @attcond_handlers)
+          { my $att_val;
+        # get the attribute value
+        if( ref $elt eq 'HASH')
+          { $att_val= $elt->{$exp->{att}}; }    # $elt is the atts hash
+        else
+          { $att_val= $elt->{'att'}->{$exp->{att}}; }# $elt is an element
+
+        # 2 cases: either there is a val and the att value should be equal to it
+        #          or there is no val (condition was gi[@att]), just for the att to be defined 
+        if( defined $att_val && ( !defined $exp->{val} || ($att_val eq $exp->{val}) ) ) 
+              { push @found_handlers, $exp->{handler}; }
+          }
+      }
+
+    # check for an attribute regexp
+    if( $handlers->{attregexp_handlers}->{$gi})
+      { my @attregexp_handlers= @{$handlers->{attregexp_handlers_exp}->{$gi}};
+        foreach my $exp ( @attregexp_handlers)
+          { my $att_val;
+        # get the attribute value
+        if( ref $elt eq 'HASH')
+          { $att_val= $elt->{$exp->{att}}; }    # $elt is the atts hash
+        else
+          { $att_val= $elt->{'att'}->{$exp->{att}}; }# $elt is an element
+
+        if( defined $att_val && ( ($att_val=~  $exp->{regexp}) ) ) 
+              { push @found_handlers, $exp->{handler}; }
+          }
+      }
+
+    # check for a full path
+    if( defined $handlers->{path_handlers}->{gi}->{$gi})
+      { my $path= $t->path( $gi); 
+        if( defined( $found_handler= $handlers->{path_handlers}->{path}->{$path}) )
+          { push @found_handlers, $found_handler; }
+      }
+
+    # check for a partial path
+    if( $handlers->{subpath_handlers}->{gi}->{$gi})
+      { my $path= $t->path( $gi);
+        while( $path)
+          { # test each sub path
+            if( defined( $found_handler= $handlers->{subpath_handlers}->{path}->{$path}) )
+              { push @found_handlers, $found_handler; }
+             $path=~ s{^[^/]*/?}{}; # remove initial gi and /
+          }
+      }
+
+    # check for a gi (simple gi's are stored directly in the handlers field)
+    if( defined $handlers->{handlers}->{gi}->{$gi})
+      { push @found_handlers, $handlers->{handlers}->{gi}->{$gi}; }
+
+    # if no handler found call default handler if defined
+    if( !@found_handlers && defined $handlers->{handlers}->{$DEFAULT})
+      { push @found_handlers, $handlers->{handlers}->{$DEFAULT}; }
+
+    if( @found_handlers and $t->{twig_do_not_chain_handlers}) 
+      { @found_handlers= ($found_handlers[0]); }
+
+    return @found_handlers; # empty if no handler found
+
+  }
+
+
+sub _replace_prefix
+  { my( $t, $name)= @_;
+    my $p= $t->parser;
+    my $uri= $p->namespace( $name);
+    # try to get the namespace rom default if none is found (for attributes)
+    # this should probably be an option
+    if( !$uri and( $name!~/^xml/)) { $uri= $p->expand_ns_prefix( '#default'); }
+    if( $uri)
+      { if (my $mapped_prefix= $t->{twig_map_xmlns}->{$uri})
+          { return "$mapped_prefix:$name"; }
+        else
+          { my $prefix= _a_proper_ns_prefix( $p, $uri);
+            return $prefix ? "$prefix:$name" : $name; 
+          }
+      }
+    else
+      { return $name; }
+  }
+
+sub _twig_char
+  { 
+    my ($p, $string)= @_;
+    my $t=$p->{twig}; 
+
+    # if keep_encoding was set then use the original string instead of
+    # the parsed (UTF-8 converted) one
+    if( $t->{twig_keep_encoding})
+      { $string= $p->original_string(); }
+
+    if( $t->{twig_input_filter})
+      { $string= $t->{twig_input_filter}->( $string); }
+
+    if( $t->{twig_char_handler})
+      { $string= $t->{twig_char_handler}->( $string); }
+
+    my $elt= $t->{twig_current};
+
+    if(    $t->{twig_in_cdata})
+      { # text is the continuation of a previously created pcdata
+        $elt->{cdata}.=  $t->{twig_stored_spaces}.$string; } 
+    elsif( $t->{twig_in_pcdata})
+      { # text is the continuation of a previously created cdata
+        $elt->{pcdata}.=  $string; 
+      } 
+    else
+      { # text is just space, which might be discarded later
+        if( $string=~/\A\s*\Z/s)
+          { if( $t->{extra_data})
+              { # we got extra data (comment, pi), lets add the spaces to it
+                $t->{extra_data} .= $string; 
+              }
+            else
+              { # no extra data, just store the spaces
+                $t->{twig_stored_spaces}.= $string;
+              }
+          } 
+        else
+          { my $new_elt= _insert_pcdata( $t, $t->{twig_stored_spaces}.$string);
+            delete $elt->{'twig_current'};
+            $new_elt->{'twig_current'}=1;
+            $t->{twig_current}= $new_elt;
+            $t->{twig_in_pcdata}=1;
+            $new_elt->{extra_data}= $t->{extra_data} if( $t->{extra_data});
+            $t->{extra_data}='';
+          }
+      }
+  }
+
+sub _twig_cdatastart
+  { 
+    my $p= shift;
+    my $t=$p->{twig};
+
+    $t->{twig_in_cdata}=1;
+    my $cdata=  $t->{twig_elt_class}->new( '#CDATA');
+    my $twig_current= $t->{twig_current};
+
+    if( $t->{twig_in_pcdata})
+      { # create the node as a sibling of the #PCDATA
+        $cdata->set_prev_sibling( $twig_current);
+        $twig_current->{next_sibling}=  $cdata;
+        my $parent= $twig_current->{parent};
+        $cdata->set_parent( $parent);
+        $parent->set_last_child( $cdata);
+        $t->{twig_in_pcdata}=0;
+      }
+    else
+      { # we have to create a PCDATA element if we need to store spaces
+        if( $t->_space_policy($XML::Twig::index2gi[$twig_current->{'gi'}]) && $t->{twig_stored_spaces})
+          { _insert_pcdata( $t, $t->{twig_stored_spaces}); }
+        $t->{twig_stored_spaces}='';
+      
+        # create the node as a child of the current element      
+        $cdata->set_parent( $twig_current);
+        if( my $prev_sibling= $twig_current->{last_child})
+          { $cdata->set_prev_sibling( $prev_sibling);
+            $prev_sibling->{next_sibling}=  $cdata;
+          }
+        else
+          { $twig_current->{first_child}=  $cdata; }
+        $twig_current->set_last_child( $cdata);
+      
+      }
+
+    delete $twig_current->{'twig_current'};
+    $t->{twig_current}= $cdata;
+    $cdata->{'twig_current'}=1;
+  }
+
+sub _twig_cdataend
+  { 
+    my $p= shift;
+    my $t=$p->{twig};
+
+    $t->{twig_in_cdata}=0;
+
+    my $elt= $t->{twig_current};
+    delete $elt->{'twig_current'};
+    my $cdata= $elt->{cdata};
+    $elt->{cdata}=  $cdata;
+
+    if( $t->{twig_handlers})
+      { # look for handlers
+        my @handlers= _handler( $t, $t->{twig_handlers}, CDATA, $elt);
+        local $_= $elt; # so we can use $_ in the handlers
+        foreach my $handler ( @handlers) { $handler->($t, $elt) || last; }
+      }
+
+    $elt= $elt->{parent};
+    $t->{twig_current}= $elt;
+    $elt->{'twig_current'}=1;
+  }
+
+sub _twig_pi
+  { 
+    my( $p, $target, $data)= @_;
+    my $t=$p->{twig};
+    return unless( $t->{twig_process_pi} || $t->{twig_keep_pi});
+
+    if( $t->{twig_input_filter})
+      { $target = $t->{twig_input_filter}->( $target) ;
+        $data   = $t->{twig_input_filter}->( $data)   ;
+      }
+
+    my $twig_current= $t->{twig_current};    # always defined
+
+    # if pi's are to be kept then we piggiback them to the current element
+    if( $t->{twig_keep_pi})
+      {  
+        if( my $handler= $t->{twig_handlers}->{pi_handlers}->{$target})
+          { $t->{extra_data}.= $handler->( $t, $target, $data); }
+        elsif( $handler= $t->{twig_handlers}->{pi_handlers}->{''})
+          { $t->{extra_data}.= $handler->( $t, $target, $data); }
+        else
+          { if( $t->{twig_stored_spaces})
+              { $t->{extra_data}.= $t->{twig_stored_spaces};
+                $t->{twig_stored_spaces}= '';
+              }
+            # then the recognized/original string (input filtered if needed)
+            my $extra_data= $XML::Twig::Elt::keep_encoding ?  $p->recognized_string() : $p->original_string();
+            $extra_data= $t->{twig_input_filter}->( $extra_data) if( $t->{twig_input_filter});
+            $t->{extra_data}.= $extra_data;
+            return;
+          }
+
+      }
+    else
+      { # pi's are processed
+        my $pi=  $t->{twig_elt_class}->new( PI);
+        $pi->set_pi( $target, $data);
+
+        unless( $t->root)
+          {  _pi_handlers( $t, $pi, $target);
+            _add_prolog_data( $t, $pi); 
+            return;
+          }
+
+        if( $t->{twig_in_pcdata})
+          { # create the node as a sibling of the #PCDATA
+            $pi->paste_after( $twig_current);
+            $t->{twig_in_pcdata}=0;
+          }
+        else
+          { # we have to create a PCDATA element if we need to store spaces
+            if( $t->_space_policy($XML::Twig::index2gi[$twig_current->{'gi'}]) && $t->{twig_stored_spaces})
+              { _insert_pcdata( $t, $t->{twig_stored_spaces}); }
+            $t->{twig_stored_spaces}='';
+            # create the node as a child of the current element
+            $pi->paste_last_child( $twig_current);
+          }
+    
+        delete $twig_current->{'twig_current'};
+        my $parent= $pi->{parent}; 
+        $t->{twig_current}= $parent;
+        $parent->{'twig_current'}=1;
+
+        _pi_handlers( $t, $pi, $target);
+      }
+
+  }
+
+sub _pi_handlers
+  { my( $t, $pi, $target)= @_;
+    if( my $handler= $t->{twig_handlers}->{pi_handlers}->{$target})
+      { local $_= $pi; $handler->( $t, $pi); }
+    elsif( $handler= $t->{twig_handlers}->{pi_handlers}->{''})
+      { local $_= $pi; $handler->( $t, $pi); }
+  }
+
+
+sub _twig_comment
+  { 
+    my( $p, $comment_text)= @_;
+    my $t=$p->{twig};
+    return unless( $t->{twig_process_comments} || $t->{twig_keep_comments});
+
+    my $twig_current= $t->{twig_current};    # always defined
+
+    # if comments are to be kept then we piggiback them to the current element
+    if( $t->{twig_keep_comments})
+      { # first add spaces
+        if( $t->{twig_stored_spaces})
+              { $t->{extra_data}.= $t->{twig_stored_spaces};
+                $t->{twig_stored_spaces}= '';
+              }
+        # then the recognized/original string (input filtered if needed)
+        my $extra_data= $XML::Twig::Elt::keep_encoding ?  $p->recognized_string() : $p->original_string();
+        $extra_data= $t->{twig_input_filter}->( $extra_data) if( $t->{twig_input_filter});
+        $t->{extra_data}.= $extra_data;
+        return;
+      }
+
+    $comment_text= $t->{twig_input_filter}->( $comment_text) if( $t->{twig_input_filter});
+
+    my $comment=  $t->{twig_elt_class}->new( COMMENT);
+    $comment->{comment}=  $comment_text;
+
+    unless( $t->root) 
+      { _add_prolog_data( $t, $comment);
+        _comment_handler( $t, $comment);
+        return;
+      }
+
+    if( $t->{twig_in_pcdata})
+      { # create the node as a sibling of the #PCDATA
+        $comment->paste_after( $twig_current);
+        $t->{twig_in_pcdata}=0;
+      }
+    else
+      { # we have to create a PCDATA element if we need to store spaces
+        if( $t->_space_policy($XML::Twig::index2gi[$twig_current->{'gi'}]) && $t->{twig_stored_spaces})
+          { _insert_pcdata( $t, $t->{twig_stored_spaces}); }
+        $t->{twig_stored_spaces}='';
+        # create the node as a child of the current element
+        $comment->paste_last_child( $twig_current);
+
+      }
+    _comment_handler( $t, $comment);
+
+    delete $twig_current->{'twig_current'};
+
+    my $parent= $comment->{parent};
+    $t->{twig_current}= $parent;
+    $parent->{'twig_current'}=1;
+
+  }
+
+sub _comment_handler
+  { my( $t, $comment)= @_;
+    if( $t->{twig_handlers}->{handlers}->{gi}->{'#COMMENT'})
+      { # look for handlers
+        local $_= $comment;
+        my @handlers= _handler( $t, $t->{twig_handlers}, '#COMMENT', $comment);
+        foreach my $handler ( @handlers)
+          { $handler->($t, $comment) || last; }
+      }
+  }
+
+
+sub _add_prolog_data
+  { my($t, $prolog_data)= @_;
+    # comment before the first element
+    $t->{prolog_data} ||= $t->{twig_elt_class}->new( '#PROLOG_DATA');
+    # create the node as a child of the current element
+    $prolog_data->paste_last_child( $t->{prolog_data});
+  }
+  
+sub _twig_final
+  { 
+    my $p= shift;
+    my $t=$p->{twig};
+
+    # restore the selected filehandle if needed
+    $t->_set_fh_to_selected_fh();
+
+    select $t->{twig_original_selected_fh} if($t->{twig_original_selected_fh}); # probably dodgy
+
+    # tries to clean-up (probably not very well at the moment)
+    undef $p->{twig};
+    undef $t->{twig_parser};
+
+    undef $t->{twig_parsing};
+
+    return $t;
+  }
+
+sub _insert_pcdata
+  { my( $t, $string)= @_;
+    # create a new #PCDATA element
+    my $parent= $t->{twig_current};    # always defined
+    my $elt=  $t->{twig_elt_class}->new( PCDATA);
+    $elt->{pcdata}=  $string;
+    my $prev_sibling= $parent->{last_child};
+    if( $prev_sibling) 
+      { $prev_sibling->{next_sibling}=  $elt; 
+        $elt->set_prev_sibling( $prev_sibling);
+      }
+    else
+      { $parent->{first_child}=  $elt; }
+
+    $elt->set_parent( $parent);
+    $parent->set_last_child( $elt);
+    $t->{twig_stored_spaces}='';
+    return $elt;
+  }
+
+sub _space_policy
+  { my( $t, $gi)= @_;
+    my $policy;
+    $policy=0 if( $t->{twig_discard_spaces});
+    $policy=1 if( $t->{twig_keep_spaces});
+    $policy=1 if( $t->{twig_keep_spaces_in}
+               && $t->{twig_keep_spaces_in}->{$gi});
+    $policy=0 if( $t->{twig_discard_spaces_in} 
+               && $t->{twig_discard_spaces_in}->{$gi});
+    return $policy;
+  }
+
+
+sub _twig_entity($$$$$$)
+  { 
+    my( $p, $name, $val, $sysid, $pubid, $ndata)= @_;
+    my $t=$p->{twig};
+    my $ent=XML::Twig::Entity->new( $name, $val, $sysid, $pubid, $ndata);
+    $t->{twig_entity_list}->add( $ent);
+    if( $parser_version > 2.27) 
+      { # this is really ugly, but with some versions of XML::Parser the value 
+        # of the entity is not properly returned by the default handler
+        my $ent_decl= $ent->text;
+        if( $t->{twig_keep_encoding})
+          { if( defined $ent->{val} && ($ent_decl !~ /["']/))
+              { my $val=  $ent->{val};
+                $ent_decl .= $val =~ /"/ ? qq{'$val' } : qq{"$val" }; 
+              }
+				    # for my solaris box (perl 5.6.1, XML::Parser 2.31, expat?)
+            $t->{twig_doctype}->{internal}=~ s{<!ENTITY\s+$name\s+$}{substr( $ent_decl, 0, -1)}e;
+          }
+        $t->{twig_doctype}->{internal} .= $ent_decl 
+          unless( $t->{twig_doctype}->{internal}=~ m{<!ENTITY\s+$name\s+});
+      }
+  }
+
+sub _twig_xmldecl
+  { 
+    my $p= shift;
+    my $t=$p->{twig};
+    $t->{twig_xmldecl}||={};                 # could have been set by set_output_encoding
+    $t->{twig_xmldecl}->{version}= shift;
+    $t->{twig_xmldecl}->{encoding}= shift; 
+    $t->{twig_xmldecl}->{standalone}= shift;
+  }
+
+sub _twig_doctype
+  { 
+    my( $p, $name, $sysid, $pub, $internal)= @_;
+    my $t=$p->{twig};
+    $t->{twig_doctype}||= {};                   # create 
+    $t->{twig_doctype}->{name}= $name;          # always there
+    $t->{twig_doctype}->{sysid}= $sysid;        #  
+    $t->{twig_doctype}->{pub}= $pub;            #  
+
+    # now let's try to cope with XML::Parser 2.28 and above
+    if( $parser_version > 2.27)
+      { @saved_default_handler= $p->setHandlers( Default     => \&_twig_store_internal_dtd,
+                                                 Entity      => \&_twig_entity,
+                                               );
+      $p->setHandlers( DoctypeFin  => \&_twig_stop_storing_internal_dtd);
+      $t->{twig_doctype}->{internal}='';
+      }
+    else            
+      # for XML::Parser before 2.28
+      { $t->{twig_doctype}->{internal}=$internal; }
+
+    # now check if we want to get the DTD info
+    if( $t->{twig_read_external_dtd} && $sysid)
+      { # let's build a fake document with an internal DTD
+        # is this portable?
+        my $tmpfile= "twig_tmp$$";
+        open( TMP, ">$tmpfile") 
+          or croak "cannot create temp file $tmpfile: $!";
+        print TMP "<!DOCTYPE $name [\n";   # print the doctype
+        # slurp the DTD
+          { open( DTD, "<$sysid") 
+              or croak "cannot open dtd file $sysid: $!";
+            local $/= undef;
+            my $dtd= <DTD>;
+            close DTD;
+            print TMP $dtd;                 # add the dtd
+          }
+        print TMP "]>";                     # close the dtd
+        print TMP "<dummy></dummy>\n";      # XML::Parser needs an element
+
+        close TMP;
+       
+        $t->save_global_state();            # save the globals (they will be reset by the following new)  
+        my $t_dtd= XML::Twig->new;          # create a temp twig
+        $t->restore_global_state();
+        $t_dtd->parsefile( $tmpfile);       # parse it
+        $t->{twig_dtd}= $t_dtd->{twig_dtd}; # grab the dtd info
+        #$t->{twig_dtd_is_external}=1;
+        $t->{twig_entity_list}= $t_dtd->{twig_entity_list}; # grab the entity info
+
+        unlink $tmpfile;
+      }
+
+  }
+
+sub _twig_element
+  { 
+    my( $p, $name, $model)= @_;
+    my $t=$p->{twig};
+    $t->{twig_dtd}||= {};                      # may create the dtd 
+    $t->{twig_dtd}->{model}||= {};             # may create the model hash 
+    $t->{twig_dtd}->{elt_list}||= [];          # ordered list of elements 
+    push @{$t->{twig_dtd}->{elt_list}}, $name; # store the elt
+    $t->{twig_dtd}->{model}->{$name}= $model;  # store the model
+    if( ($parser_version > 2.27) && ($t->{twig_doctype}->{internal}=~ m{(^|>)\s*$}) ) 
+      { my $text= $XML::Twig::Elt::keep_encoding ? $p->original_string : $p->recognized_string; 
+        unless( $text)
+          { # this version of XML::Parser does not return the text in the *_string method
+            # we need to rebuild it
+            $text= "<!ELEMENT $name $model>";
+          }
+        $t->{twig_doctype}->{internal} .= $text;
+      }
+  }
+
+sub _twig_attlist
+  { 
+    my( $p, $el, $att, $type, $default, $fixed)= @_;
+    my $t=$p->{twig};
+    $t->{twig_dtd}||= {};                      # create dtd if need be 
+    $t->{twig_dtd}->{$el}||= {};               # create elt if need be 
+    #$t->{twig_dtd}->{$el}->{att}||= {};        # create att if need be 
+    if( ($parser_version > 2.27) && ($t->{twig_doctype}->{internal}=~ m{(^|>)\s*$}) ) 
+      { my $text= $XML::Twig::Elt::keep_encoding ? $p->original_string : $p->recognized_string; 
+        unless( $text)
+          { # this version of XML::Parser does not return the text in the *_string method
+            # we need to rebuild it
+            my $att_decl="$att $type";
+            $att_decl .= " #FIXED"   if( $fixed);
+            $att_decl .= " $default" if( $default);
+            # 2 cases: there is already an attlist on that element or not
+            if( $t->{twig_dtd}->{att}->{$el})
+              { # there is already an attlist, add to it
+                $t->{twig_doctype}->{internal}=~ s{(<!ATTLIST\s*$el )(.*?)\n?>}
+                                                  { "$1$2\n" . ' ' x length( $1) . "$att_decl\n>"}es;
+              }
+            else
+              { # create the attlist
+                 $t->{twig_doctype}->{internal}.= "<!ATTLIST $el $att_decl>"
+              }
+          }
+      }
+    $t->{twig_dtd}->{att}->{$el}->{$att}= {} ;
+    $t->{twig_dtd}->{att}->{$el}->{$att}->{type}= $type; 
+    $t->{twig_dtd}->{att}->{$el}->{$att}->{default}= $default; 
+    $t->{twig_dtd}->{att}->{$el}->{$att}->{fixed}= $fixed; 
+  }
+
+sub _twig_default
+  { 
+    my( $p, $string)= @_;
+    
+    my $t= $p->{twig};
+    
+    # process only if we have an entity
+    return unless( $string=~ m{^&([^;]*);$});
+    # the entity has to be pure pcdata, or we have a problem
+    my $ent;
+    if( $t->{twig_keep_encoding}) 
+      { _twig_char( $p, $string); 
+        $ent= substr( $string, 1, -1);
+      }
+    else
+      { $ent= _twig_insert_ent( $t, $string); 
+      }
+  }
+    
+sub _twig_insert_ent
+  { 
+    my( $t, $string)=@_;
+
+    my $twig_current= $t->{twig_current};
+
+    my $ent=  $t->{twig_elt_class}->new( '#ENT');
+    $ent->{ent}=  $string;
+
+    _add_or_discard_stored_spaces( $t, force => 0);
+    
+    if( $t->{twig_in_pcdata})
+      { # create the node as a sibling of the #PCDATA
+
+        $ent->set_prev_sibling( $twig_current);
+        $twig_current->{next_sibling}=  $ent;
+        my $parent= $twig_current->{parent};
+        $ent->set_parent( $parent);
+        $parent->set_last_child( $ent);
+        # the twig_current is now the parent
+        delete $twig_current->{'twig_current'};
+        $t->{twig_current}= $parent;
+        # we left pcdata
+        $t->{twig_in_pcdata}=0;
+      }
+    else
+      { # create the node as a child of the current element
+        $ent->set_parent( $twig_current);
+        if( my $prev_sibling= $twig_current->{last_child})
+          { $ent->set_prev_sibling( $prev_sibling);
+            $prev_sibling->{next_sibling}=  $ent;
+          }
+        else
+          { $twig_current->{first_child}=  $ent; }
+        $twig_current->set_last_child( $ent);
+      }
+
+    return $ent;
+  }
+
+sub parser
+  { return $_[0]->{twig_parser}; }
+
+# returns the declaration text (or a default one)
+sub xmldecl
+  { my $t= shift;
+    return '' unless( $t->{twig_xmldecl} || $t->{output_encoding});
+    my $decl_string;
+    my $decl= $t->{twig_xmldecl};
+    if( $decl)
+      { my $version= $decl->{version};
+        $decl_string= q{<?xml};
+        $decl_string .= qq{ version="$version"};
+
+        # encoding can either have been set (in $decl->{output_encoding})
+        # or come from the document (in $decl->{encoding})
+        if( $t->{output_encoding})
+          { my $encoding= $t->{output_encoding};
+            $decl_string .= qq{ encoding="$encoding"};
+          }
+        elsif( $decl->{encoding})
+          { my $encoding= $decl->{encoding};
+            $decl_string .= qq{ encoding="$encoding"};
+          }
+    
+        if( defined( $decl->{standalone}))
+          { $decl_string .= q{ standalone="};  
+            $decl_string .= $decl->{standalone} ? "yes" : "no";  
+            $decl_string .= q{"}; 
+          }
+      
+        $decl_string .= "?>\n";
+      }
+    else
+      { my $encoding= $t->{output_encoding};
+        $decl_string= qq{<?xml version="1.0" encoding="$encoding"?>};
+      }
+      
+    my $output_filter= XML::Twig::Elt::output_filter();
+    return $output_filter ? $output_filter->( $decl_string) : $decl_string;
+  }
+
+# returns the doctype text (or none)
+# that's the doctype just has it was in the original document
+sub doctype
+  { my $t= shift;
+    my $doctype= $t->{twig_doctype} or return '';
+    my $string= "<!DOCTYPE " . $doctype->{name};
+    $string  .= qq{ SYSTEM "$doctype->{sysid}"} if( $doctype->{sysid});
+    $string  .= qq{ PUBLIC  "$doctype->{pub}" } if( $doctype->{pub});
+    if( $doctype->{internal})
+      { # !@#$%^&* code to deal with various expat/XML::Parser versions
+        $string.= " [" unless( $doctype->{internal}=~ m{^\s*\[});
+        $string.= " " if( $doctype->{internal}=~ m{^\[});
+        $string  .= $doctype->{internal};
+        $string=~ s{\n?]?>?$}{\n]>};
+      }
+    return $string;
+  }
+
+sub set_doctype
+  { my( $t, $name, $system, $public, $internal)= @_;
+    $t->{twig_doctype}= {};
+    my $doctype= $t->{twig_doctype};
+    $doctype->{name}     = $name     if( defined $name);
+    $doctype->{sysid}    = $system   if( defined $system);
+    $doctype->{pub}      = $public   if( defined $public);
+    $doctype->{internal} = $internal if( defined $internal);
+  }
+
+# return the dtd object
+sub dtd
+  { my $t= shift;
+    return $t->{twig_dtd};
+  }
+
+# return an element model, or the list of element models
+sub model
+  { my $t= shift;
+    my $elt= shift;
+    return $t->dtd->{model}->{$elt} if( $elt);
+    return sort keys %{$t->dtd->{model}};
+  }
+
+        
+# return the entity_list object 
+sub entity_list($)
+  { my $t= shift;
+    return $t->{twig_entity_list};
+  }
+
+# return the list of entity names 
+sub entity_names($)
+  { my $t= shift;
+    return sort keys %{$t->{twig_entity_list}} ;
+  }
+
+# return the entity object 
+sub entity($$)
+  { my $t= shift;
+    my $entity_name= shift;
+    return $t->{twig_entity_list}->{$entity_name};
+  }
+
+
+sub print_prolog
+  { my $t= shift;
+    my $fh=  _is_fh($_[0])  ? shift : undef;
+    if( $fh) { print $fh $t->prolog( @_); }
+    else     { print $t->prolog( @_);     }
+  }
+
+sub prolog
+  { my $t= shift;
+    my %args= _normalize_args( @_);
+    my $prolog='';
+
+    return $prolog if( $t->{no_prolog});
+
+    my $update_dtd = $args{UpdateDTD} || '';
+
+    $prolog .= $t->xmldecl;
+    return $prolog if( defined( $t->{no_dtd_output}) or !(defined $t->{twig_doctype}));
+    my $doctype= $t->{twig_doctype};
+    if( $update_dtd)
+      { 
+        if( defined $doctype->{sysid}  )  
+          { $prolog .= "<!DOCTYPE ".$doctype->{name};
+            $prolog .= " PUBLIC  \"$doctype->{pub}\""  if( $doctype->{pub});
+            $prolog .= " SYSTEM \"$doctype->{sysid}\"" if( $doctype->{sysid} && !$doctype->{pub});
+            $prolog .= "[\n";
+            $prolog .= $t->{twig_entity_list}->text;
+            $prolog .= "]>\n";
+          }
+        else
+          { my $dtd= $t->{'twig_dtd'};
+            $prolog .= $t->dtd_text;
+          }            
+      }
+    else
+      { 
+        $prolog .= "<!DOCTYPE ". $doctype->{name}  if( $doctype->{name});
+        $prolog .= " PUBLIC \"$doctype->{pub}\""  if( $doctype->{pub});
+        $prolog .= " SYSTEM" if( $doctype->{sysid} && !$doctype->{pub});
+        $prolog .= ' "' . $doctype->{sysid} . '"'  if( $doctype->{sysid}); 
+        if( my $internal= $doctype->{internal}) 
+          { # add opening and closing brackets if not already there
+            # plus some spaces and newlines for a nice formating
+            # I test it here because I can't remember which version of
+            # XML::Parser need it or not, so this is actually quite safe
+            $internal=~ s{^\s*(\[\s*)?}{ [\n};
+            $internal=~ s{\s*(\]\s*(>\s*)?)?\s*$}{\n]>\n};
+            $prolog .=  $internal; 
+          }
+      }
+
+    # terrible hack, as I can't figure out in which case the darn prolog
+    # should get an extra >
+    $prolog=~ s/(>\s*)*$/>\n/;
+
+    my $output_filter= XML::Twig::Elt::output_filter();
+    return $output_filter ? $output_filter->( $prolog) : $prolog;
+  }
+
+sub _print_prolog_data
+  { my $t= shift;
+    my $fh=  _is_fh($_[0])  ? shift : undef;
+    if( $fh) { print $fh $t->_prolog_data( @_); }
+    else     { print $t->_prolog_data( @_);     }
+  }
+
+sub _prolog_data
+  { my $t= shift;
+    return''  unless( $t->{prolog_data});
+    my $prolog_data_text='';
+    foreach ( $t->{prolog_data}->children)
+      { $prolog_data_text .= $_->sprint . "\n"; }
+    return$ prolog_data_text;
+  }
+
+sub print
+  { my $t= shift;
+    my $fh=  _is_fh( $_[0])  ? shift : undef;
+    my %args= _normalize_args( @_);
+
+    my $old_pretty;
+    if( defined $args{PrettyPrint})
+      { $old_pretty= $t->set_pretty_print( $args{PrettyPrint}); 
+        delete $args{PrettyPrint};
+      }
+
+     my $old_empty_tag_style;
+     if( defined $args{EmptyTags})
+      { $old_empty_tag_style= $t->set_empty_tag_style( $args{EmptyTags}); 
+        delete $args{EmptyTags};
+      }
+
+    if( $fh) 
+      { $t->print_prolog( $fh, %args); 
+        $t->_print_prolog_data( $fh, %args);
+      }
+    else 
+      { $t->print_prolog( %args);
+        $t->_print_prolog_data( %args);
+      }
+
+    $t->{twig_root}->print( $fh) if( $t->{twig_root});
+    $t->set_pretty_print( $old_pretty) if( defined $old_pretty); 
+    $t->set_empty_tag_style( $old_empty_tag_style) if( defined $old_empty_tag_style); 
+  }
+
+
+sub flush
+  { my $t= shift;
+    my $fh=  _is_fh( $_[0]) ? shift : undef;
+    my $old_select= defined $fh ? select $fh : undef;
+    my $up_to= ref $_[0] ? shift : undef;
+    my %args= _normalize_args( @_);
+
+    my $old_pretty;
+    if( defined $args{PrettyPrint})
+      { $old_pretty= $t->set_pretty_print( $args{PrettyPrint}); 
+        delete $args{PrettyPrint};
+      }
+
+     my $old_empty_tag_style;
+     if( $args{EmptyTags})
+      { $old_empty_tag_style= $t->set_empty_tag_style( $args{EmptyTags}); 
+        delete $args{EmptyTags};
+      }
+
+
+    # the "real" last element processed, as _twig_end has closed it
+    my $last_elt;
+    if( $up_to)
+      { $last_elt= $up_to; }
+    elsif( $t->{twig_current})
+      { $last_elt= $t->{twig_current}->_last_child; }
+    else
+      { $last_elt= $t->{twig_root}; }
+
+    # flush the DTD unless it has ready flushed (ie root has been flushed)
+    my $elt= $t->{twig_root};
+    $t->print_prolog( %args) unless( $elt->_flushed);
+
+    while( $elt)
+      { my $next_elt; 
+        if( $last_elt && $last_elt->in( $elt))
+          { 
+            unless( $elt->_flushed) 
+              { # just output the front tag
+                print $elt->start_tag();
+                $elt->_set_flushed;
+              }
+            $next_elt= $elt->{first_child};
+          }
+        else
+          { # an element before the last one or the last one,
+            $next_elt= $elt->{next_sibling};  
+            $elt->_flush();
+            $elt->delete; 
+            last if( $last_elt && ($elt == $last_elt));
+          }
+        $elt= $next_elt;
+      }
+    select $old_select if( defined $old_select);
+    $t->set_pretty_print( $old_pretty) if( defined $old_pretty); 
+    $t->set_empty_tag_style( $old_empty_tag_style) if( defined $old_empty_tag_style); 
+  }
+
+
+# flushes up to an element
+# this method just reorders the arguments and calls flush
+sub flush_up_to
+  { my $t= shift;
+    my $up_to= shift;
+    if( _is_fh( $_[0]))
+      { my $fh=  shift;
+        $t->flush( $fh, $up_to, @_);
+      }
+    else
+      { $t->flush( $up_to, @_); }
+  }
+
+    
+# same as print except the entire document text is returned as a string
+sub sprint
+  { my $t= shift;
+    my %args= _normalize_args( @_);
+
+    my $old_pretty;
+    if( defined $args{PrettyPrint})
+      { $old_pretty= $t->set_pretty_print( $args{PrettyPrint}); 
+        delete $args{PrettyPrint};
+      }
+
+     my $old_empty_tag_style;
+     if( defined $args{EmptyTags})
+      { $old_empty_tag_style= $t->set_empty_tag_style( $args{EmptyTags}); 
+        delete $args{EmptyTags};
+      }
+      
+    my $prolog= $t->prolog( %args) || '';
+    my $prolog_data= $t->_prolog_data( %args) || '';
+    
+    my $string=  $prolog . $prolog_data . $t->{twig_root}->sprint;
+
+    $t->set_pretty_print( $old_pretty) if( defined $old_pretty); 
+    $t->set_empty_tag_style( $old_empty_tag_style) if( defined $old_empty_tag_style); 
+
+    return $string;
+  }
+    
+
+# this method discards useless elements in a tree
+# it does the same thing as a flush except it does not print it
+# the second argument is an element, the last purged element
+# (this argument is usually set through the purge_up_to method)
+sub purge
+  { my $t= shift;
+    my $up_to= shift;
+
+    # the "real" last element processed, as _twig_end has closed it
+    my $last_elt;
+    if( $up_to)
+      { $last_elt= $up_to; }
+    elsif( $t->{twig_current})
+      { $last_elt= $t->{twig_current}->_last_child; }
+    else
+      { $last_elt= $t->{twig_root}; }
+    
+    my $elt= $t->{twig_root};
+
+    while( $elt)
+      { my $next_elt; 
+        if( $last_elt && $last_elt->in( $elt))
+          { $elt->_set_flushed;
+            $next_elt= $elt->{first_child};
+          }
+        else
+          { # an element before the last one or the last one,
+            $next_elt= $elt->{next_sibling};  
+            $elt->delete; 
+            last if( $elt == $last_elt);
+          }
+        $elt= $next_elt;
+      }
+  }
+    
+# flushes up to an element. This method just calls purge
+sub purge_up_to
+  { my $t= shift;
+    my $up_to= shift;
+    $t->purge( $up_to);
+  }
+
+sub root
+  { return $_[0]->{twig_root}; }
+
+#start-extract twig_document (used to generate XML::(DOM|GDOME)::Twig)
+sub first_elt
+  { my( $t, $cond)= @_;
+    my $root= $t->root || return undef;
+    return $root if( $root->passes( $cond));
+    return $root->next_elt( $cond); 
+  }
+
+sub next_n_elt
+  { my( $t, $offset, $cond)= @_;
+    $offset -- if( $t->root->matches( $cond) );
+    return $t->root->next_n_elt( $offset, $cond);
+  }
+
+sub get_xpath
+  { my $twig= shift;
+    if( isa( $_[0], 'ARRAY'))
+      { my $elt_array= shift;
+        return _unique_elts( map { $_->get_xpath( @_) } @$elt_array);
+      }
+    else
+      { return $twig->root->get_xpath( @_); }
+  }
+
+# get a list of elts and return a sorted list of unique elts
+sub _unique_elts
+  { my @sorted= sort { $a ->cmp( $b) } @_;
+    my @unique;
+    while( my $current= shift @sorted)
+      { push @unique, $current unless( @unique && ($unique[-1] == $current)); }
+    return @unique;
+  }
+
+sub findvalue
+  { my $twig= shift;
+    if( isa( $_[0], 'ARRAY'))
+      { my $elt_array= shift;
+        return join( '', map { $_->findvalue( @_) } @$elt_array);
+      }
+    else
+      { return $twig->root->findvalue( @_); }
+  }
+
+sub set_id_seed
+  { my $t= shift;
+    XML::Twig::Elt->set_id_seed( @_);
+  }
+
+
+# return a list with just the root
+# if a condition is given then return an empty list unless the root matches
+sub children
+  { my( $t, $cond)= @_;
+    my $root= $t->root;
+    unless( $cond && !($root->passes( $cond)) )
+      { return ($root); }
+    else
+      { return (); }
+  }
+
+sub _children
+  { return ($_[0]->root); }
+
+sub descendants
+  { my( $t, $cond)= @_;
+    my $root= $t->root;
+    if( $root->passes( $cond) )
+      { return ($root, $root->descendants( $cond)); }
+    else
+      { return ( $root->descendants( $cond)); }
+  }
+
+sub simplify
+  { my $t= shift;
+    $t->root->simplify( @_);
+  }
+
+sub subs_text
+  { my $t= shift;
+    $t->root->subs_text( @_);
+  }
+
+#end-extract twig_document
+
+sub set_keep_encoding
+  { return XML::Twig::Elt::set_keep_encoding( @_); }
+
+sub set_expand_external_entities
+  { return XML::Twig::Elt::set_expand_external_entities( @_); }
+
+# WARNING: at the moment the id list is not updated reliably
+sub elt_id
+  { return $_[0]->{twig_id_list}->{$_[1]}; }
+
+# change it in ALL twigs at the moment
+sub change_gi 
+  { my( $twig, $old_gi, $new_gi)= @_;
+    my $index;
+    return unless($index= $XML::Twig::gi2index{$old_gi});
+    $XML::Twig::index2gi[$index]= $new_gi;
+    delete $XML::Twig::gi2index{$old_gi};
+    $XML::Twig::gi2index{$new_gi}= $index;
+  }
+
+
+# builds the DTD from the stored (possibly updated) data
+sub dtd_text
+  { my $t= shift;
+    my $dtd= $t->{twig_dtd};
+    my $doctype= $t->{twig_doctype} or return '';
+    my $string= "<!DOCTYPE ".$doctype->{name};
+
+    unless( $parser_version > 3.27) { $string .= " [\n"; }
+
+    foreach my $gi (@{$dtd->{elt_list}})
+      { $string.= "<!ELEMENT $gi ".$dtd->{model}->{$gi}.">\n" ;
+        if( $dtd->{att}->{$gi})
+          { my $attlist= $dtd->{att}->{$gi};
+            $string.= "<!ATTLIST $gi\n";
+            foreach my $att ( sort keys %{$attlist})
+              { $string.= "   $att $attlist->{$att}->{type} ".
+                            "$attlist->{$att}->{default}"; 
+                if( $attlist->{$att}->{fixed})
+                  { $string .= " #FIXED"};
+                $string.= "\n";
+              }
+            $string.= ">\n";
+          }
+      }
+    $string.= $t->entity_list->text if( $t->entity_list);
+    $string.= "\n]>\n";
+    return $string;
+  }
+        
+# prints the DTD from the stored (possibly updated) data
+sub dtd_print
+  { my $t= shift;
+    my $fh=  _is_fh( $_[0])  ? shift : undef;
+    if( $fh) { print $fh $t->dtd_text; }
+    else     { print $t->dtd_text; }
+  }
+
+# build the subs that call directly expat
+BEGIN
+  { my @expat_methods= qw( depth in_element within_element context
+                           current_line current_column current_byte
+                           recognized_string original_string 
+                           xpcroak xpcarp 
+                           xml_escape
+                           base current_element element_index 
+                           position_in_context);
+    foreach my $method (@expat_methods)
+      { no strict 'refs';
+        *{$method}= sub { my $t= shift;
+                          croak "calling $method after parsing is finished" 
+                                 unless( $t->{twig_parsing}); 
+                          return $t->{twig_parser}->$method(@_); 
+                        };
+      }
+  }
+
+sub path
+  { my( $t, $gi)= @_;
+    return "/" . join( "/", ($t->{twig_parser}->context, $gi));
+  }
+
+sub finish
+  { my $t= shift;
+    return $t->{twig_parser}->finish;
+  }
+
+# just finish the parse by printing the rest of the document
+sub finish_print
+  { my( $t, $fh)= @_;
+    my $old_fh;
+    unless( defined $fh)
+      { $t->_set_fh_to_twig_output_fh(); }
+    elsif( defined $fh)
+      { $old_fh= select $fh; 
+        $t->{twig_original_selected_fh}= $old_fh if( $old_fh); 
+      }
+    
+    my $p=$t->{twig_parser};
+    if( $t->{twig_keep_encoding})
+      { $p->setHandlers( %twig_handlers_finish_print); }
+    else
+      { $p->setHandlers( %twig_handlers_finish_print_original); }
+  }
+
+sub output_filter { return XML::Twig::Elt::output_filter( @_); }
+sub set_output_filter { return XML::Twig::Elt::set_output_filter( @_); }
+
+sub output_text_filter { return XML::Twig::Elt::output_text_filter( @_); }
+sub set_output_text_filter { return XML::Twig::Elt::set_output_text_filter( @_); }
+
+sub set_input_filter
+  { my( $t, $input_filter)= @_;
+    my $old_filter= $t->{twig_input_filter};
+      if( !$input_filter || isa( $input_filter, 'CODE') )
+        { $t->{twig_input_filter}= $input_filter; }
+      elsif( $input_filter eq 'latin1')
+        {  $t->{twig_input_filter}= latin1(); }
+      elsif( $filter{$input_filter})
+        {  $t->{twig_input_filter}= $filter{$input_filter}; }
+      else
+        { croak "invalid input filter: $input_filter"; }
+      
+      return $old_filter;
+    }
+
+sub set_empty_tag_style
+  { return XML::Twig::Elt::set_empty_tag_style( @_); }
+
+sub set_pretty_print
+  { return XML::Twig::Elt::set_pretty_print( @_); }
+
+sub set_quote
+  { return XML::Twig::Elt::set_quote( @_); }
+
+sub set_indent
+  { return XML::Twig::Elt::set_indent( @_); }
+
+sub set_keep_atts_order
+  { shift; return XML::Twig::Elt::set_keep_atts_order( @_); }
+
+sub keep_atts_order
+  { return XML::Twig::Elt::keep_atts_order( @_); }
+
+# save and restore package globals (the ones in XML::Twig::Elt)
+sub save_global_state
+  { my $t= shift;
+    $t->{twig_saved_state}= XML::Twig::Elt::global_state();
+  }
+
+sub restore_global_state
+  { my $t= shift;
+    XML::Twig::Elt::set_global_state( $t->{twig_saved_state});
+  }
+
+sub global_state
+  { return XML::Twig::Elt::global_state(); }
+
+sub set_global_state
+  {  return XML::Twig::Elt::set_global_state( $_[1]); }
+
+sub dispose
+  { my $t= shift;
+    $t->DESTROY;
+  }
+  
+sub DESTROY
+  { my $t= shift;
+    if( $t->{twig_root} && isa(  $t->{twig_root}, 'XML::Twig')) 
+      { $t->{twig_root}->delete } 
+
+# added to break circular references
+    undef $t->{twig};
+    undef $t->{twig_root}->{twig} if( $t->{twig_root});
+    undef $t->{twig_parser};
+    
+    $t={}; # prevents memory leaks (especially when using mod_perl)
+    undef $t;
+  }        
+
+
+#
+#  non standard handlers
+#
+
+# kludge: expat 1.95.2 calls both Default AND Doctype handlers
+# so if the default handler finds '<!DOCTYPE' then it must 
+# unset itself (_twig_print_doctype will reset it)
+sub _twig_print_check_doctype
+  { 
+    my $p= shift;
+    my $string= $p->recognized_string();
+    if( $string eq '<!DOCTYPE') 
+      { $p->setHandlers( Default => undef); 
+        $p->{twig}->{expat_1_95_2}=1; 
+      }
+    else                        
+      { print $string; }
+    
+  }
+
+#sub twig_buffer_original
+#  { my $p= shift; 
+#    my $t= $p->{twig};
+#    $t->{twig_buffered_string}= $p->original_string(); 
+#  }
+
+sub _twig_print
+  { print $_[0]->recognized_string(); }
+
+sub _twig_print_default
+  { my( $p, $string)= @_;
+    print $p->recognized_string();
+  }
+
+# recognized_string does not seem to work for entities, go figure!
+# so this handler is not used 
+sub _twig_print_entity
+  { my $p= shift; }
+
+# account for the case where the element is empty
+sub _twig_print_end
+  { my $p= shift; 
+    print $p->recognized_string();
+  }
+
+
+# kludge: expat 1.95.2 calls both Default AND Doctype handlers
+# so if the default handler finds '<!DOCTYPE' then it must 
+# unset itself (_twig_print_doctype will reset it)
+sub _twig_print_original_check_doctype
+  { 
+    my $p= shift;
+    my $string= $p->original_string();
+    if( $string eq '<!DOCTYPE') 
+      { $p->setHandlers( Default => undef); 
+        $p->{twig}->{expat_1_95_2}=1; 
+      }
+    else                        
+      { print $string; }
+    
+  }
+
+sub _twig_print_original
+  { print $_[0]->original_string(); }
+
+
+sub _twig_print_original_doctype
+  { 
+    my(  $p, $name, $sysid, $pubid, $internal)= @_;
+    if( $name)
+      { # with recent versions of XML::Parser original_string does not work,
+        # hence we need to rebuild the doctype declaration
+        my $doctype='';
+        $doctype .= qq{<!DOCTYPE $name}    if( $name);
+        $doctype .=  qq{ PUBLIC  "$pubid"}  if( $pubid);
+        $doctype .=  qq{ SYSTEM}            if( $sysid && !$pubid);
+        $doctype .=  qq{ "$sysid"}          if( $sysid); 
+        $doctype .=  qq{>} unless( $p->{twig}->{expat_1_95_2});
+        print $doctype;
+      }
+    $p->setHandlers( Default => \&_twig_print_original);
+  }
+
+sub _twig_print_doctype
+  { 
+    my(  $p, $name, $sysid, $pubid, $internal)= @_;
+    if( $name)
+      { # with recent versions of XML::Parser original_string does not work,
+        # hence we need to rebuild the doctype declaration
+        my $doctype='';
+        $doctype .= qq{<!DOCTYPE $name}    if( $name);
+        $doctype .=  qq{ PUBLIC  "$pubid"}  if( $pubid);
+        $doctype .=  qq{ SYSTEM}            if( $sysid && !$pubid);
+        $doctype .=  qq{ "$sysid"}          if( $sysid); 
+        $doctype .=  qq{>} unless( $p->{twig}->{expat_1_95_2});
+        print $doctype;
+      }
+    $p->setHandlers( Default => \&_twig_print_original);
+  }
+
+
+
+
+sub _twig_print_original_default
+  { 
+    my $p= shift;
+    print $p->original_string();
+  }
+
+# account for the case where the element is empty
+sub _twig_print_end_original
+  { my $p= shift;
+    print $p->original_string();
+  }
+
+sub _twig_start_check_roots
+  { 
+    my( $p, $gi, %att)= @_;
+    my $t= $p->{twig};
+
+    if( _handler( $t, $t->{twig_roots}, $gi, \%att))
+      { 
+        $p->setHandlers( %twig_handlers); # restore regular handlers
+        $t->{twig_root_depth}= $p->depth; 
+        _twig_start( $p, $gi, %att);
+      }
+    elsif( $p->depth == 0)
+      { _twig_start( $p, $gi, %att); }
+    elsif( $t->{twig_starttag_handlers})
+      { # look for start tag handlers
+        my @handlers= _handler( $t, $t->{twig_starttag_handlers}, $gi, \%att);
+        foreach my $handler ( @handlers)
+          { $handler->($t, $gi, %att) || last; }
+      }
+  }
+
+sub _twig_start_check_roots_print
+  { 
+    my( $p, $gi, %att)= @_;
+    my $t= $p->{twig};
+
+    if( _handler( $t, $t->{twig_roots}, $gi, \%att))
+      { $p->setHandlers( %twig_handlers); # restore regular handlers
+        $t->_set_fh_to_selected_fh();      # select the proper output fh
+        $t->{twig_root_depth}= $p->depth; 
+        _twig_start( $p, $gi, %att);
+      }
+    elsif( $p->depth == 0)
+      { if( my $fh= $t->{twig_output_fh})
+          { print $fh $p->recognized_string(); }
+        else
+          { print $p->recognized_string(); }
+      
+        _twig_start( $p, $gi, %att);
+        $t->_set_fh_to_twig_output_fh();
+      }
+    elsif( $t->{twig_starttag_handlers})
+      { # look for start tag handlers
+        my @handlers= _handler( $t, $t->{twig_starttag_handlers}, $gi, \%att);
+        my $last_handler_res;
+        $t->_set_fh_to_selected_fh() if( @handlers);     # select the proper output fh
+        foreach my $handler ( @handlers)
+          { $last_handler_res= $handler->($t, $gi, %att);
+            last unless $last_handler_res;
+          }
+        $t->_set_fh_to_twig_output_fh() if( @handlers);  # re-select the twig output fh
+        print $p->recognized_string() if( !@handlers || $last_handler_res);   
+      }
+    else
+      { print $p->recognized_string(); }  
+  }
+
+sub _twig_start_check_roots_print_original
+  { 
+    my( $p, $gi, %att)= @_;
+    my $t= $p->{twig};
+
+    if( _handler( $t, $t->{twig_roots}, $gi, \%att))
+      { $p->setHandlers( %twig_handlers); # restore regular handlers
+        $t->_set_fh_to_selected_fh();      # select the proper output fh
+        $t->{twig_root_depth}= $p->depth; 
+        _twig_start( $p, $gi, %att);
+      }
+    elsif( $p->depth == 0)
+      { if( my $fh= $t->{twig_output_fh})
+          { print $fh $p->original_string(); }
+        else
+          { print $p->original_string(); }
+
+        _twig_start( $p, $gi, %att);
+        $t->_set_fh_to_twig_output_fh();
+      }
+    elsif( $t->{twig_starttag_handlers})
+      { # look for start tag handlers
+        my @handlers= _handler( $t, $t->{twig_starttag_handlers}, $gi, \%att);
+        my $last_handler_res;
+        $t->_set_fh_to_selected_fh() if( @handlers);     # select the proper output fh
+        foreach my $handler ( @handlers)
+          { $last_handler_res= $handler->($t, $gi, %att);
+            last unless( $last_handler_res);
+          }
+        $t->_set_fh_to_twig_output_fh() if( @handlers);  # re-select the twig output fh
+        print $p->original_string() if( !@handlers || $last_handler_res);   
+      }
+    else
+      { print $p->original_string(); }
+  }
+
+sub _twig_end_check_roots
+  { 
+    my( $p, $gi)= @_;
+    my $t= $p->{twig};
+    if( $t->{twig_endtag_handlers})
+      { # look for end tag handlers
+        my @handlers= _handler( $t, $t->{twig_endtag_handlers}, $gi, {});
+        my $last_handler_res=1;
+        foreach my $handler ( @handlers)
+          { $last_handler_res= $handler->($t, $gi) || last; }
+      }
+
+    if( $p->depth == 0)
+      { _twig_end( $p, $gi); }
+  }
+
+sub _twig_end_check_roots_print
+  { 
+    my( $p, $gi, %att)= @_;
+    my $t= $p->{twig};
+    if( $t->{twig_endtag_handlers})
+      { # look for start tag handlers
+        my @handlers= _handler( $t, $t->{twig_endtag_handlers}, $gi, {});
+        my $last_handler_res=1;
+        $t->_set_fh_to_selected_fh() if( @handlers);     # select the proper output fh
+        foreach my $handler ( @handlers)
+          { $last_handler_res= $handler->($t, $gi) || last; }
+        $t->_set_fh_to_twig_output_fh() if( @handlers);  # re-select the twig output fh
+        return unless $last_handler_res;
+      }
+    print $p->recognized_string();  
+    $t->_set_fh_to_selected_fh() if( $p->depth == 0);
+    if( $p->depth == 0)
+      { _twig_end( $p, $gi);  }
+  }
+
+sub _twig_end_check_roots_print_original
+  { 
+    my( $p, $gi, %att)= @_;
+    my $t= $p->{twig};
+    if( $t->{twig_endtag_handlers})
+      { # look for start tag handlers
+        my @handlers= _handler( $t, $t->{twig_endtag_handlers}, $gi, {});
+        my $last_handler_res=1;
+        $t->_set_fh_to_selected_fh() if( @handlers);     # select the proper output fh
+        foreach my $handler ( @handlers)
+          { $last_handler_res= $handler->($t, $gi) || last; }
+        $t->_set_fh_to_twig_output_fh() if( @handlers);  # re-select the twig output fh
+        return unless $last_handler_res;
+      }
+    print $p->original_string();
+    $t->_set_fh_to_selected_fh() if( $p->depth == 0);
+    if( $p->depth == 0)
+      { _twig_end( $p, $gi);  }
+  }
+
+sub _twig_pi_check_roots
+  { my( $p, $target, $data)= @_;
+    my $t= $p->{twig};
+    if( my $handler=    $t->{twig_handlers}->{pi_handlers}->{$target}
+                     || $t->{twig_handlers}->{pi_handlers}->{''}
+      )
+      { _twig_pi( @_); }
+  }
+
+
+sub _twig_ignore_start
+  { 
+    my( $p, $gi)= @_;
+    my $t= $p->{twig};
+    return unless( $gi eq $t->{twig_ignore_gi});
+    $t->{twig_ignore_level}++;
+    my $action= $t->{twig_ignore_action};
+    if( $action eq 'print' )
+      { _twig_print_original( @_); }
+#    elsif( $action eq 'string' )
+#      { $t->{twig_buffered_string} .= $p->original_string(); }
+  }
+
+sub _twig_ignore_end
+  { 
+    my( $p, $gi)= @_;
+    my $t= $p->{twig};
+
+    my $action= $t->{twig_ignore_action};
+
+    if( $action eq 'print')
+      { _twig_print_original( $p, $gi); }
+#    elsif( $action eq 'string')
+#      { $t->{twig_buffered_string} .= $p->original_string(); }
+
+    return unless( $gi eq $t->{twig_ignore_gi});
+
+    $t->{twig_ignore_level}--;
+
+    unless( $t->{twig_ignore_level})
+      { $t->{twig_ignore_elt}->delete; 
+        $p->setHandlers( @{$t->{twig_saved_handlers}});
+        # test for handlers
+        if( $t->{twig_endtag_handlers})
+          { # look for end tag handlers
+            my @handlers= _handler( $t, $t->{twig_endtag_handlers}, $gi, {});
+            my $last_handler_res=1;
+            foreach my $handler ( @handlers)
+              { $last_handler_res= $handler->($t, $gi) || last; }
+          }
+      };
+  }
+    
+sub ignore
+  { my $t= shift;
+    my $elt;
+
+    # get the element (default: current elt)
+    if( $_[0] && isa( $_[0], 'XML::Twig::Elt'))
+      { $elt= shift; }
+    else
+      { $elt = $t->{twig_current}; }
+
+    my $action= shift || 1; 
+    $t->{twig_ignore_action}= $action;
+
+    $t->{twig_ignore_elt}= $elt;     # save it
+    $t->{twig_ignore_gi}= $XML::Twig::index2gi[$elt->{'gi'}];  # save its gi
+    $t->{twig_ignore_level}++;
+    my $p= $t->{twig_parser};
+    my @saved_handlers= $p->setHandlers( %twig_handlers_ignore); # set handlers
+    if( $action eq 'print')
+      { $p->setHandlers( Default => \&_twig_print_original); }
+#    elsif( $action eq 'string')
+#      { # not used at the moment
+#        $t->{twig_buffered_string}='';
+#        $p->setHandlers( Default => \&twig_buffer_original);
+#      }
+
+    $t->{twig_saved_handlers}= \@saved_handlers;        # save current handlers
+  }
+
+# select $t->{twig_output_fh} and store the current selected fh 
+sub _set_fh_to_twig_output_fh
+  { my $t= shift;
+    my $output_fh= $t->{twig_output_fh};
+    if( $output_fh && !$t->{twig_output_fh_selected})
+      { # there is an output fh
+        $t->{twig_selected_fh}= select(); # store the currently selected fh
+        $t->{twig_output_fh_selected}=1;
+        select $output_fh;                # select the output fh for the twig
+      }
+  }
+
+# select the fh that was stored in $t->{twig_selected_fh} 
+# (before $t->{twig_output_fh} was selected)
+sub _set_fh_to_selected_fh
+  { my $t= shift;
+    return unless( $t->{twig_output_fh});
+    my $selected_fh= $t->{twig_selected_fh};
+    $t->{twig_output_fh_selected}=0;
+    select $selected_fh;
+    return;
+  }
+  
+
+sub encoding
+  { return $_[0]->{twig_xmldecl}->{encoding} if( $_[0]->{twig_xmldecl}); }
+
+sub set_encoding
+  { my( $t, $encoding)= @_;
+    $t->{twig_xmldecl} ||={};
+    $t->set_xml_version( "1.0") unless( $t->xml_version);
+    $t->{twig_xmldecl}->{encoding}= $encoding;
+    return $t;
+  }
+
+sub output_encoding
+  { return $_[0]->{output_encoding}; }
+  
+sub set_output_encoding
+  { my( $t, $encoding)= @_;
+    $t->set_output_filter( _encoding_filter( $encoding)) if( $encoding);
+    return $t->{output_encoding}= $encoding;
+  }
+
+sub xml_version
+  { return $_[0]->{twig_xmldecl}->{version} if( $_[0]->{twig_xmldecl}); }
+
+sub set_xml_version
+  { my( $t, $version)= @_;
+    $t->{twig_xmldecl} ||={};
+    return $t->{twig_xmldecl}->{version}= $version;
+  }
+
+sub standalone
+  { return $_[0]->{twig_xmldecl}->{standalone} if( $_[0]->{twig_xmldecl}); }
+
+sub set_standalone
+  { my( $t, $standalone)= @_;
+    $t->{twig_xmldecl} ||={};
+    $t->set_xml_version( "1.0") unless( $t->xml_version);
+    return $t->{twig_xmldecl}->{standalone}= $standalone;
+  }
+
+
+# SAX methods
+
+sub toSAX1
+  { croak "cannot use toSAX1 while parsing (use flush_toSAX1)" if (defined $_[0]->{twig_parser});
+    shift(@_)->_toSAX(@_, \&XML::Twig::Elt::_start_tag_data_SAX1,
+                          \&XML::Twig::Elt::_end_tag_data_SAX1
+             ); }
+
+sub toSAX2
+  { croak "cannot use toSAX2 while parsing (use flush_toSAX2)" if (defined $_[0]->{twig_parser});
+    shift(@_)->_toSAX(@_, \&XML::Twig::Elt::_start_tag_data_SAX2,
+                          \&XML::Twig::Elt::_end_tag_data_SAX2
+             ); }
+
+
+sub _toSAX
+  { my( $t, $handler, $start_tag_data, $end_tag_data) = @_;
+
+    if( my $start_document =  $handler->can( 'start_document'))
+      { $start_document->( $handler); }
+    
+    $t->_prolog_toSAX( $handler);
+    
+    $t->root->_toSAX( $handler, $start_tag_data, $end_tag_data)  if( $t->root);
+    if( my $end_document =  $handler->can( 'end_document'))
+      { $end_document->( $handler); }
+  }
+
+
+sub flush_toSAX1
+  { shift(@_)->_flush_toSAX(@_, \&XML::Twig::Elt::_start_tag_data_SAX1,
+                               \&XML::Twig::Elt::_end_tag_data_SAX1
+             ); }
+
+sub flush_toSAX2
+  { shift(@_)->_flush_toSAX(@_, \&XML::Twig::Elt::_start_tag_data_SAX2,
+                               \&XML::Twig::Elt::_end_tag_data_SAX2
+             ); }
+
+sub _flush_toSAX
+  { my( $t, $handler, $start_tag_data, $end_tag_data, $up_to)= @_;
+
+    # the "real" last element processed, as _twig_end has closed it
+    my $last_elt;
+    if( $up_to)
+      { $last_elt= $up_to; }
+    elsif( $t->{twig_current})
+      { $last_elt= $t->{twig_current}->_last_child; }
+    else
+      { $last_elt= $t->{twig_root}; }
+
+    my $elt= $t->{twig_root};
+    unless( $elt->_flushed)
+      { # init unless already done (ie root has been flushed)
+        if( my $start_document =  $handler->can( 'start_document'))
+          { $start_document->( $handler); }
+        # flush the DTD
+        $t->_prolog_toSAX( $handler) 
+      }
+
+    while( $elt)
+      { my $next_elt; 
+        if( $last_elt && $last_elt->in( $elt))
+          { 
+            unless( $elt->_flushed) 
+              { # just output the front tag
+                if( my $start_element = $handler->can( 'start_element'))
+                 { if( my $tag_data= $start_tag_data->( $elt))
+                     { $start_element->( $handler, $tag_data); }
+                 }
+                $elt->_set_flushed;
+              }
+            $next_elt= $elt->{first_child};
+          }
+        else
+          { # an element before the last one or the last one,
+            $next_elt= $elt->{next_sibling};  
+            $elt->_toSAX( $handler, $start_tag_data, $end_tag_data);
+            $elt->delete; 
+            last if( $last_elt && ($elt == $last_elt));
+          }
+        $elt= $next_elt;
+      }
+    if( !$t->{twig_parsing}) 
+      { if( my $end_document =  $handler->can( 'end_document'))
+          { $end_document->( $handler); }
+      }
+  }
+
+
+sub _prolog_toSAX
+  { my( $t, $handler)= @_;
+    $t->_xmldecl_toSAX( $handler);
+    $t->_DTD_toSAX( $handler);
+  }
+
+sub _xmldecl_toSAX
+  { my( $t, $handler)= @_;
+    my $decl= $t->{twig_xmldecl};
+    my $data= { Version    => $decl->{version},
+                Encoding   => $decl->{encoding},
+                Standalone => $decl->{standalone},
+          };
+    if( my $xml_decl= $handler->can( 'xml_decl'))
+      { $xml_decl->( $handler, $data); }
+  }
+                
+sub _DTD_toSAX
+  { my( $t, $handler)= @_;
+    my $doctype= $t->{twig_doctype};
+    return unless( $doctype);
+    my $data= { Name     => $doctype->{name},
+                PublicId => $doctype->{pub},
+                SystemId => $doctype->{sysid},
+              };
+
+    if( my $start_dtd= $handler->can( 'start_dtd'))
+      { $start_dtd->( $handler, $data); }
+
+    # I should call code to export the internal subset here 
+    
+    if( my $end_dtd= $handler->can( 'end_dtd'))
+      { $end_dtd->( $handler); }
+  }
+
+# input/output filters
+
+sub latin1 
+  { local $SIG{__DIE__};
+    if( eval 'require Encode')
+      { import Encode; 
+        return encode_convert( 'ISO-8859-15');
+      }
+    elsif( eval 'require Text::Iconv;')
+      { 
+        return iconv_convert( 'ISO-8859-15');
+      }
+    elsif( eval 'require Unicode::Map8 && require Unicode::String;')
+      { 
+        return unicode_convert( 'ISO-8859-15'); 
+      }
+    else
+      { return \&regexp2latin1; }
+  }
+
+sub _encoding_filter
+  { 
+      { local $SIG{__DIE__};
+        my $encoding= $_[1] || $_[0];
+        if( eval 'require Encode')
+          { import Encode; 
+            my $sub= encode_convert( $encoding);
+            return $sub;
+          }
+        if( eval 'require Text::Iconv;')
+          { return iconv_convert( $encoding); }
+        elsif( eval 'require Unicode::Map8 && require Unicode::String;')
+          { return unicode_convert( $encoding); }
+        }
+    croak "Encode, Text::Iconv or Unicode::Map8 and Unicode::String need to be installed ",
+          "in order to use encoding options";
+  }
+
+# shamelessly lifted from XML::TyePYX (works only with XML::Parse 2.27)
+sub regexp2latin1
+  { my $text=shift;
+    $text=~s{([\xc0-\xc3])(.)}{ my $hi = ord($1);
+                                my $lo = ord($2);
+                                chr((($hi & 0x03) <<6) | ($lo & 0x3F))
+                              }ge;
+    return $text;
+  }
+
+
+sub html_encode
+  { require HTML::Entities;
+    return HTML::Entities::encode_entities($_[0] );
+  }
+
+sub safe_encode
+  {   my $str= shift;
+      if( $] < 5.008)
+        { $str =~ s{([\xC0-\xDF].|[\xE0-\xEF]..|[\xF0-\xFF]...)}
+                   {_XmlUtf8Decode($1)}egs; 
+        }
+      else
+        { $str= encode( ascii => $str, $FB_HTMLCREF); }
+      return $str;
+  }
+
+sub safe_encode_hex
+  {   my $str= shift;
+      if( $] < 5.008)
+        { $str =~ s{([\xC0-\xDF].|[\xE0-\xEF]..|[\xF0-\xFF]...)}
+                   {_XmlUtf8Decode($1, 1)}egs; 
+        }
+      else
+        { $str= encode( ascii => $str, $FB_XMLCREF); }
+      return $str;
+  }
+
+# this one shamelessly lifted from XML::DOM
+# does NOT work on 5.8.0
+sub _XmlUtf8Decode
+  { my ($str, $hex) = @_;
+    my $len = length ($str);
+    my $n;
+
+    if ($len == 2)
+      { my @n = unpack "C2", $str;
+        $n = (($n[0] & 0x3f) << 6) + ($n[1] & 0x3f);
+      }
+    elsif ($len == 3)
+      { my @n = unpack "C3", $str;
+        $n = (($n[0] & 0x1f) << 12) + (($n[1] & 0x3f) << 6) + ($n[2] & 0x3f);
+      }
+    elsif ($len == 4)
+      { my @n = unpack "C4", $str;
+        $n = (($n[0] & 0x0f) << 18) + (($n[1] & 0x3f) << 12) 
+           + (($n[2] & 0x3f) << 6) + ($n[3] & 0x3f);
+      }
+    elsif ($len == 1)    # just to be complete...
+      { $n = ord ($str); }
+    else
+      { croak "bad value [$str] for _XmlUtf8Decode"; }
+
+    my $char= $hex ? sprintf ("&#x%x;", $n) : "&#$n;";
+    return $char;
+}
+
+
+sub unicode_convert
+  { my $enc= $_[1] ? $_[1] : $_[0]; # so the method can be called on the twig or directly
+    require Unicode::Map8;
+    require Unicode::String;
+    import Unicode::String qw(utf8);
+    my $sub= eval q{
+            { my $cnv;
+              BEGIN {  $cnv= Unicode::Map8->new($enc) 
+                           or croak "Can't create converter to $enc";
+                    }
+              sub { return  $cnv->to8 (utf8($_[0])->ucs2); } 
+            } 
+                   };
+    unless( $sub) { croak $@; }
+    return $sub;
+  }
+
+sub iconv_convert
+  { my $enc= $_[1] ? $_[1] : $_[0]; # so the method can be called on the twig or directly
+    require Text::Iconv;
+    my $sub= eval q{
+            { my $cnv;
+              BEGIN { $cnv = Text::Iconv->new( 'utf8', $enc) 
+                           or croak "Can't create iconv converter to $enc";
+                    }
+              sub { return  $cnv->convert( $_[0]); } 
+            }       
+                   };
+    unless( $sub)
+      { if( $@=~ m{^Unsupported conversion: Invalid argument})
+          { croak "Unsupported encoding: $enc"; }
+        else
+          { croak $@; }
+      }
+
+    return $sub;
+  }
+
+sub encode_convert
+  { my $enc= $_[1] ? $_[1] : $_[0]; # so the method can be called on the twig or directly
+    my $sub=  eval qq{sub { return encode( "$enc", \$_[0]); } };
+    croak "can't create Encode-based filter: $@" unless( $sub);
+    return $sub;
+  }
+
+
+# XML::XPath compatibility
+sub getRootNode        { return $_[0]; }
+sub getParentNode      { return undef; }
+sub getChildNodes      { my @children= ($_[0]->root); return wantarray ? @children : \@children; }
+
+
+1;
+
+######################################################################
+package XML::Twig::Entity_list;
+######################################################################
+use UNIVERSAL qw( isa ) ;
+
+sub new
+  { my $class = shift;
+    my $self={};
+
+    bless $self, $class;
+    return $self;
+
+  }
+
+sub add_new_ent
+  { my $list= shift;
+    my $ent= XML::Twig::Entity->new( @_);
+    $list->add( $ent);
+  }
+
+sub add
+  { my( $list, $ent)= @_;
+    $list->{$ent->{name}}= $ent;
+  }
+
+# can be called with an entity or with an entity name
+sub delete
+  { my $list= shift;
+    if( isa( ref $_[0], 'XML::Twig::Entity'))
+      { # the second arg is an entity
+        my $ent= shift;
+        delete $list->{$ent->{name}};
+      }
+    else
+      { # the second arg was not entity, must be a string then
+        my $name= shift;
+        delete $list->{$name};
+      }
+  }
+
+sub print
+  { my ($ent_list, $fh)= @_;
+    my $old_select= defined $fh ? select $fh : undef;
+
+    foreach my $ent_name ( sort keys %{$ent_list})
+      { my $ent= $ent_list->{$ent_name};
+        # we have to test what the entity is or un-defined entities can creep in
+        $ent->print() if( isa( $ent, 'XML::Twig::Entity'));
+      }
+    select $old_select if( defined $old_select);
+  }
+
+sub text
+  { my ($ent_list)= @_;
+    return join "\n", map { $ent_list->{$_}->text} sort keys %{$ent_list};
+  }
+
+sub list
+  { my ($ent_list)= @_;
+    return map { $ent_list->{$_} } sort keys %$ent_list;
+  }
+
+1;
+
+######################################################################
+package XML::Twig::Entity;
+######################################################################
+use UNIVERSAL qw( isa ) ;
+
+sub new
+  { my( $ent, $name, $val, $sysid, $pubid, $ndata)= @_;
+
+    my $self={};
+
+    $self->{name}= $name;
+    if( $val)
+      { $self->{val}= $val; }
+    else
+      { $self->{sysid}= $sysid;
+        $self->{pubid}= $pubid;
+        $self->{ndata}= $ndata;
+      }
+    bless $self;
+    return $self;
+  }
+
+sub name  { return $_[0]->{name}; }
+sub val   { return $_[0]->{val}; }
+sub sysid { return $_[0]->{sysid}; }
+sub pubid { return $_[0]->{pubid}; }
+sub ndata { return $_[0]->{ndata}; }
+
+sub print
+  { my ($ent, $fh)= @_;
+    if( $fh) { print $fh $ent->text . "\n"; }
+    else     { print $ent->text . "\n"; }
+  }
+
+
+sub text
+  { my ($ent)= @_;
+    if( exists $ent->{'val'})
+      { if( $ent->{'val'}=~ /"/)
+          { return "<!ENTITY $ent->{'name'} '$ent->{'val'}'>"; }
+        return "<!ENTITY $ent->{'name'} \"$ent->{'val'}\">";
+      }
+    elsif( $ent->{'sysid'})
+      { my $text= "<!ENTITY $ent->{'name'} ";
+        $text .= "SYSTEM \"$ent->{'sysid'}\" " if( $ent->{'sysid'});
+        $text .= "PUBLIC \"$ent->{'pubid'}\" " if( $ent->{'pubid'});
+        $text .= "NDATA $ent->{'ndata'}"        if( $ent->{'ndata'});
+        $text .= ">";
+        return $text;
+      }
+  }
+
+                
+1;
+
+######################################################################
+package XML::Twig::Elt;
+######################################################################
+use Carp;
+use UNIVERSAL qw( isa ) ;
+
+use constant  PCDATA  => '#PCDATA'; 
+use constant  CDATA   => '#CDATA'; 
+use constant  PI      => '#PI'; 
+use constant  COMMENT => '#COMMENT'; 
+use constant  ENT     => '#ENT'; 
+
+use constant  ASIS    => '#ASIS';    # pcdata elements not to be XML-escaped
+
+use constant  ELT     => '#ELT'; 
+use constant  TEXT    => '#TEXT'; 
+use constant  EMPTY   => '#EMPTY'; 
+
+use constant CDATA_START    => "<![CDATA[";
+use constant CDATA_END      => "]]>";
+use constant PI_START       => "<?";
+use constant PI_END         => "?>";
+use constant COMMENT_START  => "<!--";
+use constant COMMENT_END    => "-->";
+
+use constant XMLNS_URI      => 'http://www.w3.org/2000/xmlns/';
+my $XMLNS_URI               = XMLNS_URI;
+
+
+BEGIN
+  { # set some aliases for methods
+    *tag           = *gi; 
+    *name          = *gi; 
+    *set_tag       = *set_gi; 
+    *set_name      = *set_gi; 
+    *find_nodes    = *get_xpath; # as in XML::DOM
+    *findnodes     = *get_xpath; # as in XML::LibXML
+    *field         = *first_child_text;
+    *trimmed_field = *first_child_trimmed_text;
+    *is_field      = *contains_only_text;
+    *is            = *passes;
+    *matches       = *passes;
+    *has_child     = *first_child;
+    *has_children  = *first_child;
+    *all_children_pass = *all_children_are;
+    *all_children_match= *all_children_are;
+    *getElementsByTagName= *descendants;
+    *find_by_tag_name= *descendants_or_self;
+  
+    *first_child_is  = *first_child_matches;
+    *last_child_is   = *last_child_matches;
+    *next_sibling_is = *next_sibling_matches;
+    *prev_sibling_is = *prev_sibling_matches;
+    *next_elt_is     = *next_elt_matches;
+    *prev_elt_is     = *prev_elt_matches;
+    *parent_is       = *parent_matches;
+    *child_is        = *child_matches;
+
+    *sort_children_by_value= *sort_children_on_value;
+
+    *has_atts= *att_nb;
+
+    # imports from XML::Twig
+    *_is_fh= *XML::Twig::_is_fh;
+
+    # XML::XPath compatibility
+    *string_value       = *text;
+    *toString           = *sprint;
+    *getName            = *gi;
+    *getRootNode        = *twig;  
+    *getNextSibling     = *_next_sibling;
+    *getPreviousSibling = *_prev_sibling;
+    *isElementNode      = *is_elt;
+    *isTextNode         = *is_text;
+    *isPI               = *is_pi;
+    *isPINode           = *is_pi;
+    *isProcessingInstructionNode= *is_pi;
+    *isComment          = *is_comment;
+    *isCommentNode      = *is_comment;
+    *getTarget          = *target;
+
+    # try using weak references
+    # test whether we can use weak references
+    { local $SIG{__DIE__};
+      if( eval 'require Scalar::Util')
+        { import Scalar::Util qw(weaken); }
+      elsif( eval 'require WeakRef')
+        { import WeakRef; }
+    }
+}
+
+ 
+# can be called as XML::Twig::Elt->new( [[$gi, $atts, [@content]])
+# - gi is an optional gi given to the element
+# - $atts is a hashref to attributes for the element
+# - @content is an optional list of text and elements that will
+#   be inserted under the element 
+sub new 
+  { my $class= shift;
+    $class= ref $class || $class;
+    my $elt  = {};
+    bless ($elt, $class);
+
+    return $elt unless @_;
+
+    # if a gi is passed then use it
+    my $gi= shift;
+    $elt->set_gi( $gi);
+
+
+    my $atts= ref $_[0] eq 'HASH' ? shift : undef;
+
+    if( $gi eq PCDATA)
+      { $elt->{pcdata}=  shift; }
+    elsif( $gi eq ENT)
+      { $elt->{ent}=  shift; }
+    elsif( $gi eq CDATA)
+      { $elt->{cdata}=  shift; }
+    elsif( $gi eq COMMENT)
+      { $elt->{comment}=  shift; }
+    elsif( $gi eq PI)
+      { $elt->set_pi( shift, shift); }
+    else
+      { # the rest of the arguments are the content of the element
+        if( @_)
+          { $elt->set_content( @_); }
+        else
+          { $elt->{empty}=  1;    }
+      }
+
+    if( $atts)
+      { # the attribute hash can be used to pass the asis status 
+        if( defined $atts->{'#ASIS'})  { $elt->set_asis(  $atts->{'#ASIS'} ); delete $atts->{'#ASIS'};  }
+        if( defined $atts->{'#EMPTY'}) { $elt->{empty}=  $atts->{'#EMPTY'}; delete $atts->{'#EMPTY'}; }
+        $elt->set_atts( $atts) if( keys %$atts);
+      }
+
+    return $elt;
+  }
+
+# this function creates an XM:::Twig::Elt from a string
+# it is quite clumsy at the moment, as it just creates a
+# new twig then returns its root
+# there might also be memory leaks there
+# additional arguments are passed to new XML::Twig
+sub parse
+  { my $class= shift;
+    my $string= shift;
+    my %args= @_;
+    my $t= XML::Twig->new(%args);
+    $t->parse( $string);
+    my $elt= $t->root;
+    # clean-up the node 
+    delete $elt->{twig};         # get rid of the twig data
+    delete $elt->{twig_current}; # better get rid of this too
+    return $elt;
+  }
+    
+
+sub set_gi 
+  { my ($elt, $gi)= @_;
+    unless( defined $XML::Twig::gi2index{$gi})
+      { # new gi, create entries in %gi2index and @index2gi
+        push  @XML::Twig::index2gi, $gi;
+        $XML::Twig::gi2index{$gi}= $#XML::Twig::index2gi;
+      }
+    $elt->{gi}= $XML::Twig::gi2index{$gi};
+    return $elt; 
+  }
+
+sub gi  { return $XML::Twig::index2gi[$_[0]->{gi}]; }
+
+sub local_name 
+  { my $elt= shift;
+    return _local_name( $XML::Twig::index2gi[$elt->{'gi'}]);
+  }
+
+sub ns_prefix
+  { my $elt= shift;
+    return _ns_prefix( $XML::Twig::index2gi[$elt->{'gi'}]);
+  }
+
+# namespace prefix for any qname (can be used for elements or attributes)
+sub _ns_prefix
+  { my $qname= shift;
+    if( $qname=~ m{^([^:]*):})
+      { return $1; }
+    else
+      { return( ''); } # should it be '' ?
+  }
+
+# local name for any qname (can be used for elements or attributes)
+sub _local_name
+  { my $qname= shift;
+    (my $local= $qname)=~ s{^[^:]*:}{};
+    return $local;
+  }
+
+BEGIN 
+  { my %DEFAULT_NS= ( xml   => "http://www.w3.org/XML/1998/namespace",
+                      xmlns => "http://www.w3.org/2000/xmlns/",
+                    );
+ 
+    #sub get_namespace
+    sub namespace
+      { my $elt= shift;
+        my $prefix= defined $_[0] ? shift() : $elt->ns_prefix;
+        my $ns_att= $prefix ? "xmlns:$prefix" : "xmlns";
+        my $expanded= $DEFAULT_NS{$prefix} || $elt->inherit_att( $ns_att) || '';
+        return $expanded;
+      }
+  }
+
+
+# return #ELT for an element and #PCDATA... for others
+sub get_type
+  { my $gi_nb= $_[0]->{gi}; # the number, not the string
+    return ELT if( $gi_nb >= $XML::Twig::SPECIAL_GI);
+    return $_[0]->gi;
+  }
+
+# return the gi if it's a "real" element, 0 otherwise
+sub is_elt
+  { return $_[0]->gi if(  $_[0]->{gi} >=  $XML::Twig::SPECIAL_GI);
+    return 0;
+  }
+
+
+sub is_pcdata
+  { my $elt= shift;
+    return (exists $elt->{'pcdata'});
+  }
+
+sub is_cdata
+  { my $elt= shift;
+    return (exists $elt->{'cdata'});
+  }
+
+sub is_pi
+  { my $elt= shift;
+    return (exists $elt->{'target'});
+  }
+
+sub is_comment
+  { my $elt= shift;
+    return (exists $elt->{'comment'});
+  }
+
+sub is_ent
+  { my $elt= shift;
+    return (exists $elt->{ent} || $elt->{ent_name});
+  }
+
+
+sub is_text
+  { my $elt= shift;
+    return (exists( $elt->{'pcdata'}) || (exists $elt->{'cdata'}));
+  }
+
+sub is_empty
+  { return $_[0]->{empty} || 0; }
+
+sub set_empty
+  { $_[0]->{empty}= defined( $_[1]) ? $_[1] : 1; return $_[0]; }
+
+sub set_not_empty
+  { delete $_[0]->{empty} if( ($_[0]->{'empty'} || 0)); return $_[0]; }
+
+
+sub set_asis
+  { my $elt=shift;
+
+    foreach my $descendant ($elt, $elt->_descendants )
+      { $descendant->{asis}= 1;
+        if( (exists $descendant->{'cdata'}))
+          { $descendant->set_gi( PCDATA);
+            $descendant->{pcdata}=  $descendant->{cdata};
+          }
+
+      }
+    return $elt;
+  }
+
+sub set_not_asis
+  { my $elt=shift;
+    foreach my $descendant ($elt, $elt->descendants)
+      { delete $descendant->{asis} if $descendant->{asis};}
+    return $elt;
+  }
+
+sub is_asis
+  { return $_[0]->{asis}; }
+
+sub closed 
+  { my $elt= shift;
+    my $t= $elt->twig || return;
+    my $curr_elt= $t->{twig_current};
+    return unless( $curr_elt);
+    return $curr_elt->in( $elt);
+  }
+
+sub set_pcdata 
+  { delete $_[0]->{empty};
+    $_[0]->{'pcdata'}= $_[1];
+    return $_[0]; 
+  }
+
+sub append_pcdata
+  { delete $_[0]->{empty};
+    $_[0]->{'pcdata'}.= $_[1];
+    return $_[0]; 
+  }
+
+sub pcdata        { return $_[0]->{pcdata}; }
+
+
+sub append_extra_data 
+  {  $_[0]->{extra_data}.= $_[1];
+     return $_[0]; 
+  }
+sub set_extra_data 
+  { $_[0]->{extra_data}= $_[1];
+    return $_[0]; 
+  }
+sub extra_data { return $_[0]->{extra_data}; }
+
+sub set_target 
+  { $_[0]->{'target'}= $_[1];
+    return $_[0]; 
+     
+  }
+sub target { return $_[0]->{target}; }
+
+sub set_data 
+  { $_[0]->{'data'}= $_[1]; 
+    return $_[0];
+  }
+sub data { return $_[0]->{data}; }
+
+sub set_pi
+  { $_[0]->{target}=  $_[1];
+    $_[0]->{data}=  $_[2];
+    return $_[0]; 
+  }
+
+sub pi_string { return PI_START . $_[0]->{target} . " " . $_[0]->{data} . PI_END; }
+
+sub set_comment    { $_[0]->{comment}= $_[1]; return $_[0]; }
+sub comment        { return $_[0]->{comment}; }
+sub comment_string { return COMMENT_START . $_[0]->{comment} . COMMENT_END; }
+
+sub set_ent  { $_[0]->{ent}= $_[1]; return $_[0]; }
+sub ent      { return $_[0]->{ent}; }
+sub ent_name { return substr( $_[0]->{ent}, 1, -1);}
+
+sub set_cdata 
+  { delete $_[0]->{empty};
+    $_[0]->{'cdata'}= $_[1]; 
+    return $_[0];
+  }
+
+sub append_cdata
+  { $_[0]->{'cdata'}.= $_[1]; 
+    return $_[0];
+  }
+sub cdata { return $_[0]->{'cdata'}; }
+sub cdata_string
+  { my $cdata= $_[0]->{cdata};
+    return defined $cdata ? CDATA_START . $cdata . CDATA_END : '';
+  }
+
+#start-extract twig_node
+sub contains_only_text
+  { my $elt= shift;
+    return 0 unless $elt->is_elt;
+    foreach my $child ($elt->children)
+      { return 0 if $child->is_elt; }
+    return $elt;
+  } 
+  
+sub contains_only
+  { my( $elt, $exp)= @_;
+    my @children= $elt->children;
+    foreach my $child (@children)
+      { return 0 unless $child->is( $exp); }
+    return @children;
+  } 
+
+sub contains_a_single
+  { my( $elt, $exp)= @_;
+    my $child= $elt->{first_child} or return 0;
+    return 0 unless $child->matches( $exp);
+    return 0 if( $child->{next_sibling});
+    return $child;
+  } 
+
+
+
+sub root 
+  { my $elt= shift;
+    while( $elt->{parent}) { $elt= $elt->{parent}; }
+    return $elt;
+  }
+#end-extract twig_node
+
+sub twig 
+  { my $elt= shift;
+    my $root= $elt->root;
+    return $root->{twig};
+  }
+
+
+#start-extract twig_node
+
+# returns undef or the element, depending on whether $elt passes $cond
+# $cond can be
+# - empty: the element passes the condition
+# - ELT ('#ELT'): the element passes the condition if it is a "real" element
+# - TEXT ('#TEXT'): the element passes if it is a CDATA or PCDATA element
+# - a string with an XPath condition (only a subset of XPath is actually
+#   supported).
+# - a regexp: the element passes if its gi matches the regexp
+# - a code ref: the element passes if the code, applied on the element,
+#   returns true
+
+my %cond_cache; # expression => coderef
+
+sub reset_cond_cache { %cond_cache=(); }
+
+{ 
+   sub _install_cond
+    { my $cond= shift;
+      my $sub;
+      my $test;
+
+      my $original_cond= $cond;
+
+      my $not= ($cond=~ s{^\s*!}{}) ? '!' : '';
+
+      if( ref $cond eq 'CODE') { return $cond; }
+    
+      if( ref $cond eq 'Regexp')
+        { $test = qq{(\$_[0]->gi=~ /$cond/)}; }
+      else
+        { # the condition is a string
+          if( $cond eq ELT)     
+            { $test = qq{\$_[0]->is_elt}; }
+          elsif( $cond eq TEXT) 
+            { $test = qq{\$_[0]->is_text}; }
+          elsif( $cond=~ m{^\s*($REG_NAME_W)\s*$}o)                  
+            { # gi
+              if( $1 ne '*')
+                { # 2 options, depending on whether the gi exists in gi2index
+                  # start optimization
+                  my $gi= $XML::Twig::gi2index{$1};
+                  if( $gi)
+                    { # the gi exists, use its index as a faster shortcut
+                      $test = qq{ \$_[0]->{gi} eq "$XML::Twig::gi2index{$1}"};
+                    }
+                  else
+                  # end optimization
+                    { # it does not exist (but might be created later), compare the strings
+                      $test = qq{ \$_[0]->gi eq "$1"}; 
+                    }
+                }
+              else
+                { $test = qq{ (1) } }
+            }
+          elsif( $cond=~ m{^\s*($REG_REGEXP)\s*$}o)
+            { # /regexp/
+              $test = qq{ \$_[0]->gi=~ $1 }; 
+            }
+          elsif( $cond=~ m{^\s*($REG_NAME_W)?\s*\[\s*(\!\s*)?\@($REG_NAME)\s*\]\s*$}o)
+            { # gi[@att]
+              my( $gi, $not, $att)= ($1, $2, $3);
+              $not||='';
+              if( $gi && ($gi ne '*'))
+                { $test = qq{    (\$_[0]->gi eq "$gi") 
+                              && $not(defined \$_[0]->{'att'}->{"$att"})
+                            };
+                }
+              else
+                { $test = qq{ $not (defined \$_[0]->{'att'}->{"$att"})}; }
+             }
+          elsif( $cond=~ m{^\s*($REG_NAME_W)?\s*  # $1
+                           \[\s*(-?)\s*(\d+)\s*\] #   [$2]
+                           \s*$}xo
+               )
+            { my( $gi, $neg, $index)= ($1, $2, $3);
+              my $siblings= $neg ? q{$_[0]->_next_siblings} : q{$_[0]->_prev_siblings};
+              if( $gi && ($gi ne '*')) 
+                { $test= qq{((\$_[0]->gi eq "$gi") && (scalar( grep { \$_->gi eq "$gi" } $siblings) + 1 == $index))}; }
+              else
+                { $test= qq{(scalar( $siblings) + 1 == $index)}; }
+            }
+          elsif( $cond=~ m{^\s*($REG_NAME_W)?\s*  # $1
+                           \[\@($REG_NAME)        #   [@$2
+                           \s*($REG_OP)\s*        #        = (or other op) $3
+                          ($REG_VALUE)            #          "$4" or '$4'
+                          \s*\]\s*$}xo)           #                       ]
+            { # gi[@att="val"]
+              my( $gi, $att, $op, $string)= ($1, $2, _op( $3), $4);
+              if( $gi && ($gi ne '*'))
+                { $test = qq{    (\$_[0]->gi eq "$gi") 
+                              && (defined \$_[0]->{'att'}->{"$att"}) 
+                              && ( \$_[0]->{'att'}->{"$att"} $op $string) 
+                            }; 
+                }
+              else
+                { $test = qq{    (defined \$_[0]->{'att'}->{"$att"}) 
+                              && ( \$_[0]->{'att'}->{"$att"} $op $string) 
+                            };
+                }
+            }
+          elsif( $cond=~ m{^\s*($REG_NAME_W)?\s*  # $1
+                           \[\@($REG_NAME)        #   [@$2
+                           \s*($REG_OP)\s*        #        = (or other op) $3
+                           ($REG_VALUE)           #          "$4" or '$4'
+                           \s*(and|or)\s*         #              and or or ($5)
+                           \@($REG_NAME)          #                  @$6
+                           \s*($REG_OP)\s*        #                      = (or other op) $7
+                           ($REG_VALUE)           #                        "$8" or '$8'
+                           \s*\]\s*$}xo)          #                       ]
+            { # gi[@att="val"]
+              my( $gi, $att1, $op1, $string1, $connector, $att2, $op2, $string2)= ($1, $2, _op( $3), $4, $5, $6, _op( $7), $8);
+              if( $gi && ($gi ne '*'))
+                { $test = qq{ (   (\$_[0]->gi eq "$gi") 
+                                and ( ( (defined \$_[0]->{'att'}->{"$att1"})  and( \$_[0]->{'att'}->{"$att1"} $op1 $string1) )
+                                        $connector 
+                                      ( (defined \$_[0]->{'att'}->{"$att2"})  and( \$_[0]->{'att'}->{"$att2"} $op2 $string2) )
+                                    )
+                              )
+                            }; 
+                }
+              else
+                { $test = qq{ ( ( (defined \$_[0]->{'att'}->{"$att1"}) and ( \$_[0]->{'att'}->{"$att1"} $op1 $string1) )
+                               $connector 
+                                ( (defined \$_[0]->{'att'}->{"$att2"})  and( \$_[0]->{'att'}->{"$att2"} $op2 $string2) )
+                              )
+                            };
+                }
+            }
+          elsif( $cond=~ m{^\s*\.([\w-]+)\s*$}o)
+            { # .class
+              my $class= $1;
+              $test = qq{(\$_[0]->in_class( "$class")) }; 
+            }
+          elsif( $cond=~ m{^\s*($REG_NAME_W)?\s*  # $1
+                           \[\@($REG_NAME)        #   [@$2
+                           \s*($REG_MATCH)\s*     #        =~ or !~ ($3)
+                           ($REG_REGEXP)          #           /$4/
+                           \s*\]\s*$}xo)          #                ]
+            { # gi[@att=~ /regexp/] or gi[@att!~/regexp/]
+              my( $gi, $att, $match, $regexp)= ($1, $2, $3, $4);
+              if( $gi && ($gi ne '*'))
+                { $test = qq{    (\$_[0]->gi eq "$gi") 
+                              && (   defined \$_[0]->{'att'}->{"$att"}) 
+                              && ( \$_[0]->{'att'}->{"$att"} $match $regexp)
+                            }; 
+                }
+              else
+                { # *[@att=~/regexp/ or *[@att!~/regexp/
+                  $test = qq{(    defined \$_[0]->{'att'}->{"$att"}) 
+                               && ( \$_[0]->{'att'}->{"$att"} $match $regexp)
+                            };
+                }
+            }
+          elsif( $cond=~ m{^\s*\@($REG_NAME)\s*$}o)
+            { # @att (or !@att)
+              my( $att)= ($1);
+              $test = qq{ (defined \$_[0]->{'att'}->{"$att"})}; 
+            }
+          elsif( $cond=~ m{^\s*                   
+                           \@($REG_NAME)        #   @$1
+                           \s*($REG_OP)\s*      #       = (or other op) $2
+                           ($REG_VALUE)         #         "$3" or '$3'
+                           \s*$}xo)                                 
+            { # @att="val"
+              my( $att, $op, $string)= ( $1, _op( $2), $3);
+              $test = qq{    (defined \$_[0]->{'att'}->{"$att"}) 
+                          && ( \$_[0]->{'att'}->{"$att"} $op $string) 
+                        };
+             }
+          elsif( $cond=~ m{^\s*                   
+                           \@($REG_NAME)        #   @$1
+                           \s*($REG_OP)\s*      #       = (or other op) $2
+                           ($REG_VALUE)         #         "$3" or '$3'
+                           \s*(and|or)\s*       #              and or or ($4)
+                           \@($REG_NAME)        #   @$5
+                           \s*($REG_OP)\s*      #       = (or other op) $6
+                           ($REG_VALUE)         #         "$7" or '$7'
+                           \s*$}xo)                                 
+            { # @att="val"
+              my( $att1, $op1, $string1, $connector, $att2, $op2, $string2 )= ( $1, _op( $2), $3, $4, $5, _op( $6), $7);
+              $test = qq{ ( (    (defined \$_[0]->{'att'}->{"$att1"}) 
+                              && ( \$_[0]->{'att'}->{"$att1"} $op1 $string1) 
+                            )
+                            $connector
+                            (    (defined \$_[0]->{'att'}->{"$att2"}) 
+                              && ( \$_[0]->{'att'}->{"$att2"} $op2 $string2) 
+                            )
+                          )
+                        };
+             }
+          elsif( $cond=~ m{^\s*
+                           \@($REG_NAME)        #   [@$1
+                           \s*(=~|!~)\s*        #        =~ or !~ ($2)
+                          ($REG_REGEXP)         #           /$3/
+                          \s*\s*$}xo)           #                ]
+            { # @att=~ /regexp/ or @att!~/regexp/
+              my( $att, $match, $regexp)= ( $2, $3, $4);
+              $test = qq{(    defined \$_[0]->{'att'}->{"$att"}) 
+                           && ( \$_[0]->{'att'}->{"$att"} $match $regexp)
+                        };
+            }
+          elsif( $cond=~ m{^\s*($REG_NAME_W)?\s*            # $1
+                           \[\s*(?:text|string)(?:\(\s*\))? #   [string()
+                           \s*($REG_OP)\s*                  #            = or other op ($2)
+                           ($REG_VALUE)                     #              "$3" or '$3'
+                           \s*\]\s*$}xo)                    #                          ]
+            { # gi[string()= "val"]
+              my ($gi, $op, $text)= ($1, _op( $2), $3);
+              if( $gi && ($gi ne '*'))
+                { $test = qq{(\$_[0]->gi eq "$gi") && ( \$_[0]->text eq $text)}; }
+              else
+                { $test = qq{ \$_[0]->text eq $text }; }
+            }
+          elsif( $cond=~ m{^\s*($REG_NAME_W)?\s*            # $1
+                           \[\s*(?:text|string)(?:\(\s*\))? #   [string()
+                           \s*($REG_MATCH)\s*               #             =~ or !~ ($2)
+                           ($REG_REGEXP)                    #               /$3/
+                           \s*\]\s*$}xo)                    #                   ]
+            { # gi[string()=~ /regexp/]
+              my( $gi, $match, $regexp)= ($1, $2, $3);
+              if( $gi && ($gi ne '*'))
+                { $test = qq{(\$_[0]->gi eq "$gi") && ( \$_[0]->text $match $regexp) }; }
+              else
+                { $test = qq{ \$_[0]->text $match $regexp }; }
+            }
+          elsif( $cond=~ m{^\s*($REG_NAME_W)?\s*            # $1
+                           \[\s*(?:text|string)\s*\(\s*     #   [string(
+                           ($REG_NAME)\s*\)                 #            $2)
+                           \s*($REG_OP)\s*                  #                = or other op $3
+                           ($REG_VALUE)                     #                  "$4" or '$4'
+                           \s*\]\s*$}xo)                    #                      ]
+            { # gi[string(gi2)= "text"]
+              my ($gi, $gi2, $op, $text)= ($1, $2, _op($3), $4);
+              $text=~ s/([{}])/\\$1/g;
+              if( $gi && ($gi ne '*'))
+                { $test = qq{    (\$_[0]->gi eq "$gi") 
+                              && ( \$_[0]->first_child( qq{$gi2\[text() $op $text]}))
+                            };
+                }
+              else
+                { $test = qq{ \$_[0]->first_child(qq{$gi2\[text() $op $text]}) } ; }
+            }
+          elsif( $cond=~ m{^\s*($REG_NAME_W)?\s*     # $1
+                           \[\s*(?:text|string)\(\s* #   [string(
+                           ($REG_NAME)\s*\)          #         $2)
+                           \s*(=~|!~)\s*             #            =~ or !~ ($3)
+                           ($REG_REGEXP)             #              /$4/
+                           \s*\]\s*$}xo)             #                  ]
+            { # gi[string(gi2)=~ /regexp/]
+              my( $gi, $gi2, $match, $regexp)= ($1, $2, $3, $4);
+              if( $gi && ($gi ne '*'))
+                { $test = qq{   (\$_[0]->gi eq "$gi") 
+                             && ( \$_[0]->field( "$gi2") $match $regexp)
+                            };
+                }
+              else
+                { $test = qq{\$_[0]->field( "$gi2") $match $regexp}; }
+            }
+          else
+            { croak "wrong condition '$original_cond'"; }
+        }
+
+      my $s= eval "sub { return \$_[0] if( $not($test)) }";
+      if( $@) 
+        { croak "wrong navigation condition $original_cond ($@);" }
+      return $s;
+    }
+
+  sub _op
+    { my $op= shift;
+      if(    $op eq '=')  { $op= 'eq'; }
+      elsif( $op eq '!=') { $op= 'ne'; }
+      return $op;
+    }
+ 
+  sub passes
+    { my( $elt, $cond)= @_;
+      return $elt unless $cond;
+      my $sub= ($cond_cache{$cond} ||= _install_cond( $cond));
+      return $sub->( $elt);
+    }
+}
+# end-extract twig_nodes
+
+sub set_parent 
+  { $_[0]->{parent}= $_[1];
+    weaken( $_[0]->{parent}) if( $XML::Twig::weakrefs);
+  }
+
+#start-extract twig_node
+sub parent
+  { my $elt= shift;
+    my $cond= shift || return $elt->{parent};
+    do { $elt= $elt->{parent} || return; } until (!$elt || $elt->passes( $cond));
+    return $elt;
+  }
+#end-extract twig_node
+
+sub set_first_child 
+  { delete $_[0]->{empty};
+    $_[0]->{'first_child'}= $_[1]; 
+  }
+
+#start-extract twig_node
+sub first_child
+  { my $elt= shift;
+    my $cond= shift || return $elt->{first_child};
+    my $child= $elt->{first_child};
+    my $test_cond= ($cond_cache{$cond} ||= _install_cond( $cond));
+    while( $child && !$test_cond->( $child)) 
+       { $child= $child->{next_sibling}; }
+    return $child;
+  }
+#end-extract twig_node
+  
+sub _first_child   { return $_[0]->{first_child};  }
+sub _last_child    { return $_[0]->{last_child};   }
+sub _next_sibling  { return $_[0]->{next_sibling}; }
+sub _prev_sibling  { return $_[0]->{prev_sibling}; }
+sub _parent        { return $_[0]->{parent};       }
+sub _next_siblings { my $elt= shift; my @siblings; while( $elt= $elt->{next_sibling}) { push @siblings, $elt; } return @siblings; }
+sub _prev_siblings { my $elt= shift; my @siblings; while( $elt= $elt->{prev_sibling}) { push @siblings, $elt; } return @siblings; }
+
+# sets a field
+# arguments $record, $cond, @content
+sub set_field
+  { my $record = shift;
+    my $cond = shift;
+    my $child= $record->first_child( $cond);
+    if( $child)
+      { $child->set_content( @_); }
+    else
+      { if( $cond=~ m{^\s*($REG_NAME)})
+          { my $gi= $1;
+            $child= $record->insert_new_elt( last_child => $gi, @_); 
+          }
+        else
+          { croak "can't create a field name from $cond"; }
+      } 
+    return $child;
+  }
+
+sub set_last_child 
+  { delete $_[0]->{empty};
+    $_[0]->{'last_child'}= $_[1];
+    weaken( $_[0]->{'last_child'}) if( $XML::Twig::weakrefs);
+  }
+
+#start-extract twig_node
+sub last_child
+  { my $elt= shift;
+    my $cond= shift || return $elt->{last_child};
+    my $test_cond= ($cond_cache{$cond} ||= _install_cond( $cond));
+    my $child= $elt->{last_child};
+    while( $child && !$test_cond->( $child) )
+      { $child= $child->{prev_sibling}; }
+    return $child
+  }
+#end-extract twig_node
+
+
+sub set_prev_sibling 
+  { $_[0]->{'prev_sibling'}= $_[1]; 
+    weaken( $_[0]->{'prev_sibling'}) if( $XML::Twig::weakrefs); 
+  }
+
+#start-extract twig_node
+sub prev_sibling
+  { my $elt= shift;
+    my $cond= shift || return $elt->{prev_sibling};
+    my $test_cond= ($cond_cache{$cond} ||= _install_cond( $cond));
+    my $sibling= $elt->{prev_sibling};
+    while( $sibling && !$test_cond->( $sibling) )
+          { $sibling= $sibling->{prev_sibling}; }
+    return $sibling;
+  }
+#end-extract twig_node
+
+sub set_next_sibling { $_[0]->{'next_sibling'}= $_[1]; }
+
+#start-extract twig_node
+sub next_sibling
+  { my $elt= shift;
+    my $cond= shift || return $elt->{next_sibling};
+    my $test_cond= ($cond_cache{$cond} ||= _install_cond( $cond));
+    my $sibling= $elt->{next_sibling};
+    while( $sibling && !$test_cond->( $sibling) )
+          { $sibling= $sibling->{next_sibling}; }
+    return $sibling;
+  }
+
+# methods dealing with the class attribute, convenient if you work with xhtml
+sub class     { my( $elt)= @_; return $elt->{'att'}->{'class'}; }
+sub set_class { my( $elt, $class)= @_; $elt->set_att( class => $class); }
+
+# adds a class to an element
+sub add_to_class
+  { my( $elt, $new_class)= @_;
+    return $elt unless $new_class;
+    my $class= $elt->class;
+    my %class= $class ? map { $_ => 1 } split /\s+/, $class : ();
+    $class{$new_class}= 1;
+    $elt->set_class( join( ' ', sort keys %class));
+  }
+
+sub att_to_class      { my( $elt, $att)= @_; $elt->set_class( $elt->{'att'}->{$att}); }
+sub add_att_to_class  { my( $elt, $att)= @_; $elt->add_to_class( $elt->{'att'}->{$att}); }
+sub move_att_to_class { my( $elt, $att)= @_; $elt->add_to_class( $elt->{'att'}->{$att});
+                        $elt->del_att( $att); 
+                      }
+sub tag_to_class      { my( $elt)= @_; $elt->set_class( $elt->tag);    }
+sub add_tag_to_class  { my( $elt)= @_; $elt->add_to_class( $elt->tag); }
+sub set_tag_class     { my( $elt, $new_tag)= @_; $elt->add_tag_to_class; $elt->set_tag( $new_tag); }
+
+sub in_class          
+  { my( $elt, $class)= @_;
+    my $elt_class= $elt->class;
+    return unless( defined $elt_class);
+    return $elt->class=~ m{(?:^|\s)\Q$class\E(?:\s|$)} ? $elt : 0;
+  }
+
+#end-extract twig_node
+
+# get or set all attributes
+sub set_atts 
+  { my $elt= shift;
+    my %atts;
+    tie %atts, 'Tie::IxHash' if( keep_atts_order());
+    if( isa( $_[0] || '', 'HASH'))
+      { while( my( $att, $value)= each %{$_[0]}) { $atts{$att}= $value; } 
+      }
+    else
+      { %atts= @_; }
+    $elt->{'att'}= \%atts;
+    return $elt;
+  }
+
+sub atts      { return $_[0]->{att};           }
+sub att_names { return sort keys %{$_[0]->{att}};   }
+sub del_atts  { $_[0]->{att}={}; return $_[0]; }
+
+# get or set a single attribute (set works for several atts)
+sub set_att 
+  { my $elt= shift;
+    
+    unless( $elt->{att})
+      { $elt->{att}={};
+        tie %{$elt->{att}}, 'Tie::IxHash' if( keep_atts_order());
+      }
+
+    while(@_) { my( $att, $val)= (shift, shift);
+                $elt->{att}->{$att}= $val;
+          }
+    return $elt;
+  }
+sub att { return $_[0]->{att}->{$_[1]}; }
+sub del_att 
+  { my $elt= shift;
+    while( @_) { delete $elt->{'att'}->{shift()}; }
+    return $elt;
+  }
+
+# delete an attribute from all descendants of an element
+sub strip_att
+  { my( $elt, $att)= @_;
+    $_->del_att( $att) foreach ($elt->descendants_or_self( qq{*[\@$att]}));
+  }
+
+sub change_att_name
+  { my( $elt, $old_name, $new_name)= @_;
+    my $value= $elt->{'att'}->{$old_name};
+    return $elt unless( defined $value);
+    $elt->del_att( $old_name)
+        ->set_att( $new_name => $value);
+    return $elt;
+  }
+
+sub set_twig_current { $_[0]->{twig_current}=1; }
+sub del_twig_current { delete $_[0]->{twig_current}; }
+
+
+# get or set the id attribute
+sub set_id 
+  { my( $elt, $id)= @_;
+    $elt->set_att($ID, $id); 
+    my $t= $elt->twig || return;
+    $elt->twig->{twig_id_list}->{$id}= $elt;
+    weaken(  $elt->twig->{twig_id_list}->{$id}) if( $XML::Twig::weakrefs);
+  }
+
+sub id { return $_[0]->{att}->{$ID}; }
+
+# methods used to add ids to elements that don't have one
+BEGIN 
+{ my $id_nb   = "0001";
+  my $id_seed = "twig_id_";
+
+  sub set_id_seed
+    { $id_seed= $_[1]; $id_nb=1; }
+
+  sub add_id
+    { my $elt= shift;
+      $elt->set_id( $id_seed . $id_nb++) unless( $elt->{'att'}->{$ID});
+    }
+
+}
+
+
+
+# delete the id attribute and remove the element from the id list
+sub del_id 
+  { my $elt= shift;
+    my $id= $elt->{'att'}->{$ID} or return;
+    my $t= $elt->twig && delete $elt->twig->{twig_id_list}->{$id};
+    delete $elt->{'att'}->{$ID}; 
+  }
+
+# return the list of children
+#start-extract twig_node
+sub children
+  { my $elt= shift;
+    my @children;
+    my $child= $elt->first_child( @_);
+    while( $child) 
+      { push @children, $child;
+        $child= $child->next_sibling( @_);
+      } 
+    return @children;
+  }
+
+sub _children
+  { my $elt= shift;
+    my @children=();
+    my $child= $elt->_first_child();
+    while( $child) 
+      { push @children, $child;
+        $child= $child->{next_sibling};
+      } 
+    return @children;
+  }
+
+sub children_copy
+  { my $elt= shift;
+    my @children;
+    my $child= $elt->first_child( @_);
+    while( $child) 
+      { push @children, $child->copy;
+        $child= $child->next_sibling( @_);
+      } 
+    return @children;
+  }
+
+
+sub children_count
+  { my $elt= shift;
+    my $cond= shift;
+    my $count=0;
+    my $child= $elt->{first_child};
+    while( $child)
+      { $count++ if( $child->passes( $cond)); 
+        $child= $child->{next_sibling};
+      }
+    return $count;
+  }
+
+sub children_text
+  { my $elt= shift;
+    return map { $_->text} $elt->children( @_);
+  }
+
+sub all_children_are
+  { my( $parent, $cond)= @_;
+    foreach my $child ($parent->children)
+      { return 0 unless( $child->passes( $cond)); }
+    return 1;
+  }
+
+
+sub ancestors
+  { my( $elt, $cond)= @_;
+    my @ancestors;
+    while( $elt->{parent})
+      { $elt= $elt->{parent};
+        push @ancestors, $elt
+          if( $elt->passes( $cond));
+      }
+    return @ancestors;
+  }
+
+sub ancestors_or_self
+  { my( $elt, $cond)= @_;
+    my @ancestors;
+    while( $elt)
+      { push @ancestors, $elt
+          if( $elt->passes( $cond));
+        $elt= $elt->{parent};
+      }
+    return @ancestors;
+  }
+
+
+sub _ancestors
+  { my( $elt, $include_self)= @_;
+    my @ancestors= $include_self ? ($elt) : ();
+    while( $elt= $elt->{parent})
+      { push @ancestors, $elt;
+      }
+    return @ancestors;
+  }
+
+
+sub inherit_att
+  { my $elt= shift;
+    my $att= shift;
+    my %tags= map { ($_, 1) } @_;
+
+    do 
+      { if(   (defined $elt->{'att'}->{$att})
+           && ( !%tags || $tags{$XML::Twig::index2gi[$elt->{'gi'}]})
+          )
+          { return $elt->{'att'}->{$att}; }
+      } while( $elt= $elt->{parent});
+    return undef;
+  }
+
+
+sub current_ns_prefixes
+  { my $elt= shift;
+    my %prefix;
+    $prefix{''}=1 if( $elt->namespace( ''));
+    while( $elt)
+      { my @ns= grep { !m{^xml} } map { m{^([^:]+):} } ($XML::Twig::index2gi[$elt->{'gi'}], $elt->att_names);
+        $prefix{$_}=1 foreach (@ns);
+        $elt= $elt->{parent};
+      }
+
+    return sort keys %prefix;
+  }
+
+# kinda counter-intuitive actually:
+# the next element is found by looking for the next open tag after from the
+# current one, which is the first child, if it exists, or the next sibling
+# or the first next sibling of an ancestor
+# optional arguments are: 
+#   - $subtree_root: a reference to an element, when the next element is not 
+#                    within $subtree_root anymore then next_elt returns undef
+#   - $gi: a gi, next_elt returns the next element of this gi
+                 
+sub next_elt
+  { my $elt= shift;
+    my $subtree_root= 0;
+    $subtree_root= shift if( defined $_[0] and (isa( $_[0], 'XML::Twig::Elt')));
+    my $cond= shift;
+    my $next_elt;
+
+    my $ind;                                                              # optimization
+    my $test_cond;
+    if( $cond)                                                            # optimization
+      { unless( defined( $ind= $XML::Twig::gi2index{$cond}) )             # optimization
+          { $test_cond= ($cond_cache{$cond} ||= _install_cond( $cond)); } # optimization
+      }                                                                   # optimization
+    
+    do
+      { if( $next_elt= $elt->{first_child})
+          { # simplest case: the elt has a child
+          }
+         elsif( $next_elt= $elt->{next_sibling}) 
+          { # no child but a next sibling (just check we stay within the subtree)
+          
+            # case where elt is subtree_root, is empty and has a sibling
+            return undef if( $subtree_root && ($elt == $subtree_root));
+            
+          }
+        else
+          { # case where the element has no child and no next sibling:
+            # get the first next sibling of an ancestor, checking subtree_root 
+          
+            # case where elt is subtree_root, is empty and has no sibling
+            return undef if( $subtree_root && ($elt == $subtree_root));
+             
+            # backtrack until we find a parent with a next sibling
+            $next_elt= $elt->{parent} || return undef;
+            until( $next_elt->{next_sibling})
+              { return undef if( $subtree_root && ($subtree_root == $next_elt));
+                $next_elt= $next_elt->{parent} || return undef;
+              }
+            return undef if( $subtree_root && ($subtree_root == $next_elt)); 
+            $next_elt= $next_elt->{next_sibling};   
+          }  
+      $elt= $next_elt;                   # just in case we need to loop
+    } until(    ! defined $elt 
+             || ! defined $cond 
+         || (defined $ind       && ($elt->{gi} eq $ind))   # optimization
+         || (defined $test_cond && ($test_cond->( $elt)))
+               );
+    
+      return $elt;
+      }
+
+# counter-intuitive too:
+# the previous element is found by looking
+# for the first open tag backwards from the current one
+# it's the last descendant of the previous sibling 
+# if it exists, otherwise it's simply the parent
+sub prev_elt
+  { my $elt= shift;
+    my $cond= shift;
+    # get prev elt
+    my $prev_elt;
+    do
+      { if( $prev_elt= $elt->{prev_sibling})
+          { while( $prev_elt->{last_child})
+              { $prev_elt= $prev_elt->{last_child}; }
+          }
+        else
+          { $prev_elt= $elt->{parent} || return; }
+        $elt= $prev_elt;     # in case we need to loop 
+      } until( $elt->passes( $cond));
+
+    return $prev_elt;
+  }
+
+
+sub next_n_elt
+  { my $elt= shift;
+    my $offset= shift;
+    foreach (1..$offset)
+      { $elt= $elt->next_elt( @_) || return undef; }
+    return $elt;
+  }
+
+# checks whether $elt is included in $ancestor, returns 1 in that case
+sub in
+  { my ($elt, $ancestor)= @_;
+    if( isa( $ancestor, 'XML::Twig::Elt'))
+      { # element
+        while( $elt= $elt->{parent}) { return $elt if( $elt ==  $ancestor); } 
+      }
+    else
+      { # condition
+        while( $elt= $elt->{parent}) { return $elt if( $elt->matches( $ancestor)); } 
+      }
+    return 0;           
+  }
+
+sub first_child_text  
+  { my $elt= shift;
+    my $dest=$elt->first_child(@_) or return '';
+    return $dest->text;
+  }
+  
+sub first_child_trimmed_text  
+  { my $elt= shift;
+    my $dest=$elt->first_child(@_) or return '';
+    return $dest->trimmed_text;
+  }
+  
+sub first_child_matches
+  { my $elt= shift;
+    my $dest= $elt->{first_child} or return undef;
+    return $dest->passes( @_);
+  }
+  
+sub last_child_text  
+  { my $elt= shift;
+    my $dest=$elt->last_child(@_) or return '';
+    return $dest->text;
+  }
+  
+sub last_child_trimmed_text  
+  { my $elt= shift;
+    my $dest=$elt->last_child(@_) or return '';
+    return $dest->trimmed_text;
+  }
+  
+sub last_child_matches
+  { my $elt= shift;
+    my $dest= $elt->{last_child} or return undef;
+    return $dest->passes( @_);
+  }
+  
+sub child_text
+  { my $elt= shift;
+    my $dest=$elt->child(@_) or return '';
+    return $dest->text;
+  }
+  
+sub child_trimmed_text
+  { my $elt= shift;
+    my $dest=$elt->child(@_) or return '';
+    return $dest->trimmed_text;
+  }
+  
+sub child_matches
+  { my $elt= shift;
+    my $nb= shift;
+    my $dest= $elt->child( $nb) or return undef;
+    return $dest->passes( @_);
+  }
+
+sub prev_sibling_text  
+  { my $elt= shift;
+    my $dest=$elt->prev_sibling(@_) or return '';
+    return $dest->text;
+  }
+  
+sub prev_sibling_trimmed_text  
+  { my $elt= shift;
+    my $dest=$elt->prev_sibling(@_) or return '';
+    return $dest->trimmed_text;
+  }
+  
+sub prev_sibling_matches
+  { my $elt= shift;
+    my $dest= $elt->{prev_sibling} or return undef;
+    return $dest->passes( @_);
+  }
+  
+sub next_sibling_text  
+  { my $elt= shift;
+    my $dest=$elt->next_sibling(@_) or return '';
+    return $dest->text;
+  }
+  
+sub next_sibling_trimmed_text  
+  { my $elt= shift;
+    my $dest=$elt->next_sibling(@_) or return '';
+    return $dest->trimmed_text;
+  }
+  
+sub next_sibling_matches
+  { my $elt= shift;
+    my $dest= $elt->{next_sibling} or return undef;
+    return $dest->passes( @_);
+  }
+  
+sub prev_elt_text  
+  { my $elt= shift;
+    my $dest=$elt->prev_elt(@_) or return '';
+    return $dest->text;
+  }
+  
+sub prev_elt_trimmed_text  
+  { my $elt= shift;
+    my $dest=$elt->prev_elt(@_) or return '';
+    return $dest->trimmed_text;
+  }
+  
+sub prev_elt_matches
+  { my $elt= shift;
+    my $dest= $elt->prev_elt or return undef;
+    return $dest->passes( @_);
+  }
+  
+sub next_elt_text  
+  { my $elt= shift;
+    my $dest=$elt->next_elt(@_) or return '';
+    return $dest->text;
+  }
+  
+sub next_elt_trimmed_text  
+  { my $elt= shift;
+    my $dest=$elt->next_elt(@_) or return '';
+    return $dest->trimmed_text;
+  }
+  
+sub next_elt_matches
+  { my $elt= shift;
+    my $dest= $elt->next_elt or return undef;
+    return $dest->passes( @_);
+  }
+  
+sub parent_text  
+  { my $elt= shift;
+    my $dest=$elt->parent(@_) or return '';
+    return $dest->text;
+  }
+  
+sub parent_trimmed_text  
+  { my $elt= shift;
+    my $dest=$elt->parent(@_) or return '';
+    return $dest->trimmed_text;
+  }
+  
+sub parent_matches
+  { my $elt= shift;
+    my $dest= $elt->{parent} or return undef;
+    return $dest->passes( @_);
+  }
+ 
+sub is_first_child
+  { my $elt= shift;
+    my $parent= $elt->{parent} or return 0;
+    my $first_child= $parent->first_child( @_) or return 0;
+    return ($first_child == $elt) ? $elt : 0;
+  }
+ 
+sub is_last_child
+  { my $elt= shift;
+    my $parent= $elt->{parent} or return 0;
+    my $last_child= $parent->last_child( @_) or return 0;
+    return ($last_child == $elt) ? $elt : 0;
+  }
+
+# returns the depth level of the element
+# if 2 parameter are used then counts the 2cd element name in the
+# ancestors list
+sub level
+  { my( $elt, $cond)= @_;
+   
+    my $level=0;
+    my $name=shift || '';
+    while( $elt= $elt->{parent}) { $level++ if( !$cond || $elt->matches( $cond)); }
+    return $level;           
+  }
+
+# checks whether $elt has an ancestor that satisfies $cond, returns the ancestor
+sub in_context
+  { my ($elt, $cond, $level)= @_;
+    $level= -1 unless( $level) ;  # $level-- will never hit 0
+
+    while( $level)
+      { $elt= $elt->{parent} or return;
+        if( $elt->matches( $cond)) { return $elt; }
+        $level--;
+      }
+  }
+
+
+sub _descendants
+  { my( $subtree_root, $include_self)= @_;
+    my @descendants= $include_self ? ($subtree_root) : ();
+
+    my $elt= $subtree_root; 
+    my $next_elt;   
+ 
+    MAIN: while( 1)  
+      { if( $next_elt= $elt->{first_child})
+          { # simplest case: the elt has a child
+          }
+        elsif( $next_elt= $elt->{next_sibling}) 
+          { # no child but a next sibling (just check we stay within the subtree)
+          
+            # case where elt is subtree_root, is empty and has a sibling
+            last MAIN if( $elt == $subtree_root);
+          }
+        else
+          { # case where the element has no child and no next sibling:
+            # get the first next sibling of an ancestor, checking subtree_root 
+                
+            # case where elt is subtree_root, is empty and has no sibling
+            last MAIN if( $elt == $subtree_root);
+               
+            # backtrack until we find a parent with a next sibling
+            $next_elt= $elt->{parent} || last;
+            until( $next_elt->{next_sibling})
+              { last MAIN if( $subtree_root == $next_elt);
+                $next_elt= $next_elt->{parent} || last MAIN;
+              }
+            last MAIN if( $subtree_root == $next_elt); 
+            $next_elt= $next_elt->{next_sibling};   
+          }  
+        $elt= $next_elt || last MAIN;
+        push @descendants, $elt;
+      }
+    return @descendants;
+  }
+
+
+sub descendants
+  { my( $subtree_root, $cond)= @_;
+    my @descendants=(); 
+    my $elt= $subtree_root;
+    
+    # this branch is pure optimisation for speed: if $cond is a gi replace it
+    # by the index of the gi and loop here 
+    # start optimization
+    my $ind;
+    if( !$cond || ( defined ( $ind= $XML::Twig::gi2index{$cond})) )
+      {
+        my $next_elt;
+
+        while( 1)  
+          { if( $next_elt= $elt->{first_child})
+                { # simplest case: the elt has a child
+                }
+             elsif( $next_elt= $elt->{next_sibling}) 
+              { # no child but a next sibling (just check we stay within the subtree)
+           
+                # case where elt is subtree_root, is empty and has a sibling
+                last if( $subtree_root && ($elt == $subtree_root));
+              }
+            else
+              { # case where the element has no child and no next sibling:
+                # get the first next sibling of an ancestor, checking subtree_root 
+                
+                # case where elt is subtree_root, is empty and has no sibling
+                last if( $subtree_root && ($elt == $subtree_root));
+               
+                # backtrack until we find a parent with a next sibling
+                $next_elt= $elt->{parent} || last undef;
+                until( $next_elt->{next_sibling})
+                  { last if( $subtree_root && ($subtree_root == $next_elt));
+                    $next_elt= $next_elt->{parent} || last;
+                  }
+                last if( $subtree_root && ($subtree_root == $next_elt)); 
+                $next_elt= $next_elt->{next_sibling};   
+              }  
+            $elt= $next_elt || last;
+            push @descendants, $elt if( !$cond || ($elt->{gi} eq $ind));
+          }
+      }
+    else
+    # end optimization
+      { # branch for a complex condition: use the regular (slow but simple) way
+        while( $elt= $elt->next_elt( $subtree_root, $cond))
+          { push @descendants, $elt; }
+      }
+    return @descendants;
+  }
+
+ 
+sub descendants_or_self
+  { my( $elt, $cond)= @_;
+    my @descendants= $elt->passes( $cond) ? ($elt) : (); 
+    push @descendants, $elt->descendants( $cond);
+    return @descendants;
+  }
+  
+sub sibling
+  { my $elt= shift;
+    my $nb= shift;
+    if( $nb > 0)
+      { foreach( 1..$nb)
+          { $elt= $elt->next_sibling( @_) or return undef; }
+      }
+    elsif( $nb < 0)
+      { foreach( 1..(-$nb))
+          { $elt= $elt->prev_sibling( @_) or return undef; }
+      }
+    else # $nb == 0
+      { return $elt->passes( $_[0]); }
+    return $elt;
+  }
+
+sub sibling_text
+  { my $elt= sibling( @_);
+    return $elt ? $elt->text : undef;
+  }
+
+
+sub child
+  { my $elt= shift;
+    my $nb= shift;
+    if( $nb >= 0)
+      { $elt= $elt->first_child( @_) or return undef;
+        foreach( 1..$nb)
+          { $elt= $elt->next_sibling( @_) or return undef; }
+      }
+    else
+      { $elt= $elt->last_child( @_) or return undef;
+        foreach( 2..(-$nb))
+          { $elt= $elt->prev_sibling( @_) or return undef; }
+      }
+    return $elt;
+  }
+
+sub prev_siblings
+  { my $elt= shift;
+    my @siblings=();
+    while( $elt= $elt->prev_sibling( @_))
+      { unshift @siblings, $elt; }
+    return @siblings;
+  }
+
+sub pos
+  { my $elt= shift;
+    return 0 if ($_[0] && !$elt->matches( @_));
+    my $pos=1;
+    $pos++ while( $elt= $elt->prev_sibling( @_));
+    return $pos;
+  }
+
+
+sub next_siblings
+  { my $elt= shift;
+    my @siblings=();
+    while( $elt= $elt->next_sibling( @_))
+      { push @siblings, $elt; }
+    return @siblings;
+  }
+
+# used by get_xpath: parses the xpath expression and generates a sub that performs the
+# search
+sub _install_xpath
+  { my( $xpath_exp, $type)= @_;
+    my $original_exp= $xpath_exp;
+    my $sub= 'my $elt= shift; my @results;';
+    
+    # grab the root if expression starts with a /
+    if( $xpath_exp=~ s{^/}{})
+      { $sub .= '@results= ($elt->twig);'; }
+    elsif( $xpath_exp=~ s{^\./}{})
+      { $sub .= '@results= ($elt);'; }
+    else
+      { $sub .= '@results= ($elt);'; }
+
+
+    while( $xpath_exp &&
+           $xpath_exp=~s{^\s*(/?)                            
+                          # the xxx=~/regexp/ is a pain as it includes /  
+                          (\s*((\*|$REG_NAME|\.)\s*)?\[\s*(string\(\s*\)|\@$REG_NAME)\s*$REG_MATCH  
+                            \s*$REG_REGEXP\s*\]\s* 
+                          # or a regular condition, with no / excepts \/
+                          |([^\\/]|\\.)*
+                          )
+                          (/|$)}{}xo)
+
+      { my $wildcard= $1;
+        my $sub_exp= $2; 
+        
+        # grab a parent
+        if( $sub_exp eq '..')
+          { croak "error in xpath expression $original_exp" if( $wildcard);
+            $sub .= '@results= map { $_->{parent}} @results;';
+          }
+    # test the element itself
+    elsif( $sub_exp=~ m{^\.(.*)$}s)
+      { $sub .= "\@results= grep { \$_->matches( q{$1}) } \@results;" }
+        # grab children
+        elsif( $sub_exp=~ m{($REG_NAME_W)?\s*                # * or a gi    ($1)
+                            (?:
+                \[\s*                             #  [
+                  (
+                (?:string\(\s*\)|\@$REG_NAME) #    regexp condition 
+                   \s*$REG_MATCH\s*$REG_REGEXP\s*  # or
+                        |[^\]]*                       #    regular condition 
+                  )
+                            \]                                #   ]
+                             )?\s*$}xs)        
+          { my $gi= $1; 
+            if( !$1 or $1 eq '*') { $gi=''; }
+            my $cond= $2; 
+            if( $cond) { $cond=~ s{^\s*}{}; $cond=~ s{\s*$}{}; }
+            my $function;
+            
+
+            # "special" conditions, that return just one element
+            if( $cond && ($cond =~ m{^((-\s*)?\d+)$}) )
+              { my $offset= $1;
+                $offset-- if( $offset > 0);
+                $function=  $wildcard ? "next_n_elt( $offset, '$gi')" 
+                                      : "child( $offset, '$gi')";
+                $sub .= "\@results= map { \$_->$function } \@results;"
+              }
+            elsif( $cond && ($cond =~ m{^last\s*\(\s*\)$}) )
+              { croak "error in xpath expression $original_exp, cant use // and last()"
+                  if( $wildcard);
+                 $sub .= "\@results= map { \$_->last_child( '$gi') } \@results;";
+              }
+            else
+              { # go down and get the children or descendants
+                unless ( defined $gi)
+                  { if( $wildcard)
+                      { $sub .= '@results= map { $_->descendants  } @results;' }
+                    else
+                      { $sub .= '@results= map { $_->children } @results;'; }
+                  }
+                else
+                  { if( $wildcard)
+                      { $sub .= "\@results= map { \$_->descendants( '$gi')  } \@results;";  }            
+                    else
+                      { $sub .= "\@results= map { \$_->children( '$gi')  } \@results;"; }
+                  } 
+                # now filter using the condition
+                if( $cond)
+                  { my $op='';
+                    my $test="";
+                    do
+                      { if( $op)
+                          { $cond=~ s{^\s*$op\s*}{};
+                            $op= lc( $op);
+                            $test .= $op;
+                          }
+                       if( $cond =~ s{^string\(\s*\)\s*=\s*($REG_STRING)\s*}{}o)  # string()="string" cond
+                          { $test .= "\$_->text eq $1"; 
+                          }
+                       elsif( $cond =~ s{^string\(\s*\)\s*($REG_MATCH)\s*($REG_REGEXP)\s*}{}o)  # string()=~/regex/ cond
+                          { my( $match, $regexp)= ($1, $2);
+                            $test .= "\$_->text $match $regexp"; 
+                          }
+                       elsif( $cond=~ s{^@($REG_NAME)\s*($REG_OP)\s*($REG_STRING|$REG_NUMBER)}{}o)  # @att="val" cond
+                          { my( $att, $oper, $val)= ($1, _op( $2), $3);
+                            $test .= qq{((defined \$_->{'att'}->{"$att"})  && (\$_->{'att'}->{"$att"} $oper $val))};
+                          }
+                       elsif( $cond =~ s{^@($REG_NAME)\s*($REG_MATCH)\s*($REG_REGEXP)\s*}{}o)  # @att=~/regex/ cond XXX
+                          { my( $att, $match, $regexp)= ($1, $2, $3);
+                            $test .= qq{((defined \$_->{'att'}->{"$att"})  && (\$_->{'att'}->{"$att"} $match $regexp))};; 
+                          }
+                       elsif( $cond=~ s{^@($REG_NAME)\s*}{}o)                      # @att cond
+                          { 
+                            $test .= qq{(defined \$_->{'att'}->{"$1"})};
+                          }
+                       elsif( $cond=~ s{^\s*(\d+)\s*}{}o)                          # positive number condition
+                          { 
+                            $test .= qq{(\$_->prev_siblings( \$_->gi) == $1)};
+                          }
+                       elsif( $cond=~ s{^\s*-\s*(\d+)\s*}{}o)                      # negative number condition
+                          { 
+                            $test .= qq{(\$_->next_siblings( \$_->gi) == $1)};
+                          }
+                       } while( ($op)=($cond=~ m{^\s*(and|or)\s*}i));
+                     croak "error in xpath expression $original_exp at $cond" if( $cond);
+                     $sub .= "\@results= grep { $test } \@results;";
+                   }
+              }
+          }
+      }
+
+    if( $xpath_exp)
+      { croak "error in xpath expression $original_exp around $xpath_exp"; }
+      
+    $sub .= "return \@results; ";
+    my $s= eval "sub { $sub }";
+    if( $@) { croak "error in xpath expression $original_exp ($@);" }
+    return( $s); 
+   }
+        
+{ # extremely elaborate caching mechanism
+  my %xpath; # xpath_expression => subroutine_code;  
+  sub get_xpath
+    { my( $elt, $xpath_exp, $offset)= @_;
+      my $sub= ($xpath{$xpath_exp} ||= _install_xpath( $xpath_exp));
+      return $sub->( $elt) unless( defined $offset); 
+      my @res= $sub->( $elt);
+      return $res[$offset];
+    }
+    1; # so the module returns 1 as this is the last BEGIN block in the file
+}
+
+
+sub findvalue
+  { my $elt= shift;
+    return join '', map { $_->text } $elt->get_xpath( @_);
+  }
+
+#end-extract twig_node
+
+
+# XML::XPath compatibility
+sub getElementById     { return $_[0]->twig->elt_id( $_[1]); }
+sub getChildNodes      { my @children= $_[0]->children; return wantarray ? @children : \@children; }
+
+sub _flushed     { return $_[0]->{flushed}; }
+sub _set_flushed { $_[0]->{flushed}=1;      }
+sub _del_flushed { delete $_[0]->{flushed}; }
+
+
+sub cut
+  { my $elt= shift;
+    my( $parent, $prev_sibling, $next_sibling, $last_elt);
+
+    # you can't cut the root, sorry
+    unless( $parent= $elt->{parent}) 
+      { return; }
+    # it we cut the current element then its parent becomes the current elt
+    if( $elt->{twig_current})
+      { my $twig_current= $elt->{parent};
+        my $t= $elt->twig;
+        $t->{twig_current}= $twig_current;
+        $twig_current->{'twig_current'}=1;
+        delete $elt->{'twig_current'};
+      }
+
+    if( $parent->{first_child} == $elt)
+      { $parent->{first_child}=  $elt->{next_sibling};
+        $parent->{empty}= 1 unless( $elt->{next_sibling});
+      }
+    $parent->set_last_child( $elt->{prev_sibling}) 
+      if( $parent->{last_child} == $elt);
+
+    if( $prev_sibling= $elt->{prev_sibling})
+      { $prev_sibling->{next_sibling}=  $elt->{next_sibling}; }
+    if( $next_sibling= $elt->{next_sibling})
+      { $next_sibling->set_prev_sibling( $elt->{prev_sibling}); }
+
+
+    $elt->set_parent( undef);
+    $elt->set_prev_sibling( undef);
+    $elt->{next_sibling}=  undef;
+
+    return $elt;
+  }
+
+sub cut_children
+  { my( $elt, $exp)= @_;
+    my @children= $elt->children( $exp);
+    foreach (@children) { $_->cut; }
+    return @children;
+  }
+
+sub erase
+  { my $elt= shift;
+    #you cannot erase the current element
+    if( $elt->{twig_current})
+      { croak "trying to erase an element before it has been completely parsed"; }
+    unless( $elt->{parent})
+      { # trying to erase the root (of a twig or of a cut/new element)
+        my @children= $elt->children;
+        unless( @children == 1)
+          { croak "can only erase an element with no parent if it has a single child"; }
+        my $child= shift @children;
+        $child->set_parent( undef);
+        my $twig= $elt->twig;
+        $twig->set_root( $child);
+      }
+    else     
+      { # normal case
+        my @children= $elt->children;
+        if( @children)
+          { # elt has children, move them up
+            if( $elt->{prev_sibling})
+              { # connect first child to previous sibling
+                $elt->{first_child}->set_prev_sibling( $elt->{prev_sibling});      
+                $elt->{prev_sibling}->set_next_sibling( $elt->{first_child}); 
+              }
+            else
+              { # elt was the first child
+                $elt->{parent}->set_first_child( $elt->{first_child});
+              }
+            if( $elt->{next_sibling})
+              { # connect last child to next sibling
+                $elt->{last_child}->set_next_sibling( $elt->{next_sibling});      
+                $elt->{next_sibling}->set_prev_sibling( $elt->{last_child}); 
+              }
+            else
+              { # elt was the last child
+                $elt->{parent}->set_last_child( $elt->{last_child});
+              }
+            # update parent for all siblings
+            foreach my $child (@children)
+              { $child->set_parent( $elt->{parent}); }
+            # elt is not referenced any more, so it will be DESTROYed
+            # so we'd better break the links to its children
+            undef $elt->{'first_child'};
+            undef $elt->{'last_child'};
+            undef $elt->{'parent'};
+            undef $elt->{'prev_sibling'};
+            undef $elt->{'next_sibling'};
+          }
+          { # elt had no child, delete it
+             $elt->delete;
+          }
+    
+        return $elt;
+      }
+
+  }
+        
+
+BEGIN
+  { my %method= ( before      => \&paste_before,
+                  after       => \&paste_after,
+                  first_child => \&paste_first_child,
+                  last_child  => \&paste_last_child,
+                  within      => \&paste_within,
+        );
+    
+    # paste elt somewhere around ref
+    # pos can be first_child (default), last_child, before, after or within
+    sub paste
+      { my $elt= shift;
+        if( $elt->{parent}) 
+          { croak "cannot paste an element that belongs to a tree"; }
+        my $pos;
+        my $ref;
+        if( ref $_[0]) 
+          { $pos= 'first_child'; 
+            croak "wrong argument order in paste, should be $_[1] first" if($_[1]); 
+          }
+        else
+          { $pos= shift; }
+
+        if( my $method= $method{$pos})
+          { unless( ref $_[0]) { croak "Destination undefined in paste"; }
+            unless( isa( $_[0], "XML::Twig::Elt"))
+              { croak "wrong argument type in paste, should be XML::Twig::Elt"; }
+            # check here so error message lists the caller file/line
+            if( !$ref->{parent} && ($method=~ m{^(before|after)}) ) { croak "cannot paste $1 root"; }
+            $elt->$method( @_); 
+          }
+        else
+          { croak "tried to paste in wrong position '$pos', allowed positions " . 
+              " are 'first_child', 'last_child', 'before', 'after' and "    .
+              "'within'";
+          }
+        return $elt;
+      }
+  
+
+    sub paste_before
+      { my( $elt, $ref)= @_;
+        my( $parent, $prev_sibling, $next_sibling );
+        unless( $ref->{parent}) { croak "cannot paste before root"; }
+        $parent= $ref->{parent};
+        $prev_sibling= $ref->{prev_sibling};
+        $next_sibling= $ref;
+
+        $elt->set_parent( $parent);
+        $parent->{first_child}=  $elt if( $parent->{first_child} == $ref);
+
+        $prev_sibling->{next_sibling}=  $elt if( $prev_sibling);
+        $elt->set_prev_sibling( $prev_sibling);
+
+        $next_sibling->set_prev_sibling( $elt);
+        $elt->{next_sibling}=  $ref;
+        return $elt;
+      }
+     
+     sub paste_after
+      { my( $elt, $ref)= @_;
+        my( $parent, $prev_sibling, $next_sibling );
+        unless( $ref->{parent}) { croak "cannot paste after root"; }
+        $parent= $ref->{parent};
+        $prev_sibling= $ref;
+        $next_sibling= $ref->{next_sibling};
+
+        $elt->set_parent( $parent);
+        $parent->set_last_child( $elt) if( $parent->{last_child}== $ref);
+
+        $prev_sibling->{next_sibling}=  $elt;
+        $elt->set_prev_sibling( $prev_sibling);
+
+        $next_sibling->set_prev_sibling( $elt) if( $next_sibling);
+        $elt->{next_sibling}=  $next_sibling;
+        return $elt;
+
+      }
+
+    sub paste_first_child
+      { my( $elt, $ref)= @_;
+        my( $parent, $prev_sibling, $next_sibling );
+        $parent= $ref;
+        $next_sibling= $ref->{first_child};
+        delete $ref->{empty};
+
+        $elt->set_parent( $parent);
+        $parent->{first_child}=  $elt;
+        $parent->set_last_child( $elt) unless( $parent->{last_child});
+
+        $elt->set_prev_sibling( undef);
+
+        $next_sibling->set_prev_sibling( $elt) if( $next_sibling);
+        $elt->{next_sibling}=  $next_sibling;
+        return $elt;
+      }
+      
+    sub paste_last_child
+      { my( $elt, $ref)= @_;
+        my( $parent, $prev_sibling, $next_sibling );
+        $parent= $ref;
+        $prev_sibling= $ref->{last_child};
+        delete $ref->{empty};
+
+        $elt->set_parent( $parent);
+        $parent->set_last_child( $elt);
+        $parent->{first_child}=  $elt unless( $parent->{first_child});
+
+        $elt->set_prev_sibling( $prev_sibling);
+        $prev_sibling->{next_sibling}=  $elt if( $prev_sibling);
+
+        $elt->{next_sibling}=  undef;
+        return $elt;
+      }
+
+    sub paste_within
+      { my( $elt, $ref, $offset)= @_;
+        my $text= $ref->is_text ? $ref : $ref->next_elt( '#TEXT', $ref);
+        my $new= $text->split_at( $offset);
+        $elt->paste_before( $new);
+        return $elt;
+      }
+  }
+
+# load an element into a structure similar to XML::Simple's
+sub simplify
+  { my $elt= shift;
+
+    # normalize option names
+    my %options= @_;
+    %options= map { my ($key, $val)= ($_, $options{$_});
+                       $key=~ s{(\w)([A-Z])}{$1_\L$2}g;
+                       $key => $val
+                     } keys %options;
+
+    # check options
+    my @allowed_options= qw( keyattr forcearray noattr content_key
+                             var var_regexp variables var_attr 
+                             erase group_tags forcecontent
+                             normalise_space normalize_space
+                   );
+    my %allowed_options= map { $_ => 1 } @allowed_options;
+    foreach my $option (keys %options)
+      { warn "invalid option $option\n" unless( $allowed_options{$option}); }
+
+    $options{normalise_space} ||= $options{normalize_space} || 0;
+    
+    $options{content_key} ||= 'content';
+    if( $options{content_key}=~ m{^-})
+      { # need to remove the - and to activate extra folding
+        $options{content_key}=~ s{^-}{};
+        $options{extra_folding}= 1;
+      }
+    else
+      { $options{extra_folding}= 0; }
+   
+    $options{forcearray} ||=0; 
+    if( isa( $options{forcearray}, 'ARRAY'))
+      { my %forcearray_tags= map { $_ => 1 } @{$options{forcearray}};
+        $options{forcearray_tags}= \%forcearray_tags;
+        $options{forcearray}= 0;
+      }
+
+    $options{erase}||= $options{group_tags}; # for compat with XML::Simple
+    if( isa( $options{erase}, 'ARRAY'))
+      { my %erase_tags= map { $_ => 1 } @{$options{erase}};
+        $options{erase}= \%erase_tags;
+      }
+
+    $options{keyattr}     ||= ['name', 'key', 'id'];
+    if( ref $options{keyattr} eq 'ARRAY')
+      { foreach my $keyattr (@{$options{keyattr}})
+          { my( $prefix, $att)= ($keyattr=~ m{^([+-])?(.*)});
+            $prefix ||= '';
+            $options{key_for_all}->{$att}= 1;
+            $options{remove_key_for_all}->{$att}=1 unless( $prefix eq '+');
+            $options{prefix_key_for_all}->{$att}=1 if( $prefix eq '-');
+          }
+      }
+    elsif( ref $options{keyattr} eq 'HASH')
+      { while( my( $elt, $keyattr)= each %{$options{keyattr}})
+         { my( $prefix, $att)= ($keyattr=~ m{^([+-])?(.*)});
+           $prefix ||='';
+           $options{key_for_elt}->{$elt}= $att;
+           $options{remove_key_for_elt}->{"$elt#$att"}=1 unless( $prefix);
+           $options{prefix_key_for_elt}->{"$elt#$att"}=1 if( $prefix eq '-');
+         }
+      }
+       
+
+    $options{var}||= $options{var_attr}; # for compat with XML::Simple
+    if( $options{var}) { $options{var_values}= {}; }
+    else               { $options{var}='';         }
+
+    if( $options{variables}) 
+      { $options{var}||= 1;
+        $options{var_values}= $options{variables};
+      }
+
+    if( $options{var_regexp} and !$options{var})
+      { warn "var option not used, var_regexp option ignored\n"; }
+    $options{var_regexp} ||= '\$\{?(\w+)\}?';
+      
+    $elt->_simplify( \%options);
+ 
+ }
+
+sub _simplify
+  { my( $elt, $options)= @_;
+
+    my $data;
+
+    my $gi= $XML::Twig::index2gi[$elt->{'gi'}];
+    my @children= $elt->children;
+    my %atts= $options->{noattr} ? () : %{$elt->atts};
+    my $nb_atts= keys %atts;
+    my $nb_children= $elt->children_count + $nb_atts;
+
+    my %nb_children;
+    foreach (@children)   { $nb_children{$_->tag}++; }
+    foreach (keys %atts)  { $nb_children{$_}++;      }
+
+    my $arrays; # tag => array where elements are stored
+
+
+    # store children
+    foreach my $child (@children)
+      { if( $child->is_text)
+          { # generate with a content key
+            my $text= $elt->_text_with_vars( $options);
+            $text= _normalize_space( $text) if( $options->{normalise_space} >= 2);
+            if(    $options->{force_content}
+                || $nb_atts 
+              )
+              { $data->{$options->{content_key}}= $text; }
+            else
+              { $data= $text; }
+          }
+        else
+          { # element with sub elements
+            my $child_gi= $XML::Twig::index2gi[$child->{'gi'}];
+
+            my $child_data= $child->_simplify( $options);
+
+            # first see if we need to simplify further the child data
+            # because of grouped tags
+            if( my $grouped_tag= $options->{group_tags}->{$child_gi})
+              { # check that the child data is a hash with a single field
+                unless(    (ref( $child_data) eq 'HASH')
+                        && (keys %$child_data == 1)
+                        && defined ( my $grouped_child_data= $child_data->{$grouped_tag})
+                      )
+                  { die "error in grouped tag $child_gi"; }
+                else
+                  { $child_data=  $grouped_child_data; }
+              }
+            # because of extra folding
+            if( $options->{extra_folding})
+              { if(    (ref( $child_data) eq 'HASH')
+                    && (keys %$child_data == 1)
+                    && defined( my $content= $child_data->{$options->{content_key}})
+                  )
+                  { $child_data= $content; }
+              }
+
+
+            if( my $keyatt= $child->_key_attr( $options))
+              { # element with key
+                my $key= $child->{'att'}->{$keyatt};
+                $key= _normalize_space( $key) if( $options->{normalise_space} >= 1);
+                $data->{$child_gi}->{$key}= $child_data;
+              }
+            elsif(      $options->{forcearray}
+                   ||   $options->{forcearray_tags}->{$child_gi}
+                   || ( $nb_children{$child_gi} > 1)
+                 )
+              { # element to store in an array
+                $data->{$child_gi} ||= [];
+                push @{$data->{$child_gi}}, $child_data;
+              }
+            else
+              { # element to store as a hash field
+                $data->{$child_gi}= $child_data;
+              }
+
+          }
+    }
+
+    # store atts
+    # TODO: deal with att that already have an element by that name
+    foreach my $att (keys %atts)
+      { # do not store if the att is a key that needs to be removed
+        if(    $options->{remove_key_for_all}->{$att}
+            || $options->{remove_key_for_elt}->{"$gi#$att"}
+          )
+          { next; }
+
+        my $att_text= _replace_vars_in_text( $atts{$att}, $options);
+        $att_text= _normalize_space( $att_text) if( $options->{normalise_space} >= 2);
+        
+        if(    $options->{prefix_key_for_all}->{$att}
+            || $options->{prefix_key_for_elt}->{"$gi#$att"}
+          )
+          { # prefix the att
+            $data->{"-$att"}= $att_text;
+          } 
+        else
+          { # normal case
+            $data->{$att}= $att_text; 
+          }
+      }
+    
+    return $data;
+  }
+
+sub _key_attr
+  { my( $elt, $options)=@_;
+    return if( $options->{noattr});
+    if( $options->{key_for_all})
+      { foreach my $att ($elt->att_names)
+          { if( $options->{key_for_all}->{$att})
+              { return $att; }
+          }
+      }
+    elsif( $options->{key_for_elt})
+      { if( my $key_for_elt= $options->{key_for_elt}->{$XML::Twig::index2gi[$elt->{'gi'}]} )
+          { return $key_for_elt if( defined( $elt->{'att'}->{$key_for_elt})); }
+      }
+    return;
+  }
+
+sub _text_with_vars
+  { my( $elt, $options)= @_;
+    my $text;
+    if( $options->{var}) 
+      { $text= _replace_vars_in_text( $elt->text, $options); 
+        $elt->_store_var( $options);
+      }
+     else
+      { $text= $elt->text; }
+    return $text;
+  }
+
+
+sub _normalize_space
+  { my $text= shift;
+    $text=~ s{\s+}{ }sg;
+    $text=~ s{^\s}{};
+    $text=~ s{\s$}{};
+    return $text;
+  }
+
+
+sub att_nb
+  { return 0 unless( my $atts= $_[0]->atts);
+    return scalar keys %$atts;
+  }
+    
+sub has_no_atts
+  { return 1 unless( my $atts= $_[0]->atts);
+    return scalar keys %$atts ? 0 : 1;
+ }
+    
+sub _replace_vars_in_text
+  { my( $text, $options)= @_;
+
+    $text=~ s{($options->{var_regexp})}
+             { if( defined( my $value= $options->{var_values}->{$2}))
+                 { $value }
+               else
+                 { warn "unknown variable $2\n";
+                   $1
+                 }
+             }gex;
+    return $text;
+  }
+
+sub _store_var
+  { my( $elt, $options)= @_;
+    if( defined (my $var_name= $elt->{'att'}->{$options->{var}}))
+       { $options->{var_values}->{$var_name}= $elt->text; 
+       }
+  }
+
+
+# split a text element at a given offset
+sub split_at
+  { my( $elt, $offset)= @_;
+    my $text_elt= $elt->is_text ? $elt : $elt->first_child( TEXT) || return '';
+    my $string= $text_elt->text; 
+    my $left_string= substr( $string, 0, $offset);
+    my $right_string= substr( $string, $offset);
+    $text_elt->{pcdata}=  $left_string;
+    my $new_elt= XML::Twig::Elt->new( $XML::Twig::index2gi[$elt->{'gi'}], $right_string);
+    $new_elt->paste( after => $elt);
+    return $new_elt;
+  }
+
+    
+# split an element or its text descendants into several, in place
+# all elements (new and untouched) are returned
+sub split    
+  { my $elt= shift;
+    my @text_chunks;
+    my @result;
+    if( $elt->is_text) { @text_chunks= ($elt); }
+    else               { @text_chunks= $elt->descendants( '#TEXT'); }
+    foreach my $text_chunk (@text_chunks)
+      { push @result, $text_chunk->_split( 1, @_); }
+    return @result;
+  }
+
+# split an element or its text descendants into several, in place
+# created elements (those which match the regexp) are returned
+sub mark
+  { my $elt= shift;
+    my @text_chunks;
+    my @result;
+    if( $elt->is_text) { @text_chunks= ($elt); }
+    else               { @text_chunks= $elt->descendants( '#TEXT'); }
+    foreach my $text_chunk (@text_chunks)
+      { push @result, $text_chunk->_split( 0, @_); }
+    return @result;
+  }
+
+# split a single text element
+# return_all defines what is returned: if it is true 
+# only returns the elements created by matches in the split regexp
+# otherwise all elements (new and untouched) are returned
+
+{ my $encode_is_loaded=0;   # so we only load Encode once in 5.8.0+
+ 
+  sub _split
+    { my $elt= shift;
+      my $return_all= shift;
+      my( $regexp, $tag, $atts)= @_;
+      my @result;                                 # the returned list of elements
+      my $text= $elt->text;
+      my $gi= $XML::Twig::index2gi[$elt->{'gi'}];
+      $tag||= $elt->parent( '#ELT')->gi;          # default: same tag as the current one
+      $atts ||= {};                               # default: no attributes
+  
+      # 2 uses: if split matches then the first substring reuses $elt
+      #         once a split has occured then the last match needs to be put in
+      #         a new element      
+      my $replaced= 0;
+
+      while( $text=~/(.*?)(?:($regexp)|$)/sg)
+        { # $1 is the pre-regexp match
+          # $2 is the string that matches the regexp (if true then the regexp 
+          #    matched, otherwise no match)
+          # $3...$n are captured by the regexp (and should be wrapped in tag)
+          if( defined $2 || $replaced)
+            { # the regexp matched this time ($2) or previously ($replaced)
+              unless( $replaced)
+                { # first match in $elt, re-use $elt for the first sub-string
+                  $elt->set_text( _utf8_ify( $1));
+                  $replaced++;                     # note that there was a match
+                  push @result, $elt if( $return_all);
+                }
+              else
+                { # match, not the first one, create a new text ($gi) element
+                  my $pre_match= _utf8_ify( $1);
+                  my $new_text= XML::Twig::Elt->new( $gi, $pre_match);
+                  $new_text->paste( 'after', $elt); # paste it after $elt
+                  $elt= $new_text;                  # $elt: element to paste after
+                  push @result, $elt if( $return_all);
+                }
+              # now deal with matches captured in the regexp
+              no strict( 'refs');                   # needed to access $3...$n
+              for( my $match_nb=3; defined $$match_nb; $match_nb++)
+                { # create new element, text is the match
+                  my %atts= %$atts; # or the same atts is used for all matches!
+                  my $match= _utf8_ify( $$match_nb);
+                  my $new_text= XML::Twig::Elt->new( $tag, \%atts, $match);
+                  $new_text->paste( 'after', $elt); # paste it after the current
+                  $elt= $new_text;                  # it becomes the current elt
+                  push @result, $elt;
+                }
+            }
+          else
+            { # the regep did not match at all, $elt is not changed
+              push @result, $elt if( $return_all);
+            }
+        } 
+      return @result; # return all elements
+   }
+
+  # evil hack needed in 5.8.0, the utf flag is not set on $<n>...
+  sub _utf8_ify
+    { my $string= shift;
+      if( $] > 5.007 and !keep_encoding()) 
+        { unless( $encode_is_loaded) { require Encode; import Encode; $encode_is_loaded++; }
+          Encode::_utf8_on( $string); # the flag should be set but is not
+        }
+      return $string;
+    }
+
+
+}
+
+{ my %replace_sub; # cache for complex expressions (expression => sub)
+
+  sub subs_text
+    { my( $elt, $regexp, $replace)= @_;
+  
+      my $replacement_string;
+      my $is_string= _is_string( $replace);
+      foreach my $text_elt ($elt->descendants_or_self( '#TEXT'))
+        { if( $is_string)
+            { my $text= $text_elt->text;
+              $text=~ s{$regexp}{ _replace_var( $replace, $1, $2, $3, $4, $5, $6, $7, $8, $9)}egx;
+              $text_elt->set_text( $text);
+           }
+          else
+            { my $replace_sub= ( $replace_sub{$replace} ||= _install_replace_sub( $replace)); 
+              my $text= $text_elt->text;
+              my $pos=0;  # used to skip text that was previously matched
+              while( my( $pre_match_string, $match_string, @var)= ($text=~ m{(.*?)($regexp)}g))
+                { my $match_start  = length( $pre_match_string);
+                  my $match        = $text_elt->split_at( $match_start + $pos);
+                  my $match_length = length( $match_string);
+                  my $post_match   = $match->split_at( $match_length);
+                  $replace_sub->( $match, @var);
+                  # merge previous text with current one
+                  my $next_sibling;
+                  if(    ($next_sibling= $text_elt->{next_sibling})
+                      && ($XML::Twig::index2gi[$text_elt->{'gi'}] eq $XML::Twig::index2gi[$next_sibling->{'gi'}])
+                    )
+                    { $text_elt->merge_text( $next_sibling); }
+                  # go to next 
+                  $text_elt= $post_match;
+                  $text= $post_match->text;
+                  # merge last text element with next one if needed,
+                  # the match will be against the non-matched text,
+                  # so $pos is used to skip the merged part
+                  my $prev_sibling;
+                  if(    ($prev_sibling=  $post_match->{prev_sibling})
+                      && ($XML::Twig::index2gi[$post_match->{'gi'}] eq $XML::Twig::index2gi[$prev_sibling->{'gi'}])
+                    )
+                    { $pos= length( $prev_sibling->text);
+                      $post_match->merge_text(  $prev_sibling);
+                    }
+                }
+            }
+        }
+      return $elt;
+    }
+
+
+  sub _is_string
+    { return ($_[0]=~ m{&e[ln]t}) ? 0: 1 }
+
+  sub _replace_var
+    { my( $string, @var)= @_;
+      unshift @var, undef;
+      $string=~ s{\$(\d)}{$var[$1]}g;
+      return $string;
+    }
+
+  sub _install_replace_sub
+    { my $replace_exp= shift;
+      my @item= split m{(&e[ln]t\s*\([^)]*\))}, $replace_exp;
+      my $sub= q{ my( $match, @var)= @_; unshift @var, undef; my $new; };
+      my( $gi, $exp);
+      foreach my $item (@item)
+        { if(    $item=~ m{^&elt\s*\(([^)]*)\)})
+            { $exp= $1;
+            }
+          elsif( $item=~ m{^&ent\s*\(\s*([^\s)]*)\s*\)})
+            { $exp= " '#ENT' => $1"; }
+          else
+            { $exp= qq{ '#PCDATA' => "$item"}; }
+          $exp=~ s{\$(\d)}{\$var[$1]}g; # replace references to matches
+          $sub.= qq{ \$new= XML::Twig::Elt->new( $exp); };
+          $sub .= q{ $new->paste( before => $match); };
+        }
+      $sub .= q{ $match->delete; };
+      #$sub=~ s/;/;\n/g;
+      my $coderef= eval "sub { $sub }";
+      if( $@) { croak( "invalid replacement expression $replace_exp: ",$@); }
+      return $coderef;
+    }
+
+  }
+
+
+sub merge_text
+  { my( $e1, $e2)= @_;
+    croak "invalid merge: can only merge 2 elements" 
+        unless( isa( $e2, 'XML::Twig::Elt'));
+    croak "invalid merge: can only merge 2 text elements" 
+        unless( $e1->is_text && $e2->is_text && ($e1->gi eq $e2->gi));
+    $e1->set_text( $e1->text . $e2->text);
+    $e2->delete;
+    return $e1;
+  }
+
+
+# recursively copy an element and returns the copy (can be huge and long)
+sub copy
+  { my $elt= shift;
+    my $copy= XML::Twig::Elt->new( $XML::Twig::index2gi[$elt->{'gi'}]);
+
+    $copy->set_extra_data( $elt->extra_data) if( $elt->extra_data);
+    $copy->set_asis                          if( $elt->is_asis);
+    if( ($elt->{'empty'} || 0)) { $copy->{empty}= 1; } # do not swap or speedup will mess up this                         
+
+    if( (exists $elt->{'pcdata'}))
+      { $copy->{pcdata}=  $elt->{pcdata}; }
+    elsif( (exists $elt->{'cdata'}))
+      { $copy->{cdata}=  $elt->{cdata}; }
+    elsif( (exists $elt->{'target'}))
+      { $copy->set_pi( $elt->{target}, $elt->{data}); }
+    elsif( (exists $elt->{'comment'}))
+      { $copy->{comment}=  $elt->{comment}; }
+    elsif( (exists $elt->{'ent'}))
+      { $copy->{ent}=  $elt->{ent}; }
+    else
+      { my @children= $elt->children;
+        if( my $atts= $elt->atts)
+          { my %atts= %{$atts}; # we want to do a real copy of the attributes
+            $copy->set_atts( \%atts);
+          }
+        foreach my $child (@children)
+          { my $child_copy= $child->copy;
+            $child_copy->paste( 'last_child', $copy);
+          }
+      }
+    return $copy;
+  }
+
+sub delete
+  { my $elt= shift;
+    $elt->cut;
+    $elt->DESTROY unless( $XML::Twig::weakrefs);
+    return undef;
+  }
+
+{ my $current_twig;
+  sub DESTROY
+    { my $elt= shift;
+
+      return if( $XML::Twig::weakrefs);
+
+      foreach( @{[$elt->children]}) { $_->XML::Twig::Elt::DESTROY; }
+      # the id reference needs to be destroyed
+      $elt->del_id if( $ID && exists $elt->{att}->{$ID});
+      undef $elt;
+    }
+}
+
+
+# to be called only from a start_tag_handler: ignores the current element
+sub ignore
+  { my $elt= shift;
+    my $t= $elt->twig;
+    $t->ignore( $elt, @_);
+  }
+
+BEGIN {
+  my $pretty=0;
+  my $quote='"';
+  my $INDENT= '  ';
+  my $empty_tag_style= 0;
+  my $keep_encoding= 0;
+  my $expand_external_entities= 0;
+  my $keep_atts_order=0;
+
+  my ($NSGMLS, $NICE, $INDENTED, $INDENTEDC, $RECORD1, $RECORD2)= (1..6);
+
+  my %pretty_print_style=
+    ( none       => 0,          # no added \n
+      nsgmls     => $NSGMLS,    # nsgmls-style, \n in tags
+      # below this line styles are UNSAFE (the generated XML can be invalid)
+      nice       => $NICE,      # \n after open/close tags except when the 
+                                # element starts with text
+      indented   => $INDENTED,  # nice plus idented
+      indented_c => $INDENTEDC, # slightly more compact than indented (closing
+                                # tags are on the same line)
+      record_c   => $RECORD1,   # for record-like data (compact)
+      record     => $RECORD2,   # for record-like data  (not so compact)
+    );
+
+  my ($HTML, $EXPAND)= (1..2);
+  my %empty_tag_style=
+    ( normal => 0,        # <tag/>
+      html   => $HTML,    # <tag />
+      xhtml  => $HTML,    # <tag />
+      expand => $EXPAND,  # <tag></tag>
+    );
+
+  my %quote_style=
+    ( double  => '"',    
+      single  => "'", 
+      # smart  => "smart", 
+    );
+
+  my $xml_space_preserve; # set when an element includes xml:space="preserve"
+
+  my $output_filter;      # filters the entire output (including < and >)
+  my $output_text_filter; # filters only the text part (tag names, attributes, pcdata)
+
+  # returns those pesky "global" variables so you can switch between twigs 
+  sub global_state
+    { return
+       { pretty                    => $pretty,
+         quote                     => $quote,
+         indent                    => $INDENT,
+         empty_tag_style           => $empty_tag_style,
+         keep_encoding             => $keep_encoding,
+         expand_external_entities  => $expand_external_entities,
+         output_filter             => $output_filter,
+         output_text_filter        => $output_text_filter,
+         keep_atts_order           => $keep_atts_order,
+        };
+    }
+
+  # restores the global variables
+  sub set_global_state
+    { my $state= shift;
+      $pretty                   = $state->{pretty};
+      $quote                    = $state->{quote};
+      $INDENT                   = $state->{indent};
+      $empty_tag_style          = $state->{empty_tag_style};
+      $keep_encoding            = $state->{keep_encoding};
+      $expand_external_entities = $state->{expand_external_entities};
+      $output_filter            = $state->{output_filter};
+      $output_text_filter       = $state->{output_text_filter};
+      $keep_atts_order          = $state->{keep_atts_order};
+    }
+
+  # set the pretty_print style (in $pretty) and returns the old one
+  # can be called from outside the package with 2 arguments (elt, style)
+  # or from inside with only one argument (style)
+  # the style can be either a string (one of the keys of %pretty_print_style
+  # or a number (presumably an old value saved)
+  sub set_pretty_print
+    { my $style= lc( defined $_[1] ? $_[1] : $_[0]); # so we cover both cases 
+      my $old_pretty= $pretty;
+      if( $style=~ /^\d+$/)
+        { croak "invalid pretty print style $style"
+        unless( $style < keys %pretty_print_style);
+        $pretty= $style;
+    }
+      else
+        { croak "invalid pretty print style '$style'"
+            unless( exists $pretty_print_style{$style});
+          $pretty= $pretty_print_style{$style};
+    }
+      return $old_pretty;
+    }
+  
+  
+  # set the empty tag style (in $empty_tag_style) and returns the old one
+  # can be called from outside the package with 2 arguments (elt, style)
+  # or from inside with only one argument (style)
+  # the style can be either a string (one of the keys of %empty_tag_style
+  # or a number (presumably an old value saved)
+  sub set_empty_tag_style
+    { my $style= lc( defined $_[1] ? $_[1] : $_[0]); # so we cover both cases 
+      my $old_style= $empty_tag_style;
+      if( $style=~ /^\d+$/)
+        { croak "invalid empty tag style $style"
+        unless( $style < keys %empty_tag_style);
+        $empty_tag_style= $style;
+    }
+      else
+        { croak "invalid empty tag style '$style'"
+            unless( exists $empty_tag_style{$style});
+          $empty_tag_style= $empty_tag_style{$style};
+    }
+      return $old_style;
+    }
+      
+  sub set_quote
+    { my $style= $_[1] || $_[0];
+      my $old_quote= $quote;
+      croak "invalid quote '$style'" unless( exists $quote_style{$style});
+      $quote= $quote_style{$style};
+      return $old_quote;
+    }
+      
+  sub set_indent
+    { my $new_value= defined $_[1] ? $_[1] : $_[0];
+      my $old_value= $INDENT;
+      $INDENT= $new_value;
+      return $old_value;
+    }
+       
+  sub set_keep_encoding
+    { my $new_value= defined $_[1] ? $_[1] : $_[0];
+      my $old_value= $keep_encoding;
+      $keep_encoding= $new_value;
+      return $old_value;
+    
+   }
+
+  sub keep_encoding { return $keep_encoding; } # so I can use elsewhere in the module
+
+  sub output_filter      { return $output_filter; }
+  sub output_text_filter { return $output_text_filter; }
+
+  sub set_output_filter
+    { my $new_value= defined $_[1] ? $_[1] : $_[0]; # can be called in object/non-object mode
+      # if called in object mode with no argument, the filter is undefined
+      if( isa( $new_value, 'XML::Twig::Elt') || isa( $new_value, 'XML::Twig')) { undef $new_value; }
+      my $old_value= $output_filter;
+      if( !$new_value || isa( $new_value, 'CODE') )
+        { $output_filter= $new_value; }
+      elsif( $new_value eq 'latin1')
+        { $output_filter= XML::Twig::latin1();
+        }
+      elsif( $XML::Twig::filter{$new_value})
+        {  $output_filter= $XML::Twig::filter{$new_value}; }
+      else
+        { croak "invalid output filter '$new_value'"; }
+      
+      return $old_value;
+    }
+       
+  sub set_output_text_filter
+    { my $new_value= defined $_[1] ? $_[1] : $_[0]; # can be called in object/non-object mode
+      # if called in object mode with no argument, the filter is undefined
+      if( isa( $new_value, 'XML::Twig::Elt') || isa( $new_value, 'XML::Twig')) { undef $new_value; }
+      my $old_value= $output_text_filter;
+      if( !$new_value || isa( $new_value, 'CODE') )
+        { $output_text_filter= $new_value; }
+      elsif( $new_value eq 'latin1')
+        { $output_text_filter= XML::Twig::latin1();
+        }
+      elsif( $XML::Twig::filter{$new_value})
+        {  $output_text_filter= $XML::Twig::filter{$new_value}; }
+      else
+        { croak "invalid output text filter '$new_value'"; }
+      
+      return $old_value;
+    }
+       
+  sub set_expand_external_entities
+    { my $new_value= defined $_[1] ? $_[1] : $_[0];
+      my $old_value= $expand_external_entities;
+      $expand_external_entities= $new_value;
+      return $old_value;
+    }
+       
+  sub set_keep_atts_order
+    { my $new_value= defined $_[1] ? $_[1] : $_[0];
+      my $old_value= $keep_atts_order;
+      $keep_atts_order= $new_value;
+      return $old_value;
+    
+   }
+
+  sub keep_atts_order { return $keep_atts_order; } # so I can use elsewhere in the module
+
+  # $elt is an element to print
+  # $pretty is an optional value, if true a \n is printed after the <
+
+  my %empty_should_be_expanded= ( script => 1);
+
+  sub start_tag
+    { my $elt= shift;
+  
+      return if( $elt->{gi}<$XML::Twig::SPECIAL_GI);
+
+      my $extra_data= $elt->{extra_data} || '';
+
+      my $gi= $XML::Twig::index2gi[$elt->{'gi'}];
+
+      my $ns_map= $elt->{'att'}->{'#original_gi'};
+      if( $ns_map) { $gi= _restore_original_prefix( $ns_map, $gi); }
+ 
+      if( $output_text_filter) { $gi= $output_text_filter->( $gi); }
+
+      my $tag="<" . $gi;
+  
+      # get the attribute and their values
+      my $att= $elt->atts;
+      if( $att)
+        { foreach my $att_name ( $keep_atts_order ?  keys %{$att} : sort keys %{$att}) 
+           { # skip private attributes (they start with #)
+             next if( (substr( $att_name, 0, 1) eq '#'));
+
+             $tag .=  $pretty==$NSGMLS ? "\n" : ' ';
+
+             my $output_att_name= $ns_map ? _restore_original_prefix( $ns_map, $att_name) : $att_name;
+             if( $output_text_filter) { $output_att_name=  $output_text_filter->( $output_att_name); }
+
+             $tag .= $output_att_name . '=' . $quote . $elt->att_xml_string( $att_name, $quote) . $quote; 
+           }
+        } 
+  
+      $tag .= "\n" if($pretty==$NSGMLS);
+
+      if( $elt->{empty})
+        { if( !$empty_tag_style)
+            { $tag .= "/>";     }
+          elsif( ($empty_tag_style eq $HTML) && ! $empty_should_be_expanded{$XML::Twig::index2gi[$elt->{'gi'}]})
+            { $tag .= " />";  }
+          else #  $empty_tag_style eq $EXPAND
+            { $tag .= "></" . $XML::Twig::index2gi[$elt->{'gi'}] .">";  }
+        }
+      else
+        { $tag .= ">"; }
+
+      if( (substr( $XML::Twig::index2gi[$elt->{'gi'}], 0, 1) eq '#')) { $tag= ''; }
+
+      unless( $pretty) { return $extra_data . $tag  }
+
+      my $prefix='';
+      my $return='';   # '' or \n is to be printed before the tag
+      my $indent=0;    # number of indents before the tag
+
+      if( $pretty==$RECORD1)
+        { my $level= $elt->level;
+          $return= "\n" if( $level < 2);
+          $indent= 1 if( $level == 1);
+        }
+
+     elsif( $pretty==$RECORD2)
+        { $return= "\n";
+          $indent= $elt->level;
+        }
+
+      elsif( $pretty==$NICE)
+        { my $parent= $elt->{parent};
+          unless( !$parent || $parent->{contains_text}) 
+            { $return= "\n"; }
+          $elt->{contains_text}= 1 if( ($parent && $parent->{contains_text})
+                                     || $elt->contains_text);
+        }
+
+      elsif( ($pretty==$INDENTED) || ($pretty==$INDENTEDC))
+        { my $parent= $elt->{parent};
+          unless( !$parent || $parent->{contains_text}) 
+            { $return= "\n"; 
+              $indent= $elt->level; 
+            }
+          $elt->{contains_text}= 1 if( ($parent && $parent->{contains_text})
+                                     || $elt->contains_text);
+        }
+
+      if( $return || $indent)
+        { # check for elements in which spaces should be kept
+          my $t= $elt->twig;
+          return $extra_data . $tag if( $xml_space_preserve);
+          if( $t && $t->{twig_keep_spaces_in})
+            { foreach my $ancestor ($elt->ancestors)
+                { return $extra_data . $tag if( $t->{twig_keep_spaces_in}->{$XML::Twig::index2gi[$ancestor->{'gi'}]}) }
+                }
+        
+              $prefix= $INDENT x $indent;
+              if( $extra_data)
+                { $extra_data=~ s{\s+$}{};
+                  $extra_data= $prefix .  $extra_data . $return;
+                }
+        }
+
+      return $return . $extra_data . $prefix . $tag;
+    }
+  
+  sub end_tag
+    { my $elt= shift;
+      return  '' if( ($elt->{gi}<$XML::Twig::SPECIAL_GI) || ($elt->{'empty'} || 0));
+      my $tag= "<";
+      $tag.= "\n" if($pretty==$NSGMLS);
+
+      my $gi= $XML::Twig::index2gi[$elt->{'gi'}];
+
+      if( my $map= $elt->{'att'}->{'#original_gi'}) { $gi= _restore_original_prefix( $map, $gi); }
+
+      if( $output_text_filter) { $gi= $output_text_filter->( $XML::Twig::index2gi[$elt->{'gi'}]); } 
+      $tag .=  "/$gi>";
+
+      $tag = ($elt->{extra_data_before_end_tag} || '') . $tag;
+
+      if( (substr( $XML::Twig::index2gi[$elt->{'gi'}], 0, 1) eq '#')) { $tag= ''; }
+
+      return $tag unless $pretty;
+
+      my $prefix='';
+      my $return=0;    # 1 if a \n is to be printed before the tag
+      my $indent=0;    # number of indents before the tag
+
+      if( $pretty==$RECORD1)
+        { $return= 1 if( $elt->level == 0);
+        }
+
+     elsif( $pretty==$RECORD2)
+        { unless( $elt->contains_text)
+            { $return= 1 ;
+              $indent= $elt->level;
+            }
+        }
+
+      elsif( $pretty==$NICE)
+        { my $parent= $elt->{parent};
+          if( (    ($parent && !$parent->{contains_text}) || !$parent )
+            && ( !$elt->{contains_text}  
+             && ($elt->{has_flushed_child} || $elt->_first_child())           
+           )
+         )
+            { $return= 1; }
+        }
+
+      elsif( $pretty==$INDENTED)
+        { my $parent= $elt->{parent};
+          if( (    ($parent && !$parent->{contains_text}) || !$parent )
+            && ( !$elt->{contains_text}  
+             && ($elt->{has_flushed_child} || $elt->_first_child())           
+           )
+         )
+            { $return= 1; 
+              $indent= $elt->level; 
+            }
+        }
+
+      if( $return || $indent)
+        { # check for elements in which spaces should be kept
+          my $t= $elt->twig;
+          return $tag if( $xml_space_preserve);
+          if( $t && $t->{twig_keep_spaces_in})
+            { foreach my $ancestor ($elt, $elt->ancestors)
+                { return $tag if( $t->{twig_keep_spaces_in}->{$XML::Twig::index2gi[$ancestor->{'gi'}]}) }
+            }
+      
+          $prefix= "\n" if( $return);
+          $prefix.= $INDENT x $indent;
+    }
+
+      # add a \n at the end of the document (after the root element)
+      $tag .= "\n" unless( $elt->{parent});
+  
+      return $prefix . $tag;
+    }
+
+  sub _restore_original_prefix
+    { my( $map, $name)= @_;
+      my $prefix= _ns_prefix( $name);
+      if( my $original_prefix= $map->{$prefix})
+        { if( $original_prefix eq '#default')
+            { $name=~ s{^$prefix:}{}; }
+          else
+            { $name=~ s{^$prefix(?=:)}{$original_prefix}; }
+        }
+      return $name;
+    }
+
+  # $elt is an element to print
+  # $fh is an optional filehandle to print to
+  # $pretty is an optional value, if true a \n is printed after the < of the
+  # opening tag
+  sub print
+    { my $elt= shift;
+  
+      my $pretty;
+      my $fh= _is_fh( $_[0]) ? shift : undef;
+      my $old_select= defined $fh ? select $fh : undef;
+      my $old_pretty= defined ($pretty= shift) ? set_pretty_print( $pretty) : undef;
+
+      $xml_space_preserve= 1 if( ($elt->inherit_att( 'xml:space') || '') eq 'preserve');
+ 
+      #$elt->_print;
+      print $elt->_sprint;
+
+      $xml_space_preserve= 0;
+    
+      select $old_select if( defined $old_select);
+      set_pretty_print( $old_pretty) if( defined $old_pretty);
+    }
+      
+  
+  # same as output but does not output the start tag if the element
+  # is marked as flushed
+  sub flush
+    { my $elt= shift;
+      $elt->twig->flush( @_);
+    }
+  
+  sub _flush
+    { my $elt= shift;
+  
+      my $pretty;
+      my $fh=  _is_fh( $_[0]) ? shift : undef;
+      my $old_select= defined $fh ? select $fh : undef;
+      my $old_pretty= defined ($pretty= shift) ? set_pretty_print( $pretty) : undef;
+
+      $xml_space_preserve= 1 if( ($elt->inherit_att( 'xml:space') || '') eq 'preserve');
+
+      $elt->__flush();
+
+      $xml_space_preserve= 0;
+
+      select $old_select if( defined $old_select);
+      set_pretty_print( $old_pretty) if( defined $old_pretty);
+    }
+
+  sub __flush
+    { my $elt= shift;
+  
+      # in case there's some comments or PI's piggybacking
+      #if( $elt->{extra_data})
+      #  { print $output_filter ? $output_filter->($elt->{extra_data}) 
+      #                         : $elt->{extra_data};
+      #  }
+
+      if( $elt->{gi} >= $XML::Twig::SPECIAL_GI)
+        { my $preserve= ($elt->{'att'}->{'xml:space'} || '') eq 'preserve';
+          $xml_space_preserve++ if $preserve;
+          unless( $elt->_flushed)
+            { print $elt->start_tag();
+            }
+      
+          # flush the children
+          my @children= $elt->children;
+          foreach my $child (@children)
+            { $child->_flush( $pretty); 
+        }
+          print $elt->end_tag;
+          $xml_space_preserve-- if $preserve;
+          # used for pretty printing
+          if( my $parent= $elt->{parent}) { $parent->{has_flushed_child}= 1; }
+        }
+      else # text or special element
+        { my $text;
+          if( (exists $elt->{'pcdata'}))     { $text= $elt->pcdata_xml_string; 
+                                     if( my $parent= $elt->{parent}) 
+                                       { $parent->{contains_text}= 1; }
+                                   }
+          elsif( (exists $elt->{'cdata'}))   { $text= $elt->cdata_string;        
+                                     if( my $parent= $elt->{parent}) 
+                                       { $parent->{contains_text}= 1; }
+                                   }
+          elsif( (exists $elt->{'target'}))      { $text= $elt->pi_string;          }
+          elsif( (exists $elt->{'comment'})) { $text= $elt->comment_string;     }
+          elsif( (exists $elt->{'ent'}))     { $text= $elt->ent_string;         }
+
+          print $output_filter ? $output_filter->( $text) : $text;
+        }
+    }
+  
+
+  sub xml_text
+    { my $elt= shift;
+      my $string='';
+
+      if( $elt->{gi} >= $XML::Twig::SPECIAL_GI)
+        { # sprint the children
+          my $child= $elt->{first_child}||'';
+          while( $child)
+            { $string.= $child->xml_text;
+              $child= $child->{next_sibling};
+            }
+        }
+      elsif( (exists $elt->{'pcdata'}))  { $string .= $output_filter ?  $output_filter->($elt->pcdata_xml_string) 
+                                                           : $elt->pcdata_xml_string; 
+                               }
+      elsif( (exists $elt->{'cdata'}))   { $string .= $output_filter ?  $output_filter->($elt->cdata_xml_string)  
+                                                           : $elt->cdata_string;      
+                               }
+      elsif( (exists $elt->{'ent'}))     { $string .= $elt->ent_string; }
+
+      return $string;
+    }
+
+
+  # same as print but except... it does not print but rather returns the string
+  # if the second parameter is set then only the content is returned, not the
+  # start and end tags of the element (but the tags of the included elements are
+  # returned)
+  sub sprint
+    { my $elt= shift;
+
+      $xml_space_preserve= 1 if( ($elt->inherit_att( 'xml:space') || '') eq 'preserve');
+
+      my $sprint= $output_filter ? $output_filter->( $elt->_sprint( @_)) : $elt->_sprint( @_);
+
+      $xml_space_preserve= 0;
+
+      return $sprint;
+
+    }
+  
+  sub _sprint
+    { my $elt= shift;
+      my $no_tag= shift || 0;
+      # in case there's some comments or PI's piggybacking
+      my $string='';
+      #if( $elt->{extra_data} && !$no_tag)
+      #  { $string= $elt->{extra_data};
+      #  }
+
+      if( $elt->{gi} >= $XML::Twig::SPECIAL_GI)
+        {
+          my $preserve= ($elt->{'att'}->{'xml:space'} || '') eq 'preserve';
+          $xml_space_preserve++ if $preserve;
+
+          $string.= $elt->start_tag unless( $no_tag);
+      
+          # sprint the children
+          my $child= $elt->{first_child}||'';
+          while( $child)
+            { $string.= $child->_sprint;
+              $child= $child->{next_sibling};
+            }
+          $string.= $elt->end_tag unless( $no_tag);
+          $xml_space_preserve-- if $preserve;
+        }
+      else
+        { $string .= $elt->{extra_data} || '';
+             if( (exists $elt->{'pcdata'}))  { $string .= $elt->pcdata_xml_string; }
+          elsif( (exists $elt->{'cdata'}))   { $string .= $elt->cdata_string;      }
+          elsif( (exists $elt->{'target'}))      { $string .= $elt->pi_string;         }
+          elsif( (exists $elt->{'comment'})) { $string .= $elt->comment_string;    }
+          elsif( (exists $elt->{'ent'}))     { $string .= $elt->ent_string;        }
+        }
+
+      return $string;
+    }
+
+  # just a shortcut to $elt->sprint( 1)
+  sub xml_string
+    { $_[0]->sprint( 1); }
+
+  sub pcdata_xml_string 
+    { my $string='';
+      if( defined( $string= $_[0]->{pcdata}) )
+        { $string=~ s/([&<])/$XML::Twig::base_ent{$1}/g
+            unless( $keep_encoding || $_[0]->{asis}); 
+        }
+      return $output_text_filter ? $output_text_filter->( $string) : $string;
+    }
+  
+  sub att_xml_string 
+    { my $elt= shift;
+      my $att= shift;
+      my $quote= shift || '"';
+      my $string='';
+      if( defined ($string= $elt->{att}->{$att}))
+        { $string=~ s/([$quote<&])/$XML::Twig::base_ent{$1}/g
+            unless( $keep_encoding); 
+        }
+      return $output_text_filter ? $output_text_filter->( $string) : $string;
+    }
+
+  sub ent_string 
+    { my $ent= shift;
+      my $ent_text= $ent->{ent};
+      my( $t, $el, $ent_string);
+      if(    $expand_external_entities
+          && ($t= $ent->twig) 
+          && ($el= $t->entity_list)
+          && ($ent_string= $el->{$ent->ent_name}->{val})
+        )
+       { return $ent_string; }
+  
+       return $ent_text; 
+    }
+
+  # returns just the text, no tags, for an element
+  sub text
+    { my $elt= shift;
+      my $string;
+  
+      if( (exists $elt->{'pcdata'}))     { return  $elt->{pcdata};   }
+      elsif( (exists $elt->{'cdata'}))   { return  $elt->{cdata};    }
+      elsif( (exists $elt->{'target'}))      { return  $elt->pi_string;}
+      elsif( (exists $elt->{'comment'})) { return  $elt->{comment};  }
+      elsif( (exists $elt->{'ent'}))     { return  $elt->{ent} ;     }
+  
+      my $child= $elt->{first_child} ||'';
+      while( $child)
+        { $string.= defined($child->text) ? $child->text : '';
+          $child= $child->{next_sibling};
+        }
+      unless( defined $string) { $string=''; }
+  
+      return $output_text_filter ? $output_text_filter->( $string) : $string;
+    }
+
+  sub trimmed_text
+    { my $elt= shift;
+      my $text= $elt->text;
+      $text=~ s{\s+}{ }sg;
+      $text=~ s{^\s*}{};
+      $text=~ s{\s*$}{};
+      return $text;
+    }
+
+  # remove cdata sections (turns them into regular pcdata) in an element 
+  sub remove_cdata 
+    { my $elt= shift;
+      foreach my $cdata ($elt->descendants_or_self( CDATA))
+        { if( $keep_encoding)
+            { my $data= $cdata->{cdata};
+              $data=~ s{([&<"'])}{$XML::Twig::base_ent{$1}}g;
+              $cdata->{pcdata}=  $data;
+            }
+          else
+            { $cdata->{pcdata}=  $cdata->{cdata}; }
+          $cdata->set_gi( PCDATA);
+          undef $cdata->{cdata};
+        }
+    }
+
+sub _is_private      { return _is_private_name( $_[0]->gi); }
+sub _is_private_name { return $_[0]=~ m{^#};                }
+
+
+} # end of block containing package globals ($pretty_print, $quotes, keep_encoding...)
+
+
+# SAX export methods
+sub toSAX1
+  { _toSAX(@_, \&_start_tag_data_SAX1, \&_end_tag_data_SAX1); }
+
+sub toSAX2
+  { _toSAX(@_, \&_start_tag_data_SAX2, \&_end_tag_data_SAX2); }
+
+sub _toSAX
+  { my( $elt, $handler, $start_tag_data, $end_tag_data)= @_;
+    if( $elt->{gi} >= $XML::Twig::SPECIAL_GI)
+      { my $data= $start_tag_data->( $elt);
+        _start_prefix_mapping( $elt, $handler, $data);
+        if( $data && (my $start_element = $handler->can( 'start_element')))
+          { $start_element->( $handler, $data) unless( $elt->_flushed); }
+      
+        foreach my $child ($elt->children)
+          { $child->_toSAX( $handler, $start_tag_data, $end_tag_data); }
+
+        if( (my $data= $end_tag_data->( $elt)) && (my $end_element = $handler->can( 'end_element')) )
+          { $end_element->( $handler, $data); }
+        _end_prefix_mapping( $elt, $handler);
+      }
+    else # text or special element
+      { if( (exists $elt->{'pcdata'}) && (my $characters= $handler->can( 'characters')))
+          { $characters->( $handler, { Data => $elt->{pcdata} });  }
+        elsif( (exists $elt->{'cdata'}))  
+          { if( my $start_cdata= $handler->can( 'start_cdata'))
+              { $start_cdata->( $handler); }
+            if( my $characters= $handler->can( 'characters'))
+              { $characters->( $handler, {Data => $elt->{cdata} });  }
+            if( my $end_cdata= $handler->can( 'end_cdata'))
+              { $end_cdata->( $handler); }
+          }
+        elsif( ((exists $elt->{'target'}))  && (my $pi= $handler->can( 'processing_instruction')))
+          { $pi->( $handler, { Target =>$elt->{target}, Data => $elt->{data} });  }
+        elsif( ((exists $elt->{'comment'}))  && (my $comment= $handler->can( 'comment')))
+          { $comment->( $handler, { Data => $elt->{comment} });  }
+        elsif( ((exists $elt->{'ent'})))
+          { 
+            if( my $se=   $handler->can( 'skipped_entity'))
+              { $se->( $handler, { Name => $elt->ent_name });  }
+            elsif( my $characters= $handler->can( 'characters'))
+              { if( defined $elt->ent_string)
+                  { $characters->( $handler, {Data => $elt->ent_string});  }
+                else
+                  { $characters->( $handler, {Data => $elt->ent_name});  }
+              }
+          }
+      
+      }
+  }
+  
+sub _start_tag_data_SAX1
+  { my( $elt)= @_;
+    my $name= $XML::Twig::index2gi[$elt->{'gi'}];
+    return if( (substr( $XML::Twig::index2gi[$elt->{'gi'}], 0, 1) eq '#'));
+    my $attributes={};
+    my $atts= $elt->atts;
+    while( my( $att, $value)= each %$atts)
+      { $attributes->{$att}= $value unless( (substr( $att, 0, 1) eq '#')); }
+    my $data= { Name => $name, Attributes => $attributes};
+    return $data;
+  }
+
+sub _end_tag_data_SAX1
+  { my( $elt)= @_;
+    return if( (substr( $XML::Twig::index2gi[$elt->{'gi'}], 0, 1) eq '#'));
+    return  { Name => $XML::Twig::index2gi[$elt->{'gi'}] };
+  } 
+  
+sub _start_tag_data_SAX2
+  { my( $elt)= @_;
+    my $data={};
+    
+    my $name= $XML::Twig::index2gi[$elt->{'gi'}];
+    return if( (substr( $XML::Twig::index2gi[$elt->{'gi'}], 0, 1) eq '#'));
+    $data->{Name}         = $name;
+    $data->{Prefix}       = $elt->ns_prefix; 
+    $data->{LocalName}    = $elt->local_name;
+    $data->{NamespaceURI} = $elt->namespace;
+
+    # save a copy of the data so we can re-use it for the end tag
+    my %sax2_data= %$data;
+    $elt->{twig_elt_SAX2_data}= \%sax2_data;
+   
+    # add the attributes
+    $data->{Attributes}= $elt->_atts_to_SAX2;
+
+    return $data;
+  }
+
+sub _atts_to_SAX2
+  { my $elt= shift;
+    my $SAX2_atts= {};
+    foreach my $att (keys %{$elt->atts})
+      { 
+        next if( (substr( $att, 0, 1) eq '#'));
+        my $SAX2_att={};
+        $SAX2_att->{Name}         = $att;
+        $SAX2_att->{Prefix}       = _ns_prefix( $att); 
+        $SAX2_att->{LocalName}    = _local_name( $att);
+        $SAX2_att->{NamespaceURI} = $elt->namespace( $SAX2_att->{Prefix});
+        $SAX2_att->{Value}        = $elt->{'att'}->{$att};
+        my $SAX2_att_name= "{$SAX2_att->{NamespaceURI}}$SAX2_att->{LocalName}";
+
+        $SAX2_atts->{$SAX2_att_name}= $SAX2_att;
+      }
+    return $SAX2_atts;
+  }
+
+sub _start_prefix_mapping
+  { my( $elt, $handler, $data)= @_;
+    if( my $start_prefix_mapping= $handler->can( 'start_prefix_mapping')
+        and my @new_prefix_mappings= grep { /^\{[^}]*\}xmlns/ || /^\{$XMLNS_URI\}/ } keys %{$data->{Attributes}}
+      )
+      { foreach my $prefix (@new_prefix_mappings)
+          { my $prefix_string= $data->{Attributes}->{$prefix}->{LocalName};
+            if( $prefix_string eq 'xmlns') { $prefix_string=''; }
+            my $prefix_data=
+              {  Prefix       => $prefix_string,
+                 NamespaceURI => $data->{Attributes}->{$prefix}->{Value}
+              };
+            $start_prefix_mapping->( $handler, $prefix_data);
+            $elt->{twig_end_prefix_mapping} ||= [];
+            push @{$elt->{twig_end_prefix_mapping}}, $prefix_string;
+          }
+      }
+  }
+
+sub _end_prefix_mapping
+  { my( $elt, $handler)= @_;
+    if( my $end_prefix_mapping= $handler->can( 'end_prefix_mapping'))
+      { foreach my $prefix (@{$elt->{twig_end_prefix_mapping}})
+          { $end_prefix_mapping->( $handler, { Prefix => $prefix} ); }
+      }
+  }
+             
+sub _end_tag_data_SAX2
+  { my( $elt)= @_;
+    return if( (substr( $XML::Twig::index2gi[$elt->{'gi'}], 0, 1) eq '#'));
+    return $elt->{twig_elt_SAX2_data};
+  } 
+
+
+
+#start-extract twig_node
+sub contains_text
+  { my $elt= shift;
+    my $child= $elt->{first_child};
+    while ($child)
+      { return 1 if( $child->is_text || (exists $child->{'ent'})); 
+        $child= $child->{next_sibling};
+      }
+    return 0;
+  }
+
+#end-extract twig_node
+
+# creates a single pcdata element containing the text as child of the element
+# options: 
+#   - force_pcdata: when set to a true value forces the text to be in a#PCDATA
+#                   even if the original element was a #CDATA
+sub set_text
+  { my( $elt, $string, %option)= @_;
+
+    if( $XML::Twig::index2gi[$elt->{'gi'}] eq PCDATA) 
+      { return $elt->{pcdata}=  $string; }
+    elsif( $XML::Twig::index2gi[$elt->{'gi'}] eq CDATA)  
+      { if( $option{force_pcdata})
+          { $elt->set_gi( PCDATA);
+            $elt->{cdata}= '';
+            return $elt->{pcdata}=  $string;
+      }
+    else
+      { return $elt->{cdata}=  $string; }
+      }
+
+    foreach my $child (@{[$elt->children]})
+      { $child->delete; }
+
+    my $pcdata= XML::Twig::Elt->new( PCDATA, $string);
+    $pcdata->paste( $elt);
+
+    delete $elt->{empty};
+
+    return $elt;
+  }
+
+# set the content of an element from a list of strings and elements
+sub set_content
+  { my $elt= shift;
+
+    return $elt unless defined $_[0];
+
+    # attributes can be given as a hash (passed by ref)
+    if( ref $_[0] eq 'HASH')
+      { my $atts= shift;
+        $elt->del_atts; # usually useless but better safe than sorry
+        $elt->set_atts( $atts);
+        return  $elt unless defined $_[0];
+      }
+
+    # check next argument for #EMPTY
+    if( !(ref $_[0]) && ($_[0] eq EMPTY) ) 
+      { $elt->{empty}= 1; return $elt; }
+
+    # case where we really want to do a set_text, the element is '#PCDATA'
+    # and we only want to add text in it
+    if( ($XML::Twig::index2gi[$elt->{'gi'}] eq PCDATA) && ($#_ == 0) && !( ref $_[0]))
+      { $elt->{pcdata}=  $_[0];
+        return $elt;
+      }
+    elsif( ($XML::Twig::index2gi[$elt->{'gi'}] eq CDATA) && ($#_ == 0) && !( ref $_[0]))
+      { $elt->{cdata}=  $_[0];
+        return $elt;
+      }
+
+    # delete the children
+    # WARNING: potential problem here if the children are used
+    # somewhere else (where?). Will be solved when I use weak refs
+    foreach my $child (@{[$elt->children]})
+      { $child->delete; }
+
+    foreach my $child (@_)
+      { if( isa( $child, 'XML::Twig::Elt'))
+          { # argument is an element
+            $child->paste( 'last_child', $elt);
+          }
+        else
+          { # argument is a string
+            if( (my $pcdata= $elt->{last_child}) && $elt->{last_child}->is_pcdata)
+              { # previous child is also pcdata: just concatenate
+                $pcdata->{pcdata}=  $pcdata->{pcdata} . $child 
+              }
+            else
+              { # previous child is not a string: creat a new pcdata element
+                $pcdata= XML::Twig::Elt->new( PCDATA, $child);
+                $pcdata->paste( 'last_child', $elt);  
+              }
+          }
+      }
+
+    delete $elt->{empty};
+
+    return $elt;
+  }
+
+# inserts an element (whose gi is given) as child of the element
+# all children of the element are now children of the new element
+# returns the new element
+sub insert
+  { my ($elt, @args)= @_;
+    # first cut the children
+    my @children= $elt->children;
+    foreach my $child (@children)
+      { $child->cut; }
+    # insert elements
+    while( my $gi= shift @args)
+      { my $new_elt= XML::Twig::Elt->new( $gi);
+        # add attributes if needed
+        if( defined( $args[0]) && ( isa( $args[0], 'HASH')) )
+          { $new_elt->set_atts( shift @args); }
+        # paste the element
+        $new_elt->paste( $elt);
+        delete $elt->{empty};
+        $elt= $new_elt;
+      }
+    # paste back the children
+    foreach my $child (@children)
+      { $child->paste( 'last_child', $elt); }
+    return $elt;
+  }
+
+# insert a new element 
+# $elt->insert_new_element( $opt_position, $gi, $opt_atts_hash, @opt_content); 
+# the element is created with the same syntax as new
+# position is the same as in paste, first_child by default
+sub insert_new_elt
+  { my $elt= shift;
+    my $position= $_[0];
+    if(     ($position eq 'before') || ($position eq 'after')
+         || ($position eq 'first_child') || ($position eq 'last_child'))
+      { shift; }
+    else
+      { $position= 'first_child'; }
+
+    my $new_elt= $elt->new( @_);
+    $new_elt->paste( $position, $elt);
+    return $new_elt;
+  }
+
+# wraps an element in elements which gi's are given as arguments
+# $elt->wrap_in( 'td', 'tr', 'table') wraps the element as a single
+# cell in a table for example
+# returns the new element
+sub wrap_in
+  { my $elt= shift;
+    while( my $gi = shift @_)
+      { my $new_elt = XML::Twig::Elt->new( $gi);
+        if( $elt->{twig_current})
+          { my $t= $elt->twig;
+            $t->{twig_current}= $new_elt;
+            delete $elt->{'twig_current'};
+            $new_elt->{'twig_current'}=1;
+          }
+
+        if( my $parent= $elt->{parent})
+          { $new_elt->set_parent( $parent); 
+            $parent->{first_child}=  $new_elt if( $parent->{first_child} == $elt);
+            $parent->set_last_child( $new_elt)  if( $parent->{last_child} == $elt);
+          }
+        else
+          { # wrapping the root
+            my $twig= $elt->twig;
+            if( $twig && $twig->root && ($twig->root eq $elt) )
+              { $twig->{twig_root}= $new_elt; }
+          }
+
+        if( my $prev_sibling= $elt->{prev_sibling})
+          { $new_elt->set_prev_sibling( $prev_sibling);
+            $prev_sibling->{next_sibling}=  $new_elt;
+          }
+
+        if( my $next_sibling= $elt->{next_sibling})
+          { $new_elt->{next_sibling}=  $next_sibling;
+            $next_sibling->set_prev_sibling( $new_elt);
+          }
+        $new_elt->{first_child}=  $elt;
+        $new_elt->set_last_child( $elt);
+
+        $elt->set_parent( $new_elt);
+        $elt->set_prev_sibling( undef);
+        $elt->{next_sibling}=  undef;
+
+        # add the attributes if the next argument is a hash ref
+        if( defined( $_[0]) && (isa( $_[0], 'HASH')) )
+          { $new_elt->set_atts( shift @_); }
+
+        $elt= $new_elt;
+      }
+      
+    return $elt;
+  }
+
+sub replace
+  { my( $elt, $ref)= @_;
+    if( my $parent= $ref->{parent})
+      { $elt->set_parent( $parent);
+        $parent->{first_child}=  $elt if( $parent->{first_child} == $ref);
+        $parent->set_last_child( $elt)  if( $parent->{last_child} == $ref);
+      }
+    if( my $prev_sibling= $ref->{prev_sibling})
+      { $elt->set_prev_sibling( $prev_sibling);
+        $prev_sibling->{next_sibling}=  $elt;
+      }
+    if( my $next_sibling= $ref->{next_sibling})
+      { $elt->{next_sibling}=  $next_sibling;
+        $next_sibling->set_prev_sibling( $elt);
+      }
+   
+    $ref->set_parent( undef);
+    $ref->set_prev_sibling( undef);
+    $ref->{next_sibling}=  undef;
+    return $ref;
+  }
+
+sub replace_with
+  { my $ref= shift;
+    my $elt= shift;
+    $elt->replace( $ref);
+    foreach my $new_elt (reverse @_)
+      { $new_elt->paste( after => $elt); }
+    return $elt;
+  }
+
+
+#start-extract twig_node
+# move an element, same syntax as paste, except the element is first cut
+sub move
+  { my $elt= shift;
+    $elt->cut;
+    $elt->paste( @_);
+    return $elt;
+  }
+#end-extract twig_node
+
+
+# adds a prefix to an element, creating a pcdata child if needed
+sub prefix
+  { my ($elt, $prefix, $option)= @_;
+    my $asis= ($option && ($option eq 'asis')) ? 1 : 0;
+    if( (exists $elt->{'pcdata'}) 
+        && (($asis && $elt->{asis}) || (!$asis && ! $elt->{asis}))
+      )
+      { $elt->{pcdata}=  $prefix . $elt->{pcdata}; }
+    elsif( $elt->{first_child} && $elt->{first_child}->is_pcdata
+        && (   ($asis && $elt->{first_child}->{asis}) 
+            || (!$asis && ! $elt->{first_child}->{asis}))
+         )
+      { $elt->{first_child}->set_pcdata( $prefix . $elt->{first_child}->pcdata); }
+    else
+      { my $new_elt= XML::Twig::Elt->new( PCDATA, $prefix);
+        $new_elt->paste( $elt);
+        $new_elt->set_asis if( $asis);
+      }
+    return $elt;
+  }
+
+# adds a suffix to an element, creating a pcdata child if needed
+sub suffix
+  { my ($elt, $suffix, $option)= @_;
+    my $asis= ($option && ($option eq 'asis')) ? 1 : 0;
+    if( (exists $elt->{'pcdata'})
+        && (($asis && $elt->{asis}) || (!$asis && ! $elt->{asis}))
+      )
+      { $elt->{pcdata}=  $elt->{pcdata} . $suffix; }
+    elsif( $elt->{last_child} && $elt->{last_child}->is_pcdata
+        && (   ($asis && $elt->{last_child}->{asis}) 
+            || (!$asis && ! $elt->{last_child}->{asis}))
+         )
+      { $elt->{last_child}->set_pcdata( $elt->{last_child}->pcdata . $suffix); }
+    else
+      { my $new_elt= XML::Twig::Elt->new( PCDATA, $suffix);
+        $new_elt->paste( 'last_child', $elt);
+        $new_elt->set_asis if( $asis);
+      }
+    return $elt;
+  }
+
+#start-extract twig_node
+# create a path to an element ('/root/.../gi)
+sub path
+  { my $elt= shift;
+    my @context= ( $elt, $elt->ancestors);
+    return "/" . join( "/", reverse map {$_->gi} @context);
+  }
+
+sub xpath
+  { my $elt= shift;
+    my $xpath;
+    foreach my $ancestor (reverse $elt->ancestors_or_self)
+      { my $gi= $XML::Twig::index2gi[$ancestor->{'gi'}];
+        $xpath.= "/$gi";
+        my $index= $ancestor->prev_siblings( $gi) + 1;
+        unless( ($index == 1) && !$ancestor->next_sibling( $gi))
+          { $xpath.= "[$index]"; }
+      }
+    return $xpath;
+  }
+
+# methods used mainly by wrap_children
+
+# return a string with the 
+# for an element <foo><elt att="val">...</elt><elt2/><elt>...</elt></foo>
+# returns '<elt att="val"><elt2><elt>'
+sub _stringify_struct
+  { my( $elt, %opt)= @_;
+    my $string;
+    my $pretty_print= XML::Twig::Elt::set_pretty_print( 'none');
+    foreach my $child ($elt->children)
+      { $child->add_id; $string .= $child->start_tag; }
+    XML::Twig::Elt::set_pretty_print( $pretty_print);
+    return $string;
+  }
+
+# wrap a series of elements in a new one
+sub _wrap_range
+  { my $elt= shift;
+    my $gi= shift;
+    my $atts= isa( $_[0], 'HASH') ? shift : undef;
+    my $range= shift; # the string with the tags to wrap
+
+    my $t= $elt->twig;
+
+    # get the tags to wrap
+    my @to_wrap;
+    while( $range=~ m{<\w+\s+[^>]*id=("[^"]*"|'[^']*')[^>]*>}g)
+      { push @to_wrap, $t->elt_id( substr( $1, 1, -1)); }
+
+    return '' unless @to_wrap;
+    
+    my $to_wrap= shift @to_wrap;
+    my %atts= %$atts;
+    my $new_elt= $to_wrap->wrap_in( $gi, \%atts);
+    $_->move( last_child => $new_elt) foreach (@to_wrap);
+
+    return '';
+  }
+    
+# wrap children matching a regexp in a new element
+sub wrap_children
+  { my( $elt, $regexp, $gi, $atts)= @_;
+
+    $atts ||={};
+
+    my $elt_as_string= $elt->_stringify_struct; # stringify the elt structure
+    $regexp=~ s{(<[^>]*>)}{_match_expr( $1)}eg; # in the regexp, replace gi's by the proper regexp 
+    $elt_as_string=~ s{($regexp)}{$elt->_wrap_range( $gi, $atts, $1)}eg; # then do the actual replace
+  
+    return $elt; 
+  }
+
+sub _match_expr
+  { my $tag= shift;
+    my( $gi, %atts)= XML::Twig::_parse_start_tag( $tag);
+    return _match_tag( $gi, %atts);
+  }
+
+
+sub _match_tag
+  { my( $elt, %atts)= @_;
+    my $string= "<$elt\\b";
+    foreach my $key (sort keys %atts)
+      { my $val= $atts{$key};
+        $val= "\Q$val\E";
+       # my $val= qq{\Q$atts{$key}\E};
+        $string.= qq{[^>]*$key=(?:"$val"|'$val')};
+      }
+    $string.=  qq{[^>]*>};
+    return "(?:$string)";
+  }
+
+sub field_to_att
+  { my( $elt, $cond, $att)= @_;
+    $att ||= $cond;
+    my $child= $elt->first_child( $cond) or return undef;
+    $elt->set_att( $att => $child->text);
+    $child->cut;
+    return $elt;
+  }
+
+sub att_to_field
+  { my( $elt, $att, $tag)= @_;
+    $tag ||= $att;
+    my $child= $elt->insert_new_elt( first_child => $tag, $elt->{'att'}->{$att});
+    $elt->del_att( $att);
+    return $elt;
+  }
+
+# sort children methods
+
+sub sort_children_on_field
+  { my $elt   = shift;
+    my $field = shift;
+    my $get_key= sub { return $_[0]->field( $field) };
+    return $elt->sort_children( $get_key, @_); 
+  }
+
+sub sort_children_on_att
+  { my $elt = shift;
+    my $att = shift;
+    my $get_key= sub { return $_[0]->{'att'}->{$att} };
+    return $elt->sort_children( $get_key, @_); 
+  }
+
+sub sort_children_on_value
+  { my $elt   = shift;
+    #my $get_key= eval qq{ sub { return \$_[0]->text } };
+    my $get_key= \&text;
+    return $elt->sort_children( $get_key, @_); 
+  }
+
+
+sub sort_children
+  { my( $elt, $get_key, %opt)=@_;
+    $opt{order} ||= 'normal';
+    $opt{type}  ||= 'alpha';
+    my( $par_a, $par_b)= ($opt{order} eq 'reverse') ? qw( b a) : qw ( a b) ;
+    my $op= ($opt{type} eq 'numeric') ? '<=>' : 'cmp' ;
+    my @children= $elt->cut_children;
+    if( $opt{type} eq 'numeric')
+      {  @children= map  { $_->[1] }
+                    sort { $a->[0] <=> $b->[0] }
+                    map  { [ $get_key->( $_), $_] } @children;
+      }
+    elsif( $opt{type} eq 'alpha')
+      {  @children= map  { $_->[1] }
+                    sort { $a->[0] cmp $b->[0] }
+                    map  { [ $get_key->( $_), $_] } @children;
+      }
+    else
+      { croak "wrong sort type '$opt{type}', should be either 'alpha' or 'numeric'"; }
+
+    @children= reverse @children if( $opt{order} eq 'reverse');
+    $elt->set_content( @children);
+  }
+
+
+# comparison methods
+
+sub before
+  { my( $a, $b)=@_;
+    if( $a->cmp( $b) == -1) { return 1; } else { return 0; }
+  }
+
+sub after
+  { my( $a, $b)=@_;
+    if( $a->cmp( $b) == 1) { return 1; } else { return 0; }
+  }
+
+sub lt
+  { my( $a, $b)=@_;
+    return 1 if( $a->cmp( $b) == -1);
+    return 0;
+  }
+
+sub le
+  { my( $a, $b)=@_;
+    return 1 unless( $a->cmp( $b) == 1);
+    return 0;
+  }
+
+sub gt
+  { my( $a, $b)=@_;
+    return 1 if( $a->cmp( $b) == 1);
+    return 0;
+  }
+
+sub ge
+  { my( $a, $b)=@_;
+    return 1 unless( $a->cmp( $b) == -1);
+    return 0;
+  }
+
+
+sub cmp
+  { my( $a, $b)=@_;
+
+    # easy cases
+    return  0 if( $a == $b);    
+    return  1 if( $a->in($b)); # a starts after b 
+    return -1 if( $b->in($a)); # a starts before b
+
+    # ancestors does not include the element itself
+    my @a_pile= ($a, $a->ancestors); 
+    my @b_pile= ($b, $b->ancestors);
+
+    # the 2 elements are not in the same twig
+    return undef unless( $a_pile[-1] == $b_pile[-1]);
+
+    # find the first non common ancestors (they are siblings)
+    my $a_anc= pop @a_pile;
+    my $b_anc= pop @b_pile;
+
+    while( $a_anc == $b_anc) 
+      { $a_anc= pop @a_pile;
+        $b_anc= pop @b_pile;
+      }
+
+    # from there move left and right and figure out the order
+    my( $a_prev, $a_next, $b_prev, $b_next)= ($a_anc, $a_anc, $b_anc, $b_anc);
+    while()
+      { $a_prev= $a_prev->{prev_sibling} || return( -1);
+        return 1 if( $a_prev == $b_next);
+        $a_next= $a_next->{next_sibling} || return( 1);
+        return -1 if( $a_next == $b_prev);
+        $b_prev= $b_prev->{prev_sibling} || return( 1);
+        return -1 if( $b_prev == $a_next);
+        $b_next= $b_next->{next_sibling} || return( -1);
+        return 1 if( $b_next == $a_prev);
+      }
+  }
+    
+#end-extract twig_node
+
+1;
+
+
+__END__
+
+=head1 NAME
+
+XML::Twig - A perl module for processing huge XML documents in tree mode.
+
+=head1 SYNOPSIS
+
+Small documents (loaded in memory as a tree):
+
+  my $twig=XML::Twig->new();    # create the twig
+  $twig->parsefile( 'doc.xml'); # build it
+  my_process( $twig);           # use twig methods to process it 
+  $twig->print;                 # output the twig
+
+Huge documents (processed in combined stream/tree mode):
+
+  # at most one div will be loaded in memory
+  my $twig=XML::Twig->new(   
+    twig_handlers => 
+      { title   => sub { $_->set_gi( 'h2') }, # change title tags to h2
+        para    => sub { $_->set_gi( 'p')  }, # change para to p
+        hidden  => sub { $_->delete;       }, # remove hidden elements
+        list    => \&my_list_process,         # process list elements
+        div     => sub { $_[0]->flush;     }, # output and free memory
+      },
+    pretty_print => 'indented',               # output will be nicely formatted
+    empty_tags   => 'html',                   # outputs <empty_tag />
+                         );
+    $twig->flush;                             # flush the end of the document
+
+See L<XML::Twig 101|XML::Twig 101> for other ways to use the module, as a 
+filter for example
+
+Note that this documentation is intended as a reference to the module. A 
+tutorial is available at http://www.xmltwig.com/xmltwig/tutorial/index.html
+and a FAQ is at http://www.xmltwig.com/xmltwig/XML-Twig-FAQ.html
+
+=head1 DESCRIPTION
+
+This module provides a way to process XML documents. It is build on top
+of C<XML::Parser>.
+
+The module offers a tree interface to the document, while allowing you
+to output the parts of it that have been completely processed.
+
+It allows minimal resource (CPU and memory) usage by building the tree
+only for the parts of the documents that need actual processing, through the 
+use of the C<L<twig_roots|twig_roots> > and 
+C<L<twig_print_outside_roots|twig_print_outside_roots> > options. The 
+C<L<finish|finish> > and C<L<finish_print|finish_print> > methods also help 
+to increase performances.
+
+XML::Twig tries to make simple things easy so it tries its best to takes care 
+of a lot of the (usually) annoying (but sometimes necessary) features that 
+come with XML and XML::Parser.
+
+=head1 XML::Twig 101
+
+XML::Twig can be used either on "small" XML documents (that fit in memory)
+or on huge ones, by processing parts of the document and outputting or
+discarding them once they are processed.
+
+
+=head2 Loading an XML document and processing it
+
+  my $t= XML::Twig->new();
+  $t->parse( '<d><title>title</title><para>p 1</para><para>p 2</para></d>');
+  my $root= $t->root;
+  $root->set_gi( 'html');               # change doc to html
+  $title= $root->first_child( 'title'); # get the title
+  $title->set_gi( 'h1');                # turn it into h1
+  my @para= $root->children( 'para');   # get the para children
+  foreach my $para (@para)
+    { $para->set_gi( 'p'); }            # turn them into p
+  $t->print;                            # output the document
+
+Other useful methods include:
+
+L<att|att>: C<< $elt->{'att'}->{'foo'} >> return the C<foo> attribute for an 
+element,
+
+L<set_att|set_att> : C<< $elt->set_att( foo => "bar") >> sets the C<foo> 
+attribute to the C<bar> value,
+
+L<next_sibling|next_sibling>: C<< $elt->{next_sibling} >> return the next sibling
+in the document (in the example C<< $title->{next_sibling} >> is the first
+C<para>, you can also (and actually should) use 
+C<< $elt->next_sibling( 'para') >> to get it 
+
+The document can also be transformed through the use of the L<cut|cut>, 
+L<copy|copy>, L<paste|paste> and L<move|move> methods: 
+C<< $title->cut; $title->paste( after => $p); >> for example
+
+And much, much more, see L<Elt|"Elt">.
+
+=head2 Processing an XML document chunk by chunk
+
+One of the strengths of XML::Twig is that it let you work with files that do 
+not fit in memory (BTW storing an XML document in memory as a tree is quite
+memory-expensive, the expansion factor being often around 10).
+
+To do this you can define handlers, that will be called once a specific 
+element has been completely parsed. In these handlers you can access the
+element and process it as you see fit, using the navigation and the
+cut-n-paste methods, plus lots of convenient ones like C<L<prefix|prefix> >.
+Once the element is completely processed you can then C<L<flush|flush> > it, 
+which will output it and free the memory. You can also C<L<purge|purge> > it 
+if you don't need to output it (if you are just extracting some data from 
+the document for example). The handler will be called again once the next 
+relevant element has been parsed.
+
+  my $t= XML::Twig->new( twig_handlers => 
+                          { section => \&section,
+                            para   => sub { $_->set_tag( 'p');
+                          },
+                       );
+  $t->parsefile( 'doc.xml');
+  $t->flush; # don't forget to flush one last time in the end or anything
+             # after the last </section> tag will not be output 
+    
+  # the handler is called once a section is completely parsed, ie when 
+  # the end tag for section is found, it receives the twig itself and
+  # the element (including all its sub-elements) as arguments
+  sub section 
+    { my( $t, $section)= @_;      # arguments for all twig_handlers
+      $section->set_tag( 'div');  # change the tag name.4, my favourite method...
+      # let's use the attribute nb as a prefix to the title
+      my $title= $section->first_child( 'title'); # find the title
+      my $nb= $title->{'att'}->{'nb'}; # get the attribute
+      $title->prefix( "$nb - ");  # easy isn't it?
+      $section->flush;            # outputs the section and frees memory
+    }
+
+        
+There is of course more to it: you can trigger handlers on more elaborate 
+conditions than just the name of the element, C<section/title> for example.
+
+  my $t= XML::Twig->new( twig_handlers => 
+                           { 'section/title' => sub { $_->print } }
+                       )
+                  ->parsefile( 'doc.xml');
+
+Here C<< sub { $_->print } >> simply prints the current element (C<$_> is aliased
+to the element in the handler).
+
+You can also trigger a handler on a test on an attribute:
+
+  my $t= XML::Twig->new( twig_handlers => 
+                      { 'section[@level="1"]' => sub { $_->print } }
+                       );
+                  ->parsefile( 'doc.xml');
+
+You can also use C<L<start_tag_handlers|start_tag_handlers> > to process an 
+element as soon as the start tag is found. Besides C<L<prefix|prefix> > you
+can also use C<L<suffix|suffix> >, 
+
+=head2 Processing just parts of an XML document
+
+The twig_roots mode builds only the required sub-trees from the document
+Anything outside of the twig roots will just be ignored:
+
+  my $t= XML::Twig->new( 
+       # the twig will include just the root and selected titles 
+           twig_roots   => { 'section/title' => \&print_n_purge,
+                             'annex/title'   => \&print_n_purge
+           }
+                      );
+  $t->parsefile( 'doc.xml');
+  
+  sub print_n_purge 
+    { my( $t, $elt)= @_;
+      print $elt->text;    # print the text (including sub-element texts)
+      $t->purge;           # frees the memory
+    }
+
+You can use that mode when you want to process parts of a documents but are
+not interested in the rest and you don't want to pay the price, either in
+time or memory, to build the tree for the it.
+
+
+=head2 Building an XML filter
+
+You can combine the C<twig_roots> and the C<twig_print_outside_roots> options to 
+build filters, which let you modify selected elements and will output the rest 
+of the document as is.
+
+This would convert prices in $ to prices in Euro in a document:
+
+  my $t= XML::Twig->new( 
+           twig_roots   => { 'price' => \&convert, },   # process prices 
+           twig_print_outside_roots => 1,               # print the rest
+                      );
+  $t->parsefile( 'doc.xml');
+ 
+  sub convert 
+    { my( $t, $price)= @_;
+      my $currency=  $price->{'att'}->{'currency'};          # get the currency
+      if( $currency eq 'USD')
+        { $usd_price= $price->text;                     # get the price
+          # %rate is just a conversion table 
+          my $euro_price= $usd_price * $rate{usd2euro};
+          $price->set_text( $euro_price);               # set the new price
+          $price->set_att( currency => 'EUR');          # don't forget this!
+        }
+      $price->print;                                    # output the price
+    }
+
+=head2 XML::Twig and various versions of Perl, XML::Parser and expat:
+
+Before being uploaded to CPAN, XML::Twig 3.14 has been tested under the 
+following environments:
+
+=over 4
+
+=item linux-x86
+
+perl 5.6.2 to 5.9.1, expat 1.95.2 to 1.95.7, XML::Parser 2.31, 2.33 and 2.34
+perl 5.6.2, XML::Parser 2.27 (which comes with its own version of expat)
+
+=item Mac OS X (10.2)
+
+Mac OS X: same as linux-x86, plus perl 5.5.4
+
+=item Solaris
+
+perl 5.6.1, expat 1.95.2, XML::Parser 2.31
+
+=item Windows 98
+
+perl 5.6.1 (Activestate build 635), XML::Parser 2.27
+perl 5.8.2 (Activestate build 808), XML::Parser 2.34
+
+Note that with Windows 98 and Perl 5.6.1 C<nmake> may freeze while trying to copy
+the tools (xml_grep, xml_print and xml_spellcheck), so you have to answer no 
+when asked if you want to install them.
+
+=back
+
+See L<http://testers.cpan.org/search?request=dist&dist=XML-Twig> for the
+CPAN testers reports on XML::Twig
+
+XML::Twig does B<NOT> work with expat 1.95.4
+XML::Twig only works with XML::Parser 2.27 in perl 5.6.*  
+XML::Parser 2.28 does not really work
+
+When in doubt, upgrade expat, XML::Parser and Scalar::Util
+
+=head1 Simplifying XML processing
+
+=over 4
+
+=item Whitespaces
+
+Whitespaces that look non-significant are discarded, this behaviour can be 
+controlled using the C<L<keep_spaces|keep_spaces> >, 
+C<L<keep_spaces_in|keep_spaces_in> > and 
+C<L<discard_spaces_in|discard_spaces_in> > options.
+
+=item Encoding
+
+You can specify that you want the output in the same encoding as the input
+(provided you have valid XML, which means you have to specify the encoding
+either in the document or when you create the Twig object) using the 
+C<L<keep_encoding|keep_encoding> > option
+
+You can also use C<L<output_encoding>> to convert the internal UTF-8 format
+to the required encoding.
+
+=item Comments and Processing Instructions (PI)
+
+Comments and PI's can be hidden from the processing, but still appear in the
+output (they are carried by the "real" element closer to them)
+
+=item Pretty Printing
+
+XML::Twig can output the document pretty printed so it is easier to read for
+us humans.
+
+=item Surviving an untimely death
+
+XML parsers are supposed to react violently when fed improper XML. 
+XML::Parser just dies.
+
+XML::Twig provides the C<L<safe_parse|safe_parse> > and the 
+C<L<safe_parsefile|safe_parsefile> > methods which wrap the parse in an eval
+and return either the parsed twig or 0 in case of failure.
+
+=item Private attributes
+
+Attributes with a name starting with # (illegal in XML) will not be
+output, so you can safely use them to store temporary values during
+processing. Note that you can store anything in a private attribute, 
+not just text, it's just a regular Perl variable, so a reference to
+an object or a huge data structure is perfectly fine.
+
+=back
+
+=head1 CLASSES
+
+XML::Twig uses a very limited number of classes. The ones you are most likely to use
+are C<L<XML::Twig>> of course, which represents a complete XML document, including the 
+document itself (the root of the document itself is C<L<root>>), its handlers, its
+input or output filters... The other main class is C<L<XML::Twig::Elt>>, which models 
+an XML element. Element here has a very wide definition: it can be a regular element, or
+but also text, with an element C<L<tag>> of C<#PCDATA> (or C<#CDATA>), an entity (tag is
+C<#ENT>), a Processing Instruction (C<#PI>), a comment (C<#COMMENT>). 
+
+Those are the 2 commonly used classes.
+
+You might want to look the C<L<elt_class>> option if you want to subclass C<XML::Twig::Elt>.
+
+Attributes are just attached to their parent element, they are not objects per se. (Please
+use the provided methods C<L<att>> and C<L<set_att>> to access them, if you access them
+as a hash, then your code becomes implementaion de[endant and might break in the future).
+
+Other classes that are seldom used are C<L<XML::Twig::Entity_list>> and C<L<XML::Twig::Entity>>.
+
+If you use C<L<XML::Twig::XPath>> instead of C<XML::Twig>, elements are then created as
+C<L<XML::Twig::XPath::Elt>>
+
+
+=head1 METHODS
+
+=head2 XML::Twig 
+
+A twig is a subclass of XML::Parser, so all XML::Parser methods can be
+called on a twig object, including parse and parsefile.
+C<setHandlers> on the other hand cannot be used, see C<L<BUGS|BUGS> >
+
+
+=over 4
+
+=item new 
+
+This is a class method, the constructor for XML::Twig. Options are passed
+as keyword value pairs. Recognized options are the same as XML::Parser,
+plus some XML::Twig specifics.
+
+New Options:
+
+=over 4
+
+=item twig_handlers
+
+This argument replaces the corresponding XML::Parser argument. It consists
+of a hash C<{ expression => \&handler}> where expression is a 
+I<generic_attribute_condition>, I<string_condition>,
+an I<attribute_condition>,I<full_path>, a I<partial_path>, a I<gi>,
+I<_default_> or I<_all_>.
+
+The idea is to support a usefull but efficient (thus limited) subset of
+XPATH. A fuller expression set will be supported in the future, as users
+ask for more and as I manage to implement it efficiently. This will never
+encompass all of XPATH due to the streaming nature of parsing (no lookahead
+after the element end tag).
+
+A B<generic_attribute_condition> is a condition on an attribute, in the form
+C<*[@att="val"]> or C<*[@att]>, simple quotes can be used instead of double 
+quotes and the leading '*' is actually optional. No matter what the gi of the
+element is, the handler will be triggered either if the attribute has the 
+specified value or if it just exists. 
+
+A B<string_condition> is a condition on the content of an element, in the form
+C<gi[string()="foo"]>, simple quotes can be used instead of double quotes, at 
+the moment you cannot escape the quotes (this will be added as soon as I
+dig out my copy of Mastering Regular Expressions from its storage box).
+The text returned is, as per what I (and Matt Sergeant!) understood from
+the XPATH spec the concatenation of all the text in the element, excluding
+all markup. Thus to call a handler on the elementC<< <p>text <b>bold</b></p> >>
+the appropriate condition is C<p[string()="text bold"]>. Note that this is not
+exactly conformant to the XPATH spec, it just tries to mimic it while being
+still quite concise. 
+
+A extension of that notation is C<gi[string(B<child_gi>)="foo"]> where the
+handler will be called if a child of a C<gi> element has a text value of 
+C<foo>.  At the moment only direct children of the C<gi> element are checked.
+If you need to test on descendants of the element let me know. The fix is
+trivial but would slow down the checks, so I'd like to keep it the way it is.
+
+A B<regexp_condition> is a condition on the content of an element, in the form
+C<gi[string()=~ /foo/"]>. This is the same as a string condition except that
+the text of the element is matched to the regexp. The C<i>, C<m>, C<s> and C<o>
+modifiers can be used on the regexp.
+
+The C<< gi[string(B<child_gi>)=~ /foo/"] >> extension is also supported.
+
+An B<attribute_condition> is a simple condition of an attribute of the
+current element in the form C<gi[@att="val"]> (simple quotes can be used
+instead of double quotes, you can escape quotes either). 
+If several attribute_condition are true the same element all the handlers
+can be called in turn (in the order in which they were first defined).
+If the C<="val"> part is ommited ( the condition is then C<gi[@att]>) then
+the handler is triggered if the attribute actually exists for the element,
+no matter what it's value is.
+
+A B<full_path> looks like C<'/doc/section/chapter/title'>, it starts with
+a / then gives all the gi's to the element. The handler will be called if
+the path to the current element (in the input document) is exactly as
+defined by the C<full_path>.
+
+A B<partial_path> is like a full_path except it does not start with a /:
+C<'chapter/title'> for example. The handler will be called if the path to
+the element (in the input document) ends as defined in the C<partial_path>.
+
+B<WARNING>: (hopefully temporary) at the moment C<string_condition>, 
+C<regexp_condition> and C<attribute_condition> are only supported on a 
+simple gi, not on a path.
+
+A B<gi> (generic identifier) is just a tag name.
+
+#CDATA can be used to call a handler for a CDATA.
+
+A special gi B<_all_> is used to call a function for each element.
+The special gi B<_default_> is used to call a handler for each element
+that does NOT have a specific handler.
+
+The order of precedence to trigger a handler is: 
+I<generic_attribute_condition>, I<string_condition>, I<regexp_condition>, 
+I<attribute_condition>, I<full_path>, longer I<partial_path>, shorter 
+I<partial_path>, I<gi>, I<_default_> . 
+
+B<Important>: once a handler has been triggered if it returns 0 then no other
+handler is called, exept a C<_all_> handler which will be called anyway.
+
+If a handler returns a true value and other handlers apply, then the next
+applicable handler will be called. Repeat, rince, lather..; The exception
+to that rule is when the C<L<do_not_chain_handlers|do_not_chain_handlers>>
+option is set, in which case only the first handler will be called.
+
+Note that it might be a good idea to explicitely return a short true value
+(like 1) from handlers: this ensures that other applicable handlers are 
+called even if the last statement for the handler happens to evaluate to
+false. This might also speedup the code by avoiding the result of the last 
+statement of the code to be copied and passed to the code managing handlers.
+It can really pay to have 1 instead of a long string returned.
+
+When an element is CLOSED the corresponding handler is called, with 2
+arguments: the twig and the C<L</Element|/Element> >. The twig includes the 
+document tree that has been built so far, the element is the complete sub-tree
+for the element. This means that handlers for inner elements are called before
+handlers for outer elements.
+
+C<$_> is also set to the element, so it is easy to write inline handlers like
+
+  para => sub { $_->change_gi( 'p'); }
+
+Text is stored in elements where gi is #PCDATA (due to mixed content, text
+and sub-element in an element there is no way to store the text as just an
+attribute of the enclosing element).
+
+B<Warning>: if you have used purge or flush on the twig the element might not
+be complete, some of its children might have been entirely flushed or purged,
+and the start tag might even have been printed (by C<flush>) already, so changing
+its gi might not give the expected result.
+
+More generally, the I<full_path>, I<partial_path> and I<gi> expressions are
+evaluated against the input document. Which means that even if you have changed
+the gi of an element (changing the gi of a parent element from a handler for
+example) the change will not impact the expression evaluation. Attributes in
+I<attribute_condition> are different though. As the initial value of attribute
+is not stored the handler will be triggered if the B<current> attribute/value
+pair is found when the element end tag is found. Although this can be quite
+confusing it should not impact most of users, and allow others to play clever
+tricks with temporary attributes. Let me know if this is a problem for you.
+
+
+=item twig_roots
+
+This argument let's you build the tree only for those elements you are
+interested in. 
+
+  Example: my $t= XML::Twig->new( twig_roots => { title => 1, subtitle => 1});
+           $t->parsefile( file);
+           my $t= XML::Twig->new( twig_roots => { 'section/title' => 1});
+           $t->parsefile( file);
+
+
+return a twig containing a document including only C<title> and C<subtitle> 
+elements, as children of the root element.
+
+You can use I<generic_attribute_condition>, I<attribute_condition>,
+I<full_path>, I<partial_path>, I<gi>, I<_default_> and I<_all_> to 
+trigger the building of the twig. 
+I<string_condition> and I<regexp_condition> cannot be used as the content 
+of the element, and the string, have not yet been parsed when the condition
+is checked.
+
+B<WARNING>: path are checked for the document. Even if the C<twig_roots> option
+is used they will be checked against the full document tree, not the virtual
+tree created by XML::Twig
+
+
+B<WARNING>: twig_roots elements should NOT be nested, that would hopelessly
+confuse XML::Twig ;--(
+
+Note: you can set handlers (twig_handlers) using twig_roots
+  Example: my $t= XML::Twig->new( twig_roots => 
+                                   { title    => sub { $_{1]->print;}, 
+                                     subtitle => \&process_subtitle 
+                                   }
+                               );
+           $t->parsefile( file);
+ 
+
+=item twig_print_outside_roots
+
+To be used in conjunction with the C<twig_roots> argument. When set to a true 
+value this will print the document outside of the C<twig_roots> elements.
+
+ Example: my $t= XML::Twig->new( twig_roots => { title => \&number_title },
+                                twig_print_outside_roots => 1,
+                               );
+           $t->parsefile( file);
+           { my $nb;
+           sub number_title
+             { my( $twig, $title);
+               $nb++;
+               $title->prefix( "$nb "; }
+               $title->print;
+             }
+           }
+               
+
+This example prints the document outside of the title element, calls 
+C<number_title> for each C<title> element, prints it, and then resumes printing
+the document. The twig is built only for the C<title> elements. 
+
+If the value is a reference to a file handle then the document outside the
+C<twig_roots> elements will be output to this file handle:
+
+  open( OUT, ">out_file") or die "cannot open out file out_file:$!";
+  my $t= XML::Twig->new( twig_roots => { title => \&number_title },
+                         # default output to OUT
+                         twig_print_outside_roots => \*OUT, 
+                       );
+
+         { my $nb;
+           sub number_title
+             { my( $twig, $title);
+               $nb++;
+               $title->prefix( "$nb "; }
+               $title->print( \*OUT);    # you have to print to \*OUT here
+             }
+           }
+
+
+=item start_tag_handlers
+
+A hash C<{ expression => \&handler}>. Sets element handlers that are called when
+the element is open (at the end of the XML::Parser C<Start> handler). The handlers
+are called with 2 params: the twig and the element. The element is empty at 
+that point, its attributes are created though. 
+
+You can use I<generic_attribute_condition>, I<attribute_condition>,
+I<full_path>, I<partial_path>, I<gi>, I<_default_>  and I<_all_> to trigger 
+the handler. 
+
+I<string_condition> and I<regexp_condition> cannot be used as the content of 
+the element, and the string, have not yet been parsed when the condition is 
+checked.
+
+The main uses for those handlers are to change the tag name (you might have to 
+do it as soon as you find the open tag if you plan to C<flush> the twig at some
+point in the element, and to create temporary attributes that will be used
+when processing sub-element with C<twig_hanlders>. 
+
+You should also use it to change tags if you use C<flush>. If you change the tag 
+in a regular C<twig_handler> then the start tag might already have been flushed. 
+
+B<Note>: C<start_tag> handlers can be called outside of C<twig_roots> if this 
+argument is used, in this case handlers are called with the following arguments:
+C<$t> (the twig), C<$gi> (the gi of the element) and C<%att> (a hash of the 
+attributes of the element). 
+
+If the C<twig_print_outside_roots> argument is also used then the start tag
+will be printed if the last handler called returns a C<true> value, if it
+does not then the start tag will B<not> be printed (so you can print a
+modified string yourself for example);
+
+Note that you can use the L<ignore|ignore> method in C<start_tag_handlers> 
+(and only there). 
+
+=item end_tag_handlers
+
+A hash C<{ expression => \&handler}>. Sets element handlers that are called when
+the element is closed (at the end of the XML::Parser C<End> handler). The handlers
+are called with 2 params: the twig and the gi of the element. 
+
+I<twig_handlers> are called when an element is completely parsed, so why have 
+this redundant option? There is only one use for C<end_tag_handlers>: when using
+the C<twig_roots> option, to trigger a handler for an element B<outside> the roots.
+It is for example very useful to number titles in a document using nested 
+sections: 
+
+  my @no= (0);
+  my $no;
+  my $t= XML::Twig->new( 
+          start_tag_handlers => 
+           { section => sub { $no[$#no]++; $no= join '.', @no; push @no, 0; } },
+          twig_roots         => 
+           { title   => sub { $_[1]->prefix( $no); $_[1]->print; } },
+          end_tag_handlers   => { section => sub { pop @no;  } },
+          twig_print_outside_roots => 1
+                      );
+   $t->parsefile( $file);
+
+Using the C<end_tag_handlers> argument without C<twig_roots> will result in an
+error.
+
+=item do_not_chain_handlers
+
+If this option is set to a true value, then only one handler will be called for
+each element, even if several satisfy the condition
+
+Note that the C<_all_> handler will still be called regardeless
+
+=item ignore_elts
+
+This option lets you ignore elements when building the twig. This is useful 
+in cases where you cannot use C<twig_roots> to ignore elements, for example if
+the element to ignore is a sibling of elements you are interested in.
+
+Example:
+
+  my $twig= XML::Twig->new( ignore_elts => { elt => 1 });
+  $twig->parsefile( 'doc.xml');
+
+This will build the complete twig for the document, except that all C<elt> 
+elements (and their children) will be left out.
+
+
+=item char_handler
+
+A reference to a subroutine that will be called every time C<PCDATA> is found.
+
+=item elt_class
+
+The name of a class used to store elements. this class should inherit from
+C<XML::Twig::Elt> (and by default it is C<XML::Twig::Elt>). This option is used
+to subclass the element class and extend it with new methods.
+
+This option is needed because during the parsing of the XML, elements are created
+by C<XML::Twig>, without any control from the user code.
+
+=item keep_atts_order
+
+Setting this option to a true value causes the attribute hash to be tied to
+a Tie::IxHash object.
+This means that Tie::IxHash needs to be installe for this option to be 
+available. It also means that the hash keeps its order, so you will get 
+the attributes in order. This allows outputing the attributes in the same 
+order as they were in the original document.
+
+=item keep_encoding
+
+This is a (slightly?) evil option: if the XML document is not UTF-8 encoded and
+you want to keep it that way, then setting keep_encoding will use theC<Expat> 
+original_string method for character, thus keeping the original encoding, as 
+well as the original entities in the strings.
+
+See the C<t/test6.t> test file to see what results you can expect from the 
+various encoding options.
+
+B<WARNING>: if the original encoding is multi-byte then attribute parsing will
+be EXTREMELY unsafe under any Perl before 5.6, as it uses regular expressions
+which do not deal properly with multi-byte characters. You can specify an 
+alternate function to parse the start tags with the C<parse_start_tag> option 
+(see below)
+
+B<WARNING>: this option is NOT used when parsing with the non-blocking parser 
+(C<parse_start>, C<parse_more>, parse_done methods) which you probably should 
+not use with XML::Twig anyway as they are totally untested!
+
+=item output_encoding
+
+This option generates an output_filter using C<Encode>,  C<Text::Iconv> or 
+C<Unicode::Map8> and C<Unicode::Strings>, and sets the encoding in the XML
+declaration. This is the easiest way to deal with encodings, if you need 
+more sophisticated features, look at C<output_filter> below
+
+
+=item output_filter
+
+This option is used to convert the character encoding of the output document.
+It is passed either a string corresponding to a predefined filter or
+a subroutine reference. The filter will be called every time a document or 
+element is processed by the "print" functions (C<print>, C<sprint>, C<flush>). 
+
+Pre-defined filters: 
+
+=over 4 
+
+=item latin1 
+
+uses either C<Encode>, C<Text::Iconv> or C<Unicode::Map8> and C<Unicode::String>
+or a regexp (which works only with XML::Parser 2.27), in this order, to convert 
+all characters to ISO-8859-1 (aka latin1)
+
+=item html
+
+does the same conversion as C<latin1>, plus encodes entities using
+C<HTML::Entities> (oddly enough you will need to have HTML::Entities intalled 
+for it to be available). This should only be used if the tags and attribute 
+names themselves are in US-ASCII, or they will be converted and the output will
+not be valid XML any more
+
+=item safe
+
+converts the output to ASCII (US) only  plus I<character entities> (C<&#nnn;>) 
+this should be used only if the tags and attribute names themselves are in 
+US-ASCII, or they will be converted and the output will not be valid XML any 
+more
+
+=item safe_hex
+
+same as C<safe> except that the character entities are in hexa (C<&#xnnn;>)
+
+=item encode_convert ($encoding)
+
+Return a subref that can be used to convert utf8 strings to C<$encoding>).
+Uses C<Encode>.
+
+   my $conv = XML::Twig::encode_convert( 'latin1');
+   my $t = XML::Twig->new(output_filter => $conv);
+
+=item iconv_convert ($encoding)
+
+this function is used to create a filter subroutine that will be used to 
+convert the characters to the target encoding using C<Text::Iconv> (which needs
+to be installed, look at the documentation for the module and for the
+C<iconv> library to find out which encodings are available on your system)
+
+   my $conv = XML::Twig::iconv_convert( 'latin1');
+   my $t = XML::Twig->new(output_filter => $conv);
+
+=item unicode_convert ($encoding)
+
+this function is used to create a filter subroutine that will be used to 
+convert the characters to the target encoding using  C<Unicode::Strings> 
+and C<Unicode::Map8> (which need to be installed, look at the documentation 
+for the modules to find out which encodings are available on your system)
+
+   my $conv = XML::Twig::unicode_convert( 'latin1');
+   my $t = XML::Twig->new(output_filter => $conv);
+
+=back
+
+The C<text> and C<att> methods do not use the filter, so their 
+result are always in unicode.
+
+Those predeclared filters are based on subroutines that can be used
+by themselves (as C<XML::Twig::foo>). 
+
+=over 4
+
+=item html_encode ($string)
+
+Use C<HTML::Entities> to encode a utf8 string
+
+=item safe_encode ($string)
+
+Use either a regexp (perl < 5.8) or C<Encode> to encode non-ascii characters
+in the string in C<< &#<nnnn>; >> format
+
+=item safe_encode_hex ($string)
+
+Use either a regexp (perl < 5.8) or C<Encode> to encode non-ascii characters
+in the string in C<< &#x<nnnn>; >> format
+
+=item regexp2latin1 ($string)
+
+Use a regexp to encode a utf8 string into latin 1 (ISO-8859-1). Does not
+work with Perl 5.8.0!
+
+=back
+
+=item output_text_filter
+
+same as output_filter, except it doesn't apply to the brackets and quotes 
+around attribute values. This is useful for all filters that could change
+the tagging, basically anything that does not just change the encoding of
+the output. C<html>, C<safe> and C<safe_hex> are better used with this option.
+
+=item input_filter
+
+This option is similar to C<output_filter> except the filter is applied to 
+the characters before they are stored in the twig, at parsing time.
+
+=item parse_start_tag
+
+If you use the C<keep_encoding> option then this option can be used to replace
+the default parsing function. You should provide a coderef (a reference to a 
+subroutine) as the argument, this subroutine takes the original tag (given
+by XML::Parser::Expat C<original_string()> method) and returns a gi and the
+attributes in a hash (or in a list attribute_name/attribute value).
+
+=item expand_external_ents
+
+When this option is used external entities (that are defined) are expanded
+when the document is output using "print" functions such as C<L<print> >,
+C<L<sprint|sprint> >, C<L<flush|flush> > and C<L<xml_string|xml_string> >. 
+Note that in the twig the entity will be stored as an element whith a 
+gi 'C<#ENT>', the entity will not be expanded there, so you might want to 
+process the entities before outputting it. 
+
+=item load_DTD
+
+If this argument is set to a true value, C<parse> or C<parsefile> on the twig
+will load  the DTD information. This information can then be accessed through 
+the twig, in a C<DTD_handler> for example. This will load even an external DTD.
+
+Note that to do this the module will generate a temporary file in the current
+directory. If this is a problem let me know and I will add an option to
+specify an alternate directory.
+
+See L<DTD Handling|DTD Handling> for more information
+
+=item DTD_handler
+
+Set a handler that will be called once the doctype (and the DTD) have been 
+loaded, with 2 arguments, the twig and the DTD.
+
+=item no_prolog
+
+Does not output a prolog (XML declaration and DTD)
+
+=item id
+
+This optional argument gives the name of an attribute that can be used as
+an ID in the document. Elements whose ID is known can be accessed through
+the elt_id method. id defaults to 'id'.
+See C<L<BUGS|BUGS> >
+
+=item discard_spaces
+
+If this optional argument is set to a true value then spaces are discarded
+when they look non-significant: strings containing only spaces are discarded.
+This argument is set to true by default.
+
+=item keep_spaces
+
+If this optional argument is set to a true value then all spaces in the
+document are kept, and stored as C<PCDATA>.
+C<keep_spaces> and C<discard_spaces> cannot be both set.
+
+=item discard_spaces_in
+
+This argument sets C<keep_spaces> to true but will cause the twig builder to
+discard spaces in the elements listed.
+
+The syntax for using this argument is:
+ 
+  XML::Twig->new( discard_spaces_in => [ 'elt1', 'elt2']);
+
+=item keep_spaces_in
+
+This argument sets C<discard_spaces> to true but will cause the twig builder to
+keep spaces in the elements listed.
+
+The syntax for using this argument is: 
+
+  XML::Twig->new( keep_spaces_in => [ 'elt1', 'elt2']);
+
+=item pretty_print
+
+Set the pretty print method, amongst 'C<none>' (default), 'C<nsgmls>', 
+'C<nice>', 'C<indented>', 'C<indented_c>', 'C<record>' and 'C<record_c>'
+
+pretty_print formats:
+
+=over 4
+
+=item none
+
+The document is output as one ling string, with no line breaks except those 
+found within text elements
+
+=item nsgmls
+
+Line breaks are inserted in safe places: that is within tags, between a tag 
+and an attribute, between attributes and before the > at the end of a tag.
+
+This is quite ugly but better than C<none>, and it is very safe, the document 
+will still be valid (conforming to its DTD).
+
+This is how the SGML parser C<sgmls> splits documents, hence the name.
+
+=item nice
+
+This option inserts line breaks before any tag that does not contain text (so
+element with textual content are not broken as the \n is the significant).
+
+B<WARNING>: this option leaves the document well-formed but might make it
+invalid (not conformant to its DTD). If you have elements declared as
+
+  <!ELEMENT foo (#PCDATA|bar)>
+
+then a C<foo> element including a C<bar> one will be printed as
+
+  <foo>
+  <bar>bar is just pcdata</bar>
+  </foo>
+
+This is invalid, as the parser will take the line break after the C<foo> tag 
+as a sign that the element contains PCDATA, it will then die when it finds the 
+C<bar> tag. This may or may not be important for you, but be aware of it!
+
+=item indented
+
+Same as C<nice> (and with the same warning) but indents elements according to 
+their level 
+
+=item indented_c
+
+Same as C<indented> but a little more compact: the closing tags are on the 
+same line as the preceeding text
+
+=item record
+
+This is a record-oriented pretty print, that display data in records, one field 
+per line (which looks a LOT like C<indented>)
+
+=item record_c
+
+Stands for record compact, one record per line
+
+=back
+
+
+=item empty_tags
+
+Set the empty tag display style ('C<normal>', 'C<html>' or 'C<expand>').
+
+=item comments
+
+Set the way comments are processed: 'C<drop>' (default), 'C<keep>' or 
+'C<process>' 
+
+Comments processing options:
+
+=over 4
+
+=item drop
+
+drops the comments, they are not read, nor printed to the output
+
+=item keep
+
+comments are loaded and will appear on the output, they are not 
+accessible within the twig and will not interfere with processing
+though
+
+B<Bug>: comments in the middle of a text element such as 
+
+  <p>text <!-- comment --> more text --></p>
+
+are output at the end of the text:
+
+  <p>text  more text <!-- comment --></p>
+
+=item process
+
+comments are loaded in the twig and will be treated as regular elements 
+(their C<gi> is C<#COMMENT>) this can interfere with processing if you
+expect C<< $elt->{first_child} >> to be an element but find a comment there.
+Validation will not protect you from this as comments can happen anywhere.
+You can use C<< $elt->first_child( 'gi') >> (which is a good habit anyway)
+to get where you want. 
+
+Consider using C<process> if you are outputing SAX events from XML::Twig.
+
+=back
+
+=item pi
+
+Set the way processing instructions are processed: 'C<drop>', 'C<keep>' 
+(default) or 'C<process>'
+
+Note that you can also set PI handlers in the C<twig_handlers> option: 
+
+  '?'       => \&handler
+  '?target' => \&handler 2
+
+The handlers will be called with 2 parameters, the twig and the PI element if
+C<pi> is set to C<process>, and with 3, the twig, the target and the data if
+C<pi> is set to C<keep>. Of course they will not be called if C<pi> is set to 
+C<drop>.
+
+If C<pi> is set to C<keep> the handler should return a string that will be used
+as-is as the PI text (it should look like "C< <?target data?> >" or '' if you
+want to remove the PI), 
+
+Only one handler will be called, C<?target> or C<?> if no specific handler for
+that target is available.
+
+=item map_xmlns 
+
+This option is passed a hashref that maps uri's to prefixes. The prefixes in
+the document will be replaced by the ones in the map. The mapped prefixes can
+(actually have to) be used to trigger handlers, navigate or query the document.
+
+Here is an example:
+
+  my $t= XML::Twig->new( map_xmlns => {'http://www.w3.org/2000/svg' => "svg"},
+                         twig_handlers => 
+                           { 'svg:circle' => sub { $_->set_att( r => 20) } },
+                         pretty_print => 'indented', 
+                       )
+                  ->parse( '<doc xmlns:gr="http://www.w3.org/2000/svg">
+                              <gr:circle cx="10" cy="90" r="10"/>
+                           </doc>'
+                         )
+                  ->print;
+
+This will output:
+
+  <doc xmlns:svg="http://www.w3.org/2000/svg">
+     <svg:circle cx="10" cy="90" r="20"/>
+  </doc>
+
+Note that this only works when working on the entire twig. If you use C<twig_roots>
+then the namespace processing is not done. I have to keep something to do for the
+next release ;--)
+
+
+=item keep_original_prefix
+
+When used with C<L<map_xmlns>> this option will make C<XML::Twig> use the original
+namespace prefixes when outputing a document. The mapped prefix will still be used
+for triggering handlers and in navigation and query methods.
+
+  my $t= XML::Twig->new( map_xmlns => {'http://www.w3.org/2000/svg' => "svg"},
+                         twig_handlers => 
+                           { 'svg:circle' => sub { $_->set_att( r => 20) } },
+                         keep_original_prefix => 1,
+                         pretty_print => 'indented', 
+                       )
+                  ->parse( '<doc xmlns:gr="http://www.w3.org/2000/svg">
+                              <gr:circle cx="10" cy="90" r="10"/>
+                           </doc>'
+                         )
+                  ->print;
+
+This will output:
+
+  <doc xmlns:gr="http://www.w3.org/2000/svg">
+     <gr:circle cx="10" cy="90" r="20"/>
+  </doc>
+
+=back
+
+B<Note>: I _HATE_ the Java-like name of arguments used by most XML modules.
+So in pure TIMTOWTDI fashion all arguments can be written either as
+C<UglyJavaLikeName> or as C<readable_perl_name>: C<twig_print_outside_roots>
+or C<TwigPrintOutsideRoots> (or even C<twigPrintOutsideRoots> {shudder}). 
+XML::Twig normalizes them before processing them.
+
+=item parse (SOURCE [, OPT => OPT_VALUE [...]])
+
+This method is inherited from XML::Parser.
+The C<SOURCE> parameter should either be a string containing the whole XML
+document, or it should be an open C<IO::Handle>. Constructor options to
+C<XML::Parser::Expat> given as keyword-value pairs may follow theC<SOURCE> 
+parameter. These override, for this call, any options or attributes passed
+through from the XML::Parser instance.
+
+A die call is thrown if a parse error occurs. Otherwise it will return 
+the twig built by the parse. Use C<safe_parse> if you want the parsing
+to return even when an error occurs.
+
+=item parsestring
+
+This is just an alias for C<parse> for backwards compatibility.
+
+=item parsefile (FILE [, OPT => OPT_VALUE [...]])
+
+This method is inherited from XML::Parser.
+
+Open C<FILE> for reading, then call C<parse> with the open handle. The file
+is closed no matter how C<parse> returns. 
+
+A C<die> call is thrown if a parse error occurs. Otherwise it will return 
+the twig built by the parse. Use C<safe_parsefile> if you want the parsing
+to return even when an error occurs.
+
+=item parseurl ($url $optional_user_agent)
+
+Gets the data from C<$url> and parse it. Note that the data is piped to the
+parser in chunks the size of the XML::Parser::Expat buffer, so memory 
+consumption and hopefully speed are optimal.
+
+If the C<$optional_user_agent> argument is used then it is used, otherwise a
+new one is created.
+
+=item safe_parse ( SOURCE [, OPT => OPT_VALUE [...]])
+
+This method is similar to C<parse> except that it wraps the parsing in an
+C<eval> block. It returns the twig on success and 0 on failure (the twig object
+also contains the parsed twig). C<$@> contains the error message on failure.
+
+Note that the parsing still stops as soon as an error is detected, there is
+no way to keep going after an error.
+
+=item safe_parsefile (FILE [, OPT => OPT_VALUE [...]])
+
+This method is similar to C<parsefile> except that it wraps the parsing in an
+C<eval> block. It returns the twig on success and 0 on failure (the twig object
+also contains the parsed twig) . C<$@> contains the error message on failure
+
+Note that the parsing still stops as soon as an error is detected, there is
+no way to keep going after an error.
+
+=item safe_parseurl ($url $optional_user_agent)
+
+Same as C<parseurl> except that it wraps the parsing in an C<eval> block. It 
+returns the twig on success and 0 on failure (the twig object also contains
+the parsed twig) . C<$@> contains the error message on failure
+
+=item parser
+
+This method returns the C<expat> object (actually the XML::Parser::Expat object) 
+used during parsing. It is useful for example to call XML::Parser::Expat methods
+on it. To get the line of a tag for example use C<< $t->parser->current_line >>.
+
+=item setTwigHandlers ($handlers)
+
+Set the twig_handlers. C<$handlers> is a reference to a hash similar to the
+one in the C<twig_handlers> option of new. All previous handlers are unset.
+The method returns the reference to the previous handlers.
+
+=item setTwigHandler ($exp $handler)
+
+Set a single twig_handler for elements matching C<$exp>. C<$handler> is a 
+reference to a subroutine. If the handler was previously set then the reference 
+to the previous handler is returned.
+
+=item setStartTagHandlers ($handlers)
+
+Set the start_tag handlers. C<$handlers> is a reference to a hash similar to the
+one in the C<start_tag_handlers> option of new. All previous handlers are unset.
+The method returns the reference to the previous handlers.
+
+=item setStartTagHandler ($exp $handler)
+
+Set a single start_tag handlers for elements matching C<$exp>. C<$handler> is a 
+reference to a subroutine. If the handler was previously set then the reference
+to the previous handler is returned.
+
+=item setEndTagHandlers ($handlers)
+
+Set the end_tag handlers. C<$handlers> is a reference to a hash similar to the
+one in the C<end_tag_handlers> option of new. All previous handlers are unset.
+The method returns the reference to the previous handlers.
+
+=item setEndTagHandler ($exp $handler)
+
+Set a single end_tag handlers for elements matching C<$exp>. C<$handler> is a 
+reference to a subroutine. If the handler was previously set then the 
+reference to the previous handler is returned.
+
+=item setTwigRoots ($handlers)
+
+Same as using the C<L<twig_roots>> option when creating the twig
+
+=item setCharHandler ($exp $handler)
+
+Set a C<char_handler>
+
+=item setIgnoreEltsHandler ($exp)
+
+Set a C<ignore_elt> handler (elements that match C<$exp> will be ignored
+
+=item setIgnoreEltsHandlers ($exp)
+
+Set all C<ignore_elt> handlers (previous handlers are replaced)
+
+=item dtd
+
+Return the dtd (an L<XML::Twig::DTD> object) of a twig
+
+=item xmldecl
+
+Return the XML declaration for the document, or a default one if it doesn't
+have one
+
+=item doctype
+
+Return the doctype for the document
+
+=item dtd_text
+
+Return the DTD text
+
+=item dtd_print
+
+Print the DTD
+
+=item model ($tag)
+
+Return the model (in the DTD) for the element C<$tag>
+
+=item root
+
+Return the root element of a twig
+
+=item set_root ($elt)
+
+Set the root of a twig
+
+=item first_elt ($optional_condition)
+
+Return the first element matching C<$optional_condition> of a twig, if
+no condition is given then the root is returned
+
+=item elt_id        ($id)
+
+Return the element whose C<id> attribute is $id
+
+=item getEltById
+
+Same as C<L<elt_id>>
+
+=item encoding
+
+This method returns the encoding of the XML document, as defined by the 
+C<encoding> attribute in the XML declaration (ie it is C<undef> if the attribute
+is not defined)
+
+=item set_encoding
+
+This method sets the value of the C<encoding> attribute in the XML declaration. 
+Note that if the document did not have a declaration it is generated (with
+an XML version of 1.0)
+
+=item xml_version
+
+This method returns the XML version, as defined by the C<version> attribute in 
+the XML declaration (ie it is C<undef> if the attribute is not defined)
+
+=item set_xml_version
+
+This method sets the value of the C<version> attribute in the XML declaration. 
+If the declaration did not exist it is created.
+
+=item standalone
+
+This method returns the value of the C<standalone> declaration for the document
+
+=item set_standalone
+
+This method sets the value of the C<standalone> attribute in the XML 
+declaration.  Note that if the document did not have a declaration it is 
+generated (with an XML version of 1.0)
+
+=item set_output_encoding
+
+Set the C<encoding> "attribute" in the XML declaration
+
+=item set_doctype ($name, $system, $public, $internal)
+
+Set the doctype of the element. If an argument is C<undef> (or not present)
+then its former value is retained, if a false ('' or 0) value is passed then
+the former value is deleted;
+
+=item entity_list
+
+Return the entity list of a twig
+
+=item entity_names
+
+Return the list of all defined entities
+
+=item entity ($entity_name)
+
+Return the entity 
+
+=item change_gi      ($old_gi, $new_gi)
+
+Performs a (very fast) global change. All elements C<$old_gi> are now 
+C<$new_gi>.
+
+See C<L<BUGS|BUGS> >
+
+=item flush            ($optional_filehandle, $options)
+
+Flushes a twig up to (and including) the current element, then deletes
+all unnecessary elements from the tree that's kept in memory.
+C<flush> keeps track of which elements need to be open/closed, so if you
+flush from handlers you don't have to worry about anything. Just keep 
+flushing the twig every time you're done with a sub-tree and it will
+come out well-formed. After the whole parsing don't forget toC<flush> 
+one more time to print the end of the document.
+The doctype and entity declarations are also printed.
+
+flush take an optional filehandle as an argument.
+
+options: use the C<update_DTD> option if you have updated the (internal) DTD 
+and/or the entity list and you want the updated DTD to be output 
+
+The C<pretty_print> option sets the pretty printing of the document.
+
+   Example: $t->flush( Update_DTD => 1);
+            $t->flush( \*FILE, Update_DTD => 1);
+            $t->flush( \*FILE);
+
+
+=item flush_up_to ($elt, $optional_filehandle, %options)
+
+Flushes up to the C<$elt> element. This allows you to keep part of the
+tree in memory when you C<flush>.
+
+options: see flush.
+
+=item purge
+
+Does the same as a C<flush> except it does not print the twig. It just deletes
+all elements that have been completely parsed so far.
+
+=item purge_up_to ($elt)
+
+Purges up to the C<$elt> element. This allows you to keep part of the tree in 
+memory when you C<purge>.
+
+=item print            ($optional_filehandle, %options)
+
+Prints the whole document associated with the twig. To be used only AFTER the
+parse.
+ 
+options: see C<flush>.
+
+=item sprint
+
+Return the text of the whole document associated with the twig. To be used only
+AFTER the parse.
+
+options: see C<flush>.
+
+=item toSAX1 ($handler)
+
+Send SAX events for the twig to the SAX1 handler C<$handler>
+
+=item toSAX2 ($handler)
+
+Send SAX events for the twig to the SAX2 handler C<$handler>
+
+=item flush_toSAX1 ($handler)
+
+Same as flush, except that SAX events are sent to the SAX1 handler
+C<$handler> instead of the twig being printed
+
+=item flush_toSAX2 ($handler)
+
+Same as flush, except that SAX events are sent to the SAX2 handler
+C<$handler> instead of the twig being printed
+
+=item ignore
+
+This method can B<only> be called in C<start_tag_handlers>. It causes the 
+element to be skipped during the parsing: the twig is not built for this 
+element, it will not be accessible during parsing or after it. The element 
+will not take up any memory and parsing will be faster.
+
+Note that this method can also be called on an element. If the element is a 
+parent of the current element then this element will be ignored (the twig will
+not be built any more for it and what has already been built will be deleted)
+
+
+=item set_pretty_print  ($style)
+
+Set the pretty print method, amongst 'C<none>' (default), 'C<nsgmls>', 
+'C<nice>', 'C<indented>', 'C<record>' and 'C<record_c>'
+
+B<WARNING:> the pretty print style is a B<GLOBAL> variable, so once set it's
+applied to B<ALL> C<print>'s (and C<sprint>'s). Same goes if you use XML::Twig
+with C<mod_perl> . This should not be a problem as the XML that's generated 
+is valid anyway, and XML processors (as well as HTML processors, including
+browsers) should not care. Let me know if this is a big problem, but at the
+moment the performance/cleanliness trade-off clearly favors the global 
+approach.
+
+=item set_empty_tag_style  ($style)
+
+Set the empty tag display style ('C<normal>', 'C<html>' or 'C<expand>'). As 
+with C<L<set_pretty_print>> this sets a global flag.  
+
+C<normal> outputs an empty tag 'C<< <tag/> >>', C<html> adds a space 
+'C<< <tag /> >>' and C<expand> outputs 'C<< <tag></tag> >>'
+
+=item print_prolog     ($optional_filehandle, %options)
+
+Prints the prolog (XML declaration + DTD + entity declarations) of a document.
+
+options: see C<L<flush>>.
+
+=item prolog     ($optional_filehandle, %options)
+
+Return the prolog (XML declaration + DTD + entity declarations) of a document.
+
+options: see C<L<flush>>.
+
+=item finish
+
+Call Expat C<finish> method.
+Unsets all handlers (including internal ones that set context), but expat
+continues parsing to the end of the document or until it finds an error.
+It should finish up a lot faster than with the handlers set.
+
+=item finish_print
+
+Stop twig processing, flush the twig and proceed to finish printing the 
+document as fast as possible. Use this method when modifying a document and 
+the modification is done. 
+
+=item set_expand_external_entities
+
+Same as using the C<L<expand_external_ents>> option when creating the twig
+
+=item set_input_filter
+
+Same as using the C<L<input_filter>> option when creating the twig
+
+=item set_keep_atts_order
+
+Same as using the C<L<keep_atts_order>> option when creating the twig
+
+=item set_keep_encoding
+
+Same as using the C<L<keep_encoding>> option when creating the twig
+
+=item set_output_filter
+
+Same as using the C<L<output_filter>> option when creating the twig
+
+=item set_output_text_filter
+
+Same as using the C<L<output_text_filter>> option when creating the twig
+
+=item Methods inherited from XML::Parser::Expat
+
+A twig inherits all the relevant methods from XML::Parser::Expat. These 
+methods can only be used during the parsing phase (they will generate
+a fatal error otherwise).
+
+Inherited methods are:
+
+=over 4
+
+=item depth
+
+Returns the size of the context list.
+
+=item in_element
+
+Returns true if NAME is equal to the name of the innermost curâ
+rently opened element. If namespace processing is being used and
+you want to check against a name that may be in a namespace, then
+use the generate_ns_name method to create the NAME argument.
+
+=item within_element
+
+Returns the number of times the given name appears in the context
+list.  If namespace processing is being used and you want to check
+against a name that may be in a namespace, then use the generâ
+ate_ns_name method to create the NAME argument.
+
+=item context
+
+Returns a list of element names that represent open elements, with
+the last one being the innermost. Inside start and end tag hanâ
+dlers, this will be the tag of the parent element.
+
+=item current_line
+
+Returns the line number of the current position of the parse.
+
+=item current_column
+
+Returns the column number of the current position of the parse.
+
+=item current_byte
+
+Returns the current position of the parse.
+
+=item position_in_context
+
+Returns a string that shows the current parse position. LINES
+should be an integer >= 0 that represents the number of lines on
+either side of the current parse line to place into the returned
+string.
+
+=item base ([NEWBASE])
+
+Returns the current value of the base for resolving relative URIs.
+If NEWBASE is supplied, changes the base to that value.
+
+=item current_element
+
+Returns the name of the innermost currently opened element. Inside
+start or end handlers, returns the parent of the element associated
+with those tags.
+
+=item element_index
+
+Returns an integer that is the depth-first visit order of the curâ
+rent element. This will be zero outside of the root element. For
+example, this will return 1 when called from the start handler for
+the root element start tag.
+
+=item recognized_string
+
+Returns the string from the document that was recognized in order
+to call the current handler. For instance, when called from a start
+handler, it will give us the the start-tag string. The string is
+encoded in UTF-8.  This method doesn't return a meaningful string
+inside declaration handlers.
+
+=item original_string
+
+Returns the verbatim string from the document that was recognized
+in order to call the current handler. The string is in the original
+document encoding. This method doesn't return a meaningful string
+inside declaration handlers.
+
+=item xpcroak
+
+Concatenate onto the given message the current line number within
+the XML document plus the message implied by ErrorContext. Then
+croak with the formed message.
+
+=item xpcarp 
+
+Concatenate onto the given message the current line number within
+the XML document plus the message implied by ErrorContext. Then
+carp with the formed message.
+
+=item xml_escape(TEXT [, CHAR [, CHAR ...]])
+
+Returns TEXT with markup characters turned into character entities.
+Any additional characters provided as arguments are also turned
+into character references where found in TEXT.
+
+(this method is broken on some versions of expat/XML::Parser)
+
+=back
+
+=item path ($gi)
+
+Return the element context in a form similar to XPath's short
+form: 'C</root/gi1/../gi>'
+
+=item get_xpath  ( $optional_array_ref, $xpath, $optional_offset)
+
+Performs a C<get_xpath> on the document root (see <Elt|"Elt">)
+
+If the C<$optional_array_ref> argument is used the array must contain
+elements. The C<$xpath> expression is applied to each element in turn 
+and the result is union of all results. This way a first query can be
+refined in further steps.
+
+
+=item find_nodes ( $optional_array_ref, $xpath, $optional_offset)
+
+same as C<get_xpath> 
+
+=item findnodes ( $optional_array_ref, $xpath, $optional_offset)
+
+same as C<get_xpath> (similar to the XML::LibXML method)
+
+=item findvalue ( $optional_array_ref, $xpath, $optional_offset)
+
+Return the C<join> of all texts of the results of appling C<L<get_xpath>>
+to the node (similar to the XML::LibXML method)
+
+=item subs_text ($regexp, $replace)
+
+subs_text does text substitution on the whole document, similar to perl's 
+C< s///> operator.
+
+=item dispose
+
+Useful only if you don't have C<Scalar::Util> or C<WeakRef> installed.
+
+Reclaims properly the memory used by an XML::Twig object. As the object has
+circular references it never goes out of scope, so if you want to parse lots 
+of XML documents then the memory leak becomes a problem. Use
+C<< $twig->dispose >> to clear this problem.
+
+=back 
+
+
+=head2 XML::Twig::Elt
+
+=over 4
+
+=item new          ($optional_gi, $optional_atts, @optional_content)
+
+The C<gi> is optional (but then you can't have a content ), the C<$optional_atts> 
+argument is a refreference to a hash of attributes, the content can be just a 
+string or a list of strings and element. A content of 'C<#EMPTY>' creates an empty 
+element;
+
+ Examples: my $elt= XML::Twig::Elt->new();
+           my $elt= XML::Twig::Elt->new( para => { align => 'center' });  
+           my $elt= XML::Twig::Elt->new( para => { align => 'center' }, 'foo');  
+           my $elt= XML::Twig::Elt->new( br   => '#EMPTY');
+           my $elt= XML::Twig::Elt->new( 'para');
+           my $elt= XML::Twig::Elt->new( para => 'this is a para');  
+           my $elt= XML::Twig::Elt->new( para => $elt3, 'another para'); 
+
+The strings are not parsed, the element is not attached to any twig.
+
+B<WARNING>: if you rely on ID's then you will have to set the id yourself. At
+this point the element does not belong to a twig yet, so the ID attribute
+is not known so it won't be strored in the ID list.
+
+Note that C<#COMMENT>, C<#PCDATA> or C<#CDATA> are valid tag names, that will 
+create text elements.
+
+To create an element C<foo> containing a CDATA section:
+
+           my $foo= XML::Twig::Elt->new( '#CDATA' => "content of the CDATA section")
+                                  ->wrap_in( 'foo');
+
+=item parse         ($string, %args)
+
+Creates an element from an XML string. The string is actually
+parsed as a new twig, then the root of that twig is returned.
+The arguments in C<%args> are passed to the twig.
+As always if the parse fails the parser will die, so use an
+eval if you want to trap syntax errors.
+
+As obviously the element does not exist beforehand this method has to be 
+called on the class: 
+
+  my $elt= parse XML::Twig::Elt( "<a> string to parse, with <sub/>
+                                  <elements>, actually tons of </elements>
+                  h</a>");
+
+=item print         ($optional_filehandle, $optional_pretty_print_style)
+
+Prints an entire element, including the tags, optionally to a 
+C<$optional_filehandle>, optionally with a C<$pretty_print_style>.
+
+The print outputs XML data so base entities are escaped.
+
+=item sprint       ($elt, $optional_no_enclosing_tag)
+
+Return the xml string for an entire element, including the tags. 
+If the optional second argument is true then only the string inside the 
+element is returned (the start and end tag for $elt are not).
+The text is XML-escaped: base entities (& and < in text, & < and " in
+attribute values) are turned into entities.
+
+=item gi                       
+
+Return the gi of the element (the gi is the C<generic identifier> the tag
+name in SGML parlance).
+
+C<tag> and C<name> are synonyms of C<gi>.
+
+=item tag
+
+Same as C<L<gi|gi>>
+
+=item name
+
+Same as C<L<gi|gi>>
+
+=item set_gi         ($gi)
+
+Set the gi (tag) of an element
+
+=item set_tag        ($tag)
+
+Set the tag (=C<L<gi|gi>>) of an element
+
+=item set_name       ($name)
+
+Set the name (=C<L<gi|gi>>) of an element
+
+=item root 
+
+Return the root of the twig in which the element is contained.
+
+=item twig 
+
+Return the twig containing the element. 
+
+=item parent        ($optional_condition)
+
+Return the parent of the element, or the first ancestor matching the 
+C<$optional_condition>
+
+=item first_child   ($optional_condition)
+
+Return the first child of the element, or the first child matching the 
+C<$optional_condition>
+
+=item has_child ($optional_condition)
+
+Return the first child of the element, or the first child matching the 
+C<$optional_condition> (same as L<first_child>)
+
+=item has_children ($optional_condition)
+
+Return the first child of the element, or the first child matching the 
+C<$optional_condition> (same as L<first_child>)
+
+
+=item first_child_text   ($optional_condition)
+
+Return the text of the first child of the element, or the first child
+ matching the C<$optional_condition>
+If there is no first_child then returns ''. This avoids getting the
+child, checking for its existence then getting the text for trivial cases.
+
+Similar methods are available for the other navigation methods: 
+
+=over 4
+
+=item last_child_text
+
+=item prev_sibling_text
+
+=item next_sibling_text
+
+=item prev_elt_text
+
+=item next_elt_text
+
+=item child_text
+
+=item parent_text
+
+=back
+
+All this methods also exist in "trimmed" variant: 
+
+=over 4
+
+=item first_child_trimmed_text
+
+=item last_child_trimmed_text
+
+=item prev_sibling_trimmed_text
+
+=item next_sibling_trimmed_text
+
+=item prev_elt_trimmed_text
+
+=item next_elt_trimmed_text
+
+=item child_trimmed_text
+
+=item parent_trimmed_text
+
+=back
+
+=item field         ($optional_condition)
+
+Same method as C<first_child_text> with a different name
+
+=item trimmed_field         ($optional_condition)
+
+Same method as C<first_child_trimmed_text> with a different name
+
+=item set_field ($condition, $optional_atts, @list_of_elt_and_strings)
+
+Set the content of the first child of the element that matches
+C<$condition>, the rest of the arguments is tha same as for C<L<set_content>>
+
+If no child matches C<$condition> _and_ if C<$condition> is a valid
+XML element name, then a new element by that name is created and 
+inserted as the last child.
+
+=item first_child_matches   ($optional_condition)
+
+Return the element if the first child of the element (if it exists) passes
+the C<$optional_condition> C<undef> otherwise
+
+  if( $elt->first_child_matches( 'title')) ... 
+
+is equivalent to
+
+  if( $elt->{first_child} && $elt->{first_child}->passes( 'title')) 
+
+C<first_child_is> is an other name for this method
+
+Similar methods are available for the other navigation methods: 
+
+=over 4
+
+=item last_child_matches
+
+=item prev_sibling_matches
+
+=item next_sibling_matches
+
+=item prev_elt_matches
+
+=item next_elt_matches
+
+=item child_matches
+
+=item parent_matches
+
+=back
+
+=item is_first_child ($optional_condition)
+
+returns true (the element) if the element is the first child of its parent
+(optionaly that satisfies the C<$optional_condition>)
+
+=item is_last_child ($optional_condition)
+
+returns true (the element) if the element is the first child of its parent
+(optionaly that satisfies the C<$optional_condition>)
+
+=item prev_sibling  ($optional_condition)
+
+Return the previous sibling of the element, or the previous sibling matching
+C<$optional_condition>
+
+=item next_sibling  ($optional_condition)
+
+Return the next sibling of the element, or the first one matching 
+C<$optional_condition>.
+
+=item next_elt     ($optional_elt, $optional_condition)
+
+Return the next elt (optionally matching C<$optional_condition>) of the element. This 
+is defined as the next element which opens after the current element opens.
+Which usually means the first child of the element.
+Counter-intuitive as it might look this allows you to loop through the
+whole document by starting from the root.
+
+The C<$optional_elt> is the root of a subtree. When the C<next_elt> is out of the
+subtree then the method returns undef. You can then walk a sub tree with:
+
+  my $elt= $subtree_root;
+  while( $elt= $elt->next_elt( $subtree_root)
+    { # insert processing code here
+    }
+
+=item prev_elt     ($optional_condition)
+
+Return the previous elt (optionally matching C<$optional_condition>) of the
+element. This is the first element which opens before the current one.
+It is usually either the last descendant of the previous sibling or
+simply the parent
+
+=item next_n_elt   ($offset, $optional_condition)
+
+Return the C<$offset>-th element that matches the C<$optional_condition> 
+
+=item children     ($optional_condition)
+
+Return the list of children (optionally which matches C<$optional_condition>) of 
+the element. The list is in document order.
+
+=item children_count ($optional_condition)
+
+Return the number of children of the element (optionally which matches 
+C<$optional_condition>)
+
+=item children_text ($optional_condition)
+
+Return an array containing the text of children of the element (optionally 
+which matches C<$optional_condition>)
+
+=item children_copy ($optional_condition)
+
+Return a list of elements that are copies of the children of the element, 
+optionally which matches C<$optional_condition>
+
+=item descendants     ($optional_condition)
+
+Return the list of all descendants (optionally which matches 
+C<$optional_condition>) of the element. This is the equivalent of the 
+C<getElementsByTagName> of the DOM (by the way, if you are really a DOM 
+addict, you can use C<getElementsByTagName> instead)
+
+=item getElementsByTagName ($optional_condition)
+
+Same as C<L<descendants>>
+
+=item find_by_tag_name ($optional_condition)
+
+Same as C<L<descendants>>
+
+=item descendants_or_self ($optional_condition)
+
+Same as C<L<descendants>> except that the element itself is included in the list
+if it matches the C<$optional_condition> 
+
+=item ancestors    ($optional_condition)
+
+Return the list of ancestors (optionally matching C<$optional_condition>) of the 
+element.  The list is ordered from the innermost ancestor to the outtermost one
+
+NOTE: the element itself is not part of the list, in order to include it 
+you will have to use ancestors_or_self
+
+=item ancestors_or_self     ($optional_condition)
+
+Return the list of ancestors (optionally matching C<$optional_condition>) of the 
+element, including the element (if it matches the condition>).  
+The list is ordered from the innermost ancestor to the outtermost one
+
+=item passes ($condition)
+
+Return the element if it passes the C<$condition> 
+
+=item att          ($att)
+
+Return the value of attribute C<$att> or C<undef>
+
+=item set_att      ($att, $att_value)
+
+Set the attribute of the element to the given value
+
+You can actually set several attributes this way:
+
+  $elt->set_att( att1 => "val1", att2 => "val2");
+
+=item del_att      ($att)
+
+Delete the attribute for the element
+
+You can actually delete several attributes at once:
+
+  $elt->del_att( 'att1', 'att2', 'att3');
+
+=item cut
+
+Cut the element from the tree. The element still exists, it can be copied
+or pasted somewhere else, it is just not attached to the tree anymore.
+
+=item cut_children ($optional_condition)
+
+Cut all the children of the element (or all of those which satisfy the
+C<$optional_condition>).
+
+Return the list of children 
+
+=item copy        ($elt)
+
+Return a copy of the element. The copy is a "deep" copy: all sub elements of 
+the element are duplicated.
+
+=item paste       ($optional_position, $ref)
+
+Paste a (previously C<cut> or newly generated) element. Die if the element
+already belongs to a tree.
+
+The element is pasted 
+
+Example:
+
+  my $t= XML::Twig->new->parse( 'doc.xml')
+  my $toc= $t->root->new( 'toc');
+  $toc->paste( $t->root); # $toc is pasted as first child of the root 
+  foreach my $title ($t->findnodes( '/doc/section/title'))
+    { my $title_toc= $title->copy;
+      # paste $title_toc as the last child of toc
+      $title_toc->paste( last_child => $toc) 
+    }
+
+Position options:
+
+=over 4
+
+=item first_child (default)
+
+The element is pasted as the first child of C<$ref>
+
+=item last_child
+
+The element is pasted as the last child of C<$ref>
+
+=item before
+
+The element is pasted before C<$ref>, as its previous sibling.
+
+=item after
+
+The element is pasted after C<$ref>, as its next sibling.
+
+=item within
+
+In this case an extra argument, C<$offset>, should be supplied. The element
+will be pasted in the reference element (or in its first text child) at the
+given offset. To achieve this the reference element will be split at the 
+offset.
+
+=back
+
+Note that you can call directly the underlying method:
+
+=over 4
+
+=item paste_before
+
+=item paste_after
+
+=item paste_first_child
+
+=item paste_last_child
+
+=item paste_within
+
+=back
+
+=item move       ($optional_position, $ref)
+
+Move an element in the tree.
+This is just a C<cut> then a C<paste>.  The syntax is the same as C<paste>.
+
+=item replace       ($ref)
+
+Replaces an element in the tree. Sometimes it is just not possible toC<cut> 
+an element then C<paste> another in its place, so C<replace> comes in handy.
+The calling element replaces C<$ref>.
+
+=item replace_with   (@elts)
+
+Replaces the calling element with one or more elements 
+
+=item delete
+
+Cut the element and frees the memory.
+
+=item prefix       ($text, $optional_option)
+
+Add a prefix to an element. If the element is a C<PCDATA> element the text
+is added to the pcdata, if the elements first child is a C<PCDATA> then the
+text is added to it's pcdata, otherwise a new C<PCDATA> element is created 
+and pasted as the first child of the element.
+
+If the option is C<asis> then the prefix is added asis: it is created in
+a separate C<PCDATA> element with an C<asis> property. You can then write:
+
+  $elt1->prefix( '<b>', 'asis');
+
+to create a C<< <b> >> in the output of C<print>.
+
+=item suffix       ($text, $optional_option)
+
+Add a suffix to an element. If the element is a C<PCDATA> element the text
+is added to the pcdata, if the elements last child is a C<PCDATA> then the
+text is added to it's pcdata, otherwise a new PCDATA element is created 
+and pasted as the last child of the element.
+
+If the option is C<asis> then the suffix is added asis: it is created in
+a separate C<PCDATA> element with an C<asis> property. You can then write:
+
+  $elt2->suffix( '</b>', 'asis');
+
+=item simplify (%options)
+
+Return a data structure suspiciously similar to XML::Simple's. Options are
+identical to XMLin options, see XML::Simple doc for more details (or use
+DATA::dumper or YAML to dump the data structure)
+
+=over 4
+
+=item keyattr 
+
+=item forcearray 
+
+=item noattr 
+
+=item content_key
+                             
+=item variables (%var_hash)
+
+%var_hash is a hash { name => value }
+
+This option allows variables in the XML to be expanded when the file is read. (there is no facility for putting the variable names back if you regenerate XML using XMLout).
+
+A 'variable' is any text of the form ${name} (or $name) which occurs in an attribute value or in the text content of an element. If 'name' matches a key in the supplied hashref, ${name} will be replaced with the corresponding value from the hashref. If no matching key is found, the variable will not be replaced. 
+
+=item var_att ($attribute_name)
+
+This option gives the name of an attribute that will be used to create 
+variables in the XML:
+
+  <dirs>
+    <dir name="prefix">/usr/local</dir>
+    <dir name="exec_prefix">$prefix/bin</dir>
+  </dirs>
+
+use C<< var => 'name' >> to get $prefix replaced by /usr/local in the
+generated data structure  
+
+By default variables are captured by the following regexp: /$(\w+)/
+    
+=item var_regexp (regexp)
+
+This option changes the regexp used to capture variables. The variable
+name should be in $1
+
+=item group_tags ([<tag1>, <tag2>...])
+
+Option used to simplify the structure: elements listed will not be used.
+Their children will be, they will be considered children of the element
+parent.
+
+If the element is:
+
+  <config host="laptop.xmltwig.com">
+    <server>localhost</server>
+    <dirs>
+      <dir name="base">/home/mrodrigu/standards</dir>
+      <dir name="tools">$base/tools</dir>
+    </dirs>
+    <templates>
+      <template name="std_def">std_def.templ</template>
+      <template name="dummy">dummy</template>
+    </templates>
+  </config>
+
+Then callin simplify with C<< erase => [ 'dirs', 'templates'] >> makes the
+data structure be exactly as if the start and end tags for C<dirs> and
+C<templates> were not there.
+
+A YAML dump of the structure 
+
+  base: '/home/mrodrigu/standards'
+  host: laptop.xmltwig.com
+  server: localhost
+  template:
+    - std_def.templ
+    - dummy.templ
+  tools: '$base/tools'
+
+
+=back
+
+=item split_at        ($offset)
+
+Split a text (C<PCDATA> or C<CDATA>) element in 2 at C<$offset>, the original
+element now holds the first part of the string and a new element holds the
+right part. The new element is returned
+
+If the element is not a text element then the first text child of the element
+is split
+
+=item split        ( $optional_regexp, $optional_tag, $optional_attribute_ref)
+
+Split the text descendants of an element in place, the text is split using 
+the regexp, if the regexp includes () then the matched separators will be 
+wrapped in C<$optional_tag>, with C<$optional_attribute_ref> attributes
+
+if $elt is C<< <p>tati tata <b>tutu tati titi</b> tata tati tata</p> >>
+
+  $elt->split( qr/(ta)ti/, 'foo', {type => 'toto'} )
+
+will change $elt to
+
+  <p><foo type="toto">ta</foo> tata <b>tutu <foo type="toto">ta</foo>
+      titi</b> tata <foo type="toto">ta</foo> tata</p> 
+
+The regexp can be passed either as a string or as C<qr//> (perl 5.005 and 
+later), it defaults to \s+ just as the C<split> built-in (but this would be 
+quite a useless behaviour without the C<$optional_tag> parameter)
+
+C<$optional_tag> defaults to PCDATA or CDATA, depending on the initial element
+type
+
+The list of descendants is returned (including un-touched original elements 
+and newly created ones)
+
+=item mark        ( $regexp, $optional_tag, $optional_attribute_ref)
+
+This method behaves exactly as L<split|split>, except only the newly created 
+elements are returned
+
+=item wrap_children ( $regexp_string, $tag, $optional_att, $optional_value)
+
+Wrap the children of the element that match the regexp in an element C<$tag>.
+If C<$optional_att> and C<$optional_value> are passed then the new element will
+have an attribute C<$optional_att> with a value C<$optional_value>.
+
+Note that elements might get extra C<id> attributes in the process. See L<add_id>.
+Use L<strip_att> to remove unwanted id's. 
+
+Here is an example:
+
+If the element C<$elt> has the following content:
+
+  <elt>
+   <p>para 1</p>
+   <l_l1_1>list 1 item 1 para 1</l_l1_1>
+     <l_l1>list 1 item 1 para 2</l_l1>
+   <l_l1_n>list 1 item 2 para 1 (only para)</l_l1_n>
+   <l_l1_n>list 1 item 3 para 1</l_l1_n>
+     <l_l1>list 1 item 3 para 2</l_l1>
+     <l_l1>list 1 item 3 para 3</l_l1>
+   <l_l1_1>list 2 item 1 para 1</l_l1_1>
+     <l_l1>list 2 item 1 para 2</l_l1>
+   <l_l1_n>list 2 item 2 para 1 (only para)</l_l1_n>
+   <l_l1_n>list 2 item 3 para 1</l_l1_n>
+     <l_l1>list 2 item 3 para 2</l_l1>
+     <l_l1>list 2 item 3 para 3</l_l1>
+  </elt>
+
+Then the code
+
+  $elt->wrap_children( q{<l_l1_1><l_l1>*} , li => { type => "ul1" });
+  $elt->wrap_children( q{<l_l1_n><l_l1>*} , li => { type => "ul" });
+
+  $elt->wrap_children( q{<li type="ul1"><li type="ul">+}, "ul");
+  $elt->strip_att( 'id');
+  $elt->strip_att( 'type');
+  $elt->print;
+
+will output:
+
+  <elt>
+     <p>para 1</p>
+     <ul>
+       <li>
+         <l_l1_1>list 1 item 1 para 1</l_l1_1>
+         <l_l1>list 1 item 1 para 2</l_l1>
+       </li>
+       <li>
+         <l_l1_n>list 1 item 2 para 1 (only para)</l_l1_n>
+       </li>
+       <li>
+         <l_l1_n>list 1 item 3 para 1</l_l1_n>
+         <l_l1>list 1 item 3 para 2</l_l1>
+         <l_l1>list 1 item 3 para 3</l_l1>
+       </li>
+     </ul>
+     <ul>
+       <li>
+         <l_l1_1>list 2 item 1 para 1</l_l1_1>
+         <l_l1>list 2 item 1 para 2</l_l1>
+       </li>
+       <li>
+         <l_l1_n>list 2 item 2 para 1 (only para)</l_l1_n>
+       </li>
+       <li>
+         <l_l1_n>list 2 item 3 para 1</l_l1_n>
+         <l_l1>list 2 item 3 para 2</l_l1>
+         <l_l1>list 2 item 3 para 3</l_l1>
+       </li>
+     </ul>
+  </elt>
+
+=item subs_text ($regexp, $replace)
+
+subs_text does text substitution, similar to perl's C< s///> operator.
+
+C<$regexp> must be a perl regexp, created with the C<qr> operatot.
+
+C<$replace> can include C<$1, $2>... from the C<$regexp>. It can also be
+used to create element and entities, by using 
+C<< &elt( tag => { att => val }, text) >> (similar syntax as C<L<new>>) and
+C<< &ent( name) >>.
+
+Here is a rather complex example:
+
+  $elt->subs_text( qr{(?<!do not )link to (http://([^\s,]*))},
+                   'see &elt( a =>{ href => $1 }, $2)'
+                 );
+
+This will replace text like I<link to http://www.xmltwig.com> by 
+I<< see <a href="www.xmltwig.com">www.xmltwig.com</a> >>, but not
+I<do not link to...>
+
+Generating entities (here replacing spaces with &nbsp;):
+
+  $elt->subs_text( qr{ }, '&ent( "&nbsp;")');
+
+or, using a variable:
+
+  my $ent="&nbsp;";
+  $elt->subs_text( qr{ }, "&ent( '$ent')");
+
+Note that the substitution is always global, as in using the C<g> modifier
+in a perl substitution, and that it is performed on all text descendants
+of the element.
+
+=item add_id
+
+Add an id to the element.
+
+The id is an attribute (C<id> by default, see the C<id> option for XML::Twig
+C<new> to change it. Use an id starting with C<#> to get an id that's not 
+output by L<print>, L<flush> or L<sprint>) that allows you to use the
+L<elt_id> method to get the element easily.
+
+=item set_id_seed ($prefix)
+
+by default the id generated by C<L<add_id>> is C<< twig_id_<nnnn> >>, 
+C<set_id_seed> changes the prefix to C<$prefix> and resets the number
+to 1
+
+=item strip_att ($att)
+
+Remove the attribute C<$att> from all descendants of the element (including 
+the element)
+
+=item change_att_name ($old_name, $new_name)
+
+Change the name of the attribute from C<$old_name> to C<$new_name>. If there is no
+attribute C<$old_name> nothing happens.
+
+=item sort_children_on_value( %options)
+
+Sort the children of the element in place according to their text.
+All children are sorted. 
+
+Return the element, with its children sorted.
+
+
+L<%options> are
+
+  type  : numeric |  alpha     (default: alpha)
+  order : normal  |  reverse   (default: normal)
+
+Return the element, with its children sorted
+
+
+=item sort_children_on_att ($att, %options)
+
+Sort the children of the  element in place according to attribute C<$att>. 
+C<%options> are the same as for L<C<sort_children_on_value>>
+
+Return the element.
+
+
+=item sort_children_on_field ($gi, %options)
+
+Sort the children of the element in place, according to the field C<$gi> (the 
+text of the first child of the child with this gi). C<%options> are the same
+as for L<C<sort_children_on_value>>.
+
+Return the element, with its children sorted
+
+
+=item sort_children( $get_key, %options) 
+
+Sort the children of the element in place. The C<$get_key> argument is
+a reference to a function that returns the sort key when passed an element.
+
+For example:
+
+  $elt->sort_children( sub { $_[0]->{'att'}->{"nb"} + $_[0]->text }, 
+                       type => 'numeric', order => 'reverse'
+                     );
+
+=item field_to_att ($cond, $att)
+
+Turn the text of the first sub-element matched by C<$cond> into the value of 
+attribute C<$att> of the element. If C<$att> is ommited then C<$cond> is used 
+as the name of the attribute, which makes sense only if C<$cond> is a valid
+element (and attribute) name.
+
+The sub-element is then cut.
+
+=item att_to_field ($att, $gi)
+
+Take the value of attribute C<$att> and create a sub-element C<$gi> as first
+child of the element. If C<$gi> is ommited then C<$att> is used as the name of
+the sub-element. 
+
+
+=item get_xpath  ($xpath, $optional_offset)
+
+Return a list of elements satisfying the C<$xpath>. C<$xpath> is an XPATH-like 
+expression.
+
+A subset of the XPATH abbreviated syntax is covered:
+
+  gi
+  gi[1] (or any other positive number)
+  gi[last()]
+  gi[@att] (the attribute exists for the element)
+  gi[@att="val"]
+  gi[@att=~ /regexp/]
+  gi[att1="val1" and att2="val2"]
+  gi[att1="val1" or att2="val2"]
+  gi[string()="toto"] (returns gi elements which text (as per the text method) 
+                       is toto)
+  gi[string()=~/regexp/] (returns gi elements which text (as per the text 
+                          method) matches regexp)
+  expressions can start with / (search starts at the document root)
+  expressions can start with . (search starts at the current element)
+  // can be used to get all descendants instead of just direct children
+  * matches any gi
+  
+So the following examples from the 
+F<XPath recommendationL<http://www.w3.org/TR/xpath.html#path-abbrev>> work:
+
+  para selects the para element children of the context node
+  * selects all element children of the context node
+  para[1] selects the first para child of the context node
+  para[last()] selects the last para child of the context node
+  */para selects all para grandchildren of the context node
+  /doc/chapter[5]/section[2] selects the second section of the fifth chapter 
+     of the doc 
+  chapter//para selects the para element descendants of the chapter element 
+     children of the context node
+  //para selects all the para descendants of the document root and thus selects
+     all para elements in the same document as the context node
+  //olist/item selects all the item elements in the same document as the 
+     context node that have an olist parent
+  .//para selects the para element descendants of the context node
+  .. selects the parent of the context node
+  para[@type="warning"] selects all para children of the context node that have
+     a type attribute with value warning 
+  employee[@secretary and @assistant] selects all the employee children of the
+     context node that have both a secretary attribute and an assistant 
+     attribute
+
+
+The elements will be returned in the document order.
+
+If C<$optional_offset> is used then only one element will be returned, the one 
+with the appropriate offset in the list, starting at 0
+
+Quoting and interpolating variables can be a pain when the Perl syntax and the 
+XPATH syntax collide, so here are some more examples to get you started:
+
+  my $p1= "p1";
+  my $p2= "p2";
+  my @res= $t->get_xpath( "p[string( '$p1') or string( '$p2')]");
+
+  my $a= "a1";
+  my @res= $t->get_xpath( "//*[@att=\"$a\"]);
+
+  my $val= "a1";
+  my $exp= "//p[ \@att='$val']"; # you need to use \@ or you will get a warning
+  my @res= $t->get_xpath( $exp);
+
+Note that the only supported regexps delimiters are / and that you must 
+backslash all / in regexps AND in regular strings.
+
+XML::Twig does not provide natively full XPATH support, but you can use 
+XML::Twig does not provide natively full XPATH support, but you can use 
+C<L<XML::Twig::XPath>> to get C<findnodes> to use C<XML::XPath> as the
+XPath engine, with full coverage of the spec.
+
+C<L<XML::Twig::XPath>> to get C<findnodes> to use C<XML::XPath> as the
+XPath engine, with full coverage of the spec.
+
+=item find_nodes
+
+same asC<get_xpath> 
+
+=item findnodes
+
+same asC<get_xpath> 
+
+
+=item text
+
+Return a string consisting of all the C<PCDATA> and C<CDATA> in an element, 
+without any tags. The text is not XML-escaped: base entities such as C<&> 
+and C<< < >> are not escaped.
+
+=item trimmed_text
+
+Same as C<text> except that the text is trimmed: leading and trailing spaces
+are discarded, consecutive spaces are collapsed
+
+=item set_text        ($string)
+
+Set the text for the element: if the element is a C<PCDATA>, just set its
+text, otherwise cut all the children of the element and create a single
+C<PCDATA> child for it, which holds the text.
+
+=item insert         ($gi1, [$optional_atts1], $gi2, [$optional_atts2],...)
+
+For each gi in the list inserts an element C<$gi> as the only child of the 
+element.  The element gets the optional attributes inC<< $optional_atts<n>. >> 
+All children of the element are set as children of the new element.
+The upper level element is returned.
+
+  $p->insert( table => { border=> 1}, 'tr', 'td') 
+
+put C<$p> in a table with a visible border, a single C<tr> and a single C<td> 
+and return the C<table> element:
+
+  <p><table border="1"><tr><td>original content of p</td></tr></table></p>
+
+=item wrap_in        (@gi)
+
+Wrap elements C<$gi> as the successive ancestors of the element, returns the 
+new element.
+$elt->wrap_in( 'td', 'tr', 'table') wraps the element as a single cell in a 
+table for example.
+
+=item insert_new_elt ($opt_position, $gi, $opt_atts_hashref, @opt_content)
+
+Combines a C<L<new|new> > and a C<L<paste|paste> >: creates a new element using 
+C<$gi>, C<$opt_atts_hashref >and C<@opt_content> which are arguments similar 
+to those for C<new>, then paste it, using C<$opt_position> or C<'first_child'>,
+relative to C<$elt>.
+
+Return the newly created element
+
+=item erase
+
+Erase the element: the element is deleted and all of its children are
+pasted in its place.
+
+=item set_content    ( $optional_atts, @list_of_elt_and_strings)
+                     ( $optional_atts, '#EMPTY')
+
+Set the content for the element, from a list of strings and
+elements.  Cuts all the element children, then pastes the list
+elements as the children.  This method will create a C<PCDATA> element
+for any strings in the list.
+
+The C<$optional_atts> argument is the ref of a hash of attributes. If this
+argument is used then the previous attributes are deleted, otherwise they
+are left untouched. 
+
+B<WARNING>: if you rely on ID's then you will have to set the id yourself. At
+this point the element does not belong to a twig yet, so the ID attribute
+is not known so it won't be strored in the ID list.
+
+A content of 'C<#EMPTY>' creates an empty element;
+
+=item namespace ($optional_prefix)
+
+Return the URI of the namespace that C<$optional_prefix> or the element name
+belongs to. If the name doesn't belong to any namespace, C<undef> is returned.
+
+=item local_name
+
+Return the local name (without the prefix) for the element
+
+=item ns_prefix
+
+Return the namespace prefix for the element
+
+=item current_ns_prefixes
+
+Returna list of namespace prefixes valid for the element. The order of the
+prefixes in the list has no meaning. If the default namespace is currently 
+bound, '' appears in the list.
+
+
+=item inherit_att  ($att, @optional_gi_list)
+
+Return the value of an attribute inherited from parent tags. The value
+returned is found by looking for the attribute in the element then in turn
+in each of its ancestors. If the C<@optional_gi_list> is supplied only those
+ancestors whose gi is in the list will be checked. 
+
+=item all_children_are ($optional_condition)
+
+return 1 if all children of the element pass the C<$optional_condition>, 
+0 otherwise
+
+=item level       ($optional_condition)
+
+Return the depth of the element in the twig (root is 0).
+If C<$optional_condition> is given then only ancestors that match the condition are 
+counted.
+ 
+B<WARNING>: in a tree created using the C<twig_roots> option this will not return
+the level in the document tree, level 0 will be the document root, level 1 
+will be the C<twig_roots> elements. During the parsing (in a C<twig_handler>)
+you can use the C<depth> method on the twig object to get the real parsing depth.
+
+=item in           ($potential_parent)
+
+Return true if the element is in the potential_parent (C<$potential_parent> is 
+an element)
+
+=item in_context   ($cond, $optional_level)
+
+Return true if the element is included in an element which passes C<$cond>
+optionally within C<$optional_level> levels. The returned value is the 
+including element.
+
+=item pcdata
+
+Return the text of a C<PCDATA> element or C<undef> if the element is not 
+C<PCDATA>.
+
+=item pcdata_xml_string
+
+Return the text of a PCDATA element or undef if the element is not PCDATA. 
+The text is "XML-escaped" ('&' and '<' are replaced by '&amp;' and '&lt;')
+
+=item set_pcdata     ($text)
+
+Set the text of a C<PCDATA> element. 
+
+=item append_pcdata  ($text)
+
+Add the text at the end of a C<PCDATA> element.
+
+=item is_cdata
+
+Return 1 if the element is a C<CDATA> element, returns 0 otherwise.
+
+=item is_text
+
+Return 1 if the element is a C<CDATA> or C<PCDATA> element, returns 0 otherwise.
+
+=item cdata
+
+Return the text of a C<CDATA> element or C<undef> if the element is not 
+C<CDATA>.
+
+=item cdata_string
+
+Return the XML string of a C<CDATA> element, including the opening and
+closing markers.
+
+=item set_cdata     ($text)
+
+Set the text of a C<CDATA> element. 
+
+=item append_cdata  ($text)
+
+Add the text at the end of a C<CDATA> element.
+
+=item remove_cdata
+
+Turns all C<CDATA> sections in the element into regular C<PCDATA> elements. This is useful
+when converting XML to HTML, as browsers do not support CDATA sections. 
+
+=item extra_data 
+
+Return the extra_data (comments and PI's) attached to an element
+
+=item set_extra_data     ($extra_data)
+
+Set the extra_data (comments and PI's) attached to an element
+
+=item append_extra_data  ($extra_data)
+
+Append extra_data to the existing extra_data before the element (if no
+previous extra_data exists then it is created)
+
+=item set_asis
+
+Set a property of the element that causes it to be output without being XML
+escaped by the print functions: if it contains C<< a < b >> it will be output
+as such and not as C<< a &lt; b >>. This can be useful to create text elements
+that will be output as markup. Note that all C<PCDATA> descendants of the 
+element are also marked as having the property (they are the ones taht are
+actually impacted by the change).
+
+If the element is a C<CDATA> element it will also be output asis, without the
+C<CDATA> markers. The same goes for any C<CDATA> descendant of the element
+
+=item set_not_asis
+
+Unsets the C<asis> property for the element and its text descendants.
+
+=item is_asis
+
+Return the C<asis> property status of the element ( 1 or C<undef>)
+
+=item closed                   
+
+Return true if the element has been closed. Might be usefull if you are
+somewhere in the tree, during the parse, and have no idea whether a parent
+element is completely loaded or not.
+
+=item get_type
+
+Return the type of the element: 'C<#ELT>' for "real" elements, or 'C<#PCDATA>',
+'C<#CDATA>', 'C<#COMMENT>', 'C<#ENT>', 'C<#PI>'
+
+=item is_elt
+
+Return the gi if the element is a "real" element, or 0 if it is C<PCDATA>, 
+C<CDATA>...
+
+=item contains_only_text
+
+Return 1 if the element does not contain any other "real" element
+
+=item contains_only ($exp)
+
+Return the list of children if all children of the element match
+the expression C<$exp> 
+
+  if( $para->contains_only( 'tt')) { ... }
+
+=item contains_a_single ($exp)
+
+If the element contains a single child that matches the expression C<$exp>
+returns that element. Otherwise returns 0.
+
+=item is_field
+
+same as C<contains_only_text> 
+
+=item is_pcdata
+
+Return 1 if the element is a C<PCDATA> element, returns 0 otherwise.
+
+=item is_ent
+
+Return 1 if the element is an entity (an unexpanded entity) element, 
+return 0 otherwise.
+
+=item is_empty
+
+Return 1 if the element is empty, 0 otherwise
+
+=item set_empty
+
+Flags the element as empty. No further check is made, so if the element
+is actually not empty the output will be messed. The only effect of this 
+method is that the output will be C<< <gi att="value""/> >>.
+
+=item set_not_empty
+
+Flags the element as not empty. if it is actually empty then the element will
+be output as C<< <gi att="value""></gi> >>
+
+=item is_pi
+
+Return 1 if the element is a processing instruction (C<#PI>) element,
+return 0 otherwise.
+
+=item target
+
+Return the target of a processing instruction
+
+=item set_target ($target)
+
+Set the target of a processing instruction
+
+=item data
+
+Return the data part of a processing instruction
+
+=item set_data ($data)
+
+Set the data of a processing instruction
+
+=item set_pi ($target, $data)
+
+Set the target and data of a processing instruction
+
+=item pi_string
+
+Return the string form of a processing instruction
+(C<< <?target data?> >>)
+
+=item is_comment
+
+Return 1 if the element is a comment (C<#COMMENT>) element,
+return 0 otherwise.
+
+=item set_comment ($comment_text)
+
+Set the text for a comment
+
+=item comment
+
+Return the content of a comment (just the text, not the C<< <!-- >>
+and C<< --> >>)
+
+=item comment_string 
+
+Return the XML string for a comment (C<< <!-- comment --> >>)
+
+=item set_ent ($entity)
+
+Set an (non-expanded) entity (C<#ENT>). C<$entity>) is the entity
+text (C<&ent;>)
+
+=item ent
+
+Return the entity for an entity (C<#ENT>) element (C<&ent;>)
+
+=item ent_name
+
+Return the entity name for an entity (C<#ENT>) element (C<ent>)
+
+=item ent_string
+
+Return the entity, either expanded if the expanded version is available,
+or non-expanded (C<&ent;>) otherwise
+
+=item child ($offset, $optional_condition)
+
+Return the C<$offset>-th child of the element, optionally the C<$offset>-th 
+child that matches C<$optional_condition>. The children are treated as a list, so 
+C<< $elt->child( 0) >> is the first child, while C<< $elt->child( -1) >> is 
+the last child.
+
+=item child_text ($offset, $optional_condition)
+
+Return the text of a child or C<undef> if the sibling does not exist. Arguments
+are the same as child.
+
+=item last_child    ($optional_condition)
+
+Return the last child of the element, or the last child matching 
+C<$optional_condition> (ie the last of the element children matching
+the condition).
+
+=item last_child_text   ($optional_condition)
+
+Same as C<first_child_text> but for the last child.
+
+=item sibling  ($offset, $optional_condition)
+
+Return the next or previous C<$offset>-th sibling of the element, or the 
+C<$offset>-th one matching C<$optional_condition>. If C<$offset> is negative then a 
+previous sibling is returned, if $offset is positive then  a next sibling is 
+returned. C<$offset=0> returns the element if there is no condition or
+if the element matches the condition>, C<undef> otherwise.
+
+=item sibling_text ($offset, $optional_condition)
+
+Return the text of a sibling or C<undef> if the sibling does not exist. 
+Arguments are the same as C<sibling>.
+
+=item prev_siblings ($optional_condition)
+
+Return the list of previous siblings (optionaly matching C<$optional_condition>)
+for the element. The elements are ordered in document order.
+
+=item next_siblings ($optional_condition)
+
+Return the list of siblings (optionaly matching C<$optional_condition>)
+following the element. The elements are ordered in document order.
+
+=item pos ($optional_condition)
+
+Return the position of the element in the children list. The first child has a
+position of 1 (as in XPath).
+
+If the C<$optional_condition> is given then only siblings that match the condition 
+are counted. If the element itself does not match the  condition then
+0 is returned.
+
+=item atts
+
+Return a hash ref containing the element attributes
+
+=item set_atts      ({att1=>$att1_val, att2=> $att2_val... })
+
+Set the element attributes with the hash ref supplied as the argument
+
+=item del_atts
+
+Deletes all the element attributes.
+
+=item att_nb
+
+Return the number of attributes for the element
+
+=item has_atts
+
+Return true if the element has attributes (in fact return the number of
+attributes, thus being an alias to C<L<att_nb>>
+
+=item has_no_atts
+
+Return true if the element has no attributes, false (0) otherwise
+
+=item att_names
+
+return a list of the attribute names for the element
+
+=item att_xml_string ($att, $optional_quote)
+
+Return the attribute value, where '&', '<' and $quote (" by default)
+are XML-escaped
+
+if C<$optional_quote> is passed then it is used as the quote.
+
+=item set_id       ($id)
+
+Set the C<id> attribute of the element to the value.
+See C<L<elt_id|elt_id> > to change the id attribute name
+
+=item id
+
+Gets the id attribute value
+
+=item del_id       ($id)
+
+Deletes the C<id> attribute of the element and remove it from the id list
+for the document
+
+=item class
+
+Return the C<class> attribute for the element (methods on the C<class>
+attribute are quite convenient when dealing with XHTML, or plain XML that
+will eventually be displayed using CSS)
+
+=item set_class ($class)
+
+Set the C<class> attribute for the element to C<$class>
+
+=item add_to_class ($class)
+
+Add C<$class> to the element C<class> attribute: the new class is added
+only if it is not already present. Note that classes are sorted alphabetically,
+so the C<class> attribute can be changed even if the class is already there
+
+=item att_to_class ($att)
+
+Set the C<class> attribute to the value of attribute C<$att>
+
+=item add_att_to_class ($att)
+
+Add the value of attribute C<$att> to the C<class> attribute of the element
+
+=item move_att_to_class ($att)
+
+Add the value of attribute C<$att> to the C<class> attribute of the element
+and delete the attribute
+
+=item tag_to_class
+
+Set the C<class> attribute of the element to the element tag
+
+=item add_tag_to_class
+
+Add the element tag to its C<class> attribute
+
+=item set_tag_class ($new_tag)
+
+Add the element tag to its C<class> attribute and sets the tag to C<$new_tag>
+
+=item in_class ($class)
+
+Return true (C<1>) if the element is in the class C<$class> (if C<$class> is
+one of the tokens in the element C<class> attribute)
+
+=item DESTROY
+
+Frees the element from memory.
+
+=item start_tag
+
+Return the string for the start tag for the element, including 
+the C<< /> >> at the end of an empty element tag
+
+=item end_tag
+
+Return the string for the end tag of an element.  For an empty
+element, this returns the empty string ('').
+
+=item xml_string
+
+Equivalent to C<< $elt->sprint( 1) >>, returns the string for the entire 
+element, excluding the element's tags (but nested element tags are present)
+
+=item xml_text 
+
+Return the text of the element, encoded (and processed by the current 
+C<L<output_filter>> or C<L<output_encoding>> options, without any tag.
+
+=item set_pretty_print ($style)
+
+Set the pretty print method, amongst 'C<none>' (default), 'C<nsgmls>', 
+'C<nice>', 'C<indented>', 'C<record>' and 'C<record_c>'
+
+pretty_print styles:
+
+=over 4
+
+=item none
+
+the default, no C<\n> is used
+
+=item nsgmls
+
+nsgmls style, with C<\n> added within tags
+
+=item nice
+
+adds C<\n> wherever possible (NOT SAFE, can lead to invalid XML)
+
+=item indented
+
+same as C<nice> plus indents elements (NOT SAFE, can lead to invalid XML) 
+
+=item record
+
+table-oriented pretty print, one field per line 
+
+=item record_c
+
+table-oriented pretty print, more compact than C<record>, one record per line 
+
+=back
+
+=item set_empty_tag_style ($style)
+
+Set the method to output empty tags, amongst 'C<normal>' (default), 'C<html>',
+and 'C<expand>', 
+
+=item set_indent ($string)
+
+Set the indentation for the indented pretty print style (default is 2 spaces)
+
+=item set_quote ($quote)
+
+Set the quotes used for attributes. can be 'C<double>' (default) or 'C<single>'
+
+=item cmp       ($elt)
+
+  Compare the order of the 2 elements in a twig.
+
+  C<$a> is the <A>..</A> element, C<$b> is the <B>...</B> element
+  
+  document                        $a->cmp( $b)
+  <A> ... </A> ... <B>  ... </B>     -1
+  <A> ... <B>  ... </B> ... </A>     -1
+  <B> ... </B> ... <A>  ... </A>      1
+  <B> ... <A>  ... </A> ... </B>      1
+   $a == $b                           0
+   $a and $b not in the same tree   undef
+
+=item before       ($elt)
+
+Return 1 if C<$elt> starts before the element, 0 otherwise. If the 2 elements 
+are not in the same twig then return C<undef>.
+
+    if( $a->cmp( $b) == -1) { return 1; } else { return 0; }
+
+=item after       ($elt)
+
+Return 1 if $elt starts after the element, 0 otherwise. If the 2 elements 
+are not in the same twig then return C<undef>.
+
+    if( $a->cmp( $b) == -1) { return 1; } else { return 0; }
+
+=item other comparison methods
+
+=over 4
+
+=item lt
+
+=item le
+
+=item gt
+
+=item ge
+
+=back
+
+=item path
+
+Return the element context in a form similar to XPath's short
+form: 'C</root/gi1/../gi>'
+
+=item xpath
+
+Return a unique XPath expression that can be used to find the element
+again. 
+
+It looks like C</doc/sect[3]/title>: unique elements do not have an index,
+the others do.
+
+=item private methods
+
+Low-level methods on the twig:
+
+=over 4
+
+=item set_parent        ($parent)
+
+=item set_first_child   ($first_child)
+
+=item set_last_child    ($last_child)
+
+=item set_prev_sibling  ($prev_sibling)
+
+=item set_next_sibling  ($next_sibling)
+
+=item set_twig_current
+
+=item del_twig_current
+
+=item twig_current
+
+=item flush
+
+This method should NOT be used, always flush the twig, not an element.
+
+=item contains_text
+
+=back
+
+Those methods should not be used, unless of course you find some creative 
+and interesting, not to mention useful, ways to do it.
+
+=back
+
+=head2 cond
+
+Most of the navigation functions accept a condition as an optional argument
+The first element (or all elements for C<L<children|children> > or 
+C<L<ancestors|ancestors> >) that passes the condition is returned.
+
+The condition is a single step of an XPath expression using the XPath subset
+defined by C<L<get_xpath>>. Additional conditions are:
+
+The condition can be 
+
+=over 4
+
+=item #ELT
+
+return a "real" element (not a PCDATA, CDATA, comment or pi element) 
+
+=item #TEXT
+
+return a PCDATA or CDATA element
+
+=item regular expression
+
+return an element whose gi matches the regexp. The regexp has to be created 
+with C<qr//> (hence this is available only on perl 5.005 and above)
+
+=item code reference
+
+applies the code, passing the current element as argument, if the code returns
+true then the element is returned, if it returns false then the code is applied
+to the next candidate.
+
+=back
+
+=head2 XML::Twig::XPath
+
+XML::Twig implements a subset of XPath through the C<L<get_xpath>> method. 
+
+If you want to use the whole XPath power, then you can use C<XML::Twig::XPath>
+instead. In this case C<XML::Twig> uses C<XML::XPath> to execute XPath queries.
+You will of course need C<XML::XPath> installed to be able to use C<XML::Twig::XPath>.
+
+See L<XML::XPath> for more information.
+
+The methods you can use are:
+
+=over 4
+
+=item findnodes              ($path)
+
+return a list of nodes found by C<$path>.
+
+=item findnodes_as_string    ($path)
+
+return the nodes found reproduced as XML. The result is not guaranteed
+to be valid XML though.
+
+=item findvalue              ($path)
+
+return the concatenation of the text content of the result nodes
+
+=back
+
+In order for C<XML::XPath> to be used as the XPath engine the following methods
+are included in C<XML::Twig>:
+
+in XML::Twig
+
+=over 4
+
+=item getRootNode
+
+=item getParentNode
+
+=item getChildNodes 
+
+=back
+
+in XML::Twig::Elt
+
+=over 4
+
+=item string_value
+
+=item toString
+
+=item getName
+
+=item getRootNode
+
+=item getNextSibling
+
+=item getPreviousSibling
+
+=item isElementNode
+
+=item isTextNode
+
+=item isPI
+
+=item isPINode
+
+=item isProcessingInstructionNode
+
+=item isComment
+
+=item isCommentNode
+
+=item getTarget 
+
+=item getChildNodes 
+
+=item getElementById
+
+=back
+
+=head2 XML::Twig::XPath::Elt
+
+The methods you can use are the same as on C<XML::Twig::XPath> elements:
+
+=over 4
+
+=item findnodes              ($path)
+
+return a list of nodes found by C<$path>.
+
+=item findnodes_as_string    ($path)
+
+return the nodes found reproduced as XML. The result is not guaranteed
+to be valid XML though.
+
+=item findvalue              ($path)
+
+return the concatenation of the text content of the result nodes
+
+=back
+
+
+=head2 XML::Twig::Entity_list
+
+=over 4
+
+=item new
+
+Create an entity list.
+
+=item add         ($ent)
+
+Add an entity to an entity list.
+
+=item add_new_ent ($name, $val, $sysid, $pubid, $ndata)
+
+Create a new entity and add it to the entity list
+
+=item delete     ($ent or $gi).
+
+Delete an entity (defined by its name or by the Entity object)
+from the list.
+
+=item print      ($optional_filehandle)
+
+Print the entity list.
+
+=item list
+
+Return the list as an array
+
+=back
+
+
+=head2 XML::Twig::Entity
+
+=over 4
+
+=item new        ($name, $val, $sysid, $pubid, $ndata)
+
+Same arguments as the Entity handler for XML::Parser.
+
+=item print       ($optional_filehandle)
+
+Print an entity declaration.
+
+=item name 
+
+Return the name of the entity
+
+=item val  
+
+Return the value of the entity
+
+=item sysid
+
+Return the system id for the entity (for NDATA entities)
+
+=item pubid
+
+Return the public id for the entity (for NDATA entities)
+
+=item ndata
+
+Return true if the entity is an NDATA entity
+
+=item text
+
+Return the entity declaration text.
+
+=back
+
+
+=head1 EXAMPLES
+
+Additional examples (and a complete tutorial) can be found  on the
+F<XML::Twig PageL<http://www.xmltwig.com/xmltwig/>>
+
+To figure out what flush does call the following script with an
+XML file and an element name as arguments
+
+  use XML::Twig;
+
+  my ($file, $elt)= @ARGV;
+  my $t= XML::Twig->new( twig_handlers => 
+      { $elt => sub {$_[0]->flush; print "\n[flushed here]\n";} });
+  $t->parsefile( $file, ErrorContext => 2);
+  $t->flush;
+  print "\n";
+
+
+=head1 NOTES
+
+=head2 Subclassing XML::Twig
+
+Useful methods:
+
+=over 4
+
+=item elt_class
+
+In order to subclass C<XML::Twig> you will probably need to subclass also
+C<L<XML::Twig::Elt>>. Use the C<elt_class> option when you create the
+C<XML::Twig> object to get the elements created in a different class
+(which should be a subclass of C<XML::Twig::Elt>.
+
+=item add_options
+
+If you inherit C<XML::Twig> new method but want to add more options to it
+you can use this method to prevent XML::Twig to issue warnings for those
+additional options.
+
+=back
+
+=head2 DTD Handling
+
+There are 3 possibilities here.  They are:
+
+=over 4
+
+=item No DTD
+
+No doctype, no DTD information, no entity information, the world is simple...
+
+=item Internal DTD
+
+The XML document includes an internal DTD, and maybe entity declarations.
+
+If you use the load_DTD option when creating the twig the DTD information and
+the entity declarations can be accessed.
+
+The DTD and the entity declarations will be C<flush>'ed (or C<print>'ed) either
+as is (if they have not been modified) or as reconstructed (poorly, comments 
+are lost, order is not kept, due to it's content this DTD should not be viewed 
+by anyone) if they have been modified. You can also modify them directly by 
+changing the C<< $twig->{twig_doctype}->{internal} >> field (straight from 
+XML::Parser, see the C<Doctype> handler doc)
+
+=item External DTD
+
+The XML document includes a reference to an external DTD, and maybe entity 
+declarations.
+
+If you use the C<load_DTD> when creating the twig the DTD information and the 
+entity declarations can be accessed. The entity declarations will be
+C<flush>'ed (or C<print>'ed) either as is (if they have not been modified) or
+as reconstructed (badly, comments are lost, order is not kept).
+
+You can change the doctype through the C<< $twig->set_doctype >> method and 
+print the dtd through the C<< $twig->dtd_text >> or C<< $twig->dtd_print >>
+ methods.
+
+If you need to modify the entity list this is probably the easiest way to do it.
+
+=back
+
+
+=head2 Flush
+
+If you set handlers and use C<flush>, do not forget to flush the twig one
+last time AFTER the parsing, or you might be missing the end of the document.
+
+Remember that element handlers are called when the element is CLOSED, so
+if you have handlers for nested elements the inner handlers will be called
+first. It makes it for example trickier than it would seem to number nested
+clauses.
+
+
+
+=head1 BUGS
+
+=over 4
+
+=item entity handling
+
+Due to XML::Parser behaviour, non-base entities in attribute values disappear:
+C<att="val&ent;"> will be turned into C<< att => val >>, unless you use the 
+C<keep_encoding> argument to C<< XML::Twig->new >> 
+
+=item DTD handling
+
+Basically the DTD handling methods are competely bugged. No one uses them and
+it seems very difficult to get them to work in all cases, including with 
+several slightly incompatible versions of XML::Parser and of libexpat.
+
+So use XML::Twig with standalone documents, or with documents refering to an
+external DTD, but don't expect it to properly parse and even output back the
+DTD.
+
+=item memory leak
+
+If you use a lot of twigs you might find that you leak quite a lot of memory
+(about 2Ks per twig). You can use the C<L<dispose|dispose> > method to free 
+that memory after you are done.
+
+If you create elements the same thing might happen, use the C<L<delete|delete>>
+method to get rid of them.
+
+Alternatively installing the C<Scalar::Util> (or C<WeakRef>) module on a version 
+of Perl that supports it (>5.6.0) will get rid of the memory leaks automagically.
+
+=item ID list
+
+The ID list is NOT updated when ID's are modified or elements cut or
+deleted.
+
+=item change_gi
+
+This method will not function properly if you do:
+
+     $twig->change_gi( $old1, $new);
+     $twig->change_gi( $old2, $new);
+     $twig->change_gi( $new, $even_newer);
+
+=item sanity check on XML::Parser method calls
+
+XML::Twig should really prevent calls to some XML::Parser methods, especially 
+the C<setHandlers> method.
+
+=item pretty printing
+
+Pretty printing (at least using the 'C<indented>' style) is hard to get right! 
+Only elements that belong to the document will be properly indented. Printing 
+elements that do not belong to the twig makes it impossible for XML::Twig to 
+figure out their depth, and thus their indentation level.
+
+Also there is an anavoidable bug when using C<flush> and pretty printing for
+elements with mixed content that start with an embedded element:
+
+  <elt><b>b</b>toto<b>bold</b></elt>
+
+  will be output as 
+
+  <elt>
+    <b>b</b>toto<b>bold</b></elt>
+
+if you flush the twig when you find the C<< <b> >> element
+  
+
+=back
+
+=head1 Globals
+
+These are the things that can mess up calling code, especially if threaded.
+They might also cause problem under mod_perl. 
+
+=over 4
+
+=item Exported constants
+
+Whether you want them or not you get them! These are subroutines to use
+as constant when creating or testing elements
+
+  PCDATA  return '#PCDATA'
+  CDATA   return '#CDATA'
+  PI      return '#PI', I had the choice between PROC and PI :--(
+
+=item Module scoped values: constants
+
+these should cause no trouble:
+
+  %base_ent= ( '>' => '&gt;',
+               '<' => '&lt;',
+               '&' => '&amp;',
+               "'" => '&apos;',
+               '"' => '&quot;',
+             );
+  CDATA_START   = "<![CDATA[";
+  CDATA_END     = "]]>";
+  PI_START      = "<?";
+  PI_END        = "?>";
+  COMMENT_START = "<!--";
+  COMMENT_END   = "-->";
+
+pretty print styles
+
+  ( $NSGMLS, $NICE, $INDENTED, $RECORD1, $RECORD2)= (1..5);
+
+empty tag output style
+
+  ( $HTML, $EXPAND)= (1..2);
+
+=item Module scoped values: might be changed
+
+Most of these deal with pretty printing, so the worst that can
+happen is probably that XML output does not look right, but is
+still valid and processed identically by XML processors.
+
+C<$empty_tag_style> can mess up HTML bowsers though and changing C<$ID> 
+would most likely create problems.
+
+  $pretty=0;           # pretty print style
+  $quote='"';          # quote for attributes
+  $INDENT= '  ';       # indent for indented pretty print
+  $empty_tag_style= 0; # how to display empty tags
+  $ID                  # attribute used as a gi ('id' by default)
+
+=item Module scoped values: definitely changed
+
+These 2 variables are used to replace gi's by an index, thus 
+saving some space when creating a twig. If they really cause
+you too much trouble, let me know, it is probably possible to
+create either a switch or at least a version of XML::Twig that 
+does not perform this optimisation.
+
+  %gi2index;     # gi => index
+  @index2gi;     # list of gi's
+
+=back
+
+If you need to manipulate all those values, you can use the following methods on the
+XML::Twig object:
+
+=over 4
+
+=item global_state
+
+Return a hasref with all the global variables used by XML::Twig
+
+The hash has the following fields:  C<pretty>, C<quote>, C<indent>, 
+C<empty_tag_style>, C<keep_encoding>, C<expand_external_entities>, 
+C<output_filter>, C<output_text_filter>, C<keep_atts_order>
+
+=item set_global_state ($state)
+
+Set the global state, C<$state> is a hashref
+
+=item save_global_state
+
+Save the current global state
+
+=item restore_global_state
+
+Restore the previously saved (using C<Lsave_global_state>> state
+
+=back
+
+=head1 TODO 
+
+=over 4
+
+=item SAX handlers
+
+Allowing XML::Twig to work on top of any SAX parser
+
+=item multiple twigs are not well supported
+
+A number of twig features are just global at the moment. These include
+the ID list and the "gi pool" (if you use C<change_gi> then you change the gi 
+for ALL twigs).
+
+A future version will try to support this while trying not to be to
+hard on performance (at least when a single twig is used!).
+
+
+=back
+
+
+=head1 AUTHOR
+
+Michel Rodriguez <mirod@xmltwig.com>
+
+=head1 LICENSE
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+Bug reports should be sent using:
+F<RTL<http://rt.cpan.org/NoAuth/Bugs.html?Dist=XML-Twig>>
+
+Comments can be sent to mirod@xmltwig.com
+
+The XML::Twig page is at L<http://www.xmltwig.com/xmltwig/>
+It includes the development version of the module, a slightly better version 
+of the documentation, examples, a tutorial and a: 
+F<Processing XML efficiently with Perl and XML::Twig: 
+L<http://www.xmltwig.com/xmltwig/tutorial/index.html>>
+
+=head1 SEE ALSO
+
+XML::Parser,XML::Parser::Expat, Encode, Text::Iconv, Scalar::Utils
+
+
+=cut
+
+
Index: /gsdl/stable/perllib/cpan/XML/XPath/Variable.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/Variable.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/Variable.pm	(revision 20131)
@@ -0,0 +1,43 @@
+# $Id$
+
+package XML::XPath::Variable;
+use strict;
+
+# This class does NOT contain 1 instance of a variable
+# see the XML::XPath::Parser class for the instances
+# This class simply holds the name of the var
+
+sub new {
+    my $class = shift;
+    my ($pp, $name) = @_;
+    bless { name => $name, path_parser => $pp }, $class;
+}
+
+sub as_string {
+    my $self = shift;
+    '\$' . $self->{name};
+}
+
+sub as_xml {
+    my $self = shift;
+    return "<Variable>" . $self->{name} . "</Variable>\n";
+}
+
+sub get_value {
+    my $self = shift;
+    $self->{path_parser}->get_var($self->{name});
+}
+
+sub set_value {
+    my $self = shift;
+    my ($val) = @_;
+    $self->{path_parser}->set_var($self->{name}, $val);
+}
+
+sub evaluate {
+    my $self = shift;
+    my $val = $self->get_value;
+    return $val;
+}
+
+1;
Index: /gsdl/stable/perllib/cpan/XML/XPath/XMLParser.pm
===================================================================
--- /gsdl/stable/perllib/cpan/XML/XPath/XMLParser.pm	(revision 20131)
+++ /gsdl/stable/perllib/cpan/XML/XPath/XMLParser.pm	(revision 20131)
@@ -0,0 +1,385 @@
+# $Id$
+
+package XML::XPath::XMLParser;
+
+use strict;
+
+use XML::Parser;
+#use XML::XPath;
+use XML::XPath::Node;
+use XML::XPath::Node::Element;
+use XML::XPath::Node::Text;
+use XML::XPath::Node::Comment;
+use XML::XPath::Node::PI;
+use XML::XPath::Node::Attribute;
+use XML::XPath::Node::Namespace;
+
+my @options = qw(
+        filename
+        xml
+        parser
+        ioref
+        );
+
+my ($_current, $_namespaces_on);
+my %IdNames;
+
+use vars qw/$xmlns_ns $xml_ns/;
+
+$xmlns_ns = "http://www.w3.org/2000/xmlns/";
+$xml_ns = "http://www.w3.org/XML/1998/namespace";
+
+sub new {
+    my $proto = shift;
+    my $class = ref($proto) || $proto;
+    my %args = @_;
+    my %hash = map(( "_$_" => $args{$_} ), @options);
+    bless \%hash, $class;
+}
+
+sub parse {
+    my $self = shift;
+    
+    $self->{IdNames} = {};
+    $self->{InScopeNamespaceStack} = [ { 
+            '_Default' => undef,
+            'xmlns' => $xmlns_ns,
+            'xml' => $xml_ns,
+        } ];
+    
+    $self->{NodeStack} = [ ];
+    
+    $self->set_xml($_[0]) if $_[0];
+    
+    my $parser = $self->get_parser || XML::Parser->new(
+            ErrorContext => 2,
+            ParseParamEnt => 1,
+            );
+    
+    $parser->setHandlers(
+            Init => sub { $self->parse_init(@_) },
+            Char => sub { $self->parse_char(@_) },
+            Start => sub { $self->parse_start(@_) },
+            End => sub { $self->parse_end(@_) },
+            Final => sub { $self->parse_final(@_) },
+            Proc => sub { $self->parse_pi(@_) },
+            Comment => sub { $self->parse_comment(@_) },
+            Attlist => sub { $self->parse_attlist(@_) },
+            );
+    
+    my $toparse;
+    if ($toparse = $self->get_filename) {
+        return $parser->parsefile($toparse);
+    }
+    else {
+        return $parser->parse($self->get_xml || $self->get_ioref);
+    }
+}
+
+sub parsefile {
+    my $self = shift;
+    my ($filename) = @_;
+    $self->set_filename($filename);
+    $self->parse;
+}
+
+sub parse_init {
+    my $self = shift;
+    my $e = shift;
+    my $document = XML::XPath::Node::Element->new();
+    my $newns = XML::XPath::Node::Namespace->new('xml', $xml_ns);
+    $document->appendNamespace($newns);
+    $self->{current} = $self->{DOC_Node} = $document;
+}
+
+sub parse_final {
+    my $self = shift;
+    return $self->{DOC_Node};
+}
+
+sub parse_char {
+    my $self = shift;
+    my $e = shift;
+    my $text = shift;
+    
+    my $parent = $self->{current};
+    
+    my $last = $parent->getLastChild;
+    if ($last && $last->isTextNode) {
+        # append to previous text node
+        $last->appendText($text);
+        return;
+    }
+    
+    my $node = XML::XPath::Node::Text->new($text);
+    $parent->appendChild($node, 1);
+}
+
+sub parse_start {
+    my $self = shift;
+    my $e = shift;
+    my $tag = shift;
+    
+    push @{ $self->{InScopeNamespaceStack} },
+         { %{ $self->{InScopeNamespaceStack}[-1] } };
+    $self->_scan_namespaces(@_);
+    
+    my ($prefix, $namespace) = $self->_namespace($tag);
+    
+    my $node = XML::XPath::Node::Element->new($tag, $prefix);
+    
+    my @attributes;
+    for (my $ii = 0; $ii < $#_; $ii += 2) {
+	my ($name, $value) = ($_[$ii], $_[$ii+1]);
+        if ($name =~ /^xmlns(:(.*))?$/) {
+            # namespace node
+            my $prefix = $2 || '#default';
+#            warn "Creating NS node: $prefix = $value\n";
+            my $newns = XML::XPath::Node::Namespace->new($prefix, $value);
+            $node->appendNamespace($newns);
+        }
+        else {
+	    my ($prefix, $namespace) = $self->_namespace($name);
+            undef $namespace unless $prefix;
+
+            my $newattr = XML::XPath::Node::Attribute->new($name, $value, $prefix);
+            $node->appendAttribute($newattr, 1);
+            if (exists($self->{IdNames}{$tag}) && ($self->{IdNames}{$tag} eq $name)) {
+    #            warn "appending Id Element: $val for ", $node->getName, "\n";
+                $self->{DOC_Node}->appendIdElement($value, $node);
+            }
+        }
+    }
+        
+    $self->{current}->appendChild($node, 1);
+    $self->{current} = $node;
+}
+
+sub parse_end {
+    my $self = shift;
+    my $e = shift;
+    $self->{current} = $self->{current}->getParentNode;
+}
+
+sub parse_pi {
+    my $self = shift;
+    my $e = shift;
+    my ($target, $data) = @_;
+    my $node = XML::XPath::Node::PI->new($target, $data);
+    $self->{current}->appendChild($node, 1);
+}
+
+sub parse_comment {
+    my $self = shift;
+    my $e = shift;
+    my ($data) = @_;
+    my $node = XML::XPath::Node::Comment->new($data);
+    $self->{current}->appendChild($node, 1);
+}
+
+sub parse_attlist {
+    my $self = shift;
+    my $e = shift;
+    my ($elname, $attname, $type, $default, $fixed) = @_;
+    if ($type eq 'ID') {
+        $self->{IdNames}{$elname} = $attname;
+    }
+}
+
+sub _scan_namespaces {
+    my ($self, %attributes) = @_;
+
+    while (my ($attr_name, $value) = each %attributes) {
+	if ($attr_name eq 'xmlns') {
+	    $self->{InScopeNamespaceStack}[-1]{'_Default'} = $value;
+	} elsif ($attr_name =~ /^xmlns:(.*)$/) {
+	    my $prefix = $1;
+	    $self->{InScopeNamespaceStack}[-1]{$prefix} = $value;
+	}
+    }
+}
+
+sub _namespace {
+    my ($self, $name) = @_;
+
+    my ($prefix, $localname) = split(/:/, $name);
+    if (!defined($localname)) {
+	if ($prefix eq 'xmlns') {
+	    return '', undef;
+	} else {
+	    return '', $self->{InScopeNamespaceStack}[-1]{'_Default'};
+	}
+    } else {
+	return $prefix, $self->{InScopeNamespaceStack}[-1]{$prefix};
+    }
+}
+
+sub as_string {
+    my $node = shift;
+    $node->toString;
+}
+
+sub get_parser { shift->{_parser}; }
+sub get_filename { shift->{_filename}; }
+sub get_xml { shift->{_xml}; }
+sub get_ioref { shift->{_ioref}; }
+
+sub set_parser { $_[0]->{_parser} = $_[1]; }
+sub set_filename { $_[0]->{_filename} = $_[1]; }
+sub set_xml { $_[0]->{_xml} = $_[1]; }
+sub set_ioref { $_[0]->{_ioref} = $_[1]; }
+
+1;
+
+__END__
+
+=head1 NAME
+
+XML::XPath::XMLParser - The default XML parsing class that produces a node tree
+
+=head1 SYNOPSIS
+
+    my $parser = XML::XPath::XMLParser->new(
+                filename => $self->get_filename,
+                xml => $self->get_xml,
+                ioref => $self->get_ioref,
+                parser => $self->get_parser,
+            );
+    my $root_node = $parser->parse;
+
+=head1 DESCRIPTION
+
+This module generates a node tree for use as the context node for XPath processing.
+It aims to be a quick parser, nothing fancy, and yet has to store more information
+than most parsers. To achieve this I've used array refs everywhere - no hashes.
+I don't have any performance figures for the speedups achieved, so I make no
+appologies for anyone not used to using arrays instead of hashes. I think they
+make good sense here where we know the attributes of each type of node.
+
+=head1 Node Structure
+
+All nodes have the same first 2 entries in the array: node_parent
+and node_pos. The type of the node is determined using the ref() function.
+The node_parent always contains an entry for the parent of the current
+node - except for the root node which has undef in there. And node_pos is the
+position of this node in the array that it is in (think: 
+$node == $node->[node_parent]->[node_children]->[$node->[node_pos]] )
+
+Nodes are structured as follows:
+
+=head2 Root Node
+
+The root node is just an element node with no parent.
+
+    [
+      undef, # node_parent - check for undef to identify root node
+      undef, # node_pos
+      undef, # node_prefix
+      [ ... ], # node_children (see below)
+    ]
+
+=head2 Element Node
+
+    [
+      $parent, # node_parent
+      <position in current array>, # node_pos
+      'xxx', # node_prefix - namespace prefix on this element
+      [ ... ], # node_children
+      'yyy', # node_name - element tag name
+      [ ... ], # node_attribs - attributes on this element
+      [ ... ], # node_namespaces - namespaces currently in scope
+    ]
+
+=head2 Attribute Node
+
+    [
+      $parent, # node_parent - the element node
+      <position in current array>, # node_pos
+      'xxx', # node_prefix - namespace prefix on this element
+      'href', # node_key - attribute name
+      'ftp://ftp.com/', # node_value - value in the node
+    ]
+
+=head2 Namespace Nodes
+
+Each element has an associated set of namespace nodes that are currently
+in scope. Each namespace node stores a prefix and the expanded name (retrieved
+from the xmlns:prefix="..." attribute).
+
+    [
+      $parent,
+      <pos>,
+      'a', # node_prefix - the namespace as it was written as a prefix
+      'http://my.namespace.com', # node_expanded - the expanded name.
+    ]
+
+=head2 Text Nodes
+
+    [
+      $parent,
+      <pos>,
+      'This is some text' # node_text - the text in the node
+    ]
+
+=head2 Comment Nodes
+
+    [
+      $parent,
+      <pos>,
+      'This is a comment' # node_comment
+    ]
+
+=head2 Processing Instruction Nodes
+
+    [
+      $parent,
+      <pos>,
+      'target', # node_target
+      'data', # node_data
+    ]
+
+=head1 Usage
+
+If you feel the need to use this module outside of XML::XPath (for example
+you might use this module directly so that you can cache parsed trees), you
+can follow the following API:
+
+=head2 new
+
+The new method takes either no parameters, or any of the following parameters:
+
+        filename
+        xml
+        parser
+        ioref
+
+This uses the familiar hash syntax, so an example might be:
+
+    use XML::XPath::XMLParser;
+    
+    my $parser = XML::XPath::XMLParser->new(filename => 'example.xml');
+
+The parameters represent a filename, a string containing XML, an XML::Parser
+instance and an open filehandle ref respectively. You can also set or get all
+of these properties using the get_ and set_ functions that have the same
+name as the property: e.g. get_filename, set_ioref, etc.
+
+=head2 parse
+
+The parse method generally takes no parameters, however you are free to
+pass either an open filehandle reference or an XML string if you so require.
+The return value is a tree that XML::XPath can use. The parse method will
+die if there is an error in your XML, so be sure to use perl's exception
+handling mechanism (eval{};) if you want to avoid this.
+
+=head2 parsefile
+
+The parsefile method is identical to parse() except it expects a single
+parameter that is a string naming a file to open and parse. Again it
+returns a tree and also dies if there are XML errors.
+
+=head1 NOTICES
+
+This file is distributed as part of the XML::XPath module, and is copyright
+2000 Fastnet Software Ltd. Please see the documentation for the module as a
+whole for licencing information.
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/autosplit.ix
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/autosplit.ix	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/autosplit.ix	(revision 20131)
@@ -0,0 +1,29 @@
+# Index created by AutoSplit for lib/Image/Size.pm
+#    (file acts as timestamp)
+package Image::Size;
+sub gifsize 
+;
+sub xbmsize 
+;
+sub xpmsize 
+;
+sub pngsize 
+;
+sub mngsize 
+;
+sub jpegsize 
+;
+sub ppmsize 
+;
+sub tiffsize  ;
+sub bmpsize 
+;
+sub psdsize 
+;
+sub swfsize 
+;
+sub pcdsize 
+;
+sub swfmxsize 
+;
+1;
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/bmpsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/bmpsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/bmpsize.al	(revision 20131)
@@ -0,0 +1,25 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 1052 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/bmpsize.al)"
+# bmpsize: size a Windows-ish BitMaP image
+#
+# Adapted from code contributed by Aldo Calpini <a.calpini@romagiubileo.it>
+sub bmpsize
+{
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef, "Unable to determine size of BMP data");
+    my ($buffer);
+
+    $buffer = &$read_in($stream, 26);
+    ($x, $y) = unpack("x18VV", $buffer);
+    $id = 'BMP' if (defined $x and defined $y);
+
+    ($x, $y, $id);
+}
+
+# end of Image::Size::bmpsize
+1;
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/gifsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/gifsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/gifsize.al	(revision 20131)
@@ -0,0 +1,148 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 668 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/gifsize.al)"
+###########################################################################
+# Subroutine gets the size of the specified GIF
+###########################################################################
+sub gifsize
+{
+    my $stream = shift;
+
+    my ($cmapsize, $buf, $sh, $sw, $h, $w, $x, $y, $type);
+
+    my $gif_blockskip = sub {
+        my ($skip, $type) = @_;
+        my ($lbuf);
+
+        &$read_in($stream, $skip);        # Skip header (if any)
+        while (1)
+        {
+            if (&img_eof($stream))
+            {
+                return (undef, undef,
+                        "Invalid/Corrupted GIF (at EOF in GIF $type)");
+            }
+            $lbuf = &$read_in($stream, 1);        # Block size
+            last if ord($lbuf) == 0;     # Block terminator
+            &$read_in($stream, ord($lbuf));  # Skip data
+        }
+    };
+
+    return (undef, undef,
+            'Out-of-range value for $Image::Size::GIF_BEHAVIOR: ' .
+            $Image::Size::GIF_BEHAVIOR)
+        if ($Image::Size::GIF_BEHAVIOR > 2);
+
+    # Skip over the identifying string, since we already know this is a GIF
+    $type = &$read_in($stream, 6);
+    if (length($buf = &$read_in($stream, 7)) != 7 )
+    {
+        return (undef, undef, "Invalid/Corrupted GIF (bad header)");
+    }
+    ($sw, $sh, $x) = unpack("vv C", $buf);
+    if ($Image::Size::GIF_BEHAVIOR == 0)
+    {
+        return ($sw, $sh, 'GIF');
+    }
+
+    if ($x & 0x80)
+    {
+        $cmapsize = 3 * (2**(($x & 0x07) + 1));
+        if (! &$read_in($stream, $cmapsize))
+        {
+            return (undef, undef,
+                    "Invalid/Corrupted GIF (global color map too small?)");
+        }
+    }
+
+    # Before we start this loop, set $sw and $sh to 0s and use them to track
+    # the largest sub-image in the overall GIF.
+    $sw = $sh = 0;
+
+  FINDIMAGE:
+    while (1)
+    {
+        if (&img_eof($stream))
+        {
+            # At this point, if we haven't returned then the user wants the
+            # largest of the sub-images. So, if $sh and $sw are still 0s, then
+            # we didn't see even one Image Descriptor block. Otherwise, return
+            # those two values.
+            if ($sw and $sh)
+            {
+                return ($sw, $sh, 'GIF');
+            }
+            else
+            {
+                return (undef, undef,
+                        "Invalid/Corrupted GIF (no Image Descriptors)");
+            }
+        }
+        $buf = &$read_in($stream, 1);
+        ($x) = unpack("C", $buf);
+        if ($x == 0x2c)
+        {
+            # Image Descriptor (GIF87a, GIF89a 20.c.i)
+            if (length($buf = &$read_in($stream, 8)) != 8)
+            {
+                return (undef, undef,
+                        "Invalid/Corrupted GIF (missing image header?)");
+            }
+            ($x, $y) = unpack("x4 vv", $buf);
+            return ($x, $y, 'GIF') if ($Image::Size::GIF_BEHAVIOR == 1);
+            if ($x > $sw and $y > $sh)
+            {
+                $sw = $x;
+                $sh = $y;
+            }
+        }
+        if ($x == 0x21)
+        {
+            # Extension Introducer (GIF89a 23.c.i, could also be in GIF87a)
+            $buf = &$read_in($stream, 1);
+            ($x) = unpack("C", $buf);
+            if ($x == 0xF9)
+            {
+                # Graphic Control Extension (GIF89a 23.c.ii)
+                &$read_in($stream, 6);    # Skip it
+                next FINDIMAGE;       # Look again for Image Descriptor
+            }
+            elsif ($x == 0xFE)
+            {
+                # Comment Extension (GIF89a 24.c.ii)
+                &$gif_blockskip(0, "Comment");
+                next FINDIMAGE;       # Look again for Image Descriptor
+            }
+            elsif ($x == 0x01)
+            {
+                # Plain Text Label (GIF89a 25.c.ii)
+                &$gif_blockskip(13, "text data");
+                next FINDIMAGE;       # Look again for Image Descriptor
+            }
+            elsif ($x == 0xFF)
+            {
+                # Application Extension Label (GIF89a 26.c.ii)
+                &$gif_blockskip(12, "application data");
+                next FINDIMAGE;       # Look again for Image Descriptor
+            }
+            else
+            {
+                return (undef, undef,
+                        sprintf("Invalid/Corrupted GIF (Unknown " .
+                                "extension %#x)", $x));
+            }
+        }
+        else
+        {
+            return (undef, undef,
+                    sprintf("Invalid/Corrupted GIF (Unknown code %#x)",
+                            $x));
+        }
+    }
+}
+
+# end of Image::Size::gifsize
+1;
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/jpegsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/jpegsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/jpegsize.al	(revision 20131)
@@ -0,0 +1,62 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 896 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/jpegsize.al)"
+# jpegsize: gets the width and height (in pixels) of a jpeg file
+# Andrew Tong, werdna@ugcs.caltech.edu           February 14, 1995
+# modified slightly by alex@ed.ac.uk
+# and further still by rjray@blackperl.com
+# optimization and general re-write from tmetro@vl.com
+sub jpegsize
+{
+    my $stream = shift;
+
+    my $MARKER      = "\xFF";       # Section marker.
+
+    my $SIZE_FIRST  = 0xC0;         # Range of segment identifier codes
+    my $SIZE_LAST   = 0xC3;         #  that hold size info.
+
+    my ($x, $y, $id) = (undef, undef, "could not determine JPEG size");
+
+    my ($marker, $code, $length);
+    my $segheader;
+
+    # Dummy read to skip header ID
+    &$read_in($stream, 2);
+    while (1)
+    {
+        $length = 4;
+        $segheader = &$read_in($stream, $length);
+
+        # Extract the segment header.
+        ($marker, $code, $length) = unpack("a a n", $segheader);
+
+        # Verify that it's a valid segment.
+        if ($marker ne $MARKER)
+        {
+            # Was it there?
+            $id = "JPEG marker not found";
+            last;
+        }
+        elsif ((ord($code) >= $SIZE_FIRST) && (ord($code) <= $SIZE_LAST))
+        {
+            # Segments that contain size info
+            $length = 5;
+            ($y, $x) = unpack("xnn", &$read_in($stream, $length));
+            $id = 'JPG';
+            last;
+        }
+        else
+        {
+            # Dummy read to skip over data
+            &$read_in($stream, ($length - 2));
+        }
+    }
+
+    ($x, $y, $id);
+}
+
+# end of Image::Size::jpegsize
+1;
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/mngsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/mngsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/mngsize.al	(revision 20131)
@@ -0,0 +1,32 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 872 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/mngsize.al)"
+# mngsize: gets the width and height (in pixels) of an MNG file.
+# See <URL:http://www.libpng.org/pub/mng/spec/> for the specification.
+#
+# Basically a copy of pngsize.
+sub mngsize
+{
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef, "could not determine MNG size");
+    my ($offset, $length);
+
+    # Offset to first Chunk Type code = 8-byte ident + 4-byte chunk length + 1
+    $offset = 12; $length = 4;
+    if (&$read_in($stream, $length, $offset) eq 'MHDR')
+    {
+        # MHDR = Image Header
+        $length = 8;
+        ($x, $y) = unpack("NN", &$read_in($stream, $length));
+        $id = 'MNG';
+    }
+
+    ($x, $y, $id);
+}
+
+# end of Image::Size::mngsize
+1;
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/pcdsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/pcdsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/pcdsize.al	(revision 20131)
@@ -0,0 +1,28 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 1100 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/pcdsize.al)"
+# Suggested by Matt Mueller <mueller@wetafx.co.nz>, and based on a piece of
+# sample Perl code by a currently-unknown author. Credit will be placed here
+# once the name is determined.
+sub pcdsize
+{
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef, "Unable to determine size of PCD data");
+    my $buffer = &$read_in($stream, 0xf00);
+
+    # Second-tier sanity check
+    return ($x, $y, $id) unless (substr($buffer, 0x800, 3) eq 'PCD');
+
+    my $orient = ord(substr($buffer, 0x0e02, 1)) & 1; # Clear down to one bit
+    ($x, $y) = @{$Image::Size::PCD_MAP{lc $Image::Size::PCD_SCALE}}
+        [($orient ? (0, 1) : (1, 0))];
+
+    return ($x, $y, 'PCD');
+}
+
+# end of Image::Size::pcdsize
+1;
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/pngsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/pngsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/pngsize.al	(revision 20131)
@@ -0,0 +1,32 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 848 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/pngsize.al)"
+# pngsize : gets the width & height (in pixels) of a png file
+# cor this program is on the cutting edge of technology! (pity it's blunt!)
+#
+# Re-written and tested by tmetro@vl.com
+sub pngsize
+{
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef, "could not determine PNG size");
+    my ($offset, $length);
+
+    # Offset to first Chunk Type code = 8-byte ident + 4-byte chunk length + 1
+    $offset = 12; $length = 4;
+    if (&$read_in($stream, $length, $offset) eq 'IHDR')
+    {
+        # IHDR = Image Header
+        $length = 8;
+        ($x, $y) = unpack("NN", &$read_in($stream, $length));
+        $id = 'PNG';
+    }
+
+    ($x, $y, $id);
+}
+
+# end of Image::Size::pngsize
+1;
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/ppmsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/ppmsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/ppmsize.al	(revision 20131)
@@ -0,0 +1,37 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 950 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/ppmsize.al)"
+# ppmsize: gets data on the PPM/PGM/PBM family.
+#
+# Contributed by Carsten Dominik <dominik@strw.LeidenUniv.nl>
+sub ppmsize
+{
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef,
+                        "Unable to determine size of PPM/PGM/PBM data");
+    my $n;
+
+    my $header = &$read_in($stream, 1024);
+
+    # PPM file of some sort
+    $header =~ s/^\#.*//mg;
+    ($n, $x, $y) = ($header =~ /^(P[1-6])\s+(\d+)\s+(\d+)/s);
+    $id = "PBM" if $n eq "P1" || $n eq "P4";
+    $id = "PGM" if $n eq "P2" || $n eq "P5";
+    $id = "PPM" if $n eq "P3" || $n eq "P6";
+    if ($n eq 'P7')
+    {
+        # John Bradley's XV thumbnail pics (thanks to inwap@jomis.Tymnet.COM)
+        $id = 'XV';
+        ($x, $y) = ($header =~ /IMGINFO:(\d+)x(\d+)/s);
+    }
+
+    ($x, $y, $id);
+}
+
+# end of Image::Size::ppmsize
+1;
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/psdsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/psdsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/psdsize.al	(revision 20131)
@@ -0,0 +1,23 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 1069 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/psdsize.al)"
+# psdsize: determine the size of a PhotoShop save-file (*.PSD)
+sub psdsize
+{
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef, "Unable to determine size of PSD data");
+    my ($buffer);
+
+    $buffer = &$read_in($stream, 26);
+    ($y, $x) = unpack("x14NN", $buffer);
+    $id = 'PSD' if (defined $x and defined $y);
+
+    ($x, $y, $id);
+}
+
+# end of Image::Size::psdsize
+1;
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/swfmxsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/swfmxsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/swfmxsize.al	(revision 20131)
@@ -0,0 +1,29 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 1120 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/swfmxsize.al)"
+# swfmxsize: determine size of compressed ShockWave/Flash MX files. Adapted
+# from code sent by Victor Kuriashkin <victor@yasp.com>
+sub swfmxsize
+{
+    require Compress::Zlib;
+
+    my ($image) = @_;
+    my $header = &$read_in($image, 1058);
+    my $ver = _bin2int(unpack 'B8', substr($header, 3, 1));
+
+    my ($d, $status) = Compress::Zlib::inflateInit();
+    $header = $d->inflate(substr($header, 8, 1024));
+
+    my $bs = unpack 'B133', substr($header, 0, 9);
+    my $bits = _bin2int(substr($bs, 0, 5));
+    my $x = int(_bin2int(substr($bs, 5+$bits, $bits))/20);
+    my $y = int(_bin2int(substr($bs, 5+$bits*3, $bits))/20);
+
+    return ($x, $y, 'CWS');
+}
+
+1;
+# end of Image::Size::swfmxsize
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/swfsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/swfsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/swfsize.al	(revision 20131)
@@ -0,0 +1,24 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 1084 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/swfsize.al)"
+# swfsize: determine size of ShockWave/Flash files. Adapted from code sent by
+# Dmitry Dorofeev <dima@yasp.com>
+sub swfsize
+{
+    my $image  = shift;
+    my $header = &$read_in($image, 33);
+
+    my $ver = _bin2int(unpack 'B8', substr($header, 3, 1));
+    my $bs = unpack 'B133', substr($header, 8, 17);
+    my $bits = _bin2int(substr($bs, 0, 5));
+    my $x = int(_bin2int(substr($bs, 5+$bits, $bits))/20);
+    my $y = int(_bin2int(substr($bs, 5+$bits*3, $bits))/20);
+
+    return ($x, $y, 'SWF');
+}
+
+# end of Image::Size::swfsize
+1;
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/tiffsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/tiffsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/tiffsize.al	(revision 20131)
@@ -0,0 +1,81 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 979 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/tiffsize.al)"
+# tiffsize: size a TIFF image
+#
+# Contributed by Cloyce Spradling <cloyce@headgear.org>
+sub tiffsize {
+    my $stream = shift;
+
+    my ($x, $y, $id) = (undef, undef, "Unable to determine size of TIFF data");
+
+    my $endian = 'n';           # Default to big-endian; I like it better
+    my $header = &$read_in($stream, 4);
+    $endian = 'v' if ($header =~ /II\x2a\x00/o); # little-endian
+
+    # Set up an association between data types and their corresponding
+    # pack/unpack specification.  Don't take any special pains to deal with
+    # signed numbers; treat them as unsigned because none of the image
+    # dimensions should ever be negative.  (I hope.)
+    my @packspec = ( undef,     # nothing (shouldn't happen)
+                     'C',       # BYTE (8-bit unsigned integer)
+                     undef,     # ASCII
+                     $endian,   # SHORT (16-bit unsigned integer)
+                     uc($endian), # LONG (32-bit unsigned integer)
+                     undef,     # RATIONAL
+                     'c',       # SBYTE (8-bit signed integer)
+                     undef,     # UNDEFINED
+                     $endian,   # SSHORT (16-bit unsigned integer)
+                     uc($endian), # SLONG (32-bit unsigned integer)
+                     );
+
+    my $offset = &$read_in($stream, 4, 4); # Get offset to IFD
+    $offset = unpack(uc($endian), $offset); # Fix it so we can use it
+
+    my $ifd = &$read_in($stream, 2, $offset); # Get number of directory entries
+    my $num_dirent = unpack($endian, $ifd); # Make it useful
+    $offset += 2;
+    $num_dirent = $offset + ($num_dirent * 12); # Calc. maximum offset of IFD
+
+    # Do all the work
+    $ifd = '';
+    my $tag = 0;
+    my $type = 0;
+    while (!defined($x) || !defined($y)) {
+        $ifd = &$read_in($stream, 12, $offset); # Get first directory entry
+        last if (($ifd eq '') || ($offset > $num_dirent));
+        $offset += 12;
+        $tag = unpack($endian, $ifd); # ...and decode its tag
+        $type = unpack($endian, substr($ifd, 2, 2)); # ...and the data type
+        # Check the type for sanity.
+        next if (($type > @packspec+0) || (!defined($packspec[$type])));
+        if ($tag == 0x0100) {   # ImageWidth (x)
+            # Decode the value
+            $x = unpack($packspec[$type], substr($ifd, 8, 4));
+        } elsif ($tag == 0x0101) {      # ImageLength (y)
+            # Decode the value
+            $y = unpack($packspec[$type], substr($ifd, 8, 4));
+        }
+    }
+
+    # Decide if we were successful or not
+    if (defined($x) && defined($y)) {
+        $id = 'TIF';
+    } else {
+        $id = '';
+        $id = 'ImageWidth ' if (!defined($x));
+        if (!defined ($y)) {
+            $id .= 'and ' if ($id ne '');
+            $id .= 'ImageLength ';
+        }
+        $id .= 'tag(s) could not be found';
+    }
+
+    ($x, $y, $id);
+}
+
+# end of Image::Size::tiffsize
+1;
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/xbmsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/xbmsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/xbmsize.al	(revision 20131)
@@ -0,0 +1,25 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 808 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/xbmsize.al)"
+sub xbmsize
+{
+    my $stream = shift;
+
+    my $input;
+    my ($x, $y, $id) = (undef, undef, "Could not determine XBM size");
+
+    $input = &$read_in($stream, 1024);
+    if ($input =~ /^\#define\s*\S*\s*(\d+)\s*\n\#define\s*\S*\s*(\d+)/si)
+    {
+        ($x, $y) = ($1, $2);
+        $id = 'XBM';
+    }
+
+    ($x, $y, $id);
+}
+
+# end of Image::Size::xbmsize
+1;
Index: /gsdl/stable/perllib/cpan/auto/Image/Size/xpmsize.al
===================================================================
--- /gsdl/stable/perllib/cpan/auto/Image/Size/xpmsize.al	(revision 20131)
+++ /gsdl/stable/perllib/cpan/auto/Image/Size/xpmsize.al	(revision 20131)
@@ -0,0 +1,30 @@
+# NOTE: Derived from lib/Image/Size.pm.
+# Changes made here will be lost when autosplit is run again.
+# See AutoSplit.pm.
+package Image::Size;
+
+#line 825 "lib/Image/Size.pm (autosplit into blib/lib/auto/Image/Size/xpmsize.al)"
+# Added by Randy J. Ray, 30 Jul 1996
+# Size an XPM file by looking for the "X Y N W" line, where X and Y are
+# dimensions, N is the total number of colors defined, and W is the width of
+# a color in the ASCII representation, in characters. We only care about X & Y.
+sub xpmsize
+{
+    my $stream = shift;
+
+    my $line;
+    my ($x, $y, $id) = (undef, undef, "Could not determine XPM size");
+
+    while ($line = &$read_in($stream, 1024))
+    {
+        next unless ($line =~ /"\s*(\d+)\s+(\d+)(\s+\d+\s+\d+){1,2}\s*"/s);
+        ($x, $y) = ($1, $2);
+        $id = 'XPM';
+        last;
+    }
+
+    ($x, $y, $id);
+}
+
+# end of Image::Size::xpmsize
+1;
Index: /gsdl/stable/perllib/dbutil.pm
===================================================================
--- /gsdl/stable/perllib/dbutil.pm	(revision 20131)
+++ /gsdl/stable/perllib/dbutil.pm	(revision 20131)
@@ -0,0 +1,832 @@
+###########################################################################
+#
+# dbutil.pm -- utility functions for writing to different databases
+# Copyright (C) 2008  DL Consulting Ltd
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package dbutil;
+
+use Encode;
+use strict;
+
+
+sub open_infodb_write_handle
+{
+  my $infodb_type = shift(@_);
+  my $infodb_file_path = shift(@_);
+  
+  if ($infodb_type eq "sqlite") 
+  {
+    return &open_infodb_write_handle_sqlite($infodb_file_path);
+  } 
+  elsif ($infodb_type eq "gdbm-txtgz") 
+  {
+    return &open_infodb_write_handle_gdbm_txtgz($infodb_file_path);
+  } 
+  elsif ($infodb_type eq "mssql") 
+  {
+    return &open_infodb_write_handle_mssql($infodb_file_path);
+  } 
+
+  # Use GDBM if the infodb type is empty or not one of the values above
+  return &open_infodb_write_handle_gdbm($infodb_file_path);
+}
+
+
+sub close_infodb_write_handle
+{
+  my $infodb_type = shift(@_);
+  my $infodb_handle = shift(@_);
+
+  if ($infodb_type eq "sqlite")
+  {
+    return &close_infodb_write_handle_sqlite($infodb_handle);
+  }
+  elsif ($infodb_type eq "gdbm-txtgz")
+  {
+    return &close_infodb_write_handle_gdbm_txtgz($infodb_handle);
+  }
+  elsif ($infodb_type eq "mssql")
+  {
+    return &close_infodb_write_handle_mssql($infodb_handle);
+  }
+    
+  # Use GDBM if the infodb type is empty or not one of the values above
+  return &close_infodb_write_handle_gdbm($infodb_handle);
+}
+
+
+sub get_default_infodb_type
+{
+  # The default is GDBM so everything works the same for existing collections
+  # To use something else, specify the "infodbtype" in the collection's collect.cfg file
+  return "gdbm";
+}
+
+
+sub get_infodb_file_path
+{
+  my $infodb_type = shift(@_);
+  my $collection_name = shift(@_);
+  my $infodb_directory_path = shift(@_);
+
+  if ($infodb_type eq "sqlite")
+  {
+    return &get_infodb_file_path_sqlite($collection_name, $infodb_directory_path);
+  }
+  elsif ($infodb_type eq "gdbm-txtgz")
+  {
+    return &get_infodb_file_path_gdbm_txtgz($collection_name, $infodb_directory_path);
+  }
+  elsif ($infodb_type eq "mssql")
+  {
+    #==================================================================================================#
+    # Updated by Jeffrey (2008/08/25 Monday)
+    # After look into the run-time code, it seems we should still create a database file.
+    # Since the run-time code is always try to read a database file, the easiest way here is not
+    # to change the whole structure, but to give whatever the system is looking for. 
+    #==================================================================================================#
+    # Added by Jeffrey (2008/08/15 Friday)
+    # No file path required for MS SQL, it is a server-client connection.
+    # At the moment the information is hard coded in open_infodb_write_handle_mssql
+    # the this might need some tidy up sometime.
+    #==================================================================================================#
+    return &get_infodb_file_path_mssql($collection_name, $infodb_directory_path); 
+  }
+  
+  # Use GDBM if the infodb type is empty or not one of the values above
+  return &get_infodb_file_path_gdbm($collection_name, $infodb_directory_path);
+}
+
+
+sub read_infodb_file
+{
+  my $infodb_type = shift(@_);
+  my $infodb_file_path = shift(@_);
+  my $infodb_map = shift(@_);
+
+  if ($infodb_type eq "sqlite")
+  {
+    return &read_infodb_file_sqlite($infodb_file_path, $infodb_map);
+  }
+  elsif ($infodb_type eq "gdbm-txtgz")
+  {
+    return &read_infodb_file_gdbm_txtgz($infodb_file_path, $infodb_map);
+  }
+  elsif ($infodb_type eq "mssql")
+  {
+    return &read_infodb_file_mssql($infodb_file_path, $infodb_map);
+  }
+  
+  # Use GDBM if the infodb type is empty or not one of the values above
+  return &read_infodb_file_gdbm($infodb_file_path, $infodb_map);
+}
+
+
+sub write_infodb_entry
+{
+  my $infodb_type = shift(@_);
+  my $infodb_handle = shift(@_);
+  my $infodb_key = shift(@_);
+  my $infodb_map = shift(@_);
+
+  if ($infodb_type eq "sqlite")
+  {
+    return &write_infodb_entry_sqlite($infodb_handle, $infodb_key, $infodb_map);
+  }
+  elsif ($infodb_type eq "gdbm-txtgz")
+  {
+    return &write_infodb_entry_gdbm_txtgz($infodb_handle, $infodb_key, $infodb_map);
+  }
+  elsif ($infodb_type eq "mssql")
+  {
+    return &write_infodb_entry_mssql($infodb_handle, $infodb_key, $infodb_map);
+  }
+
+  # Use GDBM if the infodb type is empty or not one of the values above
+  return &write_infodb_entry_gdbm($infodb_handle, $infodb_key, $infodb_map);
+}
+
+
+sub delete_infodb_entry
+{
+  my $infodb_type = shift(@_);
+  my $infodb_handle = shift(@_);
+  my $infodb_key = shift(@_);
+
+  if ($infodb_type eq "sqlite")
+  {
+    return &delete_infodb_entry_sqlite($infodb_handle, $infodb_key);
+  }
+  elsif ($infodb_type eq "gdbm-txtgz")
+  {
+    return &delete_infodb_entry_gdbm_txtgz($infodb_handle, $infodb_key);
+  }
+  elsif ($infodb_type eq "mssql")
+  {
+    return &delete_infodb_entry_mssql($infodb_handle, $infodb_key);
+  }
+
+  # Use GDBM if the infodb type is empty or not one of the values above
+  return &delete_infodb_entry_gdbm($infodb_handle, $infodb_key);
+}
+
+
+
+# -----------------------------------------------------------------------------
+#   GDBM TXT-GZ IMPLEMENTATION
+# -----------------------------------------------------------------------------
+
+sub open_infodb_write_handle_gdbm_txtgz
+{
+  # Keep infodb in GDBM neutral form => save data as compressed text file, 
+  # read for txt2db to be run on it later (i.e. by the runtime system,
+  # first time the collection is ever accessed).  This makes it easier
+  # distribute pre-built collections to various architectures.
+  #
+  # NB: even if two architectures are little endian (e.g. Intel and 
+  # ARM procesors) GDBM does *not* guarantee that the database generated on 
+  # one will work on the other
+
+  my $infodb_file_path = shift(@_);
+
+  # Greenstone ships with gzip for windows, on $PATH
+
+  my $infodb_file_handle = undef;
+  if (!open($infodb_file_handle, "| gzip - > \"$infodb_file_path\""))
+  {
+    return undef;
+  }
+
+  return $infodb_file_handle;
+}
+
+
+sub close_infodb_write_handle_gdbm_txtgz
+{
+  my $infodb_handle = shift(@_);
+
+  close($infodb_handle);
+}
+
+
+sub get_infodb_file_path_gdbm_txtgz
+{
+  my $collection_name = shift(@_);
+  my $infodb_directory_path = shift(@_);
+
+  my $infodb_file_name = &util::get_dirsep_tail($collection_name).".txt.gz";
+  return &util::filename_cat($infodb_directory_path, $infodb_file_name);
+}
+
+
+sub read_infodb_file_gdbm_txtgz
+{
+  my $infodb_file_path = shift(@_);
+  my $infodb_map = shift(@_);
+
+  my $cmd = "gzip --decompress \"$infodb_file_path\"";
+
+  open (PIPEIN, "$cmd |") 
+  || die "Error: Couldn't open pipe from gzip: $!\n  $cmd\n";
+
+  my $infodb_line = "";
+  my $infodb_key = "";
+  my $infodb_value = "";
+  while (defined ($infodb_line = <PIPEIN>))
+  {
+    if ($infodb_line =~ /^\[([^\]]+)\]$/)
+    {
+      $infodb_key = $1;
+    }
+    elsif ($infodb_line =~ /^-{70}$/)
+    {
+      $infodb_map->{$infodb_key} = $infodb_value;
+      $infodb_key = "";
+      $infodb_value = "";
+    }
+    else
+    {
+      $infodb_value .= $infodb_line;
+    }
+  }
+
+  close (PIPEIN);
+}
+
+    
+sub write_infodb_entry_gdbm_txtgz
+{
+
+  my $infodb_handle = shift(@_);
+  my $infodb_key = shift(@_);
+  my $infodb_map = shift(@_);
+  
+  print $infodb_handle "[$infodb_key]\n";
+  foreach my $infodb_value_key (keys(%$infodb_map))
+  {
+    foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}})
+    {
+      if ($infodb_value =~ /-{70,}/)
+      {
+        # if value contains 70 or more hyphens in a row we need to escape them
+        # to prevent txt2db from treating them as a separator
+        $infodb_value =~ s/-/&\#045;/gi;
+      }
+      print $infodb_handle "<$infodb_value_key>" . $infodb_value . "\n";
+    }
+  }
+  print $infodb_handle '-' x 70, "\n";
+}
+
+
+sub delete_infodb_entry_gdbm_txtgz
+{
+
+  my $infodb_handle = shift(@_);
+  my $infodb_key = shift(@_);
+  
+
+  # A minus at the end of a key (after the ]) signifies 'delete'
+  print $infodb_handle "[$infodb_key]-\n"; 
+
+  # The 70 minus signs are also needed, to help make the parsing by db2txt simple
+  print $infodb_handle '-' x 70, "\n";
+}
+
+
+
+# -----------------------------------------------------------------------------
+#   GDBM IMPLEMENTATION
+# -----------------------------------------------------------------------------
+
+sub open_infodb_write_handle_gdbm
+{
+  my $infodb_file_path = shift(@_);
+  my $opt_append = shift(@_);
+
+  my $txt2db_exe = &util::filename_cat($ENV{'GSDLHOME'},"bin",$ENV{'GSDLOS'}, "txt2db" . &util::get_os_exe());
+  my $infodb_file_handle = undef;
+  my $cmd = "\"$txt2db_exe\"";
+  if ((defined $opt_append) && ($opt_append eq "append")) {
+      $cmd .= " -append";
+  }
+  $cmd .= " \"$infodb_file_path\"";
+
+  if (!-e "$txt2db_exe" || !open($infodb_file_handle, "| $cmd"))
+  {
+    return undef;
+  }
+
+  return $infodb_file_handle;
+}
+
+
+
+sub close_infodb_write_handle_gdbm
+{
+  my $infodb_handle = shift(@_);
+
+  close($infodb_handle);
+}
+
+
+sub get_infodb_file_path_gdbm
+{
+  my $collection_name = shift(@_);
+  my $infodb_directory_path = shift(@_);
+
+  my $infodb_file_extension = ".gdb";
+  my $infodb_file_name = &util::get_dirsep_tail($collection_name) . $infodb_file_extension;
+  return &util::filename_cat($infodb_directory_path, $infodb_file_name);
+}
+
+
+sub read_infodb_file_gdbm
+{
+  my $infodb_file_path = shift(@_);
+  my $infodb_map = shift(@_);
+
+  open (PIPEIN, "db2txt \"$infodb_file_path\" |") || die "couldn't open pipe from db2txt \$infodb_file_path\"\n";
+  my $infodb_line = "";
+  my $infodb_key = "";
+  my $infodb_value = "";
+  while (defined ($infodb_line = <PIPEIN>))
+  {
+    if ($infodb_line =~ /^\[([^\]]+)\]$/)
+    {
+      $infodb_key = $1;
+    }
+    elsif ($infodb_line =~ /^-{70}$/)
+    {
+      $infodb_map->{$infodb_key} = $infodb_value;
+      $infodb_key = "";
+      $infodb_value = "";
+    }
+    else
+    {
+      $infodb_value .= $infodb_line;
+    }
+  }
+
+  close (PIPEIN);
+}
+
+sub read_infodb_keys_gdbm
+{
+  my $infodb_file_path = shift(@_);
+  my $infodb_map = shift(@_);
+
+  open (PIPEIN, "gdbmkeys \"$infodb_file_path\" |") || die "couldn't open pipe from gdbmkeys \$infodb_file_path\"\n";
+  my $infodb_line = "";
+  my $infodb_key = "";
+  my $infodb_value = "";
+  while (defined ($infodb_line = <PIPEIN>))
+  {
+      chomp $infodb_line; # remove end of line 
+
+      $infodb_map->{$infodb_line} = 1;
+  }
+
+  close (PIPEIN);
+}
+
+    
+sub write_infodb_entry_gdbm
+{
+  # With infodb_handle already set up, works the same as _gdbm_txtgz version
+  write_infodb_entry_gdbm_txtgz(@_);
+}
+
+sub delete_infodb_entry_gdbm
+{
+  # With infodb_handle already set up, works the same as _gdbm_txtgz version
+  delete_infodb_entry_gdbm_txtgz(@_);
+}
+
+
+
+# -----------------------------------------------------------------------------
+#   SQLITE IMPLEMENTATION
+# -----------------------------------------------------------------------------
+
+sub open_infodb_write_handle_sqlite
+{
+  my $infodb_file_path = shift(@_);
+
+  my $sqlite3_exe = &util::filename_cat($ENV{'GSDLHOME'},"bin",$ENV{'GSDLOS'}, "sqlite3" . &util::get_os_exe());
+  my $infodb_handle = undef;
+  if (!-e "$sqlite3_exe" || !open($infodb_handle, "| \"$sqlite3_exe\" \"$infodb_file_path\""))
+  {
+    return undef;
+  }
+
+  print $infodb_handle "CREATE TABLE IF NOT EXISTS data (key TEXT PRIMARY KEY, value TEXT);\n";
+  print $infodb_handle "CREATE TABLE IF NOT EXISTS document_metadata (id INTEGER PRIMARY KEY, docOID TEXT, element TEXT, value TEXT);\n";
+
+  # This is crucial for efficiency when importing large amounts of data
+  print $infodb_handle "CREATE INDEX IF NOT EXISTS dmd ON document_metadata(docOID);\n";
+
+  # This is very important for efficiency, otherwise each command will be actioned one at a time
+  print $infodb_handle "BEGIN TRANSACTION;\n";
+
+  return $infodb_handle;
+}
+
+
+sub close_infodb_write_handle_sqlite
+{
+  my $infodb_handle = shift(@_);
+
+  # Close the transaction we began after opening the file
+  print $infodb_handle "END TRANSACTION;\n";
+
+  # This is crucial for efficient queries on the database!
+  print $infodb_handle "CREATE INDEX IF NOT EXISTS dme ON document_metadata(element);\n";
+
+  close($infodb_handle);
+}
+
+
+sub get_infodb_file_path_sqlite
+{
+  my $collection_name = shift(@_);
+  my $infodb_directory_path = shift(@_);
+
+  my $infodb_file_extension = ".db";
+  my $infodb_file_name = &util::get_dirsep_tail($collection_name) . $infodb_file_extension;
+  return &util::filename_cat($infodb_directory_path, $infodb_file_name);
+}
+
+
+sub read_infodb_file_sqlite
+{
+  my $infodb_file_path = shift(@_);
+  my $infodb_map = shift(@_);
+
+  # !! TO IMPLEMENT
+}
+
+
+sub write_infodb_entry_sqlite
+{
+  my $infodb_handle = shift(@_);
+  my $infodb_key = shift(@_);
+  my $infodb_map = shift(@_);
+
+  # Add the key -> value mapping into the "data" table
+  my $infodb_entry_value = "";
+  foreach my $infodb_value_key (keys(%$infodb_map))
+  {
+    foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}})
+    {
+      $infodb_entry_value .= "<$infodb_value_key>" . $infodb_value . "\n";
+    }
+  }
+
+  my $safe_infodb_key = &sqlite_safe($infodb_key);
+  print $infodb_handle "INSERT OR REPLACE INTO data (key, value) VALUES ('" . $safe_infodb_key . "', '" . &sqlite_safe($infodb_entry_value) . "');\n";
+
+  # If this infodb entry is for a document, add all the interesting document metadata to the
+  #   "document_metadata" table (for use by the dynamic classifiers)
+  if ($infodb_key !~ /\./ && $infodb_entry_value =~ /\<doctype\>doc\n/)
+  {
+    print $infodb_handle "DELETE FROM document_metadata WHERE docOID='" . $safe_infodb_key . "';\n";
+
+    foreach my $infodb_value_key (keys(%$infodb_map))
+    {
+      # We're not interested in most of the automatically added document metadata
+      next if ($infodb_value_key eq "archivedir" ||
+               $infodb_value_key eq "assocfilepath" ||
+               $infodb_value_key eq "childtype" ||
+               $infodb_value_key eq "contains" ||
+               $infodb_value_key eq "docnum" ||
+               $infodb_value_key eq "doctype" ||
+               $infodb_value_key eq "Encoding" ||
+               $infodb_value_key eq "FileSize" ||
+               $infodb_value_key eq "hascover" ||
+               $infodb_value_key eq "hastxt" ||
+               $infodb_value_key eq "lastmodified" ||
+               $infodb_value_key eq "metadataset" ||
+               $infodb_value_key eq "thistype" ||
+               $infodb_value_key =~ /^metadatafreq\-/ ||
+               $infodb_value_key =~ /^metadatalist\-/);
+
+      foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}})
+      {
+        print $infodb_handle "INSERT INTO document_metadata (docOID, element, value) VALUES ('" . $safe_infodb_key . "', '" . &sqlite_safe($infodb_value_key) . "', '" . &sqlite_safe($infodb_value) . "');\n";
+      }
+    }
+  }
+}
+
+
+
+sub delete_infodb_entry_sqlite
+{
+  my $infodb_handle = shift(@_);
+  my $infodb_key = shift(@_);
+
+  # Delete the key from the "data" table
+
+  my $safe_infodb_key = &sqlite_safe($infodb_key);
+
+  print $infodb_handle "DELETE FROM data WHERE key='" . $safe_infodb_key . "';\n";
+
+  # If this infodb entry is for a document, delete the
+  #   "document_metadata" table entry also (for use by the dynamic classifiers)
+  if ($infodb_key !~ /\./)
+  {
+      # Possible for there not to be a docOID matching this infodb_key
+      # (entries are only made when <doctype> == doc
+      # Attempt to delete it, and don't complain if one isn't found
+
+      print $infodb_handle "DELETE FROM document_metadata WHERE docOID='" . $safe_infodb_key . "';\n";
+
+  }
+}
+
+
+
+
+
+
+sub sqlite_safe
+{
+  my $value = shift(@_);
+
+  # Escape any single quotes in the value
+  $value =~ s/\'/\'\'/g;
+
+  return $value;
+}
+
+
+
+# ----------------------------------------------------------------------------------------
+#   MSSQL IMPLEMENTATION
+# ----------------------------------------------------------------------------------------
+
+my $mssql_collection_name = "";
+my $mssql_data_table_name = "";
+my $mssql_document_metadata_table_name = "";
+
+
+sub open_infodb_write_handle_mssql
+{
+  my $infodb_file_path = shift(@_);
+
+  # You might have to install the DBD::ADO module from CPAN
+  #================================================================#
+  # Uncomment this if you want to use MSSQL!!!
+  # By the way, MSSQL only works on a Windows machine...
+  #================================================================#
+  #use DBI;
+  #use DBD::ADO;
+  #Win32::OLE->Option(CP => Win32::OLE::CP_UTF8);
+
+  # The hard coded server connection thingy which should be placed
+  # in some configuration file.
+  # If you have problem connecting to your MS SQL server:
+  # 1. Check if your MSSQL server has been started.
+  # 2. Check if the TCP/IP connection has been enabled.
+  # 3. Use telnet to the server 
+  # (don't forget to specify the port, which can be found in the configuration manager)
+  # If none of the above helped, the you need to start googling then.
+  my $host = "localhost,1660"; # Need to look up your SQL server and see what port is it using.
+  my $user = "sa";
+  my $pwd = "[When installing the MSSQL, you will be asked to input a password for the sa user, use that password]";
+  my $database = "[Create a database in MSSQL and use it here]";
+  
+  # Create the unique name for the table
+  # We do not want to change the database for the current running index
+  # Therefore we use timestamp and collection short name to create an unqiue name
+  my $cur_time = time();
+  my $unique_key = $mssql_collection_name . "_" . $cur_time;
+  $mssql_data_table_name = "data_" . $unique_key;
+  $mssql_document_metadata_table_name = "document_metadata_" . $unique_key;
+  print STDERR "MSSQL: Creating unique table name. Unique ID:[" . $unique_key . "]\n";
+      
+  # Store these information into the infodbfile  
+  open(FH, ">" . $infodb_file_path);
+  print FH "mss-host\t" . $host . "\n";
+  print FH "username\t" . $user . "\n";
+  print FH "password\t" . $pwd . "\n";
+  print FH "database\t" . $database . "\n";
+  print FH "tableid\t" . $unique_key . "\n";
+  close(FH);
+  print STDERR "MSSQL: Saving db info into :[" . $infodb_file_path . "]\n";
+
+  # Make the connection
+  my $dsn = "Provider=SQLNCLI;Server=$host;Database=$database";
+  my $infodb_handle = DBI->connect("dbi:ADO:$dsn", $user, $pwd, { RaiseError => 1, AutoCommit => 1}) || return undef;
+  print STDERR "MSSQL: Connect to MS SQL database. DSN:[" . $dsn . "]\n";
+
+  # Make sure the data table has been created.
+  my $data_table_checker_array = dbgetarray($infodb_handle, "SELECT name FROM sysobjects WHERE name = '" . $mssql_data_table_name . "' AND OBJECTPROPERTY(id,'IsUserTable') = 1");
+  if (scalar(@{$data_table_checker_array}) == 0)
+  {
+    dbquery($infodb_handle, "CREATE TABLE " . $mssql_data_table_name . " (one_key NVARCHAR(50) UNIQUE, one_value NVARCHAR(MAX))");
+  }
+  print STDERR "MSSQL: Making sure the data table(" . $mssql_data_table_name . ") exists\n";
+    
+  # Make sure the document_metadata table has been created.
+  my $document_metadata_table_checker_array = dbgetarray($infodb_handle, "SELECT name FROM sysobjects WHERE name = '" . $mssql_document_metadata_table_name . "' AND OBJECTPROPERTY(id,'IsUserTable') = 1");
+  if (scalar(@{$document_metadata_table_checker_array}) == 0)
+  {
+    dbquery($infodb_handle, "CREATE TABLE " . $mssql_document_metadata_table_name . " (id INTEGER IDENTITY(1,1) PRIMARY KEY, docOID NVARCHAR(50), element NVARCHAR(MAX), value NVARCHAR(MAX))");
+    dbquery($infodb_handle, "CREATE INDEX dmd ON " . $mssql_document_metadata_table_name . "(docOID)");
+  } 
+  print STDERR "MSSQL: Making sure the document_metadata table(" . $mssql_data_table_name . ") exists.\n";
+  
+  return $infodb_handle;
+}
+
+
+sub close_infodb_write_handle_mssql
+{
+  my $infodb_handle = shift(@_);    
+  
+  $infodb_handle->disconnect();
+}
+
+
+sub get_infodb_file_path_mssql
+{
+  my $collection_name = shift(@_);
+  my $infodb_directory_path = shift(@_);
+
+  my $infodb_file_extension = ".mssqldbinfo";
+  my $infodb_file_name = &util::get_dirsep_tail($collection_name) . $infodb_file_extension;
+  
+  # This will be used in the open_infodb_write_handle_mssql function
+  $mssql_collection_name =  $collection_name;
+
+  return &util::filename_cat($infodb_directory_path, $infodb_file_name);
+}
+
+
+sub read_infodb_file_mssql
+{
+  my $infodb_file_path = shift(@_);
+  my $infodb_map = shift(@_);
+
+  # !! TO IMPLEMENT
+}
+
+
+sub write_infodb_entry_mssql
+{
+  my $infodb_handle = shift(@_);
+  my $infodb_key = shift(@_);
+  my $infodb_map = shift(@_);
+  
+  # Add the key -> value mapping into the "data" table
+  my $infodb_entry_value = "";
+  foreach my $infodb_value_key (keys(%$infodb_map))
+  {
+    foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}})
+    {
+      $infodb_entry_value .= "<$infodb_value_key>" . &Encode::decode_utf8($infodb_value) . "\n";
+    }
+  }
+  
+  # Prepare the query
+  my $safe_infodb_key = &mssql_safe($infodb_key);
+  my $query = "INSERT INTO " . $mssql_data_table_name . " (one_key, one_value) VALUES (N'" . $safe_infodb_key . "', N'" . &mssql_safe($infodb_entry_value) . "')";
+  dbquery($infodb_handle, $query);
+  
+  # If this infodb entry is for a document, add all the interesting document metadata to the
+  # "document_metadata" table (for use by the dynamic classifiers)
+  if ($infodb_key !~ /\./ && $infodb_entry_value =~ /\<doctype\>doc\n/)
+  {
+    dbquery($infodb_handle, "DELETE FROM " . $mssql_document_metadata_table_name . " WHERE docOID=N'" . $safe_infodb_key . "'");
+    
+    foreach my $infodb_value_key (keys(%$infodb_map))
+    {            
+      # We're not interested in most of the automatically added document metadata
+      next if ($infodb_value_key eq "archivedir" ||
+               $infodb_value_key eq "assocfilepath" ||
+               $infodb_value_key eq "childtype" ||
+               $infodb_value_key eq "contains" ||
+               $infodb_value_key eq "docnum" ||
+               $infodb_value_key eq "doctype" ||
+               $infodb_value_key eq "Encoding" ||
+               $infodb_value_key eq "FileSize" ||
+               $infodb_value_key eq "hascover" ||
+               $infodb_value_key eq "hastxt" ||
+               $infodb_value_key eq "lastmodified" ||
+               $infodb_value_key eq "metadataset" ||
+               $infodb_value_key eq "thistype" ||
+               $infodb_value_key =~ /^metadatafreq\-/ ||
+               $infodb_value_key =~ /^metadatalist\-/);
+      foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}})
+      {
+        $infodb_handle->{LongReadLen} = 65535; # Added for the encoding issue
+        my $query = "INSERT INTO " . $mssql_document_metadata_table_name . " (docOID, element, value) VALUES (N'" . $safe_infodb_key . "', N'" . &mssql_safe(&Encode::decode_utf8($infodb_value_key)) . "', N'" . &mssql_safe(&Encode::decode_utf8($infodb_value)) . "')";
+        dbquery($infodb_handle, $query);
+      }
+    }
+  }
+}
+
+sub delete_infodb_entry_mssql
+{
+  my $infodb_handle = shift(@_);
+  my $infodb_key = shift(@_);
+  
+  # Delete the key from the "data" table
+
+  
+  # Prepare the query
+  my $safe_infodb_key = &mssql_safe($infodb_key);
+  my $query = "DELETE FROM " . $mssql_data_table_name . " WHERE one_key=N'" . $safe_infodb_key . "'";
+  dbquery($infodb_handle, $query);
+  
+  # If this infodb entry is for a document, add all the interesting document metadata to the
+  # "document_metadata" table (for use by the dynamic classifiers)
+  if ($infodb_key !~ /\./)
+  {
+      # Possible for there not to be a docOID matching this infodb_key
+      # (entries are only made when <doctype> == doc
+      # Attempt to delete it, and don't complain if one isn't found
+
+      dbquery($infodb_handle, "DELETE FROM " . $mssql_document_metadata_table_name . " WHERE docOID=N'" . $safe_infodb_key . "'");
+      
+  }
+}
+
+
+
+sub mssql_safe
+{
+  my $value = shift(@_);
+  
+  # Escape any single quotes in the value
+  $value =~ s/\'/\'\'/g;
+  
+  return $value;
+}
+
+
+sub dbquery
+{
+  my $infodb_handle = shift(@_);
+  my $sql_query = shift(@_);
+
+  # Execute the SQL statement
+  my $statement_handle = $infodb_handle->prepare($sql_query);
+  $statement_handle->execute();
+  if ($statement_handle->err) 
+  {
+    print STDERR "Error:" . $statement_handle->errstr . "\n";
+    return undef;
+  }
+  
+  return $statement_handle;
+}
+
+
+sub dbgetarray
+{
+  my $infodb_handle = shift(@_);
+  my $sql_query = shift(@_);
+  
+  my $statement_handle = dbquery($infodb_handle, $sql_query);
+  my $return_array = [];
+  
+  # Iterate through the results and push them into an array
+  if (!defined($statement_handle)) 
+  {
+    return [];
+  }
+  
+  while ((my $temp_hash = $statement_handle->fetchrow_hashref()))
+  {
+    push(@$return_array, $temp_hash);
+  }
+
+  return $return_array; 
+}
+
+
+1;
Index: /gsdl/stable/perllib/doc.pm
===================================================================
--- /gsdl/stable/perllib/doc.pm	(revision 20131)
+++ /gsdl/stable/perllib/doc.pm	(revision 20131)
@@ -0,0 +1,1055 @@
+###########################################################################
+#
+# doc.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistr   te it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# base class to hold documents
+
+package doc;
+eval {require bytes};
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/dynamic/lib/site_perl/5.005/i686-linux");
+}
+
+use strict;
+use unicode;
+use util;
+use ghtml;
+use File::stat;
+##use hashdoc;
+use docprint;
+
+# the document type may be indexed_doc, nonindexed_doc, or
+# classification
+
+our $OIDcount = 0;
+
+sub new {
+    my $class = shift (@_);
+    my ($source_filename, $doc_type, $rename_method) = @_;
+
+
+    my $self = bless {'associated_files'=>[],
+		      'subsection_order'=>[],
+		      'next_subsection'=>1,
+		      'subsections'=>{},
+		      'metadata'=>[],
+		      'text'=>"",
+		      'OIDtype'=>"hash"}, $class;
+
+    # used to set lastmodified here, but this can screw up the HASH ids, so
+    # the docsave processor now calls set_lastmodified
+
+    $self->{'source_path'} = $source_filename;
+    
+    if (defined $source_filename) {
+	$source_filename = &util::filename_within_collection($source_filename);
+	print STDERR "****** doc.pm::new(): no file rename method provided\n" unless $rename_method;
+	$self->set_source_filename ($source_filename, $rename_method);
+    }
+
+    $self->set_doc_type ($doc_type) if defined $doc_type;
+
+    return $self;
+}
+# set lastmodified for OAI purposes, added by GRB, moved by kjdon
+sub set_lastmodified {
+    my $self = shift (@_);
+
+    my $source_path = $self->{'source_path'};
+   
+    if (defined $source_path && (-e $source_path)) {
+
+      	my $file_stat = stat($source_path);
+	my $mtime = $file_stat->mtime;
+	$self->add_utf8_metadata($self->get_top_section(), "lastmodified", $file_stat->mtime);
+    } 
+}
+
+# clone the $self object
+sub duplicate {
+    my $self = shift (@_);
+
+    my $newobj = {};
+    
+    foreach my $k (keys %$self) {
+	$newobj->{$k} = &clone ($self->{$k});
+    }
+
+    bless $newobj, ref($self);
+    return $newobj;
+}
+
+sub clone {
+    my ($from) = @_;
+    my $type = ref ($from);
+
+    if ($type eq "HASH") {
+	my $to = {};
+	foreach my $key (keys %$from) {
+	    $to->{$key} = &clone ($from->{$key});
+	}
+	return $to;
+    } elsif ($type eq "ARRAY") {
+	my $to = [];
+	foreach my $v (@$from) {
+	    push (@$to, &clone ($v));
+	}
+	return $to;
+    } else {
+	return $from;
+    }
+}
+
+sub set_OIDtype {
+    my $self = shift (@_);
+    my ($type, $metadata) = @_;
+
+    if (defined $type && $type =~ /^(hash|hash_on_file|hash_on_ga_xml|incremental|dirname|assigned)$/) {
+	$self->{'OIDtype'} = $type;
+    } else {
+	$self->{'OIDtype'} = "hash";
+    }
+
+    if ($type =~ /^assigned$/) {
+	if (defined $metadata) {
+	    $self->{'OIDmetadata'} = $metadata;
+	} else {
+	    $self->{'OIDmetadata'} = "dc.Identifier";
+	}
+    }
+}
+
+sub set_source_filename {
+    my $self = shift (@_);
+    my ($source_filename, $rename_method) = @_;
+
+    # Since the gsdlsourcefilename element goes into the doc.xml it has 
+    # to be utf8. However, it should also *represent* the source filename 
+    # (in the import directory) which may not be utf8 at all. 
+    # For instance, if this meta element (gsdlsourcefilename) will be used 
+    # by other applications that parse doc.xml in order to locate 
+    # gsdlsourcefilename. Therefore, the solution is to URLencode or base64 
+    # encode the real filename as this is a binary-to-text encoding meaning
+    # that the resulting string is ASCII (utf8). Decoding will give the original.
+    
+#    print STDERR "******URL/base64 encoding the gsdl_source_filename $source_filename ";
+
+    # URLencode just the gsdl_source_filename, not the directory. Then prepend dir 
+    my ($srcfilename,$dirname,$suffix) 
+	= &File::Basename::fileparse($source_filename, "\\.[^\\.]+\$");
+#    print STDERR "-> $srcfilename -> ";
+    $srcfilename = &util::rename_file($srcfilename.$suffix, $rename_method);
+    $source_filename = &util::filename_cat($dirname, $srcfilename);
+#    print STDERR "$source_filename\n";
+	
+    $self->set_utf8_metadata_element ($self->get_top_section(), 
+				 "gsdlsourcefilename", 
+				 $source_filename);
+}
+
+sub set_converted_filename {
+    my $self = shift (@_);
+    my ($converted_filename) = @_;
+
+    # we know the converted filename is utf8
+    $self->set_utf8_metadata_element ($self->get_top_section(), 
+				 "gsdlconvertedfilename", 
+				 $converted_filename);
+}
+
+# returns the source_filename as it was provided
+sub get_unmodified_source_filename {
+    my $self = shift (@_);
+
+    return $self->{'source_path'};
+}
+
+# returns the source_filename with whatever rename_method was given
+sub get_source_filename {
+    my $self = shift (@_);
+
+    return $self->get_metadata_element ($self->get_top_section(), "gsdlsourcefilename");
+}
+
+
+
+# returns converted filename if available else returns source filename
+sub get_filename_for_hashing {
+    my $self = shift (@_);
+
+    my $filename = $self->get_metadata_element ($self->get_top_section(), "gsdlconvertedfilename");
+
+    if (!defined $filename) {
+	my $plugin_name = $self->get_metadata_element ($self->get_top_section(), "Plugin");
+	# if NULPlug processed file, then don't give a filename
+	if (defined $plugin_name && $plugin_name eq "NULPlug") {
+	    $filename = undef;
+	} else { # returns the URL encoded source filename!
+	    $filename = $self->get_metadata_element ($self->get_top_section(), "gsdlsourcefilename");
+	}
+    }
+    return $filename;
+}
+
+sub set_doc_type {
+    my $self = shift (@_);
+    my ($doc_type) = @_;
+
+    $self->set_metadata_element ($self->get_top_section(), 
+				 "gsdldoctype", 
+				 $doc_type);
+}
+
+# returns the gsdldoctype as it was provided
+# the default of "indexed_doc" is used if no document
+# type was provided
+sub get_doc_type {
+    my $self = shift (@_);
+
+    my $doc_type = $self->get_metadata_element ($self->get_top_section(), "gsdldoctype");
+    return $doc_type if (defined $doc_type);
+    return "indexed_doc";
+}
+
+
+# look up the reference to the a particular section
+sub _lookup_section {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    my ($num);
+    my $sectionref = $self;
+
+    while (defined $section && $section ne "") {
+	
+	($num, $section) = $section =~ /^\.?(\d+)(.*)$/;
+	
+	$num =~ s/^0+(\d)/$1/ if defined $num ; # remove leading 0s
+	
+	$section = "" unless defined $section;
+	
+
+	if (defined $num && defined $sectionref->{'subsections'}->{$num}) {
+	    $sectionref = $sectionref->{'subsections'}->{$num};
+	} else {
+	    return undef;
+	}
+    }
+    
+    return $sectionref;
+}
+
+# calculate OID by hashing the contents of the document
+sub _calc_OID {
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    my $osexe = &util::get_os_exe();
+
+    my $hashfile_exe = &util::filename_cat($ENV{'GSDLHOME'},"bin",
+					   $ENV{'GSDLOS'},"hashfile$osexe");
+
+    my $result = "NULL";
+    
+    if (-e "$hashfile_exe") {
+#	$result = `\"$hashfile_exe\" \"$filename\"`;
+	$result = `hashfile$osexe \"$filename\"`;
+	($result) = $result =~ /:\s*([0-9a-f]+)/i;
+    } else {
+	print STDERR "doc::_calc_OID $hashfile_exe could not be found\n";
+    }
+    return "HASH$result";
+}
+
+# methods dealing with OID, not groups of them.
+
+# if $OID is not provided one is calculated
+sub set_OID {
+    my $self = shift (@_);
+    my ($OID) = @_;
+    
+    my $use_hash_oid = 0;
+    # if an OID wasn't provided calculate one
+    if (!defined $OID) {
+	$OID = "NULL";
+	if ($self->{'OIDtype'} =~ /^hash/) {
+	    $use_hash_oid = 1;
+	} elsif ($self->{'OIDtype'} eq "incremental") {
+	    $OID = "D" . $OIDcount;
+	    $OIDcount ++;
+	  
+	} elsif ($self->{'OIDtype'} eq "dirname") {
+	    $OID = 'J';
+	    my $filename = $self->get_source_filename();
+	    if (defined($filename)) { # && -e $filename) {
+		$OID = &File::Basename::dirname($filename);
+		if (defined $OID) {
+		    $OID = 'J'.&File::Basename::basename($OID);
+		    $OID = &util::tidy_up_oid($OID);
+		} else {
+		    print STDERR "Failed to find base for filename ($filename)...generating hash id\n";
+		    $use_hash_oid = 1;
+		}
+	    } else {
+		print STDERR "Failed to find filename, generating hash id\n";
+		$use_hash_oid = 1;
+	    }    
+	    
+	} elsif ($self->{'OIDtype'} eq "assigned") {
+	    my $identifier = $self->get_metadata_element ($self->get_top_section(), $self->{'OIDmetadata'});
+	    if (defined $identifier && $identifier ne "") {
+		$OID = $identifier;
+		$OID = &util::tidy_up_oid($OID);
+	    } else {
+		# need a hash id
+		print STDERR "no $self->{'OIDmetadata'} metadata found, generating hash id\n";
+		$use_hash_oid = 1;
+	    }
+	    	    
+	} else {
+	    $use_hash_oid = 1;
+	}
+
+	if ($use_hash_oid) {
+	    my $hash_on_file = 1;
+	    if ($self->{'OIDtype'} eq "hash_on_ga_xml") {
+		$hash_on_file = 0;
+	    }
+	    if ($hash_on_file) {
+		# "hash" OID - feed file to hashfile.exe
+		my $filename = $self->get_filename_for_hashing();
+		# -z: don't want to hash on the file if it is zero size
+		if (defined($filename) && -e $filename && !-z $filename) {
+		    $OID = $self->_calc_OID ($filename);
+		} else {
+		    $hash_on_file = 0;
+		}
+	    }
+	    if (!$hash_on_file) {
+		my $filename = &util::get_tmp_filename();
+		if (!open (OUTFILE, ">$filename")) {
+		    print STDERR "doc::set_OID could not write to $filename\n";
+		} else {
+		    my $doc_text = &docprint::get_section_xml($self, $self->get_top_section());
+		    print OUTFILE $doc_text;
+		    close (OUTFILE);
+		}
+		$OID = $self->_calc_OID ($filename);
+		&util::rm ($filename);
+	    }
+	}
+    }
+    $self->set_metadata_element ($self->get_top_section(), "Identifier", $OID);
+}
+
+# this uses hashdoc (embedded c thingy) which is faster but still 
+# needs a little work to be suffiently stable
+sub ___set_OID {
+    my $self = shift (@_);
+    my ($OID) = @_;
+
+    # if an OID wasn't provided then calculate hash value based on document
+    if (!defined $OID) 
+    {
+	my $hash_text = &docprint::get_section_xml($self, $self->get_top_section());
+	my $hash_len = length($hash_text);
+
+        $OID = &hashdoc::buffer($hash_text,$hash_len);
+    }
+
+    $self->set_metadata_element ($self->get_top_section(), "Identifier", $OID);
+}
+
+# returns the OID for this document
+sub get_OID {
+    my $self = shift (@_);
+    my $OID = $self->get_metadata_element ($self->get_top_section(), "Identifier");
+    return $OID if (defined $OID);
+    return "NULL";
+}
+
+sub delete_OID {
+    my $self = shift (@_);
+    
+    $self->set_metadata_element ($self->get_top_section(), "Identifier", "NULL");
+}
+
+
+# methods for manipulating section names
+
+# returns the name of the top-most section (the top
+# level of the document
+sub get_top_section {
+    my $self = shift (@_);
+    
+    return "";
+}
+
+# returns a section
+sub get_parent_section {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    $section =~ s/(^|\.)\d+$//;
+
+    return $section;
+}
+
+# returns the first child section (or the end child 
+# if there isn't any)
+sub get_begin_child {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    my $section_ptr = $self->_lookup_section($section);
+    return "" unless defined $section_ptr;
+
+    if (defined $section_ptr->{'subsection_order'}->[0]) {
+	return "$section.$section_ptr->{'subsection_order'}->[0]";
+    }
+
+    return $self->get_end_child ($section);
+}
+
+# returns the next child of a parent section
+sub get_next_child {
+    my $self = shift (@_);
+    my ($section) = @_;
+    
+    my $parent_section = $self->get_parent_section($section);
+    my $parent_section_ptr = $self->_lookup_section($parent_section);
+    return undef unless defined $parent_section_ptr;
+
+    my ($section_num) = $section =~ /(\d+)$/;
+    return undef unless defined $section_num;
+
+    my $i = 0;
+    my $section_order = $parent_section_ptr->{'subsection_order'};
+    while ($i < scalar(@$section_order)) {
+	last if $section_order->[$i] eq $section_num;
+	$i++;
+    }
+
+    $i++; # the next child
+    if ($i < scalar(@$section_order)) {
+	return $section_order->[$i] if $parent_section eq "";
+	return "$parent_section.$section_order->[$i]";
+    }
+
+    # no more sections in this level
+    return undef;
+}
+
+# returns a reference to a list of children
+sub get_children {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    my $section_ptr = $self->_lookup_section($section);
+    return [] unless defined $section_ptr;
+
+    my @children = @{$section_ptr->{'subsection_order'}};
+
+    map {$_ = "$section.$_"; $_ =~ s/^\.+//;} @children;
+    return \@children;
+}
+
+# returns the child section one past the last one (which
+# is coded as "0")
+sub get_end_child {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    return $section . ".0" unless $section eq "";
+    return "0";
+}
+
+# returns the next section in book order
+sub get_next_section {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    return undef unless defined $section;
+
+    my $section_ptr = $self->_lookup_section($section);
+    return undef unless defined $section_ptr;
+
+    # first try to find first child
+    if (defined $section_ptr->{'subsection_order'}->[0]) {
+	return $section_ptr->{'subsection_order'}->[0] if ($section eq "");
+	return "$section.$section_ptr->{'subsection_order'}->[0]";
+    }
+
+    do {
+	# try to find sibling
+	my $next_child = $self->get_next_child ($section);
+	return $next_child if (defined $next_child);
+
+	# move up one level
+	$section = $self->get_parent_section ($section);
+    } while $section =~ /\d/;
+
+    return undef;
+}
+
+sub is_leaf_section {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    my $section_ptr = $self->_lookup_section($section);
+    return 1 unless defined $section_ptr;
+
+    return (scalar (@{$section_ptr->{'subsection_order'}}) == 0);
+}
+
+# methods for dealing with sections
+
+# returns the name of the inserted section
+sub insert_section {
+    my $self = shift (@_);
+    my ($before_section) = @_;
+
+    # get the child to insert before and its parent section
+    my $parent_section = "";
+    my $before_child = "0";
+    my @before_section = split (/\./, $before_section);
+    if (scalar(@before_section) > 0) {
+	$before_child = pop (@before_section);
+	$parent_section = join (".", @before_section);
+    }
+
+    my $parent_section_ptr = $self->_lookup_section($parent_section);
+    if (!defined $parent_section_ptr) {
+	print STDERR "doc::insert_section couldn't find parent section " .
+	    "$parent_section\n";
+	return;
+    }
+
+    # get the next section number
+    my $section_num = $parent_section_ptr->{'next_subsection'}++;
+
+    my $i = 0;
+    while ($i < scalar(@{$parent_section_ptr->{'subsection_order'}}) &&
+	   $parent_section_ptr->{'subsection_order'}->[$i] ne $before_child) {
+	$i++;
+    }
+    
+    # insert the section number into the order list
+    splice (@{$parent_section_ptr->{'subsection_order'}}, $i, 0, $section_num);
+
+    # add this section to the parent section
+    my $section_ptr = {'subsection_order'=>[],
+		       'next_subsection'=>1,
+		       'subsections'=>{},
+		       'metadata'=>[],
+		       'text'=>""};
+    $parent_section_ptr->{'subsections'}->{$section_num} = $section_ptr;
+
+    # work out the full section number
+    my $section = $parent_section;
+    $section .= "." unless $section eq "";
+    $section .= $section_num;
+    
+    return $section;
+}
+
+# creates a pre-named section
+sub create_named_section {
+    my $self = shift (@_);
+    my ($mastersection) = @_;
+
+    my ($num);
+    my $section = $mastersection;
+    my $sectionref = $self;
+
+    while ($section ne "") {
+	($num, $section) = $section =~ /^\.?(\d+)(.*)$/;
+	$num =~ s/^0+(\d)/$1/; # remove leading 0s
+	$section = "" unless defined $section;
+	
+	if (defined $num) {
+	    if (!defined $sectionref->{'subsections'}->{$num}) {
+		push (@{$sectionref->{'subsection_order'}}, $num);
+		$sectionref->{'subsections'}->{$num} = {'subsection_order'=>[],
+							'next_subsection'=>1,
+							'subsections'=>{},
+							'metadata'=>[],
+							'text'=>""};
+		if ($num >= $sectionref->{'next_subsection'}) {
+		    $sectionref->{'next_subsection'} = $num + 1;
+		}
+	    }
+	    $sectionref = $sectionref->{'subsections'}->{$num};
+
+	} else {
+	    print STDERR "doc::create_named_section couldn't create section ";
+	    print STDERR "$mastersection\n";
+	    last;
+	}
+    }
+}
+
+# returns a reference to a list of subsections
+sub list_subsections {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    my $section_ptr = $self->_lookup_section ($section);
+    if (!defined $section_ptr) {
+	print STDERR "doc::list_subsections couldn't find section $section\n";
+	return [];
+    }
+
+    return [@{$section_ptr->{'subsection_order'}}];
+}
+
+sub delete_section {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+#    my $section_ptr = {'subsection_order'=>[],
+#		       'next_subsection'=>1,
+#		       'subsections'=>{},
+#		       'metadata'=>[],
+#		       'text'=>""};
+
+    # if this is the top section reset everything
+    if ($section eq "") {
+	$self->{'subsection_order'} = [];
+	$self->{'subsections'} = {};
+	$self->{'metadata'} = [];
+	$self->{'text'} = "";
+	return;
+    }
+
+    # find the parent of the section to delete
+    my $parent_section = "";
+    my $child = "0";
+    my @section = split (/\./, $section);
+    if (scalar(@section) > 0) {
+	$child = pop (@section);
+	$parent_section = join (".", @section);
+    }
+
+    my $parent_section_ptr = $self->_lookup_section($parent_section);
+    if (!defined $parent_section_ptr) {
+	print STDERR "doc::delete_section couldn't find parent section " .
+	    "$parent_section\n";
+	return;
+    }
+
+    # remove this section from the subsection_order list
+    my $i = 0;
+    while ($i < scalar (@{$parent_section_ptr->{'subsection_order'}})) {
+	if ($parent_section_ptr->{'subsection_order'}->[$i] eq $child) {
+	    splice (@{$parent_section_ptr->{'subsection_order'}}, $i, 1);
+	    last;
+	}
+	$i++;
+    }
+
+    # remove this section from the subsection hash
+    if (defined ($parent_section_ptr->{'subsections'}->{$child})) {
+	undef $parent_section_ptr->{'subsections'}->{$child};
+    }
+}
+
+#--
+# methods for dealing with metadata
+
+# set_metadata_element and get_metadata_element are for metadata
+# which should only have one value. add_meta_data and get_metadata
+# are for metadata which can have more than one value.
+
+# returns the first metadata value which matches field
+
+# This version of get metadata element works much like the one above,
+# except it allows for the namespace portion of a metadata element to
+# be ignored, thus if you are searching for dc.Title, the first piece
+# of matching metadata ending with the name Title (once any namespace
+# is removed) would be returned.
+# 28-11-2003 John Thompson
+sub get_metadata_element {
+    my $self = shift (@_);
+    my ($section, $field, $ignore_namespace) = @_;
+    my ($data);
+
+    $ignore_namespace = 0 unless defined $ignore_namespace;
+
+    my $section_ptr = $self->_lookup_section($section);
+    if (!defined $section_ptr) {
+	print STDERR "doc::get_metadata_element couldn't find section ", $section, "\n";
+	return;
+    }
+
+    # Remove the any namespace if we are being told to ignore them
+    if($ignore_namespace) {
+	$field =~ s/^\w*\.//;
+    }
+
+    foreach $data (@{$section_ptr->{'metadata'}}) {
+
+	my $data_name = $data->[0];
+
+	# Remove the any namespace if we are being told to ignore them
+	if($ignore_namespace) {
+	    $data_name =~ s/^\w*\.//;
+	}
+	
+	return $data->[1] if (scalar(@$data) >= 2 && $data_name eq $field);
+    }
+	
+    return undef; # was not found
+}
+
+# returns a list of the form [value1, value2, ...]
+sub get_metadata {
+    my $self = shift (@_);
+    my ($section, $field, $ignore_namespace) = @_;
+    my ($data);
+
+    $ignore_namespace = 0 unless defined $ignore_namespace;
+
+    my $section_ptr = $self->_lookup_section($section);
+    if (!defined $section_ptr) {
+        print STDERR "doc::get_metadata couldn't find section ",
+	    $section, "\n";
+        return;
+    }
+
+    # Remove the any namespace if we are being told to ignore them
+    if($ignore_namespace) {
+	$field =~ s/^\w*\.//;
+    }
+
+    my @metadata = ();
+    foreach $data (@{$section_ptr->{'metadata'}}) {
+
+	my $data_name = $data->[0];
+	# Remove the any namespace if we are being told to ignore them
+	if($ignore_namespace) {
+	    $data_name =~ s/^\w*\.//;
+	}
+
+        push (@metadata, $data->[1]) if ($data_name eq $field);
+    }
+
+    return \@metadata;
+}
+
+# returns a list of the form [[field,value],[field,value],...]
+sub get_all_metadata {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    my $section_ptr = $self->_lookup_section($section);
+    if (!defined $section_ptr) {
+	print STDERR "doc::get_all_metadata couldn't find section ", $section, "\n";
+	return;
+    }
+    
+    return $section_ptr->{'metadata'};
+}
+
+# $value is optional
+sub delete_metadata {
+    my $self = shift (@_);
+    my ($section, $field, $value) = @_;
+
+    my $section_ptr = $self->_lookup_section($section);
+    if (!defined $section_ptr) {
+	print STDERR "doc::delete_metadata couldn't find section ", $section, "\n";
+	return;
+    }
+
+    my $i = 0;
+    while ($i < scalar (@{$section_ptr->{'metadata'}})) {
+	if (($section_ptr->{'metadata'}->[$i]->[0] eq $field) &&
+	    (!defined $value || $section_ptr->{'metadata'}->[$i]->[1] eq $value)) {
+	    splice (@{$section_ptr->{'metadata'}}, $i, 1);
+	} else {
+	    $i++;
+	}
+    }
+}
+
+sub delete_all_metadata {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    my $section_ptr = $self->_lookup_section($section);
+    if (!defined $section_ptr) {
+	print STDERR "doc::delete_all_metadata couldn't find section ", $section, "\n";
+	return;
+    }
+    
+    $section_ptr->{'metadata'} = [];
+}
+
+sub set_metadata_element {
+    my $self = shift (@_);
+    my ($section, $field, $value) = @_;
+
+    $self->set_utf8_metadata_element ($section, $field, 
+				      &unicode::ascii2utf8(\$value));
+}
+
+# set_utf8_metadata_element assumes the text has already been
+# converted to the UTF-8 encoding.
+sub set_utf8_metadata_element {
+    my $self = shift (@_);
+    my ($section, $field, $value) = @_;
+
+    $self->delete_metadata ($section, $field);
+    $self->add_utf8_metadata ($section, $field, $value);
+}
+
+
+# add_metadata assumes the text is in (extended) ascii form. For
+# text which has already been converted to the UTF-8 format use
+# add_utf8_metadata.
+sub add_metadata {
+    my $self = shift (@_);
+    my ($section, $field, $value) = @_;
+
+    $self->add_utf8_metadata ($section, $field,
+			      &unicode::ascii2utf8(\$value));
+}
+
+sub add_utf8_metadata {
+    my $self = shift (@_);
+    my ($section, $field, $value) = @_;
+
+    my $section_ptr = $self->_lookup_section($section);
+    if (!defined $section_ptr) {
+	print STDERR "doc::add_utf8_metadata couldn't find section ", $section, "\n";
+	return;
+    }
+    if (!defined $value) {
+	print STDERR "doc::add_utf8_metadata undefined value for $field\n";
+	return;
+    }
+    if (!defined $field) {
+	print STDERR "doc::add_utf8_metadata undefined metadata type \n";
+	return;
+    }
+    
+    #print STDERR "###$field=$value\n";
+    # double check that the value is utf-8
+    if (!&unicode::check_is_utf8($value)) {
+	print STDERR "doc::add_utf8_metadata - warning: '$field''s value $value wasn't utf8.";
+	&unicode::ensure_utf8(\$value);
+	print STDERR " Tried converting to utf8: $value\n";
+    }
+
+    push (@{$section_ptr->{'metadata'}}, [$field, $value]);
+}
+
+
+# methods for dealing with text
+
+# returns the text for a section
+sub get_text {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    my $section_ptr = $self->_lookup_section($section);
+    if (!defined $section_ptr) {
+	print STDERR "doc::get_text couldn't find section " .
+	    "$section\n";
+	return "";
+    }
+
+    return $section_ptr->{'text'};
+}
+
+# returns the (utf-8 encoded) length of the text for a section
+sub get_text_length {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    my $section_ptr = $self->_lookup_section($section);
+    if (!defined $section_ptr) {
+	print STDERR "doc::get_text_length couldn't find section " .
+	    "$section\n";
+	return 0;
+    }
+
+    return length ($section_ptr->{'text'});
+}
+
+sub delete_text {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    my $section_ptr = $self->_lookup_section($section);
+    if (!defined $section_ptr) {
+	print STDERR "doc::delete_text couldn't find section " .
+	    "$section\n";
+	return;
+    }
+
+    $section_ptr->{'text'} = "";
+}
+
+# add_text assumes the text is in (extended) ascii form. For
+# text which has been already converted to the UTF-8 format
+# use add_utf8_text.
+sub add_text {
+    my $self = shift (@_);
+    my ($section, $text) = @_;
+
+    # convert the text to UTF-8 encoded unicode characters
+    # and add the text
+    $self->add_utf8_text($section, &unicode::ascii2utf8(\$text));
+}
+
+
+# add_utf8_text assumes the text to be added has already
+# been converted to the UTF-8 encoding. For ascii text use
+# add_text
+sub add_utf8_text {
+    my $self = shift (@_);
+    my ($section, $text) = @_;
+
+    my $section_ptr = $self->_lookup_section($section);
+    if (!defined $section_ptr) {
+	print STDERR "doc::add_utf8_text couldn't find section " .
+	    "$section\n";
+	return;
+    }
+
+    $section_ptr->{'text'} .= $text;
+}
+
+# returns the Source meta, which is the utf8 filename generated.
+# Added a separate method here for convenience
+sub get_source {
+    my $self = shift (@_);
+    return $self->get_metadata_element ($self->get_top_section(), "Source");
+}
+
+# returns the SourceFile meta, which is the url reference to the URL-encoded
+# version of Source (the utf8 filename). Added a separate method here for convenience
+sub get_sourcefile {
+    my $self = shift (@_);
+    return $self->get_metadata_element ($self->get_top_section(), "SourceFile");
+}
+
+# Get the actual name of the assocfile, a url-encoded string derived from SourceFile.
+# The SourceFile meta is the (escaped) url reference to the url-encoded assocfile.
+sub get_assocfile_from_sourcefile {
+    my $self = shift (@_);
+    
+    # get the SourceFile meta, which is a *URL* to a file on the filesystem
+    my $top_section = $self->get_top_section();
+    my $source_file = $self->get_metadata_element($top_section, "SourceFile");
+
+    # get the actual filename as it exists on the filesystem which this url refers to
+    $source_file = &unicode::url_to_filename($source_file); 
+    my ($assocfilename) = $source_file =~ /([^\\\/]+)$/;
+    return $assocfilename;
+}
+
+# methods for dealing with associated files
+
+# a file is associated with a document, NOT a section.
+# if section is defined it is noted in the data structure
+# only so that files associated from a particular section
+# may be removed later (using delete_section_assoc_files)
+sub associate_file {
+    my $self = shift (@_);
+    my ($real_filename, $assoc_filename, $mime_type, $section) = @_;
+    $mime_type = &ghtml::guess_mime_type ($real_filename) unless defined $mime_type;
+
+    # remove all associated files with the same name
+    $self->delete_assoc_file ($assoc_filename);
+    
+    push (@{$self->{'associated_files'}}, 
+	  [$real_filename, $assoc_filename, $mime_type, $section]);
+}
+
+# returns a list of associated files in the form
+#   [[real_filename, assoc_filename, mimetype], ...]
+sub get_assoc_files {
+    my $self = shift (@_);
+
+    return $self->{'associated_files'};
+}
+
+
+sub metadata_file {
+    my $self = shift (@_);
+    my ($real_filename, $filename) = @_;
+    
+    push (@{$self->{'metadata_files'}}, 
+	  [$real_filename, $filename]);
+}
+
+sub get_meta_files {
+    my $self = shift (@_);
+
+    return $self->{'metadata_files'};
+}
+
+sub delete_section_assoc_files {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    my $i=0;
+    while ($i < scalar (@{$self->{'associated_files'}})) {
+	if (defined $self->{'associated_files'}->[$i]->[3] &&
+	    $self->{'associated_files'}->[$i]->[3] eq $section) {
+	    splice (@{$self->{'associated_files'}}, $i, 1);
+	} else {
+	    $i++;
+	}
+    }
+}
+
+sub delete_assoc_file {
+    my $self = shift (@_);
+    my ($assoc_filename) = @_;
+
+    my $i=0;
+    while ($i < scalar (@{$self->{'associated_files'}})) {
+	if ($self->{'associated_files'}->[$i]->[1] eq $assoc_filename) {
+	    splice (@{$self->{'associated_files'}}, $i, 1);
+	} else {
+	    $i++;
+	}
+    }
+}
+
+sub reset_nextsection_ptr {
+    my $self = shift (@_);
+    my ($section) = @_;
+    
+    my $section_ptr = $self->_lookup_section($section);
+    $section_ptr->{'next_subsection'} = 1;
+}
+
+1;
Index: /gsdl/stable/perllib/docprint.pm
===================================================================
--- /gsdl/stable/perllib/docprint.pm	(revision 20131)
+++ /gsdl/stable/perllib/docprint.pm	(revision 20131)
@@ -0,0 +1,84 @@
+###########################################################################
+#
+# docprint.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# This is used to output an XML representation of a doc_obj - this will be 
+# Greenstone XML format.
+# This is used by GreenstoneXMLPlugout and doc.pm
+
+package docprint;
+
+use strict;
+
+sub get_section_xml {
+    
+    my ($doc_obj, $section) = @_;
+
+    my $section_ptr = $doc_obj->_lookup_section ($section);
+    return "" unless defined $section_ptr;
+
+    my $all_text = "<Section>\n";
+    $all_text .= "  <Description>\n";
+    
+    # output metadata
+    foreach my $data (@{$section_ptr->{'metadata'}}) {
+	my $escaped_value = &escape_text($data->[1]);
+	$all_text .= '    <Metadata name="' . $data->[0] . '">' . $escaped_value . "</Metadata>\n";
+    }
+
+    $all_text .= "  </Description>\n";
+
+    # output the text
+    $all_text .= "  <Content>";
+    $all_text .= &escape_text($section_ptr->{'text'});
+    $all_text .= "</Content>\n";
+    
+    # output all the subsections
+    foreach my $subsection (@{$section_ptr->{'subsection_order'}}) {
+	$all_text .= &get_section_xml($doc_obj, "$section.$subsection");
+    }
+    
+    $all_text .=  "</Section>\n";
+
+    # make sure no nasty control characters have snuck through
+    # (XML::Parser will barf on anything it doesn't consider to be
+    # valid UTF-8 text, including things like \c@, \cC etc.)
+    $all_text =~ s/[\x00-\x09\x0B\x0C\x0E-\x1F]//g;
+
+    return $all_text;
+}
+
+sub escape_text {
+    my ($text) = @_;
+    # special characters in the xml encoding
+    $text =~ s/&&/& &/g;
+    $text =~ s/&/&amp;/g; # this has to be first...
+    $text =~ s/</&lt;/g;
+    $text =~ s/>/&gt;/g;
+    $text =~ s/\"/&quot;/g;
+
+    return $text;
+}
+
+1;
Index: /gsdl/stable/perllib/docproc.pm
===================================================================
--- /gsdl/stable/perllib/docproc.pm	(revision 20131)
+++ /gsdl/stable/perllib/docproc.pm	(revision 20131)
@@ -0,0 +1,94 @@
+###########################################################################
+#
+# docproc.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# document processors are used by the document reader plugins
+# to do some processing on some documents
+
+package docproc;
+
+use strict;
+
+
+sub new {
+    my ($class) = @_;
+    my $self = {};
+
+    $self->{'OIDtype'} = "hash";
+    $self->{'saveas'} = "GreenstoneXML";  # default
+
+    return bless $self, $class;
+}
+
+sub process {
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+
+    die "docproc::process function must be implemented in sub classes\n";
+}
+
+# OIDtype may be "hash" or "incremental" or "dirname" or "assigned"
+sub set_OIDtype {
+    my $self = shift (@_);
+    my ($type, $metadata) = @_;
+
+    if ($type =~ /^(hash|incremental|dirname|assigned)$/) {
+	$self->{'OIDtype'} = $type;
+    } else {
+	$self->{'OIDtype'} = "hash";
+    }
+    if ($type =~ /^assigned$/) {
+	if (defined $metadata) {
+	    $self->{'OIDmetadata'} = $metadata;
+	} else {
+	    $self->{'OIDmetadata'} = "dc.Identifier";
+	}
+    }
+}
+
+sub set_saveas {
+    my $self = shift (@_);
+    my ($saveas) = @_;
+
+    $self->{'saveas'} = $saveas;
+
+}
+
+sub set_saveas_version {
+    my $self = shift (@_);
+    my ($saveas_version) = @_;
+
+    $self->{'saveas_version'} = $saveas_version;
+
+}
+
+
+1;
+
+
+
+
+
+
+
Index: /gsdl/stable/perllib/download.pm
===================================================================
--- /gsdl/stable/perllib/download.pm	(revision 20131)
+++ /gsdl/stable/perllib/download.pm	(revision 20131)
@@ -0,0 +1,91 @@
+###########################################################################
+#
+# download.pm -- functions to handle using download modules
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2005 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package download;
+
+use strict; # to pick up typos and undeclared variables...
+no strict 'refs'; # ...but allow filehandles to be variables and vice versa
+no strict 'subs';
+
+##require util;
+use util;
+use gsprintf 'gsprintf';
+
+
+sub load_download {
+    my ($download_name,$download_options) = @_;
+
+    my ($download_obj);
+
+    my $coldownloadname ="";
+
+    if ($ENV{'GSDLCOLLECTDIR'}){
+   
+	$coldownloadname = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, 
+					      "perllib","downloaders", 
+					      "${download_name}.pm");
+
+    }
+   
+    my $maindownloadname = &util::filename_cat($ENV{'GSDLHOME'},
+					       "perllib","downloaders", 
+					       "${download_name}.pm");
+
+    if (-e $coldownloadname) { require $coldownloadname;}
+    elsif (-e $maindownloadname ) { require $maindownloadname; }
+    else {
+	&gsprintf(STDERR, "{download.could_not_find_download}\n",
+		 $download_name);
+	die "\n";
+    }
+
+    eval ("\$download_obj = new \$download_name([],\$download_options)");
+    die "$@" if $@;
+ 
+    return $download_obj;
+}
+
+sub process {
+    my ($download_obj,$options) = @_;
+    # options: This is a hash map which maps to 
+    #                   downloadfrom's arguments
+    #                   $options->{'cache_dir'}
+    #                   $options->{'download_mode'}
+    #                   $options->{'gli_call'}
+    #                   $options->{'info'}
+    $download_obj->setIsGLI($options->{'gli'});
+
+    ($download_obj->download($options) == 1)?
+	return "true":
+	return "false";
+}
+
+sub get_information {
+    my ($download_obj) = @_;
+    
+    $download_obj->url_information();
+}
+
+1;
Index: /gsdl/stable/perllib/downloaders/BaseDownload.pm
===================================================================
--- /gsdl/stable/perllib/downloaders/BaseDownload.pm	(revision 20131)
+++ /gsdl/stable/perllib/downloaders/BaseDownload.pm	(revision 20131)
@@ -0,0 +1,250 @@
+###########################################################################
+#
+# BaseDownload.pm -- base class for all the Download modules
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package BaseDownload;
+
+eval {require bytes};
+
+use strict;
+no strict 'subs';
+
+use gsprintf 'gsprintf';
+use printusage;
+use parse2;
+
+# suppress the annoying "subroutine redefined" warning that various
+# gets cause under perl 5.6
+$SIG{__WARN__} = sub {warn($_[0]) unless ($_[0] =~ /Subroutine\s+\S+\sredefined/)};
+
+my $arguments = [];
+
+my $options = { 'name'     => "BaseDownload",
+		'desc'     => "{BaseDownload.desc}",
+		'abstract' => "yes",
+		'inherits' => "no" };
+
+sub new 
+{
+    my $class = shift (@_);
+    my ($downloadlist,$args,$hashArgOptLists) = @_;
+    push(@$downloadlist, $class);
+    my $strDownloadName = (defined $downloadlist->[0]) ? $downloadlist->[0] : $class;
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = {};
+    $self->{'download_type'} = $strDownloadName;
+    $self->{'option_list'} = $hashArgOptLists->{"OptList"};
+    $self->{"info_only"} = 0;
+
+    # Check if gsdlinfo is in the argument list or not - if it is, don't parse 
+    # the args, just return the object.  
+    foreach my $strArg (@{$args})
+    {
+	if($strArg eq "-gsdlinfo")
+	{
+	    $self->{"info_only"} = 1;
+	    return bless $self, $class;
+	}
+    }
+    
+    delete $self->{"info_only"};
+    
+    if(parse2::parse($args,$hashArgOptLists->{"ArgList"},$self) == -1)
+    {
+	my $classTempClass = bless $self, $class;
+	print STDERR "<BadDownload d=$self->{'download_name'}>\n";
+	&gsprintf(STDERR, "\n{BaseDownload.bad_general_option}\n", $self->{'download_name'});
+	$classTempClass->print_txt_usage("");  # Use default resource bundle
+	die "\n";
+    }
+
+    return bless $self, $class;
+
+}
+
+sub download
+{
+    my ($self) = shift (@_);
+    my ($hashGeneralOptions) = @_;
+    &error("download","No download specified for $hashGeneralOptions->{download_mode}.\n");
+}
+
+
+sub print_xml_usage
+{
+    my $self = shift(@_);
+    my $header = shift(@_);
+    my $high_level_information_only = shift(@_);
+    
+    # XML output is always in UTF-8
+    gsprintf::output_strings_in_UTF8;
+
+    if ($header) {
+	&PrintUsage::print_xml_header("download");
+    }
+    $self->print_xml($high_level_information_only);
+}
+
+
+sub print_xml
+{
+    my $self = shift(@_);
+    my $high_level_information_only = shift(@_);
+
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $downloadoptions = shift(@$optionlistref);
+    return if (!defined($downloadoptions));
+
+    gsprintf(STDERR, "<DownloadInfo>\n");
+    gsprintf(STDERR, "  <Name>$downloadoptions->{'name'}</Name>\n");
+    my $desc = gsprintf::lookup_string($downloadoptions->{'desc'});
+    $desc =~ s/</&amp;lt;/g; # doubly escaped
+    $desc =~ s/>/&amp;gt;/g;
+    gsprintf(STDERR, "  <Desc>$desc</Desc>\n");
+    gsprintf(STDERR, "  <Abstract>$downloadoptions->{'abstract'}</Abstract>\n");
+    gsprintf(STDERR, "  <Inherits>$downloadoptions->{'inherits'}</Inherits>\n");
+    unless (defined($high_level_information_only)) {
+	gsprintf(STDERR, "  <Arguments>\n");
+	if (defined($downloadoptions->{'args'})) {
+	    &PrintUsage::print_options_xml($downloadoptions->{'args'});
+	}
+	gsprintf(STDERR, "  </Arguments>\n");
+
+	# Recurse up the download hierarchy
+	$self->print_xml();
+    }
+    gsprintf(STDERR, "</DownloadInfo>\n");
+}
+
+
+sub print_txt_usage
+{
+    my $self = shift(@_);
+
+    # Print the usage message for a download (recursively)
+    my $descoffset = $self->determine_description_offset(0);
+    $self->print_download_usage($descoffset, 1);
+}
+
+sub determine_description_offset
+{
+    my $self = shift(@_);
+    my $maxoffset = shift(@_);
+
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $downloadoptions = pop(@$optionlistref);
+    return $maxoffset if (!defined($downloadoptions));
+
+    # Find the length of the longest option string of this download
+    my $downloadargs = $downloadoptions->{'args'};
+    if (defined($downloadargs)) {
+	my $longest = &PrintUsage::find_longest_option_string($downloadargs);
+	if ($longest > $maxoffset) {
+	    $maxoffset = $longest;
+	}
+    }
+
+    # Recurse up the download hierarchy
+    $maxoffset = $self->determine_description_offset($maxoffset);
+    $self->{'option_list'} = \@optionlist;
+    return $maxoffset;
+}
+
+
+sub print_download_usage
+{
+    my $self = shift(@_);
+    my $descoffset = shift(@_);
+    my $isleafclass = shift(@_);
+
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $downloadoptions = shift(@$optionlistref);
+    return if (!defined($downloadoptions));
+
+    my $downloadname = $downloadoptions->{'name'};
+    my $downloadargs = $downloadoptions->{'args'};
+    my $downloaddesc = $downloadoptions->{'desc'};
+
+    # Produce the usage information using the data structure above
+    if ($isleafclass) {
+	if (defined($downloaddesc)) {
+	    gsprintf(STDERR, "$downloaddesc\n\n");
+	}
+	gsprintf(STDERR, " {common.usage}: download $downloadname [{common.options}]\n\n");
+    }
+
+    # Display the download options, if there are some
+    if (defined($downloadargs)) {
+	# Calculate the column offset of the option descriptions
+	my $optiondescoffset = $descoffset + 2;  # 2 spaces between options & descriptions
+
+	if ($isleafclass) {
+	    gsprintf(STDERR, " {common.specific_options}:\n");
+	}
+	else {
+	    gsprintf(STDERR, " {common.general_options}:\n", $downloadname);
+	}
+
+	# Display the download options
+	&PrintUsage::print_options_txt($downloadargs, $optiondescoffset);
+    }
+
+    # Recurse up the download hierarchy
+    $self->print_download_usage($descoffset, 0);
+    $self->{'option_list'} = \@optionlist;
+}
+
+sub url_information
+{
+    my ($self) = @_;
+    print STDERR "There is no extra information provided for this Download.\n";
+    return "";
+}
+
+# method to set whether or not we're running the download scripts from GLI
+sub setIsGLI()
+{
+    my ($self, $is_gli) = @_; 
+
+    $self->{'gli'} = $is_gli;
+}
+
+sub error
+{
+      my ($strFunctionName,$strError) = @_;
+    {
+	print "An error occurred in BaseDownload.pm\n".
+	    "In Function: ".$strFunctionName."\n".
+	    "Error Message: ".$strError."\n";
+	exit(-1);
+    }  
+}
+
+1;
Index: /gsdl/stable/perllib/downloaders/MediaWikiDownload.pm
===================================================================
--- /gsdl/stable/perllib/downloaders/MediaWikiDownload.pm	(revision 20131)
+++ /gsdl/stable/perllib/downloaders/MediaWikiDownload.pm	(revision 20131)
@@ -0,0 +1,322 @@
+###########################################################################
+#
+# MediaWikiDownload.pm -- downloader for wiki pages
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package MediaWikiDownload;
+
+eval {require bytes};
+
+# suppress the annoying "subroutine redefined" warning that various
+# plugins cause under perl 5.6
+$SIG{__WARN__} = sub {warn($_[0]) unless ($_[0] =~ /Subroutine\s+\S+\sredefined/)};
+
+use WgetDownload;
+
+sub BEGIN {
+    @MediaWikiDownload::ISA = ('WgetDownload');
+}
+
+use strict; # every perl program should have this!
+no strict 'refs'; # make an exception so we can use variables as filehandles
+
+my $arguments = 
+    [ { 'name' => "url", 
+	'disp' => "{WebDownload.url_disp}",
+	'desc' => "{WebDownload.url}",
+	'type' => "string",
+	'reqd' => "yes"},
+      { 'name' => "depth", 
+	'disp' => "{WebDownload.depth_disp}",
+	'desc' => "{WebDownload.depth}",
+	'type' => "int",
+	'deft' => "0",
+	"range" => "0,",
+	'reqd' => "no"},
+      { 'name' => "below", 
+	'disp' => "{WebDownload.below_disp}",
+	'desc' => "{WebDownload.below}",
+	'type' => "flag",
+	'reqd' => "no"},
+      { 'name' => "within", 
+	'disp' => "{WebDownload.within_disp}",
+	'desc' => "{WebDownload.within}",
+	'type' => "flag",
+	'reqd' => "no"},     
+      { 'name' => "reject_files",
+	'disp' => "{MediaWikiDownload.reject_filetype_disp}",
+	'desc' => "{MediaWikiDownload.reject_filetype}",
+	'type' => "string",
+	'reqd' => "no",
+	'deft' => "*action=*,*diff=*,*oldid=*,*printable*,*Recentchangeslinked*,*Userlogin*,*Whatlinkshere*,*redirect*,*Special:*,Talk:*,Image:*,*.ppt,*.pdf,*.zip,*.doc"},
+      { 'name' => "exclude_directories",
+	'disp' => "{MediaWikiDownload.exclude_directories_disp}",
+	'desc' => "{MediaWikiDownload.exclude_directories}",
+	'type' => "string",
+	'reqd' => "no",
+	'deft' => "/wiki/index.php/Special:Recentchangeslinked,/wiki/index.php/Special:Whatlinkshere,/wiki/index.php/Talk:Creating_CD"},
+      ];
+
+my $options = { 'name'     => "MediaWikiDownload",
+		'desc'     => "{MediaWikiDownload.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+my $wget_options = "";
+
+my $self;
+
+sub new 
+{
+    my ($class) = shift (@_);
+    my ($getlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$getlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+     my $self = new WgetDownload($getlist,$inputargs,$hashArgOptLists);
+    
+    return bless $self, $class;
+}
+
+
+sub download
+{
+    my ($self) = shift (@_);
+    my ($hashGeneralOptions) = @_;
+  
+    # Download options
+    my $strOptions = $self->generateOptionsString();
+    my $strWgetOptions = $self->getWgetOptions();
+      
+    # Setup the command for using wget
+    $wget_options = "-N -k -x -t 2 -P \"". $hashGeneralOptions->{"cache_dir"}."\" $strWgetOptions $strOptions ";
+    my $cmdWget = "-N -k -x -t 2 -P \"". $hashGeneralOptions->{"cache_dir"}."\" $strWgetOptions $strOptions " . $self->{'url'};
+    
+    # Download the web pages
+    # print "Strat download from $self->{'url'}...\n";
+    print STDERR "<<Undefined Maximum>>\n";
+
+    my $strResponse = $self->useWget($cmdWget,1);
+ 
+    # if ($strResponse ne ""){print "$strResponse\n";}
+        
+    print STDERR "Finish download from $self->{'url'}\n";
+    
+    # check css files for HTML pages are downloaded as well
+    $self->{'url'} =~ /http:\/\/([^\/]*)\//;        
+    my $base_url = &util::filename_cat($hashGeneralOptions->{"cache_dir"}, $1);    
+    &check_file($base_url, $self);
+        
+    print STDERR "<<Finished>>\n";
+  
+    return 1;
+}
+
+sub check_file 
+{    
+    my $dir = shift;
+    my ($self) = shift;
+    
+    local *DIR; 
+     
+    opendir DIR, $dir or return;
+    
+    my @contents = grep { $_ ne '.' and $_ ne '..' } readdir DIR;
+    
+    closedir DIR;
+    
+    foreach (@contents) {
+      # broad-first search
+      &check_file("$dir/$_", $self);
+      
+      # read in every HTML page and check the css associated with import statement already exists.
+      &check_imported_css($self, "$dir/$_");
+    }
+} 
+
+sub check_imported_css
+{
+    my ($self) = shift(@_);    
+    my $downloaded_file = shift(@_);
+            
+    $downloaded_file =~ /(.+)(\/|\\)cache(\/|\\)([^\/\\]+)(\/|\\)/;
+    
+    # external website url, to make up the stylesheet urls
+    my $base_website_url = $4;
+    
+    # the cache download file directory
+    my $base_dir = "$1$2cache$3$4" if defined $base_website_url;
+    
+    if($downloaded_file=~/(.+)\.(html|htm)/) {
+      my $content = "";
+      if(open(INPUT, "<$downloaded_file")){
+	while(my $line = <INPUT>){
+          $content .= $line;
+	}
+        close(INPUT);
+      }
+      
+      my @css_files;
+      my @css_files_paths;
+      my $css_file_count = 0;
+      while($content =~ /<style type="text\/css"(.+)?import "(.+)?"/ig){
+	$css_files[$css_file_count] = $base_website_url . $2 if defined $2;
+        $css_files_paths[$css_file_count] = $base_dir . $2 if defined $2;
+        $css_file_count++;
+      }
+      
+      for($css_file_count=0; $css_file_count<scalar(@css_files); $css_file_count++) {        
+        my $css_file = "http://" . $css_files[$css_file_count];
+        my $css_file_path = $css_files_paths[$css_file_count];
+        
+        # trim the ? mark append to the end of a stylesheet
+        $css_file =~ s/\?([^\/\.\s]+)$//isg;         
+        $css_file_path =~ s/\?([^\/\.\s]+)$//isg;         
+        
+        # do nothing if the css file existed
+        next if(-e $css_file_path);
+        
+        # otherwise use Wget to download the css files
+        my $cmdWget = $wget_options . $css_file;        
+        my $strResponse = $self->useWget($cmdWget,1);
+        
+        print STDERR "Downloaded associated StyleSheet : $css_file\n";
+      }
+    }
+}
+
+
+sub generateOptionsString
+{
+    my ($self) = @_;
+    my $strOptions;
+
+    (defined $self) || &error("generateOptionsString","No \$self is defined!!\n");
+    (defined $self->{'depth'})|| &error("generateOptionsString","No depth is defined!!\n");   
+    
+    # -r for recursive downloading
+    # -E to append a 'html' suffix to a file of type 'application/xhtml+xml' or 'text/html'
+    $strOptions .="-r -E ";
+
+    # -X exclude file directories
+    if($self->{'exclude_directories'}==1) {
+	$strOptions .="-X " . $self->{'exclude_directories'};
+    } else {
+	$strOptions .="-X /wiki/index.php/Special:Recentchangeslinked,/wiki/index.php/Special:Whatlinkshere,/wiki/index.php/Talk:Creating_CD ";
+    }	
+
+    # -R reject file list, reject files with these text in their names
+    if($self->{'reject_files'}==1) {
+	$strOptions .="-R " . $self->{'reject_files'};
+    } else {
+	$strOptions .="-R *action=*,*diff=*,*oldid=*,*printable*,*Recentchangeslinked*,*Userlogin*,*Whatlinkshere*,*redirect*,*Special:*,Talk:*,Image:* ";
+    }    
+    
+    if($self->{'depth'} == 0){
+	$strOptions .= " ";
+    } elsif($self->{'depth'} > 0) {
+	$strOptions .= "-l ".$self->{'depth'}." "; # already got -r
+    } else {
+	$self->error("setupOptions","Incorrect Depth is defined!!\n");
+    }
+
+    if($self->{'below'})  {
+	$strOptions .="-np ";
+    }
+
+    # if($self->{'html_only'}) {
+	# $strOptions .="-A .html,.htm,.shm,.shtml,.asp,.php,.cgi,*?*=* ";
+    # } else{
+	# $strOptions .="-p ";
+    #}
+
+    if (!$self->{'within'}){
+	$strOptions .="-H ";
+    }    
+    
+    return $strOptions;  
+}
+
+sub url_information
+{
+    my ($self) = shift (@_);
+
+    my $strOptions = $self->getWgetOptions();
+
+    my $strBaseCMD = $strOptions." -q -O - \"$self->{'url'}\"";
+
+  
+    my $strIdentifyText = $self->useWget($strBaseCMD);
+    
+    if (!defined $strIdentifyText or $strIdentifyText eq ""  ){
+		print STDERR "Server information is unavailable.\n";
+		print STDERR "<<Finished>>\n";
+		return;  
+    }
+
+    while ($strIdentifyText =~ m/^(.*)<title>(.*?)<\/title>(.*)$/s)  {
+		$strIdentifyText = $1.$3;
+		print STDERR "Page Title: $2\n";
+    }
+  
+    while ($strIdentifyText =~ m/^(.*)<meta (.*?)>(.*)$/s)  {
+	$strIdentifyText = $1.$3;
+	my $strTempString = $2;
+	print STDERR "\n";
+
+	while($strTempString =~ m/(.*?)=[\"|\'](.*?)[\"|\'](.*?)$/s){
+	    # Store the infromation in to variable, since next time when we do 
+	    # regular expression, we will lost all the $1, $2, $X....
+	    $strTempString = $3;
+	    my $strMetaName = $1;
+	    my $strMetaContain = $2;
+	    
+	    # Take out the extra space in the beginning of the string.
+	    $strMetaName =~ s/^([" "])+//m;
+	    $strMetaContain =~ s/^([" "])+//m;
+              
+	    print STDERR "$strMetaName: $strMetaContain\n\n";           
+	}
+    }
+
+    print STDERR "<<Finished>>\n";
+
+}
+
+
+sub error
+{
+    my ($strFunctionName,$strError) = @_;
+    {
+	print "Error occoured in MediaWikiDownload.pm\n".
+	    "In Function:".$strFunctionName."\n".
+	    "Error Message:".$strError."\n";
+	exit(-1);
+    }
+}
+
+1;
+
Index: /gsdl/stable/perllib/downloaders/OAIDownload.pm
===================================================================
--- /gsdl/stable/perllib/downloaders/OAIDownload.pm	(revision 20131)
+++ /gsdl/stable/perllib/downloaders/OAIDownload.pm	(revision 20131)
@@ -0,0 +1,639 @@
+###########################################################################
+#
+# WebDownload.pm -- base class for all the import plugins
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package OAIDownload;
+
+eval {require bytes};
+
+# suppress the annoying "subroutine redefined" warning that various
+# plugins cause under perl 5.6
+$SIG{__WARN__} = sub {warn($_[0]) unless ($_[0] =~ /Subroutine\s+\S+\sredefined/)};
+
+use strict;
+
+use WgetDownload;
+use XMLParser;
+
+use POSIX qw(tmpnam);
+use util;
+
+sub BEGIN {
+    @OAIDownload::ISA = ('WgetDownload');
+}
+
+my $arguments = 
+    [ { 'name' => "url", 
+	'disp' => "{OAIDownload.url_disp}",
+	'desc' => "{OAIDownload.url}",
+	'type' => "string",
+	'reqd' => "yes"},
+      { 'name' => "metadata_prefix", 
+	'disp' => "{OAIDownload.metadata_prefix_disp}",
+	'desc' => "{OAIDownload.metadata_prefix}",
+	'type' => "string",
+	'deft' => "oai_dc",
+	'reqd' => "no"},
+      { 'name' => "set", 
+	'disp' => "{OAIDownload.set_disp}",
+	'desc' => "{OAIDownload.set}",
+	'type' => "string",
+	'reqd' => "no"},
+      { 'name' => "get_doc",
+	'disp' => "{OAIDownload.get_doc_disp}",
+	'desc' => "{OAIDownload.get_doc}",
+	'type' => "flag",
+	'reqd' => "no"},
+      { 'name' => "get_doc_exts",
+	'disp' => "{OAIDownload.get_doc_exts_disp}",
+	'desc' => "{OAIDownload.get_doc_exts}",
+	'type' => "string",
+	'deft' => "doc,pdf,ppt",
+	'reqd' => "no"},
+      { 'name' => "max_records", 
+	'disp' => "{OAIDownload.max_records_disp}",
+	'desc' => "{OAIDownload.max_records}",
+	'type' => "int",
+	'deft' => "500",
+	'range' => "1,",
+	'reqd' => "no"} ];
+
+my $options = { 'name'     => "OAIDownload",
+		'desc'     => "{OAIDownload.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+##my $self;
+
+#### my $strWgetOptions="";
+
+sub new 
+{
+    my ($class) = shift (@_);
+    my ($getlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$getlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new WgetDownload($getlist,$inputargs,$hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    my $parser = new XML::Parser('Style' => 'Stream',
+                                 'PluginObj' => $self,
+				 'Handlers' => {'Char' => \&Char,
+						'Start' => \&OAI_StartTag,
+						'End' => \&OAI_EndTag
+						});
+    $self->{'parser'} = $parser;
+    
+    # make sure the tmp directory that we will use later exists
+    my $tmp_dir = "$ENV{GSDLHOME}/tmp";
+    if (! -e $tmp_dir) {
+	&util::mk_dir($tmp_dir);
+    }
+    
+
+    # set up hashmap for individual items in get_doc_exts
+    # to make testing for matches easier
+
+    $self->{'lookup_exts'} = {};
+    my $get_doc_exts = $self->{'get_doc_exts'};
+
+    if ((defined $get_doc_exts) && ($get_doc_exts ne "")) {
+	my @exts = split(/,\s*/,$get_doc_exts);
+	foreach my $e (@exts) {
+	    $self->{'lookup_exts'}->{lc($e)} = 1;
+	}
+    }
+
+
+    return bless $self, $class;
+}
+
+sub download
+{
+    my ($self) = shift (@_);
+    my ($hashGeneralOptions) = @_;
+
+##    my $cmdWget = $strWgetOptions;
+  
+    my $strOutputDir ="";
+    $strOutputDir = $hashGeneralOptions->{"cache_dir"};
+    my $strBasURL = $self->{'url'};
+    my $intMaxRecords = $self->{'max_records'};
+    my $blnDownloadDoc = $self->{'get_doc'};
+
+    print STDERR "<<Defined Maximum>>\n";
+
+    my $strIDs = $self->getOAIIDs($strBasURL);
+ 
+    if($strIDs eq "")
+    {
+	print STDERR "Error: No IDs found\n";
+	return 0;
+    }
+
+    my $aryIDs = $self->parseOAIIDs($strIDs);
+    my $intIDs = 0;
+    if($self->{'max_records'} < scalar(@$aryIDs))
+    {
+	$intIDs = $self->{'max_records'};
+    }
+    else
+    {
+	$intIDs = scalar(@$aryIDs);
+    }
+    print STDERR "<<Total number of record(s):$intIDs>>\n";
+
+    $self->getOAIRecords($aryIDs, $strOutputDir, $strBasURL, $intMaxRecords, $blnDownloadDoc);
+
+#    my $tmp_file = &util::filename_cat($ENV{'GSDLHOME'},"tmp","oai.tmp");
+#    &util::rm($tmp_file); 
+
+    return 1;
+}
+
+sub getOAIIDs
+{
+    my ($self,$strBasURL) = @_;
+##    my ($cmdWget);
+     
+    my $wgetOptions = $self->getWgetOptions();
+
+    my $cmdWget = $wgetOptions;
+  
+    print STDERR  "Gathering OAI identifiers.....\n";
+
+    my $metadata_prefix = $self->{'metadata_prefix'};
+    $cmdWget .= " -q -O - \"$strBasURL?verb=ListIdentifiers&metadataPrefix=$metadata_prefix";
+
+    # if $set specified, add it in to URL
+    my $set = $self->{'set'};
+    $cmdWget .= "&set=$set" if ($set ne "");
+
+    $cmdWget .= "\" ";
+
+    my $accumulated_strIDs = "";
+    my $strIDs =  $self->useWget($cmdWget);
+
+    if (!defined $strIDs or $strIDs eq ""  ){
+	print STDERR "Server information is unavailable.\n";
+	print STDERR "<<Finished>>\n";
+        return;  
+    }
+    if ($self->{'forced_quit'}) {
+	return $strIDs;
+    }
+
+    print STDERR "<<Download Information>>\n";
+    
+    $self->parse_xml($strIDs);
+
+    $accumulated_strIDs = $strIDs;
+
+    while ($strIDs =~ m/<resumptionToken.*?>\s*(.*?)\s*<\/resumptionToken>/) {
+	# top up list with further requests for IDs
+
+	my $resumption_token = $1;
+
+	$cmdWget = $wgetOptions;
+
+	$cmdWget .= " -q -O - \"$strBasURL?verb=ListIdentifiers&resumptionToken=$resumption_token\"";
+
+	$strIDs =  $self->useWget($cmdWget);
+	if ($self->{'forced_quit'}) {
+	    return $accumulated_strIDs;
+	}
+
+	$self->parse_xml($strIDs);
+
+	$accumulated_strIDs .= $strIDs;
+
+	my @accumulated_identifiers 
+	    = ($accumulated_strIDs =~ m/<identifier>(.*?)<\/identifier>/sg);
+
+	my $num_acc_identifiers = scalar(@accumulated_identifiers);
+	if ($num_acc_identifiers > $self->{'max_records'}) {
+	    last;
+	}
+    }
+
+    return $accumulated_strIDs;
+}
+
+sub parseOAIIDs
+{   
+    my ($self,$strIDs) = @_;
+
+    print STDERR "Parsing OAI identifiers.....\n";
+    $strIDs =~ s/^.*?<identifier>/<identifier>/s;
+    $strIDs =~ s/^(.*<\/identifier>).*$/$1/s;
+
+    my @aryIDs = ();
+
+    while ($strIDs =~ m/<identifier>(.*?)<\/identifier>(.*)$/s)
+    {
+	$strIDs = $2;
+	push(@aryIDs,$1);
+    }
+    
+    return \@aryIDs;
+} 
+
+sub dirFileSplit
+{
+    my ($self,$strFile) = @_;
+
+    my @aryDirs = split("[/\]",$strFile);
+   
+    my $strLocalFile = pop(@aryDirs);
+    my $strSubDirs = join("/",@aryDirs);
+
+    return ($strSubDirs,$strLocalFile);
+}
+
+sub getOAIDoc
+{
+    my ($self,$strRecord, $oai_rec_filename) = @_;
+ 
+    print  STDERR "Gathering source documents.....\n";
+    # look out for identifier tag in metadata section
+   
+    if ($strRecord =~ m/<metadata>(.*)<\/metadata>/s)
+    {
+	my $strMetaTag = $1;
+	my $had_valid_url = 0;
+	my $count = 1;
+	while ($strMetaTag =~ s/<(dc:)?identifier>(.*?)<\/(dc:)?identifier>//is)
+	{
+	    my $doc_id_url = $2;
+
+	    next if ($doc_id_url !~ m/^(https?|ftp):\/\//);
+
+	    my $orig_doc_id_url = $doc_id_url;
+	    $had_valid_url = 1;
+
+	    my ($doc_dir_url_prefix,$doc_id_tail) = ($doc_id_url =~ m/^(.*)\/(.*?)$/);
+	    my $faked_ext = 0;
+	    my $primary_doc_match = 0;
+
+	    my ($id_file_ext) = ($doc_id_tail =~ m/\.([^\.]+)$/);
+
+	    if (defined $id_file_ext) {
+		# cross-check this filename extension with get_doc_exts option
+		# if provided
+		my $lookup_exts = $self->{'lookup_exts'};
+
+		if (defined $lookup_exts->{lc($id_file_ext)}) {
+		    # this initial URL matches requirement
+		    $primary_doc_match = 1;
+		}
+	    }
+	    else {
+		$faked_ext = 1;
+		$id_file_ext = "html";
+	    }
+
+		
+	    if ((!$primary_doc_match) && ($id_file_ext =~ m/^html?$/i)) {
+		# Download this doc if HTML, scan through it looking for a link
+		# that does match get_doc_exts
+		
+
+		# 1. Generate a tmp name
+		my $tmp_filename = &util::get_tmp_filename();
+
+		# 2. Download it
+		my $wget_opts2 = $self->getWgetOptions();
+		my $wget_cmd2 = "$wget_opts2 --convert-links -O \"$tmp_filename\" \"$doc_id_url\"";
+
+		my ($stdout_and_err2,$error2,$follow2) =  $self->useWgetMonitored($wget_cmd2);
+		return $strRecord if $self->{'forced_quit'};
+
+		if($error2 ne "")
+		{
+		    print STDERR "Error occured while retrieving OAI source documents: $error2\n";
+		    exit(-1);
+		}
+
+		if (defined $follow2) {
+		    # src url was "redirected" to another place
+		    # => pick up on this and make it the new doc_id_url
+		    $doc_id_url = $follow2;
+		}
+
+		my $primary_doc_html = "";
+		if (open(HIN,"<$tmp_filename")) {
+		    my $line;
+		    while (defined ($line = <HIN>)) {
+			$primary_doc_html .= $line;
+		    }
+		    close(HIN);
+
+		    # 3. Scan through it looking for match
+		    # 
+		    # if got match, change $doc_id_url to this new URL and
+		    # $id_file_ext to 'match' 
+		    
+		    my @href_links = ($primary_doc_html =~ m/href="(.*?)"/gsi);
+
+		    my $lookup_exts = $self->{'lookup_exts'};
+
+		    foreach my $href (@href_links) {
+			my ($ext) = ($href =~ m/\.([^\.]+)$/);
+
+			if ((defined $ext) && (defined $lookup_exts->{$ext})) {
+
+			    if ($href !~ m/^(https?|ftp):\/\//) {
+				# link is within current site
+				my ($site_domain) = ($doc_id_url =~ m/^((?:https?|ftp):\/\/.*?)\//);
+
+				$href = "$site_domain$href";
+			    }
+
+			    $doc_id_url = $href;
+			    $id_file_ext = $ext;
+			    last;
+			}
+		    }
+		}
+		else {
+		    print STDERR "Error occurred while retrieving OAI source documents:\n";
+		    print STDERR "$!\n";
+		}
+
+		if (-e $tmp_filename) {
+		    &util::rm($tmp_filename); 
+		}
+	    }
+
+	    my $download_doc_filename = $oai_rec_filename;
+	    my $new_extension = "\-$count\.$id_file_ext";
+	    $count++;
+	    #$download_doc_filename =~ s/\.oai$/\.$id_file_ext/;
+	    $download_doc_filename =~ s/\.oai$/$new_extension/;
+	    my ($unused,$download_doc_file) = $self->dirFileSplit($download_doc_filename);
+
+	    my $wget_opts = $self->getWgetOptions();
+	    my $wget_cmd = "$wget_opts --convert-links -O \"$download_doc_filename\" \"$doc_id_url\"";
+
+	    my ($stdout_and_err,$errors,$follow) =  $self->useWgetMonitored($wget_cmd);
+	    return $strRecord if $self->{'forced_quit'};
+
+	    if($errors ne "")
+	    {
+		print STDERR "Error occured while retriving OAI souce documents:\n";
+		print STDERR "$errors\n";
+		exit(-1);
+	    }
+
+	    
+	    $strRecord =~ s/<metadata>(.*?)<(dc:)?identifier>$orig_doc_id_url<\/(dc:)?identifier>(.*?)<\/metadata>/<metadata>$1<${2}identifier>$orig_doc_id_url<\/${2}identifier>\n   <gi.Sourcedoc>$download_doc_file<\/gi.Sourcedoc>$4<\/metadata>/s;
+	}
+
+	if (!$had_valid_url)
+	{
+	    print  STDERR "\tNo source document URL is specified in the OAI record (No (dc:)?identifier is provided)\n";
+	}
+    }
+    else
+    {
+	print  STDERR "\tNo source document URL is specified in the OAI record (No metadata field is provided)\n";
+    }
+
+    return $strRecord;
+}
+
+sub getOAIRecords
+{
+    my ($self,$aryIDs, $strOutputDir, $strBasURL, $intMaxRecords, $blnDownloadDoc) = @_;
+
+    my $intDocCounter = 0;
+
+    my $metadata_prefix = $self->{'metadata_prefix'};
+
+    foreach my $strID ( @$aryIDs)
+    {
+	print  STDERR "Gathering OAI record with ID $strID.....\n";
+	   
+	my $wget_opts = $self->getWgetOptions();
+	my $cmdWget= "$wget_opts -q -O - \"$strBasURL?verb=GetRecord&metadataPrefix=$metadata_prefix&identifier=$strID\"";
+
+	my $strRecord =  $self->useWget($cmdWget);
+
+	my @fileDirs = split(":",$strID);  
+	my $local_id = pop @fileDirs;
+
+	# setup directories
+
+        $strOutputDir  =~ s/"//g; #"
+
+        my $host =$self->{'url'}; 
+  
+        $host =~ s/https?:\/\///g;
+
+        $host =~ s/:.*//g; 
+
+	my $strFileURL = "$strOutputDir/$host/$local_id.oai";
+
+
+	# prepare subdirectory for record (if needed)
+	my ($strSubDirPath,$unused) = ("", "");
+
+       	($strSubDirPath,$unused) = $self->dirFileSplit($strFileURL);
+   
+	&util::mk_all_dir($strSubDirPath);
+
+	my $ds = &util::get_dirsep();
+	
+	if($blnDownloadDoc)
+	{
+	    $strRecord = $self->getOAIDoc($strRecord,$strFileURL);
+	}
+
+	# save record 
+	open (OAIOUT,">$strFileURL")
+	    || die "Unable to save oai metadata record: $!\n";
+	print OAIOUT $strRecord;
+	close(OAIOUT);
+
+        print STDERR "Saving records to $strFileURL\n";
+        print STDERR "<<Done>>\n";
+	$intDocCounter ++;	
+	last if ($intDocCounter >= $intMaxRecords);
+    }
+
+    ($intDocCounter >= $intMaxRecords) ? 
+	print  STDERR "Reached maximum download records, use -max_records to set the maximum.\n": 
+	print  STDERR "Complete download meta record from $strBasURL\n";
+
+       print STDERR "<<Finished>>\n";
+}
+
+sub url_information
+{
+    my ($self) = shift (@_);
+    if(!defined $self){ die "System Error: No \$self defined for url_information in OAIDownload\n";}
+    
+    my $wgetOptions = $self->getWgetOptions();
+    my $strBaseCMD = $wgetOptions." -q -O - \"$self->{'url'}?_OPTS_\"";
+ 
+    my $strIdentify = "verb=Identify";
+    my $strListSets = "verb=ListSets";
+    my $strListMdFormats = "verb=ListMetadataFormats";
+
+    my $strIdentifyCMD = $strBaseCMD;
+    $strIdentifyCMD =~ s/_OPTS_/$strIdentify/;	
+
+    my $strIdentifyText = $self->useWget($strIdentifyCMD);
+
+     if (!defined $strIdentifyText or $strIdentifyText eq ""  ){
+	print STDERR "Server information is unavailable.\n";
+	print STDERR "<<Finished>>\n";
+        return;  
+    }
+
+    print STDERR "General information:\n";
+    $self->parse_xml($strIdentifyText);
+    print STDERR "\n";
+
+    print STDERR "=" x 10, "\n";
+    print STDERR "Metadata Format Information (metadataPrefix):\n";
+    print STDERR "=" x 10, "\n";
+
+    my $strListMdFormatsCMD = $strBaseCMD;
+    $strListMdFormatsCMD =~ s/_OPTS_/$strListMdFormats/;	
+    my $strListMdFormatsText = $self->useWget($strListMdFormatsCMD);
+
+    $self->parse_xml($strListMdFormatsText);
+    print STDERR "\n";
+
+    print STDERR "=" x 10, "\n";
+    print STDERR "List Information:\n";
+    print STDERR "=" x 10, "\n";
+
+    my $strListSetCMD = $strBaseCMD;
+    $strListSetCMD =~ s/_OPTS_/$strListSets/;	
+    my $strListSetsText = $self->useWget($strListSetCMD);
+
+    $self->parse_xml($strListSetsText);
+}
+
+sub parse_xml
+{    
+    my ($self) = shift (@_);
+    my ($xml_text) = @_;
+   
+    #### change this to work directly from $xml_text
+
+    #Open a temporary file to store OAI information, and store the information to the temp file
+    my $name = &util::filename_cat($ENV{GSDLHOME},"tmp","oai.tmp"); 
+
+    open(*OAIOUT,"> $name");
+	
+    print OAIOUT $xml_text;
+    close(OAIOUT);
+
+    $self->{'temp_file_name'} = $name;
+
+##    print STDERR "**** xml text = $xml_text\n";
+
+    eval {
+	$self->{'parser'}->parsefile("$name");
+##	$self->{'parser'}->parse($xml_text);
+    };
+    
+    if ($@) {
+	die "OAI: Parsed file $name is not a well formed XML file ($@)\n";
+##	die "OAI: Parsed text is not a well formed XML file ($@)\n";
+    }
+
+    unlink($self->{'temp_file_name'}) or die "Could not unlink $self->{'temp_file_name'}: $!";
+}
+
+####END 
+#{
+#    if($self->{'info'})
+#    {
+#	unlink($self->{'temp_file_name'}) or die "Could not unlink $self->{'temp_file_name'}: $!";
+#    }
+#}
+
+# This Char function overrides the one in XML::Parser::Stream to overcome a
+# problem where $expat->{Text} is treated as the return value, slowing
+# things down significantly in some cases.
+sub Char {   
+    use bytes;  # Necessary to prevent encoding issues with XML::Parser 2.31+
+    $_[0]->{'Text'} .= $_[1];
+
+    my $self = $_[0]->{'PluginObj'};
+    if ((defined $self->{'subfield'} && ($self->{'subfield'} ne ""))) {
+	$self->{'text'} .= $_[1];
+	$self->{'text'} =~ s/[\n]|([ ]{2,})//g;
+	if($self->{'text'} ne "")
+	{	    
+	    print STDERR " $self->{'subfield'}:($self->{'text'})\n";
+	}
+    }
+    return undef;
+}
+
+sub OAI_StartTag
+{
+    my ($expat, $element, %attr) = @_;
+
+    my $self = $expat->{'PluginObj'};
+    $self->{'subfield'} = $element;
+    
+}
+
+sub OAI_EndTag
+{
+    my ($expat, $element) = @_;
+
+    my $self = $expat->{'PluginObj'};
+    $self->{'text'} = "";
+    $self->{'subfield'} = "";
+}
+
+sub error
+{
+    my ($self,$strFunctionName,$strError) = @_;
+    {
+	print "Error occoured in OAIDownload.pm\n".
+	    "In Function:".$strFunctionName."\n".
+	    "Error Message:".$strError."\n";
+	exit(-1);
+    }
+}
+
+
+
+1;
Index: /gsdl/stable/perllib/downloaders/SRWDownload.pm
===================================================================
--- /gsdl/stable/perllib/downloaders/SRWDownload.pm	(revision 20131)
+++ /gsdl/stable/perllib/downloaders/SRWDownload.pm	(revision 20131)
@@ -0,0 +1,205 @@
+###########################################################################
+#
+# SRWDownload.pm -- base class for all the import plugins
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package SRWDownload;
+
+eval {require bytes};
+
+# suppress the annoying "subroutine redefined" warning that various
+# plugins cause under perl 5.6
+$SIG{__WARN__} = sub {warn($_[0]) unless ($_[0] =~ /Subroutine\s+\S+\sredefined/)};
+
+use strict;
+
+use Z3950Download;
+use IPC::Open2;
+
+sub BEGIN {
+    @SRWDownload::ISA = ('Z3950Download');
+}
+
+my $arguments = [
+		 ];
+
+my $options = { 'name'     => "SRWDownload",
+		'desc'     => "{SRWDownload.desc}",
+		'abstract' => "no",
+		'inherits' => "yes"
+		};
+
+
+sub new 
+{
+    my ($class) = shift (@_);
+    my ($getlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$getlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new Z3950Download($getlist,$inputargs,$hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    # Must set $self->{'url'}, since GLI use $self->{'url'} to calculate the log file name!
+    $self->{'url'} = $self->{'host'}.":".$self->{'port'};
+    return bless $self, $class;
+}
+
+sub download
+{
+    my ($self) = shift (@_);
+    my ($hashGeneralOptions) = @_;
+    my ($strOpen,$strBase,$strFind,$strResponse,$intAmount,$intMaxRecords,$strRecords);
+
+    # If the url contains just the host and port (as it would for Z39.50), then prepend
+    # the http protocol. Otherwise the download is stuck in an infinite loop for SRW/SRU
+    $self->{'url'} = "http://$self->{'url'}"  if $self->{'url'} !~ m/^http/;
+    my $url = $self->{'url'};
+
+    print STDERR "<<Defined Maximum>>\n";
+
+    $strOpen = $self->start_yaz($url);
+    
+    print STDERR "Opening connection to \"$self->{'url'}\"\n";
+    print STDERR "Access database: \"$self->{'database'}\"\n";
+    $self->run_command_without_output("base $self->{'database'}");
+    $self->run_command_without_output("querytype prefix");
+    print STDERR "Searching for keyword: \"$self->{'find'}\"\n";
+
+    $intAmount =$self->findAmount($self->{'find'});
+
+    if($intAmount <= 0)
+    {
+	($intAmount == -1)? 
+	    print STDERR "Something wrong with the arguments,downloading can not be performed\n" : 
+		print STDERR "No Record is found\n";
+	print STDERR "<<Finished>>\n";
+	return 0;
+    }
+    $intMaxRecords = ($self->{'max_records'} > $intAmount)? $intAmount : $self->{'max_records'};
+    print STDERR "<<Total number of record(s):$intMaxRecords>>\n";
+   
+    $strRecords = $self->getRecords($intMaxRecords);
+
+    $self->saveRecords($strRecords,$hashGeneralOptions->{'cache_dir'},$intMaxRecords);
+    print STDERR "Closing connection...\n";
+    
+    $self->quit_yaz();
+    return 1;
+}
+
+
+sub saveRecords
+{
+    my ($self,$strRecords,$strOutputDir,$intMaxRecords) = @_;
+
+    # setup directories
+    # Currently only gather the MARC format
+    $strRecords ="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<collection>$strRecords</collection>";  
+    my $strFileName =  $self->generateFileName($intMaxRecords);
+    my $host = $self->{'host'};
+    $host =~ s/http:\/\///;
+    $strOutputDir  =~ s/"//g; #"
+    my $strOutputFile = &util::filename_cat($strOutputDir,$host,"$strFileName.xml");
+ 
+    # prepare subdirectory for record (if needed)
+
+    my ($strSubDirPath,$unused) = $self->dirFileSplit($strOutputFile);
+    &util::mk_all_dir($strSubDirPath);
+
+    print STDERR "Saving records to \"$strOutputFile\"\n";
+
+    # save record 
+    open (ZOUT,">$strOutputFile")
+	|| die "Unable to save oai metadata record: $!\n";
+    print ZOUT $strRecords;
+    close(ZOUT);
+}
+
+sub get {
+   my ($self,$strShow,$numRecord) = @_;  
+
+   $self->run_command_without_output($strShow); 
+
+   my $strFullOutput="";
+   my $count=0;
+   my $readRecord = 0;
+   my $endRecord = 0;
+
+   my $output = $self->{'YAZOUT'};
+   my $strLine;
+
+   while ($strLine = <$output>)    #while (defined ($strLine = <$output>)) 
+   {
+       last if ($count >= $numRecord && $endRecord); # done, if we've reached the end of the last record
+
+       last if($strLine =~ m/^HTTP ERROR/i);
+
+       if ($strLine =~ m/pos=[\d]*/i ) { 
+           $count++;
+	   $readRecord = 1;
+	   $endRecord = 0;
+	   next;
+       }
+
+       if ($strLine =~ m/<\/record>/i ) { # end tag of record
+	   $endRecord = 1;
+       }
+
+       next if(!$readRecord);
+
+       $strFullOutput .= $strLine;     
+   }
+
+   return $strFullOutput;
+}
+
+sub url_information{
+   my ($self) = @_;
+
+   my $url = $self->{'url'};
+
+   $url =~ s#http://##; 
+
+  return $self->SUPER::url_information($url);  
+
+}
+
+sub error
+{
+    my ($self, $strFunctionName,$strError) = @_;
+    {
+	print STDERR "Error occoured in SRWDownload.pm\n".
+	    "In Function:".$strFunctionName."\n".
+	    "Error Message:".$strError."\n";
+	exit(-1);
+    }
+}
+
+1;
Index: /gsdl/stable/perllib/downloaders/WebDownload.pm
===================================================================
--- /gsdl/stable/perllib/downloaders/WebDownload.pm	(revision 20131)
+++ /gsdl/stable/perllib/downloaders/WebDownload.pm	(revision 20131)
@@ -0,0 +1,246 @@
+###########################################################################
+#
+# WebDownload.pm -- base class for all the import plugins
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package WebDownload;
+
+eval {require bytes};
+
+# suppress the annoying "subroutine redefined" warning that various
+# plugins cause under perl 5.6
+$SIG{__WARN__} = sub {warn($_[0]) unless ($_[0] =~ /Subroutine\s+\S+\sredefined/)};
+
+use WgetDownload;
+
+sub BEGIN {
+    @WebDownload::ISA = ('WgetDownload');
+}
+
+use strict; # every perl program should have this!
+no strict 'refs'; # make an exception so we can use variables as filehandles
+
+my $arguments = 
+    [ { 'name' => "url", 
+	'disp' => "{WebDownload.url_disp}",
+	'desc' => "{WebDownload.url}",
+	'type' => "string",
+	'reqd' => "yes"},
+      { 'name' => "depth", 
+	'disp' => "{WebDownload.depth_disp}",
+	'desc' => "{WebDownload.depth}",
+	'type' => "int",
+	'deft' => "0",
+	"range" => "0,",
+	'reqd' => "no"},
+      { 'name' => "below", 
+	'disp' => "{WebDownload.below_disp}",
+	'desc' => "{WebDownload.below}",
+	'type' => "flag",
+	'reqd' => "no"},
+      { 'name' => "within", 
+	'disp' => "{WebDownload.within_disp}",
+	'desc' => "{WebDownload.within}",
+	'type' => "flag",
+	'reqd' => "no"},
+      { 'name' => "html_only", 
+	'disp' => "{WebDownload.html_only_disp}",
+	'desc' => "{WebDownload.html_only}",
+	'type' => "flag",
+	'reqd' => "no"}
+      ];
+
+my $options = { 'name'     => "WebDownload",
+		'desc'     => "{WebDownload.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+my $self;
+
+sub new 
+{
+    my ($class) = shift (@_);
+    my ($getlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$getlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new WgetDownload($getlist,$inputargs,$hashArgOptLists);
+    
+    return bless $self, $class;
+}
+
+sub download
+{
+    my ($self) = shift (@_);
+    my ($hashGeneralOptions) = @_;
+
+  
+    # Download options
+    my $strOptions = $self->generateOptionsString();
+    my $strWgetOptions = $self->getWgetOptions();
+      
+    # Setup the command for using wget
+    my $cache_dir = "";
+    if($hashGeneralOptions->{'cache_dir'}) { # don't provide the prefix-dir flag to wget unless the cache_dir is specified
+	if ($ENV{'GSDLOS'} eq "windows") {    
+	    $cache_dir = "-P \"".$hashGeneralOptions->{'cache_dir'}."\" ";
+	}
+	else {
+	    $cache_dir = "-P ".$hashGeneralOptions->{'cache_dir'};
+	}
+    }
+    #my $cmdWget = "-N -k -x -t 2 -P \"".$hashGeneralOptions->{"cache_dir"}."\" $strWgetOptions $strOptions ".$self->{'url'};
+    my $cmdWget = "-N -k -x -t 2  $strWgetOptions $strOptions $cache_dir " .$self->{'url'};   
+
+    # Download the web pages
+    # print "Start download from $self->{'url'}...\n";
+    print STDERR "<<Undefined Maximum>>\n";
+    
+    if ($ENV{'GSDLOS'} eq "windows") {
+	my $strResponse = $self->useWget($cmdWget,1);
+    } else {
+	my $strResponse = $self->useWget($cmdWget,1,$hashGeneralOptions->{"cache_dir"} );
+	
+    }
+    
+    # if ($strResponse ne ""){print "$strResponse\n";}
+     print STDERR "Finish download from $self->{'url'}\n";
+
+    print STDERR "<<Finished>>\n";
+  
+    return 1;
+}
+
+sub generateOptionsString
+{
+    my ($self) = @_;
+    my $strOptions;
+
+    (defined $self) || &error("generateOptionsString","No \$self is defined!!\n");
+    (defined $self->{'depth'})|| &error("generateOptionsString","No depth is defined!!\n");
+    
+   
+    if($self->{'depth'} == 0)
+    {
+	$strOptions .= " ";
+    }
+    elsif($self->{'depth'} > 0)
+    {
+	$strOptions .= "-r -l ".$self->{'depth'}." ";
+    }
+    else
+    {
+	$self->error("setupOptions","Incorrect Depth is defined!!\n");
+    }
+
+    if($self->{'below'})
+    {
+	$strOptions .="-np ";
+    }
+
+     if($self->{'html_only'})
+    {
+	$strOptions .="-A .html,.htm,.shm,.shtml,.asp,.php,.cgi,*?*=* ";
+    }
+    else{
+
+	$strOptions .="-p ";
+    }
+
+    if (!$self->{'within'}){
+	$strOptions .="-H ";
+    }
+
+    return $strOptions;
+  
+}
+
+sub url_information
+{
+    my ($self) = shift (@_);
+
+    my $strOptions = $self->getWgetOptions();
+
+    my $strBaseCMD = $strOptions." -q -O - \"$self->{'url'}\"";
+
+  
+    my $strIdentifyText = $self->useWget($strBaseCMD);
+    
+    if (!defined $strIdentifyText or $strIdentifyText eq ""  ){
+	print STDERR "Server information is unavailable.\n";
+	print STDERR "<<Finished>>\n";
+         return;  
+    }
+
+    while ($strIdentifyText =~ m/^(.*)<title>(.*?)<\/title>(.*)$/si)
+    {
+	$strIdentifyText = $1.$3;
+	print STDERR "Page Title: $2\n";
+    }
+  
+    while ($strIdentifyText =~ m/^(.*)<meta (.*?)>(.*)$/si)
+    {
+	$strIdentifyText = $1.$3;
+	my $strTempString = $2;
+	print STDERR "\n";
+
+	while($strTempString =~ m/(.*?)=[\"|\'](.*?)[\"|\'](.*?)$/si)
+	{
+	    # Store the infromation in to variable, since next time when we do 
+	    # regular expression, we will lost all the $1, $2, $X....
+	    $strTempString = $3;
+	    my $strMetaName = $1;
+	    my $strMetaContain = $2;
+	    
+	    # Take out the extra space in the beginning of the string.
+	    $strMetaName =~ s/^([" "])+//m;
+	    $strMetaContain =~ s/^([" "])+//m;
+              
+	    print STDERR "$strMetaName: $strMetaContain\n\n";
+           
+	}
+
+    }
+
+    print STDERR "<<Finished>>\n";
+
+}
+
+
+sub error
+{
+    my ($strFunctionName,$strError) = @_;
+    {
+	print "Error occoured in WebDownload.pm\n".
+	    "In Function:".$strFunctionName."\n".
+	    "Error Message:".$strError."\n";
+	exit(-1);
+    }
+}
+
+1;
+
Index: /gsdl/stable/perllib/downloaders/WgetDownload.pm
===================================================================
--- /gsdl/stable/perllib/downloaders/WgetDownload.pm	(revision 20131)
+++ /gsdl/stable/perllib/downloaders/WgetDownload.pm	(revision 20131)
@@ -0,0 +1,539 @@
+###########################################################################
+#
+# WgetDownload.pm -- Download base module that handles calling Wget
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package WgetDownload;
+
+eval {require bytes};
+
+# suppress the annoying "subroutine redefined" warning that various
+# plugins cause under perl 5.6
+$SIG{__WARN__} = sub {warn($_[0]) unless ($_[0] =~ /Subroutine\s+\S+\sredefined/)};
+
+use BaseDownload;
+use strict;
+use Cwd;
+use IPC::Open3;
+use IO::Select;
+use IO::Socket;
+
+
+sub BEGIN {
+    @WgetDownload::ISA = ('BaseDownload');
+}
+
+my $arguments = 
+     [ { 'name' => "proxy_on", 
+	'desc' => "{WgetDownload.proxy_on}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes"},
+      { 'name' => "proxy_host",  
+	'desc' => "{WgetDownload.proxy_host}",         
+	'type' => "string",
+	'reqd' => "no",
+	'hiddengli' => "yes"},
+      { 'name' => "proxy_port", 
+	'desc' => "{WgetDownload.proxy_port}",         
+	'type' => "string",
+	'reqd' => "no",
+	'hiddengli' => "yes"},
+      { 'name' => "user_name",  
+	'desc' => "{WgetDownload.user_name}",         
+	'type' => "string",
+	'reqd' => "no",
+	'hiddengli' => "yes"},
+      { 'name' => "user_password", 
+	'desc' => "{WgetDownload.user_password}",         
+	'type' => "string",
+	'reqd' => "no",
+	'hiddengli' => "yes"}];
+
+my $options = { 'name'     => "WgetDownload",
+		'desc'     => "{WgetDownload.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+# Declaring file global variables related to the wget child process so that 
+# the termination signal handler for SIGTERM can close the streams and tidy
+# up before ending the child process.
+my $childpid;
+my ($chld_out, $chld_in);
+my ($serverSocket, $read_set);
+
+# The port this script's server socket will be listening on, to handle 
+# incoming signals from GLI to terminate wget. This is also file global, 
+# since OAIDownload.pm will make several calls on wget using the same 
+# instance of this script and we want to reuse whatever port GLI gave us.
+my $port; 
+
+# When this script is called from the command line, this handler will be called
+# if this process is killed or abruptly ends due to receiving one of the
+# terminating signals that this handler is registered to deal with.
+sub abrupt_end_handler {
+    my $termination_signal = shift (@_);
+
+    if(defined $childpid) {
+	close($chld_out);
+	close($chld_in);
+	
+	print STDOUT "Received termination signal: $termination_signal\n";
+
+	# Send TERM signal to child process to terminate it. Sending the INT signal doesn't work
+	# See http://perldoc.perl.org/perlipc.html#Signals 
+	# Warning on using kill at http://perldoc.perl.org/perlfork.html
+	kill("TERM", $childpid); 
+
+	# If the SIGTERM sent on Linux calls this handler, we want to make
+	# sure any socket connection is closed.
+	# Otherwise sockets are only used when this script is run from GLI
+	# in which case the handlers don't really get called.
+	if(defined $serverSocket) {
+	    $read_set->remove($serverSocket) if defined $read_set;
+	    close($serverSocket);
+	}
+    }
+
+    exit(0);
+}
+
+# Registering a handler for when termination signals SIGINT and SIGTERM are received to stop
+# the wget child process. SIGTERM--generated by Java's Process.destroy()--is the default kill
+# signal (kill -15) on Linux, while SIGINT is generated upon Ctrl-C (also on Windows). 
+# Note that SIGKILL can't be handled as the handler won't get called for it. More information: 
+# http://affy.blogspot.com/p5be/ch13.htm
+# http://perldoc.perl.org/perlipc.html#Signals
+$SIG{'INT'} = \&abrupt_end_handler;
+$SIG{'TERM'} = \&abrupt_end_handler;
+
+sub new {
+    my ($class) = shift (@_);
+    my ($getlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$getlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseDownload($getlist,$inputargs,$hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+sub checkWgetSetup
+{
+    my ($self,$blnGliCall) = @_;
+    #TODO: proxy detection??
+    
+    if((!$blnGliCall) && $self->{'proxy_on'})
+    {
+	&checkProxySetup($self);
+    }
+    &checkURL($self); 
+}
+
+sub getWgetOptions
+{
+    my ($self) = @_;
+    my $strOptions = "";
+    
+    if ($self->{'proxy_on'} && $self->{'proxy_host'} && $self->{'proxy_port'})
+    {
+
+	$strOptions .= " -e httpproxy=$self->{'proxy_host'}:$self->{'proxy_port'} ";
+
+	if ($self->{'user_name'} && $self->{'user_password'})
+	{
+	    $strOptions .= "--proxy-user=$self->{'user_name'}"." --proxy-passwd=$self->{'user_password'}";
+	}
+    }
+
+    if ($self->{'proxy_on'}) {
+	$strOptions .= " --proxy ";
+    }
+
+    return $strOptions;
+}
+
+# Checking for proxy setup: proxy server, proxy port, proxy username and password.
+sub checkProxySetup
+{
+    my ($self) = @_;
+    ($self->{'proxy_on'}) || &error("checkProxySetup","The proxy is not on? How could that be happening?");
+    # Setup .wgetrc by using $self->{'proxy_host'} and $self->{'proxy_port'}
+    # Test if the connection is successful. If the connection wasn't successful then ask user to supply username and password.
+
+}
+
+# Returns true if the wget status needs to be monitored through sockets
+# (if a socket is used to communicate with the Java program on when to
+# terminate wget). True if we are running gli, or if the particular type
+# of WgetDownload is *not* OAIDownload (in that case, the original way of 
+# terminating the perl script from Java terminated wget as well).
+sub dealingWithSockets() {
+    my ($self) = @_;
+    return (defined $self->{'gli'} && $self->{'gli'} && !defined $port && ref($self) ne "OAIDownload");
+                       # use ref($self) to find the classname of an object
+}
+
+
+sub useWget
+{
+    #local $| = 1; # autoflush stdout buffer
+    #print STDOUT "*** Start of subroutine useWget in $0\n";
+
+    my ($self, $cmdWget,$blnShow, $working_dir) = @_;
+
+    my ($strReadIn,$strLine,$command);
+    $strReadIn = "" unless defined $strReadIn;
+
+    my $current_dir = cwd();
+    my $changed_dir = 0;
+    if (defined $working_dir && -e $working_dir) {
+	chdir "$working_dir";
+	$changed_dir = 1;
+    }
+
+    # When we are running this script through GLI, the SIGTERM signal handler 
+    # won't get called on Windows when wget is to be prematurely terminated. 
+    # Instead, when wget has to be terminated in the middle of execution, GLI will
+    # connect to a serverSocket here to communicate when it's time to stop wget.
+    if($self->dealingWithSockets()) {
+
+	$port = <STDIN>; # gets a port on localhost that's not yet in use
+	chomp($port);
+	
+	$serverSocket = IO::Socket::INET->new( Proto     => 'tcp',
+					       LocalPort => $port,
+					       Listen    => 1,
+					       Reuse     => 1);
+    
+	die "can't setup server" unless $serverSocket;
+	#print STDOUT "[Serversocket $0 accepting clients at port $port]\n";
+
+	$read_set = new IO::Select();         # create handle set for reading
+	$read_set->add($serverSocket);        # add the main socket to the set
+    }
+
+    my $wget_file_path = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "wget");
+    $command = "\"$wget_file_path\" $cmdWget";
+    #print STDOUT "Command is: $command\n";
+
+    # Wget's output needs to be monitored to find out when it has naturally termianted.
+    # Wget's output is sent to its STDERR so we can't use open2 without doing 2>&1.
+    # On linux, 2>&1 launches a subshell which then launches wget, meaning that killing
+    # the childpid does not kill wget on Linux but the subshell that launched it instead. 
+    # Therefore, we use open3. Though the child process wget sends output only to its stdout, 
+    # using open3 says chld_err is undefined and the output of wget only comes in chld_out(!)
+    # However that may be, it works with open3. But to avoid the confusion of managing and
+    # closing an extra unused handle, a single handle is used instead for both the child's
+    # stderr and stdout.
+
+    # Both open2 and open3 don't return on failure, but raise an exception. The handling
+    # of the exception is described on p.568 of the Perl Cookbook
+    eval { 
+	$childpid = open3($chld_in, $chld_out, $chld_out, $command);
+    };
+    if ($@) {
+	if($@ =~ m/^open3/) {
+	    die "open3 failed in $0: $!\n$@\n";	    
+	}
+	die "Tried to launch open3 in $0, got unexpected exception: $@";
+    }
+
+    my $loop = 1;
+    while($loop)
+    {
+	if (defined(my $strLine=<$chld_out>)) { # we're reading in from child process' stdout
+	    if($blnShow) {
+		print STDERR "$strLine\n";
+	    }
+	    $strReadIn .= $strLine;
+	} 
+	else { # wget finished, terminate naturally
+	    #print STDOUT "\nPerl: open2 command, input stream closed. Wget terminated naturally.\n";
+	    close($chld_in);
+	    close($chld_out);
+	    waitpid $childpid, 0;
+	    $loop = 0;
+	    
+	    $childpid = undef;
+	    if(defined $port) {
+		$read_set->remove($serverSocket);
+		close($serverSocket);
+	    }
+	}
+
+	# if we run this script from the command-line (as opposed to from GLI), 
+	# then we're not working with sockets and can therefore can skip the next bits
+	next unless(defined $port);
+
+	# http://www.perlfect.com/articles/select.shtml
+	# "multiplex between several filehandles within a single thread of control, 
+	# thus creating the effect of parallelism in the handling of I/O."
+	my @rh_set = $read_set->can_read(0.002); # every 2 ms check if there's a client socket connecting
+
+	# take all readable handles in turn
+	foreach my $rh (@rh_set) {
+	    if($rh == $serverSocket) {
+		my $client = $rh->accept();
+		#$client->autoflush(1); # autoflush output buffer - don't put this back in: output split irregularly over lines
+		print $client "Talked to ServerSocket (port $port). Connection accepted\n";
+		
+		# Read from the client (getting rid of the trailing newline)
+		# Has the client sent the <<STOP>> signal?
+		my $signal = <$client>;
+		chomp($signal); 
+		if($signal eq "<<STOP>>") {
+		    print $client "Perl received STOP signal (on port $port): stopping wget\n";
+		    $loop = 0;                          # out of outer while loop
+		    $self->{'forced_quit'} = 1;         # subclasses need to know we're quitting
+		    
+		    # Sometimes the wget process takes some time to start up. If the STOP signal
+		    # was sent, don't try to terminate the process until we know it is running. 
+		    # Otherwise wget may start running after we tried to kill it. Wait 5 seconds
+		    # for it to start up, checking for whether it is running in order to kill it.
+		    for(my $seconds = 1; $seconds <= 5; $seconds++) {
+			if(kill(0, $childpid)) { 
+			    # If kill(0, $childpid) returns true, then the process is running
+			    # and we need to kill it.
+			    close($chld_in);
+			    close($chld_out);
+			    kill("TERM", $childpid);
+			    
+			    $childpid = undef;
+			    
+			    # Stop monitoring the read_handle and close the serverSocket 
+			    # (the Java end will close the client socket that Java opened)
+			    $read_set->remove($rh);     #$read_set->remove($serverSocket);
+			    close($rh); 	        #close($serverSocket);
+			    print $client "Perl terminated wget and is about to exit\n";
+			    last;                           # out of inner for loop
+			}
+			else { # the process may just be starting up, wait
+			    sleep(1);
+			}
+		    }
+		    last;                               # out of foreach loop
+		}
+	    }
+	}
+    }
+
+    if ($changed_dir) {
+	chdir $current_dir;
+    }
+    
+    return $strReadIn;
+}
+
+
+sub useWgetMonitored
+{
+    #local $| = 1; # autoflush stdout buffer
+    #print STDOUT "*** Start of subroutine useWgetMonitored in $0\n";
+
+    my ($self, $cmdWget,$blnShow, $working_dir) = @_;
+
+
+    my $current_dir = cwd();
+    my $changed_dir = 0;
+    if (defined $working_dir && -e $working_dir) {
+	chdir "$working_dir";
+	$changed_dir = 1;
+    }
+
+    # When we are running this script through GLI, the SIGTERM signal handler 
+    # won't get called on Windows when wget is to be prematurely terminated. 
+    # Instead, when wget has to be terminated in the middle of execution, GLI will
+    # connect to a serverSocket here to communicate when it's time to stop wget.
+    if($self->dealingWithSockets()) {
+
+	$port = <STDIN>; # gets a port on localhost that's not yet in use
+	chomp($port);
+	
+	$serverSocket = IO::Socket::INET->new( Proto     => 'tcp',
+					       LocalPort => $port,
+					       Listen    => 1,
+					       Reuse     => 1);
+    
+	die "can't setup server" unless $serverSocket;
+	#print STDOUT "[Serversocket $0 accepting clients at port $port]\n";
+
+	$read_set = new IO::Select();         # create handle set for reading
+	$read_set->add($serverSocket);        # add the main socket to the set
+    }
+
+    my $wget_file_path = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "wget");
+    my $command = "\"$wget_file_path\" $cmdWget";
+    #print STDOUT "Command is: $command\n";
+
+    eval {     # see p.568 of Perl Cookbook
+	$childpid = open3($chld_in, $chld_out, $chld_out, $command);
+    };
+    if ($@) {
+	if($@ =~ m/^open3/) {
+	    die "open3 failed in $0: $!\n$@\n";	    
+	}
+	die "Tried to launch open3 in $0, got unexpected exception: $@";
+    }
+
+    my $full_text = "";
+    my $error_text = "";
+    my @follow_list = ();
+    my $line;
+
+    my $loop = 1;
+    while($loop)
+    {
+	if (defined($line=<$chld_out>)) { # we're reading in from child process' stdout
+	    if((defined $blnShow) && $blnShow)
+	    {
+		print STDERR "$line";
+	    }
+	    
+	    if ($line =~ m/^Location:\s*(.*?)\s*\[following\]\s*$/i) {
+		my $follow_url = $1;
+		push(@follow_list,$follow_url);
+	    }
+	    
+	    if ($line =~ m/ERROR\s+\d+/) {
+		$error_text .= $line;
+	    }
+	    
+	    $full_text .= $line;
+	} 
+	else { # wget finished, terminate naturally
+	    #print STDERR "\nPerl: open2 command, input stream closed. Wget terminated naturally.\n";
+	    close($chld_in);
+	    close($chld_out);
+	    # Program terminates only when the following line is included 
+	    # http://perldoc.perl.org/IPC/Open2.html explains why this is necessary
+	    # it prevents the child from turning into a "zombie process".
+	    # While the wget process terminates without it, this perl script does not: 
+	    # the DOS prompt is not returned without it.
+	    waitpid $childpid, 0;
+	    $loop = 0;
+	    
+	    $childpid = undef;
+	    if(defined $port) {
+		$read_set->remove($serverSocket);
+		close($serverSocket);
+	    }
+	}
+
+	# if we run this script from the command-line (as opposed to from GLI), 
+	# then we're not working with sockets and can therefore can skip the next bits
+	next unless(defined $port);
+
+	# http://www.perlfect.com/articles/select.shtml
+	# "multiplex between several filehandles within a single thread of control, 
+	# thus creating the effect of parallelism in the handling of I/O."
+	my @rh_set = $read_set->can_read(0.002); # every 2 ms check if there's a client socket connecting
+
+	# take all readable handles in turn
+	foreach my $rh (@rh_set) {
+	    if($rh == $serverSocket) {
+		my $client = $rh->accept();
+		#$client->autoflush(1); # autoflush output buffer - don't put this back in: splits output irregularly over multilines
+		print $client "Talked to ServerSocket (port $port). Connection accepted\n";
+		
+		# Read from the client (getting rid of trailing newline)
+		# Has the client sent the <<STOP>> signal?
+		my $signal = <$client>;
+		chomp($signal); 
+		if($signal eq "<<STOP>>") {
+		    print $client "Perl received STOP signal (on port $port): stopping wget\n";
+		    $loop = 0;                          # out of outer while loop
+		    $self->{'forced_quit'} = 1;         # subclasses need to know we're quitting
+		    
+		    # Sometimes the wget process takes some time to start up. If the STOP signal
+		    # was sent, don't try to terminate the process until we know it is running. 
+		    # Otherwise wget may start running after we tried to kill it. Wait 5 seconds
+		    # for it to start up, checking for whether it is running in order to kill it.
+		    for(my $seconds = 1; $seconds <= 5; $seconds++) {
+			if(kill(0, $childpid)) { 
+			    # If kill(0, $childpid) returns true, then the process is running
+			    # and we need to kill it.
+			    close($chld_in);
+			    close($chld_out);
+			    kill("TERM", $childpid);
+			    
+			    $childpid = undef;
+			    
+			    # Stop monitoring the read_handle and close the serverSocket 
+			    # (the Java end will close the client socket that Java opened)
+			    $read_set->remove($rh);     #$read_set->remove($serverSocket);
+			    close($rh); 	        #close($serverSocket);
+			    print $client "Perl terminated wget and is about to exit\n";
+			    last;                           # out of inner for loop
+			}
+			else { # the process may just be starting up, wait
+			    sleep(1);
+			}
+		    }
+		    last;                               # out of foreach loop
+		}
+	    }
+	}
+    }
+
+    my $command_status = $?;
+    if ($command_status != 0) {
+	$error_text .= "Exit error: $command_status";
+    }
+
+    if ($changed_dir) {
+	chdir $current_dir;
+    }
+    
+    my $final_follow = pop(@follow_list); # might be undefined, but that's OK
+    
+    return ($full_text,$error_text,$final_follow);
+}
+
+
+# TODO: Check if the URL is valid?? Not sure what should be in this function yet!!
+sub checkURL
+{
+    my ($self) = @_;
+    if ($self->{'url'} eq "")
+    {
+	&error("checkURL","no URL is specified!! Please specifies the URL for downloading.");
+    }
+}
+
+sub error
+{
+    my ($strFunctionName,$strError) = @_;
+    {
+	print "Error occoured in WgetDownload.pm\n".
+	    "In Function:".$strFunctionName."\n".
+	    "Error Message:".$strError."\n";
+	exit(-1);
+    }
+}
+
+1;
Index: /gsdl/stable/perllib/downloaders/Z3950Download.pm
===================================================================
--- /gsdl/stable/perllib/downloaders/Z3950Download.pm	(revision 20131)
+++ /gsdl/stable/perllib/downloaders/Z3950Download.pm	(revision 20131)
@@ -0,0 +1,417 @@
+###########################################################################
+#
+# WebDownload.pm -- base class for all the import plugins
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package Z3950Download;
+
+eval {require bytes};
+
+# suppress the annoying "subroutine redefined" warning that various
+# plugins cause under perl 5.6
+$SIG{__WARN__} = sub {warn($_[0]) unless ($_[0] =~ /Subroutine\s+\S+\sredefined/)};
+
+use strict;
+
+use BaseDownload;
+use IPC::Open2;
+use POSIX ":sys_wait_h"; # for waitpid, http://perldoc.perl.org/functions/waitpid.html
+
+sub BEGIN {
+    @Z3950Download::ISA = ('BaseDownload');
+}
+
+my $arguments = 
+    [  { 'name' => "host", 
+	'disp' => "{Z3950Download.host_disp}",
+	'desc' => "{Z3950Download.host}",
+	'type' => "string",
+	'reqd' => "yes"},
+      { 'name' => "port", 
+	'disp' => "{Z3950Download.port_disp}",
+	'desc' => "{Z3950Download.port}",
+	'type' => "string",
+	'reqd' => "yes"},
+      { 'name' => "database", 
+	'disp' => "{Z3950Download.database_disp}",
+	'desc' => "{Z3950Download.database}",
+      	'type' => "string",
+	'reqd' => "yes"},
+      { 'name' => "find", 
+	'disp' => "{Z3950Download.find_disp}",
+	'desc' => "{Z3950Download.find}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "yes"},
+      { 'name' => "max_records", 
+	'disp' => "{Z3950Download.max_records_disp}",
+	'desc' => "{Z3950Download.max_records}",
+	'type' => "int",
+	'deft' => "500",
+	'reqd' => "no"}];
+
+my $options = { 'name'     => "Z3950Download",
+		'desc'     => "{Z3950Download.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new 
+{
+    my ($class) = shift (@_);
+    my ($getlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$getlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseDownload($getlist,$inputargs,$hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    # Must set $self->{'url'}, since GLI use $self->{'url'} to calculate the log file name!
+    $self->{'url'} = $self->{'host'}.":".$self->{'port'};
+
+    $self->{'yaz'} = &util::filename_cat($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "yaz-client");
+    
+    return bless $self, $class;
+
+}
+
+sub download
+{
+    my ($self) = shift (@_);
+    my ($hashGeneralOptions) = @_;
+    my ($strOpen,$strBase,$strFind,$strResponse,$intAmount,$intMaxRecords,$strRecords);
+
+    my $url = $self->{'url'};
+ 
+    print STDERR "<<Defined Maximum>>\n";
+ 
+    $strOpen = $self->start_yaz($url);
+
+    print STDERR "Access database: \"$self->{'database'}\"\n";
+    $self->run_command_without_output("base $self->{'database'}");
+    print STDERR "Searching for keyword: \"$self->{'find'}\"\n";
+    $intAmount = $self->findAmount($self->{'find'});
+
+    if($intAmount <= 0)
+    {
+	($intAmount == -1)? 
+	    print STDERR "Something wrong with the arguments,downloading can not be performed\n": 
+		print STDERR "No Record is found\n";
+	print STDERR "<<Finished>>\n";
+	return 0;
+    }
+    $intMaxRecords = ($self->{'max_records'} > $intAmount)? $intAmount : $self->{'max_records'};
+    print STDERR "<<Total number of record(s):$intMaxRecords>>\n";
+    $strRecords = "Records: $intMaxRecords\n".$self->getRecords($intMaxRecords);
+   
+    $self->saveRecords($strRecords,$hashGeneralOptions->{'cache_dir'},$intMaxRecords);
+    print STDERR "Closing connection...\n";
+
+    $self->quit_yaz();
+    return 1;
+}
+
+
+sub start_yaz 
+{
+    my ($self, $url) = @_;    
+
+    print STDERR "Opening connection to $url\n";
+     
+    my $yaz = $self->{'yaz'};
+    
+    my $childpid = open2(*YAZOUT, *YAZIN, $yaz)
+	or (print STDERR "<<Finished>>\n" and die "can't open pipe to yaz-client: $!");
+    $self->{'pid'} = $childpid;
+    $self->{'YAZOUT'} = *YAZOUT;
+    $self->{'YAZIN'} = *YAZIN;
+
+    my $strOpen = $self->open_connection("open $url");  
+
+    if (!$strOpen) {
+        print STDERR "Cannot connect to $url\n"; 
+        print STDERR "<<Finished>>\n";  
+	return 0;
+    }
+    return $strOpen;
+}
+
+sub quit_yaz 
+{
+    my ($self) = shift (@_);
+
+    # can't send a "close" cmd to close the database here, since the close command is only
+    # recognised by Z3950, not by SRW. (This method is also used by the subclass for SRW.)
+
+    print STDERR "<<Finished>>\n";
+
+    # need to send the quit command, else yaz-client is still running in the background
+    $self->run_command_without_output("quit");
+    close($self->{'YAZIN'}); # close the input to yaz. It also flushes quit command to yaz.
+
+    # make sure nothing is being output by yaz
+    # flush the yaz-client process' outputstream, else we'll be stuck in an infinite
+    # loop waiting for the process to quit.
+    my $output = $self->{'YAZOUT'};
+    my $line;
+    while (defined ($line = <$output>)) { 
+	if($line !~ m/\w/s) { # print anything other than plain whitespace in case it is important
+	    print STDERR "***### $line";
+	}
+    }
+
+    close($self->{'YAZOUT'});
+
+    # Is the following necessary? The PerlDoc on open2 (http://perldoc.perl.org/IPC/Open2.html)
+    # says that waitpid must be called to "reap the child process", or otherwise it will hang
+    # around like a zombie process in the background. Adding it here makes the code work as 
+    # before, but it is certainly necessary to call waitpid on wget (see WgetDownload.pm).
+    # http://perldoc.perl.org/functions/waitpid.html
+    my $kidpid;
+    do {
+	$kidpid = waitpid($self->{'pid'}, WNOHANG);
+    } while $kidpid > 0; # waiting for pid to become -1
+}
+
+sub open_connection{
+  my ($self,$strCommand) =  (@_);
+  
+  $self->run_command($strCommand);  
+
+  my $out = $self->{'YAZOUT'}; 
+
+  my $opening_line = <$out>;
+  
+  return ($opening_line =~ m/Connecting...OK/i)? 1: 0; 
+ 
+}
+
+sub findAmount
+{
+    my ($self) = shift (@_);
+    my($strFindTarget) = @_;
+    my $strResponse = $self->run_command_with_output("find $strFindTarget","^Number of hits:");
+   return ($strResponse =~ m/^Number of hits: (\d+)/m)? $1:-1;    
+}
+
+sub getRecords
+{
+    my ($self) = shift (@_);
+    my ($intMaxRecords) = @_;
+    my ($strShow,$intStartNumber,$numRecords,$strResponse,$strRecords,$intRecordsLeft);
+
+    $intStartNumber = 1;
+    $intRecordsLeft = $intMaxRecords;
+    $numRecords = 0;
+    $strResponse ="";
+
+    while ($intRecordsLeft > 0)
+    {
+	if($intRecordsLeft > 50)
+	{
+	   
+	    print STDERR "Yaz is Gathering records: $intStartNumber - ".($intStartNumber+49)."\n";
+	    $numRecords = 50;
+	    $strShow = "show $intStartNumber+50";
+	    $intStartNumber = $intStartNumber + 50;
+	    $intRecordsLeft = $intRecordsLeft - 50;
+             
+	}
+	else
+	{
+	    $numRecords = $intRecordsLeft;
+	    print STDERR "Yaz is Gathering records: $intStartNumber - ".($intStartNumber+$intRecordsLeft-1)."\n";
+	    $strShow = "show $intStartNumber+$intRecordsLeft";
+	    $intRecordsLeft = 0;
+	   
+           }
+	
+	$strResponse .= $self->get($strShow,$numRecords);
+         
+	if ($strResponse eq ""){
+	    print STDERR "<<ERROR: failed to get $numRecords records>>\n";
+	}
+	else{
+	    print STDERR "<<Done:$numRecords>>\n";
+	}
+    }
+
+    return  "$strResponse\n";
+	
+}
+
+sub saveRecords
+{
+    my ($self,$strRecords,$strOutputDir,$intMaxRecords) = @_;
+
+    # setup directories
+    # Currently only gather the MARC format
+    my $strFileName = $self->generateFileName($intMaxRecords);
+
+    $strOutputDir  =~ s/"//g; #"
+
+    my $strOutputFile = &util::filename_cat($strOutputDir,$self->{'host'},"$strFileName.marc");
+     # prepare subdirectory for record (if needed)
+    my ($strSubDirPath,$unused) = $self->dirFileSplit($strOutputFile);
+ 
+    &util::mk_all_dir($strSubDirPath);
+  
+    print STDERR "Saving records to \"$strOutputFile\"\n";
+
+    # save record 
+    open (ZOUT,">$strOutputFile")
+	|| die "Unable to save Z3950 record: $!\n";
+    print ZOUT $strRecords;
+    close(ZOUT);
+}
+
+
+sub run_command_with_output
+{
+    my ($self,$strCMD,$strStopRE) =@_;
+   
+    $self->run_command($strCMD); 
+   
+    return $self->get_output($strStopRE);
+ 
+}
+
+sub get{
+   my ($self,$strShow,$numRecord) = @_;  
+
+   $self->run_command($strShow);  
+   
+   my $strFullOutput="";
+   my $count=0;
+   my $readRecord = 0;
+   
+   my $output = $self->{'YAZOUT'};
+   while (my $strLine = <$output>)
+   {
+   
+       if ($strLine =~ m/Records: ([\d]*)/i ){ 
+	   $readRecord = 1;
+	   next;  
+       }
+      
+      return $strFullOutput if ($strLine =~ m/nextResultSetPosition|Not connected/i);
+        
+      next if(!$readRecord);
+      
+      $strFullOutput .= $strLine;     
+  }
+   
+}
+
+sub run_command_without_output
+{
+     my ($self) = shift (@_);
+    my ($strCMD) = @_;
+
+    $self->run_command($strCMD);
+}
+
+sub run_command
+{
+    my ($self,$strCMD) = @_; 
+ 
+    my $input = $self->{'YAZIN'};
+
+    print $input "$strCMD\n";  
+}
+
+sub get_output{
+    my ($self,$strStopRE) = @_;  
+
+    if (!defined $strStopRE){return "";}
+    else
+    {
+	my $strFullOutput;
+        my $output = $self->{'YAZOUT'};
+	while (my $strLine = <$output>)
+	{
+           $strFullOutput .= $strLine;   
+	   if($strLine =~ m/^$strStopRE|Not connected/i){return $strFullOutput;}
+	}
+    }
+}
+
+sub generateFileName
+{
+    my ($self,$intMaxRecords) = @_;
+    my $strFileName = ($self->{'database'})."_".($self->{'find'})."_".($intMaxRecords);
+ 
+}
+
+sub dirFileSplit
+{
+    my ($self,$strFile) = @_;
+
+    my @aryDirs = split(/[\/\\]/,$strFile);
+   
+    my $strLocalFile = pop(@aryDirs);
+    my $strSubDirs = join("/",@aryDirs);
+
+    return ($strSubDirs,$strLocalFile);
+}
+
+sub url_information
+{
+   my ($self,$url) = @_;
+
+   $url = $self->{'url'} unless defined $url;
+
+   my $strOpen = $self->start_yaz();
+
+   $strOpen = $self->run_command_with_output("open $url","^Options");  
+
+   $strOpen =~ s/Z> //g;
+   $strOpen =~ s/Elapsed:.*//g;
+
+   print STDERR $strOpen; 
+
+   $self->quit_yaz();
+
+   return 0;
+
+}
+
+sub error
+{
+    my ($self,$strFunctionName,$strError) = @_;
+    {
+	print STDERR "Error occoured in Z3950Download.pm\n".
+	    "In Function:".$strFunctionName."\n".
+	    "Error Message:".$strError."\n";
+	exit(-1);
+    }
+}
+
+1;
Index: /gsdl/stable/perllib/encodings.pm
===================================================================
--- /gsdl/stable/perllib/encodings.pm	(revision 20131)
+++ /gsdl/stable/perllib/encodings.pm	(revision 20131)
@@ -0,0 +1,117 @@
+###########################################################################
+#
+# encodings.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# Each encoding supported by the Greenstone build-time software should be
+# specified in the following hash table ($encodings).
+
+package encodings;
+
+use strict;
+
+# $encodings takes the form:
+# --> identifier --> name      --> The full display name of the encoding.
+#                --> mapfile   --> The ump file associated with the encoding
+#                --> double    --> 1 if it's a double byte encoding
+#                --> converter --> If the encoding needs a specialized conversion
+#                                  routine this is the name of that routine.
+
+$encodings::encodings = {
+    'iso_8859_1' => {'name' => 'Latin1 (western languages)', 'mapfile' => '8859_1.ump'},
+
+    'iso_8859_2' => {'name' => 'Latin2 (central and eastern european languages)',
+		     'mapfile' => '8859_2.ump'},
+
+    'iso_8859_3' => {'name' => 'Latin3', 'mapfile' => '8859_3.ump'},
+
+    'iso_8859_4' => {'name' => 'Latin4', 'mapfile' => '8859_4.ump'},
+
+    'iso_8859_5' => {'name' => 'Cyrillic', 'mapfile' => '8859_5.ump'},
+
+    'iso_8859_6' => {'name' => 'Arabic', 'mapfile' => '8859_6.ump'},
+
+    'iso_8859_7' => {'name' => 'Greek', 'mapfile' => '8859_7.ump'},
+
+    'iso_8859_8' => {'name' => 'Hebrew', 'mapfile' => '8859_8.ump'},
+
+    'iso_8859_9' => {'name' => 'Turkish', 'mapfile' => '8859_9.ump'},
+
+    'iso_8859_15' => {'name' => 'Latin15 (revised western)', 'mapfile' => '8859_15.ump'},
+
+    'windows_1250' => {'name' => 'Windows codepage 1250 (WinLatin2)',
+		       'mapfile' => 'win1250.ump'},
+
+    'windows_1251' => {'name' => 'Windows codepage 1251 (WinCyrillic)',
+		       'mapfile' => 'win1251.ump'},
+
+    'windows_1252' => {'name' => 'Windows codepage 1252 (WinLatin1)',
+		       'mapfile' => 'win1252.ump'},
+
+    'windows_1253' => {'name' => 'Windows codepage 1253 (WinGreek)', 
+		       'mapfile' => 'win1253.ump'},
+
+    'windows_1254' => {'name' => 'Windows codepage 1254 (WinTurkish)',
+		       'mapfile' => 'win1254.ump'},
+
+    'windows_1255' => {'name' => 'Windows codepage 1255 (WinHebrew)', 
+		       'mapfile' => 'win1255.ump'},
+
+    'windows_1256' => {'name' => 'Windows codepage 1256 (WinArabic)', 
+		       'mapfile' => 'win1256.ump'},
+
+    'windows_1257' => {'name' => 'Windows codepage 1257 (WinBaltic)',
+		       'mapfile' => 'win1257.ump'},
+
+    'windows_1258' => {'name' => 'Windows codepage 1258 (Vietnamese)',
+		       'mapfile' => 'win1258.ump'},
+
+    'windows_874' => {'name' => 'Windows codepage 874 (Thai)', 'mapfile' => 'win874.ump'},
+
+    'dos_437' => {'name' => 'DOS codepage 437 (US English)', 'mapfile' => 'dos437.ump'},
+
+    'dos_850' => {'name' => 'DOS codepage 850 (Latin 1)', 'mapfile' => 'dos850.ump'},
+
+    'dos_852' => {'name' => 'DOS codepage 852 (Central European)', 'mapfile' => 'dos852.ump'},
+
+    'dos_866' => {'name' => 'DOS codepage 866 (Cyrillic)', 'mapfile' => 'dos866.ump'},
+
+    'koi8_r' => {'name' => 'Cyrillic', 'mapfile' => 'koi8_r.ump'},
+
+    'koi8_u' => {'name' => 'Cyrillic (Ukrainian)', 'mapfile' => 'koi8_u.ump'},
+
+    'iscii_de' => {'name' => 'ISCII Devanagari', 'mapfile' => 'iscii_de.ump'},
+
+    'shift_jis' => {'name' => 'Japanese (Shift-JIS)', 'mapfile' => 'shiftjis.ump',
+		    'converter' => 'shiftjis2unicode'},
+
+    'euc_jp' => {'name' => 'Japanese (EUC)', 'mapfile' => 'euc_jp.ump'},
+
+    'korean' => {'name' => 'Korean (Unified Hangul Code - i.e. a superset of EUC-KR)',
+		 'mapfile' => 'uhc.ump'},
+
+    'gb' => {'name' => 'Chinese Simplified (GB)', 'mapfile' => 'gbk.ump'},
+
+    'big5' => {'name' => 'Chinese Traditional (Big5)', 'mapfile' => 'big5.ump'}
+
+};
Index: /gsdl/stable/perllib/expinfo.pm
===================================================================
--- /gsdl/stable/perllib/expinfo.pm	(revision 20131)
+++ /gsdl/stable/perllib/expinfo.pm	(revision 20131)
@@ -0,0 +1,166 @@
+###########################################################################
+#
+# expinfo.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# modified by: Chi-Yu Huang
+# This module stores information about the export directory. At the moment
+# this information just consists of the file name (relative to the
+# directory the export information file is in) and its OID.
+
+# This module assumes there is a one to one correspondance between
+# a file in the export directory and an OID.
+
+package expinfo;
+
+
+use strict;
+
+
+sub new {
+    my ($class) = @_;
+    my $self = {'info'=>{},
+		'order'=>[]};
+
+    return bless $self, $class;
+}
+
+sub load_info {
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    $self->{'info'} = {};
+ 
+    if (-e $filename) {
+	open (INFILE, $filename) || 
+	    die "expinfo::load_info couldn't read $filename\n";
+
+	my ($line, @line);
+	while (defined ($line = <INFILE>)) {
+	    $line =~ s/\cM|\cJ//g; # remove end-of-line characters
+	    @line = split ("\t", $line); # filename, 
+	    if (scalar(@line) >= 2) {
+		$self->add_info (@line);
+	    }
+	}
+	close (INFILE);
+    }
+}
+
+sub save_info {
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    my ($OID, $info);
+
+    open (OUTFILE, ">$filename") || 
+	die "expinfo::save_info couldn't write $filename\n";
+
+    foreach $info (@{$self->get_OID_list()}) {
+	if (defined $info) {
+	    print OUTFILE join("\t", @$info), "\n";
+	}
+    }
+    close (OUTFILE);
+}
+
+sub delete_info {
+    my $self = shift (@_);
+    my ($OID) = @_;
+
+    if (defined $self->{'info'}->{$OID}) {
+	delete $self->{'info'}->{$OID};
+	
+	my $i = 0;
+	while ($i < scalar (@{$self->{'order'}})) {
+	    if ($self->{'order'}->[$i]->[0] eq $OID) {
+		splice (@{$self->{'order'}}, $i, 1);
+		last;
+	    }
+	    $i ++;
+	}
+    }
+}
+
+sub add_info {
+    my $self = shift (@_);
+    my ($OID, $doc_file, $sortmeta) = @_;
+    $sortmeta = "" unless defined $sortmeta;
+
+    if (! defined($OID)) {
+	# only happens when no files can be processed?
+	return undef;
+    }
+    $self->delete_info ($OID);
+    $self->{'info'}->{$OID} = [$doc_file];
+    push (@{$self->{'order'}}, [$OID, $sortmeta]);
+}
+
+# returns a list of the form [[OID, doc_file], ...]
+sub get_OID_list {
+    my $self = shift (@_);
+
+    my ($OID);
+    my @list = ();
+
+    foreach $OID (sort {$a->[1] cmp $b->[1]} @{$self->{'order'}}) {
+	push (@list, [$OID->[0], $self->{'info'}->{$OID->[0]}->[0]]);
+    }
+    return \@list;
+}
+
+# returns a list of the form [[doc_file, OID], ...]
+sub get_file_list {
+    my $self = shift (@_);
+
+    my ($OID);
+    my @list = ();
+
+    foreach $OID (sort {$a->[1] cmp $b->[1]} @{$self->{'order'}}) {
+	push (@list, [$self->{'info'}->{$OID->[0]}->[0], $OID->[0]]);
+    }
+    return \@list;
+}
+
+
+# returns a list of the form [doc_file]
+sub get_info {
+    my $self = shift (@_);
+    my ($OID) = @_;
+
+    if (defined $self->{'info'}->{$OID}) {
+	return $self->{'info'}->{$OID};
+    }
+
+    return undef;
+}
+
+
+# returns the number of documents so far
+sub size {
+    my $self = shift (@_);
+    return (scalar(@{$self->{'order'}}));
+}
+
+1;
+
Index: /gsdl/stable/perllib/g2futil.pm
===================================================================
--- /gsdl/stable/perllib/g2futil.pm	(revision 20131)
+++ /gsdl/stable/perllib/g2futil.pm	(revision 20131)
@@ -0,0 +1,412 @@
+package g2futil;
+
+
+BEGIN 
+{
+    if (!defined $ENV{'FEDORA_HOME'}) {
+	print STDERR "Error: Environment variable FEDORA_HOME not set.\n";
+	exit 1;
+    }
+
+    my $fedora_client_bin = &util::filename_cat($ENV{'FEDORA_HOME'},"client","bin");
+    &util::envvar_append("PATH",$fedora_client_bin);
+}
+
+use strict;
+use util;
+
+sub run_cmd_old
+{
+    my ($cmd,$verbosity,$tolerate_error) = @_;
+
+    if (($verbosity == 0) 
+	|| (defined $tolerate_error && ($tolerate_error eq "tolerate_error"))) {
+	if($ENV{'GSDLOS'} =~ /^windows$/i) {
+	    $cmd .= " > nul";
+	} else {
+	    $cmd .= " > /dev/null";
+	}
+    }
+    
+    if ($verbosity >= 2) {
+	print "Runing command:\n";
+	print "$cmd\n";
+    }
+
+    my $status = system($cmd);
+
+    if ($verbosity >= 2) {
+	print "Exit status = ", $status/256, "\n";
+    }
+
+    if ((!defined $tolerate_error) || ($tolerate_error ne "tolerate_error")) {
+	if ($status>0) {
+	    print STDERR "Error executing:\n$cmd\n";
+	    print STDERR "$!\n";
+	}
+    }
+
+    return $status;
+}
+
+
+sub run_cmd
+{
+    my ($prog,$arguments,$verbosity,$tolerate_error) = @_;
+
+    my $cmd_status = undef;
+
+    my $script_ext = ($ENV{'GSDLOS'} =~ m/^windows/) ? ".bat" : ".sh";
+
+    if ($prog =~ m/^fedora-/) {
+	$prog .= $script_ext;
+    }
+    if (($prog =~ m/.pl$/i) && ($ENV{'GSDLOS'} =~ m/^windows/)) {
+	$prog ="perl -S $prog";
+    }
+ 
+    my $cmd = "$prog $arguments";
+
+###    print "*** cmd = $cmd\n";
+
+    if (open(CMD,"$cmd 2>&1 |"))
+    {
+	my $result = "";
+	my $line;
+	while (defined ($line = <CMD>))
+	{	
+	    $result .= $line;	    
+
+	    if ((!defined $tolerate_error) || ($tolerate_error ne "tolerate_error"))
+	    {
+		print $line;
+	    }
+
+
+	}
+	
+	close(CMD);
+	
+	$cmd_status = $?;
+
+	if ($cmd_status == 0) {
+	    # Check for any lines in result begining 'Error:'
+	    
+	    if ($result =~ m/^Error\s*:/m) {
+		# Fedora script generated an error, but did not exit
+		# with an error status => artificially raise one
+
+		$cmd_status = -1;
+	    }
+	}
+
+	if ($cmd_status != 0) {
+
+	    if ((!defined $tolerate_error) || ($tolerate_error ne "tolerate_error"))
+	    {
+		print STDERR "Error: processing command failed.  Exit status $cmd_status\n";
+		
+		if ($verbosity >= 2) {
+		    print STDERR "  Command was: $cmd\n";
+		}
+		if ($verbosity >= 3) {
+		    print STDERR "result: $result\n";
+		}
+
+	    }
+	}
+    }
+    else 
+    {
+	print STDERR "Error: failed to execute $cmd\n";
+    }
+
+
+    return $cmd_status;
+}
+
+
+sub run_datastore_info
+{
+    my ($pid,$options) = @_;
+
+    my $verbosity = $options->{'verbosity'};
+
+    my $hostname = $options->{'hostname'};
+    my $port     = $options->{'port'};
+    my $username = $options->{'username'};
+    my $password = $options->{'password'};
+    my $protocol = $options->{'protocol'};
+
+    my $prog = "fedora-dsinfo";
+    my $arguments = "$hostname $port $username $password $pid $protocol";
+    my $status = run_cmd($prog,$arguments,$verbosity,"tolerate_error");
+
+    return $status;
+}
+
+sub run_purge
+{
+    my ($pid,$options) = @_;
+
+    my $verbosity = $options->{'verbosity'};
+
+    my $hostname = $options->{'hostname'};
+    my $port     = $options->{'port'};
+    my $username = $options->{'username'};
+    my $password = $options->{'password'};
+    my $protocol = $options->{'protocol'};
+
+    my $server = "$hostname:$port";
+
+    my $prog = "fedora-purge";
+    my $arguments = "$server $username $password $pid $protocol";
+    $arguments .= " \\\n \"Automated_purge_by_g2f_script\"";
+
+    my $status = run_cmd($prog,$arguments,$verbosity);
+
+    return $status;
+}
+
+sub run_ingest
+{
+    my ($docmets_filename,$options) = @_;
+
+    my $verbosity = $options->{'verbosity'};
+
+    my $hostname = $options->{'hostname'};
+    my $port     = $options->{'port'};
+    my $username = $options->{'username'};
+    my $password = $options->{'password'};
+    my $protocol = $options->{'protocol'};
+
+    my $server = "$hostname:$port";
+
+    my $prog = "fedora-ingest";
+
+    my $type = undef;
+    
+    if ($ENV{'FEDORA_VERSION'} =~ m/^2/) { # checking if major version is 2
+    	$type = "metslikefedora1";
+    }
+    else {
+	$type = "info:fedora/fedora-system:METSFedoraExt-1.1";
+    }
+
+    my $arguments = "file \"$docmets_filename\" $type $server $username $password $protocol";
+    $arguments .= " \\\n \"Automated_purge_by_g2f_script\"";
+
+    my $status = run_cmd($prog,$arguments,$verbosity);
+
+    return $status;
+}
+
+
+sub rec_get_all_hash_dirs
+{
+    my ($full_dir,$all_dirs) = @_;
+
+    if (opendir(DIR, $full_dir)) {
+	my @sub_dirs = grep { ($_ !~ /^\./) && (-d &util::filename_cat($full_dir,$_)) } readdir(DIR);
+	closedir DIR;
+
+	my @hash_dirs = grep { $_ =~ m/\.dir$/ } @sub_dirs;
+	my @rec_dirs = grep { $_ !~ m/\.dir$/ } @sub_dirs;
+	
+	foreach my $hd (@hash_dirs) {
+	    my $full_hash_dir = &util::filename_cat($full_dir,$hd);
+	    push(@$all_dirs,$full_hash_dir);
+	}
+
+	foreach my $rd (@rec_dirs) {
+	    my $full_rec_dir = &util::filename_cat($full_dir,$rd);
+	    rec_get_all_hash_dirs($full_rec_dir,$all_dirs);
+	}	    
+    }
+}
+
+sub get_all_hash_dirs
+{
+    my ($start_dir,$maxdocs) = @_;
+    
+    my @all_dirs = ();
+    rec_get_all_hash_dirs($start_dir,\@all_dirs);
+
+    if ((defined $maxdocs) && ($maxdocs ne "")) {
+	my @maxdoc_dirs = ();
+	for (my $i=0; $i<$maxdocs; $i++) {
+	    push(@maxdoc_dirs,shift(@all_dirs));
+	}
+	@all_dirs = @maxdoc_dirs;
+    }
+
+    return @all_dirs;
+}
+
+sub get_hash_id
+{
+    my ($hash_dir) = @_;
+
+    my $hash_id = undef;
+
+    my $docmets_filename = &util::filename_cat($hash_dir,"docmets.xml");
+
+    if (open(DIN,"<$docmets_filename"))
+    {
+	while (defined (my $line = <DIN>))
+	{
+	    if ($line =~ m/<dc:identifier>(.*?)<\/dc:identifier>/)
+	    {
+		$hash_id = $1;
+		last;
+	    }
+	}
+    
+	close(DIN);
+    }
+    else
+    {
+	print STDERR "Warning: Unable to open \"$docmets_filename\"\n";
+    }
+
+    return $hash_id;
+
+}
+
+
+# Subroutine to write the gsdl.xml file in FEDORA_HOME/tomcat/conf/Catalina/<host/localhost>/
+# This xml file will tell Fedora where to find the parent folder of the GS collect dir
+# so that it can obtain the FedoraMETS files for ingestion. 
+# It depends on the Fedora server being on the same machine as the Greenstone server that 
+# this code is part of.
+sub write_gsdl_xml_file
+{
+    my ($fedora_host, $collect_dir, $options) = @_;
+    my $verbosity = $options->{'verbosity'};
+    my $hostname = $options->{'hostname'};
+    my $port     = $options->{'port'};
+    my $protocol = $options->{'protocol'};
+
+    print STDERR "Ensuring that a correct gsdl.xml file exists on the Fedora server end\n";
+    # The top of this file has already made sure that FEDORA_HOME is set, but for GS3
+    # CATALINA_HOME is set to GS' own tomcat. Since we'll be working with fedora, we need
+    # to temporarily set CATALINA_HOME to fedora's tomcat. (Catalina is undefined for GS2).
+    my $gs_catalina_home = $ENV{'CATALINA_HOME'} if defined $ENV{'CATALINA_HOME'};
+    $ENV{'CATALINA_HOME'} = &util::filename_cat($ENV{'FEDORA_HOME'}, "tomcat");
+    
+    # 1. Find out which folder to write to: fedora_host or localhost 
+    # whichever contains fedora.xml is the one we want (if none, exit with error value?)
+    my $fedora_home = $ENV{'FEDORA_HOME'};
+    my $base_path = &util::filename_cat($fedora_home, "tomcat", "conf", "Catalina");
+
+    my $host_path = &util::filename_cat($base_path, $fedora_host);
+    my $xmlFile = &util::filename_cat($host_path, "fedora.xml");
+    if (!-e $xmlFile) {
+	# check if the folder localhost contains fedoraXML
+	$host_path = &util::filename_cat($base_path, "localhost");
+	$xmlFile = &util::filename_cat($host_path, "fedora.xml");
+	if(!-e $xmlFile) {
+	    # try putting gsdl in this folder, but still print a warning
+	    print STDERR "$host_path does not contain file fedora.xml. Hoping gsdl.xml belongs there anyway\n";
+	}
+    }
+
+    # 2. Construct the string we are going write to the gsdl.xml file
+    # a. get the parent directory of collect_dir by removinbg the word 
+    # "collect" from it and any optional OS-type slash at the end. 
+    # (Path slash direction does not matter here.)
+    my $collectParentDir = $collect_dir;
+    $collectParentDir =~ s/collect(\/|\\)?//;
+  
+    # b. Use the collectParentDir to create the contents of gsdl.xml
+    my $gsdlXMLcontents = "<?xml version='1.0' encoding='utf-8'?>\n<Context docBase=\"";
+    $gsdlXMLcontents = $gsdlXMLcontents.$collectParentDir."\" path=\"/gsdl\"></Context>";
+    
+    # 3. If there is already a gsdl.xml file in host_path, compare the string we
+    # want to write with what is already in there. If they're the same, we can return
+    $xmlFile = &util::filename_cat($host_path, "gsdl.xml");
+    if(-e $xmlFile) {
+	# such a file exists, so read the contents
+	unless(open(FIN, "<$xmlFile")) { 
+	    print STDERR "g2f-import.pl: Unable to open existing $xmlFile for comparing...Recoverable. $!\n";
+	    # doesn't matter, we'll just overwrite it then
+	}    
+	my $xml_contents;
+	{
+	    local $/ = undef;        # Read entire file at once
+	    $xml_contents = <FIN>;   # Now file is read in as one single 'line'
+	}
+	close(FIN); # close the file
+	if($xml_contents eq $gsdlXMLcontents) { 
+	    print STDERR "Fedora links to the FLI import folder through gsdl.xml.\n";
+	    # it already contains what we want, we're done
+	    return "gsdl.xml";
+	}
+    }
+
+    # 4. If we're here, the contents of gsdl.xml need to be updated:
+    # a. First stop the fedora server
+    my $script_ext = ($ENV{'GSDLOS'} =~ m/^windows/) ? ".bat" : ".sh";
+    my $stop_tomcat = &util::filename_cat($fedora_home, "tomcat", "bin", "shutdown".$script_ext);
+    # execute the command 
+    $! = 0; # does this initialise the return value?
+    my $status = system($stop_tomcat);
+    if ($status!=0) { # to get the actual exit value, divide by 256, but not useful here
+	# possible tomcat was already stopped - it's not the end of the world
+	print STDERR "Failed to stop Fedora server. Perhaps it was not running. $!\n";
+	print "Exit status = ", $status/256, "\n";
+    }
+
+    # b. overwrite the file that has outdated contents with the contents we just constructed
+    unless(open(FOUT, ">$xmlFile")) {  # create or overwrite gsdl.xml file
+	die "g2f-import.pl: Unable to open $xmlFile for telling Fedora where the collect dir is...ERROR: $!\n";
+    }
+    # write out the updated contents and close the file
+    print FOUT $gsdlXMLcontents;
+    close(FOUT);
+
+    # c. Restart the fedora server
+    my $start_tomcat = &util::filename_cat($fedora_home, "tomcat", "bin", "startup".$script_ext);
+    $! = 0;
+    $status = system($start_tomcat);
+    if ($status!=0) { 
+	print STDERR "Failed to restart the Fedora server... ERROR: $!\n";
+	print "Exit status = ", $status/256, "\n";
+    }
+
+    # reset CATALINA_HOME to GS' Tomcat (it is undefined for GS2 since GS2 has no tomcat):
+    $ENV{'CATALINA_HOME'} = $gs_catalina_home if defined $gs_catalina_home;
+    
+    # Starting up the Fedora server takes a long time. We need to wait for the server to be
+    # ready before import can continue, because g2f-import relies on an up-and-running Fedora
+    # server to purge the collection from it while g2f-build.pl needs a ready Fedora server 
+    # in order to make it ingest the FedoraMETS. Sleeping is not sufficient (#sleep 10;) since
+    # the subsequent steps depend on a proper server restart.
+    # Dr Bainbridge's suggestion: test the server is ready with a call to wget.
+    
+    # Wget tries to retrieve the fedora search page (protocol://host:port/fedora/search)
+    # 20 times, waiting 3 seconds between each failed attempt. If it ultimately fails, we
+    # print a message to the user.
+    # The wget --spider option makes it check that the page is merely there rather than 
+    # downloading it (see http://www.gnu.org/software/wget/manual/wget.html#Download-Options)
+    # -q is for quiet, --tries for the number of retries, --waitretry is the number of seconds
+    # between each attempt. Usually wget returns the contents of the page, but in our case it
+    # will return 0 for success since we are not downloading.
+
+    print STDERR "Fedora server restarted. Waiting for it to become ready...\n";
+    #print STDERR "****$protocol://$hostname:$port/fedora/search\n";
+    
+    $! = 0;
+    my $fedoraServerReady = system("wget -q --spider --waitretry=3 --tries=20 $protocol://$hostname:$port/fedora/search"); 
+    if($fedoraServerReady != 0) {
+	print STDERR "Fedora server is still not ready... ERROR: $!\n";
+	print "Exit status = ", $fedoraServerReady/256, "\n";
+	die "Exiting....\n";
+    }
+
+    # return some indication that things went well
+    return "gsdl.xml";
+}
+
+
+1;
Index: /gsdl/stable/perllib/gflock.pm
===================================================================
--- /gsdl/stable/perllib/gflock.pm	(revision 20131)
+++ /gsdl/stable/perllib/gflock.pm	(revision 20131)
@@ -0,0 +1,55 @@
+###########################################################################
+#
+# gflock.pm - an attempt to use flock only on those platforms
+# on which it's supported (i.e. everything but Windows 95/98)
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package gflock;
+
+use Fcntl ':flock';
+use strict;
+
+# returns true if successful (or if OS is a form of windows other than NT)
+sub lock {
+    my ($handle) = @_;
+
+    if ($ENV{'GSDLOS'} eq "windows" && !Win32::IsWinNT()) {
+	return 1;
+    } else {
+	return flock($handle, LOCK_EX);
+    }
+}
+
+# returns true if successful (or if OS is a form of windows other than NT)
+sub unlock {
+    my ($handle) = @_;
+
+    if ($ENV{'GSDLOS'} eq "windows" && !Win32::IsWinNT()) {
+	return 1;
+    } else {
+	return flock($handle, LOCK_UN);
+    }
+}
+
+1;
Index: /gsdl/stable/perllib/ghtml.pm
===================================================================
--- /gsdl/stable/perllib/ghtml.pm	(revision 20131)
+++ /gsdl/stable/perllib/ghtml.pm	(revision 20131)
@@ -0,0 +1,311 @@
+###########################################################################
+#
+# ghtml.pm -- this used to be called html.pm but it clashed
+# with the existing html module under windows
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package ghtml;
+
+use strict;
+use unicode;
+
+# htmlsafe(TEXT)
+# 
+# Converts SGML meta characters in TEXT to entity references.
+# 
+sub htmlsafe
+{
+    $_[0] =~ s/&/&amp;/osg;
+    $_[0] =~ s/</&lt;/osg;
+    $_[0] =~ s/>/&gt;/osg;
+    $_[0] =~ s/\"/&quot;/osg;
+}
+
+# unescape_html(TEXT)
+# 
+# Converts HTML entities into their original form.
+# 
+sub unescape_html
+{
+    my ($html) = @_;
+
+    $html =~ s/&amp;/&/osg;
+    $html =~ s/&lt;/</osg;
+    $html =~ s/&gt;/>/osg;
+    $html =~ s/&quot;/\"/osg;
+
+    return $html;
+}
+
+# urlsafe(TEXT)
+# 
+# Converts characters not allowed in a URL to their hex representation.
+# 
+sub urlsafe
+{
+    $_[0] =~ s/[\x09\x20\x22\x3c\x3e\x5b\x5c\x5d\x5e\x60\x7b\x7c\x7d\x7e\?\=\&\+_\/]/sprintf("%%%2x", ord($&))/gse;
+}
+
+# dmsafe
+#
+# Converts characters which could make display.pl or html crack to their entity references.
+# Don't use this on dm macros as they will no longer be recognisable by dm (which
+# by the way, is the whole idea).
+# -- Rodger 12/1/98
+sub dmsafe {
+    my ($s) = $_[0];
+    $s =~ s/&/&amp;/osg; # for html
+    $s =~ s/</&lt;/osg;  # for html
+    $s =~ s/>/&gt;/osg;  # for html
+    $s =~ s/\_/&#095;/osg; # for dm (we have a convention of starting macros with _
+    $s =~ s/\"/&quot;/osg; # for html (don't want to be interpreted as a quote)
+    $s =~ s/\{/&#123;/osg; # for dm blocks
+    $s =~ s/\}/&#125;/osg; # for dm blocks
+    $s =~ s/\\/&#092;/osg; # for dm (dm removes naturally occurring backquotes)
+    return $s;
+}
+
+
+# named entry to the standard html font
+my %charnetosf = ("Agrave"=> "192",  "Aacute"=> "193",  "Acirc" => "194",  "Atilde"=> "195",
+	       "Auml"  => "196",  "Aring" => "197",  "AElig" => "198",  "Ccedil"=> "199",
+	       "Egrave"=> "200",  "Eacute"=> "201",  "Ecirc" => "202",  "Euml"  => "203",
+	       "Igrave"=> "204",  "Iacute"=> "205",  "Icirc" => "206",  "Iuml"  => "207",
+	       "ETH"   => "208",  "Ntilde"=> "209",  "Ograve"=> "210",  "Oacute"=> "211",
+	       "Ocirc" => "212",  "Otilde"=> "213",  "Ouml"  => "214",  
+	       "Oslash"=> "216",  "Ugrave"=> "217",  "Uacute"=> "218",  "Ucirc" => "219",
+	       "Uuml"  => "220",  "Yacute"=> "221",  "THORN" => "222",  "szlig" => "223",
+	       "agrave"=> "224",  "aacute"=> "225",  "acirc" => "226",  "atilde"=> "227",
+	       "auml"  => "228",  "aring" => "229",  "aelig" => "230",  "ccedil"=> "231",
+	       "egrave"=> "232",  "eacute"=> "233",  "ecirc" => "234",  "euml"  => "235",
+	       "igrave"=> "236",  "iacute"=> "237",  "icirc" => "238",  "iuml"  => "239",
+	       "eth"   => "240",  "ntilde"=> "241",  "ograve"=> "242",  "oacute"=> "243",
+	       "ocirc" => "244",  "otilde"=> "245",  "ouml"  => "246",  
+	       "oslash"=> "248",  "ugrave"=> "249",  "uacute"=> "250",  "ucirc" => "251",
+	       "uuml"  => "252",  "yacute"=> "253",  "thorn" => "254",  "yuml"  => "255");
+
+my %symnetosf = ("quot"  => "34",   "amp"   => "38",   "lt"    => "60",   "gt"    => "62",
+	      "nbsp"  => "160",  "iexcl" => "161",  "cent"  => "162",  "pound" => "163",
+	      "curren"=> "164",  "yen"   => "165",  "brvbar"=> "166",  "sect"  => "167",
+	      "uml"   => "168",  "copy"  => "169",  "ordf"  => "170",  "laquo" => "171",
+	      "not"   => "172",  "shy"   => "173",  "reg"   => "174",  "macr"  => "175",
+	      "deg"   => "176",  "plusmn"=> "177",  "sup2"  => "178",  "sup3"  => "179",
+	      "acute" => "180",  "micro" => "181",  "para"  => "182",  "middot"=> "183",
+	      "cedil" => "184",  "sup1"  => "185",  "ordm"  => "186",  "raquo" => "187",
+	      "frac14"=> "188",  "frac12"=> "189",  "frac34"=> "190",  "iquest"=> "191",
+	      "times" => "215",  "divide"=> "247");
+
+
+
+# standard font to plain text
+my %sftotxt = ("32"  => " ",  "33"  => "!",  "34"  => "\"",  "35"  => "\#",  "36"  => "\$",
+	    "37"  => "\%", "38"  => "&",  "39"  => "'",   "40"  => "(",   "41"  => ")",
+	    "42"  => "*",  "43"  => "+",  "44"  => ",",   "45"  => "-",   "46"  => ".",
+	    "47"  => "/",  "48"  => "0",  "49"  => "1",   "50"  => "2",   "51"  => "3",
+	    "52"  => "4",  "53"  => "5",  "54"  => "6",   "55"  => "7",   "56"  => "8",
+	    "57"  => "9",  "58"  => ":",  "59"  => ";",   "60"  => "<",   "61"  => "=",
+	    "62"  => ">",  "63"  => "?",  "64"  => "\@",  "65"  => "A",   "66"  => "B",
+	    "57"  => "9",  "58"  => ":",  "59"  => ";",   "61"  => "=",
+	    "63"  => "?",  "64"  => "\@", "65"  => "A",  "66"  => "B",
+	    "67"  => "C",  "68"  => "D",  "69"  => "E",   "70"  => "F",   "71"  => "G",
+	    "72"  => "H",  "73"  => "I",  "74"  => "J",   "75"  => "K",   "76"  => "L",
+	    "77"  => "M",  "78"  => "N",  "79"  => "O",   "80"  => "P",   "81"  => "Q",
+	    "82"  => "R",  "83"  => "S",  "84"  => "T",   "85"  => "U",   "86"  => "V",
+	    "87"  => "W",  "88"  => "X",  "89"  => "Y",   "90"  => "Z",   "91"  => "[",
+	    "92"  => "\\", "93"  => "]",  "94"  => "^",   "95"  => "_",   "96"  => "`",
+	    "97"  => "a",  "98"  => "b",  "99"  => "c",   "100" => "d",   "101" => "e",
+	    "102" => "f",  "103" => "g",  "104" => "h",   "105" => "i",   "106" => "j",
+	    "107" => "k",  "108" => "l",  "109" => "m",   "110" => "n",   "111" => "o",
+	    "112" => "p",  "113" => "q",  "114" => "r",   "115" => "s",   "116" => "t",
+	    "117" => "u",  "118" => "v",  "119" => "w",   "120" => "x",   "121" => "y",
+	    "122" => "z",  "123" => "{",  "124" => "|",   "125" => "}",   "126" => "~",
+	    "130" => ",",  "131" => "f",  "132" => "\"",   "133" => "...", "139" => "<",
+	    "140" => "OE", "145" => "'",  "146" => "'",   "147" => "\"",   "148" => "\"",
+	    "149" => "o",  "150" => "--", "151" => "-",   "152" => "~",   "153" => "TM",
+	    "155" => ">",  "156" => "oe", "159" => "Y",   "160" => " ",   "178" => "2",
+	    "179" => "3",  "185" => "1",  "188" => "1/4", "189" => "1/2", "190" => "3/4",
+	    "192" => "A",  "193" => "A",  "194" => "A",   "195" => "A",   "196" => "A",
+	    "197" => "A",  "198" => "AE", "199" => "C",   "200" => "E",   "201" => "E",
+	    "202" => "E",  "203" => "E",  "204" => "I",   "205" => "I",   "206" => "I",
+	    "207" => "I",  "208" => "D",  "209" => "N",   "210" => "O",   "211" => "O",
+	    "212" => "O",  "213" => "O",  "214" => "O",   "215" => "*",   "216" => "O",
+	    "217" => "U",  "218" => "U",  "219" => "U",   "220" => "U",   "221" => "Y",
+	    "223" => "ss", "224" => "a",  "225" => "a",   "226" => "a",   "227" => "a",
+	    "228" => "a",  "229" => "a",  "230" => "ae",  "231" => "c",   "232" => "e",
+	    "233" => "e",  "234" => "e",  "235" => "e",   "236" => "i",   "237" => "i",
+	    "238" => "i",  "239" => "i",  "241" => "n",   "242" => "o",   "243" => "o",
+	    "244" => "o",  "245" => "o",  "246" => "o",   "247" => "/",   "248" => "o",
+	    "249" => "u",  "250" => "u",  "251" => "u",   "252" => "u",   "253" => "y",
+	    "255" => "y",  "8218" => ",");
+
+
+my %mime_type = ("ai"=>"application/postscript", "aif"=>"audio/x-aiff", 
+		     "aifc"=>"audio/x-aiff", "aiff"=>"audio/x-aiff", 
+		     "au"=>"audio/basic", "avi"=>"video/x-msvideo",
+		     "bcpio"=>"application/x-bcpio", "bin"=>"application/octet-stream", 
+		     "cdf"=>"application/x-netcdf", "class"=>"application/octet-stream", 
+		     "cpio"=>"application/x-cpio", "cpt"=>"application/mac-compactpro",
+		     "csh"=>"application/x-csh", "dcr"=>"application/x-director", 
+		     "dir"=>"application/x-director", "dms"=>"application/octet-stream", 
+		     "doc"=>"application/msword", "dvi"=>"application/x-dvi",
+		     "dxr"=>"application/x-director", "eps"=>"application/postscript", 
+		     "etx"=>"text/x-setext",
+		     "exe"=>"application/octet-stream", "gif"=>"image/gif",
+		     "gtar"=>"application/x-gtar", "hdf"=>"application/x-hdf",
+		     "hqx"=>"application/mac-binhex40", "htm"=>"text/html",
+		     "html"=>"text/html", "ice"=>"x-conference/x-cooltalk",
+		     "ief"=>"image/ief", "jpe"=>"image/jpeg",
+		     "jpeg"=>"image/jpeg", "jpg"=>"image/jpeg",
+		     "kar"=>"audio/midi", "latex"=>"application/x-latex",
+		     "lha"=>"application/octet-stream", "lzh"=>"application/octet-stream",
+		     "man"=>"application/x-troff-man", "mcf"=>"image/vasa",
+		     "me"=>"application/x-troff-me", "mid"=>"audio/midi",
+		     "midi"=>"audio/midi", "mif"=>"application/x-mif",
+		     "mov"=>"video/quicktime", "movie"=>"video/x-sgi-movie",
+		     "mp2"=>"audio/mpeg", "mpe"=>"video/mpeg",
+		     "mpeg"=>"video/mpeg", "mpg"=>"video/mpeg",
+		     "mpga"=>"audio/mpeg", "ms"=>"application/x-troff-ms",
+		     "nc"=>"application/x-netcdf", "oda"=>"application/oda",
+		     "pbm"=>"image/x-portable-bitmap", "pdb"=>"chemical/x-pdb",
+		     "pdf"=>"application/pdf", "pgm"=>"image/x-portable-graymap",
+		     "png"=>"image/png", "pnm"=>"image/x-portable-anymap",
+		     "ppm"=>"image/x-portable-pixmap",
+		     "ppt"=>"application/vnd.ms-powerpoint",
+		     "ps"=>"application/postscript", "qt"=>"video/quicktime",
+		     "ra"=>"audio/x-realaudio", "ram"=>"audio/x-pn-realaudio",
+		     "ras"=>"image/x-cmu-raster", "rgb"=>"image/x-rgb",
+		     "roff"=>"application/x-troff", "rpm"=>"audio/x-pn-realaudio-plugin",
+		     "rtf"=>"application/rtf", "rtx"=>"text/richtext",
+		     "sgm"=>"text/x-sgml", "sgml"=>"text/x-sgml",
+		     "sh"=>"application/x-sh", "shar"=>"application/x-shar",
+		     "sit"=>"application/x-stuffit", "skd"=>"application/x-koan",
+		     "skm"=>"application/x-koan", "skp"=>"application/x-koan",
+		     "skt"=>"application/x-koan", "snd"=>"audio/basic",
+		     "src"=>"application/x-wais-source", "sv4cpio"=>"application/x-sv4cpio",
+		     "sv4crc"=>"application/x-sv4crc", "t"=>"application/x-troff",
+		     "tar"=>"application/x-tar", "tcl"=>"application/x-tcl",
+		     "tex"=>"application/x-tex", "texi"=>"application/x-texinfo",
+		     "texinfo"=>"application/x-texinfo", "tif"=>"image/tiff",
+		     "tiff"=>"image/tiff", "tr"=>"application/x-troff",
+		     "tsv"=>"text/tab-separated-values", "txt"=>"text/plain",
+		     "ustar"=>"application/x-ustar", "vcd"=>"application/x-cdlink",
+		     "vrml"=>"x-world/x-vrml", "wav"=>"audio/x-wav",
+		     "wrl"=>"x-world/x-vrml", "xbm"=>"image/x-xbitmap",
+		     "xls"=>"application/vnd.ms-excel",
+		     "xpm"=>"image/x-xpixmap", "xwd"=>"image/x-xwindowdump",
+		     "xyz"=>"chemical/x-pdb", "zip"=>"application/zip");
+
+
+# returns the character as a raw utf-8 character. It assumes that the
+# & and ; have been stripped off the string.
+sub getcharequiv {
+    my ($entity, $convertsymbols) = @_;
+
+    # a numeric entity
+    if ($entity =~ /^\#0*(\d+)/) {
+	my $code=$1;
+	# non-standard Microsoft breakage, as usual
+	if ($code < 0x9f) { # code page 1252 uses reserved bytes
+	    if ($code == 0x91) {$code=0x2018} # 145 = single left quote
+	    elsif ($code == 0x92) {$code=0x2019} # 146 = single right quote
+	    elsif ($code == 0x93) {$code=0x201c} # 147 = double left quote
+	    elsif ($code == 0x94) {$code=0x201d} # 148 = double right quote
+	    # ...
+	}
+	return &unicode::unicode2utf8([$code]);
+    }
+    
+    # a named character entity
+    if (defined $charnetosf{$entity}) {
+	return &unicode::unicode2utf8([$charnetosf{$entity}]);
+    }
+
+    # a named symbol entity
+    if ($convertsymbols && defined $symnetosf{$entity}) {
+	return &unicode::unicode2utf8([$symnetosf{$entity}]);
+    }
+
+    return "&$entity;"; # unknown character
+}
+
+# convert character entities from named equivalents to html font
+sub convertcharentities {
+    # args: the text that you want to convert
+
+    $_[0] =~ s/&([^;]+);/&getcharequiv($1,0)/gse;
+}
+
+# convert any entities from named equivalents to html font
+sub convertallentities {
+    # args: the text that you want to convert
+
+    $_[0] =~ s/&([^;]+);/&getcharequiv($1,1)/gse;
+}
+
+sub html2txt {
+    # args: the text that you want converted to ascii, 
+    # and whether to strip out sgml tags
+
+    # strip out sgml tags if needed
+    $_[0] =~ s/<[^>]*>//g if $_[1];
+
+    # convert the char entities to the standard html font
+    &convertcharentities($_[0]); 
+    
+    # convert the html character set to a plain ascii character set
+    my $pos = 0;
+    while ($pos < length($_[0])) {
+	my $charnum = ord(substr($_[0], $pos, 1));
+	if ($charnum >= 32) { # only convert characters above #32
+	    my $replacechars = " ";
+	    $replacechars = $sftotxt{$charnum} if defined $sftotxt{$charnum};
+	    substr($_[0], $pos, 1) = $replacechars;
+	    $pos += length ($replacechars);
+
+	} else {
+	    $pos ++;
+	}
+    }
+}  
+
+
+# look for mime.types (eg in /etc, or apache/conf directories), or have a look
+# at <ftp://ftp.iana.org/in-notes/iana/assignments/media-types/> for defaults.
+sub guess_mime_type {
+    my ($filename) = @_;
+    # make the filename lowercase, since the mimetypes hashmap looks for lowercase
+    $filename = lc($filename);
+
+    my ($fileext) = $filename =~ /\.(\w+)$/;
+    return "unknown" unless defined $fileext;
+
+    # else
+    my $mimetype =  $mime_type{$fileext};
+    return $mimetype if (defined $mimetype);
+
+    return "unknown";
+}
+
+
+1;
Index: /gsdl/stable/perllib/giget.pm
===================================================================
--- /gsdl/stable/perllib/giget.pm	(revision 20131)
+++ /gsdl/stable/perllib/giget.pm	(revision 20131)
@@ -0,0 +1,265 @@
+use strict;
+
+
+sub readin_html 
+{
+    my ($html_fname) = @_;
+
+    open(HIN,"<$html_fname") 
+	|| die "Unable to open $html_fname: $!\n";
+    
+    my $html_text;
+    my $line;
+    while (defined ($line=<HIN>)) {
+	$html_text .= $line;
+    }
+    close(HIN);
+
+    return $html_text;
+}
+
+sub stripout_anchortags
+{
+    my ($html_text) = @_;
+
+    my @anchor_tags = ($html_text =~ m/(<a\s+.*?>)+/gs);
+
+    return @anchor_tags;
+} 
+
+
+sub print_tags
+{
+    my (@tags) = @_;
+
+    my $a;
+    foreach $a ( @tags) {
+	print "$a\n";
+    }
+}
+
+sub filter_tags
+{
+    my ($filter_text,@tags) = @_;
+
+    my @filtered_tags = ();
+
+    my $t;
+    foreach $t (@tags) {
+	if ($t =~ m/$filter_text/x) {
+	    push(@filtered_tags,$t);
+	}
+    }
+
+    return @filtered_tags;
+}
+
+sub extract_urls {
+    my (@tags) = @_;
+
+    my @urls = ();
+
+    my $t;
+    foreach $t (@tags) {
+	if ($t =~ m/href=([^ ]+)/i) {
+	    my $url = $1;
+	    $url =~ s/&amp;/&/g;
+	    push(@urls,$url);
+	}
+    }
+
+    return @urls;
+}
+
+sub get_gi_page
+{
+    my ($cgi_base,$cgi_call,$downloadto_fname) = @_;
+
+    my $full_url = "$cgi_base$cgi_call";
+    
+    if ((!-e $downloadto_fname) || (-z $downloadto_fname)) {
+	my $cmd = "wget -nv -T 10 -nc -U \"Mozilla\" -O \"$downloadto_fname\" \"$full_url\"";
+##	print STDERR "*** wget cmd:\n $cmd\n";
+
+    `$cmd`;
+    }
+
+    if (-z $downloadto_fname) { 
+	print STDERR "Warning: downloaded file 0 bytes!\n";
+    }
+}
+
+
+sub parse_gi_search_page 
+{
+    my ($ga_base,$search_term_dir,$downloaded_fname,$currpage_url) = @_;
+
+    my $nextpage_url = undef;
+
+    my @imgref_urls = ();
+
+    my $downloaded_text = readin_html($downloaded_fname);
+    if (defined $downloaded_text) {
+	my @anchor_tags = stripout_anchortags($downloaded_text);
+	
+	my @thumbimg_tags = filter_tags("imgres\\?",@anchor_tags);
+	my @nextpage_tags = filter_tags("images\\?.*?start=\\d+",@anchor_tags);
+	
+	my @thumbimg_urls = extract_urls(@thumbimg_tags);
+	my @nextpage_urls = extract_urls(@nextpage_tags);
+
+	my $curr_start = 0;
+	if ($currpage_url =~ m/start=(\d+)/) {
+	    $curr_start = $1;
+	}
+
+	my $pot_url;
+	foreach $pot_url (@nextpage_urls) {
+	
+	    my ($next_start) = ($pot_url =~ m/start=(\d+)/);
+	    if ($next_start>$curr_start) {
+		$nextpage_url = $pot_url;
+		last;
+	    }
+	}
+
+#	print "-" x 40, "\n";
+	my $c = 1;
+	my $p = 1;
+
+	foreach my $tvu (@thumbimg_urls) {
+	    my ($img_url) = ($tvu =~ m/imgurl=([^&]*)/);
+	    $img_url =~ s/%25/%/g;
+
+	    my ($imgref_url) = ($tvu =~ m/imgrefurl=([^&]*)/);
+##	    print STDERR "****imgref_url = $imgref_url\n";
+	    $imgref_url =~ s/%25/%/g;
+	    
+	    my ($img_ext) = ($img_url =~ m/\.(\w+)$/);
+	    $img_ext = lc($img_ext);
+
+	    # remove http:// if there, so later we can explicitly add it in
+	    $img_url =~ s/^http:\/\///; 
+
+	    print "Downloading image url http://$img_url\n";
+	    my $output_fname = "$search_term_dir/img_$c.$img_ext";
+
+	    get_gi_page("http://",$img_url,$output_fname);
+
+	    if (-s $output_fname == 0) {
+		unlink $output_fname;
+	    }
+	    elsif (system("identify \"$output_fname\"") > 0 ) {
+		print STDERR "**** NOT JPEG: output_fname \n";
+		unlink $output_fname;
+	    }
+	    else {
+
+		my $command = "identify \"$output_fname\" 2>&1";
+		my $result = `$command`;
+
+		my $type =   'unknown';
+		my $width =  'unknown';
+		my $height = 'unknown';
+		
+		my $image_safe = quotemeta $output_fname;
+		if ($result =~ /^$image_safe (\w+) (\d+)x(\d+)/) {
+		    $type = $1;
+		    $width = $2;
+		    $height = $3;
+		}
+
+		if (($width ne "unknown") && ($height ne "unknown")) {
+		    if (($width>200) || ($height>200)) {
+			`convert \"$output_fname\" -resize 200x200 /tmp/x.jpg`;
+			`/bin/mv /tmp/x.jpg \"$output_fname\"`;
+		    }
+		}
+		$c++;
+	    }
+
+	    push(@imgref_urls,$imgref_url);
+
+	    last if ($c==3); # Only take first 2
+
+	    $p++;
+
+	    if ($p==20) {
+		print STDERR "*** Unable to get enough images after 20 passes\n";
+		last;
+	    }
+
+
+	}
+
+	if (defined $nextpage_url) {
+	    print "Next page URL:\n";
+	    print_tags($nextpage_url);
+	}
+#	print "-" x 40, "\n";
+    }
+
+    return ($nextpage_url, \@imgref_urls);
+}
+
+sub make_search_term_safe
+{
+    my ($search_terms) = @_;
+
+    my $search_term_safe = join("+",@$search_terms);
+    $search_term_safe =~ s/\"/%22/g;
+    $search_term_safe =~ s/ /+/g;
+
+    return $search_term_safe;
+}
+
+sub gi_query_url
+{
+    my ($search_term) = @_;
+
+    my $search_term_safe = make_search_term_safe($search_term);
+
+    my $nextpage_url 
+	= "/images?as_filetype=jpg&imgc=color\&ie=UTF-8\&oe=UTF-8\&hl=en\&btnG=Google+Search";
+    $nextpage_url .= "\&q=$search_term_safe";
+
+    return $nextpage_url;
+}
+
+sub gi_url_base
+{
+    return "http://images.google.com";
+}
+
+sub giget
+{
+    my ($search_terms,$output_dir) = @_;
+    my $imgref_urls = [];
+
+    if (!-e $output_dir) {
+	mkdir($output_dir);
+    
+    }
+	
+    print STDERR "Searching Google Images for: ", join(", ",@$search_terms), "\n";
+
+    my $gi_base = gi_url_base();
+    my $nextpage_url = gi_query_url($search_terms);
+    
+    my $respage_fname = "$output_dir/respage1.html";
+    get_gi_page($gi_base,$nextpage_url,$respage_fname);
+    
+    ($nextpage_url, $imgref_urls) 
+	= parse_gi_search_page($gi_base,$output_dir,
+			       $respage_fname,$nextpage_url);
+#    else {
+#	print STDERR "  Images already mirrored\n";
+#    }
+
+    print STDERR "-" x 40, "\n";
+
+    return $imgref_urls;
+}
+
+
+1;
Index: /gsdl/stable/perllib/gsprintf.pm
===================================================================
--- /gsdl/stable/perllib/gsprintf.pm	(revision 20131)
+++ /gsdl/stable/perllib/gsprintf.pm	(revision 20131)
@@ -0,0 +1,297 @@
+###########################################################################
+#
+# gsprintf.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+use strict;
+no strict 'refs';
+
+package gsprintf;
+require Exporter;
+@gsprintf::ISA=qw(Exporter);
+
+use unicode;
+use util;
+
+@gsprintf::EXPORT_OK = qw(gsprintf); # functions we can export into namespace
+
+
+# Language-specific resource bundle
+my %specialresourcebundle = ();
+our $specialoutputencoding; # our, so that it can be changed outside.
+
+# Default resource bundle
+my %defaultresourcebundle;
+my $defaultoutputencoding;
+
+# English resource bundle
+my %englishresourcebundle;
+my $englishoutputencoding;
+
+# Ignore the OutputEncoding strings in the resource bundles and output all text in UTF-8
+my $outputstringsinUTF8 = 0;
+
+
+sub gsprintf
+{
+    my ($handle, $text_string, @text_arguments) = @_;
+
+    # Return unless the required arguments were supplied
+    return unless (defined($handle) && defined($text_string));
+    
+    # Look up all the strings in the dictionary
+    $text_string =~ s/(\{[^\}]+\})/&lookup_string($1)/eg;
+
+    # Resolve the string arguments using sprintf, then write out to the handle
+    print $handle sprintf($text_string, @text_arguments);
+}
+
+
+sub lookup_string
+{
+    my ($stringkey) = @_;
+    return "" unless defined $stringkey;
+    # Try the language-specific resource bundle first
+    my $utf8string = $specialresourcebundle{$stringkey};
+    my $outputencoding = $specialoutputencoding;
+
+    # Try the default resource bundle next
+    if (!defined($utf8string)) {
+	# Load the default resource bundle if it is not already loaded
+	&load_default_resource_bundle() if (!%defaultresourcebundle);
+	
+	$utf8string = $defaultresourcebundle{$stringkey};
+	$outputencoding = $defaultoutputencoding;
+    }
+    
+    # Try the English resource bundle last
+    if (!defined($utf8string)) {
+	# Load the English resource bundle if it is not already loaded
+	&load_english_resource_bundle() if (!%englishresourcebundle);
+	
+	$utf8string = $englishresourcebundle{$stringkey};
+	$outputencoding = $englishoutputencoding;
+    }
+    
+    # No matching string was found, so just return the key
+    if (!defined($utf8string)) {
+	return $stringkey;
+    }
+    
+    # Return the string matching the key
+    return $utf8string if (!defined($outputencoding) || $outputstringsinUTF8
+			   || $outputencoding eq "utf8");
+    
+    # If an 8-bit output encoding has been defined, encode the string appropriately
+    my $encoded=unicode::unicode2singlebyte(&unicode::utf82unicode($utf8string), $outputencoding);
+    
+    # If we successfully encoded it, return it
+    if ($encoded) { return $encoded }
+    
+    # Otherwise, we can't convert to the requested encoding. return the utf8?
+    $specialoutputencoding='utf8';
+    return $utf8string;
+}
+
+
+sub load_language_specific_resource_bundle
+{
+    my $language = shift(@_);
+    
+    # Read the specified resource bundle
+    my $resourcebundlename = "strings_" . $language . ".properties";
+    
+    %specialresourcebundle 
+	= &read_resource_bundle_and_extensions($ENV{'GSDLHOME'},"perllib",$resourcebundlename);
+    return if (!%specialresourcebundle);
+    
+    # Read the output encoding to use from the resource bundle
+    if ($ENV{'GSDLOS'} =~ /windows/) {
+	$specialoutputencoding = $specialresourcebundle{"{OutputEncoding.windows}"};
+    }
+    else {
+	# see if there is an encoding set in the appropriate locale env var
+	
+	foreach my $envvar ('LC_ALL', 'LANG') {
+	    if (!exists $ENV{$envvar}) { next }
+	    my $locale=$ENV{$envvar};
+	    if ($locale !~ /^\w+\.(.+)$/) { next }
+	    my $enc=lc($1);
+	    $enc =~ s/-/_/g;
+	    if ($enc eq 'utf_8') { $enc='utf8' } # normalise to this name
+	    $specialoutputencoding = $enc;
+	    return;
+	}
+	$specialoutputencoding = $specialresourcebundle{"{OutputEncoding.unix}"};
+    }
+}
+
+
+sub load_default_resource_bundle
+{
+    # Read the default resource bundle
+    my $resourcebundlename = "strings.properties";
+
+    %defaultresourcebundle 
+	= &read_resource_bundle_and_extensions($ENV{'GSDLHOME'},"perllib",$resourcebundlename);
+    if (!%defaultresourcebundle) {
+        # $! will still have the error value for the last failed syscall
+        print STDERR "$! $resourcebundlename\n";
+	# set something so we don't bother trying to load it again
+	$defaultresourcebundle{0}=undef; 
+        return;
+    }
+    
+    # Read the output encoding to use from the resource bundle
+    if ($ENV{'GSDLOS'} =~ /windows/) {
+	$defaultoutputencoding = $defaultresourcebundle{"{OutputEncoding.windows}"};
+    }
+    else {
+	$defaultoutputencoding = $defaultresourcebundle{"{OutputEncoding.unix}"};
+    }
+}
+
+
+sub load_english_resource_bundle
+{
+    # Ensure the English resource bundle hasn't already been loaded
+    if (%specialresourcebundle && $specialresourcebundle{"{Language.code}"} eq "en") {
+	%englishresourcebundle = %specialresourcebundle;
+	$englishoutputencoding = $specialoutputencoding;
+    }
+    
+    if ($defaultresourcebundle{"{Language.code}"} &&
+        $defaultresourcebundle{"{Language.code}"} eq "en") {
+	%englishresourcebundle = %defaultresourcebundle;
+	$englishoutputencoding = $defaultoutputencoding;
+    }
+    
+    # Read the English resource bundle
+    my $resourcebundlename = "strings_en.properties";
+
+    %englishresourcebundle 
+	= &read_resource_bundle_and_extensions($ENV{'GSDLHOME'},"perllib",$resourcebundlename);
+    return if (!%englishresourcebundle);
+    
+    # Read the output encoding to use from the resource bundle
+    if ($ENV{'GSDLOS'} =~ /windows/) {
+	$englishoutputencoding = $englishresourcebundle{"{OutputEncoding.windows}"};
+    }
+    else {
+	$englishoutputencoding = $englishresourcebundle{"{OutputEncoding.unix}"};
+    }
+}
+
+
+sub read_resource_bundle_and_extensions
+{
+    my ($bundle_base,$primary_dir,$resourcename) = @_;
+
+    my $primary_resourcebundlefile 
+	= &util::filename_cat($bundle_base,$primary_dir,$resourcename);
+
+    my $resourcebundle = read_resource_bundle($primary_resourcebundlefile);
+    return if (!defined $resourcebundle);
+
+    if (defined $ENV{'GSDLEXTS'}) {
+	my @extensions = split(/:/,$ENV{'GSDLEXTS'});
+	foreach my $e (@extensions) {	
+	    my $ext_base
+		= &util::filename_cat($bundle_base,"ext",$e);
+	    
+	    my $ext_resourcebundlefile 
+		= &util::filename_cat($ext_base,$primary_dir,$resourcename);
+	    
+	    # can ignore return value (will be same reference to $resourcebundle)
+	    read_resource_bundle($ext_resourcebundlefile,$resourcebundle);
+	}
+    }
+    
+    return %$resourcebundle;
+}
+
+
+sub read_resource_bundle
+{
+    my ($resourcebundlefilepath,$resourcebundle) = @_;
+
+    if (!open(RESOURCE_BUNDLE, "<$resourcebundlefilepath")) {
+	# When called for the first time (primary resource), $resourcebundle
+	# is not defined (=undef). If the file does not exist, then we return
+	# this 'undef' to signal it was not found
+	# For an extension resource bundle, if it does not exist this
+	# is not so serious (in fact quite likely) => return what we 
+	# have built up so far
+	
+	return $resourcebundle;
+    }
+
+    if (!defined $resourcebundle) {	
+	# resource files exists, so exect some content to be stored
+	$resourcebundle = {};
+    }
+    
+    # Load this resource bundle
+    my @resourcebundlelines = <RESOURCE_BUNDLE>;
+    close(RESOURCE_BUNDLE);
+
+    # Parse the resource bundle
+
+    foreach my $line (@resourcebundlelines) {
+        # Remove any trailing whitespace
+        $line =~ s/(\s*)$//;
+
+        # Ignore comments and empty lines
+        if ($line !~ /^\#/ && $line ne "") {
+            # Parse key (everything up to the first colon)
+            if ($line =~ m/^([^:]+):(.+)$/) {
+                my $linekey = "{" . $1 . "}";
+                my $linetext = $2;
+                $linetext =~ s/(\s*)\#\s+Updated\s+(\d?\d-\D\D\D-\d\d\d\d).*$//i;
+
+                # Map key to text
+                $resourcebundle->{$linekey} = $linetext;
+            }
+        }
+    }
+
+    return $resourcebundle;
+}
+
+
+sub output_strings_in_UTF8
+{
+    $outputstringsinUTF8 = 1;
+}
+
+
+sub debug_unicode_string
+{
+    join("",
+     map { $_ > 255 ?                      # if wide character...
+           sprintf("\\x{%04X}", $_) :  # \x{...}
+           chr($_)          
+           } unpack("U*", $_[0]));         # unpack Unicode characters
+}
+
+
+1;
Index: /gsdl/stable/perllib/inexport.pm
===================================================================
--- /gsdl/stable/perllib/inexport.pm	(revision 20131)
+++ /gsdl/stable/perllib/inexport.pm	(revision 20131)
@@ -0,0 +1,346 @@
+###########################################################################
+#
+# inexport.pm -- useful utilities to support import.pl and export.pl
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package inexport;
+
+use strict;
+
+use File::Basename;
+
+use util;
+use GDBMUtils;
+
+
+sub prime_doc_oid_count
+{
+    my ($archivedir) = @_;
+    my $oid_count_filename = &util::filename_cat ($archivedir, "OIDcount");
+
+    if (-e $oid_count_filename) {
+	if (open(OIDIN,"<$oid_count_filename")) {
+	    my $OIDcount = <OIDIN>;
+	    chomp $OIDcount;	    
+	    close(OIDIN);
+
+	    $doc::OIDcount = $OIDcount;	    
+	}
+	else {
+	    
+	    print STDERR "Warning: unable to read document OID count from $oid_count_filename\n";
+	    print STDERR "Setting value to 0\n";
+	}
+    }
+    
+}
+
+sub store_doc_oid_count
+{
+    # Use the file "OIDcount" in the archives directory to record
+    # what value doc.pm got up to
+
+    my ($archivedir) = @_;
+    my $oid_count_filename = &util::filename_cat ($archivedir, "OIDcount");
+
+
+    if (open(OIDOUT,">$oid_count_filename")) {
+	print OIDOUT $doc::OIDcount, "\n";
+	    
+	close(OIDOUT);
+    }
+    else {
+	print STDERR "Warning: unable to store document OID count\n";
+    }
+}
+
+
+
+sub new_vs_old_import_diff
+{
+    my ($archive_info,$block_hash,$importdir) = @_;
+
+    # First convert all files to absolute form
+    # This is to support the situation where the import folder is not
+    # the default
+    
+    my $prev_all_files = $archive_info->{'prev_import_filelist'};
+    my $full_prev_all_files = {};
+
+    foreach my $prev_file (keys %$prev_all_files) {
+
+	if (!&util::filename_is_absolute($prev_file)) {
+	    my $full_prev_file = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},$prev_file);
+	    $full_prev_all_files->{$full_prev_file} = $prev_file;
+	}
+	else {
+	    $full_prev_all_files->{$prev_file} = $prev_file;
+	}
+    }
+
+
+    # Figure out which are the new files, existing files and so
+    # by implication the files from the previous import that are not
+    # there any more => mark them for deletion
+    foreach my $curr_file (keys %{$block_hash->{'all_files'}}) {
+	
+	my $full_curr_file = $curr_file;
+
+	# entry in 'all_files' is moved to either 'existing_files', 
+	# 'deleted_files', or 'new_files'
+
+	if (!&util::filename_is_absolute($curr_file)) {
+	    # add in import dir to make absolute
+	    $full_curr_file = &util::filename_cat($importdir,$curr_file);
+	}
+
+	if (defined $block_hash->{'file_blocks'}->{$full_curr_file}) {
+	    # If in block list, we want to ignore it
+	    delete $block_hash->{'all_files'}->{$curr_file};
+
+	    if (defined $full_prev_all_files->{$full_curr_file}) {
+		# also make sure it is gone from 'previous' list so
+		# not mistaken for a file that needs to be deleted
+		delete $full_prev_all_files->{$full_curr_file};
+	    }
+	    next;
+	}
+
+	# figure out if new file or not
+	if (defined $full_prev_all_files->{$full_curr_file}) {
+	    
+	    # had it before
+	    $block_hash->{'existing_files'}->{$full_curr_file} = 1;
+
+	    # Now remove it, so by end of loop only the files
+	    # that need deleting are left
+
+	    delete $full_prev_all_files->{$full_curr_file};
+    	}
+	else {
+	    $block_hash->{'new_files'}->{$full_curr_file} = 1;
+	}
+	
+	delete $block_hash->{'all_files'}->{$curr_file};
+    }
+
+    # By this point full_prev_all_files contains the files
+    # mentioned in archiveinf-src.db but are not in the 'import'
+    # folder (or whatever was specified through -importdir ...)
+
+    # This list can contain files that were created in the 'tmp' or
+    # 'cache' areas (such as screen-size and thumbnail images).
+    #
+    # In building the final list of files to delete, we test to see if
+    # it exists on the filesystem and if it does (unusual for a file
+    # that's allegedly deleted!), supress it from going into the final
+    # list
+
+    my $collectdir = $ENV{'GSDLCOLLECTDIR'};
+
+    my @deleted_files = values %$full_prev_all_files;
+    map { my $curr_file = $_;
+	  my $full_curr_file = $curr_file;
+
+	  if (!&util::filename_is_absolute($curr_file)) {
+	      # add in import dir to make absolute
+
+	      $full_curr_file = &util::filename_cat($collectdir,$curr_file);
+	  }
+
+
+	  if (!-e $full_curr_file) {
+	      $block_hash->{'deleted_files'}->{$curr_file} = 1;
+	  }
+      } @deleted_files;
+}
+
+
+sub is_assoc_file
+{
+    my ($file,$doc_rec) = @_;
+
+    my ($file_root,$dirname,$suffix) = fileparse($file, "\\.[^\\.]+\$");
+
+    foreach my $af (@{$doc_rec->{'assoc-file'}}) {
+	my $full_af = &util::filename_cat($dirname,$af);
+
+	return 1 if ($full_af eq $file);
+    }
+
+    return 0;
+}
+
+
+sub _mark_docs_for_deletion
+{
+    my ($archive_info,$block_hash,$deleted_files,$archivedir,$verbosity,$mode_text) = @_;
+
+    my $doc_db = "archiveinf-doc.gdb";
+    my $src_db = "archiveinf-src.gdb";
+    my $arcinfo_doc_filename = &util::filename_cat ($archivedir, $doc_db);
+    my $arcinfo_src_filename = &util::filename_cat ($archivedir, $src_db);
+
+
+    # record files marked for deletion in arcinfo
+    foreach my $file (@$deleted_files) {
+	# use 'archiveinf-src' GDBM file to look up all the OIDs
+	# that this file is used in (note in most cases, it's just one OID)
+	
+	my $src_rec = GDBMUtils::gdbmRecordToHash($arcinfo_src_filename,$file);
+	my $oids = $src_rec->{'oid'};
+	foreach my $oid (@$oids) {
+
+	    # Find out if it's a main doc, assoc file, or metadata
+
+	    my $doc_rec = GDBMUtils::gdbmRecordToHash($arcinfo_doc_filename,$oid);
+
+	    if (is_assoc_file($file,$doc_rec)) {
+		# assoc file => mark it for re-indexing (safest thing to do)
+		my $curr_status = $archive_info->get_status_info($oid);
+
+
+		if (defined($curr_status) && (($curr_status ne "D") && ($curr_status ne "R"))) {
+		    if ($verbosity > 1) {
+			print STDERR "$oid marked for (potential) reindexing\n";
+			print STDERR "  (because associated file $file deleted)\n";
+		    }
+		    $archive_info->set_status_info($oid,"R");
+
+		    my $val = &GDBMUtils::gdbmDatabaseGet($arcinfo_doc_filename,$oid);
+		    $val =~ s/^<index-status>(.*)$/<index-status>R/m;
+		    &GDBMUtils::gdbmDatabaseSet($arcinfo_doc_filename,$oid,$val);
+		}
+		GDBMUtils::gdbmDatabaseRemove($arcinfo_src_filename,$file);
+	    }
+	    else {
+		# either src-file or metadata.xml file linking to src-file
+
+		my $src_file;
+
+		if ($doc_rec->{'src-file'}->[0] ne $file) {
+		    # it's a metadata file attached to this OID
+		    # => workout the src-file it matches to
+
+		    $src_file = $doc_rec->{'src-file'}->[0];
+		    
+		    my $src_filename = $src_file;
+		    if (!&util::filename_is_absolute($src_file)) {
+			$src_filename = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},$src_file);
+		    }
+		    
+		    $block_hash->{'reindex_files'}->{$src_filename} = 1;
+
+		    # remove the metadata file from the src-database
+		    GDBMUtils::gdbmDatabaseRemove($arcinfo_src_filename,$file);
+		}
+		else {
+		    # It's the main doc
+		    # => make it the target and mark it for deletion
+		    $src_file = $file;
+		}
+
+		# Whether the main file directly or indirectly, mark for deletion/reindex
+
+		my $val = &GDBMUtils::gdbmDatabaseGet($arcinfo_doc_filename,$oid);
+		my ($index_status) = ($val =~ m/^<index-status>(.*)$/m);
+
+
+		if ($index_status ne "D") {
+		    if ($verbosity>1) {
+			print STDERR "$oid ($src_file) marked to be $mode_text on next buildcol.pl\n";
+		    }
+		    $archive_info->set_status_info($oid,"D");
+
+		    $val =~ s/^<index-status>(.*)$/<index-status>D/m;
+		    &GDBMUtils::gdbmDatabaseSet($arcinfo_doc_filename,$oid,$val);
+
+		    GDBMUtils::gdbmDatabaseRemove($arcinfo_src_filename,$src_file);
+		}
+
+
+	    }
+
+	}
+    }
+}
+
+
+sub mark_docs_for_deletion
+{
+    _mark_docs_for_deletion(@_,"deleted from index");
+}
+
+
+sub mark_docs_for_reindex
+{
+    my ($archive_info,$block_hash,$archivedir,$verbosity) = @_;
+
+    # Reindexing is accomplished by deleting the previously indexed
+    # version of the document, and then allowing the new version to
+    # be indexed (as would a new document be indexed). 
+    # 
+    # The first step (marking for deletion) is implemented by this routine.
+    # 
+    # By default in Greenstone a new version of an index will hash to
+    # a new unique OID, and the above strategy of reindex=delete+add
+    # works fine.  A special case arises when a persistent OID is 
+    # allocated to a document (for instance through a metadata field),
+    # and the second step to reindexing (see XXXX) detects this and
+    # deals with it appropriately.
+
+    my @existing_files = sort keys %{$block_hash->{'existing_files'}};
+
+    my $doc_db = "archiveinf-doc.gdb";
+    my $arcinfo_doc_filename = &util::filename_cat ($archivedir, $doc_db);
+
+    my $archiveinf_timestamp = -M $arcinfo_doc_filename;
+
+    my $reindex_files = [];
+
+    foreach my $existing_filename (@existing_files) {
+	
+	if (-M $existing_filename < $archiveinf_timestamp) {
+	    # file is newer than last build
+	    
+	    my $existing_file = $existing_filename;
+	    my $collectdir = &util::filename_cat($ENV{'GSDLCOLLECTDIR'});
+
+	    my $collectdir_resafe = &util::filename_to_regex($collectdir);
+	    $existing_file =~ s/^$collectdir_resafe(\\|\/)?//;
+	    
+###	    print STDERR "**** Deleting existing file: $existing_file\n";
+
+	    push(@$reindex_files,$existing_file);
+	    $block_hash->{'reindex_files'}->{$existing_filename} = 1;
+	}
+
+    }
+    
+    _mark_docs_for_deletion($archive_info,$block_hash,$reindex_files,$archivedir,$verbosity, "reindex");
+
+}
+
+
+
+1;
Index: /gsdl/stable/perllib/iso639.pm
===================================================================
--- /gsdl/stable/perllib/iso639.pm	(revision 20131)
+++ /gsdl/stable/perllib/iso639.pm	(revision 20131)
@@ -0,0 +1,345 @@
+# mapping to and from iso 639 two letter language symbols
+
+package iso639;
+
+use strict;
+
+%iso639::fromiso639 = (
+	       'aa' => 'Afar',
+	       'ab' => 'Abkhazian',
+	       'af' => 'Afrikaans',
+	       'am' => 'Amharic',
+	       'ar' => 'Arabic',
+	       'as' => 'Assamese',
+	       'ay' => 'Aymara',
+	       'az' => 'Azerbaijani',
+
+	       'ba' => 'Bashkir',
+	       'be' => 'Byelorussian',
+	       'bg' => 'Bulgarian',
+	       'bh' => 'Bihari',
+	       'bi' => 'Bislama',
+	       'bn' => 'Bengali; Bangla',
+	       'bo' => 'Tibetan',
+	       'br' => 'Breton',
+
+	       'ca' => 'Catalan',
+	       'co' => 'Corsican',
+	       'cs' => 'Czech',
+	       'cy' => 'Welsh',
+
+	       'da' => 'Danish',
+	       'de' => 'German',
+	       'dz' => 'Bhutani',	       
+
+	       'el' => 'Greek',
+	       'en' => 'English',
+	       'eo' => 'Esperanto',
+	       'es' => 'Spanish',
+	       'et' => 'Estonian',
+	       'eu' => 'Basque',
+
+	       'fa' => 'Persian',
+	       'fi' => 'Finnish',
+	       'fj' => 'Fiji',
+	       'fo' => 'Faroese',
+	       'fr' => 'French',
+	       'fy' => 'Frisian',
+
+	       'ga' => 'Irish',
+	       'gd' => 'Scots Gaelic',
+	       'gl' => 'Galician',
+	       'gn' => 'Guarani',
+	       'gu' => 'Gujarati',
+
+	       'ha' => 'Hausa',
+	       'he' => 'Hebrew',
+	       'hi' => 'Hindi',
+	       'hr' => 'Croatian',
+	       'hu' => 'Hungarian',
+	       'hy' => 'Armenian',
+
+	       'ia' => 'Interlingua',
+	       'id' => 'Indonesian',
+	       'ie' => 'Interlingue',
+	       'ik' => 'Inupiak',
+	       'is' => 'Icelandic',
+	       'it' => 'Italian',
+	       'iu' => 'Inuktitut',
+
+	       'ja' => 'Japanese',
+	       'jv' => 'Javanese',
+
+	       'ka' => 'Georgian',
+	       'kk' => 'Kazakh',
+	       'kl' => 'Greenlandic',
+	       'km' => 'Cambodian',
+	       'kn' => 'Kannada',
+	       'ko' => 'Korean',
+	       'ks' => 'Kashmiri',
+	       'ku' => 'Kurdish',
+	       'ky' => 'Kirghiz',
+
+	       'la' => 'Latin',
+	       'ln' => 'Lingala',
+	       'lo' => 'Laothian',
+	       'lt' => 'Lithuanian',
+	       'lv' => 'Latvian, Lettish',
+
+	       'mg' => 'Malagasy',
+	       'mi' => 'Maori',
+	       'mk' => 'Macedonian',
+	       'ml' => 'Malayalam',
+	       'mn' => 'Mongolian',
+	       'mo' => 'Moldavian',
+	       'mr' => 'Marathi',
+	       'ms' => 'Malay',
+	       'mt' => 'Maltese',
+	       'my' => 'Burmese',
+
+	       'na' => 'Nauru',
+	       'ne' => 'Nepali',
+	       'nl' => 'Dutch',
+	       'no' => 'Norwegian',
+
+	       'oc' => 'Occitan',
+	       'om' => '(Afan) Oromo',
+	       'or' => 'Oriya',
+
+	       'pa' => 'Punjabi',
+	       'pl' => 'Polish',
+
+	       'prs'=> 'Dari',
+	       'ps' => 'Pushto',
+
+	       'pt' => 'Portuguese',
+
+	       'qu' => 'Quechua',
+	       'rm' => 'Rhaeto-Romance',
+	       'rn' => 'Kirundi',
+	       'ro' => 'Romanian',
+	       'ru' => 'Russian',
+	       'rw' => 'Kinyarwanda',
+
+	       'sa' => 'Sanskrit',
+	       'sd' => 'Sindhi',
+	       'sg' => 'Sangro',
+	       'sh' => 'Serbo-Croatian',
+	       'si' => 'Sinhalese',
+	       'sk' => 'Slovak',
+	       'sl' => 'Slovenian',
+	       'sm' => 'Samoan',
+	       'sn' => 'Shona',
+	       'so' => 'Somali',
+	       'sq' => 'Albanian',
+	       'sr' => 'Serbian',
+	       'ss' => 'Siswati',
+	       'st' => 'Sesotho',
+	       'su' => 'Sudanese',
+	       'sv' => 'Swedish',
+	       'sw' => 'Swahili',
+
+	       'ta' => 'Tamil',
+	       'te' => 'Telugu',
+	       'tg' => 'Tajik',
+	       'th' => 'Thai',
+	       'ti' => 'Tigrinya',
+	       'tk' => 'Turkmen',
+	       'tl' => 'Tagalog',
+	       'tn' => 'Setswana',
+	       'to' => 'Tonga',
+	       'tr' => 'Turkish',
+	       'ts' => 'Tsonga',
+	       'tt' => 'Tatar',
+	       'tw' => 'Twi',
+
+	       'ug' => 'Uigur',
+	       'uk' => 'Ukrainian',
+	       'ur' => 'Urdu',
+	       'uz' => 'Uzbek',
+
+	       'vi' => 'Vietnamese',
+	       'vo' => 'Volapuk',
+
+	       'wo' => 'Wolof',
+
+	       'xh' => 'Xhosa',
+
+	       'yi' => 'Yiddish',
+	       'yo' => 'Yoruba',
+
+	       'za' => 'Zhuang',
+	       'zh' => 'Chinese',
+	       'zu' => 'Zulu'
+	       );
+
+%iso639::toiso639 = (
+	     'afar' => 'aa',
+	     'abkhazian' => 'ab',
+	     'afrikaans' => 'af',
+	     'amharic' => 'am',
+	     'arabic' => 'ar',
+	     'assamese' => 'as',
+	     'aymara' => 'ay',
+	     'azerbaijani' => 'az',
+
+	     'bashkir' => 'ba',
+	     'byelorussian' => 'be',
+	     'bulgarian' => 'bg',
+	     'bihari' => 'bh',
+	     'bislama' => 'bi',
+	     'bengali' => 'bn',
+	     'bangla' => 'bn',
+	     'tibetan' => 'bo',
+	     'breton' => 'br',
+
+	     'catalan' => 'ca',
+	     'corsican' => 'co',
+	     'czech' => 'cs',
+	     'welsh' => 'cy',
+
+	     'danish' => 'da',
+	     'german' => 'de',
+	     'bhutani' => 'dz',
+
+	     'greek' => 'el',
+	     'english' => 'en',
+	     'esperanto' => 'eo',
+	     'spanish' => 'es',
+	     'estonian' => 'et',
+	     'basque' => 'eu',
+
+	     'persian' => 'fa',
+	     'finnish' => 'fi',
+	     'fiji' => 'fj',
+	     'faroese' => 'fo',
+	     'french' => 'fr',
+	     'frisian' => 'fy',
+
+	     'irish' => 'ga',
+	     'scots_gaelic' => 'gd',
+	     'galician' => 'gl',
+	     'guarani' => 'gn',
+	     'gujarati' => 'gu',
+
+	     'hausa' => 'ha',
+	     'hebrew' => 'he',
+	     'hindi' => 'hi',
+	     'croatian' => 'hr',
+	     'hungarian' => 'hu',
+	     'armenian' => 'hy',
+
+	     'interlingua' => 'ia',
+	     'indonesian' => 'id',
+	     'interlingue' => 'ie',
+	     'inupiak' => 'ik',
+	     'icelandic' => 'is',
+	     'italian' => 'it',
+	     'inuktitut' => 'iu',
+
+	     'japanese' => 'ja',
+	     'javanese' => 'jv',
+
+	     'georgian' => 'ka',
+	     'kazakh' => 'kk',
+	     'greenlandic' => 'kl',
+	     'cambodian' => 'km',
+	     'kannada' => 'kn',
+	     'korean' => 'ko',
+	     'kashmiri' => 'ks',
+	     'kurdish' => 'ku',
+	     'kirghiz' => 'ky',
+
+	     'latin' => 'la',
+	     'lingala' => 'ln',
+	     'laothian' => 'lo',
+	     'lithuanian' => 'lt',
+	     'latvian' => 'lv',
+	     'lettish' => 'lv',
+
+	     'malagasy' => 'mg',
+	     'maori' => 'mi',
+	     'macedonian' => 'mk',
+	     'malayalam' => 'ml',
+	     'mongolian' => 'mn',
+	     'moldavian' => 'mo',
+	     'marathi' => 'mr',
+	     'malay' => 'ms',
+	     'maltese' => 'mt',
+	     'burmese' => 'my',
+
+	     'nauru' => 'na',
+	     'nepali' => 'ne',
+	     'dutch' => 'nl',
+	     'norwegian' => 'no',
+
+	     'occitan' => 'oc',
+	     '(afan)_oromo' => 'om',
+	     'oriya' => 'or',
+
+	     'punjabi' => 'pa',
+	     'polish' => 'pl',
+	     'pashto' => 'ps',
+	     'pushto' => 'ps',
+	     'dari'	  => 'prs',
+	     'portuguese' => 'pt',
+
+	     'quechua' => 'qu',
+
+	     'rhaeto-romance' => 'rm',
+	     'kirundi' => 'rn',
+	     'romanian' => 'ro',
+	     'russian' => 'ru',
+	     'kinyarwanda' => 'rw',
+	     
+	     'sanskrit' => 'sa',
+	     'sindhi' => 'sd',
+	     'sangro' => 'sg',
+	     'serbo-croatian' => 'sh',
+	     'sinhalese' => 'si',
+	     'slovak' => 'sk',
+	     'slovenian' => 'sl',
+	     'samoan' => 'sm',
+	     'shona' => 'sn',
+	     'somali' => 'so',
+	     'albanian' => 'sq',
+	     'serbian' => 'sr',
+	     'siswati' => 'ss',
+	     'sesotho' => 'st',
+	     'sudanese' => 'su',
+	     'swedish' => 'sv',
+	     'swahili' => 'sw',
+
+	     'tamil' => 'ta',
+	     'telugu' => 'te',
+	     'tajik' => 'tg',
+	     'thai' => 'th',
+	     'tigrinya' => 'ti',
+	     'turkmen' => 'tk',
+	     'tagalog' => 'tl',
+	     'setswana' => 'tn',
+	     'tonga' => 'to',
+	     'turkish' => 'tr',
+	     'tsonga' => 'ts',
+	     'tatar' => 'tt',
+	     'twi' => 'tw',
+
+	     'uigur' => 'ug',
+	     'ukrainian' => 'uk',
+	     'urdu' => 'ur',
+	     'uzbek' => 'uz',
+
+	     'vietnamese' => 'vi',
+	     'volapuk' => 'vo',
+
+	     'wolof' => 'wo',
+	     
+	     'xhosa' => 'xh',
+
+	     'yiddish' => 'yi',
+	     'yoruba' => 'yo',
+
+	     'zhuang' => 'za',
+	     'chinese' => 'zh',
+	     'zul' => 'zu',
+	     );
Index: /gsdl/stable/perllib/lucenebuilder.pm
===================================================================
--- /gsdl/stable/perllib/lucenebuilder.pm	(revision 20131)
+++ /gsdl/stable/perllib/lucenebuilder.pm	(revision 20131)
@@ -0,0 +1,457 @@
+###########################################################################
+#
+# lucenebuilder.pm -- perl wrapper for building index with Lucene
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+###########################################################################
+# /*
+#  *  @version 1.0 ?
+#  *  @version 2.0 Incremental building assistance added, including
+#  *               remove_document_from_database which implements the granddad's
+#  *               empty function to call the lucene_passes.pl and full_lucene_passes_exe
+#  *               so there is one place in the code that works out where the
+#  *               perl script is. John Rowe
+#  *
+#  *  @author John Rowe, DL Consulting Ltd.
+#  */
+###########################################################################
+
+package lucenebuilder;
+
+# Use same basic XML structure setup by mgppbuilder/mgppbuildproc
+
+use mgppbuilder;
+use strict; 
+no strict 'refs';
+
+
+sub BEGIN {
+    @lucenebuilder::ISA = ('mgppbuilder');
+}
+
+# /**
+#  *  @author  John Thompson, DL Consulting Ltd.
+#  */
+sub new {
+    my $class = shift(@_);
+    my $self = new mgppbuilder (@_);
+    $self = bless $self, $class;
+
+    $self->{'buildtype'} = "lucene";
+
+    # Do we need to put exe on the end?
+    my $exe = &util::get_os_exe ();
+    my $scriptdir = "$ENV{'GSDLHOME'}/bin/script";
+
+    # So where is lucene_passes.pl anyway?
+    my $lucene_passes_script = &util::filename_cat($scriptdir, "lucene_passes.pl");
+
+    # So tack perl on the beginning to ensure execution
+    $self->{'full_lucene_passes'} = "$lucene_passes_script";
+    if ($exe eq ".exe")
+    {
+	$self->{'full_lucene_passes_exe'} = "perl$exe \"$lucene_passes_script\"";
+    }
+    else
+    {
+	$self->{'full_lucene_passes_exe'} = "perl -S \"$lucene_passes_script\"";
+    }
+
+    return $self;
+}
+# /** new() **/
+
+sub init_for_incremental_build {
+    my $self = shift (@_);
+
+    # we want to read in indexfieldmap and indexfields from existing build.cfg
+    # so that we know what has already been indexed
+    my $buildcfg = $self->read_build_cfg();
+    return unless defined $buildcfg;
+
+    my $field;
+    if (defined $buildcfg->{'indexfields'}) {
+	foreach $field (@{$buildcfg->{'indexfields'}}) {
+	    $self->{'buildproc'}->{'indexfields'}->{$field} = 1;
+	}
+    }
+
+    if (defined $buildcfg->{'indexfieldmap'}) {
+	foreach $field (@{$buildcfg->{'indexfieldmap'}}) {
+	    my ($f, $v) = $field =~ /^(.*)\-\>(.*)$/;
+	    $self->{'buildproc'}->{'indexfieldmap'}->{$f} = $v;
+	}
+    }	    
+    
+}
+
+# lucene has none of these options
+sub generate_index_options {
+    my $self = shift (@_);
+
+    $self->SUPER::generate_index_options();
+    
+    $self->{'casefold'} = 0;
+    $self->{'stem'} = 0;
+    $self->{'accentfold'} = 0; 
+    $self->{'stemindexes'} = 0;
+}    
+
+sub default_buildproc {
+    my $self  = shift (@_);
+
+    return "lucenebuildproc";
+}
+
+# this writes a nice version of the text docs
+sub compress_text
+{
+    my $self = shift (@_);
+    # we don't do anything if we don't want compressed text
+    return if $self->{'no_text'};
+
+    my ($textindex) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    # the text directory
+    my $text_dir = &util::filename_cat($self->{'build_dir'}, "text");
+    my $build_dir = &util::filename_cat($self->{'build_dir'},"");
+    &util::mk_all_dir ($text_dir);
+
+    my $osextra = "";
+    if ($ENV{'GSDLOS'} =~ /^windows$/i)
+    {
+	$text_dir =~ s@/@\\@g;
+    }
+    else
+    {
+	if ($outhandle ne "STDERR")
+	{
+	    # so lucene_passes doesn't print to stderr if we redirect output
+	    $osextra .= " 2>/dev/null";
+	}
+    }
+
+    # get any os specific stuff
+    my $scriptdir = "$ENV{'GSDLHOME'}/bin/script";
+
+    # Find the perl script to call to run lucene
+    my $full_lucene_passes = $self->{'full_lucene_passes'};
+    my $full_lucene_passes_exe = $self->{'full_lucene_passes_exe'};
+
+    my $lucene_passes_sections = "Doc";
+
+    my ($handle);
+
+    if ($self->{'debug'})
+    {
+	$handle = *STDOUT;
+    }
+    else
+    {
+        print STDERR "Full Path:     $full_lucene_passes\n";
+        print STDERR "Executable:    $full_lucene_passes_exe\n";
+        print STDERR "Sections:      $lucene_passes_sections\n";
+        print STDERR "Build Dir:     $build_dir\n";
+        print STDERR "Cmd:           $full_lucene_passes_exe text $lucene_passes_sections \"$build_dir\" \"dummy\"   $osextra\n";
+	if (!-e "$full_lucene_passes" ||
+	    !open($handle, "| $full_lucene_passes_exe text $lucene_passes_sections \"$build_dir\" \"dummy\"   $osextra"))
+	{
+	    print STDERR "<FatalError name='NoRunLucenePasses'/>\n</Stage>\n" if $self->{'gli'};
+	    die "lucenebuilder::build_index - couldn't run $full_lucene_passes_exe\n";
+	}
+    }
+
+    # stored text is always Doc and Sec levels    
+    my $levels = { 'document' => 1, 'section' => 1 };
+    # always do database at section level
+    my $db_level = "section"; 
+
+    # set up the document processr
+    $self->{'buildproc'}->set_output_handle ($handle);
+    $self->{'buildproc'}->set_mode ('text');
+    $self->{'buildproc'}->set_index ($textindex);
+    $self->{'buildproc'}->set_indexing_text (0);
+    #$self->{'buildproc'}->set_indexfieldmap ($self->{'indexfieldmap'});
+    $self->{'buildproc'}->set_levels ($levels);
+    $self->{'buildproc'}->set_db_level ($db_level);
+    $self->{'buildproc'}->reset();
+    &plugin::begin($self->{'pluginfo'}, $self->{'source_dir'},
+		   $self->{'buildproc'}, $self->{'maxdocs'});
+    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'},
+		   "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'}, 0, $self->{'gli'});
+    &plugin::end($self->{'pluginfo'});
+    close ($handle) unless $self->{'debug'};
+    $self->print_stats();
+
+    print STDERR "</Stage>\n" if $self->{'gli'};
+}
+
+sub build_indexes {
+    my $self = shift (@_);
+    my ($indexname) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my $indexes = [];
+    if (defined $indexname && $indexname =~ /\w/) {
+	push @$indexes, $indexname;
+    } else {
+	$indexes = $self->{'collect_cfg'}->{'indexes'};
+    }
+    # have we got para index?
+    foreach my $level (keys %{$self->{'levels'}}) {
+	if ($level =~ /paragraph/) {
+	    print $outhandle "Warning: Paragraph level indexing not supported by Lucene\n";
+	    last;
+	}
+    }
+    # create the mapping between the index descriptions
+    # and their directory names (includes subcolls and langs)
+    $self->{'index_mapping'} = $self->create_index_mapping ($indexes);
+
+    # build each of the indexes
+    foreach my $index (@$indexes) {
+	if ($self->want_built($index)) {
+
+	    my $idx = $self->{'index_mapping'}->{$index};
+	    foreach my $level (keys %{$self->{'levels'}}) {
+		next if $level =~ /paragraph/; # we don't do para indexing
+		my ($pindex) = $level =~ /^(.)/;
+		# should probably check that new name with level
+		# is unique ... but currently (with doc sec and para)
+		# each has unique first letter.
+		$self->{'index_mapping'}->{$index} = $pindex.$idx;
+
+		my $llevel = $mgppbuilder::level_map{$level};
+		print $outhandle "\n*** building index $index at level $llevel in subdirectory " .
+		    "$self->{'index_mapping'}->{$index}\n" if ($self->{'verbosity'} >= 1);
+		print STDERR "<Stage name='Index' source='$index' level=$llevel>\n" if $self->{'gli'};
+
+		$self->build_index($index,$llevel);
+	    }
+	    $self->{'index_mapping'}->{$index} = $idx;
+
+	} else {
+	    print $outhandle "\n*** ignoring index $index\n" if ($self->{'verbosity'} >= 1);
+	}
+    }
+
+    #define the final field lists
+    $self->make_final_field_list();
+}
+
+
+sub build_index {
+    my $self = shift (@_);
+    my ($index,$llevel) = @_;
+    my $outhandle = $self->{'outhandle'};
+    my $build_dir = $self->{'build_dir'};
+
+    # get the full index directory path and make sure it exists
+    my $indexdir = $self->{'index_mapping'}->{$index};
+    &util::mk_all_dir (&util::filename_cat($build_dir, $indexdir));
+
+    # get any os specific stuff
+    my $exedir = "$ENV{'GSDLHOME'}/bin/$ENV{'GSDLOS'}";
+    my $scriptdir = "$ENV{'GSDLHOME'}/bin/script";
+
+    # Find the perl script to call to run lucene
+    my $full_lucene_passes = $self->{'full_lucene_passes'};
+    my $full_lucene_passes_exe = $self->{'full_lucene_passes_exe'};
+
+    # define the section names for lucenepasses
+    # define the section names and possibly the doc name for lucenepasses
+    my $lucene_passes_sections = $llevel;
+
+    my $opt_create_index = ($self->{'keepold'}) ? "" : "-removeold";
+
+    my $osextra = "";
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	$build_dir =~ s@/@\\@g;
+    } else {
+	if ($outhandle ne "STDERR") {
+	    # so lucene_passes doesn't print to stderr if we redirect output
+	    $osextra .= " 2>/dev/null";
+	}
+    }
+
+    # get the index expression if this index belongs
+    # to a subcollection
+    my $indexexparr = [];
+    my $langarr = [];
+
+    # there may be subcollection info, and language info.
+    my ($fields, $subcollection, $language) = split (":", $index);
+    my @subcollections = ();
+    @subcollections = split /,/, $subcollection if (defined $subcollection);
+
+    foreach $subcollection (@subcollections) {
+	if (defined ($self->{'collect_cfg'}->{'subcollection'}->{$subcollection})) {
+	    push (@$indexexparr, $self->{'collect_cfg'}->{'subcollection'}->{$subcollection});
+	}
+    }
+
+    # add expressions for languages if this index belongs to
+    # a language subcollection - only put languages expressions for the
+    # ones we want in the index
+    my @languages = ();
+    my $language_metadata = "Language";
+    if (defined ($self->{'collect_cfg'}->{'language_metadata'})) {
+	$language_metadata = $self->{'collect_cfg'}->{'language_metadata'};
+    }
+    @languages = split /,/, $language if (defined $language);
+    foreach my $language (@languages) {
+	my $not=0;
+	if ($language =~ s/^\!//) {
+	    $not = 1;
+	}
+	if($not) {
+	    push (@$langarr, "!$language");
+	} else {
+	    push (@$langarr, "$language");
+	}
+    }
+
+    # Build index dictionary. Uses verbatim stem method
+    print $outhandle "\n    creating index dictionary (lucene_passes -I1)\n"  if ($self->{'verbosity'} >= 1);
+    print STDERR "<Phase name='CreatingIndexDic'/>\n" if $self->{'gli'};
+    my ($handle);
+
+    if ($self->{'debug'}) {
+	$handle = *STDOUT;
+    } else {
+	print STDERR "Cmd: $full_lucene_passes_exe $opt_create_index index $lucene_passes_sections \"$build_dir\" \"$indexdir\"   $osextra\n";
+	if (!-e "$full_lucene_passes" ||
+	    !open($handle, "| $full_lucene_passes_exe $opt_create_index index $lucene_passes_sections \"$build_dir\" \"$indexdir\"   $osextra")) {
+	    print STDERR "<FatalError name='NoRunLucenePasses'/>\n</Stage>\n" if $self->{'gli'};
+	    die "lucenebuilder::build_index - couldn't run $full_lucene_passes_exe\n";
+	}
+    }
+
+    my $store_levels = $self->{'levels'};
+    my $db_level = "section"; #always
+    my $dom_level = "";
+    foreach my $key (keys %$store_levels) {
+	if ($mgppbuilder::level_map{$key} eq $llevel) {
+	    $dom_level = $key;
+	}
+    }
+    if ($dom_level eq "") {
+	print STDERR "Warning: unrecognized tag level $llevel\n";
+	$dom_level = "document";
+    }
+
+    my $local_levels = { $dom_level => 1 }; # work on one level at a time
+
+    # set up the document processr
+    $self->{'buildproc'}->set_output_handle ($handle);
+    $self->{'buildproc'}->set_mode ('text');
+    $self->{'buildproc'}->set_index ($index, $indexexparr);
+    $self->{'buildproc'}->set_index_languages ($language_metadata, $langarr) if (defined $language);
+    $self->{'buildproc'}->set_indexing_text (1);
+    #$self->{'buildproc'}->set_indexfieldmap ($self->{'indexfieldmap'});
+    $self->{'buildproc'}->set_levels ($local_levels);
+    $self->{'buildproc'}->set_db_level($db_level);
+    $self->{'buildproc'}->reset();
+    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'},
+		   "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'}, 0, $self->{'gli'});
+    close ($handle) unless $self->{'debug'};
+
+    $self->print_stats();
+
+    $self->{'buildproc'}->set_levels ($store_levels);
+    print STDERR "</Stage>\n" if $self->{'gli'};
+}
+
+# /** A modified version of the basebuilder.pm's function that generates the
+#  *  information database from the GA documents. We need to change this
+#  *  so that if we've been asked to do an incremental build we only add
+#  *  metadata to autohierarchy classifiers via the IncrementalBuildUtils
+#  *  module. All other classifiers and metadata will be ignored.
+#  */
+# This was added to utilize DLC's incremental updating of Hierarchy classifiers. They are heading towards just using dynamic classifiers, and we do not want to use this code either. So now, we just use basebuilder's version of make_infodatabase
+sub make_infodatabase_dlc
+{
+    my $self = shift (@_);
+    my $outhandle = $self->{'outhandle'};
+
+    # Get info database file path
+    my $text_directory_path = &util::filename_cat($self->{'build_dir'}, "text");
+    my $infodb_file_path = &dbutil::get_infodb_file_path($self->{'infodbtype'}, $self->{'collection'}, $text_directory_path);
+
+    # If we aren't doing an incremental addition, then we just call the super-
+    # classes version
+    # Note: Incremental addition can only occur if an information database
+    #       already exists. If it doesn't, let the super classes function be
+    #       called once to generate it.
+    if (!$self->{'incremental'} || !-e $infodb_file_path)
+    {
+        # basebuilder::make_infodatabase(@_);
+        # Note: this doesn't work as the direct reference means all the $self
+        #       data is lost.
+        $self->basebuilder::make_infodatabase(@_);
+        return;
+    }
+
+    # Carry on with an incremental addition
+    print $outhandle "\n*** performing an incremental addition to the info database\n" if ($self->{'verbosity'} >= 1);
+    print STDERR "<Stage name='CreateInfoData'>\n" if $self->{'gli'};
+
+    # 1. Init all the classifiers
+    &classify::init_classifiers ($self->{'classifiers'});
+    # 2. Init the buildproc settings.
+    #    Note: we still need this to process any associated files - but we
+    #    don't expect to pipe anything to the database so we can do away with the
+    #    complex output handle.
+    my $assocdir = &util::filename_cat($self->{'build_dir'}, "assoc");
+    &util::mk_all_dir ($assocdir);
+    $self->{'buildproc'}->set_mode ('incinfodb'); # Very Important
+    $self->{'buildproc'}->set_assocdir ($assocdir);
+    # 3. Read in all the metadata from the files in the archives directory using
+    #    the GAPlug and using ourselves as the document processor!
+    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'}, "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'},0, $self->{'gli'});
+
+    print STDERR "</Stage>\n" if $self->{'gli'};
+}
+
+# /** Lucene specific document removal function. This works by calling lucene_passes.pl with
+#  *  -remove and the document id on the command line.
+#  *
+#  *  @param oid is the document identifier to be removed.
+#  *
+#  *  @author John Rowe, DL Consulting Ltd.
+#  */
+sub remove_document_from_database
+{
+    my ($self, $oid) = @_;
+    # Find the perl script to call to run lucene
+    my $full_lucene_passes_exe = $self->{'full_lucene_passes_exe'};
+    # Call lucene_passes.pl with -remove and the document ID on the command line
+    `$full_lucene_passes_exe -remove "$oid"`;
+}
+# /** remove_document_from_database **/
+
+
+1;
+
+
Index: /gsdl/stable/perllib/lucenebuildproc.pm
===================================================================
--- /gsdl/stable/perllib/lucenebuildproc.pm	(revision 20131)
+++ /gsdl/stable/perllib/lucenebuildproc.pm	(revision 20131)
@@ -0,0 +1,569 @@
+###########################################################################
+#
+# lucenebuildproc.pm -- perl wrapper for building index with Lucene
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package lucenebuildproc;
+
+# This document processor outputs a document
+# for lucene to process
+
+# Use same basic XML structure setup by mgppbuilder/mgppbuildproc
+
+use mgppbuildproc;
+use ghtml;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+
+use IncrementalBuildUtils;
+
+sub BEGIN {
+    @lucenebuildproc::ISA = ('mgppbuildproc');
+}
+
+
+sub new {
+    my $class = shift @_;
+    my $self = new mgppbuildproc (@_);
+
+    $self->{'numincdocs'} = 0;
+
+    return bless $self, $class;
+}
+
+
+sub is_incremental_capable
+{
+    my $self = shift (@_);
+
+    # Unlike MG and MGPP, Lucene supports incremental building
+    return 1;
+}
+
+
+sub textedit {
+    my $self = shift (@_);
+    my ($doc_obj,$file,$edit_mode) = @_;
+
+    my $lucenehandle = $self->{'output_handle'};
+    my $outhandle = $self->{'outhandle'};
+
+    # only output this document if it is one to be indexed
+    return if ($doc_obj->get_doc_type() ne "indexed_doc");
+
+    # skip this document if in "compress-text" mode and asked to delete it
+    return if (!$self->get_indexing_text() && ($edit_mode eq "delete"));
+
+    my $indexed_doc = $self->is_subcollection_doc($doc_obj);
+
+    # this is another document
+    if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+	$self->{'num_docs'} += 1;
+    }
+    else {
+	$self->{'num_docs'} -= 1;
+    }
+
+    # get the parameters for the output
+    # split on : just in case there is subcoll and lang stuff
+    my ($fields) = split (/:/, $self->{'index'});
+
+    my $doc_tag_name = $mgppbuildproc::level_map{'document'};
+
+    my $levels = $self->{'levels'};
+    my $ldoc_level = $levels->{'document'};
+    my $lsec_level = $levels->{'section'};
+
+    # gs2_id should be depricated #####
+    my $gs2_id = "";
+    if ($ldoc_level)
+    {
+	if ($self->{'db_level'} eq 'document')
+	{
+	    $gs2_id = $self->{'num_docs'};
+	}
+        else
+	{
+	    # default is section level
+	    $gs2_id = $self->{'num_sections'} + 1;
+	}
+    }
+    my $gs2_docOID = $doc_obj->get_OID();
+    my $documenttag = undef;
+    my $documentendtag = undef;
+
+    $documenttag = "<$doc_tag_name xmlns:gs2=\"http://www.greenstone.org/gs2\" file=\"$file\" gs2:id=\"$gs2_id\" gs2:docOID=\"$gs2_docOID\" gs2:mode=\"$edit_mode\">\n";
+    $documentendtag = "\n</$doc_tag_name>\n";
+
+    my $sec_tag_name = "";
+    if ($lsec_level)
+    {
+	$sec_tag_name = $mgppbuildproc::level_map{'section'};
+    }
+
+    my $doc_section = 0; # just for this document
+
+    my $text = "";
+    $text .= $documenttag;
+    # get the text for this document
+    my $section = $doc_obj->get_top_section();
+    while (defined $section)
+    {
+	# update a few statistics
+	$doc_section++;
+	$self->{'num_sections'}++;
+
+	my $sec_gs2_id = $self->{'num_sections'};
+	my $sec_gs2_docOID = $gs2_docOID;
+	$sec_gs2_docOID .= ".$section" if ($section ne "");
+
+	# if we are doing subcollections, then some docs shouldn't be indexed.
+	# but we need to put the section tag placeholders in there so the
+	# sections match up with database
+	my $indexed_section = $doc_obj->get_metadata_element($section, "gsdldoctype") || "indexed_section";
+	if (($indexed_doc == 0) || ($indexed_section ne "indexed_section" && $indexed_section ne "indexed_doc")) {
+	    if ($sec_tag_name ne "") {
+		$text .= "\n<$sec_tag_name gs2:id=\"$sec_gs2_id\" gs2:docOID=\"$sec_gs2_docOID\" gs2:mode=\"ignore\">\n";
+		$text .= "\n</$sec_tag_name>\n" 
+	    }
+            $section = $doc_obj->get_next_section($section);
+	    next;
+          }
+
+	if ($sec_tag_name ne "")
+	{
+	    $text .= "\n<$sec_tag_name gs2:id=\"$sec_gs2_id\" gs2:docOID=\"$sec_gs2_docOID\" gs2:mode=\"$edit_mode\">\n";
+	}
+
+	if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+	    $self->{'num_bytes'} += $doc_obj->get_text_length ($section);
+	}
+	else {
+	    # delete
+	    $self->{'num_bytes'} -= $doc_obj->get_text_length ($section);
+	}
+
+
+	# has the user added a 'metadata' index?
+	my $all_metadata_specified = 0;
+	# which fields have already been indexed? (same as fields, but in a map)
+	my $specified_fields = {};
+	
+	# do we have an allfields index??
+	my $allfields_index = 0;
+	# collect up all the text for it in here
+	my $allfields_text = "";
+	foreach my $field (split (/;/, $fields)) {
+	    if ($field eq "allfields") {
+		$allfields_index = 1;
+	    } elsif ($field eq "metadata") {
+		$all_metadata_specified = 1;
+	    }
+	}
+	
+	foreach my $field (split (/;/, $fields)) {
+	    
+	    # only deal with this field if it doesn't start with top or
+	    # this is the first section
+	    my $real_field = $field;
+	    next if (($real_field =~ s/^top//) && ($doc_section != 1));
+	    
+	    # process these two later
+	    next if ($real_field eq "allfields" || $real_field eq "metadata");
+	    
+	    #individual metadata and or text specified - could be a comma separated list
+	    $specified_fields->{$real_field} = 1;
+	    my $shortname="";
+	    my $new_field = 0; # have we found a new field name?
+	    if (defined $self->{'indexfieldmap'}->{$real_field}) {
+		$shortname = $self->{'indexfieldmap'}->{$real_field};
+	    }
+	    else {
+		$shortname = $self->create_shortname($real_field);
+		$new_field = 1;
+	    }
+
+	    my @metadata_list = (); # put any metadata values in here
+	    my $section_text = ""; # put the text in here
+	    foreach my $submeta (split /,/, $real_field) {
+		if ($submeta eq "text") {
+		    # no point in indexing text more than once
+		    if ($section_text eq "") {
+			$section_text = $doc_obj->get_text($section);
+			if ($self->{'indexing_text'}) {
+			    # we always strip html
+			    $section_text = $self->preprocess_text($section_text, 1, "");
+			}
+			else { 
+			    # leave html stuff in, but escape the tags
+			    &ghtml::htmlsafe($section_text);
+			}
+		    }
+		}
+		else {
+		    # its a metadata element
+		    my @section_metadata = @{$doc_obj->get_metadata ($section, $submeta)};
+		    if ($section ne $doc_obj->get_top_section() && $self->{'indexing_text'} && defined ($self->{'sections_index_document_metadata'})) {
+			if ($self->{'sections_index_document_metadata'} eq "always" || ( scalar(@section_metadata) == 0 && $self->{'sections_index_document_metadata'} eq "unless_section_metadata_exists")) {
+			    push (@section_metadata, @{$doc_obj->get_metadata ($doc_obj->get_top_section(), $submeta)});
+			}
+		    }
+		    push (@metadata_list, @section_metadata);
+		}
+	    } # for each field in this one index
+	    
+	    # now we add the text and/or metadata into new_text
+	    if ($section_text ne "" || scalar(@metadata_list)) {
+		my $new_text = "";
+		
+		if ($section_text ne "") {
+		    $new_text .= "$section_text ";
+		}
+		
+		foreach my $item (@metadata_list) {
+		    &ghtml::htmlsafe($item);
+		    $new_text .= "$item ";
+		}
+
+		if ($allfields_index) {
+		    $allfields_text .= $new_text;
+		}
+
+		if ($self->{'indexing_text'}) {
+		    # add the tag
+		    $new_text = "<$shortname index=\"1\">$new_text</$shortname>";
+		}
+		# filter the text
+		$new_text = $self->filter_text ($field, $new_text);
+
+		if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+		    $self->{'num_processed_bytes'} += length ($new_text);
+		    $text .= "$new_text";
+		}
+		else {
+		    # delete
+		    $self->{'num_processed_bytes'} -= length ($new_text);
+		}
+		
+
+		if ($self->{'indexing_text'} && $new_field) {
+		    # we need to add to the list in indexfields
+		    
+		    $self->{'indexfieldmap'}->{$real_field} = $shortname;
+		    $self->{'indexfieldmap'}->{$shortname} = 1;
+		}
+		
+	    }
+	    
+	} # foreach field
+
+
+   	if ($all_metadata_specified) {
+	    
+	    my $new_text = "";
+	    my $shortname = "";
+	    my $metadata = $doc_obj->get_all_metadata ($section);
+	    foreach my $pair (@$metadata) {
+		my ($mfield, $mvalue) = (@$pair);
+		# no value
+		next unless defined $mvalue && $mvalue ne "";
+		# we have already indexed this
+		next if defined ($specified_fields->{$mfield});
+		# check fields here, maybe others dont want - change to use dontindex!!
+		next if ($mfield eq "Identifier" || $mfield eq "classifytype" || $mfield eq "assocfilepath");
+		next if ($mfield =~ /^gsdl/);
+		
+		&ghtml::htmlsafe($mvalue);
+		
+		if (defined $self->{'indexfieldmap'}->{$mfield}) {
+		    $shortname = $self->{'indexfieldmap'}->{$mfield};
+		}
+		else {
+		    $shortname = $self->create_shortname($mfield);
+		    $self->{'indexfieldmap'}->{$mfield} = $shortname;
+		    $self->{'indexfieldmap'}->{$shortname} = 1;
+		}	   
+		$new_text .= "<$shortname index=\"1\">$mvalue</$shortname>\n";
+		if ($allfields_index) {
+		    $allfields_text .= "$mvalue ";
+		}
+
+		if (!defined $self->{'indexfields'}->{$mfield}) {
+		    $self->{'indexfields'}->{$mfield} = 1;
+		}				    
+	    
+	    }
+	    # filter the text
+	    $new_text = $self->filter_text ("metadata", $new_text);
+	    
+	    if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+		$self->{'num_processed_bytes'} += length ($new_text);
+		$text .= "$new_text";
+	    }
+	    else {
+		# delete
+		$self->{'num_processed_bytes'} -= length ($new_text);
+	    }	    
+	}
+
+	if ($allfields_index) {
+	    # add the index name mapping
+	    $self->{'indexfieldmap'}->{"allfields"} = "ZZ";
+	    $self->{'indexfieldmap'}->{"ZZ"} = 1;
+	    
+	    my $new_text = "<ZZ index=\"1\">$allfields_text</ZZ>\n";
+	    # filter the text
+	    $new_text = $self->filter_text ("allfields", $new_text);
+	    
+	    if (($edit_mode eq "add") || ($edit_mode eq "update")) {
+		$self->{'num_processed_bytes'} += length ($new_text);
+		$text .= "$new_text";
+	    }
+	    else {
+		# delete
+		$self->{'num_processed_bytes'} -= length ($new_text);
+	    }
+	}
+	    
+	$text .= "\n</$sec_tag_name>\n" if ($sec_tag_name ne "");
+
+        $section = $doc_obj->get_next_section($section);
+    } # while defined section
+
+    print $lucenehandle "$text\n$documentendtag";
+
+##    if ($edit_mode eq "delete") {	
+##       print STDERR "$text\n$documentendtag";
+##    }
+
+}
+
+sub text {
+    my $self = shift (@_);
+    my ($doc_obj,$file) = @_;
+
+    $self->textedit($doc_obj,$file,"add");
+}
+
+sub textreindex
+{
+    my $self = shift (@_);
+    my ($doc_obj,$file) = @_;
+
+    $self->textedit($doc_obj,$file,"update");
+}
+
+sub textdelete
+{
+    my $self = shift (@_);
+    my ($doc_obj,$file) = @_;
+
+    $self->textedit($doc_obj,$file,"delete");
+}
+
+
+
+
+
+# /** We make this builder pretend to be a document processor so we can get
+#  *  information back from the plugins.
+#  *
+#  *  @param  $self    A reference to this Lucene builder
+#  *  @param  $doc_obj A reference to a document object representing what was
+#  *                   parsed by the GAPlug
+#  *  @param  $file    The name of the file parsed as a string
+#  *
+#  *  @author John Thompson, DL Consulting Ltd
+#  */
+sub process()
+  {
+    my $self = shift (@_);
+    my ($doc_obj, $file) = @_;
+
+    # If this is called from any stage other than an incremental infodb we want
+    # to pass through to the superclass of build
+    if ($self->get_mode() eq "incinfodb")
+      {
+        print STDERR "*** Processing a document added using INCINFODB ***\n" if ($self->{'verbosity'} > 3);
+        my ($archivedir) = $file =~ /^(.*?)(?:\/|\\)[^\/\\]*$/;
+        $archivedir = "" unless defined $archivedir;
+        $archivedir =~ s/\\/\//g;
+        $archivedir =~ s/^\/+//;
+        $archivedir =~ s/\/+$//;
+
+        # Number of files
+        print STDERR "There are " . scalar(@{$doc_obj->get_assoc_files()}) . " associated documents...\n" if ($self->{'verbosity'} > 3);
+
+        # resolve the final filenames of the files associated with this document
+        $self->assoc_files ($doc_obj, $archivedir);
+
+        # is this a paged or a hierarchical document
+        my ($thistype, $childtype) = $self->get_document_type ($doc_obj);
+
+        # Determine the actual docnum by checking if we've processed any
+        # previous incrementally added documents. If so, carry on from there.
+        # Otherwise we set the counter to be the same as the number of
+        # sections encountered during the previous build
+        if ($self->{'numincdocs'} == 0)
+          {
+            $self->{'numincdocs'} = $self->{'starting_num_sections'} + 1;
+          }
+
+        my $section = $doc_obj->get_top_section ();
+        print STDERR "+ top section: '$section'\n" if ($self->{'verbosity'} > 3);
+        my $doc_OID = $doc_obj->get_OID();
+        my $url = "";
+        while (defined $section)
+          {
+            print STDERR "+ processing section: '$section'\n" if ($self->{'verbosity'} > 3);
+            # Attach all the other metadata to this document
+            # output the fact that this document is a document (unless doctype
+            # has been set to something else from within a plugin
+            my $dtype = $doc_obj->get_metadata_element ($section, "doctype");
+            if (!defined $dtype || $dtype !~ /\w/)
+              {
+                #$doc_obj->add_utf8_metadata($section, "doctype", $dtype);
+		  $doc_obj->add_utf8_metadata($section, "doctype", "doc");
+              }
+            # output whether this node contains text
+            if ($doc_obj->get_text_length($section) > 0)
+              {
+                $doc_obj->add_utf8_metadata($section, "hastxt", 1);
+              }
+            else
+              {
+                $doc_obj->add_utf8_metadata($section, "hastxt", 0);
+              }
+
+            # output archivedir if at top level
+            if ($section eq $doc_obj->get_top_section())
+              {
+                $doc_obj->add_utf8_metadata($section, "archivedir", $archivedir);
+		$doc_obj->add_utf8_metadata($section, "thistype", $thistype);
+              }
+
+            # output a list of children
+            my $children = $doc_obj->get_children ($section);
+            if (scalar(@$children) > 0)
+              {
+                $doc_obj->add_utf8_metadata($section, "childtype", $childtype);
+                my @contains = ();
+                foreach my $child (@$children)
+                  {
+                    if ($child =~ /^.*?\.(\d+)$/)
+                      {
+                        push (@contains, "\".$1");
+                      }
+                    else
+                      {
+                        push (@contains, "\".$child");
+                      }
+                  }
+                $doc_obj->add_utf8_metadata($section, "contains", join(";", @contains));
+              }
+            #output the matching doc number
+            print STDERR "+ docnum=" . $self->{'numincdocs'} . "\n" if ($self->{'verbosity'} > 3);
+            $doc_obj->add_utf8_metadata($section, "docnum", $self->{'numincdocs'});
+
+            $self->{'numincdocs'}++;
+            $section = $doc_obj->get_next_section($section);
+            # if no sections wanted, only add the docs
+            last if ($self->{'db_level'} eq "document");
+          }
+        print STDERR "\n*** incrementally add metadata from document at: " . $file . "\n" if ($self->{'verbosity'} > 3);
+        &IncrementalBuildUtils::addDocument($self->{'collection'}, $doc_obj, $doc_obj->get_top_section());
+      }
+    else
+      {
+        $self->mgppbuildproc::process(@_);
+      }
+  }
+# /** process() **/
+
+
+# Following methods seem to be no different to those defined in basebuildproc.pm
+# From inspection, it looks like these ones can be removed
+
+
+sub get_num_docs {
+    my $self = shift (@_);
+    #rint STDERR "get_num_docs(): $self->{'num_docs'}\n";
+    return $self->{'num_docs'};
+}
+
+sub get_num_sections {
+    my $self = shift (@_);
+    #rint STDERR "get_num_sections(): $self->{'num_sections'}\n";
+    return $self->{'num_sections'};
+}
+
+# num_bytes is the actual number of bytes in the collection
+# this is normally the same as what's processed during text compression
+sub get_num_bytes {
+    my $self = shift (@_);
+    #rint STDERR "get_num_bytes(): $self->{'num_bytes'}\n";
+    return $self->{'num_bytes'};
+}
+
+
+# This is similar to mgppbuildproc's preprocess_text but adds extra spaces
+# Otherwise the removal of tags below might lead to Lucene turning
+#   "...farming</p>\n<p>EDWARD.." into "farmingedward"
+#     (example from demo collection b20cre)
+# Many thanks to John Thompson, DL Consulting Ltd. (www.dlconsulting.com)
+sub preprocess_text
+{
+    my $self = shift (@_);
+    my ($text, $strip_html, $para) = @_;
+    # at this stage, we do not do paragraph tags unless have strip_html -
+    # it will result in a huge mess of non-xml
+    return unless $strip_html;
+
+    my $new_text = $text;
+
+    # if we have <pre> tags, we can have < > inside them, need to delete
+    # the <> before stripping tags
+    $new_text =~ s/<pre>(.*?)<\/pre>/$self->remove_gtlt($1,$para)/gse;
+
+    if ($para eq "") {
+       # just remove all tags
+       $new_text =~ s/<[^>]*>/ /gs;
+    } else {
+       # strip all tags except <p> tags which get turned into $para
+       $new_text =~ s/<([^>]*)>/$self->process_tags($1, $para)/gse;
+    }
+
+    # It's important that we remove name entities because otherwise the text passed to Lucene for indexing
+    #   may not be valid XML (eg. if HTML-only entities like &nbsp; are used)
+    $new_text =~ s/&\w{1,10};//g;
+    # Remove stray '&' characters, except in &#nnnn; or &#xhhhh; entities (which are valid XML)
+    $new_text =~ s/&([^\#])/ $1/g;
+
+    return $new_text;
+}
+
+
+1;
+
+
Index: /gsdl/stable/perllib/manifest.pm
===================================================================
--- /gsdl/stable/perllib/manifest.pm	(revision 20131)
+++ /gsdl/stable/perllib/manifest.pm	(revision 20131)
@@ -0,0 +1,163 @@
+package manifest;
+
+use XMLParser;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+our $self;
+
+sub new {
+    my ($class) = shift (@_);
+
+    $self = {} ;
+
+    $self->{'index'} = {};
+    $self->{'reindex'} = {};
+    $self->{'delete'} = {};
+
+    return bless $self, $class;
+}
+
+sub parse
+{
+    my ($self) = shift (@_);
+    my ($filename) = @_;
+
+    my $parser = new XML::Parser('Style' => 'Stream',
+                                 'Handlers' => {'Char' => \&Char,
+                                                'XMLDecl' => \&XMLDecl,
+                                                'Entity' => \&Entity,
+                                                'Doctype' => \&Doctype,
+                                                'Default' => \&Default
+                                                });
+
+    $parser->parsefile($filename);
+}
+
+sub StartDocument {$self->xml_start_document(@_);}
+sub XMLDecl {$self->xml_xmldecl(@_);}
+sub Entity {$self->xml_entity(@_);}
+sub Doctype {$self->xml_doctype(@_);}
+sub StartTag {$self->xml_start_tag(@_);}
+sub EndTag {$self->xml_end_tag(@_);}
+sub Text {$self->xml_text(@_);}
+sub PI {$self->xml_pi(@_);}
+sub EndDocument {$self->xml_end_document(@_);}
+sub Default {$self->xml_default(@_);}
+
+# This Char function overrides the one in XML::Parser::Stream to overcome a
+# problem where $expat->{Text} is treated as the return value, slowing
+# things down significantly in some cases.
+sub Char {
+    use bytes;  # Necessary to prevent encoding issues with XML::Parser 2.31+
+    $_[0]->{'Text'} .= $_[1];
+    return undef;
+}
+
+# Called at the beginning of the XML document.
+sub xml_start_document {
+    my $self = shift(@_);
+    my ($expat) = @_;
+
+}
+
+# Called for XML declarations
+sub xml_xmldecl {
+    my $self = shift(@_);
+    my ($expat, $version, $encoding, $standalone) = @_;
+}
+
+# Called for XML entities
+sub xml_entity {
+  my $self = shift(@_);
+  my ($expat, $name, $val, $sysid, $pubid, $ndata) = @_;
+}
+
+# Called for DOCTYPE declarations - use die to bail out if this doctype
+# is not meant for this plugin
+sub xml_doctype {
+    my $self = shift(@_);
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+    die "Manifest Cannot process XML document with DOCTYPE of $name";
+}
+
+# Called for every start tag. The $_ variable will contain a copy of the
+# tag and the %_ variable will contain the element's attributes.
+sub xml_start_tag
+{
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+
+    if ($element eq "Filename")
+    {
+	$self->{'filename'} = "";
+    }
+    elsif ($element eq "Manifest") {
+    }
+    else
+    {
+	if (defined($self->{'file-type'}))
+	{
+	    print STDERR "Warning: Malformed XML manifest ($element nested inside " . $self->{'file-type'} . ")\n";
+	}
+
+	$self->{'file-type'} = $element;
+    }
+}
+
+# Called for every end tag. The $_ variable will contain a copy of the tag.
+sub xml_end_tag
+{
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+
+    if ($element eq "Filename")
+    {
+	$self->{lc($self->{'file-type'})}->{$self->{'filename'}} = 1;
+	$self->{'filename'} = undef;
+    }
+    else
+    {
+	$self->{'file-type'} = undef;
+    }
+}
+
+# Called just before start or end tags with accumulated non-markup text in
+# the $_ variable.
+sub xml_text {
+    my $self = shift(@_);
+    my ($expat) = @_;
+
+    if (defined $self->{'filename'}) {
+	my $text = $_;
+	chomp($text);
+
+	$text =~ s/^\s+//;
+	$text =~ s/\s+$//;	
+	
+	$self->{'filename'} .= $text if ($text !~ m/^\s*$/);
+    }
+}
+
+# Called for processing instructions. The $_ variable will contain a copy
+# of the pi.
+sub xml_pi {
+    my $self = shift(@_);
+    my ($expat, $target, $data) = @_;
+}
+
+# Called at the end of the XML document.
+sub xml_end_document {
+    my $self = shift(@_);
+    my ($expat) = @_;
+
+}
+
+# Called for any characters not handled by the above functions.
+sub xml_default {
+    my $self = shift(@_);
+    my ($expat, $text) = @_;
+}
+
+
+1;
Index: /gsdl/stable/perllib/marcmapping.pm
===================================================================
--- /gsdl/stable/perllib/marcmapping.pm	(revision 20131)
+++ /gsdl/stable/perllib/marcmapping.pm	(revision 20131)
@@ -0,0 +1,146 @@
+###########################################################################
+#
+# marcmapping.pm -- code to read in the marc mapping files
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2008 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package marcmapping;
+
+sub parse_marc_metadata_mapping
+{
+    my ($mm_file_or_files, $outhandle) = @_;
+
+    my $metadata_mapping = {};
+
+    if (ref ($mm_file_or_files) eq 'ARRAY') {
+	my $mm_files = $mm_file_or_files;
+
+	# Need to process files in reverse order.  This is so in the
+	# case where we have both a "collect" and "main" version,
+	# the "collect" one tops up the main one
+
+	my $mm_file;
+	while ($mm_file = pop(@$mm_files)) {
+	    &_parse_marc_metadata_mapping($mm_file,$metadata_mapping, $outhandle);
+	}
+    }
+    else {
+	my $mm_file = $mm_file_or_files;
+	&_parse_marc_metadata_mapping($mm_file,$metadata_mapping, $outhandle);
+    }
+
+    return $metadata_mapping;
+}
+
+sub _parse_marc_metadata_mapping
+{
+    my ($mm_file,$metadata_mapping, $outhandle) = @_;
+
+    if (open(MMIN, "<$mm_file"))
+    {
+	my $l=0;
+	my $line;
+	while (defined($line=<MMIN>))
+	{
+	    $l++;
+	    chomp $line;
+	    $line =~ s/#.*$//; # strip out any comments, including end of line
+	    next if ($line =~ m/^\s*$/); 
+	    $line =~ s/\s+$//; # remove any white space at end of line
+
+	    my $parse_error_count = 0;
+	    if ($line =~ m/^-(\d+)\s*$/) {
+		# special "remove" rule syntax
+		my $marc_info = $1;
+		if (defined $metadata_mapping->{$marc_info}) {
+		    delete $metadata_mapping->{$marc_info};
+		}
+		else {
+		    print $outhandle "Parse Warning: Did not find pre-existing rule $marc_info to remove";
+		    print $outhandle " on line $l of $mm_file:\n";
+		    print $outhandle "  $line\n";
+		}
+	    }
+	    elsif ($line =~ m/^(.*?)->\s*([\w\.\^]+)$/)
+	    {
+		my $lhs = $1;
+		my $gsdl_info = $2;
+
+		my @fields = split(/,\s*/,$lhs);
+		my $f;
+		while ($f  = shift (@fields)) {
+		    $f =~ s/\s+$//; # remove any white space at end of line
+
+		    if ($f =~ m/^(\d+)\-(\d+)$/) {
+			# number range => generate number in range and
+			# push on to array
+			push(@fields,$1..$2);
+			next;
+		    }
+
+		    if ($f =~ m/^(\d+)((?:(?:\$|\^)\w)*)\s*$/) {
+
+			my $marc_info = $1;
+			my $opt_sub_fields = $2;
+
+			if ($opt_sub_fields ne "") {			
+			    my @sub_fields = split(/\$|\^/,$opt_sub_fields);
+			    shift @sub_fields; # skip first entry, which is blank
+
+			    foreach my $sub_field (@sub_fields) {
+				$metadata_mapping->{$marc_info."\$".$sub_field} = $gsdl_info;
+			    }
+			}
+			else {
+			    # no subfields to worry about
+			    $marc_info =~ s/\^/\$/;
+			    $metadata_mapping->{$marc_info} = $gsdl_info;
+			}
+		    }
+		    else {
+			$parse_error_count++;
+		    }
+		}
+	    }
+	    else
+	    {
+		$parse_error_count++;
+	    }
+
+	    if ($parse_error_count>0) {
+		
+		print $outhandle "Parse Error: $parse_error_count syntax error(s) on line $l of $mm_file:\n";
+		print $outhandle "  $line\n";
+	    }
+	}
+	close(MMIN);
+    }
+    else
+    {
+	print $outhandle "Unable to open $mm_file: $!\n";
+    }
+}
+
+
+
+1;
Index: /gsdl/stable/perllib/metadatautil.pm
===================================================================
--- /gsdl/stable/perllib/metadatautil.pm	(revision 20131)
+++ /gsdl/stable/perllib/metadatautil.pm	(revision 20131)
@@ -0,0 +1,144 @@
+###########################################################################
+#
+# metadatautil.pm -- various useful utilities for dealing with metadata
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package metadatautil;
+
+use strict;
+
+sub combine_metadata_structures { 
+    my ($mdref1, $mdref2) = @_;
+    my ($key, $value1, $value2);
+
+    foreach $key (keys %$mdref2) {
+
+	$value1 = $mdref1->{$key};
+	$value2 = $mdref2->{$key};
+	
+	# If there is no existing value for this metadata field in 
+	# $mdref1, so we simply copy the value from $mdref2 over.
+	if (!defined $value1) {
+	    $mdref1->{$key} = &clonedata($value2);
+	} 
+	# Otherwise we have to add the new values to the existing ones.
+	# If the second structure is accumulated, then acculate all the
+	# values into the first structure
+	elsif ((ref $value2) eq "ARRAY") {
+	    # If the first metadata element is a scalar we have to 
+	    # convert it into an array before we add anything more.
+	    if ((ref $value1) ne 'ARRAY') {
+		$mdref1->{$key} = [$value1];
+		$value1 = $mdref1->{$key};
+	    }
+	    # Now add the value(s) from the second array to the first
+	    $value2 = &clonedata($value2);
+	    push @$value1, @$value2;
+	} 
+	# Finally, If the second structure is not an array reference, we
+	# know it is in override mode, so override the first structure.
+	else {
+	    $mdref1->{$key} = &clonedata($value2);
+	}
+    }
+}
+
+
+# Make a "cloned" copy of a metadata value.  
+# This is trivial for a simple scalar value,
+# but not for an array reference.
+
+sub clonedata {
+    my ($value) = @_;
+    my $result;
+
+    if ((ref $value) eq 'ARRAY') {
+	$result = [];
+	foreach my $item (@$value) {
+	    push @$result, $item;
+	}
+    } else {
+	$result = $value;
+    }
+    return $result;
+}
+
+sub format_metadata_as_table {
+    my ($metadata, $remove_namespace) = @_;
+    
+    my $text = "<table cellpadding=\"4\" cellspacing=\"0\">\n";
+    
+    foreach my $field (sort keys(%$metadata)) {
+	# $metadata->{$field} may be an array reference
+	if ($field eq "gsdlassocfile_tobe") {
+	    # ignore
+	} else {
+	    my $no_ns = $field;
+	    if ($remove_namespace) {
+		$no_ns =~ s/^\w+\.//;
+	    }
+	    if (ref ($metadata->{$field}) eq "ARRAY") {
+		map { 
+		    $text .= "<tr><td valign=top><nobr><b>$no_ns</b></nobr></td><td>".$_."</td></tr>";
+		} @{$metadata->{$field}};
+	    } else {
+		$text .= "<tr><td valign=top><nobr><b>$no_ns</b></nobr></td><td valign=top>$metadata->{$field}</td></tr>\n";
+	    }
+	}
+
+    }
+    $text .= "</table>\n";
+    return $text;
+}
+
+
+sub store_saved_metadata
+{
+    my ($plug,$mname,$mvalue,$md_accumulate) = @_;
+
+    if (defined $plug->{'saved_metadata'}->{$mname}) {
+	if ($md_accumulate) {
+	    # accumulate mode - add value to existing value(s)
+	    if (ref ($plug->{'saved_metadata'}->{$mname}) eq "ARRAY") {
+		push (@{$plug->{'saved_metadata'}->{$mname}}, $mvalue);
+	    } else {
+		$plug->{'saved_metadata'}->{$mname} = 
+		    [$plug->{'saved_metadata'}->{$mname}, $mvalue];
+	    }
+	} else {
+	    # override mode
+	    $plug->{'saved_metadata'}->{$mname} = $mvalue;
+	}
+    } else {
+	if ($md_accumulate) {
+	    # accumulate mode - add value into (currently empty) array
+	    $plug->{'saved_metadata'}->{$mname} = [$mvalue];
+	} else {
+	    # override mode
+	    $plug->{'saved_metadata'}->{$mname} = $mvalue;
+	}
+    }
+}
+
+
+1;
Index: /gsdl/stable/perllib/mgbuilder.pm
===================================================================
--- /gsdl/stable/perllib/mgbuilder.pm	(revision 20131)
+++ /gsdl/stable/perllib/mgbuilder.pm	(revision 20131)
@@ -0,0 +1,550 @@
+###########################################################################
+#
+# mgbuilder.pm -- MGBuilder object
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package mgbuilder;
+
+use basebuilder;
+use plugin;
+use strict; no strict 'refs';
+use util;
+
+
+BEGIN {
+    @mgbuilder::ISA = ('basebuilder');
+}
+
+
+my %wanted_index_files = ('td'=>1,
+		       't'=>1,
+		       'idb'=>1,
+		       'ib1'=>1,
+		       'ib2'=>1,
+		       'ib3'=>1,
+		       'i'=>1,
+		       'ip'=>1,
+		       'tiw'=>1,
+		       'wa'=>1);
+
+my $maxdocsize = $basebuilder::maxdocsize;
+
+
+sub new {
+    my $class = shift(@_);
+
+    my $self = new basebuilder (@_);
+    $self = bless $self, $class;
+
+    $self->{'buildtype'} = "mg";
+    return $self;
+}
+
+sub default_buildproc {
+    my $self  = shift (@_);
+
+    return "mgbuildproc";
+}
+
+sub generate_index_list {
+    my $self = shift (@_);
+
+    if (!defined($self->{'collect_cfg'}->{'indexes'})) {
+	$self->{'collect_cfg'}->{'indexes'} = [];
+    }
+    if (scalar(@{$self->{'collect_cfg'}->{'indexes'}}) == 0) {
+	# no indexes have been specified so we'll build a "dummy:text" index
+	push (@{$self->{'collect_cfg'}->{'indexes'}}, "dummy:text");	
+    }
+
+}
+
+sub generate_index_options {
+    my $self = shift (@_);
+    $self->SUPER::generate_index_options();
+    
+    $self->{'casefold'} = 0;
+    $self->{'stem'} = 0;
+    $self->{'accentfold'} = 0; #not yet implemented for mg
+    
+    if (!defined($self->{'collect_cfg'}->{'indexoptions'})) {
+	# just use default options
+	$self->{'casefold'} = 1;
+	$self->{'stem'} = 1;
+	
+    } else {
+	foreach my $option (@{$self->{'collect_cfg'}->{'indexoptions'}}) {
+	    if ($option =~ /stem/) {
+		$self->{'stem'} = 1;
+	    } elsif ($option =~ /casefold/) {
+		$self->{'casefold'} = 1;
+	    }
+	}
+    }
+    
+    # now we record this for the build cfg
+    $self->{'stemindexes'} = 0;
+    if ($self->{'casefold'}) {
+	$self->{'stemindexes'} += 1;
+    }
+    if ($self->{'stem'}) {
+	$self->{'stemindexes'} += 2;
+    }
+
+
+}
+
+sub compress_text {
+    my $self = shift (@_);
+    my ($textindex) = @_;
+    my $exedir = "$ENV{'GSDLHOME'}/bin/$ENV{'GSDLOS'}";
+    my $exe = &util::get_os_exe ();
+    my $mg_passes_exe = &util::filename_cat($exedir, "mg_passes$exe");
+    my $mg_compression_dict_exe = &util::filename_cat($exedir, "mg_compression_dict$exe");
+    my $outhandle = $self->{'outhandle'};
+
+    my $maxnumeric = $self->{'maxnumeric'};
+
+    &util::mk_all_dir (&util::filename_cat($self->{'build_dir'}, "text"));
+
+    my $collect_tail = &util::get_dirsep_tail($self->{'collection'});
+    my $basefilename = &util::filename_cat("text",$collect_tail);
+    my $fulltextprefix = &util::filename_cat ($self->{'build_dir'}, $basefilename);
+
+    my $osextra = "";
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	$fulltextprefix =~ s@/@\\@g;
+    } else {
+	$osextra = " -d /";
+    }
+
+    print $outhandle "\n*** creating the compressed text\n" if ($self->{'verbosity'} >= 1);
+    print STDERR "<Stage name='CompressText'>\n" if $self->{'gli'};
+
+    # collect the statistics for the text
+    # -b $maxdocsize sets the maximum document size to be 12 meg
+    print $outhandle "\n    collecting text statistics\n"  if ($self->{'verbosity'} >= 1);
+    print STDERR "<Phase name='CollectTextStats'/>\n" if $self->{'gli'};
+
+    my ($handle);
+    if ($self->{'debug'}) {
+	$handle = *STDOUT;
+    }
+    else {
+	if (!-e "$mg_passes_exe" || 
+	    !open($handle, "| mg_passes$exe -f \"$fulltextprefix\" -b $maxdocsize -T1 -M $maxnumeric $osextra")) {
+	    print STDERR "<FatalError name='NoRunMGPasses'>\n</Stage>\n" if $self->{'gli'};
+	    die "mgbuilder::compress_text - couldn't run $mg_passes_exe\n";
+	}
+    }
+
+    $self->{'buildproc'}->set_output_handle ($handle);
+    $self->{'buildproc'}->set_mode ('text');
+    $self->{'buildproc'}->set_index ($textindex);
+    $self->{'buildproc'}->set_indexing_text (0);
+
+
+    if ($self->{'no_text'}) {
+	$self->{'buildproc'}->set_store_text(0);
+    } else {
+	$self->{'buildproc'}->set_store_text(1);
+    }
+    $self->{'buildproc'}->reset();
+
+    &plugin::begin($self->{'pluginfo'}, $self->{'source_dir'}, 
+		   $self->{'buildproc'}, $self->{'maxdocs'});
+    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'}, 
+		   "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'}, 0, $self->{'gli'});
+    &plugin::end($self->{'pluginfo'});
+    
+
+    close ($handle) unless $self->{'debug'};
+
+    $self->print_stats();
+
+    # create the compression dictionary
+    # the compression dictionary is built by assuming the stats are from a seed
+    # dictionary (-S), if a novel word is encountered it is spelled out (-H),
+    # and the resulting dictionary must be less than 5 meg with the most frequent
+    # words being put into the dictionary first (-2 -k 5120)
+    if (!$self->{'debug'}) {
+	print $outhandle "\n    creating the compression dictionary\n"  if ($self->{'verbosity'} >= 1);
+	print STDERR "<Phase name='CreatingCompress'/>\n" if $self->{'gli'};
+	if (!-e "$mg_compression_dict_exe") {
+	    die "mgbuilder::compress_text - couldn't run $mg_compression_dict_exe\n";
+	}
+	system ("mg_compression_dict$exe -f \"$fulltextprefix\" -S -H -2 -k 5120 $osextra");
+
+	# -b $maxdocsize sets the maximum document size to be 12 meg
+	if (!-e "$mg_passes_exe" || 
+	    !open ($handle, "| mg_passes$exe -f \"$fulltextprefix\" -b $maxdocsize -T2 -M $maxnumeric $osextra")) {
+	    print STDERR "<FatalError name='NoRunMGPasses'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgbuilder::compress_text - couldn't run $mg_passes_exe\n";
+	}
+    }
+    else {
+	print STDERR "<Phase name='SkipCreatingComp'/>\n" if $self->{'gli'};
+    }
+
+    $self->{'buildproc'}->reset();
+    # compress the text
+    print $outhandle "\n    compressing the text\n"  if ($self->{'verbosity'} >= 1);
+    print STDERR "<Phase name='CompressingText'/>\n" if $self->{'gli'};
+
+    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'}, 
+		   "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'}, 0, $self->{'gli'});
+
+    close ($handle) unless $self->{'debug'};
+
+    $self->print_stats();
+    print STDERR "</Stage>\n" if $self->{'gli'};
+}
+
+
+# creates directory names for each of the index descriptions
+sub create_index_mapping {
+    my $self = shift (@_);
+    my ($indexes) = @_;
+
+    my %mapping = ();
+    $mapping{'indexmaporder'} = [];
+    $mapping{'subcollectionmaporder'} = [];
+    $mapping{'languagemaporder'} = [];
+    
+    # dirnames is used to check for collisions. Start this off
+    # with the manditory directory names
+    my %dirnames = ('text'=>'text',
+		    'extra'=>'extra');
+    my %pnames = ('index' => {}, 'subcollection' => {}, 'languages' => {});
+    foreach my $index (@$indexes) {
+	my ($level, $gran, $subcollection, $languages) = split (":", $index);
+
+	# the directory name starts with the first character of the index level
+	my ($pindex) = $level =~ /^(.)/;
+
+	# next comes a processed version of the index
+	$pindex .= $self->process_field ($gran); 
+	$pindex = lc ($pindex);
+
+	# next comes a processed version of the subcollection if there is one.
+	my $psub = $self->process_field ($subcollection);
+	$psub = lc ($psub);
+
+	# next comes a processed version of the language if there is one.
+	my $plang = $self->process_field ($languages);
+	$plang = lc ($plang);
+
+	my $dirname = $pindex . $psub . $plang;
+
+	# check to be sure all index names are unique
+	while (defined ($dirnames{$dirname})) {
+	    $dirname = $self->make_unique (\%pnames, $index, \$pindex, \$psub, \$plang);
+	}
+	$mapping{$index} = $dirname;
+
+	# store the mapping orders as well as the maps
+	# also put index, subcollection and language fields into the mapping thing - 
+	# (the full index name (eg document:text:subcol:lang) is not used on
+	# the query page) -these are used for collectionmeta later on
+	if (!defined $mapping{'indexmap'}{"$level:$gran"}) {
+	    $mapping{'indexmap'}{"$level:$gran"} = $pindex;
+	    push (@{$mapping{'indexmaporder'}}, "$level:$gran");
+	    if (!defined $mapping{"$level:$gran"}) {
+		$mapping{"$level:$gran"} = $pindex;
+	    }
+	}
+	if ($psub =~ /\w/ && !defined ($mapping{'subcollectionmap'}{$subcollection})) {
+	    $mapping{'subcollectionmap'}{$subcollection} = $psub;
+	    push (@{$mapping{'subcollectionmaporder'}}, $subcollection);
+	    $mapping{$subcollection} = $psub;
+	}
+	if ($plang =~ /\w/ && !defined ($mapping{'languagemap'}{$languages})) {
+	    $mapping{'languagemap'}{$languages} = $plang;
+	    push (@{$mapping{'languagemaporder'}}, $languages);
+	    $mapping{$languages} = $plang;
+	}
+	$dirnames{$dirname} = $index;
+	$pnames{'index'}->{$pindex} = "$level:$gran";
+	$pnames{'subcollection'}->{$psub} = $subcollection;
+	$pnames{'languages'}->{$plang} = $languages;
+    }
+
+    return \%mapping;
+}
+
+
+sub make_unique {
+    my $self = shift (@_);
+    my ($namehash, $index, $indexref, $subref, $langref) = @_;
+    my ($level, $gran, $subcollection, $languages) = split (":", $index);
+
+    if ($namehash->{'index'}->{$$indexref} ne "$level:$gran") {
+	$self->get_next_version ($indexref);
+    } elsif ($namehash->{'subcollection'}->{$$subref} ne $subcollection) {
+	$self->get_next_version ($subref);
+    } elsif ($namehash->{'languages'}->{$$langref} ne $languages) {
+	$self->get_next_version ($langref);
+    }
+    return "$$indexref$$subref$$langref";
+}	
+
+sub build_index {
+    my $self = shift (@_);
+    my ($index) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    # get the full index directory path and make sure it exists
+    my $indexdir = $self->{'index_mapping'}->{$index};
+    &util::mk_all_dir (&util::filename_cat($self->{'build_dir'}, $indexdir));
+
+    my $collect_tail = &util::get_dirsep_tail($self->{'collection'});
+    my $fullindexprefix = &util::filename_cat ($self->{'build_dir'}, $indexdir, 
+					       $collect_tail);
+    my $fulltextprefix = &util::filename_cat ($self->{'build_dir'}, "text", 
+					       $collect_tail);
+
+    # get any os specific stuff
+    my $exedir = "$ENV{'GSDLHOME'}/bin/$ENV{'GSDLOS'}";
+    my $exe = &util::get_os_exe ();
+    my $mg_passes_exe = &util::filename_cat($exedir, "mg_passes$exe");
+    my $mg_perf_hash_build_exe = 
+	&util::filename_cat($exedir, "mg_perf_hash_build$exe");
+    my $mg_weights_build_exe = 
+	&util::filename_cat ($exedir, "mg_weights_build$exe");
+    my $mg_invf_dict_exe = 
+	&util::filename_cat ($exedir, "mg_invf_dict$exe");
+    my $mg_stem_idx_exe =
+	&util::filename_cat ($exedir, "mg_stem_idx$exe");
+
+    my $maxnumeric = $self->{'maxnumeric'};
+
+    my $osextra = "";
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	$fullindexprefix =~ s@/@\\@g;
+    } else {
+	$osextra = " -d /";
+	if ($outhandle ne "STDERR") {
+	    # so mg_passes doesn't print to stderr if we redirect output
+	    $osextra .= " 2>/dev/null";
+	}
+    }
+
+    # get the index level from the index description
+    # the index will be level 2 unless we are building a
+    # paragraph level index
+    my $index_level = 2;
+    $index_level = 3 if $index =~ /^paragraph/i;
+
+    # get the index expression if this index belongs
+    # to a subcollection
+    my $indexexparr = [];
+    my $langarr = [];
+    # there may be subcollection info, and language info. 
+    my ($level, $fields, $subcollection, $language) = split (":", $index);
+    my @subcollections = ();
+    @subcollections = split /,/, $subcollection if (defined $subcollection);
+
+    foreach my $subcollection (@subcollections) {
+	if (defined ($self->{'collect_cfg'}->{'subcollection'}->{$subcollection})) {
+	    push (@$indexexparr, $self->{'collect_cfg'}->{'subcollection'}->{$subcollection});
+	} 
+    }
+    
+    # add expressions for languages if this index belongs to
+    # a language subcollection - only put languages expressions for the 
+    # ones we want in the index
+
+    my @languages = ();
+    my $language_metadata = "Language";
+    if (defined ($self->{'collect_cfg'}->{'language_metadata'})) {
+	$language_metadata = $self->{'collect_cfg'}->{'language_metadata'};
+    }
+    @languages = split /,/, $language if (defined $language);
+    foreach my $language (@languages) {
+	my $not=0;
+	if ($language =~ s/^\!//) {
+	    $not = 1;
+	}
+	if($not) {
+	    push (@$langarr, "!$language");
+	} else {
+	    push (@$langarr, "$language");
+	}
+    }
+    
+    # Build index dictionary. Uses verbatim stem method
+    print $outhandle "\n    creating index dictionary\n"  if ($self->{'verbosity'} >= 1);
+    print STDERR "<Phase name='CreatingIndexDic'/>\n" if $self->{'gli'};
+    my ($handle);
+    if ($self->{'debug'}) {
+	$handle = *STDOUT;
+    }
+    else {
+	if (!-e "$mg_passes_exe" || 
+	    !open($handle, "| mg_passes$exe -f \"$fullindexprefix\" -b $maxdocsize " .
+		   "-$index_level -m 32 -s 0 -G -t 10 -N1 -M $maxnumeric $osextra")) {
+	    print STDERR "<FatalError name='NoRunMGPasses'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgbuilder::build_index - couldn't run $mg_passes_exe\n";
+	}
+    }
+	
+    # set up the document processor
+    $self->{'buildproc'}->set_output_handle ($handle);
+    $self->{'buildproc'}->set_mode ('text');
+    $self->{'buildproc'}->set_index ($index, $indexexparr);
+    $self->{'buildproc'}->set_index_languages ($language_metadata, $langarr) if (defined $language);
+    $self->{'buildproc'}->set_indexing_text (1);
+    $self->{'buildproc'}->set_store_text(1);
+
+    $self->{'buildproc'}->reset();
+    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'}, 
+		   "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'},0, $self->{'gli'});
+    close ($handle) unless $self->{'debug'};
+
+    $self->print_stats();
+
+    # now we check to see if the required files have been produced - if not we quit building this index so the whole process doesn't crap out.
+    # we check on the .id file - index dictionary
+    my $dict_file = "$fullindexprefix.id";
+    if (!-e $dict_file) {
+	print $outhandle "mgbuilder::build_index - Couldn't create index $index\n";
+	$self->{'notbuilt'}->{$index}=1;
+	return;
+    }
+    if (!$self->{'debug'}) {
+	# create the perfect hash function
+	if (!-e "$mg_perf_hash_build_exe") {
+	    print STDERR "<FatalError name='NoRunMGHash'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgbuilder::build_index - couldn't run $mg_perf_hash_build_exe\n";
+	}
+	system ("mg_perf_hash_build$exe -f \"$fullindexprefix\" $osextra");
+
+	if (!-e "$mg_passes_exe" || 
+	    !open ($handle, "| mg_passes$exe -f \"$fullindexprefix\" -b $maxdocsize " .
+		   "-$index_level -c 3 -G -t 10 -N2 -M $maxnumeric $osextra")) {
+	    print STDERR "<FatalError name='NoRunMGPasses'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgbuilder::build_index - couldn't run $mg_passes_exe\n";
+	}
+    }
+    
+    # invert the text
+    print $outhandle "\n    inverting the text\n"  if ($self->{'verbosity'} >= 1);
+    print STDERR "<Phase name='InvertingText'/>\n" if $self->{'gli'};
+    $self->{'buildproc'}->reset();
+    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'}, 
+		   "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'},0, $self->{'gli'});
+
+   
+    $self->print_stats ();
+
+    if (!$self->{'debug'}) {
+
+	close ($handle);
+	
+	# create the weights file
+	print $outhandle "\n    create the weights file\n"  if ($self->{'verbosity'} >= 1);
+	print STDERR "<Phase name='CreateTheWeights'/>\n" if $self->{'gli'};
+	if (!-e "$mg_weights_build_exe") {
+	    print STDERR "<FatalError name='NoRunMGWeights'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgbuilder::build_index - couldn't run $mg_weights_build_exe\n";
+	}
+	system ("mg_weights_build$exe -f \"$fullindexprefix\" -t \"$fulltextprefix\" $osextra");
+
+	# create 'on-disk' stemmed dictionary
+	print $outhandle "\n    creating 'on-disk' stemmed dictionary\n"  if ($self->{'verbosity'} >= 1);
+	print STDERR "<Phase name='CreateStemmedDic'/>\n" if $self->{'gli'};
+	if (!-e "$mg_invf_dict_exe") {
+	    print STDERR "<FatalError name='NoRunMGInvf'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgbuilder::build_index - couldn't run $mg_invf_dict_exe\n";
+	}
+	system ("mg_invf_dict$exe -f \"$fullindexprefix\" $osextra");
+
+
+	# creates stem index files for the various stemming methods
+	print $outhandle "\n    creating stem indexes\n"  if ($self->{'verbosity'} >= 1);
+	print STDERR "<Phase name='CreatingStemIndx'/>\n" if $self->{'gli'};
+	if (!-e "$mg_stem_idx_exe") {
+	    print STDERR "<FatalError name='NoRunMGStem'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgbuilder::build_index - couldn't run $mg_stem_idx_exe\n";
+	}
+	# currently mg wont work if we don't generate all the stem idexes
+	# so we generate them whatever, but don't advertise the fact
+	#if ($self->{'casefold'}) {
+	system ("mg_stem_idx$exe -b 4096 -s1 -f \"$fullindexprefix\" $osextra");
+	#}
+	#if ($self->{'stem'}) {
+	system ("mg_stem_idx$exe -b 4096 -s2 -f \"$fullindexprefix\" $osextra");
+	#}
+	#if ($self->{'casefold'} && $self->{'stem'}) {
+	system ("mg_stem_idx$exe -b 4096 -s3 -f \"$fullindexprefix\" $osextra");
+	#}
+
+	# remove unwanted files
+	my $tmpdir = &util::filename_cat ($self->{'build_dir'}, $indexdir);
+	opendir (DIR, $tmpdir) || die
+	    "mgbuilder::build_index - couldn't read directory $tmpdir\n";
+	foreach my $file (readdir(DIR)) {
+	    next if $file =~ /^\./;
+	    my ($suffix) = $file =~ /\.([^\.]+)$/;
+	    if (defined $suffix && !defined $wanted_index_files{$suffix}) {
+		# delete it!
+		print $outhandle "deleting $file\n" if $self->{'verbosity'} > 2;
+		&util::rm (&util::filename_cat ($tmpdir, $file));
+	    }
+	}
+	closedir (DIR);
+    }
+    print STDERR "</Stage>\n" if $self->{'gli'};
+}
+
+sub build_cfg_extra {
+   my $self = shift(@_);
+   my ($build_cfg) = @_;
+   
+    # get additional stats from mg
+    my $exedir = "$ENV{'GSDLHOME'}/bin/$ENV{'GSDLOS'}";
+    my $exe = &util::get_os_exe ();
+    my $mgstat_exe = &util::filename_cat($exedir, "mgstat$exe");
+
+    my $collect_tail = &util::get_dirsep_tail($self->{'collection'});
+    my $input_file = &util::filename_cat ("text", $collect_tail);
+    if (!-e "$mgstat_exe" || !open (PIPEIN, "mgstat$exe -d \"$self->{'build_dir'}\" -f \"$input_file\" |")) {
+	my $outhandle = $self->{'outhandle'};
+	print $outhandle "Warning: Couldn't open pipe to $mgstat_exe to get additional stats\n";
+    } else {
+	my $line = "";
+	while (defined ($line = <PIPEIN>)) {
+	    if ($line =~ /^Words in collection \[dict\]\s+:\s+(\d+)/) {
+		($build_cfg->{'numwords'}) = $1;
+	    } elsif ($line =~ /^Documents\s+:\s+(\d+)/) {
+		($build_cfg->{'numsections'}) = $1;
+	    }
+	}
+	close PIPEIN;
+    }
+}
+
+1;
+
+
+
Index: /gsdl/stable/perllib/mgbuildproc.pm
===================================================================
--- /gsdl/stable/perllib/mgbuildproc.pm	(revision 20131)
+++ /gsdl/stable/perllib/mgbuildproc.pm	(revision 20131)
@@ -0,0 +1,142 @@
+###########################################################################
+#
+# mgbuildproc.pm -- 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# This document processor outputs a document
+# for mg to process
+
+package mgbuildproc;
+
+
+use basebuildproc;
+use strict;
+
+
+BEGIN {
+    @mgbuildproc::ISA = ('basebuildproc');
+}
+
+sub new {
+    my $class = shift @_;
+    my $self = new basebuildproc (@_);
+    return bless $self, $class;
+}
+
+
+sub find_paragraphs {
+    $_[1] =~ s/(<p\b)/\cC$1/gi;
+}
+
+sub text {
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+    my $handle = $self->{'output_handle'};
+    
+    # only output this document if it is one to be indexed
+    return if ($doc_obj->get_doc_type() ne "indexed_doc");
+    
+    # see if this document belongs to this subcollection
+    my $indexed_doc = $self->is_subcollection_doc($doc_obj);
+
+    # this is another document
+    $self->{'num_docs'} += 1;
+
+    # get the parameters for the output
+    my ($level, $fields) = split (/:/, $self->{'index'});
+    $fields =~ s/\ball\b/Title,Creator,text/;
+    $fields =~ s/\btopall\b/topTitle,topCreator,toptext/;
+
+    my $doc_section = 0; # just for this document
+    my $text = "";
+    my $text_extra = "";
+
+    # get the text for this document
+    my $section = $doc_obj->get_top_section();
+    while (defined $section) {
+	# update a few statistics
+	$doc_section++;
+	$self->{'num_sections'} += 1;
+
+	my $indexed_section = $doc_obj->get_metadata_element($section, "gsdldoctype") || "indexed_section";
+	if (($indexed_doc) && ($indexed_section eq "indexed_section" || $indexed_section eq "indexed_doc")) {
+	    $self->{'num_bytes'} += $doc_obj->get_text_length ($section);
+	    foreach my $field (split (/,/, $fields)) {
+		# only deal with this field if it doesn't start with top or
+		# this is the first section
+		my $real_field = $field;
+		if (!($real_field =~ s/^top//) || ($doc_section == 1)) {
+		    my $new_text = "";
+		    if ($level eq "dummy") {
+			# a dummy index is a special case used when no
+			# indexes are specified (since there must always be
+			# at least one index or we can't retrieve the
+			# compressed text) - we add a small amount of text
+			# to these dummy indexes which will never be seen
+			# but will overcome mg's problems with building
+			# empty indexes
+			$new_text = "this is dummy text to stop mg barfing";
+			$self->{'num_processed_bytes'} += length ($new_text);
+
+		    } elsif ($real_field eq "text") {
+			$new_text = $doc_obj->get_text ($section) if $self->{'store_text'};
+			$self->{'num_processed_bytes'} += length ($new_text);
+			$new_text =~ s/[\cB\cC]//g;
+			$self->find_paragraphs($new_text);
+			
+		    } else {
+			my $first = 1;
+			my @section_metadata = @{$doc_obj->get_metadata ($section, $real_field)};
+			if ($level eq "section" && $section ne $doc_obj->get_top_section() && $self->{'indexing_text'} && defined ($self->{'sections_index_document_metadata'})) {
+			    if ($self->{'sections_index_document_metadata'} eq "always" || ( scalar(@section_metadata) == 0 && $self->{'sections_index_document_metadata'} eq "unless_section_metadata_exists")) {
+				push (@section_metadata, @{$doc_obj->get_metadata ($doc_obj->get_top_section(), $real_field)});
+			    }
+			}
+			foreach my $meta (@section_metadata) {
+			    $meta =~ s/[\cB\cC]//g;
+			    $self->{'num_processed_bytes'} += length ($meta);
+			    $new_text .= "\cC" unless $first;
+			    $new_text .= $meta if $self->{'store_text'};
+			    $first = 0;
+			}
+		    }
+		    
+		    # filter the text
+		    $new_text = $self->filter_text ($field, $new_text);
+
+		    $text .= "$new_text\cC";
+		}
+	    }
+	}
+	
+	if ($level eq "document") { $text_extra .= "\cB"; }
+	else { $text .= "\cB"; }
+	
+	$section = $doc_obj->get_next_section($section);
+    }
+
+    print $handle "$text$text_extra";
+}
+
+1;
+
Index: /gsdl/stable/perllib/mgppbuilder.pm
===================================================================
--- /gsdl/stable/perllib/mgppbuilder.pm	(revision 20131)
+++ /gsdl/stable/perllib/mgppbuilder.pm	(revision 20131)
@@ -0,0 +1,828 @@
+###########################################################################
+#
+# mgppbuilder.pm -- MGBuilder object
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package mgppbuilder;
+
+use basebuilder;
+use colcfg;
+use plugin;
+use strict; no strict 'refs';
+use util;
+
+
+sub BEGIN {
+    @mgppbuilder::ISA = ('basebuilder');
+}
+
+
+
+our %level_map = ('document'=>'Doc',
+	      'section'=>'Sec',
+	      'paragraph'=>'Para',
+	      'Doc'=>'_textdocument_',
+	      'Sec'=>'_textsection_',
+	      'Para'=>'_textparagraph_');
+
+our %wanted_index_files = ('td'=>1,
+		       't'=>1,
+		       'tl'=>1,
+		       'ti'=>1,
+		       'idb'=>1,
+		       'ib1'=>1,
+		       'ib2'=>1,
+		       'ib3'=>1,
+		       'ib4'=>1,
+		       'ib5'=>1,
+		       'ib6'=>1,
+		       'ib7'=>1,
+		       'i'=>1,
+		       'il'=>1,
+		       'w'=>1,
+		       'wa'=>1);
+
+
+my $maxdocsize = $basebuilder::maxdocsize;
+
+sub new {
+    my $class = shift(@_);
+
+    my $self = new basebuilder (@_);
+    $self = bless $self, $class;
+
+    #$self->{'indexfieldmap'} = \%static_indexfield_map;
+
+    # get the levels (Section, Paragraph) for indexing and compression
+    $self->{'levels'} = {};
+    $self->{'levelorder'} = ();
+    if (defined $self->{'collect_cfg'}->{'levels'}) {
+        foreach my $level ( @{$self->{'collect_cfg'}->{'levels'}} ){
+	    $level =~ tr/A-Z/a-z/;
+            $self->{'levels'}->{$level} = 1;
+	    push (@{$self->{'levelorder'}}, $level);
+        }
+    } else { # default to document
+	$self->{'levels'}->{'document'} = 1;
+	push (@{$self->{'levelorder'}}, 'document');
+    }
+    
+    $self->{'buildtype'} = "mgpp";
+
+    return $self;
+}
+
+sub generate_index_list {
+    my $self  = shift (@_);
+    
+    # sort out the indexes
+    #indexes are specified with spaces, but we put them into one index
+    my $indexes = $self->{'collect_cfg'}->{'indexes'};
+    if (defined $indexes) {
+	$self->{'collect_cfg'}->{'indexes'} = [];
+	push (@{$self->{'collect_cfg'}->{'indexes'}}, join(';', @$indexes).";");
+    }
+}
+
+sub generate_index_options {
+    my $self = shift (@_);
+
+    $self->SUPER::generate_index_options();
+
+    $self->{'casefold'} = 0;
+    $self->{'stem'} = 0;
+    $self->{'accentfold'} = 0; 
+    
+    if (!defined($self->{'collect_cfg'}->{'indexoptions'})) {
+	# just use default options
+	$self->{'casefold'} = 1;
+	$self->{'stem'} = 1;
+	$self->{'accentfold'} = 1;
+    } else {
+	foreach my $option (@{$self->{'collect_cfg'}->{'indexoptions'}}) {
+	    if ($option =~ /stem/) {
+		$self->{'stem'} = 1;
+	    } elsif ($option =~ /casefold/) {
+		$self->{'casefold'} = 1;
+	    } elsif ($option =~ /accentfold/) {
+		$self->{'accentfold'} = 1;
+	    }
+	}
+    }
+    
+    # now we record this for the build cfg
+    $self->{'stemindexes'} = 0;
+    if ($self->{'casefold'}) {
+	$self->{'stemindexes'} += 1;
+    }
+    if ($self->{'stem'}) {
+	$self->{'stemindexes'} += 2;
+    }
+    if ($self->{'accentfold'}) {
+	$self->{'stemindexes'} += 4;
+    }
+    
+}
+
+sub default_buildproc {
+    my $self  = shift (@_);
+
+    return "mgppbuildproc";
+}
+
+sub compress_text {
+
+    my $self = shift (@_);
+
+    # we don't do anything if we don't want compressed text
+    return if $self->{'no_text'};
+    
+    my ($textindex) = @_;
+
+    my $exedir = "$ENV{'GSDLHOME'}/bin/$ENV{'GSDLOS'}";
+    my $exe = &util::get_os_exe ();
+    my $mgpp_passes_exe = &util::filename_cat($exedir, "mgpp_passes$exe");
+    my $mgpp_compression_dict_exe = &util::filename_cat($exedir, "mgpp_compression_dict$exe");
+    my $outhandle = $self->{'outhandle'};
+
+    my $maxnumeric = $self->{'maxnumeric'};
+    
+    &util::mk_all_dir (&util::filename_cat($self->{'build_dir'}, "text"));
+
+    my $collect_tail = &util::get_dirsep_tail($self->{'collection'});
+    my $basefilename = &util::filename_cat("text",$collect_tail);
+    my $fulltextprefix = &util::filename_cat ($self->{'build_dir'}, $basefilename);
+    
+    my $osextra = "";
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	$fulltextprefix =~ s@/@\\@g;
+    } 
+    else {
+	$osextra = " -d /";
+    }
+
+
+    # define the section names and possibly the doc name for mgpasses
+    # the compressor doesn't need to know about paragraphs - never want to 
+    # retrieve them
+    
+    # always use Doc and Sec levels
+    my $mgpp_passes_sections = "-J ". $level_map{"document"} ." -K " . $level_map{"section"} ." ";
+
+    print $outhandle "\n*** creating the compressed text\n" if ($self->{'verbosity'} >= 1);
+    print STDERR "<Stage name='CompressText'>\n" if $self->{'gli'};
+
+    # collect the statistics for the text
+    # -b $maxdocsize sets the maximum document size to be 12 meg
+    print $outhandle "\n    collecting text statistics (mgpp_passes -T1)\n"  if ($self->{'verbosity'} >= 1);
+    print STDERR "<Phase name='CollectTextStats'/>\n" if $self->{'gli'};
+
+    my ($handle);
+    if ($self->{'debug'}) {
+	$handle = *STDOUT;
+    }
+    else {
+	if (!-e "$mgpp_passes_exe" || 
+	    !open($handle, "| mgpp_passes$exe  -M $maxnumeric $mgpp_passes_sections -f \"$fulltextprefix\" -T1 $osextra")) {
+	    print STDERR "<FatalError name='NoRunMGPasses'>\n</Stage>\n" if $self->{'gli'};
+	    die "mgppbuilder::compress_text - couldn't run $mgpp_passes_exe\n";
+	}
+    }
+    
+    my $db_level = "section";
+
+    $self->{'buildproc'}->set_output_handle ($handle);
+    $self->{'buildproc'}->set_mode ('text');
+    $self->{'buildproc'}->set_index ($textindex);
+    $self->{'buildproc'}->set_indexing_text (0);
+    #$self->{'buildproc'}->set_indexfieldmap ($self->{'indexfieldmap'});
+    $self->{'buildproc'}->set_levels ($self->{'levels'});                      
+    $self->{'buildproc'}->set_db_level ($db_level);                       
+    $self->{'buildproc'}->reset();
+    &plugin::begin($self->{'pluginfo'}, $self->{'source_dir'}, 
+		   $self->{'buildproc'}, $self->{'maxdocs'});
+    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'}, 
+		   "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'}, 0, $self->{'gli'});
+    &plugin::end($self->{'pluginfo'});
+
+    close ($handle) unless $self->{'debug'};
+
+    $self->print_stats();
+
+    # create the compression dictionary
+    # the compression dictionary is built by assuming the stats are from a seed
+    # dictionary (-S), if a novel word is encountered it is spelled out (-H),
+    # and the resulting dictionary must be less than 5 meg with the most 
+    # frequent words being put into the dictionary first (-2 -k 5120)
+    # note: these options are left over from mg version
+    if (!$self->{'debug'}) {
+	print $outhandle "\n    creating the compression dictionary\n"  if ($self->{'verbosity'} >= 1);
+	print STDERR "<Phase name='CreatingCompress'/>\n" if $self->{'gli'};
+	if (!-e "$mgpp_compression_dict_exe") {
+	    print STDERR "<FatalError name='NoRunMGCompress'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgppbuilder::compress_text - couldn't run $mgpp_compression_dict_exe\n";
+	}
+	system ("mgpp_compression_dict$exe -f \"$fulltextprefix\" -S -H -2 -k 5120 $osextra");
+
+	if (!$self->{'debug'}) {
+	    if (!-e "$mgpp_passes_exe" || 
+		!open ($handle, "| mgpp_passes$exe  -M $maxnumeric $mgpp_passes_sections -f \"$fulltextprefix\" -T2 $osextra")) {
+		print STDERR "<FatalError name='NoRunMGPasses'/>\n</Stage>\n" if $self->{'gli'};
+		die "mgppbuilder::compress_text - couldn't run $mgpp_passes_exe\n";
+	    }
+	}
+    }
+    else {
+	print STDERR "<Phase name='SkipCreatingComp'/>\n" if $self->{'gli'};
+    }
+
+    $self->{'buildproc'}->reset();
+    # compress the text
+    print $outhandle "\n    compressing the text (mgpp_passes -T2)\n"  if ($self->{'verbosity'} >= 1);
+    print STDERR "<Phase name='CompressingText'/>\n" if $self->{'gli'};
+
+    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'}, 
+		   "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'}, 0, $self->{'gli'});
+    close ($handle) unless $self->{'debug'};
+
+    $self->print_stats();
+    print STDERR "</Stage>\n" if $self->{'gli'};
+}
+
+
+sub build_indexes_extra {
+    my $self = shift(@_);
+    #define the final field lists
+    $self->make_final_field_list();
+}    
+
+# creates directory names for each of the index descriptions
+sub create_index_mapping {
+    my $self = shift (@_);
+    my ($indexes) = @_;
+
+    my %mapping = ();
+
+    return \%mapping if !(scalar @$indexes);
+
+    $mapping{'indexmaporder'} = [];
+    $mapping{'subcollectionmaporder'} = [];
+    $mapping{'languagemaporder'} = [];
+    
+    # dirnames is used to check for collisions. Start this off
+    # with the manditory directory names
+    my %dirnames = ('text'=>'text',
+		    'extra'=>'extra');
+    my %pnames = ('index' => {}, 'subcollection' => {}, 'languages' => {});
+
+    foreach my $index (@$indexes) {
+	my ($fields, $subcollection, $languages) = split (":", $index);
+	
+	# we only ever have one index, and its called 'idx'
+	my $pindex = 'idx';
+	
+	# next comes a processed version of the subcollection if there is one.
+	my $psub = $self->process_field ($subcollection);
+	$psub = lc ($psub);
+
+	# next comes a processed version of the language if there is one.
+	my $plang = $self->process_field ($languages);
+	$plang = lc ($plang);
+
+	my $dirname = $pindex . $psub . $plang;
+
+	# check to be sure all index names are unique
+	while (defined ($dirnames{$dirname})) {
+	    $dirname = $self->make_unique (\%pnames, $index, \$pindex, \$psub, \$plang);
+	}
+
+	$mapping{$index} = $dirname;
+
+	# store the mapping orders as well as the maps
+	# also put index, subcollection and language fields into the mapping thing - 
+	# (the full index name (eg text:subcol:lang) is not used on
+	# the query page) -these are used for collectionmeta later on
+	if (!defined $mapping{'indexmap'}{"$fields"}) {
+	    $mapping{'indexmap'}{"$fields"} = $pindex;
+	    push (@{$mapping{'indexmaporder'}}, "$fields");
+	    if (!defined $mapping{"$fields"}) {
+		$mapping{"$fields"} = $pindex;
+	    }	
+	}
+	if ($psub =~ /\w/ && !defined ($mapping{'subcollectionmap'}{$subcollection})) {
+	    $mapping{'subcollectionmap'}{$subcollection} = $psub;
+	    push (@{$mapping{'subcollectionmaporder'}}, $subcollection);
+	    $mapping{$subcollection} = $psub;
+	}
+	if ($plang =~ /\w/ && !defined ($mapping{'languagemap'}{$languages})) {
+	    $mapping{'languagemap'}{$languages} = $plang;
+	    push (@{$mapping{'languagemaporder'}}, $languages);
+	    $mapping{$languages} = $plang;
+	}
+	$dirnames{$dirname} = $index;
+	$pnames{'index'}->{$pindex} = "$fields";
+	$pnames{'subcollection'}->{$psub} = $subcollection;
+	$pnames{'languages'}->{$plang} = $languages;
+    }
+
+    return \%mapping;
+}
+
+sub make_unique {
+    my $self = shift (@_);
+    my ($namehash, $index, $indexref, $subref, $langref) = @_;
+    my ($fields, $subcollection, $languages) = split (":", $index);
+
+    if ($namehash->{'index'}->{$$indexref} ne "$fields") {
+	$self->get_next_version ($indexref);
+    } elsif ($namehash->{'subcollection'}->{$$subref} ne $subcollection) {
+	$self->get_next_version ($subref);
+    } elsif ($namehash->{'languages'}->{$$langref} ne $languages) {
+	$self->get_next_version ($langref);
+    }
+    return "$$indexref$$subref$$langref";
+}	
+
+
+sub build_index {
+    my $self = shift (@_);
+    my ($index) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    # get the full index directory path and make sure it exists
+    my $indexdir = $self->{'index_mapping'}->{$index};
+    &util::mk_all_dir (&util::filename_cat($self->{'build_dir'}, $indexdir));
+
+    my $collect_tail = &util::get_dirsep_tail($self->{'collection'});
+    my $fullindexprefix = &util::filename_cat ($self->{'build_dir'}, 
+					       $indexdir, 
+					       $collect_tail);
+    my $fulltextprefix = &util::filename_cat ($self->{'build_dir'}, "text", 
+					       $collect_tail);
+
+    # get any os specific stuff
+    my $exedir = "$ENV{'GSDLHOME'}/bin/$ENV{'GSDLOS'}";
+
+    my $exe = &util::get_os_exe ();
+    my $mgpp_passes_exe = &util::filename_cat($exedir, "mgpp_passes$exe");
+
+    # define the section names for mgpasses
+    my $mgpp_passes_sections = "-J ". $level_map{"document"} ." -K " . $level_map{"section"} ." ";
+    if ($self->{'levels'}->{'paragraph'}) {
+	$mgpp_passes_sections .= "-K " . $level_map{'paragraph'}. " ";
+    }
+
+    my $mgpp_perf_hash_build_exe = 
+	&util::filename_cat($exedir, "mgpp_perf_hash_build$exe");
+    my $mgpp_weights_build_exe = 
+	&util::filename_cat ($exedir, "mgpp_weights_build$exe");
+    my $mgpp_invf_dict_exe = 
+	&util::filename_cat ($exedir, "mgpp_invf_dict$exe");
+    my $mgpp_stem_idx_exe =
+	&util::filename_cat ($exedir, "mgpp_stem_idx$exe");
+
+    my $maxnumeric = $self->{'maxnumeric'};
+
+    my $osextra = "";
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	$fullindexprefix =~ s@/@\\@g;
+    } else {
+	$osextra = " -d /";
+	if ($outhandle ne "STDERR") {
+	    # so mgpp_passes doesn't print to stderr if we redirect output
+	    $osextra .= " 2>/dev/null";
+	}
+    }
+ 
+    # get the index expression if this index belongs
+    # to a subcollection
+    my $indexexparr = [];
+    my $langarr = [];
+    # there may be subcollection info, and language info. 
+    my ($fields, $subcollection, $language) = split (":", $index);
+    my @subcollections = ();
+    @subcollections = split /,/, $subcollection if (defined $subcollection);
+
+    foreach $subcollection (@subcollections) {
+	if (defined ($self->{'collect_cfg'}->{'subcollection'}->{$subcollection})) {
+	    push (@$indexexparr, $self->{'collect_cfg'}->{'subcollection'}->{$subcollection});
+	} 
+    }
+    
+    # add expressions for languages if this index belongs to
+    # a language subcollection - only put languages expressions for the 
+    # ones we want in the index
+    
+    my @languages = ();
+    my $language_metadata = "Language";
+    if (defined ($self->{'collect_cfg'}->{'language_metadata'})) {
+	$language_metadata = $self->{'collect_cfg'}->{'language_metadata'};
+    }
+    @languages = split /,/, $language if (defined $language);
+    foreach my $language (@languages) {
+	my $not=0;
+	if ($language =~ s/^\!//) {
+	    $not = 1;
+	}
+	if($not) {
+	    push (@$langarr, "!$language");
+	} else {
+	    push (@$langarr, "$language");
+	}
+    }
+
+    # Build index dictionary. Uses verbatim stem method
+    print $outhandle "\n    creating index dictionary (mgpp_passes -I1)\n"  if ($self->{'verbosity'} >= 1);
+    print STDERR "<Phase name='CreatingIndexDic'/>\n" if $self->{'gli'};
+    my ($handle);
+    if ($self->{'debug'}) {
+	$handle = *STDOUT;
+    }
+    else {
+	if (!-e "$mgpp_passes_exe" || 
+	    !open($handle, "| mgpp_passes$exe -M $maxnumeric $mgpp_passes_sections -f \"$fullindexprefix\" -I1 $osextra")) {
+	    print STDERR "<FatalError name='NoRunMGPasses'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgppbuilder::build_index - couldn't run $mgpp_passes_exe\n";
+	}
+    }
+	    
+    # db_level is always section
+    my $db_level = "section";
+
+    # set up the document processr
+    $self->{'buildproc'}->set_output_handle ($handle);
+    $self->{'buildproc'}->set_mode ('text');
+    $self->{'buildproc'}->set_index ($index, $indexexparr);
+    $self->{'buildproc'}->set_index_languages ($language_metadata, $langarr) if (defined $language);
+    $self->{'buildproc'}->set_indexing_text (1);
+    #$self->{'buildproc'}->set_indexfieldmap ($self->{'indexfieldmap'});
+    $self->{'buildproc'}->set_levels ($self->{'levels'}); 
+    $self->{'buildproc'}->set_db_level ($db_level);   
+    
+    $self->{'buildproc'}->reset();
+    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'}, 
+		   "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'}, 0, $self->{'gli'});
+    close ($handle) unless $self->{'debug'};
+
+    $self->print_stats();
+
+    # now we check to see if the required files have been produced - if not we quit building this index so the whole process doesn't crap out.
+    # we check on the .id file - index dictionary
+    my $dict_file = "$fullindexprefix.id";
+    if (!-e $dict_file) {
+	print $outhandle "mgppbuilder::build_index - Couldn't create index $index\n";
+	print STDERR "<Warning name='NoIndex'/>\n</Stage>\n" if $self->{'gli'};
+	$self->{'notbuilt'}->{$index}=1;
+	return;
+    }
+
+    if (!$self->{'debug'}) {
+	# create the perfect hash function
+	if (!-e "$mgpp_perf_hash_build_exe") {
+	    print STDERR "<FatalError name='NoRunMGHash'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgppbuilder::build_index - couldn't run $mgpp_perf_hash_build_exe\n";
+	}
+	system ("mgpp_perf_hash_build$exe -f \"$fullindexprefix\" $osextra");
+
+	if (!-e "$mgpp_passes_exe" || 
+	    !open ($handle, "| mgpp_passes$exe -M $maxnumeric $mgpp_passes_sections -f \"$fullindexprefix\" -I2 $osextra")) {
+	    print STDERR "<FatalError name='NoRunMGPasses'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgppbuilder::build_index - couldn't run $mgpp_passes_exe\n";
+	}
+    }
+    
+    # invert the text
+    print $outhandle "\n    inverting the text (mgpp_passes -I2)\n"  if ($self->{'verbosity'} >= 1);
+    print STDERR "<Phase name='InvertingText'/>\n" if $self->{'gli'};
+    $self->{'buildproc'}->reset();
+    &plugin::read ($self->{'pluginfo'}, $self->{'source_dir'}, 
+		   "", {}, {}, $self->{'buildproc'}, $self->{'maxdocs'}, 0, $self->{'gli'});
+
+    $self->print_stats ();
+    
+    if (!$self->{'debug'}) {
+
+	close ($handle);
+	
+	# create the weights file
+	print $outhandle "\n    create the weights file\n"  if ($self->{'verbosity'} >= 1);
+	print STDERR "<Phase name='CreateTheWeights'/>\n" if $self->{'gli'};
+	if (!-e "$mgpp_weights_build_exe") {
+	    print STDERR "<FatalError name='NoRunMGWeights'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgppbuilder::build_index - couldn't run $mgpp_weights_build_exe\n";
+	}
+	system ("mgpp_weights_build$exe -f \"$fullindexprefix\" $osextra");
+
+	# create 'on-disk' stemmed dictionary
+	print $outhandle "\n    creating 'on-disk' stemmed dictionary\n"  if ($self->{'verbosity'} >= 1);
+	if (!-e "$mgpp_invf_dict_exe") {
+	    print STDERR "<FatalError name='NoRunMGInvf'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgppbuilder::build_index - couldn't run $mgpp_invf_dict_exe\n";
+	}
+	system ("mgpp_invf_dict$exe -f \"$fullindexprefix\" $osextra" );
+
+
+	# creates stem index files for the various stemming methods
+	print $outhandle "\n    creating stem indexes\n"  if ($self->{'verbosity'} >= 1);
+	print STDERR "<Phase name='CreatingStemIndx'/>\n" if $self->{'gli'};
+	if (!-e "$mgpp_stem_idx_exe") {
+	    print STDERR "<FatalError name='NoRunMGStem'/>\n</Stage>\n" if $self->{'gli'};
+	    die "mgppbuilder::build_index - couldn't run $mgpp_stem_idx_exe\n";
+	}
+	my $accent_folding_enabled = 1;
+	if ($self->{'accentfold'}) {
+	    # the first time we do this, we test for accent folding enabled
+	    if (system ("mgpp_stem_idx$exe -b 4096 -s4 -f \"$fullindexprefix\" $osextra") == 2) {
+		# accent folding has not been enabled in mgpp
+		$accent_folding_enabled = 0;
+		$self->{'stemindexes'} -= 4;
+	    }
+	}
+	if ($self->{'casefold'}) {
+	    system ("mgpp_stem_idx$exe -b 4096 -s1 -f \"$fullindexprefix\" $osextra");
+	    if ($accent_folding_enabled && $self->{'accentfold'}) {
+		system ("mgpp_stem_idx$exe -b 4096 -s5 -f \"$fullindexprefix\" $osextra");
+	    }
+	}
+	if ($self->{'stem'}) {
+	    system ("mgpp_stem_idx$exe -b 4096 -s2 -f \"$fullindexprefix\" $osextra");
+	    if ($accent_folding_enabled && $self->{'accentfold'}) {
+		system ("mgpp_stem_idx$exe -b 4096 -s6 -f \"$fullindexprefix\" $osextra");
+	    }
+	}
+	if ($self->{'casefold'} && $self->{'stem'}) {
+	    system ("mgpp_stem_idx$exe -b 4096 -s3 -f \"$fullindexprefix\" $osextra");
+	    if ($accent_folding_enabled && $self->{'accentfold'}) {
+		system ("mgpp_stem_idx$exe -b 4096 -s7 -f \"$fullindexprefix\" $osextra");
+	    }
+	}
+
+	# remove unwanted files
+	my $tmpdir = &util::filename_cat ($self->{'build_dir'}, $indexdir);
+	opendir (DIR, $tmpdir) || die
+	    "mgppbuilder::build_index - couldn't read directory $tmpdir\n";
+	foreach my $file (readdir(DIR)) {
+	    next if $file =~ /^\./;
+	    my ($suffix) = $file =~ /\.([^\.]+)$/;
+	    if (defined $suffix && !defined $wanted_index_files{$suffix}) {
+		# delete it!
+		print $outhandle "deleting $file\n" if $self->{'verbosity'} > 2;
+		#&util::rm (&util::filename_cat ($tmpdir, $file));
+	    }
+	}
+	closedir (DIR);
+    }
+    print STDERR "</Stage>\n" if $self->{'gli'};
+}   
+
+
+sub get_collection_meta_indexes
+{
+    my $self = shift(@_);
+    my $collection_infodb = shift(@_);
+
+    # define the indexed field mapping if not already done so (ie if infodb called separately from build_index)
+    if (!defined $self->{'build_cfg'}) {
+	$self->read_final_field_list();
+    }
+
+    # first do the collection meta stuff - everything without a dot
+    my $collmetadefined = 0;
+    my $metadata_entry;
+    if (defined $self->{'collect_cfg'}->{'collectionmeta'}) {
+	$collmetadefined = 1;
+    }
+
+    #add the index field macros to [collection]
+    # eg <TI>Title
+    #    <SU>Subject
+    # these now come from collection meta. if that is not defined, uses the metadata name
+    my $collmeta = "";
+    if (defined $self->{'build_cfg'}->{'indexfields'}) {
+	foreach my $longfield (@{$self->{'build_cfg'}->{'indexfields'}}){
+	    my $shortfield = $self->{'buildproc'}->{'indexfieldmap'}->{$longfield};
+	    next if $shortfield eq 1;
+	    
+	    # we need to check if some coll meta has been defined - don't output 
+	    # any that have
+	    $collmeta = ".$longfield";
+	    if (!$collmetadefined || !defined $self->{'collect_cfg'}->{'collectionmeta'}->{$collmeta}) {
+		if ($longfield eq "allfields") {
+		    $collection_infodb->{$shortfield} = [ "_query:textallfields_" ];
+		} elsif ($longfield eq "text") {
+		    $collection_infodb->{$shortfield} = [ "_query:texttextonly_" ];
+		} else {
+		    $collection_infodb->{$shortfield} = [ $longfield ];
+		}
+	    }
+	}
+    }
+
+    # now add the level names
+    my $level_entry = "";
+    foreach my $level (@{$self->{'collect_cfg'}->{'levels'}}) {
+	$collmeta = ".$level"; # based on the original specification
+	$level =~ tr/A-Z/a-z/; # make it lower case
+	my $levelid = $level_map{$level}; # find the actual value we used in the index
+	if (!$collmetadefined || !defined $self->{'collect_cfg'}->{'collectionmeta'}->{$collmeta}) {
+	    # use the default macro
+	    $collection_infodb->{$levelid} = [ $level_map{$levelid} ];
+	}
+    }
+    
+    # now add subcoll meta
+    my $subcoll_entry = "";
+    my $shortname = "";
+    my $one_entry = "";
+    foreach my $subcoll (@{$self->{'index_mapping'}->{'subcollectionmaporder'}}) {
+	$shortname = $self->{'index_mapping'}->{$subcoll};
+	if (!$collmetadefined || !defined $self->{'collect_cfg'}->{'collectionmeta'}->{".$subcoll"}) {
+	    $collection_infodb->{$shortname} = [ $subcoll ];
+	}
+    }
+
+    # now add language meta
+    my $lang_entry = "";
+    foreach my $lang (@{$self->{'index_mapping'}->{'languagemaporder'}}) {
+	$shortname = $self->{'index_mapping'}->{$lang};
+	if (!$collmetadefined || !defined $self->{'collect_cfg'}->{'collectionmeta'}->{".$lang"}) {
+	    $collection_infodb->{$shortname} = [ $lang ];
+	}
+    }
+}
+
+
+# default is to output the metadata sets (prefixes) used in collection
+sub output_collection_meta
+{
+    my $self = shift(@_);
+    my $infodb_handle = shift(@_);
+
+    my %collection_infodb = ();
+    $self->get_collection_meta_sets(\%collection_infodb);
+    $self->get_collection_meta_indexes(\%collection_infodb);
+    &dbutil::write_infodb_entry($self->{'infodbtype'}, $infodb_handle, "collection", \%collection_infodb);
+}
+
+
+# at the end of building, we have an indexfieldmap with all the mappings,
+# plus some extras, and indexmap with any indexes in it that weren't
+# specified in the index definition.  we want to make an ordered list of
+# fields that are indexed, and a list of mappings that are used. this will
+# be used for the build.cfg file, and for collection meta definition we
+# store these in a build.cfg bit
+sub make_final_field_list {
+    my $self = shift (@_);
+    
+    $self->{'build_cfg'} = {};
+    
+    # store the indexfieldmap information
+    my @indexfieldmap = ();
+    my @indexfields = ();
+    my $specifiedfields = {};
+    my @specifiedfieldorder = ();
+
+    # go through the index definition and add each thing to a map, so we
+    # can easily check if it is already specified - when doing the
+    # metadata, we print out all the individual fields, but some may
+    # already be specified in the index definition, so we dont want to add
+    # those again.
+
+    my $field;
+    foreach $field (@{$self->{'collect_cfg'}->{'indexes'}}) {
+	# remove subcoll stuff
+	my $parts = $field;
+	$parts =~ s/:.*$//;
+	# *************
+	my @fs = split(';', $parts);
+	foreach my $f(@fs) {
+	    if (!defined $specifiedfields->{$f}) {
+		$specifiedfields->{$f}=1;
+		push (@specifiedfieldorder, "$f");
+	    }
+	}
+    }
+    
+    #add all fields bit 
+    my $ifm = $self->{'buildproc'}->{'indexfieldmap'};
+    
+    foreach $field (@specifiedfieldorder) {
+	if ($field eq "metadata") {
+	    foreach my $newfield (keys %{$self->{'buildproc'}->{'indexfields'}}) {
+		if (!defined $specifiedfields->{$newfield}) {
+		    push (@indexfieldmap, "$newfield\-\>$self->{'buildproc'}->{'indexfieldmap'}->{$newfield}");
+		    push (@indexfields, "$newfield");
+		}
+	    }
+
+	} elsif ($field eq 'text') {
+	    push (@indexfieldmap, "text\-\>TX");
+	    push (@indexfields, "text");
+	} elsif ($field eq 'allfields') {
+	    push (@indexfieldmap, "allfields\-\>ZZ");
+	    push (@indexfields, "allfields");
+	} else {
+	    # we only add in the ones that have been processed
+	    if (defined $ifm->{$field}) {
+		push (@indexfieldmap, "$field\-\>$ifm->{$field}");
+		push (@indexfields, "$field");
+	    }
+
+	    
+	}
+    }
+
+    if (scalar @indexfieldmap) {
+	$self->{'build_cfg'}->{'indexfieldmap'} = \@indexfieldmap;
+    }
+    if (scalar @indexfields) {
+	$self->{'build_cfg'}->{'indexfields'} = \@indexfields;
+    }
+}
+
+
+# recreate the field list from the build.cfg file, look first in building,
+# then in index to find it. if there is no build.cfg, we can't do the field
+# list (there is unlikely to be any index anyway.)
+sub read_final_field_list {
+    my $self = shift (@_);
+    $self->{'build_cfg'} = {};
+    my @indexfieldmap = ();
+    my @indexfields = ();
+    my @indexmap = ();
+
+    # we read the stuff in from the build.cfg file - if its there
+    my $buildcfg = $self->read_build_cfg();
+    return unless defined $buildcfg;
+
+    my $field;
+    if (defined $buildcfg->{'indexfields'}) {
+	foreach $field (@{$buildcfg->{'indexfields'}}) {
+	    push (@indexfields, "$field");
+	}
+    }
+
+    if (defined $buildcfg->{'indexfieldmap'}) {
+	foreach $field (@{$buildcfg->{'indexfieldmap'}}) {
+	    push (@indexfieldmap, "$field");
+	    my ($f, $v) = $field =~ /^(.*)\-\>(.*)$/;
+	    $self->{'buildproc'}->{'indexfieldmap'}->{$f} = $v;
+	}
+    }	    
+
+    if (defined $buildcfg->{'indexmap'}) {
+	foreach $field (@{$buildcfg->{'indexmap'}}) {
+	    push (@indexmap, "$field");
+	}
+    }	    
+
+    $self->{'build_cfg'}->{'indexfieldmap'} = \@indexfieldmap;
+    $self->{'build_cfg'}->{'indexfields'} = \@indexfields;
+    $self->{'build_cfg'}->{'indexmap'} = \@indexmap;
+}
+
+
+sub build_cfg_extra {
+    my $self = shift (@_);
+    my ($build_cfg) = @_;
+
+    $build_cfg->{'numsections'} = $self->{'buildproc'}->get_num_sections();
+    
+    # store the level info
+    my @indexlevels = ();
+    my @levelmap = ();
+    foreach my $l (@{$self->{'levelorder'}}) {
+	push (@indexlevels, $level_map{$l});
+	push (@levelmap, "$l\-\>$level_map{$l}");
+    }
+    $build_cfg->{'indexlevels'} = \@indexlevels;
+    $build_cfg->{'levelmap'} = \@levelmap;
+
+    # text level (and database level) is always section
+    $build_cfg->{'textlevel'} = $level_map{'section'};
+   
+}
+
+1;
+
+
Index: /gsdl/stable/perllib/mgppbuildproc.pm
===================================================================
--- /gsdl/stable/perllib/mgppbuildproc.pm	(revision 20131)
+++ /gsdl/stable/perllib/mgppbuildproc.pm	(revision 20131)
@@ -0,0 +1,462 @@
+###########################################################################
+#
+# mgppbuildproc.pm -- 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# This document processor outputs a document
+# for mgpp to process
+
+
+package mgppbuildproc;
+
+use basebuildproc;
+use cnseg;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+
+BEGIN {
+    @mgppbuildproc::ISA = ('basebuildproc');
+}
+
+#this must be the same as in mgppbuilder
+our %level_map = ('document'=>'Doc',
+		  'section'=>'Sec',
+		  'paragraph'=>'Para');
+
+# change this so a user can add their own ones in via a file or cfg
+#add AND, OR, NOT NEAR to this list - these cannot be used as field names
+#also add the level names (Doc, Sec, Para)
+our %static_indexfield_map = ('Title'=>'TI',
+			  'TI'=>1,
+			  'Subject'=>'SU',
+			  'SU'=>1,
+			  'Creator'=>'CR',
+			  'CR'=>1,
+			  'Organization'=>'ORG',
+			  'ORG'=>1,
+			  'Source'=>'SO',
+			  'SO'=>1,
+			  'Howto'=>'HT',
+			  'HT'=>1,
+			  'ItemTitle'=>'IT',
+			  'IT'=>1,
+			  'ProgNumber'=>'PN',
+			  'PN'=>1,
+			  'People'=>'PE',
+			  'PE'=>1,
+			  'Coverage'=>'CO',
+			  'CO'=>1,
+			  'allfields'=>'ZZ',
+			  'ZZ'=>1,
+			  'text'=>'TX',
+			  'TX'=>1,
+			  'AND'=>1,
+			  'OR'=>1,
+			  'NOT'=>1,
+			  'NEAR'=>1,
+			  'Doc'=>1,
+			  'Sec'=>1,
+			  'Para'=>1);
+
+
+sub new {
+    my $class = shift @_;
+    my $self = new basebuildproc (@_);
+
+    # use a different index specification to the default
+    $self->{'index'} = "text";
+
+    $self->{'dontindex'} = {};
+    $self->{'indexfieldmap'} = {};
+    $self->{'indexfields'} = {}; # only put in the ones that are not specified directly in the index
+    $self->{'strip_html'}=1;
+    
+    return bless $self, $class;
+}
+
+
+#sub set_indexfieldmap {
+#    my $self = shift (@_);
+#    my ($indexmap) = @_;
+
+#    $self->{'default_index_field_mapping'} = $indexmap;
+    #$self->{'indexfieldmap'} = $indexmap;
+#}
+
+sub get_indexfieldmap {
+    my $self = shift (@_);
+
+    return $self->{'indexfieldmap'};
+}
+
+sub set_levels {
+    my $self = shift (@_);
+    my ($levels) = @_;
+
+    $self->{'levels'} = $levels;
+}
+
+sub set_strip_html {
+    my $self = shift (@_);
+    my ($strip) = @_;
+    $self->{'strip_html'}=$strip;
+}
+
+#sub find_paragraphs {
+#    $_[1] =~ s/(<p\b)/<Paragraph>$1/gi;
+#}
+
+sub remove_gtlt {
+    my $self =shift(@_);
+    my ($text, $para) = @_;
+    $text =~s/[<>]//g;
+    return "$para$text$para";
+}
+
+sub process_tags {
+    my $self = shift(@_);
+    my ($text, $para) = @_;
+    if ($text =~ /^p\b/i) {
+	return $para;
+    }
+    return "";
+}
+
+sub preprocess_text {
+    my $self = shift (@_);
+    my ($text, $strip_html, $para) = @_;
+    # at this stage, we do not do paragraph tags unless have strip_html - 
+    # it will result in a huge mess of non-xml
+    return unless $strip_html;
+    
+    my $new_text = $text;
+    
+    # if we have <pre> tags, we can have < > inside them, need to delete 
+    # the <> before stripping tags
+    $new_text =~ s/<pre>(.*?)<\/pre>/$self->remove_gtlt($1,$para)/gse;
+   
+    if ($para eq "") {
+	# just remove all tags
+	$new_text =~ s/<[^>]*>//gs;
+    } else {
+	# strip all tags except <p> tags which get turned into $para
+	$new_text =~ s/<([^>]*)>/$self->process_tags($1, $para)/gse;
+	
+    }
+    return $new_text;
+}
+#this function strips the html tags from the doc if ($strip_html) and
+# if ($para) replaces <p> with <Paragraph> tags.
+# if both are false, the original text is returned
+#assumes that <pre> and </pre> have no spaces, and removes all < and > inside
+#these tags
+sub preprocess_text_old_and_slow {
+    my $self = shift (@_);
+    my ($text, $strip_html, $para) = @_;
+    my ($outtext) = "";
+    if ($strip_html) { 
+	while ($text =~ /<([^>]*)>/ && $text ne "") {
+	    
+	    my $tag = $1;
+	    $outtext .= $`." "; #add everything before the matched tag
+	    $text = $'; #'everything after the matched tag
+	    if ($para && $tag =~ /^\s*p\s/i) {
+		$outtext .= $para;
+	    }
+	    elsif ($tag =~ /^pre$/) { # a pre tag
+		$text =~ /<\/pre>/; # find the closing pre tag
+		my $tmp_text = $`; #everything before the closing pre tag
+		$text = $'; #'everything after the </pre>
+		$tmp_text =~ s/[<>]//g; # remove all < and >
+		$outtext.= $tmp_text . " ";
+	    }
+	}
+    
+	$outtext .= $text; # add any remaining text
+	return $outtext;
+    } #if strip_html
+
+    #if ($para) {
+	#$text =~ s/(<p\b)/$para$1/gi;
+	#return $text;
+   # }
+    return $text;
+}
+	
+sub text {
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+    my $handle = $self->{'output_handle'};
+    my $outhandle = $self->{'outhandle'};
+
+    # only output this document if it is one to be indexed
+    return if ($doc_obj->get_doc_type() ne "indexed_doc");
+    
+    my $indexed_doc = $self->is_subcollection_doc($doc_obj);
+    
+    # this is another document
+    $self->{'num_docs'} += 1;
+
+    # get the parameters for the output
+    # split on : just in case there is subcoll and lang stuff
+    my ($fields) = split (/:/, $self->{'index'});
+
+    # we always do text and index on Doc and Sec levels
+    my ($documenttag) = "\n<". $level_map{'document'} . ">\n";
+    my ($documentendtag) = "\n</". $level_map{'document'} . ">\n";
+    my ($sectiontag) = "\n<". $level_map{'section'} . ">\n";
+    my ($sectionendtag) = "\n</". $level_map{'section'} . ">\n";
+
+    my ($paratag) = "";
+    
+    # paragraph tags will only be used for indexing (can't retrieve 
+    # paragraphs), and can ony be used if we are stripping HTML tags
+    if ($self->{'indexing_text'} && $self->{'levels'}->{'paragraph'}) {
+	if ($self->{'strip_html'}) {
+	    $paratag = "<". $level_map{'paragraph'} . ">";
+	} else {
+	    print $outhandle "Paragraph level can not be used with no_strip_html!. Not indexing Paragraphs.\n";
+	}
+    }
+
+    my $doc_section = 0; # just for this document
+    
+    my $text = $documenttag;
+   
+    # get the text for this document
+    my $section = $doc_obj->get_top_section();
+    
+    while (defined $section) {
+	# update a few statistics
+	$doc_section++;
+	$self->{'num_sections'} += 1;
+	$text .= "$sectiontag";
+	
+	my $indexed_section = $doc_obj->get_metadata_element($section, "gsdldoctype") || "indexed_section";
+	if (($indexed_doc == 0) || ($indexed_section ne "indexed_section" && $indexed_section ne "indexed_doc")) {
+	    # we are not actually indexing anything for this document,
+	    # but we want to keep the section numbers the same, so we just
+	    # output section tags for each section (which is done above)
+	    $text .= "$sectionendtag";
+	    $section = $doc_obj->get_next_section($section);
+	    next;
+	}
+	
+	$self->{'num_bytes'} += $doc_obj->get_text_length ($section);
+
+	# has the user added a 'metadata' index?
+	my $all_metadata_specified = 0; 
+	# which fields have already been indexed? (same as fields, but in a map)
+	my $specified_fields = {};
+	foreach my $field (split (/;/, $fields)) {
+	    # only deal with this field if it doesn't start with top or
+	    # this is the first section
+	    my $real_field = $field;
+	    next if (($real_field =~ s/^top//) && ($doc_section != 1));
+	    
+	    my $new_text = ""; 
+
+	    # we get allfields by default - do nothing except add into the map
+	    if ($real_field eq "allfields") {
+		$self->{'indexfieldmap'}->{"allfields"} = "ZZ";
+		$self->{'indexfieldmap'}->{"ZZ"} = 1;
+	    }
+	    
+	    # metadata - output all metadata we know about except gsdl stuff
+	    # each metadata is in a separate index field
+	    if ($real_field eq "metadata") { 
+		# we will process this later, so we are not reindexing metadata already indexed
+		$all_metadata_specified = 1;
+	    }
+	    
+	    else {
+		
+		#individual metadata and or text specified - could be 
+		# a comma separated list
+		$specified_fields->{$real_field} = 1;
+		my $shortname="";
+		my $new_field = 0; # have we found a new field name?
+
+		if (defined $self->{'indexfieldmap'}->{$real_field}) {
+		    $shortname = $self->{'indexfieldmap'}->{$real_field};
+		}
+		else {
+		    $shortname = $self->create_shortname($real_field);
+		    $new_field = 1; # we want to record this shortname, but only if we have actually found some metadata values
+		}
+		my @metadata_list = (); # put any meta values in here
+		my $section_text = ""; # put any text in here
+		foreach my $submeta (split /,/, $real_field) {
+		    if ($submeta eq "text") { 
+			# no point in indexing text more than once
+			if ($section_text eq "") {
+			    $section_text = $doc_obj->get_text($section);
+			    if ($self->{'indexing_text'}) {
+				if ($paratag ne "") {
+				    # we fiddle around with splitting text into paragraphs
+				    $section_text = $self->preprocess_text($section_text, $self->{'strip_html'}, "</$shortname>$paratag<$shortname>");
+				}
+				else {
+				    $section_text = $self->preprocess_text($section_text, $self->{'strip_html'}, "");
+				}
+			    }
+			}
+		    }
+		    else {
+			# its a metadata element
+			my @section_metadata = @{$doc_obj->get_metadata ($section, $submeta)};
+			if ($section ne $doc_obj->get_top_section() && $self->{'indexing_text'} && defined ($self->{'sections_index_document_metadata'})) {
+			    if ($self->{'sections_index_document_metadata'} eq "always" || ( scalar(@section_metadata) == 0 && $self->{'sections_index_document_metadata'} eq "unless_section_metadata_exists")) {
+				push (@section_metadata, @{$doc_obj->get_metadata ($doc_obj->get_top_section(), $submeta)});
+			    }
+			}
+			push (@metadata_list, @section_metadata);
+		    }
+		} # for each field in index
+
+
+		# now we add the text and/or the metadata into new_text
+		if ($section_text ne "" || scalar(@metadata_list)) {
+		    if ($self->{'indexing_text'}) {
+			# only add tags in if indexing
+			$new_text .= "$paratag<$shortname>";
+		    }
+		    if ($section_text ne "") {
+			$new_text .= "$section_text ";
+			if ($self->{'indexing_text'} && $paratag ne "" && scalar(@metadata_list)) {
+			    $new_text .= "</$shortname>$paratag<$shortname>";
+			}
+		    }
+		    foreach my $item (@metadata_list) {
+			$new_text .= "$item ";
+		    }
+		    if ($self->{'indexing_text'}) {
+			# only add tags in if indexing
+			$new_text .= "</$shortname>";
+		    }
+		    if ($self->{'indexing_text'} && $new_field) {
+			# we need to add to the list in indexfields
+
+			$self->{'indexfieldmap'}->{$real_field} = $shortname;
+			$self->{'indexfieldmap'}->{$shortname} = 1;
+		    }
+		}
+	    }
+
+	    # filter the text
+	    $new_text = $self->filter_text ($field, $new_text);
+	    
+	    $self->{'num_processed_bytes'} += length ($new_text);
+	    $text .= "$new_text";
+	} # foreach field
+	
+   	if ($all_metadata_specified) {
+	    my $new_text = "";
+	    my $shortname = "";
+	    my $metadata = $doc_obj->get_all_metadata ($section);
+	    foreach my $pair (@$metadata) {
+		my ($mfield, $mvalue) = (@$pair);
+		# no value
+		next unless defined $mvalue && $mvalue ne "";
+		# we have already indexed this
+		next if defined ($specified_fields->{$mfield});
+		# check fields here, maybe others dont want - change to use dontindex!!
+		next if ($mfield eq "Identifier" || $mfield eq "classifytype" || $mfield eq "assocfilepath");
+		next if ($mfield =~ /^gsdl/);
+		
+			
+		if (defined $self->{'indexfieldmap'}->{$mfield}) {
+		    $shortname = $self->{'indexfieldmap'}->{$mfield};
+		}
+		else {
+		    $shortname = $self->create_shortname($mfield);
+		    $self->{'indexfieldmap'}->{$mfield} = $shortname;
+		    $self->{'indexfieldmap'}->{$shortname} = 1;
+		}	   
+		$new_text .= "$paratag<$shortname>$mvalue</$shortname>\n";
+		if (!defined $self->{'indexfields'}->{$mfield}) {
+		    $self->{'indexfields'}->{$mfield} = 1;
+		}				    
+	    
+	    }
+	    # filter the text
+	    $new_text = $self->filter_text ("metadata", $new_text);
+	    
+	    $self->{'num_processed_bytes'} += length ($new_text);
+	    $text .= "$new_text";
+
+	    
+	}
+    
+	$text .= "$sectionendtag";
+	$section = $doc_obj->get_next_section($section);
+    } # while defined section
+    print $handle "$text\n$documentendtag"; 
+    #print STDERR "***********\n$text\n***************\n";
+    
+}
+
+#chooses the first two letters or digits for the shortname
+#now ignores non-letdig characters
+sub create_shortname {
+    my $self = shift(@_);
+    
+    my ($realname) = @_;
+    # try our predefined static mapping
+    if (defined $static_indexfield_map{$realname}) {
+	return $static_indexfield_map{$realname};
+    }
+    #try the first two chars
+    my $shortname;
+    if ($realname =~ /^[^\w]*(\w)[^\w]*(\w)/) {
+	$shortname = "$1$2";
+    } else {
+	# there aren't two letdig's in the field - try arbitrary combinations
+	$realname = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+	$shortname = "AB";
+    }
+    $shortname =~ tr/a-z/A-Z/;
+
+    #if already used, take the first and third letdigs and so on
+    my $count = 1;
+    while (defined $self->{'indexfieldmap'}->{$shortname} || defined $static_indexfield_map{$shortname}) {
+	if ($realname =~ /^[^\w]*(\w)([^\w]*\w){$count}[^\w]*(\w)/) {
+	    $shortname = "$1$3";
+	    $count++;
+	    $shortname =~ tr/a-z/A-Z/;
+	
+	}
+	else {
+	    #remove up to and incl the first letdig
+	    $realname =~ s/^[^\w]*\w//;
+	    $count = 0;
+	}
+    }
+
+    return $shortname;
+}
+
+1;
+
Index: /gsdl/stable/perllib/multiread.pm
===================================================================
--- /gsdl/stable/perllib/multiread.pm	(revision 20131)
+++ /gsdl/stable/perllib/multiread.pm	(revision 20131)
@@ -0,0 +1,339 @@
+###########################################################################
+#
+# multiread.pm --
+#
+# Copyright (C) 1999 DigiLib Systems Limited, NZ
+# Copyright (C) 2005 New Zealand Digital Library project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# the multiread object will read in a number of encodings,
+# the results are always returned in the utf-8 format
+
+# encodings currently supported are
+#
+# utf8             - either utf8 or unicode (automatically detected)
+# unicode          - 2-byte UCS (does endian detection)
+#
+# plus all encodings in the "encodings" package
+
+package multiread;
+
+eval {require bytes};
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+use unicode;
+
+sub new {
+    my ($class) = @_;
+
+    my $self = {'handle'    => "",
+		'first'     => 1,
+		'encoding'  => "utf8",
+		'bigendian' => 1};
+
+    return bless $self, $class;
+}
+
+# set_handle expects the file to be already open but
+# not read yet
+sub set_handle {
+    my $self = shift;
+    $self->{'handle'} = shift;
+    binmode( $self->{'handle'} );
+    $self->{'first'} = 1;
+    $self->{'encoding'} = "utf8";
+    $self->{'bigendian'} = 1;
+}
+
+# set_encoding should be called after set_handle
+sub set_encoding {
+    my $self = shift;
+    $self->{'encoding'} = shift;
+}
+
+sub get_encoding {
+    my $self = shift (@_);
+    return $self->{'encoding'};
+}
+
+# undef will be returned if the eof has been reached
+# the result will always be returned in utf-8
+
+sub read_unicode_char {
+    my $self = shift (@_);
+
+    # make sure we have a file handle
+    return undef if ($self->{'handle'} eq "");
+    my $handle = $self->{'handle'};
+
+    if ($self->{'encoding'} eq "utf8") {
+	# utf-8 text, how many characters we get depends 
+	# on what we find
+	my $c1 = "";
+	my $c2 = "";
+	my $c3 = "";
+
+	while (!eof ($handle)) {
+	    $c1 = ord (getc ($handle));
+
+	    if ($c1 <= 0x7f) {
+		# one byte character
+		return chr ($c1);
+
+	    } elsif ($c1 >= 0xc0 && $c1 <= 0xdf) {
+		# two byte character
+		$c2 = getc ($handle) if (!eof ($handle));
+		return chr ($c1) . $c2;
+
+	    } elsif ($c1 >= 0xe0 && $c1 <= 0xef) {
+		# three byte character
+		$c2 = getc ($handle) if (!eof ($handle));
+		$c3 = getc ($handle) if (!eof ($handle));
+		return chr ($c1) . $c2 . $c3;
+	    }
+
+	    # if we get here there was an error in the file, we should
+	    # be able to recover from it however, maybe the file is in
+	    # another encoding
+	}
+
+	return undef if (eof ($handle));
+    }
+
+    if ($self->{'encoding'} eq "unicode") {
+	# unicode text, get the next two characters
+	return undef if (eof ($handle));
+	my $c1 = ord (getc ($handle));
+	return undef if (eof ($handle));
+	my $c2 = ord (getc ($handle));
+
+	return &unicode::unicode2utf8 ([(($self->{'bigendian'}) ? ($c1*256+$c2) : ($c2*256+$c1))]);
+    }
+
+    return undef;
+}
+
+
+sub unicodechar_to_ord
+{
+    my $self = shift (@_);
+    my ($unicode_text) = @_;
+
+    my $bigendian_ord_array = [];
+
+    my @unicodechar_array = ($unicode_text =~ m/(..)/g);
+
+    foreach my $pair (@unicodechar_array) {
+	# for each 2 byte pair       
+	my $c1=ord(substr($pair,0,1));
+	my $c2=ord(substr($pair,1,1));
+
+	my $be_ord = ($self->{'bigendian'}) ? $c1*256+$c2 : $c2*256+$c1;
+	push(@$bigendian_ord_array,$be_ord);
+    }
+
+    return $bigendian_ord_array;
+}
+
+
+# undef will be returned if the eof has been reached
+# the result will always be returned in utf-8
+sub read_line {
+    my $self = shift (@_);
+
+    # make sure we have a file handle
+    return undef if ($self->{'handle'} eq "");
+
+    my $handle = $self->{'handle'};
+
+    if ($self->{'encoding'} eq "utf8") {
+	# utf-8 line
+	return <$handle>;
+    }
+
+    if ($self->{'encoding'} eq "unicode") {
+	# unicode line
+	my $c = "";
+	my ($c1, $c2) = ("", "");
+	my $out = "";
+	while (read ($handle, $c, 2) == 2) {
+	    $c1 = ord (substr ($c, 0, 1));
+	    $c2 = ord (substr ($c, 1, 1));
+	    $c = &unicode::unicode2utf8([(($self->{'bigendian'}) ? ($c1*256+$c2) : ($c2*256+$c1))]);
+	    $out .= $c;
+	    last if ($c eq "\n");
+	}
+
+	return $out if (length ($out) > 0);
+	return undef;
+    }
+
+    if ($self->{'encoding'} eq "iso_8859_1") {
+	# we'll use ascii2utf8() for this as it's faster than going
+	# through convert2unicode()
+	my $line = "";
+	if (defined ($line = <$handle>)) {
+	    return &unicode::ascii2utf8 (\$line);
+	}
+    }
+
+    # everything else uses unicode::convert2unicode
+    my $line = "";
+    if (defined ($line = <$handle>)) {
+	return &unicode::unicode2utf8 (&unicode::convert2unicode ($self->{'encoding'}, \$line));
+    }
+
+    return undef;
+}
+
+
+
+# this will look for a Byte Order Marker at the start of the file, and
+# set the encoding appropriately if there is one, returning any
+# non-marker text on the first line (or returns undef).
+sub find_unicode_bom {
+    my $self=shift;
+
+    my $non_bom_text=""; # to return if we read in 'real' text
+
+    if ($self->{'first'} == 0) { return }
+
+    # make sure we have a file handle
+    return if ($self->{'handle'} eq "");
+    my $handle = $self->{'handle'};
+
+    $self->{'first'} = 0;
+
+    my $gc = getc ($handle);
+    my $b1 = ord($gc);
+    my $b2;
+    my $b3;
+
+    if ($b1 == 0xfe || $b1 == 0xff) {
+	$b2 = ord (getc ($handle)) if (!eof ($handle));
+	if ($b1 == 0xff && $b2 == 0xfe) {
+	    $self->{'encoding'} = "unicode";
+	    $self->{'bigendian'} = 0;
+	    return;
+	} elsif ($b1 == 0xfe && $b2 == 0xff) {
+	    $self->{'encoding'} = "unicode";
+	    $self->{'bigendian'} = 1;
+	    return;
+	} elsif ($b1 == 0xef && $b2 == 0xbb) {
+	    $b3 = ord(getc($handle));
+	    if ($b3 == 0xbf) {
+		$self->{'encoding'} = "utf8";
+		$self->{'bigendian'} = 1;
+		return;
+	    }
+	    else {
+		# put back all three bytes
+		$handle->ungetc($b3);
+		$handle->ungetc($b2);
+		$handle->ungetc($b1); return;
+
+	    }
+	}
+	else {
+	    # put back two bytes read
+	    $handle->ungetc($b2);
+	    $handle->ungetc($b1); return;
+	}
+    } else { # $b1 != fe or ff
+	# put back the one byte read
+	$handle->ungetc($b1); return;
+    }
+}
+
+
+sub read_file_no_decoding
+{
+    my $self = shift (@_);
+    my ($outputref) = @_;
+
+    # make sure we have a file handle
+    return if ($self->{'handle'} eq "");
+
+    my $handle = $self->{'handle'};
+
+    # if encoding is set to utf8 or unicode, sniff to see if there is a 
+    # byte order marker
+    if ($self->{'first'} &&
+	($self->{'encoding'} eq "utf8" || $self->{'encoding'} eq 'unicode')) {
+
+	# this will change $self's encoding if there is a BOM (but won't consume any characters)
+	$self->find_unicode_bom(); 
+    }
+
+    undef $/;
+    $$outputref .=  <$handle>;
+    $/ = "\n";
+}
+
+
+# will convert entire contents of file to utf8 and append result to $outputref
+# this may be a slightly faster way to get the contents of a file than by 
+# recursively calling read_line()
+sub decode_text {
+    my $self = shift (@_);
+
+    my ($raw_text,$decoded_text_ref) = @_;
+
+    if ($self->{'encoding'} eq "utf8") {
+	# Nothing to do, raw text is in utf 8
+	$$decoded_text_ref .= $raw_text;
+	return;
+    }
+
+    if ($self->{'encoding'} eq "unicode") {
+	my $unicode_array = $self->unicodechar_to_ord($raw_text);
+	$$decoded_text_ref .= &unicode::unicode2utf8($unicode_array);
+	return;
+    }
+
+    if ($self->{'encoding'} eq "iso_8859_1" || $self->{'encoding'} eq "ascii") {
+	# we'll use ascii2utf8() for this as it's faster than going
+	# through convert2unicode()
+	$$decoded_text_ref .= &unicode::ascii2utf8 (\$raw_text);
+	return;
+    }
+
+    # everything else uses unicode::convert2unicode
+    $$decoded_text_ref .= &unicode::unicode2utf8 (&unicode::convert2unicode ($self->{'encoding'}, \$raw_text));
+}
+
+
+
+# will convert entire contents of file to utf8 and append result to $outputref
+# this may be a slightly faster way to get the contents of a file than by 
+# recursively calling read_line()
+sub read_file {
+    my $self = shift (@_);
+    my ($outputref) = @_;
+
+    # While unusual, $raw_text is initialized to $$outputref
+    # to be consistent with code before refactoring
+    my $raw_text = $$outputref; 
+
+    $self->read_file_no_decoding(\$raw_text);
+    $self->decode_text($raw_text,$outputref);
+}
+
+1;
Index: /gsdl/stable/perllib/muread.pm
===================================================================
--- /gsdl/stable/perllib/muread.pm	(revision 20131)
+++ /gsdl/stable/perllib/muread.pm	(revision 20131)
@@ -0,0 +1,152 @@
+###########################################################################
+#
+# muread.pm -- read a marked-up file
+#
+# Copyright (C) 1999 DigiLib Systems Limited, NZ
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+package muread;
+
+use strict;
+use unicode;
+use multiread;
+
+sub new {
+    my ($class) = @_;
+
+    my $self = {'filename'=>"",
+		'encoding'=>"",
+		'handle'=>"",
+		'reader'=>"",
+		'buffer'=>""};
+
+    return bless $self, $class;
+}
+
+# returns a new tag with a tag name and any options
+sub parse_tag {
+    my $self = shift (@_);
+    my ($orgtagtext) = @_;
+    my $tagtext = $orgtagtext;
+    my $newtag = {};
+    my $misformed = 0;
+
+#    print STDERR "parsing \"$tagtext\"\n";
+
+    # get tag name (if there is one)
+    if ($tagtext =~ /^(\w+)/) {
+	$newtag->{'_tagname'} = $1;
+	$tagtext =~ s/^(\w+)//;
+    } else {
+	print STDERR "muread::parse_tag error - no tag name found\n";
+    }
+
+    # get the tag arguments
+    while ($tagtext =~ /\S/) {
+	$tagtext =~ s/^\s+//s;
+	if ($tagtext =~ /^(\w+)\s*=\s*\"([^\"]*)\"/s) {
+	    $newtag->{$1} = (defined $2) ? $2 : "";
+	    $tagtext =~ s/^\w+\s*=\s*\"[^\"]*\"//s;
+
+	} else {
+	    if (!$misformed) {
+		print STDERR "muread::parse_tag error - miss-formed tag <$orgtagtext>\n";
+		$misformed = 1;
+	    }
+	    $tagtext =~ s/^\S+//s;
+	}
+    }
+
+    return $newtag;
+}
+
+sub read_tag_content {
+    my $self = shift (@_);
+    my ($tag) = @_;
+
+    # all tags contain a _tagname except the tag for the document
+
+    my $line = "";
+    while (1) {
+	# deal with preceeding text
+	if ($self->{'buffer'} =~ /^([^<]+)</s) {
+	    # add preceeding text
+	    $tag->{'_contains'} = [] unless defined $tag->{'_contains'};
+	    push (@{$tag->{'_contains'}}, {'_text'=>$1});
+
+	    $self->{'buffer'} =~ s/^[^<]+</</s;
+	}
+
+	if ($self->{'buffer'} =~ /^<([^>\/]+)>/s) {
+	    # add info from this tag
+	    my $tagtext = $1;
+	    my $newtag = $self->parse_tag ($tagtext);
+	    push (@{$tag->{'_contains'}}, $newtag);
+	    $self->{'buffer'} =~ s/^<[^>\/]+>//s;
+	    
+	    # deal with the contents of this tag
+	    $self->read_tag_content ($newtag);
+
+	} elsif ($self->{'buffer'} =~ /^<\/([^>\/]+)>/s) {
+	    my $tagname = $1;
+	    $self->{'buffer'} =~ s/^<\/[^>\/]+>//s;
+
+	    # check that this tag is the right tag
+	    if (!defined $tag->{'_tagname'} || $tag->{'_tagname'} ne $tagname) {
+		print STDERR "muread::read_tag_content error - mismatched tag </$tagname>, " .
+		    "expected </$tag->{'_tagname'}>\n";
+	    } else {
+		return;
+	    }
+	} elsif (defined ($line = $self->{'reader'}->read_line())) {
+	    $self->{'buffer'} .= $line;
+	} else {
+	    if ($self->{'buffer'} =~ /\S/) {
+		print STDERR "muread::read_tag_content error - can't parse text \"$self->{'buffer'}\"\n";
+	    }
+	    last;
+	}
+    }
+    
+    if (defined $tag->{'_tagname'}) {
+	print STDERR "muread::read_tag_content error - eof reached before closing " .
+	    "tag \"$tag->{'_tagname'}\" found\n";
+    }
+}
+
+sub read_file {
+    my $self = shift (@_);
+    ($self->{'handle'}, $self->{'filename'}, $self->{'encoding'}) = @_;
+    $self->{'encoding'} = "utf8" unless defined $self->{'encoding'};
+
+    my $doc = {};
+
+    # get reader set up
+    $self->{'reader'} = new multiread ();
+    $self->{'reader'}->set_handle ($self->{'handle'});
+    $self->{'reader'}->set_encoding ($self->{'encoding'});
+
+    # read in the file
+    $self->read_tag_content ($doc);
+
+    $self->{'handle'} = "";
+    return $doc;
+}
+
+1;
Index: /gsdl/stable/perllib/parsargv.pm
===================================================================
--- /gsdl/stable/perllib/parsargv.pm	(revision 20131)
+++ /gsdl/stable/perllib/parsargv.pm	(revision 20131)
@@ -0,0 +1,241 @@
+###########################################################################
+#
+# parseargv.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package parsargv;
+
+use strict;
+
+# 
+# parse(ARGVREF, [SPEC, VARREF] ...)
+# 
+# Parse command line arguments.
+# 
+# ARGVREF is an array reference, usually to @ARGV.  The remaining
+# arguments are paired (SPEC, VARREF).  SPEC is a specification string
+# for a particular argument; VARREF is a variable reference that will
+# receive the argument.
+# 
+# SPEC is in one of the following forms:
+# 
+# ARG/REGEX/DEFAULT ARG is the name of command line argument.  REGEX is
+#     a regular expression that gives legal values for the argument.
+#     DEFAULT is the default value assigned to VARREF if the option does
+#     not appear on the command line.  Example
+# 
+# 
+# ARG/REGEX ARG and REGEX are as above.  Since no default is given, ARG
+#     must appear on the command line; if it doesn't, parse() returns 0.
+# 
+# ARG ARG is as above.  ARG is a boolean option.  VARREF is assigned 0 if ARG
+#     is not on the command line; 1 otherwise.
+# 
+# SPEC may start with a punctuation character, in which case this
+# character will be used instead of '/' as a delimiter.  Useful when '/'
+# is needed in the REGEX part.
+# 
+# VARREF is a reference to a scalar or an array.  If VARREF is an array
+# reference, then multiple command line options are allowed an append.  Example:
+# 
+# 	Command line: -day mon -day fri
+# 
+# 	parse(\@ARGV, "day/(mon|tue|wed|thu|fri)", \@days)
+# 
+# 	days => ('mon', 'fri')
+# 
+# Returns 0 if there was an error, nonzero otherwise.
+# 
+
+ 
+sub parse
+{
+    my $arglist = shift;
+    my ($spec, $var);
+    my %option;
+
+    my @rest = @_;
+
+
+    # if the last argument is the string "allow_extra_options" then options
+    # in \@rest without a corresponding SPEC will be ignored (i.e. the "$arg is
+    # not a valid option" error won't occur)\n";
+    my $allow_extra_options = pop @rest;
+    if (defined ($allow_extra_options)) {
+	if ($allow_extra_options eq "allow_extra_options") {
+	    $allow_extra_options = 1;
+	} else {
+	    # put it back where we got it
+	    push (@rest, $allow_extra_options);
+	    $allow_extra_options = 0;
+	}
+    } else {
+	$allow_extra_options = 0;
+    }
+
+    while (($spec, $var) = splice(@rest, 0, 2))
+        {
+	  
+	die "Variable for $spec is not a valid type."
+	    unless ref($var) eq 'SCALAR' || ref($var) eq 'ARRAY'
+	    || (ref($var) eq 'REF' && ref($$var) eq 'GLOB');
+
+	my $delimiter;
+	if ($spec !~ /^\w/)
+	{
+	    $delimiter = substr($spec, 0, 1);
+	    $spec = substr($spec, 1);
+	}
+	else
+	{
+	    $delimiter = '/';
+	}
+	my ($name, $regex, $default) = split(/$delimiter/, $spec, 3);
+	
+	
+	if ($name)
+	{   
+	    if ($default && $default !~ /$regex/)
+	    {
+		die "Default value for $name doesn't match regex ($spec).";
+	    }
+	    $option{$name} = {'name' => $name,
+			      'regex' => $regex,
+			      'default' => $default,
+			      'varref' => $var,
+			      'set' => 0};
+	}
+	else
+	{
+	    die "Invalid argument ($spec) for parsargv.";
+	}
+    }
+
+    my @argv;
+    my $arg;
+    my $parse_options = 1;
+    my $errors = 0;
+
+    while ($arg = shift(@$arglist))
+    {
+	if ($parse_options && $arg eq '--')
+	{
+	    $parse_options = 0;
+	    next;
+	}
+
+	if ($parse_options && $arg =~ /^-+\w/)
+	{
+	    $arg =~ s/^-+//;
+
+	    if (defined $option{$arg})
+	    {
+		&process_arg($option{$arg}, $arglist, \$errors);
+	    }
+	    elsif (!$allow_extra_options)
+	    {
+		print STDOUT "$arg is not a valid option.\n";
+		$errors++;
+	    }
+	}
+	else
+	{
+	    push(@argv, $arg);
+	}
+    }
+    @$arglist = @argv;
+
+    foreach $arg (keys %option)
+    {
+	if ($option{$arg}->{'set'} == 0)
+	{
+	    if (defined $option{$arg}->{'default'})
+	    {
+		&set_var($option{$arg}, $option{$arg}->{'default'});
+	    }
+	    elsif (!$option{$arg}->{'regex'})
+	    {
+		&set_var($option{$arg}, 0)
+	    }
+	    elsif (ref($option{$arg}->{'varref'}) ne 'ARRAY')
+	    {
+		print STDOUT "Missing command line argument -$arg.\n";
+		$errors++;
+	    }
+	}
+    }
+    return $errors == 0;
+}
+
+sub process_arg
+{
+    my ($option, $arglist, $errors) = @_;
+
+    if ($option->{'regex'} && @$arglist > 0 && $arglist->[0] !~ /^-+\w/)
+    {
+	if ($arglist->[0] =~ /$option->{'regex'}/)
+	{
+	    &set_var($option, shift(@$arglist));
+	}
+	else
+	{
+	    print STDOUT  "Bad value for -$option->{'name'} argument.\n";
+	    $$errors++;
+	}
+    }
+    elsif (!$option->{'regex'})
+    {
+	&set_var($option, 1);
+    }
+    else
+    {
+	print STDOUT "No value given for -$option->{'name'}.\n";
+	$$errors++;
+    }
+}
+
+sub set_var
+{
+    my ($option, $value) = @_;
+    my $type = ref($option->{'varref'});
+
+    if ($type eq 'SCALAR')
+    {
+	${$option->{'varref'}} = $value;
+    }
+    elsif ($type eq 'ARRAY')
+    {
+	push(@{$option->{'varref'}}, $value);
+    }
+    $option->{'set'} = 1;
+}
+
+1;
+
+
+
+
+
+
+
+
Index: /gsdl/stable/perllib/parse2.pm
===================================================================
--- /gsdl/stable/perllib/parse2.pm	(revision 20131)
+++ /gsdl/stable/perllib/parse2.pm	(revision 20131)
@@ -0,0 +1,344 @@
+#Last: Keeping doing the processArg for handing different type of arguments
+
+#parse2(\@_,$arguments,$self )
+
+package parse2;
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+}
+
+use strict;
+use util;
+
+
+
+#--Local Util Functions----------------------------
+#-----------------------------------------
+# Name: transformArg
+# Parameters: 1.(Array pointer of plugin pre-defined argument list)
+# Pre-condition: Call this function and pass a array pointer of argument list.
+# Post-condition: This function will transform the array to a hash table 
+#                 with "Argument name" as its key
+# Return value: Return a hash table of plugin pre-defined argument 
+#               list with "argument name" as the key
+#-----------------------------------------
+sub transformArg
+{
+    my ($aryptSysArguList) = @_;
+    my %hashArg;
+    
+    foreach my $hashOneArg (@{$aryptSysArguList})
+    {
+	if(!(defined $hashArg{$hashOneArg->{"name"}}))
+	{
+	    $hashArg{$hashOneArg->{"name"}} = $hashOneArg;
+	}
+    }
+    return %hashArg;
+}
+
+sub checkRange
+{
+    my ($strRange,$intInputArg,$strArgName) = @_;
+    my @aryRange = split(",",$strRange);
+    if(defined $aryRange[0])
+    {
+	if($intInputArg < $aryRange[0])
+	{
+	    print STDERR " Parameter Parsing Error (Incorrect Range): when parse argument parameter for \"-$strArgName\"\n";
+	    return 0;
+	}
+	else
+	{
+	    if(scalar(@aryRange) == 2)
+	    { 
+		if($intInputArg > $aryRange[1])
+		{
+		    print STDERR " Parameter Parsing Error (Incorrect Range): when parse argument parameter for \"-$strArgName\"\n";
+		    return 0;
+		}
+	    }
+	}
+    }
+    else{ die " System error: minimum range is not defined. Possible mistyping in Argument list for $strArgName\n";}
+    return 1;
+}
+
+sub checkCharLength
+{
+    my ($intCharLength,$intInputArg,$strArgName) = @_;
+    if($intCharLength =~ m/\d/)
+    {
+	if(length($intInputArg) != $intCharLength)
+	{ 
+	    print STDERR " Parameter Parsing Error (Incorrect Char_Length): when parse argument parameter for \"-$strArgName\"\n";
+	    return 0;
+	}
+    }
+    else
+    {
+	die " System error: incorrect char_length. Possible mistyping in Argument list for $strArgName\n";
+    }
+    return 1;
+}
+#-----------------------------------------
+# Name: processArg
+# Parameters: 1.(Hash pointer of one argument)
+#             2.(Array pointer of the user given argument)
+#             3.(Hash pointer of user given arguments' values)
+# Pre-condition: Given a argument ($hashOneArg) 
+# Post-condition: System will check whether it need to get parameter 
+#                 from $aryptInputArguList or not, and also check the 
+#                 given parameter is following the argument description
+# Return value: 1 is parsing successful, 0 is failed.
+#-----------------------------------------
+sub processArg
+{
+    my ($hashOneArg,$aryptInputArguList,$hashInputArg) = @_;
+
+    # Since these two variables are going to be 
+    # used a lot, store them with some better names.
+    my $strArgName = $hashOneArg->{"name"};
+    my $strArgType = $hashOneArg->{"type"};
+
+    # If the argument type is "flag" then 
+    # set it to 1(which is "true") 
+    if($strArgType eq "flag")
+    {
+	$hashInputArg->{$strArgName} = 1;
+    }
+
+    # If the argument type is "int" then
+    # gets the next argument from $aryptInputArguList 
+    # and check whether it is a digit
+    # TODO: check its "range" and "char_length"
+    elsif($strArgType eq "int")
+    {
+	my $intInputArg = shift(@{$aryptInputArguList});
+	if ($intInputArg =~ /\d+/)
+	{
+	    $hashInputArg->{$strArgName} = $intInputArg;
+	}
+	else
+	{
+	    print STDERR " Error: occur in parse2.pm::processArg()\n Unmatched Argument: -$strArgName with type $strArgType\n";
+	    return 0;
+	}
+    }
+
+    # If the argument type is "enum" then
+    elsif($strArgType eq "enum")
+    {
+	if(defined $hashOneArg->{"list"})
+	{
+	    my $aryptList = $hashOneArg->{"list"};
+	    my $blnCheckInList = "false";
+	    my $strInputArg = shift(@{$aryptInputArguList});
+	    foreach my $hashEachItem (@$aryptList)
+	    {
+		if($strInputArg eq $hashEachItem->{"name"})
+		{
+		    $blnCheckInList = "true";
+		}
+		last if($blnCheckInList eq "true");
+	    }
+	    if($blnCheckInList ne "true")
+	    {
+		print STDERR " Error: occur in parse2.pm::processArg()\n Unknown Enum List Type: -$strArgName with parameter: $strInputArg\n";
+		return 0;
+	    } else {
+		$hashInputArg->{$strArgName} = $strInputArg;
+	    }
+	    
+	}
+	else
+	{
+	    print STDERR " Error: occur in parse2.pm::processArg(2)\n Unknown Type: -$strArgName with type $strArgType\n";
+	    return 0;
+	}
+    }
+
+    # If the argument type is "string" or "metadata" or "quotestr" then
+    # just shift the next argument from $aryptInputArguList
+    # TODO: make sure if there is any checking required for this two types
+    elsif($strArgType eq "string" || $strArgType eq "enumstring" || $strArgType eq "quotestr" || $strArgType eq "metadata" || $strArgType eq "regexp" || $strArgType eq "url")
+    {
+	$hashInputArg->{$strArgName}= shift(@{$aryptInputArguList});
+    }
+    
+    # Report any undefined types
+    else
+    {
+	print STDERR " Error: occur in parse2.pm::processArg(3)\n Unknown Type: -$strArgName with type $strArgType\n";
+	return 0;
+    }
+    
+    return 1;
+}
+
+#--Main Parsing Function----------------------------
+#-----------------------------------------
+# Name: parse
+# Parameters: 1.(Array pointer of the user given argument)
+#             2.(Array pointer of plugin pre-defined argument list)  
+#             3.(Hash pointer, where we store all the argument value)
+# Pre-condition: Plugin gives the parameters to parse function in parse2 
+# Post-condition: Store all the default or user given values to the hash->{$ArgumentName}.
+#                 Since hash may be a plugin $self, plugin will have every values we set.
+#             4. Optional "allow_extra_options" argument. If this is set, then
+#                its ok to have arguments that are not in the predefined list
+# Return value: -1 if parsing is unsuccessful
+#                other value for success. This will be 0 unless "allow_extra_options" is set, in which case it will be the number of extra arguments found. 
+#-----------------------------------------
+sub parse
+{
+    # Get the user supplied arguments pointer "\@_"
+    my $aryptUserArguList = shift; 
+
+    # Check if allow extra arguments
+    my $blnAllowExtraOptions = "false";
+    
+    if(scalar(@_) == 3)
+    { 
+	my $strAllowExtraOptions = pop @_;
+	
+	if ($strAllowExtraOptions eq "allow_extra_options") 
+	{
+	    $blnAllowExtraOptions = "true";    
+	} 
+    }
+    
+    my ($aryptSysArguList,$self) = @_;
+    my %hashArg;
+    my %hashInputArg;
+    my @ExtraOption;
+
+    # Transform the system argument (predefined the code) 
+    # from array to hash table for increasing performance
+    %hashArg = &transformArg($aryptSysArguList);
+
+    # Process each User input argument and store the 
+    # information into hashInputArg
+    while (my $strOneArg = shift(@{$aryptUserArguList}))
+    {
+	# Check whether it start with a "-" sign
+	if ($strOneArg =~ /^-+\w/)
+	{
+	    # If it is start with a "-" sign then take it off
+	    $strOneArg =~ s/^-+//;
+
+	    # If the inputed argument is defined in the argument 
+	    # list from this plugin then process
+	    
+	    if(defined $hashArg{$strOneArg})
+	    {
+		#$%^
+		#print "($strOneArg) is processed\n";
+		# Process this argument and store the related 
+		# information in %hashInputArg
+		if(processArg($hashArg{$strOneArg},$aryptUserArguList,\%hashInputArg) == 0){ 
+		    print STDERR "<BadArgumentValue a=$strOneArg>\n";
+		    return -1;}
+	    }
+	    
+	    # Else check if it allows extra options, if yes 
+	    # then push it to a new array, else return fault
+	    else
+	    {
+		if($blnAllowExtraOptions eq "true")
+		{
+		    push(@ExtraOption,"-$strOneArg");
+		}
+		else
+		{
+		    print STDERR "<BadArgument a=$strOneArg>\n";
+		    print STDERR " Error: occur in parse2.pm::parse()\n Extra Arguments: $strOneArg\n";
+		    return -1;
+		}
+	    }
+	}
+	
+	# This part follow the previous parsing system. 
+	# It doesn't return error message even user
+	# gave a invalid argument.
+	else
+	{
+	    if($blnAllowExtraOptions eq "true")
+	    {
+		push(@ExtraOption,$strOneArg);
+	    }
+	    else
+	    {
+		print STDERR " Error: occur in parse2.pm::parse()\n Invalid Argument: $strOneArg\n";
+		return -1;
+	    }
+	}
+    }
+
+    # Store the extra option back 
+    # to the user given argument list.
+    @$aryptUserArguList = @ExtraOption;
+    
+    # Now we go through all the pre defined arguments, 
+    # if the user has specified the arguments then just 
+    # set to whatever they set. Otherwise use the default value
+    foreach my $hashOneArg (@{$aryptSysArguList})
+    {
+	my $strArgName = $hashOneArg->{"name"};
+
+	# If the strArgName has defined in the %hashInputArg, 
+	# this means users has give this argument, store the 
+	# user given to self->{"$strArgName"}
+	if(defined $hashInputArg{$strArgName})
+	{
+	    if(defined $hashOneArg->{"range"}) 
+	    {
+		if(checkRange($hashOneArg->{"range"},$hashInputArg{$strArgName},$strArgName) == 0){ return -1;}
+	    }
+	    if(defined $hashOneArg->{"char_length"})
+	    {
+		if(checkCharLength($hashOneArg->{"char_length"},$hashInputArg{$strArgName},$strArgName) == 0){ return -1;}
+	    }
+	    $self->{"$strArgName"} = $hashInputArg{"$strArgName"};
+	}
+	elsif (!defined $self->{$strArgName}) 
+	{
+	    # don't want to override default with superclass value
+	  
+	    # Else use the default value of the arguments, 
+	    # if there is no default value, then it must be a flag, 
+	    # then set it to 0 (which is false)
+	
+	    if(defined $hashOneArg->{"deft"})
+	    {
+		$self->{"$strArgName"} = $hashOneArg->{"deft"};
+	    }
+	    else
+	    {
+		if($hashOneArg->{"type"} eq "flag"){ 
+		    $self->{"$strArgName"} = 0;
+		}
+		else {
+		    # all other cases, use "" as default
+		    $self->{"$strArgName"} = "";
+		}
+	    }
+	}
+    }
+
+    # If allow_extra_options is set, then return the number of arguments left in the argument list.
+    if($blnAllowExtraOptions eq "true")
+    {
+	return scalar(@$aryptUserArguList);
+    }
+    else
+    {
+	return 0;
+    }
+}
+
+1;
Index: /gsdl/stable/perllib/parse3.pm
===================================================================
--- /gsdl/stable/perllib/parse3.pm	(revision 20131)
+++ /gsdl/stable/perllib/parse3.pm	(revision 20131)
@@ -0,0 +1,353 @@
+#Last: Keeping doing the processArg for handing different type of arguments
+
+#parse3(\@_,$arguments,$self )
+
+package parse3;
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+    die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+}
+
+use util;
+
+
+
+#--Local Util Functions----------------------------
+#-----------------------------------------
+# Name: transformArg
+# Parameters: 1.(Array pointer of plugin pre-defined argument list)
+# Pre-condition: Call this function and pass a array pointer of argument list.
+# Post-condition: This function will transform the array to a hash table 
+#                 with "Argument name" as its key
+# Return value: Return a hash table of plugin pre-defined argument 
+#               list with "argument name" as the key
+#-----------------------------------------
+sub transformArg
+{
+    my ($aryptSysArguList) = @_;
+    my %hashArg;
+    
+    foreach my $hashOneArg (@{$aryptSysArguList})
+    {
+	if(!(defined $hashArg{$hashOneArg->{"name"}}))
+	{
+	    $hashArg{$hashOneArg->{"name"}} = $hashOneArg;
+	}
+    }
+    return %hashArg;
+}
+
+sub checkRange
+{
+    my ($strRange,$intInputArg,$strArgName) = @_;
+    my @aryRange = split(",",$strRange);
+    if(defined $aryRange[0])
+    {
+	if($intInputArg < $aryRange[0])
+	{
+	    print STDERR " Parameter Parsing Error (Incorrect Range): when parse argument parameter for \"-$strArgName\"\n";
+	    return 0;
+	}
+	else
+	{
+	    if(scalar(@aryRange) == 2)
+	    { 
+		if($intInputArg > $aryRange[1])
+		{
+		    print STDERR " Parameter Parsing Error (Incorrect Range): when parse argument parameter for \"-$strArgName\"\n";
+		    return 0;
+		}
+	    }
+	}
+    }
+    else{ die " System error: minimum range is not defined. Possible mistyping in Argument list for $strArgName\n";}
+    return 1;
+}
+
+sub checkCharLength
+{
+    my ($intCharLength,$intInputArg,$strArgName) = @_;
+    if($intCharLength =~ m/\d/)
+    {
+	if(length($intInputArg) != $intCharLength)
+	{ 
+	    print STDERR " Parameter Parsing Error (Incorrect Char_Length): when parse argument parameter for \"-$strArgName\"\n";
+	    return 0;
+	}
+    }
+    else
+    {
+	die " System error: incorrect char_length. Possible mistyping in Argument list for $strArgName\n";
+    }
+    return 1;
+}
+#-----------------------------------------
+# Name: processArg
+# Parameters: 1.(Hash pointer of one argument)
+#             2.(Array pointer of the user given argument)
+#             3.(Hash pointer of user given arguments' values)
+# Pre-condition: Given a argument ($hashOneArg) 
+# Post-condition: System will check whether it need to get parameter 
+#                 from $aryptInputArguList or not, and also check the 
+#                 given parameter is following the argument description
+# Return value: 1 is parsing successful, 0 is failed.
+#-----------------------------------------
+sub processArg
+{
+    my ($hashOneArg,$aryptInputArguList,$hashInputArg) = @_;
+
+    # Since these two variables are going to be 
+    # used a lot, store them with some better names.
+    my $strArgName = $hashOneArg->{"name"};
+    my $strArgType = $hashOneArg->{"type"};
+
+    # If the argument type is "flag" then 
+    # set it to 1(which is "true") 
+    if($strArgType eq "flag")
+    {
+	$hashInputArg->{$strArgName} = 1;
+    }
+
+    # If the argument type is "int" then
+    # gets the next argument from $aryptInputArguList 
+    # and check whether it is a digit
+    # TODO: check its "range" and "char_length"
+    elsif($strArgType eq "int")
+    {
+	my $intInputArg = shift(@{$aryptInputArguList});
+	if ($intInputArg =~ /\d+/)
+	{
+	    $hashInputArg->{$strArgName} = $intInputArg;
+	}
+	else
+	{
+	    print STDERR " Error: occur in parse3.pm::processArg()\n Unmatched Argument: -$strArgName with type $strArgType\n";
+	    return 0;
+	}
+    }
+
+    # If the argument type is "enum" then
+    elsif($strArgType eq "enum")
+    {
+	if(defined $hashOneArg->{"list"})
+	{
+	    my $aryptList = $hashOneArg->{"list"};
+	    my $blnCheckInList = "false";
+	    my $strInputArg = shift(@{$aryptInputArguList});
+	    foreach my $hashEachItem (@$aryptList)
+	    {
+		if($strInputArg eq $hashEachItem->{"name"})
+		{
+		    $blnCheckInList = "true";
+		}
+		last if($blnCheckInList eq "true");
+	    }
+	    if($blnCheckInList ne "true")
+	    {
+		print STDERR " Error: occur in parse3.pm::processArg()\n Unknown Enum List Type: -$strArgName with parameter: $strInputArg\n";
+		return 0;
+	    } else {
+		$hashInputArg->{$strArgName} = $strInputArg;
+	    }
+	    
+	}
+	else
+	{
+	    print STDERR " Error: occur in parse3.pm::processArg(2)\n Unknown Type: -$strArgName with type $strArgType\n";
+	    return 0;
+	}
+    }
+
+    # If the argument type is "string" or "metadata" then
+    # just shift the next argument from $aryptInputArguList
+    # TODO: make sure if there is any checking required for this two types
+    elsif($strArgType eq "string" || $strArgType eq "metadata" || $strArgType eq "regexp" || $strArgType eq "url")
+    {
+	$hashInputArg->{$strArgName}= shift(@{$aryptInputArguList});
+    }
+    #if the argument type is "quotestr", then the next several arguments must be shifted from $aryptInputArugList
+    #lets see if we can detect an end double quote
+    elsif($strArgType eq "quotestr") 
+    {
+	my $tmpstr = shift(@{$aryptInputArguList}); 
+	$hashInputArg->{$strArgName} = ""; 
+	while($tmpstr !~ /\"$/)  {
+             $hashInputArg->{$strArgName} = $hashInputArg->{$strArgName}." ".$tmpstr; 
+	     $tmpstr = shift(@{$aryptInputArguList}); 
+        }
+        $hashInputArg->{$strArgName} = $hashInputArg->{$strArgName}." ".$tmpstr; 
+    }
+    else
+    {
+	print STDERR " Error: occur in parse3.pm::processArg(3)\n Unknown Type: -$strArgName with type $strArgType\n";
+	return 0;
+    }
+    
+    return 1;
+}
+
+#--Main Parsing Function----------------------------
+#-----------------------------------------
+# Name: parse
+# Parameters: 1.(Array pointer of the user given argument)
+#             2.(Array pointer of plugin pre-defined argument list)  
+#             3.(Hash pointer, where we store all the argument value)
+# Pre-condition: Plugin gives the parameters to parse function in parse3 
+# Post-condition: Store all the default or user given values to the hash->{$ArgumentName}.
+#                 Since hash may be a plugin $self, plugin will have every values we set.
+#             4. Optional "allow_extra_options" argument. If this is set, then
+#                its ok to have arguments that are not in the predefined list
+# Return value: -1 if parsing is unsuccessful
+#                other value for success. This will be 0 unless "allow_extra_options" is set, in which case it will be the number of extra arguments found. 
+#-----------------------------------------
+sub parse
+{
+    # Get the user supplied arguments pointer "\@_"
+    my $aryptUserArguList = shift; 
+
+    # Check if allow extra arguments
+    my $blnAllowExtraOptions = "false";
+    
+    if(scalar(@_) == 3)
+    { 
+	my $strAllowExtraOptions = pop @_;
+	
+	if ($strAllowExtraOptions eq "allow_extra_options") 
+	{
+	    $blnAllowExtraOptions = "true";    
+	} 
+    }
+    
+    my ($aryptSysArguList,$self) = @_;
+    my %hashArg;
+    my %hashInputArg;
+    my @ExtraOption;
+
+    # Transform the system argument (predefined the code) 
+    # from array to hash table for increasing performance
+    %hashArg = &transformArg($aryptSysArguList);
+
+    # Process each User input argument and store the 
+    # information into hashInputArg
+    while (my $strOneArg = shift(@{$aryptUserArguList}))
+    {
+	# Check whether it start with a "-" sign
+	if ($strOneArg =~ /^-+\w/)
+	{
+	    # If it is start with a "-" sign then take it off
+	    $strOneArg =~ s/^-+//;
+
+	    # If the inputed argument is defined in the argument 
+	    # list from this plugin then process
+	    
+	    if(defined $hashArg{$strOneArg})
+	    {
+		#$%^
+		#print "($strOneArg) is processed\n";
+		# Process this argument and store the related 
+		# information in %hashInputArg
+		if(processArg($hashArg{$strOneArg},$aryptUserArguList,\%hashInputArg) == 0){ 
+		    print STDERR "<BadArgumentValue a=$strOneArg>\n";
+		    return -1;}
+	    }
+	    
+	    # Else check if it allows extra options, if yes 
+	    # then push it to a new array, else return fault
+	    else
+	    {
+		if($blnAllowExtraOptions eq "true")
+		{
+		    push(@ExtraOption,"-$strOneArg");
+		}
+		else
+		{
+		    print STDERR "<BadArgument a=$strOneArg>\n";
+		    print STDERR " Error: occur in parse3.pm::parse()\n Extra Arguments: $strOneArg\n";
+		    return -1;
+		}
+	    }
+	}
+	
+	# This part follow the previous parsing system. 
+	# It doesn't return error message even user
+	# gave a invalid argument.
+	else
+	{
+	    if($blnAllowExtraOptions eq "true")
+	    {
+		push(@ExtraOption,$strOneArg);
+	    }
+	    else
+	    {
+		print STDERR " Error: occur in parse3.pm::parse()\n Invalid Argument: $strOneArg\n";
+		return -1;
+	    }
+	}
+    }
+
+    # Store the extra option back 
+    # to the user given argument list.
+    @$aryptUserArguList = @ExtraOption;
+    
+    # Now we go through all the pre defined arguments, 
+    # if the user has specified the arguments then just 
+    # set to whatever they set. Otherwise use the default value
+    foreach my $hashOneArg (@{$aryptSysArguList})
+    {
+	my $strArgName = $hashOneArg->{"name"};
+
+	# If the strArgName has defined in the %hashInputArg, 
+	# this means users has give this argument, store the 
+	# user given to self->{"$strArgName"}
+	if(defined $hashInputArg{$strArgName})
+	{
+	    if(defined $hashOneArg->{"range"}) 
+	    {
+		if(checkRange($hashOneArg->{"range"},$hashInputArg{$strArgName},$strArgName) == 0){ return -1;}
+	    }
+	    if(defined $hashOneArg->{"char_length"})
+	    {
+		if(checkCharLength($hashOneArg->{"char_length"},$hashInputArg{$strArgName},$strArgName) == 0){ return -1;}
+	    }
+	    $self->{"$strArgName"} = $hashInputArg{"$strArgName"};
+	}
+	elsif (!defined $self->{$strArgName}) 
+	{
+	    # don't want to override default with superclass value
+	  
+	    # Else use the default value of the arguments, 
+	    # if there is no default value, then it must be a flag, 
+	    # then set it to 0 (which is false)
+	
+	    if(defined $hashOneArg->{"deft"})
+	    {
+		$self->{"$strArgName"} = $hashOneArg->{"deft"};
+	    }
+	    else
+	    {
+		if($hashOneArg->{"type"} eq "flag"){ 
+		    $self->{"$strArgName"} = 0;
+		}
+		else {
+		    # all other cases, use "" as default
+		    $self->{"$strArgName"} = "";
+		}
+	    }
+	}
+    }
+
+    # If allow_extra_options is set, then return the number of arguments left in the argument list.
+    if($blnAllowExtraOptions eq "true")
+    {
+	return scalar(@$aryptUserArguList);
+    }
+    else
+    {
+	return 0;
+    }
+}
+
+1;
Index: /gsdl/stable/perllib/plugin.pm
===================================================================
--- /gsdl/stable/perllib/plugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugin.pm	(revision 20131)
@@ -0,0 +1,426 @@
+###########################################################################
+#
+# plugin.pm -- functions to handle using plugins
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package plugin;
+
+use strict; # to pick up typos and undeclared variables...
+no strict 'refs'; # ...but allow filehandles to be variables and vice versa
+no strict 'subs';
+
+require util;
+use gsprintf 'gsprintf';
+
+# mapping from old plugin names to new ones for backwards compatibility
+# can remove at sometime in future when we no longer want to support old xxPlug names in the config file
+my $plugin_name_map = {
+    'GAPlug' => 'GreenstoneXMLPlugin',
+    'ArcPlug' => 'ArchivesInfPlugin',
+    'RecPlug' => 'DirectoryPlugin',
+    'TEXTPlug' => 'TextPlugin',
+    'XMLPlug' => 'ReadXMLFile',
+    'EMAILPlug' => 'EmailPlugin',
+    'SRCPlug' => 'SourceCodePlugin',
+    'NULPlug' => 'NulPlugin',
+    'W3ImgPlug' => 'HTMLImagePlugin',
+    'PagedImgPlug' => 'PagedImagePlugin',
+    'METSPlug' => 'GreenstoneMETSPlugin',
+    'PPTPlug' => 'PowerPointPlugin',
+    'PSPlug' => 'PostScriptPlugin',
+    'DBPlug' => 'DatabasePlugin'
+    };
+
+# global variables
+my $stats = {'num_processed' => 0,
+	     'num_blocked' => 0,
+	     'num_not_processed' => 0,
+	     'num_not_recognised' => 0,
+	     'num_archives' => 0
+	     };
+
+#globaloptions contains any options that should be passed to all plugins
+my ($verbosity, $outhandle, $failhandle, $globaloptions);
+
+sub get_valid_pluginname {
+    my ($pluginname) = @_;
+    my $valid_name = $pluginname;
+    if (defined $plugin_name_map->{$pluginname}) {
+	$valid_name = $plugin_name_map->{$pluginname};
+    } elsif ($pluginname =~ /Plug$/) {
+	$valid_name =~ s/Plug/Plugin/;
+	
+    }
+    return $valid_name;
+}
+sub load_plugin_require
+{
+    my ($pluginname) = @_;
+
+    my @check_list = ();
+
+    # pp_plugname shorthand for 'perllib' 'plugin' '$pluginname.pm' 
+    my $pp_plugname 
+	= &util::filename_cat('perllib', 'plugins', "${pluginname}.pm");
+    my $collectdir = $ENV{'GSDLCOLLECTDIR'};
+
+    # find the plugin
+    if (defined($ENV{'GSDLCOLLECTION'}))
+    {
+	my $customplugname 
+	    = &util::filename_cat($collectdir, "custom",$ENV{'GSDLCOLLECTION'},
+				  $pp_plugname);
+	push(@check_list,$customplugname);
+    }
+
+    my $colplugname = &util::filename_cat($collectdir, $pp_plugname);
+    push(@check_list,$colplugname);
+
+    if (defined $ENV{'GSDLEXTS'}) {
+
+	my $ext_prefix = &util::filename_cat($ENV{'GSDLHOME'}, "ext");
+
+	my @extensions = split(/:/,$ENV{'GSDLEXTS'});
+	foreach my $e (@extensions) {
+	    my $extplugname = &util::filename_cat($ext_prefix, $e, $pp_plugname);
+	    push(@check_list,$extplugname);
+
+	}
+    }
+
+
+    my $mainplugname = &util::filename_cat($ENV{'GSDLHOME'}, $pp_plugname);
+    push(@check_list,$mainplugname);
+
+    my $success=0;
+    foreach my $plugname (@check_list) {
+	if (-e $plugname) {
+	    require $plugname;
+	    $success=1;
+	    last;
+	}
+    }
+
+    if (!$success) {
+	&gsprintf(STDERR, "{plugin.could_not_find_plugin}\n",
+		  $pluginname);
+	die "\n";
+    }
+}
+
+sub load_plugin_for_info {
+    my ($pluginname) = shift @_;
+    $pluginname = &get_valid_pluginname($pluginname);
+    load_plugin_require($pluginname);
+
+    # create a plugin object
+    my ($plugobj);
+    my $options = "-gsdlinfo";
+    
+    eval ("\$plugobj = new \$pluginname([],[$options])");
+    die "$@" if $@;
+
+    return $plugobj;
+}
+
+sub load_plugins {
+    my ($plugin_list) = shift @_;
+    my $incremental;
+    ($verbosity, $outhandle, $failhandle, $globaloptions, $incremental) = @_; # globals
+    my @plugin_objects = ();
+    $incremental = 0 unless (defined $incremental && $incremental == 1);
+    $verbosity = 2 unless defined $verbosity;
+    $outhandle = 'STDERR' unless defined $outhandle;
+    $failhandle = 'STDERR' unless defined $failhandle;
+
+    my $colplugindir = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"perllib/plugins");
+     unshift (@INC, $colplugindir);  
+
+    map { $_ = "\"$_\""; } @$globaloptions;
+    my $globals = join (",", @$globaloptions);
+
+    foreach my $pluginoptions (@$plugin_list) {
+	my $pluginname = shift @$pluginoptions;
+	next unless defined $pluginname;
+	$pluginname = &get_valid_pluginname($pluginname);
+	load_plugin_require($pluginname);
+
+	# create a plugin object
+	my ($plugobj);
+	map { $_ = "\"$_\""; } @$pluginoptions;
+	my $options = join (",", @$pluginoptions);
+	if ($globals) {
+	    if (@$pluginoptions) {
+		$options .= ",";
+	    }
+	    $options .= "$globals";
+	}
+	$options =~ s/\$/\\\$/g;
+
+	eval ("\$plugobj = new \$pluginname([],[$options])");
+	die "$@" if $@;
+	
+	# initialize plugin
+	$plugobj->init($verbosity, $outhandle, $failhandle);
+	
+	$plugobj->set_incremental($incremental);
+
+	# add this object to the list
+	push (@plugin_objects, $plugobj);
+    }
+
+    return \@plugin_objects;
+}
+
+
+sub begin {
+    my ($pluginfo, $base_dir, $processor, $maxdocs, $gli) = @_;
+
+    map { $_->{'gli'} = $gli; } @$pluginfo;
+    map { $_->begin($pluginfo, $base_dir, $processor, $maxdocs); } @$pluginfo;
+}
+
+sub file_block_read {
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $gli) = @_;
+
+
+    $gli = 0 unless defined $gli;
+
+    my $rv = 0;
+    my $glifile = $file;
+    
+    $glifile =~ s/^[\/\\]+//; # file sometimes starts with a / so get rid of it
+    
+    # Announce to GLI that we are handling a file
+    print STDERR "<File n='$glifile'>\n" if $gli;
+    
+    # the .kill file is a handy (if not very elegant) way of aborting 
+    # an import.pl or buildcol.pl process
+    if (-e &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, ".kill")) {
+	gsprintf($outhandle, "{plugin.kill_file}\n");
+	die "\n";
+    }
+    
+    foreach my $plugobj (@$pluginfo) {
+
+      	$rv = $plugobj->file_block_read($pluginfo, $base_dir, $file, $block_hash, $metadata, $gli); 
+	#last if (defined $rv && $rv==1); # stop this file once we have found something to 'process' it
+    }
+    
+}
+
+
+sub metadata_read {
+    my ($pluginfo, $base_dir, $file, $block_hash, 
+	$extrametakeys, $extrametadata, $extrametafile, 
+	$processor, $maxdocs, $gli, $aux) = @_;
+
+    $maxdocs = -1 unless defined $maxdocs && $maxdocs =~ /\d/;
+    $gli = 0 unless defined $gli;
+
+    my $rv = 0;
+    my $glifile = $file;
+    
+    $glifile =~ s/^[\/\\]+//; # file sometimes starts with a / so get rid of it
+    
+    # Announce to GLI that we are handling a file
+    print STDERR "<File n='$glifile'>\n" if $gli;
+    
+    # the .kill file is a handy (if not very elegant) way of aborting 
+    # an import.pl or buildcol.pl process
+    if (-e &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, ".kill")) {
+	gsprintf($outhandle, "{plugin.kill_file}\n");
+	die "\n";
+    }
+
+    my $had_error = 0;
+    # pass this file by each of the plugins in turn until one
+    # is found which will process it
+    # read must return:
+    # undef - could not recognise
+    # -1 - tried but error
+    # 0 - blocked
+    # anything else for successful processing
+	
+    foreach my $plugobj (@$pluginfo) {
+
+	$rv = $plugobj->metadata_read($pluginfo, $base_dir, $file, $block_hash,
+			     $extrametakeys, $extrametadata, $extrametafile,
+			     $processor, $maxdocs, $gli, $aux);
+
+	if (defined $rv) {
+	    if ($rv == -1) {
+	        # an error has occurred
+		$had_error = 1;
+		print STDERR "<ProcessingError n='$glifile'>\n" if $gli;
+	    } else {
+        	return $rv;
+	    }
+	} # else undefined - was not recognised by the plugin
+    }
+
+    return 0;
+}
+
+sub read {
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli, $aux) = @_;
+
+    $maxdocs = -1 unless defined $maxdocs && $maxdocs =~ /\d/;
+    $total_count = 0 unless defined $total_count && $total_count =~ /\d/;
+    $gli = 0 unless defined $gli;
+
+    my $rv = 0;
+    my $glifile = $file;
+    
+    $glifile =~ s/^[\/\\]+//; # file sometimes starts with a / so get rid of it
+    
+    # Announce to GLI that we are handling a file
+    print STDERR "<File n='$glifile'>\n" if $gli;
+    
+    # the .kill file is a handy (if not very elegant) way of aborting 
+    # an import.pl or buildcol.pl process
+    if (-e &util::filename_cat ($ENV{'GSDLCOLLECTDIR'}, ".kill")) {
+	gsprintf($outhandle, "{plugin.kill_file}\n");
+	die "\n";
+    }
+
+    my $had_error = 0;
+    # pass this file by each of the plugins in turn until one
+    # is found which will process it
+    # read must return:
+    # undef - could not recognise
+    # -1 - tried but error
+    # 0 - blocked
+    # anything else for successful processing
+	
+    foreach my $plugobj (@$pluginfo) {
+
+      	$rv = $plugobj->read($pluginfo, $base_dir, $file, 
+			     $block_hash, $metadata, $processor, $maxdocs, 
+			     $total_count, $gli, $aux);
+
+	if (defined $rv) {
+	    if ($rv == -1) {
+	        # an error has occurred
+		$had_error = 1;
+	    } else {
+        	return $rv;
+	    }
+	} # else undefined - was not recognised by the plugin
+    }
+
+    if ($had_error) {
+	# was recognised but couldn't be processed
+	if ($verbosity >= 2) {
+	    gsprintf($outhandle, "{plugin.no_plugin_could_process}\n", $file);
+	}
+	# tell the GLI that it was not processed
+	print STDERR "<NonProcessedFile n='$glifile'>\n" if $gli;
+      
+	gsprintf($failhandle, "$file: {plugin.no_plugin_could_process_this_file}\n");
+	$stats->{'num_not_processed'} ++;
+    } else {
+	# was not recognised
+	if ($verbosity >= 2) {
+	    gsprintf($outhandle, "{plugin.no_plugin_could_recognise}\n",$file);
+	}
+	# tell the GLI that it was not processed
+	print STDERR "<NonRecognisedFile n='$glifile'>\n" if $gli;
+	
+	gsprintf($failhandle, "$file: {plugin.no_plugin_could_recognise_this_file}\n");
+	$stats->{'num_not_recognised'} ++;
+    }
+    return 0;
+}
+
+# write out some general stats that the plugins have compiled - note that
+# the buildcol.pl process doesn't currently call this process so the stats
+# are only output after import.pl -
+sub write_stats {
+    my ($pluginfo, $statshandle, $faillog, $gli) = @_;
+
+    $gli = 0 unless defined $gli;
+
+    foreach my $plugobj (@$pluginfo) {
+	$plugobj->compile_stats($stats);
+    }
+
+    my $total = $stats->{'num_processed'} + $stats->{'num_blocked'} + 
+	$stats->{'num_not_processed'} + $stats->{'num_not_recognised'};
+
+    print STDERR "<ImportComplete considered='$total' processed='$stats->{'num_processed'}' blocked='$stats->{'num_blocked'}' ignored='$stats->{'num_not_recognised'}' failed='$stats->{'num_not_processed'}'>\n" if $gli;
+
+    if ($total == 1) {
+	gsprintf($statshandle, "* {plugin.one_considered}\n");
+    } else {
+	gsprintf($statshandle, "* {plugin.n_considered}\n", $total);
+    }
+    if ($stats->{'num_archives'}) {
+	if ($stats->{'num_archives'} == 1) {
+	    gsprintf($statshandle, "   ({plugin.including_archive})\n");
+	}
+	else {
+	    gsprintf($statshandle, "   ({plugin.including_archives})\n",
+		     $stats->{'num_archives'});
+	}
+    }
+    if ($stats->{'num_processed'} == 1) {
+	gsprintf($statshandle, "* {plugin.one_included}\n");
+    } else {
+	gsprintf($statshandle, "* {plugin.n_included}\n", $stats->{'num_processed'});
+    }
+    if ($stats->{'num_not_recognised'}) {
+	if ($stats->{'num_not_recognised'} == 1) {
+	    gsprintf($statshandle, "* {plugin.one_unrecognised}\n");
+	} else {
+	    gsprintf($statshandle, "* {plugin.n_unrecognised}\n",
+		     $stats->{'num_not_recognised'});
+	}
+
+    }
+    if ($stats->{'num_not_processed'}) {
+	if ($stats->{'num_not_processed'} == 1) {
+	    gsprintf($statshandle, "* {plugin.one_rejected}\n");
+	} else {
+	    gsprintf($statshandle, "* {plugin.n_rejected}\n",
+		     $stats->{'num_not_processed'});
+	}
+    }
+    if ($stats->{'num_not_processed'} || $stats->{'num_not_recognised'}) {
+	gsprintf($statshandle, " {plugin.see_faillog}\n", $faillog);
+    }
+}
+
+sub end {
+    my ($pluginfo, $processor) = @_;
+    map { $_->end($processor); } @$pluginfo;
+}
+
+sub deinit {
+    my ($pluginfo, $processor) = @_;
+   
+
+    map { $_->deinit($processor); } @$pluginfo;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/AcronymExtractor.pm
===================================================================
--- /gsdl/stable/perllib/plugins/AcronymExtractor.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/AcronymExtractor.pm	(revision 20131)
@@ -0,0 +1,180 @@
+###########################################################################
+#
+# AcronymExtractor - helper plugin that extacts acronyms from text 
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2008 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package AcronymExtractor;
+
+use acronym;
+use PrintInfo;
+use strict;
+
+BEGIN {
+    @AcronymExtractor::ISA = ('PrintInfo');
+}
+
+my $arguments = [
+      { 'name' => "extract_acronyms",
+	'desc' => "{AcronymExtractor.extract_acronyms}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "markup_acronyms",
+	'desc' => "{AcronymExtractor.markup_acronyms}",
+	'type' => "flag",
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "AcronymExtractor",
+		'desc'     => "{AcronymExtractor.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new PrintInfo($pluginlist, $inputargs, $hashArgOptLists,1);
+
+    return bless $self, $class;
+
+}
+
+
+# initialise metadata extractors
+sub initialise_acronym_extractor {
+    my $self = shift (@_);
+
+    if ($self->{'extract_acronyms'} || $self->{'markup_acronyms'}) {
+	&acronym::initialise_acronyms();
+    }
+}
+
+# finalise metadata extractors
+sub finalise_acronym_extractor {
+    my $self = shift (@_);
+
+    if ($self->{'extract_acronyms'} || $self->{'markup_acronyms'}) {
+	&acronym::finalise_acronyms();
+    }
+}
+
+# extract metadata
+sub extract_acronym_metadata {
+
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+    
+
+    if ($self->{'extract_acronyms'}) {
+	my $thissection = $doc_obj->get_top_section();
+	while (defined $thissection) {
+	    my $text = $doc_obj->get_text($thissection);
+	    $self->extract_acronyms (\$text, $doc_obj, $thissection) if $text =~ /./;
+	    $thissection = $doc_obj->get_next_section ($thissection);
+	}
+    }
+    
+    if ($self->{'markup_acronyms'}) {
+	my $thissection = $doc_obj->get_top_section();
+	while (defined $thissection) {
+	    my $text = $doc_obj->get_text($thissection);
+	    $text = $self->markup_acronyms ($text, $doc_obj, $thissection);
+	    $doc_obj->delete_text($thissection);
+	    $doc_obj->add_text($thissection, $text);
+	    $thissection = $doc_obj->get_next_section ($thissection);
+	}
+    }
+
+}
+
+
+
+# extract acronyms from a section in a document. progress is 
+# reported to outhandle based on the verbosity. both the Acronym
+# and the AcronymKWIC metadata items are created. 
+
+sub extract_acronyms {
+    my $self = shift (@_);
+    my ($textref, $doc_obj, $thissection) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    # print $outhandle " extracting acronyms ...\n" 
+    gsprintf($outhandle, " {AcronymExtractor.extracting_acronyms}...\n")
+	if ($self->{'verbosity'} > 2);
+
+    my $acro_array =  &acronym::acronyms($textref);
+    
+    foreach my $acro (@$acro_array) {
+
+	#check that this is the first time ...
+	my $seen_before = "false";
+	my $previous_data = $doc_obj->get_metadata($thissection, "Acronym");
+	foreach my $thisAcro (@$previous_data) {
+	    if ($thisAcro eq $acro->to_string()) {
+		$seen_before = "true";
+		if ($self->{'verbosity'} >= 4) {
+		    gsprintf($outhandle, " {AcronymExtractor.already_seen} " .
+			     $acro->to_string() . "\n");
+		}
+	    }
+	}
+
+	if ($seen_before eq "false") {
+	    #write it to the file ...
+	    $acro->write_to_file();
+
+	    #do the normal acronym
+	    $doc_obj->add_utf8_metadata($thissection, "Acronym",  $acro->to_string());
+	    gsprintf($outhandle, " {AcronymExtractor.adding} ".$acro->to_string()."\n")
+		if ($self->{'verbosity'} > 3);
+	}
+    }
+
+    gsprintf($outhandle, " {AcronymExtractor.done_acronym_extract}\n")
+	if ($self->{'verbosity'} > 2);
+}
+
+sub markup_acronyms {
+    my $self = shift (@_);
+    my ($text, $doc_obj, $thissection) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    gsprintf($outhandle, " {AcronymExtractor.marking_up_acronyms}...\n")
+	if ($self->{'verbosity'} > 2);
+
+    #self is passed in to check for verbosity ...
+    $text = &acronym::markup_acronyms($text, $self);
+
+    gsprintf($outhandle, " {AcronymExtractor.done_acronym_markup}\n")
+	if ($self->{'verbosity'} > 2);
+
+    return $text;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/ArchivesInfPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/ArchivesInfPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/ArchivesInfPlugin.pm	(revision 20131)
@@ -0,0 +1,306 @@
+###########################################################################
+#
+# ArchivesInfPlugin.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# plugin which reads through an archives.inf (or GDBM equivalent,
+# archiveinf-doc.gdb file (i.e. the file generated in the
+# archives directory when an import is done), processing each file it
+# finds
+
+package ArchivesInfPlugin;
+
+use util;
+use doc;
+use PrintInfo;
+use plugin;
+use arcinfo;
+use gsprintf;
+use GDBMUtils;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+BEGIN {
+    @ArchivesInfPlugin::ISA = ('PrintInfo');
+}
+
+my $arguments = [
+		 ];
+
+my $options = { 'name'     => "ArchivesInfPlugin",
+		'desc'     => "{ArchivesInfPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes" };
+         
+sub gsprintf
+{
+    return &gsprintf::gsprintf(@_);
+}
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new PrintInfo($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+# called once, at the start of processing
+sub init {
+    my $self = shift (@_);
+    my ($verbosity, $outhandle, $failhandle) = @_;
+
+    # verbosity is passed through from the processor
+    $self->{'verbosity'} = $verbosity;
+
+    # as are the outhandle and failhandle
+    $self->{'outhandle'} = $outhandle if defined $outhandle;
+    $self->{'failhandle'} = $failhandle;
+
+}
+
+sub deinit {
+    my ($self) = @_;
+
+    my $archive_info = $self->{'archive_info'};
+    my $verbosity = $self->{'verbosity'};
+    my $outhandle = $self->{'outhandle'};
+
+    if (defined $archive_info) {
+	my $archive_info_filename = $self->{'archive_info_filename'};
+
+       	my $file_list = $archive_info->get_file_list();
+
+	foreach my $subfile (@$file_list) {	    
+	    my $doc_oid = $subfile->[1];
+
+	    my $index_status = $archive_info->get_status_info($doc_oid);
+
+	    if ($index_status eq "D") {
+		# delete
+		$archive_info->delete_info($doc_oid);
+		&GDBMUtils::gdbmDatabaseRemove($archive_info_filename,$doc_oid);
+
+		my $doc_file = $subfile->[0];
+		my $base_dir =$self->{'base_dir'};
+
+		my $doc_filename = &util::filename_cat($base_dir,$doc_file);
+
+		my ($doc_tailname, $doc_dirname, $suffix) 
+		    = File::Basename::fileparse($doc_filename, "\\.[^\\.]+\$");
+
+		print $outhandle "Removing $doc_dirname\n" if ($verbosity>2);
+
+		&util::rm_r($doc_dirname);
+
+
+	    }
+	    elsif ($index_status =~ m/^(I|R)$/) {
+		# mark as "been indexed"
+		$archive_info->set_status_info($doc_oid,"B");
+	    }
+	}
+
+	$archive_info->save_info($archive_info_filename);
+    }
+}
+
+# called at the beginning of each plugin pass (import has one, buildin has many)
+sub begin {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $processor, $maxdocs) = @_;
+
+    $self->{'base_dir'} = $base_dir;
+}
+
+# called at the end of each plugin pass
+sub end {
+    my ($self) = shift (@_);
+
+}
+
+# called if we are doing incremental building
+sub set_incremental {
+    my $self = shift(@_);
+    my ($incremental) = @_;
+
+    $self->{'incremental'} = $incremental;
+}
+
+# return 1 if this class might recurse using $pluginfo
+sub is_recursive {
+    my $self = shift (@_);
+
+    return 1;
+}
+
+
+sub compile_stats {
+    my $self = shift(@_);
+    my ($stats) = @_;
+}
+
+# We don't do metadata_read
+sub metadata_read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, 
+	$extrametakeys, $extrametadata, $extrametafile,
+	$processor, $maxdocs, $gli) = @_;
+
+    return undef;
+}
+
+sub file_block_read {
+
+    my $self = shift (@_);  
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $gli) = @_;
+
+    if ($file eq "OIDcount") {
+	my ($filename_full_path, $filename_no_path) 
+	    = &util::get_full_filenames($base_dir, $file);
+	$block_hash->{'file_blocks'}->{$filename_full_path} = 1;
+	return 1;
+    }
+
+    # otherwise, we don't do any file blocking
+
+    return undef;
+}
+
+
+# return number of files processed, undef if can't process
+# Note that $base_dir might be "" and that $file might 
+# include directories
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs,$total_count, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my $count = 0;
+
+    # see if this has a archives information file within it
+##    my $archive_info_filename = &util::filename_cat($base_dir,$file,"archives.inf");
+
+    my $doc_db = "archiveinf-doc.gdb";
+    my $archive_info_filename = &util::filename_cat($base_dir,$file,$doc_db);
+
+    if (-e $archive_info_filename) {
+
+	# found an archives.inf file
+	&gsprintf($outhandle, "ArchivesInfPlugin: {common.processing} $archive_info_filename\n") if $self->{'verbosity'} > 1;
+
+	# read in the archives information file
+	my $archive_info = new arcinfo ();
+	$self->{'archive_info'} = $archive_info;
+	$self->{'archive_info_filename'} = $archive_info_filename;
+
+	$archive_info->load_info ($archive_info_filename);
+	
+	my $file_list = $archive_info->get_file_list();
+
+	# process each file
+	foreach my $subfile (@$file_list) {
+
+	    last if ($maxdocs != -1 && ($total_count + $count) >= $maxdocs);
+
+	    my $tmp = &util::filename_cat ($file, $subfile->[0]);
+	    next if $tmp eq $file;
+
+	    my $doc_oid = $subfile->[1];
+	    my $index_status = $archive_info->get_status_info($doc_oid);
+
+	    my $curr_mode = $processor->get_mode();
+	    my $new_mode = $curr_mode;
+
+	    # Start by assuming we want to process the file...
+	    my $process_file = 1;
+
+	    # ...unless the build processor is incremental capable and -incremental was specified, in which case we need to check its index_status flag
+	    if ($processor->is_incremental_capable() && $self->{'incremental'})
+	    {
+	        # Check to see if the file needs indexing
+		if ($index_status eq "B")
+		{
+		    # Don't process this file as it has already been indexed
+		    $process_file = 0;
+		}
+		elsif ($index_status eq "D") {
+		    # Need to be delete it from the index.
+		    $new_mode = $curr_mode."delete";
+		    $process_file = 1;
+		}
+		elsif ($index_status eq "R") {
+		    # Need to be reindexed/replaced
+		    $new_mode = $curr_mode."reindex";
+
+		    $process_file = 1;
+		}
+	    }
+	    # ... or we're being asked to delete it (in which case skip it)
+	    elsif ($index_status eq "D") {
+		# Non-incremental Delete
+		# It's already been deleted from the archives directory
+		# (done during import.pl)
+		# => All we need to do here is not process it
+
+		$process_file = 0;
+	    }
+
+	    if (!$processor->is_incremental_capable() && $self->{'incremental'}) {
+		# Nag feature
+		if (!defined $self->{'incremental-warning'}) {
+		    print $outhandle "\n";
+		    print $outhandle "Warning: command-line option '-incremental' used with *non-incremental*\n";
+		    print $outhandle "         processor '", ref $processor, "'. Some conflicts may arise.\n";
+		    print $outhandle "\n";
+		    sleep 10;
+		    $self->{'incremental-warning'} = 1;
+		}
+	    }
+
+	    if ($process_file) {
+		# note: metadata is not carried on to the next level
+		
+		$processor->set_mode($new_mode) if ($new_mode ne $curr_mode);
+
+		$count += &plugin::read ($pluginfo, $base_dir, $tmp, $block_hash, {}, $processor, $maxdocs, ($total_count+$count), $gli);
+
+		$processor->set_mode($curr_mode) if ($new_mode ne $curr_mode);
+	    }
+	}
+
+	return $count;
+    }
+
+
+    # wasn't an archives directory, someone else will have to process it
+    return undef;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/AutoExtractMetadata.pm
===================================================================
--- /gsdl/stable/perllib/plugins/AutoExtractMetadata.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/AutoExtractMetadata.pm	(revision 20131)
@@ -0,0 +1,150 @@
+###########################################################################
+#
+# AutoExtractMetadata.pm -- base plugin for all plugins that want to do metadata extraction from text and/or metadata 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2008 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# This plugin uses the supporting Extractors to add metadata extraction 
+# functionality to BasePlugin.
+
+
+package AutoExtractMetadata;
+
+use strict; 
+no strict 'subs';
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+use BasePlugin;
+use AcronymExtractor;
+use KeyphraseExtractor;
+use EmailAddressExtractor;
+use DateExtractor;
+use GISExtractor;
+
+sub BEGIN {
+    @AutoExtractMetadata::ISA = ( 'BasePlugin', 'AcronymExtractor', 'KeyphraseExtractor', 'EmailAddressExtractor', 'DateExtractor','GISExtractor' );
+}
+
+my $arguments = [
+		 {'name' => "first",
+		  'desc' => "{AutoExtractMetadata.first}",
+		  'type' => "string",
+		  'reqd' => "no" }
+		 ];
+
+
+my $options = { 'name'     => "AutoExtractMetadata",
+		'desc'     => "{AutoExtractMetadata.desc}",
+		'abstract' => "yes",
+		'inherits' => "no",
+		'args'     => $arguments };
+
+
+sub new {
+
+    # Start the AutoExtractMetadata Constructor
+    my $class = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists,$auxiliary) = @_;
+    push(@$pluginlist, $class);
+    
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    # load up the options and args for the supporting plugins
+    new AcronymExtractor($pluginlist, $inputargs, $hashArgOptLists);
+    new KeyphraseExtractor($pluginlist, $inputargs, $hashArgOptLists);
+    new EmailAddressExtractor($pluginlist, $inputargs, $hashArgOptLists);
+    new DateExtractor($pluginlist, $inputargs, $hashArgOptLists);
+    new GISExtractor($pluginlist, $inputargs, $hashArgOptLists);
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists,$auxiliary);
+
+    return bless $self, $class;
+    
+}
+
+sub begin {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $processor, $maxdocs) = @_;
+
+    $self->SUPER::begin(@_);
+
+    #initialise those extractors that need initialisation
+    $self->initialise_acronym_extractor();
+    $self->initialise_gis_extractor();
+
+}
+
+sub end {
+    # potentially called at the end of each plugin pass 
+    # import.pl only has one plugin pass, but buildcol.pl has multiple ones
+
+    my ($self) = @_;
+    # finalise those extractors that need finalisation
+    $self->finalise_acronym_extractor();
+}
+
+# here is where we call methods from the supporting extractor plugins 
+sub auto_extract_metadata {
+    my $self = shift(@_);
+    my ($doc_obj) = @_;
+
+    if ($self->{'first'}) {
+	my $thissection = $doc_obj->get_top_section();
+	while (defined $thissection) {
+	    my $text = $doc_obj->get_text($thissection);
+	    $self->extract_first_NNNN_characters (\$text, $doc_obj, $thissection) if $text =~ /./;
+	    $thissection = $doc_obj->get_next_section ($thissection);
+	}
+    }
+    $self->extract_acronym_metadata($doc_obj);
+    $self->extract_keyphrase_metadata($doc_obj);
+    $self->extract_email_metadata($doc_obj);
+    $self->extract_date_metadata($doc_obj);
+    $self->extract_gis_metadata($doc_obj);
+
+}
+
+
+# FIRSTNNN: extract the first NNN characters as metadata
+sub extract_first_NNNN_characters {
+    my $self = shift (@_);
+    my ($textref, $doc_obj, $thissection) = @_;
+    
+    foreach my $size (split /,/, $self->{'first'}) {
+	my $tmptext =  $$textref;
+	$tmptext =~ s/^\s+//;
+	$tmptext =~ s/\s+$//;
+	$tmptext =~ s/\s+/ /gs;
+	$tmptext = substr ($tmptext, 0, $size);
+	$tmptext =~ s/\s\S*$/&#8230;/;
+	$doc_obj->add_utf8_metadata ($thissection, "First$size", $tmptext);
+    }
+}
+
+sub clean_up_after_doc_obj_processing {
+    my $self = shift(@_);
+
+    $self->SUPER::clean_up_after_doc_obj_processing();
+    $self->GISExtractor::clean_up_temp_files();
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/BaseMediaConverter.pm
===================================================================
--- /gsdl/stable/perllib/plugins/BaseMediaConverter.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/BaseMediaConverter.pm	(revision 20131)
@@ -0,0 +1,226 @@
+###########################################################################
+#
+# BaseMediaConverter - helper plugin that provide base functionality for 
+#                  image/video conversion using ImageMagick/ffmpeg
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2008 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+package BaseMediaConverter;
+
+use PrintInfo;
+
+use convertutil;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+use gsprintf 'gsprintf';
+
+BEGIN {
+    @BaseMediaConverter::ISA = ('PrintInfo');
+}
+
+my $arguments = [
+      { 'name' => "enable_cache",
+	'desc' => "{BaseMediaConverter.enable_cache}",
+	'type' => "flag",
+	'reqd' => "no",
+	}
+
+		 ];
+
+my $options = { 'name' => "BaseMediaConverter",
+		'desc' => "{BaseMediaConverter.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+		'args' => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists,$auxiliary) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new PrintInfo($pluginlist, $inputargs, $hashArgOptLists, $auxiliary);
+
+    return bless $self, $class;
+}
+
+sub begin {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $processor, $maxdocs) = @_;
+
+    # Save base_dir for use in file cache
+    $self->{'base_dir'} = $base_dir;
+
+}
+
+
+sub init_cache_for_file
+{
+    my $self = shift @_;
+    my ($filename) = @_;
+
+    my $verbosity = $self->{'verbosity'};
+    my $outhandle = $self->{'outhandle'};
+    my $base_dir = $self->{'base_dir'};
+    
+    # Work out relative filename within 'base_dir'
+    $filename =~ s/\\/\//g;
+    my ($file) = ($filename =~ m/^$base_dir(.*?)$/);
+    
+    $file =~ s/^\/|\\//; # get rid of leading slash from relative filename
+
+    # Setup cached_dir and file_root
+
+    my ($file_root, $dirname, $suffix)
+	= &File::Basename::fileparse($file, "\\.[^\\.]+\$");
+
+    my $collect_dir = $ENV{'GSDLCOLLECTDIR'};
+    $collect_dir =~ s/\\/\//g; # Work in Unix style world
+
+    # if dirname is in collections tmp area, remove collect_dir prefix
+    $dirname =~ s/^$collect_dir//;
+
+    if ($ENV{'GSDLOS'} eq "windows") {
+	# if dirname starts with Windows drive letter, strip it off
+	$dirname =~ s/^[a-z]:\///i;
+    }
+
+    my $base_output_dir = &util::filename_cat($collect_dir,"cached",$dirname);
+
+    if (!-e $base_output_dir ) {
+	print $outhandle "Creating directory $base_output_dir\n"
+	    if ($verbosity>2);
+
+	&util::mk_all_dir($base_output_dir);
+    }
+
+    my $output_dir = &util::filename_cat($base_output_dir,$file_root);
+
+    if (!-e $output_dir) {
+	print $outhandle "Creating directory $output_dir\n"
+	    if ($verbosity>2);
+
+	&util::mk_dir($output_dir);
+    }
+
+    $self->{'cached_dir'} = $output_dir;
+    $self->{'cached_file_root'} = $file_root;    
+}
+
+
+
+sub run_general_cmd
+{
+    my $self = shift @_;
+    my ($command,$print_info) = @_;
+
+
+    if (!defined $print_info->{'verbosity'}) {
+	$print_info->{'verbosity'} = $self->{'verbosity'};
+    }
+
+    if (!defined $print_info->{'outhandle'}) {
+	$print_info->{'outhandle'} = $self->{'outhandle'};
+    }
+
+    
+    return &convertutil::run_general_cmd(@_);
+}
+
+
+sub regenerate_general_cmd
+{
+    my $self = shift @_;
+    my ($command,$ofilename,$print_info) = @_;
+
+    if (!defined $print_info->{'verbosity'}) {
+	$print_info->{'verbosity'} = $self->{'verbosity'};
+    }
+
+    if (!defined $print_info->{'outhandle'}) {
+	$print_info->{'outhandle'} = $self->{'outhandle'};
+    }
+
+    return &convertutil::regenerate_general_cmd(@_);
+}
+
+
+
+sub run_uncached_general_cmd
+{
+    my $self = shift @_;
+
+    my ($command,$ofilename,$print_info) = @_;
+
+    return $self->run_general_cmd($command,$print_info);
+}
+
+
+
+sub run_cached_general_cmd
+{
+    my $self = shift @_;
+
+    my ($command,$ofilename,$print_info) = @_;
+
+    if (!defined $print_info->{'verbosity'}) {
+	$print_info->{'verbosity'} = $self->{'verbosity'};
+    }
+
+    if (!defined $print_info->{'outhandle'}) {
+	$print_info->{'outhandle'} = $self->{'outhandle'};
+    }
+
+    return &convertutil::run_cached_general_cmd(@_);
+}
+
+
+
+sub autorun_general_cmd
+{
+    my $self = shift @_;
+
+    my ($command,$ofilename,$print_info) = @_;
+
+    my $result;
+    my $regenerated;
+    my $had_error;
+
+    if ($self->{'enable_cache'}) {
+	($regenerated,$result,$had_error)
+	    = $self->run_cached_general_cmd($command,$ofilename,$print_info);
+    }
+    else {
+	$regenerated = 1; # always true for a command that is always run
+	($result,$had_error)
+	    = $self->run_general_cmd($command,$print_info);
+    }
+
+    return ($regenerated,$result,$had_error);
+}
+
+
+#
+1;	
Index: /gsdl/stable/perllib/plugins/BasePlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/BasePlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/BasePlugin.pm	(revision 20131)
@@ -0,0 +1,1144 @@
+###########################################################################
+#
+# BasePlugin.pm -- base class for all the import plugins
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2005 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package BasePlugin;
+
+use strict; 
+no strict 'subs';
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+use File::Basename;
+
+use encodings;
+use unicode;
+use textcat;
+use doc;
+use ghtml;
+use gsprintf 'gsprintf';
+
+use PrintInfo;
+
+BEGIN {
+    @BasePlugin::ISA = ( 'PrintInfo' );
+}
+
+# the different methods that can be applied when renaming
+# imported documents and their associated files
+our $file_rename_method_list = 
+    [ { 'name' => "url",
+	'desc' => "{BasePlugin.rename_method.url}" },
+      { 'name' => "base64",
+	'desc' => "{BasePlugin.rename_method.base64}" }, 
+      { 'name' => "none",
+	'desc' => "{BasePlugin.rename_method.none}", 
+	'hiddengli' => "yes" } ];
+
+our $encoding_list =
+    [ { 'name' => "ascii",
+	'desc' => "{BasePlugin.encoding.ascii}" },
+      { 'name' => "utf8",
+	'desc' => "{BasePlugin.encoding.utf8}" },
+      { 'name' => "unicode",
+	'desc' => "{BasePlugin.encoding.unicode}" } ];
+      
+
+my $e = $encodings::encodings;
+foreach my $enc (sort {$e->{$a}->{'name'} cmp $e->{$b}->{'name'}} keys (%$e)) 
+{
+    my $hashEncode =
+    {'name' => $enc,
+     'desc' => $e->{$enc}->{'name'}};
+    
+    push(@{$encoding_list},$hashEncode);
+}
+
+our $encoding_plus_auto_list = 
+    [ { 'name' => "auto",
+	'desc' => "{BasePlugin.filename_encoding.auto}" },
+       { 'name' => "auto-language-analysis",
+	'desc' => "{BasePlugin.filename_encoding.auto_language_analysis}" }, # textcat
+      { 'name' => "auto-filesystem-encoding",
+	'desc' => "{BasePlugin.filename_encoding.auto_filesystem_encoding}" }, # locale
+      { 'name' => "auto-fl",
+	'desc' => "{BasePlugin.filename_encoding.auto_fl}" }, # locale followed by textcat
+      { 'name' => "auto-lf",
+	'desc' => "{BasePlugin.filename_encoding.auto_lf}" } ]; # texcat followed by locale 
+
+push(@{$encoding_plus_auto_list},@{$encoding_list});
+
+our $oidtype_list = 
+    [ { 'name' => "auto",
+	'desc' => "{BasePlugin.OIDtype.auto}" },
+      { 'name' => "hash",
+        'desc' => "{import.OIDtype.hash}" },
+      { 'name' => "assigned",
+        'desc' => "{import.OIDtype.assigned}" },
+      { 'name' => "incremental",
+        'desc' => "{import.OIDtype.incremental}" },
+      { 'name' => "dirname",
+        'desc' => "{import.OIDtype.dirname}" } ];
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "no_blocking",
+	'desc' => "{BasePlugin.no_blocking}",
+	'type' => "flag",
+	'reqd' => "no"},
+      { 'name' => "block_exp",
+	'desc' => "{BasePlugin.block_exp}",
+	'type' => "regexp",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "associate_ext",
+	'desc' => "{BasePlugin.associate_ext}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "associate_tail_re",
+	'desc' => "{BasePlugin.associate_tail_re}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "OIDtype",
+	'desc' => "{import.OIDtype}",
+	'type' => "enum",
+	'list' => $oidtype_list,
+	# leave default empty so we can tell if its been set or not - if not set will use option from import.pl
+	'deft' => "auto",
+	'reqd' => "no" },
+      { 'name' => "OIDmetadata",
+	'desc' => "{import.OIDmetadata}",
+	'type' => "metadata",
+	'deft' => "dc.Identifier",
+	'reqd' => "no" },      
+#      { 'name' => "use_as_doc_identifier",
+#	'desc' => "{BasePlugin.use_as_doc_identifier}",
+#	'type' => "string",
+#	'reqd' => "no" ,
+#	'deft' => "" } ,
+      { 'name' => "no_cover_image",
+	'desc' => "{BasePlugin.no_cover_image}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "filename_encoding",
+	'desc' => "{BasePlugin.filename_encoding}",
+	'type' => "enum",
+	'deft' => "auto",
+	'list' => $encoding_plus_auto_list,
+	'reqd' => "no" },
+      { 'name' => "smart_block",
+        'desc' => "{common.deprecated}. {BasePlugin.smart_block}",
+        'type' => "flag",
+        'reqd' => "no",
+	'hiddengli' => "yes" }, # deprecated, but leave in for old collections
+      { 'name' => "file_rename_method",
+	'desc' => "{BasePlugin.file_rename_method}",
+	'type' => "enum",
+	'deft' => &get_default_file_rename_method(), # by default rename imported files and assoc files using this encoding
+	'list' => $file_rename_method_list,
+	'reqd' => "no"
+      }
+      
+      ];
+
+
+my $options = { 'name'     => "BasePlugin",
+		'desc'     => "{BasePlugin.desc}",
+		'abstract' => "yes",
+		'inherits' => "no",
+		'args'     => $arguments };
+
+sub new {
+
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists,$auxiliary) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new PrintInfo($pluginlist, $inputargs, $hashArgOptLists,$auxiliary);
+    
+    if ($self->{'info_only'}) {
+        # don't worry about any options etc
+        return bless $self, $class;
+    }
+
+    if ($self->{'smart_block'}) {
+	print STDERR "WARNING: -smart_block option has been deprecated and is no longer useful\n";
+    }
+    $self->{'smart_block'} = undef;
+
+    my $plugin_name = (defined $pluginlist->[0]) ? $pluginlist->[0] : $class;
+    $self->{'plugin_type'} = $plugin_name;
+
+    $self->{'num_processed'} = 0;
+    $self->{'num_not_processed'} = 0;
+    $self->{'num_blocked'} = 0;
+    $self->{'num_archives'} = 0;
+    $self->{'cover_image'} = 1; # cover image is on by default
+    $self->{'cover_image'} = 0 if ($self->{'no_cover_image'});
+    $self->{'can_process_directories'} = 0;
+    #$self->{'option_list'} = $hashArgOptLists->{"OptList"};
+    
+    my $associate_ext = $self->{'associate_ext'};
+    if ((defined $associate_ext) && ($associate_ext ne "")) {
+
+	my $associate_tail_re = $self->{'associate_tail_re'};
+	if ((defined $associate_tail_re) && ($associate_tail_re ne "")) {
+	    my $outhandle = $self->{'outhandle'};
+	    print $outhandle "Warning: can only specify 'associate_ext' or 'associate_tail_re'\n";
+	    print $outhandle "         defaulting to 'associate_tail_re'\n";
+	}
+	else {
+	    my @exts = split(/,/,$associate_ext);
+
+	    my @exts_bracketed = map { $_ = "(?:\\.$_)" } @exts;
+	    my $associate_tail_re = join("|",@exts_bracketed);
+	    $self->{'associate_tail_re'} = $associate_tail_re;
+	}
+
+	delete $self->{'associate_ext'};
+    }
+
+    return bless $self, $class;
+
+}
+
+sub merge_inheritance
+{
+    my $self = {};
+    my @child_selfs = @_;
+
+    foreach my $child_self (@child_selfs) {	
+	foreach my $key (keys %$child_self) {
+	    if (defined $self->{$key}) {
+		if ($self->{$key} ne $child_self->{$key}) {
+#		    print STDERR "Warning: Conflicting value in multiple inheritance for '$key'\n";
+#		    print STDERR "Existing stored value = $self->{$key}\n";
+#		    print STDERR "New (child) value     = $child_self->{$key}\n";
+#		    print STDERR "Keeping existing value\n";
+		    # Existing value seems to be option specified in collect.cfg
+
+		    ### $self->{$key} = $child_self->{$key};
+		    
+		}
+		else {
+##		    print STDERR "****Info: Value $self->{$key} for $key already defined through multiple inheritance as the same value\n";
+		}
+
+	    }
+	    else {
+		$self->{$key} = $child_self->{$key};
+	    }
+	}
+    }
+
+    return $self;	
+}
+
+# initialize BasePlugin options
+# if init() is overridden in a sub-class, remember to call BasePlugin::init()
+sub init {
+    my $self = shift (@_);
+    my ($verbosity, $outhandle, $failhandle) = @_;
+
+    # verbosity is passed through from the processor
+    $self->{'verbosity'} = $verbosity;
+
+    # as are the outhandle and failhandle
+    $self->{'outhandle'} = $outhandle if defined $outhandle;
+    $self->{'failhandle'} = $failhandle;
+#    $self->SUPER::init(@_);
+    
+    # set process_exp and block_exp to defaults unless they were
+    # explicitly set
+
+    if ((!$self->is_recursive()) and 
+	(!defined $self->{'process_exp'}) || ($self->{'process_exp'} eq "")) {
+
+	$self->{'process_exp'} = $self->get_default_process_exp ();
+	if ($self->{'process_exp'} eq "") {
+	    warn ref($self) . " Warning: Non-recursive plugin has no process_exp\n";
+	}
+    }
+
+    if ((!defined $self->{'block_exp'}) || ($self->{'block_exp'} eq "")) {
+	$self->{'block_exp'} = $self->get_default_block_exp ();
+    }
+
+}
+
+sub begin {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $processor, $maxdocs) = @_;
+
+    if ($self->{'OIDtype'} eq "auto") {
+	# hasn't been set in the plugin, use the processor values
+	$self->{'OIDtype'} = $processor->{'OIDtype'};
+	$self->{'OIDmetadata'} = $processor->{'OIDmetadata'};
+    }
+    if ($self->{'OIDtype'} eq "hash") {
+	# should we hash on the file or on the doc xml??
+	$self->{'OIDtype'} = $self->get_oid_hash_type();
+	if ($self->{'OIDtype'} !~ /^(hash_on_file|hash_on_ga_xml)$/) {
+	    $self->{'OIDtype'} = "hash_on_file";
+	}
+    }
+}
+
+sub end {
+    # potentially called at the end of each plugin pass 
+    # import.pl only has one plugin pass, but buildcol.pl has multiple ones
+
+    my ($self) = shift (@_);
+}
+
+sub deinit {
+    # called only once, after all plugin passes have been done
+
+    my ($self) = @_;
+}
+
+# default hashing type is to hash on the original file (or converted file)
+# override this to return hash_on_ga_xml for filetypes where hashing on the 
+# file is no good eg video
+sub get_oid_hash_type {
+
+    my $self = shift (@_);
+
+    return "hash_on_file";
+}
+
+sub set_incremental {
+    my $self = shift(@_);
+    my ($incremental) = @_;
+
+    $self->{'incremental'} = $incremental;
+}
+
+# this function should be overridden to return 1
+# in recursive plugins
+sub is_recursive {
+    my $self = shift (@_);
+
+    return 0; 
+}
+
+sub get_default_block_exp {
+    my $self = shift (@_);
+
+    return "";
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return "";
+}
+
+# rename imported files and assoc files using URL encoding by default
+# as this will work for most plugins and give more legible filenames
+sub get_default_file_rename_method() {
+    my $self = shift (@_);
+    return "url";
+}
+
+# returns this plugin's active (possibly user-selected) file_rename_method
+sub get_file_rename_method() {
+    my $self = shift (@_);
+    my $rename_method = $self->{'file_rename_method'};
+    if($rename_method) {
+	return $rename_method;
+    } else {	
+	return $self->get_default_file_rename_method();
+    }
+}
+
+# default implementation is to do nothing
+sub store_block_files {
+    
+    my $self =shift (@_);
+    my ($filename_full_path, $block_hash) = @_;
+
+}
+
+# put files to block into hash 
+sub use_block_expressions {
+
+    my $self =shift (@_);
+    my ($filename_full_path, $block_hash) = @_;
+
+    if ($self->{'block_exp'} ne "" && $filename_full_path =~ /$self->{'block_exp'}/) {
+	$block_hash->{'file_blocks'}->{$filename_full_path} = 1;
+    }
+
+}
+
+#default implementation is to block a file with same name as this, but extension jpg or JPG, if cover_images is on.
+sub block_cover_image
+{
+    my $self =shift;
+    my ($filename, $block_hash) = @_;
+
+    if ($self->{'cover_image'}) {
+	my $coverfile = $filename;
+	$coverfile =~ s/\.[^\\\/\.]+$/\.jpg/;
+	if (!-e $coverfile) {
+	    $coverfile =~ s/jpg$/JPG/;
+	} 	
+	if (-e $coverfile) {
+	    $block_hash->{'file_blocks'}->{$coverfile} = 1;
+	} 
+    }
+
+    return;
+}
+
+
+# discover all the files that should be blocked by this plugin
+# check the args ...
+sub file_block_read {
+
+    my $self = shift (@_);  
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $gli) = @_;
+    # Keep track of filenames with same root but different extensions
+    # Used to support -associate_ext and the more generalised
+    # -associate_tail_re
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+
+    if (!-d $filename_full_path) {
+	$block_hash->{'all_files'}->{$file} = 1;
+    }
+
+    my $associate_tail_re = $self->{'associate_tail_re'};
+    if ((defined $associate_tail_re) && ($associate_tail_re ne "")) {
+	my ($file_prefix,$file_ext) 
+	    = &util::get_prefix_and_tail_by_regex($filename_full_path,$associate_tail_re);
+	if ((defined $file_prefix) && (defined $file_ext)) {
+	    my $shared_fileroot = $block_hash->{'shared_fileroot'};
+	    if (!defined $shared_fileroot->{$file_prefix}) {
+		my $file_prefix_rec = { 'tie_to'  => undef, 
+				        'exts'    => {} };
+		$shared_fileroot->{$file_prefix} = $file_prefix_rec;
+	    }
+	    
+	    my $file_prefix_rec = $shared_fileroot->{$file_prefix};
+
+	    if ($self->can_process_this_file($filename_full_path)) {
+		# This is the document the others should be tied to
+		$file_prefix_rec->{'tie_to'} = $file_ext;
+	    }
+	    else {
+		if ($file_ext =~ m/$associate_tail_re$/) {
+		    # this file should be associated to the main one
+		    $file_prefix_rec->{'exts'}->{$file_ext} = 1;
+		}
+	    }
+
+	}
+    }
+
+    # check block expressions
+    $self->use_block_expressions($filename_full_path, $block_hash) unless $self->{'no_blocking'};
+
+    # now check whether we are actually processing this
+    if (!-f $filename_full_path || !$self->can_process_this_file($filename_full_path)) {
+	return undef; # can't recognise
+    }
+   
+    # if we have a block_exp, then this overrides the normal 'smart' blocking
+    $self->store_block_files($filename_full_path, $block_hash) unless ($self->{'no_blocking'} || $self->{'block_exp'} ne "");
+
+    # block the cover image if there is one
+    if ($self->{'cover_image'}) {
+	$self->block_cover_image($filename_full_path, $block_hash); 
+    }
+       
+    return 1;
+}
+
+# plugins that rely on more than process_exp (eg XML plugins) can override this method
+sub can_process_this_file {
+    my $self = shift(@_);
+    my ($filename) = @_;
+
+    if (-d $filename && !$self->{'can_process_directories'}) {
+	return 0;
+    }
+    if ($self->{'process_exp'} ne "" && $filename =~ /$self->{'process_exp'}/) {
+	return 1;
+    }
+    return 0;
+    
+}
+
+# just converts path as is to utf8.
+sub filepath_to_utf8 {
+    my $self = shift (@_);  
+    my ($file, $file_encoding) = @_;
+    my $filemeta = $file;
+
+    my $filename_encoding = $self->{'filename_encoding'}; # filename encoding setting
+
+    # Whenever filename-encoding is set to any of the auto settings, we
+    # check if the filename is already in UTF8. If it is, then we're done.
+    if($filename_encoding =~ m/auto/) {
+	if(&unicode::check_is_utf8($filemeta)) 
+	{
+	    $filename_encoding = "utf8";
+	    return $filemeta;
+	} 
+    }
+    
+    # Auto setting, but filename is not utf8
+    if ($filename_encoding eq "auto") 
+    {
+	# try textcat
+	$filename_encoding = $self->textcat_encoding($filemeta);
+	
+	# check the locale next
+	$filename_encoding = $self->locale_encoding() if $filename_encoding eq "undefined";
+	
+
+	# now try the encoding of the document, if available
+	if ($filename_encoding eq "undefined" && defined $file_encoding) {
+	    $filename_encoding = $file_encoding;
+	}
+
+    }
+
+    elsif ($filename_encoding eq "auto-language-analysis") 
+    {	
+	$filename_encoding = $self->textcat_encoding($filemeta);
+
+	# now try the encoding of the document, if available
+	if ($filename_encoding eq "undefined" && defined $file_encoding) {
+	    $filename_encoding = $file_encoding;
+	} 
+    }
+
+    elsif ($filename_encoding eq "auto-filesystem-encoding") 
+    {
+	# try locale
+	$filename_encoding = $self->locale_encoding();
+    }
+
+    elsif ($filename_encoding eq "auto-fl") 
+    {
+	# filesystem-encoding (locale) then language-analysis (textcat)
+	$filename_encoding = $self->locale_encoding();
+	
+	# try textcat
+	$filename_encoding = $self->textcat_encoding($filemeta) if $filename_encoding eq "undefined";
+	    
+	# else assume filename encoding is encoding of file content, if that's available
+	if ($filename_encoding eq "undefined" && defined $file_encoding) {
+	    $filename_encoding = $file_encoding;
+	}
+    }
+	
+    elsif ($filename_encoding eq "auto-lf") 
+    {
+	# language-analysis (textcat) then filesystem-encoding (locale)
+	$filename_encoding = $self->textcat_encoding($filemeta);
+	
+	# guess filename encoding from encoding of file content, if available
+	if ($filename_encoding eq "undefined" && defined $file_encoding) {
+	    $filename_encoding = $file_encoding;
+	}
+
+	# try locale
+	$filename_encoding = $self->locale_encoding() if $filename_encoding eq "undefined";
+    }
+    	
+    # if still undefined, use utf8 as fallback
+    if ($filename_encoding eq "undefined") {
+	$filename_encoding = "utf8";
+    }
+
+    #print STDERR "**** UTF8 encoding the filename $filemeta ";
+    
+    # if the filename encoding is set to utf8 but it isn't utf8 already--such as when
+    # 1. the utf8 fallback is used, or 2. if the system locale is used and happens to
+    # be always utf8 (in which case the filename's encoding is also set as utf8 even 
+    # though the filename need not be if it originates from another system)--in such
+    # cases attempt to make the filename utf8 to match.
+    if($filename_encoding eq "utf8" && !&unicode::check_is_utf8($filemeta)) {
+	&unicode::ensure_utf8(\$filemeta);
+    }
+
+    # convert non-unicode encodings to utf8
+    if ($filename_encoding !~ m/(?:ascii|utf8|unicode)/) {
+	$filemeta = &unicode::unicode2utf8(
+	  &unicode::convert2unicode($filename_encoding, \$filemeta)
+	);
+    }
+
+    #print STDERR " from encoding $filename_encoding -> $filemeta\n";
+    return $filemeta;
+}
+
+# gets the filename with no path, converts to utf8, and then dm safes it.
+# filename_encoding set by user
+sub filename_to_utf8_metadata
+{
+    my $self = shift (@_);  
+    my ($file, $file_encoding) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+
+    my ($filemeta) = $file =~ /([^\\\/]+)$/; # getting the tail of the filepath (skips all string parts containing slashes upto the end)
+    $filemeta = $self->filepath_to_utf8($filemeta, $file_encoding);
+    
+    my $dmsafe_filemeta = &ghtml::dmsafe($filemeta);
+
+    return $dmsafe_filemeta;
+
+}
+
+sub locale_encoding {
+    my $self = shift(@_);
+    
+    if (!defined $self->{'filesystem_encoding'}) {
+	$self->{'filesystem_encoding'} = $self->get_filesystem_encoding();
+	$self->{'filesystem_encoding'} = "undefined" if !defined $self->{'filesystem_encoding'};
+    }
+
+    #print STDERR "*** filename encoding determined based on locale: " . $self->{'filesystem_encoding'} . "\n";
+    return $self->{'filesystem_encoding'}; # can be the string "undefined"
+}
+
+sub textcat_encoding {
+    my $self = shift(@_);
+    my ($filemeta) = @_;
+
+    # analyse filenames without extensions and digits (and trimmed of surrounding 
+    # whitespace), so that irrelevant chars don't confuse textcat
+    my $strictfilemeta = $filemeta;
+    $strictfilemeta =~ s/\.[^\.]+$//g;
+    $strictfilemeta =~ s/\d//g;
+    $strictfilemeta =~ s/^\s*//g;
+    $strictfilemeta =~ s/\s*$//g;
+    
+    my $filename_encoding = $self->encoding_from_language_analysis($strictfilemeta);
+    if(!defined $filename_encoding) {
+	$filename_encoding = "undefined";
+    }
+
+    return $filename_encoding; # can be the string "undefined"
+}
+
+# performs textcat
+sub encoding_from_language_analysis {
+    my $self = shift(@_);
+    my ($text) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+    my $best_encoding = undef;
+   
+    # get the language/encoding of the textstring using textcat
+    $self->{'textcat'} = new textcat() unless defined($self->{'textcat'});
+    my $results = $self->{'textcat'}->classify_cached_filename(\$text);
+
+
+    if (scalar @$results < 0) { 
+	return undef;
+    }
+    
+    # We have some results, we choose the first
+    my ($language, $encoding) = $results->[0] =~ /^([^-]*)(?:-(.*))?$/;
+    
+    $best_encoding = $encoding;
+    if (!defined $best_encoding) {
+	return undef;
+    } 
+        
+    if (defined $best_encoding && $best_encoding =~ m/^iso_8859/ && &unicode::check_is_utf8($text)) {
+	# the text is valid utf8, so assume that's the real encoding (since textcat is based on probabilities)
+	$best_encoding = 'utf8';
+    }
+    
+    
+    # check for equivalents where textcat doesn't have some encodings...
+    # eg MS versions of standard encodings
+    if (defined $best_encoding && $best_encoding =~ /^iso_8859_(\d+)/) {
+	my $iso = $1; # which variant of the iso standard?
+	# iso-8859 sets don't use chars 0x80-0x9f, windows codepages do
+	if ($text =~ /[\x80-\x9f]/) {
+	    # Western Europe
+	    if ($iso == 1 or $iso == 15) { $best_encoding = 'windows_1252' }
+	    elsif ($iso == 2) {$best_encoding = 'windows_1250'} # Central Europe
+	    elsif ($iso == 5) {$best_encoding = 'windows_1251'} # Cyrillic
+	    elsif ($iso == 6) {$best_encoding = 'windows_1256'} # Arabic
+	    elsif ($iso == 7) {$best_encoding = 'windows_1253'} # Greek
+	    elsif ($iso == 8) {$best_encoding = 'windows_1255'} # Hebrew
+	    elsif ($iso == 9) {$best_encoding = 'windows_1254'} # Turkish
+	}
+    }
+    
+    if (defined $best_encoding && $best_encoding !~ /^(ascii|utf8|unicode)$/ &&
+	!defined $encodings::encodings->{$best_encoding}) 
+    {
+	if ($self->{'verbosity'}) { 
+	    gsprintf($outhandle, "BasePlugin: {ReadTextFile.unsupported_encoding}\n", $text, $best_encoding, "undef");
+	}
+	$best_encoding = undef;
+    }
+    
+    return $best_encoding;
+}
+
+# uses locale
+sub get_filesystem_encoding {
+
+    my $self = shift(@_);
+
+    my $outhandle = $self->{'outhandle'};
+    my $filesystem_encoding = undef;
+
+    eval {
+	use POSIX qw(locale_h);
+	
+	# With only one parameter, setlocale retrieves the 
+	# current value
+	my $current_locale = setlocale(LC_CTYPE);
+	
+	if ($current_locale =~ m/^.*\.(.*?)$/) {
+	    my $char_encoding = lc($1);
+	    if ($char_encoding =~ m/^(iso)(8859)(\d{1,2})$/) {
+		$char_encoding = "$1\_$2\_$3";
+	    }
+
+	    $char_encoding =~ s/-/_/g;
+	    $char_encoding =~ s/^utf_8$/utf8/;
+	    
+	    if ($char_encoding =~ m/^\d+$/) {
+		if (defined $encodings::encodings->{"windows_$char_encoding"}) {
+		    $char_encoding = "windows_$char_encoding";
+		}
+		elsif (defined $encodings::encodings->{"dos_$char_encoding"}) {
+		    $char_encoding = "dos_$char_encoding";
+		}
+	    }
+	    
+	    if (($char_encoding =~ m/(?:ascii|utf8|unicode)/) 
+		|| (defined $encodings::encodings->{$char_encoding})) {
+		$filesystem_encoding = $char_encoding;
+	    }
+	    else {
+		print $outhandle "Warning: Unsupported character encoding '$char_encoding' from locale '$current_locale'\n";
+	    }
+	}
+	
+
+    };
+    if ($@) {
+	print $outhandle "$@\n";
+	print $outhandle "Warning: Unable to establish locale.  Will assume filesystem is UTF-8\n";
+	
+    }
+    return $filesystem_encoding;
+}
+
+# is there ever only one Source? Sometimes this will be called twice, for images etc that are converted.
+sub set_Source_metadata {
+    my $self = shift (@_);  
+    my ($doc_obj, $filename_no_path, $file_encoding) = @_;
+
+    my $top_section = $doc_obj->get_top_section();
+    
+    # UTF-8 version of filename
+    my $filemeta = $self->filename_to_utf8_metadata($filename_no_path, $file_encoding);
+    
+    # Source is the UTF8 display name - not necessarily the name of the file on the system
+    $doc_obj->set_utf8_metadata_element($top_section, "Source", $filemeta); 
+
+    $filemeta = &util::rename_file($filemeta, $self->{'file_rename_method'});
+    # If using URL encoding, then SourceFile is the url-reference to url-encoded
+    # filemeta: it's a url that refers to the actual file on the system
+    $filemeta = &unicode::filename_to_url($filemeta);
+
+    $doc_obj->set_utf8_metadata_element($top_section, "SourceFile", $filemeta);
+}
+   
+# this should be called by all plugins to set the oid of the doc obj, rather
+# than calling doc_obj->set_OID directly
+sub add_OID {
+    my $self = shift (@_);  
+    my ($doc_obj) = @_;
+
+    $doc_obj->set_OIDtype($self->{'OIDtype'}, $self->{'OIDmetadata'});
+
+    # see if there is a plugin specific set_OID function
+    if (defined ($self->can('set_OID'))) {
+	$self->set_OID(@_); # pass through doc_obj and any extra arguments
+    }
+    else {
+	# use the default set_OID() in doc.pm
+	$doc_obj->set_OID();
+    }
+
+}
+  
+# The BasePlugin read_into_doc_obj() function. This function does all the
+# right things to make general options work for a given plugin.  It doesn't do anything with the file other than setting reads in
+# a file and sets up a slew of metadata all saved in doc_obj, which
+# it then returns as part of a tuple (process_status,doc_obj)
+#
+# Much of this functionality used to reside in read, but it was broken
+# down into a supporting routine to make the code more flexible.  
+#
+# recursive plugins (e.g. RecPlug) and specialized plugins like those
+# capable of processing many documents within a single file (e.g.
+# GMLPlug) will normally want to implement their own version of
+# read_into_doc_obj()
+#
+# Note that $base_dir might be "" and that $file might 
+# include directories
+
+# currently blocking has been done before it gets here - does this affect secondary plugin stuff??
+sub read_into_doc_obj {
+    my $self = shift (@_);  
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+
+    # should we move this to read? What about secondary plugins?
+    print STDERR "<Processing n='$file' p='$self->{'plugin_type'}'>\n" if ($gli);
+    print $outhandle "$self->{'plugin_type'} processing $file\n"
+	    if $self->{'verbosity'} > 1;
+
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+
+    # create a new document
+    my $doc_obj = new doc ($filename_full_path, "indexed_doc", $self->{'file_rename_method'});
+    my $top_section = $doc_obj->get_top_section();
+
+    $doc_obj->add_utf8_metadata($top_section, "Plugin", "$self->{'plugin_type'}");
+    $doc_obj->add_utf8_metadata($top_section, "FileSize", (-s $filename_full_path));
+ 
+
+    # sets the UTF8 filename (Source) for display and sets the url ref to URL encoded version
+    # of the UTF8 filename (SourceFile) for generated files
+    $self->set_Source_metadata($doc_obj, $filename_no_path);
+
+
+    # plugin specific stuff - what args do we need here??
+    unless (defined ($self->process($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli))) {
+	print STDERR "<ProcessingError n='$file'>\n" if ($gli);
+	return -1;
+    }
+    
+    # include any metadata passed in from previous plugins 
+    # note that this metadata is associated with the top level section
+    my $section = $doc_obj->get_top_section();
+    # can we merge these two methods??
+    $self->add_associated_files($doc_obj, $filename_full_path);
+    $self->extra_metadata ($doc_obj, $section, $metadata);
+    $self->auto_extract_metadata($doc_obj);
+
+    # if we haven't found any Title so far, assign one
+    # this was shifted to here from inside read()
+    $self->title_fallback($doc_obj,$section,$filename_no_path);
+    
+    $self->add_OID($doc_obj);
+    
+    return (1,$doc_obj);
+}
+
+sub add_dummy_text {
+    my $self = shift(@_);
+    my ($doc_obj, $section) = @_;
+
+    # add NoText metadata so we can hide this dummy text in format statements
+    $doc_obj->add_metadata($section, "NoText", "1");
+    $doc_obj->add_text($section, &gsprintf::lookup_string("{BasePlugin.dummy_text}",1));
+    
+}
+
+# does nothing. Can be overridden by subclass
+sub auto_extract_metadata {
+    my $self = shift(@_);
+    my ($doc_obj) = @_;
+}
+
+# adds cover image, associate_file options stuff. Should be called by sub class
+# read_into_doc_obj
+sub add_associated_files {
+    my $self = shift(@_);
+    # whatis filename??
+    my ($doc_obj, $filename) = @_;
+    
+    # add in the cover image
+    if ($self->{'cover_image'}) {
+	$self->associate_cover_image($doc_obj, $filename);
+    }
+   
+
+}
+
+# implement this if you are extracting metadata for other documents
+sub metadata_read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, 
+	$extrametakeys, $extrametadata, $extrametafile,
+	$processor, $maxdocs, $gli) = @_;
+    
+    # can we process this file??
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+
+    return 1; # we recognise the file, but don't actually do anything with it
+}
+
+
+# The BasePlugin read() function. This function calls read_into_doc_obj()
+# to ensure all the right things to make general options work for a
+# given plugin are done. It then calls the process() function which
+# does all the work specific to a plugin (like the old read functions
+# used to do). Most plugins should define their own process() function
+# and let this read() function keep control.  
+#
+# recursive plugins (e.g. RecPlug) and specialized plugins like those
+# capable of processing many documents within a single file (e.g.
+# GMLPlug) might want to implement their own version of read(), but
+# more likely need to implement their own version of read_into_doc_obj()
+#
+# Return number of files processed, undef if can't recognise, -1 if can't
+# process
+
+sub read {
+    my $self = shift (@_);  
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+
+    # can we process this file??
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+    
+    my ($process_status,$doc_obj) = $self->read_into_doc_obj(@_);
+
+    if ((defined $process_status) && ($process_status == 1)) {
+
+	# process the document
+	$processor->process($doc_obj);
+
+	$self->{'num_processed'} ++;
+	undef $doc_obj; 
+    }
+    # delete any temp files that we may have created
+    $self->clean_up_after_doc_obj_processing();
+
+
+    # if process_status == 1, then the file has been processed.
+    return $process_status;
+
+}
+
+# returns undef if file is rejected by the plugin
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    gsprintf(STDERR, "BasePlugin::process {common.must_be_implemented}\n") && die "\n";
+
+    return undef; # never gets here
+}
+
+# overwrite this method to delete any temp files that we have created
+sub clean_up_after_doc_obj_processing {
+    my $self = shift(@_);
+
+}
+
+# write_file -- used by ConvertToPlug, for example in post processing
+#
+# where should this go, is here the best place??
+sub utf8_write_file {
+    my $self = shift (@_);
+    my ($textref, $filename) = @_;
+    
+    if (!open (FILE, ">$filename")) {
+	gsprintf(STDERR, "ConvertToPlug::write_file {ConvertToPlug.could_not_open_for_writing} ($!)\n", $filename);
+	 die "\n";
+     }
+    print FILE $$textref;
+    
+    close FILE;
+}
+
+
+sub filename_based_title
+{
+    my $self = shift (@_);
+    my ($file) = @_;
+
+    my $file_derived_title = $file;
+    $file_derived_title =~ s/_/ /g;
+    $file_derived_title =~ s/\..*?$//;
+
+    return $file_derived_title;
+}
+
+
+sub title_fallback
+{
+    my $self = shift (@_);
+    my ($doc_obj,$section,$file) = @_;
+
+    if (!defined $doc_obj->get_metadata_element ($section, "Title") or $doc_obj->get_metadata_element($section, "Title") eq "") {
+
+	my $file_derived_title = $self->filename_to_utf8_metadata($self->filename_based_title($file));
+	if (!defined $doc_obj->get_metadata_element ($section, "Title")) {
+	    $doc_obj->add_utf8_metadata ($section, "Title", $file_derived_title);
+	}
+	else {
+	    $doc_obj->set_utf8_metadata_element ($section, "Title", $file_derived_title);
+	} 
+    }
+	    
+}
+  
+# add any extra metadata that's been passed around from one
+# plugin to another.
+# extra_metadata uses add_utf8_metadata so it expects metadata values
+# to already be in utf8
+sub extra_metadata {
+    my $self = shift (@_);
+    my ($doc_obj, $cursection, $metadata) = @_;
+
+    my $associate_tail_re = $self->{'associate_tail_re'};
+
+    foreach my $field (keys(%$metadata)) {
+	# $metadata->{$field} may be an array reference
+	if ($field eq "gsdlassocfile_tobe") {
+	    # 'gsdlassocfile_tobe' is artificially introduced metadata
+	    # that is used to signal that certain additional files should
+	    # be tied to this document.  Useful in situations where a
+	    # metadata pass in the plugin pipeline works out some files
+	    # need to be associated with a document, but the document hasn't
+	    # been formed yet.
+	    my $equiv_form = "";
+	    foreach my $gaf (@{$metadata->{$field}}) {
+		my ($full_filename,$mimetype) = ($gaf =~ m/^(.*):(.*):$/);
+		my ($tail_filename) = ($full_filename =~ /^.*[\/\\](.+?)$/);
+		
+		# we need to make sure the filename is valid utf-8 - we do 
+		# this by url or base64 encoding it
+		# $tail_filename is the name that we store the file as
+		$tail_filename = &util::rename_file($tail_filename, $self->{'file_rename_method'});
+		$doc_obj->associate_file($full_filename,$tail_filename,$mimetype);
+		# If the filename is url_encoded, we need to encode the % signs 
+		# in the filename, so that it works in a url
+		my $url_tail_filename = &unicode::filename_to_url($tail_filename);
+		# work out extended tail extension (i.e. matching tail re)
+
+		my ($file_prefix,$file_extended_ext) 
+		    = &util::get_prefix_and_tail_by_regex($tail_filename,$associate_tail_re);
+		my ($pre_doc_ext) = ($file_extended_ext =~ m/^(.*)\..*$/);
+		my ($doc_ext) = ($tail_filename =~ m/^.*\.(.*)$/);
+		my $start_doclink = "<a href=\"_httpprefix_/collect/[collection]/index/assoc/{Or}{[parent(Top):archivedir],[archivedir]}/$url_tail_filename\">";
+		my $srcicon = "_icon".$doc_ext."_";
+		my $end_doclink = "</a>";
+
+		my $assoc_form = "$start_doclink\{If\}{$srcicon,$srcicon,$doc_ext\}$end_doclink";
+
+		if (defined $pre_doc_ext && $pre_doc_ext ne "") {
+		    # for metadata such as [mp3._edited] [mp3._full] ...
+		    $doc_obj->add_utf8_metadata ($cursection, "$doc_ext.$pre_doc_ext", $assoc_form); 
+		}
+
+		# for multiple metadata such as [mp3.assoclink]
+		$doc_obj->add_utf8_metadata ($cursection, "$doc_ext.assoclink", $assoc_form); 
+		
+		$equiv_form .= " $assoc_form";	
+	    }
+	    $doc_obj->add_utf8_metadata ($cursection, "equivlink", $equiv_form); 
+	}
+	elsif (ref ($metadata->{$field}) eq "ARRAY") {
+	    map { 
+		$doc_obj->add_utf8_metadata ($cursection, $field, $_); 
+	    } @{$metadata->{$field}};
+	} else {
+	    $doc_obj->add_utf8_metadata ($cursection, $field, $metadata->{$field}); 
+	}
+    }
+}
+
+
+sub compile_stats {
+    my $self = shift(@_);
+    my ($stats) = @_;
+
+    $stats->{'num_processed'} += $self->{'num_processed'};
+    $stats->{'num_not_processed'} += $self->{'num_not_processed'};
+    $stats->{'num_archives'} += $self->{'num_archives'};
+
+}
+
+sub associate_cover_image {
+    my $self = shift;
+    my ($doc_obj, $filename) = @_;
+
+    $filename =~ s/\.[^\\\/\.]+$/\.jpg/;
+    if (exists $self->{'covers_missing_cache'}->{$filename}) {
+	# don't stat() for existence eg for multiple document input files
+	# (eg SplitPlug)
+	return;
+    }
+
+    my $top_section=$doc_obj->get_top_section();
+
+    if (-e $filename) {
+    	$doc_obj->associate_file($filename, "cover.jpg", "image/jpeg");
+	$doc_obj->add_utf8_metadata($top_section, "hascover",  1);
+    } else {
+	my $upper_filename = $filename;
+	$upper_filename =~ s/jpg$/JPG/;
+	if (-e $upper_filename) {
+	    $doc_obj->associate_file($upper_filename, "cover.jpg",
+				     "image/jpeg");
+	    $doc_obj->add_utf8_metadata($top_section, "hascover",  1);
+	} else {
+	    # file doesn't exist, so record the fact that it's missing so
+	    # we don't stat() again (stat is slow)
+	    $self->{'covers_missing_cache'}->{$filename} = 1;
+	}
+    }
+
+}
+
+
+# Overridden by exploding plugins (eg. ISISPlug)
+sub clean_up_after_exploding
+{
+    my $self = shift(@_);
+}
+
+
+
+1;
Index: /gsdl/stable/perllib/plugins/BibTexPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/BibTexPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/BibTexPlugin.pm	(revision 20131)
@@ -0,0 +1,831 @@
+###########################################################################
+#
+# BibTexPlugin.pm - a plugin for bibliography records in BibTex format
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright 2000 Gordon W. Paynter
+# Copyright 1999-2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# BibTexPlugin reads bibliography files in BibTex format.
+#
+# by Gordon W. Paynter (gwp@cs.waikato.ac.nz), November 2000
+# Based on ReferPlug.  See ReferPlug for geneology.
+#
+# BibTexPlugin creates a document object for every reference a the file.
+# It is a subclass of SplitTextFile, so if there are multiple records, all
+# are read.
+#
+# Modified Dec 2001 by John McPherson:
+#  *  some modifications submitted by Sergey Yevtushenko
+#                      <sergey@intellektik.informatik.tu-darmstadt.de>
+#  *  some non-ascii char support (ie mostly Latin)
+
+
+package BibTexPlugin;
+
+use SplitTextFile;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+# BibTexPlugin is a sub-class of SplitTextFile.
+sub BEGIN {
+    @BibTexPlugin::ISA = ('SplitTextFile');
+}
+
+my $arguments = 
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() },
+      { 'name' => "split_exp",
+	'desc' => "{SplitTextFile.split_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_split_exp(),
+	'reqd' => "no" }
+      ];
+
+my $options = { 'name'     => "BibTexPlugin",
+		'desc'     => "{BibTexPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'explodes' => "yes",
+		'args'     => $arguments };
+
+# This plugin processes files with the suffix ".bib"
+sub get_default_process_exp {
+    return q^(?i)\.bib$^;
+}
+
+# This plugin splits the input text at blank lines
+sub get_default_split_exp {
+    return q^\n+(?=@)^;
+}
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new SplitTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+
+
+# The process function reads a single bibliographic record and stores
+# it as a new document.
+
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my $cursection = $doc_obj->get_top_section();
+    $self->{'key'} = "default";
+
+    # Check that we're dealing with a valid BibTex record
+    return undef unless ($$textref =~ /^@\w+\{.*\}/s);
+
+    # Ignore things we can't use
+    return 0 if ($$textref =~ /^\@String/);
+
+    # This hash translates BibTex field names into metadata names.  The
+    # BibTex names are taken from the "Local Guide to Latex" Graeme
+    # McKinstry.  Metadata names are consistent with ReferPlug.
+
+    # The author metadata will be stored as one "Creator" entry, but will
+    # also be split up into several individual "Author" fields.
+
+    my %field = (
+		 'address', 'PublisherAddress',
+		 'author', 'Creator',
+		  
+		 'booktitle', 'Booktitle',
+		 'chapter', 'Chapter',
+		 'edition', 'Edition',
+		 'editor', 'Editor', 
+		 'institution', 'Publisher',
+		 'journal', 'Journal',
+		 'month', 'Month',
+		 'number', 'Number',
+		 'pages', 'Pages',
+		 'publisher', 'Publisher',
+		 'school', 'Publisher',
+		 'title', 'Title',
+		 'volume', 'Volume',
+		 'year', 'Year', # Can't use "Date" as this implies DDDDMMYY!
+
+		 'keywords', 'Keywords',
+		 'abstract', 'Abstract',
+		 'copyright', 'Copyright',
+		 'note', 'Note',
+		 'url', 'URL',
+		 );
+
+    # Metadata fields 
+    my %metadata;
+    my ($EntryType, $Creator, $Keywords, $text);
+
+    my $verbosity = $self->{'verbosity'};
+    $verbosity = 0 unless $verbosity;
+
+    # Make sure the text has exactly one entry per line -
+    # append line to previous if it doesn't start with "  <key> = "
+
+    my @input_lines=split(/\r?\n/, $$textref);
+    my @all_lines;
+    my $entry_line=shift @input_lines;
+    foreach my $input_line (@input_lines) {
+	if ($input_line =~ m/^\s*\w+\s*=\s*/) {
+	    # this is a new key
+	    push(@all_lines, $entry_line);
+	    $entry_line=$input_line;
+	} else {
+	    # this is a continuation of previous line
+	    $entry_line .= " " . $input_line;
+	}
+	
+    }
+    # add final line, removing trailing '}'
+    $entry_line =~ s/\}\s*$//;
+    push(@all_lines, $entry_line);
+    push(@all_lines, "}");
+
+    # Read and process each line in the bib file.
+    my ($entryname, $name, $value, $line);
+    foreach $line (@all_lines) {
+
+	# Add each line.  Most lines consist of a field identifer and
+	# then data, and we simply store them, though we treat some
+	# of the fields a bit differently.
+
+	$line =~ s/\s+/ /g;
+	$text .= "$line\n";
+
+
+	print "Processing line = $line \n" if $verbosity>=4;
+
+	# The first line is special, it contains the reference type and OID
+	if ($line =~ /\@(\w+)\W*\{\W*([\*\.\w\d:-]*)\W*$/) {
+	    $EntryType = $1;
+	    my $EntryID = (defined $2) ? $2 : "default";
+	    print "** $EntryType - \"$EntryID\" \n"
+		if ($verbosity >= 4);
+
+	    next;
+	}
+	if ($line =~ /\@/) {
+	    print $outhandle "bibtexplug: suspect line in bibtex file: $line\n"
+		if ($verbosity >= 2);
+	    print $outhandle "bibtexplug: if that's the start of a new bibtex record ammend regexp in bibtexplug::process()\n"
+		if ($verbosity >= 2);
+	}
+	
+	# otherwise, parse the metadata out of this line
+	next unless ($line =~ /^\s*(\w+)\s*=\s*(.*)/);
+	$entryname = lc($1);
+	$value = $2;
+	$value =~ s/,?\s*$//; # remove trailing comma and space
+	if ($value =~ /^"/ && $value =~ /"$/) {
+	    # remove surrounding " marks
+	    $value =~ s/^"//; $value =~ s/"$//;
+	} elsif ($value =~ /^\{/ && $value =~ /\}$/) {
+	    # remove surrounding {} marks
+	    $value =~ s/^\{//; $value =~ s/\}$//;
+	}
+	# special case for year - we only want a 4 digit year, not 
+	# "circa 2004" etc
+	if ($entryname=~ /^year$/i) {
+	    if ($value=~ /(\d{4})/) {
+		$value=$1;
+		$metadata{$entryname} .= "$value";
+	    }
+	} 
+	else {
+	    
+	    $value = &process_latex($value);
+	    # Add this line of metadata
+	    $metadata{$entryname} .= "$value";	
+	}
+    }
+
+    # Add the Entry type as metadata
+    $doc_obj->add_utf8_metadata ($cursection, "EntryType", $EntryType);
+    
+    #Add the fileformat as metadata
+    $doc_obj->add_metadata($cursection, "FileFormat", "BibTex");
+
+
+    # Add the various field as metadata
+    foreach my $entryname (keys %metadata) {
+	next unless (defined $field{$entryname});
+	next unless (defined $metadata{$entryname});	
+	
+	$name = $field{$entryname};
+	$value = $metadata{$entryname};
+
+	if ($name =~ /^Month/) {
+	    $value=expand_month($value);
+	}
+
+	# Several special operatons on metadata follow
+	
+	# Add individual keywords.
+	# The full set of keywords will be added, in due course, as "Keywords".
+	# However, we also want to add them as individual "Keyword" metadata elements.
+	if ($entryname eq "keywords") {
+	    my @keywordlist = split(/,/, $value);
+	    foreach my $k (@keywordlist) {
+		$k = lc($k); 
+		$k =~ s/\s*$//; 
+		$k =~ s/^\s*//; 
+		if ($k =~ /\w/) {
+		    $doc_obj->add_utf8_metadata ($cursection, "Keyword", $k);
+		}
+	    } 
+	}
+	
+	# Add individual authors
+	# The author metadata will be stored as one "Creator" entry, but we
+	# also want to split it into several individual "Author" fields in
+	# "Lastname, Firstnames" format so we can browse it.
+	if ($entryname eq "author") { #added also comparison with editor
+	   
+	    # take care of "et al."...
+	    my $etal='';
+	    if ($value =~ s/\s+(and\s+others|et\.?\s+al\.?)\s*$//i) {
+		$etal=' <em>et. al.</em>';
+	    }
+	    # und here for german language...
+	    # don't use brackets in pattern, else the matched bit becomes
+	    # an element in the list!
+	    my @authorlist = split(/\s+and\s+|\s+und\s+/, $value); 
+	    my @formattedlist = ();
+	    foreach $a (@authorlist) {
+		$a =~ s/\s*$//; 
+		$a =~ s/^\s*//; 
+		# Reformat and add author name
+		next if $a=~ /^\s*$/;
+		
+		# names are "First von Last", "von Last, First"
+		# or "von Last, Jr, First". See the "BibTeXing" manual, page 16
+		my $first="";
+		my $vonlast="";
+		my $jr="";
+
+		if ($a =~ /,/) {
+		    my @parts=split(/,\s*/, $a);
+		    $first = pop @parts;
+		    if (scalar(@parts) == 2) {
+			$jr = pop @parts;
+		    }
+		    $vonlast=shift @parts;
+		    if (scalar(@parts) > 0) {
+			print $outhandle "BibTexPlugin: couldn't parse name $a\n";
+			# but we continue anyway...
+		    }
+		} else { # First von Last
+		    my @words = split(/ /, $a);
+		    while (scalar(@words) > 1 && $words[0] !~ /^[a-z]{2..}/) {
+			$first .= " " . shift (@words);
+		    }
+		    $first =~ s/^\s//;
+		    $vonlast = join (' ', @words); # whatever's left...
+		}
+		my $von="";
+		my $last="";
+		if ($vonlast =~ m/^[a-z]/) { # lowercase implies "von"
+		    $vonlast =~ s/^(([a-z]\w+\s+)+)//;
+		    $von = $1;
+		    if (!defined ($von)) {
+			# some non-English names do start with lowercase
+			# eg "Marie desJardins". Also we can get typos...
+			print $outhandle "BibTexPlugin: couldn't parse surname $vonlast\n";
+			$von="";
+			if ($vonlast =~ /^[a-z]+$/) {
+			    # if it's all lowercase, uppercase 1st.
+			    $vonlast =~ s/^(.)/\u$1/;
+
+			}
+		    }
+		    $von =~ s/\s*$//;
+		    $last=$vonlast;
+		} else {
+		    $last=$vonlast;
+		}
+		my $wholename="$first $von $last $jr";
+		$wholename =~ s/\s+/ /g; # squeeze multiple spaces
+		$wholename =~ s/ $//;
+		push (@formattedlist, $wholename);
+		my $fullname = "$last";
+		$fullname .= " $jr" if ($jr);
+		$fullname .= ", $first";
+		$fullname .= " $von" if ($von);
+
+		# Add each name to set of Authors
+		$doc_obj->add_utf8_metadata ($cursection, "Author", $fullname);
+	    }
+
+	    # Only want at most one "and" in the Creator field
+	    if (scalar(@formattedlist) > 2) {
+		my $lastauthor=pop @formattedlist;
+		$value=join(', ', @formattedlist);
+		$value.=" and $lastauthor";
+	    } else { # 1 or 2 authors...
+		$value=join(" and ",@formattedlist);
+	    }
+	    $value.=$etal; # if there was "et al."
+	}
+
+	# Books and Journals are additionally marked for display purposes
+	if ($entryname eq "booktitle") {
+	    $doc_obj->add_utf8_metadata($cursection, "BookConfOnly", 1);
+	} elsif ($entryname eq "journal") {
+	    $doc_obj->add_utf8_metadata($cursection, "JournalsOnly", 1); 
+	}
+
+	# Add the various fields as metadata	
+	$doc_obj->add_utf8_metadata ($cursection, $name, $value); 
+    
+    }
+
+    # for books and journals...
+    if (!exists $metadata{'title'}) {
+	my $name=$field{'title'}; # get Greenstone metadata name
+	my $value;
+	if (exists $metadata{'booktitle'}) {
+	    $value=$metadata{'booktitle'};
+	} elsif (exists $metadata{'journal'}) {
+	    $value=$metadata{'journal'};
+	}
+	if ($value) {
+	    $doc_obj->add_utf8_metadata ($cursection, $name, $value); 
+	}
+    }
+
+    # Add Date (yyyymmdd) metadata
+    if (defined ($metadata{'year'}) ) {
+	my $date=$metadata{'year'};
+	chomp $date;
+	my $month=$metadata{'month'};
+	if (defined($month)) {
+	    # month is currently 3 letter code or a range...
+	    $month = expand_month($month);
+	    # take the first month found... might not find one!
+	    $month =~ m/_textmonth(\d\d)_/;
+	    $month = $1;
+	}
+	if (!defined($month)) {
+	    $month="00";
+	}
+	$date .= "${month}00";
+	$doc_obj->add_utf8_metadata($cursection, "Date", $date); 
+}
+
+#    # Add the text in BibTex format (all fields)
+    if ($text =~ /\w/) {
+
+	$text =~ s@&@&amp;@g;
+	$text =~ s@<@&lt;@g;
+	$text =~ s@>@&gt;@g;
+	$text =~ s@\n@<br/>\n@g;
+	$text =~ s@\\@\\\\@g;
+
+	$doc_obj->add_utf8_text ($cursection, $text);
+    }
+
+    return 1;
+}
+
+
+
+
+# convert email addresses and URLs into links
+sub convert_urls_into_links{
+   my ($text) = @_;
+ 
+   $text =~ s/([\w\d\.\-]+@[\w\d\.\-]+)/<a href=\"mailto:$1\">$1<\/a>/g;
+   $text =~ s/(http:\/\/[\w\d\.\-]+[\/\w\d\.\-]*)/<a href=\"$1\">$1<\/a>/g;
+
+   return $text;
+}
+
+# Clean up whitespace and convert \n charaters to <BR> or <P>
+sub clean_up_whitespaces{
+   my ($text) = @_;
+
+   $text =~ s/%%%%%/<BR> <BR>/g;
+   $text =~ s/ +/ /g;
+   $text =~ s/\s*$//; 
+   $text =~ s/^\s*//; 
+   $text =~ s/\n/\n<BR>/g;
+   $text =~ s/<BR>\s*<BR>/<P>/g;
+
+   return $text;
+}
+
+
+sub convert_problem_characters_without_ampersand{
+    my ($text) = @_;
+    $text =~ s/</&lt;/g;
+    $text =~ s/>/&gt;/g;
+    
+    $text =~ s/\'\'/\"/g; #Latex -specific conversion
+    $text =~ s/\`\`/\"/g; #Latex -specific conversion
+
+    $text =~ s/\"/&quot;/g;
+    $text =~ s/\'/&#8217;/g;
+    $text =~ s/\`/&#8216;/g;
+
+#    $text =~ s/\+/ /g;
+#    $text =~ s/\(/ /g;
+#    $text =~ s/\)/ /g;
+
+    $text =~ s/\\/\\\\/g;
+
+#    $text =~ s/\./\\\./g;
+
+    return $text;
+}
+
+# Convert a text string into HTML.
+
+# The HTML is going to be inserted into a GML file, so we have to be
+# careful not to use symbols like ">", which occurs frequently in email
+# messages (and use &gt instead.
+
+# This function also turns URLs and email addresses into links, and
+# replaces carriage returns with <BR> tags (and multiple carriage returns
+# with <P> tags).
+
+sub text_into_html {
+    my ($text) = @_;
+
+    # Convert problem characters into HTML symbols
+    $text =~ s/&/&amp;/g;
+
+    $text = &convert_problem_characters_without_ampersand( $text );
+
+    # convert email addresses and URLs into links
+    $text = &convert_urls_into_links( $text );
+
+    $text = &clean_up_whitespaces( $text );
+
+    return $text;
+}
+
+
+sub expand_month {
+    my $text=shift;
+
+    # bibtex style files expand abbreviations for months.
+    # Entries can contain more than one month (eg ' month = jun # "-" # aug, ')
+    $text =~ s/jan/_textmonth01_/g;
+    $text =~ s/feb/_textmonth02_/g;
+    $text =~ s/mar/_textmonth03_/g;
+    $text =~ s/apr/_textmonth04_/g;
+    $text =~ s/may/_textmonth05_/g;
+    $text =~ s/jun/_textmonth06_/g;
+    $text =~ s/jul/_textmonth07_/g;
+    $text =~ s/aug/_textmonth08_/g;
+    $text =~ s/sep/_textmonth09_/g;
+    $text =~ s/oct/_textmonth10_/g;
+    $text =~ s/nov/_textmonth11_/g;
+    $text =~ s/dec/_textmonth12_/g;
+
+    return $text;
+}
+
+
+# Convert accented characters, remove { }, interprete some commands....
+# Note!! This is not comprehensive! Also assumes Latin -> Unicode!
+sub process_latex {
+    my ($text) = @_;
+      
+    # note - this is really ugly, but it works. There may be a prettier way
+    # of mapping latex accented chars to utf8, but we just brute force it here.
+    # Also, this isn't complete - not every single possible accented letter
+    # is in here yet, but most of the common ones are.
+
+    my %utf8_chars =
+	(
+	 # acutes
+	 '\'a' => chr(0xc3).chr(0xa1),
+	 '\'c' => chr(0xc4).chr(0x87),
+	 '\'e' => chr(0xc3).chr(0xa9),
+	 '\'i' => chr(0xc3).chr(0xad),
+	 '\'l' => chr(0xc3).chr(0xba),
+	 '\'n' => chr(0xc3).chr(0x84),
+	 '\'o' => chr(0xc3).chr(0xb3),
+	 '\'r' => chr(0xc5).chr(0x95),
+	 '\'s' => chr(0xc5).chr(0x9b),
+	 '\'u' => chr(0xc3).chr(0xba),
+	 '\'y' => chr(0xc3).chr(0xbd),
+	 '\'z' => chr(0xc5).chr(0xba),
+	 # graves
+	 '`a' => chr(0xc3).chr(0xa0),
+	 '`A' => chr(0xc3).chr(0x80),
+	 '`e' => chr(0xc3).chr(0xa8),
+	 '`E' => chr(0xc3).chr(0x88),
+	 '`i' => chr(0xc3).chr(0xac),
+	 '`I' => chr(0xc3).chr(0x8c),
+	 '`o' => chr(0xc3).chr(0xb2),
+	 '`O' => chr(0xc3).chr(0x92),
+	 '`u' => chr(0xc3).chr(0xb9),
+	 '`U' => chr(0xc3).chr(0x99),
+	 # circumflex
+	 '^a' => chr(0xc3).chr(0xa2),
+	 '^A' => chr(0xc3).chr(0x82),
+	 '^c' => chr(0xc4).chr(0x89),
+	 '^C' => chr(0xc4).chr(0x88),
+	 '^e' => chr(0xc3).chr(0xaa),
+	 '^E' => chr(0xc3).chr(0x8a),
+	 '^g' => chr(0xc4).chr(0x9d),
+	 '^G' => chr(0xc4).chr(0x9c),
+	 '^h' => chr(0xc4).chr(0xa5),
+	 '^H' => chr(0xc4).chr(0xa4),
+	 '^i' => chr(0xc3).chr(0xae),
+	 '^I' => chr(0xc3).chr(0x8e),
+	 '^j' => chr(0xc4).chr(0xb5),
+	 '^J' => chr(0xc4).chr(0xb4),
+	 '^o' => chr(0xc3).chr(0xb4),
+	 '^O' => chr(0xc3).chr(0x94),
+	 '^s' => chr(0xc5).chr(0x9d),
+	 '^S' => chr(0xc5).chr(0x9c),
+	 '^u' => chr(0xc3).chr(0xa2),
+	 '^U' => chr(0xc3).chr(0xbb),
+	 '^w' => chr(0xc5).chr(0xb5),
+	 '^W' => chr(0xc5).chr(0xb4),
+	 '^y' => chr(0xc5).chr(0xb7),
+	 '^Y' => chr(0xc5).chr(0xb6),
+	 
+	 # diaeresis
+	 '"a' => chr(0xc3).chr(0xa4),
+	 '"A' => chr(0xc3).chr(0x84),
+	 '"e' => chr(0xc3).chr(0xab),
+	 '"E' => chr(0xc3).chr(0x8b),
+	 '"\\\\i' => chr(0xc3).chr(0xaf),
+	 '"\\\\I' => chr(0xc3).chr(0x8f),
+	 '"o' => chr(0xc3).chr(0xb6),
+	 '"O' => chr(0xc3).chr(0x96),
+	 '"u' => chr(0xc3).chr(0xbc),
+	 '"U' => chr(0xc3).chr(0x9c),
+	 '"y' => chr(0xc3).chr(0xbf),
+	 '"Y' => chr(0xc3).chr(0xb8),
+	 # tilde
+	 '~A' => chr(0xc3).chr(0x83),
+	 '~N' => chr(0xc3).chr(0x91),
+	 '~O' => chr(0xc3).chr(0x95),
+	 '~a' => chr(0xc3).chr(0xa3),
+	 '~n' => chr(0xc3).chr(0xb1),
+	 '~o' => chr(0xc3).chr(0xb5),
+	 # caron - handled specially
+	 # double acute
+	 # ring
+	 # dot
+	 '.c' => chr(0xc4).chr(0x8b),
+	 '.C' => chr(0xc4).chr(0x8a),
+	 '.e' => chr(0xc4).chr(0x97),
+	 '.E' => chr(0xc4).chr(0x96),
+	 '.g' => chr(0xc4).chr(0xa1),
+	 '.G' => chr(0xc4).chr(0xa0),
+	 '.I' => chr(0xc4).chr(0xb0),
+	 '.z' => chr(0xc5).chr(0xbc),
+	 '.Z' => chr(0xc5).chr(0xbb),
+	 # macron
+	 '=a' => chr(0xc4).chr(0x81),
+	 '=A' => chr(0xc4).chr(0x80),
+	 '=e' => chr(0xc4).chr(0x93),
+	 '=E' => chr(0xc4).chr(0x92),
+	 '=i' => chr(0xc4).chr(0xab),
+	 '=I' => chr(0xc4).chr(0xaa),
+	 '=o' => chr(0xc4).chr(0x8d),
+	 '=O' => chr(0xc4).chr(0x8c),
+	 '=u' => chr(0xc4).chr(0xab),
+	 '=U' => chr(0xc4).chr(0xaa),
+	 
+	 # stroke - handled specially - see below
+	 
+	 # cedilla - handled specially
+	 );
+    
+# these are one letter latex commands - we make sure they're not a longer
+# command name. eg {\d} is d+stroke, so careful of \d
+    my %special_utf8_chars = 
+	(
+	 # breve
+	 'u g' => chr(0xc4).chr(0x9f),
+	 'u G' => chr(0xc4).chr(0x9e),
+	 'u i' => chr(0xc4).chr(0xad),
+	 'u I' => chr(0xc4).chr(0xac),
+	 'u o' => chr(0xc5).chr(0x8f),
+	 'u O' => chr(0xc5).chr(0x8e),
+	 'u u' => chr(0xc5).chr(0xad),
+	 'u U' => chr(0xc5).chr(0xac),
+	 # caron
+	 'v c' => chr(0xc4).chr(0x8d),
+	 'v C' => chr(0xc4).chr(0x8c),
+	 'v n' => chr(0xc5).chr(0x88),
+	 'v N' => chr(0xc5).chr(0x87),
+	 'v s' => chr(0xc5).chr(0xa1),
+	 'v S' => chr(0xc5).chr(0xa5),
+	 'v z' => chr(0xc5).chr(0xbe),
+	 'v Z' => chr(0xc5).chr(0xbd),
+	 # cedilla
+	 'c c' => chr(0xc3).chr(0xa7),
+	 'c C' => chr(0xc3).chr(0x87),
+	 'c g' => chr(0xc4).chr(0xa3),
+	 'c G' => chr(0xc4).chr(0xa2),
+	 'c k' => chr(0xc4).chr(0xb7),
+	 'c K' => chr(0xc4).chr(0xb6),
+	 'c l' => chr(0xc4).chr(0xbc),
+	 'c L' => chr(0xc4).chr(0xbb),
+	 'c n' => chr(0xc5).chr(0x86),
+	 'c N' => chr(0xc5).chr(0x85),
+	 'c r' => chr(0xc5).chr(0x97),
+	 'c R' => chr(0xc5).chr(0x96),
+	 'c s' => chr(0xc5).chr(0x9f),
+	 'c S' => chr(0xc5).chr(0x9e),
+	 'c t' => chr(0xc5).chr(0xa3),
+	 'c T' => chr(0xc5).chr(0xa2),
+	 # double acute / Hungarian accent
+	 'H O' => chr(0xc5).chr(0x90),
+	 'H o' => chr(0xc5).chr(0x91),
+	 'H U' => chr(0xc5).chr(0xb0),
+	 'H u' => chr(0xc5).chr(0xb1),
+	 
+	 # stroke 
+	 'd' => chr(0xc4).chr(0x91),
+	 'D' => chr(0xc4).chr(0x90),
+	 'h' => chr(0xc4).chr(0xa7),
+#	 'H' => chr(0xc4).chr(0xa6), # !! this normally(!!?) means Hung. umlaut
+	 'i' => chr(0xc4).chr(0xb1), # dotless lowercase i
+	 'l' => chr(0xc5).chr(0x82),
+	 'L' => chr(0xc5).chr(0x81),
+	 'o' => chr(0xc3).chr(0xb8),
+	 'O' => chr(0xc3).chr(0x98),
+	 't' => chr(0xc5).chr(0xa7),
+	 'T' => chr(0xc5).chr(0xa6),
+	 # german ss/szlig/sharp s
+	 'ss' => chr(0xc3).chr(0x9f),
+	 );
+    
+    # convert latex-style accented characters.
+
+    # remove space (if any) between \ and letter to accent (eg {\' a})
+
+    $text =~ s@(\\[`'="^~\.])\s(\w)@$1$2@g; #`
+		   
+    # remove {} around a single character (eg \'{e})
+    $text =~ s@(\\[`'="^~\.]){(\w)}@{$1$2}@g; #`
+
+    # \, is another way of doing cedilla \c
+    $text =~ s@\\,(.)@\\c $1@g;
+
+    # remove {} around a single character for special 1 letter commands -
+    # need to insert a space. Eg \v{s}  ->  {\v s}
+    $text =~ s@(\\[uvcH]){(\w)}@{$1 $2}@g;
+
+    # only do if the text contains a '\' character. 
+    if ($text =~ m|\\|) {
+	# "normal" accents - ie non-alpha latex tag
+	while ($text =~ m@\\([`'="^~\.])([\w])@) { #`
+	    my $tex="$1$2"; my $char="$2";
+	    my $replacement=$utf8_chars{$tex};
+	    if (!defined($replacement)) {
+		print STDERR "BibTexPlugin: Warning: unknown latex accent \"$tex\" in \"$text\"\n";
+		$replacement=$char;
+	    }
+	    $text =~ s/\\\Q$tex/$replacement/g;
+	}
+
+        # where the following letter matters (eg "sm\o rrebr\o d", \ss{})
+        # only do the change if immediately followed by a space, }, {, or \
+	# one letter accents ( + ss)
+        while ($text =~ m@\\([DdhiLlOoTt]|ss)[{}\s\"\\]@) {
+	    my $tex=$1;
+	    my $replacement=$special_utf8_chars{$tex};
+	    if (!defined($replacement)) {
+		print STDERR "BibTexPlugin: Warning: unknown latex accent \"$tex\" in \"$text\"\n";
+		$replacement=$tex;
+	    }
+	    $text =~ s/\\$tex([{}\s\"\\])/$replacement$1/g;
+
+	}
+
+	# one letter latex accent commands that affect following letter
+        while ($text =~ m@\\([uvcH]) ([\w])@) {
+          my $tex="$1 $2"; my $char="$2";
+          my $replacement=$special_utf8_chars{$tex};
+          if (!defined($replacement)) {
+	      print STDERR "BibTexPlugin: Warning: unknown latex accent \"$tex\" in \"$text\"\n";
+	      $replacement=$char;
+	  }
+          $text =~ s/\\$tex/$replacement/g;
+        }
+    }
+
+    # escape html-sensitive characters
+    $text =~ s@&@&amp;@g;
+    $text =~ s@<@&lt;@g;
+    $text =~ s@>@&gt;@g;
+    $text =~ s/''/"/g; # Latex-specific
+    $text =~ s/``/"/g; # Latex-specific
+    # greenstone-specific
+    $text =~ s@\[@&\#91;@g;
+    $text =~ s@\]@&\#93;@g;
+
+    # remove latex commands
+
+    # explicitly recognised commands
+    $text =~ s@\\ldots@&hellip;@g;
+
+    # maths mode
+    $text =~ s@\$(.*?)\$@&process_latex_math($1)@ge;
+
+    # remove all other commands with optional arguments...
+    $text =~ s@\\\w+(\[.*?\])?\s*@@g;
+    # $text =~ s@\\noopsort{[^}]+\}@@g;
+    # $text =~ s@\\\w+{(([^}]*[^\\])*)}@$1@g; # all other commands
+    
+    # remove latex groupings { } (but not \{ or \} )
+    while ($text =~ s/([^\\])[\{\}]/$1/g) {;} # needed for "...}{..."
+    $text =~ s/^\{//; # remove { if first char
+    
+    # latex characters
+    # spaces - nobr space (~), opt break (\-), append ("#" - bibtex only)
+    $text =~ s/([^\\])~+/$1 /g; # non-breaking space  "~"
+    # optional break "\-"
+    if ($text =~ m/[^&]\#/) { # concat macros (bibtex) but not HTML codes
+	# the non-macro bits have quotes around them - we just remove quotes
+	$text =~ s/([^&])[\"\#]/$1/g;
+    }
+    # dashes. Convert (m|n)-dash into single dash for html.
+    $text =~ s@\-\-+@\-@g;
+
+    # quoted { } chars
+    $text =~ s@\\{@{@g;
+    $text =~ s@\\}@}@g;
+
+    # finally to protect against macro language...
+    $text =~ s@\\@\\\\@g;
+
+    return $text;
+}
+
+
+sub process_latex_math {
+    my $text = shift;
+
+    $text =~ s@\\infty@infinity@g;       # or unicode 0x221E...
+    $text =~ s@\^{(.*?)}@<sup>$1</sup>@g; # superscript
+    $text =~ s@\^([^\{])@<sup>$1</sup>@g;
+    $text =~ s@\_{(.*?)}@<sub>$1</sub>@g; # subscript
+    $text =~ s@\_([^\{])@<sub>$1</sub>@g;
+
+    # put all other command names in italics
+    $text =~ s@\\([\w]+)@<i>$1</i>@g;
+
+    return $text;
+}
+
+sub add_OID {
+    my $self = shift (@_);
+    my ($doc_obj, $id, $segment_number) = @_;
+    
+    if ( $self->{'key'} eq "default") {
+	$self->SUPER::add_OID(@_);
+#	$doc_obj->set_OID("$id\_$segment_number");
+    } else {
+	$doc_obj->set_OID($self->{'key'});
+    }
+}
+
+1;
+
+
Index: /gsdl/stable/perllib/plugins/BookPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/BookPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/BookPlugin.pm	(revision 20131)
@@ -0,0 +1,246 @@
+###########################################################################
+#
+# BookPlugin.pm (formally called HBSPlug) -- plugin for processing simple
+# html (or text) books
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# creates multi-level document from document containing 
+# <<TOC>> level tags. Metadata for each section is taken from any
+# other tags on the same line as the <<TOC>>. e.g. <<Title>>xxxx<</Title>>
+# sets Title metadata.
+
+# Everything else between TOC tags is treated as simple html (i.e. no 
+# processing of html links or any other HTMLPlug type stuff is done).
+
+# expects input files to have a .hb file extension by default (this can be 
+# changed by adding a -process_exp option
+
+# a file with the same name as the hb file but a .jpg extension is
+# taken as the cover image (jpg files are blocked by this plugin)
+
+# BookPlugin is a simplification (and extension) of the HBPlug used
+# by the Humanity Library collections. BookPlugin is faster as it expects
+# the input files to be cleaner (The input to the HDL collections
+# contains lots of excess html tags around <<TOC>> tags, uses <<I>>
+# tags to specify images, and simply takes all text between <<TOC>>
+# tags and start of text to be Title metadata). If you're marking up
+# documents to be displayed in the same way as the HDL collections,
+# use this plugin instead of HBPlug.
+
+package BookPlugin;
+
+use AutoExtractMetadata;
+use util;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @BookPlugin::ISA = ('AutoExtractMetadata');
+}
+
+my $arguments = 
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() },
+      { 'name' => "block_exp",
+	'desc' => "{BasePlugin.block_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_block_exp() } ];
+
+my $options = { 'name'     => "BookPlugin",
+		'desc'     => "{BookPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new AutoExtractMetadata($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+sub get_default_block_exp {
+    my $self = shift (@_);
+
+    return q^\.jpg$^;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.hb$^;
+}
+
+# do plugin specific processing of doc_obj
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    print STDERR "<Processing n='$file' p='BookPlugin'>\n" if ($gli);
+    print $outhandle "BookPlugin: processing $file\n" 
+	if $self->{'verbosity'} > 1;
+    
+    my $cursection = $doc_obj->get_top_section();
+
+    # Add FileFormat as the metadata
+    $doc_obj->add_metadata($doc_obj->get_top_section(),"FileFormat", "Book");
+
+    my $filename = &util::filename_cat($base_dir, $file);
+    my $absdir = $filename;
+    $absdir =~ s/[^\/\\]*$//;
+
+    # add the cover image
+    my $coverimage = $filename;
+    $coverimage =~ s/\.[^\.]*$/\.jpg/i;
+    $doc_obj->associate_file($coverimage, "cover.jpg", "image/jpeg");
+
+    my $title = "";
+
+    # remove any leading rubbish
+    $$textref =~ s/^.*?(<<TOC)/$1/ios;
+    
+    my $curtoclevel = 1;
+    my $firstsection = 1;
+    my $toccount = 0;
+    while ($$textref =~ /\w/) {
+	$$textref =~ s/^<<TOC(\d+)>>([^\n]*)\n(.*?)(<<TOC|\Z)/$4/ios;
+	my $toclevel = $1;
+	my $metadata = $2;
+	my $sectiontext = $3;
+
+	if ($toclevel == 2) {
+	    $toccount ++;
+	}
+	
+	# close any sections below the current level and
+	# create a new section (special case for the firstsection)
+	while (($curtoclevel > $toclevel) ||
+	       (!$firstsection && $curtoclevel == $toclevel)) {
+	    $cursection = $doc_obj->get_parent_section ($cursection);
+	    $curtoclevel--;
+	}
+	if ($curtoclevel+1 < $toclevel) {
+	    print $outhandle "WARNING - jump in toc levels in $filename " . 
+		"from $curtoclevel to $toclevel\n";
+	}
+	while ($curtoclevel < $toclevel) {
+	    $curtoclevel++;
+	    $cursection = 
+		$doc_obj->insert_section($doc_obj->get_end_child($cursection));
+	}
+
+	# sort out metadata
+	while ($metadata =~ s/^.*?<<([^>]*)>>(.*?)<<[^>]*>>//) {
+	    my $metakey = $1;
+	    my $metavalue = $2;
+
+	    if ($metavalue ne "" && $metakey ne "") {
+		# make sure key fits in with gsdl naming scheme 
+		$metakey =~ tr/[A-Z]/[a-z]/;
+		$metakey = ucfirst ($metakey);
+		$doc_obj->add_utf8_metadata ($cursection, $metakey, $metavalue);
+	    }
+	}
+
+	# remove header rubbish
+	$sectiontext =~ s/^.*?<body[^>]*>//ios;
+
+	# and any other unwanted tags
+	$sectiontext =~ s/<(\/p|\/html|\/body)>//isg;
+
+	# fix up the image links
+	$sectiontext =~ s/(<img[^>]*?src\s*=\s*\"?)([^\">]+)(\"?[^>]*>)/
+	    &replace_image_links($absdir, $doc_obj, $1, $2, $3)/isge;
+
+	# add the text
+	$doc_obj->add_utf8_text($cursection, $sectiontext);
+
+	$firstsection = 0;
+
+	$$textref =~ s/^\s+//s;
+    }
+
+    return 1;
+}
+
+sub replace_image_links {
+    my $self = shift (@_);
+    my ($dir, $doc_obj, $front, $link, $back) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my ($filename, $error);
+    my $foundimage = 0;
+    
+    $link =~ s/\/\///;
+    my ($imagetype) = $link =~ /([^\.]*)$/;
+    $imagetype =~ tr/[A-Z]/[a-z]/;
+    if ($imagetype eq "jpg") {$imagetype = "jpeg";}
+    if ($imagetype !~ /^(jpeg|gif|png)$/) {
+	print $outhandle "BookPlugin: Warning - unknown image type ($imagetype)\n";
+    }
+    my ($imagefile) = $link =~ /([^\/]*)$/;
+    my ($imagepath) = $link =~ /^[^\/]*(.*)$/;
+
+    if (defined $imagepath && $imagepath =~ /\w/) {
+	# relative link
+	$filename = &util::filename_cat ($dir, $imagepath);
+	if (-e $filename) {
+	    $doc_obj->associate_file ($filename, $imagefile, "image/$imagetype");
+	    $foundimage = 1;
+	} else {
+	    $error = "BookPlugin: Warning - couldn't find image file $imagefile in either $filename or";
+	}
+    }
+
+    if (!$foundimage) {
+	$filename = &util::filename_cat ($dir, $imagefile);
+	if (-e $filename) {
+	    $doc_obj->associate_file ($filename, $imagefile, "image/$imagetype");    
+	    $foundimage = 1;
+	} elsif (defined $error) {
+	    print $outhandle "$error $filename\n";
+	} else {
+	    print $outhandle "BookPlugin: Warning - couldn't find image file $imagefile in $filename\n";
+	}
+    }
+
+    if ($foundimage) {
+	return "${front}_httpdocimg_/${imagefile}${back}";
+    } else {
+	return "";
+    }
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/CONTENTdmPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/CONTENTdmPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/CONTENTdmPlugin.pm	(revision 20131)
@@ -0,0 +1,808 @@
+###########################################################################
+#
+# CONTENTdmPlugin.pm -- reasonably with-it pdf plugin
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+package CONTENTdmPlugin;
+
+use ConvertBinaryFile;
+use ReadXMLFile;
+
+use unicode;
+use ghtml;
+
+use strict;
+no strict 'refs'; # so we can use a var for filehandles (eg STDERR)
+
+
+use XMLParser;
+
+# inherit ReadXMLFile for the apply_xslt method
+sub BEGIN {
+    @CONTENTdmPlugin::ISA = ('ConvertBinaryFile', 'ReadXMLFile');
+}
+
+
+my $convert_to_list =
+    [ {	'name' => "auto",
+	'desc' => "{ConvertBinaryFile.convert_to.auto}" },
+      {	'name' => "html",
+	'desc' => "{ConvertBinaryFile.convert_to.html}" },
+      {	'name' => "text",
+	'desc' => "{ConvertBinaryFile.convert_to.text}" },
+      { 'name' => "pagedimg",
+	'desc' => "{ConvertBinaryFile.convert_to.pagedimg}"},
+      ];
+
+
+
+my $arguments = 
+      [
+       { 'name' => "convert_to",
+	'desc' => "{ConvertBinaryFile.convert_to}",
+	'type' => "enum",
+	'reqd' => "yes",
+	'list' => $convert_to_list, 
+	'deft' => "html" },	 
+      { 'name' => "xslt",
+	'desc' => "{ReadXMLFile.xslt}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" },
+       { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" },
+      { 'name' => "block_exp",
+	'desc' => "{BasePlugin.block_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_block_exp() }
+];
+
+my $options = { 'name'     => "CONTENTdmPlugin",
+		'desc'     => "{CONTENTdmPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		# CONTENTdmPlugin is one of the few ConvertBinaryFile subclasses whose source doc can't be replaced by a GS-generated html
+		'srcreplaceable' => "no",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@$inputargs,"-title_sub");
+    push(@$inputargs,'^(Page\s+\d+)?(\s*1\s+)?');
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my @arg_array = @$inputargs;
+    my $self = new ConvertBinaryFile($pluginlist,$inputargs,$hashArgOptLists);
+    
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    my $parser = new XML::Parser('Style' => 'Stream',
+				 'Pkg' => 'ReadXMLFile',
+				 'PluginObj' => $self,
+				 'Handlers' => {'Char' => \&ReadXMLFile::Char,
+						'XMLDecl' => \&ReadXMLFile::XMLDecl,
+						'Entity'  => \&ReadXMLFile::Entity,
+						'Doctype' => \&ReadXMLFile::Doctype,
+						'Default' => \&ReadXMLFile::Default
+						});  
+    $self->{'parser'} = $parser;
+
+
+    $self->{'rdf_desc'} = undef;
+    $self->{'about_key'} = undef;
+    $self->{'metadata_name'} = undef;
+    $self->{'metadata_value'} = undef;
+
+    $self->{'convert_to'} = "PagedImage";
+    my $secondary_plugin_options = $self->{'secondary_plugin_options'};
+
+    if (!defined $secondary_plugin_options->{'PagedImagePlugin'}){
+	$secondary_plugin_options->{'PagedImagePlugin'} = [];
+    }
+    my $pagedimg_options = $secondary_plugin_options->{'PagedImagePlugin'}; 
+    push(@$pagedimg_options, "-title_sub", '^(Page\s+\d+)?(\s*1\s+)?');
+    push(@$pagedimg_options, "-create_thumbnail", "true", "-create_screenview", "true");
+    push(@$pagedimg_options, "-file_rename_method", "none");
+
+    $self = bless $self, $class;
+
+# ***** no longer needed!
+#    # This needs to be done after blss, to $self passed to XML::Parser
+#    # can correctly resolve the right call-back methods during XML parsing
+
+
+    $self->load_secondary_plugins($class,$secondary_plugin_options,$hashArgOptLists);
+    return $self;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.rdf$^;
+}
+
+sub get_default_block_exp {
+    return q^(?i)\.(jpg|jpeg|gif)$^;
+}
+
+
+
+sub rdf_desc_to_id
+{
+    my $self = shift (@_);
+    my ($rdf_desc) = @_;
+
+    my $rdf_id = {};
+
+    # initialise any .cpd (=complex multi page) structures 
+
+    foreach my $about_key (keys %{$rdf_desc}) {
+	if ($about_key =~ m/\.cpd$/) {
+	    my $about = $rdf_desc->{$about_key};
+	    my $id    = $about->{'dc:identifier'};
+
+	    if ($id =~ m/^\s*$/) {
+		# missing id, make one up based on about attribute
+
+		my ($tailname, $dirname, $suffix)
+		    = &File::Basename::fileparse($about_key, "\\.[^\\.]+\$");
+
+		$id = "about:$tailname";
+	    }
+
+	    $rdf_id->{$id} = $about;
+	    $rdf_id->{$id}->{'ex:filename'} = $about_key;
+	    $rdf_id->{$id}->{'ex:type'} = "complex";
+	    $rdf_id->{$id}->{'pages'} = [];
+	}
+
+    }
+
+    # now add in *non* .cpd items
+
+    foreach my $about_key (keys %{$rdf_desc}) {
+	if ($about_key !~ m/\.cpd$/) {
+	    my $about = $rdf_desc->{$about_key};	    
+	    my $id    = $about->{'dc:identifier'};
+
+
+	    if ($id =~ m/^\s*$/) {
+		# missing id, make one up based on about attribute
+
+		my ($tailname, $dirname, $suffix)
+		    = &File::Basename::fileparse($about_key, "\\.[^\\.]+\$");
+
+		$id = "about:$tailname";
+	    }
+
+	    if (defined $rdf_id->{$id}) {
+		$about->{'ex:filename'} = $about_key;
+
+		# dealing with complex multi-page situation
+		# Add to existing structure
+
+		my $pages = $rdf_id->{$id}->{'pages'};
+		push(@$pages,$about)
+	    }
+	    else {
+		# New entry
+
+		$rdf_id->{$id} = $about;
+		$rdf_id->{$id}->{'ex:type'} = "simple";	    
+		$rdf_id->{$id}->{'ex:filename'} = $about_key;
+	    }
+	}
+	
+    }
+
+    return $rdf_id;
+}
+
+
+sub metadata_table_txt_file
+{
+    my $self = shift (@_);
+    my ($output_root,$page_num) = @_;
+
+    my $txt_filename = $output_root."_page_$page_num.txt";
+
+    my ($tailname, $dirname, $suffix)
+	= &File::Basename::fileparse($txt_filename, "\\.[^\\.]+\$");
+
+    my $txt_file = "$tailname$suffix";
+
+    return $txt_file;
+}
+
+
+sub output_metadata_table 
+{
+    my $self = shift (@_);
+    my ($page,$page_num,$tmp_dirname,$txt_file) = @_;
+    
+    my $txt_filename = &util::filename_cat($tmp_dirname,$txt_file);
+
+    open(TOUT,">$txt_filename") 
+	|| die "Error: unable to write metadata data out as txt file $txt_filename: $!\n";
+    
+    print TOUT $page->{'MetadataTable'};
+    delete $page->{'MetadataTable'};
+
+    close (TOUT);
+}
+
+
+sub rdf_id_to_item_file
+{
+    my $self = shift (@_);
+    my ($rdf_id,$tmp_dirname,$output_root) = @_;
+
+    my $item_file_list = [];
+    
+    foreach my $id (keys %{$rdf_id}) {
+
+	my $id_safe = $id;
+	$id_safe =~ s/ /-/g;
+
+	my $output_filename = $output_root."_$id_safe.item";
+	open(FOUT,">$output_filename") 
+	    || die "Unable to open $output_filename: $!\n";
+	
+
+	print FOUT "<PagedDocument>\n";
+
+	my $rdf_doc = $rdf_id->{$id};
+	foreach my $metadata_name (keys %$rdf_doc) {
+
+
+	    next if ($metadata_name eq "pages");
+
+	    my $metadata_value = $rdf_doc->{$metadata_name};
+
+	    # convert ns:name to ns.Name
+	    $metadata_name =~ s/^(.*?):(.*)/$1\.\u$2/; 
+
+	    print FOUT "  <Metadata name=\"$metadata_name\">$metadata_value</Metadata>\n";
+	}
+
+	if ($rdf_doc->{'ex:type'} eq "complex") {
+	    my $pages = $rdf_doc->{'pages'};
+	    my $page_num = 1;
+
+	    foreach my $page (@$pages) {
+
+		my $imgfile = $page->{'ex:filename'};
+		if ($imgfile =~ m/(http|ftp):/) {
+		    $imgfile = "empty.jpg";
+		}
+		else {
+		    $imgfile = &util::filename_cat("..","import",$imgfile);
+		}
+		
+		my $txt_file 
+		    = $self->metadata_table_txt_file($output_root,$page_num);
+
+		$self->output_metadata_table($page,$page_num,
+					     $tmp_dirname,$txt_file);
+
+
+		print FOUT "  <Page pagenum=\"$page_num\" imgfile=\"$imgfile\" txtfile=\"$txt_file\">\n";
+
+		foreach my $metadata_name (keys %$page) {
+		
+		    my $metadata_value = $rdf_doc->{$metadata_name};
+		    # convert ns:name to ns.Name
+		    $metadata_name =~ s/^(.*?):(.*)/$1\.\u$2/; 
+
+		    print FOUT "  <Metadata name=\"$metadata_name\">$metadata_value</Metadata>\n";
+		}
+		
+
+		$page_num++;
+
+
+		print FOUT "  </Page>\n";
+	    }
+	}
+	else {
+	    # simple
+	    # duplicate top-level metadata for now plus image to bind to
+
+	    my $imgfile = $rdf_doc->{'ex:filename'};
+	    if ($imgfile =~ m/(http|ftp):/) {
+		$imgfile = "empty.jpg";
+	    }
+	    else {
+		$imgfile = &util::filename_cat("..","import",$imgfile);
+		$imgfile = "../import/".$imgfile;
+	    }
+
+
+	    my $txt_file = $self->metadata_table_txt_file($output_root,1);
+	    $self->output_metadata_table($rdf_doc,1,$tmp_dirname,$txt_file);
+
+	    print FOUT "  <Page pagenum=\"1\" imgfile=\"$imgfile\" txtfile=\"$txt_file\">\n";	    
+	    foreach my $metadata_name (keys %$rdf_doc) {
+
+		my $metadata_value = $rdf_doc->{$metadata_name};
+		
+		# convert ns:name to ns.Name
+		$metadata_name =~ s/^(.*?):(.*)/$1\.\u$2/; 
+
+		print FOUT "  <Metadata name=\"$metadata_name\">$metadata_value</Metadata>\n";
+	    }
+	    print FOUT "  </Page>\n";
+
+	}
+
+	print FOUT "</PagedDocument>\n";
+	close(FOUT);
+
+	push(@$item_file_list,$output_filename);
+
+    }
+    
+
+    return $item_file_list;
+}
+
+
+
+sub xml_area_convert_file
+{
+    my $self = shift (@_);
+    my ($input_filename, $tmp_dirname, $output_root) = @_;
+
+    eval {
+	# Build up hash table/tree of all records
+
+	my $xslt = $self->{'xslt'};
+	if (defined $xslt && ($xslt ne "")) {
+	    # perform xslt
+	    my $transformed_xml = $self->apply_xslt($xslt,$input_filename);
+
+	    open(TOUT,">/tmp/tout.xml") 
+		|| die "Unable to open /tmp/tout.xml: $!\n";
+	    print TOUT $transformed_xml;
+	    close(TOUT);
+
+
+	    # feed transformed file (now in memory as string) into XML parser
+	    $self->{'parser'}->parse($transformed_xml);
+	}
+	else {
+	    $self->{'parser'}->parsefile($input_filename);
+	}
+    };
+  
+    if ($@) {
+
+	# parsefile may either croak somewhere in XML::Parser (e.g. because
+	# the document is not well formed) or die somewhere in XMLPlug or a
+	# derived plugin (e.g. because we're attempting to process a
+	# document whose DOCTYPE is not meant for this plugin). For the
+	# first case we'll print a warning and continue, for the second
+	# we'll just continue quietly
+
+	print STDERR "**** Error is: $@\n";
+
+	my $file = $self->{'file'};
+
+	my ($msg) = $@ =~ /Carp::croak\(\'(.*?)\'\)/;
+	if (defined $msg) {	
+	    my $outhandle = $self->{'outhandle'};
+	    my $plugin_name = ref ($self);
+	    print $outhandle "$plugin_name failed to process $file ($msg)\n";
+	}
+
+	my $gli = $self->{'gli'};
+
+	# reset ourself for the next document
+	$self->{'section_level'}=0;
+	print STDERR "<ProcessingError n='$file'>\n" if ($gli);
+	return ("fail",undef); # error during processing
+    }
+
+    my $rdf_desc = $self->{'rdf_desc'};    
+
+#    foreach my $about_key (keys %{$rdf_desc}) {
+#	my $about = $rdf_desc->{$about_key};
+#	foreach my $metadata_name (keys %{$about}) {
+#
+#	    my $metadata_value = $about->{$metadata_name};
+##	    print STDERR " $metadata_name: $metadata_value\n";
+#	}
+#    }
+
+
+    # Merge entries with same name
+
+
+    my $merged_rdf_id = $self->rdf_desc_to_id($rdf_desc);
+
+#    foreach my $about_key (keys %{$merged_rdf_id}) {
+#	my $about = $merged_rdf_id->{$about_key};
+#	foreach my $metadata_name (keys %{$about}) {
+#
+#	    my $metadata_value = $about->{$metadata_name};
+##	    print STDERR " $metadata_name: $metadata_value\n";
+#	}
+#    }
+
+
+
+    my $item_files = $self->rdf_id_to_item_file($merged_rdf_id,$tmp_dirname, 
+						$output_root);
+
+    return ("item",$item_files);
+}
+
+
+# Override ConvertBinaryFile tmp_area_convert_file() to provide solution specific 
+# to CONTENTdm
+#
+# A better (i.e. in the future) solution would be to see if this can be
+# shifted into gsConvert.pl so there is no need to override the
+# default tmp_area_convert_file()
+
+
+sub tmp_area_convert_file {
+    my $self = shift (@_);
+    my ($output_ext, $input_filename, $textref) = @_;
+
+    # is textref ever used?!?
+
+    my $outhandle = $self->{'outhandle'};
+    my $convert_to = $self->{'convert_to'};
+    my $failhandle = $self->{'failhandle'};
+    my $convert_to_ext = $self->{'convert_to_ext'};
+    
+    # softlink to collection tmp dir
+    my $tmp_dirname 
+	= &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "tmp");
+    &util::mk_dir($tmp_dirname) if (!-e $tmp_dirname);
+
+    # derive tmp filename from input filename
+    my ($tailname, $dirname, $suffix)
+	= &File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
+
+    # Remove any white space from filename -- no risk of name collision, and
+    # makes later conversion by utils simpler. Leave spaces in path...
+    # tidy up the filename with space, dot, hyphen between
+    $tailname =~ s/\s+//g; 
+    $tailname =~ s/\.+//g;
+    $tailname =~ s/\-+//g;
+
+    $tailname = $self->SUPER::filepath_to_utf8($tailname) unless &unicode::check_is_utf8($tailname);
+    $suffix = lc($suffix);
+    my $tmp_filename = &util::filename_cat($tmp_dirname, "$tailname$suffix");
+
+    &util::soft_link($input_filename, $tmp_filename);
+    my $verbosity = $self->{'verbosity'};
+    if ($verbosity > 0) {
+	print $outhandle "Converting $tailname$suffix to $convert_to format\n";
+    }
+
+    my $errlog = &util::filename_cat($tmp_dirname, "err.log");
+    
+    # call xml_area_convert_file rather than gsConvert.pl
+
+    my $output_root = &util::filename_cat($tmp_dirname, "$tailname");
+
+    my ($output_type,$item_files) 
+	= $self->xml_area_convert_file($tmp_filename,$tmp_dirname,$output_root);
+
+
+    my $fakeimg_filename = &util::filename_cat($dirname, "empty.jpg");
+    my $fakeimg_tmp_filename = &util::filename_cat($tmp_dirname, "empty.jpg");
+
+    print STDERR "***** No source image identified with item\n";
+
+    print STDERR "***** Using default \"no image available\" $fakeimg_filename -> $fakeimg_tmp_filename\n";
+
+    &util::soft_link($fakeimg_filename, $fakeimg_tmp_filename);
+   
+    # continue as before ...
+
+    # remove symbolic link to original file
+    &util::rm($tmp_filename);
+
+    # Check STDERR here
+    chomp $output_type;
+    if ($output_type eq "fail") {
+	print $outhandle "Could not convert $tailname$suffix to $convert_to format\n";
+	print $failhandle "$tailname$suffix: " . ref($self) . " failed to convert to $convert_to\n";
+	$self->{'num_not_processed'} ++;
+	if (-s "$errlog") {
+	    open(ERRLOG, "$errlog");
+	    while (<ERRLOG>) {
+		print $outhandle "$_";
+	    }
+	    print $outhandle "\n";
+	    close ERRLOG;
+	}
+	&util::rm("$errlog") if (-e "$errlog");
+	return [];
+    }
+
+    # store the *actual* output type and return the output filename
+    # it's possible we requested conversion to html, but only to text succeeded
+    #$self->{'convert_to_ext'} = $output_type;
+    if ($output_type =~ /html/i) {
+	$self->{'converted_to'} = "HTML";
+    } elsif ($output_type =~ /te?xt/i) {
+	$self->{'converted_to'} = "Text";
+    } elsif ($output_type =~ /item/i){
+	$self->{'converted_to'} = "PagedImage";
+    }
+
+    
+    return $item_files;
+}
+
+
+
+
+# Override ConvertBinaryFile read
+# Needed so multiple .item files generated are sent down secondary plugin
+
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+
+
+    $self->{'gli'} = $gli;
+    $self->{'file'} = $file;
+
+    my $successful_rv = -1;
+
+    my $outhandle = $self->{'outhandle'};
+    
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+
+    $file =~ s/^[\/\\]+//; # $file often begins with / so we'll tidy it up
+
+    # read() deviates at this point from ConvertBinaryFile
+    # Need to work with list of filename returned
+
+    my $output_ext = $self->{'convert_to_ext'};
+    my $conv_filename_list = [];
+
+    $conv_filename_list = $self->tmp_area_convert_file($output_ext, $filename_full_path);
+
+    if (scalar(@$conv_filename_list)==0) {
+	return -1;
+    } # had an error, will be passed down pipeline 
+
+    foreach my $conv_filename ( @$conv_filename_list ) {
+	if (! -e "$conv_filename") {return -1;} 
+	$self->{'conv_filename'} = $conv_filename; # is this used anywhere?
+	$self->convert_post_process($conv_filename);
+    
+	my $secondary_plugins =  $self->{'secondary_plugins'};
+	my $num_secondary_plugins = scalar(keys %$secondary_plugins);
+
+	if ($num_secondary_plugins == 0) {
+	    print $outhandle "Warning: No secondary plugin to use in conversion.  Skipping $file\n";
+	    return 0; # effectively block it
+	}
+
+	my @plugin_names = keys %$secondary_plugins;
+	my $plugin_name = shift @plugin_names;
+	
+	if ($num_secondary_plugins > 1) {
+	    print $outhandle "Warning: Multiple secondary plugins not supported yet!  Choosing $plugin_name\n.";
+	}
+	
+	my $secondary_plugin = $secondary_plugins->{$plugin_name};
+
+	# note: metadata is not carried on to the next level
+	my ($rv,$doc_obj) 
+	    = $secondary_plugin->read_into_doc_obj ($pluginfo,"", $conv_filename, 
+						    $block_hash, $metadata, $processor, $maxdocs, $total_count,
+						    $gli);
+
+	print STDERR "**** $conv_filename => returned rv = $rv\n";
+
+	if ((defined $rv) && ($rv>=0)) {
+	    $successful_rv = 1;
+	}
+
+	# Override previous gsdlsourcefilename set by secondary plugin
+	my $collect_file = &util::filename_within_collection($filename_full_path);
+	my $collect_conv_file = &util::filename_within_collection($conv_filename);
+	$doc_obj->set_source_filename ($collect_file, $self->{'file_rename_method'}); 
+	$doc_obj->set_converted_filename($collect_conv_file);
+	
+	my ($filemeta) = $file =~ /([^\\\/]+)$/;
+	$self->set_Source_metadata($doc_obj, $filemeta);
+	$doc_obj->set_utf8_metadata_element($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");
+	$doc_obj->set_utf8_metadata_element($doc_obj->get_top_section(), "FileSize", (-s $filename_full_path));
+	
+	if ($self->{'cover_image'}) {
+	    $self->associate_cover_image($doc_obj, $filename_full_path);
+	}
+	
+	# do plugin specific processing of doc_obj
+	unless (defined ($self->process(undef, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli))) {
+	    print STDERR "***** process returned undef: $base_dir $file\n";
+	    print STDERR "<ProcessingError n='$file'>\n" if ($gli);
+	    return -1;
+	}
+	# do any automatic metadata extraction
+	$self->auto_extract_metadata ($doc_obj);
+
+	# have we found a Title??
+	$self->title_fallback($doc_obj,$doc_obj->get_top_section(),$filemeta);
+
+	# add an OID
+	$self->add_OID($doc_obj);
+	# process the document
+	$processor->process($doc_obj);
+
+	$self->{'num_processed'} ++;
+    }
+
+    return $successful_rv;
+}
+
+sub process {
+
+    return 1;
+}
+
+# do we need this? sec pluginn process would have already been called as part of read_into_doc_obj??
+sub process_old {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    
+    my $secondary_plugins =  $self->{'secondary_plugins'};
+    my @plugin_names = keys %$secondary_plugins;
+    my $plugin_name = shift @plugin_names; # already checked there is only one
+	
+    my $secondary_plugin = $secondary_plugins->{$plugin_name};
+	
+    my $result = $secondary_plugin->process(@_);
+
+    return $result;
+}
+
+
+# Called at the beginning of the XML document.
+sub xml_start_document {
+    my $self = shift(@_);
+    my ($expat) = @_;
+
+    $self->{'rdf_desc'} = {};
+}
+
+
+# Called for DOCTYPE declarations - use die to bail out if this doctype
+# is not meant for this plugin
+sub xml_doctype {
+    my $self = shift(@_);
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+
+    die "" if ($name !~ /^rdf:RDF$/);
+
+    my $outhandle = $self->{'outhandle'};
+    print $outhandle "CONTENTdmPlugin: processing $self->{'file'}\n" if $self->{'verbosity'} > 1;
+
+}
+
+# Called for every start tag. The $_ variable will contain a copy of the
+# tag and the %_ variable will contain the element's attributes.
+sub xml_start_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+
+    if ($element eq "rdf:Description") {
+
+	my $about_key = $_{'about'};
+
+	my $rdf_desc = $self->{'rdf_desc'};
+	$rdf_desc->{$about_key} = {};
+
+	$self->{'about_key'}  = $about_key;
+	$self->{'index_text'} = "";
+	$self->{'pp_text'}    = "<table width=\"100%\">\n";
+
+
+    }
+    elsif (defined $self->{'about_key'}) {	
+	$self->{'metadata_name'} = $element;
+	$self->{'metadata_value'} = "";
+    }
+
+}
+
+# Called for every end tag. The $_ variable will contain a copy of the tag.
+sub xml_end_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+
+    if ($element eq "rdf:Description") {
+	$self->{'pp_text'} .= "</table>\n";
+	## ghtml::htmlsafe($self->{'pp_text'});
+
+
+	my $about_key = $self->{'about_key'};
+	my $about = $self->{'rdf_desc'}->{$about_key};
+	$about->{'IndexText'}     = $self->{'index_text'};
+	$about->{'MetadataTable'} = $self->{'pp_text'};
+
+
+	$self->{'about_key'}   = undef;
+	$self->{'index_text'}  = undef;
+	$self->{'pp_text'}     = undef;
+
+    }
+    elsif (defined $self->{'metadata_name'}) {
+	my $metadata_name = $self->{'metadata_name'};
+	if ($element eq $metadata_name) {
+	    my $metadata_value = $self->{'metadata_value'};
+
+	    my $about_key = $self->{'about_key'};
+	    my $about = $self->{'rdf_desc'}->{$about_key};
+	    $about->{$metadata_name} = $metadata_value;
+
+	    $self->{'index_text'} .= "$metadata_value\n";
+	    $self->{'pp_text'} .= "  <tr><td>$metadata_name</td><td>$metadata_value</td></tr>\n";
+
+	    $self->{'metadata_name'}  = undef;
+	    $self->{'metadata_value'} = undef;
+	}
+    }
+}
+
+# Called just before start or end tags with accumulated non-markup text in
+# the $_ variable.
+sub xml_text {
+    my $self = shift(@_);
+    my ($expat) = @_;
+
+    if (defined $self->{'metadata_name'}) {
+	$self->{'metadata_value'} .= $_;
+    }
+}
+
+# Called at the end of the XML document.
+sub xml_end_document {
+    my $self = shift(@_);
+    my ($expat) = @_;
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/CSVPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/CSVPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/CSVPlugin.pm	(revision 20131)
@@ -0,0 +1,180 @@
+###########################################################################
+#
+# CSVPlugin.pm -- A plugin for files in comma-separated value format
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package CSVPlugin;
+
+
+use SplitTextFile;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+
+# CSVPlugin is a sub-class of SplitTextFile.
+sub BEGIN {
+    @CSVPlugin::ISA = ('SplitTextFile');
+}
+
+
+my $arguments = 
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() },
+      { 'name' => "split_exp",
+	'desc' => "{SplitTextFile.split_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_split_exp(),
+        'hiddengli' => "yes" }
+      ];
+
+
+my $options = { 'name'     => "CSVPlugin",
+		'desc'     => "{CSVPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'explodes' => "yes",
+		'args'     => $arguments };
+
+
+# This plugin processes files with the suffix ".csv"
+sub get_default_process_exp {
+    return q^(?i)(\.csv)$^;
+}
+
+    
+# This plugin splits the input text by line
+sub get_default_split_exp {
+    return q^\r?\n^;
+}
+
+
+sub new
+{
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}}, @{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}}, $options);
+
+    my $self = new SplitTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+
+sub read_file
+{
+    my $self = shift (@_);
+    my ($filename, $encoding, $language, $textref) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    # Read the CSV file content
+    open(FILE, $filename);
+    my $reader = new multiread();
+    $reader->set_handle('CSVPlugin::FILE');
+    $reader->set_encoding($encoding);
+    $reader->read_file($textref);
+    close(FILE);
+
+    # Remove any blank lines so the data is split and processed properly
+    $$textref =~ s/\n(\s*)\n/\n/g;
+
+    # The first line contains the metadata element names
+    $$textref =~ s/^(.*?)\r?\n//;
+    my @csv_file_fields = ();
+    my $csv_file_field_line = $1 . ",";  # To make the regular expressions simpler
+    while ($csv_file_field_line ne "") {
+	# Handle quoted values
+	if ($csv_file_field_line =~ s/^\"(.*?)\"\,//) {
+	    my $csv_file_field = $1;
+	    $csv_file_field =~ s/ //g;  # Remove any spaces from the field names
+	    push(@csv_file_fields, $csv_file_field);
+	}
+	# Normal comma-separated case
+	elsif ($csv_file_field_line =~ s/^(.*?)\,//) {
+	    my $csv_file_field = $1;
+	    $csv_file_field =~ s/ //g;  # Remove any spaces from the field names
+	    push(@csv_file_fields, $csv_file_field);
+	}
+	# The line must be formatted incorrectly
+	else {
+	    print STDERR "Error: Badly formatted CSV field line: $csv_file_field_line.\n";
+	    last;
+	}
+    }
+    $self->{'csv_file_fields'} = \@csv_file_fields;
+}
+
+
+sub process
+{
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my $section = $doc_obj->get_top_section();
+    my $csv_line = $$textref;
+    my @csv_file_fields = @{$self->{'csv_file_fields'}};
+
+    # Add the raw line as the document text
+    $doc_obj->add_utf8_text($section, $csv_line);
+
+    # Build a hash of metadata name to metadata value for this line
+    my $i = 0;
+    $csv_line .= ",";  # To make the regular expressions simpler
+    while ($csv_line ne "") {
+	# Metadata values containing commas are quoted
+	if ($csv_line =~ s/^\"(.*?)\"\,//) {
+	    # Only bother with non-empty values
+	    if ($1 ne "" && defined($csv_file_fields[$i])) {
+		$doc_obj->add_utf8_metadata($section, $csv_file_fields[$i], $1);
+	    }
+	}
+	# Normal comma-separated case
+	elsif ($csv_line =~ s/^(.*?)\,//) {
+	    # Only bother with non-empty values
+	    if ($1 ne "" && defined($csv_file_fields[$i])) {
+		$doc_obj->add_utf8_metadata($section, $csv_file_fields[$i], $1);
+	    }
+	}
+	# The line must be formatted incorrectly
+	else {
+	    print STDERR "Error: Badly formatted CSV line: $csv_line.\n";
+	    last;
+	}
+
+	$i++;
+    }
+
+    # Record was processed successfully
+    return 1;
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/ConvertBinaryFile.pm
===================================================================
--- /gsdl/stable/perllib/plugins/ConvertBinaryFile.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/ConvertBinaryFile.pm	(revision 20131)
@@ -0,0 +1,515 @@
+###########################################################################
+#
+# ConvertBinaryFile.pm -- plugin that facilitates conversion of binary files
+# through gsConvert.pl 
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# This plugin is inherited by such plugins as WordPlugin, PowerPointPlugin, 
+# PostScriptPlugin, 
+# RTFPlugin and PDFPlugin. It facilitates the conversion of these document types 
+# to either HTML, Text or a series of images. It works by dynamically loading 
+# an appropriate secondary plugin (HTMLPlug, StructuredHTMLPlug, 
+# PagedImagePlugin or TextPlugin) based on the plugin argument 'convert_to'. 
+
+package ConvertBinaryFile;
+
+use AutoExtractMetadata;
+use ghtml;
+use HTMLPlugin;
+use TextPlugin;
+use PagedImagePlugin;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+no strict 'subs';
+
+sub BEGIN {
+    @ConvertBinaryFile::ISA = ('AutoExtractMetadata');
+}
+
+my $convert_to_list =
+    [ {	'name' => "auto",
+	'desc' => "{ConvertBinaryFile.convert_to.auto}" },
+      {	'name' => "html",
+	'desc' => "{ConvertBinaryFile.convert_to.html}" },
+      {	'name' => "text",
+	'desc' => "{ConvertBinaryFile.convert_to.text}" }
+      ];
+
+my $arguments =
+    [ { 'name' => "convert_to",
+	'desc' => "{ConvertBinaryFile.convert_to}",
+	'type' => "enum",
+	'reqd' => "yes",
+	'list' => $convert_to_list, 
+	'deft' => "auto" },
+      { 'name' => "keep_original_filename",
+	'desc' => "{ConvertBinaryFile.keep_original_filename}",
+	'type' => "flag" },
+      { 'name' => "title_sub",
+	'desc' => "{HTMLPlugin.title_sub}",
+	'type' => "string", 
+	#'type' => "regexp",
+	'deft' => "" },
+      { 'name' => "apply_fribidi",
+	'desc' => "{ConvertBinaryFile.apply_fribidi}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "use_strings",
+	'desc' => "{ConvertBinaryFile.use_strings}",
+	'type' => "flag",
+	'reqd' => "no" },
+      ];
+
+my $options = { 'name'     => "ConvertBinaryFile",
+		'desc'     => "{ConvertBinaryFile.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub load_secondary_plugins
+{
+    my $self = shift (@_);
+    my ($class,$input_args,$hashArgOptLists) = @_;
+
+    my @convert_to_list = split(",",$self->{'convert_to'});
+    my $secondary_plugins = {};
+    # find the plugin
+
+    foreach my $convert_to (@convert_to_list) {
+	# load in "convert_to" plugin package
+	my $plugin_class = $convert_to."Plugin";
+	my $plugin_package = $plugin_class.".pm";
+
+	my $colplugname = undef;
+	if (defined $ENV{'GSDLCOLLECTDIR'}) {
+	    $colplugname = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},
+					       "perllib","plugins", 
+					       $plugin_package);
+	}
+
+	my $mainplugname = &util::filename_cat($ENV{'GSDLHOME'},
+					       "perllib","plugins", 
+					       $plugin_package);
+
+	if ((defined $colplugname) && (-e $colplugname)) { require $colplugname;}
+	elsif (-e $mainplugname) { require $mainplugname; }
+	else {
+	    &gsprintf(STDERR, "{plugin.could_not_find_plugin}\n",
+		      $plugin_class);
+	    die "\n";
+	}
+
+	# call its constructor with extra options that we've worked out!
+	my $arglist = $input_args->{$plugin_class};
+
+	my ($secondary_plugin);
+	eval("\$secondary_plugin = new $plugin_class([],\$arglist)");
+	die "$@" if $@;
+	$secondary_plugins->{$plugin_class} = $secondary_plugin;
+    }
+    $self->{'secondary_plugins'} = $secondary_plugins;
+}
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+    my $classPluginName = (defined $pluginlist->[0]) ? $pluginlist->[0] : $class;
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new AutoExtractMetadata($pluginlist, $inputargs, $hashArgOptLists);
+    
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    my $convert_to_type = $self->{'convert_to'};
+    if (!defined $convert_to_type || $convert_to_type eq "") {
+	$convert_to_type = "auto";
+    }
+    my $windows_scripting = $self->{'windows_scripting'};
+    $windows_scripting = 0 unless defined $windows_scripting;
+    if ($classPluginName eq "PDFPlugin") {
+	if ($convert_to_type eq "text" && 
+	    $ENV{'GSDLOS'} =~ /^windows$/i) {
+	    print STDERR "Windows does not support pdf to text. PDFs will be converted to HTML instead\n";
+	    $convert_to_type = "html";
+	}
+    } elsif ($classPluginName eq "WordPlugin") {
+	if ($windows_scripting && $ENV{'GSDLOS'} =~ /^windows$/i && $convert_to_type =~ /^(html|auto)$/) {
+	    # we use structured HTML, not normal html
+	    $convert_to_type = "structuredhtml";
+	} 
+    } elsif ($classPluginName eq "PowerPointPlugin") {
+	if ($windows_scripting && $ENV{'GSDLOS'} =~ /^windows$/i && $convert_to_type eq "auto") {
+	    # we use paged img
+	    $convert_to_type = "pagedimg_jpg";
+	} 
+    } elsif ($classPluginName eq "PostScriptPlugin") {
+	if ($convert_to_type eq "auto") {
+	    # we use text
+	    $convert_to_type = "text";
+	}
+    }
+    
+    if ($convert_to_type eq "auto") {
+	# choose html for now - should choose a format based on doc type
+	$convert_to_type = "html";
+    }
+    
+    if ($convert_to_type eq "html") {
+	$self->{'convert_to'} = "HTML";
+	$self->{'convert_to_ext'} = "html";
+    } elsif ($convert_to_type eq "text") {
+	$self->{'convert_to'} = "Text";
+	$self->{'convert_to_ext'} = "txt";
+    } elsif ($convert_to_type eq "structuredhtml") {
+	$self->{'convert_to'} = "StructuredHTML";
+	$self->{'convert_to_ext'} = "html";
+    } elsif ($convert_to_type =~ /^pagedimg/) {
+	$self->{'convert_to'} = "PagedImage";
+	my ($convert_to_ext) = $convert_to_type =~ /pagedimg\_(jpg|gif|png)/i;
+	$convert_to_ext = 'jpg' unless defined $convert_to_ext;
+	$self->{'convert_to_ext'} = $convert_to_ext;
+    }
+
+    return bless $self, $class;
+}
+
+
+sub init {
+    my $self = shift (@_);
+    my ($verbosity, $outhandle, $failhandle) = @_;
+
+    $self->SUPER::init($verbosity,$outhandle,$failhandle);
+
+    my $secondary_plugins =  $self->{'secondary_plugins'};
+
+    foreach my $plug_name (keys %$secondary_plugins) {
+	my $plugin = $secondary_plugins->{$plug_name};
+	$plugin->init($verbosity,$outhandle,$failhandle);
+    }
+}
+
+sub deinit {
+    # called only once, after all plugin passes have been done
+
+    my ($self) = @_;
+
+    my $secondary_plugins =  $self->{'secondary_plugins'};
+
+    foreach my $plug_name (keys %$secondary_plugins) {
+	my $plugin = $secondary_plugins->{$plug_name};
+	$plugin->deinit();
+    }
+}
+
+sub convert_post_process
+{
+    # by default do no post processing
+    return;
+}
+
+
+# Run conversion utility on the input file.  
+#
+# The conversion takes place in a collection specific 'tmp' directory so 
+# that we don't accidentally damage the input.
+#
+# The desired output type is indicated by $output_ext.  This is usually
+# something like "html" or "word", but can be "best" (or the empty string)
+# to indicate that the conversion utility should do the best it can.
+sub tmp_area_convert_file {
+    my $self = shift (@_);
+    my ($output_ext, $input_filename, $textref) = @_;
+    
+    my $outhandle = $self->{'outhandle'};
+    my $convert_to = $self->{'convert_to'};
+    my $failhandle = $self->{'failhandle'};
+    my $convert_to_ext = $self->{'convert_to_ext'};
+    
+    # derive tmp filename from input filename
+    my ($tailname, $dirname, $suffix)
+	= &File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
+
+    # softlink to collection tmp dir
+    my $tmp_dirname = $dirname;
+    if(defined $ENV{'GSDLCOLLECTDIR'}) {
+	$tmp_dirname = $ENV{'GSDLCOLLECTDIR'};
+    } elsif(defined $ENV{'GSDLHOME'}) {
+	$tmp_dirname = $ENV{'GSDLHOME'};
+    }
+    $tmp_dirname = &util::filename_cat($tmp_dirname, "tmp");
+    &util::mk_dir($tmp_dirname) if (!-e $tmp_dirname);
+   
+    # The following is not necessary and will cause problems with
+    # replacing_srcdoc_with_html in the GSDLremote case:
+    # Remove any white space from filename -- no risk of name collision, and
+    # makes later conversion by utils simpler. Leave spaces in path...
+    # tidy up the filename with space, dot, hyphen between
+    #$tailname =~ s/\s+//g; 
+    #$tailname =~ s/\.+//g;
+    #$tailname =~ s/\-+//g;
+
+    # convert to utf-8 otherwise we have problems with the doc.xml file later on
+#    print STDERR "**** filename $tailname$suffix is already UTF8\n" if &unicode::check_is_utf8($tailname);
+    $tailname = $self->SUPER::filepath_to_utf8($tailname) unless &unicode::check_is_utf8($tailname);
+
+    # URLEncode this since htmls with images where the html filename is utf8 don't seem
+    # to work on Windows (IE or Firefox), as browsers are looking for filesystem-encoded
+    # files on the filesystem.
+    $tailname = &util::rename_file($tailname, $self->{'file_rename_method'}, "without_suffix");
+
+    $suffix = lc($suffix);
+    my $tmp_filename = &util::filename_cat($tmp_dirname, "$tailname$suffix");
+    
+    # If gsdl is remote, we're given relative path to input file, of the form import/tailname.suffix
+    # But we can't softlink to relative paths. Therefore, we need to ensure that
+    # the input_filename is the absolute path, see http://perldoc.perl.org/File/Spec.html
+    my $ensure_path_absolute = 1; # true
+    &util::soft_link($input_filename, $tmp_filename, $ensure_path_absolute);
+    my $verbosity = $self->{'verbosity'};
+    if ($verbosity > 0) {
+	print $outhandle "Converting $tailname$suffix to $convert_to format\n";
+    }
+
+    my $errlog = &util::filename_cat($tmp_dirname, "err.log");
+    
+    # Execute the conversion command and get the type of the result,
+    # making sure the converter gives us the appropriate output type
+    my $output_type="";
+    if ($convert_to =~ m/PagedImage/i) {
+	$output_type = lc($convert_to)."_".lc($convert_to_ext);
+    } else {
+	$output_type = lc($convert_to);
+    }
+
+    my $cmd = "perl -S gsConvert.pl -verbose $verbosity ";
+    if (defined $self->{'convert_options'}) {
+	$cmd .= $self->{'convert_options'} . " ";
+    }
+    if ($self->{'use_strings'}) {
+      $cmd .= "-use_strings ";
+    }
+    $cmd .= "-errlog \"$errlog\" -output $output_type \"$tmp_filename\"";
+    $output_type = `$cmd`;
+
+    # remove symbolic link to original file
+    &util::rm($tmp_filename);
+    
+    # Check STDERR here
+    chomp $output_type;
+    if ($output_type eq "fail") {
+	print $outhandle "Could not convert $tailname$suffix to $convert_to format\n";
+	print $failhandle "$tailname$suffix: " . ref($self) . " failed to convert to $convert_to\n";
+	# The following  meant that if a conversion failed, the document would be counted twice - do we need it for anything?
+	#$self->{'num_not_processed'} ++;
+	if (-s "$errlog") {
+	    open(ERRLOG, "$errlog");
+	    while (<ERRLOG>) {
+		print $outhandle "$_";
+	    }
+	    print $outhandle "\n";
+	    close ERRLOG;
+	}
+	&util::rm("$errlog") if (-e "$errlog");
+	return "";
+    }
+
+    # store the *actual* output type and return the output filename
+    # it's possible we requested conversion to html, but only to text succeeded
+    #$self->{'convert_to_ext'} = $output_type;
+    if ($output_type =~ /html/i) {
+	$self->{'converted_to'} = "HTML";
+    } elsif ($output_type =~ /te?xt/i) {
+	$self->{'converted_to'} = "Text";
+    } elsif ($output_type =~ /item/i){
+	$self->{'converted_to'} = "PagedImage";
+    }
+    
+    my $output_filename = $tmp_filename;
+    if ($output_type =~ /item/i) {
+	# running under windows
+	if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	    $output_filename = $tmp_dirname . "\\$tailname\\" . $tailname . ".$output_type";
+	} else {
+	    $output_filename = $tmp_dirname . "\/$tailname\/" . $tailname . ".$output_type";
+	}
+    } else {
+	$output_filename =~ s/$suffix$/.$output_type/;
+    }
+    
+    return $output_filename;
+}
+
+
+# Override BasPlug read_into_doc_obj - we need to call secondary plugin stuff
+sub read_into_doc_obj {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+
+    my $output_ext = $self->{'convert_to_ext'};
+    my $conv_filename = "";
+    $conv_filename = $self->tmp_area_convert_file($output_ext, $filename_full_path);
+        
+    if ("$conv_filename" eq "") {return -1;} # had an error, will be passed down pipeline 
+    if (! -e "$conv_filename") {return -1;} 
+    $self->{'conv_filename'} = $conv_filename;
+    $self->convert_post_process($conv_filename);
+
+    # Run the "fribidi" (http://fribidi.org) Unicode Bidirectional Algorithm program over the converted file
+    # Added for fixing up Persian PDFs after being processed by pdftohtml, but may be useful in other cases too
+    if ($self->{'apply_fribidi'} && $self->{'converted_to'} =~ /(HTML|Text)/) {
+	my $fribidi_command = "fribidi \"$conv_filename\" >\"${conv_filename}.tmp\"";
+	if (system($fribidi_command) != 0) {
+	    print STDERR "ERROR: Cannot run fribidi on \"$conv_filename\".\n";
+	}
+	else {
+	    &util::mv("${conv_filename}.tmp", $conv_filename);
+	}	
+    }
+
+    my $secondary_plugins =  $self->{'secondary_plugins'};
+    my $num_secondary_plugins = scalar(keys %$secondary_plugins);
+
+    if ($num_secondary_plugins == 0) {
+	print $outhandle "Warning: No secondary plugin to use in conversion.  Skipping $file\n";
+	return 0; # effectively block it
+    }
+
+    my @plugin_names = keys %$secondary_plugins;
+    my $plugin_name = shift @plugin_names;
+	
+    if ($num_secondary_plugins > 1) {
+	print $outhandle "Warning: Multiple secondary plugins not supported yet!  Choosing $plugin_name\n.";
+    }
+   
+    my $secondary_plugin = $secondary_plugins->{$plugin_name};
+
+    # note: metadata is not carried on to the next level
+## **** I just replaced $metadata with {} in following
+    my ($rv,$doc_obj) 
+	= $secondary_plugin->read_into_doc_obj ($pluginfo,"", $conv_filename, $block_hash, {}, $processor, $maxdocs, $total_count, $gli);
+
+    if ((!defined $rv) || ($rv<1)) {
+	# wasn't processed
+	return $rv;
+    }
+    
+    # Override previous gsdlsourcefilename set by secondary plugin
+    my $collect_file = &util::filename_within_collection($filename_full_path);
+    my $collect_conv_file = &util::filename_within_collection($conv_filename);
+    $doc_obj->set_source_filename ($collect_file, $self->{'file_rename_method'}); 
+    $doc_obj->set_converted_filename($collect_conv_file);
+
+    $self->set_Source_metadata($doc_obj, $filename_no_path);
+        
+    $doc_obj->set_utf8_metadata_element($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");
+    $doc_obj->set_utf8_metadata_element($doc_obj->get_top_section(), "FileSize", (-s $filename_full_path));
+
+    # ****
+    my ($tailname, $dirname, $suffix)
+	= &File::Basename::fileparse($filename_full_path, "\\.[^\\.]+\$");
+$doc_obj->set_utf8_metadata_element($doc_obj->get_top_section(), "FilenameRoot", $tailname);
+
+    # do plugin specific processing of doc_obj
+    unless (defined ($self->process($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli))) {
+	print STDERR "<ProcessingError n='$file'>\n" if ($gli);
+	return -1;
+    }
+
+    my $topsection = $doc_obj->get_top_section();
+    $self->add_associated_files($doc_obj, $filename_full_path);
+
+    # extra_metadata is already called by sec plugin in process??
+    $self->extra_metadata($doc_obj, $topsection, $metadata); # do we need this here??
+    # do any automatic metadata extraction
+    $self->auto_extract_metadata ($doc_obj);
+
+    # have we found a Title??
+    $self->title_fallback($doc_obj,$topsection,$filename_no_path);
+
+    $self->add_OID($doc_obj);
+
+    return (1, $doc_obj);
+
+}
+
+sub process {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    return $self->process_type($base_dir, $file, $doc_obj);
+}
+
+# do plugin specific processing of doc_obj for doc_ext type
+sub process_type {
+    my $self = shift (@_);
+    my ($base_dir, $file, $doc_obj) = @_;
+    
+    # need to check that not empty
+    my $doc_ext = $self->{'filename_extension'};
+    my $file_type = "unknown";
+    $file_type = $self->{'file_type'} if defined $self->{'file_type'};
+    
+    # associate original file with doc object
+    my $cursection = $doc_obj->get_top_section();
+    my $filename = &util::filename_cat($base_dir, $file);
+    my $assocfilename = "doc.$doc_ext";
+    if ($self->{'keep_original_filename'} == 1) {
+	# this should be the same filename that was used for the Source and SourceFile metadata, 
+	# as we will use [SourceFile] in the srclink
+	$assocfilename = $doc_obj->get_assocfile_from_sourcefile();
+    }
+    $doc_obj->associate_file($filename, $assocfilename, undef, $cursection);
+
+    # We use set instead of add here because we only want one value
+    $doc_obj->set_utf8_metadata_element($cursection, "FileFormat", $file_type);
+    my $doclink = "<a href=\"_httpprefix_/collect/[collection]/index/assoc/[archivedir]/doc.$doc_ext\">";
+    if ($self->{'keep_original_filename'} == 1) {
+	$doclink = "<a href=\"_httpprefix_/collect/[collection]/index/assoc/[archivedir]/[SourceFile]\">";
+    }
+    $doc_obj->add_utf8_metadata ($cursection, "srclink",  $doclink); 
+    $doc_obj->add_utf8_metadata ($cursection, "srcicon",  "_icon".$doc_ext."_"); 
+    $doc_obj->add_utf8_metadata ($cursection, "/srclink", "</a>"); 
+
+    return 1;
+}
+
+1;
+
+
+
+
+
+
+
Index: /gsdl/stable/perllib/plugins/ConvertToRogPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/ConvertToRogPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/ConvertToRogPlugin.pm	(revision 20131)
@@ -0,0 +1,453 @@
+###########################################################################
+#
+# ConvertToRogPlugin.pm -- plugin that inherits from RogPlugin
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+package ConvertToRogPlugin;
+
+use RogPlugin;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @ConvertToRogPlugin::ISA = ('RogPlugin');
+}
+
+my $arguments = [
+		 ];
+my $options = { 'name'     => "ConvertToRogPlugin",
+		'desc'     => "{ConvertToRogPlugin.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes" };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new RogPlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    $self->{'convert_to'} = "Rog";
+    $self->{'convert_to_ext'} = "rog";
+
+    return bless $self, $class;
+}
+
+
+sub begin {
+    my $self = shift (@_);
+    
+    $self->SUPER::begin(@_);
+
+    $self->{'docnum'} = 0;
+}
+
+sub end {
+    my ($self) = @_;
+
+    # nothing to do, but keep symmetric with begin function
+    $self->SUPER::end(@_);
+}
+
+
+# Run conversion utility on the input file.  
+#
+# The conversion takes place in a collection specific 'tmp' directory so 
+# that we don't accidentally damage the input.
+#
+# The desired output type is indicated by $output_ext.  This is usually
+# something like "html" or "word", but can be "best" (or the empty string)
+# to indicate that the conversion utility should do the best it can.
+
+sub tmp_area_convert_file {
+    my $self = shift (@_);
+    my ($output_ext, $input_filename, $textref) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+    my $convert_to = $self->{'convert_to'};
+    my $failhandle = $self->{'failhandle'};
+
+    # softlink to collection tmp dir
+    my $tmp_dirname 
+	= &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "tmp");
+    &util::mk_dir($tmp_dirname) if (!-e $tmp_dirname);
+
+    # derive tmp filename from input filename
+    my ($tailname, $dirname, $suffix)
+	= &File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
+
+    # Remove any white space from filename -- no risk of name collision, and
+    # makes later conversion by utils simpler. Leave spaces in path...
+    $tailname =~ s/\s+//g;
+    $tailname = $self->SUPER::filepath_to_utf8($tailname) unless &unicode::check_is_utf8($tailname);
+
+    my $tmp_filename = &util::filename_cat($tmp_dirname, "$tailname$suffix");
+
+    &util::soft_link($input_filename, $tmp_filename);
+
+    my $verbosity = $self->{'verbosity'};
+    if ($verbosity > 0) {
+	print $outhandle "Converting $tailname$suffix to $convert_to format\n";
+    }
+
+    my $errlog = &util::filename_cat($tmp_dirname, "err.log");
+    
+    # Execute the conversion command and get the type of the result,
+    # making sure the converter gives us the appropriate output type
+    my $output_type = lc($convert_to);
+    my $cmd = "perl -S gsMusicConvert.pl -verbose $verbosity -errlog \"$errlog\" -output $output_type \"$tmp_filename\"";
+    $output_type = `$cmd`;
+
+    # remove symbolic link to original file
+    &util::rm($tmp_filename);
+
+    # Check STDERR here
+    chomp $output_type;
+    if ($output_type eq "fail") {
+	print $outhandle "Could not convert $tailname$suffix to $convert_to format\n";
+	print $failhandle "$tailname$suffix: " . ref($self) . " failed to convert to $convert_to\n";
+	$self->{'num_not_processed'} ++;
+	if (-s "$errlog") {
+	    open(ERRLOG, "$errlog");
+	    while (<ERRLOG>) {
+		print $outhandle "$_";
+	    }
+	    print $outhandle "\n";
+	    close ERRLOG;
+	}
+	&util::rm("$errlog") if (-e "$errlog");
+	return "";
+    }
+
+    # store the *actual* output type and return the output filename
+    # it's possible we requested conversion to html, but only to text succeeded
+
+    $self->{'convert_to_ext'} = $output_type;
+    $self->{'converted_to'} = "Rog";
+
+    my $output_filename = $tmp_filename;
+
+    $output_filename =~ s/$suffix$//;
+
+    return $output_filename;
+}
+
+
+# Remove collection specific tmp directory and all its contents.
+
+sub cleanup_tmp_area {
+    my $self = shift (@_);
+
+    my $tmp_dirname 
+	= &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "tmp");
+    &util::rm_r($tmp_dirname);
+    &util::mk_dir($tmp_dirname);
+}
+
+
+# Exact copy of read_rog_record from RogPlugin 
+# Needed for FILE in right scope
+
+sub read_rog_record
+{
+    my ($self,$file_buffer, $docnum, $seclevel) = @_;
+
+    my $next_line = $file_buffer->{'next_line'};
+
+    return 0 if (!defined $next_line);
+
+    if ($next_line eq "")
+    {
+	my $line;
+	while(defined($line=<FILE>))  
+	{
+	    $line =~ s/\r$//;
+	    $file_buffer->{'line_no'}++;
+	    next if ($line =~ m/^\#/);
+	    $next_line = $line;
+	    last;
+	}
+    }
+	    
+    if ($next_line !~ m/^song( +)\"([^\"]*)\"( +)\"([^\"]*)\"( +)(\d+)( *)$/) 
+    {
+	print STDERR "Error: Malformed Rog file: $next_line";
+	return 0;
+    }
+    else
+    {
+	# init default values
+	$file_buffer->{'song'}->{'tempo'}    = 120;
+	$file_buffer->{'song'}->{'ks_type'}  = 0;
+	$file_buffer->{'song'}->{'ks_num'}   = 0;
+	$file_buffer->{'song'}->{'metadata'} = [];
+	$file_buffer->{'song'}->{'content'}  = "";
+	
+	$file_buffer->{'song'}->{'subcol'} = $2;
+	$file_buffer->{'song'}->{'title'}  = $4;
+	$file_buffer->{'song'}->{'tval'}   = $6;
+
+	chomp($next_line);
+	my $content = $next_line;
+	if (defined $docnum) 
+	{
+	    $content.= " $docnum $seclevel";
+	}
+	$content .= "\n";
+
+	$file_buffer->{'song'}->{'content'} = $content;
+
+
+	my $line;
+	while(defined($line=<FILE>))  
+	{
+	    $line =~ s/\r$//;
+
+	    $file_buffer->{'line_no'}++;
+	    next if ($line =~ m/^\#/);
+	
+	    if ($line =~ m/^song/) 
+	    {	
+		$file_buffer->{'next_line'} = $line;
+		return 1;
+	    }
+	    elsif ($line =~ m/^tempo( +)(\d+)( *)$/) 
+	    {
+		$file_buffer->{'song'}->{'tempo'} = $2;
+		$file_buffer->{'song'}->{'content'} .= $line;
+	    } 
+	    elsif ($line =~ m/^keysig( +)(\d+)( +)(\d+)( *)$/) 
+	    {
+		$file_buffer->{'song'}->{'ks_type'} = $2;
+		$file_buffer->{'song'}->{'ks_num'}  = $4;
+		$file_buffer->{'song'}->{'content'} .= $line;	   
+	    } 
+	    elsif ($line =~ m/^timesig( +)(\d+)( +)(\d+)( *)$/) 
+	    {
+		$file_buffer->{'song'}->{'ts_numer'} = $2;
+		$file_buffer->{'song'}->{'ts_denom'} = $4;
+		$file_buffer->{'song'}->{'content'} .= $line;
+	    }
+	    elsif ($line =~ m/^metadata ([^:]*): (.*)/)
+	    {
+		push(@{$file_buffer->{'song'}->{'metadata'}},[$1,$2]);
+		$file_buffer->{'song'}->{'content'} .= $line;
+	    }
+	    else
+	    {
+		$file_buffer->{'song'}->{'content'} .= $line;
+	    }
+	}
+	
+	$file_buffer->{'next_line'} = undef;
+    }
+
+    return 1;
+}
+
+# Override RogPlugin function so rog files are stored as sections (not docs)
+
+sub process_rog_record
+{
+    my ($self,$doc_obj,$cursection,$song) = @_;
+
+    $cursection = 
+	$doc_obj->insert_section($cursection);
+    $self->{'docnum'}++;
+
+    my $title = $song->{'title'};
+    my $title_safe = $title;
+    $title_safe =~ s/\'/\\\\&apos;/g;
+
+    # add metadata 
+    $doc_obj->add_metadata($cursection, "Tempo",         $song->{'tempo'}); 
+    $doc_obj->add_metadata($cursection, "KeySigType",    $song->{'ks_type'}); 
+    $doc_obj->add_metadata($cursection, "KeySigNum",     $song->{'ks_num'}); 
+    $doc_obj->add_metadata($cursection, "SubCollection", $song->{'subcol'}); 
+    $doc_obj->add_metadata($cursection, "Title",         $title); 
+    $doc_obj->add_metadata($cursection, "TitleSafe",     $title_safe); 
+    $doc_obj->add_metadata($cursection, "TVal",          $song->{'tval'}); 
+
+    foreach my $md ( @{$song->{'metadata'}} )
+    {
+	$doc_obj->add_metadata($cursection, $md->[0], $md->[1]); 
+    }
+
+    # add contents as text
+    $doc_obj->add_text($cursection,$song->{'content'});
+
+    return $cursection;
+}
+
+
+
+# Override BasePlugin read
+# We don't want to get language encoding stuff until after we've converted
+# our file to Rog format
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+ 
+    $file =~ s/^[\/\\]+//; # $file often begins with / so we'll tidy it up
+
+    # read in file ($text will be in utf8)
+    my $text = "";
+
+    my $output_ext = $self->{'convert_to_ext'};
+    my $conv_filename = $self->tmp_area_convert_file($output_ext, $filename_full_path);
+
+    if ("$conv_filename" eq "") {return 0;} # allows continue on errors
+    $self->{'conv_filename'} = $conv_filename;
+
+
+    # create a new document
+    #my $doc_obj = new doc ($conv_filename, "indexed_doc");
+    # the original filename is used now
+    my $doc_obj = new doc ($filename_full_path, "indexed_doc", $self->{'file_rename_method'});
+    # the converted filename is set separately
+    $doc_obj->set_converted_filename($conv_filename);
+
+    my $topsection = $doc_obj->get_top_section();
+    my $cursection = $topsection;
+
+    $self->{'docnum'}++;
+    my $docnum = $self->{'docnum'};
+
+    my ($filemeta) = $file =~ /([^\\\/]+)$/;
+    $self->set_Source_metadata($doc_obj, $filemeta);
+    
+    if ($self->{'cover_image'}) {
+	$self->associate_cover_image($doc_obj, $filename_full_path);
+    }
+    $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");
+    $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "FileSize", (-s $filename_full_path));
+
+    my $track_no = "1";
+    my $rog_filename = "$conv_filename$track_no.$output_ext";
+    while (1)
+    {
+	last unless open (FILE, $rog_filename) ;
+
+	my $file_buffer = { line_no => 0, next_line => "", song => {} };
+	
+	while ($self->read_rog_record($file_buffer, $docnum, $track_no))
+	{
+	    my $song = $file_buffer->{'song'};
+	    my $content = $song->{'content'};
+	    $content =~ s/^song\w+(.*)$/song $1 X.$track_no/;
+	    
+	    $cursection 
+		= $self->process_rog_record($doc_obj,$cursection,
+					    $file_buffer->{'song'});
+	}
+
+	close FILE;
+
+	$track_no++;
+	$rog_filename = "$conv_filename$track_no.$output_ext";
+    }
+
+    print STDERR "\n";
+
+    # include any metadata passed in from previous plugins 
+    # note that this metadata is associated with the top level section
+    $self->extra_metadata ($doc_obj, $doc_obj->get_top_section(), $metadata);
+    # do plugin specific processing of doc_obj
+    unless (defined ($self->process(\$text, $pluginfo, $base_dir, $file, $metadata, $doc_obj))) {
+	print STDERR "<ProcessingError n='$file'>\n" if ($gli);
+	return -1;
+    }
+    # do any automatic metadata extraction
+    $self->auto_extract_metadata ($doc_obj);
+    # add an OID
+    $self->add_OID($doc_obj);
+
+    my $oid = $doc_obj->get_OID();
+    my $appletlink = "<a href=\"javascript:meldexout(\'$oid\','[TitleSafe]')\">";
+
+    $doc_obj->add_utf8_metadata ($topsection, "audiolink",  $appletlink); 
+    $doc_obj->add_utf8_metadata ($topsection, "audioicon",  "_iconaudio_"); 
+    $doc_obj->add_utf8_metadata ($topsection, "/audiolink", "</a>"); 
+
+    # if no title metadata defined, set it to filename minus extension
+    my $existing_title = $doc_obj->get_metadata_element($topsection,"Title");
+    if (!defined $existing_title) 
+    {
+	my $title = $doc_obj->get_metadata_element($topsection,"Source");
+	$title =~ s/\..*?$//g;
+	$doc_obj->add_utf8_metadata ($topsection, "Title", $title); 
+
+	my $title_safe = $title;
+	$title_safe =~ s/\'/\\\\&apos;/g;
+	$doc_obj->add_utf8_metadata ($topsection, "TitleSafe", $title_safe); 
+    }
+
+    # process the document
+    $processor->process($doc_obj);
+    $self->cleanup_tmp_area();
+
+    $self->{'num_processed'} ++;
+
+    return 1;
+}
+
+
+# do plugin specific processing of doc_obj for HTML type
+sub process_type {
+    my $self = shift (@_);
+    my ($doc_ext, $textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj) = @_;
+    
+    my $conv_filename = $self->{'conv_filename'};
+    my $tmp_dirname = File::Basename::dirname($conv_filename);
+    my $tmp_tailname = File::Basename::basename($conv_filename);
+    
+    my $converted_to = $self->{'converted_to'};
+    my $ret_val = 1;    
+
+#   $ret_val = &RogPlugin::process($self, $textref, $pluginfo,
+#				 $tmp_dirname, $tmp_tailname,
+#				 $metadata, $doc_obj);
+
+    # associate original file with doc object
+    my $cursection = $doc_obj->get_top_section();
+    my $filename = &util::filename_cat($base_dir, $file);
+    $doc_obj->associate_file($filename, "doc.$doc_ext", undef, $cursection);
+
+    my $doclink = "<a href=\"_httpprefix_/collect/[collection]/index/assoc/[archivedir]/doc.$doc_ext\">";
+    $doc_obj->add_utf8_metadata ($cursection, "srclink",  $doclink); 
+    $doc_obj->add_utf8_metadata ($cursection, "srcicon",  "_icon".$doc_ext."_"); 
+    $doc_obj->add_utf8_metadata ($cursection, "/srclink", "</a>"); 
+    return $ret_val;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/DSpacePlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/DSpacePlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/DSpacePlugin.pm	(revision 20131)
@@ -0,0 +1,411 @@
+
+###########################################################################
+#
+# DSpacePlugin.pm -- plugin for importing a collection from DSpace 
+# 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2004 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# This plugin takes "contents" and dublin_core.xml file, which contain 
+# Metadata and lists of associated files for a particular document
+# and produces a document containing sections, one for each page.
+# The files should be named "contents" and "dublin_core.xml".  For each of 
+# document in DSpace, it is stored in one directory
+#
+# The format of the "contents" file is as follows:
+# 
+# File.type      bundle:ORIGINAL
+# license.txt    bundle:LICENSE
+# The format of the "dublin_core.xml" file is as follows:
+# The first line contains any metadata for the whole document
+# <dublin_core>
+# eg.
+# <dcvalue element="Title" qualifier="">Snail farming</dcvalue>
+# <dcvalue element="date" qualifier="">2004-10-15</dcvalue>
+#
+
+package DSpacePlugin;
+
+use ReadTextFile;
+use plugin;
+use XMLParser;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @DSpacePlugin::ISA = ('ReadTextFile');
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "string",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" },
+      { 'name' => "only_first_doc",
+	'desc' => "{DSpacePlugin.only_first_doc}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "first_inorder_ext",
+	'desc' => "{DSpacePlugin.first_inorder_ext}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "first_inorder_mime",
+	'desc' => "{DSpacePlugin.first_inorder_mime}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "block_exp",
+	'desc' => "{BasePlugin.block_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_block_exp(),
+	'reqd' => "no" }];
+
+
+my $options = { 'name'     => "DSpacePlugin",
+		'desc'     => "{DSpacePlugin.desc}",
+		'inherits' => "yes",
+		'abstract' => "no",
+		'args'     => $arguments };
+
+
+my $primary_doc_lookup = { 'text/html' => '(?i)\.(gif|jpe?g|jpe|jpg|png|css)$' };
+
+# Important variation to regular plugin structure.  Need to declare
+# $self as global variable to file so XMLParser callback routines
+# can access the content of the object. 
+my ($self); 
+
+sub new {
+    my ($class) = shift (@_); 
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    $self = new ReadTextFile($pluginlist, $inputargs, $hashArgOptLists);
+    
+    if ($self->{'info_only'}) {
+	# don't worry about creating the XML parser as all we want is the 
+	# list of plugin options
+	return bless $self, $class;
+    }
+
+    #create XML::Parser object for parsing dublin_core.xml files
+    my $parser = new XML::Parser('Style' => 'Stream',
+				 'Handlers' => {'Char' => \&Char,
+						'Doctype' => \&Doctype
+						});
+    $self->{'parser'} = $parser;
+    $self->{'extra_blocks'} = {};
+
+    return bless $self, $class;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)(contents)$^;
+}
+
+# want to block all files except the "contents"
+sub get_default_block_exp {
+    my $self = shift (@_);
+    
+    # Block handle and txt files if present. Specifically don't block dublin_core xml
+    return q^(?i)(handle|\.tx?t)$^;
+}
+
+sub store_block_files_BACKUP
+{
+    # Option of making blocking sensitive to files that are in directory
+    # This subroutine is not currently used! (relies on default block expression stopping all handle and .txt files)
+
+    my $self =shift (@_);
+    my ($filename_full_path, $block_hash) = @_;
+
+    my ($tailname, $contents_basedir, $suffix) = &File::Basename::fileparse($filename_full_path, "\\.[^\\.]+\$");
+    my $handle_filename = &util::filename_cat($contents_basedir,"handle");
+
+    $block_hash->{'file_blocks'}->{$handle_filename} = 1 if (-e $handle_filename);
+}
+
+sub read_content
+{
+    my $self = shift (@_);
+    my ($dir, $only_first_doc, $first_inorder_ext, $first_inorder_mime, $mimetype_list) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my @fnamemime_list = ();
+    my @assocmime_list = ();
+
+    my $content_fname = &util::filename_cat($dir,"contents");
+
+    open(CIN,"<$content_fname") 
+	|| die "Unable to open $content_fname: $!\n";
+    
+    my $line;
+    my $pos = 0;
+
+    while (defined ($line = <CIN>)) {
+	if ($line =~ m/^(.*)\s+bundle:ORIGINAL\s*$/) {
+	    my $fname = $1;
+	    my $mtype = $mimetype_list->[$pos];
+	    my $fm_rec = { 'file' => $fname, 'mimetype' => $mtype};
+	    push(@fnamemime_list,$fm_rec);
+	    $pos++;
+	}
+    }
+    close CIN;
+
+    if ($only_first_doc){
+	my ($first_fname, @rest_fnames) = @fnamemime_list;
+	@fnamemime_list = ($first_fname);
+	@assocmime_list = @rest_fnames;
+    }
+
+    # allow user to specify the types of files (inorder)they would like to assign as
+    # a primary bitstream
+    if ($first_inorder_ext) {
+	# parse user-define file extension names
+	my @extfiles_list = split /,/, $first_inorder_ext;
+	my (@rest_fnames) = @fnamemime_list;
+	my @matched_list = ();
+	foreach my $file_ext (@extfiles_list) {
+	    $pos = 0;
+	    foreach my $allfiles (@fnamemime_list){
+		$allfiles->{'file'} =~ /^(.*)\.(.*?)$/;
+		my $allfiles_ext = $2;
+
+		if ($allfiles_ext =~ /$file_ext/) {
+		    print $outhandle "Existing file:$allfiles->{'file'} match the user-define File Extension:$file_ext\n";
+		    push (@matched_list, $allfiles);
+
+		    # delete the matched extension file from the array
+		    splice(@rest_fnames,$pos,1);
+
+		    return (\@matched_list, \@rest_fnames);
+
+		}
+		$pos++;
+	    }
+	}
+    }
+    
+    if ($first_inorder_mime) {
+	# parse user-define file mimetype
+	my @file_mime_list = split /,/, $first_inorder_mime;
+	my (@rest_fnames) = @fnamemime_list;
+	my @matched_list = ();
+	foreach my $file_mime (@file_mime_list) {
+	    $pos = 0;
+	    foreach my $allfiles (@fnamemime_list){
+		my $allfiles_mime = $allfiles->{'mimetype'};
+
+		if ($allfiles_mime =~ /$file_mime/) {
+		    print $outhandle "Existing file:$allfiles->{'file'} match the user-defined File MimeType:$file_mime\n";
+		    push (@matched_list, $allfiles);
+
+		    # delete the matched MIMEType file from the array
+		    splice(@rest_fnames,$pos,1);
+		    return (\@matched_list, \@rest_fnames);
+		}
+		$pos++;
+	    }
+	}
+    }
+    return (\@fnamemime_list, \@assocmime_list);
+}
+
+
+sub filemime_list_to_re
+{
+    my $self = shift (@_);
+    my ($fnamemime_list) = @_;
+
+    my @fname_list = map { "(".$_->{'file'}.")" } @$fnamemime_list;
+    my $fname_re = join("|",@fname_list);
+    $fname_re =~ s/\./\\\./g;
+
+    return $fname_re;
+}
+
+# Read dublin_core metadata from DSpace collection 
+sub metadata_read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, 
+	$extrametakeys, $extrametadata, $extrametafile,
+	$processor, $maxdocs, $gli) = @_;
+
+    my $only_first_doc = $self->{'only_first_doc'};
+    my $first_inorder_ext = $self->{'first_inorder_ext'};
+    my $first_inorder_mime = $self->{'first_inorder_mime'};
+    
+    my $outhandle = $self->{'outhandle'};
+    
+    my $filename = &util::filename_cat($base_dir, $file);
+    # return 0 if $self->{'block_exp'} ne "" && $filename =~ /$self->{'block_exp'}/;
+    
+    if ($filename !~ /dublin_core\.xml$/ || !-f $filename) {
+	return undef;
+    }
+    
+    print $outhandle "DSpacePlugin: extracting metadata from $file\n"
+	if $self->{'verbosity'} > 1;
+    
+    my ($dir) = $filename =~ /^(.*?)[^\/\\]*$/;
+
+    eval {
+	$self->{'parser'}->parsefile($filename);
+    };
+    
+    if ($@) {
+	die "DSpacePlugin: ERROR $filename is not a well formed dublin_core.xml file ($@)\n";
+    }
+
+    my $mimetype_list = $self->{'saved_metadata'}->{'dc.Format^mimetype'};
+    my ($doc_file_mimes, $assoc_file_mimes) = $self->read_content($dir, $only_first_doc, $first_inorder_ext, 
+								  $first_inorder_mime, $mimetype_list);
+
+    my $file_re = $self->filemime_list_to_re($doc_file_mimes);
+
+    if ($only_first_doc || $first_inorder_ext || $first_inorder_mime) {	
+	foreach my $afm ( @$assoc_file_mimes ) {
+ 	    my $full_af = &util::filename_cat($dir,$afm->{'file'});
+	    $self->{'extra_blocks'}->{$full_af} = 1;
+	}
+    }
+    push(@$extrametakeys,$file_re);
+
+    if (defined $self->{'saved_metadata'}->{'dc.Format^extent'}) {
+	delete $self->{'saved_metadata'}->{'dc.Format^extent'};
+    }
+
+    if (defined $mimetype_list) {
+	delete $self->{'saved_metadata'}->{'dc.Format^mimetype'};
+
+	# Temporarily store associate file info in metadata table
+	# This will be removed in 'extra_metadata' in BasePlugin and used
+	# to perform the actual file association (once the doc obj has
+	# been formed
+
+	my $main_doc = $doc_file_mimes->[0];
+	my $md_mimetype = $main_doc->{'mimetype'};
+
+	my $pd_lookup = $primary_doc_lookup->{$md_mimetype};
+
+	if (defined $pd_lookup) {
+	    my $filter_re = $pd_lookup;
+	    @$assoc_file_mimes = grep { $_->{'file'} !~ m/$filter_re/ }  @$assoc_file_mimes;
+	}
+
+	my @gsdlassocfile_tobe 
+	    = map { &util::filename_cat($dir,$_->{'file'}).":".$_->{'mimetype'}.":" } @$assoc_file_mimes;
+	$self->{'saved_metadata'}->{'gsdlassocfile_tobe'} = \@gsdlassocfile_tobe;
+
+    }
+    
+    $extrametadata->{$file_re} = $self->{'saved_metadata'};
+
+    return 1;
+}
+
+
+# The DSpacePlugin read() function. We are not actually reading any documents 
+# here, just blocking ones that have been processed by metadata read.
+#
+# Returns 0 for a file its blocking, undef for any other
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+    
+    # Block all files except contents
+    my $filename = &util::filename_cat($base_dir, $file);
+    return 0 if $self->{'block_exp'} ne "" && $filename =~ /$self->{'block_exp'}/;
+
+    my $assocfile = $metadata->{'assocfile'};
+
+    return 0 if (($filename =~ /dublin_core\.xml$/) || ($filename =~ /contents$/));
+    return 0 if (defined $self->{'extra_blocks'}->{$filename});
+    return undef;
+}
+
+sub Doctype {
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+
+    die if ($name !~ /^dublin_core$/);
+}
+
+sub StartTag {
+    my ($expat, $element) = @_;
+    if ($element eq "dublin_core") {
+	$self->{'saved_metadata'} = {};
+    } elsif ($element eq "dcvalue") {
+	my $metaname = $_{'element'};
+	my $qualifier = $_{'qualifier'}||"";
+	if ($metaname ne "description") {
+	    $metaname .= "^$qualifier" if ($qualifier ne "none" && $qualifier ne "");
+	    $self->{'metaname'} = "dc.\u$metaname";
+	}
+    }
+}
+
+sub EndTag {
+    my ($expat, $element) = @_;
+    
+    if ($element eq "dcvalue") {
+	$self->{'metaname'} = "";
+    }
+}
+
+sub Text {
+    if (defined ($self->{'metaname'}) && $self->{'metaname'} ne "") {
+	# $_ == Metadata content
+	my $mname = $self->{'metaname'};
+	if (defined $self->{'saved_metadata'}->{$mname}) {
+	    # accumulate - add value to existing value(s)
+	    if (ref ($self->{'saved_metadata'}->{$mname}) eq "ARRAY") {
+		push (@{$self->{'saved_metadata'}->{$mname}}, $_);
+	    } else {
+		$self->{'saved_metadata'}->{$mname} = 
+		    [$self->{'saved_metadata'}->{$mname}, $_];
+	    }
+	} else {
+	    # accumulate - add value into (currently empty) array
+	    $self->{'saved_metadata'}->{$mname} = [$_];
+	}
+
+    }
+}
+
+# This Char function overrides the one in XML::Parser::Stream to overcome a
+# problem where $expat->{Text} is treated as the return value, slowing
+# things down significantly in some cases.
+sub Char {
+    use bytes;  # Necessary to prevent encoding issues with XML::Parser 2.31+
+    $_[0]->{'Text'} .= $_[1];
+    return undef;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/DatabasePlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/DatabasePlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/DatabasePlugin.pm	(revision 20131)
@@ -0,0 +1,375 @@
+###########################################################################
+#
+# DatabasePlugin.pm -- plugin to import records from a database
+# 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2003 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# A plugin that imports records from a database. This uses perl's DBI module, 
+# which includes back-ends for mysql, postgresql, comma separated values (CSV),
+# MS Excel, ODBC, sybase, etc... Extra modules may need to be installed to 
+# use this. See <GSDLHOME>/etc/packages/example.dbi for an example config file.
+#
+
+# Written by John McPherson for the NZDL project
+# Mar, Apr 2003
+
+package DatabasePlugin;
+
+use strict;
+no strict 'refs'; # allow variable as a filehandle
+
+use AutoExtractMetadata;
+use unicode;
+
+sub BEGIN {
+    @DatabasePlugin::ISA = ('AutoExtractMetadata');
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" }];
+
+my $options = { 'name'     => "DatabasePlugin",
+		'desc'     => "{DatabasePlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new AutoExtractMetadata($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.dbi$^;
+}
+
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs,$total_count,$gli) = @_;
+        
+     #see if we can handle the passed file...
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+    
+    my $outhandle = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+
+    print STDERR "<Processing n='$file' p='DatabasePlugin'>\n" if ($gli);
+    print $outhandle "DatabasePlugin: processing $file\n" 
+	if $self->{'verbosity'} > 1;
+   
+    require DBI; # database independent stuff
+
+    # calculate the document hash, for document ids
+    my $hash="0";
+
+   
+    # default options - may be overridden by config file
+    my $language=undef;
+    my $encoding=undef;
+    my $dbplug_debug=0;
+    my $username='';
+    my $password='';
+
+    # these settings must be set by the config file:
+    my $db=undef;
+
+    # get id of pages from "nonempty", get latest version number from 
+    # "recent", and then get pagename from "page" and content from "version" !
+
+    my $sql_query_prime = undef ;
+    my $sql_query = undef ;
+
+    my %db_to_greenstone_fields=();
+    my %callbacks=();
+
+
+    # read in config file.
+    if (!open (CONF, $filename_full_path)) {
+	    print $outhandle "DatabasePlugin: can't read $filename_full_path: $!\n";
+	    return 0;
+    } 
+   
+    my $line;
+    my $statement="";
+    my $callback="";
+    while (defined($line=<CONF>)) {
+	chomp $line;
+	$line .= " "; # for multi-line statements - don't conjoin!
+	$line =~ s/\s*\#.*$//mg; # remove comments
+	$statement .= $line;
+
+	if ($line =~ /^\}\s*$/ && $callback) { # ends the callback
+	    $callback .= $statement ; $statement = "";
+	    # try to check that the function is "safe"
+	    if ($callback  =~ /\b(?:system|open|pipe|readpipe|qx|kill|eval|do|use|require|exec|fork)\b/ ||
+		$callback =~ /[\`]|\|\-/) {
+		# no backticks or functions that start new processes allowed
+		print $outhandle "DatabasePlugin: bad function in callback\n";
+		return 0;
+	    }
+	    $callback =~ s/sub (\w+?)_callback/sub/;
+	    my $fieldname = $1;
+	    my $ret = eval "\$callbacks{'$fieldname'} = $callback ; 1";
+	    if (!defined($ret)) {
+		print $outhandle "DatabasePlugin: error eval'ing callback: $@\n";
+		exit(1);
+	    }
+	    $callback="";
+	    print $outhandle "DatabasePlugin: callback registered for '$fieldname'\n"
+	        if $dbplug_debug;
+	} elsif ($callback) {
+	    # add this line to the callback function
+	    $callback .= $statement;
+	    $statement = "";
+	} elsif ($statement =~ m/;\s*$/) { # ends with ";"
+	    # check that it is safe
+	    # assignment
+	    if ($statement =~ m~(\$\w+)\s* = \s*
+		(\d		# digits
+		 | ".*?(?<!\\)" # " up to the next " not preceded by a \
+		 | '.*?(?<!\\)' # ' up to the next ' not preceded by a \
+		)\s*;~x ||      # /x means ignore comments and whitespace in rx
+		$statement =~ m~(\%\w+)\s*=\s*(\([\w\s\"\',:=>]+\))\s*;~ ) {   
+		# evaluate the assignment, return 1 on success "
+		if (!eval "$1=$2; 1") {
+		    my $err=$@;
+		    chomp $err;
+		    $err =~ s/\.$//; # remove a trailing .
+		    print $outhandle "DatabasePlugin: error evaluating `$statement'\n";
+		    print $outhandle " $err (in $filename_full_path)\n";
+		    return 0; # there was an error reading the config file
+		}
+	    } elsif ($statement =~ /sub \w+_callback/) {
+		# this is the start of a callback function definition
+		$callback = $statement;
+		$statement = "";
+	    } else {
+		print $outhandle "DatabasePlugin: skipping statement `$statement'\n";
+	    }
+	    $statement = "";
+	}
+    }
+    close CONF;
+
+    
+    if (!defined($db)) {
+	print $outhandle "DatabasePlugin: error: $filename_full_path does not specify a db!\n";
+	return 0;
+    }
+    if (!defined($sql_query)) {
+    	print $outhandle "DatabasePlugin: error: no SQL query specified!\n";
+	return 0;
+    }
+    # connect to database
+    my $dbhandle=DBI->connect($db, $username, $password);
+
+    if (!defined($dbhandle)) {
+	die "DatabasePlugin: could not connect to database, exiting.\n";
+    }
+    if (defined($dbplug_debug) && $dbplug_debug==1) {
+	print $outhandle "DatabasePlugin (debug): connected ok\n";
+    }
+
+    my $statement_hand;
+
+    # The user gave 2 sql statements to execute?
+    if ($sql_query_prime) {
+	    $statement_hand=$dbhandle->prepare($sql_query_prime);
+	    $statement_hand->execute;
+	    if ($statement_hand->err) {
+		    print $outhandle "Error: " . $statement_hand->errstr . "\n";
+		    return undef;
+	    }
+    }
+
+  
+    $statement_hand=$dbhandle->prepare($sql_query);
+    $statement_hand->execute;
+    if ($statement_hand->err) {
+    	print $outhandle "Error:" . $statement_hand->errstr . "\n";
+	return undef;
+    }
+
+    # get the array-ref for the field names and cast it to array
+    my @field_names;
+    @field_names=@{ $statement_hand->{NAME} };
+
+    foreach my $fieldname (@field_names) {
+	if (defined($db_to_greenstone_fields{$fieldname})) {
+	    if (defined($dbplug_debug) && $dbplug_debug==1) {
+		print $outhandle "DatabasePlugin (debug): mapping db field "
+		    . "'$fieldname' to "
+			. $db_to_greenstone_fields{$fieldname} . "\n";
+	    }
+	    $fieldname=$db_to_greenstone_fields{$fieldname};
+	}
+    }
+
+    # get rows
+
+    my $count = 0;
+    my @row_array;
+
+    @row_array=$statement_hand->fetchrow_array; # fetchrow_hashref?
+
+    my $base_oid = undef;
+    while (scalar(@row_array)) {
+	if (defined($dbplug_debug) && $dbplug_debug==1) {
+	    print $outhandle "DatabasePlugin (debug): retrieved a row from query\n";
+	}
+
+	# create a new document
+	my $doc_obj = new doc ($filename_full_path, "indexed_doc", $self->{'file_rename_method'});
+
+	my $cursection = $doc_obj->get_top_section();
+
+	# if $language not set in config file, will use BasePlugin's default
+	if (defined($language)) {
+	    $doc_obj->add_utf8_metadata($cursection, "Language", $language);
+	}
+	# if $encoding not set in config file, will use BasePlugin's default
+	if (defined($encoding)) {
+	    # allow some common aliases
+	    if ($encoding =~ m/^utf[-_]8$/i) {$encoding="utf8"}
+	    $encoding =~ s/-/_/g; # greenstone uses eg iso_8859_1
+	    $doc_obj->add_utf8_metadata($cursection, "Encoding", $encoding);
+	}
+	$self->set_Source_metadata($doc_obj, $db, $encoding);
+
+	if ($self->{'cover_image'}) {
+	    $self->associate_cover_image($doc_obj, $filename_full_path);
+	}
+	$doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");
+
+	$doc_obj->add_metadata($doc_obj->get_top_section(), "FileFormat", "DB");
+
+	# include any metadata passed in from previous plugins 
+	# note that this metadata is associated with the top level section
+	$self->extra_metadata ($doc_obj, $cursection,
+			       $metadata);
+
+	# do any automatic metadata extraction
+	$self->auto_extract_metadata ($doc_obj);
+
+	my $unique_id=undef;
+
+	foreach my $fieldname (@field_names) {
+	    my $fielddata=shift @row_array;
+
+	    if (! defined($fielddata) ) {
+	    	next; # this field was "" or NULL
+	    }
+	    # use the specified encoding, defaulting to utf-8
+	    if (defined($encoding) && $encoding ne "ascii"
+	    	&& $encoding ne "utf8") {
+	      $fielddata=&unicode::unicode2utf8(
+	      	&unicode::convert2unicode($encoding, \$fielddata)
+					       );
+	    }
+	    # see if we have a ****_callback() function defined
+	    if (exists $callbacks{$fieldname}) {
+		my $funcptr = $callbacks{$fieldname};
+		$fielddata = &$funcptr($fielddata);
+	    }
+
+	    if ($fieldname eq "text") {
+		# add as document text
+		$fielddata=~s@<@&lt;@g;
+		$fielddata=~s@>@&gt;@g; # for xml protection...
+		$fielddata=~s@_@\\_@g; # for macro language protection...
+		$doc_obj->add_utf8_text($cursection, $fielddata);
+	    } elsif ($fieldname eq "Identifier") {
+		# use as greenstone's unique record id
+		if ($fielddata =~ /^\d+$/) {
+		    # don't allow IDs that are completely numeric
+		    $unique_id="id" . $fielddata;
+		} else {
+		    $unique_id=$fielddata;
+		}
+	    } else {
+		# add as document metadata
+		$fielddata=~s/\[/&#91;/g;
+		$fielddata=~s/\]/&#93;/g;
+		$doc_obj->add_utf8_metadata($cursection,
+					    $fieldname, $fielddata);
+
+	    }
+	}
+
+
+	if (!defined $unique_id) {
+	    if (!defined $base_oid) {
+		$self->add_OID($doc_obj);
+		$base_oid = $doc_obj->get_OID(); 
+	    }
+	    $doc_obj->set_OID($base_oid."s$count");
+	} else {
+	    # use our id from the database...
+	    $doc_obj->set_OID($unique_id);
+	}
+
+
+        # process the document
+	$processor->process($doc_obj);
+
+	$count++;
+
+	# get next row
+	@row_array=$statement_hand->fetchrow_array; # fetchrow_hashref?
+    } # end of row_array is not empty
+
+    # check "$sth->err" if empty array for error
+    if ($statement_hand->err) {
+	print $outhandle "DatabasePlugin: received error: \"" .
+	    $statement_hand->errstr . "\"\n";
+    }
+
+    # clean up connection to database
+    $statement_hand->finish();
+    $dbhandle->disconnect();
+
+    # num of input files, rather than documents created?
+    $self->{'num_processed'}++;
+
+    if (defined($dbplug_debug) && $dbplug_debug==1) {
+        print $outhandle "DatabasePlugin: imported $count DB records as documents.\n";
+    }
+    $count;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/DateExtractor.pm
===================================================================
--- /gsdl/stable/perllib/plugins/DateExtractor.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/DateExtractor.pm	(revision 20131)
@@ -0,0 +1,104 @@
+###########################################################################
+#
+# DateExtractor - helper plugin that extracts historical dates from text
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2008 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package DateExtractor;
+
+use DateExtract;
+use PrintInfo;
+use strict;
+
+BEGIN {
+    @DateExtractor::ISA = ('PrintInfo');
+}
+
+my $arguments = [
+      { 'name' => "extract_historical_years",
+	'desc' => "{DateExtractor.extract_historical_years}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "maximum_year",
+	'desc' => "{DateExtractor.maximum_year}",
+	'type' => "int",
+	'deft' => (localtime)[5]+1900,
+	'char_length' => "4",
+	#'range' => "2,100",
+	'reqd' => "no"},
+      { 'name' => "maximum_century",
+	'desc' => "{DateExtractor.maximum_century}",
+	'type' => "string",
+	'deft' => "-1",
+	'reqd' => "no" },
+      { 'name' => "no_bibliography",
+	'desc' => "{DateExtractor.no_bibliography}",
+	'type' => "flag",
+	'reqd' => "no"},
+		 ];
+
+my $options = { 'name'     => "DateExtractor",
+		'desc'     => "{DateExtractor.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new PrintInfo($pluginlist, $inputargs, $hashArgOptLists, 1);
+
+    return bless $self, $class;
+
+}
+
+
+# extract metadata
+sub extract_date_metadata {
+
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+    
+    if($self->{'extract_historical_years'}) {
+	my $thissection = $doc_obj->get_top_section();
+	while (defined $thissection) {
+
+	    my $text = $doc_obj->get_text($thissection);
+	    &DateExtract::get_date_metadata($text, $doc_obj, 
+					    $thissection, 
+					    $self->{'no_bibliography'}, 
+					    $self->{'maximum_year'}, 
+					    $self->{'maximum_century'});
+	    $thissection = $doc_obj->get_next_section ($thissection);
+	}
+    }
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/DirectoryPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/DirectoryPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/DirectoryPlugin.pm	(revision 20131)
@@ -0,0 +1,645 @@
+###########################################################################
+#
+# DirectoryPlugin.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# DirectoryPlugin is a plugin which recurses through directories processing
+# each file it finds - which basically means passing it down the plugin 
+# pipeline
+
+package DirectoryPlugin;
+
+use PrintInfo;
+use plugin;
+use util;
+use metadatautil;
+
+use File::Basename;
+use strict;
+no strict 'refs';
+no strict 'subs';
+
+use Encode;
+
+BEGIN {
+    @DirectoryPlugin::ISA = ('PrintInfo');
+}
+
+my $arguments =
+    [ { 'name' => "block_exp",
+	'desc' => "{BasePlugin.block_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_block_exp(),
+	'reqd' => "no" },
+      # this option has been deprecated. leave it here for now so we can warn people not to use it
+      { 'name' => "use_metadata_files",
+	'desc' => "{DirectoryPlugin.use_metadata_files}",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" },
+      { 'name' => "recheck_directories",
+	'desc' => "{DirectoryPlugin.recheck_directories}",
+	'type' => "flag",
+	'reqd' => "no" } ];
+    
+my $options = { 'name'     => "DirectoryPlugin",
+		'desc'     => "{DirectoryPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new PrintInfo($pluginlist, $inputargs, $hashArgOptLists);
+    
+    if ($self->{'info_only'}) {
+	# don't worry about any options or initialisations etc
+	return bless $self, $class;
+    }
+
+    # we have left this option in so we can warn people who are still using it
+    if ($self->{'use_metadata_files'}) {
+	die "ERROR: DirectoryPlugin -use_metadata_files option has been deprecated. Please remove the option and add MetadataXMLPlug to your plugin list instead!\n";
+    }
+	
+    $self->{'num_processed'} = 0;
+    $self->{'num_not_processed'} = 0;
+    $self->{'num_blocked'} = 0;
+    $self->{'num_archives'} = 0;
+
+    $self->{'subdir_extrametakeys'} = {};
+
+    return bless $self, $class;
+}
+
+# called once, at the start of processing
+sub init {
+    my $self = shift (@_);
+    my ($verbosity, $outhandle, $failhandle) = @_;
+
+    # verbosity is passed through from the processor
+    $self->{'verbosity'} = $verbosity;
+
+    # as are the outhandle and failhandle
+    $self->{'outhandle'} = $outhandle if defined $outhandle;
+    $self->{'failhandle'} = $failhandle;
+
+}
+
+# called once, after all passes have finished
+sub deinit {
+    my ($self) = @_;
+
+}
+
+# called at the beginning of each plugin pass (import has one, building has many)
+sub begin {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $processor, $maxdocs) = @_;
+
+    my $proc_package_name = ref $processor;
+
+    if ($proc_package_name !~ /buildproc$/ && $self->{'incremental'} == 1) {
+
+	# Only lookup timestamp info for import.pl, and only if incremental is set
+
+	my $output_dir = $processor->getoutputdir();
+##	my $archives_inf = &util::filename_cat($output_dir,"archives.inf");
+	my $doc_db = "archiveinf-doc.gdb";
+    	my $archives_inf = &util::filename_cat($output_dir,$doc_db);
+
+	if ( -e $archives_inf ) {
+	    $self->{'inf_timestamp'} = -M $archives_inf;
+	}
+    }
+}
+
+# called at the end of each plugin pass
+sub end {
+    my ($self) = shift (@_);
+
+}
+
+
+# called if we are doing incremental building
+sub set_incremental {
+    my $self = shift(@_);
+    my ($incremental) = @_;
+
+    $self->{'incremental'} = $incremental;
+}
+
+# return 1 if this class might recurse using $pluginfo
+sub is_recursive {
+    my $self = shift (@_);
+    
+    return 1;
+}
+
+sub get_default_block_exp {
+    my $self = shift (@_);
+    
+    return '(?i)(CVS|\.svn|Thumbs\.db|OIDcount|~)$';
+}
+
+sub check_directory_path {
+
+    my $self = shift(@_);
+    my ($dirname) = @_;
+    
+    return undef unless (-d $dirname);
+
+    return 0 if ($self->{'block_exp'} ne "" && $dirname =~ /$self->{'block_exp'}/);
+
+    my $outhandle = $self->{'outhandle'};
+    
+    # check to make sure we're not reading the archives or index directory
+    my $gsdlhome = quotemeta($ENV{'GSDLHOME'});
+    if ($dirname =~ m/^$gsdlhome\/.*?\/import.*?\/(archives|index)$/) {
+	print $outhandle "DirectoryPlugin: $dirname appears to be a reference to a Greenstone collection, skipping.\n";
+        return 0;
+    }
+    
+    # check to see we haven't got a cyclic path...
+    if ($dirname =~ m%(/.*){,41}%) {
+	print $outhandle "DirectoryPlugin: $dirname is 40 directories deep, is this a recursive path? if not increase constant in DirectoryPlugin.pm.\n";
+	return 0;
+    }
+    
+    # check to see we haven't got a cyclic path...
+    if ($dirname =~ m%.*?import/(.+?)/import/\1.*%) {
+	print $outhandle "DirectoryPlugin: $dirname appears to be in a recursive loop...\n";
+	return 0;
+    }
+
+    return 1;
+}
+
+# this may be called more than once
+sub sort_out_associated_files {
+
+    my $self = shift (@_);
+    my ($block_hash) = @_;
+    if (!scalar (keys %{$block_hash->{'shared_fileroot'}})) {
+	return;
+    }
+
+    $self->{'assocfile_info'} = {} unless defined $self->{'assocfile_info'};
+    my $metadata = $self->{'assocfile_info'};
+    foreach my $prefix (keys %{$block_hash->{'shared_fileroot'}}) {
+	my $record = $block_hash->{'shared_fileroot'}->{$prefix};
+
+	my $tie_to = $record->{'tie_to'};
+	my $exts = $record->{'exts'};
+	
+	if ((defined $tie_to) && (scalar (keys %$exts) > 0)) {
+	    # set up fileblocks and assocfile_tobe
+	    my $base_file = "$prefix$tie_to";
+	    $metadata->{$base_file} = {} unless defined $metadata->{$base_file};
+	    my $base_file_metadata = $metadata->{$base_file};
+	    
+	    $base_file_metadata->{'gsdlassocfile_tobe'} = [] unless defined $base_file_metadata->{'gsdlassocfile_tobe'};
+	    my $assoc_tobe = $base_file_metadata->{'gsdlassocfile_tobe'};
+	    foreach my $e (keys %$exts) {
+		# block the file
+		$block_hash->{'file_blocks'}->{"$prefix$e"} = 1;
+		# set up as an associatd file
+		print STDERR "  $self->{'plugin_type'}: Associating $prefix$e with $tie_to version\n";
+		my $mime_type = ""; # let system auto detect this
+		push(@$assoc_tobe,"$prefix$e:$mime_type:"); 
+
+	    }
+	}
+    } # foreach record
+
+    $block_hash->{'shared_fileroot'} = undef;
+    $block_hash->{'shared_fileroot'} = {};
+
+}
+
+
+# do block exp OR special blocking ???
+
+sub file_is_blocked {
+    my $self = shift (@_);
+    my ($block_hash, $filename_full_path) = @_;
+
+    if (defined $block_hash->{'file_blocks'}->{$filename_full_path}) {
+	$self->{'num_blocked'} ++;
+	return 1;
+    }
+    # check Directory plugin's own block_exp 
+    if ($self->{'block_exp'} ne "" && $filename_full_path =~ /$self->{'block_exp'}/) {
+	$self->{'num_blocked'} ++;
+	return 1; # blocked
+    }
+    return 0;
+}
+
+
+
+sub file_block_read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $gli) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+    
+    # Calculate the directory name and ensure it is a directory and
+    # that it is not explicitly blocked.
+    my $dirname = $file;
+    $dirname = &util::filename_cat ($base_dir, $file) if $base_dir =~ /\w/;
+
+    my $directory_ok = $self->check_directory_path($dirname);
+    return $directory_ok unless (defined $directory_ok && $directory_ok == 1);
+
+    print $outhandle "Global file scan checking directory: $dirname\n";
+
+    $block_hash->{'all_files'} = {} unless defined $block_hash->{'all_files'};
+
+    $block_hash->{'file_blocks'} = {} unless defined $block_hash->{'file_blocks'};
+    $block_hash->{'shared_fileroot'} = {} unless defined $block_hash->{'shared_fileroot'};
+
+     # Recur over directory contents.
+    my (@dir, $subfile);
+    #my $count = 0;
+    
+    print $outhandle "DirectoryPlugin block: getting directory $dirname\n" if ($verbosity > 2);
+    
+    # find all the files in the directory
+    if (!opendir (DIR, $dirname)) {
+	if ($gli) {
+	    print STDERR "<ProcessingError n='$file' r='Could not read directory $dirname'>\n";
+	}
+	print $outhandle "DirectoryPlugin: WARNING - couldn't read directory $dirname\n";
+	return -1; # error in processing
+    }
+    @dir = readdir (DIR);
+    closedir (DIR);
+    
+    for (my $i = 0; $i < scalar(@dir); $i++) {
+	my $subfile = $dir[$i];
+	my $this_file_base_dir = $base_dir;
+	next if ($subfile =~ m/^\.\.?$/);
+
+	# Recursively read each $subfile
+	print $outhandle "DirectoryPlugin block recurring: $subfile\n" if ($verbosity > 2);
+	
+	#$count += &plugin::file_block_read ($pluginfo, $this_file_base_dir,
+	&plugin::file_block_read ($pluginfo, $this_file_base_dir,
+				  &util::filename_cat($file, $subfile),
+				  $block_hash, $metadata, $gli);
+	
+    }
+    $self->sort_out_associated_files($block_hash);
+    #return $count;
+    
+}
+
+# We don't do metadata_read
+sub metadata_read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, 
+	$extrametakeys, $extrametadata, $extrametafile,
+	$processor, $maxdocs, $gli) = @_;
+
+    return undef;
+}
+
+
+# return number of files processed, undef if can't process
+# Note that $base_dir might be "" and that $file might 
+# include directories
+
+# This function passes around metadata hash structures.  Metadata hash
+# structures are hashes that map from a (scalar) key (the metadata element
+# name) to either a scalar metadata value or a reference to an array of
+# such values.
+
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $in_metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+    
+    # Calculate the directory name and ensure it is a directory and
+    # that it is not explicitly blocked.
+    my $dirname;
+    if ($file eq "") {
+	$dirname = $base_dir;
+    } else {
+	$dirname = $file;
+	$dirname = &util::filename_cat ($base_dir, $file) if $base_dir =~ /\w/;
+    }
+
+    my $directory_ok = $self->check_directory_path($dirname);
+    return $directory_ok unless (defined $directory_ok && $directory_ok == 1);
+        
+    if (($verbosity > 2) && ((scalar keys %$in_metadata) > 0)) {
+        print $outhandle "DirectoryPlugin: metadata passed in: ", 
+	join(", ", keys %$in_metadata), "\n";
+    }
+    
+
+    # Recur over directory contents.
+    my (@dir, $subfile);
+    my $count = 0;
+    
+    print $outhandle "DirectoryPlugin read: getting directory $dirname\n" if ($verbosity > 2);
+    
+    # find all the files in the directory
+    if (!opendir (DIR, $dirname)) {
+	if ($gli) {
+	    print STDERR "<ProcessingError n='$file' r='Could not read directory $dirname'>\n";
+	}
+	print $outhandle "DirectoryPlugin: WARNING - couldn't read directory $dirname\n";
+	return -1; # error in processing
+    }
+    @dir = readdir (DIR);
+    closedir (DIR);
+
+    # Re-order the files in the list so any directories ending with .all are moved to the end
+    for (my $i = scalar(@dir) - 1; $i >= 0; $i--) {
+	if (-d &util::filename_cat($dirname, $dir[$i]) && $dir[$i] =~ /\.all$/) {
+	    push(@dir, splice(@dir, $i, 1));
+	}
+    }
+
+    # setup the metadata structures. we do a metadata_read pass to see if there is any additional metadata, then pass it to read
+    
+    my $additionalmetadata = 0;      # is there extra metadata available?
+    my %extrametadata;               # maps from filespec to extra metadata keys
+    my %extrametafile;               # maps from filespec to the metadata.xml (or similar) file it came from
+    my @extrametakeys;               # keys of %extrametadata in order read
+
+
+    my $os_dirsep = &util::get_os_dirsep();
+    my $dirsep    = &util::get_dirsep();
+    my $base_dir_regexp = $base_dir;
+    $base_dir_regexp =~ s/\//$os_dirsep/g;
+    my $local_dirname = $dirname;
+    $local_dirname =~ s/^$base_dir_regexp($os_dirsep)//;
+    $local_dirname .= $dirsep;
+    
+    if (defined $self->{'subdir_extrametakeys'}->{$local_dirname}) {
+	my $extrakeys = $self->{'subdir_extrametakeys'}->{$local_dirname};
+	foreach my $ek (@$extrakeys) {
+	    my $extrakeys_re  = $ek->{'re'};
+	    my $extrakeys_md  = $ek->{'md'};
+	    my $extrakeys_mf  = $ek->{'mf'};
+	    push(@extrametakeys,$extrakeys_re);
+	    $extrametadata{$extrakeys_re} = $extrakeys_md;
+	    $extrametafile{$extrakeys_re} = $extrakeys_mf;
+	}
+	delete($self->{'subdir_extrametakeys'}->{$local_dirname});
+    }
+    
+    # apply metadata pass for each of the files in the directory
+    my $num_files = scalar(@dir);
+    for (my $i = 0; $i < scalar(@dir); $i++) {
+	my $subfile = $dir[$i];
+	my $this_file_base_dir = $base_dir;
+	last if ($maxdocs != -1 && $count >= $maxdocs);
+	next if ($subfile =~ m/^\.\.?$/);
+	my $file_subfile = &util::filename_cat($file, $subfile);
+	my $full_filename = &util::filename_cat($this_file_base_dir, $file_subfile);
+	if ($self->file_is_blocked($block_hash,$full_filename)) {
+	    print STDERR "DirectoryPlugin: file $full_filename was blocked for metadata_read\n" if ($verbosity > 2);
+	    next;
+	}
+	
+	# Recursively read each $subfile
+	print $outhandle "DirectoryPlugin metadata recurring: $subfile\n" if ($verbosity > 2);
+	
+	$count += &plugin::metadata_read ($pluginfo, $this_file_base_dir,
+					  $file_subfile,$block_hash,
+					  \@extrametakeys, \%extrametadata,
+					  \%extrametafile,
+					  $processor, $maxdocs, $gli);
+	$additionalmetadata = 1;
+    }
+
+    # filter out any extrametakeys that mention subdirectories and store
+    # for later use (i.e. when that sub-directory is being processed)
+
+    foreach my $ek (@extrametakeys) {
+	my ($subdir_re,$extrakey_dir) = &File::Basename::fileparse($ek);
+	
+	$extrakey_dir =~ s/\\\./\./g; # remove RE syntax for .
+	$extrakey_dir =~ s/\\\\/\\/g; # remove RE syntax for \
+
+	my $dirsep_re = &util::get_re_dirsep();
+
+	my $ek_non_re = $ek;
+	$ek_non_re =~ s/\\\./\./g; # remove RE syntax for .
+	$ek_non_re =~ s/\\\\/\\/g; # remove RE syntax for \
+	if ($ek_non_re =~ m/$dirsep_re/) { # specifies at least one directory
+	    my $md = $extrametadata{$ek};
+	    my $mf = $extrametafile{$ek};
+
+	    my $subdir_extrametakeys = $self->{'subdir_extrametakeys'};
+
+	    my $subdir_rec = { 're' => $subdir_re, 'md' => $md, 'mf' => $mf };
+
+	    # when its looked up, it must be relative to the base dir
+	    push(@{$subdir_extrametakeys->{"$local_dirname$extrakey_dir"}},$subdir_rec);
+	    #push(@{$subdir_extrametakeys->{"$extrakey_dir"}},$subdir_rec);
+	}
+    }
+    
+    # import each of the files in the directory
+    $count=0;
+    for (my $i = 0; $i <= scalar(@dir); $i++) {
+	# When every file in the directory has been done, pause for a moment (figuratively!)
+	# If the -recheck_directories argument hasn't been provided, stop now (default)
+	# Otherwise, re-read the contents of the directory to check for new files
+	#   Any new files are added to the @dir list and are processed as normal
+	#   This is necessary when documents to be indexed are specified in bibliographic DBs
+	#   These files are copied/downloaded and stored in a new folder at import time
+	if ($i == $num_files) {
+	    last unless $self->{'recheck_directories'};
+
+	    # Re-read the files in the directory to see if there are any new files
+	    last if (!opendir (DIR, $dirname));
+	    my @dirnow = readdir (DIR);
+	    closedir (DIR);
+
+	    # We're only interested if there are more files than there were before
+	    last if (scalar(@dirnow) <= scalar(@dir));
+
+	    # Any new files are added to the end of @dir to get processed by the loop
+	    my $j;
+	    foreach my $subfilenow (@dirnow) {
+		for ($j = 0; $j < $num_files; $j++) {
+		    last if ($subfilenow eq $dir[$j]);
+		}
+		if ($j == $num_files) {
+		    # New file
+		    push(@dir, $subfilenow);
+		}
+	    }
+	    # When the new files have been processed, check again
+	    $num_files = scalar(@dir);
+	}
+
+	my $subfile = $dir[$i];
+	my $this_file_base_dir = $base_dir;
+	last if ($maxdocs != -1 && ($count + $total_count) >= $maxdocs);
+	next if ($subfile =~ /^\.\.?$/);
+
+	my $file_subfile = &util::filename_cat($file, $subfile);
+	my $full_filename 
+	    = &util::filename_cat($this_file_base_dir,$file_subfile);
+
+	if ($self->file_is_blocked($block_hash,$full_filename)) {
+	    print STDERR "DirectoryPlugin: file $full_filename was blocked for read\n" if ($verbosity > 2);
+	    next;
+	}
+	#print STDERR "processing $full_filename\n";
+	# Follow Windows shortcuts
+	if ($subfile =~ /(?i)\.lnk$/ && $ENV{'GSDLOS'} =~ /^windows$/i) {
+	    require Win32::Shortcut;
+	    my $shortcut = new Win32::Shortcut(&util::filename_cat($dirname, $subfile));
+	    if ($shortcut) {
+		# The file to be processed is now the target of the shortcut
+		$this_file_base_dir = "";
+		$file = "";
+		$subfile = $shortcut->Path;
+	    }
+	}
+
+	# check for a symlink pointing back to a leading directory
+	if (-d "$dirname/$subfile" && -l "$dirname/$subfile") {
+	    # readlink gives a "fatal error" on systems that don't implement
+	    # symlinks. This assumes the the -l test above would fail on those.
+	    my $linkdest=readlink "$dirname/$subfile";
+	    if (!defined ($linkdest)) {
+		# system error - file not found?
+		warn "DirectoryPlugin: symlink problem - $!";
+	    } else {
+		# see if link points to current or a parent directory
+		if ($linkdest =~ m@^[\./\\]+$@ ||
+		    index($dirname, $linkdest) != -1) {
+		    warn "DirectoryPlugin: Ignoring recursive symlink ($dirname/$subfile -> $linkdest)\n";
+		    next;
+		    ;
+		}
+	    }
+	}
+
+	print $outhandle "DirectoryPlugin: preparing metadata for $subfile\n" if ($verbosity > 2);
+
+	# Make a copy of $in_metadata to pass to $subfile
+	my $out_metadata = {};
+	&metadatautil::combine_metadata_structures($out_metadata, $in_metadata);
+
+	# check the assocfile_info
+	if (defined $self->{'assocfile_info'}->{$full_filename}) {
+	    &metadatautil::combine_metadata_structures($out_metadata, $self->{'assocfile_info'}->{$full_filename});
+	}
+        ## encode the filename as perl5 doesn't handle unicode filenames    
+       
+        my $tmpfile = Encode::encode_utf8($subfile); 
+	#print STDERR "subfile = $subfile, tmpfile = $tmpfile\n";
+	# Next add metadata read in XML files (if it is supplied)
+	if ($additionalmetadata == 1) {
+	    foreach my $filespec (@extrametakeys) {
+		
+		## use the utf8 encoded filename to do the filename comparison
+		if ($tmpfile =~ /^$filespec$/) {
+		    print $outhandle "File \"$subfile\" matches filespec \"$filespec\"\n" 
+			if ($verbosity > 2);
+		    my $mdref = $extrametadata{$filespec};
+		    my $mfref = $extrametafile{$filespec};
+
+		    # Add the list files where the metadata came from
+		    # into the metadata table so we can track this
+		    # This mechanism is similar to how gsdlassocfile works
+
+		    my @metafile_pair = ();
+		    foreach my $l (keys %$mfref) {
+			my $f = $mfref->{$l};
+			push (@metafile_pair, "$f : $l");
+		    }
+
+		    $mdref->{'gsdlmetafile'} = \@metafile_pair;
+
+		    &metadatautil::combine_metadata_structures($out_metadata, $mdref);
+		}
+	    }
+	}
+
+
+	if (defined $self->{'inf_timestamp'}) {
+	    # Look to see if it's a completely new file
+
+	    if (!$block_hash->{'new_files'}->{$full_filename}) {
+		# Not a new file, must be an existing file
+		# Let' see if it's newer than the last import.pl
+
+
+		if (! -d $full_filename) {
+		    if (!$block_hash->{'reindex_files'}->{$full_filename}) {
+			# filename has been around for longer than inf
+			print $outhandle "**** Skipping $subfile\n" if ($verbosity >3);
+			next;
+		    }
+		    else {
+			# Remove old folder in archives (might hash to something different)
+			# *** should be doing this on a Del one as well
+			# but leave folder name?? and ensure hashs to
+			# same again??
+
+			# Then let through as new doc??
+
+			# mark to doc-oids that rely on it for re-indexing
+			## &GDBMUtils::gdbmDatabase();
+		    }
+		}
+	    }
+	}
+
+	# Recursively read each $subfile
+	print $outhandle "DirectoryPlugin recurring: $subfile\n" if ($verbosity > 2);
+	
+	$count += &plugin::read ($pluginfo, $this_file_base_dir,
+				 $file_subfile, $block_hash,
+				 $out_metadata, $processor, $maxdocs, ($total_count + $count), $gli);
+    }
+
+    return $count;
+}
+
+sub compile_stats {
+    my $self = shift(@_);
+    my ($stats) = @_;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/EmailAddressExtractor.pm
===================================================================
--- /gsdl/stable/perllib/plugins/EmailAddressExtractor.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/EmailAddressExtractor.pm	(revision 20131)
@@ -0,0 +1,129 @@
+###########################################################################
+#
+# EmailAddressExtractor - helper plugin that extracts email addresses from text
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2008 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package EmailAddressExtractor;
+
+use PrintInfo;
+use strict;
+
+BEGIN {
+    @EmailAddressExtractor::ISA = ('PrintInfo');
+}
+
+my $arguments = [
+      { 'name' => "extract_email",
+	'desc' => "{EmailAddressExtractor.extract_email}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "new_extract_email",
+	'desc' => "",
+	'type' => "flag",
+	'reqd' => "no",
+	'hiddengli' => "yes" } 
+		 ];
+
+my $options = { 'name'     => "EmailAddressExtractor",
+		'desc'     => "{EmailAddressExtractor.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new PrintInfo($pluginlist, $inputargs, $hashArgOptLists, 1);
+
+    return bless $self, $class;
+
+}
+
+# extract metadata
+sub extract_email_metadata {
+
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+    
+    if ($self->{'extract_email'}) {
+	my $thissection = $doc_obj->get_top_section();
+	while (defined $thissection) {
+	    my $text = $doc_obj->get_text($thissection);
+	    $self->extract_email (\$text, $doc_obj, $thissection) if $text =~ /./;
+	    $thissection = $doc_obj->get_next_section ($thissection);
+	}
+    } 
+
+}
+
+sub extract_email {
+    my $self = shift (@_);
+    my ($textref, $doc_obj, $thissection) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    gsprintf($outhandle, " {EmailAddressExtractor.extracting_emails}...\n")
+	if ($self->{'verbosity'} > 2);
+    
+    my @email = ($$textref =~ m/([-a-z0-9\.@+_=]+@(?:[-a-z0-9]+\.)+(?:com|org|edu|mil|int|net|[a-z][a-z]))/g);
+    @email = sort @email;
+    
+#    if($self->{"new_extract_email"} == 0)
+#    {
+#    my @email2 = ();
+#    foreach my $address (@email) 
+#   {
+#	if (!(join(" ",@email2) =~ m/(^| )$address( |$)/ )) 
+#	    {
+#		push @email2, $address;
+#		$doc_obj->add_utf8_metadata ($thissection, "EmailAddress", $address);
+#		# print $outhandle "  extracting $address\n" 
+#		&gsprintf($outhandle, "  {AutoExtractMetadata.extracting} $address\n")
+#		    if ($self->{'verbosity'} > 3);
+#	    }
+#	}
+#    }
+#    else
+#    {
+    my $hashExistMail = {};
+    foreach my $address (@email) {
+	if (!(defined $hashExistMail->{$address}))
+	{
+	    $hashExistMail->{$address} = 1;
+	    $doc_obj->add_utf8_metadata ($thissection, "EmailAddress", $address);
+	    gsprintf($outhandle, "  {AutoExtractMetadata.extracting} $address\n")
+		if ($self->{'verbosity'} > 3);
+	}
+    }
+    gsprintf($outhandle, " {EmailAddressExtractor.done_email_extract}\n")
+	if ($self->{'verbosity'} > 2);
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/EmailPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/EmailPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/EmailPlugin.pm	(revision 20131)
@@ -0,0 +1,1213 @@
+###########################################################################
+#
+# EmailPlugin.pm - a plugin for parsing email files
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2002 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+
+# EmailPlugin
+#
+# by Gordon Paynter (gwp@cs.waikato.ac.nz)
+#
+# Email plug reads email files.  These are named with a simple
+# number (i.e. as they appear in maildir folders) or with the 
+# extension .mbx (for mbox mail file format)
+#
+# Document text:
+#   The document text consists of all the text 
+#   after the first blank line in the document.
+#
+# Metadata (not Dublin Core!):
+#   $Headers      All the header content (optional, not stored by default)
+#   $Subject      Subject: header
+#   $To           To: header
+#   $From         From: header
+#   $FromName     Name of sender (where available)
+#   $FromAddr     E-mail address of sender
+#   $DateText     Date: header
+#   $Date         Date: header in GSDL format (eg: 19990924)
+#
+#   $Title	  made up of Subject, Date and Sender (for default formatting)
+#   $InReplyTo    Message id of the one this replies to
+#
+# John McPherson - June/July 2001
+# added (basic) MIME support and quoted-printable and base64 decodings.
+# Minor fixes for names that are actually email addresses (ie <...> was lost)
+#
+# See:  * RFC 822  - ARPA Internet Text Messages
+#       * RFC 2045 - Multipurpose Internet Mail Extensions (MIME) -part1
+#       * RFC 2046 - MIME (part 2)  Media Types (and multipart messages)
+#       * RFC 2047 - MIME (part 3)  Message Header Extensions
+#       * RFC 1806 - Content Dispositions (ie inline/attachment)
+
+
+package EmailPlugin;
+
+use strict;
+no strict "refs"; # so we can use a variable as a filehandle for print $out
+
+
+use SplitTextFile;
+use unicode;  # gs conv functions
+use gsprintf 'gsprintf'; # translations
+
+use sorttools;
+use util;
+
+sub BEGIN {
+    @EmailPlugin::ISA = ('SplitTextFile');
+}
+
+my $extended_oidtype_list = 
+    [ {'name' => "message_id",
+       'desc' => "{EmailPlugin.OIDtype.message_id}" }
+      ];
+
+# add in all the standard options from BasePlugin
+unshift (@$extended_oidtype_list, @{$BasePlugin::oidtype_list});
+
+my $arguments = 
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() },
+      { 'name' => "no_attachments",
+	'desc' => "{EmailPlugin.no_attachments}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "headers",
+	'desc' => "{EmailPlugin.headers}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "OIDtype",
+	'desc' => "{import.OIDtype}",
+	'type' => "enum",
+	'list' => $extended_oidtype_list,
+	'deft' => "message_id",
+	'reqd' => "no" },
+      { 'name' => "OIDmetadata",
+	'desc' => "{import.OIDmetadata}",
+	'type' => "metadata",
+	'deft' => "dc.Identifier",
+	'reqd' => "no" },
+      { 'name' => "split_exp",
+	'desc' => "{EmailPlugin.split_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_split_exp() } 
+      ];
+
+my $options = { 'name'     => "EmailPlugin",
+		'desc'     => "{EmailPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new SplitTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    $self->{'assoc_filenames'} = {}; # to save attach names so we don't clobber
+    $self->{'tmp_file_paths'} = (); # list of tmp files to delete after processing is finished
+
+    # this might not actually be true at read-time, but after processing
+    # it should all be utf8.
+    $self->{'input_encoding'}="utf8";
+    return bless $self, $class;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+    # mbx/email for mailbox file format, \d+ for maildir (each message is
+    # in a separate file, with a unique number for filename)
+    # mozilla and IE will save individual mbx format files with a ".eml" ext.
+    return q@([\\/]\d+|\.(mbx|email|eml))$@;
+}
+
+# This plugin splits the mbox mail files at lines starting with From<sp>
+# It is supposed to be "\n\nFrom ", but this isn't always used.
+# add \d{4} so that the line ends in a year (in case the text has an
+# unescaped "From " at the start of a line).
+sub get_default_split_exp {
+    return q^\nFrom .*\d{4}\n^;
+    
+}
+
+sub can_process_this_file {
+    my $self = shift(@_);
+    my ($filename) = @_;
+
+    # avoid any confusion between filenames matching \d+ (which are by default
+    # matched by EmailPlugin) and directories that match \d+ (which should not)
+
+    return 0 if (-d $filename); 
+
+    if ($self->{'process_exp'} ne "" && $filename =~ /$self->{'process_exp'}/) {
+	return 1;
+    }
+    return 0;
+    
+}
+
+
+# do plugin specific processing of doc_obj
+sub process {
+
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    # Check that we're dealing with a valid mail file
+    # mbox message files start with "From "
+    # maildir messages usually start with Return-Path and Delivered-To
+    # mh is very similar to maildir
+    my $startoffile=substr($$textref,0,256);
+    if (($startoffile !~ /^(From )/) &&
+	($startoffile !~ /^(From|To|Envelope.*|Received|Return-Path|Date|Subject|Content\-.*|MIME-Version|Forwarded):/im)) {
+	return undef;
+    }
+
+    my $cursection = $doc_obj->get_top_section();
+
+    #
+    # Parse the document's text and extract metadata
+    #
+
+    # Protect backslashes
+    $$textref =~ s@\\@\\\\@g;
+
+    # Separate header from body of message
+    my $Headers = $$textref;
+    $Headers =~ s/\r?\n\r?\n(.*)$//s;
+    $$textref = $1;
+    $Headers .= "\n";
+    
+    # Unfold headers - see rfc822
+    $Headers =~ s/\r?\n[\t\ ]+/ /gs;
+    # Extract basic metadata from header
+    my @headers = ("From", "To", "Subject", "Date");
+    my %raw;
+    foreach my $name (@headers) {
+	$raw{$name} = "No $name value";
+    }
+
+    # Get a default encoding for the header - RFC says should be ascii...
+    my $default_header_encoding="iso_8859_1";
+
+    # We don't know what character set is the user's default...
+    # We could use textcat to guess... for now we'll look at mime content-type
+#    if ($Headers =~ /([[:^ascii:]])/) {
+#    }
+    if ($Headers =~ /^Content\-type:.*charset=\"?([a-z0-9\-_]+)/mi) {
+	$default_header_encoding=$1;
+	$default_header_encoding =~ s@\-@_@g;
+	$default_header_encoding =~ tr/A-Z/a-z/;
+    }
+
+
+    # Examine each line of the headers
+    my ($line, $name, $value);
+    my @parts;
+    foreach $line (split(/\n/, $Headers)) {
+	
+	# Ignore lines with no content or which begin with whitespace
+	next unless ($line =~ /:/);
+	next if ($line =~ /^\s/);
+
+	# Find out what metadata is on this line
+	@parts = split(/:/, $line);
+	$name = shift @parts;
+        # get fieldname in canonical form - first cap, then lower case.
+	$name =~ tr/A-Z/a-z/;
+        # uppercase the first character according to the current locale
+	$name=~s/(.+)/\u$1/;
+	next unless $name;
+	next unless ($raw{$name});
+
+	# Find the value of that metadata
+	$value = join(":", @parts);
+	$value =~ s/^\s+//;
+	$value =~ s/\s+$//;
+	# decode header values, using either =?<charset>?[BQ]?<data>?= (rfc2047) or default_header_encoding
+	$self->decode_header_value($default_header_encoding, \$value);
+	
+	# Store the metadata
+	$value =~ s@_@\\_@g; # protect against GS macro language
+	$raw{$name} = $value;
+    }
+
+    # Extract the name and e-mail address from the From metadata
+    my $frommeta = $raw{"From"};
+    my $fromnamemeta;
+    my $fromaddrmeta;
+
+    $frommeta =~ s/\s*$//;  # Remove trailing space, if any
+
+    if ($frommeta =~ m/(.+)\s*<(.+)>/) {
+	$fromnamemeta=$1;
+	$fromaddrmeta=$2;
+    } elsif ($frommeta =~ m/(.+@.+)\s+\((.*)\)/) {
+	$fromnamemeta=$2;
+	$fromaddrmeta=$1;
+    } elsif ($frommeta =~ m/(.+)\s+at\s+(.+)\s+\((.*)\)/) {
+	$fromnamemeta=$3;
+	$fromaddrmeta="$1&#64;$2";
+    }
+
+    if (!defined($fromaddrmeta)) {
+	$fromaddrmeta=$frommeta;
+    }
+    $fromaddrmeta=~s/<//; $fromaddrmeta=~s/>//;
+    # minor attempt to prevent spam-bots from harvesting addresses...
+    $fromaddrmeta=~s/@/&#64;/;
+
+    $doc_obj->add_utf8_metadata ($cursection, "FromAddr", $fromaddrmeta);
+
+    if (defined($fromnamemeta) && $fromnamemeta) { # must be > 0 long
+	$fromnamemeta =~ s/\"//g;  # remove quotes
+	$fromnamemeta =~ s/\s+$//; # remove trailing whitespace
+    }
+    else {
+	$fromnamemeta = $fromaddrmeta;
+    }
+    # if name is an address
+    $fromnamemeta =~ s/<//g; $fromnamemeta =~ s/>//g;
+    $fromnamemeta=~s/@/&#64\;/;
+    $doc_obj->add_utf8_metadata ($cursection, "FromName", $fromnamemeta);
+
+    $raw{"From"}=$frommeta;
+
+    # Process Date information
+    if ($raw{"Date"} !~ /No Date/) {
+	$raw{"DateText"} = $raw{"Date"};
+	
+	# Convert the date text to internal date format
+	$value = $raw{"Date"};
+	# proper mbox format: Tue, 07 Jan 2003 17:27:42 +1300
+	my ($day, $month, $year) = $value =~ /(\d?\d)\s([A-Z][a-z][a-z])\s(\d\d\d?\d?)/;
+	if (!defined($day) || !defined($month) || !defined ($year)) {
+	    # try monthly archive format: Wed Apr 23 00:26:08 2008
+	    ($month,$day, $year) = $value =~ /([A-Z][a-z][a-z])\s\s?(\d?\d)\s\d\d:\d\d:\d\d\s(\d\d\d\d)/;
+	}
+
+	# make some assumptions about the year formatting...
+	# some (old) software thinks 2001 is 101, some think 2001 is 01
+	if ($year < 20) { $year += 2000; } # assume not really 1920...
+	elsif ($year < 150) { $year += 1900; } # assume not really 2150...
+	$raw{"Date"} = &sorttools::format_date($day, $month, $year);
+	
+    } else {
+	# We have not extracted a date
+	$raw{"DateText"} = "Unknown.";
+	$raw{"Date"} = "19000000";
+    }
+
+    # Add extracted metadata to document object
+    foreach my $name (keys %raw) {
+	$value = $raw{$name};
+	if ($value) {
+	    # assume subject, etc headers have no special HTML meaning.
+	    $value = &text_into_html($value);
+	    # escape [] so it isn't re-interpreted as metadata
+	    $value =~ s/\[/&#91;/g; $value =~ s/\]/&#93;/g;
+	} else {
+	    $value = "No $name field";
+	}
+	$doc_obj->add_utf8_metadata ($cursection, $name, $value);
+    }
+
+
+    # extract a message ID from the headers, if there is one, and we'll use
+    # that as the greenstone doc ID. Having a predictable ID means we can
+    # link to other messages, eg from In-Reply-To or References headers...
+    if ($Headers =~ m@^Message-ID:(.+)$@mi) {
+	my $id=escape_msg_id($1);
+	$doc_obj->{'msgid'}=$id;
+    }
+    # link to another message, if this is a reply
+    if ($Headers =~ m@^In-Reply-To:(.+)$@mi) {
+	my $id=escape_msg_id($1);
+	$doc_obj->add_utf8_metadata ($cursection, 'InReplyTo', $id);
+    } elsif ($Headers =~ m@^References:.*\s([^\s]+)$@mi) {
+	# References can have multiple, get the last one
+	my $id=escape_msg_id($1);
+	# not necessarily in-reply-to, but same thread...
+	$doc_obj->add_utf8_metadata ($cursection, 'InReplyTo', $id);
+    }
+
+
+
+    my $mimetype="text/plain";
+    my $mimeinfo="";
+    my $charset = $default_header_encoding;
+    # Do MIME and encoding stuff. Allow \s in mimeinfo in case there is
+    # more than one parameter given to Content-type.
+    # eg: Content-type: text/plain; charset="us-ascii"; format="flowed"
+    if ($Headers =~ m@^content\-type:\s*([\w\.\-/]+)\s*(\;\s*.+)?\s*$@mi)
+	{
+	    $mimetype=$1;
+	    $mimetype =~ tr/[A-Z]/[a-z]/;
+
+	    if ($mimetype eq "text") { # for pre-RFC2045 messages (c. 1996)
+		$mimetype = "text/plain";
+	    }
+
+	    $mimeinfo=$2;
+	    if (!defined $mimeinfo) {
+		$mimeinfo="";
+	    } else { # strip leading and trailing stuff
+		$mimeinfo =~ s/^\;\s*//;
+		$mimeinfo =~ s/\s*$//;
+	    }
+	    if ($mimeinfo =~ /charset=\"([^\"]+)\"/i) {
+	      $charset = $1;
+	    }
+	}
+
+    my $transfer_encoding="7bit";
+    if ($Headers =~ /^content-transfer-encoding:\s*([^\s]+)\s*$/mi) {
+	$transfer_encoding=$1;
+    }
+
+    if ($mimetype eq "text/html") {
+	$$textref= $self->text_from_part($$textref, $Headers);
+    } elsif ($mimetype ne "text/plain") {
+	$self->{'doc_obj'} = $doc_obj; # in case we need to associate files...
+	$$textref=$self->text_from_mime_message($mimetype,$mimeinfo,$default_header_encoding,$$textref);
+    } else { # mimetype eq text/plain
+
+	if ($transfer_encoding =~ /quoted\-printable/) {
+	    $$textref=qp_decode($$textref);
+	} elsif ($transfer_encoding =~ /base64/) {
+	    $$textref=base64_decode($$textref);
+	}
+	$self->convert2unicode($charset, $textref);
+
+	$$textref = &text_into_html($$textref);
+	$$textref =~ s@_@\\_@g; # protect against GS macro language
+
+    }
+
+    
+    if ($self->{'headers'} && $self->{'headers'} == 1) {
+	# Add "All headers" metadata
+	$Headers = &text_into_html($Headers);
+
+	$Headers = "No headers" unless ($Headers =~ /\w/);
+	$Headers =~ s/@/&#64\;/g;
+	# escape [] so it isn't re-interpreted as metadata
+	$Headers =~ s/\[/&#91;/g; $Headers =~ s/\]/&#93;/g;
+	$self->convert2unicode($charset, \$Headers);
+
+	$Headers =~ s@_@\\_@g; # protect against GS macro language
+	$doc_obj->add_utf8_metadata ($cursection, "Headers", $Headers);
+    }
+
+
+    # Add Title metadata
+    my $Title = text_into_html($raw{'Subject'});
+    $Title .= "<br>From: " . text_into_html($fromnamemeta);
+    $Title .= "<br>Date: " . text_into_html($raw{'DateText'});
+    $Title =~ s/\[/&#91;/g; $Title =~ s/\]/&#93;/g;
+
+    $doc_obj->add_utf8_metadata ($cursection, "Title", $Title);
+	
+    # Add FileFormat metadata
+    $doc_obj->add_metadata($cursection, "FileFormat", "EMAIL");
+
+    # Add text to document object
+    $$textref = "No message" unless ($$textref =~ /\w/);
+
+    $doc_obj->add_utf8_text($cursection, $$textref);
+
+    return 1;
+}
+
+# delete any temp files that we have created
+sub clean_up_after_doc_obj_processing {
+    my $self = shift(@_);
+    
+    foreach my $tmp_file_path (@{$self->{'tmp_file_paths'}}) {
+        if (-e $tmp_file_path) {
+            &util::rm($tmp_file_path);
+        }
+    }
+    
+}
+
+# Convert a text string into HTML.
+#
+# The HTML is going to be inserted into a GML file, so 
+# we have to be careful not to use symbols like ">",
+# which ocurs frequently in email messages (and use
+# &gt instead.
+#
+# This function also turns links and email addresses into hyperlinks,
+# and replaces carriage returns with <BR> tags (and multiple carriage
+# returns with <P> tags).
+
+
+sub text_into_html {
+    my ($text) = @_;
+
+    # Convert problem characters into HTML symbols
+    $text =~ s/&/&amp;/g;
+    $text =~ s/</&lt;/g;
+    $text =~ s/>/&gt;/g;
+    $text =~ s/\"/&quot;/g;
+
+    # convert email addresses and URIs into links
+# don't markup email addresses for now
+#    $text =~ s/([\w\d\.\-]+@[\w\d\.\-]+)/<a href=\"mailto:$1\">$1<\/a>/g;
+
+    # try to munge email addresses a little bit...
+    $text =~ s/@/&#64;/;
+    # assume hostnames are \.\w\- only, then might have a trailing '/.*'
+    # assume URI doesn't finish with a '.'
+    $text =~ s@((http|ftp|https)://[\w\-]+(\.[\w\-]+)*/?((&amp;|\.|\%[a-f0-9]{2})?[\w\?\=\-_/~]+)*(\#[\w\.\-_]*)?)@<a href=\"$1\">$1<\/a>@gi;
+
+
+    # Clean up whitespace and convert \n charaters to <BR> or <P>
+    $text =~ s/ +/ /g;
+    $text =~ s/\s*$//g; 
+    $text =~ s/^\s*//g;
+    $text =~ s/\n/\n<br>/g;
+    $text =~ s/<br>\s*<br>/<p>/gi;
+
+    return $text;
+}
+
+
+
+
+#Process a MIME message.
+# the textref we are given DOES NOT include the header.
+sub text_from_mime_message {
+    my $self = shift(@_);
+    my ($mimetype,$mimeinfo,$default_header_encoding,$text)=(@_);
+    my $outhandle=$self->{'outhandle'};
+    # Check for multiparts - $mimeinfo will be a boundary
+    if ($mimetype =~ /multipart/) {
+	my $boundary="";
+	if ($mimeinfo =~ m@boundary=(\"[^\"]+\"|[^\s]+)\s*$@im) {
+	    $boundary=$1;
+	    if ($boundary =~ m@^\"@) {
+		$boundary =~ s@^\"@@; $boundary =~ s@\"$@@;
+	    }
+	} else {
+	    print $outhandle "EmailPlugin: (warning) couldn't parse MIME boundary\n";
+	}
+	# parts start with "--$boundary"
+	# message ends with "--$boundary--"
+	# RFC says boundary is <70 chars, [A-Za-z'()+_,-./:=?], so escape any
+	# that perl might want to interpolate. Also allows spaces...
+	$boundary=~s/\\/\\\\/g;
+	$boundary=~s/([\?\+\.\(\)\:\/\'])/\\$1/g;
+	my @message_parts = split("\r?\n\-\-$boundary", "\n$text");
+	# remove first "part" and last "part" (final --)
+	shift @message_parts;
+	my $last=pop @message_parts;
+	# if our boundaries are a bit dodgy and we only found 1 part...
+	if (!defined($last)) {$last="";}
+	# make sure it is only -- and whitespace
+	if ($last !~ /^\-\-\s*$/ms) {
+	    print $outhandle "EmailPlugin: (warning) last part of MIME message isn't empty\n";
+	}
+	foreach my $message_part (@message_parts) {
+	    # remove the leading newline left from split.
+	    $message_part=~s/^\r?\n//;
+	}
+	if ($mimetype eq "multipart/alternative") {
+	    # check for an HTML version first, then TEXT, otherwise use first.
+	    my $part_text="";
+	    foreach my $message_part (@message_parts) {
+		if ($message_part =~ m@^content\-type:\s*text/html@i)
+		{
+		    # Use the HTML version
+		    $part_text = $self->text_from_part($message_part);
+		    $mimetype="text/html";
+		    last;
+		}
+	    }
+	    if ($part_text eq "") { # try getting a text part instead
+		foreach my $message_part (@message_parts) {
+		    if ($message_part =~ m@^content\-type:\s*text/plain@i)
+		    {
+			# Use the plain version
+			$part_text = $self->text_from_part($message_part);
+			if ($part_text =~/[^\s]/) {
+			    $part_text = text_into_html($part_text);
+			}
+			$mimetype="text/plain";
+			last;
+		    }
+		}
+	    }
+	    if ($part_text eq "") { #use first part (no html/text part found)
+		$part_text = $self->text_from_part(shift @message_parts);
+		$part_text = text_into_html($part_text);
+	    }
+	    if ($part_text eq "") { # we couldn't get anything!!!
+		# or it was an empty message...
+		# do nothing...
+		gsprintf($outhandle, "{ReadTextFile.empty_file} - empty body?\n");
+	    } else {
+		$text = $part_text;
+	    }
+	} elsif ($mimetype =~ m@multipart/(mixed|digest|related|signed)@) {
+	    $text = "";
+	    # signed is for PGP/GPG messages... the last part is a hash
+	    if ($mimetype =~ m@multipart/signed@) {
+		pop @message_parts;
+	    }
+	    my $is_first_part=1;
+	    foreach my $message_part (@message_parts) {
+		if ($is_first_part && $text ne "") {$is_first_part=0;}
+
+		if ($mimetype eq "multipart/digest") {
+		    # default type - RTFRFC!! Set if not already set
+		    $message_part =~ m@^(.*)\n\r?\n@s;
+		    my $part_header=$1;
+		    if ($part_header !~ m@^content-type@mi) {
+			$message_part="Content-type: message/rfc822\n"
+			    . $message_part; # prepend default type
+		    }
+		}
+
+		$text .= $self->process_multipart_part($default_header_encoding,
+						       $message_part,
+						       $is_first_part);
+	    } # foreach message part.
+	} else {
+	    # we can't handle this multipart type (not mixed or alternative)
+	    # the RFC also mentions "parallel".
+	}
+    } # end of ($mimetype =~ multipart)
+    elsif ($mimetype =~ m@message/rfc822@) {
+	my $msg_header = $text;
+	$msg_header =~ s/\r?\n\r?\n(.*)$//s;
+	$text = $1;
+
+	if ($msg_header =~ /^content\-type:\s*([\w\.\-\/]+)\s*\;?\s*(.+?)\s*$/mi)
+	{
+	    $mimetype=$1;
+	    $mimeinfo=$2;
+	    $mimetype =~ tr/[A-Z]/[a-z]/;
+
+	    my $msg_text;
+	    if ($mimetype =~ m@multipart/@) {
+		$msg_text = $self->text_from_mime_message($mimetype, $mimeinfo,
+						   $default_header_encoding,
+						   $text);
+	    } else {
+		$msg_text=$self->text_from_part($text,$msg_header);
+	    }
+
+	    my $brief_header=text_into_html(get_brief_headers($msg_header));
+	    $text= "\n<b>&lt;&lt;attached message&gt;&gt;</b><br>";
+	    $text.= "<table><tr><td width=\"5%\"> </td>\n";
+	    $text.="<td>" . $brief_header . "\n</p>" . $msg_text 
+		. "</td></tr></table>";
+	}
+    } else {
+	# we don't do any processing of the content.
+    }
+
+    return $text;
+}
+
+
+
+# used for turning a message id into a more friendly string for greenstone
+sub escape_msg_id {
+#msgid
+    my $id=shift;
+    chomp $id; $id =~ s!\s!!g; # remove spaces
+    $id =~ s![<>\[\]]!!g; # remove [ ] < and >
+    $id =~ s![_&]!-!g; # replace symbols that might cause problems
+    $id =~ s!\.!-!g; # . means section to greenstone doc ids!
+    $id =~ s!@!-!g; # replace @ symbol, to avoid spambots
+    return $id;
+}
+
+
+
+sub process_multipart_part {
+    my $self = shift;
+    my $default_header_encoding = shift;
+    my $message_part = shift;
+    my $is_first_part = shift;
+
+    my $return_text="";
+    my $part_header=$message_part;
+    my $part_body;
+    if ($message_part=~ /^\s*\n/) {
+	# no header... use defaults
+	$part_body=$message_part;
+	$part_header="Content-type: text/plain; charset=us-ascii";
+    } elsif ($part_header=~s/\r?\n\r?\n(.*)$//s) {
+	$part_body=$1;
+    } else {
+	# something's gone wrong...
+	$part_header="";
+	$part_body=$message_part;
+    }
+    
+    $part_header =~ s/\r?\n[\t\ ]+/ /gs; #unfold
+    my $part_content_type="";
+    my $part_content_info="";
+
+    if ($part_header =~ m@^content\-type:\s*([\w\.\-/]+)\s*(\;.*)?$@mi) {
+	$part_content_type=$1; $part_content_type =~ tr/A-Z/a-z/;
+	$part_content_info=$2;
+	if (!defined($part_content_info)) {
+	    $part_content_info="";
+	} else {
+	    $part_content_info =~ s/^\;\s*//;
+	    $part_content_info =~ s/\s*$//;
+	}
+    }
+    my $filename="";
+    if ($part_header =~ m@name=\"?([^\"\n]+)\"?@mis) {
+	$filename=$1;
+	$filename =~ s@\r?\s*$@@; # remove trailing space, if any
+	# decode the filename
+	$self->decode_header_value($default_header_encoding, \$filename);
+
+    }
+    
+    # disposition - either inline or attachment.
+    # NOT CURRENTLY USED - we display all text types instead...
+    # $part_header =~ /^content\-disposition:\s*([\w+])/mis;
+    
+    # add <<attachment>> to each part except the first...
+    if (!$is_first_part) {
+	$return_text.="\n<p><hr><strong>&lt;&lt;attachment&gt;&gt;";
+	# add part info header
+	my $header_text = "<br>Type: $part_content_type<br>\n";
+	if ($filename ne "") {
+	    $header_text .= "Filename: $filename\n";
+	}
+	$header_text =~ s@_@\\_@g;
+	$return_text .= $header_text . "</strong></p>\n<p>\n";
+    }
+
+    if ($part_content_type =~ m@text/@)
+    {
+	# $message_part includes the mime part headers
+	my $part_text = $self->text_from_part($message_part);
+	if ($part_content_type !~ m@text/(ht|x)ml@) {
+	    $part_text = text_into_html($part_text);
+	}
+	if ($part_text eq "") {
+	    $part_text = ' ';
+	}
+	$return_text .= $part_text;
+    } elsif ($part_content_type =~ m@message/rfc822@) {
+	# This is a forwarded message
+	my $message_part_headers=$part_body;
+	$message_part_headers=~s/\r?\n\r?\n(.*)$//s;
+	my $message_part_body=$1;
+	$message_part_headers =~ s/\r?\n[\t\ ]+/ /gs; #unfold
+	
+	my $rfc822_formatted_body=""; # put result in here
+	if ($message_part_headers =~
+	    /^content\-type:\s*([\w\.\-\/]+)\s*(\;.*)?$/ims)
+	{
+	    # The message header uses MIME flags
+	    my $message_content_type=$1;
+	    my $message_content_info=$2;
+	    if (!defined($message_content_info)) {
+		$message_content_info="";
+	    } else {
+		$message_content_info =~ s/^\;\s*//;
+		$message_content_info =~ s/\s*$//;
+	    }
+	    $message_content_type =~ tr/A-Z/a-z/;
+	    if ($message_content_type =~ /multipart/) {
+		$rfc822_formatted_body=
+		    $self->text_from_mime_message($message_content_type,
+						  $message_content_info,
+						  $default_header_encoding,
+						  $message_part_body);
+	    } else {
+		$message_part_body=$self->text_from_part($part_body,
+							$message_part_headers);
+		$rfc822_formatted_body=text_into_html($message_part_body);
+	    }
+	} else {
+	    # message doesn't use MIME flags
+	    $rfc822_formatted_body=text_into_html($message_part_body);
+	    $rfc822_formatted_body =~ s@_@\\_@g;
+	}
+	# Add the returned text to the output
+	# don't put all the headers...
+#	$message_part_headers =~ s/^(X\-.*|received|message\-id|return\-path):.*\n//img;
+	my $brief_headers=get_brief_headers($message_part_headers);
+	$return_text.=text_into_html($brief_headers);
+	$return_text.="</p><p>\n";
+	$return_text.=$rfc822_formatted_body;
+	$return_text.="</p>\n";
+	# end of message/rfc822
+    } elsif ($part_content_type =~ /multipart/) { 
+	# recurse again
+	
+	my $tmptext= $self->text_from_mime_message($part_content_type,
+						   $part_content_info,
+						   $default_header_encoding,
+						   $part_body);
+	$return_text.=$tmptext;
+    } else {
+	# this part isn't text/* or another message...
+	if ($is_first_part) {
+	    # this is the first part of a multipart, or only part!
+	    $return_text="\n<p><hr><strong>&lt;&lt;attachment&gt;&gt;";
+	    # add part info header
+	    my $header_text="<br>Type: $part_content_type<br>\n";
+	    $header_text.="Filename: $filename</strong></p>\n<p>\n";
+	    $header_text =~ s@_@\\_@g;
+	    $return_text.=$header_text;
+	}
+	
+	# save attachment by default
+	if (!$self->{'no_attachments'}
+	    && $filename ne "") { # this part has a file...
+	    my $encoding="8bit";
+	    if ($part_header =~
+		/^content-transfer-encoding:\s*(\w+)/mi ) {
+		$encoding=$1; $encoding =~ tr/A-Z/a-z/;
+	    }
+	    my $tmpdir=&util::filename_cat($ENV{'GSDLHOME'}, "tmp");
+	    my $save_filename=$filename;
+	    
+	    # make sure we don't clobber files with same name;
+	    # need to keep state between .mbx files
+	    my $assoc_files=$self->{'assoc_filenames'};
+	    if ($assoc_files->{$filename}) { # it's been set...
+		$assoc_files->{$filename}++;
+		$filename =~ m/(.+)\.(\w+)$/;
+		my ($filestem, $ext)=($1,$2);
+		$save_filename="${filestem}_"
+		    . $assoc_files->{$filename} . ".$ext";
+	    } else { # first file with this name
+		$assoc_files->{$filename}=1;
+	    }
+	    my $tmp_filename = &util::filename_cat($tmpdir, $save_filename);
+	    open (SAVE, ">$tmp_filename") ||
+		warn "EMAILPlug: Can't save attachment as $tmp_filename: $!";
+	    binmode(SAVE); # needed on Windows
+	    my $part_text = $message_part;
+	    $part_text =~ s/(.*?)\r?\n\r?\n//s; # remove header
+	    if ($encoding eq "base64") {
+		print SAVE base64_decode($part_text);
+	    } elsif ($encoding eq "quoted-printable") {
+		print SAVE qp_decode($part_text);
+	    } else { # 7bit, 8bit, binary, etc...
+		print SAVE $part_text;
+	    }
+	    close SAVE;
+	    my $doc_obj=$self->{'doc_obj'};
+	    $doc_obj->associate_file("$tmp_filename",
+				     "$save_filename",
+				     $part_content_type # mimetype
+				     );
+	    # add this file to the list of tmp files for deleting later
+	    push(@{$self->{'tmp_file_paths'}}, $tmp_filename);
+
+	    my $outhandle=$self->{'outhandle'};
+	    print $outhandle "EmailPlugin: saving attachment \"$filename\"\n"; #
+	    
+	    # be nice if "download" was a translatable macro :(
+	    $return_text .="<a href=\"_httpdocimg_/$save_filename\">download</a>";
+	} # end of save attachment
+    } # end of !text/message part
+
+
+    return $return_text;
+}
+
+
+# Return only the "important" headers from a set of message headers
+sub get_brief_headers {
+    my $msg_header = shift;
+    my $brief_header = "";
+
+    # Order matters!
+    if ($msg_header =~ /^(From:.*)$/im) {$brief_header.="$1\n";}
+    if ($msg_header =~ /^(To:.*)$/im) {$brief_header.="$1\n";}
+    if ($msg_header =~ /^(Cc:.*)$/im) {$brief_header.="$1\n";}
+    if ($msg_header =~ /^(Subject:.*)$/im) {$brief_header.="$1\n";}
+    if ($msg_header =~ /^(Date:.*)$/im) {$brief_header.="$1\n";}
+
+    return $brief_header;
+}
+
+
+# Process a MIME part. Return "" if we can't decode it.
+# should only be called for parts with type "text/*" ?
+# Either pass the entire mime part (including the part's header),
+# or pass the mime part's text and optionally the part's header.
+sub text_from_part {
+    my $self = shift;
+    my $text = shift || '';
+    my $part_header = shift;
+
+
+    my $type="text/plain"; # default, overridden from part header
+    my $charset=undef;     # convert2unicode() will guess if necessary
+
+    if (! $part_header) { # no header argument was given. check the body
+	$part_header = $text;
+	# check for empty part header (leading blank line)
+	if ($text =~ /^\s*\r?\n/) {
+	    $part_header="Content-type: text/plain; charset=us-ascii";
+	} else {
+	    $part_header =~ s/\r?\n\r?\n(.*)$//s;
+	    $text=$1; if (!defined($text)) {$text="";}
+	}
+	$part_header =~ s/\r?\n[\t ]+/ /gs; #unfold
+    }
+
+    if ($part_header =~
+	/content\-type:\s*([\w\.\-\/]+).*?charset=\"?([^\;\"\s]+)\"?/is) {
+	$type=$1;
+	$charset=$2;
+    }
+    my $encoding="";
+    if ($part_header =~ /^content\-transfer\-encoding:\s*([^\s]+)/mis) {
+	$encoding=$1; $encoding=~tr/A-Z/a-z/;
+    }
+    # Content-Transfer-Encoding is per-part
+    if ($encoding ne "") {
+	if ($encoding =~ /quoted\-printable/) {
+	    $text=qp_decode($text);
+	} elsif ($encoding =~ /base64/) {
+	    $text=base64_decode($text);
+	} elsif ($encoding !~ /[78]bit/) { # leave 7/8 bit as is.
+	    # rfc2045 also allows binary, which we ignore (for now).
+	    my $outhandle=$self->{'outhandle'};
+	    print $outhandle "EmailPlugin: unknown transfer encoding: $encoding\n";
+	    return "";
+	}
+    }
+
+    if ($type eq "text/html") {
+	# only get stuff between <body> tags, or <html> tags.
+	$text =~ s@^.*<html[^>]*>@@is;
+	$text =~ s@</html>.*$@@is;
+	$text =~ s/^.*?<body[^>]*>//si;
+	$text =~ s/<\/body>.*$//si;
+    }
+    elsif ($type eq "text/xml") {
+	$text=~s/</&lt;/g;$text=~s/>/&gt;/g;
+	$text="<pre>\n$text\n</pre>\n";
+    }
+    # convert to unicode
+    $self->convert2unicode($charset, \$text);
+    $text =~ s@_@\\_@g; # protect against GS macro language
+    return $text;
+}
+
+
+
+
+# decode quoted-printable text
+sub qp_decode {
+    my $text=shift;
+
+    # if a line ends with "=\s*", it is a soft line break, otherwise
+    # keep in any newline characters.
+
+    $text =~ s/=\s*\r?\n//mg;
+    $text =~ s/=([0-9A-Fa-f]{2})/chr (hex "0x$1")/eg;
+    return $text;
+}
+
+# decode base64 text. This is fairly slow (since it's interpreted perl rather
+# than compiled XS stuff like in the ::MIME modules, but this is more portable
+# for us at least).
+# see rfc2045 for description, but basically, bits 7 and 8 are set to zero;
+# 4 bytes of encoded text become 3 bytes of binary - remove 2 highest bits
+# from each encoded byte.
+
+
+sub base64_decode {
+    my $enc_text = shift;
+# A=>0, B=>1, ..., '+'=>62, '/'=>63
+# also '=' is used for padding at the end, but we remove it anyway.
+    my $mimechars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+# map each MIME char into it's value, for more efficient lookup.
+    my %index;
+    map { $index{$_} = index ($mimechars, $_) } (split ('', $mimechars));
+# remove all non-base64 chars. eval to get variable in transliteration...
+# also remove '=' - we'll assume (!!) that there are no errors in the encoding
+    eval "\$enc_text =~ tr|$mimechars||cd";
+    my $decoded="";
+    while (length ($enc_text)>3)
+    { 
+	my $fourchars=substr($enc_text,0,4,"");
+	my @chars=(split '',$fourchars);
+	$decoded.=chr( $index{$chars[0]}        << 2 | $index{$chars[1]} >> 4);
+	$decoded.=chr( ($index{$chars[1]} & 15) << 4 | $index{$chars[2]} >> 2);
+	$decoded.=chr( ($index{$chars[2]} & 3 ) << 6 |  $index{$chars[3]});
+    } 
+# if there are any input chars left, there are either
+# 2 encoded bytes (-> 1 raw byte) left or 3 encoded (-> 2 raw) bytes left.
+    my @chars=(split '',$enc_text);
+    if (length($enc_text)) {
+	$decoded.=chr($index{$chars[0]} << 2 | (int $index{$chars[1]} >> 4));
+    } 
+    if (length($enc_text)==3) {
+	$decoded.=chr( ($index{$chars[1]} & 15) << 4 | $index{$chars[2]} >> 2);
+    }
+    return $decoded;
+}
+
+# returns 0 if valid utf-8, 1 if invalid
+sub is_utf8 {
+    my $self = shift;
+    my $textref = shift;
+
+    $$textref =~ m/^/g; # to set \G
+    my $badbytesfound=0;
+    while ($$textref =~ m!\G.*?([\x80-\xff]+)!sg) {
+	my $highbytes=$1;
+	my $highbyteslength=length($highbytes);
+	# replace any non utf8 complaint bytes
+	$highbytes =~ /^/g; # set pos()
+	while ($highbytes =~
+	       m!\G (?: [\xc0-\xdf][\x80-\xbf] | # 2 byte utf-8
+		     [\xe0-\xef][\x80-\xbf]{2} | # 3 byte
+		     [\xf0-\xf7][\x80-\xbf]{3} | # 4 byte
+		     [\xf8-\xfb][\x80-\xbf]{4} | # 5 byte
+		     [\xfc-\xfd][\x80-\xbf]{5}   # 6 byte
+		     )*([\x80-\xff])? !xg
+	       ) {
+	    my $badbyte=$1;
+	    if (!defined $badbyte) {next} # hit end of string
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+# words with non ascii characters in header values must be encoded in the 
+# following manner =?<charset>?[BQ]?<data>?= (rfc2047)
+
+sub decode_header_value {
+    my $self = shift(@_);
+    my ($default_header_encoding, $textref) = @_;
+    
+    if (!$$textref) {
+	# nothing to do!
+	return;
+    }
+    my $value = $$textref;
+    # decode headers if stored using =?<charset>?[BQ]?<data>?= (rfc2047)
+    if ($value =~ /=\?.*\?[BbQq]\?.*\?=/) {
+	my $original_value=$value;
+	my $encoded=$value;
+	$value="";
+	# we should ignore spaces between consecutive encoded-texts
+	$encoded =~ s@\?=\s+=\?@\?==\?@g;
+	while ($encoded =~ s/(.*?)=\?([^\?]*)\?([bq])\?([^\?]+)\?=//i) {
+	    my ($charset, $encoding, $data)=($2,$3,$4);
+	    my ($decoded_data);
+	    my $leading_chars = "$1";
+	    $self->convert2unicode($default_header_encoding, \$leading_chars);
+	    $value.=$leading_chars; 
+	    
+	    $data=~s/^\s*//; $data=~s/\s*$//; # strip whitespace from ends
+	    chomp $data;
+	    $encoding =~ tr/BQ/bq/;
+	    if ($encoding eq "q") { # quoted printable
+		$data =~ s/_/\ /g;  # from rfc2047 (sec 4.2.2)
+		$decoded_data=qp_decode($data);
+		# qp_decode adds \n, which is default for body text
+		chomp($decoded_data);
+	    } else { # base 64
+		$decoded_data=base64_decode($data);
+	    }
+	    $self->convert2unicode($charset, \$decoded_data);
+	    $value .= $decoded_data;
+	} # end of while loop
+	
+	# get any trailing characters
+	$self->convert2unicode($default_header_encoding, \$encoded);
+	$value.=$encoded;
+	
+	if ($value =~ /^\s*$/) { # we couldn't extract anything...
+	    $self->convert2unicode($default_header_encoding,
+				   \$original_value);
+	    $value=$original_value;
+	}
+	$$textref = $value;
+    } # end of if =?...?=
+    
+    # In the absense of other charset information, assume the
+    # header is the default (usually "iso_8859_1") and convert to unicode.
+    else {
+	$self->convert2unicode($default_header_encoding, $textref);
+    }   
+    
+}
+
+
+
+sub convert2unicode {
+  my $self = shift(@_);
+  my ($charset, $textref) = @_;
+
+  if (!$$textref) {
+      # nothing to do!
+      return;
+  }
+
+  if (! defined $charset) {
+      # check if we have valid utf-8
+      if ($self->is_utf8($textref)) { $charset = "utf8" }
+
+      # default to latin
+      $charset = "iso_8859_1" if ! defined($charset);
+  }
+
+  # first get our character encoding name in the right form.
+  $charset =~ tr/A-Z/a-z/; # lowercase
+  $charset =~ s/\-/_/g;
+  if ($charset =~ /gb_?2312/) { $charset="gb" }
+  # assumes EUC-KR, not ISO-2022 !?
+  $charset =~ s/^ks_c_5601_1987/korean/;
+  if ($charset eq 'utf_8') {$charset='utf8'}
+
+  my $outhandle = $self->{'outhandle'};
+
+  if ($charset eq "utf8") {
+      # no conversion needed, but lets check that it's valid utf8
+      # see utf-8 manpage for valid ranges
+      $$textref =~ m/^/g; # to set \G
+      my $badbytesfound=0;
+      while ($$textref =~ m!\G.*?([\x80-\xff]+)!sg) {
+	  my $highbytes=$1;
+	  my $highbyteslength=length($highbytes);
+	  # replace any non utf8 complaint bytes
+	  $highbytes =~ /^/g; # set pos()
+	  while ($highbytes =~
+		 m!\G (?: [\xc0-\xdf][\x80-\xbf] | # 2 byte utf-8
+		       [\xe0-\xef][\x80-\xbf]{2} | # 3 byte
+		       [\xf0-\xf7][\x80-\xbf]{3} | # 4 byte
+		       [\xf8-\xfb][\x80-\xbf]{4} | # 5 byte
+		       [\xfc-\xfd][\x80-\xbf]{5}   # 6 byte
+		       )*([\x80-\xff])? !xg
+		 ) {
+	      my $badbyte=$1;
+	      if (!defined $badbyte) {next} # hit end of string
+	      my $pos=pos($highbytes);
+	      substr($highbytes, $pos-1, 1, "\xc2\x80");
+	      # update the position to continue searching (for \G)
+	      pos($highbytes) = $pos+1; # set to just after the \x80
+	      $badbytesfound=1;
+	  }
+	  if ($badbytesfound==1) {
+	      # claims to be utf8, but it isn't!
+	      print $outhandle "EmailPlugin: Headers claim utf-8 but bad bytes "
+		  . "detected and removed.\n";
+
+	      my $replength=length($highbytes);
+	      my $textpos=pos($$textref);
+	      # replace bad bytes with good bytes
+	      substr( $$textref, $textpos-$replength,
+		      $replength, $highbytes);
+	      # update the position to continue searching (for \G)
+	      pos($$textref)=$textpos+($replength-$highbyteslength);
+	  }
+      }
+      return;
+  }
+
+  # It appears that we can't always trust ascii text so we'll treat it
+  # as iso-8859-1 (letting characters above 0x80 through without
+  # converting them to utf-8 will result in invalid XML documents
+  # which can't be parsed at build time).
+  $charset = "iso_8859_1" if ($charset eq "us_ascii" || $charset eq "ascii");
+
+  if ($charset eq "iso_8859_1") {
+      # test if the mailer lied, and it has win1252 chars in it...
+      # 1252 has characters between 0x80 and 0x9f, 8859-1 doesn't
+      if ($$textref =~ m/[\x80-\x9f]/) {
+	  print $outhandle "EmailPlugin: Headers claim ISO charset but MS ";
+	  print $outhandle "codepage 1252 detected.\n";
+	  $charset = "windows_1252";
+      }
+  }
+  my $utf8_text=&unicode::unicode2utf8(&unicode::convert2unicode($charset,$textref));
+
+  if ($utf8_text ne "") {
+      $$textref=$utf8_text;
+  } else {
+      # we didn't get any text... unsupported encoding perhaps? Or it is
+      # empty anyway. We'll try to continue, assuming 8859-1. We could strip
+      # characters out here if this causes problems...
+      my $outhandle=$self->{'outhandle'};
+      print $outhandle "EmailPlugin: falling back to iso-8859-1\n";
+      $$textref=&unicode::unicode2utf8(&unicode::convert2unicode("iso_8859_1",$textref));
+
+  }
+}
+
+sub get_base_OID {
+    my $self = shift(@_);
+    my ($doc_obj) = @_;
+
+    if ($self->{'OIDtype'} eq "message_id") {
+	# temporarily set OIDtype to hash to get a base id
+	$self->{'OIDtype'} = "hash_on_ga_xml";
+	my $id = $self->SUPER::get_base_OID(@_);
+	$self->{'OIDtype'} = "message_id";
+	return $id;
+    }
+    return $self->SUPER::get_base_OID(@_);
+}
+
+
+sub add_OID {
+    my $self = shift (@_);
+    my ($doc_obj, $id, $segment_number) = @_;
+    if ($self->{'OIDtype'} eq "message_id" && exists $doc_obj->{'msgid'} ) {
+	$doc_obj->set_OID($doc_obj->{'msgid'});
+    }
+    else {
+	$doc_obj->set_OID("$id\_$segment_number");
+    }
+}
+
+
+# Perl packages have to return true if they are run.
+1;
Index: /gsdl/stable/perllib/plugins/ExcelPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/ExcelPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/ExcelPlugin.pm	(revision 20131)
@@ -0,0 +1,121 @@
+###########################################################################
+#
+# ExcelPlugin.pm -- plugin for importing Microsoft Excel files.
+#  (currently only versions 95 and 97)
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2002 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package ExcelPlugin;
+
+use ConvertBinaryFile;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @ExcelPlugin::ISA = ('ConvertBinaryFile');
+}
+
+my $arguments = 
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() }
+      ];
+
+my $options = { 'name'     => "ExcelPlugin",
+		'desc'     => "{ExcelPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'srcreplaceable' => "yes", # Source docs in Excel format can be replaced with GS-generated html
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+    
+    my $self = new ConvertBinaryFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    $self->{'filename_extension'} = "xls";
+    $self->{'file_type'} = "Excel";
+
+    my $secondary_plugin_options = $self->{'secondary_plugin_options'};
+    if (!defined $secondary_plugin_options->{'HTMLPlugin'}) {
+	$secondary_plugin_options->{'HTMLPlugin'} = [];
+    }
+    if (!defined $secondary_plugin_options->{'TextPlugin'}) {
+	$secondary_plugin_options->{'TextPlugin'} = [];
+    }
+    my $html_options = $secondary_plugin_options->{'HTMLPlugin'};
+    my $text_options = $secondary_plugin_options->{'TextPlugin'};
+
+    push(@$html_options, "-input_encoding", "utf8");
+    push(@$html_options,"-extract_language") if $self->{'extract_language'};
+    push(@$html_options, "-file_rename_method", "none");
+    
+    push(@$text_options, "-input_encoding", "utf8");
+    push(@$text_options,"-extract_language") if $self->{'extract_language'};
+    push(@$text_options, "-file_rename_method", "none");
+
+    $self = bless $self, $class;
+    
+    $self->load_secondary_plugins($class,$secondary_plugin_options,$hashArgOptLists);
+    return bless $self;    
+}
+
+sub convert_post_process_old
+{
+    my $self = shift (@_);
+    my ($conv_filename) = @_;
+    
+    my $outhandle=$self->{'outhandle'};
+    
+    my ($language, $encoding) = $self->textcat_get_language_encoding ($conv_filename);
+    
+    # read in file ($text will be in utf8)
+    my $text = "";
+    $self->read_file ($conv_filename, $encoding, $language, \$text);
+    
+    # turn any high bytes that aren't valid utf-8 into utf-8.
+    #unicode::ensure_utf8(\$text);
+    
+    # Write it out again!
+    #$self->utf8_write_file (\$text, $conv_filename);
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+    return q^(?i)\.xls$^;
+}
+    
+
+1;
Index: /gsdl/stable/perllib/plugins/FOXPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/FOXPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/FOXPlugin.pm	(revision 20131)
@@ -0,0 +1,303 @@
+###########################################################################
+#
+# FOXPlugin.pm
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# plugin to process a Foxbase dbt file. This plugin provides the basic
+# functionality to read in the dbt and dbf files and process each record.
+# This general plugin should be overridden for a particular database to process
+# the appropriate fields in the file.
+
+package FOXPlugin;
+
+use BasePlugin;
+use util;
+use doc;
+use unicode;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+
+sub BEGIN {
+    @FOXPlugin::ISA = ('BasePlugin');
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() },
+      { 'name' => "block_exp",
+	'desc' => "{BasePlugin.block_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_block_exp() } ];
+
+my $options = { 'name'     => "FOXPlugin",
+		'desc'     => "{FOXPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.dbf$^;
+}
+
+#dbt files are processed at the same time as dbf files
+sub get_default_block_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.dbt$^;
+}
+
+# return number of files processed, undef if can't process
+# Note that $base_dir might be "" and that $file might 
+# include directories
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+ 
+    # can we process this file??
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+
+    print STDERR "<Processing n='$file' p='FOXPlugin'>\n" if ($gli);
+    print STDERR "FOXPlugin: processing $file\n" if $self->{'verbosity'} > 1;
+
+    my ($parent_dir) = $filename_full_path =~ /^(.*)\/[^\/]+\.dbf$/i;
+
+    # open the file
+    if (!open (FOXBASEIN, $filename_full_path)) {
+	if ($gli) {
+	    print STDERR "<ProcessingError n='$file' r='Could not read $filename_full_path'>\n";
+	}
+	print STDERR "FOXPlugin::read - couldn't read $filename_full_path\n";
+	return -1; # error in processing
+    }
+
+    # read in the database header
+    my ($temp, %dbf);
+    
+    # read in information about dbt file
+    if (read (FOXBASEIN, $temp, 32) < 32) {
+	if ($gli) {
+	    print STDERR "<ProcessingError n='$file' r='EOF while reading database header'>\n";
+	}
+	print STDERR "FOXPlugin::read - eof while reading database header\n";
+	close (FOXBASEIN);
+	return -1;
+    }
+    
+    # unpack the header
+    ($dbf{'hasdbt'},
+     $dbf{'modyear'}, $dbf{'modmonth'}, $dbf{'modday'},
+     $dbf{'numrecords'}, $dbf{'headerlen'}, 
+     $dbf{'recordlen'}) = unpack ("CCCCVvv", $temp);
+    
+    # process hasdbt
+    if ($dbf{'hasdbt'} == 131) {
+	$dbf{'hasdbt'} = 1;
+    } elsif ($dbf{'hasdbt'} == 3 || $dbf{'hasdbt'} == 48) {
+	$dbf{'hasdbt'} = 0;
+    } else {
+	if ($gli) {
+	    print STDERR "<ProcessingError n='$file' r='Does not seem to be a Foxbase file'>\n";
+	}
+	print STDERR "FOXPlugin:read - $filename_full_path doesn't seem to be a Foxbase file\n";
+	return -1;
+    }
+
+    # read in the field description
+    $dbf{'numfields'} = 0;
+    $dbf{'fieldinfo'} = [];
+    while (read (FOXBASEIN, $temp, 1) > 0) {
+	last if ($temp eq "\x0d");
+	last if (read (FOXBASEIN, $temp, 31, 1) < 31);
+
+	my %field = ();
+	$field{'name'} = $self->extracttext($temp, 11);
+	($field{'type'}, $field{'pos'}, $field{'len'}, $field{'dp'}) 
+	    = unpack ("x11a1VCC", $temp);
+
+	push (@{$dbf{'fieldinfo'}}, \%field);
+
+	$dbf{'numfields'} ++;
+    }
+
+    # open the dbt file if we need to
+    my $dbtfullname = $filename_full_path;
+    if ($filename_full_path =~ /f$/) {
+	$dbtfullname =~ s/f$/t/;
+    } else {
+	$dbtfullname =~ s/F$/T/;
+    }
+    if ($dbf{'hasdbt'} && !open (DBTIN, $dbtfullname)) {
+	if ($gli) {
+	    print STDERR "<ProcessingError n='$file' r='Could not read $dbtfullname'>\n";
+	}
+	print STDERR "FOXPlugin::read - couldn't read $dbtfullname\n";
+	close (FOXBASEIN);
+	return -1;
+    }
+
+    # read in and process each record in the database
+    my $numrecords = 0;
+    while (($numrecords < $dbf{'numrecords'}) && 
+	   (read (FOXBASEIN, $temp, $dbf{'recordlen'}) == $dbf{'recordlen'})) {
+
+	# create a new record
+	my $record = [];
+	
+	foreach my $field (@{$dbf{'fieldinfo'}}) {
+	    my $fieldvalue = "";
+	    
+	    if ($field->{'type'} eq "M" && $dbf{'hasdbt'}) {
+		# a memo field, look up this field in the dbt file
+		my $seekpos = substr ($temp, $field->{'pos'}, $field->{'len'});
+
+		$seekpos =~ s/^\s*//;
+		$seekpos = 0 unless $seekpos =~ /^\d+$/;
+		
+		$seekpos = $seekpos * 512;
+
+		if ($seekpos == 0) {
+		    # there is no memo field
+
+		} elsif (seek (DBTIN, $seekpos, 0)) {
+		    while (read (DBTIN, $fieldvalue, 512, length($fieldvalue)) > 0) {
+			last if ($fieldvalue =~ /\cZ/);
+		    }
+
+		    # remove everything after the control-Z
+		    substr($fieldvalue, index($fieldvalue, "\cZ")) = "";
+
+		} else {
+		    print STDERR "\nERROR - seek (to $seekpos) failed\n";
+		}
+
+	    } else {
+		# a normal field
+		$fieldvalue = substr ($temp, $field->{'pos'}, $field->{'len'});
+	    }
+
+	    push (@$record, {%$field, 'value'=>$fieldvalue});
+	}
+
+	# process this record
+	$self->process_record ($pluginfo, $base_dir, $file, $metadata, $processor, 
+			       $numrecords, $record);
+	
+	# finished another record...
+	$numrecords++;
+    }
+
+    # close the dbt file if we need to
+    if ($dbf{'hasdbt'}) {
+	close (DBTIN);
+    }
+
+    # close the dbf file
+    close (FOXBASEIN);
+
+    # finished processing
+    return 1;
+}
+
+
+# will extract a string from some larger string, making it
+# conform to a number of constraints
+sub extracttext {
+    my $self = shift (@_);
+    my ($text, $maxlen, $offset, $stopstr) = @_;
+    $offset = 0 unless defined $offset;
+    $stopstr = "\x00" unless defined $stopstr;
+    
+    # decide where the string finishes
+    my $end = index ($text, $stopstr, $offset);
+    $end = length ($text) if $end < 0;
+    $end = $offset+$maxlen if (defined $maxlen) && ($end-$offset > $maxlen);
+    
+    return "" if ($end <= $offset);
+    return substr ($text, $offset, $end-$offset);
+}
+
+
+# process_record should be overriden for a particular type
+# of database. This default version outputs an html document
+# containing all the fields in the record as a table.
+# It also assumes that the text is in utf-8.
+sub process_record {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $metadata, $processor, $numrecords, $record) = @_;
+
+    # create a new document
+    my $doc_obj = new doc ($file, "indexed_doc", $self->{'file_rename_method'});
+
+    $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");
+    my $section = $doc_obj->get_top_section();
+
+    $doc_obj->add_metadata($section, "FileFormat", "FOX");
+    $doc_obj->add_metadata($section, "FileSize",   (-s $file));
+
+    # start of document
+    $doc_obj->add_utf8_text($section, "<table>\n");
+
+    # add each field
+    foreach my $field (@$record) {
+	if (defined ($field->{'name'}) && defined ($field->{'value'})) {
+	    $doc_obj->add_utf8_text($section, "  <tr>\n");
+	    $doc_obj->add_utf8_text($section, "    <td>$field->{'name'}</td>\n");
+	    $doc_obj->add_utf8_text($section, "    <td>$field->{'value'}</td>\n");
+	    $doc_obj->add_utf8_text($section, "  </tr>\n");
+	}
+    }
+
+    # end of document
+    $doc_obj->add_utf8_text($section, "</table>\n");
+
+    # add an object id
+    $self->add_OID($doc_obj);
+
+    # process the document
+    $processor->process($doc_obj);
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/FavouritesPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/FavouritesPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/FavouritesPlugin.pm	(revision 20131)
@@ -0,0 +1,111 @@
+###########################################################################
+#
+# FavouritesPlug.pm -- Plugin for Internet Explorer Favourites files
+#                      By Stephen De Gabrielle
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2005 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+# hacked together by Stephen De Gabrielle from various plugins 
+# especially SRCPlug by John McPherson Nov 2000
+
+package FavouritesPlugin;
+
+use ReadTextFile;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @FavouritesPlugin::ISA = ('ReadTextFile');
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "FavouritesPlugin",
+		'desc'     => "{FavouritesPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift(@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new ReadTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+
+sub get_default_process_exp
+{
+    # URL is extension for single bookmarks under windows.
+    return q^(?i)\.URL$^;
+}
+
+
+# do plugin specific processing of doc_obj
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my $section = $doc_obj->get_top_section();
+
+    # don't want mg to turn escape chars into actual values
+    $$textref =~ s/\\/\\\\/g;
+
+    # use filename (minus the .url extension) as the title
+    my $title = $file;
+    $title =~ s/.url$//i;
+    $doc_obj->add_utf8_metadata($section, "Title", $title);
+
+    # get the URL from the file
+    my ($url) = ($$textref =~ m/^URL=(http.+)/mg);
+    $doc_obj->add_metadata($section, "URL", $url);
+
+    # Add srclink metadata for an automatic link to the webpage
+    $doc_obj->add_utf8_metadata($section, "srclink", "<a href=\"$url\">");
+    $doc_obj->add_utf8_metadata($section, "srcicon", "_iconworld_");
+    $doc_obj->add_utf8_metadata($section, "/srclink", "</a>");
+
+    # Tidy up the favourite text to look a bit nicer
+    $$textref =~ s/^\\n/<p>/g;
+    $$textref =~ s/\[/<p><strong>/g;
+    $$textref =~ s/\]/<\/strong><p>/g;
+    $$textref =~ s/^Modified=(.+)$/<strong>Modified<\/strong>$1<p>/g;
+    $doc_obj->add_utf8_text($section, "$$textref");
+
+    $doc_obj->add_metadata($section, "FileFormat", "Favourite");
+    return 1;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/GISExtractor.pm
===================================================================
--- /gsdl/stable/perllib/plugins/GISExtractor.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/GISExtractor.pm	(revision 20131)
@@ -0,0 +1,350 @@
+###########################################################################
+#
+# GISExtractor.pm -- extension base class to enhance plugins with GIS capabilities
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package GISExtractor;
+
+use PrintInfo;
+
+use util;
+
+use gsprintf 'gsprintf';
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+no strict 'subs';
+
+#field categories in DataBase files
+#$LAT = 3;
+#$LONG = 4;
+my $FC = 9;
+my $DSG = 10;
+#$CC1 = 12;
+my $FULL_NAME = 22;
+
+BEGIN {
+    @GISExtractor::ISA = ('PrintInfo');
+}
+
+
+my $arguments = 
+    [ { 'name' => "extract_placenames",
+	'desc' => "{GISExtractor.extract_placenames}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "gazetteer",
+	'desc' => "{GISExtractor.gazetteer}",
+	'type' => "string",
+	'reqd' => "no" },
+      { 'name' => "place_list",
+	'desc' => "{GISExtractor.place_list}",
+	'type' => "flag",
+	'reqd' => "no" } ];
+
+
+my $options = { 'name'     => "GISExtractor",
+		'desc'     => "{GISExtractor.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+		'args' => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    # can we indicate that these are not available if the map data is not there??
+    #if (has_mapdata()) {
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+    #}
+
+    my $self = new PrintInfo($pluginlist, $inputargs, $hashArgOptLists, 1);
+
+    return bless $self, $class;
+
+}
+
+sub initialise_gis_extractor {
+    my $self = shift (@_);
+
+    if ($self->{'extract_placenames'}) {
+	
+	my $outhandle = $self->{'outhandle'};
+	
+	my $places_ref 
+	    = $self->loadGISDatabase($outhandle,$self->{'gazetteer'});
+	
+	if (!defined $places_ref) {
+	    print $outhandle "Warning: Error loading mapdata gazetteer \"$self->{'gazetteer'}\"\n";
+	    print $outhandle "         No placename extraction will take place.\n";
+	    $self->{'extract_placenames'} = undef;
+	}
+	else {
+	    $self->{'places'} = $places_ref;
+	}
+    }
+    
+    
+}
+
+sub extract_gis_metadata
+{
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+    
+    if ($self->{'extract_placenames'}) {
+	my $thissection = $doc_obj->get_top_section();
+	while (defined $thissection) {
+	    my $text = $doc_obj->get_text($thissection);
+	    $self->extract_placenames (\$text, $doc_obj, $thissection) if $text =~ /./;
+	    $thissection = $doc_obj->get_next_section ($thissection);
+	}
+    } 
+
+}
+
+sub has_mapdata
+{
+    my $db_dir = &util::filename_cat($ENV{'GSDLHOME'}, "lamp", "data");
+    return ( -d $db_dir );
+}
+
+
+#returns a hash table of names from database files (specified in collect.cfg). 
+sub loadGISDatabase {
+    my $self = shift (@_);
+    my ($outhandle,$datasets) = @_;
+    my @dbase = map{$_ = $_ . ".txt";} split(/,/, $datasets);
+    if(scalar(@dbase)==0) { #default is to include all databases
+	@dbase=("UK.txt", "NZ.txt", "NF.txt", "CA.txt", "AS.txt", "GM.txt", "BE.txt", "IN.txt", "JA.txt", "USA.txt");
+    }
+    my $counter=0;
+    my %places = ();
+    my @cats = ();	
+    while($counter <= $#dbase){ #loop through all the databases
+	my $folder = $dbase[$counter];
+	$folder =~ s/(.*?)\.txt/$1/;
+####		my $dbName = &util::filename_cat($ENV{'GSDLHOME'}, "etc", "mapdata", "data", $folder, $dbase[$counter]);
+	my $dbName = &util::filename_cat($ENV{'GSDLHOME'}, "lamp", "data", $folder, $dbase[$counter]);
+	if (!open(FILEIN, "<$dbName")) {
+	    print $outhandle "Unable to open database $dbName: $!\n";
+	    return undef;
+	}
+	
+	my $line = <FILEIN>; #database category details.
+	my @catdetails = split("\t", $line);
+	
+	while ( defined($line = <FILEIN>)){ #stores all place names in file as keys in hash array %places
+	    @cats = split("\t", $line);
+	    if( #eliminating "bad" place names without missing real ones
+		($cats[$FC] eq "A" && !($cats[$DSG] =~ /ADMD|ADM2|PRSH/))
+		||($cats[$FC] eq "P" && ($cats[$DSG] =~ /PPLA|PPLC|PPLS/)) 
+		||($cats[$FC] eq "H" && ($cats[$DSG] =~ /BAY|LK/)) 
+		||($cats[$FC] eq "L" && !($cats[$DSG] =~ /LCTY|RGN/)) 
+		||($cats[$FC] eq "T" && ($cats[$DSG] =~ /CAPE|ISL|GRGE/))
+		||($dbase[$counter] eq "USA.txt" && ($cats[$DSG] =~ /ppl|island/))
+		){$places{$cats[$FULL_NAME]} = [@cats];}
+			@cats = ();	
+	}	
+	close(FILEIN);
+	$counter++;	
+    }	
+    return \%places;
+}
+
+#returns a unique hash array of all the places found in a document, along with coordinates, description and country data
+sub getPlaces {
+    my $self = shift @_;
+
+    my ($textref, $places) = @_;
+	my %tempPlaces = ();	
+	
+	foreach my $plc (%$places){ #search for an occurrence of each place in the text
+		if($$textref =~ m/(\W)$plc(\W)/){
+			$tempPlaces{$plc} = $places->{$plc};
+		}
+	}
+	#make sure each place is only there once
+	my %uniquePlaces = ();
+	foreach my $p (keys %tempPlaces) {	
+		if(!defined($uniquePlaces{$p})){
+			$uniquePlaces{$p} = $tempPlaces{$p};
+		}
+	}
+	return \%uniquePlaces;
+}
+
+
+
+
+#returns a lowercase version of the place, with no spaces
+sub placename_to_anchorname {
+    my $self = shift (@_);
+    my ($placename) = @_;
+    my $p_tag = lc($placename);
+    $p_tag =~ s/\s+//g;
+    return $p_tag;
+}
+
+#takes a place from the text and wraps an anchor tag, a hyperlink tag and an image tag around it
+sub anchor_wrapper {
+	my ($p, $p_counter_ref, $path) = @_;
+	my $image = "/gsdlgis/gisimages/nextplace.gif";
+	my $endTag = "</a>";
+	my $hrefTag = "<a href=";
+	$$p_counter_ref++;
+	my $next = $$p_counter_ref + 1;
+	my $p_tag = placename_to_anchorname($p);
+	my $place_anchor = "<a name=\"" . $p_tag . $$p_counter_ref . "\">" . $endTag; 
+	my $popup_anchor = $hrefTag . "'" . $path . "'>" . $p . $endTag;
+	my $image_anchor = $hrefTag . "#" . $p_tag . $next . "><img src=\"" . $image . "\" name=\"img" . $p_tag . $$p_counter_ref . "\" border=\"0\">" . $endTag;
+	return $place_anchor . $popup_anchor . $image_anchor;
+}
+
+#takes dangerous place names and checks if they are part of another placename or not.
+sub place_name_check {
+	my ($pre, $preSpace, $p, $postSpace, $post, $p_counter_ref, $path, $y) = @_;
+	if($pre =~ /$y/ || $post =~ /$y/) {return $pre . $preSpace . $p . $postSpace . $post;}
+	$pre = $pre . $preSpace;
+	$post = $postSpace . $post;
+	return $pre . &anchor_wrapper("", $p, "", $p_counter_ref, $path) . $post;
+}
+
+sub extract_placenames {
+    my $self = shift (@_);
+    my ($textref, $doc_obj, $thissection) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my $GSDLHOME = $ENV{'GSDLHOME'};
+    #field categories in DataBase file for extract_placenames.
+    my $LAT = 3;
+    my $LONG = 4;
+    my $CC1 = 12;
+
+    
+    &gsprintf($outhandle, " {GISExtractor.extracting_placenames}...\n")
+	if ($self->{'verbosity'} > 2);
+
+    #get all the places found in the document	
+    my $uniquePlaces = $self->getPlaces($textref, $self->{'places'});
+       
+    #finds 'dangerous' placenames (eg York and New York). Dangerous because program will find "York" within "New York"  
+    my %danger = ();    
+    foreach my $x (keys %$uniquePlaces){
+	foreach my $y (keys %$uniquePlaces){
+		if(($y =~ m/ /) && ($y =~ m/$x/) && ($y ne $x)){
+			$y =~ s/($x\s)|(\s$x)//;
+			$danger{$x} = $y;
+		}
+	}
+    }  
+      
+    #creates a list of clickable placenames at top of page, linked to first occurrence of name, and reads them into a file 
+    my $tempfname = $doc_obj;
+    $tempfname =~ s/.*\(0x(.*)\)/$1/;
+    my $names = "";
+    my $filename = "tmpfile" . $tempfname;
+    my $tempfile = &util::filename_cat($GSDLHOME, "tmp", $filename);
+    open(FOUT, ">$tempfile") || die "Unable to create a temp file: $!";	
+    foreach my $name (sort (keys %$uniquePlaces)){
+	if(!defined($danger{$name})){
+		my $name_tag = placename_to_anchorname($name);
+		print FOUT "$name\t" . $uniquePlaces->{$name}->[$LONG] . "\t" . $uniquePlaces->{$name}->[$LAT] . "\n";
+		if($self->{'place_list'}) {$names = $names . "<a href=\"#" . $name_tag . "1\">" . $name . "</a>" . "\n";}
+	}
+    }
+    close(FOUT);
+    $doc_obj->associate_file($tempfile, "places.txt", "text/plain");
+    $self->{'places_filename'} = $tempfile;
+    
+    my %countries = ();
+    
+    foreach my $p (keys %$uniquePlaces){
+	my $place = $p;
+	$place =~ s/\s+|\n+|\r+|\t+/(\\s+)/g;
+	my $cap_place = uc($place);	
+	my $long = $uniquePlaces->{$p}->[$LONG];
+	my $lat = $uniquePlaces->{$p}->[$LAT];
+	my $country = $uniquePlaces->{$p}->[$CC1];
+	my $path = "javascript:popUp(\"$long\",\"$lat\",\"$p\",\"$country\")";
+	my $p_counter = 0;
+	
+	if(!defined($danger{$p})){	
+		#adds html tags to each place name
+		$$textref =~ s/\b($place|$cap_place)\b/&anchor_wrapper($1,\$p_counter,$path)/sge;
+	} 
+	#else {
+	#$y = $danger{$p};
+	#$$textref =~ s/(\w+)(\s+?)($place|$cap_place)(\s+?)(\w+)/&place_name_check($1,$2,$3,$4,$5,\$p_counter,$path, $y)/sge;  
+	#}
+	
+	#edits the last place's image, and removes image if place only occurres once.
+	my $p_tag = placename_to_anchorname($p);
+	$p_counter++;
+	$$textref =~ s/#$p_tag$p_counter(><img src="\/gsdl\/images\/)nextplace.gif/#${p_tag}1$1firstplace.gif/;
+	$$textref =~ s/<img src="\/gsdl\/images\/firstplace.gif" name="img$p_tag(1)" border="0">//;
+	
+	#this line removes apostrophes from placenames (they break the javascript function)
+	$$textref =~ s/(javascript:popUp.*?)(\w)'(\w)/$1$2$3/g; #' (to get emacs colours back)
+		
+	#for displaying map of document, count num of places from each country
+	if(defined($countries{$country})){$countries{$country}++;}
+	else{$countries{$country} = 1;}
+
+	#adds placename to metadata
+	$doc_obj->add_utf8_metadata ($thissection, "Placename", $p);	
+	&gsprintf($outhandle, "  {AutoExtractMetadata.extracting} $p\n")
+		if ($self->{'verbosity'} > 3); 
+    }
+    #finding the country that most places are from, in order to display map of the document
+    my $max = 0;
+    my $CNTRY = "";
+    foreach my $c_key (keys %countries){
+	if($countries{$c_key} > $max){
+		$max = $countries{$c_key};
+		$CNTRY = $c_key;
+	}
+    }
+    #allows user to view map with all places from the document on it
+####    my $places_filename = &util::filename_cat($GSDLHOME, "collect", "_cgiargc_", "index", "assoc", "_thisOID_", "places.txt");
+    my $places_filename = &util::filename_cat("collect", "_cgiargc_", "index", "assoc", "_thisOID_", "places.txt");
+    my $docmap = "<a href='javascript:popUp(\"$CNTRY\",\"$places_filename\")'>View map for this document<\/a><br><br>\n";
+    $$textref = $docmap . $names . "<br>" . $$textref;
+    
+    $doc_obj->delete_text($thissection);
+    $doc_obj->add_utf8_text($thissection, $$textref);
+    &gsprintf($outhandle, " {GISExtractor.done_places_extract}\n")
+	if ($self->{'verbosity'} > 2);
+}
+
+sub clean_up_temp_files {
+    my $self = shift(@_);
+    
+    if(defined($self->{'places_filename'}) && -e $self->{'places_filename'}){
+	&util::rm($self->{'places_filename'});
+    }
+    $self->{'places_filename'} = undef;
+
+}
Index: /gsdl/stable/perllib/plugins/GreenstoneMETSPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/GreenstoneMETSPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/GreenstoneMETSPlugin.pm	(revision 20131)
@@ -0,0 +1,325 @@
+###########################################################################
+#
+# GreenstoneMETSPlugin.pm
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# Processes GreenstoneArchive METS documents. Note that this plugin does no
+# syntax checking (though the XML::Parser module tests for
+# well-formedness). It's assumed that the GreenstoneArchive files conform
+# to their DTD.
+
+
+package GreenstoneMETSPlugin;
+
+use ghtml;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+use ReadXMLFile;
+use XML::XPath;
+use XML::XPath::XMLParser;
+
+sub BEGIN {
+    @GreenstoneMETSPlugin::ISA = ('ReadXMLFile');
+}
+
+my $arguments = [
+		 ];
+my $options = { 'name'     => "GreenstoneMETSPlugin",
+		'desc'     => "{GreenstoneMETSPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes" };
+
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)docmets\.xml$^;
+}
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    # have no args - do we still want this?
+    #push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new ReadXMLFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    $self->{'section'} = "";
+    $self->{'section_level'} = 0;
+    $self->{'metadata_name'} = "";
+    $self->{'metadata_value'} = "";
+    $self->{'content'} = "";
+
+    return bless $self, $class;
+}
+
+sub xml_start_document {
+    my $self = shift (@_);
+    my ($expat, $element) =  @_;
+
+    $self->{'section'} = "";
+    $self->{'section_level'} = 0;
+    $self->{'metadata_name'} = "";
+    $self->{'metadata_value'} = "";
+    $self->{'content'} = "";
+
+    #**defined a dmdSection Table
+    $self->{'dmdSec_table'}={};
+
+    #**defined a fileSection Table
+    $self->{'fileSec_table'}={};
+
+    #***open doctxt.xml and read the data in 
+    my $filename = $self->{'filename'};
+    
+    $filename =~ s/docmets.xml$/doctxt.xml/;
+   
+    if (!open (FILEIN,"<$filename")){
+   	print STDERR "Warning: unable to open the $filename\n";
+	$self->{'xmltxt'} = "";
+    }
+    else {
+	my $xml_text = "";
+	while (defined (my $line = <FILEIN>)) {
+	    if ($line !~ m/^<!DOCTYPE.*>/) {
+		$xml_text .= $line;
+	    }
+	}
+        my $xml_parser = XML::XPath->new (xml=> $xml_text);
+	#my $xml_tree = $xml_parser->parse ($xml_text);
+
+	#eval {$self->{'parser_text'}->parse};
+	$self->{'parsed_xml'} = $xml_parser;
+    }
+    my $outhandle = $self->{'outhandle'};
+    print $outhandle "GreenstoneMETSPlugin: processing $self->{'file'}\n" if $self->{'verbosity'} > 1;
+    print STDERR "<Processing n='$self->{'file'}' p='GreenstoneMETSPlugin'>\n" if ($self->{'gli'});
+
+}
+
+sub xml_end_document {
+}
+
+sub xml_doctype {
+}
+
+sub xml_start_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+    $self->{'element'} = $element;
+    #**deal with dmdSection
+    if ($element =~ /^(mets:)?dmdSec$/ || $element =~ /(gsdl3:)?Metadata$/){ 
+	$self->xml_dmd_start_tag (@_);
+    } elsif ($element =~ /^(mets:)?file$/) {
+	$_{'ID'} =~ m/FILE(.*)/;
+	$self->{'file_Id'} = $1;
+    } elsif ($element =~ /^(mets:)?FLocat$/){
+	#***deal with fileSection
+	$self->xml_fileloc_start_tag (@_);
+    } elsif ($element =~ /^(mets:)?div$/){
+	#***deal with StrucMap Section
+	$self->xml_strucMap_start_tag (@_);
+    }
+}
+
+sub xml_dmd_start_tag {
+    my $self = shift (@_);
+    my ($expat, $element) = @_;
+
+    if ($element =~ /^(mets:)?dmdSec$/){
+  	my ($section_num) = ($_{'ID'} =~ m/DM(.*)/);
+	$self->{'dmdSec_table'}->{"$section_num"}=[];
+	$self->{'dmdSec_table'}->{'section_num'}=$section_num;
+    } elsif ($element =~ /^(gsdl3:)?Metadata$/) {
+	$self->{'metadata_name'} = $_{'name'};
+    }
+}
+
+sub xml_fileloc_start_tag {
+    my $self = shift (@_);
+    my ($expat, $element) = @_;
+
+    my $xlink = $_{'xlink:href'};
+    if (!defined $xlink) {
+	# try without namespace
+	$xlink = $_{'href'};
+    }
+    #my ($section_num) = ($_{'ID'} =~ m/^FLOCAT(.*)$/);
+    my $section_num = $self->{'file_Id'};
+    return if (!defined $section_num); 
+    #**return if the section_num is not defined or not deal with the whole section (ID="default.*")
+    
+    $self->{'fileSec_table'}->{"$section_num"}=[];
+    $self->{'fileSec_table'}->{'section_num'}=$section_num;
+    
+    my ($filename,$xpath_expr)=($xlink =~ m/^file:(.*)\#xpointer\((.*)\)$/);
+    my $nodeset = $self->{'parsed_xml'}->findnodes ($xpath_expr);
+    my $node_size= $nodeset->size;
+    
+    if ($node_size==0) {
+	print STDERR "Warning: no text associated with XPATH $xpath_expr\n";
+    }
+    else {
+	foreach my $node ($nodeset->get_nodelist) {
+	    my $xml_content = XML::XPath::XMLParser::as_string($node);
+	    my $unescaped_xml_content = &ghtml::unescape_html($xml_content);
+	    my $section_content={'section_content'=> $unescaped_xml_content};
+	    
+	    my $content_list = $self->{'fileSec_table'}->{"$section_num"};
+	    push (@$content_list, $section_content);
+	}
+    }
+}
+
+sub xml_strucMap_start_tag {
+    my $self = shift (@_);
+    my ($expat, $element) = @_;
+
+
+    my ($section_num) = ($_{'ID'} =~ m/DS(.*)/);
+
+    if ($_{'ID'} ne "DSAll"){
+	if ($self->{'section_level'}==0) {
+	    $self->open_document();
+	} else {
+	    my $doc_obj = $self->{'doc_obj'};
+	    $self->{'section'}=
+		$doc_obj->insert_section($doc_obj->get_end_child($self->{'section'}));
+	}
+	$self->{'section_level'}++;
+	
+	#***Add metadata from dmdSection
+	my $md_list = $self->{'dmdSec_table'}->{"$section_num"};
+	
+	foreach my $md_pair (@$md_list){
+	    my $metadata_name = $md_pair->{'metadata_name'};
+	    my $metadata_value = $md_pair->{'metadata_value'};
+	    $self->{'doc_obj'}->add_utf8_metadata($self->{'section'}, $metadata_name, $metadata_value);
+	}
+	
+	#*** Add content from fileSection
+	my $content_list = $self->{'fileSec_table'}->{"$section_num"};
+	
+	foreach my $section_content (@$content_list){
+	    my $content = $section_content->{'section_content'};
+	    $self->{'doc_obj'}->add_utf8_text($self->{'section'},$content);
+	}
+    }
+}
+
+sub get_doctype {
+    my $self = shift(@_);
+    
+    return "mets:mets";
+}
+
+sub xml_end_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+
+    if ($element =~ /^(gsdl3:)?Metadata$/) {
+	my $section_num = $self->{'dmdSec_table'}->{'section_num'};
+	my $metadata_name=$self->{'metadata_name'};
+	my $metadata_value=$self->{'metadata_value'};
+
+	my $md_pair={'metadata_name' => $metadata_name,
+		     'metadata_value'=> $metadata_value};
+
+	my $md_list = $self->{'dmdSec_table'}->{"$section_num"};
+
+	push(@$md_list,$md_pair);
+      
+	$self->{'metadata_name'} = "";
+	$self->{'metadata_value'} = "";
+    } elsif ($element =~ /^(mets:)?file$/){
+	$self->{'file_id'} = "";
+    }
+    
+    
+    #*** StrucMap Section
+    if ($element =~ /^(mets:)?div$/) {
+	$self->{'section_level'}--;
+	$self->{'section'} = $self->{'doc_obj'}->get_parent_section($self->{'section'});
+	$self->close_document() if $self->{'section_level'}==0;
+    }
+    $self->{'element'} = "";
+}
+
+sub xml_text {
+    my $self = shift(@_);
+    my ($expat) = @_; 
+
+    if ($self->{'element'} =~ /^(gsdl3:)?Metadata$/) {
+   	$self->{'metadata_value'} .= $_;
+    }
+}
+
+sub open_document {
+    my $self = shift(@_);
+
+    # create a new document
+    $self->{'doc_obj'} = new doc ();
+    $self->{'section'} = "";
+}
+
+sub close_document {
+    my $self = shift(@_);
+    
+    # add the associated files
+    my $assoc_files = 
+	$self->{'doc_obj'}->get_metadata($self->{'doc_obj'}->get_top_section(), "gsdlassocfile");
+
+    # for when "assocfilepath" isn't the same directory that doc.xml is in...
+    my $assoc_filepath_list= $self->{'doc_obj'}->get_metadata($self->{'doc_obj'}->get_top_section(), "assocfilepath");
+
+    my $assoc_filepath=shift (@$assoc_filepath_list);
+    if (defined ($assoc_filepath)) {
+	# make absolute rather than relative...
+	$self->{'filename'} =~ m@^(.*[\\/]archives)@;
+	$assoc_filepath = "$1/$assoc_filepath/";
+    } else {
+	$assoc_filepath = $self->{'filename'};
+	$assoc_filepath =~ s/[^\\\/]*$//;
+    }
+
+    foreach my $assoc_file_info (@$assoc_files) {
+	my ($assoc_file, $mime_type, $dir) = split (":", $assoc_file_info);
+	my $real_dir = &util::filename_cat($assoc_filepath, $assoc_file),
+	my $assoc_dir = (defined $dir && $dir ne "") 
+	    ? &util::filename_cat($dir, $assoc_file) : $assoc_file;
+	$self->{'doc_obj'}->associate_file($real_dir, $assoc_dir, $mime_type);
+    }
+    $self->{'doc_obj'}->delete_metadata($self->{'doc_obj'}->get_top_section(), "gsdlassocfile");
+
+    # process the document
+    $self->{'processor'}->process($self->{'doc_obj'}, $self->{'file'});
+}
+
+
+1;
+
Index: /gsdl/stable/perllib/plugins/GreenstoneXMLPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/GreenstoneXMLPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/GreenstoneXMLPlugin.pm	(revision 20131)
@@ -0,0 +1,262 @@
+###########################################################################
+#
+# GreenstoneXMLPlugin.pm
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# Processes GreenstoneArchive XML documents. Note that this plugin does no
+# syntax checking (though the XML::Parser module tests for
+# well-formedness). It's assumed that the GreenstoneArchive files conform
+# to their DTD.
+
+package GreenstoneXMLPlugin;
+
+use ReadXMLFile;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @GreenstoneXMLPlugin::ISA = ('ReadXMLFile');
+}
+
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)doc\.xml$^;
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "GreenstoneXMLPlugin",
+		'desc'     => "{GreenstoneXMLPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+	        'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new ReadXMLFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    $self->{'section'} = "";
+    $self->{'section_level'} = 0;
+    $self->{'metadata_name'} = "";
+    $self->{'metadata_value'} = "";
+    $self->{'content'} = "";
+
+#    # Currently used to store information for previous values controls. In
+#    # the next contract I'll move to using information directly from Lucene.
+#    $self->{'sqlfh'} = 0;
+   
+    return bless $self, $class;
+}
+
+sub xml_start_document {
+}
+
+sub xml_end_document {
+}
+
+sub get_doctype {
+    my $self = shift(@_);
+    
+    return "(Greenstone)?Archive";
+}
+
+
+sub xml_doctype {
+    my $self = shift(@_);
+
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+
+    # allow the short-lived and badly named "GreenstoneArchive" files to be processed
+    # as well as the "Archive" files which should now be created by import.pl
+    die "" if ($name !~ /^(Greenstone)?Archive$/);
+
+    my $outhandle = $self->{'outhandle'};
+    print $outhandle "GreenstoneXMLPlugin: processing $self->{'file'}\n" if $self->{'verbosity'} > 1;
+    print STDERR "<Processing n='$self->{'file'}' p='GreenstoneXMLPlugin'>\n" if $self->{'gli'};
+
+}
+
+
+sub xml_start_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+
+    $self->{'element'} = $element;
+    if ($element eq "Section") {
+	if ($self->{'section_level'} == 0) {
+	    $self->open_document();
+       	} else {
+	    my $doc_obj = $self->{'doc_obj'};
+	    $self->{'section'} = 
+		$doc_obj->insert_section($doc_obj->get_end_child($self->{'section'}));
+	}
+	
+	$self->{'section_level'} ++;
+    }
+    elsif ($element eq "Metadata") {
+	$self->{'metadata_name'} = $_{'name'};
+    }
+}
+
+sub xml_end_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+
+    if ($element eq "Section") {
+	$self->{'section_level'} --;
+	$self->{'section'} = $self->{'doc_obj'}->get_parent_section ($self->{'section'});
+	$self->close_document() if $self->{'section_level'} == 0;
+    }
+    elsif ($element eq "Metadata") {
+	$self->{'doc_obj'}->add_utf8_metadata($self->{'section'}, $self->{'metadata_name'},$self->{'metadata_value'});
+        # Ensure this value is added to the allvalues database in gseditor.
+        # Note that the database constraints prevent multiple occurances of the
+        # same key-value pair.
+        # We write these out to a file, so they can all be commited in one
+        # transaction
+        #if (!$self->{'sqlfh'})
+        #  {
+        #    my $sql_file = $ENV{'GSDLHOME'} . "/collect/lld/tmp/gseditor.sql";
+        #    # If the file doesn't already exist, open it and begin a transaction
+        #    my $sql_fh;
+        #    if (!-e $sql_file)
+        #      {
+        #        open($sql_fh, ">" . $sql_file);
+        #        print $sql_fh "BEGIN TRANSACTION;\n";
+        #      }
+        #    else
+        #      {
+        #        open($sql_fh, ">>" . $sql_file);
+        #      }
+        #    print STDERR "Opened SQL log\n";
+        #    $self->{'sqlfh'} = $sql_fh;
+        #  }
+
+        #my $mvalue = $self->{'metadata_value'};
+        #$mvalue =~ s/\'/\'\'/g;
+        #$mvalue =~ s/_claimantsep_/ \& /g;
+
+        #my $fh = $self->{'sqlfh'};
+        #if ($fh)
+        #  {
+        #    print $fh "INSERT INTO allvalues (mkey, mvalue) VALUES ('" . $self->{'metadata_name'} . "', '" . $mvalue . "');\n";
+        #  }
+
+        # Clean Up
+	$self->{'metadata_name'} = "";
+	$self->{'metadata_value'} = "";
+    }
+    elsif ($element eq "Content" && $self->{'content'} ne "") {
+	$self->{'doc_obj'}->add_utf8_text($self->{'section'}, $self->{'content'});
+	$self->{'content'} = "";
+    }
+    $self->{'element'} = "";
+}
+
+sub xml_text {
+    my $self = shift(@_);
+    my ($expat) = @_;
+
+    if ($self->{'element'} eq "Metadata") {
+	$self->{'metadata_value'} .= $_;
+    }
+    elsif ($self->{'element'} eq "Content") {
+	$self->{'content'} .= $_;
+    }
+}
+
+sub open_document {
+    my $self = shift(@_);
+
+    # create a new document
+    $self->{'doc_obj'} = new doc ();
+    $self->{'section'} = "";
+}
+
+sub close_document {
+    my $self = shift(@_);
+
+    # add the associated files
+    my $assoc_files = 
+	$self->{'doc_obj'}->get_metadata($self->{'doc_obj'}->get_top_section(), "gsdlassocfile");
+
+    # for when "assocfilepath" isn't the same directory that doc.xml is in...
+    my $assoc_filepath_list= $self->{'doc_obj'}->get_metadata($self->{'doc_obj'}->get_top_section(), "assocfilepath");
+
+    my $assoc_filepath=shift (@$assoc_filepath_list);
+
+    #rint STDERR "Filename is: " . $self->{'filename'} . "\n";
+    #rint STDERR "Initially my assoc_filepath is: $assoc_filepath\n";
+    #rint STDERR "Custom archive dir is: " . $self->{'base_dir'} . "\n";
+    # Correct the assoc filepath if one is defined
+    if (defined ($assoc_filepath))
+      {
+        # Check whether the assoc_filepath already includes the base dir
+        if (index($assoc_filepath, $self->{'base_dir'}) == -1)
+          {
+            # And if not, append it so as to make this absolute
+            $assoc_filepath = &util::filename_cat($self->{'base_dir'}, $assoc_filepath);
+          }
+      }
+    else
+      {
+	$assoc_filepath = $self->{'filename'};
+	$assoc_filepath =~ s/[^\\\/]*$//;
+      }
+    #rint STDERR "Goned and made it absolute: $assoc_filepath\n";
+
+    foreach my $assoc_file_info (@$assoc_files) {
+	my ($assoc_file, $mime_type, $dir) = split (":", $assoc_file_info);
+        #rint STDERR "assoc_file: $assoc_file\n";
+        #rint STDERR "mime_type: $mime_type\n";
+        #rint STDERR "dir: $dir\n";
+	my $real_dir = &util::filename_cat($assoc_filepath, $assoc_file),
+	my $assoc_dir = (defined $dir && $dir ne "") 
+	    ? &util::filename_cat($dir, $assoc_file) : $assoc_file;
+	$self->{'doc_obj'}->associate_file($real_dir, $assoc_dir, $mime_type);
+        #rint STDERR "According to me the real assoc_filepath is: $real_dir\n";
+    }
+    $self->{'doc_obj'}->delete_metadata($self->{'doc_obj'}->get_top_section(), "gsdlassocfile");
+
+    # process the document
+    $self->{'processor'}->process($self->{'doc_obj'}, $self->{'file'});
+}
+
+
+1;
+
+
Index: /gsdl/stable/perllib/plugins/HBPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/HBPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/HBPlugin.pm	(revision 20131)
@@ -0,0 +1,332 @@
+###########################################################################
+#
+# HBPlugin.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# plugin which processes an HTML book directory
+
+# This plugin is used by the Humanity Library collections and does not handle
+# input encodings other than ascii or extended ascii
+
+# this code is kind of ugly and could no doubt be made to run faster, by leaving
+# it in this state I hope to encourage people to make their collections use
+# HBSPlug instead ;-)
+
+# Use HBSPlug if creating a new collection and marking up files like the
+# Humanity Library collections. HBSPlug accepts all input encodings but
+# expects the marked up files to be cleaner than those used by the
+# Humanity Library collections
+
+package HBPlugin;
+
+use ghtml;
+use BasePlugin;
+use unicode;
+use util;
+use doc;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @HBPlugin::ISA = ('BasePlugin');
+}
+my $encoding_list =     
+    [ { 'name' => "ascii",
+	'desc' => "{BasePlugin.encoding.ascii}" },
+      { 'name' => "iso_8859_1",
+	'desc' => "{HBPlugin.encoding.iso_8859_1}" } ];
+ 
+my $arguments = 
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() },
+      { 'name' => "input_encoding",
+	'desc' => "{ReadTextFile.input_encoding}",
+	'type' => "enum",
+	'deft' => "iso_8859_1",
+	'list' => $encoding_list,
+	'reqd' => "no" }
+      ];
+
+my $options = { 'name'     => "HBPlugin",
+		'desc'     => "{HBPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+# this is included only to prevent warnings being printed out 
+# from BasePlugin::init. The process_exp is not used by this plugin
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return "This plugin does not use a process_exp\n";
+}
+
+
+sub HB_read_html_file {
+    my $self = shift (@_);
+    my ($htmlfile, $text) = @_;
+
+    # load in the file
+    if (!open (FILE, $htmlfile)) {
+	my $outhandle = $self->{'outhandle'};
+	print $outhandle "ERROR - could not open $htmlfile\n";
+	return;
+    }
+
+    my $foundbody = 0;
+    $self->HB_gettext (\$foundbody, $text, "FILE");
+    close FILE;
+
+    # just in case there was no <body> tag
+    if (!$foundbody) {
+	$foundbody = 1;
+	open (FILE, $htmlfile) || return;
+	$self->HB_gettext (\$foundbody, $text, "FILE");	
+	close FILE;
+    }
+    # text is in utf8
+}
+
+# converts the text to utf8, as ghtml does that for &eacute; etc.
+sub HB_gettext {
+    my $self = shift (@_);
+    my ($foundbody, $text, $handle) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my $line = "";
+    while (defined ($line = <$handle>)) {
+	# look for body tag
+	if (!$$foundbody) {
+	    if ($line =~ s/^.*<body[^>]*>//i) {
+		$$foundbody = 1;
+	    } else {
+		next;
+	    }
+	}
+	
+	# check for symbol fonts
+	if ($line =~ /<font [^>]*?face\s*=\s*\"?(\w+)\"?/i) {
+	    my $font = $1;
+	    print $outhandle "HBPlugin::HB_gettext - warning removed font $font\n" 
+		if ($font !~ /^arial$/i);
+	}
+
+	$line =~ s/<\/p>//ig;   # remove </p> tags
+	$line =~ s/<\/?(body|html|font)\b[^>]*>//ig; # remove any unwanted tags
+
+	$$text .= $line;
+    }
+    #
+    if ($self->{'input_encoding'} eq "iso_8859_1") {
+	# convert to utf-8
+	$$text=&unicode::unicode2utf8(&unicode::convert2unicode("iso_8859_1", $text));
+    }
+    # convert any alphanumeric character entities to their utf-8
+    # equivalent for indexing purposes
+    &ghtml::convertcharentities ($$text);
+
+    $$text =~ s/\s+/ /g; # remove \n's
+}
+
+sub HB_clean_section {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    # remove tags without a starting tag from the section
+    my ($tag, $tagstart);
+    while ($section =~ /<\/([^>]{1,10})>/) {
+	$tag = $1;
+	$tagstart = index($section, "<$tag");
+	last if (($tagstart >= 0) && ($tagstart < index($section, "<\/$tag")));
+	$section =~ s/<\/$tag>//;
+    }
+    
+    # remove extra paragraph tags
+    while ($section =~ s/<p\b[^>]*>\s*<p\b/<p/ig) {}
+    
+    # remove extra stuff at the end of the section
+    while ($section =~ s/(<u>|<i>|<b>|<p\b[^>]*>|&nbsp;|\s)$//i) {}
+    
+    # add a newline at the beginning of each paragraph
+    $section =~ s/(.)\s*<p\b/$1\n\n<p/gi;
+    
+    # add a newline every 80 characters at a word boundary
+    # Note: this regular expression puts a line feed before
+    # the last word in each section, even when it is not
+    # needed.
+    $section =~ s/(.{1,80})\s/$1\n/g;
+    
+    # fix up the image links
+    $section =~ s/<img[^>]*?src=\"?([^\">]+)\"?[^>]*>/
+	<center><img src=\"_httpdocimg_\/$1\"><\/center><br>/ig;
+    $section =~ s/&lt;&lt;I&gt;&gt;\s*([^\.]+\.(png|jpg|gif))/
+	<center><img src=\"_httpdocimg_\/$1\"><\/center><br>/ig;
+
+    return $section;
+}
+
+
+sub shorten {
+    my $self = shift (@_);
+    my ($text) = @_;
+
+    return "\"$text\"" if (length($text) < 100);
+
+    return "\"" . substr ($text, 0, 50) . "\" ... \"" . 
+	substr ($text, length($text)-50) . "\"";
+}
+
+# return number of files processed, undef if can't process
+# Note that $base_dir might be "" and that $file might 
+# include directories
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    # get the html filename and see if this is an HTML Book...
+    my $jobnumber = $file;
+    if ($file =~ /[\\\/]/) {
+	($jobnumber) = $file =~ /[\\\/]([^\\\/]+)$/;
+    }
+    return undef unless defined $jobnumber;
+    my $htmlfile = &util::filename_cat($base_dir, $file, "$jobnumber.htm");
+    return undef unless -e $htmlfile;
+
+    print STDERR "<Processing n='$file' p='HBPlugin'>\n" if ($gli);
+    print $outhandle "HBPlugin: processing $file\n";
+
+    # read in the file and do basic html cleaning (removing header etc)
+    my $html = "";
+    $self->HB_read_html_file ($htmlfile, \$html);
+    # html is in utf8
+
+    # create a new document
+    my $doc_obj = new doc ($file, "indexed_doc", $self->{'file_rename_method'});
+
+    # copy the book cover if it exists
+    my $bookcover = &util::filename_cat($base_dir, $file, "$jobnumber.jpg");
+    $doc_obj->associate_file($bookcover, "cover.jpg", "image/jpeg");
+    $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");
+    $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "FileFormat", "HB");
+    $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "FileSize", (-s $htmlfile));
+
+    my $cursection = $doc_obj->get_top_section();
+    
+    # add metadata for top level of document
+    foreach my $field (keys(%$metadata)) {
+	# $metadata->{$field} may be an array reference
+	if (ref ($metadata->{$field}) eq "ARRAY") {
+	    map {
+		$doc_obj->add_utf8_metadata($cursection, $field, $_);
+	    } @{$metadata->{$field}};
+	} else {
+	    $doc_obj->add_utf8_metadata($cursection, $field, $metadata->{$field}); 
+	}
+    }
+
+    # process the file one section at a time
+    my $curtoclevel = 1;
+    my $firstsection = 1;
+    while (length ($html) > 0) {
+	if ($html =~ s/^.*?(?:<p\b[^>]*>)?((<b>|<i>|<u>|\s)*)&lt;&lt;TOC(\d+)&gt;&gt;\s*(.*?)<p\b/<p/i) {
+	    my $toclevel = $3;
+	    my $title = $4;
+	    my $sectiontext = "";
+	    if ($html =~ s/^(.*?)((?:<p\b[^>]*>)?((<b>|<i>|<u>|\s)*)&lt;&lt;TOC\d+&gt;&gt;)/$2/i) {
+		$sectiontext = $1;
+	    } else {
+		$sectiontext = $html;
+		$html = "";
+	    }
+
+	    # remove tags and extra spaces from the title
+	    $title =~ s/<\/?[^>]+>//g;
+	    $title =~ s/^\s+|\s+$//g;
+
+	    # close any sections below the current level and
+	    # create a new section (special case for the firstsection)
+	    while (($curtoclevel > $toclevel) ||
+		   (!$firstsection && $curtoclevel == $toclevel)) {
+		$cursection = $doc_obj->get_parent_section ($cursection);
+		$curtoclevel--;
+	    }
+	    if ($curtoclevel+1 < $toclevel) {
+		print $outhandle "WARNING - jump in toc levels in $htmlfile " . 
+		    "from $curtoclevel to $toclevel\n";
+	    }
+	    while ($curtoclevel < $toclevel) {
+		$curtoclevel++;
+		$cursection = 
+		    $doc_obj->insert_section($doc_obj->get_end_child($cursection));
+	    }
+
+	    # add the metadata to this section
+	    $doc_obj->add_utf8_metadata($cursection, "Title", $title);
+
+	    # clean up the section html
+	    $sectiontext = $self->HB_clean_section($sectiontext);
+
+	    # associate any files
+	    map { $doc_obj->associate_file(&util::filename_cat ($base_dir, $file, $1), $1)
+		      if /_httpdocimg_\/([^\"]+)\"/; 0; }
+	         split (/(_httpdocimg_\/[^\"]+\")/, $sectiontext);
+
+	    # add the text for this section
+	    $doc_obj->add_utf8_text ($cursection, $sectiontext);
+	} else {
+	    print $outhandle "WARNING - leftover text\n" , $self->shorten($html), 
+	    "\nin $htmlfile\n";
+	    last;
+	}
+	$firstsection = 0;
+    }
+
+    # add a OID
+    $self->add_OID($doc_obj);
+
+    # process the document
+    $processor->process($doc_obj, &util::filename_cat($file, "$jobnumber.htm"));
+        
+    return 1; # processed the file
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/HTMLImagePlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/HTMLImagePlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/HTMLImagePlugin.pm	(revision 20131)
@@ -0,0 +1,1069 @@
+###########################################################################
+#
+# HTMLImagePlugin.pm -- Context-based image indexing plugin for HTML documents
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# DESCRIPTION:
+#
+#  Extracts images and associated text and metadata from
+#  web pages as individual documents for indexing. Thumbnails
+#  are created from each image for browsing purposes.
+#
+#  Options are available for configuring the aggressiveness of the
+#  associated text extraction mechanisms. A higher level of
+#  aggressiveness will extract more text and consequently
+#  may mean lower accuracy (precision); however, it may also 
+#  retrieve more of the relevant images from the collection (recall). 
+#  Lower levels of aggressiveness maybe result in slightly faster
+#  collection builds at the import stage.
+#
+#  HTMLImagePlugin is a subclass of HTMLPlug (i.e. it will index pages also 
+#  if required). It can be used in place of HTMLPlugin to index both
+#  pages and their images.
+#
+# REQUIREMENTS:
+#   
+#  The ImageMagick image manipulation is used to create
+#  thumbnails and extract some image metadata. (Available 
+#  from http://www.imagemagick.org/)
+#
+#  Unix:
+#    Many Linux distributions contain ImageMagick.
+#
+#  Windows:
+#    ImageMagick can be downloaded from the website above.
+#    Make sure the system path includes the ImageMagick binaries
+#    before using HTMLImagePlugin.
+#
+#    NOTE: NT/2000/XP contain a filesystem utility 'convert.exe' 
+#    with the same name as the image conversion utility. The
+#    ImageMagick FAQ recommends renaming the filesystem
+#    utility (e.g. to 'fsconvert.exe') to avoid this clash.
+#
+# USAGE:  
+#
+#  An image document consists of metadata elements:
+#
+#   OriginalFilename, FilePath, Filename, FileExt, FileSize,
+#   Width, Height, URL, PageURL, ThumbURL, CacheURL, CachePageURL
+#   ImageText, PageTitle
+#
+#  Most of these are only useful in format strings (e.g. ThumbURL, 
+#  Filename, URL, PageURL, CachePageURL). 
+#
+#  ImageText, as the name suggests contains the indexable text.
+#  (unless using the -document_text plugin option)
+#
+#  Since image documents are made up of metadata elements 
+#  alone, format strings are needed to display them properly. 
+#  NOTE: The receptionist will only display results (e.g. thumbnails)
+#  in 4 columns if the format string begins with "<td><table>".
+#
+#  The example below takes the user to the image within the
+#  source HTML document rather than using a format string
+#  on DocumentText to display the image document itself.
+#
+#  Example collect.cfg:
+#
+#   ...
+#
+#   indexes document:ImageText document:text
+#   defaultindex document:ImageText
+#  
+#   collectionmeta .document:ImageText "images"
+#   collectionmeta .document:text "documents"
+#
+#   ...
+#
+#   plugin HTMLImagePlugin -index_pages -aggressiveness 6
+#
+#   ...
+#  
+#   format SearchVList '<td>{If}{[Title],[link][icon]&nbsp;[Title][[/link],
+#    <table><tr><td align="center"><a href="[CachePageURL]">
+#    <img src="[ThumbURL]"></a></td></tr><tr><td align="center">
+#    <a href="[CachePageURL]"><font size="-1">[OriginalFilename]</font></a>
+#    <br>[Width]x[Height]</td></tr></table>}</td>'
+#
+#   ...
+#
+ 
+package HTMLImagePlugin;
+
+use HTMLPlugin;
+use ghtml;
+use unicode;
+use util;
+use strict; # 'subs';
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @HTMLImagePlugin::ISA = qw( HTMLPlugin );
+}
+
+my $aggressiveness_list = 
+    [ { 'name' => "1",
+	'desc' => "{HTMLImagePlugin.aggressiveness.1}" },
+      { 'name' => "2",
+	'desc' => "{HTMLImagePlugin.aggressiveness.2}" },
+      { 'name' => "3",
+	'desc' => "{HTMLImagePlugin.aggressiveness.3}" },
+      { 'name' => "4",
+	'desc' => "{HTMLImagePlugin.aggressiveness.4}" },
+      { 'name' => "5",
+	'desc' => "{HTMLImagePlugin.aggressiveness.5}" },
+      { 'name' => "6",
+	'desc' => "{HTMLImagePlugin.aggressiveness.6}" },
+      { 'name' => "7",
+	'desc' => "{HTMLImagePlugin.aggressiveness.7}" },
+      { 'name' => "8",
+	'desc' => "{HTMLImagePlugin.aggressiveness.8}" },
+      { 'name' => "9",
+	'desc' => "{HTMLImagePlugin.aggressiveness.9}" } ];
+
+my $arguments =
+    [ { 'name' => "aggressiveness",
+	'desc' => "{HTMLImagePlugin.aggressiveness}",
+	'type' => "int",
+	'list' => $aggressiveness_list,
+	'deft' => "3",
+	'reqd' => "no" },
+      { 'name' => "index_pages",
+	'desc' => "{HTMLImagePlugin.index_pages}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "no_cache_images",
+	'desc' => "{HTMLImagePlugin.no_cache_images}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "min_size",
+	'desc' => "{HTMLImagePlugin.min_size}",
+	'type' => "int",
+	'deft' => "2000",
+	'reqd' => "no" },
+      { 'name' => "min_width",
+	'desc' => "{HTMLImagePlugin.min_width}",
+	'type' => "int",
+	'deft' => "50",
+	'reqd' => "no" },
+      { 'name' => "min_height",
+	'desc' => "{HTMLImagePlugin.min_height}",
+	'type' => "int",
+	'deft' => "50",
+	'reqd' => "no" },
+      { 'name' => "thumb_size",
+	'desc' => "{HTMLImagePlugin.thumb_size}",
+	'type' => "int",
+	'deft' => "100",
+	'reqd' => "no" },
+      { 'name' => "convert_params",
+	'desc' => "{HTMLImagePlugin.convert_params}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "min_near_text",
+	'desc' => "{HTMLImagePlugin.min_near_text}",
+	'type' => "int",
+	'deft' => "10",
+	'reqd' => "no" },
+      { 'name' => "max_near_text",
+	'desc' => "{HTMLImagePlugin.max_near_text}",
+	'type' => "int",
+	'deft' => "400",
+	'reqd' => "no" },
+      { 'name' => "smallpage_threshold",
+	'desc' => "{HTMLImagePlugin.smallpage_threshold}",
+	'type' => "int",
+	'deft' => "2048",
+	'reqd' => "no" },
+      { 'name' => "textrefs_threshold",
+	'desc' => "{HTMLImagePlugin.textrefs_threshold}",
+	'type' => "int",
+	'deft' => "2",
+	'reqd' => "no" },
+      { 'name' => "caption_length",
+	'desc' => "{HTMLImagePlugin.caption_length}",
+	'type' => "int",
+	'deft' => "80",
+	'reqd' => "no" },
+      { 'name' => "neartext_length",
+	'desc' => "{HTMLImagePlugin.neartext_length}",
+	'type' => "int",
+	'deft' => "300",
+	'reqd' => "no" },
+      { 'name' => "document_text",
+	'desc' => "{HTMLImagePlugin.document_text}",
+	'type' => "flag",
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "HTMLImagePlugin",
+		'desc'     => "{HTMLImagePlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new HTMLPlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    # init class variables
+    $self->{'textref'} = undef; # init by read_file fn
+    $self->{'htdoc_obj'} = undef; # init by process fn
+    $self->{'htpath'} = undef; # init by process fn
+    $self->{'hturl'} = undef; # init by process fn
+    $self->{'plaintext'} = undef; # HTML stripped version - only init if needed by raw_neartext sub
+    $self->{'smallpage'} = 0; # set by process fn
+    $self->{'images_indexed'} = undef; # num of images indexed - if 1 or 2 then we know page is small
+    $self->{'initialised'} = undef; # flag (see set_extraction_options())
+
+    return bless $self, $class;
+}
+
+# if indexing pages, let HTMLPlugin do it's stuff
+# image extraction done through read()
+sub process {
+    my $self = shift(@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    $self->{'imglist'} = ();
+    if ( $self->{'index_pages'} ) {
+	my $ok = $self->SUPER::process($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli);
+	if ( ! $ok ) { return $ok }
+	$self->{'htdoc_obj'} = $doc_obj;
+    }
+    # else use URL for referencing
+    #if ( $file =~ /(.*)[\/\\]/ ) { $self->{'htpath'} = $1; } else { $self->{'htpath'} = $file; }
+
+    $self->{'htpath'} = $base_dir if (-d $base_dir);
+    if ( $file =~ /(.*)[\/\\]/ ) { $self->{'htpath'} .= "/$1"; }
+    $self->{'htpath'} =~ s/\\/\//g;  # replace \ with /
+
+    $self->{'hturl'} = "http://$file";
+    $self->{'hturl'} =~ s/\\/\//g; # for windows
+    ($self->{'filename'}) = $file =~ /.*[\/\\](.*)/;
+    ($self->{'base_path'}) = $file =~ /(.*)[\/\\]/i;
+    if ( ( -s "$base_dir/$file") <= $self->{'smallpage_threshold'} ) {
+	$self->{'smallpage'} = 1;
+    } else { $self->{'smallpage'} = 0; }
+
+    if ( defined($self->{'initialised'}) ) { return 1; }
+    else {
+	$self->{'initialised'} = $self->set_extraction_options($base_dir =~ /^(.*?)\/import/i);
+	return $self->{'initialised'};
+    }
+}
+
+# get complex configuration options from configuration files
+# -- $GSDLCOLLECTION/etc/HTMLImagePlugin.cfg (tag sets for aggr 2+)
+# -- $GSDLHOME/etc/packages/phind/stopword/en/brown.sw (stopwords for aggr 5+)
+
+# If there's no HTMLImagePlugin.cfg file we'll use the following default values
+my $defaultcfg = '
+<delimitertagset>
+  <setname>Caption</setname>
+  <taggroup>font</taggroup>
+  <taggroup>tt</taggroup>
+  <taggroup>small</taggroup>
+  <taggroup>b</taggroup>
+  <taggroup>i</taggroup>
+  <taggroup>u</taggroup>
+  <taggroup>em</taggroup>
+  <taggroup>td</taggroup>
+  <taggroup>li</taggroup>
+  <taggroup>a</taggroup>
+  <taggroup>p</taggroup>
+  <taggroup>tr</taggroup>
+  <taggroup>center</taggroup>
+  <taggroup>div</taggroup>
+  <taggroup>caption</taggroup>
+  <taggroup>br</taggroup>
+  <taggroup>ul</taggroup>
+  <taggroup>ol</taggroup>
+  <taggroup>table</taggroup>
+  <taggroup>hr</taggroup>
+</delimitertagset>
+
+<delimitertagset>
+  <setname>Neartext</setname>
+  <taggroup>tr|hr|table|h\d|img|body</taggroup>
+  <taggroup>td|tr|hr|table|h\d|img|body</taggroup>
+  <taggroup>p|br|td|tr|hr|table|h\d|img|body</taggroup>
+  <taggroup>font|p|i|b|em|img</taggroup>
+</delimitertagset>
+';
+
+sub set_extraction_options() {
+    my ($self, $collpath) = @_;
+    my ($filepath);
+
+    print {$self->{'outhandle'}} "HTMLImagePlugin: Initialising\n"
+	if $self->{'verbosity'} > 1;
+    # etc/HTMLImagePlugin.cfg (XML)
+    # tag sets for captions and neartext
+    if ( $self->{'aggressiveness'} > 1 && $self->{'aggressiveness'} != 9 ) {
+	$self->{'delims'} = [];
+	$self->{'cdelims'} = [];
+	my ($cfg, @tagsets, $tagset, $type, @delims);
+
+	$filepath = "$collpath/etc/HTMLImagePlugin.cfg";
+	if ( open CFG, "<$filepath" ) {
+	    while (<CFG>) { $cfg .= $_ }
+	    close CFG;
+	} else {
+	    $cfg = $defaultcfg;
+	}
+
+	(@tagsets) = 
+	    $cfg =~ /<delimitertagset>(.*?)<\/delimitertagset>/igs;
+	foreach $tagset ( @tagsets ) {
+	    ($type) = $tagset =~ /<setname>(.*?)<\/setname>/i;
+	    if ( lc($type) eq "caption" ) {
+		(@{$self->{'cdelims'}}) = $tagset =~ /<taggroup>(.*?)<\/taggroup>/igs;
+	    }
+	    elsif ( lc($type) eq "neartext" ) {
+		(@{$self->{'delims'}}) = $tagset =~ /<taggroup>(.*?)<\/taggroup>/igs;
+	    }
+	}
+
+	# output a warning if there seem to be no delimiters
+	if ( scalar(@{$self->{'cdelims'}} == 0)) {
+	    print {$self->{'outhandle'}} "HTMLImagePlugin: Warning: no caption delimiters found in $filepath\n";
+	}
+	if ( scalar(@{$self->{'delims'}} == 0)) {
+	    print {$self->{'outhandle'}} "HTMLImagePlugin: Warning: no neartext delimiters found in $filepath\n";
+	}
+    }
+    
+    # get stop words for textual reference extraction
+    # TODO: warnings scroll off. Would be best to output them again at end of import
+    if ( $self->{'aggressiveness'} >=5 && $self->{'aggressiveness'} != 9 ) {
+	$self->{'stopwords'} = ();
+	$filepath = &util::filename_cat($ENV{'GSDLHOME'}, "etc", "packages", "phind", "stopword", "en", "brown.sw");
+	if ( open STOPWORDS, "<$filepath" ) {
+	    while ( <STOPWORDS> ) {
+		chomp;
+		$self->{'stopwords'}{$_} = 1;
+	    }
+	    close STOPWORDS;
+	} else {
+	    print {$self->{'outhandle'}} "HTMLImagePlugin: Warning: couldn't open stopwords file at $filepath ($!)\n";
+	}
+	
+    }
+
+    if ( $self->{'neartext_length'} > $self->{'max_near_text'} ) {
+	$self->{'max_near_text'} = $self->{'neartext_length'} * 1.33;
+	print {$self->{'outhandle'}} "HTMLImagePlugin: Warning: adjusted max_text to $self->{'max_near_text'}\n";
+    } 
+    if ( $self->{'caption_length'} > $self->{'max_near_text'} ) {
+	$self->{'max_near_text'} = $self->{'caption_length'} * 1.33;
+	print {$self->{'outhandle'}} "HTMLImagePlugin: Warning: adjusted max_text to $self->{'max_near_text'}\n";
+    }
+
+    return 1;
+}
+
+# return number of files processed, undef if can't recognise, -1 if 
+# cant process
+# Note that $base_dir might be "" and that $file might 
+# include directories
+sub read {
+    my ($self, $pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = (@_);
+    my ($doc_obj, $section, $filepath, $imgtag, $pos, $context, $numdocs, $tndir, $imgs);
+    # forward normal read (runs HTMLPlugin if index_pages T)
+    my $ok =  $self->SUPER::read($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli); 
+    if ( ! $ok ) { return $ok } # what is this returning??
+
+    my $outhandle = $self->{'outhandle'};
+    my $textref = $self->{'textref'};
+    my $htdoc_obj = $self->{'htdoc_obj'};
+    $numdocs = 0;
+    $base_dir =~ /(.*)\/.*/;
+    $tndir = "$1/archives/thumbnails"; # TODO: this path shouldn't be hardcoded?
+    &util::mk_all_dir($tndir) unless -e "$tndir"; 
+
+    $imgs = \%{$self->{'imglist'}};
+    my $nimgs = $self->get_img_list($textref);
+    $self->{'images_indexed'} = $nimgs;
+    if ( $nimgs > 0 ) {
+	my @fplist = (sort { $imgs->{$a}{'pos'} <=> $imgs->{$b}{'pos'} } keys %{$imgs});
+	my $i = 0;
+	foreach $filepath ( @fplist ) {
+	    $pos = $imgs->{$filepath}{'pos'}; 
+	    $context = substr ($$textref, $pos - 50, $pos + 50); # grab context (quicker)
+	    ($imgtag) = ($context =~ /(<(?:img|a|body)\s[^>]*$filepath[^>]*>)/is );
+	    if (! defined($imgtag)) { $imgtag = $filepath }
+	    print $outhandle "HTMLImagePlugin: extracting $filepath\n"
+		if ( $self->{'verbosity'} > 1 );
+	    $doc_obj = new doc ("", "indexed_doc", $self->{'file_rename_method'});
+	    $section = $doc_obj->get_top_section();
+	    my $prevpos = ( $i == 0 ? 0 : $imgs->{$fplist[$i - 1]}{'pos'});
+	    my $nextpos = ( $i >= ($nimgs -1) ? -1 : $imgs->{$fplist[$i + 1]}{'pos'} );
+
+	    $self->extract_image_info($imgtag, $filepath, $textref, $doc_obj, $section, $tndir, $prevpos, $nextpos);
+            $processor->process($doc_obj);
+	    $numdocs++;
+	    $i++;
+	}
+	return $numdocs;
+    } else {
+	print $outhandle "HTMLImagePlugin: No images from $file indexed\n"
+	    if ( $self->{'verbosity'} > 2 );
+	return 1;
+    }
+    
+}
+
+# for every valid image tag
+# 1. extract related text and image metadata
+# 2. add this as document meta-data
+# 3. add assoc image(s) as files
+#
+sub extract_image_info {
+    my $self = shift (@_);
+    my ($tag, $id, $textref, $doc_obj, $section, $tndir, $prevpos, $nextpos) = (@_);
+    my ($filename, $orig_fp, $fn, $ext, $reltext, $relreltext, $crcid, $imgs,
+	$thumbfp, $pagetitle, $alttext,	$filepath, $aggr);
+    $aggr = $self->{'aggressiveness'};
+    $imgs = \%{$self->{'imglist'}};
+    $filepath = $imgs->{$id}{'relpath'}; 
+    ($filename) = $filepath =~ /([^\/\\]+)$/s;
+    ($orig_fp) = "$self->{'base_path'}/$filepath"; 
+    $orig_fp =~ tr/+/ /;
+    $orig_fp =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; # translate %2E to space, etc
+    $orig_fp =~ s/\\/\//g;
+    $filepath = "$self->{'htpath'}/$filepath";
+    my ($onlyfn) = $filename =~ /([^\\\/]*)$/;
+    ($fn, $ext) = $onlyfn =~ /(.*)\.(.*)/;
+    $fn = lc $fn; $ext = lc $ext;
+    ($reltext) = "<tr><td>GifComment</td><td>" . `identify $filepath -ping -format "%c"` . "</td></tr>\n"
+        if ($ext eq "gif");
+    $reltext .= "<tr><td>FilePath</td><td>$orig_fp</td></tr>\n";
+
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	$crcid = "$fn.$ext." . $self->{'next_crcid'}++;
+    } else { ($crcid) = `cksum $filepath` =~ /^(\d+)/; }
+    $thumbfp = "$tndir/tn_$crcid.jpg";
+    `convert -flatten -filter Hanning $self->{'convert_params'} -geometry "$self->{'thumb_size'}x$self->{'thumb_size'}>" $filepath $thumbfp` unless -e $thumbfp;
+    if ( ! (-e $thumbfp) ) {
+	print STDERR "HTMLImagePlugin: 'convert' failed. Check ImageMagicK binaries are installed and working correctly\n"; return 0; 
+    }
+    
+    # shove in full text (tag stripped or unstripped) if settings require it
+    if ( $aggr == 10) {
+	$reltext = "<tr><td>AllPage</td><td>" . $$textref . "</td><tr>\n";   # level 10 (all text, verbatim)
+    } else {
+	$pagetitle = $self->get_meta_value("title", $textref);
+	($alttext) = $tag =~ /\salt\s*=\s*(?:\"|\')(.+?)(?:\"|\')/is;
+	if ( defined($alttext) && length($alttext) > 1) {
+	    $reltext .= "<tr><td>ALTtext</td><td>$alttext</td></tr>\n"; }
+	$reltext .= "<tr><td>SplitCapitalisation</td><td>" . 
+	    $self->split_filepath($orig_fp) . "</td></tr>\n";
+
+	# get caption/tag based near text (if appropriate)
+	if ( $aggr > 1 ) {
+	    if ( $aggr >= 2 ) {
+		$reltext .= 
+		    $self->extract_caption_text($tag, $textref, $prevpos, $imgs->{$id}{'pos'}, $nextpos);
+		$relreltext = $reltext;
+	    } 
+	    # repeat the filepath, alt-text, caption, etc
+	    if ( $aggr == 8 ) {
+		$reltext .= $relreltext; 
+	    }
+	    if ( $aggr >= 3 ) {
+		$reltext .= 
+		    $self->extract_near_text($tag, $textref, $prevpos, $imgs->{$id}{'pos'}, $nextpos);
+	    }
+	
+	    # get page metadata (if appropriate)
+	    if ( $aggr >= 6 || ( $aggr >= 2 && 
+						     ( $self->{'images_indexed'} < 2 || 
+						       ($self->{'smallpage'} == 1 && $self->{'images_indexed'} < 6 )))) {	
+		$reltext .= $self->get_page_metadata($textref);
+	    }
+	    # textual references
+	    if ( $aggr  == 5 || $aggr >= 7) {
+		if ( length($relreltext) > ($self->{'caption_length'} * 2) )  {
+		    $reltext .= $self->get_textrefs($relreltext, $textref, $prevpos, $imgs->{$id}{'pos'}, $nextpos); }
+		else {
+		    $reltext .= $self->get_textrefs($reltext, $textref, $prevpos, $imgs->{$id}{'pos'}, $nextpos); 
+		}
+	    }
+	} # aggr > 1
+    } # aggr != 10
+    
+    $doc_obj->set_OID($crcid); 
+    $doc_obj->associate_file($thumbfp, "$fn.thumb.jpg", undef, $section);
+    $doc_obj->add_metadata($section, "OriginalFilename", $filename);
+    $doc_obj->add_metadata($section, "FilePath", $orig_fp);
+    $doc_obj->add_metadata($section, "Filename", $fn);
+    $doc_obj->add_metadata($section, "FileExt", $ext);
+    $doc_obj->add_metadata($section, "FileSize", $imgs->{$id}{'filesize'});
+    $doc_obj->add_metadata($section, "Width", $imgs->{$id}{'width'});
+    $doc_obj->add_metadata($section, "Height", $imgs->{$id}{'height'});
+    $doc_obj->add_metadata($section, "URL", "http://$orig_fp");
+    $doc_obj->add_metadata($section, "PageURL", $self->{'hturl'});
+    $doc_obj->add_metadata($section, "PageTitle", $pagetitle);
+    $doc_obj->add_metadata($section, "ThumbURL", 
+			   "_httpprefix_/collect/[collection]/index/assoc/[archivedir]/$fn.thumb.jpg");
+    $doc_obj->add_metadata($section, "FileFormat", "W3Img");
+
+    if ( $self->{'document_text'} ) {
+	$doc_obj->add_utf8_text($section, "<table border=1>\n$reltext</table>");
+    } else {
+	$doc_obj->add_metadata($section, "ImageText", "<table border=1>\n$reltext</table>\n");
+    }
+    
+    if ( $self->{'index_pages'} ) {
+	my ($cache_url) = "_httpdoc_&d=" . $self->{'htdoc_obj'}->get_OID();
+	if ( $imgs->{$id}{'anchored'} ) {
+	    my $a_name = $id;
+	    $a_name =~ s/[\/\\\:\&]/_/g;
+	    $cache_url .=  "#gsdl_$a_name" ;
+	}
+	$doc_obj->add_utf8_metadata($section, "CachePageURL", $cache_url);
+    }
+    if ( ! $self->{'no_cache_images'} ) {
+	$onlyfn = lc $onlyfn;
+	$doc_obj->associate_file($filepath, $onlyfn, undef, $section);
+	$doc_obj->add_utf8_metadata($section, "CacheURL", 
+			       "_httpprefix_/collect/[collection]/index/assoc/[archivedir]/$onlyfn");
+    }
+    return 1;
+}
+
+sub get_page_metadata {
+    my ($self, $textref) = (@_);
+    my (@rval);
+    $rval[0] = $self->get_meta_value("title", $textref);
+    $rval[1] = $self->get_meta_value("keywords", $textref);
+    $rval[2] = $self->get_meta_value("description", $textref);
+    $rval[3] = $self->{'filename'};
+
+    return wantarray ? @rval : "<tr><td>PageMeta</td><td>@rval</td></tr>\n" ;
+}
+
+# turns LargeCatFish into Large,Cat,Fish so MG sees the separate words
+sub split_filepath {
+    my ($self, $filepath) = (@_);
+    my (@words) = $filepath =~ /([A-Z][a-z]+)/g; 
+    return join(',', @words);
+}
+
+# finds and extracts sentences
+# that seem to be on the same topic
+# as other related text (correlations)
+# and textual references (e.g. in figure 3 ...)
+sub get_textrefs {
+    my ($self, $reltext, $textref, $prevpos, $pos, $nextpos) = (@_);
+    my ($maxtext, $mintext, $startpos, $context_size, $context);
+
+    my (@relwords, @refwords, %sentences, @pagemeta);
+
+    # extract larger context
+    $maxtext = $self->{'max_near_text'};
+    $startpos = $pos - ($maxtext * 4);
+    $context_size = $maxtext*10;
+    if ($startpos < $prevpos ) { $startpos = $prevpos }
+    if ($nextpos != -1 && $context_size > ( $nextpos - $startpos )) { $context_size = ($nextpos - $startpos) }
+    $context = substr ( $$textref, $startpos, $context_size );
+    $context =~ s/<.*?>//gs;
+    $context =~ s/^.*>(.*)/$1/gs;
+    $context =~ s/(.*)<.*$/$1/gs;
+
+    # get page meta-data (if not already included)
+    if ( $self->{'aggressiveness'} == 5 && ! $self->{'smallpage'} ) {
+	@pagemeta = $self->get_page_metadata($textref);
+	foreach my $value ( @pagemeta ) {
+	    $context .= "$value."; # make each into psuedo-sentence
+	}
+    }
+
+    # TODO: this list is not exhaustive
+    @refwords = ( '(?:is|are)? ?(?:show(?:s|n)|demonstrate(?:d|s)|explains|features) (?:in|by|below|above|here)', 
+		  '(?:see)? (?:figure|table)? (?:below|above)');    
+
+    # extract general references
+    foreach my $rw ( @refwords ) {
+	while ( $context =~ /[\.\?\!\,](.*?$rw\W.*?[\.\?\!\,])/ig ) {
+	    my $sentence = $1;
+	    $sentence =~ s/\s+/ /g;
+	    $sentences{$sentence}+=2;
+	}
+    }
+    # extract specific (figure, table) references by number
+    my ($fignum) = $context =~ /[\.\?\!].*?(?:figure|table)s?[\-\_\ \.](\d+\w*)\W.*?[\.\?\!]/ig;
+    if ( $fignum ) {
+	foreach my $rw ( @refwords ) {
+	    while ( $context =~ /[\.\?\!](.*?(figure|table)[\-\_\ \.]$fignum\W.*?[\.\?\!])/ig ) {
+		my $sentence = $1;
+		$sentence =~ s/\s+/ /g;
+		$sentences{$sentence}+=4;
+	    }
+	}
+    }
+
+    # sentences with occurances of important words
+    @relwords = $reltext =~ /([a-zA-Z]{4,})/g; # take out small words
+    foreach my $word ( @relwords ) {
+	if ( $self->{'stopwords'}{$word} ) { next } # skip stop words
+	while ( $context =~ /([^\.\?\!]*?$word\W.*?[\.\?\!])/ig ) {
+	    my $sentence = $1;
+	    $sentence =~ s/\s+/ /g;
+	    $sentences{$sentence}++;
+	}
+    }
+    foreach my $sentence ( keys %sentences ) {
+	if ($sentences{$sentence} < $self->{'textrefs_threshold'}) {
+	    delete $sentences{$sentence};
+	}
+    }
+    my ($rval) = join "<br>\n", (keys %sentences);
+    if ( $rval && length($rval) > 5 ) {
+	return ( "<tr><td>TextualReferences</td><td>" . $rval . "</td></tr>\n") }
+    else { return "" }
+}
+
+# handles caption extraction
+# calling the extractor with different
+# tags and choosing the best candidate caption
+sub extract_caption_text {
+    my ($self, $tag, $textref, $prevpos, $pos, $nextpos) = (@_);
+    my (@neartext, $len, $hdelim, $mintext, $goodlen,
+	$startpos, $context, $context_size);
+    
+    $mintext = $self->{'min_near_text'};
+    $goodlen = $self->{'caption_length'};
+
+    # extract a context to extract near text from (faster)
+    $context_size = $self->{'max_near_text'}*3;
+    $startpos = $pos - ($context_size / 2);
+    if ($startpos < $prevpos ) { $startpos = $prevpos }
+    if ($nextpos != -1 && $context_size > ( $nextpos - $startpos )) 
+    { $context_size = ($nextpos - $startpos) }
+
+    $context = substr ( $$textref, $startpos, $context_size );
+    $context =~ s/<!--.*?-->//gs;
+    $context =~ s/^.*-->(.*)/$1/gs;
+    $context =~ s/(.*)<!--.*$/$1/gs;
+
+    # try stepping through markup delimiter sets
+    # and selecting the best one
+    foreach $hdelim ( @{ $self->{'cdelims'} } ) {
+	@neartext = $self->extract_caption($tag, $hdelim, \$context);
+	$len = length(join("", @neartext));
+	last if ($len >= $mintext && $len <= $goodlen);
+    }
+    # reject if well over reasonable length
+    if ( $len > $goodlen ) {
+	@neartext = [];
+    }
+    $neartext[0] = " " if (! defined $neartext[0]);
+    $neartext[1] = " " if (! defined $neartext[1]);
+    return "<tr><td>Caption</td><td>" . (join ",",  @neartext) . "</td></tr>\n"; # TODO: the | is for testing purposes
+} # end extract_caption_text
+
+# the previous section header often gives a bit
+# of context to the section that the image is
+# in (invariably the header is before/above the image)
+# so extract the text of the closest header above the image
+#
+# this fn just gets all the headers above the image, within the context window
+sub get_prev_header {
+    my ($self, $pos, $textref) = (@_);
+    my ($rhtext);
+    while ( $$textref =~ /<h\d>(.*?)<\/h\d>/sig ) {
+	# only headers before image
+	if ((pos $$textref) < $pos) {
+	    $rhtext .= "$1, ";
+	}
+    } 
+    if ( $rhtext ) { return "Header($rhtext)" }
+    else { return "" }
+}
+
+# not the most robust tag stripping 
+# regexps (see perl.com FAQ) but good enough
+#
+# used by caption & tag-based near text algorithms
+sub strip_tags {
+    my ( $self, $value ) = @_;
+    if ( ! defined($value) ) { $value = "" } # handle nulls
+    else {
+	$value =~ s/<.*?>//gs; # strip all html tags
+	$value =~ s/\s+/\ /g; # remove extra whitespace
+	$value =~ s/\&\w+\;//g; # remove &nbsp; etc
+    }
+    return $value;
+}
+
+# uses the given tag(s) to identify
+# the caption near to the image
+# (below, above or both below and above)
+sub extract_caption {
+    my ($self, $tag, $bound_tag, $contextref) = (@_);
+    my (@nt, $n, $etag, $gotcap);
+    return ("", "") if ( ! ($$contextref =~ /\Q$tag/) );
+
+    $nt[0] = $`;
+    $nt[1] = $';
+    $gotcap = 0;
+
+    # look before the image for a boundary tag
+    ($etag, $nt[0]) = $nt[0] =~ /<($bound_tag)[\s]?.*?>(.*?)$/is;
+    # if bound_tag too far from the image, then prob not caption
+    # (note: have to allow for tags, so multiply by 3
+    if ( $etag && length($nt[0]) < ($self->{'caption_length'} * 3) ) { 
+	if ( $nt[0] =~ /<\/$etag>/si ) {
+	    # the whole caption is above the image: <tag>text</tag><img>
+	    ($nt[0]) =~ /<(?:$etag)[\s]?.*?>(.*?)<\/$etag>/is;
+	    $nt[0] = $self->strip_tags($nt[0]);
+	    if ( length($nt[0]) > $self->{'min_near_text'} ) { 
+		$gotcap = 1;
+		$nt[1] = ""; 
+	    }
+
+	} elsif ( $nt[1] =~ /<\/$etag>/si) {
+	    # the caption tag covers image: <tag>text?<img>text?</tag>
+	    ($nt[1]) = $nt[1] =~ /(.*?)<\/$etag>/si;
+	    $nt[0] = $self->strip_tags($nt[0] . $nt[1]);
+	    if ( length($nt[0]) > $self->{'min_near_text'} ) { 
+		$gotcap = 2;
+		$nt[1] = "";
+	    }
+	}
+    }
+    # else try below the image
+    if ( ! $gotcap ) { 
+	# the caption is after the image: <img><tag>text</tag>
+	($etag, $nt[1]) = $nt[1] =~ /^.*?<($bound_tag)[\s]?.*?>(.*)/is;
+	if ( $etag && $nt[1] =~ /<\/$etag>/s) {
+	    ($nt[1]) = $nt[1] =~ /(.*?)<\/$etag>/si;
+	    $gotcap = 3;
+	    $nt[0] = "";
+	    $nt[1] = $self->strip_tags($nt[1]);
+	} 
+    }
+    if ( ! $gotcap ) { $nt[0] = $nt[1] = "" }
+    else {
+	# strip part-tags
+	$nt[0] =~ s/^.*>//s;
+	$nt[1] =~ s/<.*$//s;
+    }
+    my ($type);
+    if ( $gotcap == 0 ) { return ("nocaption", "") }
+    elsif ( $gotcap == 1 ) { $type = "captionabove:" }
+    elsif ( $gotcap == 2 ) { $type = "captioncovering:" }
+    elsif ( $gotcap == 3 ) { $type = "captionbelow:" }
+    return ($type, $nt[0], $nt[1]);
+}
+
+# tag-based near text
+# 
+# tries different tag sets
+# and chooses the best one
+sub extract_near_text {
+    my ($self, $tag, $textref, $prevpos, $pos, $nextpos) = (@_);
+    my (@neartext, $len, $hdelim, $maxtext, $mintext, $goodlen,
+	@bestlen, @best, $startpos, $context, $context_size,
+	$dist, $bdist, $best1, $i, $nt);
+    $bestlen[0] = $bestlen[1] = 0; $bestlen[2] = $bdist = 999999;
+    $best[0] = $best[1] = $best[2] = "";
+    $maxtext = $self->{'max_near_text'};
+    $mintext = $self->{'min_near_text'};
+    $goodlen = $self->{'neartext_length'}; 
+
+    # extract a context to extract near text from (faster)
+    $context_size = $maxtext*4;
+    $startpos = $pos - ($context_size / 2);
+    if ($startpos < $prevpos ) { $startpos = $prevpos }
+    if ($nextpos != -1 && $context_size > ( $nextpos - $startpos )) 
+    { $context_size = ($nextpos - $startpos) }
+    $context = substr ( $$textref, $startpos, $context_size );
+    $context =~ s/<!--.*?-->//gs;
+    $context =~ s/^.*-->(.*)/$1/gs;
+    $context =~ s/(.*)<!--.*$/$1/gs;
+
+    # try stepping through markup delimiter sets
+    # and selecting the best one
+    foreach $hdelim ( @{ $self->{'delims'} } ) {
+	@neartext = $self->extract_tagged_neartext($tag, $hdelim, \$context);
+	$nt = join("", @neartext);
+	$len = length($nt);
+	# Priorities:
+	# 1. Greater than mintext 
+	# 2. Less than maxtext 
+	# 3. Closest to goodlen
+	if ( $len <= $goodlen && $len > $bestlen[0] ) {
+	    $bestlen[0] = $len;
+	    $best[0] = $hdelim;
+	} elsif ( $len >= $maxtext && $len < $bestlen[2] ) {
+	    $bestlen[2] = $len;
+	    $best[2] = $hdelim;
+	} elsif ( $len >= $bestlen[0] && $len <= $bestlen[2] ) {
+	    $dist = abs($goodlen - $len);
+	    if ( $dist < $bdist ) {
+		$bestlen[1] = $len;
+		$best[1] = $hdelim;
+		$bdist = $dist;
+	    }
+	}
+    }
+    $best1 = 2;
+    foreach $i ( 0..2 ) {
+	if ( $bestlen[$i] == 999999 ) { $bestlen[$i] = 0 }
+	$dist = abs($goodlen - $bestlen[$i]);
+	if ( $bestlen[$i] > $mintext && $dist <= $bdist ) {
+	    $best1 = $i;
+	    $bdist = $dist;
+	}
+    }
+    @neartext = $self->extract_tagged_neartext($tag, $best[$best1], \$context);
+    if ( $bestlen[$best1] > $maxtext ) {
+	# truncate on word boundary if too much text
+	my $hmax = $maxtext / 2;
+	($neartext[0]) = $neartext[0] =~ /([^\s]*.{1,$hmax})$/s;
+	($neartext[1]) = $neartext[1] =~ /^(.{1,$hmax}[^\s]*)/s;
+    } elsif ( $bestlen[$best1] < $mintext ) {
+	# use plain text extraction if tags failed (e.g. usable tag outside context)
+	print {$self->{'outhandle'}} "HTMLImagePlugin: Fallback to plain-text extraction for $tag\n" 
+	    if $self->{'verbosity'} > 2;
+	$neartext[0] = "<tr><td>RawNeartext</td><td>" . $self->extract_raw_neartext($tag, $textref) . "</td></tr>";
+	$neartext[1] = "";
+    }
+    # get previous header if available
+    $neartext[0] .= "<br>\n" . 
+	$self->get_prev_header($pos, \$context) if ( $self->{'aggressiveness'} >= 4 );
+    $neartext[0] = " " if (! defined $neartext[0]);
+    $neartext[1] = " " if (! defined $neartext[1]);
+
+    return "<tr><td>NearText</td><td>" . (join "|",  @neartext) . "</td></tr>\n"; # TODO: the | is for testing purposes
+} # end extract_near_text
+
+# actually captures tag-based
+# near-text given a tag set
+sub extract_tagged_neartext {
+    my ($self, $tag, $bound_tag, $textref) = (@_);
+    return "" if ( ! ($$textref =~ /\Q$tag/) );
+    my (@nt, $delim, $pre_tag, $n);
+    $nt[0] = $`;
+    $nt[1] = $';
+
+    # get text after previous image tag
+    $nt[0] =~ s/.*<($bound_tag)[^>]*>(.*)/$2/is; # get rid of preceding text
+    if (defined($1)) { $delim = $1 }    
+    $pre_tag = $bound_tag;
+
+    if (defined($delim)) {
+	# we want to try and use the end tag of the previous delimiter
+	# (put it on the front of the list)
+	$pre_tag =~ s/(^|\|)($delim)($|\|)//i; # take it out
+	$pre_tag =~ s/\|\|/\|/i; # replace || with |
+	$pre_tag = $delim . "|" . $pre_tag; # put it on the front
+    }
+    
+    # get text before next image tag
+    $nt[1] =~ s/<\/?(?:$pre_tag)[^>]*>.*//is; # get rid of stuff after first delimiter
+
+    # process related text
+    for $n (0..1) {
+	if ( defined($nt[$n]) ) {
+	    $nt[$n] =~ s/<.*?>//gs; # strip all html tags
+	    $nt[$n] =~ s/\s+/\ /gs; # remove extra whitespace
+	    $nt[$n] =~ s/\&\w+\;//sg; # remove &nbsp; etc
+	    # strip part-tags
+	    if ( $n == 0 ) { $nt[0] =~ s/^.*>//s }
+	    if ( $n == 1 ) { $nt[1] =~ s/<.*$//s }
+	} else { $nt[$n] = ""; } # handle nulls
+    }
+    return @nt;
+}
+
+# this function is fall-back
+# if tags aren't suitable.
+#
+# extracts a fixed length of characters
+# either side of image tag (on word boundary)
+sub extract_raw_neartext {
+    my ($self, $tag, $textref) = (@_);
+    my ($rawtext, $startpos, $fp);
+    my $imgs = \%{$self->{'imglist'}};
+    ($fp) = $tag =~ /([\w\\\/]+\.(?:gif|jpe?g|png))/is;
+    if (! $fp) { return " " };
+    # if the cached, plain-text version isn't there, then create it
+    $self->init_plaintext($textref) unless defined($self->{'plaintext'});
+
+    # take the closest maxtext/2 characters 
+    # either side of the tag (by word boundary)
+    return "" if ( ! exists $imgs->{$fp}{'rawpos'} );
+    $startpos = $imgs->{$fp}{'rawpos'} - (($self->{'max_near_text'} / 2) + 20);
+    if ( $startpos < 0 ) { $startpos = 0 }
+    $rawtext = substr $self->{'plaintext'}, $startpos, $self->{'max_near_text'} + 20;
+    $rawtext =~ s/\s\s/ /g;
+
+    return $rawtext;
+}
+
+# init plaintext variable for HTML-stripped version 
+# (for full text index/raw assoc text extraction)
+sub init_plaintext {
+    my ($self, $textref) = (@_);
+    my ($page, $fp);
+    my $imgs = \%{$self->{'imglist'}};
+    $page = $$textref; # make a copy of original
+
+    # strip tags around image filenames so they don't get zapped
+    $page =~ s/<\w+\s+.*?([\w\/\\]+\.(?:gif|jpe?g|png))[^>]*>/\"$1\"/gsi;
+    $page =~ s/<.*?>//gs;
+    $page =~ s/&nbsp;/ /gs;
+    $page =~ s/&amp;/&/gs; #TODO: more &zzz; replacements (except &lt;, $gt;)
+
+    # get positions and strip images
+    while ( $page =~ /([^\s\'\"]+\.(jpe?g|gif|png))/ig ) {
+	$fp = $1;
+	if ( $imgs->{$fp}{'exists'} ) {
+	    $imgs->{$fp}{'rawpos'} = pos $page;
+	}
+	$page =~ s/\"$fp\"//gs;
+    }
+    $self->{'plaintext'} = $page;
+}
+
+# finds and filters images based on size 
+# (dimensions, height, filesize) and existence
+#
+# looks for image filenames (.jpg, .gif, etc)
+# and checks for existence on disk 
+# (hence supports most JavaScript images)
+sub get_img_list {
+    my $self = shift (@_);
+    my ($textref) = (@_);
+    my ($filepath, $relpath, $abspath, $pos, $num, $width, $height, $filesize);
+    my $imgs = \%{$self->{'imglist'}};
+    while ( $$textref =~ /([^\s\'\"]+\.(jpe?g|gif|png))/ig ) {
+	$filepath = $1;
+	$pos = pos $$textref;
+	next if ( $imgs->{$filepath}{'relpath'} );
+        $relpath = $filepath;
+	$relpath =~ s/^http\:\/\///; # remove http:// in case we have mirrored it
+	$relpath =~ s/\\/\//g;  # replace \ with /
+	$relpath =~ s/^\.\///s; # make "./filepath" into "filepath"
+	$imgs->{$filepath}{'relpath'} = $relpath;
+	$abspath = "$self->{'htpath'}/$relpath";
+
+	if (! -e $abspath) { next }
+
+	# can't modify real filepath var because it
+	# then can't be located in the page for tag recognition later
+	($width, $height) = 
+	    `identify $abspath -ping -format "%wx%h"` =~ /^(\d*)x(\d*)$/m;
+	if (! ($width && $height)) { 
+	    print STDERR "HTMLImagePlugin: ($abspath) 'identify' failed. Check ImageMagicK binaries are installed and working correctly\n"; next;
+	}
+	$filesize = (-s $abspath);
+	if ( $filesize >= $self->{'min_size'} 
+	    && ( $width >= $self->{'min_width'} ) 
+	    && ( $height >= $self->{'min_height'} ) ) {
+	    
+	   $imgs->{$filepath}{'exists'} = 1;
+	   $imgs->{$filepath}{'pos'} = $pos;
+	   $imgs->{$filepath}{'width'} = $width;
+	   $imgs->{$filepath}{'height'} = $height;
+	   $imgs->{$filepath}{'filesize'} = $filesize;
+       } else {
+	   print {$self->{'outhandle'}} "HTMLImagePlugin: skipping $self->{'base_path'}/$relpath: $filesize, $width x $height\n" 
+	       if $self->{'verbosity'} > 2;
+       }
+    }
+    $num = 0;
+    foreach my $i ( keys %{$imgs} ) {
+	if ( $imgs->{$i}{'pos'} ) {
+	    $num++;
+	} else { delete $imgs->{$i} }
+    }
+    return $num;
+}
+
+# make the text available to the read function
+# by making it an object variable
+sub read_file {
+    my ($self, $filename, $encoding, $language, $textref) = @_;
+    $self->SUPER::read_file($filename, $encoding, $language, $textref);
+
+    # if HTMLplug has run through, then it will
+    # have replaced references so we have to 
+    # make a copy of the text before processing
+    if ( $self->{'index_pages'} ) {
+	$self->{'text'} = $$textref;
+	$self->{'textref'} = \($self->{'text'});
+    } else {
+	$self->{'textref'} = $textref;
+    }
+    $self->{'plaintext'} = undef;
+}
+
+# HTMLPlugin only extracts meta-data if it is specified in plugin options
+# hence a special function to do it here
+sub get_meta_value {
+    my ($self, $name, $textref) = @_;
+    my ($value);
+    $name = lc $name;
+    if ($name eq "title") {
+	($value) = $$textref =~ /<title>(.*?)<\/title>/is
+    } else {
+	my $qm = "(?:\"|\')";
+	($value) = $$textref =~ /<meta name\s*=\s*$qm?$name$qm?\s+content\s*=\s*$qm?(.*?)$qm?\s*>/is
+    }
+    $value = "" unless $value;
+    return $value;
+}
+
+# make filename an anchor reference
+# so we can go straight to the image
+# within the cached version of the source page
+# (augment's HTMLPlugin sub)
+sub replace_images {
+    my $self = shift (@_);
+    my ($front, $link, $back, $base_dir, 
+	$file, $doc_obj, $section) = @_;
+    $link =~ s/\"//g;
+    my ($a_name) = $link;
+    $a_name =~ s/[\/\\\:\&]/_/g;
+    # keep a list so we don't repeat the same anchor
+    if ( ! $self->{'imglist'}{$link}{'anchored'} ) {
+	$front = "<a name=\"gsdl_$a_name\">$front";
+	$back = "$back</a>";
+	$self->{'imglist'}{$link}{'anchored'} = 1;
+    }
+    return $self->SUPER::replace_images($front, $link, $back, $base_dir, 
+				     $file, $doc_obj, $section);
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/HTMLPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/HTMLPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/HTMLPlugin.pm	(revision 20131)
@@ -0,0 +1,1549 @@
+###########################################################################
+#
+# HTMLPlugin.pm -- basic html plugin
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# 
+# Note that this plugin handles frames only in a very simple way
+# i.e. each frame is treated as a separate document. This means
+# search results will contain links to individual frames rather
+# than linking to the top level frameset.
+# There may also be some problems caused by the _parent target
+# (it's removed by this plugin)
+#
+
+package HTMLPlugin;
+
+use ReadTextFile;
+use HBPlugin;
+use ghtml;
+use unicode;
+use util;
+use XMLParser;
+
+use Image::Size;
+use File::Copy;
+
+sub BEGIN {
+    @HTMLPlugin::ISA = ('ReadTextFile', 'HBPlugin');
+}
+
+use strict; # every perl program should have this!
+no strict 'refs'; # make an exception so we can use variables as filehandles
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' =>  &get_default_process_exp() },
+      { 'name' => "block_exp",
+	'desc' => "{BasePlugin.block_exp}",
+	'type' => 'regexp',
+	'deft' =>  &get_default_block_exp() },
+      { 'name' => "nolinks",
+	'desc' => "{HTMLPlugin.nolinks}",
+	'type' => "flag" },
+      { 'name' => "keep_head",
+	'desc' => "{HTMLPlugin.keep_head}",
+	'type' => "flag" },
+      { 'name' => "no_metadata",
+	'desc' => "{HTMLPlugin.no_metadata}",
+	'type' => "flag" },
+      { 'name' => "metadata_fields",
+	'desc' => "{HTMLPlugin.metadata_fields}",
+	'type' => "string",
+	'deft' => "Title" },
+      { 'name' => "hunt_creator_metadata",
+	'desc' => "{HTMLPlugin.hunt_creator_metadata}",
+	'type' => "flag" },
+      { 'name' => "file_is_url",
+	'desc' => "{HTMLPlugin.file_is_url}",
+	'type' => "flag" },
+      { 'name' => "assoc_files",
+	'desc' => "{HTMLPlugin.assoc_files}",
+	'type' => "regexp",
+	'deft' => &get_default_block_exp() },
+      { 'name' => "rename_assoc_files",
+	'desc' => "{HTMLPlugin.rename_assoc_files}",
+	'type' => "flag" },
+      { 'name' => "title_sub",
+	'desc' => "{HTMLPlugin.title_sub}",
+	'type' => "string", 
+	'deft' => "" },
+      { 'name' => "description_tags",
+	'desc' => "{HTMLPlugin.description_tags}",
+	'type' => "flag" },
+      # retain this for backward compatibility (w3mir option was replaced by
+      # file_is_url)
+      { 'name' => "w3mir",
+#	'desc' => "{HTMLPlugin.w3mir}",
+	'type' => "flag",
+	'hiddengli' => "yes"},
+      { 'name' => "no_strip_metadata_html",
+	'desc' => "{HTMLPlugin.no_strip_metadata_html}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no"},
+      { 'name' => "sectionalise_using_h_tags",
+	'desc' => "{HTMLPlugin.sectionalise_using_h_tags}",
+	'type' => "flag" },
+      { 'name' => "use_realistic_book",
+        'desc' => "{HTMLPlugin.tidy_html}",
+	'type' => "flag"},
+      { 'name' => "old_style_HDL",
+        'desc' => "{HTMLPlugin.old_style_HDL}",
+	'type' => "flag"}
+      ];
+
+my $options = { 'name'     => "HTMLPlugin",
+		'desc'     => "{HTMLPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub HB_read_html_file {
+    my $self = shift (@_);
+    my ($htmlfile, $text) = @_;
+    
+    # load in the file
+    if (!open (FILE, $htmlfile)) {
+	print STDERR "ERROR - could not open $htmlfile\n";
+	return;
+    }
+
+    my $foundbody = 0;
+    $self->HB_gettext (\$foundbody, $text, "FILE");
+    close FILE;
+    
+    # just in case there was no <body> tag
+    if (!$foundbody) {
+	$foundbody = 1;
+	open (FILE, $htmlfile) || return;
+	$self->HB_gettext (\$foundbody, $text, "FILE");	
+	close FILE;
+    }
+    # text is in utf8
+}		
+
+# converts the text to utf8, as ghtml does that for &eacute; etc.
+sub HB_gettext {
+    my $self = shift (@_);
+    my ($foundbody, $text, $handle) = @_;
+    
+    my $line = "";
+    while (defined ($line = <$handle>)) {
+	# look for body tag
+	if (!$$foundbody) {
+	    if ($line =~ s/^.*<body[^>]*>//i) {
+		$$foundbody = 1;
+	    } else {
+		next;
+	    }
+	}
+	
+	# check for symbol fonts
+	if ($line =~ m/<font [^>]*?face\s*=\s*\"?(\w+)\"?/i) {
+	    my $font = $1;
+	    print STDERR "HBPlug::HB_gettext - warning removed font $font\n" 
+		if ($font !~ m/^arial$/i);
+	}
+
+	$$text .= $line;
+    }
+
+    if ($self->{'input_encoding'} eq "iso_8859_1") {
+	# convert to utf-8
+	$$text=&unicode::unicode2utf8(&unicode::convert2unicode("iso_8859_1", $text));
+    }
+    # convert any alphanumeric character entities to their utf-8
+    # equivalent for indexing purposes
+    #&ghtml::convertcharentities ($$text);
+
+    $$text =~ s/\s+/ /g; # remove \n's
+}
+
+sub HB_clean_section {
+    my $self = shift (@_);
+    my ($section) = @_;
+
+    # remove tags without a starting tag from the section
+    my ($tag, $tagstart);
+    while ($section =~ m/<\/([^>]{1,10})>/) {
+	$tag = $1;
+	$tagstart = index($section, "<$tag");
+	last if (($tagstart >= 0) && ($tagstart < index($section, "<\/$tag")));
+	$section =~ s/<\/$tag>//;
+    }
+    
+    # remove extra paragraph tags
+    while ($section =~ s/<p\b[^>]*>\s*<p\b/<p/ig) {}
+    
+    # remove extra stuff at the end of the section
+    while ($section =~ s/(<u>|<i>|<b>|<p\b[^>]*>|&nbsp;|\s)$//i) {}
+    
+    # add a newline at the beginning of each paragraph
+    $section =~ s/(.)\s*<p\b/$1\n\n<p/gi;
+    
+    # add a newline every 80 characters at a word boundary
+    # Note: this regular expression puts a line feed before
+    # the last word in each section, even when it is not
+    # needed.
+    $section =~ s/(.{1,80})\s/$1\n/g;
+    
+    # fix up the image links
+    $section =~ s/<img[^>]*?src=\"?([^\">]+)\"?[^>]*>/
+	<center><img src=\"$1\" \/><\/center><br\/>/ig;
+    $section =~ s/&lt;&lt;I&gt;&gt;\s*([^\.]+\.(png|jpg|gif))/
+	<center><img src=\"$1\" \/><\/center><br\/>/ig;
+
+    return $section;
+}
+
+# Will convert the oldHDL format to the new HDL format (using the Section tag)	
+sub convert_to_newHDLformat
+{
+    my $self = shift (@_);
+    my ($file,$cnfile) = @_;
+    my $input_filename = $file;
+    my $tmp_filename = $cnfile;
+    
+    # write HTML tmp file with new HDL format
+    open (PROD, ">$tmp_filename") || die("Error Writing to File: $tmp_filename $!");
+    
+    # read in the file and do basic html cleaning (removing header etc)
+    my $html = "";
+    $self->HB_read_html_file ($input_filename, \$html);
+    
+    # process the file one section at a time
+    my $curtoclevel = 1;
+    my $firstsection = 1;
+    my $toclevel = 0;
+    while (length ($html) > 0) {
+	if ($html =~ s/^.*?(?:<p\b[^>]*>)?((<b>|<i>|<u>|\s)*)&lt;&lt;TOC(\d+)&gt;&gt;\s*(.*?)<p\b/<p/i) {
+	    $toclevel = $3;
+	    my $title = $4;
+	    my $sectiontext = "";
+	    if ($html =~ s/^(.*?)((?:<p\b[^>]*>)?((<b>|<i>|<u>|\s)*)&lt;&lt;TOC\d+&gt;&gt;)/$2/i) {
+		$sectiontext = $1;
+	    } else {
+		$sectiontext = $html;
+		$html = "";
+	    }
+
+	    # remove tags and extra spaces from the title
+	    $title =~ s/<\/?[^>]+>//g;
+	    $title =~ s/^\s+|\s+$//g;
+
+	    # close any sections below the current level and
+	    # create a new section (special case for the firstsection)
+	    print PROD "<!--\n";
+	    while (($curtoclevel > $toclevel) ||
+		   (!$firstsection && $curtoclevel == $toclevel)) {
+		$curtoclevel--;
+		print PROD "</Section>\n";
+	    }
+	    if ($curtoclevel+1 < $toclevel) {
+		print STDERR "WARNING - jump in toc levels in $input_filename " . 
+		    "from $curtoclevel to $toclevel\n";
+	    }
+	    while ($curtoclevel < $toclevel) {
+		$curtoclevel++;
+	    }
+
+	    if ($curtoclevel == 1) {
+	    	# add the header tag
+		print PROD "-->\n";
+    		print PROD "<HTML>\n<HEAD>\n<TITLE>$title</TITLE>\n</HEAD>\n<BODY>\n";
+		print PROD "<!--\n";
+	    }
+	    
+	    print PROD "<Section>\n\t<Description>\n\t\t<Metadata name=\"Title\">$title</Metadata>\n\t</Description>\n";
+	    
+	    print PROD "-->\n";
+	    
+	    # clean up the section html
+	    $sectiontext = $self->HB_clean_section($sectiontext);
+
+	    print PROD "$sectiontext\n";	 
+
+	} else {
+	    print STDERR "WARNING - leftover text\n" , $self->shorten($html), 
+	    "\nin $input_filename\n";
+	    last;
+	}
+	$firstsection = 0;
+    }
+    
+    print PROD "<!--\n";
+    while ($curtoclevel > 0) {
+	$curtoclevel--;
+	print PROD "</Section>\n";
+    }
+    print PROD "-->\n";
+    
+    close (PROD) || die("Error Closing File: $tmp_filename $!");
+    
+    return $tmp_filename;
+}		
+
+sub shorten {
+    my $self = shift (@_);
+    my ($text) = @_;
+
+    return "\"$text\"" if (length($text) < 100);
+
+    return "\"" . substr ($text, 0, 50) . "\" ... \"" . 
+	substr ($text, length($text)-50) . "\"";
+}
+
+sub convert_tidy_or_oldHDL_file
+{
+    my $self = shift (@_);
+    my ($file) = @_;
+    my $input_filename = $file;
+    
+    if (-d $input_filename)
+    {
+    	return $input_filename;
+    }
+    
+    # get the input filename
+    my ($tailname, $dirname, $suffix) = &File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
+    my $base_dirname = $dirname;
+    $suffix = lc($suffix);   
+    
+    # derive tmp filename from input filename
+    # Remove any white space from filename -- no risk of name collision, and
+    # makes later conversion by utils simpler. Leave spaces in path...
+    # tidy up the filename with space, dot, hyphen between
+    $tailname =~ s/\s+//g; 
+    $tailname =~ s/\.+//g;
+    $tailname =~ s/\-+//g;
+    # convert to utf-8 otherwise we have problems with the doc.xml file
+    # later on
+    &unicode::ensure_utf8(\$tailname);
+    
+    # softlink to collection tmp dir
+    my $tmp_dirname = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "tidytmp");
+    &util::mk_dir($tmp_dirname) if (!-e $tmp_dirname);
+    
+    my $test_dirname = "";
+    my $f_separator = &util::get_os_dirsep();
+    
+    if ($dirname =~ m/import$f_separator/)
+    {
+    	$test_dirname = $'; #'
+	
+	#print STDERR "init $'\n";
+	
+	while ($test_dirname =~ m/[$f_separator]/)
+	{
+	    my $folderdirname = $`;
+	    $tmp_dirname = &util::filename_cat($tmp_dirname,$folderdirname);
+	    &util::mk_dir($tmp_dirname) if (!-e $tmp_dirname);
+	    $test_dirname = $'; #'
+	}
+    }
+    
+    my $tmp_filename = &util::filename_cat($tmp_dirname, "$tailname$suffix");
+    
+    # tidy or convert the input file if it is a HTML-like file or it is accepted by the process_exp
+    if (($suffix eq ".htm") || ($suffix eq ".html") || ($suffix eq ".shtml"))
+    {   
+    	#convert the input file to a new style HDL
+    	my $hdl_output_filename = $input_filename;
+    	if ($self->{'old_style_HDL'})
+    	{
+	    $hdl_output_filename = &util::filename_cat($tmp_dirname, "$tailname$suffix");
+	    $hdl_output_filename = $self->convert_to_newHDLformat($input_filename,$hdl_output_filename);
+    	}
+	
+	#just for checking copy all other file from the base dir to tmp dir if it is not exists
+	opendir(DIR,$base_dirname) or die "Can't open base directory : $base_dirname!";
+	my @files = grep {!/^\.+$/} readdir(DIR);
+	close(DIR);
+
+	foreach my $file (@files) 
+	{
+	    my $src_file = &util::filename_cat($base_dirname,$file);
+	    my $dest_file = &util::filename_cat($tmp_dirname,$file);
+	    if ((!-e $dest_file) && (!-d $src_file))
+	    {
+		# just copy the original file back to the tmp directory
+		copy($src_file,$dest_file) or die "Can't copy file $src_file to $dest_file $!";
+	    }
+	}
+	
+	# tidy the input file
+	my $tidy_output_filename = $hdl_output_filename;
+	if ($self->{'use_realistic_book'})
+	{
+	    $tidy_output_filename = &util::filename_cat($tmp_dirname, "$tailname$suffix");
+	    $tidy_output_filename = $self->tmp_tidy_file($hdl_output_filename,$tidy_output_filename);
+	}
+	$tmp_filename = $tidy_output_filename;
+    }
+    else
+    {
+    	if (!-e $tmp_filename)
+	{
+	    # just copy the original file back to the tmp directory
+	    copy($input_filename,$tmp_filename) or die "Can't copy file $input_filename to $tmp_filename $!";
+	}
+    }
+    
+    return $tmp_filename;
+}
+
+
+# Will make the html input file as a proper XML file with removed font tag and
+# image size added to the img tag.
+# The tidying process takes place in a collection specific 'tmp' directory so 
+# that we don't accidentally damage the input.
+sub tmp_tidy_file 
+{
+    my $self = shift (@_);
+    my ($file,$cnfile) = @_;
+    my $input_filename = $file;
+    my $tmp_filename = $cnfile;
+    
+    # get the input filename
+    my ($tailname, $dirname, $suffix) = &File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
+
+    require HTML::TokeParser::Simple;
+    
+    # create HTML parser to decode the input file
+    my $parser = HTML::TokeParser::Simple->new($input_filename);
+
+    # write HTML tmp file without the font tag and image size are added to the img tag
+    open (PROD, ">$tmp_filename") || die("Error Writing to File: $tmp_filename $!");
+    while (my $token = $parser->get_token())
+    {
+	# is it an img tag
+	if ($token->is_start_tag('img'))
+	{
+	    # get the attributes
+	    my $attr = $token->return_attr;
+
+	    # get the full path to the image
+	    my $img_file = &util::filename_cat($dirname,$attr->{src});
+	    
+	    # set the width and height attribute
+	    ($attr->{width}, $attr->{height}) = imgsize($img_file);
+
+	    # recreate the tag
+	    print PROD "<img";
+	    print PROD map { qq { $_="$attr->{$_}"} } keys %$attr;
+	    print PROD ">";
+	}
+	# is it a font tag
+	else 
+	{
+	    if (($token->is_start_tag('font')) || ($token->is_end_tag('font')))
+	    {
+		# remove font tag
+		print PROD "";
+	    }
+	    else
+	    {
+		# print without changes
+		print PROD $token->as_is;
+	    }
+	}
+    }
+    close (PROD) || die("Error Closing File: $tmp_filename $!");
+
+    # run html-tidy on the tmp file to make it a proper XML file
+    my $tidyfile = `tidy -utf8 -wrap 0 -asxml "$tmp_filename"`;
+
+    # write result back to the tmp file
+    open (PROD, ">$tmp_filename") || die("Error Writing to File: $tmp_filename $!");
+    print PROD $tidyfile;
+    close (PROD) || die("Error Closing File: $tmp_filename $!");
+    
+    # return the output filename
+    return $tmp_filename;
+} 
+
+sub read_into_doc_obj 
+{
+    my $self = shift (@_);  
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+        
+    # get the input file
+    my $input_filename = $file;
+    my ($tailname, $dirname, $suffix) = &File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
+    $suffix = lc($suffix);   
+    
+    if (($self->{'use_realistic_book'}) || ($self->{'old_style_HDL'}))
+    {
+	# because the document has to be sectionalized set the description tags 
+	$self->{'description_tags'} = 1;
+	
+	# set the file to be tidied
+	$input_filename = &util::filename_cat($base_dir,$file) if $base_dir =~ m/\w/;
+	
+	# get the tidied file
+	#my $tidy_filename = $self->tmp_tidy_file($input_filename);
+	my $tidy_filename = $self->convert_tidy_or_oldHDL_file($input_filename);
+	
+	# derive tmp filename from input filename
+	my ($tailname, $dirname, $suffix) = &File::Basename::fileparse($tidy_filename, "\\.[^\\.]+\$");
+	
+	# set the new input file and base_dir to be from the tidied file
+	$file = "$tailname$suffix";
+	$base_dir = $dirname;
+    }
+    
+    # call the parent read_into_doc_obj
+    my ($process_status,$doc_obj) = $self->SUPER::read_into_doc_obj($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli);
+    
+    return ($process_status,$doc_obj);
+}
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+    
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+    
+
+    my $self = new ReadTextFile($pluginlist,$inputargs,$hashArgOptLists);
+    
+    if ($self->{'w3mir'}) {
+	$self->{'file_is_url'} = 1;
+    }
+    $self->{'aux_files'} = {};
+    $self->{'dir_num'} = 0;
+    $self->{'file_num'} = 0;
+    
+    return bless $self, $class;
+}
+
+# may want to use (?i)\.(gif|jpe?g|jpe|png|css|js(?:@.*)?)$
+# if have eg <script language="javascript" src="img/lib.js@123">
+sub get_default_block_exp {
+    my $self = shift (@_);
+    
+    #return q^(?i)\.(gif|jpe?g|jpe|jpg|png|css)$^;
+    return "";
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+    
+    # the last option is an attempt to encode the concept of an html query ...
+    return q^(?i)(\.html?|\.shtml|\.shm|\.asp|\.php\d?|\.cgi|.+\?.+=.*)$^;
+}
+
+sub store_block_files
+{
+    my $self =shift (@_);
+    my ($filename_full_path, $block_hash) = @_;
+
+    my $html_fname = $filename_full_path;
+    my @file_blocks;
+    
+    my ($language, $encoding) = $self->textcat_get_language_encoding ($filename_full_path);
+
+    # read in file ($text will be in utf8)
+    my $raw_text = "";
+    $self->read_file_no_decoding ($filename_full_path, \$raw_text);
+
+    my $textref = \$raw_text;
+    my $opencom = '(?:<!--|&lt;!(?:&mdash;|&#151;|--))';
+    my $closecom = '(?:-->|(?:&mdash;|&#151;|--)&gt;)';
+    $$textref =~ s/$opencom(.*?)$closecom//gs;
+
+    my $attval = "\\\"[^\\\"]+\\\"|[^\\s>]+";
+    my @img_matches = ($$textref =~ m/<img[^>]*?src\s*=\s*($attval)[^>]*>/igs);
+    my @usemap_matches = ($$textref =~ m/<img[^>]*?usemap\s*=\s*($attval)[^>]*>/igs);
+    my @link_matches = ($$textref =~ m/<link[^>]*?href\s*=\s*($attval)[^>]*>/igs);
+    my @embed_matches = ($$textref =~ m/<embed[^>]*?src\s*=\s*($attval)[^>]*>/igs);
+    my @tabbg_matches = ($$textref =~ m/<(?:body|table|tr|td)[^>]*?background\s*=\s*($attval)[^>]*>/igs);
+    my @script_matches = ($$textref =~ m/<script[^>]*?src\s*=\s*($attval)[^>]*>/igs);
+
+    if(!defined $self->{'utf8_to_original_filename'}) { 
+	# maps from utf8 converted link name -> original filename referrred to by (possibly URL-encoded) src url
+	$self->{'utf8_to_original_filename'} = {};
+    }
+
+    foreach my $link (@img_matches, @usemap_matches, @link_matches, @embed_matches, @tabbg_matches, @script_matches) {
+
+	# remove quotes from link at start and end if necessary
+	if ($link=~/^\"/) {
+	    $link=~s/^\"//;
+	    $link=~s/\"$//;
+	}
+
+	$link =~ s/\#.*$//s; # remove any anchor names, e.g. foo.html#name becomes foo.html
+	# some links may just be anchor names
+	next unless ($link =~ /\S+/);
+
+	if ($link !~ m@^/@ && $link !~ m/^([A-Z]:?)\\/) {
+	    # Turn relative file path into full path
+	    my $dirname = &File::Basename::dirname($filename_full_path);
+	    $link = &util::filename_cat($dirname, $link);
+	}
+	$link = $self->eval_dir_dots($link);
+
+	# this is the actual filename on the filesystem (that the link refers to)
+	my $url_original_filename = $self->opt_url_decode($link);
+
+	# Convert the url_original_filename into its utf8 version. Store the utf8 link along with the url_original_filename
+	my $utf8_link = "";
+	$self->decode_text($link,$encoding,$language,\$utf8_link);
+
+	$self->{'utf8_to_original_filename'}->{$utf8_link} = $url_original_filename;
+#	print STDERR "**** utf8_encoded_link to original src filename:\n\t$utf8_link\n\t".$self->{'utf8_to_original_filename'}->{$utf8_link}."\n";
+
+	if ($url_original_filename ne $utf8_link) {
+	    my $outhandle = $self->{'outhandle'};
+
+	    print $outhandle "URL Encoding $url_original_filename\n";
+	    print $outhandle " ->$utf8_link\n";
+	}
+
+	$block_hash->{'file_blocks'}->{$url_original_filename} = 1;
+    }
+}
+
+# Given a filename in any encoding, will URL decode it to get back the original filename
+# in the original encoding. Because this method is intended to work out the *original* 
+# filename*, it does not URL decode any filename if a file by the name of the *URL-encoded*
+# string already exists in the local folder.
+# Return the original filename corresponding to the parameter URL-encoded filename, and
+# a decoded flag that is set to true iff URL-decoding had to be applied.
+sub opt_url_decode {
+    my $self = shift (@_);
+    my ($link) = @_;
+
+    # Replace %XX's in URL with decoded value if required.
+    # Note that the filename may include the %XX in some situations
+    if ($link =~ m/\%[A-F0-9]{2}/i) {
+	if (!-e $link) {
+	    $link = &unicode::url_decode($link);
+	}
+    } 
+
+    return $link;
+}
+
+
+# do plugin specific processing of doc_obj
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    if ($ENV{'GSDLOS'} =~ m/^windows/i) {
+	# this makes life so much easier... perl can cope with unix-style '/'s.
+	$base_dir =~ s@(\\)+@/@g;
+	$file =~ s@(\\)+@/@g; 
+    }
+    
+    # reset per-doc stuff...
+    $self->{'aux_files'} = {};
+    $self->{'dir_num'} = 0;
+    $self->{'file_num'} = 0;
+
+    # process an HTML file where sections are divided by headings tags (H1, H2 ...)
+    # you can also include metadata in the format (X can be any number)
+    # <hX>Title<!--gsdl-metadata
+    #	<Metadata name="name1">value1</Metadata>
+    #	...
+    #	<Metadata name="nameN">valueN</Metadata>
+    #--></hX>
+    if ($self->{'sectionalise_using_h_tags'}) {
+	# description_tags should allways be activated because we convert headings to description tags
+	$self->{'description_tags'} = 1;
+
+	my $arrSections = [];
+	$$textref =~ s/<h([0-9]+)[^>]*>(.*?)<\/h[0-9]+>/$self->process_heading($1, $2, $arrSections, $file)/isge;
+
+	if (scalar(@$arrSections)) {
+	    my $strMetadata = $self->update_section_data($arrSections, -1);
+	    if (length($strMetadata)) {
+		$strMetadata = '<!--' . $strMetadata . "\n-->\n</body>";
+		$$textref =~ s/<\/body>/$strMetadata/ig;
+	    }
+	}
+    }
+
+    my $cursection = $doc_obj->get_top_section();
+
+    $self->extract_metadata ($textref, $metadata, $doc_obj, $cursection)
+	unless $self->{'no_metadata'} || $self->{'description_tags'};
+
+    # Store URL for page as metadata - this can be used for an
+    # altavista style search interface. The URL won't be valid
+    # unless the file structure contains the domain name (i.e.
+    # like when w3mir is used to download a website).
+
+    # URL metadata (even invalid ones) are used to support internal
+    # links, so even if 'file_is_url' is off, still need to store info
+
+    my ($tailname,$dirname,$suffix) = &File::Basename::fileparse($file, "\\.[^\\.]+\$");
+    my $utf8_file = $self->filename_to_utf8_metadata($file);
+    $utf8_file =~ s/&\#095;/_/g;
+    my $web_url = "http://";
+    if(defined $dirname) { # local directory
+	$dirname = $self->eval_dir_dots($dirname);
+	$dirname .= &util::get_dirsep() if $dirname ne ""; # if there's a directory, it should end on "/"
+	$web_url = $web_url.$dirname.$utf8_file; 
+    } else {
+	$web_url = $web_url.$utf8_file;
+    }
+    $web_url =~ s/\\/\//g;
+    $doc_obj->add_utf8_metadata($cursection, "URL", $web_url);
+
+    if ($self->{'file_is_url'}) {
+	$doc_obj->add_metadata($cursection, "weblink", "<a href=\"$web_url\">");
+	$doc_obj->add_metadata($cursection, "webicon", "_iconworld_");
+	$doc_obj->add_metadata($cursection, "/weblink", "</a>");
+    }
+
+    if ($self->{'description_tags'}) {
+	# remove the html header - note that doing this here means any
+	# sections defined within the header will be lost (so all <Section>
+	# tags must appear within the body of the HTML)
+	my ($head_keep) = ($$textref =~ m/^(.*?)<body[^>]*>/is);
+
+	$$textref =~ s/^.*?<body[^>]*>//is;
+	$$textref =~ s/(<\/body[^>]*>|<\/html[^>]*>)//isg;
+
+	my $opencom = '(?:<!--|&lt;!(?:&mdash;|&#151;|--))';
+	my $closecom = '(?:-->|(?:&mdash;|&#151;|--)&gt;)';
+
+	my $lt = '(?:<|&lt;)';
+	my $gt = '(?:>|&gt;)';
+	my $quot = '(?:"|&quot;|&rdquo;|&ldquo;)';
+
+	my $dont_strip = '';
+	if ($self->{'no_strip_metadata_html'}) {
+	    ($dont_strip = $self->{'no_strip_metadata_html'}) =~ s{,}{|}g;
+	}
+
+	my $found_something = 0; my $top = 1;
+	while ($$textref =~ s/^(.*?)$opencom(.*?)$closecom//s) {
+	    my $text = $1;
+	    my $comment = $2;
+	    if (defined $text) {
+		# text before a comment - note that getting to here
+		# doesn't necessarily mean there are Section tags in
+		# the document
+		$self->process_section(\$text, $base_dir, $file, $doc_obj, $cursection);
+	    }
+	    while ($comment =~ s/$lt(.*?)$gt//s) {
+		my $tag = $1;
+		if ($tag eq "Section") {
+		    $found_something = 1;
+		    $cursection = $doc_obj->insert_section($doc_obj->get_end_child($cursection)) unless $top;
+		    $top = 0;
+		} elsif ($tag eq "/Section") {
+		    $found_something = 1;
+		    $cursection = $doc_obj->get_parent_section ($cursection);
+		} elsif ($tag =~ m/^Metadata name=$quot(.*?)$quot/s) {
+		    my $metaname = $1;
+		    my $accumulate = $tag =~ m/mode=${quot}accumulate${quot}/ ? 1 : 0;
+		    $comment =~ s/^(.*?)$lt\/Metadata$gt//s;
+		    my $metavalue = $1;
+		    $metavalue =~ s/^\s+//;
+		    $metavalue =~ s/\s+$//;
+                    # assume that no metadata value intentionally includes
+                    # carriage returns or HTML tags (if they're there they
+                    # were probably introduced when converting to HTML from
+                    # some other format).
+		    # actually some people want to have html tags in their
+		    # metadata.
+		    $metavalue =~ s/[\cJ\cM]/ /sg;
+		    $metavalue =~ s/<[^>]+>//sg
+			unless $dont_strip && ($dont_strip eq 'all' || $metaname =~ m/^($dont_strip)$/);
+		    $metavalue =~ s/\s+/ /sg;
+		    if ($accumulate) {
+			$doc_obj->add_utf8_metadata($cursection, $metaname, $metavalue);
+		    } else {
+			$doc_obj->set_utf8_metadata_element($cursection, $metaname, $metavalue);	
+		    }
+		} elsif ($tag eq "Description" || $tag eq "/Description") {
+		    # do nothing with containing Description tags
+		} else {
+		    # simple HTML tag (probably created by the conversion
+		    # to HTML from some other format) - we'll ignore it and
+		    # hope for the best ;-)
+		}
+	    }
+	}
+	if ($cursection ne "") {
+	    print $outhandle "HTMLPlugin: WARNING: $file contains unmatched <Section></Section> tags\n";
+	}
+
+	$$textref =~ s/^.*?<body[^>]*>//is;
+	$$textref =~ s/(<\/body[^>]*>|<\/html[^>]*>)//isg;
+	if ($$textref =~ m/\S/) {
+	    if (!$found_something) {
+		if ($self->{'verbosity'} > 2) {
+		    print $outhandle "HTMLPlugin: WARNING: $file appears to contain no Section tags so\n";
+		    print $outhandle "          will be processed as a single section document\n";
+		}
+
+		# go ahead and process single-section document
+		$self->process_section($textref, $base_dir, $file, $doc_obj, $cursection);
+
+		# if document contains no Section tags we'll go ahead
+		# and extract metadata (this won't have been done
+		# above as the -description_tags option prevents it)
+		my $complete_text = $head_keep.$doc_obj->get_text($cursection);
+		$self->extract_metadata (\$complete_text, $metadata, $doc_obj, $cursection) 
+		    unless $self->{'no_metadata'};
+
+	    } else {
+		print $outhandle "HTMLPlugin: WARNING: $file contains the following text outside\n";
+		print $outhandle "          of the final closing </Section> tag. This text will\n";
+		print $outhandle "          be ignored.";
+
+		my ($text);
+		if (length($$textref) > 30) {
+		    $text = substr($$textref, 0, 30) . "...";
+		} else {
+		    $text = $$textref;
+		}
+		$text =~ s/\n/ /isg;
+		print $outhandle " ($text)\n";
+	    }
+	} elsif (!$found_something) {
+
+	    if ($self->{'verbosity'} > 2) {
+		# may get to here if document contained no valid Section
+		# tags but did contain some comments. The text will have
+		# been processed already but we should print the warning
+		# as above and extract metadata
+		print $outhandle "HTMLPlugin: WARNING: $file appears to contain no Section tags and\n";
+		print $outhandle "          is blank or empty.  Metadata will be assigned if present.\n";
+	    }
+
+	    my $complete_text = $head_keep.$doc_obj->get_text($cursection);
+	    $self->extract_metadata (\$complete_text, $metadata, $doc_obj, $cursection) 
+		unless $self->{'no_metadata'};
+	}
+	
+    } else {
+
+	# remove header and footer
+	if (!$self->{'keep_head'} || $self->{'description_tags'}) {
+	    $$textref =~ s/^.*?<body[^>]*>//is;
+	    $$textref =~ s/(<\/body[^>]*>|<\/html[^>]*>)//isg;
+	}
+
+	# single section document
+	$self->process_section($textref, $base_dir, $file, $doc_obj, $cursection);
+    }
+    return 1;
+}
+
+
+sub process_heading
+{
+    my ($self, $nHeadNo, $strHeadingText, $arrSections, $file) = @_;
+    $strHeadingText = '' if (!defined($strHeadingText));
+
+    my $strMetadata = $self->update_section_data($arrSections, int($nHeadNo));
+
+    my $strSecMetadata = '';
+    while ($strHeadingText =~ s/<!--gsdl-metadata(.*?)-->//is)
+    {
+	$strSecMetadata .= $1;
+    }
+
+    $strHeadingText =~ s/^\s+//g;
+    $strHeadingText =~ s/\s+$//g;
+    $strSecMetadata =~ s/^\s+//g;
+    $strSecMetadata =~ s/\s+$//g;
+
+    $strMetadata .= "\n<Section>\n\t<Description>\n\t\t<Metadata name=\"Title\">" . $strHeadingText . "</Metadata>\n";
+
+    if (length($strSecMetadata)) {
+	$strMetadata .= "\t\t" . $strSecMetadata . "\n";
+    }
+
+    $strMetadata .= "\t</Description>\n";
+
+    return "<!--" . $strMetadata . "-->";
+}
+
+
+sub update_section_data
+{
+    my ($self, $arrSections, $nCurTocNo) = @_;
+    my ($strBuffer, $nLast, $nSections) = ('', 0, scalar(@$arrSections));
+
+    if ($nSections == 0) {
+	push @$arrSections, $nCurTocNo;
+	return $strBuffer;
+    }
+    $nLast = $arrSections->[$nSections - 1];
+    if ($nCurTocNo > $nLast) {
+	push @$arrSections, $nCurTocNo;
+	return $strBuffer;
+    }
+    for(my $i = $nSections - 1; $i >= 0; $i--) {
+	if ($nCurTocNo <= $arrSections->[$i]) {
+	    $strBuffer .= "\n</Section>";
+	    pop @$arrSections;
+	}
+    }
+    push @$arrSections, $nCurTocNo;
+    return $strBuffer;
+}
+
+
+# note that process_section may be called multiple times for a single
+# section (relying on the fact that add_utf8_text appends the text to any
+# that may exist already).
+sub process_section {
+    my $self = shift (@_);
+    my ($textref, $base_dir, $file, $doc_obj, $cursection) = @_;
+    # trap links
+    if (!$self->{'nolinks'}) {
+	# usemap="./#index" not handled correctly => change to "#index"
+##	$$textref =~ s/(<img[^>]*?usemap\s*=\s*[\"\']?)([^\"\'>\s]+)([\"\']?[^>]*>)/
+
+	$$textref =~ s/(<img[^>]*?usemap\s*=\s*)((?:[\"][^\"]+[\"])|(?:[\'][^\']+[\'])|(?:[^\s\/>]+))([^>]*>)/
+	    $self->replace_usemap_links($1, $2, $3)/isge;
+
+##	$$textref =~ s/(<(?:a|area|frame|link|script)\s+[^>]*?\s*(?:href|src)\s*=\s*[\"\']?)([^\"\'>\s]+)([\"\']?[^>]*>)/
+
+	$$textref =~ s/(<(?:a|area|frame|link|script)\s+[^>]*?\s*(?:href|src)\s*=\s*)((?:[\"][^\"]+[\"])|(?:[\'][^\']+[\'])|(?:[^\s\/>]+))([^>]*>)/
+	    $self->replace_href_links ($1, $2, $3, $base_dir, $file, $doc_obj, $cursection)/isge;
+    }
+
+    # trap images
+
+    # Previously, by default, HTMLPlugin would embed <img> tags inside anchor tags
+    # i.e. <a href="image><img src="image"></a> in order to overcome a problem that
+    # turned regular text succeeding images into links. That is, by embedding <imgs>
+    # inside <a href=""></a>, the text following images were no longer misbehaving.
+    # However, there would be many occasions whereby images were not meant to link
+    # to their source images but where the images would link to another web page.
+    # To allow this, the no_image_links option was introduced: it would prevent
+    # the behaviour of embedding images into links that referenced the source images.
+
+    # Somewhere along the line, the problem of normal text turning into links when 
+    # such text followed images which were not embedded in <a href=""></a> ceased 
+    # to occur. This is why the following lines have been commented out (as well as 
+    # two lines in replace_images). They appear to no longer apply.
+
+    # If at any time, there is a need for having images embedded in <a> anchor tags,
+    # then it might be better to turn that into an HTMLPlugin option rather than make
+    # it the default behaviour. Also, eventually, no_image_links needs to become
+    # a deprecated option for HTMLPlugin as it has now become the default behaviour.
+
+    #if(!$self->{'no_image_links'}){
+    $$textref =~ s/(<(?:img|embed|table|tr|td)[^>]*?(?:src|background)\s*=\s*)((?:[\"][^\"]+[\"])|(?:[\'][^\']+[\'])|(?:[^\s\/>]+))([^>]*>)/
+	$self->replace_images ($1, $2, $3, $base_dir, $file, $doc_obj, $cursection)/isge;
+    #}
+
+    # add text to document object
+    # turn \ into \\ so that the rest of greenstone doesn't think there
+    # is an escape code following. (Macro parsing loses them...)
+    $$textref =~ s/\\/\\\\/go;
+    
+    $doc_obj->add_utf8_text($cursection, $$textref);
+}
+
+sub replace_images {
+    my $self = shift (@_);
+    my ($front, $link, $back, $base_dir, 
+	$file, $doc_obj, $section) = @_;
+
+    # remove quotes from link at start and end if necessary
+    if ($link=~/^[\"\']/) {
+	$link=~s/^[\"\']//;
+	$link=~s/[\"\']$//;
+	$front.='"';
+	$back="\"$back";
+    }
+
+    $link =~ s/\n/ /g;
+
+    # Hack to overcome Windows wv 0.7.1 bug that causes embedded images to be broken
+    # If the Word file path has spaces in it, wv messes up and you end up with
+    #   absolute paths for the images, and without the "file://" prefix
+    # So check for this special case and massage the data to be correct
+    if ($ENV{'GSDLOS'} =~ m/^windows/i && $self->{'plugin_type'} eq "WordPlug" && $link =~ m/^[A-Za-z]\:\\/) {
+	$link =~ s/^.*\\([^\\]+)$/$1/;
+    }
+    
+    my ($href, $hash_part, $rl) = $self->format_link ($link, $base_dir, $file);
+
+    my $img_file =  $self->add_file ($href, $rl, $hash_part, $base_dir, $doc_obj, $section);
+
+#    print STDERR "**** link = $link\n**** href = $href\n**** img_file = $img_file, rl = $rl\n";
+
+    my $anchor_name = $img_file;
+    #$anchor_name =~ s/^.*\///;
+    #$anchor_name = "<a name=\"$anchor_name\" ></a>";
+
+    my $image_link = $front . $img_file .$back;
+    return $image_link;
+
+    # The reasons for why the following two lines are no longer necessary can be 
+    # found in subroutine process_section
+    #my $anchor_link = "<a href=\"$img_file\" >".$image_link."</a>";  
+    #return $anchor_link;	
+    
+    #return $front . $img_file . $back . $anchor_name;
+}
+
+sub replace_href_links {
+    my $self = shift (@_);
+    my ($front, $link, $back, $base_dir, $file, $doc_obj, $section) = @_;
+
+    # remove quotes from link at start and end if necessary
+    if ($link=~/^[\"\']/) {
+	$link=~s/^[\"\']//;
+	$link=~s/[\"\']$//;
+	$front.='"';
+	$back="\"$back";
+    }
+
+    # attempt to sort out targets - frames are not handled 
+    # well in this plugin and some cases will screw things
+    # up - e.g. the _parent target (so we'll just remove 
+    # them all ;-)
+    $front =~ s/(target=\"?)_top(\"?)/$1_gsdltop_$2/is;
+    $back =~ s/(target=\"?)_top(\"?)/$1_gsdltop_$2/is;
+    $front =~ s/target=\"?_parent\"?//is;
+    $back =~ s/target=\"?_parent\"?//is;
+
+    return $front . $link . $back if $link =~ m/^\#/s;
+    $link =~ s/\n/ /g;
+
+    # Find file referred to by $link on file system 
+    # This is more complicated than it sounds when char encodings
+    # is taken in to account
+    my ($href, $hash_part, $rl) = $self->format_link ($link, $base_dir, $file);
+ 
+    # href may use '\'s where '/'s should be on Windows
+    $href =~ s/\\/\//g;
+    my ($filename) = $href =~ m/^(?:.*?):(?:\/\/)?(.*)/;
+    
+
+    ##### leave all these links alone (they won't be picked up by intermediate 
+    ##### pages). I think that's safest when dealing with frames, targets etc.
+    ##### (at least until I think of a better way to do it). Problems occur with
+    ##### mailto links from within small frames, the intermediate page is displayed
+    ##### within that frame and can't be seen. There is still potential for this to
+    ##### happen even with html pages - the solution seems to be to somehow tell
+    ##### the browser from the server side to display the page being sent (i.e. 
+    ##### the intermediate page) in the top level window - I'm not sure if that's 
+    ##### possible - the following line should probably be deleted if that can be done
+    return $front . $link . $back if $href =~ m/^(mailto|news|gopher|nntp|telnet|javascript):/is;
+
+
+    if (($rl == 0) || ($filename =~ m/$self->{'process_exp'}/) || 
+	($href =~ m/\/$/) || ($href =~ m/^(mailto|news|gopher|nntp|telnet|javascript):/i)) {
+	&ghtml::urlsafe ($href);
+	return $front . "_httpextlink_&amp;rl=" . $rl . "&amp;href=" . $href . $hash_part . $back;
+    } else {
+	# link is to some other type of file (eg image) so we'll
+	# need to associate that file
+	return $front . $self->add_file ($href, $rl, $hash_part, $base_dir, $doc_obj, $section) . $back;
+    }
+}
+
+sub add_file {
+    my $self = shift (@_);
+    my ($href, $rl, $hash_part, $base_dir, $doc_obj, $section) = @_;
+    my ($newname);
+
+    my $filename = $href;
+    if ($base_dir eq "") {
+	# remove http:/ thereby leaving one slash at the start
+	$filename =~ s/^[^:]*:\///;
+    }
+    else {
+	# remove http://
+	$filename =~ s/^[^:]*:\/\///;
+    }
+
+    $filename = &util::filename_cat($base_dir, $filename);
+    # Replace %XX's in URL with decoded value if required. Note that the filename may include the %XX in some
+    # situations. If the *original* file's name was in URL encoding, the following method will not decode it.
+    my $utf8_filename = $filename;
+    $filename = $self->opt_url_decode($utf8_filename);
+
+    # some special processing if the intended filename was converted to utf8, but
+    # the actual file still needs to be renamed
+    if (!-e $filename) {
+	# try the original filename stored in map
+	my $original_filename = $self->{'utf8_to_original_filename'}->{$filename};
+	if (defined $original_filename && -e $original_filename) {
+	    $filename = $original_filename;
+	}
+    }
+    
+    my ($ext) = $filename =~ m/(\.[^\.]*)$/;
+
+    if ($rl == 0) {
+	if ((!defined $ext) || ($ext !~ m/$self->{'assoc_files'}/)) {
+	    return "_httpextlink_&amp;rl=0&amp;el=prompt&amp;href=" . $href . $hash_part;
+	}
+	else {
+	    return "_httpextlink_&amp;rl=0&amp;el=direct&amp;href=" . $href . $hash_part;
+	}
+    }
+
+    if ((!defined $ext) || ($ext !~ m/$self->{'assoc_files'}/)) {
+	return "_httpextlink_&amp;rl=" . $rl . "&amp;href=" . $href . $hash_part;
+    }
+    if ($self->{'rename_assoc_files'}) {
+	if (defined $self->{'aux_files'}->{$href}) {
+	    $newname = $self->{'aux_files'}->{$href}->{'dir_num'} . "/" .
+		$self->{'aux_files'}->{$href}->{'file_num'} . $ext;
+	} else {
+	    $newname = $self->{'dir_num'} . "/" . $self->{'file_num'} . $ext;
+	    $self->{'aux_files'}->{$href} = {'dir_num' => $self->{'dir_num'}, 'file_num' => $self->{'file_num'}};
+	    $self->inc_filecount ();
+	}
+	$doc_obj->associate_file($filename, $newname, undef, $section);
+	return "_httpdocimg_/$newname";
+    } else {
+	if(&unicode::is_url_encoded($utf8_filename)) {
+	    # use the possibly-decoded filename instead to avoid double URL encoding
+	    ($newname) = $filename =~ m/([^\/\\]*)$/;
+	} else {
+	    ($newname) = $utf8_filename =~ m/([^\/\\]*)$/;
+	}
+
+	# Make sure this name uses only ASCII characters. 
+	# We use either base64 or URL encoding, as these preserve original encoding
+	$newname = &util::rename_file($newname, $self->{'file_rename_method'});
+
+	$doc_obj->associate_file($filename, $newname, undef, $section);
+
+	# Since the generated image will be URL-encoded to avoid file-system/browser mess-ups
+	# of filenames, URL-encode the additional percent signs of the URL-encoded filename
+	my $newname_url = $newname;
+	$newname_url = &unicode::filename_to_url($newname_url);
+	return "_httpdocimg_/$newname_url";	
+    }
+}
+
+
+sub format_link {
+    my $self = shift (@_);
+    my ($link, $base_dir, $file) = @_;
+
+    my ($before_hash, $hash_part) = $link =~ m/^([^\#]*)(\#?.*)$/;
+    
+    $hash_part = "" if !defined $hash_part;
+    if (!defined $before_hash || $before_hash !~ m/[\w\.\/]/) {
+	my $outhandle = $self->{'outhandle'};
+	print $outhandle "HTMLPlugin: ERROR - badly formatted tag ignored ($link)\n"
+	    if $self->{'verbosity'};
+	return ($link, "", 0);
+    }
+
+    if ($before_hash =~ s@^((?:http|ftp|file)://)@@i) {
+	my $type = $1;
+
+	if ($link =~ m/^(http|ftp):/i) {
+	    # Turn url (using /) into file name (possibly using \ on windows)
+	    my @http_dir_split = split('/', $before_hash);
+	    $before_hash = &util::filename_cat(@http_dir_split);
+	}
+
+	$before_hash = $self->eval_dir_dots($before_hash);
+	
+	my $linkfilename = &util::filename_cat ($base_dir, $before_hash);
+	
+	my $rl = 0;
+	$rl = 1 if (-e $linkfilename);
+
+	# make sure there's a slash on the end if it's a directory
+	if ($before_hash !~ m/\/$/) {
+	    $before_hash .= "/" if (-d $linkfilename);
+	}
+	return ($type . $before_hash, $hash_part, $rl);
+	
+    } elsif ($link !~ m/^(mailto|news|gopher|nntp|telnet|javascript):/i && $link !~ m/^\//) {
+
+	if ($before_hash =~ s@^/@@ || $before_hash =~ m/\\/) {
+
+	    # the first directory will be the domain name if file_is_url
+	    # to generate archives, otherwise we'll assume all files are
+	    # from the same site and base_dir is the root
+
+	    if ($self->{'file_is_url'}) {
+		my @dirs = split /[\/\\]/, $file;
+		my $domname = shift (@dirs);
+		$before_hash = &util::filename_cat($domname, $before_hash);
+		$before_hash =~ s@\\@/@g; # for windows
+	    }
+	    else
+	    {
+		# see if link shares directory with source document
+		# => turn into relative link if this is so!
+		
+		if ($ENV{'GSDLOS'} =~ m/^windows/i) {
+		    # too difficult doing a pattern match with embedded '\'s...
+		    my $win_before_hash=$before_hash;
+		    $win_before_hash =~ s@(\\)+@/@g;
+		    # $base_dir is already similarly "converted" on windows.
+		    if ($win_before_hash =~ s@^$base_dir/@@o) {
+			# if this is true, we removed a prefix
+			$before_hash=$win_before_hash;
+		    }
+		}
+		else {
+		    # before_hash has lost leading slash by this point,
+		    # -> add back in prior to substitution with $base_dir
+		    $before_hash = "/$before_hash"; 
+
+		    $before_hash = &util::filename_cat("",$before_hash);
+		    $before_hash =~ s@^$base_dir/@@;
+		}
+	    }
+	} else {
+	    # Turn relative file path into full path
+	    my $dirname = &File::Basename::dirname($file);
+	    $before_hash = &util::filename_cat($dirname, $before_hash);
+	    $before_hash = $self->eval_dir_dots($before_hash);	    	    
+	}
+
+	my $linkfilename = &util::filename_cat ($base_dir, $before_hash); 
+	# make sure there's a slash on the end if it's a directory
+	if ($before_hash !~ m/\/$/) {
+	    $before_hash .= "/" if (-d $linkfilename);
+	}
+	return ("http://" . $before_hash, $hash_part, 1);
+    } else {
+	# mailto, news, nntp, telnet, javascript or gopher link
+	return ($before_hash, "", 0);
+    }
+}
+
+sub extract_first_NNNN_characters {
+    my $self = shift (@_);
+    my ($textref, $doc_obj, $thissection) = @_;
+    
+    foreach my $size (split /,/, $self->{'first'}) {
+	my $tmptext =  $$textref;
+	# skip to the body
+	$tmptext =~ s/.*<body[^>]*>//i;
+	# remove javascript
+	$tmptext =~ s@<script.*?</script>@ @sig;
+	$tmptext =~ s/<[^>]*>/ /g;
+	$tmptext =~ s/&nbsp;/ /g;
+	$tmptext =~ s/^\s+//;
+	$tmptext =~ s/\s+$//;
+	$tmptext =~ s/\s+/ /gs;
+	$tmptext = &unicode::substr ($tmptext, 0, $size);
+	$tmptext =~ s/\s\S*$/&#8230;/; # adds an ellipse (...)
+	$doc_obj->add_utf8_metadata ($thissection, "First$size", $tmptext);
+    }
+}
+
+
+sub extract_metadata {
+    my $self = shift (@_);
+    my ($textref, $metadata, $doc_obj, $section) = @_;
+    my $outhandle = $self->{'outhandle'};
+    # if we don't want metadata, we may as well not be here ...
+    return if (!defined $self->{'metadata_fields'});
+
+    # metadata fields to extract/save. 'key' is the (lowercase) name of the
+    # html meta, 'value' is the metadata name for greenstone to use
+    my %find_fields = ();
+
+    my %creator_fields = (); # short-cut for lookups
+
+
+    foreach my $field (split /,/, $self->{'metadata_fields'}) {
+        $field =~ s/^\s+//; # remove leading whitespace
+        $field =~ s/\s+$//; # remove trailing whitespace
+
+	# support tag<tagname>
+	if ($field =~ m/^(.*?)<(.*?)>$/) {
+	    # "$2" is the user's preferred gs metadata name
+	    $find_fields{lc($1)}=$2; # lc = lowercase
+	} else { # no <tagname> for mapping
+	    # "$field" is the user's preferred gs metadata name
+	    $find_fields{lc($field)}=$field; # lc = lowercase
+	}
+    }
+
+    if (defined $self->{'hunt_creator_metadata'} &&
+	$self->{'hunt_creator_metadata'} == 1 ) {
+	my @extra_fields =
+	    (
+	     'author',
+	     'author.email',
+	     'creator',
+	     'dc.creator',
+	     'dc.creator.corporatename',
+	     );
+
+	# add the creator_metadata fields to search for
+	foreach my $field (@extra_fields) {
+	    $creator_fields{$field}=0; # add to lookup hash
+	}
+    }
+
+
+    # find the header in the html file, which has the meta tags
+    $$textref =~ m@<head>(.*?)</head>@si;
+
+    my $html_header=$1;
+
+    # go through every <meta... tag defined in the html and see if it is
+    # one of the tags we want to match.
+    
+    # special case for title - we want to remember if its been found
+    my $found_title = 0;
+    # this assumes that ">" won't appear. (I don't think it's allowed to...)
+    $html_header =~ m/^/; # match the start of the string, for \G assertion
+    
+    while ($html_header =~ m/\G.*?<meta(.*?)>/sig) {
+	my $metatag=$1;
+	my ($tag, $value);
+
+	# find the tag name
+	$metatag =~ m/(?:name|http-equiv)\s*=\s*([\"\'])?(.*?)\1/is;
+	$tag=$2;
+	# in case they're not using " or ', but they should...
+	if (! $tag) {
+	    $metatag =~ m/(?:name|http-equiv)\s*=\s*([^\s\>]+)/is;
+	    $tag=$1;
+	}
+
+	if (!defined $tag) {
+	    print $outhandle "HTMLPlugin: can't find NAME in \"$metatag\"\n";
+	    next;
+	}
+	
+	# don't need to assign this field if it was passed in from a previous 
+	# (recursive) plugin
+	if (defined $metadata->{$tag}) {next}
+
+	# find the tag content
+	$metatag =~ m/content\s*=\s*([\"\'])?(.*?)\1/is;
+	$value=$2;
+
+	if (! $value) {
+	    $metatag =~ m/(?:name|http-equiv)\s*=\s*([^\s\>]+)/is;
+	    $value=$1;
+	}
+	if (!defined $value) {
+	    print $outhandle "HTMLPlugin: can't find VALUE in \"$metatag\"\n";
+	    next;
+	}
+
+	# clean up and add
+	$value =~ s/\s+/ /gs;
+	chomp($value); # remove trailing \n, if any
+	if (exists $creator_fields{lc($tag)}) {
+	    # map this value onto greenstone's "Creator" metadata
+	    $tag='Creator';
+	} elsif (!exists $find_fields{lc($tag)}) {
+	    next; # don't want this tag
+	} else {
+	    # get the user's preferred capitalisation
+	    $tag = $find_fields{lc($tag)};
+	}
+	if (lc($tag) eq "title") {
+	    $found_title = 1;
+	}
+
+	if ($self->{'verbosity'} > 2) {
+	    print $outhandle " extracted \"$tag\" metadata \"$value\"\n";
+	}
+
+	# Do we still reply on the following?  Surely there must 
+	# be a better way to go about this outside of the plugin?
+	# 
+	#if ($tag =~ m/date.*/i){
+	#    $tag = lc($tag);
+	#}
+
+	$doc_obj->add_utf8_metadata($section, $tag, $value);
+
+    }
+    
+    # TITLE: extract the document title
+    if (exists $find_fields{'title'} && !$found_title) {
+	# we want a title, and didn't find one in the meta tags
+	# see if there's a <title> tag
+	my $title;
+	my $from = ""; # for debugging output only
+	if ($html_header =~ m/<title[^>]*>([^<]+)<\/title[^>]*>/is) {
+	    $title = $1;
+	    $from = "<title> tags";
+	}
+
+	if (!defined $title) {
+	    $from = "first 100 chars";
+	    # if no title use first 100 or so characters
+	    $title = $$textref;
+	    $title =~ s/^\xFE\xFF//; # Remove unicode byte order mark	    
+	    $title =~ s/^.*?<body>//si;
+	    # ignore javascript!
+	    $title =~ s@<script.*?</script>@ @sig;
+	    $title =~ s/<\/([^>]+)><\1>//g; # (eg) </b><b> - no space
+	    $title =~ s/<[^>]*>/ /g; # remove all HTML tags
+	    $title = substr ($title, 0, 100);
+	    $title =~ s/\s\S*$/.../;
+	}
+	$title =~ s/<[^>]*>/ /g; # remove html tags
+	$title =~ s/&nbsp;/ /g;
+	$title =~ s/(?:&nbsp;|\xc2\xa0)/ /g; # utf-8 for nbsp...
+	$title =~ s/\s+/ /gs; # collapse multiple spaces
+	$title =~ s/^\s*//;   # remove leading spaces
+	$title =~ s/\s*$//;   # remove trailing spaces
+
+	$title =~ s/^$self->{'title_sub'}// if ($self->{'title_sub'});
+	$title =~ s/^\s+//s; # in case title_sub introduced any...
+	$doc_obj->add_utf8_metadata ($section, 'Title', $title);
+	print $outhandle " extracted Title metadata \"$title\" from $from\n" 
+	    if ($self->{'verbosity'} > 2);
+    } 
+    
+    # add FileFormat metadata
+    $doc_obj->add_metadata($section,"FileFormat", "HTML");
+
+    # Special, for metadata names such as tagH1 - extracts
+    # the text between the first <H1> and </H1> tags into "H1" metadata.
+
+    foreach my $field (keys %find_fields) {
+	if ($field !~ m/^tag([a-z0-9]+)$/i) {next}
+	my $tag = $1;
+	if ($$textref =~ m@<$tag[^>]*>(.*?)</$tag[^>]*>@g) {
+	    my $content = $1;
+	    $content =~ s/&nbsp;/ /g;
+	    $content =~ s/<[^>]*>/ /g;
+	    $content =~ s/^\s+//;
+	    $content =~ s/\s+$//;
+	    $content =~ s/\s+/ /gs;
+	    if ($content) {
+		$tag=$find_fields{"tag$tag"}; # get the user's capitalisation
+		$tag =~ s/^tag//i;
+		$doc_obj->add_utf8_metadata ($section, $tag, $content);
+		print $outhandle " extracted \"$tag\" metadata \"$content\"\n" 
+		    if ($self->{'verbosity'} > 2);
+	    }
+	}
+    }    
+}
+
+
+# evaluate any "../" to next directory up
+# evaluate any "./" as here
+sub eval_dir_dots {
+    my $self = shift (@_);
+    my ($filename) = @_;
+    my $dirsep_os = &util::get_os_dirsep();
+    my @dirsep = split(/$dirsep_os/,$filename);
+
+    my @eval_dirs = ();
+    foreach my $d (@dirsep) {
+	if ($d eq "..") {
+	    pop(@eval_dirs);
+	    
+	} elsif ($d eq ".") {
+	    # do nothing!
+
+	} else {
+	    push(@eval_dirs,$d);
+	}
+    }
+
+    # Need to fiddle with number of elements in @eval_dirs if the
+    # first one is the empty string.  This is because of a
+    # modification to util::filename_cat that supresses the addition
+    # of a leading '/' character (or \ if windows) (intended to help
+    # filename cat with relative paths) if the first entry in the
+    # array is the empty string.  Making the array start with *two*
+    # empty strings is a way to defeat this "smart" option.
+    #
+    if (scalar(@eval_dirs) > 0) {
+	if ($eval_dirs[0] eq ""){
+	    unshift(@eval_dirs,"");
+	}
+    }
+    
+    my $evaluated_filename = (scalar @eval_dirs > 0) ? &util::filename_cat(@eval_dirs) : "";
+    return $evaluated_filename;
+}
+
+sub replace_usemap_links {
+    my $self = shift (@_);
+    my ($front, $link, $back) = @_;
+
+    # remove quotes from link at start and end if necessary
+    if ($link=~/^[\"\']/) {
+	$link=~s/^[\"\']//;
+	$link=~s/[\"\']$//;
+	$front.='"';
+	$back="\"$back";
+    }
+
+    $link =~ s/^\.\///;
+    return $front . $link . $back;
+}
+
+sub inc_filecount {
+    my $self = shift (@_);
+
+    if ($self->{'file_num'} == 1000) {
+	$self->{'dir_num'} ++;
+	$self->{'file_num'} = 0;
+    } else {
+	$self->{'file_num'} ++;
+    }
+}
+
+
+# Extend read_file so that strings like &eacute; are
+# converted to UTF8 internally.  
+#
+# We don't convert &lt; or &gt; or &amp; or &quot; in case
+# they interfere with the GML files
+
+sub read_file {
+    my $self = shift(@_);
+    my ($filename, $encoding, $language, $textref) = @_;
+
+    $self->SUPER::read_file($filename, $encoding, $language, $textref);
+
+    # Convert entities to their UTF8 equivalents
+    $$textref =~ s/&(lt|gt|amp|quot|nbsp);/&z$1;/go;
+    $$textref =~ s/&([^;]+);/&ghtml::getcharequiv($1,1)/gseo;
+    $$textref =~ s/&z(lt|gt|amp|quot|nbsp);/&$1;/go;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/ISISPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/ISISPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/ISISPlugin.pm	(revision 20131)
@@ -0,0 +1,437 @@
+###########################################################################
+#
+# ISISPlugin.pm -- A plugin for CDS/ISIS databases
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright 1999-2004 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package ISISPlugin;
+
+
+use multiread;
+use SplitTextFile;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+# ISISPlugin is a sub-class of SplitTextFile.
+sub BEGIN {
+    @ISISPlugin::ISA = ('SplitTextFile');
+}
+
+
+my $arguments = 
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() },
+      { 'name' => "block_exp",
+	'desc' => "{BasePlugin.block_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_block_exp(),
+	'hiddengli' => "yes" },
+      { 'name' => "split_exp",
+	'desc' => "{SplitTextFile.split_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_split_exp(),
+        'hiddengli' => "yes" },
+
+      # The interesting options
+      { 'name' => "entry_separator",
+	'desc' => "{ISISPlugin.entry_separator}",
+	'type' => "string",
+	'reqd' => "no",
+	'deft' => "<br>" },
+      { 'name' => "subfield_separator",
+	'desc' => "{ISISPlugin.subfield_separator}",
+	'type' => "string",
+	'reqd' => "no",
+	'deft' => ", " }
+      ];
+
+my $options = { 'name'     => "ISISPlugin",
+		'desc'     => "{ISISPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'explodes' => "yes",
+		'args'     => $arguments };
+
+
+# This plugin processes files with the suffix ".mst"
+sub get_default_process_exp {
+    return q^(?i)(\.mst)$^;
+}
+
+
+# This plugin blocks files with the suffix ".fdt" and ".xrf"
+sub get_default_block_exp {
+    return q^(?i)(\.fdt|\.xrf)$^;
+    #return "";
+}
+
+    
+# This plugin splits the input text at the "----------" lines
+sub get_default_split_exp {
+    return q^\r?\n----------\r?\n^;
+}
+
+
+sub new
+{
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new SplitTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    # isis plug doesn't care about encoding - it assumes ascii unless the user
+    # has specified an encoding
+    if ($self->{'input_encoding'} eq "auto") {
+	$self->{'input_encoding'} = "ascii";
+    }
+    return bless $self, $class;
+}
+
+# we block the corresponding fdt and xrf
+# a pain on windows. blocks xxx.FDT, but if actual file is xx.fdt then 
+# complains that no plugin can process it. Have put it back to using 
+# block exp for now
+sub store_block_files_tmp {
+    
+    my $self =shift (@_);
+    my ($filename_full_path, $block_hash) = @_;
+    print STDERR "in store block files\n";
+    $self->check_auxiliary_files($filename_full_path);
+    if (-e $self->{'fdt_file_path'}) {
+	print STDERR "$self->{'fdt_file_path'}\n";
+	my $fdt_file = $self->{'fdt_file_path'};
+	$block_hash->{'file_blocks'}->{$fdt_file} = 1;
+    }
+    if (-e $self->{'xrf_file_path'}) {
+	print STDERR "$self->{'xrf_file_path'}\n";
+	my $xrf_file = $self->{'xrf_file_path'};
+	$block_hash->{'file_blocks'}->{$xrf_file} = 1;
+    }
+    
+
+}
+
+sub check_auxiliary_files {
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    my ($database_file_path_root) = ($filename =~ /(.*)\.mst$/i);
+    # Check the associated .fdt and .xrf files exist
+    $self->{'fdt_file_path'} = $database_file_path_root . ".FDT";
+    if (!-e $self->{'fdt_file_path'}) {
+	$self->{'fdt_file_path'} = $database_file_path_root . ".fdt";
+    }
+    $self->{'xrf_file_path'} = $database_file_path_root . ".XRF";
+    if (!-e $self->{'xrf_file_path'}) {
+	$self->{'xrf_file_path'} = $database_file_path_root . ".xrf";
+    }
+}
+    
+
+sub read_file
+{
+    my $self = shift (@_);
+    my ($filename, $encoding, $language, $textref) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my ($database_file_path_root) = ($filename =~ /(.*)\.mst$/i);
+    my $mst_file_path_relative = $filename;
+    $mst_file_path_relative =~ s/^.+import.(.*?)$/$1/;
+
+    # Check the associated .fdt and .xrf files exist
+    $self->check_auxiliary_files($filename);
+    
+    if (!-e $self->{'fdt_file_path'}) {
+	print STDERR "<ProcessingError n='$mst_file_path_relative' r='Could not find ISIS FDT file $self->{'fdt_file_path'}'>\n" if ($self->{'gli'});
+	print $outhandle "Error: Could not find ISIS FDT file " . $self->{'fdt_file_path'} . ".\n";
+	return;
+    }
+    if (!-e $self->{'xrf_file_path'}) {
+	print STDERR "<ProcessingError n='$mst_file_path_relative' r='Could not find ISIS XRF file $self->{'xrf_file_path'}'>\n" if ($self->{'gli'});
+	print $outhandle "Error: Could not find ISIS XRF file " . $self->{'xrf_file_path'} . ".\n";
+	return;
+    }
+
+    # The text to split is exported from the database by the IsisGdl program
+    open(FILE, "IsisGdl \"$filename\" |");
+
+    my $reader = new multiread();
+    $reader->set_handle('ISISPlugin::FILE');
+    $reader->set_encoding($encoding);
+    $reader->read_file($textref);
+
+    close(FILE);
+
+    # Parse the associated ISIS database Field Definition Table file (.fdt)
+    my %fdt_mapping = &parse_field_definition_table($self->{'fdt_file_path'}, $encoding);
+    $self->{'fdt_mapping'} = \%fdt_mapping;
+
+    # Remove the line at the start, and any blank lines, so the data is split and processed properly
+    $$textref =~ s/^----------\n//;
+    $$textref =~ s/\n\n/\n/g;
+}
+
+
+sub process
+{
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my $section = $doc_obj->get_top_section();
+    my $fdt_mapping = $self->{'fdt_mapping'};
+    my $subfield_separator = $self->{'subfield_separator'};
+    my $entry_separator = $self->{'entry_separator'};
+    my $isis_record_html_metadata_value = "<table cellpadding=\"4\" cellspacing=\"0\">";
+
+    # Process each line of the ISIS record, one at a time
+    foreach my $line (split(/\n/, $$textref)) {
+	$line =~ s/(\s*)$//;  # Remove any nasty whitespace (very important for Windows)
+	$line =~ /^tag=(.*) data=(.+)$/;
+	my $tag = $1;
+	my $tag_data = $2;
+        # print STDERR "\nTag: $tag, Data: $tag_data\n";
+
+	# Convert the tag number into a name, and remove any invalid characters
+	my $raw_metadata_name = $fdt_mapping->{$tag}{'name'} || "";
+	$raw_metadata_name =~ s/[,&\#\.\-\/]/ /g;
+	next if ($raw_metadata_name eq "");
+
+	# Metadata field names: title case, then remove spaces
+	my $metadata_name = "";
+	foreach my $word (split(/\s+/, $raw_metadata_name)) {
+	    substr($word, 0, 1) =~ tr/a-z/A-Z/;
+	    $metadata_name .= $word;
+	}
+
+	my $all_metadata_name = $metadata_name . "^all";
+	my $all_metadata_value = "";
+
+	# Handle repeatable fields
+	if ($fdt_mapping->{$tag}{'repeatable'}) {
+	    # Multiple values are separated using the '%' character
+	    foreach my $raw_metadata_value (split(/%/, $tag_data)) {
+		my $metadata_value = "";
+
+		# Handle subfields
+		while ($raw_metadata_value ne "") {
+		    # If there is a subfield specifier, parse it off
+		    my $sub_metadata_name = $metadata_name;
+		    if ($raw_metadata_value =~ s/^\^// && $raw_metadata_value =~ s/^([a-z])//) {
+			$sub_metadata_name .= "^$1";
+		    }
+
+		    # Parse the value off and add it as metadata
+		    $raw_metadata_value =~ s/^([^\^]*)//;
+		    my $sub_metadata_value = &escape_metadata_value($1);
+
+		    # print STDERR "Sub metadata name: $sub_metadata_name, value: $sub_metadata_value\n";
+		    if ($sub_metadata_name ne $metadata_name) {
+			$doc_obj->add_utf8_metadata($section, $sub_metadata_name, $sub_metadata_value); 
+		    }
+
+		    # If this tag has subfields and this is the first, use the value for the CDS/ISIS ^* field
+		    if ($fdt_mapping->{$tag}{'subfields'} ne "" && $metadata_value eq "") {
+			$doc_obj->add_utf8_metadata($section, $metadata_name . "^*", $sub_metadata_value); 
+		    }
+
+		    $metadata_value .= $subfield_separator unless ($metadata_value eq "");
+		    $metadata_value .= $sub_metadata_value;
+		}
+
+		# Add the metadata value
+		# print STDERR "Metadata name: $metadata_name, value: $metadata_value\n";
+		$doc_obj->add_utf8_metadata($section, $metadata_name, $metadata_value); 
+
+		$all_metadata_value .= $entry_separator unless ($all_metadata_value eq "");
+		$all_metadata_value .= $metadata_value;
+	    }
+	}
+
+	# Handle non-repeatable fields
+	else {
+	    my $raw_metadata_value = $tag_data;
+	    my $metadata_value = "";
+
+	    # Handle subfields
+	    while ($raw_metadata_value ne "") {
+		# If there is a subfield specifier, parse it off
+		my $sub_metadata_name = $metadata_name;
+		if ($raw_metadata_value =~ s/^\^// && $raw_metadata_value =~ s/^([a-z])//) {
+		    $sub_metadata_name .= "^$1";
+		}
+
+		# Parse the value off and add it as metadata
+		$raw_metadata_value =~ s/^([^\^]*)//;
+		my $sub_metadata_value = $1;
+
+		# Deal with the case when multiple values are specified using <...>
+		if ($sub_metadata_value =~ /\<(.+)\>/) {
+		    my $sub_sub_metadata_name = $sub_metadata_name . "^sub";
+		    my $tmp_sub_metadata_value = $sub_metadata_value;
+		    while ($tmp_sub_metadata_value =~ s/\<(.+?)\>//) {
+			my $sub_sub_metadata_value = $1;
+			$doc_obj->add_utf8_metadata($section, $sub_sub_metadata_name, $sub_sub_metadata_value); 
+		    }
+		}
+		# Deal with the legacy case when multiple values are specified using /.../
+		elsif ($sub_metadata_value =~ /\/(.+)\//) {
+		    my $sub_sub_metadata_name = $sub_metadata_name . "^sub";
+		    my $tmp_sub_metadata_value = $sub_metadata_value;
+		    while ($tmp_sub_metadata_value =~ s/\/(.+?)\///) {
+			my $sub_sub_metadata_value = $1;
+			$doc_obj->add_utf8_metadata($section, $sub_sub_metadata_name, $sub_sub_metadata_value); 
+		    }
+		}
+
+		# Escape the metadata value so it appears correctly in the final collection
+		$sub_metadata_value = &escape_metadata_value($sub_metadata_value);
+
+		# print STDERR "Sub metadata name: $sub_metadata_name, value: $sub_metadata_value\n";
+		if ($sub_metadata_name ne $metadata_name) {
+		    $doc_obj->add_utf8_metadata($section, $sub_metadata_name, $sub_metadata_value); 
+		}
+
+		# If this tag has subfields and this is the first, use the value for the CDS/ISIS ^* field
+		if ($fdt_mapping->{$tag}{'subfields'} ne "" && $metadata_value eq "") {
+		    $doc_obj->add_utf8_metadata($section, $metadata_name . "^*", $sub_metadata_value); 
+		}
+
+		$metadata_value .= $subfield_separator unless ($metadata_value eq "");
+		$metadata_value .= $sub_metadata_value;
+	    }
+
+	    # Add the metadata value
+	    # print STDERR "Metadata name: $metadata_name, value: $metadata_value\n";
+	    $doc_obj->add_utf8_metadata($section, $metadata_name, $metadata_value); 
+
+	    $all_metadata_value .= $entry_separator unless ($all_metadata_value eq "");
+	    $all_metadata_value .= $metadata_value;
+	}
+
+	# Add the "^all" metadata value
+	# print STDERR "All metadata name: $all_metadata_name, value: $all_metadata_value\n";
+	$doc_obj->add_utf8_metadata($section, $all_metadata_name, $all_metadata_value); 
+
+	$isis_record_html_metadata_value .= "<tr><td valign=top><nobr><b>" . $fdt_mapping->{$tag}{'name'} . "</b></nobr></td><td valign=top>" . $all_metadata_value . "</td></tr>";
+    }
+
+    # Add a reasonably formatted HTML table view of the record as the document text
+    $isis_record_html_metadata_value .= "</table>";
+    $doc_obj->add_utf8_text($section, $isis_record_html_metadata_value);
+
+    # Add the full raw record as metadata
+    my $isis_raw_record_metadata_value = &escape_metadata_value($$textref);
+    $doc_obj->add_utf8_metadata($section, "ISISRawRecord", $isis_raw_record_metadata_value);
+
+    # Add FileFormat metadata
+    $doc_obj->add_utf8_metadata($section, "FileFormat", "CDS/ISIS");
+
+    # Record was processed successfully
+    return 1;
+}
+
+
+sub parse_field_definition_table
+{
+    my $fdtfilename = shift(@_);
+    my $encoding = shift(@_);
+
+    my %fdtmapping = ();
+
+    open(FDT_FILE, "<$fdtfilename") || die "Error: Could not open file $fdtfilename.\n";
+
+    my $fdtfiletext = "";
+    my $reader = new multiread();
+    $reader->set_handle('ISISPlugin::FDT_FILE');
+    $reader->set_encoding($encoding);
+    $reader->read_file($fdtfiletext);
+
+    my $amongstdefinitions = 0;
+    foreach my $fdtfileline (split(/\n/, $$fdtfiletext)) {
+	$fdtfileline =~ s/(\s*)$//;  # Remove any nasty spaces at the end of the lines
+
+	if ($amongstdefinitions) {
+	    my $fieldname      = &unicode::substr($fdtfileline,  0, 30);
+	    my $fieldsubfields = &unicode::substr($fdtfileline, 30, 20);
+	    my $fieldspecs     = &unicode::substr($fdtfileline, 50, 50);
+
+	    # Remove extra spaces
+	    $fieldname =~ s/(\s*)$//;
+	    $fieldsubfields =~ s/(\s*)$//;
+	    $fieldspecs =~ s/(\s*)$//;
+
+	    # Map from tag number to metadata field title, subfields, and repeatability
+	    my $fieldtag = (split(/ /, $fieldspecs))[0];
+	    my $fieldrepeatable = (split(/ /, $fieldspecs))[3];
+	    $fdtmapping{$fieldtag} = { 'name' => $fieldname,
+				       'subfields' => $fieldsubfields,
+				       'repeatable' => $fieldrepeatable };
+	}
+	elsif ($fdtfileline eq "***") {
+	    $amongstdefinitions = 1;
+	}
+    }
+
+    close(FDT_FILE);
+
+    return %fdtmapping;
+}
+
+
+sub escape_metadata_value
+{
+    my $value = shift(@_);
+    $value =~ s/\</&lt;/g;
+    $value =~ s/\>/&gt;/g;
+    $value =~ s/\\/\\\\/g;
+    return $value;
+}
+
+
+sub clean_up_after_exploding
+{
+    my $self = shift(@_);
+
+    # Delete the FDT and XRF files too
+    &util::rm($self->{'fdt_file_path'});
+    &util::rm($self->{'xrf_file_path'});
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/ImageConverter.pm
===================================================================
--- /gsdl/stable/perllib/plugins/ImageConverter.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/ImageConverter.pm	(revision 20131)
@@ -0,0 +1,457 @@
+###########################################################################
+#
+# ImageConverter - helper plugin that does image conversion using ImageMagick
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2008 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+package ImageConverter;
+
+use BaseMediaConverter;
+
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+use gsprintf 'gsprintf';
+
+BEGIN {
+    @ImageConverter::ISA = ('BaseMediaConverter');
+}
+
+my $arguments = [
+      { 'name' => "create_thumbnail",
+	'desc' => "{ImageConverter.create_thumbnail}",
+	'type' => "enum",
+	'list' => [{'name' => "true", 'desc' => "{common.true}"},
+		   {'name' => "false", 'desc' => "{common.false}"}],
+	'deft' => "true",
+	'reqd' => "no" },
+      { 'name' => "thumbnailsize",
+	'desc' => "{ImageConverter.thumbnailsize}",
+	'type' => "int",
+	'deft' => "100",
+	'range' => "1,",
+	'reqd' => "no" },
+      { 'name' => "thumbnailtype",
+	'desc' => "{ImageConverter.thumbnailtype}",
+	'type' => "string",
+	'deft' => "gif",
+	'reqd' => "no" },
+      { 'name' => "noscaleup",
+	'desc' => "{ImageConverter.noscaleup}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "create_screenview",
+	'desc' => "{ImageConverter.create_screenview}",
+	'type' => "enum",
+	'list' => [{'name' => "true", 'desc' => "{common.true}"},
+		   {'name' => "false", 'desc' => "{common.false}"}],
+	'deft' => "true",
+	'reqd' => "no" },
+      { 'name' => "screenviewsize",
+	'desc' => "{ImageConverter.screenviewsize}",
+	'type' => "int",
+	'deft' => "500",
+	'range' => "1,",
+	'reqd' => "no" },
+      { 'name' => "screenviewtype",
+	'desc' => "{ImageConverter.screenviewtype}",
+	'type' => "string",
+	'deft' => "jpg",
+	'reqd' => "no" },
+      { 'name' => "converttotype",
+	'desc' => "{ImageConverter.converttotype}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "minimumsize",
+	'desc' => "{ImageConverter.minimumsize}",
+	'type' => "int",
+	'deft' => "100",
+	'range' => "1,",
+	'reqd' => "no" }
+		 ];
+
+my $options = { 'name' => "ImageConverter",
+		'desc' => "{ImageConverter.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+		'args' => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BaseMediaConverter($pluginlist, $inputargs, $hashArgOptLists, 1);
+
+
+    return bless $self, $class;
+
+}
+
+# needs to be called after BasePlugin init, so that outhandle is set up.
+sub init {
+    my $self = shift(@_);
+
+    $self->{'tmp_file_paths'} = ();
+
+    # Check that ImageMagick is installed and available on the path 
+    my $image_conversion_available = 1;
+    my $no_image_conversion_reason = "";
+    # None of this works very well on Windows 95/98...
+    if ($ENV{'GSDLOS'} eq "windows" && !Win32::IsWinNT()) {
+	$image_conversion_available = 0;
+	$no_image_conversion_reason = "win95notsupported";
+    } else {
+	my $result = `identify -help 2>&1`;
+	my $return_value = $?;
+	if ( ($ENV{'GSDLOS'} eq "windows" && $return_value == 256) || $return_value == -1) {  # Linux and Windows return different values for "program not found"
+	    $image_conversion_available = 0;
+	    $no_image_conversion_reason = "imagemagicknotinstalled";
+	}
+    }
+    $self->{'image_conversion_available'} = $image_conversion_available;
+    $self->{'no_image_conversion_reason'} = $no_image_conversion_reason;
+
+    if ($self->{'image_conversion_available'} == 0) {
+	my $outhandle = $self->{'outhandle'};
+	&gsprintf($outhandle, "ImageConverter: {ImageConverter.noconversionavailable} ({ImageConverter.".$self->{'no_image_conversion_reason'}."})\n");
+    }
+       
+}
+	
+
+# convert image to new type if converttotype is set
+# generate thumbnails if required
+# generate screenview if required
+# discover image metadata
+# filename_no_path must be in utf8 and url-encoded
+sub generate_images {
+    my $self = shift(@_);
+    my ($filename_full_path, $filename_no_path, $doc_obj, $section) = @_;
+
+    # check image magick status
+    return 0 if $self->{'image_conversion_available'} == 0;
+
+    # check the filenames
+    return 0 if ($filename_no_path eq "" || !-f $filename_full_path);
+
+    if ($self->{'enable_cache'}) {
+	$self->init_cache_for_file($filename_full_path);
+    }
+
+    my $verbosity = $self->{'verbosity'};
+    my $outhandle = $self->{'outhandle'};
+
+    # check the size of the image against minimum size if specified
+    my $minimumsize = $self->{'minimumsize'};
+    if (defined $minimumsize && (-s $filename_full_path < $minimumsize)) {
+        print $outhandle "ImageConverter: \"$filename_full_path\" too small, skipping\n"
+	    if ($verbosity > 1);
+	return 0; # or is there a better return value??
+    }
+    
+    my $filehead = $filename_no_path;
+    $filehead =~ s/\.([^\.]*)$//; # filename with no extension
+    my $assocfilemeta = "[assocfilepath]";
+    if ($section ne $doc_obj->get_top_section()) {
+	$assocfilemeta = "[parent(Top):assocfilepath]";
+    }
+
+    # The images that will get generated may contain percent signs in their src filenames
+    # Encode those percent signs themselves so that urls to the imgs refer to them correctly 
+    my $url_to_filehead = &unicode::filename_to_url($filehead);
+    my $url_to_filename_no_path = &unicode::filename_to_url($filename_no_path);
+    
+    # Convert the image to a new type (if required).
+    my $converttotype = $self->{'converttotype'};
+    my $type = "unknown";
+
+    if ($converttotype ne "" && $filename_full_path !~ m/$converttotype$/) {
+	#    $doc_obj->add_utf8_metadata($section, "Image", $utf8_filename_meta);
+
+	my ($result, $converted_filename_full_path)
+	    = $self->convert($filename_full_path, $converttotype, "", "CONVERTTYPE");
+
+	$type = $converttotype;
+	$filename_full_path = $converted_filename_full_path;
+	$filename_no_path = "$filehead.$type";
+	$url_to_filename_no_path = "$url_to_filehead.$type";
+    }
+
+    # add Image metadata 
+    $doc_obj->add_utf8_metadata($section, "Image", $url_to_filename_no_path); # url to generated image
+
+    # here we overwrite the original with the potentially converted one
+    $doc_obj->set_utf8_metadata_element($section, "Source", &unicode::url_decode($filename_no_path)); # displayname of generated image
+    $doc_obj->set_utf8_metadata_element($section, "SourceFile", $url_to_filename_no_path); # displayname of generated image
+
+    # use identify to get info about the (possibly converted) image
+    my ($image_type, $image_width, $image_height, $image_size) 
+	= &identify($filename_full_path, $outhandle, $verbosity);
+
+    if ($image_type ne " ") {
+	$type = $self->correct_mime_type($image_type);
+    }
+
+    #overwrite the ones added in BasePlugin
+    $doc_obj->set_metadata_element ($section, "FileFormat", $type);
+    $doc_obj->set_metadata_element ($section, "FileSize",   $image_size);
+
+    $doc_obj->add_metadata ($section, "ImageType",   $image_type);
+    $doc_obj->add_metadata ($section, "ImageWidth",  $image_width);
+    $doc_obj->add_metadata ($section, "ImageHeight", $image_height);
+    $doc_obj->add_metadata ($section, "ImageSize",   $image_size);
+
+    if ((defined $self->{'MaxImageWidth'}) 
+	&& ($image_width > $self->{'MaxImageWidth'})) {
+	$self->{'MaxImageWidth'} = $image_width;
+    }
+    if ((defined $self->{'MaxImageHeight'})
+	&& ($image_height > $self->{'MaxImageHeight'})) {
+	$self->{'MaxImageHeight'} = $image_height;
+    }
+
+
+    $doc_obj->add_metadata ($section, "srclink", "<a href=\"_httpprefix_/collect/[collection]/index/assoc/$assocfilemeta/[Image]\">");
+    $doc_obj->add_metadata ($section, "/srclink", "</a>");
+    $doc_obj->add_metadata ($section, "srcicon", "<img src=\"_httpprefix_/collect/[collection]/index/assoc/$assocfilemeta/[Image]\" width=\"[ImageWidth]\" height=\"[ImageHeight]\">");
+
+    # Add the image as an associated file
+    $doc_obj->associate_file($filename_full_path, $filename_no_path, "image/$type", $section);
+
+    if ($self->{'create_thumbnail'} eq "true") {
+	$self->create_thumbnail($filename_full_path, $filehead, $doc_obj, $section, $assocfilemeta, $url_to_filehead);
+    }
+    if ($self->{'create_screenview'} eq "true") {
+	$self->create_screenview($filename_full_path, $filehead, $doc_obj, $section, $assocfilemeta, $url_to_filehead, $image_width, $image_height);
+    }
+}
+
+sub create_thumbnail {
+    my $self = shift(@_);
+    my ($original_file, $filehead, $doc_obj, $section, $assocfilemeta, $url_to_filehead) = @_;
+    $url_to_filehead = $filehead unless defined $url_to_filehead; 
+
+    my $thumbnailsize = $self->{'thumbnailsize'};
+    my $thumbnailtype = $self->correct_mime_type($self->{'thumbnailtype'});
+
+    # Generate the thumbnail with convert
+    my ($result,$thumbnailfile) 
+	= $self->convert($original_file, $thumbnailtype, "-geometry $thumbnailsize" . "x$thumbnailsize", "THUMB");
+    
+    # Add the thumbnail as an associated file ...
+    if (-e "$thumbnailfile") { 
+	$doc_obj->associate_file("$thumbnailfile", $filehead."_thumb.$thumbnailtype", 
+				 "image/$thumbnailtype",$section); # name of generated image
+	$doc_obj->add_metadata ($section, "ThumbType", $thumbnailtype);
+	$doc_obj->add_utf8_metadata ($section, "Thumb", $url_to_filehead."_thumb.$thumbnailtype"); # url to generated image
+	
+	$doc_obj->add_metadata ($section, "thumbicon", "<img src=\"_httpprefix_/collect/[collection]/index/assoc/$assocfilemeta/[Thumb]\" width=[ThumbWidth] height=[ThumbHeight]>");
+    
+	
+	# Extract Thumbnail metadata from convert output
+	if ($result =~ m/[0-9]+x[0-9]+=>([0-9]+)x([0-9]+)/) {
+	    $doc_obj->add_metadata ($section, "ThumbWidth", $1);
+	    $doc_obj->add_metadata ($section, "ThumbHeight", $2);
+	}
+    } else {
+	my $outhandle = $self->{'outhandle'};
+	print $outhandle "Couldn't find thumbnail $thumbnailfile\n";
+
+    }
+}
+
+sub create_screenview {
+    
+    my $self = shift(@_);
+    my ($original_file, $filehead, $doc_obj, $section, $assocfilemeta, $url_to_filehead, $image_width, $image_height) = @_;
+    $url_to_filehead = $filehead unless defined $url_to_filehead; 
+
+    my $screenviewsize = $self->{'screenviewsize'};
+    my $screenviewtype = $self->correct_mime_type($self->{'screenviewtype'});
+
+    # Scale the image, unless the original image is smaller than the screenview size and -noscaleup is set
+    my $scale_option = "-geometry $screenviewsize" . "x$screenviewsize";
+    if ($self->{'noscaleup'} && $image_width < $screenviewsize && $image_height < $screenviewsize)
+    {
+	$scale_option = "";
+    }
+    
+    # make the screenview image
+    my ($result,$screenviewfilename) 
+	= $self->convert($original_file, $screenviewtype, $scale_option, "SCREEN");    
+    
+    #add the screenview as an associated file ...
+    if (-e "$screenviewfilename") { 
+	$doc_obj->associate_file("$screenviewfilename", $filehead."_screen.$screenviewtype", "image/$screenviewtype",$section); # name of generated image
+	$doc_obj->add_metadata ($section, "ScreenType", $screenviewtype);
+	$doc_obj->add_utf8_metadata ($section, "Screen", $url_to_filehead."_screen.$screenviewtype"); # url to generated image
+	
+	$doc_obj->add_metadata ($section, "screenicon", "<img src=\"_httpprefix_/collect/[collection]/index/assoc/$assocfilemeta/[Screen]\" width=[ScreenWidth] height=[ScreenHeight]>");
+
+	# get screenview dimensions, size and type
+	if ($result =~ m/[0-9]+x[0-9]+=>([0-9]+)x([0-9]+)/) {
+	    $doc_obj->add_metadata ($section, "ScreenWidth", $1);
+	    $doc_obj->add_metadata ($section, "ScreenHeight", $2);
+	} elsif ($result =~ m/([0-9]+)x([0-9]+)/) {
+	    #if the image hasn't changed size, the previous regex doesn't match
+	    $doc_obj->add_metadata ($section, "ScreenWidth", $1);
+	    $doc_obj->add_metadata ($section, "ScreenHeight", $2);
+	}
+    } else {
+	my $outhandle = $self->{'outhandle'};
+	print $outhandle "Couldn't find screenview file $screenviewfilename\n";
+
+    }
+
+}
+
+
+
+sub convert {
+    my $self = shift(@_);
+    my $source_file_path = shift(@_);
+    my $target_file_type = shift(@_);
+    my $convert_options  = shift(@_) || "";
+    my $convert_id       = shift(@_) || "";
+
+    my $outhandle = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+
+    my $source_file_no_path = &File::Basename::basename($source_file_path);
+
+    # Determine the full name and path of the output file
+    my $target_file_path;
+    if ($self->{'enable_cache'}) {
+	my $cached_image_dir = $self->{'cached_dir'};
+	my $image_root = $self->{'cached_file_root'};
+	$image_root .= "_$convert_id" if ($convert_id ne "");
+	my $image_file = "$image_root.$target_file_type";
+	$target_file_path = &util::filename_cat($cached_image_dir,$image_file);
+    }
+    else {
+	$target_file_path = &util::get_tmp_filename($target_file_type);
+	push(@{$self->{'tmp_file_paths'}}, $target_file_path);
+
+	# Output filename used to be parsed from result line:
+	#   my ($ofilename) = ($result =~ m/=>(.*\.$target_file_type)/);
+	# by the function that called 'convert'
+	# but this is no longer needed, as output filename is now
+	# explicitly passed back
+    }
+
+    # Generate and run the convert command
+    my $convert_command = "convert -interlace plane -verbose $convert_options \"$source_file_path\" \"$target_file_path\"";
+
+    my $print_info = { 'message_prefix' => $convert_id,
+		       'message' => "Converting image $source_file_no_path to: $convert_id $target_file_type" };
+ 
+    my ($regenerated,$result,$had_error) 
+	= $self->autorun_general_cmd($convert_command,$target_file_path,$print_info);
+
+    return ($result,$target_file_path);
+}
+
+
+# Discover the characteristics of an image file with the ImageMagick
+# "identify" command.
+
+sub identify { 
+    my ($image, $outhandle, $verbosity) = @_;
+
+    # Use the ImageMagick "identify" command to get the file specs
+    my $command = "identify \"$image\" 2>&1";
+    print $outhandle "$command\n" if ($verbosity > 2);
+    my $result = '';
+    $result = `$command`;
+    print $outhandle "$result\n" if ($verbosity > 3);
+
+    # Read the type, width, and height
+    my $type =   'unknown';
+    my $width =  'unknown';
+    my $height = 'unknown';
+
+    my $image_safe = quotemeta $image;
+    if ($result =~ /^$image_safe (\w+) (\d+)x(\d+)/) {
+	$type = $1;
+	$width = $2;
+	$height = $3;
+    }
+
+    # Read the size
+    my $size = "unknown";
+    if ($result =~ m/^.* ([0-9]+)b/) {
+	$size = $1;
+    }
+    elsif ($result =~ m/^.* ([0-9]+)(\.([0-9]+))?kb?/) {
+	$size = 1024 * $1;
+	if (defined($2)) {
+	    $size = $size + (1024 * $2);
+	    # Truncate size (it isn't going to be very accurate anyway)
+	    $size = int($size);
+	}
+    }
+    elsif ($result =~ m/^.* (([0-9]+)(\.([0-9]+))?e\+([0-9]+))(kb|b)?/) {
+	# Deals with file sizes on Linux of type "3.4e+02kb" where e+02 is 1*10^2.
+	# 3.4e+02 therefore evaluates to 3.4 x 1 x 10^2 = 340kb.
+	# Programming languages including Perl know how that 3.4e+02 is a number,
+	# so we don't need to do any calculations.
+	$size = $1*1; # turn the string into a number by multiplying it by 1
+	       #if we did $size = $1; $size would be merely the string "3.4e+02"
+	$size = int($size); # truncate size
+    }
+    print $outhandle "file: $image:\t $type, $width, $height, $size\n" 
+	if ($verbosity > 2);
+
+    # Return the specs
+    return ($type, $width, $height, $size);
+}
+
+sub clean_up_temporary_files {
+    my $self = shift(@_);
+
+    foreach my $tmp_file_path (@{$self->{'tmp_file_paths'}}) {
+	if (-e $tmp_file_path) {
+	    &util::rm($tmp_file_path);
+	}
+    }
+   
+}
+
+# image/jpg is not a valid mime-type, it ought to be image/jpeg. 
+# Sometimes JPEG is passed in also, want to keep things lowercase just in case.
+sub correct_mime_type {
+    my $self = shift(@_);
+    my ($file_extension) = @_;
+    
+    $file_extension = lc($file_extension);
+    $file_extension =~ s/jpg/jpeg/s; 
+
+    return $file_extension;
+}
+
+1;	
Index: /gsdl/stable/perllib/plugins/ImagePlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/ImagePlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/ImagePlugin.pm	(revision 20131)
@@ -0,0 +1,163 @@
+###########################################################################
+#
+# ImagePlugin.pm -- for processing standalone images
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package ImagePlugin;
+
+use BasePlugin;
+use ImageConverter;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+no strict 'subs';
+
+use gsprintf 'gsprintf';
+
+sub BEGIN {
+    @ImagePlugin::ISA = ('BasePlugin', 'ImageConverter');
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" },
+      ];
+
+my $options = { 'name'     => "ImagePlugin",
+		'desc'     => "{ImagePlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    new ImageConverter($pluginlist, $inputargs, $hashArgOptLists);
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+    my ($verbosity, $outhandle, $failhandle) = @_;
+
+    $self->SUPER::init(@_);
+    $self->ImageConverter::init();
+    $self->{'cover_image'} = 0; # makes no sense for images
+}
+
+sub begin {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $processor, $maxdocs) = @_;
+
+    $self->SUPER::begin(@_);
+    $self->ImageConverter::begin(@_);
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+	# from .jpf and onwards below, the file extensions are for JPEG2000
+    return q^(?i)(\.jpe?g|\.gif|\.png|\.bmp|\.xbm|\.tif?f|\.jpf|\.jpx|\.jp2|\.jpc|\.j2k|\.pnm|\.pgx)$^; 
+}
+
+# this makes no sense for images
+sub block_cover_image
+{
+    my $self =shift (@_);
+    my ($filename) = @_;
+
+    return;
+}
+
+# do plugin specific processing of doc_obj
+sub process {
+    my $self = shift (@_);
+    # options??
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+
+    my $outhandle = $self->{'outhandle'};
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+
+    if ($self->{'image_conversion_available'} == 1)
+    {
+	my $utf8_filename_no_path = $self->filepath_to_utf8($filename_no_path);
+	my $url_encoded_filename = &util::rename_file($utf8_filename_no_path, $self->{'file_rename_method'});
+	$self->generate_images($filename_full_path, $url_encoded_filename, $doc_obj, $doc_obj->get_top_section()); # should we check the return value?
+    }
+    else
+    {
+	if ($gli) {
+	    &gsprintf(STDERR, "<Warning p='ImagePlugin' r='{ImageConverter.noconversionavailable}: {ImageConverter.".$self->{'no_image_conversion_reason'}."}'>");
+	}
+	# all we do is add the original image as an associated file, and set up srclink etc
+	my $assoc_file = $doc_obj->get_assocfile_from_sourcefile();
+	my $section = $doc_obj->get_top_section();
+
+	$doc_obj->associate_file($filename_full_path, $assoc_file, "", $section);
+
+	$doc_obj->add_metadata ($section, "srclink", "<a href=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[SourceFile]\">");
+	$doc_obj->add_metadata ($section, "/srclink", "</a>");
+	# We don't know the size of the image, but the browser should display it at full size
+	$doc_obj->add_metadata ($section, "srcicon", "<img src=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[SourceFile]\">");
+
+	# Add a fake thumbnail icon with the full-sized image scaled down by the browser
+	$doc_obj->add_metadata ($section, "thumbicon", "<img src=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[SourceFile]\" width=\"" . $self->{'thumbnailsize'} . "\">");
+    }
+    #we have no text - adds dummy text and NoText metadata
+    $self->add_dummy_text($doc_obj, $doc_obj->get_top_section());
+
+    return 1;
+
+}
+
+sub clean_up_after_doc_obj_processing {
+    my $self = shift(@_);
+    
+    $self->ImageConverter::clean_up_temporary_files();
+}
+
+1;
+
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/perllib/plugins/IndexPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/IndexPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/IndexPlugin.pm	(revision 20131)
@@ -0,0 +1,158 @@
+###########################################################################
+#
+# IndexPlugin.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# This recursive plugin processes an index.txt file. 
+# The index.txt file should contain the list of files to be
+# included in the collection followed by any extra metadata to
+# be associated with each file.
+
+# The index.txt file should be formatted as follows:
+# The first line may be a key (beginning with key:)
+# to name the metadata fields
+# (e.g. key: Subject Organization Date) 
+# The following lines will contain a filename followed 
+# by the value that metadata entry is to be set to.
+# (e.g. 'irma/iw097e 3.2 unesco 1993' will associate the
+# metadata Subject=3.2, Organization=unesco, and Date=1993
+# with the file irma/iw097e if the above key line was used)
+
+# Note that if any of the metadata fields use the Hierarchy
+# classifier plugin then the value they're set to should
+# correspond to the first field (the descriptor) in the
+# appropriate classification file.
+
+# Metadata values may be named separately using a tag 
+# (e.g. <Subject>3.2) and this will override any name 
+# given to them by the key line.
+# If there's no key line any unnamed metadata value will be
+# named 'Subject'.
+
+package IndexPlugin;
+
+use plugin;
+use BasePlugin;
+use doc;
+use util;
+use cfgread;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @IndexPlugin::ISA = ('BasePlugin');
+}
+
+#my $arguments = [
+#		 ];
+
+my $options = { 'name'     => "IndexPlugin",
+		'desc'     => "{IndexPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes" };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    #push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+# return 1 if this class might recurse using $pluginfo
+sub is_recursive {
+    my $self = shift (@_);
+    
+    return 1;
+}
+
+# return number of files processed, undef if can't process
+# Note that $base_dir might be "" and that $file might 
+# include directories
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my $indexfile = &util::filename_cat($base_dir, $file, "index.txt");
+    if (!-f $indexfile) {
+	# not a directory containing an index file
+	return undef;
+    }
+
+    # found an index.txt file
+    print STDERR "<Processing n='$file' p='IndexPlugin'>\n" if ($gli);
+    print $outhandle "IndexPlugin: processing $indexfile\n";
+
+    # read in the index.txt
+    my $list = &cfgread::read_cfg_file ($indexfile, undef, '^[^#]\w');
+    my @fields = ();
+    # see if there's a 'key:' line
+    if (defined $list->{'key:'}) {
+	@fields = @{$list->{'key:'}};
+    }
+
+    my $index_base_dir = &util::filename_cat($base_dir, $file);
+
+    # process each document
+    my $count = 0;
+    foreach my $docfile (keys (%$list)) {
+	last if ($maxdocs != -1 && ($total_count + $count) >= $maxdocs);
+	$metadata = {}; # at present we can do this as metadata
+	                # will always be empty when it arrives
+	                # at this plugin - this might cause 
+	                # problems if things change though
+
+	# note that $list->{$docfile} is an array reference
+	if ($docfile !~ /key:/i) {
+	    my $i = 0;
+	    for ($i = 0; $i < scalar (@{$list->{$docfile}}); $i ++) {
+		if ($list->{$docfile}->[$i] =~ /^<([^>]+)>(.+)$/) {
+		    unless (defined ($metadata->{$1})) {
+			$metadata->{$1} = [];
+		    } 
+		    push (@{$metadata->{$1}}, $2);
+		} elsif (scalar @fields >= $i) {
+		    unless (defined ($metadata->{$fields[$i]})) {
+			$metadata->{$fields[$i]} = [];
+		    } 
+		    push (@{$metadata->{$fields[$i]}}, $list->{$docfile}->[$i]);
+		} else {
+		    $metadata->{'Subject'} = $list->{$docfile};
+		}
+	    }
+	    $count += &plugin::read ($pluginfo, $index_base_dir, $docfile, $block_hash, $metadata, $processor, $maxdocs, ($total_count +$count), $gli);
+	}
+    }
+
+    return $count; # was processed
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/KeyphraseExtractor.pm
===================================================================
--- /gsdl/stable/perllib/plugins/KeyphraseExtractor.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/KeyphraseExtractor.pm	(revision 20131)
@@ -0,0 +1,145 @@
+###########################################################################
+#
+# KeyphraseExtractor - helper plugin to extract key phrases
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2008 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package KeyphraseExtractor;
+
+use Kea;
+use PrintInfo;
+use gsprintf 'gsprintf';
+
+use strict;
+no strict 'subs';
+
+BEGIN {
+    @KeyphraseExtractor::ISA = ('PrintInfo');
+}
+
+my $arguments = [
+      { 'name' => "extract_keyphrases",
+	'desc' => "{KeyphraseExtractor.extract_keyphrases}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "extract_keyphrases_kea4",
+	'desc' => "{KeyphraseExtractor.extract_keyphrases_kea4}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "extract_keyphrase_options",
+	'desc' => "{KeyphraseExtractor.extract_keyphrase_options}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" }
+		 ];
+
+my $options = { 'name'     => "KeyphraseExtractor",
+		'desc'     => "{KeyphraseExtractor.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new PrintInfo($pluginlist, $inputargs, $hashArgOptLists, 1);
+
+    return bless $self, $class;
+
+}
+# extract metadata
+sub extract_keyphrase_metadata {
+
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+
+    if ($self->{'extract_keyphrases'} || $self->{'extract_keyphrases_kea4'}) {
+	$self->extract_keyphrases($doc_obj);
+    }
+
+}
+
+
+#adding kea keyphrases
+sub extract_keyphrases
+{
+    my $self = shift(@_);
+    my $doc_obj = shift(@_);
+
+    # Use Kea 3.0 unless 4.0 has been specified
+    my $kea_version = "3.0";
+    if ($self->{'extract_keyphrases_kea4'}) {
+	$kea_version = "4.0";
+    }
+
+    # Check that Kea exists, and tell the user where to get it if not
+    my $keahome = &Kea::get_Kea_directory($kea_version);
+    if (!-e $keahome) {
+	gsprintf(STDERR, "{KeyphraseExtractor.missing_kea}\n", $keahome, $kea_version);
+	return;
+    }
+
+    my $thissection = $doc_obj->get_top_section();
+    my $text = "";
+    my $list;
+
+    #loop through sections to gather whole doc
+    while (defined $thissection) { 
+	my $sectiontext = $doc_obj->get_text($thissection);   
+	$text = $text.$sectiontext;
+	$thissection = $doc_obj->get_next_section ($thissection);
+    } 
+   
+    if($self->{'extract_keyphrase_options'}) { #if kea options flag is set, call Kea with specified options 
+	$list = &Kea::extract_KeyPhrases ($kea_version, $text, $self->{'extract_keyphrase_options'});
+    } else { #otherwise call Kea with no options
+	$list = &Kea::extract_KeyPhrases ($kea_version, $text);
+    }
+ 
+    if ($list){
+	# if a list of kea keyphrases was returned (ie not empty)
+	if ($self->{'verbosity'}) {
+	    gsprintf(STDERR, "{KeyphraseExtractor.keyphrases}: $list\n");
+	}
+
+	#add metadata to top section
+	$thissection = $doc_obj->get_top_section(); 
+
+	# add all key phrases as one metadata
+	$doc_obj->add_metadata($thissection, "Keyphrases", $list);
+
+	# add individual key phrases as multiple metadata
+	foreach my $keyphrase (split(',', $list)) {
+	    $keyphrase =~ s/^\s+|\s+$//g;
+	    $doc_obj->add_metadata($thissection, "Keyphrase", $keyphrase);
+	}
+    }
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/LOMPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/LOMPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/LOMPlugin.pm	(revision 20131)
@@ -0,0 +1,712 @@
+###########################################################################
+#
+# LOMPlugin.pm -- plugin for import the collection from LOM
+# 
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2005 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+### Note this plugin currently can't download source documents from outside if you are behind a firewall.
+
+package LOMPlugin;
+
+use ReadTextFile;
+use MetadataPass;
+use XMLParser;
+use Cwd;
+
+sub BEGIN {
+    @ISA = ('ReadTextFile', 'MetadataPass');
+}
+
+use strict; # every perl program should have this!
+no strict 'refs'; # make an exception so we can use variables as filehandles
+
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "string",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" },
+      { 'name' => "root_tag",
+	'desc' => "{LOMPlugin.root_tag}",
+	'type' => "regexp",
+	'deft' => q/^(?i)lom$/,
+	'reqd' => "no" },
+      { 'name' => "check_timestamp",
+	'desc' => "{LOMPlugin.check_timestamp}",
+	'type' => "flag" },
+      { 'name' => "download_srcdocs",
+	'desc' => "{LOMPlugin.download_srcdocs}",
+	'type' => "regexp",
+	'deft' => "",
+	'reqd' => "no" }];
+
+my $options = { 'name'     => "LOMPlugin",
+		'desc'     => "{LOMPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+
+my ($self);
+sub new {
+    my $class = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+    
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+   
+    $self = new ReadTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about creating the XML parser as all we want is the 
+	# list of plugin options
+	return bless $self, $class;
+    }
+
+    #create XML::Parser object for parsing dublin_core.xml files
+    my $parser = new XML::Parser('Style' => 'Stream',
+				 'Handlers' => {'Char' => \&Char,
+						'Doctype' => \&Doctype
+						});
+    $self->{'parser'} = $parser;
+
+    $self->{'extra_blocks'} = {};
+
+    return bless $self, $class;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.xml$^;
+}
+
+
+sub can_process_this_file {
+    my $self = shift(@_);
+    my ($filename) = @_;
+
+    if ($self->SUPER::can_process_this_file($filename) && $self->check_doctype($filename)) {
+	return 1; # its a file for us
+    }
+    return 0;
+}
+
+sub metadata_read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, 
+	$extrametakeys, $extrametadata, $extrametafile,
+	$processor, $maxdocs, $gli) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+
+    # can we process this file??
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+
+    $file =~ s/^[\/\\]+//; # $file often begins with / so we'll tidy it up
+    
+    print $outhandle "LOMPlugin: extracting metadata from $file\n"
+	if $self->{'verbosity'} > 1;
+
+    my ($dir,$tail) = $filename_full_path =~ /^(.*?)([^\/\\]*)$/;
+    $self->{'output_dir'} = $dir;
+
+    eval {
+	$self->{'parser'}->parsefile($filename_full_path);
+    };
+    
+    if ($@) {
+	print $outhandle "LOMPlugin: skipping $filename_full_path as not conformant to LOM syntax\n" if ($self->{'verbosity'} > 1);
+	print $outhandle "\n Perl Error:\n $@\n" if ($self->{'verbosity'}>2);
+	return 0;
+    }
+
+    $self->{'output_dir'} = undef;
+
+    my $file_re;
+    my $lom_srcdoc = $self->{'lom_srcdoc'};
+
+    if (defined $lom_srcdoc) {
+	my $dirsep = &util::get_re_dirsep();
+	$lom_srcdoc =~ s/^$base_dir($dirsep)//;
+	$self->{'extra_blocks'}->{$file}++;
+
+	$file_re = $lom_srcdoc;
+    }
+    else {
+	$file_re = $tail;
+    }
+    $file_re =~ s/\./\\\./g;
+
+    $self->{'lom_srcdoc'} = undef; # reset for next file to be processed
+
+    push(@$extrametakeys,$file_re);
+    $extrametadata->{$file_re} = $self->{'saved_metadata'};
+
+    return 1;
+}
+
+sub check_doctype {
+    $self = shift (@_);
+    
+    my ($filename) = @_;
+    
+    if (open(XMLIN,"<$filename")) {
+	my $doctype = $self->{'root_tag'};
+	## check whether the doctype has the same name as the root element tag
+	while (defined (my $line = <XMLIN>)) {
+	    ## find the root element
+	    if ($line =~ /<([\w\d:]+)[\s>]/){
+		my $root = $1;
+		if ($root !~ $doctype){
+		    close(XMLIN);
+		    return 0;
+		}
+		else {
+		    close(XMLIN); 
+		    return 1;
+		}
+	    }
+	}
+	close(XMLIN);
+    }
+    
+    return undef; # haven't found a valid line
+    
+}
+
+sub read_file {
+    my $self = shift (@_);
+    my ($filename, $encoding, $language, $textref) = @_;
+
+    my $metadata_table = $self->{'metadata_table'};
+
+    my $rawtext = $metadata_table->{'rawtext'};
+
+    delete $metadata_table->{'rawtext'};
+
+    $$textref = $rawtext;
+}
+
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+
+    return 0 if (defined $self->{'extra_blocks'}->{$file});
+
+    # can we process this file??
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+
+    $self->{'metadata_table'} = $metadata;
+
+    my $lom_language = $metadata->{'lom_language'};
+
+    my $store_input_encoding;
+    my $store_extract_language;
+    my $store_default_language;
+    my $store_default_encoding;
+
+    if (defined $lom_language) {
+	delete $metadata->{'lom_language'};
+
+	$store_input_encoding   = $self->{'input_encoding'};
+	$store_extract_language = $self->{'extract_language'};
+	$store_default_language = $self->{'default_language'};
+	$store_default_encoding = $self->{'default_encoding'};
+
+	$self->{'input_encoding'}   = "utf8";
+	$self->{'extract_language'} = 0;
+	$self->{'default_language'} = $lom_language;
+	$self->{'default_encoding'} = "utf8";
+    }
+
+    my $rv = $self->SUPER::read(@_);
+
+    if (defined $lom_language) {	
+	$self->{'input_encoding'}   = $store_input_encoding;
+	$self->{'extract_language'} = $store_extract_language;
+	$self->{'default_language'} = $store_default_language;
+	$self->{'default_encoding'} = $store_default_encoding;
+    }
+
+    $self->{'metadata_table'} = undef;
+
+    return $rv;
+}
+
+# do plugin specific processing of doc_obj
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    print STDERR "<Processing n='$file' p='LOMPlugin'>\n" if ($gli);
+
+    print $outhandle "LOMPLug: processing $file\n";
+
+    my $cursection = $doc_obj->get_top_section();
+    $doc_obj->add_utf8_text($cursection, $$textref);
+
+    return 1;
+}
+
+sub Doctype {
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+
+    my $root_tag = $self->{'root_tag'};
+
+    if ($name !~ /$root_tag/) {	
+	die "Root tag $name does not match regular expression $root_tag";
+    }
+}
+
+sub StartTag {
+    my ($expat, $element) = @_;
+
+    my %attr = %_;
+    
+    my $raw_tag = "&lt;$element";
+    map { $raw_tag .= " $_=\"$attr{$_}\""; } keys %attr;
+    $raw_tag .= "&gt;";
+
+    if ($element =~ m/$self->{'root_tag'}/) {
+	$self->{'raw_text'} = $raw_tag;
+
+	$self->{'saved_metadata'} = {};
+	$self->{'metaname_stack'} = [];
+	$self->{'lom_datatype'} = "";
+	$self->{'lom_language'} = undef;
+	$self->{'metadatatext'} = "<table class=\"metadata\" width=\"_pagewidth_\" >\n";
+    }
+    else {
+	my $xml_depth = scalar(@{$self->{'metaname_stack'}});
+	$self->{'raw_text'} .= "\n"; 
+	$self->{'raw_text'} .= "&nbsp;&nbsp;" x $xml_depth; 
+	$self->{'raw_text'} .= $raw_tag;
+
+	my $metaname_stack = $self->{'metaname_stack'};
+	push(@$metaname_stack,$element);
+	if (scalar(@$metaname_stack)==1) {
+	    # top level LOM category
+	    my $style = "class=\"metadata\"";
+	    my $open_close
+		= "<a id=\"${element}opencloselink\" href=\"javascript:hideTBodyArea('$element')\">\n";
+	    $open_close
+		.= "<img id=\"${element}openclose\" border=\"0\" src=\"_httpopenmdicon_\"></a>\n";
+
+	    my $header_line = "  <tr $style ><th $style colspan=\"3\">$open_close \u$element</th></tr>\n";
+	    my $md_tbody = "<tbody id=\"$element\">\n";
+
+	    $self->{'mdheader'}     = $header_line;
+	    $self->{'mdtbody'}      = $md_tbody;
+	    $self->{'mdtbody_text'} = "";
+	}
+    }
+}
+
+sub EndTag {
+    my ($expat, $element) = @_;
+
+    my $raw_tag = "&lt;/$element&gt;";
+    
+    if ($element =~ m/$self->{'root_tag'}/) {
+	$self->{'raw_text'} .= $raw_tag;
+
+	my $metadatatext = $self->{'metadatatext'};
+	$metadatatext .= "</table>";
+
+	my $raw_text = $self->{'raw_text'};
+
+	$self->{'saved_metadata'}->{'MetadataTable'} =  $metadatatext;
+	$self->{'metadatatext'} = "";
+
+	$self->{'saved_metadata'}->{'rawtext'} =  $raw_text;
+	$self->{'raw_text'} = "";
+
+	if (defined $self->{'lom_language'}) {
+	    $self->{'saved_metadata'}->{'lom_language'} = $self->{'lom_language'};
+	    $self->{'lom_language'} = undef;
+	}
+    }
+    else {
+	my $metaname_stack = $self->{'metaname_stack'};
+
+	if (scalar(@$metaname_stack)==1) {
+	    my $header_line = $self->{'mdheader'};
+	    my $tbody_start = $self->{'mdtbody'};
+	    my $tbody_text  = $self->{'mdtbody_text'};
+	    if ($tbody_text !~ m/^\s*$/s) {
+		my $tbody_end = "</tbody>\n";
+		my $table_chunk 
+		    = $header_line.$tbody_start.$tbody_text.$tbody_end;
+
+		$self->{'metadatatext'} .= $table_chunk;
+	    }
+	    $self->{'mdtheader'}    = "";
+	    $self->{'mdtbody'}      = "";
+	    $self->{'mdtbody_text'} = "";
+	}
+
+	pop(@$metaname_stack);
+
+	my $xml_depth = scalar(@{$self->{'metaname_stack'}});
+	$self->{'raw_text'} .= "\n"; 
+	$self->{'raw_text'} .= "&nbsp;&nbsp;" x $xml_depth; 
+	$self->{'raw_text'} .= $raw_tag;
+    }
+}
+
+sub process_datatype_info
+{
+    my $self = shift(@_);
+    my ($metaname_stack,$md_content) = @_;
+
+    my @without_dt_stack = @$metaname_stack; # without datatype stack
+
+    my $innermost_element = $without_dt_stack[$#without_dt_stack];
+
+    # Loose last item if encoding datatype information
+    if ($innermost_element =~ m/^(lang)?string$/) {
+	$self->{'lom_datatype'} = $innermost_element;
+
+	pop @without_dt_stack;
+	$innermost_element = $without_dt_stack[$#without_dt_stack];
+    }
+    elsif ($innermost_element =~ m/^date(Time)?$/i) { 
+	if ($innermost_element =~ m/^date$/i) {
+	    $self->{'lom_datatype'} = "dateTime";
+	}
+	else {
+	    $self->{'lom_datatype'} = $innermost_element;
+
+	    pop @without_dt_stack;
+	    $innermost_element = $without_dt_stack[$#without_dt_stack];
+	}
+
+	if ($md_content =~ m/^(\d{1,2})\s*(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\w*\s*(\d{4})/i) {
+	    my ($day,$mon,$year) = ($1,$2,$3);
+	    
+	    my %month_lookup = ( 'jan' =>  1, 'feb' =>  2, 'mar' =>  3,
+				 'apr' =>  4, 'may' =>  5, 'jun' =>  6,
+				 'jul' =>  7, 'aug' =>  8, 'sep' =>  9,
+				 'oct' => 10, 'nov' => 11, 'dec' => 12 );
+
+	    my $mon_num = $month_lookup{lc($mon)};
+
+	    $md_content = sprintf("%d%02d%02d",$year,$mon_num,$day);
+	}
+
+	$md_content =~ s/\-//g;
+    }
+
+    if ($innermost_element eq "source") {
+	$self->{'lom_source'} = $md_content;
+    }
+    elsif ($innermost_element eq "value") {
+	$self->{'lom_value'} = $md_content;
+    }
+
+    return (\@without_dt_stack,$innermost_element,$md_content);
+}
+
+sub reset_datatype_info
+{
+    my $self = shift(@_);
+
+    $self->{'lom_datatype'} = "";
+}
+
+
+sub pretty_print_text
+{
+    my $self = shift(@_);
+    
+    my ($pretty_print_text) = @_;
+
+##    $metavalue_utf8 = &util::hyperlink_text($metavalue_utf8);
+    $pretty_print_text = &util::hyperlink_text($pretty_print_text);
+	
+####    $pretty_print_text =~ s/(BEGIN:vCard.*END:vCard)/<pre>$1<\/pre>/sg;
+
+    if ($self->{'lom_datatype'} eq "dateTime") {
+	if ($pretty_print_text =~ m/^(\d{4})(\d{2})(\d{2})$/) {
+	    $pretty_print_text = "$1-$2-$3";
+	}
+    }
+
+    return $pretty_print_text;
+}
+
+sub pretty_print_table_tr
+{
+    my $self = shift (@_);
+    my ($without_dt_stack) = @_;
+
+    my $style = "class=\"metadata\"";
+
+    my $innermost_element = $without_dt_stack->[scalar(@$without_dt_stack)-1];
+    my $outermost_element = $without_dt_stack->[0];
+
+    # Loose top level stack item (already named in pretty print table)
+    my @pretty_print_stack = @$without_dt_stack;
+    shift @pretty_print_stack; 
+
+    if ($innermost_element eq "source") {
+	return if (!defined $self->{'lom_value'});
+    }
+
+    if ($innermost_element eq "value") {
+	return if (!defined $self->{'lom_source'});
+    }
+
+    my $pretty_print_text = "";
+
+    if (($innermost_element eq "value") || ($innermost_element eq "source")) {
+	my $source = $self->{'lom_source'};
+	my $value  = $self->pretty_print_text($self->{'lom_value'});
+
+	$self->{'lom_source'} = undef;
+	$self->{'lom_value'} = undef;
+
+	pop @pretty_print_stack;
+	
+	$pretty_print_text = "<td $style>$source</td><td $style>$value</td>";
+    }
+    else {
+	$pretty_print_text = $self->pretty_print_text($_);
+	$pretty_print_text = "<td $style colspan=2>$pretty_print_text</td>";
+    }
+    my $pretty_print_fmn = join(' : ',map { "\u$_"; } @pretty_print_stack);
+
+
+    # my $tr_attr = "id=\"$outermost_element\" style=\"display:block;\"";
+    my $tr_attr = "$style id=\"$outermost_element\"";
+
+    my $mdtext_line = "  <tr $tr_attr><td $style><nobr>$pretty_print_fmn</nobr></td>$pretty_print_text</tr>\n";
+    $self->{'mdtbody_text'} .= $mdtext_line;
+}
+
+
+sub check_for_language
+{
+    my $self = shift(@_);
+    my ($innermost_element,$md_content) = @_;
+
+    # Look for 'language' tag
+    if ($innermost_element eq "language") {
+	my $lom_lang = $self->{'lom_language'};
+	
+	if (defined $lom_lang) {
+	    my $new_lom_lang = $md_content;
+	    $new_lom_lang =~ s/-.*//; # remove endings like -US or -GB
+
+	    if ($lom_lang ne $new_lom_lang) {
+		my $outhandle = $self->{'outhandle'};
+		
+		print $outhandle "Warning: Conflicting general language in record\n";
+		print $outhandle "         $new_lom_lang (previous value for language = $lom_lang)\n";
+	    }
+	    # otherwise, existing value OK => do nothing
+	}
+	else {
+	    $lom_lang = $md_content;
+	    $lom_lang =~ s/-.*//; # remove endings like -US or -GB
+	    
+	    $self->{'lom_language'} = $lom_lang;
+	}
+    }
+}
+
+sub found_specific_identifier
+{
+    my $self = shift(@_);
+    my ($specific_id,$full_mname,$md_content) = @_;
+
+    my $found_id = 0;
+    if ($full_mname eq $specific_id) {
+	if ($md_content =~ m/^(http|ftp):/) {
+	    $found_id = 1;
+	}
+    }
+
+    return $found_id;
+}
+
+sub download_srcdoc
+{
+    my $self = shift(@_);
+    my ($doc_url) = @_;
+
+    my $outhandle  = $self->{'outhandle'};
+    my $output_dir = $self->{'output_dir'};
+
+    $output_dir = &util::filename_cat($output_dir,"_gsdldown.all");
+
+    if (! -d $output_dir) {
+	mkdir $output_dir;
+    }
+
+    my $re_dirsep = &util::get_re_dirsep();
+    my $os_dirsep = &util::get_dirsep();
+
+    my $file_url = $doc_url;
+    $file_url =~ s/$re_dirsep/$os_dirsep/g;
+    $file_url =~ s/^(http|ftp):\/\///;
+    $file_url .= "index.html" if ($file_url =~ m/\/$/);
+
+    my $full_file_url = &util::filename_cat($output_dir,$file_url);
+
+    my $check_timestamp = $self->{'check_timestamp'};
+    my $status;
+
+    if (($check_timestamp) || (!$check_timestamp && !-e $full_file_url)) {
+	if (!-e $full_file_url) {
+	    print $outhandle "Mirroring $doc_url\n";
+	}
+	else {
+	    print $outhandle "Checking to see if update needed for $doc_url\n";
+	}
+
+	# on linux, if we pass an absolute path as -P arg to wget, then it 
+	# stuffs up the 
+	# URL rewriting in the file. Need a relative path or none, so now
+	# we change working directory first.
+	my $changed_dir = 0;
+	my $current_dir = cwd();
+	my $wget_cmd = "";
+	if ($ENV{'GSDLOS'} ne "windows") {
+	    $changed_dir = 1;
+	    
+	    chdir "$output_dir";
+	    $wget_cmd = "wget -nv  --timestamping -k -p \"$doc_url\"";
+	} else {
+	    $wget_cmd = "wget -nv -P \"$output_dir\" --timestamping -k -p \"$doc_url\""; 
+	}
+	#my $wget_cmd = "wget -nv -P$output_dir --timestamping -k -p \"$doc_url\""; 
+	### my $full_dir_url = &File::Basename::dirname($full_file_url);
+
+	## my $wget_cmd = "wget -O $full_file_url --timestamping -k \"$doc_url\"";
+	#my $wget_cmd = "wget -nv -P$output_dir --timestamping -x -k \"$doc_url\"";
+	print STDERR "**** wget = $wget_cmd\n";
+
+	
+	$status = system($wget_cmd);
+	if ($changed_dir) {
+	    chdir $current_dir;
+	}
+	if ($status==0) {
+	    $self->{'lom_srcdoc'} = $full_file_url;	
+	}
+	else {
+	    $self->{'lom_srcdoc'} = undef;
+	    print $outhandle "Error: failed to execute $wget_cmd\n";
+	}
+    }
+    else {
+	# not time-stamping and file already exists
+	$status=0;
+	$self->{'lom_srcdoc'} = $full_file_url;	
+    }
+
+    return $status==0;
+    
+}
+
+
+sub check_for_identifier
+{
+    my $self = shift(@_);
+    my ($full_mname,$md_content) = @_;
+
+    my $success = 0;
+
+    my $download_re = $self->{'download_srcdocs'};
+    if (($download_re ne "") && $md_content =~ m/$download_re/) {
+	
+	if ($self->found_specific_identifier("general^identifier^entry",$full_mname,$md_content)) {
+	    $success = $self->download_srcdoc($md_content);
+	}
+
+	if (!$success) {
+	    if ($self->found_specific_identifier("technical^location",$full_mname,$md_content)) {
+		$success = $self->download_srcdoc($md_content);
+	    }
+	}
+    }
+
+    return $success;
+}
+
+
+sub Text {
+    if ($_ !~ m/^\s*$/) {
+	#
+	# Work out indentations and line wraps for raw XML
+	#
+	my $xml_depth = scalar(@{$self->{'metaname_stack'}})+1;
+	my $indent = "&nbsp;&nbsp;" x $xml_depth; 
+	
+	my $formatted_text = "\n".$_;
+
+	# break into lines < 80 chars on space
+	$formatted_text =~ s/(.{50,80})\s+/$1\n/mg; 
+	$formatted_text =~ s/^/$indent/mg;
+	## $formatted_text =~ s/\s+$//s;
+
+	$self->{'raw_text'} .= $formatted_text;
+    }
+
+    my $metaname_stack = $self->{'metaname_stack'};
+    if (($_ !~ /^\s*$/) && (scalar(@$metaname_stack)>0)) {
+
+	my ($without_dt_stack,$innermost_element,$md_content)
+	    = $self->process_datatype_info($metaname_stack,$_);
+
+	$self->pretty_print_table_tr($without_dt_stack);
+
+	my $full_mname = join('^',@{$without_dt_stack});
+	$self->set_filere_metadata(lc($full_mname),$md_content);
+
+	$self->check_for_language($innermost_element,$md_content);
+	$self->check_for_identifier($full_mname,$md_content); # source doc
+
+	$self->reset_datatype_info();
+    }
+}
+
+# This Char function overrides the one in XML::Parser::Stream to overcome a
+# problem where $expat->{Text} is treated as the return value, slowing
+# things down significantly in some cases.
+sub Char {
+  $_[0]->{'Text'} .= $_[1];
+  return undef;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/LaTeXPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/LaTeXPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/LaTeXPlugin.pm	(revision 20131)
@@ -0,0 +1,754 @@
+###########################################################################
+#
+# LaTeXPlugin.pm
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Written by John McPherson
+# Copyright (C) 2004 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+###########################################################################
+
+# todo:
+#  \includegraphics
+#  parse/remove tex \if ... macros
+
+package LaTeXPlugin;
+
+# System complains about $arguments if the strict is set
+use strict;
+no strict 'refs'; # so we can print to a handle named by a variable
+
+# greenstone packages
+use ReadTextFile;
+use unicode;
+use util;
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() } ];
+
+my $options = { 'name'     => "LaTeXPlugin",
+		'desc'     => "{LaTeXPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub BEGIN {
+    @LaTeXPlugin::ISA = ('ReadTextFile');
+}
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new ReadTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    $self->{'aux_files'} = {};
+    $self->{'dir_num'} = 0;
+    $self->{'file_num'} = 0;
+    return bless $self, $class;
+}
+
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+    return q^\.tex$^;
+}
+
+sub get_default_block_exp {
+    # assume any .eps files are part of the latex stuff
+    return '\.(?:eps)$';
+}
+
+
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    my $start=substr($$textref, 0, 200); # first 200 bytes
+
+    if ($start !~ m~\\ (?:documentclass | documentstyle | input | section 
+			| chapter | contents | begin) ~x) {
+	# this doesn't look like latex...
+	return undef;
+    }
+    my $outhandle = $self->{'outhandle'};
+
+    my $cursection = $doc_obj->get_top_section();
+
+    ###### clean up text ######
+    $$textref =~ s/\r$//mg;  # remove dos ^M
+    $$textref =~ s/%.*$//mg; # remove comments
+
+    # convert to utf-8 if not already - assume non ascii => iso-8859-1/latin
+
+    $$textref =~ s@(?<=[[:ascii:]])\xA0+@\xc2\xa0@g; # latin nonbreaking space
+    # check that both sides are ascii, so we don't screw up utf-8 chars
+    $$textref =~ s@ (?<=[[:ascii:]])([\x80-\xff])(?=[[:ascii:]]) @
+	unicode::ascii2utf8($1) @egx; # takes "extended ascii" (ie latin)
+
+
+    ###### find metadata ######
+
+    ## FileFormat metadata ##
+    $doc_obj->add_metadata($cursection, "FileFormat", "LaTeX");
+
+    ### title metadata ###
+    $$textref =~ m@\\title\s*{(.*?)}@s;
+    my $title = $1;
+    if (!$title) {
+	# no title tag. look for a chapter/section heading
+	$$textref =~ m@\\(?:chapter|section)\s*{(.*?)}@s; # will get 1st match
+	$title = $1;
+    }
+    if (!$title) {
+	# no chapter/section heading tags either... use filename
+	$title = $file;
+	$title =~ s/\.tex$//i;
+	$title =~ s/[-_.]/ /g; # turn punctuation into spaces
+    }
+    if ($title) {
+	$title =~ s@\\\\@ @g; # embedded newlines
+	$title = $self->process_latex($title); # no "-html" for title eg in browser
+	$doc_obj->add_utf8_metadata($cursection, "Title", $title);
+    }
+
+    ### creator/individual author metadata ###
+    $$textref =~ m@\\author\s*{((?:{.*?}|.*?)+)}\s*$@sm;
+    my $authors=$1;
+    if ($authors) {
+	# take care of "et al."...
+	$authors =~ s/(\s+et\.?\s+al\.?)\s*$//;
+	my $etal=$1;
+	$etal="" if (!defined ($etal));
+
+	my @authorlist=parse_authors($self, $authors);
+
+	foreach my $author (@authorlist) {
+	    # Add each name to set of Authors
+	    $doc_obj->add_utf8_metadata ($cursection, "Author", $author);
+	}
+
+	# Only want at most one "and" in the Creator field
+	my $creator_str="";
+	if (scalar(@authorlist) > 2) {
+	    my $lastauthor=pop @authorlist;
+	    $creator_str=join(', ', @authorlist);
+	    $creator_str.=" and $lastauthor";
+	} else { # 1 or 2 authors...
+	    $creator_str=join(" and ",@authorlist);
+	}
+	$creator_str.=$etal; # if there was "et al."
+    	$doc_obj->add_utf8_metadata($cursection, "Creator", $creator_str);
+    }
+    ### end of author metadata ###
+
+    ###### process latex for the main text ######
+    $$textref =~ s/^.*?\\begin{document}//s;
+    $$textref =~ s/\\end{document}.*?$//s;
+    $$textref = $self->process_latex("-html",$$textref);
+    $doc_obj->add_utf8_text($cursection, $$textref);
+
+    return 1;
+}
+
+
+# returns a list of author names
+sub parse_authors {
+    my $self=shift;
+    my $authors=shift;
+
+    my $outhandle=$self->{'outhandle'};
+
+    $authors =~ s/\n/ /g; # remove newlines
+	
+    # some people do this for affiliation footnote/dagger
+    $authors =~ s@\$.*?\$@@g; # remove maths from author :(
+
+    # und here for german language...
+    # don't use brackets in pattern, else the matched bit becomes
+    # an element in the list!
+    my @authorlist = split(/\s+and\s+|\s+und\s+/, $authors);
+    my @formattedlist = ();
+    foreach my $author (@authorlist) {
+	$author =~ s/\s*$//; 
+	$author =~ s/^\s*//; 
+	# Reformat and add author name
+	next if $author=~ /^\s*$/;
+
+	# names are "First von Last", "von Last, First"
+	# or "von Last, Jr, First". See the "BibTeXing" manual, page 16
+	my $first="";
+	my $vonlast="";
+	my $jr="";
+	    
+	if ($author =~ /,/) {
+	    my @parts=split(/,\s*/, $author);
+	    $first = pop @parts;
+	    if (scalar(@parts) == 2) {
+		$jr = pop @parts;
+	    }
+	    $vonlast=shift @parts;
+	    if (scalar(@parts) > 0) {
+		print $outhandle $self->{'plugin_type'} .
+		    ": couldn't parse name $author\n";
+		# but we continue anyway...
+	    }
+	} else { # First von Last
+	    my @words = split(/ /, $author);
+	    while (scalar(@words) > 1 && $words[0] !~ /^[a-z]{2..}/) {
+		$first .= " " . shift (@words);
+	    }
+	    $first =~ s/^\s//;
+	    $vonlast = join (' ', @words); # whatever's left...
+	}
+	my $von="";
+	my $last="";
+	if ($vonlast =~ m/^[a-z]/) { # lowercase implies "von"
+	    $vonlast =~ s/^(([a-z]\w+\s+)+)//;
+	    $von = $1;
+	    if (!defined ($von)) {
+		# some non-English names do start with lowercase
+		# eg "Marie desJardins". Also we can get typos...
+		print $outhandle "BibTexPlug: couldn't parse surname $vonlast\n";
+		$von="";
+		if ($vonlast =~ /^[a-z]+$/) {
+		    # if it's all lowercase, uppercase 1st.
+		    $vonlast =~ s/^(.)/\u$1/;
+		}
+	    }
+	    $von =~ s/\s*$//;
+	    $last=$vonlast;
+	} else {
+	    $last=$vonlast;
+	}
+	my $wholename="$first $von $last $jr";
+	$wholename =~ s/ $//; $wholename =~ s/\s+/ /g;
+#	my $fullname = "$last";
+#	$fullname .= " $jr" if ($jr);
+#	$fullname .= ", $first";
+#	$fullname .= " $von" if ($von);
+	push (@formattedlist, $wholename);
+    }
+    return @formattedlist;
+}
+
+
+## following functions based on bibtex plugin ##
+# not actually used at the moment, but might be useful in future?
+sub expand_month {
+    my $text=shift;
+
+    # bibtex style files expand abbreviations for months.
+    # Entries can contain more than one month (eg ' month = jun # "-" # aug, ')
+    $text =~ s/jan/_textmonth01_/g;
+    $text =~ s/feb/_textmonth02_/g;
+    $text =~ s/mar/_textmonth03_/g;
+    $text =~ s/apr/_textmonth04_/g;
+    $text =~ s/may/_textmonth05_/g;
+    $text =~ s/jun/_textmonth06_/g;
+    $text =~ s/jul/_textmonth07_/g;
+    $text =~ s/aug/_textmonth08_/g;
+    $text =~ s/sep/_textmonth09_/g;
+    $text =~ s/oct/_textmonth10_/g;
+    $text =~ s/nov/_textmonth11_/g;
+    $text =~ s/dec/_textmonth12_/g;
+
+    return $text;
+}
+
+
+# If you want basic html formatting (eg \emph -> <em>, \bf, etc), give "-html"
+# as the first argument to this function.
+#
+# Convert accented characters, remove { }, interprete some commands....
+# Note!! This is not comprehensive! Also assumes Latin -> Unicode!
+
+# Also, it sucks quite a bit for complicated/nested commands since it doesn't
+# match { with the corresponding }, only the nearest }
+
+sub process_latex {
+    my $self=shift;
+    my $text=shift;
+
+    my $outhandle=$self->{'outhandle'};
+
+    my $html_markup=0;
+    if ($text =~ /^\-html/) {
+	$html_markup=1;
+	$text=shift;
+    }
+
+    if (! $text) {
+	return $text;
+    }
+    # escape html-sensitive characters
+    $text =~ s@&@&amp;@g;
+    $text =~ s@<@&lt;@g;
+    $text =~ s@>@&gt;@g;
+ 
+    # do this before accents, since \= means something different in tabbing
+    # also \> is a tab stop too, and \\ is newline
+    sub do_tabbing {
+	my $tabbing=shift;
+	$tabbing =~ s!^.*\\kill\s*$!!mg; # \kill sets tab stops, kills line
+	$tabbing =~ s~\\(?:=|&gt;)~\xc2\xa0~g; # replace with nbsp
+	$tabbing =~ s~[\\][\\](?:\[.*?\])?\s*$~<br/>~mg;
+	return "<br/>" . $tabbing . "<br/>\n";
+    }
+    $text =~ s@\\begin{tabbing}(.*?)\\end{tabbing}@do_tabbing($1)@ges;
+    sub do_tabular {
+	my $tabular=shift;
+	$tabular =~ s~(?<!\\)\s*&amp;\s*~</td><td>~g;
+	$tabular =~ s~[\\][\\]\s*~</td></tr>\n <tr><td>~g;
+	$tabular =~ s~\\hline~~g; # for now...
+	$tabular =~ s~<td>\s*\\multicolumn{(\d+)}{.*?}~<td colspan="$1">~g;
+	return "<table border=\"1\">\n <tr><td>"
+	    . $tabular . "</td></tr></table>\n";
+    }
+    $text =~ s@\\begin{tabular}(?:\[.*?\])?{.*?}(.*?)\\end{tabular} @
+    		do_tabular($1)  @xges;
+
+    $text =~ s@[\\][\\]\s*\n@ @g; # fold lines ending with \\
+
+    # process maths mode before accents... things like \, mean different!
+    # maths mode
+    $text =~ s@\$\$(.*?)\$\$ 
+	@ process_latex_math($html_markup,$1)
+	@xsge; # multi-line maths: $$ .... $$
+
+    $text =~ s@([^\\])\$(.*?[^\\])\$
+	@$1.process_latex_math($html_markup,$2)@xsge;
+
+
+    # is this an amstext environment, or just custom for that input file?
+    $text =~ s@\\begin{(algorithm)}(.*?)\\end{\1}@remove_equals($2)@ges;
+
+    # convert latex-style accented characters.
+    $self->latex_accents_to_utf8(\$text);
+
+    # replace quotes with utf-8
+
+    $text =~ s/``/\xe2\xc0\x9c/g; # Latex-specific, left-dbl quote (&ldquo;)
+    $text =~ s/''/\xe2\xc0\x9d/g; # Latex-specific, right-dbl quote (&rdquo;)
+    $text =~ s/`/\xe2\xc0\x98/g; # single left quote
+    $text =~ s/'/\xe2\xc0\x99/g; # single right quote
+
+    ###### remove/replace latex commands ######
+    ### commands that expand to something that gets displayed ###
+    $text =~ s~\\ldots~&hellip;~g;
+    $text =~ s~\\hrule~<hr/>\n~g;
+    $text =~ s~\\maketitle~ ~;
+    ### space commands ###
+    $text =~ s~\\[vh]skip\s+\S+~~g;
+    $text =~ s~\\vspace\*?{.*?}~<div>&nbsp;</div>~g; # vertical space
+    $text =~ s~\\\w+skip~ ~g; # \smallskip \medskip \bigskip \baselineskip etc
+    $text =~ s~\\noindent\b~~g;
+    # newpage, etc
+    $text =~ s~\\(?:clearemptydoublepage|newpage)~~g;
+    ### counters, contents, environments, labels, etc ###
+    $text =~ s~\\(?:addcontentsline){.*?}{.*?}{.*}~~g;
+    $text =~ s~\s*\\begin{itemize}\s*~\n<ul>\n~g;
+    $text =~ s~\s*\\end{itemize}\s*~</li></ul>\n~g;
+    $text =~ s~\s*\\begin{enumerate}\s*~<ol>\n~g;
+    $text =~ s~\s*\\end{enumerate}\s*~</li></ol>\n~g;
+    if ($text =~ s~\s*\\item~</li>\n<li>~g) {
+	# (count for first list item)
+	$text =~ s~<([ou])l>\s*</li>\s*~<$1l>~g;
+    }
+    $text =~ s~\\(?:label|begin|end){.*?}\s*\n?~ ~g; # remove tag and contents
+    $text =~ s~\\(?:tableofcontents|listoffigures)~ ~g;
+    ### font sizes/styles ###
+    $text =~ s~\\(?:tiny|small|footnotesize|normalsize|large|Large|huge|Huge)\b~~g;
+
+    if ($html_markup) {
+	$text =~ s~\\section\*?{([^\}]+)}\s*\n?~<H1>$1</H1>\n~g;
+	$text =~ s~\\subsection\*?{(.*?)}\s*\n?~<H2>$1</H2>\n~g;
+	$text =~ s~{\\tt\s*(.*?)}~<tt>$1</tt>~g;
+	$text =~ s~\\(?:texttt|tt|ttseries)\s*{(.*?)}~<tt>$1</tt>~g;
+	$text =~ s~\\emph{(.*?)}~<em>$1</em>~g;
+	$text =~ s~{\\(?:em|it)\s*(.*?)}~<em>$1</em>~g;
+	$text =~ s~{\\(?:bf|bfseries)\s*(.*?)}~<strong>$1</strong>~g;
+	$text =~ s~\\(?:textbf|bf|bfseries)\s*{(.*?)}~<strong>$1</strong>~g;
+    } else {
+	# remove tags for text-only
+	$text =~ s~\\(?:textbf|bf|bfseries|em|emph|tt|rm|texttt)\b~ ~g;
+    }
+    $text =~ s ~ {\\sc\s+(.*?)} ~
+		{<span style="font-variant:\ small-caps">$1</span>} ~gx;
+    # ignore these font tags (if there are any left)
+    # sf is sans-serif
+    $text =~ s~\\(?:mdseries|textmd|bfseries|textbf|sffamily|sf|sc)\b~ ~;
+    #### end font-related stuff ####
+
+    ### remove all other commands with optional arguments... ###
+    # don't remove commands without { }....
+    # $text =~ s~\\\w+(\[.*?\])?\s*~~g;
+    # $text =~ s~\\noopsort{[^}]+\}~~g;
+    # verbatim
+    $text =~ s~\\verb(.)(.*?)\1~verb_text($1)~ge;
+    # remove tags, keep contents for \tag[optional]{contents}
+    while ($text =~ s~\\\w+(\[.*?\])?{([^}]+)}~$2 ~g) {;} # all other commands
+    
+    # remove latex groupings { } (but not \{ or \} )
+    while ($text =~ s/([^\\])[\{\}]/$1/g) {;} # needed for "...}{..."
+    $text =~ s/^\{//; # remove { if first char
+
+    # latex characters
+    # spaces - nobr space (~), opt break (\-), append ("#" - bibtex only)
+    $text =~ s/([^\\])~+/$1 /g; # non-breaking space  "~"
+    # optional break "\-"
+    if ($text =~ m/[^&]\#/) { # concat macros (bibtex) but not HTML codes
+	# the non-macro bits have quotes around them - we just remove quotes
+	# XXX bibtex and latex differ here (for the '#' char)...
+	$text =~ s/([^&])[\"\#]/$1/g;
+    }
+    # dashes. Convert (m|n)-dash into single dash for html.
+    $text =~ s~\-\-+~\-~g;
+
+    # quoted { } chars
+    $text =~ s~\\{~{~g;
+    $text =~ s~\\}~}~g;
+
+    # spaces
+    $text =~ s~\\ ~ ~g;
+
+    # finally to protect against macro language...
+    # greenstone-specific
+    $text =~ s~\[~&\#91;~g;
+    $text =~ s~\]~&\#93;~g;
+    $text =~ s~(?<!\\)([\\_])~\\$1~g;
+
+    if ($html_markup) {
+	$text =~ s~\n{2,}~\n</p>\n<p>~g;
+	return "<p>$text</p>";
+    }
+
+    return $text;
+}
+
+# only used by process_latex for \verb....
+sub verb_text {
+    my $verbatim=shift;
+    $verbatim =~ s/([{}_])/\\$1/g;
+    return $verbatim;
+}
+# only used by process_latex_math
+# returns a unicode char if applicable, otherwise ascii
+sub math_fraction {
+    my $num=$1;
+    my $denom=$2;
+
+    if ($num==1 && $denom==2) {return chr(0xc2).chr(0xbd)}
+    if ($num==1 && $denom==4) {return chr(0xc2).chr(0xbc)}
+    if ($num==3 && $denom==4) {return chr(0xc2).chr(0xbe)}
+    return "$num/$denom";
+}
+
+sub process_latex_math {
+
+    my $text = pop; # if given one or two args, this is the last one...
+    my $html_markup=pop; # if given two args, this is the first one else undef
+
+    $text =~ s~\\,~ ~g; # forces a space?
+    $text =~ s~\\infty~infinity~g;             # or unicode 0x221E...
+
+# use this one when more things can read 3-byte utf8 values like this!
+#    $text =~ s~\\cup\b~\xe2\xc8\xaa~g; # union operator - unicode 0x222a
+    $text =~ s~\\cup\b~ U ~g;
+
+    $text =~ s~\\frac\s*{(.+?)}{(.+?)}~math_fraction($1,$2)~ge;
+
+    if ($html_markup) {
+	$text =~ s~\^{(.*?)}~<sup>$1</sup>~g;  # a^b superscript
+	$text =~ s~\^([^\{])~<sup>$1</sup>~g;
+	$text =~ s~\_{(.*?)}~<sub>$1</sub>~g;  # a_b subscript
+	$text =~ s~\_([^\{])~<sub>$1</sub>~g;
+	
+	$text =~ s~\\ldots~&hellip;~g;         # use html named entity for now
+
+	# put all other command names in italics for now
+	$text =~ s~\\([\w]+)~<i>$1</i> ~g;
+    }
+
+    # special cases, for some input files
+    if ($text =~ m~^\\\w+$~) {
+	$text="{" . $text . "}";
+    }
+
+    return $text;
+}
+
+
+
+sub latex_accents_to_utf8 {
+
+    # note - this is really ugly, but it works. There may be a prettier way
+    # of mapping latex accented chars to utf8, but we just brute force it here.
+    # Also, this isn't complete - not every single possible accented letter
+    # is in here yet, but most of the common ones are.
+
+    my %utf8_chars =
+	(
+	 # acutes
+	 '\'a' => chr(0xc3).chr(0xa1),
+	 '\'c' => chr(0xc4).chr(0x87),
+	 '\'e' => chr(0xc3).chr(0xa9),
+	 '\'i' => chr(0xc3).chr(0xad),
+	 '\'l' => chr(0xc3).chr(0xba),
+	 '\'n' => chr(0xc3).chr(0x84),
+	 '\'o' => chr(0xc3).chr(0xb3),
+	 '\'r' => chr(0xc5).chr(0x95),
+	 '\'s' => chr(0xc5).chr(0x9b),
+	 '\'u' => chr(0xc3).chr(0xba),
+	 '\'y' => chr(0xc3).chr(0xbd),
+	 '\'z' => chr(0xc5).chr(0xba),
+	 # graves
+	 '`a' => chr(0xc3).chr(0xa0),
+	 '`A' => chr(0xc3).chr(0x80),
+	 '`e' => chr(0xc3).chr(0xa8),
+	 '`E' => chr(0xc3).chr(0x88),
+	 '`i' => chr(0xc3).chr(0xac),
+	 '`I' => chr(0xc3).chr(0x8c),
+	 '`o' => chr(0xc3).chr(0xb2),
+	 '`O' => chr(0xc3).chr(0x92),
+	 '`u' => chr(0xc3).chr(0xb9),
+	 '`U' => chr(0xc3).chr(0x99),
+	 # circumflex
+	 '^a' => chr(0xc3).chr(0xa2),
+	 '^A' => chr(0xc3).chr(0x82),
+	 '^c' => chr(0xc4).chr(0x89),
+	 '^C' => chr(0xc4).chr(0x88),
+	 '^e' => chr(0xc3).chr(0xaa),
+	 '^E' => chr(0xc3).chr(0x8a),
+	 '^g' => chr(0xc4).chr(0x9d),
+	 '^G' => chr(0xc4).chr(0x9c),
+	 '^h' => chr(0xc4).chr(0xa5),
+	 '^H' => chr(0xc4).chr(0xa4),
+	 '^i' => chr(0xc3).chr(0xae),
+	 '^I' => chr(0xc3).chr(0x8e),
+	 '^j' => chr(0xc4).chr(0xb5),
+	 '^J' => chr(0xc4).chr(0xb4),
+	 '^o' => chr(0xc3).chr(0xb4),
+	 '^O' => chr(0xc3).chr(0x94),
+	 '^s' => chr(0xc5).chr(0x9d),
+	 '^S' => chr(0xc5).chr(0x9c),
+	 '^u' => chr(0xc3).chr(0xa2),
+	 '^U' => chr(0xc3).chr(0xbb),
+	 '^w' => chr(0xc5).chr(0xb5),
+	 '^W' => chr(0xc5).chr(0xb4),
+	 '^y' => chr(0xc5).chr(0xb7),
+	 '^Y' => chr(0xc5).chr(0xb6),
+	 
+	 # diaeresis
+	 '"a' => chr(0xc3).chr(0xa4),
+	 '"A' => chr(0xc3).chr(0x84),
+	 '"e' => chr(0xc3).chr(0xab),
+	 '"E' => chr(0xc3).chr(0x8b),
+	 '"i' => chr(0xc3).chr(0xaf),
+	 '"I' => chr(0xc3).chr(0x8f),
+	 '"\\\\i' => chr(0xc3).chr(0xaf),
+	 '"\\\\I' => chr(0xc3).chr(0x8f),
+	 '"o' => chr(0xc3).chr(0xb6),
+	 '"O' => chr(0xc3).chr(0x96),
+	 '"u' => chr(0xc3).chr(0xbc),
+	 '"U' => chr(0xc3).chr(0x9c),
+	 '"y' => chr(0xc3).chr(0xbf),
+	 '"Y' => chr(0xc3).chr(0xb8),
+	 # tilde
+	 '~A' => chr(0xc3).chr(0x83),
+	 '~N' => chr(0xc3).chr(0x91),
+	 '~O' => chr(0xc3).chr(0x95),
+	 '~a' => chr(0xc3).chr(0xa3),
+	 '~n' => chr(0xc3).chr(0xb1),
+	 '~o' => chr(0xc3).chr(0xb5),
+	 # caron - handled specially
+	 # double acute
+	 # ring
+	 # dot
+	 '.c' => chr(0xc4).chr(0x8b),
+	 '.C' => chr(0xc4).chr(0x8a),
+	 '.e' => chr(0xc4).chr(0x97),
+	 '.E' => chr(0xc4).chr(0x96),
+	 '.g' => chr(0xc4).chr(0xa1),
+	 '.G' => chr(0xc4).chr(0xa0),
+	 '.I' => chr(0xc4).chr(0xb0),
+	 '.z' => chr(0xc5).chr(0xbc),
+	 '.Z' => chr(0xc5).chr(0xbb),
+	 # macron
+	 '=a' => chr(0xc4).chr(0x81),
+	 '=A' => chr(0xc4).chr(0x80),
+	 '=e' => chr(0xc4).chr(0x93),
+	 '=E' => chr(0xc4).chr(0x92),
+	 '=i' => chr(0xc4).chr(0xab),
+	 '=I' => chr(0xc4).chr(0xaa),
+	 '=o' => chr(0xc4).chr(0x8d),
+	 '=O' => chr(0xc4).chr(0x8c),
+	 '=u' => chr(0xc4).chr(0xab),
+	 '=U' => chr(0xc4).chr(0xaa),
+	 
+	 # stroke - handled specially - see below
+	 
+	 # cedilla - handled specially
+	 );
+    
+# these are one letter latex commands - we make sure they're not a longer
+# command name. eg {\d} is d+stroke, so careful of \d
+    my %special_utf8_chars = 
+	(
+	 # breve
+	 'u g' => chr(0xc4).chr(0x9f),
+	 'u G' => chr(0xc4).chr(0x9e),
+	 'u i' => chr(0xc4).chr(0xad),
+	 'u I' => chr(0xc4).chr(0xac),
+	 'u o' => chr(0xc5).chr(0x8f),
+	 'u O' => chr(0xc5).chr(0x8e),
+	 'u u' => chr(0xc5).chr(0xad),
+	 'u U' => chr(0xc5).chr(0xac),
+	 'u z' => chr(0xc5).chr(0xbe), # !!! no such char, but common mistake
+	 'u Z' => chr(0xc5).chr(0xbd), # used instead of v Z !!!
+	 # caron
+	 'v c' => chr(0xc4).chr(0x8d),
+	 'v C' => chr(0xc4).chr(0x8c),
+	 'v n' => chr(0xc5).chr(0x88),
+	 'v N' => chr(0xc5).chr(0x87),
+	 'v s' => chr(0xc5).chr(0xa1),
+	 'v S' => chr(0xc5).chr(0xa5),
+	 'v z' => chr(0xc5).chr(0xbe),
+	 'v Z' => chr(0xc5).chr(0xbd),
+	 # cedilla
+	 'c c' => chr(0xc3).chr(0xa7),
+	 'c C' => chr(0xc3).chr(0x87),
+	 'c g' => chr(0xc4).chr(0xa3),
+	 'c G' => chr(0xc4).chr(0xa2),
+	 'c k' => chr(0xc4).chr(0xb7),
+	 'c K' => chr(0xc4).chr(0xb6),
+	 'c l' => chr(0xc4).chr(0xbc),
+	 'c L' => chr(0xc4).chr(0xbb),
+	 'c n' => chr(0xc5).chr(0x86),
+	 'c N' => chr(0xc5).chr(0x85),
+	 'c r' => chr(0xc5).chr(0x97),
+	 'c R' => chr(0xc5).chr(0x96),
+	 'c s' => chr(0xc5).chr(0x9f),
+	 'c S' => chr(0xc5).chr(0x9e),
+	 'c t' => chr(0xc5).chr(0xa3),
+	 'c T' => chr(0xc5).chr(0xa2),
+	 # double acute / Hungarian accent
+	 'H O' => chr(0xc5).chr(0x90),
+	 'H o' => chr(0xc5).chr(0x91),
+	 'H U' => chr(0xc5).chr(0xb0),
+	 'H u' => chr(0xc5).chr(0xb1),
+	 
+	 # stroke 
+	 'd' => chr(0xc4).chr(0x91),
+	 'D' => chr(0xc4).chr(0x90),
+	 'h' => chr(0xc4).chr(0xa7),
+#	 'H' => chr(0xc4).chr(0xa6), # !! this normally(!!?) means Hung. umlaut
+	 'i' => chr(0xc4).chr(0xb1), # dotless lowercase i
+	 'l' => chr(0xc5).chr(0x82),
+	 'L' => chr(0xc5).chr(0x81),
+	 'o' => chr(0xc3).chr(0xb8),
+	 'O' => chr(0xc3).chr(0x98),
+	 't' => chr(0xc5).chr(0xa7),
+	 'T' => chr(0xc5).chr(0xa6),
+
+         # other special chars
+         'ss' => chr(0xc3).chr(0x9f), # german ss/szlig/sharp s
+         'aa' =>,chr(0xc3).chr(0xa5), # scandanavian/latin a with ring
+	 );
+
+    my $self=shift;
+    my $textref=shift;
+
+    my $outhandle=$self->{'outhandle'};
+    my $text=$$textref;
+    
+    # remove space (if any) between \ and letter to accent (eg {\' a})
+    $text =~ s!(\\[`'="^~\.])\s(\w)\b!$1$2!g;   # for emacs indenting... `]);
+
+    # remove {} around a single character (eg \'{e})
+    $text =~ s!(\\[`'="^~\.]){(\w)}!{$1$2}!g;  # for emacs indenting... `]);
+
+    ## only in bibtex... not in latex proper?!
+    ### \, is another way of doing cedilla \c
+    ##$text =~ s~\\,(.)~\\c $1~g;
+
+    # remove {} around a single character for special 1 letter commands -
+    # need to insert a space. Eg \v{s}  ->  {\v s}
+    $text =~ s~(\\[uvcH]){(\w)}~{$1 $2}~g;
+
+    # only do if the text contains a '\' character. 
+    if ($text =~ m|\\|) {
+	# "normal" accents - ie non-alpha latex tag
+	# xxx used to have ([\w]\b)@ (for word boundary)
+	while ($text =~ m/\\([`'="^~\.])([\w])/) {      # for emacs `])){
+	    my $tex="$1$2"; my $char="$2";
+	    my $replacement=$utf8_chars{$tex};
+	    if (!defined($replacement)) {
+		$text =~ m~(.{20}\\\Q$tex\E.{20})~s;
+		print $outhandle . $self->{'plugin_type'} .
+		    ": Warning: unknown latex accent \"$tex\""
+		    . " in \"$1\"\n";
+		$replacement=$char;
+	    }
+	    $text =~ s/\\\Q$tex/$replacement/g;
+	}
+
+        # where the following letter matters (eg "sm\o rrebr\o d", \ss{})
+        # only do the change if immediately followed by a space, }, {, or \
+	# one letter accents ( + ss / aa)
+        while ($text =~ m~\\([DdhiLlOoTt]|ss|aa)[{}\s\"\\]~) {
+	    my $tex=$1;
+	    my $replacement=$special_utf8_chars{$tex};
+	    if (!defined($replacement)) {
+		$text =~ m~(.{20}\\\Q$tex\E.{20})~s;
+		print $outhandle $self->{'plugin_type'} .
+		    ": Warning: unknown latex accent \"$tex\""
+		    . " in \"$1\"\n";
+		$replacement=$tex;
+	    }
+	    ($text =~ s/{\\$tex}/$replacement/g) or
+		$text =~ s/\\$tex([{}\s\"\\])/$replacement$1/g;
+
+	}
+
+	# one letter latex accent commands that affect following letter
+        while ($text =~ m~\\([uvcH]) ([\w])~) {
+          my $tex="$1 $2"; my $char="$2";
+          my $replacement=$special_utf8_chars{$tex};
+          if (!defined($replacement)) {
+	      $text =~ m~(.{20}\\\Q$tex\E.{20})~s;
+	      print  $outhandle $self->{'plugin_type'} .
+		  ": Warning: unknown latex accent \"$tex\""
+		  . " in \"$1\"\n";
+	      $replacement=$char;
+	  }
+          $text =~ s/\\$tex/$replacement/g;
+        }
+    }
+    $textref=\$text;
+}
+
+
+# modules must return true
+1;
Index: /gsdl/stable/perllib/plugins/MARCPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/MARCPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/MARCPlugin.pm	(revision 20131)
@@ -0,0 +1,449 @@
+###########################################################################
+#
+# MARCPlugin.pm -- basic MARC plugin
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2002 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package MARCPlugin;
+
+use SplitTextFile;
+
+use unicode;
+use util;
+use marcmapping;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @MARCPlugin::ISA = ('SplitTextFile');
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+}
+
+my $arguments = 
+    [ { 'name' => "metadata_mapping",
+	'desc' => "{common.deprecated} {MARCPlugin.metadata_mapping}",
+	'type' => "string",
+	'deft' => "",
+	'hiddengli' => "yes", # deprecated in favour of 'metadata_mapping_file'
+	'reqd' => "no" },
+      { 'name' => "metadata_mapping_file",
+	'desc' => "{MARCXMLPlugin.metadata_mapping_file}",
+	'type' => "string",
+	'deft' => "marc2dc.txt",
+	'reqd' => "no" },
+      { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() },
+      { 'name' => "split_exp",
+	'desc' => "{SplitTextFile.split_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_split_exp() } 
+      ];
+
+my $options = { 'name'     => "MARCPlugin",
+		'desc'     => "{MARCPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'explodes' => "yes",
+		'args'     => $arguments };
+
+require MARC::Record;  
+require MARC::Batch;  
+#use MARC::Record;  
+#use MARC::Batch;
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new SplitTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about the options
+	return bless $self, $class;
+    }
+    # 'metadata_mapping' was used in two ways in the plugin: as a plugin
+    # option (filename) and as a datastructure to represent the mapping.
+    # In MARXXMLPlug (written later) the two are separated: filename is
+    # represented through 'metadata_mapping_file' and the data-structure
+    # mapping left as 'metadata_mapping'
+    # 'metadata_mapping' still present (but hidden in GLI) for
+    # backwards compatibility, but 'metadata_mapping_file' is used by
+    # preference
+
+    if ($self->{'metadata_mapping'} ne "") {
+	print STDERR "MARCPlugin WARNING:: the metadata_mapping option is set but has been deprecated. Please use metadata_mapping_file option instead\n";
+	# If the old version is set, use it. 
+	$self->{'metadata_mapping_file'} = $self->{'metadata_mapping'};
+    }
+    $self->{'metadata_mapping'} = undef;
+    $self->{'type'} = "";
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+    my ($verbosity, $outhandle, $failhandle) = @_;
+
+    ## the mapping file has already been loaded
+    if (defined $self->{'metadata_mapping'} ){ 
+	$self->SUPER::init(@_);
+	return;
+    }
+
+    # read in the metadata mapping files
+    my $mm_files = &util::locate_config_files($self->{'metadata_mapping_file'});
+    if (scalar(@$mm_files)==0)
+    {
+	my $msg = "MARCPlugin ERROR: Can't locate mapping file \"" .
+	    $self->{'metadata_mapping_file'} . "\".\n " .
+		"    No metadata will be extracted from MARC files.\n";
+
+	print $outhandle $msg;
+	print $failhandle $msg;
+	$self->{'metadata_mapping'} = undef;
+	# We pick up the error in process() if there is no $mm_file
+	# If we exit here, then pluginfo.pl will exit too!
+    }
+    else {
+	$self->{'metadata_mapping'} = &marcmapping::parse_marc_metadata_mapping($mm_files, $outhandle);
+    }
+
+    ##map { print STDERR $_."=>".$self->{'metadata_mapping'}->{$_}."\n"; } keys %{$self->{'metadata_mapping'}};
+
+    $self->SUPER::init(@_);
+}
+
+
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)(\.marc)$^;
+}
+
+
+sub get_default_split_exp {
+    # \r\n for msdos eol, \n for unix
+    return q^\r?\n\s*\r?\n|\[\w+\]Record type: USmarc^;
+}
+
+
+
+# The bulk of this function is based on read_line in multiread.pm
+# Unable to use read_line original because it expects to get its input
+# from a file.  Here the line to be converted is passed in as a string
+
+sub to_utf8
+{
+    my $self = shift (@_);
+    my ($encoding, $line) = @_;
+
+    if ($encoding eq "utf8") {
+	# nothing needs to be done
+	return $line;
+    }
+
+    if ($encoding eq "iso_8859_1") {
+	# we'll use ascii2utf8() for this as it's faster than going
+	# through convert2unicode()
+	return &unicode::ascii2utf8 (\$line);
+    }
+
+    # everything else uses unicode::convert2unicode
+    return &unicode::unicode2utf8 (&unicode::convert2unicode ($encoding, \$line));
+}
+
+
+sub read_file {
+    my $self = shift (@_);
+    my ($filename, $encoding, $language, $textref) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+    
+    if (! defined($self->{'metadata_mapping'}))
+    {
+	# print a warning
+	print $outhandle "MARCPlugin: no metadata mapping file! Can't extract metadata from $filename\n";
+    }
+
+    $self->{'readfile_encoding'}->{$filename} = $encoding;
+
+       
+    if (!-r $filename)
+    {
+	print $outhandle "Read permission denied for $filename\n" if $self->{'verbosity'};
+	return;
+    }
+
+    ##handle ascii marc
+    #test whether this is ascii marc file 
+    if (open (FILE, $filename)) {
+	while (defined (my $line = <FILE>)) {
+	    $$textref .= $line;
+	   if ($line =~ /\[\w+\]Record type:/){
+	       undef $/;
+	       $$textref .= <FILE>;
+	       $/ = "\n";
+	       $self->{'type'} = "ascii";
+	       close FILE;
+	       return;
+	   }
+	}
+	close FILE;	
+    }
+
+      
+    $$textref = "";
+    my @marc_entries = ();
+ 
+    my $batch = new MARC::Batch( 'USMARC', $filename );
+    while ( my $marc = $batch->next ) 
+    {
+      	push(@marc_entries,$marc);
+	$$textref .= $marc->as_formatted();
+	$$textref .= "\n\n"; # for SplitTextFile - see default_split_exp above...
+    }
+
+    $self->{'marc_entries'}->{$filename} = \@marc_entries;
+}
+
+
+
+# do plugin specific processing of doc_obj
+# This gets done for each record found by SplitTextFile in marc files.
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+    my $filename = &util::filename_cat($base_dir, $file);
+
+    my $cursection = $doc_obj->get_top_section();
+
+    # Add fileFormat as the metadata
+    $doc_obj->add_metadata($cursection, "FileFormat", "MARC");
+    
+    my $marc_entries = $self->{'marc_entries'}->{$filename};
+    my $marc = shift(@$marc_entries);
+
+    my $encoding = $self->{'readfile_encoding'}->{$filename};
+
+    if (defined ($self->{'metadata_mapping'}) ) {
+	if ($self->{'type'} ne "ascii" ){   
+	    $self->extract_metadata ($marc, $metadata, $encoding, $doc_obj, $cursection);
+	}
+	else{
+	    $self->extract_ascii_metadata ($$textref,$metadata,$doc_obj, $cursection);
+	}
+    }
+
+    # add spaces after the sub-field markers, for word boundaries
+    $$textref =~ s/^(.{6} _\w)/$1 /gm;
+
+    # add text to document object
+    $$textref =~ s/</&lt;/g;
+    $$textref =~ s/>/&gt;/g;
+
+    $$textref = $self->to_utf8($encoding,$$textref);
+
+    print $outhandle "  Adding Marc Record:\n",substr($$textref,0,40), " ...\n"
+	if $self->{'verbosity'} > 2;
+
+    # line wrapping
+    $$textref = &wrap_text_in_columns($$textref, 64);
+    $$textref = "<pre>\n" . $$textref . "</pre>\n"; # HTML formatting...
+
+    $doc_obj->add_utf8_text($cursection, $$textref);
+
+    return 1;
+}
+
+sub wrap_text_in_columns
+{
+    my ($text, $columnwidth) = @_;
+    my $newtext = "";
+    my $linelength = 0;
+    
+    # Break the text into words, and display one at a time
+    my @words = split(/ /, $text);
+
+    foreach my $word (@words) {
+	# If printing this word would exceed the column end, start a new line
+	if (($linelength + length($word)) >= $columnwidth) {
+	    $newtext .= "\n";
+	    $linelength = 0;
+	}
+	
+	# Write the word
+	$newtext .= " $word";
+	if ($word =~ /\n/) {
+	    $linelength = 0;
+	} else {
+	    $linelength = $linelength + length(" $word");
+	}
+    }
+
+    $newtext .= "\n";
+    return $newtext;
+}
+
+
+sub extract_metadata
+{
+    my $self = shift (@_);
+ 
+    my ($marc, $metadata, $encoding, $doc_obj, $section) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    if (!defined $marc){
+	return;
+    }
+
+    my $metadata_mapping = $self->{'metadata_mapping'};;
+
+    foreach my $marc_field ( keys %$metadata_mapping )
+    {
+	my $gsdl_field = $metadata_mapping->{$marc_field};
+	
+	# have we got a subfield?
+	my $subfield = undef;
+	if ($marc_field =~ /(\d\d\d)(?:\$|\^)?(\w)/){
+	    $marc_field = $1;
+	    $subfield = $2;
+	}
+	if (defined $subfield) {
+	    my $meta_value = $marc->subfield($marc_field, $subfield);
+	    if (defined $meta_value) {
+		# Square brackets in metadata values need to be escaped so they don't confuse Greenstone/GLI
+		$meta_value =~ s/\[/&\#091;/g;
+		$meta_value =~ s/\]/&\#093;/g;
+		my $metavalue_str = $self->to_utf8($encoding, $meta_value);
+		$doc_obj->add_utf8_metadata ($section, $gsdl_field, $metavalue_str);
+	    }
+	}
+	else
+	{
+	    foreach my $meta_value_obj ($marc->field($marc_field))
+	    {
+		my $meta_value = $meta_value_obj->as_string();
+
+		# Square brackets in metadata values need to be escaped so they don't confuse Greenstone/GLI
+		$meta_value =~ s/\[/&\#091;/g;
+		$meta_value =~ s/\]/&\#093;/g;
+		my $metavalue_str = $self->to_utf8($encoding, $meta_value);
+		$doc_obj->add_utf8_metadata ($section, $gsdl_field, $metavalue_str);
+	    }
+	}
+    }
+}
+
+
+sub extract_ascii_metadata 
+{
+    my $self = shift (@_);
+
+    my ($text, $metadata,$doc_obj, $section) = @_;
+    my $outhandle = $self->{'outhandle'};
+    my $metadata_mapping = $self->{'metadata_mapping'};
+    ## get fields
+    my @fields = split(/[\n\r]+/,$text);
+    my $marc_mapping ={};
+
+    foreach my $field (@fields){
+	if ($field ne ""){
+	    $field =~ /^(\d\d\d)\s/;
+	    my $code = $1;
+	    $field = $'; #'
+	    ##get subfields
+	    my @subfields = split(/\$/,$field);
+	    my $i=0;
+	    $marc_mapping->{$code} = [];  
+	    foreach my $subfield (@subfields){
+		if ($i == 0){
+		    ##print STDERR $subfield."\n";
+		    push(@{$marc_mapping->{$code}},"info");
+		    push(@{$marc_mapping->{$code}},$subfield);
+		    	 
+		    $i++;
+		} 
+		 else{
+		     $subfield =~ /(\w)\s/;
+		     ##print STDERR "$1=>$'\n";
+		     push(@{$marc_mapping->{$code}},$1);
+                     push(@{$marc_mapping->{$code}},$'); #'
+		 }
+	    }
+	}
+    }
+
+
+     foreach my $marc_field ( keys %$metadata_mapping )
+    {
+		
+	my $matched_field = $marc_mapping->{$marc_field};
+ 	my $subfield = undef;
+
+	if (defined $matched_field){
+	    ## test whether this field has subfield
+	    if ($marc_field =~ /\d\d\d(\w)/){
+		$subfield = $1;
+	    }
+	    my $metaname = $metadata_mapping->{$marc_field};
+ 
+	    my $metavalue;
+	    if (defined $subfield){
+		my %mapped_subfield = {@$matched_field};
+		$metavalue = $mapped_subfield{$subfield};
+	    }
+	    else{ ## get all values except info
+		my $i =0;
+		foreach my $value (@$matched_field){
+		    if ($i%2 != 0 and $i != 1){
+			$metavalue .= $value." ";
+		    }
+		    $i++;
+		}
+	    }
+	    
+	    ## escape [ and ]
+	    $metavalue =~ s/\[/\\\[/g;
+	    $metavalue =~ s/\]/\\\]/g;
+	    ##print STDERR  "$metaname=$metavalue\n";
+   	    $doc_obj->add_metadata ($section, $metaname, $metavalue) ;		 	
+	}
+       
+    }
+
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/MARCXMLPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/MARCXMLPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/MARCXMLPlugin.pm	(revision 20131)
@@ -0,0 +1,506 @@
+###########################################################################
+#
+# MARCXMLPlugin.pm
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# Processes MARCXML documents. Note that this plugin does no
+# syntax checking (though the XML::Parser module tests for
+# well-formedness).
+
+package MARCXMLPlugin;
+
+use ReadXMLFile;
+use ReadTextFile;
+use marcmapping;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @MARCXMLPlugin::ISA = ('ReadXMLFile', 'ReadTextFile');
+}
+
+my $arguments = [{'name' => "metadata_mapping_file",
+		  'desc' => "{MARCXMLPlugin.metadata_mapping_file}",
+		  'type' => "string",
+		  'deft' => "marc2dc.txt",
+		  'reqd' => "no" }];
+
+my $options = { 'name'     => "MARCXMLPlugin",
+		'desc'     => "{MARCXMLPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments 
+		};
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+    
+    # we want to be able to use the textcat methods from ReadTextFile
+    # to get the language and encoding
+    new ReadTextFile($pluginlist, $inputargs, $hashArgOptLists, 1);
+
+    my $self = new ReadXMLFile($pluginlist, $inputargs, $hashArgOptLists);
+        
+    # we want to strip namespaces, so have to create a new XML parser
+    my $parser = new XML::Parser('Style' => 'Stream',
+                                 'Pkg' => 'ReadXMLFile',
+                                 'PluginObj' => $self,
+				 'Namespaces' => 1, # strip out namespaces
+				 'Handlers' => {'Char' => \&ReadXMLFile::Char,
+						'XMLDecl' => \&ReadXMLFile::XMLDecl,
+						'Entity'  => \&ReadXMLFile::Entity,
+						'Doctype' => \&ReadXMLFile::Doctype,
+						'Default' => \&ReadXMLFile::Default
+                                 });
+
+    $self->{'parser'} = $parser;
+
+    $self->{'content'} = "";
+    $self->{'xmlcontent'} = "";
+    $self->{'record_count'} = 1;
+    $self->{'language'} = "";
+    $self->{'encoding'} = "";
+    $self->{'marc_mapping'} = {};
+    $self->{'current_code'} = "";
+    $self->{'current_tag'} = "";
+    $self->{'current_element'} = "";
+    $self->{'metadata_mapping'} = undef;
+    $self->{'num_processed'} = 0;
+    $self->{'indent'} = 0;
+
+    return bless $self, $class;
+}
+
+
+
+sub get_doctype {
+    my $self = shift(@_);
+    
+    return "collection";
+}
+
+
+sub init {
+    my $self = shift (@_);
+    my ($verbosity, $outhandle, $failhandle) = @_;
+    
+    ## the mapping file has already been loaded
+    if (defined $self->{'metadata_mapping'} ){ 
+	$self->SUPER::init(@_);
+	return;
+    }
+
+    # read in the metadata mapping file
+    my $mm_file = &util::locate_config_file($self->{'metadata_mapping_file'}); 
+
+    if (! defined $mm_file)
+    {
+	my $msg = "MARCXMLPlugin ERROR: Can't locate mapping file \"" .
+	    $self->{'metadata_mapping_file'} . "\".\n " .
+		"    No metadata will be extracted from MARCXML files.\n";
+
+	print $outhandle $msg;
+	print $failhandle $msg;
+	$self->{'metadata_mapping'} = undef;
+	# We pick up the error in process() if there is no $mm_file
+	# If we exit here, then pluginfo.pl will exit too!
+    }
+    else {
+	$self->{'metadata_mapping'} = &marcmapping::parse_marc_metadata_mapping($mm_file, $outhandle);
+    }
+
+
+    ##map { print STDERR $_."=>".$self->{'metadata_mapping'}->{$_}."\n"; } keys %{$self->{'metadata_mapping'}};
+
+    $self->SUPER::init(@_);
+}
+
+# Called for DOCTYPE declarations - use die to bail out if this doctype
+# is not meant for this plugin
+sub xml_doctype {
+    my $self = shift(@_);
+
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+   return;
+
+}
+
+
+sub xml_start_document {
+    my $self = shift(@_);
+
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+
+      
+    my $file = $self->{'file'};
+    my $filename = $self->{'filename'};
+       
+    my ($language, $encoding) = $self->textcat_get_language_encoding ($filename);
+
+    $self->{'language'} = $language;
+    $self->{'encoding'} = $encoding;
+    $self->{'element_count'} = 1;
+    $self->{'indent'} = 0;
+    my $outhandle = $self->{'outhandle'};
+    print $outhandle "MARCXMLPlugin: processing $self->{'file'}\n" if $self->{'verbosity'} > 1;
+    print STDERR "<Processing n='$self->{'file'}' p='MARCXMLPlugin'>\n" if $self->{'gli'};
+
+    # reset the base id
+    $self->{'base_oid'} = undef;
+ 
+}
+
+sub xml_end_document {
+
+}
+
+sub xml_start_tag {
+    my $self = shift;
+    my $expat = shift;
+    my $element = shift;  
+
+    my $text = $_;
+    my $escaped_text =  $self->escape_text($_); 
+  
+    $self->{'current_element'} = $element;
+
+    ##get all atributes of this element and store it in a map name=>value    
+    my %attr_map = (); 
+    my $attrstring = $_;
+    while ($attrstring =~ /(\w+)=\"(\w+)\"/){
+	$attr_map{$1}=$2;
+	$attrstring = $'; #'
+    }
+
+
+    my $processor = $self->{'processor'};
+  
+    ##create a new document for each record 
+    if ($element eq "record") {
+        my $filename = $self->{'filename'};
+	my $language = $self->{'language'};
+        my $encoding = $self->{'encoding'};
+	my $file = $self->{'file'};
+	my $doc_obj = new doc($filename, undef, $self->{'file_rename_method'});
+	$doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Language", $language);
+	$doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Encoding", $encoding);
+	my ($filemeta) = $file =~ /([^\\\/]+)$/;
+	$self->set_Source_metadata($doc_obj, $filemeta, $encoding);
+	$doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "SourceSegment", "$self->{'record_count'}");
+        if ($self->{'cover_image'}) {
+	    $self->associate_cover_image($doc_obj, $filename);
+	}
+	$doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");
+	$doc_obj->add_metadata($doc_obj->get_top_section(), "FileFormat", "MARCXML");
+
+	my $outhandle = $self->{'outhandle'};
+	print $outhandle "Record $self->{'record_count'}\n" if $self->{'verbosity'} > 1; 
+
+        $self->{'record_count'}++;
+        $self->{'doc_obj'} = $doc_obj;       
+	$self->{'num_processed'}++;
+	if (!defined $self->{'base_oid'}) {
+	    $self->SUPER::add_OID($doc_obj);
+	    $self->{'base_oid'} = $doc_obj->get_OID();
+	}
+	
+
+    }
+    
+    ## get the marc code, for example 520
+     if ($element eq "datafield") {
+    	 if (defined $attr_map{'tag'} and $attr_map{'tag'} ne ""){
+	     $self->{'current_tag'} = $attr_map{tag};  
+	 }
+     }
+
+
+    ## append the subcode to the marc code for example 520a or 520b 
+    if ($element eq "subfield"){
+   	if (defined $attr_map{'code'} and $attr_map{'code'} ne "" and $self->{'current_tag'} ne ""){
+	    $self->{'current_code'} = $attr_map{'code'};
+	}
+    }
+
+   if ($element eq "record"){
+        $self->{'indent'} = 0;
+        $self->{'content'} = "";
+        $self->{'xmlcontent'} = "";
+    }
+    else {
+         if ($element ne "subfield"){
+              $self->{'indent'} = 1;
+         }
+         else{
+           $self->{'indent'} = 2;
+         }
+    }
+    
+
+    if ($element eq "collection") {
+	# remember the full start tag for <collection ...>
+	# This is needed to wrap around each <record> when generating its associate MARCXML file
+
+        $self->{'xmlcollectiontag'} = $text;
+    }
+    else {
+        $self->{'content'} .= "<br/>" if ($element ne "record");
+        $self->{'content'} .= $self->calculate_indent($self->{'indent'}).$escaped_text;
+        $self->{'xmlcontent'} .= $text;
+   }
+    
+}
+
+
+
+sub xml_end_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+
+    my $text = $_;
+    my $escaped_text =  $self->escape_text($_); 
+ 
+    if ($element eq "record" and defined $self->{'doc_obj'}) {
+	# process the document
+	my $processor = $self->{'processor'};
+	my $doc_obj = $self->{'doc_obj'};
+        $self->{'content'} .= "<br/>".$escaped_text;
+        $self->{'xmlcontent'} .= $text;
+      
+
+	my $top_section = $doc_obj->get_top_section();
+
+	my $tmp_marcxml_filename = &util::get_tmp_filename("xml");
+	if (open (XMLOUT,">$tmp_marcxml_filename")) {
+
+	    print XMLOUT "<?xml-stylesheet type=\"text/xsl\" href=\"MARC21slim2English.xsl\"?>\n";	    
+	    my $xml_content = $self->{'xmlcontent'};
+
+	    $xml_content = $self->{'xmlcollectiontag'}.$xml_content."</collection>";
+
+	    print XMLOUT $xml_content;
+
+	    close(XMLOUT);
+
+	    $doc_obj->associate_file($tmp_marcxml_filename,"marcxml.xml","text/xml", $top_section);
+	    
+	    # assicate xsl style file for presentation as HTML
+	    my $xsl_filename = &util::filename_cat($ENV{'GSDLHOME'},"etc","MARC21slim2English.xsl");
+	    $doc_obj->associate_file($xsl_filename,"MARC21slim2English.xsl","text/xml", $top_section);
+
+	}
+	else {
+	    my $outhandle = $self->{'outhandle'};
+	    print $outhandle "Warning: Unable for write out associated MARCXML file $tmp_marcxml_filename\n";
+	}
+	
+	# include any metadata passed in from previous plugins 
+	# note that this metadata is associated with the top level section
+	
+	$self->extra_metadata ($doc_obj, 
+			       $doc_obj->get_top_section(), 
+			       $self->{'metadata'});
+	
+
+	$self->add_OID($doc_obj, $self->{'base_oid'}, $self->{'record_count'});
+
+	$doc_obj->add_utf8_text($doc_obj->get_top_section(),$self->{'content'});
+        $processor->process($doc_obj);
+
+        ##clean up
+	$self->{'content'} = "";  
+	$self->{'xmlcontent'} = "";  
+	$self->{'doc_obj'} = undef;
+        return;
+    }
+
+    ## map the xmlmarc to gsdl metadata
+    if ($element eq "datafield" and defined $self->{'doc_obj'} and defined $self->{'marc_mapping'} and defined $self->{'metadata_mapping'}){
+	my $metadata_mapping = $self->{'metadata_mapping'};
+	my $marc_mapping = $self->{'marc_mapping'};
+	my $doc_obj = $self->{'doc_obj'};
+
+	##print STDERR "**** Marc Record\n";
+      ##map { print STDERR $_."=>".$marc_mapping->{$_}."\n"; } keys %$marc_mapping;
+	##print STDERR "**** Metadata Mapping\n";
+      ##map { print STDERR $_."=>".$metadata_mapping->{$_}."\n"; } keys %$metadata_mapping;
+
+
+	foreach my $marc_field (keys %$metadata_mapping){
+
+	    ## test whether this field has subfield
+	    my $subfield = undef;
+	    if ($marc_field =~ /(\d\d\d)(?:\$|\^)?(\w)/){
+		$marc_field = $1;
+		$subfield = $2;
+	    }
+
+	    my $matched_field = $marc_mapping->{$marc_field}; 
+
+	    if (defined $matched_field) {
+
+		my $meta_name  = undef;
+		my $meta_value = undef;
+
+		if (defined $subfield){
+		    $meta_name = $metadata_mapping->{$marc_field."\$".$subfield};
+
+		    $meta_value = $matched_field->{$subfield};
+		    
+		    if (!defined $meta_value) {
+			# record read in does not have the specified subfield
+			next;
+		    }
+		}
+		else {
+		    $meta_name = $metadata_mapping->{$marc_field};
+		    
+		    # no subfield => get all the values
+		    my $first = 1;
+		    foreach my $value (sort keys %{$matched_field}) {
+			if ($first) {
+			    $meta_value = $matched_field->{$value};
+			    $first = 0;
+			} else {
+			    $meta_value .= " " . $matched_field->{$value};
+			}
+		    }
+
+		}
+		
+		## escape [ and ]
+		$meta_value =~ s/\[/\\\[/g;
+		$meta_value =~ s/\]/\\\]/g;
+		##print STDERR  "$meta_name=$meta_value\n";
+		$doc_obj->add_utf8_metadata($doc_obj->get_top_section(),$meta_name, $meta_value);
+		
+	    }		    
+			
+	}
+
+	##clean up
+	$self->{'marc_mapping'} = undef;
+	$self->{'current_tag'} = "";
+    }
+  
+   if ($element eq "datafield"){
+       $self->{'indent'} = 1;
+       $self->{'content'} .= "<br/>".$self->calculate_indent($self->{'indent'}).$escaped_text;
+       $self->{'xmlcontent'} .= $text;
+   }
+    else{
+	$self->{'content'} .= $escaped_text;   
+	$self->{'xmlcontent'} .= $text;   
+    }
+     
+}
+
+sub add_OID {
+    my $self = shift (@_);
+    my ($doc_obj, $id, $record_number) = @_;
+
+    my $full_id = $id . "r" . $record_number;
+    if ($self->{'OIDtype'} eq "assigned") {
+	my $identifier = $doc_obj->get_metadata_element ($doc_obj->get_top_section(), $self->{'OIDmetadata'});
+	if (defined $identifier && $identifier ne "") {
+	    $full_id = $identifier;
+	    $full_id = &util::tidy_up_oid($full_id);
+	}
+    }
+    $doc_obj->set_OID($full_id);
+}
+
+sub xml_text {
+    my $self = shift(@_);
+    my ($expat) = @_;
+
+    my $text = $_;
+    my $escaped_text = $self->escape_text($_);
+
+    # protect against & in raw text file
+    $text =~ s/&/&amp;/g; # can't have & in raw form, even in 'raw' xml text
+
+    ## store the text of a marc code, for exapmle 520a=>A poem about....
+    if ($self->{'current_element'} eq "subfield" and $self->{'current_code'} ne "" and $_ ne "" ){
+	##stored it in the marc_mapping 
+
+	my $current_tag  = $self->{'current_tag'};
+	my $current_code = $self->{'current_code'};
+
+     	$self->{'marc_mapping'}->{$current_tag}->{$current_code} .= $_;
+
+	$self->{'current_code'} = "";
+    }
+    
+    $self->{'content'} .= $escaped_text;
+    $self->{'xmlcontent'} .= $text;
+   
+}
+
+sub calculate_indent{
+   my ($self,$num) = @_;
+
+   my $indent ="";
+  
+   for (my $i=0; $i<$num;$i++){
+       $indent .= "&nbsp;&nbsp;&nbsp;&nbsp;";
+    } 
+ 
+   return $indent;
+
+}
+
+sub escape_text {
+    my ($self,$text) = @_;
+    # special characters in the xml encoding
+    $text =~ s/&/&amp;/g; # this has to be first...
+    $text =~ s/</&lt;/g;
+    $text =~ s/>/&gt;/g;
+    $text =~ s/\"/&quot;/g;
+
+    return $text;
+}
+
+
+sub unescape_text {
+    my ($self,$text) = @_;
+    # special characters in the xml encoding
+    $text =~ s/&lt;/</g;
+    $text =~ s/&gt;/>/g;
+    $text =~ s/&quot;/\"/g;
+
+    $text =~ s/&/&amp;/g; # can't have & in raw form, even in unescaped xml!
+
+    return $text;
+}
+
+
+1;
+
+
Index: /gsdl/stable/perllib/plugins/MP3Plugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/MP3Plugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/MP3Plugin.pm	(revision 20131)
@@ -0,0 +1,370 @@
+###########################################################################
+#
+# MP3Plugin.pm -- Plugin for MP3 files (MPEG audio layer 3).
+#
+# A component of the Greenstone digital library software from the New
+# Zealand Digital Library Project at the University of Waikato, New
+# Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+package MP3Plugin;
+
+use BasePlugin;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+no strict 'subs';
+
+use MP3::Info;
+
+require giget;
+
+sub BEGIN {
+    @MP3Plugin::ISA = ('BasePlugin');
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" },
+      { 'name' => "assoc_images",
+        'desc' => "{MP3Plugin.assoc_images}",
+        'type' => "flag",
+        'deft' => "",
+        'reqd' => "no" },
+      { 'name' => "applet_metadata",
+	'desc' => "{MP3Plugin.applet_metadata}",
+	'type' => "flag",
+	'deft' => "" },
+      { 'name' => "metadata_fields",
+	'desc' => "{MP3Plugin.metadata_fields}",
+	'type' => "string",
+	'deft' => "Title,Artist,Genre" },
+      { 'name' => "file_rename_method",
+	'desc' => "{BasePlugin.file_rename_method}",
+	'type' => "enum",
+	'deft' => &get_default_file_rename_method(), # by default rename imported files and assoc files using this encoding
+	'list' => $BasePlugin::file_rename_method_list,
+	'reqd' => "no"
+      } ];
+
+my $options = { 'name'     => "MP3Plugin",
+		'desc'     => "{MP3Plugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+sub get_default_process_exp {
+    return q^(?i)\.mp3$^;
+}
+
+# rename imported files and assoc files using base64 encoding by default
+# so that the urls generated will always work with media files even when
+# opened in external applications (when wmv file names contain spaces in
+# them and they get url-encoded, wmv player fails to open the doubly url-
+# encoded url reference to the url-encoded filename). 
+sub get_default_file_rename_method() {
+    return "base64";
+}
+
+# we don't want to hash on the file
+sub get_oid_hash_type {
+    my $self = shift (@_);
+    return "hash_on_ga_xml";
+}
+
+sub process {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+
+    # associate the file with the document
+    if ($self->associate_mp3_file($filename_full_path, $filename_no_path, $doc_obj) != 1)
+    {
+	print "MP3Plugin: couldn't process \"$filename_full_path\"\n";
+	return 0;
+    }
+   
+    my $text = &gsprintf::lookup_string("{BasePlugin.dummy_text}",1);
+    if ($self->{'assoc_images'}) {
+	$text .= "[img1]<br>";
+	$text .= "[img2]<br>";
+    }
+    $doc_obj->add_utf8_text($doc_obj->get_top_section(), $text);
+    $doc_obj->add_metadata ($doc_obj->get_top_section(), "NoText",    "1");
+
+}
+
+sub gen_mp3applet {
+
+    my ($mp3_filename) = @_;
+
+    my $applet_html = '
+<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
+        WIDTH = "59"
+        HEIGHT = "32"
+        codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
+<PARAM NAME = CODE VALUE = "javazoom.jlGui.TinyPlayer" >
+<PARAM NAME = ARCHIVE VALUE = "_httpcollection_/tinyplayer.jar,_httpcollection_/jl10.jar" >
+<PARAM NAME="type" VALUE="application/x-java-applet;version=1.3">
+<PARAM NAME="scriptable" VALUE="false">
+<PARAM NAME = "skin" VALUE ="_httpcollection_/skins/Digitalized">
+<PARAM NAME = "autoplay" VALUE ="yes">
+<PARAM NAME = "bgcolor" VALUE ="638182">
+<PARAM NAME = "audioURL" VALUE ="MP3FILENAME">
+<COMMENT>
+<EMBED type="application/x-java-applet;version=1.3"
+       CODE = "javazoom.jlGui.TinyPlayer"
+       ARCHIVE = "_httpcollection_/tinyplayer.jar,_httpcollection_/jl10.jar"
+       WIDTH = "59"
+       HEIGHT = "32"
+       skin = "_httpcollection_/skins/Digitalized"
+       autoplay = "yes"
+       bgcolor = "638182"
+       audioURL = "MP3FILENAME"
+       scriptable=false
+       pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html">
+<NOEMBED>
+</COMMENT>
+</NOEMBED></EMBED>
+</OBJECT>
+';
+
+    $applet_html =~ s/MP3FILENAME/$mp3_filename/g;
+
+    return $applet_html;
+}
+
+
+
+# Associate the mp3 file with the new document
+
+sub associate_mp3_file {
+    my $self = shift (@_);
+    my $filename = shift (@_);   # filename with full path
+    my $file = shift (@_);       # filename without path
+    my $doc_obj = shift (@_);
+    
+    my $verbosity = $self->{'verbosity'};
+    my $outhandle = $self->{'outhandle'};
+
+    # check the filename is okay
+    return 0 if ($file eq "" || $filename eq "");
+
+    # Add the file metadata.
+    # $assoc_url will be the srcurl. Since it is URL encoded here, it will be
+    # able to cope with special characters--including spaces--in mp3 filenames.
+    # the assocfilename generated will be a URL encoded version of the utf8 filename
+    my $assoc_url = $doc_obj->get_sourcefile(); 
+    my $dst_file = $doc_obj->get_assocfile_from_sourcefile();
+
+    # Add the file as an associated file ...
+    my $section = $doc_obj->get_top_section();
+    my $mime_type = $self->{'mime_type'} || "audio/mp3";
+    my $assoc_field = $self->{'assoc_field'} || "mp3";
+    my $assoc_name = $file;
+    $assoc_name =~ s/\.mp3$//;
+
+    $doc_obj->associate_file($filename, $dst_file, $mime_type, $section);
+    $doc_obj->add_metadata ($section, $assoc_field, $assoc_name);
+    $doc_obj->add_metadata ($section, "srcurl", $assoc_url);
+
+    my $mp3_info = get_mp3info($filename);
+    my $mp3_tags = get_mp3tag($filename);
+
+    my $metadata_fields = $self->{'metadata_fields'};
+
+    if ($metadata_fields eq "*") {
+	# Locate all info and tag metadata
+
+	foreach my $ki ( keys %$mp3_info ) {
+	    my $mp3_metavalue = $mp3_info->{$ki};
+
+	    if ($mp3_metavalue !~ m/^\s*$/s) {
+		my $mp3_metaname = "mp3:".lc($ki);
+		$doc_obj->add_metadata ($section, $mp3_metaname, $mp3_metavalue);
+	    }
+	}
+
+	foreach my $kt ( keys %$mp3_tags ) {
+	    my $mp3_metavalue = $mp3_tags->{$kt};
+	    
+	    if ($mp3_metavalue !~ m/^\s*$/s) {
+		my $kt_len = length($kt);
+		my $kt_initial_cap = uc(substr($kt,0,1)).lc(substr($kt,1,$kt_len-1));
+		my $mp3_metaname = "mp3:".$kt_initial_cap;
+		
+		$doc_obj->add_metadata ($section, $mp3_metaname, $mp3_metavalue);
+	    }
+	}
+    }
+    else {
+
+	# Restrict metadata to that specifically given
+	foreach my $field (split /,/, $metadata_fields) {
+
+	    # check info
+	    if (defined $mp3_info->{$field}) {
+
+		my $mp3i_metavalue = $mp3_info->{$field};
+		
+		if ($mp3i_metavalue !~ m/^\s*$/s) {
+		    my $mp3i_metaname = "mp3:".lc($field);
+		    $doc_obj->add_metadata ($section, $mp3i_metaname, $mp3i_metavalue);
+		}
+	    }
+
+	    # check tags
+	    if (defined $mp3_tags->{uc($field)}) {
+
+		my $mp3t_metavalue = $mp3_tags->{uc($field)};
+		
+		if ($mp3t_metavalue !~ m/^\s*$/s) {
+		    my $mp3t_metaname = "mp3:".$field;
+		    
+		    $doc_obj->add_metadata ($section, $mp3t_metaname, $mp3t_metavalue);
+		}
+	    }
+	    
+	}
+    }
+
+    $doc_obj->add_metadata ($section, "FileFormat", "MP3");
+    
+    $doc_obj->add_metadata ($section, "srclink", 
+			    "<a href=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[srcurl]\">");
+    $doc_obj->add_metadata ($section, "srcicon", "_iconmp3_");
+    $doc_obj->add_metadata ($section, "/srclink", "</a>");
+
+    my $applet_metadata = $self->{'applet_metadata'};
+    if (defined $applet_metadata && $applet_metadata ) {
+	my $applet_html 
+	    = gen_mp3applet("_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[srcurl]");
+	$doc_obj->add_metadata ($section, "mp3applet", $applet_html);
+    }
+
+    my $assoc_images = $self->{'assoc_images'};
+    if (defined $assoc_images && $assoc_images) {
+	my @search_terms = ();
+
+	my $title  = $mp3_tags->{'TITLE'};
+	my $artist = $mp3_tags->{'ARTIST'};
+
+	if (defined $title && $title ne "") {
+
+	    push(@search_terms,$title);
+
+	    if (defined $artist && $artist ne "") {
+		push(@search_terms,$artist);
+	    }
+	}
+	else {
+	    push(@search_terms,$assoc_name);
+	}
+
+	push(@search_terms,"song");
+
+	my $output_dir = $filename;
+	$output_dir =~ s/\.\w+$//;
+
+	my ($imgref_urls) = giget(\@search_terms,$output_dir);
+
+	my $gi_base = gi_url_base();
+	my $gi_query_url = gi_query_url(\@search_terms);
+
+	$doc_obj->add_metadata ($section, "giquery", "<a href=\"$gi_base$gi_query_url\" target=giwindow>");
+	$doc_obj->add_metadata ($section, "/giquery", "</a>");
+
+	for (my $i=1; $i<=2; $i++) {
+	    my $img_filename = "$output_dir/img_$i.jpg";
+	    my $dst_file = "img_$i.jpg";
+
+	    if (-e $img_filename) {
+		$doc_obj->associate_file($img_filename, $dst_file, "image/jpeg", $section);
+
+		my $srcurl = "src=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/$dst_file\"";
+
+		$doc_obj->add_metadata ($section, "img$i", 
+					"<img $srcurl>");
+		$doc_obj->add_metadata ($section, "smallimg$i", 
+					"<img $srcurl width=100>");
+
+		my $imgref_url = $imgref_urls->[$i-1];
+
+		$doc_obj->add_metadata ($section, "imgref$i", "<a href=\"$imgref_url\" target=giwindow>");
+		$doc_obj->add_metadata ($section, "/imgref$i", "</a>");
+	    }
+
+	}
+
+
+    }
+
+    return 1;
+}
+
+
+# we want to use mp3:Title if its there, otherwise we'll use BasePlugin method
+sub title_fallback
+{
+    my $self = shift (@_);
+    my ($doc_obj,$section,$file) = @_;
+
+    if (!defined $doc_obj->get_metadata_element ($section, "Title")) {
+	my $mp3_title = $doc_obj->get_metadata_element ($section, "mp3:Title");
+	if (defined $mp3_title) {
+	    $doc_obj->add_metadata ($section, "Title", $mp3_title);
+	}
+	else {
+	    $self->BasePlugin::title_fallback($doc_obj, $section, $file);
+	}
+    }
+}
+
+
+1;
+
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/perllib/plugins/MediaWikiPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/MediaWikiPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/MediaWikiPlugin.pm	(revision 20131)
@@ -0,0 +1,665 @@
+###########################################################################
+#
+# MediaWikiPlugin.pm -- html plugin with extra facilities for wiki page 
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+# This plugin is to process an HTML file from a MediaWiki website which downloaded by 
+# the MediaWikiDownload plug. This plugin will trim MediaWiki functional sections like 
+# login, discussion, history, etc. Only the navigation and search section could be preserved. 
+# Searchbox will be modified to search the Greenstone collection instead of the website.
+# It also can automatically add the table of contents on the website's Main_Page to the 
+# collection's Home page. 
+
+package MediaWikiPlugin;
+
+use HTMLPlugin;
+use unicode;
+
+use strict; # every perl program should have this!
+no strict 'refs'; # make an exception so we can use variables as filehandles
+
+
+sub BEGIN {
+    @MediaWikiPlugin::ISA = ('HTMLPlugin');        
+}
+
+my $arguments = 
+    [          
+     # show the table of contents on collection's home page
+     { 'name' => "show_toc",
+       'desc' => "{MediaWikiPlugin.show_toc}",
+       'type' => "flag",
+       'reqd' => "no"},
+     # set to delete the table of contents section on each MediaWiki page
+     { 'name' => "delete_toc",
+       'desc' => "{MediaWikiPlugin.delete_toc}",
+       'type' => "flag",
+       'reqd' => "no"},
+     # regexp to match the table of contents
+     { 'name' => "toc_exp",
+       'desc' => "{MediaWikiPlugin.toc_exp}",
+       'type' => "regexp",
+       'reqd' => "no",
+       'deft' => "<table([^>]*)id=(\\\"|')toc(\\\"|')(.|\\n)*?</table>\\n" },        
+     # set to delete the navigation section
+     { 'name' => "delete_nav",
+       'desc' => "{MediaWikiPlugin.delete_nav}",
+       'type' => "flag",
+       'reqd' => "no",
+       'deft' => ""}, 
+     # regexp to match the navigation section    
+     { 'name' => "nav_div_exp",
+       'desc' => "{MediaWikiPlugin.nav_div_exp}",
+       'type' => "regexp",
+       'reqd' => "no",
+       'deft' => "<div([^>]*)id=(\\\"|')p-navigation(\\\"|')(.|\\n)*?<\/div>" },
+     # set to delete the searchbox section
+     { 'name' => "delete_searchbox",
+       'desc' => "{MediaWikiPlugin.delete_searchbox}",
+       'type' => "flag",
+       'reqd' => "no",
+       'deft' => ""},
+     # regexp to match the searchbox section
+     { 'name' => "searchbox_div_exp",
+       'desc' => "{MediaWikiPlugin.searchbox_div_exp}",
+       'type' => "regexp",
+       'reqd' => "no",
+       'deft' => "<div([^>]*)id=(\\\"|')p-search(\\\"|')(.|\\n)*?<\/div>"},     
+     # regexp to match title suffix
+     # can't use the title_sub option in HTMLPlugin instead
+     # because title_sub always matches from the begining      
+     { 'name' => "remove_title_suffix_exp",
+       'desc' => "{MediaWikiPlugin.remove_title_suffix_exp}",
+       'type' => "regexp",
+       'reqd' => "no",
+       'deft' => ""}
+     ];
+
+my $options = { 'name'     => "MediaWikiPlugin",
+		'desc'     => "{MediaWikiPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+    
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+    
+    my $self = new HTMLPlugin($pluginlist, $inputargs, $hashArgOptLists);    
+    return bless $self, $class;
+}
+
+
+
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my @head_and_body = split(/<body/i,$$textref);
+    my $head = shift(@head_and_body);
+    my $body_text = join("<body", @head_and_body);      
+    
+    $head =~ m/<title>(.+)<\/title>/i;
+    my $doctitle = $1 if defined $1;    
+    
+    if (defined $self->{'metadata_fields'} && $self->{'metadata_fields'}=~ /\S/) {
+	my @doc_properties = split(/<xml>/i,$head);
+	my $doc_heading = shift(@doc_properties);
+	my $rest_doc_properties = join(" ", @doc_properties);
+	
+	my @extracted_metadata = split(/<\/xml>/i, $rest_doc_properties);
+	my $extracted_metadata = shift (@extracted_metadata);
+	$self->extract_metadata($extracted_metadata, $metadata, $doc_obj);
+    }
+    
+    # set the title here if we haven't found it yet
+    if (!defined $doc_obj->get_metadata_element ($doc_obj->get_top_section(), "Title")) {    
+	if (defined $doctitle && $doctitle =~ /\S/) {        	    
+            # remove suffix in title if required
+            my $remove_suffix_exp = $self->{'remove_title_suffix_exp'};
+	    if (defined $remove_suffix_exp && $remove_suffix_exp =~ /\S/){
+	       $doctitle =~ s/$remove_suffix_exp//i;
+	    }	    
+	    $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Title", $doctitle);
+	} else {
+	    $self->title_fallback($doc_obj,$doc_obj->get_top_section(),$file);
+	}
+    }
+
+    # we are only interested in the column-contents div <div id="column-content">
+    # remove header section, it may contain header images or additional search boxes
+    my $header_exp = "<div([^>]*)id=(\"|')container(\"|')([^>]*)>(.|\\n)*<div([^>]*)id=(\"|')column-content";
+    if($body_text =~ /$header_exp/){
+	    $body_text =~ s/$header_exp/<div$1id='container'$4><div$6id='column-content/isg;
+	} else {				
+		$header_exp = "(.|\\n)*?<div([^>]*)?id=(\"|')column-content";
+                if($body_text =~ /$header_exp/){
+                  $body_text =~ s/$header_exp/<div$2id='column-content/i;                
+                }
+	}
+    
+    # remove timeline
+    $body_text =~ s/<div([^>]*)class=("|')smwtimeline("|')[\s\S]*?<\/div>//mg;
+    
+    # remove extra bits
+    my $extra_bits = "Retrieved from(.+)</a>\"";
+    $body_text =~ s/$extra_bits//isg;
+    
+    $body_text =~ s/(<p[^>]*><span[^>]*><o:p>&nbsp;<\/o:p><\/span><\/p>)//isg;
+    $body_text =~ s/(<p[^>]*><o:p>&nbsp;<\/o:p><\/p>)//isg;
+    $body_text =~ s/<!\[if !vml\]>/<![if vml]>/g; 
+    $body_text =~ s/(&nbsp;)+/&nbsp;/sg;
+    
+    # get rid of the [edit] buttons
+    $body_text =~ s/\[<a([^>]*)>edit<\/a>]//g;
+    # get rid of the last time edit information at the bottom
+    $body_text =~ s/<a href="([^>]*)edit([^>]*)"([^>]*?)>(\w+)<\/a> \d\d:\d\d,([\s|\w]*?)\(PST\)//g;    
+    # get rid of the (Redirected from ...)
+    $body_text =~ s/\(Redirected from <a ([^>]*)>(\w|\s)*?<\/a>\)//isg;  
+    
+    # escape texts macros
+    $body_text =~ s/_([^\s]*)_/_<span>$1<\/span>_/isg;
+    # may change the links, like Greenstone_Documentation_All.html, then change back
+    $body_text =~ s/<a([^>]*)_<span>([^>]*)<\/span>_/<a$1_$2_/isg;
+    
+    # define file delimiter for different platforms
+    my $file_delimiter;
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+       $file_delimiter = "\\";
+    } else {
+       $file_delimiter = "/";	        
+    }    
+    
+    # IMPORTANT: different delimiter for $base_dir and $file
+    # $base_dir use forward slash for both windows and linux
+    # print "\nbase_dir : $base_dir\n\n"; # windows: C:/Program Files/Greenstone2.73/collect/wiki/import    
+                                        # linux: /research/lh92/greenstone/greenstone2.73/collect/wiki/import
+    # $file use different delimiters : forward slash for linux; backward slash for windows
+    # print "\nfile : $file\n\n";         # windows: greenstone.sourceforge.net\wiki\index.php\Access_Processing_using_DBPlugin.html    
+                                        # linux: greenstone.sourceforge.net/wiki/index.php/Using_GreenstoneWiki.html
+    
+    # get the base url for the MediaWiki website
+    my $safe_delimiter = &safe_escape_regexp($file_delimiter);
+    my @url_dirs=split($safe_delimiter, $file);
+    my $url_base = $url_dirs[0];    
+        
+    # Re-check css files associated with MediaWiki pages
+    if(defined $base_dir && $base_dir ne ""){ 	
+	my @css_files;
+	my $css_file_count = 0;
+	
+	# find all the stylesheets imported with @import statement	
+	while($head =~ m"<style type=\"text/css\"(.+)import \"(.+)\""ig){
+	    $css_files[$css_file_count++] = $2 if defined $2;
+	}
+	    
+	# download the stylesheets if we haven't downloaded them yet
+        # add prefix to each style elmement, comment out the body element
+        # and copy the files to collection's style folder 
+	for ($css_file_count = 0; $css_file_count < scalar(@css_files); $css_file_count++) {	    
+	    
+	    my $css_file = $css_files[$css_file_count];	      
+	    
+	    # remove prefix gli/cache directory	                
+            $css_file =~ s/^(.+)gli(\\|\/)cache(\\|\/)//i;
+                        
+            # change the \ delimiter in $css_file to / for consistency
+            $css_file =~ s/\\/\//isg;
+            if($css_file !~ /$url_base/) {
+              $css_file = $url_base . $css_file;  
+            }
+            
+            # trim the ? mark append to the end of a stylesheet
+	    $css_file =~ s/\?(.+)$//isg;  
+	   
+            my $css_file_path = &util::filename_cat($base_dir, $css_file);	    
+	    
+	    # do nothing if we have already downloaded the css files
+	    if (! -e $css_file_path) {		
+	     
+             # check the stylesheet's directory in the import folder
+             # if the directory doesn't exist, create one            
+	     my @dirs = split(/\//i,$css_file);	    
+	     my $path_check = "$base_dir/";            
+	     for (my $i = 0; $i < (scalar(@dirs)-1); $i++) {
+		$path_check .= $dirs[$i] . "/";	
+		mkdir($path_check) if (! -d $path_check );
+	     }
+	     
+             # NOTE: wget needs configuration to directly access Internet
+             # These files should already downloaded if we used the MediaWikiDownload             
+	     # downloading            
+	     $css_file = "http://$css_file";	    
+             print "\ndownloading : " . $css_file . "\n\n";
+	     system("wget", "--non-verbose", "$css_file", "--output-document=$css_file_path");
+	     if ($? != 0) {
+              print "[ERROR] Download Failed! Make sure WGet connects to Internet directly \n";
+              print "[ERROR] OR ues the MediaWikiDownload in the GLI DownloadPanel to download from a MediaWiki website\n";
+              unlink("$css_file_path");
+             }
+            } # done with download
+		
+	    # add a prefix "#wikispecificstyle" to each element
+	    # because we want to preserve this website's formats and don't want to mess up with Greenstone formats
+            # so we will wrap the web page with a div with id = wikispecificstyle
+            my $css_content;
+	    if(open(INPUT, "<$css_file_path")){		
+		while(my $line = <INPUT>){
+                    # comment out the body element because we change the body to div
+                    $line =~ s/^(\s*)body(\s*){(\s*)$/$1\/*body$2*\/{$3/isg;
+                    
+                    if($line =~ m/^(.+)\{/i || $line =~ m/^(\s)*#/i){                    
+                      if($line !~ m/wikispecificstyle/i){
+                        $line = "#wikispecificstyle " . $line;
+                      } 
+                    }
+                    
+		    $css_content .= $line;
+		}
+		close(INPUT);			
+		open(OUTPUT, ">$css_file_path");
+		print OUTPUT $css_content;
+		close(OUTPUT);
+	    }
+            
+            # Copy the modified stylesheets to collection's style folder
+            # for future customization
+            my $style_dir = $base_dir;
+            $style_dir =~ s/import$/style/;
+            $css_file =~ m/(.*)\/(.*)$/;
+            $style_dir = &util::filename_cat($style_dir, $2);            
+            
+            if(open(OUTPUT, ">$style_dir")){	
+              print OUTPUT $css_content;
+              close(OUTPUT);
+            }
+	}
+    }    
+    
+    
+    # by default, only preserve navigation box and search box
+    # others like toolbox, interaction, languages box, will be removed  
+    
+    # extract the larger part -- footer section
+    my $print_footer = "<div class=\"printfooter\">(.|\n)+</body>";
+    $body_text =~ /$print_footer/;
+    my $footer = "";
+    $footer = $& if defined $&;
+    $footer =~ s/<\/body>//isg;
+    
+    # trim the comments first    
+    $footer =~ s/<!--[\s\S]*?--[ \t\n\r]*>//isg;
+    
+    # contain sections that are to be preserved
+    my $preserve_sections = "";   
+    
+    # process the navigation section    
+    my $nav_match_exp = "<div([^>]*)id=(\"|')p-navigation(\"|')(.|\n)*?<\/div>";
+    if (defined $self->{'nav_div_exp'}) {
+      $nav_match_exp = $self->{'nav_div_exp'} if ($self->{'nav_div_exp'} =~ /\S/) ;
+    }
+        
+    if (defined $self->{'delete_nav'} && ($self->{'delete_nav'} eq "1")) {	
+        # do nothing	
+    } else {      
+      if ($footer =~ m/$nav_match_exp/ig) {
+        $preserve_sections = $& ;
+      } else {
+        print $outhandle "Can't find the navigation section with : $nav_match_exp\n";
+      }
+      # if($preserve_sections =~/\S/){
+      #  $preserve_sections .= "</div>";
+      # }            
+    }          
+            
+    # process the searchbox section        
+    my $searchbox_exp = "<div([^>]*)id=(\"|')p-search(\"|')(.|\\n)*?<\/div>";
+    if(defined $self->{'searchbox_div_exp'}) {                
+        $searchbox_exp = $self->{'searchbox_div_exp'} if ($self->{'searchbox_div_exp'} =~ /\S/);
+    }    
+                        
+    my $searchbox_section = "";    
+    $footer =~ m/$searchbox_exp/ig;
+    $searchbox_section = $& if defined $&;    
+    
+    # make the searchbox form work in Greenstone
+    if($searchbox_section =~ /\S/){        
+        # replace action
+        $searchbox_section =~ s/action="([^>]*)"/action="_gwcgi_"/isg;
+                
+        # remove buttons
+        $searchbox_section =~ s/name="search"/name="q"/isg;
+        $searchbox_section =~ s/name="go"//isg;
+        $searchbox_section =~ s/name="fulltext"//isg;
+                
+        # get collection name from $base_dir for c param        
+        $base_dir =~ m/\/collect\/(.+)\//i;
+        my $collection_name = "";
+        $collection_name = $1 if defined $1;
+        
+        # add Greenstone search params
+        my $hidden_params = "<input type=\"hidden\" name=\"a\" value=\"q\"/>\n" 
+            ."<input type=\"hidden\" name=\"c\" value=\"$collection_name\"/>\n";
+            # ."<input type=\"hidden\" name=\"fqf\" value=\"TX\"/>\n"
+            # ."<input type=\"hidden\" name=\"r\" value=\"1\">\n";
+        
+        $searchbox_section =~ s/<form([^>]*)>/<form$1>\n$hidden_params/isg;         
+        
+        # $searchbox_section .= "</div>";
+    } else {
+      print $outhandle "Can't find the searchbox section with : $searchbox_section\n";
+    }        
+    
+    # either delete or replace the searchbox 
+    if(defined $self->{'delete_searchbox'} && $self->{'delete_searchbox'} eq "1") {
+        # do nothing        
+    } else {
+        $preserve_sections .= "\n$searchbox_section\n";
+    } 
+    
+    if($preserve_sections ne ""){
+      $preserve_sections = "<div id=\"column-one\">\n" . $preserve_sections . "\n</div>\n";
+    }
+    $preserve_sections = "</div></div></div>\n" . $preserve_sections . "\n</body>";   
+            
+    $body_text =~ s/$print_footer/$preserve_sections/isg;
+    
+    
+    # delete other forms in the page
+    my @forms;
+    my $form_count = 0;
+    while($body_text =~ m/<form([^>]*)name=("|')([^>"']*)?("|')/isg){
+        next if($3 eq "searchform");
+        $forms[$form_count++] = $&;        
+    }
+    foreach my $form (@forms) {      
+      $body_text =~ s/$form[\s\S]*?<\/form>//m;
+    }
+    
+    # process links. 
+    # because current WGET 1.10 the -k and -E option doesn't work together
+    # need to 'manually' convert the links to relative links
+    # Dealing with 3 types of links:
+    # -- outgoing links
+    #   -- if we have downloaded the target files, link to the internal version (relative link)
+    #   -- otherwise, link to the external version (absolute links)
+    # -- in-page links (relative link)
+    
+    # NOTE: (important)
+    #   must use the MediaWikiDownload in GLI Download Panel to download files from a MediaWiki website
+    #   otherwise, the internal links may have problems
+    
+    # remove the title attribute of <a> tag
+    $body_text =~ s/<a([^>]*)title="(.*?)"/<a$1/isg;
+    
+    # extract all the links
+    my @links;
+    my $link_count = 0;    
+    while($body_text =~ m/(href|src)="([^>\s]*)$url_base\/([^>\s]*)"/ig){        
+        $links[$link_count++] = "$1=\"$2$url_base/$3\"";		
+    }
+    
+    foreach my $cur_link (@links) {     
+        # escape greedy match + character
+        $cur_link =~ s/\+/\\+/isg;
+        
+        $cur_link =~ m/(.+)"([^>]*)$url_base\/([^>\s]*)"/;          
+        my $external_file_path = "$1\"http://$url_base/$3\"";
+           
+        $body_text =~ s/$cur_link/$external_file_path/i; 
+    }
+             
+    # tag links to new wiki pages as red    
+    $body_text =~ s/<a([^>]*)class="new"([^>]*)>/<a$1style="color:red"$2)>/gi;
+    
+    # tag links to pages external of the MediaWiki website as blue
+    $body_text =~ s/<a([^>]*)class='external text'([^>]*)>/<a$1style="color:blue"$2)>/gi;
+        
+    
+    # process the table-of-contents section
+    # if 'show_toc' is set, add Main_Page's toc to the collection's About page, change extra.dm file     
+    # 1. read _content_ macro from about.dm
+    # 2. append the toc, change all links to the Greenstone internal format for relative links 
+    # 3. write to the extra.dm
+    # TODO: we assume the _about:content_ hasn't been specified before
+    #	    so needs to add function to handle when the macro is already in the extra.dm	   
+    if($self->{'show_toc'}==1 && $file =~ m/Main_Page.(html|htm)$/){
+    
+      # extract toc of the Main_Page           	 
+      my $mainpage_toc = "";  
+      my $toc_exp = "<table([^>]*)id=(\"|')toc(\"|')(.|\\n)*</table>\\n";
+      if($self->{'toc_exp'} =~ /\S/){
+         $toc_exp = $self->{'toc_exp'};	     
+      }
+      if($body_text =~ /$toc_exp/){                      	
+        $mainpage_toc = $&;
+      }
+        
+      if($mainpage_toc =~ /\S/) {
+        
+        # change the in-page links to relative links, for example, change <a href="#section1"> to 
+        # <a href="_httpquery_&a=extlink&rl=1&href=http://www.mediawikisite.com/Main_Page.html#section1">           
+        my $file_url_format = $file;
+        $file_url_format =~ s/\\/\//isg; 
+	$file_url_format = "http://" . $file_url_format;
+	   
+        # encode as URL, otherwise doesn't work on Windows
+        $file_url_format =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg;
+	$mainpage_toc =~ s/<a href="([^>"#]*)#([^>"]*)"/<a href="_httpquery_&a=extlink&rl=1&href=$file_url_format#$2"/isg;
+        
+        
+        # read the collection's extra.dm    
+        my $macro_path = $base_dir;
+        $macro_path =~ s/import$/macros/;    	
+    	my $extradm_file = &util::filename_cat($macro_path, "extra.dm");        
+        
+        my $extra_dm = "";
+        if(open(INPUT, "<$extradm_file")){    	            
+	    while(my $line = <INPUT>){
+		$extra_dm .= $line;
+	    }	    	
+        } else {
+            print $outhandle "can't open file $extradm_file\n";
+        }
+        close(INPUT);
+        
+        # check whether we have changed the macros
+        my @packages = split("package ", $extra_dm);
+        my $about_package = "";
+        foreach my $package (@packages) {
+          $about_package = "package " . $package if($package =~ /^about/);
+        }      
+                
+        my $update_extra_dm = 0;        
+        
+        if( $about_package =~ /\S/ && $about_package =~ m/_content_(\s*){/ && $about_package =~ m/$mainpage_toc/){  
+	   print $outhandle "_content_ macro already changed!!!!\n";
+	}
+        # if extra.dm doesn't have an "about package"
+        elsif ($about_package !~ /\S/) {          
+          # read _content_ macro from $GSDLHOME/macros/about.dm file          
+	  my $global_about_package = $self->read_content_from_about_dm();	    
+            
+          # create the extra _content_ macro for this collection           
+          # add the original content of the _content_ macro
+          $global_about_package =~ m/{(.|\n)*<\/div>\n\n/;
+          
+          # append the new about package to extra.dm
+          $extra_dm .= "\n\npackage about\n_content_$&\n\n";
+          $extra_dm .= "<div class=\"section\">\n$mainpage_toc\n</div>\n</div>\n}";
+          
+          $update_extra_dm = 1;
+        } 
+        # the about package exists, but either doesn't have the _content_ macro or 
+        # the _content_ macro doesn't contain the toc
+        else {        
+          # check if there is a content macro   
+          my $content_macro_existed = 0;
+          $content_macro_existed = ($about_package =~ /(\s*|\n)_content_(\s*){/);
+            
+          # if there is one
+          # append a new section div for toc to the end of the document section                    
+          if($content_macro_existed ==1) {
+            $about_package =~ /(\s*|\n)_content_(\s*){(.|\n)*?}/;
+            my $content_macro = $&;                          
+            my $new_content_macro = $content_macro;
+            $new_content_macro =~ s/<div[^>]*class="document">(.|\n)*<\/div>/<div$1class="document">$2\n\n<div class="section">\n$mainpage_toc\n<\/div>\n<\/div>/;              
+            $extra_dm =~ s/$content_macro/$new_content_macro/mg;                                    
+          }
+          # otherwise, append _content_ macro to the about package
+          else {
+            my $new_about_package = $about_package;            
+            my $content_macro = &read_content_from_about_dm();
+            $content_macro =~ m/{(.|\n)*<\/div>\n\n/;            
+            
+            $new_about_package .= "\n\n_content_$&\n\n";
+            $new_about_package .= "<div class=\"section\">\n$mainpage_toc\n</div>\n</div>\n}";              
+            $extra_dm =~ s/$about_package/$new_about_package/mg;   
+          } 
+          
+          # either the case, we need to update the extra.dm         
+          $update_extra_dm = 1;
+         }          
+                  
+         if($update_extra_dm==1){
+            # write to the extra.dm file of the collection
+            if (open(OUTPUT, ">$extradm_file")) {
+                print OUTPUT $extra_dm;
+            } else {
+                print "can't open $extradm_file\n";
+            }
+            close(OUTPUT);
+         }
+      } else {
+        print $outhandle "Main_Page doesn't have a table-of-contents section\n";
+      }
+    }
+	
+    # If delete_toc is set, remove toc and tof contents.    
+    if (defined $self->{'delete_toc'} && ($self->{'delete_toc'} == 1)){
+	if (defined $self->{'toc_exp'} && $self->{'toc_exp'} =~ /\S/){		
+          # print "\nit matches toc_exp !!\n" if $body_text =~ /$self->{'toc_exp'}/;
+          if ($body_text =~ /$self->{'toc_exp'}/) {
+	    $body_text =~ s/$self->{'toc_exp'}//i;	    
+          }
+	}
+    }        
+    
+    $$textref = "<body" . $body_text;
+    
+    # Wrap the whole page with <div id="wikispecificstyle"></div>
+    # keep the style of this website and don't mess up with the Greenstone styles
+    $$textref =~ s/<body([^>]*)>/$&\n<div id="wikispecificstyle">\n/is;
+    $$textref =~ s/<\/body>/<\/div><\/body>/is;     
+	       
+    $self->SUPER::process(@_);
+    
+    return 1;
+}
+
+
+sub extract_metadata 
+{
+    my $self = shift (@_);
+    my ($textref, $metadata, $doc_obj) = @_;
+    my $outhandle = $self->{'outhandle'};
+    
+    return if (!defined $textref);
+
+    # metadata fields to extract/save. 'key' is the (lowercase) name of the
+    # html meta, 'value' is the metadata name for greenstone to use
+    my %find_fields = ();
+    my ($tag,$value);
+
+    my $orig_field = "";
+    foreach my $field (split /,/, $self->{'metadata_fields'}) {
+	# support tag<tagname>
+	if ($field =~ /^(.*?)<(.*?)>$/) {
+	    # "$2" is the user's preferred gs metadata name
+	    $find_fields{lc($1)}=$2; # lc = lowercase
+	    $orig_field = $1;
+	} else { # no <tagname> for mapping
+	    # "$field" is the user's preferred gs metadata name
+	    $find_fields{lc($field)}=$field; # lc = lowercase
+	    $orig_field = $field;
+	}
+
+	if ($textref =~ m/<o:$orig_field>(.*)<\/o:$orig_field>/i){
+	    $tag = $orig_field;
+	    $value = $1;
+	    if (!defined $value || !defined $tag){
+		#print $outhandle "MediaWikiPlugin: can't find VALUE in \"$tag\"\n";
+		next;
+	    } else {
+		# clean up and add
+		chomp($value); # remove trailing \n, if any
+		$tag = $find_fields{lc($tag)};
+		#print $outhandle " extracted \"$tag\" metadata \"$value\"\n" 
+		#    if ($self->{'verbosity'} > 2);
+		$doc_obj->add_utf8_metadata($doc_obj->get_top_section(), $tag, $value);
+	    }
+	}
+    }
+}
+
+sub safe_escape_regexp
+{
+  my $regexp = shift (@_);
+  
+  # if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+    $regexp =~ s/\\/\\\\/isg;    
+  #} else {
+    $regexp =~ s/\//\\\//isg;         
+  #}
+  return $regexp;
+}
+
+sub read_content_from_about_dm
+{
+    my $self = shift(@_);
+
+  my $about_macro_file = &util::filename_cat($ENV{'GSDLHOME'}, "macros", "about.dm");
+  my $about_page_content = "";
+  if (open(INPUT, "<$about_macro_file")){
+    while (my $line=<INPUT>){
+      $about_page_content .= $line;
+    }
+  } else {
+      my $outhandle = $self->{'outhandle'};
+    print $outhandle "can't open file $about_macro_file\n";
+  }    		
+  close(INPUT);
+            
+  # extract the _content_ macro
+  $about_page_content =~ m/_content_ {(.|\n)*<\/div>\n\n<\/div>\n}/i;
+  $about_page_content = $&;
+  
+  return $about_page_content;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/MetadataCSVPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/MetadataCSVPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/MetadataCSVPlugin.pm	(revision 20131)
@@ -0,0 +1,181 @@
+###########################################################################
+#
+# MetadataCSVPlugin.pm -- A plugin for metadata in comma-separated value format
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package MetadataCSVPlugin;
+
+
+use BasePlugin;
+use strict;
+
+use multiread;
+
+
+sub BEGIN {
+    @MetadataCSVPlugin::ISA = ('BasePlugin');
+}
+
+
+my $arguments = [
+      { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() }
+
+];
+
+
+my $options = { 'name'     => "MetadataCSVPlugin",
+		'desc'     => "{MetadataCSVPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new
+{
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+
+sub get_default_process_exp
+{
+    return q^(?i)\.csv$^;
+}
+
+sub metadata_read
+{
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, 
+	$extrametakeys, $extrametadata, $extrametafile,
+	$processor, $maxdocs, $gli) = @_;
+
+    # Read metadata from CSV files
+    my $filename = &util::filename_cat($base_dir, $file);
+    if ($filename !~ /\.csv$/ || !-f $filename) {
+	return undef;
+    }
+    print STDERR "\n<Processing n='$file' p='MetadataCSVPlugin'>\n" if ($gli);
+    print STDERR "MetadataCSVPlugin: processing $file\n" if ($self->{'verbosity'}) > 1;
+
+    # add the file to the block list so that it won't be processed in read, as we will do all we can with it here
+    $block_hash->{'file_blocks'}->{$filename} = 1;
+
+    # Read the CSV file to get the metadata
+    my $csv_file_content;
+    open(CSV_FILE, "$filename");
+    my $csv_file_reader = new multiread();
+    $csv_file_reader->set_handle('MetadataCSVPlugin::CSV_FILE');
+    $csv_file_reader->read_file(\$csv_file_content);
+    close(CSV_FILE);
+
+    # Split the file into lines and read the first line (contains the metadata names)
+    $csv_file_content =~ s/\r/\n/g;  # Handle non-Unix line endings
+    $csv_file_content =~ s/\n+/\n/g;
+    my @csv_file_lines = split(/\n/, $csv_file_content);
+    my $csv_file_field_line = shift(@csv_file_lines);
+    my @csv_file_fields = split(/\,/, $csv_file_field_line);
+    my $found_filename_field = 0;
+    for (my $i = 0; $i < scalar(@csv_file_fields); $i++) {
+	# Remove any spaces from the field names
+	$csv_file_fields[$i] =~ s/ //g;
+	if ($csv_file_fields[$i] eq "Filename") {
+	    $found_filename_field = 1;
+	}
+    }
+
+    if (!$found_filename_field) {
+	print STDERR "MetadataCSVPlugin Error: No Filename field in CSV file: $filename\n";
+	return -1; # error
+    }
+    # Read each line of the file and assign the metadata appropriately
+    foreach my $csv_line (@csv_file_lines) {
+	# Ignore lines containing only whitespace
+	next if ($csv_line =~ /^\s*$/);
+	my $orig_csv_line = $csv_line;
+	# Build a hash of metadata name to metadata value for this line
+	my %csv_line_metadata;
+	my $i = 0;
+	$csv_line .= ",";  # To make the regular expressions simpler
+	while ($csv_line ne "") {
+	    # Metadata values containing commas are quoted
+	    if ($csv_line =~ s/^\"(.*?)\"\,//) {
+		# Only bother with non-empty values
+		if ($1 ne "" && defined($csv_file_fields[$i])) {
+		    if (!defined $csv_line_metadata{$csv_file_fields[$i]}) {
+			$csv_line_metadata{$csv_file_fields[$i]} = [];
+		    }
+		    push (@{$csv_line_metadata{$csv_file_fields[$i]}}, $1);
+		}
+	    }
+	    # Normal comma-separated case
+	    elsif ($csv_line =~ s/^(.*?)\,//) {
+		# Only bother with non-empty values
+		if ($1 ne "" && defined($csv_file_fields[$i])) {
+		    if (!defined $csv_line_metadata{$csv_file_fields[$i]}) {
+			$csv_line_metadata{$csv_file_fields[$i]} = [];
+		    }
+		    push (@{$csv_line_metadata{$csv_file_fields[$i]}}, $1);
+		}
+	    }
+	    # The line must be formatted incorrectly
+	    else {
+		print STDERR "MetadataCSVPlugin Error: Badly formatted CSV line: $csv_line.\n";
+		last;
+	    }
+
+	    $i++;
+	}
+
+	# We can't associate any metadata without knowing the file to associate it with
+	my $csv_line_filename_array = $csv_line_metadata{"Filename"};
+	if (!defined $csv_line_filename_array) {
+	    print STDERR "MetadataCSVPlugin Error: No Filename metadata in CSV line: $orig_csv_line\n";
+	    next;
+	}
+	my $csv_line_filename = shift(@$csv_line_filename_array);
+	delete $csv_line_metadata{"Filename"};
+
+
+ 	# Associate the metadata now
+	$csv_line_filename = &util::filename_to_regex($csv_line_filename);
+
+ 	$extrametadata->{$csv_line_filename} = \%csv_line_metadata;
+ 	push(@$extrametakeys, $csv_line_filename);
+    }
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/MetadataEXIFPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/MetadataEXIFPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/MetadataEXIFPlugin.pm	(revision 20131)
@@ -0,0 +1,220 @@
+###########################################################################
+#
+# MetadataEXIFPlugin.pm -- A plugin for EXIF
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright 2007 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+package MetadataEXIFPlugin;
+
+use BasePlugin;
+
+use Image::ExifTool qw(:Public);
+use strict;
+
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+
+sub BEGIN
+{
+  @MetadataEXIFPlugin::ISA = ('BasePlugin');
+}
+
+
+
+my $arguments =
+    [ ];
+
+
+my $options = { 'name'     => "MetadataEXIFPlugin",
+		'desc'     => "{MetadataEXIFPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new()
+{
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    if(defined $arguments){ push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});}
+    if(defined $options) { push(@{$hashArgOptLists->{"OptList"}},$options)};
+
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+
+    # Create a new Image::ExifTool object
+    my $exifTool = new Image::ExifTool;
+    $exifTool->Options(Duplicates => 0);
+    $exifTool->Options(PrintConv => 0);
+    $exifTool->Options(Unknown => 1);
+    $exifTool->Options('Verbose');
+    $self->{'exiftool'} = $exifTool;
+
+
+    return bless $self, $class;
+}
+
+
+# Need to think some more about this
+sub get_default_process_exp()
+{
+    return q^(?i)\.(wma|wmv|jpe?g|gif)$^;
+}
+
+
+# This plugin doesn't block any files 
+sub get_default_block_exp()
+{
+    return '';
+}
+
+
+sub extractEmbeddedMetadata()
+{
+    my $self = shift(@_);
+    my ($file, $filename, $extrametadata, $extrametakeys) = @_;
+
+    my %exif_metadata = ();
+
+    my $verbosity = $self->{'verbosity'};
+    my $outhandle = $self->{'outhandle'};
+
+    my $metadata_count = 0;
+    
+    my @group_list = Image::ExifTool::GetAllGroups(0);
+    foreach my $group (@group_list)
+      {
+##	  print STDERR "**** group = $group\n";
+
+        # Extract meta information from an image
+        $self->{'exiftool'}->Options(Group0 => [$group]);
+        $self->{'exiftool'}->ExtractInfo($filename);
+
+        # Get list of tags in the order they were found in the file
+        my @tag_list = $self->{'exiftool'}->GetFoundTags('File');
+        foreach my $tag (@tag_list)
+          {
+###	      print STDERR "**** tag = $tag\n";
+
+            # Strip any numbering suffix
+            $tag =~ s/^([^\s]+)\s.*$/$1/i;
+            my $value = $self->{'exiftool'}->GetValue($tag);
+            if (defined $value && $value =~ /[a-z0-9]+/i)
+              {
+                if (ref $value eq 'SCALAR')
+                  {
+                    if ($$value =~ /^Binary data/)
+                      {
+                        $value = "($$value)";
+                      }
+                    else
+                      {
+                        my $len = length($$value);
+                        $value = "(Binary data $len bytes)";
+                      }
+                  }
+
+		my $field = "$group.$tag";
+
+		if (!defined $exif_metadata{$field})
+		{
+		    $exif_metadata{$field} = [];
+		}
+		push (@{$exif_metadata{$field}}, $self->gsSafe($value));
+##		print STDERR "**** adding $field: $value\n";
+
+		++$metadata_count;
+              }
+          }
+      }
+
+
+    if ($metadata_count > 0) {
+	print $outhandle " Extracted $metadata_count pieces of metadata from $filename EXIF block\n";
+    }
+
+    # Protect windows directory chars \
+    $file = &util::filename_to_regex($file);
+    # print STDERR "**** file = $file\n";
+
+    # Associate the metadata now
+
+    $extrametadata->{$file} = \%exif_metadata;
+    push(@$extrametakeys, $file);
+
+}
+
+
+sub metadata_read()
+{
+  my $self = shift (@_);
+  my ($pluginfo, $base_dir, $file, $block_hash, 
+      $extrametakeys, $extrametadata, $extrametafile,
+      $processor, $maxdocs, $gli) = @_;
+  
+
+
+  # See if we are looking at a PDF file... which may contain EXIF
+  my $filename = &util::filename_cat($base_dir, $file);
+#  if ($filename !~ /\.pdf$/i || !-f $filename)
+#    {
+#      return undef;
+#    }
+
+  print STDERR "\n<Processing n='$file' p='MetadataEXIFPlugin'>\n" if ($gli);
+  print STDERR "MetadataEXIFPlugin: processing $file\n" if ($self->{'verbosity'}) > 1;
+
+
+  $self->extractEmbeddedMetadata($file,$filename,
+				 $extrametadata,$extrametakeys);
+
+    
+  return undef;
+}
+
+
+sub process()
+{
+    # not used
+    return undef;
+}
+
+sub gsSafe()
+  {
+    my $self = shift(@_);
+    my ($text) = @_;
+    # Replace dangerous characters
+    $text =~ s/\(/&#40;/g;
+    $text =~ s/\)/&#41;/g;
+    $text =~ s/,/&#44;/g;
+    $text =~ s/\</&#60;/g;
+    $text =~ s/\</&#62;/g;
+    $text =~ s/\[/&#91;/g;
+    $text =~ s/\]/&#93;/g;
+    # Done
+    return $text;
+  }
+
+1;
Index: /gsdl/stable/perllib/plugins/MetadataPass.pm
===================================================================
--- /gsdl/stable/perllib/plugins/MetadataPass.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/MetadataPass.pm	(revision 20131)
@@ -0,0 +1,158 @@
+###########################################################################
+#
+# MetadataPass.pm -- class to enhance plugins with generic metadata capabilities
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package MetadataPass;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+use PrintInfo; # uses PrintInfo, but is not inherited
+
+
+my $options = { 'name'     => "MetadataPass",
+		'desc'     => "{MetadataPass.desc}",
+		'abstract' => "yes",
+		'inherits' => "no" };
+
+
+sub new {
+    my $class = shift (@_);
+    my $plugin_name = shift (@_);
+
+    my $self = {};
+    $self->{'plugin_type'} = "MetadataPass";
+
+    $self->{'option_list'} = [ $options ];
+
+    return bless $self, $class;
+}
+
+sub init {
+}
+
+sub print_xml_usage
+{
+    PrintInfo::print_xml_usage(@_);
+}
+
+sub print_xml
+{
+    PrintInfo::print_xml(@_);
+}
+
+sub set_incremental
+{
+    PrintInfo::set_incremental(@_);
+}
+
+sub reset_saved_metadata {
+    my $self = shift(@_);
+
+    $self->{'saved_metadata'} = {};
+}
+
+
+sub get_saved_metadata {
+    my $self = shift(@_);
+    
+    return $self->{'saved_metadata'};
+}
+
+sub open_prettyprint_metadata_table
+{
+    my $self = shift(@_);
+
+    my $att   = "width=100% cellspacing=2";
+    my $style = "style=\'border-bottom: 4px solid #000080\'";
+
+    $self->{'ppmd_table'} = "\n<table $att $style>";
+}
+
+sub add_prettyprint_metadata_line 
+{
+    my $self = shift(@_);
+    my ($metaname, $metavalue_utf8) = @_;
+
+    $metavalue_utf8 = &util::hyperlink_text($metavalue_utf8);
+
+    $self->{'ppmd_table'} .= "  <tr bgcolor=#b5d3cd>\n";
+    $self->{'ppmd_table'} .= "    <td width=30%>\n";
+    $self->{'ppmd_table'} .= "      $metaname\n";
+    $self->{'ppmd_table'} .= "    </td>\n";
+    $self->{'ppmd_table'} .= "    <td>\n";
+    $self->{'ppmd_table'} .= "      $metavalue_utf8\n";
+    $self->{'ppmd_table'} .= "    </td>\n";
+    $self->{'ppmd_table'} .= "  </tr>\n";
+
+}
+
+sub close_prettyprint_metadata_table
+{
+    my $self = shift(@_);
+    $self->{'ppmd_table'} .= "</table>\n";
+
+    $self->set_filere_metadata("prettymd",$self->{'ppmd_table'});
+    $self->{'ppmd_table'} = undef;
+}
+
+sub set_filere_metadata
+{
+    my $self = shift(@_);
+    my ($full_mname,$md_content) = @_;
+
+    if (defined $self->{'saved_metadata'}->{$full_mname}) {
+	# accumulate - add value to existing value(s)
+	if (ref ($self->{'saved_metadata'}->{$full_mname}) eq "ARRAY") {
+	    push (@{$self->{'saved_metadata'}->{$full_mname}}, $md_content);
+	} else {
+	    $self->{'saved_metadata'}->{$full_mname} = 
+		[$self->{'saved_metadata'}->{$full_mname}, $md_content];
+	}
+    } else {
+	# accumulate - add value into (currently empty) array
+	$self->{'saved_metadata'}->{$full_mname} = [$md_content];
+    }
+}
+
+
+sub get_filere_metadata
+{
+    my $self = shift(@_);
+    my ($full_mname) = @_;
+
+    return $self->{'saved_metadata'}->{$full_mname};
+}
+
+sub get_filere_metadata_head
+{
+    my $self = shift(@_);
+    my ($full_mname) = @_;
+    
+    return $self->{'saved_metadata'}->{$full_mname}->[0];
+}
+
+
+
+1;
Index: /gsdl/stable/perllib/plugins/MetadataXMLPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/MetadataXMLPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/MetadataXMLPlugin.pm	(revision 20131)
@@ -0,0 +1,309 @@
+###########################################################################
+#
+# MetadataXMLPlugin.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# MetadataXMLPlugin process metadata.xml files in a collection
+
+# Here's an example of a metadata file that uses three FileSet structures
+# (ignore the # characters):
+
+#<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+#<!DOCTYPE DirectoryMetadata SYSTEM "http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd">
+#<DirectoryMetadata>
+#  <FileSet>
+#    <FileName>nugget.*</FileName>
+#    <Description>
+#      <Metadata name="Title">Nugget Point, The Catlins</Metadata>
+#      <Metadata name="Place" mode="accumulate">Nugget Point</Metadata>
+#    </Description>
+#  </FileSet>
+#  <FileSet>
+#    <FileName>nugget-point-1.jpg</FileName>
+#    <Description>
+#      <Metadata name="Title">Nugget Point Lighthouse, The Catlins</Metadata>
+#      <Metadata name="Subject">Lighthouse</Metadata>
+#    </Description>
+#  </FileSet>
+#  <FileSet>
+#    <FileName>kaka-point-dir</FileName>
+#    <Description>
+#      <Metadata name="Title">Kaka Point, The Catlins</Metadata>
+#    </Description>
+#  </FileSet>
+#</DirectoryMetadata>
+
+# Metadata elements are read and applied to files in the order they appear
+# in the file.
+#
+# The FileName element describes the subfiles in the directory that the
+# metadata applies to as a perl regular expression (a FileSet group may
+# contain multiple FileName elements). So, <FileName>nugget.*</FileName>
+# indicates that the metadata records in the following Description block
+# apply to every subfile that starts with "nugget".  For these files, a
+# Title metadata element is set, overriding any old value that the Title
+# might have had.
+#
+# Occasionally, we want to have multiple metadata values applied to a
+# document; in this case we use the "mode=accumulate" attribute of the
+# particular Metadata element.  In the second metadata element of the first
+# FileSet above, the "Place" metadata is accumulating, and may therefore be
+# given several values.  If we wanted to override these values and use a
+# single metadata element again, we could set the mode attribute to
+# "override" instead.  Remember: every element is assumed to be in override
+# mode unless you specify otherwise, so if you want to accumulate metadata
+# for some field, every occurance must have "mode=accumulate" specified.
+#
+# The second FileSet element above applies to a specific file, called
+# nugget-point-1.jpg.  This element overrides the Title metadata set in the
+# first FileSet, and adds a "Subject" metadata field.
+#
+# The third and final FileSet sets metadata for a subdirectory rather than
+# a file.  The metadata specified (a Title) will be passed into the
+# subdirectory and applied to every file that occurs in the subdirectory
+# (and to every subsubdirectory and its contents, and so on) unless the
+# metadata is explictly overridden later in the import.
+
+package MetadataXMLPlugin;
+
+use strict;
+no strict 'refs';
+use BasePlugin;
+use util;
+use metadatautil;
+
+sub BEGIN {
+    @MetadataXMLPlugin::ISA = ('BasePlugin');
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+}
+
+use XMLParser;
+
+my $arguments = [
+      { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() }
+
+];
+
+my $options = { 'name'     => "MetadataXMLPlugin",
+		'desc'     => "{MetadataXMLPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+my ($self);
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options or initialisations etc
+	return bless $self, $class;
+    }
+	
+    # create XML::Parser object for parsing metadata.xml files
+    my $parser;
+    if ($]<5.008) {
+	# Perl 5.6
+	$parser = new XML::Parser('Style' => 'Stream',
+				  'Handlers' => {'Char' => \&Char,
+						 'Doctype' => \&Doctype
+						 });
+    }
+    else {
+	# Perl 5.8
+	$parser = new XML::Parser('Style' => 'Stream',
+				  'ProtocolEncoding' => 'ISO-8859-1',
+				  'Handlers' => {'Char' => \&Char,
+						 'Doctype' => \&Doctype
+						 });
+    }
+
+    $self->{'parser'} = $parser;
+    $self->{'in_filename'} = 0;
+    
+    
+    return bless $self, $class;
+}
+
+
+sub get_default_process_exp
+{
+    return q^metadata\.xml$^;
+}
+
+
+sub metadata_read
+{
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, 
+	$extrametakeys, $extrametadata,$extrametafile,
+	$processor, $maxdocs, $gli) = @_;
+
+    my $filename = &util::filename_cat($base_dir, $file);
+    if ($filename !~ /metadata\.xml$/ || !-f $filename) {
+        return undef;
+    }
+
+    $self->{'metadata-file'} = $file;
+    $self->{'metadata-filename'} = $filename;
+
+    my $outhandle = $self->{'outhandle'};
+    
+    print STDERR "\n<Processing n='$file' p='MetadataXMLPlugin'>\n" if ($gli);
+    print $outhandle "MetadataXMLPlugin: processing $file\n" if ($self->{'verbosity'})> 1;
+    # add the file to the block list so that it won't be processed in read, as we will do all we can with it here
+    $block_hash->{'file_blocks'}->{$filename} = 1;
+    $self->{'metadataref'} = $extrametadata;
+    $self->{'metafileref'} = $extrametafile;
+    $self->{'metakeysref'} = $extrametakeys;
+    
+    eval {
+	$self->{'parser'}->parsefile($filename);
+    };
+
+    if ($@) {
+	my $plugin_name = ref ($self);
+	print $outhandle "$plugin_name failed to process $file ($@)\n";
+	
+	return -1; #error
+    }
+
+    return 1;
+
+}
+
+sub Doctype {
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+
+    # allow the short-lived and badly named "GreenstoneDirectoryMetadata" files 
+    # to be processed as well as the "DirectoryMetadata" files which should now
+    # be created by import.pl
+    die if ($name !~ /^(Greenstone)?DirectoryMetadata$/);
+}
+
+sub StartTag {
+    my ($expat, $element) = @_;
+
+    if ($element eq "FileSet") {
+	$self->{'saved_targets'} = [];
+	$self->{'saved_metadata'} = {};
+    }
+    elsif ($element eq "FileName") {
+	$self->{'in_filename'} = 1;
+    }
+    elsif ($element eq "Metadata") {
+	$self->{'metadata_name'} = $_{'name'};
+	$self->{'metadata_value'} = "";
+	if ((defined $_{'mode'}) && ($_{'mode'} eq "accumulate")) {
+	    $self->{'metadata_accumulate'} = 1;
+	} else {
+	    $self->{'metadata_accumulate'} = 0;
+	}
+    }
+}
+
+sub EndTag {
+    my ($expat, $element) = @_;
+
+    if ($element eq "FileSet") {
+	foreach my $target (@{$self->{'saved_targets'}}) {
+	    my $file_metadata = $self->{'metadataref'}->{$target};
+	    my $saved_metadata = $self->{'saved_metadata'};
+
+	    if (!defined $file_metadata) {
+		$self->{'metadataref'}->{$target} = $saved_metadata;
+
+		# not had target before
+		push (@{$self->{'metakeysref'}}, $target);
+	    }
+	    else {
+		&metadatautil::combine_metadata_structures($file_metadata,$saved_metadata);
+	    }
+
+	    
+	    # now record which metadata.xml file it came from
+
+	    my $file = $self->{'metadata-file'};
+	    my $filename = $self->{'metadata-filename'};
+
+	    if (!defined $self->{'metafileref'}->{$target}) {
+		$self->{'metafileref'}->{$target} = {};
+	    }
+
+	    $self->{'metafileref'}->{$target}->{$file} = $filename
+	}
+    }
+    elsif ($element eq "FileName") {
+	$self->{'in_filename'} = 0;
+    }
+    elsif ($element eq "Metadata") {
+	&metadatautil::store_saved_metadata($self,$self->{'metadata_name'}, $self->{'metadata_value'}, $self->{'metadata_accumulate'});
+	$self->{'metadata_name'} = "";
+    }
+
+}
+
+sub Text {
+
+    if ($self->{'in_filename'}) {
+	# $_ == FileName content
+	push (@{$self->{'saved_targets'}}, $_);
+    }
+    elsif (defined ($self->{'metadata_name'}) && $self->{'metadata_name'} ne "") {
+	# $_ == Metadata content
+	$self->{'metadata_value'} = $_;
+    }
+}
+
+# This Char function overrides the one in XML::Parser::Stream to overcome a
+# problem where $expat->{Text} is treated as the return value, slowing
+# things down significantly in some cases.
+sub Char {
+    if ($]<5.008) {
+	use bytes;  # Necessary to prevent encoding issues with XML::Parser 2.31+ and Perl 5.6
+    }
+    $_[0]->{'Text'} .= $_[1];
+    return undef;
+}
+
+#sub combine_metadata_structures
+#{
+#    my $self = shift(@_);
+#
+#    my ($mdref1, $mdref2) = @_;
+#    &metadatautil::combine_metadata_structures($mdref1, $mdref2);
+#}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/NulPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/NulPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/NulPlugin.pm	(revision 20131)
@@ -0,0 +1,125 @@
+###########################################################################
+#
+# NulPlugin.pm -- Plugin for dummy (.nul) files
+#
+# A component of the Greenstone digital library software from the New
+# Zealand Digital Library Project at the University of Waikato, New
+# Zealand.
+#
+# Copyright (C) 2005 Katherine Don
+# Copyright (C) 2005 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# NulPlugin - a plugin for dummy files
+
+# This is a simple Plugin for importing dummy files, along with
+# their metadata.  A fictional document will
+# be created for every such file, and the metadata added to it.
+
+# This is used mainly for the null files resulting from exploding metadata
+# databases
+
+package NulPlugin;
+
+use BasePlugin;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @NulPlugin::ISA = ('BasePlugin');
+}
+
+my $arguments = 
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() },
+      { 'name' => "assoc_field",
+	'desc' => "{NulPlugin.assoc_field}",
+	'type' => "string",
+	'deft' => "null_file",
+	'reqd' => "no" },
+      { 'name' => "add_metadata_as_text",
+	'desc' => "{NulPlugin.add_metadata_as_text}",
+	'type' => "flag" },
+      { 'name' => "remove_namespace_for_text",
+	'desc' => "{NulPlugin.remove_namespace_for_text}",
+	'type' => "flag" }
+      ];
+
+my $options = { 'name'     => "NulPlugin",
+		'desc'     => "{NulPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+                 'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+    
+    return bless $self, $class;
+}
+
+sub get_default_process_exp {
+    return '(?i)\.nul$';
+}
+
+# NulPlugin specific processing of doc_obj. 
+sub process {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    
+    my $topsection = $doc_obj->get_top_section();
+       
+    my $assoc_field = $self->{'assoc_field'}; # || "null_file"; TODO, check this
+    $doc_obj->add_metadata ($topsection, $assoc_field, $file);
+
+    # format the metadata passed in (presumably from metadata.xml)
+    my $text = "";
+    if ($self->{'add_metadata_as_text'}) {
+	$text = &metadatautil::format_metadata_as_table($metadata, $self->{'remove_namespace_for_text'});
+	$doc_obj->add_utf8_text($topsection, $text);
+    } else {
+	$self->add_dummy_text($doc_obj, $topsection);
+    }
+    
+    return 1;
+}
+
+
+1;
+
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/perllib/plugins/OAIPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/OAIPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/OAIPlugin.pm	(revision 20131)
@@ -0,0 +1,529 @@
+###########################################################################
+#
+# OAIPlug.pm -- basic Open Archives Initiative (OAI) plugin
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package OAIPlugin;
+
+use unicode;
+use util;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+use ReadXMLFile;
+use ReadTextFile; # needed for subroutine textcat_get_language_encoding
+use metadatautil;
+
+sub BEGIN {
+    @OAIPlugin::ISA = ('ReadXMLFile', 'ReadTextFile');
+}
+
+my $set_list =
+    [ { 'name' => "auto",
+	'desc' => "{OAIPlugin.metadata_set.auto}" },
+      { 'name' => "dc",
+	'desc' => "{OAIPlugin.metadata_set.dc}" } 
+      ];
+
+my $arguments = 
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() },
+      { 'name' => "metadata_set",
+	'desc' => "{OAIPlugin.metadata_set}",
+	'type' => "enumstring",
+	'reqd' => "no",
+	'list' => $set_list,
+	'deft' => "dc" },
+      { 'name' => "document_field",
+	'desc' => "{OAIPlugin.document_field}",
+	'type' => "metadata",
+	'reqd' => "no",
+	'deft' => "gi.Sourcedoc" }
+      ];
+
+my $options = { 'name'     => "OAIPlugin",
+		'desc'     => "{OAIPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'explodes' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    new ReadTextFile($pluginlist, $inputargs, $hashArgOptLists,1);
+    my $self = new ReadXMLFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)(\.oai)$^;
+}
+
+sub get_doctype {
+    my $self = shift(@_);
+    
+    return "OAI-PMH";
+}
+
+sub xml_start_document {
+    my $self = shift (@_);
+    $self->{'in_metadata_node'} = 0;
+    $self->{'rawxml'} = "";
+    $self->{'saved_metadata'} = {};
+}
+
+sub xml_end_document {
+}
+
+sub xml_doctype {
+    my $self = shift(@_);
+
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+
+    ##die "" if ($name !~ /^OAI-PMH$/);
+
+    my $outhandle = $self->{'outhandle'};
+    print $outhandle "OAIPlugin: processing $self->{'file'}\n" if $self->{'verbosity'} > 1;
+    print STDERR "<Processing n='$self->{'file'}' p='OAIPlugin'>\n" if $self->{'gli'};
+
+}
+
+
+sub xml_start_tag {
+    my $self = shift(@_);
+    my ($expat,$element) = @_;
+
+    my %attr_hash = %_;
+
+    my $attr = "";
+    map { $attr .= " $_=$attr_hash{$_}"; } keys %attr_hash;
+
+    $self->{'rawxml'} .= "<$element$attr>";
+
+    if ($element eq "metadata") {
+	$self->{'in_metadata_node'} = 1;
+	$self->{'metadata_xml'} = "";
+    }
+
+    if ($self->{'in_metadata_node'}) {
+	$self->{'metadata_xml'} .= "<$element$attr>";
+    }
+}
+
+sub xml_end_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+
+    $self->{'rawxml'} .= "</$element>";
+
+    if ($self->{'in_metadata_node'}) {
+	$self->{'metadata_xml'} .= "</$element>";
+    }
+
+    if ($element eq "metadata") {
+	my $textref = \$self->{'metadata_xml'};
+	#my $metadata = $self->{'metadata'};
+	my $metadata = $self->{'saved_metadata'};
+	$self->extract_oai_metadata($textref,$metadata);
+
+	$self->{'in_metadata_node'} = 0;	
+    }
+
+
+}
+
+sub xml_text {
+    my $self = shift(@_);
+    my ($expat) = @_;
+
+    $self->{'rawxml'} .= $_;
+
+    if ($self->{'in_metadata_node'}) {
+	$self->{'metadata_xml'} .= $_;
+    }
+}
+
+
+sub metadata_read {
+    my $self = shift (@_);  
+
+    my ($pluginfo, $base_dir, $file, $block_hash, 
+	$extrametakeys, $extrametadata, $extrametafile,
+	$processor, $maxdocs, $gli) = @_;
+
+    # can we process this file??
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+    
+    if (!$self->parse_file($filename_full_path, $file, $gli)) {
+	$self->{'saved_metadata'} = undef;
+	return undef;
+    }
+
+    my $new_metadata = $self->{'saved_metadata'};
+    $self->{'saved_metadata'} = undef;
+
+    # add the pretty metadata table as metadata
+    my $ppmd_table = $self->{'ppmd_table'};
+    $new_metadata->{'prettymd'} = $ppmd_table;
+    $self->{'ppmd_table'} = undef;
+      
+    my $document_metadata_field = $self->{'document_field'};
+    my $url_array = $new_metadata->{$document_metadata_field};
+    my $num_urls = (defined $url_array) ? scalar(@$url_array) : 0;
+    ##print STDERR "$num_urls urls for $file\n";
+    my $srcdoc_exists = 0;
+    my $srcdoc_pos = 0;
+    my $filename_dir = &util::filename_head($filename_full_path);
+    
+    # filenames in extrametadata must be relative to current dir, as 
+    # DirectoryPlugin adds path info on itself
+    my ($filename_for_metadata) = $file =~ /([^\\\/]+)$/; # this assumes there will only be one record per oai file - is this always the case??
+    for (my $i=0; $i<$num_urls; $i++) {
+	
+	if ($url_array->[$i] !~ m/^(https?|ftp):/) {
+	    
+	    my $src_filename = &util::filename_cat($filename_dir, $url_array->[$i]);
+	    if (-e $src_filename) {
+		$srcdoc_pos = $i;
+		$srcdoc_exists = 1;
+		# get the slashes the right way, use filename_cat
+		$filename_for_metadata = &util::filename_cat($url_array->[$i]);
+		last;
+	    }
+	}
+    }
+    
+    if ($srcdoc_exists) {
+	$self->{'oai-files'}->{$file}->{'srcdoc_exists'} = 1;
+    }
+    else {
+	# save the rawxml for the source document
+	$self->{'oai-files'}->{$file}->{'srcdoc_exists'} = 0;
+	$self->{'oai-files'}->{$file}->{'rawxml'} = $self->{'rawxml'};
+	$self->{'rawxml'} = "";
+    }
+    
+    # return all the metadata we have extracted to the caller.
+    # Directory plug will pass it back in at read time, so we don't need to extract it again.
+    # extrametadata keys should be regular expressions
+    $filename_for_metadata = &util::filename_to_regex($filename_for_metadata);
+    $extrametadata->{$filename_for_metadata} = $new_metadata;
+    push(@$extrametakeys, $filename_for_metadata);
+
+    return 1;
+    
+}
+
+
+sub read {
+    my $self = shift (@_);  
+    
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+
+    if (!defined $self->{'oai-files'}->{$file}) {
+	return undef;
+    }
+        
+    my $srcdoc_exists = $self->{'oai-files'}->{$file}->{'srcdoc_exists'};
+    if ($srcdoc_exists) {
+	# do nothing more - all the metadata has been extracted and associated with the srcdoc
+	# no more need to access details of this $file => tidy up as you go
+	delete $self->{'oai-files'}->{$file};
+	return 0; # not processed here, but don't pass on to rest of plugins
+    }
+
+    my $filename = $file;
+    $filename = &util::filename_cat ($base_dir, $file) if $base_dir =~ /\w/;
+
+    # Do encoding stuff on metadata
+    my ($language, $encoding) = $self->textcat_get_language_encoding ($filename);
+
+    # create a new document
+    my $doc_obj = new doc ($filename, "indexed_doc", $self->{'file_rename_method'});
+    my $top_section = $doc_obj->get_top_section;
+    my $plugin_type = $self->{'plugin_type'};
+    
+    my ($filemeta) = $file =~ /([^\\\/]+)$/;
+    $self->set_Source_metadata($doc_obj, $filemeta, $encoding);
+    $doc_obj->add_utf8_metadata($top_section, "Language", $language);
+    $doc_obj->add_utf8_metadata($top_section, "Encoding", $encoding);
+    $doc_obj->add_utf8_metadata($top_section, "Plugin", $plugin_type);
+    $doc_obj->add_metadata($top_section, "FileFormat", "OAI");
+    $doc_obj->add_metadata($top_section, "FileSize", (-s $filename));
+    
+    # include any metadata passed in from previous plugins 
+    # note that this metadata is associated with the top level section
+    # this will include all the metadata from the oai file that we extracted
+    # during metadata_read
+    $self->extra_metadata ($doc_obj, $doc_obj->get_top_section(), $metadata);
+    
+    # do plugin specific processing of doc_obj
+    my $text = $self->{'oai-files'}->{$file}->{'rawxml'};
+    delete $self->{'oai-files'}->{$file};
+
+    unless (defined ($self->process(\$text, $pluginfo, $base_dir, $file, $metadata, $doc_obj))) {
+	print STDERR "<ProcessingError n='$file'>\n" if ($gli);
+	return -1;
+    }
+    
+    # do any automatic metadata extraction
+    $self->auto_extract_metadata ($doc_obj);
+    
+    # add an OID
+    $self->add_OID($doc_obj);
+        
+    # process the document
+    $processor->process($doc_obj);
+    
+    $self->{'num_processed'} ++;
+    
+    return 1; # processed the file
+}
+
+
+# do plugin specific processing of doc_obj
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    print STDERR "<Processing n='$file' p='OAIPlugin'>\n" if ($gli);
+    print $outhandle "OAIPlugin: processing $file\n"
+	if $self->{'verbosity'} > 1;
+
+    my $cursection = $doc_obj->get_top_section();
+
+##    $self->extract_metadata ($textref, $metadata, $doc_obj, $cursection);
+
+    # add text to document object
+
+#    $$textref =~ s/<(.*?)>/$1 /g;
+    $$textref =~ s/</&lt;/g;
+    $$textref =~ s/>/&gt;/g;
+    $$textref =~ s/\[/&#91;/g;
+    $$textref =~ s/\]/&#93;/g;
+
+    $doc_obj->add_utf8_text($cursection, $$textref);
+
+    return 1;
+}
+
+
+# Improvement is to merge this with newer version in MetadataPass
+
+sub open_prettyprint_metadata_table
+{
+    my $self = shift(@_);
+
+    my $att   = "width=100% cellspacing=2";
+    my $style = "style=\'border-bottom: 4px solid #000080\'";
+
+	$self->{'ppmd_table'} = "\n<table $att $style>";
+}
+
+sub add_prettyprint_metadata_line 
+{
+    my $self = shift(@_);
+    my ($metaname, $metavalue_utf8) = @_;
+
+    $metavalue_utf8 = &util::hyperlink_text($metavalue_utf8);
+
+    $self->{'ppmd_table'} .= "  <tr bgcolor=#b5d3cd>\n";
+    $self->{'ppmd_table'} .= "    <td width=30%>\n";
+    $self->{'ppmd_table'} .= "      $metaname\n";
+    $self->{'ppmd_table'} .= "    </td>\n";
+    $self->{'ppmd_table'} .= "    <td>\n";
+    $self->{'ppmd_table'} .= "      $metavalue_utf8\n";
+    $self->{'ppmd_table'} .= "    </td>\n";
+    $self->{'ppmd_table'} .= "  </tr>\n";
+
+}
+
+sub close_prettyprint_metadata_table
+{
+    my $self = shift(@_);
+
+    $self->{'ppmd_table'} .= "</table>\n";
+}
+
+my $qualified_dc_mapping = {
+    "alternative" => "dc.title",
+    "tableOfContents" => "dc.description",
+    "abstract" => "dc.description",
+    "created" => "dc.date",
+    "valid" => "dc.date",
+    "available" => "dc.date",
+    "issued" => "dc.date",
+    "modified" => "dc.date",
+    "dateAccepted" => "dc.date",
+    "dateCopyrighted" => "dc.date",
+    "dateSubmitted" => "dc.date",
+    "extent" => "dc.format",
+    "medium" => "dc.format",
+    "isVersionOf" => "dc.relation",
+    "hasVersion" => "dc.relation",
+    "isReplacedBy" => "dc.relation",
+    "replaces" => "dc.relation",
+    "isRequiredBy" => "dc.relation",
+    "requires" => "dc.relation",
+    "isPartOf" => "dc.relation",
+    "hasPart" => "dc.relation",
+    "isReferencedBy" => "dc.relation",
+    "references" => "dc.relation",
+    "isFormatOf" => "dc.relation",
+    "hasFormat" => "dc.relation",
+    "conformsTo" => "dc.relation",
+    "spatial" => "dc.coverage",
+    "temporal" => "dc.coverage",
+# these are now top level elements in our qualified dc metadata set
+#	"audience" => "dc.any",
+#	"accrualMethod" => "dc.any",
+#	"accrualPeriodicity" => "dc.any",
+#	"accrualPolicy" => "dc.any",
+#	"instructionalMethod" => "dc.any",
+#	"provenance" => "dc.any",
+#	"rightsHolder" => "dc.any",
+    "mediator" => "dc.audience",
+    "educationLevel" => "dc.audience",
+    "accessRights" => "dc.rights",
+    "license" => "dc.rights",
+    "bibliographicCitation" => "dc.identifier"
+    };
+
+sub remap_dc_metadata
+{
+    my $self = shift(@_);
+
+    my ($metaname) = @_;
+
+    my ($prefix,$name) = ($metaname =~ m/^(.*?)\.(.*?)$/);
+    
+    if (defined $qualified_dc_mapping->{$name}) {
+	
+	return $qualified_dc_mapping->{$name}."^".$name;
+    }
+    
+    
+    return $metaname; # didn't get a match, return param passed in unchanged
+}
+
+
+sub extract_oai_metadata {
+    my $self = shift (@_);
+    my ($textref, $metadata) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    $self->open_prettyprint_metadata_table();
+
+    if ($$textref =~ m/<metadata\s*>(.*?)<\/metadata\s*>/s)
+    {
+	my $metadata_text = $1;
+
+	# locate and remove outermost tag (ignoring any attribute information in top-level tag)
+	my ($outer_tagname,$inner_metadata_text) = ($metadata_text =~ m/<([^ >]+).*?>(.*?)<\/\1>/s);
+	# split tag into namespace and tag name
+	my($namespace,$top_level_prefix) = ($outer_tagname =~ m/^(.*?):(.*?)$/);
+	# sometimes, the dc namespace is not specified as the prefix in each element (like <dc:title>)
+	# but is rather defined in the wrapper element containing the various dc meta elements,
+	# like <dc><title></title><creator></creator></dc>.
+	# In such a case, we use this wrapper element as the top_level_prefix
+	
+	# if there was no prefix, then the tag itself becomes the top_level_prefix
+	if(!defined $top_level_prefix && defined $outer_tagname) {
+	    $top_level_prefix = $outer_tagname;
+	}
+
+	#process each element one by one
+	while ($inner_metadata_text =~ m/<([^ >]+).*?>(.*?)<\/\1>(.*)/s)
+	{
+
+	    my $metaname = $1;
+	    my $metavalue = $2;
+	    $inner_metadata_text = $3;
+
+	    # greenstone uses . for namespace, while oai uses :
+	    $metaname =~ s/:/\./;
+	    # if there is no namespace, then we use the outer tag name or 
+	    # namespace for this element
+	    if ($metaname !~ m/\./)
+	    {
+		$metaname = "$top_level_prefix.$metaname";
+	    }
+	    
+	    # if metadata set is auto, leave as is, otherwise convert to 
+	    # specified namespace
+	    if ($self->{'metadata_set'} ne "auto") {
+		$metaname =~ s/^([^\.]*)\./$self->{'metadata_set'}\./;
+		if ($self->{'metadata_set'} eq "dc") {
+		    # convert qualified dc terms to gs version, e.g.
+		    # spatial becomes coverage^spatial
+		    $metaname = $self->remap_dc_metadata($metaname);
+		}
+	    }
+
+	    # uppercase the first char of the name
+	    $metaname =~ s/\.(.)/\.\u$1/;
+	    $metavalue =~ s/\[/&#91;/g;
+	    $metavalue =~ s/\]/&#93;/g;
+
+	    if (defined $metadata->{$metaname})
+	    {
+		push(@{$metadata->{$metaname}},$metavalue);
+
+	    }
+	    else
+	    {
+		$metadata->{$metaname} = [ $metavalue ];
+	    }
+
+	    $self->add_prettyprint_metadata_line($metaname, $metavalue);
+	    
+	}
+    }
+
+    $self->close_prettyprint_metadata_table();
+}
+
+## we know from the file extension, so doesn't need to check the doctype
+sub check_doctype {
+
+    return 1;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/OggVorbisPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/OggVorbisPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/OggVorbisPlugin.pm	(revision 20131)
@@ -0,0 +1,154 @@
+###########################################################################
+#
+# OggVorbisPlug.pm -- A plugin for Ogg Vorbis audio files
+#
+# Original code by Christy Kuo
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright 1999-2004 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package OggVorbisPlugin;
+
+
+use BasePlugin;
+use Ogg::Vorbis::Header::PurePerl;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+no strict 'subs';
+
+sub BEGIN {
+    @OggVorbisPlugin::ISA = ('BasePlugin');
+}
+
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "string",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" },
+      { 'name' => "add_technical_metadata",
+	'desc' => "{OggVorbisPlugin.add_technical_metadata}",
+	'type' => "flag",
+	'deft' => "" }, 
+      { 'name' => "file_rename_method",
+	'desc' => "{BasePlugin.file_rename_method}",
+	'type' => "enum",
+	'deft' => &get_default_file_rename_method(), # by default rename imported files and assoc files using this encoding
+	'list' => $BasePlugin::file_rename_method_list,
+	'reqd' => "no"
+      } ];
+
+my $options = { 'name'     => "OggVorbisPlugin",
+		'desc'     => "{OggVorbisPlugin.desc}",
+		'inherits' => "yes",
+		'abstract' => "no",
+		'args'     => $arguments };
+
+
+# This plugin processes exported Ogg Vorbis files with the suffix ".ogg"
+sub get_default_process_exp
+{
+    return q^(?i)(\.ogg)$^;
+}
+
+# rename imported media files using base64 encoding by default
+# so that the urls generated will always work with external apps
+sub get_default_file_rename_method() {
+    return "base64";
+}
+
+sub new
+{
+    my ($class) = shift(@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+    
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+    
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+    
+    return bless $self, $class;
+}
+
+# we don't want to hash on the file
+sub get_oid_hash_type {
+    my $self = shift (@_);
+    return "hash_on_ga_xml";
+}
+
+sub process
+{
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+
+    my $top_section = $doc_obj->get_top_section();
+    # Extract metadata
+    my $ogg = Ogg::Vorbis::Header::PurePerl->new($filename_full_path);
+
+    # Comments added to the file
+    foreach my $key ($ogg->comment_tags())
+    {
+	# Convert key to title case
+	my $keytc = uc(substr($key, 0, 1)) . substr($key, 1, length($key));
+	foreach my $value ($ogg->comment($key))
+	{
+	    if (defined $value && $value ne "") {
+		$doc_obj->add_metadata($top_section, $keytc, $value);
+	    }
+	}
+    }
+
+    # Technical data (optional)
+    if ($self->{'add_technical_metadata'}) {
+	foreach my $key (keys %{$ogg->info})
+	{
+	    # Convert key to title case
+	    my $keytc = uc(substr($key, 0, 1)) . substr($key, 1, length($key));
+	    my $value = $ogg->info->{$key};
+	    if (defined $value && $value ne "") {
+		$doc_obj->add_metadata($top_section, $keytc, $value);
+	    }
+	}
+    }
+
+    $doc_obj->add_metadata ($top_section, "FileFormat", "OggVorbis");
+    $doc_obj->add_metadata ($top_section, "srclink", "<a href=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[SourceFile]\">");
+    $doc_obj->add_metadata ($top_section, "/srclink", "</a>");
+    # srcicon (need to include "iogg.gif" in the greenstone images directory
+    $doc_obj->add_metadata ($top_section, "srcicon", "<img src=\"_httpprefix_/images/iogg.gif\" title=\"Download\" border=0>");
+
+    # add dummy text and NoText metadata which can be used to suppress the dummy text
+    $self->add_dummy_text($doc_obj, $top_section);
+
+    # Add the actual file as an associated file
+    my $assoc_file = $doc_obj->add_assocfile_from_sourcefile();
+    $doc_obj->associate_file($filename_full_path, $assoc_file, "VORBIS", $top_section);
+
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/OpenDocumentPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/OpenDocumentPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/OpenDocumentPlugin.pm	(revision 20131)
@@ -0,0 +1,304 @@
+###########################################################################
+#
+# OpenDocumentPlugin.pm -- The Open Document plugin
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# Processes OASIS Open Document format.
+# Word processing document: .odt, template: .ott 
+# Spreadsheet document: .ods, template: .ots
+# Presentation document: .odp, template: .otp
+# Graphics document: .odg, template: .otg
+# Formulas document: .odf, template: .otf (not supported)
+
+#This basically extracts any text out of the document, but not much else. 
+
+# this inherits ReadXMLFile, and therefore offers -xslt option, but does
+# nothing with it.
+
+package OpenDocumentPlugin;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+use ReadXMLFile;
+use XML::XPath;
+use XML::XPath::XMLParser;
+use Cwd;
+use util;
+use ghtml;
+
+sub BEGIN {
+    @OpenDocumentPlugin::ISA = ('ReadXMLFile');
+}
+
+our @filesProcess = ( "content.xml" , "meta.xml" );
+
+my $arguments = [
+		 { 'name' => "process_exp",
+		   'desc' => "{BasePlugin.process_exp}",
+		   'type' => "regexp",
+		   'deft' =>  &get_default_process_exp() }
+		 ];
+
+my $options = { 'name'     => "OpenDocumentPlugin",
+		'desc'     => "{OpenDocumentPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments};
+
+sub get_default_process_exp { return q^(?i)\.o(?:d|t)(?:t|s|p|g)$^; }
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new ReadXMLFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    $self->{'section'} = "";
+    $self->{'office:meta'} = "";
+    
+    return bless $self, $class;
+}
+
+sub get_doctype {
+    my $self = shift(@_);
+    
+    return "manifest:manifest";
+}
+
+sub xml_doctype {
+    my $self = shift(@_);
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+    die "The only valid doctype is manifest, $name is not valid" if ($name ne "manifest:manifest");
+}
+
+# Called for every start tag. The $_ variable will contain a copy of the
+# tag and the %_ variable will contain the element's attributes.
+sub xml_start_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+    my %atts  = %_;
+    $self->{'office:meta'} = $element if $self->{'office:meta'} eq "Start";
+    if($element eq 'office:text') {
+	$self->{'collectedText'} = "";
+    }elsif($element eq 'office:meta') {
+	$self->{'collectedText'} = "";
+	$self->{'office:meta'} = "Start";
+    }elsif($element eq 'meta:document-statistic'){
+	foreach my $att (keys %atts) {
+	    $self->{'doc_obj'}->add_utf8_metadata("",$att,$atts{$att});
+	}
+	
+    }
+}
+
+sub xml_end_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+    
+    if($element eq 'office:text') {
+	$self->{'doc_obj'}->add_utf8_text("",$self->{'collectedText'});
+	$self->{'collectedText'} = "";
+    }elsif($element eq $self->{'office:meta'}) {
+	if( $self->{'collectedText'} ne "") {
+	    $self->{'doc_obj'}->add_utf8_metadata("",$self->{'office:meta'},$self->{'collectedText'});
+	    $self->{'doc_obj'}->add_utf8_metadata("","Title",$self->{'collectedText'}) if $self->{'office:meta'} =~ m/:title$/;
+	    $self->{'doc_obj'}->add_utf8_metadata("","Language",$self->{'collectedText'}) if $self->{'office:meta'} =~ m/:language$/;
+	    $self->{'doc_obj'}->add_utf8_metadata("","GENERATOR",$self->{'collectedText'}) if $self->{'office:meta'} =~ m/:generator$/;
+	    
+    	}
+	$self->{'collectedText'} = "";
+        $self->{'office:meta'} = "Start";
+    }elsif($element eq 'office:meta'){
+	$self->{'office:meta'} = "";
+    }elsif($element eq 'office:body'){
+	#some documents have text in other places that should probably be indexed if we can't find any doc text
+	
+	if( defined $self->{'collectedText'} && $self->{'collectedText'} ne "" && $self->{'doc_obj'}->get_text("") eq "") {
+	    $self->{'doc_obj'}->add_utf8_text("",$self->{'collectedText'});
+	}
+    }
+}
+
+sub xml_text {
+    my $self = shift(@_);
+    my ($expat) = @_;
+    if($_ =~ m/\w/i) {
+	$self->{'collectedText'} .= "<br/>" if $self->{'collectedText'} ne "";
+	$self->{'collectedText'} .= "$_";
+    }
+}
+
+#trap start and end document so we do not get our doc_obj closed too soon
+sub xml_start_document {}
+sub xml_end_document {}
+
+sub read {
+    my $self = shift (@_);  
+   
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+
+    # can we process this file??
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+
+    my $outhandle = $self->{'outhandle'};
+    # Report that we're processing the file
+    print STDERR "<Processing n='$file' p='OpenDocumentPlugin'>\n" if ($gli);
+    print $outhandle "OpenDocumentPlugin: processing $file\n"
+  	if ($self->{'verbosity'}) > 1;
+
+    $file =~ s/^[\/\\]+//; # $file often begins with / so we'll tidy it up
+    $self->{'file'} = $file;
+    $self->{'filename'} = $filename_full_path;
+    $self->{'processor'} = $processor;
+    $self->{'metadata'} = $metadata;
+    
+    eval{
+	my ($file_only) = $file =~ /([^\\\/]*)$/;
+	my $tmpdir = &util::get_tmp_filename ();
+	&util::mk_all_dir ($tmpdir);
+	
+	$self->open_document();
+	
+	# save current working directory
+	my $cwd = getcwd();
+	chdir ($tmpdir) || die "Unable to change to $tmpdir";
+	&util::cp ($filename_full_path, $tmpdir);
+	
+	$self->unzip ("\"$file_only\"");
+	foreach my $xmlFile (@OpenDocumentPlugin::filesProcess) {
+	    if (-e $xmlFile) {
+		$self->{'parser'}->parsefile($xmlFile);
+	    }
+	}
+	$self->close_document($filename_full_path,$file_only);
+	
+	chdir ($cwd) || die "Unable to change back to $cwd";
+	&util::rm_r ($tmpdir);
+	
+    };
+    
+    if ($@) {
+
+	# parsefile may either croak somewhere in XML::Parser (e.g. because
+	# the document is not well formed) or die somewhere in ReadXMLFile or a
+	# derived plugin (e.g. because we're attempting to process a
+	# document whose DOCTYPE is not meant for this plugin). For the
+	# first case we'll print a warning and continue, for the second
+	# we'll just continue quietly
+
+	print STDERR "**** Error is: $@\n";
+
+	my ($msg) = $@ =~ /Carp::croak\(\'(.*?)\'\)/;
+	if (defined $msg) {	
+	    my $plugin_name = ref ($self);
+	    print $outhandle "$plugin_name failed to process $file ($msg)\n";
+	}
+
+	# reset ourself for the next document
+	print STDERR "<ProcessingError n='$file'>\n" if ($gli);
+	return -1; # error during processing
+    }
+
+    return 1;
+}
+
+sub unzip {
+    my $self = shift (@_);
+    my ($file) = @_;
+
+    system ("unzip $file");
+    &util::rm ($file) if -e $file;
+}
+
+sub close_document() {
+    my $self = shift(@_);
+    my ($filename,$file_only) = @_;
+  
+    my $doc_obj = $self->{'doc_obj'};  
+
+    my $mimetype = $self->get_mimetype();
+
+    $file_only = $doc_obj->get_assocfile_from_sourcefile(); # url-encoded filename in archives
+    
+    $doc_obj->associate_file($filename, $file_only, $mimetype, "");
+    $doc_obj->associate_file("Thumbnails/thumbnail.png", "thumbnail.png", "image/png", "");
+    my $doc_ext = $filename;
+    $doc_ext =~ s/.*\.od(.)/od$1/;
+    
+    # We use set instead of add here because we only want one value
+    $doc_obj->set_utf8_metadata_element("", "FileFormat", "Open Document");
+
+    #setup to doclink thingi
+    my $doclink = "<a href=\"_httpprefix_/collect/[collection]/index/assoc/[archivedir]/$file_only\">";
+    $doc_obj->add_utf8_metadata ("", "srclink",  $doclink); 
+    $doc_obj->add_utf8_metadata ("", "srcicon",  "<img border=\"0\" align=\"absmiddle\" src=\"_httpprefix_/collect/[collection]/index/assoc/[archivedir]/thumbnail.png\" alt=\"View the Open document\" title=\"View the Open document\">"); 
+    $doc_obj->add_utf8_metadata ("", "/srclink", "</a>"); 
+    $self->set_Source_metadata($doc_obj, $file_only);
+     $doc_obj->set_utf8_metadata_element("", "FileSize", (-s $filename));
+     
+    # include any metadata passed in from previous plugins 
+    # note that this metadata is associated with the top level section
+    $self->extra_metadata ($doc_obj, 
+			   $doc_obj->get_top_section(), 
+			   $self->{'metadata'});
+    
+    # add a Title if none has been found yet
+    $self->title_fallback($doc_obj,"",$file_only);
+   
+    # add an OID
+    $self->add_OID($doc_obj);
+    
+    $doc_obj->add_utf8_metadata("", "Plugin", "$self->{'plugin_type'}");
+
+    # process the document
+    $self->{'processor'}->process($doc_obj);
+    
+    $self->{'num_processed'} ++;
+    return 1;
+}
+
+sub get_mimetype(){
+    my $filename = "mimetype";
+    if (!open (FILEIN,"<$filename")){
+   	print STDERR "Warning: unable to open the $filename\n";
+	return "Unknown OpenDocument Format";
+    }
+    else {
+	my $text = "";
+	while (defined (my $line = <FILEIN>)) {
+	   $text .= $line;   
+	}
+	return $text;
+    }
+}
+1;
+
+
+
+
Index: /gsdl/stable/perllib/plugins/PDFPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/PDFPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/PDFPlugin.pm	(revision 20131)
@@ -0,0 +1,346 @@
+###########################################################################
+#
+# PDFPlugin.pm -- reasonably with-it pdf plugin
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+package PDFPlugin;
+
+use ConvertBinaryFile;
+use ReadTextFile;
+use unicode;
+use strict;
+no strict 'refs'; # so we can use a var for filehandles (eg STDERR)
+
+sub BEGIN {
+    @PDFPlugin::ISA = ('ConvertBinaryFile', 'ReadTextFile');
+}
+
+my $convert_to_list =
+    [ {	'name' => "auto",
+	'desc' => "{ConvertBinaryFile.convert_to.auto}" },
+      {	'name' => "html",
+	'desc' => "{ConvertBinaryFile.convert_to.html}" },
+      {	'name' => "text",
+	'desc' => "{ConvertBinaryFile.convert_to.text}" },
+      { 'name' => "pagedimg_jpg",
+	'desc' => "{ConvertBinaryFile.convert_to.pagedimg_jpg}"},
+      { 'name' => "pagedimg_gif",
+	'desc' => "{ConvertBinaryFile.convert_to.pagedimg_gif}"},
+      { 'name' => "pagedimg_png",
+	'desc' => "{ConvertBinaryFile.convert_to.pagedimg_png}"}, 
+      ];
+
+
+my $arguments = 
+    [
+     { 'name' => "convert_to",
+       'desc' => "{ConvertBinaryFile.convert_to}",
+       'type' => "enum",
+       'reqd' => "yes",
+       'list' => $convert_to_list, 
+       'deft' => "html" },	 
+     { 'name' => "process_exp",
+       'desc' => "{BasePlugin.process_exp}",
+       'type' => "regexp",
+       'deft' => &get_default_process_exp(),
+       'reqd' => "no" },
+     { 'name' => "block_exp",
+       'desc' => "{BasePlugin.block_exp}",
+       'type' => "regexp",
+       'deft' => &get_default_block_exp() },
+     { 'name' => "metadata_fields",
+       'desc' => "{HTMLPlugin.metadata_fields}",
+       'type' => "string",
+       'deft' => "" },
+     { 'name' => "noimages",
+       'desc' => "{PDFPlugin.noimages}",
+       'type' => "flag" },
+     { 'name' => "allowimagesonly",
+       'desc' => "{PDFPlugin.allowimagesonly}",
+       'type' => "flag" },
+     { 'name' => "complex",
+       'desc' => "{PDFPlugin.complex}",
+       'type' => "flag" },
+     { 'name' => "nohidden",
+       'desc' => "{PDFPlugin.nohidden}",
+       'type' => "flag" },
+     { 'name' => "zoom",
+       'desc' => "{PDFPlugin.zoom}",
+       'deft' => "2",
+       'range' => "1,3", # actually the range is 0.5-3 
+       'type' => "int" },
+     { 'name' => "use_sections",
+       'desc' => "{PDFPlugin.use_sections}",
+       'type' => "flag" },
+     { 'name' => "description_tags",
+       'desc' => "{HTMLPlugin.description_tags}",
+       'type' => "flag" }
+     ];
+
+my $options = { 'name'     => "PDFPlugin",
+		'desc'     => "{PDFPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'srcreplaceable' => "yes", # Source docs in PDF can be replaced with GS-generated html		
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@$inputargs,"-title_sub");
+    push(@$inputargs,'^(Page\s+\d+)?(\s*1\s+)?');
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my @arg_array = @$inputargs;
+    my $self = new ConvertBinaryFile($pluginlist, $inputargs, $hashArgOptLists);
+    
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    $self->{'filename_extension'} = "pdf";
+    $self->{'file_type'} = "PDF";
+
+    # these are passed through to gsConvert.pl by ConvertBinaryFile.pm
+    my $zoom = $self->{"zoom"};
+    $self->{'convert_options'} = "-pdf_zoom $zoom";
+    $self->{'convert_options'} .= " -pdf_complex" if $self->{"complex"};
+    $self->{'convert_options'} .= " -pdf_nohidden" if $self->{"nohidden"};
+    $self->{'convert_options'} .= " -pdf_ignore_images" if $self->{"noimages"};
+    $self->{'convert_options'} .= " -pdf_allow_images_only" if $self->{"allowimagesonly"};
+
+    my $secondary_plugin_options = $self->{'secondary_plugin_options'};
+
+    if (!defined $secondary_plugin_options->{'HTMLPlugin'}) {
+	$secondary_plugin_options->{'HTMLPlugin'} = [];
+    }
+    if (!defined $secondary_plugin_options->{'TextPlugin'}) {
+	$secondary_plugin_options->{'TextPlugin'} = [];
+    }
+    if (defined $self->{'convert_to'} && $self->{'convert_to'} =~ m/(pagedimage|pagedimg).*/i) {
+	if (!defined $secondary_plugin_options->{'PagedImagePlugin'}){
+	    $secondary_plugin_options->{'PagedImagePlugin'} = [];
+	    my $pagedimg_options = $secondary_plugin_options->{'PagedImagePlugin'}; 
+	    push(@$pagedimg_options, "-title_sub", '^(Page\s+\d+)?(\s*1\s+)?');
+	    push(@$pagedimg_options, "-screenviewsize", "1000");
+	    push(@$pagedimg_options, "-enable_cache");
+	}
+    }
+    my $html_options = $secondary_plugin_options->{'HTMLPlugin'};
+    my $text_options = $secondary_plugin_options->{'TextPlugin'};
+    my $pagedimg_options = $secondary_plugin_options->{'PagedImagePlugin'};
+
+#    if ($self->{'input_encoding'} eq "auto") {
+#	$self->{'input_encoding'} = "utf8";
+#    }
+
+    # if pdftohtml is always producing utf8, then htmlplug always needs this option
+    push(@$html_options,"-input_encoding", "utf8");
+    push(@$html_options,"-extract_language") if $self->{'extract_language'};
+    # Instruct HTMLPlug (when eventually accessed through read_into_doc_obj) 
+    # to extract these metadata fields from the HEAD META fields
+    my $required_metadata;
+    if (defined $self->{'metadata_fields'} && $self->{'metadata_fields'} =~ /\S/) {
+	push(@$html_options,"-metadata_fields",$self->{'metadata_fields'});
+    } else {
+	push(@$html_options,"-metadata_fields","Title,GENERATOR,date,author<Creator>");
+    }
+    #push(@$html_options,"-metadata_fields","Title,GENERATOR,date,author<Creator>");
+        
+    if ($self->{'use_sections'} || $self->{'description_tags'}) {
+	$self->{'description_tags'} = 1;
+	push(@$html_options,"-description_tags");
+    }
+
+    # following title_sub removes "Page 1" added by pdftohtml, and a leading
+    # "1", which is often the page number at the top of the page. Bad Luck
+    # if your document title actually starts with "1 " - is there a better way?
+    push(@$html_options , "-title_sub", '^(Page\s+\d+)?(\s*1\s+)?');
+    push(@$text_options , "-title_sub", '^(Page\s+\d+)?(\s*1\s+)?');
+
+    my $associate_tail_re = $self->{'associate_tail_re'};
+    if ((defined $associate_tail_re) && ($associate_tail_re ne "")) {
+	push(@$html_options, "-associate_tail_re", $associate_tail_re);
+	push(@$text_options, "-associate_tail_re", $associate_tail_re);
+	push(@$pagedimg_options, "-associate_tail_re", $associate_tail_re) if defined $pagedimg_options;
+    }
+
+    push(@$html_options, "-file_rename_method", "none");
+    push(@$text_options, "-file_rename_method", "none");
+    push(@$pagedimg_options, "-file_rename_method", "none") if defined $pagedimg_options;
+
+    $self = bless $self, $class;
+    $self->load_secondary_plugins($class,$secondary_plugin_options,$hashArgOptLists);
+    return $self;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.pdf$^;
+}
+
+# so we don't inherit HTMLPlug's block exp...
+sub get_default_block_exp {
+    return "";
+}
+    
+sub convert_post_process
+{
+    my $self = shift (@_);
+    my ($conv_filename) = @_;
+
+    my $outhandle=$self->{'outhandle'};
+
+    #$self->{'input_encoding'} = "utf8"; # The output is always in utf8 (is it?? it is for html, but what about other types?)
+    #my ($language, $encoding) = $self->textcat_get_language_encoding ($conv_filename);
+
+    # read in file ($text will be in utf8)
+    my $text = "";
+    # encoding will be utf8 for html files - what about other types? will we do this step for them anyway?
+    $self->read_file ($conv_filename, "utf8", "", \$text);
+
+    # Calculate number of pages based on <a ...> tags (we have a <a name=1> etc
+    # for each page).  Metadata based on this calculation not set until process()
+    # 
+    # Note: this is done even if we are not breaking to document into pages as it might
+    # be useful to give an indication of document length in browser through setting
+    # num_pages as metadata.
+    my @pages = ($text =~ /\<[Aa] name=\"?\w+\"?>/ig);
+    my $num_pages = scalar(@pages);
+    $self->{'num_pages'} = $num_pages;
+
+    if ($self->{'use_sections'}
+	&& $self->{'converted_to'} eq "HTML") {
+
+	print $outhandle "PDFPlugin: Calculating sections...\n";
+
+	# we have "<a name=1></a>" etc for each page
+	# it may be <A name=
+	my @sections = split('<[Aa] name=', $text);
+
+	my $top_section = "";
+
+	if (scalar (@sections) == 1) { #only one section - no split!
+	    print $outhandle "PDFPlugin: warning - no sections found\n";
+	} else {
+	    $top_section .= shift @sections; # keep HTML header etc as top_section
+	}
+
+	# handle first section specially for title? Or all use first 100...
+	
+	my $title = $sections[0];
+	$title =~ s/^\"?\w+\"?>//; # specific for pdftohtml...
+	$title =~ s/<\/([^>]+)><\1>//g; # (eg) </b><b> - no space
+	$title =~ s/<[^>]*>/ /g;
+	$title =~ s/(?:&nbsp;|\xc2\xa0)/ /g; # utf-8 for nbsp...
+	$title =~ s/^\s+//s;
+	$title =~ s/\s+$//;
+	$title =~ s/\s+/ /gs;
+	$title =~ s/^$self->{'title_sub'}// if ($self->{'title_sub'});
+	$title =~ s/^\s+//s; # in case title_sub introduced any...
+	$title = substr ($title, 0, 100);
+	$title =~ s/\s\S*$/.../;
+
+
+	if (scalar (@sections) == 1) { # no sections found
+	    $top_section .= $sections[0];
+	    @sections=();
+	} else {
+	    $top_section .= "<!--<Section>\n<Metadata name=\"Title\">$title</Metadata>\n-->\n <!--</Section>-->\n";
+	}
+
+	# add metadata per section...
+	foreach my $section (@sections) {
+	    # section names are not always just digits, may be like "outline"
+	    $section =~ s@^\"?(\w+)\"?></a>@@; # leftover from split expression...
+
+	    $title = $1; # Greenstone does magic if sections are titled digits
+	    if (! defined($title) ) {
+		print STDERR "no title: $section\n";
+		$title = " "; # get rid of the undefined warning in next line
+	    }
+	    my $newsection = "<!-- from PDFPlugin -->\n<!-- <Section>\n";
+	    $newsection .= "<Metadata name=\"Title\">" . $title
+		. "</Metadata>\n--><p>\n";
+	    $newsection .= $section;
+	    $newsection .= "<!--</Section>-->\n";
+	    $section = $newsection;
+	}
+
+	$text=join('', ($top_section, @sections));
+    }
+
+    # turn any high bytes that aren't valid utf-8 into utf-8.
+    unicode::ensure_utf8(\$text);
+
+    # Write it out again!
+    $self->utf8_write_file (\$text, $conv_filename);
+}
+
+
+# do plugin specific processing of doc_obj for HTML type
+sub process {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    my $result = $self->process_type($base_dir,$file,$doc_obj);
+
+    # fix up the extracted date metadata to be in Greenstone date format,
+    # and fix the capitalisation of 'date'
+    my $cursection = $doc_obj->get_top_section();
+    foreach my $datemeta (@{$doc_obj->get_metadata($cursection, "date")}) {
+	$doc_obj->delete_metadata($cursection, "date", $datemeta);
+
+	# We're just interested in the date bit, not the time
+	# some pdf creators (eg "Acrobat 5.0 Scan Plug-in for Windows")
+	# set a /CreationDate, and set /ModDate to 000000000. pdftohtml
+	# extracts the ModDate, so it is 0...
+	$datemeta =~ /(\d+)-(\d+)-(\d+)/;
+	my ($year, $month, $day) = ($1,$2,$3);
+	if (defined($year) && defined($month) && defined($day)) {
+	    if ($year == 0) {next}
+	    if ($year < 100) {$year += 1900} # just to be safe
+	    if ($month =~ /^\d$/) {$month="0$month"} # single digit
+	    if ($day =~ /^\d$/) {$day="0$day"} # single digit
+	    my $date="$year$month$day";
+	    $doc_obj->add_utf8_metadata($cursection, "Date", $date);
+	}
+    }
+
+    $doc_obj->add_utf8_metadata($cursection, "NumPages", $self->{'num_pages'});
+    
+    if ($self->{'use_sections'} && $self->{'converted_to'} eq "HTML") {
+	# we explicitly make it a paged document, cos greenstone won't get it
+	# right if any section has an empty title, or one with letters in it
+	$doc_obj->set_utf8_metadata_element ($cursection, "gsdlthistype", "Paged");
+    }
+
+    return $result;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/PagedImagePlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/PagedImagePlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/PagedImagePlugin.pm	(revision 20131)
@@ -0,0 +1,663 @@
+###########################################################################
+#
+# PagedImagePlugin.pm -- plugin for sets of images and OCR text that
+#  make up a document
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# PagedImagePlugin
+# processes sequences of images, with optional OCR text
+#
+# This plugin takes *.item files, which contain metadata and lists of image 
+# files, and produces a document containing sections, one for each page.
+# The files should be named something.item, then you can have more than one 
+# book in a directory. You will need to create these files, one for each
+# document/book.
+#
+#There are two formats for the item files: a plain text format, and an xml 
+#format. You can use either format, and can have both formats in the same 
+#collection if you like. If you use the plain format, you must not start the 
+#file off with <PagedDocument>
+
+#### PLAIN FORMAT
+# The format of the xxx.item file is as follows:
+# The first lines contain any metadata for the whole document
+# <metadata-name>metadata-value
+# eg.
+# <Title>Snail farming
+# <Date>19230102
+# Then comes a list of pages, one page per line, each line has the format
+#
+# pagenum:imagefile:textfile:r
+#
+# page num and imagefile are required. pagenum is used for the Title 
+# of the section, and in the display is shown as page <pagenum>. 
+# imagefile is the image for the page. textfile is an optional text 
+# file containing the OCR (or any) text for the page - this gets added 
+# as the text for the section. r is optional, and signals that the image 
+# should be rotated 180deg. Eg use this if the image has been made upside down.
+# So an example item file looks like:
+# <Title>Snail farming
+# <Date>19960403
+# 1:p1.gif:p1.txt:
+# 2:p2.gif::
+# 3:p3.gif:p3.txt:
+# 3b:p3b.gif:p3b.txt:r
+# The second page has no text, the fourth page is a back page, and 
+# should be rotated.
+# 
+
+#### XML FORMAT
+# The xml format looks like the following
+#<PagedDocument>
+#<Metadata name="Title">The Title of the entire document</Metadata>
+#<Page pagenum="1" imgfile="xxx.jpg" txtfile="yyy.txt">
+#<Metadata name="Title">The Title of this page</Metadata>
+#</Page>
+#... more pages
+#</PagedDocument>
+#PagedDocument contains a list of Pages, Metadata and PageGroups. Any metadata 
+#that is not inside another tag will belong to the document.
+#Each Page has a pagenum (not used at the moment), an imgfile and/or a txtfile.
+#These are both optional - if neither is used, the section will have no content.
+#Pages can also have metadata associated with them.
+#PageGroups can be introduced at any point - they can contain Metadata and Pages and other PageGroups. They are used to introduce hierarchical structure into the document.
+#For example
+#<PagedDocument>
+#<PageGroup>
+#<Page>
+#<Page>
+#</PageGroup>
+#<Page>
+#</PagedDocument>
+#would generate a structure like
+#X
+#--X
+#  --X
+#  --X
+#--X
+#PageGroup tags can also have imgfile/textfile metadata if you like - this way they get some content themselves.
+
+#Currently the XML structure doesn't work very well with the paged document type, unless you use numerical Titles for each section.
+#There is still a bit of work to do on this format:
+#* enable other text file types, eg html, pdf etc
+#* make the document paging work properly
+#* add pagenum as Title unless a Title is present?
+
+# All the supplemetary image amd text files should be in the same folder as 
+# the .item file.
+#
+# To display the images instead of the document text, you can use [srcicon] 
+# in the DocumentText format statement.
+# For example, 
+#
+# format DocumentText "<center><table width=_pagewidth_><tr><td>[srcicon]</td></tr></table></center>"
+#
+# To have it create thumbnail size images, use the '-create_thumbnail' option.
+# To have it create medium size images for display, use the '-create_screenview'
+# option. As usual, running 
+# 'perl -S pluginfo.pl PagedImagePlugin' will list all the options.
+
+# If you want the resulting documents to be presented with a table of 
+# contents, use '-documenttype hierarchy', otherwise they will have 
+# next and previous arrows, and a goto page X box. 
+
+# If you have used -create_screenview, you can also use [screenicon] in the format
+# statement to display the smaller image.  Here is an example  that switches 
+# between the two: 
+#
+# format DocumentText "<center><table width=_pagewidth_><tr><td>{If}{_cgiargp_ eq full,<a href='_httpdocument_&d=_cgiargd_&p=small'>Switch to small version.</a>,<a href='_httpdocument_&d=_cgiargd_&p=full'>Switch to fullsize version</a>}</td></tr><tr><td>{If}{_cgiargp_ eq full,<a href='_httpdocument_&d=_cgiargd_&p=small' title='Switch to small version'>[srcicon]</a>,<a href='_httpdocument_&d=_cgiargd_&p=full' title='Switch to fullsize version'>[screenicon]</a>}</td></tr></table></center>"
+#
+# Additional metadata can be added into the .item files, alternatively you can 
+# use normal metadata.xml files, with the name of the xxx.item file as the 
+# FileName (only for document level metadata).
+
+package PagedImagePlugin;
+
+use ReadXMLFile;
+use ReadTextFile;
+use ImageConverter;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @PagedImagePlugin::ISA = ('ReadXMLFile', 'ReadTextFile', 'ImageConverter');
+}
+
+my $type_list =
+    [ { 'name' => "paged",
+        'desc' => "{PagedImagePlugin.documenttype.paged}" },
+      { 'name' => "hierarchy",
+        'desc' => "{PagedImagePlugin.documenttype.hierarchy}" } ];
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "string",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" },
+      { 'name' => "block_exp",
+	'desc' => "{BasePlugin.block_exp}",
+	'type' => "string",
+	'deft' => &get_default_block_exp(),
+	'reqd' => "no" },
+      { 'name' => "title_sub",
+	'desc' => "{HTMLPlugin.title_sub}",
+	'type' => "string", 
+	'deft' => "" },
+      { 'name' => "headerpage",
+	'desc' => "{PagedImagePlugin.headerpage}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "documenttype",
+	'desc' => "{PagedImagePlugin.documenttype}",
+	'type' => "enum",
+	'list' => $type_list,
+	'deft' => "paged",
+	'reqd' => "no" } ];
+
+
+my $options = { 'name'     => "PagedImagePlugin",
+		'desc'     => "{PagedImagePlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+    
+    my $imc_self = new ImageConverter($pluginlist, $inputargs, $hashArgOptLists);
+    my $rtf_self = new ReadTextFile($pluginlist, $inputargs, $hashArgOptLists, 1);
+    my $rxf_self = new ReadXMLFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    my $self = BasePlugin::merge_inheritance($imc_self,$rtf_self,$rxf_self);
+
+    # Update $self used by XML::Parser so it finds callback functions 
+    # such as start_document here and not in ReadXMLFile (which is what
+    # $self was when new XML::Parser was done)
+    #
+    # If the $self returned by this constructor is the same as the one
+    # used in ReadXMLFile (e.g. in the GreenstoneXMLPlugin) then this step isn't necessary
+    #
+    # Consider embedding this type of assignment into merge_inheritance
+    # to help catch all cases?
+
+    $rxf_self->{'parser'}->{'PluginObj'} = $self;
+
+    return bless $self, $class;
+}
+
+
+sub init {
+    my $self = shift (@_);
+    my ($verbosity, $outhandle, $failhandle) = @_;
+
+    $self->SUPER::init(@_);
+    $self->ImageConverter::init();
+}
+
+sub begin {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $processor, $maxdocs) = @_;
+
+    $self->SUPER::begin(@_);
+    $self->ImageConverter::begin(@_);
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^\.item$^;
+}
+
+sub get_doctype {
+    my $self = shift(@_);
+    
+    return "PagedDocument";
+}
+
+
+# want to block everything except the .item ones 
+# but instead we will block images and txt files
+sub get_default_block_exp {
+    my $self = shift (@_);
+    
+    return q^(?i)(\.jpe?g|\.gif|\.png|\.tif?f|\.te?xt|\.html?|~)$^
+###    return q^(?i)(\.jpe?g|\.gif|\.png|\.tif?f|\.te?xt|\.html?|\.css|\.opd|\.pdf|~)$^
+}
+
+
+# want to use BasePlugin's version of this, not ReadXMLFile's
+sub can_process_this_file {
+    my $self = shift(@_);
+    
+    return $self->BasePlugin::can_process_this_file(@_);
+}
+
+# we want to use BasePlugin's read, not ReadXMLFile's
+sub read
+{
+    my $self = shift (@_);
+
+    $self->BasePlugin::read(@_);
+}
+
+
+
+sub read_into_doc_obj {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+    
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+
+    print $outhandle "PagedImagePlugin processing \"$filename_full_path\"\n"
+	if $verbosity > 1;
+    print STDERR "<Processing n='$file' p='PagedImagePlugin'>\n" if ($gli);
+    
+    $self->{'MaxImageWidth'} = 0;
+    $self->{'MaxImageHeight'} = 0;
+    
+    # here we need to decide if we have an old text .item file, or a new xml 
+    # .item file
+    my $xml_version = $self->is_xml_item_file($filename_full_path);
+
+    $self->tidy_item_file($filename_full_path);
+    
+    my $doc_obj;
+    if ($xml_version) {
+	# careful checking needed here!! are we using local xml handlers or super ones
+	$self->ReadXMLFile::read($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli);
+	$doc_obj = $self->{'doc_obj'};
+    } else {
+	my ($dir);
+	($dir, $file) = $filename_full_path =~ /^(.*?)([^\/\\]*)$/;
+
+	#process the .item file
+	$doc_obj = $self->process_item($filename_full_path, $dir, $file, $processor);
+	
+    }
+
+    my $section = $doc_obj->get_top_section();
+        
+    $doc_obj->add_utf8_metadata($section, "Plugin", "$self->{'plugin_type'}");
+    $doc_obj->add_metadata($section, "FileFormat", "PagedImage");
+
+    # include any metadata passed in from previous plugins 
+    # note that this metadata is associated with the top level section
+    $self->add_associated_files($doc_obj, $filename_full_path);
+    $self->extra_metadata ($doc_obj, $section, $metadata);
+    $self->auto_extract_metadata ($doc_obj);
+
+    # if we haven't found any Title so far, assign one
+    $self->title_fallback($doc_obj,$section,$filename_no_path);
+
+    $self->add_OID($doc_obj);
+    return (1,$doc_obj);
+}
+
+# for now, the test is if the first non-empty line is <PagedDocument>, then its xml
+sub is_xml_item_file {
+    my $self = shift(@_);
+    my ($filename) = @_;
+
+    my $xml_version = 0;
+    open (ITEMFILE, $filename) || die "couldn't open $filename\n";
+
+    my $line = "";
+    my $num = 0;
+
+    $line = <ITEMFILE>;
+    while (defined ($line) && ($line !~ /\w/)) {
+	$line = <ITEMFILE>;
+    }
+
+    if (defined $line) {
+	chomp $line;
+	if ($line =~ /<PagedDocument/) {
+	    $xml_version = 1;
+	}
+    } 
+
+    close ITEMFILE; 
+    return $xml_version;
+}
+
+sub tidy_item_file {
+    my $self = shift(@_);
+    my ($filename) = @_;
+
+    open (ITEMFILE, $filename) || die "couldn't open $filename\n";
+    my $backup_filename = "backup.item";
+    open (BACKUP,">$backup_filename")|| die "couldn't write to $backup_filename\n";
+    my $line = "";
+    $line = <ITEMFILE>;
+    $line =~ s/^\xEF\xBB\xBF//; # strip BOM
+    $line =~ s/\x0B+//ig;
+    $line =~ s/&/&amp;/g;
+    print BACKUP ($line);
+    #Tidy up the item file some metadata title contains \vt-vertical tab
+    while ($line = <ITEMFILE>) {
+	$line =~ s/\x0B+//ig;
+	$line =~ s/&/&amp;/g;
+	print BACKUP ($line);
+    }
+    close ITEMFILE;
+    close BACKUP;
+    &File::Copy::copy ($backup_filename, $filename);
+    &util::rm($backup_filename);
+
+}
+
+sub rotate_image {
+    my $self = shift (@_);
+    my ($filename_full_path) = @_;
+    
+    my ($this_filetype) = $filename_full_path =~ /\.([^\.]*)$/;
+    my $result = $self->convert($filename_full_path, $this_filetype, "-rotate 180", "ROTATE");
+    my ($new_filename) = ($result =~ /=>(.*\.$this_filetype)/);
+    if (-e "$new_filename") {
+	return $new_filename;
+    }
+    # somethings gone wrong
+    return $filename_full_path;
+
+}
+
+sub process_image {
+    my $self = shift(@_);
+    my ($filename_full_path, $filename_no_path, $doc_obj, $section, $rotate) = @_;
+    # do rotation
+    if  ((defined $rotate) && ($rotate eq "r")) {
+	# check the filenames
+	return 0 if ($filename_no_path eq "" || !-f $filename_full_path);
+
+	# we get a new temporary file which is rotated
+	$filename_full_path = $self->rotate_image($filename_full_path);
+    }
+    
+    # do generate images
+    my $result = 0;
+    if ($self->{'image_conversion_available'} == 1) {
+	# do we need to convert $filename_no_path to utf8? We are already reading in from a file, what encoding is it in???
+	$result = $self->generate_images($filename_full_path, $filename_no_path, $doc_obj, $section);
+    }
+    #overwrite one set in ImageConverter
+    $doc_obj->set_metadata_element ($section, "FileFormat", "PagedImage");
+    return $result;
+}
+
+
+sub xml_start_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+    $self->{'element'} = $element;
+    
+    my $doc_obj = $self->{'doc_obj'};
+    if ($element eq "PagedDocument") {
+	$self->{'current_section'} = $doc_obj->get_top_section();
+    } elsif ($element eq "PageGroup" || $element eq "Page") {
+	# create a new section as a child
+	$self->{'current_section'} = $doc_obj->insert_section($doc_obj->get_end_child($self->{'current_section'}));
+	$self->{'num_pages'}++;
+	# assign pagenum as  what??
+	my $pagenum = $_{'pagenum'}; #TODO!!
+	if (defined $pagenum) {
+	    $doc_obj->set_utf8_metadata_element($self->{'current_section'}, 'PageNum', $pagenum);
+	}
+	my ($imgfile) = $_{'imgfile'};
+	if (defined $imgfile) {
+	    # *****
+	    # What about support for rotate image (e.g. old ':r' notation)? 
+	    $self->process_image($self->{'xml_file_dir'}.$imgfile, $imgfile, $doc_obj, $self->{'current_section'});
+	}
+	my ($txtfile) = $_{'txtfile'};
+	if (defined($txtfile)&& $txtfile ne "") {
+	    $self->process_text ($self->{'xml_file_dir'}.$txtfile, $txtfile, $doc_obj, $self->{'current_section'});
+  	} else {
+	    $self->add_dummy_text($doc_obj, $self->{'current_section'});
+	}
+    } elsif ($element eq "Metadata") {
+	$self->{'metadata_name'} = $_{'name'};
+    }
+}
+
+sub xml_end_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+    
+    my $doc_obj = $self->{'doc_obj'};
+    if ($element eq "Page" || $element eq "PageGroup") {
+	# if Title hasn't been assigned, set PageNum as Title
+	if (!defined $doc_obj->get_metadata_element ($self->{'current_section'}, "Title") && defined $doc_obj->get_metadata_element ($self->{'current_section'}, "PageNum" )) {
+	    $doc_obj->add_utf8_metadata ($self->{'current_section'}, "Title", $doc_obj->get_metadata_element ($self->{'current_section'}, "PageNum" ));
+	}
+	# move the current section back to the parent
+	$self->{'current_section'} = $doc_obj->get_parent_section($self->{'current_section'});
+    } elsif ($element eq "Metadata") {
+	
+	$doc_obj->add_utf8_metadata ($self->{'current_section'}, $self->{'metadata_name'}, $self->{'metadata_value'});
+	$self->{'metadata_name'} = "";
+	$self->{'metadata_value'} = "";
+
+    }
+    # otherwise we ignore the end tag
+}
+
+
+sub xml_text {
+    my $self = shift(@_);
+    my ($expat) = @_; 
+
+    if ($self->{'element'} eq "Metadata" && $self->{'metadata_name'}) {
+   	$self->{'metadata_value'} .= $_;
+    }
+}
+
+sub xml_doctype {
+}
+
+sub open_document {
+    my $self = shift(@_);
+    
+    # create a new document
+    $self->{'doc_obj'} = new doc ($self->{'filename'}, "indexed_doc", $self->{'file_rename_method'});
+    # TODO is file filenmae_no_path??
+    $self->set_initial_doc_fields($self->{'doc_obj'}, $self->{'file'}, $self->{'processor'});
+
+    my ($dir, $file) = $self->{'filename'} =~ /^(.*?)([^\/\\]*)$/;
+    $self->{'xml_file_dir'} = $dir;
+    $self->{'num_pages'} = 0;
+
+}
+
+sub close_document {
+    my $self = shift(@_);
+    my $doc_obj = $self->{'doc_obj'};
+    
+    # add numpages metadata
+    my $topsection = $doc_obj->get_top_section();
+
+    $doc_obj->set_utf8_metadata_element ($topsection, 'NumPages', $self->{'num_pages'});
+
+    $doc_obj->set_utf8_metadata_element($topsection,"MaxImageWidth",$self->{'MaxImageWidth'});
+    $doc_obj->set_utf8_metadata_element($topsection,"MaxImageHeight",$self->{'MaxImageHeight'});
+    $self->{'MaxImageWidth'} = undef;
+    $self->{'MaxImageHeight'} = undef;
+    
+}
+
+
+sub set_initial_doc_fields {
+    my $self = shift(@_);
+    my ($doc_obj, $filename_no_path, $processor) = @_;
+
+    my $topsection = $doc_obj->get_top_section();
+
+    if ($self->{'documenttype'} eq 'paged') {
+	# set the gsdlthistype metadata to Paged - this ensures this document will
+	# be treated as a Paged doc, even if Titles are not numeric
+	$doc_obj->set_utf8_metadata_element ($topsection, "gsdlthistype", "Paged");
+    } else {
+	$doc_obj->set_utf8_metadata_element ($topsection, "gsdlthistype", "Hierarchy");
+    }
+
+    $self->set_Source_metadata($doc_obj, $filename_no_path);
+   
+    # if we want a header page, we need to add some text into the top section, otherwise this section will become invisible
+    if ($self->{'headerpage'}) {
+	$self->add_dummy_text($doc_obj, $topsection);
+    }
+
+
+}
+
+
+sub process_item {
+    my $self = shift (@_);
+    my ($filename_full_path, $dir, $filename_no_path, $processor) = @_;
+
+    my $doc_obj = new doc ($filename_full_path, "indexed_doc", $self->{'file_rename_method'});
+    $self->set_initial_doc_fields($doc_obj, $filename_no_path, $processor);
+    my $topsection = $doc_obj->get_top_section();
+    open (ITEMFILE, $filename_full_path) || die "couldn't open $filename_full_path\n";
+    my $line = "";
+    my $num = 0;
+    while (defined ($line = <ITEMFILE>)) {
+	next unless $line =~ /\w/;
+	chomp $line;
+	next if $line =~ /^#/; # ignore comment lines
+	if ($line =~ /^<([^>]*)>\s*(.*?)\s*$/) {
+	    $doc_obj->set_utf8_metadata_element ($topsection, $1, $2);
+	    #$meta->{$1} = $2;
+	} else {
+	    $num++;
+	    # line should be like page:imagefilename:textfilename:r - the r is optional -> means rotate the image 180 deg
+	    $line =~ s/^\s+//; #remove space at the front
+	    $line =~ s/\s+$//; #remove space at the end
+	    my ($pagenum, $imgname, $txtname, $rotate) = split /:/, $line;
+	    
+	    # create a new section for each image file
+	    my $cursection = $doc_obj->insert_section($doc_obj->get_end_child($topsection));
+	    # the page number becomes the Title
+	    $doc_obj->set_utf8_metadata_element($cursection, 'Title', $pagenum);
+	 
+	    # process the image for this page if there is one
+	    if (defined $imgname && $imgname ne "") {
+		my $result1 = $self->process_image($dir.$imgname, $imgname, $doc_obj, $cursection, $rotate);
+		
+		if (!defined $result1)
+		{
+		    print "PagedImagePlugin: couldn't process image \"$dir.$imgname\" for item \"$filename_full_path\"\n";
+		}
+	    }
+	    # process the text file if one is there
+	    if (defined $txtname && $txtname ne "") {
+		my $result2 = $self->process_text ($dir.$txtname, $txtname, $doc_obj, $cursection);
+               
+		if (!defined $result2) {
+		    print "PagedImagePlugin: couldn't process text file \"$dir.$txtname\" for item \"$filename_full_path\"\n";
+		    $self->add_dummy_text($doc_obj, $cursection);
+		}
+	    } else {
+		# otherwise add in some dummy text 
+		$self->add_dummy_text($doc_obj, $cursection);
+	    }
+	}
+    }
+    
+    close ITEMFILE;
+
+    # add numpages metadata
+    $doc_obj->set_utf8_metadata_element ($topsection, 'NumPages', "$num");
+
+    $doc_obj->set_utf8_metadata_element($topsection,"MaxImageWidth",$self->{'MaxImageWidth'});
+    $doc_obj->set_utf8_metadata_element($topsection,"MaxImageHeight",$self->{'MaxImageHeight'});
+    $self->{'MaxImageWidth'} = undef;
+    $self->{'MaxImageHeight'} = undef;
+
+
+    return $doc_obj;
+}
+
+sub process_text {
+    my $self = shift (@_);
+    my ($filename_full_path, $file, $doc_obj, $cursection) = @_;
+    
+    # check that the text file exists!!
+    if (!-f $filename_full_path) {
+	print "PagedImagePlugin: ERROR: File $filename_full_path does not exist, skipping\n";
+	return 0;
+    }
+
+    # Do encoding stuff
+    my ($language, $encoding) = $self->textcat_get_language_encoding ($filename_full_path);
+
+    my $text="";
+    &ReadTextFile::read_file($self, $filename_full_path, $encoding, $language, \$text);
+    if (!length ($text)) {
+	# It's a bit unusual but not out of the question to have no text, so just give a warning
+        print "PagedImagePlugin: WARNING: $filename_full_path contains no text\n";
+    }
+
+    # we need to escape the escape character, or else mg will convert into
+    # eg literal newlines, instead of leaving the text as '\n'
+    $text =~ s/\\/\\\\/g; # macro language
+    $text =~ s/_/\\_/g; # macro language
+
+
+    if ($text =~ m/<html.*?>\s*<head.*?>.*<\/head>\s*<body.*?>(.*)<\/body>\s*<\/html>\s*$/is) {
+	# looks like HTML input
+	# no need to escape < and > or put in <pre> tags
+
+	$text = $1;
+
+	# insert preformat tags and add text to document object
+	$doc_obj->add_utf8_text($cursection, "$text");
+    }
+    else {
+	$text =~ s/</&lt;/g;
+	$text =~ s/>/&gt;/g;
+
+	# insert preformat tags and add text to document object
+	$doc_obj->add_utf8_text($cursection, "<pre>\n$text\n</pre>");
+    }
+
+    
+    return 1;
+}
+
+
+sub clean_up_after_doc_obj_processing {
+    my $self = shift(@_);
+    
+    $self->ImageConverter::clean_up_temporary_files();
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/PostScriptPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/PostScriptPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/PostScriptPlugin.pm	(revision 20131)
@@ -0,0 +1,269 @@
+###########################################################################
+#
+# PostScriptPlugin.pm -- plugin to process PostScript files
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package PostScriptPlugin;
+
+use ConvertBinaryFile;
+use ReadTextFile; # for read_file in convert_post_process. do we need it?
+use sorttools;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @PostScriptPlugin::ISA = ('ConvertBinaryFile', 'ReadTextFile');
+}
+
+my $convert_to_list =
+    [ {	'name' => "auto",
+	'desc' => "{ConvertBinaryFile.convert_to.auto}" },
+      {	'name' => "text",
+	'desc' => "{ConvertBinaryFile.convert_to.text}" },
+      { 'name' => "pagedimg_jpg",
+	'desc' => "{ConvertBinaryFile.convert_to.pagedimg_jpg}" },
+      { 'name' => "pagedimg_gif",
+	'desc' => "{ConvertBinaryFile.convert_to.pagedimg_gif}" },
+      { 'name' => "pagedimg_png",
+	'desc' => "{ConvertBinaryFile.convert_to.pagedimg_png}" }
+      ];
+
+my $arguments =
+    [ { 'name' => "convert_to",
+	'desc' => "{ConvertBinaryFile.convert_to}",
+	'type' => "enum",
+	'reqd' => "yes",
+	'list' => $convert_to_list, 
+	'deft' => "text" },
+      { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" },
+      { 'name' => "block_exp",
+	'desc' => "{BasePlugin.block_exp}",
+	'type' => 'regexp',
+	'deft' => &get_default_block_exp() },
+      { 'name' => "extract_date",
+	'desc' => "{PostScriptPlugin.extract_date}",
+	'type' => "flag" },
+      { 'name' => "extract_pages",
+	'desc' => "{PostScriptPlugin.extract_pages}",
+	'type' => "flag" },
+      { 'name' => "extract_title",
+	'desc' => "{PostScriptPlugin.extract_title}",
+	'type' => "flag" } ];
+
+my $options = { 'name'     => "PostScriptPlugin",
+		'desc'     => "{PostScriptPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'srcreplaceable' => "yes", # Source docs in postscript format can be replaced with GS-generated html
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    #push(@$inputargs,"-convert_to");
+    #push(@$inputargs,"text");
+    push(@$inputargs,"-title_sub");
+    push(@$inputargs,'^(Page\s+\d+)?(\s*1\s+)?');
+    
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+    
+    my $self = new ConvertBinaryFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    $self->{'filename_extension'} = "ps";
+    $self->{'file_type'} = "PS";
+
+    my $secondary_plugin_options = $self->{'secondary_plugin_options'};
+
+    if (!defined $secondary_plugin_options->{'TextPlugin'}) {
+	$secondary_plugin_options->{'TextPlugin'} = [];
+    }
+
+    if (!defined $secondary_plugin_options->{'HTMLPlugin'}) {
+	$secondary_plugin_options->{'HTMLPlugin'} = [];
+    }
+
+    my $text_options = $secondary_plugin_options->{'TextPlugin'};
+    my $html_options = $secondary_plugin_options->{'HTMLPlugin'};
+
+    if (defined $self->{'convert_to'} && $self->{'convert_to'} =~ m/(pagedimage|pagedimg).*/i) {
+	if (!defined $secondary_plugin_options->{'PagedImagePlugin'}){
+	    $secondary_plugin_options->{'PagedImagePlugin'} = [];
+	    my $pagedimg_options = $secondary_plugin_options->{'PagedImagePlugin'}; 
+	    push(@$pagedimg_options, "-title_sub", '^(Page\s+\d+)?(\s*1\s+)?');
+	    push(@$pagedimg_options, "-file_rename_method", "none");
+	}
+    }
+    # following title_sub removes "Page 1" added by ps2ascii, and a leading
+    # "1", which is often the page number at the top of the page. Bad Luck
+    # if your document title actually starts with "1 " - is there a better way?
+    #$self->{'input_encoding'} = "utf8";
+    #$self->{'extract_language'} = 1;
+    push(@$text_options, "-input_encoding", "utf8");
+    push(@$text_options,"-extract_language") if $self->{'extract_language'};
+    push(@$text_options , "-title_sub", '^(Page\s+\d+)?(\s*1\s+)?');
+
+    push(@$text_options, "-file_rename_method", "none");
+    push(@$html_options, "-file_rename_method", "none");
+    
+    $self = bless $self, $class;
+    # used for convert_post_process
+    $self->{'input_encoding'} = "auto";
+    $self->{'default_encoding'} = "utf8";
+
+    $self->load_secondary_plugins($class,$secondary_plugin_options, $hashArgOptLists);
+
+    return $self;
+}
+
+
+sub get_default_block_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.(eps)$^;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.ps$^;
+}
+
+# this has been commented out in other plugins. do we need it here?
+# ps files are converted to images (item file should be in utf8) or text (uses pstoascii), so we shouldn't need to ensure utf8
+sub convert_post_process
+{
+    my $self = shift (@_);
+    my ($conv_filename) = @_;
+    
+    my $outhandle=$self->{'outhandle'};
+    
+    my ($language, $encoding) = $self->textcat_get_language_encoding ($conv_filename);
+    
+    # read in file ($text will be in utf8)
+    my $text = "";
+    $self->read_file ($conv_filename, $encoding, $language, \$text);
+    
+    # turn any high bytes that aren't valid utf-8 into utf-8.
+    unicode::ensure_utf8(\$text);
+    
+    # Write it out again!
+    $self->utf8_write_file (\$text, $conv_filename);
+}
+
+sub extract_metadata_from_postscript {
+    my $self = shift (@_);
+
+    my ($filename,$doc) = @_;
+
+    my $section = $doc->get_top_section();
+
+    my $title_found = 0;
+    my $pages_found = 0;
+    my $date_found = 0;
+
+    print STDERR "PostScriptPlugin: extracting PostScript metadata from \"$filename\"\n" 
+	if $self->{'verbosity'} > 1;
+
+    open(INPUT, "<$filename");
+    my $date;
+
+    while(my $line =<INPUT>) {
+	if ($self->{'extract_title'} && !$title_found) {
+	    foreach my $word ($line =~ m|Title: ([-A-Za-z0-9@/\/\(\):,. ]*)|g) {
+		my $new_word = $word; 
+		$new_word =~ s/\(Untitled\)//i;
+		$new_word =~ s/\(Microsoft Word\)//i;
+		$new_word =~ s/Microsoft Word//i;
+		$new_word =~ s/^\(//i;
+		$new_word =~ s/\)$//i;
+		$new_word =~ s/^ - //i;
+		if ($new_word ne "") {
+		    $doc->add_utf8_metadata($section, "Title", $new_word );
+		    $title_found = 1;
+		}
+	    }
+	}
+	if ($self->{'extract_date'} && !$date_found) {
+            foreach my $word ($line =~ m/(Creation[-A-Za-z0-9@\/\(\):,. ]*)/g) {
+                if ($word =~ m/ ([A-Za-z][A-Za-z][A-Za-z]) ([0-9 ][0-9])  ?[0-9: ]+ ([0-9]{4})/) {
+                    $date = &sorttools::format_date($2,$1,$3);
+		    if (defined $date) {
+			$doc->add_utf8_metadata($section, "Date", $date );
+		    }
+                }
+                if ($word =~ m/D:([0-9]{4})([0-9]{2})([0-9]{2})[0-9]{6}\)/) {
+                    $date = &sorttools::format_date($3,$2,$1);
+		    if (defined $date) {
+			$doc->add_utf8_metadata($section, "Date", $date );
+		    }
+                }
+                if ($word =~ m/CreationDate: ([0-9]{4}) ([A-Za-z][A-Za-z][A-Za-z]) ([0-9 ][0-9]) [0-9:]*/) {
+                    $date = &sorttools::format_date($3,$2,$1);
+		    if (defined $date) {
+			$doc->add_utf8_metadata($section, "Date", $date );
+		    }
+                }
+		$date_found = 1;
+            }
+	}
+	if ($self->{'extract_pages'} && !$pages_found) {
+	    foreach my $word ($line =~ m/(Pages: [0-9]*)/g) {
+                my $digits = $word;
+                $digits =~ s/[^0-9]//g;
+		if ($digits ne "" && $digits ne "0") {
+		    $doc->add_utf8_metadata($section, "Pages", $digits );
+		    $pages_found = 1;
+		}
+            }
+	}
+    }
+}
+
+# do plugin specific processing of doc_obj 
+sub process {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    my $filename = &util::filename_cat($base_dir,$file);
+    $self->extract_metadata_from_postscript($filename, $doc_obj);
+
+    return $self->SUPER::process(@_);
+
+}
+
+
+1;
+
Index: /gsdl/stable/perllib/plugins/PowerPointPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/PowerPointPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/PowerPointPlugin.pm	(revision 20131)
@@ -0,0 +1,150 @@
+###########################################################################
+#
+# PowerPointPlugin.pm -- plugin for importing Microsoft PowerPoint files.
+#  (currently only versions 95 and 97)
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2002 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package PowerPointPlugin;
+
+use ConvertBinaryFile;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @PowerPointPlugin::ISA = ('ConvertBinaryFile');
+}
+
+my $convert_to_list =
+    [ {	'name' => "auto",
+	'desc' => "{ConvertBinaryFile.convert_to.auto}" },
+      {	'name' => "html",
+	'desc' => "{ConvertBinaryFile.convert_to.html}" },
+      {	'name' => "text",
+	'desc' => "{ConvertBinaryFile.convert_to.text}" },
+      { 'name' => "pagedimg_jpg",
+	'desc' => "{ConvertBinaryFile.convert_to.pagedimg_jpg}" },
+      { 'name' => "pagedimg_gif",
+	'desc' => "{ConvertBinaryFile.convert_to.pagedimg_gif}" },
+      { 'name' => "pagedimg_png",
+	'desc' => "{ConvertBinaryFile.convert_to.pagedimg_png}" }
+      ];
+
+my $arguments = 
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp()}
+      ];
+
+my $options = { 'name'     => "PowerPointPlugin",
+		'desc'     => "{PowerPointPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'srcreplaceable' => "yes", # Source docs in PPT format can be replaced with GS-generated html
+	        'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    if ($ENV{'GSDLOS'} =~ m/^windows$/i) {
+	my $ws_arg =[{ 'name' => "convert_to",
+		       'desc' => "{ConvertBinaryFile.convert_to}",
+		       'type' => "enum",
+		       'reqd' => "yes",
+		       'list' => $convert_to_list, 
+		       'deft' => "html" },
+		     { 'name' => "windows_scripting",
+		       'desc' => "{PowerPointPlugin.windows_scripting}",
+		       'type' => "flag",
+		       'reqd' => "no" }
+		     ];
+	push(@$arguments,@$ws_arg);
+    }
+    
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+
+    my $self = new ConvertBinaryFile($pluginlist, $inputargs, $hashArgOptLists);
+ 
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    $self->{'filename_extension'} = "ppt";
+    $self->{'file_type'} = "PPT";
+
+    # ppthtml outputs utf-8 already.
+    #these are passed through to gsConvert.pl by ConvertBinaryFile.pm
+    $self->{'convert_options'} = "-windows_scripting" if $self->{'windows_scripting'};
+    my $secondary_plugin_options = $self->{'secondary_plugin_options'};
+
+    if ($self->{'windows_scripting'} && ($self->{'convert_to'} =~ m/(pagedimage|pagedimg).*/i)) {
+	$secondary_plugin_options->{'PagedImagePlugin'} = [];
+    } else {
+	$secondary_plugin_options->{'HTMLPlugin'} = [];
+	$secondary_plugin_options->{'TextPlugin'} = [];
+    }
+    my $html_options = $secondary_plugin_options->{'HTMLPlugin'};
+    my $text_options = $secondary_plugin_options->{'TextPlugin'};
+    my $pageimg_options = $secondary_plugin_options->{'PagedImagePlugin'};
+ 
+    if (defined $html_options){
+	push(@$html_options,"-input_encoding", "utf8");
+	push(@$html_options,"-extract_language") if $self->{'extract_language'};
+	push(@$html_options,"-file_rename_method", "none");
+	
+	# Instruct HTMLPlugin (when eventually accessed through read_into_doc_obj) 
+	# to extract these metadata fields from the HEAD META fields
+	push(@$html_options,"-metadata_fields","Title,GENERATOR,date,author<Creator>");
+    } 
+    if (defined $text_options){
+	push(@$text_options,"-input_encoding", "utf8");
+	push(@$text_options,"-extract_language") if $self->{'extract_language'};
+	push(@$text_options,"-file_rename_method", "none");
+    }
+    if (defined $pageimg_options){
+	push(@$pageimg_options,"-input_encoding", "utf8");
+	push(@$pageimg_options,"-extract_language") if $self->{'extract_language'};	
+	push(@$pageimg_options,"-file_rename_method", "none");
+    }
+
+    $self = bless $self, $class;
+
+    $self->load_secondary_plugins($class,$secondary_plugin_options,$hashArgOptLists);
+    return $self;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+    return q^(?i)\.ppt$^;
+}
+
+1;
+
Index: /gsdl/stable/perllib/plugins/PrintInfo.pm
===================================================================
--- /gsdl/stable/perllib/plugins/PrintInfo.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/PrintInfo.pm	(revision 20131)
@@ -0,0 +1,269 @@
+###########################################################################
+#
+# PrintInfo - most base plugin
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2008 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+## Most basic plugin, just handles parsing the arguments and printing out descriptions. Used for plugins and Extractor plugins
+
+package PrintInfo;
+
+BEGIN {
+    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
+}
+
+eval {require bytes};
+eval "require diagnostics"; # some perl distros (eg mac) don't have this
+
+# suppress the annoying "subroutine redefined" warning that various
+# plugins cause under perl 5.6
+$SIG{__WARN__} = sub {warn($_[0]) unless ($_[0] =~ /Subroutine\s+\S+\sredefined/)};
+
+use strict;
+no strict 'subs';
+
+use gsprintf 'gsprintf';
+use parse2;
+use printusage;
+
+my $arguments = [];
+
+my $options = { 'name'     => "PrintInfo",
+		'desc'     => "{PrintInfo.desc}",
+		'abstract' => "yes",
+		'inherits' => "no",
+		'args'     => $arguments };
+
+# $auxiliary_plugin argument passed in by "on-the-side" plugin helpers such as Extractors and ImageConverter. We don't want parsing of args done by them.
+sub new 
+{
+    my $class = shift (@_);
+    my ($pluginlist,$args,$hashArgOptLists, $auxiliary) = @_;
+    my $plugin_name = (defined $pluginlist->[0]) ? $pluginlist->[0] : $class;
+
+    if ($plugin_name eq $class) {
+	push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+	push(@{$hashArgOptLists->{"OptList"}},$options);
+    }
+    my $self = {};
+    $self->{'outhandle'} = STDERR;
+    $self->{'option_list'} = $hashArgOptLists->{"OptList"};
+    $self->{"info_only"} = 0;
+
+    # Check if gsdlinfo is in the argument list or not - if it is, don't parse 
+    # the args, just return the object.  
+    foreach my $strArg (@{$args})
+    {
+	if($strArg eq "-gsdlinfo")
+	{
+	    $self->{"info_only"} = 1;
+	    return bless $self, $class;
+	}
+    }
+    
+    if (defined $auxiliary) { # don't parse the args here
+	return bless $self, $class;
+    }
+
+    if(parse2::parse($args,$hashArgOptLists->{"ArgList"},$self) == -1)
+    {
+	my $classTempClass = bless $self, $class;
+	print STDERR "<BadPlugin p=$plugin_name>\n";
+	&gsprintf(STDERR, "\n{PrintInfo.bad_general_option}\n", $plugin_name);
+	$classTempClass->print_txt_usage("");  # Use default resource bundle
+	die "\n";
+    }
+
+    delete $self->{"info_only"};
+    # else parsing was successful.
+
+    $self->{'plugin_type'} = $plugin_name;
+ 
+    return bless $self, $class;
+    
+}   
+
+#sub init {
+#}
+
+sub get_arguments
+{
+    my $self = shift(@_);
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $pluginoptions = pop(@$optionlistref);
+    my $pluginarguments = $pluginoptions->{'args'};
+    return $pluginarguments;
+}
+
+
+sub print_xml_usage
+{
+    my $self = shift(@_);
+    my $header = shift(@_);
+    my $high_level_information_only = shift(@_);
+    
+    # XML output is always in UTF-8
+    gsprintf::output_strings_in_UTF8;
+
+    if ($header) {
+	&PrintUsage::print_xml_header("plugin");
+    }
+    $self->print_xml($high_level_information_only);
+}
+
+
+sub print_xml
+{
+    my $self = shift(@_);
+    my $high_level_information_only = shift(@_);
+
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $pluginoptions = shift(@$optionlistref);
+    return if (!defined($pluginoptions));
+
+    # Find the process and block default expressions in the plugin arguments
+    my $process_exp = "";
+    my $block_exp = "";
+    if (defined($pluginoptions->{'args'})) {
+	foreach my $option (@{$pluginoptions->{'args'}}) {
+	    if ($option->{'name'} eq "process_exp") {
+		$process_exp = $option->{'deft'};
+	    }
+	    if ($option->{'name'} eq "block_exp") {
+		$block_exp = $option->{'deft'};
+	    }
+	}
+    }
+
+    gsprintf(STDERR, "<PlugInfo>\n");
+    gsprintf(STDERR, "  <Name>$pluginoptions->{'name'}</Name>\n");
+    my $desc = gsprintf::lookup_string($pluginoptions->{'desc'});
+    $desc =~ s/</&amp;lt;/g; # doubly escaped
+    $desc =~ s/>/&amp;gt;/g;
+    gsprintf(STDERR, "  <Desc>$desc</Desc>\n");
+    gsprintf(STDERR, "  <Abstract>$pluginoptions->{'abstract'}</Abstract>\n");
+    gsprintf(STDERR, "  <Inherits>$pluginoptions->{'inherits'}</Inherits>\n");
+    gsprintf(STDERR, "  <Processes>$process_exp</Processes>\n");
+    gsprintf(STDERR, "  <Blocks>$block_exp</Blocks>\n");
+    gsprintf(STDERR, "  <Explodes>" . ($pluginoptions->{'explodes'} || "no") . "</Explodes>\n");
+    # adding new option that works with replace_srcdoc_with_html.pl
+    gsprintf(STDERR, "  <SourceReplaceable>" . ($pluginoptions->{'srcreplaceable'} || "no") . "</SourceReplaceable>\n");
+    unless (defined($high_level_information_only)) {
+	gsprintf(STDERR, "  <Arguments>\n");
+	if (defined($pluginoptions->{'args'})) {
+	    &PrintUsage::print_options_xml($pluginoptions->{'args'});
+	}
+	gsprintf(STDERR, "  </Arguments>\n");
+
+	# Recurse up the plugin hierarchy
+	$self->print_xml();
+    }
+    gsprintf(STDERR, "</PlugInfo>\n");
+}
+
+
+sub print_txt_usage
+{
+    my $self = shift(@_);
+    # Print the usage message for a plugin (recursively)
+    my $descoffset = $self->determine_description_offset(0);
+    $self->print_plugin_usage($descoffset, 1);
+}
+
+
+sub determine_description_offset
+{
+    my $self = shift(@_);
+    my $maxoffset = shift(@_);
+
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $pluginoptions = shift(@$optionlistref);
+    return $maxoffset if (!defined($pluginoptions));
+
+    # Find the length of the longest option string of this plugin
+    my $pluginargs = $pluginoptions->{'args'};
+    if (defined($pluginargs)) {
+	my $longest = &PrintUsage::find_longest_option_string($pluginargs);
+	if ($longest > $maxoffset) {
+	    $maxoffset = $longest;
+	}
+    }
+
+    # Recurse up the plugin hierarchy
+    $maxoffset = $self->determine_description_offset($maxoffset);
+    $self->{'option_list'} = \@optionlist;
+    return $maxoffset;
+}
+
+
+sub print_plugin_usage
+{
+    my $self = shift(@_);
+    my $descoffset = shift(@_);
+    my $isleafclass = shift(@_);
+
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $pluginoptions = shift(@$optionlistref);
+    return if (!defined($pluginoptions));
+
+    my $pluginname = $pluginoptions->{'name'};
+    my $pluginargs = $pluginoptions->{'args'};
+    my $plugindesc = $pluginoptions->{'desc'};
+
+    # Produce the usage information using the data structure above
+    if ($isleafclass) {
+	if (defined($plugindesc)) {
+	    gsprintf(STDERR, "$plugindesc\n\n");
+	}
+	gsprintf(STDERR, " {common.usage}: plugin $pluginname [{common.options}]\n\n");
+    }
+
+    # Display the plugin options, if there are some
+    if (defined($pluginargs)) {
+	# Calculate the column offset of the option descriptions
+	my $optiondescoffset = $descoffset + 2;  # 2 spaces between options & descriptions
+
+	if ($isleafclass) {
+	    gsprintf(STDERR, " {common.specific_options}:\n");
+	}
+	else {
+	    gsprintf(STDERR, " {common.general_options}:\n", $pluginname);
+	}
+
+	# Display the plugin options
+	&PrintUsage::print_options_txt($pluginargs, $optiondescoffset);
+    }
+
+    # Recurse up the plugin hierarchy
+    $self->print_plugin_usage($descoffset, 0);
+    $self->{'option_list'} = \@optionlist;
+}
+
+
+1;
+
+
Index: /gsdl/stable/perllib/plugins/ProCitePlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/ProCitePlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/ProCitePlugin.pm	(revision 20131)
@@ -0,0 +1,252 @@
+###########################################################################
+#
+# ProCitePlugin.pm -- A plugin for (exported) ProCite databases
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright 1999-2004 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package ProCitePlugin;
+
+
+use multiread;
+use SplitTextFile;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+# ProCitePlugin is a sub-class of SplitTextFile
+sub BEGIN {
+    @ProCitePlugin::ISA = ('SplitTextFile');
+}
+
+
+my $arguments = 
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() },
+      { 'name' => "split_exp",
+	'desc' => "{SplitTextFile.split_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_split_exp(),
+	'reqd' => "no" },
+      
+      # The interesting options
+      { 'name' => "entry_separator",
+	'desc' => "{ProCitePlugin.entry_separator}",
+	'type' => "string",
+	'reqd' => "no",
+	'deft' => "//" },
+      ];
+
+my $options = { 'name'     => "ProCitePlugin",
+		'desc'     => "{ProCitePlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'explodes' => "yes",
+		'args'     => $arguments };
+
+
+# This plugin processes exported ProCite files with the suffix ".txt"
+sub get_default_process_exp
+{
+    return q^(?i)(\.txt)$^;
+}
+
+
+# This plugin splits the input text at every line
+sub get_default_split_exp
+{
+    return q^\n^;
+}
+
+
+sub new
+{
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new SplitTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+
+my %crazy_workform_mapping =
+    ( "A", "Book, Long Form",
+      "B", "Book, Short Form",
+      "C", "Journal, Long Form",
+      "D", "Journal, Short Form",
+      "E", "Report",
+      "F", "Newspaper",
+      "G", "Dissertation",
+      "H", "Trade Catalog",
+      "I", "Letter (Correspondence)",
+      "J", "Manuscript",
+      "K", "Conference Proceedings",
+      "L", "Map",
+      "M", "Music Score",
+      "N", "Sound Recording",
+      "O", "Motion Picture",
+      "P", "Audiovisual Material",
+      "Q", "Video Recording",
+      "R", "Art Work",
+      "S", "Computer Program",
+      "T", "Data File" );
+
+
+sub read_file
+{
+    my $self = shift (@_);
+    my ($filename, $encoding, $language, $textref) = @_;
+    
+    # Store the workform definitions for this file
+    my %workform_definitions = ();
+
+    # Read the contents of the file into $textref
+    open(PROCITE_FILE, "<$filename");
+    my $reader = new multiread();
+    $reader->set_handle ('ProCitePlugin::PROCITE_FILE');
+    $reader->set_encoding ($encoding);
+    $reader->read_file ($textref);
+    close(PROCITE_FILE);
+
+    # Read the workform definitions at the start of the file
+    while ($$textref =~ /^\<Workform Definition\>/) {
+	# Remove the workform definition line so it is not processed later as a record
+	$$textref =~ s/^\<Workform Definition\>(.*)\n//;
+	my $workform_definition = $1;
+	# Parse the workform definitions and store them for later
+	$workform_definition =~ s/^\"([^\"]*)\",//;
+	my $workform_name = $1;
+	my @workform_values;
+	while ($workform_definition !~ /^\s*$/) {
+	    $workform_definition =~ s/^\"([^\"]*)\",?//;
+	    my $workform_field = $1;
+	    push(@workform_values, $workform_field);
+	}
+	
+	# Remember this workform definition for when we're reading the records
+	$workform_definitions{$workform_name} = \@workform_values;
+    }
+
+    $self->{'workform_definitions'}->{$filename} = \%workform_definitions;
+}
+
+
+sub process
+{
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+    my $filename = &util::filename_cat($base_dir, $file);
+    my $cursection = $doc_obj->get_top_section();
+
+    # Build up an HTML view of the record for easy display at run-time
+    my $html_record = "<table>";
+
+    # Read the record's workform indicator and record number
+    #$$textref =~ s/^\"([^\"]*)\",\"([^\"]*)\",//;
+    $$textref =~  s/^\"([^\"]*)\",//;
+    my $workform_indicator = $1;
+
+    # some procite files have a record number next
+    
+    my $recordnum = $$textref =~ s/^\"(\d*)\",//;
+    $recordnum = "undefined" unless defined $recordnum;
+
+    # If necessary, map the workform indicator into something useful
+    if ($crazy_workform_mapping{$workform_indicator}) {
+	$workform_indicator = $crazy_workform_mapping{$workform_indicator};
+    }
+
+    # Check we know about the workform of this record
+    my %workform_definitions = %{$self->{'workform_definitions'}->{$filename}};
+    if (!$workform_definitions{$workform_indicator}) {
+	print STDERR "Unknown workform $workform_indicator!\n";
+	return 0;
+    }
+
+    # Store the full record as the document text
+    $doc_obj->add_utf8_text($cursection, $$textref);
+
+    # Store workform and record number as metadata
+    $doc_obj->add_utf8_metadata($cursection, "Workform", $workform_indicator);
+    $doc_obj->add_utf8_metadata($cursection, "RecordNumber", $recordnum);
+    
+    # Store FileFormat metadata
+    $doc_obj->add_metadata($cursection, "FileFormat", "ProCite");
+
+    $html_record .= "<tr><td valign=top><b>Record Number: </b></td><td valign=top>$recordnum</td></tr>";
+
+    my @workform_values = @{$workform_definitions{$workform_indicator}};
+
+    # Read each field (surrounded by quotes) of the record
+    my $fieldnum = 0;
+    while ($$textref !~ /^\s*$/) {
+	$$textref =~ s/^\"([^\"]*)\",?//;
+	my $field_value_raw = $1;
+
+	# Add non-empty metadata values to the document
+	unless ($field_value_raw eq "") {
+	    # Add the display name of the metadata field for format statement convenience
+	    my $field_name = $workform_values[$fieldnum];
+	    #unless ($field_name eq "---") {
+	#	my $meta_name = "Field" . ($fieldnum + 1) . "Name";
+	#	$doc_obj->add_utf8_metadata($cursection, $meta_name, $field_name);
+	 #   }
+	    if ($field_name eq "---") {
+		$field_name = "Field" . ($fieldnum + 1);
+	    }
+	    $html_record .= "<tr><td valign=top><b>$field_name: </b></td><td valign=top>";
+
+	    # Multiple metadata values are separated with "//"
+	    #foreach my $field_value (split(/\/\//, $field_value_raw)) {
+	    foreach my $field_value (split($self->{'entry_separator'}, $field_value_raw)) {
+		#my $meta_name = "Field" . ($fieldnum + 1) . "Value";
+		#$doc_obj->add_utf8_metadata($cursection, $meta_name, $field_value);
+		$doc_obj->add_utf8_metadata($cursection, $field_name, $field_value);
+		$html_record .= $field_value . "<br>";
+	    }
+
+	    $html_record .= "</td></tr>";
+	}
+
+	$fieldnum++;
+    }
+
+    $html_record .= "</table>";
+    # Store HTML view of record as metadata
+    $doc_obj->add_utf8_metadata($cursection, "HTMLDisplay", $html_record);
+
+    # Record was processed successfully
+    return 1;
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/RTFPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/RTFPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/RTFPlugin.pm	(revision 20131)
@@ -0,0 +1,105 @@
+###########################################################################
+#
+# RTFPlugin.pm -- plugin for importing Rich Text Format files.
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package RTFPlugin;
+
+use ConvertBinaryFile;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @RTFPlugin::ISA = ('ConvertBinaryFile');
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" },
+      { 'name' => "description_tags",
+	'desc' => "{HTMLPlugin.description_tags}",
+	'type' => "flag" }
+];
+
+my $options = { 'name'     => "RTFPlugin",
+		'desc'     => "{RTFPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'srcreplaceable' => "yes", # Source docs in rtf can be replaced with GS-generated html
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+ 
+    my $self = new ConvertBinaryFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    $self->{'filename_extension'} = "rtf";
+    $self->{'file_type'} = "RTF";
+
+    my $secondary_plugin_options = $self->{'secondary_plugin_options'};
+    if (!defined $secondary_plugin_options->{'TextPlugin'}) {
+	$secondary_plugin_options->{'TextPlugin'} = [];
+    }
+    if (!defined $secondary_plugin_options->{'HTMLPlugin'}) {
+	$secondary_plugin_options->{'HTMLPlugin'} = [];
+    }
+    my $text_options = $secondary_plugin_options->{'TextPlugin'};
+    my $html_options = $secondary_plugin_options->{'HTMLPlugin'};
+    
+    #$self->{'input_encoding'} = "utf8";
+    #$self->{'extract_language'} = 1;
+    push(@$text_options, "-input_encoding", "utf8");
+    push(@$text_options,"-extract_language") if $self->{'extract_language'};
+    push(@$html_options, "-description_tags") if $self->{'description_tags'};
+    push(@$html_options,"-extract_language") if $self->{'extract_language'};
+
+    push(@$html_options, "-file_rename_method", "none");
+    push(@$text_options, "-file_rename_method", "none");
+
+    $self = bless $self, $class;
+
+    $self->load_secondary_plugins($class,$secondary_plugin_options, $hashArgOptLists);
+
+    return $self;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+    return q^(?i)\.rtf$^;
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/ReadTextFile.pm
===================================================================
--- /gsdl/stable/perllib/plugins/ReadTextFile.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/ReadTextFile.pm	(revision 20131)
@@ -0,0 +1,518 @@
+###########################################################################
+#
+# ReadTxtFile.pm -- base class for import plugins that have plain text files
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2005 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package ReadTextFile;
+
+use strict; 
+no strict 'subs';
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+
+use multiread;
+use encodings;
+use unicode;
+use textcat;
+use doc;
+use ghtml;
+use gsprintf 'gsprintf';
+
+use AutoExtractMetadata;
+
+sub BEGIN {
+    @ReadTextFile::ISA = ( 'AutoExtractMetadata' );
+}
+
+my $encoding_plus_auto_list = 
+    [ { 'name' => "auto",
+	'desc' => "{ReadTextFile.input_encoding.auto}" } ];
+push(@{$encoding_plus_auto_list},@{$BasePlugin::encoding_list});
+
+my $arguments =
+    [ { 'name' => "input_encoding",
+	'desc' => "{ReadTextFile.input_encoding}",
+	'type' => "enum",
+	'list' => $encoding_plus_auto_list,
+	'reqd' => "no" ,
+	'deft' => "auto" } ,
+      { 'name' => "default_encoding",
+	'desc' => "{ReadTextFile.default_encoding}",
+	'type' => "enum",
+	'list' => $BasePlugin::encoding_list,
+	'reqd' => "no",
+        'deft' => "utf8" },
+      { 'name' => "extract_language",
+	'desc' => "{ReadTextFile.extract_language}",
+	'type' => "flag",
+	'reqd' => "no" },
+      { 'name' => "default_language",
+	'desc' => "{ReadTextFile.default_language}",
+	'type' => "string",
+	'deft' => "en",
+	'reqd' => "no" }
+      ];
+
+
+my $options = { 'name'     => "ReadTextFile",
+		'desc'     => "{ReadTextFile.desc}",
+		'abstract' => "yes",
+		'inherits' => "no",
+		'args'     => $arguments };
+
+
+
+sub new {
+    my $class = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists, $auxiliary) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new AutoExtractMetadata($pluginlist, $inputargs, $hashArgOptLists, $auxiliary);
+
+    return bless $self, $class;
+    
+}
+
+
+
+# The ReadTextFile read_into_doc_obj() function. This function does all the
+# right things to make general options work for a given plugin.  It reads in
+# a file and sets up a slew of metadata all saved in doc_obj, which
+# it then returns as part of a tuple (process_status,doc_obj)
+#
+# Much of this functionality used to reside in read, but it was broken
+# down into a supporting routine to make the code more flexible.  
+#
+# recursive plugins (e.g. RecPlug) and specialized plugins like those
+# capable of processing many documents within a single file (e.g.
+# GMLPlug) will normally want to implement their own version of
+# read_into_doc_obj()
+#
+# Note that $base_dir might be "" and that $file might 
+# include directories
+sub read_into_doc_obj {
+    my $self = shift (@_);  
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+    # should we move this to read? What about secondary plugins?
+    print STDERR "<Processing n='$file' p='$self->{'plugin_type'}'>\n" if ($gli);
+    print $outhandle "$self->{'plugin_type'} processing $file\n"
+	    if $self->{'verbosity'} > 1;
+
+    my ($filename_full_path, $filename_no_path) =  &util::get_full_filenames($base_dir, $file);
+
+    # Do encoding stuff
+    my ($language, $encoding) = $self->textcat_get_language_encoding ($filename_full_path);
+    if ($self->{'verbosity'} > 2) {
+	print $outhandle "ReadTextFile: reading $file as ($encoding,$language)\n";
+    }
+
+    # create a new document
+    my $doc_obj = new doc ($filename_full_path, "indexed_doc", $self->{'file_rename_method'});
+    my $top_section = $doc_obj->get_top_section();
+
+    # this should look at the plugin option too...
+    $doc_obj->add_utf8_metadata($top_section, "Plugin", "$self->{'plugin_type'}");
+    $doc_obj->add_utf8_metadata($top_section, "FileSize", (-s $filename_full_path));
+    $self->set_Source_metadata($doc_obj, $filename_no_path, $encoding);
+
+    $doc_obj->add_utf8_metadata($top_section, "Language", $language);
+    $doc_obj->add_utf8_metadata($top_section, "Encoding", $encoding);
+    
+    # read in file ($text will be in utf8)
+    my $text = "";
+    $self->read_file ($filename_full_path, $encoding, $language, \$text);
+
+    if (!length ($text)) {
+	if ($gli) {
+	    print STDERR "<ProcessingError n='$file' r='File contains no text'>\n";
+	}
+	gsprintf($outhandle, "$self->{'plugin_type'}: {ReadTextFile.file_has_no_text}\n", $filename_full_path) if $self->{'verbosity'};
+
+	my $failhandle = $self->{'failhandle'};
+	gsprintf($failhandle, "$file: " . ref($self) . ": {ReadTextFile.empty_file}\n");
+	# print $failhandle "$file: " . ref($self) . ": file contains no text\n";
+	$self->{'num_not_processed'} ++;
+
+	return (0,undef); # what should we return here?? error but don't want to pass it on
+    }
+   
+    # do plugin specific processing of doc_obj
+    unless (defined ($self->process (\$text, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli))) {
+	$text = '';
+	undef $text;
+	print STDERR "<ProcessingError n='$file'>\n" if ($gli);
+	return (-1,undef);
+    }
+    $text='';
+    undef $text;
+   
+    # include any metadata passed in from previous plugins 
+    # note that this metadata is associated with the top level section
+    $self->add_associated_files($doc_obj, $filename_full_path);
+    $self->extra_metadata ($doc_obj, $top_section, $metadata);
+
+     # do any automatic metadata extraction
+    $self->auto_extract_metadata ($doc_obj);
+
+
+    # if we haven't found any Title so far, assign one
+    $self->title_fallback($doc_obj,$top_section,$filename_no_path);
+
+    $self->add_OID($doc_obj);
+    
+    return (1,$doc_obj);
+}
+
+# uses the multiread package to read in the entire file pointed to
+# by filename and loads the resulting text into $$textref. Input text
+# may be in any of the encodings handled by multiread, output text
+# will be in utf8
+sub read_file {
+    my $self = shift (@_);
+    my ($filename, $encoding, $language, $textref) = @_;
+
+    if (!-r $filename)
+    {
+	my $outhandle = $self->{'outhandle'};
+	gsprintf($outhandle, "{ReadTextFile.read_denied}\n", $filename) if $self->{'verbosity'};
+	# print $outhandle "Read permission denied for $filename\n" if $self->{'verbosity'};
+	return;
+    }
+    $$textref = "";
+    if (!open (FILE, $filename)) {
+	gsprintf(STDERR, "ReadTextFile::read_file {ReadTextFile.could_not_open_for_reading} ($!)\n", $filename);
+	die "\n";
+    }
+     
+    if ($encoding eq "ascii") {
+	undef $/;
+	$$textref = <FILE>;
+	$/ = "\n";
+    } else {
+	my $reader = new multiread();
+	$reader->set_handle ('ReadTextFile::FILE');
+	$reader->set_encoding ($encoding);
+	$reader->read_file ($textref);
+    }
+    close FILE;
+}
+
+
+sub read_file_no_decoding {
+    my $self = shift (@_);
+    my ($filename, $textref) = @_;
+
+    if (!-r $filename)
+    {
+	my $outhandle = $self->{'outhandle'};
+	gsprintf($outhandle, "{ReadTextFile.read_denied}\n", $filename) if $self->{'verbosity'};
+	# print $outhandle "Read permission denied for $filename\n" if $self->{'verbosity'};
+	return;
+    }
+    $$textref = "";
+    if (!open (FILE, $filename)) {
+	gsprintf(STDERR, "ReadTextFile::read_file {ReadTextFile.could_not_open_for_reading} ($!)\n", $filename);
+	die "\n";
+    }
+     
+    my $reader = new multiread();
+    $reader->set_handle ('ReadTextFile::FILE');
+    $reader->read_file_no_decoding ($textref);
+    
+    $self->{'reader'} = $reader;
+
+    close FILE;
+}
+
+
+sub decode_text {
+    my $self = shift (@_);
+    my ($raw_text, $encoding, $language, $textref) = @_;
+
+    my $reader = $self->{'reader'};
+    if (!defined $reader) {
+	gsprintf(STDERR, "ReadTextFile::decode_text needs to call ReadTextFile::read_file_no_decoding first\n");
+    }
+    else {
+	$reader->set_encoding($encoding);
+	$reader->decode_text($raw_text,$textref);
+    }
+}
+
+
+sub textcat_get_language_encoding {
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    my ($language, $encoding, $extracted_encoding);
+    if ($self->{'input_encoding'} eq "auto") {
+        # use textcat to automatically work out the input encoding and language
+        ($language, $encoding) = $self->get_language_encoding ($filename);
+    } elsif ($self->{'extract_language'}) {
+	# use textcat to get language metadata
+        ($language, $extracted_encoding) = $self->get_language_encoding ($filename);
+        $encoding = $self->{'input_encoding'};
+	# don't print this message for english... english in utf8 is identical
+	# to english in iso-8859-1 (except for some punctuation). We don't have
+	# a language model for en_utf8, so textcat always says iso-8859-1!
+        if ($extracted_encoding ne $encoding && $language ne "en" && $self->{'verbosity'}) {
+	    my $plugin_name = ref ($self);
+	    my $outhandle = $self->{'outhandle'};
+	    gsprintf($outhandle, "$plugin_name: {ReadTextFile.wrong_encoding}\n", $filename, $encoding, $extracted_encoding);
+        }
+    } else {
+        $language = $self->{'default_language'};
+        $encoding = $self->{'input_encoding'}; 
+    }
+    
+#    print STDERR "**** language encoding of contents of file $filename:\n\t****$language $encoding\n";
+
+    return ($language, $encoding);
+}
+
+
+# Uses textcat to work out the encoding and language of the text in 
+# $filename. All html tags are removed before processing.
+# returns an array containing "language" and "encoding"
+sub get_language_encoding {
+    my $self = shift (@_);
+    my ($filename) = @_;
+    my $outhandle = $self->{'outhandle'};
+    my $unicode_format = "";
+    my $best_language = "";
+    my $best_encoding = "";
+    
+
+    # read in file
+    if (!open (FILE, $filename)) {
+	gsprintf(STDERR, "ReadTextFile::get_language_encoding {ReadTextFile.could_not_open_for_reading} ($!)\n", $filename);
+	# this is a pretty bad error, but try to continue anyway
+	return ($self->{'default_language'}, $self->{'input_encoding'});
+    }
+    undef $/;
+    my $text = <FILE>;
+    $/ = "\n";
+    close FILE;
+
+    # check if first few bytes have a Byte Order Marker
+    my $bom=substr($text,0,2); # check 16bit unicode
+    if ($bom eq "\xff\xfe") { # little endian 16bit unicode
+	$unicode_format="unicode";
+    } elsif ($bom eq "\xfe\xff") { # big endian 16bit unicode
+	$unicode_format="unicode";
+    } else {
+	$bom=substr($text,0,3); # check utf-8
+	if ($bom eq "\xef\xbb\xbf") { # utf-8 coded FEFF bom
+	    $unicode_format="utf8";
+#	} elsif ($bom eq "\xef\xbf\xbe") { # utf-8 coded FFFE bom. Error!?
+#	    $unicode_format="utf8";
+	}
+    }
+    
+    my $found_html_encoding = 0;
+    # handle html files specially
+    # XXX this doesn't match plugins derived from HTMLPlug (except ConvertTo)
+    if (ref($self) eq 'HTMLPlugin' ||
+	(exists $self->{'converted_to'} && $self->{'converted_to'} eq 'HTML')){
+
+	# remove comments in head, including multiline ones, so that we don't match on 
+	# inactive tags (those that are nested inside comments)
+	my ($head) = ($text =~ m/<head>(.*)<\/head>/si);
+	$head = "" unless defined $head; # some files are not proper HTML eg php files
+	$head =~ s/<!--.*?-->//sg;
+
+	# remove <title>stuff</title> -- as titles tend often to be in English
+	# for foreign language documents
+	$text =~ s!<title>.*?</title>!!si;
+
+	# see if this html file specifies its encoding
+	if ($text =~ /^<\?xml.*encoding="(.+?)"/) {
+	    $best_encoding = $1;
+	}
+	# check the meta http-equiv charset tag
+	elsif ($head =~ m/<meta http-equiv.*content-type.*charset=(.+?)\"/si) {		       
+	    $best_encoding = $1;
+	}
+	if ($best_encoding) { # we extracted an encoding
+	    $best_encoding =~ s/-+/_/g;
+	    $best_encoding = lc($best_encoding); # lowercase
+	    if ($best_encoding eq "utf_8") { $best_encoding = "utf8" }
+	    $found_html_encoding = 1;
+	    # We shouldn't be modifying this here!!
+	    #$self->{'input_encoding'} = $best_encoding;
+	}
+        
+	# remove all HTML tags
+	$text =~ s/<[^>]*>//sg;
+    }
+
+    # don't need to do textcat if we know the encoding now AND don't need to extract language
+    if($found_html_encoding && !$self->{'extract_language'}) { # encoding specified in html file
+	$best_language = $self->{'default_language'};
+    }
+
+    else { # need to use textcat to get either the language, or get both language and encoding
+	$self->{'textcat'} = new textcat() if (!defined($self->{'textcat'}));
+	
+	if($found_html_encoding) { # know encoding, find language by limiting search to known encoding
+	    my $results = $self->{'textcat'}->classify_contents_for_encoding(\$text, $filename, $best_encoding);
+	    
+	    my $language;
+	    ($language) = $results->[0] =~ m/^([^-]*)(?:-(?:.*))?$/ if (scalar @$results > 0);
+
+	    if (!defined $language || scalar @$results > 3) {
+		# if there were too many results even when restricting results by encoding,
+		# or if there were no results, use default language with the known encoding
+		$best_language = $self->use_default_language($filename);
+	    } 
+	    else { # fewer than 3 results means textcat is more certain, use the first result
+		$best_language = $language;		
+	    } 
+	}
+	else { # don't know encoding or language yet, therefore we use textcat
+	    my $results = $self->{'textcat'}->classify_contents(\$text, $filename);
+	    
+	    # if textcat returns 3 or less possibilities we'll use the first one in the list
+	    if (scalar @$results <= 3) { # results will be > 0 when we don't constrain textcat by an encoding
+		my ($language, $encoding) = $results->[0] =~ m/^([^-]*)(?:-(.*))?$/;
+
+		$language = $self->use_default_language($filename) unless defined $language;
+		$encoding = $self->use_default_encoding($filename) unless defined $encoding;
+
+		$best_language = $language;
+		$best_encoding = $encoding;
+	    }
+	    else { # if (scalar @$results > 3) {
+		if ($unicode_format) { # in case the first had a BOM
+		    $best_encoding=$unicode_format;
+		}
+		else {
+		    # Find the most frequent encoding in the textcat results returned
+		    # Returns "" if there's no encoding more frequent than another
+		    $best_encoding = $self->{'textcat'}->most_frequent_encoding($results);
+		}
+		
+		if ($best_encoding eq "") { # encoding still not set, use defaults
+		    $best_language = $self->use_default_language($filename);
+		    $best_encoding = $self->use_default_encoding($filename);
+		}
+		elsif (!$self->{'extract_language'}) { # know encoding but don't need to discover language
+		    $best_language = $self->use_default_language($filename);
+		}
+		else { # textcat again using the most frequent encoding or the $unicode_format set above
+		    $results = $self->{'textcat'}->classify_contents_for_encoding(\$text, $filename, $best_encoding);
+		    my $language;
+		    ($language) = $results->[0] =~ m/^([^-]*)(?:-(.*))?$/ if (scalar @$results > 0);
+		    if (!defined $language || scalar @$results > 3) { 
+			# if no result or too many results, use default language for the encoding previously found
+			$best_language = $self->use_default_language($filename);
+		    }
+		    else { # fewer than 3 results, use the language of the first result
+			$best_language = $language;
+		    }
+		}
+	    }
+	}
+    }
+
+    if($best_encoding eq "" || $best_language eq "") {
+	print STDERR "****Shouldn't happen: encoding and/or language still not set. Using defaults.\n";
+	$best_encoding = $self->use_default_encoding($filename) if $best_encoding eq "";
+	$best_language = $self->use_default_language($filename) if $best_language eq "";
+    }
+#    print STDERR "****Content language: $best_language; Encoding: $best_encoding.\n";
+
+
+    if ($best_encoding =~ /^iso_8859/ && &unicode::check_is_utf8($text)) {
+	# the text is valid utf8, so assume that's the real encoding
+	# (since textcat is based on probabilities)
+	$best_encoding = 'utf8';
+    }
+
+    # check for equivalents where textcat doesn't have some encodings...
+    # eg MS versions of standard encodings
+    if ($best_encoding =~ /^iso_8859_(\d+)/) {
+	my $iso = $1; # which variant of the iso standard?
+	# iso-8859 sets don't use chars 0x80-0x9f, windows codepages do
+	if ($text =~ /[\x80-\x9f]/) {
+	    # Western Europe
+	    if ($iso == 1 or $iso == 15) { $best_encoding = 'windows_1252' }
+	    elsif ($iso == 2) {$best_encoding = 'windows_1250'} # Central Europe
+	    elsif ($iso == 5) {$best_encoding = 'windows_1251'} # Cyrillic
+	    elsif ($iso == 6) {$best_encoding = 'windows_1256'} # Arabic
+	    elsif ($iso == 7) {$best_encoding = 'windows_1253'} # Greek
+	    elsif ($iso == 8) {$best_encoding = 'windows_1255'} # Hebrew
+	    elsif ($iso == 9) {$best_encoding = 'windows_1254'} # Turkish
+	}
+    }
+
+    if ($best_encoding !~ /^(ascii|utf8|unicode)$/ &&
+	!defined $encodings::encodings->{$best_encoding}) {
+	if ($self->{'verbosity'}) {
+	    gsprintf($outhandle, "ReadTextFile: {ReadTextFile.unsupported_encoding}\n",
+		     $filename, $best_encoding, $self->{'default_encoding'});
+	}
+	$best_encoding = $self->{'default_encoding'};
+    }
+
+    return ($best_language, $best_encoding);
+}
+
+
+sub use_default_language {
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    if ($self->{'verbosity'}>2) {
+	gsprintf($self->{'outhandle'},
+		 "ReadTextFile: {ReadTextFile.could_not_extract_language}\n",
+		 $filename, $self->{'default_language'});
+    }
+    return $self->{'default_language'};
+}
+
+sub use_default_encoding {
+    my $self = shift (@_);
+    my ($filename) = @_;
+
+    if ($self->{'verbosity'}>2) {
+	gsprintf($self->{'outhandle'},
+		 "ReadTextFile: {ReadTextFile.could_not_extract_encoding}\n",
+		 $filename, $self->{'default_encoding'});
+    }
+    return $self->{'default_encoding'};
+}
+
+# Overridden by exploding plugins (eg. ISISPlug)
+sub clean_up_after_exploding
+{
+    my $self = shift(@_);
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/ReadXMLFile.pm
===================================================================
--- /gsdl/stable/perllib/plugins/ReadXMLFile.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/ReadXMLFile.pm	(revision 20131)
@@ -0,0 +1,409 @@
+###########################################################################
+#
+# ReadXMLFile.pm -- base class for XML plugins
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package ReadXMLFile;
+
+use BasePlugin;
+use doc;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @ReadXMLFile::ISA = ('BasePlugin');
+    unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
+}
+
+use XMLParser;
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" },
+      { 'name' => "xslt",
+	'desc' => "{ReadXMLFile.xslt}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "ReadXMLFile",
+		'desc'     => "{ReadXMLFile.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+    
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about creating the XML parser as all we want is the 
+	# list of plugin options
+	return bless $self, $class;
+    }
+
+    my $parser = new XML::Parser('Style' => 'Stream',
+                                 'Pkg' => 'ReadXMLFile',
+                                 'PluginObj' => $self,
+				 'Handlers' => {'Char' => \&Char,
+						'XMLDecl' => \&XMLDecl,
+						'Entity'  => \&Entity,
+						'Doctype' => \&Doctype,
+						'Default' => \&Default
+                                 });
+
+    $self->{'parser'} = $parser;
+
+    return bless $self, $class;
+}
+
+# the inheriting class must implement this method to tell whether to parse this doc type
+sub get_doctype {
+    my $self = shift(@_);
+    die "$self The inheriting class must implement get_doctype method";
+}
+
+
+sub apply_xslt
+{
+    my $self = shift @_;
+    my ($xslt,$filename) = @_;
+    
+    my $outhandle = $self->{'outhandle'};
+
+    my $xslt_filename = $xslt;
+
+    if (! -e $xslt_filename) {
+	# Look in main site directory
+	my $gsdlhome = $ENV{'GSDLHOME'};
+	$xslt_filename = &util::filename_cat($gsdlhome,$xslt);
+    }
+
+    if (! -e $xslt_filename) {
+	# Look in collection directory
+	my $coldir = $ENV{'GSDLCOLLECTDIR'};
+	$xslt_filename = &util::filename_cat($coldir,$xslt);
+    }
+
+    if (! -e $xslt_filename) {
+	print $outhandle "Warning: Unable to find XSLT $xslt\n";
+	if (open(XMLIN,"<$filename")) {
+
+	    my $untransformed_xml = "";
+	    while (defined (my $line = <XMLIN>)) {
+
+		$untransformed_xml .= $line;
+	    }
+	    close(XMLIN);
+	    
+	    return $untransformed_xml;
+	}
+	else {
+	    print $outhandle "Error: Unable to open file $filename\n";
+	    print $outhandle "       $!\n";
+	    return "";
+	}
+	
+    }
+
+    my $bin_java = &util::filename_cat($ENV{'GSDLHOME'},"bin","java");
+    my $jar_filename = &util::filename_cat($bin_java,"xalan.jar");
+    my $xslt_base_cmd = "java -jar $jar_filename";
+    my $xslt_cmd = "$xslt_base_cmd -IN \"$filename\" -XSL \"$xslt_filename\"";
+
+    my $transformed_xml = "";
+
+    if (open(XSLT_IN,"$xslt_cmd |")) {
+	while (defined (my $line = <XSLT_IN>)) {
+
+	    $transformed_xml .= $line;
+	}
+	close(XSLT_IN);
+    }
+    else {
+	print $outhandle "Error: Unable to run command $xslt_cmd\n";
+	print $outhandle "       $!\n";
+    }
+
+    return $transformed_xml;
+
+}
+
+sub can_process_this_file {
+    my $self = shift(@_);
+    my ($filename) = @_;
+
+    if (-f $filename && $self->SUPER::can_process_this_file($filename) && $self->check_doctype($filename)) {
+	return 1; # its a file for us
+    }
+    return 0;
+}
+
+sub check_doctype {
+    my $self = shift (@_);
+    
+    my ($filename) = @_;
+
+    if (open(XMLIN,"<$filename")) {
+	my $doctype = $self->get_doctype();
+	## check whether the doctype has the same name as the root element tag
+	while (defined (my $line = <XMLIN>)) {
+	    ## find the root element
+	    if ($line =~ /<([\w\d:]+)[\s>]/){
+		my $root = $1;
+		if ($root !~ $doctype){
+		    close(XMLIN);
+		    return 0;
+		}
+		else {
+		    close(XMLIN); 
+		    return 1;
+		}
+	    }
+	}
+	close(XMLIN);
+    }
+    
+    return undef; # haven't found a valid line
+    
+}
+
+sub read {
+    my $self = shift (@_);  
+  
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+
+    # can we process this file??
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+    
+    $file =~ s/^[\/\\]+//; # $file often begins with / so we'll tidy it up
+    $self->{'base_dir'} = $base_dir;
+    $self->{'file'} = $file;
+    $self->{'filename'} = $filename_full_path;
+    $self->{'processor'} = $processor;
+    # this contains metadata passed in from running metadata_read with other plugins (eg from MetadataXMLPlugin)
+    # we are also using it to store up any metadata found during parsing the XML, so that it can be added to the doc obj.
+    $self->{'metadata'} = $metadata;
+
+    if ($self->parse_file($filename_full_path)) {
+	return 1; # processed the file
+    }
+    return -1;
+}
+
+
+sub parse_file {
+    my $self = shift (@_);
+    my ($filename_full_path, $file, $gli) = @_;
+    eval {
+	my $xslt = $self->{'xslt'};
+	if (defined $xslt && ($xslt ne "")) {
+	    # perform xslt
+	    my $transformed_xml = $self->apply_xslt($xslt,$filename_full_path);
+
+	    # feed transformed file (now in memory as string) into XML parser
+	    $self->{'parser'}->parse($transformed_xml);
+	}
+	else {
+	    $self->{'parser'}->parsefile($filename_full_path);
+	}
+    };
+  
+    if ($@) {
+
+	# parsefile may either croak somewhere in XML::Parser (e.g. because
+	# the document is not well formed) or die somewhere in ReadXMLFile or a
+	# derived plugin (e.g. because we're attempting to process a
+	# document whose DOCTYPE is not meant for this plugin). For the
+	# first case we'll print a warning and continue, for the second
+	# we'll just continue quietly
+
+	print STDERR "**** Error is: $@\n";
+
+	my ($msg) = $@ =~ /Carp::croak\(\'(.*?)\'\)/;
+	if (defined $msg) {	
+	    my $outhandle = $self->{'outhandle'};
+	    my $plugin_name = ref ($self);
+	    print $outhandle "$plugin_name failed to process $file ($msg)\n";
+	}
+
+	# reset ourself for the next document
+	$self->{'section_level'}=0;
+	print STDERR "<ProcessingError n='$file'>\n" if ($gli);
+	return -1; # error during processing
+    }
+    return 1; # parsing was successful
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.xml$^;
+}
+
+sub StartDocument {$_[0]->{'PluginObj'}->xml_start_document(@_);}
+sub XMLDecl {$_[0]->{'PluginObj'}->xml_xmldecl(@_);}
+sub Entity {$_[0]->{'PluginObj'}->xml_entity(@_);}
+sub Doctype {$_[0]->{'PluginObj'}->xml_doctype(@_);}
+sub StartTag {$_[0]->{'PluginObj'}->xml_start_tag(@_);}
+sub EndTag {$_[0]->{'PluginObj'}->xml_end_tag(@_);}
+sub Text {$_[0]->{'PluginObj'}->xml_text(@_);}
+sub PI {$_[0]->{'PluginObj'}->xml_pi(@_);}
+sub EndDocument {$_[0]->{'PluginObj'}->xml_end_document(@_);}
+sub Default {$_[0]->{'PluginObj'}->xml_default(@_);}
+
+# This Char function overrides the one in XML::Parser::Stream to overcome a
+# problem where $expat->{Text} is treated as the return value, slowing
+# things down significantly in some cases.
+sub Char {
+    use bytes;  # Necessary to prevent encoding issues with XML::Parser 2.31+
+    $_[0]->{'Text'} .= $_[1];
+    return undef;
+}
+
+
+# Called at the beginning of the XML document.
+sub xml_start_document {
+    my $self = shift(@_);
+    my ($expat) = @_;
+
+    $self->open_document();
+}
+
+# Called for XML declarations
+sub xml_xmldecl {
+    my $self = shift(@_);
+    my ($expat, $version, $encoding, $standalone) = @_;
+}
+
+# Called for XML entities
+sub xml_entity {
+  my $self = shift(@_);
+  my ($expat, $name, $val, $sysid, $pubid, $ndata) = @_;
+}
+
+# Called for DOCTYPE declarations - use die to bail out if this doctype
+# is not meant for this plugin
+sub xml_doctype {
+    my $self = shift(@_);
+
+    my ($expat, $name, $sysid, $pubid, $internal) = @_;
+    die "ReadXMLFile Cannot process XML document with DOCTYPE of $name";
+}
+
+
+# Called for every start tag. The $_ variable will contain a copy of the
+# tag and the %_ variable will contain the element's attributes.
+sub xml_start_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+}
+
+# Called for every end tag. The $_ variable will contain a copy of the tag.
+sub xml_end_tag {
+    my $self = shift(@_);
+    my ($expat, $element) = @_;
+}
+
+# Called just before start or end tags with accumulated non-markup text in
+# the $_ variable.
+sub xml_text {
+    my $self = shift(@_);
+    my ($expat) = @_;
+}
+
+# Called for processing instructions. The $_ variable will contain a copy
+# of the pi.
+sub xml_pi {
+    my $self = shift(@_);
+    my ($expat, $target, $data) = @_;
+}
+
+# Called at the end of the XML document.
+sub xml_end_document {
+    my $self = shift(@_);
+    my ($expat) = @_;
+
+    $self->close_document();
+}
+
+# Called for any characters not handled by the above functions.
+sub xml_default {
+    my $self = shift(@_);
+    my ($expat, $text) = @_;
+}
+
+sub open_document {
+    my $self = shift(@_);
+
+    # create a new document
+    $self->{'doc_obj'} = new doc ($self->{'filename'}, "indexed_doc", $self->{'file_rename_method'});
+    $self->{'doc_obj'}->add_utf8_metadata($self->{'doc_obj'}->get_top_section(), "Plugin", "$self->{'plugin_type'}");
+
+    # do we want other auto metadata here (see BasePlugin.read_into_doc_obj)
+}
+
+sub close_document {
+    my $self = shift(@_);
+    my $doc_obj = $self->{'doc_obj'};
+
+    # do we want other auto stuff here, see BasePlugin.read_into_doc_obj
+
+    # include any metadata passed in from previous plugins 
+    # note that this metadata is associated with the top level section
+    $self->extra_metadata ($doc_obj, 
+			   $doc_obj->get_top_section(), 
+			   $self->{'metadata'});
+   
+    # do any automatic metadata extraction
+    $self->auto_extract_metadata ($doc_obj);
+   
+    # add an OID
+    $self->add_OID($doc_obj);
+    
+    $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");
+    $doc_obj->add_metadata($doc_obj->get_top_section(), "FileFormat", "XML");
+
+    # process the document
+    $self->{'processor'}->process($doc_obj);
+    
+    $self->{'num_processed'} ++;
+    undef $self->{'doc_obj'};
+    undef $doc_obj; # is this the same as above??
+}
+
+1;
+
+
+
+
Index: /gsdl/stable/perllib/plugins/RealMediaPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/RealMediaPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/RealMediaPlugin.pm	(revision 20131)
@@ -0,0 +1,122 @@
+###########################################################################
+#
+# RealMediaPlugin.pm -- Extract metadata from Real Media files
+#
+# Original code by Xin Gao
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2005 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package RealMediaPlugin;
+
+
+use BasePlugin;
+use rm::Header::PurePerl;
+
+use strict;
+no strict 'refs'; # make an exception so we can use variables as filehandles
+no strict 'subs';
+
+sub BEGIN {
+    @RealMediaPlugin::ISA = ('BasePlugin');
+}
+
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "RealMediaPlugin",
+		'desc'     => "{RealMediaPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+# This plugin processes Real Media files with the suffixes ".rm" and ".rmvb"
+sub get_default_process_exp
+{
+    return q^(?i)(\.rm|rmvb)$^;
+}
+
+
+sub new
+{
+    my ($class) = shift(@_);
+    my ($pluginlist, $inputargs, $hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}}, @{$arguments}); 
+    push(@{$hashArgOptLists->{"OptList"}}, $options); 
+
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+    
+    return bless $self, $class;
+}
+
+# we don't want to hash on the file
+sub get_oid_hash_type {
+    my $self = shift (@_);
+    return "hash_on_ga_xml";
+}
+
+sub process
+{
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    my $top_section = $doc_obj->get_top_section();
+
+    my $text = "";
+    my $real_media = rm::Header::PurePerl->new($filename_full_path);
+    if (!defined $real_media || !defined $real_media->info) {
+	my $outhandle = $self->{'outhandle'};
+	print $outhandle "RealMediaPlugin: $filename_no_path is not a real media file\n";
+	return undef;
+    }
+    foreach my $key (keys %{$real_media->info})
+    {
+	my $value = $real_media->info->{$key};
+	$doc_obj->add_metadata($top_section, $key, $value);
+	$text .= "$key: $value\n";
+    }
+    
+    $doc_obj->add_utf8_text($top_section, "<pre>\n$text\n</pre>");
+    $doc_obj->add_metadata($top_section, "FileFormat", "RealMedia");
+
+    $doc_obj->add_metadata($top_section, "srclink", "<a href=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[SourceFile]\">");
+    $doc_obj->add_metadata($top_section, "/srclink", "</a>");
+    # srcicon (need to include "irmvideo.gif" in the greenstone images directory
+    $doc_obj->add_metadata($top_section, "srcicon", "<img src=\"_httpprefix_/images/irmvideo.gif\" title=\"Download\" border=0>");
+
+    # Add the actual filename as it exists on the file system (URL-encoded) as an 
+    # associated file by making sure we undo any escaped URL-encoding there may be
+    my $assoc_file = $doc_obj->get_assocfile_from_sourcefile(); # just url-encoded filename, no path
+    $doc_obj->associate_file($filename_full_path, $assoc_file, "RealMedia", $top_section);
+
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/ReferPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/ReferPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/ReferPlugin.pm	(revision 20131)
@@ -0,0 +1,308 @@
+###########################################################################
+#
+# ReferPlugin.pm - a plugin for bibliography records in Refer format
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright 2000 Gordon W. Paynter
+# Copyright 1999-2000 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# ReferPlugin reads bibliography files in Refer format.
+#
+# by Gordon W. Paynter (gwp@cs.waikato.ac.nz), November 2000
+#
+# Loosely based on hcibib2Plug by Steve Jones (stevej@cs.waikato.ac.nz).
+# Which was based on EMAILPlug by Gordon Paynter (gwp@cs.waikato.ac.nz).
+# Which was based on old versions of HTMLplug and HCIBIBPlugby by Stefan
+# Boddie and others -- it's hard to tell what came from where, now.
+#
+#
+# ReferPlugin creates a document object for every reference in the file.
+# It is a subclass of SplitTextFile, so if there are multiple records, all
+# are read.
+#
+# Document text:
+#   The document text consists of the reference in Refer format
+#
+# Metadata:
+#	$Creator	%A	Author name
+#	$Title		%T	Title of article of book
+#	$Journal	%J	Title of Journal
+#	$Booktitle	%B	Title of book containing the publication
+#	$Report		%R	Type of Report, paper or thesis
+#	$Volume		%V	Volume Number of Journal
+#	$Number		%N	Number of Journal within Volume
+#	$Editor		%E	Editor name
+#	$Pages		%P	Page Number of article
+#	$Publisher	%I	Name of Publisher
+#	$Publisheraddr	%C	Publisher's address
+#	$Date		%D	Date of publication
+#	$Keywords	%K	Keywords associated with publication 
+#	$Abstract	%X	Abstract of publication
+#	$Copyright	%*	Copyright information for the article
+#
+
+package ReferPlugin;
+
+use SplitTextFile;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+# ReferPlugin is a sub-class of BasePlugin.
+sub BEGIN {
+    @ReferPlugin::ISA = ('SplitTextFile');
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" },
+      { 'name' => "split_exp",
+	'desc' => "{SplitTextFile.split_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_split_exp() } 
+      ];
+
+my $options = { 'name'     => "ReferPlugin",
+		'desc'     => "{ReferPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'explodes' => "yes",
+		'args'     => $arguments };
+
+# This plugin processes files with the suffix ".bib"
+sub get_default_process_exp {
+    return q^(?i)\.bib$^;
+}
+
+# This plugin splits the input text at blank lines
+sub get_default_split_exp {
+    return q^\n\s*\n^;
+}
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new SplitTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+# The process function reads a single bibliographic record and stores
+# it as a new document.
+
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    # Check that we're dealing with a valid Refer file
+    return undef unless ($$textref =~ /^\s*%/);
+
+    my $cursection = $doc_obj->get_top_section();
+
+    my %field = ('H', 'Header',
+		 'A', 'Creator',
+		 'T', 'Title',
+		 'J', 'Journal',
+		 'B', 'Booktitle',
+		 'R', 'Report',
+		 'V', 'Volume',
+		 'N', 'Number',
+		 'E', 'Editor',
+		 'P', 'Pages',
+		 'I', 'Publisher',
+		 'C', 'PublisherAddress',
+		 'D', 'Date',
+		 'O', 'OtherInformation',
+		 'K', 'Keywords',
+		 'X', 'Abstract',
+		 '*', 'Copyright');
+
+    # Metadata fields 
+    my %metadata;
+    my ($id, $Creator, $Keywords, $text);
+    my @lines = split(/\n+/, $$textref);
+
+    
+    # Read and process each line in the bib file.
+    # Each file consists of a set of metadata items, one to each line
+    # with the Refer key followed by a space then the associated data
+    foreach my $line (@lines) {
+	
+	# Add each line.  Most lines consist of a field identifer and
+	# then data, and we simply store them, though we treat some
+	# of the fields a bit differently.
+
+	$line =~ s/\s+/ /g;
+	$text .= "$line\n";
+	# $ReferFormat .= "$line\n"; # what is this???
+	
+	next unless ($line =~ /^%[A-Z\*]/);
+	$id = substr($line,1,1);
+	$line =~ s/^%. //;
+   	
+	# Add individual authors in "Lastname, Firstname" format.
+	# (The full set of authors will be added below as "Creator".)
+	if ($id eq "A") {
+
+	    # Reformat and add author name
+	    my @words = split(/ /, $line);
+	    my $lastname = pop @words;
+	    my $firstname = join(" ",  @words);
+	    my $fullname = $lastname . ", " . $firstname;
+	    
+	    # Add each name to set of Authors
+	    if ($fullname =~ /\w/) {
+		$fullname = &text_into_html($fullname);
+		$doc_obj->add_metadata ($cursection, "Author", $fullname);
+	    }
+	}
+
+	# Add individual keywords.
+	# (The full set of authors will be added below as "Keywords".)
+	if ($id eq "K") {
+	    my @keywordlist = split(/,/, $line);
+	    foreach my $k (@keywordlist) {
+		$k = lc($k);
+		$k =~ s/\s*$//; 
+		$k =~ s/^\s*//; 
+		if ($k =~ /\w/) {
+		    $k = &text_into_html($k);
+		    $doc_obj->add_metadata ($cursection, "Keyword", $k);
+		}
+	    } 
+	}
+	
+	# Add this line of metadata
+	$metadata{$id} .= "$line\n";
+    }
+
+
+
+    # Add the various field as metadata
+    my ($f, $name, $value);
+    foreach $f (keys %metadata) {
+	
+	next unless (defined $field{$f});
+	next unless (defined $metadata{$f});	
+
+	$name = $field{$f};
+	$value = $metadata{$f};
+
+	# Add the various field as metadata	
+	
+	# The Creator metadata is found by concatenating authors.
+	if ($f eq "A") {
+
+	    my @authorlist = split(/\n/, $value);
+	    my $lastauthor = pop @authorlist;
+	    my $Creator = "";
+	    if (scalar @authorlist) {
+		$Creator = join(", ", @authorlist) . " and $lastauthor";
+	    } else {
+		$Creator = $lastauthor;
+	    }
+
+	    if ($Creator =~ /\w/) {
+		$Creator = &text_into_html($Creator);
+		$doc_obj->add_metadata ($cursection, "Creator", $Creator);
+	    }
+	}
+
+	# The rest are added in a standard way
+	else {
+	    $value = &text_into_html($value);
+	    $doc_obj->add_metadata ($cursection, $name, $value);
+	}
+
+	# Books and Journals are additionally marked for display purposes
+	if ($f eq "B") {
+	    $doc_obj->add_metadata($cursection, "BookConfOnly", 1);
+	} elsif ($f eq "J") {
+	    $doc_obj->add_metadata($cursection, "JournalsOnly", 1); 
+	}
+
+
+    }
+
+    # Add the text in refer format(all fields)
+    if ($text =~ /\w/) {
+	$text = &text_into_html($text);
+	$doc_obj->add_text ($cursection, $text);
+    }
+    # Add FileFormat as the metadata
+    $doc_obj->add_metadata($cursection,"FileFormat","Refer");
+
+    return 1; # processed the file
+}
+
+1;
+#
+# Convert a text string into HTML.
+#
+# The HTML is going to be inserted into a GML file, so 
+# we have to be careful not to use symbols like ">",
+# which ocurs frequently in email messages (and use
+# &gt instead.
+#
+# This function also turns links and email addresses into hyperlinks,
+# and replaces carriage returns with <BR> tags (and multiple carriage
+# returns with <P> tags).
+#
+
+sub text_into_html {
+    my ($text) = @_;
+
+
+    # Convert problem charaters into HTML symbols
+    $text =~ s/&/&amp;/g;
+    $text =~ s/</&lt;/g;
+    $text =~ s/>/&gt;/g;
+    $text =~ s/\"/&quot;/g;
+    $text =~ s/\'/ /g;
+    $text =~ s/\+/ /g;
+    $text =~ s/\(/ /g;
+    $text =~ s/\)/ /g;
+
+    # convert email addresses and URLs into links
+    $text =~ s/([\w\d\.\-]+@[\w\d\.\-]+)/<a href=\"mailto:$1\">$1<\/a>/g;
+    $text =~ s/(http:\/\/[\w\d\.\-]+[\/\w\d\.\-]*)/<a href=\"$1">$1<\/a>/g;
+
+    # Clean up whitespace and convert \n charaters to <BR> or <P>
+    $text =~ s/ +/ /g;
+    $text =~ s/\s*$//; 
+    $text =~ s/^\s*//; 
+    $text =~ s/\n/\n<BR>/g;
+    $text =~ s/<BR>\s*<BR>/<P>/g;
+
+    return $text;
+}
+
+
Index: /gsdl/stable/perllib/plugins/RogPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/RogPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/RogPlugin.pm	(revision 20131)
@@ -0,0 +1,282 @@
+###########################################################################
+#
+# RogPlugin.pm -- simple text plugin
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# creates simple single-level document from .rog or .mdb files 
+
+package RogPlugin;
+
+use BasePlugin;
+use sorttools;
+use doc; 
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @RogPlugin::ISA = ('BasePlugin');
+}
+
+my $arguments = 
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'reqd' => "no",
+	'deft' => &get_default_process_exp() },
+      ];
+
+my $options = { 'name'     => "RogPlugin",
+		'desc'     => "{RogPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args' => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+
+# This plugin processes files with the suffix ".mdb" or ".rog"
+sub get_default_process_exp {
+    return q^(?i)\.(mdb|rog)$^;
+}
+
+sub read_rog_record
+{
+    my ($self,$file_buffer, $seclevel) = @_;
+
+    my $next_line = $file_buffer->{'next_line'};
+
+    return 0 if (!defined $next_line);
+
+    if ($next_line eq "")
+    {
+	my $line;
+	while(defined($line=<FILE>))  
+	{
+	    $line =~ s/\r$//;
+	    $file_buffer->{'line_no'}++;
+	    next if ($line =~ m/^\#/);
+	    $next_line = $line;
+	    last;
+	}
+    }
+	    
+    if ($next_line !~ m/^song( +)\"([^\"]*)\"( +)\"([^\"]*)\"( +)(\d+)( *)$/) 
+    {
+	print STDERR "Error: Malformed Rog file: $next_line";
+	return 0;
+    }
+    else
+    {
+	# init default values
+	$file_buffer->{'song'}->{'tempo'}    = 120;
+	$file_buffer->{'song'}->{'ks_type'}  = 0;
+	$file_buffer->{'song'}->{'ks_num'}   = 0;
+	$file_buffer->{'song'}->{'metadata'} = [];
+	$file_buffer->{'song'}->{'content'}  = "";
+	
+	$file_buffer->{'song'}->{'subcol'} = $2;
+	$file_buffer->{'song'}->{'title'}  = $4;
+	$file_buffer->{'song'}->{'tval'}   = $6;
+
+	chomp($next_line);
+	my $content = $next_line;
+	if (defined $seclevel) 
+	{
+	    $content.= " $seclevel";
+	}
+	$content .= "\n";
+
+	$file_buffer->{'song'}->{'content'} = $content;
+
+
+	my $line;
+	while(defined($line=<FILE>))  
+	{
+	    $line =~ s/\r$//;
+
+	    $file_buffer->{'line_no'}++;
+	    next if ($line =~ m/^\#/);
+	
+	    if ($line =~ m/^song/) 
+	    {	
+		$file_buffer->{'next_line'} = $line;
+		return 1;
+	    }
+	    elsif ($line =~ m/^tempo( +)(\d+)( *)$/) 
+	    {
+		$file_buffer->{'song'}->{'tempo'} = $2;
+		$file_buffer->{'song'}->{'content'} .= $line;
+	    } 
+	    elsif ($line =~ m/^keysig( +)(\d+)( +)(\d+)( *)$/) 
+	    {
+		$file_buffer->{'song'}->{'ks_type'} = $2;
+		$file_buffer->{'song'}->{'ks_num'}  = $4;
+		$file_buffer->{'song'}->{'content'} .= $line;	   
+	    } 
+	    elsif ($line =~ m/^timesig( +)(\d+)( +)(\d+)( *)$/) 
+	    {
+		$file_buffer->{'song'}->{'ts_numer'} = $2;
+		$file_buffer->{'song'}->{'ts_denom'} = $4;
+		$file_buffer->{'song'}->{'content'} .= $line;
+	    }
+	    elsif ($line =~ m/^metadata ([^:]*): (.*)/)
+	    {
+		push(@{$file_buffer->{'song'}->{'metadata'}},[$1,$2]);
+		$file_buffer->{'song'}->{'content'} .= $line;
+	    }
+	    else
+	    {
+		$file_buffer->{'song'}->{'content'} .= $line;
+	    }
+	}
+	
+	$file_buffer->{'next_line'} = undef;
+    }
+
+    return 1;
+}
+
+sub process_rog_record
+{
+    my ($self,$file,$metadata,$song,$processor) = @_;
+
+    # create a new document
+    my $doc_obj = new doc ($file, "indexed_doc", $self->{'file_rename_method'});
+    my $cursection = $doc_obj->get_top_section();
+    $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");
+
+    my $title = $song->{'title'};
+    my $title_safe = $title;
+    $title_safe =~ s/\'/\\\\&apos;/g;
+
+    # add metadata 
+    $doc_obj->add_metadata($cursection, "Tempo",         $song->{'tempo'}); 
+    $doc_obj->add_metadata($cursection, "KeySigType",    $song->{'ks_type'}); 
+    $doc_obj->add_metadata($cursection, "KeySigNum",     $song->{'ks_num'}); 
+    $doc_obj->add_metadata($cursection, "SubCollection", $song->{'subcol'}); 
+    $doc_obj->add_metadata($cursection, "Title",         $title); 
+    $doc_obj->add_metadata($cursection, "TitleSafe",     $title_safe); 
+    $doc_obj->add_metadata($cursection, "TVal",          $song->{'tval'}); 
+    $doc_obj->add_metadata($cursection, "FileFormat",    "Rog");
+    $doc_obj->add_metadata($cursection, "FileSize",      (-s $file));
+
+    foreach my $md ( @{$song->{'metadata'}} )
+    {
+	$doc_obj->add_metadata($cursection, $md->[0], $md->[1]); 
+    }
+
+    # add contents as text
+    $doc_obj->add_text($cursection,$song->{'content'});
+
+    $self->extra_metadata($doc_obj,$cursection, $metadata);
+    
+    # add OID
+    $self->add_OID($doc_obj);
+
+    my $oid = $doc_obj->get_OID();
+    my $appletlink = "<a href=\"javascript:meldexout(\'$oid\','[TitleSafe]')\">";
+
+    $doc_obj->add_utf8_metadata ($cursection, "audiolink",  $appletlink); 
+    $doc_obj->add_utf8_metadata ($cursection, "audioicon",  "_iconaudio_"); 
+    $doc_obj->add_utf8_metadata ($cursection, "/audiolink", "</a>"); 
+
+    # process the document
+    $processor->process($doc_obj);
+}
+
+# return number of files processed, undef if can't process
+# Note that $base_dir might be "" and that $file might 
+# include directories
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+
+    my $filename = &util::filename_cat($base_dir, $file);
+
+    return undef unless ($filename =~ /\.((rog|mdb)(\.gz)?)$/i && (-e $filename));
+
+    my $gz = (defined $3) ? 1: 0;
+
+    print STDERR "<Processing n='$file' p='RogPlugin'>\n" if ($gli);
+    print STDERR "RogPlugin: processing $filename\n" if $processor->{'verbosity'};
+    
+    if ($gz) {
+	open (FILE, "zcat $filename |") 
+	    || die "RogPlugin::read - zcat can't open $filename\n";
+    } else {
+	open (FILE, $filename) 
+	    || die "RogPlugin::read - can't open $filename\n";
+    }
+
+    my $doc_count = 0;
+    my $dot_count = 0;
+    my $file_buffer = { line_no => 0, next_line => "", song => {} };
+
+    while ($self->read_rog_record($file_buffer))
+    {
+	$self->process_rog_record($file,$metadata,$file_buffer->{'song'},$processor);
+	$doc_count++;
+
+	last if ($maxdocs !=-1 && ($total_count+$doc_count) >= $maxdocs);
+	
+	if (($doc_count % 10) == 0)
+	{
+	    print STDERR ".";
+	    $dot_count++;
+	    print STDERR "\n" if (($dot_count % 80) == 0);
+	}
+    }
+
+    close FILE;
+
+    print STDERR "\n";
+
+    $self->{'num_processed'} = $doc_count;
+
+    return 1; # processed the file
+}
+
+1;
+
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/perllib/plugins/SourceCodePlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/SourceCodePlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/SourceCodePlugin.pm	(revision 20131)
@@ -0,0 +1,242 @@
+###########################################################################
+#
+# SourceCodePlugin.pm -- source code plugin
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+# John McPherson Nov 2000
+# originally based on TEXTPlug
+
+# filename is currently used for Title ( optionally minus some prefix )
+
+# Current languages:
+#   text: READMEs/Makefiles
+#   C/C++   (currently extracts #include statements and C++ class decls)
+#   Perl    (currently only done as text)
+#   Shell   (currently only done as text)
+
+package SourceCodePlugin;
+
+use ReadTextFile;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @SourceCodePlugin::ISA = ('ReadTextFile');
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" } ,
+      { 'name' => "block_exp",
+	'desc' => "{BasePlugin.block_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_block_exp(),
+	'reqd' => "no" },
+      { 'name' => "remove_prefix",
+	'desc' => "{SourceCodePlugin.remove_prefix}",
+	'type' => "regexp",
+	'deft' => "^.*[/\\]",
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "SourceCodePlugin",
+		'desc'     => "{SourceCodePlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new ReadTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+sub get_default_block_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.(o|obj|a|so|dll)$^;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(Makefile.*|README.*|(?i)\.(c|cc|cpp|C|h|hpp|pl|pm|sh))$^;
+}
+
+
+
+# do plugin specific processing of doc_obj
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+    
+    my $cursection = $doc_obj->get_top_section();
+
+    my $filetype="text";  # Makefiles, READMEs, ...
+    if ($file =~ /\.(cc|h|cpp|C)$/) {$filetype="C++";} # assume all .h files...
+    elsif ($file =~ /\.c$/)         {$filetype="C";}
+    elsif ($file =~ /\.p(l|m)$/)    {$filetype="perl";}
+    elsif ($file =~ /\.sh$/)        {$filetype="sh";}
+
+    # modify '<' and '>' for GML... (even though inside <pre> tags!!)
+    $$textref =~ s/</&lt;/g;
+    $$textref =~ s/>/&gt;/g;
+    $$textref =~ s/_/&#95;/g;
+    # try _escape_text($text) from doc.pm....
+
+    # don't want mg to turn escape chars into actual values
+    $$textref =~ s/\\/\\\\/g;
+
+    # use filename (minus any prefix) as the title.
+    my $title;
+    if ($self->{'remove_prefix' ne ""}) {
+	($title = $file) =~ s/^$self->{'remove_prefix'}//;
+    } else {
+	($title = $file) =~ s@^.*[/\\]@@; # remove pathname by default
+    }
+    $doc_obj->add_utf8_metadata ($cursection, "Title", $title);
+    $doc_obj->add_metadata ($cursection, "FileFormat", "SRC");
+
+    # remove the gsdl prefix from the filename
+    my $relative_filename=$file;
+    $relative_filename =~ s@^.*?gsdl[/\\]@@;
+    $doc_obj->add_utf8_metadata ($cursection, "filename", $relative_filename);
+
+    # class information from .h and .cc and .C and .cpp files
+    if ($filetype eq "C++") 
+    {
+	process_c_plus_plus($textref,$pluginfo, $base_dir, 
+				   $file, $metadata, $doc_obj);
+    } elsif ($filetype eq "C")
+    {
+	get_includes_metadata($textref, $doc_obj);
+    }
+
+
+     # default operation...
+     # insert preformat tags and add text to document object
+    $doc_obj->add_utf8_text($cursection, "<pre>\n$$textref\n</pre>");
+    
+    return 1;
+}
+
+
+
+
+sub get_includes_metadata {
+    my ($textref, $doc_obj) = @_;
+    
+    my $topsection = $doc_obj->get_top_section();
+
+    # Get '#include' directives for metadata
+    if ($$textref !~ /\#\s*include\b/) {
+	return;
+    }
+
+    my @includes =
+	($$textref =~ m/^\s*\#\s*include\s*(?:\"|&lt;)(.*?)(?:\"|&gt;)/mg);
+    
+    my $incs_done_ref=$doc_obj->get_metadata($topsection, "includes");
+    my @incs_done;
+    if (defined($incs_done_ref)) {
+	@incs_done=@$incs_done_ref;
+    } else {
+	@incs_done=();
+    }
+
+    foreach my $inc (@includes) {
+	# add entries, but only if they don't already exist
+	if (!join('', map {$_ eq "$inc"?1:""} @incs_done)) {
+	    push @incs_done, $inc;
+	    $doc_obj->add_utf8_metadata($topsection, "includes", $inc);
+	}
+    }
+}
+
+
+
+sub process_c_plus_plus {
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj) = @_;
+
+    my $topsection = $doc_obj->get_top_section();
+
+
+    # Check for include metadata
+    get_includes_metadata($textref, $doc_obj);
+
+
+
+    # Get class declarations (but not forward declarations...) as metadata
+    if ($$textref =~ /\bclass\b/ ) {
+	my $classnames=$$textref;
+	
+	# remove commented lines
+	$classnames =~ s@/\*.*?\*/@@sg;
+	$classnames =~ s@//.*$@@mg;
+	while ($classnames =~ /\bclass\b/) {
+
+	    # delete all lines up to the next "class"
+	    while ($classnames !~ /^[^\n]*\bclass\b[^\n]*\n/)
+	    {$classnames =~ s/.*\n//;}
+	    
+#	    $classnames =~ s/^([^c][^l])*(.)?$//mg; # delete unneccessary lines
+
+	    # get the line including the next "class" and remove it from
+	    # our tmp text.
+	    $classnames =~ s/^(.*\bclass\b.*)$//m;
+
+	    # don't index if merely a reference/fwd decl. of another class
+	    if ($1 !~ /(friend\Wclass)|(class\W\w+\W?\;)|(\/\/.*class)/) {
+		# $1 is still the whole line - eg:
+		# "class StaffSystem: public BaseStaffSystem"
+		my $wholeline=$1;
+		my $classname=$1;
+		$classname =~ s/.*class\W(\w+).*/$1/;
+		my $classes=$doc_obj->get_metadata($topsection, "class");
+		foreach my $elem (@$classes) {
+		    if ("$elem" eq "$classname") {goto class_done;}
+		}
+		$doc_obj->add_utf8_metadata($topsection, "class", $classname);
+	      class_done:
+		$doc_obj->add_utf8_metadata($topsection, "classdecl", $wholeline);
+	    }
+	}
+    } # end of "class"
+
+    return 1;
+}
+
+1;
+
Index: /gsdl/stable/perllib/plugins/SplitTextFile.pm
===================================================================
--- /gsdl/stable/perllib/plugins/SplitTextFile.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/SplitTextFile.pm	(revision 20131)
@@ -0,0 +1,315 @@
+###########################################################################
+#
+# SplitTextFile.pm - a plugin for splitting input files into segments that
+#                will then be individually processed.
+#
+#
+# Copyright 2000 Gordon W. Paynter (gwp@cs.waikato.ac.nz)
+# Copyright 2000 The New Zealand Digital Library Project
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+# SplitTextFile is a plugin for splitting input files into segments that will
+# then be individually processed.  
+
+# This plugin should not be called directly.  Instead, if you need to
+# process input files that contain several documents, you should write a
+# plugin with a process function that will handle one of those documents
+# and have it inherit from SplitTextFile.  See ReferPlug for an example.
+
+
+package SplitTextFile;
+
+use ReadTextFile;
+use gsprintf 'gsprintf';
+use util;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+# SplitTextFile is a sub-class of ReadTextFile
+sub BEGIN {
+    @SplitTextFile::ISA = ('ReadTextFile');
+}
+
+
+my $arguments =
+    [ { 'name' => "split_exp",
+	'desc' => "{SplitTextFile.split_exp}",
+	'type' => "regexp",
+	#'deft' => &get_default_split_exp(),
+	'deft' => "",
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "SplitTextFile",
+		'desc'     => "{SplitTextFile.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes",
+	        'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new ReadTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    $self->{'textcat_store'} = {};
+    $self->{'metapass_srcdoc'} = {}; # which segments have valid metadata_srcdoc
+    return bless $self, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+    my ($verbosity, $outhandle, $failhandle) = @_;
+
+    $self->ReadTextFile::init($verbosity, $outhandle, $failhandle);
+
+    # why is this is init and not in new??
+    if ((!defined $self->{'process_exp'}) || ($self->{'process_exp'} eq "")) {
+
+	$self->{'process_exp'} = $self->get_default_process_exp ();
+	if ($self->{'process_exp'} eq "") {
+	    warn ref($self) . " Warning: plugin has no process_exp\n";
+	}
+    }
+
+
+    # set split_exp to default unless explicitly set
+    if (!$self->{'split_exp'}) {
+	$self->{'split_exp'} = $self->get_default_split_exp ();
+    }
+
+}
+
+# This plugin recurs over the segments it finds
+sub is_recursive {
+    return 1;
+}
+
+# By default, we split the input text at blank lines
+sub get_default_split_exp {
+    return q^\n\s*\n^;
+}
+
+sub metadata_read {
+    my $self = shift (@_);  
+    my ($pluginfo, $base_dir, $file, $block_hash, 
+	$extrametakeys, $extrametadata, $extrametafile,
+	$processor, $maxdocs, $gli) = @_;
+
+    # returns 1 if matches process_exp, and has done blocking in the meantime
+    my $matched = $self->SUPER::metadata_read($pluginfo, $base_dir, $file,
+					      $block_hash, 
+					      $extrametakeys, 
+					      $extrametadata, 
+					      $extrametafile,
+					      $processor, $maxdocs, $gli);
+    my $split_matched = undef;
+
+    if ($matched) {
+
+	my $outhandle = $self->{'outhandle'};
+	my $filename = &util::filename_cat($base_dir, $file);
+
+	my $plugin_name = ref ($self);
+	$file =~ s/^[\/\\]+//; # $file often begins with / so we'll tidy it up
+
+	$self->{'metapass_srcdoc'}->{$file} = {};
+
+	# Do encoding stuff
+	my ($language, $encoding) = $self->textcat_get_language_encoding ($filename);
+	my $le_rec = { 'language' => $language, 'encoding' => $encoding };
+	$self->{'textcat_store'}->{$file} = $le_rec;
+
+	# Read in file ($text will be in utf8)
+	my $text = "";
+	$self->read_file ($filename, $encoding, $language, \$text);
+
+ 
+	if ($text !~ /\w/) {
+	    gsprintf($outhandle, "$plugin_name: {ReadTextFile.file_has_no_text}\n",
+		     $file)
+		if $self->{'verbosity'};
+	    
+	    my $failhandle = $self->{'failhandle'};
+	    print $failhandle "$file: " . ref($self) . ": file contains no text\n";
+	    $self->{'num_not_processed'} ++;
+
+	    $self->{'textcat_store'}->{$file} = undef;
+
+	    return 0; 
+	}
+    
+    
+	# Split the text into several smaller segments
+	my $split_exp = $self->{'split_exp'};
+        my @tmp  = split(/$split_exp/i, $text);
+	my @segments =();
+	## get rid of empty segments
+	foreach my $seg (@tmp){
+	    if ($seg ne ""){
+		push @segments, $seg;
+	    }
+	}
+
+	print $outhandle "SplitTextFile found " . (scalar @segments) . " documents in $filename\n" 
+	    if $self->{'verbosity'};
+	
+	$self->{'split_segments'}->{$file} = \@segments;
+	$split_matched = scalar(@segments);
+    }
+    
+    return $split_matched;
+}
+
+
+
+# The read function opens a file and splits it into parts. 
+# Each part is sent to the process function
+#
+# Returns: Number of document objects created (or undef if it fails)
+
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+
+    # can we process this file??
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+
+    $file =~ s/^[\/\\]+//; # $file often begins with / so we'll tidy it up
+
+    my $le_rec = $self->{'textcat_store'}->{$file};
+    if (!defined $le_rec) {
+	# means no text was found;
+	return 0; # not processed but no point in passing it on
+    }
+
+    print STDERR "<Processing n='$file' p='$self->{'plugin_type'}'>\n" if ($gli);
+    print $outhandle "$self->{'plugin_type'} processing $file\n"
+	    if $self->{'verbosity'} > 1;    
+
+    my $language = $le_rec->{'language'};
+    my $encoding = $le_rec->{'encoding'};
+    $self->{'textcat_store'}->{$file} = undef;
+
+    my $segments = $self->{'split_segments'}->{$file};
+    $self->{'split_segments'}->{$file} = undef;
+
+    # Process each segment in turn
+    my ($count, $segment, $segtext, $status, $id);
+    $segment = 0;
+    $count = 0;
+    foreach $segtext (@$segments) {
+     	$segment++;
+
+	if (defined $self->{'metapass_srcdoc'}->{$file}->{$segment}) {
+	    # metadata is attached to a srcdoc
+	    next;
+	}
+
+	# create a new document
+	my $doc_obj = new doc ($filename_full_path, "indexed_doc", $self->{'file_rename_method'});
+	$doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Language", $language);
+	$doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Encoding", $encoding);
+	my ($filemeta) = $file =~ /([^\\\/]+)$/;
+	$self->set_Source_metadata($doc_obj, $filemeta, $encoding);
+	$doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "SourceSegment", "$segment");
+	if ($self->{'cover_image'}) {
+	    $self->associate_cover_image($doc_obj, $filename_full_path);
+	}
+	$doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");
+	#$doc_obj->add_metadata($doc_obj->get_top_section(), "FileFormat", "Split");
+
+	# Calculate a "base" document ID.
+	if (!defined $id) {
+	    $id = $self->get_base_OID($doc_obj);
+	}
+    
+	# include any metadata passed in from previous plugins 
+	# note that this metadata is associated with the top level section
+	$self->extra_metadata ($doc_obj, $doc_obj->get_top_section(), $metadata);
+
+	# do plugin specific processing of doc_obj
+	print $outhandle "segment $segment\n" if ($self->{'verbosity'});
+	$status = $self->process (\$segtext, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli);
+	if (!defined $status) {
+	    print $outhandle "WARNING - no plugin could process segment $segment of $file\n" 
+		if ($verbosity >= 2);
+	    next;
+	}
+	# If the plugin returned 0, it threw away this part
+	if ($status == 0) {
+	    next;
+	}
+	$count += $status;
+
+	# do any automatic metadata extraction
+	$self->auto_extract_metadata ($doc_obj);
+
+	# add an OID
+	$self->add_OID($doc_obj, $id, $segment);
+
+	# process the document
+	$processor->process($doc_obj);
+
+	$self->{'num_processed'} ++;
+    }
+
+    delete $self->{'metapass_srcdoc'}->{$file};
+
+    # Return number of document objects produced
+    return $count; 
+}
+
+sub get_base_OID {
+    my $self = shift(@_);
+    my ($doc_obj) = @_;
+
+    $self->SUPER::add_OID($doc_obj);
+    return $doc_obj->get_OID();
+}
+
+sub add_OID {
+    my $self = shift (@_);
+    my ($doc_obj, $id, $segment) = @_;
+
+    my $full_id = $id . "s" . $segment;
+    if ($self->{'OIDtype'} eq "assigned") {
+	my $identifier = $doc_obj->get_metadata_element ($doc_obj->get_top_section(), $self->{'OIDmetadata'});
+	if (defined $identifier && $identifier ne "") {
+	    $full_id = $identifier;
+	    $full_id = &util::tidy_up_oid($full_id);
+	}
+    }
+    $doc_obj->set_OID($full_id);
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/StructuredHTMLPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/StructuredHTMLPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/StructuredHTMLPlugin.pm	(revision 20131)
@@ -0,0 +1,403 @@
+###########################################################################
+#
+# StructuredHTMLPlugin.pm -- html plugin with extra facilities for teasing out 
+# hierarchical structure (such as h1, h2, h3, or user-defined tags) in an 
+# HTML document
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+# This plugin is to process an HTML file where sections are divided by 
+# user-defined headings tags. As it is difficult to predict what user's definition
+# this plugin allows to detect the user-defined titles up to three levels (level1, level2, level3...)
+# as well as allows to get rid of user-defined Table of Content (TOC)...
+# format:e.g. level1 (Abstract_title|ChapterTitle|Referencing Heading) level2(SectionHeading)...
+
+package StructuredHTMLPlugin;
+
+use HTMLPlugin;
+use ImageConverter; # want the identify method
+
+use strict; # every perl program should have this!
+no strict 'refs'; # make an exception so we can use variables as filehandles
+
+sub BEGIN {
+    @StructuredHTMLPlugin::ISA = ('HTMLPlugin');
+}
+
+my $arguments = 
+    [
+     { 'name' => "level1_header",
+       'desc' => "{StructuredHTMLPlugin.level1_header}",
+       'type' => "regexp",
+       'reqd' => "no",
+       'deft' => "" },
+     { 'name' => "level2_header",
+       'desc' => "{StructuredHTMLPlugin.level2_header}",
+       'type' => "regexp",
+       'reqd' => "no",
+       'deft' => "" },
+     { 'name' => "level3_header",
+       'desc' => "{StructuredHTMLPlugin.level3_header}",
+       'type' => "regexp",
+       'reqd' => "no",
+       'deft' => "" },
+     { 'name' => "title_header",
+       'desc' => "{StructuredHTMLPlugin.title_header}",
+       'type' => "regexp",
+       'reqd' => "no",
+       'deft' => "" },
+     { 'name' => "delete_toc",
+       'desc' => "{StructuredHTMLPlugin.delete_toc}",
+       'type' => "flag",
+       'reqd' => "no"},
+     { 'name' => "toc_header",
+       'desc' => "{StructuredHTMLPlugin.toc_header}",
+       'type' => "regexp",
+       'reqd' => "no",
+       'deft' => "" }     
+     ];
+
+my $options = { 'name'     => "StructuredHTMLPlugin",
+		'desc'     => "{StructuredHTMLPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+    
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+    
+    my $self = new HTMLPlugin($pluginlist, $inputargs, $hashArgOptLists);
+    
+    return bless $self, $class;
+}
+
+
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    my @head_and_body = split(/<body/i,$$textref);
+    my $head = shift(@head_and_body);
+    my $body_text = join("<body", @head_and_body);
+    $head =~ m/<title>(.+)<\/title>/i;
+    my $doctitle = $1 if defined $1;
+    if (defined $self->{'metadata_fields'} && $self->{'metadata_fields'}=~ /\S/) {
+	my @doc_properties = split(/<xml>/i,$head);
+	my $doc_heading = shift(@doc_properties);
+	my $rest_doc_properties = join(" ", @doc_properties);
+
+	my @extracted_metadata = split(/<\/xml>/i, $rest_doc_properties);
+	my $extracted_metadata = shift (@extracted_metadata);
+	$self->extract_metadata($extracted_metadata, $metadata, $doc_obj);
+    }
+    
+    # set the title here if we haven't found it yet
+    if (!defined $doc_obj->get_metadata_element ($doc_obj->get_top_section(), "Title")) {
+	if (defined $doctitle && $doctitle =~ /\S/) {
+	    $doc_obj->add_metadata($doc_obj->get_top_section(), "Title", $doctitle);
+	} else {
+	    $self->title_fallback($doc_obj,$doc_obj->get_top_section(),$file);
+	}
+    }
+
+    # If delete_toc is enabled, it means to get rid of toc and tof contents.
+    # get rid of TOC and TOF sections and their title
+    if (defined $self->{'delete_toc'} && ($self->{'delete_toc'} == 1)){
+	if (defined $self->{'toc_header'}&& $self->{'toc_header'} =~ /\S/){
+	    $body_text =~ s/<p class=(($self->{'toc_header'})[^>]*)>(.+?)<\/p>//isg;
+	}
+    }
+    
+    if (defined $self->{'title_header'} && $self->{'title_header'}=~ /\S/){
+	$self->{'title_header'} =~ s/^(\()(.*)(\))/$2/is;
+	$body_text =~ s/<p class=(($self->{'title_header'})[^>]*)>(.+?)<\/p>/<p class=$1><h1>$3<\/h1><\/p>/isg;
+    }
+
+    if (defined $self->{'level1_header'} && $self->{'level1_header'}=~ /\S/ ){
+     	$self->{'level1_header'} =~ s/^\((.*)\)/$1/i;
+	$body_text =~ s/<p class=(($self->{'level1_header'})[^>]*)>(.+?)<\/p>/<p class=$1><h1>$3<\/h1><\/p>/isg;
+    }
+    
+    if (defined $self->{'level2_header'} && $self->{'level2_header'}=~ /\S/){
+	$self->{'level2_header'} =~ s/^\((.*)\)/$1/i;
+	$body_text =~ s/<p class=(($self->{'level2_header'})[^>]*)>(.+?)<\/p>/<p class=$1><h2>$3<\/h2><\/p>/isg;
+    }
+    
+    if (defined $self->{'level3_header'} && $self->{'level3_header'}=~ /\S/ ){
+	$self->{'level3_header'} =~ s/^\((.*)\)/$1/is;
+	$body_text =~ s/<p class=(($self->{'level3_header'})[^>]*)>(.+?)<\/p>/<p class=$1><h3>$3<\/h3><\/p>/isg;
+    }
+    
+    # Tidy up extra new lines
+    $body_text =~ s/(<p[^>]*><span[^>]*><o:p>&nbsp;<\/o:p><\/span><\/p>)//isg;
+    $body_text =~ s/(<p[^>]*><o:p>&nbsp;<\/o:p><\/p>)//isg;
+    
+    # what was the following line for. effectively unused. do we need it??
+    #$section_text .= "<!--\n<Section>\n-->\n";
+    #my $top_section_tag = "<!--\n<Section>\n-->\n";
+    #$body_text =~ s/(<div.*)/$top_section_text$doctitle$1/i;
+    #$body_text =~ s/(<div.*)/$top_section_tag$1/i;
+    my $body = "<body".$body_text;
+    
+    my $section_text = $head;
+    
+    # split HTML text on <h1>, <h2> etc tags
+    my @h_split = split(/<h/i,$body);
+    
+    my $hnum = 0;
+
+    my $sectionh1 = 0;
+    $section_text .= shift(@h_split);
+    
+    my $hc;
+    foreach $hc ( @h_split )
+    {
+	if ($hc =~ m/^([1-3])\s*.*?>(.*)$/s)
+	{
+	    my $new_hnum = $1;
+	    my $hc_after = $2;
+	    
+	    if ($hc_after =~ m/^(.*?)<\/h$new_hnum>/is)
+	    {
+		my $h_text = $1;
+		$hc =~ s/^(\&nbsp\;)+/\&nbsp\;/g;
+		# boil HTML down to some interesting text
+		$h_text =~ s/^[1-3]>//;
+		$h_text =~ s/<\/?.*?>//sg;
+		$h_text =~ s/\s+/ /sg;
+		$h_text =~ s/^\s$//s;
+		$h_text =~ s/(&nbsp;)+\W*/&nbsp;/sg;
+		
+		if ($h_text =~ m/\w+/)
+		{
+		    if ($new_hnum > $hnum)
+		    {
+			# increase section nesting
+			$hnum++;
+			while ($hnum < $new_hnum)
+			{
+			    my $spacing = "  " x $hnum;
+			    $section_text .= "<!--\n";
+			    $section_text .= $spacing."<Section>\n";
+			    $section_text .= "-->\n";
+			    $hnum++;
+			}
+		    }
+		    else # ($new_hnum <= $hnum)
+		    {
+			# descrease section nesting
+			while ($hnum >= $new_hnum)
+			{
+			    my $spacing = "  " x $hnum;
+			    $section_text .= "<!--\n";
+			    $section_text .= $spacing."</Section>\n";
+			    $section_text .= "-->\n";
+			    $hnum--;
+			}
+			$hnum++;
+		    }
+
+		    my $spacing = "  " x $hnum;
+		    $section_text .= "<!--\n";
+		    $section_text .= $spacing."<Section>\n";
+		    $section_text .= $spacing."  <Description>\n";
+		    $section_text .= $spacing."    <Metadata name=\"Title\">$h_text</Metadata>";
+		    $section_text .= $spacing."  </Description>\n";
+		    $section_text .= "-->\n";
+		    
+		    #print $outhandle $spacing."$h_text\n"
+		    #	if $self->{'verbosity'} > 2;
+		    
+		    $sectionh1++ if ($hnum==1);
+		}
+	    }
+	    else {
+###		print STDERR "***** hc = <h$hc\n\n";
+	    }
+	    $section_text .= "<h$hc";
+	}
+	else
+	{
+	    $section_text .= "<h$hc";
+	}
+    }
+
+    while ($hnum >= 1)
+    {
+	my $spacing = "  " x $hnum;
+	$section_text .= "<!--\n";
+	$section_text .= $spacing."</Section>\n";
+	$section_text .= "-->\n";
+	$hnum--;
+    }
+
+    $section_text .= "<!--\n</Section>\n-->\n";
+
+    $$textref = $section_text;
+    
+#    if ($sectionh1>0)
+#    {
+#	print $outhandle "  Located section headings ..."
+#	    if $self->{'verbosity'} > 1;
+#    }
+    
+    $$textref =~ s/<!\[if !vml\]>/<![if vml]>/g;
+    
+    $$textref =~ s/(&nbsp;)+/&nbsp;/sg;    
+    
+    ## $$textref =~ s/<o:p>&nbsp;<\/o:p>//g; # used with VML to space figures?
+    
+    $self->SUPER::process(@_);
+    
+}
+
+
+sub resize_if_necessary
+{
+    my ($self,$front,$back,$base_dir,$href) = @_;
+    
+    # dig out width and height of image, if there
+    my $img_attributes = "$front back";
+    my ($img_width)  = ($img_attributes =~ m/\s+width=\"?(\d+)\"?/i);
+    my ($img_height) = ($img_attributes =~ m/\s+height=\"?(\d+)\"?/i);
+    
+    # derive local filename for image based on its URL
+    my $img_filename = $href;
+    $img_filename =~ s/^[^:]*:\/\///;
+    $img_filename = &util::filename_cat($base_dir, $img_filename);
+    
+    # Replace %20's in URL with a space if required. Note that the filename
+    # may include the %20 in some situations
+    if ($img_filename =~ /\%20/) {
+	if (!-e $img_filename) {
+	    $img_filename =~ s/\%20/ /g;
+	}
+    }
+    if ((-e $img_filename) && (defined $img_width) && (defined $img_height)) {
+	# get image info on width and height
+	
+	my $outhandle = $self->{'outhandle'};
+	my $verbosity = $self->{'verbosity'};
+
+	my ($image_type, $actual_width, $actual_height, $image_size) 
+	    = &ImageConverter::identify($img_filename, $outhandle, $verbosity);
+	
+	#print STDERR "**** $actual_width x $actual_height";
+	#print STDERR " (requested: $img_width x $img_height)\n";
+
+	if (($img_width < $actual_width) || ($img_height < $actual_height)) {
+	    #print $outhandle "Resizing $img_filename\n" if ($verbosity > 0);
+	    
+	    # derive new image name based on current image
+	    my ($tailname, $dirname, $suffix)
+		= &File::Basename::fileparse($img_filename, "\\.[^\\.]+\$");
+	    
+	    my $resized_filename 
+		= &util::filename_cat($dirname, $tailname."_resized".$suffix);
+	    
+	    #print STDERR "**** suffix = $suffix\n";
+	    
+	    # Generate smaller image with convert
+	    my $newsize = "$img_width"."x$img_height";
+	    my $command = "convert -interlace plane -verbose "
+		."-geometry $newsize \"$img_filename\" \"$resized_filename\"";
+	    #print $outhandle "ImageResize: $command\n" if ($verbosity > 2);
+	    #my $result = '';
+	    #print $outhandle "ImageResize result: $result\n" if ($verbosity > 2);
+	}
+    }
+    return $href;
+}
+
+sub replace_images {
+    my $self = shift (@_);
+    my ($front, $link, $back, $base_dir, 
+	$file, $doc_obj, $section) = @_;
+    # remove quotes from link at start and end if necessary
+    if ($link=~/^\"/) {
+	$link=~s/^\"//;$link=~s/\"$//;
+	$front.='"';
+	$back="\"$back";
+    }
+    
+    $link =~ s/\n/ /g;
+    
+    my ($href, $hash_part, $rl) = $self->format_link ($link, $base_dir, $file);
+    
+##    $href = $self->resize_if_necessary($front,$back,$base_dir,$href);
+    
+    my $middle = $self->add_file ($href, $rl, $hash_part, $base_dir, $doc_obj, $section);
+    
+    return $front . $middle . $back;
+}
+
+sub extract_metadata 
+{
+    my $self = shift (@_);
+    my ($textref, $metadata, $doc_obj) = @_;
+    my $outhandle = $self->{'outhandle'};
+    
+    return if (!defined $textref);
+
+    # metadata fields to extract/save. 'key' is the (lowercase) name of the
+    # html meta, 'value' is the metadata name for greenstone to use
+    my %find_fields = ();
+    my ($tag,$value);
+
+    my $orig_field = "";
+    foreach my $field (split /\s*,\s*/, $self->{'metadata_fields'}) {
+	# support tag<tagname>
+	if ($field =~ /^(.*?)\s*<(.*?)>$/) {
+	    # "$2" is the user's preferred gs metadata name
+	    $find_fields{lc($1)}=$2; # lc = lowercase
+	    $orig_field = $1;
+	} else { # no <tagname> for mapping
+	    # "$field" is the user's preferred gs metadata name
+	    $find_fields{lc($field)}=$field; # lc = lowercase
+	    $orig_field = $field;
+	}
+
+	if ($textref =~ m/<o:$orig_field>(.*)<\/o:$orig_field>/i){
+	    $tag = $orig_field;
+	    $value = $1;
+	    if (!defined $value || !defined $tag){
+		#print $outhandle "StructuredHTMLPlugin: can't find VALUE in \"$tag\"\n";
+		next;
+	    } else {
+		# clean up and add
+		chomp($value); # remove trailing \n, if any
+		$tag = $find_fields{lc($tag)};
+		#print $outhandle " extracted \"$tag\" metadata \"$value\"\n" 
+		#    if ($self->{'verbosity'} > 2);
+		$doc_obj->add_utf8_metadata($doc_obj->get_top_section(), $tag, $value);
+	    }
+	}
+    }
+}
+
+1;
Index: /gsdl/stable/perllib/plugins/TextPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/TextPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/TextPlugin.pm	(revision 20131)
@@ -0,0 +1,235 @@
+###########################################################################
+#
+# TextPlugin.pm -- simple text plugin
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# creates simple single-level document. Adds Title metadata 
+# of first line of text (up to 100 characters long).
+
+package TextPlugin;
+
+use ReadTextFile;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+no strict 'subs';
+
+sub BEGIN {
+    @TextPlugin::ISA = ('ReadTextFile');
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" } ,
+      { 'name' => "title_sub",
+	'desc' => "{TextPlugin.title_sub}",
+	'type' => "regexp",
+	'deft' => "",
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "TextPlugin",
+		'desc'     => "{TextPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'srcreplaceable' => "yes", # Source docs in regular txt format can be replaced with GS-generated html
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new ReadTextFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.te?xt$^;
+}
+
+# do plugin specific processing of doc_obj
+sub process {
+    my $self = shift (@_);
+    my ($textref, $pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+    
+    my $cursection = $doc_obj->get_top_section();
+    # get title metadata
+    # (don't need to get title if it has been passed
+    # in from another plugin)
+    if (!defined $metadata->{'Title'}) {
+	my $title = $self->get_title_metadata($textref);
+	$doc_obj->add_utf8_metadata ($cursection, "Title", $title);
+    }
+    # Add FileFormat metadata
+    $doc_obj->add_metadata($cursection, "FileFormat", "Text");
+
+    # insert preformat tags and add text to document object    
+    $self->text_to_html($textref); # modifies the text
+    $doc_obj->add_utf8_text($cursection, $$textref);
+
+    return 1;
+}
+
+sub get_title_metadata {
+    my $self = shift (@_);
+    my ($textref) = @_;
+    
+    my ($title) = $$textref;
+    $title =~ /^\s+/s;
+    if (defined $self->{'title_sub'} && $self->{'title_sub'}) {
+	$title =~ s/$self->{'title_sub'}//;
+    }
+    $title =~ /^\s*([^\n]*)/s; $title=$1;
+    if (length($title) > 100) {
+	$title = substr ($title, 0, 100) . "...";
+    }
+    $title =~ s/\[/&\#91;/g;
+    $title =~ s/\[/&\#93;/g;
+    $title =~ s/\</&\#60;/g;
+    $title =~ s/\>/&\#62;/g;
+    
+    return $title;
+}
+
+sub text_to_html {
+    my $self = shift (@_);
+    my ($textref) = @_;
+    
+    # we need to escape the escape character, or else mg will convert into
+    # eg literal newlines, instead of leaving the text as '\n'
+    $$textref =~ s/\\/\\\\/g; # macro language
+    $$textref =~ s/_/\\_/g; # macro language
+    $$textref =~ s/</&lt;/g;
+    $$textref =~ s/>/&gt;/g;
+    
+    # insert preformat tags and add text to document object
+    $$textref = "<pre>\n$$textref\n</pre>";
+}
+
+
+# replace_srcdoc_with_html.pl requires all subroutines that support src_replaceable
+# to contain a method called tmp_area_convert_file - this is indeed the case with all
+# Perl modules that are subclasses of ConvertToPlug.pm, but as we want TextPlugin to also
+# be srcreplaceable and because TextPlugin does not inherit from ConvertToPlug.pm, we have
+# a similar subroutine with the same name here.
+sub tmp_area_convert_file {
+    my $self = shift (@_);
+    my ($output_ext, $input_filename) = @_;
+    
+    my $outhandle = $self->{'outhandle'};
+    #my $failhandle = $self->{'failhandle'};
+    
+    # derive output filename from input filename
+    my ($tailname, $dirname, $suffix)
+	= &File::Basename::fileparse($input_filename, "\\.[^\\.]+\$");
+
+    # Softlink to collection tmp dir
+    # First find a temporary directory to create the output file in
+    my $tmp_dirname = $dirname;
+    if(defined $ENV{'GSDLCOLLECTDIR'}) {
+	$tmp_dirname = $ENV{'GSDLCOLLECTDIR'};
+    } elsif(defined $ENV{'GSDLHOME'}) {
+	$tmp_dirname = $ENV{'GSDLHOME'};
+    }
+    $tmp_dirname = &util::filename_cat($tmp_dirname, "tmp");
+    &util::mk_dir($tmp_dirname) if (!-e $tmp_dirname);
+
+    # convert to utf-8 otherwise we have problems with the doc.xml file
+    # later on
+    $tailname = $self->SUPER::filepath_to_utf8($tailname) unless &unicode::check_is_utf8($tailname);
+
+    $suffix = lc($suffix);
+    my $tmp_filename = &util::filename_cat($tmp_dirname, "$tailname$suffix"); 
+    
+    # Make sure we have the absolute path to the input file
+    # (If gsdl is remote, we're given relative path to input file, of the form import/tailname.suffix
+    # But we can't softlink to relative paths. Therefore, we need to ensure that
+    # the input_filename is the absolute path.
+    my $ensure_path_absolute = 1; # true
+
+    # Now make the softlink,  so we don't accidentally damage the input file
+    # softlinking creates a symbolic link to (or, if that's not possible, it makes a copy of) the original
+    &util::soft_link($input_filename, $tmp_filename, $ensure_path_absolute);
+     
+    my $verbosity = $self->{'verbosity'};
+    if ($verbosity > 0) {
+	# need this output statement, as GShell.java's runRemote() sets status to CANCELLED
+	# if there is no output! (Therefore, it only had this adverse affect when running GSDL remotely)
+	print $outhandle "Converting $tailname$suffix to html\n";
+    }
+
+    #my $output_filename = $tailname$output_ext; #output_ext has to be html!
+    my $output_filename = &util::filename_cat($tmp_dirname, $tailname.".html");
+    
+    # Read contents of text file line by line into an array
+    # create an HTML file from the text file
+    # Recreate the original file for writing the updated contents
+    unless(open(TEXT, "<$tmp_filename")) { # open it as a new file for writing
+	print STDERR "TextPlugin.pm: Unable to open and read from $tmp_filename for converting to html...ERROR: $!\n";
+	return ""; # no file name
+    }
+
+    # Read the entire file at once
+    my $text;
+    { 
+	local $/ = undef; # Now can read the entire file at once. From http://perl.plover.com/local.html
+	$text = <TEXT>;   # File is read in as one single 'line'
+    }
+    close(TEXT); # close the file
+
+    # Get the title before embedding the text in pre tags
+    my $title = $self->get_title_metadata(\$text);   
+
+    # Now convert the text 
+    $self->text_to_html(\$text);
+    
+    # try creating this new file writing and try opening it for writing, else exit with error value
+    unless(open(HTML, ">$output_filename")) {  # open the new html file for writing
+	print STDERR "TextPlugin.pm: Unable to create $output_filename for writing $tailname$suffix txt converted to html...ERROR: $!\n";
+	return ""; # no filename
+    }
+    # write the html contents of the text (which is embedded in <pre> tags) out to the file with proper enclosing tags
+    print HTML "<html>\n<head>\n<title>$title</title>\n</head>\n<body>\n";
+    print HTML $text;
+    print HTML "\n</body>\n</html>";
+    close HTML;
+
+    # remove the copy of the original file/remove the symbolic link to original file
+    &util::rm($tmp_filename);
+
+    return $output_filename; # return the output file path
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugins/UnknownPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/UnknownPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/UnknownPlugin.pm	(revision 20131)
@@ -0,0 +1,171 @@
+###########################################################################
+#
+# UnknownPlugin.pm -- Plugin for files you know about but Greenstone doesn't
+#
+# A component of the Greenstone digital library software from the New
+# Zealand Digital Library Project at the University of Waikato, New
+# Zealand.
+#
+# Copyright (C) 2001 Gordon W. Paynter
+# Copyright (C) 2001 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# UnknownPlugin - a plugin for unknown files
+
+# This is a simple Plugin for importing files in formats that
+# Greenstone doesn't know anything about.  A fictional document will
+# be created for every such file, and the file itself will be passed
+# to Greenstone as the "associated file" of the document.
+
+# Here's an example where it is useful: I have a collection of
+# pictures that include a couple of quicktime movie files with names
+# like DCP_0163.MOV.  Rather than write a new plugin for quicktime
+# movies, I add this line to the collection configuration file:
+
+# plugin UnknownPlugin -process_exp "*.MOV" -assoc_field "movie"
+
+# A document is created for each movie, with the associated movie
+# file's name in the "movie" metadata field.  In the collection's
+# format strings, I use the {If} macro to output different text for
+# each type of file, like this:
+
+# {If}{[movie],<HTML for displaying movie>}{If}{[Image],<HTML for displaying image>}
+
+# You can also add extra metadata, such as the Title, Subject, and
+# Duration, with metadata.xml files and RecPlug.  (If you want to use
+# UnknownPlugin with more than one type of file, you will have to add
+# some sort of distinguishing metadata in this way.)
+
+
+
+package UnknownPlugin;
+
+use BasePlugin;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @UnknownPlugin::ISA = ('BasePlugin');
+}
+
+my $arguments =
+    [ { 'name' => "assoc_field",
+	'desc' => "{UnknownPlugin.assoc_field}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "file_format",
+	'desc' => "{UnknownPlugin.file_format}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "mime_type",
+	'desc' => "{UnknownPlugin.mime_type}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" },
+      { 'name' => "srcicon",
+	'desc' => "{UnknownPlugin.srcicon}",
+	'type' => "string",
+	'deft' => "iconunknown",
+	'reqd' => "no" },
+      { 'name' => "process_extension",
+	'desc' => "{UnknownPlugin.process_extension}",
+	'type' => "string",
+	'deft' => "",
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "UnknownPlugin",
+		'desc'     => "{UnknownPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    # "-process_extension" is a simpler alternative to -process_exp for non-regexp people
+    if (!$self->{'process_exp'} && $self->{'process_extension'}) {
+	$self->{'process_exp'} = "\\." . $self->{'process_extension'} . "\$";
+    }
+
+    return bless $self, $class;
+}
+
+
+sub process {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
+
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    my $outhandle = $self->{'outhandle'};
+    my $verbosity = $self->{'verbosity'};
+
+    # check the filename is okay - do we need this??
+    if ($filename_full_path eq "" || $filename_no_path eq "") {
+	print $outhandle "UnknownPlugin: couldn't process \"$filename_no_path\"\n";
+	return undef;
+    }
+
+    # Add the file as an associated file ...
+    my $section = $doc_obj->get_top_section();
+    my $file_format = $self->{'file_format'} || "unknown";
+    my $mime_type = $self->{'mime_type'} || "unknown/unknown";
+    my $assoc_field = $self->{'assoc_field'} || "unknown_file";
+
+    # The assocfilename is the url-encoded version of the utf8 filename
+    my $assoc_file = $doc_obj->get_assocfile_from_sourcefile();
+
+    $doc_obj->associate_file($filename_full_path, $assoc_file, $mime_type, $section);
+    $doc_obj->add_metadata ($section, "FileFormat", $file_format);
+    $doc_obj->add_metadata ($section, "MimeType", $mime_type);
+    $doc_obj->add_utf8_metadata ($section, $assoc_field, $doc_obj->get_source()); # Source metadata is already in utf8 
+
+    $doc_obj->add_metadata ($section, "srclink", 
+			    "<a href=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[SourceFile]\">");
+    $doc_obj->add_metadata ($section, "srcicon", "_".$self->{'srcicon'}."_");
+    $doc_obj->add_metadata ($section, "/srclink", "</a>");
+    
+    # we have no text - add dummy text and NoText metadata
+    $self->add_dummy_text($doc_obj, $section);
+
+    return 1;
+}
+
+
+1;
+
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/perllib/plugins/WordPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/WordPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/WordPlugin.pm	(revision 20131)
@@ -0,0 +1,231 @@
+###########################################################################
+#
+# WordPlugin.pm -- plugin for importing Microsoft Word documents
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+package WordPlugin;
+
+use ConvertBinaryFile;
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+sub BEGIN {
+    @WordPlugin::ISA = ('ConvertBinaryFile');
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "regexp",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" },
+      { 'name' => "description_tags",
+	'desc' => "{HTMLPlugin.description_tags}",
+	'type' => "flag" }
+      ];
+
+my $options = { 'name'     => "WordPlugin",
+		'desc'     => "{WordPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'srcreplaceable' => "yes", # Source docs in Word can be replaced with GS-generated html
+		'args'     => $arguments };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    if ($ENV{'GSDLOS'} =~ m/^windows$/i) {
+	my $ws_arg = [ { 'name' => "windows_scripting",
+			 'desc' => "{WordPlugin.windows_scripting}",
+			 'type' => "flag",
+		         'reqd' => "no" },
+		       { 'name' => "metadata_fields",
+			 'desc' => "{WordPlugin.metadata_fields}",
+			 'type' => "string",
+			 'deft' => "Title" },
+		       { 'name' => "level1_header",
+			 'desc' => "{StructuredHTMLPlugin.level1_header}",
+			 'type' => "regexp",
+			 'reqd' => "no",
+			 'deft' => "" },
+		       { 'name' => "level2_header",
+			 'desc' => "{StructuredHTMLPlugin.level2_header}",
+			 'type' => "regexp",
+			 'reqd' => "no",
+			 'deft' => "" },
+		       { 'name' => "level3_header",
+			 'desc' => "{StructuredHTMLPlugin.level3_header}",
+			 'type' => "regexp",
+			 'reqd' => "no",
+			 'deft' => "" },
+		       { 'name' => "title_header",
+			 'desc' => "{StructuredHTMLPlugin.title_header}",
+			 'type' => "regexp",
+			 'reqd' => "no",
+			 'deft' => "" },
+		       { 'name' => "delete_toc",
+			 'desc' => "{StructuredHTMLPlugin.delete_toc}",
+			 'type' => "flag",
+			 'reqd' => "no" },
+		       { 'name' => "toc_header",
+			 'desc' => "{StructuredHTMLPlugin.toc_header}",
+			 'type' => "regexp",
+			 'reqd' => "no",
+			 'deft' => "" }
+		       ];
+	
+	push(@$arguments,@$ws_arg);
+    }
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new ConvertBinaryFile($pluginlist, $inputargs, $hashArgOptLists);
+
+    if ($self->{'info_only'}) {
+	# don't worry about any options etc
+	return bless $self, $class;
+    }
+
+    $self->{'filename_extension'} = "doc";
+    $self->{'file_type'} = "Word";
+
+    #this is passed through to gsConvert.pl by ConvertBinaryFile.pm
+    $self->{'convert_options'} = "-windows_scripting" if $self->{'windows_scripting'};
+
+    # we always save as utf-8
+#    if ($self->{'input_encoding'} eq "auto") {
+#	$self->{'input_encoding'} = "utf8";
+#    }
+
+    my $secondary_plugin_options = $self->{'secondary_plugin_options'};
+    if (defined $self->{'windows_scripting'}) { 
+	if (!defined $secondary_plugin_options->{'StructuredHTMLPlugin'}){
+	    $secondary_plugin_options->{'StructuredHTMLPlugin'} = [];
+	    my $structhtml_options = $secondary_plugin_options->{'StructuredHTMLPlugin'};
+	    
+	    # Instruct HTMLPlugin (when eventually accessed through read_into_doc_obj)
+	    # to extract these metadata fields from the HEAD META fields
+	    push (@$structhtml_options, "-metadata_fields","Title,GENERATOR,date,author<Creator>");
+	    push (@$structhtml_options, "-title_sub", '^(Page\s+\d+)?(\s*1\s+)?');
+	    push (@$structhtml_options, "-description_tags") if $self->{'windows_scripting'};
+	    push (@$structhtml_options, "-extract_language") if $self->{'extract_language'};
+	    push (@$structhtml_options, "-delete_toc") if $self->{'delete_toc'};
+	    push (@$structhtml_options, "-toc_header", $self->{'toc_header'}) if $self->{'toc_header'};
+	    push (@$structhtml_options, "-title_header", $self->{'title_header'}) if $self->{'title_header'};
+	    push (@$structhtml_options, "-level1_header", $self->{'level1_header'}) if $self->{'level1_header'};
+	    push (@$structhtml_options, "-level2_header", $self->{'level2_header'})if $self->{'level2_header'};
+	    push (@$structhtml_options, "-level3_header", $self->{'level3_header'}) if $self->{'level3_header'};
+	    push (@$structhtml_options, "-metadata_fields", $self->{'metadata_fields'}) if $self->{'metadata_fields'};
+	}
+    }
+    if (!defined $secondary_plugin_options->{'HTMLPlugin'}) {
+	$secondary_plugin_options->{'HTMLPlugin'} = [];
+    }
+    if (!defined $secondary_plugin_options->{'TextPlugin'}) {
+	$secondary_plugin_options->{'TextPlugin'} = [];
+    }
+
+    my $html_options = $secondary_plugin_options->{'HTMLPlugin'};
+    my $text_options = $secondary_plugin_options->{'TextPlugin'};
+    my $structhtml_options = $secondary_plugin_options->{'StructuredHTMLPlugin'};    
+    # wvWare will always produce html files encoded as utf-8, so make sure the secondary HTMLPlugin knows this
+    push(@$html_options,"-input_encoding", "utf8");
+    push(@$html_options,"-extract_language") if $self->{'extract_language'};
+    push(@$html_options, "-description_tags") if $self->{'description_tags'};
+
+    # Instruct HTMLPlugin (when eventually accessed through read_into_doc_obj)
+    # to extract these metadata fields from the HEAD META fields
+    push(@$html_options,"-metadata_fields","Title,GENERATOR,date,author<Creator>");
+    push(@$html_options , "-title_sub", '^(Page\s+\d+)?(\s*1\s+)?');
+
+    my $associate_tail_re = $self->{'associate_tail_re'};
+    if ((defined $associate_tail_re) && ($associate_tail_re ne "")) {
+	push(@$html_options, "-associate_tail_re", $associate_tail_re);
+	push(@$text_options, "-associate_tail_re", $associate_tail_re);
+	push(@$structhtml_options, "-associate_tail_re", $associate_tail_re) if defined $structhtml_options;
+    }
+
+    push(@$html_options, "-file_rename_method", "none");
+    push(@$text_options, "-file_rename_method", "none");
+    push(@$structhtml_options, "-file_rename_method", "none") if defined $structhtml_options;
+
+    $self = bless $self, $class;
+    $self->load_secondary_plugins($class,$secondary_plugin_options,$hashArgOptLists);
+
+    return bless $self;
+}
+
+sub get_default_process_exp {
+    my $self = shift (@_);
+
+    return q^(?i)\.(doc|dot)$^;
+}
+
+sub convert_post_process_old
+{
+    my $self = shift (@_);
+    my ($conv_filename) = @_;
+
+    my $outhandle=$self->{'outhandle'};
+     
+    my ($language, $encoding) = $self->textcat_get_language_encoding ($conv_filename);
+
+    # read in file ($text will be in utf8)
+    my $text = "";
+    $self->read_file ($conv_filename, $encoding, $language, \$text);
+
+    # turn any high bytes that aren't valid utf-8 into utf-8.
+    #unicode::ensure_utf8(\$text);
+    
+    # Write it out again!
+    #$self->utf8_write_file (\$text, $conv_filename);
+}
+
+# Modified to cache HTML files for efficieny reasons rather
+# than delete all.  HTML is modified not to use IE's VML.
+# VML uses WML files, so these can be deleted.
+sub cleanup_tmp_area {
+    my ($self) = @_;
+    if (defined $self->{'files_dir'}) {
+	my $html_files_dir = $self->{'files_dir'};
+
+	if (opendir(DIN,$html_files_dir)) {
+	    my @wmz_files = grep( /\.wmz$/, readdir(DIN));
+	    foreach my $f (@wmz_files) {
+		my $full_f = &util::filename_cat($html_files_dir,$f);
+		&util::rm($full_f);
+	    }
+	    closedir(DIN);
+	}
+	else {
+	    # if HTML file has no supporting images, then no _files dir made
+	    # => do nothing
+	}
+    }
+}
+
+
+1;
+
Index: /gsdl/stable/perllib/plugins/ZIPPlugin.pm
===================================================================
--- /gsdl/stable/perllib/plugins/ZIPPlugin.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugins/ZIPPlugin.pm	(revision 20131)
@@ -0,0 +1,190 @@
+###########################################################################
+#
+# ZIPPlugin.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# plugin which handles compressed and/or archived input formats
+#
+# currently handled formats and file extensions are:
+# 
+# gzip (.gz, .z, .tgz, .taz)
+# bzip (.bz)
+# bzip2 (.bz2)
+# zip (.zip .jar)
+# tar (.tar)
+#
+# this plugin relies on the following utilities being present 
+# (if trying to process the corresponding formats)
+#
+# gunzip (for gzip)
+# bunzip (for bzip)
+# bunzip2 
+# unzip (for zip)
+# tar (for tar) 
+
+
+package ZIPPlugin;
+
+use BasePlugin;
+use plugin;
+use util;
+use Cwd;
+
+use strict;
+no strict 'refs'; # allow filehandles to be variables and viceversa
+
+BEGIN {
+    @ZIPPlugin::ISA = ('BasePlugin');
+}
+
+my $arguments =
+    [ { 'name' => "process_exp",
+	'desc' => "{BasePlugin.process_exp}",
+	'type' => "string",
+	'deft' => &get_default_process_exp(),
+	'reqd' => "no" } ];
+
+my $options = { 'name'     => "ZIPPlugin",
+		'desc'     => "{ZIPPlugin.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+		'args'     => $arguments };
+
+sub new {
+
+    my ($class) = shift (@_);
+    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
+    push(@$pluginlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
+
+    return bless $self, $class;
+}
+
+# this is a recursive plugin
+sub is_recursive {
+    my $self = shift (@_);
+
+    return 1;
+}
+
+sub get_default_process_exp {
+    return q^(?i)\.(gz|tgz|z|taz|bz|bz2|zip|jar|tar)$^;
+}
+
+# return number of files processed, undef if can't process
+# Note that $base_dir might be "" and that $file might 
+# include directories
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
+    my $outhandle = $self->{'outhandle'};
+
+    # can we process this file??
+    my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
+    return undef unless $self->can_process_this_file($filename_full_path);
+	
+    my $tmpdir = &util::get_tmp_filename ();
+    &util::mk_all_dir ($tmpdir);
+    
+    print $outhandle "ZIPPlugin: extracting $filename_no_path to $tmpdir\n"
+	if $self->{'verbosity'} > 1;
+    
+    # save current working directory
+    my $cwd = cwd();
+    chdir ($tmpdir) || die "Unable to change to $tmpdir";
+    &util::cp ($filename_full_path, $tmpdir);
+    
+    if ($file =~ /\.bz$/i) {
+	$self->bunzip ($filename_no_path);
+    } elsif ($file =~ /\.bz2$/i) {
+	$self->bunzip2 ($filename_no_path);
+    } elsif ($file =~ /\.(zip|jar)$/i) {
+	$self->unzip ($filename_no_path);
+    } elsif ($file =~ /\.tar$/i) {
+	$self->untar ($filename_no_path);
+    } else {
+	$self->gunzip ($filename_no_path);
+    }
+    
+    chdir ($cwd) || die "Unable to change back to $cwd";
+    
+    my $numdocs = &plugin::read ($pluginfo, "", $tmpdir, $block_hash, $metadata, $processor, $maxdocs, $total_count, $gli);
+    &util::rm_r ($tmpdir);
+    
+    $self->{'num_archives'} ++;
+    
+    return $numdocs;
+    
+}
+
+sub bunzip {
+    my $self = shift (@_);
+    my ($file) = @_;
+
+    if (system ("bunzip \"$file\"")!=0)
+    {
+	&util::rm ($file);
+    }
+}
+
+sub bunzip2 {
+    my $self = shift (@_);
+    my ($file) = @_;
+
+    if (system ("bunzip2 \"$file\"")!=0)
+    {
+	&util::rm ($file);
+    }
+}
+
+sub unzip {
+    my $self = shift (@_);
+    my ($file) = @_;
+
+    system ("unzip \"$file\"");
+    &util::rm ($file) if -e $file;
+}
+
+sub untar {
+    my $self = shift (@_);
+    my ($file) = @_;
+
+    system ("tar xf \"$file\"");
+    &util::rm ($file) if -e $file;
+}
+
+sub gunzip {
+    my $self = shift (@_);
+    my ($file) = @_;
+
+    if (system ("gunzip \"$file\"")!=0)
+    {
+	&util::rm ($file);
+    };
+}
+
+1;
Index: /gsdl/stable/perllib/plugout.pm
===================================================================
--- /gsdl/stable/perllib/plugout.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugout.pm	(revision 20131)
@@ -0,0 +1,84 @@
+###########################################################################
+#
+# plugout.pm -- functions to handle using plugouts
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package plugout;
+
+use strict; # to pick up typos and undeclared variables...
+no strict 'refs'; # ...but allow filehandles to be variables and vice versa
+no strict 'subs';
+
+require util;
+use gsprintf 'gsprintf';
+
+# global variables
+my $stats = {'num_processed' => 0,
+	     'num_blocked' => 0,
+	     'num_not_processed' => 0,
+	     'num_not_recognised' => 0,
+	     'num_archives' => 0
+	     };
+
+#globaloptions contains any options that should be passed to all plugouts
+my ($verbosity, $outhandle, $failhandle, $globaloptions);
+
+sub load_plugout{
+    my ($plugout) = shift @_;
+
+    my $colplugdir = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"perllib/plugouts");
+    unshift (@INC, $colplugdir); 
+    
+    my $plugoutname = shift @$plugout;
+
+    # find the plugout
+    my $customplugname;
+    if (defined($ENV{'GSDLCOLLECTION'}))
+    {
+        $customplugname = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, "custom", $ENV{'GSDLCOLLECTION'}, 
+						 'perllib', 'plugouts', "${plugoutname}.pm");
+    }
+
+    my $colplugname = &util::filename_cat($ENV{'GSDLCOLLECTDIR'}, 'perllib', 'plugouts', 
+					  "${plugoutname}.pm");
+    my $mainplugname = &util::filename_cat($ENV{'GSDLHOME'}, 'perllib', 'plugouts',
+					  "${plugoutname}.pm");
+    if (defined($customplugname) && -e $customplugname) { require $customplugname; }
+    elsif (-e $colplugname) { require $colplugname; }
+    elsif (-e $mainplugname) { require $mainplugname; }
+    else {
+	gsprintf($outhandle, "{plugout.could_not_find_plugout}\n",
+		 $plugoutname);
+	    die "\n";
+    }
+
+    # create a plugout object
+    my ($plugobj);
+
+    eval ("\$plugobj = new \$plugoutname([],\$plugout)");
+    die "$@" if $@;
+
+    return $plugobj;
+}
+
+1;
Index: /gsdl/stable/perllib/plugouts/BasePlugout.pm
===================================================================
--- /gsdl/stable/perllib/plugouts/BasePlugout.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugouts/BasePlugout.pm	(revision 20131)
@@ -0,0 +1,1069 @@
+###########################################################################
+#
+# BasePlugout.pm -- base class for all the plugout modules
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package BasePlugout;
+
+eval {require bytes};
+
+use strict;
+no strict 'subs';
+no strict 'refs';
+
+use gsprintf 'gsprintf';
+use printusage;
+use parse2;
+use GDBMUtils;
+
+
+# suppress the annoying "subroutine redefined" warning that various
+# gets cause under perl 5.6
+$SIG{__WARN__} = sub {warn($_[0]) unless ($_[0] =~ /Subroutine\s+\S+\sredefined/)};
+
+my $arguments = [ 
+       { 'name' => "group_size", 
+	'desc' => "{BasPlugout.group_size}",
+	'type' => "int",
+        'deft' =>  "1",
+	'reqd' => "no",
+	'hiddengli' => "no"},
+       { 'name' => "output_info", 
+	'desc' => "{BasPlugout.output_info}",
+	'type' => "string",   
+	'reqd' => "yes",
+	'hiddengli' => "yes"},        
+       { 'name' => "xslt_file", 
+	'desc' => "{BasPlugout.xslt_file}",
+	'type' => "string",
+	'reqd' => "no",
+	'hiddengli' => "no"},
+       { 'name' => "output_handle", 
+	'desc' => "{BasPlugout.output_handle}",
+	'type' => "string",
+        'deft' =>  'STDERR',
+	'reqd' => "no",
+	'hiddengli' => "yes"},
+       { 'name' => "verbosity", 
+	'desc' => "{BasPlugout.verbosity}",
+	'type' => "int",
+        'deft' =>  "0",
+	'reqd' => "no",  
+     	'hiddengli' => "no"},
+       { 'name' => "gzip_output", 
+	'desc' => "{BasPlugout.gzip_output}",
+	'type' => "flag",
+	'reqd' => "no",  
+     	'hiddengli' => "no"},
+       { 'name' => "debug",
+	 'desc' => "{BasPlugout.debug}",
+	 'type' => "flag",
+	 'reqd' => "no",
+	 'hiddengli' => "yes"}
+];
+
+my $options = { 'name'     => "BasePlugout",
+		'desc'     => "{BasPlugout.desc}",
+		'abstract' => "yes",
+		'inherits' => "no",
+		'args'     => $arguments};
+
+sub new 
+{
+    my $class = shift (@_);
+
+    my ($plugoutlist,$args,$hashArgOptLists) = @_;
+    push(@$plugoutlist, $class);
+
+    my $strPlugoutName = (defined $plugoutlist->[0]) ? $plugoutlist->[0] : $class;
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = {};
+    $self->{'plugout_type'} = $class;
+    $self->{'option_list'} = $hashArgOptLists->{"OptList"};
+    $self->{"info_only"} = 0;
+
+    # Check if gsdlinfo is in the argument list or not - if it is, don't parse 
+    # the args, just return the object.  
+    foreach my $strArg (@{$args})
+    {
+	if(defined $strArg && $strArg eq "-gsdlinfo")
+	{
+	    $self->{"info_only"} = 1;
+	    return bless $self, $class;
+	}
+    }
+    
+    delete $self->{"info_only"};
+    
+    if(parse2::parse($args,$hashArgOptLists->{"ArgList"},$self) == -1)
+    {
+	my $classTempClass = bless $self, $class;
+	print STDERR "<BadPlugout d=$self->{'plugout_name'}>\n";
+	&gsprintf(STDERR, "\n{BasPlugout.bad_general_option}\n", $self->{'plugout_name'});
+	$classTempClass->print_txt_usage("");  # Use default resource bundle
+	die "\n";
+    }
+
+ 
+    if(defined $self->{'xslt_file'} &&  $self->{'xslt_file'} ne "")
+    {
+      ##$self->{'xslt_file'} =~ s/\"//g;##working on Windows???
+	print STDERR "Can not find $self->{'xslt_file'}, please make sure you have supplied the correct file path\n" and  die "\n" unless (-e $self->{'xslt_file'});
+    }
+
+    $self->{'gs_count'} = 0;    
+
+    $self->{'keep_import_structure'} = 0; 
+
+    return bless $self, $class;
+
+}
+
+sub print_xml_usage
+{
+    my $self = shift(@_);
+    my $header = shift(@_);
+    my $high_level_information_only = shift(@_);
+    
+    # XML output is always in UTF-8
+    gsprintf::output_strings_in_UTF8;
+
+    if ($header) {
+	&PrintUsage::print_xml_header("plugout");
+    }
+    $self->print_xml($high_level_information_only);
+}
+
+
+sub print_xml
+{
+    my $self = shift(@_);
+    my $high_level_information_only = shift(@_);
+
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $plugoutoptions = shift(@$optionlistref);
+    return if (!defined($plugoutoptions));
+
+    gsprintf(STDERR, "<PlugoutInfo>\n");
+    gsprintf(STDERR, "  <Name>$plugoutoptions->{'name'}</Name>\n");
+    my $desc = gsprintf::lookup_string($plugoutoptions->{'desc'});
+    $desc =~ s/</&amp;lt;/g; # doubly escaped
+    $desc =~ s/>/&amp;gt;/g;
+    gsprintf(STDERR, "  <Desc>$desc</Desc>\n");
+    gsprintf(STDERR, "  <Abstract>$plugoutoptions->{'abstract'}</Abstract>\n");
+    gsprintf(STDERR, "  <Inherits>$plugoutoptions->{'inherits'}</Inherits>\n");
+    unless (defined($high_level_information_only)) {
+	gsprintf(STDERR, "  <Arguments>\n");
+	if (defined($plugoutoptions->{'args'})) {
+	    &PrintUsage::print_options_xml($plugoutoptions->{'args'});
+	}
+	gsprintf(STDERR, "  </Arguments>\n");
+
+	# Recurse up the plugout hierarchy
+	$self->print_xml();
+    }
+    gsprintf(STDERR, "</PlugoutInfo>\n");
+}
+
+
+sub print_txt_usage
+{
+    my $self = shift(@_);
+
+    # Print the usage message for a plugout (recursively)
+    my $descoffset = $self->determine_description_offset(0);
+    $self->print_plugout_usage($descoffset, 1);
+}
+
+sub determine_description_offset
+{
+    my $self = shift(@_);
+    my $maxoffset = shift(@_);
+
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $plugoutoptions = pop(@$optionlistref);
+    return $maxoffset if (!defined($plugoutoptions));
+
+    # Find the length of the longest option string of this download
+    my $plugoutargs = $plugoutoptions->{'args'};
+    if (defined($plugoutargs)) {
+	my $longest = &PrintUsage::find_longest_option_string($plugoutargs);
+	if ($longest > $maxoffset) {
+	    $maxoffset = $longest;
+	}
+    }
+
+    # Recurse up the download hierarchy
+    $maxoffset = $self->determine_description_offset($maxoffset);
+    $self->{'option_list'} = \@optionlist;
+    return $maxoffset;
+}
+
+
+sub print_plugout_usage
+{
+    my $self = shift(@_);
+    my $descoffset = shift(@_);
+    my $isleafclass = shift(@_);
+
+    my $optionlistref = $self->{'option_list'};
+    my @optionlist = @$optionlistref;
+    my $plugoutoptions = shift(@$optionlistref);
+    return if (!defined($plugoutoptions));
+
+    my $plugoutname = $plugoutoptions->{'name'};
+    my $plugoutargs = $plugoutoptions->{'args'};
+    my $plugoutdesc = $plugoutoptions->{'desc'};
+
+    # Produce the usage information using the data structure above
+    if ($isleafclass) {
+	if (defined($plugoutdesc)) {
+	    gsprintf(STDERR, "$plugoutdesc\n\n");
+	}
+	gsprintf(STDERR, " {common.usage}: plugout $plugoutname [{common.options}]\n\n");
+    }
+
+    # Display the download options, if there are some
+    if (defined($plugoutargs)) {
+	# Calculate the column offset of the option descriptions
+	my $optiondescoffset = $descoffset + 2;  # 2 spaces between options & descriptions
+
+	if ($isleafclass) {
+	    gsprintf(STDERR, " {common.specific_options}:\n");
+	}
+	else {
+	    gsprintf(STDERR, " {common.general_options}:\n", $plugoutname);
+	}
+
+	# Display the download options
+	&PrintUsage::print_options_txt($plugoutargs, $optiondescoffset);
+    }
+
+    # Recurse up the download hierarchy
+    $self->print_plugout_usage($descoffset, 0);
+    $self->{'option_list'} = \@optionlist;
+}
+
+
+sub error
+{
+      my ($strFunctionName,$strError) = @_;
+    {
+	print "Error occoured in BasePlugout.pm\n".
+	    "In Function: ".$strFunctionName."\n".
+	    "Error Message: ".$strError."\n";
+	exit(-1);
+    }  
+}
+
+# OIDtype may be "hash" or "incremental" or "dirname" or "assigned"
+sub set_OIDtype {
+    my $self = shift (@_);
+    my ($type, $metadata) = @_;
+
+    if ($type =~ /^(hash|incremental|dirname|assigned)$/) {
+	$self->{'OIDtype'} = $type;
+    } else {
+	$self->{'OIDtype'} = "hash";
+    }
+    if ($type =~ /^assigned$/) {
+	if (defined $metadata) {
+	    $self->{'OIDmetadata'} = $metadata;
+	} else {
+	    $self->{'OIDmetadata'} = "dc.Identifier";
+	}
+    }
+}
+
+sub set_output_dir 
+{
+    my $self = shift @_;
+    my ($output_dir) = @_;
+
+   $self->{'output_dir'} = $output_dir;
+}
+
+sub setoutputdir 
+{
+    my $self = shift @_;
+    my ($output_dir) = @_;
+
+    $self->{'output_dir'} = $output_dir;
+}
+
+sub get_output_dir 
+{
+    my $self = shift (@_);
+
+   return $self->{'output_dir'};
+}
+
+sub getoutputdir 
+{
+    my $self = shift (@_);
+
+    return $self->{'output_dir'};
+}
+
+sub getoutputinfo 
+{
+    my $self = shift (@_);
+
+    return $self->{'output_info'};
+}
+
+
+sub get_output_handler
+{
+    my $self = shift (@_);
+
+    my ($output_file_name) = @_;
+     
+    open(*OUTPUT, ">$output_file_name") or die "Can not open a file handler for  $output_file_name\n";
+
+    return *OUTPUT;            
+}
+
+sub release_output_handler
+{
+    my $self = shift (@_);
+    my ($outhandler) = @_;
+
+    close($outhandler);
+
+}
+
+sub output_xml_header {
+    my $self = shift (@_);
+    my ($handle,$docroot,$nondoctype) = @_;
+    
+    print $handle '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n";
+   
+    if (!defined $nondoctype){
+	print $handle '<!DOCTYPE Archive SYSTEM "http://greenstone.org/dtd/Archive/1.0/Archive.dtd">' . "\n";
+    }
+
+    print $handle "<$docroot>\n" if defined $docroot;
+}
+
+sub output_xml_footer {
+    my $self = shift (@_);
+    my ($handle,$docroot) = @_;
+    print $handle "</$docroot>\n" if defined $docroot;
+}
+
+sub process {
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+    
+    $doc_obj->set_lastmodified();
+
+     if ($self->{'group_size'} > 1) {
+	 $self->group_process ($doc_obj);
+	return;
+    }
+
+    my $OID = $doc_obj->get_OID();
+    $OID = "NULL" unless defined $OID;     
+
+    my $top_section = $doc_obj->get_top_section();
+
+    #get document's directory
+    my $doc_dir = $self->get_doc_dir ($OID, $doc_obj->get_source_filename());
+    
+    my $output_info = $self->{'output_info'};
+    return if (!defined $output_info);
+     
+    ##############################
+    # call subclass' saveas method
+    ##############################
+    $self->saveas($doc_obj,$doc_dir);
+    $self->archiveinf_gdbm($doc_obj,$doc_dir); 
+
+}
+
+sub store_output_info_reference {
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+
+    my $output_info = $self->{'output_info'};
+    my $metaname = $self->{'sortmeta'};
+    if (!defined $metaname || $metaname !~ /\S/) {
+	$output_info->add_info($doc_obj->get_OID(),$self->{'short_doc_file'}, undef, "");
+	return;
+    }
+    
+    my $metadata = "";
+    my $top_section = $doc_obj->get_top_section();
+    
+    my @commameta_list = split(/,/, $metaname);
+    foreach my $cmn (@commameta_list) {
+	my $meta = $doc_obj->get_metadata_element($top_section, $cmn);
+	if ($meta) {
+	    # do remove prefix/suffix - this will apply to all values
+	    $meta =~ s/^$self->{'removeprefix'}// if defined $self->{'removeprefix'};	       
+	    $meta =~ s/$self->{'removesuffix'}$// if defined $self->{'removesuffix'};
+	    $meta = &sorttools::format_metadata_for_sorting($cmn, $meta, $doc_obj);
+	    $metadata .= $meta if ($meta);
+	}
+    }
+
+    # store reference in the output_info     
+    $output_info->add_info($doc_obj->get_OID(),$self->{'short_doc_file'}, undef, $metadata);
+    
+}
+
+sub group_process {
+
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+    
+    my $OID = $doc_obj->get_OID(); 
+    $OID = "NULL" unless defined $OID;
+
+    my $groupsize = $self->{'group_size'};
+    my $gs_count = $self->{'gs_count'};
+    my $open_new_file = (($gs_count % $groupsize)==0);
+    my $outhandle = $self->{'output_handle'};
+
+    # opening a new file, or document has assoicated files => directory needed
+    if (($open_new_file) || (scalar(@{$doc_obj->get_assoc_files()})>0)) {
+		  
+        # The directory the archive file (doc.xml) and all associated files
+        # should end up in
+        my $doc_dir;
+        # If we've determined its time for a new file, open it now
+        if ($open_new_file || !defined($self->{'gs_doc_dir'}))
+          {
+            $doc_dir = $self->get_doc_dir ($OID, $doc_obj->get_source_filename());
+            # only if opening new file
+	    my $output_dir = $self->get_output_dir();
+	    &util::mk_all_dir ($output_dir) unless -e $output_dir;
+	    my $doc_file = &util::filename_cat ($output_dir, $doc_dir, "doc.xml");
+	    my $short_doc_file = &util::filename_cat ($doc_dir, "doc.xml");
+	    
+	    if ($gs_count>0)
+	    {
+		return if (!$self->close_file_output());
+	    }
+
+	    open (GROUPPROCESS, ">$doc_file") or (print $outhandle "BasePlugout::group_process could not write to file $doc_file\n" and return);
+		    
+
+	    $self->{'gs_filename'} = $doc_file;
+	    $self->{'short_doc_file'} = $short_doc_file;
+	    $self->{'gs_OID'} = $OID;
+            $self->{'gs_doc_dir'} = $doc_dir;
+
+	    $self->output_xml_header('BasePlugout::GROUPPROCESS','Archive');
+	}
+        # Otherwise load the same archive document directory used last time
+        else
+          {
+            $doc_dir = $self->{'gs_doc_dir'};
+          }
+
+	# copy all the associated files, add this information as metadata
+	# to the document
+        print $outhandle "Writing associated files to $doc_dir\n";
+	$self->process_assoc_files ($doc_obj, $doc_dir);
+
+	# look up 'gsdlmetafile' metadata and store that information
+	# explicitly in $doc_obj
+	$self->process_metafiles_metadata ($doc_obj);
+    }
+
+    # save this document
+    my $section_text = &docprint::get_section_xml($doc_obj,$doc_obj->get_top_section());
+    print GROUPPROCESS $section_text;
+
+    $self->{'gs_count'}++;
+}
+
+
+sub saveas {
+    my $self = shift (@_);
+   
+    die "Basplug::saveas function must be implemented in sub classes\n";
+}
+
+sub get_doc_dir {
+    my $self = shift (@_);
+    my ($OID, $source_filename) = @_;
+
+    my $working_dir  = $self->get_output_dir();
+    my $working_info = $self->{'output_info'}; 
+    return if (!defined $working_info);
+
+    my $doc_info = $working_info->get_info($OID);
+    my $doc_dir = '';
+
+    if (defined $doc_info && scalar(@$doc_info) >= 1)
+    {
+	# This OID already has an archives directory, so use it again
+	$doc_dir = $doc_info->[0];
+	$doc_dir =~ s/\/?((doc(mets)?)|(dublin_core))\.xml(\.gz)?$//;
+    }
+    elsif ($self->{'keep_import_structure'})
+    {
+	$source_filename = &File::Basename::dirname($source_filename);
+	$source_filename =~ s/[\\\/]+/\//g;
+	$source_filename =~ s/\/$//;
+
+      	$doc_dir = substr($source_filename, length($ENV{'GSDLIMPORTDIR'}) + 1);
+    }
+
+    # We have to use a new archives directory for this document
+    if ($doc_dir eq "")
+    {
+	$doc_dir = $self->get_new_doc_dir ($working_info, $working_dir, $OID);
+    }
+
+    if (!defined $self->{'group'} || !$self->{'group'}){
+	&util::mk_all_dir (&util::filename_cat ($working_dir, $doc_dir));
+    }
+
+    return $doc_dir;
+}
+
+sub get_new_doc_dir{
+   my $self = shift (@_);  
+   my($working_info,$working_dir,$OID) = @_;      
+   
+   
+   my $doc_dir = "";
+   my $doc_dir_rest = $OID;
+   # remove any \ and / from the OID
+   $doc_dir_rest =~ s/[\\\/]//g;
+   my $doc_dir_num = 0;
+
+   do {
+       $doc_dir .= "/" if $doc_dir_num > 0;
+       if ($doc_dir_rest =~ s/^(.{1,8})//) {
+	   $doc_dir .= $1;
+	   $doc_dir_num++;
+       }
+   } while ($doc_dir_rest ne "" && 
+	    ((-d &util::filename_cat ($working_dir, "$doc_dir.dir")) || 
+	     ($working_info->size() >= 1024 && $doc_dir_num < 2)));
+   my $i = 1;
+   my $doc_dir_base = $doc_dir;
+   while (-d &util::filename_cat ($working_dir, "$doc_dir.dir")) {
+       $doc_dir = "$doc_dir_base-$i";
+       $i++;
+   }
+          
+   return "$doc_dir.dir";
+}
+
+sub process_assoc_files {
+    my $self = shift (@_);
+    my ($doc_obj, $doc_dir, $handle) = @_;
+
+    my $outhandle = $self->{'output_handle'};
+    
+    my $output_dir = $self->get_output_dir();
+    return if (!defined $output_dir);
+
+    &util::mk_all_dir ($output_dir) unless -e $output_dir;
+      
+    my $working_dir = &util::filename_cat($output_dir, $doc_dir);
+    &util::mk_all_dir ($working_dir) unless -e $working_dir;
+
+    my @assoc_files = ();
+    my $filename;;
+
+    my $source_filename = $doc_obj->get_source_filename();
+
+    my $collect_dir = $ENV{'GSDLCOLLECTDIR'};
+
+    if (defined $collect_dir) {
+	my $dirsep_regexp = &util::get_os_dirsep();
+
+	if ($collect_dir !~ /$dirsep_regexp$/) {
+	    $collect_dir .= &util::get_dirsep(); # ensure there is a slash at the end
+	}
+
+	# This test is never going to fail on Windows -- is this a problem?
+     
+	if ($source_filename !~ /^$dirsep_regexp/) {
+	    $source_filename = &util::filename_cat($collect_dir, $source_filename);
+	}
+    }
+
+
+    # set the assocfile path (even if we have no assoc files - need this for lucene)
+    $doc_obj->set_utf8_metadata_element ($doc_obj->get_top_section(),
+					 "assocfilepath",
+					 "$doc_dir");
+    foreach my $assoc_file_rec (@{$doc_obj->get_assoc_files()}) {
+	my ($dir, $afile) = $assoc_file_rec->[1] =~ /^(.*?)([^\/\\]+)$/;
+	$dir = "" unless defined $dir;
+	    
+	
+	my $real_filename = $assoc_file_rec->[0];
+	# for some reasons the image associate file has / before the full path
+	$real_filename =~ s/^\\(.*)/$1/i;
+	if (-e $real_filename) {
+
+	    $filename = &util::filename_cat($working_dir, $afile);
+
+	    &util::hard_link ($real_filename, $filename, $self->{'verbosity'});
+	    
+	    $doc_obj->add_utf8_metadata ($doc_obj->get_top_section(),
+					 "gsdlassocfile",
+					 "$afile:$assoc_file_rec->[2]:$dir");
+	} elsif ($self->{'verbosity'} > 2) {
+	    print $outhandle "BasePlugout::process couldn't copy the associated file " .
+		"$real_filename to $afile\n";
+	}
+    }
+}
+
+
+sub process_metafiles_metadata 
+{
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+
+    my $top_section = $doc_obj->get_top_section();
+    my $metafiles = $doc_obj->get_metadata($top_section,"gsdlmetafile");
+
+    foreach my $metafile_pair (@$metafiles) {
+	my ($full_metafile,$metafile) = split(/ : /,$metafile_pair);
+
+	$doc_obj->metadata_file($full_metafile,$metafile);
+    }
+
+    $doc_obj->delete_metadata($top_section,"gsdlmetafile");
+}
+
+sub archiveinf_files_to_field
+{
+    my $self = shift(@_);
+    my ($files,$field,$collect_dir,$oid_files,$reverse_lookups) = @_;
+
+    foreach my $file_rec (@$files) {
+	my $real_filename = $file_rec->[0];
+	my $full_file = $file_rec->[1];
+
+	# for some reasons the image associate file has / before the full path
+	$real_filename =~ s/^\\(.*)/$1/i;
+	if (-e $real_filename) {
+
+	    if (defined $collect_dir) {
+		my $collect_dir_re_safe = $collect_dir;
+		$collect_dir_re_safe =~ s/\\/\\\\/g;
+		$collect_dir_re_safe =~ s/\./\\./g;
+
+		$real_filename =~ s/^$collect_dir_re_safe//;
+	    }
+
+	    $reverse_lookups->{$real_filename} = 1;
+
+	    push(@{$oid_files->{$field}},$full_file);
+	}
+	else {
+	    print STDERR "Warning: archiveinf_files_to_field()\n  $real_filename does not appear to be on the file system\n";
+	}
+    }
+}
+
+sub archiveinf_gdbm
+{
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+
+    my $verbosity = $self->{'verbosity'};
+
+    my $collect_dir = $ENV{'GSDLCOLLECTDIR'};
+    if (defined $collect_dir) {
+	my $dirsep_regexp = &util::get_os_dirsep();
+
+	if ($collect_dir !~ /$dirsep_regexp$/) {
+	    # ensure there is a slash at the end
+	    $collect_dir .= &util::get_dirsep(); 
+	}
+    }
+
+    my $oid = $doc_obj->get_OID();
+    my $source_filename = $doc_obj->get_unmodified_source_filename();
+
+    my $working_info = $self->{'output_info'}; 
+    my $doc_info = $working_info->get_info($oid);
+    my ($doc_file,$index_status) = @$doc_info;
+
+    my $oid_files = { 'doc-file' => $doc_file,
+		      'index-status' => $index_status,
+		      'src-file' => $source_filename,
+		      'assoc-file' => [],
+		      'meta-file'  => [] };
+    
+    my $reverse_lookups = { $source_filename => "1" };
+
+
+    $self->archiveinf_files_to_field($doc_obj->get_assoc_files(),"assoc-file",
+				     $collect_dir,$oid_files,$reverse_lookups);
+
+# ******* 
+#    foreach my $assoc_file_rec (@{$doc_obj->get_assoc_files()}) {
+#	my $real_filename = $assoc_file_rec->[0];
+#	my $full_afile = $assoc_file_rec->[1];
+#
+#	# for some reasons the image associate file has / before the full path
+#	$real_filename =~ s/^\\(.*)/$1/i;
+#	if (-e $real_filename) {
+#
+#	    if (defined $collect_dir) {
+#		my $collect_dir_re_safe = $collect_dir;
+#		$collect_dir_re_safe =~ s/\\/\\\\/g;
+#		$collect_dir_re_safe =~ s/\./\\./g;
+#
+#		$real_filename =~ s/^$collect_dir_re_safe//;
+#	    }
+#
+#	    $reverse_lookups->{$real_filename} = 1;
+#
+#	    push(@{$oid_files->{'assoc-file'}},$full_afile);
+#	}
+#	else {
+#	    print STDERR "Warning: archiveinf_gdbm()\n  $real_filename does not appear to be on the file system\n";
+#	}
+#    }
+
+    $self->archiveinf_files_to_field($doc_obj->get_meta_files(),"meta-file",
+				     $collect_dir,$oid_files,$reverse_lookups);
+
+
+    # better not to commit to a particular db implementation, but
+    # for simplicity, will use GDBM for now.
+
+    my $output_dir = $self->{'output_dir'};
+
+    my $doc_db = &util::filename_cat($output_dir,"archiveinf-doc.gdb");
+    my $src_db = &util::filename_cat($output_dir,"archiveinf-src.gdb");
+
+#    my $doc_db_text = "";
+#    $doc_db_text .= "<doc-file>$oid_files->{'doc-file'}\n";
+#    $doc_db_text .= "<index-status>$oid_files->{'index-status'}\n";
+#    $doc_db_text .= "<src-file>$oid_files->{'src-file'}\n";
+
+#    foreach my $af (@{$oid_files->{'assoc-file'}}) {
+#	$doc_db_text .= "<assoc-file>$af\n";
+#    }
+
+#    foreach my $mf (@{$oid_files->{'meta-file'}}) {
+#	$doc_db_text .= "<meta-file>$mf\n";
+#    }
+
+#    chomp($doc_db_text); # remove trailing \n
+
+    ##print STDERR "*** To set in db: \n\t$doc_db\n\t$oid\n\t$doc_db_text\n";
+
+    ### &GDBMUtils::gdbmDatabaseSet($doc_db,$oid,$doc_db_text);
+
+    # switch to using GDBMUtils
+
+    $oid_files->{'doc-file'} = [ $oid_files->{'doc-file'} ];
+    $oid_files->{'index-status'} = [ $oid_files->{'index-status'} ];
+    $oid_files->{'src-file'} = [ $oid_files->{'src-file'} ];
+
+    my $infodb_file_handle 
+	= &dbutil::open_infodb_write_handle_gdbm($doc_db,"append");
+    &dbutil::write_infodb_entry_gdbm($infodb_file_handle,$oid,$oid_files);
+    &dbutil::close_infodb_write_handle_gdbm($infodb_file_handle);
+
+
+
+    foreach my $rl (keys %$reverse_lookups) {
+	## &GDBMUtils::gdbmDatabaseAppend($src_db,$rl,"<oid>$oid\n");	
+	$working_info->add_reverseinfo($rl,$oid);
+    }    
+}
+
+
+sub set_sortmeta {
+    my $self = shift (@_);
+    my ($sortmeta, $removeprefix, $removesuffix) = @_;
+    
+    $self->{'sortmeta'} = $sortmeta;
+    if (defined ($removeprefix) && $removeprefix ) {
+	$removeprefix =~ s/^\^//; # don't need a leading ^
+	$self->{'removeprefix'} = $removeprefix;
+    }
+    if (defined ($removesuffix) && $removesuffix) {
+	$removesuffix =~ s/\$$//; # don't need a trailing $
+	$self->{'removesuffix'} = $removesuffix;
+    }
+}
+
+sub open_xslt_pipe
+{
+    my $self = shift @_;
+    my ($output_file_name, $xslt_file)=@_;
+
+   return unless defined $xslt_file and $xslt_file ne "" and -e $xslt_file;
+
+    my $java_class_path =  &util::filename_cat ($ENV{'GSDLHOME'},"bin","java");
+
+    my $mapping_file_path = "";
+
+    if ($ENV{'GSDLOS'} eq "windows"){
+	$java_class_path .=";".&util::filename_cat ($ENV{'GSDLHOME'},"bin","java","xalan.jar");
+	$xslt_file = "\"file:///".$xslt_file."\"";
+	$mapping_file_path = "\"file:///";
+    }
+    else{
+	$java_class_path .=":".&util::filename_cat ($ENV{'GSDLHOME'},"bin","java","xalan.jar");
+    }
+
+
+    $java_class_path = "\"".$java_class_path."\"";
+
+    my $cmd = "| java -cp $java_class_path org.nzdl.gsdl.ApplyXSLT -t $xslt_file "; 
+
+    if (defined $self->{'mapping_file'} and $self->{'mapping_file'} ne ""){
+	my $mapping_file_path = "\"".$self->{'mapping_file'}."\""; 
+	$cmd .= "-m $mapping_file_path";
+    }
+
+    open(*XMLWRITER, $cmd)
+	or die "can't open pipe to xslt: $!";
+
+    
+    $self->{'xslt_writer'} = *XMLWRITER;
+
+    print XMLWRITER "<?DocStart?>\n";	    
+    print XMLWRITER "$output_file_name\n";
+
+ 
+  }
+  
+
+sub close_xslt_pipe
+{
+  my $self = shift @_;
+
+  
+  return unless defined $self->{'xslt_writer'} ;
+    
+  my $xsltwriter = $self->{'xslt_writer'};
+  
+  print $xsltwriter "<?DocEnd?>\n";
+  close($xsltwriter);
+
+  undef $self->{'xslt_writer'};
+
+}
+
+sub close_file_output
+{
+    my ($self) = @_;
+ 
+    # make sure that the handle has been opened - it won't be if we failed
+    # to import any documents...
+    if (defined(fileno(GROUPPROCESS))) {
+	$self->output_xml_footer('GROUPPROCESS','Archive');    
+	close GROUPPROCESS;
+    }
+
+    my $OID = $self->{'gs_OID'};
+    my $short_doc_file = $self->{'short_doc_file'};
+   
+    if ($self->{'gzip'}) {
+	my $doc_file = $self->{'gs_filename'};
+	`gzip $doc_file`;
+	$doc_file .= ".gz";
+	$short_doc_file .= ".gz";
+	if (!-e $doc_file) {
+	     my $outhandle = $self->{'output_handle'};
+	    print $outhandle "error while gzipping: $doc_file doesn't exist\n";
+	    return 0;
+	}
+    }
+
+    # store reference in output_info
+    my $output_info = $self->{'output_info'};
+    return 0 if (!defined $output_info);
+    $output_info->add_info($OID, $short_doc_file, undef, undef);
+    return 1;
+}
+
+
+#the subclass should implement this method if is_group method could return 1.
+sub close_group_output{
+   my $self = shift (@_);        
+}
+
+sub is_group {
+    my $self = shift (@_);
+    return 0;        
+}
+
+my $dc_set = { Title => 1,       
+	       Creator => 1, 
+	       Subject => 1, 
+	       Description => 1, 
+	       Publisher => 1, 
+	       Contributor => 1, 
+	       Date => 1, 
+	       Type => 1, 
+	       Format => 1, 
+	       Identifier => 1, 
+	       Source => 1, 
+	       Language => 1, 
+	       Relation => 1, 
+	       Coverage => 1, 
+	       Rights => 1};
+
+
+# returns an XML representation of the dublin core metadata
+# if dc meta is not found, try ex mete
+sub get_dc_metadata {
+    my $self = shift(@_);
+    my ($doc_obj, $section, $version) = @_;
+    
+    # build up string of dublin core metadata
+    $section="" unless defined $section;
+    
+    my $section_ptr = $doc_obj->_lookup_section($section);
+    return "" unless defined $section_ptr;
+
+
+    my $explicit_dc = {};
+    my $explicit_ex = {};
+
+    my $all_text="";
+    foreach my $data (@{$section_ptr->{'metadata'}}){
+	my $escaped_value = &docprint::escape_text($data->[1]);
+	if ($data->[0]=~ m/^dc\./) {
+	    $data->[0] =~ tr/[A-Z]/[a-z]/;
+
+	    $data->[0] =~ m/^dc\.(.*)/;
+	    my $dc_element =  $1;
+
+	    if (!defined $explicit_dc->{$dc_element}) {
+		$explicit_dc->{$dc_element} = [];
+	    }
+	    push(@{$explicit_dc->{$dc_element}},$escaped_value);
+
+	    if (defined $version && ($version eq "oai_dc")) {
+		$all_text .= "   <dc:$dc_element>$escaped_value</dc:$dc_element>\n";
+	    }
+	    else {
+		# qualifier???
+		$all_text .= '   <dcvalue element="'. $dc_element.'">'. $escaped_value. "</dcvalue>\n";
+	    }
+
+	} 
+	elsif (($data->[0] =~ m/^ex\./) || ($data->[0] !~ m/\./)) {
+	    $data->[0] =~ m/^(ex\.)?(.*)/;
+	    my $ex_element =  $2;
+	    my $lc_ex_element = lc($ex_element);
+
+	    if (defined $dc_set->{$ex_element}) {
+		if (!defined $explicit_ex->{$lc_ex_element}) {
+		    $explicit_ex->{$lc_ex_element} = [];
+		}
+		push(@{$explicit_ex->{$lc_ex_element}},$escaped_value);
+	    }
+	}
+    }
+
+    # go through dc_set and for any element *not* defined in explicit_dc
+    # that does exist in explicit_ex, add it in as metadata
+    foreach my $k ( keys %$dc_set ) {
+	my $lc_k = lc($k);
+
+	if (!defined $explicit_dc->{$lc_k}) {
+	    if (defined $explicit_ex->{$lc_k}) {
+
+		foreach my $v (@{$explicit_ex->{$lc_k}}) {
+		    my $dc_element    = $lc_k;
+		    my $escaped_value = $v;
+
+		    if (defined $version && ($version eq "oai_dc")) {
+			$all_text .= "   <dc:$dc_element>$escaped_value</dc:$dc_element>\n";
+		    }
+		    else {
+			$all_text .= '   <dcvalue element="'. $dc_element.'">'. $escaped_value. "</dcvalue>\n";
+		    }
+		    
+		}
+	    }
+	}
+    }
+
+    if ($all_text eq "") {
+	$all_text .= "   There is no Dublin Core metatdata in this document\n";
+    }	
+    $all_text =~ s/[\x00-\x09\x0B\x0C\x0E-\x1F]//g;
+
+    return $all_text;
+}
+
+# Build up dublin_core metadata.  Priority given to dc.* over ex.*
+# This method was apparently added by Jeffrey and committed by Shaoqun.
+# But we don't know why it was added, so not using it anymore.
+sub new_get_dc_metadata {
+    
+    my $self = shift(@_);
+    my ($doc_obj, $section, $version) = @_;
+
+    # build up string of dublin core metadata
+    $section="" unless defined $section;
+    
+    my $section_ptr=$doc_obj->_lookup_section($section);
+    return "" unless defined $section_ptr;
+
+    my $all_text = "";
+    foreach my $data (@{$section_ptr->{'metadata'}}){
+	my $escaped_value = &docprint::escape_text($data->[1]);
+	my $dc_element =  $data->[0];
+	
+	my @array = split('\.',$dc_element);
+	my ($type,$name);
+
+	if(defined $array[1])
+	{
+	    $type = $array[0];
+	    $name = $array[1];
+	}
+	else
+	{
+	    $type = "ex";
+	    $name = $array[0];
+	}
+	
+	$all_text .= '   <Metadata Type="'. $type.'" Name="'.$name.'">'. $escaped_value. "</Metadata>\n";
+    }
+    return $all_text;
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugouts/DSpacePlugout.pm
===================================================================
--- /gsdl/stable/perllib/plugouts/DSpacePlugout.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugouts/DSpacePlugout.pm	(revision 20131)
@@ -0,0 +1,220 @@
+###########################################################################
+#
+# DSpacePlugout.pm -- the plugout module for DSpace archives
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package DSpacePlugout;
+
+use strict;
+no strict 'refs';
+
+eval {require bytes};
+use util;
+use BasePlugout;
+
+sub BEGIN {
+    @DSpacePlugout::ISA = ('BasePlugout');
+}
+
+my $arguments = [];
+
+my $options = { 'name'     => "DSpacePlugout",
+		'desc'     => "{DSpacePlugout.desc}",
+		'abstract' => "no",
+		'inherits' => "yes" };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($plugoutlist, $inputargs,$hashArgOptLists) = @_;
+    push(@$plugoutlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugout($plugoutlist,$inputargs,$hashArgOptLists);    
+    
+    return bless $self, $class;
+}
+
+sub saveas {
+    my $self = shift (@_);
+    my ($doc_obj,$doc_dir) = @_;
+
+    my $output_dir = $self->get_output_dir();
+    &util::mk_all_dir ($output_dir) unless -e $output_dir;
+
+    my $working_dir = &util::filename_cat ($output_dir, $doc_dir);    
+    &util::mk_all_dir ($working_dir, $doc_dir);
+
+    #########################
+    # save the handle file
+    #########################
+    my $outhandle = $self->{'output_handle'};
+  
+    # Genereate handle file 
+    # (Note: this section of code would benefit from being restructured)
+    my $doc_handle_file = &util::filename_cat ($working_dir, "handle");
+    
+    my $env_hp = $ENV{'DSPACE_HANDLE_PREFIX'};
+    my $handle_prefix = (defined $env_hp) ? $env_hp : "123456789";
+
+    my $outhandler =  $self->get_output_handler($doc_handle_file);
+
+    my ($handle) = ($doc_dir =~ m/^(.*)\.dir$/);
+
+    print $outhandler "$handle_prefix/$handle\n";
+    
+    close ($outhandler);
+    
+    #########################
+    # save the content file
+    #########################
+    my $doc_contents_file = &util::filename_cat ($working_dir, "contents");
+    
+    $outhandler =  $self->get_output_handler($doc_contents_file);
+
+    $self->process_assoc_files ($doc_obj, $doc_dir, $outhandler);
+    
+    close($outhandler);
+
+     #############################
+    # save the dublin_core.xml file
+    ###############################
+    my $doc_dc_file = &util::filename_cat ($working_dir, "dublin_core.xml");
+    $self->open_xslt_pipe($doc_dc_file,$self->{'xslt_file'});
+
+    if (defined $self->{'xslt_writer'}){
+	$outhandler = $self->{'xslt_writer'};
+    }
+    else{
+	$outhandler = $self->get_output_handler($doc_dc_file);
+     }
+   
+    $self->output_xml_header($outhandler, "dublin_core",1);
+
+    my $all_text = $self->get_dc_metadata($doc_obj, $doc_obj->get_top_section());
+    print $outhandler $all_text;
+
+    $self->output_xml_footer($outhandler,"dublin_core");
+   
+    if (defined $self->{'xslt_writer'}){     
+	$self->close_xslt_pipe(); 
+    }
+    else{
+	close($outhandler);
+    }
+       
+    $self->{'short_doc_file'} =  &util::filename_cat ($doc_dir, "dublin_core.xml"); 
+    $self->store_output_info_reference($doc_obj);
+}
+
+ sub process_assoc_files {
+    my $self = shift (@_);
+    my ($doc_obj, $doc_dir, $handle) = @_;
+
+    my $outhandler = $self->{'output_handle'};
+    
+    my $output_dir = $self->get_output_dir();
+    return if (!defined $output_dir);
+
+    my $working_dir = &util::filename_cat($output_dir, $doc_dir);
+
+    my @assoc_files = ();
+    my $filename;;
+
+    my $source_filename = $doc_obj->get_source_filename();
+
+    my $collect_dir = $ENV{'GSDLCOLLECTDIR'};
+
+    if (defined $collect_dir) {
+	my $dirsep_regexp = &util::get_os_dirsep();
+
+	if ($collect_dir !~ /$dirsep_regexp$/) {
+	    $collect_dir .= &util::get_dirsep(); # ensure there is a slash at the end
+	}
+
+	# This test is never going to fail on Windows -- is this a problem?
+	if ($source_filename !~ /^$dirsep_regexp/) {
+	    $source_filename = &util::filename_cat($collect_dir, $source_filename);
+	}
+    }
+   
+    my ($tail_filename) = ($source_filename =~ m/\/([^\/\\]*)$/);
+    
+    print $handle "$tail_filename\n";
+    
+    $filename = &util::filename_cat($working_dir, $tail_filename);
+    &util::hard_link ($source_filename, $filename, $self->{'verbosity'});
+             
+    # set the assocfile path (even if we have no assoc files - need this for lucene)
+    $doc_obj->set_utf8_metadata_element ($doc_obj->get_top_section(),
+					 "assocfilepath",
+					 "$doc_dir");
+    foreach my $assoc_file_rec (@{$doc_obj->get_assoc_files()}) {
+	my ($dir, $afile) = $assoc_file_rec->[1] =~ /^(.*?)([^\/\\]+)$/;
+	$dir = "" unless defined $dir;
+	    
+	
+	my $real_filename = $assoc_file_rec->[0];
+	# for some reasons the image associate file has / before the full path
+	$real_filename =~ s/^\\(.*)/$1/i;
+	if (-e $real_filename) {
+
+	    if ($real_filename =~ m/$source_filename$/) {
+		next;
+	    }
+	    else {
+		my $bundle = "bundle:ORIGINAL";
+		
+		if ($afile =~ m/^thumbnail\./) {
+		    $bundle = "bundle:THUMBNAIL";
+		}
+
+		# Store the associated file to the "contents" file
+		print $handle "$assoc_file_rec->[1]\t$bundle\n";
+	    }
+	
+
+	    $filename = &util::filename_cat($working_dir, $afile);
+	    
+	    
+	    &util::hard_link ($real_filename, $filename, $self->{'verbosity'});
+	    
+	    $doc_obj->add_utf8_metadata ($doc_obj->get_top_section(),
+					 "gsdlassocfile",
+					 "$afile:$assoc_file_rec->[2]:$dir");
+	} elsif ($self->{'verbosity'} > 2) {
+	    print $outhandler "DSpacePlugout::process couldn't copy the associated file " .
+		"$real_filename to $afile\n";
+	}
+    }
+}
+                          
+
+sub get_new_doc_dir{
+   my $self = shift (@_);  
+   my($working_info,$working_dir,$OID) = @_; 
+  
+   return $OID;
+
+}
Index: /gsdl/stable/perllib/plugouts/FedoraMETSPlugout.pm
===================================================================
--- /gsdl/stable/perllib/plugouts/FedoraMETSPlugout.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugouts/FedoraMETSPlugout.pm	(revision 20131)
@@ -0,0 +1,705 @@
+###########################################################################
+#
+# FedoraMETSPlugout.pm -- the plugout module for METS archives
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# But WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package FedoraMETSPlugout;
+
+use strict;
+no strict 'refs';
+
+#eval {require bytes};
+#use util;
+use METSPlugout;
+#use docprint; # for escape_text
+
+sub BEGIN {
+    @FedoraMETSPlugout::ISA = ('METSPlugout');
+}
+
+my $arguments = [ 
+      { 'name' => "fedora_namespace", 
+	'desc' => "{FedoraMETSPlugout.fedora_namespace}",
+	'type' => "string",
+        'deft' =>  "greenstone",
+	'reqd' => "no",    
+	'hiddengli' => "no"}
+		  ];
+
+
+
+my $options = { 'name'     => "FedoraMETSPlugout",
+		'desc'     => "{FedoraMETSPlugout.desc}",
+		'abstract' => "no",
+		'inherits' => "yes", 
+	        'args'     => $arguments
+                };
+
+
+sub new 
+{
+    my ($class) = shift (@_);
+    my ($plugoutlist, $inputargs,$hashArgOptLists) = @_;
+    push(@$plugoutlist, $class);
+    
+    
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+    
+    my $self = new METSPlugout($plugoutlist,$inputargs,$hashArgOptLists);
+    
+    return bless $self, $class;
+}
+
+
+sub output_mets_xml_header
+{
+    my $self = shift(@_);
+    my ($handle, $OID, $doc_title) = @_;
+
+    my $fnamespace = $self->{'fedora_namespace'};
+    my $oid_namespace = (defined $fnamespace) ? $fnamespace : "test";
+
+    my $collection = $ENV{'GSDLCOLLECTION'};
+
+    # Might need the following in the schemeLocation attribute for Fedora3
+    #   http://www.fedora.info/definitions/1/0/mets-fedora-ext1-1.xsd
+    my $extra_attr = "OBJID=\"$oid_namespace:$collection-$OID\" TYPE=\"FedoraObject\" LABEL=\"$doc_title\"";
+
+    my $extra_schema = undef;
+
+    if ($ENV{'FEDORA_VERSION'} =~ m/^2/) { # checking if major version is 2
+    	$extra_schema = "http://www.fedora.info/definitions/1/0/mets-fedora-ext.xsd";
+    }
+    else {
+	$extra_attr .= " EXT_VERSION=\"1.1\"";
+    }
+    
+    $self->output_mets_xml_header_extra_attribute($handle,$extra_attr,$extra_schema);
+
+    print $handle '<mets:metsHdr RECORDSTATUS="A"/>'. "\n"; # A = active
+
+}
+
+#
+#  Print out "family" of doctxt.xml files
+#
+
+sub saveas_doctxt_section
+{
+    my $self = shift (@_);
+    my ($doc_obj,$working_dir,$section) = @_;
+
+    my $section_ptr=$doc_obj->_lookup_section($section);
+    return unless defined $section_ptr;
+
+    my $section_fnum ="1". $section;
+    $section_fnum =~ s/\./_/g;
+
+    my $doc_txt_file = &util::filename_cat ($working_dir,"doctxt$section_fnum.xml");	
+	
+    $self->open_xslt_pipe($doc_txt_file,$self->{'xslt_txt'});
+
+    my $outhandler; 
+
+    if (defined $self->{'xslt_writer'}){
+	$outhandler = $self->{'xslt_writer'};
+    }
+    else{
+	$outhandler = $self->get_output_handler($doc_txt_file);
+    } 
+
+    $self->output_xml_header($outhandler);
+    $self->output_txt_section($outhandler,$doc_obj, $section);
+    $self->output_xml_footer($outhandler);
+    
+
+    if (defined $self->{'xslt_writer'}){     
+	$self->close_xslt_pipe(); 
+    }
+    else{
+	close($outhandler);
+    } 
+
+
+    # Output all the subsections as separate files
+    foreach my $subsection (@{$section_ptr->{'subsection_order'}}){
+	
+	$self->saveas_doctxt_section($doc_obj, $working_dir, "$section.$subsection");
+    }
+
+
+}
+
+
+sub saveas_doctxt
+{
+    my $self = shift (@_);
+    my ($doc_obj,$working_dir) = @_;
+
+    my $section = $doc_obj->get_top_section();
+
+    $self->saveas_doctxt_section($doc_obj,$working_dir,$section);
+
+    $self->saveas_toc($doc_obj,$working_dir);
+}
+
+sub buffer_toc
+{
+    my $self = shift (@_);
+    my ($doc_obj,$working_dir,$section,$depth) = @_;
+    
+    my $section_ptr=$doc_obj->_lookup_section($section);
+    return "" unless defined $section_ptr;
+
+    my $all_text = "";
+
+    my $section_num ="1". $section;
+    my $indent = " " x ($depth*2);
+
+    $all_text .= "$indent<Section id=\"$section_num\">\n";
+
+    # Output all the subsections as separate files
+    foreach my $subsection (@{$section_ptr->{'subsection_order'}})
+    {
+	$all_text 
+	    .= $self->buffer_toc($doc_obj, $working_dir, 
+				 "$section.$subsection",$depth+1);
+    }
+
+    $all_text .= "$indent</Section>\n";
+
+    return $all_text;
+}
+
+
+sub saveas_toc
+{
+    my $self = shift (@_);
+    my ($doc_obj,$working_dir) = @_;
+
+    my $section = $doc_obj->get_top_section();
+    my $section_ptr=$doc_obj->_lookup_section($section);
+    my $num_subsections = scalar(@{$section_ptr->{'subsection_order'}});
+
+    # If num_subsections is 0, then there is no nested TOC
+
+    if ($num_subsections>0) {
+
+	my $doc_txt_file = &util::filename_cat ($working_dir,"doctoc.xml");
+	
+	$self->open_xslt_pipe($doc_txt_file,$self->{'xslt_txt'});
+	
+	my $outhandler; 
+	
+	if (defined $self->{'xslt_writer'}){
+	    $outhandler = $self->{'xslt_writer'};
+	}
+	else{
+	    $outhandler = $self->get_output_handler($doc_txt_file);
+	} 
+	print $outhandler $self->buffer_toc($doc_obj, $working_dir, $section, 0);
+	
+	if (defined $self->{'xslt_writer'}){     
+	    $self->close_xslt_pipe(); 
+	}
+	else{
+	    close($outhandler);
+	} 
+    }
+
+}
+
+
+sub buffer_mets_relsext_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj) = @_;
+
+    my $OID = $doc_obj->get_OID();
+
+    my $fnamespace = $self->{'fedora_namespace'};
+    my $oid_namespace = (defined $fnamespace) ? $fnamespace : "test";
+    my $collection = $ENV{'GSDLCOLLECTION'};
+
+    my $fed_id = "$oid_namespace:$collection-$OID";
+
+    my $all_text = "";
+
+    my $top_section = $doc_obj->get_top_section();
+    my $plugin_type = $doc_obj->get_metadata_element($top_section,"Plugin");
+    
+# Images do not get ingested into Fedora when on Linux if the following is included
+# Needs more investigation, since we'd like a working version of the following
+# in order to get thumbnails working and other stuff.
+#    if ((defined $plugin_type) && ($plugin_type eq "ImagePlugin"))
+#    {
+#
+#	$all_text .= "<mets:amdSec ID=\"RELS-EXT\">\n";
+#	$all_text .= "  <mets:techMD ID=\"RELS-EXT1.0\" STATUS=\"A\">\n";
+#	$all_text .= "    <mets:mdWrap LABEL=\"RELS-EXT - RDF formatted relationship metadata\" MDTYPE=\"OTHER\" MIMETYPE=\"text/xml\">\n";
+#	$all_text .= "      <mets:xmlData>\n";
+#	$all_text .= "        <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:fedora-model=\"info:fedora/fedora-system:def/model#\">\n";
+#	$all_text .= "          <rdf:Description rdf:about=\"info:fedora/$fed_id\">\n";
+#	$all_text .= "            <fedora-model:hasContentModel rdf:resource=\"info:fedora/demo:UVA_STD_IMAGE\"/>\n";
+#	$all_text .= "          </rdf:Description>\n";
+#	$all_text .= "        </rdf:RDF>\n";
+#	$all_text .= "      </mets:xmlData>\n";
+#	$all_text .= "    </mets:mdWrap>\n";
+#	$all_text .= "  </mets:techMD>\n";
+#	$all_text .= "</mets:amdSec>\n";
+#    }
+
+    return $all_text;
+}
+
+
+#
+#  Print out docmets.xml file
+#
+sub output_mets_section 
+{
+    my $self = shift(@_);
+    my ($handle, $doc_obj, $section, $working_dir) = @_;
+
+    # print out the dmdSection
+    print $handle $self->buffer_mets_dmdSection_section_xml($doc_obj,$section);
+
+    print $handle $self->buffer_mets_relsext_xml($doc_obj);
+
+    print $handle "<mets:fileSec>\n";
+    print $handle "  <mets:fileGrp ID=\"DATASTREAMS\">\n";
+
+    # Generate Filestream for Table of Contents (TOC)
+    my $section_ptr=$doc_obj->_lookup_section($section);
+    my $num_subsections = scalar(@{$section_ptr->{'subsection_order'}});
+
+    # If num_subsections is 0, then there is no nested TOC
+
+    if ($num_subsections>0) {
+	print $handle $self->buffer_mets_fileSection_toc($doc_obj,$section,$working_dir);
+    }
+
+    # print out the fileSection by sections
+    print $handle $self->buffer_mets_fileSection_section_xml($doc_obj,$section,$working_dir);
+
+    # print out the whole fileSection
+    print $handle $self->buffer_mets_fileWhole_section_xml($doc_obj,$section,$working_dir); 
+
+    print $handle "  </mets:fileGrp>\n";
+    print $handle "</mets:fileSec>\n";
+  
+    # print out the StructMapSection by sections
+
+    my $struct_type = "fedora:dsBindingMap";
+
+    # If document is going to make use of deminators (BMech and BDef) then
+    # need to code up more output XML here (structMap)and in  
+    # METS:behaviorSec (Fedora extension?) sections
+  
+}
+
+sub buffer_mets_amdSec_header
+{
+    my $self = shift(@_);
+    my ($section,$id) = @_;
+
+    # convert section number
+    my $section_num ="1". $section;
+
+    my $all_text = "";
+
+    my $label_attr = "";
+
+    $all_text .= "<mets:amdSec ID=\"$id$section\" >\n";
+    $all_text .= "  <mets:techMD ID=\"$id$section.0\">\n"; # .0 fedora version number?
+    
+    $label_attr = "LABEL=\"Metadata\"";
+
+    $all_text .= "  <mets:mdWrap $label_attr MDTYPE=\"OTHER\" OTHERMDTYPE=\"gsdl3\" ID=\"".$id."gsdl$section_num\">\n";
+    $all_text .= "    <mets:xmlData>\n";
+
+    return $all_text;
+
+}
+
+sub buffer_mets_amdSec_footer
+{
+    my $self = shift(@_);
+
+    my $all_text = "";
+    
+    $all_text .= "    </mets:xmlData>\n";
+    $all_text .= "  </mets:mdWrap>\n";
+    
+    $all_text .= "  </mets:techMD>\n";
+    $all_text .= "</mets:amdSec>\n";
+
+    return $all_text;
+
+}
+
+sub oai_dc_metadata_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section) = @_;
+
+    my $all_text = "";
+
+    my $dc_namespace = "";
+    $dc_namespace .= "xmlns:dc=\"http://purl.org/dc/elements/1.1/\"";
+    $dc_namespace .= " xmlns:oai_dc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\" ";
+    
+    $all_text .= "  <oai_dc:dc $dc_namespace>\n";
+    
+    $all_text .= $self->get_dc_metadata($doc_obj, $section,"oai_dc");
+    $all_text .= "  </oai_dc:dc>\n";
+
+    return $all_text;
+}
+
+
+
+
+
+# Work out the what the metadata set prefixes (dc,dls etc.) are for 
+# this document
+
+sub metadata_set_prefixes
+{
+    my $self = shift(@_);
+    my ($doc_obj, $section) = @_;
+    
+    $section="" unless defined $section;
+    
+    my $section_ptr = $doc_obj->_lookup_section($section);
+    return {} unless defined $section_ptr;
+
+    my $unique_prefix = {};
+
+    foreach my $data (@{$section_ptr->{'metadata'}})
+    {
+	my ($prefix) = ($data->[0]=~ m/^(.*?)\./);
+	
+	if (defined $prefix)
+	{
+	    next if ($prefix eq "dc"); # skip dublin core as handled separately elsewhere
+
+	    $unique_prefix->{$prefix} = 1;
+	}
+	else
+	{
+	    $unique_prefix->{"ex"} = 1;
+	}
+
+    }
+
+    return $unique_prefix;
+}
+
+
+sub mds_metadata_xml 
+{
+    my $self = shift(@_);
+    my ($doc_obj, $section, $mds_prefix, $namespace) = @_;
+    
+    # build up string of metadata with $mds_prefix
+    $section="" unless defined $section;
+    
+    my $section_ptr = $doc_obj->_lookup_section($section);
+    return "" unless defined $section_ptr;
+
+    my $all_text="";
+    $all_text .= "  <$mds_prefix:$mds_prefix $namespace>\n";
+
+
+    foreach my $data (@{$section_ptr->{'metadata'}})
+    {
+	if ($data->[0]=~ m/^(?:(.*?)\.)?(.*)$/) 
+	{
+	    my $curr_mds_prefix = $1;
+	    my $mds_full_element = $2;
+
+	    $curr_mds_prefix = "ex" unless defined $curr_mds_prefix;
+
+	    if ($curr_mds_prefix eq $mds_prefix)
+	    {
+		# split up full element in the form Title^en into element=Title, attr="en"
+		my ($mds_element,$subelem) = ($mds_full_element =~ m/^(.*?)(?:\^(.*))?$/);
+		my $mds_attr = (defined $subelem) ? "qualifier=\"$subelem\"" : "";
+		
+		my $escaped_value = &docprint::escape_text($data->[1]);
+		
+		$all_text .= "   <$mds_prefix:metadata name=\"$mds_element\" $mds_attr>$escaped_value</$mds_prefix:metadata>\n";
+	    }
+	}
+    }
+
+    $all_text .= "  </$mds_prefix:$mds_prefix>\n";
+
+
+    $all_text =~ s/[\x00-\x09\x0B\x0C\x0E-\x1F]//g;
+
+    return $all_text;
+}
+
+
+
+sub buffer_mets_dmdSection_section_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section) = @_;
+   
+    $section="" unless defined $section;
+    
+    my $section_ptr=$doc_obj->_lookup_section($section);
+    return "" unless defined $section_ptr;
+
+    my $all_text = "";
+
+    $all_text .= $self->buffer_mets_amdSec_header($section,"DC");
+    $all_text .= $self->oai_dc_metadata_xml($doc_obj,$section);
+    $all_text .= $self->buffer_mets_amdSec_footer($section);
+
+    # for each metadata set
+    my $md_sets = $self->metadata_set_prefixes($doc_obj,$section);
+
+    foreach my $md_set (keys %$md_sets)
+    {
+	# Greenstone's agnostic approach to metadata sets conflicts with
+	# Fedoras more clinically prescribed one.  Fake a namespace for
+	# each $md_set to keep both sides happy
+
+	my $fake_namespace 
+	    = "xmlns:$md_set=\"http://www.greenstone.org/namespace/fake/$md_set\"";
+	my $id_caps = $md_set;
+	$id_caps =~ tr/[a-z]/[A-Z]/;
+
+	$all_text .= $self->buffer_mets_amdSec_header($section,$id_caps);
+	$all_text .= $self->mds_metadata_xml($doc_obj,$section,$md_set,$fake_namespace);
+	$all_text .= $self->buffer_mets_amdSec_footer($section);
+    }
+
+
+    foreach my $subsection (@{$section_ptr->{'subsection_order'}}){
+       $all_text .= $self->buffer_mets_dmdSection_section_xml($doc_obj,"$section.$subsection");
+    }
+    
+    $all_text =~ s/[\x00-\x09\x0B\x0C\x0E-\x1F]//g;
+
+    return $all_text;
+}
+
+
+sub doctxt_to_xlink
+{
+    my $self = shift @_;
+    my ($fname,$working_dir) = @_;
+
+    my $xlink_href;
+
+    my $fedora_prefix = $ENV{'FEDORA_HOME'};
+    if (!defined $fedora_prefix) {
+	$xlink_href  = "file:$fname";
+    }
+    else
+    {
+	my $collectparent;
+	if (defined $ENV{'GSDL3SRCHOME'}) { # we're dealing with a GS3 server
+	    if(defined $ENV{'GSDL3HOME'}) { # in case the web directory is located in a separate place
+		$collectparent = &util::filename_cat($ENV{'GSDL3HOME'},"sites","localsite");
+	    } 
+	    else { # try the default location for the web directory
+		$collectparent = &util::filename_cat($ENV{'GSDL3SRCHOME'},"web","sites","localsite");
+	    }
+	}
+	else {
+	    # greenstone 2
+	    $collectparent = $ENV{'GSDLHOME'};
+	}
+	
+	my $gsdl_href = &util::filename_cat($working_dir, $fname);
+	$collectparent =~ s/\\/\\\\/g;             # escape reserved metacharacter \ in path (by replacing it with \\) for substitution
+	$gsdl_href =~ s/^$collectparent(\/|\\)?//; # remove the collectparent path in gsdl_href and any trailing slash
+	$gsdl_href =~ s/\\/\//g;                   # make sure we have url paths (which only use / not \)
+	$gsdl_href = "/gsdl/$gsdl_href";           # prepend gsdl
+
+	my $fserver = $ENV{'FEDORA_HOSTNAME'};
+	my $fport = $ENV{'FEDORA_SERVER_PORT'};
+	
+	my $fdomain = "http://$fserver:$fport";
+	$xlink_href  = "$fdomain$gsdl_href";
+    }
+	
+
+    return $xlink_href;
+
+}
+
+
+sub buffer_mets_fileSection_toc
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section,$working_dir) = @_;
+
+    my $opt_attr = "OWNERID=\"M\"";
+
+    my $all_text = '  <mets:fileGrp ID="TOC">'. "\n";
+    $all_text .= "    <mets:file MIMETYPE=\"text/xml\" ID=\"FILETOC\" $opt_attr >\n";    
+    my $xlink = $self->doctxt_to_xlink("doctoc.xml",$working_dir);
+
+    $all_text .= '      <mets:FLocat LOCTYPE="URL" xlink:href="'.$xlink.'"';
+
+    $all_text .= ' xlink:title="Table of Contents"/>' . "\n";
+    $all_text .= "    </mets:file>\n";
+    $all_text .= "  </mets:fileGrp>\n";
+
+    return $all_text;
+}
+
+
+sub buffer_mets_fileSection_section_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section,$working_dir) = @_;
+
+    my $is_txt_split = 1;
+    my $opt_owner_id = "OWNERID=\"M\"";
+
+    my $all_text 
+	= $self->SUPER::buffer_mets_fileSection_section_xml($doc_obj,$section,$working_dir,$is_txt_split, $opt_owner_id,"SECTION");
+
+
+    return $all_text;
+}
+
+sub buffer_mets_fileWhole_section_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section,$working_dir) = @_;
+
+    my $section_ptr = $doc_obj-> _lookup_section($section);
+    return "" unless defined $section_ptr;
+    
+    my $all_text="";
+
+    my $fileID=0;
+
+    # Output the fileSection for the whole section
+    #  => get the sourcefile and associative file
+
+    my $id_root = "";
+    my $opt_owner_id = "OWNERID=\"M\"";
+
+
+    my $first_assocfile = 1;
+
+    foreach my $data (@{$section_ptr->{'metadata'}}){
+       my $escaped_value = &docprint::escape_text($data->[1]);
+
+       if ($data->[0] eq "gsdlassocfile"){
+	   
+	   $escaped_value =~ m/^(.*?):(.*):(.*)$/;
+	   my $assoc_file = $1;
+	   my $mime_type  = $2;
+	   my $assoc_dir  = $3;
+
+	   if ($first_assocfile) {
+	       $id_root = "url";
+	       $first_assocfile = 0;
+	   }
+	   else {
+	       $id_root = "FG$assoc_file";
+	   }
+
+	   $id_root =~ s/\//_/g;
+	   $all_text .= "  <mets:fileGrp ID=\"$id_root\">\n";
+	   
+	   # The assoc_file's name may be url-encoded, so the xlink_href in the <mets:FLocat>
+	   # element must be the url to this (possibly url-encoded) filename
+	   my $assocfile_url = &unicode::filename_to_url($assoc_file);
+	   my $assfilePath = ($assoc_dir eq "") ? $assocfile_url : "$assoc_dir/$assocfile_url";
+	   ++$fileID;
+	   
+	   my $mime_attr   = "MIMETYPE=\"$mime_type\"";
+	   my $xlink_title = "xlink:title=\"$assoc_file\"";
+
+	   my $id_attr;
+	   my $xlink_href;
+
+	   $id_attr = "ID=\"F$id_root.0\"";
+
+	   my $fedora_prefix = $ENV{'FEDORA_HOME'};
+	   if (!defined $fedora_prefix) {
+	       $xlink_href  = "xlink:href=\"$assfilePath\"";
+	   }
+	   else
+	   {
+	       my $collectparent;
+	       if (defined $ENV{'GSDL3SRCHOME'}) { # we're dealing with a GS3 server
+		   if(defined $ENV{'GSDL3HOME'}) { # in case the web directory is located in a separate place
+		       $collectparent = &util::filename_cat($ENV{'GSDL3HOME'},"sites","localsite");
+		   } 
+		   else { # try the default location for the web directory
+		       $collectparent = &util::filename_cat($ENV{'GSDL3SRCHOME'},"web","sites","localsite");
+		   }
+	       }	      
+	       else {
+		   # greenstone 2
+		   $collectparent = $ENV{'GSDLHOME'};
+	       }
+
+	       my $gsdl_href = &util::filename_cat($working_dir,$assfilePath);
+	       $collectparent =~ s/\\/\\\\/g;             # escape reserved metacharacter \ in path (by replacing it with \\) for substitution
+	       $gsdl_href =~ s/^$collectparent(\/|\\)?//; # remove the collectparent path in gsdl_href and any trailing slash
+	       $gsdl_href =~ s/\\/\//g;                   # make sure we have url paths (which only use / not \)
+	       $gsdl_href = "/gsdl/$gsdl_href";           # prepend gsdl
+
+	       my $fserver = $ENV{'FEDORA_HOSTNAME'};
+	       my $fport = $ENV{'FEDORA_SERVER_PORT'};
+	       
+	       my $fdomain = "http://$fserver:$fport";
+	       $xlink_href = "xlink:href=\"$fdomain$gsdl_href\"";
+	   }
+	   
+	   my $top_section = $doc_obj->get_top_section();
+	   my $id = $doc_obj->get_metadata_element($top_section,"Identifier");
+	   
+###	   print STDERR "**** mime-type: $mime_attr\n";
+
+	   $all_text .= "    <mets:file $mime_attr $id_attr $opt_owner_id >\n";
+	   $all_text .= "      <mets:FLocat LOCTYPE=\"URL\" $xlink_href $xlink_title />\n";
+
+	   $all_text .= "    </mets:file>\n";
+	   
+	   $all_text .= "  </mets:fileGrp>\n";	   
+       }
+   }
+    
+    $all_text =~ s/[\x00-\x09\x0B\x0C\x0E-\x1F]//g;
+    
+    return $all_text;
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugouts/GreenstoneMETSPlugout.pm
===================================================================
--- /gsdl/stable/perllib/plugouts/GreenstoneMETSPlugout.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugouts/GreenstoneMETSPlugout.pm	(revision 20131)
@@ -0,0 +1,263 @@
+###########################################################################
+#
+# GreenstoneMETSPlugout.pm -- the plugout module for METS archives
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package GreenstoneMETSPlugout;
+
+use strict;
+no strict 'refs';
+
+#eval {require bytes};
+#use util;
+use METSPlugout;
+#use docprint; # for escape_text
+
+sub BEGIN {
+    @GreenstoneMETSPlugout::ISA = ('METSPlugout');
+}
+
+my $arguments = [
+      ];
+
+my $options = { 'name'     => "GreenstoneMETSPlugout",
+		'desc'     => "{GreenstoneMETSPlugout.desc}",
+		'abstract' => "no",
+		'inherits' => "yes", 
+	        'args'     => $arguments
+                };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($plugoutlist, $inputargs,$hashArgOptLists) = @_;
+    push(@$plugoutlist, $class);
+      
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new METSPlugout($plugoutlist,$inputargs,$hashArgOptLists);
+    
+    return bless $self, $class;
+}
+
+
+sub output_mets_xml_header
+{
+    my $self = shift(@_);
+    my ($handle, $OID, $doc_title) = @_;
+
+    my $extra_attr = "OBJID=\"$OID:2\"";
+
+    $self->output_mets_xml_header_extra_attribute($handle,$extra_attr);
+
+}
+
+#
+#  Print out docmets.xml file
+#
+sub output_mets_section 
+{
+    my $self = shift(@_);
+    my ($handle, $doc_obj, $section, $working_dir) = @_;
+
+    # print out the dmdSection
+    print $handle $self->buffer_mets_dmdSection_section_xml($doc_obj,$section);
+
+    print $handle "<mets:fileSec>\n";
+
+    # print out the fileSection by sections
+    print $handle $self->buffer_mets_fileSection_section_xml($doc_obj,$section,$working_dir);
+
+    # print out the whole fileSection
+    print $handle $self->buffer_mets_fileWhole_section_xml($doc_obj,$section,$working_dir); 
+
+    print $handle "</mets:fileSec>\n";
+  
+    # print out the StructMapSection by sections
+
+    my $struct_type = "Section";
+
+
+    # consider making the following its own subroutine
+
+    print $handle "<mets:structMap ID=\"Section\" TYPE=\"$struct_type\" LABEL=\"Section\">\n";
+    my $order_num=0;
+    print $handle $self->buffer_mets_StructMapSection_section_xml($doc_obj,$section, \$order_num);
+    print $handle "</mets:structMap>\n";
+    
+    print $handle '<mets:structMap ID="All" TYPE="Whole Document" LABEL="All">'."\n";
+    print $handle $self->buffer_mets_StructMapWhole_section_xml($doc_obj,$section);
+    print $handle "</mets:structMap>\n";
+
+  
+}
+
+sub buffer_mets_dmdSection_section_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section) = @_;
+   
+    $section="" unless defined $section;
+    
+    my $section_ptr=$doc_obj->_lookup_section($section);
+    return "" unless defined $section_ptr;
+
+    # convert section number
+    my $section_num ="1". $section;
+    my $dmd_num = $section_num;
+
+    my $all_text = "";
+
+    my $label_attr = "";
+    # TODO::
+    #print STDERR "***** Check that GROUPID in dmdSec is valid!!!\n";
+    #print STDERR "***** Check to see if <techMD> required\n";
+    # if it isn't allowed, go back and set $mdTag = dmdSec/amdSec
+
+    $all_text .= "<mets:dmdSec ID=\"DM$dmd_num\" GROUPID=\"$section_num\">\n";
+
+    $all_text .= "  <mets:mdWrap $label_attr MDTYPE=\"OTHER\" OTHERMDTYPE=\"gsdl3\" ID=\"gsdl$section_num\">\n";
+    $all_text .= "    <mets:xmlData>\n";
+
+    foreach my $data (@{$section_ptr->{'metadata'}}){
+	my $escaped_value = &docprint::escape_text($data->[1]);
+	$all_text .= '      <gsdl3:Metadata name="'. $data->[0].'">'. $escaped_value. "</gsdl3:Metadata>\n";
+	if ($data->[0] eq "dc.Title") {
+	    $all_text .= '      <gsdl3:Metadata name="Title">'. $escaped_value."</gsdl3:Metadata>\n";
+	}
+    }
+   
+    $all_text .= "    </mets:xmlData>\n";
+    $all_text .= "  </mets:mdWrap>\n";
+    
+    $all_text .= "</mets:dmdSec>\n";    
+
+
+    foreach my $subsection (@{$section_ptr->{'subsection_order'}}){
+	$all_text .= $self->buffer_mets_dmdSection_section_xml($doc_obj,"$section.$subsection");
+    }
+    
+    $all_text =~ s/[\x00-\x09\x0B\x0C\x0E-\x1F]//g;
+
+    return $all_text;
+}
+
+
+
+sub doctxt_to_xlink
+{
+    my $self = shift @_;
+    my ($fname,$working_dir) = @_;
+
+    my $xlink_href  = "file:$fname";
+
+    return $xlink_href;
+
+}
+
+
+
+sub buffer_mets_fileSection_section_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section,$working_dir,$is_recursive) = @_;
+
+    my $is_txt_split = undef;
+
+    my $all_text 
+	= $self->SUPER::buffer_mets_fileSection_section_xml($doc_obj,$section,$working_dir,$is_txt_split);
+
+    return $all_text;
+}
+
+sub buffer_mets_fileWhole_section_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section,$working_dir) = @_;
+
+    my $section_ptr = $doc_obj-> _lookup_section($section);
+    return "" unless defined $section_ptr;
+    
+    my $all_text="";
+
+    my $fileID=0;
+
+    # Output the fileSection for the whole section
+    #  => get the sourcefile and associative file
+
+    my $id_root = "default";
+    my $opt_owner_id = "";    
+
+    $all_text .= "  <mets:fileGrp ID=\"$id_root\">\n";
+
+
+    foreach my $data (@{$section_ptr->{'metadata'}}){
+       my $escaped_value = &docprint::escape_text($data->[1]);
+
+       if ($data->[0] eq "gsdlsourcefilename") { 
+          my ($dirPath) = $escaped_value =~ m/^(.*)[\/\\][^\/\\]*$/;
+
+          ++$fileID;	  
+          $all_text .= "    <mets:file MIMETYPE=\"text/xml\" ID=\"$id_root.$fileID\" $opt_owner_id >\n";
+        
+	  $all_text .= '      <mets:FLocat LOCTYPE="URL" xlink:href="file:'.$data->[1].'" />'."\n";
+	  
+          $all_text .= "    </mets:file>\n";
+       }
+       
+       if ($data->[0] eq "gsdlassocfile"){
+	   
+	   $escaped_value =~ m/^(.*?):(.*):(.*)$/;
+	   my $assoc_file = $1;
+	   my $mime_type  = $2;
+	   my $assoc_dir  = $3;
+	   
+	   my $assfilePath = ($assoc_dir eq "") ? $assoc_file : "$assoc_dir/$assoc_file";
+	   ++$fileID;
+	   
+	   my $mime_attr   = "MIMETYPE=\"$mime_type\"";
+	   my $xlink_title = "xlink:title=\"$assoc_file\"";
+
+	   my $id_attr;
+	   my $xlink_href;
+
+	   $id_attr = "ID=\"$id_root.$fileID\"";
+	   $xlink_href  = "xlink:href=\"$assfilePath\"";
+
+	   $all_text .= "    <mets:file $mime_attr $id_attr $opt_owner_id >\n";
+	   $all_text .= "      <mets:FLocat LOCTYPE=\"URL\" $xlink_href $xlink_title />\n";
+	   
+	   $all_text .= "    </mets:file>\n";
+	   	   
+       }
+   }
+    
+    $all_text .= "  </mets:fileGrp>\n";
+    
+    $all_text =~ s/[\x00-\x09\x0B\x0C\x0E-\x1F]//g;
+    
+    return $all_text;
+}
+
+
+1;
Index: /gsdl/stable/perllib/plugouts/GreenstoneXMLPlugout.pm
===================================================================
--- /gsdl/stable/perllib/plugouts/GreenstoneXMLPlugout.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugouts/GreenstoneXMLPlugout.pm	(revision 20131)
@@ -0,0 +1,116 @@
+###########################################################################
+#
+# GreenstoneXMLPlugout.pm -- the plugout module for Greenstone Archives
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package GreenstoneXMLPlugout;
+
+use strict;
+no strict 'refs';
+no strict 'subs';
+
+eval {require bytes};
+use util;
+use BasePlugout;
+use docprint;
+
+sub BEGIN {
+    @GreenstoneXMLPlugout::ISA = ('BasePlugout');
+}
+
+my $arguments = [];
+
+my $options = { 'name'     => "GreenstoneXMLPlugout",
+		'desc'     => "{GreenstoneXMLPlugout.desc}",
+		'abstract' => "no",
+		'inherits' => "yes" };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($plugoutlist, $inputargs,$hashArgOptLists) = @_;
+    push(@$plugoutlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugout($plugoutlist,$inputargs,$hashArgOptLists);
+ 
+    return bless $self, $class;
+}
+
+sub saveas {
+    my $self = shift (@_);
+    my ($doc_obj,$doc_dir) = @_;
+
+    my $outhandler;
+    if ($self->{'debug'}) {
+	$outhandler = STDOUT;
+	# can we do the xslt and still do debug mode?
+    } 
+    else {
+	my $output_dir = $self->get_output_dir();
+	&util::mk_all_dir ($output_dir) unless -e $output_dir;
+	
+	my $working_dir = &util::filename_cat ($output_dir, $doc_dir);    
+	&util::mk_all_dir ($working_dir) unless -e $working_dir;
+	
+	$self->process_assoc_files ($doc_obj, $doc_dir, '');
+	
+	$self->process_metafiles_metadata ($doc_obj);
+
+	my $output_file = util::filename_cat ($working_dir, "doc.xml");
+	
+	$self->open_xslt_pipe($output_file, $self->{'xslt_file'});
+	
+	
+	if (defined $self->{'xslt_writer'}){
+	    $outhandler = $self->{'xslt_writer'};
+	}
+	else{
+	    $outhandler = $self->get_output_handler($output_file);
+	}
+    }
+    
+    $self->output_xml_header($outhandler,"Archive");
+    my $section_output = &docprint::get_section_xml($doc_obj, $doc_obj->get_top_section());
+    print $outhandler $section_output;
+    $self->output_xml_footer($outhandler,"Archive");
+
+    if (!$self->{'debug'}) {
+	if (defined $self->{'xslt_writer'}){     
+	    $self->close_xslt_pipe(); 
+	}
+	else {
+	    close($outhandler);
+	}
+	
+	$self->{'short_doc_file'} = util::filename_cat ($doc_dir, "doc.xml");  
+	
+	$self->store_output_info_reference($doc_obj);
+    }
+}
+
+
+
+1;
+
Index: /gsdl/stable/perllib/plugouts/MARCXMLPlugout.pm
===================================================================
--- /gsdl/stable/perllib/plugouts/MARCXMLPlugout.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugouts/MARCXMLPlugout.pm	(revision 20131)
@@ -0,0 +1,176 @@
+###########################################################################
+#
+# MARCXMLPlugout.pm -- the plugout module for MARC xml recored
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package MARCXMLPlugout;
+
+use strict;
+no strict 'refs';
+
+eval {require bytes};
+use util;
+use BasePlugout;
+use docprint; # for escape_text
+
+
+sub BEGIN {
+    @MARCXMLPlugout::ISA = ('BasePlugout');
+}
+
+my $arguments = [
+		 { 'name' => "group", 
+		   'desc' => "{MARCXMLPlugout.group}",
+		   'type' => "flag",
+                   'deft' => "0",
+		   'reqd' => "no",    
+		   'hiddengli' => "no"},
+		 { 'name' => "mapping_file", 
+		   'desc' => "{MARCXMLPlugout.mapping_file}",
+		   'type' => "string",
+		   'deft' => "$ENV{'GSDLHOME'}/etc/dc2marc-mapping.xml",
+		   'reqd' => "yes",    
+		   'hiddengli' => "no"}
+                ];
+
+my $options = { 'name'     => "MARCXMLPlugout",
+		'desc'     => "{MARCXMLPlugout.desc}",
+		'abstract' => "no",
+		'inherits' => "yes",
+	        'args'     => $arguments
+                };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($plugoutlist, $inputargs,$hashArgOptLists) = @_;
+    push(@$plugoutlist, $class);
+
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugout($plugoutlist,$inputargs,$hashArgOptLists);
+
+    $self->{'buffered_output'} ="";
+
+    if (!defined $self->{'mapping_file'} ||  (defined $self->{'mapping_file'} && $self->{'mapping_file'} eq "")){
+	$self->{'mapping_file'} = "$ENV{'GSDLHOME'}/etc/dc2marc-mapping.xml";
+	}
+    
+    if (!defined $self->{'xslt_file'} || (defined $self->{'xslt_file'} && $self->{'xslt_file'} eq "")){
+	$self->{'xslt_file'} = "$ENV{'GSDLHOME'}/etc/dc2marc.xsl";
+    }
+  
+    if(defined $self->{'mapping_file'} &&  $self->{'mapping_file'} ne "")
+    {
+	print STDERR "Can not find $self->{'mapping_file'}, please make sure you have supplied the correct file path\n" and  die "\n" unless (-e $self->{'mapping_file'});
+    }
+
+    if(defined $self->{'xslt_file'} &&  $self->{'xslt_file'} ne "")
+    {
+	print STDERR "Can not find $self->{'xslt_file'}, please make sure you have supplied the correct file path\n" and  die "\n" unless (-e $self->{'xslt_file'});
+    }
+
+   return bless $self, $class;
+}
+
+sub saveas {
+    my $self = shift (@_);
+    my ($doc_obj,$doc_dir) = @_;
+
+   
+    if ($self->{'group'}){
+        $self->{buffered_output} .= $self->get_top_metadata_list($doc_obj)."\n"; 
+        return;
+    }
+    
+ 
+    my $output_dir = $self->get_output_dir();
+    &util::mk_all_dir ($output_dir) unless -e $output_dir;
+    
+    my $working_dir = &util::filename_cat ($output_dir, $doc_dir);    
+    &util::mk_all_dir ($working_dir) unless -e $working_dir;
+
+    my $output_file = util::filename_cat ($working_dir, "marc.xml");
+
+    $self->open_xslt_pipe($output_file,$self->{'xslt_file'});
+
+    my $outhandler = $self->{'xslt_writer'}; 
+
+    $self->output_xml_header($outhandler,"MARCXML");
+    print $outhandler $self->get_top_metadata_list($doc_obj);
+    $self->output_xml_footer($outhandler,"MARCXML");  
+    $self->close_xslt_pipe(); 
+              
+}
+
+# returns a xml element of the form <MetadataList><Metadata name="metadata-name">metadata_value</Metadata>...</MetadataList>
+
+sub get_top_metadata_list {
+
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+    
+    my @topmetadata =$doc_obj->get_all_metadata($doc_obj->get_top_section());
+    my $metadatalist ='<MetadataList>';
+    
+    foreach my $i (@topmetadata){
+	foreach my $j (@$i){	
+	    my %metaMap = @$j;
+	    foreach my $key (keys %metaMap){
+		$metadatalist .='<Metadata name='."\"$key\"".'>'.&docprint::escape_text($metaMap{$key}).'</Metadata>'."\n";
+	    }        
+	}    
+    }
+    
+    $metadatalist .='</MetadataList>';   
+    return $metadatalist;
+}
+
+
+sub close_group_output{
+    my $self = shift (@_);
+    
+    return unless $self->{'group'} and  $self->{buffered_output};
+
+    my $output_dir = $self->get_output_dir();
+    &util::mk_all_dir ($output_dir) unless -e $output_dir;
+
+    my $output_file = util::filename_cat($output_dir, "marc.xml");
+
+    $self->open_xslt_pipe($output_file,$self->{'xslt_file'});
+
+    my $outhandler = $self->{'xslt_writer'}; 
+
+    $self->output_xml_header($outhandler,"MARCXML");
+    print $outhandler $self->{buffered_output};
+    $self->output_xml_footer($outhandler,"MARCXML");  
+    $self->close_xslt_pipe();    
+}
+
+
+sub is_group{
+     my $self = shift (@_);
+     return $self->{'group'}; 
+}
+
+1;
Index: /gsdl/stable/perllib/plugouts/METSPlugout.pm
===================================================================
--- /gsdl/stable/perllib/plugouts/METSPlugout.pm	(revision 20131)
+++ /gsdl/stable/perllib/plugouts/METSPlugout.pm	(revision 20131)
@@ -0,0 +1,433 @@
+###########################################################################
+#
+# METSPlugout.pm -- the plugout module for METS archives
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2006 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package METSPlugout;
+
+use strict;
+no strict 'subs';
+no strict 'refs';
+
+use gsprintf 'gsprintf';
+
+eval {require bytes};
+use util;
+use BasePlugout;
+use docprint; # for escape_text
+
+sub BEGIN {
+    @METSPlugout::ISA = ('BasePlugout');
+}
+
+my $arguments = [
+      { 'name' => "xslt_txt", 
+	'desc' => "{METSPlugout.xslt_txt}",
+	'type' => "string",
+	'reqd' => "no",    
+	'hiddengli' => "no"},
+      { 'name' => "xslt_mets", 
+	'desc' => "{METSPlugout.xslt_mets}",
+	'type' => "string",
+	'reqd' => "no",    
+	'hiddengli' => "no"}
+      ];
+
+my $options = { 'name'     => "METSPlugout",
+		'desc'     => "{METSPlugout.desc}",
+		'abstract' => "yes",
+		'inherits' => "yes", 
+	        'args'     => $arguments
+                };
+
+sub new {
+    my ($class) = shift (@_);
+    my ($plugoutlist, $inputargs,$hashArgOptLists) = @_;
+    push(@$plugoutlist, $class);
+
+      
+    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
+    push(@{$hashArgOptLists->{"OptList"}},$options);
+
+    my $self = new BasePlugout($plugoutlist,$inputargs,$hashArgOptLists);
+    return bless $self, $class;
+}
+
+
+sub saveas_doctxt
+{
+    my $self = shift (@_);
+    my ($doc_obj,$working_dir) = @_;
+
+    my $is_recursive = 1;
+
+    my $doc_txt_file = &util::filename_cat ($working_dir,"doctxt.xml");	
+	
+    $self->open_xslt_pipe($doc_txt_file,$self->{'xslt_txt'});
+
+    my $outhandler; 
+
+    if (defined $self->{'xslt_writer'}){
+	$outhandler = $self->{'xslt_writer'};
+    }
+    else{
+	$outhandler = $self->get_output_handler($doc_txt_file);
+    } 
+
+    $self->output_xml_header($outhandler);
+    my $section = $doc_obj->get_top_section();
+    $self->output_txt_section($outhandler,$doc_obj, $section, $is_recursive);
+    $self->output_xml_footer($outhandler);
+    
+
+    if (defined $self->{'xslt_writer'}){     
+	$self->close_xslt_pipe(); 
+    }
+    else{
+	close($outhandler);
+    }
+
+}
+
+sub saveas_docmets
+{
+    my $self = shift (@_);
+    my ($doc_obj,$working_dir) = @_;
+
+    my $doc_mets_file = &util::filename_cat ($working_dir, "docmets.xml");
+    
+    my $doc_title = $doc_obj->get_metadata_element($doc_obj->get_top_section(),"dc.Title");
+    if (!defined $doc_title) {
+	$doc_title = $doc_obj->get_metadata_element($doc_obj->get_top_section(),"Title");
+    }
+ 
+    $self->open_xslt_pipe($doc_mets_file,$self->{'xslt_mets'});
+
+    my $outhandler; 
+
+    if (defined $self->{'xslt_writer'}){
+       $outhandler = $self->{'xslt_writer'};
+    }
+    else{
+       $outhandler = $self->get_output_handler($doc_mets_file);
+     }   
+ 
+      
+    $self->output_mets_xml_header($outhandler, $doc_obj->get_OID(), $doc_title);
+    $self->output_mets_section($outhandler, $doc_obj, $doc_obj->get_top_section(),$working_dir);
+    $self->output_mets_xml_footer($outhandler);
+	
+     if (defined $self->{'xslt_writer'}){     
+	$self->close_xslt_pipe(); 
+    }
+    else{
+	close($outhandler);
+    }
+    
+
+}
+
+sub saveas 
+{
+    my $self = shift (@_);
+    my ($doc_obj,$doc_dir) = @_;
+
+    $self->process_assoc_files ($doc_obj, $doc_dir, '');
+
+    my $output_dir = $self->get_output_dir();
+    &util::mk_all_dir ($output_dir) unless -e $output_dir;
+ 
+    my $working_dir = &util::filename_cat ($output_dir, $doc_dir);              
+   
+    &util::mk_all_dir ($working_dir) unless -e $working_dir;
+
+    ###
+    # Save the text as a filefile
+    ###
+    $self->saveas_doctxt($doc_obj,$working_dir);
+
+    ###
+    # Save the structure and metadata as a METS file
+    ###
+    $self->saveas_docmets($doc_obj,$working_dir);
+
+    $self->{'short_doc_file'} =  &util::filename_cat ($doc_dir, "docmets.xml");
+  
+    $self->store_output_info_reference($doc_obj);  
+
+}
+
+
+sub output_mets_xml_header
+{
+    my $self = shift(@_);
+    my ($handle, $OID, $doc_title) = @_;
+
+    gsprintf(STDERR, "METSPlugout::output_mets_xml_header {common.must_be_implemented}\n") && die "\n";
+}
+
+sub output_mets_xml_header_extra_attribute
+{
+    my $self = shift(@_);
+    my ($handle, $extra_attr, $extra_schema) = @_;
+
+    print $handle '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n";
+    print $handle '<mets:mets xmlns:mets="http://www.loc.gov/METS/"' . "\n";
+    print $handle '           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' . "\n";
+    print $handle '           xmlns:gsdl3="http://www.greenstone.org/namespace/gsdlmetadata/1.0/"' . "\n";
+    if (defined ($ENV{'FEDORA_VERSION'}) &&  $ENV{'FEDORA_VERSION'} =~ m/^2/) { # checking if major version is 2
+    	print $handle '           xmlns:xlink="http://www.w3.org/TR/xlink"' ."\n";
+    }
+    else {
+	print $handle '           xmlns:xlink="http://www.w3.org/1999/xlink"' ."\n";
+    }
+    print $handle '           xsi:schemaLocation="http://www.loc.gov/METS/' . "\n";
+    print $handle '           http://www.loc.gov/standards/mets/mets.xsd' . "\n";
+    print $handle " $extra_schema\n" if (defined $extra_schema);
+    print $handle '           http://www.greenstone.org/namespace/gsdlmetadata/1.0/' . "\n";
+    print $handle '           http://www.greenstone.org/namespace/gsdlmetadata/1.0/gsdl_metadata.xsd"' . "\n";
+
+    print $handle "  $extra_attr>\n";
+
+}
+
+sub output_mets_xml_footer 
+{
+    my $self = shift(@_);
+    my ($handle) = @_;
+    print $handle '</mets:mets>' . "\n";
+}
+
+#  print out doctxt.xml file
+sub output_txt_section {
+    my $self = shift (@_);
+    my ($handle, $doc_obj, $section, $is_recursive) = @_;
+
+    print $handle $self->buffer_txt_section_xml($doc_obj, $section, $is_recursive);
+}
+
+sub buffer_txt_section_xml {
+    my $self = shift(@_);
+    my ($doc_obj, $section, $is_recursive) = @_;
+ 
+    my $section_ptr = $doc_obj->_lookup_section ($section);
+    
+    return "" unless defined $section_ptr;
+   
+    my $all_text = "<Section>\n";
+    $all_text .= &docprint::escape_text("$section_ptr->{'text'}");
+   
+    if (defined $is_recursive && $is_recursive)
+    {
+	# Output all the subsections
+	foreach my $subsection (@{$section_ptr->{'subsection_order'}}){
+	    $all_text .= $self->buffer_txt_section_xml($doc_obj, "$section.$subsection", $is_recursive);
+	}
+    }
+
+     $all_text .= "</Section>\n";
+
+     
+     $all_text =~ s/[\x00-\x09\x0B\x0C\x0E-\x1F]//g;
+     return $all_text;
+}
+
+#
+#  Print out docmets.xml file
+#
+sub output_mets_section 
+{
+    my $self = shift(@_);
+    my ($handle, $doc_obj, $section, $working_dir) = @_;
+
+    gsprintf(STDERR, "METSPlugout::output_mets_section {common.must_be_implemented}\n") && die "\n";
+
+}
+
+
+sub buffer_mets_dmdSection_section_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section) = @_;
+
+    gsprintf(STDERR, "METSPlugout::buffer_mets_dmdSection_section_xml {common.must_be_implemented}\n") && die "\n";
+}
+
+sub buffer_mets_StructMapSection_section_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section, $order_numref, $fileid_base) = @_;
+
+    $section="" unless defined $section;
+    
+    
+    my $section_ptr=$doc_obj->_lookup_section($section);
+    return "" unless defined $section_ptr;
+
+    $fileid_base = "FILEGROUP_PRELUDE" unless defined $fileid_base;
+
+    # output fileSection by Sections
+    my $section_num ="1". $section;
+    my $dmd_num = $section_num;
+
+    #**output the StructMap details
+ 
+    my $dmdid_attr = "DM$dmd_num";
+
+    my $all_text = "  <mets:div ID=\"DS$section_num\" TYPE=\"Section\" \n";
+    $all_text .= '      ORDER="'.$$order_numref++.'" ORDERLABEL="'. $section_num .'" '."\n";
+    $all_text .= "      LABEL=\"$section_num\" DMDID=\"$dmdid_attr\">\n";
+   
+    $all_text .= '    <mets:fptr FILEID="'.$fileid_base.$section_num.'" />'. "\n";
+
+
+    foreach my $subsection (@{$section_ptr->{'subsection_order'}}){
+       $all_text .= $self->buffer_mets_StructMapSection_section_xml($doc_obj,"$section.$subsection", $order_numref, $fileid_base);
+    }
+    
+    $all_text .= "  </mets:div>\n";
+
+    $all_text =~ s/[\x00-\x09\x0B\x0C\x0E-\x1F]//g;
+
+    return $all_text;
+}
+
+
+sub buffer_mets_StructMapWhole_section_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section) = @_;
+    
+    my $section_ptr = $doc_obj->_lookup_section($section);
+    return "" unless defined $section_ptr;
+    
+    my $all_text="";
+    my $fileID=0;
+    my $order_num = 0;
+
+    $all_text .= '  <mets:div ID="DSAll" TYPE="Document" ORDER="'.$order_num.'" ORDERLABEL="All" LABEL="Whole Documemt" DMDID="DM1">' . "\n";
+  
+    #** output the StructMapSection for the whole section
+    #  get the sourcefile and associative file
+
+    foreach my $data (@{$section_ptr->{'metadata'}}){
+       my $escaped_value = &docprint::escape_text($data->[1]);
+   
+       if ($data->[0] eq "gsdlsourcefilename") { 
+          ++$fileID;
+	  $all_text .= '    <mets:fptr FILEID="default.'.$fileID.'" />'."\n";
+       }
+       
+       if ($data->[0] eq "gsdlassocfile"){
+          ++$fileID;
+	  $all_text .= '    <mets:fptr FILEID="default.'.$fileID. '" />'. "\n";
+       }
+    }
+    $all_text .= "  </mets:div>\n";
+    
+    $all_text =~ s/[\x00-\x09\x0B\x0C\x0E-\x1F]//g;
+    
+    return $all_text;
+}
+
+
+
+sub doctxt_to_xlink
+{
+    my $self = shift @_;
+    my ($fname,$working_dir) = @_;
+
+    gsprintf(STDERR, "METSPlugout::doxtxt_to_xlink {common.must_be_implemented}\n") && die "\n";
+}
+
+sub buffer_mets_fileSection_section_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section,$working_dir, $is_txt_split,$opt_attr,$fileid_base) = @_;
+
+    #$section="" unless defined $section;
+    
+    my $section_ptr=$doc_obj->_lookup_section($section);
+    return "" unless defined $section_ptr;
+ 
+    $fileid_base = "FILEGROUP_PRELUDE" unless defined $fileid_base;
+
+    # output fileSection by sections
+    my $section_num ="1". $section;
+ 
+    $opt_attr = "" unless defined $opt_attr;
+     
+    # output the fileSection details
+    my $all_text = '  <mets:fileGrp ID="'.$fileid_base.$section_num . '">'. "\n";
+    $all_text .= "    <mets:file MIMETYPE=\"text/xml\" ID=\"FILE$section_num\" $opt_attr >\n";
+
+    my $xlink;
+    if (defined $is_txt_split && $is_txt_split)
+    {
+	my $section_fnum ="1". $section;
+	$section_fnum =~ s/\./_/g;
+
+    	$xlink = $self->doctxt_to_xlink("doctxt$section_fnum.xml",$working_dir);
+    }
+    else
+    {
+	$xlink = $self->doctxt_to_xlink("doctxt.xml",$working_dir);
+
+	$xlink .= '#xpointer(/Section[';
+    
+	my $xpath = "1".$section;
+	$xpath =~ s/\./\]\/Section\[/g;
+	
+	$xlink .=  $xpath;
+	
+	$xlink .= ']/text())';
+    }
+
+
+
+    $all_text .= '      <mets:FLocat LOCTYPE="URL" xlink:href="'.$xlink.'"';
+
+    $all_text .= ' xlink:title="Hierarchical Document Structure"/>' . "\n";
+    $all_text .= "    </mets:file>\n";
+    $all_text .= "  </mets:fileGrp>\n";
+
+
+    foreach my $subsection (@{$section_ptr->{'subsection_order'}}){
+	$all_text .= $self->buffer_mets_fileSection_section_xml($doc_obj,"$section.$subsection",$working_dir, $is_txt_split, $opt_attr, $fileid_base);
+    }
+    
+    $all_text =~ s/[\x00-\x09\x0B\x0C\x0E-\x1F]//g;
+
+    return $all_text;
+}
+
+sub buffer_mets_fileWhole_section_xml
+{
+    my $self = shift(@_);
+    my ($doc_obj,$section,$working_dir) = @_;
+
+    gsprintf(STDERR, "METSPlugout::buffer_mets_fileWhole_section_xml {common.must_be_implemented}\n") && die "\n";
+
+}
+
+1;
Index: /gsdl/stable/perllib/printusage.pm
===================================================================
--- /gsdl/stable/perllib/printusage.pm	(revision 20131)
+++ /gsdl/stable/perllib/printusage.pm	(revision 20131)
@@ -0,0 +1,353 @@
+###########################################################################
+#
+# printusage.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+package PrintUsage;
+
+
+use gsprintf;
+use strict;
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+
+
+sub gsprintf
+{
+    return &gsprintf::gsprintf(@_);
+}
+
+# this is not called by plugins or classifiers, just by scripts
+sub print_xml_usage
+{
+    my $options = shift(@_);
+
+    # XML output is always in UTF-8
+    &gsprintf::output_strings_in_UTF8;
+
+    &print_xml_header("script");
+
+    &gsprintf(STDERR, "<Info>\n");
+    &gsprintf(STDERR, "  <Name>$options->{'name'}</Name>\n");
+    &gsprintf(STDERR, "  <Desc>$options->{'desc'}</Desc>\n");
+    &gsprintf(STDERR, "  <Arguments>\n");
+    if (defined($options->{'args'})) {
+	&print_options_xml($options->{'args'});
+    }
+    &gsprintf(STDERR, "  </Arguments>\n");
+    &gsprintf(STDERR, "</Info>\n");
+}
+
+
+sub print_xml_header
+{
+    &gsprintf(STDERR, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+}
+
+
+sub print_options_xml
+{
+    my $options = shift(@_);
+
+    foreach my $option (@$options) {
+	my $optionname = $option->{'name'};
+	my $displayname = $option->{'disp'};
+	
+	my $optiondesc = &gsprintf::lookup_string($option->{'desc'});
+
+	# Escape '<' and '>' characters
+	$optiondesc =~ s/</&amp;lt;/g; # doubly escaped
+	$optiondesc =~ s/>/&amp;gt;/g;
+
+	# Display option name, description and type
+	&gsprintf(STDERR, "    <Option>\n");
+	&gsprintf(STDERR, "      <Name>$optionname</Name>\n");
+	if (defined($option->{'disp'})) {
+	    my $displayname = &gsprintf::lookup_string($option->{'disp'});
+	    # Escape '<' and '>' characters
+	    $displayname =~ s/</&amp;lt;/g; # doubly escaped
+	    $displayname =~ s/>/&amp;gt;/g;
+	    &gsprintf(STDERR, "      <DisplayName>$displayname</DisplayName>\n");
+	}
+	&gsprintf(STDERR, "      <Desc>$optiondesc</Desc>\n");
+	&gsprintf(STDERR, "      <Type>$option->{'type'}</Type>\n");
+
+	# If the option has a required field, display this
+	if (defined($option->{'reqd'})) {
+	    &gsprintf(STDERR, "      <Required>$option->{'reqd'}</Required>\n");
+	}
+
+	# If the option has a charactor length field, display this
+	if (defined($option->{'char_length'})) {
+	    &gsprintf(STDERR, "      <CharactorLength>$option->{'char_length'}</CharactorLength>\n");
+	}
+
+	# If the option has a range field, display this
+	if (defined($option->{'range'})) {
+	    &gsprintf(STDERR, "      <Range>$option->{'range'}</Range>\n");
+	}
+
+	# If the option has a list of possible values, display these
+	if (defined $option->{'list'}) {
+	    &gsprintf(STDERR, "      <List>\n");
+	    my $optionvalueslist = $option->{'list'};
+	    foreach my $optionvalue (@$optionvalueslist) {
+		&gsprintf(STDERR, "        <Value>\n");
+		&gsprintf(STDERR, "          <Name>$optionvalue->{'name'}</Name>\n");
+		if (defined $optionvalue->{'desc'}) {
+		    my $optionvaluedesc = &gsprintf::lookup_string($optionvalue->{'desc'});
+
+		    # Escape '<' and '>' characters
+		    $optionvaluedesc =~ s/</&amp;lt;/g; #doubly escaped
+		    $optionvaluedesc =~ s/>/&amp;gt;/g;
+
+		    &gsprintf(STDERR, "          <Desc>$optionvaluedesc</Desc>\n");
+		}
+		&gsprintf(STDERR, "        </Value>\n");
+	    }
+
+#	    # Special case for 'input_encoding'
+#	    if ($optionname =~ m/^input_encoding$/i) {
+#		my $e = $encodings::encodings;
+#		foreach my $enc (sort {$e->{$a}->{'name'} cmp $e->{$b}->{'name'}} keys (%$e)) {
+#		    &gsprintf(STDERR, "        <Value>\n");
+#		    &gsprintf(STDERR, "          <Name>$enc</Name>\n");
+#		    &gsprintf(STDERR, "          <Desc>$e->{$enc}->{'name'}</Desc>\n");
+#		    &gsprintf(STDERR, "        </Value>\n");
+#		}
+#	    }
+
+	    &gsprintf(STDERR, "      </List>\n");
+	}
+
+	# Show the default value for the option, if there is one
+	if (defined $option->{'deft'}) {
+	    my $optiondeftvalue = $option->{'deft'};
+
+	    # Escape '<' and '>' characters
+	    $optiondeftvalue =~ s/</&lt;/g;
+	    $optiondeftvalue =~ s/>/&gt;/g;
+
+	    &gsprintf(STDERR, "      <Default>$optiondeftvalue</Default>\n");
+	}
+
+	# If the option is noted as being hidden in GLI, add that to the printout
+	if (defined($option->{'hiddengli'})) {
+	    &gsprintf(STDERR, "      <HiddenGLI>$option->{'hiddengli'}</HiddenGLI>\n");
+	}
+	# If the argument is not hidden then print out the lowest detail mode it is visible in
+	if (defined($option->{'modegli'})) {
+	    &gsprintf(STDERR, "      <ModeGLI>$option->{'modegli'}</ModeGLI>\n");
+	}
+
+	&gsprintf(STDERR, "    </Option>\n");
+    }
+}
+
+
+sub print_txt_usage
+{
+    my $options = shift(@_);
+    my $params = shift(@_);
+    my $programdesc = shift(@_);
+
+    # this causes us to automatically send output to a pager, if one is
+    # set, AND our output is going to a terminal
+    # active state perl on windows doesn't do open(handle, "-|");
+    if ($ENV{'GSDLOS'} !~ /windows/ && -t STDOUT) {
+        my $pager = $ENV{"PAGER"};
+	if (! $pager) {$pager="(less || more)"}
+	my $pid = open(STDIN, "-|"); # this does a fork... see man perlipc(1)
+	if (!defined $pid) {
+	    gsprintf(STDERR, "pluginfo.pl - can't fork: $!");
+	} else {
+	    if ($pid != 0) { # parent (ie forking) process. child gets 0
+		exec ($pager);
+	    }
+	}
+	open(STDERR,">&STDOUT"); # so it's easier to pipe output
+    }
+
+
+
+    my $programname = $options->{'name'};
+    my $programargs = $options->{'args'};
+
+    # Find the length of the longest option string
+    my $descoffset = 0;
+    if (defined($programargs)) {
+	$descoffset = &find_longest_option_string($programargs);
+    }
+
+    # Produce the usage information using the data structure above
+    if ($programdesc) {
+	&gsprintf(STDERR, $programname . ": $options->{'desc'}\n\n");
+    }
+
+    &gsprintf(STDERR, " {common.usage}: $programname $params\n\n");
+
+    # Display the program options, if there are some
+    if (defined($programargs)) {
+	# Calculate the column offset of the option descriptions
+	my $optiondescoffset = $descoffset + 2;  # 2 spaces between options & descriptions
+
+	&gsprintf(STDERR, " {common.options}:\n");
+
+	# Display the program options
+	&print_options_txt($programargs, $optiondescoffset);
+    }
+}
+
+
+sub print_options_txt
+{
+    my $options = shift(@_);
+    my $optiondescoffset = shift(@_);
+
+    foreach my $option (@$options) {
+	# Display option name
+	my $optionname = $option->{'name'};
+	&gsprintf(STDERR, "  -$optionname");
+	my $optionstringlength = length("  -$optionname");
+
+	# Display option type, if the option is not a flag
+	my $optiontype = $option->{'type'};
+	if ($optiontype ne "flag") {
+	    &gsprintf(STDERR, " <$optiontype>");
+	    $optionstringlength = $optionstringlength + length(" <$optiontype>");
+	}
+
+	# Display the option description	
+	if (defined($option->{'disp'})) {
+	    my $optiondisp = &gsprintf::lookup_string($option->{'disp'});
+	    &display_text_in_column($optiondisp, $optiondescoffset, $optionstringlength, 80);
+	    &gsprintf(STDERR, " " x $optionstringlength);
+	}
+	my $optiondesc = &gsprintf::lookup_string($option->{'desc'});
+	my $optionreqd = $option->{'reqd'};
+	if (defined($optionreqd) && $optionreqd eq "yes") {
+	    $optiondesc = "(" . &gsprintf::lookup_string("{PrintUsage.required}") . ") " . $optiondesc;
+	}
+	&display_text_in_column($optiondesc, $optiondescoffset, $optionstringlength, 80);
+
+	# Show the default value for the option, if there is one
+	my $optiondefault = $option->{'deft'};
+	if (defined($optiondefault)) {
+	    &gsprintf(STDERR, " " x $optiondescoffset);
+	    &gsprintf(STDERR, "{PrintUsage.default}: $optiondefault\n");
+	}
+
+	# If the option has a list of possible values, display these
+	my $optionvalueslist = $option->{'list'};
+	if (defined($optionvalueslist)) {
+	    &gsprintf(STDERR, "\n");
+	    foreach my $optionvalue (@$optionvalueslist) {
+		my $optionvaluename = $optionvalue->{'name'};
+		&gsprintf(STDERR, " " x $optiondescoffset);
+		&gsprintf(STDERR, "$optionvaluename:");
+
+		my $optionvaluedesc = &gsprintf::lookup_string($optionvalue->{'desc'});
+		&display_text_in_column($optionvaluedesc, $optiondescoffset + 2,
+					$optiondescoffset + length($optionvaluename), 80);
+	    }
+	}
+
+#	# Special case for 'input_encoding'
+#	if ($optionname =~ m/^input_encoding$/i) {
+#	    my $e = $encodings::encodings;
+#	    foreach my $enc (sort {$e->{$a}->{'name'} cmp $e->{$b}->{'name'}} keys (%$e)) {
+#		&gsprintf(STDERR, " " x $optiondescoffset);
+#		&gsprintf(STDERR, "$enc:");
+#
+#		my $encodingdesc = $e->{$enc}->{'name'};
+#		&display_text_in_column($encodingdesc, $optiondescoffset + 2,
+#					$optiondescoffset + length("$enc:"), 80);
+#	    }
+#	}
+
+	# Add a blank line to separate options
+	&gsprintf(STDERR, "\n");
+    }
+}
+
+
+sub display_text_in_column
+{
+    my ($text, $columnbeg, $firstlineoffset, $columnend) = @_;
+
+    # Spaces are put *before* words, so treat the column beginning as 1 smaller than it is
+    $columnbeg = $columnbeg - 1;
+
+    # Add some padding (if needed) for the first line
+    my $linelength = $columnbeg;
+    if ($firstlineoffset < $columnbeg) {
+	&gsprintf(STDERR, " " x ($columnbeg - $firstlineoffset));
+    }
+    else {
+	$linelength = $firstlineoffset;
+    }
+
+    # Break the text into words, and display one at a time
+    my @words = split(/ /, $text);
+
+    foreach my $word (@words) {
+	# If printing this word would exceed the column end, start a new line
+	if (($linelength + length($word)) >= $columnend) {
+	    &gsprintf(STDERR, "\n");
+	    &gsprintf(STDERR, " " x $columnbeg);
+	    $linelength = $columnbeg;
+	}
+
+	# Write the word
+	&gsprintf(STDERR, " $word");
+	$linelength = $linelength + length(" $word");
+    }
+
+    &gsprintf(STDERR, "\n");
+}
+
+
+sub find_longest_option_string
+{
+    my $options = shift(@_);
+
+    my $maxlength = 0;
+    foreach my $option (@$options) {
+	my $optionname = $option->{'name'};
+	my $optiontype = $option->{'type'};
+
+	my $optionlength = length("  -$optionname");
+	if ($optiontype ne "flag") {
+	    $optionlength = $optionlength + length(" <$optiontype>");
+	}
+
+	# Remember the longest
+	if ($optionlength > $maxlength) {
+	    $maxlength = $optionlength;
+	}
+    }
+    return $maxlength;
+}
+
+
+1;
Index: /gsdl/stable/perllib/rm/Header/PurePerl.pm
===================================================================
--- /gsdl/stable/perllib/rm/Header/PurePerl.pm	(revision 20131)
+++ /gsdl/stable/perllib/rm/Header/PurePerl.pm	(revision 20131)
@@ -0,0 +1,255 @@
+###########################################################################
+#
+# Code by Xin Gao based on the Ogg::Vorbis::Header::PurePerl module by
+#   Andrew Molloy (GNU General Public Licensed)
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2005 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package rm::Header::PurePerl;
+
+use 5.005;
+use strict;
+use warnings;
+
+use Fcntl qw/SEEK_END/;
+
+our $VERSION = '0.07';
+
+sub new 
+{
+    my $class = shift;
+    my $file = shift;
+
+    return load($class, $file);
+}
+
+sub load 
+{
+    my $class    = shift;
+    my $file     = shift;
+    my $from_new = shift;
+    my %data;
+    my $self;
+
+    # there must be a better way...
+    if ($class eq 'rm::Header::PurePerl')
+    {
+	$self = bless \%data, $class;
+    }
+    else
+    {
+	$self = $class;
+    }
+
+    if ($self->{'FILE_LOADED'})
+    {
+	return $self;
+    }
+
+    $self->{'FILE_LOADED'} = 1;
+
+    # check that the file exists and is readable
+    unless ( -e $file && -r _ )
+    {
+	warn "File does not exist or cannot be read.";
+	# file does not exist, can't do anything
+	return undef;
+    }
+    # open up the file
+    open FILE, $file;
+    # make sure dos-type systems can handle it...
+    binmode FILE;
+
+    $data{'filename'} = $file;
+    $data{'fileHandle'} = \*FILE;
+
+    _loadInfo(\%data);
+
+    close FILE;
+
+    return $self;
+}
+
+sub info 
+{
+    my $self = shift;
+    my $key = shift;
+
+    # if the user did not supply a key, return the entire hash
+    unless ($key)
+    {
+	return $self->{'INFO'};
+    }
+
+    # otherwise, return the value for the given key
+    return $self->{'INFO'}{lc $key};
+}
+
+sub _loadInfo
+{
+    my $data = shift;
+    my $start = 0;
+    my $fh = $data->{'fileHandle'};
+    my $buffer;
+    my $byteCount = $start;
+    my %info;
+    
+    # check that the first four bytes are '.RMF'
+    read($fh, $buffer, 4);
+    if ($buffer ne '.RMF')
+    {
+	warn "No RMF header?";
+	return undef;
+    }
+
+$buffer='';
+my $char;
+
+#find the header
+my $bytes = "DATA";
+my @byteList = split //, $bytes;
+my $numBytes = @byteList;
+my $i;
+
+LINE:   while (1){
+  INNER:  for ($i = 0; $i < $numBytes; $i ++)
+    {
+  unless ( read($fh, $char, 1) ) {last LINE ;}
+	# Find out all of char
+	$buffer= $buffer.$char;  
+
+if (ord($char) !=  ord($byteList[$i]) ) 
+{last  INNER ;}
+    }
+if ($i == $numBytes) {last LINE ;} #jump out the while loop
+        }
+
+#find the tail
+ $bytes = "INDX";
+ @byteList = split //, $bytes;
+ $numBytes = @byteList;
+
+my $isrecord=0;
+LINE:  while (read($fh, $char, 1)){
+   if ($isrecord) {
+	# Find out all of char
+	$buffer= $buffer.$char;  
+   }else
+        {
+         INNER:  for ($i = 0; $i < $numBytes; $i ++)
+                     {
+                      if (ord($char) !=  ord($byteList[$i]) ) {last  INNER ;}
+                      unless ( read($fh, $char, 1) ) {last LINE ;}
+                     }
+if ($i == $numBytes) {$isrecord = 1;} #start record
+        }
+       }
+
+my @cliptype = (
+
+#add clip type here
+"Comments",
+"Keywords",
+"Category",
+"MimeType",# title
+"Lyrics",
+"Artist",
+"CD Track #",
+"Album",
+"Extension",
+"Genre",
+"Statistics",
+"PROP",
+"MDPR",
+"Target Audiences",
+"Audio Format",
+"Creation Date",
+"Modification Date",
+"Generated By",
+"Abstract",
+"Content Rating",
+"File ID",
+"CONT",
+"Audio Stream",
+"Video Stream",
+"Title"
+);
+
+for my $j ( 1 .. scalar(@cliptype) ) {
+$info{$cliptype[$j - 1]} = _loadInfor($buffer,$cliptype[$j - 1]);
+}
+
+    $data->{'INFO'} = \%info;
+}
+
+#search for the element name and value
+sub _loadInfor
+{my $data = shift;
+my $item = shift;
+
+my @byteList = split //, $data;
+my $startbyte = 0;
+
+
+my $isrecord;
+my $data2 = "";
+my $char;
+my $item2 = "";
+if ( $item eq "Title") {$item2 = $item; $item = "MimeType";}
+
+
+OUT: while(index($data, $item, $startbyte) != -1){
+$startbyte = index($data, $item, $startbyte);
+$isrecord=0;
+
+$startbyte += length($item);
+
+if(ord($byteList[$startbyte]) == 0 or ord($byteList[$startbyte]) == 0x14){
+  if ( $item eq "Album" or $item eq "Artist" or $item2 eq "Title"){
+     if ( index($data,"Name",$startbyte) != -1) {
+     $startbyte = index($data,"Name",$startbyte);
+     $startbyte += length("Name");
+     }else {next OUT;}
+}
+
+  if ($data2 ne "") {$data2 = $data2."; ";}
+
+LINE:   while (1){
+        $char = $byteList[++$startbyte];
+
+	if (ord($char) >= 32 and ord($char) <= 126)
+	{
+        $isrecord=1; #record the string started
+	$data2 = $data2.$char;  
+	}else{
+             if ( $isrecord == 1 ) {last LINE ;}# stop at the end of string
+             }
+        }# end LINE: while
+
+ }# end if 
+}# end while
+
+return $data2;
+}
+
+1;
Index: /gsdl/stable/perllib/scriptutil.pm
===================================================================
--- /gsdl/stable/perllib/scriptutil.pm	(revision 20131)
+++ /gsdl/stable/perllib/scriptutil.pm	(revision 20131)
@@ -0,0 +1,71 @@
+###########################################################################
+#
+# scriptutil.pm -- various useful utilities for the scripts
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package scriptutil;
+
+use strict;
+no strict 'subs'; # allow barewords (eg STDERR) as function arguments
+no strict 'refs'; # ...but allow filehandles to be variables and vice versa
+
+use gsprintf 'gsprintf';
+
+# returns $removeold, $keepold
+sub check_removeold_and_keepold {
+
+    my ($removeold, $keepold, $incremental, $dir, $collectcfg) = @_;
+
+    if (($keepold && $removeold) || ($incremental && $removeold) ) {
+	gsprintf(STDERR, "{scripts.both_old_options}\n", $dir);
+	sleep(3); #just in case
+	return (1,0); 
+	
+    } 
+
+    if (!$keepold && !$removeold && !$incremental && defined $collectcfg) {
+	# we only look at config file options if we dont have these on the command line
+	if (defined $collectcfg->{'removeold'} && $collectcfg->{'removeold'} =~ /^true$/i ) {
+	    $removeold = 1;
+	} elsif (defined $collectcfg->{'keepold'} && $collectcfg->{'keepold'} =~ /^true$/i) {
+	    $keepold = 1;
+	} elsif (defined $collectcfg->{'incremental'} && $collectcfg->{'incremental'} =~ /^true$/i) {
+	    $incremental = 1;
+	}
+    }
+
+    if (!$keepold && !$removeold && !$incremental) {
+	gsprintf(STDERR, "{scripts.no_old_options} \n", $dir);
+	sleep(3); #just in case
+	return (1,0);
+    }
+    
+    # incremental implies keepold
+    if ($incremental) {
+	$keepold = 1;
+    }
+    return ($removeold, $keepold, $incremental);
+
+}
+
+1;
Index: /gsdl/stable/perllib/sorttools.pm
===================================================================
--- /gsdl/stable/perllib/sorttools.pm	(revision 20131)
+++ /gsdl/stable/perllib/sorttools.pm	(revision 20131)
@@ -0,0 +1,196 @@
+###########################################################################
+#
+# sorttools.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# various subroutines to format strings
+# for sorting
+
+package sorttools;
+
+use strict;
+
+# moved here from BasClas so import can share it
+sub format_metadata_for_sorting {
+    my ($metaname, $metavalue, $doc_obj) = @_;
+    if (!defined $metaname || $metaname !~ /\S/ || ! defined $metavalue || $metavalue !~ /\S/) {
+	return "";
+    }
+
+    if ($metaname eq "Language") {
+	$metavalue = $iso639::fromiso639{$metavalue};
+	return $metavalue;
+    } 
+    
+    my $lang;
+    if (defined $doc_obj) {
+	$lang = $doc_obj->get_metadata_element ($doc_obj->get_top_section(), 'Language');
+    }
+    $lang = 'en' unless defined $lang;
+    
+    # is this metadata likely to be a name?
+    my $function_name="format_string_name_$lang";
+    if ($metaname =~ /^(?:\w+\.)?(?:Creators?|Authors?|Editors?)(?:[:,].*)?$/
+	&& exists &$function_name) {
+	no strict 'refs';
+	&$function_name(\$metavalue);
+    } else {
+	$function_name="format_string_$lang";
+	if (exists &$function_name) {
+	    no strict 'refs';
+	    &$function_name(\$metavalue);
+	}
+    }
+    
+    return $metavalue;
+}
+
+### language-specific sorting functions (called by format_metadata_for_sorting)
+
+## format_string_$lang() converts to lowercase (where appropriate), and
+# removes punctuation, articles from the start of string, etc
+## format_string_name_$lang() converts to lowercase, puts the surname first,
+# removes punctuation, etc
+
+sub format_string_en {
+    my $stringref = shift;
+    $$stringref = lc($$stringref);
+    $$stringref =~ s/&[^\;]+\;//g; # html entities
+    $$stringref =~ s/^\s*(the|a|an)\b//; # articles
+    $$stringref =~ s/[^[:alnum:]]//g;
+    $$stringref =~ s/\s+/ /g;
+    $$stringref =~ s/^\s+//;
+    $$stringref =~ s/\s+$//;
+}
+
+sub format_string_name_en {
+    my ($stringref) = @_;
+    $$stringref =~ tr/A-Z/a-z/;
+    $$stringref =~ s/&\S+;//g;
+
+    my $comma_format = ($$stringref =~ m/^.+,.+$/);
+    $$stringref =~ s/[[:punct:]]//g;
+    $$stringref =~ s/\s+/ /g;
+    $$stringref =~ s/^\s+//;
+    $$stringref =~ s/\s+$//;
+
+    
+    if (!$comma_format) {
+	# No commas in name => name in 'firstname surname' format
+	# need to sort by surname
+	my @names = split / /, $$stringref;
+	my $surname = pop @names;
+	while (scalar @names && $surname =~ /^(jnr|snr)$/i) {
+	    $surname = pop @names;
+	}
+	$$stringref = $surname . " " . $$stringref;
+    }
+}
+
+
+sub format_string_fr {
+    my $stringref = shift;
+
+    $$stringref = lc($$stringref);
+    $$stringref =~ s/&[^\;]+\;//g; # html entities
+    $$stringref =~ s/^\s*(les?|la|une?)\b//; # articles
+    $$stringref =~ s/[^[:alnum:]]//g;
+    $$stringref =~ s/\s+/ /g;
+    $$stringref =~ s/^\s+//;
+    $$stringref =~ s/\s+$//;
+}
+
+sub format_string_es {
+    my $stringref = shift;
+
+    $$stringref = lc($$stringref);
+    $$stringref =~ s/&[^\;]+\;//g; # html entities
+    $$stringref =~ s/^\s*(la|el)\b//; # articles
+    $$stringref =~ s/[^[:alnum:]]//g;
+    $$stringref =~ s/\s+/ /g;
+    $$stringref =~ s/^\s+//;
+    $$stringref =~ s/\s+$//;
+}
+
+### end of language-specific functions
+
+# takes arguments of day, month, year and converts to
+# date of form yyyymmdd. month may be full (e.g. "January"),
+# abbreviated (e.g. "Jan"), or a number (1-12). Years like "86" 
+# will be assumed to be "1986".
+sub format_date {
+    my ($day, $month, $year) = @_;
+
+    my %months = ('january' => '01', 'jan' => '01', 'february' => '02', 'feb' => '02',
+		  'march' => '03', 'mar' => '03', 'april' => '04', 'apr' => '04',
+		  'may' => '05', 'june' => '06', 'jun' => '06', 'july' => '07', 
+		  'jul' => '07', 'august' => '08', 'aug' => '08', 'september' => '09', 
+		  'sep' => '09', 'october' => '10', 'oct' => '10', 'november' => '11', 
+		  'nov' => '11', 'december' => '12', 'dec' => '12');
+
+    $month =~ tr/A-Z/a-z/;
+    
+    if ($day < 1) { 
+	print STDERR "sorttools::format_date WARNING day $day out of range\n";
+	$day = "01";
+    } elsif ($day > 31) {
+	print STDERR "sorttools::format_date WARNING day $day out of range\n";
+	$day = "31";
+    }
+
+    $day = "0$day" if (length($day) == 1);
+
+    if ($month =~ /^\d\d?$/) {
+	if ($month < 1) {
+	    print STDERR "sorttools::format_date WARNING month $month out of range\n";
+	    $month = "01";
+	} elsif ($month > 12) {
+	    print STDERR "sorttools::format_date WARNING month $month out of range\n";
+	    $month = "12";
+	}
+	if ($month =~ /^\d$/) {
+	    $month = "0" . $month;
+	}
+    } elsif (!defined $months{$month}) {
+	print STDERR "sorttools::format_date WARNING month $month out of range\n";
+	$month = "01";
+    } else {
+	$month = $months{$month};
+    }
+    
+    if ($year !~ /^\d\d\d\d$/) {
+	if ($year !~ /^\d\d$/) {
+	    my $newyear = 1900 + $year;
+	    print STDERR "sorttools::format_date WARNING year $year assumed to be $newyear\n";
+	    $year=$newyear;
+	} else {
+	    print STDERR "sorttools::format_date WARNING year $year out of range - reset to 1900\n";
+	    $year = "1900";
+	}
+    }
+
+    return "$year$month$day";
+}
+
+
+1;
Index: /gsdl/stable/perllib/strings.properties
===================================================================
--- /gsdl/stable/perllib/strings.properties	(revision 20131)
+++ /gsdl/stable/perllib/strings.properties	(revision 20131)
@@ -0,0 +1,1319 @@
+#
+# Resource bundle description
+#
+
+Language.code:en
+Language.name:English
+
+OutputEncoding.unix:iso_8859_1
+OutputEncoding.windows:iso_8859_1
+
+
+#
+# Common output messages and strings
+#
+
+common.cannot_create_file:ERROR: Can't create file %s
+
+common.cannot_find_cfg_file:ERROR: Can't find the configuration file %s
+
+common.cannot_open:ERROR: Can't open %s
+
+common.cannot_open_fail_log:ERROR: Can't open fail log %s
+
+common.cannot_open_output_file:ERROR: Can't open output file %s
+
+common.cannot_read:ERROR: Can't read %s
+
+common.cannot_read_file:ERROR: Can't read file %s
+
+common.general_options:general options (for %s)
+
+common.must_be_implemented:function must be implemented in sub-class
+
+common.options:options
+
+common.processing:processing
+
+common.specific_options:specific options
+
+common.usage:Usage
+
+common.info:info
+
+common.invalid_options:Invalid arguments: %s
+
+common.true:true
+
+common.false:false
+
+common.deprecated: SUPERSEDED
+#
+# Script option descriptions and output messages
+#
+
+scripts.language:Language to display option descriptions in (eg. 'en_US' specifies American English). Requires translations of the option descriptions to exist in the perllib/strings_language-code.rb file.
+
+scripts.xml:Produces the information in an XML form, without 'pretty' comments but with much more detail.
+
+scripts.listall:Lists all items known about.
+
+scripts.describeall:Display options for all items known about
+
+scripts.both_old_options:WARNING: -removeold was specified with -keepold or -incremental, defaulting to -removeold. Current contents of %s directory will be deleted.
+
+scripts.no_old_options:WARNING: None of -removeold, -keepold or -incremental were specified, defaulting to -removeold. Current contents of %s directory will be deleted.
+
+scripts.gli:A flag set when running this script from gli, enables output specific for gli.
+
+# -- buildcol.pl --
+
+buildcol.archivedir:Where the archives live.
+
+buildcol.builddir:Where to put the built indexes.
+
+buildcol.cachedir:Collection will be temporarily built here before being copied to the build directory.
+
+buildcol.cannot_open_cfg_file:WARNING: Can't open config file for updating: %s
+
+buildcol.collectdir:The path of the "collect" directory.
+
+buildcol.copying_back_cached_build:Copying back the cached build
+
+buildcol.create_images:Attempt to create default images for new collection. This relies on the Gimp being installed along with relevant perl modules to allow scripting from perl.
+
+buildcol.debug:Print output to STDOUT.
+
+buildcol.desc:PERL script used to build a greenstone collection from archive documents.
+
+buildcol.faillog:Fail log filename. This log receives the filenames of any files which fail to be processed.
+
+buildcol.incremental_default_builddir:WARNING: The building directory has defaulted to 'building'. If you want to incrementally add to the index directory, please use the "-builddir index" option to buildcol.pl.
+
+buildcol.index:Index to build (will build all in config file if not set).
+
+buildcol.incremental:Only index documents which have not been previously indexed. Implies -keepold. Relies on the lucene indexer.
+
+buildcol.keepold:Will not destroy the current contents of the building directory.
+
+buildcol.maxdocs:Maximum number of documents to build.
+buildcol.maxnumeric:The maximum nuber of digits a 'word' can have in the index dictionary. Large numbers are split into several words for indexing. For example, if maxnumeric is 4, "1342663" will be split into "1342" and "663".
+buildcol.mode:The parts of the building process to carry out.
+buildcol.mode.all:Do everything.
+buildcol.mode.build_index:Just index the text.
+buildcol.mode.compress_text:Just compress the text.
+buildcol.mode.infodb:Just build the metadata database.
+
+buildcol.no_default_images:Default images will not be generated.
+
+buildcol.no_image_script:WARNING: Image making script could not be found: %s
+
+buildcol.no_strip_html:Do not strip the html tags from the indexed text (only used for mgpp collections).
+
+buildcol.no_text:Don't store compressed text. This option is useful for minimizing the size of the built indexes if you intend always to display the original documents at run time (i.e. you won't be able to retrieve the compressed text version).
+
+buildcol.sections_index_document_metadata:Index document level metadata at section level
+buildcol.sections_index_document_metadata.never:Don't index any document metadata at section level.
+buildcol.sections_index_document_metadata.always:Add all specified document level metadata even if section level metadata of that name exists.
+buildcol.sections_index_document_metadata.unless_section_metadata_exists:Only add document level metadata if no section level metadata of that name exists.
+
+buildcol.out:Filename or handle to print output status to.
+
+buildcol.params:[options] collection-name
+
+buildcol.remove_empty_classifications:Hide empty classifiers and classification nodes (those that contain no documents).
+
+buildcol.removeold:Will remove the old contents of the building directory.
+
+buildcol.unlinked_col_images:Collection images may not be linked correctly.
+
+buildcol.unknown_mode:Unknown mode: %s
+
+buildcol.updating_archive_cache:Updating archive cache
+
+buildcol.verbosity:Controls the quantity of output. 0=none, 3=lots.
+
+
+# -- classinfo.pl --
+
+classinfo.collection:Giving a collection name will make classinfo.pl look in collect/collection-name/perllib/classify first. If the classifier is not found there it will look in the general perllib/classify directory.
+
+classinfo.desc:Prints information about a classifier.
+
+classinfo.general_options:General options are inherited from parent classes of the classifier.
+
+classinfo.info:info
+
+classinfo.no_classifier_name:ERROR: You must provide a classifier name.
+
+classinfo.option_types:Classifiers may take two types of options
+
+classinfo.params:[options] classifier-name
+
+classinfo.passing_options:Options may be passed to any classifier by including them in your collect.cfg configuration file.
+
+classinfo.specific_options:Specific options are defined within the classifier itself, and are available only to this particular classifier.
+
+# -- downloadfrom.pl --
+downloadfrom.cache_dir:The location of the cache directory
+downloadfrom.desc:Downloads files from an external server
+downloadfrom.download_mode:The type of server to download from
+downloadfrom.download_mode.Web:HTTP  
+downloadfrom.download_mode.MediaWiki:MediaWiki website
+downloadfrom.download_mode.OAI: Open Archives Initiative 
+downloadfrom.download_mode.z3950:z3950 server
+downloadfrom.download_mode.SRW:SearchRetrieve Webservice
+downloadfrom.incorrect_mode:download_mode parameter was incorrect.
+downloadfrom.info:Print information about the server, rather than downloading
+downloadfrom.params:[general options] [specific download options]
+
+# -- downloadinfo.pl --
+
+downloadinfo.desc:Prints information about a download module
+downloadinfo.collection:Giving a collection name will make downloadinfo.pl look in collect/collection-name/perllib/downloaders first. If the module is not found there it will look in the general perllib/downloaders directory.
+downloadinfo.params:[options] [download-module]
+downloadinfo.general_options:General options are inherited from parent classes of the download modules.
+downloadinfo.specific_options:Specific options are defined within the download module itself, and are available only to this particular downloader.
+downloadinfo.option_types:Download modules may take two types of options
+
+# -- explode_metadata_database.pl --
+explode.desc:Explode a metadata database
+
+explode.collection:The collection name. Some plugins look for auxiliary files in the collection folder.
+ 
+explode.document_field:The metadata element specifying the file name of documents to obtain and include in the collection.
+
+explode.document_prefix:A prefix for the document locations (for use with the document_field option).
+
+explode.document_suffix:A suffix for the document locations (for use with the document_field option).
+
+explode.encoding:Encoding to use when reading in the database file
+explode.metadata_set:Metadata set (namespace) to export all metadata as
+explode.plugin: Plugin to use for exploding
+explode.plugin_options:Options to pass to the plugin before exploding. Option nmaes must start with -. Separate option names and values with space. Cannot be used with -use_collection_plugin_options.
+explode.use_collection_plugin_options: Read the collection configuration file and use the options for the specified plugin. Requires the -collection option. Cannot be used with -plugin_options.
+explode.params: [options] filename
+explode.records_per_folder: The number of records to put in each subfolder.
+
+# -- replace_srcdoc_with_html.pl --
+srcreplace.desc: Replace source document with the generated HTML file when rebuilding
+srcreplace.params: [options] filename
+srcreplace.plugin: Plugin to use for converting the source document
+
+# -- exportcol.pl --
+
+exportcol.out:Filename or handle to print output status to.
+exportcol.cddir:The name of the directory that the CD contents are exported to.
+exportcol.cdname:The name of the CD-ROM -- this is what will appear in the start menu once the CD-ROM is installed.
+exportcol.desc:PERL script used to export one or more collections to a Windows CD-ROM. 
+exportcol.noinstall:Create a CD-ROM where the library runs directly off the CD-ROM and nothing is installed on the host computer.
+exportcol.params:[options] collection-name1 collection-name2 ...
+exportcol.coll_not_found:Ignoring invalid collection %s: collection not found at %s.
+exportcol.coll_dirs_not_found:Ignoring invalid collection %s: one of the following directories not found:
+exportcol.fail:exportcol.pl failed:
+exportcol.no_valid_colls:No valid collections specified to export.
+exportcol.couldnt_create_dir:Could not create directory %s.
+exportcol.couldnt_create_file:Could not create %s.
+exportcol.instructions:To create a self-installing Windows CD-ROM, write the contents of this folder out to a CD-ROM.
+exportcol.non_exist_files:One or more of the following necessary files and directories does not exist:
+exportcol.success:exportcol.pl succeeded:
+exportcol.output_dir:The exported collections (%s) are in %s.
+exportcol.export_coll_not_installed:The Export to CD-ROM functionality has not been installed.
+
+# -- import.pl --
+
+import.archivedir:Where the converted material ends up.
+
+import.manifest:An XML file that details what files are to be imported. Used instead of recursively descending the import folder, typically for incremental building.
+
+import.cannot_open_stats_file:WARNING: Couldn't open stats file %s.
+
+import.cannot_open_fail_log:ERROR: Couldn't open fail log %s
+
+import.cannot_sort:WARNING: import.pl cannot sort documents when groupsize > 1. sortmeta option will be ignored.
+
+import.collectdir:The path of the "collect" directory.
+
+import.complete:Import complete
+
+import.debug:Print imported text to STDOUT (for GreenstoneXML importing)
+
+import.desc:PERL script used to import files into a format (GreenstoneXML or GreenstoneMETS) ready for building.
+
+import.faillog:Fail log filename. This log receives the filenames of any files which fail to be processed.
+
+import.groupsize:Number of import documents to group into one XML file.
+
+import.gzip:Use gzip to compress resulting xml documents (don't forget to include ZIPPlugin in your plugin list when building from compressed documents).
+
+import.importdir:Where the original material lives.
+
+import.incremental:Only import documents which are newer (by timestamp) than the current archives files. Implies -keepold.
+
+import.keepold:Will not destroy the current contents of the archives directory.
+
+import.maxdocs:Maximum number of documents to import.
+
+import.no_import_dir:Error: Import dir (%s) not found.
+
+import.no_plugins_loaded:ERROR: No plugins loaded.
+
+import.OIDtype:The method to use when generating unique identifiers for each document.
+import.OIDtype.hash:Hash the contents of the file. Document identifiers will be the same every time the collection is imported.
+
+import.OIDtype.incremental:Use a simple document count. Significantly faster than "hash", but does not assign the same identifier to the same document content, and further documents cannot be added to existing archives.
+
+import.OIDtype.assigned:Use the metadata value given by the OIDmetadata option (preceded by 'D'); if unspecified, for a particular document a hash is used instead. These identifiers should be unique. 
+
+import.OIDtype.dirname:Use the parent directory name (preceded by 'J'). There should only be one document per directory, and directory names should be unique. E.g. import/b13as/h15ef/page.html will get an identifier of Jh15ef.
+
+import.OIDmetadata:Specifies the metadata element that hold's the document's unique identifier, for use with -OIDtype=assigned.
+
+import.saveas:Format that the archive files should be saved as. 
+
+import.out:Filename or handle to print output status to.
+
+import.params:[options] collection-name
+
+import.removeold:Will remove the old contents of the archives directory.
+
+import.removing_archives:Removing current contents of the archives directory...
+
+import.removing_tmpdir:Removing contents of the collection "tmp" directory...
+
+import.reversesort:Sort in reverse order. Used with the -sortmeta option.
+
+import.site:Site to find collect directory in (for Greenstone 3 installation).
+
+import.sortmeta:Sort documents alphabetically by metadata for building. Search results for boolean queries will be displayed in this order. This will be disabled if groupsize > 1. May be a commma separated list to sort by more than one metadata value.
+
+import.statsfile:Filename or handle to print import statistics to.
+
+import.stats_backup:Will print stats to STDERR instead.
+
+import.verbosity:Controls the quantity of output. 0=none, 3=lots.
+
+# -- schedule.pl --
+schedule.deleted:Scheduled execution deleted for collection
+schedule.scheduled:Execution script created for collection
+schedule.cron:Scheduled execution set up for collection
+schedule.params:[options]
+schedule.error.email:-email requires -smtp -toaddr and -fromaddr to be specified.
+schedule.error.importbuild:-import and -build must be specified. 
+schedule.error.colname:Collection using -colname must be specified. 
+schedule.gli:Running from the GLI
+schedule.frequency:How often to automatically re-build the collection
+schedule.frequency.hourly:Re-build every hour
+schedule.frequency.daily:Re-build every day
+schedule.frequency.weekly:Re-build every week
+schedule.action:How to set up automatic re-building
+schedule.action.add:Schedule automatic re-building
+schedule.action.update:Update existing scheduling
+schedule.action.delete:Delete existing scheduling
+schedule.email:Send email notification 
+schedule.schedule:Select to set up scheduled automatic collection re-building
+schedule.colname:The colletion name for which scheduling will be set up
+schedule.import:The import command to be scheduled
+schedule.build:The buildcol command to be scheduled
+schedule.toaddr:The email address to send scheduled build notifications to
+schedule.toaddr.default:Specify User's Email in File->Preferences
+schedule.fromaddr:The sender email address
+schedule.fromaddr.default:Specify maintainer in main.cfg
+schedule.smtp:The mail server that sendmail must contact to send email
+schedule.smtp.default:Specify MailServer in main.cfg
+schedule.out:Filename or handle to print output status to.
+# -- export.pl --
+
+export.exportdir:Where the export material ends up.
+
+export.cannot_open_stats_file:WARNING: Couldn't open stats file %s.
+
+export.cannot_open_fail_log:ERROR: Couldn't open fail log %s
+
+export.cannot_sort:WARNING: export.pl cannot sort documents when groupsize > 1. sortmeta option will be ignored.
+
+export.collectdir:The path of the "collect" directory.
+
+export.complete:Export complete
+
+export.debug:Print exported text to STDOUT (for GreenstoneXML exporting)
+
+export.desc:PERL script used to export files in a Greenstone collection to another format.
+
+export.faillog:Fail log filename. This log receives the filenames of any files which fail to be processed. (Default: collectdir/collname/etc/fail.log)
+
+export.groupsize:Number of documents to group into one XML file.
+
+export.gzip:Use gzip to compress resulting xml documents (don't forget to include ZIPPlugin in your plugin list when building from compressed documents).
+
+export.importdir:Where the original material lives.
+
+export.keepold:Will not destroy the current contents of the export directory. 
+
+export.maxdocs:Maximum number of documents to export.
+
+export.listall:List all the saveas formats
+
+export.saveas:Format to export documents as.
+
+export.saveas.DSpace:DSpace Archive format.
+
+export.saveas.GreenstoneMETS:METS format using the Greenstone profile.
+export.saveas.FedoraMETS:METS format using the Fedora profile.
+
+export.saveas.GreenstoneXML:Greenstone XML Archive format
+
+export.saveas.MARCXML:MARC XML format (an XML version of MARC 21)
+
+export.out:Filename or handle to print output status to.
+
+export.params:[options] collection-name
+
+export.removeold:Will remove the old contents of the export directory. 
+
+export.removing_export:Removing current contents of the export directory...
+
+export.sortmeta:Sort documents alphabetically by metadata for building. This will be disabled if groupsize > 1.
+
+export.statsfile:Filename or handle to print export statistics to.
+
+export.stats_backup:Will print stats to STDERR instead.
+
+export.verbosity:Controls the quantity of output. 0=none, 3=lots.
+
+
+
+# -- mkcol.pl --
+
+mkcol.about:The about text for the collection.
+
+mkcol.bad_name_cvs:ERROR: No collection can be named CVS as this may interfere with directories created by the CVS versioning system.
+
+mkcol.bad_name_svn:ERROR: No collection can be named .svn as this may interfere with directories created by the SVN versioning system.
+
+mkcol.bad_name_modelcol:ERROR: No collection can be named modelcol as this is the name of the model collection.
+
+mkcol.cannot_find_modelcol:ERROR: Cannot find the model collection %s
+
+mkcol.col_already_exists:ERROR: This collection already exists.
+
+mkcol.collectdir:Directory where new collection will be created.
+
+mkcol.group_not_valid_in_gs3:The group option is not valid in Greenstone 3 mode (-gs3mode).
+mkcol.creating_col:Creating the collection %s
+
+mkcol.creator:The collection creator's e-mail address.
+
+mkcol.creator_undefined:ERROR: The creator was not defined. This variable is needed to recognise duplicate collection names.
+
+mkcol.desc:PERL script used to create the directory structure for a new Greenstone collection.
+
+mkcol.doing_replacements:doing replacements for %s
+
+mkcol.group:Create a new collection group instead of a standard collection.
+
+mkcol.gs3mode:Mode for Greenstone 3 collections.
+
+mkcol.long_colname:ERROR: The collection name must be less than 8 characters so compatibility with earlier filesystems can be maintained.
+
+mkcol.maintainer:The collection maintainer's email address (if different from the creator).
+
+mkcol.no_collectdir:ERROR: The collect dir doesn't exist: %s
+
+mkcol.no_collectdir_specified:ERROR: No collect dir was specified. In gs3mode, either the -site or -collectdir option must be specified.
+
+mkcol.no_colname:ERROR: No collection name was specified.
+
+mkcol.optionfile:Get options from file, useful on systems where long command lines may cause problems.
+
+mkcol.params:[options] collection-name
+
+mkcol.plugin:Perl plugin module to use (there may be multiple plugin entries).
+
+mkcol.public:If this collection has anonymous access.
+mkcol.public.true:Collection is public
+mkcol.public.false:Collection is private
+
+mkcol.quiet:Operate quietly.
+
+mkcol.site:In gs3mode, uses this site name with the GSDL3HOME environment variable to determine collectdir, unless -collectdir is specified.
+
+mkcol.success:The new collection was created successfully at %s
+
+mkcol.title:The title of the collection.
+
+mkcol.win31compat:Whether or not the named collection directory must conform to Windows 3.1 file conventions or not (i.e. 8 characters long).
+mkcol.win31compat.true:Directory name 8 characters or less
+mkcol.win31compat.false:Directory name any length
+
+# -- pluginfo.pl --
+
+pluginfo.collection:Giving a collection name will make pluginfo.pl look in collect/collection-name/perllib/plugins first. If the plugin is not found there it will look in the general perllib/plugins directory.
+
+pluginfo.desc:Prints information about a plugin.
+
+pluginfo.general_options:General options are inherited from parent classes of the plugin.
+
+pluginfo.info:info
+
+pluginfo.no_plugin_name:ERROR: You must provide a plugin name.
+
+pluginfo.option_types:Plugins may take two types of options
+
+pluginfo.params:[options] plugin-name
+
+pluginfo.passing_options:Options may be passed to any plugin by including them in your collect.cfg configuration file.
+
+pluginfo.specific_options:Specific options are defined within the plugin itself, and are available only to this particular plugin.
+
+
+# -- plugoutinfo.pl --
+
+plugoutinfo.collection:Giving a collection name will make plugoutinfo.pl look in collect/collection-name/perllib/plugouts first. If the plugout is not found there it will look in the general perllib/plugouts directory.
+
+plugoutinfo.desc:Prints information about a plugout.
+
+plugoutinfo.general_options:General options are inherited from parent classes of the plugout.
+
+plugoutinfo.info:info
+
+plugoutinfo.no_plugout_name:ERROR: You must provide a plugout name.
+
+plugoutinfo.option_types:Plugouts may take two types of options
+
+plugoutinfo.params:[options] plugout-name
+
+plugoutinfo.passing_options:Options may be passed to any plugout by including them in your collect.cfg configuration file.
+
+plugoutinfo.specific_options:Specific options are defined within the plugout itself, and are available only to this particular plugout.
+
+
+
+#
+# Classifier option descriptions
+#
+
+AllList.desc:Creates a single list of all documents. Use by the oaiserver.
+
+AZCompactList.allvalues:Use all metadata values found.
+
+AZCompactList.desc:Classifier plugin for sorting alphabetically (on a-z, A-Z, 0-9). Produces a horizontal A-Z list, then a vertical list containing documents, or bookshelves for documents with common metadata.
+
+AZCompactList.doclevel:Level to process document at.
+AZCompactList.doclevel.top:Whole document.
+AZCompactList.doclevel.section:By sections.
+
+AZCompactList.firstvalueonly:Use only the first metadata value found.
+
+AZCompactList.freqsort:Sort by node frequency rather than alpha-numeric.
+
+AZCompactList.maxcompact:Maximum number of documents to be displayed per page.
+
+AZCompactList.metadata:A single metadata field, or a comma separated list of metadata fields, used for classification. If a list is specified, the first metadata type that has values will be used. May be used in conjunction with the -firstvalueonly and -allvalues flags, to select only the first value, or all metadata values from the list.
+
+AZCompactList.mincompact:Minimum number of documents to be displayed per page.
+
+AZCompactList.mingroup:The smallest value that will cause a group in the hierarchy to form.
+
+AZCompactList.minnesting:The smallest value that will cause a list to be converted into a nested list.
+
+AZCompactList.recopt:Used in nested metadata such as -metadata Year/Organisation.
+AZCompactList.sort:Metadata field to sort the leaf nodes by. 
+
+AZCompactSectionList.desc:Variation on AZCompactList that classifies sections rather than documents. Entries are sorted by section-level metadata.
+
+AZList.desc:Classifier plugin for sorting alphabetically (on a-z, A-Z, 0-9). Produces a horizontal A-Z list, with documents listed underneath.
+
+AZList.metadata:A single metadata field or a comma separated list of metadata fields used for classification. Following the order indicated by the list, the first field that contains a metadata value will be used. List will be sorted by this element.
+
+AZSectionList.desc:Variation on AZList that classifies sections rather that documents. Entries are sorted by section-level metadata. 
+
+BasClas.bad_general_option:The %s classifier uses an incorrect option. Check your collect.cfg configuration file.
+
+BasClas.builddir:Where to put the built indexes.
+
+BasClas.buttonname:The label for the classifier screen and button in navigation bar. The default is the metadata element specified with -metadata.
+
+BasClas.desc:Base class for all the classifiers.
+
+BasClas.no_metadata_formatting:Don't do any automatic metadata formatting (for sorting.)
+
+BasClas.outhandle:The file handle to write output to.
+
+BasClas.removeprefix:A prefix to ignore in metadata values when sorting.
+
+BasClas.removesuffix:A suffix to ignore in metadata values when sorting.
+
+BasClas.verbosity:Controls the quantity of output. 0=none, 3=lots.
+
+Browse.desc:A fake classifier that provides a link in the navigation bar to a prototype combined browsing and searching page. Only works for mgpp collections, and is only practical for small collections.
+
+DateList.bymonth:Classify by year and month instead of only year.
+
+DateList.desc:Classifier plugin for sorting by date. By default, sorts by 'Date' metadata. Dates are assumed to be in the form yyyymmdd or yyyy-mm-dd.
+
+DateList.metadata:The metadata that contains the dates to classify by. The format is expected to be yyyymmdd or yyyy-mm-dd. Can be a comma separated list, in which case the first date found will be used.
+
+DateList.reverse_sort:Sort the documents in reverse chronological order (newest first).
+
+DateList.nogroup:Make each year an individual entry in the horizontal list, instead of spanning years with few entries. (This can also be used with the -bymonth option to make each month a separate entry instead of merging).
+
+DateList.no_special_formatting:Don't display Year and Month information in the document list.
+
+DateList.sort:An extra metadata field to sort by in the case where two documents have the same date.
+
+HFileHierarchy.desc:Classifier plugin for generating hierarchical classifications based on a supplementary structure file.
+
+Hierarchy.desc:Classifier plugin for generating a hierarchical classification. This may be based on structured metadata, or may use a supplementary structure file (use the -hfile option).
+
+Hierarchy.documents_last:Display document nodes after classifier nodes.
+
+Hierarchy.hfile:Use the specified classification structure file.
+
+Hierarchy.hlist_at_top:Display the first level of the classification horizontally.
+
+Hierarchy.reverse_sort:Sort leaf nodes in reverse order (use with -sort).
+
+Hierarchy.separator:Regular expression used for the separator, if using structured metadata.
+
+Hierarchy.sort:Metadata field to sort leaf nodes by. Leaves will not be sorted if not specified.
+
+Hierarchy.suppressfirstlevel:Ignore the first part of the metadata value. This is useful for metadata where the first element is common, such as the import directory in gsdlsourcefilename.
+
+Hierarchy.suppresslastlevel:Ignore the final part of the metadata value. This is useful for metadata where each value is unique, such as file paths.
+
+HTML.desc:Creates an empty classification that's simply a link to a web page.
+
+HTML.url:The url of the web page to link to.
+
+List.bookshelf_type:Controls when to create bookshelves
+List.bookshelf_type.always:Create a bookshelf icon even if there is only one item in each group at the leaf nodes.
+List.bookshelf_type.never:Never create a bookshelf icon even if there are more than one item in each group at the leaf nodes.
+List.bookshelf_type.duplicate_only:Create a bookshelf icon only when there are more than one item in each group at the leaf nodes.
+
+List.classify_sections:Classify sections instead of documents.
+
+List.desc:A general and flexible list classifier with most of the abilities of AZCompactList, but with better Unicode, metadata and sorting capabilities.
+
+List.level_partition.none:None.
+List.level_partition.per_letter:Create a partition for each letter.
+List.level_partition.constant_size:Create partition with constant size.
+List.level_partition.per_letter_fixed_size:Create a partition per letter with approximately fixed size.
+
+List.metadata:Metadata fields used for classification. Use '/' to separate the levels in the hierarchy and ';' to separate metadata fields within each level.
+
+List.partition_name_length:The length of the partition name; defaults to a variable length from 1 up to 3 characters, depending on how many are required to distinguish the partition start from its end. This option only applies when partition_type_within_level is set to 'constant_size'.
+
+List.partition_size_within_level:The number of items in each partition (only applies when partition_type_within_level is set to 'constant_size').
+
+List.partition_type_within_level:The type of partitioning done: either 'per_letter', 'per_letter_fixed_size', 'constant_size', or 'none'.
+
+List.sort_leaf_nodes_using:Metadata fields used for sorting the leaf nodes. Use '|' to separate the metadata groups to stable sort and ';' to separate metadata fields within each group.
+
+List.sort_using_unicode_collation:Sort using the Unicode Collation Algorithm. Requires http://www.unicode.org/Public/UCA/latest/allkeys.txt file to be downloaded into perl's lib/Unicode/Collate folder.
+
+List.use_hlist_for:Metadata fields to use a hlist rather than a vlist. Use ',' to separate the metadata groups and ';' to separate the metadata fields within each group.
+
+SimpleList.metadata:A single metadata field or a comma separated list of metadata fields used for classification. Following the order indicated by the list, the first field that contains a metadata value will be used. List will be sorted by this element, unless -sort is used. If no metadata is specified, then all documents will be included in the list, otherwise only documents that contain a metadata value will be included.
+
+SimpleList.desc:Simple list classifier plugin. 
+
+SimpleList.sort:Metadata field to sort by. Use '-sort nosort' for no sorting. 
+
+Phind.desc:Produces a hierarchy of phrases found in the text, which is browsable via an applet.
+
+Phind.language:Language or languages to use building hierarchy. Languages are identified by two-letter country codes like en (English), es (Spanish), and fr (French). Language is a regular expression, so 'en|fr' (English or French) and '..' (match any language) are valid.
+
+Phind.min_occurs:The minimum number of times a phrase must appear in the text to be included in the phrase hierarchy.
+
+Phind.savephrases:If set, the phrase infomation will be stored in the given file as text. It is probably a good idea to use an absolute path.
+
+Phind.suffixmode:The smode parameter to the phrase extraction program. A value of 0 means that stopwords are ignored, and of 1 means that stopwords are used.
+
+Phind.text:The text used to build the phrase hierarchy.
+
+Phind.thesaurus:Name of a thesaurus stored in Phind format in the collection's etc directory.
+
+Phind.title:The metadata field used to describe each document.
+
+Phind.untidy:Don't remove working files.
+
+RecentDocumentsList.desc:Classifier that gives a list of newly added or modified documents.
+
+RecentDocumentsList.include_docs_added_since:Include only documents modified or added after the specified date (in yyyymmdd or yyyy-mm-dd format). 
+
+RecentDocumentsList.include_most_recently_added:Include only the specified number of most recently added documents. Only used if include_docs_added_since is not specified.
+
+RecentDocumentsList.sort:Metadata to sort List by. If not specified, list will be sorted by date of modification/addition.
+
+SectionList.desc:Same as List classifier but includes all sections of document (excluding top level) rather than just top level document itself.
+
+Collage.desc:An applet is used to display a collage of images found in the collection.
+
+Collage.geometry:The dimensions of the collage canvas. For a canvas 600 pixels wide by 400 pixels high, for example, specify geometry as 600x400
+
+Collage.maxDepth:Images for collaging are drawn from mirroring the underlying browse classifier. This controls the maximum depth of the mirroring process.
+
+Collage.maxDisplay:The maximum number of images to show in the collage at any one time.
+
+Collage.imageType:Used to control, by expressing file name extensions, which file types are used in the collage.  A list of file name extensions is separated by the percent (%%) symbol.
+
+Collage.bgcolor:The background color of the collage canvas, specified in hexadecimal form (for example #008000 results in a forest green background).
+
+Collage.buttonname:The label for the classifier screen and button in navigation bar.
+
+Collage.refreshDelay:Rate, in milliseconds, that the collage canvas is refreshed.
+
+Collage.isJava2:Used to control which run-time classes of Java are used. More advanced version of Java (i.e. Java 1.2 onwards) include more sophisticated support for controlling transparency in images, this flag helps control what happens; however the built-in Java runtime for some browsers is version 1.1.  The applet is designed to, by default, auto-detect which version of Java the browser is running and act accordingly.
+
+Collage.imageMustNotHave:Used to suppress images that should not appear in the collage, such as image buttons that make up the navigation bar.
+
+Collage.caption:Optional captions to display below the collage canvas.
+
+
+#
+# Plugin option descriptions
+#
+AcronymExtractor.adding:adding
+
+AcronymExtractor.already_seen:already seen
+
+AcronymExtractor.desc:Helper extractor plugin for location and marking up acronyms in text.
+
+AcronymExtractor.done_acronym_extract:done extracting acronyms.
+
+AcronymExtractor.done_acronym_markup:done acronym markup.
+
+AcronymExtractor.extract_acronyms:Extract acronyms from within text and set as metadata.
+
+AcronymExtractor.extracting_acronyms:extracting acronyms
+
+AcronymExtractor.marking_up_acronyms:marking up acronyms
+
+AcronymExtractor.markup_acronyms:Add acronym metadata into document text.
+
+ArchivesInfPlugin.desc:Plugin which processes the archive info database (archiveinf-doc.gdb) which is generated by the import process. It passes each archive file listed in the database to the plugin pipeline to be processed by GreenstoneXMLPlugin.
+
+AutoExtractMetadata.desc: Base plugin that brings together all the extractor functionality from the extractor plugins.
+
+AutoExtractMetadata.extracting:extracting
+
+AutoExtractMetadata.first:Comma separated list of numbers of characters to extract from the start of the text into a set of metadata fields called 'FirstN', where N is the size. For example, the values "3,5,7" will extract the first 3, 5 and 7 characters into metadata fields called "First3", "First5" and "First7".
+
+BaseMediaConverter.desc:Helper plugin that provides base functionality for media converter plugins such as ImageConverter and video converters.
+
+BasePlugin.associate_ext:Causes files with the same root filename as the document being processed by the plugin AND a filename extension from the comma separated list provided by this argument to be associated with the document being processed rather than handled as a separate list.
+
+BasePlugin.associate_tail_re:A regular expression to match filenames against to find associated files. Used as a more powerful alternative to associate_ext.
+
+BasePlugin.block_exp:Files matching this regular expression will be blocked from being passed to any later plugins in the list.
+
+BasePlugin.desc:Base class for all the import plugins.
+
+BasePlugin.dummy_text:This document has no text.
+
+BasePlugin.encoding.ascii:Plain 7 bit ASCII. This may be a bit faster than using iso_8859_1. Beware of using this when the text may contain characters outside the plain 7 bit ASCII set though (e.g. German or French text containing accents), use iso_8859_1 instead.
+
+BasePlugin.encoding.unicode:Just unicode.
+
+BasePlugin.encoding.utf8:Either utf8 or unicode -- automatically detected.
+
+BasePlugin.filename_encoding:The encoding of the source file filenames.
+
+BasePlugin.filename_encoding.auto:Automatically detect the encoding of the filename.
+
+BasePlugin.filename_encoding.auto_language_analysis:Auto-detect the encoding of the filename by analysing it.
+
+BasePlugin.filename_encoding.auto_filesystem_encoding:Auto-detect the encoding of the filename using filesystem encoding.
+
+BasePlugin.filename_encoding.auto_fl:Uses filesystem encoding then language analysis to detect the filename encoding.
+
+BasePlugin.filename_encoding.auto_lf:Uses language analysis then filesystem encoding to detect the filename encoding.
+
+BasePlugin.no_blocking:Don't do any file blocking. Any associated files (e.g. images in a web page) will be added to the collection as documents in their own right.
+
+BasePlugin.no_cover_image:Do not look for a prefix.jpg file (where prefix is the same prefix as the file being processed) to associate as a cover image.
+
+BasePlugin.OIDtype.auto:Use OIDtype set in import.pl
+
+BasePlugin.process_exp:A perl regular expression to match against filenames. Matching filenames will be processed by this plugin. For example, using '(?i).html?\$' matches all documents ending in .htm or .html (case-insensitive).
+
+BasePlugin.smart_block:Block files in a smarter way than just looking at filenames.
+
+BasePlugin.stems:stems
+
+BasePlugin.file_rename_method:The method to be used in renaming the copy of the imported file and associated files.
+
+BasePlugin.rename_method.url:Use url encoding in renaming imported files and associated files.
+
+BasePlugin.rename_method.base64:Use base64 encoding in renaming imported files and associated files.
+
+BasePlugin.rename_method.none:Don't rename imported files and associated files.
+
+BibTexPlugin.desc:BibTexPlugin reads bibliography files in BibTex format. BibTexPlugin creates a document object for every reference in the file. This plugin is a subclass of SplitTextFile class, so if there are multiple records, all are read.
+
+BookPlugin.desc:Creates multi-level document from document containing <<TOC>> level tags. Metadata for each section is taken from any other tags on the same line as the <<TOC>>. e.g. <<Title>>xxxx<</Title>> sets Title metadata. Everything else between TOC tags is treated as simple html (i.e. no HTMLPlugin type of processing is done, such as processing html links). Expects input files to have a .hb file extension by default (this can be changed by adding a -process_exp option); a file with the same name as the hb file but a .jpg extension is taken as the cover image (jpg files are blocked by this plugin). BookPlugin is a simplification (and extension) of the HBPlugin used by the Humanity Development Library collections. BookPlugin is faster as it expects the input files to be cleaner (The input to the HDL collections contains lots of excess html tags around <<TOC>> tags, uses <<I>> tags to specify images, and simply takes all text appearing after a <<TOC>> tag and on the same line as Title metadata). If you're marking up documents to be displayed in the same way as the HDL collections, use this plugin instead of HBPlugin.
+
+CONTENTdmPlugin.desc:Plugin that processes RDF files in exported CONTENTdm collections.
+
+ConvertBinaryFile.apply_fribidi:Run the "fribidi" Unicode Bidirectional Algorithm program over the converted file (for right-to-left text).
+
+ConvertBinaryFile.convert_to:Plugin converts to TEXT or HTML or various types of Image (e.g. JPEG, GIF, PNG).
+
+ConvertBinaryFile.convert_to.auto:Automatically select the format converted to. Format chosen depends on input document type, for example Word will automatically be converted to HTML, whereas PowerPoint will be converted to Greenstone's PagedImage format.
+
+ConvertBinaryFile.convert_to.html:HTML format.
+
+ConvertBinaryFile.convert_to.text:Plain text format.
+
+ConvertBinaryFile.convert_to.pagedimg:A series of images.
+
+ConvertBinaryFile.convert_to.pagedimg_jpg:A series of images in JPEG format.
+
+ConvertBinaryFile.convert_to.pagedimg_gif:A series of images in GIF format.
+
+ConvertBinaryFile.convert_to.pagedimg_png:A series of images in PNG format. 
+
+ConvertBinaryFile.desc:This plugin is inherited by such plugins as WordPlugin, PowerPointPlugin, PostScriptPlugin, RTFPlugin and PDFPlugin. It facilitates the conversion of these document types to either HTML, TEXT or a series of images. It works by dynamically loading an appropriate secondary plugin (HTMLPlugin, StructuredHTMLPlugin, PagedImagePlugin or TextPlugin) based on the plugin argument 'convert_to'. 
+
+ConvertBinaryFile.keep_original_filename:Keep the original filename for the associated file, rather than converting to doc.pdf, doc.doc etc.
+
+ConvertBinaryFile.use_strings:If set, a simple strings function will be called to extract text if the conversion utility fails.
+
+ConvertToRogPlugin.desc:A plugin that inherits from RogPlugin.
+
+CSVPlugin.desc:A plugin for files in comma-separated value format. A new document will be created for each line of the file.
+
+DateExtractor.desc:Helper extractor plugin for extracting historical date information from text.
+
+DateExtractor.extract_historical_years:Extract time-period information from historical documents.  This is stored as metadata with the document. There is a search interface for this metadata, which you can include in your collection by adding the statement, "format QueryInterface DateSearch" to your collection configuration file.
+
+DateExtractor.maximum_century:The maximum named century to be extracted as historical metadata (e.g. 14 will extract all references up to the 14th century).
+
+DateExtractor.maximum_year:The maximum historical date to be used as metadata (in a Common Era date, such as 1950).
+
+DateExtractor.no_bibliography:Do not try to block bibliographic dates when extracting historical dates.
+
+DirectoryPlugin.desc:A plugin which recurses through directories processing each file it finds.
+
+DirectoryPlugin.recheck_directories:After the files in an import directory have been processed, re-read the directory to discover any new files created.
+
+DirectoryPlugin.use_metadata_files:SUPERSEDED - Add MetadataXMLPlugin to the list of plugins in order to read metadata from metadata XML files.
+
+DatabasePlugin.desc:A plugin that imports records from a database. This uses perl's DBI module, which includes back-ends for mysql, postgresql, comma separated values (CSV), MS Excel, ODBC, sybase, etc... Extra modules may need to be installed to use this. See <GSDLHOME>/etc/packages/example.dbi for an example config file. 
+
+DSpacePlugin.desc:A plugin that takes a collection of documents exported from DSpace and imports them into Greenstone.
+	
+DSpacePlugin.first_inorder_ext: This is used to identify the primary document file for a DSpace collection document. With this option, the system will treat the defined ext types of document in sequence to look for the primary document file.
+
+DSpacePlugin.first_inorder_mime:This is used to identify the primary document file for a DSpace collection document. With this option, the system will treat the defined mime types of document in sequence to look for the primary document file.
+
+DSpacePlugin.only_first_doc:This is used to identify the primary document file for a DSpace collection document. With this option, the system will treat the first document referenced in the dublin_core metadata file as the primary document file.
+
+EmailAddressExtractor.desc:Helper extractor plugin for discovering email addresses in text.
+
+EmailAddressExtractor.done_email_extract:done extracting e-mail addresses.
+
+EmailAddressExtractor.extracting_emails:extracting e-mail addresses
+
+EmailAddressExtractor.extract_email:Extract email addresses as metadata.
+
+EmailPlugin.desc:A plugin that reads email files.  These are named with a simple number (i.e. as they appear in maildir folders) or with the extension .mbx (for mbox mail file format).\nDocument text: The document text consists of all the text after the first blank line in the document.\nMetadata (not Dublin Core!):\n\t\$Headers      All the header content (optional, not stored by default)\n\t\$Subject      Subject: header\n\t\$To           To: header\n\t\$From         From: header\n\t\$FromName     Name of sender (where available)\n\t\$FromAddr     E-mail address of sender\n\t\$DateText     Date: header\n\t\$Date         Date: header in GSDL format (eg: 19990924)
+
+EmailPlugin.no_attachments:Do not save message attachments.
+
+EmailPlugin.headers:Store email headers as "Headers" metadata.
+
+EmailPlugin.OIDtype.message_id:Use the message identifier as the document OID. If no message identifier is found, then will use a hash OID.
+
+EmailPlugin.split_exp:A perl regular expression used to split files containing many messages into individual documents.
+
+ExcelPlugin.desc:A plugin for importing Microsoft Excel files (versions 95 and 97).
+
+FavouritesPlugin.desc:Plugin to process Internet Explorer Favourites files.
+
+FOXPlugin.desc:Plugin to process a Foxbase dbt file. This plugin only provides the basic functionality to read in the dbt and dbf files and process each record. A customized plugin based on this general one would need to be written for a particular database to process the appropriate fields.
+
+GreenstoneXMLPlugin.desc:Processes Greenstone Archive XML documents. Note that this plugin does no syntax checking (though the XML::Parser module tests for well-formedness). It's assumed that the Greenstone Archive files conform to their DTD.
+
+GISExtractor.desc:Helper extractor plugin for extracting placenames from text. Requires GIS extension to Greenstone.
+
+GISExtractor.extract_placenames:Extract placenames from within text and set as metadata. Requires GIS extension to Greenstone.
+
+GISExtractor.gazetteer:Gazetteer to use to extract placenames from within text and set as metadata. Requires GIS extension to Greenstone.
+
+GISExtractor.place_list:When extracting placements, include list of placenames at start of the document. Requires GIS extension to Greenstone.
+
+HBPlugin.desc:Plugin which processes an HTML book directory. This plugin is used by the Humanity Development Library collections and does not handle input encodings other than ASCII or extended ASCII. This code is not very clean and could no doubt be made to run faster, by leaving it in this state we hope to encourage the utilisation of BookPlugin instead ;-)\n\nUse BookPlugin if creating a new collection and marking up files like the Humanity Library collections. BookPlugin accepts all input encodings but expects the marked up files to be cleaner than those used by the Humanity Library collections
+
+HBPlugin.encoding.iso_8859_1:Latin1 (western languages)
+
+HTMLImagePlugin.aggressiveness:Range of related text extraction techniques to use.
+HTMLImagePlugin.aggressiveness.1:Filename, path, alternative text (ALT attributes in img HTML tags) only.
+HTMLImagePlugin.aggressiveness.2:All of 1, plus caption where available.
+HTMLImagePlugin.aggressiveness.3:All of 2, plus near paragraphs where available.
+HTMLImagePlugin.aggressiveness.4:All of 3, plus previous headers (<h1>, <h2>...) where available.
+HTMLImagePlugin.aggressiveness.5:All of 4, plus textual references where available.
+HTMLImagePlugin.aggressiveness.6:All of 4, plus metadata tags in HTML pages (title, keywords, etc).
+HTMLImagePlugin.aggressiveness.7:All of 6, 5 and 4 combined.
+HTMLImagePlugin.aggressiveness.8:All of 7, plus duplicating filename, path, alternative text, and caption (raise ranking of more relevant results).
+HTMLImagePlugin.aggressiveness.9:All of 1, plus full text of source page.
+
+HTMLImagePlugin.caption_length:Maximum length of captions (in characters).
+
+HTMLImagePlugin.convert_params:Additional parameters for ImageMagicK convert on thumbnail creation. For example, '-raise' will give a three dimensional effect to thumbnail images.
+
+HTMLImagePlugin.desc:A plugin for extracting images and associated text from webpages.
+
+HTMLImagePlugin.document_text:Add image text as document:text (otherwise IndexedText metadata field).
+
+HTMLImagePlugin.index_pages:Index the pages along with the images. Otherwise reference the pages at the source URL.
+
+HTMLImagePlugin.max_near_text:Maximum characters near images to extract.
+
+HTMLImagePlugin.min_height:Pixels. Skip images shorter than this.
+
+HTMLImagePlugin.min_near_text:Minimum characters of near text or caption to extract.
+
+HTMLImagePlugin.min_size:Bytes. Skip images smaller than this.
+
+HTMLImagePlugin.min_width:Pixels. Skip images narrower than this.
+
+HTMLImagePlugin.neartext_length:Target length of near text (in characters).
+
+HTMLImagePlugin.no_cache_images:Don't cache images (point to URL of original).
+
+HTMLImagePlugin.smallpage_threshold:Images on pages smaller than this (bytes) will have the page (title, keywords, etc) meta-data added.
+
+HTMLImagePlugin.textrefs_threshold:Threshold for textual references. Lower values mean the algorithm is less strict.
+
+HTMLImagePlugin.thumb_size:Max thumbnail size. Both width and height.
+
+HTMLPlugin.assoc_files:Perl regular expression of file extensions to associate with html documents.
+
+HTMLPlugin.desc:This plugin processes HTML files
+
+HTMLPlugin.description_tags:Split document into sub-sections where <Section> tags occur. '-keep_head' will have no effect when this option is set.
+
+HTMLPlugin.extract_style:Extract style and script information from the HTML <head> tag and save as DocumentHeader metadata. This will be set in the document page as the _document:documentheader_ macro.
+
+HTMLPlugin.file_is_url:Set if input filenames make up url of original source documents e.g. if a web mirroring tool was used to create the import directory structure.
+
+HTMLPlugin.hunt_creator_metadata:Find as much metadata as possible on authorship and place it in the 'Creator' field. 
+
+HTMLPlugin.keep_head:Don't remove headers from html files.
+
+HTMLPlugin.metadata_fields:Comma separated list of metadata fields to attempt to extract. Use 'tag<tagname>' to have the contents of the first <tagname> pair put in a metadata element called 'tagname'. Capitalise this as you want the metadata capitalised in Greenstone, since the tag extraction is case insensitive.
+
+HTMLPlugin.no_metadata:Don't attempt to extract any metadata from files.
+
+HTMLPlugin.no_strip_metadata_html:Comma separated list of metadata names, or 'all'. Used with -description_tags, it prevents stripping of HTML tags from the values for the specified metadata.
+
+HTMLPlugin.nolinks:Don't make any attempt to trap links (setting this flag may improve speed of building/importing but any relative links within documents will be broken).
+
+HTMLPlugin.no_image_links:Don't make any attempt to trap image links to allow view images.
+
+HTMLPlugin.rename_assoc_files:Renames files associated with documents (e.g. images). Also creates much shallower directory structure (useful when creating collections to go on cd-rom).
+
+HTMLPlugin.sectionalise_using_h_tags:Automatically create a sectioned document using h1, h2, ... hX tags.
+
+HTMLPlugin.title_sub:Substitution expression to modify string stored as Title. Used by, for example, PDFPlugin to remove "Page 1", etc from text used as the title.
+
+HTMLPlugin.tidy_html:If set, converts an HTML document into a well-formed XHTML to enable users view the document in the book format.
+
+HTMLPlugin.old_style_HDL:To mark whether the file in this collection used the old HDL document's tags style. 
+
+BaseMediaConverter.enable_cache:Cache automatically generated files (such as thumbnails and screen-size images) so they don't need to be repeatedly generated.
+
+ImageConverter.converttotype:Convert main image to format 's'.
+
+ImageConverter.create_screenview:If set to true, create a screen sized image, and set Screen, ScreenType, screenicon, ScreenWidth, ScreenHeight metadata.
+
+ImageConverter.create_thumbnail:If set to true, create a thumbnail version of each image, and add Thumb, ThumbType, thumbicon, ThumbWidth, ThumbHeight metadata.
+ImageConverter.desc:Helper plugin for image conversion using ImageMagick.
+
+ImageConverter.imagemagicknotinstalled:Image Magick not installed
+
+ImageConverter.minimumsize:Ignore images smaller than n bytes.
+
+ImageConverter.noconversionavailable:Image conversion not available
+
+ImageConverter.noscaleup:Don't scale up small images when making thumbnails.
+
+ImageConverter.screenviewsize:Make screenview images of size nxn.
+
+ImageConverter.screenviewtype:Make screenview images in format 's'.
+
+ImageConverter.thumbnailsize:Make thumbnails of size nxn.
+
+ImageConverter.thumbnailtype:Make thumbnails in format 's'.
+
+ImageConverter.win95notsupported: Image Magick not supported on Win95/98
+
+ImagePlugin.desc:This plugin processes images, adding basic metadata
+
+IndexPlugin.desc:This recursive plugin processes an index.txt file. The index.txt file should contain the list of files to be included in the collection followed by any extra metadata to be associated with each file.\n\nThe index.txt file should be formatted as follows: The first line may be a key (beginning with key:) to name the metadata fields (e.g. key: Subject Organization Date). The following lines will contain a filename followed by the value that metadata entry is to be set to. (e.g. 'irma/iw097e 3.2 unesco 1993' will associate the metadata Subject=3.2, Organization=unesco, and Date=1993 with the file irma/iw097e if the above key line was used)\n\nNote that if any of the metadata fields use the Hierarchy classifier plugin then the value they're set to should correspond to the first field (the descriptor) in the appropriate classification file.\n\nMetadata values may be named separately using a tag (e.g. <Subject>3.2) and this will override any name given to them by the key line. If there's no key line any unnamed metadata value will be named 'Subject'.
+
+ISISPlugin.desc:This plugin processes CDS/ISIS databases. For each CDS/ISIS database processed, three files must exist in the collection's import folder: the Master file (.mst), the Field Definition Table (.fdt), and the Cross-Reference File (.xrf).
+
+ISISPlugin.subfield_separator:The string used to separate subfields in CDS/ISIS database records.
+
+ISISPlugin.entry_separator:The string used to separate multiple values for single metadata fields in CDS/ISIS database records.
+
+KeyphraseExtractor.desc:Helper extractor plugin for generating keyphrases from text. Uses Kea keyphrase extraction system.
+
+KeyphraseExtractor.extract_keyphrases:Extract keyphrases automatically with Kea (default settings).
+
+KeyphraseExtractor.extract_keyphrases_kea4:Extract keyphrases automatically with Kea 4.0 (default settings). Kea 4.0 is a new version of Kea that has been developed for controlled indexing of documents in the domain of agriculture.
+
+KeyphraseExtractor.extract_keyphrase_options:Options for keyphrase extraction with Kea. For example: mALIWEB - use ALIWEB extraction model; n5 - extract 5 keyphrase;, eGBK - use GBK encoding.
+
+KeyphraseExtractor.keyphrases:keyphrases
+
+KeyphraseExtractor.missing_kea:Error: The Kea software could not be found at %s. Please download Kea %s from http://www.nzdl.org/Kea and install it in this directory.
+
+LaTeXPlugin.desc:Plugin for LaTeX documents.
+
+LOMPlugin.desc:Plugin for importing LOM (Learning Object Metadata) files.
+
+LOMPlugin.root_tag:The DocType of the XML file (or a regular expression that matches the root element).
+
+LOMPlugin.check_timestamp:Check timestamps of previously downloaded files, and only download again if source file is newer.
+
+LOMPlugin.download_srcdocs:Download the source document if one is specified (in general^identifier^entry or technical^location). This option should specify a regular expression to match filenames against before downloading. Note, this currently doesn't work for documents outside a firewall.
+
+MARCPlugin.desc:Basic MARC plugin.
+
+MARCPlugin.metadata_mapping:Name of file that includes mapping details from MARC values to Greenstone metadata names. Defaults to 'marc2dc.txt' found in the site's etc directory.
+
+MARCXMLPlugin.desc:MARCXML plugin.
+
+MARCXMLPlugin.metadata_mapping_file:Name of file that includes mapping details from MARC values to Greenstone metadata names. Defaults to 'marc2dc.txt' found in the site's etc directory.
+
+MediaWikiPlugin.desc:Plugin for importing MediaWiki web pages
+
+MediaWikiPlugin.show_toc: Add to the collection's About page the 'table of contents' on the MediaWiki website's main page. Needs to specify a Perl regular expression in toc_exp below to match the 'table of contents' section.
+
+MediaWikiPlugin.delete_toc:Delete the 'table of contents' section on each HTML page. Needs to specify a Perl regular expression in toc_exp below to match the 'table of contents' section.
+
+MediaWikiPlugin.toc_exp:A Perl regular expression to match the 'table of contents'. The default value matches common MediaWiki web pages.
+
+MediaWikiPlugin.delete_nav:Delete the navigation section. Needs to specify a Perl regular expression in nav_div_exp below.
+
+MediaWikiPlugin.nav_div_exp:A Perl regular expression to match the navigation section. The default value matches common MediaWiki web pages. 
+
+MediaWikiPlugin.delete_searchbox:Delete the searchbox section. Needs to specify a Perl regular expression in searchbox_div_exp below.
+
+MediaWikiPlugin.searchbox_div_exp:A Perl regular expression to match the searchbox section. The default value matches common MediaWiki web pages.
+
+MediaWikiPlugin.remove_title_suffix_exp:A Perl regular expression to trim the extracted title. For example, \\s-(.+) will trim title contents after "-".
+
+MetadataCSVPlugin.desc:A plugin for metadata in comma-separated value format. The Filename field in the CSV file is used to determine which document the metadata belongs to.
+
+MetadataPass.desc:On-the-side base class to BasePlugin that supports metadata plugins utilise metadata_read pass of import.pl
+
+MetadataXMLPlugin.desc:Plugin that processes metadata.xml files.
+
+MetadataEXIFPlugin.desc:Plugin that extracts EXIF metadata from images, audio and video.  More specifically, it is based on the CPAN module 'ExifTool'. This actually supports many more formats then the name suggests (e.g. GPS, XMP, FlashPix, ID3, Vorbis).  The plugin benefits from this, and has been designed to support all the formats ExifTool supports. See ExifTool documentation for the file types and metadata schemes supported.
+
+GreenstoneMETSPlugin.desc:Process Greenstone-style METS documents
+
+MP3Plugin.desc:Plugin for processing MP3 files.
+
+MP3Plugin.assoc_images:Use Google image search to locate images related to MP3 file based on ID3 Title and Artist metadata.
+
+MP3Plugin.applet_metadata:Used to store [applet] metadata for each document that contains the necessary HTML for an MP3 audio player applet to play that file.
+
+MP3Plugin.metadata_fields:Comma separated list of metadata fields to extract (assuming present) in an MP3 file. Use \"*\" to extract all the fields.
+
+NulPlugin.desc:Dummy (.nul) file plugin. Used with the files produced by exploding metadata database files.
+
+NulPlugin.assoc_field:Name of a metadata field that will be set for each nul file.
+NulPlugin.add_metadata_as_text:Add a table of metadata as the text of the document, rather than "This document has no text".
+
+NulPlugin.remove_namespace_for_text:Remove namepsaces from metadata names in the document text (if add_metadata_as_text is set).
+
+OAIPlugin.desc:Basic Open Archives Initiative (OAI) plugin.
+
+OAIPlugin.document_field:The metadata element specifying the file name of documents to attach the metadata to.
+
+OAIPlugin.metadata_set:Metadata set (namespace prefix) to import all metadata as
+OAIPlugin.metadata_set.auto:Use the prefixes specified in the OAI record
+OAIPlugin.metadata_set.dc: Use the dc prefix. Will map qualified dc elements into their Greenstone form, eg spatial becomes dc.Coverage^spatial.
+
+OggVorbisPlugin.add_technical_metadata:Add technical (eg. bitrate) metadata.
+
+OggVorbisPlugin.desc:A plugin for importing Ogg Vorbis audio files.
+
+OpenDocumentPlugin.desc:Plugin for OASIS OpenDocument format documents (used by OpenOffice 2.0)
+
+PagedImagePlugin.desc:Plugin for documents made up of a sequence of images, with optional OCR text for each image. This plugin processes .item files which list the sequence of image and text files, and provide metadata.
+
+PagedImagePlugin.documenttype:Set the document type (used for display)
+
+PagedImagePlugin.documenttype.paged:Paged documents have next and previous arrows and a 'go to page X' box
+
+PagedImagePlugin.documenttype.hierarchy:Hierarchical documents have a table of contents
+
+PagedImagePlugin.headerpage:Add a top level header page (that contains no image) to each document.
+
+PDFPlugin.allowimagesonly:Allow PDF files with no extractable text. Avoids the need to have -complex set. Only useful with convert_to html.
+
+PDFPlugin.complex:Create more complex output. With this option set the output html will look much more like the original PDF file. For this to function properly you Ghostscript installed (for *nix gs should be on your path while for windows you must have gswin32c.exe on your path).
+
+PDFPlugin.desc:Plugin that processes PDF documents.
+
+PDFPlugin.nohidden:Prevent pdftohtml from attempting to extract hidden text. This is only useful if the -complex option is also set.
+
+PDFPlugin.noimages:Don't attempt to extract images from PDF.
+
+PDFPlugin.use_sections:Create a separate section for each page of the PDF file.
+
+PDFPlugin.zoom:The factor by which to zoom the PDF for output (this is only useful if -complex is set).
+
+PostScriptPlugin.desc:This is a \"poor man's\" ps to text converter. If you are serious, consider using the PRESCRIPT package, which is available for download at http://www.nzdl.org/html/software.html
+
+PostScriptPlugin.extract_date:Extract date from PS header.
+
+PostScriptPlugin.extract_pages:Extract pages from PS header.
+
+PostScriptPlugin.extract_title:Extract title from PS header.
+
+PowerPointPlugin.desc:A plugin for importing Microsoft PowerPoint files.
+
+PowerPointPlugin.windows_scripting:Use MicroSoft Windows scripting technology (Visual Basic for Applications) to get PPT to convert document to various image types (e.g. JPEG,PNG,GIF) rather than rely on the open source package ppttohtml. 
+
+PrintInfo.bad_general_option:The %s plugin uses an incorrect option. Check your collect.cfg configuration file.
+
+PrintInfo.desc:Most base plugin, handles printing info (using pluginfo.pl) and parsing of the arguments.
+
+ProCitePlugin.desc:A plugin for (exported) ProCite databases
+
+ProCitePlugin.entry_separator:The string used to separate multiple values for single metadata fields in ProCite database records.
+
+ReadTextFile.could_not_extract_encoding:WARNING: encoding could not be extracted from %s - defaulting to %s
+
+ReadTextFile.could_not_extract_language:WARNING: language could not be extracted from %s - defaulting to %s
+
+ReadTextFile.could_not_open_for_reading:could not open %s for reading
+
+ReadTextFile.default_encoding:Use this encoding if -input_encoding is set to 'auto' and the text categorization algorithm fails to extract the encoding or extracts an encoding unsupported by Greenstone. This option can take the same values as -input_encoding.
+
+ReadTextFile.default_language:If Greenstone fails to work out what language a document is the 'Language' metadata element will be set to this value. The default is 'en' (ISO 639 language symbols are used: en = English). Note that if -input_encoding is not set to 'auto' and -extract_language is not set, all documents will have their 'Language' metadata set to this value.
+
+ReadTextFile.desc:Base plugin for files that are plain text.
+
+ReadTextFile.empty_file:file contains no text
+
+ReadTextFile.extract_language:Identify the language of each document and set 'Language' metadata. Note that this will be done automatically if -input_encoding is 'auto'.
+
+ReadTextFile.file_has_no_text:ERROR: %s contains no text
+
+ReadTextFile.input_encoding:The encoding of the source documents. Documents will be converted from these encodings and stored internally as utf8.
+
+ReadTextFile.input_encoding.auto:Use text categorization algorithm to automatically identify the encoding of each source document. This will be slower than explicitly setting the encoding but will work where more than one encoding is used within the same collection.
+
+ReadTextFile.read_denied:Read permission denied for %s
+
+ReadTextFile.separate_cjk:Insert spaces between Chinese/Japanese/Korean characters to make each character a word. Use if text is not segmented.
+
+ReadTextFile.unsupported_encoding:WARNING: %s appears to be encoded in an unsupported encoding (%s) - using %s
+
+ReadTextFile.wrong_encoding:WARNING: %s was read using %s encoding but appears to be encoded as %s.
+
+ReadXMLFile.desc:Base class for XML plugins.
+
+ReadXMLFile.xslt:Transform a matching input document with the XSLT in the named file.  A relative filename is assumed to be in the collection's file area, for instance etc/mods2dc.xsl.
+
+RealMediaPlugin.desc:A plugin for processing Real Media files.
+
+ReferPlugin.desc:ReferPlugin reads bibliography files in Refer format.
+
+RogPlugin.desc:Creates simple single-level documents from .rog or .mdb files.
+
+RTFPlugin.desc:Plugin for importing Rich Text Format files.
+
+SourceCodePlugin.desc:Filename is currently used for Title ( optionally minus some prefix ). Current languages:\ntext: READMEs/Makefiles\nC/C++   (currently extracts #include statements and C++ class decls)\nPerl    (currently only done as text)\nShell   (currently only done as text)
+
+SourceCodePlugin.remove_prefix:Remove this leading pattern from the filename (eg -remove_prefix /tmp/XX/src/). The default is to remove the whole path from the filename.
+
+SplitTextFile.desc:SplitTextFile is a plugin for splitting input files into segments that will then be individually processed. This plugin should not be called directly.  Instead, if you need to process input files that contain several documents, you should write a plugin with a process function that will handle one of those documents and have it inherit from SplitTextFile.  See ReferPlugin for an example.
+
+SplitTextFile.split_exp:A perl regular expression to split input files into segments.
+
+StructuredHTMLPlugin.desc:A plugin to process structured HTML documents, splitting them into sections based on style information.
+
+StructuredHTMLPlugin.delete_toc:Remove any table of contents, list of figures etc from the converted HTML file. Styles for these are specified by the toc_header option.
+
+StructuredHTMLPlugin.title_header:possible user-defined styles for the title header.
+
+StructuredHTMLPlugin.level1_header:possible user-defined styles for the level1 header in the HTML document (equivalent to <h1>).
+
+StructuredHTMLPlugin.level2_header:possible user-defined styles for the level2 header in the HTML document (equivalent to <h2>).
+
+StructuredHTMLPlugin.level3_header:possible user-defined styles for the level3 header in the HTML document (equivalent to <h3>).
+
+StructuredHTMLPlugin.toc_header:possible user-defined header styles for the table of contents, table of figures etc, to be removed if delete_toc is set.
+
+TextPlugin.desc:Creates simple single-level document. Adds Title metadata of first line of text (up to 100 characters long).
+
+TextPlugin.title_sub:Substitution expression to modify string stored as Title. Used by, for example, PostScriptPlugin to remove "Page 1" etc from text used as the title.
+
+UnknownPlugin.assoc_field:Name of the metadata field that will hold the associated file's name.
+
+UnknownPlugin.desc:This is a simple Plugin for importing files in formats that Greenstone doesn't know anything about.  A fictional document will be created for every such file, and the file itself will be passed to Greenstone as the \"associated file\" of the document.
+
+UnknownPlugin.file_format:Type of the file (e.g. MPEG, MIDI, ...)
+
+UnknownPlugin.mime_type:Mime type of the file (e.g. image/gif).
+
+UnknownPlugin.process_extension:Process files with this file extension. This option is an alternative to process_exp that is simpler to use but less flexible.
+
+UnknownPlugin.srcicon:Specify a macro name (without underscores) to use as srcicon metadata.
+
+WordPlugin.desc:A plugin for importing Microsoft Word documents.
+
+WordPlugin.windows_scripting:Use MicroSoft Windows scripting technology (Visual Basic for Applications) to get Word to convert document to HTML rather than rely on the open source package WvWare.  Causes Word application to open on screen if not already running.
+
+WordPlugin.metadata_fields: This is to retrieve metadata from the HTML document converted by VB scripting. It allows users to define comma separated list of metadata fields to attempt to extract. Use 'tag<tagname>' to have the contents of the first <tagname> pair put in a metadata element called 'tagname'. Capitalise this as you want the metadata capitalised in Greenstone, since the tag extraction is case insensitive
+
+ZIPPlugin.desc:Plugin which handles compressed and/or archived input formats currently handled formats and file extensions are:\ngzip (.gz, .z, .tgz, .taz)\nbzip (.bz)\nbzip2 (.bz2)\nzip (.zip .jar)\ntar (.tar)\n\nThis plugin relies on the following utilities being present (if trying to process the corresponding formats):\ngunzip (for gzip)\nbunzip (for bzip)\nbunzip2 \nunzip (for zip)\ntar (for tar)
+
+#
+# Download module option descriptions
+#
+
+BaseDownload.desc:Base class for Download modules
+BaseDownload.bad_general_option:The %s download module uses an incorrect option.
+MediaWikiDownload.desc:A module for downloading from MediaWiki websites
+MediaWikiDownload.reject_filetype:Ignore url list, separate by comma, e.g.*cgi-bin*,*.ppt ignores hyperlinks that contain either 'cgi-bin' or '.ppt'
+MediaWikiDownload.reject_filetype_disp:Ignore URL patterns
+MediaWikiDownload.exclude_directories:List of exclude directories (must be absolute path to the directory), e.g. /people,/documentation will exclude the 'people' and 'documentation' subdirectory under the currently crawling site.
+MediaWikiDownload.exclude_directories_disp:Exclude directories
+
+OAIDownload.desc:A module for downloading from OAI repositories
+OAIDownload.url_disp:Source URL
+OAIDownload.url:OAI repository URL
+OAIDownload.set_disp:Restrict to set
+OAIDownload.set:Restrict the download to the specified set in the repository
+OAIDownload.metadata_prefix_disp:Metadata prefix
+OAIDownload.metadata_prefix:The metadata format used in the exported, e.g. oai_dc, qdc, etc. Press the <Server information> button to find out what formats are supported.
+OAIDownload.get_doc_disp:Get document
+OAIDownload.get_doc:Download the source document if one is specified in the record
+OAIDownload.get_doc_exts_disp:Only include file types
+OAIDownload.get_doc_exts:Permissible filename extensions of documents to get
+OAIDownload.max_records_disp:Max records
+OAIDownload.max_records:Maximum number of records to download
+
+SRWDownload.desc:A module for downloading from SRW (Search/Retrieve Web Service) repositories
+
+WebDownload.desc:A module for downloading from the Internet via HTTP or FTP
+WebDownload.url:Source URL. In case of http redirects, this value may change
+WebDownload.url_disp:Source URL
+WebDownload.depth:How many hyperlinks deep to go when downloading
+WebDownload.depth_disp:Download Depth
+WebDownload.below:Only mirror files below this URL
+WebDownload.below_disp:Only files below URL
+WebDownload.within:Only mirror files within the same site
+WebDownload.within_disp:Only files within site
+WebDownload.html_only:Download only HTML files, and ignore associated files e.g images and stylesheets
+WebDownload.html_only_disp:Only HTML files
+
+WgetDownload.desc: Base class that handles calls to wget
+WgetDownload.proxy_on:Proxy on
+WgetDownload.proxy_host:Proxy host
+WgetDownload.proxy_port:Proxy port
+WgetDownload.user_name:User name
+WgetDownload.user_password:User password
+
+Z3950Download.desc:A module for downloading from Z3950 repositories
+Z3950Download.host:Host URL
+Z3950Download.host_disp:Host 
+Z3950Download.port:Port number of the repository
+Z3950Download.port_disp:Port
+Z3950Download.database:Database to search for records in
+Z3950Download.database_disp:Database
+Z3950Download.find:Retrieve records containing the specified search term
+Z3950Download.find_disp:Find
+Z3950Download.max_records:Maximum number of records to download
+Z3950Download.max_records_disp:Max Records
+
+
+#
+#Plugout option descriptions
+#
+
+BasPlugout.bad_general_option:The %s plugout uses an incorrect option.
+BasPlugout.debug:Set debugging mode
+BasPlugout.desc:Base class for all the export plugouts.
+BasPlugout.group_size:Number of documents to group into one XML file.
+BasPlugout.gzip_output:Use gzip to compress resulting xml documents (don't forget to include ZIPPlugin in your plugin list when building from compressed documents).
+BasPlugout.output_handle: the file descriptor used to receive output data
+BasPlugout.output_info:The reference to an arcinfo object used to store information about the archives.
+BasPlugout.verbosity:Controls the quantity of output. 0=none, 3=lots.
+BasPlugout.xslt_file:Transform a document with the XSLT in the named file.  
+
+DSpacePlugout.desc:DSpace Archive format.
+
+FedoraMETSPlugout.desc:METS format using the Fedora profile.
+FedoraMETSPlugout.fedora_namespace:The prefix used in Fedora for process ids (PIDS) e.g. greenstone:HASH0122efe4a2c58d0
+
+GreenstoneXMLPlugout.desc:Greenstone XML Archive format.
+
+GreenstoneMETSPlugout.desc:METS format using the Greenstone profile.
+
+MARCXMLPlugout.desc:MARC xml format.
+MARCXMLPlugout.group:Output the marc xml records into a single file.
+MARCXMLPlugout.mapping_file:Use the named mapping file for the transformation.
+
+METSPlugout.desc:Superclass plugout for METS format.  Provides common functionality for profiles such as GreenstoneMETS and FedoraMETS and key abstract methods.
+METSPlugout.xslt_txt:Transform a mets's doctxt.xml with the XSLT in the named file.  
+METSPlugout.xslt_mets:Transform a mets's docmets.xml with the XSLT in the named file.  
+
+#
+# Perl module strings
+#
+
+classify.could_not_find_classifier:ERROR: Could not find classifier \"%s\"
+
+download.could_not_find_download:ERROR: Could not find download module \"%s\"
+
+plugin.could_not_find_plugin:ERROR: Could not find plugin \"%s\"
+
+plugin.including_archive:including the contents of 1 ZIP/TAR archive
+
+plugin.including_archives:including the contents of %d ZIP/TAR archives
+
+plugin.kill_file:Process killed by .kill file
+
+plugin.n_considered:%d documents were considered for processing
+
+plugin.n_included:%d were processed and included in the collection
+
+plugin.n_rejected:%d were rejected
+
+plugin.n_unrecognised:%d were unrecognised
+
+plugin.no_plugin_could_process:WARNING: No plugin could process %s
+
+plugin.no_plugin_could_recognise:WARNING: No plugin could recognise %s
+
+plugin.no_plugin_could_process_this_file:no plugin could process this file
+
+plugin.no_plugin_could_recognise_this_file:no plugin could recognise this file
+
+plugin.one_considered:1 document was considered for processing
+
+plugin.one_included:1 was processed and included in the collection
+
+plugin.one_rejected:1 was rejected
+
+plugin.one_unrecognised:1 was unrecognised
+
+plugin.see_faillog:See %s for a list of unrecognised and/or rejected documents
+
+PrintUsage.default:Default
+
+PrintUsage.required:REQUIRED
+
+plugout.could_not_find_plugout:ERROR: Could not find plugout \"%s\"
Index: /gsdl/stable/perllib/strings_ar.properties
===================================================================
--- /gsdl/stable/perllib/strings_ar.properties	(revision 20131)
+++ /gsdl/stable/perllib/strings_ar.properties	(revision 20131)
@@ -0,0 +1,3853 @@
+#
+# Resource bundle description
+#
+
+Language.code:ar
+Language.name:Arabic
+
+OutputEncoding.unix:utf-8
+OutputEncoding.windows:utf-8
+
+
+#
+# Common output messages and strings
+#
+
+common.cannot_create_file:Ø®Ø·Ø£: ÙØ§ÙÙ
+ÙÙ Ø¥ÙØŽØ§Ø¡ Ø§ÙÙ
+ÙÙ %s
+
+common.cannot_find_cfg_file:Ø®Ø·Ø£: ÙØ§ ÙÙ
+ÙÙ Ø¥ÙØ¬Ø§Ø¯ Ù
+ÙÙ Ø§ÙØ¥Ø¹Ø¯Ø§Ø¯ %s
+
+common.cannot_open:Ø®Ø·Ø£: ÙØ§ ÙÙ
+ÙÙ ÙØªØ­ %s
+
+common.cannot_open_fail_log:Ø®Ø·Ø£: ÙØ§ ÙÙ
+ÙÙ ÙØªØ­ Ù
+Ø¯ÙÙØ© Ø§ÙØ®Ø·Ø£ %s
+
+common.cannot_open_output_file:Ø®Ø·Ø£: ÙØ§ ÙÙ
+ÙÙ ÙØªØ­ Ù
+ÙÙ Ø§ÙÙ
+Ø®Ø±Ø¬Ø§Øª %s
+
+common.cannot_read:Ø®Ø·Ø£: ÙØ§ ÙÙ
+ÙÙ ÙØ±Ø§Ø¡Ø© %s
+
+common.cannot_read_file:Ø®Ø·Ø£: ÙØ§ ÙÙ
+ÙÙ ÙØ±Ø§Ø¡Ø© %s
+
+common.general_options:Ø®ÙØ§Ø±Ø§Øª Ø¹Ø§Ù
+Ø© (Ù %s)
+
+common.must_be_implemented:ÙØ±Ø§Ø¡Ø© Ø¯Ø§ÙØ© ÙØ¬Øš ØªÙÙÙØ°ÙØ§ ÙÙ ÙØŠØ© ÙØ±Ø¹ÙØ© ÙÙ
+ÙØ§ØšØ³ Ù
+ØªÙØ±Ø±Ø©.  
+
+common.options:Ø®ÙØ§Ø±Ø§Øª
+
+common.processing:Ù
+Ø¹Ø§ÙØ¬Ø©
+
+common.specific_options:Ø®ÙØ§Ø±Ø§Øª Ù
+Ø­Ø¯Ø¯Ø©
+
+common.usage:Ø¥Ø³ØªØ¹Ù
+Ø§Ù
+
+common.info:Ù
+Ø¹ÙÙÙ
+Ø§Øª
+
+common.invalid_options:Ù
+Ø¶Ù
+ÙÙ ØºÙØ± ØµØ§ÙØ­: %s
+
+common.true:ØµØ­ÙØ­  
+
+common.false:Ø²Ø§ØŠÙ  
+
+common.deprecated:Ù
+ØªØ±ÙÙ  
+#
+# Script option descriptions and output messages
+#
+
+scripts.language:ÙØºØ© Ø¹Ø±Ø¶ ÙØµÙ Ø§ÙØ®ÙØ§Ø±Ø§Øª ÙÙ (Ù
+Ø«Ø§ÙØ 'en_us'ÙØ­Ø¯Ø¯ Ø§ÙØ¥Ù
+ÙØ§Ø¡ Ø§ÙØ£Ù
+Ø±ÙÙÙ ). ÙØªØ·ÙØš ØªØ±Ø¬Ù
+Ø© ÙØµÙ Ø§ÙØ®ÙØ§Ø±Ø§Øª Ø§ÙÙ
+ØªÙÙØ±Ø© ÙÙ Ù
+ÙÙ
+
+scripts.xml:ØªÙØªØ¬ Ù
+Ø¹ÙÙÙ
+Ø§Øª ÙÙ ØŽÙÙ Ù
+ÙÙ XML Ø ØšØ¯ÙÙ ØŽÙÙ Ø¹Ø±Ø¶ "Ø¬Ù
+ÙÙ" Ù ÙÙÙ ØšØªÙÙØ± ØªÙØ§ØµÙÙ Ø£ÙØ«Ø±  
+
+scripts.listall:Ø¹Ø±Ø¶ Ø§ÙØ®ÙØ§Ø±Ø§Øª ÙÙÙ Ø§ÙØ¹ÙØ§ØµØ± Ø§ÙÙ
+Ø¹Ø±ÙÙØ© Ø­ÙÙ  
+
+scripts.describeall:Ø®ÙØ§Ø±Ø§Øª Ø§ÙØ¹Ø±Ø¶ ÙÙÙ Ø§ÙÙ
+ÙØ§Ø¯ Ø§ÙÙ
+Ø¹Ø±ÙÙØ©.  
+
+scripts.both_old_options:ØªØ­Ø°ÙØ±: ÙÙ
+ ÙØªÙ
+ ØªØ­Ø¯ÙØ¯ Ø§ÙØ£Ø«ÙÙÙ  -Ø­Ø°Ù Ø§ÙÙØ¯ÙÙ
+ Ù  -Ø­ÙØž Ø§ÙÙØ¯ÙÙ
+, Ø§ÙÙÙÙ
+Ø© Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ© ÙÙ  -Ø­Ø°Ù Ø§ÙÙØ¯ÙÙ
+. Ø³ÙÙ ÙØªÙ
+ Ø­Ø°Ù Ù
+Ø­ØªÙÙØ§Øª Ù
+Ø³Ø§Ø± %s
+
+scripts.no_old_options:ØªØ­Ø°ÙØ±: ÙÙ
+ ÙØªÙ
+ ØªØ­Ø¯ÙØ¯   -Ø­Ø°Ù Ø§ÙÙØ¯ÙÙ
+ Ø£Ù  -Ø­ÙØž Ø§ÙÙØ¯ÙÙ
+, Ø§ÙÙÙÙ
+Ø© Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ© ÙÙ  -Ø­Ø°Ù Ø§ÙÙØ¯ÙÙ
+. Ø³ÙÙ ÙØªÙ
+ Ø­Ø°Ù Ù
+Ø­ØªÙÙØ§Øª Ù
+Ø³Ø§Ø± %s
+
+scripts.gli:Ø§Ø³ØªØ®Ø¯Ù
+ Ø§ÙØ¹ÙÙ
+ Ø¹ÙØ¯ ØªØŽØºÙÙ ÙØ°Ù Ø§ÙÙ
+Ø®Ø·ÙØ·Ø© Ù
+Ù gli ØªÙØŽÙØ· Ø§ÙÙ
+Ø®Ø±Ø¬Ø§Øª Ø§ÙÙ
+Ø®ØµØµØ© Ù gli".  
+
+# -- buildcol.pl --
+
+buildcol.archivedir:Where the archives live.
+
+buildcol.builddir:Ø£ÙÙ ØªÙØ¶Ø¹ Ø§ÙÙØŽØ§ÙØ§Øª Ø§ÙÙ
+ØšÙÙØ©.
+
+buildcol.cachedir:Ø³ÙÙ ÙØªÙ
+ Ù
+Ø€ÙØªØ§ ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ÙÙØ§ ÙØšÙ ÙØ³Ø®ÙØ§ Ø¥ÙÙ Ù
+Ø³Ø§Ø± Ø§ÙØšÙØ§Ø¡.
+
+buildcol.cannot_open_cfg_file:ØªØ­Ø°ÙØ±: ÙØ§ ÙÙ
+ÙÙ ÙØªØ­ Ù
+ÙÙ Ø§ÙØªÙÙÙÙ ÙÙØªØ­Ø¯ÙØ« %s
+
+buildcol.collectdir:Ù
+Ø³Ø§Ø± Ø¯ÙÙÙ "Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©".  
+
+buildcol.copying_back_cached_build:Ø¥Ø¹Ø§Ø¯Ø© Ø§ÙØ·ØšØ§Ø¹Ø© ÙÙ cached build  
+
+buildcol.create_images:Ø­Ø§ÙÙ Ø£Ù ØªÙØŽÙØ¡ ØµÙØ± ØªÙÙØ§ØŠÙØ© ÙÙÙ
+Ø¬Ù
+ÙØ¹Ø©. ÙÙØ°Ø§ ÙØ¹ØªÙ
+Ø¯ Ø¹ÙÙ ØšØ±ÙØ§Ù
+Ø¬ Gimp Ø§ÙÙ
+Ø«ØšØª Ø¹ÙÙ ØšØ±ÙØ§Ù
+Ø¬ Perl ÙÙ ÙØ³Ù
+Ø­ ØšØ§ÙÙØªØ§ØšØ© ÙÙ.  
+
+buildcol.debug:Ø·ØšØ§Ø¹Ø© Ø§ÙÙ
+Ø®Ø±Ø¬Ø§Øª Ø¥ÙÙ STDOUT.
+
+buildcol.desc:ÙØµ Perl Ø§ÙØ°Ù ÙØ³ØªØ®Ø¯Ù
+ ÙØšÙØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø© ÙØ±ÙÙØ³ØªÙÙ Ù
+Ù Ø£Ø±ØŽÙÙ Ø§ÙÙØ«Ø§ØŠÙ  .  
+
+buildcol.faillog:Ù
+Ø¯ÙÙØ© Ù
+ÙÙØ§Øª Ø§ÙØ¥Ø¬Ø±Ø§Ø¡Ø§Øª Ø§ÙÙØ§ØŽÙØ©Ø ØªØªØ¶Ù
+Ù ÙØ°Ù Ø§ÙÙ
+Ø¯ÙÙØ© Ø§Ø³Ù
+Ø§Ø¡ Ù
+ÙÙØ§Øª Ø§ÙØ¥Ø¬Ø±Ø§Ø¡Ø§Øª Ø§ÙØªÙ ÙØŽÙØª  
+
+buildcol.incremental_default_builddir:ØªØ­Ø°ÙØ± : Ø¯ÙÙÙ Ø§ÙØšÙØ§Ø¡ ÙØ¶Ø¹ Ø¥ÙØªØ±Ø§Ø¶ÙØ§ ÙÙ Ø­Ø§ÙØ© ' ØšÙØ§Ø¡ '. Ø¥Ø°Ø§ ÙÙØª ØªØ±ÙØ¯ Ø£Ù ØªØ¶ÙÙ ØªØ¯Ø±ÙØ¬ÙØ§ Ø¥ÙÙ  Ø¯ÙÙÙ Ø§ÙÙØŽØ§Ù Ø ÙØ±Ø¬Ù Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø®ÙØ§Ø±  ""-builddir index" Ù" buildcol.pl""  
+
+buildcol.index:ÙØŽØ§Ù ÙÙØšÙØ§Ø¡ (Ø¥Ø°Ø§ ÙÙ
+ ÙØ­Ø¯Ø¯ Ø³ÙÙ ÙØªÙ
+ ØšÙØ§Ø¡ ÙÙ Ø§ÙÙØŽØ§ÙØ§Øª ÙÙ Ù
+ÙÙ Ø§ÙØ¥Ø¹Ø¯Ø§Ø¯  
+
+buildcol.incremental:ØªÙØŽÙÙ Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ÙÙ
+ ÙØªÙ
+ ØªÙØŽÙÙÙØ§ Ù
+Ù ÙØšÙ.ØªØ·ØšÙÙ -keepold. ØªØ¹ØªÙ
+Ø¯ Ø¹ÙÙ Ù
+ÙØŽÙ lucene .  
+
+buildcol.keepold:ÙÙ ØªØ­Ø·Ù
+ Ø§ÙÙ
+Ø­ØªÙÙØ§Øª Ø§ÙØ­Ø§ÙÙØ© ÙØ¯ÙÙÙ Ø§ÙØšÙØ§Ø¡  
+
+buildcol.maxdocs:Ø§ÙØ¹Ø¯Ø¯ Ø§ÙØ£ÙØµÙ ÙÙÙØ«Ø§ØŠÙ ÙÙØšÙØ§Ø¡.
+buildcol.maxnumeric:Ø£ÙØµÙ Ø¹Ø¯Ø¯ Ø­Ø±ÙÙ ÙÙÙÙ
+Ø© ÙÙ
+ÙÙ Ø£Ù ÙÙÙÙ ÙÙ ÙØ§Ù
+ÙØ³ Ø§ÙÙØŽØ§Ù. Ø§ÙØ£Ø±ÙØ§Ù
+ Ø§ÙÙØšÙØ±Ø© ØªÙÙØ³Ù
+ Ø¥ÙÙ Ø¹Ø¯Ø© ÙÙÙ
+Ø§Øª ÙÙØªÙØŽÙÙ. Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù: ÙÙ ÙØ§Ù Ø£ÙØµÙ Ø¹Ø¯Ø¯ Ø­Ø±ÙÙ ÙÙ 4 ÙØ¥Ù "1342663" Ø³ÙÙ ØªÙÙØ³Ù
+ Ø¥ÙÙ "1342" Ù "663".  
+buildcol.mode:Ø§Ø¬Ø²Ø§Ø¡ Ø¹Ù
+ÙÙØ© Ø§ÙØšÙØ§Ø¡ ÙÙÙ
+ÙØ§ØµÙØ©
+buildcol.mode.all:Ø¥ÙØ¹Ù ÙÙ ØŽÙ.
+buildcol.mode.build_index:ØªÙØŽÙÙ Ø§ÙÙØµ ÙÙØ·.
+buildcol.mode.compress_text:Ø¶ØºØ· Ø§ÙÙØµ ÙÙØ·.
+buildcol.mode.infodb:ØšÙØ§Ø¡ ÙØ§Ø¹Ø¯Ø© ØšÙØ§ÙØ§Øª ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª
+
+buildcol.no_default_images:ÙÙ ÙØªÙ
+ ØªÙÙÙØ¯ Ø§ÙØµÙØ± Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ©.
+
+buildcol.no_image_script:ØªØ­Ø°ÙØ±: Ø§ÙØµÙØ± ØªØ¬Ø¹Ù Ø§ÙÙØµ ØºÙØ± Ù
+ÙØ¬ÙØ¯: %s  
+
+buildcol.no_strip_html:ÙØ§ ØªÙÙÙ
+ ØšØ¥Ø²Ø§ÙØ© Ø¹ÙØ§Ù
+Ø§Øª HTML Ù
+Ù Ø§ÙÙØµ Ø§ÙÙ
+ÙØŽÙ (ØªØ³ØªØ®Ø¯Ù
+ ÙÙØ· Ù
+Ø¹ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª mgpp).  
+
+buildcol.no_text:ÙØ§ ØªØ¶ØºØ· Ø§ÙÙØµ.ÙØ°Ø§ Ø§ÙØ®ÙØ§Ø± Ù
+ÙÙØ¯ ØªÙÙÙÙ Ø­Ø¬Ù
+ Ø§ÙÙØŽØ§ÙØ§Øª Ø§ÙÙ
+ØšÙÙØ© Ø¥Ø°Ø§ ÙÙØª ØªÙÙÙ Ø¯Ø§ØŠÙ
+Ø§ Ø¹Ø±Ø¶ Ø¹Ø±Ø¶ Ø§ÙÙØ«Ø§ØŠÙ ÙÙ Ø²Ù
+Ù Ø§ÙØªØŽØºÙÙ Ø§ÙÙØ¹ÙÙ (Ù
+Ø«Ø§Ù.ÙÙ ØªØ³ØªØ·ÙØ¹
+
+buildcol.sections_index_document_metadata:ØªÙØŽÙÙ ÙØ«ÙÙØ© Ù
+Ø³ØªÙÙ Ø§ÙÙØ§ØµÙØ§Øª Ø¹ÙÙ Ù
+Ø³ØªÙÙ Ø§ÙØ£ÙØ³Ø§Ù
+  
+buildcol.sections_index_document_metadata.never:ÙØ§ ØªÙØŽÙ Ø§Ù ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙÙÙØ«ÙÙØ© Ø¹ÙØ¯ Ù
+Ø³ØªÙÙ Ø§ÙÙØ³Ù
+
+buildcol.sections_index_document_metadata.always:Ø§Ø¶Ù ÙÙ Ø§ÙÙ
+Ø®ØµØµ
+buildcol.sections_index_document_metadata.unless_section_metadata_exists:Ø£Ø¶Ù Ù
+ÙØªØ§Ø¯Ø§ØªØ§ Ø§ÙÙ
+Ø³ØªÙÙ ÙÙØ· Ø¥Ø°Ø§ ÙÙ
+ ÙÙÙ ÙÙØ§Ù Ù
+ÙØªØ§Ø¯Ø§ØªØ§ ÙØ³Ù
+ Ù
+Ø°ÙØ±ÙØ© ÙÙØ°Ø§ Ø§ÙØ§Ø³Ù
+.  
+
+buildcol.out:Ø¥Ø³Ù
+ Ù
+ÙÙ Ø£Ù Ø£Ù Ù
+Ø¹Ø§ÙØ¬Ø© ÙØ·ØšØ§Ø¹Ø© Ø­Ø§ÙØ© Ø§ÙÙ
+Ø®Ø±Ø¬Ø§Øª .  
+
+buildcol.params:[Ø®ÙØ§Ø±Ø§Øª] Ø¥Ø³Ù
+-Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©
+
+buildcol.remove_empty_classifications:ÙÙ
+ ØšØ¥Ø®ÙØ§Ø¡ Ø¹ÙØ§ØµØ± Ø§ÙØªØµÙÙÙ Ø§ÙÙØ§Ø±ØºØ© (ØªÙÙ Ø§ÙØªÙ ÙØ§ ØªØ­ØªÙÙ Ø¹ÙÙ ÙØ«Ø§ØŠÙ).  
+
+buildcol.removeold:Ø³ÙÙ ÙØªÙ
+ Ø­Ø°Ù Ø§ÙÙ
+Ø­ØªÙÙØ§Øª Ø§ÙÙØ¯ÙÙ
+Ø© ÙÙ Ù
+Ø³Ø§Ø± Ø§ÙØšÙØ§Ø¡.
+
+buildcol.unlinked_col_images:ÙØ¯ ÙØ§ ÙØªÙ
+ Ø±ØšØ· ØµÙØ± Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ØšØµÙØ±Ø© ØµØ­ÙØ­Ø©.
+
+buildcol.unknown_mode:Ø³ÙØ§Ù ØºÙØ± Ù
+Ø¹Ø±ÙÙ: %s
+
+buildcol.updating_archive_cache:ØªØ­Ø¯ÙØ« Ø§ÙØ§Ø±ØŽÙÙ Ø§ÙÙ
+Ø®Ø²Ù
+
+buildcol.verbosity:Ø¶ØšØ· ÙÙ
+ÙØ© Ø§ÙÙ
+Ø®Ø±Ø¬t. 0=ÙØ§ØŽÙØ¡, 3=ÙØ«ÙØ±.
+
+
+# -- classinfo.pl --
+
+classinfo.collection:Ø¥Ø¹Ø·Ø§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø© Ø£Ø³Ù
+Ø§ Ø³ÙÙ ÙØ¬Ø¹Ù Ù
+ÙÙ classinfo.pl ÙÙØžØ± ÙÙ collect/collection-
+
+classinfo.desc:Ø·ØšØ§Ø¹Ø© Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø­ÙÙ Ø§ÙÙ
+ØµÙÙ.
+
+classinfo.general_options:Ø§ÙØ®ÙØ§Ø±Ø§Øª Ø§ÙØ¹Ø§Ù
+Ø© ÙØªÙ
+ ØªØ¶Ù
+ÙÙÙØ§ Ù
+Ù Ø§ÙÙØŠØ§Øª Ø§ÙØ£Ù
+ ÙÙÙ
+ØµÙÙ
+
+classinfo.info:Ù
+Ø¹ÙÙÙ
+Ø§Øª
+
+classinfo.no_classifier_name:Ø®Ø·Ø£: ÙØ¬Øš Ø¥Ø¹Ø·Ø§ Ø¥Ø³Ù
+ Ù
+ØµÙÙ.
+
+classinfo.option_types:Ø§ÙØ®ÙØ§Ø±Ø§Øª Ø§ÙÙ
+Ø­Ø¯Ø¯Ø© Ù
+Ø¹Ø±ÙØ© ÙÙØ· Ø¶Ù
+Ù Ø§ÙÙ
+ØµÙÙØ Ù ÙÙ Ù
+ØªÙÙØ±Ø© Ø¯Ø§ØŠÙ
+Ø§ ÙÙØ°Ø§ Ø§ÙÙ
+ØµÙÙ.  
+
+classinfo.params:[Ø®ÙØ§Ø±Ø§Øª] Ø¥Ø³Ù
+-Ù
+ØµÙÙ
+
+classinfo.passing_options:ÙÙ
+ÙÙ ØªÙ
+Ø±ÙØ± Ø§ÙØ®ÙØ§Ø±Ø§Øª ÙØ¢Ù  plugout ØšØªØ¶Ù
+ÙÙÙØ§ ÙÙ Ù
+ÙÙ Ø§ÙØ¥Ø¹Ø¯Ø§Ø¯ collect.cfg  
+
+classinfo.specific_options:Ø§ÙØ®ÙØ§Ø±Ø§Øª Ø§ÙÙ
+Ø­Ø¯Ø¯Ø© Ù
+Ø¹Ø±ÙØ© ÙÙØ· Ø¶Ù
+Ù Ø§ÙÙ
+ØµÙÙØ Ù ÙÙ Ù
+ØªÙÙØ±Ø© Ø¯Ø§ØŠÙ
+Ø§ ÙÙØ°Ø§ Ø§ÙÙ
+ØµÙÙ  
+
+# -- downloadfrom.pl --
+downloadfrom.cache_dir:Ù
+ÙÙØ¹ Ù
+Ø³Ø§Ø± Ø§ÙØªØ®Ø²ÙÙ
+downloadfrom.desc:ØªØ­Ù
+ÙÙ Ù
+ÙÙØ§Øª Ù
+Ù Ù
+Ø²ÙØ¯ Ø®Ø§Ø±Ø¬Ù
+downloadfrom.download_mode:ÙÙØ¹ Ø§ÙÙ
+Ø²ÙØ¯ Ø§ÙÙ
+ÙØ²Ù Ù
+ÙÙ
+downloadfrom.download_mode.Web:ØšØ±ÙØªÙÙÙÙ ÙÙÙ Ø§ÙÙØµ Ø§ÙØªØŽØ¹ØšÙ
+downloadfrom.download_mode.MediaWiki:Ù
+ÙÙØ¹ MediaWiki  
+downloadfrom.download_mode.OAI:Ù
+ØšØ§Ø¯Ø±Ø© Ø§ÙØ£Ø±ØŽØšÙ Ø§ÙÙ
+ÙØªÙØ­
+downloadfrom.download_mode.z3950:z3950 Ù
+Ø²ÙØ¯
+downloadfrom.download_mode.SRW:ØšØ­Ø«Ø¥Ø³ØªØ±Ø¬Ø§Ø¹ Ø®Ø¯Ù
+Ø§Øª Ø§ÙÙØš SRW
+downloadfrom.incorrect_mode:Ù
+Ø€ØŽØ± Ø³ÙØ§Ù Ø§ÙØªØ­Ù
+ÙÙ ØºÙØ± ØµØ­ÙØ­.
+downloadfrom.info:Ø¥Ø·ØšØ¹ Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø­ÙÙ Ø§ÙÙ
+Ø²ÙØ¯ Ø£ÙØ«Ø± Ù
+Ù Ø§ÙØªÙØ²ÙÙ
+downloadfrom.params:[Ø®ÙØ§Ø±Ø§Øª Ø¹Ø§Ù
+Ø©] [Ø®ÙØ§Ø±Ø§Øª Ø§ÙØªÙØ²ÙÙ Ø§ÙØ®Ø§ØµØ©]
+
+# -- downloadinfo.pl --
+
+downloadinfo.desc:Ø·ØšØ§Ø¹Ø© Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø­ÙÙ ÙÙ
+ÙØ°Ø¬ Ø§ÙØªØ­Ù
+ÙÙ
+downloadinfo.collection:Ø¥Ø¹Ø·Ø§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§Ø³Ù
+ Ø³ÙÙØŽÙØ¡ Ù
+ÙÙ download.pl ÙØ§ÙØžØ± Ø£ÙÙØ§ ÙÙ Ùcollect/collection-name/perllib/downloaders . ÙÙ ÙØ§Ù Ø§ÙØšØ±ÙØ§Ù
+Ø¬ ØºÙØ± Ù
+ÙØ¬ÙØ¯ ÙÙØ§Ù Ø³ÙÙ ÙØšØ­Ø« ÙÙ Ø¯ÙÙÙ perllib/downloaders Ø§ÙØ¹Ø§Ù
+.  
+downloadinfo.params:[Ø®ÙØ§Ø±Ø§Øª] [ÙÙ
+ÙØ°Ø¬-Ø§ÙØªÙØ²ÙÙ]
+downloadinfo.general_options:Ø§ÙØ®ÙØ§Ø±Ø§Øª Ø§ÙØ¹Ø§Ù
+Ø© ÙØªÙ
+ ØªØ¶Ù
+ÙÙÙØ§ Ù
+Ù Ø§ÙÙØŠØ§Øª Ø§ÙØ£Ù
+ ÙÙÙ
+ØµÙÙ
+downloadinfo.specific_options:Ø§ÙØ®ÙØ§Ø±Ø§Øª Ø§ÙÙ
+Ø­Ø¯Ø¯Ø© Ù
+Ø¹Ø±ÙØ© Ø¶Ù
+Ù ÙØ­Ø¯Ø© Ø§ÙØªÙØ²ÙÙØ ÙÙÙ Ù
+ØªÙÙØ±Ø© Ø¯Ø§ØŠÙ
+Ø§ ÙÙØ°Ø§ Ø§ÙÙ
+ÙØ²Ù.  
+downloadinfo.option_types:ÙØ­Ø¯Ø§Øª Ø§ÙØªÙØ²ÙÙ ÙÙ
+ÙÙ Ø£Ù ØªØ£Ø®Ø° ÙÙØ¹ÙÙ Ù
+Ù Ø§ÙØ®ÙØ§Ø±Ø§Øª  
+
+# -- explode_metadata_database.pl --
+explode.desc:ØªØ¬Ø²ØŠØ© ÙØ§Ø¹Ø¯Ø© ØšÙØ§ÙØ§Øª ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª
+
+explode.collection:Ø§Ø³Ù
+ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© . ØšØ¹Ø¶  Ø§ÙÙ
+ÙØ§ØšØ³ ØªØšØ­Ø« Ø¹Ù Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØ¥Ø¶Ø§ÙÙØ© ÙÙ Ù
+Ø¬ÙØ¯ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© .  
+ 
+explode.document_field:Ø¹ÙØµØ± ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙØ°Ù ÙØ­Ø¯Ø¯ Ø¥Ø³Ù
+ Ù
+ÙÙ Ø§ÙÙØ«Ø§ØŠÙ ÙØªØ¶Ù
+ÙÙÙ ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©  
+
+explode.document_prefix:ØšØ§Ø¯ØŠØ© ÙÙ
+ÙØ§ÙØ¹ Ø§ÙÙØ«ÙÙØ© ( ÙÙØ¥Ø³ØªØ®Ø¯Ø§Ù
+ Ù
+Ø¹ document_field option).  
+
+explode.document_suffix:ÙØ§Ø­ÙØ© ÙÙ
+ÙØ§ÙØ¹ Ø§ÙÙØ«ÙÙØ© ( ÙÙØ¥Ø³ØªØ®Ø¯Ø§Ù
+ Ù
+Ø¹  document_field option).  
+
+explode.encoding:Ø§ÙØªØ±Ù
+ÙØ² ÙÙØ¥Ø³ØªØ®Ø¯Ø§Ù
+ Ø¹ÙØ¯ ÙØ±Ø§Ø¡Ø© Ù
+ÙÙ ÙØ§Ø¹Ø¯Ø© Ø§ÙØšÙØ§ÙØ§Øª  
+explode.metadata_set:Ù
+Ø¹ÙØ§Ø± ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª (Ø¥Ø³Ù
+ Ù
+Ø³Ø§Ø­Ø©) ÙØªØµØ¯ÙØ± ÙÙ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ù
+Ø«ÙÙ  
+explode.plugin:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙÙØªØ¬Ø²ØŠØ©
+explode.plugin_options:Ø®ÙØ§Ø±Ø§Øª ÙØªÙ
+Ø±Ø± Ø¥ÙÙ Ø§ÙÙ
+ÙØ§ØšØ³ ÙØšÙ Ø§ÙØªØ¬Ø²ØŠØ©.Ø®ÙØ§Ø±Ø§Øª  Ø§ÙØ¥Ø³Ù
+  ÙØ¬Øš Ø£Ù ØªØšØ¯Ø£ Øš - . Ø£ÙØµÙ Ø£Ø³Ù
+Ø§Ø¡ Ù ÙÙÙ
+ Ø§ÙØ®ÙØ§Ø± ØšÙ
+Ø³Ø§ÙØ©.  
+explode.use_collection_plugin_options:Ø§ÙØ±Ø£ Ù
+ÙÙ ØªØ¬ÙÙØ² Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ù Ø§Ø³ØªØ®Ø¯Ù
+ Ø®ÙØ§Ø±Ø§Øª Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙÙ
+Ø®ØµØµ . ÙØªØ·ÙØš -Ø®ÙØ§Ø±Ø§Øª Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©. ÙØ§ ÙÙ
+ÙÙ Ø£Ù ÙØ³ØªØ®Ø¯Ù
+ Ù
+Ø¹ - plugin_options  
+explode.params:[Ø®ÙØ§Ø±Ø§Øª] Ø¥Ø³Ù
+ Ù
+ÙÙ
+explode.records_per_folder:Ø±ÙÙ
+ Ø§ÙØªØ³Ø¬ÙÙØ§Øª Ø§ÙÙ
+Ø·ÙÙØš  ÙÙ ÙÙ Ù
+Ø¬ÙØ¯ ÙØ±Ø¹Ù.
+
+# -- replace_srcdoc_with_html.pl --
+srcreplace.desc:Ø£Ø³ØªØšØ¯Ø§Ù Ù
+ØµØ¯Ø± ÙØ«ÙÙØ© ØšÙ
+ÙÙ HTML Ù
+ÙÙØ¯ Ø¹ÙØ¯ Ø¥Ø¹Ø§Ø¯Ø© Ø§ÙØšÙØ§Ø¡ .  
+srcreplace.params:Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙ[Ø®ÙØ§Ø±Ø§Øª]  
+srcreplace.plugin:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙØ°Ù ÙØ³ØªØ®Ø¯Ù
+ ÙØªØ­ÙÙÙ Ù
+ØµØ¯Ø± Ø§ÙÙØ«ÙÙØ©  
+
+# -- exportcol.pl --
+
+exportcol.out:Ø¥Ø³Ù
+ Ù
+ÙÙ Ø£Ù Ø£Ù Ù
+Ø¹Ø§ÙØ¬Ø© ÙØ·ØšØ§Ø¹Ø© Ø­Ø§ÙØ© Ø§ÙÙ
+Ø®Ø±Ø¬Ø§Øª .  
+exportcol.cddir:Ø¥Ø³Ù
+ Ø§ÙÙ
+Ø³Ø§Ø± Ø§ÙØ°Ù ØªÙØ¯ ØªØµØ¯ÙØ± Ù
+ÙÙÙØ§Øª Ø§ÙÙØ±Øµ Ø¥ÙÙÙ.
+exportcol.cdname:Ø£Ø³Ù
+ Ø§ÙÙØ±Øµ Ø§ÙÙ
+Ø¶ØºÙØ· -- ÙÙÙ Ø§ÙØ°Ù ÙØžÙØ± ÙÙ ÙØ§ØŠÙ
+Ø© Ø¥ØšØ¯Ø£ Ø¹ÙØ¯ ØªØ«ØšÙØª Ø§ÙÙØ±Øµ Ø§ÙÙ
+Ø¶ØºÙØ·.
+exportcol.desc:ØšØ±Ù
+Ø¬Ø© PERL ØªØ³ØªØ®Ø¯Ù
+ ÙØªØµØ¯ÙØ± ÙØ§Ø­Ø¯Ø© Ø£Ù Ø£ÙØ«Ø± Ù
+Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø¥ÙÙ ÙØ±Øµ Ù
+Ø¯Ù
+Ø¬ ÙÙ ØšÙØŠØ© Windows.  
+exportcol.noinstall:Ø¥ÙØŽØ§Ø¡ ÙØ±Øµ Ù
+Ø¯Ù
+Ø¬ ÙØªØŽØºÙÙ Ø§ÙÙ
+ÙØªØšØ© Ù
+ØšØ§ØŽØ±Ø© Ù
+ÙÙ ØšØ­ÙØ« ÙØ§ ÙØªÙ
+ ØªØ«ØšÙØª ØŽÙ ÙÙ Ø§ÙØ­Ø§Ø³Øš Ø§ÙÙ
+Ø¶ÙÙ  
+exportcol.params:[Ø®ÙØ§Ø±Ø§Øª] Ø¥Ø³Ù
+-Ù
+Ø¬Ù
+ÙØ¹Ø©1 Ø¥Ø³Ù
+-Ù
+Ø¬Ù
+ÙØ¹Ø©2 ...
+exportcol.coll_not_found:ØªØ¬Ø§ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© ØºÙØ± ØµØ§ÙØ­Ø© %s: ÙØ§ ØªÙØ¬Ø¯ Ù
+Ø¬Ù
+ÙØ¹Ø© ÙÙ %s.
+exportcol.coll_dirs_not_found:ØªØ¬Ø§ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª ØºÙØ± Ø§ÙØµØ§ÙØ­Ø© %s: ÙØ§ ÙÙØ¬Ø¯ ÙØ§Ø­Ø¯ Ù
+Ù Ø§ÙÙ
+Ø¬ÙØ¯Ø§Øª Ø§ÙØªØ§ÙÙØ©:
+exportcol.fail:exportcol.pl ÙØŽÙ:
+exportcol.no_valid_colls:ÙÙ
+ ÙØªÙ
+ ØªØ­Ø¯ÙØ¯ Ù
+Ø¬Ù
+ÙØ¹Ø© ØµØ§ÙØ­Ø© ÙÙØªØµØ¯ÙØ±.
+exportcol.couldnt_create_dir:ÙÙ
+ ÙØªÙ
+ Ø¥ÙØŽØ§Ø¡ Ù
+Ø³Ø§Ø± %s.
+exportcol.couldnt_create_file:ÙÙ
+ ÙØªÙ
+ Ø¥ÙØŽØ§Ø¡ %s.
+exportcol.instructions:ÙØ¥ÙØŽØ§Ø¡ ÙØ±Øµ Ù
+Ø¯Ù
+Ø¬ Ø°Ø§ØªÙ Ø§ÙØªØŽØºÙÙ ÙØ§ÙØªØ«ØšÙØª ÙÙ ØšÙØŠØ© WindowsØ Ø§ÙØ³Ø® Ù
+Ø­ØªÙØ§ÙØª ÙØ°Ø§ Ø§ÙÙ
+Ø¬ÙØ¯ Ø¥ÙÙ Ø§ÙÙØ±Øµ Ø§ÙÙ
+Ø¯Ù
+Ø¬.  
+exportcol.non_exist_files:ÙØ§Ø­Ø¯ Ø£Ù Ø£ÙØ«Ø± Ù
+Ù Ø§ÙÙ
+ÙÙØ§Øª Ù Ø§ÙÙ
+Ø¬ÙØ¯Ø§Øª Ø§ÙØªØ§ÙÙØ© ÙÙ
+ ÙØªÙ
+ Ø§ÙØ¹Ø«ÙØ± Ø¹ÙÙÙ  
+exportcol.success:exportcol.pl ÙØ¬Ø­:
+exportcol.output_dir:Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙÙ
+ØµØ¯Ø±Ø© (%s) ÙÙ ÙÙ %s.
+exportcol.export_coll_not_installed:ÙØžÙÙØ© Ø§ÙØªØµØ¯ÙØ± Ø¥ÙÙ ÙØ±Øµ Ù
+Ø¯Ù
+Ø¬ ÙÙ
+ ØªÙÙ Ù
+Ø«ØšØªØ©.  
+
+# -- import.pl --
+
+import.archivedir:Ø­ÙØ« Ø³ØªÙØªÙÙ Ø§ÙÙ
+ÙØ§Ø¯ Ø§ÙÙ
+Ø­ÙÙØ©.  
+
+import.manifest:Ù
+ÙÙ XML Ø§ÙØ°Ù ÙÙØµÙ Ù
+Ø§ ÙÙ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØªÙ ÙØ¬Øš Ø§Ù ØªØ³ØªÙØ±Ø¯. Used instead of recursively descending the import folder, typically for incremental building.  
+
+import.cannot_open_stats_file:ØªØ­Ø°ÙØ±: ÙØ§ ÙÙ
+ÙÙ ÙØªØ­ Ù
+ÙÙ Ø§ÙØ¥Ø­ØµØ§Ø¡ %s.
+
+import.cannot_open_fail_log:Ø®Ø·Ø£: ÙØ§ ÙÙ
+ÙÙ ÙØªØ­ Ù
+Ø¯ÙÙØ© Ø§ÙØ£Ø®Ø·Ø§Ø¡ %s
+
+import.cannot_sort:ØªØ­Ø°ÙØ±: ÙÙ ÙØªÙ
+ÙÙimport.pl Ù
+Ù ÙØ±Ø² Ø§ÙÙØ«Ø§ØŠÙ Ø¹ÙØ¯Ù
+Ø§ ÙÙÙÙ Ø­Ø¬Ù
+ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© > 1. Ø³ÙÙ ÙØªÙ
+ Ø¥ÙÙ
+Ø§Ù Ø®ÙØ§Ø±Ø§Øªsortmeta .
+
+import.collectdir:Ù
+Ø³Ø§Ø± Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©.
+
+import.complete:Ø¥ÙØªÙ
+Ù Ø§ÙØ¥Ø³ØªÙØ±Ø§Ø¯
+
+import.debug:Ø·ØšØ§Ø¹Ø© Ø§ÙÙØµ Ø§ÙÙ
+Ø³ØªÙØ±Ø¯ Ø¥ÙÙ STDOUT. (ÙØ§Ø³ØªÙØ±Ø§Ø¯ Ø¬Ø±ÙÙØ³ØªÙÙ XML )  
+
+import.desc:Ù
+Ø®Ø·ÙØ·Ø© PERL Ø§ÙØªÙ ØªØ³ØªØ®Ø¯Ù
+ ÙØ¥Ø³ØªÙØ±Ø§Ø¯ Ø§ÙÙ
+ÙÙØ§Øª ÙÙ ØŽÙÙ (Ø¬Ø±ÙÙØ³ØªÙÙ XML Ø£Ù Ø¬Ø±ÙÙØ³ØªÙÙ METS) Ø¥Ø³ØªØ¹Ø¯Ø§Ø¯Ø§ ÙØšÙØ§ØŠÙØ§.  
+
+import.faillog:Ù
+Ø¯ÙÙØ© Ù
+ÙÙØ§Øª Ø§ÙØ¥Ø¬Ø±Ø§Ø¡Ø§Øª Ø§ÙÙØ§ØŽÙØ©Ø ØªØªØ¶Ù
+Ù ÙØ°Ù Ø§ÙÙ
+Ø¯ÙÙØ© Ø§Ø³Ù
+Ø§Ø¡ Ù
+ÙÙØ§Øª Ø§ÙØ¥Ø¬Ø±Ø§Ø¡Ø§Øª Ø§ÙØªÙ ÙØŽÙØª
+
+import.groupsize:Ø¹Ø¯Ø¯ Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙÙ
+Ø³ØªÙØ±Ø¯Ø© ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ÙÙ Ù
+ÙÙ XML ÙØ§Ø­Ø¯  
+
+import.gzip:Ø§Ø³ØªØ®Ø¯Ù
+ gzip ÙØ¶ØºØ· ÙØ«Ø§ØŠÙ xml Ø§ÙÙØ§ØªØ¬Ø© ( ÙØ§ ØªÙØ³Ù ØªØ¶Ù
+ÙÙ ZIPPlug ÙÙ ÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+ÙØ§ØšØ³ Ø¹ÙØ¯ Ø§ÙØšÙØ§Ø¡ Ù
+Ù ÙØ«Ø§ØŠÙ Ù
+Ø¶ØºÙØ·Ø©)  
+
+import.importdir:Ø­ÙØ« ØªÙØ¬Ø¯ Ø§ÙÙ
+ÙØ§Ø¯ Ø§ÙØ£ØµÙÙØ©  
+
+import.incremental:Ø¥Ø³ØªÙØ±Ø§Ø¯ Ø§ÙÙØ«Ø§ØŠÙ ÙØ¬Ø¯ÙØ¯Ø© (ÙÙØ¯ Ø²Ù
+ÙÙ)Ø¯ÙÙ Ù
+ÙÙØ§Øª Ø§ÙØ£Ø±ØŽÙÙ Ø§ÙØ­Ø§ÙÙØ©. ØªØ¹ÙÙ  -keepold.  
+
+import.keepold:ÙÙ ØªØ­Ø·Ù
+ Ø§ÙÙ
+Ø­ØªÙÙØ§Øª Ø§ÙØ­Ø§ÙÙØ© ÙÙ Ø¯ÙÙÙ Ø§ÙØ£Ø±ØŽÙÙ  
+
+import.maxdocs:Ø§ÙØ¹Ø¯Ø¯ Ø§ÙØ£ÙØµÙ ÙÙÙØ«Ø§ØŠÙ ÙÙØ¥Ø³ØªÙØ±Ø§Ø¯.
+
+import.no_import_dir:Ø®Ø·Ø£: Ù
+Ø³Ø§Ø± Ø§ÙØ¥Ø³ØªÙØ±Ø§Ø¯  (%s) ØºÙØ± Ù
+ÙØ¬ÙØ¯.
+
+import.no_plugins_loaded:Ø®Ø·Ø£: ÙÙ
+ ÙØªÙ
+ ØªØ­Ù
+ÙÙ Ù
+ÙØ§ØšØ³.
+
+import.OIDtype:Ø§ÙÙ
+ÙÙØ¬ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ Ø¹ÙØ¯ ØªÙÙÙØ¯ Ù
+Ø­Ø¯Ø¯Ø§Øª ÙØ±ÙØ¯Ø© ÙØ¢Ù ÙØ«ÙÙØ©.
+import.OIDtype.hash:Ù
+Ø²Ø¬ Ù
+Ø­ØªÙÙØ§Øª Ø§ÙÙ
+ÙÙ.Ø³ÙÙ ØªØšÙÙ Ù
+Ø¹Ø±ÙØ§Øª Ø§ÙÙØ«ÙÙØ© ÙÙ
+Ø§ ÙÙ ÙÙ ÙÙ Ù
+Ø±Ø© ÙØªÙ
+ ÙÙÙØ§ Ø¥Ø³ØªÙØ±Ø§Ø¯ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©  
+
+import.OIDtype.incremental:Ø§Ø³ØªØ®Ø¯Ù
+ Ø¹Ø¯Ø§Ø¯ ÙØ«ÙÙØ© ØšØ³ÙØ·. ÙÙ Ø£Ø³Ø±Ø¹ ØšÙØ«ÙØ± Ù
+Ù "hash"Ø ÙÙÙÙ ÙØ§ ØªØ­Ø¯Ø¯ ÙÙØ³ Ø§ÙÙ
+Ø­Ø¯Ø¯Ø§Øª ÙÙÙØ³ Ø¹Ø¯Ø§Ø¯ Ø§ÙÙØ«ÙÙØ©Ø ÙÙØ°ÙÙ ÙØ§ ÙÙ
+ÙÙ Ø¥Ø¶Ø§ÙØ© ÙØ«Ø§ØŠÙ Ø¬Ø¯ÙØ¯Ø© ÙÙØ£Ø±ØŽÙÙØ§Øª Ø§ÙÙ
+ÙØ¬ÙØ¯Ø©.  
+
+import.OIDtype.assigned:Ø§Ø³ØªØ®Ø¯Ù
+ ÙÙÙ
+Ø© ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙÙ
+Ø¹Ø·Ø§Ø© ØšÙØ§Ø³Ø·Ø© Ø®ÙØ§Ø± OIDmetadata (Ù
+Ø³ØšÙÙØ© Øš "D"); Ø¥Ø°Ø§ ÙÙ
+ ÙØªÙ
+ ØªØ­Ø¯ÙØ¯ÙØ§ ÙÙØ«ÙÙØ© Ù
+Ø­Ø¯Ø¯Ø© Ø³ÙÙ ÙØªÙ
+ Ø¥Ø³ØªØ®Ø¯Ø§Ù
+ # ØšØ¯ÙØ§ Ù
+ÙÙØ§. ÙØ¬Øš Ø£Ù ØªÙÙÙ ÙØ°Ù Ø§ÙÙ
+Ø¹Ø±ÙØ§Øª ÙØ±ÙØ¯Ø©.  
+
+import.OIDtype.dirname:Ø¥Ø³ØªØ®Ø¯Ù
+ Ø¥Ø³Ù
+ Ø§ÙØ¯ÙÙÙ Ø§ÙØ¹Ø§ØŠÙÙ(Ù
+Ø³ØšÙÙØ§ ØšÙ "j" . ÙØ¬Øš Ø§Ù ØªÙÙÙ ÙÙØ§Ù ÙØ«ÙÙØ© ÙØ§Ø­Ø¯Ø© ÙÙ ÙÙ Ø¯ÙÙÙØ Ù ÙØ¬Øš Ø§Ù ÙÙÙÙ Ø£Ø³Ù
+ Ø§ÙØ¯ÙÙÙ ÙØ±ÙØ¯Ø§. Ù
+Ø«Ø§Ù Ø  import/b13as/h15ef/page.html Ø³ÙÙ ÙØ­ØµÙ Ø¹ÙÙ Ø§ÙÙ
+Ø¹Ø±Ù Jh15ef.  
+
+import.OIDmetadata:ØªØ®ØµÙØµ Ø¹ÙØµØ± ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙØ°Ù ÙØ­Ø¬Ø² ÙÙÙØ«ÙÙØ© Ø§ÙÙ
+Ø­Ø¯Ø¯ Ø§ÙÙØ±ÙØ¯Ø ÙÙØ¥Ø³ØªØ®Ø¯Ø§Ù
+ Ù
+Ø¹  -OIDtype=.  
+
+import.saveas:ÙØ°Ø§ ÙØªØ­Ø¯ÙØ¯ Ø£Ù Ø£ØŽÙØ§Ù Ø§ÙØ£Ø±ØŽÙÙ Ø§ÙØªÙ ÙØ¬Øš ØªÙÙÙØ¯ÙØ§. Ø§ÙØŽÙÙ Ø§ÙØ¥ÙØªØ±Ø§Ø¶Ù ÙÙ  GA.  
+
+import.out:Ø¥Ø³Ù
+ Ù
+ÙÙ Ø£Ù Ø£Ù Ù
+Ø¹Ø§ÙØ¬Ø© ÙØ·ØšØ§Ø¹Ø© Ø­Ø§ÙØ© Ø§ÙÙ
+Ø®Ø±Ø¬Ø§Øª  
+
+import.params:[Ø®ÙØ§Ø±Ø§Øª] Ø¥Ø³Ù
+-Ù
+Ø¬Ù
+ÙØ¹Ø©
+
+import.removeold:Ø³ÙÙ ÙØªÙ
+ Ø¥Ø²Ø§Ø­Ø© Ø§ÙÙ
+Ø­ØªÙÙØ§Øª Ø§ÙÙØ¯ÙÙ
+Ø© Ù
+Ù Ù
+Ø³Ø§Ø± Ø§ÙØ£Ø±ØŽÙÙ.
+
+import.removing_archives:Ø¥Ø²Ø§Ø­Ø© Ø§ÙÙ
+Ø­ØªÙÙØ§Øª Ø§ÙØ­Ø§ÙÙØ© ÙÙ Ù
+Ø³Ø§Ø± Ø§ÙØ£Ø±ØŽÙÙ
+
+import.removing_tmpdir:Ø¥Ø²Ø§Ø­Ø© Ù
+Ø­ØªÙÙØ§Øª Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ÙÙ Ø§ÙÙ
+Ø³Ø§Ø± Ø§ÙÙ
+Ø€ÙØª...
+
+import.reversesort:ÙØ±Ø² ØšØªØ±ØªÙØš Ø¹ÙØ³Ù. ÙØ³ØªØ¹Ù
+Ù Ù
+Ø¹ Ø®ÙØ§Ø± - sortmeta .  
+
+import.site:Ù
+ÙÙØ¹ ÙÙØ¹Ø«ÙØ± Ø¹ÙÙ Ø¯ÙÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© ÙÙ (ÙØªØ«ØšÙØª Ø¬Ø±ÙÙØ³ØªÙÙ 3).  
+
+import.sortmeta:ÙØ±Ø² Ø§ÙÙØ«Ø§ØŠÙ Ø£ÙÙØšØ§ØŠÙØ§ ØšÙØ§Ø³Ø·Ø© ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª ÙÙØšÙØ§Ø¡.Ø³ÙÙ ÙØªÙ
+ Ø¥Ø®Ù
+Ø§Ø¯ ÙØ°Ø§ Ø§ÙØ¥Ø¬Ø±Ø§Ø¡ Ø¥Ø°Ø§ ÙØ§ÙØª ÙÙÙ
+Ø© groupsize > 1.  
+
+import.statsfile:Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙ Ø£Ù Ø§ÙØªØ¹Ø§Ù
+Ù ÙØ·ØšØ§Ø¹Ø© Ø¥Ø­ØµØ§Ø¡Ø§Øª Ø§ÙØªØµØ¯ÙØ± ÙÙ.  
+
+import.stats_backup:Ø³ÙÙ ÙØ·ØšØ¹ Ø§ÙØ­Ø§ÙØ§Øª ÙÙ STDERR ØšØ¯ÙØ§Ù.  
+
+import.verbosity:Ø¶ØšØ· ÙÙ
+ÙØ© Ø§ÙÙ
+Ø®Ø±Ø¬t. 0=ÙØ§ØŽÙØ¡, 3=ÙØ«ÙØ±.
+
+# -- schedule.pl --
+schedule.deleted:Ø¥ÙØºØ§Ø¡ Ø§ÙØ¬Ø¯ÙÙØ© Ø§ÙÙ
+Ø¹Ø¯Ø© ÙÙ
+Ø¬Ù
+ÙØ¹Ø©  
+schedule.scheduled:Ù
+Ø®Ø·ÙØ·Ø© Ø§ÙØªÙÙÙØ° Ø§ÙØªÙ Ø£ÙØŽØŠØª ÙÙ
+Ø¬Ù
+ÙØ¹Ø©.  
+schedule.cron:ØªÙÙÙØ° Ø§ÙØ¬Ø¯ÙÙØ© Ø§ÙÙ
+Ø¹Ø¯Ø© ÙÙ
+Ø¬Ù
+ÙØ¹Ø©  
+schedule.params:[Ø§ÙØ®ÙØ§Ø±Ø§Øª]  
+schedule.error.email:Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ ÙØªØ·ÙØš ØªØ­Ø¯ÙØ¯  -smtp -toaddr Ù -fromaddr.  
+schedule.error.importbuild:ÙØ¬Øš ØªØ­Ø¯ÙØ¯ build- Ù import-.  
+schedule.error.colname:ÙØ¬Øš ØªØ­Ø¯ÙØ¯ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙØªÙ ØªØ³ØªØ®Ø¯Ù
+ -colname .  
+schedule.gli:ØªØŽØºÙÙ Ù
+Ù GLI  
+schedule.frequency:Ø¹Ø¯Ø¯ Ù
+Ø±Ø§Øª Ø¥Ø¹Ø§Ø¯Ø© Ø§ÙØšÙØ§Ø¡ Ø§ÙØªÙÙØ§ØŠÙ  
+schedule.frequency.hourly:Ø¥Ø¹Ø§Ø¯Ø© ØšÙØ§Ø¡ ÙÙ Ø³Ø§Ø¹Ø©  
+schedule.frequency.daily:Ø¥Ø¹Ø§Ø¯Ø© ØšÙØ§Ø¡ ÙÙ ÙÙÙ
+  
+schedule.frequency.weekly:Ø¥Ø¹Ø§Ø¯Ø© ØšÙØ§Ø¡ ÙÙ Ø£Ø³ØšÙØ¹  
+schedule.action:ÙÙÙ ØªØ¹Ø¯ Ø¥Ø¹Ø§Ø¯Ø© ØšÙØ§Ø¡ ØªÙÙØ§ØŠÙØ§.  
+schedule.action.add:Ø¬Ø¯ÙÙØ© Ø¥Ø¹Ø§Ø¯Ø© Ø§ÙØšÙØ§Ø¡  ØªÙÙØ§ØŠÙØ§  
+schedule.action.update:ØªØ­Ø¯ÙØ« Ø¬Ø¯ÙÙØ© Ù
+ÙØ¬ÙØ¯Ø©  
+schedule.action.delete:Ø­Ø°Ù Ø¬Ø¯ÙÙØ© Ù
+ÙØ¬ÙØ¯Ø©  
+schedule.email:Ø£Ø±Ø³Ù  Ø¥Ø®Ø·Ø§Ø±  ØšØ§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ  
+schedule.schedule:Ø¥Ø®ØªÙØ§Ø± Ø¬Ø¯ÙÙØ© Ù
+Ø¬Ù
+ÙØ¹Ø© ØªÙÙØ§ØŠÙØ§ ÙØ¥Ø¹Ø§Ø¯Ø© ØšÙØ§Ø¡ .  
+schedule.colname:Ø§Ø³Ù
+ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙØªÙ Ø³ÙÙ ØªØªÙ
+ Ø¬Ø¯ÙÙØªÙØ§  
+schedule.import:Ø£Ù
+Ø± Ø§ÙØ¥Ø³ØªÙØ±Ø§Ø¯ ÙØ¬Ø¯ÙÙØªÙ  
+schedule.build:Ø£Ù
+Ø± ØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙÙ
+Ø²Ù
+Ø¹ Ø¬Ø¯ÙÙØªÙ  
+schedule.toaddr:Ø¹ÙÙØ§Ù Ø§ÙØšØ±ÙØ¯ Ø§ÙØ§ÙÙØªØ±ÙÙÙ ÙØ§Ø±Ø³Ø§Ù Ø¥Ø®Ø·Ø§Ø±Ø§Øª Ø§ÙØšÙØ§Ø¡ Ø§ÙÙ
+Ø¬Ø¯ÙÙØ©.  
+schedule.toaddr.default:Ø­Ø¯Ø¯ ØšØ±ÙØ¯ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ Ø§ÙØ§ÙÙØªØ±ÙÙÙ  ÙÙ Ù
+ÙÙ-> ØªÙØ¶ÙÙØ§Øª  
+schedule.fromaddr:Ø¹ÙÙØ§Ù Ø§ÙØšØ±ÙØ¯ Ø§ÙØ§ÙÙØªØ±ÙÙÙ ÙÙÙ
+Ø±Ø³Ù  
+schedule.fromaddr.default:Ø­Ø¯Ø¯ maintainer ÙÙ main.cfg  
+schedule.smtp:Ù
+Ø²ÙØ¯ Ø®Ø¯Ù
+Ø© Ø§ÙØšØ±ÙØ¯ Ø§ÙØ°Ù ÙØ±Ø³Ù Ø§ÙØšØ±ÙØ¯ ÙØ¬Øš Ø§Ù ÙÙÙÙ Ù
+ØªØµÙØ§ ÙØ¥Ø±Ø³Ø§Ù ØšØ±ÙØ¯ Ø¥ÙÙØªØ±ÙÙÙ  
+schedule.smtp.default:Ø­Ø¯Ø¯ Ù
+Ø²ÙØ¯ Ø§ÙØšØ±ÙØ¯ ÙÙ main.cfg  
+schedule.out:Ø§Ø³Ù
+ Ù
+ÙÙ ÙØ·ØšØ§Ø¹Ø© Ø­Ø§ÙØ© Ø§ÙÙ
+Ø®Ø±Ø¬Ø§Øª Ø§ÙÙ.  
+# -- export.pl --
+
+export.exportdir:Ø­ÙØ« ØªÙØªÙÙ Ø§ÙÙ
+ÙØ§Ø¯ Ø§ÙÙ
+ØµØ¯Ø±Ø©  
+
+export.cannot_open_stats_file:ØªØ­Ø°ÙØ±: ÙØ§ ÙÙ
+ÙÙ ÙØªØ­ Ù
+ÙÙ Ø§ÙØ¥Ø­ØµØ§Ø¡ %s.
+
+export.cannot_open_fail_log:Ø®Ø·Ø£: ÙØ§ ÙÙ
+ÙÙ ÙØªØ­ Ù
+Ø¯ÙÙØ© Ø§ÙØ£Ø®Ø·Ø§Ø¡ %s
+
+export.cannot_sort:ØªØ­Ø°ÙØ±: Ù
+ÙÙ export.pl ÙØ§ ÙÙ
+ÙÙÙ ØªØ±ØªÙØš Ø§ÙÙØ«Ø§ØŠÙ Ø¹ÙØ¯Ù
+Ø§ ØªÙØ¶Ø¹ ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª> 1. Ø®ÙØ§Ø± Ø§ÙØªØ±ØªÙØš Ø³ÙÙ ÙØªÙ
+ ØªØ¬Ø§ÙÙÙ.  
+
+export.collectdir:Ù
+Ø³Ø§Ø± Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©.
+
+export.complete:Ø¥ÙØªÙ
+Ø§Ù Ø§ÙØªØµØ¯ÙØ±
+
+export.debug:Ø·ØšØ§Ø¹Ø© Ø§ÙÙØµ Ø§ÙÙ
+Ø³ØªÙØ±Ø¯ Ø¥ÙÙ STDOUT.(ÙØªØµØ¯ÙØ± Ø¬Ø±ÙÙØ³ØªÙÙ XML )  
+
+export.desc:ÙØµ PERL Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙØªØµØ¯ÙØ± ÙØ§Ø­Ø¯Ø© Ø£Ù Ø£ÙØ«Ø± Ù
+Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª Ø¥ÙÙ ÙØ±Øµ Ù
+Ø¯Ù
+Ø¬ ÙØžØ§Ù
+ Ø§ÙÙÙØ§ÙØ°.  
+
+export.faillog:ÙØŽÙ ÙÙ Ø§Ø³Ù
+ Ù
+ÙÙ Ø§ÙØ³Ø¬Ù. ÙØ°Ø§ Ø§ÙØ³Ø¬Ù ÙØ³ØªÙØšÙ Ø£Ø³Ù
+Ø§Ø¡ Ø£Ù Ù
+ÙÙØ§Øª ØªÙØŽÙ Ø¹Ù
+ÙÙØ© ØªØŽØºÙÙÙØ§. (Default: collectdir/collname/etc/fail.log)  
+
+export.groupsize:Ø§ÙØ¹Ø¯Ø¯ Ø§ÙØ£Ø¯ÙÙ ÙÙÙØ«Ø§ØŠÙ / ØµÙØ­Ø©.  
+
+export.gzip:Ø§Ø³ØªØ®Ø¯Ù
+ gzip ÙØ¶ØºØ· ÙØ«Ø§ØŠÙ xml (ÙØ§ ØªÙØ³ Ø£Ù ØªØ¶Ù
+Ù ZIPPlug ÙÙ ÙØ§ØŠÙ
+Ø© ØšØ±Ø§Ù
+Ø¬Ù Ø§ÙÙ
+Ø¶Ù
+ÙØ© Ø¹ÙØ¯ Ø§ÙØšÙØ§Ø¡ Ù
+Ù ÙØ«Ø§ØŠÙ Ù
+Ø¶ØºÙØ·Ø©).  
+
+export.importdir:Ø­ÙØ« ØªÙØ¬Ø¯ Ø§ÙÙ
+ÙØ§Ø¯ Ø§ÙØ£ØµÙÙØ©  
+
+export.keepold:ÙÙ ØªØ¯Ù
+Ø± Ø§ÙÙ
+Ø­ØªÙÙ Ø§ÙØ­Ø§ÙÙ Ø§ÙÙ
+ÙØ¬ÙØ¯ ÙÙ Ø¯ÙÙÙ Ø§ÙØªØµØ¯ÙØ±.  
+
+export.maxdocs:Ø§ÙØ¹Ø¯Ø¯ Ø§ÙØ£ÙØµÙ ÙÙÙØ«Ø§ØŠÙ ÙÙØªØµØ¯ÙØ±.  
+
+export.listall:Ø§Ø¹Ø±Ø¶ ÙØ§ÙØ© ØªØ±ÙÙØšØ§Øª Ø§ÙÙ
+ØªØ§Ø­Ø© Ù
+Ø¹ Ø§ÙØ£Ù
+Ø± save as  
+
+export.saveas:ÙØ³Ù ØªØµØ¯ÙØ± Ø§ÙÙØ«Ø§ØŠÙ.
+
+export.saveas.DSpace:ÙÙØŠØ© Ø£Ø±ØŽÙÙ DSpace .
+
+export.saveas.GreenstoneMETS:ØŽÙÙ METS ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø³Ù
+Ø§Øª Ø¬Ø±ÙÙØ³ØªÙÙ .  
+export.saveas.FedoraMETS:ØŽÙÙ METS ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø³Ù
+Ø§Øª ÙÙØ¯ÙØ±Ø§ .  
+
+export.saveas.GreenstoneXML:ØŽÙÙ Ø§Ø±ØŽÙÙ Ø¬Ø±ÙÙØ³ØªÙÙ XML .  
+
+export.saveas.MARCXML:MARC XML ÙÙØŠØ© (Ø¥ØµØ¯Ø§Ø±Ø© MARC 21)  
+
+export.out:Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙ Ø£Ù Ø§ÙØ¥Ø¬Ø±Ø§Ø¡ Ø§ÙØ°Ù Ø³ØªØ·ØšØ¹ Ø­Ø§ÙØ© Ø§ÙÙ
+Ø®Ø±Ø¬Ø§Øª Ø¹ÙÙÙ.  
+
+export.params:[Ø®ÙØ§Ø±Ø§Øª] Ø¥Ø³Ù
+-Ù
+Ø¬Ù
+ÙØ¹Ø©1 Ø¥Ø³Ù
+-Ù
+Ø¬Ù
+ÙØ¹Ø©2 ...  
+
+export.removeold:Ø³ÙÙ ÙØªÙ
+ Ø¥Ø²Ø§Ø­Ø© Ø§ÙÙ
+Ø­ØªÙÙØ§Øª Ø§ÙÙØ¯ÙÙ
+Ø© ÙÙ Ø¯ÙÙÙ Ø§ÙØªØµØ¯ÙØ±  
+
+export.removing_export:Ø­Ø°Ù Ø§ÙÙ
+ÙÙÙØ§Øª Ø§ÙØ­Ø§ÙÙØ© ÙÙ
+Ø³Ø§Ø± Ø§ÙØªØµØ¯ÙØ±...
+
+export.sortmeta:Ø±ØªØš Ø§ÙÙØ«Ø§ØŠÙ ÙØ¬Ø§ØŠÙØ§Ù ØšØšÙØ§ÙØ§Øª Ù
+ÙØªØ§Ø¯Ø§ØªØ§ Ø§ÙØšÙØ§Ø¡, ÙÙØ°Ø§ ÙÙÙ ÙØªÙ
+ ÙÙ ÙØ§Ù groupsize > 1.  
+
+export.statsfile:Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙ Ø£Ù Ø·ØšØ§Ø¹Ø© Ø§ÙØ¥Ø­ØµØ§Ø¡Ø§Øª Ø§ÙÙ
+ØµØ¯Ø±Ø© Ø¥ÙÙÙ.  
+
+export.stats_backup:Ø³ÙØªÙ
+ Ø·ØšØ§Ø¹Ø© Ø¥Ø­ØµØ§Ø¡Ø§Øª ÙÙ STDERR ÙØšØ¯ÙÙ.  
+
+export.verbosity:Ø¶ØšØ· ÙÙ
+ÙØ© Ø§ÙÙ
+Ø®Ø±Ø¬t. 0=ÙØ§ØŽÙØ¡, 3=ÙØ«ÙØ±.
+
+
+
+# -- mkcol.pl --
+
+mkcol.about:ÙØµ Ø­ÙÙ ÙÙÙ
+Ø¬Ù
+ÙØ¹Ø©.
+
+mkcol.bad_name_cvs:Ø®Ø·Ø£: ÙØ§ ÙÙ
+ÙÙ Ø£Ù ØªØ³Ù
+Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ØšØ§Ø³Ù
+ CVS ÙØ£Ù ÙØ°Ø§ ÙØ¯ ÙØªØ¯Ø§Ø®Ù Ù
+Ø¹ Ø§ÙØ£Ø¯ÙØ© Ø§ÙÙ
+ÙØŽØ£Ø© ØšÙØ§Ø³Ø·Ø© ÙØžØ§Ù
+ CVS versioning .  
+
+mkcol.bad_name_svn:Ø®Ø·Ø£ : ÙØ§ ÙÙ
+ÙÙ ØªØ³Ù
+ÙØ© Ù
+Ø¬Ù
+ÙØ¹Ø©. svn ÙØ£Ù ÙØ°Ø§ ÙØ¯ ÙØªØ¹Ø§Ø±Ø¶ Ù
+Ø¹ Ø§ÙØ£Ø¯ÙØ© Ø§ÙØªÙ Ø®ÙÙÙØ§ SVN .  
+
+mkcol.bad_name_modelcol:Ø®Ø·Ø£: ÙØ§ ÙÙ
+ÙÙ Ø£Ù ØªØ³Ù
+Ù Ù
+Ø¬Ù
+ÙØ¹Ø© ØšØ§ÙØ§Ø³Ù
+ modelcol ÙØ£Ù ÙØ°Ø§ Ø§ÙØ§Ø³Ù
+ ÙØ®ØªØµ ØšÙ
+Ø¬Ù
+ÙØ¹Ø© model .  
+
+mkcol.cannot_find_modelcol:Ø®Ø·Ø£: ÙÙ
+ ÙØªÙ
+ Ø§ÙØ¹Ø«ÙØ± Ø¹ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙÙÙ
+ÙØ°Ø¬ÙØ©%s  
+
+mkcol.col_already_exists:Ø®Ø·Ø£: ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ù
+ÙØ¬ÙØ¯Ø© Ù
+Ù ÙØšÙ.
+
+mkcol.collectdir:Ø§ÙØ¯ÙÙÙ Ø­ÙØ« ØªÙØŽØŠ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙØ¬Ø¯ÙØ¯Ø©  
+
+mkcol.group_not_valid_in_gs3:Ø®ÙØ§Ø± Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ÙÙØ³ ØµØ§ÙØ­Ø§ ÙÙ Ø³ÙØ§Ù Ø¬Ø±ÙÙØ³ØªÙÙ3 (-gs3mode).
+mkcol.creating_col:Ø¥ÙØŽØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© %s
+
+mkcol.creator:Ø¹ÙÙØ§Ù Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ ÙÙ
+ÙØŽÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©.
+
+mkcol.creator_undefined:Ø®Ø·Ø£: ÙÙ
+ ÙØªÙ
+ ØªØ¹Ø±ÙÙ Ø§ÙÙ
+ÙØŽÙØ¡. ÙØ°Ø§ Ø§ÙÙ
+ØªØºÙØ± Ù
+Ø·ÙÙØš ÙÙØªØ¹Ø±Ù Ø¹ÙÙ Ø§ÙØªÙØ±Ø§Ø± ÙÙ Ø£Ø³Ù
+Ø§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø§Øª.  
+
+mkcol.desc:ÙØµ PERL Ø§ÙØ°Ù ÙØ³ØªØ®Ø¯Ù
+ ÙØ¥ÙØŽØ§Ø¡ ÙÙÙÙ Ø¯ÙÙÙ ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ÙØ±ÙÙØ³ØªÙÙ Ø¬Ø¯ÙØ¯Ø©.  
+
+mkcol.doing_replacements:Ø¥Ø¬Ø±Ø§Ø¡ Ø¥Ø³ØªØšØ¯Ø§Ù Ù %s
+
+mkcol.group:Ø¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø© Ø¬Ø¯ÙØ¯Ø© Ù
+ÙØ­Ø¯Ø© ØšØ¯ÙØ§ Ù
+Ù Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ø¹ÙØ§Ø±ÙØ©.  
+
+mkcol.gs3mode:Ø³ÙØ§Ù Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ø¬Ø±ÙÙØ³ØªÙÙ 3 .  
+
+mkcol.long_colname:Ø®Ø·Ø£: ÙØ¬Øš Ø§Ù ÙÙÙÙ Ø¥Ø³Ù
+ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø£ÙÙ Ù
+Ù 8 Ù
+Ø­Ø§Ø±Ù ÙØªØ­ÙÙÙ Ø§ÙØªÙØ§ÙÙ Ù
+Ø¹ ÙØžØ§Ù
+ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙØ¯ÙÙ
+
+
+mkcol.maintainer:Ø¹ÙÙØ§Ù Ø§ÙØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ ÙÙ
+Ø§ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© (Ø¥Ø°Ø§ ÙØ§Ù Ù
+Ø®ØªÙÙØ§ Ø¹Ù Ù
+ÙØŽÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©).
+
+mkcol.no_collectdir:Ø®Ø·Ø£: ÙØ§ ÙÙØ¬Ø¯ Ù
+Ø³Ø§Ø± Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©: %s
+
+mkcol.no_collectdir_specified:Ø®Ø·Ø£ : ÙÙ
+ ÙØªÙ
+ ØªØ­Ø¯ÙØ¯ Ø¯ÙÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© . ÙÙÙ Ø³ÙØ§Ù gs3 Ø Ø³ÙØ§Ø¡ ÙÙ site- Ø£Ù collectdir- ÙØ¬Øš ØªØ­Ø¯ÙØ¯ Ø§ÙØ®ÙØ§Ø±".  
+
+mkcol.no_colname:Ø®Ø·Ø£: ÙÙ
+ ÙØªÙ
+ ØªØ­Ø¯ÙØ¯ Ø§Ø³Ù
+ ÙÙÙ
+Ø¬Ù
+ÙØ¹Ø©.
+
+mkcol.optionfile:ÙÙÙÙ Ø¥Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙØ®ÙØ§Ø±Ø§Øª Ù
+Ù Ù
+ÙÙ Ù
+ÙÙØ¯Ø§ Ø­ÙÙÙ
+Ø§ ÙØªØ³ØšØš Ø·ÙÙ Ø£Ù
+Ø± Ø§ÙØ³Ø·Ø± ÙÙ Ù
+ØŽØ§ÙÙ Ù
+Ø¹ ØšØ¹Ø¶ Ø§ÙØ£ÙØžÙ
+Ø©
+
+mkcol.params:[Ø®ÙØ§Ø±Ø§Øª] Ø¥Ø³Ù
+-Ù
+Ø¬Ù
+ÙØ¹Ø©
+
+mkcol.plugin:ÙØ§Ø³ØªØ®Ø¯Ø§Ù
+ Perl plugin module (Ø±ØšÙ
+Ø§ ØªØ¬Ø¯ plugins Ù
+ØªØ¹Ø¯Ø¯Ø©).  
+
+mkcol.public:ÙÙ ÙØ§Ù ÙÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ø¯Ø®Ù ØªØµÙØ­ ØšØ§ÙÙ
+Ø®ØªØµØ±Ø§Øª.  
+mkcol.public.true:Ù
+Ø¬Ù
+ÙØ¹Ø© Ø¹Ø§Ù
+Ø©
+mkcol.public.false:Ù
+Ø¬Ù
+ÙØ¹Ø© Ø®Ø§ØµØ©
+
+mkcol.quiet:Ø¥Ø¹Ù
+Ù ØšÙØ¯ÙØ¡.
+
+mkcol.site:ÙÙ Ø³ÙØ§Ù gs3 Ø Ø§ÙØ³ØªØ®Ø¯Ù
+ Ø§Ø³Ù
+ ÙØ°Ø§ Ø§ÙÙ
+ÙÙØ¹ Ù
+Ø¹ Ù
+ØªØºÙØ± Ø§ÙØšÙØŠØ© GSDL3HOME  ÙØªØ­Ø¯ÙØ¯ collectdir- Ø Ù
+Ø§ ÙÙ
+ ÙØ­Ø¯Ø¯ collectdir-  
+
+mkcol.success:ØªÙ
+ Ø¥ÙØŽØ§Ø¡ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙØ¬Ø¯ÙØ¯Ø© ØšÙØ¬Ø§Ø­ ÙÙ %s
+
+mkcol.title:Ø¹ÙÙØ§Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©.
+
+mkcol.win31compat:ÙÙ ÙÙ Ø­Ø§Ù ÙØ¬Øš Ø§Ù ÙØªØ·Ø§ØšÙ Ø§Ø³Ù
+ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ø¹ ØªÙØ§ÙÙØ¯ Ù
+ÙÙØ§ØªWindows 3.1  (Ù
+Ø«Ø§Ù ÙÙØ³ Ø£ÙØ«Ø± Ù
+Ù 8 Ù
+Ø­Ø§Ø±Ù).  
+mkcol.win31compat.true:Ø¥Ø³Ù
+ Ø§ÙÙ
+Ø³Ø§Ø± 8 Ù
+Ø­Ø§Ø±Ù Ø£Ù Ø£ÙÙ
+mkcol.win31compat.false:Ø¥Ø³Ù
+ Ø§ÙÙ
+Ø³Ø§Ø± ØšØ§Ù Ø·ÙÙ
+
+# -- pluginfo.pl --
+
+pluginfo.collection:Ø¥Ø¹Ø·Ø§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø© Ø¥Ø³Ù
+Ø§ Ø³ÙÙ ÙØ¬Ø¹Ù Ù
+ÙÙ plugoutinfo.pl ÙÙØžØ± Ø£ÙÙØ§ ÙÙ collect/collection-name/perllib/plugouts . Ø¥Ø°Ø§ ÙÙ
+ ÙØªÙ
+ Ø§ÙØ¹Ø«ÙØ± Ø¹ÙÙ plugout Ø³ÙÙ ÙØªÙ
+ Ø§ÙØšØ­Ø« ÙÙ Ø§ÙÙ
+Ø¬ÙØ¯ Ø§ÙØ¹Ø§Ù
+ perllib/plugouts .
+
+pluginfo.desc:Ø·ØšØ§Ø¹Ø© Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø­ÙÙ Ù
+ÙØ§ØšØ³  
+
+pluginfo.general_options:Ø§ÙØ®ÙØ§Ø±Ø§Øª Ø§ÙØ¹Ø§Ù
+Ø© ÙØªÙ
+ ØªØ¶Ù
+ÙÙÙØ§ Ù
+Ù Ø§ÙÙØŠØ§Øª Ø§ÙØ£Ù
+ ÙÙÙ
+ØµÙÙ
+
+pluginfo.info:Ù
+Ø¹ÙÙÙ
+Ø§Øª
+
+pluginfo.no_plugin_name:Ø®Ø·Ø£: ÙØ¬Øš Ø¥Ø¹Ø·Ø§Ø¡ Ø¥Ø³Ù
+ ÙÙÙ
+ÙØ§ØšØ³.
+
+pluginfo.option_types:ÙÙ
+ÙÙ Ø§Ù ØªØ£Ø®Ø° Ø§ÙÙ
+ÙØ§ØšØ³ ÙÙØ¹ÙÙ Ù
+Ù Ø§ÙØ®ÙØ§Ø±Ø§Øª
+
+pluginfo.params:[Ø®ÙØ§Ø±Ø§Øª] Ø£Ø³Ù
+-Ù
+ÙØ§ØšØ³
+
+pluginfo.passing_options:ÙÙ
+ÙÙ ØªØ¹ÙÙÙ Ø§ÙØ®ÙØ§Ø±Ø§Øª ÙØ£Ù Ù
+ÙØ§ØšØ³ ØšØªØ¶Ù
+ÙÙÙØ§ ÙÙ Ù
+ÙÙ Ø§ÙØ¥Ø¹Ø¯Ø§Ø¯ collect.cfg .
+
+pluginfo.specific_options:Ø§ÙØ®ÙØ§Ø±Ø§Øª Ø§ÙÙ
+Ø®ØµØµØ© Ù
+Ø¹Ø±ÙØ© Ø¶Ù
+Ù plugout Ù ÙÙ Ù
+ØªØ§Ø­Ø© ÙÙØ· ÙÙ plugout.  
+
+
+# -- plugoutinfo.pl --
+
+plugoutinfo.collection:Ø¥Ø¹Ø·Ø§Ø¡ Ø§Ø³Ù
+ ÙÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø³ÙÙ ÙØ¬Ø¹Ù Ø§ÙÙ
+ÙÙ plugoutinfo.pl ÙØšØ­Ø« Ø£ÙÙØ§ ÙÙ collect/collection-name/perllib/plugouts . Ø«Ù
+ ØšØ¹Ø¯ Ø°ÙÙ Ø³ÙÙ ÙØšØ­Ø« ÙÙ Ø¯ÙÙÙ perllib/plugouts Ø§ÙØ¹Ø§Ù
+.  
+
+plugoutinfo.desc:Ø·ØšØ§Ø¹Ø© Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø¹Ù Ø¥ÙÙØ§Ø¡ Ø§ÙØšØ±ÙØ§Ù
+Ø¬.  
+
+plugoutinfo.general_options:Ø§ÙØ®ÙØ§Ø±Ø§Øª Ø§ÙØ¹Ø§Ù
+Ø© ÙØªÙ
+ ØªØ¶Ù
+ÙÙÙØ§ Ù
+Ù Ø§ÙÙØŠØ§Øª Ø§ÙØ£Ù
+ ÙÙÙ
+ØµÙÙ
+
+plugoutinfo.info:Ù
+Ø¹ÙÙÙ
+Ø§Øª
+
+plugoutinfo.no_plugout_name:Ø®Ø·Ø£: ÙØ¬Øš Ø¥Ø¹Ø·Ø§Ø¡ Ø¥Ø³Ù
+  plugout .  
+
+plugoutinfo.option_types:Plugouts Ø±ØšÙ
+Ø§ ØªØ£Ø®Ø° ÙÙØ¹ÙÙ Ù
+Ù Ø§ÙØ®ÙØ§Ø±Ø§Øª.  
+
+plugoutinfo.params:[Ø®ÙØ§Ø±Ø§Øª] plugout-name
+
+plugoutinfo.passing_options:Ø§ÙØ®ÙØ§Ø±Ø§Øª ÙÙ
+ÙÙ ØªØ®Ø·ÙÙØ§ Ø¹Ù Ø·Ø±ÙÙ Ù
+ÙÙ Ø§ÙØ®ØµØ§ØŠØµ collect.cfg.  
+
+plugoutinfo.specific_options:Ø§ÙØ®ÙØ§Ø±Ø§Øª Ø§ÙÙ
+Ø®ØµØµØ© Ù
+Ø¹Ø±ÙØ© Ø¶Ù
+Ù plugout Ù ÙÙ Ù
+ØªØ§Ø­Ø© ÙÙØ· ÙÙ plugout.  
+
+
+
+#
+# Classifier option descriptions
+#
+
+AllList.desc:Ø¥ÙØŽØ§Ø¡ ÙØ§ØŠÙ
+Ø© ÙØ§Ø­Ø¯Ø© ØšÙÙ Ø§ÙÙØ«Ø§ØŠÙ . ØªØ³ØªØ®Ø¯Ù
+ ØšÙ
+Ø²ÙØ¯ oai.  
+
+AZCompactList.allvalues:Ø§Ø³ØªØ®Ø¯Ù
+ ÙÙ ÙÙÙ
+ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙÙ
+ÙØ¬ÙØ¯Ø©.
+
+AZCompactList.desc:Ù
+ÙØ§ØšØ³ Ø§ÙÙ
+ØµÙÙ ÙÙÙØ±Ø² Ø§ÙØ£ÙÙØšØ§ØŠÙ
+
+AZCompactList.doclevel:Ù
+Ø³ØªÙÙ Ù
+Ø¹Ø§ÙØ¬Ø© Ø§ÙÙØ«ÙÙØ©.
+AZCompactList.doclevel.top:ÙÙ Ø§ÙÙØ«ÙÙØ©.
+AZCompactList.doclevel.section:ØšØ§ÙØ£ÙØ³Ø§Ù
+.
+
+AZCompactList.firstvalueonly:Ø§Ø³ØªØ®Ø¯Ù
+ Ø§ÙÙ ÙÙÙ
+Ø© ÙÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙÙ
+ÙØ¬ÙØ¯Ø© ÙÙØ·.
+
+AZCompactList.freqsort:Ø£ÙØ±Ø² ØšØ§ÙØ¹ÙØ¯ Ø¯ÙÙ Ø§ÙÙØ±Ø² Ø§ÙØ£ÙÙØšØ§ØŠÙ.  
+
+AZCompactList.maxcompact:Ø§ÙØ­Ø¯ Ø§ÙØ§ÙØµÙ ÙØ¹Ø¯Ø¯ Ø§ÙØµÙØ± ØªØžÙØ± ÙÙ Ø§ÙÙÙ Ø§ÙØªØµÙÙØ±Ù ÙÙ Ø§Ù ÙÙØª Ù
+Ù Ø§ÙØ§ÙÙØ§Øª  
+
+AZCompactList.metadata:Ø­ÙÙ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙØ­ÙØ¯ Ø£Ù ÙØ§ØŠÙ
+Ø© Ù
+ÙØµÙÙØ© ØšÙØ§ØµÙØ© Ø ØªØ³ØªØ®Ø¯Ù
+ ÙÙØªØµÙÙÙ. Ø¥Ø°Ø§ ØªÙ
+ ØªØ­Ø¯ÙØ¯ ÙØ§ØŠÙ
+Ø© Ø³ÙÙ ÙØ³ØªØ®Ø¯Ù
+ Ø£ÙÙ ÙÙØ¹
+
+AZCompactList.mincompact:Ø§ÙØ¹Ø¯Ø¯ Ø§ÙØ£Ø¯ÙÙ ÙÙÙØ«Ø§ØŠÙ / ØµÙØ­Ø©.  
+
+AZCompactList.mingroup:Ø§ÙÙÙÙ
+Ø© Ø§ÙØµØºØ±Ù Ø§ÙØªÙ ØªØªØ³ØšØš ØšØªÙÙÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© ÙÙ ÙÙ Ø§ÙØªØ±ØªÙØš Ø§ÙÙØ±Ù
+Ù  
+
+AZCompactList.minnesting:Ø§ÙÙÙÙ
+Ø© Ø§ÙØµØºØ±Ù Ø§ÙØªÙ ØªØ³ØšØš ØšØªØ­ÙÙÙ ÙØ§ØŠÙ
+Ø© Ø¥ÙÙ ÙØ§ØŠÙ
+Ø© Ù
+ØªØ¯Ø§Ø®ÙØ©  
+
+AZCompactList.recopt:Ù
+Ø³ØªØ®Ø¯Ù
+Ø© ÙÙ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª Ù
+ØªØ¯Ø§Ø®ÙØ© Ù
+Ø«Ù ÙØ§ØµÙØ§Øª Ø§ÙØ³ÙØ© / Ø§ÙÙ
+ÙØžÙ
+Ø©.  
+AZCompactList.sort:Ø­ÙÙ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª ÙÙØ±Ø² ÙØ±ÙØ© Ø§ÙØ¹ÙØ¯ ØšÙØ§.  
+
+AZCompactSectionList.desc:AZCompactList ÙØµÙÙ Ø§ÙØ£ÙØ³Ø§Ù
+ Ø¯ÙÙ Ø§ÙÙØ«Ø§ØŠÙ. ÙØªÙ
+ ÙØ±Ø² ÙÙÙØ§ ÙÙ
+Ø³ØªÙÙ ÙØ§ØµÙØ© ØšÙØ§ÙØ§Øª Ø§ÙÙØ³Ù
+.  
+
+AZList.desc:ØšØ±ÙØ§Ù
+Ø¬ ÙÙØªØµÙÙÙ ÙØ±ØªØš ÙØ¬Ø§ØŠÙØ§ (Ø£-Ù Ù a-z Ù A-Z Ù 0-9). ÙÙÙØªØ¬ ÙØ°Ø§ Ø§ÙØšØ±ÙØ§Ù
+Ø¬ ÙØ§ØŠÙ
+Ø© ÙØ¬Ø§ØŠÙØ© ØšØ§ÙÙØ«Ø§ØŠÙ Ø§ÙÙ
+Ø±ØªØšØ© ØªØ­Øª ÙÙ Ø­Ø±Ù.  
+
+AZList.metadata:Ø­ÙÙ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙØ§Ø­Ø¯ Ø£Ù ÙØ§ØŠÙ
+Ø© Ø­ÙÙÙ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª Ù
+ÙØµÙÙØ© ØšÙØ§ØµÙØ© ØªØ³ØªØ®Ø¯Ù
+ ÙÙØªØµÙÙÙ.ØªØšØ¹Ø§ ÙÙØªØ±ØªÙØš Ø§ÙØ°Ù ØªØ¯Ù Ø¹ÙÙÙ Ø§ÙÙØ§ØŠÙ
+Ø©Ø ÙØ§Ù Ø§ÙÙ Ø­ÙÙ ÙÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙØªÙ
+Ù ÙÙÙ
+Ø© Ø³ÙÙ ÙØ³ØªØ®Ø¯Ù
+. Ø³ÙÙ ÙØªÙ
+ ÙØ±Ø² Ø§ÙÙØ§ØŠÙ
+Ø© ÙÙÙØ§ ÙÙØ°Ø§ Ø§ÙØ¹ÙØµØ± Ø¥ÙØ§ Ø¥Ø°Ø§ Ø§Ø³ØªØ®Ø¯Ù
+  -sort .Ø¥Ø°Ø§ ÙÙ
+ ÙØªÙ
+ ØªØ­Ø¯ÙØ¯ ÙØ§ØµÙØ© ØšÙØ§ÙØ§Øª ÙØ§Ù Ø¬Ù
+ÙØ¹ Ø§ÙÙØ«Ø§ØŠÙ Ø³ÙØªÙ
+ Ø¥Ø¯Ø±Ø§Ø¬ÙØ§ ÙÙ Ø§ÙÙØ§ØŠÙ
+Ø©Ø ÙØ§ÙØ§ Ø³ÙÙ Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ØªØªØ¶Ù
+Ù ÙÙÙ
+Ø© ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø³ØªØ¯Ø±Ø¬.  
+
+AZSectionList.desc:Ø§ÙØªÙÙØ¹ ÙÙ Ø§ÙÙØ§ØŠÙ
+Ø© Ø§ÙÙØ¬Ø§ØŠÙØ© ØšØªØµÙÙÙ Ø§ÙØ£ÙØ³Ø§Ù
+ ÙØ¶ÙØ§ Ø¹Ù Ø§ÙÙØ«Ø§ØŠÙ. ØªØ±ØªØš Ø§ÙÙ
+Ø¯Ø§Ø®Ù ØšÙ
+ÙØªØ§Ø¯Ø§ØªØ§ Ù
+Ø³ØªÙÙ Ø§ÙÙØ³Ù
+  
+
+BasClas.bad_general_option:Ø§ÙÙ
+ØµÙÙ  %s ÙØ³ØªØ®Ø¯Ù
+ Ø®ÙØ§Ø±Ø§Øª ØºÙØ± ØµØ­ÙØ­Ø©.Ø¥ÙØ­Øµ Ù
+ÙÙ Ø§ÙØ¥Ø¹Ø¯Ø§Ø¯ collect.cfg .  
+
+BasClas.builddir:Ø£ÙÙ ØªÙØ¶Ø¹ Ø§ÙÙØŽØ§ÙØ§Øª Ø§ÙÙ
+ØšÙÙØ©.
+
+BasClas.buttonname:Ø¥Ø³Ù
+ Ø§ÙÙ
+ØµÙÙ ÙÙ Ø§ÙØŽØ§ØŽØ© Ù ÙÙ Ø¹Ù
+ÙØ¯ Ø§ÙØªØ¬ÙØ§Ù. Ø§ÙÙÙÙ
+Ø© Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ© ÙÙ Ø¹ÙØµØ± ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙÙ
+Ø®ØµØµØ© Ù
+Ø¹ Ø§ÙØ¥Ø³Ù
+
+
+BasClas.desc:Ø§ÙÙØŠØ© Ø§ÙØ£Ø³Ø§Ø³ÙØ© ÙÙÙ Ø§ÙÙ
+ØµÙÙØ§Øª.
+
+BasClas.no_metadata_formatting:ÙØ§ ØªØ­Ø§ÙÙ Ø¹Ù
+Ù Ø§Ù Ø¹Ø±Ø¶ ØªÙÙØ§ØŠÙ ÙÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª (ÙÙÙØ±Ø²)
+
+BasClas.outhandle:Ù
+ÙÙ ÙØªØ§ØšØ© Ø§ÙÙ
+Ø®Ø±Ø¬ Ø¥ÙÙ.
+
+BasClas.removeprefix:ØªØ¬Ø§ÙÙ ØšØ§Ø¯ØŠØ© ÙÙ ÙÙÙ
+ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø¹ÙØ¯ Ø§ÙÙØ±Ø².
+
+BasClas.removesuffix:ØªØ¬Ø§ÙÙ ÙØ§Ø­ÙØ© ÙÙ ÙÙÙ
+ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø¹ÙØ¯ Ø§ÙÙØ±Ø².
+
+BasClas.verbosity:Ø¶ØšØ· ÙÙ
+ÙØ© Ø§ÙÙ
+Ø®Ø±Ø¬t. 0=ÙØ§ØŽÙØ¡, 3=ÙØ«ÙØ±.
+
+Browse.desc:.
+
+DateList.bymonth:ØµÙÙ ØšØ§ÙØ³ÙØ© Ù Ø§ÙØŽÙØ± ØšØ¯ÙØ§ Ù
+Ù Ø§ÙØ³ÙØ© ÙÙØ·.
+
+DateList.desc:ØšØ±ÙØ§Ù
+Ø¬ Ø§ÙÙ
+ØµÙÙ ÙÙØªØ±ØªÙØš ØšØ§ÙØªØ§Ø±ÙØ®. ÙÙÙÙ
+ ØªÙÙØ§ØŠÙØ§Ù ØšØ§ÙØªØ±ØªÙØš ØšØ­ÙÙ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ Ø§ÙØ®Ø§Øµ ØšØ§ÙØªØ§Ø±ÙØ®. ØªØµØ§Øº Ø§ÙØªÙØ§Ø±ÙØ® ÙÙ ØµÙØ±Ø© yyyymmdd Ø£Ù yyyy-mm-dd.  
+
+DateList.metadata:ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙØªÙ ØªØªØ¶Ù
+Ù Ø§ÙØªÙØ§Ø±ÙØ® Ø§ÙÙ
+ØµÙÙ ØšÙØ§.Ø§ÙØµÙØºØ© Ø§ÙÙ
+ØªÙÙØ¹Ø© ÙÙ  yyyymmdd Ø£Ù yyyy-mm-dd. ÙÙ
+ÙÙ Ø£Ù ØªÙÙÙ ÙØ§ØŠÙ
+Ø© Ù
+ÙØµÙÙØ© ØšÙØ§ØµÙØ©Ø Ù Ø§ÙÙ ØªØ§Ø±ÙØ® ÙÙØ¬Ø¯ Ø³ÙÙ ÙØ³ØªØ®Ø¯Ù
+.  
+
+DateList.reverse_sort:ÙØ±Ø² Ø§ÙÙØ«Ø§ØŠÙ ÙÙ ØªØ±ØªÙØš Ø²Ù
+ÙÙ Ù
+Ø¹ÙÙØ³ (Ø§ÙØ£Ø­Ø¯Ø« Ø£ÙÙØ§).  
+
+DateList.nogroup:Ø¬Ø¹Ù ÙÙ Ø³ÙØ© Ù
+Ø¯Ø®Ù ÙØ±Ø¯Ù ÙÙ ÙØ§ØŠÙ
+Ø© Ø§ÙÙÙÙ ØšØ¯ÙØ§ Ù
+Ù Ø§Ù ØªÙ
+ØªØ¯ Ø³ÙÙØ§Øª ØšÙ
+Ø¯Ø§Ø®Ù ÙÙÙÙØ©. (ÙÙØ°Ø§ ÙÙ
+ÙÙ Ø§Ù ØªØ³ØªØ®Ø¯Ù
+ Ø§ÙØ¶Ø§ Ù
+Ø¹ bymonth - Ø§ÙØ®ÙØ§Ø± ÙØ¬Ø¹Ù ÙÙ ØŽÙØ± Ù
+Ø¯Ø®Ù ÙØ±Ø¯Ù ØšØ¯ÙØ§ Ù
+Ù Ø§ÙØ¯Ù
+Ø¬).  
+
+DateList.no_special_formatting:ÙØ§ ØªØ¹Ø±Ø¶ Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙØ³ÙØ© Ù Ø§ÙØŽÙØ± ÙÙ ÙØ§ØŠÙ
+Ø© Ø§ÙÙØ«ÙÙØ©.
+
+DateList.sort:Ø­ÙÙ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª Ø¥Ø¶Ø§ÙÙ ÙØ³ØªØ®Ø¯Ù
+ ÙÙÙØ±Ø² ÙÙ Ø­Ø§ÙØ© ØªØŽØ§ØšÙ ÙØ«ÙÙØªÙÙ ÙÙ ÙÙØ³ Ø§ÙØªØ§Ø±ÙØ®.
+
+HFileHierarchy.desc:Ù
+ØµÙÙ Ø§ÙÙ
+ÙØ§ØšØ³ ÙØªÙÙÙØ¯ ØªØµÙÙÙØ§Øª Ø¹ÙÙ Ø§Ø³Ø§Ø³ ÙØ±Ù
+Ù ÙÙ ÙÙÙÙ Ø§ÙÙ
+ÙÙ Ø§ÙØªÙÙ
+ÙÙÙ  
+
+Hierarchy.desc:Ù
+ØµÙÙ Ø§ÙÙ
+ÙØ§ØšØ³ ÙØªÙÙÙØ¯ Ø§ÙØªØµÙÙÙ Ø§ÙÙØ±Ù
+Ù. ÙØ°Ø§ ÙÙ
+ÙÙ Ø§Ù ÙØ³ØªÙØ¯ Ø¹ÙÙ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª Ù
+ÙÙÙÙØ© Ø Ø§Ù ÙÙ
+ÙÙ Ø§Ø³ØªØ®Ø¯Ø§Ù
+ ÙÙÙÙ Ù
+ÙÙ ØªÙÙ
+ÙÙÙ (hfile - Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙØ®ÙØ§Ø±).  
+
+Hierarchy.documents_last:Ø¹Ø±Ø¶ Ø¹ÙØ¯ Ø§ÙÙØ«ÙÙØ© ØšØ¹Ø¯ Ø¹ÙØ¯ Ø§ÙÙ
+ØµÙÙ  
+
+Hierarchy.hfile:Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ù
+ÙÙ ÙÙÙÙ Ø§ÙØªØµÙÙÙ Ø§ÙÙ
+Ø­Ø¯Ø¯.  
+
+Hierarchy.hlist_at_top:Ø¹Ø±Ø¶ Ø§ÙÙ
+Ø³ØªÙÙ Ø§ÙØ£ÙÙ ÙÙØªØµÙÙÙ Ø£ÙÙÙØ§.
+
+Hierarchy.reverse_sort:ÙØ±Ø² Ø§ÙØ¹ÙØ¯ ÙÙ ØªØ±ØªÙØš Ø¹ÙØ³Ù (ÙØ³ØªØ®Ø¯Ù
+ Ù
+Ø¹ -sort).  
+
+Hierarchy.separator:ØªØ¹ØšÙØ± Ù
+Ø¹ØªØ§Ø¯ ÙØ³ØªØ®Ø¯Ù
+ ÙÙÙØ§ØµÙØ Ø¥Ø°Ø§ ÙÙØª ØªØ³ØªØ®Ø¯Ù
+ Ù
+ÙØªØ§Ø¯Ø§ØªØ§ Ù
+ÙÙÙÙØ©.  
+
+Hierarchy.sort:Ø­ÙÙ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙÙØ±Ø² Ø§ÙØ¹ÙØ¯.ÙÙ ØªÙØ±Ø² Ø§ÙØ£ÙØ±Ø§Ù Ø¥Ø°Ø§ ÙÙ
+ ÙØªÙ
+ ØªØ¹ÙÙÙØ§.
+
+Hierarchy.suppressfirstlevel:ØªØ¬Ø§ÙÙ Ø§ÙØ¬Ø²Ø¡ Ø§ÙØ£ÙÙ Ù
+Ù ÙÙÙ
+Ø© ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª. Ù ÙØ°Ø§ Ù
+ÙÙØ¯ ÙÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙØªÙ ÙÙÙÙ Ø§ÙØ¹ÙØµØ± Ø§ÙØ£ÙÙ ÙÙÙØ§ Ù
+ØŽØªØ±Ù. Ù
+Ø«Ù Ù
+Ø«Ù Ø¥Ø³ØªÙØ±Ø§Ø¯ Ø¯ÙÙÙ ÙÙ gsdlsourcefilename.  
+
+Hierarchy.suppresslastlevel:ØªØ¬Ø§ÙÙ Ø§ÙØ¬Ø²Ø¡ Ø§ÙØ£Ø®ÙØ± Ù
+Ù ÙÙÙ
+Ø© ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª.Ù ÙØ°Ø§ Ù
+ÙÙØ¯ ÙÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙØªÙ ØªÙÙÙ ÙÙ ÙÙÙ
+Ø© ÙÙÙØ§ ÙØ±ÙØ¯Ø© Ù
+Ø«Ù Ù
+Ø³Ø§Ø± Ù
+ÙÙ.  
+
+HTML.desc:ÙÙØŽÙØ¡ ØªØµÙÙÙ ÙØ§Ø±Øº ÙÙÙ Ø¹ØšØ§Ø±Ø© Ø¹Ù Ø±Ø§ØšØ·Ø© ÙØµÙØ­Ø© Ø¥ÙØªØ±ÙØª.  
+
+HTML.url:Ø±ØšØ· Ø¹ÙÙØ§Ù ØµÙØ­Ø© Ø§ÙÙ
+ÙØ§Ø±Ø¯ ÙØµÙØ­Ø© Ø§ÙÙØš Ø¥ÙÙ.
+
+List.bookshelf_type:ÙÙØªØ­ÙÙ
+ Ø¹ÙØ¯ Ø¥ÙØŽØ§Ø¡ Ø±ÙÙÙ Ø§ÙÙØªØš  
+List.bookshelf_type.always:Ø¥ÙØŽØ§Ø¡ Ø£ÙÙÙÙØ© Ø±Ù ÙØªØš Ø­ØªÙ Ø¥Ø°Ø§ ÙØ§Ù ÙÙØ§Ù Ø¹ÙØµØ± ÙØ§Ø­Ø¯ ÙÙØ· ÙÙ ÙÙ Ø±Ù  
+List.bookshelf_type.never:ÙØ§ ØªÙØŽÙØ¡ Ø£ÙÙÙÙØ© Ø±Ù ÙØªØš Ø­ØªÙ Ø¥Ø°Ø§ ÙØ§Ù ÙÙØ§Ù Ø§ÙØ«Ø± Ù
+Ù Ø¹ÙØµØ± ÙØ§Ø­Ø¯ ÙÙ ÙÙ Ø±Ù  
+List.bookshelf_type.duplicate_only:Ø¥ÙØŽØ§Ø¡ Ø£ÙÙÙÙØ© Ø±Ù ÙØªØš Ø­ØªÙ Ø¥Ø°Ø§ ÙØ§Ù ÙÙØ§Ù Ø£ÙØ«Ø± Ù
+Ù Ø¹ÙØµØ± ÙØ§Ø­Ø¯ ÙÙØ· ÙÙ ÙÙ Ø±Ù  
+
+List.classify_sections:ØªØµÙÙÙ Ø§ÙØ£ÙØ³Ø§Ù
+ ØšØ¯ÙØ§ Ù
+Ù Ø§ÙÙØ«Ø§ØŠÙ.
+
+List.desc:ÙØ§ØŠÙ
+Ø© Ù
+ØµÙÙ Ø¹Ø§Ù
+Ø© Ù Ù
+Ø±ÙØ© ÙØªØªØ¶Ù
+Ù Ù
+Ø¹ØžÙ
+ ÙØ¯Ø±Ø§Øª azcompactlist Ø ÙÙÙÙ ØšØ§ÙØ¶Ù ÙÙÙÙÙÙØ¯ Ø ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙÙØ¯Ø±Ø§Øª Ø§ÙÙØ±Ø².  
+
+List.level_partition.per_letter:Ø§ÙØŽØ§Ø¡ ÙØ·Ø§Ø¹ ÙÙÙ Ø­Ø±Ù  
+List.level_partition.constant_size:Ø§ÙØŽØ§Ø¡ ÙØ·Ø§Ø¹ ØšØ­Ø¬Ù
+ Ø«Ø§ØšØª  
+List.level_partition.per_letter_fixed_size:Ø§ÙØŽØ§Ø¡ ÙØ·Ø§Ø¹ ØšØ­Ø¬Ù
+ Ø«Ø§ØšØª ØªÙØ±ÙØšØ§ ÙÙÙ Ø­Ø±Ù  
+
+List.metadata:Ø­ÙÙÙ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª ØªØ³ØªØ®Ø¯Ù
+ ÙÙØªØµÙÙÙ. Ø§Ø³ØªØ®Ø¯Ù
+ "/" ÙÙØµÙ Ø§ÙÙ
+Ø³ØªÙÙØ§Øª Ø§ÙÙØ±Ù
+ÙØ© Ù ";" ÙÙØµÙ Ø­ÙÙÙ ÙØ§ØµÙØ§Øª Ø§ÙØšÙÙØ§Øª ÙÙ ÙÙ Ù
+Ø³ØªÙÙ  
+
+List.partition_name_length:Ø·ÙÙ Ø§Ø³Ù
+ Ø§ÙÙØ·Ø§Ø¹ ; Ø¥ÙØªØ±Ø§Ø¶ÙØ§ Ù
+ØªØºÙØ± Ø§ÙØ·ÙÙ Ù
+Ù 1 Ø§ÙÙ 3 Ù
+Ø­Ø§Ø±Ù Ù ÙØªÙÙÙ ÙØ°Ø§ Ø¹ÙÙ Ù
+Ø¯Ù Ø§ÙØ­ÙØ¬Ø© Ø§ÙÙ ØªÙ
+ÙØ² ØšØ¯Ø§ÙØ© Ø§ÙÙØ·Ø§Ø¹ Ù
+Ù ÙÙØ§ÙØªÙ. ÙØ³ØªØ®Ø¯Ù
+ ÙØ°Ø§ Ø§ÙØ®ÙØ§Ø± ÙÙØ· Ø¹ÙØ¯ ØªØ¹ÙÙ partition_type_within_level Ø§ÙÙ 'constant_size'.
+
+List.partition_size_within_level:Ø¹Ø¯Ø¯ Ø§ÙÙ
+ÙØ§Ø¯ ÙÙ ÙÙ ÙØ³Ù
+ (ÙÙ
+ÙÙ Ø§ÙØ­ØµÙÙ Ø¹ÙÙÙØ§ ÙÙØ· Ø¹ÙØ¯Ù
+Ø§ partition_type_within_level Ù
+Ø¶ØšÙØ· Ø¹ÙÙ 'constant_size').
+
+List.partition_type_within_level:ØªØ­Ø¯ÙØ¯ Ø§ÙØªÙØ³ÙÙ
+ Ø§ÙÙØ·Ø§Ø¹Ù : Ø§Ù
+Ø§ 'per_letter',
+
+List.sort_leaf_nodes_using:Ø­ÙÙÙ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+Ø© ÙØªØ±ØªÙØš Ø§ÙØ£ÙØ±Ø§Ù. Ø§Ø³ØªØ®Ø¯Ù
+ '|' ÙÙ ØªÙØµÙ ØšÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ ÙÙ ÙÙÙÙ Ø§ÙØªØ±ØªÙØš Ù
+Ø¶ØšÙØ·. Ù ';' ÙÙÙØµÙ Ø­ÙÙÙ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ ÙÙ Ø­ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© Ø¹ÙÙ Ø­Ø¯Ø©.
+
+List.sort_using_unicode_collation:Ø§ÙÙØ±Ø²  ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø®ÙØ§Ø±Ø²Ù
+ÙØ© Ø§ÙÙÙÙÙÙØ¯ Ø§ÙÙ
+Ø¬Ù
+Ø¹ . ÙØªØ·ÙØš ØªÙØ²ÙÙ Ø§ÙÙ
+ÙÙ http://www.unicode.org/Public/UCA/latest/allkeys.txt ÙÙØ¶Ø¹Ù ÙÙ Ø§ÙÙ
+Ø¬ÙØ¯ Ù
+ÙÙ ÙÙØªØ­Ù
+ÙÙ ÙÙ perlib/Unicode/Collate.
+
+List.use_hlist_for:Ø­ÙÙÙ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ ØªØ³ØªØ®Ø¯Ù
+ hlist ØšØ¯ÙØ§ Ù
+Ù vlist. Ø§Ø³ØªØ®Ø¯Ù
+ (Ø) ÙÙØµÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§Ø Ù(Ø) ÙÙØµÙ Ø­ÙÙÙ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ ÙÙ ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø©.
+
+SimpleList.metadata:Ø­ÙÙ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙØ­ÙØ¯ Ø£Ù ÙØ§ØŠÙ
+Ø© Ù
+ÙØµÙÙØ© ØšÙØ§ØµÙØ© Ø ØªØ³ØªØ®Ø¯Ù
+ ÙÙØªØµÙÙÙ. Ø¥Ø°Ø§ ØªÙ
+ ØªØ­Ø¯ÙØ¯ ÙØ§ØŠÙ
+Ø© Ø³ÙÙ ÙØ³ØªØ®Ø¯Ù
+ Ø£ÙÙ ÙÙØ¹ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙØ¯ÙÙ ÙÙÙ
+Ø©. ÙÙ
+ÙÙ Ø¥Ø³ØªØ®Ø¯Ø§Ù
+ÙØ§ Ù
+Ø¹  -firstvalueonly Ù -allvalues ØŽØ§Ø±Ø§Øª Ø§ÙØªÙ
+ÙØ², ÙØ¥Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙÙÙÙ
+Ø© Ø§ÙØ£ÙÙÙ Ø£Ù ÙÙ Ø§ÙÙÙÙ
+ ÙÙ Ø§ÙÙØ§ØŠÙ
+Ø©.
+
+SimpleList.desc:Ù
+ÙØ§ØšØ³ Ù
+ØµÙÙ ÙØ§ØŠÙ
+Ø© ØšØ³ÙØ·Ø©
+
+SimpleList.sort:Ø­ÙÙ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ ÙÙØªØ±ØªÙØš. Ø§Ø³ØªØ®Ø¯Ù
+ '-sort nosort' ÙÙ ÙÙØª ÙØ§ ØªØ±ÙØ¯ ØªØ±ØªÙØš.
+
+Phind.desc:Ù
+ØµÙÙ Ù
+ÙØ§ØšØ³ Ø§ÙØ¬Ù
+ÙØ©.
+
+Phind.language:Ø§ÙÙØºØ© Ø§Ù Ø§ÙÙØºØ§Øª Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+Ø© ÙÙØšÙØ§Ø¡ Ø§ÙÙØ±Ù
+Ù.
+
+Phind.min_occurs:Ø§ÙØ­Ø¯ Ø§ÙØ§Ø¯ÙÙ ÙØ¹Ø¯Ø¯ Ø§ÙÙ
+Ø±Ø§Øª Ø§ÙØªÙ ÙØ¬Øš Ø§Ù ØªØžÙØ± Ø§ÙØ¹ØšØ§Ø±Ø© ÙÙ Ø§ÙÙØµ Ø§ÙÙ
+Ø±Ø§Ø¯ Ø§Ø¯Ø±Ø§Ø¬ÙØ§ ÙÙ Ø§ÙØ¬Ù
+ÙÙ Ø§ÙÙØ±Ù
+ÙÙ.  
+
+Phind.savephrases:Ø°Ø§ ØªÙ
+ ØªØ¹ÙÙØØªØ®Ø²Ù Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙØ¹ØšØ§Ø±Ø© ÙÙ Ù
+ÙÙ Ù
+Ø¹Ø·Ù Ø¹ÙÙ Ø§Ø³Ø§Ø³ ÙØµ. Ù ÙØ¹ÙÙ Ù
+Ù Ø§ÙÙ
+Ø³ØªØ­Ø³Ù Ø¥Ø³ØªØ®Ø¯Ø§Ù
+ Ù
+Ø³Ø§Ø± Ù
+Ø·ÙÙ  
+
+Phind.suffixmode:Ù
+Ø¹Ø§Ù
+Ù smode ÙØšØ±ÙØ§Ù
+Ø¬ Ø§Ø³ØªØ®ÙØ§Øµ Ø§ÙØ¹ØšØ§Ø±Ø§Øª. Ø§ÙÙÙÙ
+Ø© ØµÙØ± ØªØ¹ÙÙ Ø£Ù ÙØ§ØŠÙ
+Ø© Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙÙ
+ÙÙÙÙØ© ØªÙ
+ ØªØ¬Ø§ÙÙÙØ§Ø ÙØ§ÙÙÙÙ
+Ø© 1 ØªØ¹ÙÙ Ø£Ù ÙØ§ØŠÙ
+Ø© Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙÙ
+ÙÙÙÙØ© ØªÙ
+ Ø§Ø³ØªØ®Ø¯Ø§Ù
+ÙØ§.  
+
+Phind.text:Ø§ÙÙØµ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙØšÙØ§Ø¡ ÙØ±Ù
+ÙØ© Ø§ÙØ¬Ù
+ÙØ©.  
+
+Phind.thesaurus:Ø¥Ø³Ù
+ Ø§ÙÙ
+ÙÙØ² Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙÙ ÙØ³Ù Phind ÙÙ Ø¯ÙÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© etc .  
+
+Phind.title:ÙØ³ØªØ®Ø¯Ù
+ Ø­ÙÙ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª ÙÙØµÙ ÙÙ ÙØ«ÙÙØ©.
+
+Phind.untidy:ÙØ§ ØªØ­Ø°Ù Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØ¹Ø§Ù
+ÙØ©.
+
+RecentDocumentsList.desc:Ù
+ØµÙÙ ÙÙÙØ± ÙØ§ØŠÙ
+Ø© ØšØ§ÙÙØ«Ø§ØŠÙ Ø§ÙÙ
+Ø¶Ø§ÙØ© Ø£Ù Ø§ÙÙ
+Ø¹Ø¯ÙØ© Ø­Ø¯ÙØ«Ø§.  
+
+RecentDocumentsList.include_docs_added_since:ÙØªØ¶Ù
+Ù ÙÙØ· Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙÙ
+Ø¹Ø¯ÙØ© Ø£Ù Ø§ÙÙ
+Ø¶Ø§ÙØ© ØšØ¹Ø¯ Ø§ÙØªØ§Ø±ÙØ® Ø§ÙÙ
+Ø­Ø¯Ø¯  (ÙÙ ÙÙØŠØ©  yyyymmdd Ø£Ù yyyy-mm-dd ).
+
+RecentDocumentsList.include_most_recently_added:ÙØªØ¶Ù
+Ù ÙÙØ· Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙÙ
+Ø¹Ø¯ÙØ© Ø£Ù Ø§ÙÙ
+Ø¶Ø§ÙØ© ØšØ¹Ø¯ Ø§ÙØªØ§Ø±ÙØ® Ø§ÙÙ
+Ø­Ø¯Ø¯  (ÙÙ ÙÙØŠØ©  yyyymmdd Ø£Ù yyyy-mm-dd ).  
+
+RecentDocumentsList.sort:ÙØ§ØŠÙ
+Ø© ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª ÙÙÙØ±Ø² .Ø¥Ø°Ø§ ÙÙ
+ ØªØ­Ø¯Ø¯ Ø Ø³ÙÙ ÙØªÙ
+ Ø§ÙÙØ±Ø² ØšØ§Ø±ÙØ® Ø§ÙØ¥Ø¶Ø§ÙØ© / Ø§ÙØªØ¹Ø¯Ù  
+
+SectionList.desc:ÙÙØ³ ÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+ØµÙÙ Ø§ÙÙ
+Ø§ ÙØŽÙ
+Ù Ø¬Ù
+ÙØ¹ Ø£ÙØ³Ø§Ù
+ Ø§ÙÙØ«ÙÙØ© (ØšØ¥Ø³ØªØšØ¹Ø§Ø¯ Ø§ÙÙ
+Ø³ØªÙÙ Ø§ÙØ£ÙÙ) ØšØ¯ÙØ§ Ù
+Ù Ù
+Ø¬Ø±Ø¯ Ø§ÙÙ
+Ø³ØªÙÙ Ø§ÙØ£ÙÙ Ø§ÙÙØ«ÙÙØ© ÙÙØ³ÙØ§.  
+
+Collage.desc:ÙÙÙ Ù
+ÙØ§ØšØ³ ÙØ³ØªØ®Ø¯Ù
+ ÙØ¥ØžÙØ§Ø± ØµÙØ± Ø§ÙÙÙ Ø§ÙØªØµÙÙØ±Ù Ø§ÙÙ
+ÙØ¬ÙØ¯Ø© ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©.  
+
+Collage.geometry:Ø§ØšØ¹Ø§Ø¯ Ø§ÙÙÙ Ø§ÙØªØµÙÙØ±Ù ÙÙÙØ­Ø©. ÙÙØ­Ø© 600 ØšÙØ³Ù ÙÙ 400 ØšÙØ³Ù ÙØ§Ø³Ø¹Ø© Ø¹Ø§ÙÙØ© Ø Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù Ø ØªØ­Ø¯Ø¯ Ø­Ø³Øš ÙÙØ¯Ø³Ø© 600x400  
+
+Collage.maxDepth:ØµÙØ± ÙÙØªØ¬Ù
+ÙØ¹ Ù
+Ù Ù
+ØµÙÙ ØªØµÙØ­ Ø§Ø³Ø§Ø³Ù . ÙØ¶ØšØ· ÙØ°Ø§ Ø§ÙØ¹Ù
+Ù Ø§ÙØ£ÙØµÙ ÙØ¹Ù
+ÙÙØ© Ø§ÙØ¥ÙØ¹ÙØ§Ø³  
+
+Collage.maxDisplay:Ø§ÙØ­Ø¯ Ø§ÙØ§ÙØµÙ ÙØ¹Ø¯Ø¯ Ø§ÙØµÙØ± ØªØžÙØ± ÙÙ Ø§ÙÙÙ Ø§ÙØªØµÙÙØ±Ù ÙÙ Ø§Ù ÙÙØª Ù
+Ù Ø§ÙØ§ÙÙØ§Øª.  
+
+Collage.imageType:ØªØ³ØªØ®Ø¯Ù
+ ÙÙØ¶ØšØ· Ø ØšØ§ÙØ¥Ø¹Ø±Ø§Øš Ø¹Ù Ø§Ø³Ù
+ Ø§Ù
+ØªØ¯Ø§Ø¯Ø§Øª Ø§ÙÙ
+ÙÙ Ø Ù
+Ø§ÙÙ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+Ø© ÙÙ Ø§ÙÙÙ Ø§ÙØªØµÙÙØ±Ù . ÙØ§ØŠÙ
+Ø© ØšØ§Ø³Ù
+ Ø¥Ù
+ØªØ¯Ø§Ø¯Ø§Øª Ø§ÙÙ
+ÙÙ Ù
+ÙØµÙÙØ© ØšÙØ§ÙØ±Ù
+Ø² (%%) .  
+
+Collage.bgcolor:ÙÙÙ Ø§ÙØ®ÙÙÙØ© Ø§ÙØ®Ø§ØµØ© ØšÙ
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙÙÙØ­Ø§ØªØ Ø§Ø®ØªØ± Ø±ÙÙ
+ ÙØ¹ØšØ± Ø¹Ù Ø§ÙÙÙÙ (Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù #008000 Ø³ÙÙ ØªØ¹Ø·Ù ÙØªÙØ¬Ø© Ø§ÙÙÙÙ Ø§ÙØ£Ø®Ø¶Ø±).  
+
+Collage.buttonname:Ø¥Ø³Ù
+ Ø§ÙÙ
+ØµÙÙ ÙÙ Ø§ÙØŽØ§ØŽØ© Ù ÙÙ Ø¹Ù
+ÙØ¯ Ø§ÙØªØ¬ÙØ§Ù. Ø§ÙÙÙÙ
+Ø© Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ© ÙÙ Ø¹ÙØµØ± ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙÙ
+Ø®ØµØµØ© Ù
+Ø¹ Ø§ÙØ¥Ø³Ù
+  
+
+Collage.refreshDelay:Ø§ÙØªØ±ØªÙØšØ ØšØ§ÙØ¬Ø²Ø¡ Ù
+Ù Ø§ÙØ«Ø§ÙÙØ© Ù
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙÙÙØ­Ø§Øª ØªÙ
+ ØªØ¬Ø¯ÙØ¯ÙØ§.  
+
+Collage.isJava2:ÙØ³ØªØ®Ø¯Ù
+ ÙÙ
+Ø±Ø§ÙØšØ© Ø§ÙÙÙØª Ø§ÙØ°Ù ØªØ¯ÙØ± ÙØŠØ§Øª Java Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+Ø©. Ø¥ØµØ¯Ø§Ø±Ø© Ø§ÙØ«Ø± ØªØ·ÙØ±Ø§ Ù
+Ù Java (Ø§Ù 1.2 Java ÙØµØ§Ø¹Ø¯Ø§) ØªØŽÙ
+Ù Ø¯Ø¹Ù
+ Ø£ÙØ«Ø± ØªØ·ÙØ±Ø§ ÙØ¶ØšØ·  Ø§ÙØŽÙØ§ÙÙÙ ÙÙ Ø§ÙØµÙØ± Ø ÙÙØ°Ø§ Ø§ÙØ¹ÙÙ
+ ÙØ³Ø§Ø¹Ø¯ ÙÙ Ù
+Ø±Ø§ÙØšØ© Ù
+Ø§ ÙØ­Ø¯Ø« Ø ØšØ¹Ø¶ ØšØ±Ø§Ù
+Ø¬ Ø§ÙØªØµÙØ­ ØºÙØ± Ù
+Ø¯Ù
+Ø¬Ù ÙÙ ÙÙØª Ø§ÙØªØŽØºÙÙ Java Ø¥ØµØ¯Ø§Ø±Ø© 1.1. ØªÙ
+ ØªØµÙ
+ÙÙ
+ appletØ Ø§ÙØªØ±Ø§Ø¶Ù Ø ØªÙØªØŽÙ Ø§ÙÙ
+ØªØµÙØ­Ø§Øª Ø¥ØµØ¯Ø§Ø±Ø© Java Ù ÙØ¹Ù
+Ù Ø§ÙÙ
+ØªØµÙØ­  ÙÙØªØµØ±Ù Ø¹ÙÙ ÙØ°Ø§ Ø§ÙØ§Ø³Ø§Ø³.  
+
+Collage.imageMustNotHave:Ù
+Ø³ØªØ®Ø¯Ù
+ ÙØ¥Ø®ÙØ§Ø¡ Ø§ÙØµÙØ± Ø§ÙØªÙ ÙØ§ ÙØ¬Øš Ø£Ù ØªØžÙØ± ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©Ø Ù
+Ø«Ù ØµÙØ± Ø§ÙØ£Ø²Ø±Ø§Ø± Ø§ÙØªÙ ØªÙÙÙ ØŽØ±ÙØ· Ø§ÙØªØµÙØ­.  
+
+Collage.caption:ÙÙØ·Ø§Øª Ø¥Ø®ØªÙØ§Ø±ÙÙ  ØªØ¹Ø±Ø¶ Ø£Ø³ÙÙ   Ø§ÙÙÙ Ø§ÙØªØµÙÙØ±Ù  
+
+
+#
+# Plugin option descriptions
+#
+AcronymExtractor.adding:Ø¥Ø¶Ø§ÙØ©
+
+AcronymExtractor.already_seen:ØŽÙÙØ¯ Ù
+Ù ÙØšÙ
+
+AcronymExtractor.desc:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙÙ
+Ø³Ø§Ø¹Ø¯ Ø§ÙÙ
+Ø³ØªØ®Ø±Ø¬ ÙÙÙ
+ÙÙØ¹ Ù ØªØ£ØŽÙØ± Ø§ÙÙ
+Ø®ØªØµØ±Ø§Øª ÙÙ Ø§ÙÙØµ.  
+
+AcronymExtractor.done_acronym_extract:ÙØªÙ
+ Ø§Ø³ØªØ®Ø±Ø§Ø¬ Ø§ÙÙ
+Ø®ØªØµØ±Ø§Øª.  
+
+AcronymExtractor.done_acronym_markup:ØªÙÙÙØ° Ù
+Ø®ØªØµØ§Ø±Øª ÙØºØ© Ø§ÙØªØ±Ù
+ÙØ²  
+
+AcronymExtractor.extract_acronyms:Ø§Ø³ØªØ®ÙØµ Ø§ÙÙ
+Ø®ØªØµØ±Ø§Øª Ù
+Ù Ø§ÙÙØµ ÙØ§Ø¬Ø¹ÙÙØ§ Ù
+ÙØªØ§Ø¯Ø§ØªØ§  
+
+AcronymExtractor.extracting_acronyms:Ø§Ø³ØªØ®ÙØ§Øµ Ø§ÙÙ
+Ø®ØªØµØ±Ø§Øª  
+
+AcronymExtractor.marking_up_acronyms:ÙØªÙ
+ ØªØ±Ù
+ÙØ² Ø§ÙÙ
+Ø®ØªØµØ±  
+
+AcronymExtractor.markup_acronyms:Ø§Ø¶Ù ÙØ§ØµÙØ© ØšÙØ§ÙØ§Øª Ø§ÙÙ
+Ø®ØªØµØ± Ø§ÙÙ ÙØµ Ø§ÙÙØ«ÙÙØ©.  
+
+ArchivesInfPlugin.desc:Ø§ÙÙ
+ÙØ§ØšØ³  
+
+AutoExtractMetadata.desc:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙØ£Ø³Ø§Ø³ Ø§ÙØ°Ù ÙØ¬Ù
+Ø¹ ØšÙÙ ÙØžÙÙØ© ÙÙ Ù
+Ø³ØªØ®Ø±Ø¬ Ù
+Ù Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙÙ
+Ø³ØªØ®Ø±Ø¬Ø©.  
+
+AutoExtractMetadata.extracting:Ø¥Ø³ØªØ®ÙØ§Øµ
+
+AutoExtractMetadata.first:ÙØ§ØŠÙ
+Ø© Ù
+ÙÙØµÙØ© ØšÙØ§ØµÙØ© ÙÙØ£Ø­Ø¬Ø§Ù
+ Ø§ÙØ£ÙÙÙ Ø§ÙØªÙ ØªØ³ØªØ®ÙØµ Ù
+Ù Ø§ÙÙØµ Ø§ÙÙ Ø­ÙÙ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª. ÙØ°Ø§ Ø§ÙØ­ÙÙ ÙØ³Ù
+Ù  'FirstNNN'.  
+
+BaseMediaConverter.desc:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙÙ
+Ø³Ø§Ø¹Ø¯ Ø§ÙØ°Ù ÙÙÙØ± Ø§ÙÙØžÙÙØ© Ø§ÙØ§Ø³Ø§Ø³ÙØ© ÙÙ
+ÙØ§ØšØ³ ØªØ­ÙÙÙ Ø§ÙÙØ³Ø§ØŠØ· Ø§ÙÙ
+ØªØ¹Ø¯Ø¯Ø© Ù
+Ø«Ù Ù
+Ø­ÙÙ Ø§ÙØµÙØ±Ø©ÙÙ
+Ø­ÙÙ Ø§ÙÙÙØ¯ÙÙ.  
+
+BasePlugin.associate_ext:ØªØªØ³ØšØš ÙÙ Ø§Ù ÙØªÙ
+ ØªØ¬ÙÙØ² Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØªÙ ÙÙØ§  ÙÙØ³ Ø§Ø³Ù
+ Ø§ÙÙØ«ÙÙØ© ØšÙØ§Ø³Ø·Ø© Ø§ÙÙ
+ÙØ§ØšØ³ Ù Ø§Ù ÙØªÙ
+ Ø¥ÙØ­Ø§Ù Ø§Ø³Ù
+ Ø£Ù
+ØªØ¯Ø§Ø¯ Ø§ÙÙ
+ÙÙ Ù
+Ù ÙØ§ØŠÙ
+Ø© Ù
+ÙØµÙÙØ© ØšÙØ§ØµÙØ© ÙÙÙØ§ ÙÙÙ
+Ø¶Ù
+ÙÙ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ Ù
+Ø¹ Ø§ÙÙØ«ÙÙØ© Ø§ÙØªÙ ÙØ¬Ø±Ù ØªØ¬ÙÙØ²ÙØ§ ØšØ¯ÙØ§ Ù
+Ù Ø§Ù ØªØ¹Ø§ÙØ¬ ØšÙØµÙÙØ§ ÙØ§ØŠÙ
+Ø© Ù
+ÙÙØµÙØ©  
+
+BasePlugin.associate_tail_re:ØªØ¹ØšÙØ± Ù
+ÙØªØžÙ
+ ÙÙ
+Ø¶Ø§ÙØ§Ø© Ø£Ø³Ù
+Ø§Ø¡ Ø§ÙÙ
+ÙÙØ§Øª ÙØ¥ÙØ¬Ø§Ø¯ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø±ØªØšØ·Ø© . ÙØ³ØªØ®Ø¯Ù
+  ÙØšØ¯ÙÙ Ø£ÙØ«Ø± ÙÙØ©  Ùassociate_ext.  
+
+BasePlugin.block_exp:BasPlug.block_exp:Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø¶Ø§ÙØ§Ø© Ù
+Ø¹ ÙØ°Ø§ Ø§ÙØªØ¹ØšÙØ± Ø§ÙÙ
+ÙØªØžÙ
+ Ø³ÙÙ ØªØºÙÙ Ù ÙÙ ÙØ³Ù
+Ø­ ØšØªÙ
+Ø±ÙØ±ÙØ§ ÙØ§Ù Ù
+ÙØ§ØšØ³ Ø¢Ø®Ø± ÙÙ Ø§ÙÙØ§ØŠÙ
+Ø©.ÙØ¹Ø§ÙÙØ© ÙØ°Ø§ Ø§ÙØ¥Ø¬Ø±Ø§Ø¡ ØªÙÙ
+Ù ÙÙ Ù
+ÙØ¹ Ø±Ø³Ø§ØŠÙ ÙØ«ÙØ±Ø© Ø­ÙÙ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø¯Ø®ÙØ© Ù Ø§ÙØªÙ ÙØ§ ØªØ§ØšÙ ÙØŽØ§ÙÙØ§.Ø¢Ù Ù
+ÙØ§ØšØ³ ÙØ¯ÙÙ Ù
+ÙØ¹ Ø¥ÙØªØ±Ø§Ø¶Ù ÙÙ
+ÙÙØ§ØªØÙ
+Ø«Ù Ù
+ÙØ§ØšØ³ HTMLplug Ù Ø§ÙØ°Ù ÙÙ
+ÙØ¹ ØªÙ
+Ø±ÙØ± Ø§ÙÙ
+ÙÙØ§Øª ØšØ§ÙØ¥Ù
+ØªØ¯Ø§Ø¯Ø§Øª Ø§ÙØªØ§ÙÙØ©: .gif, .jpg, .jpeg, .png or .css .
+
+BasePlugin.desc:Ø§ÙÙØŠØ© Ø§ÙØ£Ø³Ø§Ø³ÙØ© ÙÙÙ Ù
+ÙØ§ØšØ³ Ø§ÙØ¥Ø³ØªÙØ±Ø§Ø¯.
+
+BasePlugin.dummy_text:ÙØ°Ø§ Ø§ÙÙ
+ÙÙ ÙØ§ ÙØªØ¶Ù
+Ù ÙØµ.
+
+BasePlugin.encoding.ascii:Plain 7 bit ascii. ÙØ°Ø§ ÙØ¯ ÙÙÙÙ Ø§Ø³Ø±Ø¹ ÙÙÙÙØ§ Ù
+Ù Ø§Ø³ØªØ®Ø¯Ø§Ù
+ iso_8859_1. Ø­Ø°Ø§Ø± Ù
+Ù Ø§Ø³ØªØ®Ø¯Ø§Ù
+ ÙØ°Ø§ Ø¹ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ù Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ÙÙ
+ÙÙ Ø§Ù ØªØ­ØªÙÙ Ø¹ÙÙ Ø£Ø­Ø±Ù plain 7 bit ascii Ø±ØºÙ
+ (Ù
+Ø«Ø§ÙØÙØ«Ø§ØŠÙ Ø§ÙÙ
+Ø§ÙÙØ© Ø£Ù ÙØ±ÙØ³ÙØ© ØªØªØ¶Ù
+Ù ÙÙÙØ§Øª) Ø ÙØšØ¯ÙØ§ Ù
+Ù Ø§Ø³ØªØ®Ø¯Ø§Ù
+ , ÙØ§Ø³ØªØ®Ø¯Ù
+ ØšØ¯ÙØ§ iso_8859_1 .  
+
+BasePlugin.encoding.unicode:ØŽÙÙØ±Ø© ÙÙØ§Ø³ÙØ© ÙÙØ·.
+
+BasePlugin.encoding.utf8:Ø¥Ù
+Ø§ utf8 Ø£Ù ØŽÙÙØ±Ø© ÙÙØ§Ø³ÙØ© -- ØªØ­Ø³Ø³ ØªÙÙØ§ØŠÙ.
+
+BasePlugin.filename_encoding:ØªØ±Ù
+ÙØ² Ù
+ØµØ¯Ø± Ø§ÙÙ
+ÙÙ ÙØ£Ø³Ù
+Ø§Ø¡ Ø§ÙÙ
+ÙÙØ§Øª.  
+
+BasePlugin.filename_encoding.auto:ØªÙÙØ§ØŠÙØ§ Ø§ÙØ­Øµ ØªØ±Ù
+ÙØ²  Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙ.  
+
+BasePlugin.filename_encoding.auto_language_analysis:Ø§ÙÙØŽÙ Ø§ÙØªÙÙØ§ØŠÙ ÙØªØ±Ù
+ÙØ² Ø§ÙÙ
+ÙÙ Ø¹Ù Ø·Ø±ÙÙ ØªØ­ÙÙÙÙ .  
+
+BasePlugin.filename_encoding.auto_filesystem_encoding:Ø§ÙÙØŽÙ Ø§ÙØªÙÙØ§ØŠÙ ÙØªØ±Ù
+ÙØ² Ø§ÙÙ
+ÙÙ ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+  ÙØžØ§Ù
+ ØªØ±Ù
+ÙØ² Ø§ÙÙ
+ÙÙØ§Øª.  
+
+BasePlugin.filename_encoding.auto_fl:Ø§Ø³ØªØ®Ø¯Ù
+ ÙØžØ§Ù
+ ØªØ±Ù
+ÙØ² Ø§ÙÙ
+ÙÙØ§Øª Ø Ø«Ù
+ ØªØ­ÙÙÙ Ø§ÙÙØºØ©  ÙÙÙØŽÙ Ø¹Ù ØªØ±Ù
+ÙØ² Ø§Ø³Ù
+ Ù
+ÙÙ .  
+
+BasePlugin.filename_encoding.auto_lf:Ø§Ø³ØªØ®Ø¯Ù
+  Ø§ÙØªØ­ÙÙÙ Ø§ÙÙØºÙÙ Ø«Ù
+ ÙØžØ§Ù
+ ØªØ±Ù
+ÙØ² Ø§ÙÙ
+ÙÙØ§Øª Ø  ÙÙÙØŽÙ Ø¹Ù ØªØ±Ù
+ÙØ² Ø§Ø³Ù
+ Ù
+ÙÙ .  
+
+BasePlugin.no_blocking:ÙØ§ ØªØºÙÙ Ø§Ù Ù
+ÙÙ. ÙØ±ØªØšØ· ØšÙØ§ Ù
+Ù Ø£Ù ØµÙØ±Ø© (Ù
+Ø«Ù Ø§ÙØµÙØ± ÙÙ ØµÙØ­Ø© ÙÙØš) Ø³ØªØ¶Ø§Ù Ø§ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ÙÙØ«Ø§ØŠÙ .  
+
+BasePlugin.no_cover_image:ÙØ§ ØªØ­Ø§ÙÙ Ø§ÙÙØžØ± Ø¥ÙÙ ØšØ§Ø¯ØŠØ© Ø§ÙÙ
+ÙÙ.jpg  (Ø­ÙØ« Ø§ÙØšØ§Ø¯ØŠØ© ÙÙ ÙÙØ³ Ø¥Ø³Ù
+ Ø§ÙÙ
+ÙÙ Ù
+ÙØ¶ÙØ¹ Ø§ÙÙ
+Ø¹Ø§ÙØ¬Ø©) Ù Ø¥ÙØ­Ø§Ù ÙØ°Ø§ Ø§ÙÙ
+ÙÙ ÙØµÙØ±Ø© ØºÙØ§Ù.
+
+BasePlugin.OIDtype.auto:Ø§Ø³ØªØ®Ø¯Ø§Ù
+ OIDtype Ø§ÙÙ
+Ø­Ø¯Ø¯ ÙÙ import.pl  
+
+BasePlugin.process_exp:ØªØ¹ØšÙØ± Ù
+ÙØªØžÙ
+ ÙØšÙØ±Ù ÙÙ
+Ø¶Ø§ÙØ§Ø© Ø£Ø³Ù
+Ø§Ø¡ Ø§ÙÙ
+ÙÙØ§Øª. Ø³ÙÙ ØªØ¹Ø§ÙØ¬ Ø£Ø³Ù
+Ø§Ø¡ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø¶Ø§ÙØ§Ø©  ØšÙØ§Ø³Ø·Ø© ÙØ°Ø§ Ø§ÙÙ
+ÙØ§ØšØ³. Ù
+Ø«Ø§Ù, Ø¥Ø³ØªØ®Ø¯Ø§Ù
+  '(?i).html?\$' ÙØ¶Ø§ÙÙ  ÙÙ Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ØªÙØªÙÙ Øš .htm Ø£Ù .html (Ø­Ø§ÙØ©-ØºÙØ± Ø­Ø³Ø§Ø³Ø©).
+
+BasePlugin.smart_block:ÙÙ
+ÙØ¹ ÙÙ Ø§ÙÙ
+ÙÙØ§Øª ØšØµÙØ±Ø© Ù
+Ø±ÙØ­Ø© Ø Ù ÙØºÙÙÙ Ø¹Ù Ø§ÙÙØžØ± ÙÙ Ø£Ø³Ù
+Ø§Ø¡ Ø§ÙÙ
+ÙÙØ§Øª
+
+BasePlugin.stems:stem  
+
+BasePlugin.file_rename_method:Ø§ÙØ§Ø³ÙÙØš Ø§ÙØ°Ù ÙØ³ØªØ®Ø¯Ù
+ ÙÙ Ø¥Ø¹Ø§Ø¯Ø© ØªØ³Ù
+ÙØ© ÙØ³Ø®Ø© Ù
+Ù Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø³ØªÙØ±Ø¯Ø© Ù Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø±ØªØšØ·Ø© ØšÙØ§.  
+
+BasePlugin.rename_method.url:Ø¥Ø³ØªØ®Ø¯Ù
+ ØªØ±Ù
+ÙØ² Ø¹ÙÙØ§Ù Ø§ÙÙ
+ÙØ§Ø±Ø¯ Ø§ÙÙ
+ÙØ­Ø¯ ÙÙ Ø¥Ø¹Ø§Ø¯Ø© ØªØ³Ù
+ÙØ© Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø³ØªÙØ±Ø¯Ø© ÙØ§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø±ØªØšØ·Ø© ØšÙØ§.  
+
+BasePlugin.rename_method.base64:Ø§Ø³ØªØ®Ø¯Ø§Ù
+ ØªØ±Ù
+ÙØ² base64  ÙÙ Ø¥Ø¹Ø§Ø¯Ø© ØªØ³Ù
+ÙØ© Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø³ØªÙØ±Ø¯Ø© ÙØ§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø±ØªØšØ·Ø© ØšÙØ§.  
+
+BasePlugin.rename_method.none:ÙØ§ ØªØ¹Ø¯ ØªØ³Ù
+ÙØ© Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø³ØªÙØ±Ø¯Ø© ÙØ§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø±ØªØšØ·Ø© ØšÙØ§.  
+
+BibTexPlugin.desc:ÙÙØ±Ø§Ø¡ BibTexPlug Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØšÙØšÙÙÙØ¬Ø±Ø§ÙÙØ© ÙÙ ØŽÙÙ BibTex .ÙÙØŽØŠ BibTexPlug ÙÙØ§Ù ÙØ«ÙÙØ© ÙØ£Ù Ù
+Ø±Ø¬Ø¹ ÙÙ Ø§ÙÙ
+ÙÙ. ÙÙ ÙØŠØ© ÙØ±Ø¹ÙØ© Ù
+Ù  SplitPlug, ÙØ°ÙÙ Ø¥Ø°Ø§ ÙØ§ÙØª ÙÙØ§Ù ØªØ³Ø¬ÙÙØ§Øª Ù
+ØªØ¹Ø¯Ø¯Ø© ÙÙÙØ§ ØªÙØ±Ø£.  
+
+BookPlugin.desc:ÙØ®ÙÙ ÙØ«ÙÙØ© Ù
+ØªØ¹Ø¯Ø¯Ø© Ø§ÙÙ
+Ø³ØªÙÙØ§Øª  Ù
+Ù ÙØ«ÙÙØ© ØªØªØ¶Ù
+Ù ØªÙØ¬Ø§Ù Ù
+Ø³ØªÙÙ Ø¬Ø¯ÙÙ Ø§ÙÙ
+Ø­ØªÙÙØ§Øª <<toc>> . ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª  ÙÙÙ ÙØ³Ù
+ Ù
+Ø£Ø®ÙØ° Ù
+Ù Ø£Ù ØªÙØ¬Ø§Ù Ø§Ø®Ø±Ù Ø¹ÙÙ ÙÙØ³ Ø§ÙØ®Ø· Ø ÙÙ
+Ø§ . <<TOC>>. Ù
+Ø«Ø§Ù <<Title>>xxxx<</Title>> ØªØ¹ÙÙ ÙØ§ØµÙØ© ØšÙØ§ÙØ§Øª Ø§ÙØ¹ÙÙØ§Ù. ÙÙ ØŽØŠ Ø¢Ø®Ø± ØšÙÙ ØªÙØ¬Ø§Ù ÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+Ø­ØªÙÙØ§Øª ÙØ¹Ø§Ù
+Ù ÙÙØµ ØšØ³ÙØ· ØšÙØºØ© html ( Ù
+Ø«Ø§ÙØ ÙÙ ØªØªÙ
+ Ù
+Ø¹Ø§ÙØ¬Ø© Ø±ÙØ§ØšØ· html Ø§Ù Ø£Ù ØŽØŠ Ù
+Ù Ù
+Ø§Ø¯Ø© Ù
+ÙØ§ØšØ³ HTMLPlug ). Ù
+Ø§ Ø¹Ø¯Ø§ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØªÙ ÙÙØ§ Ø§ÙØ¥Ù
+ØªØ¯Ø§Ø¯ .hb ØšØµÙØ±Ø© Ø¥ÙØªØ±Ø§Ø¶ÙØ© (ÙÙ
+ÙÙ ØªØºÙØ± ÙØ°Ø§ ØšØ§Ø¶Ø§ÙØ© Ù
+ÙÙ ÙØ­Ù
+Ù ÙÙØ³ Ø§ÙØ¥Ø³Ù
+  ÙÙ Ø®ÙØ§Ø±  process_exp- ÙÙÙÙ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØªÙ ÙÙØ§ Ø§ÙØ¥Ù
+ØªØ¯Ø§Ø¯  .jpg ØªØ¹ØªØšØ± ØµÙØ±Ø© ØºÙØ§Ù (Ù
+ÙÙØ§Øª jpg ÙØªÙ
+ ØºÙÙÙØ§ ØšÙØ§Ø³Ø·Ø© ÙØ°Ø§ Ø§ÙÙ
+ÙØ§ØšØ³). BookPlug  ÙÙ ØªØšØ³ÙØ· (Ù Ø¥Ù
+ØªØ¯Ø§Ø¯) ÙÙ
+ÙØ§ØšØ³ HBPlug Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ø§ÙÙ
+ÙØªØšØ© Ø§ÙØ¥ÙØ³Ø§ÙÙØ©.ÙØ¹ØªØšØ± BookPlug ÙÙ Ø§ÙØ£Ø³Ø±Ø¹ ÙØ§ÙÙ ÙØªÙÙØ¹ Ø§Ù ØªÙÙÙ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø¯Ø®ÙØ© Ø£ÙØžÙ (Ù
+Ø¯Ø®ÙØ§Øª Ù
+Ø¬Ù
+ÙØ¹Ø§Øª  HDL ØªØªØ¶Ù
+Ù Ø§ÙÙØ«ÙØ± Ù
+Ù ØªÙØ¬Ø§Ù html Ø­ÙÙ <<TOC>> , ØªØ³ØªØ®Ø¯Ù
+ ØªÙØ¬Ø§Ù <<I>> ÙØªÙ
+ÙØ² Ø§ÙØµÙØ± Ù ØšØšØ³Ø§Ø·Ø© ØªØ£Ø®Ø¯ ÙÙ Ø§ÙÙØµ ØšÙÙ ØªÙØ¬Ø§Ù <<TOC>> Ù ØšØ¯Ø§ÙØ© Ø§ÙÙØµ ÙÙØ§ØµÙØ© ØšÙØ§ÙØ§Øª Ø§ÙØ¹ÙÙØ§Ù). Ø¥Ø°Ø§ ÙÙØª ØªÙÙÙ
+ ØšØªØ£ØŽÙØ± ÙØ«Ø§ØŠÙ ÙØªØ¹Ø±Ø¶ ØšÙÙØ³ Ø§Ø³ÙÙØš Ù
+Ø¬Ù
+ÙØ¹Ø§Øª HDL Ø§Ø³ØªØ®Ø¯Ù
+ ÙØ°Ø§ Ø§ÙÙ
+ÙØ§ØšØ³ ØšØ¯ÙØ§ Ù
+Ù HBPlug.  
+
+CONTENTdmPlugin.desc:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙØªÙ ØªØ¹Ø§ÙØ¬ Ù
+ÙÙØ§Øª RDF Ø§ÙØªÙ ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª CONTENTdm Ø§ÙÙ
+ØµØ¯Ø±Ø© .  
+
+ConvertBinaryFile.apply_fribidi:ØªØŽØºÙÙ "fribidi" ØšØ±ÙØ§Ù
+Ø¬ Ø®ÙØ§Ø±Ø²Ù
+ÙØ© Ø§ÙÙÙÙÙÙÙØ¯ Ø«ÙØ§ØŠÙ Ø§ÙØ¥ØªØ¬Ø§Ù Ø¹ÙÙ Ù
+ÙÙ Ù
+Ø­ÙÙ (ÙØµ Ù
+Ù Ø§ÙÙÙ
+ÙÙ Ø§ÙÙ Ø§ÙÙØ³Ø§Ø±).  
+
+ConvertBinaryFile.convert_to:Plugin converts to TEXT or HTML or various types of Image (e.g. JPEG, GIF, PNG).
+
+ConvertBinaryFile.convert_to.auto:ØªÙÙØ§ØŠÙØ§ ÙÙ
+ ØšØ§Ø®ØªÙØ§Ø± Ø§ÙÙÙØŠØ© Ø§ÙÙ
+Ø­ÙÙØ© Ø£ÙØ¶Ø§ .Ø§ÙÙÙØŠØ© Ø§ÙÙ
+Ø®ØªØ§Ø±Ø© ØªØ¹ØªÙ
+Ø¯ Ø¹ÙÙ ÙÙØ¹ Ø§ÙÙØ«ÙÙØ© Ø§ÙÙ
+Ø¯Ø®ÙØ© Ø Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù Ø ÙØ§Ù  Word ÙØªØ­ÙÙ ØªÙÙØ§ØŠÙØ§ Ø§ÙÙ HTML, ØšÙÙÙ
+Ø§ ÙØªÙ
+ ØªØ­ÙÙÙ PowerPoint Ø§ÙÙ ÙÙØŠØ© Greenstone's PagedImage
+
+ConvertBinaryFile.convert_to.html:ÙÙØŠØ© ÙØºØ© ØªØ±Ù
+ÙØ² Ø§ÙÙØµ Ø§ÙØªØŽØ¹ØšÙ.
+
+ConvertBinaryFile.convert_to.text:ÙÙØŠØ© ÙØµ ØšØ³ÙØ·.
+
+ConvertBinaryFile.convert_to.pagedimg:Ø³ÙØ³ÙØ© Ù
+Ù Ø§ÙØµÙØ±.  
+
+ConvertBinaryFile.convert_to.pagedimg_jpg:JPEG ÙÙØŠØ©.
+
+ConvertBinaryFile.convert_to.pagedimg_gif:GIF ÙÙØŠØ©.
+
+ConvertBinaryFile.convert_to.pagedimg_png:PNG ÙÙØŠØ©.
+
+ConvertBinaryFile.desc:ÙØ°Ø§ ÙÙ Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙØ°Ù ÙØ±Ø«ØªÙ Ù
+ÙØ§ØšØ³  WordPlugin, PowerPointPlugin, PostScriptPlugin, RTFPlugin and PDFPlugin ÙØ³ÙÙ ØªØ­ÙÙÙ Ø£ØŽÙØ§Ù ÙØ°Ù Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙÙ ÙØµ Ø HTML Ø£Ù Ø³ÙØ³ÙØ© Ù
+Ù Ø§ÙØµÙØ±.Ù ÙÙ ÙØ¹Ù
+Ù ØšØ¢ÙÙØ© Ø§ÙØªØ­ÙÙÙ Ø§ÙØ¯ÙÙØ§Ù
+ÙÙÙ ÙÙÙ
+ÙØ§ØšØ³ Ø§ÙØ«Ø§ÙÙÙØ© (HTMLPlugin, StructuredHTMLPlugin, PagedImagePlugin or TextPlugin) ØªØ£Ø³ÙØ³Ø§ Ø¹ÙÙ Ø­Ø¬Ø© Ø§ÙÙ
+ÙØ§ØšØ³ 'convert_to'.  
+
+ConvertBinaryFile.keep_original_filename:Ø§Ø­ØªÙØž ØšØ§Ø³Ù
+ Ø§ÙÙ
+ÙÙ Ø§ÙØ£ØµÙÙ ÙÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+ØªØ¹ÙÙØ©Ø ÙÙØ°ÙÙ ÙÙÙ
+Ø­ÙÙØ© Ø¥ÙÙ .doc Ù.pdf ÙÙÙØ°Ø§.  
+
+ConvertBinaryFile.use_strings:Ø§Ø°Ø§ ØªÙ
+ Ø¥Ø¹Ø¯Ø§Ø¯ÙØ§ Ø Ø³ÙÙ ÙØªÙ
+ Ø¥Ø³ØªØ¯Ø¹Ø§Ø¡ Ø¯Ø§ÙØ© Ø³ÙØ³ÙØ© ÙØµÙØ© ÙØ¥Ø³ØªØ®ÙØ§Øµ Ø§ÙÙØµ Ø¥Ø°Ø§ ÙØŽÙ Ù
+Ø±ÙÙ Ø§ÙØªØ­ÙÙÙ.  
+
+ConvertToRogPlugin.desc:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙØ°Ù ÙØ±Ø« Ù
+Ù RogPlugin.  
+
+CSVPlugin.desc:Ù
+ÙØ§ØšØ³ ÙÙÙ
+ÙÙØ§Øª ÙÙ ÙØ§ØŠÙ
+Ø© Ù
+ÙØµÙÙØ© ØšÙØ§ØµÙØ© ÙÙÙÙ
+ Ø§ÙÙÙØŠØ§Øª. Ø³ÙÙ ÙØªÙ
+ Ø¥ÙØŽØ§Ø¡ ÙØ«ÙÙØ© Ø¬Ø¯ÙØ¯Ø© ÙÙÙ Ø³Ø·Ø± ÙÙ Ø§ÙÙ
+ÙÙ.  
+
+DateExtractor.desc:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙÙ
+Ø³Ø§Ø¹Ø¯ Ø§ÙÙ
+Ø³ØªØ®Ø±Ø¬ ÙØ§Ø³ØªØ®Ø±Ø§Ø¬ Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙØªØ§Ø±ÙØ® Ù
+Ù Ø§ÙÙØµ.  
+
+DateExtractor.extract_historical_years:Ø¥Ø³ØªØ®ÙØ§Øµ Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙÙØªØ±Ø§Øª Ø§ÙØ²Ù
+ÙÙØ© Ù
+Ù Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªØ§Ø±ÙØ®ÙØ©. ÙØ°Ù Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª ØªØ®Ø²Ù ÙÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª Ù
+Ø¹ Ø§ÙÙØ«ÙÙØ© . ØªÙØ¬Ø¯ ÙØ§Ø¬ÙØ© ØšØ­Ø« ÙÙØ°Ù Ø§ÙÙØ§ØµÙØ© Ù Ø§ÙØªÙ ÙÙ
+ÙÙ ØªØ¶Ù
+ÙÙÙØ§ ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ØšØ¥Ø¶Ø§ÙØ© ÙØ°Ø§ Ø§ÙÙØµ , "format QueryInterface DateSearch" ÙÙ Ù
+ÙÙ Ø§ÙØªÙÙÙÙ
+
+DateExtractor.maximum_century:Ø¥Ø³ØªØ®ÙØ§Øµ Ø¥Ø³Ù
+ Ø§ÙÙØ±Ù Ø§ÙØ£ÙØµÙ ÙÙØ§ØµÙØ© ØšÙØ§ÙØ§Øª ØªØ§Ø±ÙØ®ÙØ©.0(Ù
+Ø«Ø§Ù Ø . 14 Ø³ÙÙ ÙØ³ØªØ®ÙØµ ÙÙ Ø§ÙÙ
+Ø±Ø§Ø¬Ø¹ Ø­ØªÙ Ø§ÙÙØ±Ù Ø§ÙØ±Ø§ØšØ¹ Ø¹ØŽØ±).
+
+DateExtractor.maximum_year:Ø§Ø³ØªØ®Ø¯Ù
+ Ø§ÙÙ
+ÙØ¹Ø¯ Ø§ÙØ²Ù
+ÙÙ Ø§ÙØ£ÙØµÙ ÙÙØ§ØµÙØ© ØšÙØ§ÙØ§Øª (ÙÙ Ø­ÙØšØ© Ø²Ù
+ÙÙØ© Ø¹Ø§Ù
+Ø©, Ù
+Ø«Ù  1950).
+
+DateExtractor.no_bibliography:ÙØ§ ØªØ­Ø§ÙÙ ØºÙÙ Ø§ÙØªÙØ§Ø±ÙØ® Ø§ÙØšÙØšÙÙÙØ¬Ø±Ø§ÙÙØ© Ø¹ÙØ¯ Ø¥Ø³ØªØ®ÙØ§Øµ Ø§ÙÙ
+ÙØ§Ø¹ÙØ¯ Ø§ÙØ²Ù
+ÙÙØ©.
+
+DirectoryPlugin.desc:Ù Ù
+ÙØ§ØšØ³ ÙØ¹ÙØ¯ Ø§ÙÙ ÙÙ Ø§ÙØ£Ø¯ÙØ© Ù
+Ø¹Ø§ÙØ¬Ø§ ÙÙ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØªÙ ÙØ¬Ø¯ÙØ§  
+
+DirectoryPlugin.recheck_directories:ØšØ¹Ø¯ Ù
+Ø¹Ø§ÙØ¬Ø© Ù
+ÙÙØ§Øª ÙÙ Ø¯ÙÙÙ Ø¥Ø³ØªÙØ±Ø§Ø¯Ø Ø£Ø¹Ø¯ ÙØ±Ø§Ø¡Ø© Ø§ÙØ¯ÙÙÙ ÙÙØ­Øµ Ø£Ù Ù
+ÙÙØ§Øª Ø¬Ø¯ÙØ¯Ø© Ø£ÙØŽØŠØª  
+
+DirectoryPlugin.use_metadata_files:ÙØ±Ø§Ø¡Ø© ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ù
+Ù Ù
+ÙÙØ§Øª ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª xml(Ù
+Ø³ØªÙÙØ± - metadataxmlplug (Ø§ÙÙ ÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+ÙØ§ØšØ³ ØšØ¯ÙØ§  
+
+DatabasePlugin.desc:ÙØ³ØªØ®Ø¯Ù
+ Ø§ÙØªØ³Ø¬ÙÙØ§Øª Ù
+Ù ÙØ§Ø¹Ø¯Ø© Ø§ÙØšÙØ§ÙØ§Øª ÙÙØ«Ø§ØŠÙ.
+
+DSpacePlugin.desc:Ù
+ÙØ§ØšØ³ DSpacePlug ÙØ£Ø®Ø° Ù
+Ø¬Ù
+ÙØ¹Ø© Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙÙ
+ØµØ¯Ø±Ø© Ù
+Ù DSpace Ù ÙØ³ØªÙØ±Ø¯ÙØ§ Ø¥ÙÙ ÙØ±ÙÙØ³ØªÙÙ.  
+	
+DSpacePlugin.first_inorder_ext:ÙØ³ØªØ®Ø¯Ù
+ ÙØ°Ø§ ÙØªØ¹Ø±ÙÙ Ø§ÙØ±Ø§ÙØ¯ Ø§ÙØ¥ØšØªØ¯Ø§ØŠÙ ÙÙØ«Ø§ØŠÙ Ù
+Ø¬Ù
+ÙØ¹Ø© DSpace Ù
+Ø¹ ÙØ°Ø§ Ø§ÙØ®ÙØ§Ø±Ø ÙØ§Ù Ø§ÙÙØžØ§Ù
+
+
+DSpacePlugin.first_inorder_mime:ÙØ³ØªØ®Ø¯Ù
+ ÙØ°Ø§ ÙØªØ­Ø¯ÙØ¯ Ù
+ØŽØºÙ Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙØ£ÙÙÙ ÙÙØ«ÙÙØ© Ù
+Ø¬Ù
+ÙØ¹Ø© DSpace. Ù
+Ø¹ ÙØ°Ø§ Ø§ÙØ®ÙØ§Ø±Ø Ø³ÙÙ ÙØªØ¹Ø§Ù
+Ù Ø§ÙÙØžØ§Ù
+ Ø£ÙÙØ§Ø¹ ÙØ«Ø§ØŠÙ MIME ØšØ§ÙØªØ±ØªÙØš ÙÙØšØ­Ø« Ø¹Ù Ø§ÙÙ
+ØŽØºÙ Ø§ÙØ£ÙÙÙ Ø§ÙÙ
+ØªØ§Ø­.  
+
+DSpacePlugin.only_first_doc:ÙØ³ØªØ®Ø¯Ù
+ ÙØ°Ø§ ÙØªØ¹Ø±ÙÙ Ø§ÙØ±Ø§ÙØ¯ Ø§ÙØ§ØšØªØ¯Ø§ØŠÙ ÙØšÙØ§ÙØ§Øª Ù
+Ø¬Ù
+ÙØ¹Ø© ÙØ«Ø§ØŠÙ DSpace Ù
+Ø¹ ÙØ°Ø§ Ø§ÙØ®ÙØ§Ø±Ø ÙØ§Ù Ø§ÙÙØžØ§Ù
+ Ø³ÙÙ ÙØ¹Ø§Ù
+Ù Ø£ÙÙØ§Ø¹
+
+EmailAddressExtractor.desc:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙÙ
+Ø³Ø§Ø¹Ø¯ Ø§ÙÙ
+Ø³ØªØ®Ø±Ø¬ ÙØ§ÙØªØŽØ§Ù  Ø¹ÙØ§ÙÙÙ Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ ÙÙ Ø§ÙÙØµ.  
+
+EmailAddressExtractor.done_email_extract:ØªÙ
+ ÙØ¥Ø³ØªØ®ÙØ§Øµ Ø¹ÙØ§ÙÙÙ Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ.
+
+EmailAddressExtractor.extracting_emails:Ø¥Ø³ØªØ®ÙØ§Øµ Ø¹ÙØ§ÙÙÙ Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ
+
+EmailAddressExtractor.extract_email:Ø¥Ø³ØªØ®ÙØ§Øµ Ø¹ÙØ§ÙÙÙ Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ ÙÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª.
+
+EmailPlugin.desc:Ù
+ÙØ§ØšØ³ mail plug ÙÙØ±Ø£ Ù
+ÙÙØ§Øª Ø§ÙØšØ±ÙØ¯ Ø§ÙØ§ÙÙØªØ±ÙÙÙ.  ÙØ°Ù Ø§ÙÙ
+ÙÙØ§Øª ØªÙ
+Øª ØªØ³Ù
+ÙØªÙØ§ ØšØ£Ø¹Ø¯Ø§Ø¯ ØšØ³ÙØ·Ø© (Ø£Ù ÙÙ
+Ø§ ÙØ±Ø¯Øª ÙÙ Ù
+Ø¬ÙØ¯Ø§Øª Ø¯ÙÙÙ Ø§ÙØšØ±ÙØ¯ ) Ø£Ù Ù
+Ø¹
+
+EmailPlugin.no_attachments:ÙØ§ ØªØ­ÙØž Ù
+ÙØ­ÙØ§Øª Ø§ÙØ±Ø³Ø§ÙØ©.
+
+EmailPlugin.headers:Ø®Ø²Ù ØªØ±ÙÙØ³Ø§Øª Ø§ÙØšØ±ÙØ¯ Ø§ÙØ¥ÙÙØªØ±ÙÙÙ ÙÙ "ØªØ±ÙÙØ³Ø§Øª" ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª  
+
+EmailPlugin.OIDtype.message_id:Ø§Ø³ØªØ®Ø¯Ù
+ Ù
+Ø¹Ø±Ù Ø§ÙØ±Ø³Ø§ÙØ© ØšÙØµÙÙ Ù
+Ø¹Ø±Ù Ø§ÙÙØ«ÙÙØ© OID. Ø¥Ø°Ø§ ÙÙ
+ ÙÙÙ ÙÙØ§Ù Ù
+Ø¹Ø±Ù Ø±Ø³Ø§ÙØ© Ø Ø³ÙÙ ÙØ³ØªØ®Ø¯Ù
+  hash OID"  
+
+EmailPlugin.split_exp:Ø§ÙØªØ¹ØšÙØ±Ø§Øª Ø§ÙÙ
+ÙØªØžÙ
+Ø© ØšÙØºØ© perl Ø§ÙØªÙ ØªØ³ØªØ®Ø¯Ù
+ ÙØªÙØ³ÙÙ
+ Ù
+ÙÙØ§Øª ØªØ­ØªÙÙ Ø¹ÙÙ Ø§ÙØ¹Ø¯ÙØ¯ Ù
+Ù Ø§ÙØ±Ø³Ø§ØŠÙ Ø¥ÙÙ ÙØ«Ø§ØŠÙ ÙØ±Ø¯ÙØ©.  
+
+ExcelPlugin.desc:Ù
+ÙØ§ØšØ³ ÙØ§Ø³ØªÙØ±Ø§Ø¯ Ù
+ÙÙØ§Øª Ù
+Ø§ÙÙØ±ÙØ³ÙÙØª Ø§ÙØ³Ù (95 Ù 97 Ø¥ØµØ¯Ø§Ø±Ø§Øª).  
+
+FavouritesPlugin.desc:Ø§ÙÙ
+ÙØ§ØšØ³ ÙÙ
+Ø¹Ø§ÙØ¬Ø© Ù
+ÙÙØ§Øª Ø¥ÙØªØ±ÙØª Ø¥ÙØ³ØšÙÙØ±Ø± Ø§ÙÙ
+ÙØ¶ÙØ© .  
+
+FOXPlugin.desc:Ù
+ÙØ§ØšØ³ ÙÙ
+Ø¹Ø§ÙØ¬Ø© Ù
+ÙÙ Foxbase dbt . ÙÙÙØ± ÙØ°Ø§ Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙÙØžÙÙØ© Ø§ÙØ£Ø³Ø§Ø³ÙØ© ÙÙØ±Ø§Ø¡Ø©  dbt Ù Ù
+ÙÙØ§Øª dbf Ù Ù
+Ø¹Ø§ÙØ¬Ø© ÙÙ ØªØ³Ø¬ÙÙØ©. ÙØ°Ø§ Ø§ÙÙ
+ÙØ§ØšØ³
+
+GreenstoneXMLPlugin.desc:ÙØ¹Ø§ÙØ¬ ÙØ«Ø§ØŠÙ ÙØ±ÙÙØ³ØªÙÙ ÙÙ ÙÙØŠØ© xml .Ø¹ÙÙ
+Ø§ ØšØ§Ù ÙØ°Ø§ Ø§ÙÙ
+ÙØ§ØšØ³ ÙÙØ³ ÙÙ ÙØ­Øµ ØµÙØºØ©  (Ø±ØºÙ
+ Ø§Ù ÙØ­Ø¯Ø§Øª Ø§ÙÙ
+Ø¹Ø±Øš Ø§ÙÙØºÙÙ ÙÙ XML::ØªØ®ØªØšØ± Ø§ÙØ¬ÙØ¯Ø© Ø§ÙØªØ±ÙÙØš). Ù
+Ù
+
+GISExtractor.desc:ØšØ¬Ø§ÙØš Ø§ÙÙØŠØ© Ø§ÙØ£Ø³Ø§Ø³ BasPlug Ø§ÙØ°Ù ÙØ¯Ø¹Ù
+ ÙØ¯Ø±Ø§Øª GIS  
+
+GISExtractor.extract_placenames:Ø§Ø³ØªØ®ÙØ§Øµ Ø§ÙØ£Ù
+Ø§ÙÙ Ù
+Ù Ø§ÙÙØµ ÙØ§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§. ØªØªØ·ÙØš Ø§Ù
+ØªØ¯Ø§Ø¯ GIS ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone.  
+
+GISExtractor.gazetteer:Gazetteer ÙØ³ØªØ®ÙØµ Ø£Ø³Ù
+Ø§Ø¡ Ø§ÙØ£Ù
+Ø§ÙÙ Ù ØªØ¹ÙÙÙØ§ ÙÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª. ÙØªØ·ÙØš Ø¥Ù
+ØªØ¯Ø§Ø¯ GIS ÙÙ ÙØ±ÙÙØ³ØªÙÙ.  
+
+GISExtractor.place_list:Ø¹ÙØ¯ Ø§Ø³ØªØ®ÙØ§Øµ Ø§ÙØ£Ù
+Ø§ÙÙØ Ø¶Ù
+Ù ÙØ§ØŠÙ
+Ø© Ø§ÙØ£Ù
+Ø§ÙÙ ÙÙ ØšØ¯Ø§ÙØ© Ø§ÙÙØ«ÙÙØ©. ÙÙØ°Ø§ ÙØ­ØªØ§Ø¬ Ø¥ÙÙ Ø§Ù
+ØªØ¯Ø§Ø¯ GIS ÙØšØ±ÙØ§Ù
+Ø¬ Greenstone.  
+
+HBPlugin.desc:Ø§ÙØšØ±ÙØ§Ù
+Ø¬ Ø§ÙØ°Ù ÙÙÙÙ
+ ØšØ§ÙØ¹Ù
+Ù Ø¹ÙÙ Ù
+Ø¬ÙØ¯ ÙØªØš ØšØµÙØºØ© HTML. ÙÙØ°Ø§ Ø§ÙØšØ±ÙØ§Ù
+Ø¬ ÙØ³ØªØ®Ø¯Ù
+ Ù
+Ù ÙØšÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ù
+ÙØªØšØ© Ø§ÙØ¥ÙØ³Ø§ÙÙØ§Øª Humanity Library ÙÙØ§ ÙØªØ¹Ø§Ù
+ Ù
+Ø¹ Ø§ÙØ±Ù
+ÙØ² Ø§ÙÙ
+Ø¯Ø®ÙØ© ÙÙØ§ ASCII. ÙØ°Ø§ Ø§ÙØšØ±ÙØ§Ù
+Ø¬ ÙØ¹Ù
+Ù Ø£Ø³Ø±Ø¹Ø ÙÙÙÙ ÙÙØ¯ ÙÙØ§ ØªØŽØ¬ÙØ¹ Ø§ÙÙØ§Ø³ ÙÙÙ ØªÙØŽÙØ¡ Ù
+Ø¬Ù
+ÙØ¹Ø§ØªÙÙ
+ ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ BookPlugin ØšØ¯ÙØ§ Ù
+Ù ;-)\n\nUse BookPlugin Ø¥Ø°Ø§ Ø§ÙØŽØ£Øª Ù
+Ø¬Ù
+ÙØ¹Ø© Ø¬Ø¯ÙØ¯Ø© Ù Ø£Ø¹Ø¯Ø¯Øª Ù
+ÙÙØ§Øª Ù
+Ø«Ù Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ù
+ÙØªØšØ© Ø§ÙØ¥ÙØ³Ø§ÙÙØ§Øª. BookPlugin ÙÙØšÙ ÙÙ Ø±Ù
+ÙØ² Ø§ÙØ¥Ø¯Ø®Ø§Ù ÙÙÙÙ ÙØªØ·ÙØš Ø£Ù ØªÙÙÙ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø±Ù
+Ø²Ø© Ø®Ø§ÙÙØ© Ù
+Ù Ø§ÙØ£Ø®Ø·Ø§Ø¡ Ù
+Ø«Ù ÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª Ù
+ÙØªØšØ© Ø§ÙØ¥ÙØ³Ø§ÙÙØ§Øª  
+
+HBPlugin.encoding.iso_8859_1:ÙØ§ØªÙÙ 1 (ÙØºØ§Øª ØºØ±ØšÙØ©)  
+
+HTMLImagePlugin.aggressiveness:Ù
+Ø¯Ù ØªÙÙÙØ§Øª Ø¥Ø³ØªØ®ÙØ§Øµ Ø§ÙÙØµ ÙÙØ¥Ø³ØªØ®Ø¯Ø§Ù
+.  
+HTMLImagePlugin.aggressiveness.1:Ø¥Ø³Ù
+ Ù
+ÙÙ, Ù
+Ø³Ø§Ø±, ALT ÙØµ ÙÙØ·.  
+HTMLImagePlugin.aggressiveness.2:ÙÙ Ø§Ù  1, Ø²Ø§ØŠØ¯ Ø¹ÙÙØ§Ù Ø§ÙÙÙØ·Ø© Ø­ÙØ« ØªÙÙØ±.  
+HTMLImagePlugin.aggressiveness.3:ÙÙ Ù
+Ù 2 Ø ØšØ§ÙØ¥Ø¶Ø§ÙØ© Ø¥ÙÙ ÙØ±Øš Ø§ÙÙÙØ±Ø§Øª ÙÙÙ
+Ø§ ÙØ§Ù Ø°ÙÙ Ù
+ØªØ§Ø­Ø§  
+HTMLImagePlugin.aggressiveness.4:ÙÙ Ø§Ù  3, Ø²Ø§ØŠØ¯ Ø§ÙØªØ±ÙÙØ³Ø§Øª Ø§ÙØ³Ø§ØšÙØ© (<h1>, <h2>...) Ø­ÙØ« ØªÙÙØ±Øª.  
+HTMLImagePlugin.aggressiveness.5:ÙÙ Ø§Ù  4, Ø²Ø§ØŠØ¯ Ø§ÙÙ
+Ø±Ø§Ø¬Ø¹ Ø§ÙÙØµÙØ© Ø­ÙØ« ØªÙÙØ±Øª.  
+HTMLImagePlugin.aggressiveness.6:ÙÙ Ø§Ù  4, Ø²Ø§ØŠØ¯Ø§ ØªÙØ¬Ø§Ù Ø§ÙØµÙØ­Ø© ( Ø¹ÙÙØ§Ù Ø ÙÙÙ
+Ø§Øª Ù
+ÙØªØ§Ø­ÙØ©ØØ§ÙØ®)  
+HTMLImagePlugin.aggressiveness.7:ÙÙ 6 Ù 5 Ù 4 Ù
+Ø¹Ø§  
+HTMLImagePlugin.aggressiveness.8:ÙÙ 7Ø ØšØ§ÙØ¥Ø¶Ø§ÙØ© Ø¥ÙÙ ØªÙØ±Ø§Ø± Ø¹ÙÙØ§Ù Ø§ÙÙÙØ·Ø©Ø ÙØ§Ø³Ù
+ Ø§ÙÙ
+ÙÙØ Ù Ø¥ÙØ® (Ø¥ØšØ±Ø§Ø² Ø§ÙÙØªØ§ØŠØ¬ Ø§ÙØ£ÙØ«Ø± Ø§Ø±ØªØšØ§Ø·Ø§Ù).  
+HTMLImagePlugin.aggressiveness.9:ÙÙ Ø§Ù  1, Ø²Ø§ØŠØ¯ Ø§ÙÙØµ Ø§ÙÙØ§Ù
+Ù ÙÙ
+ØµØ¯Ø± Ø§ÙØµÙØ­Ø©.  
+
+HTMLImagePlugin.caption_length:ÙØ·ÙÙ Ø§ÙØ£ÙØµÙ  ÙØ¹ÙÙØ§Ù Ø§ÙÙÙØ·Ø§Øª (Ù
+Ø­Ø§Ø±Ù)  
+
+HTMLImagePlugin.convert_params:Ù
+Ø€ØŽØ±Ø§Øª Ø¥Ø¶Ø§ÙÙØ© ÙÙ
+Ø­ÙÙ ImageMagicK ÙÙ Ø¥ÙØŽØ§Ø¡ Ø§ÙÙ
+ØµØºØ±Ø© Ø Ù
+Ø«Ø§Ù , '-raise' Ø³ÙÙ ÙØ¹Ø·Ù ØªØ£Ø«ÙØ± Ø«ÙØ§Ø«Ù Ø§ÙØ£ØšØ¹Ø§Ø¯ Ø§ÙÙ Ø§ÙØµÙØ±Ø© Ø§ÙÙ
+ØµØºØ±Ø©.  
+
+HTMLImagePlugin.desc:ØšØ±ÙØ§Ù
+Ø¬ ÙØ§Ø³ØªØ®ÙØ§Øµ Ø§ÙØµÙØ± Ù Ø§ÙÙØµÙØµ Ø§ÙÙ
+Ø±ØªØšØ·Ø© Ù
+Ù ØµÙØ­Ø§Øª Ø§ÙØ¥ÙØªØ±ÙØª.  
+
+HTMLImagePlugin.document_text:Ø¥Ø¶Ø§ÙØ© ÙØµ ØµÙØ±Ø© ÙÙ ÙØ«ÙÙØ©: ÙØµ (Ø®ÙØ§Ù Ø°ÙÙ Ø§ÙÙØµ Ø§ÙÙ
+ÙØŽÙ ÙØ­ÙÙ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ).  
+
+HTMLImagePlugin.index_pages:ØªÙØŽÙÙ ØµÙØ­Ø§Øª Ù
+Ø¹ Ø§ÙØµÙØ±. ØšØ®ÙØ§Ù Ø§ÙØ§ØŽØ§Ø±Ø© ÙÙ ØµÙØ­Ø§Øª Ù
+ÙÙØ¹ Ø§ÙÙ
+ØµØ¯Ø±  
+
+HTMLImagePlugin.max_near_text:Ø§ÙØ¹Ø¯Ø¯ Ø§ÙØ£ÙØµÙ ÙÙ
+Ø­Ø§Ø±Ù ÙØ±Øš ØµÙØ± ÙÙØ¥Ø³ØªØ®ÙØ§Øµ  
+
+HTMLImagePlugin.min_height:ØšÙØ³Ù.ØªØ¬Ø§ÙØ² Ø§ÙØµÙØ± Ø§ÙØªÙ ÙÙ Ø£ÙØµØ± Ù
+Ù ÙØ°Ù.  
+
+HTMLImagePlugin.min_near_text:Ø§ÙØ¹Ø¯Ø¯ Ø§ÙØ£Ø¯ÙÙ ÙÙ
+Ø­Ø§Ø±Ù ÙØ±Øš ÙØµ Ø£Ù Ø¹ÙÙØ§Ù ÙÙØ·Ø© ÙÙØ¥Ø³ØªØ®ÙØ§Øµ  
+
+HTMLImagePlugin.min_size:ØšØ§ÙØªØ³. ØªØ¬Ø§ÙØ² Ø§ÙØµÙØ± Ø§ÙØªÙ ÙÙ Ø£ØµØºØ± Ù
+Ù ÙØ°Ø§.
+
+HTMLImagePlugin.min_width:ØšÙÙØ³Ù. ØªØ¬Ø§ÙØ² Ø§ÙØµÙØ± Ø§ÙØªÙ ÙÙ Ø£Ø¶ÙÙ Ù
+Ù ÙØ°Ø§.
+
+HTMLImagePlugin.neartext_length:Ø§ÙØ·ÙÙ Ø§ÙÙØ¯Ù ÙØ£ÙØ±Øš ÙØµ (Ù
+Ø­Ø§Ø±Ù).  
+
+HTMLImagePlugin.no_cache_images:ÙØ§ ØªØ¶Ø¹ Ø§ÙØµÙØ± ÙÙ Ø§ÙØ°Ø§ÙØ±Ø© Ø§ÙÙ
+Ø€ÙØªØ© (Ø£ØŽØ± Ø§ÙÙ Ø¹ÙÙØ§Ù Ø§ÙÙ
+ÙØ§Ø±Ø¯ Ø§ÙÙ
+ÙØ­Ø¯ Ø§ÙØ£ØµÙÙ).  
+
+HTMLImagePlugin.smallpage_threshold:Ø§ÙØµÙØ± Ø§ÙØªÙ ÙÙ Ø§ÙØµÙØ­Ø§Øª Ø£ØµØºØ± Ù
+Ù ÙØ°Ù ØšØ§ÙÙ(ØšØ§ÙØªØ³)Ø Ø³ÙÙ ØªØ­ØªÙÙ Ø§ÙØµÙØ­Ø© Ø¹ÙÙ Ø¥Ø¶Ø§ÙØ© ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙÙÙ Ù
+Ù (Ø§ÙØ¹ÙÙØ§Ù - Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙÙ
+ÙØªØ§Ø­ÙØ© - ... Ø¥ÙØ®)  
+
+HTMLImagePlugin.textrefs_threshold:ØšØ¯Ø§ÙØ© ÙÙØ¥ØŽØ§Ø±Ø§Øª Ø§ÙÙØµÙØ© .Ø§ÙÙÙÙ
+ Ø§ÙØ£ÙÙ ØªØ¹ÙÙ Ø§Ù Ø§ÙØ®ÙØ§Ø±Ø²Ù
+ÙØ© Ø£ÙÙ ØµØ±Ø§Ù
+Ø©  
+
+HTMLImagePlugin.thumb_size:Ø£ÙØµÙ Ø­Ø¬Ù
+ ÙÙØµÙØ±Ø© Ø§ÙÙ
+ØµØºØ±Ø© . ÙÙ Ù
+Ù Ø§ÙØ¹Ø±Ø¶ Ù Ø§ÙØ¥Ø±ØªÙØ§Ø¹.  
+
+HTMLPlugin.assoc_files:Ø§ÙØªØ¹ØšÙØ±Ø§Øª Ø§ÙÙ
+ÙØªØžÙ
+Ø© ÙÙ Perl ÙØ¥Ù
+ØªØ¯Ø§Ø¯Ø§Øª Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØªÙ ØªÙØ­Ù ØšÙØ«Ø§ØŠÙ HTML.  
+
+HTMLPlugin.desc:ÙØ¹Ø§ÙØ¬ ÙØ°Ø§ Ø§ÙÙ
+ÙØ§ØšØ³ Ù
+ÙÙØ§Øª Ø§ÙÙØµÙØµ Ø§ÙØªØŽØ¹ØšÙØ©
+
+HTMLPlugin.description_tags:ØªÙØ³ÙÙ
+ Ø§ÙÙØ«ÙÙØ© Ø¥ÙÙ Ø£ÙØ³Ø§Ù
+ ÙØ±Ø¹ÙØ© Ø¹ÙØ¯ Ù
+ÙØ§Ù Ø¹ÙØ§Ù
+Ø© <Section>. ØšÙÙÙ
+Ø§ Ø¥Ø°Ø§ ÙÙ ÙÙÙÙ ÙÙØ§Ù Ø£Ù ØªØ£Ø«ÙØ± ÙÙ ÙØªØš '-keep_head' .  
+
+HTMLPlugin.extract_style:Ø¥Ø³ØªØ®ÙØ§Øµ Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙÙØµ Ù Ø§ÙØ§Ø³ÙÙØš Ù
+Ù Ù
+Ù
+ÙØ² HTML <head> Ù Ø­ÙØž DocumentHeader ÙÙØ§ØµÙØ§Øª  
+
+HTMLPlugin.file_is_url:ÙØ¹ÙÙ Ø¥Ø°Ø§ ÙØ§ÙØª Ø£Ø³Ù
+Ø§Ø¡ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø¯Ø®ÙØ© Ø§ÙØªÙ ØªØŽÙÙ Ø¹ÙÙØ§Ù Ø§ÙÙ
+ÙØ§Ø±Ø¯ Ø§ÙÙ
+Ø­Ø¯ Ù
+ØµØ§Ø¯Ø± ÙØ«Ø§ØŠÙ Ø£ØµÙÙØ© Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù Ø¥Ø°Ø§ Ø§Ø³ØªØ®Ø¯Ù
+Øª Ø£Ø¯Ø§Ø© Ø¥ÙØ¹ÙØ§Ø³ ÙÙØš ÙØ¥Ø³ØªÙØ±Ø§Ø¯ ÙÙÙÙ Ø¯ÙÙÙ Ø§ÙØ¥Ø³ØªÙØ±Ø§Ø¯.  
+
+HTMLPlugin.hunt_creator_metadata:Ø§ÙØ¬Ø§Ø¯ Ø§ÙØšØ± ÙØ¯Ø± Ù
+Ù
+ÙÙ Ù
+Ù ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø¹ÙÙ Ø§ÙØªØ£ÙÙÙ ÙÙØ¶Ø¹Ù ÙÙ Ø­ÙÙ'Ø§ÙÙ
+ÙØŽØŠ'  
+
+HTMLPlugin.keep_head:ÙØ§ ØªØ²ÙØ­ Ø§ÙØ±Ø€ÙØ³ Ù
+Ù Ù
+ÙÙØ§Øª Ø§ÙÙØµÙØµ Ø§ÙØªØŽØ¹ØšÙØ©.
+
+HTMLPlugin.metadata_fields:ÙØ§ØŠÙ
+Ø© Ø­ÙÙÙ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª Ù
+ÙØµÙÙØ© ØšÙØ§ØµÙØ© ÙÙ
+Ø­Ø§ÙÙØ© Ø¥Ø³ØªØ®ÙØ§Øµ. ØªØ³Ù
+Ø­ ÙÙÙ
+Ø³ØªØ®Ø¯Ù
+ÙÙ ØšØªØ¹Ø±ÙÙ ÙØ§ØŠÙ
+Ø© Ù
+ÙØµÙÙØ© ØšÙØ§ØµÙØ© ÙØ­ÙÙÙ ÙØ§ØµÙØ§Øª
+
+HTMLPlugin.no_metadata:ÙØ§ ØªØ­Ø§ÙÙ Ø¥Ø³ØªØ®ÙØ§Øµ Ø¢Ù ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª Ù
+Ù Ø§ÙÙ
+ÙÙØ§Øª.
+
+HTMLPlugin.no_strip_metadata_html:ÙØ§ØŠÙ
+Ø© Ù
+ÙØµÙÙØ© ØšÙØ§ØµÙØ©  
+
+HTMLPlugin.nolinks:ÙØ§ ØªØšØ°Ù Ø§Ù Ù
+Ø­Ø§ÙÙØ© ÙÙ
+ØµÙØ¯Ø© Ø±ÙØ§ØšØ· ((ÙØ¶Ø¹ ÙØ°Ø§ Ø§ÙØ¹ÙÙ
+ ÙØ¯ ÙØ­Ø³Ù Ø³Ø±Ø¹Ø© ØšÙØ§Ø¡ / Ø§Ø³ØªÙØ±Ø§Ø¯ Ø§Ù ÙØ±ÙØš ÙÙÙÙ Ø§ÙØ±ÙØ§ØšØ· Ø¯Ø§Ø®Ù Ø³ØªÙÙÙ Ø§ÙÙØ«Ø§ØŠÙ Ù
+ÙØ³ÙØ±Ù).  
+
+HTMLPlugin.no_image_links:ÙØ§ ØªØšØ°Ù Ø£Ù Ù
+Ø­Ø§ÙÙØ© ÙØ¥ÙØªÙØ§Øµ  Ø±ÙØ§ØšØ· ØµÙØ±Ø©  ÙÙØ³Ù
+Ø§Ø­ ØšÙ
+ØŽØ§ÙØ¯Ø© Ø§ÙØµÙØ±.  
+
+HTMLPlugin.rename_assoc_files:Ø¥Ø¹Ø§Ø¯Ø© ØªØ³Ù
+ÙØ© Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+ÙØ­ÙØ© ØšØ§ÙÙØ«Ø§ØŠÙ (Ù
+Ø«Ø§ÙØØµÙØ±). Ø£ÙØ¶Ø§ Ø£ÙØŽØŠ ÙÙÙÙ Ø£Ø¯ÙØ© Ø¶Ø­Ù (Ù
+ÙÙØ¯ ÙÙÙ
+Ø§ ÙØªØ¹ÙÙ ØšØ¥ÙØŽØ§Ø¡ Ù
+Ø¬Ù
+ÙØ¹Ø§Øª
+
+HTMLPlugin.sectionalise_using_h_tags:ØªÙÙØ§ØŠÙØ§ Ø£ÙØŽØŠ ÙØ«ÙÙØ© Ù
+Ø¬Ø²Ø§Ø© ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ù
+Ù
+ÙØ²Ø§Øª  h1, h2, ... hX .  
+
+HTMLPlugin.title_sub:Ø¥Ø³ØªØšØ¯Ø§Ù Ø§ÙØªØ¹ØšÙØ± ÙØªØ¹Ø¯ÙÙ Ø³ÙØ³ÙØ© ÙØµÙØ© Ù
+Ø®Ø²ÙØ© ÙØ¹ÙÙØ§Ù. ØªØ³ØªØ®Ø¯Ù
+ Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§ÙØ ØšÙØ§Ø³Ø·Ø©  Ù
+ÙØ§ØšØ³ PDFPlug ÙØ¥Ø²Ø§Ø­Ø© "ØµÙØ­Ø© 1" Ø§ÙØ® Ù
+Ù ÙØµ Ù
+Ø³ØªØ®Ø¯Ù
+ ÙØ¹ÙÙØ§Ù.  
+
+HTMLPlugin.tidy_html:Ø¥Ø°Ø§ ØªÙ
+ ØªØ¹ÙÙÙØ§ØØªÙÙÙ
+ ØšØªØ­ÙÙÙ ÙØ«ÙÙØ© HTML Ø¥ÙÙ ÙÙØŠØ© XHTML Ø¬ÙØ¯Ø© Ø§ÙØ¥Ø¹Ø¯Ø§Ø¯. ØªÙ
+ÙÙ Ø§ÙÙ
+Ø³ØªÙÙØ¯ÙÙ Ù
+Ù Ø¹Ø±Ø¶ Ø§ÙÙØ«ÙÙØ© ÙÙ ÙÙØŠØ© ÙØªØ§Øš  
+
+HTMLPlugin.old_style_HDL:ÙØªØ­Ø¯ÙØ¯ Ù
+Ø§ Ø¥Ø°Ø§ ÙØ§Ù Ø§ÙÙ
+ÙÙ ÙÙ ÙØ°Ù Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ù
+ÙØ³Ù
+ ØšØ¥Ø³ØªØ®Ø¯Ø§Ù
+ Ø§Ø³ÙÙØš ÙØ³Ù
+ HDL Ø§ÙÙØ¯ÙÙ
+.  
+
+BaseMediaConverter.enable_cache:ÙØ¶Ø¹ Ø§ÙØµÙØ± Ø§ÙÙ
+ØµØºØ±Ø© ÙØ¹Ø±Ø¶ Ø§ÙØŽØ§ØŽØ© ÙÙ Ø°Ø§ÙØ±Ø© Ø§ÙØªØ®Ø²ÙÙ Ø§ÙÙ
+Ø€ÙØª Ø­ØªÙ ÙØ§ ØªØ­ØªØ§Ø¬ Ø¥ÙÙ ØªÙÙÙØ¯ÙØ§ Ù
+Ø±Ø§Ø±Ø§.  
+
+ImageConverter.converttotype:ØªØ­ÙÙÙ Ø§ÙØµÙØ±Ø© Ø§ÙØ£Ø³Ø§Ø³ÙØ© Ø§ÙÙ ÙÙØŠØ© 's'.
+
+ImageConverter.create_screenview:Ø§Ø°Ø§ ÙØ¶Ø¹Øª Ø§ÙÙÙÙ
+Ø© ØµØ­ÙØ­ ØØ³ÙÙ ØªÙØŽØŠ ØµÙØ±Ø© ØšØ­Ø¬Ù
+ Ø§ÙØŽØ§ØŽØ© Ù ØªØ¹Ø¯ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª  Ø ÙØ¶Ø¹ Ø§ÙØŽØ§ØŽØ© ØØ·ÙÙ Ø§ÙØŽØ§ØŽØ©ØØ§ÙÙÙÙØ© Ø§ÙØŽØ§ØŽØ©Ø Ù ÙÙØ¹ Ø§ÙØŽØ§ØŽØ© .  
+
+ImageConverter.create_thumbnail:Ø§Ø°Ø§ ÙØ¶Ø¹Øª Ø§ÙÙÙÙ
+Ø© ØµØ­ÙØ­ ØØ³ÙÙ ØªÙØŽØŠ Ù
+ØµØºØ±Ø© ÙÙÙ ØµÙØ±Ø©Ø Ù ØªØ¶ÙÙ Ù
+ØµØºØ±Ø© Ø ÙÙØ¹ Ø§ÙÙ
+ØµØºØ±Ø© ØØ§ÙÙÙÙØ© Ø§ÙÙ
+ØµØºØ±Ø©ØØ¹Ø±Ø¶ Ø§ÙÙ
+ØµØºØ±Ø©ØØ Ù Ø·ÙÙ Ø§ÙÙ
+ØµØºØ±Ø© .  
+ImageConverter.desc:ÙØ°Ø§ Ø§ÙÙ
+ÙØ§ØšØ³ ÙØ¹Ø§ÙØ¬ Ø§ÙØµÙØ±, Ø¥Ø¶Ø§ÙØ© ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙØ£Ø³Ø§Ø³ÙØ©
+
+ImageConverter.imagemagicknotinstalled:ÙÙ
+ ÙØªÙ
+ ØªØ«ØšÙØª  ImageMagick  
+
+ImageConverter.minimumsize:ØªØ¬Ø§ÙÙ Ø§ÙØµÙØ± Ø§ÙØ£ØµØºØ± Ù
+Ù  n ØšØ§ÙØª.
+
+ImageConverter.noconversionavailable:ØªØ­ÙÙÙ Ø§ÙØµÙØ±Ø© ØºÙØ± Ù
+ØªÙÙØ±  
+
+ImageConverter.noscaleup:ÙØ§ ØªÙÙØ³ Ø§ÙØµÙØ± Ø§ÙØµØºÙØ±Ø© Ø¹ÙØ¯ Ø¥ÙØŽØ§Ø¡ Ù
+Ø®ØªØµØ± ØµÙØ±  
+
+ImageConverter.screenviewsize:Ø¥ÙØŽØ§Ø¡ ØµÙØ± ØšÙ
+ØŽÙØ¯ ØŽØ§ØŽØ© ØšØ­Ø¬Ù
+ nxn.  
+
+ImageConverter.screenviewtype:'Ø§Ø³ØªØ®Ø¯Ø§Ù
+ ØµÙØ±Ø© Ø§ÙØŽØ§ØŽØ© ÙÙ Ø§ÙØªÙØ³ÙÙ '.  
+
+ImageConverter.thumbnailsize:Ø¥ÙØŽØ§Ø¡ Ù
+Ø®ØªØµØ± ØµÙØ±Ø© ØšØ­Ø¬Ù
+ nxn.  
+
+ImageConverter.thumbnailtype:Ø¥ÙØŽØ§Ø¡ Ù
+Ø®ØªØµØ± ØµÙØ±Ø© ÙÙ ÙÙØŠØ© 's'.  
+
+ImageConverter.win95notsupported:ImageMagick ØºÙØ± Ù
+Ø¯Ø¹ÙÙ
+ ÙÙ ØšÙØŠØ© Win95/98  
+
+ImagePlugin.desc:ÙØ°Ø§ Ø§ÙÙ
+ÙØ§ØšØ³ ÙØ¹Ø§ÙØ¬ Ø§ÙØµÙØ±, Ø¥Ø¶Ø§ÙØ© ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙØ£Ø³Ø§Ø³ÙØ©
+
+IndexPlugin.desc:ÙØ°Ø§ Ù
+ÙØ§ØšØ³ ØºÙØ± Ù
+ØªÙØ±Ø± ÙØ¹Ø§ÙØ¬ Ù
+ÙÙ index.txt . Ù
+ÙÙ index.txt ÙØ¬Øš Ø§Ù ÙØªØ¶Ù
+Ù ÙØ§ØŠÙ
+Ø© ØšØ§ÙÙ
+ÙÙØ§Øª Ù Ø§ÙØªÙ Ø³ØªØ¯Ø±Ø¬ ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ù
+ØªØšÙØ¹Ø©
+
+ISISPlugin.desc:ÙØ¹Ø§ÙØ¬ ÙØ°Ø§ Ø§ÙÙ
+ÙØ§ØšØ³ ÙÙØ§Ø¹Ø¯ ØšÙØ§ÙØ§Øª  CDS/ISIS . Ø§Ù ÙØ§Ø¹Ø¯Ø© ØšÙØ§ÙØ§Øª ÙÙ CDS/ISIS Ù
+Ø¹Ø§ÙØ¬Ø© ØªØŽØªØ±Ø· ÙØ¬ÙØ¯ Ø«ÙØ§Ø«Ø© Ù
+ÙÙØ§Øª ÙÙ Ù
+Ø³Ø§Ø± Ø¥Ø³ØªÙØ±Ø§Ø¯ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ù ÙÙ Ø§ÙÙ
+ÙÙ Ø§ÙØ±ØŠÙØ³Ù (.mst), Ø¬Ø¯ÙÙ ØªØ¹Ø±ÙÙ Ø§ÙØ­ÙÙÙ (.fdt), Ù Ù
+ÙÙ Ø§ÙØ¥Ø­Ø§ÙØ§Øª Ø§ÙØšÙÙÙØ© (.xrf).
+
+ISISPlugin.subfield_separator:Ø§ÙÙ
+Ø­Ø±Ù Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙÙØµÙ Ø§ÙØ­ÙÙÙ Ø§ÙÙØ±Ø¹ÙØ© ÙÙ ØªØ³Ø¬ÙÙØ§Øª ÙÙØ§Ø¹Ø¯ ØšÙØ§ÙØ§Øª CDS/ISIS .
+
+ISISPlugin.entry_separator:Ø§ÙÙ
+Ø­Ø±Ù Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙÙØµÙ Ø§ÙÙÙÙ
+ Ø§ÙÙ
+ØªØ¹Ø¯Ø¯Ø© ÙÙ Ø­ÙÙÙ Ø§ÙÙÙÙ
+Ø§Øª Ø§ÙÙ
+ÙØªØ§Ø­ÙØ© ÙÙ ØªØ³Ø¬ÙÙØ§Øª ÙÙØ§Ø¹Ø¯ ØšÙØ§ÙØ§Øª  CDS/ISIS .
+
+KeyphraseExtractor.desc:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙÙ
+Ø³Ø§Ø¹Ø¯ Ø§ÙÙ
+Ø³ØªØ®Ø±Ø¬  ÙØªÙÙÙØ¯ Ø¬Ù
+ÙØ© Ù
+ÙØªØ§Ø­ÙØ© Ù
+Ù Ø§ÙÙØµ. ÙÙØ³ØªØ®Ø¯Ù
+ ÙØžØ§Ù
+ Kea keyphrase ÙÙØ§Ø³ØªØ®Ø±Ø§Ø¬.  
+
+KeyphraseExtractor.extract_keyphrases:Ø¥Ø³ØªØ®ÙØ§Øµ Ø§ÙØ¬Ù
+Ù Ø§ÙÙ
+ÙØªØ§Ø­ÙØ© ØšÙØ§Ø³Ø·Ø© Kea (Ø¥Ø¹Ø¯Ø§Ø¯Ø§Øª Ø¥ÙØªØ±Ø§Ø¶ÙØ©).
+
+KeyphraseExtractor.extract_keyphrases_kea4:Ø¥Ø³ØªØ®ÙØ§Øµ ØªÙÙØ§ØŠÙ ÙÙØ¬Ù
+Ù Ø§ÙÙ
+ÙØªØ§Ø­ÙØ© ØšÙØ§Ø³Ø·Ø© Kea 4.0 (Ø¥Ø¹Ø¯Ø§Ø¯Ø§Øª Ø¥ÙØªØ±Ø§Ø¶ÙØ©). Kea 4.0 Ù ÙÙ Ø¥ØµØ¯Ø§Ø±Ø© Ø¬Ø¯ÙØ¯Ø© ØªÙ
+ ØªØ·ÙÙØ±ÙØ§ ÙÙØªÙØŽÙÙ Ø§ÙÙ
+Ø¶ØšÙØ· ÙÙÙØ«Ø§ØŠÙ ÙÙ ÙØ·Ø§Ù Ø§ÙØ²Ø±Ø§Ø¹Ø©.
+
+KeyphraseExtractor.extract_keyphrase_options:ÙÙÙØ± Kea Ø®ÙØ§Ø±Ø§Øª ÙØ¥Ø³ØªØ®ÙØ§Øµ Ø§ÙØ¬Ù
+Ù Ø§ÙÙ
+ÙØªØ§Ø­ÙØ©.Ù
+Ø«Ø§Ù: mALIWEB - Ø¥Ø³ØªØ®Ø¯Ù
+ ÙÙ
+ÙØ°Ø¬ Ø¥Ø³ØªØ®ÙØ§Øµ  ALIWEB ; n5 - Ø¥Ø³ØªØ®ÙØ§Øµ  5 Ø¬Ù
+Ù Ù
+ÙØªØ§Ø­ÙØ©;, eGBK - Ø¥Ø³ØªØ®Ø¯Ù
+ ØªØ±Ù
+ÙØ²  GBK .
+
+KeyphraseExtractor.keyphrases:Ø¬Ù
+Ù Ù
+ÙØªØ§Ø­ÙØ©
+
+KeyphraseExtractor.missing_kea:Ø®Ø·Ø£: ÙÙ
+ ÙØªÙ
+ Ø§ÙØ¹Ø«ÙØ± Ø¹ÙÙ ØšØ±Ø§Ù
+Ø¬ Kea ÙÙ %s. Ø§ÙØ±Ø¬Ø§Ø¡ ØªÙØ²ÙÙ  Kea %s Ù
+Ù http://www.nzdl.org/Kea ÙØªØ«ØšÙØªÙ ÙÙ ÙØ°Ø§ Ø§ÙÙ
+Ø³Ø§Ø±.
+
+LaTeXPlugin.desc:Ù
+ÙØ§ØšØ³ ÙÙ
+Ø¹Ø§ÙØ¬Ø© ÙØ«Ø§ØŠÙ LaTeX .
+
+LOMPlugin.desc:Ù
+ÙØ§ØšØ³ ÙØ¥Ø³ØªÙØ±Ø§Ø¯ Ù
+ÙÙØ§Øª LOM (ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙÙØ§ÙØ§Øª Ø§ÙØªØ¹ÙÙ
+) .  
+
+LOMPlugin.root_tag:DocType ÙÙ
+ÙÙØ§Øª XML  (Ø£Ù ØªØ¹ØšÙØ± Ù
+ÙØªØžÙ
+ ÙØªØ·Ø§ØšÙ Ù
+Ø¹ Ø¬Ø°Ø± Ø§ÙØ¹ÙØµØ±).  
+
+LOMPlugin.check_timestamp:Ø§ÙØ­Øµ ØªÙØ§Ø±ÙØ® Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+ÙØ²ÙØ© Ø³Ø§ØšÙØ§Ø ÙÙÙ
+ ØšØªÙØ²ÙÙ Ø§ÙÙ
+ÙÙ Ø§ÙØ£Ø­Ø¯Ø« ÙÙØ·.  
+
+LOMPlugin.download_srcdocs:ØªÙØ²ÙÙ Ù
+ØµØ¯Ø± Ø§ÙÙØ«ÙÙØ© Ø¥Ø°Ø§ ØªÙ
+ ØªØ­Ø¯ÙØ¯ ÙØ§Ø­Ø¯ (in general^identifier^entry or
+
+MARCPlugin.desc:Ù
+ÙØ§ØšØ³ Ù
+Ø§Ø±Ù Ø§Ø³Ø§Ø³Ù.
+
+MARCPlugin.metadata_mapping:Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙ Ø§ÙØ°Ù ÙØ¶Ù
+ ØªÙØ§ØµÙÙ Ø§ÙØ®Ø±Ø§ØŠØ· ÙÙÙÙ
+ Ù
+Ø§Ø±Ù Ø§ÙÙ Ø£Ø³Ù
+Ø§Ø¡ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙÙ
+
+MARCXMLPlugin.desc:MARCXML plugin.  
+
+MARCXMLPlugin.metadata_mapping_file:Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙ Ø§ÙØ°Ù ÙØ¶Ù
+ ØªÙØ§ØµÙÙ Ø§ÙØ®Ø±Ø§ØŠØ· ÙÙÙÙ
+ Ù
+Ø§Ø±Ù Ø§ÙÙ Ø§Ø³Ù
+Ø§Ø¡ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙÙ ÙØ±ÙÙØ³ØªÙÙ.Ø§ÙØªØ±Ø§Ø¶ÙØ§ Ø¥ÙÙ  
+
+MediaWikiPlugin.desc:Ù
+ÙØ§ØšØ³ ÙØ§Ø³ØªÙØ±Ø§Ø¯ ØµÙØ­Ø§Øª Ø§ÙÙÙØš ÙÙ MediaWiki  
+
+MediaWikiPlugin.show_toc:Ø£Ø¶Ù Ø§ÙÙ ØµÙØ­Ø© Ø­ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© 'Ø¬Ø¯ÙÙ Ø§ÙÙ
+Ø­ØªÙÙØ§Øª' ÙÙ Ø§ÙØµÙØ© Ø§ÙØ±ØŠÙØ³Ø© ÙÙ
+ÙÙØ¹ MediaWiki .
+
+MediaWikiPlugin.delete_toc:Ø­Ø°Ù ÙØ³Ù
+ 'Ø¬Ø¯ÙÙ Ø§ÙÙ
+Ø­ØªÙÙØ§Øª' ÙÙ ÙÙ ØµÙØ­Ø© HTML . ØªØ­ØªØ§Ø¬ ÙØªØ­Ø¯ÙØ¯ ØªØ¹ØšÙØ± Ù
+ÙØªØžÙ
+  ÙÙ Perl ÙÙ toc_exp Ø£Ø¯ÙØ§Ù
+
+MediaWikiPlugin.toc_exp:ØªØ¹ØšÙØ± Ù
+ÙØªØžÙ
+ ÙÙ Perl ÙÙ
+Ø·Ø§ØšÙØ© 'Ø¬Ø¯ÙÙ Ø§ÙÙ
+Ø­ØªÙÙØ§Øª'. Ø§ÙÙÙÙ
+Ø© Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ© ØªØ·Ø§ØšÙ ØµÙØ­Ø§Øª Ø§ÙÙÙØš Ø§ÙØ¹Ø§Ù
+Ø©
+
+MediaWikiPlugin.delete_nav:Ø­Ø°Ù ÙØ³Ù
+ Ø§ÙØªØ¬ÙØ§Ù . ØªØ­ØªØ§Ø¬ ÙØªØ­Ø¯ÙØ¯ ØªØ¹ØšÙØ± Ù
+ÙØªØžÙ
+ ÙÙ Perl ÙÙ nav_div_exp Ø§Ø¯ÙØ§Ù.  
+
+MediaWikiPlugin.nav_div_exp:ØªØ¹ØšÙØ± Ù
+ÙØªØžÙ
+ ÙÙ Perl ÙÙ
+Ø·Ø§ØšÙØ© ÙØ³Ù
+ Ø§ÙØªØ¬ÙØ§Ù. Ø§ÙÙÙÙ
+Ø© Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ© ØªØ·Ø§ØšÙ ØµÙØ­Ø§Øª Ø§ÙÙÙØš Ø§ÙØ¹Ø§Ù
+Ø© MediaWikiÙÙ  
+
+MediaWikiPlugin.delete_searchbox:Ø§Ø­Ø°Ù Ø§ÙÙØ³Ù
+ Ø§ÙØ®Ø§Øµ ØšÙ
+Ø±ØšØ¹ Ø§ÙØšØ­Ø«. ÙØ­ØªØ§Ø¬ Ø¥ÙÙ ØªØ­Ø¯ÙØ¯ ØšØ±Ù
+Ø¬Ø© Perl ÙÙ searchbox_div_exp ØšØ£Ø³ÙÙ.  
+
+MediaWikiPlugin.searchbox_div_exp:ØªØ¹ØšÙØ± ÙØºØ© Perl Ù
+Ø¹Ø±ÙÙ ÙÙÙ ÙØ¶Ø§ÙÙ Ù
+Ø±ØšØ¹ Ø§ÙØšØ­Ø«. Ø§ÙÙÙÙ
+Ø© Ø§ÙØªÙÙØ§ØŠÙØ© ØªØ¶Ø§ÙÙ ØµÙØ­Ø§Øª MediaWiki Ø§ÙÙ
+Ø¹ØªØ§Ø¯Ø©.  
+
+MediaWikiPlugin.remove_title_suffix_exp:ØªØ¹ØšÙØ± Ù
+ÙØªØžÙ
+ ÙÙ Perl ÙØªÙÙÙÙ
+ Ø§ÙØ¹ÙÙØ§Ù Ø§ÙÙ
+Ø³ØªØ®Ø±Ø¬. Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§ÙØ \\s-(.+) Ø³ÙÙ
+
+MetadataCSVPlugin.desc:Ù
+ÙØ§ØšØ³ ÙÙØ§ØŠÙ
+Ø© Ù
+ÙØµÙÙØ© ØšÙØ§ØµÙØ© ÙÙÙÙ
+ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª .Ø­ÙÙ Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙ ÙÙ Ù
+ÙÙ CSV ÙÙØ­Ø¯Ø¯ Ø§ÙÙ Ø£Ù ÙØ«ÙÙØ© ØªÙØªÙ
+Ù ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª.  
+
+MetadataPass.desc:ØšØ¬Ø§ÙØš Ø§ÙÙØŠØ© Ø§ÙØ£Ø³Ø§Ø³ ÙÙ BasPlug Ø§ÙØ°Ù ÙØ¯Ø¹Ù
+ Ø¥Ø³ØªØ®Ø¯Ø§Ù
+ Ù
+ÙØ§ØšØ³ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª ÙØªÙ
+Ø±ÙØ± metadata_read ÙÙ import.pl  
+
+MetadataXMLPlugin.desc:Ù
+ÙØ§ØšØ³ ÙØ¹Ø§ÙØ¬  Ù
+ÙÙØ§Øª metadata.xml .  
+
+MetadataEXIFPlugin.desc:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙØ°Ù ÙØ³ØªØ®Ø±Ø¬ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª EXIF Ù
+Ù Ø§ÙØµÙØ± ØÙ Ø§ÙØµÙØª Ù Ø§ÙÙÙØ¯ÙÙ  . ØšØŽÙÙ Ø£ÙØ«Ø± ØªØ­Ø¯ÙØ¯Ø§ Ø ÙØ£ÙÙ ÙÙÙÙ
+ Ø¹ÙÙ ÙØ­Ø¯Ø© CPAN 'ExifTool'. ÙÙØ¯Ø¹Ù
+ ÙØ°Ø§ Ø§ÙØ¹Ø¯ÙØ¯ Ù
+Ù Ø§ÙØ£ØŽÙØ§Ù Ø Ø«Ù
+ ÙØŽÙØ± Ø¥ÙÙ Ø§Ø³Ù
+ (Ù
+Ø«Ù GPS, XMP, FlashPix, ID3, VorbisØ ). Ù ÙØ³ØªÙÙØ¯ Ø§ÙÙ
+ÙØ§ØšØ³ Ù
+Ù ÙØ°Ø§  Ø Ù ÙØ¯ ØªÙ
+ ØªØµÙ
+ÙÙ
+Ù ÙØ¯Ø¹Ù
+ Ø§ÙØ§ØŽÙØ§Ù Ø§ÙØªÙ ÙØ¯Ø¹Ù
+ÙØ§  ExifTool. Ø§ÙØžØ± ÙØ«Ø§ØŠÙ ExifTool ÙØ£ÙÙØ§Ø¹ Ø§ÙÙ
+ÙÙØ§Øª ÙØ¯Ø¹Ù
+ Ù
+Ø®Ø·Ø·Ø§Øª ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª.  
+
+GreenstoneMETSPlugin.desc:Ù
+Ø¹Ø§ÙØ¬Ø© ÙØ«Ø§ØŠÙ METS ØšØ§Ø³ÙÙØš ÙØ±ÙÙØ³ØªÙÙ.  
+
+MP3Plugin.desc:Ù
+ÙØ§ØšØ³ ÙÙ
+Ø¹Ø§ÙØ¬Ø© Ù
+ÙÙØ§Øª MP3 .
+
+MP3Plugin.assoc_images:ØšÙ
+Ø­Ø¯Ø¯ Ø¹ÙÙØ§Ù ID3 Ù ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª Ø§ÙÙ
+Ø€Ø¯ÙMP3 Ø§Ø³ØªØ®Ø¯Ù
+ Ù
+Ø­Ø±Ù Ø§ÙØšØ­Ø« Ø¬ÙØ¬Ù ÙÙØµÙØ± ÙØªØ­Ø¯ÙØ¯ Ø§ÙØµÙØ± Ø§ÙÙ
+Ø±ØªØšØ·Ø© Ù
+Ø¹ Ù
+ÙÙ  
+
+MP3Plugin.applet_metadata:[applet] ÙØªØ®Ø²ÙÙ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙÙÙ ÙØ«ÙÙØ© ØªØ­ØªÙÙ Ø¹ÙÙ ÙØ¯Ø± Ù
+Ø·ÙÙØš Ù
+Ù HTML ÙØªØŽØºÙÙ ØšØ±ÙØ§Ù
+Ø¬  
+
+MP3Plugin.metadata_fields:ÙØ§ØŠÙ
+Ø©ØšØ­ÙÙÙ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ Ù
+ÙØµÙÙØ© ØšØ¹ÙØ§Ù
+Ø© ÙØ§ØµÙØ© (Ø). Ø§Ø³ØªØ®Ø¯Ù
+ "\*"\ ÙØ§Ø³ØªØ±Ø¬Ø§Ø¹ ÙØ§ÙØ© Ø§ÙØ­ÙÙÙ.  
+
+NulPlugin.desc:Ù
+ÙØ§ØšØ³ Ù
+ÙÙ (.nul) Ø§ÙÙÙÙ
+Ù. ÙØ³ØªØ®Ø¯Ù
+ Ù
+Ø¹ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØªÙ ØªÙØªØ¬ ØšØªÙ
+Ø¯ÙØ¯ Ù
+ÙÙØ§Øª ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙØ§Ø¹Ø¯Ø© ØšÙØ§ÙØ§Øª.  
+
+NulPlugin.assoc_field:Ø¥Ø³Ù
+ Ø­ÙÙ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ù Ø§ÙØ°Ù Ø³ÙÙ ÙØªÙ
+ ØªØ®ØµÙØµØ© ÙÙ
+ÙÙ nul  
+NulPlugin.add_metadata_as_text:Ø¶Ø¹ Ø¬Ø¯ÙÙ ÙÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ ÙÙ ÙØµ Ø§ÙÙØ«ÙÙØ©Ø Ø¥ÙØ§ Ø¥Ø°Ø§ ÙØ§ÙØª ÙØ°Ù Ø§ÙÙØ«ÙÙØ© ÙÙØ³Øª ÙØµÙØ©.  
+
+NulPlugin.remove_namespace_for_text:Ø­Ø°Ù Ø§Ø³Ù
+ Ø§ÙÙ
+Ø³Ø§Ø­Ø© Ù
+Ù Ø§Ø³Ù
+Ø§Ø¡ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª ÙÙ ÙØµ ÙØ«ÙÙØ©  (Ø¥Ø°Ø§ ØªÙ
+ ØªØ¹ÙÙ add_metadata_as_text ).  
+
+OAIPlugin.desc:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙØ£Ø³Ø§Ø³Ù ÙÙ
+ØšØ§Ø¯Ø±Ø© Ø§ÙØ£Ø±ØŽÙÙ Ø§ÙÙ
+ÙØªÙØ­ (OAI) .
+
+OAIPlugin.document_field:Ø¹ÙØµØ± ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙØ°Ù ÙØ­Ø¯Ø¯ Ø§Ø³Ù
+ Ù
+ÙÙ Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØ°Ù ØªÙØ­Ù ØšÙ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª.  
+
+OAIPlugin.metadata_set:Ù
+Ø¹ÙØ§Ø± ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª (ØšØ§Ø¯ØŠØ© Ø¥Ø³Ù
+ Ù
+Ø³Ø§Ø­Ø©) ÙØ¥Ø³ØªÙØ±Ø§Ø¯ ÙÙ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª ÙÙÙØ§ Ù  
+OAIPlugin.metadata_set.auto:Ø£Ø³ØªØ®Ø¯Ù
+ Ø§ÙØšØ§Ø¯ØŠØ§Øª Ø§ÙÙ
+Ø®ØµØµØ© ÙÙ ØªØ³Ø¬ÙÙØ© OAI  
+OAIPlugin.metadata_set.dc:"Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø§ÙØšØ§Ø¯ØŠØ© dc. Ø³ÙÙ ÙØ®Ø·Ø· Ø¹ÙØ§ØµØ± ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª Ù
+Ø¹ÙØ§Ø± Ø¯ØšÙÙ ÙÙØ± Ø§ÙÙ
+Ø¹Ø¯Ù ÙÙ ØŽÙÙ Ø¬Ø±ÙÙØ³ØªÙÙØØ¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù Ø³ÙÙ ØªØµØšØ­ Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙÙ
+ÙØ§ÙÙØ© dc.Ø§ÙØªØºØ·ÙØ©^Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙÙ
+ÙØ§ÙÙØ©"
+
+  
+
+OggVorbisPlugin.add_technical_metadata:Ø¥Ø¶Ø§ÙØ© ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙÙÙØ© (Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù (eg. bitrate)  
+
+OggVorbisPlugin.desc:ØšØ±ÙØ§Ù
+Ø¬ ÙØªØµØ¯ÙØ± Ù
+ÙÙØ§Øª Ø§ÙØµÙØª Ù
+Ù ÙÙØ¹ Ogg Vorbis.  
+
+OpenDocumentPlugin.desc:Ù
+ÙØ§ØšØ³ ÙÙØ«Ø§ØŠÙ ÙÙ ÙÙØŠØ© OASIS OpenDocument (ØªØ³ØªØ®Ø¯Ù
+ ÙÙ OpenOffice 2.0)  
+
+PagedImagePlugin.desc:Ø§ÙØšØ±ÙØ§Ù
+Ø¬ Ø§ÙÙ
+Ø³Ø§Ø¹Ø¯ ÙÙØ­ØµÙÙ Ø¹ÙÙ ÙØ«Ø§ØŠÙ ØªØªÙÙÙ Ù
+Ù Ø³ÙØ³ÙØ© Ù
+Ù Ø§ÙØµÙØ± Ø Ù
+Ø¹ Ø±Ù
+ÙØ² Ø§ÙÙØµ Ø§ÙØ§Ø®ØªÙØ§Ø±Ù ÙÙÙ ØµÙØ±Ø©. ÙØ°Ø§ Ø§ÙØšØ±ÙØ§Ù
+Ø¬ Ø§ÙÙ
+Ø³Ø§Ø¹Ø¯ Ø§ÙØ¹Ù
+ÙÙØ§Øª.
+
+PagedImagePlugin.documenttype:Ø­Ø¯Ø¯ ÙÙØ¹ Ø§ÙÙØ«ÙÙØ© (ØªØ³ØªØ®Ø¯Ù
+ ÙÙØ¹Ø±Ø¶)  
+
+PagedImagePlugin.documenttype.paged:ØµÙØ­Ø§Øª Ø§ÙÙØ«Ø§ØŠÙ ØšÙØ§ Ø£Ø³ÙÙ
+ ØªØ§ÙÙ Ù ÙØšÙ Ù Ù
+Ø±ØšØ¹  'Ø¥ÙÙ ØµÙØ­Ø© X'  
+
+PagedImagePlugin.documenttype.hierarchy:Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙÙØ±Ù
+ÙØ© ØªØªØ¶Ù
+Ù ÙØ§ØŠÙ
+Ø© Ù
+Ø­ØªÙÙØ§Øª.  
+
+PagedImagePlugin.headerpage:Ø§Ø¶Ù ÙØ±Ù
+ ØªØ±Ù ÙØ³Ù Ø§ÙØµÙØ­Ø© (Ø§ÙØªÙ ÙØ§ ØªØ­ØªÙÙ Ø¹ÙÙ ØµÙØ±Ø©) ÙÙÙ ÙØ«ÙÙØ©.  
+
+PDFPlugin.allowimagesonly:Ø§Ø³Ù
+Ø­ ÙÙÙ
+ÙÙØ§Øª Ù
+Ù ÙÙØ¹ PDF. ØªØ¬ÙØš Ø§ÙØ­Ø§Ø¬Ø© Ø¥ÙÙ Ø£Ù ØªÙÙÙ Ù
+Ø¬Ù
+ÙØ¹Ø© Ù
+Ø¹ÙØ¯Ø©. ÙÙØ· useful with convert_to html .  
+
+PDFPlugin.complex:Ø¥ÙØŽØ§Ø¡ ÙØ§ØªØ¬ Ø£ÙØ«Ø± ØªØ¹ÙÙØ¯Ø§. Ù
+Ø¹ ÙØ°Ø§ Ø§ÙØ®ÙØ§Ø± Ø­Ø¯Ø¯ ÙØ§ØªØ¬ html Ø³ÙØšØ¯Ù Ø£ÙØ«Ø± ØŽØšÙØ§ ÙÙ
+ÙÙ PDF Ø§ÙØ£ØµÙÙ. ÙÙÙ ÙØ¹Ù
+Ù ÙØ°Ø§ ØšØŽÙÙ ØµØ­ÙØ­ ÙØ¬Øš ØªØ«ØšÙØª
+
+PDFPlugin.desc:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙØ°Ù ÙØ¹Ø§ÙØ¬ ÙØ«Ø§ØŠÙ PDF .  
+
+PDFPlugin.nohidden:ØªÙ
+ÙØ¹  pdftohtml Ù
+Ù Ù
+Ø­Ø§ÙÙØ© Ø¥Ø³ØªØ®ÙØ§Øµ ÙØµ Ù
+Ø®ÙÙ.ÙØ°Ø§ ÙÙÙØ¯ ÙÙØ· ÙÙ Ø­Ø§ÙØ© ØªØ¹ÙÙ Ø®ÙØ§Ø± -complex .  
+
+PDFPlugin.noimages:ÙØ§ ØªØ­Ø§ÙÙ Ø£Ù ØªØ³ØªØ®ÙØµ Ø§ÙØµÙØ± Ù
+Ù Ù
+ÙÙØ§Øª PDF.  
+
+PDFPlugin.use_sections:Ø¥ÙØŽØ§Ø¡ ÙØ³Ù
+ Ù
+ÙÙØµÙ ÙØ¢Ù ØµÙØ­Ø© Ù
+Ù Ù
+ÙÙ PDF .  
+
+PDFPlugin.zoom:Ø§ÙØ¹Ø§Ù
+Ù Ø§ÙØ°Ù ÙØ³ØªØ®Ø¯Ù
+ ÙØªÙØšÙØ± ÙØ§ØªØ¬ PDF  (Ù ÙØ°Ø§ ÙÙÙØ¯ ÙÙØ· Ø¥Ø°Ø§ ØªÙ
+ ØªØ¹ÙÙ -complex ).  
+
+PostScriptPlugin.desc:ÙØ°Ø§ ÙÙ Ù
+Ø­ÙÙ ÙØµ\ "Ø§ÙØ±Ø¬Ù Ø§ÙÙÙÙØ± \" Ù
+Ùps. Ø§Ø°Ø§ ÙÙØª Ø¬Ø§Ø¯Ø© Ø Ø§ÙÙØžØ± ÙÙ Ø§Ø³ØªØ®Ø¯Ø§Ù
+ Ø­Ø²Ù
+Ø© Ø§ÙØ£Ù
+Ø± Ø§ÙØ±Ø³Ù
+Ù Ø ÙÙÙ Ù
+ØªØ§Ø­ ÙÙØªØ­Ù
+ÙÙ ÙÙ
+
+PostScriptPlugin.extract_date:Ø¥Ø³ØªØ®ÙØ§Øµ Ø§ÙØªØ§Ø±ÙØ® Ù
+Ù ØªØ±ÙÙØ³Ø© PS .
+
+PostScriptPlugin.extract_pages:Ø¥Ø³ØªØ®ÙØ§Øµ Ø§ÙØµÙØ­Ø§Øª Ù
+Ù ØªØ±ÙÙØ³Ø© PS .
+
+PostScriptPlugin.extract_title:Ø¥Ø³ØªØ®ÙØ§Øµ Ø§ÙØ¹ÙÙØ§Ù Ù
+Ù ØªØ±ÙÙØ³Ø© PS .
+
+PowerPointPlugin.desc:Ù
+ÙØ§ØšØ³ ÙØ¥Ø³ØªÙØ±Ø§Ø¯ Ù
+ÙÙØ§Øª Ù
+Ø§ÙÙØ±ÙØ³ÙÙØª ØšØ§ÙØ± ØšÙÙÙØª.
+
+PowerPointPlugin.windows_scripting:Ø§Ø³ØªØ®Ø¯Ù
+  MicroSoft Windows scripting technology (Visual Basic ØªØ·ØšÙÙØ§Øª) ÙØ¥ÙØ¬Ø§Ø¯ PPT Ù ØªØ­ÙÙÙ Ø§ÙÙØ«ÙÙØ© Ø§ÙÙ Ù
+Ø®ØªÙÙ ÙÙØŠØ§Øª Ø§ÙØµÙØ± (Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù JPEG,PNG,GIF) ØšØ¯ÙØ§ Ù
+Ù Ø§ÙØªØ¹ÙÙÙ Ø¹ÙÙ Ø§ÙØ­Ø²Ù
+Ø© Ø§ÙÙ
+ÙØªÙØ­Ø© Ø§ÙÙ
+ØµØ¯Ø±
+
+PrintInfo.bad_general_option:Ø§ÙÙ
+ÙØ§ØšØ³  %s ÙØ³ØªØ®Ø¯Ù
+ Ø®ÙØ§Ø± ØºÙØ± Ø³ÙÙÙ
+. Ø§ÙØ±Ø¬Ø§Ø¡ ÙØ­Øµ Ù
+ÙÙ Ø§ÙØªÙÙÙÙ collect.cfg .
+
+PrintInfo.desc:Ù
+Ø¹ØžÙ
+  Ø§ÙÙ
+ÙØ§ØšØ³ Ø ØªØ¹Ø§ÙØ¬ Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙØ·ØšØ§Ø¹Ø© (ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ pluginfo.pl) Ø ÙØ§ÙØªØ­ÙÙÙ Ù
+Ù Ø§ÙØ­Ø¬Ø¬  
+
+ProCitePlugin.desc:Ù
+ÙØ§ØšØ³ ÙÙ (Ù
+ØµØ¯Ø±Ø©) ProCite ÙÙØ§Ø¹Ø¯ ØšÙØ§ÙØ§Øª  
+
+ProCitePlugin.entry_separator:Ø§ÙØ³ÙØ³ÙØ© Ø§ÙØªÙ ØªØ³ØªØ®Ø¯Ù
+ ÙÙØµÙ Ø§ÙÙÙÙ
+ Ø§ÙÙ
+ØªØ¹Ø¯Ø¯Ø© ÙÙ Ø­ÙÙ ÙØ§ØµÙØ§Øª ØšÙØ§ÙØ§Øª ÙØ§Ø­Ø¯ ÙÙ ØªØ³Ø¬ÙÙØ§Øª ÙØ§Ø¹Ø¯Ø© ØšÙØ§ÙØ§Øª ProCite .  
+
+ReadTextFile.could_not_extract_encoding:ØªØ­Ø°ÙØ±: ÙØ§ ÙÙ
+ÙÙ Ø¥Ø³ØªØ®ÙØ§Øµ Ø§ÙØªØ±Ù
+ÙØ² Ù
+Ù %s - Ø§ÙÙÙÙ
+Ø© Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ© Ø¥ÙÙ %s
+
+ReadTextFile.could_not_extract_language:ØªØ­Ø°ÙØ±: ÙØ§ ÙÙ
+ÙÙ Ø¥Ø³ØªØ®ÙØ§Øµ Ø§ÙÙØºØ© Ù
+Ù %s - Ø¥ÙØªØ±Ø§Ø¶ÙØ§ Ø¥ÙÙ %s
+
+ReadTextFile.could_not_open_for_reading:ÙØ§ ÙÙ
+ÙÙ ÙØªØ­  %s ÙÙÙØ±Ø§Ø¡Ø©
+
+ReadTextFile.default_encoding:Ø¥Ø³ØªØ®Ø¯Ù
+ ÙØ°Ø§ Ø§ÙØªØ±Ù
+ÙØ² Ø¥Ø°Ø§ ØªÙ
+ ÙØ¶Ø¹  -input_encoding ÙÙ 'auto' Ø®ÙØ§Ø±Ø²Ù
+ÙØ© ÙØŠØ§Øª Ø§ÙÙØµ ÙÙ Ø¥Ø³ØªØ®ÙØ§Øµ Ø§ÙØªØ±Ù
+ÙØ² Ø£Ù Ø¥Ø³ØªØ®ÙØµØª ØªØ±Ù
+ÙØ² ØºÙØ± Ù
+Ø¯Ø¹ÙÙ
+ ÙÙ ÙØ±ÙÙØ³ØªÙÙ. ÙØ°Ø§ Ø§ÙØ®ÙØ§Ø± ÙÙ
+ÙÙ Ø£Ù ÙØ£Ø®Ø° ÙÙØ³ Ø§ÙÙÙÙ
+Ø© Ù
+Ø«Ù  -input_encoding.
+
+ReadTextFile.default_language:Ø¥Ø°Ø§ ÙØŽÙ ÙØ±ÙÙØ³ØªÙÙ ÙÙ ØªØ­Ø¯ÙØ¯ Ø¹ÙØµØ± ÙØ§ØµÙØ© ÙØºØ© Ø§ÙÙØ«ÙÙØ©Ø ÙØ³ØªØ®Ø¯Ù
+ ÙØ±ÙÙØ³ØªÙÙ Ø§ÙÙ
+Ø¶Ù
+ÙÙ Ø§ÙÙ
+Ø­Ø¯Ø¯ ÙÙØ§. Ø§ÙÙÙÙ
+Ø© Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ© ÙÙ 'en' (ÙÙÙØ§ ÙÙÙ
+ÙØ§ØµÙØ© Ø§ÙÙÙØ§Ø³ÙØ© Ø§ÙØ¯ÙÙÙØ© ÙØ±Ù
+ÙØ² Ø§ÙÙØºØ§ØªISO 639 Ø±Ù
+Ø² Ø§ÙÙØºØ© Ø§ÙØ¥ÙØ¬ÙÙØ²ÙØ© ÙÙ= en ). ØªØ¬Øš Ù
+ÙØ§Ø­ØžØ© Ø§ÙÙ Ø¥Ø°Ø§ ÙÙ
+ ØªØ£Ø®Ø°  -input_encoding ÙÙÙ
+Ø© 'auto' Ù ÙÙ
+ ÙØªÙ
+ ØªØ­Ø¯ÙØ¯ -extract_language , ØªØ£Ø®Ø° ÙÙ Ø§ÙÙØ«Ø§ØŠÙ ÙÙÙ
+Ø© ÙØ°Ø§ Ø§ÙÙ
+Ø¶Ù
+ÙÙ.
+
+ReadTextFile.desc:Ø§ÙÙ
+ÙØ§ØšØ³ Ø§ÙØ£Ø³Ø§Ø³ ÙÙÙ
+ÙÙØ§Øª Ø§ÙØªÙ ÙÙ ÙØµ Ø¹Ø§Ø¯Ù.  
+
+ReadTextFile.empty_file:ÙØ°Ø§ Ø§ÙÙ
+ÙÙ ÙØ§ ÙØªØ¶Ù
+Ù ÙØµ
+
+ReadTextFile.extract_language:Ø¹Ø±Ù ÙØºØ© Ø£Ù ÙØ«ÙÙØ©Ø Ù Ø£Ø¹Ø¯ ÙØ§ØµÙØ© ØšÙØ§ÙØ§Øª Ø§ÙÙØºØ©.ØªØ¬Øš Ù
+ÙØ§Ø­ØžØ© Ø£Ù ÙØ°Ø§ Ø§ÙØ¥Ø¬Ø±Ø§Ø¡ ÙØªÙ
+ ØªÙÙØ§ØŠÙØ§ Ø¥Ø°Ø§ ÙØ§Ù ÙØ¶Ø¹ -input_encoding ÙÙ  'auto'.
+
+ReadTextFile.file_has_no_text:Ø®Ø·Ø£: %s ÙØ§ ÙØªØ¶Ù
+Ù ÙØµ
+
+ReadTextFile.input_encoding:ØªØ±Ù
+ÙØ² Ù
+ØµØ§Ø¯Ø± Ø§ÙÙØ«Ø§ØŠÙ.Ø³ÙÙ ÙØªÙ
+ ØªØ­ÙÙÙ ÙØ°Ø§ Ø§ÙØªØ±Ù
+ÙØ² ÙÙÙØ«Ø§ØŠÙ Ø¥ÙÙ utf8 Ù ÙØ­ÙØž Ø¯Ø§Ø®ÙÙØ§8.
+
+ReadTextFile.input_encoding.auto:Ø§Ø³ØªØ®Ø¯Ù
+ Ø®ÙØ§Ø±Ø²Ù
+ÙØ© ØªØµÙÙÙ Ø§ÙÙØµ ÙÙØªÙ
+ Ø§ÙØªØ¹Ø±Ù Ø§ÙØªÙÙØ§ØŠÙ Ø¹ÙÙ ØªØ±Ù
+ÙØ² ÙÙ Ù
+ØµØ¯Ø± ÙØ«ÙÙØ©. Ù Ø³ÙÙÙÙ ÙØ°Ø§ Ø£ØšØ·Ø£
+
+ReadTextFile.read_denied:ØºÙØ± Ù
+Ø³Ù
+ÙØ­  
+
+ReadTextFile.separate_cjk:Ø£Ø­ØŽØ± Ù
+Ø³Ø§Ø­Ø§Øª ØšÙÙ Ù
+Ø­Ø§Ø±Ù Ø§ÙÙØºØ© Ø§ÙØµÙÙÙØ©/Ø§ÙÙØºØ© Ø§ÙÙØ§ØšØ§ÙÙØ©/Ø§ÙÙØºØ© Ø§ÙÙÙØ±ÙØ© ÙØ¬Ø¹Ù ÙÙ Ù
+Ø­Ø±Ù ÙÙÙ
+Ø©.Ø¥Ø³ØªØ®Ø¯Ù
+ Ø¥Ø°Ø§ ÙÙ
+ ÙÙÙ Ø§ÙÙØµ Ù
+Ø¬Ø²Ø£.
+
+ReadTextFile.unsupported_encoding:ØªØ­Ø°ÙØ±: %s ØªØšØ¯Ù ÙÙ ØªØ±Ù
+ÙØ² ØºÙØ± Ù
+Ø¯Ø¹ÙÙ
+ (%s) - Ø§Ø³ØªØ®Ø¯Ù
+ %s
+
+ReadTextFile.wrong_encoding:ØªØ­Ø°ÙØ±: %s ØªÙ
+Øª ÙØ±Ø§Ø¡ØªÙØ§ ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ ØªØ±Ù
+ÙØ² %s Ù ÙÙÙ ÙØšØ¯Ù Ø§Ù ØªØ±Ù
+ÙØ²ÙØ§ ÙÙ %s.  
+
+ReadXMLFile.desc:Ø§ÙÙØŠØ© Ø§ÙØ£Ø³Ø§Ø³ ÙÙ
+ÙØ§ØšØ³ XML  
+
+ReadXMLFile.xslt:ØªØ­ÙÙÙ Ø§ÙØ«ÙÙØ© Ø§ÙÙ
+Ø¯Ø®ÙØ© Ø§ÙÙ
+ØªØ·Ø§ØšÙØ© Ù
+Ø¹ XSLT ÙÙ Ø§ÙÙ
+ÙÙ Ø§ÙÙ
+Ø³Ù
+Ù .Ø§Ø³Ù
+ Ù
+ÙÙ ÙØ³ØšÙ ÙÙØªØ±Ø¶ Ø§Ù ÙÙÙÙ ÙÙ Ù
+Ø¬Ø§Ù Ù
+ÙÙ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø© Ø Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù
+
+RealMediaPlugin.desc:Ù
+ÙØ§ØšØ³ ÙÙ
+Ø¹Ø§ÙØ¬Ø© Ù
+ÙÙØ§Øª Real Media .
+
+ReferPlugin.desc:Ù
+ÙØ§ØšØ³ ReferPlug  ÙÙØ±Ø§Ø¡ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙØšÙØšÙÙÙØ¬Ø±Ø§ÙÙØ© ÙÙ ÙÙØŠØ© Refer  
+
+RogPlugin.desc:ÙÙØŽØŠ ÙØ«Ø§ØŠÙ Ù
+Ø³ØªÙÙ ÙØ§Ø­Ø¯ ØšØ³ÙØ· Ù
+Ù Ù
+ÙÙØ§Øª .rog Ø£Ù .mdb .  
+
+RTFPlugin.desc:Ù
+ÙØ§ØšØ³ ÙØ¥Ø³ØªÙØ±Ø§Ø¯ Ù
+ÙÙØ§Øª rtf.  
+
+SourceCodePlugin.desc:Ø¥Ø³Ù
+ Ù
+ÙÙ ÙØ³ØªØ®Ø¯Ù
+ Ø­Ø§ÙÙØ§ ÙØ¹ÙÙØ§Ù ( Ø¥Ø®ØªÙØ§Ø±ÙØ§ ÙÙÙØµ ØšØ¹Ø¶ Ø§ÙØšØ§Ø¯Ø¡Ù). Ø§ÙÙØºØ§Øª Ø§ÙØ­Ø§ÙÙØ©:\nÙØµ: READMEs/Makefiles\nC/C++   (Ø­Ø§ÙÙØ§ ÙØ³ØªØ®Ø±Ø¬ #ÙØªØ¶Ù
+Ù Ø­Ø§ÙØ© Ù C++ class decls)\nPerl    (Ø­Ø§ÙÙØ§ ÙÙØ· ØªÙØ¬Ø² ÙÙØµ)\nShell   (Ø­Ø§ÙÙØ§ ÙÙØ· ØªÙØ¬Ø² ÙÙØµ)
+
+SourceCodePlugin.remove_prefix:Ø­Ø°Ù ÙØ°Ø§ Ø§ÙÙÙ
+Ø· Ø§ÙØ±ÙØ§Ø¯Ù Ù
+Ù Ø¥Ø³Ù
+ Ù
+ÙÙ (Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù -remove_prefix /tmp/XX/src/). Ø§ÙÙÙÙ
+Ø© Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ© ÙÙ Ø­Ø°Ù ÙÙ Ø§ÙÙ
+Ø³Ø§Ø± Ù
+Ù Ø¥Ø³Ù
+ Ø§ÙÙ
+ÙÙ.  
+
+SplitTextFile.desc:ÙØ³ØªØ®Ø¯Ù
+ Ù
+ÙØ§ØšØ³ SplitPlug ÙØªÙØ³ÙÙ
+ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø¯Ø®ÙØ© Ø§ÙÙ ÙØ·Ø§Ø¹Ø§Øª ØªØ¹ÙØ¬ ØšØµÙØ±Ø© ÙØ±Ø¯ÙØ©. ÙØ¬Øš Ø§Ù ÙØ§ ÙØ³ØªØ¯Ø¹Ù  ÙØ°Ø§ Ø§ÙÙ
+ÙØ§ØšØ³ ØšØµÙØ±Ø© Ù
+ÙÙØ±Ø¯Ø© Ø ØšØ¯ÙØ§ Ø Ø¥Ø°Ø§
+
+SplitTextFile.split_exp:ØªØ¹ØšÙØ± Ù
+ÙØªØžÙ
+ ÙÙ perl ÙØªÙØ³ÙÙ
+ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø¯Ø®ÙØ© Ø§ÙÙ ÙØ·Ø§Ø¹Ø§Øª.  
+
+StructuredHTMLPlugin.desc:Ù
+ÙØ§ØšØ³ ÙØ¹Ù
+ÙÙØ© ÙÙÙÙØ© ÙØ«Ø§ØŠÙ HTML Ø Ù ØªÙØ³ÙÙ
+ÙØ§ Ø§ÙÙ Ø£ÙØ³Ø§Ù
+ Ø¹ÙÙ Ø§Ø³Ø§Ø³ Ø§Ø³ÙÙØš Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª.  
+
+StructuredHTMLPlugin.delete_toc:Ø­Ø°Ù Ø£Ù Ø¬Ø¯ÙÙ Ù
+Ø­ØªÙÙØ§Øª Ø ÙØ§ØŠÙ
+Ø© Ø£ØŽÙØ§Ù Ø§ÙØ® Ù
+Ù Ù
+ÙÙ HTML Ø§ÙÙ
+Ø­ÙÙ. ØªØ­Ø¯Ø¯ Ø§ÙØ£Ø³Ø§ÙÙØš ÙÙØ°Ø§ Ø§ÙØ¥Ø¬Ø±Ø§Ø¡ ÙÙ Ø®ÙØ§Ø±  
+
+StructuredHTMLPlugin.title_header:ÙÙ
+ÙÙ ÙÙÙ
+Ø³ØªØ®Ø¯Ù
+ ØªØ­Ø¯ÙØ¯ Ø£Ø³Ø§ÙÙØš ØªØ±ÙÙØ³Ø© Ø§ÙØ¹ÙÙØ§Ù  
+
+StructuredHTMLPlugin.level1_header:ÙÙ
+ÙÙ ÙÙÙ
+Ø³ØªØ®Ø¯Ù
+ ØªØ­Ø¯ÙØ¯ Ø£Ø³Ø§ÙÙØš ØªØ±ÙÙØ³Ø© Ø§ÙÙ
+Ø³ØªÙÙ Ø§ÙØ£ÙÙ ÙÙØ«ÙÙØ© HTML (Ù
+Ø³Ø§ÙÙ ÙÙ <h1>).  
+
+StructuredHTMLPlugin.level2_header:ÙÙ
+ÙÙ ÙÙÙ
+Ø³ØªØ®Ø¯Ù
+ ØªØ­Ø¯ÙØ¯ Ø£Ø³Ø§ÙÙØš ØªØ±ÙÙØ³Ø© Ø§ÙÙ
+Ø³ØªÙÙ Ø§ÙØ«Ø§ÙÙ ÙÙØ«ÙÙØ© HTML (Ù
+Ø³Ø§ÙÙ ÙÙ <h2>).  
+
+StructuredHTMLPlugin.level3_header:ÙÙ
+ÙÙ ÙÙÙ
+Ø³ØªØ®Ø¯Ù
+ ØªØ­Ø¯ÙØ¯ Ø£Ø³Ø§ÙÙØš ØªØ±ÙÙØ³Ø© Ø§ÙÙ
+Ø³ØªÙÙ Ø§ÙØ«Ø§ÙØ« ÙÙØ«ÙÙØ© HTML (Ù
+Ø³Ø§ÙÙ ÙÙ <h3>).  
+
+StructuredHTMLPlugin.toc_header:ÙÙ
+ÙÙ ÙÙÙ
+Ø³ØªØ®Ø¯Ù
+ ØªØ­Ø¯ÙØ¯ Ø£Ø³Ø§ÙÙØš ÙØ¬Ø¯ÙÙ Ø§ÙÙ
+Ø­ØªÙÙØ§Øª Ø ÙØ§ØŠÙ
+Ø© Ø§ÙØ£ØŽÙØ§Ù Ø§ÙØ®.ÙØ¥Ø²Ø§ÙØªÙØ§ Ø¹ÙØ¯ ØªØ­Ø¯ÙØ¯ delete_toc  
+
+TextPlugin.desc:ÙÙØŽÙØ¡ ÙØ«ÙÙØ© ØšØ³ÙØ·Ø© Ù
+Ù Ù
+Ø³ØªÙÙ ÙØ§Ø­Ø¯. ÙØ¶ÙÙ Ø­ÙÙ Ù
+ÙØªØ§Ø¯Ø§ØªØ§ Ø®Ø§Øµ ØšØ§ÙØ¹ÙÙØ§Ù ÙÙ Ø£ÙÙ Ø³Ø·Ø± Ù
+Ù Ø§ÙÙØµ (ØšØ·ÙÙ 100 Ø­Ø±Ù ØšØ­Ø¯ Ø£ÙØµÙ).  
+
+TextPlugin.title_sub:Ø¥Ø³ØªØšØ¯Ø§Ù Ø§ÙØªØ¹ØšÙØ± ÙØªØ¹Ø¯ÙÙ Ø³ÙØ³ÙØ© ÙØµÙØ© Ù
+Ø®Ø²ÙØ© ÙØ¹ÙÙØ§Ù. ØªØ³ØªØ®Ø¯Ù
+ Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§ÙØ ØšÙØ§Ø³Ø·Ø©  PSPlug ÙØ¥Ø²Ø§Ø­Ø© "ØµÙØ­Ø© 1"
+
+UnknownPlugin.assoc_field:Ø§Ø³Ù
+ Ø­ÙÙ Ù
+ÙØªØ§Ø¯Ø§ØªØ§ Ø§ÙØ°Ù Ø³ÙØ­Ù
+Ù Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+Ø±ØªØšØ·Ø©.  
+
+UnknownPlugin.desc:ÙØ°Ø§ Ù
+ÙØ§ØšØ³ ØšØ³ÙØ· ÙØ¥Ø³ØªÙØ±Ø§Ø¯ Ù
+ÙÙØ§Øª ÙÙ ÙÙØŠØ§Øª ÙØ§ ÙØ¹Ø±Ù ÙØ±ÙÙØ³ØªÙÙ Ø¹ÙÙØ§ ØŽÙØŠØ§..  ÙØªÙ
+ Ø¥ÙØŽØ§Ø¡ ÙØ«ÙÙØ© Ø®ÙØ§ÙÙØ© ÙÙÙ Ù
+ÙÙØ Ù Ø³ÙÙ ÙØªÙ
+ ØªÙ
+Ø±ÙØ± Ø§ÙÙ
+ÙÙ Ø§ÙÙ ÙØ±ÙÙØ³ØªÙÙ ÙÙ  \"associated file\" ÙÙÙØ«ÙÙØ©.  
+
+UnknownPlugin.file_format:ÙÙØ¹ Ø§ÙÙ
+ÙÙ (e.g. MPEG, MIDI, ...)
+
+UnknownPlugin.mime_type:ÙÙØ¹ Ø§ÙÙ
+ÙÙ (Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù image/gif).  
+
+UnknownPlugin.process_extension:Ù
+Ø¹Ø§ÙØ¬Ø© Ù
+ÙÙØ§Øª ØšÙÙØ³ Ø§Ù
+ØªØ¯Ø§Ø¯ ÙØ°Ø§ Ø§ÙÙ
+ÙÙ . ÙØ°Ø§ Ø§ÙØ®ÙØ§Ø± ÙØ¹ØªØšØ± ØšØ¯ÙÙØ§ ÙÙ  process_exp Ø§ÙØ°Ù ÙÙ Ø§Ø³ÙÙ Ø¹ÙØ¯Ø§ÙØ¥Ø³ØªØ®Ø¯Ø§Ù
+ Ù ÙÙÙ Ø£ÙÙ Ù
+Ø±ÙÙØ©.  
+
+UnknownPlugin.srcicon:Ø­Ø¯Ø¯ Ø§Ø³Ù
+ Ù
+Ø§ÙØ±Ù (ØšØ¯ÙÙ ØŽØ±Ø·Ø© Ø³ÙÙÙØ©) ÙØªØ³ØªØ®Ø¯Ù
+ÙØ§ Ù
+Ø¹ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ Ø§ÙÙ
+Ø­Ø¯Ø¯Ø©.  
+
+WordPlugin.desc:Ù
+ÙØ§ØšØ³ ÙØ¥Ø³ØªÙØ±Ø§Ø¯ Ù
+ÙÙØ§Øª .DOC.  
+
+WordPlugin.windows_scripting:Ø§Ø³ØªØ®Ø¯Ù
+  MicroSoft Windows scripting technology (Visual
+
+WordPlugin.metadata_fields:ÙØ§Ø³ØªØ±Ø¬Ø§Ø¹ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ Ù
+Ù ÙØ«ÙÙØ© HTML Ù
+Ø­ÙÙØ© ØšØšØ±ÙØ§Ù
+Ø¬ VB scripting. ØªØ³Ù
+Ø­ ÙÙÙ
+Ø³ØªØ®Ø¯Ù
+ ØšØªØ¹Ø±ÙÙ ÙØ§ØŠÙ
+Ø© Ø­ÙÙÙ Ø§ÙÙ
+ÙØªØ§Ø¯Ø§ØªØ§ Ø§ÙÙ
+ÙØµÙÙØ© ØšÙØ§ØµÙØ© ÙÙ
+Ø­Ø§ÙÙØ© Ø§Ø³ØªØ®ÙØ§ØµÙØ§. Ø§Ø³ØªØ®Ø¯Ù
+ 'tag<tagname>' ÙÙÙ
+Ø­ØªÙÙ Ø§ÙØ®Ø§Øµ ØšØ£ÙÙ <tagname>.  
+
+ZIPPlugin.desc:Ø§ÙØšØ±ÙØ§Ù
+Ø¬ Ø§ÙØ°Ù ÙØªØ¹Ø§Ù
+Ù Ù
+Ø¹ Ø§ÙÙ
+Ø¯Ø®ÙØ§Øª Ø§ÙÙ
+Ø¶ØºÙØ·Ø© Ø£Ù Ø§ÙÙ
+Ø€Ø±ØŽÙØ© ÙÙÙÙ
+ Ø­Ø§ÙÙØ§ ØšØ§ÙØªØ¹Ø§Ù
+Ù Ù
+Ø¹ Ø§ÙØ§Ù
+ØªØ¯Ø§Ø¯Ø§Øª :\ngzip (.gz, .z, .tgz, .taz)\nbzip (.bz)\nbzip2 (.bz2)\nzip (.zip .jar)\ntar (.tar)\n\n ÙÙØ°Ø§ Ø§ÙØšØ±ÙØ§Ù
+Ø¬ ÙØ¹ØªÙ
+Ø¯ Ø¹ÙÙ Ø§ÙÙ
+Ø±Ø§ÙÙ Ø§ÙØªØ§ÙÙØ© (ÙÙ Ø­Ø§ÙØ© Ù
+Ø­Ø§ÙÙØ© ØªØŽØºÙÙ ÙØžØ§Ù
+ Ø§ÙØ±Ø¯): \ngunzip (ÙÙgzip)\nbunzip (ÙÙbzip)\nbunzip2 \nunzip (ÙÙzip)\ntar (ÙÙtar)  
+
+#
+# Download module option descriptions
+#
+
+BaseDownload.desc:Ø§ÙÙØŠØ© Ø§ÙØ£Ø³Ø§Ø³ÙØ© ÙÙÙ
+Ø§Ø°Ø¬ Ø§ÙØªÙØ²ÙÙ
+BaseDownload.bad_general_option:ÙØ­Ø¯Ø©Ø§ÙØªÙØ²ÙÙ Ùª ØªØ³ØªØ®Ø¯Ù
+  Ø®ÙØ§Ø± ØºÙØ± ØµØ­ÙØ­.  
+MediaWikiDownload.desc:ØšØ±Ø§ÙØ§Ù
+Ø¬ ÙØ±Ø¹Ù ÙÙØªØ­Ù
+ÙÙ Ù
+Ù Ù
+ÙØ§ÙØ¹ MediaWiki  
+MediaWikiDownload.reject_filetype:ØªØ¬Ø§ÙÙ ÙØ§ØŠÙ
+Ø© urlØ Ø§ÙØµÙ ØšÙØ§ØµÙØ© (Ø)Ø Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù: *cgi-bin*,*.ppt ØªØ¹ÙÙ ØªØ¬Ø§ÙÙ Ø§ÙØ±ÙØ§ØšØ· Ø§ÙØªÙ ØªØ­ØªÙÙ Ø¹ÙÙ ÙÙ Ù
+Ù 'cgi-bin' Ø£Ù '.ppt'.  
+MediaWikiDownload.reject_filetype_disp:ØªØ¬Ø§ÙÙ Ø§ÙÙ
+Ø§Ø· Ø¹ÙØ§ÙÙÙ Ø§ÙÙ
+ÙØ§Ø±Ø¯ Ø§ÙÙ
+ÙØ­Ø¯Ø©.  
+MediaWikiDownload.exclude_directories:ÙØ§ØŠÙ
+Ø© Ø§ÙØ£Ø¯ÙØ© Ø§ÙÙ
+Ø³ØªØšØ¹Ø¯Ø©(Ù
+Ø³Ø§Ø±Ø§Øª ÙØ£Ø¯ÙØ© Ù
+ÙØªÙÙØ©)Ø Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù: /peopleÙ /documentation Ø³ÙÙ ØªØ³ØªØšØ¹Ø¯ ÙÙ Ù
+Ù Ø§ÙØ£Ø¯ÙØ© 'people'Ù 'documentation' ØªØ­Øª Ø§ÙÙ
+ÙÙØ¹ Ø§ÙØ­Ø§ÙÙ.  
+MediaWikiDownload.exclude_directories_disp:Ø¥Ø³ØªØšØ¹Ø§Ø¯ Ø£Ø¯ÙØ©  
+
+OAIDownload.desc:ÙÙ
+ÙØ°Ø¬ Ø§ÙØªÙØ²ÙÙ Ù
+Ù Ù
+Ø³ØªÙØ¯Ø¹Ø§Øª Ù
+ØšØ§Ø¯Ø±Ø© Ø§ÙØ£Ø±ØŽÙÙ Ø§ÙÙ
+ÙØªÙØ­
+OAIDownload.url_disp:Ù
+ØµØ¯Ø± Ø¹ÙÙØ§Ù Ø§ÙÙ
+ÙØ§Ø±Ø¯ Ø§ÙÙ
+ÙØ­Ø¯
+OAIDownload.url:Ù
+Ø³ØªÙØ¯Ø¹ Ø¹ÙÙØ§Ù Ø§ÙÙ
+ØµØ§Ø¯Ø± Ø§ÙÙ
+ÙØ­Ø¯ ÙÙ
+ØšØ§Ø¯Ø±Ø© Ø§ÙØ£Ø±ØŽÙÙ Ø§ÙÙ
+ÙØªÙØ­
+OAIDownload.set_disp:Ù
+ÙÙØ¯ ÙÙ
+Ø¹ÙØ§Ø±  
+OAIDownload.set:ØªÙÙÙØ¯ Ø§ÙØªÙØ²ÙÙ ÙÙÙØ§ ÙÙÙ
+Ø¹ÙØ§Ø± Ø§ÙÙ
+Ø­Ø¯Ø¯ ÙÙ Ø§ÙÙ
+Ø³ØªÙØ¯Ø¹
+OAIDownload.metadata_prefix_disp:ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙØšØ§Ø¯ØŠØ©  
+OAIDownload.metadata_prefix:ØŽÙÙ ÙØ§ØµÙØ§Øª Ø§ÙØšÙØ§ÙØ§Øª Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+ ÙÙ Ø§ÙÙ
+ØµØ¯Ø±  Ø Ù
+Ø«Ù oai_dc Ø qdc Ø Ø§Ø¶ØºØ· Ø¹ÙÙ Ø§ÙØ²Ø±Ø§ <Ù
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙÙ
+Ø²ÙØ¯>  ÙÙ
+Ø¹Ø±ÙØ© Ù
+Ø§ ÙÙ Ø§ÙØ£ØŽÙØ§Ù Ø§ÙÙ
+Ø¯Ø¹ÙÙ
+Ø©.  
+OAIDownload.get_doc_disp:Ø£ÙØ¬Ø¯ ÙØ«ÙÙØ©
+OAIDownload.get_doc:ØªÙØ²ÙÙ Ù
+ØµØ¯Ø± Ø§ÙÙØ«ÙÙØ© Ø¥Ø°Ø§ ØªÙ
+ ØªØ­Ø¯ÙØ¯ ÙØ§Ø­Ø¯Ø© ÙÙ Ø§ÙØªØ³Ø¬ÙÙØ©
+OAIDownload.get_doc_exts_disp:ÙÙØ· ØªØŽÙ
+Ù Ø£ÙÙØ§Ø¹ Ø§ÙÙ
+ÙÙØ§Øª  
+OAIDownload.get_doc_exts:Ø¥Ù
+ØªØ¯Ø§Ø¯Ø§Øª Ø§Ø³Ù
+ Ø§ÙÙ
+ÙÙ Ø§ÙÙ
+Ø³Ù
+ÙØ­ ÙÙØ«Ø§ØŠÙ ÙÙØ­ØµÙÙ .  
+OAIDownload.max_records_disp:Ø¹Ø¯Ø¯ Ø§ÙØªØ³Ø¬ÙÙØ§Øª Ø§ÙØ£ÙØµÙ
+OAIDownload.max_records:Ø¹Ø¯Ø¯ Ø§ÙØªØ³Ø¬ÙÙØ§Øª Ø§ÙØ£ÙØµÙ ÙÙØªÙØ²ÙÙ
+
+SRWDownload.desc:ÙÙ
+ÙØ°Ø¬ ÙÙØªÙØ²ÙÙ Ù
+Ù Ù
+Ø³ØªÙØ¯Ø¹Ø§Øª  SRW (ØšØ­Ø«/Ø¥Ø³ØªØ±Ø¬Ø§Ø¹ Ø®Ø¯Ù
+Ø§Øª Ø§ÙÙØš)
+
+WebDownload.desc:ÙÙ
+ÙØ°Ø¬ ÙÙØªÙØ²ÙÙ Ù
+Ù Ø§ÙØ¥ÙØªØ±ÙØª Ø¹ØšØ± ØšØ±ÙØªÙÙÙÙ ÙÙÙ Ø§ÙÙØµ Ø§ÙØªØŽØ¹ØšÙ Ø£Ù ØšØ±ÙØªÙÙÙÙ ÙÙÙ Ø§ÙØšÙØ§ÙØ§Øª
+WebDownload.url:Ù
+ØµØ¯Ø± Ø¹ÙÙØ§Ù Ø§ÙÙ
+ÙØ§Ø±Ø¯ Ø§ÙÙ
+ÙØ­Ø¯.ÙÙ Ø­Ø§ÙØ© Ø¥Ø¹Ø§Ø¯Ø© ØªÙØ¬ÙÙ http Ø Ø±ØšÙ
+Ø§ ØªØªØºÙØ± ÙØ°Ù Ø§ÙÙÙÙ
+Ø©.  
+WebDownload.url_disp:Ù
+ØµØ¯Ø± Ø¹ÙÙØ§Ù Ø§ÙÙ
+ÙØ§Ø±Ø¯ Ø§ÙÙ
+ÙØ­Ø¯
+WebDownload.depth:ÙÙ
+ ÙÙ Ø¹Ù
+Ù Ø§ÙØ¥Ø±ØªØšØ§Ø· Ø§ÙØªØŽØ¹ØšÙ Ø¹ÙØ¯ Ø§ÙØªØªÙØ²ÙÙ
+WebDownload.depth_disp:Ø¹Ù
+Ù Ø§ÙØªÙØ²ÙÙ
+WebDownload.below:Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+ØªØ·Ø§ØšÙØ© ÙÙØ· ØªØ­Øª Ø¹ÙÙØ§Ù Ø§ÙÙ
+ØµØ§Ø¯Ø± Ø§ÙÙ
+ÙØ­Ø¯
+WebDownload.below_disp:ÙÙØ· Ø§ÙÙ
+ÙÙØ§Øª ØªØ­Øª Ø¹ÙÙØ§Ù Ø§ÙÙ
+ØµØ§Ø¯Ø± Ø§ÙÙ
+ÙØ­Ø¯  
+WebDownload.within:Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+ØªØ·Ø§ØšÙØ© Ø¶Ù
+Ù ÙØ°Ø§ Ø§ÙÙ
+ÙÙØ¹
+WebDownload.within_disp:Ø§ÙÙ
+ÙÙØ§Øª Ø¶Ù
+Ù ÙØ°Ø§ Ø§ÙÙ
+ÙÙØ¹ ÙÙØ·.  
+WebDownload.html_only:ØªØ­Ù
+ÙÙ Ù
+ÙÙØ§Øª ÙØºØ© ØªØ±Ù
+ÙØ² Ø§ÙÙØµÙØµ Ø§ÙØªØŽØ¹ØšÙØ© ÙÙØ· ØÙ ØªØ¬Ø§ÙÙ Ø§ÙÙ
+ÙÙØ§Øª Ø§ÙÙ
+ØªØ¹ÙÙØ© ØšÙØ§ Ù
+Ø«Ù Ø§ÙØµÙØ± Ù Ø§ÙØ¥Ø³ØªØ§ÙÙ ØŽÙØª
+WebDownload.html_only_disp:ÙÙØ· Ù
+ÙÙØ§Øª HTML  
+
+WgetDownload.desc:Ø§ÙÙØŠØ© Ø§ÙØ£Ø³Ø§Ø³ Ø§ÙØªÙ ØªØªÙØ§ÙÙ Ø§ÙØ¥Ø³ØªØ¯Ø¹Ø§Ø¡ Ø§ÙÙ wget  
+WgetDownload.proxy_on:ØšØ±ÙÙØ³Ù ÙØŽØ·
+WgetDownload.proxy_host:Ù
+Ø¶ÙÙ Ø§ÙØšØ±ÙÙØ³Ù
+WgetDownload.proxy_port:Ù
+ÙÙØ° Ø§ÙØšØ±ÙÙØ³Ù
+WgetDownload.user_name:Ø¥Ø³Ù
+ Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+
+WgetDownload.user_password:ÙÙÙ
+Ø© Ù
+Ø±ÙØ± Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+
+
+Z3950Download.desc:ÙÙ
+ÙØ°Ø¬ Ø§ÙØªÙØ²ÙÙ Ù
+Ù Ù
+Ø³ØªÙØ¯Ø¹Ø§Øª  Z3950
+Z3950Download.host:Ù
+Ø¶ÙÙ Ø¹ÙÙØ§Ù Ø§ÙÙ
+ÙØ§Ø±Ø¯ Ø§ÙÙ
+ÙØ­Ø¯
+Z3950Download.host_disp:Ù
+Ø¶ÙÙ
+Z3950Download.port:Ø±ÙÙ
+ Ù
+ÙÙØ° Ø§ÙÙ
+Ø³ØªÙØ¯Ø¹
+Z3950Download.port_disp:Ù
+ÙÙØ°
+Z3950Download.database:ØšØ­Ø« Ø§ÙØªØ³Ø¬ÙÙØ§Øª ÙÙ ÙØ§Ø¹Ø¯Ø© ØšÙØ§ÙØ§Øª
+Z3950Download.database_disp:ÙØ§Ø¹Ø¯Ø© ØšÙØ§ÙØ§Øª
+Z3950Download.find:Ø¥Ø³ØªØ±Ø¬Ø§Ø¹ Ø§ÙØªØ³Ø¬ÙÙØ§Øª Ø§ÙÙ
+ØªØ¶Ù
+ÙØ© Ù
+ØµØ·ÙØ­Ø§Øª ØšØ­Ø« Ù
+Ø­Ø¯Ø¯Ø©
+Z3950Download.find_disp:Ø£ÙØ¬Ø¯
+Z3950Download.max_records:Ø§ÙØ¹Ø¯Ø¯ Ø§ÙØ§ÙØµÙ ÙÙØªØ³Ø¬ÙÙØ§Øª ÙÙØªÙØ²ÙÙ
+Z3950Download.max_records_disp:Ø¹Ø¯Ø¯ Ø§ÙØªØ³Ø¬ÙÙØ§Øª Ø§ÙØ§ÙØµÙ
+
+
+#
+#Plugout option descriptions
+#
+
+BasPlugout.bad_general_option:%s plugout ØªØ³ØªØ®Ø¯Ù
+ Ø®ÙØ§Ø± ØºÙØ± ØµØ­ÙØ­.  
+BasPlugout.debug:Ø¥Ø¹Ø¯Ø§Ø¯ Ø³ÙØ§Ù ØªØµØ­ÙØ­ Ø§ÙØ£Ø®Ø·Ø§Ø¡  
+BasPlugout.desc:Ø§ÙÙ
+ØµÙÙ Ø§ÙØ£Ø³Ø§Ø³ ÙÙÙ Ù
+Ø®Ø±Ø¬Ø§Øª Ø§ÙÙ
+ÙØ§ØšØ³.  
+BasPlugout.group_size:Ø¹Ø¯Ø¯ Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙÙ
+Ø¬Ù
+Ø¹Ø© ÙÙ Ù
+ÙÙ XML ÙØ§Ø­Ø¯.  
+BasPlugout.gzip_output:Ø£Ø³ØªØ®Ø¯Ù
+ gzip ÙØ¶ØºØ· ÙØ«Ø§ØŠÙ xml Ø§ÙÙØ§ØªØ¬Ø© ( ÙØ§ ØªÙØ³Ù Ø§Ù ØªØ¶Ù
+Ù Ø§ÙÙ
+ÙØ§ØšØ³ ZIPPlug ÙÙ ÙØ§ØŠÙ
+Ø© Ø§ÙÙ
+ÙØ§ØšØ³  Ø¹ÙØ¯ ØšÙØ§Ø¡ Ø§ÙÙØ«Ø§ØŠÙ
+BasPlugout.output_handle:ÙØ§ØµÙØ© Ø§ÙÙ
+ÙÙ ØªØ³ØªØ®Ø¯Ù
+ ÙØ¥Ø±Ø³Ø§Ù Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙÙ
+Ø®Ø±Ø¬Ø©  
+BasPlugout.output_info:Ø§ÙØ¥ØŽØ§Ø±Ø© ÙÙÙØ§Ù Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø§ÙØ£Ø±ØŽÙÙÙ Ø§ÙØ°Ù Ø³ØªØ®Ø¯Ù
+ ÙØ­ÙØž Ø§ÙÙ
+Ø¹ÙÙÙ
+Ø§Øª Ø­ÙÙ Ø§ÙØ£Ø±ØŽÙÙØ§Øª.  
+BasPlugout.verbosity:Ø¶ØšØ· ÙÙ
+ÙØ© Ø§ÙÙ
+Ø®Ø±Ø¬t. 0=ÙØ§ØŽÙØ¡, 3=ÙØ«ÙØ±.
+BasPlugout.xslt_file:ØªØ­ÙÙÙ ÙØ«ÙÙØ© Ø¹Ù Ø·Ø±ÙÙ XSLT ÙÙ Ø§ÙÙ
+ÙÙ Ø§ÙÙ
+Ø³Ù
+Ù.  
+
+DSpacePlugout.desc::DSpace ÙÙØŠØ© Ø£Ø±ØŽÙÙ.
+
+FedoraMETSPlugout.desc:ØŽÙÙ METS ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø³Ù
+Ø§Øª ÙÙØ¯ÙØ±Ø§ .  
+FedoraMETSPlugout.fedora_namespace:Ø§ÙØšØ§Ø¯ØŠØ© Ø§ÙÙ
+Ø³ØªØ®Ø¯Ù
+Ø© ÙÙ ÙÙØ¯ÙØ±Ø§ ÙÙ
+Ø¹Ø§ÙØ¬Ø© ids (PIDS) Ø¹ÙÙ Ø³ØšÙÙ Ø§ÙÙ
+Ø«Ø§Ù greenstone:HASH0122efe4a2c58d0  
+
+GreenstoneXMLPlugout.desc:ØŽÙÙ Ø§Ø±ØŽÙÙ Ø¬Ø±ÙÙØ³ØªÙÙ XML .  
+
+GreenstoneMETSPlugout.desc:ØŽÙÙ METS ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø³Ù
+Ø§Øª Ø¬Ø±ÙÙØ³ØªÙÙ .  
+
+MARCXMLPlugout.desc:MARC xml ØŽÙÙ.  
+MARCXMLPlugout.group:Ø¥Ø®Ø±Ø§Ø¬ ØªØ³Ø¬ÙÙØ§Øª marc xml ÙÙ Ù
+ÙÙ ÙØ§Ø­Ø¯.  
+MARCXMLPlugout.mapping_file:Ø§Ø³ØªØ®Ø¯Ù
+ Ù
+ÙÙ Ø§ÙØªØ®Ø·ÙØ· Ø§ÙÙ
+Ø³Ù
+Ù ÙÙØªØ­ÙÙÙ.  
+
+METSPlugout.desc:METS ØšØ§Ø³ØªØ®Ø¯Ø§Ù
+ Ø®ØµØ§ØŠØµ Greenstone  
+METSPlugout.xslt_txt:Ø­ÙÙ Ù
+ÙÙ METS Ø§ÙØ®Ø§ØµØ© ØšÙ doctxt.xml Ù
+Ø¹ Ø§ÙÙ XSLT ÙÙ Ø§ÙÙ
+ÙÙ Ø§ÙÙ
+Ø³Ù
+Ù.  
+METSPlugout.xslt_mets:Ø­ÙÙ Ù
+ÙÙ METS Ø§ÙØ®Ø§ØµØ© ØšÙ doctxt.xml Ù
+Ø¹ Ø§ÙÙ XSLT ÙÙ Ø§ÙÙ
+ÙÙ Ø§ÙÙ
+Ø³Ù
+Ù.  
+
+#
+# Perl module strings
+#
+
+classify.could_not_find_classifier:Ø®Ø·Ø£: ÙÙ
+ ÙØªÙ
+ Ø§ÙØ¹Ø«ÙØ± Ø¹ÙÙ Ø§ÙÙ
+ØµÙÙ \"%s\"
+
+download.could_not_find_download:Ø®Ø·Ø£: ÙÙ
+ ÙØªÙ
+ Ø§ÙØ¹Ø«ÙØ± Ø¹ÙÙ ÙÙ
+ÙØ°Ø¬ Ø§ÙØªÙØ²ÙÙ \"%s\"
+
+plugin.could_not_find_plugin:Ø®Ø·Ø£: ÙÙ
+ ÙØªÙ
+ Ø§ÙØ¹Ø«ÙØ± Ø¹ÙÙ Ø§ÙÙ
+ÙØ§ØšØ³ \"%s\"
+
+plugin.including_archive:ÙØªØ¶Ù
+Ù Ù
+Ø­ØªÙÙØ§Øª Ø§ÙØ£Ø±ØŽÙÙ Ù 1 ZIP/TAR
+
+plugin.including_archives:ÙØªØ¶Ù
+Ù Ù
+Ø­ØªÙÙØ§Øª Ø§ÙØ£Ø±ØŽÙÙ Ù %d ZIP/TAR
+
+plugin.kill_file:ØªÙ
+ Ø¥ØšØ·Ø§Ù Ø§ÙØ¥Ø¬Ø±Ø§Ø¡ ØšÙØ§Ø³Ø·Ø© Ù
+ÙÙ Ø§ÙØ¥ØšØ·Ø§Ù
+
+plugin.n_considered:%d ÙØ«Ø§ØŠÙ ØªÙ
+ Ø§Ø¹ØªØšØ§Ø±ÙØ§ ÙÙÙ
+Ø¹Ø§ÙØ¬Ø©
+
+plugin.n_included:%d ØªÙ
+Øª Ù
+Ø¹Ø§ÙØ¬ØªÙØ§ Ù ØªØ¶Ù
+ÙÙÙØ§ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©
+
+plugin.n_rejected:%d ØªÙ
+ Ø±ÙØ¶ÙØ§
+
+plugin.n_unrecognised:%d ÙÙ
+ ÙØªÙ
+ Ø§ÙØªØ¹Ø±Ù Ø¹ÙÙÙØ§
+
+plugin.no_plugin_could_process:ØªØ­Ø°ÙØ±: ÙØ§ ÙÙØ¬Ø¯ Ù
+ÙØ§ØšØ³ ÙÙ
+Ø¹Ø§ÙØ¬Ø© %s
+
+plugin.no_plugin_could_recognise:ØªØ­Ø°ÙØ±: ÙÙ
+ ÙØªØ¹Ø±Ù Ø§Ù Ù
+ÙØ§ØšØ³ Ø¹ÙÙ %s
+
+plugin.no_plugin_could_process_this_file:ÙØ§ ÙÙØ¬Ø¯ Ù
+ÙØ§ØšØ³ ÙÙ
+Ø¹Ø§ÙØ¬Ø© ÙØ°Ø§ Ø§ÙÙ
+ÙÙ
+
+plugin.no_plugin_could_recognise_this_file:ÙÙ
+ ÙØªØ¹Ø±Ù Ø§Ù Ù
+ÙØ§ØšØ³ Ø¹ÙÙ ÙØ°Ø§ Ø§ÙÙ
+ÙÙ
+
+plugin.one_considered:1 ÙØ«ÙÙØ© ØªÙ
+ Ø§Ø¹ØªØšØ§Ø±ÙØ§ ÙÙÙ
+Ø¹Ø§ÙØ¬Ø©
+
+plugin.one_included:1 ØªÙ
+Øª Ù
+Ø¹Ø§ÙØ¬ØªÙØ§ Ù ØªØ¶Ù
+ÙÙÙØ§ Ø§ÙÙ
+Ø¬Ù
+ÙØ¹Ø©
+
+plugin.one_rejected:1 ØªÙ
+ Ø±ÙØ¶ÙØ§
+
+plugin.one_unrecognised:1 ÙÙ
+ ÙØªÙ
+ Ø§ÙØªØ¹Ø±Ù Ø¹ÙÙÙØ§
+
+plugin.see_faillog:Ø£ÙØžØ±  %s ÙÙØ§ØŠÙ
+Ø© Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙØªÙ ÙÙ
+ ÙØªÙ
+ Ø§ÙØªØ¹Ø±Ù Ø¹ÙÙÙØ§ Ù/ Ø§ÙÙØ«Ø§ØŠÙ Ø§ÙÙ
+Ø±ÙÙØ¶Ø© documents
+
+PrintUsage.default:Ø¥ÙØªØ±Ø§Ø¶Ù
+
+PrintUsage.required:Ù
+Ø·ÙÙØš
+
+plugout.could_not_find_plugout:Ø®Ø·Ø£: ÙÙ
+ ÙØªÙ
+ Ø§ÙØ¹Ø«ÙØ± Ø¹ÙÙ plugout \"%s\"  
Index: /gsdl/stable/perllib/strings_es.properties
===================================================================
--- /gsdl/stable/perllib/strings_es.properties	(revision 20131)
+++ /gsdl/stable/perllib/strings_es.properties	(revision 20131)
@@ -0,0 +1,1318 @@
+#
+# Resource bundle description
+#
+
+Language.code:es
+Language.name:EspaÃ±ol
+
+OutputEncoding.unix:iso_8859_1
+OutputEncoding.windows:iso_8859_1
+
+
+#
+# Common output messages and strings
+#
+
+common.cannot_create_file:ERROR: no puede crear archivo %s
+
+common.cannot_find_cfg_file:ERROR: no puede encontrar el archivo de configuraciÃ³n %s
+
+common.cannot_open:ERROR: no puede abrir %s
+
+common.cannot_open_fail_log:ERROR: no puede abrir el fail log %s
+
+common.cannot_open_output_file:ERROR: no se puede abrir el fichero salida %s  
+
+common.cannot_read:ERROR: no puede leer %s
+
+common.cannot_read_file:ERROR: no puede leer el archivo %s
+
+common.general_options:las opciones generales (para % s)
+
+common.must_be_implemented:La funciÃ³n de BasPlug::read deberÃ¡ ser implementada en la subclase para los plugins recursivos
+
+common.options:opciones
+
+common.processing:procesando
+
+common.specific_options:opciones especÃ­ficas
+
+common.usage:uso
+
+common.info:informaciÃ³n  
+
+common.invalid_options:Argumentos invÃ¡lidos: %s  
+
+common.true:verdadero  
+
+common.false:falso  
+
+common.deprecated:SUSTITUIDO  
+#
+# Script option descriptions and output messages
+#
+
+scripts.language:El idioma para desplegar las descripciones de la opciÃ³n en ('en_US' especifica inglÃ©s americano). Requiere las traducciones de las descripciones de la opciÃ³n existente en el archivo de perllib/strings_language-code.rb.
+
+scripts.xml:Produce la informaciÃ³n en un formato XML, sin comentarios 'elegantes' pero con mucho mÃ¡s detalle.
+
+scripts.listall:Listar todos los Ã­tems conocidos.
+
+scripts.describeall:Mostrar opciones para todos los elementos conocidos  
+
+scripts.both_old_options:ATENCIÃN: Se especificÃ³ -removeold con -keepold o -incremental, se usarÃ¡ -removeold. Los contenidos actuales del directorio %s se borrarÃ¡n.  
+
+scripts.no_old_options:ATENCIÃN: Si no se especificaron -removeol, -keepold o -incremental, se establece -removeold. Se borrarÃ¡n todos los contenidos del directorio %s.  
+
+scripts.gli:Una opciÃ³n asignada cuando se ejecuta este script desde el GLI que permite una salida especÃ­fica para el gli.  
+
+# -- buildcol.pl --
+
+buildcol.archivedir:LocalizaciÃ³n de los archivos.  
+
+buildcol.builddir:DÃ³nde poner los Ã­ndices construidos.
+
+buildcol.cachedir:La colecciÃ³n se construirÃ¡ aquÃ­ temporalmente antes de copiarse al directorio construido.
+
+buildcol.cannot_open_cfg_file:ADVERTENCIA: no puede abrir los archivos config a efecto de poner al dÃ­a: %s
+
+buildcol.collectdir:Ruta al directorio "collect".  
+
+buildcol.copying_back_cached_build:Copiando la figura anteriormente construida
+
+buildcol.create_images:Intente crear las imÃ¡genes predefinidas para la nueva colecciÃ³n. Esto confÃ­a en el Gimp instalÃ¡ndose a lo largo con los mÃ³dulos perl pertinentes que permitan el scripting del perl.
+
+buildcol.debug:Imprima el output a STDOUT.
+
+buildcol.desc:Script PERL usado para construir una colecciÃ³n Greenstone desde documentos GA.  
+
+buildcol.faillog:Fallo en el fichero de control. Este fichero contiene el de cualquier fichero que haya fallado al ser procesado.  
+
+buildcol.incremental_default_builddir:AVISO: el directorio de construcciÃ³n es por defecto "building". Si quiere hacer una indexaciÃ³n incremental, por favor agregue la opciÃ³n "-builddir index" al buildcol.pl.  
+
+buildcol.index:Ãndice a construir (construirÃ¡ todos los ficheros en el config si no estÃ¡ determinado).  
+
+buildcol.incremental:SÃ³lo indiza documentos que no lo hayan sido previamente. Implica -keepold. Se basa en el indizador Lucene.  
+
+buildcol.keepold:No destruirÃ¡ los volÃºmenes actuales del directorio construido.
+
+buildcol.maxdocs:El nÃºmero mÃ¡ximo de documentos para construir.
+buildcol.maxnumeric:NÃºmero mÃ¡ximo de dÃ­gitos que una 'palabra' puede tener en el diccionario de Ã­ndice. Los nÃºmeros largos se dividen en varias palabras para su indizaciÃ³n. Por ej., si maxnumeric es 4, "1342663" se dividirÃ¡ en "1342" y "663"  
+buildcol.mode:Las partes del proceso construido para llevar a cabo.
+buildcol.mode.all:Realizar todo.
+buildcol.mode.build_index:Simplemente ponga en un Ã­ndice el texto.
+buildcol.mode.compress_text:Simplemente comprima el texto.
+buildcol.mode.infodb:Simplemente construye la base de datos de metadatos.  
+
+buildcol.no_default_images:No se generarÃ¡n las imÃ¡genes predefinidas.
+
+buildcol.no_image_script:ADVIRTIENDO: Imagen que hace la escritura no encontrada: %s
+
+buildcol.no_strip_html:No despoje las etiquetas html del texto puesto en un Ã­ndice (sÃ³lo utilice para las colecciones del mgpp).
+
+buildcol.no_text:No guarde el texto comprimido. Esta opciÃ³n es Ãºtil para minimizar el tamaÃ±o de los Ã­ndices construidos si usted siempre piensa desplegar los documentos originales en momento que estÃ¡ utilizando el programa (es decir usted no podrÃ¡ recuperar la versiÃ³n del texto comprimido).
+
+buildcol.sections_index_document_metadata:Indiza metadatos de nivel de documento a nivel de secciÃ³n.  
+buildcol.sections_index_document_metadata.never:No indiza ningÃºn metadato de documento a nivel de secciÃ³n.  
+buildcol.sections_index_document_metadata.always:AÃ±ade todos los metadatos a nivel de documento, incluso si existen metadatos a nivel de secciÃ³n con ese nombre.  
+buildcol.sections_index_document_metadata.unless_section_metadata_exists:SÃ³lo aÃ±ade metadatos a nivel de documento si no existen metadatos con ese nombre a nivel de secciÃ³n.  
+
+buildcol.out:Nombre de fichero o dispositivo para imprimir el estado de la salida.  
+
+buildcol.params:[las opciones] collection-name
+
+buildcol.remove_empty_classifications:Ocultar los clasificadores y los nodos de clasificaciÃ³n vacÃ­os (aquellos que no contienen documentos).
+
+buildcol.removeold:BorrarÃ¡ todos los contenidos previos del directorio building.  
+
+buildcol.unlinked_col_images:No pueden unirse las imÃ¡genes de la colecciÃ³n de manera correcta.
+
+buildcol.unknown_mode:Modo desconocido: %s
+
+buildcol.updating_archive_cache:Actualizando el cachÃ©  
+
+buildcol.verbosity:Los mandos la cantidad de rendimiento. El 0=ninguno, 3=muchos.
+
+
+# -- classinfo.pl --
+
+classinfo.collection:Dar un nombre de la colecciÃ³n harÃ¡n que classinfo.pl aparezca primero clasifique en el collect/collection-name/perllib/classify. Si el clasificador no se encuentra allÃ­ buscarÃ¡ en el directorio general perllib/classify.
+
+classinfo.desc:Imprime la informaciÃ³n de las impresiones sobre un clasificador.
+
+classinfo.general_options:Se heredan las opciones generales de las clases paternales del clasificador.
+
+classinfo.info:info
+
+classinfo.no_classifier_name:ERROR: Usted debe proporcionar un nombre del clasificador.
+
+classinfo.option_types:Los clasificadores pueden tomar dos tipos de opciones
+
+classinfo.params:[opciones] nombre-clasificador
+
+classinfo.passing_options:Las opciones pueden pasarse a cualquier clasificador incluyÃ©ndolos en su archivo de configuraciÃ³n collect.cfg.
+
+classinfo.specific_options:Se definen las opciones especÃ­ficas dentro del propio clasificador, y sÃ³lo estÃ¡ disponible a este clasificador particular.
+
+# -- downloadfrom.pl --
+downloadfrom.cache_dir:LocalizaciÃ³n del directorio de cachÃ©  
+downloadfrom.desc:Descarga ficheros de un servidor externo  
+downloadfrom.download_mode:Tipo de servidor desde el que descargar  
+downloadfrom.download_mode.Web:HTTP  
+downloadfrom.download_mode.MediaWiki:Sitio web MediaWiki  
+downloadfrom.download_mode.OAI:Open Archives Initiative (Iniciativa de Archivos Abiertos).  
+downloadfrom.download_mode.z3950:Servidor z3950  
+downloadfrom.download_mode.SRW:Servicio web de BÃºsqueda y RecuperaciÃ³n  
+downloadfrom.incorrect_mode:El parÃ¡metro modo de descarga es incorrecto  
+downloadfrom.info:Ofrece informaciÃ³n sobre el servidor, en preferencia a descargar  
+downloadfrom.params:[opciones generales] [opciones especÃ­ficas de descarga]  
+
+# -- downloadinfo.pl --
+
+downloadinfo.desc:Ofrece informaciÃ³n sobre el mÃ³dulo de descarga  
+downloadinfo.collection:Dar un nombre de colecciÃ³n harÃ¡ que downloadinfo.pl busque en collect/collection-name/perllib/downloaders primero. Si no encuentra el mÃ³dulo aquÃ­, buscarÃ¡ en el directorio general perllib/downloaders  
+downloadinfo.params:[opciones] [mÃ³dulo de descarga]  
+downloadinfo.general_options:Las opciones generale se heredan de las clases padre de los mÃ³dulos de descarga.  
+downloadinfo.specific_options:Las opciones especÃ­ficas se definen dentro del propio mÃ³dulo de descarga, y sÃ³lo estÃ¡n disponibles para este descargador en particular.  
+downloadinfo.option_types:Los mÃ³dulos de descarga pueden tomar dos tipos de opciones  
+
+# -- explode_metadata_database.pl --
+explode.desc:Explotar una base de datos de metadatos.
+
+explode.collection:El nombre de la colecciÃ³n. Algunos conectores buscan archivos auxiliares en la carpeta de la colecciÃ³n.  
+ 
+explode.document_field:El elemento de los metadatos que especifica los nombres de los documentos a obtener e incluir en la colecciÃ³n.  
+
+explode.document_prefix:Un prefijo para las ubicaciones de los documentos (para usar con la opciÃ³n document_field).
+
+explode.document_suffix:Un sufijo para las ubicaciones de los documentos (para usar con la opciÃ³n document_field).
+
+explode.encoding:CodificaciÃ³n a utilizar al leer el archivo de la base de datos
+explode.metadata_set:Conjunto de metadatos (espacio de nombres) para exportar todos los metadatos
+explode.plugin:Plugin a utilizar para explotar
+explode.plugin_options:Opciones a pasarle al plugin antes de ejecutarse. Los nombres de opciÃ³n deben comenzar con -. Separar nombres de opciÃ³n y valores con espacios. No puede usarse con -use_collection_plugin_options.  
+explode.use_collection_plugin_options:Leer el archivo de configuraciÃ³n de la colecciÃ³n y usar las opciones para el plugin especificado. Requiere la opciÃ³n -collection. No puede usarse junto a la opciÃ³n -plugin_options.  
+explode.params:[opciones] nombre de archivo
+explode.records_per_folder:NÃºmero de registros a situar en cada subcarpeta.  
+
+# -- replace_srcdoc_with_html.pl --
+srcreplace.desc:Reemplaza el documento origen con el HTML generado cuando se hace una reconstrucciÃ³n  
+srcreplace.params:[opciones] nombre de archivo  
+srcreplace.plugin:Conector usado paa convertir el documento de origen  
+
+# -- exportcol.pl --
+
+exportcol.out:Nombre del archivo o identificador para imprimir el estado de los resultados.
+exportcol.cddir:Nombre del directorio al que se exportan los contenidos del CD.  
+exportcol.cdname:El nombre del CD-ROM. Esto es lo que aparecerÃ¡ en el menÃº de inicio una vez que el CD-ROM se haya instalado.
+exportcol.desc:GuiÃ³n PERL usado para exportar una o mÃ¡s colecciones a un CD-ROM para Windows.
+exportcol.noinstall:Crea un CD-ROM en el que se ejecuta directamente la Biblioteca, y no instala nada en el computador.  
+exportcol.params:[opciones] nombre de la colecciÃ³n 1 nombre de la colecciÃ³n 2 ...
+exportcol.coll_not_found:El %s de la colecciÃ³n no es vÃ¡lido: la colecciÃ³n no se encontrÃ³ en %s.
+exportcol.coll_dirs_not_found:El %s de la colecciÃ³n no es vÃ¡lido: no se pudo encontrar uno de los siguientes directorios:
+exportcol.fail:exportcol.pl no se pudo ejecutar:
+exportcol.no_valid_colls:Las colecciones especificadas no son vÃ¡lidas y por lo tanto no se pueden exportar.
+exportcol.couldnt_create_dir:No se pudo crear el directorio %s.
+exportcol.couldnt_create_file:No se pudo crear %s.
+exportcol.instructions:Para crear un CD-ROM en Windows que se podrÃ¡ instalar automÃ¡ticamente, grabe el contenido de esta carpeta en un CD-ROM.
+exportcol.non_exist_files:Uno o mÃ¡s de los siguientes archivos y directorios no existe:
+exportcol.success:exportcol.pl se ejecutÃ³ con Ã©xito:
+exportcol.output_dir:Las colecciones que se exportaron (%s) se encuentran en %s
+exportcol.export_coll_not_installed:La funcionalidad de 'Exportar a un CD-ROM' no ha estado instalada.
+
+# -- import.pl --
+
+import.archivedir:Lugar donde los materiales convertidos finalizan.
+
+import.manifest:Fichero XML que indica que ficheros deben importarse. Usado en lugar de explorar en descendente la carpeta de importaciÃ³n, normalmente para construcciÃ³n incremental.  
+
+import.cannot_open_stats_file:ATENCIÃN: No podrÃ­a abrir el archivo de estadÃ­sticas %s.  
+
+import.cannot_open_fail_log:ERROR: No se pudo abrir el registro %s
+
+import.cannot_sort:ADVIRTIENDO: import.pl no puede ordenar los documentos cuando el tamaÃ±o del grupo > 1. la opciÃ³n sortmeta se ignorarÃ¡.
+
+import.collectdir:La ruta al directorio "collect".  
+
+import.complete:La importaciÃ³n ha sido completada
+
+import.debug:Imprimir texto importado a STDOUT (para importar GreenstoneXML)  
+
+import.desc:Script Perl utilizado para importar los archivos a un formato listo para construir (GreenstoneXML o GreenstoneMETS).  
+
+import.faillog:FallÃ³ el nombre del fichero de control. Este fichero recibe los nombres de los ficheros que hayan fallado al ser procesados.  
+
+import.groupsize:El nÃºmero de documentos importados que se agrupan en un archivo de XML.  
+
+import.gzip:Use el gzip para comprimir los documentos xml resultantes (no se olvide de incluir ZIPPlugin en su lista de conectores al construir con documentos comprimidos).  
+
+import.importdir:Donde el material original reside.
+
+import.incremental:SÃ³lo importa documentos mÃ¡s recientes (por fecha) que los existentes en los archivos. Implica -keepold.  
+
+import.keepold:No borrarÃ¡ los contenidos actuales del directorio archives.  
+
+import.maxdocs:El nÃºmero mÃ¡ximo de documentos para importar.
+
+import.no_import_dir:Error: directorio de importaciÃ³n (%s) no encontrado.  
+
+import.no_plugins_loaded:ERROR: NingÃºn plugins ha sido cargado.
+
+import.OIDtype:El mÃ©todo a utilizar al generar los Ãºnicos identificadores para cada documento.
+import.OIDtype.hash:Codifica los contenidos del fichero. Los identificadores del documento serÃ¡n los mismos cada vez que la colecciÃ³n sea importada.  
+
+import.OIDtype.incremental:Usa un conteo simple del documento simple que es significativamente mÃ¡s rÃ¡pido que hash. pero no asigna el mismo identificador al mismos contenido del documento, y no permite agregar mÃ¡s documentos a los archivos existentes.  
+
+import.OIDtype.assigned:Usa el valor del elemento de metadato indicado por la opciÃ³n OIDmetadata (precedido por 'D'); si no se especifica, se usa un hash para un documento particular. Estos identificadores deben ser Ãºnicos.  
+
+import.OIDtype.dirname:Usa el nombre del directorio padre. (precedido de 'J') SÃ³lo deberÃ­a haber un documento por directorio, y todos los nombres de directorio deberÃ­an ser Ãºnicos. Ej.:  import/b13as/h15ef/page.html producirÃ¡ Jh15ef como identificador.  
+
+import.OIDmetadata:Especifica el elemento de metadato que contiene el identificador Ãºnico de documento, se usa con -OIDtype=assigned, .  
+
+import.saveas:Establece el fomato de archivo a generar.  
+
+import.out:Nombre de fichero o dispositivo para imprimir el estado de la salida.  
+
+import.params:[opciones] colecciÃ³n-nombre
+
+import.removeold:BorrarÃ¡ los contenidos antiguos del directorio archives.  
+
+import.removing_archives:Borrando el contenido actual del directorio archives...  
+
+import.removing_tmpdir:Borrando los contenidos del directorio "tmp" de la colecciÃ³n...  
+
+import.reversesort:Ordenar en orden inverso. Usado con la opciÃ³n -sortmeta.  
+
+import.site:Sitio en el cual encontrar la carpeta collect (para la instalaciÃ³n de Greenstone 3)  
+
+import.sortmeta:Ordena documentos alfabÃ©ticamente por metadatos para la construcciÃ³n. Los resultados de las bÃºsquedas booleanas se mostrarÃ¡n con este orden. Se desactivarÃ¡ si groupsize > 1. Puede usar una lista separada por comas para ordenar por mÃ¡s de un valor de metadato.  
+
+import.statsfile:Nombre de fichero o dispositivo para imprimir las estadÃ­sticas de importaciÃ³n.  
+
+import.stats_backup:ImprimirÃ¡ el stats en lugar de STDERR.
+
+import.verbosity:Controla la cantidad de output rendimiento. El 0=ninguno, 3=muchos.
+
+# -- schedule.pl --
+schedule.deleted:Borrado de la ejecuciÃ³n planificada de la colecciÃ³n  
+schedule.scheduled:Script de ejecuciÃ³n creado para la colecciÃ³n.  
+schedule.cron:ConfiguraciÃ³n de la ejecuciÃ³n planificada de la colecciÃ³n  
+schedule.params:[opciones]  
+schedule.error.email:-email requiere que se especifique -smtp -toaddr y -fromaddr  
+schedule.error.importbuild:Debe especificarse -import y -build.  
+schedule.error.colname:Debe especificarse la colecciÃ³n usando -colname  
+schedule.gli:Ejecutando desde el GLI  
+schedule.frequency:Con que frecuencia reconstruir automÃ¡ticamente la colecciÃ³n.  
+schedule.frequency.hourly:Reconstruir cada hora  
+schedule.frequency.daily:Reconstruir todos los dÃ­as  
+schedule.frequency.weekly:Reconstruir cada semana  
+schedule.action:CÃ³mo configurar reindexaciÃ³n automÃ¡tica.  
+schedule.action.add:Programar reindexaciÃ³n automÃ¡tica  
+schedule.action.update:Actualizar la programaciÃ³n existente  
+schedule.action.delete:Borrar la programaciÃ³n existente  
+schedule.email:Enviar notificaciÃ³n por email  
+schedule.schedule:Seleccionelo para configurar la reconstrucciÃ³n planificada automÃ¡tica de la colecciÃ³n  
+schedule.colname:El nombre de la colecciÃ³n para la cual se configurarÃ¡ la programaciÃ³n.  
+schedule.import:El comando import a ser programado  
+schedule.build:El comando buildcol a ser programado  
+schedule.toaddr:La direcciÃ³n de email a la cual enviar notificaciones de las construcciones programadas.  
+schedule.toaddr.default:Especifique el mail del usuario en el menÃº Archivo -> Preferencias  
+schedule.fromaddr:La direcciÃ³n de mail del emisor  
+schedule.fromaddr.default:Especificar el "maintainer" en el main.cfg.  
+schedule.smtp:El servidor de mail que "sendmail" contactarÃ¡ para hacer el envio.  
+schedule.smtp.default:Especifique "MailServer" en el main.cfg  
+schedule.out:archivo o dispositivo en el que imprimir el estado de salida.
+# -- export.pl --
+
+export.exportdir:LocalizaciÃ³n final del material exportado.
+
+export.cannot_open_stats_file:ATENCIÃN:No se puede abrir el archivo de estadÃ­sticas %s.
+
+export.cannot_open_fail_log:ERROR: No se puede abrir el registro de errores %s
+
+export.cannot_sort:ATENCIÃN: export.pl no puede ordenar los documentos cuando groupsize>1. Se ignorarÃ¡ la opciÃ³n sortmeta.
+
+export.collectdir:Ruta al directorio de la colecciÃ³n  
+
+export.complete:ExportaciÃ³n completa
+
+export.debug:Imprimir el texto exportado a STDOUT (para exportaciÃ³n GreenstoneXML)  
+
+export.desc:Script PERL usado para exportat ficheros de una colecciÃ³n Greenstone a otro formato.  
+
+export.faillog:Nombre de fichero del registro de fallos. Este registro contiene el nombre de cualquier fichero que falle al ser procesado.(Por definiciÃ³n: collectdir/collect/collname/etc/fail.log)  
+
+export.groupsize:NÃºmero de documentos a agrupar en un fichero XML.  
+
+export.gzip:Use gzip para comprimir los documentos xml resultantes (no olvide incluir ZIPPlugin en su lista de plugins cuando construya desde documentos comprimidos).  
+
+export.importdir:LocalizaciÃ³n del material original.
+
+export.keepold:No borrarÃ¡ el contenido actual del directorio export.  
+
+export.maxdocs:NÃºmero mÃ¡ximo de documentos a exportar.  
+
+export.listall:Lista todos los formatos a guardar  
+
+export.saveas:Formato al que exportar el documento.  
+
+export.saveas.DSpace:Formato de archivo DSpace.  
+
+export.saveas.GreenstoneMETS:Formato METS usando el perfil de Greenstone.  
+export.saveas.FedoraMETS:Formato METS usando el perfil de Fedora.  
+
+export.saveas.GreenstoneXML:Formato de archivo XML de Greenstone  
+
+export.saveas.MARCXML:Formato MARC XML (versiÃ³n XML del MARC 21)  
+
+export.out:archivo o dispositivo en el que imprimir el estado de salida.
+
+export.params:[opciones] nombre de colecciÃ³n  
+
+export.removeold:BorrarÃ¡ los contenidos previos del directorio export.  
+
+export.removing_export:Borrando los contenidos actuales del directorio exportâŠ
+
+export.sortmeta:Ordenar los documentos alfabÃ©ticamente por metadatos para construir. Se desactivarÃ¡ si groupsize > 1.
+
+export.statsfile:Fichero o dispositivo en el que imprimir las estadÃ­sticas de exportaciÃ³n.  
+
+export.stats_backup:ImrprimirÃ¡ las estadÃ­sticas en STDERR en su lugar.
+
+export.verbosity:Controla la cantidad de salida. 0=nada, 3=mucha.
+
+
+
+# -- mkcol.pl --
+
+mkcol.about:Sobre el texto para la colecciÃ³n.
+
+mkcol.bad_name_cvs:ERROR: Ninguna colecciÃ³n puede nombrarse CVS puesto que puede interferir con directorios creados por la versiÃ³n del sistema CVS.
+
+mkcol.bad_name_svn:ERROR: ninguna colecciÃ³n puede nombrarse como .svn ya que interfiere con directorios creados por el sistema de versionado SVN.  
+
+mkcol.bad_name_modelcol:ERROR: Ninguna colecciÃ³n puede nombrarse modelcol puesto que este es el nombre de la colecciÃ³n model
+
+mkcol.cannot_find_modelcol:ERROR: Ninguna colecciÃ³n puede nombrarse el modelcol puesto que este es el nombre del ejemplo de colecciÃ³n %s
+
+mkcol.col_already_exists:ERROR: Esta colecciÃ³n ya existe.
+
+mkcol.collectdir:Directorio dÃ³nde la nueva colecciÃ³n serÃ¡ creada.
+
+mkcol.group_not_valid_in_gs3:La opciÃ³n de grupo no es vÃ¡lida en modo Greenstone 3 (-gs3mode).  
+mkcol.creating_col:Creando la colecciÃ³n %s
+
+mkcol.creator:La direcciÃ³n de correo electrÃ³nico del creador de la colecciÃ³n.
+
+mkcol.creator_undefined:ERROR: El creador no fue definido. Esta variable se necesita reconocer los nombres duplicados de la colecciÃ³n.
+
+mkcol.desc:La escritura de PERL utilizada para crear la estructura del directorio para una nueva colecciÃ³n de Greenstone.
+
+mkcol.doing_replacements:realizando reemplazos %s
+
+mkcol.group:Crear un nuevo grupo de colecciones en vez de una colecciÃ³n estÃ¡ndar.  
+
+mkcol.gs3mode:Modo para colecciones de Greenstone 3.  
+
+mkcol.long_colname:ERROR: El nombre de la colecciÃ³n debe ser menor de 8 caracteres para que pueda mantenerse la compatibilidad con sistemas de ficheros anteriores.  
+
+mkcol.maintainer:La direcciÃ³n del correo electrÃ³nico de la persona que proporciona mantenimiento a la colecciÃ³n (si es diferente a la del creador).
+
+mkcol.no_collectdir:ERROR: El dir del coleccionador no existe: %s
+
+mkcol.no_collectdir_specified:ERROR: No se ha especificado la carpeta collect. En gs3mode, tanto la opciÃ³n -site o -collectdir debe ser especificada.  
+
+mkcol.no_colname:ERROR: NingÃºn nombre de la colecciÃ³n fue especificado.
+
+mkcol.optionfile:Reciba las opciones del archivo, Ãºtil en sistemas donde las lÃ­neas de orden largas pueden causar problemas.
+
+mkcol.params:[opciones] colecciÃ³n-nombre
+
+mkcol.plugin:El mÃ³dulo Perl plugin para usar (puede haber entradas mÃºltiples plugin).
+
+mkcol.public:Si esta colecciÃ³n tiene acceso anÃ³nimo.  
+mkcol.public.true:La colecciÃ³n es pÃºblica  
+mkcol.public.false:La colecciÃ³n es privada  
+
+mkcol.quiet:Opere de manera silenciosa
+
+mkcol.site:En gs3mode, usa el nombre del site con la variable de entorno GSDL3HOME para determinar el collectdir, a menos que se especifique -collectdir.  
+
+mkcol.success:La nueva colecciÃ³n se creada exitosamente a %s
+
+mkcol.title:El tÃ­tulo de la colecciÃ³n.
+
+mkcol.win31compat:Establece si el directorio de la colecciÃ³n indicada debe ser conforme a las convenciones de archivo de Windows 3.1 (ej.: longitud de 8 caracteres).
+mkcol.win31compat.true:Nombre del directorio, 8 caracteres o menos  
+mkcol.win31compat.false:Cualquier longitud de nombre del directorio  
+
+# -- pluginfo.pl --
+
+pluginfo.collection:Al dar un nombre a la colecciÃ³n realizarÃ¡ que un pluginfo.pl revise primero en el collect/collection-name/perllib/plugins. Si el plugin general no se encuentra allÃ­ que aparecerÃ¡ en el directorio del perllib/plugins.
+
+pluginfo.desc:Imprime informaciÃ³n sobre un plugin.
+
+pluginfo.general_options:Se toman las opciones generales de las clases paternal inicial del plugin.
+
+pluginfo.info:info
+
+pluginfo.no_plugin_name:ERROR: Usted debe proporcionar un nombre plug.
+
+pluginfo.option_types:Plugins podrÃ¡n tomar dos tipos de opciones
+
+pluginfo.params:[opciones] el nombre-plugin
+
+pluginfo.passing_options:Pueden pasarse las opciones a cualquier plugin incluyÃ©ndolos en su archivo de configuraciÃ³n collect.cfg.
+
+pluginfo.specific_options:Se definen las opciones especÃ­ficas dentro del propio plugin, y sÃ³lo estÃ¡n disponibles en este plugin en particular.
+
+
+# -- plugoutinfo.pl --
+
+plugoutinfo.collection:Dando un nombre de colecciÃ³n harÃ¡ que plugoutinfo.pl busque primero en collect/collection-name/perllib/plugouts. Si la salida no se encuentra allÃ­, buscarÃ¡ en el directorio general perllib/plugouts  
+
+plugoutinfo.desc:Muestra informaciÃ³n sobre la salida.  
+
+plugoutinfo.general_options:La opciones generales se heredan de las clases padres de la salida.  
+
+plugoutinfo.info:informaciÃ³n  
+
+plugoutinfo.no_plugout_name:ERROR: debe dar un nombre de salida.  
+
+plugoutinfo.option_types:La salidas pueden tomar dos tipos de opciones  
+
+plugoutinfo.params:[options] nombre de salida  
+
+plugoutinfo.passing_options:Las ocpiones pueden pasarse a cualquier salida incluyÃ©ndolas en el fichero de configuraciÃ³n collect.cfg.  
+
+plugoutinfo.specific_options:Las opciones especÃ­ficas se definen dentro de la propia salida, y sÃ³lo estÃ¡n disponibles para esta salida en particular.  
+
+
+
+#
+# Classifier option descriptions
+#
+
+AllList.desc:Crea una lista sencilla de todos los documentos. Usada por el servidor OAI.  
+
+AZCompactList.allvalues:Utilizar todos los valores de metadatos encontrados.  
+
+AZCompactList.desc:Plugin para clasificar por orden alfabÃ©tica (a-zA-Z0-9). Produce una lista horizontal A-Z, una lista vertical conteniendo los documentos, o estanterÃ­as para documentos con metadatos comunes.  
+
+AZCompactList.doclevel:Nivel para procesar el documento a
+AZCompactList.doclevel.top:Documento completo
+AZCompactList.doclevel.section:Por secciones
+
+AZCompactList.firstvalueonly:Utilizar Ãºnicamente el primer valor de metadato encontrado.  
+
+AZCompactList.freqsort:Clasificar por la frecuencia del nodo en lugar de alfa-numÃ©rico.
+
+AZCompactList.maxcompact:NÃºmero mÃ¡ximo de documentos que serÃ¡n desplegados por pÃ¡gina.
+
+AZCompactList.metadata:Un sÃ³lo campo de metadatos, o una lista de campos de metadatos separada por comas, utilizados para clasificaciÃ³n. Si se especifica una lista, serÃ¡ utilizado el primer tipo de metadatos que tenga valores. Puede utilizarse al tiempo con los parÃ¡metros -firstvalueonly y -allvalues, para seleccionar Ãºnicamente el primer valor o todos los valores de la lista.  
+
+AZCompactList.mincompact:NÃºmero mÃ­nimo de documentos que serÃ¡n desplegados por pÃ¡gina.
+
+AZCompactList.mingroup:El valor mÃ¡s pequeÃ±o que causarÃ¡ un grupo en formato jerÃ¡rquico
+
+AZCompactList.minnesting:El valor mÃ¡s pequeÃ±o que causarÃ¡ una lista a ser convertida en una lista anidada.
+
+AZCompactList.recopt:Usado en metadatos anidados como -metadato AÃ±o/OrganizaciÃ³n.
+AZCompactList.sort:Campo de metadatos por medio del cual ordenar los nodos anidados.  
+
+AZCompactSectionList.desc:VariaciÃ³n de AZCompactList que clasifica secciones en vez de documentos. Las entradas se ordenan por medio de metadatos a nivel de secciÃ³n.
+
+AZList.desc:Plugin clasificador alfabÃ©tico (a-zA-Z0-9). Produce una lista horizontal A-Z, con los documentos listado debajo.  
+
+AZList.metadata:Un solo campo de metadatos o una lista de campos de metadatos separados por una coma y usados con fines de clasificaciÃ³n. Siguiendo el orden indicado por la lista, se utilizarÃ¡ el primer campo que contiene un valor. La lista se ordenarÃ¡ de acuerdo a este elemento.  
+
+AZSectionList.desc:VariaciÃ³n de AZList que clasifica secciones antes que documentos. Las entradas se ordenan por metadatos de nivel de secciÃ³n.  
+
+BasClas.bad_general_option:El clasificador %s utiliza una opciÃ³n incorrecta. Revise su archivo de configuraciÃ³n collect.cfg.  
+
+BasClas.builddir:En dÃ³nde poner los Ã­ndices construidos.
+
+BasClas.buttonname:Etiqueta para la pantalla del clasificador y para el botÃ³n de la barra de navegaciÃ³n. Por definiciÃ³n, se usa el elemento de metadato espcificado con -metadata.  
+
+BasClas.desc:Clase base para todos los clasificadores.
+
+BasClas.no_metadata_formatting:No hacer ningÃºn formateo automÃ¡tico de metadatos (para ordenaciÃ³n)  
+
+BasClas.outhandle:El fichero o dispositivo donde escribir la salida.  
+
+BasClas.removeprefix:Un prefijo que al clasificar se debe ignorar en los valores de los metadatos.
+
+BasClas.removesuffix:Un sufijo que al clasificar se debe ignorar en los valores de los metadatos.
+
+BasClas.verbosity:Controla la cantidad de (output) rendimiento. 0=ninguno, 3=muchos.
+
+Browse.desc:Clasificador falso que ofrece un enlace en la barra de navegaciÃ³n a un prototipo de pÃ¡gina que combina bÃºsqueda y exploraciÃ³n. SÃ³lo funciona con colecciones de MGPP, y sÃ³lo es Ãºtil para pequeÃ±as colecciones.  
+
+DateList.bymonth:Clasificar por aÃ±o y mes en vez de sÃ³lo aÃ±o.
+
+DateList.desc:Plugin clasificador que ordena por fecha. El metadato predefinido para ordenar es 'Date/Fecha'. Se asume que la fecha estÃ¡ en formato aaaammdd o aaa-mm-dd.  
+
+DateList.metadata:El metadato que contiene las fechas para clasificar. Se espera que el formato sea el aaaammdd o aaa-mm-dd. Puede ser una lista separada por comas, en cuyo caso se usarÃ¡   la primera fecha encontrada.  
+
+DateList.reverse_sort:Ordenar los documentos en orden cronolÃ³gico inverso (el mÃ¡s nuevo al comienzo).
+
+DateList.nogroup:Haga de cada aÃ±o una entrada individual en la lista horizontal, en vez de extender los aÃ±os con pocas entradas. (Esto tambiÃ©n se puede usar con la opciÃ³n -bymonth para hacer que cada mes tenga una entrada separada en vez de combinarlas).
+
+DateList.no_special_formatting:No mostrar informaciÃ³n de AÃ±o ni Mes en la lista de documentos.  
+
+DateList.sort:Un campo de metadato extra para ordenar en el caso de que dos documentos tengan la misma fecha.  
+
+HFileHierarchy.desc:Plugin clasificador para generar clasificaciones jerÃ¡rquicas basadas en una estructura existente en un archivo suplementario.
+
+Hierarchy.desc:Plugin clasificador para generar una clasificaciÃ³n jerÃ¡rquica. Ãsta debe basarse en metadatos estructurados, o debe usar un fichero suplementario de estructura (usar la opciÃ³n -hfile)  
+
+Hierarchy.documents_last:Muestra nodos de documento despÃºes de los nodos de clasificadores.  
+
+Hierarchy.hfile:Usa el fichero de estructura de clasificaciÃ³n especificado.  
+
+Hierarchy.hlist_at_top:Despliega el primer nivel de clasificaciÃ³n horizontalmente
+
+Hierarchy.reverse_sort:Ordenar hojas de nodos en orden inverso (usar con -sort).
+
+Hierarchy.separator:ExpresiÃ³n regular utilizada por el separador
+
+Hierarchy.sort:Campo de metadato para clasificar nodos anidados. Los dejarÃ¡ sin clasificar si no se indica.  
+
+Hierarchy.suppressfirstlevel:Ignorar la primera parte del valor del metadato. Esto es Ãºtil para metadatos en los cuales el primer valor es comÃºn, como el directorio de importaciÃ³n en gsdlsourcefilename.  
+
+Hierarchy.suppresslastlevel:Ignorar la parte final del valor del metadato. Es Ãºtil para metadatos en los cuales cada valor es Ãºnico, como en la rutas de archivos.
+
+HTML.desc:Crea una clasificaciÃ³n vacÃ­a que simplemente es un link a una pÃ¡gina web.
+
+HTML.url:El url de la pÃ¡gina web para unirse a.
+
+List.bookshelf_type:Controla cuando crear estantes  
+List.bookshelf_type.always:Crea un Ã­cono de estante aun cuando haya en cada grupo un Ãºnico nodo hijo.  
+List.bookshelf_type.never:Nunca crear un icono de estante aun cuando existan mÃ¡s de un item en cada grupo.  
+List.bookshelf_type.duplicate_only:Crea un Ã­cono de estante solo cuando haya mÃ¡s de un nodo hijo en cada grupo.  
+
+List.classify_sections:Clasifica secciones en lugar de documentos.  
+
+List.desc:Clasificador de lista general y flexible con muchas de las posibilidades de AZCompactList, pero con mejor capacidad de ordenaciÃ³n, metadatos y Unicode.
+  
+List.level_partition.per_letter:Crear una particiÃ³n para cada letra.  
+List.level_partition.constant_size:Crear particiones de tamaÃ±o constante  
+List.level_partition.per_letter_fixed_size:Crear una particiÃ³n por letra con un tamaÃ±o fijo aproximado.  
+
+List.metadata:Campos de metadatos usados para la clasificaciÃ³n. Use '/' para separar los niveles de la jerarquÃ­a y ';' para separar los campos de metadatos dentro de cada nivel.  
+
+List.partition_name_length:Longitud del nombre de la particiÃ³n: el valor predefinido es una variable entre 1 y 3 caracteres, dependiendo de cuÃ¡ntos son necesarios para distinguir el principio de la particiÃ³n de su final. Esta opciÃ³n sÃ³lo se aplica cuando partition_type_within_level se marca como 'constant_size'.  
+
+List.partition_size_within_level:NÃºmero de elementos en cada particiÃ³n (sÃ³lo se aplica cuando partition_type_within_level se establece a 'constant_size').  
+
+List.partition_type_within_level:Tipo de particiÃ³n hecha: puede ser 'per_letter', 'constant_size' o 'none'.  
+
+List.sort_leaf_nodes_using:Campos de metadatos usados para ordenar los nodos anidados. Use '|' para separar los grupos de metadatos para ordenaciÃ³n estable y ';' para separar campos de metadatos dentro de cada grupo.  
+
+List.sort_using_unicode_collation:Ordenar usando el algoritmo Unicode. Requiere que se descargue el archivo http://www.unicode.org/Public/UCA/latest/allkeys.txt en la carpeta lib/unicode/Collate de Perl.  
+
+List.use_hlist_for:Campos de metadato para usar una hlist mejor que una vlist. Use ',' para separar los grupos de metadatos y ';' para separar los campos de metadatos dentro de cada grupo.  
+
+SimpleList.metadata:Un solo campo de metadatos o una lista de campos de metadatos separados por una coma y usados para clasificaciÃ³n. Siguiendo el orden indicado por la lista, se usarÃ¡ el primer campo que contiene un valor de metadato. La lista se ordenarÃ¡ por este elemento, a menos que se use -sort. Si no se especifica metadato, entonces todos los documentos se incluirÃ¡n en la lista, en otro caso sÃ³lo se incluirÃ¡n aquellos documentos que contengan un valor de metadato.  
+
+SimpleList.desc:Plugin clasificador para lista simple.  
+
+SimpleList.sort:Campo de metadato a partir del cual se harÃ¡ la ordenaciÃ³n. Use '-sort nosort' para no ordenar.  
+
+Phind.desc:Produce una jerarquÃ­a de las frases encontradas en el texto, que es mostrada mediante un applet.  
+
+Phind.language:Idioma o idiomas utilizados para construir una jerarquÃ­a. Los idiomas son identificados por un cÃ³digo de paÃ­s de dos letras: en (inglÃ©s), es (espaÃ±ol), y fr (francÃ©s). El lenguaje es una expresiÃ³n normal, de modo que 'en|fr' (inglÃ©s o francÃ©s) y '.. ' (iguala cualquier idioma) son vÃ¡lidos.
+
+Phind.min_occurs:MÃ­nimo nÃºmero de veces que debe aparecer una frase en el texto para que sea incluida en la jerarquÃ­a de frases.
+
+Phind.savephrases:Si estÃ¡ marcado, la informaciÃ³n de la frase se guardarÃ¡ en el fichero dado como texto. Probablemente es una buena idea utilizar una ruta absoluta.  
+
+Phind.suffixmode:El parÃ¡metro smode para el programa de extracciÃ³n de frase. Un valor de 0 significa que los stopwords serÃ¡n ignorados, y 1 significa que los stopwords serÃ¡n utilizadas.
+
+Phind.text:El texto utilizado para construir la jerarquÃ­a de la frase.
+
+Phind.thesaurus:El nombre de un thesaurus guardado en formato Phind en el directorio etc de la colecciÃ³n.
+
+Phind.title:Campo del metadato usado para describir cada documento.  
+
+Phind.untidy:No elimine los archivos activos.
+
+RecentDocumentsList.desc:Clasificador que ofrece una lista de documentos nuevos aÃ±adidos o modificados.  
+
+RecentDocumentsList.include_docs_added_since:Incluye sÃ³lo documentos aÃ±adidos o modificados despuÃ©s de la fecha indicada (en formatos aaaammdd o aaaa-mm-dd)  
+
+RecentDocumentsList.include_most_recently_added:Incluye sÃ³lo el nÃºmero indicado de los documentos aÃ±adidos mÃ¡s recientemente. SÃ³lo usado si no se indica include_docs_added_since.  
+
+RecentDocumentsList.sort:Metadato pro el cual ordenar la Lista por. Si no se indica, la lista se ordenarÃ¡ por la fecha de entrada/modificaciÃ³n.  
+
+SectionList.desc:Igual que el clasificador de la lista pero incluye todas las secciones del documento (excluyendo el nivel superior) y no sÃ³lo el propio documento del nivel superior.
+
+Collage.desc:Applet usado para mostrar un collage de imÃ¡genes encontradas en la colecciÃ³n.  
+
+Collage.geometry:Las dimensiones del lienzo del collage. Para un lienzo de 600 pixels de ancho y 400 pixels de alto, por ejemplo, especifique la geometrÃ­a como 600x400
+
+Collage.maxDepth:Las imÃ¡genes para el collage se dibujan mediante un espejo del clasificador de navegaciÃ³n subyacente. Esto controla la profundidad mÃ¡xima del proceso de espejo.
+
+Collage.maxDisplay:El mÃ¡ximo nÃºmero de imÃ¡genes a mostrar en el collage en cualquier momento.
+
+Collage.imageType:Utilizado para controlar, empleando las extensiones del nombre de fichero, que tipos de fichero se utilizan en el collage. Una lista de las extensiones del nombre de archivo se separa con el sÃ­mbolo (%%).  
+
+Collage.bgcolor:El color de fondo del lienzo del collage, especificado en hexadecimal (por ejemplo, #008000 produce un fondo verde bosque).
+
+Collage.buttonname:Etiqueta para clasificador de pantalla y botÃ³n en la barra de navegaciÃ³n.
+
+Collage.refreshDelay:Rata, en milisegundos, de refresco del lienzo del collage.
+
+Collage.isJava2:Utilizado para controlar cuales clases del run-time de Java se usan. Las versiones mÃ¡s avanzadas de Java (desde Java 1.2 en adelante) incluyen un soporte mas sofisticado para controlar la transparencia de las imÃ¡genes. Esta bandera ayuda a controlar los que pasa, sin embargo, el run-time de Java integrado con algunos navegadores es versiÃ³n 1.1. El applet estÃ¡ disÃ±ado, por defecto, para auto-detectar cual versiÃ³n de Java estÃ¡ utilizando el navegador y actuar en conformidad.
+
+Collage.imageMustNotHave:Utilizado para suprimir las imÃ¡genes que no deben aparecer en el collage, tales como las imÃ¡genes de los botones que forman la barra de navegaciÃ³n.
+
+Collage.caption:TÃ­tulos opcionales para desplegar bajo el lienzo del collage.
+
+
+#
+# Plugin option descriptions
+#
+AcronymExtractor.adding:agregando
+
+AcronymExtractor.already_seen:ya ha sido visto
+
+AcronymExtractor.desc:Conector asistente para la localizaciÃ³n y el marcado de acrÃ³nimos en el texto.  
+
+AcronymExtractor.done_acronym_extract:terminÃ³ de extraer las siglas.
+
+AcronymExtractor.done_acronym_markup:TerminÃ³ el marcado de sigla (o acrÃ³nimo).
+
+AcronymExtractor.extract_acronyms:Extrae las siglas que contiene el texto y las coloca como metadato.  
+
+AcronymExtractor.extracting_acronyms:extrayendo siglas
+
+AcronymExtractor.marking_up_acronyms:marcando siglas
+
+AcronymExtractor.markup_acronyms:Agregue el metadato de sigla en el texto del documento.
+
+ArchivesInfPlugin.desc:Plugin que reproduce a travÃ©s de un archivo de archivos.inf file (es decir el archivo generado en el directorio de archivos cuando realiza una importaciÃ³n), procesando cada archivo que encuentra.
+
+AutoExtractMetadata.desc:Conector base que agrupa todas las funcionalidades de extracciÃ³n de los conectores de extracciÃ³n.  
+
+AutoExtractMetadata.extracting:extrayendo
+
+AutoExtractMetadata.first:Lista, separada por comas, de los primeros tamaÃ±os para extraer del texto en un campo de metadato. El campo se llama 'FirstNNN'.  
+
+BaseMediaConverter.desc:Conector que provee funcionalidad bÃ¡sica para los conectores conversores de media como el ImageConverter y los conversores de video.  
+
+BasePlugin.associate_ext:Hace que los ficheros cuyos nombres contienen la misma parte inicial que el documento procesado por el plugin y una extensiÃ³n que figura en la lista separada por comas que provee este argumento, sean asociados con el documento que se estÃ¡ procesando en vez de ser manejados como una lista separada.  
+
+BasePlugin.associate_tail_re:Una expresiÃ³n regular para cotejar con los nombres de archivos y encontrar los archivos asociados.  
+
+BasePlugin.block_exp:Los ficheros que sean iguales a esta expresiÃ³n regular serÃ¡n bloqueados para no pasarse a cualquier plugin posterior en el listado. Esto no tiene otro efecto real mas que prevenir muchos mensajes de alerta sobre los archivos de entrada que a usted no le interesen. Cada plugin podrÃ­a tener un block_exp predefinido, por ej., por definiciÃ³n HTMLPlug bloquea cualquier archivo gif. jpg. jpeg. png o los archivos css.  
+
+BasePlugin.desc:La clase base para todos los plugins de importaciÃ³n.
+
+BasePlugin.dummy_text:Este documento no tiene contenido.
+
+BasePlugin.encoding.ascii:Conjunto de 7 bits ascii simples. Ãste puede resultar mÃ¡s rÃ¡pido que usando el iso_8859_1. Tenga cuidado con usar esto en una colecciÃ³n de documentos que pueden contener caracteres fuera de los 7 ascii simples (por ejemplo documentos en AlemÃ¡n o FrancÃ©s que contengan acentos), mejor utilice el iso_8859_1.
+
+BasePlugin.encoding.unicode:SÃ³lo unicode.
+
+BasePlugin.encoding.utf8:Ya sea Utf8 o unicodeâdetectada automÃ¡ticamente
+
+BasePlugin.filename_encoding:La codificaciÃ³n de los nombres de archivos de origen.  
+
+BasePlugin.filename_encoding.auto:Detectar automÃ¡ticamente la codificaciÃ³n del nombre de archivo.  
+
+BasePlugin.filename_encoding.auto_language_analysis:Auto detectar la codificaciÃ³n analizando el nombre de archivo.  
+
+BasePlugin.filename_encoding.auto_filesystem_encoding:Auto detectar la codificaciÃ³n del nombre de archivo usando la codificaciÃ³n del filesystem.  
+
+BasePlugin.filename_encoding.auto_fl:Utiliza la codificaciÃ³n del filesystem y luego anÃ¡lisis de idioma para detectar la codificaciÃ³n del nombre de archivo.  
+
+BasePlugin.filename_encoding.auto_lf:Utilizar anÃ¡lisis de idioma y luego codificaciÃ³n del filesystem para detectar la codificaciÃ³n del nombre de archivo.  
+
+BasePlugin.no_blocking:No hacer bloqueo de archivos. Cualquier archivo asociado (ej. ImÃ¡genes en una pÃ¡gina web) serÃ¡ agregado a la colecciÃ³n como documentos separados.  
+
+BasePlugin.no_cover_image:No buscar un archivo prefix.jpg (en el cual prefix es el mismo prefix que el del archivo que estÃ¡ siendo procesado) y asociarlo como imagen de portada.
+
+BasePlugin.OIDtype.auto:Usar OIDType definido en import.pl  
+
+BasePlugin.process_exp:Una expresiÃ³n Perl regular para comprobar contra nombres de ficheros que se procesarÃ¡n por este plugin. Por ej., usando '(? i). html? \ $' aparecerÃ¡n todos los documentos con terminaciÃ³n. htm .html (no es sensible a mayÃºsculas/minÃºsculas).  
+
+BasePlugin.smart_block:Ablocar los archivos en una forma mÃ¡s inteligente que simplemente examinando sus nombres.
+
+BasePlugin.stems:tallos (inicios, bases)
+
+BasePlugin.file_rename_method:El mÃ©todo a utilizarse para renombrar la copia de los archivos importados y asociados.  
+
+BasePlugin.rename_method.url:Usar codificaciÃ³n de URL al renombrar archivos importados y asociados.  
+
+BasePlugin.rename_method.base64:Usar codificaciÃ³n base64 para renombrar archivos importados y asociados.  
+
+BasePlugin.rename_method.none:No renombrar archivos importados y asociados.  
+
+BibTexPlugin.desc:BibTexPlugin lee archivos de bibliografÃ­a en el formato de BibTex. BibTexPlugin crea un objeto de documento para cada referencia en el archivo. Es una subclase de SplitTextFile, por lo que si hay registros mÃºltiples, todos se leen.  
+
+BookPlugin.desc:Crea documentos multinivel a partir de documentos que contengan etiquetas de nivel <<TOC>>. Los metadatos para cada secciÃ³n se toman de cualquier otra etiqueta que estÃ© en la misma lÃ­nea que el << TOC >>, por ej., <<Title>> xxxx <</Title>> establece el metadato TÃ­tulo. Todo lo demÃ¡s que aparezca entre las etiquetas TOC se tratarÃ¡ como html simple (es decir, no se establece ningÃºn proceso de vÃ­nculos html ni se ejcuta ninguna otra tarea del conector HTMLPlugin). Se espera que los archivos de entrada tengan una extensiÃ³n .hb  predefinida (puede cambiarse agregando una opciÃ³n -process_exp, un fichero con el mismo nombre que el fichero hb pero con una extensiÃ³n .jpg se toma como la imagen de la portada (los ficheros jpg son bloqueados por este plugin). BookPlugin es una simplificaciÃ³n (y extensiÃ³n) del HBPlugin utilizado por las colecciones de la Biblioteca de la Humanidad. BookPlugin es mÃ¡s rÃ¡pido en tanto que espera la entrada de archivos mÃ¡s limpios (La entrada a las colecciones de HDL contiene muchas etiquetas html adicionales alrededor de etiquetas << TOC >>, utiliza etiquetas << I >> para especificar las imÃ¡genes, y simplemente toma todo el texto entre las etiquetas << TOC >> y el inicio del texto como metadato Title). Si usted estÃ¡ colocando marcas en documentos para que sean desplegados de la misma manera que las colecciones HDL, use este plugin en lugar de HBPlugin.  
+
+CONTENTdmPlugin.desc:Conector que procesa archivos RDF en colecciones CONTENTdm exportadas.  
+
+ConvertBinaryFile.apply_fribidi:Ejecutar el programa del Algoritmo Bidireccional Unicode "fribidi" sobre el fichero convertido (para textos escritos de derecha a izquierda).  
+
+ConvertBinaryFile.convert_to:Plugin que convierte a TEXTO o a HTML o a varios tipos de imagen (ej. JPEG, GIF, PNG).  
+
+ConvertBinaryFile.convert_to.auto:Selecciona automÃ¡ticamente el formato convertido. La elecciÃ³n del formato depende del tipo de documento importado, por ejemplo, Word serÃ¡ automÃ¡ticamente convertido a HTML, mientras que PowerPoint serÃ¡ convertido al formato PagedImage de Greenstone  
+
+ConvertBinaryFile.convert_to.html:Formato HTML
+
+ConvertBinaryFile.convert_to.text:Formato texto simple.
+
+ConvertBinaryFile.convert_to.pagedimg:Una serie de imÃ¡genes.  
+
+ConvertBinaryFile.convert_to.pagedimg_jpg:Formato JPEG.  
+
+ConvertBinaryFile.convert_to.pagedimg_gif:Formato GIF.  
+
+ConvertBinaryFile.convert_to.pagedimg_png:Formato PNG.  
+
+ConvertBinaryFile.desc:Este conector es heredado por otros como WordPlugin, PowerPointPlugin, PostScriptPlugin, RTFPlugin y PDFPlugin. Facilita la conversiÃ³n de Ã©stos tipos de documentos a HTML o a TEXTO o a una serie de imÃ¡genes. Funciona cargando dinÃ¡micamente un conector secundario apropiado (HTMLPlugin, StructuredHTMLPlugin, PagedImgPlugin o TEXTPlugin), segÃºn el argumento 'convert_to'.  
+
+ConvertBinaryFile.keep_original_filename:mantener el nombre de fichero original para el fichero asociado, antes que convertirlo a doc.pdf, pdf.pdf, etc.  
+
+ConvertBinaryFile.use_strings:Si estÃ¡ definido, una funciÃ³n de cadenas simple serÃ¡ llamada para extraer el texto si la conversiÃ³n de utilidad falla.
+
+ConvertToRogPlugin.desc:Un plugin que hereda de RogPlugin.  
+
+CSVPlugin.desc:Plugin para ficheros con valores separados por comas. Se crearÃ¡ un nuevo documento para cada lÃ­nea del fichero.  
+
+DateExtractor.desc:Conector asistente para la extracciÃ³n de informaciÃ³n de fechas histÃ³ricas desde el texto.  
+
+DateExtractor.extract_historical_years:Extrae informaciÃ³n periÃ³dica de documentos histÃ³ricos. Se guarda como metadato con el documento. Existe una interfaz de bÃºsqueda para este metadato, que se puede incluir en la colecciÃ³n agregando la expresiÃ³n âformat QueryInterface DateSearchâ al fichero de configuraciÃ³n de la colecciÃ³n.  
+
+DateExtractor.maximum_century:El nÃºmero mÃ¡ximo de siglo que serÃ¡ extraÃ­do como metadato histÃ³rico (por ej., 14 extraerÃ¡ todas las referencias hasta el siglo XIV).  
+
+DateExtractor.maximum_year:La fecha histÃ³rica mÃ¡xima a ser usada como metadato (en una fecha referida la era comÃºn, como 1950).  
+
+DateExtractor.no_bibliography:No intente bloquear las fechas bibliogrÃ¡ficas al extraer las fechas histÃ³ricas.
+
+DirectoryPlugin.desc:RecPlug es un plugin que recorre el Ã¡rbol de directorios recursivamente, procesando cada fichero encontrado.  
+
+DirectoryPlugin.recheck_directories:DespuÃ©s de procesar los archivos en un directorio de importaciÃ³n, vuelva a leer el directorio para descubrir los nuevos archivos creados.
+
+DirectoryPlugin.use_metadata_files:SUSTITUIDO - AÃ±adir MetadataXMLPlugin a la lista de plugins para que se puedan leer los metadatos desde los archivos XML de metadatos.
+
+DatabasePlugin.desc:Conector que importa registros de una base de datos. Usa el mÃ³dulo Perl DBI, que incluye soporte para mysql, postgresql, valores separados por comas (CSV), MS Excel, ODBC, sybase, etc... Pueden necesitarse mÃ³dulos extra para su uso. VÃ©ase <GSDLHOME>/etc/packages/example.dbi para un ejemplo de uso.  
+
+DSpacePlugin.desc:DSpacePlug toma una colecciÃ³n de documentos exportados desde DSpace y los importa a Greenstone.  
+	
+DSpacePlugin.first_inorder_ext:Esto se usa para identificar la primera corriente del documento de la colecciÃ³n de DSpace.  Con esta opciÃ³n, el sistema tratarÃ¡ los tipos de documentos ext definidos secuencialmente, buscando la posible corriente primaria.  
+
+DSpacePlugin.first_inorder_mime:Se usa para identificar la corriente de datos primarios de un documento de una colecciÃ³n DSpace. Con esta opciÃ³n, el sistema tratarÃ¡ los tipos de documento mime definidos secuencialmente para buscar la corriente primaria posible.  
+
+DSpacePlugin.only_first_doc:Se usa para identificar la corriente de datos primaria de un documento de una colecciÃ³n DSpace. Con esta opciÃ³n, el sistema tratarÃ¡ el primer documento en el fichero de metadatos dublic_core como la corriente primaria posible.  
+
+EmailAddressExtractor.desc:Conector asistente para el descubrimiento de direcciones de mail en el texto.  
+
+EmailAddressExtractor.done_email_extract:terminÃ³ de extraer las direcciones electrÃ³nicas.
+
+EmailAddressExtractor.extracting_emails:extrayendo direcciones electrÃ³nicas
+
+EmailAddressExtractor.extract_email:Extrae direcciones de correo electrÃ³nico como metadatos.  
+
+EmailPlugin.desc:El plugin del correo electrÃ³nico lee ficheros de correo electrÃ³nico.  Ãstos se nombran con un nÃºmero simple (por ej. cuando aparecen en las carpetas del maildir) o con la extensiÃ³n. mbx (formato de fichero mbox). \ntexto del documento: El texto del documento consiste en todo el texto despuÃ©s de la primera lÃ­nea en blanco. \nMetadato (Â¡no DublÃ­n Core!):\n\t\$Headers Todo el contenido de la cabecera (opcional, no se almacenan si no se indica)\n\t\$Asunto  Asunto:  cabecera\n\t\$To/A: cabecera\n\t\$From/De: la cabecera\n\t\$From/Name Nombre del remitente (cuando estÃ© disponible)\n\t\$FromAddr direcciÃ³n del remitente\n\t\$DateText   Fecha: cabecera\n\t\$Date Fecha: ecabecera en formato GSDL (por ej. 19990924)  
+
+EmailPlugin.no_attachments:No guarde los anexos del mensaje.
+
+EmailPlugin.headers:Almacenar encabezados de email como metadatos "Headers".
+
+EmailPlugin.OIDtype.message_id:Usar el identificador de mensaje como el OID del documento. Si no se encuentra un indentificador, entonces se usarÃ¡ un OID hash.  
+
+EmailPlugin.split_exp:Un expresiÃ³n regular de Perl se utiliza para separar archivos que contengan muchos mensajes en documentos individuales.  
+
+ExcelPlugin.desc:Plugin para importar ficheros de Microsoft Excel (versiones 95 y 97).  
+
+FavouritesPlugin.desc:Conector para procesar archivos Favoritos de Internet Explorer.  
+
+FOXPlugin.desc:Plugin para procesar un archivo Foxbase dbt. Este plugin proporciona la funcionalidad bÃ¡sica para leer los archivos dbt y dbf y procesa cada registro. Este plugin generales debe doblemente leÃ­do para una base de datos particular para procesar los campos apropiados en el archivo.
+
+GreenstoneXMLPlugin.desc:Procesa los documentos XML de Archivo de Greenstone. Note que este conector no realiza ninguna verificaciÃ³n de sintaxis (aunque el mÃ³dulo de XML::Parser comprueba la correcta forma). Se asume que los ficheros de Archivo de Greenstone son conformes a su DTD.  
+
+GISExtractor.desc:Clase base paralela a BasPlug que soporta capacidades de GIS
+
+GISExtractor.extract_placenames:Extraer del texto nombres de lugares y establecerlos como metadatos. Requiere la extensiÃ³n GIS de Greenstone.  
+
+GISExtractor.gazetteer:Ãndice geogrÃ¡fico para extraer del texto nombres de lugares y establecerlos como metadatos. Requiere la extensiÃ³n GIS de Greenstone.  
+
+GISExtractor.place_list:Al extractar ubicaciones, incluya la lista de nombres de lugares al comienzo del documento. Requiere extensiÃ³n de Greenstone a GIS.
+
+HBPlugin.desc:Plugin que procesa un directorio de libro HTML. Este plugin se usa por las colecciones de la Biblioteca de Humanidades y no se ocupa de codificaciones de la entrada mas que de ascii o el ascii extendido. Este cÃ³digo es algo pesado y podrÃ­a hacerse correr mÃ¡s rÃ¡pidamente indudablemente, dejÃ¡ndolo en este estado espero animar a las personas para hagan sus colecciones utilizando el BookPlugin en cambio ;-)\n\nUse utilice BookPlugin si estÃ¡ creando una nueva colecciÃ³n y marcando a los archivos como las colecciones de la Biblioteca de Humanidades. BookPlugin acepta todas las codificaciones de entrada pero espera los archivos marcados sean mas limpios que aquellos usados por las colecciones de la Biblioteca de Humanidades
+
+HBPlugin.encoding.iso_8859_1:Latin1 (idiomas occidentales)  
+
+HTMLImagePlugin.aggressiveness:El rango de tÃ©cnicas de extracciÃ³n de textos relacionados a utilizar.
+HTMLImagePlugin.aggressiveness.1:Nombre de Archivo, ruta, ALT sÃ³lo texto.
+HTMLImagePlugin.aggressiveness.2:Todos de 1, mÃ¡s el subtÃ­tulo si hubiese disponible.
+HTMLImagePlugin.aggressiveness.3:Todos de 2, mÃ¡s los pÃ¡rrafos disponibles.
+HTMLImagePlugin.aggressiveness.4:Todos de 3, mÃ¡s los encabezados anteriores (<h1>, <h2>...) disponibles.
+HTMLImagePlugin.aggressiveness.5:Todos de 4, mÃ¡s las referencias textuales disponibles.
+HTMLImagePlugin.aggressiveness.6:Todos de 4, mÃ¡s la metaetiqueta de la pÃ¡gina (tÃ­tulo, las palabras clave, etc).
+HTMLImagePlugin.aggressiveness.7:Todos de 6, 5 y 4 combinados.
+HTMLImagePlugin.aggressiveness.8:Todos de 7, mÃ¡s la repeticiÃ³n de subtÃ­tulo, el nombre del archivo, etc (la clasificaciÃ³n jerÃ¡rquica de resultados mÃ¡s relevantes).
+HTMLImagePlugin.aggressiveness.9:Todos de 1, mÃ¡s el texto completo de la pÃ¡gina fuente.
+
+HTMLImagePlugin.caption_length:La longitud mÃ¡xima de subtÃ­tulos (en caracteres).
+
+HTMLImagePlugin.convert_params:ParÃ¡metros adicionales para la que ImageMagicK convierta el Ã­cono. Por ejemplo, '-raise' darÃ¡ un efecto tridimensional a las imÃ¡genes en miniatura.
+
+HTMLImagePlugin.desc:Plugin para extraer imÃ¡genes y el texto asociado de pÃ¡ginas web.
+
+HTMLImagePlugin.document_text:Agrega el texto de imagen como document:text (de lo contrario el campo de metadatos IndexedText).  
+
+HTMLImagePlugin.index_pages:Indice las pÃ¡ginas junto con las imÃ¡genes. Por otra parte referencia las pÃ¡ginas a la fuente URL.
+
+HTMLImagePlugin.max_near_text:Caracteres mÃ¡ximos cerca de las imÃ¡genes a extraer.
+
+HTMLImagePlugin.min_height:Pixeles. Salta las imÃ¡genes mÃ¡s pequeÃ±as que Ã©sta.
+
+HTMLImagePlugin.min_near_text:Caracteres mÃ­nimos cerca del texto o subtitulo para extraer.
+
+HTMLImagePlugin.min_size:Bytes. Brinca las imÃ¡genes mÃ¡s pequeÃ±as que estas.
+
+HTMLImagePlugin.min_width:Pixeles. Salta imÃ¡genes mas breves que Ã©sta.
+
+HTMLImagePlugin.neartext_length:Longitud designada del texto mas cercano (en caracteres)
+
+HTMLImagePlugin.no_cache_images:No esconda las imÃ¡genes (apunte al URL original).
+
+HTMLImagePlugin.smallpage_threshold:Las imÃ¡genes en las pÃ¡ginas mÃ¡s pequeÃ±as que esto (bytes) tendrÃ¡n asignados los metadatos de la pÃ¡gina (el tÃ­tulo, las palabras claves, etc).  
+
+HTMLImagePlugin.textrefs_threshold:El umbral para las referencias textuales. Los valores mÃ¡s bajos significan que el algoritmo es menos estricto.
+
+HTMLImagePlugin.thumb_size:Max el tamaÃ±o en miniatura. Ambos ancho y altura.
+
+HTMLPlugin.assoc_files:ExpresiÃ³n Perl normal de las extensiones de archivo para asociar con documentos html.
+
+HTMLPlugin.desc:Este plugin procesa archivos HTML
+
+HTMLPlugin.description_tags:Divide el documento en sub-secciones segÃºn aparecen las etiquetas <Section>.  '-keep_head' no tendrÃ¡ efecto cuando esta opciÃ³n estÃ© marcada.  
+
+HTMLPlugin.extract_style:Extrae  informaciÃ³n de estilo y de script de la etiqueta >head> de HTML y la guarda como metadato DocumentHeader. Se establece en la pÃ¡gina de documento como _document:documentheader_ macro.  
+
+HTMLPlugin.file_is_url:Marque si los nombres de los ficheros de la entrada constituyen el url de los documentos fuente originales, por ej. si una herramienta para descargar pÃ¡ginas web fuera utilizada para crear la estructura del directorio de importaciÃ³n.  
+
+HTMLPlugin.hunt_creator_metadata:Localiza tantos metadatos como sea posible en autor y los coloca en el campo 'Creator'.  
+
+HTMLPlugin.keep_head:No elimine los tÃ­tulos de los archivos html.
+
+HTMLPlugin.metadata_fields:Listado de campos de metadatos separados por comas para intentar extraer. Use 'tag<tagname>' para tener los contenidos del primer par <tagname> en un elemento del metadato llamado 'tagname' (nombre de etiqueta). Ponga en mayÃºsculas esto si desea el metadato en mayÃºsculas en Greenstone, ya que la extracciÃ³n de la etiqueta no tiene la capacidad para hacerlo.  
+
+HTMLPlugin.no_metadata:No intente extraer metadatos de los archivos.  
+
+HTMLPlugin.no_strip_metadata_html:Lista de nombres de metadatos separados por comas o 'all'. Utilizado con -description_tags, evita la supresiÃ³n de las etiquetas HTML de los valores de los metadatos especificados.
+
+HTMLPlugin.nolinks:No se esfuerce por tomar links (poniendo esta bandera puede mejorar la velocidad para crear/importar pero cualquier link relativo dentro de los documentos se romperÃ¡).
+
+HTMLPlugin.no_image_links:No hacer ningÃºn intento para capturar links a imÃ¡genes para permitir la visualizaciÃ³n de las imÃ¡genes.  
+
+HTMLPlugin.rename_assoc_files:Renombra archivos asociados con documentos (por ejemplo imÃ¡genes). TambiÃ©n crea mucha estructura de directorios de poco peso (Ãºtil al crear las colecciones cd-rom).
+
+HTMLPlugin.sectionalise_using_h_tags:Crea automÃ¡ticamente un documento con secciones, usando las etiquetas h1, h2, ... hx.  
+
+HTMLPlugin.title_sub:ExpresiÃ³n de sustituciÃ³n para modificar una cadena almacenada como TÃ­tulo. Usada, por ejemplo, en PDFPlugin para eliminar "PÃ¡gina 1", etc de un texto usado como tÃ­tulo.  
+
+HTMLPlugin.tidy_html:Si se activa, convierte un fichero HTML en un XHTML bien formado. Permite a los usuarios ver el documento en formato libro.  
+
+HTMLPlugin.old_style_HDL:Para marcar los ficheros de esta colecciÃ³n que se seccionan usando el antiguo estilo de secciÃ³n HDL.  
+
+BaseMediaConverter.enable_cache:Almacenar en cache los archivos generados automÃ¡ticamente (como las miniaturas y las imÃ¡genes en tamaÃ±o pantalla) de manera que no necesiten generarse repetidamente.  
+
+ImageConverter.converttotype:Convertir la imagen principal al formato 's'.
+
+ImageConverter.create_screenview:Si se configura como true, crea una imagen tamaÃ±o pantalla y asigna los metadatos Screen, ScreenType, screenicon, ScreenWidth, ScreenHeight.  
+
+ImageConverter.create_thumbnail:Si se configura como true, crea una versiÃ³n miniatura de cada imagen y agrega los metadatos Thumb, ThumbType, thumbicon, ThumbWidth, ThumbHeight.  
+ImageConverter.desc:Este plugin procesa las imÃ¡genes, agregando los metadatos bÃ¡sicos  
+
+ImageConverter.imagemagicknotinstalled:Image Magick no estÃ¡ instalado.  
+
+ImageConverter.minimumsize:Ignore las imÃ¡genes menores que n bytes.
+
+ImageConverter.noconversionavailable:ConversiÃ³n de imagen no disponible  
+
+ImageConverter.noscaleup:No sobreponga las imÃ¡genes pequeÃ±as al hacer thumbnails .
+
+ImageConverter.screenviewsize:Producir imÃ¡genes "screenview" de tamaÃ±o nxn.
+
+ImageConverter.screenviewtype:Producir imÃ¡genes "screenview" en formato 's'.
+
+ImageConverter.thumbnailsize:Realiza iconos pequeÃ±os tamaÃ±o nxn.
+
+ImageConverter.thumbnailtype:Realiza iconos pequeÃ±os en el formato 's'.
+
+ImageConverter.win95notsupported:Image Magick no estÃ¡ soportado en Win95/98  
+
+ImagePlugin.desc:Este plugin procesa las imÃ¡genes, agregando los metadatos bÃ¡sicos  
+
+IndexPlugin.desc:Este plugin recursivo procesa un fichero index.txt. El fichero index.txt deberÃ­a contener la lista de archivos que deberÃ¡n ser incluidos en la colecciÃ³n, seguida por cualesquiera metadatos extras que deban ser asociados con cada fichero.\n\n El fichero index.txt debe estructurarse de la siguiente manera: La primera lÃ­nea puede ser una llave (empezando con key:)  para nombrar los ficheros de metadatos (por ejemplo, key: Asunto OrganizaciÃ³n Fecha). Las lÃ­neas siguientes contendrÃ¡n un nombre de afichero seguido por el valor que se asignarÃ¡ a la entrada del metadato. (por ejemplo, 'irma/iw097e 3.2 unesco 1993' asociarÃ¡ el metadato Asunto=3.2, OrganizaciÃ³n=unesco, y Fecha=1993 con el archivo irma/iw097e si se utilizÃ³ la lÃ­nea anterior)\n\n Note que si cualquiera de los campos de los metadatos utiliza el plugin de clasificador de JerarquÃ­a, entonces el valor de ellos debe corresponder al primer campo (el descriptor) en el fichero de la clasificaciÃ³n apropiado.\n\nLos valores de los metadatos pueden nombrarse utilizando una etiqueta de manera separada (por ejemplo <Asunto>3.2) y esto prevalecerÃ¡ sobre cualquier nombre que se les haya asignado en la lÃ­nea que contiene la "key". Si no hay ninguna lÃ­nea que contenga una "key", cualquier valor sin nombre de los metadatos se denominarÃ¡ 'Asunto'.  
+
+ISISPlugin.desc:Este plugin procesa las bases de datos CDS/ISIS. Por cada base de datos CDS/ISIS procesada deberÃ¡n existir tres archivos en la carpeta de importaciÃ³n de la colecciÃ³n: el archivo Maestro (.mst), la Tabla de DefiniciÃ³n de Campos (.fdt) y el Archivo de Referencias Cruzadas (.xrf)
+
+ISISPlugin.subfield_separator:La cadena de caracteres que se usa para separar subcampos en los registros de la base de datos CDS/ISIS.
+
+ISISPlugin.entry_separator:La cadena de caracteres que se usa para separar mÃºltiples valores en los campos de metadatos de los registros de la base de datos CDS/ISIS.
+
+KeyphraseExtractor.desc:Conector asociado para la generaciÃ³n de keyphrases desde el texto. Utiliza el sistema de extracciÃ³n de frases Kea.  
+
+KeyphraseExtractor.extract_keyphrases:Extraer automÃ¡ticamente frases clave con Kea (opciones por defecto).
+
+KeyphraseExtractor.extract_keyphrases_kea4:Extraer frases calve automÃ¡ticamente con Kea 4.0 (configuraciÃ³n estÃ¡ndar). Kea 4.0 es una nueva versiÃ³n de Kea que ha sido desarrollada para la indizaciÃ³n controlada de documentos del campo de la agricultura.  
+
+KeyphraseExtractor.extract_keyphrase_options:Opciones para extracciÃ³n de frases clave con Kea. Por ejemplo: mALIWEB - utilizar el modelo de extracciÃ³n ALIWEB; n5 - extraer 5 frases clave;, eGBK - utilizar codificaciÃ³n GBK.
+
+KeyphraseExtractor.keyphrases:frases clave
+
+KeyphraseExtractor.missing_kea:Error: el software Kea no se encuentra en %s. Por favor, descargue Kea %s de http://www.nzdl.org/Kea e instÃ¡lelo en este directorio.  
+
+LaTeXPlugin.desc:Plugin para documentos LaTeX.
+
+LOMPlugin.desc:Plugin para importar ficheros LOM (Learning Object Metadata, Metadatos de Objetos de Aprendizaje).  
+
+LOMPlugin.root_tag:DocType para el fichero XML (o una expresiÃ³n regular que coincida con el elemento raÃ­z).  
+
+LOMPlugin.check_timestamp:Comprueba las fechas y horas de documentos previamente descargados, y sÃ³lo los descarga de nuevo si el dato es mÃ¡s moderno.  
+
+LOMPlugin.download_srcdocs:Descarga el documento fuente si se indica uno (en general^identifier^entry o technical^location).). Esta opciÃ³n deberÃ­a especificar una expresiÃ³n regular que coincida con los nombres de fichero antes de su descarga. NÃ³tese que actualemnte sÃ³lo funciona para documentos fuera de un cortafuegos.  
+
+MARCPlugin.desc:Plugin MARC bÃ¡sico.
+
+MARCPlugin.metadata_mapping:Nombre de fichero que incluye la correspondencia detallada de valores MARC para los nombres de los metadatos de Greenstone. Predeterminado a 'marc2dc.txt' que se encuentra en el directorio etc del sitio.  
+
+MARCXMLPlugin.desc:Plugin MARCXML  
+
+MARCXMLPlugin.metadata_mapping_file:Nombre del fichero que incluye los detalles de mapeado de valores MARC a nombres de metadatos Greenstone. Predefinido a 'marc2dc.txt', en el directorio etc del sitio.  
+
+MediaWikiPlugin.desc:Plugin para importar pÃ¡ginas web de MediaWiki  
+
+MediaWikiPlugin.show_toc:AÃ±ade a la pÃ¡gina Sobre la colecciÃ³n la 'tabla de contenidos' de la pÃ¡gina principal del sitio de MediaWiki. Necesita una expresiÃ³n regular Perl debajo, en toc_exp, que coincida con la secciÃ³n 'tabla de contenidos'.  
+
+MediaWikiPlugin.delete_toc:Borra la secciÃ³n 'tabla de contenidos' de cada pÃ¡gina HTML. Necesita especificar una expresiÃ³n regular Perl debajo, en toc_exp, que coincida con la secciÃ³n 'tabla de contenidos'.  
+
+MediaWikiPlugin.toc_exp:ExpresiÃ³n regular Perl que coincida con 'tabla de contenido'. El valor predefinido coincide con las pÃ¡ginas comunes de MediaWiki.  
+
+MediaWikiPlugin.delete_nav:Boorar la secciÃ³n de navegaciÃ³n. Necesita que se especifique una expresiÃ³n regular Perl debajo, en nav_div_exp.  
+
+MediaWikiPlugin.nav_div_exp:ExpresiÃ³n regular Perl que coincida con la secciÃ³n de navegaciÃ³n. El valor predefinido coincide con pÃ¡ginas comunes de MediaWiki.  
+
+MediaWikiPlugin.delete_searchbox:Borrar la secciÃ³n de la caja de bÃºsqueda. Necesita especificar una expresiÃ³n regular Perl debajo, en searchbox_div_exp.  
+
+MediaWikiPlugin.searchbox_div_exp:Una expresiÃ³n regular Perl para contrastar contra la secciÃ³n del cuadro de bÃºsqueda. El valor por defecto se corresponde con pÃ¡ginas web de MediaWiki  
+
+MediaWikiPlugin.remove_title_suffix_exp:ExpresiÃ³n regular Perl para recortar el tÃ­tulo extraido. Por ejemplo, \\s-(.+) cortarÃ¡ el contenido del tÃ­tulo despuÃ©s de "-".  
+
+MetadataCSVPlugin.desc:Plugin para metadatos en formato de valores separados pro comas. El campo Filename del fichero CSV se usa para determinar a que documento pertenece el metadato.  
+
+MetadataPass.desc:Clase base separada a BasePlugin que soporta que los conectores de metadato utilicen la pasada metadata_read del import.pl  
+
+MetadataXMLPlugin.desc:Conector que procesa archivos metadata.xml.  
+
+MetadataEXIFPlugin.desc:Conector que extrae metadatos EXIF de imÃ¡genes, audio y video. MÃ¡s especÃ­ficamente, estÃ¡ basado en el mÃ³dulo CPAN 'ExifTool'. Actualmente soporta muchos mas formatos de los que sugiere el nombre (ej. GPS, XMP, FlashPix, ID3, Vorbis). El conector se beneficia de esto y ha sido diseÃ±ado para soportar todos los formatos que admite ExifTool. Ver la documentaciÃ³n de ExifTool para los esquemas de metadatos y tipos de archivos soportados.  
+
+GreenstoneMETSPlugin.desc:Procesa documentos METS en el estilo de Greenstone  
+
+MP3Plugin.desc:Plugin para procesar archivos MP3.
+
+MP3Plugin.assoc_images:Use la bÃºsqueda de imÃ¡genes de Google para localizar imÃ¡genes relacionadas con ficheros  MP3 usando TÃ­tulo ID3 y metadato de Artista.  
+
+MP3Plugin.applet_metadata:Usado para almacenar [applet] metadatos para cada documento que contiene el HTML necesario para que un applet de audio MP3 pueda reproducir ese archivo.
+
+MP3Plugin.metadata_fields:Lista de campos de metadatos separados por comas, a extraer (asumiendo los existentes) de un archivo MP3. Use \"*\" para extraer todos los campos.
+
+NulPlugin.desc:Plugin de fichero nulo (.nul). Utilizado con los archivos producidos al expandir los ficherosos de la base de datos de metadatos.  
+
+NulPlugin.assoc_field:Nombre del campo de metadato a asignar para cada fichero nulo.  
+NulPlugin.add_metadata_as_text:AÃ±adir una tabla de metadatos como el texto del documento, antes que "Este documento no tiene texto".  
+
+NulPlugin.remove_namespace_for_text:Borra los espacios de nombres de los nombres de metadatos en el texto del documento (si se ha marcado add_metadata_as_text).  
+
+OAIPlugin.desc:Plugin bÃ¡sico para Open Archives Initiative (OAI)  
+
+OAIPlugin.document_field:El elemento de metadato que especifica el nombre del archivo del documento al cual adjuntar los metadatos.  
+
+OAIPlugin.metadata_set:Conjunto de metadatos (prefijo del nombre de esquema) al cual importar todos los metadatos  
+OAIPlugin.metadata_set.auto:Usar los prefijos especificados en el registro OAI  
+OAIPlugin.metadata_set.dc:Usar el prefijo dc. MapearÃ¡ elementos dc cualificados a su forma Greenstone, por ej., spatial se convertirÃ¡ en dc.Coverage^spatial.  
+
+OggVorbisPlugin.add_technical_metadata:AÃ±adir metadatos tÃ©cnicos (ej. bitrate)
+
+OggVorbisPlugin.desc:Plugin para importar archivos de audio Ogg Vorbis.
+
+OpenDocumentPlugin.desc:Plugin para documentos en formato OASIS OpenDocument (usado por OpenOffice 2.0)  
+
+PagedImagePlugin.desc:Plugin para documentos hechos con secuencias de imÃ¡genes, con texto opcional de OCR para cada imagen. Procesa ficheros .item qye listan la secuencia de ficheros de imÃ¡genes y texto, y proveen los metadatos.  
+
+PagedImagePlugin.documenttype:Establecer el tipo de documento (usado para despliegue)
+
+PagedImagePlugin.documenttype.paged:Los documentos paginados tienen flechas "siguiente" y "anterior", asÃ­ como una opciÃ³n para "ir a la pÃ¡gina X"
+
+PagedImagePlugin.documenttype.hierarchy:Los documentos jerÃ¡rquicos tienen una tabla de contenido
+
+PagedImagePlugin.headerpage:AÃ±adir una cabecera de pÃ¡gina de nivel principal (que no contenga imagen) a cada documento.
+
+PDFPlugin.allowimagesonly:Permitir ficheros PDF con texto no extraÃ­ble. Evitar tener indicado -complex set. SÃ³lo Ãºtil con convert_to html.  
+
+PDFPlugin.complex:Crea una salida mÃ¡s compleja. Con esta opciÃ³n marcada los html resultantes se parecerÃ¡n mucho mÃ¡s al archivo PDF original. Para que funcione adecuadamente debe tener instalado Ghostscript (para *nix gs debe estar su ruta, mientras que para windows se debe tener gswin32c.exe en el path).  
+
+PDFPlugin.desc:Plugin que procesa documentos PDF.  
+
+PDFPlugin.nohidden:Prevenga al pdftohtml de intentar extraer texto oculto. Esto sÃ³lo es Ãºtil si la opciÃ³n -complex estÃ¡ determinada.
+
+PDFPlugin.noimages:No intente extraer las imÃ¡genes de PDF.
+
+PDFPlugin.use_sections:Cree una secciÃ³n separada para cada pÃ¡gina del archivo de PDF.
+
+PDFPlugin.zoom:El factor por el cual se hace acercamiento al PDF para la salida (esto sÃ³lo es Ãºtil si el -complex esta determinado).
+
+PostScriptPlugin.desc:Este es un ps \"poor manâs\" para convertidor de texto. Si si plan es serio, considere utilizar el paquete PRESCRIPT, para bajarlo lo podrÃ¡ encontrar en http://www.nzdl.org/html/software.html
+
+PostScriptPlugin.extract_date:Extrae la fecha del encabezado de PS.
+
+PostScriptPlugin.extract_pages:Extrae las pÃ¡ginas del encabezado de PS.
+
+PostScriptPlugin.extract_title:Extrae el encabezado de PS inicial.
+
+PowerPointPlugin.desc:Conector para importar archivos de Microsoft PowerPoint.  
+
+PowerPointPlugin.windows_scripting:Usa la tecnologÃ­a de scripting de MicroSoft Windows (Visual Basic for Applications) para convertir documentos PPT a varios tipos de imagen (ej. JPEG,PNG,GIF), en vez de hacerlo con el paquete de software libre ppttohtml.  
+
+PrintInfo.bad_general_option:El % del plugin utiliza una opciÃ³n general incorrecta (las opciones generales estÃ¡n disponibles para todos los plugins). Revise su fichero de configuraciÃ³n collect.cfg.  
+
+PrintInfo.desc:La mayorÃ­a de los conectores bÃ¡sicos permiten la impresiÃ³n de informaciÃ³n (usando pluginfo.pl) y el anÃ¡lisis de los argumentos.  
+
+ProCitePlugin.desc:Plugin para bases de datos Procite (exportadas)  
+
+ProCitePlugin.entry_separator:La cadena usada para separar valores mÃºltiples para campos de metadatos simples en registros de ProCite.  
+
+ReadTextFile.could_not_extract_encoding:ALERTA: codificando no podrÃ­an extraerse de % s - predefiniendo a % s
+
+ReadTextFile.could_not_extract_language:ALERTA: el idioma no podrÃ­a extraerse de % s - predefiniendo a % s
+
+ReadTextFile.could_not_open_for_reading:no podrÃ¡ abrir % s ni leerlos
+
+ReadTextFile.default_encoding:Utilice esta codificaciÃ³n si -input_encoding estÃ¡ puesto en âautoâ y el algoritmo de categorizaciÃ³n de texto no puede extraer el cÃ³digo o extrae un cÃ³digo que Greenstone no soporte. Esta opciÃ³n puede tomar los mismos valores que -input_encoding.
+
+ReadTextFile.default_language:Si Greenstone no identifica el lenguaje del documento, el elemento del metadato se colocarÃ¡ en este valor. El valor predeterminado es 'en' (se usan los sÃ­mbolos de lenguaje ISO 639: en = inglÃ©s). Note que si -input_encoding no estÃ¡ en 'auto' y -extract_language no estÃ¡ definido, todos los documentos tendrÃ¡n el metadato 'Lenguaje' ajustado a este valor.  
+
+ReadTextFile.desc:Conector base para archivos de texto plano.  
+
+ReadTextFile.empty_file:el archivo no contiene ningÃºn texto
+
+ReadTextFile.extract_language:Identifica el idioma de cada documento y establece el 'lenguaje' del metadato. Note que esto se harÃ¡ automÃ¡ticamente si -input_encoding estÃ¡ en 'auto'.  
+
+ReadTextFile.file_has_no_text:ERROR: % s no contiene texto alguno
+
+ReadTextFile.input_encoding:La codificaciÃ³n de los documentos de la fuente. Los documentos se convertirÃ¡n de estas codificaciones y se guardarÃ¡n internamente como utf8.
+
+ReadTextFile.input_encoding.auto:Use el algoritmo de categorizaciÃ³n de texto para identificar la codificaciÃ³n de cada fuente de documento automÃ¡ticamente. Esto serÃ¡ mÃ¡s lento que poniendo la codificaciÃ³n explÃ­citamente pero trabajarÃ¡ en donde mÃ¡s de una codificaciÃ³n se use dentro de la misma colecciÃ³n.
+
+ReadTextFile.read_denied:Lea permiso negado para % s
+
+ReadTextFile.separate_cjk:Inserta espacios entre caracteres Chinos/Japoneses/Coreanos para hacer cada carÃ¡cter una palabra. Usar si el texto no estÃ¡ segmentado.  
+
+ReadTextFile.unsupported_encoding:ALERTA: % s aparece para ser codificado en un cÃ³digo sin apoyo (% s) â usando % s
+
+ReadTextFile.wrong_encoding:ALERTA: %s fue leÃ­do utilizando la codificaciÃ³n %s pero parece haber sido codificado como % s.
+
+ReadXMLFile.desc:La clase base para plugins XML.
+
+ReadXMLFile.xslt:Transforma un documento de entrada que cumple la condiciÃ³n con la XSLT contenida en el nombre de fichero. Se asume que existe un nombre de fichero relativo en el Ã¡rea de ficheros de la colecciÃ³n, por ejemplo etc/mods2dc.xsl.  
+
+RealMediaPlugin.desc:Plugin para procesar ficheros Real Media  
+
+ReferPlugin.desc:ReferPlug lee archivos bibliogrÃ¡ficos en formato Refer.
+
+RogPlugin.desc:Crea los documentos simples single-level (de nivel Ãºnico) a partir de archivos .rog o .mdb.
+
+RTFPlugin.desc:Plugin para importar ficheros en Formato de Texto Enriquecido  (Rich Text Format, RTF)  
+
+SourceCodePlugin.desc:Nombre de Archivo utilizado actualmente para TÃ­tulo (opcionalmente menos algÃºn prefijo). Languages actuales:\ntextl: READMEs/Makefiles\nC/C++ (actualmente los extractos #incluye las declaraciones y clase C++ decls)\nPerl (actualmente sÃ³lo elaborado como texto)\nShell (actualmente sÃ³lo elaborado como texto)
+
+SourceCodePlugin.remove_prefix:Elimine este modelo principal del nombre del archivo (eg - remove_prefix /tmp/XX/src/). El valor predeterminado es eliminar la ruta completa del nombre del archivo.
+
+SplitTextFile.desc:SplitTextFile es un conector para dividir archivos de entrada en segmentos que se procesarÃ¡n de manera individual. Este conector no debe llamarse de manera directa.  En cambio, si usted necesita procesar archivos input que contienen varios documentos, debe escribir un conector con una funciÃ³n de proceso que manejarÃ¡ uno de esos documentos habiÃ©ndolo tomado de SplitTextFile. Vea ReferPlugin para un ejemplo.  
+
+SplitTextFile.split_exp:Una expresiÃ³n Perl regular para separar la entrada de ficheros en segmentos.  
+
+StructuredHTMLPlugin.desc:Plugin para procesar documentos HTML estructurados, dividiÃ©ndolos en secciones basadas en la informaciÃ³n de estilos.  
+
+StructuredHTMLPlugin.delete_toc:Borra cada tabla de contenidos, lista de figuras, etc., del fichero HTML convertido. Los estilos para ello se definen con la opciÃ³n toc_header  
+
+StructuredHTMLPlugin.title_header:posible estilo definido por el usuario para la cabecera de tÃ­tulo.  
+
+StructuredHTMLPlugin.level1_header:posibles estilos definidos por el usuario para la cabecera nivel1 en el documento HTML (equivalente a <H1>).  
+
+StructuredHTMLPlugin.level2_header:posibles estilos definidos por el usuario para la cabecera de nivel2 en el documento HTML (equivalente a <h2>).  
+
+StructuredHTMLPlugin.level3_header:posibles estilos definidos por el usuario para la cabecera nivel3 en el documento HTML (equivalente a <h3>).  
+
+StructuredHTMLPlugin.toc_header:posibles estilos de cabecera definidos por el usuario para tabla de contenidos, tabla de figuras, etc., se borra si se selecciona delete_toc  
+
+TextPlugin.desc:Crea un documento simple de nivel Ãºnico (single-level). Agrega el metadato TÃ­tulo de la primera lÃ­nea de texto (hasta 100 caracteres).
+
+TextPlugin.title_sub:ExpresiÃ³n de substituciÃ³n para modificar la cadena guardada como TÃ­tulo. Por ejemplo, PSPlug para eliminar "PÃ¡gina 1" etc del texto utilizado como tÃ­tulo.
+
+UnknownPlugin.assoc_field:Nombre del campo del metadato que mantendrÃ¡ el nombre del fichero asociado.  
+
+UnknownPlugin.desc:Plugin simple para los ficherosos importados en formatos que Greenstone no soporta. CrearÃ¡ un documento virtual para cada uno de esos ficheros, cada uno de ellos se pasarÃ¡ a Greenstone como fichero asociado \âassociated file\â del documento.  
+
+UnknownPlugin.file_format:Tipo de archivo (ej: MPEG, MIDI, âŠ)
+
+UnknownPlugin.mime_type:Tipo mime del archivo (por ejemplo image/gif).
+
+UnknownPlugin.process_extension:Procesar archivos con esta extensiÃ³n de archivo. Esta oopciÃ³n es una alternativa a process_exp mÃ¡s sencilla de usar pero menos flexible.
+
+UnknownPlugin.srcicon:Indique un nombre de macro (sin guiones bajos) para usar como metadato de srcicon.  
+
+WordPlugin.desc:Plugin importador para los documentos de Microsoft Word.
+
+WordPlugin.windows_scripting:Usa la tecnologÃ­a de scripting de MicroSoft Windows (Visual Basic for Applications) para convertir Word a HTML, mejor que usar sÃ³lo el software libre WvWare. Hace que se abra la aplicaciÃ³n Word en la pantalla si no se estÃ¡ ejecutando previamente.  
+
+WordPlugin.metadata_fields:Para recuperar metadatos del documento HTML convertido por un script VB. Permite a los usuarios definir una lista, separada por comas, de campos de metadatos que intentarÃ¡ extraer. Use 'tag<tagname>' para poner los contenidos del primer par <tagname> e un elemento de metadato llamado 'tagname'. Ponga las mayÃºsculas como quiera que se pongan en los metadatos en Greenstone, ya que la extracciÃ³n de etiquetas no es sensible a ello.  
+
+ZIPPlugin.desc:Plugin que se ocupa de los formatos comprimidos y/o archivados de entrada los formatos actualmente manejados y las extensiones de archivo son are:\ngzip de (.gz. z. el tgz. taz)\nbzip (.bz)\nbzip2 (.bz2)\nzip (.zip. .jar)\ntar\n\n Este plugin confÃ­a en las utilerÃ­as siguientes que estÃ¡n presentes (si estÃ¡ intentando procesar formatos correspondientes) :\ngunzip (para gzip)\nbunzip (para bzip)\nbunzip2 \nunzip (para zip)\ntar (para tar)
+
+#
+# Download module option descriptions
+#
+
+BaseDownload.desc:Clase bÃ¡sica para mÃ³dulos de descarga  
+BaseDownload.bad_general_option:El mÃ³dulo de descarga %s usa una opciÃ³n incorrecta.  
+MediaWikiDownload.desc:MÃ³dulo para descargar sitios web construidos con MediaWiki  
+MediaWikiDownload.reject_filetype:Lista de urls a ignorar, separados por comas, ej. *cgi-bin*,*.ppt ignorarÃ¡ todos los enlaces que incluyan 'cgi-bin' o '.ppt'  
+MediaWikiDownload.reject_filetype_disp:Ignorar patrones de URL  
+MediaWikiDownload.exclude_directories:Lista de exclusiÃ³n de directorios (debe incluir la ruta completa al directorio), ej. /gente,/documentacion excluirÃ¡ los subdirectorios "gente" y "documentacion" en el sitio que se estÃ¡ capturando.  
+MediaWikiDownload.exclude_directories_disp:Excluir directorios  
+
+OAIDownload.desc:MÃ³dulo para descargar de repositorios OAI  
+OAIDownload.url_disp:URL fuente  
+OAIDownload.url:URL de repositorio OAI  
+OAIDownload.set_disp:Restringir al conjunto  
+OAIDownload.set:Restringe la descarga al conjunto indicado en el repositorio  
+OAIDownload.metadata_prefix_disp:Prefijo de metadato  
+OAIDownload.metadata_prefix:El formato de metadato usado en la exportaciÃ³n, ej. Oai_dc, qdc, etc. Presione el botÃ³n <InformaciÃ³n del servidor> para conocer que formatos son soportados.  
+OAIDownload.get_doc_disp:Obtener documento  
+OAIDownload.get_doc:Descarga el documento fuente si no se indica ninguno en el registro  
+OAIDownload.get_doc_exts_disp:Solo incluir tipos de archivos  
+OAIDownload.get_doc_exts:Extensiones de archivos de documentos permitidas  
+OAIDownload.max_records_disp:MÃ¡ximo de registros  
+OAIDownload.max_records:NÃºmero mÃ¡ximo de registros a descargar  
+
+SRWDownload.desc:MÃ³dulo para descargar de un repositorio SRW (Search/Retrieve Web Service)  
+
+WebDownload.desc:MÃ³dulo para descargar de internet mediante HTTP o FTP  
+WebDownload.url:URL origen. En caso de redirects de HTTP, este valor puede cambiar.  
+WebDownload.url_disp:URL fuente  
+WebDownload.depth:NÃºmero de profundidad de enlaces a seguir cuando descargue  
+WebDownload.depth_disp:Profundidad de descarga  
+WebDownload.below:SÃ³lo ficheros de copia bajo este URL  
+WebDownload.below_disp:SÃ³lo archivos por debajo de este URL  
+WebDownload.within:SÃ³lo ficheros de copia dentro del mismo sitio  
+WebDownload.within_disp:SÃ³lo archivos dentro del sitio
+WebDownload.html_only:Descaragar sÃ³lo ficheros HTML, e ignorar ficheros asociados, por ej. imÃ¡genes y hojas de estilo  
+WebDownload.html_only_disp:SÃ³lo archivos HTML  
+
+WgetDownload.desc:Clase bÃ¡sica que maneja las llamadas a wget  
+WgetDownload.proxy_on:Proxy activado  
+WgetDownload.proxy_host:Servidor proxy  
+WgetDownload.proxy_port:Puerto del proxy  
+WgetDownload.user_name:Nombre de usuario  
+WgetDownload.user_password:Clave de usuario  
+
+Z3950Download.desc:MÃ³dulo para descargar de repositorios Z3950  
+Z3950Download.host:URL del servidor  
+Z3950Download.host_disp:Servidor  
+Z3950Download.port:NÃºmero de puerto del repositorio  
+Z3950Download.port_disp:Puerto  
+Z3950Download.database:Base de datos en la que buscar registros  
+Z3950Download.database_disp:Base de datos  
+Z3950Download.find:Recupera registros que contienen el tÃ©rmino de bÃºsqueda indicado  
+Z3950Download.find_disp:Encontrar  
+Z3950Download.max_records:NÃºmero mÃ¡ximo de registros a descargar  
+Z3950Download.max_records_disp:MÃ¡ximo de registros  
+
+
+#
+#Plugout option descriptions
+#
+
+BasPlugout.bad_general_option:La salida %s usa una opciÃ³n general incorrecta.  
+BasPlugout.debug:configurar modo debug  
+BasPlugout.desc:Clase bÃ¡sica para todos las salidas de exportaciÃ³n.  
+BasPlugout.group_size:NÃºmero de documentos a agrupar en un fichero XML.  
+BasPlugout.gzip_output:Usar gzip para comprimir los documentos xml resultantes (no olvide incluir ZIPPlugin en su lista de conectores cuando construya con documentos compactados).  
+BasPlugout.output_handle:descriptor de archivo usado para enviar la informaciÃ³n de salida  
+BasPlugout.output_info:referencia a un objeto arcinfo usado para almacenar informaciÃ³n sobre los ficheros.  
+BasPlugout.verbosity:Controla la cantidad de salida. 0=nada, 3=mucha.  
+BasPlugout.xslt_file:Transforma un documento con XSLT en el fichero indicado.  
+
+DSpacePlugout.desc:formato de archivo DSpace  
+
+FedoraMETSPlugout.desc:Formato METS usando el perfil de Fedora.  
+FedoraMETSPlugout.fedora_namespace:El prefijo usado en Fedora para los ids de procesos (PIDS), ej. Greenstone:HASH0122efe4a2c58d0  
+
+GreenstoneXMLPlugout.desc:Formato de archivo XML de Greenstone.  
+
+GreenstoneMETSPlugout.desc:Formato METS usando el perfil de Greenstone.  
+
+MARCXMLPlugout.desc:Formato MARC xml.  
+MARCXMLPlugout.group:Exporta los registros marc xml a un Ãºnico archivo.  
+MARCXMLPlugout.mapping_file:Usa el archivo de mapeo indicado para la transformaciÃ³n.  
+
+METSPlugout.desc:Conector de salida superclase para el formato METS. Provee funcionalidades comunes para perfiles como GreenstoneMETS y FedoraMETS y mÃ©todos abstractos de claves.  
+METSPlugout.xslt_txt:Transforma un fichero doctxt.xml de mets con la XSLT en el archivo indicado.  
+METSPlugout.xslt_mets:Transforma un fichero docmets.xml de mets con la XSLT en el archivo nombrado.  
+
+#
+# Perl module strings
+#
+
+classify.could_not_find_classifier:ERROR: no encontrÃ³ el clasificador \â% s\â
+
+download.could_not_find_download:ERROR: no se puede encontrar el mÃ³dulo de descarga \"%s\"  
+
+plugin.could_not_find_plugin:ERROR: No podrÃ¡ encontrar el plugin \"% s\"
+
+plugin.including_archive:inclusive los volÃºmenes de 1 archivo de ZIP/TAR
+
+plugin.including_archives:inclusive los volÃºmenes de %d los archivos de ZIP/TAR
+
+plugin.kill_file:Proceso terminado por el fichero .kill  
+
+plugin.n_considered:%d de los documentos fueron considerados a efecto de ser procesados
+
+plugin.n_included:%d se procesaron e incluidos en la colecciÃ³n
+
+plugin.n_rejected:%d rechazados
+
+plugin.n_unrecognised:%d no fueron reconocidos
+
+plugin.no_plugin_could_process:ADVIRTIENDO: NingÃºn plugin podrÃ¡ ser procesado %s
+
+plugin.no_plugin_could_recognise:ATENCIÃN: NingÃºn plugin pudo reconocer %s
+
+plugin.no_plugin_could_process_this_file:ningÃºn plugin podrÃ¡ procesar este archivo
+
+plugin.no_plugin_could_recognise_this_file:ningÃºn plugin pudo reconocer este archivo
+
+plugin.one_considered:1 documento fue considerado a efecto de ser procesado
+
+plugin.one_included:1 fue procesado e incluido en la colecciÃ³n
+
+plugin.one_rejected:1 fue rechazado
+
+plugin.one_unrecognised:1 no fue reconocido
+
+plugin.see_faillog:Vea en %s una lista de documentos no reconocidos y/o rechazados
+
+PrintUsage.default:Valor predeterminado (default)
+
+PrintUsage.required:REQUERIDO
+
+plugout.could_not_find_plugout:ERROR: No se pudo encontrar salida \"%s\"  
Index: /gsdl/stable/perllib/strings_fr.properties
===================================================================
--- /gsdl/stable/perllib/strings_fr.properties	(revision 20131)
+++ /gsdl/stable/perllib/strings_fr.properties	(revision 20131)
@@ -0,0 +1,1318 @@
+#
+# Resource bundle description
+#
+
+Language.code:fr
+Language.name:FranÃ§ais
+
+OutputEncoding.unix:iso_8859_1
+OutputEncoding.windows:iso_8859_1
+
+
+#
+# Common output messages and strings
+#
+
+common.cannot_create_file:ERREUR: impossible de crÃ©er le fichier %s
+
+common.cannot_find_cfg_file:ERREUR: fichier de configuration introuvable %s
+
+common.cannot_open:ERREUR: impossible d'ouvrir %s
+
+common.cannot_open_fail_log:ERREUR: Impossible d'ouvrir le log d'Ã©chec %s
+
+common.cannot_open_output_file:ERREUR: impossible d'ouvrir le fichier output %s
+
+common.cannot_read:ERREUR: impossible de lire %s
+
+common.cannot_read_file:ERREUR: impossible de lire le fichier %s
+
+common.general_options:options gÃ©nÃ©rales (pour %s)
+
+common.must_be_implemented:fonction doit Ãªtre implÃ©mentÃ©e dans sous-classe
+
+common.options:options
+
+common.processing:traitement
+
+common.specific_options:options spÃ©cifiques
+
+common.usage:Utilisation  
+
+common.info:info  
+
+common.invalid_options:Arguments non valides: %s  
+
+common.true:vrai  
+
+common.false:faux  
+
+common.deprecated:OBSOLETE  
+#
+# Script option descriptions and output messages
+#
+
+scripts.language:Langue dans laquelle les descriptions d'option sont affichÃ©es (ex. 'en_US' spÃ©cifie l'anglais amÃ©ricain). NÃ©cessite des traductions des descriptions d'options qui sont prÃ©sentes dans le fichier perllib/strings_language-code.rb.
+
+scripts.xml:Produit l'information sous forme XML, sans 'jolis' commentaires mais avec beaucoup plus de dÃ©tails.
+
+scripts.listall:Liste tous les Ã©lÃ©ments connus.
+
+scripts.describeall:Des options d'affichage de tous les Ã©lÃ©ments connus  
+
+scripts.both_old_options:AVERTISSEMENT: - removeold a Ã©tÃ© spÃ©cifiÃ© avec - keepold ou -incremental, par dÃ©faut sera  -removeold. Le contenu actuel du rÃ©pertoire %s sera supprimÃ©.  
+
+scripts.no_old_options:AVERTISSEMENT: Aucune des options  -removeold, - keepold ou --incremental n'a Ã©tÃ© prÃ©cisÃ©e, par dÃ©faut sera mis  -removeold. Les contenus actuels du rÃ©pertoire %s sera supprimÃ©.  
+
+scripts.gli:Un drapeau positionnÃ© lorsque ce script est lancÃ© Ã  partir de l'Interface BibliothÃ©caire, permet d'avoir une sortie spÃ©cifique pour l'Interface BibliothÃ©caire.  
+
+# -- buildcol.pl --
+
+buildcol.archivedir:LÃ  oÃ¹ se trouvent les archives.
+
+buildcol.builddir:LÃ  oÃ¹ mettre les indexes construits.
+
+buildcol.cachedir:La collection sera temporairement construite ici avant d'Ãªtre copiÃ©e dans le le rÃ©pertoire de construction.
+
+buildcol.cannot_open_cfg_file:ATTENTION: Impossible d'ouvrir le fichier de configuration pour mise Ã  jour: %s
+
+buildcol.collectdir:Le chemin du rÃ©pertoire Â«Â collectÂ Â»  
+
+buildcol.copying_back_cached_build:Recopie de la construction mise en cache
+
+buildcol.create_images:Tente de crÃ©er des images par dÃ©faut pour la nouvelle collection. Cela dÃ©pend de l'installation de Gimp en mÃªme temps que les modules qui vont avec pour permettre l'Ã©criture de scripts Ã  partir de perl.
+
+buildcol.debug:Imprimer la sortie sur STDOUT.
+
+buildcol.desc:Script PERL utilisÃ© pour construire une collection Greenstone Ã  partir de documents archives.  
+
+buildcol.faillog:Nom de fichier log d'Ã©chec. Ce fichier log reÃ§oit les noms de fichiers de tous les fichiers qu'on n'a pas pu traiter.
+
+buildcol.incremental_default_builddir:ATTENTION : le rÃ©pertoire de construction est 'building' par dÃ©faut. Si vous voulez Ã©tendre le rÃ©pertoire d'indexation de maniÃšre incrÃ©mentale, veuillez ajouter l'option "-builddir index" Ã  la commande buildcol.pl.  
+
+buildcol.index:Index Ã  construire (va construire toust dans le fichier de configuration si pas dÃ©fini).
+
+buildcol.incremental:Indexe seuls les documents qui n'ont pas Ã©tÃ© prÃ©alablement indexÃ©s. Implique -keepold. Repose sur l' indexeur lucene.  
+
+buildcol.keepold:Ne dÃ©truira pas les contenus actuels du rÃ©pertoire de construction.
+
+buildcol.maxdocs:Nombre maximum de documents Ã  construire.
+buildcol.maxnumeric:Le nombre maximum de chiffres un "mot" peut avoir dans le dictionnaire de l'index. Les grands nombres sont divisÃ©s en plusieurs mots pour l'indexation. Par exemple, si maxnumeric est 4, "1342663" sera dÃ©composÃ© en "1342" et "663".  
+buildcol.mode:Les parties du processus de construction Ã  mener.
+buildcol.mode.all:Tout faire.
+buildcol.mode.build_index:Indexer le texte uniquement.
+buildcol.mode.compress_text:Compresser le texte uniquement.
+buildcol.mode.infodb:Construire la base de donnÃ©es des mÃ©ta-donnÃ©es uniquement.
+
+buildcol.no_default_images:Des images par dÃ©faut ne seront gÃ©nÃ©rÃ©es.
+
+buildcol.no_image_script:ATTENTION: script de fabrication d'images introuvable: %s
+
+buildcol.no_strip_html:Ne pas enlever les balises html du texte indexÃ© (utilisÃ© seulement pour les collections mgpp).
+
+buildcol.no_text:Ne pas stocker de texte compressÃ©. Cette option est utile pour la rÃ©duction de la taille des indexes incorporÃ©s si vous voulez toujours afficher les documents originaux en temps voulu (c'est Ã  dire que vous ne pouvez pas retrouver la version du texte compressÃ©).
+
+buildcol.sections_index_document_metadata:Indexe les mÃ©tadonnÃ©es de niveau document au niveau section  
+buildcol.sections_index_document_metadata.never:N'indexe aucune mÃ©tadonnÃ©e de document au niveau section.  
+buildcol.sections_index_document_metadata.always:Ajoute toutes les mÃ©tadonnÃ©es spÃ©cifiÃ©es d'un niveau document  mÃªme s'il existe une mÃ©tadonnÃ©es de niveau section de ce nom.  
+buildcol.sections_index_document_metadata.unless_section_metadata_exists:N' ajouter le document de niveau metadata que si le nom de section de niveau metadata n'existe pas.  
+
+buildcol.out:Nom de fichier ou de contrÃŽle vers lequel envoyer le statut de sortie.
+
+buildcol.params:[options] nom de collection
+
+buildcol.remove_empty_classifications:Cacher les nÅuds de classeurs et classification (ceux qui sont vides, sans documents)
+
+buildcol.removeold:Ãliminera les anciens contenus du rÃ©pertoire "building".  
+
+buildcol.unlinked_col_images:Les images de la collection peuvent ne pas Ãªtre correctement Ãªtre liÃ©es.
+
+buildcol.unknown_mode:Mode inconnu: %s
+
+buildcol.updating_archive_cache:Mise Ã  jour du cache d'archive
+
+buildcol.verbosity:ContrÃŽle la quantitÃ© de sortie. 0=aucun, 3= beaucoup.
+
+
+# -- classinfo.pl --
+
+classinfo.collection:En donnant un nom Ã  la collection fera que classinfo.pl va regarder d'abord dans collect/nom-de-collection/perlib/classify. Si le classificateur n'est pas trouvÃ©, il va alors chercher dans le rÃ©pertoire gÃ©nÃ©ral perlib/classify.
+
+classinfo.desc:Impime l'information sur un classificateur.
+
+classinfo.general_options:Options gÃ©nÃ©rales hÃ©ritÃ©es de classes parentes du classificateur.
+
+classinfo.info:info
+
+classinfo.no_classifier_name:ERREUR: Vous devez donner un nom de classificateur.
+
+classinfo.option_types:Les classificateurs peuvent prendre deux types d'options
+
+classinfo.params:[options] nom de classificateur
+
+classinfo.passing_options:Les options peuvent Ãªtre passÃ©es Ã  tout classificateur en les intÃ©grant au fichier de configuration de votre collection collect.cfg.
+
+classinfo.specific_options:Les options spÃ©cifiques sont dÃ©finies dans le classificateur lui mÃªme, et sont disponibles seulement pour ce classificateur particulier.
+
+# -- downloadfrom.pl --
+downloadfrom.cache_dir:L'emplacement du rÃ©pertoire cache  
+downloadfrom.desc:TÃ©lÃ©charger des fichiers Ã  partir d'un serveur externe  
+downloadfrom.download_mode:Le type de serveur Ã  partir duquel tÃ©lÃ©charger  
+downloadfrom.download_mode.Web:HTTP  
+downloadfrom.download_mode.MediaWiki:Site de MediaWiki  
+downloadfrom.download_mode.OAI:Initiative Archives Ouvertes  
+downloadfrom.download_mode.z3950:Serveur z3950  
+downloadfrom.download_mode.SRW:Service web SearchRetrieve  
+downloadfrom.incorrect_mode:Le paramÃštre Download_mode est incorrect.  
+downloadfrom.info:Imprimer les informations sur le serveur, plutÃŽt que le tÃ©lÃ©charger  
+downloadfrom.params:[options gÃ©nÃ©rales] [options spÃ©cifiques de tÃ©lÃ©chargement]  
+
+# -- downloadinfo.pl --
+
+downloadinfo.desc:Imprimer des informations sur un module de tÃ©lÃ©chargement  
+downloadinfo.collection:Donner un nom de collection fera regarder en premier downloadinfo.pl dans collecter/collection nom/perllib/tÃ©lÃ©chargeurs. Si le module n'est pas trouvÃ© lÃ , il regardera dans le rÃ©pertoire gÃ©nÃ©ral perllib/ tÃ©lÃ©chargeurs .  
+downloadinfo.params:[options] [module-tÃ©lÃ©chrgement]  
+downloadinfo.general_options:Les ptions gÃ©nÃ©rales sont hÃ©ritÃ©es des classes parents des modules de tÃ©lÃ©chargement .  
+downloadinfo.specific_options:Les options spÃ©cifiques sont dÃ©finis dans le module de tÃ©lÃ©chargement lui-mÃªme, et ne sont disponibles que pour ce tÃ©lÃ©chargeur.  
+downloadinfo.option_types:Les modules de tÃ©lÃ©chargement peuvent prendre deux types d'options  
+
+# -- explode_metadata_database.pl --
+explode.desc:Ãclater la base de donnÃ©es mÃ©ta-donnÃ©es.
+
+explode.collection:Le nom de la collection. Certains plugiciels recherchent des fichiers complÃ©mentaires dans le dossier de la collection.  
+ 
+explode.document_field:L'Ã©lÃ©ment de metadata indiquant le nom de fichier des documents Ã  obtenir et inclure dans la collection.
+
+explode.document_prefix:PrÃ©fixe pour localiser les documents (s'utilise avec l'option "document_field").
+
+explode.document_suffix:Suffixe pour localiser les documents (s'utilise avec l'option "document_field").
+
+explode.encoding:Encodage Ã  utiliser lors de la lecture de la base de donnÃ©es
+explode.metadata_set:Jeu mÃ©ta-donnÃ©es (espace nom) pour exporter toutes les mÃ©ta-donnÃ©es comme
+explode.plugin:Plugin Ã  utiliser pour Ã©clater
+explode.plugin_options:Options Ã  transmettre au plugiciel avant son utilisation. Les options doivent commencer par -. Il faut sÃ©parer les options et leurs valeurs par un espace. Ne peut pas Ãªtre utilisÃ© avec l'option -use_collection_plugin_options.  
+explode.use_collection_plugin_options:Lit le fichier de configuration de la collection et utilise les options propres au plugiciel. NÃ©cessite l'activation de l'option -collection. Ne peut pas Ãªtre utilisÃ© avec le paramÃštre -plugin_options.  
+explode.params:[options] nom de fichier
+explode.records_per_folder:Le nombre d'enregistrements Ã  mettre dans chaque sous-dossier.  
+
+# -- replace_srcdoc_with_html.pl --
+srcreplace.desc:Remplace le document source par le fichier HTML gÃ©nÃ©rÃ© lors de la reconstruction  
+srcreplace.params:[options] nom de fichier  
+srcreplace.plugin:Plugiciel Ã  utiliser pour convertir le document source  
+
+# -- exportcol.pl --
+
+exportcol.out:Nom de fichier ou de contrÃŽle vers lequel envoyer le statut de sortie.
+exportcol.cddir:Le nom du rÃ©pertoire oÃ¹ les contenus du CD sont exportÃ©s.  
+exportcol.cdname:Le nom du CD-ROM -- c'est ce qui va apparaÃ®tre dans le menu de dÃ©marrage une fois que le CD-ROM est installÃ©.
+exportcol.desc:Script PERL utilisÃ© pour exporter une ou plusieurs collections vers un CD-ROM Windows.
+exportcol.noinstall:CrÃ©er un CD-ROM oÃ¹ la bibliothÃšque s'Ã©xÃ©cute directement sur le CD-ROM et rien n'est installÃ© sur l'ordinateur hÃŽte.  
+exportcol.params:[options] nom de collection1 nom de collection 2âŠ
+exportcol.coll_not_found:Collection non valide %s ignorÃ©e: collection introuvable Ã  %s.
+exportcol.coll_dirs_not_found:Collection non valide %s ignorÃ©e: l'un des rÃ©pertoires suivants n'a pas Ã©tÃ© trouvÃ©:
+exportcol.fail:echec de export.pl:
+exportcol.no_valid_colls:Pas de collection valide spÃ©cifiÃ©e pour exportation
+exportcol.couldnt_create_dir:N'a pas pu crÃ©er rÃ©pertoire %s.
+exportcol.couldnt_create_file:N'a pas pu crÃ©er %s.
+exportcol.instructions:Pour crÃ©er un CD-ROM d'auto-installation pour Windows, Ã©crire les contenus de ce fichier dans un CD-ROM.
+exportcol.non_exist_files:Un ou plusieurs des fichiers et rÃ©pertoires nÃ©cessaires suivants n'existent pas:
+exportcol.success:succÃšs de export.pl:
+exportcol.output_dir:Les collections exportÃ©es (%s) sont dans %s.
+exportcol.export_coll_not_installed:La fonctionnalitÃ© de 'Exporter vers CD-Rom' n'a pas Ã©tÃ© installÃ©e.
+
+# -- import.pl --
+
+import.archivedir:LÃ  oÃ¹ finissent le matÃ©riau converti.
+
+import.manifest:Un fichier XML qui prÃ©cise quels sont les fichiers Ã  importer. UtilisÃ© Ã  la place de la descente rÃ©cursive du dossier de l'importation, gÃ©nÃ©ralement pour obtenir une construction incrÃ©mentale.  
+
+import.cannot_open_stats_file:ATTENTION: impossible d'ouvrir le fichier stats %s.
+
+import.cannot_open_fail_log:Erreur: N'a pas pu ouvrir le journal des Ã©checs %s
+
+import.cannot_sort:ATTENTION: le plugin d'importation ne peut pas trier les documents si groupsize > 1. L'option sortmeta sera ignorÃ©e.
+
+import.collectdir:Le chemin du rÃ©pertoire "collect".  
+
+import.complete:Fin de l'importation.
+
+import.debug:Imprimer le texte importÃ© vers STDOUT ( pour une importation au format GreenstoneXML)  
+
+import.desc:Script PERL utilisÃ© pour importer des fichiers dans un format prÃªt pour la construction (GreenstoneXML ou GreenstoneMETS).  
+
+import.faillog:Nom de fichier du log d'Ã©chec. Ce log reÃ§oit les noms de fichier de tous les fichiers qui n'ont pas pu Ãªtre traitÃ©s
+
+import.groupsize:Nombre de documents importÃ©s Ã  regrouper dans un fichier XML.
+
+import.gzip:Utiliser gzip pour compresser les documents xml de sortie (ne pas oublier d'intÃ©grer ZIPPLugin dans votre liste de plugins en construisant Ã  partir de documents compressÃ©s.
+
+import.importdir:lÃ  oÃ¹ se trouve le matÃ©riau original.
+
+import.incremental:Importe uniquement les documents qui sont plus rÃ©cents (par date) que les actuels fichiers d'archives. Implique -keepold.  
+
+import.keepold:Ne dÃ©truira pas les contenus actuels du rÃ©pertoire d'archives.  
+
+import.maxdocs:Nombre maximum de documents Ã  importer.
+
+import.no_import_dir:Erreur: le dossier d'importation (%s) n'a pas Ã©tÃ© trouvÃ©.  
+
+import.no_plugins_loaded:ERREUR: plugins non chargÃ©s
+
+import.OIDtype:La mÃ©thode Ã  utiliser pour produire des identificateurs uniques pour chaque document
+import.OIDtype.hash:Hashe le contenu du fichier. Les identifiants de documents sera la mÃªme Ã  chaque fois que la collection est importeÃ©.  
+
+import.OIDtype.incremental:Utilise un simple comptage de document. Beaucoup plus rapide que le "hachage", mais ne attribuera pas le mÃªme identifiant pour le mÃªme contenu de document, et d'autres documents ne peuvent pas Ãªtre ajoutÃ©es aux archives existantes.  
+
+import.OIDtype.assigned:Utiliser la valeur des mÃ©tadonnÃ©es fournies par l'option OIDmetadata (prÃ©cÃ©dÃ©e par "D"); si non spÃ©cifiÃ©e, Ã  un document de hachage est utilisÃ© Ã  la place. Ces identificateurs doivent Ãªtre uniques.  
+
+import.OIDtype.dirname:Utilisez le nom du rÃ©pertoire parent (prÃ©cÃ©dÃ© par 'J'). Il ne devrait Ãªtre qu'un document par rÃ©pertoire, et les noms de rÃ©pertoire doivent Ãªtre uniques. Par exemple Import/b13as/h15ef/page.html donnera un identifiant de Jh15ef.  
+
+import.OIDmetadata:SpÃ©cifie les Ã©lÃ©ments de mÃ©tadonnÃ©es qui dÃ©tiennent l'identificateur unique du document, pour une utilisation avec - OIDtype = assignÃ©s.  
+
+import.saveas:Format Ã  gÃ©nÃ©rer pour l'exportation. L'option par dÃ©faut est GA.  
+
+import.out:Nom de fichier ou contrÃŽle vers lequel envoyer le statut.
+
+import.params:[options] nom de collection
+
+import.removeold:Supprimera les anciens contenus du rÃ©pertoire d'archives.  
+
+import.removing_archives:Suppression des contenus du rÃ©pertoire d'archivesâŠ
+
+import.removing_tmpdir:Ãlimine les contenus du rÃ©pertoire "tmp" de la collection...  
+
+import.reversesort:Trie en ordre inverse. UtilisÃ© conjointement avec l'option -sortmeta.  
+
+import.site:Site oÃ¹ trouver le rÃ©pertoire collect (pour l'installation de Greenstone 3)  
+
+import.sortmeta:Trier pour la construction les documents par ordre alphabÃ©tique des mÃ©tadonnÃ©es. Les rÃ©sultats de la recherche pour les expressions boolÃ©ennes seront affichÃ©s dans cet ordre. Ceci sera dÃ©sactivÃ© si groupsize> 1. Pour trier par plus d'une valeur de mÃ©tadonnÃ©es, peut Ãªtre une liste sÃ©parÃ©e par des virgules.  
+
+import.statsfile:Nom de fichier ou contrÃŽle vers lequel envoyer les statistiques d'importation.
+
+import.stats_backup:Va plutÃŽt imprimer les stats vers STDERR.
+
+import.verbosity:ContrÃŽle la quantitÃ© de sortie. 0=aucun, 3=beaucoup.
+
+# -- schedule.pl --
+schedule.deleted:L'exÃ©cution planifiÃ©e a Ã©tÃ© supprimÃ©e pour la collection  
+schedule.scheduled:Script d'exÃ©cution crÃ©Ã© pour la collection.  
+schedule.cron:L'exÃ©cution planifiÃ©e a Ã©tÃ© activÃ©e pour la collection  
+schedule.params:[options]  
+schedule.error.email:L'option -email requiert que les paramÃštres -smtp, -toaddr et -fromaddr soient dÃ©finis.  
+schedule.error.importbuild:Les paramÃštres -import et -build doivent Ãªtre dÃ©finis.  
+schedule.error.colname:La collection doit Ãªtre spÃ©cifiÃ©e par le biais de l'option -colname  
+schedule.gli:LancÃ© Ã  partir de l'interface graphique.  
+schedule.frequency:DÃ©finit Ã  quelle frÃ©quence la collection doit Ãªtre reconstruite.  
+schedule.frequency.hourly:Reconstruire la collection toutes les heures.  
+schedule.frequency.daily:Reconstruire la collection tous les jours.  
+schedule.frequency.weekly:Reconstruire la collection toutes les semaines.  
+schedule.action:Comment activer la reconstruction automatique de collection.  
+schedule.action.add:Planifie la reconstruction automatique de collection.  
+schedule.action.update:Met Ã  jour une planification existante.  
+schedule.action.delete:Supprime une planification existante.  
+schedule.email:Envoie un e-mail de notification.  
+schedule.schedule:SÃ©lectionner pour activer la planification automatique de la reconstruction de la collection.  
+schedule.colname:Le nom de la collection pour laquelle la planification sera activÃ©e.  
+schedule.import:La commande d'importation Ã  planifier.  
+schedule.build:La commande de construction de collection (buildcol) Ã  planifier.  
+schedule.toaddr:L'adresse de courriel Ã  laquelle envoyer les avis de construction planifiÃ©e de la collection  
+schedule.toaddr.default:DÃ©finir l'adresse courriel de l'utilisateur dans le menu Fichier -> PrÃ©fÃ©rences.  
+schedule.fromaddr:L'adresse de courriel de l'expÃ©diteur.  
+schedule.fromaddr.default:SpÃ©cifier le responsable maintenance dans le fichier main.cfg.  
+schedule.smtp:Le serveur de courrier que sendmail doit contacter pour envoyer un courriel  
+schedule.smtp.default:SpÃ©cifier le serveur de messagerie (variable MailServer) dans le fichier main.cfg.  
+schedule.out:Fichier ou pointeur vers lequel rediriger le statut de sortie.  
+# -- export.pl --
+
+export.exportdir:Ou le matÃ©riel exportÃ© se termine
+
+export.cannot_open_stats_file:ATTENTION: Impossible d'ouvrir le fichier stats %s
+
+export.cannot_open_fail_log:ERREUR: Impossible d'ouvrir la log des Ã©checs %s
+
+export.cannot_sort:ATTENTION: export.pl ne peut trier les documents lorsque groupsize>1. L'option sortmeta sera ignorÃ©e.
+
+export.collectdir:Le chemin du rÃ©pertoire "collect".  
+
+export.complete:Exportation terminÃ©e
+
+export.debug:Imprimer le texte exportÃ© vers STDOUT (pour l'export au format GreenstoneXML)  
+
+export.desc:Script PERL utilisÃ© pour exporter des fichiers dans une collection Greenstone vers un autre format.  
+
+export.faillog:Nom du fichier journal d'Ã©chec. Ce journal reÃ§oit les noms de fichiers de tous les fichiers qui ne sont pas traitÃ©s. (Valeur par dÃ©faut: collectdir/collname/etc/fail.log)  
+
+export.groupsize:Nombre de documents Ã  regrouper dans un fichier XML.  
+
+export.gzip:Utiliser gzip pour compresser les documents xml rÃ©sultats (Noubliez pas d'insÃ©rer ZIPPlugin dans votre liste de plugins lorsque vous construisez Ã  partir de documents comprÃ©ssÃ©s.
+
+export.importdir:La ou le matÃ©riel original rÃ©side.
+
+export.keepold:Ne dÃ©truira pas les contenus actuels du rÃ©pertoire "export".  
+
+export.maxdocs:Nombre maximum de documents Ã  exporter.  
+
+export.listall:Recenser touts les formats Â«saveasÂ»  
+
+export.saveas:Format Ã  gÃ©nÃ©rer pour l'exportation.  
+
+export.saveas.DSpace:Format Archive DSPACE.  
+
+export.saveas.GreenstoneMETS:Format METS utilisant le profile Greenstone.
+export.saveas.FedoraMETS:Format METS utilisant le profil Fedora.  
+
+export.saveas.GreenstoneXML:Format d'archivage XML Greenstone  
+
+export.saveas.MARCXML:Format MARC XML (une version XML de MARC 21)  
+
+export.out:Nom de fichier ou sortie pour imprimer l'Ã©tat.
+
+export.params:[options] nom1-collection, nom2-collection...  
+
+export.removeold:Ãliminera le contenu du rÃ©pertoire "export".  
+
+export.removing_export:Suppression des contenus du rÃ©pertoire exportâŠ
+
+export.sortmeta:Trier les documents en ordre alphabÃ©tique des mÃ©ta-donnÃ©es pour la construction. DÃ©sactivÃ© si groupsize > 1.
+
+export.statsfile:Nom de fichier ou sortie pour imprimer les statistiques d'exportation.
+
+export.stats_backup:Va imprimer les stats sur STDERR
+
+export.verbosity:ContrÃŽle du volume de sortie. 0=aucun, 3=beaucoup.
+
+
+
+# -- mkcol.pl --
+
+mkcol.about:Le texte Ã  propos pour la collection.
+
+mkcol.bad_name_cvs:ERREUR: Aucune collection ne peut Ãªtre nommÃ©e CVS car cela pourrait interfÃ©rer avec des rÃ©pertoires de gestion de version de CVS.
+
+mkcol.bad_name_svn:ERREUR : aucune collection ne peut porter l'extension .svn, car cela pourrait interfÃ©rer avec les rÃ©pertoires crÃ©Ã©s par le systÃšme de versionnage SVN.  
+
+mkcol.bad_name_modelcol:ERREUR: Aucune collection ne peut Ãªtre nommÃ©e modelcol puisque c'est le nom de la collection modÃšle.
+
+mkcol.cannot_find_modelcol:ERREUR: impossible de trouver la collection modÃšle %s
+
+mkcol.col_already_exists:ERREUR: Cette collection existe dÃ©jÃ .
+
+mkcol.collectdir:Le rÃ©pertoire dans lequel la nouvelle collection va Ãªtre crÃ©Ã©e.
+
+mkcol.group_not_valid_in_gs3:L'option de groupe n'est pas valable dans le mode Greenstone 3 (-gs3mode).  
+mkcol.creating_col:CrÃ©ation de la collection %s
+
+mkcol.creator:L'adresse e-mail du crÃ©ateur de la collection.
+
+mkcol.creator_undefined:ERREUR: Le crÃ©ateur n'a pas Ã©tÃ© dÃ©fini. Cette variable est nÃ©cesaire pour reconnaÃ®tre les noms de collection dupliquÃ©s.
+
+mkcol.desc:Script PERL utilisÃ© pour crÃ©er la structure de rÃ©pertoire pour une nouvelle collection Greenstone.
+
+mkcol.doing_replacements:en train d'effectuer des remplacements pour %s
+
+mkcol.group:CrÃ©e un nouveau groupe de collection et non pas une simple collection.  
+
+mkcol.gs3mode:Mode pour les collections Greenstone 3.  
+
+mkcol.long_colname:ERREUR: Le nom de collection doit Ãªtre de moins de 8 caractÃšres afin de maintenir la compatibilitÃ© avec des sytÃšmes prÃ©cÃ©dents.
+
+mkcol.maintainer:L'adresse e-mail du maintenancier de la collection (si diffÃ©rent du crÃ©ateur).
+
+mkcol.no_collectdir:ERREUR: Le rÃ©pertoire de la collection n'existe pas: %s
+
+mkcol.no_collectdir_specified:ERREUR : aucun rÃ©pertoire collect n'a Ã©tÃ© dÃ©fini. Dans le mode gs3, l'option -site ou l'option -collectdir doivent Ãªtre dÃ©finies.  
+
+mkcol.no_colname:ERREUR: Aucun nom de collection n'a Ã©tÃ© spÃ©cifiÃ©.
+
+mkcol.optionfile:Prendre des options Ã  partir du fichier, utile dans des systÃšmes oÃ¹ des longues lignes de commandes peuvent poser des problÃšmes.
+
+mkcol.params:[option] nom de collection
+
+mkcol.plugin:Module plugin Perl Ã  utiliser (il peut y avoir plusieurs entrÃ©es de plugins).
+
+mkcol.public:Si cette collection a des accÃšs anonymes.  
+mkcol.public.true:La collection est publique  
+mkcol.public.false:La collection est privÃ©e  
+
+mkcol.quiet:Fonctionne en silence.
+
+mkcol.site:Dans gs3mode ce nom de site est conjointement utilisÃ© avec la variable d'environnement GSDL3HOME pour dÃ©terminer collectdir, sauf si -collectdir est spÃ©cifiÃ©.  
+
+mkcol.success:La nouvelle collection a Ã©tÃ© crÃ©e avec succÃšs Ã  %s
+
+mkcol.title:Le titre de la collection
+
+mkcol.win31compat:Est-ce que les noms de rÃ©pertoires doivent suivre le modÃšle Windows 3.1 ou non (c.a.d. 8 caractÃšres max).
+mkcol.win31compat.true:Nom du rÃ©pertoire : 8 caractÃšres maximum  
+mkcol.win31compat.false:Nom du rÃ©pertoire de longueur quelconque  
+
+# -- pluginfo.pl --
+
+pluginfo.collection:L'attribution d'un nom de colection fera que pluginfo.pl va rechercher d'abord dans collect/nom_de_collection/perllib/plugins. Si le plugin n'y est pas trouvÃ© il va alors chercher dans le rÃ©pertoire gÃ©nÃ©ral de logiciels/perlib.
+
+pluginfo.desc:Imprime l'information concernant un plugin.
+
+pluginfo.general_options:Les options gÃ©nÃ©rales sont hÃ©ritÃ©es des classes parentes du plugin.
+
+pluginfo.info:info
+
+pluginfo.no_plugin_name:ERREUR: Vous devez donner un nom de plugin.
+
+pluginfo.option_types:Les plugins peuvent prendre deux types d'options.
+
+pluginfo.params:[options] nom de plugin
+
+pluginfo.passing_options:Des options peuvent Ãªtre passÃ©es Ã  tous les plugins en les intÃ©grant dans votre fichier de configuration collect.cfg.
+
+pluginfo.specific_options:Les options spÃ©cifiques sont dÃ©finies au sein du plugin mÃªme, et sont disponibles uniquement pour ce plugin particulier.
+
+
+# -- plugoutinfo.pl --
+
+plugoutinfo.collection:Etant donnÃ© un nom de collection, on fera en premier pointer plugoutinfo.pl dans collecter/ collection nom/perllib/plugouts.  Si le "plugout" n'est pas trouvÃ© lÃ , on regardera dans le rÃ©pertoire gÃ©nÃ©ral perllib/plugouts.  
+
+plugoutinfo.desc:Imprimer l'informations sur un Â«plugoutÂ».  
+
+plugoutinfo.general_options:Les options gÃ©nÃ©rales sont hÃ©ritÃ©es de la classes parente du "plugout".  
+
+plugoutinfo.info:info  
+
+plugoutinfo.no_plugout_name:ERREUR: Vous devez fournir un nom de "plugout".  
+
+plugoutinfo.option_types:Les Plugouts peuvent prendre deux types d'options  
+
+plugoutinfo.params:[Options] nom-Â«plugoutÂ Â»  
+
+plugoutinfo.passing_options:Les options peuvent Ãªtre transmises Ã  des "plugout" en les incluant dans votre fichier de configuration collect.cfg .  
+
+plugoutinfo.specific_options:Les options spÃ©cifiques sont dÃ©finis dans le "plugout" lui-mÃªme, et ne sont disponibles que pour ce "plugout".  
+
+
+
+#
+# Classifier option descriptions
+#
+
+AllList.desc:CrÃ©e une liste unique de tous les documents. Utilisation par le serveur OAI.  
+
+AZCompactList.allvalues:Utiliser toutes les valeurs de mÃ©ta-donnÃ©es trouvÃ©es.
+
+AZCompactList.desc:Plugiciel de classificateur pour le tri alphabÃ©tique (dans l'ordre a-z,A-Z,0-9). Produit une liste AZ horizontale, puis une liste verticale contenant des documents, ou des Ã©tagÃšres pour les documents avec des mÃ©tadonnÃ©es communes.  
+
+AZCompactList.doclevel:Niveau oÃ¹ le document est traitÃ©.
+AZCompactList.doclevel.top:Tout le document.
+AZCompactList.doclevel.section:Par sections.
+
+AZCompactList.firstvalueonly:Utiliser uniquement la premiÃšre valeur de mÃ©tadonnÃ©es trouvÃ©e  
+
+AZCompactList.freqsort:Trier par frÃ©quence nodale plutÃŽt que de maniÃšre alpha-numÃ©rique.  
+
+AZCompactList.maxcompact:Nombre maximum de documents Ã  afficher par page.
+
+AZCompactList.metadata:Champ de mÃ©tadonnÃ©es, ou liste de champs de mÃ©tadonnÃ©es sÃ©parÃ©s par des virgules, utilisÃ© pour la classification. Si une liste est spÃ©cifiiÃ©e, le premier Ã©lÃ©ment de mÃ©ta-donnÃ©es qui a une valeur sera utilisÃ©. Peut Ãªtre utilisÃ© avec les options -firstvalueonly et -allvalues, pour sÃ©lectioner uniquement la premiÃšre valeur, ou toutes les valeurs de mÃ©tadonnÃ©es de la liste.  
+
+AZCompactList.mincompact:Nombre minimum de documents Ã  afficher par page.
+
+AZCompactList.mingroup:Valeur minimale qui entraÃ®nera la formation d'un groupe dans la hierarchie.  
+
+AZCompactList.minnesting:La valeur minimale qui entraÃ®nera la conversion d'une liste en liste imbriquÃ©e.  
+
+AZCompactList.recopt:UtilisÃ© dans des mÃ©tadonnÃ©es imbriquÃ©es tel que AnnÃ©e/Organisation  
+AZCompactList.sort:Champ de mÃ©tadonnÃ©es Ã  partir duquel les nÅuds externes seront triÃ©s.  
+
+AZCompactSectionList.desc:Variation sur AZCompactList qui classifie des sections plutÃŽt que des documents. Les entrÃ©es sont triÃ©es par mÃ©tadonnÃ©es de niveau section.  
+
+AZList.desc:Plugiciel de classificateur pour le tri alphabÃ©tique (dans l'ordre a-z,A-Z,0-9). Produit une liste AZ horizontale, avec les documents Ã©numÃ©rÃ©s ci-dessous.  
+
+AZList.metadata:Un champ de mÃ©ta-donnÃ©e unique ou une liste de champs de mÃ©ta-donnÃ©e sÃ©parÃ©s par des virgules utilisÃ© pour classification. En suivant l'ordre indiquÃ© par la liste, le premier champ qui contient  une valeur de mÃ©ta-donnÃ©e sera utilisÃ©. La liste sera triÃ©e suivant cet Ã©lÃ©ment.  
+
+AZSectionList.desc:Variation de AZList qui classe les sections plutÃŽt que les documents. Les entrÃ©es sont triÃ©es par les mÃ©tadonnÃ©es au niveau de la section.  
+
+BasClas.bad_general_option:Le classificateur %s utilise une mauvaise option. VÃ©rifiez votre fichier de configuration collect.cfg  
+
+BasClas.builddir:Endroit oÃ¹ les indexes construits vont Ãªtre mis.
+
+BasClas.buttonname:L'Ã©tiquette pour la fenÃªtre du classificateur et pour le bouton dans la barre de navigation. Le dÃ©faut est l' Ã©lÃ©ment de mÃ©tadonnÃ©es spÃ©cifiÃ© par -metadata.  
+
+BasClas.desc:Classe de base pour tous les classificateurs.
+
+BasClas.no_metadata_formatting:Ne faire aucun formatage automatique de mÃ©tadonnÃ©es (pour tri.)  
+
+BasClas.outhandle:Le pointeur vers le fichier qui va recevoir les rÃ©sultats.  
+
+BasClas.removeprefix:PrÃ©fixe Ã  ignorer dans les valeurs de mÃ©tadonnÃ©es lors du tri.  
+
+BasClas.removesuffix:Suffixe Ã  ignorer dans les valeurs de mÃ©tadonnÃ©es lors du tri.  
+
+BasClas.verbosity:ContrÃŽle le volume des sorties de donnÃ©es. 0=aucun, 3=beaucoup.  
+
+Browse.desc:Un classificateur factice qui fournit un lien dans la barre de navigation vers un prototype de page combinÃ©e de navigation et de recherche. Fonctionne uniquement pour les collections mgpp, et n'est pratique que pour les petites collections.  
+
+DateList.bymonth:Classifier par annÃ©e et par mois plutÃŽt que par annÃ©e seulement.
+
+DateList.desc:Plugiciel de classification pour le tri par date. Par dÃ©faut, il trie par la mÃ©tadonnÃ©e 'Date' . Les dates sont supposÃ©es Ãªtre en format aaaammjj ou aaaa-mm-jj.  
+
+DateList.metadata:La mÃ©tadonnÃ©e qui contient les dates pour le classement. Le format est supposÃ© Ãªtre aaaammjj ou aaaa-mm-jj. Peut Ãªtre une liste des valueurs sÃ©parÃ©es par des virgules, auquel cas la premiÃšre date de la liste sera utilisÃ©e.  
+
+DateList.reverse_sort:Trier les documents par ordre chronologique inverse (les plus rÃ©cents d'abord).  
+
+DateList.nogroup:CrÃ©er une entrÃ©e spÃ©cifique pour chaque annÃ©e dans la liste horizontale, au lieu de regrouper les annÃ©es dans quelques entrÃ©es. (Ceci peut aussi Ãªtre utilisÃ© en combinaison avec l'option -bymonth pour crÃ©er une entrÃ©e spÃ©cifique pour chaque mois au lieu de regrouper les mois dans quelques entrÃ©es.)  
+
+DateList.no_special_formatting:Ne pas afficher des informations AnnÃ©e et Mois dans liste de documents.  
+
+DateList.sort:Champ de mÃ©tadonnÃ©es supplÃ©mentaire pour le tri pour le cas oÃ¹ deux documents auraient la mÃªme date.  
+
+HFileHierarchy.desc:Plugiciel de classificateur pour gÃ©nÃ©rer des classifications hiÃ©rarchiques sur la base d'un fichier structurel supplÃ©mentaire.  
+
+Hierarchy.desc:Plugiciel Classificateur pour gÃ©nÃ©rer une classification hiÃ©rachique. Ceci peut Ãªtre basÃ© sur des mÃ©tadonnÃ©es structurÃ©es, ou peut utiliser un fichier de structure supplÃ©mentaire (utilisez l' option -hfile).  
+
+Hierarchy.documents_last:Affiche les nÅuds du document aprÃšs les nÅuds classificateurs.  
+
+Hierarchy.hfile:Utiliser le fichier de structure de classification spÃ©cifiÃ©.  
+
+Hierarchy.hlist_at_top:Affiche horizontalement le premier niveau de la classification.
+
+Hierarchy.reverse_sort:Trier les nÅuds feuilles en ordre inverse (utiliser avec -sort).
+
+Hierarchy.separator:Expression rÃ©guliÃšre utilisÃ©e pour le sÃ©parateur
+
+Hierarchy.sort:Champ de mÃ©ta-donnÃ©e suivant lequel trier. Utiliser '-sort nosort' pour dÃ©sactiver le tri.
+
+Hierarchy.suppressfirstlevel:Ignorer la premiÃšre partie de la valeur de mÃ©tadonnÃ©e. Ceci est utile pour des mÃ©tadonnÃ©es dont le premier Ã©lÃ©ment est connu, tel que le rÃ©pertoire d'import dans gsdlsourcefilename.  
+
+Hierarchy.suppresslastlevel:Ignorer la partie finale de la valeur de mÃ©ta-donnÃ©e. C'est particuliÃšrement utile pour des mÃ©ta-donnÃ©es dont chaque valeur est unique, telles que les chemins de fichiers.
+
+HTML.desc:CrÃ©e une classification vide qui qui est tout simplement un lien vers une page web.
+
+HTML.url:L'URL de la page web de destination.  
+
+List.bookshelf_type:ContrÃŽle Ã  quel moment seront crÃ©Ã©es les Ã©tagÃšres.  
+List.bookshelf_type.always:CrÃ©er une icÃŽne d'Ã©tagÃšre mÃªme s'il n'existe qu'un seul objet dans chaque groupe sur les noeuds terminaux.  
+List.bookshelf_type.never:Ne jamais crÃ©er une icÃŽne d'Ã©tagÃšre mÃªme s'il existe plus d'un objet dans chaque groupe sur les noeuds terminaux.  
+List.bookshelf_type.duplicate_only:CrÃ©er une icÃŽne d'Ã©tagÃšre seulement s'il existe plus d'un objet dans chaque groupe sur les noeuds terminaux.  
+
+List.classify_sections:Classe des sections au lieu de documents.
+
+List.desc:Un classificateur de liste gÃ©nÃ©ral et flexible avec la plupart des possibilitÃ©s de AZCompactList, mais avec un meilleur support de l'Unicode et une meileure capacitÃ© de tri.  
+
+List.level_partition.per_letter:CrÃ©er une partition pour chaque lettre.  
+List.level_partition.constant_size:CrÃ©er une partition de taille constante.  
+List.level_partition.per_letter_fixed_size:CrÃ©er une partition de taille Ã  peu prÃšs fixe pour chaque lettre.
+
+List.metadata:Les champs de mÃ©tadonnÃ©e utilisÃ©s pour la classification. Utiliser '/' pour sÃ©parer les niveaux dans la hiÃ©rarchie et ';' pour sÃ©parer les champs de mÃ©tadonnÃ©es dans chaque niveau.  
+
+List.partition_name_length:La longueur du nom de partition; valeurs par dÃ©faut d'une longueur variable de 1 Ã  3 caractÃšres, dÃ©pendant de combien sont nÃ©cessaires pour distinguer le dÃ©but de la partition de sa fin. Cette option ne s'applique que si partition_type_within_level est Ã  'constant_size'.
+
+List.partition_size_within_level:Le nombre d'Ã©lÃ©ments dans chaque division (ceci s'applique seulement quand la partition_type_within_level est mis Ã  'constant_size').
+
+List.partition_type_within_level:Le type de division effectuÃ© : soit 'par_lettre', 'taille_constante' ou 'aucune'.
+
+List.sort_leaf_nodes_using:Champs de mÃ©tadonnÃ©es utilisÃ©s pour trier les nÅuds extrÃªmes. Utiliser '|' pour sÃ©parer les groupes de mÃ©tadonnÃ©e en type table et ';' pour sÃ©parer les champs de mÃ©tadonnÃ©es dans chaque groupe.
+
+List.sort_using_unicode_collation:Trier en utilisant l'algorithme de rÃ©colement Unicode. NÃ©cessite le tÃ©lÃ©chargement du fichier http://www.unicode.org/Public/UCA/latest/allkeys.txt dans le dossier des librairies Perl lib/Unicode/Collate.
+
+List.use_hlist_for:Les champs de mÃ©tadonnÃ©es qui utilisent une hlist au lieu d'une vlist. Utiliser ',' pour sÃ©parer les groupes de mÃ©tadonnÃ©es et ';' pour sÃ©parer les champs de mÃ©tadonnÃ©es dans chaque groupe.
+
+SimpleList.metadata:Un champ de mÃ©tadonnÃ©e unique ou une liste de champs de mÃ©tadonnÃ©e sÃ©parÃ©s par des virgules utilisÃ©s pour classification. En suivant l'ordre indiquÃ© par la liste, le premier champ qui contient  une valeur de mÃ©tadonnÃ©e sera utilisÃ©. La liste sera triÃ©e suivant cet Ã©lÃ©ment, Ã  moins que -sort ne soit utilisÃ©. Si aucune mÃ©tadonnÃ©e n'est spÃ©cifiÃ©e, tous les documents seront inclus dans la liste, sinon seuls les documents qui contiennent une valeur de mÃ©tadonnÃ©e seront inclus.
+
+SimpleList.desc:Plugiciel de classificateur de liste simple.
+
+SimpleList.sort:Champ de mÃ©ta-donnÃ©e suivant lequel trier. Utiliser '-sort nosort' pour dÃ©sactiver le tri.
+
+Phind.desc:Produit une hiÃ©rarchie des phrases figurant dans le texte, qui est consultable par le biais d'une applet.  
+
+Phind.language:Langue ou langues Ã  utiliser pour la construction d'une hiÃ©rarchie. Les langues sont identifiÃ©es par des codes de pays Ã  deux lettres comme en (anglais), es (espagnole), fr (franÃ§ais). Langue est une expression ordinaire, donc 'en|fr' (anglais ou franÃ§ais) et '..' (toute langue) sont valides.
+
+Phind.min_occurs:Le nombre minimum de fois qu'une phrase doit apparaÃ®tre dans le texte pour faire partie de la hiÃ©rarchie des phrases.
+
+Phind.savephrases:Lorsque dÃ©finie, l'information d'expression sera stockÃ©e comme texte dans le fichier spÃ©cifiÃ©. C'est probablement une bonne idÃ©e d'utiliser une chemin absolu.
+
+Phind.suffixmode:Le paramÃštre smode du programme d'extraction d'expression. Une valeur 0 signifie que les mots d'arrÃªt sont ignorÃ©s et 1 signifie que les mots d'arrÃªts sont utilisÃ©s.
+
+Phind.text:Le texte utilisÃ© pour construire la hierarchie d'expression.
+
+Phind.thesaurus:Nom d'un thÃ©saurus stockÃ© au format Phind dans le repertoire etc de la collection.
+
+Phind.title:Le champ de mÃ©ta-donnÃ©e utilisÃ© pour dÃ©crire chaque document.
+
+Phind.untidy:Ne pas supprimer les fichiers actifs.
+
+RecentDocumentsList.desc:Classificateur qui donne une liste des documents nouvellement ajoutÃ©s ou modifiÃ©s.  
+
+RecentDocumentsList.include_docs_added_since:Inclure uniquement les documents ajoutÃ©s ou modifiÃ©s aprÃšs la date spÃ©cifiÃ©e (au format  aaaammjj ou aaaa-mm-jj).  
+
+RecentDocumentsList.include_most_recently_added:Inclure uniquement le nombre spÃ©cifiÃ© des documents les plus rÃ©cemment ajoutÃ©s. Uniquement utilisÃ© si include_docs_added_since n'est pas spÃ©cifiÃ©.  
+
+RecentDocumentsList.sort:MÃ©tadonnÃ©es pour trier par liste. S'il n'est pas spÃ©cifiÃ©, la liste sera triÃ©e par date de modification/ajout.  
+
+SectionList.desc:Comme le classificateur List, mais inclut toutes les sections du document (Ã  l'exception du niveau supÃ©rieur) plutÃŽt que le document de niveau supÃ©rieur seulement.
+
+Collage.desc:Un applet est utilisÃ© pour afficher un collage d'images trouvÃ©es dans la collection.  
+
+Collage.geometry:Les dimensions de la toile de fond du collage. Pour un fond de 600 pixels de large et 400 pixels de haut par example, indiquez la gÃ©omÃ©trie comme 600x400  
+
+Collage.maxDepth:Les images pour le collage sont obtenues d'une mise en miroir du classificateur utilisÃ©. Ce paramÃštre contrÃŽle la profondeur maximum du processus de mise en miroir.  
+
+Collage.maxDisplay:Le nombre maximum d'images Ã  afficher dans le collage Ã  un moment donnÃ©.  
+
+Collage.imageType:UtilisÃ© pour contrÃŽler, en spÃ©cifiant les extensions de nom de fichier, quels types de fichier sont utilisÃ©s pour le collage. Une liste d'extensions est sÃ©parÃ©e par le caractÃšre pourcent (%%).  
+
+Collage.bgcolor:La couleur d'arriÃšre plan de la toile de fond, indiquÃ©e sous forme hexadÃ©cimale (par exemple #008000 a comme consÃ©quence un arriÃšre plan vert forÃªt).
+
+Collage.buttonname:L'Ã©tiquette pour l'Ã©cran de classificateur et pour le bouton dans la barre de navigation  
+
+Collage.refreshDelay:Taux, en millisecondes, de rafraichissement de la toile de fond du collage.  
+
+Collage.isJava2:UtilisÃ© pour contrÃŽler l'utilisation des classes "runtime" de Java. Les versions le plus rÃ©centes de Java (c.-Ã -d. Ã  partir de Java 1.2) incluent des fonctions plus avancÃ©es pour contrÃŽler la transparence des images, ce qui permet un contrÃŽle plus fin ; toutefois le "Java runtime" intÃ©grÃ© dans certain navigateurs est la version 1,1. L'applet dÃ©tecte automatiquement la version du "Java runtime" utilisÃ©e par le navigateur et rÃ©agit en consÃ©quence.  
+
+Collage.imageMustNotHave:UtilisÃ© pour supprimer les images qui ne devraient pas apparaÃ®tre dans le collage, telles que les images des boutons qui composent la barre de navigation.
+
+Collage.caption:Sous-titres facultatifs Ã  afficher au-dessous de la toile de fond.
+
+
+#
+# Plugin option descriptions
+#
+AcronymExtractor.adding:ajout
+
+AcronymExtractor.already_seen:dÃ©jÃ  vu
+
+AcronymExtractor.desc:Plugiciel d'aide Ã  l'extraction pour la localisation et le balisage des acronymes dans un texte.  
+
+AcronymExtractor.done_acronym_extract:extraction des acronymes terminÃ©e.
+
+AcronymExtractor.done_acronym_markup:balisage des acronymes terminÃ©.  
+
+AcronymExtractor.extract_acronyms:Extraire les acronymes du texte et les dÃ©finir comme mÃ©tadonnÃ©es.  
+
+AcronymExtractor.extracting_acronyms:extraction d'acronymes
+
+AcronymExtractor.marking_up_acronyms:balisage des acronymes  
+
+AcronymExtractor.markup_acronyms:Ajouter des mÃ©tadonnÃ©es d'acromyme au texte du document  
+
+ArchivesInfPlugin.desc:Plugiciel qui traite la base de donnÃ©es d'informations sur les archives (archiveinf-doc.gdb) qui est gÃ©nÃ©rÃ©e pendant le processus d'importation. Il transmet chaque fichier d'archive rÃ©fÃ©rencÃ© dans la base au pipeline de plugiciels pour Ãªtre traitÃ© par GreenstoneXMLPlugin.  
+
+AutoExtractMetadata.desc:Plugiciel de base qui rassemble toutes les fonctionnalitÃ©s d'extraction des plugiciels d'extraction.  
+
+AutoExtractMetadata.extracting:Extraction
+
+AutoExtractMetadata.first:Liste (en format valeurs sÃ©parÃ©es par des virgules) des nombres de caractÃšres Ã  extraire Ã  partir du dÃ©but du texte pour peupler une sÃ©rie de champs de mÃ©tadonnÃ©es appelÃ©s 'FirstN', oÃ¹ N est la taille d'une mÃ©tadonnÃ©e en nombre de caractÃšres. Par exemple, les valeurs "3,5,7" aura pour effet le transfert des premiers 3, 5 et 7 caractÃšres du texte vers les champs de mÃ©tadonnÃ©es "First3", "First5" and "First7". 
+
+BaseMediaConverter.desc:Plugiciel d'aide qui fournit les fonctionnalitÃ©s de base aux plugiciels de conversion des formats multimÃ©dia tels qu'ImageConverter et les convertisseurs de vidÃ©o.  
+
+BasePlugin.associate_ext:Associe les fichiers ayant le mÃªme nom principal de fichier que le document traitÃ© par le plugiciel ET une extension de fichier provenant de la liste de valeurs sÃ©parÃ©es par des virgules donnÃ©e par cet argument au document en cours de traitement plutÃŽt que les manipuler comme une liste sÃ©parÃ©e.  
+
+BasePlugin.associate_tail_re:Une expression rÃ©guliÃšre utilisÃ©e pour reconnaÃ¯tre les noms des fichiers associÃ©s. UtilisÃ© comme option plus puissante qu'associate_ex/  
+
+BasePlugin.block_exp:Les fichiers qui correspondent Ã  cette expression rÃ©guliÃšre ne seront pas passÃ©s aux plugiciels qui viennent aprÃšs dans la liste.  
+
+BasePlugin.desc:Classe de base pour tous les plugiciels d'importation.  
+
+BasePlugin.dummy_text:Ce document n'a pas de texte.
+
+BasePlugin.encoding.ascii:ASCII ordinaire 7 bits. Ceci pourrait Ãªtre un peu plus rapide que l'utilisation d'iso_8859_1. Cependant, faites attention si le texte peut contenir des caractÃšres hors ASCII ordinaire 7 bits (par ex. textes en allemand ou en franÃ§ais qui comportent des accents), dans ce cas utiliser iso_8859_1.  
+
+BasePlugin.encoding.unicode:Unicode seulement.
+
+BasePlugin.encoding.utf8:Utf8 ou unicode -- dÃ©tectÃ© automatiquement  
+
+BasePlugin.filename_encoding:Encodage des noms des fichiers sources.  
+
+BasePlugin.filename_encoding.auto:DÃ©tecter automatiquement l'encodage du nom de fichier.  
+
+BasePlugin.filename_encoding.auto_language_analysis:DÃ©tecter automatiquement l'encodage par l'analyse du nom de fichier.  
+
+BasePlugin.filename_encoding.auto_filesystem_encoding:DÃ©tecter automatiquement l'encodage du nom de fichier en utilisant l'encodage du systÃšme de fichiers.  
+
+BasePlugin.filename_encoding.auto_fl:Utilise l'encodage du systÃšme de fichiers puis l'analyse de la langue pour dÃ©tecter l'encodage du nom de fichier.  
+
+BasePlugin.filename_encoding.auto_lf:Utilise l'analyse de la langue puis l'encodage du systÃšme de fichiers pour dÃ©tecter l'encodage du nom de fichier.  
+
+BasePlugin.no_blocking:Importer tous les fichiers. Tous les fichiers associÃ©s (images dans une page web, etc.) seront ajoutÃ©s Ã  la collection comme des documents indÃ©pendants.  
+
+BasePlugin.no_cover_image:Ne pas rechercher un fichier prÃ©fix.jpg (prÃ©fix Ã©tant le mÃªme prÃ©fix que celui du fichier en cours de traitement) pour associer en tant qu'image de couverture.  
+
+BasePlugin.OIDtype.auto:Utiliser l'OIDtype dÃ©fini dans import.pl  
+
+BasePlugin.process_exp:Expression rÃ©guliÃšre de Perl Ã  faire correspondre Ã  des noms de fichiers. Les fichiers correspondants seront traitÃ©s avec ce plugiciel. Par exemple, l'usage de '(?i).html?\$' fait correspondre tous les documents terminant en .htm ou en .html (indÃ©pendemment de la casse).  
+
+BasePlugin.smart_block:Bloquer les fichiers d'une faÃ§on plus flexible qu'en regardant le nom du fichier.  
+
+BasePlugin.stems:racines  
+
+BasePlugin.file_rename_method:La mÃ©thode Ã  utiliser pour renommer la copie du fichier importÃ© et ses fichiers associÃ©s.  
+
+BasePlugin.rename_method.url:Utiliser un encodage basÃ© sur l'adresse URL pour renommer les fichiers importÃ©s et les fichiers qui leur sont associÃ©s.  
+
+BasePlugin.rename_method.base64:Utiliser un encodage base64 pour renommer les fichiers importÃ©s et les fichiers qui leur sont associÃ©s.  
+
+BasePlugin.rename_method.none:Ne pas renommer les fichiers importÃ©s et les fichiers qui leur sont associÃ©s.  
+
+BibTexPlugin.desc:BibTexPlugin lit les fichiers bibliographiques en format BibTex. BibTexPlugin crÃ©e un objet document pour chaque rÃ©fÃ©rence dans le fichier. Ce plugiciel est une sous-classe de la classe SplitTextFile, donc s'il y a plusieurs enregistrements, ils sont tous lus.  
+
+BookPlugin.desc:CrÃ©e un document Ã  niveaux multiples Ã  partir d'un document contenant les balises de niveau <<TOC>>. Les mÃ©tadonnÃ©es pour chaque section sont extraites Ã  partir des autres balises se trouvant sur la mÃªme ligne que <<TOC>>. Par exemple, <<Title>>xxxx<</Title>> dÃ©finit une mÃ©tadonnÃ©e de titre. Tout le reste entre des balises TOC est traitÃ© comme du simple html (c.-Ã -d. aucun traitement de type HTMLPlugin, tel que la prise en compte des liens HTML, n'est effectuÃ©). Les fichiers d'entrÃ©e sont supposÃ©s avoir l'extension .hb par dÃ©faut (cela peut Ãªtre changÃ© en ajoutant une option -process_exp); un fichier avec le mÃªme nom principal que celui du fichier hb mais une extension .jpg est prise comme image de couverture (les fichiers jpg sont bloquÃ©s par ce plugin). BookPlugin est une simplification (et une extension) de HBPlugin qui est utilisÃ© par les collections BibliothÃšque du DÃ©veloppement Humanitaire. BookPlugin est plus rapide mais il s'attend Ã  ce que les fichiers d'entrÃ©e soient plus propres (Les documents source pour collections HDL contiennent diverses balises html autour de <<TOC>>, utilisent des balises <<I>> pour spÃ©cifier les images, et interprÃ©tant tout simplement tout le texte aprÃšs une balise <<TOC>> et sur la mÃªme ligne que celle-ci comme Ã©tant la mÃ©tadonnÃ©e Titre). Si vous dÃ©sirez baliser un document pour qu'il soit affichÃ© de la mÃªme maniÃšre que dans les collections HDL, utilisez ce plugiciel au lieu de HBPlugin.  
+
+CONTENTdmPlugin.desc:Plugiciel qui traite les fichiers RDF dans les collections CONTENTdm exportÃ©es.  
+
+ConvertBinaryFile.apply_fribidi:ExÃ©cutez le programme d'algorithme bidirectional d'Unicode "fribidi" pour le fichier convertit (pour texte de droite-Ã -gauche).  
+
+ConvertBinaryFile.convert_to:Ce plugiciel convertit en TEXT, en HTML ou en diffÃ©rents types de format d' images (par ex : JPEG, GIF, PNG).  
+
+ConvertBinaryFile.convert_to.auto:SÃ©lectionnez aussi automatiquement le format cible. Ce format dÃ©pend du type de document d'entrÃ©e, par exemple les fichiers Word seront automatiquement convertit en HTML, alors que PowerPoint sera convertit en format PagedImage de Greenstone.  
+
+ConvertBinaryFile.convert_to.html:Format HTML  
+
+ConvertBinaryFile.convert_to.text:Format de texte simple  
+
+ConvertBinaryFile.convert_to.pagedimg:Une sÃ©rie d'images  
+
+ConvertBinaryFile.convert_to.pagedimg_jpg:Une sÃ©rie d'images en format JPEG.  
+
+ConvertBinaryFile.convert_to.pagedimg_gif:Une sÃ©rie d'images en format GIF.  
+
+ConvertBinaryFile.convert_to.pagedimg_png:Une sÃ©rie d'images en format PNG.  
+
+ConvertBinaryFile.desc:Ce plugiciel est utilisÃ© par des plugiciels tels que WordPlugin, PPTPlugin, PSPlugin, RTFPlugin et PDFPlugin. Il facilite la conversion de ces types de documents Ã  la fois en HTML, en TEXT ou en une sÃ©rie d'images. Il agit par chargement dynamique d'un plugiciel secondaire (HTMLPlugin, StructuredHTMLPlugin, PagedImgPlugin ou TextPlugin) en tenant compte de l'argument de plugiciel  'convert_to '.  
+
+ConvertBinaryFile.keep_original_filename:Conserver le nom de fichier d'origine pour le fichier associÃ©, plutÃŽt que de le transformer en doc.pdf, doc.doc etcâŠ  
+
+ConvertBinaryFile.use_strings:S'il est activÃ©, une simple fonction de chaÃ®ne sera appelÃ©e pour extraire le texte si l'utilitaire de conversion Ã©choue.  
+
+ConvertToRogPlugin.desc:Un plugiciel qui hÃ©rite de RogPlugin.  
+
+CSVPlugin.desc:Un plugiciel pour les fichiers en format de valeurs sÃ©parÃ©s par des virgules. Un nouveau document sera crÃ©Ã© pour chaque ligne du fichier.  
+
+DateExtractor.desc:Plugiciel d'aide pour extraire d'un texte des informations sur les dates historiques.  
+
+DateExtractor.extract_historical_years:Extraire des informations temporelles des documents historiques. Celles-ci sont stockÃ©es comme mÃ©tadonnÃ©es avec le document. Il y a une interface de recherche pour cette mÃ©tadonnÃ©e que vous pouvez inclure dans votre collection en ajoutant la formule ''format QueryInterface DateSearch'' dans le fichier de configuration de votre collection.  
+
+DateExtractor.maximum_century:Le siÃšcle le plus rÃ©cent Ã  extraire comme mÃ©tadonnÃ©e historique (par ex. : 14 aura pour effet d'extraire toutes les rÃ©fÃ©rences jusqu'au 14Ãšme siÃšcle).  
+
+DateExtractor.maximum_year:La date historique la plus rÃ©cente Ã  utiliser comme mÃ©tadonnÃ©e (dans une date d'Ãšre commune, comme 1950).  
+
+DateExtractor.no_bibliography:Ne cherchez pas Ã  bloquer les dates bibliographiques lors de l'extraction de dates historiques.
+
+DirectoryPlugin.desc:Plugiciel qui analyse les rÃ©pertoires rÃ©cursivement, en traitant les fichiers trouvÃ©s.  
+
+DirectoryPlugin.recheck_directories:Une fois le traitement des fichiers dans un rÃ©pertoire d'importation terminÃ©, vÃ©rifiez le rÃ©pertoire pour voir si des nouveaux fichiers ont Ã©tÃ© crÃ©Ã©s.  
+
+DirectoryPlugin.use_metadata_files:OBSOLETE - Ajouter MetadataXMLPlug Ã  la liste des plugiciels pour lire des mÃ©tadonnÃ©es Ã  partir de fichiers de mÃ©tadonnÃ©es XML.  
+
+DatabasePlugin.desc:Plugiciel qui importe des enregistrements d'une base de donnÃ©es. Il utilise le module perl DBI, qui comprend des interfaces pour mysql, postgresql, les fichiers de valeurs sÃ©parÃ©es par des virgules (CSV), MS Excel, ODBC, sybase, etc... Il peut Ãªtre nÃ©cessaire d'installer des modules supplÃ©mentaires pour l'utiliser. Voir <GSDLHOME>/etc/packages/example.dbi pour un exemple de fichier de configuration.  
+
+DSpacePlugin.desc:Plugiciel qui prend une collection de documents exportÃ©s de DSpace et les importe dans Greenstone.  
+	
+DSpacePlugin.first_inorder_ext:Ceci est utilisÃ© pour identifier le fichier de document primaire parmi les fichiers d'un document d'une collection DSpace. Quand cette option est active, les documents des types ext dÃ©finis seront examinÃ©s en sÃ©quence par le systÃšme pour rechercher le documents primaire.  
+
+DSpacePlugin.first_inorder_mime:Ceci est utilisÃ© pour identifier le fichier de document primaire parmi les fichiers d'un document d'une collection DSpace. Quand cette option est active, les documents des types mime dÃ©finis seront examinÃ©s en sÃ©quence par le systÃšme pour rechercher le documents primaire.  
+
+DSpacePlugin.only_first_doc:Ceci est utilisÃ© pour identifier le fichier de document primaire parmi les fichiers d'un document d'une collection DSpace. Quand cette option est active, le premier document rÃ©fÃ©rencÃ© dans le fichier de metadonnÃ©s dublin_core sera identifiÃ© par le systÃšme comme document primaire.  
+
+EmailAddressExtractor.desc:Plugiciel d'aide Ã  l'extraction pour dÃ©tecter les adresses e-mail dans le texte.  
+
+EmailAddressExtractor.done_email_extract:extraction des adresses e-mail terminÃ©e.
+
+EmailAddressExtractor.extracting_emails:extraction d'adresses e-mail
+
+EmailAddressExtractor.extract_email:Extraire les adresses e-mail en tant que mÃ©tadonnÃ©es.  
+
+EmailPlugin.desc:Plugiciel qui lit les fichiers e-mail. Ceux-ci sont nommÃ©s simplement avec un numÃ©ro (c'est-Ã -dire comme ils apparaissent dans les dossiers maildir) ou avec l'extension .mbx (pour format de fichier courrier mbox).\nTexte de document : Le texte de document est composÃ© de tout le texte situÃ© aprÃšs la premiÃšre ligne vide du document.\nMÃ©tadonnÃ©es (pas Dublin Core  !):\n\t\$Headers    Tout le contenu en tÃªte (facultatif, il n'est pas emmagasinÃ© par defaut)\n\t\$Subject     Objet: en-tÃªte\n\t\$To        A: en-tÃªte\n\t\$From     De: en-tÃªte\n\t\$FromName    Nom de l'expÃ©diteur (si disponible)\n\t\$FromAddr    Adresse Ã©lectronique de l'expÃ©diteur\n\t\$DateText     Date: en-tÃªte\n\t\$Date   Date: en-tÃªte en format GSDL (par ex. 19990924)  
+
+EmailPlugin.no_attachments:Ne pas sauvegarder les fichiers attachÃ©s aux messages.  
+
+EmailPlugin.headers:Emmagasiner tous les en-tÃªtes d'un e-mail dans la mÃ©tadonnÃ©e "Headers".  
+
+EmailPlugin.OIDtype.message_id:Utiliser l'identifiant du message comme l'OID du document. SI aucun identifiant de message n'est trouvÃ©, utiliser un identifiant de hachage.  
+
+EmailPlugin.split_exp:Expression rÃ©guliÃšre perl utilisÃ©e pour scinder en documents sÃ©parÃ©s les fichiers contenant plusieurs messages.  
+
+ExcelPlugin.desc:Plugiciel pour importer des fichiers Microsoft Excel (les versions 95 et 97).  
+
+FavouritesPlugin.desc:Plugiciel pour traiter les fichiers de favoris d'Internet Explorer.  
+
+FOXPlugin.desc:Plugiciel pour traiter un fichier Foxbase dbt. Ce plugiciel fournit une fonctionnalitÃ© de base pour lire les fichiers dbt et dbf et pour traiter chaque enregistrement. Il faudrait Ã©crire un plugiciel personnalisÃ© sur la base de ce plugiciel gÃ©nÃ©ral afin de traiter les champs appropriÃ©s d'une base de donnÃ©es spÃ©cifique.  
+
+GreenstoneXMLPlugin.desc:Traite les documents des Archives Greenstone XML. Notez que ce plugiciel ne fait pas de test de syntaxe (bien que le module XML::Parser vÃ©rifie que les documents soient bien formÃ©s). Il est supposÃ© que les fichiers d'Archives Greenstone se conforment Ã  leur DTD.  
+
+GISExtractor.desc:Plugiciel d'aide pour l'extraction des noms des lieux Ã  partir du texte. NÃ©cessite l'extension GIS de Greenstone.  
+
+GISExtractor.extract_placenames:Extraire les noms des lieux du texte et les dÃ©finir en tant que mÃ©tadonnÃ©es. NÃ©cessite l'extension GIS de Greenstone.  
+
+GISExtractor.gazetteer:Atlas Ã  utiliser pour extraire les noms des lieux du texte et les dÃ©finir en tant que mÃ©tadonnÃ©es. NÃ©cessite l'extension GIS de Greenstone.  
+
+GISExtractor.place_list:Lors de l'extraction des emplacements, contient la liste des noms d'emplacements au dÃ©but du document. NÃ©cessite l'extension GIS de Greenstone.  
+
+HBPlugin.desc:Plugiciel qui traite un rÃ©pertoire de livres en HTML. Ce plugiciel est utilisÃ© par les collections BibliothÃšque du DÃ©veloppement Humanitaire et ne traite pas d'encodages d'entrÃ©e autres qu'ASCII et ASCII Ã©tendu. Le code n'est pas du tout joli et on pourrait sÃ»rement Ãªtre rendu plus rapide. En le laissant tel quel, nous espÃ©rons encourager l'utilsation de BookPlugin comme alternative ;-) \n\n Utilisez BookPlugin pour crÃ©er une nouvelle collection si vous utilisez le mÃªme langage de balisage de fichiers que celui des collections BibliothÃšque du DÃ©veloppement Humanitaire. BookPlugin accepte tous les encodages d'entrÃ©e mais exige un balisage de fichiers plus propre que celui requis dans les collections BibliothÃšque du DÃ©veloppement Humanitaire.  
+
+HBPlugin.encoding.iso_8859_1:Latin1 (Europe occidentale)  
+
+HTMLImagePlugin.aggressiveness:Choix de mÃ©thodes apparentÃ©es d'extraction de texte Ã  utiliser.  
+HTMLImagePlugin.aggressiveness.1:Nom de fichier, chemin d'accÃšs et texte alternatif (attributs ALT dans des balises img de HTML) uniquement.  
+HTMLImagePlugin.aggressiveness.2:NÂ° 1, ainsi que la lÃ©gende si disponible.  
+HTMLImagePlugin.aggressiveness.3:NÂ° 2, ainsi que les paragraphes proches si disponibles.  
+HTMLImagePlugin.aggressiveness.4:NÂ° 3, ainsi que les titres prÃ©cÃ©dents (<h1>, <h2>...) si disponibles.  
+HTMLImagePlugin.aggressiveness.5:NÂ° 4, ainsi que les rÃ©fÃ©rences textuelles si elles sont disponibles.  
+HTMLImagePlugin.aggressiveness.6:NÂ° 4, ainsi que les balises de mÃ©tadonnÃ©es dans des pages HTML (titre, mots-clÃ©s, etc.)  
+HTMLImagePlugin.aggressiveness.7:NÂ° 6, NÂ° 5 et NÂ°4 combinÃ©s.  
+HTMLImagePlugin.aggressiveness.8:NÂ° 7, en dupliquant le nom de fichier, le chemin d'accÃšs, le texte alternatif et la lÃ©gende (pour augmenter le poids des rÃ©sultats les plus pertinents)  
+HTMLImagePlugin.aggressiveness.9:NÂ° 1, ainsi que le texte intÃ©gral de la page d'origine.  
+
+HTMLImagePlugin.caption_length:Longueur maximale des extraits (en caractÃšres)  
+
+HTMLImagePlugin.convert_params:ParamÃštres supplÃ©mentaires Ã  transmettre Ã  ImageMagick lors de la crÃ©ation des vignettes. Par exemple, '-raise' donnera un effet 3D aux vignettes.  
+
+HTMLImagePlugin.desc:Un plugiciel pour extraire les images et le texte associÃ© des pages web.  
+
+HTMLImagePlugin.document_text:Ajoute le texte de l'image en tant que document:text (sinon en tant que champs de mÃ©tadonnÃ©es IndexedText).  
+
+HTMLImagePlugin.index_pages:Indexe les pages en mÃªme temps que les images. Sinon, rÃ©fÃ©rence les pages comme l'URL source.  
+
+HTMLImagePlugin.max_near_text:Le nombre maximal de caractÃšres Ã  extraire autour des images.  
+
+HTMLImagePlugin.min_height:Pixels. Ne pas traiter les images plus petites que cette taille.  
+
+HTMLImagePlugin.min_near_text:Nombre minimal de caractÃšres Ã  extraire du texte voisin ou de la lÃ©gende.  
+
+HTMLImagePlugin.min_size:Bytes. Ne pas traiter les images plus petites que cette taille.  
+
+HTMLImagePlugin.min_width:Pixels. Ne pas traiter les images plus petites que cette taille.  
+
+HTMLImagePlugin.neartext_length:Longueur cible du texte voisin (en caractÃšres).  
+
+HTMLImagePlugin.no_cache_images:Ne pas mettre les images en cache (pointer directement sur l'URL d'origine).  
+
+HTMLImagePlugin.smallpage_threshold:Les images sur les pages plus petites que cette taille (bytes) auront la page de mÃ©ta-donnÃ©es (titre, mots-clÃ©s, etc.) ajoutÃ©e.  
+
+HTMLImagePlugin.textrefs_threshold:Seuil pour les rÃ©fÃ©rences textuelles. Une valeur plus faible signifie que l'algorithme est moins stricte.  
+
+HTMLImagePlugin.thumb_size:Taille maximale des vignettes. Valable pour la largeur ou la longueur.  
+
+HTMLPlugin.assoc_files:Expression perl d'extensions de fichiers Ã  associer avec des documents html.
+
+HTMLPlugin.desc:Ce plugin traite les fichiers HTML
+
+HTMLPlugin.description_tags:Scinder le document en sous-sections oÃ¹ apparaissent des balises<Section> . '- Keep_head' n'aura aucun effet si cette option est activÃ©e.  
+
+HTMLPlugin.extract_style:Extraire le style et les  informations du script de la balise HTML <head> et enregistrer dans la mÃ©tadonnÃ©e DocumentHeader. Ce sera dÃ©fini dans la page document comme la macro _document: documentheader_ .  
+
+HTMLPlugin.file_is_url:DÃ©fini si les noms de fichiers d'entrÃ©e constituent l'url des documents source d'origine, p.ex. si un outil de "mirroring" a Ã©tÃ© utilisÃ© pour crÃ©er la structure du rÃ©pertoire d'importation.
+
+HTMLPlugin.hunt_creator_metadata:Trouver autant de mÃ©tadonnÃ©es que possible sur l'auteur et les placer dans le champ 'Creator'.  
+
+HTMLPlugin.keep_head:Ne pas supprimer les en-tÃªtes des fichiers html.
+
+HTMLPlugin.metadata_fields:Liste de champs de mÃ©tadonnÃ©es Ã  essayer d'extraire, sÃ©parÃ©s par des virgules. Utiliser l'expression 'tag<nom de balise>' pour mettre le contenu de la premiÃšre paire de <nom de balise> dans l'Ã©lÃ©ment de mÃ©tadonnÃ©es 'nom de balise'. Utiliser les majuscules parce que les Ã©lÃ©ments de mÃ©tadonnes sont capitalisÃ©s en Greenstone, et l'extraction des balises ne tient pas compte de la casse.  
+
+HTMLPlugin.no_metadata:Ne cherchez pas Ã  extraire des mÃ©tadata des fichiers.
+
+HTMLPlugin.no_strip_metadata_html:Liste de noms de mÃ©ta-donnÃ©es sÃ©parÃ©es par des virgules, ou 'all'. UtilisÃ© avec -description_tags, cela Ã©vite d'Ã©liminer les balises HTML des valeurs pour les mÃ©ta-donnÃ©es spÃ©cifiÃ©es.
+
+HTMLPlugin.nolinks:Ne pas essayer de piÃ©ger les liens (la dÃ©finition de ce drapeau peut amÃ©liorer la vitesse de construction/importation mais tout lien relatif dans le document sera brisÃ©).
+
+HTMLPlugin.no_image_links:Ne pas faire de tentative pour capturer les liens vers les images pour permettre de voir directement les images.  
+
+HTMLPlugin.rename_assoc_files:Renomme les fichiers associÃ©s aux documents (ex. les images). CrÃ©e aussi une structure de rÃ©pertoire beaucoup plus petite (utile pour la crÃ©ation de collections sur cd-rom).
+
+HTMLPlugin.sectionalise_using_h_tags:CrÃ©e automatiquement un document sectionnÃ© en utilisant les tags h1, h2, ...hX.  
+
+HTMLPlugin.title_sub:Expression de substitution pour modifier la chaine enregistrÃ©e comme titre. UtilisÃ© par exemple par PDFPlugin pour supprimer ''Page 1'', etc du texte utilisÃ© comme titre.
+
+HTMLPlugin.tidy_html:Si dÃ©fini, convertit un document HTML en un document XHTML bien formÃ©. Cela permettra Ã  l'utilisateur de visualiser le document en format livre.  
+
+HTMLPlugin.old_style_HDL:Pour marquer si le fichier dans cette collection est dÃ©coupÃ© en sections en utilisant l'ancien style de la section de HDL.  
+
+BaseMediaConverter.enable_cache:Mettre en cache les fichiers produits automatiquement (comme les vignettes ou les images grand format) pour qu'ils ne soient pas gÃ©nÃ©rÃ©s Ã  chaque demande.  
+
+ImageConverter.converttotype:Convertit lâimage pricipale en une format 's'.
+
+ImageConverter.create_screenview:Si cette option est cochÃ©e, crÃ©e une image de la taille de l'Ã©cran, et dÃ©finit les mÃ©tadonnÃ©es Ã©cran, type d'Ã©cran, icÃŽne d'Ã©cran, largeur d'Ã©cran, hauteur d'Ã©cran.  
+
+ImageConverter.create_thumbnail:Si cette option est cochÃ©e, crÃ©e une vignette de chaque image, et dÃ©finit les mÃ©tadonnÃ©es vignette, type de vignette, icÃŽne de vignette, largeur de vignette et hauteur de vignette.  
+ImageConverter.desc:Plugiciel pour des documents constituÃ©s d'une suite d'images, avec la possibilitÃ© de texte OCR pour chaque image. Ce plugiciel traite des fichiers .item qui listent  la sÃ©quence des images et des fichiers texte, et fournit des mÃ©tadonnÃ©es.
+
+ImageConverter.imagemagicknotinstalled:Image Magick n'est pas installÃ©.  
+
+ImageConverter.minimumsize:Ignorer les images de moins de n octets.
+
+ImageConverter.noconversionavailable:La conversion d'image n'est pas disponible.  
+
+ImageConverter.noscaleup:Ne pas rÃ©Ã©chelonner les petites images en crÃ©ant des vignettes.
+
+ImageConverter.screenviewsize:CrÃ©e des images vue-Ã©cran de taille nxn.
+
+ImageConverter.screenviewtype:CrÃ©e des images vue-Ã©cran en format 's'.
+
+ImageConverter.thumbnailsize:CrÃ©e des vignettes de taille nxn.
+
+ImageConverter.thumbnailtype:CrÃ©e des vignettes au format 's'.
+
+ImageConverter.win95notsupported:Image Magick n'est pas supportÃ© sous Win95/98  
+
+ImagePlugin.desc:Ce plugin traite les images, en ajoutant des mÃ©ta-donnÃ©es de base
+
+IndexPlugin.desc:Ce plugin rÃ©cursif traite un fichier index.txt. Le fichier index.txt doit contenir la liste des fichiers Ã  inclure dans la collection, suivie par toute mÃ©ta-donnÃ©e supplÃ©mentaire Ã  associer Ã  chaque fichier\n\nLe fichier index.txt doit Ãªtre formatÃ© comme suit: la premiÃšre ligne peut Ãªtre une clÃ© (commenÃ§ant par key:) pour nommer les champs de mÃ©ta-donnÃ©e (ex. key: Subject Organization Date). Les lignes suivantes contiennent un nom de fichier suivi de la valeur de la mÃ©ta-donnÃ©e (ex 'irma/iwo097e 3.2 unesco 93â va associer les mÃ©ta-donnÃ©es Subject= 3.2, Organization=unesco, et Date=1993 avec le fichier irma/iwo097e si la ligne de clÃ© ci dessus a Ã©tÃ© utilisÃ©e)\n\nNotez que si l'un des champs de mÃ©ta-donnÃ©e utilise le plugin de classification de HiÃ©rarchie, alors sa valeur doit correspondre au premier champ (le descripteur) dans le fichier de classification appropriÃ©.\n\nLes valeurs de mÃ©ta-donnÃ©e peuvent Ãªtre nommÃ©es sÃ©parÃ©ment en utilisant une balise (ex. >Sujet<3.2) et cela va remplacer tout nom qui leur a Ã©tÃ© attribuÃ© par la ligne de clÃ©. S'il n'y a pas de ligne de clÃ©, toute valeur de  mÃ©ta-donnÃ©e sans nom sera nommÃ©e 'Subject'.
+
+ISISPlugin.desc:Ce plugin traite les bases de donnÃ©es CDS/ISIS. Pour chaque base de donnÃ©es CDS/ISIS traitÃ©e, il doit y avoir trois fichiers dans le dossier d'importation de la collection: le Fichier de Base (.mst), le Tableau de DÃ©finition de Champ (.fdt), et le Fichier de RÃ©fÃ©rences croisÃ©es (.xrf).
+
+ISISPlugin.subfield_separator:La chaÃ®ne utilisÃ©e pour sÃ©parer les sous champs dans les enregistrements de bases de donnÃ©es CDS/ISIS.
+
+ISISPlugin.entry_separator:La chaÃ®ne utilisÃ©e pour sÃ©parer les valeurs multiples des champs de mÃ©ta-donnÃ©es individuelles dans les enregistrements de base de donnÃ©es CDS/ISIS.
+
+KeyphraseExtractor.desc:Plugiciel d'extraction pour gÃ©nÃ©rer les phrases clÃ©s Ã  partir du texte. Utilise le systÃšme d'extraction de mots-clÃ©s Kea.  
+
+KeyphraseExtractor.extract_keyphrases:Extraction automatique des phrases clÃ©s avec Kea (par dÃ©faut).
+
+KeyphraseExtractor.extract_keyphrases_kea4:Extrait les phrases clÃ© automatiquement avec Kea 4.0 (configuration par dÃ©faut). Kea 4.0 est une nouvelle version qui a Ã©tÃ© developpÃ©e pour une indexation controllÃ©e de documents dans le domaine de l' agriculture.  
+
+KeyphraseExtractor.extract_keyphrase_options:Options pour l'extraction phrase clÃ© avec Kea. Par exemple: mALIWEB - utilise ALIWEB modÃšle d'extraction; n5 - extraire 5 phrases clÃ©; eGBK - utiliser l'encodage GBK
+
+KeyphraseExtractor.keyphrases:expressions clÃ©s
+
+KeyphraseExtractor.missing_kea:Erreur: Le logiciel Kea n' a pas pu Ãªtre trouvÃ© Ã  %s. TÃ©lÃ©chargez Kea %s de http://nzdl.org/Kea et installez-le dans ce catalogue.  
+
+LaTeXPlugin.desc:Plugin pour documents  LaTeX .
+
+LOMPlugin.desc:Plugiciel pour importer des fichiers LOM (Learning Object Metadata).  
+
+LOMPlugin.root_tag:Le DocType du fichier XML (ou une expression rÃ©guliÃšre qui correspond Ã  l'Ã©lÃ©ment racine).  
+
+LOMPlugin.check_timestamp:VÃ©rifie l'horodatage des fichiers tÃ©lÃ©chargÃ©s prÃ©cÃ©demment, et les tÃ©lÃ©charge seulement si le nouveau fichier source est plus rÃ©cent.  
+
+LOMPlugin.download_srcdocs:TÃ©lÃ©charge le document source si on l'a spÃ©cifiÃ© (avec  general^identifier^entry ou technical^location). Cette option devrait comporter une expression rÃ©guliÃšre correspondant aux  noms de fichiers avant leur tÃ©lÃ©chargement. Remarque: cela ne fonctionne pas pour les documents en dehors d'un pare-feu.  
+
+MARCPlugin.desc:Plugin MARC de base.
+
+MARCPlugin.metadata_mapping:Nom du fichier qui contient les dÃ©tails de correspondance des champs MARC avec les noms des mÃ©tadonnÃ©es Greenstone. Le fichier par dÃ©faut est 'marctodc.txt' qui se trouve dans le rÃ©pertoire etc du site.  
+
+MARCXMLPlugin.desc:Plugiciel MARCXML.  
+
+MARCXMLPlugin.metadata_mapping_file:Nom de fichier qui comprend les dÃ©tails de la correspondance  des valeurs MARC  avec les noms des mÃ©tadonnÃ©es Greenstone. Les valeurs par dÃ©faut sont dans  'marc2dc.txt',  qui se trouve dans le rÃ©pertoire etc du site.  
+
+MediaWikiPlugin.desc:Plugiciel pour importer des pages Web au format MediaWiki  
+
+MediaWikiPlugin.show_toc:Ajoute Ã  la page "A propo"s de la collection la page "Table des matiÃšres" situÃ©e sur la page principale du site de MediaWiki. Il est nÃ©cessaire de spÃ©cifier ci-dessous une expression rÃ©guliÃšre Perl dans toc_exp  pour reconnaÃ®tre la section "table des matiÃšres".  
+
+MediaWikiPlugin.delete_toc:Supprime la section "table des matiÃšres" sur chaque page HTML. Il est nÃ©cessaire de spÃ©cifier ci-dessous  une expression rÃ©guliÃšre Perl dans toc_exp pour correspondre Ã  la "table des matiÃšres".  
+
+MediaWikiPlugin.toc_exp:Une expression rÃ©guliÃšre Perl pour reconnaÃ®tre la "Table des matiÃšres". La valeur par dÃ©faut correspond Ã  des pages Web courantes au format MediaWiki.  
+
+MediaWikiPlugin.delete_nav:Supprime la section de navigation. Il est nÃ©cessaire de spÃ©cifier ci-dessous une expression rÃ©guliÃšre Perl dans nav_div_exp.  
+
+MediaWikiPlugin.nav_div_exp:Une expression rÃ©guliÃšre Perl pour reconnaÃ®tre la section de navigation. La valeur par dÃ©faut correspond Ã  des pages Web courantes au format MediaWiki.  
+
+MediaWikiPlugin.delete_searchbox:Supprime la section "searchbox". Il est nÃ©cessaire de spÃ©cifier ci-dessous une expression rÃ©guliÃšre Perl dans searchbox_div_exp .  
+
+MediaWikiPlugin.searchbox_div_exp:Une expression rÃ©guliÃšre Perl pour reconnaÃ®tre la section "searchbox". La valeur par dÃ©faut correspond Ã  des pages Web courantes au format MediaWiki.  
+
+MediaWikiPlugin.remove_title_suffix_exp:Une expression rÃ©guliÃšre Perl pour dÃ©limiter le titre extrait. Par exemple, \ \ s (. +) limitera le titre au contenu situÃ© avant "-".  
+
+MetadataCSVPlugin.desc:Un plugiciel pour les mÃ©tadonnÃ©es situÃ©es dans des champs sÃ©parÃ©s par des virgules. Le champ Nom de fichier dans le fichier CSV est utilisÃ© pour dÃ©terminer Ã  quel document appartiennent les mÃ©tadonnÃ©es.  
+
+MetadataPass.desc:Classe de base Ã  BasePlugin qui permet l'utilisation des plugins mÃ©ta-donnÃ©e, utilise la passe metadata_read de import.pl
+
+MetadataXMLPlugin.desc:Plugiciel traitant les fichiers metadata.xml  
+
+MetadataEXIFPlugin.desc:Plugiciel qui extrait les mÃ©tadonnÃ©es EXIF des fichiers images, audio et vidÃ©o. Plus prÃ©cisÃ©ment, il est basÃ© sur le module CPAN Perl 'ExifTool'. Celui-ci est compatible avec davantage de formats que son nom ne le laisse croire (par exemple GPS, XMP, FlashPix, ID3, Vorbis). Le plugiciel en bÃ©nÃ©ficie et il a Ã©tÃ© conÃ§u pour travailler avec tous les formats supportÃ©s par ExifTool. Voir la documentation du module ExifTool pour connaÃ®tre la liste des types de fichiers et des schÃ©mas de mÃ©tadonnÃ©es supportÃ©s.  
+
+GreenstoneMETSPlugin.desc:Traiter des documents METS de style Greenstone  
+
+MP3Plugin.desc:Plugin pour le traitement des fichiers MP3.
+
+MP3Plugin.assoc_images:Utilise la recherche d'images Google pour localiser des images qui ont une relation avec les fichiers MP3 en se basant sur les mÃ©tadonnÃ©es ID3 Titre et Artiste.  
+
+MP3Plugin.applet_metadata:UtilisÃ© pour enregistrer [applet] des mÃ©ta-donnÃ©es pour chaque document qui contient le code HTML d'un applet MP3 audio player pour jouer ce fichier.
+
+MP3Plugin.metadata_fields:Liste de champs mÃ©ta-donnÃ©es sÃ©parÃ©s par des virgules pour extraction dans un fichier MP3 (supposÃ© prÃ©sent) . Utiliser \"*\" pour extraire tous les champs.
+
+NulPlugin.desc:Fichier plugin factice (.nul). UtilisÃ© avec les fichiers gÃ©nÃ©rÃ©s lors de l'Ã©clatement des bases de donnÃ©es mÃ©ta-donnÃ©es.
+
+NulPlugin.assoc_field:Nom du champ de mÃ©tadonnÃ©es qui sera dÃ©fini pour chaque fichier nul.  
+NulPlugin.add_metadata_as_text:Ajoute une table de mÃ©tadonnÃ©es en tant que texte du document plutÃŽt que Â«Â Ce document n'a pas de texteÂ Â».  
+
+NulPlugin.remove_namespace_for_text:Supprime l'espace de noms dans les noms de mÃ©tadonnÃ©es dans le texte du document (si add_metadata_as_text est cochÃ©).  
+
+OAIPlugin.desc:Plugiciel de base pour les donnÃ©es Open Archives Initiative (OAI)  
+
+OAIPlugin.document_field:L'Ã©lÃ©ment de mÃ©tadonnÃ©es spÃ©cifiant le nom de fichier des documents auxquels rattacher les mÃ©tadonnÃ©es.  
+
+OAIPlugin.metadata_set:Jeu de mÃ©tadonnÃ©es (prÃ©fixe de l'espace de nom) dans lequel toutes les mÃ©tadonnÃ©es seront importÃ©es.  
+OAIPlugin.metadata_set.auto:Utiliser les prÃ©fixes dÃ©finis dans les enregistrements OAI.  
+OAIPlugin.metadata_set.dc:Utilise le prÃ©fixe Dublin Core (dc). Transformera les Ã©lÃ©ments Dublin Core qualifiÃ©s dans leur forme appropriÃ©e dans Greenstone, par exemple spatial deviendra dc.Coverage^spatial.  
+
+OggVorbisPlugin.add_technical_metadata:Ajouter des mÃ©ta-donnÃ©es techniques (c.a.d. bitrate)
+
+OggVorbisPlugin.desc:Un plugin pour importer des fichiers audio Ogg Vorbis.
+
+OpenDocumentPlugin.desc:Module externe pour les documents au format OASIS OpenDocument (utilisÃ© par OpenOffice 2.0)  
+
+PagedImagePlugin.desc:Plugiciel pour les documents constituÃ©s d'une suite d'images, avec la possibilitÃ© faire une reconnaissance automatique de texte (OCR) pour chaque image. Ce plugiciel traite les fichiers .item qui dressent la liste les images et les fichiers texte, et fournit des mÃ©tadonnÃ©es.  
+
+PagedImagePlugin.documenttype:Met le type de document (utilisÃ© pour le display)
+
+PagedImagePlugin.documenttype.paged:Les documents avec pages numÃ©rotÃ©es ont des flÃšches qui indiquent la prochaine et la derniÃšre page, ainsi qu'une boite permettant d'aller directement la page X
+
+PagedImagePlugin.documenttype.hierarchy:Les documents hiÃ©rarchiques ont une table de contenu.
+
+PagedImagePlugin.headerpage:Ajouter une page d'entÃªte au niveau supÃ©rieur( sans image) Ã  chaque document.
+
+PDFPlugin.allowimagesonly:Autorise les fichiers en format PDF qui n' ont pas de texte extractible. Evite d'avoir Ã  dÃ©finir -set complexe. Uniquement utile avec l'option convert_to html.  
+
+PDFPlugin.complex:CrÃ©e une sortie plus complexe. Avec la dÃ©finition de cette option, la sortie html va beaucoup plus ressembler au fichier PDF original. Pour que cela fonctionne correctement, il faut que Ghostscript soit installÃ© (pour *nix, gs doit Ãªtre dans la dÃ©finition de chemins, pendant que pour windows, vous devez avoir gswin32c.exe sur votre chemin).
+
+PDFPlugin.desc:Plugiciel qui traite  les documents PDF.  
+
+PDFPlugin.nohidden:EmpÃªche pdftohtml de chercher Ã  extraire du texte cachÃ©. Cela n'est utile que si l'option -complex est Ã©galement dÃ©finie.
+
+PDFPlugin.noimages:Ne pas chercher Ã  extraire des images de PDF.
+
+PDFPlugin.use_sections:CreÃ©e une section sÃ©parÃ©e pour chaque page du fichier PDF.
+
+PDFPlugin.zoom:Le facteur avec lequel zoomer PDF pour la sortie (ceci n'est utile que si -comlex est dÃ©fini).
+
+PostScriptPlugin.desc:Ceci est un convertisseur de texte ps \''bon marchÃ©\''. Si vous Ãªtes sÃ©rieux, pensez Ã  utiliser le paquetage PRESCRIT, qui est disponible pour tÃ©lÃ©chargement Ã  http://www.nzdl/software.html
+
+PostScriptPlugin.extract_date:Extrait date de l'en-tÃªte PS.
+
+PostScriptPlugin.extract_pages:Extrait pages de l'en-tÃªte PS.
+
+PostScriptPlugin.extract_title:Extrait titre de l'entÃªte PS.
+
+PowerPointPlugin.desc:Un plugin pour importer des fichiers Microsoft PowerPoint.
+
+PowerPointPlugin.windows_scripting:Utilise la technologie de script de Microsoft Windows (Visual Basic pour Applications) pour que PPT puisse convertir le document vers plusieurs types d' images (p. ex. JPEG, PNG, GIF) au lieu de dÃ©pendre du logiciel open source ppttohtml.  
+
+PrintInfo.bad_general_option:Le plugiciel %s utilise une option incorrecte. VÃ©rifiez votre fichier de configuration collect.cfg.  
+
+PrintInfo.desc:Plugiciel de base qui gÃšre les informations d'impression (en utilisant pluginfo.pl) et en traitant tous les arguments.  
+
+ProCitePlugin.desc:Un plugiciel pour les bases de donnÃ©es ProCite (exportÃ©es)  
+
+ProCitePlugin.entry_separator:La chaÃ®ne de caractÃšre utilisÃ©e pour sÃ©parer les valeurs multiples des champs de mÃ©tadonnÃ©es dans les enregistrements des bases ProCite.  
+
+ReadTextFile.could_not_extract_encoding:ATTENTION: encodage n'a pas pu Ãªtre extrait de %s - utilisation de %s par dÃ©faut
+
+ReadTextFile.could_not_extract_language:ATTENTION: langue n'a pas pu Ãªtre extraite de %s - utilisation de %s par dÃ©faut
+
+ReadTextFile.could_not_open_for_reading:impossible d'ouvrir %s pour lecture
+
+ReadTextFile.default_encoding:Utiliser cet encodage si -input_ encoding est placÃ© Ã  'auto' et l'algorithme de catÃ©gorisation de texte ne rÃ©ussit pas Ã  extraire l'encodage ou lorsqu'il extrait un encodage non supportÃ© par Greenstone. Cette option peut prendre la mÃªme valeur que -input_ encoding.
+
+ReadTextFile.default_language:Si Greenstone ne rÃ©ussit pas Ã  identifier la langue du document, l'Ã©lÃ©ment de mÃ©tadonnÃ©es 'Langue' sera fixÃ© Ã  cette valeur. Le dÃ©faut est 'en' (les symboles de langue ISO 639 sont utilisÃ©s: en= anglais). Notez que si -imput_encoding n'est pas fixÃ© Ã  'auto' et -extract_language n'est pas dÃ©fini, la mÃ©tadonnÃ©e 'Langue' sera fixÃ©e Ã  cette valeur pour tous les documents.  
+
+ReadTextFile.desc:Plugiciel de base pour les fichiers plein texte.  
+
+ReadTextFile.empty_file:le fichier ne contient aucun texte
+
+ReadTextFile.extract_language:Identifier la langue de chaque document et dÃ©finir la mÃ©ta-donnÃ©e 'Langue'. Notez que cela se fera automatiquement si -imput_encoding est Ã  'auto'.
+
+ReadTextFile.file_has_no_text:ERREUR: %s ne contient pas de texte
+
+ReadTextFile.input_encoding:Encodage des documents sources. Les documents vont Ãªtre convertis de ces encodages et stoquÃ©s en interne au format utf8.
+
+ReadTextFile.input_encoding.auto:Utilisez un algorithme de catÃ©gorisation de texte pour identifier automatiquement le codage de chaque document source, cela sera plus lent que l'opÃ©ration consistant Ã  mettre explicitement le codage mais est efficace lorsqu'il y a plusieurs codes dans une mÃªme collection.
+
+ReadTextFile.read_denied:Permission de lecture refusÃ©e pour %s
+
+ReadTextFile.separate_cjk:InsÃ©re des espaces entre les charactÃšres Chinois/Japonais/CorÃ©ens pour faire de chaque caractÃšre un mot. A utiliser si le texte n' est pas segmentÃ©.  
+
+ReadTextFile.unsupported_encoding:ATTENTION: %s semble encodÃ© dans un encodage non supportÃ© (%s) - utilisant %
+
+ReadTextFile.wrong_encoding:ATTENTION: %s a Ã©tÃ© lu en utilisant l'encodage %s mais semble avoir Ã©tÃ© encodÃ© comme %s
+
+ReadXMLFile.desc:Classe de base pour les plugins XML.
+
+ReadXMLFile.xslt:Transforme un document entrant compatible avec le XSLT nommÃ© dans le fichier. Un nom de fichier relatif est dÃ©fini Ã  partir du rÃ©pertoire du fichier de la collection, par exemple etc/mods2dc.xsl.  
+
+RealMediaPlugin.desc:Un plugciel pour le traitement automatique de l'information des fichiers Real Media.  
+
+ReferPlugin.desc:ReferPlugin lit les fichiers de bibliographie au format Refer.
+
+RogPlugin.desc:CrÃ©e des documents Ã  un seul niveau Ã  partir de fichiers .rog ou .mdb.
+
+RTFPlugin.desc:Plugin pour l'importation de fichiers Rich Text Format.
+
+SourceCodePlugin.desc:Le nom du fichier est prÃ©sentement utilisÃ© pour Titre (optionnellement moins un certain prÃ©fixe). Languages actuels:\ntext:READMEs/Makefiles\nC/C++ (extrait actuellement les dÃ©clarations #include et les dÃ©clarations de classe C++)\n Perl (pour le moment, effectuÃ© uniquement comme texte)\nShell (pour le moment, effectuÃ© uniquement comme texte)
+
+SourceCodePlugin.remove_prefix:Enlever cette chaine de dÃ©but du nom de fichier (ex.: -remove_prefix /tmp/XX/src). Par dÃ©faut, le chemin complet est supprimÃ© du nom de fichier.
+
+SplitTextFile.desc:SplitTextFile est un plugin pour Ã©clater des fichiers d'entrÃ© en en segments qui vont Ãªtre traitÃ©s individuellement. Ce plugin ne doit pas Ãªtre invoquÃ© directement. Si vous voulez traiter des fichiers d'entrÃ©e qui contiennent plusieurs documents, vous devez plutÃŽt Ã©crire un plugin avec une fonction de traitement qui va traiter un de ces documents et hÃ©riter de SplitTextFile. Voir ReferPlugin en guise d'exemple.
+
+SplitTextFile.split_exp:Une expression ordinaire Perl pour Ã©clater les fichiers d'entrÃ©e en segments.
+
+StructuredHTMLPlugin.desc:Un plugiciel pour traiter les documents HTML structurÃ©s, en les scindant en sections basÃ©es sur les informations de style.  
+
+StructuredHTMLPlugin.delete_toc:Retire toute table des matiÃšres, liste des figures, etc du fichier HTML converti. Des styles  sont dÃ©finis pour cela par l'option toc_header.  
+
+StructuredHTMLPlugin.title_header:Styles possibles dÃ©finis par l'utilisateur pour l'en-tÃªte du titre  
+
+StructuredHTMLPlugin.level1_header:Styles possibles dÃ©finis par l'utilisateur pour l' entÃªte de niveau 1 dans le document au format HTML (Ã©quivalent Ã  <h1>).  
+
+StructuredHTMLPlugin.level2_header:Styles possibles dÃ©finis par l'utilisateur pour l' entÃªte de niveau 2 dans le document au format HTML (Ã©quivalent Ã  <h2>).  
+
+StructuredHTMLPlugin.level3_header:Styles possibles dÃ©finis par l'utilisateur pour l' entÃªte de niveau 3 dans le document HTML (Ã©quivalent Ã  <h3>).  
+
+StructuredHTMLPlugin.toc_header:Les styles possibles d'en-tÃªte dÃ©finis par l'utilisateur pour la table des matiÃšres, le tableau de figures, etc, devront Ãªtre Ã©liminÃ©s si delete_toc est cochÃ©.  
+
+TextPlugin.desc:CrÃ©e un document Ã  niveau unique. Ajoute une mÃ©ta-donnÃ©e de Titre de premiÃšre ligne de texte (jusqu'Ã  100 caractÃšres).
+
+TextPlugin.title_sub:Expression de substitution pour modifier la chaine stockÃ©e comme Titre. UtilisÃ©e par exemple par PostScriptPlugin pour supprimer ''Page 1'' etc du texte utilisÃ© comme titre.  
+
+UnknownPlugin.assoc_field:Nom du champ de mÃ©ta-donnÃ©e qui va contenir le nom de fichier associÃ©.
+
+UnknownPlugin.desc:Ceci est un plugin simple d'importation de fichiers aux formats inconnus de Greenstone. Un document fictif va Ãªtre crÃ©Ã© pour chacun de ses fichiers et le fichier lui mÃªme va Ãªtre passÃ© Ã  Greenstone comme \"fichier associÃ©\" du document.
+
+UnknownPlugin.file_format:Type Mime du fichier (ex. image/gif).
+
+UnknownPlugin.mime_type:Type Mime du fichier (c.a.d. image/gif).
+
+UnknownPlugin.process_extension:Traiter les fichiers avec cette extension. Cette option est une alternative Ã  process_exp qui est plus simple Ã  utiliser mais moins flexible.
+
+UnknownPlugin.srcicon:SpÃ©cifie un nom de macro (sans tiret bas) Ã  utiliser comme mÃ©tadonnÃ©e srcicon.  
+
+WordPlugin.desc:Un plugin pour des documents Microsoft Word.
+
+WordPlugin.windows_scripting:Utilise la technologie de scripts de Microsoft Windows (Applications pour Visual Basic) pour que Word transforme le document au format HTML au lieu d'utiliser le logiciel open source WvWare. Cela provoque le dÃ©marrage de l'application Word si celle-ci n'est pas dÃ©jÃ  ouverte.
+
+WordPlugin.metadata_fields:Ceci sert Ã  rÃ©cupÃ©rer les mÃ©tadonnÃ©es du document au format HTML converties par un script VB. Cela permet de dÃ©finir des listes de champs sÃ©parÃ©s par une virgule pour tenter d'en extraire les mÃ©tadonnÃ©es. Utilisez 'tag<tagname>' pour extraire les contenus de la premiÃšre paire <tagname> et les classer dans un Ã©lÃ©ment de mÃ©tadonnÃ©es appelÃ© 'tagname'. Vous pouvez Ã©crire comme vous voulez le nom de la mÃ©tadonnÃ©e dans Greenstone car l'extraction des attributs est insensible Ã  la casse.  
+
+ZIPPlugin.desc:Plugin qui traite les formats d'entrÃ©e compressÃ©s et/ou les formats d'entrÃ©e archivÃ©s actuellement traitÃ©s et les extensions de fichiers sont:\ngzip (.gz, .z, .tgz, .taz)\nbzip (.bz)\nbzip2 (.bz2)\nzip (.zip .jar)\ntar (.tar)\n\n. Ce plugin dÃ©pend de la prÃ©sence des utilaires suivants (lorsqu'il essaie de traiter les formats correspondants):\ngunzip (pour gzip)\nbunzip (pour bzip)\nbunzip2 \nunzip (pour zip)\ntar (pour tar)
+
+#
+# Download module option descriptions
+#
+
+BaseDownload.desc:Classe de base pour les modules de tÃ©lÃ©chargement  
+BaseDownload.bad_general_option:Le module de tÃ©lÃ©chargement %s utilise un paramÃštre incorrect.  
+MediaWikiDownload.desc:Un module de tÃ©lÃ©chargement Ã  partir de sites Internet MediaWiki  
+MediaWikiDownload.reject_filetype:La liste URL Ã  ignorer, sÃ©parÃ©s par une virgule, par exemple cgi-bin * *, *. ppt ignore les hyperliens qui contiennent soit "cgi-bin" ou ". ppt '  
+MediaWikiDownload.reject_filetype_disp:La liste des URL Ã  ignorer, sÃ©parÃ©s par une virgule  
+MediaWikiDownload.exclude_directories:Liste des rÃ©pertoires exclus (doit Ãªtre le chemin absolu vers le rÃ©pertoire), par exemple : /personnes, /documentation excluront les sous-rÃ©pertoires "peuple" et "documentation"  dans l'exploration du site actuel en exploration.  
+MediaWikiDownload.exclude_directories_disp:La liste des rÃ©pertoires Ã  exclure, sÃ©parÃ©s par une virgule  
+
+OAIDownload.desc:Un module de tÃ©lÃ©chargement Ã  partir des dÃ©pÃŽts OAI  
+OAIDownload.url_disp:URL de la source  
+OAIDownload.url:URL de l'entrepÃŽt OAI  
+OAIDownload.set_disp:Restreint au jeu  
+OAIDownload.set:Restreindre le tÃ©lÃ©chargement vers des installations spÃ©cifiÃ©es dans le dÃ©pÃŽt  
+OAIDownload.metadata_prefix_disp:PrÃ©fixe des mÃ©tadonnÃ©es.  
+OAIDownload.metadata_prefix:Le format de mÃ©tadonnÃ©es utilisÃ© pour les exports, par exemple oai_dc, gdc, etc. Cliquer sur le bouton <Server information> pour connaÃ®tre les formats supportÃ©s.  
+OAIDownload.get_doc_disp:Obtenir le document  
+OAIDownload.get_doc:TÃ©lÃ©charger le document source si il'est spÃ©cifiÃ© dans l'enregistrement  
+OAIDownload.get_doc_exts_disp:Inclut seulement les types de fichiers.  
+OAIDownload.get_doc_exts:TÃ©lÃ©charger le document source si il'est spÃ©cifiÃ© dans l'enregistrement
+OAIDownload.max_records_disp:Maximum d'enregistrements  
+OAIDownload.max_records:Nombre maximum d'enregistrements Ã  tÃ©lÃ©charger  
+
+SRWDownload.desc:Un module de tÃ©lÃ©chargement Ã  partir de dÃ©pÃŽts SRW (Search/Retrieve Web Service)  
+
+WebDownload.desc:Un module de tÃ©lÃ©chargement Ã  partir d'Internet via HTTP ou FTP  
+WebDownload.url:URL Source. En cas de redirection http, cette valeur peut changer  
+WebDownload.url_disp:URL Source  
+WebDownload.depth:Jusqu'Ã  quelle profondeur d'hyperliens aller lors du tÃ©lÃ©chargement  
+WebDownload.depth_disp:Profondeur de tÃ©lÃ©chargement  
+WebDownload.below:Mettre en miroir seulement les fichiers ci-dessous cette URL  
+WebDownload.below_disp:Mettre en miroir seulement les fichiers dont l'adresse commence par cet URL.  
+WebDownload.within:Mettre en mirroir seuls les fichiers dans le mÃªme site  
+WebDownload.within_disp:Mettre en mirroir seulement les fichiers situÃ©s dans le mÃªme site  
+WebDownload.html_only:TÃ©lÃ©chagez uniquement des fichiers HTML, et ignorez les fichiers associÃ©s, par exemple des images et des feuilles de style  
+WebDownload.html_only_disp:Ne tÃ©lÃ©charger que des fichiers HTML  
+
+WgetDownload.desc:Classe de base qui gÃšre les appels Ã  wget  
+WgetDownload.proxy_on:Proxy en marche  
+WgetDownload.proxy_host:HÃŽte mandataire  
+WgetDownload.proxy_port:Port du Proxy  
+WgetDownload.user_name:Nom d'utilisateur  
+WgetDownload.user_password:Password d'utilisateur  
+
+Z3950Download.desc:Un module de tÃ©lÃ©chargement Ã  partir d'un dÃ©pÃŽt Z3950  
+Z3950Download.host:URL de l'hÃŽte  
+Z3950Download.host_disp:HÃŽte mandataire  
+Z3950Download.port:NumÃ©ro de port du dÃ©pÃŽt  
+Z3950Download.port_disp:Port  
+Z3950Download.database:Base de donnÃ©es pour y rechercher des documents  
+Z3950Download.database_disp:Base de donnÃ©es  
+Z3950Download.find:RÃ©cupÃ©rez les enregistrements contenant le terme de recherche spÃ©cifiÃ©  
+Z3950Download.find_disp:Trouvez  
+Z3950Download.max_records:Nombre maximum d'enregistrements Ã  tÃ©lÃ©charger  
+Z3950Download.max_records_disp:Maximum d'enregistrements  
+
+
+#
+#Plugout option descriptions
+#
+
+BasPlugout.bad_general_option:Le % s plugout utilise un paramÃštre incorrect.  
+BasPlugout.debug:mettre le mode de dÃ©bogage.  
+BasPlugout.desc:Classe de base pour tous les plugiciels d'export.  
+BasPlugout.group_size:Nombre de documents Ã  regrouper dans un seul fichier XML.  
+BasPlugout.gzip_output:Utiliser gzip pour compresser les documents xml rÃ©sultants (ne pas oublier d'inclure ZIPPlugin dans votre liste de plugiciels lors d'une construction Ã  partir de documents compressÃ©s)  
+BasPlugout.output_handle:le descripteur de fichier utilisÃ© pour recevoir les donnÃ©es de sortie  
+BasPlugout.output_info:la rÃ©fÃ©rence Ã  un objet arcinfo utilisÃ©e pour stocker des informations au sujet des archives.  
+BasPlugout.verbosity:ContrÃŽle le volume des sorties de donnÃ©es. 0=aucun, 3=beaucoup.  
+BasPlugout.xslt_file:Transformer un document avec le XSLT dans le fichier nommÃ©.  
+
+DSpacePlugout.desc:Format Archive Dspace.  
+
+FedoraMETSPlugout.desc:Format METS utilisant le profil Fedora.  
+FedoraMETSPlugout.fedora_namespace:PrÃ©fixe utilisÃ© dans Fedora pour traiter les identifiants (PIDS), par exemple greenstone:HASH0122efe4a2c58d0  
+
+GreenstoneXMLPlugout.desc:Format d'archivage XML Greenstone.  
+
+GreenstoneMETSPlugout.desc:Format METS utilisant le profil Greenstone.  
+
+MARCXMLPlugout.desc:Format MARC xml  
+MARCXMLPlugout.group:Extrait les enregistrement Marc XML dans un seul fichier.  
+MARCXMLPlugout.mapping_file:Pour la transformation, utilisez le fichier de correpondances nommÃ©.  
+
+METSPlugout.desc:Plugicel superclass pour le format METS. Il fournit une fonctionnalitÃ© commune pour des profils tels que GreenstoneMETS, FedoraMETS et les mÃ©thodes "key abstract".
+METSPlugout.xslt_txt:Transforme un fichier METS docmets.txtl avec le fichier XSLT nommÃ© dans le fichier .  
+METSPlugout.xslt_mets:Transforme un fichier METS docmets.xml avec le fichier XSLT nommÃ© dans le fichier .  
+
+#
+# Perl module strings
+#
+
+classify.could_not_find_classifier:ERREUR: Classificateur \''%s\'' introuvable
+
+download.could_not_find_download:ERREUR: Impossible de trouver le module tÃ©lÃ©charger \"%s\"  
+
+plugin.could_not_find_plugin:ERREUR: impossible de trouver le plugin /''%s''
+
+plugin.including_archive:intÃ©gration des contenus d'une archive ZIP/TAR
+
+plugin.including_archives:intÃ©gration des contenus de %d archives ZIP/TAR
+
+plugin.kill_file:Processus tuÃ© par le fichier .kill
+
+plugin.n_considered:%d documents ont Ã©tÃ© pris en compte pour traitement
+
+plugin.n_included:%d ont Ã©tÃ© traitÃ©s et intÃ©grÃ©s dans la collection
+
+plugin.n_rejected:%d ont Ã©tÃ© rejetÃ©s
+
+plugin.n_unrecognised:%d n'ont pas Ã©tÃ© reconnus
+
+plugin.no_plugin_could_process:ATTENTION: Aucun plugin n'a pu traiter %s
+
+plugin.no_plugin_could_recognise:ATTENTION: Aucun plugin n'a pu reconnaÃ®tre %s
+
+plugin.no_plugin_could_process_this_file:aucun plugin n'a pu traiter ce fichier
+
+plugin.no_plugin_could_recognise_this_file:Aucun plugin n'a pu reconnaÃ®tre ce fichier
+
+plugin.one_considered:1 document a Ã©tÃ© pris en compte pour traitement
+
+plugin.one_included:1 a Ã©tÃ© traitÃ© et intÃ©grÃ© dans la collection
+
+plugin.one_rejected:1 a Ã©tÃ© rejetÃ©
+
+plugin.one_unrecognised:1 n'a pas Ã©tÃ© reconnu
+
+plugin.see_faillog:Voir %s pour une liste des documents rejetÃ©s ou non-identifiÃ©s  
+
+PrintUsage.default:DÃ©faut
+
+PrintUsage.required:REQUIS
+
+plugout.could_not_find_plugout:ERREUR: Impossible de trouver le "plugout" \"%s"  
Index: /gsdl/stable/perllib/strings_mr.properties
===================================================================
--- /gsdl/stable/perllib/strings_mr.properties	(revision 20131)
+++ /gsdl/stable/perllib/strings_mr.properties	(revision 20131)
@@ -0,0 +1,1326 @@
+#
+# Resource bundle description
+#
+
+Language.code:mr
+Language.name:Marathi
+
+OutputEncoding.unix:utf-8
+OutputEncoding.windows:utf-8  
+
+
+#
+# Common output messages and strings
+#
+
+
+
+
+
+common.cannot_open:ERROR: Can't open %s  
+
+
+
+
+
+
+
+common.cannot_read_file:à€à¥à€à€ à€«à€Ÿà€à€² à€µà€Ÿà€à€€à€Ÿ à€¯à¥à€€ à€šà€Ÿà€¹à¥.  
+
+
+
+
+
+common.options:à€à€ªà¥à€¶à€š  
+
+
+
+
+
+common.usage:à€¯à¥à€à¥à€ž  
+
+
+
+common.invalid_options:Invalid arguments: %s  
+
+
+
+
+
+
+#
+# Script option descriptions and output messages
+#
+
+scripts.language:Language to display option descriptions in (eg. 'en_US' specifies American English). Requires translations of the option descriptions to exist in the perllib/strings_language-code.rb file.  
+
+scripts.xml:Produces the information in an XML form, without 'pretty' comments but with much more detail.  
+
+scripts.listall:à€®à€Ÿà€¹à€¿à€€à¥ à€
+à€žà€²à¥à€²à¥ à€žà€°à¥à€µ à€à€¯à€à€®à€à¥ à€¯à€Ÿà€Šà¥ à€à€°à€Ÿ  
+
+scripts.describeall:à€®à€Ÿà€¹à¥à€€à¥ à€
+à€žà€£à€Ÿà€°à¥à€¯à€Ÿ à€à€à€à€Ÿà€à€à¥ à€à€ªà¥à€¶à€š à€Šà€Ÿà€à€µà€Ÿ  
+
+scripts.both_old_options:WARNING: -removeold was specified with -keepold or -incremental, defaulting to -removeold. Current contents of %s directory will be deleted.  
+
+scripts.no_old_options:WARNING: None of -removeold, -keepold or -incremental were specified, defaulting to -removeold. Current contents of %s directory will be deleted.  
+
+
+
+# -- buildcol.pl --
+
+
+
+
+
+buildcol.cachedir:à€šà€¿à€°à¥à€Šà¥à€¶à€¿à€à€Ÿ à€€à€¯à€Ÿà€° à€¹à¥à€£à¥à€¯à€Ÿà€ªà¥à€°à¥à€µà¥ à€€à€Ÿà€€à¥à€ªà¥à€°à€€à€Ÿ à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€¹à¥à€€ à€à€¹à¥.  
+
+buildcol.cannot_open_cfg_file:à€žà¥à€à€šà€Ÿà€ à€
+à€Šà¥à€¯à€¯à€Ÿà€µà€€ à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€à¥à€šà¥à€«à€¿à€ à€«à€Ÿà€à€² à€à€à€¡à€€ à€šà€Ÿà€¹à¥à€€à€ %s  
+
+
+
+
+
+buildcol.create_images:Attempt to create default images for new collection. This relies on the Gimp being installed along with relevant perl modules to allow scripting from perl.  
+
+buildcol.debug:Print output to STDOUT.  
+
+
+
+buildcol.faillog:Fail log filename. This log receives the filenames of any files which fail to be processed.  
+
+
+
+buildcol.index:à€šà€¿à€°à¥à€Šà¥à€¶ à€€à€¯à€Ÿà€° à€¹à¥à€€ à€à€¹à¥ (à€à¥à€šà¥à€«à€¿à€à€° à€«à€Ÿà€à€² à€€à€¯à€Ÿà€° à€¹à¥à€€ à€à€¹à¥ )  
+
+
+
+buildcol.keepold:à€€à€¯à€Ÿà€° à€¹à¥à€€ à€
+à€žà€²à¥à€²à¥à€¯à€Ÿ à€žà€§à¥à€¯à€Ÿà€à¥à€¯à€Ÿ à€šà€¿à€°à¥à€Šà€¶à¥à€à€Ÿ à€
+à€šà¥à€à¥à€°à€® à€¬à€Šà€²à€Ÿà€° à€šà€Ÿà€¹à¥
+
+
+
+
+buildcol.mode.all:à€žà€°à¥à€µ à€à€°à€Ÿ.  
+
+buildcol.mode.compress_text:Just compress the text.  
+buildcol.mode.infodb:à€®à¥à€à¥à€¡à¥à€à€Ÿà€à€Ÿ à€¡à¥à€à€Ÿà€¬à€Ÿà€ž à€€à€¯à€Ÿà€° à€à€°à€Ÿ.  
+
+
+
+
+
+
+
+buildcol.no_text:Don't store compressed text. This option is useful for minimizing the size of the built indexes if you intend always to display the original documents at run time (i.e. you won't be able to retrieve the compressed text version).  
+
+
+
+buildcol.sections_index_document_metadata.always:Add all specified document level metadata even if section level metadata of that name exists.  
+buildcol.sections_index_document_metadata.unless_section_metadata_exists:Only add document level metadata if no section level metadata of that name exists.  
+
+buildcol.out:Filename or handle to print output status to.  
+
+buildcol.params:(à€à€ªà¥à€¶à€š) à€žà€à€à¥à€°à€¹ - à€šà€Ÿà€µ  
+
+buildcol.remove_empty_classifications:à€°à€¿à€à€Ÿà€®à¥ à€à¥à€²à€Ÿà€žà€¿à€«à€Ÿà€¯à€° à€à€£à€¿ à€à¥à€²à€Ÿà€žà€¿à€«à€¿à€à¥à€¶à€š à€šà¥à€¡ à€²à€ªà€µà€Ÿ ( à€¯à€Ÿ à€®à€§à¥à€¯à¥ à€à€Ÿà€¹à¥à€¹à¥ à€ªà¥à€°à€²à¥à€ à€šà€Ÿà€¹à¥à€€).  
+
+
+
+buildcol.unlinked_col_images:à€à€¿à€€à¥à€° à€žà€à€à¥à€°à€¹à€Ÿà€à¥ à€²à€¿à€à€ à€à¥à€¡à€²à¥ à€à¥à€²à¥ à€šà€Ÿà€¹à¥  
+
+
+
+
+
+
+
+
+# -- classinfo.pl --
+
+
+
+
+
+classinfo.general_options:General options are inherited from parent classes of the classifier.  
+
+
+
+
+
+
+
+
+
+
+
+
+
+# -- downloadfrom.pl --
+downloadfrom.cache_dir:The location of the cache directory  
+
+
+
+
+
+
+
+downloadfrom.incorrect_mode:à€¡à€Ÿà€à€šà€²à¥à€¡ à€®à¥à€¡ à€
+à€¯à¥à€à¥à€¯.  
+
+
+
+# -- downloadinfo.pl --
+
+downloadinfo.desc:à€¡à€Ÿà€à€šà€²à¥à€¡ à€à¥à€²à¥à€²à¥ à€®à€Ÿà€¹à€¿à€€à¥à€à¥ à€ªà¥à€°à€€  
+downloadinfo.collection:Giving a collection name will make downloadinfo.pl look in collect/collection-name/perllib/downloaders first. If the module is not found there it will look in the general perllib/downloaders directory.  
+
+
+
+
+
+# -- explode_metadata_database.pl --
+
+
+
+ 
+explode.document_field:The metadata element specifying the file name of documents to obtain and include in the collection.  
+
+
+
+
+
+explode.encoding:à€¡à¥à€à€Ÿà€¬à¥à€ž à€«à€Ÿà€à€² à€µà€Ÿà€à€€ à€
+à€žà€€à€Ÿà€šà€Ÿ à€à€šà€à¥à€¡à¥à€à€à€à€Ÿ à€µà€Ÿà€ªà€° à€à€°à€Ÿ.  
+
+explode.plugin:Plugin to use for exploding  
+
+
+
+
+# -- replace_srcdoc_with_html.pl --
+
+
+
+
+# -- exportcol.pl --
+
+exportcol.out:Filename or handle to print output status to.  
+
+
+
+
+
+exportcol.coll_not_found:Ignoring invalid collection %s: collection not found at %s.  
+
+exportcol.fail:exportcol.pl failed:  
+
+exportcol.couldnt_create_dir:à€šà€¿à€°à¥à€Šà¥à€¶à€¿à€à€Ÿ à€€à€¯à€Ÿà€° à€à€°à€€à€Ÿ à€¯à¥à€£à€Ÿà€° à€šà€Ÿà€¹à¥ %s.  
+
+
+
+
+
+exportcol.export_coll_not_installed:The Export to CD-ROM functionality has not been installed.  
+
+# -- import.pl --
+
+import.archivedir:Where the converted material ends up.  
+
+import.manifest:An XML file that details what files are to be imported. Used instead of recursively descending the import folder, typically for incremental building.  
+
+
+
+
+
+
+
+import.collectdir:"à€žà€à€à¥à€°à€¹" à€šà€¿à€°à¥à€Šà¥à€¶à€š à€®à€Ÿà€°à¥à€  
+
+
+
+
+
+import.desc:PERL script used to import files into a GA format ready for building.  
+
+
+
+import.groupsize:à€à€à€Ÿ à€à€à¥à€žà€à€®à€à€² à€«à€Ÿà€à€² à€®à€§à¥à€¯à¥ à€à€®à¥à€ªà¥à€°à¥à€ à€à¥à€²à¥à€²à¥ à€ªà¥à€°à€²à¥à€  
+
+import.gzip:Use gzip to compress resulting xml documents (don't forget to include ZIPPlug in your plugin list when building from compressed documents).  
+
+
+
+
+
+
+
+
+
+import.no_import_dir:à€à¥à€à€ à€à€à€®à¥à€ªà¥à€°à¥à€ à€à¥à€²à¥à€²à¥ à€šà€¿à€°à¥à€Šà¥à€¶à€¿à€à€Ÿ à€®à€¿à€³à€€ à€šà€Ÿà€¹à¥.  
+
+
+
+import.OIDtype:à€ªà¥à€°à€€à¥à€¯à¥à€ à€ªà¥à€°à€²à¥à€à€Ÿà€žà€Ÿà€ à¥ à€
+à€Šà¥à€µà€¿à€€à¥à€¯ à€à¥à€¡ à€€à€¯à€Ÿà€° à€à€°à€£à¥à€¯à€Ÿà€à¥ à€ªà€§à¥à€Šà€€.  
+
+
+
+
+
+
+import.OIDtype.dirname:à€ªà¥
+à€°à¥à€à€ à€¡à€¿à€°à¥à€à¥à€à€°à¥à€à¥à€¯à€Ÿ à€šà€Ÿà€µà€Ÿà€à€Ÿ à€à€ªà€¯à¥à€ à€à€°à€Ÿ (preceded by 'J').à€ªà¥à€°à€€à¥à€¯à¥à€ à€¡à€¿à€°à¥à€à¥à€à€°à¥ à€®à€§à¥à€¯à¥ à€à€à€ à€ªà¥à€°à€²à¥à€ à€
+à€žà€Ÿà€µà€Ÿ, à€à€£à€¿ à€¡à€¿à€°à¥à€à¥à€à€°à¥ à€šà€Ÿà€µ à€¹à¥ à€
+à€Šà¥à€µà€¿à€€à¥à€¯ à€
+à€žà€Ÿà€µà¥.E.g. import/b13as/h15ef/page.html will get an identifier of Jh15ef.  
+
+
+
+
+
+import.out:Filename or handle to print output status to.
+
+import.params:[options] collection-name  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+import.stats_backup:Will print stats to STDERR instead.  
+
+import.verbosity:Controls the quantity of output. 0=none, 3=lots.  
+
+# -- schedule.pl --
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# -- export.pl --
+
+export.exportdir:Where the export material ends up.  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+export.keepold:Will not destroy the current contents of the export directory.  
+
+export.maxdocs:à€à€Ÿà€žà¥à€€à¥à€€ à€à€Ÿà€žà¥à€€ à€ªà¥à€°à€²à¥à€ à€ªà€Ÿà€ à€µà€¿à€²à¥.
+
+
+
+
+
+export.saveas.DSpace:à€¡à€¿à€žà¥à€ªà¥à€ž à€Šà€«à¥à€€à€°à€à€Ÿà€šà¥à€¯à€Ÿà€à¥ à€°à¥à€ªà€°à¥à€·à€Ÿ  
+
+
+
+
+
+
+
+
+export.out:Filename or handle to print output status to.  
+
+export.params:(à€à€ªà¥à€¶à€š) à€žà€à€à¥à€°à€¹- à€šà€Ÿà€µ à¥§, à€žà€à€à¥à€°à€¹- à€šà€Ÿà€µ à¥š...  
+
+
+
+export.removing_export:à€ªà€Ÿà€ à€µà€¿à€€ à€
+à€žà€²à¥à€²à¥à€¯à€Ÿ à€šà€¿à€°à¥à€Šà¥à€¶à€¿à€à¥à€€à¥à€² à€à€à€ à€à€Ÿà€¢à¥à€š à€à€Ÿà€à€Ÿ..........  
+
+
+
+export.statsfile:Filename or handle to print export statistics to.  
+
+
+
+
+
+
+
+# -- mkcol.pl --
+
+mkcol.about:The about text for the collection.  
+
+
+
+
+
+
+
+mkcol.cannot_find_modelcol:ERROR: Cannot find the model collection %s  
+
+
+
+
+
+
+
+
+
+mkcol.creator_undefined:à€à¥à€à€ à€žà€à€à¥à€°à€¹à€ à€šà€¿à€¶à¥à€à€¿à€€ à€à¥à€²à¥à€²à€Ÿ à€šà€Ÿà€¹à¥.This variable is needed to recognise duplicate collection names.  
+
+
+
+mkcol.doing_replacements:doing replacements for %s  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+mkcol.public:If this collection has anonymous access.  
+
+
+
+
+
+
+
+mkcol.success:%s à€šà€µà€¿à€š à€žà€à€à¥à€°à€¹ à€€à€¯à€Ÿà€° à€à€Ÿà€²à€Ÿ  
+
+
+
+
+mkcol.win31compat.true:à€šà€¿à€°à¥à€Šà¥à€¶à€¿à€à¥à€à¥ à€šà€Ÿà€µ à¥® à€à€¿à€à€µà€Ÿ à€€à¥à€¯à€Ÿà€ªà¥à€à¥à€·à€Ÿ à€à€®à¥ à€
+à€à¥à€·à€°à€Ÿà€à€à¥ à€
+à€žà€Ÿà€µà¥.  
+
+
+# -- pluginfo.pl --
+
+
+
+
+
+
+
+
+
+pluginfo.no_plugin_name:à€à¥à€à€ à€€à¥à€®à¥à€¹à¥ à€ªà¥à€²à€à€à€šà€à¥ à€šà€Ÿà€µ à€Šà¥à€£à¥ à€à€µà€¶à¥à€¯à€ à€à€¹à¥.  
+
+pluginfo.option_types:à€ªà¥à€²à€à€à€š à€®à€§à¥à€¯à¥ à€Šà¥à€š à€ªà¥à€°à€à€Ÿà€°à€à¥ à€à€ªà¥à€¶à€š à€à¥à€ à€¶à€à€€à¥.  
+
+
+
+
+
+pluginfo.specific_options:Specific options are defined within the plugin itself, and are available only to this particular plugin.  
+
+
+# -- plugoutinfo.pl --
+
+
+
+plugoutinfo.desc:à€ªà¥à€²à€à€à€à€ à€µà€¿à€·à€¯à¥ à€®à€Ÿà€¹à€¿à€€à¥ à€²à€¿à€¹à€Ÿ.  
+
+plugoutinfo.general_options:General options are inherited from parent classes of the plugout.  
+
+
+
+plugoutinfo.no_plugout_name:à€à¥à€à€ à€€à¥à€®à¥à€¹à¥ à€ªà¥à€²à€à€à€à€à€à¥ à€šà€Ÿà€µ à€Šà¥à€£à¥ à€à€µà€¶à¥à€¯à€ à€à€¹à¥.  
+
+plugoutinfo.option_types:à€ªà¥à€²à€à€à€à€à€žà¥ à€Šà¥à€š à€à€ªà¥à€¶à€š à€à¥à€ à€¶à€à€€à€Ÿà€€.  
+
+plugoutinfo.params:[options] plugout-name  
+
+
+
+
+
+
+
+#
+# Classifier option descriptions
+#
+
+AllList.desc:à€žà€°à¥à€µ à€ªà¥à€°à€²à¥à€à€Ÿà€à€à¥ à€à€à€ à€¯à€Ÿà€Šà¥ à€à€°à€Ÿ.  
+
+AZCompactList.allvalues:à€®à¥à€à€Ÿà€¡à¥à€à€Ÿ à€µà¥à€¹à€Œà¥
+à€²à¥à€¯à¥ à€µà€Ÿà€ªà€°à€Ÿ.  
+
+AZCompactList.desc:Classifier plugin for sorting alphabetically (on a-zA-Z0-9). Produces a horizontal A-Z list, then a vertical list containing documents, or bookshelves for documents with common metadata.  
+
+AZCompactList.doclevel:à€ªà¥à€°à€²à¥à€ à€ªà¥à€°à€à¥à€°à€¿à€¯à¥à€à€Ÿ à€žà¥à€€à€°.  
+
+
+
+
+
+
+
+AZCompactList.maxcompact:à€ªà¥à€°à€€à¥à€¯à¥à€ à€ªà€Ÿà€šà€Ÿà€µà€° à€à€Ÿà€žà¥à€€à¥à€€ à€à€Ÿà€žà¥à€€ à€ªà¥à€°à€²à¥à€ à€Šà€¿à€žà€€à¥à€².  
+
+AZCompactList.metadata:A single Metadata field, or a comma separated list of Metadata fields, used for classification. If a list is specified, the first metadata type that has values will be used. May be used in conjunction with the -firstvalueonly and -allvalues flags, to select only the first value, or all metadata values from the list.  
+
+AZCompactList.mincompact:à€ªà¥à€°à€€à¥à€¯à¥à€ à€ªà€Ÿà€šà€Ÿà€µà€° à€à€®à¥à€€ à€à€®à¥ à€ªà¥à€°à€²à¥à€ à€Šà€Ÿà€à€µà€Ÿ.  
+
+AZCompactList.mingroup:The smallest value that will cause a group in the hierarchy to form.  
+
+
+
+AZCompactList.recopt:Used in nested metadata such as -metadata Year/Organisation.  
+AZCompactList.sort:à€²à€¿à€« à€šà¥à€¡à€šà¥ à€®à¥à€à€Ÿà€¡à¥à€à€Ÿà€à¥ à€µà€¿à€­à€Ÿà€ à€à¥à€²à¥ à€à€¹à¥à€€.
+
+
+
+
+
+AZList.metadata:à€à¥à€²à€Ÿà€žà€¿à€«à€¿à€à¥à€¶à€šà€žà€Ÿà€ à¥ à€µà€Ÿà€ªà€°à€€ à€
+à€žà€²à¥à€²à€Ÿ à¥§ à€®à¥à€à€Ÿà€¡à¥à€à€Ÿ à€«à€¿à€²à¥à€¡, à€®à¥à€à€¡à¥à€à€Ÿà€à¥ à€¯à€Ÿà€Šà¥ à€žà¥à€µà€²à¥à€ªà€µà€¿à€°à€Ÿà€®à€šà¥ à€µà€¿à€­à€Ÿà€à€€à€Ÿ à€¯à¥à€€à¥.
+
+
+
+
+
+
+
+BasClas.buttonname:The label for the classifier screen and button in navigation bar. The default is the metadata element specified with -metadata.  
+
+BasClas.desc:Base class for all the classifiers.  
+
+
+
+
+
+
+
+
+
+
+
+Browse.desc:A fake classifier that provides a link in the navigation bar to a prototype combined browsing and searching page. Only works for mgpp collections, and is only practical for small collections.  
+
+
+
+DateList.desc:à€à¥à€²à€Ÿà€žà¥à€«à€Ÿà€¯à€° à€ªà¥à€²à€à€à€šà€šà¥à€žà€Ÿà€° à€®à€Ÿà€¹à¥à€€à¥ à€¹à¥ à€Šà€¿à€šà€Ÿà€à€à€Ÿà€šà¥à€žà€Ÿà€° à€µà€¿à€­à€Ÿà€à€²à¥ à€à€¹à¥.à€Šà€¿à€šà€Ÿà€à€ à€µà€°à¥à€·à€®à€¹à€¿à€šà€Ÿà€Šà€¿à€šà€Ÿà€à€ à€à€¿à€à€µà€Ÿ à€µà€°à¥à€·-à€®à€¹à€¿à€šà€Ÿ-à€Šà€¿à€šà€Ÿà€à€ à€¯à€Ÿ à€ªà¥à€°à€à€Ÿà€°à¥  
+
+DateList.metadata:à€®à¥à€à€Ÿà€¡à€Ÿà€à€Ÿ à€à¥à€²à€Ÿà€žà¥à€«à€Ÿà€¯à€° à€ªà¥à€²à€à€à€šà€šà¥à€žà€Ÿà€° à€
+à€žà¥à€š à€€à¥ à€®à€Ÿà€¹à¥à€€à¥ à€¹à¥ à€Šà€¿à€šà€Ÿà€à€à€Ÿà€šà¥à€žà€Ÿà€° à€µà€¿à€­à€Ÿà€à€²à¥ à€à€¹à¥.à€Šà€¿à€šà€Ÿà€à€ à€µà€°à¥à€·à€®à€¹à€¿à€šà€Ÿà€Šà€¿à€šà€Ÿà€à€ à€à€¿à€à€µà€Ÿ à€µà€°à¥à€·-à€®à€¹à€¿à€šà€Ÿ-à€Šà€¿à€šà€Ÿà€à€ à€¯à€Ÿ à€ªà¥à€°à€à€Ÿà€°à¥  
+
+
+
+
+
+DateList.no_special_formatting:à€Šà€žà¥à€€à€à€µà€à€Ÿà€à¥à€¯à€Ÿ à€¯à€Ÿà€Šà¥à€®à€§à¥à€¯à¥ à€µà€°à¥à€· à€µ à€®à€¹à€¿à€šà€Ÿ à€¯à€Ÿ à€¬à€Šà¥à€Šà€² à€®à€Ÿà€¹à€¿à€€à¥ à€Šà€°à¥à€¶à€µà¥ à€šà€à€Ÿ.  
+
+
+
+List.always_bookshelf_last_level:leaf nodes à€à¥à€¯à€Ÿ à€¯à¥à€¥à¥ à€à€°à¥ à€à€à€Ÿ à€à€à€Ÿà€€ à€à€ à€à€à€ à€
+à€žà€²à€Ÿ à€€à€°à¥ à€à¥à€°à€à€¥à€Ÿà€à¥ à€à€¿à€šà¥à€¹ à€€à€¯à€Ÿà€° à€à€°à€Ÿ  
+
+
+
+
+
+List.partition_type_within_level:The type of partitioning done: either 'per_letter', 'constant_size', or 'none'.  
+
+List.sort_leaf_nodes_using:Metadata fields used for sorting the leaf nodes. Use '|' to separate the metadata groups to stable sort and ';' to separate metadata fields within each group.  
+
+List.use_hlist_for:Metadata fields to use a hlist rather than a vlist. Use ',' to separate the metadata groups and ';' to separate the metadata fields within each group.  
+
+HFileHierarchy.desc:Classifier plugin for generating hierarchical classifications based on a supplementary structure file.  
+
+
+
+Hierarchy.documents_last:à€à¥à€²à€Ÿà€žà€¿à€«à€Ÿà€à€¡ à€šà¥à€¡ à€šà€à€€à€° à€Šà€žà¥à€€à€à€µà€ à€šà¥à€¡ à€Šà€Ÿà€à€µà€Ÿ.  
+
+
+
+
+
+
+
+
+
+Hierarchy.sort:à€®à¥à€à€Ÿà€¡à¥à€à€Ÿ Metadata field to sort leaf nodes by. Leaves will not be sorted if not specified.  
+
+Hierarchy.suppressfirstlevel:Ignore the first part of the metadata value. This is useful for metadata where the first element is common, such as the import directory in gsdlsourcefilename.  
+
+Hierarchy.suppresslastlevel:Ignore the final part of the metadata value. This is useful for metadata where each value is unique, such as file paths.  
+
+HTML.desc:Creates an empty classification that's simply a link to a web page.  
+
+
+
+
+
+
+
+
+
+
+
+Phind.language:Language or languages to use building hierarchy. Languages are identified by two-letter country codes like en (English), es (Spanish), and fr (French). Language is a regular expression, so 'en|fr' (English or French) and '..' (match any language) are valid.  
+
+Phind.min_occurs:The minimum number of times a phrase must appear in the text to be included in the phrase hierarchy.  
+
+
+
+
+
+
+
+
+
+
+
+Phind.untidy:à€µà€°à¥à€à€«à€Ÿà€à€² à€à€Ÿà€¢à¥ à€šà€à€Ÿ.  
+
+
+
+
+
+
+
+RecentDocumentsList.sort:Metadata to sort List by. If not specified, list will be sorted by date of modification/addition.  
+
+
+
+
+
+
+
+Collage.maxDepth:Images for collaging are drawn from mirroring the underlying browse classifier. This controls the maximum depth of the mirroring process.  
+
+Collage.maxDisplay:à€à€Ÿà€žà¥à€€à¥à€€à€à€Ÿà€žà¥à€€ à€à€¿à€€à¥à€° à€žà€à€à¥à€°à€¹à€Ÿà€€ à€Šà€¿à€žà€Ÿà€µà€¯à€Ÿà€ž à€¹à€µà¥.  
+
+
+
+Collage.bgcolor:The background color of the collage canvas, specified in hexadecimal form (for example #008000 results in a forest green background).  
+
+
+
+
+
+Collage.isJava2:Used to control which run-time classes of Java are used. More advanced version of Java (i.e. Java 1.2 onwards) include more sophisticated support for controlling transparency in images, this flag helps control what happens, however the built-in Java runtime for some browsers is version 1.1.  The applet is designed to, by default, auto-detect which version of Java the browser is running and act accordingly.  
+
+Collage.imageMustNotHave:Used to suppress images that should not appear in the collage, such as image buttons that make up the navigation bar.  
+
+
+
+
+#
+# Plugin option descriptions
+#
+AcronymExtractor.adding:à€­à€°à€Ÿ  
+
+
+
+
+
+AcronymExtractor.done_acronym_extract:à€žà€à€à¥à€·à€¿à€ªà¥à€€ à€šà€Ÿà€µà¥  
+
+AcronymExtractor.done_acronym_markup:à€žà€à€à¥à€·à€¿à€ªà¥à€€ à€šà€Ÿà€µ  
+
+
+
+
+
+
+
+
+
+ArchivesInfPlugin.desc:Plugin which recurses through an archives.inf file (i.e. the file generated in the archives directory when an import is done), processing each file it finds.  
+
+
+
+
+
+
+
+
+
+
+
+
+
+BasePlugin.block_exp:Files matching this regular expression will be blocked from being passed to any later plugins in the list. This has no real effect other than to prevent lots of warning messages about input files you don't care about. Each plugin might have a default block_exp. e.g. by default HTMLPlug blocks any files with .gif, .jpg, .jpeg, .png or .css file extensions.  
+
+
+
+BasePlugin.dummy_text:à€¯à€Ÿ à€Šà€žà¥à€€à€à€µà€à€Ÿà€€ à€®à€Ÿà€¹à€¿à€€à¥ à€šà€Ÿà€¹à¥.  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+BasePlugin.smart_block:Block files in a smarter way than just looking at filenames.  
+
+BasePlugin.stems:stems  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ConvertBinaryFile.apply_fribidi:Run the "fribidi" Unicode Bidirectional Algorithm program over the converted file (for right-to-left text).  
+
+
+
+ConvertBinaryFile.convert_to.auto:Automatically select the format converted too.  Format chosen depends on input document type, for example Word will automatically be converted to HTML, whereas PowerPoint will be converted to Greenstone's PagedImage format.  
+
+ConvertBinaryFile.convert_to.html:à€à€à€à¥à€à€®à€à€² à€«à¥à€°à€®à¥
+à€.  
+
+
+
+
+
+ConvertBinaryFile.convert_to.pagedimg_jpg:à€à¥à€ªà¥à€à€à¥ à€°à¥à€ªà€°à¥à€·à€Ÿ  
+
+
+
+
+
+ConvertBinaryFile.desc:This plugin is inherited by such plugins as WordPlug, PPTPlug, PSPlug, RTFPlug and PDFPlug. It facilitates the conversion of these document types to either HTML, TEXT or a series of images. It works by dynamically loading an appropriate secondary plugin (HTMLPlug, StructuredHTMLPlug, PagedImgPlug or TEXTPlug) based on the plugin argument 'convert_to'.  
+
+
+
+
+
+
+
+CSVPlugin.desc:A plugin for files in comma-separated value format. A new document will be created for each line of the file.  
+
+
+
+
+
+DateExtractor.maximum_century:The maximum named century to be extracted as historical metadata (e.g. 14 will extract all references up to the 14th century).  
+
+
+
+
+
+
+
+DirectoryPlugin.recheck_directories:After the files in an import directory have been processed, re-read the directory to discover any new files created.  
+
+
+
+DatabasePlugin.desc:A plugin that imports records from a database. This uses perl's DBI module, which includes back-ends for mysql, postgresql, comma separated values (CSV), MS Excel, ODBC, sybase, etc... Extra modules may need to be installed to use this. See <GSDLHOME>/etc/packages/example.dbi for an example config file.  
+
+DSpacePlugin.desc:DSpacePlug takes a collection of documents exported from DSpace and imports them into Greenstone.  
+	
+
+
+
+
+DSpacePlugin.only_first_doc:This is used to identify the primary data stream of DSpace collection document.With this option, the system will treat the first document in dublic_core metadata file as the possible primary stream.  
+
+
+
+
+
+EmailAddressExtractor.extracting_emails:extracting e-mail addresses  
+
+
+
+
+
+EmailPlugin.no_attachments:à€à¥à€¡à€²à¥à€²à€Ÿ à€®à¥à€žà¥à€ à€žà¥à€µà¥à€¹ à€à€°à¥ à€šà€à€Ÿ.  
+
+
+
+
+
+EmailPlugin.split_exp:A perl regular expression used to split files containing many messages into individual documents.  
+
+ExcelPlugin.desc:à€®à€Ÿà€¯à€à¥à€°à¥à€žà¥à€ªà¥à€ à€à€à¥à€žà¥à€² à€«à€Ÿà€à€² à€®à€¿à€³à€µà€¿à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ (à€°à¥à€µà¥à€¹à€à€š à¥¯à¥« à€à€£à€¿ à¥¯à¥­ )à€ªà¥à€²à€à€à€š  
+
+
+
+
+
+
+
+
+
+
+
+GISExtractor.gazetteer:Gazetteer to use to extract placenames from within text and set as metadata. Requires GIS extension to Greenstone.  
+
+GISExtractor.place_list:When extracting placements, include list of placenames at start of the document. Requires GIS extension to Greenstone.  
+
+
+
+
+
+HTMLImagePlugin.aggressiveness:Range of related text extraction techniques to use.  
+HTMLImagePlugin.aggressiveness.1:Filename, path, ALT text only.  
+HTMLImagePlugin.aggressiveness.2:à€žà€°à¥à€µà€Ÿà€à€à¥ à¥§, à€ªà¥à€²à€ž à€à¥
+à€ªà¥à€¶à€š à€à¥à€¥à¥ à€®à€¿à€³à¥à€².  
+HTMLImagePlugin.aggressiveness.3:à€žà€°à¥à€µà€Ÿà€à€à¥ à€Šà¥à€š, à€ªà¥à€²à€ž à€à¥à€¥à¥ à€ªà€°à€¿à€à¥à€à¥à€Š à€à€ªà€²à€¬à¥à€§  
+HTMLImagePlugin.aggressiveness.4:à¥© à€žà€°à¥à€µ, à€à€£à€¿ à€à€§à¥à€à¥ à€¹à¥à€¡à€° (<h1>, <h2>...) à€à¥à€¥à¥ à€à€ªà€²à€¬à¥à€§ à€
+à€žà¥à€².  
+HTMLImagePlugin.aggressiveness.5:à¥ª à€žà€°à¥à€µ, à€à€£à€¿ à€à€ªà€²à€¬à¥à€§ à€
+à€žà€²à¥à€²à€Ÿ à€¶à€Ÿà€¬à¥à€Šà€¿à€ à€žà€à€°à¥à€Šà€­ .  
+HTMLImagePlugin.aggressiveness.6:à¥ª à€žà€°à¥à€µ, à€à€£à€¿ à€®à¥à€à€Ÿà€à¥
+à€à€à¥ à€ªà€Ÿà€š (à€¶à€¿à€°à¥à€·à€, à€ªà¥à€°à€®à¥à€à€¶à€¬à¥à€Š,à€à€€à¥à€¯à€Ÿà€Šà¥).  
+HTMLImagePlugin.aggressiveness.7:à¥¬ à€à¥ à€žà€°à¥à€µ, à¥«à€µà¥ª à€à€à€€à¥à€°.  
+HTMLImagePlugin.aggressiveness.8:à¥­ à€à¥ à€žà€°à¥à€µ, à€à€£à€¿ à€°à€¿à€ªà¥à€ à€à¥
+à€ªà¥à€¶à€š, à€«à€Ÿà€à€²à€šà€Ÿà€µ, à€à€€à¥à€¯à€Ÿà€Šà¥ (raise ranking of more relevant results)  
+HTMLImagePlugin.aggressiveness.9:à¥§ à€à¥ à€žà€°à¥à€µ, à€à€£à€¿ à€ªà¥à€°à¥à€£ à€à¥à€à¥à€žà€à¥ à€ªà€Ÿà€š.  
+
+
+
+HTMLImagePlugin.convert_params:Additional parameters for ImageMagicK convert on thumbnail creation. For example, '-raise' will give a three dimensional effect to thumbnail images.  
+
+HTMLImagePlugin.desc:A plugin for extracting images and associated text from webpages.  
+
+
+
+
+
+HTMLImagePlugin.max_near_text:Maximum characters near images to extract.  
+
+
+
+
+
+
+
+
+
+
+
+HTMLImagePlugin.no_cache_images:cache images à€à¥à€ à€šà€à€Ÿ (à€®à¥à€³ à€¯à¥à€à€°à€à€² à€ªà€¹à€Ÿ)  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+HTMLPlugin.hunt_creator_metadata:à€à¥à€°à€à€¥à€à€Ÿà€° à€¯à¥à€¥à¥à€š à€®à€Ÿà€¹à€¿à€€à¥ à€¶à¥à€§à¥à€š à€€à¥ à€žà€à€à¥à€°à€¹à€ à€¯à¥à€¥à¥ à€ à¥à€µà€Ÿ.  
+
+HTMLPlugin.keep_head:à€à€à€à¥à€à€®à€à€² à€«à€Ÿà€à€² à€®à€§à¥à€š à€¹à¥à€¡à€° à€à€Ÿà€¢à¥ à€šà€à€Ÿ.  
+
+HTMLPlugin.metadata_fields:Comma separated list of metadata fields to attempt to extract. Use 'tag<tagname>' to have the contents of the first <tagname> pair put in a metadata element called 'tagname'. Capitalise this as you want the metadata capitalised in Greenstone, since the tag extraction is case insensitive.  
+
+HTMLPlugin.no_metadata:Don't attempt to extract any metadata from files.  
+
+
+
+HTMLPlugin.nolinks:Don't make any attempt to trap links (setting this flag may improve speed of building/importing but any relative links within documents will be broken).  
+
+
+
+
+
+
+
+HTMLPlugin.title_sub:Substitution expression to modify string stored as Title. Used by, for example, PDFPlug to remove "Page 1", etc from text used as the title.  
+
+
+
+
+
+
+
+ImageConverter.converttotype:à€®à¥à€à¥à€¯ à€à€¿à€€à¥à€° 's'à€¯à€Ÿ à€®à€§à¥à€¯à¥ à€°à¥à€ªà€Ÿà€à€€à€°à¥à€€ à€à€°à€Ÿ.  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ImageConverter.screenviewsize:Make screenview images of size nxn.  
+
+
+
+
+
+
+
+
+
+
+
+IndexPlugin.desc:This recursive plugin processes an index.txt file. The index.txt file should contain the list of files to be included in the collection followed by any extra metadata to be associated with each file.\n\nThe index.txt file should be formatted as follows: The first line may be a key (beginning with key:) to name the metadata fields (e.g. key: Subject Organization Date). The following lines will contain a filename followed by the value that metadata entry is to be set to. (e.g. 'irma/iw097e 3.2 unesco 1993' will associate the metadata Subject=3.2, Organization=unesco, and Date=1993 with the file irma/iw097e if the above key line was used)\n\nNote that if any of the metadata fields use the Hierarchy classifier plugin then the value they're set to should correspond to the first field (the descriptor) in the appropriate classification file.\n\nMetadata values may be named separately using a tag (e.g. <Subject>3.2) and this will override any name given to them by the key line. If there's no key line any unnamed metadata value will be named 'Subject'.  
+
+
+
+ISISPlugin.subfield_separator:The string used to separate subfields in CDS/ISIS database records.  
+
+
+
+
+
+
+
+KeyphraseExtractor.extract_keyphrases_kea4:Extract keyphrases automatically with Kea 4.0 (default settings). Kea 4.0 is a new version of Kea that has been developed for controlled indexing of documents in the domain of agriculture.  
+
+KeyphraseExtractor.extract_keyphrase_options:Options for keyphrase extraction with Kea. For example: mALIWEB - use ALIWEB extraction model; n5 - extract 5 keyphrase;, eGBK - use GBK encoding.  
+
+
+
+KeyphraseExtractor.missing_kea:Error: The Kea software could not be found at %s. Please download Kea %s from http://www.nzdl.org/Kea and install it in this directory.  
+
+LaTeXPlugin.desc:LaTeX à€ªà¥à€°à€²à¥à€à€Ÿ à€žà€Ÿà€ à¥ à€ªà¥à€²à€à€à€š  
+
+LOMPlugin.desc:à€à€£à€²à¥à€²à¥à€¯à€Ÿ LOM (Learning Object Metadata) à€«à€Ÿà€à€² à€à€°à¥à€€à€Ÿ à€ªà¥à€²à€à€à€š.  
+
+
+
+
+
+
+
+MARCPlugin.desc:à€®à€Ÿà€°à¥à€ à€ªà¥à€²à€à€à€š  
+
+MARCPlugin.metadata_mapping:Name of file that includes mapping details from MARC values to Greenstone metadata names. Defaults to 'marctodc.txt' found in the site's etc directory.  
+
+
+
+MARCXMLPlugin.metadata_mapping_file:Name of file that includes mapping details from MARC values to Greenstone metadata names. Defaults to 'marctodc.txt' found in the site's etc directory.  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+MetadataPass.desc:On-the-side base class to BasPlug that supports metadata plugins utilise metadata_read pass of import.pl  
+
+
+
+
+
+MP3Plugin.desc:à€à€®à€ªà¥à¥© à€«à€Ÿà€à€² à€ªà¥à€°à¥à€žà¥à€ž à€à€°à€£à¥à€¯à€Ÿà€à€°à¥à€€à€Ÿ à€ªà¥à€²à€à€à€š.  
+
+
+
+
+
+MP3Plugin.metadata_fields:Comma separated list of metadata fields to extract (assuming present) in an MP3 file. Use \"*\" to extract all the fields.  
+
+
+
+
+NulPlugin.add_metadata_as_text:Add a table of metadata as the text of the document, rather than "This document has no text".  
+
+
+
+
+
+
+
+
+
+OggVorbisPlugin.desc:A plugin for importing Ogg Vorbis audio files.  
+
+
+
+
+
+
+
+PagedImagePlugin.documenttype.paged:Paged documents have next and previous arrows and a 'go to page X' box  
+
+PagedImagePlugin.documenttype.hierarchy:à€®à¥à€à¥à€¯ à€ªà¥à€°à€²à¥à€à€Ÿà€à¥ à€žà¥à€à¥ à€ªà€€à¥à€°  
+
+PagedImagePlugin.headerpage:à€ªà¥à€°à€€à¥à€¯à¥à€ à€ªà¥à€°à€²à¥à€à€Ÿà€²à€Ÿ à€
+à€žà¥ à€¹à¥à€¡à€° à€Šà¥à€¯à€Ÿ à€à¥à€¯à€Ÿ à€®à€§à¥à€¯à¥ à€à€¿à€€à¥à€° à€šà€Ÿà€¹à¥.  
+
+
+
+
+
+
+
+
+
+
+
+PDFPlugin.use_sections:à€ªà¥à€¡à¥à€à€« à€«à€Ÿà€à€²à€à¥à€¯à€Ÿ à€ªà¥à€°à€€à¥à€¯à¥à€ à€ªà€Ÿà€šà€Ÿà€à€°à¥à€€à€Ÿ à€žà¥à€µà€€à€à€€à¥à€° à€µà€¿à€­à€Ÿà€ à€€à€¯à€Ÿà€° à€à€°à€Ÿ.  
+
+
+
+
+
+
+
+PostScriptPlugin.extract_pages:à€ªà¥à€à€ž à€¹à¥à€¡à€° à€µà€°à¥à€š à€ªà€Ÿà€šà¥ à€à¥à€¯à€Ÿ.  
+
+
+
+PowerPointPlugin.desc:à€®à€Ÿà€¯à€à¥à€°à¥à€žà¥à€«à¥à€ à€ªà¥à€µà€°à€ªà¥à€à€à€ à€«à€Ÿà€à€² à€à¥à€£à¥à€¯à€Ÿà€à€°à¥à€€à€Ÿ à€ªà¥à€²à€à€à€š.  
+
+
+
+
+
+
+
+
+
+
+
+ReadTextFile.could_not_extract_encoding:à€žà¥à€à€šà€Ÿ: %s - à€
+à€à¥à€ %s à€¯à¥à€¥à¥à€š à€à€šà€à¥à€¡à¥à€à€ à€¹à¥à€£à€Ÿà€° à€šà€Ÿà€¹à¥.  
+
+
+
+ReadTextFile.could_not_open_for_reading:à€µà€Ÿà€à€šà€Ÿà€à€°à¥à€€à€Ÿ à€à€à€¡à€€à€Ÿ à€¯à¥à€£à€Ÿà€° à€šà€Ÿà€¹à¥.  
+
+
+
+
+
+
+
+ReadTextFile.empty_file:à€«à€Ÿà€à€² à€®à€§à¥à€¯à¥ à€®à€Ÿà€¹à€¿à€€à¥ à€šà€Ÿà€¹à¥  
+
+
+
+ReadTextFile.file_has_no_text:à€à¥à€à€ %s contains no text  
+
+ReadTextFile.input_encoding:The encoding of the source documents. Documents will be converted from these encodings and stored internally as utf8.  
+
+ReadTextFile.input_encoding.auto:Use text categorization algorithm to automatically identify the encoding of each source document. This will be slower than explicitly setting the encoding but will work where more than one encoding is used within the same collection.  
+
+ReadTextFile.read_denied:%s à€¡à€¿à€šà€Ÿà€à€¡ à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€ªà€°à€µà€Ÿà€šà€à¥  
+
+ReadTextFile.separate_cjk:Insert spaces between Chinese/Japanese/Korean characters to make each character a word. Use if text is not segmented.  
+
+
+
+ReadTextFile.wrong_encoding:WARNING: %s was read using %s encoding but appears to be encoded as %s.  
+
+ReadXMLFile.desc:à€¬à¥à€ž à€à¥à€²à€Ÿà€ž à€à€à¥à€žà€à€®à€à€² à€ªà¥à€²à€à€žà€Ÿà€ à¥.  
+
+ReadXMLFile.xslt:Transform a matching input document with the XSLT in the named file.  A relative filename is assumed to be in the collection's file area, for instance etc/mods2dc.xsl.  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+StructuredHTMLPlugin.level3_header:possible user-defined styles for the level3 header in the HTML document (equivalent to <h3>).  
+
+
+
+TextPlugin.desc:à€à€à€ à€žà€Ÿà€§à€Ÿ à€ªà¥à€°à€²à¥à€ à€€à€¯à€Ÿà€° à€à€°à€Ÿ.à€®à¥à€à€¡à¥à€à€Ÿ à€à€°à¥à€€à€Ÿ à€°à¥à€¶à€¿à€·à€ à€Šà¥à€¯à€Ÿ.(  
+
+
+
+
+
+
+
+UnknownPlugin.file_format:à€«à€Ÿà€à€²à€à¥ à€ªà¥à€°à€à€Ÿà€° (à€à€Šà€Ÿà€ MPEG, MIDI, ...)  
+
+UnknownPlugin.mime_type:Mime type of the file (e.g. image/gif).  
+
+UnknownPlugin.process_extension:Process files with this file extension. This option is an alternative to process_exp that is simpler to use but less flexible.  
+
+
+
+WordPlugin.desc:à€®à€Ÿà€¯à€à¥à€°à¥à€žà¥à€«à¥à€ à€µà€°à¥à€¡à€à¥ à€ªà¥à€°à€²à¥à€ à€®à€¿à€³à€µà€¿à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€ªà¥à€²à€à€à€š.  
+
+
+
+
+
+ZIPPlugin.desc:Plugin which handles compressed and/or archived input formats currently handled formats and file extensions are:\ngzip (.gz, .z, .tgz, .taz)\nbzip (.bz)\nbzip2 (.bz2)\nzip (.zip .jar)\ntar (.tar)\n\nThis plugin relies on the following utilities being present (if trying to process the corresponding formats):\ngunzip (for gzip)\nbunzip (for bzip)\nbunzip2 \nunzip (for zip)\ntar (for tar)  
+
+#
+# Download module option descriptions
+#
+
+
+
+
+
+
+
+
+
+
+OAIDownload.url_disp:à€¯à¥à€à€°à€à€² à€žà¥à€°à¥à€ž  
+
+
+OAIDownload.set:Restrict the download to the specified set in the repository  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+WebDownload.depth:à€¡à€Ÿà€à€šà€²à¥à€¡ à€à€°à€€à€Ÿà€šà€Ÿ à€à€¿à€€à¥ à€¹à€Ÿà€¯à€ªà€°à€²à€¿à€à€ à€Šà¥à€€à€Ÿ à€¯à¥à€€à€Ÿà€€.  
+WebDownload.depth_disp:à€¡à€Ÿà€à€šà€²à¥à€¡ Depth  
+WebDownload.below:à€¯à€Ÿ à€¯à¥à€à€°à€à€² à€«à€à¥à€€ à€®à€¿à€°à€° à€žà€Ÿà€à€ à€à€°à€¿à€€à€Ÿ  
+
+
+WebDownload.within_disp:à€¯à€Ÿà€ à€žà€Ÿà€à€ à€®à€§à¥à€² à€«à€à¥à€€ à€®à€¿à€°à€° à€«à€Ÿà€à€²  
+
+WebDownload.html_only_disp:à€«à€à¥à€€ à€à€à€à¥à€à€®à€à€² à€«à€Ÿà€à€² à€¡à€Ÿà€à€šà€žà€²à¥à€¡ à€à€°à€Ÿ.  
+
+
+WgetDownload.proxy_on:Proxy on  
+WgetDownload.proxy_host:à€ªà¥à€°à¥à€à¥à€à¥ à€¹à¥à€žà¥à€  
+
+
+
+
+Z3950Download.desc:Z3950 repositories à€¯à¥à€¥à¥à€š à€¡à€Ÿà€à€šà€²à¥à€¡ à€à€°à€£à¥à€¯à€Ÿà€žà€Ÿà€ à¥ à€®à¥à€¡à¥à€¯à¥à€²  
+
+Z3950Download.host_disp:à€¹à¥à€žà¥à€  
+Z3950Download.port:à€°à€¿à€ªà¥à€à€à€°à¥à€à€Ÿ à€ªà¥à€°à¥à€ à€šà€à€¬à€°  
+
+Z3950Download.database:à€¯à€Ÿ à€°à¥à€à¥à€°à¥à€¡ à€à€°à¥à€€à€Ÿ à€¡à¥à€à€Ÿà€¬à¥à€žà€®à€§à¥à€¯à¥ à€¶à¥à€§ à€à¥à€¯à€Ÿ.  
+Z3950Download.database_disp:à€¡à¥à€à€Ÿà€¬à¥à€ž  
+
+
+
+
+
+
+#
+#Plugout option descriptions
+#
+
+
+
+BasPlugout.desc:Base class for all the export plugouts.
+BasPlugout.group_size:à€à€à€Ÿà€ à€à€à¥à€žà€à€®à€à€² à€«à€Ÿà€à€² à€®à€§à¥à€¯à¥ à€
+à€šà¥à€ à€ªà¥à€°à€²à¥à€.  
+BasPlugout.gzip_output:Use gzip to compress resulting xml documents (don't forget to include ZIPPlug in your plugin list when building from compressed documents).  
+
+
+BasPlugout.verbosity:Controls the quantity of output. 0=none, 3=lots.  
+BasPlugout.xslt_file:Transform a document with the XSLT in the named file.  
+
+
+
+
+
+
+
+
+
+
+
+MARCXMLPlugout.group:Output the marc xml records into a single file.  
+MARCXMLPlugout.mapping_file:à€à¥à€°à€Ÿà€šà¥à€žà€«à¥à€°à€®à¥à€¶à€š à€à€°à€¿à€€à€Ÿ à€®à¥
+à€ªà¥à€à€ à€«à€Ÿà€à€² à€µà€Ÿà€ªà€°à€Ÿ.  
+
+METSPlugout.desc:à€à¥à€°à¥à€šà€žà¥à€à¥à€š à€ªà¥à€°à¥à€«à€Ÿà€à€² à€µà€Ÿà€ªà€°à€£à¥à€¯à€Ÿà€à€°à¥à€€à€Ÿ METS à€«à¥à€°à€®à¥
+à€ à€µà€Ÿà€ªà€°à€Ÿ  
+
+METSPlugout.xslt_mets:Transform a mets's docmets.xml with the XSLT in the named file.  
+
+#
+# Perl module strings
+#
+
+classify.could_not_find_classifier:à€à¥à€à€ à€à¥à€²à€Ÿà€žà€¿à€«à€Ÿà€¯à€° à€šà€Ÿà€¹à¥.  
+
+
+
+
+
+
+
+
+
+plugin.kill_file:Process killed by .kill file  
+
+plugin.n_considered:%d à€ªà¥à€°à€²à¥à€ à€ªà¥à€°à€à¥à€°à€¿à€¯à¥à€žà€Ÿà€ à¥ à€à¥à€€à€²à¥.  
+
+
+
+
+
+
+
+plugin.no_plugin_could_process:à€žà¥à€à€šà€Ÿà€ à€ªà¥à€²à€à€à€š à€ªà¥à€°à¥à€žà¥à€ž à€à€Ÿà€²à¥à€²à¥ à€šà€Ÿà€¹à¥.  
+
+plugin.no_plugin_could_recognise:à€žà¥à€à€šà€Ÿà€ %s à€ªà¥à€²à€à€à€š à€à€³à€à¥ à€¶à€à€€ à€šà€Ÿà€¹à¥.  
+
+
+
+plugin.no_plugin_could_recognise_this_file:à€à¥à€£à€€à¥à€¯à€Ÿà€¹à¥ à€ªà¥à€²à€à€à€šà€²à€Ÿ à€¹à¥ à€«à€Ÿà€à€² à€à€³à€à€€à€Ÿ à€à€²à¥ à€šà€Ÿà€¹à¥.  
+
+
+
+
+
+
+
+plugin.one_unrecognised:à¥§ à€
+à€šà¥à€³à€à¥  
+
+
+
+
+
+
+
+plugout.could_not_find_plugout:à€à¥à€à€ \"%s\" à€ªà¥à€²à€à€à€à€ à€®à€¿à€³à€€ à€šà€Ÿà€¹à¥  
Index: /gsdl/stable/perllib/strings_ro.properties
===================================================================
--- /gsdl/stable/perllib/strings_ro.properties	(revision 20131)
+++ /gsdl/stable/perllib/strings_ro.properties	(revision 20131)
@@ -0,0 +1,1301 @@
+#
+# Resource bundle description
+#
+
+Language.code:ro  
+Language.name:EnglezÄ  
+
+OutputEncoding.unix:iso_8859_1  
+OutputEncoding.windows:iso_8859_1  
+
+
+#
+# Common output messages and strings
+#
+
+common.cannot_create_file:EROARE: Nu pot crea fiÅierul %s  
+
+common.cannot_find_cfg_file:EROARE: Nu pot gÄsi fiÅierul de configurare %s  
+
+common.cannot_open:EROARE: Nu pot deschide %s  
+
+common.cannot_open_fail_log:EROARE: Nu pot deschide jurnalul %s  
+
+common.cannot_open_output_file:EROARE: Nu pot deschide fiÅierul rezultat %s  
+
+common.cannot_read:EROARE: Nu pot citi %s  
+
+common.cannot_read_file:EROARE: Nu pot citi fiÅierul %s  
+
+common.general_options:opÅ£iuni generale (pentru %s)  
+
+common.must_be_implemented:funcÅ£ia trebuie implementatÄ Ã®n subclasÄ  
+
+common.options:opÅ£iuni  
+
+common.processing:procesez  
+
+common.specific_options:opÅ£iuni specifice  
+
+common.usage:Utilizare  
+
+common.info:informaÅ£ii  
+
+common.invalid_options:Argumente invalide: %s  
+
+
+
+
+
+
+#
+# Script option descriptions and output messages
+#
+
+scripts.language:Limba pentru afiÅarea descrierii opÅ£iunilor ( de exemplu, 'en_US' specificÄ engleza americanÄ).
+
+scripts.xml:Produce informaÅ£ii Ã®n format XML fÄrÄ comentarii âcosmetizateâ, dar care au mult mai multe detalii.  
+
+scripts.listall:ListeazÄ toate elementele care sunt cunoscute.  
+
+scripts.describeall:AfiÅeazÄ opÅ£iunile pentru toate elementele cunoscute  
+
+scripts.both_old_options:ATENÅ¢IE: -removeold a fost menÅ£ionat cu -keepold sau cu -incremental, se procedeazÄ automat la -removeold. ConÅ£inutul curent al directorului %s va fi Åters.
+
+scripts.no_old_options:ATENÅ¢IE: Niciuna dintre -removeold, -keepold sau -incremental nu au fost specificate: se trece automat la -removeold. ConÅ£inutul curent al directorului %s va fi Åters.  
+
+
+
+# -- buildcol.pl --
+
+buildcol.archivedir:Unde stau arhivele.  
+
+buildcol.builddir:Unde trebuie puse indexurile construite.  
+
+buildcol.cachedir:ColecÅ£ia va fi construitÄ temporar aici Ã®nainte de a fi copiatÄ Ã®n directorul de construcÅ£ie.  
+
+buildcol.cannot_open_cfg_file:ATENÅ¢IE: Nu pot deschide fiÅierul de configurare pentru actualizare: %s  
+
+buildcol.collectdir:Calea cÄtre directorul de âcolectareâ.  
+
+buildcol.copying_back_cached_build:CopiazÄ Ã®napoi construcÅ£ia cache (prestocare)  
+
+buildcol.create_images:IntenÅ£ia este de a crea imagini implicite pentru noua colecÅ£ie. AceastÄ funcÅ£ionalitate se bazeazÄ pe instalarea prealabilÄ a GIMP-ului Ã®mpreunÄ cu modulele perl care sÄ permitÄ scriptingul din perl.  
+
+buildcol.debug:PrintaÅ£i rezultatele la STDOUT.  
+
+buildcol.desc:Script PERL folosit pentru a construi o colecÅ£ie Greenstone din documente GA.  
+
+buildcol.faillog:Numele jurnalului de nereuÅite (fail log) . Acest jurnal Ã®nscrie fiÅierele Åi tipul acestora, care nu pot fi procesate.  
+
+
+
+buildcol.index:Indexul de construcÅ£ie (va construi totul Ã®n fiÅierul config dacÄ nu este setat).  
+
+buildcol.incremental:Doar documentele index care nu au fost indexate Ã®n prealabil. ImplicÄ utilizarea -keepold. Se bazeazÄ pe indexatorul lucene.  
+
+buildcol.keepold:Nu va distruge conÅ£inutul curent al directorului de construcÅ£ie.  
+
+buildcol.maxdocs:NumÄrul maxim de documente pentru a fi construite.  
+buildcol.maxnumeric:NumÄrul maxim de digiÅ£i pe care Ã®l poate avea un âcuvÃ¢ntâ Ã®n indexul dicÅ£ionarului. Numerele mari sunt sparte Ã®n cÃ¢teva cuvinte pentru indexare. De exemplu, dacÄ numÄrul este de 4 digiÅ£i maxim, atunci â1342663â va fi spart Ã®n â1342â Åi â663â.  
+buildcol.mode:PÄrÅ£i ale procesului de construcÅ£ie pentru a fi Ã®ndeplinite.  
+buildcol.mode.all:IndeplineÅte-le pe toate.  
+buildcol.mode.build_index:Pur Åi simplu indexaÅ£i textul.  
+buildcol.mode.compress_text:ComprimaÅ£i textul.  
+buildcol.mode.infodb:ConstruieÅte baza de date pentru metadate.  
+
+buildcol.no_default_images:Nu vor fi generate imagini Ã®n mod implicit.  
+
+buildcol.no_image_script:ATENÅ¢IE: Scriptul de alcÄtuire a imaginilor nu a putut fi gÄsit: %s  
+
+buildcol.no_strip_html:Nu eliminaÅ£i tagurile html din textul indexat (se foloseÅte doar pentru colecÅ£iile mgpp).  
+
+buildcol.no_text:Nu stocaÅ£i text comprimat. AceastÄ opÅ£iune este necesarÄ minimizÄrii dimensiunii indexurilor construite dacÄ doriÅ£i sÄ afiÅaÅ£i documentele originale la momentul rulÄrii (de exemplu, nu veÅ£i putea regÄsi versiunea comprimatÄ a textului).  
+
+buildcol.sections_index_document_metadata:Indexarea metadatelor documentului la nivelul secÅ£iunii  
+buildcol.sections_index_document_metadata.never:Nu indexaÅ£i niciun document de metadate la nivel de secÅ£iune.  
+buildcol.sections_index_document_metadata.always:AdÄugarea tuturor metadatelor de pe acelaÅi nivel chiar dacÄ metadatele de la nivelul secÅ£iunii pentru acel nume existÄ deja.  
+buildcol.sections_index_document_metadata.unless_section_metadata_exists:AdÄugaÅ£i doar metadate la nivel de document dacÄ nu existÄ metadate la nivel de secÅ£iune pentru acel nume.  
+
+buildcol.out:Numele fiÅierului sau mijlocul de tipÄrire Åi a rezultatelor de stare.  
+
+buildcol.params:numele colecÅ£iei [options]  
+
+buildcol.remove_empty_classifications:Ascunde clasificatorii goi Åi nodurile de clasificare (aceia care nu conÅ£in niciun document).  
+
+buildcol.removeold:Va elimina conÅ£inutul vechi al directorului de construcÅ£ie.  
+
+buildcol.unlinked_col_images:Imaginile ColecÅ£iei nu pot fi legate corect (prin linkuri).  
+
+buildcol.unknown_mode:Mod de acÅ£iune necunoscut: %s  
+
+buildcol.updating_archive_cache:Actualizarea arhivei de preÃ®ncÄrcare (cache)  
+
+buildcol.verbosity:ControleazÄ calitatea rezultatelor. 0=lipsÄ, 3=mai multe.  
+
+
+# -- classinfo.pl --
+
+classinfo.collection:Numind o colecÅ£ie, veÅ£i face ca classinfo.pl sÄ aparÄ mai Ã®ntÃ¢i Ã®n collect/collection-name/perllib/classify. DacÄ clasificatorul nu este gÄsit acolo se va cÄuta Åi Ã®n directorul general perllib/classify.  
+
+classinfo.desc:AfiÅeazÄ informaÅ£ii despre un clasificator.  
+
+classinfo.general_options:OpÅ£iunile generale sunt moÅtenite din clasele pÄrinte ale clasificatorului.  
+
+classinfo.info:informaÅ£ii  
+
+classinfo.no_classifier_name:EROARE: Trebuie furnizat un nume pentru clasificator.  
+
+classinfo.option_types:Clasificatorii au douÄ tipuri de opÅ£iuni  
+
+classinfo.params:[options] nume clasificator  
+
+classinfo.passing_options:OpÅ£iunile pot fi trecute oricÄrui clasificator prin includerea acestora Ã®n fiÅierul de configurare collect.cfg.  
+
+classinfo.specific_options:Sunt definite opÅ£iuni specifice Ã®n cadrul clasificatorului Åi sunt disponibile doar acestui clasificator Ã®n mod explicit.  
+
+# -- downloadfrom.pl --
+downloadfrom.cache_dir:LocaÅ£ia directorului de preÃ®ncÄrcare (cache)  
+downloadfrom.desc:DescarcÄ fiÅierele dintr-un server extern  
+downloadfrom.download_mode:tipul serverului de la care se face descÄrcarea  
+downloadfrom.download_mode.Web:HTTP  
+downloadfrom.download_mode.MediaWiki:Site-ul MediaWiki  
+downloadfrom.download_mode.OAI:Open Archives Initiative  
+downloadfrom.download_mode.z3950:Server z3950  
+downloadfrom.download_mode.SRW:Serviciu web SearchRetrieve  
+downloadfrom.incorrect_mode:parametrul download_mode a fost incorect.  
+downloadfrom.info:Mai degrabÄ printaÅ£i informaÅ£iile despre server decÃ¢t sÄ le descÄrcaÅ£i  
+downloadfrom.params:[general options] [specific download options]  
+
+# -- downloadinfo.pl --
+
+downloadinfo.desc:PrinteazÄ informaÅ£ii despre un modul de download  
+downloadinfo.collection:Denumind o colecÅ£ie va face ca downloadinfo.pl sÄ aparÄ mai Ã®ntÃ¢i Ã®n collect/collection-name/perllib/downloaders. DacÄ modulul nu este gÄsit acolo sistemul va cÄuta Ã®n directorul general perllib/downloaders.  
+downloadinfo.params:[options] [download-module]  
+downloadinfo.general_options:OpÅ£iunile generale sunt moÅtenite din clasele pÄrinte ale modulelor de descÄrcare.  
+downloadinfo.specific_options:OpÅ£iuni specifice sunt definite Ã®n cadrul modulului de descÄrcare Åi sunt disponibile doar acestui tip particular de modul de descÄrcare.  
+downloadinfo.option_types:Modulele de descÄrcare pot avea douÄ tipuri de opÅ£iuni  
+
+# -- explode_metadata_database.pl --
+explode.desc:Destinderea bazei de date a metadatelor  
+
+
+ 
+explode.document_field:Elementele de metadate care specificÄ numele de fiÅiere ale documentelor pentru a le obÅ£ine Åi include Ã®n colecÅ£ie.  
+
+explode.document_prefix:Un prefix pentru locaÅ£iile documentelor (de exemplu pentru utilizarea opÅ£iunii document_field).  
+
+explode.document_suffix:Un sufix pentru locaÅ£ia documentului (pentru a fi utilizat cu opÅ£iunea document_field).  
+
+explode.encoding:Codarea utilizatÄ atunci cÃ¢nd se citeÅte fiÅierul de baze de date  
+explode.metadata_set:Setul de metadate (namespace) pentru a exporta toate metadatele precum  
+explode.plugin:Extensie pentru destindere  
+
+explode.params:[options] numele fiÅierului  
+explode.records_per_folder:NumÄrul Ã®nregistrÄrilor care sunt puse Ã®n fiecare subdirector.  
+
+# -- replace_srcdoc_with_html.pl --
+
+
+
+
+# -- exportcol.pl --
+
+exportcol.out:Nume de fiÅier sau mijloc de printare a stÄrii rezultatelor.  
+exportcol.cddir:Numele directorului Ã®n care se face exportul conÅ£inutului CD-ului.  
+exportcol.cdname:Numele CD-ROM-ului -- acesta este lucrul care apare Ã®n meniul de start din moment ce CD-ROM-ul este instalat  
+exportcol.desc:Script PERL utilizat pentru a exporta una sau mai multe colecÅ£ii pe un CD-ROM destinat sistemului de operare Windows.  
+exportcol.noinstall:Crearea unui CD-ROM de pe care sÄ ruleze biblioteca fÄrÄ a instala nimic pe computerul gazdÄ.  
+exportcol.params:[options] numele-colecÅ£iei1 numele-colecÅ£iei2 ...  
+exportcol.coll_not_found:Ignorarea colecÅ£iilor invalide %s: colecÅ£ia nu a fost gÄsitÄ la %s.  
+exportcol.coll_dirs_not_found:Ignorarea colecÅ£iilor %s invalide: unul dintre directoarele urmÄtoare nu au fost gÄsite:  
+exportcol.fail:exportcol.pl a eÅuat:  
+exportcol.no_valid_colls:Nu sunt specificate colecÅ£ii valide pentru export.  
+exportcol.couldnt_create_dir:Nu am putut crea directorul %s.  
+exportcol.couldnt_create_file:Nu am putut crea %s.  
+exportcol.instructions:Pentru a crea un CD auto instalabil pentru sistemul de operare Windows, scrieÅ£i conÅ£inutul acestui director direct pe CD-ROM.  
+exportcol.non_exist_files:Unul sau mai multe dintre fiÅierele urmÄtoare care sunt necesare, precum Åi directoarele acestora, nu existÄ:  
+exportcol.success:exportcol.pl a avut succes:  
+exportcol.output_dir:ColecÅ£iile exportate (%s) sunt Ã®n %s.  
+exportcol.export_coll_not_installed:Nu a fost instalatÄ funcÅ£ia de export pe CD-ROM.  
+
+# -- import.pl --
+
+import.archivedir:Aici se Ã®ncheie materialul convertit.  
+
+import.manifest:Un fiÅier XML care detaliazÄ care fiÅiere trebuie importate. Utilizat Ã®n locul parcurgerii descendente a directorului de import, de obicei pentru construcÅ£ia incrementalÄ.  
+
+import.cannot_open_stats_file:ATENÅ¢IE: Nu am putut deschide fiÅierele de stare %s.  
+
+import.cannot_open_fail_log:EROARE: Nu am putut deschide jurnalul de nereuÅite %s  
+
+import.cannot_sort:ATENÅ¢IE: import.pl nu poate sorta documentele atunci cÃ¢nd dimensiunea grupului este mai mica decÃ¢t 1. OpÅ£iunea sortmeta va fi ignoratÄ.  
+
+import.collectdir:Calea directorului de âcolectareâ.  
+
+import.complete:Import complet  
+
+import.debug:ImprimaÅ£i textul importat cÄtre STDOUT (pentru importarea GA)  
+
+import.desc:Script Perl utilizat pentru a importa fiÅiere Ã®n formatul GA pregÄtit pentru construcÅ£ie.  
+
+import.faillog:Numele fiÅierului jurnal pentru eÅecuri. Acest jurnal primeÅte numele fiÅierelor celor care au eÅuat Ã®n a procesate.  
+
+import.groupsize:NumÄrul de documente importate, care sÄ fie grupate Ã®ntr-un fiÅier XML.  
+
+import.gzip:FolosiÅ£i gzip pentru a comprima documentele xml rezultate (nu uitaÅ£i sÄ includeÅ£i ZIPPlug Ã®n lista extensiilor atunci cÃ¢nd construiÅ£i din documentele comprimate).  
+
+import.importdir:Locul unde stÄ materialul original.  
+
+import.incremental:ImportÄ doar documente care sunt mai recente (dupÄ timestamp) decÃ¢t cele din arhivÄ. ImplicÄ -keepold.  
+
+import.keepold:Nu va distruge conÅ£inutul curent al directorului arhivei.  
+
+import.maxdocs:numÄrul maxim de domente pentru a fi importate.  
+
+import.no_import_dir:Eroare: Directorul de import (%s) nu a fost gÄsit.  
+
+import.no_plugins_loaded:EROARE: Nu sunt Ã®ncÄrcate extensii.  
+
+import.OIDtype:Metoda utilizatÄ cÃ¢nd se genereazÄ identificatori unici pentru fiecare document.  
+import.OIDtype.hash:Se aplicÄ codare hash asupra conÅ£inutului fiÅierului. Identificatorii documentului vor fi aceiaÅi de fiecare datÄ cÃ¢nd colecÅ£ia este importatÄ.  
+
+import.OIDtype.incremental:FoloseÅte un contor simplu pentru document. Este semnificativ mai rapid decÃ¢t modul âhashâ, dar nu atribuie acelaÅi identificator aceluiaÅi conÅ£inut al documentului iar documentele urmÄtoare nu pot fi adÄugate arhivei existente.  
+
+import.OIDtype.assigned:FolosiÅ£i valoarea de metadate datÄ de opÅ£iunea OIDmetadata (precedatÄ de 'D'). DacÄ nu este specificat, pentru un anume document, atunci va fi folosit un hash (codare tip utilizatÄ pentru a individualiza un fiÅier). AceÅti identificatori ar trebui sÄ fie unici.  
+
+import.OIDtype.dirname:FoloseÅte numele directorului pÄrinte (precedat de 'J'). Aici ar trebui sÄ fie doar un singur document pentru fiecare director, iar numele directoarelor ar trebui sÄ fie unice. De exemplu, import/b13as/h15ef/page.html va avea un identificator Jh15ef.  
+
+import.OIDmetadata:SpecificÄ elementul de metadate care conÅ£ine identificatorul unic al documentului pentru a fi utilizat cu -OIDtype=assigned.  
+
+import.saveas:Acest lucru este pentru a decide formatul de arhivÄ care trebuie generat. Setarea implicitÄ este GA.  
+
+import.out:Numele fiÅierului sau instrumentul de printare al statisticilor.  
+
+import.params:numele colecÅ£iei [options]  
+
+import.removeold:Va elimina vechiul conÅ£inut al directorului arhivei.  
+
+import.removing_archives:Eliminarea conÅ£inutului curent al directorului arhivelor...  
+
+import.removing_tmpdir:Eliminarea conÅ£inutului directorului âtmpâ al colecÅ£iei...  
+
+
+
+
+
+import.sortmeta:SortaÅ£i documentele alfabetic dupÄ metdate pentru a fi construite. Rezultatele cÄutÄrii dupÄ interogÄri boolean vor fi afiÅate Ã®n aceastÄ ordine. Acestea vor fi dezactivate dacÄ dimensiunea grupului este mai micÄ decÃ¢t 1. Poate fi o listÄ separatÄ prin virgule pentru sortarea a mai mult de o valoare de metadate.  
+
+import.statsfile:Numele fiÅierului sau instrumentul de printare al statisticilor.  
+
+import.stats_backup:Ãn loc, va tipÄri statisticile cÄtre STDERR.  
+
+import.verbosity:ControleazÄ calitatea rezultatelor. 0=lipsÄ, 3=mai multe.  
+
+# -- schedule.pl --
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# -- export.pl --
+
+export.exportdir:Unde se terminÄ exportul materialelor.  
+
+export.cannot_open_stats_file:ATENÅ¢IE: Nu am putut deschide fiÅierele statistice %s.  
+
+export.cannot_open_fail_log:EROARE: Nu am putut deschide jurnalul de nereuÅite (fail log) %s  
+
+export.cannot_sort:ATENÅ¢IE: export.pl nu poate sorta documentele atunci cÃ¢nd dimensiunea grupului este mai micÄ decÃ¢t 1. OpÅ£iunea sortmeta va fi ignoratÄ.  
+
+export.collectdir:Calea directorului de âcolectareâ.  
+
+export.complete:Export complet  
+
+export.debug:PrinteazÄ textul exportat cÄtre STDOUT (pentru exportul GA)  
+
+export.desc:Scripturile PERL utilizate pentru a exporta fiÅierele Ã®ntr-o colecÅ£ie Greenstone cÄtre alt format.  
+
+export.faillog:Numele jurnalului conÅ£inÃ¢nd nereuÅitele (fail log). Acest jurnal include numele tuturor fiÅierelor care nu pot fi procesate. (Implicit se gÄseÅte la: collectdir/collname/etc/fail.log)  
+
+export.groupsize:NumÄrul documentelor grupate Ã®ntr-un fiÅier XML.  
+
+export.gzip:FoloseÅte gzip pentru a comprima documentele xml rezultate (nu uitaÅ£i includerea  extensiei ZIPPlug Ã®n lista extensiilor atunci cÃ¢nd se face construcÅ£ia din documente comprimate deja).  
+
+export.importdir:Unde este materialul original.  
+
+export.keepold:Aceasta nu va distruge conÅ£inutul curent al directorului de export.  
+
+export.maxdocs:NumÄrul maxim de documente pentru export.  
+
+export.listall:Lista tuturor formatelor Ã®n care se poate salva (saveas)  
+
+export.saveas:Formatare pentru a exporta documentele.  
+
+export.saveas.DSpace:Formatul de arhivÄ DSpace.  
+
+
+
+
+
+
+export.saveas.MARCXML:Formatul MARC XML (este o versiune XML a formatului MARC21)  
+
+export.out:Numele fiÅierului sau instrument de a printa Åi starea rezultatelor.  
+
+export.params:[options] numele-colecÅ£iei1, numele-colecÅ£iei2...  
+
+export.removeold:Va elimina conÅ£inutul vechi al directorului de export.  
+
+export.removing_export:Eliminarea conÅ£inutului curent al directorului de export...  
+
+export.sortmeta:SorteazÄ documentele alfabetic prin intermediul metadatelor de construcÅ£ie. AceastÄ opÅ£iune va fi dezactivatÄ dacÄ dimensiunea grupului este mai mica decÃ¢t 1.  
+
+export.statsfile:Numele fiÅierului sau instrumentul de printare a statisticilor de export.  
+
+export.stats_backup:Ãn loc, va printa starea cÄtre STDERR.  
+
+export.verbosity:ControleazÄ calitatea rezultatelor. 0=lipsÄ, 3=mai multe.  
+
+
+
+# -- mkcol.pl --
+
+mkcol.about:Textul descriptiv pentru colecÅ£ie.  
+
+mkcol.bad_name_cvs:EROARE: Nicio colecÅ£ie nu poate fi numitÄ CVS deoarece acest lucru ar putea influienÅ£a negativ directoarele create de sistemul de versionare CVS.  
+
+
+
+mkcol.bad_name_modelcol:EROARE: Nicio colecÅ£ie nu poate fi denumitÄ modelcol deoarece acesta este numele colecÅ£iei model.  
+
+mkcol.cannot_find_modelcol:EROARE: Nu pot gÄsi colecÅ£ia model %s  
+
+mkcol.col_already_exists:EROARE: AceastÄ colecÅ£ie existÄ deja.  
+
+mkcol.collectdir:Directorul unde va fi creatÄ noua colecÅ£ie.  
+
+mkcol.creating_col:Crearea colecÅ£iei %s  
+
+mkcol.creator:Adresa de email a creatorului colecÅ£iei.  
+
+mkcol.creator_undefined:EROARE: Creatorul nu a fost definit. AceastÄ variabilÄ este necesarÄ pentru a recunoaÅte numele duplicate ale diferitelor colecÅ£ii.  
+
+mkcol.desc:Script Perl folosit pentru a fi creatÄ structura de directoare pentru o nouÄ colecÅ£ie Greenstone.  
+
+mkcol.doing_replacements:se fac Ã®nlocuirile pentru %s  
+
+
+
+
+
+mkcol.long_colname:EROARE: Numele colecÅ£iei trebuie sÄ fie mai puÅ£in de 8 caractere pentru a fi pÄstratÄ compatibilitatea cu sistemele de fiÅiere folosite Ã®n trecut.  
+
+mkcol.maintainer:Adresa de email a curatorului colecÅ£iei (dacÄ diferÄ de cea a creatorului).  
+
+mkcol.no_collectdir:EROARE: Directorul colecÅ£iei nu existÄ: %s  
+
+
+
+mkcol.no_colname:EROARE: Nu a fost specificat numele colecÅ£iei.  
+
+mkcol.optionfile:ObÅ£ineÅ£i opÅ£iunile din fiÅier. Este util pentru sistemele unde liniile de comandÄ lungi pot cauza probleme.  
+
+mkcol.params:numele colecÅ£iei [options]  
+
+mkcol.plugin:Modul Perl folosit pentru extensie (aici pot fi mai multe intrÄri reprezentÃ¢nd mai multe extensii).  
+
+mkcol.public:DacÄ aceastÄ colecÅ£ie are permis acces anonim.  
+mkcol.public.true:ColecÅ£ia este publicÄ  
+mkcol.public.false:Este o colecÅ£ie privatÄ  
+
+mkcol.quiet:OperaÅ£iuni Ã®n liniÅte.  
+
+
+
+mkcol.success:Noua colecÅ£ie a fost creatÄ cu succes la %s  
+
+mkcol.title:Titlul colecÅ£iei.  
+
+mkcol.win31compat:Fie cÄ numele directorului colecÅ£iei trebuie sÄ fie conform convenÅ£iilor Windows 3.1 sau nu (de exemplu cu o lungime de 8 caractere).  
+mkcol.win31compat.true:Numele directorului are 8 caractere sau mai puÅ£ine  
+mkcol.win31compat.false:Numele directorului, orice lungime  
+
+# -- pluginfo.pl --
+
+pluginfo.collection:Stabilind numele unei colecÅ£ii va avea ca efect acÅ£iunea lui pluginfo.pl, care se va uita mai Ã®ntÃ¢i Ã®n collect/collection-name/perllib/plugins. DacÄ extensia nu este gÄsitÄ aici atunci se va uita Ã®n directorul general: perllib/plugins.  
+
+pluginfo.desc:PrinteazÄ informaÅ£ii despre o extensie.  
+
+pluginfo.general_options:OpÅ£iunile Generale sunt moÅtenite din clasele pÄrinte ale extensiei.  
+
+pluginfo.info:informaÅ£ii  
+
+pluginfo.no_plugin_name:EROARE: Trebuie introdus numele pentru extensie.  
+
+pluginfo.option_types:Extensiile pot avea douÄ tipuri de opÅ£iuni  
+
+pluginfo.params:[options] numele extensiei  
+
+pluginfo.passing_options:OpÅ£iunile vor fi pasate oricÄrei extensii prin includerea acestora Ã®n fiÅierul de configurare collect.cfg.  
+
+pluginfo.specific_options:OpÅ£iuni specifice sunt definite Ã®n cadrul extensiei Ã®n sine Åi sunt disponibile doar pentru aceastÄ anume extensie.  
+
+
+# -- plugoutinfo.pl --
+
+plugoutinfo.collection:DÃ¢nd numele unei colecÅ£ii va determina ca plugoutinfo.pl sÄ se uite mai Ã®ntÃ¢i Ã®n collect/collection-name/perllib/plugouts. DacÄ extensia externÄ nu este gÄsitÄ aici acesta va cÄuta Ã®n directorul perllib/plugouts.  
+
+plugoutinfo.desc:PrinteazÄ informaÅ£ii despre o extensie externÄ  
+
+plugoutinfo.general_options:OpÅ£iunile generale sunt moÅtenite din clasele pÄrinÅ£i ale plugout.  
+
+plugoutinfo.info:informaÅ£ii  
+
+plugoutinfo.no_plugout_name:EROARE: Trebuie furnizat numele unui plugout.  
+
+plugoutinfo.option_types:Plugouts pot avea douÄ tipuri de opÅ£iuni  
+
+plugoutinfo.params:[options] nume plugout  
+
+plugoutinfo.passing_options:OpÅ£iunile pot fi pasate oricÄrei extensii externe prin includerea acestora Ã®n fiÅierul de configurare collect.cfg.  
+
+plugoutinfo.specific_options:OpÅ£iuni specifice sunt definite Ã®n interiorul lui plugout Åi sunt disponibile doar acestui anume plugout.  
+
+
+
+#
+# Classifier option descriptions
+#
+
+AllList.desc:CreeazÄ o listÄ unicÄ a tuturor documentelor. Este utilizatÄ de oaiserver.  
+
+AZCompactList.allvalues:UtilizeazÄ toate valorile de metadate gÄsite.  
+
+AZCompactList.desc:Extensia Classifier pentru sortarea alfabeticÄ (on a-zA-Z0-9). Produce o listÄ orizontalÄ de la A la Z Åi apoi o listÄ verticalÄ conÅ£inÃ¢nd documente, sau âpoliÅ£eâ pentru documente care au aceleaÅi metadate.  
+
+AZCompactList.doclevel:Nivelul de procesare al documentului.  
+AZCompactList.doclevel.top:Ãntregul document.  
+AZCompactList.doclevel.section:DupÄ secÅ£iuni.  
+
+AZCompactList.firstvalueonly:UtilizaÅ£i doar prima valoarea de metadate gÄsitÄ.  
+
+AZCompactList.freqsort:SortaÅ£i dupÄ frecvenÅ£a nodurilor mai degrabÄ decÃ¢t alfa-numeric.  
+
+AZCompactList.maxcompact:NumÄrul maxim de documente pentru a fi afiÅate pe paginÄ.  
+
+AZCompactList.metadata:Un singur cÃ¢mp de metadate sau o listÄ de cÃ¢mpuri de metadate separate prin virgulÄ folosite pentru clasificare. DacÄ este specificatÄ o listÄ, atunci va fi folosit primul tip de metadate care are valori. Poate fi folosit conjugat cu marcatorii -firstvalueonly Åi -allvalues pentru a selecta doar prima valoare sau toate valorile de metadate din listÄ.  
+
+AZCompactList.mincompact:NumÄrul minim de documente care sÄ fie afiÅate pe paginÄ.  
+
+AZCompactList.mingroup:NumÄrul cel mai mic de valori care va cauza formarea unui grup Ã®n cadrul ierarhiei.  
+
+AZCompactList.minnesting:Ce mai micÄ valoare care va cauza ca o listÄ sÄ fie convertitÄ Ã®ntr-o listÄ imbricatÄ.  
+
+AZCompactList.recopt:Utilizat Ã®n metadate imbricate precum -metadata An/OrganizaÅ£ie.  
+AZCompactList.sort:CÃ¢mp de Metadate pentru sortarea dupÄ nodurile descendenÅ£i.  
+
+AZCompactSectionList.desc:VariaÅ£ie asupra AZCompactList, care clasificÄ secÅ£iunile mai degrabÄ decÃ¢t documentele. IntrÄrile sunt sortate de metadate la nivel de secÅ£iune.  
+
+AZList.desc:Extensie pentru clasificare care sorteazÄ alfabetic ( de la a-z, A-Z Åi 0-9). Este produsÄ o listÄ orizontalÄ de la A la Z avÃ¢nd documentele listate dedesubt.  
+
+AZList.metadata:Pentru clasificare este utilizat in singur cÃ¢mp de metadate sau o listÄ separatÄ prin virgule de cÃ¢mpuri de metadate. UrmÃ¢nd ordinea indicatÄ de listÄ, primul cÃ¢mp care conÅ£ine o valoare de Metadate va fi folosit. Lista va fi sortatÄ dupÄ acest element.  
+
+AZSectionList.desc:VariaÅ£ia pe lista de la A la Z, care mai degrabÄ clasificÄ secÅ£iunile decÃ¢t documentele. IntrÄrile sunt sortate dupÄ metadatele de la nivelul fiecÄrei secÅ£iuni.  
+
+BasClas.bad_general_option:Clasificatorul %s foloseÅte o opÅ£iune eronatÄ. VerificaÅ£i fiÅierul de configurare collect.cfg.  
+
+BasClas.builddir:Unde sunt puse indexurile construite.  
+
+BasClas.buttonname:Eticheta pentru ecranul clasificatorului Åi butonul din bara de navigare. Implicit este specificat elementul de metadate prin -metadata.  
+
+BasClas.desc:Clasa de bazÄ pentru toÅ£i clasificatorii.  
+
+BasClas.no_metadata_formatting:Nu efectuaÅ£i nicio formatare automatÄ a metadatelor (Ã®n vederea sortÄrii.)  
+
+BasClas.outhandle:Mijlocul (file handle) prin care se scriu rezultatele Ã®ntr-un fiÅier.  
+
+BasClas.removeprefix:Un prefix pentru a ignora valorile de metadate la momentul sortÄrii.  
+
+BasClas.removesuffix:Un sufix pentru a ignora valorile din metadate la momentul sortÄrii.  
+
+BasClas.verbosity:ControleazÄ calitatea rezultatelor. 0=lipsÄ, 3=mai multe.
+
+Browse.desc:Un clasificator fals care furnizeazÄ un link Ã®n bara de navigare pentru un model prototip de navigare combinatÄ. Este activ doar pentru colecÅ£iile mgpp Åi este practic  pentru colecÅ£ii de dimensiune micÄ.  
+
+DateList.bymonth:ClasificÄ dupÄ an Åi lunÄ Ã®n loc de a folosi doar anul.  
+
+DateList.desc:Extensia Clasificator pentru sortarea dupÄ datÄ. Implicit se poate face sortare dupÄ metadatelel 'DatÄ'. Se presupune cÄ datele (cronologic) sunt de forma aaaalllzz sau aaaa-ll-zz.  
+
+DateList.metadata:Metadatele care conÅ£in datele dupÄ care sÄ se facÄ clasificarea. Se aÅteaptÄ ca formatul sÄ fie yyyymmdd sau yyyy-mm-dd. Poate sÄ fie o listÄ separatÄ prin virgule, caz Ã®n care prima datÄ care va fi gÄsitÄ va fi utilizatÄ.  
+
+DateList.reverse_sort:Sortarea documentelor Ã®n ordine cronologicÄ inversÄ (cel mai nou primul).  
+
+DateList.nogroup:FaceÅ£i din fiecare an o intrare individualÄ Ã®n lista orizontalÄ Ã®n loc de a destinde anii cu cÃ¢teva intrÄri. (Acest lucru poate fi fÄcut Åi cu opÅ£iunea -bymonth pentru a face fiecare lunÄ o intrare separatÄ Ã®n locul fuzionÄrilor).  
+
+DateList.no_special_formatting:Nu afiÅaÅ£i informaÅ£ii An Åi LunÄ Ã®n lista documentelor.  
+
+DateList.sort:Un cÃ¢mp de metadate Ã®n plus pentru sortare Ã®n cazul Ã®n care sunt douÄ documente care au aceeaÅi datÄ.  
+
+List.always_bookshelf_last_level:CreaÅ£i o pictogramÄ tip raft de cÄrÅ£i chiar dacÄ existÄ doar un singur element Ã®n fiecare grup Ã®n nodurile descendente.  
+
+List.classify_sections:ClasificÄ secÅ£iuni Ã®n loc de documente.  
+
+List.desc:Un clasificator de listÄ general Åi flexibil care are cele mai multe caracteristici ale AZCompactList, dar care face dovada utilizÄrii unor mai bune metadate, Unicode Åi capacitÄÅ£i de sortare.  
+
+List.metadata:CÃ¢mpurile de metadate utilizate pentru clasificare. UtilizaÅ£i '/' pentru a separa nivelurile Ã®n cadrul ierarhiei Åi ';' pentru a separa cÃ¢mpurile de metadate Ã®n cadrul fiecÄrui nivel.  
+
+List.partition_name_length:Lungimea numelui partiÅ£iei; setÄrile implicite variazÄ Ã®ntre 1 Åi 3 caractere depinzÃ¢nd de cÃ¢te sunt necesare pentru a distinge startul partiÅ£iei de finalul sÄu. AceastÄ opÅ£iune se aplicÄ atunci cÃ¢nd partition_type_within_level este setat cu 'constant_size'.  
+
+List.partition_size_within_level:NumÄrul de elemente din fiecare partiÅ£ie (se aplicÄ doar cÃ¢nd partition_type_within_level este setat la 'constant_size').  
+
+List.partition_type_within_level:Tipul partiÅ£iei fÄcute: fie 'per_letter', 'constant_size', sau 'none'.  
+
+List.sort_leaf_nodes_using:CÃ¢mpurile de metadate folosite pentru sortarea nodurilor. FolosiÅ£i '|' pentru a separa  grupurile de metadate Åi ';' pentru a separa cÃ¢mpurile de metadate din cadrul fiecÄrui grup.  
+
+List.use_hlist_for:CÃ¢mpuri de metadate folosite mai mult la un hlist decÃ¢t la un vlist. FoloseÅte â,â pentru a separa grupurile de metadate Åi â;â pentru a separa cÃ¢mpurile de metadate din fiecare dintre grupuri.  
+
+HFileHierarchy.desc:Extensie Classifier pentru generarea clasificÄrii ierarhice bazate pe o structurÄ de fiÅiere suplimentarÄ.  
+
+Hierarchy.desc:Extensia Clasificator pentru generarea unei clasificÄri ierarhice. Acesta poate sÄ se bazeze pe metadate structurate sau poate folosi o structurÄ de fiÅiere suplimentarÄ (folosirea opÅ£iunii -hfile).  
+
+Hierarchy.documents_last:AfiÅarea nodurilor documentului dupÄ nodurile clasificatorului.  
+
+Hierarchy.hfile:UtilizaÅ£i fiÅierul de clasificare a structurii.  
+
+Hierarchy.hlist_at_top:AfiÅaÅ£i orizontal primul nivel al clasificÄrii.  
+
+Hierarchy.reverse_sort:Sortarea nodurilor descendenÅ£i Ã®n ordine inversÄ (utilizat cu -sort).  
+
+Hierarchy.separator:Expresie regulatÄ folositÄ ca separator Ã®n cazul utilizÄrii metadatelor structurate.  
+
+Hierarchy.sort:CÃ®mpurile de metadate pentru a sorta nodurile descendenÅ£i. DescendenÅ£ii nu vor fi sortaÅ£i dacÄ nu au fost specificaÅ£i.  
+
+Hierarchy.suppressfirstlevel:IgnoraÅ£i prima parte a valorii metadatelor. Acest lucru este util pentru metadate acolo unde primul element este comun, este Åi cazul directorului de import din gsdlsourcefilename.  
+
+Hierarchy.suppresslastlevel:Trebuie ignoratÄ partea finalÄ a valorii de metadate. Acest lucru este necesar pentru metadate, unde fiecare dintre valori sunt unice aÅa cum sunt Åi cÄile fiÅierului.  
+
+HTML.desc:CreazÄ o clasificare goalÄ, care este o simplÄ legÄturÄ cÄtre o paginÄ web.  
+
+HTML.url:Url-ul paginii web la care se face trimiterea.  
+
+SimpleList.desc:O extensie pentru un clasificator simplu de listÄ.  
+
+SimpleList.metadata:Un singur cÃ¢mp de metadate sau o listÄ separatÄ prin virgule a cÃ¢mpurilor de metadate folosite pentru clasificare. UrmÄrind ordinea indicatÄ prin listÄ, va fi folosit primul cÃ¢mp care conÅ£ine o valoare de metadate. Lista va fi sortatÄ dupÄ acest element numai dacÄ nu este folosit -sort. DacÄ nu este specificatÄ nicio metadatÄ, atunci toate documentele vor fi incluse Ã®n listÄ, altfel doar documentele care conÅ£in o valoare a metadatelor va fi inclusÄ.  
+
+SimpleList.sort:CÃ¢mpuri de metadate dupÄ care se poate face sortarea. FolosiÅ£i â-sort nosortâ pentru a preciza nesortarea.  
+
+Phind.desc:Produce o ierarhie a frazelor gÄsite Ã®n text, care este navigabilÄ prin intermediul unui applet.  
+
+Phind.language:Limba sau limbile folosite pentru a construi o ierarhie. Limbile sunt identificate printr-un cod format din douÄ litere pentru fiecare Å£arÄ, precum en pentru englezÄ, es pentru spaniolÄ, etc. Limba este o expresie regulatÄ precum Ã®n 'en|fr' (englezÄ sau francezÄ) and '..' (potriveÅte cu oricare limbÄ).  
+
+Phind.min_occurs:NumÄrul minim de apariÅ£ii al unei fraze Ã®n text pentru a fi inclusÄ Ã®n ierarhia frazeologicÄ.  
+
+Phind.savephrases:DacÄ este setat, informaÅ£ia despre frazÄ va fi stocatÄ Ã®n fiÅierul dat ca Åi text. Poate cÄ este o idee bunÄ utilizarea unei cÄi absolute.  
+
+Phind.suffixmode:Parametrul smode al programului de extragere a frazelor. O valoare 0 Ã®nseamnÄ cÄ toate cuvintele semnal (stopwords) vor fi ignorate iar valoarea 1 va indica folosirea tuturor acestora.  
+
+Phind.text:Textul utilizat pentru construcÅ£ia ierarhiei frazei.  
+
+Phind.thesaurus:Numele tezaurului stocat Ã®n format Phind Ã®n directorul etc al colecÅ£iei.  
+
+Phind.title:CÃ¢mpul de metadate folosit pentru a descrie fiecare document.  
+
+Phind.untidy:Nu eliminaÅ£i fiÅierele de lucru.  
+
+RecentDocumentsList.desc:Clasificator care dÄ o listÄ de documente nou adÄugate sau modificate.  
+
+RecentDocumentsList.include_docs_added_since:Include doar documentele modificare sau adÄugate dupÄ data specificatÄ (Ã®n format yyyymmdd sau Ã®n format yyyy-mm-dd).  
+
+RecentDocumentsList.include_most_recently_added:IncludeÅ£i doar numÄrul specificat a celor mai recent adÄugate documente. Este utilizat dacÄ nu este specificat include_docs_added_since.  
+
+RecentDocumentsList.sort:Metadate pentru sortarea Listei. DacÄ nu sunt specificate, lista va fi sortatÄ dupÄ data modificÄrii/adÄugÄrii.  
+
+SectionList.desc:La fel precum Clasificatorul de ListÄ doar cÄ include toate secÅ£iunile unui document (excluzÃ¢nd nivelul vÃ¢rfului) mai mult decÃ¢t doar nivelul superior al documentului Ã®n sine.  
+
+Collage.desc:Un applet este utilizat pentru a afiÅa un colaj de imagini gÄsite Ã®n colecÅ£ie.  
+
+Collage.geometry:Dimensiunile spaÅ£iului pentru Colaj. Pentru un spaÅ£iu de 600 de pixeli lungime pe 400 de pixeli Ã®nÄlÅ£ime, de exemplu, se specificÄ o geometrie de 600x400  
+
+Collage.maxDepth:Imaginile care intrÄ Ã®n colaje sunt extrase prin oglindirea clasificatorului de navigare de substrat. Acest lucru controleazÄ adÃ¢ncimea maximÄ al procesului de oglindire (mirroring).  
+
+Collage.maxDisplay:NumÄrul maxim de imagini pentru a fi afiÅate Ã®n colaj Ã®n orice moment.  
+
+Collage.imageType:Utilizat pentru controlul cÄror tipuri de fiÅiere sunt utilizate Ã®n colaj, prin exprimarea numelor extensiilor. O listÄ de nume de fiÅiere ale extensiilor este separatÄ prin simbolul (%%).  
+
+Collage.bgcolor:Culoarea de fond specificatÄ Ã®n formÄ hexazecimalÄ (de exemplu #008000 are ca efect o culoare verde frumoasÄ precum a pÄdurii).  
+
+Collage.buttonname:Eticheta pentru ecranul de clasificare Åi a butonului din bara de navigare.  
+
+Collage.refreshDelay:FrecvenÅ£a de reÃ®mprospÄtare a ecranului Ã®n milisecunde.  
+
+Collage.isJava2:Utilizat pentru a controla care dintre clasele run-time ale Java sunt utilizate. Versiuni mai complete de Java (de la Java 1.2 Ã®n sus) includ asistenÅ£Ä mai sofisticatÄ pentru a controla transparenÅ£a imaginilor, acest marcator ajutÄ la controlul a aceea ce se Ã®ntÃ¢mplÄ Åi oricum run-time-ul existent Ã®n anumite browsere este la versiunea 1.1. Appletul este proiectat din start pentru a autodetecta ce versiune de Java ruleazÄ Ã®n browser Åi pentru a se ajusta Ã®n acord.  
+
+Collage.imageMustNotHave:Utilizat pentru a elimina imaginile care nu ar trebui sÄ aparÄ Ã®n colaj, precum imaginile butoanelor care alcÄtuiesc bara de navigaÅ£ie.  
+
+Collage.caption:Etichete explicative opÅ£ionale pentru a fi afiÅate mai jos de spaÅ£iul colaÅ£iunii.  
+
+
+#
+# Plugin option descriptions
+#
+AcronymExtractor.adding:adÄugare  
+
+AcronymExtractor.already_seen:care a mai fost vÄzutÄ  
+
+
+
+AcronymExtractor.done_acronym_extract:am terminat de extras acronimele.  
+
+AcronymExtractor.done_acronym_markup:am fÄcut marcajul pentru acronime.  
+
+AcronymExtractor.extract_acronyms:Extrage acronimele din text Åi le transpune ca metadate.  
+
+AcronymExtractor.extracting_acronyms:extragerea acronimelor  
+
+AcronymExtractor.marking_up_acronyms:alcÄtuirea acronimelor  
+
+AcronymExtractor.markup_acronyms:AdÄugaÅ£i metadate pentru acronime Ã®n textul documentului.  
+
+ArchivesInfPlugin.desc:Extensie care parcurge o arhivÄ recursiv fiÅierul archives.inf (de exempolu, fiÅierul generat Ã®n directorul arhivei atunci cÃ¢nd a fost fÄcut un import), procesÃ¢nd fiecare fiÅier Ã®ntÃ¢lnit.  
+
+
+
+AutoExtractMetadata.extracting:extragere  
+
+AutoExtractMetadata.first:O listÄ separatÄ prin virgule a primelor dimensiuni pentru extragerea lor din text Ã®ntr-un cÃ¢mp de metadate. CÃ¢mpul de numeÅte 'FirstNNN'.  
+
+
+
+BasePlugin.associate_ext:Are ca efect ca fiÅierele care au aceeaÅi nume de fiÅier rÄdÄcinÄ ca Åi documentul Ã®n curs de procesare de cÄtre extensie Åi o numele unei extensii dintr-o listÄ separatÄ prin virgule furnizatÄ de acest argument, sÄ fie asociatÄ cu documentul Ã®n curs de procesare decÃ¢t mÃ¢nuirea lor ca o listÄ separatÄ.  
+
+
+
+BasePlugin.block_exp:FiÅierele care se potrivesc cu aceastÄ expresie regulatÄ vor fi blocate Ã®n a fi pasate oricÄror alte extensii succesive din listÄ. Acest lucru nu are un efect real altul decÃ¢t cel al prevenirii apariÅ£iei a unei mulÅ£imi de mesaje de avertizare privind fiÅierele intrate, care nu au relevanÅ£Ä pentru dumneavoastrÄ. Fiecare extensie poate avea un block_exp de start. De exemplu, din start HTMLPlug blocheazÄ orice fiÅier care are extensiile .gif, .jpg, .jpeg, .png sau .css.  
+
+BasePlugin.desc:Clasa de bazÄ pentru toate extensiile destinate importului.  
+
+BasePlugin.dummy_text:Acest document nu are text.  
+
+BasePlugin.encoding.ascii:ASCII pe 7 biÅ£i. Acesta poate fi ceva mai rapid decÃ¢t folosirea lui iso_8859_1. FiÅ£i atenÅ£i la folosirea acestuia asupra unei colecÅ£ii de documente care pot conÅ£ine caractere Ã®n afara setului pe 7 biÅ£i ASCII (de exemplu, documentele germane sau franceze conÅ£in accente). Ãn cazul existenÅ£ei unor astfel de documente, folosiÅ£i iso_8859_1.  
+
+BasePlugin.encoding.unicode:Doar unicode.
+
+BasePlugin.encoding.utf8:Fie utf8, fie unicode -- detectat automat.  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+BasePlugin.no_cover_image:Nu cÄutaÅ£i un fiÅier prefix.jpg (acolo unde prefixul este acelaÅi prefix ca fiÅierul care este procesat) Åi asociaÅ£i-l ca imagine a coperÅ£ii.  
+
+
+
+BasePlugin.process_exp:O expresie regulatÄ perl care se potriveÅte cu numele fiÅierelor. FiÅierele care se potrivesc vor fi procesate de cÄtre acest plugin. De exemplu, folosirea  lui '(?i).html?\$' potriveÅte toate documentele care se terminÄ cu .htm sau .html (sunt case-insensitive).  
+
+BasePlugin.smart_block:BlocheazÄ fiÅierele Ã®ntr-un mod mai inteligent decÃ¢t dupÄ numele fiÅierelor.  
+
+BasePlugin.stems:rÄdÄcini  
+
+
+
+
+
+
+
+
+
+BibTexPlugin.desc:BibTexPlug citeÅte fiÅierele bibliografice Ã®n format BibTex. BibTexPlug creazÄ un document obiect pentru fiecare referinÅÄ din fiÅier. Acesta este o subclasÄ a lui SplitPlug, astfel cÄ, Ã®n cazul existenÅ£ei a mai multor Ã®nregistrÄri, toate acestea sunt citite.  
+
+BookPlugin.desc:CreazÄ un document multi-nivel din elementele de nivel <<TOC>>. Metadatele pentru fiecare secÅ£iune sunt recoltate din oricare alte taguri aflate pe acelaÅi nivel cu <<TOC>>; de exemplu, <<Title>>xxxx<</Title>> furnizeazÄ metadatele pentru Titlu. orice altceva Ã®ntre tagurile TOC este creat ca Åi cod html simplu (adicÄ nu sunt procesate linkurile html sau orice alt material caracteristic pentru HTMLPlug). Se aÅteaptÄ ca fiÅierele de intrare sÄ aibe extensia .hb din start (acest lucru poate fi modificat prin adÄugarea unei opÅ£iuni -process_exp unui fiÅier care are are acelaÅi nume ca fiÅierul hb iar o extensie .jpg este preluatÄ ca fiind imaginea coperÅ£ii (fiÅierele jpg sunt blocate de acest plugin). BookPlug reprezintÄ o simplificare (Åi extensie) a HBPlug utilizat de colecÅ£iile Humanity Library. BookPlug este mai rapid Åi aÅteaptÄ ca fiÅierele de intrare sÄ fie mai curate (IntrÄrile Ã®n colecÅ£iile HDL conÅ£in o mulÅ£ime de taguri html Ã®n jurul tagurilor <<TOC>>, foloseÅte tagurile <<I>> pentru a specifica imaginile Åi pentru a lua pur Åi simplu tot textul dintre tagurile  <<TOC>> iar debutul textului sÄ fie metadatele Titlu). DacÄ se marcheazÄ documentele care trebuie afiÅate Ã®n aceeaÅi manierÄ precum colecÅ£iile HDL, utilizaÅ£i extensia Ã®n locul lui HBPlug.  
+
+
+
+ConvertBinaryFile.apply_fribidi:RulaÅ£i Algoritmul Unicode BidirecÅ£ional âfribidiâ peste fiÅierul convertit (pentru textul de la dreapta la stÃ¢nga).  
+
+ConvertBinaryFile.convert_to:Extensia converteÅte Ã®n TEXT sau HTML sau diversele tipuri de imagini (de exemplu JPEG, GIF, PNG).  
+
+ConvertBinaryFile.convert_to.auto:Selectarea automatÄ a formatului acoperit. Alegerea formatului depinde de tipul documentului introdus, de exemplu Word va fi convertit automat la HTML, iar PowerPoint va fi convertit Ã®n formatul Greenstone PagedImage.  
+
+ConvertBinaryFile.convert_to.html:Format HTML.  
+
+ConvertBinaryFile.convert_to.text:Formatul de text plat.  
+
+
+
+ConvertBinaryFile.convert_to.pagedimg_jpg:Format JPEG.  
+
+ConvertBinaryFile.convert_to.pagedimg_gif:Formatul GIF.  
+
+ConvertBinaryFile.convert_to.pagedimg_png:formatul PNG.  
+
+ConvertBinaryFile.desc:AceastÄ extensie este moÅtenitÄ de alte extensii precum WordPlug, PPTPlug, PSPlug, RTFPlug Åi PDFPlug. Are rolul de a facilita conversia acestor tipuri de documente fie Ã®n HTML sau TEXT sau o serie de imagini. Modul de lucru este prin Ã®ncÄrcarea dinamicÄ a unei extensii secundare corespunzÄtoare (HTMLPlug, StructuredHTMLPlug, PagedImgPlug sau TEXTPlug) bazate pe argumentul extensiei 'convert_to'.  
+
+ConvertBinaryFile.keep_original_filename:DecÃ¢t sÄ convertiÅ£i Ã®n formatul doc.pdf, doc.doc, mai bine Å£ineÅ£i numele fiÅierului original pentru fiÅierele asociate.  
+
+ConvertBinaryFile.use_strings:DacÄ este setat, va fi apelatÄ o funcÅ£ie pentru stringuri simple pentru a extrage text dacÄ utilitarul de conversie eÅueazÄ Ã®n aceastÄ operaÅ£iune.  
+
+ConvertToRogPlugin.desc:O extensie care moÅteneÅte din RogPlug.  
+
+CSVPlugin.desc:O extensie pentru fiÅierele Ã®n format csv - comma-separated value. Va fi creat un nou document pentru fiecare linie a fiÅierului.  
+
+
+
+DateExtractor.extract_historical_years:Extrage informaÅ£ii privind perioade de timp din documentele istorice. Acestea sunt stocate ca metadate Ã®n cadrul documentului. ExistÄ o interfaÅ£Ä de cÄutare pentru aceste metadate, care poate fi inclusÄ Ã®n colecÅ£ia proprie prin adÄugarea enunÅ£ului âformat QueryInterface DateSearchâ Ã®n fiÅierul de configurare al colecÅ£iei.  
+
+DateExtractor.maximum_century:Numele maxim al secolului care poate fi extras ca metadate istorice (de exemplu 14 are ca rezultat extragerea tuturor referinÅ£elor pÃ¢nÄ Ã®n secolul al paisprezecelea).  
+
+DateExtractor.maximum_year:Data istoricÄ maximÄ pentru a fi folositÄ ca metadate (precum Era noastrÄ - 1950).  
+
+DateExtractor.no_bibliography:Nu Ã®ncercaÅ£i sÄ blocaÅ£i datele din Ã®nregistrÄrile bibliografice atunci cÃ¢nd extrageÅ£i date istorice.  
+
+DirectoryPlugin.desc:Extensia RecPlug este un plugin care are un comportament recursiv printre directoare procesÃ¢nd fiecare fiÅier Ã®ntÃ¢lnit.  
+
+DirectoryPlugin.recheck_directories:DupÄ ce au fost procesate fiÅierele dintr-un director de import, se va reciti directorul pentru a se decoperi oricare alte fiÅiere noi create.  
+
+DirectoryPlugin.use_metadata_files:(DEPÄÅIT - Ãn schimb, adaugÄ MetadataXMLPlug la lista de extensii) CiteÅte metadatele din fiÅiere XML.  
+
+DatabasePlugin.desc:O extensie care importÄ Ã®nregistrÄri dintr-o bazÄ de date. Acesta utilizeazÄ modulul perl DBI, care include back-ends pentru mysql, postgresql, valori separate prin virgulÄ (CVS), MS Excel, ODBC, sybase, etc... Modulele suplimentare pot sÄ aibe nevoie de instalare pentru a-l utiliza acesta. Vezi Åi <GSDLHOME>/etc/packages/example.dbi pentru exemplul de fiÅier de configurare.  
+
+DSpacePlugin.desc:DSpacePlug ia o colecÅ£ie de documente exportate din DSpace Åi o importÄ Ã®n Greenstone.  
+	
+DSpacePlugin.first_inorder_ext:Este folosit pentru a identifica streamul primar al uni document aparÅ£inÃ¢nd unei colecÅ£ii DSpace. Cu aceastÄ opÅ£iune, sistemul va trata tipurile ext definite secvenÅ£ial pentru a cÄuta posibilul stream primar.  
+
+DSpacePlugin.first_inorder_mime:Sunt folosite pentru a identifica streamul de date primar al unui document al unei colecÅ£ii DSpace. Cu aceastÄ opÅ£iune, sistemul va trata tipurile de fiÅiere definite secvenÅ£ial pentru a identifica posibilul stream primar.  
+
+DSpacePlugin.only_first_doc:Aceasta este utilizatÄ pentru a identifica fluxul primar de date al documentului reprezentÃ¢nd o colecÅ£ie DSpace. AvÃ¢nd aceastÄ opÅ£iune, sistemul va trata primul document din fiÅierul de metadate dublin_core ca fiind primul flux primar posibil.  
+
+
+
+EmailAddressExtractor.done_email_extract:s-a Ã®ncheiat extragerea adreselor de email.  
+
+EmailAddressExtractor.extracting_emails:extrag adresele de email  
+
+EmailAddressExtractor.extract_email:Extragerea adreselor de email ca metadate.  
+
+EmailPlugin.desc:Extensia pentru emailuri. Emailurile sunt numite cu un simplu numÄr (aÅa cum apar ele Ã®n directoarele de mailing) sau cu extensia .mbx (de la mbox mail file format).\nTextul documentului: textul documentului constÄ din tot textul de dupÄ prima linie goalÄ din document.\nMetadatele (nu Åi Dublin Core!):\n\t\$Headere      Tot conÅ£inutul headerului (opÅ£ional, nu este stocat implicit)\n\t\$Subject      Subject: header\n\t\$To           To: header\n\t\$From         From: header\n\t\$FromName
+
+EmailPlugin.no_attachments:Nu salva ataÅamentele mesajelor.  
+
+EmailPlugin.headers:StocaÅ£i headere email ca metadate "Headers".  
+
+
+
+EmailPlugin.split_exp:O expresie regulatÄ utilizatÄ pentru a desface fiÅierele care conÅ£in multe mesaje Ã®n documentele individuale.  
+
+ExcelPlugin.desc:O extensie pentru importul fiÅierelor MS Excel (versiunile 95 Åi 97).  
+
+
+
+FOXPlugin.desc:Extensie pentru procesarea fiÅierelor dbt Foxbase. AceastÄ extensie furnizeazÄ funcÅ£ionalitÄÅ£i de bazÄ pentru a citi fiÅierele dbt Åi dbf Åi pentru a procesa fiecare Ã®nregistrare. AceastÄ extensie generalÄ ar trebui suprascrisÄ pentru o anume bazÄ de date pentru a procesa cÃ¢mpurile corespunzÄtoare din fiÅier.  
+
+GreenstoneXMLPlugin.desc:ProceseazÄ documente de arhivÄ XML ale Greenstone. Trebuie notat cÄ aceastÄ extensie nu face nicio verificare a sintaxei (prin intermediul modulului XML::Parser, modulul testeazÄ conformitatea). Se presupune cÄ fiÅierele de arhivÄ Greenstone sunt conforme cu DTD-ul aferent.  
+
+GISExtractor.desc:Clasa de bazÄ on-the-side al lui BasPlug care suportÄ capabilitÄÅ£i GIS  
+
+GISExtractor.extract_placenames:Extrage toponimele din text Åi le va seta ca metadate. NecesitÄ preinstalarea extensiei GIS pentru Greenstone.  
+
+GISExtractor.gazetteer:Gazetteer folosit pentru a extrage toponime din text Åi pentru a le seta ca metadate. NecesitÄ extensia GIS Ã®n Greenstone.  
+
+GISExtractor.place_list:La momentul extragerii amplasamentelor sunt incluse o lustÄ de toponime la Ã®nceputul documentului. NecesitÄ instalarea Ã®n prealabil al extensiei GIS pentru Greenstone.  
+
+HBPlugin.desc:O extensie care proceseazÄ directorul unei cÄrÅ£i Ã®n format HTML. AceastÄ extensie este folositÄ de colecÅ£iile Humanity Library Åi nu gestioneazÄ coduri de input altele decÃ¢t ascii sau ascii extins. Acest cod este cam âurÃ¢tâ Åi poate fi optimizat fÄrÄ discuÅ£ii. Doresc sÄ Ã®ncurajez oamenii sÄ-Åi construiascÄ colecÅ£iile mai bine cu extensia HBSPlug ;-)\n\nUtilizaÅ£i HBSPlug dacÄ construiÅ£i noi colecÅ£ii Åi alcÄtuiÅ£i fiÅiere precum cele ale colecÅ£iilor Humanity Library. HBSPlug acceptÄ toate codurile de input, dar are pretenÅ£ia ca marcajul HTML sÄ fie mai curat decÃ¢t cel folosit de colecÅ£iile Humanity Library  
+
+
+
+HTMLImagePlugin.aggressiveness:Gama tehnicilor de extragere a textului Ã®nrudit folosite.  
+HTMLImagePlugin.aggressiveness.1:Numele fiÅierului, cale Åi doar textul pentru ALT.  
+HTMLImagePlugin.aggressiveness.2:Toate cele 1 plus etichetele explicative acolo unde sunt disponibile.  
+HTMLImagePlugin.aggressiveness.3:Cele 2 plus paragrafele care urmeazÄ acolo unde sunt disponibile.  
+HTMLImagePlugin.aggressiveness.4:Toate cele 3 plus headerele anterioare (<h1>, <h2>...) acolo unde sunt disponibile.  
+HTMLImagePlugin.aggressiveness.5:Toate 4 plus referinÅ£ele textuale acolo unde acestea sunt disponibile.  
+HTMLImagePlugin.aggressiveness.6:Toate cele 4, plus metatagurile paginii (titlu, keywords, etc).  
+HTMLImagePlugin.aggressiveness.7:Toate cele 6, 5 Åi 4 combinate.  
+HTMLImagePlugin.aggressiveness.8:Toate cele 7 plus repetarea titlului (caption), numele fiÅierului, etc (ridicÄ ierarhic cele mai relevante rezultate).  
+HTMLImagePlugin.aggressiveness.9:Toate cele 1 plus textul integral al paginii sursÄ.  
+
+HTMLImagePlugin.caption_length:Dimensiunea maximÄ a etichetelor explicative (folosind caractere).  
+
+HTMLImagePlugin.convert_params:Parametri adiÅ£ionali pentru conversiunea ImageMagicK la momentul creÄrii imaginilor miniaturÄ (thumbnails). De exemplu, '-raise' va da un efect tridimensional imaginilor miniaturÄ.  
+
+HTMLImagePlugin.desc:O extensie pentru extragerea imaginilor Åi a textului asociat din paginile web.  
+
+HTMLImagePlugin.document_text:AdaugÄ text la imagine ca document:text (altfel, se foloseÅte cÃ¢mpul de metadate IndexedText).  
+
+HTMLImagePlugin.index_pages:IndexaÅ£i paginile Ã®mpreunÄ cu imaginile. Altfel, referenÅ£iaÅ£i paginile cÄtre sursa URL.  
+
+HTMLImagePlugin.max_near_text:NumÄrul maxim de caractere apropiat imaginilor pentru a fi extras.  
+
+HTMLImagePlugin.min_height:Pixeli. Sari peste imaginile mai mici de atÃ¢t.  
+
+HTMLImagePlugin.min_near_text:Minimul de caractere al textului din proximitate sau eticheta descriptivÄ pentru a fi extrasÄ.  
+
+HTMLImagePlugin.min_size:Bytes. Treci peste imaginile mai mici decÃ¢t atÃ¢t.  
+
+HTMLImagePlugin.min_width:Pixeli. TreceÅ£i peste imaginile mai mici de atÃ¢t.  
+
+HTMLImagePlugin.neartext_length:Lungimea Å£intei textlui adiacent (Ã®n caractere).  
+
+HTMLImagePlugin.no_cache_images:Nu prestocaÅ£i imagini (indicaÅ£i URL-ul originalului).  
+
+HTMLImagePlugin.smallpage_threshold:Imaginile din paginÄ mai mici decÃ¢t atÃ¢t (bytes) li se vor adÄuga metadatele (title, keywords, etc).  
+
+HTMLImagePlugin.textrefs_threshold:Pragul pentru referinÅ£ele textuale. Valorile mici Ã®nseamnÄ cÄ algoritmul este mai puÅ£in strict.  
+
+HTMLImagePlugin.thumb_size:Dimensiunea maximÄ a imaginii miniaturÄ (thumbnail). Se specificÄ lÄÅ£imea Åi Ã®nÄlÅ£imea deopotrivÄ.  
+
+HTMLPlugin.assoc_files:Expresii regulate Perl ale extensiilor fiÅierelor care pot fi asociate cu documentele html.  
+
+HTMLPlugin.desc:AceastÄ extensie proceseazÄ fiÅiere HTML  
+
+HTMLPlugin.description_tags:Sparge documentul Ã®n subsecÅ£iuni acolo unde apar tagurile <Section>. '-keep_head' nu va avea niciun efect atunci cÃ¢nd este setatÄ aceastÄ opÅ£iune.  
+
+HTMLPlugin.extract_style:ExtrageÅ£i  informaÅ£ii privind stilurile Åi scripturile din tagul <head> al codului HTML Åi salvaÅ£i-l ca metadate DocumentHeader. Acesta va fi setat Ã®n pagina documentului ca Åi _document:documentheader_ macro.  
+
+HTMLPlugin.file_is_url:Setat dacÄ fiÅierele intrate exhibÄ url-ul documentului sursÄ original, de exemplu dacÄ un instrument de mirroring a fost folosit pentru a crea structura de directorului de import.  
+
+HTMLPlugin.hunt_creator_metadata:CÄutaÅ£i cÃ¢t mai multe metadate posibile privind autorii Åi plasaÅ£ile Ã®n cÃ¢mpul 'Creator'.  
+
+HTMLPlugin.keep_head:Nu elimina headerele din fiÅierele html.  
+
+HTMLPlugin.metadata_fields:O listÄ de cÃ¢mpuri de metadate separatÄ prin virgule care se doreÅte a fi extrasÄ. UtilizaÅ£i 'tag<tagname>' pentru a avea conÅ£inutul primei perechi <tagname> pus Ã®ntr-un element de metadate numit 'tagname'. CapitalizaÅ£i aceasta dacÄ doriÅ£i metadatele sÄ fie capitalizate Ã®n Greenstone pentru cÄ oricum extragerea tagurilor nu este sensibilÄ la mÄrimea caracterului.  
+
+HTMLPlugin.no_metadata:Nu Ã®ncercaÅ£i sÄ extrageÅ£i nicio metadatÄ din fiÅiere.  
+
+HTMLPlugin.no_strip_metadata_html:ListÄ de nume de metadate separate sau 'toate'. UtilizatÄ cu -description_tags are ca efect prevenirea pierderii tagurilor HTML din valorile pentru metadatele specificate.  
+
+HTMLPlugin.nolinks:Nu Ã®ncercaÅ£i sÄ capturaÅ£i linkuri (setarea acestui marcator vÄ poate Ã®mbunÄtÄÅ£i viteza de construcÅ£ie/import, dar oricare linkuri relative din cadrul documentului vor fi pierdute).  
+
+
+
+HTMLPlugin.rename_assoc_files:RedenumeÅte fiÅierele asociate cu documente (de exemplu imaginile). De asemenea, creeazÄ o structurÄ de directoare mult mai joasÄ (util atunci cÃ¢nd sunt create colecÅ£iile care merg pe cd-rom).  
+
+HTMLPlugin.sectionalise_using_h_tags:CreaÅ£i automat un document alcÄtuit pe secÅ£iuni folosind tagurile h1, h2, ... hX.  
+
+HTMLPlugin.title_sub:Expresie de substituire pentru a modifica stringul stocat ca Titlu. Utilizat, de exemplu, pentru PDFPlug pentru a elimina "Page 1", etc din text Åi care este utilizat ca titlu.  
+
+HTMLPlugin.tidy_html:DacÄ este setat, converteÅte un document HTML Ã®ntr-un document XHTML bine format. Permite utilizatorilor sÄ vadÄ documentul Ã®n format carte.  
+
+HTMLPlugin.old_style_HDL:Pentru a marca dacÄ fiÅierul din aceastÄ colecÅ£ie este Ã®ncadrat unei secÅ£iuni utilizÃ¢nd vechiul stil de secÅ£iune HDL.  
+
+
+
+ImageConverter.converttotype:ConverteÅte imaginea principalÄ la formatul 's'.  
+
+
+
+
+ImageConverter.desc:AceastÄ extensie proceseazÄ imagini adÄugÃ¢nd metadate de bazÄ.  
+
+
+
+ImageConverter.minimumsize:IgnorÄ imaginile mai mici de n byte.  
+
+
+
+ImageConverter.noscaleup:Nu modificaÅ£i dimensiunea imaginilor de micÄ dimensiune atunci cÃ¢nd generaÅ£i imaginile miniaturÄ (thumbnails).  
+
+ImageConverter.screenviewsize:Se fac imagini pentru ecran de dimensiunea nxn.  
+
+ImageConverter.screenviewtype:FaceÅ£i capturi de ecran Ã®n format 's'.  
+
+ImageConverter.thumbnailsize:FaceÅ£i imagini miniaturÄ de dimensiunea nxn.  
+
+ImageConverter.thumbnailtype:Se fac miniaturile (thumbnails) Ã®n formatul 's'.  
+
+
+
+ImagePlugin.desc:AceastÄ extensie proceseazÄ imagini adÄugÃ¢nd metadate de bazÄ.  
+
+IndexPlugin.desc:AceastÄ extensie recursivÄ proceseazÄ un fiÅier index.txt. FiÅierul index.txt ar trebui sÄ conÅ£inÄ o listÄ de fiÅiere care sÄ fie incluse Ã®n colecÅ£ie urmate de metadate suplimentare care sÄ fie asociate cu fiecare fiÅier.\n\nFiÅierul index.txt ar trebui formatat dupÄ cum urmeazÄ: Prima linie ar trebui sÄ fie o cheie (porniÅ£i cu o cheie:) pentru a denumi cÃ¢mpurile de metadate (de exemplu, cheia: Subject Organization Date). UrmÄtoarele linii vor conÅ£ine un nume de fiÅier urmat de valoarea cu care trebuie sÄ fie setat elementul de metadate. (de exemplu, âirma/iw097e 3.2 unesco 1993â va asocia metadatele Subiect=3.2, OrganizaÅ£ie=unesco, Åi Data=1993 cu fiÅierul irma/iw097e dacÄ a fost utilizatÄ cheia de mai sus)\n\nTrebuie remarcat cÄ dacÄ oricare dintre cÃ¢mpurile de metadate utilizaeazÄ extensia de clasificator al Ierarhiei, atunci valoarea cu care sunt setate ar trebui sÄ corespundÄ cu primul cÃ¢mp (descriptorul) Ã®n fiÅierul de clasificare corespunzÄtor.\n\nValorile de Metadate pot fi numite separat folosindu-se un tag (de exemplu, <Subiect>3.2) iar aceasta va avea ca efect suprascrierea oricÄrui nume dat acestora prin linia cheie. DacÄ nu existÄ nicio linie cheie, oricare metadate care nu au fost denumite, vor fi numite âSubiectâ.  
+
+ISISPlugin.desc:AceastÄ extensie proceseazÄ bazele de date CDS/ISIS. Pentru fiecare bazÄ de date CDS/ISIS procesatÄ, trebuie sÄ existe trei fiÅiere Ã®n directorul de import al colecÅ£iei: fiÅiere Master (.mst), Field Definition Table (.fdt) Åi Cross-Reference File (.xrf).  
+
+ISISPlugin.subfield_separator:Stringul folosit pentru separarea subcÃ¢mpurilor Ã®n baza de Ã®nregistrÄri CDS/ISIS.  
+
+ISISPlugin.entry_separator:Stringul folosit pentru a separa valorile multiple care sÄ foloseascÄ cÃ¢mpurilor unice de metadate Ã®n cazul Ã®nregistrÄrilor CDS/ISIS.  
+
+
+
+KeyphraseExtractor.extract_keyphrases:Extrage automat frazele cheie cu ajutorul Kea (setÄrile implicite).  
+
+KeyphraseExtractor.extract_keyphrases_kea4:Extragerea frazelor cheie automat cu Kea 4.0 (setÄrile implicite). Kea 4.0 este o versine nouÄ de Kea care a fost dezvoltatÄ pentru a controla indexarea documentelor din domeniul agriculturii.  
+
+KeyphraseExtractor.extract_keyphrase_options:OpÅ£iuni pentru extragerea frazelor-cheie cu Kea. De exemplu: mALIWEB - foloseÅte modelul de extragere ALIWEB; n5 - extrage 5 frazÄ-cheie;, eGBK - foloseÅte codarea GBK.  
+
+KeyphraseExtractor.keyphrases:fraze cheie  
+
+KeyphraseExtractor.missing_kea:Eroare: Software-ul Kea nu a putut fi gÄsit la %s. VÄ rugÄm sÄ descÄrcaÅ£i %s Kea de la http://www.nzdl.org/Kea Åi instalaÅ£i-l Ã®n acest director.  
+
+LaTeXPlugin.desc:Extensie pentru documente LaTeX.  
+
+LOMPlugin.desc:Extensie pentru importarea fiÅierelor LOM (Learning Object Metadata).  
+
+LOMPlugin.root_tag:DocType-ul fiÅierului XML (sau o expresie regulatÄ care se potriveÅte elementului rÄdÄcinÄ).  
+
+LOMPlugin.check_timestamp:VerificÄ marcajele temporale (timestamps) a fiÅierelor descÄrcate anterior Åi descÄrcaÅ£i doar dacÄ fiÅierul sursÄ este mai nou.  
+
+LOMPlugin.download_srcdocs:DescÄrcaÅ£i documentul susrsÄ dacÄ este specificat unul (Ã®n general^identifier^entry sau technical^location). AceastÄ opÅ£iune ar trebui sÄ specifice o expresie regulatÄ pentru a potrivi numele fiÅierelor Ã®nainte de a fi descÄrcate. Trebuie spus cÄ aceastÄ funcÅ£ionalitate nu lucreazÄ pentru documentele aflate Ã®n afara unui firewall.  
+
+MARCPlugin.desc:Extensie pentru suportul MARC.  
+
+MARCPlugin.metadata_mapping:Numele fiÅierului care include detaliile de mapare din valorile MARC cÄtre numele metadatelor Greenstone. Au fost gÄsite setÄrile implicite Ã®n 'marctodc.txt' din directorul etc al siteului.  
+
+MARCXMLPlugin.desc:Extensie MARCXML.  
+
+MARCXMLPlugin.metadata_mapping_file:Numele fiÅierului care include detalii de mapare din valorile MARC pentru numele metadatelor Greenstone. SetÄrile implicite pentru âmarctodc.txtâ se gÄsesc Ã®n directorul etc al site-ului.  
+
+MediaWikiPlugin.desc:Extensie pentru importul paginilor web MediaWiki  
+
+MediaWikiPlugin.show_toc:AdaugÄ la pagina About a paginii 'cuprinsul' (table of contents) al paginii principale a website-ului MediaWiki vizat. Trebuie specificatÄ o expresie regulatÄ Perl mai jos Ã®n toc_exp pentru a corespunde cu secÅ£iunea 'cuprins'.  
+
+MediaWikiPlugin.delete_toc:Återge secÅ£iunea 'table of contents' a fiecÄrei pagini HTML. Trebuie specificatÄ o expresie regulatÄ Perl Ã®n toc_exp mai jos pentru a face potrivirea cu secÅ£iunea 'table of contents'.  
+
+MediaWikiPlugin.toc_exp:Expresie regulatÄ Perl pentru a potrivi cu 'table of content'. Valoarea implicitÄ se potriveÅte cu paginile web generate de MediaWiki.  
+
+MediaWikiPlugin.delete_nav:ÅtergeÅ£i secÅ£iunea de navigare. Trebuie specificatÄ o expresie regulatÄ Perl Ã®n nav_div_exp mai jos.  
+
+MediaWikiPlugin.nav_div_exp:O expresie regulatÄ Perl pentru a se potrivi cu secÅ£iunea de navigare. Valoarea implicitÄ se potriveÅte cu stilul de redactare comun al paginilor MediaWiki.  
+
+MediaWikiPlugin.delete_searchbox:Återge secÅ£iunea de cÄutare. Trebuie sÄ specifice o expresie regulatÄ mai jos Ã®n searchbox_div_exp.  
+
+MediaWikiPlugin.searchbox_div_exp:O expresie regulatÄ care sÄ se potriveascÄ cu secÅ£iunea de cÄutare. Valorile implicite se potrivesc cu cele ale paginilor obisnuite ale MediaWiki.  
+
+MediaWikiPlugin.remove_title_suffix_exp:O expresie regulatÄ Perl pentru a âperiaâ titlul extras. De exemplu, \\s-(.+) va filtra conÅ£inutul titlului dupÄ â-â.  
+
+MetadataCSVPlugin.desc:O extensie pentru metadate Ã®n formatul de valori separate prin virgule. CÃ¢mpul numelui fiÅierului din fiÅierul CSV este utilizat petru a determina cÄrui document aparÅ£in metadatele.  
+
+MetadataPass.desc:O clasÄ de bazÄ On-the-side pentru BasPlug care suportÄ extensii pentru metadate utilizeazÄ o trecere metadata_read a scriptului import.pl  
+
+
+
+GreenstoneMETSPlugin.desc:Procesarea documentelor dupÄ stilul METS Greenstone  
+
+MP3Plugin.desc:Extensie pentru procesarea fiÅierelor MP3.  
+
+MP3Plugin.assoc_images:FolosiÅ£i modulul de cÄutare al imaginilor din Google pentru a gÄsi imaginile legate de fiÅierele MP3 bazate pe ID3 avÃ¢nd metadatele pentru Titlu Åi Artist.  
+
+MP3Plugin.applet_metadata:Utilizat pentru stocarea metadatelor [applet] fiecÄrui document care conÅ£ine codul HTML necesar pentru ca un un applet de redare a fiÅierelor MP3 sÄ-l poatÄ rula.  
+
+MP3Plugin.metadata_fields:O lista de cÃ¢mpuri de metadate separate prin virgule pentru a fi extrase Ã®ntr-un fiÅier MP3 (se presupune cÄ sunt disponibilitÄÅ£ile). FolosiÅ£i \"*\" pentru a extrage toate cÃ¢mpurile.  
+
+NulPlugin.desc:Extensie pentru fiÅiere ÅuÅÄ - dummy (.nul). Utilizat cu fiÅierele produse prin destinderea metadatelor fiÅierelor din bazÄ.  
+
+NulPlugin.assoc_field:Numele cÃ¢mpului de metadate care va fi setat pentru fiecare fiÅier nul.  
+NulPlugin.add_metadata_as_text:AdÄugarea unei tabele de metadate ca text al documentului e mai bine decÃ¢t sÄ te loveÅti de lipsÄ semnalatÄ prin âAcest document nu conÅ£ine textâ.  
+
+NulPlugin.remove_namespace_for_text:EliminaÅ£i namespace-urile pentru numele metadatelor in documentul text (dacÄ este setat add_metadata_as_text)  
+
+OAIPlugin.desc:Extensie de bazÄ pentru Open Archives Initiative (OAI).  
+
+
+
+OggVorbisPlugin.add_technical_metadata:AdaugÄ metadate de ordin tehnic, de exemplu bitrate-ul.  
+
+OggVorbisPlugin.desc:O extensie capabilÄ de a importa fiÅiere audio Ogg Vorbis.  
+
+OpenDocumentPlugin.desc:Extensie pentru formatul OpenDocument al OASIS (utilizat de OpenOffice 2.0)  
+
+PagedImagePlugin.desc:Extensie pentru documentele alcÄtuite dintr-o serie de imagini cu text OCRizat pentru fiecare imagine. AceastÄ extensie proceseazÄ fiÅiere .item, care listeazÄ secvenÅ£a fiÅierelor de text Åi imagine Åi furnizeazÄ metadate.  
+
+PagedImagePlugin.documenttype:SetaÅ£i tipul documentului (utilizat pentru afiÅare)  
+
+PagedImagePlugin.documenttype.paged:Documentele avÃ¢nd pagini au sÄgeÅ£i urmÄtoarea Åi anterior precum Åi o cÄsuÅ£Ä 'mergi la pagina X'  
+
+PagedImagePlugin.documenttype.hierarchy:Documentele ierarhice au un cuprins  
+
+PagedImagePlugin.headerpage:AdÄugaÅ£i headerul de nivel Ã®nalt al unei pagini (care nu conÅ£ine nicio imagine) fiecÄrui document.  
+
+PDFPlugin.allowimagesonly:Permite fiÅiere PDF care nu au text exploatabil (protejat). EvitÄ necesitatea existenÅ£ei unui set complex. Este util doar Ã®n combinaÅ£ie cu convert_to html.  
+
+PDFPlugin.complex:CreaÅ£i rezultate mai complexe. AvÃ¢nd aceastÄ opÅ£iune setatÄ codul html rezultat va arÄta mai mult ca fiÅierul original PDF. Pentru ca acest lucru sÄ funcÅ£ioneze normal ar trebui sÄ aveÅ£i instalat Ghostscript (pentru unixuri gs ar trebui sÄ fie specificat Ã®n cÄi Ã®n timp ce pentru windows trebuie sÄ die specificat Ã®n cÄi gswin32c.exe).  
+
+PDFPlugin.desc:Extensie care proceseazÄ documentele PDF.  
+
+PDFPlugin.nohidden:PreveniÅ£i ca pdftohtml sÄ Ã®ncerce sÄ extragÄ text ascuns. AceastÄ capacitate este utilizabilÄ doar dacÄ este setatÄ opÅ£iunea -complex.  
+
+PDFPlugin.noimages:Nu incercaÅ£i sÄ extrageÅ£i imagini din PDF-uri.  
+
+PDFPlugin.use_sections:CreazÄ o secÅ£iune separatÄ pentru fiecare paginÄ a fiÅierului PDF.  
+
+PDFPlugin.zoom:Factorul de mÄrire al documentului PDF pentru ieÅire (acest lucru este util doar dacÄ -complex este setat).  
+
+PostScriptPlugin.desc:Acesta este convertorul ps Ã®n text \"al sÄracului\". DacÄ este nevoie de mai mult luaÅ£i Ã®n considerare utilizarea pachetului PRESCRIPT, care este disponibil pentru descÄrcare la http://www.nzdl.org/html/software.html  
+
+PostScriptPlugin.extract_date:ExtrageÅ£i date din headerul PS.  
+
+PostScriptPlugin.extract_pages:ExtrageÅ£i paginile din headerul PS.  
+
+PostScriptPlugin.extract_title:Extragerea titlului din headerul PS.  
+
+PowerPointPlugin.desc:O extensie pentru importul fiÅierelor MS PowerPoint.  
+
+PowerPointPlugin.windows_scripting:FolosiÅ£i tehnologia de scripting a lui Microsoft Windows (Visual Basic for Applications) pentru a converti PPT-urile Ã®n diferite tipuri de imagini (de exemplu, JPEG,PNG,GIF) mai degrabÄ decÃ¢t sÄ vÄ bazaÅ£i pe pachetul open source ppttohtml.  
+
+PrintInfo.bad_general_option:Extensia %s utilizeazÄ o opÅ£iune incorectÄ. VerificaÅ£i fiÅierul de configurare collect.cfg.  
+
+
+
+ProCitePlugin.desc:O extensie pentru bazele de date ProCite (exportate)  
+
+
+
+ReadTextFile.could_not_extract_encoding:ATENÅ¢IE: codarea nu a putut fi extrasÄ din %s - se aplicÄ modul implicit la %s  
+
+ReadTextFile.could_not_extract_language:ATENÅ¢IE: nu a putut fi extrasÄ limba din %s - implicit la %s  
+
+ReadTextFile.could_not_open_for_reading:nu a putut fi deschis %s pentru a fi citit  
+
+ReadTextFile.default_encoding:UtilizaÅ£i aceastÄ codare dacÄ -input_encoding este setat pe 'auto' iar argoritmul de categorisire a textului eÅueazÄ Ã®n a extrage schema de codare sau extrage o schemÄ de codare nesuportatÄ de Greenstone. AceastÄ opÅ£iune poate lua aceleaÅi valori ca Åi -input_encoding.  
+
+ReadTextFile.default_language:DacÄ Greenstone eÅueazÄ Ã®n a identifica limba unui document, elementul de metadate 'Language' va fi setat la aceastÄ valoare. Setarea implicitÄ este 'en' (sunt utilizate simbolurile pentru limbÄ specificate de ISO 639: en = English). Trebuie notat cÄ dacÄ nu este setat -input_encoding cu valoarea 'auto' iar -extract_language nu este setat, atunci toate documentele vor avea setul de metadate 'Language' setat cu aceastÄ valoare.  
+
+
+
+ReadTextFile.empty_file:fiÅierul nu conÅ£ine text  
+
+ReadTextFile.extract_language:Identificarea limbii fiecÄrui document, precum Åi setarea metadatelor 'Language'. Trebuie remarcat cÄ acest lucru va fi fÄcut automat dacÄ -input_encoding este setat pe 'auto'.  
+
+ReadTextFile.file_has_no_text:EROARE: %s nu conÅ£ine text  
+
+ReadTextFile.input_encoding:Codarea documentelor sursÄ. Documentele vor fi convertite din aceste codÄri Åi vor fo stocate intern ca utf8.  
+
+ReadTextFile.input_encoding.auto:FoloseÅte algoritmul de categorisire a textului pentru a identifica automat schema de codare a fiecÄrui document sursÄ. AceastÄ procedurÄ va fi mai lentÄ decÃ¢t prin explicarea directÄ a codÄrii, dar va funcÅ£iona acolo unde sunt folosite mai mult de o schemÄ de codare din cadrul aceleiaÅi colecÅ£ii.  
+
+ReadTextFile.read_denied:Citire interzisÄ pentru %s  
+
+ReadTextFile.separate_cjk:Introdu spaÅ£ii Ã®ntre caracterele ChinezeÅti/Japoneze/Coreene pentru a face fiecare caracter un cuvÃ¢nt. FolosiÅ£i dacÄ textul nu este segmentat.  
+
+ReadTextFile.unsupported_encoding:ATENÅ¢IE: %s pare sÄ fie codatÄ cu o codare care nu are suport (%s) - folosind %s  
+
+ReadTextFile.wrong_encoding:ATENÅ¢IE: %s a fost citit folosindu-se codarea %s dar apare codat ca %s.  
+
+ReadXMLFile.desc:Clasa de bazÄ pentru extensiile XML.  
+
+ReadXMLFile.xslt:Transformarea unui document de intrare care s-a potrivit cu XSLT-ul din fiÅierul numit. Este considerat un nume de fiÅier relativ care sÄ existe deja Ã®n zona fiÅierelor colecÅ£iei, de exemplu etc/mods2dc.xsl.  
+
+RealMediaPlugin.desc:O extensie pentru procesarea fiÅierelor Real Media.  
+
+ReferPlugin.desc:ReferPlug citeÅte fiÅierele bibliografice Ã®n format Refer.  
+
+RogPlugin.desc:CreazÄ documente la un nivel unic din fiÅiere .rog sau .mdb.  
+
+RTFPlugin.desc:Extensie pentru importul fiÅierelor Rich text Format (.rtf).  
+
+SourceCodePlugin.desc:Numele fiÅierului este folosit pentru Titlu (opÅ£ional fÄrÄ vreun prefix). Limbile curente:\ntext: READMEs/Makefiles\nC/C++ (extrage #include statements Åi clasele C++ decls)\nPerl    (fÄcut doar ca text)\nShell   (fÄcut doar ca text)  
+
+SourceCodePlugin.remove_prefix:EliminaÅ£i acest Åablon de coordonare din numele fiÅierului (de exemplu, -remove_prefix /tmp/XX/src/). Modul de lucru uzual este de a elimina Ã®ntreaga cale din numele fiÅierului.  
+
+SplitTextFile.desc:SplitPlug este o extensie pentru a sparge fiÅierele intrate Ã®n segmente care vor fi procesate apoi individual. AceastÄ extensie nu ar trebui sÄ fie chematÄ Ã®n mod direct. DacÄ este necesarÄ procesarea fiÅierelor intrate care conÅ£in cÃ¢teva documente, mai bine  scrieÅ£i o extensie care sÄ conÅ£inÄ o funcÅ£ie de procesare care sÄ se ocupe de astfel de documente Åi apoi sÄ o faceÅ£i moÅtenire pentru extensia SplitPlug. Vezi SplitPlug pentru un exemplu.  
+
+SplitTextFile.split_exp:O expresie regulatÄ perl pentru a sparge fiÅierele intrate Ã®n segmente.  
+
+StructuredHTMLPlugin.desc:O extensie pentru procesarea documentelor structurate HTML, spargerea acestora Ã®n secÅ£iuni bazate pe informaÅ£iile de stil.  
+
+StructuredHTMLPlugin.delete_toc:EliminÄ orice cuprins, liste de figuri etc din fiÅierele HTML convertite. Stilurile pentru acestea sunt specificate prin opÅ£iunea toc_header.  
+
+StructuredHTMLPlugin.title_header:Posibile stiluri definite de utilizator pentru titlul headerului.  
+
+StructuredHTMLPlugin.level1_header:stiluri definite de utilizator pentru headerul de nivel1 Ã®n documentul HTML (echivalentul lui <h1>).  
+
+StructuredHTMLPlugin.level2_header:Posibile stiluri definite de utilizatori pentru headerul de nivelul2 Ã®n documentul HTML (echivalent cu <h2>).  
+
+StructuredHTMLPlugin.level3_header:stiluri definite de utilizatori pentru header de nivel 3 Ã®n documentele HTML (echivalent cu <h3>).  
+
+StructuredHTMLPlugin.toc_header:posibile headere definite prin stiluri compuse de utilizator pentru cuprins, tabelul ilustraÅ£iilor, etc,. Ar trebui eliminat dacÄ este setat delete_toc.  
+
+TextPlugin.desc:CreaÅ£i documente simple pe un singur nivel. AdaugÄ metadate Titlu la prima linie de text (pÃ¢nÄ la 100 de caractere lungime).  
+
+TextPlugin.title_sub:Expresia de substituire pentru a modifica stringul stocat ca Titlu. De exemplu se foloseÅte PSPlug pentru a elimina âPagina 1â din textul folosit ca titlu.  
+
+UnknownPlugin.assoc_field:Numele cÃ¢mpului de metadate care conÅ£ine numele fiÅierului asociat.  
+
+UnknownPlugin.desc:Acesta este o extensie simplÄ pentru importarea fiÅierelor Ã®n formate despre care Greenstone nu cunoaÅte detalii. Un document ficÅ£ional va fi creat pentru fiecare dintre  aceste fiÅiere iar fiÅierul Ã®n sine va fi pasat cÄtre Greenstone ca \"fiÅier asociat\" al documentului.  
+
+UnknownPlugin.file_format:Tipul fiÅierului (de exemplu, MPEG, MIDI, ...)  
+
+UnknownPlugin.mime_type:Tipul fiÅierului (mime), de exemplu image/gif.  
+
+UnknownPlugin.process_extension:ProcesaÅ£i fiÅierele cu aceastÄ extensie pentru fiÅiere. AceastÄ opÅ£iune este o alternativÄ la process_exp care este mai simplu de utilizat, dar care este mai puÅ£in flexibil.  
+
+UnknownPlugin.srcicon:SpecificÄ un nume pentru macro (fÄrÄ liniuÅ£e jos) pentru a fi folosite ca metadate srcicon.  
+
+WordPlugin.desc:O extensie pentru importul documentelor Microsoft Word.  
+
+WordPlugin.windows_scripting:FolosiÅ£i tehnologia de scripting Microsoft Windows (Visual Basic for Applications) pentru a determina Wordul sÄ converteascÄ documentele Ã®n HTML, mai degrabÄ decÃ¢t sÄ vÄ bazaÅ£i pe pachetul open source WvWare. Are ca efect deschiderea aplicaÅ£iei Word dacÄ aceasta nu ruleazÄ deja.  
+
+WordPlugin.metadata_fields:Este folosit pentru a extrage metadatele dintr-un document HTML convertit de un script VB. Permite utilizatorilor sÄ defineascÄ o listÄ de cÃ¢mpuri de metadate separate prin virgule pentru a Ã®ncerca sÄ le extragÄ. FoloseÅte 'tag<tagname>' pentru a avea conÅ£inutul primei perechi de taguri <tagname> pusÄ Ã®ntr-un element de metadate numit 'tagname'. PuneÅ£i leterÄ mare acum dacÄ doriÅ£i metadatele sÄ fie cu majuscule Ã®n cadrul Greenstone din moment ce extragerea tagurilor Å£ine cont de dimensiunea caracterelor.  
+
+ZIPPlugin.desc:Extensie care se ocupÄ de formatele comprimate iar dacÄ fiÅierele sunt:\ngzip (.gz, .z, .tgz, .taz)\nbzip (.bz)\nbzip2 (.bz2)\nzip (.zip .jar)\ntar (.tar)\n\nAceastÄ extensie se bazeazÄ pe prezenÅ£a urmÄtoarelor utilitÄÅ£i (dacÄ Ã®ncearcÄ sÄ proceseze formatele corespondente):\ngunzip (pentru gzip)\nbunzip (pentru bzip)\nbunzip2 \nunzip (pentru zip)\ntar (pentru tar)  
+
+#
+# Download module option descriptions
+#
+
+BaseDownload.desc:Clasa de bazÄ pentru modulele de descÄrcare  
+
+MediaWikiDownload.desc:Este un modul pentru descarcarea din siteurile bazate pe MediaWiki  
+MediaWikiDownload.reject_filetype:IgnorÄ lista de url-uri separate prin virgule, de exemplu: *cgi-bin*,*.ppt ignorÄ hyperlinkurile care au ca Åi conÅ£inut fie un fiÅier âcgi-binâ sau â.pptâ  
+MediaWikiDownload.reject_filetype_disp:Lista de URL-uri ignorate. Sunt separate prin virgule.  
+MediaWikiDownload.exclude_directories:Lista directoarelor de excludere (trebuie precizatÄ calea absolutÄ cÄtre directorul respectiv), de exemplu, /people Åi /documentation vor exclude subdirectoarele menÅ£ionate din raza acÅ£iunilor de indexare automatÄ.  
+MediaWikiDownload.exclude_directories_disp:Lista directoarelor care ar trebui excluse separate prin virgule  
+
+OAIDownload.desc:Un modul pentru descÄrcarea din depozitele OAI  
+OAIDownload.url_disp:URL-ul sursÄ  
+OAIDownload.url:URL-ul depozitului OAI  
+OAIDownload.set_disp:Setare  
+OAIDownload.set:RestricÅ£ionaÅ£i descÄrcarea la un set specific din depozit  
+
+
+OAIDownload.get_doc_disp:ObÅ£ine documentul  
+OAIDownload.get_doc:DescÄrcaÅ£i documentul sursÄ dacÄ este specificat unul Ã®n Ã®nregistrare  
+
+
+OAIDownload.max_records_disp:NumÄrul maxim de Ã®nregistrÄri  
+OAIDownload.max_records:NumÄrul maxim de Ã®nregistrÄri pentru a fi descÄrcate  
+
+SRWDownload.desc:Un modul pentru descÄrcarea de pe depozitele SRW (Search/Retrive Web Service)  
+
+WebDownload.desc:Un modul pentru descÄrcarea de pe Internet via HTTP sau FTP  
+WebDownload.url:URL-ul Sursei  
+WebDownload.url_disp:Sursa URL  
+WebDownload.depth:Care este adÃ¢ncimea Ã®n hyperlinkuri la momentul descÄrcÄrii  
+WebDownload.depth_disp:AdÃ¢ncimea de descÄrcare  
+WebDownload.below:Doar fiÅierele oglindite mai jos de acest URL  
+WebDownload.below_disp:Doar fiÅierele oglindÄ de sub acest URL  
+WebDownload.within:Doar fiÅierele oglindite Ã®n cadrul aceluiaÅi site  
+WebDownload.within_disp:Doar fiÅiere mirror din cadrul aceluiaÅi site  
+WebDownload.html_only:DescarcÄ doar fiÅierele HTML Åi ignorÄ fiÅierele asociate, de exemplu imaginile Åi stylesheeturile  
+WebDownload.html_only_disp:DescarcÄ doar fiÅierele HTML  
+
+WgetDownload.desc:Clasa de bazÄ care gestioneazÄ apelurile cÄtre wget (utilitar GNU pentru descÄrcare de pe web)  
+WgetDownload.proxy_on:Proxy pornit  
+WgetDownload.proxy_host:Computer Proxy  
+WgetDownload.proxy_port:Port proxy  
+WgetDownload.user_name:Numele utilizatorului  
+WgetDownload.user_password:Parola utilizatorului  
+
+Z3950Download.desc:Un modul pentru descÄrcarea din depozitele Z3950  
+Z3950Download.host:URL-ul calculatorului gazdÄ  
+Z3950Download.host_disp:Computer gazdÄ  
+Z3950Download.port:NumÄrul portului depozitului  
+Z3950Download.port_disp:Port  
+Z3950Download.database:Baza de date cautÄ Ã®nregistrÄri Ã®n  
+Z3950Download.database_disp:Baza de date  
+Z3950Download.find:Extragerea Ã®nregistrÄrilor care conÅ£in termenii de cÄutare specificaÅ£i  
+Z3950Download.find_disp:CautÄ  
+Z3950Download.max_records:NumÄrul maxim de Ã®nregistrÄri pentru descÄrcare  
+Z3950Download.max_records_disp:Maximum de ÃnregistrÄri  
+
+
+#
+#Plugout option descriptions
+#
+
+BasPlugout.bad_general_option:Plugout-ul %s utilizeazÄ o opÅ£iune incorectÄ.  
+
+BasPlugout.desc:Base class for all the export plugouts.
+BasPlugout.group_size:NumÄrul de documente pentru a fi grupate Ã®ntr-un fiÅier XML.  
+BasPlugout.gzip_output:FolosiÅ£i gzip pentru a comprima documentele xml rezultante (nu uitaÅ£i sÄ includeÅ£i ZIPPlug Ã®n lista extensiilor proprii atunci cÃ¢nd construiÅ£i din documente comprimate).  
+BasPlugout.output_handle:descriptorul fiÅierului folosit pentru a trimite informaÅ£iile conÅ£inute Ã®n rezultate  
+BasPlugout.output_info:referinÅ£a cÄtre un obiect arcinfo utilizat pentru a stoca informaÅ£ii despre arhive.  
+BasPlugout.verbosity:ControleazÄ calitatea rezultatelor. 0=lipsÄ, 3=mai multe.  
+BasPlugout.xslt_file:TransformÄ un document cu XSLT Ã®n numele fiÅierului.  
+
+DSpacePlugout.desc:Formatul de arhivÄ :DSpace.  
+
+
+
+
+
+
+
+
+MARCXMLPlugout.desc:Formatul xml MARC.  
+MARCXMLPlugout.group:Punerea rezultatelor Ã®nregistrÄrilor marc xml Ã®ntr-un singur fiÅier.  
+MARCXMLPlugout.mapping_file:FoloseÅte fiÅierul numit de mapare pentru transformare.  
+
+METSPlugout.desc:Formatul METS care foloseÅte profilul Greenstone.  
+METSPlugout.xslt_txt:TransformÄ un document mets doctxt.xml folosind XSLT Ã®n numele fiÅierului.  
+METSPlugout.xslt_mets:TransformÄ documentul docmets.xml Ã®n formatul mets cu ajutorul XSLT Ã®n fiÅier denumit.  
+
+#
+# Perl module strings
+#
+
+classify.could_not_find_classifier:EROARE: Nu am putut gÄsi clasificatorul \"%s\"  
+
+download.could_not_find_download:EROARE: Nu am putut gÄsi modulul de descÄrcare \"%s\"  
+
+plugin.could_not_find_plugin:ERROARE: Nu am putut gÄsi extensia \"%s\"  
+
+plugin.including_archive:incluzÃ¢nd conÅ£inutul unei arhive ZIP/TAR  
+
+plugin.including_archives:includerea conÅ£inutului arhivelor %d ZIP/TAR  
+
+plugin.kill_file:Proces terminat de fiÅierul .kill  
+
+plugin.n_considered:Documentele %d au fost considerate pentru procesare  
+
+plugin.n_included:%d au fost procesate Åi incluse Ã®n colecÅ£ie  
+
+plugin.n_rejected:%d au fost respinse  
+
+plugin.n_unrecognised:%d nu au fost recunoscute  
+
+plugin.no_plugin_could_process:ATENÅ¢IE: Niciun plugin nu poate procesa %s  
+
+plugin.no_plugin_could_recognise:ATENÅ¢IE: Nicio extensie nu poate recunoaÅte %s  
+
+plugin.no_plugin_could_process_this_file:fiÅierul nu a fost procesat de nicio extensie  
+
+plugin.no_plugin_could_recognise_this_file:nicio extensie nu a putut recunoaÅte acest fiÅier  
+
+plugin.one_considered:Un document a fost luat Ã®n considerare pentru a fi procesat  
+
+plugin.one_included:Unu a fost procesat Åi inclus Ã®n colecÅ£ie  
+
+plugin.one_rejected:1 a fost respins  
+
+plugin.one_unrecognised:A fost recunoscut 1  
+
+plugin.see_faillog:Vezi %s pentru o listÄ de documente nerecunoscute Åi/sau respinse  
+
+PrintUsage.default:Implicit  
+
+PrintUsage.required:NECESAR  
+
+plugout.could_not_find_plugout:EROARE: Nu am gÄsit \"%s\" plugout  
Index: /gsdl/stable/perllib/strings_ru.properties
===================================================================
--- /gsdl/stable/perllib/strings_ru.properties	(revision 20131)
+++ /gsdl/stable/perllib/strings_ru.properties	(revision 20131)
@@ -0,0 +1,1737 @@
+#
+# Resource bundle description
+# 
+
+Language.code:ru
+Language.name:Russian
+
+OutputEncoding.unix:koi8_r
+OutputEncoding.windows:dos_850
+
+
+#
+# Common output messages and strings
+#
+
+common.cannot_create_file:ÐÐšÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÑÐŸÐ·ÐŽÐ°ÑÑ ÑÐ°Ð¹Ð» %s
+
+common.cannot_find_cfg_file:ÐÐšÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐœÐ°Ð¹ÑÐž ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐŸÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» %s
+
+common.cannot_open:ÐÐšÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐŸÑÐºÑÑÑÑ %s
+
+common.cannot_open_fail_log:ÐÐšÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐŸÑÐºÑÑÑÑ ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÐŸÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» %s
+
+common.cannot_open_output_file:ÐÐšÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐŸÑÐºÑÑÑÑ Ð²ÑÑ
+ÐŸÐŽÐœÐŸÐ¹ ÑÐ°Ð¹Ð» %s.
+
+common.cannot_read:ÐÐšÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÑÐžÑÐ°ÑÑ %s
+
+common.cannot_read_file:ÐÐšÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ Ð¿ÑÐŸÑÐµÑÑÑ ÑÐ°Ð¹Ð» %s
+
+common.general_options:ÐŸÐ±ÑÐžÐµ Ð²Ð°ÑÐžÐ°ÐœÑÑ (ÐŽÐ»Ñ %s)
+
+common.must_be_implemented:ÑÑÐœÐºÑÐžÑ ÐŽÐŸÐ»Ð¶ÐœÐ° Ð±ÑÑÑ ÐŸÑÑÑÐµÑÑÐ²Ð»ÐµÐœÐ° Ð² Ð¿ÐŸÐŽÐºÐ»Ð°ÑÑÐµ
+
+common.options:ÐŸÐ¿ÑÐžÐž
+
+common.processing:ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐ°
+
+common.specific_options:ÑÐ¿ÐµÑÐžÑÐžÑÐµÑÐºÐžÐµ ÐŸÐ¿ÑÐžÐž
+
+common.usage:ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµ
+
+common.info:ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ  
+
+common.invalid_options:ÐÐµÐ²ÐµÑÐœÑÐµ Ð°ÑÐ³ÑÐŒÐµÐœÑÑ: %s  
+
+common.true:Ð²ÐµÑÐœÐŸ  
+
+common.false:ÐœÐµÐ²ÐµÑÐœÐŸ  
+
+common.deprecated:ÐÐÐÐÐÐÐÐ«  
+#
+# Script option descriptions and output messages
+#
+
+scripts.language:Ð¯Ð·ÑÐº ÐŽÐ»Ñ ÐŸÑÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÐŸÐ¿ÐžÑÐ°ÐœÐžÐ¹ ÐŸÐ¿ÑÐžÐ¹ Ð² (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, 'en_US' ÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÐµÑ Ð°ÐŒÐµÑÐžÐºÐ°ÐœÑÐºÐžÐ¹ Ð°ÐœÐ³Ð»ÐžÐ¹ÑÐºÐžÐ¹ ÑÐ·ÑÐº). Ð¢ÑÐµÐ±ÑÐµÑ Ð¿ÐµÑÐµÐ²ÐŸÐŽÐŸÐ² ÐŸÐ¿ÐžÑÐ°ÐœÐžÐ¹ ÐŸÐ¿ÑÐžÐ¹ ÐŽÐ»Ñ Ð¿ÑÐžÑÑÑÑÑÐ²ÐžÑ Ð² ÑÐ°Ð¹Ð»Ðµ perllib/strings_language-code.rb.
+
+scripts.xml:ÐÑÐŸÐžÐ·Ð²ÐŸÐŽÐžÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ Ð² ÑÐŸÑÐŒÐ°ÑÐµ XML Ð±ÐµÐ· 'ÑÐžÐŒÐ¿Ð°ÑÐžÑÐœÑÑ
+' ÐºÐŸÐŒÐŒÐµÐœÑÐ°ÑÐžÐµÐ², ÐœÐŸ Ñ ÐœÐ°ÐŒÐœÐŸÐ³ÐŸ Ð±ÐŸÐ»ÑÑÐžÐŒ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸÐŒ ÐŽÐµÑÐ°Ð»ÐµÐ¹.
+
+scripts.listall:Ð¡Ð¿ÐžÑÐŸÐº Ð²ÑÐµÑ
+ ÐžÐ·Ð²ÐµÑÑÐœÑÑ
+ ÐµÐŽÐžÐœÐžÑ.
+
+scripts.describeall:ÐÑÐŸÐ±ÑÐ°Ð·ÐžÑÑ ÐŸÐ¿ÑÐžÐž ÐŽÐ»Ñ Ð²ÑÐµÑ
+ ÐžÐ·Ð²ÐµÑÑÐœÑÑ
+ Ð¿ÑÐœÐºÑÐŸÐ²  
+
+scripts.both_old_options:ÐÐÐÐÐÐÐÐ: ÐÑÐž ÑÐºÐ°Ð·Ð°ÐœÐžÐž ÐŸÐ±ÐµÐžÑ
+ ÐŸÐ¿ÑÐžÐ¹ -removeold Ðž -keepold (ÑÑÐŸ ÑÐ°Ð²ÐœÐŸÐ·ÐœÐ°ÑÐœÐŸ -removeold Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ) Ð²ÑÐµ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž %s Ð±ÑÐŽÐµÑ ÑÐŽÐ°Ð»ÐµÐœÐŸ.  
+
+scripts.no_old_options:ÐÐÐÐÐÐÐÐ: ÐÐž -removeold ÐœÐž -keepold ÐœÐµ Ð±ÑÐ»Ðž ÑÐºÐ°Ð·Ð°ÐœÑ, ÑÑÐŸ ÑÐ°Ð²ÐœÐŸÐ·ÐœÐ°ÑÐœÐŸ -removeold. ÐÑÐµ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž %s Ð±ÑÐŽÐµÑ ÑÐŽÐ°Ð»ÐµÐœÐŸ.  
+
+scripts.gli:Ð£ÑÑÐ°ÐœÐŸÐ²ÐžÑÑ ÑÐ»Ð°Ð³ Ð¿ÑÐž Ð·Ð°Ð¿ÑÑÐºÐµ ÑÑÐŸÐ³ÐŸ ÑÐºÑÐžÐ¿ÑÐ° ÐžÐ· GLI, ÐŽÐ°ÐµÑ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÑ Ð²ÑÑ
+ÐŸÐŽÐ° ÐœÐ° ÐºÐŸÐœÐºÑÐµÑÐœÑÐµ ÐžÐœÑÐµÑÑÐµÐ¹ÑÑ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ°ÑÐµÐ¹ GLI.  
+
+# -- buildcol.pl --
+
+buildcol.archivedir:ÐÐŽÐµ ÐœÐ°Ñ
+ÐŸÐŽÑÑÑÑ Ð°ÑÑ
+ÐžÐ²Ñ.
+
+buildcol.builddir:ÐÐŽÐµ Ð¿ÐŸÐŒÐµÑÑÐžÑÑ ÑÐŸÐ·ÐŽÐ°ÐœÐœÑÐµ ÐžÐœÐŽÐµÐºÑÑ.
+
+buildcol.cachedir:ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ Ð±ÑÐŽÐµÑ Ð²ÑÐµÐŒÐµÐœÐœÐŸ ÑÐŸÐ·ÐŽÐ°ÐœÐ° Ð·ÐŽÐµÑÑ, Ð¿ÐµÑÐµÐŽ ÑÐµÐŒ ÐºÐ°Ðº Ð±ÑÐŽÐµÑ ÑÐºÐŸÐ¿ÐžÑÐŸÐ²Ð°ÐœÐ° Ð² ÑÐŸÐ·ÐŽÐ°ÐœÐœÑÑ ÐŽÐžÑÐµÐºÑÐŸÑÐžÑ.
+
+buildcol.cannot_open_cfg_file:ÐÐ ÐÐÐ£ÐÐ ÐÐÐÐÐÐÐ: ÐÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐŸÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» ÐœÐµ ÐŒÐŸÐ¶ÐµÑ ÐŸÑÐºÑÑÑÑ ÐŽÐ»Ñ ÐŸÐ±ÐœÐŸÐ²Ð»ÐµÐœÐžÑ: %s
+
+buildcol.collectdir:ÐÑÑÑ Ðº 'collect" ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž.  
+
+buildcol.copying_back_cached_build:ÐÐ±ÑÐ°ÑÐœÐŸÐµ ÐºÐŸÐ¿ÐžÑÐŸÐ²Ð°ÐœÐžÐµ ÐºÑÑÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐ¹ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑ.
+
+buildcol.create_images:ÐÐŸÐ¿ÑÑÐºÐ° ÑÐŸÐ·ÐŽÐ°ÑÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ ÐŽÐ»Ñ ÐœÐŸÐ²ÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. ÐÐœÐ° ÐŸÑÐœÐŸÐ²Ð°ÐœÐ° ÐœÐ° Gimp, ÐºÐŸÑÐŸÑÑÐ¹ ÐžÐœÑÑÐ°Ð»Ð»ÐžÑÑÐµÑÑÑ ÐœÐ°ÑÑÐŽÑ Ñ Ð¿ÐŸÐŽÑ
+ÐŸÐŽÑÑÐžÐŒÐž ÐŒÐŸÐŽÑÐ»ÑÐŒÐž perl, ÑÑÐŸÐ±Ñ Ð¿ÐŸÐ·Ð²ÐŸÐ»ÐžÑÑ ÐœÐ°Ð¿ÐžÑÐ°ÐœÐžÐµ ÑÐºÑÐžÐ¿ÑÐŸÐ² ÐŸÑ perl.
+
+buildcol.debug:ÐÐ°Ð¿ÐžÑÐ°ÑÑ Ð¿ÑÐŸÐŽÑÐºÑÐžÑ Ð² STDOUT.
+
+buildcol.desc:Ð¡ÐºÑÐžÐ¿Ñ PERL, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÐ¹ ÐŽÐ»Ñ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Greenstone ÐžÐ· ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² GML.  
+
+buildcol.faillog:ÐÐµÑÐŽÐ°ÑÐœÐ°Ñ ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÑ ÐžÐŒÐµÐœÐž ÑÐ°Ð¹Ð»Ð°. Ð­ÑÐŸÑ Ð¶ÑÑÐœÐ°Ð» ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÑ Ð¿ÐŸÐ»ÑÑÐžÐ» ÐžÐŒÐµÐœÐ° ÑÐ°Ð¹Ð»ÐŸÐ² ÐžÐ· Ð»ÑÐ±ÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ², ÐºÐŸÑÐŸÑÑÐµ ÐœÐµ ÐŒÐŸÐ³ÑÑ Ð±ÑÑÑ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÐœÑ
+
+buildcol.incremental_default_builddir:ÐÐÐÐÐÐÐÐ: Ð¡ÑÑÑÐºÑÑÑÐ° ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž Ð±ÑÐ»Ð° ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐ° ÐŽÐ»Ñ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ. ÐÑÐ»Ðž Ð²Ñ Ð¶ÐµÐ»Ð°ÐµÑÐµ ÐŽÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÐŸ ÐŽÐŸÐ±Ð°Ð²ÐžÑÑ Ðº ÐžÐŒÐµÑÑÐµÐŒÑÑÑ ÐžÐœÐŽÐµÐºÑÑ ÐŽÐžÑÐµÐºÑÐŸÑÐžÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ  "-builddir index" ÐŸÐ¿ÑÐžÑ Ð² buildcol.pl.  
+
+buildcol.index:ÐÐœÐŽÐµÐºÑ ÐŽÐ»Ñ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ ( Ð²ÑÐµ Ð±ÑÐŽÐµÑ ÑÐŸÐ·ÐŽÐ°Ð²Ð°ÑÑÑÑ Ð² ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐŸÐœÐœÐŸÐŒ ÑÐ°Ð¹Ð»Ðµ, ÐµÑÐ»Ðž ÐŸÐœ ÐœÐµ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœ).
+
+buildcol.incremental:ÐÐœÐŽÐµÐºÑÐžÑÐŸÐ²Ð°ÑÑ ÑÐŸÐ»ÑÐºÐŸ ÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ, ÐºÐŸÑÐŸÑÑÐµ ÐµÑÐµ ÐœÐµ Ð±ÑÐ»Ðž Ð¿ÑÐŸÐžÐœÐŽÐµÐºÑÐžÑÐŸÐ²Ð°ÐœÑ. ÐÐºÐ»ÑÑÐ°ÐµÑ -keepold. ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑ ÐžÐœÐŽÐµÐºÑÐ°ÑÐŸÑ lucene.  
+
+buildcol.keepold:ÐÐµ Ð±ÑÐŽÐµÑ ÑÐœÐžÑÑÐŸÐ¶Ð°ÑÑ ÑÐµÐºÑÑÐµÐµ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ ÑÐŸÐ·ÐŽÐ°Ð²Ð°ÐµÐŒÐŸÐ¹ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž.
+
+buildcol.maxdocs:ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÑÐžÑÐ»ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÐŽÐ»Ñ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ.
+buildcol.maxnumeric:ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÑÐžÑÐ»ÐŸ ÑÐžÑÑ, ÐºÐŸÑÐŸÑÐŸÐµ ÐŒÐŸÐ¶ÐµÑ ÐžÐŒÐµÑÑ Â«ÑÐ»ÐŸÐ²ÐŸÂ» Ð² ÑÐ»ÐŸÐ²Ð°ÑÐµ ÐžÐœÐŽÐµÐºÑÐ°. ÐÐŸÐ»ÑÑÐžÐµ ÑÐžÑÐ»Ð° ÑÐ°Ð·ÐŽÐµÐ»ÑÑÑÑÑ ÐœÐ° ÐœÐµÑÐºÐŸÐ»ÑÐºÐŸ ÑÐ»ÐŸÐ² ÐŽÐ»Ñ ÐžÐœÐŽÐµÐºÑÐ°ÑÐžÐž. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, ÐµÑÐ»Ðž ÐŒÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÑÐžÑÐ»ÐŸ ÑÐ°Ð²ÐœÐŸ 4, "1342663" Ð±ÑÐŽÐµÑ ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐŸ ÐœÐ° "1342" Ðž "663".  
+buildcol.mode:Ð§Ð°ÑÑÐž Ð¿ÑÐŸÑÐµÑÑÐ° Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž, ÐºÐŸÑÐŸÑÑÐµ ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÐŸ Ð²ÑÐ¿ÐŸÐ»ÐœÐžÑÑ.
+buildcol.mode.all:ÐÐµÐ»Ð°ÑÑ Ð²ÑÐµ.
+buildcol.mode.build_index:Ð¢ÐŸÐ»ÑÐºÐŸ ÐžÐœÐŽÐµÐºÑÐžÑÐŸÐ²Ð°ÑÑ ÑÐµÐºÑÑ.
+buildcol.mode.compress_text:Ð¢ÐŸÐ»ÑÐºÐŸ ÑÐ¶Ð°ÑÑ ÑÐµÐºÑÑ.
+buildcol.mode.infodb:Ð¢ÐŸÐ»ÑÐºÐŸ ÑÐŸÐ·ÐŽÐ°ÑÑ Ð±Ð°Ð·Ñ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+.
+
+buildcol.no_default_images:ÐÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ ÐœÐµ Ð±ÑÐŽÑÑ ÑÐŸÐ·ÐŽÐ°ÐœÑ.
+
+buildcol.no_image_script:ÐÐ ÐÐÐ£ÐÐ ÐÐÐÐÐÐÐ: Ð¡ÐºÑÐžÐ¿Ñ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÐœÐµ ÐŒÐŸÐ³ Ð±ÑÑÑ ÐœÐ°Ð¹ÐŽÐµÐœ: %s
+
+buildcol.no_strip_html:ÐÐµ ÑÐŽÐ°Ð»ÑÑÑ ÑÑÐ³Ðž HTML ÐžÐ· ÐžÐœÐŽÐµÐºÑÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐ³ÐŸ ÑÐµÐºÑÑÐ° (ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÑÐŸÐ»ÑÐºÐŸ ÐŽÐ»Ñ mgpp ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹).
+
+buildcol.no_text:ÐÐµ Ñ
+ÑÐ°ÐœÐžÑÑ ÑÐ¶Ð°ÑÑÐ¹ ÑÐµÐºÑÑ. Ð­ÑÐŸÑ ÐŸÐ¿ÑÐžÑ Ð¿ÐŸÐ»ÐµÐ·ÐœÐ° ÐŽÐ»Ñ ÐŒÐžÐœÐžÐŒÐžÐ·Ð°ÑÐžÐž ÑÐ°Ð·ÐŒÐµÑÐ° Ð¿ÐŸÑÑÑÐŸÐµÐœÐœÑÑ
+ ÐžÐœÐŽÐµÐºÑÐŸÐ², ÐµÑÐ»Ðž ÐÑ ÐœÐ°ÐŒÐµÑÐµÐ²Ð°ÐµÑÐµÑÑ Ð²ÑÐµÐ³ÐŽÐ° Ð¿ÐŸÐºÐ°Ð·ÑÐ²Ð°ÑÑ ÐŸÑÐžÐ³ÐžÐœÐ°Ð»Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° Ð² ÑÐµÐºÑÑÐµÐµ Ð²ÑÐµÐŒÑ (ÑÐŸ ÐµÑÑÑ ÐÑ ÐœÐµ Ð±ÑÐŽÐµÑÐµ ÑÐ¿ÐŸÑÐŸÐ±ÐœÑ Ð²ÐŸÑÑÑÐ°ÐœÐŸÐ²ÐžÑÑ ÑÐ¶Ð°ÑÑÑ Ð²ÐµÑÑÐžÑ ÑÐµÐºÑÑÐ°).
+
+buildcol.sections_index_document_metadata:ÐÐœÐŽÐµÐºÑÐžÑÐŸÐ²Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ ÐœÐ° ÑÑÐŸÐ²ÐœÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ð² ÑÐµÐºÑÐžÑÑ
+  
+buildcol.sections_index_document_metadata.never:ÐÐµ ÐžÐœÐŽÐµÐºÑÐžÑÐŸÐ²Ð°ÑÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° ÐœÐ° ÑÑÐŸÐ²ÐœÐµ ÑÐµÐºÑÐžÐž.  
+buildcol.sections_index_document_metadata.always:ÐÐŸÐ±Ð°Ð²ÐžÑÑ Ð²ÑÐµ ÐŸÐ±ÐŸÐ·ÐœÐ°ÑÐµÐœÐœÑÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° ÐœÐ° ÑÑÐŸÐŒ ÑÑÐŸÐ²ÐœÐµ, ÐŽÐ°Ð¶Ðµ ÐµÑÐ»Ðž ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ Ð²ÑÐµÐ¹ ÑÐµÐºÑÐžÐž ÐœÐ° ÑÑÐŸÐŒ ÑÑÐŸÐ²ÐœÐµ ÑÑÑÐµÑÑÐ²ÑÑÑ.  
+buildcol.sections_index_document_metadata.unless_section_metadata_exists:ÐÐŸÐ±Ð°Ð²ÐžÑÑ ÑÐŸÐ»ÑÐºÐŸ ÑÐŸÐ³ÐŽÐ° ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐœÐ° ÑÑÐŸÐŒ ÑÑÐŸÐ²ÐœÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°, ÐµÑÐ»Ðž ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÑÐµÐºÑÐžÐž ÐœÐ° ÑÑÐŸÐŒ ÑÑÐŸÐ²ÐœÐµ Ñ ÑÑÐžÐŒ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµÐŒ ÐœÐµ ÑÑÑÐµÑÑÐ²ÑÑÑ.  
+
+buildcol.out:ÐÐŒÑ ÑÐ°Ð¹Ð»Ð° ÐžÐ»Ðž ÐžÐœÐŽÐµÐºÑ ÐŽÐ»Ñ Ð¿ÐµÑÐ°ÑÐž ÑÑÐ°ÑÑÑÐ° Ð¿ÑÐŸÐŽÑÐºÑÐžÐž Ð².
+
+buildcol.params:[Ð²Ð°ÑÐžÐ°ÐœÑÑ] ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž
+
+buildcol.remove_empty_classifications:Ð¡ÐºÑÑÑÑ ÐœÐµÐ·Ð°Ð¿ÐŸÐ»ÐœÐµÐœÐœÑÐµ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÑ Ðž ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐŸÐœÐœÑÐµ ÑÐ·Ð»Ñ (Ð±ÐµÐ· ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ²).
+
+buildcol.removeold:Ð£ÐŽÐ°Ð»ÐžÑ ÑÑÑÐ°ÑÐµÐ²ÑÐµÐµ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ ÑÐ°Ð±ÐŸÑÐµÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.  
+
+buildcol.unlinked_col_images:ÐÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐœÐµ ÐŒÐŸÐ³ÑÑ Ð±ÑÑÑ ÑÐ²ÑÐ·Ð°ÐœÑ Ð¿ÑÐ°Ð²ÐžÐ»ÑÐœÐŸ.
+
+buildcol.unknown_mode:ÐÐµÐžÐ·Ð²ÐµÑÑÐœÑÐ¹ ÑÐ¿ÐŸÑÐŸÐ±: %s
+
+buildcol.updating_archive_cache:ÐÐ±ÐœÐŸÐ²Ð»ÐµÐœÐžÐµ ÐºÑÑÐ° Ð°ÑÑ
+ÐžÐ²Ð°
+
+buildcol.verbosity:Ð£Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÐµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸÐŒ Ð¿ÑÐŸÐŽÑÐºÑÐžÐž. 0=ÐœÐžÑÐµÐ³ÐŸ, 3=Ð±ÐŸÐ»ÑÑÐŸÐµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ.
+
+
+# -- classinfo.pl --
+
+classinfo.collection:ÐÑÐž Ð¿ÑÐµÐŽÐŸÑÑÐ°Ð²Ð»ÐµÐœÐžÐž ÐžÐŒÐµÐœÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐœÐ°ÐŽÐŸ Ð±ÑÐŽÐµÑ Ð¿ÑÐµÐ¶ÐŽÐµ Ð²ÑÐµÐ³ÐŸ Ð¿ÑÐŸÑÐŒÐŸÑÑÐµÑÑ classinfo.pl Ð² collect/collection-name/perllib/classify. ÐÑÐ»Ðž ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑ ÑÐ°ÐŒ ÐœÐµ ÐœÐ°Ð¹ÐŽÐµÐœ, ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÐŸ Ð±ÑÐŽÐµÑ Ð¿ÑÐŸÑÐŒÐŸÑÑÐµÑÑ ÐŸÐ±ÑÑÑ ÐŽÐžÑÐµÐºÑÐŸÑÐžÑ perllib/classify.
+
+classinfo.desc:ÐÐ°Ð¿ÐžÑÐ°ÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐµ.
+
+classinfo.general_options:ÐÐ±ÑÐžÐµ ÐŸÐ¿ÑÐžÐž ÑÐœÐ°ÑÐ»ÐµÐŽÐŸÐ²Ð°ÐœÑ ÐŸÑ ÑÐŸÐŽÐžÑÐµÐ»ÑÑÐºÐžÑ
+ ÐºÐ»Ð°ÑÑÐŸÐ² ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ°.
+
+classinfo.info:ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ
+
+classinfo.no_classifier_name:ÐÐšÐÐÐÐ: ÐÑ ÐŽÐŸÐ»Ð¶ÐœÑ Ð¿ÑÐµÐŽÐŸÑÑÐ°Ð²ÐžÑÑ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ°.  
+
+classinfo.option_types:ÐÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÑ ÐŒÐŸÐ³ÑÑ ÐžÐŒÐµÑÑ ÐŽÐ²Ð° ÑÐžÐ¿Ð° ÐŸÐ¿ÑÐžÐ¹.
+
+classinfo.params:[ÐŸÐ¿ÑÐžÐž] classifier-name ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ°  
+
+classinfo.passing_options:ÐÐ¿ÑÐžÐž ÐŒÐŸÐ³ÑÑ Ð±ÑÑÑ Ð¿ÐµÑÐµÐŽÐ°ÐœÑ Ð»ÑÐ±ÐŸÐŒÑ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÑ Ð²ÐºÐ»ÑÑÐµÐœÐžÐµÐŒ ÐžÑ
+ Ð² ÐÐ°Ñ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐŸÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» collect.cfg.
+
+classinfo.specific_options:ÐÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÑÐµ ÐŸÐ¿ÑÐžÐž ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÑ Ð² Ð¿ÑÐµÐŽÐµÐ»Ð°Ñ
+ ÑÐ°ÐŒÐŸÐ³ÐŸ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ° Ðž ÐŽÐŸÑÑÑÐ¿ÐœÑ ÑÐŸÐ»ÑÐºÐŸ ÑÑÐŸÐŒÑ ÑÐ¿ÐµÑÐžÑÐžÑÐµÑÐºÐŸÐŒÑ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÑ.
+
+# -- downloadfrom.pl --
+downloadfrom.cache_dir:ÐÐµÑÑÐŸÐœÐ°Ñ
+ÐŸÐ¶ÐŽÐµÐœÐžÐµ ÐºÐ°ÑÐ°Ð»ÐŸÐ³Ð° Ñ ÐºÑÑÐµÐŒ  
+downloadfrom.desc:ÐÐ°Ð³ÑÑÐ·ÐºÐ° ÑÐ°Ð¹Ð»ÐŸÐ² Ñ Ð²ÐœÐµÑÐœÐµÐ³ÐŸ ÑÐµÑÐ²ÐµÑÐ°  
+downloadfrom.download_mode:Ð¢ÐžÐ¿ ÑÐµÑÐ²ÐµÑÐ°, Ñ ÐºÐŸÑÐŸÑÐŸÐ³ÐŸ Ð·Ð°Ð³ÑÑÐ¶Ð°ÑÑ  
+downloadfrom.download_mode.Web:HTTP  
+downloadfrom.download_mode.MediaWiki:ÐÐµÐ±-ÑÐ°Ð¹Ñ MediaWiki  
+downloadfrom.download_mode.OAI:Open Archives Initiative  
+downloadfrom.download_mode.z3950:ÑÐµÑÐ²ÐµÑ Z3950  
+downloadfrom.download_mode.SRW:SearchRetrieve Webservice  
+downloadfrom.incorrect_mode:Ð¿Ð°ÑÐ°ÐŒÐµÑÑ ÑÐµÐ¶ÐžÐŒÐ° Ð·Ð°Ð³ÑÑÐ·ÐºÐž Ð±ÑÐ» ÐœÐµÐºÐŸÑÑÐµÐºÑÐœÑÐŒ  
+downloadfrom.info:ÐÐ°Ð¿ÐµÑÐ°ÑÐ°ÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ ÑÐµÑÐ²ÐµÑÐµ, Ð° ÐœÐµ Ð·Ð°Ð³ÑÑÐ¶Ð°ÑÑ Ñ ÐœÐµÐ³ÐŸ  
+downloadfrom.params:[ÐŸÑÐœÐŸÐ²ÐœÑÐµ ÐŸÐ¿ÑÐžÐž] [ÑÐ¿ÐµÑÐžÐ°Ð»ÑÐœÑÐµ ÐŸÐ¿ÑÐžÐž Ð·Ð°Ð³ÑÑÐ·ÐºÐž]  
+
+# -- downloadinfo.pl --
+
+downloadinfo.desc:ÐÐ°Ð¿ÐµÑÐ°ÑÐ°ÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ ÐŒÐŸÐŽÑÐ»Ðµ Ð·Ð°Ð³ÑÑÐ·ÐºÐž  
+downloadinfo.collection:ÐÐ°ÐŽÐ°ÐœÐžÐµ ÐžÐŒÐµÐœÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ð·Ð°ÑÑÐ°Ð²ÐžÑ downloadinfo.pl ÑÐœÐ°ÑÐ°Ð»Ð° ÑÐŒÐŸÑÑÐµÑÑ Ð² collect/collection-name/perllib/downloaders. ÐÑÐ»Ðž ÐŒÐŸÐŽÑÐ»Ñ ÐœÐµ Ð±ÑÐŽÐµÑ ÑÐ°ÐŒ ÐœÐ°Ð¹ÐŽÐµÐœ, Ð¿ÐŸÐžÑÐº Ð±ÑÐŽÐµÑ Ð¿ÑÐŸÐžÐ·Ð²ÐµÐŽÐµÐœ Ð² ÐŸÑÐœÐŸÐ²ÐœÐŸÐŒ ÐºÐ°ÑÐ°Ð»ÐŸÐ³Ðµ perllib/downloaders.  
+downloadinfo.params:[ÐŸÐ¿ÑÐžÐž] [ÐŒÐŸÐŽÑÐ»Ñ-Ð·Ð°Ð³ÑÑÐ·ÐºÐž]  
+downloadinfo.general_options:ÐÑÐœÐŸÐ²ÐœÑÐµ ÐŸÐ¿ÑÐžÐž ÐœÐ°ÑÐ»ÐµÐŽÑÑÑÑÑ ÐŒÐŸÐŽÑÐ»ÐµÐŒ ÐŸÑ ÐºÐ»Ð°ÑÑÐ°-ÑÐŸÐŽÐžÑÐµÐ»Ñ ÐŒÐŸÐŽÑÐ»ÐµÐ¹ Ð·Ð°Ð³ÑÑÐ·ÐºÐž.  
+downloadinfo.specific_options:ÐÑÐŸÐ±ÑÐµ ÐŸÐ¿ÑÐžÐž ÐŒÐŸÐŽÑÐ»Ðž Ð·Ð°Ð³ÑÑÐ·ÐºÐž ÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÑÑ ÑÐ°ÐŒÐž, Ðž Ð¿ÐŸÑÑÐŸÐŒÑ ÐŸÐœÐž ÐŽÐŸÑÑÑÐ¿ÐœÑ ÑÐŸÐ»ÑÐºÐŸ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÐŸÐŒÑ Ð·Ð°Ð³ÑÑÐ·ÑÐžÐºÑ.  
+downloadinfo.option_types:ÐÐŸÐŽÑÐ»Ðž Ð·Ð°Ð³ÑÑÐ·ÐºÐž ÐŒÐŸÐ³ÑÑ Ð¿ÑÐžÐœÐžÐŒÐ°ÑÑ ÐŽÐ²Ð° Ð²ÐžÐŽÐ° ÐŸÐ¿ÑÐžÐ¹  
+
+# -- explode_metadata_database.pl --
+explode.desc:Ð Ð°ÑÑÐžÑÐžÑÑ Ð±Ð°Ð·Ñ ÐŽÐ°ÐœÐœÑÑ
+ ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÑ
+Ñ
+
+explode.collection:ÐÐŒÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. ÐÐµÐºÐŸÑÐŸÑÑÐµ Ð¿Ð»Ð°Ð³ÐžÐœÑ ÐžÑÑÑ Ð²ÑÐ¿ÐŸÐŒÐŸÐ³Ð°ÑÐµÐ»ÑÐœÑÐµ ÑÐ°Ð¹Ð»Ñ Ð² Ð¿Ð°Ð¿ÐºÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.  
+ 
+explode.document_field:Ð­Ð»ÐµÐŒÐµÐœÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, ÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÑÑÐžÐ¹ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÑÐ°Ð¹Ð»Ð° ÐŽÐ»Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÐºÐŸÑÐŸÑÑÐµ Ð±ÑÐŽÑÑ Ð¿ÐŸÐ»ÑÑÐµÐœÑ Ðž Ð²ÐºÐ»ÑÑÐµÐœÑ Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ.  
+
+explode.document_prefix:ÐÑÐžÑÑÐ°Ð²ÐºÐ° ÐŽÐ»Ñ ÐŒÐµÑÑÐŸÐ¿ÐŸÐ»ÐŸÐ¶ÐµÐœÐžÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° (ÐŽÐ»Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ Ñ ÐŸÐ¿ÑÐžÐµÐ¹ document_field).
+
+explode.document_suffix:Ð¡ÑÑÑÐžÐºÑ ÐŽÐ»Ñ ÐŒÐµÑÑÐŸÐ¿ÐŸÐ»ÐŸÐ¶ÐµÐœÐžÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° (ÐŽÐ»Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ Ñ ÐŸÐ¿ÑÐžÐµÐ¹ document_field).
+
+explode.encoding:ÐÐŸÐŽÐžÑÐŸÐ²ÐºÐ° ÐŽÐ»Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ Ð¿ÑÐž ÑÑÐµÐœÐžÐž ÑÐ°Ð¹Ð»ÐŸÐ² Ð² Ð±Ð°Ð·Ðµ ÐŽÐ°ÐœÐœÑÑ
+
+explode.metadata_set:ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐœÐ°Ð±ÐŸÑÐ° ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ ÑÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ Ð²ÑÐµÑ
+ ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÑ
+
+explode.plugin:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ Ð¿ÑÐž ÑÐ°ÑÑÐžÑÐµÐœÐžÐž
+explode.plugin_options:ÐÐ¿ÑÐžÐž Ð¿ÐµÑÐµÐŽÐ°ÑÐž Ð¿Ð»Ð°Ð³ÐžÐœÑ Ð¿ÐµÑÐµÐŽ ÐŽÐŸ Ð·Ð°Ð¿ÑÑÐºÐ°. ÐÐ¿ÑÐžÑ nmaes ÐŽÐŸÐ»Ð¶ÐœÐ° ÐœÐ°ÑÐ°ÑÑÑÑ Ñ -. ÐÑÐŽÐµÐ»ÑÐœÐ°Ñ ÐŸÐ¿ÑÐžÑ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ Ðž Ð·ÐœÐ°ÑÐµÐœÐžÐµ Ñ Ð¿ÑÐŸÐ±ÐµÐ»ÐŸÐŒ.  
+explode.use_collection_plugin_options:ÐÑÐŸÑÑÐžÑÐµ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐŸÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ðž ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ ÐŸÐ¿ÑÐžÐž ÐŽÐ»Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÑÑ
+ Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐ². Ð¢ÑÐµÐ±ÑÐµÑ ÐŸÐ¿ÑÐžÑ -collection. 
+ÐÐµ ÐŒÐŸÐ¶ÐµÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°Ðœ ÐŽÐ»Ñ -plugin_options.  
+explode.params:[ÐŸÐ¿ÑÐžÐž] ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÑÐ°Ð¹Ð»Ð°
+explode.records_per_folder:ÐÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ Ð·Ð°Ð¿ÐžÑÐµÐ¹ ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ¹ Ð¿ÐŸÐŽÐ¿Ð°Ð¿ÐºÐž  
+
+# -- replace_srcdoc_with_html.pl --
+srcreplace.desc:ÐÐ°ÐŒÐµÐœÐžÑÑ ÐžÑÑ
+ÐŸÐŽÐœÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ, Ð³ÐµÐœÐµÑÐžÑÑÐµÐŒÑÐŒ HTML ÑÐ°Ð¹Ð»ÐŸÐŒ Ð¿ÑÐž Ð¿ÐµÑÐµÑÑÑÐŸÐ¹ÐºÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž  
+srcreplace.params:[ÐŸÐ¿ÑÐžÐž] ÐžÐŒÑ ÑÐ°Ð¹Ð»Ð°  
+srcreplace.plugin:ÐÐŸÐŽÑÐ»Ñ Ð±ÑÐŽÐµÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑÑÑ ÐŽÐ»Ñ Ð¿ÑÐµÐŸÐ±ÑÐ°Ð·ÐŸÐ²Ð°ÐœÐžÑ ÐžÑÑ
+ÐŸÐŽÐœÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°  
+
+# -- exportcol.pl --
+
+exportcol.out:ÐÐŒÑ ÑÐ°Ð¹Ð»Ð° ÐžÐ»Ðž ÐžÐœÐŽÐµÐºÑ ÐŽÐ»Ñ Ð¿ÐµÑÐ°ÑÐž ÑÑÐ°ÑÑÑÐ° Ð¿ÑÐŸÐŽÑÐºÑÐžÐž Ð².
+exportcol.cddir:ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž, ÐºÑÐŽÐ° ÑÐºÑÐ¿ÐŸÑÑÐžÑÑÐµÑÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ ÐºÐŸÐŒÐ¿Ð°ÐºÑÐœÐŸÐ³ÐŸ ÐŽÐžÑÐºÐ°.  
+exportcol.cdname:ÐÐŒÑ CD-ROM - ÑÑÐŸ ÑÐŸ, ÑÑÐŸ Ð¿ÐŸÑÐ²ÐžÑÑÑ Ð² ÑÑÐ°ÑÑÐŸÐ²ÐŸÐŒ ÐŒÐµÐœÑ, ÐºÐ°Ðº ÑÐŸÐ»ÑÐºÐŸ CD-ROM ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœ.
+exportcol.desc:Ð¡ÐºÑÐžÐ¿Ñ PERL ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°Ð»ÑÑ ÐŽÐ»Ñ ÑÐºÑÐ¿ÐŸÑÑÐ° ÐŸÐŽÐœÐŸÐ¹ ÐžÐ»Ðž Ð±ÐŸÐ»ÐµÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹ Ð² Windows CD-ROM.
+exportcol.noinstall:Ð¡ÐŸÐ·ÐŽÐ°ÑÑ ÑÐ°ÐºÐŸÐ¹ CD-ROM, Ñ ÐºÐŸÑÐŸÑÐŸÐ³ÐŸ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐ° ÑÐ°Ð±ÐŸÑÐ°ÐµÑ ÐœÐ°Ð¿ÑÑÐŒÑÑ, Ð° ÐœÐ° Ñ
+ÐŸÑÑ-ÐºÐŸÐŒÐ¿ÑÑÑÐµÑ ÐœÐžÑÐµÐ³ÐŸ ÐœÐµ ÑÑÑÐ°ÐœÐ°Ð²Ð»ÐžÐ²Ð°ÐµÑÑÑ.  
+exportcol.params:[ÐŸÐ¿ÑÐžÐž] ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ-ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž1 ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ-ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž2...  
+exportcol.coll_not_found:ÐÐµ Ð¿ÑÐžÐœÐžÐŒÐ°ÑÑ Ð²ÐŸ Ð²ÐœÐžÐŒÐ°ÐœÐžÐµ ÐœÐµÐŽÐµÐ¹ÑÑÐ²ÐžÑÐµÐ»ÑÐœÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ %s:ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐœÐµ ÐœÐ°Ð¹ÐŽÐµÐœÐ° Ð² %s.
+exportcol.coll_dirs_not_found:ÐÐµ Ð¿ÑÐžÐœÐžÐŒÐ°ÑÑ Ð²ÐŸ Ð²ÐœÐžÐŒÐ°ÐœÐžÐµ ÐœÐµÐŽÐµÐ¹ÑÑÐ²ÐžÑÐµÐ»ÑÐœÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ %s: ÐŸÐŽÐœÐ° ÐžÐ· ÑÐ»ÐµÐŽÑÑÑÐžÑ
+ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐ¹ ÐœÐµ ÐœÐ°Ð¹ÐŽÐµÐœÐ°.
+exportcol.fail:exportcol.pl ÐœÐµ ÑÐŽÐ°Ð»ÑÑ:
+exportcol.no_valid_colls:ÐÐžÐºÐ°ÐºÐžÑ
+ Ð¿ÑÐžÐ³ÐŸÐŽÐœÑÑ
+ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹, ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÑÑ
+ ÐŽÐ»Ñ ÑÐºÑÐ¿ÐŸÑÑÐ°.
+exportcol.couldnt_create_dir:ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÑÐŸÐ·ÐŽÐ°ÑÑ ÐŽÐžÑÐµÐºÑÐŸÑÐžÑ %s.
+exportcol.couldnt_create_file:ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÑÐŸÐ·ÐŽÐ°ÑÑ %s.
+exportcol.instructions:Ð§ÑÐŸÐ±Ñ ÑÐŸÐ·ÐŽÐ°ÑÑ ÑÐ°ÐŒÐŸÑÑÑÐ°ÐœÐ°Ð²Ð»ÐžÐ²Ð°ÑÑÐžÐ¹ÑÑ CD-ROM ÐŽÐ»Ñ Windows, Ð·Ð°Ð¿ÐžÑÐžÑÐµ ÐœÐ° CD-ROM ÑÐŸÐŽÐµÑÐ¶ÐžÐŒÐŸÐµ ÑÑÐŸÐ¹ Ð¿Ð°Ð¿ÐºÐž.
+exportcol.non_exist_files:ÐÐŽÐžÐœ ÐžÐ»Ðž Ð±ÐŸÐ»ÐµÐµ ÐžÐ· ÑÐ»ÐµÐŽÑÑÑÐžÑ
+ ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ² Ðž ÐŽÐžÑÐµÐºÑÐŸÑÐžÐ¹ ÐœÐµ ÑÑÑÐµÑÑÐ²ÑÐµÑ:
+exportcol.success:exportcol.pl ÑÐ»ÐµÐŽÐŸÐ²Ð°Ð²ÑÐžÐ¹:
+exportcol.output_dir:Ð­ÐºÑÐ¿ÐŸÑÑÐžÑÑÐµÐŒÑÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž (%s) ÐœÐ°Ñ
+ÐŸÐŽÑÑÑÑ Ð² %s.
+exportcol.export_coll_not_installed:Ð€ÑÐœÐºÑÐžÐŸÐœÐ°Ð»ÑÐœÑÐµ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÐž âÐ­ÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ Ð² CD-ROMâ ÐœÐµ Ð±ÑÐ»Ðž ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÑ.
+
+# -- import.pl --
+
+import.archivedir:ÐÐŽÐµ Ð·Ð°ÐºÐ°ÐœÑÐžÐ²Ð°ÐµÑÑÑ ÐºÐŸÐœÐ²ÐµÑÑÐžÑÐŸÐ²Ð°ÐœÐœÑÐ¹ ÐŒÐ°ÑÐµÑÐžÐ°Ð» Ð·Ð°ÐºÐ°ÐœÑÐžÐ²Ð°ÐµÑÑÑ.
+
+import.manifest:XML-ÑÐ°Ð¹Ð», ÐºÐŸÑÐŸÑÑÐ¹ ÑÑÐŸÑÐœÑÐµÑ, ÐºÐ°ÐºÐžÐµ ÐžÐŒÐµÐœÐœÐŸ ÑÐ°Ð¹Ð»Ñ ÐŽÐŸÐ»Ð¶ÐœÑ Ð±ÑÑÑ ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÑ. ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ Ð²ÐŒÐµÑÑÐŸ ÑÐµÐºÑÑÑÐžÐ²ÐœÐŸÐ³ÐŸ ÐŸÐ±Ñ
+ÐŸÐŽÐ° Ð¿Ð°Ð¿ÐºÐž ÐžÐŒÐ¿ÐŸÑÑÐ°, Ð² ÐŸÑÐœÐŸÐ²ÐœÐŸÐŒ, ÐŽÐ»Ñ ÐžÐœÐºÑÐµÐŒÐµÐœÑÐœÐŸÐ¹ ÑÐ±ÐŸÑÐºÐž.  
+
+import.cannot_open_stats_file:ÐÐ ÐÐÐ£ÐÐ ÐÐÐÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐŸÑÐºÑÑÑÑ ÑÐ°Ð¹Ð» ÑÐŸÑÑÐŸÑÐœÐžÑ %s.
+
+import.cannot_open_fail_log:ÐÐšÐÐÐÐ: Ð ÐµÐ³ÐžÑÑÑÐ°ÑÐžÐŸÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» ÐœÐµ ÐŒÐŸÐ³ Ð±ÑÑÑ ÐŸÑÐºÑÑÑ %s
+
+import.cannot_sort:ÐÐ ÐÐÐ£ÐÐ ÐÐÐÐÐÐÐ: import.pl ÐœÐµ ÐŒÐŸÐ¶ÐµÑ ÑÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ, ÐºÐŸÐ³ÐŽÐ° ÑÐ°Ð·ÐŒÐµÑ Ð³ÑÑÐ¿Ð¿Ñ> 1. sortmeta ÐÐ¿ÑÐžÑ ÐŒÐµÑÐ°ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž Ð±ÑÐŽÐµÑ ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÑÑÑÑ.
+
+import.collectdir:ÐÐžÑÐµÐºÑÐŸÑÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.  
+
+import.complete:ÐÐŒÐ¿ÐŸÑÑ Ð·Ð°Ð²ÐµÑÑÐµÐœ
+
+import.debug:ÐÐ°Ð¿ÐžÑÐ°ÑÑ ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐœÑÐ¹ ÑÐµÐºÑÑ Ð² STDOUT.  
+
+import.desc:Ð¡ÐºÑÐžÐ¿Ñ PERL, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÐ¹ ÐŽÐ»Ñ ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ ÑÐ°Ð¹Ð»ÐŸÐ² Ð² ÑÐŸÑÐŒÐ°Ñ GML, Ð³ÐŸÑÐŸÐ² ÐŽÐ»Ñ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ.  
+
+import.faillog:ÐÐµÑÐŽÐ°ÑÐœÐ°Ñ ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÑ ÐžÐŒÐµÐœÐž ÑÐ°Ð¹Ð»Ð°. Ð­ÑÐŸÑ Ð¶ÑÑÐœÐ°Ð» ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÐž Ð¿ÐŸÐ»ÑÑÐ°ÐµÑ ÐžÐŒÐµÐœÐ° ÑÐ°Ð¹Ð»Ð° Ð»ÑÐ±ÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ², ÐºÐŸÑÐŸÑÑÐµ ÐœÐµ ÐŒÐŸÐ³ÑÑ Ð±ÑÑÑ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÐœÑ.
+
+import.groupsize:Ð§ÐžÑÐ»ÐŸ ÐžÐŒÐ¿ÐŸÑÑÐžÑÑÐµÐŒÑÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÐŽÐ»Ñ Ð³ÑÑÐ¿Ð¿ÐžÑÐŸÐ²ÐºÐž Ð² ÐŸÐŽÐžÐœ XML ÑÐ°Ð¹Ð».
+
+import.gzip:ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ gzip ÐŽÐ»Ñ ÑÐ¶Ð°ÑÐžÑ ÑÐµÐ·ÑÐ»ÑÑÐžÑÑÑÑÐžÑ
+ xml ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² (ÐœÐµ Ð·Ð°Ð±ÑÐŽÑÑÐµ Ð²ÐºÐ»ÑÑÐžÑÑ ZIPPlug Ð² ÐÐ°Ñ ÑÐ¿ÐžÑÐŸÐº Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐ², ÐºÐŸÐ³ÐŽÐ° ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÑÐŸÐ·ÐŽÐ°ÐµÑÑÑ ÐžÐ· ÑÐ¶Ð°ÑÑÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ²).  
+
+import.importdir:ÐÐŽÐµ ÐœÐ°Ñ
+ÐŸÐŽÐžÑÑÑ ÐžÑÑ
+ÐŸÐŽÐœÑÐ¹ ÐŒÐ°ÑÐµÑÐžÐ°Ð».
+
+import.incremental:ÐÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ ÑÐŸÐ»ÑÐºÐŸ ÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ, ÐºÐŸÑÐŸÑÑÐµ ÐœÐŸÐ²ÐµÐµ (Ð¿ÐŸ Ð²ÑÐµÐŒÐµÐœÐœÐŸÐ¹ ÐŸÑÐŒÐµÑÐºÐµ), ÑÐµÐŒ ÑÐµÐºÑÑÐžÐµ ÑÐ°Ð¹Ð»Ñ Ð² Ð°ÑÑ
+ÐžÐ²Ðµ. ÐÐºÐ»ÑÑÐ°ÐµÑ -keepold.  
+
+import.keepold:ÐÐµ Ð±ÑÐŽÐµÑ ÑÐœÐžÑÑÐŸÐ¶Ð°ÑÑ ÑÐµÐºÑÑÐµÐµ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ Ð°ÑÑ
+ÐžÐ²ÐœÐŸÐ¹ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž.  
+
+import.maxdocs:ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÑÐžÑÐ»ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÐŽÐ»Ñ ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ.
+
+import.no_import_dir:ÐÑÐžÐ±ÐºÐ°: ÐºÐ°ÑÐ°Ð»ÐŸÐ³ ÐžÐŒÐ¿ÐŸÑÑÐ° (%s) ÐœÐµ ÐœÐ°Ð¹ÐŽÐµÐœ.  
+
+import.no_plugins_loaded:ÐÐšÐÐÐÐ: ÐÐžÐºÐ°ÐºÐžÐµ Ð¿Ð»Ð°Ð³ÐžÐœÑ ÐœÐµ Ð·Ð°Ð³ÑÑÐ¶ÐµÐœÑ.
+
+import.OIDtype:ÐÐµÑÐŸÐŽ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ Ð¿ÑÐž Ð³ÐµÐœÐµÑÐžÑÐŸÐ²Ð°ÐœÐžÐž ÑÐœÐžÐºÐ°Ð»ÑÐœÑÑ
+ ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑÐŸÐ² ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°.  
+import.OIDtype.hash:Ð¥ÐµÑÐžÑÐŸÐ²Ð°ÐœÐžÐµ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÑ ÑÐ°Ð¹Ð»Ð°. ÐÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° Ð±ÑÐŽÐµÑ ÑÐµÐŒ Ð¶Ðµ ÑÐ°ÐŒÑÐŒ ÐºÐ°Ð¶ÐŽÑÐ¹ ÑÐ°Ð·, ÐºÐŸÐ³ÐŽÐ° ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐžÐŒÐ¿ÐŸÑÑÐžÑÑÐµÑÑÑ.  
+
+import.OIDtype.incremental:ÐÑÐŸÑÑÐŸÐ¹ Ð¿ÐŸÐŽÑÑÐµÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÐºÐŸÑÐŸÑÑÐ¹ ÑÐ²Ð»ÑÐµÑÑÑ Ð·ÐœÐ°ÑÐžÑÐµÐ»ÑÐœÐŸ Ð±ÐŸÐ»ÐµÐµ Ð±ÑÑÑÑÑÐŒ, ÑÐµÐŒ "Ñ
+ÐµÑÐžÑÐŸÐ²Ð°ÐœÐžÐµ". Ð­ÑÐŸ ÐœÐµ Ð³Ð°ÑÐ°ÐœÑÐžÑÑÑÑ ÑÐŸÐ³ÐŸ, ÑÑÐŸ Ð²ÑÐµÐ³ÐŽÐ° Ð±ÑÐŽÐµÑ ÐœÐ°Ð·ÐœÐ°ÑÐµÐœ ÑÐŸÑ Ð¶Ðµ ÑÐ°ÐŒÑÐ¹ ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑ Ðº ÐŽÐ°ÐœÐœÐŸÐŒÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ, Ñ
+ÐŸÑÑ Ðž ÐœÐµ Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ Ð¿ÐŸÑÐ»ÐµÐŽÑÑÑÐžÐŒ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒ Ð±ÑÑÑ ÐŽÐŸÐ±Ð°Ð²Ð»ÐµÐœÐœÑÐŒÐž Ðº ÑÑÑÐµÑÑÐ²ÑÑÑÐžÐŒ  xml Ð°ÑÑ
+ÐžÐ²Ð°ÐŒ.  
+
+import.OIDtype.assigned:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑ 'D' Ð¿Ð»ÑÑ Ð·ÐœÐ°ÑÐµÐœÐžÐµ Ð² Ð¿ÐŸÐ»Ðµ dc.Identifier Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑÐ° ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°. ÐÐŸÐ»Ðµ dc.Identifiers ÐŽÐŸÐ»Ð¶ÐœÐŸ Ð±ÑÑÑ ÐŸÐŽÐœÐŸÐ·ÐœÐ°ÑÐœÑÐŒ. ÐÑÐ»Ðž dc.Identifier ÐœÐµ Ð·Ð°Ð¿ÐŸÐ»ÐœÐµÐœÐŸ ÐŽÐ»Ñ ÐŽÐ°ÐœÐœÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°, Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ Ð·Ð°ÐŒÐµÐœÑ Ð±ÑÐŽÐµÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°Ðœ hash id.  
+
+import.OIDtype.dirname:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑ 'J' Ð¿Ð»ÑÑ ÑÐŸÐŽÐžÑÐµÐ»ÑÑÐºÑÑ Ð¿Ð°Ð¿ÐºÑ as the identifier. ÐÐ»Ñ ÑÑÐŸÐ³ÐŸ Ð² ÐºÐ°Ð¶ÐŽÐŸÐ¹ Ð¿Ð°Ð¿ÐºÐµ ÐŽÐŸÐ»Ð¶ÐµÐœ Ð±ÑÑÑ ÑÐŸÐ»ÑÐºÐŸ ÐŸÐŽÐžÐœ ÑÐ°Ð¹Ð», Ð° ÐµÐµ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐŽÐŸÐ»Ð¶ÐœÐŸ Ð±ÑÑÑ ÐŸÐŽÐœÐŸÐ·ÐœÐ°ÑÐœÑÐŒ. E.g. import/b13as/h15ef/page.html Ð¿ÐŸÐ»ÑÑÐžÑ ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑ Jh15ef.  
+
+import.OIDmetadata:Ð£ÐºÐ°Ð·ÑÐ²Ð°ÐµÑ ÑÐ»ÐµÐŒÐµÐœÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, ÐºÐŸÑÐŸÑÑÐ¹ ÑÐŸÐŽÐµÑÐ¶ÐžÑ ÑÐœÐžÐºÐ°Ð»ÑÐœÑÐ¹ ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°, ÐŽÐ»Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ Ñ -OIDtype=assigned.  
+
+import.saveas:Ð ÐºÐ°ÐºÐŸÐŒ ÑÐŸÑÐŒÐ°ÑÐµ Ð³ÐµÐœÐµÑÐžÑÐŸÐ²Ð°ÑÑ Ð°ÑÑ
+ÐžÐ². ÐÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ GA.  
+
+import.out:ÐÐŒÑ ÑÐ°Ð¹Ð»Ð° ÐžÐ»Ðž ÐžÐœÐŽÐµÐºÑ ÐŽÐ»Ñ Ð·Ð°Ð¿ÐžÑÐž Ð²ÑÑ
+ÐŸÐŽÐœÐŸÐ³ÐŸ ÑÑÐ°ÑÑÑÐ° Ð².
+
+import.params:[ÐŸÐ¿ÑÐžÐž] ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ-ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž1 ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ-ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž2...  
+
+import.removeold:Ð£ÐŽÐ°Ð»ÐžÑ ÑÑÐ°ÑÐŸÐµ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ Ð°ÑÑ
+ÐžÐ²ÐœÐŸÐ¹ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž.  
+
+import.removing_archives:Ð£ÐŽÐ°Ð»ÐµÐœÐžÐµ ÑÐµÐºÑÑÐµÐ³ÐŸ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÑ Ð°ÑÑ
+ÐžÐ²ÐœÐŸÐ¹ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž...
+
+import.removing_tmpdir:Ð£ÐŽÐ°Ð»ÐµÐœÐžÐµ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÑ Ð¿Ð°Ð¿ÐºÐž "tmp" ÑÑÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž...  
+
+import.reversesort:Ð¡ÐŸÑÑÐžÑÐŸÐ²ÐºÐ° Ð² ÐŸÐ±ÑÐ°ÑÐœÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ. ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ Ñ ÐŸÐ¿ÑÐžÐµÐ¹ -sortmeta  
+
+import.site:Ð¡Ð°Ð¹Ñ ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ° ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŒÐž Ð² (ÐŽÐ»Ñ ÑÑÑÐ°ÐœÐŸÐ²ÐºÐž ÐÑÐžÐœÑÑÐŸÑÐœ 3 Ð²ÐµÑÑÐžÐž)  
+
+import.sortmeta:Ð¡ÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð² Ð°Ð»ÑÐ°Ð²ÐžÑÐœÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. Ð ÐµÐ·ÑÐ»ÑÑÐ°ÑÑ Ð¿ÐŸÐžÑÐºÐ° Ð±ÑÐ»ÐµÐ²ÑÑ
+ Ð·Ð°Ð¿ÑÐŸÑÐŸÐ² Ð±ÑÐŽÑÑ Ð²ÑÐŽÐ°ÐœÑ Ð² ÑÑÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ. Ð­ÑÐŸ Ð±ÑÐŽÐµÑ Ð±Ð»ÐŸÐºÐžÑÐŸÐ²Ð°ÐœÐŸ, ÐµÑÐ»Ðž ÑÐ°Ð·ÐŒÐµÑ Ð³ÑÑÐ¿Ð¿Ñ Ð±ÐŸÐ»ÑÑÐµ ÐµÐŽÐžÐœÐžÑÑ.  
+
+import.statsfile:ÐÐŒÑ ÑÐ°Ð¹Ð»Ð° ÐžÐ»Ðž ÐžÐœÐŽÐµÐºÑ ÐŽÐ»Ñ Ð·Ð°Ð¿ÐžÑÐž ÑÑÐ°ÑÐžÑÑÐžÐºÐž ÐžÐŒÐ¿ÐŸÑÑÐ° Ð².
+
+import.stats_backup:ÐÐŒÐµÑÑÐŸ ÑÑÐŸÐ³ÐŸ Ð±ÑÐŽÐµÑ Ð·Ð°Ð¿ÐžÑÑÐ²Ð°ÑÑ stats Ð² STDERR.
+
+import.verbosity:Ð£Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÐµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸÐŒ Ð¿ÑÐŸÐŽÑÐºÑÐžÐž. 0=ÐœÐžÑÐµÐ³ÐŸ, 3=Ð±ÐŸÐ»ÑÑÐŸÐµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ.
+
+# -- schedule.pl --
+schedule.deleted:Ð Ð°ÑÐ¿ÐžÑÐ°ÐœÐœÐŸÐµ Ð²ÑÐ¿ÐŸÐ»ÐœÐµÐœÐžÐµ ÑÐŽÐ°Ð»ÐµÐœÐŸ ÐŽÐ»Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž  
+schedule.scheduled:ÐÑÐ¿ÐŸÐ»ÐœÐµÐœÐžÐµ ÑÑÐµÐœÐ°ÑÐžÑ, ÑÐŸÐ·ÐŽÐ°ÐœÐœÐŸÐ³ÐŸ ÐŽÐ»Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž  
+schedule.cron:Ð Ð°ÑÐ¿ÐžÑÐ°ÐœÐœÐŸÐµ Ð²ÑÐ¿ÐŸÐ»ÐœÐµÐœÐžÐµ - ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐœÐŸÐµ ÐŽÐ»Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž  
+schedule.params:[ÐŸÐ¿ÑÐžÐž]  
+schedule.error.email:-email ÑÑÐµÐ±ÑÐµÑÑÑ -smtp -toaddr Ðž -fromaddr ÐŽÐŸÐ»Ð¶ÐœÑ Ð±ÑÑÑ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÑ.  
+schedule.error.importbuild:-import Ðž -build ÐŽÐŸÐ»Ð¶ÐœÑ Ð±ÑÑÑ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÑ.  
+schedule.error.colname:ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐžÐŒÑ -colname ÐŽÐŸÐ»Ð¶ÐœÐŸ Ð±ÑÑÑ ÑÐºÐ°Ð·Ð°ÐœÐŸ.  
+schedule.gli:ÐÐ°Ð¿ÑÑÐº ÐžÐ· ÐÐžÐ±Ð»ÐžÐŸÑÐµÑÐœÐŸÐ³ÐŸ ÐžÐœÑÐµÑÑÐµÐ¹ÑÐ° - GLI  
+schedule.frequency:ÐÐ°Ðº ÑÐ°ÑÑÐŸ Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐž Ð¿ÐŸÐ²ÑÐŸÑÐœÐŸ Ð¿ÐµÑÐµÑÑÑÐŸÐžÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ  
+schedule.frequency.hourly:ÐÐµÑÐµÑÑÑÐŸÐžÑÑ ÐºÐ°Ð¶ÐŽÑÐ¹ ÑÐ°Ñ  
+schedule.frequency.daily:ÐÐµÑÐµÑÑÑÐŸÐžÑÑ ÐºÐ°Ð¶ÐŽÑÐ¹ ÐŽÐµÐœÑ  
+schedule.frequency.weekly:ÐÐµÑÐµÑÑÑÐŸÐžÑÑ ÐºÐ°Ð¶ÐŽÑÑ ÐœÐµÐŽÐµÐ»Ñ  
+schedule.action:ÐÐ°Ðº ÐœÐ°ÑÑÑÐŸÐžÑÑ Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐŸÐµ Ð¿ÐŸÐ²ÑÐŸÑÐœÐŸÐµ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÐµ  
+schedule.action.add:Ð Ð°ÑÐ¿ÐžÑÐ°ÑÑ Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐŸÐµ Ð¿ÐŸÐ²ÑÐŸÑÐœÐŸÐµ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÐµ  
+schedule.action.update:ÐÐ±ÐœÐŸÐ²ÐžÑÑ ÑÑÑÐµÑÑÐ²ÑÑÑÐµÐµ ÑÐ°ÑÐ¿ÐžÑÐ°ÐœÐžÐµ  
+schedule.action.delete:Ð£ÐŽÐ°Ð»ÐžÑÑ ÑÑÑÐµÑÑÐ²ÑÑÑÐµÐµ ÑÐ°ÑÐ¿ÐžÑÐ°ÐœÐžÐµ  
+schedule.email:ÐÐŸÑÐ»Ð°ÑÑ ÑÐ²ÐµÐŽÐŸÐŒÐ»ÐµÐœÐžÐµ Ð¿ÐŸ email  
+schedule.schedule:ÐÑÐ±ÐµÑÐžÑÐµ ÐŽÐ»Ñ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ Ð·Ð°Ð¿Ð»Ð°ÐœÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐ³ÐŸ Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐŸÐ³ÐŸ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ  
+schedule.colname:ÐÐŒÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐŽÐ»Ñ ÐºÐŸÑÐŸÑÐŸÐ³ÐŸ Ð·Ð°Ð¿Ð»Ð°ÐœÐžÑÐŸÐ²Ð°ÐœÐŸ ÑÐ°ÑÐ¿ÐžÑÐ°ÐœÐžÐµ  
+schedule.import:ÐÐŸÐŒÐ°ÐœÐŽÐ° ÐžÐŒÐ¿ÐŸÑÑÐ° ÐŽÐŸÐ»Ð¶ÐœÐ° Ð±ÑÑÑ Ð²ÐºÐ»ÑÑÐµÐœÐ° Ð² ÑÐ°ÑÐ¿ÐžÑÐ°ÐœÐžÐµ  
+schedule.build:ÐÐŸÐŒÐ°ÐœÐŽÐ° buildcol Ð±ÑÐŽÐµÑ Ð²ÐºÐ»ÑÑÐµÐœÐ° Ð² ÑÐ°ÑÐ¿ÐžÑÐ°ÐœÐžÐµ  
+schedule.toaddr:ÐÐŽÑÐµÑ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ ÐÐŸÐŒÑ ÐŸÑÐ¿ÑÐ°Ð²Ð»ÑÑÑ ÑÐ²ÐµÐŽÐŸÐŒÐ»ÐµÐœÐžÑ ÐŸ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÐž  
+schedule.toaddr.default:Ð£ÐºÐ°Ð¶ÐžÑÐµ Ð°ÐŽÑÐµÑÐ° ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐ¹ Ð² ÐŒÐµÐœÑ Ð€Ð°Ð¹Ð»-> ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž  
+schedule.fromaddr:Email ÐŸÑÐ¿ÑÐ°Ð²ÐžÑÐµÐ»Ñ  
+schedule.fromaddr.default:ÐÐ¿ÑÐµÐŽÐµÐ»ÐžÑÐµ ÐºÑÐŸ Ð·Ð°ÐœÐžÐŒÐ°ÐµÑÑÑ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ð² main.cfg  
+schedule.smtp:ÐÐŸÑÑÐŸÐ²ÑÐ¹ ÑÐµÑÐ²ÐµÑ sendmail, ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÑÐ¹ ÐŽÐ»Ñ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ  
+schedule.smtp.default:Ð£ÐºÐ°Ð¶ÐžÑÐµ MailServer Ð² main.cfg  
+schedule.out:Ð£ÐºÐ°Ð¶ÐžÑÐµ ÐžÐŒÑ ÑÐ°Ð¹Ð»Ð° ÐºÑÐŽÐ° Ð¿ÐµÑÐ°ÑÐ°ÑÑ ÑÑÐ°ÑÑÑ.  
+# -- export.pl --
+
+export.exportdir:ÐÐŽÐµ ÐœÐ°Ñ
+ÐŸÐŽÐžÑÑÑ ÑÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐœÑÐ¹ ÐŒÐ°ÑÐµÑÐžÐ°Ð».
+
+export.cannot_open_stats_file:ÐÐÐÐÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐŸÑÐºÑÑÑÑ ÑÐ°Ð¹Ð» ÑÑÐ°ÑÑ %s
+
+export.cannot_open_fail_log:ÐÐšÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐŸÑÐºÑÑÑÑ ÑÐ°Ð¹Ð» Ð»ÐŸÐ³ %s
+
+export.cannot_sort:ÐÐÐÐÐÐÐÐ: export.pl ÐœÐµ ÐŒÐŸÐ¶ÐµÑ ÑÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ, ÐµÑÐ»Ðž ÑÐ°Ð·ÐŒÐµÑ Ð³ÑÑÐ¿Ð¿Ñ > 1. ÐÐµÑÐ°-ÐŸÐ¿ÑÐžÑ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÑ Ð±ÑÐŽÐµÑ Ð¿ÑÐŸÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÐœÐ°.
+
+export.collectdir:ÐÑÑÑ Ðº ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž  ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž "collect".  
+
+export.complete:Ð­ÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐµ ÐŸÐºÐŸÐœÑÐµÐœÐœÐŸ.
+
+export.debug:ÐÑÐ²ÐµÑÑÐž ÑÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐœÑÐ¹ ÑÐµÐºÑÑ Ð² STDOUT (ÐŽÐ»Ñ ÑÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ Ð² GreenstoneXML).  
+
+export.desc:PERL ÑÐºÑÐžÐ¿Ñ ÐŽÐ»Ñ ÑÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ ÑÐ°Ð¹Ð»ÐŸÐ² Ð² ÐÑÐžÐœÑÑÐŸÐœ Ð² ÐŽÑÑÐ³ÐŸÐ¹ ÑÐŸÑÐŒÐ°Ñ.  
+
+export.faillog:ÐÐµÑÐŽÐ°Ð»ÐŸÑÑ Ð·Ð°Ð¿ÐžÑÐ°ÑÑ Ð² Ð»ÐŸÐ³ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÑÐ°Ð¹Ð»Ð°. Ð­ÑÐŸÑ Ð»ÐŸÐ³ Ð·Ð°Ð¿ÐžÑÑÐ²Ð°ÐµÑ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÑÐ°Ð¹Ð»ÐŸÐ², ÐºÐŸÑÐŸÑÑÐµ ÐœÐµ ÑÐŒÐŸÐ³Ð»Ðž Ð±ÑÑÑ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÐœÐœÑ. (ÐÑÑÑ Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ: collectdir/collect/collname/etc/fail.log)  
+
+export.groupsize:Ð§ÐžÑÐ»ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÐŽÐ»Ñ Ð³ÑÑÐ¿Ð¿ÐžÑÐŸÐ²ÐºÐž Ð² ÐŸÐŽÐœÐŸÐŒ XML ÑÐ°Ð¹Ð»Ðµ.  
+
+export.gzip:ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑ gzip ÐŽÐ»Ñ ÐºÐŸÐŒÐ¿ÑÐžÐŒÐžÑÐŸÐ²Ð°ÐœÐžÑ ÑÐµÐ·ÑÐ»ÑÑÐžÑÑÑÑÐžÑ
+ xml ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² (ÐœÐµ Ð·Ð°Ð±ÑÐŽÑÑÐµ Ð²ÐºÐ»ÑÑÐžÑÑ ZIPPlug Ð² ÑÐ¿ÐžÑÐŸÐº Ð²Ð°ÑÐžÑ
+ Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐ² Ð¿ÑÐž ÐºÐŸÐœÑÑÑÑÐžÑÐŸÐ²Ð°ÐœÐžÐž ÐžÐ· ÐºÐŸÐŒÐ¿ÑÐžÐŒÐžÑÐŸÐ²Ð°ÐœÐžÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ²).  
+
+export.importdir:ÐÐŽÐµ ÐœÐ°Ñ
+ÐŸÐŽÐžÑÑÑ ÐžÑÑ
+ÐŸÐŽÐœÑÐ¹ ÐŒÐ°ÑÐµÑÐžÐ°Ð».
+
+export.keepold:ÐÐµ ÑÐœÐžÑÑÐŸÐ¶ÐžÑ ÐœÐ°ÑÑÐŸÑÑÐµÐµ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ ÑÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐ¹ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž.  
+
+export.maxdocs:ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÑÐžÑÐ»ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², Ð¿ÑÐµÐŽÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐœÑÑ
+ ÐŽÐ»Ñ ÑÐºÑÐ¿ÐŸÑÑÐ°.  
+
+export.listall:ÐÐŸÐºÐ°Ð·Ð°ÑÑ Ð²ÑÐµ ÑÐŸÑÐŒÐ°ÑÑ ÑÐŸÑ
+ÑÐ°ÐœÐµÐœÐžÑ  
+
+export.saveas:Ð ÐºÐ°ÐºÐŸÐŒ ÑÐŸÑÐŒÐ°ÑÐµ ÑÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ.  
+
+export.saveas.DSpace:Ð€ÐŸÑÐŒÐ°Ñ DSpace Archive.  
+
+export.saveas.GreenstoneMETS:METS ÑÐŸÑÐŒÐ°Ñ Ñ Ð¿ÑÐžÐŒÐµÐœÐµÐœÐžÐµÐŒ Ð¿ÑÐŸÑÐžÐ»Ñ ÐÑÐžÐœÑÑÐŸÑÐœ.  
+export.saveas.FedoraMETS:METS ÑÐŸÑÐŒÐ°Ñ Ñ Ð¿ÑÐžÐŒÐµÐœÐµÐœÐžÐµÐŒ Ð¿ÑÐŸÑÐžÐ»Ñ Fedora.  
+
+export.saveas.GreenstoneXML:Ð€ÐŸÑÐŒÐ°Ñ XML Ð°ÑÑ
+ÐžÐ²Ð° ÐÑÐžÐœÑÑÐŸÑÐœ  
+
+export.saveas.MARCXML:Ð€ÐŸÑÐŒÐ°Ñ MARC XML (XML-Ð²ÐµÑÑÐžÑ MARC 21)  
+
+export.out:ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ ÑÐ°Ð¹Ð»Ð° ÐžÐ»Ðž ÐµÐ³ÐŸ ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑ, Ð² ÐºÐŸÑÐŸÑÑÐ¹ Ð±ÑÐŽÐµÑ Ð·Ð°Ð¿ÐžÑÐ°Ðœ ÑÑÐ°ÑÑÑ Ð²ÑÐ²ÐŸÐŽÐ°.
+
+export.params:[ÐŸÐ¿ÑÐžÐž] ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ-ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž1 ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ-ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž2...  
+
+export.removeold:Ð£ÐŽÐ°Ð»ÐžÑ ÑÑÐ°ÑÐŸÐµ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ ÑÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐ¹ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž.  
+
+export.removing_export:Ð£ÐŽÐ°Ð»ÐµÐœÐžÐµ ÐœÐ°ÑÑÐŸÑÑÐµÐ³ÐŸ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÑ ÑÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐ¹ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž...
+
+export.sortmeta:Ð¡ÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð² Ð°Ð»ÑÐ°Ð²ÐžÑÐœÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµÐŒ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. Ð­ÑÐŸ Ð±ÑÐŽÐµÑ Ð±Ð»ÐŸÐºÐžÑÐŸÐ²Ð°ÐœÐŸ, ÐµÑÐ»Ðž ÑÐ°Ð·ÐŒÐµÑ Ð³ÑÑÐ¿Ð¿Ñ> 1.
+
+export.statsfile:ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ ÑÐ°Ð¹Ð»Ð° ÐžÐ»Ðž ÐµÐ³ÐŸ ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑ, Ð² ÐºÐŸÑÐŸÑÑÐ¹ Ð±ÑÐŽÑÑ Ð·Ð°Ð¿ÐžÑÐ°ÐœÑ ÑÑÐ°ÑÐžÑÑÐžÐºÐž ÑÐºÑÐ¿ÐŸÑÑÐ°.
+
+export.stats_backup:ÐÐ·Ð°ÐŒÐµÐœ Ð²ÑÐ²ÐŸÐŽÐžÑ ÐœÐ° STDERR (Ð¿ÑÐŸÑÐŸÐºÐŸÐ» ÐŸÑÐžÐ±ÐŸÐº).
+
+export.verbosity:ÐÐŸÐœÑÑÐŸÐ»ÐžÑÑÐµÑ ÐºÐŸÐ»Ð»ÐžÑÐµÑÑÐ²ÐŸ Ð²ÑÐ²ÐŸÐŽÐ°.  0=ÐœÐžÑÐµÐ³ÐŸ, 3=ÐŒÐœÐŸÐ³ÐŸ.
+
+
+
+# -- mkcol.pl --
+
+mkcol.about:Ð ÑÐµÐºÑÑÐµ ÐŽÐ»Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.
+
+mkcol.bad_name_cvs:ÐÐšÐÐÐÐ: ÐÐžÐºÐ°ÐºÐ°Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐœÐµ ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ ÐœÐ°Ð·Ð²Ð°ÐœÐ° CVS, Ð¿ÐŸÑÐºÐŸÐ»ÑÐºÑ ÑÑÐŸ ÐŒÐŸÐ¶ÐµÑ ÐœÐ°Ð»ÐŸÐ¶ÐžÑÑÑÑ ÐœÐ° ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž, ÑÐŸÐ·ÐŽÐ°ÐœÐœÑÐµ Ð²ÐµÑÑÐžÐµÐ¹ CVS ÑÐžÑÑÐµÐŒÑ.
+
+mkcol.bad_name_svn:ÐÐšÐÐÐÐ: ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐœÐµ ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ ÐœÐ°Ð·Ð²Ð°ÐœÐ° .svn Ð¿ÐŸÑÐºÐŸÐ»ÑÐºÑ ÑÑÐŸ Ð¿ÐµÑÐµÑÐµÐºÐ°ÐµÑÑÑ Ñ ÐŽÐžÑÐµÐºÑÐŸÑÐžÑÐŒÐž ÑÐŸÐ·ÐŽÐ°ÐœÐœÑÐŒÐž Ð² ÑÐ°Ð¹Ð»ÐŸÐ²ÐŸÐ¹ ÑÐžÑÑÐµÐŒÐµ SVN.  
+
+mkcol.bad_name_modelcol:ÐÐšÐÐÐÐ: ÐÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐœÐµÐ»ÑÐ·Ñ ÐœÐ°Ð·ÑÐ²Ð°ÑÑ modelcol, Ð¿ÐŸÑÐºÐŸÐ»ÑÐºÑ ÑÑÐŸ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐŒÐŸÐŽÐµÐ»ÑÐœÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.  
+
+mkcol.cannot_find_modelcol:ÐÐšÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐœÐ°Ð¹ÑÐž ÐŒÐŸÐŽÐµÐ»ÑÐœÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ %s
+
+mkcol.col_already_exists:ÐÐšÐÐÐÐ: Ð­ÑÐ° ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ ÑÐ¶Ðµ ÑÑÑÐµÑÑÐ²ÑÐµÑ.
+
+mkcol.collectdir:ÐÐžÑÐµÐºÑÐŸÑÐžÑ, Ð³ÐŽÐµ ÐœÐŸÐ²Ð°Ñ ÐºÐŸÐ»ÐµÐºÑÐžÑ Ð±ÑÐŽÐµÑ ÑÐŸÐ·ÐŽÐ°ÐœÐ°.
+
+mkcol.group_not_valid_in_gs3:Ð³ÑÑÐ¿Ð¿ÐŸÐ²Ð°Ñ ÐŸÐ¿ÑÐžÑ ÐœÐµ Ð²Ð°Ð»ÐžÐŽÐœÐ° Ð² ÑÐµÐ¶ÐžÐŒÐµ ÐÑÐžÐœÑÑÐŸÑÐœ 3 (-gs3mode)  
+mkcol.creating_col:Ð¡ÐŸÐ·ÐŽÐ°ÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž %s
+
+mkcol.creator:ÐÐŽÑÐµÑ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ ÑÐŸÐ·ÐŽÐ°ÑÐµÐ»Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.
+
+mkcol.creator_undefined:ÐÐšÐÐÐÐ: ÑÐŸÐ·ÐŽÐ°ÑÐµÐ»Ñ ÐœÐµ Ð±ÑÐ» ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœ. Ð­ÑÐ° Ð¿ÐµÑÐµÐŒÐµÐœÐœÐ°Ñ ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÐ°, ÑÑÐŸÐ±Ñ ÑÐ°ÑÐ¿ÐŸÐ·ÐœÐ°ÑÑ ÐŽÑÐ±Ð»ÐžÐºÐ°ÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.
+
+mkcol.desc:Ð¡ÐºÑÐžÐ¿Ñ PERL, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÐ¹ ÐŽÐ»Ñ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ ÑÑÑÑÐºÑÑÑÑ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž ÐŽÐ»Ñ ÐœÐŸÐ²ÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Greenstone.
+
+mkcol.doing_replacements:Ð²ÑÐ¿ÐŸÐ»ÐœÐµÐœÐžÐµ Ð·Ð°ÐŒÐµÐœ ÐŽÐ»Ñ %s
+
+mkcol.group:Ð¡ÐŸÐ·ÐŽÐ°ÐœÐžÐµ Ð³ÑÑÐ¿Ð¿ ÐœÐŸÐ²ÑÑ
+ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹ Ð²ÐŒÐµÑÑÐŸ ÑÑÐ°ÐœÐŽÐ°ÑÑÐœÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.  
+
+mkcol.gs3mode:Ð ÐµÐ¶ÐžÐŒ ÐŽÐ»Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹ ÐÑÐžÐœÑÑÐŸÑÐœ 3-Ð¹ Ð²ÐµÑÑÐžÐž  
+
+mkcol.long_colname:ÐÐšÐÐÐÐ: ÐÐŒÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐŽÐŸÐ»Ð¶ÐœÐŸ ÑÐŸÐŽÐµÑÐ¶Ð°ÑÑ ÐŒÐµÐœÐµÐµ 8 Ð·ÐœÐ°ÐºÐŸÐ², ÑÑÐŸÐ±Ñ Ð±ÑÑÑ ÑÐŸÐ²ÐŒÐµÑÑÐžÐŒÑÐŒ  Ñ Ð±ÐŸÐ»ÐµÐµ ÑÐ°ÐœÐœÐžÐŒÐž ÑÐ°Ð¹Ð»ÐŸÐ²ÑÐŒÐž ÑÐžÑÑÐµÐŒÐ°ÐŒÐž Ðž ÐžÐŒÐµÑÑ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÑ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÐž.
+
+mkcol.maintainer:ÐÐŽÑÐµÑ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ Ð»ÐžÑÐ°, Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐžÐ²Ð°ÑÑÐµÐ³ÐŸ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ (ÐµÑÐ»Ðž ÐŸÐœ ÐŸÑÐ»ÐžÑÐ°ÐµÑÑÑ ÐŸÑ ÑÐŸÐ·ÐŽÐ°ÑÐµÐ»Ñ).
+
+mkcol.no_collectdir:ÐÐšÐÐÐÐ: ÐÐžÑÐµÐºÑÐŸÑÐžÑ collect ÐœÐµ ÑÑÑÐµÑÑÐ²ÑÐµÑ: %s
+
+mkcol.no_collectdir_specified:ÐÐšÐÐÐÐ: ÐÐµ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐ° ÐŽÐžÑÐµÐºÑÐŸÑÐžÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž. Ð gs3mode, ÐžÐ»Ðž ÐŸÐ¿ÑÐžÐž: -site ÐžÐ»Ðž -collectdir ÐŽÐŸÐ»Ð¶ÐœÑ Ð±ÑÑÑ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÑ.  
+
+mkcol.no_colname:ÐÐšÐÐÐÐ: ÐÐžÐºÐ°ÐºÐŸÐ³ÐŸ ÐžÐŒÐµÐœÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐœÐµ Ð±ÑÐ»ÐŸ Ð·Ð°ÐŽÐ°ÐœÐŸ.
+
+mkcol.optionfile:ÐÐŸÐ»ÑÑÐžÑÑ ÐŸÐ¿ÑÐžÐž ÑÐ°Ð¹Ð»Ð°, Ð¿ÐŸÐ»ÐµÐ·ÐœÐŸÐ³ÐŸ ÐŽÐ»Ñ ÑÐžÑÑÐµÐŒ, Ð³ÐŽÐµ ÐŽÐ»ÐžÐœÐœÑÐµ ÐºÐŸÐŒÐ°ÐœÐŽÐœÑÐµ ÑÑÑÐŸÐºÐž ÐŒÐŸÐ³ÑÑ Ð²ÑÐ·ÑÐ²Ð°ÑÑ Ð¿ÑÐŸÐ±Ð»ÐµÐŒÑ.
+
+mkcol.params:[ÐŸÐ¿ÑÐžÐž] ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž  
+
+mkcol.plugin:ÐÐŸÐŽÑÐ»Ñ Ð¿Ð»Ð°Ð³ÐžÐœÐ° Perl ÐŽÐ»Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ (Ð·ÐŽÐµÑÑ ÐŒÐŸÐ³ÑÑ Ð±ÑÑÑ ÐŒÐœÐŸÐ³ÐŸÐºÑÐ°ÑÐœÑÐµ Ð²Ñ
+ÐŸÐ¶ÐŽÐµÐœÐžÑ Ð¿Ð»Ð°Ð³ÐžÐœÐ°).
+
+mkcol.public:ÐÐŒÐµÐµÑ Ð»Ðž ÑÑÐ° ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ Ð°ÐœÐŸÐœÐžÐŒÐœÑÐ¹  ÐŽÐŸÑÑÑÐ¿.  
+mkcol.public.true:ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÐŸÑÐºÑÑÑÐŸÐ³ÐŸ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ  
+mkcol.public.false:ÐÐŸÐ»Ð»ÐµÐºÑÐžÑ ÑÐ°ÑÑÐœÐŸÐ³ÐŸ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ  
+
+mkcol.quiet:Ð Ð°Ð±ÐŸÑÐ°ÑÑ ÑÐ¿ÐŸÐºÐŸÐ¹ÐœÐŸ.
+
+mkcol.site:Ð ÑÐµÐ¶ÐžÐŒÐµ gs3mode, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÑÑÐŸ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÑÐ°Ð¹ÑÐ° Ñ Ð¿ÐµÑÐµÐŒÐµÐœÐœÐŸÐ¹ ÑÑÐµÐŽÑ GSDL3HOME ÐŽÐ»Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÑ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž collectdir, ÐµÑÐ»Ðž -collectdir ÑÐºÐ°Ð·Ð°Ðœ.  
+
+mkcol.success:ÐÐŸÐ²Ð°Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ Ð±ÑÐ»Ð° ÑÐŸÐ·ÐŽÐ°ÐœÐ° ÑÑÐ¿ÐµÑÐœÐŸ Ð² %s
+
+mkcol.title:ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.
+
+mkcol.win31compat:Ð£ÑÐžÑÑÐ²Ð°ÑÑ Ð»Ðž ÐºÐŸÐœÐ²ÐµÐœÑÐžÐž Windows 3.1, Ð¿ÑÐž Ð²ÑÐ±ÐŸÑÐµ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐ¹ ÐŽÐ»Ñ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, ÐœÐµ Ð±ÐŸÐ»ÐµÐµ 8 Ð·ÐœÐ°ÐºÐŸÐ²).  
+mkcol.win31compat.true:ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ Ð¿Ð°Ð¿ÐºÐž ÐŽÐ»ÐžÐœÐŸÐ¹ Ð² 8 ÐžÐ»Ðž ÐŒÐµÐœÐµÐµ ÑÐžÐŒÐ²ÐŸÐ»ÐŸÐ²  
+mkcol.win31compat.false:ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ Ð¿Ð°Ð¿ÐºÐž Ð»ÑÐ±ÐŸÐ¹ ÐŽÐ»ÐžÐœÑ  
+
+# -- pluginfo.pl --
+
+pluginfo.collection:ÐÑÐµÐŽÐŸÑÑÐ°Ð²Ð»ÐµÐœÐžÐµ ÐžÐŒÐµÐœÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ð±ÑÐŽÐµÑ Ð²ÑÐ¿ÐŸÐ»ÐœÐµÐœÐŸ Ð¿ÑÐž Ð¿ÑÐŸÑÐŒÐŸÑÑÐµ Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐ² Ð¿ÑÐµÐ¶ÐŽÐµ Ð²ÑÐµÐ³ÐŸ  Ð² collect/collection-name/perllib/plugins.  ÐÑÐ»Ðž Ð¿Ð»Ð°Ð³ÐžÐœ ÑÐ°ÐŒ ÐœÐµ ÐœÐ°Ð¹ÐŽÐµÐœ, ÑÐŸ ÐœÐ°ÐŽÐŸ Ð±ÑÐŽÐµÑ Ð¿ÑÐŸÑÐŒÐŸÑÑÐµÑÑ Ð² ÐŸÐ±ÑÐµÐ¹ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž perllib/plugins.
+
+pluginfo.desc:ÐÐ°Ð¿ÐžÑÐ°ÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ Ð¿Ð»Ð°Ð³ÐžÐœÐ°Ñ
+.
+
+pluginfo.general_options:ÐÐ±ÑÐžÐµ ÐŸÐ¿ÑÐžÐž, ÑÐœÐ°ÑÐ»ÐµÐŽÐŸÐ²Ð°ÐœÐœÑÐµ ÐŸÑ ÑÐŸÐŽÐžÑÐµÐ»ÑÑÐºÐžÑ
+ ÐºÐ»Ð°ÑÑÐŸÐ² Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐ².
+
+pluginfo.info:ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ
+
+pluginfo.no_plugin_name:ÐÐšÐÐÐÐ: ÐÑ ÐŽÐŸÐ»Ð¶ÐœÑ ÑÐºÐ°Ð·Ð°ÑÑ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ Ð¿Ð»Ð°Ð³ÐžÐœÐ°.  
+
+pluginfo.option_types:ÐÐ»Ð°Ð³ÐžÐœÑ ÐŒÐŸÐ³ÑÑ ÐžÐŒÐµÑÑ ÐŽÐ²Ð° ÑÐžÐ¿Ð° ÐŸÐ¿ÑÐžÐ¹.
+
+pluginfo.params:[ÐŸÐ¿ÑÐžÐž] ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ Ð¿Ð»Ð°Ð³ÐžÐœÐ°  
+
+pluginfo.passing_options:ÐÐ¿ÑÐžÐž ÐŒÐŸÐ³ÑÑ Ð±ÑÑÑ Ð¿ÐµÑÐµÐŽÐ°ÐœÑ Ð»ÑÐ±ÑÐŒ Ð¿Ð»Ð°Ð³ÐžÐœÐ°ÐŒ Ð²ÐºÐ»ÑÑÐµÐœÐžÐµÐŒ ÐžÑ
+ Ð² ÐÐ°Ñ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐŸÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» collect.cfg.
+
+pluginfo.specific_options:Ð¡Ð¿ÐµÑÐžÑÐžÑÐµÑÐºÐžÐµ ÐŸÐ¿ÑÐžÐž ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÑ Ð² Ð¿ÑÐµÐŽÐµÐ»Ð°Ñ
+ ÑÐ°ÐŒÐžÑ
+ Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐ² Ðž ÐŽÐŸÑÑÑÐ¿ÐœÑ ÑÐŸÐ»ÑÐºÐŸ ÑÑÐŸÐŒÑ ÑÐ¿ÐµÑÐžÑÐžÑÐµÑÐºÐŸÐŒÑ Ð¿Ð»Ð°Ð³ÐžÐœÑ.
+
+
+# -- plugoutinfo.pl --
+
+plugoutinfo.collection:ÐÐ°ÐŽÐ°ÐœÐžÐµ ÐžÐŒÐµÐœÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ð·Ð°ÑÑÐ°Ð²ÐžÑ plugout.pl ÑÐœÐ°ÑÐ°Ð»Ð° ÑÐŒÐŸÑÑÐµÑÑ Ð² collect/collection-name/perllib/plugouts. ÐÑÐ»Ðž ÐŒÐŸÐŽÑÐ»Ñ ÐœÐµ Ð±ÑÐŽÐµÑ ÑÐ°ÐŒ ÐœÐ°Ð¹ÐŽÐµÐœ, Ð¿ÐŸÐžÑÐº Ð±ÑÐŽÐµÑ Ð¿ÑÐŸÐžÐ·Ð²ÐµÐŽÐµÐœ Ð² ÐŸÑÐœÐŸÐ²ÐœÐŸÐŒ ÐºÐ°ÑÐ°Ð»ÐŸÐ³Ðµ perllib/plugouts.  
+
+plugoutinfo.desc:ÐÑÐ²ÐµÑÑÐž ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ ÐŒÐŸÐŽÑÐ»Ðµ.  
+
+plugoutinfo.general_options:ÐÑÐœÐŸÐ²ÐœÑÐµ ÐŸÐ¿ÑÐžÐž ÐœÐ°ÑÐ»ÐµÐŽÑÑÑÑÑ ÐŒÐŸÐŽÑÐ»ÐµÐŒ ÐŸÑ ÐºÐ»Ð°ÑÑÐ°-ÑÐŸÐŽÐžÑÐµÐ»Ñ.  
+
+plugoutinfo.info:ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ  
+
+plugoutinfo.no_plugout_name:ÐÐšÐÐÐÐ: ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÐŸ ÑÐºÐ°ÑÐ°ÑÑ ÐžÐŒÑ ÐŒÐŸÐŽÑÐ»Ñ.  
+
+plugoutinfo.option_types:ÐÐŸÐŽÑÐ»Ðž ÐŒÐŸÐ³ÑÑ Ð¿ÑÐžÐœÐžÐŒÐ°ÑÑ ÐŽÐ²Ð° Ð²ÐžÐŽÐ° ÐŸÐ¿ÑÐžÐ¹  
+
+plugoutinfo.params:[ÐŸÐ¿ÑÐžÐž] ÐžÐŒÑ-ÐŒÐŸÐŽÑÐ»Ñ  
+
+plugoutinfo.passing_options:ÐÐŸÐŽÑÐ»Ñ ÐŒÐŸÐ¶ÐœÐŸ Ð¿ÐµÑÐµÐŽÐ°Ð²Ð°ÑÑ ÐŸÐ¿ÑÐžÐž, Ð²ÐºÐ»ÑÑÐ°Ñ ÐžÑ
+ Ð² ÑÐŸÐ±ÑÑÐ²ÐµÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐž collect.cfg  
+
+plugoutinfo.specific_options:ÐÑÐŸÐ±ÑÐµ ÐŸÐ¿ÑÐžÐž ÐŒÐŸÐŽÑÐ»Ðž ÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÑÑ ÑÐ°ÐŒÐž, Ðž Ð¿ÐŸÑÑÐŸÐŒÑ ÐŸÐœÐž ÐŽÐŸÑÑÑÐ¿ÐœÑ ÑÐŸÐ»ÑÐºÐŸ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÐŸÐŒÑ ÐŒÐŸÐŽÑÐ»Ñ.  
+
+
+
+#
+# Classifier option descriptions
+#
+
+AllList.desc:Ð¡ÐŸÐ·ÐŽÐ°ÐµÑ ÐµÐŽÐžÐœÑÐ¹ ÑÐ¿ÐžÑÐŸÐº Ð²ÑÐµÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ². ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ oaiserver.  
+
+AZCompactList.allvalues:ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ Ð²ÑÐµ ÐœÐ°Ð¹ÐŽÐµÐœÐœÑÐµ Ð·ÐœÐ°ÑÐµÐœÐžÑ ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÑ
+.
+
+AZCompactList.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ° ÐŽÐ»Ñ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž Ð² Ð°Ð»ÑÐ°Ð²ÐžÑÐœÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ (ÐŸÑ Ð-Ð¯, 0-9). ÐÑÐŸÐžÐ·Ð²ÐŸÐŽÐžÑ Ð³ÐŸÑÐžÐ·ÐŸÐœÑÐ°Ð»ÑÐœÑÐ¹ Ð-Ð¯ ÑÐ¿ÐžÑÐŸÐº. ÐÐ°ÑÐµÐŒ ÑÐ¿ÐžÑÐŸÐº, ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐžÐ¹ Ð¿ÐµÑÐµÑÐµÐœÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÐžÐ»Ðž ÐºÐœÐžÐ¶ÐœÑÐµ Ð¿ÐŸÐ»ÐºÐž Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒÐž, ÐžÐŒÐµÑÑÐžÐŒÐž ÐŸÐ±ÑÐžÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ.  
+
+AZCompactList.doclevel:Ð£ÑÐŸÐ²ÐµÐœÑ ÐŽÐ»Ñ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° Ð².
+AZCompactList.doclevel.top:ÐŠÐµÐ»ÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ.
+AZCompactList.doclevel.section:Ð Ð°Ð·ÐŽÐµÐ»Ð°ÐŒÐž.
+
+AZCompactList.firstvalueonly:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÑÑÑÑ ÑÐŸÐ»ÑÐºÐŸ Ð¿ÐµÑÐ²ÑÐµ Ð·ÐœÐ°ÑÐµÐœÐžÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+.
+
+AZCompactList.freqsort:Ð¡ÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑ Ð¿ÐŸ ÑÐ°ÑÑÐŸÑÐµ ÑÐ·Ð»Ð°, Ð° ÐœÐµ Ð² Ð°Ð»ÑÐ°Ð²ÐžÑÐœÐŸ-ÑÐžÑÑÐŸÐ²ÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ.
+
+AZCompactList.maxcompact:ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÑÐžÑÐ»ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÐºÐŸÑÐŸÑÑÐµ Ð±ÑÐŽÑÑ Ð¿ÐŸÐºÐ°Ð·Ð°ÐœÑ ÐœÐ° ÑÑÑÐ°ÐœÐžÑÐµ.
+
+AZCompactList.metadata:ÐÐŽÐžÐœÑÑÐ²ÐµÐœÐœÐŸÐµ Ð¿ÐŸÐ»Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, ÐžÐ»Ðž Ð·Ð°Ð¿ÑÑÐ°Ñ ÑÐ°Ð·ÐŽÐµÐ»ÐžÑÐµÐ»Ñ Ð¿ÐŸÐ»ÐµÐ¹ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐŽÐ»Ñ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐž. ÐÑÐ»Ðž ÑÐ¿ÐžÑÐŸÐº ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœ, Ð±ÑÐŽÐµÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑÑÑ Ð¿ÐµÑÐ²ÑÐ¹ ÑÐžÐ¿ ÐŒÐµÑÐ°Ð»ÐŽÐ°ÐœÐœÑÑ
+, ÐºÐŸÑÐŸÑÑÐ¹ ÐŸÐ±Ð»Ð°ÐŽÐ°ÐµÑ Ð·ÐœÐ°ÑÐµÐœÐžÑÐŒÐž. ÐÐŸÐ¶ÐµÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑÑÑ Ð² ÑÐŸÐµÐŽÐžÐœÐµÐœÐžÐž Ñ -firstvalueonly Ðž ÑÐ»Ð°Ð³Ð°ÐŒÐž -allvalues, ÐŽÐ»Ñ Ð²ÑÐ±ÐŸÑÐ° ÑÐŸÐ»ÑÐºÐŸ Ð¿ÐµÑÐ²ÐŸÐ³ÐŸ Ð·ÐœÐ°ÑÐµÐœÐžÑ, ÐžÐ»Ðž Ð²ÑÐµÑ
+ Ð·ÐœÐ°ÑÐµÐœÐžÐ¹ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐžÐ· ÑÐ¿ÐžÑÐºÐ°.
+
+AZCompactList.mincompact:ÐÐžÐœÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÑÐžÑÐ»ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÐºÐŸÑÐŸÑÑÐµ Ð±ÑÐŽÑÑ Ð¿ÐŸÐºÐ°Ð·Ð°ÐœÑ ÐœÐ° ÑÑÑÐ°ÐœÐžÑÐµ.
+
+AZCompactList.mingroup:ÐÐ°ÐžÐŒÐµÐœÑÑÐ°Ñ ÑÐžÑÐ»ÐŸ, ÐºÐŸÑÐŸÑÐŸÐµ Ð²ÑÐ·ÑÐ²Ð°ÐµÑ ÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÐœÐžÐµ Ð³ÑÑÐ¿Ð¿ Ð² ÐžÐµÑÐ°ÑÑ
+ÐžÑÐµÑÐºÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ.
+
+AZCompactList.minnesting:ÐÐ°ÐžÐŒÐµÐœÑÑÐµÐµ ÑÐžÑÐ»ÐŸ, ÐºÐŸÑÐŸÑÐŸÐµ Ð²ÑÐ·ÐŸÐ²ÐµÑ Ð¿ÑÐµÐŸÐ±ÑÐ°Ð·ÐŸÐ²Ð°ÐœÐžÐµ ÑÐ¿ÐžÑÐºÐ° Ð²ÐŸ Ð²Ð»ÐŸÐ¶ÐµÐœÐœÑÐ¹ ÑÐ¿ÐžÑÐŸÐº.
+
+AZCompactList.recopt:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÐ¹ Ð²ÐŸ Ð²Ð»ÐŸÐ¶ÐµÐœÐœÑÑ
+ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÑÐžÐ¿Ð° -ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐÐŸÐŽÐ°/ÐÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÐž.
+AZCompactList.sort:ÐÐŸÐ»Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž ÐŽÐŸÑÐµÑÐœÐžÑ
+ ÑÐ·Ð»ÐŸÐ².  
+
+AZCompactSectionList.desc:ÐÐ°ÑÐžÐ°ÑÐžÐž Ð² AZCompactList, ÐºÐŸÑÐŸÑÑÐ¹ ÐºÐ»Ð°ÑÑÐžÑÐžÑÐžÑÑÐµÑ ÑÐ°Ð·ÐŽÐµÐ»Ñ, Ð° ÐœÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ. ÐÑ
+ÐŸÐ¶ÐŽÐµÐœÐžÑ ÐŸÑÑÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÑ Ð¿ÐŸ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐŒ ÑÑÐŸÐ²ÐœÑ ÑÐ°Ð·ÐŽÐµÐ»Ð°.
+
+AZList.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ° ÐŽÐ»Ñ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž Ð² Ð°Ð»ÑÐ°Ð²ÐžÑÐœÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ (ÐŸÑ Ð-Ð¯, 0-9). ÐÑÐŸÐžÐ·Ð²ÐŸÐŽÐžÑ Ð³ÐŸÑÐžÐ·ÐŸÐœÑÐ°Ð»ÑÐœÑÐ¹ Ð-Ð¯ ÑÐ¿ÐžÑÐŸÐº Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒÐž.  
+
+AZList.metadata:ÐÐŽÐžÐœÑÑÐ²ÐµÐœÐœÐŸÐµ Ð¿ÐŸÐ»Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐžÐ»Ðž ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐœÑÐ¹ Ð·Ð°Ð¿ÑÑÐŸÐ¹ ÑÐ¿ÐžÑÐŸÐº Ð¿ÐŸÐ»ÐµÐ¹ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÑ
+ ÐŽÐ»Ñ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐž. Ð¡Ð»ÐµÐŽÑÑ Ð¿ÐŸÑÑÐŽÐºÑ, ÐŸÐ±ÐŸÐ·ÐœÐ°ÑÐµÐœÐœÐŸÐŒÑ Ð² ÑÐ¿ÐžÑÐºÐµ, Ð¿ÐµÑÐ²ÐŸÐµ Ð¿ÐŸÐ»Ðµ, ÐºÐŸÑÐŸÑÐŸÐµ ÑÐŸÐŽÐµÑÐ¶ÐžÑ Ð·ÐœÐ°ÑÐµÐœÐžÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, Ð±ÑÐŽÐµÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑÑÑ. Ð¡Ð¿ÐžÑÐŸÐº Ð±ÑÐŽÐµÑ ÐŸÑÑÐŸÑÑÐžÑÐŸÐ²Ð°Ðœ Ð¿ÐŸ ÑÑÐŸÐŒÑ ÑÐ»ÐµÐŒÐµÐœÑÑ.
+
+AZSectionList.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ° ÐŽÐ»Ñ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž ÑÐµÐºÑÐžÐ¹ Ð² Ð°Ð»ÑÐ°Ð²ÐžÑÐœÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ. Ð¡ÐŸÑÑÐžÑÑÐµÑ Ð¿ÐŸ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐŒ ÑÑÐŸÐ²ÐœÑ ÑÐµÐºÑÐžÐ¹.  
+
+BasClas.bad_general_option:ÐÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑ %s  ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑ ÐœÐµÐºÐŸÑÑÐµÐºÑÐœÑÑ ÐŸÐ±ÑÑÑ ÐŸÐ¿ÑÐžÑ. ÐÑÐŸÐ²ÐµÑÑÑÐµ ÐÐ°Ñ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐŸÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» collect.cfg.  
+
+BasClas.builddir:ÐÐŽÐµ Ð¿ÐŸÐŒÐµÑÑÐžÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐœÑÐµ ÐžÐœÐŽÐµÐºÑÑ.
+
+BasClas.buttonname:Ð¯ÑÐ»ÑÐº ÐŽÐ»Ñ Ð¿ÐŸÐºÐ°Ð·Ð° ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ° ÐœÐ° ÑÐºÑÐ°ÐœÐµ Ðž ÐºÐœÐŸÐ¿ÐºÐ° Ð² ÐœÐ°Ð²ÐžÐ³Ð°ÑÐžÐŸÐœÐœÐŸÐ¹ Ð»ÐžÐœÐµÐ¹ÐºÐµ. ÐÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ ÑÑÐŸ ÑÐ»ÐµÐŒÐµÐœÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ñ ÑÐºÐ°Ð·Ð°ÐœÐŸÐ¹ ÐŸÐ¿ÑÐžÐµÐ¹ -metadata.  
+
+BasClas.desc:ÐÑÐœÐŸÐ²ÐœÐŸÐ¹ ÐºÐ»Ð°ÑÑ ÐŽÐ»Ñ Ð²ÑÐµÑ
+ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐŸÐ².
+
+BasClas.no_metadata_formatting:ÐÐµ ÑÐŸÑÐŒÐ°ÑÐžÑÐŸÐ²Ð°ÑÑ Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐž ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ (ÐŽÐ»Ñ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž).  
+
+BasClas.outhandle:ÐÐœÐŽÐµÐºÑÐœÑÐ¹ ÑÐ°Ð¹Ð» ÐŽÐ»Ñ ÐŸÐ¿ÐžÑÐ°ÐœÐžÑ ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÐ°.
+
+BasClas.removeprefix:ÐÑÐµÑÐžÐºÑ, Ñ ÐºÐŸÑÐŸÑÐŸÐ³ÐŸ ÐœÐ°ÑÐžÐœÐ°ÑÑÑÑ ÐŽÐ°ÐœÐœÑÐµ ÐŽÐ»Ñ ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÐœÐžÑ Ð¿ÑÐž ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž.
+
+BasClas.removesuffix:Ð¡ÑÑÑÐžÐºÑ, Ñ ÐºÐŸÑÐŸÑÐŸÐ³ÐŸ ÐœÐ°ÑÐžÐœÐ°ÑÑÑÑ ÐŽÐ°ÐœÐœÑÐµ ÐŽÐ»Ñ ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÐœÐžÑ Ð¿ÑÐž ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž.
+
+BasClas.verbosity:Ð£Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÐµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸÐŒ Ð¿ÑÐŸÐŽÑÐºÑÐžÐž. 0=ÐŸÑÑÑÑÑÑÐ²ÐžÐµ, 3=Ð±ÐŸÐ»ÑÑÐžÐµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²Ð°.
+
+Browse.desc:Ð€Ð°Ð»ÑÑÐžÐ²ÑÐ¹ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑ, ÐºÐŸÑÐŸÑÑÐ¹ ÐŸÐ±ÐµÑÐ¿ÐµÑÐžÐ²Ð°ÐµÑ ÑÐ²ÑÐ·Ñ Ð² Ð¿Ð°ÐœÐµÐ»Ðž ÐœÐ°Ð²ÐžÐ³Ð°ÑÐžÐž Ð² ÑÐŸÑÐµÑÐ°ÐœÐžÐž Ñ Ð¿ÑÐŸÑÐŒÐŸÑÑÐŸÐŒ Ðž Ð¿ÐŸÐžÑÐºÐŸÐŒ ÑÑÑÐ°ÐœÐžÑ. Ð Ð°Ð±ÐŸÑÐ°ÐµÑ ÑÐŸÐ»ÑÐºÐŸ Ð²  ÐœÐµÐ±ÐŸÐ»ÑÑÐžÑ
+ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÑ
+ mgpp.  
+
+DateList.bymonth:ÐÐ»Ð°ÑÑÐžÑÐžÑÐžÑÐŸÐ²Ð°ÑÑ Ð¿ÐŸ Ð³ÐŸÐŽÑ Ðž ÐŒÐµÑÑÑÑ Ð²ÐŒÐµÑÑÐŸ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐž ÑÐŸÐ»ÑÐºÐŸ Ð¿ÐŸ Ð³ÐŸÐŽÑ
+
+DateList.desc:ÐÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐŸÐœÐœÑÐ¹ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž Ð¿ÐŸ ÐŽÐ°ÑÐ°ÐŒ. ÐÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐ° Ð¿ÑÐŸÐžÐ·Ð²ÐŸÐŽÐžÑÑÑ Ð¿ÐŸ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐŒ 'ÐÐ°ÑÐ°'. ÐÑÐžÐœÑÑÐŸ, ÑÑÐŸ ÐŽÐ°ÑÐ° ÐŽÐŸÐ»Ð¶ÐœÐ° ÐžÐŒÐµÑÑ Ð²ÐžÐŽ Ð³Ð³Ð³Ð³ÐŒÐŒÐŽÐŽ ÐžÐ»Ðž Ð³Ð³Ð³Ð³-ÐŒÐŒ-ÐŽÐŽ.  
+
+DateList.metadata:ÐÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ, ÐºÐŸÑÐŸÑÑÐµ ÑÐŸÐŽÐµÑÐ¶Ð°Ñ ÐŽÐ°ÑÑ ÐŽÐ»Ñ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐž. ÐÑÐµÐŽÐ¿ÐŸÐ»Ð°Ð³Ð°ÐµÑÑÑ, ÑÑÐŸ ÑÐŸÑÐŒÐ°Ñ Ð±ÑÐŽÐµÑ Ð³Ð³Ð³Ð³ÐŒÐŒÐŽÐŽ ÐžÐ»Ðž Ð³Ð³Ð³Ð³-ÐŒÐŒ-ÐŽÐŽ. ÐÑÐ»Ðž ÐŽÐ°ÑÑ Ð¿ÐµÑÐµÑÐžÑÐ»ÐµÐœÑ ÑÐµÑÐµÐ· Ð·Ð°Ð¿ÑÑÑÑ, Ð±ÑÐŽÐµÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑÑÑ Ð¿ÐµÑÐ²Ð°Ñ ÐŽÐ°ÑÐ°.  
+
+DateList.reverse_sort:Ð¡ÐŸÑÑÐžÑÐŸÐ²ÐºÐ° ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ð² ÐŸÐ±ÑÐ°ÑÐœÐŸÐŒ Ñ
+ÑÐŸÐœÐŸÐ»ÐŸÐ³ÐžÑÐµÑÐºÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ (ÐœÐŸÐ²ÐµÐ¹ÑÐžÐ¹ Ð²ÐœÐ°ÑÐ°Ð»Ðµ).
+
+DateList.nogroup:Ð¡ÐŽÐµÐ»Ð°ÑÑ ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ Ð³ÐŸÐŽÐ° ÐžÐœÐŽÐžÐ²ÐžÐŽÑÐ°Ð»ÑÐœÑÐ¹ Ð²Ñ
+ÐŸÐŽ Ð² Ð³ÐŸÑÐžÐ·ÐŸÐœÑÐ°Ð»ÑÐœÐŸÐŒ ÑÐ¿ÐžÑÐºÐµ, Ð²ÐŒÐµÑÑÐŸ ÑÐŸÐ³ÐŸ, ÑÑÐŸÐ±Ñ ÐŸÑ
+Ð²Ð°ÑÐžÑÑ Ð³ÐŸÐŽÑ ÐœÐµÑÐºÐŸÐ»ÑÐºÐžÐŒÐž Ð²Ñ
+ÐŸÐŽÐ°ÐŒÐž. (Ð­ÑÐŸ ÐŒÐŸÐ¶ÐµÑ ÑÐ°ÐºÐ¶Ðµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑÑÑ ÐŽÐ»Ñ ÐŽÐ²ÑÑ
+ÐŒÐµÑÑÑÐœÐŸÐ¹ ÐŸÐ¿ÑÐžÐž, ÐŽÐµÐ»Ð°Ñ ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ ÐŒÐµÑÑÑÐ° ÐŸÑÐŽÐµÐ»ÑÐœÑÐ¹ Ð²Ñ
+ÐŸÐŽ Ð²ÐŒÐµÑÑÐŸ ÐŸÐ±ÑÐµÐŽÐžÐœÐµÐœÐŸÐ³ÐŸ).
+
+DateList.no_special_formatting:ÐÐµ ÐŸÑÐŸÐ±ÑÐ°Ð¶Ð°ÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ Ð³ÐŸÐŽÐµ Ðž ÐŒÐµÑÑÑÐµ Ð² ÑÐ¿ÐžÑÐºÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ².  
+
+DateList.sort:ÐÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÐŸÐµ Ð¿ÐŸÐ»Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž Ð² ÑÐ»ÑÑÐ°Ðµ, ÐºÐŸÐ³ÐŽÐ° ÐŽÐ²Ð° ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° ÐžÐŒÐµÑÑ ÐŸÐŽÐœÑ Ðž ÑÑ Ð¶Ðµ  ÐŽÐ°ÑÑ.
+
+HFileHierarchy.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ° ÐŽÐ»Ñ Ð³ÐµÐœÐµÑÐžÑÐŸÐ²Ð°ÐœÐžÑ ÐžÐµÑÐ°ÑÑ
+ÐžÑÐµÑÐºÐžÑ
+ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐ¹, Ð¿ÐŸÑÑÑÐŸÐµÐœÐœÑÑ
+ ÐœÐ° ÐŽÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÐŸÐŒ ÑÐ°Ð¹Ð»Ðµ ÑÐŸ ÑÑÑÑÐºÑÑÑÐŸÐ¹.
+
+Hierarchy.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ° ÐŽÐ»Ñ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ ÐžÐµÑÐ°ÑÑ
+ÐžÑÐµÑÐºÐžÑ
+ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐ¹. Ð­ÑÐŸ Ð±Ð°Ð·ÐžÑÑÐµÑÑÑ ÐœÐ° ÑÑÑÑÐºÑÑÑÐžÑÐŸÐ²Ð°ÐœÐœÑÑ
+ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐžÐ»Ðž ÐœÐ° ÐŽÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÐŸÐŒ ÑÐ°Ð¹Ð»ÐŸÐŒ, ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐžÐŒ ÑÑÑÑÐºÑÑÑÑ (ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ ÐŸÐ¿ÑÐžÑ -hfile).  
+
+Hierarchy.documents_last:ÐÐ·ÐŸÐ±ÑÐ°Ð¶Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð² ÑÐ¿ÐžÑÐºÐµ Ð¿ÐŸÑÐ»Ðµ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐŸÐ².  
+
+Hierarchy.hfile:ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÑÐ°Ð¹Ð» Ñ ÑÐºÐ°Ð·Ð°ÐœÐŸÐ¹ ÑÑÑÑÐºÑÑÑÐŸÐ¹ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐž.  
+
+Hierarchy.hlist_at_top:ÐÐŸÐºÐ°Ð·Ð°ÑÑ Ð¿ÐµÑÐ²ÑÐ¹ ÑÑÐŸÐ²ÐµÐœÑ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐž Ð³ÐŸÑÐžÐ·ÐŸÐœÑÐ°Ð»ÑÐœÐŸ.
+
+Hierarchy.reverse_sort:Ð¡ÐŸÑÑÐžÑÐŸÐ²ÐºÐ° Ð»ÐžÑÑÑÐµÐ² ÐŽÐµÑÐµÐ²Ð° (ÐºÐŸÐœÑÐµÐ²ÑÑ
+ Ð²ÐµÑÑÐžÐœ) Ð² ÐŸÐ±ÑÐ°ÑÐœÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ (ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ Ñ -sort).
+
+Hierarchy.separator:Ð ÐµÐ³ÑÐ»ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐœÐŸÐµ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÑÐ°Ð·ÐŽÐµÐ»ÐžÑÐµÐ»Ñ.
+
+Hierarchy.sort:ÐÐŸÐ»Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž ÐŽÐŸÑÐµÑÐœÐžÑ
+ ÑÐ·Ð»ÐŸÐ². ÐÑÐ»Ðž Ð¿ÐŸÐ»Ðµ ÐœÐµ ÑÐºÐ°Ð·Ð°ÐœÐŸ, ÑÐ·Ð»Ñ ÑÐŸÑÑÐžÑÐŸÐ²Ð°ÑÑÑÑ ÐœÐµ Ð±ÑÐŽÑÑ.  
+
+Hierarchy.suppressfirstlevel:ÐÐµ Ð¿ÑÐžÐŽÐ°Ð²Ð°Ð¹ÑÐµ Ð·ÐœÐ°ÑÐµÐœÐžÑ Ð¿ÐµÑÐ²ÐŸÐ¹ ÑÐ°ÑÑÐž Ð·ÐœÐ°ÑÐµÐœÐžÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+. Ð­ÑÐŸ Ð¿ÐŸÐ»ÐµÐ·ÐœÐŸ ÐŽÐ»Ñ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ñ ÐŸÐŽÐžÐœÐ°ÐºÐŸÐ²ÑÐŒ ÐœÐ°ÑÐ°Ð»ÑÐœÑÐŒ ÑÐ»ÐµÐŒÐµÐœÑÐŸÐŒ, ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž ÐžÐŒÐ¿ÐŸÑÑÐ° Ð² gsdlsourcefilename.  
+
+Hierarchy.suppresslastlevel:ÐÐ³ÐœÐŸÑÐžÑÑÐ¹ÑÐµ Ð¿ÐŸÑÐ»ÐµÐŽÐœÑÑ ÑÐ°ÑÑÑ Ð² Ð·ÐœÐ°ÑÐµÐœÐžÐž ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÑ
+. Ð­ÑÐŸ Ð¿ÐŸÐ»ÐµÐ·ÐœÐŸ ÐŽÐ»Ñ ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÑ
+, Ð² ÐºÐŸÑÐŸÑÑÑ
+ ÐºÐ°Ð¶ÐŽÐŸÐµ Ð·ÐœÐ°ÑÐµÐœÐžÐµ ÐŸÐŽÐžÐœÐ°ÐºÐŸÐ²ÐŸ, ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, Ð²ÐµÑÐ²Ñ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž.
+
+HTML.desc:Ð¡ÐŸÐ·ÐŽÐ°ÐµÑ Ð¿ÑÑÑÑÑ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÑ, ÐºÐŸÑÐŸÑÐ°Ñ ÑÐ²Ð»ÑÐµÑÑÑ Ð¿ÑÐŸÑÑÐŸ ÑÑÑÐ»ÐºÐŸÐ¹ ÐœÐ° Ð²ÐµÐ±-ÑÑÑÐ°ÐœÐžÑÑ.
+
+HTML.url:URL Ð²ÐµÐ±-ÑÑÑÐ°ÐœÐžÑÑ ÐŽÐ»Ñ ÑÐ²ÑÐ·Ðž Ñ.
+
+List.bookshelf_type:ÐÐŸÐœÑÑÐŸÐ»ÐžÑÑÐµÑ Ð³ÐŽÐµ ÑÐŸÐ·ÐŽÐ°ÑÑ "ÐºÐœÐžÐ¶ÐœÑÐµ Ð¿ÐŸÐ»ÐºÐž"  
+List.bookshelf_type.always:Ð¡ÐŸÐ·ÐŽÐ°ÐµÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐµ ÐºÐœÐžÐ¶ÐœÐŸÐ¹ Ð¿ÐŸÐ»ÐºÐž, ÐŽÐ°Ð¶Ðµ ÐµÑÐ»Ðž ÑÐ°ÐŒ ÑÐŸÐ»ÑÐºÐŸ ÐŸÐŽÐžÐœ ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð² ÐºÐ°Ð¶ÐŽÐŸÐ¹ Ð³ÑÑÐ¿Ð¿Ðµ.  
+List.bookshelf_type.never:ÐÐžÐºÐŸÐ³ÐŽÐ° ÐœÐµ ÑÐŸÐ·ÐŽÐ°ÐµÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐµ ÐºÐœÐžÐ¶ÐœÐŸÐ¹ Ð¿ÐŸÐ»ÐºÐž, ÐŽÐ°Ð¶Ðµ ÐµÑÐ»Ðž ÑÐ°ÐŒ Ð±ÐŸÐ»ÐµÐµ ÐŸÐŽÐœÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° Ð² ÐºÐ°Ð¶ÐŽÐŸÐ¹ Ð³ÑÑÐ¿Ð¿Ðµ.  
+List.bookshelf_type.duplicate_only:Ð¡ÐŸÐ·ÐŽÐ°ÐµÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐµ ÐºÐœÐžÐ¶ÐœÐŸÐ¹ Ð¿ÐŸÐ»ÐºÐž, ÑÐŸÐ»ÑÐºÐŸ ÐµÑÐ»Ðž ÑÐ°ÐŒ Ð±ÐŸÐ»ÐµÐµ ÐŸÐŽÐœÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° Ð² ÐºÐ°Ð¶ÐŽÐŸÐ¹ Ð³ÑÑÐ¿Ð¿Ðµ.  
+
+List.classify_sections:ÐÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÑ ÑÐµÐºÑÐžÐ¹ Ð²ÐŒÐµÑÑÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ².
+
+List.desc:ÐÐ±ÑÐžÐ¹ Ðž Ð³ÐžÐ±ÐºÐžÐ¹ ÑÐ¿ÐžÑÐŸÑÐœÑÐ¹ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑ, Ñ Ð¿ÐŸÑÑÐž Ð²ÑÐµÐŒÐž Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÑÐŒÐž, ÑÑÐŸ Ðž AZCompactList, ÐœÐŸ Ð»ÑÑÑÐžÐŒÐž ÑÐ¿ÐŸÑÐŸÐ±ÐœÐŸÑÑÑÐŒÐž ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž, Ð° ÑÐ°ÐºÐ¶Ðµ ÑÐ°Ð±ÐŸÑÑ Ñ Unicode Ðž ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐŒÐž.  
+
+List.level_partition.per_letter:Ð¡ÐŸÐ·ÐŽÐ°ÑÑ ÑÐ°Ð·ÐŽÐµÐ» ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ Ð¿ÐžÑÑÐŒÐ°.  
+List.level_partition.constant_size:Ð¡ÐŸÐ·ÐŽÐ°ÑÑ ÑÐ°Ð·ÐŽÐµÐ» Ð¿ÐŸÑÑÑÐœÐœÐŸÐ³ÐŸ ÑÐ°Ð·ÐŒÐµÑÐ°.  
+List.level_partition.per_letter_fixed_size:Ð¡ÐŸÐ·ÐŽÐ°ÑÑ ÑÐ°Ð·ÐŽÐµÐ» ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ Ð¿ÐžÑÑÐŒÐ° ÐŸÑÐžÐµÐœÑÐžÑÐŸÐ²ÐŸÑÐœÐŸ ÑÐ»ÐµÐŽÑÑÑÐµÐ³ÐŸ ÑÐ°Ð·ÐŒÐµÑÐ°.  
+
+List.metadata:ÐÐŸÐ»Ñ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐž. ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ  '/' ÐŽÐ»Ñ ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐžÑ ÑÑÐŸÐ²ÐœÐµÐ¹ ÐžÐµÑÐ°ÑÑ
+ÐžÐž, Ð° ';' ÐŽÐ»Ñ ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐžÑ Ð¿ÐŸÐ»ÐµÐ¹ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐœÐ° ÐºÐ°Ð¶ÐŽÐŸÐ¹ ÑÑÐŸÐ²ÐœÐµ.  
+
+List.partition_name_length:ÐÐ»ÐžÐœÐ° ÐžÐŒÐµÐœÐž ÑÐ°Ð·ÐŽÐµÐ»Ð°; Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ Ð¿ÐµÑÐµÐŒÐµÐœÐœÑÐ¹ ÑÐ°Ð·ÐŒÐµÑ ÐŸÑ 1 ÐŽÐŸ 3 ÑÐžÐŒÐ²ÐŸÐ»ÐŸÐ², Ð·Ð°Ð²ÐžÑÐžÑ ÐŸÑ ÑÐŸÐ³ÐŸ, ÑÐºÐŸÐ»ÑÐºÐŸ ÐœÑÐ¶ÐœÐŸ ÐŽÐ»Ñ ÐŸÑÐŽÐµÐ»ÐµÐœÐžÑ ÐœÐ°ÑÐ°Ð»Ð° ÑÐ°Ð·ÐŽÐµÐ»Ð° ÐŸÑ ÐµÐ³ÐŸ ÐºÐŸÐœÑÐ°. Ð­ÑÐ° ÐŸÐ¿ÑÐžÑ Ð¿ÑÐžÐŒÐµÐœÐžÐŒÐ° ÑÐŸÐ»ÑÐºÐŸ ÑÐŸÐ³ÐŽÐ°, ÐºÐŸÐ³ÐŽÐ° partition_type_within_level ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœ Ð² 'constant_size'.  
+
+List.partition_size_within_level:ÐÐŸÐ»Ð»ÐžÑÐµÑÑÐ²ÐŸ ÑÐ»ÐµÐŒÐµÐœÑÐŸÐ² Ð² ÐºÐ°Ð¶ÐŽÐŸÐŒ ÑÐ°Ð·ÐŽÐµÐ»Ðµ (Ð¿ÑÐžÐŒÐµÐœÑÐµÑÑÑ ÑÐŸÐ»ÑÐºÐŸ ÐµÑÐ»Ðž partition_type_within_level Ð¿ÐŸÑÑÐ°Ð²Ð»ÐµÐœ ÐœÐ° 'constant_size').  
+
+List.partition_type_within_level:Ð¢ÐžÐ¿ ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐžÑ ÐœÐ° Ð³ÑÑÐ¿Ð¿Ñ: 'Ð¿ÐŸ Ð±ÑÐºÐ²Ðµ Ð°Ð»ÑÐ°Ð²ÐžÑÐ°' ('per_letter'), 'ÐºÐŸÐœÑÑÐ°ÐœÑÐœÑÐ¹ ÑÐ°Ð·ÐŒÐµÑ' ('constant_size'), ÐžÐ»Ðž 'ÐœÐžÑÐµÐ³ÐŸ' ('none').  
+
+List.sort_leaf_nodes_using:ÐÐŸÐ»Ñ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž ÐºÐŸÐœÐµÑÐœÑÑ
+ ÑÐ·Ð»ÐŸÐ². ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ  '|' ÐŽÐ»Ñ ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐžÑ Ð³ÑÑÐ¿Ð¿ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ ÑÑÐ°Ð±ÐžÐ»ÑÐœÐŸÐ¹ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž, Ð° ';' ÐŽÐ»Ñ ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐžÑ Ð¿ÐŸÐ»ÐµÐ¹ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ð² ÐºÐ°Ð¶ÐŽÐŸÐ¹ Ð³ÑÑÐ¿Ð¿Ðµ.  
+
+List.sort_using_unicode_collation:Ð¡ÐŸÑÑÐžÑÐŸÐ²ÐºÐ° Ñ Ð¿ÑÐžÐŒÐµÐœÐµÐœÐžÐµÐŒ Ð°Ð»Ð³ÐŸÑÐžÑÐŒÐ° Unicode Collation. Ð¢ÑÐµÐ±ÑÑÑÑÑ http://www.unicode.org/Public/UCA/latest/allkeys.txt ÑÐ°Ð¹Ð» ÐŽÐ»Ñ Ð·Ð°Ð³ÑÑÐ·ÐºÐž Ð² Ð¿Ð°Ð¿ÐºÑ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž perl lib/Unicode/Collate.
+
+List.use_hlist_for:ÐÐŸÐ»Ñ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ Ð³ÐŸÑÐžÐ·ÐŸÐœÑÐ°Ð»ÑÐœÐŸÐ³ÐŸ ÑÐ¿ÐžÑÐºÐ° (hlist) Ð²ÐŒÐµÑÑÐŸ Ð²ÐµÑÑÐžÐºÐ°Ð»ÑÐœÐŸÐ³ÐŸ (vlist). ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ ',' ÐŽÐ»Ñ ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐžÑ Ð³ÑÑÐ¿Ð¿ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, Ð° ';' ÐŽÐ»Ñ ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐžÑ Ð¿ÐŸÐ»ÐµÐ¹ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ð² ÐºÐ°Ð¶ÐŽÐŸÐ¹ Ð³ÑÑÐ¿Ð¿Ðµ.  
+
+SimpleList.metadata:ÐÐŽÐœÐŸ Ð¿ÐŸÐ»Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐžÐ»Ðž ÐœÐµÑÐºÐŸÐ»ÑÐºÐŸ, Ð² ÑÐ¿ÐžÑÐºÐµ, ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐœÑÐŒ Ð·Ð°Ð¿ÑÑÑÐŒÐž, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÐµ ÐŽÐ»Ñ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐž. Ð¡Ð»ÐµÐŽÑÑ Ð¿ÐŸ Ð¿ÐŸÑÑÐŽÐºÑ, ÐŸÐ±ÐŸÐ·ÐœÐ°ÑÐµÐœÐœÐŸÐŒÑ Ð² ÑÐ¿ÐžÑÐºÐµ, Ð¿ÐµÑÐ²ÐŸÐµ Ð¿ÐŸÐ»Ðµ, ÐºÐŸÑÐŸÑÐŸÐµ ÑÐŸÐŽÐµÑÐ¶ÐžÑ Ð·ÐœÐ°ÑÐµÐœÐžÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, Ð±ÑÐŽÐµÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑÑÑ. Ð¡Ð¿ÐžÑÐŸÐº Ð±ÑÐŽÐµÑ ÐŸÑÑÐŸÑÑÐžÑÐŸÐ²Ð°Ðœ ÑÑÐžÐŒ ÑÐ»ÐµÐŒÐµÐœÑÐŸÐŒ, ÐµÑÐ»Ðž ÐœÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ -sort. ÐÑÐ»Ðž ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐœÐµ ÑÐºÐ°Ð·Ð°ÐœÑ, Ð² ÑÐ¿ÐžÑÐŸÐº Ð±ÑÐŽÑÑ Ð²ÐºÐ»ÑÑÐµÐœÑ Ð²ÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ, ÐžÐœÐ°ÑÐµ, ÑÐŸÐ»ÑÐºÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ñ ÑÐºÐ°Ð·Ð°ÐœÑÐŒ Ð·ÐœÐ°ÑÐµÐœÐžÐµÐŒ ÑÑÐžÑ
+ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+.
+
+SimpleList.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ Ð¿ÑÐŸÑÑÐŸÐ³ÐŸ ÑÐ¿ÐžÑÐŸÑÐœÐŸÐ³ÐŸ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ°.
+
+SimpleList.sort:ÐÐŸÐ»Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž. ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ'-sort nosort', ÐµÑÐ»Ðž ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐ° ÐœÐµ ÐœÑÐ¶ÐœÐ°.
+
+Phind.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐºÐ»Ð°ÑÐžÑÐžÐºÐ°ÑÐŸÑÐ° Phind.  
+
+Phind.language:Ð¯Ð·ÑÐº ÐžÐ»Ðž ÑÐ·ÑÐºÐž, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÐµ ÐŽÐ»Ñ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ ÐžÐµÑÐ°ÑÑ
+ÐžÐž. Ð¯Ð·ÑÐºÐž ÐŸÐ±ÐŸÐ·ÐœÐ°ÑÐ°ÑÑÑÑ ÐŽÐ²ÑÑ
+Ð±ÑÐºÐ²ÐµÐœÐœÑÐŒÐž ÐºÐŸÐŽÐ°ÐŒÐž ÑÑÑÐ°Ðœ, Ðº Ð¿ÑÐžÐŒÐµÑÑ, en (Ð°ÐœÐ³Ð»ÐžÐ¹ÑÐºÐžÐ¹ ÑÐ·ÑÐº), es (ÐžÑÐ¿Ð°ÐœÑÐºÐžÐ¹ ÑÐ·ÑÐº) Ðž fr (ÑÑÐ°ÐœÑÑÐ·ÑÐºÐžÐ¹ ÑÐ·ÑÐº). Ð¯Ð·ÑÐº ÑÐ²Ð»ÑÐµÑÑÑ Ð¿ÑÐ°Ð²ÐžÐ»ÑÐœÑÐŒ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµÐŒ, ÑÐ°Ðº 'en|fr' (Ð°ÐœÐ³Ð»ÐžÐ¹ÑÐºÐžÐ¹ ÐžÐ»Ðž ÑÑÐ°ÐœÑÑÐ·ÑÐºÐžÐ¹ ÑÐ·ÑÐº) Ðž '..' (ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐµÐœÐœÐŸ, Ð»ÑÐ±ÐŸÐ¹ ÑÐ·ÑÐº) Ð¿ÑÐžÐ³ÐŸÐŽÐœÑ.
+
+Phind.min_occurs:ÐÐžÐœÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÑÐžÑÐ»ÐŸ ÐŸÐ±ÐŸÐ·ÐœÐ°ÑÐ°ÑÑÐµÐµ, ÑÐºÐŸÐ»ÐºÐŸ ÑÐ°Ð· ÑÑÐ°Ð·Ð° ÐŽÐŸÐ»Ð¶ÐœÐ° Ð²ÑÑÑÐµÑÐžÑÑÑÑ Ð² ÑÐµÐºÑÑÐµ, ÑÑÐŸÐ±Ñ Ð±ÑÑÑ Ð²ÐºÐ»ÑÑÐµÐœÐœÐŸÐ¹ Ð²ÐŸ ÑÑÐ°Ð·ÐŸÐ²ÑÑ ÐžÐµÑÐ°ÑÑ
+ÐžÑ.
+
+Phind.savephrases:ÐÑÐ»Ðž ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐŸ, ÑÐŸ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐŸÐœÐœÐ°Ñ ÑÑÐ°Ð·Ð° Ð±ÑÐŽÐµÑ Ñ
+ÑÐ°ÐœÐžÑÑÑÑ Ð² Ð·Ð°ÐŽÐ°ÐœÐœÐŸÐŒ ÑÐ°Ð¹Ð»Ðµ ÐºÐ°Ðº ÑÐµÐºÑÑ. Ð­ÑÐŸ  Ð²ÐµÑÐŸÑÑÐœÐŸ Ñ
+ÐŸÑÐŸÑÐ°Ñ ÐžÐŽÐµÑ - ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ Ð°Ð±ÑÐŸÐ»ÑÑÐœÑÐ¹ Ð¿ÑÑÑ ÐŽÐŸÑÑÑÐ¿Ð°.
+
+Phind.suffixmode:Smode Ð¿Ð°ÑÐ°ÐŒÐµÑÑ Ðº Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐµ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ÑÑÐ°Ð·Ñ. ÐÐœÐ°ÑÐµÐœÐžÐµ 0 ÐŸÐ·ÐœÐ°ÑÐ°ÐµÑ, ÑÑÐŸ ÑÑÐŸÐ¿-ÑÐ»ÐŸÐ²Ð° ÐžÐ³ÐœÐŸÑÐžÑÑÑÑÑÑ, Ð° 1  -  ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑÑÑÑ.
+
+Phind.text:Ð¢ÐµÐºÑÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÐ¹ ÐŽÐ»Ñ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ ÐžÐµÑÐ°ÑÑ
+ÐžÐž ÑÑÐ°Ð·.
+
+Phind.thesaurus:ÐÐŒÑ ÑÐµÐ·Ð°ÑÑÑÑÐ°, Ñ
+ÑÐ°ÐœÑÑÐµÐ³ÐŸÑÑ Ð² Phind-ÑÐŸÑÐŒÐ°ÑÐµ Ð² ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ðž Ñ.ÐŽ.
+
+Phind.title:ÐÐŸÐ»Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÐŸÐµ ÐŽÐ»Ñ ÐŸÐ¿ÐžÑÐ°ÐœÐžÑ ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°.
+
+Phind.untidy:ÐÐµ ÑÐŽÐ°Ð»ÑÑÑ ÑÐ°Ð±ÐŸÑÐžÐµ ÑÐ°Ð¹Ð»Ñ.
+
+RecentDocumentsList.desc:ÐÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑ, ÐºÐŸÑÐŸÑÑÐ¹ Ð²ÑÐŽÐ°ÐµÑ ÑÐ¿ÐžÑÐŸÐº ÐœÐŸÐ²ÑÑ
+ ÐžÐ·ÐŒÐµÐœÐœÑÑ
+ ÐžÐ»Ðž ÐŽÐŸÐ±Ð°Ð²Ð»ÐµÐœÐœÑÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ².  
+
+RecentDocumentsList.include_docs_added_since:ÐÐºÐ»ÑÑÐ°ÑÑ ÑÐŸÐ»ÑÐºÐŸ ÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ, ÐºÐŸÑÐŸÑÑÐµ Ð±ÑÐ»Ðž ÐžÐ·ÐŒÐµÐœÐµÐœÑ ÐžÐ»Ðž ÐŽÐŸÐ±Ð°Ð²Ð»ÐµÐœÑ Ð² ÑÐºÐ°Ð·Ð°ÐœÐœÑÑ ÐŽÐ°ÑÑ (Ð² ÑÐŸÑÐŒÐ°ÑÐµ Ð³Ð³Ð³Ð³ÐŒÐŒÐŽÐŽ ÐžÐ»Ðž Ð³Ð³Ð³Ð³-ÐŒÐŒ-ÐŽÐŽ)  
+
+RecentDocumentsList.include_most_recently_added:ÐÐºÐ»ÑÑÐ°ÑÑ ÑÐŸÐ»ÑÐºÐŸ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÐŸÐµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ ÑÐ°ÐŒÑÑ
+ Ð¿ÐŸÑÐ»ÐµÐŽÐœÐžÑ
+ ÐŽÐŸÐ±Ð°Ð²Ð»ÐµÐœÐœÑÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ². ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÑÐŸÐ»ÑÐºÐŸ ÐµÑÐ»Ðž ÐœÐµ ÑÐºÐ°Ð·Ð°ÐœÐŸ include_docs_added_since  
+
+RecentDocumentsList.sort:ÐÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐŽÐ»Ñ ÑÐŸÑÑÐžÑÐŸÐ²ÐºÐž Ð¡Ð¿ÐžÑÐºÐ°. ÐÑÐ»Ðž ÐœÐµ ÑÐºÐ°Ð·Ð°ÐœÑ, ÑÐ¿ÐžÑÐŸÐº Ð±ÑÐŽÐµÑ ÐŸÑÑÐŸÑÑÐžÑÐŸÐ²Ð°Ðœ Ð¿ÐŸ ÐŽÐ°ÑÐµ ÐžÐ·ÐŒÐµÐœÐµÐœÐžÑ/ÐŽÐŸÐ±Ð°Ð²Ð»ÐµÐœÐžÑ.  
+
+SectionList.desc:Ð¢ÐŸ Ð¶Ðµ ÑÐ°ÐŒÐŸÐµ, ÑÑÐŸ Ðž ÑÐ¿ÐžÑÐŸÐº ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐŸÐ², ÐœÐŸ Ð²ÐºÐ»ÑÑÐ°ÐµÑ Ð²ÑÐµ ÑÐ°Ð·ÐŽÐµÐ»Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° (ÐžÑÐºÐ»ÑÑÐ°Ñ Ð²ÑÑÑÐžÐ¹ ÑÑÐŸÐ²ÐµÐœÑ), Ð° ÐœÐµ ÑÐŸÐ»ÑÐºÐŸ Ð²ÑÑÑÐžÐ¹ ÑÑÐŸÐ²ÐµÐœÑ ÑÐ°ÐŒÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°.
+
+Collage.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.  
+
+Collage.geometry:ÐÐ·ÐŒÐµÑÐµÐœÐžÑ ÑÐ°Ð·ÐŒÐµÑÐ° ÐºÐŸÐ»Ð»Ð°Ð¶Ð°. ÐÐ»Ñ ÐºÐŸÐ»Ð»Ð°Ð¶Ð° Ð² 600 Ð¿ÐžÐºÑÐµÐ»ÐµÐ¹ ÑÐžÑÐžÐœÐŸÐ¹ Ðž 400 Ð¿ÐžÐºÑÐµÐ»ÐµÐ¹ Ð²ÑÑÐŸÑÐŸÐ¹, ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, ÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÑÑ Ð³ÐµÐŸÐŒÐµÑÑÐžÑ ÐºÐ°Ðº 600x400
+
+Collage.maxDepth:ÐÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÐŽÐ»Ñ ÐºÐŸÐ»Ð»Ð°Ð¶Ð° Ð¿ÑÐŸÑÐžÑÐŸÐ²Ð°ÐœÑ ÐŸÑ Ð·ÐµÑÐºÐ°Ð»ÐžÑÐŸÐ²Ð°ÐœÐžÑ Ðº ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÑ Ð±ÑÐ°ÑÐ·ÐµÑÐ°. Ð­ÑÐŸ ÐºÐŸÐœÑÑÐŸÐ»ÐžÑÑÐµÑ ÐŒÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÑÑ Ð³Ð»ÑÐ±ÐžÐœÑ Ð¿ÑÐŸÑÐµÑÑÐ° Ð·ÐµÑÐºÐ°Ð»ÐžÑÐŸÐ²Ð°ÐœÐžÑ.
+
+Collage.maxDisplay:ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÑÐžÑÐ»ÐŸ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ Ð¿ÐŸÐºÐ°Ð·ÑÐ²Ð°ÐµÐŒÑÑ
+ ÐŸÐŽÐœÐŸÐ²ÑÐµÐŒÐµÐœÐœÐŸ Ð² ÐºÐŸÐ»Ð»Ð°Ð¶Ðµ.
+
+Collage.imageType:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ, ÑÑÐŸÐ±Ñ ÑÐ¿ÑÐ°Ð²Ð»ÑÑÑ, Ð²ÑÑÐ°Ð¶Ð°Ñ ÑÐ°ÑÑÐžÑÐµÐœÐžÐµ ÐžÐŒÐµÐœÐž ÑÐ°Ð¹Ð»Ð°, ÑÐµÑ
+ ÑÐžÐ¿ÐŸÐ² ÑÐ°Ð¹Ð»ÐŸÐ² ÐºÐŸÑÐŸÑÑÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑÑÑÑ Ð² ÐºÐŸÐ»Ð»Ð°Ð¶Ðµ. Ð¡Ð¿ÐžÑÐŸÐº ÑÐ°ÑÑÐžÑÐµÐœÐžÐ¹ ÐžÐŒÐµÐœ ÑÐ°Ð¹Ð»ÐŸÐ² ÐŸÑÐŽÐµÐ»ÐµÐœ ÑÐžÐŒÐ²ÐŸÐ»ÐŸÐŒ Ð¿ÑÐŸÑÐµÐœÑÐ° (%%).
+
+Collage.bgcolor:ÐŠÐ²ÐµÑ ÑÐŸÐœÐ° Ñ
+ÐŸÐ»ÑÑÐ° ÐºÐŸÐ»Ð»Ð°Ð¶Ð°, ÑÐºÐ°Ð·Ð°ÐœÐœÐŸÐ³ÐŸ Ð² ÑÐµÑÑÐœÐ°ÐŽÑÐ°ÑÐžÑÐžÑÐœÐŸÐ¹ ÑÐŸÑÐŒÐµ (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ #008000 ÑÐµÐ·ÑÐ»ÑÑÐ°Ñ: ÑÐµÐŒÐœÐŸ-Ð·ÐµÐ»ÐµÐœÑÐ¹ ÑÐŸÐœ).
+
+Collage.buttonname:Ð¯ÑÐ»ÑÐº ÐŽÐ»Ñ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ° Ð¿ÐŸÐºÐ°Ð·Ð° ÐœÐ° ÑÐºÑÐ°ÐœÐµ Ðž ÐºÐœÐŸÐ¿ÐºÐ° Ð² ÐœÐ°Ð²ÐžÐ³Ð°ÑÐžÐŸÐœÐœÐŸÐ¹ Ð»ÐžÐœÐµÐ¹ÐºÐµ.
+
+Collage.refreshDelay:ÐÐŸÑÐŒÐ°, Ð² ÐŒÐžÐ»Ð»ÐžÑÐµÐºÑÐœÐŽÐ°Ñ
+, Ñ ÐºÐŸÑÐŸÑÐŸÐ¹ ÐŸÐ±ÐœÐŸÐ²Ð»ÑÐµÑÑÑ ÐºÐŸÐ»Ð»Ð°Ð¶.
+
+Collage.isJava2:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ, ÑÑÐŸÐ±Ñ ÑÐ¿ÑÐ°Ð²Ð»ÑÑÑ, ÐœÐµÐºÐŸÑÐŸÑÑÐŒÐž  ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑÑÐžÐŒÐžÑÑ ÐºÐ»Ð°ÑÑÐ°ÐŒÐž-Ð²ÑÐ¿ÐŸÐ»ÐœÐµÐœÐžÑ Java. ÐÐŸÐ»ÐµÐµ Ð¿ÑÐŸÐŽÐ²ÐžÐœÑÑÐ°Ñ Ð²ÐµÑÑÐžÑ Java (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ: Java 1.2 Ðž ÐŽÐ°Ð»ÐµÐµ) Ð²ÐºÐ»ÑÑÐ°ÐµÑ Ð±ÐŸÐ»ÐµÐµ ÐžÑÐºÑÑÐµÐœÐœÑÑ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÑ ÐŽÐ»Ñ ÑÐ¿ÑÐ°Ð²Ð»ÐµÐœÐžÑ Ð¿ÑÐŸÐ·ÑÐ°ÑÐœÐŸÑÑÑÑ Ð² ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑÑ
+, ÑÑÐŸ Ð¿ÐŸÐŒÐŸÐ³Ð°ÐµÑ ÐºÐŸÐœÑÑÐŸÐ»ÐžÑÐŸÐ²Ð°ÑÑ ÑÑÐŸ ÑÐ»ÑÑÐ°ÐµÑÑÑ Ñ ÑÐ»Ð°Ð³ÐŸÐŒ, ÐŸÐŽÐœÐ°ÐºÐŸ Ð²ÑÑÑÐŸÐµÐœÐœÐ°Ñ Ð²ÐµÑÑÐžÑ Java ÐŽÐ»Ñ ÐœÐµÐºÐŸÑÐŸÑÑÑ
+ Ð±ÑÐ°ÑÐ·ÐµÑÐŸÐ² - Ð²ÐµÑÑÐžÑ 1.1. ÐÐ¿Ð¿Ð»ÐµÑ ÑÐ°Ð·ÑÐ°Ð±ÐŸÑÐ°Ðœ ÑÐ°Ðº, ÑÑÐŸÐ±Ñ Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ,  ÐŸÐ±ÐœÐ°ÑÑÐ¶ÐžÐ²Ð°Ð»ÑÑ Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐž, ÐŽÐ»Ñ ÑÐŸÐ¹ Ð²ÐµÑÑÐžÐž Java ÐºÐŸÑÐŸÑÐŸÐ¹ ÐŸÐ±Ð»Ð°ÐŽÐ°ÐµÑ Ð±ÑÐ°ÑÐ·ÐµÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ, ÑÑÐŸ Ð·Ð°ÑÑÐ°Ð²Ð»ÑÐµÑ Ð²ÑÐ¿ÐŸÐ»ÐœÑÑÑÑÑ Ðž ÐŽÐµÐ¹ÑÑÐ²ÐŸÐ²Ð°ÑÑ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐµÐœÐœÐŸ.
+
+Collage.imageMustNotHave:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐŽÐ»Ñ ÑÐ¶Ð°ÑÐžÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹, ÐºÐŸÑÐŸÑÑÐµ ÐœÐµ ÐŽÐŸÐ»Ð¶ÐœÑ Ð¿ÐŸÑÐ²ÐžÑÑÑÑ Ð² ÐºÐŸÐ»Ð»Ð°Ð¶Ðµ, ÑÐžÐ¿Ð° ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ ÐºÐœÐŸÐ¿ÐŸÑÐµÐº, ÐºÐŸÑÐŸÑÑÐµ ÑÐŸÑÑÐ°Ð²Ð»ÑÑÑ ÐœÐ°Ð²ÐžÐ³Ð°ÑÐžÐŸÐœÐœÑÑ Ð¿Ð°ÐœÐµÐ»Ñ.
+
+Collage.caption:ÐÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÑÐµ Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐž, Ð¿ÐŸÐºÐ°Ð·Ð°ÐœÑ ÐœÐžÐ¶Ðµ ÐºÐŸÐ»Ð»Ð°Ð¶Ð°.
+
+
+#
+# Plugin option descriptions
+#
+AcronymExtractor.adding:ÐŽÐŸÐ±Ð°Ð²Ð»ÐµÐœÐžÐµ
+
+AcronymExtractor.already_seen:ÑÐ¶Ðµ Ð·Ð°ÐŒÐµÑÐµÐœÐœÑÐ¹
+
+AcronymExtractor.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ Ð¿ÐŸÐŒÐŸÑÐž ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ° Ðž ÐŸÑÐŒÐµÑÐºÐž Ð°ÐºÑÐŸÐœÐžÐŒÐ° Ð² ÑÐµÐºÑÑÐµ.  
+
+AcronymExtractor.done_acronym_extract:ÐÑÐŸÐžÐ·Ð²ÐµÐŽÐµÐœÐŸ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÐµ Ð°ÐºÑÐŸÐœÐžÐŒÐŸÐ².
+
+AcronymExtractor.done_acronym_markup:ÐÑÐ¿ÐŸÐ»ÐœÐµÐœÐ° Ð¿ÐŸÐŒÐµÑÐºÐ° Ð°ÐºÑÐŸÐœÐžÐŒÐ°.
+
+AcronymExtractor.extract_acronyms:ÐÐºÑÐŸÐœÐžÐŒÑ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÑ ÐžÐ· ÑÐµÐºÑÑÐ° Ðž ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÑ  Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+.
+
+AcronymExtractor.extracting_acronyms:ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÐµ Ð°ÐºÑÐŸÐœÐžÐŒÐŸÐ²
+
+AcronymExtractor.marking_up_acronyms:Ð¿ÐŸÐŒÐµÑÐºÐ° Ð°ÐºÑÐŸÐœÐžÐŒÐŸÐ²
+
+AcronymExtractor.markup_acronyms:ÐÐŸÐ±Ð°Ð²ÐžÑÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ Ð°ÐºÑÐŸÐœÐžÐŒÐ° Ð² ÑÐµÐºÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°.
+
+ArchivesInfPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ, ÐºÐŸÑÐŸÑÑÐ¹ Ð¿ÐŸÐ²ÑÐŸÑÑÐµÑÑÑ Ð² ÑÐ°Ð¹Ð»Ðµ archives.inf (ÑÐŸ ÐµÑÑÑ ÑÐ°Ð¹Ð», Ð³ÐµÐœÐµÑÐžÑÐŸÐ²Ð°ÐœÐœÑÐ¹ Ð² Ð°ÑÑ
+ÐžÐ²ÐœÐŸÐ¹ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž, ÐºÐŸÐ³ÐŽÐ°  Ð²ÑÐ¿ÐŸÐ»ÐœÑÐ»ÑÑ ÐžÐŒÐ¿ÐŸÑÑ ), ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°Ñ ÐºÐ°Ð¶ÐŽÑÐ¹ ÐœÐ°Ð¹ÐŽÐµÐœÐœÑÐ¹ ÑÐ°Ð¹Ð».
+
+AutoExtractMetadata.desc:ÐÐ°Ð·ÐŸÐ²ÑÐ¹ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŽÐ°ÑÑÐžÐ¹ Ð²ÑÑ ÑÑÐœÐºÑÐžÐŸÐœÐ°Ð»ÑÐœÐŸÑÑÑ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ÐžÐ· Ð¿Ð»Ð°Ð³ÐžÐœÐ° Extractor.  
+
+AutoExtractMetadata.extracting:ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÐµ
+
+AutoExtractMetadata.first:ÐÑÐŽÐµÐ»ÐµÐœÐœÑÐ¹ Ð·Ð°Ð¿ÑÑÐŸÐ¹ ÑÐ¿ÐžÑÐŸÐº Ð¿ÐµÑÐ²ÑÑ
+ Ð²ÐµÐ»ÐžÑÐžÐœ ÐŽÐ»Ñ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ÐžÐ· ÑÐµÐºÑÑÐ° Ð² Ð¿ÐŸÐ»Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+. ÐÐŸÐ»Ðµ ÐœÐ°Ð·Ð²Ð°ÐœÐŸ 'FirstNNN'.
+
+BaseMediaConverter.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ Ð¿ÐŸÐŒÐŸÑÐž ÐžÐŒÐµÑÑÐžÐ¹ ÑÑÐœÐºÐžÑ ÐŽÐ»Ñ Ð¿Ð»Ð°Ð³ÐžÐœÐ° ÐŒÐµÐŽÐžÐ° ÐºÐŸÐœÐ²ÐµÑÑÐŸÑÐ°, ÐœÐ°Ð¿ÑÐžÐŒÐµÑ ÐºÐŸÐœÐ²ÐµÑÑÐŸÑÐ° ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ ÐžÐ»Ðž Ð²ÐžÐŽÐµÐŸ ÐºÐŸÐœÐ²ÐµÑÑÐŸÑÐŸÐ².  
+
+BasePlugin.associate_ext:ÐÑÐ·ÑÐ²Ð°ÐµÑ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÑ ÑÐ°Ð¹Ð»ÐŸÐ² Ñ ÑÐµÐŒ Ð¶Ðµ ÐºÐŸÑÐœÐµÐ²ÑÐŒ ÐºÐ°ÑÐ°Ð»ÐŸÐ³ÐŸÐŒ Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐŒ  AND Ð°ÑÑÐŸÑÐžÐžÑÑÐµÑ Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒÐž ÑÐ¿ÐžÑÐŸÐº ÑÐ°ÑÑÐžÑÐµÐœÐžÑ ÑÐ°Ð¹Ð»ÐŸÐ², Ð¿ÐµÑÐµÑÐžÑÐ»ÐµÐœÐœÑÑ
+ ÑÐµÑÐµÐ· Ð·Ð°Ð¿ÑÑÑÑ, Ð¿ÐµÑÐµÐŽÐ°Ð²Ð°ÐµÐŒÑÐ¹ Ð·ÐŽÐµÑÑ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ Ð°ÑÐ³ÑÐŒÐµÐœÑÐ°.
+
+BasePlugin.associate_tail_re:Ð ÐµÐ³ÑÐ»ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ ÐŽÐ»Ñ ÑÐŸÑÐµÑÐ°ÐœÐžÑ ÐžÐŒÐµÐœ ÑÐ°Ð¹Ð»ÐŸÐ² ÐœÐ°Ð¹ÐŽÐµÐœÐœÑÐŒ ÑÐ°Ð¹Ð»Ð°ÐŒ. ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐºÐ°Ðº Ð±ÐŸÐ»ÐµÐµ ÐŒÐŸÑÐœÐ°Ñ Ð°Ð»ÑÑÐµÑÐœÐ°ÑÐžÐ²Ð° ÐŽÐ»Ñ associate_ext.  
+
+BasePlugin.block_exp:Ð€Ð°Ð¹Ð»Ñ, ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÑÑÐžÐµ ÑÑÐŸÐŒÑ Ð¿ÑÐ°Ð²ÐžÐ»ÑÐœÐŸÐŒÑ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÑ, Ð±ÑÐŽÑÑ Ð·Ð°Ð±Ð»ÐŸÐºÐžÑÐŸÐ²Ð°ÐœÑ ÐŸÑ ÑÐŸÐ³ÐŸ, ÑÑÐŸÐ±Ñ Ð±ÑÑÑ Ð¿ÐµÑÐµÐŽÐ°ÐœÐœÑÐŒÐž Ð»ÑÐ±ÐŸÐŒÑ ÐŽÐ°Ð»ÑÐœÐµÐ¹ÑÐµÐŒÑ Ð¿Ð»Ð°Ð³ÐžÐœÑ Ð² ÑÐ¿ÐžÑÐºÐµ. Ð­ÑÐŸ ÐœÐµ ÐžÐŒÐµÐµÑ ÐœÐžÐºÐ°ÐºÐŸÐ³ÐŸ ÐŽÑÑÐ³ÐŸÐ³ÐŸ ÑÐµÐ°Ð»ÑÐœÐŸÐ³ÐŸ ÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐžÑ, ÑÐµÐŒ Ð¿ÑÐµÐŽÐŸÑÐ²ÑÐ°ÑÐžÑÑ Ð±ÐŸÐ»ÑÑÐŸÐµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ Ð¿ÑÐµÐŽÑÐ¿ÑÐµÐ¶ÐŽÐ°ÑÑÐžÑ
+ ÑÐŸÐŸÐ±ÑÐµÐœÐžÐ¹ ÐŸ Ð²Ñ
+ÐŸÐŽÐœÑÑ
+ ÑÐ°Ð¹Ð»Ð°Ñ
+, ÐºÐŸÑÐŸÑÑÐŒ ÐÑ ÐœÐµ ÑÐŽÐµÐ»ÑÐµÑÐµ Ð²ÐœÐžÐŒÐ°ÐœÐžÑ. ÐÐ°Ð¶ÐŽÑÐ¹ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŒÐŸÐ³ Ð±Ñ ÐžÐŒÐµÑÑ Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ block_exp., ÐºÐ°Ðº ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, HTMLPlug  Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ Ð±Ð»ÐŸÐºÐžÑÑÐµÑ Ð»ÑÐ±ÑÐµ ÑÐ°Ð¹Ð»Ñ Ñ  ÑÐ°ÑÑÐžÑÐµÐœÐžÐµÐŒ .gif, .jpg, .jpeg, .png ÐžÐ»Ðž .css.
+
+BasePlugin.desc:ÐÑÐœÐŸÐ²ÐœÐŸÐ¹ ÐºÐ»Ð°ÑÑ ÐŽÐ»Ñ Ð²ÑÐµÐ³ÐŸ Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐ² ÐžÐŒÐ¿ÐŸÑÑÐ°.
+
+BasePlugin.dummy_text:ÐÐ°ÐœÐœÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ ÐœÐµ ÐžÐŒÐµÐµÑ ÑÐµÐºÑÑÐ°.
+
+BasePlugin.encoding.ascii:ÐÑÐŸÑÑÐŸÐ¹ 7-Ð±ÐžÑÐœÑÐ¹ ascii. ÐÐœ ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ ÐœÐµÐŒÐœÐŸÐ³ÐŸ Ð±ÑÑÑÑÐµÐµ, ÑÐµÐŒ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµ iso_8859_1. ÐÑÑÐµÑÐµÐ³Ð°Ð¹ÑÐµÑÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ ÑÑÐŸÐ³ÐŸ Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÐºÐŸÑÐŸÑÑÐµ ÐŒÐŸÐ³ÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÑÑ ÑÐžÐŒÐ²ÐŸÐ»Ñ Ð²ÐœÐµ Ð¿ÑÐŸÑÑÑÑ
+ 7-Ð±ÐžÑÐœÑÑ
+ ÐœÐ°Ð±ÐŸÑÐŸÐ² ascii (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, ÐœÐµÐŒÐµÑÐºÐžÐµ ÐžÐ»Ðž ÑÑÐ°ÐœÑÑÐ·ÑÐºÐžÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°Ñ Ð·ÐœÐ°ÐºÐž ÑÐŽÐ°ÑÐµÐœÐžÑ), ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ Ð²ÐŒÐµÑÑÐŸ ÑÑÐŸÐ³ÐŸ iso_8859_1.
+
+BasePlugin.encoding.unicode:Ð¢ÐŸÐ»ÑÐºÐŸ ÑÐœÐžÐºÐŸÐŽ.
+
+BasePlugin.encoding.utf8:ÐÐ»Ðž utf8, ÐžÐ»Ðž ÑÐœÐžÐºÐŸÐŽ - Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐž ÐŸÐ±ÐœÐ°ÑÑÐ¶ÐµÐœÐœÑÐµ.
+
+BasePlugin.filename_encoding:ÐÐµÑÐµÐºÐŸÐŽÐžÑÐŸÐ²ÐºÐ° ÐžÑÑÐŸÑÐœÐžÐºÐŸÐ² ÐŽÐ»Ñ ÐžÐŒÐµÐœ ÑÐ°Ð¹Ð»ÐŸÐ²  
+
+BasePlugin.filename_encoding.auto:ÐÐ²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐž ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐžÑÑ ÐžÐŒÑ ÑÐ°Ð¹Ð»Ð°  
+
+BasePlugin.filename_encoding.auto_language_analysis:ÐÐ²ÑÐŸÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÐµ ÐŽÐµÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÑ ÐžÐŒÐµÐœ ÑÐ°Ð¹Ð»ÐŸÐ² Ñ Ð¿ÐŸÐŒÐŸÑÑÑ Ð°ÐœÐ°Ð»ÐžÐ·Ð°.  
+
+BasePlugin.filename_encoding.auto_filesystem_encoding:ÐÐ²ÑÐŸÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÐµ ÐºÐŸÐŽÐµÐºÐ° ÐŽÐ»Ñ ÐžÐŒÐµÐœÐž ÑÐ°Ð¹Ð»Ð° ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ ÐŽÐµÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÐµ Ð² ÑÐ°Ð¹Ð»ÐŸÐ²ÐŸÐ¹ ÑÐžÑÑÐµÐŒÐµ  
+
+BasePlugin.filename_encoding.auto_fl:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑ ÐŽÐµÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÐµ ÑÐ°Ð¹Ð»ÐŸÐ²ÐŸÐ¹ ÑÐžÑÑÐµÐŒÑ Ðž Ð·Ð°ÑÐµÐŒ ÑÐ·ÑÐºÐŸÐ²ÐŸÐ¹ Ð°ÐœÐ°Ð»ÐžÐ· ÐŽÐ»Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÑ ÐŽÐµÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÑ ÐžÐŒÐµÐœÐž ÑÐ°Ð¹Ð»Ð°  
+
+BasePlugin.filename_encoding.auto_lf:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÑ ÑÐ·ÑÐºÐŸÐ²ÐŸÐ¹ Ð°ÐœÐ°Ð»ÐžÐ· Ð·Ð°ÑÐµÐŒ ÐŽÐµÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÐµ ÑÐ°Ð¹Ð»ÐŸÐ²ÐŸÐ¹ ÑÐžÑÑÐµÐŒÑ ÐŽÐ»Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÑ ÐŽÐµÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÑ ÐžÐŒÐµÐœÐž ÑÐ°Ð¹Ð»Ð°  
+
+BasePlugin.no_blocking:ÐÐµ ÐŸÑÐºÑÑÐ²Ð°Ð¹ÑÐµ Ðž ÐœÐµ Ð±Ð»ÐŸÐºÐžÑÑÐ¹ÑÐµ ÑÐ°Ð¹Ð»Ñ. ÐÑÐ±ÑÐµ Ð°ÑÑÐŸÑÐžÐžÑÐŸÐ²Ð°ÐœÐœÑÐµ ÑÐ°Ð¹Ð»Ñ (ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÐœÐ° Ð²ÐµÐ± ÑÑÑÐ°ÐœÐžÑÐµ) Ð±ÑÐŽÑÑ ÐŽÐŸÐ±Ð°Ð²Ð»ÐµÐœÑ Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ².  
+
+BasePlugin.no_cover_image:ÐÐµ ÐŸÐ±ÑÐ°ÑÐ°Ð¹ÑÐµ Ð²ÐœÐžÐŒÐ°ÐœÐžÑ ÐœÐ° ÑÐ°Ð¹Ð» prefix.jpg (Ð³ÐŽÐµ prefix - ÑÑÐŸ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÐŒÐŸÐ³ÐŸ ÑÐ°Ð¹Ð»Ð°). Ð­ÑÐŸ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐµ ÐŸÐ±Ð»ÐŸÐ¶ÐºÐž.
+
+BasePlugin.OIDtype.auto:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐœÐ°Ð±ÐŸÑ OIDtype Ð² import.pl  
+
+BasePlugin.process_exp:ÐÐ±ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ Perl ÐŽÐ»Ñ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐžÑ  ÐžÐŒÐµÐœÐ°ÐŒ ÑÐ°Ð¹Ð»Ð°. Ð¡ÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐžÐµ ÐžÐŒÐµÐœÐ°ÐŒ ÑÐ°Ð¹Ð»Ð° Ð±ÑÐŽÐµÑ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÐœÐŸ ÑÑÐžÐŒ Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐŒ. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµ '(?i).html?\$' ÑÐŸÑÐ²ÐµÑÑÑÐ²ÑÐµÑ Ð²ÑÐµÐŒ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒ, Ð·Ð°ÐºÐ°ÐœÑÐžÐ²Ð°ÑÑÐžÐŒÑÑ ÐœÐ° .htm ÐžÐ»Ðž .html (Ð±ÐµÐ· ÑÐ°Ð·Ð»ÐžÑÐµÐœÐžÑ Ð·Ð°Ð³Ð»Ð°Ð²ÐœÑÑ
+ Ðž ÑÑÑÐŸÑÐœÑÑ
+ Ð±ÑÐºÐ²).
+
+BasePlugin.smart_block:ÐÐ»ÐŸÐºÐžÑÐŸÐ²ÐºÐ° ÑÐ°Ð¹Ð»ÐŸÐ² ÑÐ»ÑÑÑÐµÐœÐœÑÐŒ ÐŒÐµÑÐŸÐŽÐŸÐŒ, Ð²ÐŒÐµÑÑÐŸ Ð¿ÑÐŸÑÑÐŸÐ³ÐŸ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ° ÐœÐ°Ð·Ð²Ð°ÐœÐžÐ¹ ÑÐ°Ð¹Ð»ÐŸÐ².  
+
+BasePlugin.stems:ÑÑÐµÐ±Ð»Ðž  
+
+BasePlugin.file_rename_method:ÐÐµÑÐŸÐŽ ÐŽÐ»Ñ Ð¿ÐµÑÐžÐŒÐµÐœÐŸÐ²Ð°ÐœÐžÑ ÐºÐŸÐ¿ÐžÐž ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐ³ÐŸ ÑÐ°Ð¹Ð»Ð° Ðž Ð°ÑÑÐŸÑÐžÐžÑÐŸÐ²Ð°ÐœÐœÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ².  
+
+BasePlugin.rename_method.url:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐŽÐµÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÐµ URL Ðž Ð¿ÐµÑÐµÐžÐŒÐµÐœÐŸÐ²Ð°ÐœÐžÐµ ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐœÑÑ
+ Ðž Ð°ÑÑÐŸÑÐžÐžÑÐŸÐ²Ð°ÐœÐœÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ²  
+
+BasePlugin.rename_method.base64:ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµ ÐŽÐµÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÐµ base64 ÐŽÐ»Ñ Ð¿ÐµÑÐµÐžÐŒÐµÐœÐŸÐ²Ð°ÐœÐžÑ ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐœÑÑ
+ Ðž Ð°ÑÑÐŸÑÐžÐžÑÐŸÐ²Ð°ÐœÐœÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ².  
+
+BasePlugin.rename_method.none:ÐÐµ Ð¿ÐµÑÐµÐžÐŒÐµÐœÐŸÐ²ÑÐ²Ð°Ð¹ÑÐµ Ð¿ÑÐŸÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐœÑÐµ Ðž Ð°ÑÑÐŸÑÐžÐžÑÐŸÐ²Ð°ÐœÐœÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ²  
+
+BibTexPlugin.desc:BibTexPlug ÑÐžÑÐ°ÐµÑ Ð±ÐžÐ±Ð»ÐžÐŸÐ³ÑÐ°ÑÐžÑÐµÑÐºÐžÐµ ÑÐ°Ð¹Ð»Ñ Ð² ÑÐŸÑÐŒÐ°ÑÐµ BibTex. BibTexPlug ÑÐŸÐ·ÐŽÐ°ÐµÑ ÐŸÐ±ÑÐ°Ð· ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ¹ ÑÑÑÐ»ÐºÐž Ð² ÑÐ°Ð¹Ð»Ðµ. Ð­ÑÐŸ - Ð¿ÐŸÐŽÐºÐ»Ð°ÑÑ SplitPlug, ÑÐ°Ðº ÑÑÐŸ ÐµÑÐ»Ðž ÐžÐŒÐµÑÑÑÑ ÐŒÐœÐŸÐ¶ÐµÑÑÐ²ÐµÐœÐœÑÐµ Ð·Ð°Ð¿ÐžÑÐž, ÑÐŸ Ð²ÑÐµ ÐŸÐœÐž ÑÐžÑÐ°ÑÑÑÑ.  
+
+BookPlugin.desc:Ð¡ÐŸÐ·ÐŽÐ°ÐµÑÑÑ ÐŒÐœÐŸÐ³ÐŸÑÑÐŸÐ²ÐœÐµÐ²ÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ ÐžÐ· ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°, ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐµÐ³ÐŸ ÑÑÐ³Ðž ÑÑÐŸÐ²ÐœÑ <<TOC>>. ÐÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ  ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ ÑÐ°Ð·ÐŽÐµÐ»Ð° Ð²Ð·ÑÑÑ ÐžÐ· Ð»ÑÐ±ÐŸÐ³ÐŸ ÐŽÑÑÐ³ÐŸÐ³ÐŸ ÑÑÐ³Ð° Ð² ÑÐŸÐ¹ Ð¶Ðµ ÑÐ°ÐŒÐŸÐ¹ ÑÑÑÐŸÐºÐµ, ÐºÐ°Ðº Ðž <<TOC>>. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, <<Title>>xxxx<</Title>>  ÑÑÑÐ°ÐœÐ°Ð²Ð»ÐžÐ²Ð°ÐµÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐœÐ°Ð·Ð²Ð°ÐœÐžÑ. ÐÑÐµ ÐŸÑÑÐ°Ð»ÑÐœÐŸÐµ ÐŒÐµÐ¶ÐŽÑ ÑÑÐ³Ð°ÐŒÐž ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑÑÑ ÐºÐ°Ðº Ð¿ÑÐŸÑÑÐŸÐ¹ html (ÑÐŸ ÐµÑÑÑ ÐœÐžÐºÐ°ÐºÐŸÐ¹ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž ÑÐ²ÑÐ·ÐµÐ¹ html ÐžÐ»Ðž Ð»ÑÐ±ÑÑ
+ ÐŽÑÑÐ³ÐžÑ
+ Ð²ÐžÐŽÐŸÐ² HTMLPlug  ÐœÐµ Ð¿ÑÐŸÐžÐ·Ð²ÐŸÐŽÐžÑÑÑ). ÐÐ¶ÐžÐŽÐ°ÐµÑÑÑ, ÑÑÐŸ Ð²Ñ
+ÐŸÐŽÐœÑÐµ ÑÐ°Ð¹Ð»Ñ ÐžÐŒÐµÑÑ ÑÐ°ÑÑÐžÑÐµÐœÐžÐµ .hb Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ. Ð­ÑÐŸ ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ ÐžÐ·ÐŒÐµÐœÐµÐœÐŸ ÐŽÐŸÐ±Ð°Ð²Ð»ÐµÐœÐžÐµÐŒ ÐŸÐ¿ÑÐžÐž -process_exp Ðº  ÑÐ°Ð¹Ð»Ñ Ñ ÑÐµÐŒ Ð¶Ðµ ÑÐ°ÐŒÑÐŒ ÐžÐŒÐµÐœÐµÐŒ, ÑÑÐŸ Ðž hb ÑÐ°Ð¹Ð», ÐœÐŸ ÑÐ°ÑÑÐžÑÐµÐœÐžÐµ .jpg Ð²Ð·ÑÑÐŸ ÐŽÐ»Ñ ÐŸÐ±Ð»ÐŸÐ¶ÐºÐž ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ (jpg ÑÐ°Ð¹Ð»Ñ Ð±Ð»ÐŸÐºÐžÑÑÑÑÑÑ ÑÑÐžÐŒ Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐŒ). BookPlug ÑÐ²Ð»ÑÐµÑÑÑ ÑÐ¿ÑÐŸÑÐµÐœÐžÐµÐŒ (Ðž ÑÐ°ÑÑÐžÑÐµÐœÐžÐµÐŒ) HBPlug, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÐŸÐ³ÐŸ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŒÐž ÐÑÐŒÐ°ÐœÐžÑÐ°ÑÐœÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž. BookPlug ÑÐ²Ð»ÑÐµÑÑÑ Ð±ÐŸÐ»ÐµÐµ Ð±ÑÑÑÑÑÐŒ, Ð¿ÐŸÑÐºÐŸÐ»ÑÐºÑ Ð¿ÑÐµÐŽÐ¿ÐŸÐ»Ð°Ð³Ð°ÐµÑÑÑ, ÑÑÐŸ Ð²Ñ
+ÐŸÐŽÐœÑÐµ ÑÐ°Ð¹Ð»Ñ ÐŽÐŸÐ»Ð¶ÐœÑ Ð±ÑÑÑ Ð±ÐŸÐ»ÐµÐµ ÑÐžÑÑÑÐŒÐž (Ð²Ñ
+ÐŸÐŽ Ðº HDL ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŒ ÑÐŸÐŽÐµÑÐ¶ÐžÑ ÐŒÐœÐŸÐ¶ÐµÑÑÐ²ÐŸ ÐŽÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÑÑ
+ ÑÑÐ³ÐŸÐ² html Ð²ÐŸÐºÑÑÐ³  ÑÑÐ³ÐŸÐ² <<TOC>>, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ ÑÑÐ³Ðž <<I>>, ÑÑÐŸÐ±Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐžÑÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ, Ðž Ð¿ÑÐŸÑÑÐŸ Ð±ÐµÑÑÑ Ð²ÐµÑÑ ÑÐµÐºÑÑ ÐŒÐµÐ¶ÐŽÑ ÑÑÐ³Ð°ÐŒÐž <<TOC>>, Ð° ÐœÐ°ÑÐ°Ð»ÐŸÐŒ ÑÐµÐºÑÑÐ° ÐŽÐŸÐ»Ð¶ÐœÑ Ð±ÑÑÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐÐ°Ð·Ð²Ð°ÐœÐžÑ). ÐÑÐ»Ðž ÐÑ Ð¿ÐŸÐŒÐµÑÐ°ÐµÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ, ÐºÐŸÑÐŸÑÑÐµ Ð±ÑÐŽÑÑ Ð¿ÐŸÐºÐ°Ð·Ð°ÐœÑ ÑÐµÐŒ Ð¶Ðµ ÑÐ°ÐŒÑÐŒ ÑÐ¿ÐŸÑÐŸÐ±ÐŸÐŒ, ÑÑÐŸ Ðž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ HDL, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ ÑÑÐŸÑ Ð¿Ð»Ð°Ð³ÐžÐœ Ð²ÐŒÐµÑÑÐŸ HBPlug.  
+
+CONTENTdmPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÑÑÐžÐ¹ RDF ÑÐ°Ð¹Ð»Ñ Ð² Ð¿ÑÐŸÑÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐœÑÑ
+ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÑ
+ CONTENTdm.  
+
+ConvertBinaryFile.apply_fribidi:ÐÑÐ¿ÐŸÐ»ÐœÐžÑÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑ "fribidi" Unicode Bidirectional Algorithm ÐœÐ° ÑÐºÐŸÐœÐ²ÐµÑÑÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐŒ ÑÐ°Ð¹Ð»Ðµ (Ñ ÑÐµÐºÑÑÐŸÐŒ ÑÐ¿ÑÐ°Ð²Ð° ÐœÐ°Ð»ÐµÐ²ÐŸ).  
+
+ConvertBinaryFile.convert_to:ÐÐ»Ð°Ð³ÐžÐœ ÐºÐŸÐœÐ²ÐµÑÑÐžÑÑÐµÑ Ð² TEXT, ÐžÐ»Ðž HTML, ÐžÐ»Ðž ÑÐ°Ð·Ð»ÐžÑÐœÑÐµ ÑÐžÐ¿Ñ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, JPEG, GIF, PNG).  
+
+ConvertBinaryFile.convert_to.auto:Ð¢Ð°ÐºÐ¶Ðµ Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐž Ð²ÑÐ±ÐžÑÐ°ÐµÑÑÑ ÑÐŸÑÐŒÐ°Ñ ÐŽÐ»Ñ ÐºÐŸÐœÐ²ÐµÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ. ÐÑÐ±ÐŸÑ ÑÐŸÑÐŒÐ°ÑÐ° Ð·Ð°Ð²ÐžÑÐžÑ ÐŸÑ ÑÐžÐ¿Ð° ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°. ÐÐ° Ð¿ÑÐžÐŒÐµÑ, Word Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐž ÐºÐŸÐœÐ²ÐµÑÑÐžÑÑÐµÑÑÑ Ð² HTML, Ð² ÑÐŸ Ð²ÑÐµÐŒÑ ÐºÐ°Ðº PowerPoint Ð² ÑÐŸÑÐŒÐ°Ñ ÐÑÐžÐœÑÑÐŸÑÐœ ÑÑÑÐ°ÐœÐžÑÐœÐ°Ñ ÐžÐ»Ð»ÑÑÑÑÐ°ÑÐžÑ (PagedImage).  
+
+ConvertBinaryFile.convert_to.html:Ð€ÐŸÑÐŒÐ°Ñ HTML.  
+
+ConvertBinaryFile.convert_to.text:Ð€ÐŸÑÐŒÐ°Ñ Ð¿ÑÐŸÑÑÐŸÐ³ÐŸ ÑÐµÐºÑÑÐ°.  
+
+ConvertBinaryFile.convert_to.pagedimg:Ð¡ÐµÑÐžÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹.  
+
+ConvertBinaryFile.convert_to.pagedimg_jpg:Ð¡ÐµÑÐžÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ Ð² ÑÐŸÑÐŒÐ°ÑÐµ JPEG.  
+
+ConvertBinaryFile.convert_to.pagedimg_gif:Ð¡ÐµÑÐžÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ Ð² ÑÐŸÑÐŒÐ°ÑÐµ GIF.  
+
+ConvertBinaryFile.convert_to.pagedimg_png:Ð¡ÐµÑÐžÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ Ð² ÑÐŸÑÐŒÐ°ÑÐµ PNG.  
+
+ConvertBinaryFile.desc:Ð­ÑÐŸÑ Ð¿Ð»Ð°Ð³ÐžÐœ Ð¿ÐµÑÐµÐŽÐ°ÐµÑÑÑ Ð¿ÐŸ ÐœÐ°ÑÐ»ÐµÐŽÑÑÐ²Ñ Ð¿Ð»Ð°Ð³ÐžÐœÐ°ÐŒ ÑÐ°ÐºÐžÐŒ ÐºÐ°Ðº WordPlug Ðž PDFPlug. ÐÐœ Ð¿ÐŸÐŒÐŸÐ³Ð°ÐµÑ ÐºÐŸÐœÐ²ÐµÑÑÐžÑÐŸÐ²Ð°ÑÑ ÑÑÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð² ÑÐŸÑÐŒÐ°ÑÑ HTML ÐžÐ»Ðž TEXT ÑÐµÐŒ, ÑÑÐŸ ÑÐºÐ°Ð·ÑÐ²Ð°ÐµÑ Ð·ÐœÐ°ÑÐµÐœÐžÑ Ð¿ÐµÑÐµÐŒÐµÐœÐœÑÑ
+, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÑ
+ Ð² ÑÐ°Ð±ÐŸÑÐµ Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐŒ ConvertToBasPlug. Ð­ÑÐŸ Ð¿ÑÐŸÐžÑÑ
+ÐŸÐŽÐžÑ ÐŽÐžÐœÐ°ÐŒÐžÑÐœÐŸ Ñ Ð¿ÐŸÐŒÐŸÑÑÑ Ð¿ÐµÑÐµÐŽÐ°ÑÐž Ð¿ÐŸ ÐœÐ°ÑÐ»ÐµÐŽÑÑÐ²Ñ Ð°ÑÐ³ÑÐŒÐµÐœÑÐ° Ð¿Ð»Ð°Ð³ÐžÐœÐ° 'convert_to' Ð¿Ð»Ð°Ð³ÐžÐœÐ°ÐŒÐž HTMLPlug ÐžÐ»Ðž TEXTPlug. ÐÑÐ»Ðž Ð°ÑÐ³ÑÐŒÐµÐœÑ ÐœÐµ ÑÑÑÐµÑÑÐ²ÑÐµÑ, Ð¿ÐµÑÐµÐŽÐ°ÐµÑÑÑ Ð·ÐœÐ°ÑÐµÐœÐžÐµ Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ.  
+
+ConvertBinaryFile.keep_original_filename:Ð¡ÐŸÑ
+ÑÐ°ÐœÐžÑÑ ÐŸÑÐžÐ³ÐžÐœÐ°Ð»ÑÐœÐŸÐµ ÐžÐŒÑ ÑÐ°Ð¹Ð»Ð° ÐŽÐ»Ñ Ð°ÑÑÐŸÑÐžÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐ³ÐŸ ÑÐ°Ð¹Ð»Ð°, Ð° ÐœÐµ Ð¿ÑÐµÐŸÐ±ÑÐ°Ð·ÐŸÐ²Ð°ÐœÐžÐµ Ð² doc.pdf, doc.doc Ðž Ñ.ÐŽ.  
+
+ConvertBinaryFile.use_strings:ÐÑÐ»Ðž ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐŸ, ÑÐŸ Ð¿ÑÐŸÑÑÐ°Ñ  ÑÑÑÐŸÐºÐŸÐ²Ð°Ñ ÑÑÐœÐºÑÐžÑ Ð±ÑÐŽÐµÑ Ð²ÑÐ·ÑÐ²Ð°ÑÑÑÑ ÐŽÐ»Ñ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ÑÐµÐºÑÑÐ°, ÐµÑÐ»Ðž ÑÑÐžÐ»ÐžÑÐ° ÐºÐŸÐœÐ²ÐµÑÑÐžÐž ÐœÐµ ÑÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑ.  
+
+ConvertToRogPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ, ÐºÐŸÑÐŸÑÑÐ¹ ÐœÐ°ÑÐ»ÐµÐŽÑÐµÑ RogPlug.  
+
+CSVPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÑÐ°Ð¹Ð»ÐŸÐ² Ð² ÑÐŸÑÐŒÐ°ÑÐµ Ð·ÐœÐ°ÑÐµÐœÐžÐ¹, ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐœÑÑ
+ Ð·Ð°Ð¿ÑÑÐŸÐ¹. ÐÐ° ÐºÐ°Ð¶ÐŽÑÑ ÑÑÑÐŸÑÐºÑ ÑÐ°Ð¹Ð»Ð° Ð±ÑÐŽÐµÑ ÑÐŸÐ·ÐŽÐ°Ðœ ÐœÐŸÐ²ÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ.  
+
+DateExtractor.desc:ÐÐ»Ð°Ð³ÐžÐœ Ð¿ÐŸÐŒÐŸÑÐž ÑÐºÑÑÑÐ°ÐºÑÐŸÑÐ° ÐŽÐ»Ñ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ÐžÑÑÐŸÑÐžÑÐµÑÐºÐžÑ
+ ÐŽÐ°Ñ ÐžÐ· ÑÐµÐºÑÑÐ°.  
+
+DateExtractor.extract_historical_years:ÐÐ·Ð²Ð»ÐµÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ Ð²ÑÐµÐŒÐµÐœÐœÐŸÐŒ Ð¿ÐµÑÐžÐŸÐŽÐµ ÐžÐ· ÐžÑÑÐŸÑÐžÑÐµÑÐºÐžÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ². ÐÐœÐ° Ñ
+ÑÐ°ÐœÐžÑÑÑ Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐŒ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+. ÐÐŒÐµÐµÑÑÑ ÐžÐœÑÐµÑÑÐµÐ¹Ñ Ð¿ÐŸÐžÑÐºÐ° ÐŽÐ»Ñ ÑÑÐžÑ
+ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, ÐºÐŸÑÐŸÑÑÐ¹ ÐÑ ÐŒÐŸÐ¶ÐµÑÐµ Ð²ÐºÐ»ÑÑÐžÑÑ Ð² ÐÐ°ÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ, ÐŽÐŸÐ±Ð°Ð²Ð»ÑÑ ÐŸÐ¿ÐµÑÐ°ÑÐŸÑ"format QueryInterface DateSearch" Ðº ÐÐ°ÑÐµÐŒÑ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐŸÐœÐœÐŸÐŒÑ ÑÐ°Ð¹Ð»Ñ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.
+
+DateExtractor.maximum_century:ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐµ Ð·ÐœÐ°ÑÐµÐœÐžÐµ ÐœÐ°Ð·Ð²Ð°ÐœÐœÐŸÐ³ÐŸ ÑÑÐŸÐ»ÐµÑÐžÑ, ÐºÐŸÑÐŸÑÐŸÐµ Ð±ÑÐŽÐµÑ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐŸ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÐžÑÑÐŸÑÐžÑÐµÑÐºÐžÑ
+ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, 14 ÐžÐ·Ð²Ð»ÐµÑÐµÑ Ð²ÑÐµ ÑÑÑÐ»ÐºÐž, ÐŸÑÐœÐŸÑÑÑÐžÐµÑÑ Ðº 14-ÐŸÐŒÑ ÑÑÐŸÐ»ÐµÑÐžÑ).
+
+DateExtractor.maximum_year:ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐ°Ñ ÐžÑÑÐŸÑÐžÑÐµÑÐºÐ°Ñ ÐŽÐ°ÑÐ°, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐœÐ°Ñ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ (ÐŽÐ°ÑÐ° ÑÑÑ, ÑÐžÐ¿Ð° 1950).
+
+DateExtractor.no_bibliography:ÐÐµ Ð¿ÑÐŸÐ±ÑÐ¹ÑÐµ Ð±Ð»ÐŸÐºÐžÑÐŸÐ²Ð°ÑÑ Ð±ÐžÐ±Ð»ÐžÐŸÐ³ÑÐ°ÑÐžÑÐµÑÐºÐžÐµ ÐŽÐ°ÑÑ Ð¿ÑÐž ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÐž ÐžÑÑÐŸÑÐžÑÐµÑÐºÐžÑ
+ ÐŽÐ°Ñ.
+
+DirectoryPlugin.desc:RecPlug - ÑÑÐŸ Ð¿Ð»Ð°Ð³ÐžÐœ, ÐºÐŸÑÐŸÑÑÐ¹ Ð¿ÐŸÐ²ÑÐŸÑÑÐµÑÑÑ Ð² ÐºÐ°Ð¶ÐŽÐŸÐ¹ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž, ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°Ñ ÐºÐ°Ð¶ÐŽÑÐ¹ ÑÐ°Ð¹Ð», ÐºÐŸÑÐŸÑÑÐ¹ ÐŸÐœ ÐœÐ°Ñ
+ÐŸÐŽÐžÑ.
+
+DirectoryPlugin.recheck_directories:ÐÐŸÑÐ»Ðµ ÑÐŸÐ³ÐŸ, ÐºÐ°Ðº ÑÐ°Ð¹Ð»Ñ Ð² Ð¿Ð°Ð¿ÐºÐµ ÐžÐŒÐ¿ÐŸÑÑÐ° Ð±ÑÐ»Ðž ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÐœÑ, Ð¿Ð°Ð¿ÐºÐ° Ð¿ÐŸÐ²ÑÐŸÑÐœÐŸ Ð¿ÑÐŸÑÐžÑÑÐ²Ð°ÐµÑÑÑ, ÑÑÐŸÐ±Ñ ÐŸÐ±ÐœÐ°ÑÑÐ¶ÐžÑÑ Ð»ÑÐ±ÑÐµ Ð²ÐœÐŸÐ²Ñ ÑÐŸÐ·ÐŽÐ°ÐœÐœÑÐµ ÑÐ°Ð¹Ð»Ñ.
+
+DirectoryPlugin.use_metadata_files:(ÐÐÐÐÐÐÐÐ« - Ð²ÐŒÐµÑÑÐŸ, ÐŽÐŸÐ±Ð°Ð²ÐžÑÑ Ð¿Ð»Ð°Ð³ÐžÐœ MetadataXMLPlugin Ðº ÑÐ¿ÐžÑÐºÑ Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐ²) Ð§ÐžÑÐ°ÑÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐžÐ· XML-ÑÐ°Ð¹Ð»ÐŸÐ².  
+
+DatabasePlugin.desc:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑ Ð·Ð°Ð¿ÐžÑÐž ÐžÐ· Ð±Ð°Ð·Ñ ÐŽÐ°ÐœÐœÑÑ
+  ÐºÐ°Ðº ÐŽÐŸÐºÑÐŒÐµÐœÑÑ.
+
+DSpacePlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÑÑÐžÑÑÐ²Ð°ÐµÑ ÑÐºÑÐ¿ÐŸÑÑÐžÑÑÐµÐŒÑÐµ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÐžÐ· DSpace Ðž ÐžÐŒÐ¿ÐŸÑÑÐžÑÑÐµÑ Ð² ÐÑÐžÐœÑÑÐŸÑÐœ.  
+	
+DSpacePlugin.first_inorder_ext:Ð­ÑÐ° ÐŸÐ¿ÑÐžÑ Ð¿ÑÐµÐŽÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐ° ÐŽÐ»Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÑ Ð¿ÐµÑÐ²ÐŸÑÑÐµÐ¿ÐµÐœÐœÐŸÐ³ÐŸ Ð¿ÐŸÑÐŸÐºÐ° ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² DSpace. ÐÑÐŸÐ³ÑÐ°ÐŒÐŒÐ° Ð±ÑÐŽÐµÑ ÐžÑÐºÐ°ÑÑ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÑÐ¹ Ð¿ÐµÑÐ²ÐŸÑÑÐµÐ¿ÐµÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» ext.  
+
+DSpacePlugin.first_inorder_mime:Ð­ÑÐ° ÐŸÐ¿ÑÐžÑ Ð¿ÑÐµÐŽÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐ° ÐŽÐ»Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÑ Ð¿ÐµÑÐ²ÐžÑÐœÐŸÐ³ÐŸ Ð¿ÐŸÑÐŸÐºÐ° ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž DSpace. ÐÑÐŸÐ³ÑÐ°ÐŒÐŒÐ° Ð±ÑÐŽÐµÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÐŸÐ±ÐŸÐ·ÐœÐ°ÑÐµÐœÐœÑÐµ ÑÐžÐ¿Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° mime Ð² ÑÐµÑÐžÐž, ÑÑÐŸÐ±Ñ ÐœÐ°Ð¹ÑÐž Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÑÐ¹ Ð¿ÐµÑÐ²ÐŸÑÑÐµÐ¿ÐµÐœÐœÑÐ¹ ÑÐ°Ð¹Ð».  
+
+DSpacePlugin.only_first_doc:Ð­ÑÐ° ÐŸÐ¿ÑÐžÑ Ð¿ÑÐµÐŽÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐ° ÐŽÐ»Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÑ Ð¿ÐµÑÐ²ÐžÑÐœÐŸÐ³ÐŸ Ð¿ÐŸÑÐŸÐºÐ° Ð² ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°Ñ
+ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž DSpace. ÐÑÐŸÐ³ÑÐ°ÐŒÐŒÐ° Ð±ÑÐŽÐµÑ ÑÑÐžÑÐ°ÑÑ Ð¿ÐµÑÐ²ÐŸÑÑÐµÐ¿ÐµÐœÐœÑÐŒ ÑÐ°Ð¹Ð»ÐŸÐŒ Ð¿ÐµÑÐ²ÑÐ¹ ÐŸÐ±ÐŸÐ·ÐœÐ°ÑÐµÐœÐœÑÐ¹ Ð² ÑÐ°Ð¹Ð»Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ dublic_core.  
+
+EmailAddressExtractor.desc:ÐÐ»Ð°Ð³ÐžÐœ Ð¿ÐŸÐŒÐŸÑÐž ÑÐºÑÑÑÐ°ÐºÑÐŸÑÐ° ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ° Ð°ÐŽÑÐµÑÐŸÐ² ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ Ð² ÑÐµÐºÑÑÐµ.  
+
+EmailAddressExtractor.done_email_extract:ÐÑÐ¿ÐŸÐ»ÐœÐµÐœÐŸ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÐµ Ð°ÐŽÑÐµÑÐŸÐ² ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ.
+
+EmailAddressExtractor.extracting_emails:ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÐµ Ð°ÐŽÑÐµÑÐŸÐ² ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ
+
+EmailAddressExtractor.extract_email:ÐÐ·Ð²Ð»ÐµÑÑ Ð°ÐŽÑÐµÑÐ° ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+.
+
+EmailPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ Email ÑÐžÑÐ°ÐµÑ ÑÐ°Ð¹Ð»Ñ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ. ÐÐœÐž ÐžÐŒÐµÐœÑÑÑÑÑ Ð¿ÑÐŸÑÑÑÐŒÐž ÐœÐŸÐŒÐµÑÐ°ÐŒÐž (Ñ.Ðµ.Ð² ÑÐŸÐŒ Ð¿ÐŸÑÑÐŽÐºÐµ,ÐºÐ°Ðº ÐŸÐœÐž Ð¿ÐŸÑÐ²Ð»ÑÑÑÑÑ Ð² Ð¿Ð°Ð¿ÐºÐ°Ñ
+ Ð¿ÐŸÑÑÐŸÐ²ÐŸÐ¹ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž) ÐžÐ»Ðž Ñ ÑÐ°ÑÑÐžÑÐµÐœÐžÐµÐŒ .mbx (ÑÐŸÑÐŒÐ°Ñ ÑÐ°Ð¹Ð»Ð° ÐŽÐ»Ñ Ð¿ÐžÑÐµÐŒ mbox).\nÐ¢ÐµÐºÑÑ ÐŽÐŸÐŸÐºÑÐŒÐµÐœÑÐ°: Ð¢ÐµÐºÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° ÑÐŸÑÑÐŸÐžÑ ÐžÐ· Ð²ÑÐµÐ³ÐŸ ÑÐµÐºÑÑÐ° Ð¿ÐŸÑÐ»Ðµ Ð¿ÐµÑÐ²ÐŸÐ¹ Ð¿ÑÑÑÐŸÐ¹ ÑÑÑÐŸÐºÐž Ð² ÐŽÐŸÐºÑÐŒÐµÐœÑÐµ.\nÐÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ (ÐœÐµ Dublin Core!):\n\t\$Headers ÐÑÐµ ÑÑÐŸ ÑÐŸÐŽÐµÑÐ¶ÐžÑ Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐŸÐº (ÐœÐµÐŸÐ±ÑÐ·Ð°ÑÐµÐ»ÑÐœÐŸ, Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ ÐœÐµ ÑÐŸÑ
+ÑÐ°ÐœÑÐµÑÑÑ)\n\t\$Subject ÐÑÐµÐŽÐŒÐµÑ: Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐŸÐº\n\t\$To  ÐÐŸÐŒÑ:Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐŸÐº\n\t\$From ÐºÐŸÐ³ÐŸ   ÐÑ ÐºÐŸÐ³ÐŸ: Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐŸÐº\n\t\$FromName ÐŸÑ ÐºÐŸÐ³ÐŸ  ÐÐŒÑ ÐŸÑÐ¿ÑÐ°Ð²ÐžÑÐµÐ»Ñ(ÐºÐŸÐ³ÐŽÐŽÐ° ÐŸÐœÐŸ ÐžÐŒÐµÐµÑÑÑ Ð² ÐœÐ°Ð»ÐžÑÐžÐž)\n\t\$FromAddr ÐŸÑ ÐºÐŸÐ³ÐŸ  Ð°ÐŽÑÐµÑ ÑÐ»ÐµÐºÑÑÐŸÐœÐœÐŸÐ¹ Ð¿ÐŸÑÑÑ ÐŸÑÐ¿ÑÐ°Ð²ÐžÑÐµÐ»Ñ\n\t\$DateText ÐŽÐ°ÑÑ  ÐÐ°ÑÐ°: Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐŸÐº\n\t\$Date   ÐÐ°ÑÐ°: Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐŸÐº Ð² ÑÐŸÑÐŒÐ°ÑÐµ ÑÐžÑÑÐŸÐ²ÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž Greenstone (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ: 19990924)  
+
+EmailPlugin.no_attachments:ÐÐµ ÑÐŸÑ
+ÑÐ°ÐœÑÑÑ Ð¿ÑÐžÐ»ÐŸÐ¶ÐµÐœÐžÑ ÑÐŸÐŸÐ±ÑÐµÐœÐžÑ.
+
+EmailPlugin.headers:Ð¡ÐŸÑ
+ÑÐ°ÐœÑÑÑ Ð¿ÐŸÑÑÐŸÐ²ÑÐµ Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐž ÐºÐ°Ðº ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÐµ "Headers"
+
+EmailPlugin.OIDtype.message_id:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑ ÑÐŸÐŸÐ±ÑÐµÐœÐžÑ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ OID ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°. ÐÑÐ»Ðž ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑ ÐœÐ°Ð¹ÐŽÐµÐœ, Ð·Ð°ÑÐµÐŒ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐžÑÑÐŸÑÐœÐžÐº OID.  
+
+EmailPlugin.split_exp:ÐÐ±ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ  perl ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐŽÐ»Ñ ÑÐ°ÑÑÐµÐ¿Ð»ÐµÐœÐžÑ ÑÐ°Ð¹Ð»ÐŸÐ², ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐžÑ
+ ÐžÐŒÐµÐ»ÐŸ ÐŸÐ±ÑÐºÐœÐŸÐ²ÐµÐœÐžÐµ ÑÐ°ÑÐºÐ°Ð»ÑÐ²Ð°ÑÑ ÑÐ°Ð¹Ð»Ñ, ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐžÐµ ÐŒÐœÐŸÐ³ÐŸ ÑÐŸÐŸÐ±ÑÐµÐœÐžÐ¹ Ð² ÐžÐœÐŽÐžÐ²ÐžÐŽÑÐ°Ð»ÑÐœÑÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°Ñ
+.
+
+ExcelPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐžÐŒÐ¿ÐŸÑÑÐ° ÑÐ°Ð¹Ð»Ð° Microsoft Excel.
+
+FavouritesPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž ÑÐ°Ð¹Ð»ÐŸÐ² Ð·Ð°ÐºÐ»Ð°ÐŽÐŸÐº ÐÑÐŸÐ²ÐŸÐŽÐœÐžÐºÐ° ÐÐœÑÐµÑÐœÐµÑ  
+
+FOXPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž ÑÐ°Ð¹Ð»Ð° Foxbase dbt. Ð­ÑÐŸÑ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŸÐ±ÐµÑÐ¿ÐµÑÐžÐ²Ð°ÐµÑ ÐŸÑÐœÐŸÐ²ÐœÑÐµ ÑÑÐœÐºÑÐžÐŸÐœÐ°Ð»ÑÐœÑÐµ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÐž ÑÑÐµÐœÐžÑ dbt Ðž dbf ÑÐ°Ð¹Ð»ÐŸÐ² Ðž ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž ÐºÐ°Ð¶ÐŽÐŸÐ¹ Ð·Ð°Ð¿ÐžÑÐž. Ð­ÑÐŸÑ ÐŸÐ±ÑÐžÐ¹ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŽÐŸÐ»Ð¶ÐµÐœ Ð±ÑÑÑ Ð·Ð°ÐŒÐµÑÐµÐœ ÐŽÐ»Ñ ÑÐ¿ÐµÑÐžÑÐžÑÐµÑÐºÐŸÐ¹ Ð±Ð°Ð·Ñ ÐŽÐ°ÐœÐœÑÑ
+, ÑÑÐŸÐ±Ñ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÑÑ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÑÑÐžÐµ Ð¿ÐŸÐ»Ñ Ð² ÑÐ°Ð¹Ð»Ðµ.
+
+GreenstoneXMLPlugin.desc:ÐÐ±ÑÐ°Ð±ÐŸÑÐºÐ° XML ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ð°ÑÑ
+ÐžÐ²Ð° Greenstone. ÐÐ±ÑÐ°ÑÐžÑÐµ Ð²ÐœÐžÐŒÐ°ÐœÐžÐµ, ÑÑÐŸ ÑÑÐŸÑ Ð¿Ð»Ð°Ð³ÐžÐœ ÐœÐµ ÐŽÐµÐ»Ð°ÐµÑ ÐœÐžÐºÐ°ÐºÐŸÐ¹ Ð¿ÑÐŸÐ²ÐµÑÐºÐž ÑÐžÐœÑÐ°ÐºÑÐžÑÐ° (Ñ
+ÐŸÑÑ  Ð°ÐœÐ°Ð»ÐžÐ·ÐžÑÑÑÑÐžÐ¹ ÐŒÐŸÐŽÑÐ»Ñ XML::   Ð¿ÑÐŸÐ²ÐµÑÑÐµÑ Ð¿ÑÐ°Ð²ÐžÐ»ÑÐœÐŸÑÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ). ÐÑÐµÐŽÐ¿ÐŸÐ»Ð°Ð³Ð°ÐµÑÑÑ, ÑÑÐŸ ÑÐ°Ð¹Ð»Ñ Ð°ÑÑ
+ÐžÐ²Ð° Greenstone ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÑÑ ÐžÑ
+ DTD .
+
+GISExtractor.desc:ÐÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÑÐ¹ ÐºÐ»Ð°ÑÑ Ðº BasPlug, ÐºÐŸÑÐŸÑÑÐ¹ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐžÐ²Ð°ÐµÑ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸÑÑÐž ÐÐµÐŸÐ³ÑÐ°ÑÐžÑÐµÑÐºÐžÑ
+ ÐÐœÑÐŸÑÐŒÐ°ÑÐžÐŸÐœÑÑ
+ Ð¡ÐžÑÑÐµÐŒ (ÐÐÐ¡)
+
+GISExtractor.extract_placenames:Ð Ð°ÑÐ¿ÐŸÐ·ÐœÐŸÐ²Ð°ÑÑ Ð³ÐµÐŸÐ³ÑÐ°ÑÐžÑÐµÑÐºÐžÐµ ÐœÐ°Ð·Ð²Ð°ÐœÐžÑ Ð² ÑÐµÐºÑÑÐµ Ðž Ð²ÐºÐ»ÑÑÐžÑÑ ÐžÑ
+ Ð² ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÐµ. Ð¢ÑÐµÐ±ÑÐµÑ ÑÐ°ÑÑÐžÑÐµÐœÐžÐµ ÐÐÐ¡ Ð² ÐÑÐžÐœÑÑÐŸÑÐœ.
+
+GISExtractor.gazetteer:ÐÐµÐŸÐ³ÑÐ°ÑÐžÑÐµÑÐºÐžÐ¹ ÑÐ¿ÑÐ°Ð²ÐŸÑÐœÐžÐº ÐŽÐ»Ñ ÑÐ°ÑÐ¿ÐŸÐ·ÐœÐ°ÐœÐžÑ Ð³ÐµÐŸÐ³ÑÐ°ÑÐžÑÐµÑÐºÐžÑ
+ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐ¹ Ð² ÑÐµÐºÑÑÐµ Ðž ÐŽÐŸÐ±Ð°Ð²Ð»ÐµÐœÐžÑ ÐžÑ
+ Ð² ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÑ
+. Ð¢ÑÐµÐ±ÑÐµÑ ÑÐ°ÑÑÐžÑÐµÐœÐžÐµ ÐÐÐ¡ Ð² ÐÑÐžÐœÑÑÐŸÑÐœ.
+
+GISExtractor.place_list:ÐÑÐž ÑÐ°ÑÐ¿ÐŸÐ·ÐœÐ°ÐœÐžÐž Ð³ÐµÐŸÐ³ÑÐ°ÑÐžÑÐµÑÐºÐžÑ
+ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐ¹, Ð¿Ð»Ð°Ð³ÐžÐœ Ð²ÐºÐ»ÑÑÐ°ÐµÑ ÐžÑ
+ ÑÐ¿ÐžÑÐŸÐº Ð² ÐœÐ°ÑÐ°Ð»ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°. Ð¢ÑÐµÐ±ÑÐµÑ ÑÐ°ÑÑÐžÑÐµÐœÐžÐµ ÐÐÐ¡ Ð² ÐÑÐžÐœÑÑÐŸÑÐœ.
+
+HBPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ, ÐºÐŸÑÐŸÑÑÐ¹ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑ HTML ÐºÐœÐžÐ¶ÐœÑÑ ÐŽÐžÑÐµÐºÑÐŸÑÐžÑ. Ð­ÑÐŸÑ Ð¿Ð»Ð°Ð³ÐžÐœ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŒÐž ÐÑÐŒÐ°ÐœÐžÑÐ°ÑÐœÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž Ðž ÐœÐµ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑ ÐŽÑÑÐ³ÐžÐµ Ð²Ñ
+ÐŸÐŽÐœÑÐµ ÑÐžÑÑÐŸÐ²Ð°ÐœÐžÑ, ÐºÑÐŸÐŒÐµ ascii ÐžÐ»Ðž Ñ ÑÐ°ÑÑÐžÑÐµÐœÐžÐµÐŒ ascii. Ð­ÑÐ° Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐ° ÑÐ²Ð»ÑÐµÑÑÑ Ð»ÑÑÑÐµÐ¹ ÐžÐ· Ñ
+ÑÐŽÑÐžÑ
+ Ðž ÐŒÐŸÐ³Ð»Ð° Ð±Ñ Ð±ÐµÐ· ÑÐŸÐŒÐœÐµÐœÐžÑ ÐŽÐŸÑÐ°Ð±ÐŸÑÐ°ÐœÐ° ÑÐ°Ðº, ÑÑÐŸÐ±Ñ Ð·Ð°Ð³ÑÑÐ¶Ð°ÑÑÑÑ Ð±ÑÑÑÑÐµÐµ. ÐÑÑÐ°Ð²Ð»ÑÑ ÐµÐµ Ð² ÑÑÐŸÐŒ ÑÐŸÑÑÐŸÑÐœÐžÐž, Ñ ÐœÐ°ÐŽÐµÑÑÑ Ð¿ÐŸÐŸÑÑÐžÑÑ Ð»ÑÐŽÐµÐ¹ ÐŽÐµÐ»Ð°ÑÑ ÐžÑ
+ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ Ð²ÐŒÐµÑÑÐŸ ÑÑÐŸÐ³ÐŸ Ð¿Ð»Ð°Ð³ÐžÐœ HBSPlug. ;-)\n\n ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ HBSPlug Ð¿ÑÐž ÑÐŸÐ·ÐŽÐ°ÐœÐžÐž ÐœÐŸÐ²ÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž Ðž Ð¿ÐŸÐŒÐµÑÐµÐœÐœÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ², Ð¿ÐŸÐŽÐŸÐ±ÐœÐŸ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŒ ÐÑÐŒÐ°ÐœÐžÑÐ°ÑÐœÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž. HBSPlug Ð¿ÑÐžÐœÐžÐŒÐ°ÐµÑ Ð²ÑÐµ Ð²Ñ
+ÐŸÐŽÐœÑÐµ ÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÑ, ÐœÐŸ ÐŸÐ¶ÐžÐŽÐ°ÐµÑ, ÑÑÐŸ Ð¿ÐŸÐŒÐµÑÐµÐœÐœÑÐµ ÑÐ°Ð¹Ð»Ñ Ð±ÑÐŽÑÑ Ð±ÐŸÐ»ÐµÐµ ÑÐžÑÑÑÐŒÐž, ÑÐµÐŒ ÑÐµ, ÑÑÐŸ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑÑÑÑ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑÐŒÐž ÐÑÐŒÐ°ÐœÐžÑÐ°ÑÐœÐŸÐ¹ Ð±ÐžÐ±Ð»ÐžÐŸÑÐµÐºÐž.  
+
+HBPlugin.encoding.iso_8859_1:Latin1 (Ð·Ð°Ð¿Ð°ÐŽÐœÑÐµ ÑÐ·ÑÐºÐž)  
+
+HTMLImagePlugin.aggressiveness:Ð Ð°ÐœÐ³ ÑÐ²ÑÐ·Ð°ÐœÐœÑÑ
+ ÐŒÐµÑÐŸÐŽÐŸÐ², ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÑ
+ ÐŽÐ»Ñ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ÑÐµÐºÑÑÐ°.
+HTMLImagePlugin.aggressiveness.1:ÐÐŒÑ ÑÐ°Ð¹Ð»Ð°, Ð¿ÑÑÑ, ÐŒÐŸÐŽÐžÑÐžÐºÐ°ÑÐžÑ (ALT) ÑÐŸÐ»ÑÐºÐŸ ÑÐµÐºÑÑÐ°.
+HTMLImagePlugin.aggressiveness.2:ÐÑÐµ ÐžÐ· 1 Ð¿Ð»ÑÑ Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐŸÐº, Ð³ÐŽÐµ ÑÑÐŸ ÐŽÐŸÑÑÑÐ¿ÐœÐŸ.
+HTMLImagePlugin.aggressiveness.3:ÐÑÐµ  ÐžÐ· 2 Ð¿Ð»ÑÑ Ð±Ð»ÐžÐ¶Ð°Ð¹ÑÐžÐµ Ð¿Ð°ÑÐ°Ð³ÑÐ°ÑÑ, Ð³ÐŽÐµ ÑÑÐŸ ÐŽÐŸÑÑÑÐ¿ÐœÐŸ.
+HTMLImagePlugin.aggressiveness.4:ÐÑÐµ ÐžÐ· 3 Ð¿Ð»ÑÑ Ð¿ÑÐµÐŽÑÐŽÑÑÐžÐµ Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐž (<h1>, <h2> ...), Ð³ÐŽÐµ ÑÑÐŸ ÐŽÐŸÑÑÑÐ¿ÐœÐŸ.
+HTMLImagePlugin.aggressiveness.5:ÐÑÐµ ÐžÐ· 4 Ð¿Ð»ÑÑ ÑÐµÐºÑÑÐŸÐ²ÑÐµ ÑÑÑÐ»ÐºÐž, Ð³ÐŽÐµ ÑÑÐŸ ÐŽÐŸÑÑÑÐ¿ÐœÐŸ.
+HTMLImagePlugin.aggressiveness.6:ÐÑÐµ ÐžÐ· 4 Ð¿Ð»ÑÑ ÑÑÑÐ°ÐœÐžÑÐ° ÐŒÐµÑÐ°ÑÑÐ³ÐŸÐ² (ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ, ÐºÐ»ÑÑÐµÐ²ÑÐµ ÑÐ»ÐŸÐ²Ð° Ðž Ñ.ÐŽ).
+HTMLImagePlugin.aggressiveness.7:ÐÑÐµ  ÐžÐ· ÐŸÐ±ÑÐµÐŽÐžÐœÐµÐœÐœÑÑ
+ 6, 5 Ðž 4.
+HTMLImagePlugin.aggressiveness.8:ÐÑÐµ ÐžÐ· 7 Ð¿Ð»ÑÑ Ð¿ÐŸÐ²ÑÐŸÑÐµÐœÐžÐµ Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐ°, ÐžÐŒÐµÐœÐž ÑÐ°Ð¹Ð»Ð° Ðž Ñ.ÐŽ ( Ð¿ÐŸÐ²ÑÑÐµÐœÐžÐµ ÑÐ°ÐœÐ³Ð° Ð±ÐŸÐ»ÐµÐµ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÑÑÐžÑ
+ ÑÐµÐ·ÑÐ»ÑÑÐ°ÑÐŸÐ²).
+HTMLImagePlugin.aggressiveness.9:ÐÑÐµ ÐžÐ· 1 Ð¿Ð»ÑÑ Ð¿ÐŸÐ»ÐœÑÐ¹ ÑÐµÐºÑÑ ÐžÑÑ
+ÐŸÐŽÐœÐŸÐ¹ ÑÑÑÐ°ÐœÐžÑÑ.
+
+HTMLImagePlugin.caption_length:ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐ°Ñ ÐŽÐ»ÐžÐœÐ° Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐŸÐ² (Ð² Ð·ÐœÐ°ÐºÐ°Ñ
+).
+
+HTMLImagePlugin.convert_params:ÐÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÑÐµ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÑ ÐŽÐ»Ñ ImageMagicK ÐºÐŸÐœÐ²ÐµÑÑÐžÑÑÑÑ ÑÐŒÐµÐœÑÑÐµÐœÐœÑÐµ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, '-Ð¿ÐŸÐ²ÑÑÐµÐœÐžÐµ' ÐŽÐ°ÑÑ ÑÑÐµÑ
+ÐŒÐµÑÐœÑÐ¹ Ð²ÐžÐŽ ÑÐŒÐµÐœÑÑÐµÐœÐœÑÐŒ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑÐŒ.
+
+HTMLImagePlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ Ðž ÑÐ²ÑÐ·Ð°ÐœÐœÐŸÐ³ÐŸ ÑÐµÐºÑÑÐ° ÐžÐ· Ð²ÐµÐ±-ÑÑÑÐ°ÐœÐžÑ.
+
+HTMLImagePlugin.document_text:ÐÐŸÐ±Ð°Ð²ÐžÑÑ ÑÐµÐºÑÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ Ð² Ð²ÐžÐŽÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°:ÑÐµÐºÑÑ (ÐžÐœÐ°ÑÐµ, Ð¿ÐŸÐ»Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ IndexedText).
+
+HTMLImagePlugin.index_pages:ÐÐœÐŽÐµÐºÑÐžÑÐŸÐ²Ð°ÑÑ ÑÑÑÐ°ÐœÐžÑÑ ÐœÐ°ÑÑÐŽÑ Ñ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑÐŒÐž. ÐÐœÐ°ÑÐµ, ÑÐŸÑÐ»Ð°ÑÑÑÑ ÐœÐ° ÑÑÑÐ°ÐœÐžÑÑ Ð² ÐžÑÑ
+ÐŸÐŽÐœÐŸÐŒ URL.
+
+HTMLImagePlugin.max_near_text:ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ Ð·ÐœÐ°ÐºÐŸÐ² Ñ ÐžÐ·Ð²Ð»ÐµÐºÐ°ÐµÐŒÑÑ
+ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹.
+
+HTMLImagePlugin.min_height:ÐÐžÐºÑÐµÐ»Ñ. ÐÑÐŸÐ¿ÑÑÑÐžÑÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ, ÐŒÐµÐœÑÑÐžÐµ, ÑÐµÐŒ ÑÑÐŸ.
+
+HTMLImagePlugin.min_near_text:ÐÐžÐœÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ Ð·ÐœÐ°ÐºÐŸÐ² Ñ ÐžÐ·Ð²Ð»ÐµÐºÐ°ÐµÐŒÐŸÐ³ÐŸ ÑÐµÐºÑÑÐ° ÐžÐ»Ðž Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐ°.
+
+HTMLImagePlugin.min_size:ÐÐ°Ð¹ÑÑ. ÐÑÐŸÐ¿ÑÑÑÐžÑÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ, ÐŒÐµÐœÑÑÐžÐµ, ÑÐµÐŒ ÑÑÐŸ.
+
+HTMLImagePlugin.min_width:ÐÐžÐºÑÐµÐ»Ñ. ÐÑÐŸÐ¿ÑÑÑÐžÑÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ, Ð±ÐŸÐ»ÐµÐµ ÑÐ·ÐºÐžÐµ, ÑÐµÐŒ ÑÑÐŸ.
+
+HTMLImagePlugin.neartext_length:ÐÐ»ÐžÐœÐ° Ð°ÐŽÑÐµÑÐ° Ñ ÑÐµÐºÑÑÐ° (Ð² Ð·ÐœÐ°ÐºÐ°Ñ
+).
+
+HTMLImagePlugin.no_cache_images:ÐÐµ ÐŽÐµÐ»Ð°ÑÑ ÐºÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ (ÑÐºÐ°Ð·Ð°ÑÑ URL ÐŸÑÐžÐ³ÐžÐœÐ°Ð»Ð°).
+
+HTMLImagePlugin.smallpage_threshold:ÐÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÐœÐ° ÑÑÑÐ°ÐœÐžÑÐ°Ñ
+, ÐŒÐµÐœÑÑÐžÑ
+ ÑÐµÐŒ ÑÑÐ° ( Ð² Ð±Ð°Ð¹ÑÐ°Ñ
+), Ð±ÑÐŽÑÑ ÐžÐŒÐµÑÑ ÐŽÐŸÐ±Ð°Ð²Ð»ÐµÐœÐœÑÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÑÑÑÐ°ÐœÐžÑÑ (ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ, ÐºÐ»ÑÑÐµÐ²ÑÐµ ÑÐ»ÐŸÐ²Ð° Ðž Ñ.ÐŽ).
+
+HTMLImagePlugin.textrefs_threshold:ÐÐŸÑÐŸÐ³ ÐŽÐ»Ñ ÑÐµÐºÑÑÐŸÐ²ÑÑ
+ ÑÑÑÐ»ÐŸÐº. ÐÐŸÐ»ÐµÐµ ÐœÐžÐ·ÐºÐžÐµ Ð·ÐœÐ°ÑÐµÐœÐžÑ Ð¿ÐŸÐŽÑÐ°Ð·ÑÐŒÐµÐ²Ð°ÑÑ, ÑÑÐŸ Ð°Ð»Ð³ÐŸÑÐžÑÐŒ ÐŒÐµÐœÐµÐµ ÑÑÑÐŸÐ³.
+
+HTMLImagePlugin.thumb_size:ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐµ ÑÐŒÐµÐœÑÑÐµÐœÐžÐµ ÑÐ°Ð·ÐŒÐµÑÐ° - Ðž ÑÐžÑÐžÐœÑ, Ðž Ð²ÑÑÐŸÑÑ.
+
+HTMLPlugin.assoc_files:ÐÐ±ÑÑÐœÐŸÐµ Perl Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ ÑÐ°Ð¹Ð»Ð° ÑÐ°ÑÑÐžÑÐµÐœÐžÐ¹ ÐŽÐ»Ñ ÑÐ²ÑÐ·Ðž Ñ  html -ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒÐž.
+
+HTMLPlugin.desc:Ð­ÑÐŸÑ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑ ÑÐ°Ð¹Ð»Ñ HTML
+
+HTMLPlugin.description_tags:Ð Ð°Ð·Ð±ÐžÐµÐœÐžÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° ÐœÐ° Ð¿ÐŸÐŽÑÐ°Ð·ÐŽÐµÐ»Ñ, Ð³ÐŽÐµ ÐžÐŒÐµÑÑÑÑ ÑÑÐ³Ðž <Ð Ð°Ð·ÐŽÐµÐ»>. ÐÐ±ÑÐ°ÑÐžÑÐµ Ð²ÐœÐžÐŒÐ°ÐœÐžÐµ, ÑÑÐŸ Ð¿ÑÐž ÑÑÑÐ°ÐœÐŸÐ²ÐºÐµ ÑÑÐŸÐ¹ ÐŸÐ¿ÑÐžÐž, ÐÑ ÐœÐµÑÐ²ÐœÐŸ ÑÑÑÐ°ÐœÐ°Ð²Ð»ÐžÐ²Ð°ÐµÑÐµ -no_metadata (ÐœÐžÐºÐ°ÐºÐžÑ
+ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+), Ð¿ÐŸÑÐºÐŸÐ»ÑÐºÑ Ð²ÑÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐŽÐŸÐ»Ð¶ÐœÑ Ð±ÑÑÑ Ð²ÐºÐ»ÑÑÐµÐœÑ Ð² Ð¿ÑÐµÐŽÐµÐ»Ð°Ñ
+ ÑÑÐ³ÐŸÐ² <Ð Ð°Ð·ÐŽÐµÐ»>. ÐÑÐŸÐŒÐµ ÑÐŸÐ³ÐŸ '-keep_head' ÐœÐµ Ð±ÑÐŽÐµÑ ÐžÐŒÐµÑÑ ÐœÐžÐºÐ°ÐºÐŸÐ³ÐŸ ÐŽÐµÐ¹ÑÑÐ²ÐžÑ, ÐºÐŸÐ³ÐŽÐ° ÑÑÐ° ÐŸÐ¿ÑÐžÑ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐ°.
+
+HTMLPlugin.extract_style:ÐÐ·Ð²Ð»ÐµÑÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ ÑÑÐžÐ»ÑÑ
+ Ðž ÑÐºÑÐžÐ¿ÑÐŸÐ² ÐžÐ· ÑÐµÐ³Ð° HTML <head> Ðž ÑÐŸÑ
+ÑÐ°ÐœÐžÑÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐºÐ°Ðº DocumentHeader. Ð­ÑÐŸ Ð±ÑÐŽÐµÑ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐŸ ÐœÐ° ÑÑÑÐ°ÐœÐžÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° ÐŒÐ°ÐºÑÐŸÑÐŸÐŒ _document:documentheader_ macro.  
+
+HTMLPlugin.file_is_url:Ð£ÑÑÐ°ÐœÐŸÐ²ÐžÑÑ, ÐµÑÐ»Ðž Ð²Ñ
+ÐŸÐŽÐœÑÐµ ÐžÐŒÐµÐœÐ° ÑÐ°Ð¹Ð»ÐŸÐ² ÑÐŸÐŽÐµÑÐ¶Ð°Ñ URL Ð¿ÐµÑÐ²ÐŸÐœÐ°ÑÐ°Ð»ÑÐœÑÑ
+ ÐžÑÑ
+ÐŸÐŽÐœÑÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, ÐµÑÐ»Ðž ÑÑÐµÐŽÑÑÐ²Ð° Ð²ÐµÐ±-Ð·ÐµÑÐºÐ°Ð»Ð° ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°Ð»ÐžÑÑ ÐŽÐ»Ñ ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ ÑÑÑÑÐºÑÑÑÑ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž ÐžÐŒÐ¿ÐŸÑÑÐ°.
+
+HTMLPlugin.hunt_creator_metadata:ÐÐ°Ð¹ÑÐž ÐœÐ°ÑÐºÐŸÐ»ÑÐºÐŸ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ Ð±ÐŸÐ»ÑÑÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ð² Ð°Ð²ÑÐŸÑÑÑÐ²Ðµ Ðž ÑÐ°Ð·ÐŒÐµÑÑÐžÑÑ ÐžÑ
+ Ð² Ð¿ÐŸÐ»Ðµ 'CÐŸÐ·ÐŽÐ°ÑÐµÐ»Ñ'. Ð¢ÑÐµÐ±ÑÐµÑÑÑ ÑÑÑÐ°ÐœÐŸÐ²ÐºÐ° ÑÐ»Ð°Ð³Ð° ÐœÐ° -metadata_fields (ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ Ð¿ÐŸÐ»ÐµÐ¹).
+
+HTMLPlugin.keep_head:ÐÐµ ÑÐŽÐ°Ð»ÑÑÑ Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐž ÐžÐ· html-ÑÐ°Ð¹Ð»ÐŸÐ².
+
+HTMLPlugin.metadata_fields:ÐÐ°Ð¿ÑÑÐ°Ñ ÐŸÑÐŽÐµÐ»ÑÐµÑ ÑÐ¿ÐžÑÐŸÐº Ð¿ÐŸÐ»ÐµÐ¹ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, ÑÑÐŸÐ±Ñ Ð¿ÐŸÐ¿ÑÑÐ°ÑÑÑÑ  ÐœÐ°ÑÐ°ÑÑ ÑÐºÑÑÑÐ°ÐºÑÐžÑ. ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ'ÑÑÐ³ <tagname>', ÑÑÐŸÐ±Ñ Ð¿ÐŸÐ»ÑÑÐžÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ Ð¿ÐµÑÐ²ÐŸÐ¹  Ð¿Ð°ÑÑ <tagname>, Ð²ÑÑÐ°Ð²Ð»ÐµÐœÐœÐŸÐ¹ Ð² ÑÐ»ÐµÐŒÐµÐœÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, ÐœÐ°Ð·ÑÐ²Ð°ÐµÐŒÑÐ¹ 'tagname'. ÐÐ°ÐŒÐµÐœÐžÑÐµ Ð·ÐŽÐµÑÑ ÑÑÑÐŸÑÐœÑÐµ Ð±ÑÐºÐ²Ñ Ð·Ð°Ð³Ð»Ð°Ð²ÐœÑÐŒÐž, ÐµÑÐ»Ðž ÐÑ Ñ
+ÐŸÑÐžÑÐµ, ÑÑÐŸÐ±Ñ ÑÑÐž ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ Ð±ÑÐ»Ðž Ð¿ÑÐµÐŽÑÑÐ°Ð²Ð»ÐµÐœÑ Ð² Greenstone Ð·Ð°Ð³Ð»Ð°Ð²ÐœÑÐŒÐž Ð±ÑÐºÐ²Ð°ÐŒÐž, ÑÐ°Ðº ÐºÐ°Ðº ÑÐºÑÑÑÐ°ÐºÑÐžÑ ÑÑÐ³ÐŸÐ² ÑÐ²Ð»ÑÐµÑÑÑ ÐŒÐ°Ð»ÐŸÑÑÐ²ÑÑÐ²ÐžÑÐµÐ»ÑÐœÑÐŒ ÐŽÐµÐ¹ÑÑÐ²ÐžÐµÐŒ.
+
+HTMLPlugin.no_metadata:ÐÐµ Ð¿ÑÑÐ°Ð¹ÑÐµÑÑ ÐžÐ·Ð²Ð»ÐµÐºÐ°ÑÑ Ð»ÑÐ±ÑÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐžÐ· ÑÐ°Ð¹Ð»ÐŸÐ².
+
+HTMLPlugin.no_strip_metadata_html:Ð¡Ð¿ÐžÑÐŸÐº ÐœÐ°Ð·Ð²Ð°ÐœÐžÐ¹ ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÑ
+, Ð¿ÐµÑÐµÑÐžÑÐ»ÐµÐœÐœÑÑ
+ ÑÐµÑÐµÐ· Ð·Ð°Ð¿ÑÑÑÑ, ÐžÐ»Ðž 'all' (Ð²ÑÐµ). ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ Ñ -description_tags, ÑÑÐŸ Ð¿ÑÐµÐŽÐŸÑÐ²ÑÐ°ÑÐ°ÐµÑ ÑÐŽÐ°Ð»ÐµÐœÐžÐµ HTML ÑÐ°Ð³ÐŸÐ² ÐžÐ· Ð·ÐœÐ°ÑÐµÐœÐžÐ¹ ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÑ
+.
+
+HTMLPlugin.nolinks:ÐÐµ ÐŽÐµÐ»Ð°Ð¹ÑÐµ ÐœÐžÐºÐ°ÐºÐžÑ
+ Ð¿ÐŸÐ¿ÑÑÐŸÐº  ÑÐ»Ð°Ð²Ð»ÐžÐ²Ð°ÑÑ Ð»ÐžÐœÐºÐž (ÑÑÑÐ°ÐœÐŸÐ²ÐºÐ° ÑÐ°ÐºÐŸÐ³ÐŸ ÑÐ»Ð°Ð³Ð° ÐŒÐŸÐ¶ÐµÑ ÑÐ»ÑÑÑÐžÑÑ ÑÐºÐŸÑÐŸÑÑÑ Ð¿ÐŸÑÑÑÐŸÐµÐœÐžÑ/ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ, ÐœÐŸ Ð»ÑÐ±ÑÐµ ÐŸÑÐœÐŸÑÐžÑÐµÐ»ÑÐœÑÐµ ÑÐ²ÑÐ·Ðž Ð² Ð¿ÑÐµÐŽÐµÐ»Ð°Ñ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ð±ÑÐŽÑÑ ÐœÐ°ÑÑÑÐµÐœÑ).
+
+HTMLPlugin.no_image_links:ÐÐµ ÐŽÐµÐ»Ð°Ð¹ÑÐµ ÐºÐ°ÐºÐžÐµ-Ð»ÐžÐ±ÐŸ Ð¿ÐŸÐ¿ÑÑÐºÐž ÑÐŽÐµÐ»Ð°ÑÑ ÑÑÑÐ»ÐºÐž ÐœÐ° ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÐŽÐ»Ñ ÐžÑ
+ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ°.  
+
+HTMLPlugin.rename_assoc_files:ÐÐµÑÐµÐžÐŒÐµÐœÐŸÐ²ÑÐ²Ð°ÐµÑ ÑÐ°Ð¹Ð»Ñ, ÑÐ²ÑÐ·Ð°ÐœÐœÑÐµ Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÐŒÐž (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑÐŒÐž). Ð¢Ð°ÐºÐ¶Ðµ ÑÐŸÐ·ÐŽÐ°ÐµÑ ÐœÐ°ÐŒÐœÐŸÐ³ÐŸ Ð±ÐŸÐ»ÐµÐµ ÐŒÐµÐ»ÐºÑÑ ÑÑÑÑÐºÑÑÑÑ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž (Ð¿ÐŸÐ»ÐµÐ·ÐœÐŸ Ð¿ÑÐž ÑÐŸÐ·ÐŽÐ°ÐœÐžÐž ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐ¹, ÐºÐŸÑÐŸÑÑÐµ Ð±ÑÐŽÑÑ Ð¿ÐµÑÐµÐœÐµÑÐµÐœÑ ÐœÐ° CD-ROM).
+
+HTMLPlugin.sectionalise_using_h_tags:ÐÐ²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐŸÐµ ÑÐŸÐ·ÐŽÐ°ÐœÐžÐµ ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐžÐ¹ Ð² ÐŽÐŸÐºÑÐŒÐµÐœÑÐµ Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµÐŒ ÑÐ°Ð³ÐŸÐ² h1, h2, ... hX.  
+
+HTMLPlugin.title_sub:ÐÑÑÐ°Ð¶ÐµÐœÐžÐµ Ð·Ð°ÐŒÐµÐœÑ ÐŽÐ»Ñ ÐžÐ·ÐŒÐµÐœÐµÐœÐžÑ ÑÑÑÐŸÐºÐž, Ñ
+ÑÐ°ÐœÑÑÐµÐ¹ÑÑ ÐºÐ°Ðº ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ.ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ, ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐŒ PDFPlug, ÑÑÐŸÐ±Ñ ÑÐŽÐ°Ð»ÐžÑÑ "Ð¡ÑÑÐ°ÐœÐžÑÑ 1 ", Ðž Ñ.ÐŽ ÐžÐ· ÑÐµÐºÑÑÐ°, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÐŸÐ³ÐŸ ÐºÐ°Ðº ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ.  
+
+HTMLPlugin.tidy_html:ÐÑÐ»Ðž ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐŸ, Ð¿ÑÐµÐŸÐ±ÑÐ°Ð·ÑÐµÑ HTML-ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð² Ñ
+ÐŸÑÐŸÑÐŸ ÑÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÐœÐœÑÐ¹ XHTML. Ð­ÑÐŸ Ð¿ÐŸÐ·Ð²ÐŸÐ»ÑÐµÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÑÐŒ Ð¿ÑÐŸÑÐŒÐ°ÑÑÐžÐ²Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð² ÑÐŸÑÐŒÐ°ÑÐµ ÐºÐœÐžÐ³Ðž.  
+
+HTMLPlugin.old_style_HDL:ÐÐŸÐŒÐµÑÐºÐ° ÐŸ ÑÐŸÐŒ, Ð±ÑÐ» Ð»Ðž ÑÐ°Ð¹Ð» ÑÐ°Ð·Ð±ÐžÑ ÐœÐ° ÑÐµÐºÑÐžÐž, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ ÑÑÐ°ÑÑÐ¹ ÑÑÐžÐ»Ñ ÑÐµÐºÑÐžÐ¹ HDL.  
+
+BaseMediaConverter.enable_cache:ÐÑÑ Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐž Ð³ÐµÐœÐµÑÐžÑÑÐµÑ ÑÐ°Ð¹Ð»Ñ (ÑÐ°ÐºÐžÐµ ÐºÐ°Ðº ÑÐŒÐµÐœÑÑÐµÐœÐœÑÐµ ÐºÐŸÐ¿ÐžÐž ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ Ðž ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÑÐºÑÐ°ÐœÐœÐŸÐ³ÐŸ ÑÐ°Ð·ÐŒÐµÑÐ°) 
+ÐœÐµÑ ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÐŸÑÑÐž ÐžÑ
+ ÑÐµÐ³ÐµÐœÐµÑÐžÑÐŸÐ²Ð°ÑÑ.  
+
+ImageConverter.converttotype:ÐÑÐµÐŸÐ±ÑÐ°Ð·ÐŸÐ²Ð°ÑÑ Ð³Ð»Ð°Ð²ÐœÐŸÐµ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐµ Ðº ÑÐŸÑÐŒÐ°ÑÑ 's'
+
+ImageConverter.create_screenview:ÐÑÐ»Ðž ÐœÐ°Ð±ÐŸÑ Ð²ÐµÑÐµÐœ, ÑÐŸÐ·ÐŽÐ°Ð¹ÑÐµ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÑÐºÑÐ°ÐœÐœÐŸÐ³ÐŸ ÑÐ°Ð·ÐŒÐµÑÐ°, Ðž ÑÑÑÐ°ÐœÐŸÐ²ÐžÑÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ: Screen, ScreenType, screenicon, ScreenWidth Ðž ScreenHeight.  
+
+ImageConverter.create_thumbnail:ÐÑÐ»Ðž ÐœÐ°Ð±ÐŸÑ Ð²ÐµÑÐµÐœ, ÑÐŸÐ·ÐŽÐ°ÑÑÑÑ ÑÐŒÐµÐœÑÑÐµÐœÐœÑÐµ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ Ðž ÐŽÐŸÐ±Ð°Ð²Ð»ÑÑÑÑÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ: Thumb, ThumbType, thumbicon, ThumbWidth, ThumbHeight.  
+ImageConverter.desc:Ð­ÑÐŸÑ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ, ÐŽÐŸÐ±Ð°Ð²Ð»ÑÑ Ð±Ð°Ð·ÐŸÐ²ÑÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ
+
+ImageConverter.imagemagicknotinstalled:Ð¿ÑÐžÐ»ÐŸÐ¶ÐµÐœÐžÐµ Image Magick ÐœÐµ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐŸ  
+
+ImageConverter.minimumsize:ÐÐµ Ð¿ÑÐžÐœÐžÐŒÐ°ÑÑ Ð²ÐŸ Ð²ÐœÐžÐŒÐ°ÐœÐžÐµ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ, ÐŒÐµÐœÑÑÐžÐµ, ÑÐµÐŒ n Ð±Ð°Ð¹Ñ.
+
+ImageConverter.noconversionavailable:ÐÐŸÐœÐ²ÐµÑÑÐ°ÑÐžÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ ÐœÐµÐŽÐŸÑÑÑÐ¿ÐœÐ°  
+
+ImageConverter.noscaleup:ÐÐµ ÑÐ²ÐµÐ»ÐžÑÐžÐ²Ð°ÑÑ ÐŒÐ°Ð»ÐµÐœÑÐºÐžÐµ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ Ð¿ÑÐž ÑÐŒÐµÐœÑÑÐµÐœÐžÑÑ
+.
+
+ImageConverter.screenviewsize:Ð¡ÐŸÐ·ÐŽÐ°Ð¹ÑÐµ ÑÐºÑÐ°ÐœÐœÑÐµ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÑÐ°Ð·ÐŒÐµÑÐ° nxn.
+
+ImageConverter.screenviewtype:Ð¡ÐŸÐ·ÐŽÐ°Ð¹ÑÐµ ÑÐºÑÐ°ÐœÐœÑÐµ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ Ð² ÑÐŸÑÐŒÐ°ÑÐµ 's'.
+
+ImageConverter.thumbnailsize:ÐÑÐ¿ÐŸÐ»ÐœÐžÑÑ ÑÐŒÐµÐœÑÑÐµÐœÐžÐµ ÑÐ°Ð·ÐŒÐµÑÐ° nxn.
+
+ImageConverter.thumbnailtype:ÐÑÐ¿ÐŸÐ»ÐœÐžÑÑ ÑÐŒÐµÐœÑÑÐµÐœÐžÐµ Ð² ÑÐŸÑÐŒÐ°ÑÐµ 's'.
+
+ImageConverter.win95notsupported:Image Magick ÐœÐµ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐžÐ²Ð°ÐµÑÑÑ Ð² Win95/98  
+
+ImagePlugin.desc:Ð­ÑÐŸÑ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ, ÐŽÐŸÐ±Ð°Ð²Ð»ÑÑ Ð±Ð°Ð·ÐŸÐ²ÑÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ
+
+IndexPlugin.desc:Ð­ÑÐŸÑ ÑÐµÐºÑÑÑÐžÐ²ÐœÑÐ¹ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑ ÑÐ°Ð¹Ð» index.txt. Ð€Ð°Ð¹Ð» index.txt ÐŽÐŸÐ»Ð¶ÐµÐœ ÑÐŸÐŽÐµÑÐ¶Ð°ÑÑ ÑÐ¿ÐžÑÐŸÐº ÑÐ°Ð¹Ð»ÐŸÐ², ÐºÐŸÑÐŸÑÑÐµ ÐŽÐŸÐ»Ð¶ÐœÑ Ð±ÑÑÑ Ð²ÐºÐ»ÑÑÐµÐœÑ Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ, ÑÐŸÐ¿ÑÐŸÐ²ÐŸÐ¶ÐŽÐ°ÐµÐŒÑÐ¹ Ð»ÑÐ±ÑÐŒÐž ÐŽÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÑÐŒÐž ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐŒÐž, ÑÐ²ÑÐ·Ð°ÐœÐœÑÐŒÐž Ñ ÐºÐ°Ð¶ÐŽÑÐŒ ÑÐ°Ð¹Ð»ÐŸÐŒ \n\n Ð€Ð°Ð¹Ð» index.txt ÐŽÐŸÐ»Ð¶ÐµÐœ Ð±ÑÑÑ ÑÐŸÑÐŒÐ°ÑÐžÑÐŸÐ²Ð°Ðœ ÑÐ»ÐµÐŽÑÑÑÐžÐŒ ÐŸÐ±ÑÐ°Ð·ÐŸÐŒ: Ð¿ÐµÑÐ²Ð°Ñ ÑÑÑÐŸÐºÐ° ÐŒÐŸÐ¶ÐµÑ Ð±ÑÑÑ ÐºÐ»ÑÑÐŸÐŒ (ÐœÐ°ÑÐžÐœÐ°Ñ Ñ ÐºÐ»ÑÑÐ°:), ÑÑÐŸÐ±Ñ ÐœÐ°Ð·Ð²Ð°ÑÑ Ð¿ÐŸÐ»Ñ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, ÐºÐ»ÑÑ: ÐÑÐµÐŽÐŒÐµÑ, ÐÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÑ, ÐÐ°ÑÐ°). Ð¡Ð»ÐµÐŽÑÑÑÐžÐµ ÑÑÑÐŸÐºÐž Ð±ÑÐŽÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°ÑÑ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÑÐ°Ð¹Ð»Ð°, Ð·Ð°ÑÐµÐŒ Ð·ÐœÐ°ÑÐµÐœÐžÐµ ÑÐµÑ
+ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ð²Ñ
+ÐŸÐŽÐ°, ÐºÐŸÑÐŸÑÑÐµ ÐŽÐŸÐ»Ð¶ÐœÑ Ð±ÑÑÑ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÑ. (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, 'irma/iw097e 3.2 unesco 1993' ÑÐ²ÑÐ¶ÐµÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐÑÐµÐŽÐŒÐµÑ=3.2, ÐÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÑ=unesco, Ðž ÐÐ°ÑÐ°=1993 Ñ ÑÐ°Ð¹Ð»ÐŸÐŒ irma/iw097e, ÐµÑÐ»Ðž Ð²ÑÑÐµÑÐ¿ÐŸÐŒÑÐœÑÑÐ°Ñ ÑÑÑÐŸÐºÐ° ÐºÐ»ÑÑÐ° ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐ°). \n\nÐÐ°ÐŒÐµÑÑÑÐµ, ÑÑÐŸ ÐµÑÐ»Ðž Ð»ÑÐ±ÐŸÐµ ÐžÐ· Ð¿ÐŸÐ»ÐµÐ¹ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑ Ð¿Ð»Ð°Ð³ÐžÐœ ÐžÐµÑÐ°ÑÑ
+ÐžÑÐµÑÐºÐŸÐ³ÐŸ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑÐ°, ÐºÐŸÐ³ÐŽÐ° ÐžÑ
+ Ð·ÐœÐ°ÑÐµÐœÐžÐµ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÑ , ÐŸÐœ ÐŽÐŸÐ»Ð¶ÐµÐœ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐŸÐ²Ð°ÑÑ Ð¿ÐµÑÐ²ÐŸÐŒÑ Ð¿ÐŸÐ»Ñ (ÐŽÐµÑÐºÑÐžÐ¿ÑÐŸÑ) Ð² ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÑÑÐµÐŒ ÑÐ°Ð¹Ð»Ðµ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐž. \n\nÐÐœÐ°ÑÐµÐœÐžÑ  ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐŒÐŸÐ³ÑÑ Ð±ÑÑÑ ÐœÐ°Ð·Ð²Ð°ÐœÑ ÐŸÑÐŽÐµÐ»ÑÐœÐŸ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ ÑÑÐ³ (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ,>ÐÑÐµÐŽÐŒÐµÑ<3.2) Ðž ÑÑÐŸ Ð·Ð°ÐŒÐµÐœÐžÑ Ð»ÑÐ±ÐŸÐµ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ, Ð¿ÑÐžÑÐ²ÐŸÐµÐœÐœÐŸÐµ ÐžÐŒ ÐºÐ»ÑÑÐµÐ²ÐŸÐ¹ ÑÑÑÐŸÐºÐŸÐ¹. ÐÑÐ»Ðž ÐºÐ»ÑÑÐµÐ²Ð°Ñ ÑÑÑÐŸÐºÐ° ÐŸÑÑÑÑÑÑÐ²ÑÐµÑ, Ð»ÑÐ±ÐŸÐµ ÐœÐµÐœÐ°Ð·Ð²Ð°ÐœÐœÐŸÐµ Ð·ÐœÐ°ÑÐµÐœÐžÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ð±ÑÐŽÐµÑ ÐœÐ°Ð·Ð²Ð°ÐœÐŸ 'ÐÑÐµÐŽÐŒÐµÑ'.  
+
+ISISPlugin.desc:Ð­ÑÐŸÑ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑ Ð±Ð°Ð·Ñ ÐŽÐ°ÐœÐœÑÑ
+ CDS/ISIS. ÐÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ¹ ÑÐ°ÐºÐŸÐ¹ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÐœÐœÐŸÐ¹ Ð±Ð°Ð·Ñ ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐŸÐ»Ð¶ÐœÑ ÑÑÑÐµÑÑÐ²ÐŸÐ²Ð°ÑÑ ÑÑÐž ÑÐ°Ð¹Ð»Ð° Ð² Ð¿Ð°Ð¿ÐºÐµ ÐžÐŒÐ¿ÐŸÑÑÐ° ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž: ÐŸÑÐœÐŸÐ²ÐœÐŸÐ¹ ÑÐ°Ð¹Ð» (.mst), ÑÐ°Ð±Ð»ÐžÑÐ° ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÑ Ð¿ÐŸÐ»ÐµÐ¹ (.fdt), Ðž ÑÐ°Ð¹Ð» Ð¿ÐµÑÐµÐºÑÐµÑÑÐœÑÑ
+ ÑÑÑÐ»ÐŸÐº (.xrf).
+
+ISISPlugin.subfield_separator:Ð¡ÑÑÐŸÐºÐ°, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÐ°Ñ ÐŽÐ»Ñ ÐŸÑÐŽÐµÐ»ÐµÐœÐžÑ Ð¿ÐŸÐŽÐ¿ÐŸÐ»ÐµÐ¹  Ð² Ð·Ð°Ð¿ÐžÑÑÑ
+ Ð±Ð°Ð·Ñ ÐŽÐ°ÐœÐœÑÑ
+ CDS/ISIS.
+
+ISISPlugin.entry_separator:Ð¡ÑÑÐŸÐºÐ°, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÐ°Ñ ÐŽÐ»Ñ ÐŸÑÐŽÐµÐ»ÐµÐœÐžÑ ÐŒÐœÐŸÐ¶ÐµÑÑÐ²ÐµÐœÐœÑÑ
+ Ð·ÐœÐ°ÑÐµÐœÐžÐ¹ ÐŽÐ»Ñ ÐŸÑÐŽÐµÐ»ÑÐœÑÑ
+ Ð¿ÐŸÐ»ÐµÐ¹ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ð² Ð·Ð°Ð¿ÐžÑÑÑ
+ Ð±Ð°Ð·Ñ ÐŽÐ°ÐœÐœÑÑ
+ CDS/ISIS.
+
+KeyphraseExtractor.desc:ÐÐ»Ð°Ð³ÐžÐœ Ð¿ÐŸÐŒÐŸÑÐž ÐŽÐ»Ñ ÑÐºÑÑÑÐ°ÐºÑÐŸÑÐ° ÐŽÐ»Ñ Ð³ÐµÐœÐµÑÐ°ÑÐžÐž ÐºÐ»ÑÑÐµÐ²ÑÑ
+ ÑÑÐ°Ð· ÐžÐ· ÑÐµÐºÑÑÐ°. ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐ° ÑÐžÑÑÐµÐŒÐ° ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ Kea.  
+
+KeyphraseExtractor.extract_keyphrases:ÐÐ·Ð²Ð»ÐµÑÑ ÐºÐ»ÑÑÐµÐ²ÑÐµ ÑÑÐ°Ð·Ñ  Ñ Ð¿ÐŸÐŒÐŸÑÑÑ Kea (ÐŸÐ¿ÑÐžÐž Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ)
+
+KeyphraseExtractor.extract_keyphrases_kea4:ÐÐ²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐŸÐµ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÐµ ÐºÐ»ÑÑÐµÐ²ÑÑ
+ ÑÐ»ÐŸÐ² Ñ Ð¿ÐŸÐŒÐŸÑÑÑ Kea 4.0 (Ñ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÐ°ÐŒÐž Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ). Kea 4.0 - ÑÑÐŸ ÐœÐŸÐ²Ð°Ñ Ð²ÐµÑÑÐžÑ Kea, ÑÐ°Ð·ÑÐ°Ð±ÐŸÑÐ°ÐœÐ°Ñ ÐŽÐ»Ñ ÐºÐŸÐœÑÑÐŸÐ»ÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐ³ÐŸ ÐžÐœÐŽÐµÐºÑÐžÑÐŸÐ²Ð°ÐœÐžÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ð°Ð³ÑÐžÐºÑÐ»ÑÑÑÑÐœÐŸÐ¹ ÑÐµÐŒÐ°ÑÐžÐºÐž.  
+
+KeyphraseExtractor.extract_keyphrase_options:ÐÐ¿ÑÐžÐž ÐŽÐ»Ñ Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐŸÐ³ÐŸ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ÐºÐ»ÑÑÐµÐ²ÑÑ
+ ÑÑÐ°Ð· Ñ Ð¿ÐŸÐŒÐŸÑÑÑ Kea. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, mALIWEB - ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ ÐŒÐŸÐŽÐµÐ»Ñ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ALIWEB; n5 - ÐžÐ·Ð²Ð»ÐµÐºÐ°Ð¹ Ð¿ÐŸ 5 ÐºÐ»ÑÑÐµÐ²ÑÑ
+ ÑÐ»ÐŸÐ² ÐžÐ· ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°; eGBK - ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ ÐºÐŸÐŽÐžÑÐŸÐ²ÐºÑ GBK.
+
+KeyphraseExtractor.keyphrases:ÐÐ»ÑÑÐµÐ²ÑÐµ ÑÑÐ°Ð·Ñ
+
+KeyphraseExtractor.missing_kea:ÐÑÐžÐ±ÐºÐ°: ÐÐµ ÑÐŽÐ°Ð»ÐŸÑÑÑ ÐœÐ°Ð¹ÑÐž Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑ Kea Ð² %s. ÐÐŸÐ¶Ð°Ð»ÑÐ¹ÑÑÐ°, ÑÐºÐ°ÑÐ°Ð¹ÑÐµ Kea %s Ñ http://www.nzdl.org/Kea Ðž ÑÑÑÐ°ÐœÐŸÐ²ÐžÑÐµ Ð² ÑÑÐŸÐ¹ ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž.  
+
+LaTeXPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² LaTeX.
+
+LOMPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐžÐŒÐ¿ÐŸÑÑÐ° ÑÐ°Ð¹Ð»ÐŸÐ² LOM (Learning Object Metadata).  
+
+LOMPlugin.root_tag:DocType XML-ÑÐ°Ð¹Ð»Ð° (ÐžÐ»Ðž ÑÐµÐ³ÑÐ»ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ, ÑÐºÐ°Ð·ÑÐ²Ð°ÑÑÐµÐµ ÐœÐ° ÐºÐŸÑÐœÐµÐ²ÐŸÐ¹ ÑÐ»ÐµÐŒÐµÐœÑ).  
+
+LOMPlugin.check_timestamp:ÐÑÐŸÐ²ÐµÑÐºÐ° Ð²ÑÐµÐŒÐµÐœÐœÑÑ
+ ÐŸÑÐŒÐµÑÐŸÐº ÑÐ°ÐœÐµÐµ Ð·Ð°Ð³ÑÑÐ¶ÐµÐœÐœÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ², Ð±ÑÐŽÑÑ Ð·Ð°Ð³ÑÑÐ¶ÐµÐœÑ ÑÐŸÐ»ÑÐºÐŸ Ð±ÐŸÐ»ÐµÐµ ÐœÐŸÐ²ÑÐµ.  
+
+LOMPlugin.download_srcdocs:ÐÐ°Ð³ÑÑÐ·ÐžÑÑ ÐžÑÑ
+ÐŸÐŽÐœÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ, ÐµÑÐ»Ðž ÐŸÐœ ÑÐºÐ°Ð·Ð°Ðœ Ð² (general^identifier^entry or technical^location). Ð ÑÑÐŸÐ¹ ÐŸÐ¿ÑÐžÐž ÐœÑÐ¶ÐœÐŸ ÑÐºÐ°Ð·Ð°ÑÑ ÑÐµÐ³ÑÐ»ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ ÐŽÐ»Ñ Ð·Ð°Ð³ÑÑÐ¶Ð°ÐµÐŒÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ² Ð¿ÐµÑÐµÐŽ ÑÐŸÐ±ÑÑÐ²ÐµÐœÐœÐŸ Ð·Ð°Ð³ÑÑÐ·ÐºÐŸÐ¹. ÐÐ° Ð·Ð°ÐŒÐµÑÐºÑ: ÑÑÐŸ ÐœÐµ ÑÐ°Ð±ÐŸÑÐ°ÐµÑ, ÐµÑÐ»Ðž ÐžÑÑ
+ÐŸÐŽÐœÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ ÐœÐ°Ñ
+ÐŸÐŽÐžÑÑÑ Ð·Ð° ÑÐ°Ð¹ÐµÑÐ²ÐŸÐ»ÐŸÐŒ.  
+
+MARCPlugin.desc:ÐÑÐœÐŸÐ²ÐœÐŸÐ¹ Ð¿Ð»Ð°Ð³ÐžÐœ  MARC.
+
+MARCPlugin.metadata_mapping:ÐÐŒÑ ÑÐ°Ð¹Ð»Ð°, ÐºÐŸÑÐŸÑÐŸÐµ Ð²ÐºÐ»ÑÑÐ°ÐµÑ ÐŽÐµÑÐ°Ð»Ðž ÐŸÑÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ Ð·ÐœÐ°ÑÐµÐœÐžÐ¹ ÐžÐ· MARC Ð² ÐžÐŒÐµÐœÐ° ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Greenstone. ÐÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ 'marc2dc.txt' ÐœÐ°Ñ
+ÐŸÐŽÐžÑÑÑ Ð²  ÐŽÐžÑÐµÐºÑÐŸÑÐžÐž ÑÐ°Ð¹ÑÐŸÐ².  
+
+MARCXMLPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ MARCXML.  
+
+MARCXMLPlugin.metadata_mapping_file:ÐÐŒÑ ÑÐ°Ð¹Ð»Ð°, ÐºÐŸÑÐŸÑÐŸÐµ Ð²ÐºÐ»ÑÑÐ°ÐµÑ ÐŸÑÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐµ ÐŽÐµÑÐ°Ð»ÐµÐ¹ ÐžÐ· Ð·ÐœÐ°ÑÐµÐœÐžÐ¹ MARC Ð² ÐžÐŒÐµÐœÐ° ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Greenstone. ÐÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ ÐžÑÐµÑÑÑ 'marcdoc.txt' Ð² etc ÐºÐ°ÑÐ°Ð»ÐŸÐ³Ðµ ÑÐ°Ð¹ÑÐ°.  
+
+MediaWikiPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐžÐŒÐ¿ÐŸÑÑÐ° Ð²ÐµÐ±-ÑÑÑÐ°ÐœÐžÑ MediaWiki.  
+
+MediaWikiPlugin.show_toc:ÐÐŸÐ±Ð°Ð²ÐžÑÑ Ð² ÑÑÑÐ°ÐœÐžÑÑ Â«Ð ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐžÂ» Â«ÐÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÐµÂ» Ñ Ð³Ð»Ð°Ð²ÐœÐŸÐ³ÐŸ ÑÐ°Ð¹ÑÐ° MediaWiki. ÐÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÐŸ ÑÐºÐ°Ð·Ð°ÑÑ ÑÐµÐ³ÑÐ»ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ Perl Ð² toc_exp ÐœÐžÐ¶Ðµ.  
+
+MediaWikiPlugin.delete_toc:Ð£ÐŽÐ°Ð»ÐžÑÑ ÑÐµÐºÑÐžÑ Â«ÐÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÐµÂ» ÐœÐ° ÐºÐ°Ð¶ÐŽÐŸÐ¹ HTML-ÑÑÑÐ°ÐœÐžÑÐµ. ÐÑÐ¶ÐœÐŸ ÑÐºÐ°Ð·Ð°ÑÑ ÑÐµÐ³ÑÐ»ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ Perl Ð² toc_exp ÐœÐžÐ¶Ðµ.  
+
+MediaWikiPlugin.toc_exp:Ð ÐµÐ³ÑÐ»ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ Perl ÐŽÐ»Ñ Â«ÐÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÑÂ». ÐÐœÐ°ÑÐµÐœÐžÐµ Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ Ð±ÑÐŽÐµÑ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐŸÐ²Ð°ÑÑ ÐŸÐ±ÑÑÐœÑÐŒ ÑÑÑÐ°ÐœÐžÑÐ°ÐŒ MediaWiki.  
+
+MediaWikiPlugin.delete_nav:Ð£ÐŽÐ°Ð»ÐžÑÑ ÑÐµÐºÑÐžÑ ÐœÐ°Ð²ÐžÐ³Ð°ÑÐžÐž. ÐÑÐ¶ÐœÐŸ ÑÐºÐ°Ð·Ð°ÑÑ ÑÐµÐ³ÑÐ»ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ Perl Ð² nav_div_exp ÐœÐžÐ¶Ðµ.  
+
+MediaWikiPlugin.nav_div_exp:Ð ÐµÐ³ÑÐ»ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ Perl ÐŽÐ»Ñ ÑÐµÐºÑÐžÐž ÐœÐ°Ð²ÐžÐ³Ð°ÑÐžÐž. ÐÐœÐ°ÑÐµÐœÐžÐµ Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ Ð±ÑÐŽÐµÑ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐŸÐ²Ð°ÑÑ ÐŸÐ±ÑÑÐœÑÐŒ ÑÑÑÐ°ÐœÐžÑÐ°ÐŒ MediaWiki.  
+
+MediaWikiPlugin.delete_searchbox:Ð£ÐŽÐ°Ð»ÐžÑÑ ÑÐµÐºÑÐžÑ Ð¿ÐŸÐžÑÐºÐŸÐ²ÐŸÐ³ÐŸ ÐŽÐžÐ°Ð»ÐŸÐ³Ð°. ÐÑÐ¶ÐœÐŸ ÑÐºÐ°Ð·Ð°ÑÑ ÑÐµÐ³ÑÐ»ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ Perl Ð² searchbox_div_exp ÐœÐžÐ¶Ðµ.  
+
+MediaWikiPlugin.searchbox_div_exp:Ð ÐµÐ³ÑÐ»ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ ÐœÐ° ÑÐ·ÑÐºÐµ Perl ÐŽÐ»Ñ Ð²Ð²ÐµÐŽÐµÐœÐžÑ Ð² ÐŸÐºÐœÐµ Ð¿ÐŸÐžÑÐºÐ°. ÐÐœÐ°ÑÐµÐœÐžÐµ Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÐµÑ ÐŸÐ±ÑÐžÐŒ Ð²ÐµÐ±ÑÑÑÐ°ÐœÐžÑÐ°ÐŒ MediaWiki.  
+
+MediaWikiPlugin.remove_title_suffix_exp:Ð ÐµÐ³ÑÐ»ÑÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ Perl ÐŽÐ»Ñ ÐŸÐ±ÑÐµÐ·ÐºÐž ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐœÐŸÐ³ÐŸ Ð·Ð°Ð³Ð»Ð°Ð²ÐžÑ. ÐÐ°Ð¿ÑÐžÐŒÐµÑ, \\s-(.+) ÐŸÐ±ÑÐµÐ¶ÐµÑ ÑÐŸÐŽÐµÑÐ¶ÐžÐŒÐŸÐµ Ð¿ÐŸÑÐ»Ðµ Â«-Â».  
+
+MetadataCSVPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ð² ÑÐŸÑÐŒÐ°ÑÐµ Ð·ÐœÐ°ÑÐµÐœÐžÐ¹, ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐœÑÑ
+ Ð·Ð°Ð¿ÑÑÐŸÐ¹. ÐÐŸÐ»Ðµ Filename Ð² ÑÐ°Ð¹Ð»Ðµ CSV ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐŽÐ»Ñ ÑÐŸÐ³ÐŸ, ÑÑÐŸÐ±Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐžÑÑ, ÐºÐ°ÐºÐŸÐŒÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð¿ÑÐžÐœÐ°ÐŽÐ»ÐµÐ¶Ð°Ñ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ.  
+
+MetadataPass.desc:ÐÐŸÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»ÑÐœÑÐ¹ ÐºÐ»Ð°ÑÑ Ðº BasPlug, ÐºÐŸÑÐŸÑÑÐ¹ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐžÐ²Ð°ÐµÑ Ð¿Ð°ÑÐ°ÐŒÐµÑÑ Ð¿Ð»Ð°Ð³ÐžÐœÐ° ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÑ
+ metadata_read Ð² import.pl  
+
+MetadataXMLPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐºÐŸÑÐŸÑÑÐ¹ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑ ÑÐ°Ð¹Ð» metadata.xml.  
+
+MetadataEXIFPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÐŸÐ³ÐŸ EXIF ÐžÐ· ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹, Ð°ÑÐŽÐžÐŸ Ðž Ð²ÐžÐŽÐµÐŸ. ÐÐŸÐ»ÐµÐµ ÐºÐŸÐœÐºÑÐµÑÐœÐŸ ÐŸÐœ, ÐŸÑÐœÐŸÐ²Ð°ÐœÐœ ÐœÐ° CPAN ÐŒÐŸÐŽÑÐ»Ðµ 'ExifTool ". ÐÐ° ÑÐ°ÐŒÐŸÐŒ ÐŽÐµÐ»Ðµ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐžÐ²Ð°ÐµÑ Ð±ÐŸÐ»ÑÑÐµ ÑÐŸÑÐŒÐ°ÑÐŸÐ², ÐœÐ°Ð¿ÑÐžÐŒÐµÑ GPS, XMP, FlashPix, ID3, Vorbis. ÐÐ»Ð°Ð³ÐžÐœ Ð²ÑÐžÐ³ÑÑÐ²Ð°ÐµÑ ÐŸÑ ÑÑÐŸÐ³ÐŸ, Ðž Ð±ÑÐ» ÑÐ°Ð·ÑÐ°Ð±ÐŸÑÐ°Ðœ ÐŽÐ»Ñ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐºÐž Ð²ÑÐµÑ
+ ÑÐŸÑÐŒÐ°ÑÐŸÐ² Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐžÐ²Ð°ÑÑÐžÑ
+ ExifTool-ÐŸÐŒ. Ð¡ÐŒ.  ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°ÑÐžÑ ExifTool Ð¿ÐŸ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐžÐ²Ð°ÐµÐŒÑÐŒ ÑÐžÐ¿Ð°ÐŒ ÑÐ°Ð¹Ð»ÐŸÐ² Ðž ÑÑ
+ÐµÐŒ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+.  
+
+GreenstoneMETSPlugin.desc:ÐÐ±ÑÐ°Ð±ÐŸÑÐ°ÑÑ METS-ÐŽÐŸÐºÑÐŒÐµÐœÑÑ ÐºÐ°Ðº ÐÑÐžÐœÑÑÐŸÑÐœ  
+
+MP3Plugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž MP3 ÑÐ°Ð¹Ð»ÐŸÐ².
+
+MP3Plugin.assoc_images:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ Ð¿ÐŸÐžÑÐº ÐºÐ°ÑÑÐžÐœÐŸÐº Ð² Google, ÑÑÐŸÐ±Ñ ÐœÐ°Ð¹ÑÐž ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ Ð¿ÐŸÐŽÑ
+ÐŸÐŽÑÑÐµÐµ Ðº ÑÐ°Ð¹Ð»Ñ MP3, ÐœÐ° ÐŸÑÐœÐŸÐ²Ðµ ÐµÐ³ÐŸ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ ID3 Title Ðž ÐÑÐ¿ÐŸÐ»ÐœÐžÑÐµÐ»Ñ.  
+
+MP3Plugin.applet_metadata:ÐÑÐ¿ÐŸÐ»ÑÐ·Ð°Ð²Ð°ÐœÐœÐŸ ÐŽÐ»Ñ ÑÐŸÐ³ÐŸ, ÑÑÐŸÐ±Ñ Ñ
+ÑÐ°ÐœÐžÑÑ ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÐµ [applet] ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°, Ð² ÐºÐŸÑÐŸÑÐŸÐŒ ÑÐŸÐŽÐµÑÐ¶ÐžÑÑÑ ÐºÐŸÐŽ HTML ÐŽÐ»Ñ Ð¿ÑÐŸÐžÐ³ÑÑÐ²Ð°ÐœÐžÑ ÑÑÐŸÐ³ÐŸ ÑÐ°Ð¹Ð»Ð° Ð² MP3 Ð¿ÑÐŸÐžÐ³ÑÑÐ²Ð°ÑÐµÐ»Ðµ.  
+
+MP3Plugin.metadata_fields:Ð¡Ð¿ÐžÑÐŸÐº Ð¿ÐŸÐ»ÐµÐ¹ ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÑ
+, Ð¿ÐµÑÐµÑÐžÑÐ»ÐµÐœÐœÑÑ
+ ÑÐµÑÐµÐ· Ð·Ð°Ð¿ÑÑÑÑ, ÐºÐŸÑÐŸÑÑÐµ Ð¿ÑÐµÐŽÐœÐ°Ð·ÐœÐ°ÑÐµÐœÑ ÐŽÐ»Ñ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ÐžÐ· MP3 ÑÐ°Ð¹Ð»Ð° (ÐµÑÐ»Ðž ÐŽÐŸÑÑÑÐ¿ÐµÐœ). ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ \"*\" ÐŽÐ»Ñ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ Ð²ÑÐµÑ
+ Ð¿ÐŸÐ»ÐµÐ¹.
+
+NulPlugin.desc:Ð¥ÐŸÐ»ÐŸÑÑÐŸÐµ Ð·ÐœÐ°ÑÐµÐœÐžÐµ Ð¿Ð»Ð°Ð³ÐžÐœÐ° ÐŽÐ»Ñ ÑÐ°Ð¹Ð»Ð° (.nul). ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ Ñ ÑÐ°Ð¹Ð»Ð°ÐŒÐž, ÑÐŸÐ·ÐŽÐ°ÐœÐœÑÐŒÐž Ð¿ÑÐž ÑÐ°ÑÑÐžÑÐµÐœÐžÐž Ð±Ð°Ð·Ñ ÐŽÐ°ÐœÐœÑÐ¹ ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÐŒÐž ÑÐ°Ð¹Ð»ÐŸÐ².
+
+NulPlugin.assoc_field:ÐÐ°Ð·Ð²Ð°ÐœÐžÑ Ð¿ÐŸÐ»Ñ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, ÐºÐŸÑÐŸÑÐŸÐµ Ð±ÑÐŽÐµÑ Ð¿ÑÐžÑÐ²ÐŸÐµÐœÐŸ ÐºÐ°Ð¶ÐŽÐŸÐŒÑ ÑÐ°Ð¹Ð»Ñ nul.  
+NulPlugin.add_metadata_as_text:ÐÐŸÐ±Ð°Ð²ÐžÑÑ ÑÐ°Ð±Ð»ÐžÑÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐºÐ°Ðº ÑÐµÐºÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°, Ð° ÐœÐµ ÐºÐ°Ðº Â«Ð­ÑÐŸÑ ÐŽÐŸÐºÑÐŒÐµÐœÑ ÐœÐµ ÑÐŸÐŽÐµÑÐ¶ÐžÑ ÑÐµÐºÑÑÐ°Â».  
+
+NulPlugin.remove_namespace_for_text:Ð£ÐŽÐ°Ð»ÐžÑÑ Ð¿ÑÐŸÐ±ÐµÐ»Ñ ÐžÐ· ÐžÐŒÐµÐœ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ð² ÑÐµÐºÑÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° (ÐµÑÐ»Ðž ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐŸ add_metadata_as_text).  
+
+OAIPlugin.desc:ÐÑÐœÐŸÐ²ÐœÐŸÐ¹ Ð¿Ð»Ð°Ð³ÐžÐœ ÐžÑÑ
+ÐŸÐŽÐœÑÑ
+ ÐŸÑÐºÑÑÑÑÑ
+ Ð°ÑÑ
+ÐžÐ²ÐŸÐ² (OAI).  
+
+OAIPlugin.document_field:Ð­Ð»ÐµÐŒÐµÐœÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ Ñ ÑÐºÐ°Ð·Ð°ÐœÐžÐµÐŒ ÐžÐŒÐµÐœÐž ÑÐ°Ð¹Ð»Ð° ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Ñ Ð¿ÐŸÐŽÐºÐ»ÑÑÐµÐœÐœÑÐŒÐž Ðº ÐœÐžÐŒ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐŒÐž.  
+
+OAIPlugin.metadata_set:ÐÐ°Ð±ÐŸÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ (ÐžÐŒ Ñ Ð¿ÑÐµÑÐžÐºÑÐŸÐŒ) ÐŽÐ»Ñ ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ Ð²ÑÐµÑ
+ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐºÐ°Ðº  
+OAIPlugin.metadata_set.auto:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ Ð¿ÑÐµÑÐžÐºÑÑ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÑÐµ Ð² Ð·Ð°Ð¿ÐžÑÑÑ
+ 
+ÐžÐœÐžÑÐžÐ°ÑÐžÐ²Ñ "ÐÑÐºÑÑÑÑÐµ Ð°ÑÑ
+ÐžÐ²Ñ" (OAI)  
+OAIPlugin.metadata_set.dc:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ Ð¿ÑÐµÑÐžÐºÑ dc.   
+
+OggVorbisPlugin.add_technical_metadata:ÐÐŸÐ±Ð°Ð²ÐžÑÑ ÑÐµÑ
+ÐœÐžÑÐµÑÐºÐžÐµ ÐŒÐµÑÐ°-ÐŽÐ°ÐœÐœÑÐµ (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, ÑÐºÐŸÑÐŸÑÑÑ Ð¿ÐµÑÐµÐŽÐ°ÑÐž).
+
+OggVorbisPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ Ð·Ð²ÑÐºÐŸÐ²ÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ² Ogg Vorbis.
+
+OpenDocumentPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² ÑÐŸÑÐŒÐ°ÑÐ° OASIS OpenDocument (ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÑ
+ Ð² OpenOffice 2.0)  
+
+PagedImagePlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÑÐŸÑÑÐ°Ð²Ð»ÐµÐœÐœÑÑ
+ ÐžÐ· Ð¿ÐŸÑÐ»ÐµÐŽÐŸÐ²Ð°ÑÐµÐ»ÑÐœÐŸÑÑÐž ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹, Ñ ÐœÐµÐŸÐ±ÑÐ·Ð°ÑÐµÐ»ÑÐœÑÐŒ ÑÐ°ÑÐ¿ÐŸÐ·ÐœÐ°ÐœÐœÑÐŒ ÑÐµÐºÑÑÐŸÐŒ Ðº ÐºÐ°Ð¶ÐŽÐŸÐŒÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ.
+
+PagedImagePlugin.documenttype:Ð£ÑÑÐ°ÐœÐŸÐ²ÐžÑÐµ ÑÐžÐ¿ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° (ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐŽÐ»Ñ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ°).
+
+PagedImagePlugin.documenttype.paged:Ð¡ÑÑÐ°ÐœÐžÑÐœÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°Ñ ÑÑÑÐµÐ»ÐºÐž 'Ð¡Ð»ÐµÐŽÑÑÑÐ°Ñ' Ðž 'ÐÑÐµÐŽÑÐŽÑÑÐ°Ñ' Ðž ÐºÐœÐŸÐ¿ÐºÑ 'ÐÐµÑÐµÐ¹ÑÐž Ðº ÑÑÑÐ°ÐœÐžÑÐµ X'.
+
+PagedImagePlugin.documenttype.hierarchy:ÐÐµÑÐ°ÑÑ
+ÐžÑÐµÑÐºÐžÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ ÑÐŸÐŽÐµÑÐ¶Ð°Ñ ÐŸÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÐµ.
+
+PagedImagePlugin.headerpage:ÐÐŸÐ±Ð°Ð²ÐžÑÑ ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° Ð·Ð°Ð³Ð»Ð°Ð²ÐœÑÑ ÑÑÑÐ°ÐœÐžÑÐºÑ (Ð±ÐµÐ· ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ).
+
+PDFPlugin.allowimagesonly:Ð Ð°Ð·ÑÐµÑÐžÑÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµ ÑÐ°Ð¹Ð»ÐŸÐ² PDF, Ð² ÐºÐŸÑÐŸÑÑÑ
+ ÐœÐµÑ ÐžÐ·Ð²Ð»ÐµÐºÐ°ÐµÐŒÐŸÐ³ÐŸ ÑÐµÐºÑÑÐ°. Ð¡ÐœÐžÐŒÐ°ÐµÑ ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒÐŸÑÑÑ ÐºÐ»Ð°ÑÑÐ° -complex. ÐÐŸÐ»ÐµÐ·ÐœÐŸ ÑÐŸÐ»ÑÐºÐŸ Ñ convert_to html.  
+
+PDFPlugin.complex:Ð¡ÐŸÐ·ÐŽÐ°ÐµÑ Ð±ÐŸÐ»ÐµÐµ ÑÐ»ÐŸÐ¶ÐœÑÑ Ð¿ÑÐŸÐŽÑÐºÑÐžÑ. Ð¡ ÑÑÐŸÐ¹ ÐŸÐ¿ÑÐžÐµÐ¹ ÑÑÑÐ°ÐœÐŸÐ²ÐŸÐº Ð¿ÑÐŸÐŽÑÐºÑÐžÑ Ð² ÑÐŸÑÐŒÐ°ÑÐµ HTML Ð±ÑÐŽÐµÑ Ð²ÑÐ³Ð»ÑÐŽÐµÑÑ Ð·ÐœÐ°ÑÐžÑÐµÐ»ÑÐœÐŸ Ð±ÐŸÐ»ÐµÐµ Ð¿ÐŸÑ
+ÐŸÐ¶ÐµÐ¹ ÐœÐ° ÐŸÑÐžÐ³ÐžÐœÐ°Ð»ÑÐœÑÐ¹ PDF-ÑÐ°Ð¹Ð». ÐÐ»Ñ ÑÐŸÐ³ÐŸ, ÑÑÐŸÐ±Ñ ÑÑÐœÐºÑÐžÐŸÐœÐžÑÐŸÐ²Ð°ÑÑ ÐŽÐŸÐ»Ð¶ÐœÑÐŒ ÐŸÐ±ÑÐ°Ð·ÐŸÐŒ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœ Ghostscript (ÐŽÐ»Ñ *nix gs ÐŽÐŸÐ»Ð¶ÐµÐœ Ð±ÑÑÑ ÐœÐ° Ð²Ð°ÑÐµÐŒ Ð¿ÑÑÐž ÐŽÐŸÑÑÑÐ¿Ð°, Ð² ÑÐŸ Ð²ÑÐµÐŒÑ ÐºÐ°Ðº ÐŽÐ»Ñ Windows Ñ ÐÐ°Ñ ÐŽÐŸÐ»Ð¶ÐµÐœ Ð±ÑÑÑ gswin32c.exe ÐœÐ° Ð¿ÑÑÐž ÐŽÐŸÑÑÑÐ¿Ð°).
+
+PDFPlugin.desc:ÐÑÐžÐµÐŒÐ»ÐµÐŒÑÐ¹ Ð¿Ð»Ð°Ð³ÐžÐœ with-it pdf.
+
+PDFPlugin.nohidden:ÐÑÐµÐ¿ÑÑÑÑÐ²ÑÐµÑ Ð¿ÐŸÐ¿ÑÑÐºÐ°ÐŒ pdftohtml ÐžÐ·Ð²Ð»ÐµÑÑ ÑÐºÑÑÑÑÐ¹ ÑÐµÐºÑÑ. Ð­ÑÐŸ Ð¿ÐŸÐ»ÐµÐ·ÐœÐŸ ÑÐŸÐ»ÑÐºÐŸ, ÐµÑÐ»Ðž ÐŸÐ¿ÑÐžÑ  -complex ÑÐ°ÐºÐ¶Ðµ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐ°.
+
+PDFPlugin.noimages:ÐÐµ Ð¿ÑÑÐ°Ð¹ÑÐµÑÑ ÐžÐ·Ð²Ð»ÐµÐºÐ°ÑÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÐžÐ· PDF.
+
+PDFPlugin.use_sections:Ð¡ÐŸÐ·ÐŽÐ°ÑÑ ÐŸÑÐŽÐµÐ»ÑÐœÑÐ¹ ÑÐ°Ð·ÐŽÐµÐ» ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ¹ ÑÑÑÐ°ÐœÐžÑÑ PDF-ÑÐ°Ð¹Ð»Ð°.
+
+PDFPlugin.zoom:Ð€Ð°ÐºÑÐŸÑ, c Ð¿ÐŸÐŒÐŸÑÑÑ ÐºÐŸÑÐŸÑÐŸÐ³ÐŸ ÐžÐ·ÐŒÐµÐœÑÐµÑÑÑ ÐŒÐ°ÑÑÑÐ°Ð± ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ PDF (ÑÑÐŸ Ð¿ÐŸÐ»ÐµÐ·ÐœÐŸ ÑÐŸÐ»ÑÐºÐŸ, ÐµÑÐ»Ðž   ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœ -complex).
+
+PostScriptPlugin.desc:Ð­ÑÐŸ - Ð¿ÐŸÑÑÑÐºÑÐžÐ¿ÑÑÐŒ \"Ð±ÐµÐŽÐœÑÐµ Ð»ÑÐŽÐž\" ÐŽÐ»Ñ ÑÐµÐºÑÑÐŸÐ²ÐŸÐ³ÐŸ ÐºÐŸÐœÐ²ÐµÑÑÐµÑÐ°.. ÐÑÐ»Ðž ÑÐµÑÑÐµÐ·ÐœÐŸ, ÑÐ°ÑÑÐŒÐŸÑÑÐžÑÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµ Ð¿Ð°ÐºÐµÑÐ° PRESCRIPT, ÐºÐŸÑÐŸÑÑÐ¹ ÐŽÐŸÑÑÑÐ¿ÐµÐœ ÐŽÐ»Ñ Ð·Ð°Ð³ÑÑÐ·ÐºÐž Ñ http://www.nzdl.org/html/software.html
+
+PostScriptPlugin.extract_date:ÐÐ·Ð²Ð»ÐµÑÐµÐœÐžÐµ ÐŽÐ°ÑÑ ÐžÐ· Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐ° PS.
+
+PostScriptPlugin.extract_pages:ÐÐ·Ð²Ð»ÐµÑÐµÐœÐžÐµ ÑÑÑÐ°ÐœÐžÑ ÐžÐ· Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐ° PS.
+
+PostScriptPlugin.extract_title:ÐÐ·Ð²Ð»ÐµÑÐµÐœÐžÐµ ÐœÐ°Ð·Ð²Ð°ÐœÐžÑ ÐžÐ· Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐ° PS.
+
+PowerPointPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐžÐŒÐ¿ÐŸÑÑÐ° ÑÐ°Ð¹Ð»ÐŸÐ² Microsoft PowerPoint.
+
+PowerPointPlugin.windows_scripting:ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÑÐµÑ
+ÐœÐŸÐ»ÐŸÐ³ÐžÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐžÑÐŸÐ²Ð°ÐœÐžÑ MicroSoft Windows (Visual Basic ÐŽÐ»Ñ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ), ÑÑÐŸÐ±Ñ ÑÐºÐŸÐœÐ²ÐµÑÑÐžÑÐŸÐ²Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ PPT Ð² ÑÐµÑÐžÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐ¹ ÑÐ°Ð·Ð»ÐžÑÐœÐŸÐ³ÐŸ ÑÐžÐ¿Ð° (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, JPEG,PNG,GIF), Ð²ÐŒÐµÑÑÐŸ Ð¿Ð°ÐºÐµÑÐ° open source ppttohtml.  
+
+PrintInfo.bad_general_option:ÐÐ»Ð°Ð³ÐžÐœ %s ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑ ÐœÐµÐºÐŸÑÑÐµÐºÑÐœÑÑ ÐŸÐ±ÑÑÑ ÐŸÐ¿ÑÐžÑ (ÐŸÐ±ÑÐžÐµ ÐŸÐ¿ÑÐžÐž -  ÑÑÐŸ ÑÐµ, ÐºÐŸÑÐŸÑÑÐµ ÐŽÐŸÑÑÑÐ¿ÐœÑ Ð²ÑÐµÐŒ Ð¿Ð»Ð°Ð³ÐžÐœÐ°ÐŒ). ÐÑÐŸÐ²ÐµÑÑÑÐµ Ð²Ð°Ñ ÐºÐŸÐœÑÐžÐ³ÑÑÐ°ÑÐžÐŸÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» collect.cfg.
+
+PrintInfo.desc:Ð Ð±ÐŸÐ»ÑÑÐžÐœÑÑÐ²Ðµ Ð¿Ð»Ð°Ð³ÐžÐœ, ÐžÐŒÐµÐµÑ ÐŽÐµÐ»ÐŸ Ñ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐµÐ¹ ÐŸ Ð¿ÐµÑÐ°ÑÐž  (pluginfo.pl) Ðž Ð°ÐœÐ°Ð»ÐžÐ·ÐžÑÑÐµÑ Ð°ÑÐ³ÑÐŒÐµÐœÑÑ pluginfo.pl.  
+
+ProCitePlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ (ÑÐºÑÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐœÑÑ
+) Ð±Ð°Ð· ÐŽÐ°ÐœÐœÑÑ
+ ProCite  
+
+ProCitePlugin.entry_separator:Ð¡ÑÑÐŸÐºÐ° ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐŽÐ»Ñ ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐžÑ ÐœÐµÑÐºÐŸÐ»ÑÐºÐžÑ
+ Ð·ÐœÐ°ÑÐµÐœÐžÐ¹ ÐŸÑÐŽÐµÐ»ÑÐœÑÑ
+ Ð¿ÐŸÐ»ÐµÐ¹ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ Ð·Ð°Ð¿ÐžÑÐµÐ¹ Ð² Ð±Ð°Ð·Ðµ ÐŽÐ°ÐœÐœÑÑ
+ ProCite.  
+
+ReadTextFile.could_not_extract_encoding:ÐÐ ÐÐÐ£ÐÐ ÐÐÐÐÐÐÐ: ÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÐµ ÐœÐµ ÑÐŒÐŸÐ³Ð»ÐŸ Ð±ÑÑÑ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐŸ ÐžÐ· %s - Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ Ðº %s
+
+ReadTextFile.could_not_extract_language:ÐÐ ÐÐÐ£ÐÐ ÐÐÐÐÐÐÐ: ÑÐ·ÑÐº ÐœÐµ ÑÐŒÐŸÐ³ Ð±ÑÑÑ ÐžÐ·Ð²Ð»ÐµÑÐµÐœ ÐžÐ· %s - Ð¿ÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ Ðº %s
+
+ReadTextFile.could_not_open_for_reading:ÐœÐµ ÑÐŒÐŸÐ³ ÐŸÑÐºÑÑÑÑ %s ÐŽÐ»Ñ ÑÑÐµÐœÐžÑ
+
+ReadTextFile.default_encoding:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ ÑÑÐŸ ÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÐµ, ÐµÑÐ»Ðž -input_encoding ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœ ÐœÐ° 'Ð°Ð²ÑÐŸ', Ð° Ð°Ð»Ð³ÐŸÑÐžÑÐŒ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐž ÑÐµÐºÑÑÐ° ÐœÐµ Ð² ÑÐŸÑÑÐŸÑÐœÐžÐž ÐžÐ·Ð²Ð»ÐµÑÑ Ð·Ð°ÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐœÑÐµ ÐžÐ»Ðž ÐžÐ·Ð²Ð»ÐµÐºÐ°ÐµÑ Ð·Ð°ÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐœÑÐµ, ÐœÐŸ ÐœÐµÐ¿ÐŸÐŽÐŽÐµÑÐ¶ÐžÐ²Ð°ÐµÐŒÑÐµ Greenstone. Ð­ÑÐ° ÐŸÐ¿ÑÐžÑ ÐŒÐŸÐ¶ÐµÑ Ð±ÑÐ°ÑÑ ÑÐµ Ð¶Ðµ ÑÐ°ÐŒÑÐµ Ð·ÐœÐ°ÑÐµÐœÐžÑ, ÐºÐ°Ðº Ðž -input_encoding.
+
+ReadTextFile.default_language:ÐÑÐ»Ðž Greenstone ÐœÐµ Ð² ÑÐŸÑÑÐŸÑÐœÐžÐž ÑÐµÑÐžÑÑ, ÐºÐ°ÐºÐžÐŒ ÑÐ²Ð»ÑÐµÑÑÑ ÑÐ·ÑÐº ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°, ÑÐ»ÐµÐŒÐµÐœÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ 'Ð¯Ð·ÑÐº' Ð±ÑÐŽÐµÑ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœ ÐœÐ° ÑÑÐŸ Ð·ÐœÐ°ÑÐµÐœÐžÐµ. ÐÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ -  ÑÑÐŸ 'en' (ÐÐ¡Ð ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑ 639 ÑÐžÐŒÐ²ÐŸÐ»ÐŸÐ² ÑÐ·ÑÐºÐ°: en = Ð°ÐœÐ³Ð»ÐžÐ¹ÑÐºÐžÐ¹ ÑÐ·ÑÐº). ÐÐ±ÑÐ°ÑÐžÑÐµ Ð²ÐœÐžÐŒÐ°ÐœÐžÐµ, ÑÑÐŸ ÐµÑÐ»Ðž -input_encoding ÐœÐµ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœ ÐœÐ° 'Ð°Ð²ÑÐŸ', Ðž -extract_language ÐœÐµ ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœ, Ð²ÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð±ÑÐŽÑÑ ÐžÐŒÐµÑÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐžÑ
+ 'Ð¯Ð·ÑÐºÐ°' ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœÐœÑÐŒÐž ÐœÐ° ÑÑÐŸ Ð·ÐœÐ°ÑÐµÐœÐžÐµ.
+
+ReadTextFile.desc:ÐÐ°Ð·ÐŸÐ²ÑÐ¹ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÑÐ°Ð¹Ð»ÐŸÐ², ÐžÐŒÐµÑÑÐžÑ
+ ÐŸÐ±ÑÑÐœÑÐ¹ ÑÐµÐºÑÑÐŸÐ²ÑÐ¹ ÑÐŸÑÐŒÐ°Ñ.  
+
+ReadTextFile.empty_file:ÑÐ°Ð¹Ð» ÐœÐµ ÑÐŸÐŽÐµÑÐ¶ÐžÑ ÐœÐžÐºÐ°ÐºÐŸÐ³ÐŸ ÑÐµÐºÑÑÐ°
+
+ReadTextFile.extract_language:ÐÐŽÐµÐœÑÐžÑÐžÑÐžÑÑÐ¹ÑÐµ ÑÐ·ÑÐº ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ° Ðž ÑÑÑÐ°ÐœÐŸÐ²ÐžÑÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ 'Ð¯Ð·ÑÐº' . ÐÐ±ÑÐ°ÑÐžÑÐµ Ð²ÐœÐžÐŒÐ°ÐœÐžÐµ, ÑÑÐŸ ÑÑÐŸ Ð±ÑÐŽÐµÑ ÑÐŽÐµÐ»Ð°ÐœÐŸ Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐž, ÐµÑÐ»Ðž -input_encoding ÑÑÑÐ°ÐœÐŸÐ²Ð»ÐµÐœ ÐœÐ° 'Ð°Ð²ÑÐŸ'.
+
+ReadTextFile.file_has_no_text:ÐÐšÐÐÐÐ: %s ÐœÐµ ÑÐŸÐŽÐµÑÐ¶ÐžÑ ÐœÐžÐºÐ°ÐºÐŸÐ³ÐŸ ÑÐµÐºÑÑÐ°
+
+ReadTextFile.input_encoding:ÐÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÐµ ÐžÑÑ
+ÐŸÐŽÐœÑÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ². ÐÐŸÐºÑÐŒÐµÐœÑÑ Ð±ÑÐŽÑÑ ÐºÐŸÐœÐ²ÐµÑÑÐžÑÐŸÐ²Ð°ÐœÑ ÐžÐ· ÑÑÐžÑ
+ ÑÐžÑÑÐŸÐ²Ð°ÐœÐžÐ¹ Ðž Ñ
+ÑÐ°ÐœÐžÑÑÑÑ Ð²ÐœÑÑÑÐž ÑÐžÑÑÐµÐŒÑ Ð² Ð²ÐžÐŽÐµ utf8.
+
+ReadTextFile.input_encoding.auto:ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐ¹ÑÐµ Ð°Ð»Ð³ÐŸÑÐžÑÐŒ ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐžÐž ÑÐµÐºÑÑÐ° ÐŽÐ»Ñ Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐŸÐ¹ ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐžÐž ÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÑ ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ ÐžÑÑ
+ÐŸÐŽÐœÐŸÐ³ÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°. Ð­ÑÐŸ Ð±ÑÐŽÐµÑ ÐŒÐµÐŽÐ»ÐµÐœÐœÐµÐµ, ÑÐµÐŒ ÑÑÑÐ°ÐœÐŸÐ²ÐºÐ° ÑÐžÑÑÐŸÐ²Ð°ÐœÐžÑ Ð² ÑÐ²ÐœÐŸÐŒ Ð²ÐžÐŽÐµ, ÐœÐŸ Ð±ÑÐŽÐµÑ ÑÐ°Ð±ÐŸÑÐ°ÑÑ ÑÐ°ÐŒ, Ð³ÐŽÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ Ð±ÐŸÐ»ÑÑÐµ ÑÐµÐŒ ÐŸÐŽÐžÐœ Ð²ÐžÐŽ ÑÐžÑÑÐŸÐ²Ð°ÐœÐžÑ  Ð² Ð¿ÑÐµÐŽÐµÐ»Ð°Ñ
+ ÑÐŸÐ¹ Ð¶Ðµ ÑÐ°ÐŒÐŸÐ¹ ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž.
+
+ReadTextFile.read_denied:Ð Ð°Ð·ÑÐµÑÐµÐœÐžÐµ ÑÑÐµÐœÐžÑ,  ÐŸÑÐºÐ»ÐŸÐœÐµÐœÐœÐŸÐµ ÐŽÐ»Ñ %s
+
+ReadTextFile.separate_cjk:ÐÐŸÐŒÐµÑÐ°ÐµÑ Ð·ÐœÐ°ÐºÐž Ð¿ÑÐŸÐ±ÐµÐ»Ð° ÐŒÐµÐ¶ÐŽÑ ÐºÐžÑÐ°Ð¹ÑÐºÐžÐŒÐž, ÑÐ¿ÐŸÐœÑÐºÐžÐŒÐž Ðž ÐºÐŸÑÐµÐ¹ÑÐºÐžÐŒÐž ÐžÐµÑÐŸÐ³Ð»ÐžÑÐ°ÐŒÐž, ÑÐ°Ðº ÑÑÐŸ ÐºÐ°Ð¶ÐŽÑÐ¹ Ð¿ÑÐŸÐ±ÐµÐ» ÑÐ°Ð·ÐŽÐµÐ»ÑÐµÑ ÐŽÐ²Ð° ÑÐ»ÐŸÐ²Ð°. ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÐŽÐ»Ñ ÐœÐµ ÑÐµÐ³ÐŒÐµÐœÑÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐ³ÐŸ ÑÐµÐºÑÑÐ°.  
+
+ReadTextFile.unsupported_encoding:ÐÐ ÐÐÐ£ÐÐ ÐÐÐÐÐÐÐ: %s Ð¿ÐŸÑÐ²Ð»ÑÐµÑÑÑ, ÑÑÐŸÐ±Ñ Ð±ÑÑÑ Ð·Ð°ÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐœÑÐŒ Ð² ÐœÐµÐ¿ÐŸÐŽÐŽÐµÑÐ¶Ð°ÐœÐœÐŸÐŒ ÑÐžÑÑÐŸÐ²Ð°ÐœÐžÐž (%s) - ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ %s
+
+ReadTextFile.wrong_encoding:ÐÐ ÐÐÐ£ÐÐ ÐÐÐÐÐÐÐ: %s ÑÐžÑÐ°Ð»ÐŸÑÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑ %s ÑÐžÑÑÐŸÐ²Ð°ÐœÐžÐµ, ÐœÐŸ  Ð¿ÐŸÑÐ²Ð»ÑÐ»ÐŸÑÑ ÐºÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐœÑÐŒ ÐºÐ°Ðº %s.
+
+ReadXMLFile.desc:ÐÑÐœÐŸÐ²ÐœÐŸÐ¹ ÐºÐ»Ð°ÑÑ Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐ² XML.
+
+ReadXMLFile.xslt:Ð¢ÑÐ°ÐœÑÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÑÑ Ð¿ÐŸÐŽÑ
+ÐŸÐŽÑÑÐžÐ¹ Ð²Ð²ÐŸÐŽÐžÐŒÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð² ÐŸÐ±ÐŸÐ·ÐœÐ°ÑÐµÐœÑÐ¹ ÑÐ°Ð¹Ð» Ñ Ð¿ÐŸÐŒÐŸÑÑÑ XSLT.  ÐÑÐµÐŽÐ¿ÐŸÐ»Ð°Ð³Ð°ÐµÑÑÑ ÐŸÑÐœÐŸÑÐžÑÐµÐ»ÑÐœÐŸÐµ ÐœÐ°Ð·Ð²Ð°ÐœÐžÑ ÑÐ°Ð¹Ð»Ð°, ÐœÐ°Ñ
+ÐŸÐŽÑÑÐµÐ³ÐŸÑÑ Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÐž, Ðº Ð¿ÑÐžÐŒÐµÑÑ  etc/mods2dc.xsl.  
+
+RealMediaPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž ÑÐ°Ð¹Ð»ÐŸÐ² Real Media.  
+
+ReferPlugin.desc:ReferPlug ÑÐžÑÐ°ÐµÑ Ð±ÐžÐ±Ð»ÐžÐŸÐ³ÑÐ°ÑÐžÑÐµÑÐºÐžÐµ ÑÐ°Ð¹Ð»Ñ Ð² ÑÐµÑÐµÑÐ°ÑÐžÐ²ÐœÐŸÐŒ ÑÐŸÑÐŒÐ°ÑÐµ.  
+
+RogPlugin.desc:Ð¡ÐŸÐ·ÐŽÐ°ÐµÑ Ð¿ÑÐŸÑÑÑÐµ ÐŸÐŽÐœÐŸ-ÑÑÐŸÐ²ÐœÐµÐ²ÑÐµ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ ÐžÐ· ÑÐ°Ð¹Ð»ÐŸÐ² .rog ÐžÐ»Ðž .mdb.
+
+RTFPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ ÑÐ°Ð¹Ð»ÐŸÐ² RTF.
+
+SourceCodePlugin.desc:ÐÐŒÑ ÑÐ°Ð¹Ð»Ð° Ð² ÐœÐ°ÑÑÐŸÑÑÐµÐµ Ð²ÑÐµÐŒÑ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ ÐŽÐ»Ñ ÐÐ°Ð·Ð²Ð°ÐœÐžÑ (Ð¿ÑÐŸÐžÐ·Ð²ÐŸÐ»ÑÐœÐŸ Ð²ÑÐ±ÑÐ°ÐœÐœÐŸÐµ ÐŒÐžÐœÑÑ ÐœÐµÐºÐŸÑÐŸÑÑÑ Ð¿ÑÐžÑÑÐ°Ð²ÐºÑ). Ð¢ÐµÐºÑÑÐžÐµ ÑÐ·ÑÐºÐž:\nÑÐµÐºÑÑ:READMEs/Ð¡ÐŸÐ·ÐŽÐ°ÐœÐžÐµÑÐ°Ð¹Ð»ÐŸÐ²\nC/C ++ (Ð² ÐœÐ°ÑÑÐŸÑÑÐµÐµ Ð²ÑÐµÐŒÑ ÐžÐ·Ð²Ð»ÐµÐºÐ°ÐµÑ #Ð²ÐºÐ»ÑÑÐµÐœÐœÑÐµ ÐŸÐ¿ÐµÑÐ°ÑÐŸÑÑ Ðž decls ÐºÐ»Ð°ÑÑÐ° C ++ ) \nPerl (Ð² ÐœÐ°ÑÑÐŸÑÑÐµÐµ Ð²ÑÐµÐŒÑ Ð¿ÑÐµÐŽÑÑÐ°Ð²Ð»ÐµÐœÐœÑÐ¹ ÑÐŸÐ»ÑÐºÐŸ Ð² Ð²ÐžÐŽÐµ ÑÐµÐºÑÑÐ°) \nÐÐ±ÐŸÐ»ÐŸÑÐºÐ° (Ð² ÐœÐ°ÑÑÐŸÑÑÐµÐµ Ð²ÑÐµÐŒÑ Ð¿ÑÐµÐŽÑÑÐ°Ð²Ð»ÐµÐœÐœÐ°Ñ ÑÐŸÐ»ÑÐºÐŸ Ð² Ð²ÐžÐŽÐµ ÑÐµÐºÑÑÐ°).
+
+SourceCodePlugin.remove_prefix:Ð£ÐŽÐ°Ð»ÐžÑÑ ÑÑÐŸÑ Ð²ÐµÐŽÑÑÐžÐ¹ ÐŸÐ±ÑÐ°Ð·ÐµÑ ÐžÐ· ÐžÐŒÐµÐœÐž ÑÐ°Ð¹Ð»Ð° (eg-remove_prefix/tmp/xx/src/). ÐÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ ÐŽÐŸÐ»Ð¶ÐµÐœ Ð²ÐµÑÑ Ð¿ÑÑÑ ÐŽÐŸÑÑÑÐ¿Ð° ÐŸÑ ÐžÐŒÐµÐœÐž ÑÐ°Ð¹Ð»Ð°.
+
+SplitTextFile.desc:SplitPlug - ÑÑÐŸ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÑÐ°Ð·Ð±ÐžÐµÐœÐžÑ Ð²Ñ
+ÐŸÐŽÐœÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ² ÐœÐ° ÑÐµÐ³ÐŒÐµÐœÑÑ, ÐºÐŸÑÐŸÑÑÐµ Ð±ÑÐŽÑÑ Ð¿ÐŸÑÐŸÐŒ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÑÑÑÑ Ð¿ÐŸ ÐŸÑÐŽÐµÐ»ÑÐœÐŸÑÑÐž.Ð­ÑÐŸÑ Ð¿Ð»Ð°Ð³ÐžÐœ ÐœÐµÐ»ÑÐ·Ñ Ð²ÑÐ·Ð²Ð°ÑÑ ÐœÐµÐ¿ÐŸÑÑÐµÐŽÑÑÐ²ÐµÐœÐœÐŸ. ÐÐŒÐµÑÑÐŸ ÑÑÐŸÐ³ÐŸ, ÐµÑÐ»Ðž ÐÑ ÐŽÐŸÐ»Ð¶ÐœÑ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÑÑ Ð²Ñ
+ÐŸÐŽÐœÑÐµ ÑÐ°Ð¹Ð»Ñ, ÐºÐŸÑÐŸÑÑÐµ ÑÐŸÐŽÐµÑÐ¶Ð°Ñ ÐœÐµÑÐºÐŸÐ»ÑÐºÐŸ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÐÑ ÐŽÐŸÐ»Ð¶ÐœÑ ÐœÐ°Ð¿ÐžÑÐ°ÑÑ Ð¿Ð»Ð°Ð³ÐžÐœ Ñ ÑÑÐœÐºÑÐžÐµÐ¹ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž, ÐºÐŸÑÐŸÑÑÐ¹ Ð±ÑÐŽÐµÑ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÑÑ ÐŸÐŽÐžÐœ ÐžÐ· ÑÑÐžÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ², ÐœÐ°ÑÐ»ÐµÐŽÑÑ ÐµÐ³ÐŸ ÐžÐ· SplitPlug. Ð¡ÐŒ. ReferPlug ÐŽÐ»Ñ Ð¿ÑÐžÐŒÐµÑÐ°.  
+
+SplitTextFile.split_exp:ÐÑÐ°Ð²ÐžÐ»ÑÐœÐŸÐµ Ð²ÑÑÐ°Ð¶ÐµÐœÐžÐµ perl ÐŽÐ»Ñ ÑÐ°Ð·Ð±ÐžÐµÐœÐžÑ Ð²Ñ
+ÐŸÐŽÐœÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ² ÐœÐ° ÑÐ°ÑÑÐž.
+
+StructuredHTMLPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž ÑÑÑÑÐºÑÑÑÐžÑÐŸÐ²Ð°ÐœÐœÑÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² HTML, ÑÐ°Ð·ÐŽÐµÐ»ÑÑ ÐžÑ
+ ÐœÐ° ÑÐµÐºÑÐžÐž Ð¿ÐŸ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž ÐžÐ· ÑÑÐžÐ»ÐµÐ¹.  
+
+StructuredHTMLPlugin.delete_toc:Ð£ÐŽÐ°Ð»ÐžÑÑ "Ð¡ÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÐµ" Ðž "Ð¡Ð¿ÐžÑÐŸÐº ÑÐ°Ð±Ð»ÐžÑ" ÐžÐ· ÐºÐŸÐœÐ²ÐµÑÑÐžÑÐŸÐ²Ð°ÐœÐœÐŸÐ³ÐŸ ÑÐ°Ð¹Ð»Ð° HTML.  
+
+StructuredHTMLPlugin.title_header:ÑÑÑÐ°ÐœÐŸÐ²ÐžÑÑ Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÑÐ¹ ÑÑÐžÐ»Ñ ÐŽÐ»Ñ title_header, ÐºÐŸÑÐŸÑÑÐ¹ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐžÐ» Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ.  
+
+StructuredHTMLPlugin.level1_header:Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÑÐ¹ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÑÐ¹ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐŒ ÑÑÐžÐ»Ñ Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐŸÐ² Ð¿ÐµÑÐ²ÐŸÐ³ÐŸ ÑÑÐŸÐ²ÐœÑ Ð² ÐŽÐŸÐºÑÐŒÐµÐœÑÐµ HTML (ÑÐºÐ²ÐžÐ²Ð°Ð»ÐµÐœÑ Ðº <h1>).  
+
+StructuredHTMLPlugin.level2_header:Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÑÐ¹ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÑÐ¹ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐŒ ÑÑÐžÐ»Ñ Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐŸÐ² Ð²ÑÐŸÑÐŸÐ³ÐŸ ÑÑÐŸÐ²ÐœÑ Ð² ÐŽÐŸÐºÑÐŒÐµÐœÑÐµ HTML (ÑÐºÐ²ÐžÐ²Ð°Ð»ÐµÐœÑ Ðº <h2>).  
+
+StructuredHTMLPlugin.level3_header:Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÑÐµ ÑÑÐžÐ»Ðž, ÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÐµÐŒÑÐµ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐŒ, ÐŽÐ»Ñ Ð·Ð°Ð³ÐŸÐ»ÐŸÐ²ÐºÐŸÐ² ÑÑÐµÑÑÐµÐ³ÐŸ ÑÑÐŸÐ²ÐœÑ Ð² ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°Ñ
+ HTML (ÑÐºÐ²ÐžÐ²Ð°Ð»ÐµÐœÑ Ðº <h3>).  
+
+StructuredHTMLPlugin.toc_header:Ð²ÐŸÐ·ÐŒÐŸÐ¶ÐœÑÐ¹ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÑÐ¹ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐŒ ÑÑÐžÐ»Ñ ÐŸÐ³Ð»Ð°Ð²Ð»ÐµÐœÐžÑ  
+
+TextPlugin.desc:Ð¡ÐŸÐ·ÐŽÐ°ÐµÑ Ð¿ÑÐŸÑÑÐŸÐ¹ ÐŸÐŽÐœÐŸ-ÑÑÐŸÐ²ÐœÐµÐ²ÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ. ÐÐŸÐ±Ð°Ð²Ð»ÑÐµÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ ÐÐ°Ð·Ð²Ð°ÐœÐžÑ ÐžÐ· Ð¿ÐµÑÐ²ÐŸÐ¹ ÑÑÑÐŸÐºÐž ÑÐµÐºÑÑÐ° (ÐŽÐ»ÐžÐœÐŸÐ¹ ÐŽÐŸ 100 Ð·ÐœÐ°ÐºÐŸÐ².
+
+TextPlugin.title_sub:ÐÑÑÐ°Ð¶ÐµÐœÐžÐµ Ð·Ð°ÐŒÐµÐœÑ ÐŽÐ»Ñ ÐžÐ·ÐŒÐµÐœÐµÐœÐžÑ ÑÑÑÐŸÐºÐž, Ñ
+ÑÐ°ÐœÑÑÐµÐ¹ÑÑ ÐºÐ°Ðº ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ. ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ, ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, PSPlug, ÑÑÐŸÐ±Ñ ÑÐŽÐ°Ð»ÐžÑÑ "Ð¡ÑÑÐ°ÐœÐžÑÑ 1" Ðž Ñ.ÐŽ ÐžÐ· ÑÐµÐºÑÑÐ°, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÐŸÐ³ÐŸ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÐœÐ°Ð·Ð²Ð°ÐœÐžÑ.  
+
+UnknownPlugin.assoc_field:ÐÐŒÑ Ð¿ÐŸÐ»Ñ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, ÐºÐŸÑÐŸÑÐŸÐµ Ð±ÑÐŽÐµÑ ÐŽÐµÑÐ¶Ð°ÑÑ ÐžÐŒÐµÐœÐ° Ð°ÑÑÐŸÑÐžÐžÑÐŸÐ²Ð°ÐœÐœÑÑ
+ ÑÐ°Ð¹Ð»ÐŸÐ².
+
+UnknownPlugin.desc:Ð­ÑÐŸ Ð¿ÑÐŸÑÑÐŸÐ¹ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ ÑÐ°Ð¹Ð»ÐŸÐ² Ð² ÑÐŸÑÐŒÐ°ÑÐ°Ñ
+, ÐœÐµÐžÐ·Ð²ÐµÑÑÐœÑÑ
+ ÐŽÐ»Ñ Greenstone.  ÐÑÐŒÑÑÐ»ÐµÐœÐœÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð±ÑÐŽÐµÑ ÑÐŸÐ·ÐŽÐ°Ðœ ÐŽÐ»Ñ ÐºÐ°Ð¶ÐŽÐŸÐ³ÐŸ ÑÐ°ÐºÐŸÐ³ÐŸ ÑÐ°Ð¹Ð»Ð°, Ðž ÑÐ°ÐŒ ÑÐ°Ð¹Ð» Ð±ÑÐŽÐµÑ Ð¿ÐµÑÐµÐŽÐ°Ðœ Ð² Greenstone ÐºÐ°Ðº \"Ð°ÑÑÐŸÑÐžÐžÑÐŸÐ²Ð°ÐœÐœÑÐ¹ ÑÐ°Ð¹Ð»\" ÐŽÐŸÐºÑÐŒÐµÐœÑÐ°.
+
+UnknownPlugin.file_format:Ð¢ÐžÐ¿ ÑÐ°Ð¹Ð»Ð° (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, MPEG, MIDI, ...).
+
+UnknownPlugin.mime_type:Ð¢ÐžÐ¿ ÑÐ°Ð¹Ð»Ð°  mime (ÐœÐ°Ð¿ÑÐžÐŒÐµÑ, ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐµ/gif).
+
+UnknownPlugin.process_extension:ÐÐ±ÑÐ°Ð±ÐŸÑÐºÐ° ÑÐ°Ð¹Ð»ÐŸÐ² Ñ ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÑÐŒ ÑÐ°ÑÑÐžÑÐµÐœÐžÐµÐŒ. Ð­ÑÐ° ÐŸÐ¿ÑÐžÑ - Ð°Ð»ÑÑÐµÑÐœÐ°ÑÐžÐ²Ð° Ðº process_exp, ÐºÐŸÑÐŸÑÐ°Ñ Ð¿ÑÐŸÑÐµ, ÐœÐŸ ÐŒÐµÐœÐµÐµ Ð¿ÑÐžÑÐ¿ÐŸÑÐ°Ð±Ð»ÐžÐ²Ð°ÐµÐŒÐ°Ñ.
+
+UnknownPlugin.srcicon:Ð£ÐºÐ°Ð¶ÐžÑÐµ ÐŒÐ°ÐºÑÐŸ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ (Ð±ÐµÐ· ÑÐžÐŒÐ²ÐŸÐ»ÐŸÐ² Ð¿ÐŸÐŽÑÐµÑÐºÐžÐ²Ð°ÐœÐžÑ), ÑÑÐŸÐ±Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ Ð² ÐºÐ°ÑÐµÑÑÐ²Ðµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ srcicon.  
+
+WordPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ ÐŽÐ»Ñ ÐžÐŒÐ¿ÐŸÑÑÐžÑÐŸÐ²Ð°ÐœÐžÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² Microsoft Word.
+
+WordPlugin.windows_scripting:ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÑÐµÑ
+ÐœÐŸÐ»ÐŸÐ³ÐžÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐžÑÐŸÐ²Ð°ÐœÐžÑ Microsoft Windows (Visual Basic ÐŽÐ»Ñ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒ), ÑÑÐŸÐ±Ñ Word ÐºÐŸÐœÐ²ÐµÑÑÐžÑÐŸÐ²Ð°Ð» ÐŽÐŸÐºÑÐŒÐµÐœÑÑ Ð²  HTML, Ð²ÐŒÐµÑÑÐŸ Ð¿Ð°ÐºÐµÑÐ° open source WvWare. ÐÑÐž ÑÑÐŸÐŒ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐ° Word ÐŸÑÐºÑÐŸÐµÑÑÑ ÐœÐ° ÑÐºÑÐ°ÐœÐµ, ÐµÑÐ»Ðž ÐŸÐœÐ° ÐµÑÐµ ÐœÐµ Ð·Ð°Ð¿ÑÑÐµÐœÐ°.
+
+WordPlugin.metadata_fields:Ð­ÑÐ° ÐŸÐ¿ÑÐžÑ ÐŽÐ»Ñ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐžÐ· ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² HTML ÑÐºÐŸÐœÐ²ÐµÑÑÐžÑÐŸÐ²Ð°ÐœÐœÑÑ
+ Ñ Ð¿ÐŸÐŒÐŸÑÑÑ ÑÐºÑÐžÐ¿ÑÐ° VB. ÐÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ ÐŒÐŸÐ¶ÐµÑ ÑÐºÐ°Ð·Ð°ÑÑ ÑÐµÑÐµÐ· Ð·Ð°Ð¿ÑÑÑÑ ÑÐ¿ÐžÑÐŸÐº Ð¿ÐŸÐ»ÐµÐ¹ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+, ÐºÐŸÑÐŸÑÑÐµ ÑÑÐµÐ±ÑÐµÑÑÑ ÐžÐ·Ð²Ð»ÐµÑÑ. Ð£ÐºÐ°Ð¶ÐžÑÐµ 'tag<tagname>', ÑÑÐŸÐ±Ñ Ð¿ÐµÑÐ²ÐŸÐµ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐœÐŸÐµ Ð·ÐœÐ°ÑÐµÐœÐžÐµ Ð¿Ð°ÑÑ <tagname> ÑÐŸÑ
+ÑÐ°ÐœÐžÑÑ Ð² ÑÐ»ÐµÐŒÐµÐœÑÐµ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐœÐ°Ð·Ð²Ð°ÐœÐœÐŸÐŒ 'tagname'. ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÐµ Ð±ÐŸÐ»ÑÑÐžÐµ Ð±ÑÐºÐ²Ñ, ÑÑÐŸÐ±Ñ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÐµ Ð±ÑÐ»Ðž Ð¿ÐŸÐºÐ°Ð·Ð°ÐœÑ Ð² ÐÑÐžÐœÑÑÐŸÑÐœ ÑÐŸÐŸÑÐ²ÐµÑÑÐ²ÑÑÑÐµ. ÐÐ»Ñ ÐžÐ·Ð²Ð»ÐµÑÐµÐœÐžÑ ÑÑÐŸ ÐœÐµ ÐžÐ³ÑÐ°ÐµÑ ÑÐŸÐ»Ðž.  
+
+ZIPPlugin.desc:ÐÐ»Ð°Ð³ÐžÐœ, ÐºÐŸÑÐŸÑÑÐ¹ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑ ÑÐ¶Ð°ÑÑÐµ Ðž/ÐžÐ»Ðž Ð°ÑÑ
+ÐžÐ²ÐžÑÐŸÐ²Ð°ÐœÐœÑÐµ Ð²Ñ
+ÐŸÐŽÐœÑÐµ ÑÐŸÑÐŒÐ°ÑÑ, ÑÐµÐºÑÑÐžÐµ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÐœÐœÑÐµ ÑÐŸÑÐŒÐ°ÑÑ Ðž ÑÐ°Ð¹Ð»Ñ Ñ ÑÐ°ÑÑÐžÑÐµÐœÐžÑÐŒÐž:\ngzip (.gz, .z, .tgz, .taz)\nbzip (.bz)\nbzip2 (.bz2)\nzip (.zip .jar)\ntar (.tar)\n\n Ð­ÑÐŸÑ Ð¿Ð»Ð°Ð³ÐžÐœ ÐŸÐ¿ÐžÑÐ°ÐµÑÑÑ ÐœÐ° ÑÐ»ÐµÐŽÑÑÑÐžÐµ Ð¿ÑÐžÑÑÑÑÑÐ²ÑÑÑÐžÐµ ÑÑÐžÐ»ÐžÑÑ (ÐµÑÐ»Ðž Ð¿ÑÑÐ°ÑÑÑÑ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÑÑ ÑÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÑÑÑÐžÐµ ÑÐŸÑÐŒÐ°ÑÑ):\ngunzip (ÐŽÐ»Ñ gzip)\nbunzip (ÐŽÐ»Ñ bzip)\nbunzip2 \nunzip (ÐŽÐ»Ñzip)\ntar (ÐŽÐ»Ñ tar).
+
+#
+# Download module option descriptions
+#
+
+BaseDownload.desc:ÐÑÐœÐŸÐ²ÐœÐŸÐ¹ ÐºÐ»Ð°ÑÑ ÐŽÐ»Ñ ÐŒÐŸÐŽÑÐ»ÐµÐ¹ Ð·Ð°Ð³ÑÑÐ·ÐºÐž  
+BaseDownload.bad_general_option:% Ð·Ð°Ð³ÑÑÐ·ÐºÐž ÐŒÐŸÐŽÑÐ»Ñ ÐŽÐ»Ñ ÐœÐµÐºÐŸÑÐµÐºÑÐœÐŸÐ³ÐŸ Ð²ÑÐ±ÐŸÑÐ°.  
+MediaWikiDownload.desc:ÐÐŸÐŽÑÐ»Ñ ÐŽÐ»Ñ Ð·Ð°Ð³ÑÑÐ·ÐºÐž Ñ ÑÐ°Ð¹ÑÐŸÐ² MediaWiki.  
+MediaWikiDownload.reject_filetype:Ð¡Ð¿ÐžÑÐŸÐº ÐžÐ³ÐœÐŸÑÐžÑÑÐµÐŒÑÑ
+ URL-ÐŸÐ², ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐœÑÑ
+ Ð·Ð°Ð¿ÑÑÑÐŒÐž, ÐœÐ°Ð¿ÑÐžÐŒÐµÑ *cgi-bin*,*.ppt Ð·Ð°ÑÑÐ°Ð²ÐžÑ ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÑÑ Ð³ÐžÐ¿ÐµÑÑÑÑÐ»ÐºÐž, ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐžÐµ ÐžÐ»Ðž 'cgi-bin', ÐžÐ»Ðž '.ppt'  
+MediaWikiDownload.reject_filetype_disp:Ð¡Ð¿ÐžÑÐŸÐº ÐžÐ³ÐœÐŸÑÐžÑÑÐµÐŒÑÑ
+ URL-ÐŸÐ², ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐœÑÑ
+ Ð·Ð°Ð¿ÑÑÑÐŒÐž.  
+MediaWikiDownload.exclude_directories:Ð¡Ð¿ÐžÑÐŸÐº ÐžÑÐºÐ»ÑÑÐ°ÐµÐŒÑÑ
+ ÐºÐ°ÑÐ°Ð»ÐŸÐ³ÐŸÐ² (ÐœÐµÐŸÐ±Ñ
+ÐŸÐŽÐžÐŒ Ð¿ÐŸÐ»ÐœÑÐ¹ Ð¿ÑÑÑ Ðº ÐºÐ°ÑÐ°Ð»ÐŸÐ³Ñ), ÐœÐ°Ð¿ÑÐžÐŒÐµÑ /people,/documentation ÐžÑÐºÐ»ÑÑÐžÑ Ð¿ÐŸÐŽÐºÐ°ÑÐ°Ð»ÐŸÐ³Ðž 'people' Ðž 'documentation'.  
+MediaWikiDownload.exclude_directories_disp:Ð¡Ð¿ÐžÑÐŸÐº ÐžÑÐºÐ»ÑÑÐ°ÐµÐŒÑÑ
+ ÐºÐ°ÑÐ°Ð»ÐŸÐ³ÐŸÐ², ÑÐ°Ð·ÐŽÐµÐ»ÐµÐœÐœÑÑ
+ Ð·Ð°Ð¿ÑÑÑÐŒÐž.  
+
+OAIDownload.desc:ÐÐŸÐŽÑÐ»Ñ ÐŽÐ»Ñ Ð·Ð°Ð³ÑÑÐ·ÐºÐž ÐžÐ· ÑÐµÐ¿ÐŸÐ·ÐžÑÐŸÑÐžÐµÐ² OAI  
+OAIDownload.url_disp:ÐÑÑ
+ÐŸÐŽÐœÑÐ¹ URL  
+OAIDownload.url:URL ÑÐµÐ¿ÐŸÐ·ÐžÑÐŸÑÐžÑ OAI  
+OAIDownload.set_disp:Ð£ÑÑÐ°ÐœÐŸÐ²ÐžÑÑ  
+OAIDownload.set:ÐÐ³ÑÐ°ÐœÐžÑÐžÑÑ Ð·Ð°Ð³ÑÑÐ·ÐºÑ ÑÐºÐ°Ð·Ð°ÐœÐœÐŸÐ³ÐŸ ÐœÐ°Ð±ÐŸÑÐ° Ð² ÑÐµÐ¿ÐŸÐ·ÐžÑÐŸÑÐžÐž  
+OAIDownload.metadata_prefix_disp:ÐÑÐµÑÐžÐºÑ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+  
+OAIDownload.metadata_prefix:Ð€ÐŸÑÐŒÐ°Ñ ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ Ð² ÑÐºÑÐ¿ÐŸÑÑÐµ, Ð¿ÑÐžÐŒ: oai_dc, qdc Ðž Ñ.ÐŽ. ÐÐ°Ð¶ÐŒÐžÑÐµ ÐºÐœÐŸÐ¿ÐºÑ <server information>, ÑÑÐŸÐ±Ñ Ð²ÑÑÑÐœÐžÑÑ, ÐºÐ°ÐºÐžÐµ ÑÐŸÑÐŒÐ°ÑÑ Ð¿ÐŸÐŽÐŽÐµÑÐ¶ÐžÐ²Ð°ÑÑÑÑ.  
+OAIDownload.get_doc_disp:ÐÐŸÐ»ÑÑÐžÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑ  
+OAIDownload.get_doc:ÐÐ°Ð³ÑÑÐ·ÐžÑÑ ÐžÑÑ
+ÐŸÐŽÐœÑÐ¹ ÐŽÐŸÐºÑÐŒÐµÐœÑ, ÐµÑÐ»Ðž ÐŸÐœ ÑÐºÐ°Ð·Ð°Ðœ Ð² Ð·Ð°Ð¿ÐžÑÐž  
+OAIDownload.get_doc_exts_disp:ÐÐºÐ»ÑÑÐ°ÐµÑ ÑÐŸÐ»ÑÐºÐŸ ÑÐžÐ¿Ñ ÑÐ°Ð¹Ð»ÐŸÐ²  
+OAIDownload.get_doc_exts:ÐÐŸÐ¿ÑÑÑÐžÐŒÑÐµ ÑÐ°ÑÑÐžÑÐµÐœÐžÑ ÑÐ°Ð¹Ð»ÐŸÐ² ÐŽÐ»Ñ Ð¿ÐŸÐ»ÑÑÐµÐœÐžÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ²  
+OAIDownload.max_records_disp:ÐÐ°ÐºÑÐžÐŒÑÐŒ Ð·Ð°Ð¿ÐžÑÐµÐ¹  
+OAIDownload.max_records:ÐÐ°ÐºÑÐžÐŒÑÐŒ Ð·Ð°Ð¿ÐžÑÐµÐ¹ ÐŽÐ»Ñ Ð·Ð°Ð³ÑÑÐ·ÐºÐž  
+
+SRWDownload.desc:ÐÐŸÐŽÑÐ»Ñ ÐŽÐ»Ñ Ð·Ð°Ð³ÑÑÐ·ÐºÐž ÐžÐ· ÑÐµÐ¿ÐŸÐ·ÐžÑÐŸÑÐžÐµÐ² SRW (Search/Retrieve Web Service)  
+
+WebDownload.desc:ÐÐŸÐŽÑÐ»Ñ ÐŽÐ»Ñ Ð·Ð°Ð³ÑÑÐ·ÐºÐž ÐžÐ· ÐÐœÑÐµÑÐœÐµÑÐ° Ð¿ÐŸ HTTP ÐžÐ»Ðž FTP  
+WebDownload.url:ÐÑÑ
+ÐŸÐŽÐœÑÐ¹ URL. ÐÐŸÐ¶ÐµÑ ÐžÐ·ÐŒÐµÐœÑÑÑÑÑ Ð² ÑÐ»ÑÑÐ°Ðµ Ñ http.  
+WebDownload.url_disp:ÐÑÑ
+ÐŸÐŽÐœÑÐ¹ URL  
+WebDownload.depth:ÐÐ° ÑÐºÐŸÐ»ÑÐºÐŸ ÑÑÑÐ»ÐŸÐº Ð² Ð³Ð»ÑÐ±ÐžÐœÑ ÐŸÐ¿ÑÑÐºÐ°ÑÑÑÑ Ð¿ÑÐž Ð·Ð°Ð³ÑÑÐ·ÐºÐµ  
+WebDownload.depth_disp:ÐÐ»ÑÐ±ÐžÐœÐ° Ð·Ð°ÐºÐ°ÑÐºÐž  
+WebDownload.below:ÐÑÐ·ÐµÑÐºÐ°Ð»ÐžÑÑ ÑÐŸÐ»ÑÐºÐŸ ÑÐ°Ð¹Ð»Ñ Ñ ÑÑÐŸÐ³ÐŸ URL  
+WebDownload.below_disp:ÐÑÐ·ÐµÑÐºÐ°Ð»ÐžÑÑ ÑÐŸÐ»ÑÐºÐŸ ÑÐ°Ð¹Ð»Ñ Ñ ÑÑÐŸÐ³ÐŸ URL  
+WebDownload.within:Ð¢ÐŸÐ»ÑÐºÐŸ ÐŸÑÐ·ÐµÑÐºÐ°Ð»ÐžÑÑ ÑÐ°Ð¹Ð»Ñ Ñ ÑÐŸÐ³ÐŸ Ð¶Ðµ ÑÐ°Ð¹ÑÐ°  
+WebDownload.within_disp:Ð¢ÐŸÐ»ÑÐºÐŸ ÐŽÐ»Ñ ÑÐ°Ð¹Ð»ÐŸÐ² Ñ ÑÐŸÐ³ÐŸ Ð¶Ðµ ÑÐ°Ð¹ÑÐ°  
+WebDownload.html_only:ÐÐ°Ð³ÑÑÐ¶Ð°ÑÑ ÑÐŸÐ»ÑÐºÐŸ HTML-ÑÐ°Ð¹Ð»Ñ Ðž ÐžÐ³ÐœÐŸÑÐžÑÐŸÐ²Ð°ÑÑ Ð°ÑÑÐŸÑÐžÐžÑÐŸÐ²Ð°ÐœÐœÑÐµ Ñ ÐœÐžÐŒÐž ÑÐ°Ð¹Ð»Ñ, ÑÐ°ÐºÐžÐµ ÐºÐ°Ðº ÐºÐ°ÑÑÐžÐœÐºÐž Ðž ÑÐ°Ð±Ð»ÐžÑÑ ÑÑÐžÐ»ÐµÐ¹  
+WebDownload.html_only_disp:ÐÐ°Ð³ÑÑÐ¶Ð°ÑÑ ÑÐŸÐ»ÑÐºÐŸ HTML-ÑÐ°Ð¹Ð»Ñ  
+
+WgetDownload.desc:ÐÑÐœÐŸÐ²ÐœÐŸÐ¹ ÐºÐ»Ð°ÑÑ, ÐºÐŸÑÐŸÑÑÐ¹ ÐŸÐ±ÑÐ°Ð±Ð°ÑÑÐ²Ð°ÐµÑ Ð·Ð°Ð¿ÑÐŸÑÑ Ðº wget  
+WgetDownload.proxy_on:ÐÐºÐ»ÑÑÐžÑÑ Ð¿ÑÐŸÐºÑÐž  
+WgetDownload.proxy_host:ÐÐŒÑ Ñ
+ÐŸÑÑÐ° Ð¿ÑÐŸÐºÑÐž  
+WgetDownload.proxy_port:ÐÐŸÑÑ Ð¿ÑÐŸÐºÑÐž  
+WgetDownload.user_name:ÐÐŒÑ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ  
+WgetDownload.user_password:ÐÐ°ÑÐŸÐ»Ñ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»Ñ  
+
+Z3950Download.desc:ÐÐŸÐŽÑÐ»Ñ ÐŽÐ»Ñ Ð·Ð°Ð³ÑÑÐ·ÐºÐž ÐžÐ· ÑÐµÐ¿ÐŸÐ·ÐžÑÐŸÑÐžÐµÐ² Z3950  
+Z3950Download.host:URL Ñ
+ÐŸÑÑÐ°  
+Z3950Download.host_disp:Ð¥ÐŸÑÑ  
+Z3950Download.port:ÐÐŸÐŒÐµÑ Ð¿ÐŸÑÑÐ° ÑÐµÐ¿ÐŸÐ·ÐžÑÐŸÑÐžÑ  
+Z3950Download.port_disp:ÐÐŸÑÑ  
+Z3950Download.database:ÐÐ°Ð·Ð° ÐŽÐ°ÐœÐœÑÑ
+ ÐŽÐ»Ñ Ð¿ÐŸÐžÑÐºÐ°  
+Z3950Download.database_disp:ÐÐ°Ð·Ð° ÐŽÐ°ÐœÐœÑÑ
+  
+Z3950Download.find:ÐÐŸÐºÐ°Ð·Ð°ÑÑ Ð·Ð°Ð¿ÐžÑÐž, ÑÐŸÐŽÐµÑÐ¶Ð°ÑÐžÐµ ÑÐºÐ°Ð·Ð°ÐœÐœÑÑ ÑÑÑÐŸÐºÑ Ð¿ÐŸÐžÑÐºÐ°  
+Z3950Download.find_disp:ÐÐ°Ð¹ÑÐž  
+Z3950Download.max_records:ÐÐ°ÐºÑÐžÐŒÑÐŒ Ð·Ð°Ð¿ÐžÑÐµÐ¹ ÐŽÐ»Ñ Ð·Ð°Ð³ÑÑÐ·ÐºÐž  
+Z3950Download.max_records_disp:ÐÐ°ÐºÑÐžÐŒÑÐŒ Ð·Ð°Ð¿ÐžÑÐµÐ¹  
+
+
+#
+#Plugout option descriptions
+#
+
+BasPlugout.bad_general_option:ÐÐŸÐŽÑÐ»Ñ %s ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑ ÐœÐµÐºÐŸÑÑÐµÐºÑÐœÑÑ ÐŸÐ¿ÑÐžÑ.  
+BasPlugout.debug:ÑÑÑÐ°ÐœÐŸÐ²ÐºÐ° ÑÐµÐ¶ÐžÐŒÐ° ÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÑ ÐŸÑÐžÐ±ÐŸÐº  
+BasPlugout.desc:ÐÑÐœÐŸÐ²ÐœÐŸÐ¹ ÐºÐ»Ð°ÑÑ ÐŽÐ»Ñ Ð²ÑÐµÑ
+ ÐŒÐŸÐŽÑÐ»ÐµÐ¹.  
+BasPlugout.group_size:ÐÑÐŸÐœÑÐŒÐµÑÐŸÐ²Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑÑ ÐŽÐ»Ñ Ð³ÑÑÐ¿Ð¿ÐžÑÐŸÐ²ÐºÐž Ð² ÐŸÐŽÐžÐœ XML-ÑÐ°Ð¹Ð».  
+BasPlugout.gzip_output:ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ gzip ÐŽÐ»Ñ ÑÐ¶Ð°ÑÐžÑ ÑÐµÐ·ÑÐ»ÑÑÐžÑÑÑÑÐžÑ
+ xml-ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ² (ÐœÐµ Ð·Ð°Ð±ÑÐŽÑÑÐµ Ð²ÐºÐ»ÑÑÐžÑÑ ZIPPlug Ð² ÑÐ²ÐŸÐ¹ ÑÐ¿ÐžÑÐŸÐº Ð¿Ð»Ð°Ð³ÐžÐœÐŸÐ² ÐŽÐ»Ñ ÑÐ±ÐŸÑÐºÐž ÑÐ¶Ð°ÑÑÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ²).  
+BasPlugout.output_handle:ÑÐ°Ð¹Ð»ÐŸÐ²ÑÐ¹ ÐŽÐµÑÐºÑÐžÐ¿ÑÐŸÑ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÐ¹ ÐŽÐ»Ñ Ð¿ÐŸÑÑÐ»ÐºÐž Ð²ÑÑ
+ÐŸÐŽÐœÐŸÐ¹ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž  
+BasPlugout.output_info:ÑÑÑÐ»ÐºÐ° ÐœÐ° ÐŸÐ±ÑÐµÐºÑ archinfo, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÐ¹ ÐŽÐ»Ñ Ñ
+ÑÐ°ÐœÐµÐœÐžÑ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž ÐŸÐ± Ð°ÑÑ
+ÐžÐ²Ð°Ñ
+.  
+BasPlugout.verbosity:ÐÐŸÐœÑÑÐŸÐ»ÐžÑÑÐµÑ ÐºÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ Ð²ÑÐ²ÐŸÐŽÐ°. 0=ÐœÐµÑ, 3=ÐœÐ°ÐžÐ±ÐŸÐ»ÑÑÐžÐ¹.  
+BasPlugout.xslt_file:Ð¢ÑÐ°ÐœÑÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÑÑ ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð¿ÑÐž Ð¿ÐŸÐŒÐŸÑÐž XSLT Ð² ÑÐºÐ°Ð·Ð°ÐœÐœÐŸÐŒ ÑÐ°Ð¹Ð»Ðµ.  
+
+DSpacePlugout.desc:Ð€ÐŸÑÐŒÐ°Ñ Ð°ÑÑ
+ÐžÐ²Ð° DSpace.  
+
+FedoraMETSPlugout.desc:METS ÑÐŸÑÐŒÐ°Ñ ÐŽÐ»Ñ Ð¿ÑÐžÐŒÐµÐœÐµÐœÐžÑ ÑÐŸÑÐŒÐ°ÑÐ° Fedora.  
+FedoraMETSPlugout.fedora_namespace:ÐÑÐµÑÐžÐºÑ ÐŽÐ»Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÑ Ð€ÐµÐŽÐŸÑÑ ÐŽÐ»Ñ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž (PIDS) ÐœÐ°Ð¿ÑÐžÐŒÐµÑ greenstone:HASH0122efe4a2c58d0  
+
+GreenstoneXMLPlugout.desc:Ð€ÐŸÑÐŒÐ°Ñ XML Ð°ÑÑ
+ÐžÐ²Ð° ÐÑÐžÐœÑÑÐŸÑÐœ  
+
+GreenstoneMETSPlugout.desc:METS ÑÐŸÑÐŒÐ°Ñ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÐ¹ Ð² Ð¿ÑÐŸÑÐžÐ»Ðµ ÐÑÐžÐœÑÑÐŸÑÐœ.  
+
+MARCXMLPlugout.desc:Ð€ÐŸÑÐŒÐ°Ñ MARC XML  
+MARCXMLPlugout.group:ÐÑÐ²ÐµÑÑÐž Ð·Ð°Ð¿ÐžÑÐž marc xml Ð² ÐŸÐŽÐžÐœ ÑÐ°Ð¹Ð».  
+MARCXMLPlugout.mapping_file:ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÑ ÐžÐŒÐµÐœÐŸÐ²Ð°ÐœÐœÑÐ¹ ÑÐ°Ð¹Ð» ÐŸÑÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÐŽÐ»Ñ ÑÑÐ°ÐœÑÑÐŸÑÐŒÐ°ÑÐžÐž.  
+
+METSPlugout.desc:METS-ÑÐŸÑÐŒÐ°Ñ, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÑÑÐžÐ¹ Ð¿ÑÐŸÑÐžÐ»Ñ Greenstone.  
+METSPlugout.xslt_txt:Ð¢ÑÐ°ÐœÑÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÑÑ ÑÐ°Ð¹Ð» ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ doctxt.xml Ð¿ÑÐž Ð¿ÐŸÐŒÐŸÑÐž XSLT Ð² ÑÐºÐ°Ð·Ð°ÐœÐœÐŸÐŒ ÑÐ°Ð¹Ð»Ðµ.  
+METSPlugout.xslt_mets:Ð¢ÑÐ°ÐœÑÑÐŸÑÐŒÐžÑÐŸÐ²Ð°ÑÑ ÑÐ°Ð¹Ð» ÐŒÐµÑÐ°ÐŽÐ°ÐœÐœÑÑ
+ docmets.xml Ð¿ÑÐž Ð¿ÐŸÐŒÐŸÑÐž XSLT Ð² ÑÐºÐ°Ð·Ð°ÐœÐœÐŸÐŒ ÑÐ°Ð¹Ð»Ðµ.  
+
+#
+# Perl module strings
+#
+
+classify.could_not_find_classifier:ÐÐšÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐœÐ°Ð¹ÑÐž ÐºÐ»Ð°ÑÑÐžÑÐžÐºÐ°ÑÐŸÑ \"%s\"
+
+download.could_not_find_download:ÐÐšÐÐÐÐ: ÐœÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ Ð·Ð°Ð³ÑÑÐ·ÐžÑÑ ÐŒÐŸÐŽÑÐ»Ñ \"%s\"  
+
+plugin.could_not_find_plugin:ÐÐšÐÐÐÐ: ÐÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐœÐ°Ð¹ÑÐž Ð¿Ð»Ð°Ð³ÐžÐœ \"%s\"
+
+plugin.including_archive:Ð²ÐºÐ»ÑÑÐµÐœÐžÐµ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÑ 1 Ð°ÑÑ
+ÐžÐ²Ð° ZIP/TAR.
+
+plugin.including_archives:Ð²ÐºÐ»ÑÑÐµÐœÐžÐµ ÑÐŸÐŽÐµÑÐ¶Ð°ÐœÐžÑ  Ð°ÑÑ
+ÐžÐ²ÐŸÐ² %d ZIP/TAR
+
+plugin.kill_file:ÐÐ±ÑÐ°Ð±ÐŸÑÐºÐ°, ÑÐœÐžÑÑÐŸÐ¶ÐµÐœÐœÐ°Ñ ÑÐ°Ð¹Ð»ÐŸÐŒ .kill.
+
+plugin.n_considered:%d ÐŽÐŸÐºÑÐŒÐµÐœÑÑ, Ð¿ÑÐµÐŽÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐœÑÐµ ÐŽÐ»Ñ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž
+
+plugin.n_included:%d Ð±ÑÐ»Ðž ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÐœÑ Ðž Ð²ÐºÐ»ÑÑÐµÐœÑ Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ
+
+plugin.n_rejected:%d Ð±ÑÐ»Ðž ÐŸÑÐºÐ»ÐŸÐœÐµÐœÑ
+
+plugin.n_unrecognised:%d Ð·ÐŽÐµÑÑ ÐœÐµÑÐ°ÑÐ¿ÐŸÐ·ÐœÐ°ÐœÐŸ
+
+plugin.no_plugin_could_process:ÐÐ ÐÐÐ£ÐÐ ÐÐÐÐÐÐÐ: ÐÐžÐºÐ°ÐºÐžÐµ Ð¿Ð»Ð°Ð³ÐžÐœÑ ÐœÐµ ÑÐŒÐŸÐ³Ð»Ðž ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÑÑ %s
+
+plugin.no_plugin_could_recognise:ÐÐÐÐÐÐÐÐ: ÐÐµÑ Ð¿Ð»Ð°Ð³ÐžÐœÐ° ÐºÐŸÑÐŸÑÑÐ¹ ÑÐ°ÑÐ¿ÐŸÐ·ÐœÐ°ÐµÑ %s
+
+plugin.no_plugin_could_process_this_file:ÐœÐžÐºÐ°ÐºÐžÐµ Ð¿Ð»Ð°Ð³ÐžÐœÑ ÐœÐµ ÑÐŒÐŸÐ³Ð»Ðž  ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°ÑÑ ÑÑÐŸÑ ÑÐ°Ð¹Ð»
+
+plugin.no_plugin_could_recognise_this_file:ÐœÐµÑ Ð¿Ð»Ð°Ð³ÐžÐœÐ° ÐºÐŸÑÐŸÑÑÐ¹ ÑÐ°ÑÐ¿ÐŸÐ·ÐœÐ°ÐµÑ ÑÑÐŸÑ ÑÐ°Ð¹Ð»
+
+plugin.one_considered:1 ÐŽÐŸÐºÑÐŒÐµÐœÑ Ð¿ÑÐµÐŽÐœÐ°Ð·ÐœÐ°ÑÐ°Ð»ÑÑ ÐŽÐ»Ñ ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž
+
+plugin.one_included:1 Ð±ÑÐ» ÐŸÐ±ÑÐ°Ð±ÐŸÑÐ°Ðœ Ðž Ð²ÐºÐ»ÑÑÐµÐœ Ð² ÐºÐŸÐ»Ð»ÐµÐºÑÐžÑ
+
+plugin.one_rejected:1 Ð±ÑÐ» ÐŸÑÐºÐ»ÐŸÐœÐµÐœ
+
+plugin.one_unrecognised:1 Ð±ÑÐ» ÐœÐµ ÑÐ°ÑÐ¿ÐŸÐ·ÐœÐ°Ðœ
+
+plugin.see_faillog:Ð¡ÐŒ. %s ÐŽÐ»Ñ ÑÐ¿ÐžÑÐºÐ° ÐœÐµÑÐ°ÑÐ¿ÐŸÐ·ÐœÐ°ÐœÐœÑÑ
+  Ðž/ÐžÐ»Ðž ÐŸÑÐºÐ»ÐŸÐœÐµÐœÐœÑÑ
+ ÐŽÐŸÐºÑÐŒÐµÐœÑÐŸÐ²
+
+PrintUsage.default:ÐÐŸ ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ
+
+PrintUsage.required:Ð¢Ð ÐÐÐ£ÐÐÐ«Ð
+
+plugout.could_not_find_plugout:ÐÐšÐÐÐÐ: ÐœÐµÐ²ÐŸÐ·ÐŒÐŸÐ¶ÐœÐŸ ÐœÐ°Ð¹ÑÐž ÐŒÐŸÐŽÑÐ»Ñ \"%s\"  
Index: /gsdl/stable/perllib/strings_th.properties
===================================================================
--- /gsdl/stable/perllib/strings_th.properties	(revision 20131)
+++ /gsdl/stable/perllib/strings_th.properties	(revision 20131)
@@ -0,0 +1,1307 @@
+#
+# Resource bundle description
+#
+
+Language.code:th  
+Language.name:àž­àž±àžàžàž€àž©  
+
+OutputEncoding.unix:utf-8  
+OutputEncoding.windows:utf-8  
+
+
+#
+# Common output messages and strings
+#
+
+common.cannot_create_file:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžªàž£à¹àž²àžà¹àžà¹àž¡ %s à¹àžà¹  
+
+common.cannot_find_cfg_file:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžàžà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž² %s  
+
+common.cannot_open:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àžàžŽàž %s à¹àžà¹  
+
+common.cannot_open_fail_log:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àžàžŽàžà¹àžà¹àž¡àžàž±àžàžàž¶àžàžàž§àž²àž¡àž¥à¹àž¡à¹àž«àž¥àž§ %s à¹àžà¹  
+
+common.cannot_open_output_file:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àžàžŽàžà¹àžà¹àž¡àžàž¥àž¥àž±àžàžà¹ %s à¹àžà¹  
+
+common.cannot_read:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžàž­à¹àž²àž %s à¹àžà¹  
+
+common.cannot_read_file:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžàž­à¹àž²àžà¹àžà¹àž¡ %s à¹àžà¹  
+
+common.general_options:àžàž±àž§à¹àž¥àž·àž­àžàžàž±à¹àž§à¹àž (àžªàž³àž«àž£àž±àž %s)  
+
+common.must_be_implemented:àžàž°àžà¹àž­àžàžàžŽàžàžàž±à¹àžàžàž±àžàžà¹àžàž±àžà¹àž§à¹à¹àžàžàž¥àž²àžªàž¢à¹àž­àž¢  
+
+common.options:àžàž±àž§à¹àž¥àž·àž­àž  
+
+common.processing:àžàž²àž£àžàž£àž°àž¡àž§àž¥àžàž¥  
+
+common.specific_options:àžàž±àž§à¹àž¥àž·àž­àžà¹àžàžàž²àž°  
+
+common.usage:àž§àžŽàžàžµàžàž²àž£à¹àžà¹àžàž²àž  
+
+common.info:info  
+
+common.invalid_options:àž­àž²àž£à¹àžàžŽàž§à¹àž¡àžàžà¹à¹àž¡à¹àžàž¹àžàžà¹àž­àž: %s  
+
+common.true:à¹àžà¹  
+
+common.false:à¹àž¡à¹à¹àžà¹  
+
+common.deprecated:DEPRECATED  
+#
+# Script option descriptions and output messages
+#
+
+scripts.language:àž àž²àž©àž²àžàžµà¹àžàž°à¹àžªàžàžàž£àž²àž¢àž¥àž°à¹àž­àžµàž¢àžàžàž­àžàžàž±àž§à¹àž¥àž·àž­àž (à¹àžà¹àž 'en_US' àž«àž¡àž²àž¢àžàž¶àž àž àž²àž©àž²àž­àž±àžàžàž€àž©à¹àžàžàž­à¹àž¡àž£àžŽàžàž±àž (American English) àžà¹àž­àžàžàž²àž£àžàž²àž£à¹àžàž¥àž£àž²àž¢àž¥àž°à¹àž­àžµàž¢àžàžàž­àžàžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹àžàž°àžàž£àž²àžàžà¹àžà¹àžà¹àž¡ perllib/strings_language-code.rb  
+
+scripts.xml:àžªàž£à¹àž²àžàžà¹àž­àž¡àž¹àž¥à¹àžàž£àž¹àžà¹àžàž XML à¹àžàž¢à¹àž¡à¹àžà¹àž­àžàž¡àžµàžàž³àž­àžàžŽàžàž²àž¢àžàžµà¹àžªàž¥àž°àžªàž¥àž§àž¢ à¹àžà¹àžàž­à¹àž«à¹àž¡àžµàž£àž²àž¢àž¥àž°à¹àž­àžµàž¢àžàž¡àž²àž  
+
+scripts.listall:à¹àžªàžàžàž£àž²àž¢àžàž²àž£àžàž±à¹àžàž«àž¡àžàžàžµà¹àž£àž¹à¹àžàž±àž  
+
+scripts.describeall:à¹àžªàžàžàžàž±àž§à¹àž¥àž·àž­àžàžªàž³àž«àž£àž±àžàž£àž²àž¢àžàž²àž£àžàž±à¹àžàž«àž¡àžàžàžµà¹àž£àž¹à¹àžàž±àž  
+
+scripts.both_old_options:àžàž³à¹àžàž·àž­àž: àžà¹àž²àž¡àžµàžàž²àž£àž£àž°àžàžž -removeold àžàž£à¹àž­àž¡àžà¹àž§àž¢ -keepold àž«àž£àž·àž­ -incremental à¹àž«à¹àžàž³àž«àžàžàžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžà¹àžà¹àžàžà¹àž² -removeold à¹àžàž·à¹àž­àž«àž²àžàž±àžàžàžžàžàž±àžàžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµ %s àžàž°àžàž¹àžàž¥àžàžàžŽà¹àž  
+
+scripts.no_old_options:àžàž³à¹àžàž·àž­àž: àžà¹àž²à¹àž¡à¹àž¡àžµàžàž²àž£àž£àž°àžàžžàžà¹àž² -removeold -keepold àž«àž£àž·àž­ -incremental à¹àž«à¹àžàž³àž«àžàžàžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžà¹àžà¹àžàžà¹àž² -removeold à¹àžàž·à¹àž­àž«àž²àžàž±àžàžàžžàžàž±àžàžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµ %s àžàž°àžàž¹àžàž¥àžàžàžŽà¹àž  
+
+scripts.gli:àžàž±àž§àžà¹àžàžàžµà¹àžàžµà¹à¹àžà¹àž£àž±àžàžàž²àž£àžàž±à¹àžàžà¹àž²à¹àž¡àž·à¹àž­à¹àž£àžµàž¢àžà¹àžà¹àžªàžàž£àžŽàžàžà¹àžàžµà¹àžàž²àž GLI àžàž¶à¹àžà¹àžàžŽàžà¹àžà¹àžàž²àžà¹àž­àž²àžà¹àžàžžàžàžàžµà¹à¹àžàžàž²àž°à¹àžàž²àžàžàžªàž³àž«àž£àž±àž GLI  
+
+# -- buildcol.pl --
+
+buildcol.archivedir:àžàžµà¹àžàž±àžà¹àžà¹àžàžà¹àž­àž¡àž¹àž¥àžàž²àž§àž£  
+
+buildcol.builddir:àžàžµà¹àžàž±àžà¹àžà¹àžàžàž±àžàžàžµàžàžµà¹àžªàž£à¹àž²àž  
+
+buildcol.cachedir:àž£àž°àžàžàžàž°àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž±à¹àž§àžàž£àž²àž§àžàžµà¹àžàžµà¹àžà¹àž­àžàžàž³àžªàž³à¹àžàž²à¹àžàž¢àž±àžà¹àžà¹àž£àžàžàž­àž£àžµàžàž²àž£àžªàž£à¹àž²àž  
+
+buildcol.cannot_open_cfg_file:àžàž³à¹àžàž·àž­àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àžàžŽàžà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž²à¹àžàž·à¹àž­àžàž£àž±àžàžàž£àžžàž %s à¹àžà¹  
+
+buildcol.collectdir:à¹àžªà¹àžàžàž²àžàžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµ "collect"  
+
+buildcol.copying_back_cached_build:àžàž³àž¥àž±àžàžªàž³à¹àžàž²àžàž¥àž±àžà¹àžàž¢àž±àžàžàž²àž£àžªàž£à¹àž²àžàžàžµà¹à¹àžà¹àžà¹àžàž«àžà¹àž§àž¢àžàž§àž²àž¡àžàž³  
+
+buildcol.create_images:àžàž¢àž²àž¢àž²àž¡àžªàž£à¹àž²àžàž£àž¹àžà¹àž£àžŽà¹àž¡àžà¹àžàžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹ àžàž¶à¹àžàžàž¶à¹àžàž­àž¢àž¹à¹àžàž±àžàž§à¹àž² àžàžžàžà¹àžà¹àžàžŽàžàžàž±à¹àž Gimp àžàž£à¹àž­àž¡àžà¹àž§àž¢à¹àž¡àžàž¹àž¥ perl àžàžµà¹à¹àžàžµà¹àž¢àž§àžà¹àž­àžà¹àžàž·à¹àž­à¹àž«à¹àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžªàžàž£àžŽàžàžà¹àžàž²àž perl à¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§  
+
+buildcol.debug:àžàžŽàž¡àžà¹àžàž¥àž¥àž±àžàžà¹à¹àžàž¢àž±àž STDOUT  
+
+buildcol.desc:àžªàžàž£àžŽàžàžà¹ Perl àžàžµà¹à¹àžà¹àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž£àžµàžàžªà¹àžàžàžàž²àžà¹àž­àžàžªàž²àž£àžàž±àžà¹àžà¹àžàžàž²àž§àž£  
+
+buildcol.faillog:àžàž·à¹àž­à¹àžà¹àž¡àžàž±àžàžàž¶àžàžàž§àž²àž¡àž¥à¹àž¡à¹àž«àž¥àž§ à¹àžà¹àž¡àžàž±àžàžàž¶àžàžàžµà¹àžàž°à¹àžà¹àžàžàž·à¹àž­à¹àžà¹àž¡àžàž­àžà¹àžà¹àž¡à¹àžà¹ àžàžµà¹à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹  
+
+buildcol.incremental_default_builddir:àžàž³à¹àžàž·àž­àž: à¹àžà¹àž£àžàžàž­àž£àžµàžàž²àž£àžªàž£à¹àž²àžàžàž°àž¡àžµàžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžà¹àžà¹àž 'building' àž«àž²àžàžàžžàžàžà¹àž­àžàžàž²àž£à¹àžàžŽà¹àž¡à¹àžàžŽàž¡à¹àžà¹àž²à¹àžàž¢àž±àžà¹àžà¹àž£àžàžàž­àž£àžµàžàž±àžàžàžµ àžàž£àžžàžàž²à¹àžà¹àžàž±àž§à¹àž¥àž·àž­àž "-builddir index" à¹àž«à¹àžàž±àž buildcol.pl.  
+
+buildcol.index:àžàž±àžàžàžµàžàžµà¹àžàž°à¹àžà¹àžªàž£à¹àž²àž (àžàž°àžªàž£à¹àž²àžàžàž±à¹àžàž«àž¡àžà¹àžà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž²àžà¹àž²à¹àž¡à¹àž¡àžµàžàž²àž£àžàž±à¹àžàžà¹àž²à¹àž§à¹)  
+
+buildcol.incremental:à¹àžàžàž²àž°à¹àž­àžàžªàž²àž£àžàž±àžàžàžµàžàžµà¹àž¢àž±àžà¹àž¡à¹à¹àžàž¢àžàž±àžàžàž³àžàž±àžàžàžµàž¡àž²àžà¹àž­àžà¹àžà¹àž²àžàž±à¹àž àž«àž¡àž²àž¢àžàž¶àž -keepold à¹àžàž¢àžàž¶à¹àžàž­àž¢àž¹à¹àžàž±àžàžàž±àž§àžàž³àžàž±àžàžàžµ lucene  
+
+buildcol.keepold:àžàž°à¹àž¡à¹àžàž³àž¥àž²àž¢à¹àžàž·à¹àž­àž«àž²àžàž±àžàžàžžàžàž±àžàžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµàžàž²àž£àžªàž£à¹àž²àž  
+
+buildcol.maxdocs:àžàž³àžàž§àžàžªàž¹àžàžªàžžàžàžàž­àžà¹àž­àžàžªàž²àž£àžàžµà¹àžà¹àž­àžàžàž²àž£àžªàž£à¹àž²àž  
+buildcol.maxnumeric:àžàž³àžàž§àžàž«àž¥àž±àžàžªàž¹àžàžªàžžàžàžàžµà¹ 'àžàž³' àžªàž²àž¡àž²àž£àžàž¡àžµà¹àžà¹à¹àžàžàžàžàž²àžàžžàžàž£àž¡àžàž±àžàžàžµ àžàž±àž§à¹àž¥àžàžàžµà¹àž¡àžµàžàž³àžàž§àžàž«àž¥àž±àžàž¡àž²àžàžàž°àžàž¹àžà¹àžà¹àžàž­àž­àžà¹àžà¹àžàž«àž¥àž²àž¢àžàž³à¹àžàž·à¹àž­àžàž±àžàžàž³àžàž±àžàžàžµ  àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž àžà¹àž²àžà¹àž² maxnumeric àž¡àžµàžà¹àž² 4 à¹àž¥àž "1342663" àžàž°àžàž¹àžà¹àžà¹àžà¹àžà¹àž "1342" à¹àž¥àž° "663"  
+buildcol.mode:àžªà¹àž§àžàžà¹àž²àžà¹ àžàž­àžàžàž£àž°àžàž§àžàžàž²àž£àžªàž£à¹àž²àžàžàžµà¹àžàž°àžàž³à¹àžàžŽàžàžàž²àž£  
+buildcol.mode.all:àžàž³àžàžžàžàž­àž¢à¹àž²àž  
+buildcol.mode.build_index:à¹àžàžµàž¢àžàžàž±àžàžàž³àžàž±àžàžàžµàžà¹àž­àžàž§àž²àž¡  
+buildcol.mode.compress_text:à¹àžàžµàž¢àžàžàžµàžàž­àž±àžàžà¹àž­àžàž§àž²àž¡  
+buildcol.mode.infodb:à¹àžàžµàž¢àžàžªàž£à¹àž²àžàžàž²àžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²  
+
+buildcol.no_default_images:àž£àž°àžàžàžàž°à¹àž¡à¹àžªàž£à¹àž²àžàž£àž¹àžà¹àž£àžŽà¹àž¡àžà¹àž  
+
+buildcol.no_image_script:àžàž³à¹àžàž·àž­àž: à¹àž¡à¹àžàžàžªàžàž£àžŽàžàžà¹àžàžµà¹àžªàž£à¹àž²àžàž£àž¹àž: %s  
+
+buildcol.no_strip_html:à¹àž¡à¹àžàž§àž£à¹àž¢àžà¹àžà¹àž html àž­àž­àžàžàž²àžàžà¹àž­àž¡àž¹àž¥àžàžµà¹àžàž±àžàžàž³àžàž±àžàžàžµà¹àž¥à¹àž§ (à¹àžà¹àžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž mgpp à¹àžà¹àž²àžàž±à¹àž)  
+
+buildcol.no_text:àžàž£àžžàžàž²àž­àž¢à¹àž²àžàž±àžà¹àžà¹àžàžà¹àž­àžàž§àž²àž¡àžàžµà¹àžàž¹àžàžàžµàžàž­àž±àž àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹àž¡àžµàžàž£àž°à¹àž¢àžàžà¹à¹àžàžàž²àž£àž¥àžàžàžàž²àžàžàž­àžàžàž±àžàžàžµàžàžµà¹àžªàž£à¹àž²àžàžàž¶à¹àžàžà¹àž²àžàžžàžàžàž±à¹àžà¹àžàžàž°à¹àžªàžàžà¹àž­àžàžªàž²àž£àžà¹àžàžàžàž±àžà¹àž¡àž·à¹àž­à¹àž£àžµàž¢àžà¹àžà¹àž£àž°àžàž (à¹àžà¹àž àžàžžàžà¹àž¡à¹àžªàž²àž¡àž²àž£àžàžà¹àžàžàž·àžàž£àžžà¹àžàžàž­àžàžà¹àž­àžàž§àž²àž¡àžàžµà¹àžàž¹àžàžàžµàžàž­àž±àžà¹àžà¹)  
+
+buildcol.sections_index_document_metadata:àžàž±àžàžàž³àžàž±àžàžàžµà¹àž¡àžàž²àžàž²àžàž²àž£àž°àžàž±àžà¹àž­àžàžªàž²àž£àžàžµà¹àž£àž°àžàž±àžàžªà¹àž§àž  
+buildcol.sections_index_document_metadata.never:àžàž£àžžàžàž²àž­àž¢à¹àž²àžàž±àžàžàž³àžàž±àžàžàžµà¹àž¡àžàž²àžàž²àžàž²à¹àž­àžàžªàž²àž£à¹àžà¹ àžàžµà¹àž£àž°àžàž±àžàžªà¹àž§àž  
+buildcol.sections_index_document_metadata.always:à¹àžàžŽà¹àž¡à¹àž¡àžàž²àžàž²àžàž²àž£àž°àžàž±àžà¹àž­àžàžªàž²àž£àžàžµà¹àž£àž°àžàžžàžàž±à¹àžàž«àž¡àžà¹àž¡à¹àž§à¹àž²àžàž°àž¡àžµà¹àž¡àžàž²àžàž²àžàž²àž£àž°àžàž±àžàžªà¹àž§àžàžàž­àžàžàž·à¹àž­àžàž±à¹àžàž­àž¢àž¹à¹à¹àž¥à¹àž§  
+buildcol.sections_index_document_metadata.unless_section_metadata_exists:à¹àžàžµàž¢àžà¹àžàžŽà¹àž¡à¹àž¡àžàž²àžàž²àžàž²àž£àž°àžàž±àžà¹àž­àžàžªàž²àž£àžà¹àž²à¹àž¡à¹àž¡àžµà¹àž¡àžàž²àžàž²àžàž²àž£àž°àžàž±àžàžªà¹àž§àžàžàž­àžàžàž·à¹àž­àžàž±à¹àžàž­àž¢àž¹à¹  
+
+buildcol.out:àžàž·à¹àž­à¹àžà¹àž¡àž«àž£àž·àž­àž«àž¡àž²àž¢à¹àž¥àžàž­à¹àž²àžàž­àžŽàžàžàžµà¹àžàž°àžàžŽàž¡àžà¹àžªàžàž²àžàž°àžàž­àžàžàž¥àž¥àž±àžàžà¹àž¥àžà¹àž  
+
+buildcol.params:[àžàž±àž§à¹àž¥àž·àž­àž] àžàž­àž¥à¹àž¥àžàžàž±àž-àžàž·à¹àž­  
+
+buildcol.remove_empty_classifications:àžà¹àž­àžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàž§à¹àž²àž à¹àž¥àž°à¹àž«àžàžàžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àž (àžàž¶à¹àžà¹àž¡à¹àž¡àžµà¹àž­àžàžªàž²àž£à¹àžà¹)  
+
+buildcol.removeold:àžàž°à¹àž­àž²à¹àžàž·à¹àž­àž«àž²à¹àžà¹àž²àžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµàžàž²àž£àžªàž£à¹àž²àžàž­àž­àžà¹àž  
+
+buildcol.unlinked_col_images:àž­àž²àžàžàž°à¹àžàž·à¹àž­àž¡à¹àž¢àžàž£àž¹àžàžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž¡à¹àžàž¹àžàžà¹àž­àž  
+
+buildcol.unknown_mode:à¹àž«àž¡àžàžàžµà¹à¹àž¡à¹àž£àž¹à¹àžàž±àž: %s  
+
+buildcol.updating_archive_cache:àžàž³àž¥àž±àžàžàž£àž±àžàžàž£àžžàžàž«àžà¹àž§àž¢àžàž§àž²àž¡àžàž³à¹àžàžàžàžµà¹à¹àžà¹àžàžàž²àž§àž£  
+
+buildcol.verbosity:àžàž§àžàžàžžàž¡àžàž£àžŽàž¡àž²àžàžàž­àžàžàž¥àž¥àž±àžàžà¹  0=à¹àž¡à¹àž¡àžµ  3=àžàž³àžàž§àžàž¡àž²àž  
+
+
+# -- classinfo.pl --
+
+classinfo.collection:àžàž²àž£à¹àž«à¹àžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àžàžàž°àžàž³à¹àž«à¹ classinfo.pl àžà¹àžàž«àž²à¹àž collect/collection-name/perllib/classify àžà¹àž­àž  àžà¹àž²à¹àž¡à¹àžàžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àž classinfo.pl àžàž°àžà¹àžàž«àž²à¹àžà¹àžà¹àž£àžàžàž­àž£àžµ perllib/classify àžàž±à¹àž§à¹àž  
+
+classinfo.desc:àžàžŽàž¡àžà¹àžà¹àž­àž¡àž¹àž¥à¹àžàžµà¹àž¢àž§àžàž±àžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àž  
+
+classinfo.general_options:àžàž±àž§à¹àž¥àž·àž­àžàžàž±à¹àž§à¹àžàžàž°à¹àžà¹àž£àž±àžàžàž²àž£àžªàž·àžàžàž­àžàž¡àž²àžàž²àžàžàž¥àž²àžªà¹àž¡à¹àžàž­àžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àž  
+
+classinfo.info:info  
+
+classinfo.no_classifier_name:àžà¹àž­àžàžŽàžàžàž¥àž²àž: àžàžžàžàžà¹àž­àžà¹àžªà¹àžàž·à¹àž­àžàž­àžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àž  
+
+classinfo.option_types:àžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàž­àž²àžà¹àžà¹àžàž±àž§à¹àž¥àž·àž­àžàžªàž­àžàžàžàžŽàž  
+
+classinfo.params:[àžàž±àž§à¹àž¥àž·àž­àž] àžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àž-àžàž·à¹àž­  
+
+classinfo.passing_options:àžàž±àž§à¹àž¥àž·àž­àžàž­àž²àžàžàž¹àžàžªà¹àžàžà¹àž²àžà¹àžàž¢àž±àžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžà¹àžà¹ àžà¹àž§àž¢àžàž²àž£àž£àž§àž¡àžàž±àž§à¹àž¥àž·àž­àžà¹àž«àž¥à¹àž²àžàž±à¹àžàž¥àžà¹àžà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž² collect.cfg àžàž­àžàžàžžàž  
+
+classinfo.specific_options:àžàž±àž§à¹àž¥àž·àž­àžà¹àžàžàž²àž°àžàž°àžàž¹àžàžàž³àž«àžàžà¹àž§à¹àž àž²àž¢à¹àžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžà¹àž­àž à¹àž¥àž°àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžà¹àžà¹àžàž±àžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàžàžŽà¹àžšàž©àžàžµà¹à¹àžà¹àž²àžàž±à¹àž  
+
+# -- downloadfrom.pl --
+downloadfrom.cache_dir:àžàžµà¹àžàž±à¹àžàžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµàž«àžà¹àž§àž¢àžàž§àž²àž¡àžàž³à¹àžàž  
+downloadfrom.desc:àžàž²àž§àžà¹à¹àž«àž¥àžà¹àžà¹àž¡àžàž²àžà¹àžàžŽàž£à¹àžà¹àž§àž­àž£à¹àž àž²àž¢àžàž­àž  
+downloadfrom.download_mode:àžàžàžŽàžàžàž­àžà¹àžàžŽàž£à¹àžà¹àž§àž­àž£à¹àžàžµà¹àžàž°àžàž²àž§àžà¹à¹àž«àž¥àž  
+downloadfrom.download_mode.Web:HTTP  
+downloadfrom.download_mode.MediaWiki:à¹àž§à¹àžà¹àžàžà¹ MediaWiki  
+downloadfrom.download_mode.OAI:Open Archives Initiative  
+downloadfrom.download_mode.z3950:à¹àžàžŽàž£à¹àžà¹àž§àž­àž£à¹ z3950  
+downloadfrom.download_mode.SRW:SearchRetrieve Webservice  
+downloadfrom.incorrect_mode:àžàž²àž£àž²àž¡àžŽà¹àžàž­àž£à¹ download_mode à¹àž¡à¹àžàž¹àžàžà¹àž­àž  
+downloadfrom.info:àžàžŽàž¡àžà¹àžà¹àž­àž¡àž¹àž¥à¹àžàžµà¹àž¢àž§àžàž±àžà¹àžàžŽàž£à¹àžà¹àž§àž­àž£à¹à¹àžàžàžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àž  
+downloadfrom.params:[àžàž±àž§à¹àž¥àž·àž­àžàžàž±à¹àž§à¹àž] [àžàž±àž§à¹àž¥àž·àž­àžàžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àžà¹àžàžàž²àž°]  
+
+# -- downloadinfo.pl --
+
+downloadinfo.desc:àžàžŽàž¡àžà¹àžà¹àž­àž¡àž¹àž¥à¹àžàžµà¹àž¢àž§àžàž±àžà¹àž¡àžàž¹àž¥àžàž²àž§àžà¹à¹àž«àž¥àž  
+downloadinfo.collection:àžàž²àž£à¹àž«à¹àžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àžàžàž°àžàž³à¹àž«à¹ downloadinfo.pl àžà¹àžàž«àž²àžà¹àž­àž¡àž¹àž¥à¹àž collect/collection-name/perllib/downloaders àžà¹àž­àž  àžà¹àž²à¹àž¡à¹àžàžà¹àž¡àžàž¹àž¥àžàžµà¹àžàž±à¹àž downloadinfo.pl àžàž°àžà¹àžàž«àž²à¹àžà¹àžà¹àž£àžàžàž­àž£àžµ perllib/downloaders àžàž±à¹àž§à¹àžàžà¹àž­à¹àž  
+downloadinfo.params:[àžàž±àž§à¹àž¥àž·àž­àž] [àžàž²àž§àžà¹à¹àž«àž¥àž-à¹àž¡àžàž¹àž¥]  
+downloadinfo.general_options:àžàž±àž§à¹àž¥àž·àž­àžàžàž±à¹àž§à¹àžàžàž°à¹àžà¹àž£àž±àžàžªàž·àžàžàž­àžàžàž²àžàžàž¥àž²àžªà¹àž¡à¹ (parent classes) àžàž­àžà¹àž¡àžàž¹àž¥àžàž²àž§àžà¹à¹àž«àž¥àž  
+downloadinfo.specific_options:àžàž°àž¡àžµàžàž²àž£àžàž³àž«àžàžàžàž±àž§à¹àž¥àž·àž­àžà¹àžàžàž²àž°à¹àž§à¹à¹àžàžàž±àž§à¹àž¡àžàž¹àž¥àžàž²àž§àžà¹à¹àž«àž¥àžà¹àž­àž à¹àž¥àž°àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžà¹àžà¹àžàž±àžà¹àžàžàž²àž°àžàž±àž§àžàž²àž§àžà¹à¹àž«àž¥àžàžàžµà¹à¹àžà¹àž²àžàž±à¹àž  
+downloadinfo.option_types:à¹àž¡àžàž¹àž¥àžàž²àž§àžà¹à¹àž«àž¥àžàž­àž²àžà¹àžà¹àžàž±àž§à¹àž¥àž·àž­àžàžªàž­àžàžàžàžŽàž  
+
+# -- explode_metadata_database.pl --
+explode.desc:àžàž£àž°àžàž²àž¢àžàž²àžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²  
+
+explode.collection:àžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àž àžàž¥àž±à¹àžàž­àžŽàžàžàž²àžàžàž±àž§àžàž°àž¡àž­àžàž«àž²à¹àžà¹àž¡à¹àžªàž£àžŽàž¡à¹àžà¹àžàž¥à¹àžàž­àž£à¹àžàž­àž¥à¹àž¥àžàžàž±àž  
+ 
+explode.document_field:àž­àžàžà¹àžàž£àž°àžàž­àžà¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àž£àž°àžàžžàžàž·à¹àž­à¹àžà¹àž¡àžàž­àžà¹àž­àžàžªàž²àž£à¹àžàž·à¹àž­àž£àž±àžà¹àž¥àž°àž£àž§àž¡àž¥àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àž  
+
+explode.document_prefix:àžàž³àžàž³àž«àžà¹àž²àžªàž³àž«àž£àž±àžàžàžµà¹àžàž±à¹àžà¹àž­àžàžªàž²àž£ (àžªàž³àž«àž£àž±àžà¹àžà¹àžàž±àžàžàž±àž§à¹àž¥àž·àž­àž document_field)  
+
+explode.document_suffix:àžàž³àž¥àžàžà¹àž²àž¢àžªàž³àž«àž£àž±àžàžàžµà¹àžàž±à¹àžà¹àž­àžàžªàž²àž£ (àžªàž³àž«àž£àž±àžà¹àžà¹àžàž±àžàžàž±àž§à¹àž¥àž·àž­àž document_field)  
+
+explode.encoding:àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàžµà¹àžàž°à¹àžà¹à¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£àž­à¹àž²àžà¹àžà¹àžà¹àž¡àžàž²àžàžà¹àž­àž¡àž¹àž¥  
+explode.metadata_set:àžàžžàžà¹àž¡àžàž²àžàž²àžàž² (à¹àžàž¡àžªà¹àžàž) à¹àžàž·à¹àž­àžªà¹àžàž­àž­àžà¹àž¡àžàž²àžàž²àžàž²àžàž±à¹àžàž«àž¡àžà¹àžà¹àž  
+explode.plugin:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžà¹àžªàž³àž«àž£àž±àžàžàž²àž£àžàž£àž°àžàž²àž¢  
+explode.plugin_options:àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹àžàž°àžªà¹àžàžà¹àž²àžà¹àžàž¢àž±àžàžàž¥àž±à¹àžàž­àžŽàžàžà¹àž­àžàžàž³àžàž²àž£àžàž£àž°àžàž²àž¢à¹àžà¹àž¡ àžàž·à¹àž­àžàž­àžàžàž±àž§à¹àž¥àž·àž­àžàžàž°àžà¹àž­àžàžàž¶à¹àžàžà¹àžàžà¹àž§àž¢ - à¹àžàž¢àž¡àžµàžà¹àž­àžàž§à¹àž²àžàž£àž°àž«àž§à¹àž²àžàžàž·à¹àž­àžàž±àž§à¹àž¥àž·àž­àžà¹àž¥àž°àžà¹àž²àžàž­àžàžàž±àž§à¹àž¥àž·àž­àž  
+explode.params:[àžàž±àž§à¹àž¥àž·àž­àž] àžàž·à¹àž­à¹àžà¹àž¡  
+explode.records_per_folder:àžàž³àžàž§àžàž£àž°à¹àžàžµàž¢àžàžàžµà¹àžàž°à¹àžªà¹àž¥àžà¹àžà¹àžà¹àž¥àž°à¹àžàž¥à¹àžàž­àž£à¹àž¢à¹àž­àž¢  
+
+# -- replace_srcdoc_with_html.pl --
+srcreplace.desc:à¹àžàžàžàžµà¹à¹àž­àžàžªàž²àž£àžà¹àžàžàžàž±àžàžà¹àž§àž¢à¹àžà¹àž¡ HTML àžàžµà¹àžªàž£à¹àž²àžàžàž¶à¹àžàžàžàž°àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹  
+srcreplace.params:[àžàž±àž§à¹àž¥àž·àž­àž] àžàž·à¹àž­à¹àžà¹àž¡  
+srcreplace.plugin:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžà¹à¹àžàžàž²àž£à¹àžàž¥àžà¹àž­àžàžªàž²àž£àžà¹àžàžàžàž±àž  
+
+# -- exportcol.pl --
+
+exportcol.out:àžàž·à¹àž­à¹àžà¹àž¡àž«àž£àž·àž­àž«àž¡àž²àž¢à¹àž¥àžàž­à¹àž²àžàž­àžŽàžàžàžµà¹àžàž°àžàžŽàž¡àžà¹àžªàžàž²àžàž°àžàž¥àž¥àž±àžàžà¹à¹àžàž¢àž±àž  
+exportcol.cddir:àžàž·à¹àž­àžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµàžàž¥àž²àž¢àžàž²àžàžàžµà¹àžàž°àžªà¹àžàž­àž­àžà¹àžàž·à¹àž­àž«àž²àžàžµàžàžµà¹àžàž¢àž±àž  
+exportcol.cdname:àžàž·à¹àž­àžàž­àžàžàžµàžàžµàž£àž­àž¡ -- àžàž°à¹àžà¹àžàžªàžŽà¹àžàžàžµà¹àžàž£àž²àžàžà¹àžà¹àž¡àžàž¹à¹àž£àžŽà¹àž¡àžàž±àžàžàžµàžàžµà¹à¹àžà¹àžàžŽàžàžàž±à¹àžàžàžµàžàžµàž£àž­àž¡  
+exportcol.desc:àžªàžàž£àžŽàžàžà¹ PERL àžàžµà¹à¹àžà¹àžªà¹àžàž­àž­àžàžàž­àž¥à¹àž¥àžàžàž±àžàž­àž¢à¹àž²àžàžà¹àž­àž¢àž«àžàž¶à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžàž¢àž±àžàžàžµàžàžµàž£àž­àž¡àžàž­àžàž§àžŽàžà¹àžàžªà¹  
+exportcol.noinstall:àžªàž£à¹àž²àžàžàžµàžàžµàž£àž­àž¡àžàžµà¹à¹àž¥àžàž£àž²àž£àžµàžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžàžàžµàžàžµàž£àž­àž¡à¹àžà¹à¹àžàž¢àžàž£àž à¹àž¥àž°à¹àž¡à¹àžà¹àž­àžàžàžŽàžàžàž±à¹àžàžªàžŽà¹àžà¹àžàžàžµà¹àžàž­àž¡àžàžŽàž§à¹àžàž­àž£à¹à¹àž¡à¹àžà¹àž²àž¢  
+exportcol.params:"[àžàž±àž§à¹àž¥àž·àž­àž] collection-name1, collection-name2..."  
+exportcol.coll_not_found:àž¥àž°à¹àž§à¹àžàžàž­àž¥à¹àž¥àžàžàž±àž %s àžàžµà¹à¹àž¡à¹àžàž¹àžàžà¹àž­àž: à¹àž¡à¹àžàžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹ %s  
+exportcol.coll_dirs_not_found:àž¥àž°à¹àž§à¹àžàžàž­àž¥à¹àž¥àžàžàž±àž %s àžàžµà¹à¹àž¡à¹àžàž¹àžàžà¹àž­àž: à¹àž¡à¹àžàžàž«àžàž¶à¹àžà¹àžà¹àžà¹àž£àžàžàž­àž£àžµàžà¹àž­à¹àžàžàžµà¹:  
+exportcol.fail:exportcol.pl àž¥à¹àž¡à¹àž«àž¥àž§:  
+exportcol.no_valid_colls:àžàžžàžàž¢àž±àžà¹àž¡à¹à¹àžà¹àž£àž°àžàžžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžàž¹àžàžà¹àž­àžà¹àžàž·à¹àž­àžªà¹àžàž­àž­àž  
+exportcol.couldnt_create_dir:à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžªàž£à¹àž²àžà¹àžà¹àž£àžàžàž­àž£àžµ %s à¹àžà¹  
+exportcol.couldnt_create_file:à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžªàž£à¹àž²àž %s à¹àžà¹  
+exportcol.instructions:à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àžªàž£à¹àž²àžàžàžµàžàžµàž£àž­àž¡àžàž­àžàž§àžŽàžà¹àžàžªà¹à¹àžàžàžàžŽàžàžàž±à¹àžà¹àžà¹à¹àž­àž à¹àž«à¹à¹àžàžµàž¢àžà¹àžàž·à¹àž­àž«àž²àžàž­àžà¹àžàž¥à¹àžàž­àž£à¹àžàžµà¹àž¥àžà¹àžà¹àžàžàžµàžàžµàž£àž­àž¡  
+exportcol.non_exist_files:à¹àž¡à¹àž¡àžµà¹àžà¹àž¡àžàžµà¹àžàž³à¹àžà¹àžàžà¹àž­à¹àžàžàžµà¹àž­àž¢à¹àž²àžàžà¹àž­àž¢àž«àžàž¶à¹àžà¹àžà¹àž¡ à¹àž¥àž°à¹àžà¹àž£àžàžàž­àž£àžµàž­àž¢à¹àž²àžàžà¹àž­àž¢àž«àžàž¶à¹àžà¹àžà¹àž£àžàžàž­àž£àžµàž­àž¢àž¹à¹:  
+exportcol.success:exportcol.pl àžàž³àžàž²àžà¹àžªàž£à¹àžà¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§:  
+exportcol.output_dir:àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžªà¹àžàž­àž­àž (%s) àž­àž¢àž¹à¹à¹àž %s  
+exportcol.export_coll_not_installed:àžàžžàžàž¢àž±àžà¹àž¡à¹à¹àžà¹àžàžŽàžàžàž±à¹àžàžàž²àž£à¹àžà¹àžàž²àžàžàž²àž£àžªà¹àžàž­àž­àžà¹àžàž¢àž±àžàžàžµàžàžµàž£àž­àž¡  
+
+# -- import.pl --
+
+import.archivedir:àžàžµà¹àžàž±àžà¹àžà¹àžà¹àžàž·à¹àž­àž«àž²àžàžµà¹à¹àžàž¥àžà¹àž¥à¹àž§  
+
+import.manifest:à¹àžà¹àž¡ XML àžàžµà¹à¹àž«à¹àž£àž²àž¢àž¥àž°à¹àž­àžµàž¢àžàž§à¹àž²à¹àžà¹àž¡à¹àžàžà¹àž²àžàžàžµà¹àžàž°àžàž¹àžàžàž³à¹àžà¹àž²  à¹àž«à¹à¹àžà¹à¹àžàžàžàž²àž£àžàž±àžà¹àž£àžµàž¢àžà¹àžàž¥à¹àžàž­àž£à¹àžàž³à¹àžà¹àž²àžàž²àžàž¡àž²àžà¹àžàžà¹àž­àž¢à¹àžàžàž§àžàžà¹àž³àžàž¶à¹àžàžàžàžàžŽà¹àž¥à¹àž§àžàž°à¹àžà¹àžªàž³àž«àž£àž±àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžàžà¹àžàžŽà¹àž¡  
+
+import.cannot_open_stats_file:àžàž³à¹àžàž·àž­àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àžàžŽàžà¹àžà¹àž¡àžªàžàžŽàžàžŽ %s à¹àžà¹  
+
+import.cannot_open_fail_log:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àžàžŽàžà¹àžà¹àž¡àžàž±àžàžàž¶àžàžàž§àž²àž¡àž¥à¹àž¡à¹àž«àž¥àž§ %s à¹àžà¹  
+
+import.cannot_sort:àžàž³à¹àžàž·àž­àž: import.pl à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžàž¥àž³àžàž±àžà¹àž­àžàžªàž²àž£à¹àžà¹à¹àž¡àž·à¹àž­ groupsize > 1   àžàž±àž§à¹àž¥àž·àž­àž sortmeta àžàž°àžàž¹àžàž¥àž°à¹àž§à¹àž  
+
+import.collectdir:à¹àžªà¹àžàžàž²àžàžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµ "collect"  
+
+import.complete:àžàž²àž£àžàž³à¹àžà¹àž²à¹àžªàž£à¹àžàžªàž¡àžàž¹àž£àžà¹  
+
+import.debug:àžàžŽàž¡àžà¹àžà¹àž­àžàž§àž²àž¡àžàžµà¹àžàž³à¹àžà¹àž²à¹àžàž¢àž±àž STDOUT (àžªàž³àž«àž£àž±àžàžàž²àž£àžàž³à¹àžà¹àž² GreenstoneXML)  
+
+import.desc:àžªàžàž£àžŽàžàžà¹ Perl àžàžµà¹à¹àžà¹àžàž³à¹àžà¹àž²à¹àžà¹àž¡à¹àž«à¹àž­àž¢àž¹à¹à¹àžàž£àž¹àžà¹àžàž (GreenstoneXML àž«àž£àž·àž­ GreenstoneMETS) àžàžµà¹àžàž£à¹àž­àž¡àžªàž³àž«àž£àž±àžàžàž²àž£àžªàž£à¹àž²àž  
+
+import.faillog:àžàž·à¹àž­à¹àžà¹àž¡àžàž±àžàžàž¶àžàžàžµà¹àž¥à¹àž¡à¹àž«àž¥àž§ à¹àžà¹àž¡àžàž±àžàžàž¶àžàžàžµà¹àžàž°àžàž±àžà¹àžà¹àžàžàž·à¹àž­à¹àžà¹àž¡àžàž­àžà¹àžà¹àž¡à¹àžà¹ àžàžµà¹à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹  
+
+import.groupsize:àžàž³àžàž§àžàžàž­àžà¹àž­àžàžªàž²àž£àžàž³à¹àžà¹àž²àžàžµà¹àžàž±àžàžàž¥àžžà¹àž¡àž¥àžà¹àžà¹àžà¹àž¡ XMLà¹àžà¹àž¡à¹àžàžµàž¢àž§  
+
+import.gzip:à¹àžà¹à¹àžàž£à¹àžàž£àž¡ gzip à¹àžàž·à¹àž­àžàžµàžàž­àž±àžà¹àž­àžàžªàž²àž£ XML àžàžµà¹à¹àžà¹àžàžàž¥àž¥àž±àžàžà¹ (àž­àž¢à¹àž²àž¥àž·àž¡àž£àž§àž¡ ZIPPlugin àž¥àžà¹àžàž£àž²àž¢àžàž²àž£àžàž¥àž±à¹àžàž­àžŽàžàžàž­àžàžàžžàžà¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£àžªàž£à¹àž²àžàžàž²àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž¹àžàžàžµàžàž­àž±àž)  
+
+import.importdir:àžàžµà¹àžàž±àžà¹àžà¹àžà¹àž­àžàžªàž²àž£àžà¹àžàžàžàž±àžàž­àž¢àž¹à¹  
+
+import.incremental:àžàž³à¹àžà¹àž²à¹àžàžàž²àž°à¹àž­àžàžªàž²àž£àžàžµà¹à¹àž«àž¡à¹ (àžàž¹àžàž²àžàžàž²àž£àž¥àžàžàž±àžàžàž¶àžà¹àž§àž¥àž²) àžàž§à¹àž²à¹àžà¹àž¡àžàžµà¹à¹àžà¹àžàžàž²àž§àž£à¹àžàžàž±àžàžàžžàžàž±àž àž«àž¡àž²àž¢àžàž¶àž -keepold  
+
+import.keepold:àžàž°à¹àž¡à¹àžàž³àž¥àž²àž¢à¹àžàž·à¹àž­àž«àž²àžàž±àžàžàžžàžàž±àžàžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµàžàžµà¹à¹àžà¹àžàžàž²àž§àž£  
+
+import.maxdocs:àžàž³àžàž§àžàžªàž¹àžàžªàžžàžàžàž­àžà¹àž­àžàžªàž²àž£àžàžµà¹àžªàž²àž¡àž²àž£àžàžàž³à¹àžà¹àž²à¹àžà¹  
+
+import.no_import_dir:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžàžà¹àžà¹àž£àžàžàž­àž£àžµàžàž³à¹àžà¹àž² (%s)  
+
+import.no_plugins_loaded:àžà¹àž­àžàžŽàžàžàž¥àž²àž: àž¢àž±àžà¹àž¡à¹à¹àžà¹à¹àž«àž¥àžàžàž¥àž±à¹àžàž­àžŽàž  
+
+import.OIDtype:àž§àžŽàžàžµàžàž²àž£àžàžµà¹àžàž°à¹àžà¹à¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£àžªàž£à¹àž²àžàžàž±àž§àž£àž°àžàžžàžàžµà¹à¹àž¡à¹àžà¹àž³àžàž±àžàžªàž³àž«àž£àž±àžà¹àžà¹àž¥àž°à¹àž­àžàžªàž²àž£  
+import.OIDtype.hash:àžàž³à¹àžàž·à¹àž­àž«àž²àžàž­àžà¹àžà¹àž¡àžàž¥àž±àžàž¡àž²àžàž³à¹àž«àž¡à¹ àžàž±àž§àž£àž°àžàžžà¹àž­àžàžªàž²àž£àžàž°à¹àžà¹àžàžàž±àž§à¹àžàžµàž¢àž§àžàž±àžàžàžžàžàžàž£àž±à¹àžà¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£àžàž³à¹àžà¹àž²àžàž­àž¥à¹àž¥àžàžàž±àž  
+
+import.OIDtype.incremental:à¹àžà¹àžàž²àž£àžàž±àžà¹àž­àžàžªàž²àž£àž­àž¢à¹àž²àžàžà¹àž²àž¢  àžàž¶à¹àžàžàž°à¹àž£à¹àž§àžàž§à¹àž² "à¹àž®àž" àž¡àž²àž à¹àžà¹àžàž°à¹àž¡à¹àžàž³àž«àžàžàžàž±àž§àž£àž°àžàžžàžàž±àž§à¹àžàžµàž¢àž§àžàž±àžà¹àž«à¹àžàž±àžà¹àžàž·à¹àž­àž«àž²à¹àž­àžàžªàž²àž£à¹àžàžµàž¢àž§àžàž±àž à¹àž¥àž°à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àžàžŽà¹àž¡à¹àž­àžàžªàž²àž£àž¥àžà¹àžàžàžµà¹à¹àžà¹àžàžàž²àž§àž£àžàžµà¹àž¡àžµàž­àž¢àž¹à¹à¹àžà¹  
+
+import.OIDtype.assigned:à¹àž«à¹à¹àžà¹àžà¹àž²à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àžàž³àž«àžàžà¹àžàž¢àžàž±àž§à¹àž¥àž·àž­àž OIDmetadata (àžàž³àž«àžà¹àž²àžà¹àž§àž¢ 'D')  àžà¹àž²à¹àž¡à¹àž¡àžµàžàž²àž£àž£àž°àžàžžà¹àž§à¹ àž£àž°àžàžàž­àž²àžàžàž°à¹àžà¹à¹àž®àž (hash) à¹àžàžàžªàž³àž«àž£àž±àžà¹àž­àžàžªàž²àž£àžàž²àžàžàž£àž°à¹àž àž àžàž±àž§àž£àž°àžàžžà¹àž«àž¥à¹àž²àžàžµà¹à¹àž¡à¹àžàž§àž£àž¡àžµàžà¹àž²àžà¹àž³àžàž±àž  
+
+import.OIDtype.dirname:à¹àžà¹àžàž·à¹àž­à¹àžà¹àž£àžàžàž­àž£àžµà¹àž¡à¹ (àžàž³àž«àžà¹àž²àžà¹àž§àž¢ 'J') àžàž¶à¹àžàžàž§àž£àžàž°àž¡àžµàž«àžàž¶à¹àžà¹àž­àžàžªàž²àž£àžà¹àž­à¹àžà¹àž£àžàžàž­àž£àžµà¹àžà¹àž²àžàž±à¹àž à¹àž¥àž°àžàž·à¹àž­à¹àžà¹àž£àžàžàž­àž£àžµà¹àž¡à¹àžàž§àž£àžàž°àžà¹àž³àžàž±àž  à¹àžà¹àž import/b13as/h15ef/page.html àžàž°à¹àžà¹àžàž±àž§àž£àž°àžàžžà¹àžà¹àž Jh15ef  
+
+import.OIDmetadata:àž£àž°àžàžžàž­àžàžà¹àžàž£àž°àžàž­àžà¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àžàž±àžà¹àžà¹àžàžàž±àž§àž£àž°àžàžžàžàžµà¹à¹àž¡à¹àžà¹àž³àžàž±àžàžàž­àžà¹àž­àžàžªàž²àž£ àžªàž³àž«àž£àž±àžà¹àžà¹àž£à¹àž§àž¡àžàž±àž -OIDtype=assigned  
+
+import.saveas:àž£àž¹àžà¹àžàžàž­àž·à¹àžàžàžµà¹àžà¹àž­àžàžàž²àž£àžàž±àžàžàž¶àžà¹àžà¹àž¡àžàž±àžà¹àžà¹àžàžàž²àž§àž£  
+
+import.out:àžàž·à¹àž­à¹àžà¹àž¡àž«àž£àž·àž­àž«àž¡àž²àž¢à¹àž¥àžàž­à¹àž²àžàž­àžŽàžàžàžµà¹àžàž°àžàžŽàž¡àžà¹àžªàžàž²àžàž°àžàž¥àž¥àž±àžàžà¹àž¥àžà¹àž  
+
+import.params:[àžàž±àž§à¹àž¥àž·àž­àž] àžàž­àž¥à¹àž¥àžàžàž±àž-àžàž·à¹àž­  
+
+import.removeold:àžàž°à¹àž­àž²à¹àžàž·à¹àž­àž«àž²à¹àžà¹àž²àžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµàžàžµà¹à¹àžà¹àžàžàž²àž§àž£àž­àž­àž  
+
+import.removing_archives:àžàž²àž£à¹àž­àž²à¹àžàž·à¹àž­àž«àž²àžàž±àžàžàžžàžàž±àžàžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµàžàžµà¹à¹àžà¹àžàžàž²àž§àž£àž­àž­àž...  
+
+import.removing_tmpdir:àžàž²àž£à¹àž­àž²à¹àžàž·à¹àž­àž«àž²à¹àžà¹àžà¹àž£àžàžàž­àž£àžµ "tmp" àžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àžàž­àž­àž...  
+
+import.reversesort:à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž²àžàž¡àž²àžà¹àžàžà¹àž­àž¢ à¹àžà¹àžàž±àžàžàž±àž§à¹àž¥àž·àž­àž -sortmeta  
+
+import.site:à¹àžàžà¹àžªàž³àž«àž£àž±àžàžà¹àžàž«àž²à¹àžà¹àž£àžàžàž­àž£àžµ "collect" (àžªàž³àž«àž£àž±àžàžàž²àž£àžàžŽàžàžàž±à¹àžà¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàž 3)  
+
+import.sortmeta:à¹àž£àžµàž¢àžàž¥àž³àžàž±àžà¹àž­àžàžªàž²àž£àžàž²àž¡àžàž±àž§àž­àž±àžàž©àž£àžà¹àž§àž¢à¹àž¡àžàž²àžàž²àžàž²àžªàž³àž«àž£àž±àžàžàž²àž£àžªàž£à¹àž²àž àžàž¥àž¥àž±àžàžà¹àžàž²àž£àžà¹àžàž«àž²àžªàž³àž«àž£àž±àžàžàž²àž£àžªàž­àžàžàž²àž¡à¹àžàžàžàž£àž£àžàž°àžàž°à¹àžªàžàžàžàž¥à¹àžàž¥àž³àžàž±àžàžàžµà¹ àžàžžàžàž¥àž±àžàž©àžàž°àžàžµà¹àžàž°àžàž¹àžàžàžŽàžà¹àžà¹àžàž²àžàžà¹àž² groupsize > 1  àž«àž£àž·àž­àž­àž²àžàžàž°à¹àžà¹àž£àž²àž¢àžàž²àž£àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àžà¹àžàž·à¹àž­à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžà¹àž§àž¢àžà¹àž²à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àž¡àž²àžàžàž§à¹àž²àž«àžàž¶à¹àžàžà¹àž²àžà¹à¹àžà¹  
+
+import.statsfile:àžàž·à¹àž­à¹àžà¹àž¡àž«àž£àž·àž­àž«àž¡àž²àž¢à¹àž¥àžàž­à¹àž²àžàž­àžŽàžàžàžµà¹àžàž°àžàžŽàž¡àžà¹àžªàžàžŽàžàžŽàžàž³à¹àžà¹àž²à¹àžàž¢àž±àž  
+
+import.stats_backup:àžàž°àžàžŽàž¡àžà¹àžªàžàžŽàžàžŽà¹àžàž¢àž±àž STDERR à¹àžàž  
+
+import.verbosity:àžàž§àžàžàžžàž¡àžàž£àžŽàž¡àž²àžàžàž¥àž¥àž±àžàžà¹  0=à¹àž¡à¹àž¡àžµ  3=àžàž³àžàž§àžàž¡àž²àž  
+
+# -- schedule.pl --
+schedule.deleted:àžàž²àž£àž¥àžàžà¹àž²àžàž³àžªàž±à¹àžàžàžàžŽàžàž±àžàžŽàžàž²àž£àžàžµà¹à¹àžà¹àžàž³àž«àžàžà¹àž§àž¥àž²à¹àž§à¹à¹àž¥à¹àž§àžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž  
+schedule.scheduled:àžªàžàž£àžŽàžàžà¹àžàž³àžªàž±à¹àžàžàžàžŽàžàž±àžàžŽàžàž²àž£àžàžµà¹àžªàž£à¹àž²àžàžàž¶à¹àžàžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž  
+schedule.cron:àžàž²àž£àžàž±à¹àžàžà¹àž²àžàž³àžªàž±à¹àžàžàžàžŽàžàž±àžàžŽàžàž²àž£àžàžµà¹à¹àžà¹àžàž³àž«àžàžà¹àž§àž¥àž²à¹àž§à¹à¹àž¥à¹àž§àžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž  
+schedule.params:[àžàž±àž§à¹àž¥àž·àž­àž]  
+schedule.error.email:à¹àžàžàž²àž£àž£àž°àžàžž -email àžàžžàžàžà¹àž­àžàž£àž°àžàžž -smtp -toaddr à¹àž¥àž° -fromaddr àžà¹àž§àž¢  
+schedule.error.importbuild:àžàžžàžàžà¹àž­àžàž£àž°àžàžž -import à¹àž¥àž° -build  
+schedule.error.colname:àžàžžàžàžà¹àž­àžàž£àž°àžàžžàžàž­àž¥à¹àž¥àžàžàž±àžàžà¹àž§àž¢ -colname  
+schedule.gli:à¹àž£àžµàž¢àžàžàž³àžàž²àžàžàž²àž GLI  
+schedule.frequency:àžàž§àž²àž¡àžàžµà¹à¹àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹à¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽ  
+schedule.frequency.hourly:àžªàž£à¹àž²àžà¹àž«àž¡à¹àžàžžàžàžàž±à¹àž§à¹àž¡àž  
+schedule.frequency.daily:àžªàž£à¹àž²àžà¹àž«àž¡à¹àžàžžàžàž§àž±àž  
+schedule.frequency.weekly:àžªàž£à¹àž²àžà¹àž«àž¡à¹àžàžžàžàžªàž±àžàžàž²àž«à¹  
+schedule.action:àž§àžŽàžàžµàžàž²àž£àžàž±à¹àžàžà¹àž²àžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹à¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽ  
+schedule.action.add:àžàž³àž«àžàžà¹àž§àž¥àž²àžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹à¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽ  
+schedule.action.update:àžàž£àž±àžàžàž£àžžàžàžàž²àž£àžàž³àž«àžàžà¹àž§àž¥àž²àžàžµà¹àž¡àžµàž­àž¢àž¹à¹  
+schedule.action.delete:àž¥àžàžàž²àž£àžàž³àž«àžàžà¹àž§àž¥àž²àžàžµà¹àž¡àžµàž­àž¢àž¹à¹  
+schedule.email:àžªà¹àžàž­àžµà¹àž¡àž¥à¹àžà¹àžà¹àžàž·àž­àž  
+schedule.schedule:à¹àž¥àž·àž­àžà¹àžàž·à¹àž­àžàž±à¹àžàžà¹àž²àžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹à¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽàžà¹àž§àž¢àžàž²àž£àžàž³àž«àžàžà¹àž§àž¥àž²  
+schedule.colname:àžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àžàžžàžàžà¹àž­àžàžàž²àž£àžàž±à¹àžàžà¹àž²àžàž²àž£àžàž³àž«àžàžà¹àž§àž¥àž²  
+schedule.import:àžàž³àžªàž±à¹àžàžàž³à¹àžà¹àž²àžàžµà¹àžà¹àž­àžàžàž²àž£àžàž³àž«àžàžà¹àž§àž¥àž²  
+schedule.build:àžàž³àžªàž±à¹àž buildcol àžàžµà¹àžà¹àž­àžàžàž²àž£àžàž³àž«àžàžà¹àž§àž¥àž²  
+schedule.toaddr:àžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥àžàž¥àž²àž¢àžàž²àžàžàžµà¹àžà¹àž­àžàžàž²àž£àžªà¹àžàžàž²àž£à¹àžà¹àžà¹àžàž·àž­àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž²àž¡àžàž³àž«àžàžà¹àž§àž¥àž²  
+schedule.toaddr.default:àž£àž°àžàžžàž­àžµà¹àž¡àž¥àžàž­àžàžàž¹à¹à¹àžà¹à¹àž à¹àžà¹àž¡->àžàž³àž«àžàžàž¥àž±àžàž©àžàž°  
+schedule.fromaddr:àžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥àžàž­àžàžàž¹à¹àžªà¹àž  
+schedule.fromaddr.default:àž£àž°àžàžžàžàž¹à¹àžàž¹à¹àž¥àž£àž°àžàžà¹àžà¹àžà¹àž¡ main.cfg  
+schedule.smtp:à¹àž¡àž¥à¹àžàžŽàž£à¹àžà¹àž§àž­àž£à¹àžàžµà¹à¹àžàž£à¹àžàž£àž¡ 'sendmail' àžà¹àž­àžàžàžŽàžàžà¹àž­à¹àžàž·à¹àž­àžªà¹àžàž­àžµà¹àž¡àž¥  
+schedule.smtp.default:àž£àž°àžàžž 'MailServer' à¹àž main.cfg  
+schedule.out:àžàž·à¹àž­à¹àžà¹àž¡àž«àž£àž·àž­àžàž±àž§àžà¹àžàžàžµà¹àžàžµà¹àžà¹àž­àžàžàž²àž£à¹àž«à¹àžàžŽàž¡àžà¹àžªàžàž²àžàž°àžàž¥àž¥àž±àžàžà¹  
+# -- export.pl --
+
+export.exportdir:àžàžµà¹àžàž±àžà¹àžà¹àžàžà¹àž­àž¡àž¹àž¥àžàžµà¹àžªà¹àžàž­àž­àž  
+
+export.cannot_open_stats_file:àžàž³à¹àžàž·àž­àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àžàžŽàžà¹àžà¹àž¡àžªàžàžŽàžàžŽ %s à¹àžà¹  
+
+export.cannot_open_fail_log:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àžàžŽàžà¹àžà¹àž¡àžàž±àžàžàž¶àžàžàž§àž²àž¡àž¥à¹àž¡à¹àž«àž¥àž§ %s à¹àžà¹  
+
+export.cannot_sort:àžàž³à¹àžàž·àž­àž: export.pl à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžàž¥àž³àžàž±àžà¹àž­àžàžªàž²àž£à¹àžà¹à¹àž¡àž·à¹àž­ groupsize) > 1  àžàž±àž§à¹àž¥àž·àž­àž sortmeta àžàž°àžàž¹àžàž¥àž°à¹àž§à¹àž  
+
+export.collectdir:à¹àžªà¹àžàžàž²àžàžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµ "collect"  
+
+export.complete:àžàž²àž£àžªà¹àžàž­àž­àžà¹àžªàž£à¹àžàžªàž¡àžàž¹àž£àžà¹  
+
+export.debug:àžàžŽàž¡àžà¹àžà¹àž­àžàž§àž²àž¡àžàžµà¹àžªà¹àžàž­àž­àžà¹àžàž¢àž±àž STDOUT (àžªàž³àž«àž£àž±àžàžªà¹àžàž­àž­àž GreenstoneXML)  
+
+export.desc:àžªàžàž£àžŽàžàžà¹ PERL àžàžµà¹à¹àžà¹àžªà¹àžàž­àž­àžà¹àžà¹àž¡à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàžàž£àžµàžàžªà¹àžàžà¹àžà¹àžà¹àžàž£àž¹àžà¹àžàžàž­àž·à¹àž  
+
+export.faillog:àžàž·à¹àž­à¹àžà¹àž¡àžàž±àžàžàž¶àžàžàž§àž²àž¡àž¥à¹àž¡à¹àž«àž¥àž§ à¹àžà¹àž¡àžàž±àžàžàž¶àžàžàžµà¹àžàž°à¹àžà¹àžàžàž·à¹àž­à¹àžà¹àž¡àžàž­àžà¹àžà¹àž¡à¹àžà¹ àžàžµà¹à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹ (àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àž: collectdir/collname/etc/fail.log)  
+
+export.groupsize:àžàž³àžàž§àžàžàž­àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž°àžàž±àžàžàž¥àžžà¹àž¡àž¥àžà¹àžà¹àžà¹àž¡ XML à¹àžà¹àž¡à¹àžàžµàž¢àž§  
+
+export.gzip:à¹àžà¹à¹àžàž£à¹àžàž£àž¡ gzip à¹àžàž·à¹àž­àžàžµàžàž­àž±àžà¹àž­àžàžªàž²àž£ XML àžàžµà¹à¹àžà¹àžàžàž¥àž¥àž±àžàžà¹ (àž­àž¢à¹àž²àž¥àž·àž¡àž£àž§àž¡ ZIPPlugin àž¥àžà¹àžàž£àž²àž¢àžàž²àž£àžàž¥àž±à¹àžàž­àžŽàžàžàž­àžàžàžžàžà¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£àžªàž£à¹àž²àžàžàž²àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž¹àžàžàžµàžàž­àž±àž)  
+
+export.importdir:àžàžµà¹à¹àžà¹àžà¹àž­àžàžªàž²àž£àžà¹àžàžàžàž±àž  
+
+export.keepold:àžàž°à¹àž¡à¹àžàž³àž¥àž²àž¢à¹àžàž·à¹àž­àž«àž²àžàž±àžàžàžžàžàž±àžàžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµàžªà¹àžàž­àž­àž  
+
+export.maxdocs:àžàž³àžàž§àžàžªàž¹àžàžªàžžàžàžàž­àžà¹àž­àžàžªàž²àž£àžàžµà¹àžªàž²àž¡àž²àž£àžàžªà¹àžàž­àž­àžà¹àžà¹  
+
+export.listall:à¹àžªàžàžàž£àž²àž¢àžàž²àž£àž£àž¹àžà¹àžàž àžàž±àžàžàž¶àžà¹àžà¹àž àžàž±à¹àžàž«àž¡àž  
+
+export.saveas:àž£àž¹àžà¹àžàžàžàžµà¹àžàž°àžªà¹àžàž­àž­àžà¹àž­àžàžªàž²àž£  
+
+export.saveas.DSpace:àž£àž¹àžà¹àžàžàžàžµà¹à¹àžà¹àžàžàž²àž§àž£àžàž­àž Dspace  
+
+export.saveas.GreenstoneMETS:àž£àž¹àžà¹àžàž METS àžàžµà¹à¹àžà¹à¹àžàž£à¹àžàž¥à¹ Greenstone  
+export.saveas.FedoraMETS:àž£àž¹àžà¹àžàž METS àžàžµà¹à¹àžà¹à¹àžàž£à¹àžàž¥à¹ Fedora  
+
+export.saveas.GreenstoneXML:àž£àž¹àžà¹àžàžàžàž²àž£àžàž±àžà¹àžà¹àžà¹àžà¹àž¡ XML à¹àžàžàžàž²àž§àž£àžàž­àžà¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàž  
+
+export.saveas.MARCXML:àž£àž¹àžà¹àžàž MARC XML (MARC21 àž£àžžà¹àžàžàžµà¹à¹àžà¹àž XML)  
+
+export.out:àžàž·à¹àž­à¹àžà¹àž¡àž«àž£àž·àž­àž«àž¡àž²àž¢à¹àž¥àžàž­à¹àž²àžàž­àžŽàžà¹àžàž·à¹àž­àžàžŽàž¡àžà¹àžªàžàž²àžàž°àžàž¥àž¥àž±àžàžà¹à¹àžàž¢àž±àž  
+
+export.params:[àžàž±àž§à¹àž¥àž·àž­àž] collection-name  
+
+export.removeold:àžàž°à¹àž­àž²à¹àžàž·à¹àž­àž«àž²à¹àžà¹àž²àžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµàžªà¹àžàž­àž­àžàž­àž­àž  
+
+export.removing_export:àžàž²àž£à¹àž­àž²à¹àžàž·à¹àž­àž«àž²àžàž±àžàžàžžàžàž±àžàžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµàžªà¹àžàž­àž­àžàž­àž­àžâŠ  
+
+export.sortmeta:à¹àž£àžµàž¢àžàž¥àž³àžàž±àžà¹àž­àžàžªàž²àž£àžàž²àž¡àžàž±àž§àž­àž±àžàž©àž£àžà¹àž§àž¢à¹àž¡àžàž²àžàž²àžàž²àžªàž³àž«àž£àž±àžàžàž²àž£àžªàž£à¹àž²àž àžàž²àž£àžàž³à¹àžàžŽàžàžàž²àž£àžàžµà¹àžàž°àžàž¹àžàžàžŽàžà¹àžà¹àžàž²àžàžà¹àž² groupsize > 1  
+
+export.statsfile:àžàž·à¹àž­à¹àžà¹àž¡àž«àž£àž·àž­àž«àž¡àž²àž¢à¹àž¥àžàž­à¹àž²àžàž­àžŽàžàžàžµà¹àžàž°àžàžŽàž¡àžà¹àžªàžàžŽàžàžŽàžàž²àž£àžªà¹àžàž­àž­àžà¹àž  
+
+export.stats_backup:àžàž°àžàžŽàž¡àžà¹àžªàžàžŽàžàžŽà¹àžàž¢àž±àž STDERR à¹àžàž  
+
+export.verbosity:àžàž§àžàžàžžàž¡àžàž£àžŽàž¡àž²àžàžàž­àžàžàž¥àž¥àž±àžàžà¹  0=à¹àž¡à¹àž¡àžµ  3=àžàž³àžàž§àžàž¡àž²àž  
+
+
+
+# -- mkcol.pl --
+
+mkcol.about:àžà¹àž­àžàž§àž²àž¡àž£àž²àž¢àž¥àž°à¹àž­àžµàž¢àžà¹àžàžµà¹àž¢àž§àžàž±àžàžàž­àž¥à¹àž¥àžàžàž±àž  
+
+mkcol.bad_name_cvs:àžà¹àž­àžàžŽàžàžàž¥àž²àž: àžàžžàžà¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàž±à¹àžàžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àžàž§à¹àž² 'CVS' à¹àžà¹ à¹àžàž·à¹àž­àžàžàž²àžàž­àž²àžàžàž°à¹àžàžàž±àžà¹àž¢à¹àžàžàž±àžà¹àžà¹àž£àžàžàž­àž£àžµàžàžµà¹àžªàž£à¹àž²àžà¹àžàž¢àž£àž°àžàžàžàž±àžàžàž²àž£àž£àžžà¹àž CVS  
+
+mkcol.bad_name_svn:àžà¹àž­àžàžŽàžàžàž¥àž²àž: àžàžžàžà¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàž±à¹àžàžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àžàž§à¹àž² .svn à¹àžà¹ à¹àžàž·à¹àž­àžàžàž²àžàž­àž²àžà¹àžàžŽàžàžàž§àž²àž¡àžàž±àžà¹àž¢à¹àžàžàž±àžà¹àžà¹àž£àžàžàž­àž£àžµàžàžµà¹àžªàž£à¹àž²àžà¹àžàž¢àž£àž°àžàžàžàž±àžàžàž²àž£àž£àžžà¹àž SVN  
+
+mkcol.bad_name_modelcol:àžà¹àž­àžàžŽàžàžàž¥àž²àž: àžàžžàžà¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàž±à¹àžàžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àžàž§à¹àž² 'modelcol' à¹àžà¹ à¹àžàž·à¹àž­àžàžàž²àžàžàž·à¹àž­àžàžµà¹àžàž¹àžà¹àžà¹à¹àžà¹àžàžàž·à¹àž­àžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àžàžà¹àžà¹àžàžà¹àž¥à¹àž§  
+
+mkcol.cannot_find_modelcol:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžàžàžàž­àž¥à¹àž¥àžàžàž±àžàžà¹àžà¹àžàž %s  
+
+mkcol.col_already_exists:àžà¹àž­àžàžŽàžàžàž¥àž²àž: àž¡àžµàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž­àž¢àž¹à¹à¹àž¥à¹àž§  
+
+mkcol.collectdir:à¹àžà¹àž£àžàžàž­àž£àžµàžàžµà¹àžàž°à¹àžà¹àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹  
+
+
+mkcol.creating_col:àžàž³àž¥àž±àžàžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àž %s  
+
+mkcol.creator:àžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥àžàž­àžàžàž¹à¹àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àž  
+
+mkcol.creator_undefined:àžà¹àž­àžàžŽàžàžàž¥àž²àž: àžàžžàžà¹àž¡à¹à¹àžà¹àžàž³àž«àžàžàžàž·à¹àž­àžàž¹à¹àžªàž£à¹àž²àžà¹àž§à¹ àžàžžàžàžàž³à¹àžà¹àžàžà¹àž­àžà¹àžà¹àžàž±àž§à¹àžàž£àžàžµà¹à¹àžàž·à¹àž­àžàž£àž§àžàžªàž­àžàžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž­àž²àžàžàž°àžà¹àž³àžàž±àž  
+
+mkcol.desc:àžªàžàž£àžŽàžàžà¹ PERL àžàžµà¹à¹àžà¹àžªàž£à¹àž²àžà¹àžàž£àžàžªàž£à¹àž²àžà¹àžà¹àž£àžàžàž­àž£àžµàžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž£àžµàžàžªà¹àžàžà¹àž«àž¡à¹  
+
+mkcol.doing_replacements:àžàž³àž¥àž±àžàžàž³à¹àžàžŽàžàžàž²àž£à¹àžàžàžàžµà¹àžªàž³àž«àž£àž±àž %s  
+
+mkcol.group:àžªàž£à¹àž²àžàžàž¥àžžà¹àž¡àžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹à¹àžàžàžàž­àž¥à¹àž¥àžàžàž±àžàž¡àž²àžàž£àžàž²àž  
+
+mkcol.gs3mode:à¹àž«àž¡àžàžªàž³àž«àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžà¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàž 3  
+
+mkcol.long_colname:àžà¹àž­àžàžŽàžàžàž¥àž²àž: àžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àžàžà¹àž­àžàž¡àžµàžàž§àž²àž¡àž¢àž²àž§àžà¹àž­àž¢àžàž§à¹àž² 8 àž­àž±àžàžàž£àž°à¹àžàž·à¹àž­à¹àž«à¹àžªàž²àž¡àž²àž£àžà¹àžà¹àž²àžàž±àžà¹àžà¹àžàž±àžàž£àž°àžàžà¹àžà¹àž¡àž£àžžà¹àžà¹àžà¹àž²  
+
+mkcol.maintainer:àžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥àžàž­àžàžàž¹à¹àžàž¹à¹àž¥àž£àž±àžàž©àž²àžàž­àž¥à¹àž¥àžàžàž±àž (àžà¹àž²à¹àžàžàžà¹àž²àžàžàž²àžàžàž¹à¹àžªàž£à¹àž²àž)  
+
+mkcol.no_collectdir:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àž¡àžµà¹àžà¹àž£àžàžàž­àž£àžµ 'collect' àž­àž¢àž¹à¹: %s  
+
+mkcol.no_collectdir_specified:àžà¹àž­àžàžŽàžàžàž¥àž²àž: àžàžžàžà¹àž¡à¹à¹àžà¹àž£àž°àžàžž 'collect dir' à¹àžà¹àž«àž¡àž gs3mode àžàžžàžàžàž³à¹àžà¹àžàžà¹àž­àžàž£àž°àžàžžàžàž±àž§à¹àž¥àž·àž­àž -site àž«àž£àž·àž­ -collectdir   
+
+mkcol.no_colname:àžà¹àž­àžàžŽàžàžàž¥àž²àž: àžàžžàžàž¢àž±àžà¹àž¡à¹à¹àžà¹àž£àž°àžàžžàžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àž  
+
+mkcol.optionfile:à¹àžà¹àž£àž±àžàžàž±àž§à¹àž¥àž·àž­àžàžàž²àžà¹àžà¹àž¡ àžàž¶à¹àžàžàž°à¹àžà¹àžàžàž£àž°à¹àž¢àžàžà¹àžàž±àžàž£àž°àžàžàžàžµà¹àžàž²àž£à¹àžà¹àžàž£àž£àžàž±àžàžàž³àžªàž±à¹àžàž¢àž²àž§àž­àž²àžàžà¹àž­à¹àž«à¹à¹àžàžŽàžàžàž±àžàž«àž²àžàž±àžàž£àž°àžàž  
+
+mkcol.params:[àžàž±àž§à¹àž¥àž·àž­àž] àžàž­àž¥à¹àž¥àžàžàž±àž-àžàž·à¹àž­  
+
+mkcol.plugin:à¹àž¡àžàž¹àž¥àžàž¥àž±à¹àžàž­àžŽàž Perl àžàžµà¹àžà¹àž­àžàžàž²àž£à¹àžà¹àžàž²àž (àž­àž²àžàž¡àžµàž£àž²àž¢àžàž²àž£àžàž¥àž±à¹àžàž­àžŽàžàž«àž¥àž²àž¢àžàž±àž§)  
+
+mkcol.public:àžà¹àž²àžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž¡àžµàžàž²àž£à¹àžà¹àž²àžàž¶àžàž£àž°àžàžà¹àžàžà¹àž¡à¹àž£àž°àžàžžàžàž·à¹àž­  
+mkcol.public.true:àžàž­àž¥à¹àž¥àžàžàž±àžà¹àžà¹àžà¹àžàžàžªàž²àžàž²àž£àžàž°  
+mkcol.public.false:àžàž­àž¥à¹àž¥àžàžàž±àžà¹àžà¹àžà¹àžàžàžªà¹àž§àžàžàž±àž§  
+
+mkcol.quiet:àžàž³à¹àžàžŽàžàžàž²àž£à¹àžàž¢à¹àž¡à¹àžà¹àž­àžàž¡àžµàžà¹àž­àžàž§àž²àž¡à¹àžà¹àž  
+
+mkcol.site:à¹àž gs3mode à¹àž«à¹à¹àžà¹àžàž·à¹àž­à¹àžàžà¹àžàžµà¹àžàž±àžàžàž±àž§à¹àžàž£àžªàž àž²àžà¹àž§àžàž¥à¹àž­àž¡ GSDL3HOME à¹àžàž·à¹àž­àžàž³àž«àžàž collectdir àžàž­àžàžàž²àžàž§à¹àž²àžàžžàžà¹àžà¹àž£àž°àžàžž -collectdir à¹àž¥à¹àž§  
+
+mkcol.success:àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹à¹àžªàž£à¹àžà¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§àžàžµà¹ %s  
+
+mkcol.title:àžàž·à¹àž­àžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àž  
+
+mkcol.win31compat:à¹àžà¹àž£àžàžàž­àž£àžµàžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹àž¡àžµàžàž²àž£àžàž³àž«àžàžàžàž·à¹àž­àžàž°àžà¹àž­àžà¹àžà¹àžà¹àžàžàž²àž¡à¹àžàžà¹àžàžà¹àžà¹àž¡àžàž­àž Windows 3.1 àž«àž£àž·àž­à¹àž¡à¹ (à¹àžà¹àž àž¡àžµàžàž§àž²àž¡àž¢àž²àž§ 8 àž­àž±àžàžàž£àž°)  
+mkcol.win31compat.true:àžàž·à¹àž­à¹àžà¹àž£àžàžàž­àž£àžµàž¢àž²àž§ 8 àž­àž±àžàžàž£àž°àž«àž£àž·àž­àžà¹àž­àž¢àžàž§à¹àž²  
+mkcol.win31compat.false:àžàž·à¹àž­à¹àžà¹àž£àžàžàž­àž£àžµàž¢àž²àž§à¹àžà¹àž²à¹àžàžà¹à¹àžà¹  
+
+# -- pluginfo.pl --
+
+pluginfo.collection:àžàž²àž£à¹àž«à¹àžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àžàžàž°àžàž³à¹àž«à¹ pluginfo.pl àžà¹àžàž«àž²àžàž²àž collect/collection-name/perllib/plugins àžà¹àž­àž àžà¹àž²à¹àž¡à¹àžàžàžàž¥àž±à¹àžàž­àžŽàžà¹àžàžàž±à¹àžà¹àž¥à¹àž§ pluginfo.pl àžàž°àžà¹àžàž«àž²à¹àžà¹àžà¹àž£àžàžàž­àž£àžµ perllib/plugins àžàž±à¹àž§à¹àž  
+
+pluginfo.desc:àžàžŽàž¡àžà¹àžà¹àž­àž¡àž¹àž¥à¹àžàžµà¹àž¢àž§àžàž±àžàžàž¥àž±à¹àžàž­àžŽàž  
+
+pluginfo.general_options:àžàž±àž§à¹àž¥àž·àž­àžàžàž±à¹àž§à¹àžàžàž°à¹àžà¹àž£àž±àžàžàž²àž£àžªàž·àžàžàž­àžàž¡àž²àžàž²àžàžàž¥àž²àžªà¹àž¡à¹àžàž­àžàžàž¥àž±à¹àžàž­àžŽàž  
+
+pluginfo.info:info  
+
+pluginfo.no_plugin_name:àžà¹àž­àžàžŽàžàžàž¥àž²àž: àžàžžàžàžà¹àž­àžà¹àžªà¹àžàž·à¹àž­àžàž¥àž±à¹àžàž­àžŽàž  
+
+pluginfo.option_types:àžàž¥àž±à¹àžàž­àžŽàžàž­àž²àžà¹àžà¹àžàž±àž§à¹àž¥àž·àž­àžà¹àžà¹àžªàž­àžàžàžàžŽàž  
+
+pluginfo.params:[àžàž±àž§à¹àž¥àž·àž­àž] àžàž¥àž±à¹àžàž­àžŽàž-àžàž·à¹àž­  
+
+pluginfo.passing_options:àžàž±àž§à¹àž¥àž·àž­àžàž­àž²àžàžàž°àžàž¹àžàžªà¹àžàžà¹àž­à¹àžàž¢àž±àžàžàž¥àž±à¹àžàž­àžŽàžà¹àžà¹ àžà¹à¹àžà¹à¹àžàž¢àžàž²àž£àž£àž§àž¡àžàž±àž§à¹àž¥àž·àž­àžà¹àž«àž¥à¹àž²àžàž±à¹àžàž¥àžà¹àžà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž² collect.cfg àžàž­àžàžàžžàž  
+
+pluginfo.specific_options:àžàž±àž§à¹àž¥àž·àž­àžà¹àžàžàž²àž°àžàž¹àžàžàž³àž«àžàžà¹àž§à¹àž àž²àž¢à¹àžàžàž±àž§àžàž¥àž±à¹àžàž­àžŽàžà¹àž­àž à¹àž¥àž°àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžà¹àžà¹à¹àžàžàž²àž°àžàž±àžàžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžà¹àž²àžàž±à¹àž  
+
+
+# -- plugoutinfo.pl --
+
+plugoutinfo.collection:àžàž²àž£à¹àž«à¹àžàž·à¹àž­àžàž­àž¥à¹àž¥àžàžàž±àžàžàž°àžàž³à¹àž«à¹ plugoutinfo.pl àžà¹àžàž«àž²àžàž²àž collect/collection-name/perllib/plugouts àžà¹àž­àž  àžà¹àž²à¹àž¡à¹àžàžàžàž¥àž±à¹àžà¹àž­àž²àžà¹à¹àžàžàž±à¹àžà¹àž¥à¹àž§ pluginfo.pl àžàž°àžà¹àžàž«àž²à¹àžà¹àžà¹àž£àžàžàž­àž£àžµ perllib/plugouts àžàž±à¹àž§à¹àž  
+
+plugoutinfo.desc:àžàžŽàž¡àžà¹àžà¹àž­àž¡àž¹àž¥à¹àžàžµà¹àž¢àž§àžàž±àžàžàž¥àž±à¹àžà¹àž­àž²àžà¹  
+
+plugoutinfo.general_options:àžàž±àž§à¹àž¥àž·àž­àžàžàž±à¹àž§à¹àžàžàž°à¹àžà¹àž£àž±àžàžàž²àž£àžªàž·àžàžàž­àžàžàž²àžàžàž¥àž²àžªà¹àž¡à¹àžàž­àžàžàž¥àž±à¹àžà¹àž­àž²àžà¹  
+
+plugoutinfo.info:info  
+
+plugoutinfo.no_plugout_name:àžà¹àž­àžàžŽàžàžàž¥àž²àž: àžàžžàžàžà¹àž­àžà¹àžªà¹àžàž·à¹àž­àžàž¥àž±à¹àžà¹àž­àž²àžà¹  
+
+plugoutinfo.option_types:àžàž¥àž±à¹àžà¹àž­àž²àžà¹àž­àž²àžà¹àžà¹àžàž±àž§à¹àž¥àž·àž­àžà¹àžà¹àžªàž­àžàžàžàžŽàž  
+
+plugoutinfo.params:[àžàž±àž§à¹àž¥àž·àž­àž] àžàž¥àž±à¹àžà¹àž­àž²àžà¹-àžàž·à¹àž­  
+
+plugoutinfo.passing_options:àžàž±àž§à¹àž¥àž·àž­àžàž­àž²àžàžàž°àžàž¹àžàžªà¹àžàžà¹àž­à¹àžàž¢àž±àžàžàž¥àž±à¹àžà¹àž­àž²àžà¹à¹àžà¹ àžà¹à¹àžà¹à¹àžàž¢àžàž²àž£àž£àž§àž¡àžàž±àž§à¹àž¥àž·àž­àžà¹àž«àž¥à¹àž²àžàž±à¹àžàž¥àžà¹àžà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž² collect.cfg àžàž­àžàžàžžàž  
+
+plugoutinfo.specific_options:àžàž±àž§à¹àž¥àž·àž­àžà¹àžàžàž²àž°àžàž°àžàž¹àžàžàž³àž«àžàžà¹àž§à¹àž àž²àž¢à¹àžàžàž±àž§àžàž¥àž±à¹àžà¹àž­àž²àžà¹à¹àž­àž à¹àž¥àž°àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžà¹àžà¹à¹àžàžàž²àž°àžàž±àžàžàž¥àž±à¹àžà¹àž­àž²àžà¹àžàžµà¹à¹àžà¹àž²àžàž±à¹àž  
+
+
+
+#
+# Classifier option descriptions
+#
+
+AllList.desc:àžªàž£à¹àž²àžà¹àž­àžàžªàž²àž£àžàž±à¹àžàž«àž¡àžà¹àžà¹àžàž£àž²àž¢àžàž²àž£à¹àžàžµàž¢àž§ àžàž¶à¹àžà¹àžà¹à¹àžàž¢ oaiserver  
+
+AZCompactList.allvalues:à¹àžà¹àžà¹àž²à¹àž¡àžàž²àžàž²àžàž²àžàž±à¹àžàž«àž¡àžàžàžµà¹àžàž  
+
+AZCompactList.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àž (Classifier) àžªàž³àž«àž£àž±àžàžàž²àž£à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž²àž¡àžàž±àž§àž­àž±àžàž©àž£ (à¹àžàž a-zA-Z0-9)  àžàž°àžªàž£à¹àž²àžàž£àž²àž¢àžàž²àž£ A-Z à¹àž£àžµàž¢àžàžàž²àž¡à¹àžàž§àžàž­àž àžàž²àž¡àžà¹àž§àž¢àž£àž²àž¢àžàž²àž£àžàž²àž¡à¹àžàž§àžàž±à¹àžàžàžµà¹àžàž£àž°àžàž­àžàžà¹àž§àž¢à¹àž­àžàžªàž²àž£ àž«àž£àž·àž­àžàž±à¹àžàž§àž²àžàžªàž³àž«àž£àž±àžà¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžµà¹àž¡àžàž²àžàž²àžàž²à¹àž«àž¡àž·àž­àžàžàž±àž  
+
+AZCompactList.doclevel:àž£àž°àžàž±àžàžàžµà¹àžàž°àžàž£àž°àž¡àž§àž¥àžàž¥à¹àž­àžàžªàž²àž£  
+AZCompactList.doclevel.top:à¹àž­àžàžªàž²àž£àžàž±à¹àžàž«àž¡àž  
+AZCompactList.doclevel.section:àžàž²àž¡àžªà¹àž§àž  
+
+AZCompactList.firstvalueonly:à¹àžà¹à¹àžàžàž²àž°àžà¹àž²à¹àž¡àžàž²àžàž²àžàž²à¹àž£àžàžàžµà¹àžàž  
+
+AZCompactList.freqsort:à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž²àž¡àžàž§àž²àž¡àžàžµà¹àžàž­àžà¹àž«àžàžà¹àžàžàžàž²àž£à¹àž£àžµàž¢àžàžàž²àž¡àžàž±àž§àž«àžàž±àžàžªàž·àž­à¹àž¥àž°àžàž±àž§à¹àž¥àž  
+
+AZCompactList.maxcompact:àžàž³àžàž§àžàžªàž¹àžàžªàžžàžàžàž­àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž°à¹àžªàžàžàžà¹àž­àž«àžàž¶à¹àžàž«àžà¹àž²  
+
+AZCompactList.metadata:à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²à¹àžàžµà¹àž¢àž§ àž«àž£àž·àž­àž£àž²àž¢àžàž²àž£àžàž­àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àžàžàžµà¹à¹àžà¹àžªàž³àž«àž£àž±àžàžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àž àžà¹àž²àž¡àžµàžàž²àž£àž£àž°àžàžžàž£àž²àž¢àžàž²àž£à¹àž§à¹ àž£àž°àžàžàžàž°à¹àžà¹àžàžàžŽàžàžàž­àžà¹àž¡àžàž²àžàž²àžàž²à¹àž£àžàžàžµà¹àž¡àžµàžà¹àž² à¹àžàž¢àž­àž²àžàžàž°à¹àžà¹àž£à¹àž§àž¡àžàž±àžàžªàžàž²àžàž° -firstvalueonly à¹àž¥àž° -allvalues à¹àžàž·à¹àž­à¹àž¥àž·àž­àžà¹àžàžàž²àž°àžà¹àž²à¹àž£àžàž«àž£àž·àž­àžà¹àž²à¹àž¡àžàž²àžàž²àžàž²àžàž±à¹àžàž«àž¡àžàžàž²àžàž£àž²àž¢àžàž²àž£  
+
+AZCompactList.mincompact:àžàž³àžàž§àžàžà¹àž³àžªàžžàžàžàž­àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž°à¹àžªàžàžàžà¹àž­àž«àžàž¶à¹àžàž«àžà¹àž²  
+
+AZCompactList.mingroup:àžà¹àž²àžàžµà¹àžà¹àž­àž¢àžàžµà¹àžªàžžàžàžàžµà¹àžàž³à¹àž«à¹à¹àžàžŽàžàžàž²àž£àžªàž£à¹àž²àžàžàž¥àžžà¹àž¡à¹àžàž¥àž³àžàž±àžàžàž±à¹àž  
+
+AZCompactList.minnesting:àžà¹àž²àžàžµà¹àžà¹àž­àž¢àžàžµà¹àžªàžžàžàžàžµà¹àžàž³à¹àž«à¹àž£àž²àž¢àžàž²àž£à¹àžàž¥àžà¹àžà¹àžà¹àžàž£àž²àž¢àžàž²àž£à¹àžàžàžà¹àž­àž  
+
+AZCompactList.recopt:à¹àžà¹à¹àžà¹àž¡àžàž²àžàž²àžàž²à¹àžàžàžà¹àž­àž à¹àžà¹àž -metadata àžàžµ/àž­àžàžà¹àžàž£  
+AZCompactList.sort:à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àžàž°à¹àžà¹à¹àž£àžµàž¢àžàž¥àž³àžàž±àžà¹àž«àžàžàžàž¥àž²àž¢àžªàžžàž (Leaf node)  
+
+AZCompactSectionList.desc:àžàž²àž£à¹àžàž£àžàž±àžàžàž­àž AZCompactList àžàžµà¹à¹àž¢àžàžàž£àž°à¹àž àžàžªà¹àž§àžà¹àžàžàžàž²àž£à¹àž¢àžàžàž²àž¡à¹àž­àžàžªàž²àž£ àž£àž²àž¢àžàž²àž£àžà¹àž²àžà¹ àžàž°àžàž¹àžàžàž±àžà¹àž£àžµàž¢àžàžàž²àž¡à¹àž¡àžàž²àžàž²àžàž²àž£àž°àžàž±àžàžªà¹àž§àž  
+
+AZList.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàžªàž³àž«àž£àž±àžàžàž²àž£à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž²àž¡àžàž±àž§àž­àž±àžàž©àž£ (à¹àžàž a-zA-Z0-9) àžàž°àžªàž£à¹àž²àžàž£àž²àž¢àžàž²àž£ A-Z à¹àž£àžµàž¢àžàžàž²àž¡à¹àžàž§àžàž­àž à¹àžàž¢àž¡àžµà¹àž­àžàžªàž²àž£àž­àž¢àž¹à¹àžà¹àž²àžà¹àžà¹  
+
+AZList.metadata:à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²à¹àžàžµà¹àž¢àž§àž«àž£àž·àž­àž£àž²àž¢àžàž²àž£àžàž­àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àžàžàžµà¹à¹àžà¹àžªàž³àž«àž£àž±àžàžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àž àžàž°à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž²àž¡àžàžµà¹àž£àž²àž¢àžàž²àž£àžà¹àžàžàžµà¹ à¹àžàž¢àž£àž°àžàžàžàž°à¹àžà¹à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž£àžàžàžµà¹àžàž£àž°àžàž­àžàžà¹àž§àž¢àžà¹àž²à¹àž¡àžàž²àžàž²àžàž² àžàž¶à¹àžàž£àž²àž¢àžàž²àž£àžàž°àžàž¹àžà¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž²àž¡àž­àžàžà¹àžàž£àž°àžàž­àžàžàžµà¹  
+
+AZSectionList.desc:àžàž²àž£à¹àžàž£àžàž±àžàžàž­àž AZList àžàžµà¹à¹àž¢àžàžàž£àž°à¹àž àžàžàž²àž¡àžªà¹àž§àžà¹àžàžàžàž²àž£àžàž²àž¡à¹àž¢àžà¹àž­àžàžªàž²àž£ àž£àž²àž¢àžàž²àž£àžà¹àž²àžà¹ àžàž°àžàž¹àžàžàž±àžà¹àž£àžµàž¢àžàžàž²àž¡à¹àž¡àžàž²àžàž²àžàž²àž£àž°àžàž±àžàžªà¹àž§àž  
+
+BasClas.bad_general_option:àžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àž %s à¹àžà¹àžàž±àž§à¹àž¥àž·àž­àžà¹àž¡à¹àžàž¹àžàžà¹àž­àž à¹àž«à¹àžàž£àž§àžàžªàž­àžà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž² collect.cfg àžàž­àžàžàžžàž  
+
+BasClas.builddir:àžàžµà¹àžàž±àžàžàžµà¹à¹àžà¹àžàžàž±àžàžàžµàžàžµà¹àžªàž£à¹àž²àž  
+
+BasClas.buttonname:àžà¹àž²àž¢àžàž·à¹àž­àžªàž³àž«àž£àž±àžàž«àžà¹àž²àžàž­àžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžà¹àž¥àž°àžàžžà¹àž¡à¹àžà¹àžàžàžàž³àžàž²àž àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžàžàž·àž­ àž­àžàžà¹àžàž£àž°àžàž­àžà¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àž£àž°àžàžžàžà¹àž§àž¢ -metadata  
+
+BasClas.desc:àžàž¥àž²àžªàžàž·à¹àžàžàž²àžàžªàž³àž«àž£àž±àžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàžàž±à¹àžàž«àž¡àž  
+
+BasClas.no_metadata_formatting:àžàž£àžžàžàž²àž­àž¢à¹àž²à¹àžà¹àžàž²àž£àžàž±àžàž£àž¹àžà¹àžàžà¹àž¡àžàž²àžàž²àžàž²àž­àž±àžà¹àžàž¡àž±àžàžŽà¹àžà¹ (àžªàž³àž«àž£àž±àžàžàž²àž£à¹àž£àžµàž¢àžàž¥àž³àžàž±àž)  
+
+BasClas.outhandle:àžàž²àž£àžàž±àžàžàž²àž£à¹àžà¹àž¡àžàžµà¹àžàž°à¹àžà¹à¹àžàžµàž¢àžàžà¹àž­àž¡àž¹àž¥àžàž¥àž¥àž±àžàžà¹  
+
+BasClas.removeprefix:àžàž³àžàž³àž«àžà¹àž²àžàžµà¹àžàž°àž¥àž°à¹àž§à¹àžà¹àžàžà¹àž²à¹àž¡àžàž²àžàž²àžàž²àžàžàž°à¹àž£àžµàž¢àžàž¥àž³àžàž±àž  
+
+BasClas.removesuffix:àžàž³àžà¹àž­àžà¹àž²àž¢àžàžµà¹àžàž°àž¥àž°à¹àž§à¹àžà¹àžàžà¹àž²à¹àž¡àžàž²àžàž²àžàž²àžàžàž°à¹àž£àžµàž¢àžàž¥àž³àžàž±àž  
+
+BasClas.verbosity:àžàž§àžàžàžžàž¡àžàž£àžŽàž¡àž²àžàžàž¥àž¥àž±àžàžà¹  0=à¹àž¡à¹àž¡àžµ  3=àžàž³àžàž§àžàž¡àž²àž  
+
+Browse.desc:àžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàžàžµà¹àžàž¥àž­àž¡à¹àžàž¥àžàžàž¶à¹àžàžàžµà¹àž¡àžµàžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžà¹àžà¹àžàžàžàž³àžàž²àžà¹àžàž¢àž±àžàžà¹àžà¹àžàžàžàžµà¹àž£àž§àž¡àž«àžà¹àž²à¹àž£àžµàž¢àžàžàž¹à¹àž¥àž°àžà¹àžàž«àž² àžàž¶à¹àžàžàž°àžàž³àžàž²àžà¹àžà¹àžàž±àžàžàž­àž¥à¹àž¥àžàžàž±àž mgpp à¹àžà¹àž²àžàž±à¹àž à¹àž¥àž°àžªàž²àž¡àž²àž£àžà¹àžà¹à¹àžà¹àžàžµàžàž±àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž¥à¹àžà¹ à¹àžà¹àž²àžàž±à¹àž  
+
+DateList.bymonth:à¹àž¢àžàžàž£àž°à¹àž àžàžà¹àž§àž¢àžà¹àž²àžàžµà¹àž¥àž°à¹àžàž·àž­àžà¹àžàžàžàž²àž£à¹àž¢àžàžà¹àž§àž¢àžàžµà¹àžàžµàž¢àžàž­àž¢à¹àž²àžà¹àžàžµàž¢àž§  
+
+DateList.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàžªàž³àž«àž£àž±àžàžàž²àž£à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž²àž¡àž§àž±àžàžàžµà¹ à¹àžàž¢àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžà¹àž¥à¹àž§ àžàž°à¹àž£àžµàž¢àžàžàž²àž¡à¹àž¡àžàž²àžàž²àžàž² 'àž§àž±àžàžàžµà¹' àž§àž±àžàžàžµà¹àžàž§àž£àžàž°àž­àž¢àž¹à¹à¹àžàž£àž¹àžà¹àžàž àžàžàžàžàžàžàž§àž§ àž«àž£àž·àž­ àžàžàžàž-àžàž-àž§àž§  
+
+DateList.metadata:à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àž¡àžµàž§àž±àžàžàžµà¹à¹àžàž·à¹àž­à¹àžà¹à¹àžàžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àž àž£àž¹àžà¹àžàžàžàžµà¹àžàž§àž£àžàž°à¹àžà¹àž àžàž·àž­ àžàžàžàžàžàžàž§àž§ àž«àž£àž·àž­ àžàžàžàž-àžàž-àž§àž§ à¹àžàž¢àž­àž²àžàžàž°àž­àž¢àž¹à¹à¹àžàž£àž¹àžà¹àžàžàž£àž²àž¢àžàž²àž£àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àžà¹àžà¹ àžàž¶à¹àžà¹àžàžàž£àžàžµàžàžµà¹àž£àž°àžàžàžàž°à¹àžà¹àž§àž±àžàžàžµà¹à¹àž£àžàžàžµà¹àžàž  
+
+DateList.reverse_sort:à¹àž£àžµàž¢àžàž¥àž³àžàž±àžà¹àž­àžàžªàž²àž£àžàž²àž¡àž¥àž³àžàž±àžà¹àž§àž¥àž²à¹àžàžàž¢à¹àž­àžàžàž¥àž±àž (à¹àž§àž¥àž²àž¥à¹àž²àžªàžžàžàžàž¶à¹àžàžà¹àž­àž)  
+
+DateList.nogroup:àžàž³à¹àž«à¹à¹àžà¹àž¥àž°àžàžµà¹àž¢àžà¹àžà¹àžà¹àžà¹àž¥àž°àž£àž²àž¢àžàž²àž£à¹àžàž£àž²àž¢àžàž²àž£à¹àžàž§àžàž­àž à¹àžàžàžàž²àž£àžàž¢àž²àž¢àžàžµàžàžµà¹àž¡àžµàžàž³àžàž§àžàž£àž²àž¢àžàž²àž£àžà¹àž­àž¢ (àžàžžàžàž¥àž±àžàž©àžàž°àžàžµà¹àž¢àž±àžàžªàž²àž¡àž²àž£àžà¹àžà¹àž£à¹àž§àž¡àžàž±àžàžàž±àž§à¹àž¥àž·àž­àž -bymonth à¹àžàž·à¹àž­àžàž³à¹àž«à¹à¹àžà¹àž¥àž°à¹àžàž·àž­àžà¹àž¢àžà¹àžà¹àžàž£àž²àž¢àžàž²àž£àžà¹àž²àžàž«àž²àžà¹àžàžàžàžµà¹àžàž°àžàžªàž²àžàžàž±àžà¹àžà¹)  
+
+DateList.no_special_formatting:àžàž£àžžàžàž²àž­àž¢à¹àž²à¹àžªàžàžàžà¹àž­àž¡àž¹àž¥ 'àžàžµ' à¹àž¥àž° 'à¹àžàž·àž­àž' à¹àžàž£àž²àž¢àžàž²àž£à¹àž­àžàžªàž²àž£  
+
+DateList.sort:à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžŽà¹àžšàž©àžàžµà¹àžàž°à¹àž£àžµàž¢àžàž¥àž³àžàž±àžà¹àžàžàž£àžàžµàžàžµà¹à¹àž­àžàžªàž²àž£àžªàž­àžàžàžàž±àžàž¡àžµàž§àž±àžàžàžµà¹à¹àžàžµàž¢àž§àžàž±àž  
+
+List.always_bookshelf_last_level:àžªàž£à¹àž²àžà¹àž­àžàž­àžàžàž±à¹àžàž§àž²àžàž«àžàž±àžàžªàž·àž­à¹àž¡à¹àž§à¹àž²àžàž°àž¡àžµàž«àžàž±àžàžªàž·àž­à¹àžàžµàž¢àžàž£àž²àž¢àžàž²àž£à¹àžàžµàž¢àž§à¹àžà¹àžà¹àž¥àž°àžàž¥àžžà¹àž¡à¹àžà¹àž«àžàžàžàž¥àž²àž¢àžªàžžàž  
+
+List.classify_sections:à¹àž¢àžàžàž£àž°à¹àž àžàžàž²àž¡àžªà¹àž§àžà¹àžàžàžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àžàžàž²àž¡à¹àž­àžàžªàž²àž£  
+
+List.desc:àžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàž£àž²àž¢àžàž²àž£à¹àžàžàžàž±à¹àž§à¹àžà¹àž¥àž°à¹àžàžàž¢àž·àžàž«àž¢àžžà¹àžàžàžµà¹àž£àž§àž¡àžàž§àž²àž¡àžªàž²àž¡àž²àž£àžà¹àžàž·àž­àžàžàž±à¹àžàž«àž¡àžàžàž­àž AZCompactList à¹àžà¹àž¡àžµ Unicode à¹àž¡àžàž²àžàž²àžàž²à¹àž¥àž°àžàž§àž²àž¡àžªàž²àž¡àž²àž£àžà¹àžàžàž²àž£à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàžµà¹àžàžµàžàž§à¹àž²  
+
+List.metadata:à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹à¹àžà¹àžªàž³àž«àž£àž±àžàžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àž à¹àž«à¹à¹àžà¹ '/' à¹àžàž·à¹àž­à¹àžà¹àžàž£àž°àžàž±àžà¹àžàž¥àž³àžàž±àžàžàž±à¹àž à¹àž¥àž°à¹àžà¹ ';' à¹àžàž·à¹àž­à¹àžà¹àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àž àž²àž¢à¹àžà¹àžà¹àž¥àž°àž£àž°àžàž±àž  
+
+List.partition_name_length:àžàž§àž²àž¡àž¢àž²àž§àžàž­àžàžàž·à¹àž­àžàž²àž£à¹àžàžŽàžàž±àž àžàž¶à¹àžàž¡àžµàžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžàžàžµà¹àžªàž²àž¡àž²àž£àžà¹àžàž¥àžµà¹àž¢àžàžà¹àž²à¹àžà¹àžàž±à¹àžà¹àžà¹ 1 àžàž¶àž 3 àž­àž±àžàžàž£àž° àžàž¶à¹àžàž­àž¢àž¹à¹àžàž±àžàžàž³àžàž§àžàžàžµà¹àžà¹àž­àžàžàž²àž£à¹àžà¹à¹àžà¹àžà¹àž¢àžàžàž²àž£à¹àžàžŽàžàž±àžàžàž±à¹àžà¹àžà¹àžà¹àžàžàžàžàž àžàžžàžàžªàž²àž¡àž²àž£àžàžàž£àž°àž¢àžžàžàžà¹à¹àžà¹àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹à¹àžà¹à¹àžàžàž²àž°à¹àž¡àž·à¹àž­à¹àžà¹àžàž±à¹àžàžà¹àž² partition_type_within_level à¹àžà¹àž 'constant_size' à¹àžà¹àž²àžàž±à¹àž  
+
+List.partition_size_within_level:àžàž³àžàž§àžàž£àž²àž¢àžàž²àž£à¹àžà¹àžà¹àž¥àž°àžàž²àž£à¹àžàžŽàžàž±àž (àžàž£àž°àž¢àžžàžàžà¹à¹àžà¹à¹àžà¹à¹àžàžàž²àž°à¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£àžàž±à¹àžàžà¹àž² partition_type_within_level à¹àžà¹àž 'constant_size' à¹àžà¹àž²àžàž±à¹àž)  
+
+List.partition_type_within_level:àžàžàžŽàžàžàž­àžàžàž²àž£àžàž³àžàž²àž£à¹àžàžŽàžàž±àžàžàžµà¹àžàž³à¹àžàžŽàžàžàž²àž£à¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§: 'per_letter' 'constant_size' àž«àž£àž·àž­ 'none'  
+
+List.sort_leaf_nodes_using:à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹à¹àžà¹à¹àž£àžµàž¢àžàž¥àž³àžàž±àžà¹àž«àžàžàžàž¥àž²àž¢àžªàžžàž à¹àž«à¹à¹àžà¹ '|' à¹àžàž·à¹àž­à¹àž¢àžàžàž¥àžžà¹àž¡à¹àž¡àžàž²àžàž²àžàž²à¹àž«à¹àž¡àžµàžàž²àž£à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàž­àž¢à¹àž²àžàžàžàžàžµà¹ à¹àž¥àž°à¹àžà¹ ';' à¹àžàž·à¹àž­à¹àž¢àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àž àž²àž¢à¹àžà¹àžà¹àž¥àž°àžàž¥àžžà¹àž¡  
+
+List.sort_using_unicode_collation:àžàž±àžà¹àž£àžµàž¢àžàž¥àž³àžàž±àžà¹àžàž¢à¹àžà¹ Unicode Collation Algorithm àžàžžàžàžàž³à¹àžà¹àžàžà¹àž­àžàžàž³àžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àžà¹àžà¹àž¡ http://www.unicode.org/Public/UCA/latest/allkeys.txt file àž¥àžà¹àžà¹àžàž¥à¹àžàž­àž£à¹ lib/Unicode/Collate àžàž­àž Perl  
+
+List.use_hlist_for:à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹à¹àžà¹ hlist à¹àžàžàžàž²àž£à¹àžà¹ vlist  à¹àž«à¹à¹àžà¹ ',' à¹àžàž·à¹àž­à¹àžà¹àžàžàž¥àžžà¹àž¡à¹àž¡àžàž²àžàž²àžàž² à¹àž¥àž°à¹àžà¹ ';' à¹àžàž·à¹àž­à¹àžà¹àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àž àž²àž¢à¹àžà¹àžà¹àž¥àž°àžàž¥àžžà¹àž¡  
+
+HFileHierarchy.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàžªàž³àž«àž£àž±àžàžªàž£à¹àž²àžàžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àžà¹àžàžàž¥àž³àžàž±àžàžàž±à¹àžàžàžµà¹àž¡àžµàžàž·à¹àžàžàž²àžàž­àž¢àž¹à¹àžàžà¹àžà¹àž¡à¹àžàž£àžàžªàž£à¹àž²àžà¹àžªàž£àžŽàž¡  
+
+Hierarchy.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàžªàž³àž«àž£àž±àžàžªàž£à¹àž²àžàžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àžà¹àžàžàž¥àž³àžàž±àžàžàž±à¹àž àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àž­àž²àžàž¡àžµàžàž·à¹àžàžàž²àžàž­àž¢àž¹à¹àžàžà¹àž¡àžàž²àžàž²àžàž²à¹àžàžŽàžà¹àžàž£àžàžªàž£à¹àž²àž àž«àž£àž·àž­àž­àž²àžà¹àžà¹à¹àžà¹àž¡à¹àžàž£àžàžªàž£à¹àž²àžà¹àžªàž£àžŽàž¡àžà¹à¹àžà¹ (à¹àžà¹àžàž±àž§à¹àž¥àž·àž­àž -hfile)  
+
+Hierarchy.documents_last:à¹àžªàžàžàžàž¥à¹àž«àžàžà¹àž­àžàžªàž²àž£àž«àž¥àž±àžà¹àž«àžàžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àž  
+
+Hierarchy.hfile:à¹àžà¹à¹àžà¹àž¡à¹àžàž£àžàžªàž£à¹àž²àžàžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àžàžàžµà¹àž£àž°àžàžž  
+
+Hierarchy.hlist_at_top:à¹àžªàžàžàžàž¥àž£àž°àžàž±àžà¹àž£àžàžàž­àžàžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àžà¹àžà¹àžàž§àžàž­àž  
+
+Hierarchy.reverse_sort:à¹àž£àžµàž¢àžàž¥àž³àžàž±àžà¹àž«àžàžàžàž¥àž²àž¢àžªàžžàžà¹àžàž¥àž³àžàž±àžàž¢à¹àž­àžàžàž¥àž±àž (à¹àžà¹àžàž±àž -sort)  
+
+Hierarchy.separator:àžàžŽàžàžàžà¹àžàžàžàžŽàžàžµà¹à¹àžà¹àžªàž³àž«àž£àž±àžàžàž±àž§à¹àžà¹àž àžà¹àž²àžàž³àž¥àž±àžà¹àžà¹à¹àž¡àžàž²àžàž²àžàž²à¹àžàžŽàžà¹àžàž£àžàžªàž£à¹àž²àž  
+
+Hierarchy.sort:à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹à¹àžà¹àžàž±àžà¹àž£àžµàž¢àžàž¥àž³àžàž±àžà¹àž«àžàžàžàž¥àž²àž¢àžªàžžàž àžàž°à¹àž¡à¹àž¡àžµàžàž²àž£àžàž±àžà¹àž£àžµàž¢àžà¹àž«àžàžàžàž¥àž²àž¢àžªàžžàžàž«àž²àžà¹àž¡à¹àž£àž°àžàžžà¹àž§à¹  
+
+Hierarchy.suppressfirstlevel:àž¥àž°à¹àž§à¹àžàžªà¹àž§àžà¹àž£àžàžàž­àžàžà¹àž²à¹àž¡àžàž²àžàž²àžàž² àžà¹àž²àžàžµà¹àž¡àžµàžàž£àž°à¹àž¢àžàžà¹àžà¹àž­à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àž¡àžµàžà¹àž²àž­àžàžà¹àžàž£àž°àžàž­àžàžàž±àž§à¹àž£àžà¹àž«àž¡àž·àž­àžàžàž±àž à¹àžà¹àž à¹àžà¹àž£àžàžàž­àž£àžµàžàž³à¹àžà¹àž²à¹àž gsdlsourcefilename  
+
+Hierarchy.suppresslastlevel:àž¥àž°à¹àž§à¹àžàžªà¹àž§àžàžà¹àž²àž¢àžªàžžàžàžàž­àžàžà¹àž²à¹àž¡àžàž²àžàž²àžàž² àžà¹àž²àžàžµà¹àž¡àžµàžàž£àž°à¹àž¢àžàžà¹àžà¹àž­à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àžà¹àž²à¹àžà¹àž¥àž°àžà¹àž²à¹àž¡à¹àžà¹àž³àžàž±àž à¹àžà¹àž à¹àžªà¹àžàžàž²àžàžàž­àžà¹àžà¹àž¡  
+
+HTML.desc:àžªàž£à¹àž²àžàžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àžàž§à¹àž²àžàžàžµà¹à¹àžà¹àžàžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàž­àž¢à¹àž²àžàžà¹àž²àž¢à¹àžàž¢àž±àžàž«àžà¹àž²à¹àž§à¹àž  
+
+HTML.url:url àžàž­àžàž«àžà¹àž²à¹àž§à¹àžàžàžµà¹à¹àžàž·à¹àž­àž¡à¹àž¢àž  
+
+SimpleList.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàž£àž²àž¢àžàž²àž£àž­àž¢à¹àž²àžàžà¹àž²àž¢  
+
+SimpleList.metadata:à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²à¹àžàžµà¹àž¢àž§àž«àž£àž·àž­àž£àž²àž¢àžàž²àž£à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àžàžàžµà¹à¹àžà¹àžªàž³àž«àž£àž±àžàžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àž àžàž²àž¡àž¥àž³àžàž±àžàžàžµà¹àžà¹àžàžàžµà¹à¹àžàž¢àž£àž²àž¢àžàž²àž£ àž£àž°àžàžàžàž°à¹àžà¹à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž£àžàžàžµà¹àž¡àžµàžà¹àž²à¹àž¡àžàž²àžàž²àžàž² àž£àž²àž¢àžàž²àž£àžàž°àžàž¹àžàžàž±àžà¹àž£àžµàž¢àžàžàž²àž¡àž­àžàžà¹àžàž£àž°àžàž­àžàžàžµà¹ àžàž­àžàžàž²àžàžàžžàžàžàž°à¹àžà¹ -sort àžà¹àž²à¹àž¡à¹àž¡àžµàžàž²àž£àž£àž°àžàžžà¹àž¡àžàž²àžàž²àžàž² à¹àž­àžàžªàž²àž£àžàž±à¹àžàž«àž¡àžàžàž°àžàž¹àžàž£àž§àž¡à¹àž§à¹à¹àžàž£àž²àž¢àžàž²àž£ à¹àž¡à¹à¹àžà¹àžàžàž±à¹àžà¹àž¥à¹àž§ à¹àžàžàž²àž°à¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžµàžà¹àž²à¹àž¡àžàž²àžàž²àžàž²à¹àžà¹àž²àžàž±à¹àžàžàžµà¹àžàž°àžàž¹àžàž£àž§àž¡à¹àžà¹àž²àž¡àž²  
+
+SimpleList.sort:à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àžàž°à¹àž£àžµàž¢àžàž¥àž³àžàž±àž à¹àž«à¹à¹àžà¹ '-sort nosort' à¹àž¡àž·à¹àž­à¹àž¡à¹àžà¹àž­àžàžàž²àž£à¹àž£àžµàž¢àžàž¥àž³àžàž±àž  
+
+Phind.desc:àžªàž£à¹àž²àžàž¥àž³àžàž±àžàžàž±à¹àžàžàž­àžàž§àž¥àžµàžàžµà¹àžàžà¹àžàžà¹àž­àžàž§àž²àž¡ àžàž¶à¹àžàžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžàžàž¹à¹àžà¹àžà¹àž²àžàžàž²àžà¹àž­àžà¹àžàž¥à¹àž  
+
+Phind.language:àž àž²àž©àž²àž«àžàž¶à¹àžàž àž²àž©àž²àž«àž£àž·àž­àž«àž¥àž²àž¢àž àž²àž©àž²àžàžµà¹àžàž°à¹àžà¹àž¥àž³àžàž±àžàžàž±à¹àžàžàž²àž£àžªàž£à¹àž²àž àž àž²àž©àž²àžàž°àžàž¹àžàž£àž°àžàžžàžà¹àž§àž¢àž£àž«àž±àžªàžàž£àž°à¹àžàžšàžªàž­àžàžàž±àž§àž­àž±àžàž©àž£ à¹àžà¹àž en (àž­àž±àžàžàž€àž©) es (àžªà¹àžàž) à¹àž¥àž° fr (àžàž£àž±à¹àžà¹àžšàžª) àž àž²àž©àž²à¹àžà¹àžàžàžŽàžàžàžà¹àžàžàžàžŽ àžàž±àžàžàž±à¹àžàžàž¶àžàžªàž²àž¡àž²àž£àžà¹àžà¹ 'en|fr' (àž­àž±àžàžàž€àž©àž«àž£àž·àž­àžàž£àž±à¹àžà¹àžšàžª) à¹àž¥àž° '..' (àžàž£àžàžàž±àžàžàžžàžàž àž²àž©àž²) à¹àžà¹à¹àžà¹àžàžàž±àž  
+
+Phind.min_occurs:àžàž³àžàž§àžàžàž£àž±à¹àžàžàžµà¹àžà¹àž³àžªàžžàžàžàžµà¹àž§àž¥àžµàžàž°àžà¹àž­àžàžàž£àž²àžàžà¹àžàžà¹àž­àžàž§àž²àž¡àžàžµà¹àžàž°àž£àž§àž¡àž­àž¢àž¹à¹à¹àžàž¥àž³àžàž±àžàžàž±à¹àžàž§àž¥àžµ  
+
+Phind.savephrases:àžà¹àž²àž¡àžµàžàž²àž£àžàž±à¹àžàžà¹àž²à¹àž§à¹ àžà¹àž­àž¡àž¹àž¥àž§àž¥àžµàžàž°àžàž¹àžàžàž±àžà¹àžà¹àžà¹àž§à¹à¹àžà¹àžà¹àž¡àžàžµà¹àžàž³àž«àžàžà¹àžàž£àž¹àžà¹àžàžàžà¹àž­àžàž§àž²àž¡ àžàž¶à¹àžàž­àž²àžà¹àžà¹àžàžàž§àž²àž¡àžàžŽàžàžàžµà¹àžàžµàžàžµà¹àžàž°à¹àžà¹à¹àžªà¹àžàžàž²àžàžªàž±àž¡àžàž¹àž£àžà¹ (absolute path)  
+
+Phind.suffixmode:àžàž²àž£àž²àž¡àžŽà¹àžàž­àž£à¹ smode àžàžµà¹à¹àžà¹àžàž±àžà¹àžàž£à¹àžàž£àž¡àžàž²àž£àžàž±àžàžàž­àžàž§àž¥àžµ àžà¹àž² 0 àž«àž¡àž²àž¢àžàž§àž²àž¡àž§à¹àž² àž¥àž°à¹àž§à¹àžàžàž³àž«àž¢àžžàž (stopwords) à¹àž¥àž° 1 àž«àž¡àž²àž¢àžàž§àž²àž¡àž§à¹àž² à¹àžà¹àžàž³àž«àž¢àžžàž (stopwords)  
+
+Phind.text:àžà¹àž­àžàž§àž²àž¡àžàžµà¹à¹àžà¹àžªàž£à¹àž²àžàž¥àž³àžàž±àžàžàž±à¹àžàž§àž¥àžµ  
+
+Phind.thesaurus:àžàž·à¹àž­àžàž­àžàž­àž àžŽàžàž²àžàžšàž±àžàžà¹ (Thesaurus) àžàžµà¹àžàž±àžà¹àžà¹àžà¹àžàž£àž¹àžà¹àžàž Phind à¹àžà¹àžà¹àž£àžàžàž­àž£àžµ etc àžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àž  
+
+Phind.title:à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹à¹àžà¹àž­àžàžŽàžàž²àž¢à¹àž­àžàžªàž²àž£à¹àžà¹àž¥àž°àžàžàž±àž  
+
+Phind.untidy:àžàž£àžžàžàž²àž­àž¢à¹àž²àž¥àžà¹àžà¹àž¡àžàžµà¹àžàž³àž¥àž±àžàžàž³àžàž²àžàž­àž¢àž¹à¹àž­àž­àž  
+
+RecentDocumentsList.desc:àžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàžàžµà¹à¹àžªàžàžàž£àž²àž¢àžàž²àž£à¹àž­àžàžªàž²àž£àžàžµà¹à¹àžàžŽà¹àž¡à¹àž«àž¡à¹àž«àž£àž·àž­à¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžµàžàž²àž£à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àž  
+
+RecentDocumentsList.include_docs_added_since:àž£àž§àž¡à¹àžàžàž²àž°à¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžµàžàž²àž£à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àžàž«àž£àž·àž­à¹àž­àžàžªàž²àž£àžàžµà¹à¹àžàžŽà¹àž¡àž«àž¥àž±àžàžàž²àžàž§àž±àžàžàžµà¹àž£àž°àžàžžà¹àž§à¹ (à¹àžàž£àž¹àžà¹àžàž àžàžàžàžàžàžàž§àž§ àž«àž£àž·àž­ àžàžàžàž-àžàž-àž§àž§)  
+
+RecentDocumentsList.include_most_recently_added:àž£àž§àž¡à¹àžàžàž²àž°à¹àž­àžàžªàž²àž£àžàžµà¹à¹àžàžŽà¹àž¡àž¥à¹àž²àžªàžžàžàžàž²àž¡àžàž³àžàž§àžàžàžµà¹àž£àž°àžàžžà¹àžà¹àž²àžàž±à¹àž à¹àžà¹à¹àžàžàž²àž°à¹àž¡àž·à¹àž­à¹àž¡à¹àž¡àžµàžàž²àž£àž£àž°àžàžžàžà¹àž² include_docs_added_since à¹àž§à¹  
+
+RecentDocumentsList.sort:à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àžà¹àž­àžàžàž²àž£à¹àžà¹à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàž£àž²àž¢àžàž²àž£ àžà¹àž²à¹àž¡à¹àž¡àžµàžàž²àž£àž£àž°àžàžžàžà¹àž²à¹àž§à¹ àž£àž²àž¢àžàž²àž£àžàž°àžàž¹àžàžàž±àžà¹àž£àžµàž¢àžàžàž²àž¡àž§àž±àžàžàžµà¹àžàžµà¹à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àž/à¹àžàžŽà¹àž¡à¹àž­àžàžªàž²àž£  
+
+SectionList.desc:à¹àžà¹àžà¹àžàžµàž¢àž§àžàž±àžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàž£àž²àž¢àžàž²àž£ à¹àžà¹àž£àž§àž¡àžàžžàžàžªà¹àž§àžàžàž­àžà¹àž­àžàžªàž²àž£ (àž¢àžà¹àž§à¹àžàž£àž°àžàž±àžàžàžàžªàžžàž) à¹àžàžàžàž²àž£àž£àž§àž¡à¹àžàžµàž¢àžàžàž±àž§à¹àž­àžàžªàž²àž£àž£àž°àžàž±àžàžàžàžªàžžàž  
+
+Collage.desc:à¹àž­àžà¹àžàž¥à¹àžàžàž°àžàž¹àžà¹àžà¹à¹àžàž·à¹àž­à¹àžªàžàžàž àž²àžàžàž±àžàžàž°àžàž­àžàž£àž¹àžàžàžµà¹àžàžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àž  
+
+Collage.geometry:àžàž­àžà¹àžàžàžàž­àžàžàž·à¹àžàžàž²àžàž àž²àžàžàž±àžàžàž° àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž àžªàž³àž«àž£àž±àžàžàž·à¹àžàžàž²àžàžàžàž²àžàžàž§à¹àž²àž 600 àžàžŽàžà¹àžàž¥à¹àž¥àž°àžªàž¹àž 400 àžàžŽàžà¹àžàž¥ àžà¹àž²àžàž³àž«àžàžàžàž²àžà¹àž£àžàž²àžàžàžŽàžàžàž°à¹àžà¹àž 600x400  
+
+Collage.maxDepth:àž£àž¹àžàžªàž³àž«àž£àž±àžàžàž²àž£àžàž°àžàžŽàžàžàž¹àžàž§àž²àžàžàž²àžàžàž²àž£àžàž³àž¡àžŽà¹àž£àž­àž£à¹àžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàžàž²àž£à¹àž£àžµàž¢àžàžàž¹àžàžµà¹àž­àž¢àž¹à¹à¹àžàžàž³à¹àž«àžà¹àžàžà¹àž³àžàž§à¹àž² àžàž¶à¹àžàžàž°àžàž§àžàžàžžàž¡àž£àž°àžàž±àžàžàž§àž²àž¡àž¥àž¶àžàžªàžžàžàžàž­àžàžàž£àž°àžàž§àžàžàž²àž£àžàž³àž¡àžŽà¹àž£àž­àž£à¹  
+
+Collage.maxDisplay:àžàž³àžàž§àžàž£àž¹àžàžªàž¹àžàžªàžžàžàžàžµà¹àžàž°à¹àžªàžàžà¹àžàž àž²àžàžàž±àžàžàž°à¹àžà¹àž§àž¥àž²àž«àžàž¶à¹àž  
+
+Collage.imageType:à¹àžà¹à¹àžàž·à¹àž­àžàž§àžàžàžžàž¡àžàžàžŽàžàžàž­àžà¹àžà¹àž¡àžàžµà¹à¹àžà¹à¹àžàž àž²àžàžàž±àžàžàž°à¹àžàž¢àžàž²àž£à¹àžªàžàžàžàž²àž¡àžªàžàžžàž¥àžàž­àžàžàž·à¹àž­à¹àžà¹àž¡ àž£àž²àž¢àžàž²àž£àžàž­àžàžàž²àž¡àžªàžàžžàž¥àžàž·à¹àž­à¹àžà¹àž¡àžàž°àžàž¹àžà¹àžà¹àžà¹àžàž¢àžªàž±àžàž¥àž±àžàž©àžà¹à¹àžàž­àž£à¹à¹àžà¹àžàžà¹ (%%)  
+
+Collage.bgcolor:àžªàžµàžàž·à¹àžàž«àž¥àž±àžàžàž­àžàžàž·à¹àžàžàž²àžàž àž²àžàžàž±àžàžàž°àžàžµà¹àž£àž°àžàžžà¹àžàž£àž¹àžà¹àžàžà¹àž¥àžàžàž²àžàžªàžŽàžàž«àž (àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž #008000 àžàž°à¹àžªàžàžàžàž·à¹àžàž«àž¥àž±àžà¹àžà¹àžàžªàžµà¹àžàžµàž¢àž§à¹àžà¹ (forest green)  
+
+Collage.buttonname:àžà¹àž²àž¢àžàž·à¹àž­àžªàž³àž«àž£àž±àžàž«àžà¹àž²àžàž­àžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àž à¹àž¥àž°àžàžžà¹àž¡à¹àžà¹àžàžàžàž³àžàž²àž  
+
+Collage.refreshDelay:àž­àž±àžàž£àž²àžàžµà¹àžàž·à¹àžàžàž²àžàž àž²àžàžàž°àžà¹àž­àžàž°à¹àžªàžàžàžàž¥à¹àž«àž¡à¹ (refresh) à¹àžàž¢àž¡àžµàž«àžà¹àž§àž¢à¹àžà¹àžàž¡àžŽàž¥àž¥àžŽàž§àžŽàžàž²àžàžµ  
+
+Collage.isJava2:à¹àžà¹à¹àžàž·à¹àž­àžàž§àžàžàžžàž¡àžàž²àž£à¹àž¥àž·àž­àžà¹àžà¹àžàž¥àž²àžªàž£àž±àžà¹àžàž¡à¹ (run-time) àžàž­àžàžàž²àž§àž² àžàž²àž§àž²à¹àžàž£àžžà¹àžàžàžµà¹àžªàž¹àžàžàž§à¹àž² (à¹àžà¹àž àžàž²àž§àž² 1.2 àžàž¶à¹àžà¹àž) àžàž°àž¡àžµàžàž²àž£àžªàžàž±àžàžªàžàžžàžàžàž²àž£àžàž§àžàžàžžàž¡àžàž§àž²àž¡à¹àžàž£à¹àžà¹àžªàžàžàž­àžàž àž²àžàžàžµà¹àž¥àž°à¹àž­àžµàž¢àžàžàž¶à¹àž àžªàžàž²àžàž°àžàžµà¹àžàž°àžà¹àž§àž¢àžàž§àžàžàžžàž¡àžªàžŽà¹àžàžà¹àž²àžà¹ àžàžµà¹à¹àžàžŽàžàžàž¶à¹àž àž­àž¢à¹àž²àžà¹àž£àžà¹àžàž²àž¡ àžàž²àž§àž²àž£àž±àžà¹àžàž¡à¹àžàžµà¹àž¡àžµàž­àž¢àž¹à¹à¹àžà¹àžàž£àž²à¹àžàž­àž£à¹ (built-in) àžàž²àžàžàž±àž§àžàž°à¹àžà¹àžàž£àžžà¹àž 1.1 à¹àžàž¢àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžà¹àž¥à¹àž§ à¹àž­àžà¹àžàž¥à¹àžàžàž°àžàž¹àžàž­àž­àžà¹àžàžàž¡àž²à¹àž«à¹àžàž£àž§àžàžªàž­àžàž£àžžà¹àžàžàž­àžàžàž²àž§àž²àžàžµà¹à¹àžàž£àž²à¹àžàž­àž£à¹à¹àž£àžµàž¢àžà¹àžà¹àžàž²àžà¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽ à¹àž¥àž°àžàž³àžàž²àžàž­àž¢à¹àž²àžàžªàž­àžàžàž¥à¹àž­àžàžàž±àž  
+
+Collage.imageMustNotHave:à¹àžà¹à¹àžàž·à¹àž­àž¢àž±àžàž¢àž±à¹àžàž£àž¹àžàžàžµà¹à¹àž¡à¹àžàž§àž£àžàž£àž²àžàžà¹àžàž àž²àžàžàž±àžàžàž° à¹àžà¹àž àžàžžà¹àž¡àž£àž¹àžàžàžµà¹àžàž£àž°àžàž­àžàžàž¶à¹àžà¹àžà¹àžà¹àžàžàžàž³àžàž²àž  
+
+Collage.caption:àžàž³àž­àžàžŽàžàž²àž¢àžàž¶à¹àžà¹àžà¹àžàžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹àžàž°à¹àžªàžàžà¹àžà¹àžàž·à¹àžàžàž²àžàž àž²àžàžàž±àžàžàž°  
+
+
+#
+# Plugin option descriptions
+#
+AcronymExtractor.adding:àžàž²àž£à¹àžàžŽà¹àž¡  
+
+AcronymExtractor.already_seen:àžàžà¹àž¥à¹àž§  
+
+AcronymExtractor.desc:àžàž¥àž±à¹àžàž­àžŽàž Helper Extractor àžªàž³àž«àž£àž±àžàžàž³à¹àž«àžà¹àžà¹àž¥àž°àžàž²àž£àž¡àž²àž£à¹àžàž­àž±àžàžàž±àž§àž¢à¹àž­à¹àžàžà¹àž­àžàž§àž²àž¡  
+
+AcronymExtractor.done_acronym_extract:àžàž³àžàž²àž£àžàž±àžàžàž­àžàžàž±àž§àž¢à¹àž­à¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§  
+
+AcronymExtractor.done_acronym_markup:àžàž³àž¡àž²àž£à¹àžàž­àž±àžàžàž±àž§àž¢à¹àž­à¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§  
+
+AcronymExtractor.extract_acronyms:àžàž±àžàžàž­àžàžàž±àž§àž¢à¹àž­àžàž²àžàž àž²àž¢à¹àžàžà¹àž­àžàž§àž²àž¡ à¹àž¥àž°àžàž±à¹àžàžà¹àž²à¹àžà¹àžà¹àž¡àžàž²àžàž²àžàž²  
+
+AcronymExtractor.extracting_acronyms:àžàž²àž£àžàž±àžàžàž­àžàžàž±àž§àž¢à¹àž­  
+
+AcronymExtractor.marking_up_acronyms:à¹àžªà¹àžà¹àž²àžàž±àž§àž¢à¹àž­  
+
+AcronymExtractor.markup_acronyms:à¹àžàžŽà¹àž¡à¹àž¡àžàž²àžàž²àžàž²àžàž±àž§àž¢à¹àž­àž¥àžà¹àžàžà¹àž­àžàž§àž²àž¡à¹àž­àžàžªàž²àž£  
+
+ArchivesInfPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àž­à¹àž²àžàžà¹àž²àžà¹àžà¹àž¡ archives.inf (à¹àžà¹àž¡àžàžµà¹àžªàž£à¹àž²àžà¹àžà¹àžà¹àž£àžàžàž­àž£àžµàžà¹àž­àž¡àž¹àž¥àžàž±àžà¹àžà¹àžàžàž²àž§àž£à¹àž¡àž·à¹àž­à¹àžªàž£à¹àžàžªàžŽà¹àžàžàž²àž£àžàž³à¹àžà¹àž²) à¹àž¥àž°àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡à¹àžà¹àž¥àž°à¹àžà¹àž¡àžàžµà¹àžàž  
+
+AutoExtractMetadata.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàž·à¹àžàžàž²àžàžàžµà¹àž£àž§àž¡à¹àž­àž²àž«àžà¹àž²àžàžµà¹àžàž²àž£àžàž³àžàž²àžàžàž±à¹àžàž«àž¡àžàžàž²àžàžàž¥àž±à¹àžàž­àžŽàž Extractor à¹àžà¹àž²àžà¹àž§àž¢àžàž±àž  
+
+AutoExtractMetadata.extracting:àžàž²àž£àžàž±àžàžàž­àž  
+
+AutoExtractMetadata.first:àž£àž²àž¢àžàž²àž£àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àžàžàž­àžàžàžàž²àžà¹àž£àžàžàžµà¹àžàž°àžàž±àžàžàž­àžàžàž²àžàžà¹àž­àžàž§àž²àž¡à¹àžà¹àžªà¹à¹àž§à¹à¹àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž² à¹àžàžàžà¹àž­àž¡àž¹àž¥àžàžµà¹à¹àž£àžµàž¢àžàž§à¹àž² 'FirstNNN'  
+
+BaseMediaConverter.desc:àžàž¥àž±à¹àžàž­àžŽàž Helper àžàžµà¹àžàž±àžà¹àžàž£àžµàž¢àž¡àž«àžà¹àž²àžàžµà¹àžàž²àž£àžàž³àžàž²àžàžàž·à¹àžàžàž²àžàžªàž³àž«àž£àž±àžàžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžà¹à¹àžàž¥àžàžªàž·à¹àž­àžà¹àž²àžà¹ à¹àžà¹àž ImageConverter à¹àž¥àž°àžàž±àž§à¹àžàž¥àžà¹àžà¹àž¡àž§àžŽàžàžµà¹àž­  
+
+BasePlugin.associate_ext:àžàž³à¹àž«à¹à¹àžà¹àž¡àžàž¶à¹àžàž¡àžµàžàž·à¹àž­à¹àžà¹àž¡àžàžµà¹àž¡àžµàž£àž²àžà¹àžàžµàž¢àž§àžàž±àžàžàž±àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž³àž¥àž±àžàžàž¹àžàžàž£àž°àž¡àž§àž¥àžàž¥àžà¹àž§àž¢àžàž¥àž±à¹àžàž­àžŽàž à¹àž¥àž°àžàž²àž¡àžªàžàžžàž¥àžàž­àžàžàž·à¹àž­à¹àžà¹àž¡àžàž²àžàž£àž²àž¢àžàž²àž£àžàžµà¹àžàž±à¹àžàžà¹àž­àž¡àž¹àž¥àžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àžàžàž¶à¹àžà¹àžà¹àžàž²àžàž­àž²àž£à¹àžàžŽàž§à¹àž¡àžàžà¹àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž³àž¥àž±àžàžàž£àž°àž¡àž§àž¥àžàž¥à¹àžàžàžàž²àž£àžàž±àžàžàž²àž£à¹àžà¹àžàž£àž²àž¢àžàž²àž£à¹àž¢àžàžà¹àž²àžàž«àž²àž  
+
+BasePlugin.associate_tail_re:àžàžŽàžàžàžà¹àžàžàžàžŽàžàžµà¹à¹àžà¹à¹àžàžµàž¢àžàžàž·à¹àž­à¹àžà¹àž¡à¹àž«à¹àžàž£àžàžàž±àžà¹àžàž·à¹àž­àžà¹àžàž«àž²à¹àžà¹àž¡àžàžµà¹àž¡àžµàžàž§àž²àž¡àžªàž±àž¡àžàž±àžàžà¹àžàž±àž à¹àžà¹àžàžàž²àžà¹àž¥àž·àž­àžàžàžµà¹àž¡àžµàžàž§àž²àž¡àžªàž²àž¡àž²àž£àžàž¡àž²àžàžàž§à¹àž² associate_ext  
+
+BasePlugin.block_exp:à¹àžà¹àž¡àžàžµà¹àžàž£àžàžàž±àžàžàžŽàžàžàžà¹àžàžàžàžŽàžàžµà¹àžàž°àžàž¹àžàžà¹àž­àžàžàž±àžà¹àž¡à¹à¹àž«à¹àžàž¹àžàžªà¹àžàžà¹àž­à¹àžàž¢àž±àžàžàž¥àž±à¹àžàž­àžŽàžàžàž±àžà¹àžà¹àžàž£àž²àž¢àžàž²àž£ àžàž²àž£àžàž£àž°àžàž³à¹àžà¹àžàžàžµà¹àžàž°à¹àž¡à¹àžªà¹àžàžàž¥à¹àžà¹ àžàž­àžàžàž²àžà¹àžàž·à¹àž­à¹àžà¹àžàžàž²àž£àžà¹àž­àžàžàž±àžà¹àž¡à¹à¹àž«à¹à¹àžàžŽàžàžà¹àž­àžàž§àž²àž¡à¹àžàž·àž­àžà¹àžàžµà¹àž¢àž§àžàž±àžà¹àžà¹àž¡àžà¹àž­àž¡àž¹àž¥àžàž³à¹àžà¹àž²àžàž³àžàž§àžàž¡àž²àžàžàžµà¹àžàžžàžàž­àž²àžàžàž°à¹àž¡à¹à¹àžà¹àžªàžà¹àž àžàž¥àž±à¹àžàž­àžŽàžà¹àžà¹àž¥àž°àžàž±àž§àž­àž²àžàž¡àžµ block_exp à¹àž£àžŽà¹àž¡àžà¹àž à¹àžà¹àž à¹àžàž¢àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžà¹àž¥à¹àž§ HTMLPlugin àžàž°àžà¹àž­àžàžàž±àžà¹àžà¹àž¡à¹àžà¹ àžàžµà¹àž¡àžµàžàž²àž¡àžªàžàžžàž¥ .gif, .jpg, .jpeg, .png àž«àž£àž·àž­ .css  
+
+BasePlugin.desc:àžàž¥àž²àžªàžàž·à¹àžàžàž²àžàžªàž³àž«àž£àž±àžàžàž¥àž±à¹àžàž­àžŽàžàžàž³à¹àžà¹àž²àžàž±à¹àžàž«àž¡àž  
+
+BasePlugin.dummy_text:à¹àž¡à¹àž¡àžµàžà¹àž­àžàž§àž²àž¡à¹àžà¹ à¹àžà¹àž­àžàžªàž²àž£àžàžµà¹  
+
+BasePlugin.encoding.ascii:àž£àž«àž±àžªà¹àž­àžªàžàžµà¹àžàž 7 àžàžŽàžàž­àž¢à¹àž²àžà¹àžàžµàž¢àž§ àžàž¶à¹àžàž­àž²àžàžàž°à¹àž£à¹àž§àžàž§à¹àž²à¹àžà¹ iso_8859_1 à¹àž¥à¹àžàžà¹àž­àž¢ à¹àžàž£àžàž£àž°àž§àž±àžà¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£à¹àž¥àž·àž­àžà¹àžà¹àž£àž«àž±àžªàžàžµà¹ à¹àžàž·à¹àž­àžàžàž²àžàžà¹àž­àžàž§àž²àž¡àž­àž²àžàžàž£àž°àžàž­àžàžà¹àž§àž¢àž­àž±àžàžàž£àž°àžàžµà¹àž­àž¢àž¹à¹àžàž­àžà¹àž«àžàž·àž­àž£àž«àž±àžªà¹àž­àžªàžàžµà¹àžàž 7 àžàžŽàžàž­àž¢à¹àž²àžà¹àžàžµàž¢àž§ (à¹àžà¹àž àžà¹àž­àžàž§àž²àž¡àžàžµà¹à¹àžà¹àžàž àž²àž©àž²à¹àž¢àž­àž£àž¡àž±àžàž«àž£àž·àž­àžàž£àž±à¹àžà¹àžšàžªàžàžµà¹àž¡àžµàžàž±àž§à¹àžà¹àžà¹àžªàžµàž¢àž) àž«àž²àžà¹àžà¹àžàžàž£àžàžµàžàžµà¹ à¹àž«à¹à¹àžà¹ iso_8859_1 à¹àžàž  
+
+BasePlugin.encoding.unicode:à¹àžà¹àžàžàžµàž¢àžà¹àžà¹ Unicode  
+
+BasePlugin.encoding.utf8:utf8 àž«àž£àž·àž­ Unicode à¹àžàž¢àž£àž°àžàžàžàž°àžàž£àž§àžàžàž±àžà¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽ  
+
+BasePlugin.filename_encoding:àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàž·à¹àž­à¹àžà¹àž¡àžàž­àžà¹àžà¹àž¡àžà¹àžàžàžàž±àž  
+
+BasePlugin.filename_encoding.auto:àžàž£àž§àžàžàž±àžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàž­àžàžàž·à¹àž­à¹àžà¹àž¡à¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽ  
+
+BasePlugin.filename_encoding.auto_language_analysis:àžàž£àž§àžàžàž±àžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàž·à¹àž­à¹àžà¹àž¡à¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽàžà¹àž§àž¢àžàž²àž£àž§àžŽà¹àžàž£àž²àž°àž«à¹àžàž·à¹àž­à¹àžà¹àž¡  
+
+BasePlugin.filename_encoding.auto_filesystem_encoding:àžàž£àž§àžàžàž±àžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàž·à¹àž­à¹àžà¹àž¡à¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽà¹àžàž¢à¹àžà¹àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàž­àžàž£àž°àžàžà¹àžà¹àž¡  
+
+BasePlugin.filename_encoding.auto_fl:à¹àžà¹àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàž­àžàž£àž°àžàžà¹àžà¹àž¡àžàž²àž¡àžà¹àž§àž¢àžàž²àž£àž§àžŽà¹àžàž£àž²àž°àž«à¹àž àž²àž©àž²à¹àžàž·à¹àž­àžàž£àž§àžàžàž±àžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàž·à¹àž­à¹àžà¹àž¡  
+
+BasePlugin.filename_encoding.auto_lf:à¹àžà¹àžàž²àž£àž§àžŽà¹àžàž£àž²àž°àž«à¹àž àž²àž©àž²àžàž²àž¡àžà¹àž§àž¢àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàž­àžàž£àž°àžàžà¹àžà¹àž¡à¹àžàž·à¹àž­àžàž£àž§àžàžàž±àžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàž·à¹àž­à¹àžà¹àž¡  
+
+BasePlugin.no_blocking:àžàž£àžžàžàž²àž­àž¢à¹àž²àžàž³à¹àžàžŽàžàžàž²àž£àžàž¥à¹àž­àžà¹àžà¹àž¡à¹àžà¹ à¹àžà¹àž¡àžàžµà¹à¹àžàžµà¹àž¢àž§àžà¹àž­àžà¹àžà¹ (à¹àžà¹àž àž£àž¹àžàž àž²àžà¹àžà¹àž§à¹àžà¹àžàž) àžàž°àžàž¹àžà¹àžàžŽà¹àž¡à¹àžà¹àž²à¹àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžà¹àžà¹àžàžµàž¢àž§àžàž±àžà¹àž­àžàžªàž²àž£àž­àž·à¹àžà¹  
+
+BasePlugin.no_cover_image:àžàž£àžžàžàž²àž­àž¢à¹àž²àž¡àž­àžàž«àž²à¹àžà¹àž¡ prefix.jpg (àžàž¶à¹àžàžàž³àžàž³àž«àžà¹àž²à¹àžà¹àžàžàž³à¹àžàžµàž¢àž§àžàž±àžà¹àžà¹àž¡àžàžµà¹àžàž³àž¥àž±àžàžàž¹àžàžàž£àž°àž¡àž§àž¥àžàž¥) à¹àž¥àž°àžàž³àž¡àž²à¹àžà¹àžàž£àž¹àžàž«àžà¹àž²àžàž  
+
+BasePlugin.OIDtype.auto:à¹àžà¹àžàžžàž OIDtype à¹àž import.pl  
+
+BasePlugin.process_exp:àžàžŽàžàžàžà¹àžàžàžàžŽàžàž­àžàž àž²àž©àž² Perl àžàžµà¹àžªàž­àžàžàž¥à¹àž­àžàžàž±àžàžàž·à¹àž­à¹àžà¹àž¡ àžàž·à¹àž­à¹àžà¹àž¡àžàžµà¹àžàž£àžàžàž±àžàžàž°àžàž¹àžàžàž£àž°àž¡àž§àž¥àžàž¥àžà¹àž§àž¢àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹ àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž àžàž²àž£à¹àžà¹ '(?i).html?\$' àžàž°àžàž£àžàžàž±àžà¹àž­àžàžªàž²àž£àžàž±à¹àžàž«àž¡àžàžàžµà¹àž¥àžàžà¹àž²àž¢àžà¹àž§àž¢ .htm àž«àž£àž·àž­ .html (à¹àž¡à¹à¹àž¢àžà¹àž¢àž°àžàž±àž§àžàžŽàž¡àžà¹à¹àž«àžà¹-à¹àž¥à¹àž)  
+
+BasePlugin.smart_block:àžàž¥à¹àž­àžà¹àžà¹àž¡àžà¹àž§àž¢àž§àžŽàžàžµàžàž²àž£àžàžµà¹àžàžªàžàžàž¥àž²àžàžàž§à¹àž²àžàž²àž£àžàž¹àžàžµà¹àžàž·à¹àž­à¹àžà¹àž¡à¹àžàžµàž¢àžàž­àž¢à¹àž²àžà¹àžàžµàž¢àž§  
+
+BasePlugin.stems:àž£àž²àžàžšàž±àžàžà¹  
+
+BasePlugin.file_rename_method:à¹àž¡àžàž­àžàžàžµà¹à¹àžà¹à¹àžàžàž²àž£àžàž±à¹àžàžàž·à¹àž­à¹àž«àž¡à¹à¹àž«à¹àžàž±àžàžªàž³à¹àžàž²àžàž­àžà¹àžà¹àž¡àžàžµà¹àžàž³à¹àžà¹àž²à¹àž¥àž°à¹àžà¹àž¡àžàžµà¹àž¡àžµàžàž§àž²àž¡àžªàž±àž¡àžàž±àžàžà¹àžàž±àž  
+
+BasePlugin.rename_method.url:à¹àžà¹àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžª url à¹àžàžàž²àž£àžàž±à¹àžàžàž·à¹àž­à¹àž«àž¡à¹à¹àž«à¹àžàž±àžà¹àžà¹àž¡àžàžµà¹à¹àžà¹àžàž³à¹àžà¹àž²à¹àž¥àž°à¹àžà¹àž¡àžàžµà¹à¹àžàžµà¹àž¢àž§àžà¹àž­àž  
+
+BasePlugin.rename_method.base64:à¹àžà¹àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžª base64 à¹àžàžàž²àž£àžàž±à¹àžàžàž·à¹àž­à¹àž«àž¡à¹à¹àž«à¹àžàž±àžà¹àžà¹àž¡àžàžµà¹à¹àžà¹àžàž³à¹àžà¹àž²à¹àž¥àž°à¹àžà¹àž¡àžàžµà¹à¹àžàžµà¹àž¢àž§àžà¹àž­àž  
+
+BasePlugin.rename_method.none:à¹àž¡à¹àžàž±à¹àžàžàž·à¹àž­à¹àž«àž¡à¹à¹àž«à¹àžàž±àžà¹àžà¹àž¡àžàžµà¹à¹àžà¹àžàž³à¹àžà¹àž²à¹àž¥àž°à¹àžà¹àž¡àžàžµà¹à¹àžàžµà¹àž¢àž§àžà¹àž­àž  
+
+BibTexPlugin.desc:BibTexPlugin àžàž°àž­à¹àž²àžà¹àžà¹àž¡àžàž£àž£àžàž²àžàžžàžàž£àž¡à¹àžàž£àž¹àžà¹àžàž BibTex à¹àž¥àž°àžàž°àžªàž£à¹àž²àžàž§àž±àžàžàžžà¹àž­àžàžªàž²àž£àžªàž³àž«àž£àž±àžàžàžžàžàžàž²àž£àž­à¹àž²àžàž­àžŽàžà¹àžà¹àžà¹àž¡ à¹àžàž¢ BibTexPlugin à¹àžà¹àžàžàž¥àž²àžªàž¢à¹àž­àž¢àžàž­àž SplitTextFile àžàž±àžàžàž±à¹àž àžà¹àž²àž¡àžµàž«àž¥àž²àž¢àž£àž°à¹àžàžµàž¢àž àž£àž°àžàžàžàž°àž­à¹àž²àžàž£àž°à¹àžàžµàž¢àžà¹àž«àž¥à¹àž²àžàž±à¹àžàžàž±à¹àžàž«àž¡àž  
+
+BookPlugin.desc:àžªàž£à¹àž²àžà¹àž­àžàžªàž²àž£àž«àž¥àž²àž¢àž£àž°àžàž±àžàžàž²àžà¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžµà¹àžà¹àžàž£àž°àžàž±àž <<TOC>>  à¹àž¡àžàž²àžàž²àžàž²àžàž­àžà¹àžà¹àž¥àž°àžªà¹àž§àžàžàž°àžàž¹àžàžàž¶àžàžàž²àžà¹àžà¹àžàž­àž·à¹àžà¹ à¹àžàžàž£àž£àžàž±àžà¹àžàžµàž¢àž§àžàž±àžàžàž±àž <<TOC>> à¹àžà¹àž <<Title>>xxxx<</Title>> àžàž°àžàž±à¹àžàžà¹àž²à¹àž¡àžàž²àžàž²àžàž² 'àžàž·à¹àž­à¹àž£àž·à¹àž­àž' àžà¹àž­àž¡àž¹àž¥àž­àž·à¹àžà¹ àž£àž°àž«àž§à¹àž²àžà¹àžà¹àž TOC àžàž°àžàž¹àžàžàž³à¹àžàžŽàžàžàž²àž£à¹àžàž£àž¹àžà¹àžàž HTML àž­àž¢à¹àž²àžàžà¹àž²àž¢ (à¹àž¡à¹àž¡àžµàžàž²àž£àžàž£àž°àž¡àž§àž¥àžàž¥àžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àž HTML àž«àž£àž·àž­àžàž²àž£àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžàž HTMLPlugin) à¹àžà¹àž¡àžà¹àž­àž¡àž¹àž¥à¹àžà¹àž²àžàž§àž£àžàž°àž¡àžµàžàž²àž¡àžªàžàžžàž¥ .hb àžàž²àž¡àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àž (àžàž¶à¹àžàžªàž²àž¡àž²àž£àžà¹àžàž¥àžµà¹àž¢àžà¹àžà¹àžà¹àž§àž¢àžàž²àž£à¹àžà¹àžàž±àž§à¹àž¥àž·àž­àž -process_exp) à¹àžà¹àž¡àžàžµà¹àž¡àžµàžàž·à¹àž­à¹àžàžµàž¢àž§àžàž±àžàžàž±àžà¹àžà¹àž¡ hb à¹àžà¹àž¡àžµàžàž²àž¡àžªàžàžžàž¥ .jpg àžàž°àžàž¹àžàžàž¶àžàž¡àž²à¹àžà¹àžàž£àž¹àžàž«àžà¹àž²àžàž (à¹àžà¹àž¡ jpg àžàž°àžàž¹àžàžàž¥à¹àž­àžàžà¹àž§àž¢àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹)  BookPlugin à¹àžà¹àžàžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž¹àžàžàž³à¹àž«à¹àžà¹àž²àž¢ (à¹àž¥àž°àžàž¢àž²àž¢) àžàž²àž HBPlugin àžàžµà¹à¹àžà¹à¹àžàž¢àžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàž«à¹àž­àžàžªàž¡àžžàžàž¡àžàžžàž©àž¢à¹àžšàž²àžªàžàž£à¹ (Humanity Library) BookPlugin àžàž°àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹à¹àž£à¹àž§àžàž§à¹àž² à¹àžàž·à¹àž­àžàžàž²àžàž£àž°àžàžàžàž²àžàž§à¹àž²à¹àžà¹àž¡àžà¹àž­àž¡àž¹àž¥à¹àžà¹àž²àžàž°àž¡àžµàžàž§àž²àž¡à¹àžà¹àžàž£àž°à¹àžàžµàž¢àžàžàž§à¹àž² (àžà¹àž­àž¡àž¹àž¥àžàžµà¹à¹àžà¹àž²à¹àžàž¢àž±àžàžàž­àž¥à¹àž¥àžàžàž±àž HDL àžàž°àž¡àžµà¹àžà¹àž HTML à¹àžàžàž³àžàž§àžàžàžµà¹àž¡àž²àžà¹àžàžŽàžàž­àž¢àž¹à¹àž£àž­àžà¹ à¹àžà¹àž <<TOC>> à¹àžà¹à¹àžà¹àž <<I>> à¹àžàž·à¹àž­àž£àž°àžàžžàž àž²àž à¹àž¥àž°àžàž¶àžàžà¹àž­àžàž§àž²àž¡àžàž±à¹àžàž«àž¡àžàžàžµà¹àž­àž¢àž¹à¹àž£àž°àž«àž§à¹àž²àžà¹àžà¹àž <<TOC>> à¹àž¥àž°àžàžžàžà¹àž£àžŽà¹àž¡àžà¹àžàžàž­àžàžà¹àž­àžàž§àž²àž¡àž¡àž²à¹àžà¹àžà¹àž¡àžàž²àžàž²àžàž² 'àžàž·à¹àž­à¹àž£àž·à¹àž­àž') àžà¹àž²àžàžžàžàžàž³àž¥àž±àžàžàž£àž±àžà¹àžà¹àžà¹àž­àžàžªàž²àž£à¹àžàž·à¹àž­à¹àž«à¹à¹àžªàžàžà¹àžàž£àž¹àžà¹àžàžà¹àžàžµàž¢àž§àžàž±àžàžàž±àžàžàž­àž¥à¹àž¥àžàžàž±àž HDL à¹àž«à¹à¹àžà¹àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžàž HBPlugin  
+
+CONTENTdmPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž³à¹àžàžŽàžàžàž²àž£àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡ RDF à¹àžàžàž­àž¥à¹àž¥àžàžàž±àž CONTENTdm àžàžµà¹àžªà¹àžàž­àž­àž  
+
+ConvertBinaryFile.apply_fribidi:à¹àž£àžµàž¢àžà¹àžà¹à¹àžàž£à¹àžàž£àž¡àž­àž±àž¥àžàž­àž£àžŽàžàž¶àž¡ Unicode à¹àžàžàžªàž­àžàžàžŽàžšàžàž²àž "fribidi" àžàž±àžà¹àžà¹àž¡àžàžµà¹à¹àžàž¥àžà¹àž¥à¹àž§ (àžªàž³àž«àž£àž±àžàžà¹àž­àžàž§àž²àž¡àžàž²àžàžàž§àž²à¹àžàžà¹àž²àž¢)  
+
+ConvertBinaryFile.convert_to:àžàž¥àž±à¹àžàž­àžŽàžàžàž°à¹àžàž¥àžà¹àž«à¹à¹àžà¹àž TEXT àž«àž£àž·àž­ HTML àž«àž£àž·àž­àž£àž¹àžàžàžàžŽàžàžà¹àž²àžà¹ (à¹àžà¹àž JPEG, GIF, PNG)  
+
+ConvertBinaryFile.convert_to.auto:à¹àž¥àž·àž­àžàž£àž¹àžà¹àžàžàžàž¥àž²àž¢àžàž²àžàžàžµà¹àžà¹àž­àžàžàž²àž£à¹àžàž¥àžà¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽ àž£àž¹àžà¹àžàžàžàžµà¹à¹àž¥àž·àž­àžàžàž¶à¹àžàž­àž¢àž¹à¹àžàž±àžàžàžàžŽàžàžàž­àžà¹àž­àžàžªàž²àž£àžà¹àž² àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž Word àžàž°àžàž¹àžà¹àžàž¥àžà¹àž«à¹à¹àžà¹àž HTML à¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽ à¹àžàžàžàž°àžàžµà¹ PowerPoint àžàž°àžàž¹àžà¹àžàž¥àžà¹àž«à¹àž­àž¢àž¹à¹à¹àžàž£àž¹àžà¹àžàž PagedImage àžàž­àžà¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàž  
+
+ConvertBinaryFile.convert_to.html:àž£àž¹àžà¹àžàž HTML  
+
+ConvertBinaryFile.convert_to.text:àž£àž¹àžà¹àžàžàžà¹àž­àžàž§àž²àž¡àž­àž¢à¹àž²àžà¹àžàžµàž¢àž§  
+
+ConvertBinaryFile.convert_to.pagedimg:àžàžžàžàžàž­àžàž£àž¹àžàž àž²àž  
+
+ConvertBinaryFile.convert_to.pagedimg_jpg:àž£àž¹àžà¹àžàž JPEG  
+
+ConvertBinaryFile.convert_to.pagedimg_gif:àž£àž¹àžà¹àžàž GIF  
+
+ConvertBinaryFile.convert_to.pagedimg_png:àž£àž¹àžà¹àžàž PNG  
+
+ConvertBinaryFile.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžà¹àž£àž±àžàžªàž·àžàžàž­àžàž¡àž²à¹àžàž¢àžàž¥àž±à¹àžàž­àžŽàžàžà¹àž²àžà¹ à¹àžà¹àž WordPlugin, PowerPointPlugin, PostscriptPlugin, RTFPlugin à¹àž¥àž° PDFPlugin àžàž¥àž±à¹àžàž­àžŽàžàžàž°àžà¹àž§àž¢à¹àžàž¥àžàžàžàžŽàžàžàž­àžà¹àž­àžàžªàž²àž£à¹àž«àž¥à¹àž²àžàžµà¹à¹àžà¹àž HTML, TEXT àž«àž£àž·àž­àžàžžàžàžàž­àžàž£àž¹àž àžàž¥àž±à¹àžàž­àžŽàžàžàž°àžàž³àžàž²àžàžà¹àž§àž¢àžàž²àž£à¹àž«àž¥àžàžàž¥àž±à¹àžàž­àžŽàžàž£àž­àžàžàžµà¹à¹àž«àž¡àž²àž°àžªàž¡à¹àžàžà¹àžàžàž²àž¡àžŽàž (HTMLPlugin, StructuredHTMLPlugin, PagedImgPlugin àž«àž£àž·àž­ TEXTPlugin) àžàž¶à¹àžàž­àž¢àž¹à¹àžàž±àžàž­àž²àž£à¹àžàžŽàž§à¹àž¡àžàžà¹àžàž­àžàžàž¥àž±à¹àžàž­àžŽàž 'convert_to'  
+
+ConvertBinaryFile.keep_original_filename:à¹àžà¹àžàžàž·à¹àž­à¹àžà¹àž¡àžàž±à¹àžà¹àžàžŽàž¡àžªàž³àž«àž£àž±àžà¹àžà¹àž¡àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àž à¹àžàžàžàž²àž£à¹àžàž¥àžà¹àž«à¹à¹àžà¹àž doc.pdf, doc.doc à¹àžà¹àžàžà¹àž  
+
+ConvertBinaryFile.use_strings:àžà¹àž²àž¡àžµàžàž²àž£àžàž±à¹àžàžà¹àž²à¹àž§à¹ àžàž±àžàžà¹àžàž±àžàžªàžàž£àžŽàžàž­àž¢à¹àž²àžàžà¹àž²àž¢àžàž°àžàž¹àžà¹àž£àžµàž¢àžà¹àžàž·à¹àž­àžàž±àžàžàž­àžàžà¹àž­àžàž§àž²àž¡àžà¹àž²à¹àžàž£à¹àžàž£àž¡àž­àž£àž£àžàžàž£àž°à¹àž¢àžàžà¹àžàž²àž£à¹àžàž¥àžà¹àž¡à¹àžàž³àžàž²àž  
+
+ConvertToRogPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àž£àž±àžàžªàž·àžàžàž­àžàžàž²àž RogPlugin.  
+
+CSVPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžà¹àžà¹àž¡à¹àžàž£àž¹àžà¹àžàžàžà¹àž²àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àž à¹àž­àžàžªàž²àž£à¹àž«àž¡à¹àžàž°àžàž¹àžàžªàž£à¹àž²àžà¹àž«à¹àžàž±àžà¹àžà¹àž¥àž°àžàž£àž£àžàž±àžàžàž­àžà¹àžà¹àž¡  
+
+DateExtractor.desc:àžàž¥àž±à¹àžàž­àžŽàž Helper extractor àžªàž³àž«àž£àž±àžàžàž²àž£àžàž¶àžàžà¹àž­àž¡àž¹àž¥àž§àž±àžàžàžµà¹àžàž²àžàžàž£àž°àž§àž±àžàžŽàžšàž²àžªàžàž£à¹àžàž²àžàžà¹àž­àžàž§àž²àž¡  
+
+DateExtractor.extract_historical_years:àžàž±àžàžàž­àžàžà¹àž­àž¡àž¹àž¥àžà¹àž§àžà¹àž§àž¥àž²àžàž²àžà¹àž­àžàžªàž²àž£à¹àžàžŽàžàžàž£àž°àž§àž±àžàžŽàžšàž²àžªàžàž£à¹ à¹àžàž¢àžà¹àž²àžàžµà¹àžàž°àžàž¹àžàžàž±àžà¹àžà¹àžà¹àžà¹àžà¹àž¡àžàž²àžàž²àžàž²àžàž£à¹àž­àž¡à¹àž­àžàžªàž²àž£ à¹àž¥àž°àžàž°àž¡àžµàž«àžà¹àž²àžàž­àžà¹àžàž«àž²àžªàž³àž«àž£àž±àžà¹àž¡àžàž²àžàž²àžàž²àžàžµà¹ àžàž¶à¹àžàžàžžàžàžªàž²àž¡àž²àž£àžàž£àž§àž¡à¹àžà¹àž²à¹àžà¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàžàžžàžà¹àžà¹ à¹àžàž¢à¹àžàžŽà¹àž¡àžà¹àž­àžàž§àž²àž¡ "format QueryInterface DateSearch" àž¥àžà¹àžà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž²àžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàžàžžàž  
+
+DateExtractor.maximum_century:àžà¹àž²àžªàž¹àžàžªàžžàžàžàž­àžàžšàžàž§àž£àž£àž©àžàžµà¹àžàž°àžàž¹àžàžàž±àžàžàž­àžà¹àžà¹àžà¹àž¡àžàž²àžàž²àžàž²à¹àžàžŽàžàžàž£àž°àž§àž±àžàžŽàžšàž²àžªàžàž£à¹ (à¹àžà¹àž 14 àžàž°àžàž±àžàžàž­àžàžàž²àž£àž­à¹àž²àžàž­àžŽàžàžàž±à¹àžàž«àž¡àžàžàžàžàž¶àžàžšàžàž§àž£àž£àž©àžàžµà¹ 14)  
+
+DateExtractor.maximum_year:àžà¹àž²àžªàž¹àžàžªàžžàžàžàž­àžàž§àž±àžàžàžµà¹à¹àžàžŽàžàžàž£àž°àž§àž±àžàžŽàžšàž²àžªàžàž£à¹àžàžµà¹àžàž°à¹àžà¹à¹àžà¹àžà¹àž¡àžàž²àžàž²àžàž² (àž£àž¹àžà¹àžàžàž§àž±àžàžàžµà¹à¹àžàžàžàž£àžŽàžªàžàžšàž±àžàž£àž²àž à¹àžà¹àž 1950)  
+
+DateExtractor.no_bibliography:àžàž£àžžàžàž²àž­àž¢à¹àž²àžàž¢àž²àž¢àž²àž¡àžàž¥à¹àž­àžàž§àž±àžàžàžµà¹à¹àžàžŽàžàžàž£àž£àžàž²àžàžžàžàž£àž¡àžàžàž°àžàž±àžàžàž­àžàž§àž±àžàžàžµà¹à¹àžàžŽàžàžàž£àž°àž§àž±àžàžŽàžšàž²àžªàžàž£à¹  
+
+DirectoryPlugin.desc:RecPlug à¹àžà¹àžàžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àž§àžàžà¹àž³à¹àžà¹àžà¹àž£àžàžàž­àž£àžµà¹àžàž·à¹àž­àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡à¹àžà¹àž¥àž°à¹àžà¹àž¡àžàžµà¹àžàž  
+
+DirectoryPlugin.recheck_directories:àž«àž¥àž±àžàžàž²àžàžàžµà¹à¹àžà¹àž¡à¹àžà¹àžà¹àž£àžàžàž­àž£àžµàžàž³à¹àžà¹àž²àžàž¹àžàžàž£àž°àž¡àž§àž¥àžàž¥à¹àž¥à¹àž§ à¹àž«à¹àž­à¹àž²àžà¹àžà¹àž£àžàžàž­àž£àžµàž­àžµàžàžàž£àž±à¹àžà¹àžàž·à¹àž­àžà¹àžàž«àž²à¹àžà¹àž¡à¹àž«àž¡à¹àž­àž·à¹àžà¹ àžàžµà¹àžªàž£à¹àž²àžàžàž¶à¹àž  
+
+DirectoryPlugin.use_metadata_files:(àžàž±àžàžà¹àž²àž - à¹àžàžŽà¹àž¡ MetadataXMLPlug àž¥àžà¹àžàž£àž²àž¢àžàž²àž£àžàž¥àž±à¹àžàž­àžŽàžà¹àžàž) àž­à¹àž²àžà¹àž¡àžàž²àžàž²àžàž²àžàž²àžà¹àžà¹àž¡ XML à¹àž¡àžàž²àžàž²àžàž²  
+
+DatabasePlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž³à¹àžà¹àž²àž£àž°à¹àžàžµàž¢àžàžàž²àžàžàž²àžàžà¹àž­àž¡àž¹àž¥ àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž°à¹àžà¹à¹àž¡àžàž¹àž¥ DBI àžàž­àž perl àžàž¶à¹àžàž£àž§àž¡àžàž¶àžà¹àžà¹àžà¹àž­à¹àžàžà¹àžªàž³àž«àž£àž±àž mysql, postgresql, àžà¹àž²àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àž (CSV), MS Excel, ODBC, sybase à¹àž¥àž°àž­àž·à¹àžà¹ àžàžžàžàž­àž²àžàžàž³à¹àžà¹àžàžà¹àž­àžàžàžŽàžàžàž±à¹àžà¹àž¡àžàž¹àž¥àžàžŽà¹àžšàž©à¹àžàž·à¹àž­à¹àžà¹àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹ àžªàž³àž«àž£àž±àžàžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž² à¹àž«à¹àžàž¹àžàžµà¹ <GSDLHOME>/etc/packages/example.dbi  
+
+DSpacePlugin.desc:DSpacePlug àžàž°àž£àž±àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžà¹àž­àžàžªàž²àž£àžàžµà¹àžªà¹àžàž­àž­àžàžàž²àž DSpace àž¡àž² à¹àž¥àž°àžàž³à¹àžà¹àž²àžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¥à¹àž²àžàž±à¹àžà¹àžà¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàž  
+	
+DSpacePlugin.first_inorder_ext:àž£àž°àžàžàžàž°à¹àžà¹àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžàž·à¹àž­àž£àž°àžàžžàžàž£àž°à¹àžªàžà¹àž­àž¡àž¹àž¥àž«àž¥àž±àžàžàž­àžà¹àž­àžàžªàž²àž£à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àž Dspace àžà¹àž§àž¢àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹ àž£àž°àžàžàžàž°àžàž³à¹àžàžŽàžàžàž²àž£àžàž±àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž³àž«àžàžàžàžàžŽàžà¹àžà¹àž ext àžàž²àž¡àž¥àž³àžàž±àžà¹àžàž·à¹àž­àžà¹àžàž«àž²àžàž£àž°à¹àžªàžà¹àž­àž¡àž¹àž¥àž«àž¥àž±àžàžàžµà¹à¹àžà¹àžà¹àžà¹àžà¹  
+
+DSpacePlugin.first_inorder_mime:àž£àž°àžàžàžàž°à¹àžà¹àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžàžàž²àž£àž£àž°àžàžžàžàž£àž°à¹àžªàžà¹àž­àž¡àž¹àž¥àž«àž¥àž±àžàžàž­àžà¹àž­àžàžªàž²àž£à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àž Dspace àžà¹àž§àž¢àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹ àž£àž°àžàžàžàž°àžàž³à¹àžàžŽàžàžàž²àž£àžàž±àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž³àž«àžàžàžàžàžŽàžà¹àžà¹àž mimeàžàž²àž¡àž¥àž³àžàž±àžà¹àžàž·à¹àž­àžà¹àžàž«àž²àžàž£àž°à¹àžªàžà¹àž­àž¡àž¹àž¥àž«àž¥àž±àžàžàžµà¹à¹àžà¹àžà¹àžà¹àžà¹  
+
+DSpacePlugin.only_first_doc:àž£àž°àžàžàžàž°à¹àžà¹àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžàžàž²àž£àž£àž°àžàžžàžàž£àž°à¹àžªàžà¹àž­àž¡àž¹àž¥àž«àž¥àž±àžàžàž­àžà¹àž­àžàžªàž²àž£à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àž Dspace àžà¹àž§àž¢àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹ àž£àž°àžàžàžàž°àžàžàžŽàžàž±àžàžŽàžàž±àžà¹àž­àžàžªàž²àž£à¹àž£àžà¹àžà¹àžà¹àž¡à¹àž¡àžàž²àžàž²àžàž² dublic_core à¹àžà¹àžàžàž£àž°à¹àžªàžà¹àž­àž¡àž¹àž¥àž«àž¥àž±àžàžàžµà¹à¹àžà¹àžà¹àžà¹àžà¹  
+
+EmailAddressExtractor.desc:àžàž¥àž±à¹àžàž­àžŽàž Helper extractor àžªàž³àž«àž£àž±àžàžàž²àž£àžà¹àžàžàžàžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥à¹àžàžà¹àž­àžàž§àž²àž¡  
+
+EmailAddressExtractor.done_email_extract:àžàž³àžàž²àž£àžàž±àžàžàž­àžàžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥à¹àž£àžµàž¢àžàž£à¹àž­àž¢à¹àž¥à¹àž§  
+
+EmailAddressExtractor.extracting_emails:àžàž²àž£àžàž±àžàžàž­àžàžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥  
+
+EmailAddressExtractor.extract_email:àžàž±àžàžàž­àžàžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥à¹àžà¹àžà¹àž¡àžàž²àžàž²àžàž²  
+
+EmailPlugin.desc:Email plug àžàž°àžàž³àžàž²àž£àž­à¹àž²àžà¹àžà¹àž¡àž­àžµà¹àž¡àž¥  àžàž¶à¹àžàžàž°àžàž¹àžàžàž±à¹àžàžàž·à¹àž­àžà¹àž§àž¢àžàž±àž§à¹àž¥àžàžà¹àž²àž¢à¹ (à¹àžà¹àž àžàž±àžàžàžµà¹àžàž£àž²àžàžà¹àžà¹àžàž¥à¹àžàž­àž£à¹ maildir) àž«àž£àž·àž­à¹àžàž¢àž¡àžµàžàž²àž¡àžªàžàžžàž¥ .mbx (àžªàž³àž«àž£àž±àžàž£àž¹àžà¹àžàžà¹àžà¹àž¡à¹àž¡àž¥ mbox) \nàžà¹àž­àžàž§àž²àž¡à¹àž­àžàžªàž²àž£: àžà¹àž­àžàž§àž²àž¡à¹àž­àžàžªàž²àž£àžàž£àž°àžàž­àžàžà¹àž§àž¢àžà¹àž­àžàž§àž²àž¡àžàž±à¹àžàž«àž¡àžàž«àž¥àž±àžàžàž£àž£àžàž±àžàž§à¹àž²àžàžàž£àž£àžàž±àžà¹àž£àžà¹àžà¹àž­àžàžªàž²àž£\nà¹àž¡àžàž²àžàž²àžàž² (à¹àž¡à¹à¹àžà¹àžàž±àžàž¥àžŽàžàžàž­àž£à¹!):\n\t\$Headers      à¹àžàž·à¹àž­àž«àž²àžªà¹àž§àžàž«àž±àž§àžàž±à¹àžàž«àž¡àž (à¹àžà¹àžàžàž±àž§à¹àž¥àž·àž­àž à¹àž¥àž°à¹àžàž¢àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžà¹àž¥à¹àž§àžàž°à¹àž¡à¹àž¡àžµàžàž²àž£àžàž±àžà¹àžà¹àž)\n\t\$Subject      à¹àž£àž·à¹àž­àž: àžªà¹àž§àžàž«àž±àž§\n\t\$To           àžàž¶àž: àžªà¹àž§àžàž«àž±àž§\n\t\$From         àžàž²àž: àžªà¹àž§àžàž«àž±àž§\n\t\$FromName     àžàž·à¹àž­àžàž­àžàžàž¹à¹àžªà¹àž (àžà¹àž²àž¡àžµ)\n\t\$FromAddr     àžàžµà¹àž­àž¢àž¹à¹àž­àžµà¹àž¡àž¥àžàž­àžàžàž¹à¹àžªà¹àž\n\t\$DateText     àž§àž±àžàžàžµà¹: àžªà¹àž§àžàž«àž±àž§\n\t\$Date         àž§àž±àžàžàžµà¹: àžªà¹àž§àžàž«àž±àž§à¹àžàž£àž¹àžà¹àžàž GSDL (à¹àžà¹àž 19990924)  
+
+EmailPlugin.no_attachments:àžàž£àžžàžàž²àž­àž¢à¹àž²àžàž±àžàžàž¶àžàžªàžŽà¹àžàžàžµà¹à¹àžàžàž¡àž²àžàž±àžàžà¹àž­àžàž§àž²àž¡  
+
+EmailPlugin.headers:àžàž±àžà¹àžà¹àžàžªà¹àž§àžàž«àž±àž§àž­àžµà¹àž¡àž¥à¹àžà¹àžà¹àž¡àžàž²àžàž²àžàž² "Headers"  
+
+EmailPlugin.OIDtype.message_id:à¹àžà¹àžàž±àž§àž£àž°àžàžžàžà¹àž­àžàž§àž²àž¡à¹àžà¹àž OID àžàž­àžà¹àž­àžàžªàž²àž£ àžà¹àž²àž£àž°àžàžà¹àž¡à¹àžàžàžàž±àž§àž£àž°àžàžžà¹àž­àžàžªàž²àž£ àž£àž°àžàžàžàž°à¹àžà¹à¹àž®àž OID à¹àžàž  
+
+EmailPlugin.split_exp:àžàžŽàžàžàžà¹àžàžàžàžŽàžàž­àžàž àž²àž©àž² Perl àžàžµà¹à¹àžà¹à¹àžà¹àžà¹àžà¹àž¡àžàžµà¹àž¡àžµàžà¹àž­àžàž§àž²àž¡àžàž³àžàž§àžàž¡àž²àžàž¥àžà¹àžà¹àž­àžàžªàž²àž£à¹àž¢àžà¹àžà¹àž¥àž°àžàžàž±àž  
+
+ExcelPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžàžàž²àž£àžàž³à¹àžà¹àž²à¹àžà¹àž¡ Microsoft Excel (àž£àžžà¹àž 95 à¹àž¥àž° 97)  
+
+FavouritesPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžà¹àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡àž£àž²àž¢àžàž²àž£à¹àžàž£àžàžàž­àž Internet Explorer  
+
+FOXPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžà¹àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡àžàž²àžàžà¹àž­àž¡àž¹àž¥ dbt àžàž­àž Foxbase àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àž¡àžµàžàž±àžàžà¹àžàž±àžàžàž·à¹àžàžàž²àžàžàžµà¹à¹àžà¹àž­à¹àž²àžà¹àžà¹àž¡ dbt à¹àž¥àž° dbf à¹àž¥àž°àžàž£àž°àž¡àž§àž¥àžàž¥àž£àž°à¹àžàžµàž¢àžà¹àžà¹àž¥àž°àžàž±àž§  àžàž¥àž±à¹àžàž­àžŽàžàžàž±à¹àž§à¹àžàžàžµà¹àžàž§àž£àžàž¹àžà¹àžàžàžàžµà¹à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£à¹àžà¹àžàž²àžàžà¹àž­àž¡àž¹àž¥à¹àžàžàž²àž°à¹àžàž·à¹àž­àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžàžàžà¹àž­àž¡àž¹àž¥àžàžµà¹à¹àž«àž¡àž²àž°àžªàž¡à¹àžà¹àžà¹àž¡  
+
+GreenstoneXMLPlugin.desc:àžàž£àž°àž¡àž§àž¥àžàž¥à¹àž­àžàžªàž²àž£ XML àžàžµà¹à¹àžà¹àžàžàž²àž§àž£àžàž­àžà¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàž à¹àžàž£àžàžªàž±àžà¹àžàžàž§à¹àž² àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àž¡à¹àž¡àžµàžàž²àž£àžàž£àž§àžàžªàž­àžà¹àž§àž¢àž²àžàž£àžà¹ (à¹àžà¹à¹àž¡àžàž¹àž¥ XML::Parser àžàž°àžàž£àž§àžàžªàž­àžàž£àž¹àžà¹àžàžàžàžµà¹àžàž¹àžàžà¹àž­àž) à¹àžàž¢àžàž°àžàž·àž­àž§à¹àž²à¹àžà¹àž¡àžàž±àžà¹àžà¹àžàžàž²àž§àž£àžàž­àžà¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàžà¹àžà¹àžà¹àžàžàž²àž¡ DTD àžàž­àžà¹àž­àžàžªàž²àž£ XMLàžàž±à¹àž  
+
+GISExtractor.desc:àžàž¥àž²àžªàžàž·à¹àžàžàž²àžàžàž­àž (on-the-side) BasPlug àžàžµà¹àžªàžàž±àžàžªàžàžžàžàžàž§àž²àž¡àžªàž²àž¡àž²àž£àžàžàž²àžàžà¹àž²àž GIS  
+
+GISExtractor.extract_placenames:àžàž±àžàžàž­àžàžàž·à¹àž­àžàž³à¹àž«àžà¹àž (placenames) àžàž²àžàž àž²àž¢à¹àžàžà¹àž­àžàž§àž²àž¡ à¹àž¥àž°àžàž±à¹àžàžà¹àž²à¹àžà¹àžà¹àž¡àžàž²àžàž²àžàž² àžàž³à¹àžà¹àžàžà¹àž­àžàž¡àžµàžàž²àž¡àžªàžàžžàž¥ GIS à¹àž«à¹àžàž±àž Greenstone  
+
+GISExtractor.gazetteer:Gazetteer à¹àžà¹à¹àžàž·à¹àž­àžàž±àžàžàž­àžàžàž·à¹àž­àžàž³à¹àž«àžà¹àž (placenames) àžàž²àžàž àž²àž¢à¹àžàžà¹àž­àžàž§àž²àž¡ à¹àž¥àž°àžàž±à¹àžàžà¹àž²à¹àž«à¹à¹àžà¹àžà¹àž¡àžàž²àžàž²àžàž² àžàž³à¹àžà¹àžàžà¹àž­àžàž¡àžµàžàž²àž¡àžªàžàžžàž¥ GIS à¹àž«à¹àžàž±àž Greenstone  
+
+GISExtractor.place_list:à¹àž¡àž·à¹àž­àžàž³àžàž²àž£àžàž±àžàžàž­àžàžàž²àž£àž§àž²àžàžàž³à¹àž«àžà¹àž à¹àž«à¹àž£àž§àž¡àž£àž²àž¢àžàž²àž£àžàž·à¹àž­àžàž³à¹àž«àžà¹àžà¹àž§à¹àžàžµà¹àžªà¹àž§àžàžà¹àžàžàž­àžà¹àž­àžàžªàž²àž£àžà¹àž§àž¢ àžàž³à¹àžà¹àžàžà¹àž­àžàž¡àžµàžàž²àž¡àžªàžàžžàž¥ GIS à¹àž«à¹àžàž±àž Greenstone  
+
+HBPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž£àžàžàž­àž£àžµàž«àžàž±àžàžªàž·àž­ HTML  àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž°àžàž¹àžà¹àžà¹à¹àžàž¢àžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàž«à¹àž­àžàžªàž¡àžžàžàž¡àžàžžàž©àž¢àžšàž²àžªàžàž£à¹ (Humanity Library) à¹àž¥àž°àžàž°à¹àž¡à¹àžàž±àžàžàž²àž£àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàž³à¹àžà¹àž²àž­àž·à¹àžà¹ àžàž­àžàžàž²àžà¹àž­àžªàžàžµàž«àž£àž·àž­à¹àž­àžªàžàžµà¹àžàžàžàž¢àž²àž¢ à¹àžà¹àžàžàžµà¹à¹àžàžµàž¢àžà¹àžà¹à¹àž¡à¹àžàžµàžàž±àž à¹àž¥àž°à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàž³à¹àž«à¹àžàž³àžàž²àžà¹àž£à¹àž§àžàž¶à¹àžà¹àžà¹ àžà¹àž§àž¢àžàž²àž£àžàž¥à¹àž­àž¢à¹àž«à¹àž­àž¢àž¹à¹àžªàžàž²àžàž°à¹àžà¹àžàžàžµà¹ àžàž±àžàž­àž¢àž²àžàžàž°à¹àžàžŽàžàžàž§àžà¹àž«à¹àžàžžàžà¹ àžàžàžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàžàžà¹àž­àžà¹àžàž¢à¹àžà¹ BookPlugin à¹àžàž ;-)\n\nà¹àž«à¹à¹àžà¹ BookPlugin àžà¹àž²àžà¹àž­àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àž«àž¡à¹ à¹àž¥àž°àžà¹àž­àžàžàž²àž£àžàž£àž±àžà¹àžà¹àžà¹àžà¹àž¡à¹àž«à¹à¹àž«àž¡àž·àž­àžàžàž±àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàž«à¹àž­àžàžªàž¡àžžàžàž¡àžàžžàž©àž¢àžšàž²àžªàžàž£à¹ (Humanity Library) BookPlugin àž¢àž­àž¡àž£àž±àžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžà¹àž­àž¡àž¹àž¥àžàž³à¹àžà¹àž²à¹àžà¹àžàžžàžà¹àžàž à¹àžà¹àžàž²àžàž«àž§àž±àžà¹àž«à¹à¹àžà¹àž¡àžàžµà¹àžàž£àž±àžà¹àžà¹àžàž¡àžµàžàž§àž²àž¡à¹àžà¹àžàž£àž°à¹àžàžµàž¢àžàžàž§à¹àž²à¹àžà¹àž¡àžàžµà¹à¹àžà¹à¹àžàž¢àžàž­àž¥à¹àž¥àžàžàž±àžàžàž­àžàž«à¹àž­àžàžªàž¡àžžàžàž¡àžàžžàž©àž¢àžšàž²àžªàžàž£à¹ (Humanity Library)  
+
+HBPlugin.encoding.iso_8859_1:Latin1 (àž àž²àž©àž²àžàž°àž§àž±àžàžàž)  
+
+HTMLImagePlugin.aggressiveness:àžà¹àž§àžàžàž­àžà¹àžàžàžàžŽàžàžàž²àž£àžàž±àžàžàž­àžàžà¹àž­àžàž§àž²àž¡àžàžµà¹à¹àžàžµà¹àž¢àž§àžà¹àž­àžàžàžµà¹àžà¹àž­àžàžàž²àž£à¹àžà¹  
+HTMLImagePlugin.aggressiveness.1:àžàž·à¹àž­à¹àžà¹àž¡ à¹àžªà¹àžàžàž²àž àžà¹àž­àžàž§àž²àž¡ ALT à¹àžà¹àž²àžàž±à¹àž  
+HTMLImagePlugin.aggressiveness.2:àžà¹àž² 1 àžàž±à¹àžàž«àž¡àž àž£àž§àž¡àžàž³àž­àžàžŽàžàž²àž¢ àžà¹àž²àž¡àžµ  
+HTMLImagePlugin.aggressiveness.3:àžà¹àž² 2 àžàž±à¹àžàž«àž¡àž àž£àž§àž¡àž¢à¹àž­àž«àžà¹àž²à¹àžàž¥à¹à¹àžàžµàž¢àž àžà¹àž²àž¡àžµ  
+HTMLImagePlugin.aggressiveness.4:àžà¹àž² 3 àžàž±à¹àžàž«àž¡àž àž£àž§àž¡àžªà¹àž§àžàž«àž±àž§àžàž±à¹àžàž«àž¡àžàžà¹àž­àžàž«àžà¹àž² (<h1>, <h2>...) àžà¹àž²àž¡àžµ  
+HTMLImagePlugin.aggressiveness.5:àžà¹àž² 4 àžàž±à¹àžàž«àž¡àž àž£àž§àž¡àžàž²àž£àž­à¹àž²àžàž­àžŽàžàžàžµà¹à¹àžà¹àžàžà¹àž­àžàž§àž²àž¡ àžà¹àž²àž¡àžµ  
+HTMLImagePlugin.aggressiveness.6:àžà¹àž² 4 àžàž±à¹àžàž«àž¡àž àž£àž§àž¡à¹àž¡àžàž²à¹àžà¹àžàžàž­àžàž«àžà¹àž² (àžàž·à¹àž­à¹àž£àž·à¹àž­àž àžàž³àžªàž³àžàž±àž à¹àž¥àž°àž­àž·à¹àžà¹)  
+HTMLImagePlugin.aggressiveness.7:àžà¹àž² 6, 5 à¹àž¥àž° 4 àžàž±à¹àžàž«àž¡àžàž£àž§àž¡àžàž±àž  
+HTMLImagePlugin.aggressiveness.8:àžà¹àž² 7 àžàž±à¹àžàž«àž¡àž àž£àž§àž¡àžàž³àž­àžàžŽàžàž²àž¢àžà¹àž³ àžàž·à¹àž­à¹àžà¹àž¡ à¹àž¥àž°àž­àž·à¹àžà¹ (àž¢àžàž£àž°àžàž±àžàžàž±à¹àžàžàž­àžàžàž¥àž¥àž±àžàžà¹àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àžàž¡àž²àžàžàž§à¹àž²)  
+HTMLImagePlugin.aggressiveness.9:àžà¹àž² 1 àžàž±à¹àžàž«àž¡àž àž£àž§àž¡àžà¹àž­àžàž§àž²àž¡àžàžàž±àžà¹àžà¹àž¡àžàž­àžàž«àžà¹àž²àžà¹àžàžàžàž±àž  
+
+HTMLImagePlugin.caption_length:àžàž§àž²àž¡àž¢àž²àž§àžªàž¹àžàžªàžžàžàžàž­àžàžàž³àž­àžàžŽàžàž²àž¢ (àž«àžà¹àž§àž¢à¹àžà¹àžàž­àž±àžàžàž£àž°)  
+
+HTMLImagePlugin.convert_params:àžàž²àž£àž²àž¡àžŽà¹àžàž­àž£à¹à¹àžàžŽà¹àž¡à¹àžàžŽàž¡àžªàž³àž«àž£àž±àž ImageMagicK àžàž¶à¹àžà¹àžàž¥àžàžàžàžàž²àž£àžªàž£à¹àž²àžàž£àž¹àžàžàžàž²àžàž¢à¹àž­  àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž '-raise' àžàž°àžªà¹àžàžàž¥àžà¹àž­àž£àž¹àžàžàžµà¹à¹àžà¹àžàž£àž¹àžàžàžàž²àžàž¢à¹àž­à¹àžàžàžªàž²àž¡àž¡àžŽàžàžŽ  
+
+HTMLImagePlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžàžàž²àž£àžàž±àžàžàž­àžàž£àž¹àž à¹àž¥àž°àžà¹àž­àžàž§àž²àž¡àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àžàžàž²àžàž«àžà¹àž²à¹àž§à¹àž  
+
+HTMLImagePlugin.document_text:à¹àžàžŽà¹àž¡àžà¹àž­àžàž§àž²àž¡àžàžµà¹à¹àžà¹àžàž£àž¹àžà¹àž«à¹à¹àžà¹àž à¹àž­àžàžªàž²àž£:àžà¹àž­àžàž§àž²àž¡ (à¹àž¡à¹à¹àžà¹àžàžàž±à¹àž à¹àž«à¹à¹àžà¹à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž² IndexedText)  
+
+HTMLImagePlugin.index_pages:àžàž±àžàžàž³àžàž±àžàžàžµàž«àžà¹àž²àžàž£à¹àž­àž¡àžà¹àž§àž¢àž£àž¹àž à¹àž¡à¹à¹àžà¹àžàžàž±à¹àžà¹àž«à¹àžàž³àžàž²àž£àž­à¹àž²àžàž­àžŽàžàž«àžà¹àž²àžàžµà¹ URL àžàž­àžàžà¹àžàžàžàž±àž  
+
+HTMLImagePlugin.max_near_text:àžàž³àžàž§àžàž­àž±àžàžàž£àž°àžªàž¹àžàžªàžžàžàžàžµà¹àž­àž¢àž¹à¹à¹àžàž¥à¹àž£àž¹àžàžàžµà¹àžà¹àž­àžàžàž²àž£àžàž±àžàžàž­àž  
+
+HTMLImagePlugin.min_height:àžàžŽàžà¹àžàž¥ à¹àž«à¹àžà¹àž²àž¡àž£àž¹àžàžàžµà¹àžªàž±à¹àžàžàž§à¹àž²àžàžµà¹  
+
+HTMLImagePlugin.min_near_text:àžàž³àžàž§àžàž­àž±àžàžàž£àž°àžà¹àž³àžªàžžàžàžàž­àžàžà¹àž­àžàž§àž²àž¡àž«àž£àž·àž­àžàž³àž­àžàžŽàžàž²àž¢à¹àžàž¥à¹à¹àžàžµàž¢àžàžàžµà¹àžà¹àž­àžàžàž²àž£àžàž±àžàžàž­àž  
+
+HTMLImagePlugin.min_size:à¹àžàžà¹  à¹àž«à¹àžà¹àž²àž¡àž£àž¹àžàžàžµà¹àž¡àžµàžàžàž²àžà¹àž¥à¹àžàžàž§à¹àž²àžàžµà¹  
+
+HTMLImagePlugin.min_width:àžàžŽàžà¹àžàž¥  à¹àž«à¹àžà¹àž²àž¡àž£àž¹àžàžàžµà¹à¹àžàžàžàž§à¹àž²àžàžµà¹  
+
+HTMLImagePlugin.neartext_length:àžàž§àž²àž¡àž¢àž²àž§àžàžµà¹àžàž³àž«àžàžàžàž­àžàžà¹àž­àžàž§àž²àž¡à¹àžàž¥à¹à¹àžàžµàž¢àž (àž«àžà¹àž§àž¢à¹àžà¹àžàž­àž±àžàžàž£àž°)  
+
+HTMLImagePlugin.no_cache_images:àžàž£àžžàžàž²àž­àž¢à¹àž²à¹àžà¹àžàž£àž¹àžà¹àž§à¹à¹àžà¹àžàž (à¹àž«à¹àžàžµà¹à¹àžàžàžµà¹ URL àžàž­àžàž£àž¹àžàžàž±à¹àžà¹àžàžŽàž¡)  
+
+HTMLImagePlugin.smallpage_threshold:àž£àž¹àžàžàžµà¹àž­àž¢àž¹à¹àžàžàž«àžà¹àž²àžàžµà¹àž¡àžµàžàžàž²àžà¹àž¥à¹àžàžàž§à¹àž²àžàžµà¹ (à¹àžàžà¹) àžàž°àž¡àžµàžàž²àž£à¹àžàžŽà¹àž¡à¹àž¡àžàž²àžàž²àžàž²àžàž­àžàž«àžà¹àž² (àžàž·à¹àž­à¹àž£àž·à¹àž­àž àžàž³àžªàž³àžàž±àž à¹àž¥àž°àž­àž·à¹àžà¹) àžà¹àž§àž¢  
+
+HTMLImagePlugin.textrefs_threshold:àžàž­àžà¹àžàžàžàžµà¹àžàž³àž«àžàžàžªàž³àž«àž£àž±àžàžàž²àž£àž­à¹àž²àžàž­àžŽàžà¹àžàžàžà¹àž­àžàž§àž²àž¡ àžà¹àž²àžà¹àž­àž¢àž«àž¡àž²àž¢àžàž§àž²àž¡àž§à¹àž²àž­àž±àž¥àžàž­àž£àžŽàžàž¶àž¡à¹àžà¹àž¡àžàž§àžàžà¹àž­àž¢  
+
+HTMLImagePlugin.thumb_size:àžàžàž²àžà¹àž«àžà¹àžàžµà¹àžªàžžàžàžàž­àžàž£àž¹àžàžàžàž²àžàž¢à¹àž­ àžàž±à¹àžàžàž§àž²àž¡àžàž§à¹àž²àžà¹àž¥àž°àžàž§àž²àž¡àžªàž¹àž  
+
+HTMLPlugin.assoc_files:àžàžŽàžàžàžà¹àžàžàžàžŽàžàž­àžàž àž²àž©àž² Perl àžàž­àžàžàž²àž¡àžªàžàžžàž¥à¹àžà¹àž¡àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àžà¹àž­àžàžªàž²àž£ html  
+
+HTMLPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž°àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡ HTML  
+
+HTMLPlugin.description_tags:à¹àž¢àžà¹àž­àžàžªàž²àž£à¹àž«à¹à¹àžà¹àžàžªà¹àž§àžàž¢à¹àž­àž¢àžàžµà¹à¹àžà¹àž <Section> àžàž°àžàž£àž²àžàžàž¶à¹àž '-keep_head' àžàž°à¹àž¡à¹àž¡àžµàžàž¥à¹àžà¹ à¹àž¡àž·à¹àž­àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹àžàž¹àžàžàž±à¹àžàžà¹àž²à¹àž§à¹  
+
+HTMLPlugin.extract_style:àžàž±àžàžàž­àžàžà¹àž­àž¡àž¹àž¥àž£àž¹àžà¹àžàžà¹àž¥àž°àžªàžàž£àžŽàžàžà¹àž­àž­àžàžàž²àžà¹àžà¹àž <head> HTML à¹àž¥àž°àžàž±àžàžàž¶àžà¹àžà¹àžà¹àž¡àžàž²àžàž²àžàž² DocumentHeader àžàž¶à¹àžàžàž°àžàž¹àžàžàž±à¹àžàžà¹àž²à¹àž§à¹à¹àžàž«àžà¹àž²à¹àž­àžàžªàž²àž£à¹àžà¹àžà¹àž¡à¹àžàž£ _document:documentheader_  
+
+HTMLPlugin.file_is_url:à¹àžà¹àž£àž±àžàžàž²àž£àžàž±à¹àžàžà¹àž² àžà¹àž²àžàž·à¹àž­à¹àžà¹àž¡àžàž³à¹àžà¹àž²à¹àžà¹àžà¹àžàžŽàž¡ url àžàž­àžà¹àž­àžàžªàž²àž£àžà¹àžàžàžàž±àžà¹àžàžŽàž¡ à¹àžà¹àž àžà¹àž²àž¡àžµàžàž²àž£à¹àžà¹à¹àžàž£àž·à¹àž­àžàž¡àž·àž­àžàž³àž¡àžŽà¹àž£àž­àž£à¹à¹àž§à¹àžàžªàž£à¹àž²àžà¹àžàž£àžàžªàž£à¹àž²àžà¹àžà¹àž£àžàžàž­àž£àžµàžàž³à¹àžà¹àž²  
+
+HTMLPlugin.hunt_creator_metadata:àžà¹àžàž«àž²à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹à¹àžàžµà¹àž¢àž§àžàž±àžàžàž§àž²àž¡à¹àžà¹àžà¹àžà¹àž²àžàž­àžàžàž¥àžàž²àžà¹àž«à¹àž¡àž²àžàžàžµà¹àžªàžžàžà¹àžà¹àž²àžàžµà¹àžàž°àžàž³à¹àžà¹ à¹àž¥àž°à¹àžªà¹àžà¹àž²àž¥àžà¹àžà¹àžàžàžà¹àž­àž¡àž¹àž¥ 'Creator'  
+
+HTMLPlugin.keep_head:à¹àž¡à¹àžàž§àž£à¹àž­àž²àžªà¹àž§àžàž«àž±àž§àžàž­àžà¹àžà¹àž¡ html àž­àž­àž  
+
+HTMLPlugin.metadata_fields:àž£àž²àž¢àžàž²àž£àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àžàžàžµà¹àžàž°àžàž±àžàžàž­àžàž­àž­àž à¹àžà¹ 'tag<tagname>' à¹àžàž·à¹àž­à¹àžªà¹à¹àžàž·à¹àž­àž«àž²àžàž­àžàžàž¹à¹ <tagname> à¹àž£àžàž¥àžà¹àžàž­àžàžà¹àžàž£àž°àžàž­àžà¹àž¡àžàž²àžàž²àžàž²àžàžµà¹à¹àž£àžµàž¢àžàž§à¹àž² 'tagname'  àžàž³àžà¹àž­àž¡àž¹àž¥à¹àž«à¹à¹àžà¹àžàžàž±àž§àžàžŽàž¡àžà¹à¹àž«àžà¹àžà¹àž²àžàžžàžàžà¹àž­àžàžàž²àž£à¹àž«à¹à¹àž¡àžàž²àžàž²àžàž²à¹àžà¹àžàžàž±àž§àžàžŽàž¡àžà¹à¹àž«àžà¹à¹àžà¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàž à¹àžàž·à¹àž­àžàžàž²àžàžàž²àž£àžàž±àžàžàž­àžà¹àžà¹àžà¹àž¡à¹à¹àž¢àžà¹àž¢àž°àžàž±àž§àžàžŽàž¡àžà¹à¹àž«àžà¹-à¹àž¥à¹àž  
+
+HTMLPlugin.no_metadata:àžàž£àžžàžàž²àž­àž¢à¹àž²àžàž¢àž²àž¢àž²àž¡àžàž±àžàžàž­àžà¹àž¡àžàž²àžàž²àžàž²à¹àžà¹ àž­àž­àžàžàž²àžà¹àžà¹àž¡  
+
+HTMLPlugin.no_strip_metadata_html:àž£àž²àž¢àžàž²àž£àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àžàžàž­àžàžàž·à¹àž­à¹àž¡àžàž²àžàž²àžàž² àž«àž£àž·àž­ 'àžàž±à¹àžàž«àž¡àž'  à¹àž¡àž·à¹àž­à¹àžà¹àžàž±àž -description_tags àžàž°à¹àžà¹àžàžàž²àž£àžà¹àž­àžàžàž±àžàžàž²àž£à¹àž¢àžà¹àžà¹àž HTML àž­àž­àžàžàž²àžàžà¹àž²àžªàž³àž«àž£àž±àžà¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àž£àž°àžàžž  
+
+HTMLPlugin.nolinks:àžàž£àžžàžàž²àž­àž¢à¹àž²àžàž¢àž²àž¢àž²àž¡àžàž±àžàžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àž (àžàž²àž£àžàž±à¹àžàžà¹àž²àžªàžàž²àžàž°àžàžµà¹àž­àž²àžàžà¹àž§àž¢à¹àžàžŽà¹àž¡àžàž§àž²àž¡à¹àž£à¹àž§à¹àžàžàž²àž£àžªàž£à¹àž²àž/àžàž²àž£àžàž³à¹àžà¹àž² à¹àžà¹àžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àžàž àž²àž¢à¹àžà¹àž­àžàžªàž²àž£àžàž°àžàž¹àžàžàž³àž¥àž²àž¢)  
+
+HTMLPlugin.no_image_links:à¹àž¡à¹àžàž¢àž²àž¢àž²àž¡àžàž±àžàžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàž£àž¹àžàž àž²àžà¹àžàž·à¹àž­à¹àž«à¹àžªàž²àž¡àž²àž£àžàžàž¹àž£àž¹àžàž àž²àžà¹àžà¹  
+
+HTMLPlugin.rename_assoc_files:à¹àžàž¥àžµà¹àž¢àžàžàž·à¹àž­à¹àžà¹àž¡àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àžà¹àž­àžàžªàž²àž£ (à¹àžà¹àž àž£àž¹àž) à¹àž¥àž°àžªàž£à¹àž²àžà¹àžàž£àžàžªàž£à¹àž²àžà¹àžà¹àž£àžàžàž­àž£àžµàžàžµà¹àžàž·à¹àžàžàž§à¹àž²àž¡àž²àž (àž¡àžµàžàž£àž°à¹àž¢àžàžà¹à¹àž¡àž·à¹àž­àžà¹àž­àžàžàž²àž£àžªàž£à¹àž²àžàžàž­àž¥à¹àž¥àžàžàž±àžàžªàž³àž«àž£àž±àžàžªà¹àžàž­àž­àžà¹àžàž¢àž±àžàžàžµàžàžµàž£àž­àž¡)  
+
+HTMLPlugin.sectionalise_using_h_tags:àžªàž£à¹àž²àžà¹àž­àžàžªàž²àž£àžàžµà¹à¹àžà¹àžà¹àžà¹àžàžªà¹àž§àžà¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽà¹àžàž¢à¹àžà¹à¹àžà¹àž h1, h2, âŠ hX  
+
+HTMLPlugin.title_sub:àžàžŽàžàžàžà¹àžàž²àž£à¹àžàžàžàžµà¹àžàž¶à¹àžà¹àžà¹à¹àžà¹à¹àžàžªàžàž£àžŽàžàžàžµà¹àžàž±àžà¹àžà¹àžà¹àžà¹àžàžàž·à¹àž­à¹àž£àž·à¹àž­àž àžàž±àž§àž­àž¢à¹àž²àžàžàž²àž£à¹àžà¹ à¹àžà¹àž PDFPlugin à¹àžà¹à¹àžàž·à¹àž­à¹àž­àž² "àž«àžà¹àž² 1" à¹àž¥àž°àž­àž·à¹àžà¹ àž­àž­àžàžàž²àžàžà¹àž­àžàž§àž²àž¡àžàžµà¹à¹àžà¹à¹àžà¹àžàžàž·à¹àž­à¹àž£àž·à¹àž­àž  
+
+HTMLPlugin.tidy_html:àžà¹àž²àž¡àžµàžàž²àž£àžàž±à¹àžàžà¹àž²à¹àž§à¹ àž£àž°àžàžàžàž°àžàž³àžàž²àž£à¹àžàž¥àžà¹àž­àžàžªàž²àž£ HTML à¹àž«à¹àž­àž¢àž¹à¹à¹àžàž£àž¹àžà¹àžàžàžàž­àž XHTML àžàžµà¹àž¡àžµàžàž²àž£àžàž³àž«àžàžàž£àž¹àžà¹àžàžàžàžµà¹àžàžµ àžàž¶à¹àžàžàž°àžàž³à¹àž«à¹àžàž¹à¹à¹àžà¹àžªàž²àž¡àž²àž£àžàžàž¹à¹àž­àžàžªàž²àž£à¹àžàž£àž¹àžà¹àžàžàž«àžàž±àžàžªàž·àž­à¹àžà¹  
+
+HTMLPlugin.old_style_HDL:à¹àžàž·à¹àž­àžàž³à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àž§à¹àž² à¹àžà¹àž¡à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàžµà¹à¹àžà¹àžàž¹àžàžàž±àžà¹àžà¹àžàž­àž­àžà¹àžà¹àžàžªà¹àž§àžà¹ à¹àžàž¢à¹àžà¹àž£àž¹àžà¹àžàžàžªà¹àž§àžàžàž­àž HDL àž£àžžà¹àžà¹àžà¹àž²  
+
+BaseMediaConverter.enable_cache:à¹àžàžà¹àžà¹àž¡àžàžµà¹àžªàž£à¹àž²àžà¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽ (à¹àžà¹àž àž àž²àžàžàžàž²àžà¹àž¥à¹àž àž«àž£àž·àž­àž àž²àžàžàžàž²àžà¹àžà¹àž²àž«àžà¹àž²àžàž­) à¹àžàž·à¹àž­àžàž°à¹àžà¹à¹àž¡à¹àžà¹àž­àžàžªàž£à¹àž²àžàžà¹àž³àž­àžµàž  
+
+ImageConverter.converttotype:à¹àžàž¥àžàž£àž¹àžàž«àž¥àž±àžà¹àž«à¹à¹àžà¹àžàž£àž¹àžà¹àžàž 's'  
+
+ImageConverter.create_screenview:àž«àž²àžàžàž±à¹àžàžà¹àž²à¹àžà¹àž "à¹àžà¹" àž£àž°àžàžàžàž°àžàž³àžàž²àž£àžªàž£à¹àž²àžàž àž²àžàžàžàž²àžà¹àžà¹àž²àžàž­àž àž²àž à¹àž¥àž°àžàž±à¹àžàžà¹àž²à¹àž¡àžàž²àžàž²àžàž²à¹àž«à¹àžàž±àž Screen, ScreenType, screenicon, ScreenWidth à¹àž¥àž° ScreenHeight  
+
+ImageConverter.create_thumbnail:àž«àž²àžàžàž±à¹àžàžà¹àž²à¹àžà¹àž "à¹àžà¹" àž£àž°àžàžàžàž°àžàž³àžàž²àž£àžªàž£à¹àž²àžàž àž²àžàžàžàž²àžà¹àž¥à¹àžà¹àž«à¹àžàž±àžà¹àžà¹àž¥àž°àž àž²àž à¹àž¥àž°à¹àžàžŽà¹àž¡à¹àž¡àžàž²àžàž²àžàž²à¹àž«à¹àžàž±àž Thumb, ThumbType, thumbicon, ThumbWidth à¹àž¥àž°ThumbHeight   
+ImageConverter.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž°àžàž£àž°àž¡àž§àž¥àžàž¥àž£àž¹àž à¹àž¥àž°à¹àžàžŽà¹àž¡à¹àž¡àžàž²àžàž²àžàž²àžàž·à¹àžàžàž²àž  
+
+ImageConverter.imagemagicknotinstalled:àžàžžàžà¹àž¡à¹à¹àžà¹àžàžŽàžàžàž±à¹àž Image Magick  
+
+ImageConverter.minimumsize:àž¥àž°à¹àž§à¹àžàž£àž¹àžàžàžµà¹àž¡àžµàžàžàž²àžà¹àž¥à¹àžàžàž§à¹àž² n à¹àžàžà¹  
+
+ImageConverter.noconversionavailable:à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àž£àžµàž¢àžà¹àžà¹àžàž²àžàžàž²àž£à¹àžàž¥àžàž àž²àžà¹àžà¹  
+
+ImageConverter.noscaleup:à¹àž¡à¹àžàž§àž£àžàž¢àž²àž¢àž£àž¹àžàžàžàž²àžà¹àž¥à¹àžàžàžàž°àžªàž£à¹àž²àžàž£àž¹àžàžàžàž²àžàž¢à¹àž­  
+
+ImageConverter.screenviewsize:àžªàž£à¹àž²àžàž£àž¹àžà¹àžªàžàžàž«àžà¹àž²àžàž­àžà¹àž§àž¢àžàžàž²àž nxn  
+
+ImageConverter.screenviewtype:àžªàž£à¹àž²àžàž£àž¹àžà¹àžªàžàžàž«àžà¹àž²àžàž­à¹àžàž£àž¹àžà¹àžàž 's'  
+
+ImageConverter.thumbnailsize:àžªàž£à¹àž²àžàž£àž¹àžàžàžàž²àžàž¢à¹àž­àžà¹àž§àž¢àžàžàž²àž nxn  
+
+ImageConverter.thumbnailtype:àžªàž£à¹àž²àžàž£àž¹àžàžàžàž²àžàž¢à¹àž­à¹àžàž£àž¹àžà¹àžàž 's'  
+
+ImageConverter.win95notsupported:à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àžà¹àžàž²àž Image Magick àžàž Win95/98 à¹àžà¹  
+
+ImagePlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž°àžàž³àžàž²àž£àžàž£àž°àž¡àž§àž¥àžàž¥àž àž²àž à¹àž¥àž°à¹àžàžŽà¹àž¡à¹àž¡àžàž²àžàž²àžàž²àžàž·à¹àžàžàž²àž  
+
+IndexPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžà¹àžàžàž§àžàžà¹àž³àžàžµà¹àžàž°àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡ index.txt  à¹àžà¹àž¡ index.txt àžàž§àž£àžàž£àž°àžàž­àžàžà¹àž§àž¢àž£àž²àž¢àžàž²àž£àžàž­àžà¹àžà¹àž¡àžàžµà¹àžàž°àž£àž§àž¡àž­àž¢àž¹à¹à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžàžàž²àž¡àžà¹àž§àž¢à¹àž¡àžàž²àžàž²àžàž²àžàžŽà¹àžšàž©à¹àžà¹ àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àžà¹àžà¹àž¥àž°à¹àžà¹àž¡\n\nà¹àžà¹àž¡ index.txt àžàž§àž£àž¡àžµàž£àž¹àžà¹àžàžàžàž±àžàžàžµà¹: àžàž£àž£àžàž±àžà¹àž£àžàž­àž²àžà¹àžà¹àžàžàžµàž¢à¹ (àžàž¶à¹àžàžà¹àžàžà¹àž§àž¢àžàž³àž§à¹àž² key:) à¹àžàž·à¹àž­àžàž³àž«àžàžàžàž·à¹àž­à¹àž«à¹à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž² (à¹àžà¹àž key: Subject Organization Date) àžàž£àž£àžàž±àžàžà¹àž­à¹ à¹àžàžàž°àžàž£àž°àžàž­àžàžà¹àž§àž¢àžàž·à¹àž­à¹àžà¹àž¡àžàž²àž¡àžà¹àž§àž¢àžà¹àž²àžàžµà¹àžàž°àžàž±à¹àžàžà¹àž²àž£àž²àž¢àžàž²àž£à¹àž¡àžàž²àžàž²àžàž² (à¹àžà¹àž 'irma/iw097e 3.2 unesco 1993' àžàž°à¹àžàž·à¹àž­àž¡à¹àž¢àžà¹àž¡àžàž²àžàž²àžàž² Subject=3.2, Organization=unesco à¹àž¥àž° Date=1993 à¹àžà¹àž²àžàž±àžà¹àžà¹àž¡ irma/iw097e àžà¹àž²àž¡àžµàžàž²àž£à¹àžà¹àžàž£àž£àžàž±àžàžàžµàž¢à¹àžà¹àž²àžàžàž)\n\nà¹àžàž£àžàžªàž±àžà¹àžàžàž§à¹àž² àžà¹àž²à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²à¹àžà¹ à¹àžà¹àžàž¥àž±à¹àžàž­àžŽàžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àžàž¥àž³àžàž±àžàžàž±à¹àž àžà¹àž²àžàžµà¹àžàž¹àžàžàž±à¹àžà¹àž§à¹àžàž§àž£àžàž°àžªàž­àžàžàž¥à¹àž­àžàžàž±àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž£àž (àžàž±àž§àž­àžàžŽàžàž²àž¢) à¹àžà¹àžà¹àž¡àžàž²àž£à¹àž¢àžàžàž£àž°à¹àž àžàžàžµà¹à¹àž«àž¡àž²àž°àžªàž¡\n\nàžàžžàžàžªàž²àž¡àž²àž£àžàžàž±à¹àžàžàž·à¹àž­àžà¹àž²à¹àž¡àžàž²àžàž²àžàž²à¹àž¢àžàžà¹àž²àžàž«àž²àžà¹àžà¹à¹àžàž¢à¹àžà¹à¹àžà¹àž (à¹àžà¹àž <Subject>3.2) à¹àž¥àž°àžà¹àž²àžàžµà¹àžàž°à¹àžà¹àž²à¹àžà¹àžàžàžàžµà¹àžàž·à¹àž­à¹àžà¹ àžàžµà¹à¹àžà¹àžàž³àž«àžàžà¹àž§à¹à¹àžàž¢àžàž£àž£àžàž±àžàžàžµàž¢à¹ àžà¹àž²à¹àž¡à¹àž¡àžµàžàž£àž£àžàž±àžàžàžµàž¢à¹ àžà¹àž²à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹à¹àž¡à¹àž¡àžµàžàž²àž£àžàž±à¹àžàžàž·à¹àž­à¹àž§à¹ àžàž°àžàž¹àžàžàž±à¹àžàžàž·à¹àž­à¹àžà¹àž 'Subject'  
+
+ISISPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž°àžàž³àžàž²àž£àžàž£àž°àž¡àž§àž¥àžàž¥àžàž²àžàžà¹àž­àž¡àž¹àž¥ CDS/ISIS àžªàž³àž«àž£àž±àžà¹àžà¹àž¥àž°àžàž²àžàžà¹àž­àž¡àž¹àž¥ CDS/ISIS àžàžµà¹àžàž¹àžàžàž£àž°àž¡àž§àž¥àžàž¥ àžàž°àž¡àžµà¹àžà¹àž¡àžàž³àžàž§àžàžªàž²àž¡à¹àžà¹àž¡àžàž£àž²àžàžàž­àž¢àž¹à¹à¹àžà¹àžàž¥à¹àžàž­àž£à¹àžàž³à¹àžà¹àž²àžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àž: à¹àžà¹àž¡àžà¹àžà¹àžàž (.mst) àžàž²àž£àž²àžàžà¹àž­àžàž³àž«àžàžà¹àžàžàžà¹àž­àž¡àž¹àž¥ (.fdt) à¹àž¥àž°à¹àžà¹àž¡àž­à¹àž²àžàž­àžŽàžà¹àž¢àž (.xrf)  
+
+ISISPlugin.subfield_separator:àžªàžàž£àžŽàžàžàžµà¹à¹àžà¹à¹àž¢àžà¹àžàžàžà¹àž­àž¡àž¹àž¥àž¢à¹àž­àž¢à¹àžàž£àž°à¹àžàžµàž¢àžàžàž²àžàžà¹àž­àž¡àž¹àž¥ CDS/ISIS  
+
+ISISPlugin.entry_separator:àžªàžàž£àžŽàžàžàžµà¹à¹àžà¹à¹àž¢àžàžà¹àž²àžà¹àž²àžà¹ àžªàž³àž«àž£àž±àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²à¹àžàžµà¹àž¢àž§à¹àžàž£àž°à¹àžàžµàž¢àžàžàž²àžàžà¹àž­àž¡àž¹àž¥ CDS/ISIS  
+
+KeyphraseExtractor.desc:àžàž¥àž±à¹àžàž­àžŽàž Helper Extractor àžªàž³àž«àž£àž±àžàžàž²àž£àžªàž£à¹àž²àžàž§àž¥àžµàž«àž¥àž±àžàžàž²àžàžà¹àž­àžàž§àž²àž¡ à¹àžà¹àž£àž°àžàžàžàž²àž£àžàž¶àžàž§àž¥àžµàž«àž¥àž±àžà¹àžàž Kea  
+
+KeyphraseExtractor.extract_keyphrases:àžàž±àžàžàž­àž keyphrases à¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽàžà¹àž§àž¢ Kea (àžàž²àž£àžàž±à¹àžàžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àž)  
+
+KeyphraseExtractor.extract_keyphrases_kea4:àžàž±àžàžàž­àž keyphrases à¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽàžà¹àž§àž¢ Kea 4.0 (àžàž²àž£àžàž±à¹àžàžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àž)  Kea 4.0 àžàž·àž­ Kea àž£àžžà¹àžà¹àž«àž¡à¹àžàžµà¹à¹àžà¹àž£àž±àžàžàž²àž£àžàž±àžàžàž²àžªàž³àž«àž£àž±àžàžàž²àž£àžàž±àžàžàž³àžàž±àžàžàžµà¹àžàžàžàž§àžàžàžžàž¡àžàž­àžà¹àž­àžàžªàž²àž£à¹àžàžàž­àžà¹àžàžàžàž²àžàžà¹àž²àžà¹àžàž©àžàž£àžàž£àž£àž¡  
+
+KeyphraseExtractor.extract_keyphrase_options:àžàž±àž§à¹àž¥àž·àž­àžàžªàž³àž«àž£àž±àžàžàž²àž£àžàž±àžàžàž­àž keyphrase àžà¹àž§àž¢ Kea  àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž mALIWEB - à¹àžà¹à¹àž¡à¹à¹àžàžàžàž²àž£àžàž±àžàžàž­àž ALIWEB; n5 - àžàž±àžàžàž­àž keyphrase 5 àžàž±àž§; eGBK - à¹àžà¹àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžª GBK  
+
+KeyphraseExtractor.keyphrases:keyphrases  
+
+KeyphraseExtractor.missing_kea:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžàžàžàž­àžàžà¹à¹àž§àž£à¹ Kea àžàžµà¹ %s àžàž£àžžàžàž²àžàž²àž§àžà¹à¹àž«àž¥àž Kea %s àžàž²àž http://www.nzdl.org/Kea à¹àž¥àž°àžàžŽàžàžàž±à¹àžàž¥àžà¹àžà¹àžà¹àž£àžàžàž­àž£àžµàžàžµà¹  
+
+LaTeXPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžà¹àž­àžàžªàž²àž£ LaTeX  
+
+LOMPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžàžàž²àž£àžàž³à¹àžà¹àž²à¹àžà¹àž¡ LOM (Learning Object Metadata)  
+
+LOMPlugin.root_tag:DocType àžàž­àžà¹àžà¹àž¡ XML (àž«àž£àž·àž­àžàžŽàžàžàžà¹àžàžàžàžŽàžàžµà¹àžàž£àžàžàž±àžàž­àžàžà¹àžàž£àž°àžàž­àžàž£àž²àž)  
+
+LOMPlugin.check_timestamp:àžàž£àž§àžàžªàž­àžàžàž²àž£àž¥àžàžàž±àžàžàž¶àžà¹àž§àž¥àž²àžàž­àžà¹àžà¹àž¡àžàžµà¹àžàž²àž§àžà¹à¹àž«àž¥àžàžà¹àž­àžàž«àžà¹àž²àžàžµà¹ à¹àž¥àž°àžàž³àžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àžàž­àžµàžàžàž£àž±à¹àžàž«àž²àžà¹àžà¹àž¡àžà¹àžàžàžàž±àžàž¡àžµàžàž§àž²àž¡à¹àž«àž¡à¹àžàž§à¹àž²  
+
+LOMPlugin.download_srcdocs:àžàž²àž§àžà¹à¹àž«àž¥àžà¹àž­àžàžªàž²àž£àžà¹àžàžàžàž±àžàžà¹àž²àž¡àžµàžàž²àž£àž£àž°àžàžžà¹àž§à¹ (à¹àž general^identifier^entry àž«àž£àž·àž­ technical^location) àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹àžàž§àž£àž£àž°àžàžžàžàžŽàžàžàžà¹àžàžàžàžŽà¹àžàž·à¹àž­à¹àž«à¹àžàž£àžàžàž±àžàžàž·à¹àž­à¹àžà¹àž¡àžà¹àž­àžàžàž³àžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àž à¹àžàž£àžàžªàž±àžà¹àžàžàž§à¹àž² àžàžàž°àžàžµà¹àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹àžàž°à¹àž¡à¹àžàž³àžàž²àžàžàž±àžà¹àž­àžàžªàž²àž£àžàžµà¹àž­àž¢àž¹à¹àžàž­àžà¹àžàž£à¹àž§àž­àž¥àž¥à¹  
+
+MARCPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàž MARC àžàž·à¹àžàžàž²àž  
+
+MARCPlugin.metadata_mapping:àžàž·à¹àž­àžàž­àžà¹àžà¹àž¡àžàžµà¹àž£àž§àž¡àž£àž²àž¢àž¥àž°à¹àž­àžµàž¢àžàžàž²àž£à¹àž¡àžàžàž²àžàžà¹àž² MARC à¹àžà¹àž²àžàž±àžàžàž·à¹àž­à¹àž¡àžàž²àžàž²àžàž²àžàž­àžàžàž£àžµàžàžªà¹àžàž àžàžžàžàžªàž²àž¡àž²àž£àžàžàž¹àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžàžàž­àž 'marctodc.txt' à¹àžà¹àžàž²àžà¹àžà¹àž£àžàžàž­àž£àžµ etc àžàž­àžà¹àžàžà¹  
+
+MARCXMLPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàž MARCXML  
+
+MARCXMLPlugin.metadata_mapping_file:àžàž·à¹àž­àžàž­àžà¹àžà¹àž¡àžàžµà¹àž£àž§àž¡àž£àž²àž¢àž¥àž°à¹àž­àžµàž¢àžàžàž²àž£à¹àž¡àžàžàž²àžàžà¹àž² MARC à¹àžà¹àž²àžàž±àžàžàž·à¹àž­à¹àž¡àžàž²àžàž²àžàž²àžàž­àžàžàž£àžµàžàžªà¹àžàž àžàžžàžàžªàž²àž¡àž²àž£àžàžàž¹àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžàžàž­àž 'marctodc.txt' à¹àžà¹àžàž²àžà¹àžà¹àž£àžàžàž­àž£àžµ etc àžàž­àžà¹àžàžà¹  
+
+MediaWikiPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžàžàž²àž£àžàž³à¹àžà¹àž²à¹àž§à¹àžà¹àžàžàžàžµà¹àžªàž£à¹àž²àžàžàž²àž MediaWiki  
+
+MediaWikiPlugin.show_toc:à¹àžàžŽà¹àž¡ 'table of contents' àžàžµà¹àž­àž¢àž¹à¹àžàžàž«àžà¹àž²àž«àž¥àž±àžàžàž­àžà¹àž§à¹àžà¹àžàžà¹ MediaWiki à¹àžàžàžµà¹àž«àžà¹àž² 'à¹àžàžµà¹àž¢àž§àžàž±àž' àžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àž àžàž³à¹àžà¹àžàžà¹àž­àžàž£àž°àžàžžàžàžŽàžàžàžà¹àžàžàžàžŽàžàž­àž Perl à¹àž toc_exp àžà¹àž²àžàž¥à¹àž²àžàžªàž³àž«àž£àž±àžà¹àžàžµàž¢àžàž«àž²àžªà¹àž§àž 'àžªàž²àž£àžàž±àž'   
+
+MediaWikiPlugin.delete_toc:àž¥àžàžªà¹àž§àž 'àžªàž²àž£àžàž±àž' àžàžà¹àžà¹àž¥àž°àž«àžà¹àž²àžàž­àž HTML àžàž³à¹àžà¹àžàžà¹àž­àžàž£àž°àžàžžàžàžŽàžàžàžà¹àžàžàžàžŽàžàž­àž Perl à¹àž toc_exp àžà¹àž²àžàž¥à¹àž²àžà¹àžàž·à¹àž­à¹àž«à¹àžàž£àžàžàž±àžàžªà¹àž§àž 'àžªàž²àž£àžàž±àž'  
+
+MediaWikiPlugin.toc_exp:àžàžŽàžàžàžà¹àžàžàžàžŽàžàž­àž Perl àžªàž³àž«àž£àž±àžà¹àžàžµàž¢àžàž«àž² 'àžªàž²àž£àžàž±àž' àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžàžàž°àžàž£àžàžàž±àžàžàž±àžà¹àž§à¹àžà¹àžàžàžàžµà¹àžªàž£à¹àž²àžàžàž²àž MediaWiki àžàž±à¹àž§à¹àž  
+
+MediaWikiPlugin.delete_nav:àž¥àžàžªà¹àž§àžàžàž²àž£àžàž³àžàž²àž àžàž³à¹àžà¹àžàžà¹àž­àžàž£àž°àžàžžàžàžŽàžàžàžà¹àžàžàžàžŽàžàž­àž Perl à¹àž nav_div_exp àžà¹àž²àžàž¥à¹àž²àž  
+
+MediaWikiPlugin.nav_div_exp:àžàžŽàžàžàžà¹àžàžàžàžŽàžàž­àž Perl àžªàž³àž«àž£àž±àžà¹àžàžµàž¢àžàž«àž²àžªà¹àž§àžàžàž²àž£àžàž³àžàž²àž àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžàžàž°àžàž£àžàžàž±àžàžàž±àžà¹àž§à¹àžà¹àžàžàžàžµà¹àžªàž£à¹àž²àžàžàž²àž MediaWiki àžàž±à¹àž§à¹àž  
+
+MediaWikiPlugin.delete_searchbox:àž¥àžàžªà¹àž§àž "searchbox" àžàž³à¹àžà¹àžàžà¹àž­àžàž£àž°àžàžžàžàžŽàžàžàžà¹àžàžàžàžŽàžàž­àž Perl à¹àž searchbox_div_exp àžà¹àž²àžàž¥à¹àž²àž  
+
+MediaWikiPlugin.searchbox_div_exp:àžàžŽàžàžàžà¹àžàžàžàžŽàžàž­àž Perl àžªàž³àž«àž£àž±àžà¹àžàžµàž¢àžàž«àž²àžªà¹àž§àž 'searchbox' àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžàžàž°àžàž£àžàžàž±àžàžàž±àžà¹àž§à¹àžà¹àžàžàžàžµà¹àžªàž£à¹àž²àžàžàž²àž MediaWiki àžàž±à¹àž§à¹àž  
+
+MediaWikiPlugin.remove_title_suffix_exp:àžàžŽàžàžàžà¹àžàžàžàžŽàžàž­àž Perl à¹àžàž·à¹àž­à¹àžà¹àžàž±àžàžàž·à¹àž­à¹àž£àž·à¹àž­àžàžàžµà¹àžàž¶àžàž¡àž² àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž \\s-(.+) àžàž°àžàž±àžà¹àžàž·à¹àž­àž«àž²àžàž­àžàžàž·à¹àž­à¹àž£àž·à¹àž­àžàž«àž¥àž±àžà¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢ "-"  
+
+MetadataCSVPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžà¹àž¡àžàž²àžàž²àžàž²à¹àžàž£àž¹àžà¹àžàžàžà¹àž²àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àž à¹àžàžàžà¹àž­àž¡àž¹àž¥àžàž·à¹àž­à¹àžà¹àž¡à¹àžà¹àžà¹àž¡ CSV àžàž°àžàž¹àžà¹àžà¹à¹àžàž·à¹àž­àžàž³àž«àžàžàžàž§àž²àž¡àžªàž±àž¡àžàž±àžàžà¹àž£àž°àž«àž§à¹àž²àžà¹àž­àžàžªàž²àž£àžàž±àžà¹àž¡àžàž²àžàž²àžàž²  
+
+MetadataPass.desc:àžàž¥àž²àžªàžàž·à¹àžàžàž²àžàžàž­àž BasePlugin àžàžµà¹àžªàžàž±àžàžªàžàžžàžàžàž¥àž±à¹àžàž­àžŽàžà¹àž¡àžàž²àžàž²àžàž²àžàž°à¹àžà¹àžàž£àž°à¹àž¢àžàžà¹àžàž²àž metadata_read à¹àžàž·à¹àž­àžªà¹àžàžà¹àž²àž import.pl  
+
+MetadataXMLPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡ metadata.xml  
+
+MetadataEXIFPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžàžàž¶àžà¹àž¡àžàž²àžàž²àžàž² EXIF àžàž²àžàžà¹àž­àž¡àž¹àž¥àž àž²àž à¹àžªàžµàž¢àž à¹àž¥àž°àž§àžŽàžàžµà¹àž­ àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àž¡àžµàžàž·à¹àžàžàž²àžàž­àž¢àž¹à¹àžàž à¹àž¡àžàž¹àž¥ CPAN 'ExifTool' àžàž¶à¹àžà¹àž¡àžàž¹àž¥àžàžµà¹àžªàžàž±àžàžªàžàžžàžàž£àž¹àžà¹àžàžà¹àžà¹àž¡àž­àž·à¹àžà¹ àž­àžµàžàž¡àž²àžàž¡àž²àž¢ (à¹àžà¹àž GPS, XMP, FlashPix, ID3, Vorbis) àžàž¥àž±à¹àžàž­àžŽàžàžàž±àž§àžàžµà¹à¹àžà¹àžàžžàžàžªàž¡àžàž±àžàžŽàžàž­àžà¹àž¡àžàž¹àž¥àžàž±àžàžàž¥à¹àž²àž§ à¹àž¥àž°àžàž¹àžàž­àž­àžà¹àžàžà¹àž«à¹àžªàž²àž¡àž²àž£àžàž£àž­àžàž£àž±àžàžà¹àž­àž¡àž¹àž¥àžàžžàžàž£àž¹àžà¹àžàžàžàžµà¹ ExifTool àž£àž­àžàž£àž±àž àžàž¹àžàž¹à¹àž¡àž·àž­àžàž­àž ExifTool àžªàž³àž«àž£àž±àžàžàžàžŽàžàžàž­àžà¹àžà¹àž¡à¹àž¥àž°à¹àžàž£àžàž£à¹àž²àžà¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àž£àž­àžàž£àž±àž  
+
+GreenstoneMETSPlugin.desc:àžàž£àž°àž¡àž§àž¥àžàž¥à¹àž­àžàžªàž²àž£ METS à¹àžàž£àž¹àžà¹àžàžàžàž­àžàžàž£àžµàžàžªà¹àžàž  
+
+MP3Plugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžàžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡ MP3  
+
+MP3Plugin.assoc_images:à¹àžà¹ Google image àžà¹àžàž«àž²à¹àžàž·à¹àž­àž£àž°àžàžžàžàž³à¹àž«àžà¹àžàž£àž¹àžàžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àžà¹àžà¹àž¡ MP3 àžàžµà¹àž¡àžµàžàž·à¹àžàžàž²àžàž­àž¢àž¹à¹àžàžà¹àž¡àžàž²àžàž²àžàž²àžàž·à¹àž­à¹àž£àž·à¹àž­àžà¹àž¥àž°àžšàžŽàž¥àžàžŽàžà¹àžàž ID3  
+
+MP3Plugin.applet_metadata:à¹àžà¹àžàž±àžà¹àžà¹àžà¹àž¡àžàž²àžàž²àžàž² [à¹àž­àžà¹àžàž¥à¹àž] àžªàž³àž«àž£àž±àžà¹àž­àžàžªàž²àž£à¹àžà¹àž¥àž°àžàžàž±àžàžàžµà¹àž¡àžµ HTML àžàžµà¹àžàž³à¹àžà¹àžàžªàž³àž«àž£àž±àžà¹àž­àžà¹àžàž¥à¹àžà¹àžàž£àž·à¹àž­àžà¹àž¥à¹àžà¹àžªàžµàž¢àž MP3 à¹àžàž·à¹àž­à¹àž¥à¹àžà¹àžà¹àž¡àžàž±à¹àž  
+
+MP3Plugin.metadata_fields:àž£àž²àž¢àžàž²àž£àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àžàžàž­àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àžà¹àž­àžàžàž²àž£àžàž±àžàžàž­àž (àžàž·àž­àž§à¹àž²à¹àžà¹àžàžàž±àžàžàžžàžàž±àž) à¹àžà¹àžà¹àž¡ MP3  à¹àž«à¹à¹àžà¹ \"*\" à¹àžàž·à¹àž­àžàž±àžàžàž­àžà¹àžàžàžà¹àž­àž¡àž¹àž¥àžàž±à¹àžàž«àž¡àž  
+
+NulPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžà¹àžà¹àž¡àžàž±àž¡àž¡àžµ (.nul)  à¹àžà¹àžàž±àžà¹àžà¹àž¡àžàžµà¹àžàž¹àžàžªàž£à¹àž²àžà¹àžàž¢àžàž²àž£àžàž£àž°àžàž²àž¢à¹àžà¹àž¡àžàž²àžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²  
+
+NulPlugin.assoc_field:àžàž·à¹àž­àžàž­àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àžàž°àžàž¹àžàžàž±à¹àžàžà¹àž²àžªàž³àž«àž£àž±àžà¹àžà¹àž¡ nul à¹àžà¹àž¥àž°à¹àžà¹àž¡  
+NulPlugin.add_metadata_as_text:à¹àžàžŽà¹àž¡àžàž²àž£àž²àžàžàž­àžà¹àž¡àžàž²àžàž²àžàž²à¹àž«à¹à¹àžà¹àžàžà¹àž­àžàž§àž²àž¡àžàž­àžà¹àž­àžàžªàž²àž£ à¹àžàžàžàž£àž°à¹àž¢àž "à¹àž­àžàžªàž²àž£àžàžµà¹à¹àž¡à¹àž¡àžµàžà¹àž­àžàž§àž²àž¡à¹àžà¹"  
+
+NulPlugin.remove_namespace_for_text:à¹àž­àž²à¹àžàž¡àžªà¹àžàžàž­àž­àžàžàž²àžàžàž·à¹àž­à¹àž¡àžàž²àžàž²àžàž²à¹àžàžà¹àž­àžàž§àž²àž¡à¹àž­àžàžªàž²àž£ (àžà¹àž²àž¡àžµàžàž²àž£àžàž±à¹àžàžà¹àž² add_metadata_as_text à¹àž§à¹)  
+
+OAIPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàž Open Archives Initiative (OAI) à¹àžàžàžàž·à¹àžàžàž²àž  
+
+OAIPlugin.document_field:àž«àžà¹àž§àž¢àžà¹àž­àž¡àž¹àž¥àž¢à¹àž­àž¢àžàž­àžà¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àž£àž°àžàžžàžàž·à¹àž­à¹àžà¹àž¡àžàž­àžà¹àž­àžàžªàž²àž£àžàžµà¹àžà¹àž­àžàžàž²àž£à¹àžàžà¹àž¡àžàž²àžàž²àžàž²  
+
+OggVorbisPlugin.add_technical_metadata:à¹àžàžŽà¹àž¡à¹àž¡àžàž²àžàž²àžàž²à¹àžàžŽàžà¹àžàžàžàžŽàž (à¹àžà¹àž àžàžŽàžà¹àž£àž)  
+
+OggVorbisPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžàžàž²àž£àžàž³à¹àžà¹àž²à¹àžà¹àž¡à¹àžªàžµàž¢àž Ogg Vorbis  
+
+OpenDocumentPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžà¹àž­àžàžªàž²àž£àž£àž¹àžà¹àžàž OASIS OpenDocument (à¹àžà¹à¹àžàž¢à¹àžàž£à¹àžàž£àž¡ OpenOffice 2.0)  
+
+PagedImagePlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžà¹àž­àžàžªàž²àž£àžàžµà¹àžªàž£à¹àž²àžàžàž¶à¹àžàžàž²àžàžàž²àž£à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàžàž­àžàž£àž¹àž àžàžµà¹àž¡àžµàžà¹àž­àžàž§àž²àž¡ OCR àžªàž³àž«àž£àž±àžà¹àžà¹àž¥àž°àž£àž¹àž (à¹àžà¹àžàžàž±àž§à¹àž¥àž·àž­àž)  àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž°àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡ .item àžàž¶à¹àžà¹àžªàžàžàž£àž²àž¢àžàž²àž£àž¥àž³àžàž±àžàžàž­àžà¹àžà¹àž¡àž£àž¹àžà¹àž¥àž°àžà¹àž­àžàž§àž²àž¡ àžàž£à¹àž­àž¡àžàž±à¹àžà¹àž«à¹àžà¹àž²à¹àž¡àžàž²àžàž²àžàž²  
+
+PagedImagePlugin.documenttype:àžàž±à¹àžàžà¹àž²àžàžàžŽàžàžàž­àžà¹àž­àžàžªàž²àž£ (à¹àžà¹àžªàž³àž«àž£àž±àžà¹àžªàžàžàžàž¥)  
+
+PagedImagePlugin.documenttype.paged:à¹àž­àžàžªàž²àž£àžàžµà¹àž¡àžµàžàž²àž£à¹àž£àžµàž¢àžàž¥àž³àžàž±àžàž«àžà¹àž²àžàž°àž¡àžµàž¥àž¹àžàžšàž£ 'àžàž±àžà¹àž' à¹àž¥àž° 'àžà¹àž­àžàž«àžà¹àž²' à¹àž¥àž°àžàž¥à¹àž­àž 'à¹àžàž¢àž±àžàž«àžà¹àž² X'  
+
+PagedImagePlugin.documenttype.hierarchy:à¹àž­àžàžªàž²àž£à¹àžàžàž¥àž³àžàž±àžàžàž±à¹àžàž¡àžµàžªàž²àž£àžàž±àž  
+
+PagedImagePlugin.headerpage:à¹àžàžŽà¹àž¡àž«àžà¹àž²àžªà¹àž§àžàž«àž±àž§àž£àž°àžàž±àžàžàžàžªàžžàž (àžàžµà¹à¹àž¡à¹àž¡àžµàž£àž¹àž) à¹àžàž¢àž±àžà¹àž­àžàžªàž²àž£à¹àžà¹àž¥àž°àžàžàž±àž  
+
+PDFPlugin.allowimagesonly:àž­àžàžžàžàž²àžà¹àžà¹àž¡ PDF àžàžµà¹à¹àž¡à¹àž¡àžµàžà¹àž­àžàž§àž²àž¡àžàžµà¹àžªàž²àž¡àž²àž£àžàžàž±àžàžàž­àžà¹àžà¹ àžàž£àžžàžàž²àž«àž¥àžµàžà¹àž¥àžµà¹àž¢àžàžàž²àž£àžàž±à¹àžàžà¹àž² -complex àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹àžàž°àž¡àžµàžàž£àž°à¹àž¢àžàžà¹à¹àžàžàž²àž°àžàž±àž convert_to html à¹àžà¹àž²àžàž±à¹àž  
+
+PDFPlugin.complex:àžªàž£à¹àž²àžàžàž¥àž¥àž±àžàžà¹àžàžµà¹àžàž±àžàžà¹àž­àžàž¡àž²àžàžàž¶à¹àž àžà¹àž§àž¢àžàž²àž£àžàž±à¹àžàžà¹àž²àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹ html àžàžµà¹à¹àžà¹àžàžàž¥àž¥àž±àžàžà¹àžàž°àžàž¹àžàž¥à¹àž²àž¢àžàž¥àž¶àžàžàž±àžà¹àžà¹àž¡ PDF àžà¹àžàžàžàž±àžàž¡àž²àž à¹àžàž·à¹àž­à¹àž«à¹àžàž±àžàžà¹àžàž±àžàžàžµà¹àžàž³àžàž²àžà¹àžà¹àžàžàžàžàžŽ àžàžžàžàžàž³à¹àžà¹àžàžà¹àž­àžàžàžŽàžàžàž±à¹àž Ghostscript àžà¹àž§àž¢ (àžªàž³àž«àž£àž±àž *nix gs àžàž§àž£àž­àž¢àž¹à¹àžàžà¹àžªà¹àžàžàž²àžàžàž­àžàžàžžàž àžàžàž°àžàžµà¹àžªàž³àž«àž£àž±àž windows àžàžžàžàžàž°àžà¹àž­àžàž¡àžµà¹àžàž£à¹àžàž£àž¡ gswin32c.exe àžàžà¹àžªà¹àžàžàž²àžàžàž­àžàžàžžàžàžà¹àž§àž¢)  
+
+PDFPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž£àž°àž¡àž§àž¥àžàž¥à¹àž­àžàžªàž²àž£ PDF  
+
+PDFPlugin.nohidden:àžà¹àž­àžàžàž±àž pdftohtml àžàž²àžàžàž²àž£àžàž¢àž²àž¢àž²àž¡àžàž±àžàžàž­àžàžà¹àž­àžàž§àž²àž¡àžàžµà¹àžà¹àž­àžà¹àž§à¹  àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹àžàž°à¹àžà¹àžàžàž£àž°à¹àž¢àžàžà¹à¹àžàžàž²àž°à¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£àžàž±à¹àžàžà¹àž²àžàž±àž§à¹àž¥àž·àž­àž -complex à¹àž§à¹àžà¹àž§àž¢  
+
+PDFPlugin.noimages:à¹àž¡à¹àžàž§àž£àžàž¢àž²àž¢àž²àž¡àžàž±àžàžàž­àžàž£àž¹àžàž àž²àžàž­àž­àžàžàž²àž PDF  
+
+PDFPlugin.use_sections:àžªàž£à¹àž²àžàžªà¹àž§àžà¹àž¢àžàžà¹àž²àžàž«àž²àžàžªàž³àž«àž£àž±àžà¹àžà¹àž¥àž°àž«àžà¹àž²àžàž­àžà¹àžà¹àž¡ PDF  
+
+PDFPlugin.zoom:à¹àžàžà¹àžàž­àž£à¹àžàžµà¹àžàž°à¹àžà¹àžàž³àž«àžàžàžàž²àž£àžàž¢àž²àž¢ PDF à¹àžàž·à¹àž­à¹àžªàžàžàžàž¥àž¥àž±àžàžà¹ (àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž°à¹àžà¹àžàžàž£àž°à¹àž¢àžàžà¹à¹àžàžàž²àž°à¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£àžàž±à¹àžàžà¹àž²àžàž±àž§à¹àž¥àž·àž­àž -complex à¹àž§à¹)  
+
+PostScriptPlugin.desc:àžàž·à¹àžàž·àž­àžàž±àž§à¹àžàž¥àžàžàž²àž \"poor man's\" ps à¹àžà¹àžà¹àžàžà¹àž­àžàž§àž²àž¡ àžà¹àž²àžàžžàžàžà¹àž­àžàžàž²àž£à¹àžà¹àž­àž¢à¹àž²àžàžàž£àžŽàžàžàž±àž àžàž­à¹àž«à¹àžàžŽàžàž²àž£àžàž²à¹àžà¹à¹àžàžà¹àžàž PRESCRIPT àžàž¶à¹àžàžªàž²àž¡àž²àž£àžàžàž²àž§àžà¹à¹àž«àž¥àžà¹àžà¹àžàžµà¹ http://www.nzdl.org/html/software.html  
+
+PostScriptPlugin.extract_date:àžàž±àžàžàž­àžàž§àž±àžàžàžµà¹àž­àž­àžàžàž²àžàžªà¹àž§àžàž«àž±àž§ PS  
+
+PostScriptPlugin.extract_pages:àžàž±àžàžàž­àžàž«àžà¹àž²àž­àž­àžàžàž²àžàžªà¹àž§àžàž«àž±àž§ PS  
+
+PostScriptPlugin.extract_title:àžàž±àžàžàž­àžàžàž·à¹àž­à¹àž£àž·à¹àž­àžàž­àž­àžàžàž²àžàžªà¹àž§àžàž«àž±àž§ PS  
+
+PowerPointPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžàžàž²àž£àžàž³à¹àžà¹àž²à¹àžà¹àž¡ Microsoft PowerPoint  
+
+PowerPointPlugin.windows_scripting:à¹àžà¹à¹àžàžà¹àžà¹àž¥àž¢àžµàžªàžàž£àžŽàžàžà¹àžàž­àž Microsoft Windows (Visual Basic for Applications) à¹àžàž·à¹àž­à¹àžà¹à¹àžàž£à¹àžàž£àž¡ PPT à¹àžàž¥àžà¹àž­àžàžªàž²àž£à¹àž«à¹à¹àžà¹àžàž£àž¹àžàžàžàžŽàžàžà¹àž²àžà¹ (à¹àžà¹àž JPEG, PNG, GIF) à¹àžàžàžàž²àž£àžàž¶à¹àžàžàž²à¹àžàžà¹àžàžàž£àž«àž±àžªà¹àžàžŽàž ppttohtml  
+
+PrintInfo.bad_general_option:àžàž¥àž±à¹àžàž­àžŽàž %s à¹àžà¹àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹à¹àž¡à¹àžàž¹àžàžà¹àž­àž à¹àž«à¹àžàž£àž§àžàžªàž­àžà¹àžà¹àž¡àžàž³àž«àžàžàžà¹àž² collect.cfg àžàž­àžàžàžžàž  
+
+PrintInfo.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàž·à¹àžàžàž²àžàžàžµà¹àžªàžžàž àžàž³àž«àžà¹àž²àžàžµà¹àžàž±àžàžàž²àž£àžà¹àž­àž¡àž¹àž¥àžàž²àž£àžàžŽàž¡àžà¹ (à¹àžàž¢à¹àžà¹ pluginfo.pl) à¹àž¥àž°à¹àžàžàž­àž²àž£à¹àžàžŽàž§à¹àž¡àžàžà¹  
+
+ProCitePlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžàžàž²àžàžà¹àž­àž¡àž¹àž¥ ProCite (àžàžµà¹àžªà¹àžàž­àž­àž)  
+
+ProCitePlugin.entry_separator:àžªàžàž£àžŽàžàžàžµà¹à¹àžà¹àžàž±à¹àžàžà¹àž²àž«àž¥àž²àž¢à¹ àžà¹àž²àžªàž³àž«àž£àž±àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²à¹àžàžµà¹àž¢àž§à¹àžàž£àž°à¹àžàžµàž¢àžàžàž­àžàžàž²àžàžà¹àž­àž¡àž¹àž¥ ProCite  
+
+ReadTextFile.could_not_extract_encoding:àžàž³à¹àžàž·àž­àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàž±àžàžàž­àžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàž²àž %s - àžàž¶à¹àžà¹àžà¹àžàžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžà¹àžàž¢àž±àž %s à¹àžà¹  
+
+ReadTextFile.could_not_extract_language:àžàž³à¹àžàž·àž­àž: à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàž±àžàžàž­àžàž àž²àž©àž²àžàž²àž %s - àžàž¶à¹àžà¹àžà¹àžàžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžà¹àžàž¢àž±àž %s à¹àžà¹  
+
+ReadTextFile.could_not_open_for_reading:à¹àž¡à¹àžªàž²àž¡àž²àž£àžà¹àžàžŽàž %s à¹àžàž·à¹àž­àž­à¹àž²àžà¹àžà¹  
+
+ReadTextFile.default_encoding:à¹àžà¹àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàžµà¹àžà¹àž² -input_encoding àžàž¹àžàžàž±à¹àžàžà¹àž²à¹àžà¹àž 'auto' à¹àž¥àž°àž­àž±àž¥àžàž­àž£àžŽàžàž¶àž¡àžàž²àž£à¹àžà¹àžàžàž£àž°à¹àž àžàžà¹àž­àžàž§àž²àž¡à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàž±àžàžàž­àžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàžµà¹ àž«àž£àž·àž­à¹àž¡à¹àžªàž²àž¡àž²àž£àžàžàž±àžàžàž­àžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàžµà¹à¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàžà¹àž¡à¹àžªàžàž±àžàžªàžàžžàžà¹àžà¹ àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹àžªàž²àž¡àž²àž£àžàž¡àžµàžà¹àž²à¹àžàžµàž¢àž§àžàž±àž -input_encoding à¹àžà¹  
+
+ReadTextFile.default_language:àžà¹àž²à¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàžà¹àž¡à¹àžªàž²àž¡àž²àž£àžàž£àž°àžàžžàž àž²àž©àž²àžàž­àžà¹àž­àžàžªàž²àž£à¹àžà¹ àž­àžàžà¹àžàž£àž°àžàž­àžà¹àž¡àžàž²àžàž²àžàž² 'àž àž²àž©àž²' àžàž°àžàž¹àžàžàž±à¹àžà¹àž«à¹à¹àžà¹àžàžà¹àž²àžàžµà¹ àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžàžàž·àž­ 'en' (à¹àžà¹àžªàž±àžàž¥àž±àžàž©àžà¹àž àž²àž©àž²à¹àžàž ISO 639: en = English) à¹àžàž£àžàžªàž±àžà¹àžàžàž§à¹àž² àžà¹àž² -input_encoding à¹àž¡à¹àžàž¹àžàžàž±à¹àžàžà¹àž²à¹àžà¹àž 'auto' à¹àž¥àž°à¹àž¡à¹àž¡àžµàžàž²àž£àžàž±à¹àžàžà¹àž² -extract_language à¹àž§à¹ àž£àž°àžàžàžàž°àžàž±à¹àžàžà¹àž²à¹àž¡àžàž²àžàž²àžàž² 'Language' àžàž­àžà¹àž­àžàžªàž²àž£àžàž±à¹àžàž«àž¡àžà¹àž«à¹à¹àžà¹àžàžà¹àž²àžàžµà¹  
+
+ReadTextFile.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàž·à¹àžàžàž²àžàžªàž³àž«àž£àž±àžà¹àžà¹àž¡àžàžµà¹à¹àžà¹àžàžà¹àž­àžàž§àž²àž¡àž­àž¢à¹àž²àžà¹àžàžµàž¢àž§  
+
+ReadTextFile.empty_file:à¹àž¡à¹àž¡àžµàžà¹àž­àžàž§àž²àž¡à¹àžà¹ à¹àžà¹àžà¹àž¡  
+
+ReadTextFile.extract_language:àž£àž°àžàžžàž àž²àž©àž²àžªàž³àž«àž£àž±àžà¹àž­àžàžªàž²àž£à¹àžà¹àž¥àž°àžàžàž±àž à¹àž¥àž°àžàž±à¹àžàžà¹àž²à¹àž¡àžàž²àžàž²àžàž² 'àž àž²àž©àž²'  à¹àžàž£àžàžªàž±àžà¹àžàžàž§à¹àž² àž£àž°àžàžàžàž°àžàž³à¹àžàžŽàžàžàž²àž£à¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽàžà¹àž²àžà¹àž² -input_encoding à¹àžà¹àž 'auto'  
+
+ReadTextFile.file_has_no_text:àžà¹àž­àžàžŽàžàžàž¥àž²àž: %s à¹àž¡à¹àž¡àžµàžà¹àž­àžàž§àž²àž¡à¹àžà¹  
+
+ReadTextFile.input_encoding:àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªà¹àž­àžàžªàž²àž£àžà¹àžàžàžàž±àž à¹àž­àžàžªàž²àž£àžàž°àžàž¹àžà¹àžàž¥àžàžàž²àžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªà¹àž«àž¥à¹àž²àžàžµà¹ à¹àž¥àž°àžàž¹àžàžàž±àžà¹àžà¹àžà¹àž§à¹àž àž²àž¢à¹àžà¹àžàž£àž¹àžà¹àžàžàžàž­àž utf8  
+
+ReadTextFile.input_encoding.auto:à¹àžà¹àž­àž±àž¥àžàž­àž£àžŽàžàž¶àž¡àžàž²àž£à¹àžà¹àžàžàž£àž°à¹àž àžàžà¹àž­àžàž§àž²àž¡à¹àžàž·à¹àž­àž£àž°àžàžžàžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàž­àžà¹àž­àžàžªàž²àž£àžà¹àžàžàžàž±àžà¹àžà¹àž¥àž°àžàžàž±àžà¹àžàž¢àž­àž±àžà¹àžàž¡àž±àžàžŽ àžàž²àž£àžàž³à¹àžàžŽàžàžàž²àž£à¹àžà¹àžàžàžµà¹àžàž°àžà¹àž²àžàž§à¹àž²àžàž²àž£àžàž±à¹àžàžà¹àž²àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàž­àž¢à¹àž²àžàžàž±àžà¹àžàž à¹àžà¹àžªàž²àž¡àž²àž£àžà¹àžà¹àžàž²àžà¹àžà¹à¹àž¡àž·à¹àž­àžàžžàžà¹àžà¹àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàž¡àž²àžàžàž§à¹àž²àž«àžàž¶à¹àžà¹àžàžàž àž²àž¢à¹àžàžàž­àž¥à¹àž¥àžàžàž±àžà¹àžàžµàž¢àž§àžàž±àž  
+
+ReadTextFile.read_denied:àžàžàžŽà¹àžªàžàžªàžŽàžàžàžŽàžàž²àž£àž­à¹àž²àžàžªàž³àž«àž£àž±àž %s  
+
+ReadTextFile.separate_cjk:à¹àžàž£àžàžà¹àž­àžàž§à¹àž²àžàž£àž°àž«àž§à¹àž²àžàž­àž±àžàžàž£àž° àžàžµàž/àžàžµà¹àžàžžà¹àž/à¹àžàž²àž«àž¥àžµ à¹àžàž·à¹àž­àžªàž£à¹àž²àžàžàž³àžàž²àžàž­àž±àžàžàž£àž°à¹àžà¹àž¥àž°àžàž±àž§ à¹àž«à¹à¹àžà¹àžàžžàžàž¥àž±àžàž©àžàž°àžàžµà¹àžà¹àž²à¹àž¡à¹àž¡àžµàžàž²àž£àžàž±àžàžàž³à¹àžàžà¹àž­àžàž§àž²àž¡  
+
+ReadTextFile.unsupported_encoding:àžàž³à¹àžàž·àž­àž: %s àžàž¹à¹àž«àž¡àž·àž­àžàžàž°àžàž¹àžà¹àžà¹àž²àž£àž«àž±àžªàžà¹àž§àž¢àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžªàžàžµà¹à¹àž¡à¹àž£àž±àžàžàž²àž£àžªàžàž±àžàžªàžàžžàž (%s) - à¹àžàž¢à¹àžà¹ %s  
+
+ReadTextFile.wrong_encoding:àžàž³à¹àžàž·àž­àž: %s àžàž¹àžàž­à¹àž²àžà¹àžàž¢à¹àžà¹àžàž²àž£à¹àžà¹àž²àž£àž«àž±àžª %s à¹àžà¹àžàž¹à¹àž«àž¡àž·àž­àžàžàž°àžàž¹àžà¹àžà¹àž²àž£àž«àž±àžªà¹àžà¹àž %s  
+
+ReadXMLFile.desc:àžàž¥àž²àžªàžàž·à¹àžàžàž²àžàžªàž³àž«àž£àž±àžàžàž¥àž±à¹àžàž­àžŽàž XML  
+
+ReadXMLFile.xslt:à¹àžàž¥àžà¹àž­àžàžªàž²àž£à¹àžà¹àž²àžàžµà¹àžàž£àžàžàž±àžàžàž±àž XSLT à¹àžà¹àžà¹àž¡àžàžµà¹àžàž³àž«àžàžàžàž·à¹àž­à¹àž¥à¹àž§ àžàž·à¹àž­à¹àžà¹àž¡àžàžµà¹à¹àžàžµà¹àž¢àž§àžà¹àž­àžàžàž°àžàž¹àžàžàž·àž­àž§à¹àž² àž­àž¢àž¹à¹à¹àžàžàž·à¹àžàžàžµà¹à¹àžà¹àž¡àžàž­àžàžàž­àž¥à¹àž¥àžàžàž±àž àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž etc/mods2dc.xsl  
+
+RealMediaPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžàžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡ Real Media  
+
+ReferPlugin.desc:ReferPlugin àžàž°àž­à¹àž²àžà¹àžà¹àž¡àžàž£àž£àžàž²àžàžžàžàž£àž¡à¹àžàž£àž¹àžà¹àžàž Refer  
+
+RogPlugin.desc:àžªàž£à¹àž²àžà¹àž­àžàžªàž²àž£àž£àž°àžàž±àžà¹àžàžµàž¢àž§àž­àž¢à¹àž²àžàžà¹àž²àž¢àžàž²àžà¹àžà¹àž¡ .rog àž«àž£àž·àž­ .mdb  
+
+RTFPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžàžàž²àž£àžàž³à¹àžà¹àž²à¹àžà¹àž¡àž£àž¹àžà¹àžàž Rich Text  
+
+SourceCodePlugin.desc:à¹àžàžàž±àžàžàžžàžàž±àžàžàž·à¹àž­à¹àžà¹àž¡àžàž°àžàž¹àžà¹àžà¹à¹àžà¹àžàžàž·à¹àž­à¹àž£àž·à¹àž­àž (àžàž²àžàžàž£àž±à¹àžàž­àž²àžà¹àž¡à¹àž¡àžµàžàž³àžàž³àž«àžà¹àž²àžàž²àžàžàž±àž§)  àž àž²àž©àž²àžàž±àžàžàžžàžàž±àž:\ntext\: READMEs/Makefiles\nC/C++ (àžàžàž°àžàžµà¹àžàž±àžàžàž­àžàžàž³àžªàž±à¹àž #include à¹àž¥àž° C++ class decls)\nPerl    (àžàžàž°àžàžµà¹àžàž³à¹àžàžŽàžàžàž²àž£à¹àžªàž£à¹àžàžªàžŽà¹àžà¹àžà¹àžàž£àž¹àžà¹àžàžàžà¹àž­àžàž§àž²àž¡à¹àžà¹àž²àžàž±à¹àž)\nShell   (àžàžàž°àžàžµà¹àžàž³à¹àžàžŽàžàžàž²àž£à¹àžªàž£à¹àžàžªàžŽà¹àžà¹àžà¹àžàž£àž¹àžà¹àžàžàžà¹àž­àžàž§àž²àž¡à¹àžà¹àž²àžàž±à¹àž)  
+
+SourceCodePlugin.remove_prefix:à¹àž­àž²àž£àž¹àžà¹àžàžàžàž²àž£àžàž³àžàžµà¹àž­àž­àžàžàž²àžàžàž·à¹àž­à¹àžà¹àž¡ (à¹àžà¹àž -remove_prefix /tmp/XX/src/)  àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àžàžàž·àž­ à¹àž«à¹à¹àž­àž²à¹àžªà¹àžàžàž²àžàžàž±à¹àžàž«àž¡àžàž­àž­àžàžàž²àžàžàž·à¹àž­à¹àžà¹àž¡  
+
+SplitTextFile.desc:SplitTextFile à¹àžà¹àžàžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžà¹à¹àžà¹àžà¹àžà¹àž¡àžà¹àž­àž¡àž¹àž¥à¹àžà¹àž²àž­àž­àžà¹àžà¹àžàžªà¹àž§àžà¹ àžàž¶à¹àžàžàž°àžàž¹àžàžàž£àž°àž¡àž§àž¥àžàž¥à¹àž¢àžàžàž±àžàžàžµàž¥àž°àžªà¹àž§àž àžàžžàžà¹àž¡à¹àžàž§àž£à¹àž£àžµàž¢àžà¹àžà¹àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹à¹àžàž¢àžàž£àž àžà¹àž²àžàžžàžàžàž³à¹àžà¹àžàžà¹àž­àžàžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡àžà¹àž­àž¡àž¹àž¥à¹àžà¹àž²àžàžµà¹àž¡àžµà¹àž­àžàžªàž²àž£àž«àž¥àž²àž¢àžàžàž±àž àžàžžàžàžàž§àž£à¹àžàžµàž¢àžàžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àž¡àžµàžàž±àžàžà¹àžàž±àžàžàž²àž£àžàž£àž°àž¡àž§àž¥àžàž¥àžàž¶à¹àžàžàž°àžàž±àžàžàž²àž£à¹àž­àžàžªàž²àž£à¹àž«àž¥à¹àž²àžàž±à¹àžà¹àžà¹àž¥àž°àžàžàž±àž à¹àž¥àž°à¹àž«à¹àžàž¥àž±à¹àžàž­àžŽàžàžàž±à¹àžà¹àžà¹àž£àž±àžàžàž²àž£àžªàž·àžàžàž­àžàžàž²àž SplitTextFile à¹àž«à¹àžàž¹ ReferPlugin à¹àžà¹àžàžàž±àž§àž­àž¢à¹àž²àž  
+
+SplitTextFile.split_exp:àžàžŽàžàžàžà¹àžàžàžàžŽàžàž­àžàž àž²àž©àž² Perl àžàžµà¹à¹àžà¹àžà¹àžà¹àž¡àžà¹àž­àž¡àž¹àž¥à¹àžà¹àž²àž­àž­àžà¹àžà¹àžàžªà¹àž§àžà¹  
+
+StructuredHTMLPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž°àžàž£àž°àž¡àž§àž¥àžàž¥à¹àž­àžàžªàž²àž£ HTML à¹àžàžŽàžà¹àžàž£àžàžªàž£à¹àž²àž à¹àž¥àž°à¹àž¢àžà¹àž­àžàžªàž²àž£à¹àž«àž¥à¹àž²àžàž±à¹àžàž­àž­àžà¹àžà¹àžàžªà¹àž§àžà¹ àžàž²àž¡àžà¹àž­àž¡àž¹àž¥àž£àž¹àžà¹àžàž  
+
+StructuredHTMLPlugin.delete_toc:à¹àž­àž²àžªàž²àž£àžàž±àž àž£àž²àž¢àžàž²àž£àž£àž¹àž à¹àž¥àž°àžªàžŽà¹àžàž­àž·à¹àžà¹ àž­àž­àžàžàž²àžà¹àžà¹àž¡ HTML àžàžµà¹à¹àžàž¥àžà¹àž¥à¹àž§ àž£àž¹àžà¹àžàžàžªàž³àž«àž£àž±àžàžªàžŽà¹àžà¹àž«àž¥à¹àž²àžàžµà¹àžàž°àžàž¹àžàž£àž°àžàžžàžà¹àž§àž¢àžàž±àž§à¹àž¥àž·àž­àž toc_header  
+
+StructuredHTMLPlugin.title_header:àž£àž¹àžà¹àžàžàžàžµà¹àžàž¹à¹à¹àžà¹àžàž³àž«àžàžà¹àž­àžàžàžµà¹à¹àžà¹àžà¹àžà¹àžà¹àžªàž³àž«àž£àž±àžàžªà¹àž§àžàž«àž±àž§àžàž·à¹àž­à¹àž£àž·à¹àž­àž  
+
+StructuredHTMLPlugin.level1_header:àž£àž¹àžà¹àžàžàžàžµà¹àžàž¹à¹à¹àžà¹àžàž³àž«àžàžà¹àž­àžàžàžµà¹à¹àžà¹àžà¹àžà¹àžà¹àžªàž³àž«àž£àž±àžàžªà¹àž§àžàž«àž±àž§ level1 à¹àžà¹àž­àžàžªàž²àž£ HTML (à¹àžàžµàž¢àžà¹àžà¹àž²àžàž±àž <h1>)  
+
+StructuredHTMLPlugin.level2_header:àž£àž¹àžà¹àžàžàžàžµà¹àžàž¹à¹à¹àžà¹àžàž³àž«àžàžà¹àž­àžàžàžµà¹à¹àžà¹àžà¹àžà¹àžà¹àžªàž³àž«àž£àž±àžàžªà¹àž§àžàž«àž±àž§ level2 à¹àžà¹àž­àžàžªàž²àž£ HTML (à¹àžàžµàž¢àžà¹àžà¹àž²àžàž±àž <h2>)  
+
+StructuredHTMLPlugin.level3_header:àž£àž¹àžà¹àžàžàžàžµà¹àžàž¹à¹à¹àžà¹àžàž³àž«àžàžà¹àž­àžàžàžµà¹à¹àžà¹àžà¹àžà¹àžà¹àžªàž³àž«àž£àž±àžàžªà¹àž§àžàž«àž±àž§ level3 à¹àžà¹àž­àžàžªàž²àž£ HTML (à¹àžàžµàž¢àžà¹àžà¹àž²àžàž±àž <h3>)  
+
+StructuredHTMLPlugin.toc_header:àž£àž¹àžà¹àžàžàžªà¹àž§àžàž«àž±àž§àžàžµà¹àžàž¹à¹à¹àžà¹àžàž³àž«àžàžà¹àž­àžàžàžµà¹à¹àžà¹àžà¹àžà¹àžà¹àžªàž³àž«àž£àž±àžàžªàž²àž£àžàž±àž àžàž²àž£àž²àžàž£àž¹àž à¹àž¥àž°àž­àž·à¹àžà¹ àžàž¶à¹àžàžàž°àžàž¹àžà¹àž­àž²àž­àž­àžàžà¹àž²àž¡àžµàžàž²àž£àžàž±à¹àžàžà¹àž² delete_toc à¹àž§à¹  
+
+TextPlugin.desc:àžªàž£à¹àž²àžà¹àž­àžàžªàž²àž£àž£àž°àžàž±àžà¹àžàžµàž¢àž§àž­àž¢à¹àž²àžàžà¹àž²àž¢ à¹àžàžŽà¹àž¡à¹àž¡àžàž²àžàž²àžàž²àžàž·à¹àž­à¹àž£àž·à¹àž­àžàžàž­àžàžàž£àž£àžàž±àžà¹àž£àžàžàž­àžàžà¹àž­àžàž§àž²àž¡ (àžàž§àž²àž¡àž¢àž²àž§àžªàž¹àžàžªàžžàž 100 àž­àž±àžàžàž£àž°)  
+
+TextPlugin.title_sub:àžàžŽàžàžàžà¹àžàž²àž£à¹àžàžàžàžµà¹à¹àžàž·à¹àž­àžàž£àž±àžà¹àžàž¥àžµà¹àž¢àžàžªàžàž£àžŽàžàžàžµà¹àžàž¹àžàžàž±àžà¹àžà¹àžà¹àžà¹àžàžàž·à¹àž­à¹àž£àž·à¹àž­àž àžàž±àž§àž­àž¢à¹àž²àžàžàž²àž£à¹àžà¹ à¹àžà¹àž PostscriptPlugin à¹àžà¹à¹àžàž·à¹àž­à¹àž­àž² "àž«àžà¹àž² 1" à¹àž¥àž°àž­àž·à¹àžà¹ àž­àž­àžàžàž²àžàžà¹àž­àžàž§àž²àž¡àžàžµà¹à¹àžà¹à¹àžà¹àžàžàž·à¹àž­à¹àž£àž·à¹àž­àž  
+
+UnknownPlugin.assoc_field:àžàž·à¹àž­àžàž­àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹à¹àžà¹àžàžàž·à¹àž­àžàž­àžà¹àžà¹àž¡àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àž  
+
+UnknownPlugin.desc:àžàžµà¹àžàž·àž­àžàž¥àž±à¹àžàž­àžŽàžàž­àž¢à¹àž²àžàžà¹àž²àž¢àžªàž³àž«àž£àž±àžàžàž²àž£àžàž³à¹àžà¹àž²à¹àžà¹àž¡à¹àžàž£àž¹àžà¹àžàžàžàžµà¹à¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàžà¹àž¡à¹à¹àžàž¢àž£àž¹à¹àžàž±àžàž¡àž²àžà¹àž­àž à¹àž­àžàžªàž²àž£àžàžµà¹àžàž¥àž­àž¡àžàž°àžàž¹àžàžªàž£à¹àž²àžàžàž¶à¹àžàžªàž³àž«àž£àž±àžàžàžžàžà¹ à¹àžà¹àž¡ à¹àž¥àž°àžàž±àž§à¹àžà¹àž¡àžàž°àžàž¹àžàžªà¹àžàžà¹àž²àžà¹àžàž¢àž±àžà¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàžà¹àžà¹àž \"à¹àžà¹àž¡àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àž\" àžàž­àžà¹àž­àžàžªàž²àž£  
+
+UnknownPlugin.file_format:àžàžàžŽàžàžàž­àžà¹àžà¹àž¡ (à¹àžà¹àž MPEG, MIDI, âŠ)  
+
+UnknownPlugin.mime_type:à¹àžà¹àž¡àžàžàžŽàž Mime (à¹àžà¹àž image/gif)  
+
+UnknownPlugin.process_extension:àžàž£àž°àž¡àž§àž¥àžàž¥à¹àžà¹àž¡àžà¹àž§àž¢àžàž²àž¡àžªàžàžžàž¥àžàž­àžà¹àžà¹àž¡àžàžµà¹  àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹à¹àžà¹àžàžàž²àžà¹àž¥àž·àž­àžàžªàž³àž«àž£àž±àž process_exp àžàž¶à¹àžàžàž°à¹àžà¹àžàž²àžàžà¹àž²àž¢àžàž§à¹àž² à¹àžà¹àž¡àžµàžàž§àž²àž¡àž¢àž·àžàž«àž¢àžžà¹àžàžà¹àž­àž¢àžàž§à¹àž²  
+
+UnknownPlugin.srcicon:àž£àž°àžàžžàžàž·à¹àž­à¹àž¡à¹àžàž£ (à¹àžàž¢à¹àž¡à¹àž¡àžµà¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžµàžàž¥à¹àž²àž) à¹àžàž·à¹àž­à¹àžà¹à¹àžà¹àžà¹àž¡àžàž²àžàž²àžàž² srcicon  
+
+WordPlugin.desc:àžàž¥àž±à¹àžàž­àžŽàžàžªàž³àž«àž£àž±àžàžàž²àž£àžàž³à¹àžà¹àž²à¹àž­àžàžªàž²àž£ Microsoft Word  
+
+WordPlugin.windows_scripting:à¹àž«à¹à¹àžà¹à¹àžàžà¹àžà¹àž¥àž¢àžµàžªàžàž£àžŽàžàžà¹àžàž­àž Microsoft Windows (Visual Basic àžªàž³àž«àž£àž±àžà¹àžàž£à¹àžàž£àž¡àžàž£àž°àž¢àžžàžàžà¹) à¹àžàž·à¹àž­à¹àž«à¹à¹àžàž£à¹àžàž£àž¡ Word àžàž³àžàž²àž£à¹àžàž¥àžà¹àž­àžàžªàž²àž£à¹àžà¹àž HTML à¹àžàžàžàž²àž£àžàž¶à¹àžàžàž²à¹àžàžà¹àžàžàž£àž«àž±àžªà¹àžàžŽàž WvWare àžàž¶à¹àžàžàž³à¹àž«à¹àžªàž²àž¡àž²àž£àžà¹àžàžŽàžà¹àžàž£à¹àžàž£àž¡àžàž£àž°àž¢àžžàžàžà¹ Word àžàžàž«àžà¹àž²àžàž­à¹àžà¹àžà¹àž²àž¢àž±àžà¹àž¡à¹à¹àžà¹à¹àžàžŽàžà¹àžàž£à¹àžàž£àž¡àž­àž¢àž¹à¹  
+
+WordPlugin.metadata_fields:à¹àžà¹à¹àžàž·à¹àž­àžà¹àžàžàž·àžà¹àž¡àžàž²àžàž²àžàž²àžàž²àžà¹àž­àžàžªàž²àž£ HTML àžàžµà¹àžàž¹àžà¹àžàž¥àžà¹àžàž¢àžªàžàž£àžŽàžàžà¹ VB àžàž¥àž±à¹àžàž­àžŽàžàžàž°àž­àžàžžàžàž²àžà¹àž«à¹àžàž¹à¹à¹àžà¹àžàž³àž«àžàžàž£àž²àž¢àžàž²àž£à¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àžà¹àžàž·à¹àž­àžàž¢àž²àž¢àž²àž¡àžàž±àžàžàž­àžàžà¹àž­àžàž§àž²àž¡ à¹àž«à¹à¹àžà¹ 'tag<tagname>' à¹àžàž·à¹àž­à¹àžªà¹à¹àžàž·à¹àž­àž«àž²àžàž­àžàžàž¹à¹ <tagname> à¹àž£àžàž¥àžà¹àžàž­àžàžà¹àžàž£àž°àžàž­àžà¹àž¡àžàž²àžàž²àžàž²àžàžµà¹àž¡àžµàžàž·à¹àž­àž§à¹àž² 'tagname' à¹àž«à¹àžàž³à¹àž¡àžàž²àžàž²àžàž²à¹àž«à¹à¹àžà¹àžàžàž±àž§àžàžŽàž¡àžà¹à¹àž«àžà¹àžà¹àž²àžàžžàžàžà¹àž­àžàžàž²àž£à¹àž«à¹à¹àžªàžàžà¹àž¡àžàž²àžàž²àžàž²à¹àžà¹àžàžàž±àž§àžàžŽàž¡àžà¹à¹àž«àžà¹à¹àžà¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàž à¹àžàž·à¹àž­àžàžàž²àžàžàž²àž£àžàž±àžàžàž­àžà¹àžà¹àžà¹àž¡à¹à¹àž¢àžà¹àž¢àž°àžàž±àž§àžàžŽàž¡àžà¹à¹àž«àžà¹-à¹àž¥à¹àž  
+
+ZIPPlugin.desc:"àžàžàž°àžàžµà¹ àžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž±àžàžàž²àž£àž£àž¹àžà¹àžàžàžà¹àž­àž¡àž¹àž¥à¹àžà¹àž²àžàžµà¹àžàž¹àžàžàžµàžàž­àž±àž à¹àž¥àž°/àž«àž£àž·àž­àžàžµà¹àžàž±àžà¹àžà¹àžàžàž²àž§àž£ à¹àžà¹àžàž±àžàžàž²àž£àž£àž¹àžà¹àžàžà¹àž¥àž°àžàž²àž¡àžªàžàžžàž¥àžàž­àžà¹àžà¹àž¡àžàž±àžàžàžµà¹:\ngzip (.gz, .z, .tgz, .taz)\nbzip (.bz)\nbzip2 (.bz2)\nzip (.zip .jar)\ntar (.tar)\n\nàžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àžàž°àžà¹àž­àžàžàž³àžàž²àžàž£à¹àž§àž¡àžàž±àžà¹àžàž£à¹àžàž£àž¡àž­àž£àž£àžàžàž£àž°à¹àž¢àžàžà¹àžàž±àžàžàžµà¹ (àžà¹àž²àžàž³àž¥àž±àžàžàž¢àž²àž¢àž²àž¡àžàž£àž°àž¡àž§àž¥àžàž¥àž£àž¹àžà¹àžàžàžàžµà¹àžªàž­àžàžàž¥à¹àž­àžàžàž±àž):\ngunzip (àžªàž³àž«àž£àž±àž gzip)\nbunzip (àžªàž³àž«àž£àž±àž bzip)\nbunzip2 \nunzip (àžªàž³àž«àž£àž±àž zip)\ntar (àžªàž³àž«àž£àž±àž tar)"
+
+#
+# Download module option descriptions
+#
+
+BaseDownload.desc:àžàž¥àž²àžªàžàž·à¹àžàžàž²àžàžªàž³àž«àž£àž±àžà¹àž¡àžàž¹àž¥àžàž²àž§àžà¹à¹àž«àž¥àž  
+BaseDownload.bad_general_option:à¹àž¡àžàž¹àž¥àžàž²àž§àžà¹à¹àž«àž¥àž %s à¹àžà¹àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹à¹àž¡à¹àžàž¹àžàžà¹àž­àž  
+MediaWikiDownload.desc:à¹àž¡àžàž¹àž¥àžªàž³àž«àž£àž±àžàžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àžàžà¹àž­àž¡àž¹àž¥àžàž²àžà¹àž§à¹àžàžàžµà¹à¹àžà¹ MediaWiki  
+MediaWikiDownload.reject_filetype:àž£àž²àž¢àžàž²àž£ URL àžàžµà¹àžà¹àž­àžàžàž²àž£àžà¹àž²àž¡ àžàž±à¹àžàžà¹àž§àž¢à¹àžàž£àž·à¹àž­àžàž«àž¡àž²àž¢àžàžžàž¥àž àž²àž (,) àžàž±àž§àž­àž¢à¹àž²àžà¹àžà¹àž *cgi-bin*,*.ppt àžàž°àž¡àž­àžàžà¹àž²àž¡à¹àž®à¹àžàž­àž£à¹àž¥àžŽàžàžà¹àžàžµà¹àž¡àžµàžàž³àž§à¹àž² 'cgi-bin' àž«àž£àž·àž­ '.ppt'  
+MediaWikiDownload.reject_filetype_disp:àž£àž¹àžà¹àžàž URL àžàžµà¹àžà¹àž­àžàžàž²àž£àžà¹àž²àž¡  
+MediaWikiDownload.exclude_directories:àž£àž²àž¢àžàž²àž£àžàž­àžà¹àžà¹àž£àžàžàž­àž£àžµàžàžµà¹àžà¹àž­àžàžàž²àž£àž¥àž°à¹àž§à¹àž (àžà¹àž­àžà¹àžà¹àžà¹àžªà¹àžàžàž²àžàžàžµà¹àžªàž¡àžàž¹àž£àžà¹à¹àžàž¢àž±àžà¹àžà¹àž£àžàžàž­àž£àžµ) à¹àžà¹àž /people, /documentation àžàž°àž¥àž°à¹àž§à¹àžà¹àžà¹àž£àžàžàž­àž£àžµàž¢à¹àž­àž¢ 'people' à¹àž¥àž° 'documentation' àž àž²àž¢à¹àžà¹à¹àžàžà¹àžàžµà¹àžàž³àž¥àž±àžàžàž±àžà¹àžà¹àžàžà¹àž­àž¡àž¹àž¥àž­àž¢àž¹à¹à¹àžàžàž±àžàžàžžàžàž±àž  
+MediaWikiDownload.exclude_directories_disp:àž¥àž°à¹àž§à¹àžà¹àžà¹àž£àžàžàž­àž£àžµ  
+
+OAIDownload.desc:à¹àž¡àžàž¹àž¥àžªàž³àž«àž£àž±àžàžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àžàžàž²àžàžàž¥àž±àž OAI  
+OAIDownload.url_disp:URL àžà¹àžàžàžàž±àž  
+OAIDownload.url:URL àžàž­àžàžàž¥àž±àž OAI  
+OAIDownload.set_disp:àžàž³àžàž±àžà¹àžàžàž²àž°àžàž¥àžžà¹àž¡  
+OAIDownload.set:àžàž³àžàž±àžàžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àžàžà¹àž§àž¢àžàžžàžàžàžµà¹àž£àž°àžàžžà¹àž§à¹à¹àžàžàž¥àž±àž  
+OAIDownload.metadata_prefix_disp:àžàž³àžàž³àž«àžà¹àž²à¹àž¡àžàž²àžàž²àžàž²  
+OAIDownload.metadata_prefix:àž£àž¹àžà¹àžàžàžàž­àžà¹àž¡àžàž²àžàž²àžàž²àžàžµà¹à¹àžà¹à¹àžàžà¹àž­àž¡àž¹àž¥àžàžµà¹àžªà¹àžàž­àž­àž à¹àžà¹àž oai_dc, qdc, à¹àž¥àž°àž­àž·à¹àžà¹ à¹àž«à¹àžàžàžàžžà¹àž¡ <àžà¹àž­àž¡àž¹àž¥à¹àžàžŽàž£à¹àžà¹àž§àž­àž£à¹> à¹àžàž·à¹àž­àžà¹àžàž«àž²àž£àž¹àžà¹àžàžà¹àžà¹àž¡àžàžµà¹àž£àž°àžàžàž£àž­àžàž£àž±àž  
+OAIDownload.get_doc_disp:àž£àž±àžà¹àž­àžàžªàž²àž£  
+OAIDownload.get_doc:àžàž²àž§àžà¹à¹àž«àž¥àžà¹àž­àžàžªàž²àž£àžà¹àžàžàžàž±àžàžà¹àž²àž¡àžµàžàž²àž£àž£àž°àžàžžà¹àž§à¹à¹àžàž£àž°à¹àžàžµàž¢àž  
+OAIDownload.get_doc_exts_disp:à¹àžàžàž²àž°àžàžàžŽàžàžàž­àžà¹àžà¹àž¡à¹àž«àž¥à¹àž²àžàžµà¹à¹àžà¹àž²àžàž±à¹àž  
+OAIDownload.get_doc_exts:àžàž²àž¡àžªàžàžžàž¥à¹àžà¹àž¡àžàž­àžà¹àž­àžàžªàž²àž£àžàžµà¹àžà¹àž­àžàžàž²àž£à¹àžà¹àžà¹àžàžµà¹àž¢àž§àž¡àž²  
+OAIDownload.max_records_disp:àžàž³àžàž§àžàž£àž°à¹àžàžµàž¢àžàžªàž¹àžàžªàžžàž  
+OAIDownload.max_records:àžàž³àžàž§àžàžªàž¹àžàžªàžžàžàžàž­àžàž£àž°à¹àžàžµàž¢àžàžàžµà¹àžªàž²àž¡àž²àž£àžàžàž²àž§àžà¹à¹àž«àž¥àžà¹àžà¹  
+
+SRWDownload.desc:à¹àž¡àžàž¹àž¥àžªàž³àž«àž£àž±àžàžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àžàžàž²àžàžàž¥àž±àž SRW (àžà¹àžàž«àž²/àžà¹àžàžàž·àž àžàž£àžŽàžàž²àž£à¹àž§à¹àž)  
+
+WebDownload.desc:à¹àž¡àžàž¹àž¥àžªàž³àž«àž£àž±àžàžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àžàžàž²àžàž­àžŽàžà¹àžàž­àž£à¹à¹àžà¹àžàžà¹àž²àžàžàž²àž HTTP àž«àž£àž·àž­ FTP  
+WebDownload.url:URL àžà¹àžà¹àž«àž¥à¹àž à¹àžàžàž£àžàžµàžàžµà¹à¹àžà¹àž HTTP Redirect àžà¹àž²àžàžµà¹àž­àž²àžàž¡àžµàžàž²àž£à¹àžàž¥àžµà¹àž¢àžà¹àžàž¥àž  
+WebDownload.url_disp:URL àžàž­àžàžà¹àžàžàžàž±àž  
+WebDownload.depth:àžàž°àžà¹àž­àžàž¡àžµàžàž²àž£à¹àžàž·à¹àž­àž¡à¹àž¢àžàž«àž¥àž²àž¢àž¡àžŽàžàžŽàž¥àž¶àžàž¥àžà¹àžàž¡àž²àžà¹àžà¹àž²à¹àžàžàžàž°àžàž³àžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àž  
+WebDownload.depth_disp:àžàž§àž²àž¡àž¥àž¶àžà¹àžàžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àž  
+WebDownload.below:à¹àžàžàž²àž°à¹àžà¹àž¡àž¡àžŽà¹àž£àž­àž£à¹àž àž²àž¢à¹àžà¹ URL àžàžµà¹  
+WebDownload.below_disp:à¹àžàžàž²àž°à¹àžà¹àž¡àžà¹àž­àž¡àž¹àž¥àž àž²àž¢à¹àžà¹ URL àžàžµà¹  
+WebDownload.within:à¹àžàžàž²àž°à¹àžà¹àž¡àž¡àžŽà¹àž£àž­àž£à¹àž àž²àž¢à¹àžà¹àžàžà¹à¹àžàžµàž¢àž§àžàž±àž  
+WebDownload.within_disp:à¹àžàžàž²àž°à¹àžà¹àž¡àž àž²àž¢à¹àžà¹àžàžà¹à¹àžàžµàž¢àž§àžàž±àž
+  
+WebDownload.html_only:àžàž²àž§àžà¹à¹àž«àž¥àžà¹àžàžàž²àž°à¹àžà¹àž¡ HTML à¹àžà¹àž²àžàž±à¹àž à¹àž¥àž°àž¥àž°à¹àž§à¹àžà¹àžà¹àž¡àžàžµà¹àžªàž±àž¡àžàž±àžàžà¹àžàž±àž à¹àžà¹àž àž£àž¹àž à¹àž¥àž°àžªà¹àžàž¥à¹àžàžµàž  
+WebDownload.html_only_disp:à¹àžàžàž²àž°à¹àžà¹àž¡ HTML à¹àžà¹àž²àžàž±à¹àž  
+
+WgetDownload.desc:àžàž¥àž²àžªàžàž·à¹àžàžàž²àžàžàžµà¹àžàž±àžàžàž²àž£àžàž²àž£à¹àž£àžµàž¢àžà¹àžàž¢àž±àž wget  
+WgetDownload.proxy_on:àžàž£à¹àž­àžàžàžµà¹àžàžŽàžàž­àž¢àž¹à¹  
+WgetDownload.proxy_host:à¹àž®àžªàžà¹àžàž£à¹àž­àžàžàžµ  
+WgetDownload.proxy_port:àžàž­àž£à¹àžàžàž­àžàžàž£à¹àž­àžàžàžµ  
+WgetDownload.user_name:àžàž·à¹àž­àžàž¹à¹à¹àžà¹  
+WgetDownload.user_password:àž£àž«àž±àžªàžà¹àž²àžàžàž­àžàžàž¹à¹à¹àžà¹  
+
+Z3950Download.desc:à¹àž¡àžàž¹àž¥àžªàž³àž«àž£àž±àžàžàž²àž£àžàž²àž§àžà¹à¹àž«àž¥àžàžàž²àžàžàž¥àž±àž Z3950  
+Z3950Download.host:URL àžàž­àžà¹àž®àžªàžà¹  
+Z3950Download.host_disp:à¹àž®àžªàžà¹  
+Z3950Download.port:àž«àž¡àž²àž¢à¹àž¥àžàžàž­àž£à¹àžàžàž­àžàžàž¥àž±àž  
+Z3950Download.port_disp:àžàž­àž£à¹àž  
+Z3950Download.database:àžàž²àžàžà¹àž­àž¡àž¹àž¥àžàžµà¹àžàž°à¹àžà¹àžà¹àžàž«àž²àž£àž°à¹àžàžµàž¢àž  
+Z3950Download.database_disp:àžàž²àžàžà¹àž­àž¡àž¹àž¥  
+Z3950Download.find:àžà¹àžàžàž·àžàž£àž°à¹àžàžµàž¢àžàžàžµà¹àž¡àžµàžàž³àžà¹àžàžàžµà¹àž£àž°àžàžž  
+Z3950Download.find_disp:àžà¹àžàž«àž²  
+Z3950Download.max_records:àžàž³àžàž§àžàžªàž¹àžàžªàžžàžàžàž­àžàž£àž°à¹àžàžµàž¢àžàžàžµà¹àžªàž²àž¡àž²àž£àžàžàž²àž§àžà¹à¹àž«àž¥àžà¹àžà¹  
+Z3950Download.max_records_disp:àžàž³àžàž§àžàž£àž°à¹àžàžµàž¢àžàžªàž¹àžàžªàžžàž  
+
+
+#
+#Plugout option descriptions
+#
+
+BasPlugout.bad_general_option:àžàž¥àž±à¹àžà¹àž­àž²àžà¹ %s à¹àžà¹àžàž±àž§à¹àž¥àž·àž­àžàžàžµà¹à¹àž¡à¹àžàž¹àžàžà¹àž­àž  
+BasPlugout.debug:àžàž±à¹àžàžà¹àž²à¹àž«àž¡àžàžàžµàžàž±à¹àž  
+BasPlugout.desc:àžàž¥àž²àžªàžàž·à¹àžàžàž²àžàžªàž³àž«àž£àž±àžàžàž¥àž±à¹àžà¹àž­àž²àžà¹àžªà¹àžàž­àž­àžàžàž±à¹àžàž«àž¡àž  
+BasPlugout.group_size:àžàž³àžàž§àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž°àž£àž§àž¡àž­àž¢àž¹à¹à¹àžà¹àžà¹àž¡ XML à¹àžà¹àž¡à¹àžàžµàž¢àž§  
+BasPlugout.gzip_output:à¹àž«à¹à¹àžà¹à¹àžàž£à¹àžàž£àž¡ gzip à¹àžàž·à¹àž­àžàžµàžàž­àž±àžà¹àž­àžàžªàž²àž£ XML àžàžµà¹à¹àžà¹àžàžàž¥àž¥àž±àžàžà¹ (à¹àž¡àž·à¹àž­àž¡àžµàžàž²àž£àžªàž£à¹àž²àžàžàž²àžà¹àž­àžàžªàž²àž£àžàžµà¹àžàž¹àžàžàžµàžàž­àž±àž àž­àž¢à¹àž²àž¥àž·àž¡àž£àž§àž¡ ZIPPlugin à¹àžà¹àž²à¹àžà¹àžàž£àž²àž¢àžàž²àž£àžàž¥àž±à¹àžàž­àžŽàžàžàž­àžàžàžžàžàžà¹àž§àž¢)  
+BasPlugout.output_handle:àžàž±àž§àž­àžàžŽàžàž²àž¢à¹àžà¹àž¡àžàžµà¹à¹àžà¹àžªà¹àžàžà¹àž­àž¡àž¹àž¥àžàž¥àž¥àž±àžàžà¹  
+BasPlugout.output_info:àžàž²àž£àž­à¹àž²àžàž­àžŽàžà¹àžàž¢àž±àžàž§àž±àžàžàžž arcinfo àžàžµà¹à¹àžà¹àžàž±àžà¹àžà¹àžàžà¹àž­àž¡àž¹àž¥à¹àžàžµà¹àž¢àž§àžàž±àžà¹àž«àž¥à¹àžàžà¹àž­àž¡àž¹àž¥àžàž²àž§àž£  
+BasPlugout.verbosity:àžàž§àžàžàžžàž¡àžàž£àžŽàž¡àž²àžàžà¹àž­àžàž§àž²àž¡àžàžµà¹à¹àžªàžàž  0=à¹àž¡à¹àž¡àžµ  3=àž¡àž²àž  
+BasPlugout.xslt_file:à¹àžàž¥àžà¹àž­àžàžªàž²àž£àžà¹àž§àž¢ XSLT à¹àžà¹àžà¹àž¡àžàžµà¹àž£àž°àžàžž  
+
+DSpacePlugout.desc:àž£àž¹àžà¹àžàžà¹àž­àžàžªàž²àž£àžàž±àžà¹àžà¹àžàžàž²àž§àž£àžàž­àž DSpace  
+
+FedoraMETSPlugout.desc:àž£àž¹àžà¹àžàž METS àžàžµà¹à¹àžà¹à¹àžàž£à¹àžàž¥à¹ Fedora  
+FedoraMETSPlugout.fedora_namespace:àžàž³àžàž³àž«àžà¹àž²àžàžµà¹à¹àžà¹à¹àž Fedora à¹àžàž·à¹àž­àžàž£àž°àž¡àž§àž¥àžàž¥  ids (PIDS) à¹àžà¹àž greenstone:HASH0122efe4a2c58d0  
+
+GreenstoneXMLPlugout.desc:àž£àž¹àžà¹àžàžàžàž²àž£àžàž±àžà¹àžà¹àžà¹àžà¹àž¡ XML à¹àžàžàžàž²àž§àž£àžàž­àžà¹àžàž£à¹àžàž£àž¡àžàž£àžµàžàžªà¹àžàž  
+
+GreenstoneMETSPlugout.desc:àž£àž¹àžà¹àžàž METS àžàžµà¹à¹àžà¹à¹àžàž£à¹àžàž¥à¹ Greenstone  
+
+MARCXMLPlugout.desc:àž£àž¹àžà¹àžàž MARC XML  
+MARCXMLPlugout.group:àžªà¹àžàž­àž­àžàž£àž°à¹àžàžµàž¢àž MARC XML àž¥àžà¹àžà¹àžà¹àž¡à¹àžàžµà¹àž¢àž§  
+MARCXMLPlugout.mapping_file:àžàž·à¹àž­à¹àžà¹àž¡àžàž²àž£à¹àž¡àžàžªàž³àž«àž£àž±àžàžàž²àž£à¹àžàž¥àžàžà¹àž­àž¡àž¹àž¥  
+
+METSPlugout.desc:àžàž¥àž²àžªàžàž·à¹àžàžàž²àžàžàž¥àž±à¹àžà¹àž­àž²àžà¹àžªàž³àž«àž£àž±àžàž£àž¹àžà¹àžàž METS àžàž±àžà¹àžàž£àžµàž¢àž¡àžàž±àžàžà¹àžàž±àžàžàž²àž£àžàž³àžàž²àžàžàžµà¹à¹àžà¹àž£à¹àž§àž¡àžàž±àžàžªàž³àž«àž£àž±àžà¹àžàž£à¹àžàž¥à¹àžà¹àž²àžà¹ à¹àžà¹àž GreenstoneMETS à¹àž¥àž° FedoraMETS àžàž£à¹àž­àž¡àžàž±à¹àž Abstract Methods  
+METSPlugout.xslt_txt:à¹àžàž¥àžà¹àžà¹àž¡ doctxt.xml àžàž­àž METS àžà¹àž§àž¢ XSLT à¹àžà¹àžà¹àž¡àžàžµà¹àž£àž°àžàžž  
+METSPlugout.xslt_mets:à¹àžàž¥àžà¹àžà¹àž¡ docmets.xml àžàž­àž METS àžà¹àž§àž¢ XSLT à¹àžà¹àžà¹àž¡àžàžµà¹àž£àž°àžàžž  
+
+#
+# Perl module strings
+#
+
+classify.could_not_find_classifier:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžàžàžàž±àž§à¹àž¢àžàžàž£àž°à¹àž àž \"%s\"  
+
+download.could_not_find_download:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžàžà¹àž¡àžàž¹àž¥àžàž²àž§àžà¹à¹àž«àž¥àž \"%s\"  
+
+plugin.could_not_find_plugin:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžàžàžàž¥àž±à¹àžàž­àžŽàž \"%s\"  
+
+plugin.including_archive:àž£àž§àž¡àžàž¶àžà¹àžàž·à¹àž­àž«àž²àžàž­àžà¹àžà¹àž¡à¹àžà¹àžàžàž²àž§àž£ ZIP/TAR 1 à¹àžà¹àž¡  
+
+plugin.including_archives:àž£àž§àž¡àžàž¶àžà¹àžàž·à¹àž­àž«àž²àžàž­àžà¹àžà¹àž¡à¹àžà¹àžàžàž²àž§àž£ ZIP/TAR %d à¹àžà¹àž¡  
+
+plugin.kill_file:àžàž²àž£àžàž£àž°àž¡àž§àž¥àžàž¥àžàž¹àžàžàž³àžàž±àžà¹àžàž¢à¹àžà¹àž¡ .kill  
+
+plugin.n_considered:à¹àž­àžàžªàž²àž£àžàž³àžàž§àž %d àžàžàž±àžà¹àžà¹àž£àž±àžàžàž²àž£àžàžŽàžàž²àž£àžàž²à¹àž«à¹àžàž£àž°àž¡àž§àž¥àžàž¥  
+
+plugin.n_included:%d àžàž¹àžàžàž£àž°àž¡àž§àž¥àžàž¥ à¹àž¥àž°àž£àž§àž¡à¹àžà¹àž²à¹àžàžàž­àž¥à¹àž¥àžàžàž±àž  
+
+plugin.n_rejected:%d àžàž¹àžàžàžàžŽà¹àžªàž  
+
+plugin.n_unrecognised:à¹àž¡à¹àž£àž¹à¹àžàž±àž %d  
+
+plugin.no_plugin_could_process:àžàž³à¹àžàž·àž­àž: à¹àž¡à¹àž¡àžµàžàž¥àž±à¹àžàž­àžŽàžà¹àžàžàžµà¹àžªàž²àž¡àž²àž£àžàžàž£àž°àž¡àž§àž¥àžàž¥ %s à¹àžà¹  
+
+plugin.no_plugin_could_recognise:àžàž³à¹àžàž·àž­àž: à¹àž¡à¹àž¡àžµàžàž¥àž±à¹àžàž­àžŽàžà¹àžàžàžµà¹àž£àž¹à¹àžàž±àž %s  
+
+plugin.no_plugin_could_process_this_file:à¹àž¡à¹àž¡àžµàžàž¥àž±à¹àžàž­àžŽàžà¹àžàžàžµà¹àžªàž²àž¡àž²àž£àžàžàž£àž°àž¡àž§àž¥à¹àžà¹àž¡àžàžµà¹à¹àžà¹  
+
+plugin.no_plugin_could_recognise_this_file:à¹àž¡à¹àž¡àžµàžàž¥àž±à¹àžàž­àžŽàžàžàžµà¹àž£àž¹à¹àžàž±àžà¹àžà¹àž¡àžàžµà¹  
+
+plugin.one_considered:à¹àž­àžàžªàž²àž£ 1 àžàžàž±àžà¹àžà¹àž£àž±àžàžàž²àž£àžàžŽàžàž²àž£àžàž²à¹àž«à¹àžàž£àž°àž¡àž§àž¥àžàž¥  
+
+plugin.one_included:1 àžàž¹àžàžàž£àž°àž¡àž§àž¥àžàž¥ à¹àž¥àž°àž£àž§àž¡à¹àžà¹àž²à¹àžàžàž­àž¥à¹àž¥àžàžàž±àž  
+
+plugin.one_rejected:1 àžàž¹àžàžàžàžŽà¹àžªàž  
+
+plugin.one_unrecognised:à¹àž¡à¹àž£àž¹à¹àžàž±àž 1  
+
+plugin.see_faillog:àžàž¹ %s àžªàž³àž«àž£àž±àžàž£àž²àž¢àžàž²àž£à¹àž­àžàžªàž²àž£àžàžµà¹à¹àž¡à¹àž£àž¹à¹àžàž±àž à¹àž¥àž°/àž«àž£àž·àž­àžàž¹àžàžàžàžŽà¹àžªàž  
+
+PrintUsage.default:àžà¹àž²à¹àž£àžŽà¹àž¡àžà¹àž  
+
+PrintUsage.required:àžàž³à¹àžà¹àž  
+
+plugout.could_not_find_plugout:àžà¹àž­àžàžŽàžàžàž¥àž²àž: à¹àž¡à¹àžàžàžàž¥àž±à¹àžà¹àž­àž²àžà¹ \"%s\"  
Index: /gsdl/stable/perllib/strings_zh.properties
===================================================================
--- /gsdl/stable/perllib/strings_zh.properties	(revision 20131)
+++ /gsdl/stable/perllib/strings_zh.properties	(revision 20131)
@@ -0,0 +1,1764 @@
+#
+# Resource bundle description
+#
+
+Language.code:zh  
+Language.name:è±è¯­  
+
+OutputEncoding.unix:utf-8  
+OutputEncoding.windows:utf-8  
+
+
+#
+# Common output messages and strings
+#
+
+common.cannot_create_file:éè¯¯ïŒæ æ³åå»ºæä»¶ïŒ
+s  
+
+common.cannot_find_cfg_file:éè¯¯ïŒæ æ³æŸå°é
+çœ®æä»¶ïŒ
+s  
+
+common.cannot_open:éè¯¯ïŒæ æ³æåŒïŒ
+s  
+
+common.cannot_open_fail_log:éè¯¯ïŒæ æ³æåŒæ¥å¿æä»¶ïŒ
+S  
+
+common.cannot_open_output_file:éè¯¯ïŒæ æ³æåŒèŸåºæä»¶ïŒ
+s  
+
+common.cannot_read:éè¯¯ïŒæ æ³è¯»åïŒ
+s  
+
+common.cannot_read_file:éè¯¯ïŒæ æ³è¯»åæä»¶ïŒ
+s  
+
+common.general_options:éçšéé¡¹ïŒçšäºïŒ
+sïŒ  
+
+common.must_be_implemented:åœæ°å¿
+é¡»åšå­ç±»äž­å®ç°ã  
+
+common.options:éé¡¹  
+
+common.processing:å€ç  
+
+common.specific_options:å
+·äœéé¡¹  
+
+common.usage:çšæ³  
+
+common.info:ä¿¡æ¯  
+
+common.invalid_options:éæ³éé¡¹ïŒïŒ
+s  
+
+common.true:ç  
+
+common.false:å  
+
+common.deprecated:éå  
+#
+# Script option descriptions and output messages
+#
+
+scripts.language:çšäœç§è¯­èšæŸç€ºéé¡¹æè¿°ïŒäŸåŠ'en US'æå®çŸåœè±è¯­ïŒãèŠæ±éé¡¹æè¿°çç¿»è¯å¿
+é¡»èœåšperllib/strings_language-code.rbæä»¶äž­æŸå°ã  
+
+scripts.xml:ä»¥XMLåœ¢åŒäº§çä¿¡æ¯ïŒæ éåäžœçè¯è¿°äœèŠè¯Šç»ã  
+
+scripts.listall:ååºå·²ç¥ææé¡¹ç®çéé¡¹ã  
+
+scripts.describeall:æŸç€ºå·²ç¥ææé¡¹ç®çéé¡¹ã  
+
+scripts.both_old_options:è­ŠåïŒéé¡¹-removeoldäž-keepoldæ-incrementaläžèµ·è®Ÿå®ïŒåå®æ¡ä»¶äžº-removeoldãïŒ
+sç®åœäžçåœåå
+å®¹å°è¢«å é€ã  
+
+scripts.no_old_options:è­ŠåïŒéé¡¹-removeold, -keepold æ -incrementaläž­çäžäžªå¿
+é¡»æå®ïŒåå®äžº-removeoldãïŒ
+sç®åœäžçåœåå
+å®¹å°è¢«å é€ã  
+
+scripts.gli:ä»GLIäž­è¿è¡è¯¥èæ¬çåæ°ïŒæ¿æŽ»äžéšçGLIèŸåºã  
+
+# -- buildcol.pl --
+
+buildcol.archivedir:å­æ¡£æä»¶å­æŸå€  
+
+buildcol.builddir:çŽ¢åŒå­æŸå€  
+
+buildcol.cachedir:åšå€å¶å°åå»ºç®åœäžä¹åæ¶èäŒææ¶å­æŸåšè¿éã  
+
+buildcol.cannot_open_cfg_file:è­ŠåïŒæ æ³æåŒé
+çœ®æä»¶è¿è¡åçº§ïŒïŒ
+s  
+
+buildcol.collectdir:âcollectâç®åœçè·¯åŸ  
+
+buildcol.copying_back_cached_build:å€å¶åçŒå­çåå»º  
+
+buildcol.create_images:è¯åŸäžºæ°æ¶èåå»ºåå®åŸåãè¿æèµäºå·²ç»å®è£
+äºGimpä»¥åçžå
+³çperlæš¡åã  
+
+buildcol.debug:å°èŸåºåéå°STDOUT  
+
+buildcol.desc:çšäºä»å­æ¡£ææ¡£äž­åå»ºGreenstoneéŠèçPERLèæ¬ã  
+
+buildcol.faillog:éè¯¯æ¥å¿æä»¶åãè¯¥æ¥å¿å­åšæææ æ³è¢«å€ççæä»¶çåå­ã  
+
+buildcol.incremental_default_builddir:è­ŠåïŒçŒºççåå»ºç®åœäžºâbuildingâãåŠæäœ æ³ä»¥éå¢çæ¹åŒæ·»å å°çŽ¢åŒç®åœïŒè¯·äœ¿çšbuildcol.plçâ-builddir indexâéé¡¹ã  
+
+buildcol.index:åŸ
+åå»ºççŽ¢åŒïŒåŠææªè®Ÿå®ïŒååå»ºé
+çœ®æä»¶äž­çå
+šéšçŽ¢åŒïŒã  
+
+buildcol.incremental:ä»
+åªä»¥åæªè¢«çŽ¢åŒè¿ççŽ¢åŒææ¡£ãè¿æå³ç-keepoldéé¡¹ãäŸèµäºluceneçŽ¢åŒåšã  
+
+buildcol.keepold:äžæž
+é€åå»ºç®åœäžçåœåå
+å®¹ã  
+
+buildcol.maxdocs:åŸ
+åå»ºææ¡£çæå€§åŒã  
+buildcol.maxnumeric:çŽ¢åŒåºäž­äžäžªâè¯âæèœå«æçæå€çäœæ°ãå€§çæ°å­äŒåå²æå äžªè¯ä»¥äŸ¿æé çŽ¢åŒãäŸåŠïŒåŠææå€§äœæ°æ¯4ïŒâ1342663âäŒåå²æâ1342"å"663"ã  
+buildcol.mode:åå»ºè¿çšäž­å°è¢«å®æœçéšåã  
+buildcol.mode.all:å
+šéšå®æœã  
+buildcol.mode.build_index:ä»
+åå»ºææ¬ççŽ¢åŒã  
+buildcol.mode.compress_text:ä»
+åçŒ©ææ¬ã  
+buildcol.mode.infodb:ä»
+åå»ºmetadataæ°æ®åºã  
+
+buildcol.no_default_images:äžäŒçæåå®åŸå  
+
+buildcol.no_image_script:è­ŠåïŒæ æ³æŸå°åŸåçæèæ¬ïŒïŒ
+s  
+
+buildcol.no_strip_html:äžèŠä»çŽ¢åŒææ¬äž­å»é€htmlæ ç­ŸïŒä»
+éçšäºmgppæ¶èïŒã  
+
+buildcol.no_text:äžèŠå­åšåçŒ©ææ¬ãåŠæèŠåšè¿è¡ç¶æäžæŸç€ºåå§ææ¡£ïŒè¯¥éé¡¹æå©äºåå°æåå»ºçŽ¢åŒçå€§å°ïŒå³ïŒå°æ æ³åŸå°åçŒ©çææ¬ïŒã  
+
+buildcol.sections_index_document_metadata:æ®µèœçº§å«äžççŽ¢åŒææ¡£metadataã  
+buildcol.sections_index_document_metadata.never:äžèŠåšæ®µèœçº§å«åå»ºä»»äœææ¡£çº§metadataã  
+buildcol.sections_index_document_metadata.always:å³äœ¿æ®µèœçº§å«metadataå­åšïŒä¹èŠæ·»å æææå®çææ¡£çº§metadataã  
+buildcol.sections_index_document_metadata.unless_section_metadata_exists:ä»
+åœæææ®µèœçº§metadataäžå­åšæ¶ææ·»å ææ¡£çº§metadataã  
+
+buildcol.out:å­åšèŸåºç¶æçæä»¶åã  
+
+buildcol.params:ãéé¡¹ãæ¶èçåç§°  
+
+buildcol.remove_empty_classifications:éèç©ºçåç±»åšååç±»èç¹ïŒå³é£äºäžå«ææ¡£çèç¹ïŒ  
+
+buildcol.removeold:å é€åå»ºç®åœäžçæ§ææ¡£ã  
+
+buildcol.unlinked_col_images:æ¶èäž­çåŸåå¯èœæªè¢«æ­£ç¡®éŸæ¥ã  
+
+buildcol.unknown_mode:æªç¥æš¡åŒïŒïŒ
+s  
+
+buildcol.updating_archive_cache:åçº§å­æ¡£çŒå­  
+
+buildcol.verbosity:æ§å¶èŸåºçæ°éã0ïŒæ ïŒ3ïŒåŸå€  
+
+
+# -- classinfo.pl --
+
+classinfo.collection:äžºæ¶èåœåäŒä»€classinfo.pléŠå
+åšcollect/collection-name/perllib/classifyäž­æå¯»ãåŠæåšé£éæŸäžå°åç±»åšïŒåæå¯»perllib/classifyç®åœã  
+
+classinfo.desc:æå°æå
+³åç±»åšçä¿¡æ¯ã  
+
+classinfo.general_options:éçšéé¡¹ä»åç±»åšçç¶ç±»ç»§æ¿ã  
+
+classinfo.info:ä¿¡æ¯  
+
+classinfo.no_classifier_name:éè¯¯ïŒå¿
+é¡»æäŸåç±»åšåç§°ã  
+
+classinfo.option_types:åç±»åšå¯æ¥åäž€ç§éé¡¹ã  
+
+classinfo.params:ãéé¡¹ãåç±»åšåç§°  
+
+classinfo.passing_options:å¯å°éé¡¹å
+æ¬åšcollect.cfgé
+çœ®æä»¶äž­ä»èäŒ éç»å
+¶ä»åç±»åšã  
+
+classinfo.specific_options:å®ä¹åšåç±»åšäž­çå
+·äœéé¡¹ïŒäžåªéçšäºè¯¥åç±»åšã  
+
+# -- downloadfrom.pl --
+downloadfrom.cache_dir:çŒå­ç®åœçäœçœ®ã  
+downloadfrom.desc:ä»å€çœ®æå¡åšäžèœœçæä»¶ã  
+downloadfrom.download_mode:äžèœœæå¡åšçç±»åã  
+downloadfrom.download_mode.Web:HTTP  
+downloadfrom.download_mode.MediaWiki:MediaWikiçœç«ã  
+downloadfrom.download_mode.OAI:Open Archives Initiative  
+downloadfrom.download_mode.z3950:z3950 æå¡åš  
+downloadfrom.download_mode.SRW:SearchRetrieve çœäžæå¡ã  
+downloadfrom.incorrect_mode:download_modeéé¡¹éè¯¯  
+downloadfrom.info:ååºæå¡åšä¿¡æ¯ïŒäžèŠäžèœœã  
+downloadfrom.params:ãéçšéé¡¹ããå
+·äœäžèœœéé¡¹ã  
+
+# -- downloadinfo.pl --
+
+downloadinfo.desc:ååºäžèœœæš¡åçä¿¡æ¯ã  
+downloadinfo.collection:äžºæ¶èåœåäŒä»€downloadinfo.pléŠå
+åšcollect/collection-name/perllib/downloadersäž­æå¯»ãåŠæåšé£éæŸäžå°åç±»åšïŒåæå¯»perllib/downloadersç®åœã  
+downloadinfo.params:ãéé¡¹ããäžèœœæš¡åã  
+downloadinfo.general_options:éçšéé¡¹ä»äžèœœæš¡åçç¶ç±»ç»§æ¿ã  
+downloadinfo.specific_options:å®ä¹åšäžèœœæš¡åäž­çå
+·äœéé¡¹ïŒäžåªéçšäºè¯¥äžèœœåšã  
+downloadinfo.option_types:äžèœœæš¡åå¯æ¥åäž€ç§éé¡¹ã  
+
+# -- explode_metadata_database.pl --
+explode.desc:æ¿åäžäžªmetadataæ°æ®åºã  
+
+explode.collection:éŠèåç§°ãæäºæä»¶äŒå¯»æŸéŠèæä»¶å€¹äž­çéå±æä»¶ã  
+ 
+explode.document_field:è®Ÿå®èŠè·ååå
+æ¬åšæ¶èäž­çææ¡£çæä»¶åçmetadataå
+çŽ ã  
+
+explode.document_prefix:ææ¡£äœçœ®çåçŒïŒçšäºææ¡£åéé¡¹ïŒã  
+
+explode.document_suffix:ææ¡£äœçœ®çåçŒïŒçšäºææ¡£åéé¡¹ïŒã  
+
+explode.encoding:çšäºåœè¯»å
+¥æ°æ®åºæä»¶æ¶ççŒç ã  
+explode.metadata_set:çšäºèŸåºææmetadataçmetadataç»ïŒåè¯åºéŽïŒã  
+explode.plugin:çšäºæ¿åçæä»¶ã  
+explode.plugin_options:åšæ©å±ä¹åäŒ éå°æä»¶çéé¡¹ãéé¡¹åç§°å¿
+é¡»ä»¥ïŒåŒå€Žãéé¡¹ååéé¡¹åŒä»¥ç©ºæ ŒéŽéãäžèœäž-use_collection_plugin_optionså
+±çšã  
+explode.use_collection_plugin_options:è¯»å
+¥éŠèé
+çœ®æä»¶å¹¶äœ¿çšç¹å®æä»¶çéé¡¹ãèŠæ±æ-collectionéé¡¹ãäžèœäž-plugin_optionså
+±çšã  
+explode.params:ãéé¡¹ãæä»¶å  
+explode.records_per_folder:å­å
+¥æ¯äžªå­æä»¶å€¹çè®°åœçæ°éã  
+
+# -- replace_srcdoc_with_html.pl --
+srcreplace.desc:åšéå»ºæ¶çšçæçHTMLæä»¶æ¿æ¢æºææ¡£ã  
+srcreplace.params:[éé¡¹]æä»¶å  
+srcreplace.plugin:çšæ¥èœ¬æ¢æºææ¡£çæä»¶  
+
+# -- exportcol.pl --
+
+exportcol.out:å­åšèŸåºç¶æçæä»¶åã  
+exportcol.cddir:èŸåºCDå
+å®¹çç®åœåã  
+exportcol.cdname:CD-ROMçåå­ïŒäžæŠCD-ROMå®è£
+å®æ¯ååºç°åšåŒå§èåçåå­ã  
+exportcol.desc:çšäºèŸåºäžäžªæå€äžªWindows CD-ROMçPERLèæ¬  
+exportcol.noinstall:çæäžäžªå¯çŽæ¥è¿è¡åŸä¹ŠéŠçCD-ROMäžäžåšè¿è¡è®¡ç®æºäžå®è£
+ä»»äœå
+å®¹  
+exportcol.params:ãéé¡¹ãæ¶èå1ïŒæ¶èå2âŠ  
+exportcol.coll_not_found:å¿œç¥æ ææ¶èïŒ
+sïŒæ æ³æŸå°ç®åœïŒ
+s  
+exportcol.coll_dirs_not_found:å¿œç¥æ ææ¶èïŒ
+sïŒä»¥äžç®åœäž­çäžäžªæ æ³æŸå°ïŒ  
+exportcol.fail:exportcol.plå€±èŽ¥:  
+exportcol.no_valid_colls:æ æææå®çæ¶èå¯ä»¥èŸåºã  
+exportcol.couldnt_create_dir:æ æ³åå»ºç®åœïŒ
+s  
+exportcol.couldnt_create_file:æ æ³åå»ºïŒ
+s  
+exportcol.instructions:çæäžäžªèªæå®è£
+çWindows CD-ROMïŒå°è¯¥æä»¶å€¹ååºè³CD-ROMã  
+exportcol.non_exist_files:ä»¥äžå¿
+èŠçæä»¶åç®åœäž­çäžäžªäžå­åšïŒ  
+exportcol.success:exportcol.plè¿è¡æåïŒ  
+exportcol.output_dir:èŸåºçæ¶èåšïŒ
+s  
+exportcol.export_coll_not_installed:èŸåºè³CD-ROMçåèœæªè¢«å®è£
+ã  
+
+# -- import.pl --
+
+import.archivedir:èœ¬æ¢æä»¶çç®æ ç®åœã  
+
+import.manifest:äžäžªè¯Šç»æè¿°ä»ä¹æ ·çæä»¶å¯è¢«èŸå
+¥çXMLæä»¶ãçšäºæ¿ä»£åµå¥åŒåäžéåèŸå
+¥æä»¶å€¹æ¹åŒïŒéåžžçšäºéå¢åŒåå»ºã  
+
+import.cannot_open_stats_file:è­ŠåïŒæ æ³æåŒç»è®¡æä»¶ïŒ
+s  
+
+import.cannot_open_fail_log:éè¯¯ïŒæ æ³æåŒéè¯¯æ¥å¿ïŒ
+s  
+
+import.cannot_sort:è­ŠåïŒåœgroupsize>1æ¶import.plæ æ³æåææ¡£ãSortmetaéé¡¹å°è¢«å¿œç¥ã  
+
+import.collectdir:"collectâç®åœçè·¯åŸã  
+
+import.complete:èŸå
+¥å®æã  
+
+import.debug:æå°èŸå
+¥ææ¬è³STDOUTïŒçšäºGreenstoneXMLå¯Œå
+¥ïŒã  
+
+import.desc:PERLèæ¬ïŒçšäºå°æä»¶å¯Œå
+¥æå¯äŸåå»ºçæ ŒåŒïŒGreenstoneXMLæè
+GreenstoneMETSïŒã  
+
+import.faillog:å€±èŽ¥æ¥å¿æä»¶åãè¯¥æ¥å¿å­æä»»äœæ æ³è¢«å€ççæä»¶åã  
+
+import.groupsize:ç»ååšäžäžªXMLæä»¶äž­çææ¡£æ°éã  
+
+import.gzip:äœ¿çšgzipåçŒ©çæçxmlææ¡£ïŒåœä»åçŒ©ææ¡£æå»ºæ¶èæ¶äžèŠå¿è®°æZIPPluginæ·»å å°æä»¶åè¡šäž­ïŒã  
+
+import.importdir:åå§æä»¶å­æŸå€  
+
+import.incremental:ä»
+èŸå
+¥æ¯åœåå­æ¡£æä»¶æ°çææ¡£ïŒæ ¹æ®æ¶éŽæ è®°ïŒã  
+
+import.keepold:äžæž
+é€å­æ¡£ç®åœäžçåœåå
+å®¹ã  
+
+import.maxdocs:åŸ
+èŸå
+¥ææ¡£çæå€§åŒã  
+
+import.no_import_dir:éè¯¯ïŒæ æ³æŸå°èŸå
+¥ç®åœïŒïŒ
+sïŒã  
+
+import.no_plugins_loaded:éè¯¯ïŒæ æä»¶è¢«è°å
+¥ã  
+
+import.OIDtype:çšäºäžºæ¯äžäžªææ¡£çæç¬ç¹æ å¿ç¬Šçæ¹æ³ã  
+import.OIDtype.hash:åªåæä»¶çå
+å®¹ãæ¶èåšæ¯æ¬¡è¢«èŸå
+¥æ¶ææ¡£çæ å¿ç¬Šäžåã  
+
+import.OIDtype.incremental:äœ¿çšç®åææ¡£è®¡æ°ãæ¯"hash"å€§å€§å å¿«ïŒäœåæ ·çææ¡£å
+å®¹äŒæäžåçæ å¿ç¬ŠïŒäžéåçææ¡£æ æ³å å
+¥å°ç°æçå­æ¡£äž­ã  
+
+import.OIDtype.assigned:äœ¿çšç±OIDmetadataéé¡¹æç»åºçmetadataçåŒïŒå«æ'D'åçŒïŒïŒåŠææªæå®ïŒåäœ¿çšå
+·äœææ¡£çåªååŒãè¿äºæ å¿ç¬Šå¿
+é¡»æ¯ç¬ç¹çã  
+
+import.OIDtype.dirname:äœ¿çšç¶ç®åœåå­ïŒå«æ'J'åçŒïŒãâäžç®åœäžäžå¯¹åºïŒäžç®åœåå­äžéå€ãäŸåŠïŒimport/b13as/h15ef/page.htmlçæ å¿ç¬ŠåºäžºJh15efã  
+
+import.OIDmetadata:çšäºæå®ææææ¡£çç¬ç¹æ å¿ç¬Šçmetadataå
+çŽ ïŒäž-OLDtype=assignedåæ¶äœ¿çšã  
+
+import.saveas:å­æ¡£æä»¶çæ ŒåŒã  
+
+import.out:å­åšèŸåºç¶æçæä»¶åã  
+
+import.params:ãéé¡¹ãæ¶èçåç§°  
+
+import.removeold:æž
+é€å­æ¡£ç®åœäžçæ§å
+å®¹ã  
+
+import.removing_archives:æž
+é€å­æ¡£ç®åœäžçåœåå
+å®¹ã  
+
+import.removing_tmpdir:æž
+é€æ¶èç"tmp"ç®åœäžçå
+å®¹ã  
+
+import.reversesort:ååæåºïŒçš-sortmetaéé¡¹ã  
+
+import.site:éŠèç®åœæåšçç«ç¹ïŒå¯¹Greenstone3ïŒã  
+
+import.sortmeta:æå­æ¯é¡ºåºæ ¹æ®metadataå¯¹ææ¡£è¿è¡æåïŒçšäºåå»ºãåžå°æ¥è¯¢çæçŽ¢ç»ææè¯¥é¡ºåºæŸç€ºãåœgroupsize > 1æ¶æŸç€ºãä¹è®žæ¯äžäžªéå·åéçéïŒæå€äžªmetadataåŒæåºã  
+
+import.statsfile:å­åšèŸå
+¥ç»è®¡æ°æ®çæä»¶åã  
+
+import.stats_backup:æå°ç»è®¡æ°æ®è³STDERRã  
+
+import.verbosity:æ§å¶èŸåºçæ°éã0ïŒæ ïŒ3ïŒåŸå€  
+
+# -- schedule.pl --
+schedule.deleted:æ¬éŠèæå é€çéå»º  
+schedule.scheduled:äžºæ¬éŠèåå»ºçè¿è¡èæ¬  
+schedule.cron:æ¬éŠèæå®æçéå»º  
+schedule.params:[éé¡¹]  
+schedule.error.email:-emailèŠæ±è®Ÿçœ®-smtpã-toaddrå-fromaddr  
+schedule.error.importbuild:å¿
+é¡»è®Ÿçœ®-importå-build  
+schedule.error.colname:å¿
+é¡»çš-colnameæå®éŠèã  
+schedule.gli:ä»GLIäž­è¿è¡  
+schedule.frequency:èªåšéå»ºéŠèçé¢ç  
+schedule.frequency.hourly:æ¯å°æ¶éå»ºäžæ¬¡  
+schedule.frequency.daily:æ¯å€©éå»ºäžæ¬¡  
+schedule.frequency.weekly:æ¯åšéå»ºäžæ¬¡  
+schedule.action:åŠäœè®Ÿçœ®èªåšéå»º  
+schedule.action.add:å®æèªåšéå»ºçæ¶éŽè¡š  
+schedule.action.update:æŽæ°ç°æçæ¶éŽè¡š  
+schedule.action.delete:å é€ç°æçæ¶éŽè¡š  
+schedule.email:åéemailéç¥  
+schedule.schedule:è®Ÿçœ®èªåšéå»ºçæ¶éŽè¡š  
+schedule.colname:å®ææ¶å»è¡šçç®æ éŠèåç§°  
+schedule.import:å¯¹è¿äžªimportïŒå¯Œå
+¥ïŒåœä»€å®ææ¶å»è¡š  
+schedule.build:å¯¹è¿äžªbuildcolåœä»€å®ææ¶å»è¡š  
+schedule.toaddr:å°å®æ¶åå»ºçéç¥åéå°è¿äžªemailå°å  
+schedule.toaddr.default:åšæä»¶->åå¥œäž­è®Ÿçœ®çšæ·çemail  
+schedule.fromaddr:åéè
+emailå°å  
+schedule.fromaddr.default:åšmain.cfgäž­æå®éŠèçç»Žæ€è
+  
+schedule.smtp:åéemailçšå°çé®ä»¶æå¡åš  
+schedule.smtp.default:åšmain.cfgäž­æå®é®ä»¶æå¡åš  
+schedule.out:çšæ¥ä¿å­èŸåºç¶æçæä»¶åæå¯¹è±¡  
+# -- export.pl --
+
+export.exportdir:èŸåºæä»¶çç®æ ç®åœã  
+
+export.cannot_open_stats_file:è­ŠåïŒæ æ³æåŒç»è®¡æä»¶ïŒ
+s  
+
+export.cannot_open_fail_log:éè¯¯ïŒæ æ³æåŒéè¯¯æ¥å¿ïŒ
+s  
+
+export.cannot_sort:è­ŠåïŒåœgroupsize>1æ¶export.plæ æ³å¯¹ææ¡£æåºãSortmetaéé¡¹è¢«å¿œç¥ã  
+
+export.collectdir:âcollectâç®åœçè·¯åŸã  
+
+export.complete:èŸåºå®æ  
+
+export.debug:æå°èŸåºçææ¬è³STDOUTïŒçšäºGreenstoneXMLå¯ŒåºïŒ  
+
+export.desc:çšäºå°Greenstoneæ¶èäž­çæä»¶èŸåºæåŠäžç§æ ŒåŒçPERLèæ¬  
+
+export.faillog:éè¯¯æ¥å¿æä»¶åãè¯¥æ¥å¿å­åšæææ æ³è¢«å€ççæä»¶çåå­ãïŒåå®æ¡ä»¶äžïŒcollectdir/collname/etc/fail.log).  
+
+export.groupsize:ç»ååšäžäžªXMLæä»¶äž­çææ¡£æ°éã  
+
+export.gzip:çšgzipåçŒ©çæçxmlææ¡£ïŒåœä»åçŒ©ææ¡£æå»ºæ¶èæ¶äžèŠå¿è®°å°ZIPPlugæ·»å å°æä»¶åè¡šäž­ïŒã  
+
+export.importdir:åå§æä»¶å­æŸå€  
+
+export.keepold:äžæž
+é€èŸåºç®åœäžçåœåå
+å®¹ã  
+
+export.maxdocs:èŸåºææ¡£çæå€§æ°éã  
+
+export.listall:ååºææå­åšçæ ŒåŒ  
+
+export.saveas:èŸåºææ¡£çæ ŒåŒã  
+
+export.saveas.DSpace:DSpace Archiveæ ŒåŒã  
+
+export.saveas.GreenstoneMETS:METSæ ŒåŒïŒäœ¿çšGreenstoneæ ŒåŒã  
+export.saveas.FedoraMETS:METSæ ŒåŒïŒäœ¿çšFedoraæ ŒåŒã  
+
+export.saveas.GreenstoneXML:Greenstone XML å­æ¡£æ ŒåŒ  
+
+export.saveas.MARCXML:MARC XMLæ ŒåŒïŒäžäžªMARC 21çXMLçæ¬ïŒ  
+
+export.out:å­åšèŸåºç¶æçæä»¶åã  
+
+export.params:ãéé¡¹ãæ¶èå  
+
+export.removeold:å é€èŸåºç®åœäžçæ§ææ¡£ã  
+
+export.removing_export:å é€èŸåºç®åœäžçåœåææ¡£ã  
+
+export.sortmeta:æå­æ¯é¡ºåºæ ¹æ®metadataå¯¹ææ¡£è¿è¡æåïŒçšäºåå»ºãåœgroupsize>1æ¶è¯¥éé¡¹äŒè¢«çŠçšã  
+
+export.statsfile:å­åšèŸåºç»è®¡æ°æ®çæä»¶åã  
+
+export.stats_backup:æå°ç»è®¡æ°æ®è³STDERRã  
+
+export.verbosity:æ§å¶èŸåºçæ°éã0ïŒæ ïŒ3ïŒåŸå€  
+
+
+
+# -- mkcol.pl --
+
+mkcol.about:æ¶èçâå
+³äºâæè¿°ã  
+
+mkcol.bad_name_cvs:éè¯¯ïŒæ¶èäžå¯è¢«åœåäžºCVSïŒå äžºè¿å°äžCVSçæ¬ç³»ç»çæçç®åœçžå²çªã  
+
+mkcol.bad_name_svn:éè¯¯ïŒäžå¯å°éŠèåœåäžº.svnïŒå äžºè¿å¯èœäŒäžSVNçæ¬ç³»ç»åå»ºçç®åœå²çªã  
+
+mkcol.bad_name_modelcol:éè¯¯ïŒæ¶èäžå¯è¢«åœåäžºmodelcolïŒå äžºè¿æ¯èäŸæ¶èçåå­ã  
+
+mkcol.cannot_find_modelcol:éè¯¯ïŒæ æ³æŸå°èäŸæ¶èïŒ
+s  
+
+mkcol.col_already_exists:éè¯¯ïŒè¯¥æ¶èå·²ç»å­åšã  
+
+mkcol.collectdir:å­æŸæ°æ¶èçç®åœã  
+
+mkcol.group_not_valid_in_gs3:ç»éé¡¹åšGreenstone3æš¡åŒïŒ-gs3modeïŒäž­äžå¯çšã  
+mkcol.creating_col:çææ¶èïŒ
+s  
+
+mkcol.creator:æ¶èåå»ºè
+ççµå­é®ä»¶å°åã  
+
+mkcol.creator_undefined:éè¯¯ïŒåå»ºè
+æªè¢«å®ä¹ãè¯¥åéçšäºè¯å«éå€çæ¶èåå­ã  
+
+mkcol.desc:çšäºçææ°Greenstoneæ¶èçç®åœç»æçPERLèæ¬ã  
+
+mkcol.doing_replacements:äžºïŒ
+såæ¿æ¢  
+
+mkcol.group:åå»ºäžäžªæ°éŠèç»ïŒèäžæ¯äžäžªæ åéŠèã  
+
+mkcol.gs3mode:Greenstone 3éŠèæš¡åŒã  
+
+mkcol.long_colname:éè¯¯ïŒæ¶èåå­å¿
+é¡»å°äº8äžªå­æ¯ïŒä»¥äŸ¿äžæ©ææä»¶ç³»ç»çžå¹é
+ã  
+
+mkcol.maintainer:æ¶èç»Žæ€è
+ççµå­é®ä»¶å°åïŒåŠæäžåå»ºè
+äžåçè¯ïŒã  
+
+mkcol.no_collectdir:éè¯¯ïŒcollectç®åœäžå­åšïŒïŒ
+s  
+
+mkcol.no_collectdir_specified:éè¯¯ïŒæªç¥éŠèïŒcollectïŒç®åœïŒå¿
+é¡»è®Ÿçœ®-siteæ-collectdiréé¡¹äž­çäžäžªã  
+
+mkcol.no_colname:éè¯¯ïŒæªæå®æ¶èåç§°ã  
+
+mkcol.optionfile:ç±æä»¶åŸå°éé¡¹ïŒçšäºé¿çåœä»€è¡äŒå¯ŒèŽé®é¢çç³»ç»ã  
+
+mkcol.params:ãéé¡¹ãæ¶èåç§°  
+
+mkcol.plugin:æçšçperlæä»¶æš¡åïŒä¹è®žäŒæå€äžªæä»¶æ¡ç®ïŒã  
+
+mkcol.public:åŠæè¯¥æ¶èæå¿åè®¿é®ã  
+mkcol.public.true:æ¶èæ¯å
+¬åŒçã  
+mkcol.public.false:æ¶èæ¯ç§å¯çã  
+
+mkcol.quiet:ééçè¿è¡ã  
+
+mkcol.site:gs3modeïŒGreenstone3æš¡åŒïŒçšç«ç¹åäžGSDL3HOMEç¯å¢åéæ¥ç¡®å®éŠèç®åœïŒcollectdirïŒïŒé€éè®Ÿçœ®äº-collectdirã  
+
+mkcol.success:æ°æ¶èåšïŒ
+såå»ºæå  
+
+mkcol.title:æ¶èçæ é¢ã  
+
+mkcol.win31compat:æ¯åŠæææ¶èç®åœå¿
+é¡»äžWindows 3.1æä»¶æ ŒåŒçžç¬ŠïŒå³ïŒ8äžªå­æ¯é¿ïŒã  
+mkcol.win31compat.true:ç®åœåæé¿8äžªå­æ¯ã  
+mkcol.win31compat.false:ç®åœåå¯ä»»æé¿åºŠã  
+
+# -- pluginfo.pl --
+
+pluginfo.collection:äžºæ¶èåœåäŒä»€pluginfo.pléŠå
+åšcollect/collection-name/perllib/pluginsäž­æå¯»ãåŠæåšé£éæŸäžå°æä»¶ïŒåæå¯»perllib/pluginsç®åœã  
+
+pluginfo.desc:ååºæä»¶çä¿¡æ¯ã  
+
+pluginfo.general_options:éçšéé¡¹ä»æä»¶çç¶ç±»ç»§æ¿ã  
+
+pluginfo.info:ä¿¡æ¯  
+
+pluginfo.no_plugin_name:éè¯¯ïŒå¿
+é¡»æäŸæä»¶åç§°ã  
+
+pluginfo.option_types:æä»¶å¯æ¥åäž€ç§éé¡¹ã  
+
+pluginfo.params:ãéé¡¹ãæä»¶å  
+
+pluginfo.passing_options:å¯å°éé¡¹å
+æ¬åšcollect.cfgé
+çœ®æä»¶äž­ä»èäŒ éç»å
+¶ä»æä»¶ã  
+
+pluginfo.specific_options:å®ä¹åšæä»¶äž­çå
+·äœéé¡¹ïŒäžåªéçšäºè¯¥æä»¶ã  
+
+
+# -- plugoutinfo.pl --
+
+plugoutinfo.collection:äžºæ¶èåœåäŒä»€plugoutinfo.pléŠå
+åšcollect/collection-name/perllib/plugoutsäž­æå¯»ãåŠæåšé£éæŸäžå°æä»¶ïŒåæå¯»perllib/plugoutsç®åœã  
+
+plugoutinfo.desc:ååºplugoutçä¿¡æ¯ã  
+
+plugoutinfo.general_options:éçšéé¡¹ä»plugoutçç¶ç±»ç»§æ¿ã  
+
+plugoutinfo.info:ä¿¡æ¯  
+
+plugoutinfo.no_plugout_name:éè¯¯ïŒå¿
+é¡»æäŸplugoutçåå­ã  
+
+plugoutinfo.option_types:plugoutå¯æ¥åäž€ç§éé¡¹ã  
+
+plugoutinfo.params:ãéé¡¹ãplugoutå  
+
+plugoutinfo.passing_options:å¯å°éé¡¹å
+æ¬åšcollect.cfgé
+çœ®æä»¶äž­ä»èäŒ éç»å
+¶ä»plugoutã  
+
+plugoutinfo.specific_options:å®ä¹åšplugoutäž­çå
+·äœéé¡¹ïŒäžåªéçšäºè¯¥plugoutã  
+
+
+
+#
+# Classifier option descriptions
+#
+
+AllList.desc:åå»ºäžäžªå
+å«æææä»¶çéãçšäºoaiserverã  
+
+AZCompactList.allvalues:äœ¿çšæææŸå°ç metadata çåŒã  
+
+AZCompactList.desc:çšäºæå­æ¯é¡ºåºæåºçåç±»åšæä»¶(æa-zïŒA-ZïŒ0-9)ãéŠå
+çæäžäžªæ°Žå¹³ç A-Z åè¡šïŒç¶åçæäžäžªåçŽåè¡šïŒå
+¶äž­ååºäºææ¡£æç»ç»äºæçå
+±åå
+æ°æ®çææ¡£çä¹Šæ¶ã  
+
+AZCompactList.doclevel:å€çæä»¶æ¶æå€çæ°Žå¹³  
+AZCompactList.doclevel.top:æŽäžªæä»¶  
+AZCompactList.doclevel.section:æ ¹æ®æ®µèœ  
+
+AZCompactList.firstvalueonly:äœ¿çšæåç°çç¬¬äžäžª metadataç åŒ  
+
+AZCompactList.freqsort:æ ¹æ®èé¢çèéé¿å°å-æ°åŒè¿è¡æåã  
+
+AZCompactList.maxcompact:æ¯äžé¡µææŸç€ºçæä»¶çæå€æ°é  
+
+AZCompactList.metadata:äžäžªåäžå
+æ°æ®å­æ®µïŒæè
+äžäžªéç¹éŽéçå
+æ°æ®å­æ®µåè¡šïŒçšäºåå»ºåç±»åšãåŠææå®çæ¯å­æ®µåè¡šïŒååç±»åšå°äœ¿çšè¯¥åè¡šäž­ç¬¬äžäžªæåŒçå
+æ°æ®å­æ®µãå¯äž-firstvalueonlyå-allvaluesæ ç­Ÿè¿çšïŒæ¥éæ©åªäœ¿çšç¬¬äžäžªåŒïŒæè
+åè¡šäž­ææå
+æ°æ®å­æ®µçåŒã  
+
+AZCompactList.mincompact:æ¯äžé¡µææŸç€ºçæä»¶çæå€æ°é  
+
+AZCompactList.mingroup:äœ¿åŸåšå±çº§ç»æäž­åœ¢æäžäžªç»çæå°åŒ  
+
+AZCompactList.minnesting:çšäºå°äžäžªéèœ¬æ¢æäžäžªåµå¥éçæå°åŒ  
+
+AZCompactList.recopt:çšäºåµå¥çmetadataåŠïŒmetadata å¹Ž/ç»ç»  
+AZCompactList.sort:æåå¶èç¹çmetadataå  
+
+AZCompactSectionList.desc:çšäºåç±»æ®µèœèéæä»¶çAZCompactListåäœãæ¡ç®æ¯æç
+§æ®µèœçmetadataè¢«åç±»ç  
+
+AZList.desc:çšäºæå­æ¯é¡ºåºè¿è¡æåçåç±»åšæä»¶(æa-zïŒA-ZïŒ0-9)ãçæäžäžªæ°Žå¹³ç A-Zåè¡šïŒçžå
+³æä»¶ååšäžé¢ã  
+
+AZList.metadata:äžäžªåäžå
+æ°æ®å­æ®µïŒæè
+äžäžªéç¹éŽéçå
+æ°æ®å­æ®µåè¡šïŒçšäºåå»ºåç±»åšãæç
+§åè¡šäž­çé¡ºåºïŒåç±»åšäœ¿çšç¬¬äžäžªæåŒçå
+æ°æ®å­æ®µãææ¡£åè¡šå°æç
+§è¯¥å
+çŽ æåºã  
+
+AZSectionList.desc:çšäºåç±»æ®µèœèéæä»¶çAZListåäœãæ¡ç®æ¯æç
+§æ®µèœçmetadataè¢«åç±»ç  
+
+BasClas.bad_general_option:ïŒ
+såç±»åšäœ¿çšäºéè¯¯çéé¡¹ãæ¥çäœ çé
+çœ®æä»¶collect.cfg  
+
+BasClas.builddir:å°æå»ºçŽ¢åŒæŸåšäœå€  
+
+BasClas.buttonname:åç±»åšäžçæ ç­Ÿä»¥åå¯Œèªæ¡äžçæé®ãåå®åŒæ¯ç±-metadataéé¡¹æå®çmetadataå
+çŽ   
+
+BasClas.desc:éçšäºææåç±»åšçåºç±»  
+
+BasClas.no_metadata_formatting:äžèŠåä»»äœèªåšçmetadataæ ŒåŒåïŒåšæåºæ¶ïŒ  
+
+BasClas.outhandle:ååºæä»¶æ¶çèŸåºéé  
+
+BasClas.removeprefix:æåºæ¶metadataåŒäž­å¿œç¥çåçŒ  
+
+BasClas.removesuffix:æåºæ¶metadataåŒäž­å¿œç¥çåçŒ  
+
+BasClas.verbosity:æ§å¶èŸåºçæ°éã0ïŒæ ïŒ3ïŒåŸå€  
+
+Browse.desc:äžäžªåçä»
+åšå¯Œèªæ¡äžæäŸäžäžªéŸæ¥çåç±»åšïŒè¯¥éŸæ¥æåäžäžªæç»äºæµè§åæçŽ¢çé¡µé¢çåå§æš¡åãä»
+éçšäºmgppç±»å°åæ¶èã  
+
+DateList.bymonth:æå¹Žåæåç±»èäžæ¯åªæå¹Žã  
+
+DateList.desc:çšäºææ¥ææåºçåç±»åšæä»¶ãåå®æ¡ä»¶äžæâDate'metadataæåºãæ¥æåå®äžºyyyymmddæyyyy-mm-ddæ ŒåŒã  
+
+DateList.metadata:å«æçšæ¥åç±»çæ¥æçmetadataãæ¥ææ ŒåŒäžºyyyymmdd or yyyy-mm-ddãä¹å¯ä»¥æ¯éå·åéçéïŒåšè¿ç§æ
+åµäžäœ¿çšææŸå°çç¬¬äžäžªæ¥æã  
+
+DateList.reverse_sort:å°ææ¡£æå¹Žä»£é¡ºåºæåïŒææ°çåšåïŒã  
+
+DateList.nogroup:åšæ°Žå¹³éäž­å°æ¯äžå¹Žåäžºåç¬æ¡ç®ïŒèäžæ¯æå¹ŽåºéŽåäžºå äžªæ¡ç®ãïŒçš-bymonthéé¡¹ä¹å¯ä»€æ¯äžªæåæåç¬æ¡ç®ïŒã  
+
+DateList.no_special_formatting:äžèŠåšææ¡£éäž­æŸç€ºå¹Žåæçä¿¡æ¯ã  
+
+DateList.sort:çšäºåœäž€äžªææ¡£å«æçžåæ¥ææ¶æ¥è¿è¡æåºçé¢å€çmetadataã  
+
+HFileHierarchy.desc:åºäºäžäžªèŸ
+å©ç»ææä»¶çšäºçæå±çº§ç»æåç±»çåç±»åšæä»¶ã  
+
+Hierarchy.desc:çšäºçæå±çº§ç»æåç±»çåç±»åšæä»¶ãè¯¥æä»¶å¯åºäºç»ææ§metadataïŒæäœ¿çšäžäžªèŸ
+å©æ§ç»ææä»¶ïŒçš-hfileéé¡¹ïŒã  
+
+Hierarchy.documents_last:å°ææ¡£èç¹æŸç€ºåšåç±»åšèç¹ä¹åã  
+
+Hierarchy.hfile:äœ¿çšè®Ÿå®çåç±»ç»ææä»¶ã  
+
+Hierarchy.hlist_at_top:æ°Žå¹³å°æŸç€ºåç±»çç¬¬äžçº§ã  
+
+Hierarchy.reverse_sort:åé¡ºåºæåå¶èç¹ïŒçš-sort)ã  
+
+Hierarchy.separator:åœäœ¿çšç»ææ§metadataæ¶çšäºåçŠ»çè§åè¡šè¿°ã  
+
+Hierarchy.sort:çšäºæåå¶èç¹çmetadataåãåŠæè¯¥åæªè®Ÿå®åå¶èç¹äžäŒè¢«æåºã  
+
+Hierarchy.suppressfirstlevel:å¿œç¥metadataåŒçç¬¬äžéšåãè¿åœmetadataçç¬¬äžå
+çŽ æ¯éçšåŒæ¶æ¯èŸæçšïŒäŸåŠåšgsdlsourcefilenameäž­çèŸå
+¥ç®åœéšåã  
+
+Hierarchy.suppresslastlevel:å¿œç¥metadataåŒçæåäžéšåãè¿åœmetadataçæ¯äžªå
+çŽ éœäžåæ¶æ¯èŸæçšïŒäŸåŠæä»¶è·¯åŸã  
+
+HTML.desc:çæäžäžªç©ºçåç±»ïŒå³äžäžªå°çœé¡µçéŸæ¥ã  
+
+HTML.url:éŸæ¥å°çœé¡µçå°åã  
+
+List.bookshelf_type:æ§å¶äœæ¶å»ºç«ä¹Šæ¶ã  
+List.bookshelf_type.always:å³äœ¿å¶å­èç¹çæ¯äžªåç»éåªæäžäžªæ¡ç®ä¹äœ¿çšä¹Šæ¶åŸæ ã  
+List.bookshelf_type.never:å³äœ¿å¶å­èç¹çæ¯äžªåç»éæäžåªäžäžªæ¡ç®ïŒä¹äžäœ¿çšä¹Šæ¶åŸæ ã  
+List.bookshelf_type.duplicate_only:åœå¶å­èç¹çæ¯äžªåç»æäžåªäžäžªæ¡ç®æ¶ïŒäœ¿çšä¹Šæ¶åŸæ ã  
+
+List.classify_sections:å¯¹æ®µèœèäžæ¯ææ¡£è¿è¡åç±»ã
+
+List.desc:äžäžªéçšäžéåºæ§åŒºçéåç±»åšïŒå
+·æAZCompackListçå€§éšååèœïŒèŸå¥œçç»äžçŒç ïŒmetadataåæåºèœåã  
+
+List.level_partition.per_letter:äžºæ¯äžªå­æ¯åå»ºäžäžªååºã  
+List.level_partition.constant_size:æåºå®å€§å°åå»ºååºã  
+List.level_partition.per_letter_fixed_size:æå€§èŽåºå®çå€§å°äžºæ¯äžªå­æ¯åå»ºäžäžªååºã  
+
+List.metadata:çšäºåç±»çmetadataåãçšâ/'åçŠ»å±çº§ç»æäž­ççº§ïŒçš';'åçŠ»æ¯äžçº§çmetadataåã  
+
+List.partition_name_length:ååºåçé¿åºŠïŒåå®æ¡ä»¶äžæ¯1è³3äžªå­æ¯ïŒè¿èŠçåºåäžäžªååºçå€Žåå°ŸéèŠå€å°å­æ¯ãè¯¥éé¡¹åªæåœpartition_type_within_levelè®Ÿäžº'constant_size'æ¶æææã
+
+List.partition_size_within_level:æ¯äžªååºçå€§å°ïŒè¯¥éé¡¹åªæåœpartition_type_within_levelè®Ÿäžº'constant_size'æ¶æææïŒã
+
+List.partition_type_within_level:è¿è¡ååºçç±»åïŒâper_letter', 'constant_size', æ'none'ã
+
+List.sort_leaf_nodes_using:çšäºæåºå¶å­èç¹çå
+æ°æ®å­æ®µãçšâ|âæ¥åéçš³å®åç»çå
+æ°æ®ç»ïŒçšâ;âåéæ¯äžªç»éçå
+æ°æ®å­æ®µã  
+
+List.sort_using_unicode_collation:äœ¿çšUnicode Collationç®æ³æåºãéèŠäžèœœæä»¶http://www.unicode.org/Public/UCA/latest/allkeys.txtïŒå¹¶æŸå°perlçlib/Unicode/Collateæä»¶å€¹äž­ã  
+
+List.use_hlist_for:äœ¿çšæ°Žå¹³éèäžæ¯åçŽéçmetadataåãçš','åçŠ»metadataç»ïŒçšâ;'åçŠ»æ¯äžªç»çmetadataåã
+
+SimpleList.metadata:äžäžªåäžMetadataå, æäžäžªéç¹ååŒç Metadata åçéïŒçšäºåç±»ãæç
+§éçé¡ºåºïŒäœ¿çšç¬¬äžäžªå«æmetadataåŒçåãé€éäœ¿çšäº-sortéé¡¹ïŒéå°æç
+§è¯¥å
+çŽ æåºãåŠææªæå®metadataïŒææææ¡£å°è¢«å
+å«åšéäž­ïŒåŠååªæå«æmetadataåŒçææ¡£æäŒè¢«å
+æ¬è¿æ¥ã
+
+SimpleList.desc:ç®åéåç±»åšæä»¶ã
+
+SimpleList.sort:çšäºæåçmetadataåãçš'-sort nosort'åäžè¿è¡æåã
+
+Phind.desc:äº§çäžäžªææ¬äž­åç°çç­å¥çå±çº§ç»æïŒè¯¥ç»æå¯éè¿Javaå°çšåºæµè§ã  
+
+Phind.language:åå»ºå±çº§ç»æçè¯­èšãè¯­èšæ¯ç±äž€äžªå­æ¯çåœå®¶ç éŽå«çïŒäŸåŠ en (è±è¯­), es (è¥¿ç­çè¯­), å fr (æ³è¯­)ãè¯­èšæ¯äžäžªè§åè¡šè¿°ïŒå æ­€ 'en|fr' (è±è¯­ææ³è¯­) ä»¥å '..' (å¹é
+ä»»äœè¯­èš) éœææã  
+
+Phind.min_occurs:äžäžªç­å¥åºç°åšææ¬äž­çæå°æ¬¡æ°ïŒè¯¥ææ¬å°è¢«å
+æ¬åšç­å¥å±çº§ç»æäž­ã  
+
+Phind.savephrases:è®Ÿå®åïŒç­å¥ä¿¡æ¯äŒè¢«äœäžºææ¬å­åšåšç»å®çæä»¶äž­ãå»ºè®®äœ¿çšç»å¯¹è·¯åŸã  
+
+Phind.suffixmode:ç­å¥æåçšåºçsmodeåæ°ãåæ°åŒ0æå³çéçšè¯è¯­å°è¢«å¿œç¥ïŒåŒ1æå³çéçšè¯è¯­å°è¢«äœ¿çšã  
+
+Phind.text:è¯­èšåå»ºç­å¥å±çº§ç»æçææ¬ã  
+
+Phind.thesaurus:åšæ¶èçetcç®åœäž­å­åšçPhindæ ŒåŒçåç±»è¯æ±çŒçåå­ã  
+
+Phind.title:è¯­èšæè¿°æ¯äžªææ¡£çmetadataçåã  
+
+Phind.untidy:äžèŠå é€æ­£åšè¿è¡çæä»¶ã  
+
+RecentDocumentsList.desc:äžäžªå¯ååºæ°æ·»å çæä¿®æ¹çææ¡£çåç±»åšã  
+
+RecentDocumentsList.include_docs_added_since:ä»
+å
+æ¬åšæå®æ¥æïŒyyyymmddæyyyy-mm-ddæ ŒåŒïŒä»¥åä¿®æ¹ææ·»å çææ¡£ã  
+
+RecentDocumentsList.include_most_recently_added:ä»
+å
+æ¬æå®æ°éçïŒè¿ææ·»å çææ¡£ãä»
+åœinclude_docs_added_sinceä¿¡æ¯æªè®Ÿæ¶äœ¿çšã  
+
+RecentDocumentsList.sort:çšäºäžºéæåºçmetadataãåŠæªè®Ÿå®ïŒéå°æä¿®æ¹/æ·»å çæ¥ææåºã  
+
+SectionList.desc:äžéåç±»åšçžåäœå
+å«ææ¡£çæææ®µèœïŒäžå
+æ¬é¡¶çº§ïŒèäžæ¯ä»
+ä»
+é¡¶çº§ææ¡£èªå·±ã  
+
+Collage.desc:äžäžªJavaå°çšåºçšäºæŸç€ºæ¶èäž­æŸå°çæŒèŽŽåŸåã  
+
+Collage.geometry:æŒèŽŽç»åžçå°ºå¯žãæå®äžäžª600åçŽ å®œx400åçŽ é«çç»åžïŒåºè®Ÿäžº600x400ã  
+
+Collage.maxDepth:æŒèŽŽçåŸåæ¯ä»éåæçšæµè§åç±»åšæœåçãè¯¥éé¡¹æ§å¶éåè¿çšçæå€§æ·±åºŠã  
+
+Collage.maxDisplay:äžæ¬¡ææŸç€ºçåŸåçæå€§æ°éã  
+
+Collage.imageType:éè¿æå®æä»¶æ©å±åæ¥æ§å¶åªäºæä»¶äŒçšäºåŸåæ»æ±äž­ãæä»¶æ©å±åéçš(%%)è»å·åºåã  
+
+Collage.bgcolor:æŒèŽŽç»åžçèæ¯è²ïŒåå
+­è¿å¶ïŒäŸåŠïŒ008000æ£®æç»¿èæ¯ïŒã  
+
+Collage.buttonname:åç±»åšå±å¹æ ç­Ÿåå¯Œèªæ¡äžçæé®  
+
+Collage.refreshDelay:æŒèŽŽç»åžçæŽæ°çïŒä»¥åŸ®ç§è®¡ã  
+
+Collage.isJava2:çšäºæ§å¶åªäºJavaè¿è¡ç±»è¢«äœ¿çšãæŽé«çæ¬çJavaïŒåŠJava 1.2ä»¥äž)äžºæ§å¶åŸåçéæåºŠæäŸæŽå¥œçæ¯æïŒæ¬æ ç­Ÿçšäºæ§å¶è¿äžè®Ÿçœ®ïŒå³äœ¿äžäºæµè§åšçJavaè¿è¡çæ¬æ¯1.1ãè¯¥Javaå°çšåºåšçŒºçæ
+åµäžå°èªåšäŸŠæµæµè§åšçJavaçæ¬å¹¶éåçžåºæªæœã  
+
+Collage.imageMustNotHave:çšäºéèäžè¯¥åºç°çåŸåïŒåŠå¯Œèªæ¡äžçåŸåæé®ã  
+
+Collage.caption:æŸç€ºåšæŒèŽŽç»åžäžçéé¡¹æå­  
+
+
+#
+# Plugin option descriptions
+#
+AcronymExtractor.adding:æ·»å   
+
+AcronymExtractor.already_seen:å·²è§å°  
+
+AcronymExtractor.desc:æœåå°ç¹äžææ¬äž­çŒ©åè¯è¡šç€ºçæä»¶  
+
+AcronymExtractor.done_acronym_extract:å®ææåçŒ©åè¯  
+
+AcronymExtractor.done_acronym_markup:å®æçŒ©åè¯æ è®°  
+
+AcronymExtractor.extract_acronyms:ä»ææ¬äž­æåçŒ©åè¯å¹¶è®Ÿäžºmetadata  
+
+AcronymExtractor.extracting_acronyms:æåçŒ©åè¯  
+
+AcronymExtractor.marking_up_acronyms:æ è¯çŒ©åè¯  
+
+AcronymExtractor.markup_acronyms:åšææ¡£ææ¬äž­æ·»å çŒ©åè¯ã  
+
+ArchivesInfPlugin.desc:æ¬æä»¶å€çå¯Œå
+¥è¿çšçæçå­æ¡£æä»¶æ°æ®åºïŒarchives-doc.gdbïŒãå®å°è¯¥æ°æ®åºäž­çæ¯äžªå­æ¡£ïŒarchiveïŒæä»¶éè¿ç®¡éæºå¶éäº€ç»GreenstoneXMLPluginå€çã  
+
+AutoExtractMetadata.desc:å°æœåæä»¶äž­æææœååèœèéå°äžèµ·çåºæ¬æä»¶  
+
+AutoExtractMetadata.extracting:æå  
+
+AutoExtractMetadata.first:ä»¥éå·éŽéçäžç»æ°å­ïŒæå®ä»ææ¬èµ·å§æåçå­ç¬ŠéïŒææååºçå
+å®¹ä¿å­å°äžç»åäžº'FirstN'çå
+æ°æ®å­æ®µäž­ïŒå
+¶äž­çNä»£è¡šæœåçå­ç¬Šæ°ãæ¯åŠïŒåŒâ3,5,7âå°æœåèµ·å§ç3ïŒ5å7äžªå­ç¬Šå¹¶åå«ä¿å­å°åäžºâFirst3âïŒâFirst5âåâFirst7âçå
+æ°æ®å­æ®µäž­ã  
+
+BaseMediaConverter.desc:æäŸåªäœèœ¬æ¢æä»¶æ¯åŠImageConverteråè§é¢èœ¬æ¢çåºæ¬åèœçæä»¶ã  
+
+BasePlugin.associate_ext:äœ¿æçåæ ·æ ¹æä»¶åçæä»¶  
+
+BasePlugin.associate_tail_re:å¹é
+æä»¶åçæ­£åè¡šèŸŸåŒïŒç­ééå±çæä»¶ãè¿äžªéé¡¹æ¿æ¢associate_extïŒäžæŽææã  
+
+BasePlugin.block_exp:äžè¯¥æ­£åè¡šèŸŸåŒå¹é
+çæä»¶äžäŒè¢«äŒ å°æä»¶éäž­ååšåé¢çæä»¶ã  
+
+BasePlugin.desc:éçšææèŸå
+¥æä»¶çåºç±»  
+
+BasePlugin.dummy_text:è¯¥ææ¡£æ å
+å®¹  
+
+BasePlugin.encoding.ascii:ç®æ7æ¯ç¹ASCIIãè¿ä¹è®žèŠæ¯çšiso_8895_1å¿«äºãåœææ¬å¯èœå«æç®æ7æ¯ç¹ASCIIå­ç¬Šéä¹å€çå­ç¬Šæ¶ïŒæ¯åŠæéé³ç¬Šå·çåŸ·æææ³æïŒïŒäœ¿çšiso_8859_1ã  
+
+BasePlugin.encoding.unicode:åªæ¯ç»äžçå­ç¬ŠçŒç æ å  
+
+BasePlugin.encoding.utf8:utf8åç»äžçå­ç¬ŠçŒç æ åäºè
+ä¹äž ïŒèªåšèŸšè¯ã  
+
+BasePlugin.filename_encoding:æºæä»¶åç§°ççŒç ã  
+
+BasePlugin.filename_encoding.auto:èªåšæ£æµæä»¶åççŒç ã  
+
+BasePlugin.filename_encoding.auto_language_analysis:åæå¹¶èªåšæ£æµæä»¶åçŒç ã  
+
+BasePlugin.filename_encoding.auto_filesystem_encoding:çšæä»¶ç³»ç»çŒç èªåšæ£æµæä»¶åçŒç ã  
+
+BasePlugin.filename_encoding.auto_fl:äœ¿çšæä»¶ç³»ç»çŒç ä»¥åè¯­ç§åææ¥æ£æµæä»¶åçŒç ã  
+
+BasePlugin.filename_encoding.auto_lf:äœ¿çšè¯­ç§åæä»¥åæä»¶ç³»ç»çŒç æ¥æ£æµæä»¶åçŒç ã  
+
+BasePlugin.no_blocking:äžè¿è¡ä»»äœæä»¶å±èœãä»»äœéåžŠçæä»¶ïŒæ¯åŠçœé¡µäž­çåŸçïŒå°è¢«ç¬ç«åŸæ·»å å°åœåæ¶èã  
+
+BasePlugin.no_cover_image:äžæ¥æŸprefix.jpgæä»¶ïŒprefixæåœåå€çäž­çæä»¶çåçŒïŒæ¥äœäžºå°é¢åŸåã  
+
+BasePlugin.OIDtype.auto:äœ¿çšimport.pläž­è®Ÿçœ®çOIDtype  
+
+BasePlugin.process_exp:äžäžªäžæä»¶åçžå¹é
+çperlè§åè¡šè¿°ãæä»¶åçå¹é
+å°ç±è¯¥æä»¶å€çãäŸåŠïŒçš'(?i).html?\$' å¹é
+ä»¥.htm or .htmlç»å°Ÿçææææ¡£(åºåå€§å°å)ã  
+
+BasePlugin.smart_block:äœ¿çšæ¯ä»
+ä»
+èèæä»¶åæŽå¥œçåæ³é»æ­¢æä»¶ã  
+
+BasePlugin.stems:è¯å¹²  
+
+BasePlugin.file_rename_method:éåœåå·²å¯Œå
+¥æä»¶åéå±æä»¶åç§°çæ¹æ³ã  
+
+BasePlugin.rename_method.url:äœ¿çšurlçŒç å¯¹å·²å¯Œå
+¥åéåžŠæä»¶éåœåã  
+
+BasePlugin.rename_method.base64:äœ¿çšbase64çŒç å¯¹å·²å¯Œå
+¥åéåžŠæä»¶éåœåã  
+
+BasePlugin.rename_method.none:äžå¯¹å·²å¯Œå
+¥åéåžŠæä»¶è¿è¡éåœåã  
+
+BibTexPlugin.desc:BibTexPluginè¯»å
+¥BibTexæ ŒåŒçä¹Šç®æèŠãBibTexPluginäžºæä»¶äž­çæ¯æ¡ä¹Šç®åå»ºäžäžªææ¡£å¯¹è±¡ãå®æ¯SplitTextFileçå­ç±»ïŒæä»¥åŠæå­åšå€æ¡è®°åœïŒåå
+šéšè¯»åã  
+
+BookPlugin.desc:ä»å«æ<<TOC>>å±çº§æ è®°çææ¡£äž­åå»ºå€çº§ææ¡£ãæ¯äžªæ®µèœçå
+æ°æ®åèªä»»äœäž<<TOC>>åšåäžè¡çå
+¶ä»æ è®°ãäŸåŠ<<Title>>xxxx<</Title>>å°è®Ÿå®é¢åå
+æ°æ®ã<<TOC>>æ è®°ç¬Šä¹éŽçææå
+¶ä»å
+å®¹è§äžºç®åhtmlïŒå³äžå€çhtmléŸæ¥æå
+¶ä»HTMLPluginç±»çå€çïŒã ææçèŸå
+¥æä»¶ççŒºçæä»¶æ©å±åäžº.hbïŒè¯¥éé¡¹å¯éè¿å å
+¥-process_expéé¡¹è¿è¡æŽæ¹ïŒãäžhbæä»¶ååç.jpgæä»¶å°è¢«äœäžºææ¡£çå°é¢åŸåïŒæ¬æä»¶å±èœjpgæä»¶ïŒãBookPluginæ¯Humanity LibraryéŠèçšå°çHBPluginçç®åïŒåæ©å±ïŒãBookPluginçå€çæ¯èŸå¿«å äžºå®ææææ¯èŸå¹²åçèŸå
+¥æä»¶ ïŒHDLéŠèçèŸå
+¥éšåå«æè®žå€åŽç»<<TOC>>æ ç­Ÿçhtmlæ ç­ŸïŒäœ¿çš<<I>>æ ç­Ÿæ¥æå®åŸå, äžçš<<TOC>>æ ç­Ÿäžææ¬èµ·å§å€ä¹éŽçå
+å®¹äœäžºæ é¢å
+æ°æ®ïŒãåŠæèŠä»€ææ¡£æŸç€ºæäžHDLéŠèäžæ ·çåœ¢åŒïŒåºäœ¿çšæ¬æä»¶èäžæ¯HBPluginã  
+
+CONTENTdmPlugin.desc:æ¬æä»¶å€çå¯ŒåºCONTENTdméŠèäž­çRDFæä»¶ã  
+
+ConvertBinaryFile.apply_fribidi:åšèœ¬æ¢çæä»¶äžè¿è¡âfribidiâç»äžçŒç ååç®æ³ïŒéçšäºå³è³å·Šææ¬ïŒã  
+
+ConvertBinaryFile.convert_to:èœ¬æ¢æTEXTæHTMLæå
+¶ä»ç§ç±»åŸåçæä»¶ïŒåŠJPEG,GIF,PNG)ã  
+
+ConvertBinaryFile.convert_to.auto:èªåšéæ©èŠèœ¬æ¢çæ ŒåŒãæéæ ŒåŒåå³äºèŸå
+¥ææ¡£çç±»åïŒæ¯åŠWordææ¡£äŒèœ¬æ¢æHTMLæ ŒåŒïŒèPowerPointææ¡£å°èœ¬æ¢æGreenstoneçPagedImageïŒåé¡µåŸçïŒæ ŒåŒã  
+
+ConvertBinaryFile.convert_to.html:HTMLæ ŒåŒã  
+
+ConvertBinaryFile.convert_to.text:ç®æææ¬æ ŒåŒã  
+
+ConvertBinaryFile.convert_to.pagedimg:äžç³»åçåŸçã  
+
+ConvertBinaryFile.convert_to.pagedimg_jpg:JPEGæ ŒåŒã  
+
+ConvertBinaryFile.convert_to.pagedimg_gif:GIFæ ŒåŒã  
+
+ConvertBinaryFile.convert_to.pagedimg_png:PNGæ ŒåŒã  
+
+ConvertBinaryFile.desc:è¯¥æä»¶ç±WordPluginãPowerPointPluginãPostScriptPluginãRTFPluginåPDFPluginç»§æ¿ãçšäºæè¿äºææ¡£ç±»åèœ¬æ¢æHTMLãTEXTæåŸåç³»åãå
+¶å·¥äœåçæ¯æ ¹æ®è¯¥æä»¶çâconvert_toâéé¡¹åšæè¯»åçžåºçäºçº§æä»¶ïŒHTMLPluginãStructuredHTMLPluginãPagedImagePluginæTextPluginïŒã  
+
+ConvertBinaryFile.keep_original_filename:ä¿çå
+³èæä»¶çåå§æä»¶åïŒèäžæ¯èœ¬æ¢ædoc.pdfïŒdoc.docç­ã  
+
+ConvertBinaryFile.use_strings:åŠæè®Ÿå®çè¯ïŒåœèœ¬æ¢æ æ³è¿è¡æ¶äžäžªç®åçå­ç¬Šäž²åœæ°äŒè¢«çšæ¥æåææ¬ã  
+
+ConvertToRogPlugin.desc:ç±RogPluginç»§æ¿æ¥çæä»¶ã  
+
+CSVPlugin.desc:çšäºéå·åéæ ŒåŒçåŒçæä»¶ãäŒäžºæä»¶çæ¯äžè¡åå»ºäžäžªæ°ææ¡£ã  
+
+DateExtractor.desc:èŸ
+å©æœåæä»¶ïŒçšæ¥æœåææ¬äž­çåå²æ¥æä¿¡æ¯ã  
+
+DateExtractor.extract_historical_years:ä»åå²ææ¡£äž­æåæå
+³æ¶éŽåºéŽçä¿¡æ¯ãè¯¥ä¿¡æ¯æ¯äœäžºææ¡£çmetadataå­åšçãæäžäžªçé¢å¯çšäºæçŽ¢è¯¥metadataãåšæ¶èé
+çœ®æä»¶äž­åå
+¥"format QueryInterface DateSearch"è¯­å¥å³å¯å°è¯¥çé¢å å
+¥çžå
+³æ¶èã  
+
+DateExtractor.maximum_century:æåæå€§çç»è¿åœåçäžçºªäœäžºåå²metadataïŒäŸåŠ14ïŒå³æåæªè³14äžçºªææçåèèµæïŒ  
+
+DateExtractor.maximum_year:çšäºmetadataçæå€§çåå²äžçæ¥æïŒä»¥åºç£æ¶ä»£äžºåïŒåŠ1950ïŒ  
+
+DateExtractor.no_bibliography:åœæååå²æ¥ææ¶ïŒäžèŠè¯åŸé»æ­¢ä¹Šç®æèŠæ¥æã  
+
+DirectoryPlugin.desc:RecPlugæä»¶å¯å€çå®åšåµå¥ç®åœäž­åç°çæ¯äžäžªæä»¶ã  
+
+DirectoryPlugin.recheck_directories:åœäžäžªèŸå
+¥ç®åœäž­çæææä»¶å€çå®æ¯åïŒéæ°è¯»åç®åœä»¥åç°ä»»äœæ°åå»ºçæä»¶ã  
+
+DirectoryPlugin.use_metadata_files:äžèµæäœ¿çšïŒè¯·æ·»å MetadataXMLPluginä»¥äŸ¿ä»å
+æ°æ®XMLæä»¶äž­è¯»åå
+æ°æ®ã  
+
+DatabasePlugin.desc:æ¬æä»¶ä»æ°æ®åºäž­å¯Œå
+¥è®°åœãæ¬æä»¶äœ¿çšperlçDBIæš¡åïŒå®å«æmysqlãpostgresqlãéå·åéåŒïŒCSVïŒãMS ExcelãODBCãsybaseç­ç­çåç«¯ãäœ¿çšæ¬æä»¶éèŠå®è£
+é¢å€çæš¡åãåè§<GSDLHOME>/etc/packages/example.dbiäž­çç€ºèé
+çœ®æä»¶ã  
+
+DSpacePlugin.desc:DSpacePlug æ¥åä»Dspaceäž­èŸåºçæ¶èå¹¶èŸå
+¥ç»Greenstoneã  
+	
+DSpacePlugin.first_inorder_ext:æ¬éé¡¹çšäºè¯å«äžäžªDspaceéŠèææ¡£çäž»ææ¡£ãè¥è®Ÿå®æ¬éé¡¹ïŒç³»ç»å°æé¡ºåºäœ¿çšæ¬éé¡¹äž­å®ä¹çæä»¶æ©å±ç±»åæ¥å¯»æŸäž»ææ¡£æä»¶ã  
+
+DSpacePlugin.first_inorder_mime:æ¬éé¡¹çšäºè¯å«äžäžªDspaceéŠèææ¡£çäž»ææ¡£ãè¥è®Ÿå®æ¬éé¡¹ïŒç³»ç»å°æé¡ºåºäœ¿çšæ¬éé¡¹äž­å®ä¹çmimeç±»åæ¥å¯»æŸäž»ææ¡£æä»¶ã  
+
+DSpacePlugin.only_first_doc:æ¬éé¡¹çšäºè¯å«äžäžªDspaceéŠèææ¡£çäž»ææ¡£ãè¥è®Ÿå®æ¬éé¡¹ïŒéœæææ žå¿å
+æ°æ®æä»¶äž­åŒçšçç¬¬äžäžªææ¡£å°è¢«äœäžºäž»ææ¡£æä»¶ã  
+
+EmailAddressExtractor.desc:èŸ
+å©æœåæä»¶ïŒçšæ¥æœåææ¬äž­çemailå°åã  
+
+EmailAddressExtractor.done_email_extract:å®ææåçµå­é®ä»¶å°å  
+
+EmailAddressExtractor.extracting_emails:æåçµå­é®ä»¶å°å  
+
+EmailAddressExtractor.extract_email:æåçµå­é®ä»¶å°åå¹¶äœäžºmetadata  
+
+EmailPlugin.desc:EmailPlugè¯»åçµå­é®ä»¶æä»¶ãè¿äºæä»¶äŒçšç®åæ°å­åœåïŒå³ïŒå®ä»¬åºç°åšmaildiræä»¶å€¹äž­ïŒæå
+·æ.mbxæä»¶æ©å±å (å¯¹äºmboxé®ä»¶æä»¶æ ŒåŒ)ãææ¡£ææ¬: ææ¡£äž­ç¬¬äžäžªç©ºçœè¡åé¢çææææ¬ãMetadata (éDublin Core!):$Headers ææçé¡µéŠå
+å®¹ïŒå¯éæ©çïŒåå®æ¡ä»¶äžäžå­åšïŒ:$Subject Subject: é¡µéŠ$To To: é¡µéŠ$From From: é¡µéŠ$FromName åéäººå§å (åŠææçè¯)$FromAddr åéäººçµé®å°å$DateText     Date: é¡µéŠ$Date æ¥æ: GSDLæ ŒåŒçé¡µéŠ (äŸåŠ: 19990924)  
+
+EmailPlugin.no_attachments:äžèŠå­åšä¿¡æ¯éä»¶ã  
+
+EmailPlugin.headers:å°çµå­é®ä»¶é¡µéŠå­åšäžºâHeadersâmetadataã  
+
+EmailPlugin.OIDtype.message_id:å°æ¶æ¯æ è¯çšäœææ¡£OIDãåŠææ²¡ææ¶æ¯æ è¯ïŒåçšååžOIDã  
+
+EmailPlugin.split_exp:çšäºå°å«æå€é¡¹ä¿¡æ¯çæä»¶åå²æç¬ç«ææ¡£çperlè§åè¡šè¿°ã  
+
+ExcelPlugin.desc:çšäºèŸå
+¥Microsoft Excelæä»¶çæä»¶ïŒ95å97çïŒã  
+
+FavouritesPlugin.desc:æ¬æä»¶å€çè±ç¹çœæµè§åšçæ¶èæä»¶ã  
+
+FOXPlugin.desc:æ¬æä»¶å€çFoxbase dbtæä»¶ãæ¬æä»¶åªæäŸè¯»ådbtådbfæä»¶åå€çè®°åœçåºæ¬åèœãå¯¹å€çå
+·äœæ°æ®åºäž­çå­æ®µïŒåéèŠåšè¿äžªéçšæä»¶çåºç¡äžè¿è¡å®å¶ã  
+
+GreenstoneXMLPlugin.desc:å€çGreenstone Archive XMLææ¡£ãæ³šæè¯¥æä»¶äžäœè¯­æ³æ£æ¥ïŒå°œç®¡XML:Parseræš¡åæµè¯æ ŒåŒçå®å¥œæ§ïŒãè¿éåå®Greenstone Archiveæä»¶ç¬Šåå
+¶DTDã  
+
+GISExtractor.desc:å
+·GISåèœçBasPlugçèŸ
+å©åºç±»  
+
+GISExtractor.extract_placenames:ä»ææ¬äž­æåå°ç¹åç§°å¹¶è®ŸäžºmetadataãèŠæ±æGreenstoneçGISæ©å±ã  
+
+GISExtractor.gazetteer:äœ¿çšGazetteerä»ææ¬äž­æåå°ç¹åç§°å¹¶è®ŸäžºmetadataãèŠæ±æGreenstoneçGISæ©å±ã  
+
+GISExtractor.place_list:åœæåå°ç¹æ¶ïŒå°å°ç¹åç§°éå
+æ¬åšææ¡£çèµ·å§å€ãèŠæ±æGreenstoneçGISæ©å±ã  
+
+HBPlugin.desc:æ¬æä»¶çšäºå€çHTMLä¹Šç®åœãæ¬æä»¶äž»èŠçšäºHumanity Development LibraryéŠèäžåªå€çASCIIåæ©å±ASCIIçŒç ãæ¬æä»¶çè¿è¡éåºŠæåŸå€§çæåç©ºéŽïŒæä»¬æŽåžæéŒå±çšæ·äœ¿çšBookPluginæ¥åå»ºä»ä»¬èªå·±çæ¶èã\n\nå°œéäœ¿çšBookPluginæ¥çææ°çæ¶èä»¥åå€çç±»äŒŒHumanity LibraryéŠèæä»¶çææ æ³šçæä»¶ãBookPluginæ¥åææèŸå
+¥çŒç äœèŠæ±æä»¶äž­çæ æ³šæ¯Humanity LibraryéŠèäž­çæŽæŽã  
+
+HBPlugin.encoding.iso_8859_1:æäž1ïŒè¥¿æ¹è¯­èšïŒ  
+
+HTMLImagePlugin.aggressiveness:å¯çšçææ¬æåèåŽã  
+HTMLImagePlugin.aggressiveness.1:ä»
+æä»¶åãè·¯åŸãæ¿æ¢ææ¬ïŒHTML img æ ç­ŸçALTå±æ§ïŒã  
+HTMLImagePlugin.aggressiveness.2:1äž­çå
+šéšïŒå äžå¯æœåçæ é¢ã  
+HTMLImagePlugin.aggressiveness.3:2äž­çå
+šéšïŒå äžå¯æœåçéè¿æ®µèœã  
+HTMLImagePlugin.aggressiveness.4:3äž­çå
+šéšïŒå äžå¯æœåçä»¥åçé¡µéŠïŒ<h1>,<h2>âŠ)ã  
+HTMLImagePlugin.aggressiveness.5:4äž­çå
+šéšïŒå äžå¯æœåçææ¬åèã  
+HTMLImagePlugin.aggressiveness.6:4äž­çå
+šéšïŒå äžHTMLé¡µé¢äž­çmetaæ ç­ŸïŒæ é¢ïŒå
+³é®è¯ç­ïŒã  
+HTMLImagePlugin.aggressiveness.7:4ïŒ5å6çç»åã  
+HTMLImagePlugin.aggressiveness.8:7äž­çå
+šéšïŒä»¥åéå€æä»¶åãè·¯åŸãæ¿æ¢ææ¬åæ é¢ïŒæ¥æåå
+¶åšçžå
+³ç»æäž­çæåºïŒã  
+HTMLImagePlugin.aggressiveness.9:1äž­çå
+šéšïŒå äžæºé¡µé¢çå
+šéšææ¬ã  
+
+HTMLImagePlugin.caption_length:æ é¢è¯Žæçæå€§é¿åºŠïŒä»¥å­æ¯è®¡ïŒã  
+
+HTMLImagePlugin.convert_params:çšäºImageMagicKç¥åŸåå»ºèœ¬æ¢çé¢å€åæ°ãäŸåŠïŒ'-raise'å°åšçŒ©ç¥åŸäžæ·»å äžç»Žææã  
+
+HTMLImagePlugin.desc:æ¬æä»¶çšäºä»çœé¡µæååŸååå
+³èææ¬ã  
+
+HTMLImagePlugin.document_text:æ·»å åŸåææ¬äœäžºdocument:textïŒåŠåäœäžºIndexedTextå
+æ°æ®å­æ®µïŒã  
+
+HTMLImagePlugin.index_pages:å°é¡µé¢äžåŸåäžèµ·çŒå
+¥çŽ¢åŒãåŠååšæºææ¡£çURLäž­åŒçšè¯¥é¡µé¢ã  
+
+HTMLImagePlugin.max_near_text:ä»åŸåéè¿æåçå­æ¯çæå€§æ°ç®ã  
+
+HTMLImagePlugin.min_height:ä»¥è±¡çŽ äžºåäœãç¥è¿å°äºè¯¥éé¡¹çåŸåã  
+
+HTMLImagePlugin.min_near_text:åšææ¬ææ é¢è¯Žæéè¿å
+è®žæåçæå°å­æ¯ã  
+
+HTMLImagePlugin.min_size:ä»¥å­èäžºåäœãç¥è¿å€§å°å°äºè¯¥éé¡¹çåŸåã  
+
+HTMLImagePlugin.min_width:ä»¥è±¡çŽ äžºåäœãç¥è¿çªäºè¯¥éé¡¹çåŸåã  
+
+HTMLImagePlugin.neartext_length:éè¿ææ¬çç®æ é¿åºŠïŒä»¥å­æ¯è®¡ïŒã  
+
+HTMLImagePlugin.no_cache_images:äžèŠçŒå­åŸåïŒæååå§åŸåçURLïŒã  
+
+HTMLImagePlugin.smallpage_threshold:é¡µé¢äžå°äºæå®å­èçåŸåäŒè¢«å å
+¥è¯¥é¡µé¢çå
+æ°æ®ïŒæ é¢ïŒå
+³é®è¯ç­ïŒã  
+
+HTMLImagePlugin.textrefs_threshold:ææ¬åŒçšççéåŒãèŸäœçåŒæå³çäžåŸäž¥æ Œçç®æ³ã  
+
+HTMLImagePlugin.thumb_size:æå€§çç¥åŸå°ºå¯žïŒå®œåé¿ã  
+
+HTMLPlugin.assoc_files:äžhtmlææ¡£çžå
+³èçæä»¶æ©å±åçperlè§åè¡šè¿°ã  
+
+HTMLPlugin.desc:è¯¥æä»¶å€çHTMLæä»¶ã  
+
+HTMLPlugin.description_tags:åš<Section>æ ç­Ÿåºç°çå°æ¹åå²ææ¡£ãåšè¯¥éé¡¹è®Ÿå®çæ
+åµäžïŒ'-keep_head'äžèµ·äœçšã  
+
+HTMLPlugin.extract_style:ä»HTML<head>æ ç­Ÿæåæ ŒåŒåèæ¬ä¿¡æ¯å¹¶å­åšæDocumentHeader metadataãè¿äŒåšææ¡£é¡µé¢äž­ä»¥_document:documentheader_ macroçåœ¢åŒè®Ÿå®ã  
+
+HTMLPlugin.file_is_url:åŠæèŸå
+¥æä»¶åæææºææ¡£çurlçäžéšååè®Ÿå®è¯¥åïŒäŸåŠåœäžäžªçœé¡µéåå·¥å
+·è¢«çšäºçæèŸå
+¥ç®åœç»ææ¶ã  
+
+HTMLPlugin.hunt_creator_metadata:å°œå¯èœåç°æŽå€çæå
+³äœè
+èº«ä»œçmetadataå¹¶å­æŸåš'Creator'åäž­ã  
+
+HTMLPlugin.keep_head:äžèŠä»htmlæä»¶äž­å»é€é¡µéŠã  
+
+HTMLPlugin.metadata_fields:è¯åŸæåçéå·åéçmetadataåçéãçš'tag<tagname>'åŸå°å­æŸåšåäžº'tagname'çmetadataå
+çŽ çç¬¬äžäžª<tagname>æ ç­Ÿç»çå
+å®¹ãå äžºæ ç­Ÿæåäžèèå€§å°åïŒé¡»å°è¯¥åè±¡å€§åGreenstoneäž­çmetadataäžæ ·å€§åæææã  
+
+HTMLPlugin.no_metadata:äžèŠè¯åŸä»æä»¶äž­æåä»»äœmetadataã  
+
+HTMLPlugin.no_strip_metadata_html:éå·åéçmetadataåç§°çéïŒæ'all'ãäž-description_tagsäžèµ·äœ¿çšïŒå®äŒé²æ­¢ä»è®Ÿå®çmetadataçåŒäž­å¥çŠ»HTMLæ ç­Ÿã  
+
+HTMLPlugin.nolinks:äžèŠè¯åŸéå¶éŸæ¥ïŒè®Ÿå®è¯¥æ è®°å¯æé«åå»º/èŸå
+¥çéåºŠäœäŒäœ¿ææ¡£äž­ççžå¯¹éŸæ¥å€±å»äœçšã  
+
+HTMLPlugin.no_image_links:äžå€çåŸçéŸæ¥ååŸçé¢è§  
+
+HTMLPlugin.rename_assoc_files:éåœåäžææ¡£çžå
+³èçæä»¶ïŒåŠåŸåïŒãåæ ·çææŽæµ
+çç®åœç»æïŒåœåå»ºcd-romæ¶èæ¶èŸæçšïŒã  
+
+HTMLPlugin.sectionalise_using_h_tags:çšh1,h2,âŠ,hXæ ç­Ÿèªåšçææ®µèœææ¡£ã  
+
+HTMLPlugin.title_sub:çšäºä¿®æ¹å­åšäžºæ é¢çå­ç¬Šäž²çæ¿æ¢è¡šèŸŸåŒãæ¯åŠPDFPluginçšå®ä»æ é¢ææ¬äž­æž
+é€âPage 1âç­ã  
+
+HTMLPlugin.tidy_html:è®Ÿå®åäŒå°HTMLææ¡£èœ¬æ¢äžºå¯¹ç§°çXHTMLãçšæ·ä»èå¯çšä¹Šæ¬æ ŒåŒæ¥çææ¡£ã  
+
+HTMLPlugin.old_style_HDL:æ æ³šæ¯åŠè¯¥æ¶èäž­çæä»¶çšæ§çHDLæ®µèœæ ŒåŒæ®µèœåã  
+
+BaseMediaConverter.enable_cache:èªåšçŒå­çæçæä»¶ïŒæ¯åŠçŒ©ç¥åŸåå±å¹å€§å°çåŸçïŒä»¥äŸ¿äžéèŠéå€çæè¿äºæä»¶ã  
+
+ImageConverter.converttotype:èœ¬æ¢äž»åŸåè³æ ŒåŒ's'ã  
+
+ImageConverter.create_screenview:è¥è®Ÿçœ®äžºçïŒååå»ºäžäžªå±å¹å€§å°çåŸçïŒå¹¶è®Ÿçœ®Screen, ScreenType, screenicon, ScreenWidth, ScreenHeightå
+æ°æ®ã  
+
+ImageConverter.create_thumbnail:è¥è®Ÿçœ®äžºçïŒåäžºæ¯äžªåŸçåå»ºäžäžªçŒ©ç¥åŸïŒå¹¶è®Ÿçœ®Thumb, ThumbType, thumbicon, ThumbWidth, ThumbHeightå
+æ°æ®ã  
+ImageConverter.desc:è¯¥æä»¶å€çåŸåïŒæ·»å åºæ¬çmetadataã  
+
+ImageConverter.imagemagicknotinstalled:Image Magickæ²¡æå®è£
+  
+
+ImageConverter.minimumsize:å¿œç¥å°äºnæ¯ç¹çåŸåã  
+
+ImageConverter.noconversionavailable:åŸçèœ¬æ¢åèœäžå¯çš  
+
+ImageConverter.noscaleup:çæç¥åŸæ¶äžèŠæŸå€§å°åŸåã  
+
+ImageConverter.screenviewsize:çæå€§å°äžºnxnçå±å¹åŸåã  
+
+ImageConverter.screenviewtype:çææ ŒåŒäžº's'çå±å¹åŸåã  
+
+ImageConverter.thumbnailsize:çæå€§å°äžºnxnçç¥åŸã  
+
+ImageConverter.thumbnailtype:çææ ŒåŒäžº's'çç¥åŸã  
+
+ImageConverter.win95notsupported:Win95/98äžæ¯æImage Magick  
+
+ImagePlugin.desc:è¯¥æä»¶å€çåŸåïŒæ·»å åºæ¬çmetadataã  
+
+IndexPlugin.desc:è¯¥åµå¥æä»¶å€çäžäžªindex.txtæä»¶ãè¯¥index.txtæä»¶åºå«æå°è¢«å
+æ¬åšæ¶èäž­çæä»¶éïŒçŽ§æ¥è¯¥éçæ¯äžæ¯äžªæä»¶çžå
+³èçé¢å€çmetadataãè¯¥index.txtæä»¶é¡»äžºä»¥äžæ ŒåŒïŒç¬¬äžè¡åºæ¯äžäžªå
+³é®è¯(ä»¥key:åŒå§ïŒïŒçšäºåœåmetadataåïŒäŸåŠïŒkey: Subject Organization Date)ãæ¥äžæ¥æ¯æä»¶åä»¥åäžºmetadataæ¡ç®æè®ŸçåŒïŒäŸåŠïŒåœäœ¿çšäžäŸçå
+³é®è¯è¡æ¶ïŒ'irma/iw097e 3.2 unesco 1993'å°æmetadata Subject=3.2, Organization=unesco, å Date=1993äžæä»¶irma/iw097eçžå
+³è)ãæ³šæåŠæä»»äœmetadataåäœ¿çšäºHierarchyåç±»åšæä»¶ïŒåæè®ŸåŒåºäžçžåºåç±»æä»¶äž­çç¬¬äžäžªåïŒæè¿°è
+ïŒçžå¯¹åºãMetadataçåŒå¯çšæ ç­Ÿåå«åœåïŒäŸåŠ <Subject>3.2)ïŒè¿å°èŠçææç±å
+³é®è¯è¡èµäºå®ä»¬çåå­ãåŠæå
+³é®è¯è¡äžå­åšïŒæææªåœåçmetadataåŒå°è¢«åœåæªâSubject'ã  
+
+ISISPlugin.desc:è¯¥æä»¶å€çCDS/ISISæ°æ®åºãå¯¹äºæ¯äžªè¢«å€ççCDS/ISISæ°æ®åºïŒæ¶èçèŸå
+¥æä»¶å€¹äž­å¿
+é¡»å«æä»¥äžäžäžªæä»¶ïŒäž»æä»¶ïŒ.mst),åå®ä¹è¡š (.fdt), ä»¥ååç
+§æä»¶ (.xrf)ã  
+
+ISISPlugin.subfield_separator:CDS/ISISæ°æ®åºè®°åœäž­çšäºåéå­åçå€äžªåŒçå­ç¬Šäž²ã  
+
+ISISPlugin.entry_separator:CDS/ISISæ°æ®åºè®°åœäž­çšäºåéåäžªmetadataåçå€äžªåŒçå­ç¬Šäž²ã  
+
+KeyphraseExtractor.desc:èŸ
+å©æœåæä»¶ïŒçšäºä»ææ¬äž­æœåå
+³é®è¯ç»ãäœ¿çšKeaå
+³é®è¯ç»æœåç³»ç»ã  
+
+KeyphraseExtractor.extract_keyphrases:äœ¿çšKeaèªåšæåå
+³é®è¯è¯­ïŒåå®è®Ÿçœ®ïŒ  
+
+KeyphraseExtractor.extract_keyphrases_kea4:äœ¿çšKea 4.0èªåšæåå
+³é®è¯è¯­ïŒåå®è®Ÿçœ®ïŒãKea 4.0æ¯Keaçæ°çæ¬ïŒçšäºæ§å¶çŒå¶åäžé¢åçææ¡£ã  
+
+KeyphraseExtractor.extract_keyphrase_options:çšäºå
+³é®è¯è¯­æåçKeaéé¡¹ãäŸåŠïŒmALIWEB - äœ¿çš ALIWEB æåæš¡åŒ; n5 - æå5äžªå
+³é®è¯è¯­;, eGBK - äœ¿çš GBK çŒç ã  
+
+KeyphraseExtractor.keyphrases:å
+³é®è¯è¯­  
+
+KeyphraseExtractor.missing_kea:éè¯¯ïŒïŒ
+säž­æ æ³æŸå°Keaèœ¯ä»¶ãè¯·ä»http://www.nzdl.org/KeaäžèœœKeaïŒ
+så¹¶å®è£
+å°è¯¥ç®åœäžã  
+
+LaTeXPlugin.desc:çšäºLaTexææ¡£çæä»¶ã  
+
+LOMPlugin.desc:çšäºèŸå
+¥LOMïŒLearning Object Metadata)çæä»¶ã  
+
+LOMPlugin.root_tag:XMLæä»¶çDocType(æäžäžªäžæ ¹å
+çŽ å¹é
+çè§åè¡šè¿°ïŒã  
+
+LOMPlugin.check_timestamp:æ¥çä»¥åäžèœœçæä»¶çæ¶éŽæ è®°ïŒäžä»
+åšæºæä»¶èŸæ°æ¶æéæ°äžèœœã  
+
+LOMPlugin.download_srcdocs:åŠæè®Ÿå®çè¯åäžèœœæºææ¡£ïŒéåžžæ å¿ç¬Šæ¡ç®æææ¯äœçœ®ïŒãè¯¥éé¡¹åºæå®äžäžªè§åè¡šè¿°æ¥å¹é
+æèŠäžèœœçæä»¶åãæ³šæïŒè¯¥åç®ååªå¯¹é²ç«å¢å€èŸ¹çææ¡£ææã  
+
+MARCPlugin.desc:åºæ¬çMARCæä»¶ã  
+
+MARCPlugin.metadata_mapping:æä»¶åïŒè¯¥æä»¶äž­æä»MARCåŒå°Greenstoneå
+æ°æ®åçæ å°ãçŒºçåŒæ¯åœåç«ç¹etcç®åœäžç'marc2dc.txt'æä»¶ã  
+
+MARCXMLPlugin.desc:MARCXMLæä»¶ã  
+
+MARCXMLPlugin.metadata_mapping_file:æä»¶åïŒè¯¥æä»¶äž­æä»MARCåŒå°Greenstoneå
+æ°æ®åçæ å°ãçŒºçåŒæ¯åœåç«ç¹etcç®åœäžç'marc2dc.txt'æä»¶ã  
+
+MediaWikiPlugin.desc:çšäºèŸå
+¥MediaWikiçœé¡µçæä»¶ã  
+
+MediaWikiPlugin.show_toc:æ·»å å°æ¶èçAbouté¡µïŒå³MediaWikiçœç«çäž»é¡µç'table of contents'ãé¡»åštoc_expä»¥äžæå®äžäžªPerlè§åè¡šè¿°ä»¥å¹é
+'table of contents'æ®µèœã  
+
+MediaWikiPlugin.delete_toc:å é€æ¯äžªHTMLé¡µç'table of contents'æ®µèœãé¡»åštoc_div_expä»¥äžæå®äžäžªPerlè§åè¡šè¿°ä»¥å¹é
+'table of contents'æ®µèœã  
+
+MediaWikiPlugin.toc_exp:çšäºå¹é
+'table of contents'çPerlè§åè¡šè¿°ãçŒºçåŒå°å¹é
+äžè¬çMediaWikiçœé¡µã  
+
+MediaWikiPlugin.delete_nav:å é€å¯Œèªæ®µèœãé¡»åšnav_div_expä»¥äžæå®äžäžªPerlè§åè¡šè¿°ã  
+
+MediaWikiPlugin.nav_div_exp:çšäºå¹é
+å¯Œèªæ®µèœçPerlè§åè¡šè¿°ãåå®åŒäžéçšMediaWikiçœé¡µçžå¹é
+ã  
+
+MediaWikiPlugin.delete_searchbox:å é€æçŽ¢æ¡æ®µèœãé¡»åšsearchbox_div_expä»¥äžæå®äžäžªPerlè§åè¡šè¿°ã  
+
+MediaWikiPlugin.searchbox_div_exp:çšäºå¹é
+æçŽ¢æ¡æ®µèœçPerlè§åè¡šè¿°ãåå®åŒäžéçšMediaWikiçœé¡µçžå¹é
+ã  
+
+MediaWikiPlugin.remove_title_suffix_exp:çšäºä¿®åªæåçæ é¢çPerlè§åè¡šè¿°ãäŸåŠïŒ\\s-(.+)å°ä¿®åª"-"ä¹åçæ é¢å
+å®¹ã  
+
+MetadataCSVPlugin.desc:çšäºå€çéå·åéçåŒçæ ŒåŒçmetadataçæä»¶ãCSVæä»¶äž­çæä»¶åéšåçšäºå³å®metadataå±äºåªäžªææ¡£ã  
+
+MetadataPass.desc:BasPluginçèŸ
+å©åºç±»ïŒæ¯æå
+æ°æ®æä»¶äœ¿çšimport.plçmetadata_readã  
+
+MetadataXMLPlugin.desc:æ¬æä»¶å€çmetadata.xmlæä»¶ã  
+
+MetadataEXIFPlugin.desc:æ¬æä»¶ä»åŸçãé³é¢åè§é¢äž­æœåEXIFå
+æ°æ®ãæŽå
+·äœçïŒè¿æ¯ä»¥CPANæš¡åâExifToolâäžºåºç¡ãè¿äžªæš¡åå®é
+äžä¹æ¯æå
+¶ä»æ ŒåŒïŒæ¯åŠGPSãXMPãFlashPixãID3ãVorbisïŒãæ¬æä»¶çç®æ æ¯æ¯æææExifToolæ¯æçæ ŒåŒãå
+³äºExifToolææ¯æçæä»¶ç±»ååå
+æ°æ®éè¯·åè§å
+¶ææ¡£ã  
+
+GreenstoneMETSPlugin.desc:å€çGreenstoneé£æ ŒçMETSææ¡£ã  
+
+MP3Plugin.desc:å€çMP3æä»¶çæä»¶ã  
+
+MP3Plugin.assoc_images:æ ¹æ®ID3 TitleåArtist metadataïŒäœ¿çšGoogleåŸåæçŽ¢æ¥å®äœäžMP3æä»¶çžå
+³çåŸåã  
+
+MP3Plugin.applet_metadata:çšäºå­åšæ¯äžªææ¡£çãappletãmetadataïŒææ¡£å«æå¿
+èŠçå¯ä»€MP3é³é¢æ­æŸåšå°çšåºæ­æŸè¯¥æä»¶çHTMLã  
+
+MP3Plugin.metadata_fields:ä»MP3æä»¶äž­æåéå·åéçmetadataåçéãäœ¿çš\â*\"æåææåã  
+
+NulPlugin.desc:èæïŒ.nul)æä»¶æä»¶ãäžæ¿åmetadataæ°æ®åºæä»¶æäº§ççæä»¶åæ¶äœ¿çšã  
+
+NulPlugin.assoc_field:äžºæ¯äžªæ ææä»¶è®Ÿå®çmetadataåçåå­ã  
+NulPlugin.add_metadata_as_text:æ·»å äžäžªmetadataè¡šæ Œçšäœææ¡£çææ¬ïŒå
+åŸæŸç€ºâThis document has no text"ã  
+
+NulPlugin.remove_namespace_for_text:ä»ææ¡£ææ¬äž­çmetadataåå­äž­å»é€åå­åºéŽïŒåŠæadd_metadata_as_textå·²è®Ÿå®ïŒã  
+
+OAIPlugin.desc:åºæ¬Open Archive Initiative(OAI)æä»¶ã  
+
+OAIPlugin.document_field:æ¬å
+æ°æ®çšäºæå®åœåå
+æ°æ®åºéå±çææ¡£åç§°  
+
+OAIPlugin.metadata_set:å¯Œå
+¥ææå
+æ°æ®å°è¿äžªå
+æ°æ®éïŒåœåååçŒïŒ  
+OAIPlugin.metadata_set.auto:äœ¿çšOAIè®°åœäž­æå®çåçŒ  
+OAIPlugin.metadata_set.dc:äœ¿çšdcåçŒãå°éå®æ§dcå
+çŽ æ å°å°å
+¶Greenstoneæ ŒåŒïŒæ¯åŠspatialå°è¢«æ å°ædc.Coverage^spatial.  
+
+OggVorbisPlugin.add_technical_metadata:æ·»å ææ¯ïŒäŸåŠæ¯ç¹çïŒmetadataã  
+
+OggVorbisPlugin.desc:çšäºèŸå
+¥Ogg Vorbis é³é¢æä»¶çæä»¶ã  
+
+OpenDocumentPlugin.desc:å€çOASIS OpenDocumentæ ŒåŒææ¡£çæä»¶ïŒçšäºOpenOffice 2.0)ã  
+
+PagedImagePlugin.desc:å€çç±äžè¿äž²åŸåç»æçææ¡£çæä»¶ïŒæ¯äžªåŸååžŠæå¯éçOCRææ¬ãè¯¥æä»¶å€ç.itemæä»¶ïŒè¯¥ç±»æä»¶ååºè¿ç»­åŸååææ¬æä»¶å¹¶æäŸmetadataã  
+
+PagedImagePlugin.documenttype:è®Ÿå®ææ¡£ç±»åïŒçšäºæŸç€ºïŒã  
+
+PagedImagePlugin.documenttype.paged:åé¡µçææ¡£å«æåååååçç®­å€Žä»¥å'go to page X' æ¡ã  
+
+PagedImagePlugin.documenttype.hierarchy:å±çº§ææ¡£å«ææç« ç®åœã  
+
+PagedImagePlugin.headerpage:äžºæ¯äžªææ¡£æ·»å äžäžªé¡¶çº§é¡µéŠé¡µïŒäžå«åŸåïŒã  
+
+PDFPlugin.allowimagesonly:å
+è®žPDFæä»¶äžå«å¯æåææ¬ãå
+åŸè®Ÿå®-complexéé¡¹ãä»
+çšäºconvert_to_htmlã  
+
+PDFPlugin.complex:çææŽå€æçèŸåºãè®Ÿå®è¯¥éé¡¹äŒäœ¿èŸåºçhtmlæŽè±¡åå§PDFæä»¶ãè¯¥éé¡¹èŠæ±å®è£
+GhostscriptïŒå¯¹äº*nixïŒgså¿
+é¡»äœäºç³»ç»è·¯åŸïŒå¯¹äºWindowsïŒgswin32c.exeè®Ÿå®åšç³»ç»è·¯åŸäž­ïŒã  
+
+PDFPlugin.desc:å€çPDFææ¡£çæä»¶ã  
+
+PDFPlugin.nohidden:é»æ­¢pdftohtmlæåéèææ¬ãè¿åªåš-complexéé¡¹ä¹è®Ÿå®çæ
+åµäžæçšã  
+
+PDFPlugin.noimages:äžèŠè¯åŸä»PDFäž­æååŸåã  
+
+PDFPlugin.use_sections:äžºæ¯äžªPDFæä»¶çé¡µé¢åå»ºäžäžªåç¬çæ®µèœã  
+
+PDFPlugin.zoom:èŸåºæ¶æŸå€§PDFæä»¶çç³»æ°ïŒè¿åªåš-complexéé¡¹ä¹è®Ÿå®çæ
+åµäžæçšïŒã  
+
+PostScriptPlugin.desc:è¿æ¯äžäžª\"poor man\"çpsè³ææ¬èœ¬æ¢åšãåŠæäœ æ³äœ¿çšé«çº§çåèœïŒå¯ä»¥èèPRESCRIPTå
+ïŒå¯ä»http://www.nzdl.org/html/software.htmläžèœœã  
+
+PostScriptPlugin.extract_date:ä»PSé¡µéŠæåæ¥æã  
+
+PostScriptPlugin.extract_pages:ä»PSé¡µéŠæåé¡µé¢ã  
+
+PostScriptPlugin.extract_title:ä»PSé¡µéŠæåæ é¢ã
+  
+
+PowerPointPlugin.desc:æ¬æä»¶çšäºå¯Œå
+¥Microsoft PowerPointæä»¶ã  
+
+PowerPointPlugin.windows_scripting:äœ¿çšMicrosoft Windows çèæ¬ææ¯ææ¯ïŒVisual BasicåºçšçšåºïŒæ¥å°PPTèœ¬æ¢æåç§æ ŒåŒçåŸåïŒäŸåŠJPEG,PNG,GIF)ïŒèäžäœ¿çšppttohtmlåŒæºå
+ã  
+
+PrintInfo.bad_general_option:ïŒ
+såç±»åšäœ¿çšäºéè¯¯çéé¡¹ãæ¥çäœ çé
+çœ®æä»¶collect.cfg  
+
+PrintInfo.desc:æåºæ¬æä»¶ïŒå€çæå°ä¿¡æ¯ïŒäœ¿çšpluginfo.plïŒä»¥åè§£æåæ°ã  
+
+ProCitePlugin.desc:çšäºProCiteæ°æ®åºïŒèŸåºçïŒçæä»¶ã  
+
+ProCitePlugin.entry_separator:çšæ¥åéProCiteæ°æ®åºè®°åœäž­åäžªå
+æ°æ®å­æ®µçå€äžªåŒçå­ç¬Šäž²ã  
+
+ReadTextFile.could_not_extract_encoding:è­ŠåïŒæ æ³ä»ïŒ
+säž­æåçŒç ïŒåå®åŒïŒ
+s  
+
+ReadTextFile.could_not_extract_language:è­ŠåïŒæ æ³ä»ïŒ
+säž­æåè¯­èšïŒåå®åŒïŒ
+s  
+
+ReadTextFile.could_not_open_for_reading:æ æ³æåŒïŒ
+sè¿è¡è¯»å  
+
+ReadTextFile.default_encoding:åŠæ-input_encodingéé¡¹è®Ÿäžºâautoâäžææ¬åç±»ç®æ³äžèœçŒç ææåäºäžè¢«Greenstoneæ¯æççŒç ïŒåäœ¿çšè¯¥çŒç ãè¯¥éé¡¹å¯éçšäž-input_encodingéé¡¹çžåçåŒã  
+
+ReadTextFile.default_language:åŠæGreenstoneæ æ³ç¡®è®€æäžªææ¬çè¯­èšïŒ'Language'metadataè®Ÿäžºè¯¥åŒãå
+¶åå®åŒæ¯'en' (äœ¿çšISO 639: en = English)ãè¯·æ³šæïŒåŠæ-input_encodingéé¡¹æªè®Ÿæâautoâäžæªè®Ÿ-extract_languageéé¡¹ïŒåææææ¬çâlanguage'metadataçè®Ÿäžºè¯¥åŒã  
+
+ReadTextFile.desc:çšäºå€ççº¯ææ¬æä»¶çåºæ¬æä»¶ã  
+
+ReadTextFile.empty_file:è¯¥æä»¶æ å
+å®¹  
+
+ReadTextFile.extract_language:éŽå«æ¯äžªææ¡£çè¯­èšå¹¶è®Ÿå®âLanguage'metadataãæ³šæïŒåŠæ -input_encodingè®Ÿäžºâauto'ïŒè¯¥è¿çšäŒèªåšå®æã  
+
+ReadTextFile.file_has_no_text:éè¯¯ïŒïŒ
+säžå«ææ¬  
+
+ReadTextFile.input_encoding:æºææ¡£ççŒç ãææ¡£å°çšè¿äºçŒç è¿è¡èœ¬æ¢å¹¶åšå
+éšå­åšäžºutf8ã  
+
+ReadTextFile.input_encoding.auto:äœ¿çšææ¬åç±»ç®æ³èªåšéŽå«æ¯äžªæºææ¡£ççŒç ãè¿èŠæ¯æç¡®è®Ÿå®çŒç æ
+¢ïŒäœéçšäºåäžæ¶èè®Ÿå®äºå€äžªçŒç ã  
+
+ReadTextFile.read_denied:å¯¹äºïŒ
+sè¯»åæéè¢«æç»ã  
+
+ReadTextFile.separate_cjk:åšäž­æ/æ¥æ/é©æäž­æå
+¥ç©ºæ Œä»€æ¯äžªå­æ¯æäžºäžäžªè¯ãéçšäºåœææ¬æªè¢«åå²æ¶ã  
+
+ReadTextFile.unsupported_encoding:è­ŠåïŒïŒ
+säŒŒä¹äœ¿çšäºäžè¢«æ¯æççŒç ïŒïŒ
+sïŒïŒäœ¿çšïŒ
+s  
+
+ReadTextFile.wrong_encoding:è­ŠåïŒïŒ
+sçšïŒ
+sè¯»å
+¥äœäŒŒä¹äœäžºïŒ
+sçŒç   
+
+ReadXMLFile.desc:çšäºXMLæä»¶çåºç±»ã  
+
+ReadXMLFile.xslt:çšæå®æä»¶äž­çXSLTèœ¬æ¢å¹é
+çèŸå
+¥ææ¡£ãåå®äžäžªçžå¯¹çæä»¶åäŒåšæ¶èçæä»¶åºåæŸå°ïŒäŸåŠïŒetc/mods2dc.xslã  
+
+RealMediaPlugin.desc:å€çReal Mediaæä»¶çæä»¶ã  
+
+ReferPlugin.desc:ReferPluginè¯»å
+¥Referæ ŒåŒçç®åœæç®æä»¶  
+
+RogPlugin.desc:ä».rogæ.mdbæä»¶åå»ºç®ååçº§ææ¡£ã  
+
+RTFPlugin.desc:çšäºèŸå
+¥Rich Text æ ŒåŒçæä»¶ã  
+
+SourceCodePlugin.desc:æä»¶åç®åè¢«çšäºæ é¢ïŒå¯éæ©åå»äžäºåçŒïŒãåœåè¯­èš:\nææ¬ïŒREADMEs/Makefiles\nC/C++   (ç®åä»
+æåå
+å«è¯­å¥ä»¥åC++ ç±»)\nPerl    (ç®åä»
+å€çææ¬)\nShell   (ç®åä»
+å€çææ¬)  
+
+SourceCodePlugin.remove_prefix:ä»æä»¶åäž­å é€åçŒïŒäŸåŠ-remove_prefix /tmp/XX/src/)ãåå®æ¡ä»¶äžæ¯ä»æä»¶åäž­å é€å
+šéšè·¯åŸã  
+
+SplitTextFile.desc:SplitTextFileæ¯äžäžªå°èŸå
+¥æä»¶åå²æè¥å¹²éšåçæä»¶ïŒæ¯äžªéšåéœå°è¢«åç¬å€çãæ¬æä»¶äžåºè¯¥è¢«çŽæ¥è°çšãçžåïŒåŠæäœ éèŠå€çå«æå€äžªææ¡£çæä»¶ïŒåºè¯¥çŒåèªå·±çæä»¶ïŒå
+¶äž­çå€çïŒprocessïŒåœæ°å°å€çåäžªææ¡£ïŒå¹¶äœ¿å
+¶ç»§æ¿SplitTextFileãåè§ReferPluginïŒäœäžºäžäžªèäŸã  
+
+SplitTextFile.split_exp:å°èŸå
+¥æä»¶åå²ææ®µçperlè§åè¡šè¿°ã  
+
+StructuredHTMLPlugin.desc:äžäžªå€çç»ææ§HTMLææ¡£çæä»¶ïŒåºäºæ ŒåŒä¿¡æ¯å°å®ä»¬åå²ææ®µèœã  
+
+StructuredHTMLPlugin.delete_toc:ä»èœ¬æ¢çHTMLæä»¶äž­å é€æææç« ç®åœïŒåŸè¡šç­ãå
+¶æ ŒåŒç±toc_headeréé¡¹æå®ã  
+
+StructuredHTMLPlugin.title_header:çšäºæ é¢é¡µéŠçå¯èœççšæ·å®ä¹çæ ŒåŒã  
+
+StructuredHTMLPlugin.level1_header:çšäºHTMLææ¡£äž­ç¬¬äžçº§é¡µéŠçå¯èœççšæ·å®ä¹çæ ŒåŒïŒçžåœäº<h1>)ã  
+
+StructuredHTMLPlugin.level2_header:çšäºHTMLææ¡£äž­ç¬¬äºçº§é¡µéŠçå¯èœççšæ·å®ä¹çæ ŒåŒïŒçžåœäº<h2>)ã  
+
+StructuredHTMLPlugin.level3_header:çšäºHTMLææ¡£äž­ç¬¬äžçº§é¡µéŠçå¯èœççšæ·å®ä¹çæ ŒåŒïŒçžåœäº<h3>)ã  
+
+StructuredHTMLPlugin.toc_header:çšäºæç« ç®åœïŒåŸè¡šç­çå¯èœççšæ·å®ä¹çæ ŒåŒïŒåŠædelete_tocè®Ÿå®ïŒåå é€ã  
+
+TextPlugin.desc:åå»ºç®ååçº§ææ¡£ãçšç¬¬äžè¡ææ¬äœäžºæ é¢metadataïŒäžè¶
+è¿100äžªå­æ¯ïŒã  
+
+TextPlugin.title_sub:çšäºä¿®æ¹å­åšäžºæ é¢çå­ç¬Šäž²çæ¿æ¢è¡šèŸŸåŒãæ¯åŠPostScriptPluginçšå®ä»æ é¢ææ¬äž­æž
+é€âPage 1âç­ã  
+
+UnknownPlugin.assoc_field:ææå
+³èæä»¶åçmetadataåçåç§°ã  
+
+UnknownPlugin.desc:è¿æ¯äžäžªç®åççšäºèŸå
+¥Greenstoneæ æ³è¯å«æ ŒåŒçæä»¶çæä»¶ãå°äžºæ¯äžªæä»¶äº§çäžäžªèæçææ¡£ïŒäžè¯¥æä»¶æ¬èº«äŒè¢«äœäžºææ¡£ç\"å
+³èæä»¶\"äŒ éç»Greenstoneã  
+
+UnknownPlugin.file_format:æä»¶ç±»åïŒäŸåŠMPEG,MIDI,âŠ)ã  
+
+UnknownPlugin.mime_type:æä»¶çMimeç±»åïŒäŸåŠïŒåŸå/gifïŒã  
+
+UnknownPlugin.process_extension:çšè¯¥æä»¶æ©å±å€çæä»¶ãè¯¥éé¡¹æ¯process_expçæ¿ä»£éé¡¹ïŒprocess_expæŽç®åäœéåºæ§äžåŒºã  
+
+UnknownPlugin.srcicon:æå®äžäžªäœäžºsrcicon metadataçå®çåç§°ïŒäžå äžåçº¿ïŒã  
+
+WordPlugin.desc:çšäºèŸå
+¥Microsoft Wordææ¡£çæä»¶ã  
+
+WordPlugin.windows_scripting:äœ¿çšMicrosoft Windows èæ¬ææ¯ïŒVisual BasicåºçšçšåºïŒæ¥åŸå°Wordä»èæææ¡£èœ¬æ¢æHTMLïŒèäžæ¯äŸèµäºåŒæºå
+WvWareãåŠWordåºçšçšåºæªåšè¿è¡ïŒå®å¯ä»€å
+¶èªåšæåŒã  
+
+WordPlugin.metadata_fields:è¯¥éé¡¹ä»çšVBèæ¬èœ¬æ¢æ¥çHTMLææ¡£äž­è·åmetadataãå®å
+è®žçšæ·å®ä¹è¯åŸæåçéå·åéçmetadataåçéãçš'tag<tagname>'åŸå°å­æŸåšåäžº'tagname'çmetadataå
+çŽ çç¬¬äžäžª<tagname>æ ç­Ÿç»çå
+å®¹ãå äžºæ ç­Ÿæåäžèèå€§å°åïŒé¡»å°è¯¥åè±¡å€§åGreenstoneäž­çmetadataäžæ ·å€§åæææã  
+
+ZIPPlugin.desc:å€çåçŒ©çå/æå­æ¡£çèŸå
+¥æ ŒåŒãç®åå€ççæ ŒåŒåæä»¶æ©å±åæïŒ\ngzip (.gz, .z, .tgz, .taz)\nbzip (.bz)\nbzip2 (.bz2)\nzip (.zip .jar)\ntar (.tar)ã\n\nè¯¥æä»¶èŠæ±ä»¥äžçåºçšçšåº (åŠæèŠå€ççžå¯¹åºçæ ŒåŒçè¯ïŒïŒ\ngunzip (for gzip)\nbunzip (for bzip)\nbunzip2 \nunzip (for zip)\ntar (çšäº taræä»¶)ã
+
+#
+# Download module option descriptions
+#
+
+BaseDownload.desc:Downloadæš¡åçåºç±»  
+BaseDownload.bad_general_option:%säžèœœæš¡åäœ¿çšäºäžæ°åœçéé¡¹ã  
+MediaWikiDownload.desc:çšäºä»MediaWikiçœç«äžèœœçæš¡åã  
+MediaWikiDownload.reject_filetype:å¿œç¥éå·åéçurléïŒäŸåŠ*cgi-bin*,*.pptå°å¿œç¥å«æ'cgi-bin'æ'.ppt'çéŸæ¥ã  
+MediaWikiDownload.reject_filetype_disp:å¿œç¥è¿äºURLæš¡åŒ  
+MediaWikiDownload.exclude_directories:æ¬²æé€ç®åœçéïŒå¿
+é¡»æ¯å°ç®åœçç»å¯¹è·¯åŸïŒïŒäŸåŠ /people,/documentationå°æé€åœåè åšç«ç¹äžç'people'å'documentation'å­ç®åœã  
+MediaWikiDownload.exclude_directories_disp:æé€è¿äºç®åœ  
+
+OAIDownload.desc:çšäºä»OAIç¥è¯åºäž­äžèœœçæš¡åã  
+OAIDownload.url_disp:æºURL  
+OAIDownload.url:OAIç¥è¯åºURL  
+OAIDownload.set_disp:éå¶äºè¿äžªéå  
+OAIDownload.set:ä»
+äžèœœç¥è¯åºäž­æå®çåå
+ã  
+OAIDownload.metadata_prefix_disp:å
+æ°æ®åçŒ  
+OAIDownload.metadata_prefix:å¯Œåºææ¡£äž­äœ¿çšçå
+æ°æ®æ ŒåŒïŒæ¯åŠoai_deãqdcç­ç­ãç¹å»<æå¡åšä¿¡æ¯>æé®æ¥çææ¯æçæ ŒåŒã  
+OAIDownload.get_doc_disp:è·åææ¡£ã  
+OAIDownload.get_doc:åŠææºæä»¶å·²åšè®°åœäž­æå®ïŒäžèœœå®ã  
+OAIDownload.get_doc_exts_disp:åªå
+æ¬è¿äºæä»¶ç±»å  
+OAIDownload.get_doc_exts:å
+è®žè®¿é®çæä»¶æ©å±åã  
+OAIDownload.max_records_disp:èŠäžèœœçè®°åœçæå€§æ°éã  
+OAIDownload.max_records:èŠäžèœœçè®°åœçæå€§æ°éã  
+
+SRWDownload.desc:äžäžªçšäºä»SRWïŒæçŽ¢/è·åçœç»æå¡ïŒç¥è¯åºäžèœœçæš¡åã  
+
+WebDownload.desc:å¯çšHTTPæFTPä»Internetè¿è¡äžèœœçæš¡åã  
+WebDownload.url:æºURLãå¯¹äºhttpéå®åèèšïŒè¿äžªåŒå¯èœäŒææ¹å  
+WebDownload.url_disp:æºURL  
+WebDownload.depth:äžèœœæ¶è¶
+éŸæ¥çæææ·±åºŠã  
+WebDownload.depth_disp:äžèœœæ·±åºŠã  
+WebDownload.below:ä»
+å¯¹è¯¥URLäžçæä»¶å»ºç«éåã  
+WebDownload.below_disp:ä»
+äžèœœè¯¥URLäžçæä»¶  
+WebDownload.within:ä»
+å¯¹åäžç«ç¹çæä»¶è¿è¡éåã  
+WebDownload.within_disp:ä»
+äžèœœç«ç¹å
+çæä»¶
+WebDownload.html_only:ä»
+äžèœœHTMLæä»¶ïŒå¹¶å¿œç¥å
+³èæä»¶ïŒäŸåŠåŸåååŒæ ·åŸè¡šã  
+WebDownload.html_only_disp:ä»
+äžèœœHTMLæä»¶  
+
+WgetDownload.desc:å€çwgetè°å
+¥çåºç±»ã  
+WgetDownload.proxy_on:ä»£çæå¡åšæ­£åšè¿è¡  
+WgetDownload.proxy_host:ä»£çäž»æºã  
+WgetDownload.proxy_port:ä»£çç«¯å£  
+WgetDownload.user_name:çšæ·å  
+WgetDownload.user_password:çšæ·å¯ç   
+
+Z3950Download.desc:çšäºä»Z3950ç¥è¯åºäžèœœçæš¡åã  
+Z3950Download.host:äž»æºURL  
+Z3950Download.host_disp:äž»æº  
+Z3950Download.port:ç¥è¯åºçç«¯å£åŒ  
+Z3950Download.port_disp:ç«¯å£  
+Z3950Download.database:åšå
+¶äž­æçŽ¢è®°åœçæ°æ®åºã  
+Z3950Download.database_disp:æ°æ®åº  
+Z3950Download.find:è·åå«ææå®æçŽ¢è¯çè®°åœã  
+Z3950Download.find_disp:åç°  
+Z3950Download.max_records:äžèœœçè®°åœçæå€æ°éã  
+Z3950Download.max_records_disp:æå€è®°åœ  
+
+
+#
+#Plugout option descriptions
+#
+
+BasPlugout.bad_general_option:ïŒ
+s plugoutäœ¿çšäºéè¯¯çéé¡¹ã  
+BasPlugout.debug:è®Ÿçœ®è°è¯æš¡åŒ  
+BasPlugout.desc:éçšäºææå¯Œåºplugoutçåºç±»ã  
+BasPlugout.group_size:äžäžªXMLæä»¶äž­åºå
+å«çææ¡£æ°éã  
+BasPlugout.gzip_output:äœ¿çšgzipæ¥åçŒ©çæçxmlææ¡£ïŒåœä»åçŒ©ææ¡£æå»ºæ¶èæ¶äžèŠå¿è®°å°ZIPPlugæ·»å å°æä»¶åè¡šäž­ïŒã  
+BasPlugout.output_handle:çšäºåéèŸåºä¿¡æ¯çæä»¶æè¿°åš  
+BasPlugout.output_info:arcinfoå¯¹è±¡çåŒçšïŒè¯¥arcinfoå¯¹è±¡çšäºå­åšè·å­æ¡£æä»¶çžå
+³çä¿¡æ¯ã  
+BasPlugout.verbosity:æ§å¶èŸåºä¿¡æ¯çæ°éã0ïŒæ ïŒ3ïŒåŸå€ã  
+BasPlugout.xslt_file:çšæå®æä»¶çXSLTèœ¬æ¢ææ¡£ã  
+
+DSpacePlugout.desc:Dspace Archiveæ ŒåŒã  
+
+FedoraMETSPlugout.desc:METSæ ŒåŒïŒäœ¿çšFedoraæ ŒåŒã  
+FedoraMETSPlugout.fedora_namespace:Fedoraäž­çšæ¥å€çidsïŒPIDSïŒçåçŒïŒæ¯åŠgreenstone:HASH0122efe4a2c58d0  
+
+GreenstoneXMLPlugout.desc:Greenstone XML å­æ¡£æ ŒåŒ  
+
+GreenstoneMETSPlugout.desc:METSæ ŒåŒïŒäœ¿çšGreenstoneæ ŒåŒã  
+
+MARCXMLPlugout.desc:MARC xml æ ŒåŒã  
+MARCXMLPlugout.group:å°marc xmlè®°åœèŸåºå°äžäžªåç¬æä»¶ã  
+MARCXMLPlugout.mapping_file:äœ¿çšåç§°æ å°æä»¶æ¥åèœ¬æ¢ã  
+
+METSPlugout.desc:çšäºMETSæ ŒåŒçäžçº§ç±»å¯Œåºæä»¶ãæ¬æä»¶æäŸçšäºGreenstoneMETSåFedoraMETSæ ŒåŒçåžžçšåèœïŒä»¥åæ žå¿æœè±¡æ¹æ³ã  
+METSPlugout.xslt_txt:çšæå®æä»¶äž­çXSLTèœ¬æ¢metsçdoctxt.xmlææ¡£ã  
+METSPlugout.xslt_mets:çšæå®æä»¶äž­çXSLTèœ¬æ¢metsçdocmets.xmlææ¡£ã  
+
+#
+# Perl module strings
+#
+
+classify.could_not_find_classifier:éè¯¯ïŒæ æ³æŸå°åç±»åšïŒ
+s  
+
+download.could_not_find_download:éè¯¯ïŒæ æ³æŸå°äžèœœæš¡åïŒ
+s  
+
+plugin.could_not_find_plugin:éè¯¯ïŒæ æ³æŸå°æä»¶ïŒ
+s  
+
+plugin.including_archive:å
+æ¬1 ZIP/TARå­æ¡£çå
+å®¹ã  
+
+plugin.including_archives:å
+æ¬ïŒ
+d ZIP/TARå­æ¡£çå
+å®¹ã  
+
+plugin.kill_file:è¢«.killæä»¶æž
+ççè¿çšã  
+
+plugin.n_considered:ïŒ
+d ææ¡£è¢«æ¥åå€çã  
+
+plugin.n_included:ïŒ
+d è¢«å€çäžå
+æ¬åšæ¶èäž­ã  
+
+plugin.n_rejected:ïŒ
+d è¢«æç»ã  
+
+plugin.n_unrecognised:ïŒ
+d æªç¥ã  
+
+plugin.no_plugin_could_process:è­ŠåïŒæ æä»¶å¯å€çïŒ
+s  
+
+plugin.no_plugin_could_recognise:è­ŠåïŒæ æä»¶å¯è¯å«ïŒ
+s  
+
+plugin.no_plugin_could_process_this_file:æ æä»¶å¯å€çæ­€æä»¶ã  
+
+plugin.no_plugin_could_recognise_this_file:æ æä»¶å¯è¯å«æ­€æä»¶ã  
+
+plugin.one_considered:äžäžªææ¡£è¢«æ¥åå€çã  
+
+plugin.one_included:äžäžªææ¡£è¢«å€çäžå
+æ¬åšæ¶èäž­ã  
+
+plugin.one_rejected:äžäžªææ¡£è¢«æç»ã  
+
+plugin.one_unrecognised:äžäžªææ¡£æ æ³è¯å«ã  
+
+plugin.see_faillog:è§ïŒ
+säž­äžäžªæ æ³è¯å«çïŒå/ææç»çææ¡£ã  
+
+PrintUsage.default:åå®æ¡ä»¶  
+
+PrintUsage.required:å¿
+èŠç  
+
+plugout.could_not_find_plugout:éè¯¯ïŒæ æ³æŸå°plugout\"ïŒ
+s\"  
Index: /gsdl/stable/perllib/textcat.pm
===================================================================
--- /gsdl/stable/perllib/textcat.pm	(revision 20131)
+++ /gsdl/stable/perllib/textcat.pm	(revision 20131)
@@ -0,0 +1,333 @@
+###########################################################################
+#
+# textcat.pm -- Identify the language of a piece of text
+#
+#
+# This file is based on TextCat version 1.08 by Gertjan van Noord
+# Copyright (C) 1997 Gertjan van Noord (vannoord@let.rug.nl)
+# TextCat is available from: http://odur.let.rug.nl/~vannoord/TextCat 
+#
+# It was modified by Gordon Paynter (gwp@cs.waikato.ac.nz) and turned
+# into a package for use in Greenstone digital library system.  Most of
+# the modifications consist of commenting out or deleting functionality
+# I don't need.  
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package textcat;
+
+use strict;
+
+# OPTIONS
+my $model_dir = $ENV{'GSDLHOME'} . "/perllib/textcat";
+
+my $opt_f = 1;                # Ngrams which occur <= this number of times are removed
+my $opt_t = 400;              # topmost number of ngrams that should be used
+my $opt_u = 1.05;             # how much worse result must be before it is ignored
+
+my $non_word_characters = '0-9\s';
+
+# caching related
+my %filename_cache = (); # map of cached text-strings each to array of char-encodings for the strings themselves
+my %filecontents_cache = (); # map of cached filenames to array of char-encodings for the contents of the files
+my $MAX_CACHE_SIZE = 1000;
+
+sub new {
+    my $class = shift (@_);
+    my ($tmp_f, $tmp_t, $tmp_u) = @_;
+
+    my $self = {};
+
+    # open directory to find which languages are supported
+    opendir DIR, "$model_dir" or die "directory $model_dir: $!\n";
+    my @languages = sort(grep { s/\.lm// && -r "$model_dir/$_.lm" } readdir(DIR));
+    closedir DIR;
+    @languages or die "sorry, can't read any language models from $model_dir\n" .
+	"language models must reside in files with .lm ending\n";
+
+    # load model and count for each language.
+    foreach my $language (@languages) {
+	my %ngram=();
+	my $rang=1;
+	open(LM, "$model_dir/$language.lm") || die "cannot open $language.lm: $!\n";
+	while (<LM>) {
+	    chomp;
+	    # only use lines starting with appropriate character. Others are ignored.
+	    if (/^[^$non_word_characters]+/o) {
+		$self->{'ngrams'}->{$language}->{$&} = $rang++;
+	    } 
+	}
+	close(LM);
+    }
+
+    $self->{'languages'} = \@languages;
+
+    $self->{'opt_f'} = defined($tmp_f) ? $tmp_f : $opt_f;
+    $self->{'opt_t'} = defined($tmp_t) ? $tmp_t : $opt_t;
+    $self->{'opt_u'} = defined($tmp_u) ? $tmp_u : $opt_u;
+    $self->{'max_cache_size'} = $MAX_CACHE_SIZE;
+
+    return bless $self, $class;
+}
+
+
+# CLASSIFICATION
+#
+# What language is a text string?
+#   Input:  text string
+#   Output: array of language names
+# $languages is the set of language models to consider (to textcat on)
+# Can be set to filter out language models that don't belong to the given encoding 
+# in order to obtain a list of the probable languages for that known encoding.
+# $filter_by_encoding indicates what encoding to narrow the search for languages down to.
+# This is for when we already know the encoding, but we're still looking for the language.
+sub classify {
+    my ($self, $inputref, $filter_by_encoding)=@_;
+    my $languages;
+    @$languages = ();
+
+    # filter language filenames by encoding 
+    if(defined $filter_by_encoding) {
+	# make sure to normalize language and filtering encoding so we are not
+	# stuck comparing hyphens with underscores in such things as iso-8859-1
+	my $normalized_filter = $filter_by_encoding; 
+	$normalized_filter =~ s/[\W\_]//g;
+
+	foreach my $lang (@{$self->{'languages'}}) {
+	    my $normalized_lang = $lang; 
+	    $normalized_lang =~ s/[\W\_]//g;
+
+	    if($normalized_lang =~ m/$normalized_filter/i) {
+		push (@$languages, $lang);
+	    }
+	}
+    }
+
+    # if the filter_by_encoding wasn't in the list of language model filenames
+    # or if we're not filtering, then work with all language model filenames
+    if(scalar @$languages == 0) {
+	$languages = $self->{'languages'};
+    }
+
+    my %results = ();
+    my $maxp = $self->{'opt_t'};
+
+    # create ngrams for input.
+    my $unknown = $self->create_lm($inputref);
+
+    foreach my $language (@$languages) {	
+	# compare language model with input ngrams list
+	my ($i,$p)=(0,0);
+	while ($i < scalar (@$unknown)) {
+	    if (defined ($self->{'ngrams'}->{$language}->{$unknown->[$i]})) {
+		$p=$p+abs($self->{'ngrams'}->{$language}->{$unknown->[$i]}-$i);
+	    } else { 
+		$p=$p+$maxp; 
+	    }
+	    ++$i;
+	}
+	$results{$language} = $p;
+    }
+
+    my @results = sort { $results{$a} <=> $results{$b} } keys %results;
+    my $a = $results{$results[0]};
+  
+    my @answers=(shift(@results));
+    while (@results && $results{$results[0]} < ($self->{'opt_u'} *$a)) {
+	@answers=(@answers,shift(@results));
+    }
+
+    return \@answers;
+}
+
+
+# Same as below, but caches textcat results on filenames for subsequent use.
+# The cache is a map of the filename to the corresponding filename_encodings
+# (an array of results returned by textcat of the possible filename-encodings 
+# for the indexing filename string itself). 
+# Need to make sure that the filename is only the tailname: no path and no
+# extension (no digits), in order to make optimum use of cached textcat.
+# Textcat is performed on $filename_ref and the results associated with $filename_ref.
+# The cache will be cleared when the max_cache_size is reached, which is
+# MAX_CACHE_SIZE by default or can be specified as a parameter. The cache
+# can also be cleared by a call to clear_filename_cache.
+sub classify_cached_filename {
+    my ($self, $filename_ref)=@_;
+    
+    # if not already in the cache, work it out and put it there
+    if (!defined $filename_cache{$$filename_ref}) 
+    {
+	if (scalar (keys %filename_cache) >= $self->{'max_cache_size'}) {
+	    $self->clear_filename_cache();
+	}
+	$filename_cache{$$filename_ref} = $self->classify($filename_ref);
+    } 
+
+    # return cached array of encodings for the given string
+    return $filename_cache{$$filename_ref}; 
+}
+
+# Same as above, but caches textcat results on filecontents for subsequent use.
+# Textcat on a file's contents to work out its possible encodings. Uses the cache.
+# The cache is a map of the filename to an array of possible filename_encodings
+# for the *contents* of the file returned by textcat.
+# Textcat is performed on $contents_ref and the results associated with $filename.
+# The cache will be cleared when the max_cache_size is reached, which is
+# MAX_CACHE_SIZE by default or can be specified as a parameter. The cache
+# can also be cleared by a call to clear_filecontents_cache.
+sub classify_contents {
+    my ($self, $contents_ref, $filename)=@_;
+     
+    # if not already in the cache, work it out and put it there
+    if (!defined $filecontents_cache{$filename})
+    {	   
+	if (scalar (keys %filecontents_cache) >= $self->{'max_cache_size'}) {
+	    $self->clear_filecontents_cache();
+	}
+	
+	# Finally, we can perform the textcat classification of language and encoding
+	$filecontents_cache{$filename} = $self->classify($contents_ref);
+    }
+    # return cached array of content encodings for the given filename
+    return $filecontents_cache{$filename};
+}
+
+
+# Given the known encoding for a file's contents, performs a textcat 
+# filtering on the languages for the given encoding. Results are stored
+# in the cache TWICE: once under $filename|$filter_by_encoding, and
+# once under the usual $filename, so that subsequent calls to either
+# this method or classify_contents using the same filename will not
+# perform textcat again. 
+sub classify_contents_for_encoding {
+    my ($self, $contents_ref, $filename, $filter_by_encoding)=@_;
+
+    if (!defined $filecontents_cache{"$filename|$filter_by_encoding"})
+    {	   
+	if (scalar (keys %filecontents_cache) >= $self->{'max_cache_size'}) {
+	    $self->clear_filecontents_cache();
+	}	
+
+	$filecontents_cache{"$filename|$filter_by_encoding"} = $self->classify($contents_ref, $filter_by_encoding);
+	# store this in cache again under $filename entry, so that subsequent 
+	# calls to classify_contents will find it in the cache already
+	$filecontents_cache{$filename} = $self->classify($contents_ref, $filter_by_encoding);
+    }
+    return $filecontents_cache{$filename};
+}
+   
+
+# This method returns the most frequently occurring encoding 
+# but only if any encoding occurs more than once in the given results.
+# Otherwise, "" is returned.
+sub most_frequent_encoding {
+    my ($self, $results) = @_;
+    my $best_encoding = "";
+
+    # guessed_encodings is a hashmap of Encoding -> Frequency pairs
+    my %guessed_encodings = ();
+    foreach my $result (@$results) {
+	# Get the encoding portion of a language-model filename like en-iso8859_1
+	my ($encoding) = ($result =~ /^(?:[^\-]+)\-([^\-]+)$/);
+	if(!defined($guessed_encodings{$encoding})) {
+	    $guessed_encodings{$encoding} = 0;
+	}
+	$guessed_encodings{$encoding}++;
+    }
+    
+    $guessed_encodings{""}=-1; # for default best_encoding of ""
+
+    foreach my $enc (keys %guessed_encodings) {
+	if ($guessed_encodings{$enc} > $guessed_encodings{$best_encoding}) {
+	    $best_encoding = $enc;
+	}
+    }
+
+    # If best_encoding's frequency == 1, then the frequency for all encodings will 
+    # be 1 since the sum total of all frequencies is num_results: if any encoding
+    # has frequency > 1 (it's possibly the best_encoding), one or more of the others
+    # would have been at 0 frequency to compensate.
+    return ($guessed_encodings{$best_encoding} > 1) ? $best_encoding : "";
+}
+
+
+# set some of the specific member variables
+sub set_opts {
+    my ($self, $opt_freq, $opt_factor, $opt_top, $max_size_of_cache)=@_;
+         
+    $self->{'opt_f'} = $opt_freq if defined $opt_freq;
+    $self->{'opt_u'} = $opt_factor if defined $opt_factor;
+    $self->{'opt_t'} = $opt_top if defined $opt_top;
+
+    $self->{'max_cache_size'} = $max_size_of_cache if defined $max_size_of_cache;
+}
+
+sub get_opts {
+    my $self = shift (@_);
+    return ($self->{'opt_f'}, $self->{'opt_u'}, $self->{'opt_t'}, $self->{'max_cache_size'});
+}
+
+# Clears the filename cache (a map of strings to the textcat results for each string).
+sub clear_filename_cache {
+    my $self = shift (@_);
+
+    %filename_cache = ();
+}
+
+# Clears the filecontents cache (a map of filenames to the textcat results on the contents of each file).
+sub clear_filecontents_cache {
+    my $self = shift (@_);
+
+    %filecontents_cache = ();
+}
+
+sub create_lm {
+    # $ngram contains reference to the hash we build
+    # then add the ngrams found in each word in the hash
+    my ($self, $textref) = @_;  
+    
+    my $ngram = {};
+
+    foreach my $word (split(/[$non_word_characters]+/, $$textref)) {
+	$word = "_" . $word . "_";
+	my $len = length($word);
+	my $flen=$len;
+	my $i;
+
+	for ($i=0; $i<$flen; $i++) {
+	    $ngram->{substr($word,$i,5)}++ if $len > 4;
+	    $ngram->{substr($word,$i,4)}++ if $len > 3;
+	    $ngram->{substr($word,$i,3)}++ if $len > 2;
+	    $ngram->{substr($word,$i,2)}++ if $len > 1;
+	    $ngram->{substr($word,$i,1)}++;
+	    $len--;
+	}
+    }
+
+    map { if ($ngram->{$_} <= $self->{'opt_f'}) { delete $ngram->{$_}; }
+      } keys %$ngram;
+  
+    # sort the ngrams, and spit out the $opt_t frequent ones.
+    # adding  `or $a cmp $b' in the sort block makes sorting five
+    # times slower..., although it would be somewhat nicer (unique result)
+    my @sorted = sort { $ngram->{$b} <=> $ngram->{$a} } keys %$ngram;
+    splice(@sorted,$self->{'opt_t'}) if (@sorted > $self->{'opt_t'}); 
+    return \@sorted;
+}
+
+1;
Index: /gsdl/stable/perllib/unicode.pm
===================================================================
--- /gsdl/stable/perllib/unicode.pm	(revision 20131)
+++ /gsdl/stable/perllib/unicode.pm	(revision 20131)
@@ -0,0 +1,704 @@
+###########################################################################
+#
+# unicode.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2004 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# useful functions for dealing with Unicode
+
+# Unicode strings are stored as arrays of scalars as perl 
+# lacks characters are 8-bit (currently)
+
+package unicode;
+
+eval {require bytes};
+
+use encodings;
+use strict;
+use util;
+use MIME::Base64; # for base64 encoding
+
+no strict 'refs';
+
+# ascii2unicode takes an (extended) ascii string (ISO-8859-1)
+# and returns a unicode array.
+sub ascii2unicode {
+    my ($in) = @_;
+    my $out = [];
+
+    my $i = 0;
+    my $len = length($in);
+    while ($i < $len) {
+	push (@$out, ord(substr ($in, $i, 1)));	
+	$i++;
+    }
+
+    return $out;
+}
+
+# ascii2utf8 takes a reference to an (extended) ascii string and returns a
+# UTF-8 encoded string. This is just a faster version of
+# "&unicode2utf8(&ascii2unicode($str));"
+# "Extended ascii" really means "iso_8859_1"
+sub ascii2utf8 {
+    my ($in) = @_;
+    my $out = "";
+
+    if (!defined($in)|| !defined($$in)) {
+	return $out;
+    }
+
+    my ($c);
+    my $i = 0;
+    my $len = length($$in);
+    while ($i < $len) {
+	$c = ord (substr ($$in, $i, 1));
+	if ($c < 0x80) {
+	    # ascii character
+	    $out .= chr ($c);
+
+	} else {
+	    # extended ascii character
+	    $out .= chr (0xc0 + (($c >> 6) & 0x1f));
+	    $out .= chr (0x80 + ($c & 0x3f));
+	}
+	$i++;
+    }
+
+    return $out;
+}
+
+# unicode2utf8 takes a unicode array as input and encodes it
+# using utf-8
+sub unicode2utf8 {
+    my ($in) = @_;
+    my $out = "";
+    
+    foreach my $num (@$in) {
+	next unless defined $num;
+	if ($num < 0x80) {
+	    $out .= chr ($num);
+
+	} elsif ($num < 0x800) {
+	    $out .= chr (0xc0 + (($num >> 6) & 0x1f));
+	    $out .= chr (0x80 + ($num & 0x3f));
+
+	} elsif ($num < 0xFFFF) {
+	    $out .= chr (0xe0 + (($num >> 12) & 0xf));
+	    $out .= chr (0x80 + (($num >> 6) & 0x3f));
+	    $out .= chr (0x80 + ($num & 0x3f));
+
+	} else {
+	    # error, don't encode anything
+	    die;
+	}
+    }
+    return $out;
+}
+
+# utf82unicode takes a utf-8 string and produces a unicode
+# array
+sub utf82unicode {
+    my ($in) = @_;
+    my $out = [];
+
+    my $i = 0;
+    my ($c1, $c2, $c3);
+    my $len = length($in);
+    while ($i < $len) {
+	if (($c1 = ord(substr ($in, $i, 1))) < 0x80) {
+	    # normal ascii character
+	    push (@$out, $c1);
+
+	} elsif ($c1 < 0xc0) {
+	    # error, was expecting the first byte of an
+	    # encoded character. Do nothing.
+
+	} elsif ($c1 < 0xe0 && $i+1 < $len) {
+	    # an encoded character with two bytes
+	    $c2 = ord (substr ($in, $i+1, 1));
+	    if ($c2 >= 0x80 && $c2 < 0xc0) {
+		# everything looks ok
+		push (@$out, ((($c1 & 0x1f) << 6) +
+		      ($c2 & 0x3f)));
+		$i++; # gobbled an extra byte
+	    }
+
+	} elsif ($c1 < 0xf0 && $i+2 < $len) {
+	    # an encoded character with three bytes
+	    $c2 = ord (substr ($in, $i+1, 1));
+	    $c3 = ord (substr ($in, $i+2, 1));
+	    if ($c2 >= 0x80 && $c2 < 0xc0 &&
+		$c3 >= 0x80 && $c3 < 0xc0) {
+		# everything looks ok
+		push (@$out, ((($c1 & 0xf) << 12) +
+		      (($c2 & 0x3f) << 6) +
+		      ($c3 & 0x3f)));
+
+		$i += 2; # gobbled an extra two bytes
+	    }
+
+	} else {
+	    # error, only decode Unicode characters not full UCS.
+	    # Do nothing.
+	}
+
+	$i++;
+    }
+
+    return $out;
+}
+
+# unicode2ucs2 takes a unicode array and produces a UCS-2
+# unicode string (every two bytes forms a unicode character)
+sub unicode2ucs2 {
+    my ($in) = @_;
+    my $out = "";
+
+    foreach my $num (@$in) {
+	$out .= chr (($num & 0xff00) >> 8);
+	$out .= chr ($num & 0xff);
+    }
+
+    return $out;
+}
+
+# ucs22unicode takes a UCS-2 string and produces a unicode array
+sub ucs22unicode {
+    my ($in) = @_;
+    my $out = [];
+
+    my $i = 0;
+    my $len = length ($in);
+    while ($i+1 < $len) {
+	push (@$out, ord (substr($in, $i, 1)) << 8 +
+	      ord (substr($in, $i+1, 1)));
+
+	$i ++;
+    }
+
+    return $out;
+}
+
+# takes a reference to a string and returns a reference to a unicode array
+sub convert2unicode {
+    my ($encoding, $textref) = @_;
+
+    if (!defined $encodings::encodings->{$encoding}) {
+	print STDERR "unicode::convert2unicode: ERROR: Unsupported encoding ($encoding)\n";
+	return [];
+    }
+
+    my $encodename = "$encoding-unicode";
+    my $enc_info = $encodings::encodings->{$encoding};
+    my $mapfile = &util::filename_cat($ENV{'GSDLHOME'}, "mappings",
+				      "to_uc", $enc_info->{'mapfile'});
+    if (!&loadmapencoding ($encodename, $mapfile)) {
+	print STDERR "unicode: ERROR - could not load encoding $encodename: $! $mapfile\n";
+	return [];
+    }
+    
+    if (defined $enc_info->{'converter'}) {
+	my $converter = $enc_info->{'converter'};
+	return &$converter ($encodename, $textref);
+    }
+
+    if ($unicode::translations{$encodename}->{'count'} == 1) {
+	return &singlebyte2unicode ($encodename, $textref);
+    } else {
+	return &doublebyte2unicode ($encodename, $textref);
+    }
+}
+
+# singlebyte2unicode converts simple 8 bit encodings where characters below
+# 0x80 are normal ascii characters and the rest are decoded using the
+# appropriate mapping files.
+#
+# Examples of encodings that may be converted using singlebyte2unicode are
+# the iso-8859 and windows-125* series.
+sub singlebyte2unicode {
+    my ($encodename, $textref) = @_;
+
+    my @outtext = ();
+    my $len = length($$textref);
+    my ($c);
+    my $i = 0;
+
+    while ($i < $len) {
+	if (($c = ord(substr($$textref, $i, 1))) < 0x80) {
+	    # normal ascii character
+	    push (@outtext, $c);
+	} else {
+	    $c = &transchar ($encodename, $c);
+	    # put a black square if cannot translate
+	    $c = 0x25A1 if $c == 0;
+	    push (@outtext, $c);
+	}
+	$i ++;
+    }
+    return \@outtext;
+}
+
+# doublebyte2unicode converts simple two byte encodings where characters
+# below code point 0x80 are single-byte characters and the rest are
+# double-byte characters.
+#
+# Examples of encodings that may be converted using doublebyte2unicode are
+# CJK encodings like GB encoded Chinese and UHC Korean.
+#
+# Note that no error checking is performed to make sure that the input text
+# is valid for the given encoding.
+#
+# Also, encodings that may contain characters of more than two bytes are
+# not supported (any EUC encoded text may in theory contain 3-byte
+# characters but in practice only one and two byte characters are used).
+sub doublebyte2unicode {
+    my ($encodename, $textref) = @_;    
+    
+    my @outtext = ();
+    my $len = length($$textref);
+    my ($c1, $c2);
+    my $i = 0;
+
+    while ($i < $len) {
+	if (($c1 = ord(substr($$textref, $i, 1))) >= 0x80) {
+	    if ($i+1 < $len) {
+		# double-byte character
+		$c2 = ord(substr($$textref, $i+1, 1));
+		my $c = &transchar ($encodename, ($c1 << 8) | $c2);
+		# put a black square if cannot translate
+		$c = 0x25A1 if $c == 0;
+		push (@outtext, $c);
+		$i += 2;
+		
+	    } else {
+		# error
+		print STDERR "unicode: ERROR missing second half of double-byte character\n";
+		$i++;
+	    }
+	    
+	} else {
+	    # single-byte character
+	    push (@outtext, $c1);
+	    $i++;
+	}
+    }
+    return \@outtext;
+}
+
+# Shift-JIS to unicode
+# We can't use doublebyte2unicode for Shift-JIS because it uses some
+# single-byte characters above code point 0x80 (i.e. half-width katakana
+# characters in the range 0xA1-0xDF)
+sub shiftjis2unicode {
+    my ($encodename, $textref) = @_;
+    
+    my @outtext = ();
+    my $len = length($$textref);
+    my ($c1, $c2);
+    my $i = 0;
+
+    while ($i < $len) {
+	$c1 = ord(substr($$textref, $i, 1));
+
+	if (($c1 >= 0xA1 && $c1 <= 0xDF) || $c1 == 0x5c || $c1 == 0x7E) {
+	    # Single-byte half-width katakana character or
+	    # JIS Roman yen or overline characters
+	    my $c = &transchar ($encodename, $c1);
+	    # - put a black square if cannot translate
+	    $c = 0x25A1 if $c == 0;
+	    push (@outtext, $c);
+	    $i++;
+
+	} elsif ($c1 < 0x80) {
+	    # ASCII
+	    push (@outtext, $c1);
+	    $i ++;
+
+	} elsif ($c1 < 0xEF) {
+	    if ($i+1 < $len) {
+		$c2 = ord(substr($$textref, $i+1, 1));
+		if (($c2 >= 0x40 && $c2 <= 0x7E) || ($c2 >= 0x80 && $c2 <= 0xFC)) {
+		    # Double-byte shift-jis character
+		    my $c = &transchar ($encodename, ($c1 << 8) | $c2);
+		    # put a black square if cannot translate
+		    $c = 0x25A1 if $c == 0;
+		    push (@outtext, $c);
+		} else {
+		    # error
+		    print STDERR "unicode: ERROR Invalid Shift-JIS character\n";
+		}
+		$i += 2;
+	    } else {
+		# error
+		print STDERR "unicode: ERROR missing second half of Shift-JIS character\n";
+		$i ++;
+	    }
+	} else {
+	    # error
+	    print STDERR "unicode: ERROR Invalid Shift-JIS character\n";
+	    $i ++;
+	}
+    }
+    return \@outtext;
+}
+
+sub transchar {
+    my ($encoding, $from) = @_;
+    my $high = ($from / 256) % 256;
+    my $low = $from % 256;
+
+    return 0 unless defined $unicode::translations{$encoding};
+
+    my $block = $unicode::translations{$encoding}->{'map'};
+
+    if (ref ($block->[$high]) ne "ARRAY") {
+	return 0;
+    }
+    return $block->[$high]->[$low];
+}
+
+# %translations is of the form:
+#
+# encodings{encodingname-encodingname}->{'map'}->blocktranslation
+# blocktranslation->[[0-255],[256-511], ..., [65280-65535]]
+#
+# Any of the top translation blocks can point to an undefined
+# value. This data structure aims to allow fast translation and 
+# efficient storage.
+%unicode::translations = ();
+
+# @array256 is used for initialisation, there must be
+# a better way...
+# What about this?: @array256 = (0) x 256;
+@unicode::array256 = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+
+# returns 1 if successful, 0 if unsuccessful
+sub loadmapencoding {
+    my ($encoding, $mapfile) = @_;
+    
+    # check to see if the encoding has already been loaded
+    return 1 if (defined $unicode::translations{$encoding});
+
+    if (! -r $mapfile || -d $mapfile) {
+	return 0;
+    }
+    return 0 unless open (MAPFILE, $mapfile);
+    binmode (MAPFILE);
+
+    $unicode::translations{$encoding} = {'map' => [@unicode::array256], 'count' => 0};
+    my $block = $unicode::translations{$encoding};
+
+    my ($in,$i,$j);
+    while (1) {
+	my $ret=read(MAPFILE, $in, 1);
+	if (!defined($ret)) { # error
+	    print STDERR "unicode.pm: error reading mapfile: $!\n";
+	    last;
+	}
+	if ($ret != 1) { last }
+	$i = unpack ("C", $in);
+	$block->{'map'}->[$i] = [@unicode::array256];
+	for ($j=0; $j<256 && read(MAPFILE, $in, 2)==2; $j++) {
+	    my ($n1, $n2) = unpack ("CC", $in);
+	    $block->{'map'}->[$i]->[$j] = ($n1*256) + $n2;
+	}
+	$block->{'count'} ++;
+    }
+
+    close (MAPFILE);
+}
+
+# unicode2singlebyte converts unicode to simple 8 bit encodings where
+# characters below 0x80 are normal ascii characters and the rest are encoded
+# using the appropriate mapping files.
+#
+# Examples of encodings that may be converted using unicode2singlebyte are
+# the iso-8859 and windows-125* series, KOI8-R (Russian), and the Kazakh encoding.
+sub unicode2singlebyte {
+    my ($uniref, $encoding) = @_;
+
+    my $outtext = "";
+    my $encodename = "unicode-$encoding";
+
+    if (!exists $encodings::encodings->{$encoding}) {
+	print STDERR "unicode.pm: ERROR - unsupported encoding "
+	    . "'$encoding' requested\n";
+	return "";
+    }
+
+    my $enc_info = $encodings::encodings->{$encoding};
+    my $mapfile = &util::filename_cat($ENV{'GSDLHOME'}, "mappings",
+				      "from_uc", $enc_info->{'mapfile'});
+    if (!&loadmapencoding ($encodename, $mapfile)) {
+	print STDERR "unicode: ERROR - could not load encoding $encodename: $! $mapfile\n";
+	return "";
+    }
+    
+    foreach my $c (@$uniref) {
+	if ($c < 0x80) {
+	    # normal ascii character
+	    $outtext .= chr($c);
+	} else {
+	    # extended ascii character
+	    $c = &transchar ($encodename, $c);
+
+	    # put a question mark if cannot translate
+	    if ($c == 0) {
+		$outtext .= "?";
+	    } else {
+		$outtext .= chr($c);
+	    }
+	}
+    }
+    return $outtext;
+}
+
+
+# this makes sure that the referenced input string is utf8 encoded, and
+# will change/remove bytes that aren't.
+# returns 0 if the text was already utf8, or 1 if text modified to become utf8
+sub ensure_utf8 {
+    my $stringref=shift;
+
+    if (!defined($stringref) || ref($stringref) ne 'SCALAR') {
+	return $stringref;
+    }
+
+    my $value=$$stringref;
+
+    my $non_utf8_found = 0;
+    $value =~ m/^/g; # to set \G
+    while ($value =~ m!\G.*?([\x80-\xff]+)!sg) {
+	my $highbytes=$1;
+	my $highbyteslength=length($highbytes);
+	# make sure this block of high bytes is utf-8
+	$highbytes =~ /^/g; # set pos()
+	my $byte_replaced = 0;
+	while ($highbytes =~
+		m!\G (?: [\xc0-\xdf][\x80-\xbf]   | # 2 byte utf-8
+			[\xe0-\xef][\x80-\xbf]{2} | # 3 byte
+			[\xf0-\xf7][\x80-\xbf]{3} | # 4 byte
+			[\xf8-\xfb][\x80-\xbf]{4} | # 5 byte
+			[\xfc-\xfd][\x80-\xbf]{5} | # 6 byte
+			)*([\x80-\xff])? !xg
+		) {
+	    # this highbyte is "out-of-place" for valid utf-8
+	    my $badbyte=$1;
+	    if (!defined $badbyte) {next} # hit end of string
+	    my $pos=pos($highbytes);
+	    # replace bad byte. assume iso-8859-1 -> utf-8
+	    # ascii2utf8 does "extended ascii"... ie iso-8859-1
+	    my $replacement=&unicode::ascii2utf8(\$badbyte);
+	    substr($highbytes, $pos-1, 1, $replacement);
+	    # update the position to continue searching (for \G)
+	    pos($highbytes) = $pos+length($replacement)-1;
+	    $byte_replaced = 1;
+	}
+	if ($byte_replaced) {
+	    # replace this block of high bytes in the $value
+	    $non_utf8_found = 1;
+	    my $replength=length($highbytes); # we've changed the length
+	    my $textpos=pos($value); # pos at end of last match
+	    # replace bad bytes with good bytes
+	    substr($value, $textpos-$highbyteslength,
+			    $highbyteslength, $highbytes);
+	    # update the position to continue searching (for \G)
+	    pos($value)=$textpos+($replength-$highbyteslength)+1;
+	}
+    }
+
+    $$stringref = $value;
+    return $non_utf8_found;
+}
+
+# Returns true (1) if the given string is utf8 and false (0) if it isn't.
+# Does not modify the string parameter.
+sub check_is_utf8 {
+    my $value=shift;
+
+    if (!defined($value)) {
+	return 0; # not utf8 because it is undefined
+    }
+
+    $value =~ m/^/g; # to set \G
+    while ($value =~ m!\G.*?([\x80-\xff]+)!sg) {
+	my $highbytes=$1;
+	# make sure this block of high bytes is utf-8
+	$highbytes =~ /^/g; # set pos()
+	while ($highbytes =~
+		m!\G (?: [\xc0-\xdf][\x80-\xbf]   | # 2 byte utf-8
+			[\xe0-\xef][\x80-\xbf]{2} | # 3 byte
+			[\xf0-\xf7][\x80-\xbf]{3} | # 4 byte
+			[\xf8-\xfb][\x80-\xbf]{4} | # 5 byte
+			[\xfc-\xfd][\x80-\xbf]{5} | # 6 byte
+			)*([\x80-\xff])? !xg
+		) {
+	    my $badbyte=$1;
+	    if (defined $badbyte) { # not end of string
+		return 0; # non-utf8 found
+	    } 
+	}
+    }
+    
+    return 1;
+}
+
+sub url_encode {
+    my ($text) = @_;
+    
+    if (!&is_url_encoded($text)) {
+	$text =~ s/([^A-Z0-9\ \.\-\_])/sprintf("%%%02X", ord($1))/iseg;
+	# return the url-encoded character entity for underscore back to the entity
+	$text =~ s/%26%23095%3B/&\#095;/g;
+    }
+    return $text;
+}
+
+sub url_decode {
+    my ($text) = @_;
+
+    $text =~ s/\%([A-F0-9]{2})/pack('C', hex($1))/ige;
+    return $text;
+}
+
+sub is_url_encoded {
+    my ($text) = @_;
+    return ($text =~ m/\%([A-F0-9]{2})/);
+}
+
+# When a filename on the filesystem is already URL-encoded, the
+# URL to it will have %25s in place of every % sign, so that 
+# URLs in html pages can refer to the URL-encoded filename.
+# This method changes the URL reference back into the actual 
+# (URL-encoded) filename on the filesystem by replacing %25 with %. 
+sub url_to_filename {
+    my ($text) =@_;
+    $text =~ s/%25/%/g if &is_url_encoded($text);
+    # DM safing would have replaced underscores with character entity &#095; 
+    # in SourceFile meta. Undo any such change to get the filename referred to.
+    $text =~ s/&\#095;/_/g;
+    return $text;
+}
+
+# When a filename on the filesystem is already URL-encoded, the
+# URL to it will have %25s in place of every % sign, so that 
+# URLs in html pages can refer to the URL-encoded filename.
+# Given a (URL-encoded) filename on the filesystem, this subroutine
+# returns the URL reference string for it by replacing % with %25. 
+# The output string will be the same as the input string if the input
+# already contains one or more %25s. This is to prevent processing 
+# a url more than once this way.
+sub filename_to_url {
+    my ($text) = @_;
+    
+    if($text !~ m/%25/) {
+	$text =~ s/%/%25/g;
+    }
+    return $text;
+}
+
+sub base64_encode {
+    my ($text) = @_;
+    if(!&conforms_to_mod_base64($text)) {
+	# return entity for underscore to underscore before encoding
+	$text =~ s/&\#095;/_/g;
+
+	$text = &MIME::Base64::encode_base64($text);
+	# base64 encoding may introduce + and / signs,
+	# replacing them with - and _ to ensure it's filename-safe
+	$text =~ s/\+/\-/g; # + -> -
+	$text =~ s/\//\_/g; # / -> _
+    }
+    return $text;
+}
+
+# If the input fits the modified base64 pattern, this will try decoding it. 
+# Still, this method does not guarantee the return value is the 'original', only
+# that the result is where the base64 decoding process has been applied once.
+# THIS METHOD IS NOT USED at the moment. It's here for convenience and symmetry.
+sub base64_decode {
+    my ($text) = @_;
+    if(&conforms_to_mod_base64($text)) {
+	# base64 encodes certain chars with + and /, but if we'd encoded it, we'd
+	# have replaced them with - and _ respectively. Undo this before decoding.
+	$text =~ s/\-/\+/g;      # - -> +
+	$text =~ s/\_/\//g;      # _ -> /
+	$text = &MIME::Base64::decode_base64($text);
+    }
+    return $text;
+}
+
+# Returns true if the given string is compatible with a modified version
+# of base64 (where the + and / are replaced with - and _), a format which 
+# includes also regular ASCII alphanumeric values. This method does not 
+# guarantee that the given string is actually base64 encoded, since it will
+# return true for any simple alphanumeric ASCII string as well. 
+sub conforms_to_mod_base64 {
+    my ($text) = @_;
+
+    # need to treat the entity ref for underscore as underscore
+    $text =~ s/&\#095;/_/g;
+
+    # base 64 takes alphanumeric and [=+/], 
+    # but we use modified base64 where + and / are replaced with  - and _
+    return ($text =~ m/^[A-Za-z0-9\=\-\_]+$/); #alphanumeric and [=-_]
+}
+
+sub substr
+{
+    my ($utf8_string, $offset, $length) = @_;
+
+    my @unicode_string = @{&utf82unicode($utf8_string)};
+    my $unicode_string_length = scalar(@unicode_string);
+
+    my $substr_start = $offset;
+    if ($substr_start >= $unicode_string_length) {
+	return "";
+    }
+
+    my $substr_end = $offset + $length - 1;
+    if ($substr_end >= $unicode_string_length) {
+	$substr_end = $unicode_string_length - 1;
+    }
+
+    my @unicode_substring = @unicode_string[$substr_start..$substr_end];
+    return &unicode2utf8(\@unicode_substring);
+}
+
+
+1;
Index: /gsdl/stable/perllib/util.pm
===================================================================
--- /gsdl/stable/perllib/util.pm	(revision 20131)
+++ /gsdl/stable/perllib/util.pm	(revision 20131)
@@ -0,0 +1,1103 @@
+###########################################################################
+#
+# util.pm -- various useful utilities
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+package util;
+
+use File::Copy;
+use File::Basename;
+
+use strict;
+
+
+# removes files (but not directories)
+sub rm {
+    my (@files) = @_;
+
+    my @filefiles = ();
+
+    # make sure the files we want to delete exist 
+    # and are regular files
+    foreach my $file (@files) {
+	if (!-e $file) {
+	    print STDERR "util::rm $file does not exist\n";
+	} elsif ((!-f $file) && (!-l $file)) {
+	    print STDERR "util::rm $file is not a regular (or symbolic) file\n";
+	} else {
+	    push (@filefiles, $file);
+	}
+    }
+    
+    # remove the files
+    my $numremoved = unlink @filefiles;
+
+    # check to make sure all of them were removed
+    if ($numremoved != scalar(@filefiles)) {
+	print STDERR "util::rm Not all files were removed\n";
+    }
+}
+
+
+
+# recursive removal
+sub filtered_rm_r {
+    my ($files,$file_accept_re,$file_reject_re) = @_;
+
+    my @files_array = (ref $files eq "ARRAY") ? @$files : ($files);
+
+    # recursively remove the files
+    foreach my $file (@files_array) {
+	$file =~ s/[\/\\]+$//; # remove trailing slashes
+	
+	if (!-e $file) {
+	    print STDERR "util::filtered_rm_r $file does not exist\n";
+
+	} elsif ((-d $file) && (!-l $file)) { # don't recurse down symbolic link
+	    # get the contents of this directory
+	    if (!opendir (INDIR, $file)) {
+		print STDERR "util::filtered_rm_r could not open directory $file\n";
+	    } else {
+		my @filedir = grep (!/^\.\.?$/, readdir (INDIR));
+		closedir (INDIR);
+				
+		# remove all the files in this directory
+		map {$_="$file/$_";} @filedir;
+		&filtered_rm_r (\@filedir,$file_accept_re,$file_reject_re);
+
+		if (!defined $file_accept_re && !defined $file_reject_re) {
+		    # remove this directory
+		    if (!rmdir $file) {
+			print STDERR "util::filtered_rm_r couldn't remove directory $file\n";
+		    }
+		}
+	    }
+	} else {
+	    next if (defined $file_reject_re && ($file =~ m/$file_reject_re/));
+
+	    if ((!defined $file_accept_re) || ($file =~ m/$file_accept_re/)) {
+		# remove this file	
+		&rm ($file);
+	    }
+	}
+    }
+}
+
+
+# recursive removal
+sub rm_r {
+    my (@files) = @_;
+    
+    # use the more general (but reterospectively written function
+    # filtered_rm_r function()
+
+    filtered_rm_r(\@files,undef,undef); # no accept or reject expressions
+}
+
+
+
+
+# moves a file or a group of files
+sub mv {
+    my $dest = pop (@_);
+    my (@srcfiles) = @_;
+
+    # remove trailing slashes from source and destination files
+    $dest =~ s/[\\\/]+$//;
+    map {$_ =~ s/[\\\/]+$//;} @srcfiles;
+
+    # a few sanity checks
+    if (scalar (@srcfiles) == 0) {
+	print STDERR "util::mv no destination directory given\n";
+	return;
+    } elsif ((scalar (@srcfiles) > 1) && (!-d $dest)) {
+	print STDERR "util::mv if multiple source files are given the ".
+	    "destination must be a directory\n";
+	return;
+    }
+
+    # move the files
+    foreach my $file (@srcfiles) {
+	my $tempdest = $dest;
+	if (-d $tempdest) {
+	    my ($filename) = $file =~ /([^\\\/]+)$/;
+	    $tempdest .= "/$filename";
+	}
+	if (!-e $file) {
+	    print STDERR "util::mv $file does not exist\n";
+	} else {
+	    rename ($file, $tempdest);
+	}
+    }
+}
+
+
+# copies a file or a group of files
+sub cp {
+    my $dest = pop (@_);
+    my (@srcfiles) = @_;
+
+    # remove trailing slashes from source and destination files
+    $dest =~ s/[\\\/]+$//;
+    map {$_ =~ s/[\\\/]+$//;} @srcfiles;
+
+    # a few sanity checks
+    if (scalar (@srcfiles) == 0) {
+	print STDERR "util::cp no destination directory given\n";
+	return;
+    } elsif ((scalar (@srcfiles) > 1) && (!-d $dest)) {
+	print STDERR "util::cp if multiple source files are given the ".
+	    "destination must be a directory\n";
+	return;
+    }
+
+    # copy the files
+    foreach my $file (@srcfiles) {
+	my $tempdest = $dest;
+	if (-d $tempdest) {
+	    my ($filename) = $file =~ /([^\\\/]+)$/;
+	    $tempdest .= "/$filename";
+	}
+	if (!-e $file) {
+	    print STDERR "util::cp $file does not exist\n";
+	} elsif (!-f $file) {
+	    print STDERR "util::cp $file is not a plain file\n";
+	} else {
+	    &File::Copy::copy ($file, $tempdest);
+	}
+    }
+}
+
+
+
+# recursively copies a file or group of files
+# syntax: cp_r (sourcefiles, destination directory)
+# destination must be a directory - to copy one file to
+# another use cp instead
+sub cp_r {
+    my $dest = pop (@_);
+    my (@srcfiles) = @_;
+
+    # a few sanity checks
+    if (scalar (@srcfiles) == 0) {
+	print STDERR "util::cp_r no destination directory given\n";
+	return;
+    } elsif (-f $dest) {
+	print STDERR "util::cp_r destination must be a directory\n";
+	return;
+    }
+    
+    # create destination directory if it doesn't exist already
+    if (! -d $dest) {
+	my $store_umask = umask(0002);
+	mkdir ($dest, 0777);
+	umask($store_umask);
+    } 
+
+    # copy the files
+    foreach my $file (@srcfiles) {
+
+	if (!-e $file) {
+	    print STDERR "util::cp_r $file does not exist\n";
+
+	} elsif (-d $file) {
+	    # make the new directory
+	    my ($filename) = $file =~ /([^\\\/]*)$/;
+	    $dest = &util::filename_cat ($dest, $filename);
+	    my $store_umask = umask(0002);
+	    mkdir ($dest, 0777);
+	    umask($store_umask);
+
+	    # get the contents of this directory
+	    if (!opendir (INDIR, $file)) {
+		print STDERR "util::cp_r could not open directory $file\n";
+	    } else {
+		my @filedir = readdir (INDIR);
+		closedir (INDIR);
+		foreach my $f (@filedir) {
+		    next if $f =~ /^\.\.?$/;
+		    # copy all the files in this directory
+		    my $ff = &util::filename_cat ($file, $f); 
+		    &cp_r ($ff, $dest);
+		}
+	    }
+
+	} else {
+	    &cp($file, $dest);
+	}
+    }
+}
+
+# copies a directory and its contents, excluding subdirectories, into a new directory
+sub cp_r_toplevel {
+    my $dest = pop (@_);
+    my (@srcfiles) = @_;
+
+    # a few sanity checks
+    if (scalar (@srcfiles) == 0) {
+	print STDERR "util::cp_r no destination directory given\n";
+	return;
+    } elsif (-f $dest) {
+	print STDERR "util::cp_r destination must be a directory\n";
+	return;
+    }
+    
+    # create destination directory if it doesn't exist already
+    if (! -d $dest) {
+	my $store_umask = umask(0002);
+	mkdir ($dest, 0777);
+	umask($store_umask);
+    } 
+
+    # copy the files
+    foreach my $file (@srcfiles) {
+
+	if (!-e $file) {
+	    print STDERR "util::cp_r $file does not exist\n";
+
+	} elsif (-d $file) {
+	    # make the new directory
+	    my ($filename) = $file =~ /([^\\\/]*)$/;
+	    $dest = &util::filename_cat ($dest, $filename);
+	    my $store_umask = umask(0002);
+	    mkdir ($dest, 0777);
+	    umask($store_umask);
+
+	    # get the contents of this directory
+	    if (!opendir (INDIR, $file)) {
+		print STDERR "util::cp_r could not open directory $file\n";
+	    } else {
+		my @filedir = readdir (INDIR);
+		closedir (INDIR);
+		foreach my $f (@filedir) {
+		    next if $f =~ /^\.\.?$/;
+		    
+		    # copy all the files in this directory, but not directories
+		    my $ff = &util::filename_cat ($file, $f); 
+		    if (-f $ff) {
+			&cp($ff, $dest);
+			#&cp_r ($ff, $dest);
+		    }
+		}
+	    }
+
+	} else {
+	    &cp($file, $dest);
+	}
+    }
+}
+
+sub mk_dir {
+    my ($dir) = @_;
+
+    my $store_umask = umask(0002);
+    my $mkdir_ok = mkdir ($dir, 0777);
+    umask($store_umask);
+    
+    if (!$mkdir_ok) 
+    {
+	print STDERR "util::mk_dir could not create directory $dir\n";
+	return;
+    }
+}
+
+# in case anyone cares - I did some testing (using perls Benchmark module)
+# on this subroutine against File::Path::mkpath (). mk_all_dir() is apparently
+# slightly faster (surprisingly) - Stefan.
+sub mk_all_dir {
+    my ($dir) = @_;
+
+    # use / for the directory separator, remove duplicate and
+    # trailing slashes
+    $dir=~s/[\\\/]+/\//g; 
+    $dir=~s/[\\\/]+$//;
+
+    # make sure the cache directory exists
+    my $dirsofar = "";
+    my $first = 1;
+    foreach my $dirname (split ("/", $dir)) {
+	$dirsofar .= "/" unless $first;
+	$first = 0;
+
+	$dirsofar .= $dirname;
+
+	next if $dirname =~ /^(|[a-z]:)$/i;
+	if (!-e $dirsofar)
+	    {
+		my $store_umask = umask(0002);
+		my $mkdir_ok = mkdir ($dirsofar, 0777);
+		umask($store_umask);
+		if (!$mkdir_ok)
+		{
+		    print STDERR "util::mk_all_dir could not create directory $dirsofar\n";
+		    return;
+		}
+	    }
+    }
+}
+
+# make hard link to file if supported by OS, otherwise copy the file
+sub hard_link {
+    my ($src, $dest, $verbosity) = @_;
+
+    # remove trailing slashes from source and destination files
+    $src =~ s/[\\\/]+$//;
+    $dest =~ s/[\\\/]+$//;
+
+    # a few sanity checks
+    if (-e $dest) {
+	# destination file already exists
+	return;
+    }
+    elsif (!-e $src) {
+	print STDERR "util::hard_link source file $src does not exist\n";
+	return 1;
+    }
+    elsif (-d $src) {
+	print STDERR "util::hard_link source $src is a directory\n";
+	return 1;
+    }
+
+    my $dest_dir = &File::Basename::dirname($dest);
+    mk_all_dir($dest_dir) if (!-e $dest_dir);
+
+    # link not supported on windows 9x
+    if (($ENV{'GSDLOS'} =~ /^windows$/i) && (Win32::FsType() !~ /^ntfs$/i)) {
+	&File::Copy::copy ($src, $dest);
+
+    } elsif (!link($src, $dest)) {
+	if ((!defined $verbosity) || ($verbosity>2)) {
+	    print STDERR "util::hard_link: unable to create hard link. ";
+	    print STDERR " Copying file: $src -> $dest\n";
+	}
+	&File::Copy::copy ($src, $dest);
+    }
+    return 0;
+}
+
+# make soft link to file if supported by OS, otherwise copy file
+sub soft_link {
+    my ($src, $dest, $ensure_paths_absolute) = @_;
+
+    # remove trailing slashes from source and destination files
+    $src =~ s/[\\\/]+$//;
+    $dest =~ s/[\\\/]+$//;
+
+    # Ensure file paths are absolute IF requested to do so 
+    # Soft_linking didn't work for relative paths
+    if(defined $ensure_paths_absolute && $ensure_paths_absolute) {
+	# We need to ensure that the src file is the absolute path 
+	# See http://perldoc.perl.org/File/Spec.html
+	if(!File::Spec->file_name_is_absolute( $src ))  { # it's relative
+	    $src = File::Spec->rel2abs($src); # make absolute
+	}
+	# Might as well ensure that the destination file's absolute path is used
+	if(!File::Spec->file_name_is_absolute( $dest )) {
+	    $dest = File::Spec->rel2abs($dest); # make absolute
+	}
+    }
+
+    # a few sanity checks
+    if (!-e $src) {
+	print STDERR "util::soft_link source file $src does not exist\n";
+	return 0;
+    }
+
+    my $dest_dir = &File::Basename::dirname($dest);
+    mk_all_dir($dest_dir) if (!-e $dest_dir);
+
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	# symlink not supported on windows
+	&File::Copy::copy ($src, $dest);
+
+    } elsif (!eval {symlink($src, $dest)}) {
+	print STDERR "util::soft_link: unable to create soft link.\n";
+	return 0;
+    }
+
+    return 1;
+}
+
+
+
+
+# updates a copy of a directory in some other part of the filesystem
+# verbosity settings are: 0=low, 1=normal, 2=high
+# both $fromdir and $todir should be absolute paths
+sub cachedir {
+    my ($fromdir, $todir, $verbosity) = @_;
+    $verbosity = 1 unless defined $verbosity;
+
+    # use / for the directory separator, remove duplicate and
+    # trailing slashes
+    $fromdir=~s/[\\\/]+/\//g; 
+    $fromdir=~s/[\\\/]+$//;
+    $todir=~s/[\\\/]+/\//g; 
+    $todir=~s/[\\\/]+$//;
+
+    &mk_all_dir ($todir);
+
+    # get the directories in ascending order
+    if (!opendir (FROMDIR, $fromdir)) {
+	print STDERR "util::cachedir could not read directory $fromdir\n";
+	return;
+    }
+    my @fromdir = grep (!/^\.\.?$/, sort(readdir (FROMDIR)));
+    closedir (FROMDIR);
+
+    if (!opendir (TODIR, $todir)) {
+	print STDERR "util::cacedir could not read directory $todir\n";
+	return;
+    }
+    my @todir = grep (!/^\.\.?$/, sort(readdir (TODIR)));
+    closedir (TODIR);
+
+    my $fromi = 0;
+    my $toi = 0;
+		    
+    while ($fromi < scalar(@fromdir) || $toi < scalar(@todir)) {
+#	print "fromi: $fromi toi: $toi\n";
+
+	# see if we should delete a file/directory
+	# this should happen if the file/directory
+	# is not in the from list or if its a different
+	# size, or has an older timestamp
+	if ($toi < scalar(@todir)) {
+	    if (($fromi >= scalar(@fromdir)) ||
+		($todir[$toi] lt $fromdir[$fromi] || 
+		 ($todir[$toi] eq $fromdir[$fromi] && 
+		  &differentfiles("$fromdir/$fromdir[$fromi]","$todir/$todir[$toi]",
+				  $verbosity)))) {
+
+		# the files are different
+		&rm_r("$todir/$todir[$toi]");
+		splice(@todir, $toi, 1); # $toi stays the same
+
+	    } elsif ($todir[$toi] eq $fromdir[$fromi]) {
+		# the files are the same
+		# if it is a directory, check its contents
+		if (-d "$todir/$todir[$toi]") {
+		    &cachedir ("$fromdir/$fromdir[$fromi]",
+			       "$todir/$todir[$toi]", $verbosity);
+		}
+
+		$toi++;
+		$fromi++;
+		next;
+	    }
+	}
+  
+	# see if we should insert a file/directory
+	# we should insert a file/directory if there
+	# is no tofiles left or if the tofile does not exist
+	if ($fromi < scalar(@fromdir) && ($toi >= scalar(@todir) || 
+					  $todir[$toi] gt $fromdir[$fromi])) {
+	    &cp_r ("$fromdir/$fromdir[$fromi]", "$todir/$fromdir[$fromi]");
+	    splice (@todir, $toi, 0, $fromdir[$fromi]);
+
+	    $toi++;
+	    $fromi++;
+	}
+    }
+}
+
+# this function returns -1 if either file is not found
+# assumes that $file1 and $file2 are absolute file names or
+# in the current directory
+# $file2 is allowed to be newer than $file1
+sub differentfiles {
+    my ($file1, $file2, $verbosity) = @_;
+    $verbosity = 1 unless defined $verbosity;
+
+    $file1 =~ s/\/+$//;
+    $file2 =~ s/\/+$//;
+    
+    my ($file1name) = $file1 =~ /\/([^\/]*)$/;
+    my ($file2name) = $file2 =~ /\/([^\/]*)$/;
+
+    return -1 unless (-e $file1 && -e $file2);
+    if ($file1name ne $file2name) {
+	print STDERR "filenames are not the same\n" if ($verbosity >= 2);
+	return 1;
+    }
+
+    my @file1stat = stat ($file1);
+    my @file2stat = stat ($file2);
+
+    if (-d $file1) {
+	if (! -d $file2) {
+	    print STDERR "one file is a directory\n" if ($verbosity >= 2);
+	    return 1;
+	}
+	return 0;
+    }
+
+    # both must be regular files
+    unless (-f $file1 && -f $file2) {
+	print STDERR "one file is not a regular file\n" if ($verbosity >= 2);
+	return 1;
+    }
+
+    # the size of the files must be the same
+    if ($file1stat[7] != $file2stat[7]) {
+	print STDERR "different sized files\n" if ($verbosity >= 2);
+	return 1;
+    }
+
+    # the second file cannot be older than the first
+    if ($file1stat[9] > $file2stat[9]) {
+	print STDERR "file is older\n" if ($verbosity >= 2);
+	return 1;
+    }
+
+    return 0;
+}
+
+
+sub get_tmp_filename 
+{
+    my $file_ext = shift(@_) || undef;
+
+    my $opt_dot_file_ext = (defined $file_ext) ? ".$file_ext" : "";
+
+    my $tmpdir = filename_cat($ENV{'GSDLHOME'}, "tmp");
+    &mk_all_dir ($tmpdir) unless -e $tmpdir;
+
+    my $count = 1000;
+    my $rand = int(rand $count);
+    my $full_tmp_filename = &filename_cat($tmpdir, "F$rand$opt_dot_file_ext");
+
+    while (-e $full_tmp_filename) {
+	$rand = int(rand $count);
+	$full_tmp_filename = &filename_cat($tmpdir, "F$rand$opt_dot_file_ext");
+	$count++;
+    }
+    
+    return $full_tmp_filename;
+}
+
+sub filename_to_regex {
+    my $filename = shift (@_);
+
+    # need to put single backslash back to double so that regex works
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	$filename =~ s/\\/\\\\/g;
+    }
+    return $filename;
+}
+
+sub filename_cat {
+    my $first_file = shift(@_);
+    my (@filenames) = @_;
+
+#   Useful for debugging 
+#     -- might make sense to call caller(0) rather than (1)??
+#   my ($cpackage,$cfilename,$cline,$csubr,$chas_args,$cwantarray) = caller(1);
+#   print STDERR "Calling method; $cfilename:$cline $cpackage->$csubr\n";
+   
+    # If first_file is not null or empty, then add it back into the list
+    if (defined $first_file && $first_file =~ /\S/) {
+	unshift(@filenames, $first_file);
+    }
+
+    my $filename = join("/", @filenames);
+
+    # remove duplicate slashes and remove the last slash
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	$filename =~ s/[\\\/]+/\\/g;
+    } else {
+	$filename =~ s/[\/]+/\//g; 
+	# DB: want a filename abc\de.html to remain like this
+    }
+    $filename =~ s/[\\\/]$//;
+
+    return $filename;
+}
+
+sub tidy_up_oid {
+    my ($OID) = @_;
+    if ($OID =~ /\./) {
+	print STDERR "Warning, identifier $OID contains periods (.), removing them\n";
+	$OID =~ s/\.//g; #remove any periods
+    }
+    if ($OID =~ /^\s.*\s$/) {
+	print STDERR "Warning, identifier $OID starts or ends with whitespace. Removing it\n";
+	# remove starting and trailing whitespace
+	$OID =~ s/^\s+//;
+	$OID =~ s/\s+$//;
+    }
+    if ($OID =~ /^[\d]*$/) {
+	print STDERR "Warning, identifier $OID contains only digits. Prepending 'D'.\n";
+	$OID = "D" . $OID;
+    }		
+    
+    return $OID;
+}
+sub envvar_prepend {
+    my ($var,$val) = @_;
+
+    # do not prepend any value/path that's already in the environment variable
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) 
+    {
+	my $escaped_val = $val;
+	$escaped_val =~ s/\\/\\\\/g; # escape any Windows backslashes for upcoming regex
+	if($ENV{$var} !~ m/$escaped_val/) { 
+	    $ENV{$var} = "$val;".$ENV{$var};
+	}
+    }
+    else {
+	if($ENV{$var} !~ m/$val/) { 
+	    $ENV{$var} = "$val:".$ENV{$var};
+	}
+    }
+}
+
+sub envvar_append {
+    my ($var,$val) = @_;
+
+    # do not append any value/path that's already in the environment variable
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) 
+    {
+	my $escaped_val = $val;
+	$escaped_val =~ s/\\/\\\\/g; # escape any Windows backslashes for upcoming regex
+	if($ENV{$var} !~ m/$escaped_val/) { 
+	    $ENV{$var} .= ";$val";
+	}
+    }
+    else {
+	if($ENV{$var} !~ m/$val/) { 
+	    $ENV{$var} .= ":$val";
+	}
+    }    
+}
+
+
+# splits a filename into a prefix and a tail extension using the tail_re, or 
+# if that fails, splits on the file_extension . (dot) 
+sub get_prefix_and_tail_by_regex {
+
+    my ($filename,$tail_re) = @_;
+    
+    my ($file_prefix,$file_ext) = ($filename =~ m/^(.*?)($tail_re)$/);
+    if ((!defined $file_prefix) || (!defined $file_ext)) {
+	($file_prefix,$file_ext) = ($filename =~ m/^(.*)(\..*?)$/);
+    }
+
+    return ($file_prefix,$file_ext);
+}
+
+# get full path and file only path from a base_dir (which may be empty) and 
+# file (which may contain directories)
+sub get_full_filenames {
+    my ($base_dir, $file) = @_;
+    
+    my $filename_full_path = $file;
+    # add on directory if present
+    $filename_full_path = &util::filename_cat ($base_dir, $file) if $base_dir =~ /\S/;
+    
+    my $filename_no_path = $file;
+
+    # remove directory if present
+    $filename_no_path =~ s/^.*[\/\\]//;
+    return ($filename_full_path, $filename_no_path);
+}
+
+# returns the path of a file without the filename -- ie. the directory the file is in
+sub filename_head {
+    my $filename = shift(@_);
+
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	$filename =~ s/[^\\\\]*$//;
+    }
+    else {
+	$filename =~ s/[^\\\/]*$//;
+    }
+
+    return $filename;
+}
+
+
+# returns 1 if filename1 and filename2 point to the same
+# file or directory
+sub filenames_equal {
+    my ($filename1, $filename2) = @_;
+
+    # use filename_cat to clean up trailing slashes and 
+    # multiple slashes
+    $filename1 = filename_cat ($filename1);
+    $filename2 = filename_cat ($filename2);
+
+    # filenames not case sensitive on windows
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	$filename1 =~ tr/[A-Z]/[a-z]/;
+	$filename2 =~ tr/[A-Z]/[a-z]/;
+    }
+    return 1 if $filename1 eq $filename2;
+    return 0;
+}
+
+sub filename_within_collection
+{
+    my ($filename) = @_;
+
+    my $collect_dir = $ENV{'GSDLCOLLECTDIR'};
+    
+    if (defined $collect_dir) {
+	my $dirsep = &util::get_dirsep();
+	if ($collect_dir !~ m/$dirsep$/) {
+	    $collect_dir .= $dirsep;
+	}
+	
+	$collect_dir =~ s/\\/\\\\/g; # escape DOS style file separator
+	
+	# if from within GSDLCOLLECTDIR, then remove directory prefix
+	# so source_filename is realative to it.  This is done to aid
+	# portability, i.e. the collection can be moved to somewhere
+	# else on the file system and the archives directory will still
+	# work.  This is needed, for example in the applet version of
+	# GLI where GSDLHOME/collect on the server will be different to
+	# the collect directory of the remove user.  Of course,
+	# GSDLCOLLECTDIR subsequently needs to be put back on to turn
+	# it back into a full pathname.
+	
+	if ($filename =~ /^$collect_dir(.*)$/) {
+	    $filename = $1;
+	}
+    }
+    
+    return $filename;
+}
+
+sub filename_is_absolute
+{
+    my ($filename) = @_;
+
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	return ($filename =~ m/^(\w:)?\\/);
+    }
+    else {
+	return ($filename =~ m/^\//);
+    }
+}
+
+
+## @method make_absolute()
+#
+#  Ensure the given file path is absolute in respect to the given base path.
+#
+#  @param  $base_dir A string denoting the base path the given dir must be
+#                    absolute to.
+#  @param  $dir The directory to be made absolute as a string. Note that the
+#               dir may already be absolute, in which case it will remain
+#               unchanged.
+#  @return The now absolute form of the directory as a string.
+#
+#  @author John Thompson, DL Consulting Ltd.
+#  @copy 2006 DL Consulting Ltd.
+#
+#used in buildcol.pl, doesn't work for all cases --kjdon
+sub make_absolute {
+    
+    my ($base_dir, $dir) = @_;
+###    print STDERR "dir = $dir\n";
+    $dir =~ s/[\\\/]+/\//g;
+    $dir = $base_dir . "/$dir" unless ($dir =~ m|^(\w:)?/|); 
+    $dir =~ s|^/tmp_mnt||;
+    1 while($dir =~ s|/[^/]*/\.\./|/|g);
+    $dir =~ s|/[.][.]?/|/|g;
+    $dir =~ tr|/|/|s;
+###    print STDERR "dir = $dir\n";
+    
+    return $dir;
+}
+## make_absolute() ##
+
+sub get_dirsep {
+
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	return "\\";
+    } else {
+	return "\/";
+    }
+}
+
+sub get_os_dirsep {
+
+    if ($ENV{'GSDLOS'} =~ /^windows$/i) {
+	return "\\\\";
+    } else {
+	return "\\\/";
+    }
+}
+
+sub get_re_dirsep {
+
+    return "\\\\|\\\/";
+}
+
+
+sub get_dirsep_tail {
+    my ($filename) = @_;
+    
+    # returns last part of directory or filename
+    # On unix e.g. a/b.d => b.d
+    #              a/b/c => c
+
+    my $dirsep = get_re_dirsep();
+    my @dirs = split (/$dirsep/, $filename);
+    my $tail = pop @dirs;
+
+    # - caused problems under windows
+    #my ($tail) = ($filename =~ m/^(?:.*?$dirsep)?(.*?)$/); 
+
+    return $tail;
+}
+
+
+# if this is running on windows we want binaries to end in
+# .exe, otherwise they don't have to end in any extension
+sub get_os_exe {
+    return ".exe" if $ENV{'GSDLOS'} =~ /^windows$/i;
+    return "";
+}
+
+
+# test to see whether this is a big or little endian machine
+sub is_little_endian
+{
+    # To determine the name of the operating system, the variable $^O is a cheap alternative to pulling it out of the Config module;
+    # If it is a Macintosh machine (i.e. the Darwin operating system), regardless if it's running on the IBM power-pc cpu or the x86 Intel-based chip with a power-pc emulator running on top of it, it's big-endian
+    # Otherwise, it's little endian
+
+    #return 0 if $^O =~ /^darwin$/i;
+    #return 0 if $ENV{'GSDLOS'} =~ /^darwin$/i;
+    
+    # Going back to stating exactly whether the machine is little endian
+    # or big endian, without any special case for Macs. Since for rata it comes
+    # back with little endian and for shuttle with bigendian.
+    return (ord(substr(pack("s",1), 0, 1)) == 1);
+}
+
+
+# will return the collection name if successful, "" otherwise
+sub use_collection {
+    my ($collection, $collectdir) = @_;
+
+    if (!defined $collectdir || $collectdir eq "") {
+	$collectdir = &filename_cat ($ENV{'GSDLHOME'}, "collect");
+    }
+
+    # get and check the collection
+    if (!defined($collection) || $collection eq "") {
+	if (defined $ENV{'GSDLCOLLECTION'}) {
+	    $collection = $ENV{'GSDLCOLLECTION'};
+	} else {
+	    print STDOUT "No collection specified\n";
+	    return "";
+	}
+    }
+    
+    if ($collection eq "modelcol") {
+	print STDOUT "You can't use modelcol.\n";
+	return "";
+    }
+
+    # make sure the environment variables GSDLCOLLECTION and GSDLCOLLECTDIR
+    # are defined
+    $ENV{'GSDLCOLLECTION'} = $collection;
+    $ENV{'GSDLCOLLECTDIR'} = &filename_cat ($collectdir, $collection);
+
+    # make sure this collection exists
+    if (!-e $ENV{'GSDLCOLLECTDIR'}) {
+	print STDOUT "Invalid collection ($collection).\n";
+	return "";
+    }
+
+    # everything is ready to go
+    return $collection;
+}
+
+
+
+
+# will return the collection name if successful, "" otherwise.  
+# Like use_collection (above) but for greenstone 3 (taking account of site level)
+
+sub use_site_collection {
+    my ($site, $collection, $collectdir) = @_;
+
+    if (!defined $collectdir || $collectdir eq "") {
+	die "GSDL3HOME not set.\n" unless defined $ENV{'GSDL3HOME'};
+	$collectdir = &filename_cat ($ENV{'GSDL3HOME'}, "sites", $site, "collect");
+    }
+
+    # collectdir explicitly set by this point (using $site variable if required).
+    # Can call "old" gsdl2 use_collection now.
+
+    return use_collection($collection,$collectdir);
+}
+
+
+
+sub locate_config_file
+{
+    my ($file) = @_;
+
+    my $locations = locate_config_files($file);
+
+    return shift @$locations; # returns undef if 'locations' is empty
+}
+
+
+sub locate_config_files
+{
+    my ($file) = @_;
+
+    my @locations = ();
+
+    if (-e $file) {
+	# Clearly specified (most likely full filename)
+	# No need to hunt in 'etc' directories, return value unchanged
+	push(@locations,$file);
+    }
+    else {
+	# Check for collection specific one before looking in global GSDL 'etc'
+	if (defined $ENV{'GSDLCOLLECTDIR'} && $ENV{'GSDLCOLLECTDIR'} ne "") {
+	    my $test_collect_etc_filename 
+		= &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"etc", $file);
+	    
+	    if (-e $test_collect_etc_filename) {
+		push(@locations,$test_collect_etc_filename);
+	    }
+	}
+	my $test_main_etc_filename 
+	    = &util::filename_cat($ENV{'GSDLHOME'},"etc", $file);
+	if (-e $test_main_etc_filename) {
+	    push(@locations,$test_main_etc_filename);
+	}
+    }
+
+    return \@locations;
+}
+
+
+sub hyperlink_text
+{
+    my ($text) = @_;
+    
+    $text =~ s/(http:\/\/[^\s]+)/<a href=\"$1\">$1<\/a>/mg;
+    $text =~ s/(^|\s+)(www\.(\w|\.)+)/<a href=\"http:\/\/$2\">$2<\/a>/mg;
+
+    return $text;
+}
+
+
+# A method to check if a directory is empty (note that an empty directory still has non-zero size!!!) 
+# Code is from http://episteme.arstechnica.com/eve/forums/a/tpc/f/6330927813/m/436007700831
+sub is_dir_empty
+{
+    my ($path) = @_;
+    opendir DIR, $path;
+    while(my $entry = readdir DIR) {
+        next if($entry =~ /^\.\.?$/);
+        closedir DIR;
+        return 0;
+    }
+    closedir DIR;
+    return 1;
+}
+
+# Returns the given filename converted using either URL encoding or base64
+# encoding, as specified by $rename_method. If the given filename has no suffix
+# (if it is just the tailname), then $no_suffix should be some defined value. 
+sub rename_file {
+    my ($filename, $rename_method, $no_suffix)  = @_;
+
+    if(!$filename) { # undefined or empty string
+	return $filename;
+    }
+
+    # No longer replace spaces with underscores, since underscores mess with incremental rebuild
+    ### Replace spaces with underscore. Do this first else it can go wrong below when getting tailname
+    ###$filename =~ s/ /_/g;
+
+    my ($tailname,$dirname,$suffix); 
+    if($no_suffix) { # given a tailname, no suffix
+	($tailname,$dirname) = File::Basename::fileparse($filename);
+    } 
+    else {
+	($tailname,$dirname,$suffix) = File::Basename::fileparse($filename, "\\.(?:[^\\.]+?)\$");
+    }
+    $suffix = "" if !$suffix;
+
+    if (!$rename_method) {
+	print STDERR "WARNING: no file renaming method specified. Defaulting to using URL encoding...\n";
+	# Debugging information
+	my ($cpackage,$cfilename,$cline,$csubr,$chas_args,$cwantarray) = caller(1);
+	print STDERR "Calling method: $cfilename:$cline $cpackage->$csubr\n";
+    } elsif($rename_method eq "none") {
+	return $filename; # would have already been renamed
+    }
+
+    if (!$rename_method || $rename_method eq "url") {
+	$tailname = &unicode::url_encode($tailname);
+    }
+    elsif ($rename_method eq "base64") {
+	$tailname = &unicode::base64_encode($tailname);
+	$tailname =~ s/\s*//sg;      # for some reason it adds spaces not just at end but also in middle
+    }
+
+    $filename = "$tailname$suffix";
+    $filename = "$dirname$filename" if ($dirname ne "./" && $dirname ne ".\\");
+
+    return $filename;
+}
+
+# makes sure that the file has a gdb extension
+sub rename_gdbm_file {
+    my ($filename_no_ext) = @_;
+
+    my $new_filename = "$filename_no_ext.gdb";
+    return if (-f $new_filename); # if gdb file exists, don't need to do anything
+    # try ldb
+    my $old_filename = "$filename_no_ext.ldb";
+    
+    if (-f $old_filename) {
+	print STDERR "Renaming $old_filename to $new_filename\n";
+	rename ($old_filename, $new_filename)
+	    || print STDERR "Rename failed: $!\n";
+	return;
+    }
+    # try bdb
+    $old_filename = "$filename_no_ext.bdb";
+    if (-f $old_filename) {
+	print STDERR "Renaming $old_filename to $new_filename\n";	
+	rename ($old_filename, $new_filename)
+	    || print STDERR "Rename failed: $!\n";
+	return;
+    }
+}
+
+
+
+1;
Index: /gsdl/stable/perllib/webpageutil.pm
===================================================================
--- /gsdl/stable/perllib/webpageutil.pm	(revision 20131)
+++ /gsdl/stable/perllib/webpageutil.pm	(revision 20131)
@@ -0,0 +1,25 @@
+package webpageutil;
+
+use ghtml;
+use strict;
+
+sub error_location
+{
+    my ($args,$text) = @_;
+
+    &ghtml::urlsafe($text);
+    my $mess_url = "$args->{'httpbuild'}&bca=mess&head=_headerror_";
+    print "Location: $mess_url&mess=$text\n\n";
+}
+
+sub status_location
+{
+    my ($args,$text,$tmpname,$bc1finished) = @_;
+
+    &ghtml::urlsafe($text);    
+    my $mess_url = "$args->{'httpbuild'}&bca=buildstatus";
+    $mess_url .= "&bc1tmpfilename=$tmpname&bc1finished=$bc1finished";
+    print "Location: $mess_url&mess=$text\n\n";
+}
+
+1;
Index: /gsdl/stable/runtime-src/Makefile.in
===================================================================
--- /gsdl/stable/runtime-src/Makefile.in	(revision 20131)
+++ /gsdl/stable/runtime-src/Makefile.in	(revision 20131)
@@ -0,0 +1,105 @@
+###########################################################################
+#
+# Makefile -- gsdl runtime code
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+srcdir = @srcdir@
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+@SET_MAKE@
+CC = @CC@
+CXX = @CXX@
+CFLAGS = @CFLAGS@
+CXXFLAGS = @CXXFLAGS@
+LIBS   = @LIBS@
+MDEFINES =
+
+GSDLOS = @gsdlos@
+
+COMPILE = $(CC) -c
+
+SOURCES = 
+
+OBJECTS = 
+
+ALLFILES = $(OBJECTS)
+
+
+# all directories should be compiled
+COMPILEDIRS = packages src/colservr src/protocol src/z3950 src/recpt src/corba src/oaiservr
+
+# a subset of the directories get installed
+INSTALLDIRS = packages src/z3950 src/recpt src/corba src/oaiservr
+
+MODULEDIRS = @MODULEDIRS@
+
+
+all:
+	for odir in $(COMPILEDIRS) $(MODULEDIRS); do \
+	  echo making $@ in $$odir; \
+	  (cd $$odir && $(MAKE) $(MDEFINES) $@) || exit 1; \
+	done
+
+install: all
+	for idir in $(INSTALLDIRS); do \
+	  echo installing $$idir; \
+	  (cd $$idir && $(MAKE) install) || exit 1; \
+	done
+
+distclean: clean
+	rm -f Makefile config.cache config.h config.log stamp-h config.status
+	for subdir in $(COMPILEDIRS); do \
+	  echo cleaning $@ in $$subdir; \
+	  (cd $$subdir && $(MAKE) distclean) || exit 1; \
+	done
+
+clean:
+	for subdir in $(COMPILEDIRS); do \
+	  echo cleaning $@ in $$subdir; \
+	  (cd $$subdir && $(MAKE) clean) || exit 1; \
+	done
+
+# commented out - jrm21 Dec 2004 - can get confused by cvs timestamps
+# (and might run the wrong version of autoconf)
+#
+## For an explanation of the following Makefile rules, see node
+## `Automatic Remaking' in GNU Autoconf documentation.
+#Makefile: Makefile.in config.status
+#	CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+#config.status: configure
+#	./config.status --recheck
+#configure: configure.in aclocal.m4
+#	cd $(srcdir) && autoconf
+#
+#config.h: stamp-h
+#stamp-h: config.h.in config.status
+#	CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status
+#config.h.in: stamp-h.in
+#stamp-h.in: configure.in aclocal.m4 acconfig.h
+#	cd $(srcdir) && autoheader
+#	$(TOUCH) $(srcdir)/stamp-h.in
+
+
+
Index: /gsdl/stable/runtime-src/aclocal.m4
===================================================================
--- /gsdl/stable/runtime-src/aclocal.m4	(revision 20131)
+++ /gsdl/stable/runtime-src/aclocal.m4	(revision 20131)
@@ -0,0 +1,140 @@
+# Local additions to Autoconf macros.
+# Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+# François Pinard <pinard@iro.umontreal.ca>, 1992.
+
+# [TS:Aug/95] - chopped out the NLS stuff which I don't support
+
+## ------------------------------- ##
+## Check for function prototypes.  ##
+## ------------------------------- ##
+
+AC_DEFUN(fp_C_PROTOTYPES,
+[AC_REQUIRE([fp_PROG_CC_STDC])
+AC_MSG_CHECKING([for function prototypes])
+if test "$ac_cv_prog_cc_stdc" != no; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(PROTOTYPES)
+  U= ANSI2KNR=
+else
+  AC_MSG_RESULT(no)
+  U=_ ANSI2KNR=ansi2knr
+fi
+AC_SUBST(U)dnl
+AC_SUBST(ANSI2KNR)dnl
+])
+
+## ----------------------------------------- ##
+## ANSIfy the C compiler whenever possible.  ##
+## ----------------------------------------- ##
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so.  This macro tries various
+# options that select ANSI C on some system or another.  It considers the
+# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and
+# handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{ac_cv_prog_cc_stdc} is set to @samp{no}.  If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN(fp_PROG_CC_STDC,
+[AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
+AC_CACHE_VAL(ac_cv_prog_cc_stdc,
+[ac_cv_prog_cc_stdc=no
+ac_save_CFLAGS="$CFLAGS"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX			-Aa -D_HPUX_SOURCE
+# SVR4			-Xc
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" -Xc
+do
+  CFLAGS="$ac_save_CFLAGS $ac_arg"
+  AC_TRY_COMPILE(
+[#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif	
+], [int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};],
+[ac_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CFLAGS="$ac_save_CFLAGS"
+])
+AC_MSG_RESULT($ac_cv_prog_cc_stdc)
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno) ;;
+  *) CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+])
+
+## --------------------------------------------------------- ##
+## Use AC_PROG_INSTALL, supplementing it with INSTALL_SCRIPT ##
+## substitution.					     ##
+## --------------------------------------------------------- ##
+
+AC_DEFUN(fp_PROG_INSTALL,
+[AC_PROG_INSTALL
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL} -m 755'
+AC_SUBST(INSTALL_SCRIPT)dnl
+])
+
+## ----------------------------------- ##
+## Check if --with-dmalloc was given.  ##
+## ----------------------------------- ##
+
+# I just checked, and GNU rx seems to work fine with a slightly
+# modified GNU m4.  So, I put out the test below in my aclocal.m4,
+# and will try to use it in my things.  The idea is to distribute
+# rx.[hc] and regex.[hc] together, for a while.  The WITH_REGEX symbol
+# (which should also be documented in acconfig.h) is used to decide
+# which of regex.h or rx.h should be included in the application.
+#
+# If `./configure --with-regex' is given, the package will use
+# the older regex.  Else, a check is made to see if rx is already
+# installed, as with newer Linux'es.  If not found, the package will
+# use the rx from the distribution.  If found, the package will use
+# the system's rx which, on Linux at least, will result in a smaller
+# executable file.
+
+AC_DEFUN(fp_WITH_DMALLOC,
+[AC_MSG_CHECKING(if malloc debugging is wanted)
+AC_ARG_WITH(dmalloc,
+[  --with-dmalloc          use dmalloc, as in
+                          ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz],
+[if test "$withval" = yes; then
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(WITH_DMALLOC)
+  LIBS="$LIBS -ldmalloc"
+  LDFLAGS="$LDFLAGS -g"
+else
+  AC_MSG_RESULT(no)
+fi], [AC_MSG_RESULT(no)])
+])
+
+## --------------------------------- ##
+## Check if --with-regex was given.  ##
+## --------------------------------- ##
+
+AC_DEFUN(fp_WITH_REGEX,
+[AC_MSG_CHECKING(which of rx or regex is wanted)
+AC_ARG_WITH(regex,
+[  --with-regex            use older regex in lieu of GNU rx for matching],
+[if test "$withval" = yes; then
+  ac_with_regex=1
+  AC_MSG_RESULT(regex)
+  AC_DEFINE(WITH_REGEX)
+  AC_LIBOBJ([regex])
+fi])
+if test -z "$ac_with_regex"; then
+  AC_MSG_RESULT(rx)
+  AC_CHECK_FUNC(re_rx_search, , [AC_LIBOBJ([rx])])
+fi
+])
Index: /gsdl/stable/runtime-src/config.h.in
===================================================================
--- /gsdl/stable/runtime-src/config.h.in	(revision 20131)
+++ /gsdl/stable/runtime-src/config.h.in	(revision 20131)
@@ -0,0 +1,217 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+#ifndef _GSDL_CONFIG_H
+#define _GSDL_CONFIG_H
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+#undef _ALL_SOURCE
+#endif
+
+/* Define if using alloca.c.  */
+#undef C_ALLOCA
+
+/* Define if big endian */
+#undef WORDS_BIGENDIAN
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro.  */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+#undef HAVE_ALLOCA_H
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+#undef HAVE_DOPRNT
+
+/* Define if you have the vprintf function.  */
+#undef HAVE_VPRINTF
+
+/* Define if on MINIX.  */
+#undef _MINIX
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+#undef off_t
+
+/* Define if the system does not provide POSIX.1 features except
+   with this defined.  */
+#undef _POSIX_1_SOURCE
+
+/* Define if you need to in order for stat and other things to work.  */
+#undef _POSIX_SOURCE
+
+/* Define as the return type of signal handlers (int or void).  */
+#undef RETSIGTYPE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm.  */
+#undef TM_IN_SYS_TIME
+
+/* Define to the name of the distribution.  */
+#undef PACKAGE
+
+/* Define to the version of the distribution.  */
+#undef VERSION
+
+/* Define to 1 if you have the valloc function.  */
+#undef HAVE_VALLOC
+
+/* Define to 1 if ANSI function prototypes are usable.  */
+#undef PROTOTYPES
+
+/* Define if you don't want to use long long's with GCC */
+#undef DISABLE_LONG_LONG
+ 
+/* Define to 1 for better use of the debugging malloc library.  See
+   site ftp.antaire.com in antaire/src, file dmalloc/dmalloc.tar.gz.  */
+#undef WITH_DMALLOC
+
+ 
+/* Define to 1 if GNU regex should be used instead of GNU rx.  */
+#undef WITH_REGEX
+
+/* Some braindead header files do not have the requ'd function declarations */
+#undef HAVE_FGETC_DECL
+#undef HAVE_FREAD_DECL
+
+/* See if have this field in the prstatus_t structure */
+/* It stores the size of the process heap */
+#undef HAVE_PR_BRKSIZE
+
+/* Define FASTCGI if needsbe */
+#undef USE_FASTCGI
+
+/* Define USE_CORBA if needsbe */
+#undef USE_CORBA
+
+/* Define MICO_DIR if needsbe */
+#undef MICO_DIR
+
+/* Define MICO_VERSION if required */
+#undef MICO_VERSION
+
+/* Define if you have the ftime function.  */
+#undef HAVE_FTIME
+
+/* Define if you have the ftruncate function.  */
+#undef HAVE_FTRUNCATE
+
+/* Define if you have the getpagesize function.  */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the getrusage function.  */
+#undef HAVE_GETRUSAGE
+
+/* Define if you have the mallinfo function.  */
+#undef HAVE_MALLINFO
+
+/* Define if you have the select function.  */
+#undef HAVE_SELECT
+
+/* Define if you have the setbuffer function.  */
+#undef HAVE_SETBUFFER
+
+/* Define if you have the strcasecmp function.  */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strerror function.  */
+#undef HAVE_STRERROR
+
+/* Define if you have the strftime function.  */
+#undef HAVE_STRFTIME
+
+/* Define if you have the strstr function.  */
+#undef HAVE_STRSTR
+
+/* Define if you have the strtol function.  */
+#undef HAVE_STRTOL
+
+/* Define if you have the times function.  */
+#undef HAVE_TIMES
+
+/* Define if you have the valloc function.  */
+#undef HAVE_VALLOC
+
+/* Define if you have the <crypt.h> header file.  */
+#undef HAVE_CRYPT_H
+
+/* Define if you have the <dirent.h> header file.  */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <fcntl.h> header file.  */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <limits.h> header file.  */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <memory.h> header file.  */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <ndir.h> header file.  */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <string.h> header file.  */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/dir.h> header file.  */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/ndir.h> header file.  */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/procfs.h> header file.  */
+#undef HAVE_SYS_PROCFS_H
+
+/* Define if you have the <sys/time.h> header file.  */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <unistd.h> header file.  */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the crypt library (-lcrypt).  */
+#undef HAVE_LIBCRYPT
+
+/* Define if you have the g library (-lg).  */
+#undef HAVE_LIBG
+
+/* Define if you have the gdbm library (-lgdbm).  */
+#undef HAVE_LIBGDBM
+
+/* Define if you have the m library (-lm).  */
+#undef HAVE_LIBM
+
+/* Define if you have the stdc++ library (-lstdc++).  */
+#undef HAVE_LIBSTDC__
+
+/* Define if you have gettext (eg glibc) */
+#undef ENABLE_NLS
+
+/* Define if big endian */
+#undef WORDS_BIGENDIAN
+
+#endif /* _GSDL_CONFIG_H */
Index: /gsdl/stable/runtime-src/configure
===================================================================
--- /gsdl/stable/runtime-src/configure	(revision 20131)
+++ /gsdl/stable/runtime-src/configure	(revision 20131)
@@ -0,0 +1,8626 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subdirs_all="$ac_subdirs_all packages"
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS PACKAGE VERSION USE_FASTCGI USE_LANGACTION USE_CORBA MICO_DIR USE_Z3950 USE_YAZ ENABLE_ACCENTFOLD USE_SQLITE USE_APACHE_HTTPD LDFLAGS CFLAGS CC CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX AWK YACC build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB COMPAT32BITFLAGS MICO_VER CPP EGREP U ANSI2KNR ALLOCA LIBOBJS STATIC gsdlos MODULEDIRS subdirs LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CXX_set=${CXX+set}
+ac_env_CXX_value=$CXX
+ac_cv_env_CXX_set=${CXX+set}
+ac_cv_env_CXX_value=$CXX
+ac_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_env_CXXFLAGS_value=$CXXFLAGS
+ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_cv_env_CXXFLAGS_value=$CXXFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-corba          Enable CORBA support
+  --enable-z3950          Enable Z39.50 client support
+  --disable-yaz           Disable YAZ compilation
+  --disable-accentfold    Disable Accent Folding for MGPP
+  --disable-sqlite        Disable SQLite support
+  --enable-apache-httpd   Enable Apache httpd support
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-micodir          Use installed MICO directory
+  --with-dmalloc          use dmalloc, as in
+                          ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz
+  --with-regex            use older regex in lieu of GNU rx for matching
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers config.h"
+
+
+
+
+PACKAGE=gsdl
+VERSION=2.82-svn
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+
+
+
+USE_FASTCGI=0
+if test USE_FASTCGI = 1; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_FASTCGI 1
+_ACEOF
+
+
+fi
+
+if test USE_LANGACTION = 1; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_LANGACTION 1
+_ACEOF
+
+
+fi
+
+# Check whether --enable-corba or --disable-corba was given.
+if test "${enable_corba+set}" = set; then
+  enableval="$enable_corba"
+  USE_CORBA=1
+else
+  USE_CORBA=0
+fi;
+cat >>confdefs.h <<_ACEOF
+#define USE_CORBA $USE_CORBA
+_ACEOF
+
+
+
+
+# Check whether --with-micodir or --without-micodir was given.
+if test "${with_micodir+set}" = set; then
+  withval="$with_micodir"
+  MICO_DIR=$enableval
+else
+  MICO_DIR="default"
+fi;
+cat >>confdefs.h <<_ACEOF
+#define MICO_DIR "$MICO_DIR"
+_ACEOF
+
+
+
+# Check whether --enable-z3950 or --disable-z3950 was given.
+if test "${enable_z3950+set}" = set; then
+  enableval="$enable_z3950"
+  USE_Z3950=1
+else
+  USE_Z3950=0
+fi;
+if test USE_Z3950 = 1; then
+cat >>confdefs.h <<\_ACEOF
+#define USE_Z3950 $USE_Z3950
+_ACEOF
+
+
+fi
+
+# Check whether --enable-yaz or --disable-yaz was given.
+if test "${enable_yaz+set}" = set; then
+  enableval="$enable_yaz"
+  USE_YAZ=0
+else
+  USE_YAZ=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define USE_YAZ $USE_YAZ
+_ACEOF
+
+
+
+# Check whether --enable-accentfold or --disable-accentfold was given.
+if test "${enable_accentfold+set}" = set; then
+  enableval="$enable_accentfold"
+  ENABLE_ACCENTFOLD=0
+else
+  ENABLE_ACCENTFOLD=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define ENABLE_ACCENTFOLD $ENABLE_ACCENTFOLD
+_ACEOF
+
+
+
+# Check whether --enable-sqlite or --disable-sqlite was given.
+if test "${enable_sqlite+set}" = set; then
+  enableval="$enable_sqlite"
+  USE_SQLITE=0
+else
+  USE_SQLITE=1
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define USE_SQLITE $USE_SQLITE
+_ACEOF
+
+
+
+# Check whether --enable-apache-httpd or --disable-apache-httpd was given.
+if test "${enable_apache_httpd+set}" = set; then
+  enableval="$enable_apache_httpd"
+  USE_APACHE_HTTPD=1
+else
+  USE_APACHE_HTTPD=0
+fi;
+cat >>confdefs.h <<\_ACEOF
+#define USE_APACHE_HTTPD $USE_APACHE_HTTPD
+_ACEOF
+
+
+
+
+LDFLAGS=$LDFLAGS
+
+if test -z "$CFLAGS"; then
+CFLAGS=-O2
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+	;;
+    conftest.$ac_ext )
+	# This is the source file.
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
+    * )
+	break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  export ac_cv_exeext
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX 10.20 and later	-Ae
+# HP-UX older versions	-Aa -D_HPUX_SOURCE
+# SVR4			-Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CXX" && break
+done
+test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
+
+  CXX=$ac_ct_CXX
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cxx_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+for ac_prog in 'bison -y' byacc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_YACC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_YACC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+  echo "$as_me:$LINENO: result: $YACC" >&5
+echo "${ECHO_T}$YACC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6
+if test "${ac_cv_target+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_target_alias=$target_alias
+test "x$ac_cv_target_alias" = "x" &&
+  ac_cv_target_alias=$ac_cv_host_alias
+ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6
+target=$ac_cv_target
+target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+	@echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+echo "$as_me:$LINENO: checking to see if architecture is 64-bit" >&5
+echo $ECHO_N "checking to see if architecture is 64-bit... $ECHO_C" >&6
+arch_64bit=no
+case "$host_cpu" in
+x86_64) arch_64bit=yes ;;
+esac
+
+if test "$arch_64bit" = yes; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS="-m32"
+  fi
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS=
+  fi
+fi
+export COMPAT32BITFLAGS
+
+
+
+#moved CORBA MICO directory test to get version of MICO
+if test $USE_CORBA = 1; then
+
+if test $MICO_DIR = "default"; then
+#do something
+MICO_INC="-I packages/mico/mico/include"
+else
+#build the micotest program
+MICO_INC= ""
+if test $MICO_DIR != yes; then
+MICO_INC="-I $MICO_DIR"
+fi
+fi
+
+#get MICO_VER value
+sh -c "$CC -c micotest.cpp -o micotest.o $MICO_INC 2>&1" > /dev/null
+sh -c "$CC -o micotest micotest.o -lstdc++ 2>&1" > /dev/null
+MICO_VER=`./micotest` || MICO_VER=2.3.5
+sh -c "rm micotest"
+sh -c "rm micotest.o"
+
+#do test of MICO_VER
+if test MICO_VER != 0; then
+cat >>confdefs.h <<\_ACEOF
+#define MICO_VER 1
+_ACEOF
+
+
+fi
+#end USE_CORBA test
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+
+echo "$as_me:$LINENO: checking for AIX" >&5
+echo $ECHO_N "checking for AIX... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef _AIX
+  yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+cat >>confdefs.h <<\_ACEOF
+#define _ALL_SOURCE 1
+_ACEOF
+
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest*
+
+
+echo "$as_me:$LINENO: checking for library containing strerror" >&5
+echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6
+if test "${ac_cv_search_strerror+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_strerror=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char strerror ();
+int
+main ()
+{
+strerror ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_strerror="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_strerror" = no; then
+  for ac_lib in cposix; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char strerror ();
+int
+main ()
+{
+strerror ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_strerror="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5
+echo "${ECHO_T}$ac_cv_search_strerror" >&6
+if test "$ac_cv_search_strerror" != no; then
+  test "$ac_cv_search_strerror" = "none required" || LIBS="$ac_cv_search_strerror $LIBS"
+
+fi
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for minix/config.h" >&5
+echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
+echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking minix/config.h usability" >&5
+echo $ECHO_N "checking minix/config.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <minix/config.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking minix/config.h presence" >&5
+echo $ECHO_N "checking minix/config.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <minix/config.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: minix/config.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: minix/config.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for minix/config.h" >&5
+echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_minix_config_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
+echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6
+
+fi
+if test $ac_cv_header_minix_config_h = yes; then
+  MINIX=yes
+else
+  MINIX=
+fi
+
+
+if test "$MINIX" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_SOURCE 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_1_SOURCE 2
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _MINIX 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for ${CC-cc} option to accept ANSI C" >&5
+echo $ECHO_N "checking for ${CC-cc} option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CFLAGS="$CFLAGS"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX			-Aa -D_HPUX_SOURCE
+# SVR4			-Xc
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" -Xc
+do
+  CFLAGS="$ac_save_CFLAGS $ac_arg"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif
+
+int
+main ()
+{
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc="$ac_arg"; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+CFLAGS="$ac_save_CFLAGS"
+
+fi
+
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno) ;;
+  *) CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+
+echo "$as_me:$LINENO: checking for function prototypes" >&5
+echo $ECHO_N "checking for function prototypes... $ECHO_C" >&6
+if test "$ac_cv_prog_cc_stdc" != no; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  cat >>confdefs.h <<\_ACEOF
+#define PROTOTYPES 1
+_ACEOF
+
+  U= ANSI2KNR=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  U=_ ANSI2KNR=ansi2knr
+fi
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for off_t" >&5
+echo $ECHO_N "checking for off_t... $ECHO_C" >&6
+if test "${ac_cv_type_off_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((off_t *) 0)
+  return 0;
+if (sizeof (off_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_off_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_off_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
+if test $ac_cv_type_off_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((size_t *) 0)
+  return 0;
+if (sizeof (size_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_size_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_size_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+if test $ac_cv_type_size_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+if test "${ac_cv_header_time+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_time=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_time=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6
+if test $ac_cv_header_time = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TIME_WITH_SYS_TIME 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5
+echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6
+if test "${ac_cv_struct_tm+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <time.h>
+
+int
+main ()
+{
+struct tm *tp; tp->tm_sec;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_struct_tm=time.h
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5
+echo "${ECHO_T}$ac_cv_struct_tm" >&6
+if test $ac_cv_struct_tm = sys/time.h; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TM_IN_SYS_TIME 1
+_ACEOF
+
+fi
+
+
+if test "$ac_cv_prog_cc_stdc" = '-Xc'; then
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+int
+main ()
+{
+ FILE *rubbish = popen("yes", "r");
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+CC="`echo $CC | sed 's/-Xc/-Xa/'`"    ac_cv_prog_cc_stdc='-Xa'
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+
+echo "$as_me:$LINENO: checking for main in -lg" >&5
+echo $ECHO_N "checking for main in -lg... $ECHO_C" >&6
+if test "${ac_cv_lib_g_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lg  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_g_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_g_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_g_main" >&5
+echo "${ECHO_T}$ac_cv_lib_g_main" >&6
+if test $ac_cv_lib_g_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBG 1
+_ACEOF
+
+  LIBS="-lg $LIBS"
+
+fi
+ac_cv_lib_g=ac_cv_lib_g_main
+
+
+echo "$as_me:$LINENO: checking for main in -lm" >&5
+echo $ECHO_N "checking for main in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5
+echo "${ECHO_T}$ac_cv_lib_m_main" >&6
+if test $ac_cv_lib_m_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+fi
+ac_cv_lib_m=ac_cv_lib_m_main
+
+
+echo "$as_me:$LINENO: checking for main in -lcrypt" >&5
+echo $ECHO_N "checking for main in -lcrypt... $ECHO_C" >&6
+if test "${ac_cv_lib_crypt_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypt_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypt_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_main" >&5
+echo "${ECHO_T}$ac_cv_lib_crypt_main" >&6
+if test $ac_cv_lib_crypt_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCRYPT 1
+_ACEOF
+
+  LIBS="-lcrypt $LIBS"
+
+fi
+ac_cv_lib_crypt=ac_cv_lib_crypt_main
+
+if test $ENABLE_ACCENTFOLD = 1; then
+
+echo "$as_me:$LINENO: checking for main in -liconv" >&5
+echo $ECHO_N "checking for main in -liconv... $ECHO_C" >&6
+if test "${ac_cv_lib_iconv_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-liconv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_iconv_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_iconv_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_iconv_main" >&5
+echo "${ECHO_T}$ac_cv_lib_iconv_main" >&6
+if test $ac_cv_lib_iconv_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBICONV 1
+_ACEOF
+
+  LIBS="-liconv $LIBS"
+
+fi
+ac_cv_lib_iconv=ac_cv_lib_iconv_main
+
+fi
+
+
+
+
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5
+echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in dir; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+else
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in x; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+fi
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+
+
+for ac_header in fcntl.h limits.h sys/time.h unistd.h crypt.h string.h memory.h sys/procfs.h sys/stat.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "fread" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_FREAD_DECL 1
+_ACEOF
+
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "fgetc" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_FGETC_DECL 1
+_ACEOF
+
+fi
+rm -f conftest*
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/procfs.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "pr_brksize" >/dev/null 2>&1; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_PR_BRKSIZE 1
+_ACEOF
+
+fi
+rm -f conftest*
+
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+echo "$as_me:$LINENO: checking for working alloca.h" >&5
+echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6
+if test "${ac_cv_working_alloca_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_working_alloca_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_working_alloca_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5
+echo "${ECHO_T}$ac_cv_working_alloca_h" >&6
+if test $ac_cv_working_alloca_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA_H 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for alloca" >&5
+echo $ECHO_N "checking for alloca... $ECHO_C" >&6
+if test "${ac_cv_func_alloca_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  if HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_alloca_works=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_alloca_works=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5
+echo "${ECHO_T}$ac_cv_func_alloca_works" >&6
+
+if test $ac_cv_func_alloca_works = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA 1
+_ACEOF
+
+else
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble.  Some versions do not even contain alloca or
+# contain a buggy version.  If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=alloca.$ac_objext
+
+cat >>confdefs.h <<\_ACEOF
+#define C_ALLOCA 1
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5
+echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6
+if test "${ac_cv_os_cray+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "webecray" >/dev/null 2>&1; then
+  ac_cv_os_cray=yes
+else
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5
+echo "${ECHO_T}$ac_cv_os_cray" >&6
+if test $ac_cv_os_cray = yes; then
+  for ac_func in _getb67 GETB67 getb67; do
+    as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+    break
+fi
+
+  done
+fi
+
+echo "$as_me:$LINENO: checking stack direction for C alloca" >&5
+echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6
+if test "${ac_cv_c_stack_direction+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_c_stack_direction=0
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+  exit (find_stack_direction () < 0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_stack_direction=1
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5
+echo "${ECHO_T}$ac_cv_c_stack_direction" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+if test $ac_cv_c_compiler_gnu = yes; then
+    echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5
+echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6
+if test "${ac_cv_prog_gcc_traditional+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+else
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5
+echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+echo "$as_me:$LINENO: checking return type of signal handlers" >&5
+echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
+if test "${ac_cv_type_signal+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+# undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_signal=void
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_signal=int
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
+echo "${ECHO_T}$ac_cv_type_signal" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+
+for ac_func in vprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+echo "$as_me:$LINENO: checking for _doprnt" >&5
+echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6
+if test "${ac_cv_func__doprnt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define _doprnt to an innocuous variant, in case <limits.h> declares _doprnt.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define _doprnt innocuous__doprnt
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _doprnt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef _doprnt
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char _doprnt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+char (*f) () = _doprnt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != _doprnt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func__doprnt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func__doprnt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5
+echo "${ECHO_T}$ac_cv_func__doprnt" >&6
+if test $ac_cv_func__doprnt = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DOPRNT 1
+_ACEOF
+
+fi
+
+fi
+done
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_func in ftime select strftime strtol getrusage times mallinfo setbuffer getpagesize strerror
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+for ac_func in ftruncate strstr strcasecmp
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+echo "$as_me:$LINENO: checking for textdomain" >&5
+echo $ECHO_N "checking for textdomain... $ECHO_C" >&6
+if test "${ac_cv_func_textdomain+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define textdomain to an innocuous variant, in case <limits.h> declares textdomain.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define textdomain innocuous_textdomain
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char textdomain (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef textdomain
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char textdomain ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_textdomain) || defined (__stub___textdomain)
+choke me
+#else
+char (*f) () = textdomain;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != textdomain;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_textdomain=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_textdomain=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_textdomain" >&5
+echo "${ECHO_T}$ac_cv_func_textdomain" >&6
+if test $ac_cv_func_textdomain = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define ENABLE_NLS  1
+_ACEOF
+
+fi
+
+
+# *** Custom checking (based on GNU tar configure.in) ***
+# ---------------------------------------------------------------------------
+echo "$as_me:$LINENO: checking for HP-UX needing gmalloc" >&5
+echo $ECHO_N "checking for HP-UX needing gmalloc... $ECHO_C" >&6
+if test "`(uname -s) 2> /dev/null`" = 'HP-UX'; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  case $LIBOBJS in
+    "gmalloc.$ac_objext"   | \
+  *" gmalloc.$ac_objext"   | \
+    "gmalloc.$ac_objext "* | \
+  *" gmalloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS gmalloc.$ac_objext" ;;
+esac
+
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_VALLOC 1
+_ACEOF
+
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+for ac_func in valloc
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+fi
+
+# we cannot generate static libraries under Darwin
+echo "$as_me:$LINENO: checking for Apple MacOS X/Darwin" >&5
+echo $ECHO_N "checking for Apple MacOS X/Darwin... $ECHO_C" >&6
+if test "`(uname -s) 2> /dev/null`" = 'Darwin'; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  STATIC=""
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  STATIC="-static "
+fi
+
+
+echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5
+echo $ECHO_N "checking if malloc debugging is wanted... $ECHO_C" >&6
+
+# Check whether --with-dmalloc or --without-dmalloc was given.
+if test "${with_dmalloc+set}" = set; then
+  withval="$with_dmalloc"
+  if test "$withval" = yes; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  cat >>confdefs.h <<\_ACEOF
+#define WITH_DMALLOC 1
+_ACEOF
+
+  LIBS="$LIBS -ldmalloc"
+  LDFLAGS="$LDFLAGS -g"
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi;
+
+echo "$as_me:$LINENO: checking which of rx or regex is wanted" >&5
+echo $ECHO_N "checking which of rx or regex is wanted... $ECHO_C" >&6
+
+# Check whether --with-regex or --without-regex was given.
+if test "${with_regex+set}" = set; then
+  withval="$with_regex"
+  if test "$withval" = yes; then
+  ac_with_regex=1
+  echo "$as_me:$LINENO: result: regex" >&5
+echo "${ECHO_T}regex" >&6
+  cat >>confdefs.h <<\_ACEOF
+#define WITH_REGEX 1
+_ACEOF
+
+  case $LIBOBJS in
+    "regex.$ac_objext"   | \
+  *" regex.$ac_objext"   | \
+    "regex.$ac_objext "* | \
+  *" regex.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS regex.$ac_objext" ;;
+esac
+
+fi
+fi;
+if test -z "$ac_with_regex"; then
+  echo "$as_me:$LINENO: result: rx" >&5
+echo "${ECHO_T}rx" >&6
+  echo "$as_me:$LINENO: checking for re_rx_search" >&5
+echo $ECHO_N "checking for re_rx_search... $ECHO_C" >&6
+if test "${ac_cv_func_re_rx_search+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define re_rx_search to an innocuous variant, in case <limits.h> declares re_rx_search.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define re_rx_search innocuous_re_rx_search
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char re_rx_search (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef re_rx_search
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char re_rx_search ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_re_rx_search) || defined (__stub___re_rx_search)
+choke me
+#else
+char (*f) () = re_rx_search;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != re_rx_search;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_re_rx_search=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_re_rx_search=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_re_rx_search" >&5
+echo "${ECHO_T}$ac_cv_func_re_rx_search" >&6
+if test $ac_cv_func_re_rx_search = yes; then
+  :
+else
+  case $LIBOBJS in
+    "rx.$ac_objext"   | \
+  *" rx.$ac_objext"   | \
+    "rx.$ac_objext "* | \
+  *" rx.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS rx.$ac_objext" ;;
+esac
+
+fi
+
+fi
+
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+  case $LIBOBJS in
+    "xmalloc.$ac_objext"   | \
+  *" xmalloc.$ac_objext"   | \
+    "xmalloc.$ac_objext "* | \
+  *" xmalloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS xmalloc.$ac_objext" ;;
+esac
+
+  case $LIBOBJS in
+    "error.$ac_objext"   | \
+  *" error.$ac_objext"   | \
+    "error.$ac_objext "* | \
+  *" error.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS error.$ac_objext" ;;
+esac
+
+fi
+
+
+# ---------------------------------------------------------------------------
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking that Perl 5 is available" >&5
+echo $ECHO_N "checking that Perl 5 is available... $ECHO_C" >&6
+success="no"
+pl_path="$PATH"
+IFS="${IFS=   }"; pl_save_ifs="$IFS"; IFS=":"
+for pl_dir in $pl_path; do
+  test -z "$pl_dir" && pl_dir=.
+  if test -x $pl_dir/perl; then
+    success="yes"
+    break
+  fi
+done
+IFS="$pl_save_ifs"
+
+success=no
+echo "$as_me:$LINENO: checking \"whether STL library has known faults\"" >&5
+echo $ECHO_N "checking \"whether STL library has known faults\"... $ECHO_C" >&6
+
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <vector>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  success=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $success = "no"; then
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <vector.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  success="yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test $success = "no"; then
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ospace\\std\\vector>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  success="yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test $success = yes; then
+echo "$as_me:$LINENO: result: \"no\"" >&5
+echo "${ECHO_T}\"no\"" >&6
+else
+echo "$as_me:$LINENO: result: \"yes\"" >&5
+echo "${ECHO_T}\"yes\"" >&6
+{ { echo "$as_me:$LINENO: error: \"STL Broken - Obtain newer version of GNU C Compiler\"" >&5
+echo "$as_me: error: \"STL Broken - Obtain newer version of GNU C Compiler\"" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+gsdlos=`uname | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+# check for running bash under cygwin
+ if test "`echo $gsdlos | sed 's/cygwin//'`" != "$gsdlos" ;
+ then
+  gsdlos=windows
+ fi
+
+
+# check for endianness
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+main ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+  case $LIBOBJS in
+    "xmalloc.o.$ac_objext"   | \
+  *" xmalloc.o.$ac_objext"   | \
+    "xmalloc.o.$ac_objext "* | \
+  *" xmalloc.o.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS xmalloc.o.$ac_objext" ;;
+esac
+
+  case $LIBOBJS in
+    "error.$ac_objext"   | \
+  *" error.$ac_objext"   | \
+    "error.$ac_objext "* | \
+  *" error.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS error.$ac_objext" ;;
+esac
+
+fi
+
+# ---------------------------------------------------------------------------
+
+
+moduleDirs=""
+MODULEDIRS=""
+if test -d modules ; then
+  for x in `find modules -mindepth 1 -maxdepth 2`; do
+    if test -d "$x"; then
+      d="$x/Makefile.in"
+      if test -e "$d"; then
+          moduleDirs="$moduleDirs $x/Makefile"
+        MODULEDIRS="$MODULEDIRS $x"
+      fi
+    fi
+  done
+  echo "Making $moduleDirs in modules directory"
+
+fi
+
+
+
+
+subdirs="$subdirs packages"
+
+
+# the list of folders in the src folder
+srclist="src/colservr/Makefile \
+         src/corba/Makefile \
+         src/protocol/Makefile \
+         src/recpt/Makefile \
+         src/oaiservr/Makefile \
+         src/z3950/Makefile"
+
+                                        ac_config_files="$ac_config_files packages/Makefile Makefile $srclist $moduleDirs"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "packages/Makefile" ) CONFIG_FILES="$CONFIG_FILES packages/Makefile" ;;
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "$srclist" ) CONFIG_FILES="$CONFIG_FILES $srclist" ;;
+  "$moduleDirs" ) CONFIG_FILES="$CONFIG_FILES $moduleDirs" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@USE_FASTCGI@,$USE_FASTCGI,;t t
+s,@USE_LANGACTION@,$USE_LANGACTION,;t t
+s,@USE_CORBA@,$USE_CORBA,;t t
+s,@MICO_DIR@,$MICO_DIR,;t t
+s,@USE_Z3950@,$USE_Z3950,;t t
+s,@USE_YAZ@,$USE_YAZ,;t t
+s,@ENABLE_ACCENTFOLD@,$ENABLE_ACCENTFOLD,;t t
+s,@USE_SQLITE@,$USE_SQLITE,;t t
+s,@USE_APACHE_HTTPD@,$USE_APACHE_HTTPD,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@CC@,$CC,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CXX@,$CXX,;t t
+s,@CXXFLAGS@,$CXXFLAGS,;t t
+s,@ac_ct_CXX@,$ac_ct_CXX,;t t
+s,@AWK@,$AWK,;t t
+s,@YACC@,$YACC,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@target@,$target,;t t
+s,@target_cpu@,$target_cpu,;t t
+s,@target_vendor@,$target_vendor,;t t
+s,@target_os@,$target_os,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@LN_S@,$LN_S,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@COMPAT32BITFLAGS@,$COMPAT32BITFLAGS,;t t
+s,@MICO_VER@,$MICO_VER,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@U@,$U,;t t
+s,@ANSI2KNR@,$ANSI2KNR,;t t
+s,@ALLOCA@,$ALLOCA,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@STATIC@,$STATIC,;t t
+s,@gsdlos@,$gsdlos,;t t
+s,@MODULEDIRS@,$MODULEDIRS,;t t
+s,@subdirs@,$subdirs,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+#
+# CONFIG_SUBDIRS section.
+#
+if test "$no_recursion" != yes; then
+
+  # Remove --cache-file and --srcdir arguments so they do not pile up.
+  ac_sub_configure_args=
+  ac_prev=
+  for ac_arg in $ac_configure_args; do
+    if test -n "$ac_prev"; then
+      ac_prev=
+      continue
+    fi
+    case $ac_arg in
+    -cache-file | --cache-file | --cache-fil | --cache-fi \
+    | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+      ac_prev=cache_file ;;
+    -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+    | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \
+    | --c=*)
+      ;;
+    --config-cache | -C)
+      ;;
+    -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+      ac_prev=srcdir ;;
+    -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+      ;;
+    -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+      ac_prev=prefix ;;
+    -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+      ;;
+    *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+    esac
+  done
+
+  # Always prepend --prefix to ensure using the same prefix
+  # in subdir configurations.
+  ac_sub_configure_args="--prefix=$prefix $ac_sub_configure_args"
+
+  ac_popdir=`pwd`
+  for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue
+
+    # Do not complain, so a configure script can configure whichever
+    # parts of a large source tree are present.
+    test -d $srcdir/$ac_dir || continue
+
+    { echo "$as_me:$LINENO: configuring in $ac_dir" >&5
+echo "$as_me: configuring in $ac_dir" >&6;}
+    { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+    cd $ac_dir
+
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      ac_sub_configure="$SHELL '$ac_srcdir/configure.gnu'"
+    elif test -f $ac_srcdir/configure; then
+      ac_sub_configure="$SHELL '$ac_srcdir/configure'"
+    elif test -f $ac_srcdir/configure.in; then
+      ac_sub_configure=$ac_configure
+    else
+      { echo "$as_me:$LINENO: WARNING: no configuration information is in $ac_dir" >&5
+echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
+      ac_sub_configure=
+    fi
+
+    # The recursion is here.
+    if test -n "$ac_sub_configure"; then
+      # Make the cache file name correct relative to the subdirectory.
+      case $cache_file in
+      [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;;
+      *) # Relative path.
+	ac_sub_cache_file=$ac_top_builddir$cache_file ;;
+      esac
+
+      { echo "$as_me:$LINENO: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
+echo "$as_me: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
+      # The eval makes quoting arguments work.
+      eval $ac_sub_configure $ac_sub_configure_args \
+	   --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir ||
+	{ { echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5
+echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+
+    cd $ac_popdir
+  done
+fi
+
+
+
Index: /gsdl/stable/runtime-src/configure.in
===================================================================
--- /gsdl/stable/runtime-src/configure.in	(revision 20131)
+++ /gsdl/stable/runtime-src/configure.in	(revision 20131)
@@ -0,0 +1,371 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl Use autoconf-2.59 or later... it might not work anymore with
+dnl the older 2.1x versions - jrm21 12/2004
+AC_INIT()
+AC_CONFIG_HEADER(config.h)
+
+
+
+PACKAGE=gsdl
+VERSION=2.82-svn
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+dnl
+dnl Set use of fast cgi
+dnl
+USE_FASTCGI=0
+if test USE_FASTCGI = 1; then
+AC_DEFINE(USE_FASTCGI)
+AC_SUBST(USE_FASTCGI)
+fi
+
+dnl
+dnl Set use of langaction
+dnl
+dnl USE_LANGACTION=0
+if test USE_LANGACTION = 1; then
+AC_DEFINE(USE_LANGACTION)
+AC_SUBST(USE_LANGACTION)
+fi
+
+dnl
+dnl Set use of corba
+dnl
+AC_ARG_ENABLE(corba, [  --enable-corba          Enable CORBA support], USE_CORBA=1, USE_CORBA=0)
+AC_DEFINE_UNQUOTED(USE_CORBA, $USE_CORBA)
+AC_SUBST(USE_CORBA)
+
+AC_ARG_WITH(micodir, [  --with-micodir          Use installed MICO directory], MICO_DIR=$enableval, MICO_DIR="default")
+AC_DEFINE_UNQUOTED(MICO_DIR, "$MICO_DIR")
+AC_SUBST(MICO_DIR)
+
+dnl
+dnl Set use of z39.50
+dnl
+AC_ARG_ENABLE(z3950, [  --enable-z3950          Enable Z39.50 client support], USE_Z3950=1, USE_Z3950=0)
+if test USE_Z3950 = 1; then
+AC_DEFINE(USE_Z3950, $USE_Z3950)
+AC_SUBST(USE_Z3950)
+fi
+
+dnl
+dnl Set use of yaz - now compiled by default even when z3950 support not required
+dnl
+AC_ARG_ENABLE(yaz, [  --disable-yaz           Disable YAZ compilation], USE_YAZ=0, USE_YAZ=1)
+dnl if test USE_YAZ = 1; then
+AC_DEFINE(USE_YAZ, $USE_YAZ)
+AC_SUBST(USE_YAZ)
+dnl fi
+
+dnl 
+dnl disable compilation of accent folding stuff for mgpp (and one day mg)
+dnl
+AC_ARG_ENABLE(accentfold, [  --disable-accentfold    Disable Accent Folding for MGPP], ENABLE_ACCENTFOLD=0, ENABLE_ACCENTFOLD=1)
+AC_DEFINE(ENABLE_ACCENTFOLD, $ENABLE_ACCENTFOLD)
+AC_SUBST(ENABLE_ACCENTFOLD)
+
+dnl
+dnl Set use of SQLite (enabled by default)
+dnl
+AC_ARG_ENABLE(sqlite, [  --disable-sqlite        Disable SQLite support], USE_SQLITE=0, USE_SQLITE=1)
+AC_DEFINE(USE_SQLITE, $USE_SQLITE)
+AC_SUBST(USE_SQLITE)
+
+dnl
+dnl Set use of Apache httpd (enabled by default)
+dnl
+AC_ARG_ENABLE(apache-httpd, [  --disable-apache-httpd  Disable Apache httpd support], USE_APACHE_HTTPD=0, USE_APACHE_HTTPD=1)
+AC_DEFINE(USE_APACHE_HTTPD, $USE_APACHE_HTTPD)
+AC_SUBST(USE_APACHE_HTTPD)
+
+
+dnl Checks for programs.
+LDFLAGS=$LDFLAGS
+AC_SUBST(LDFLAGS)
+dnl only set CFLAGS if not already set in environment
+if test -z "$CFLAGS"; then
+CFLAGS=-O2
+fi
+AC_SUBST(CFLAGS)
+
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_AWK
+AC_PROG_YACC
+dnl get $target_cpu, $target_vendor, and $target_os
+dnl (as well as host_*)
+AC_CANONICAL_SYSTEM
+dnl do we actually want this? It adds a prefix based on host, system etc
+dnl AC_ARG_PROGRAM
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+
+AC_MSG_CHECKING(to see if architecture is 64-bit)
+arch_64bit=no
+case "$host_cpu" in
+x86_64) arch_64bit=yes ;;
+esac
+
+if test "$arch_64bit" = yes; then
+  AC_MSG_RESULT(yes)
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS="-m32"
+  fi
+else
+  AC_MSG_RESULT(no)
+  if test -z "$COMPAT32BITFLAGS" ; then
+    COMPAT32BITFLAGS=
+  fi
+fi
+export COMPAT32BITFLAGS
+AC_SUBST(COMPAT32BITFLAGS)
+
+
+#moved CORBA MICO directory test to get version of MICO
+if test $USE_CORBA = 1; then
+
+if test $MICO_DIR = "default"; then
+#do something
+MICO_INC="-I packages/mico/mico/include"
+else
+#build the micotest program
+MICO_INC= ""
+if test $MICO_DIR != yes; then
+MICO_INC="-I $MICO_DIR"
+fi
+fi
+
+#get MICO_VER value
+sh -c "$CC -c micotest.cpp -o micotest.o $MICO_INC 2>&1" > /dev/null
+sh -c "$CC -o micotest micotest.o -lstdc++ 2>&1" > /dev/null
+MICO_VER=`./micotest` || MICO_VER=2.3.5
+sh -c "rm micotest"
+sh -c "rm micotest.o"
+
+#do test of MICO_VER
+if test MICO_VER != 0; then
+AC_DEFINE(MICO_VER)
+AC_SUBST(MICO_VER)
+fi
+#end USE_CORBA test
+fi
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_AIX
+AC_ISC_POSIX
+AC_MINIX
+fp_C_PROTOTYPES
+AC_C_CONST
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl --- This should be in the stdc checking -----------------
+if test "$ac_cv_prog_cc_stdc" = '-Xc'; then
+dnl The Pyramids running SMP_DC.OSx on MIPS r3000 chips with
+dnl /usr/opt/cc3.11/bin/cc treat -Xc as full ANSI mode - no POSIX or
+dnl XOPEN extensions (like popen).
+dnl Unfortunately -D_{XOPEN,POSIX}_SOURCE can't provide all that mg
+dnl needs. So drop back to -Xa
+AC_TRY_COMPILE(
+[#include <stdio.h>
+], [ FILE *rubbish = popen("yes", "r"); ],,
+[CC="`echo $CC | sed 's/-Xc/-Xa/'`"    ac_cv_prog_cc_stdc='-Xa'])
+fi
+dnl ----------------------
+
+
+dnl Checks for libraries.
+dnl check for -lg:
+AC_HAVE_LIBRARY(g)
+dnl check for -lm:
+AC_HAVE_LIBRARY(m)
+dnl check for -lcrypt:
+AC_HAVE_LIBRARY(crypt)
+if test $ENABLE_ACCENTFOLD = 1; then
+AC_HAVE_LIBRARY(iconv)
+fi
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h limits.h sys/time.h unistd.h crypt.h string.h memory.h sys/procfs.h sys/stat.h)
+AC_EGREP_HEADER(fread, stdio.h, AC_DEFINE(HAVE_FREAD_DECL))
+AC_EGREP_HEADER(fgetc, stdio.h, AC_DEFINE(HAVE_FGETC_DECL))
+AC_EGREP_HEADER(pr_brksize, sys/procfs.h, AC_DEFINE(HAVE_PR_BRKSIZE))
+
+dnl Checks for library functions.
+AC_FUNC_ALLOCA
+AC_PROG_GCC_TRADITIONAL
+AC_TYPE_SIGNAL
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(ftime select strftime strtol getrusage times mallinfo setbuffer getpagesize strerror)
+AC_REPLACE_FUNCS(ftruncate strstr strcasecmp)
+
+dnl see if gettext is in libc. (try the textdomain() function).
+AC_CHECK_FUNC(textdomain, AC_DEFINE(ENABLE_NLS ,1) )
+
+# *** Custom checking (based on GNU tar configure.in) ***
+# ---------------------------------------------------------------------------
+AC_MSG_CHECKING(for HP-UX needing gmalloc)
+if test "`(uname -s) 2> /dev/null`" = 'HP-UX'; then
+  AC_MSG_RESULT(yes)
+  AC_LIBOBJ([gmalloc])
+  AC_DEFINE(HAVE_VALLOC)
+else
+  AC_MSG_RESULT(no)
+  AC_CHECK_FUNCS(valloc)
+fi
+
+# we cannot generate static libraries under Darwin
+AC_MSG_CHECKING(for Apple MacOS X/Darwin)
+if test "`(uname -s) 2> /dev/null`" = 'Darwin'; then
+  AC_MSG_RESULT(yes)
+  STATIC=""
+else
+  AC_MSG_RESULT(no)
+  STATIC="-static "
+fi
+AC_SUBST(STATIC)
+
+fp_WITH_DMALLOC
+fp_WITH_REGEX
+
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+dnl    support functions for alloca.c
+  AC_LIBOBJ([xmalloc])
+  AC_LIBOBJ([error])
+fi
+
+
+# ---------------------------------------------------------------------------
+
+dnl
+dnl Switch into C++
+dnl
+AC_LANG_CPLUSPLUS
+
+dnl
+dnl Now check that Perl is actually around, and can be found
+dnl
+AC_MSG_CHECKING(that Perl 5 is available)
+success="no"
+pl_path="$PATH"
+IFS="${IFS=   }"; pl_save_ifs="$IFS"; IFS=":"
+for pl_dir in $pl_path; do
+  test -z "$pl_dir" && pl_dir=.
+  if test -x $pl_dir/perl; then
+    success="yes"
+    break
+  fi
+done
+IFS="$pl_save_ifs"
+
+dnl
+dnl Check if the STL library has any known faults;
+dnl In GCC 2.7.2.x series, some STL library headers are missing
+dnl a file called "new" which is referred to by other headers
+dnl (eg. vector/vector.h); if this applies, then all use of the
+dnl STL will cause a compile fail, so we'd better let the user
+dnl know now, before things really go wrong!
+dnl
+success=no
+AC_MSG_CHECKING("whether STL library has known faults")
+
+dnl - first shot, try simple good old vector on its own
+AC_TRY_COMPILE(
+[#include <vector>
+], 
+[],
+success=yes,
+)
+
+dnl - try using the .h equivalent
+if test $success = "no"; then
+AC_TRY_COMPILE(
+[#include <vector.h>
+], 
+[],
+success="yes",
+)
+fi
+
+dnl - now try for the objectspace headers
+if test $success = "no"; then
+AC_TRY_COMPILE(
+[#include <ospace\\std\\vector>
+], 
+[],
+success="yes",
+)
+fi
+
+if test $success = yes; then
+AC_MSG_RESULT("no")
+else
+AC_MSG_RESULT("yes")
+AC_MSG_ERROR("STL Broken - Obtain newer version of GNU C Compiler")
+fi
+
+gsdlos=`uname | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+# check for running bash under cygwin
+ if test "`echo $gsdlos | sed 's/cygwin//'`" != "$gsdlos" ;
+ then
+  gsdlos=windows
+ fi
+AC_SUBST(gsdlos)
+
+# check for endianness
+AC_C_BIGENDIAN
+# ---------------------------------------------------------------------------
+if test "$ac_cv_func_alloca" = 'no'; then
+dnl    support functions for alloca.c
+  AC_LIBOBJ([xmalloc.o])
+  AC_LIBOBJ([error])
+fi
+
+# ---------------------------------------------------------------------------
+
+
+dnl
+dnl Locate all children of the modules folder
+dnl
+moduleDirs=""
+MODULEDIRS=""
+if test -d modules ; then
+  for x in `find modules -mindepth 1 -maxdepth 2`; do
+    if test -d "$x"; then
+      d="$x/Makefile.in"
+      if test -e "$d"; then
+  dnl      echo $d
+        moduleDirs="$moduleDirs $x/Makefile"
+        MODULEDIRS="$MODULEDIRS $x"
+      fi
+    fi
+  done
+  echo "Making $moduleDirs in modules directory"
+  AC_SUBST(MODULEDIRS)
+fi
+
+
+AC_CONFIG_SUBDIRS(packages)
+
+# the list of folders in the src folder
+srclist="src/colservr/Makefile \
+         src/corba/Makefile \
+         src/protocol/Makefile \
+         src/recpt/Makefile \
+         src/oaiservr/Makefile \
+         src/z3950/Makefile"
+
+AC_OUTPUT(packages/Makefile Makefile $srclist $moduleDirs)
+
+
Index: /gsdl/stable/runtime-src/packages/Makefile.in
===================================================================
--- /gsdl/stable/runtime-src/packages/Makefile.in	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/Makefile.in	(revision 20131)
@@ -0,0 +1,187 @@
+###########################################################################
+#
+# Makefile -- Makefile for packages included with Greenstone runtime
+#
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 2000 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+
+USE_Z3950=@USE_Z3950@
+USE_YAZ=@USE_YAZ@
+USE_APACHE_HTTPD=@USE_APACHE_HTTPD@
+
+ifeq ($(USE_Z3950), 1)
+# make sure USE_YAZ is set
+USE_YAZ=1
+D2M=d2m
+else
+D2M=
+endif
+
+ifeq ($(USE_YAZ), 1)
+# we only compile the src and client dirs for now.
+YAZ=yaz/yaz-2.1.4/src yaz/yaz-2.1.4/client 
+else
+YAZ=
+endif
+
+
+USE_CORBA=@USE_CORBA@
+MICO_DIR=@MICO_DIR@
+ifeq ($(USE_CORBA), 1)
+ifeq ($(MICO_DIR), default)
+CORBA="mico/mico"
+else
+CORBA=
+endif
+else
+CORBA=
+endif
+
+GSDLOS = @gsdlos@
+
+ifeq ($(USE_APACHE_HTTPD), 1)
+HTTPD=apache-httpd/httpd-2.2.11
+else
+HTTPD=
+endif
+
+
+# PACKAGEDIRS contains the packages that we want to make and install.  It
+# is assumed that each package will have at least four rules: all, install,
+# clean, and distclean.
+PACKAGEDIRS =	$(YAZ) $(D2M) $(CORBA)  $(HTTPD)
+
+REPLACELIST = conf/extra/httpd-dav.conf \
+	conf/extra/httpd-manual.conf \
+	conf/extra/httpd-autoindex.conf \
+	conf/extra/httpd-vhosts.conf \
+	conf/extra/httpd-ssl.conf \
+	conf/extra/httpd-multilang-errordoc.conf \
+	conf/original/extra/httpd-dav.conf \
+	conf/original/extra/httpd-manual.conf \
+	conf/original/extra/httpd-autoindex.conf \
+	conf/original/extra/httpd-vhosts.conf \
+	conf/original/extra/httpd-ssl.conf \
+	conf/original/extra/httpd-multilang-errordoc.conf \
+	conf/original/httpd.conf\
+	lib/apr-util-1/apr_dbd_odbc.la \
+	lib/apr-util-1/apr_dbd_sqlite3.la \
+	lib/pkgconfig/apr-util-1.pc \
+	lib/pkgconfig/apr-1.pc \
+	lib/libaprutil-1.la \
+	lib/libapr-1.la \
+	build/config_vars.mk \
+	build/config.nice \
+	build/apr_rules.mk \
+	bin/apu-1-config \
+	bin/apr-1-config \
+	include/ap_config_auto.h \
+	include/ap_config_layout.h
+
+all:
+	for odir in $(PACKAGEDIRS); do \
+          echo making $@ in $$odir; \
+          (cd $$odir && $(MAKE) $(MDEFINES) $@) || exit 1; \
+        done
+ifeq ($(USE_APACHE_HTTPD), 1)
+	# Need to make install here, otherwise src/recpt won't be able
+	# to compile mod_gsdl.cpp with installed header files etc.
+	(cd $(HTTPD) && $(MAKE) $(MDEFINES) install) || exit 
+endif
+
+ifeq ($(CORBA), "mico/mico")
+	cd mico/mico; $(MAKE)  $(MDEFINES) install
+	mkdir -p ../bin/linux
+	mkdir -p ../lib
+	mkdir -p ../include
+	mkdir -p ../man
+	cp -f mico/bin/* ../bin/linux
+	cp -f mico/lib/* ../lib/
+	cp -fr mico/include/* ../include
+	cp -fr mico/man ../man
+endif
+ifeq ($(USE_YAZ), 1)
+# need to do make install in include and src dirs to get the header files and
+# lib file into the right place
+	cd yaz/yaz-2.1.4/include; $(MAKE)  $(MDEFINES) install
+	cd yaz/yaz-2.1.4/src; $(MAKE)  $(MDEFINES) install
+endif
+
+install:
+	for idir in $(PACKAGEDIRS); do \
+          echo installing $$idir; \
+          (cd $$idir && $(MAKE) install) || exit 1; \
+        done
+ifeq ($(USE_APACHE_HTTPD), 1)
+	mkdir -p ../../apache-httpd/$(GSDLOS)/conf
+	cp -f apache-httpd/httpd.conf.in ../../apache-httpd/$(GSDLOS)/conf/.
+	mkdir -p ../../etc/logs-gsi
+	@ echo "*************** INFO ***************"
+	@ echo "Run: source setup.bash, to set up the environment for greenstone"
+	@ echo "Type: make configure-admin, to set the admin password"
+	@ echo "Edit: llssite.cfg and glisite.cfg files to change the port number if necessary"
+	@ echo "Type: make configure-web, to configure the included apache webserver"
+	@ echo "EITHER type: make web-start, to launch the webserver from the command-line"
+	@ echo "OR run: gs2-server.sh, to launch the GUI version of the included webserver"
+	@ echo "************************************"
+endif
+
+clean:
+	for subdir in $(PACKAGEDIRS); do \
+          echo cleaning $@ in $$subdir; \
+          (cd $$subdir && $(MAKE) clean || exit 0) ; \
+        done
+
+distclean:
+	for subdir in $(PACKAGEDIRS); do \
+          echo cleaning $@ in $$subdir; \
+          (cd $$subdir && $(MAKE) distclean || exit 0) ; \
+        done
+
+apache-for-dist:
+	( httpddir=`cd ./apache-httpd/httpd* ; pwd` ; \
+	  cp $$httpddir/support/apxs.in ../../apache-httpd/$(GSDLOS)/apxs.in ; \
+	  cp apache-httpd/install-bindist.sh ../../apache-httpd/$(GSDLOS)/install-bindist.sh ; \
+	  chmod 755 ../../apache-httpd/$(GSDLOS)/install-bindist.sh ; \
+	  gsdldir=`cd ../.. ; pwd` ; \
+	  pre="$$gsdldir/apache-httpd/$(GSDLOS)" ; \
+	  for one_file in apachectl envvars envvars-std; do \
+	    sed -e "s%$$pre%*\*\APACHE_HOME_OS\*\*%" $$pre/bin/$$one_file > $$pre/bin/$$one_file.tmp ; \
+	    mv $$pre/bin/$$one_file.tmp $$pre/bin/$$one_file ; \
+	  done ; \
+	  for one_file in $(REPLACELIST); do \
+	    sed -e "s%$$pre%*\*\APACHE_HOME_OS\*\*%" "$$pre/$$one_file" > "$$pre/$$one_file.tmp" ; \
+	    mv "$$pre/$$one_file.tmp" "$$pre/$$one_file" ; \
+	  done ; \
+	  cat "$$pre/bin/apr-1-config" \
+	    | sed -e "s%^APR_SOURCE_DIR=.*%APR_SOURCE_DIR=%" \
+	    | sed -e "s%^APR_BUILD_DIR=.*%APR_BUILD_DIR=%" \
+	    > "$$pre/bin/apr-1-config.tmp" ; \
+	  mv "$$pre/bin/apr-1-config.tmp" "$$pre/bin/apr-1-config" ; \
+	  cat "$$pre/bin/apu-1-config" \
+	    | sed -e "s%^APU_SOURCE_DIR=.*%APU_SOURCE_DIR=%" \
+	    | sed -e "s%^APU_BUILD_DIR=.*%APU_BUILD_DIR=%" \
+	    > "$$pre/bin/apu-1-config.tmp" ; \
+	  mv "$$pre/bin/apu-1-config.tmp" "$$pre/bin/apu-1-config" ; \
+	  sed -e "s%^EXTRA_INCLUDES\s*=.*%EXTRA_INCLUDES=%" "$$pre/build/config_vars.mk" > "$$pre/build/config_vars.mk.tmp" ; \
+	  mv "$$pre/build/config_vars.mk.tmp" "$$pre/build/config_vars.mk" ; )
Index: /gsdl/stable/runtime-src/packages/apache-httpd/httpd.conf.in
===================================================================
--- /gsdl/stable/runtime-src/packages/apache-httpd/httpd.conf.in	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/apache-httpd/httpd.conf.in	(revision 20131)
@@ -0,0 +1,423 @@
+#
+# This is the main Apache HTTP server configuration file.  It contains the
+# configuration directives that give the server its instructions.
+# See <URL:http://httpd.apache.org/docs/2.2> for detailed information.
+# In particular, see 
+# <URL:http://httpd.apache.org/docs/2.2/mod/directives.html>
+# for a discussion of each configuration directive.
+#
+# Do NOT simply read the instructions in here without understanding
+# what they do.  They're here only as hints or reminders.  If you are unsure
+# consult the online docs. You have been warned.  
+#
+# Configuration and logfile names: If the filenames you specify for many
+# of the server's control files begin with "/" (or "drive:/" for Win32), the
+# server will use that explicit path.  If the filenames do *not* begin
+# with "/", the value of ServerRoot is prepended -- so "logs/foo_log"
+# with ServerRoot set to "**APACHE_HOME_OS**" will be interpreted by the
+# server as "**APACHE_HOME_OS**/logs/foo_log".
+
+#
+# ServerRoot: The top of the directory tree under which the server's
+# configuration, error, and log files are kept.
+#
+# Do not add a slash at the end of the directory path.  If you point
+# ServerRoot at a non-local disk, be sure to point the LockFile directive
+# at a local disk.  If you wish to share the same ServerRoot for multiple
+# httpd daemons, you will need to change at least LockFile and PidFile.
+#
+ServerRoot "**APACHE_HOME_OS**"
+
+#
+# Listen: Allows you to bind Apache to specific IP addresses and/or
+# ports, instead of the default. See also the <VirtualHost>
+# directive.
+#
+# Change this to Listen on specific IP addresses as shown below to 
+# prevent Apache from glomming onto all bound IP addresses.
+#
+#Listen 12.34.56.78:80
+Listen **PORT**
+
+#
+# Dynamic Shared Object (DSO) Support
+#
+# To be able to use the functionality of a module which was built as a DSO you
+# have to place corresponding `LoadModule' lines at this location so the
+# directives contained in it are actually available _before_ they are used.
+# Statically compiled modules (those listed by `httpd -l') do not need
+# to be loaded here.
+#
+# Example:
+# LoadModule foo_module modules/mod_foo.so
+#
+
+<IfModule !mpm_netware_module>
+<IfModule !mpm_winnt_module>
+#
+# If you wish httpd to run as a different user or group, you must run
+# httpd as root initially and it will switch.  
+#
+# User/Group: The name (or #number) of the user/group to run httpd as.
+# It is usually good practice to create a dedicated user and group for
+# running httpd, as with most system services.
+#
+User daemon
+Group daemon
+
+</IfModule>
+</IfModule>
+
+# 'Main' server configuration
+#
+# The directives in this section set up the values used by the 'main'
+# server, which responds to any requests that aren't handled by a
+# <VirtualHost> definition.  These values also provide defaults for
+# any <VirtualHost> containers you may define later in the file.
+#
+# All of these directives may appear inside <VirtualHost> containers,
+# in which case these default settings will be overridden for the
+# virtual host being defined.
+#
+
+#
+# ServerAdmin: Your address, where problems with the server should be
+# e-mailed.  This address appears on some server-generated pages, such
+# as error documents.  e.g. admin@your-domain.com
+#
+ServerAdmin you@example.com
+
+#
+# ServerName gives the name and port that the server uses to identify itself.
+# This can often be determined automatically, but we recommend you specify
+# it explicitly to prevent problems during startup.
+#
+# If your host doesn't have a registered DNS name, enter its IP address here.
+#
+#ServerName www.example.com:80
+
+#
+# DocumentRoot: The directory out of which you will serve your
+# documents. By default, all requests are taken from this directory, but
+# symbolic links and aliases may be used to point to other locations.
+#
+DocumentRoot "**APACHE_HOME_OS**/htdocs"
+
+#
+# Each directory to which Apache has access can be configured with respect
+# to which services and features are allowed and/or disabled in that
+# directory (and its subdirectories). 
+#
+# First, we configure the "default" to be a very restrictive set of 
+# features.  
+#
+<Directory />
+    Options FollowSymLinks
+    AllowOverride None
+    Order deny,allow
+    Deny from all
+</Directory>
+
+#
+# Note that from this point forward you must specifically allow
+# particular features to be enabled - so if something's not working as
+# you might expect, make sure that you have specifically enabled it
+# below.
+#
+
+#
+# This should be changed to whatever you set DocumentRoot to.
+#
+<Directory "**APACHE_HOME_OS**/htdocs">
+    #
+    # Possible values for the Options directive are "None", "All",
+    # or any combination of:
+    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
+    #
+    # Note that "MultiViews" must be named *explicitly* --- "Options All"
+    # doesn't give it to you.
+    #
+    # The Options directive is both complicated and important.  Please see
+    # http://httpd.apache.org/docs/2.2/mod/core.html#options
+    # for more information.
+    #
+    Options Indexes FollowSymLinks
+
+    #
+    # AllowOverride controls what directives may be placed in .htaccess files.
+    # It can be "All", "None", or any combination of the keywords:
+    #   Options FileInfo AuthConfig Limit
+    #
+    AllowOverride None
+
+    #
+    # Controls who can get stuff from this server.
+    #
+    Order allow,deny
+    Allow from all
+
+</Directory>
+
+#
+# DirectoryIndex: sets the file that Apache will serve if a directory
+# is requested.
+#
+<IfModule dir_module>
+    DirectoryIndex index.html
+</IfModule>
+
+#
+# The following lines prevent .htaccess and .htpasswd files from being 
+# viewed by Web clients. 
+#
+<FilesMatch "^\.ht">
+    Order allow,deny
+    Deny from all
+    Satisfy All
+</FilesMatch>
+
+#
+# ErrorLog: The location of the error log file.
+# If you do not specify an ErrorLog directive within a <VirtualHost>
+# container, error messages relating to that virtual host will be
+# logged here.  If you *do* define an error logfile for a <VirtualHost>
+# container, that host's errors will be logged there and not here.
+#
+ErrorLog "logs/error_log"
+
+#
+# LogLevel: Control the number of messages logged to the error_log.
+# Possible values include: debug, info, notice, warn, error, crit,
+# alert, emerg.
+#
+LogLevel warn
+
+<IfModule log_config_module>
+    #
+    # The following directives define some format nicknames for use with
+    # a CustomLog directive (see below).
+    #
+    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+    LogFormat "%h %l %u %t \"%r\" %>s %b" common
+
+    <IfModule logio_module>
+      # You need to enable mod_logio.c to use %I and %O
+      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
+    </IfModule>
+
+    #
+    # The location and format of the access logfile (Common Logfile Format).
+    # If you do not define any access logfiles within a <VirtualHost>
+    # container, they will be logged here.  Contrariwise, if you *do*
+    # define per-<VirtualHost> access logfiles, transactions will be
+    # logged therein and *not* in this file.
+    #
+    CustomLog "logs/access_log" common
+
+    #
+    # If you prefer a logfile with access, agent, and referer information
+    # (Combined Logfile Format) you can use the following directive.
+    #
+    #CustomLog "logs/access_log" combined
+</IfModule>
+
+<IfModule alias_module>
+    #
+    # Redirect: Allows you to tell clients about documents that used to 
+    # exist in your server's namespace, but do not anymore. The client 
+    # will make a new request for the document at its new location.
+    # Example:
+    # Redirect permanent /foo http://www.example.com/bar
+
+    #
+    # Alias: Maps web paths into filesystem paths and is used to
+    # access content that does not live under the DocumentRoot.
+    # Example:
+    # Alias /webpath /full/filesystem/path
+    #
+    # If you include a trailing / on /webpath then the server will
+    # require it to be present in the URL.  You will also likely
+    # need to provide a <Directory> section to allow access to
+    # the filesystem path.
+
+    #
+    # ScriptAlias: This controls which directories contain server scripts. 
+    # ScriptAliases are essentially the same as Aliases, except that
+    # documents in the target directory are treated as applications and
+    # run by the server when requested rather than as documents sent to the
+    # client.  The same rules about trailing "/" apply to ScriptAlias
+    # directives as to Alias.
+    #
+    ScriptAlias /cgi-bin/ "**APACHE_HOME_OS**/cgi-bin/"
+
+</IfModule>
+
+<IfModule cgid_module>
+    #
+    # ScriptSock: On threaded servers, designate the path to the UNIX
+    # socket used to communicate with the CGI daemon of mod_cgid.
+    #
+    #Scriptsock logs/cgisock
+</IfModule>
+
+#
+# "**APACHE_HOME_OS**/cgi-bin" should be changed to whatever your ScriptAliased
+# CGI directory exists, if you have that configured.
+#
+<Directory "**APACHE_HOME_OS**/cgi-bin">
+    AllowOverride None
+    Options None
+    Order allow,deny
+    Allow from all
+</Directory>
+
+#
+# DefaultType: the default MIME type the server will use for a document
+# if it cannot otherwise determine one, such as from filename extensions.
+# If your server contains mostly text or HTML documents, "text/plain" is
+# a good value.  If most of your content is binary, such as applications
+# or images, you may want to use "application/octet-stream" instead to
+# keep browsers from trying to display binary files as though they are
+# text.
+#
+DefaultType text/plain
+
+<IfModule mime_module>
+    #
+    # TypesConfig points to the file containing the list of mappings from
+    # filename extension to MIME-type.
+    #
+    TypesConfig conf/mime.types
+
+    #
+    # AddType allows you to add to or override the MIME configuration
+    # file specified in TypesConfig for specific file types.
+    #
+    #AddType application/x-gzip .tgz
+    #
+    # AddEncoding allows you to have certain browsers uncompress
+    # information on the fly. Note: Not all browsers support this.
+    #
+    #AddEncoding x-compress .Z
+    #AddEncoding x-gzip .gz .tgz
+    #
+    # If the AddEncoding directives above are commented-out, then you
+    # probably should define those extensions to indicate media types:
+    #
+    AddType application/x-compress .Z
+    AddType application/x-gzip .gz .tgz
+
+    #
+    # AddHandler allows you to map certain file extensions to "handlers":
+    # actions unrelated to filetype. These can be either built into the server
+    # or added with the Action directive (see below)
+    #
+    # To use CGI scripts outside of ScriptAliased directories:
+    # (You will also need to add "ExecCGI" to the "Options" directive.)
+    #
+    #AddHandler cgi-script .cgi
+
+    # For type maps (negotiated resources):
+    #AddHandler type-map var
+
+    #
+    # Filters allow you to process content before it is sent to the client.
+    #
+    # To parse .shtml files for server-side includes (SSI):
+    # (You will also need to add "Includes" to the "Options" directive.)
+    #
+    #AddType text/html .shtml
+    #AddOutputFilter INCLUDES .shtml
+</IfModule>
+
+#
+# The mod_mime_magic module allows the server to use various hints from the
+# contents of the file itself to determine its type.  The MIMEMagicFile
+# directive tells the module where the hint definitions are located.
+#
+#MIMEMagicFile conf/magic
+
+#
+# Customizable error responses come in three flavors:
+# 1) plain text 2) local redirects 3) external redirects
+#
+# Some examples:
+#ErrorDocument 500 "The server made a boo boo."
+#ErrorDocument 404 /missing.html
+#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
+#ErrorDocument 402 http://www.example.com/subscription_info.html
+#
+
+#
+# EnableMMAP and EnableSendfile: On systems that support it, 
+# memory-mapping or the sendfile syscall is used to deliver
+# files.  This usually improves server performance, but must
+# be turned off when serving from networked-mounted 
+# filesystems or if support for these functions is otherwise
+# broken on your system.
+#
+#EnableMMAP off
+#EnableSendfile off
+
+# Supplemental configuration
+#
+# The configuration files in the conf/extra/ directory can be 
+# included to add extra features or to modify the default configuration of 
+# the server, or you may simply copy their contents here and change as 
+# necessary.
+
+# Server-pool management (MPM specific)
+#Include conf/extra/httpd-mpm.conf
+
+# Multi-language error messages
+#Include conf/extra/httpd-multilang-errordoc.conf
+
+# Fancy directory listings
+#Include conf/extra/httpd-autoindex.conf
+
+# Language settings
+#Include conf/extra/httpd-languages.conf
+
+# User home directories
+#Include conf/extra/httpd-userdir.conf
+
+# Real-time info on requests and configuration
+#Include conf/extra/httpd-info.conf
+
+# Virtual hosts
+#Include conf/extra/httpd-vhosts.conf
+
+# Local access to the Apache HTTP Server Manual
+#Include conf/extra/httpd-manual.conf
+
+# Distributed authoring and versioning (WebDAV)
+#Include conf/extra/httpd-dav.conf
+
+# Various default settings
+#Include conf/extra/httpd-default.conf
+
+# Secure (SSL/TLS) connections
+#Include conf/extra/httpd-ssl.conf
+#
+# Note: The following must must be present to support
+#       starting without SSL on platforms with no /dev/random equivalent
+#       but a statically compiled-in mod_ssl.
+#
+<IfModule ssl_module>
+SSLRandomSeed startup builtin
+SSLRandomSeed connect builtin
+</IfModule>
+
+  ScriptAlias /greenstone/cgi-bin "**GSDLHOME**/cgi-bin"
+  <Directory "**GSDLHOME**/cgi-bin">
+     Options None
+     AllowOverride None
+  </Directory>
+  
+  Alias /greenstone "**GSDLHOME**"
+  <Directory "**GSDLHOME**">
+     Options Indexes MultiViews FollowSymLinks
+     AllowOverride None
+     Order allow,deny
+     Allow from **CONNECTION**
+  </Directory>
Index: /gsdl/stable/runtime-src/packages/apache-httpd/install-bindist.sh
===================================================================
--- /gsdl/stable/runtime-src/packages/apache-httpd/install-bindist.sh	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/apache-httpd/install-bindist.sh	(revision 20131)
@@ -0,0 +1,131 @@
+#!/bin/sh
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+# Usage: install-bindist.sh [ServerRoot]
+# This script installs the Apache binary distribution and
+# was automatically created by binbuild.sh.
+
+
+##
+##  determine path to (optional) Perl interpreter
+##
+PERL=no-perl5-on-this-system
+perls='perl5 perl'
+path=`echo $PATH | sed -e 's/:/ /g'`
+found_perl=0
+ 
+for dir in ${path} ;  do
+  for pperl in ${perls} ; do
+    if test -f "${dir}/${pperl}" ; then
+      if `${dir}/${pperl} -v >/dev/null 2>&1` ; then
+        PERL="${dir}/${pperl}"
+        found_perl=1
+        break
+      fi
+    fi
+  done
+  if test $found_perl = 1 ; then
+    break
+  fi
+done
+ 
+if [ "x$1" = "x" ]
+then
+  echo "Number of arguments should be 1. Provide the root directory for the web server."
+  exit 1
+else
+  SR="$1"
+fi
+
+if [ -f "$SR/bin/envvars" ]
+then
+  echo "[Preserving existing envvars settings.]"
+  HAD_ENVVARS=yes
+else
+  HAD_ENVVARS=no
+fi
+
+# Need to run this script from its own directory 
+# instead of whatever directory it may be called from
+#currentdir=$(cd `dirname "$0"` && pwd)
+currentdir="`dirname \"$0\"`"
+currentdir="`cd \"$currentdir\" && pwd`"
+cd "$currentdir"
+
+sed -e "s%\*\*APACHE_HOME_OS\*\*%$SR%" "$SR/conf/httpd.conf.in" > "$SR/conf/httpd.conf"
+
+sed -e "s;^#!\@perlbin\@.*;#!$PERL;" -e "s;\@exp_installbuilddir\@;\"$SR/build\";" \
+	apxs.in > "$SR/bin/apxs"
+
+# usually we're updating existing files, so need to copy them over into tmp files first
+#PRE=`grep "^prefix = " build/config_vars.mk`
+#PRE=`echo $PRE | sed -e "s;prefix = ;;"`
+sed -e "s%\*\*APACHE_HOME_OS\*\*%\"$SR\"%" build/config_vars.mk > "$SR/build/config_vars.mk.tmp"
+mv "$SR/build/config_vars.mk.tmp" "$SR/build/config_vars.mk"
+chmod u+rwx "$SR/build/config_vars.mk"
+
+sed -e "s;^#!/.*;#!$PERL;" bin/dbmmanage > "$SR/bin/dbmmanage.tmp"
+mv "$SR/bin/dbmmanage.tmp" "$SR/bin/dbmmanage"
+
+sed -e "s%\*\*APACHE_HOME_OS\*\*%\"$SR\"%" \
+    -e "s%^HTTPD=.*$%HTTPD=\"$SR/bin/httpd\"%" \
+    -e "s%\$HTTPD%\"\$HTTPD\" -d \"$SR\"%" bin/apachectl > "$SR/bin/apachectl.tmp"
+mv "$SR/bin/apachectl.tmp" "$SR/bin/apachectl"
+chmod u+rwx "$SR/bin/apachectl"
+
+sed -e "s%\*\*APACHE_HOME_OS\*\*%\"$SR\"%" \
+        bin/envvars-std > "$SR/bin/envvars-std.tmp"
+mv "$SR/bin/envvars-std.tmp" "$SR/bin/envvars-std"
+chmod u+rwx "$SR/bin/envvars-std"
+
+if [ $HAD_ENVVARS = no ]
+then
+    cp -p "$SR/bin/envvars-std" "$SR/bin/envvars"
+fi
+ 
+
+# Non-crucial files (replacements not essential)
+# but replacing the occurrences of $PRE in them with $SR anyway:
+REPLACELIST="conf/extra/httpd-dav.conf conf/extra/httpd-manual.conf conf/extra/httpd-autoindex.conf conf/extra/httpd-vhosts.conf conf/extra/httpd-ssl.conf conf/extra/httpd-multilang-errordoc.conf conf/original/extra/httpd-dav.conf conf/original/extra/httpd-manual.conf conf/original/extra/httpd-autoindex.conf conf/original/extra/httpd-vhosts.conf conf/original/extra/httpd-ssl.conf conf/original/extra/httpd-multilang-errordoc.conf conf/original/httpd.conf lib/apr-util-1/apr_dbd_odbc.la lib/apr-util-1/apr_dbd_sqlite3.la lib/pkgconfig/apr-util-1.pc lib/pkgconfig/apr-1.pc lib/libaprutil-1.la lib/libapr-1.la build/config_vars.mk build/config.nice build/apr_rules.mk bin/apu-1-config bin/apr-1-config include/ap_config_auto.h include/ap_config_layout.h"
+
+for one_file in $REPLACELIST; do
+    if [ -f $one_file ]; then
+        sed -e "s%\*\*APACHE_HOME_OS\*\*%$SR%" "$one_file" > "$one_file.tmp"
+        mv $one_file.tmp $one_file
+        chmod u+w $one_file
+    fi
+done
+
+echo "Ready."
+echo " +--------------------------------------------------------+"
+echo " | You now have successfully installed the Apache         |"
+echo " | HTTP server. To verify that Apache actually works      |"
+echo " | correctly you should first check the (initially        |"
+echo " | created or preserved) configuration files:             |"
+echo " |                                                        |"
+echo " |   $SR/conf/httpd.conf"
+echo " |                                                        |"
+echo " | You should then be able to immediately fire up         |"
+echo " | Apache the first time by running:                      |"
+echo " |                                                        |"
+echo " |   $SR/bin/apachectl start "
+echo " |                                                        |"
+echo " | Thanks for using Apache.       The Apache Group        |"
+echo " |                                http://www.apache.org/  |"
+echo " +--------------------------------------------------------+"
+echo " "
Index: /gsdl/stable/runtime-src/packages/apache-httpd/win32.mak
===================================================================
--- /gsdl/stable/runtime-src/packages/apache-httpd/win32.mak	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/apache-httpd/win32.mak	(revision 20131)
@@ -0,0 +1,44 @@
+###########################################################################
+#
+# win32 makefile -- gsdl + apache-httpd
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDLHOME = $(GSDLHOME)
+APACHEHOME = $(MAKEDIR)\httpd-2.2.11
+
+compile: 
+	cd "$(APACHEHOME)"
+	nmake /f Makefile.win _apacher PORT=8282 
+	cd "$(GSDLHOME)"
+
+install: compile
+	cd "$(APACHEHOME)"
+	nmake /f Makefile.win installr INSTDIR=$(GSDLHOME)\apache-httpd\windows
+	cd "$(GSDLHOME)"
+
+clean:
+	cd "$(APACHEHOME)"
+	nmake /f Makefile.win clean
+	cd "$(GSDLHOME)"
+
Index: /gsdl/stable/runtime-src/packages/configure
===================================================================
--- /gsdl/stable/runtime-src/packages/configure	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/configure	(revision 20131)
@@ -0,0 +1,202 @@
+#! /bin/sh
+
+PACKAGES=`pwd`
+cd ../..
+GSDLHOME=`pwd`
+cd $PACKAGES
+
+GSDLOS=`uname -s |tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+# check for running bash under cygwin
+if test "`echo $GSDLOS | sed 's/cygwin//'`" != "$GSDLOS" ;
+then
+ GSDLOS=windows
+fi
+
+prefix=""
+bindir=""
+HOSTTARGETFLAGS=""
+
+# only some of the packages can take environment variables as options to 
+# configure 
+# format is VAR=value, e.g "LDFLAGS=-static"
+ENVIRONMENT=""
+
+# SQLite support enabled by default, can switch it off with --disable-sqlite
+USE_SQLITE=true
+# yaz compilation enabled by default, can switch it off with --disable-yaz
+USE_YAZ=true
+# z3950 server disabled by default, switch it on with --enable-z3950
+USE_Z3950=false
+# CORBA support disabled by default, switch it on with --enable-corba
+USE_CORBA=false
+MICO_DIR=default
+# Apache's httpd (web server) enabled by default
+USE_APACHE_HTTPD=false
+
+# parse any arguments given from toplevel configure
+while test $# -ne 0; do
+    case "$1" in
+	--cache-file=*)
+	    cache_filename=`echo $1 | sed s/--cache-file=//`
+	    # turn relative path into an absolute path
+	    cache_dir=`echo $cache_filename | sed 's@/[^/]*$@@'`
+	    cache_dir=`cd $cache_dir 2>/dev/null && pwd`
+
+	    cache_basefile=`echo $cache_filename | sed 's@.*/@@'`
+	    cache_file="$cache_dir/$cache_basefile"
+	    if test ! -f "$cache_file"; then
+		CACHE_FILE=""
+	    else
+		CACHE_FILE="--cache-file=$cache_file"
+	    fi
+	    ;;
+	--disable-sqlite)
+	    USE_SQLITE=false
+	    ;;
+	--disable-yaz)
+	    USE_YAZ=false
+	    ;;
+	--enable-z3950)
+	    USE_Z3950=true
+	    ;;
+	--enable-corba)
+	    USE_CORBA=true
+	    ;;
+	--with-micodir=*)
+	    if test $1 = ""; then
+	      $1 = "default"
+            fi
+	    MICO_DIR=$1
+	    ;;       
+	--enable-apache-httpd)
+	    USE_APACHE_HTTPD=true
+	    ;;
+	--prefix=*)
+	    prefix=`echo $1 | sed s/--prefix=//`
+	    ;;
+	--bindir=*)
+	    # where to install binaries to
+	    bindir=`echo $1 | sed s/--bindir=//`
+	    # turn relative path into an absolute path
+	    if test -d "$bindir" ; then
+	      bindir=`cd "$bindir" ; pwd `
+	      cd "$PACKAGES"
+	    elif test -z `echo $bindir | sed '/^\// p;D'` ; then
+	      rel_bindir="`echo $bindir | sed s@/.*@@`"
+	      cd "$rel_bindir"
+	      bindir="`pwd`/`echo $bindir | sed s@^[^/]*/@@`"
+	      cd "$PACKAGES"
+	    else
+	      # bindir doesn't exist, and isn't relative
+	      true
+	    fi
+	    ;;
+	--host=* | --target=*)
+	    HOSTTARGETFLAGS="$HOSTTARGETFLAGS $1"
+	    ;;
+	*)
+	    # ignore all other options for now
+	    ;;
+    esac
+    shift
+done
+
+# note! Our GSDL package currently always installs into it's source
+# directory, ignoring any --prefix given to configure.
+# When this is fixed, uncomment the relevant lines below...
+
+##if test -z "$prefix" ; then
+prefix="${GSDLHOME}"
+##fi
+
+##if test -z "$bindir" ; then
+bindir="${prefix}/bin/$GSDLOS"
+##fi
+
+# This loads the top configure's cache file, with variables already set.
+if test -f "$cache_file" ; then
+  . $cache_file
+fi
+
+# we assume that gzip and tar are on the search path.
+# non-GNU versions of tar don't take the -z option.
+
+if test $USE_CORBA = true ; then
+  if test $MICO_DIR = default; then
+    # configure the MICO CORBA ORB
+    echo ""
+    echo "Configuring MICO CORBA"
+    echo ""
+
+    cd "$PACKAGES/mico"
+    gzip -dc mico-2.3.5.tar.gz | tar -xf -
+    cd mico && \
+    ./configure $CACHE_FILE    --prefix=$PACKAGES/mico/  --disable-coss --disable-naming --disable-relship --disable-events --disable-streams --disable-property --disable-trader --disable-time --disable-debug --enable-optimize --enable-final --enable-speed-tune
+    sed 's/tools//'  $PACKAGES/mico/mico/Makefile | sed 's/ldconfig//' >$PACKAGES/mico/mico/Makefile.out
+    mv $PACKAGES/mico/mico/Makefile.out $PACKAGES/mico/mico/Makefile
+  else
+    #MICO is on the system path
+    echo ""
+    echo "Taking MICO from system paths"
+    echo ""
+  fi
+else
+  echo "corba support disabled - mico compiler not required."
+  echo "  add '--enable-corba' to the configure command to include corba support."
+  echo ""
+fi
+
+
+
+# D2M stuff needed for z3950server
+echo ""
+echo "Configuring D2M"
+if test x$USE_Z3950 = xtrue ; 
+then
+  USE_YAZ=true
+  echo ""
+  cd "$PACKAGES/d2m"
+  ./configure $CACHE_FILE --prefix="$PACKAGES/d2m" $HOSTTARGETFLAGS
+else
+  echo "Z39.50 support disabled - D2M library not required."
+  echo "  add '--enable-z3950' to the configure command to include z39.50 support."
+  echo ""
+fi
+   
+# YAZ Z39.50 toolkit
+echo ""
+echo "Configuring YAZ"
+if test x$USE_YAZ = xtrue ; 
+then
+  echo "YAZ library support enabled"
+  echo "add --disable-yaz to the configure command to disable this"
+  echo ""
+  cd "$PACKAGES/yaz" 
+  gzip -dc yaz-2.1.4.tar.gz | tar -xf -
+  cd yaz-2.1.4 && \
+    ./configure $CACHE_FILE --prefix="$PACKAGES/yaz" --bindir="$bindir" $HOSTTARGETFLAGS
+else
+  echo "YAZ support disabled"
+  echo ""
+fi
+
+
+# Apache's HTTPD web server
+echo ""
+echo "Configuring Apache httpd"
+if test x$USE_APACHE_HTTPD = xtrue ; 
+then
+  echo "Apache httpd support enabled"
+  echo "add --disable-apache-httpd to the configure command to disable this"
+  echo ""
+  cd "$PACKAGES/apache-httpd" 
+  gzip -dc httpd-2.2.11.tar.gz | tar -xf -
+  cd httpd-2.2.11&& \
+    ./configure $CACHE_FILE --with-included-apr --with-layout=BinaryDistribution --enable-most --prefix="${prefix}/apache-httpd/${GSDLOS}" $HOSTTARGETFLAGS
+else
+  echo "Apache httpd support disabled"
+  echo "add --enable-apache-httpd to the configure command to enable this"
+  echo ""
+fi
+
+
Index: /gsdl/stable/runtime-src/packages/d2m/D2Mcgi.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/D2Mcgi.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/D2Mcgi.c	(revision 20131)
@@ -0,0 +1,326 @@
+/* ------------------------------------------------------------------- */
+/* D2Mcgi.c  : CGI program for DC -> MARC conversion                   */
+/* Author    : Ole Husby                                               */
+/* Updated   : 1998-09-30                                              */
+/* ------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+D2MCgi() will take metadata input from a parameter, or fetch an
+HTML file using HTTP.
+
+DC metadata will be converted into MARC, and presented in one of
+several formats.
+
+The program will look for the following QUERY_STRING:
+
+url=xxx&fmt=xxx&prs=xxx&txt=xxx&par=xxx 
+
+where: 
+
+  url
+      xxx = the URL for the file containing the metadata
+  fmt
+      The MARC format. xxx =
+      DANMARC | FINMARC | ISMARC | NORMARC (default) | SWEMARC | USMARC.
+  prs
+      The presentation format. xxx =
+      plain (default) | html | 2709 | binary.
+
+  txt
+      If present, this field will be parsed for metadata, and the only 
+      use of the URL (if entered) will be used to produce the 856 field 
+      of the MARC record. 
+
+  par
+      If xxx = on, the program will additionally display the tags as
+      they are recognized. Will only work together with the html format.
+   ------------------------------------------------------------------- */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <ctype.h>
+#include <unistd.h>
+#include "d2m.h"
+
+
+
+
+/* ------------------------------------------------------------------- */
+/* main() program                                                      */
+/* ------------------------------------------------------------------- */
+
+int main ()
+{
+  int rc, i, source, textarea, f2709, tracing, mformat, marcfile;
+  int linel, llen, slen;
+  int *meta;
+
+  FILE *df, *of;
+  char contype[64], dfilename[64], tfilename[64], line[50000];
+  char *pq, *p, *q, pre[16], *l, *u;
+  char marcformat[256], url[1000], method[32];
+  char *buffer[50000];
+  char syntax[64];
+
+  char recstatus = 'n';
+  char rectype   = 'm';
+  char biblevel  = ' ';
+
+/* Initializing  */
+
+  of = stdout;
+  *url = 0;
+  marcfile = 0;
+
+  strcpy(marcformat, D2M_DEFAULT_FORMAT);
+  strcpy(syntax, D2M_DEFAULT_SYNTAX);
+  sprintf(dfilename, "%s.%d", D2M_TEMPFILE, getpid());
+
+  textarea = tracing = f2709 = 0;
+  *line = 0;
+
+
+/* Decide parameters for line format formating   */
+
+  linel = D2M_LINELEN;
+  if (!linel)
+    linel = 80;
+
+  if (linel > 200)
+    linel = 200;
+
+  llen = linel - 9;
+  slen = linel - 30;
+  if (slen < 10)
+    slen = 10;
+
+
+/* Check request method (POST or GET)  */
+
+  strcpy(method, getenv("REQUEST_METHOD"));
+
+  if (strcmp(method, "GET") == 0)
+  {
+    strcpy(line, getenv("QUERY_STRING"));
+    pq = (char *) strdup(line);
+  }
+  
+  else if (strcmp(method, "POST") == 0)
+    pq = poq();
+
+  else
+    pq = (char *) NULL;           /* Error exit is missing here ! */
+
+
+/* Parse parameters  */
+  
+  if (pq)
+  {
+    strcpy(line, pq);
+    free(pq);
+
+    l = (char *) line;
+
+    u = strtok(l, "&");
+    while (u)
+    {
+      unescape(u);
+      if (strncasecmp(u, "url=", 4) == 0)
+        strcpy(url, u + 4); 
+      else if (strncasecmp(u, "fmt=", 4) == 0)
+        strcpy(marcformat, u + 4); 
+      else if (strncasecmp(u, "prs=", 4) == 0)
+        strcpy(syntax, u + 4); 
+      else if (strncasecmp(u, "par=", 4) == 0)
+      {
+        if (strcmp(u + 4, "on") == 0) 
+          tracing = 1;
+      }
+      else if (strncasecmp(u, "txt=", 4) == 0)
+      {
+        if (strlen(u + 4))
+        {
+          if ( df = fopen(dfilename, "w"))
+          {
+            fprintf(df, "%s", u + 4);
+            textarea = 1;
+            fclose(df);
+          }
+        }
+      }
+      u = strtok(NULL, "&");
+    }
+  }
+
+
+
+/* Check the syntax */
+
+  if (strcmp(syntax, "2709") == 0)
+  {
+    strcpy(contype, "text/plain");
+    tracing = 0;
+    f2709 = 1;
+  }
+
+  else if (strcmp(syntax, "binary") == 0)
+  {
+    strcpy(contype, "application/marc");
+    tracing = 0;
+    f2709 = 1;
+  }
+
+  else if (strcmp(syntax, "html") == 0)
+  {
+    strcpy(contype, "text/html");
+  }
+
+  else if (strcmp(syntax, "plain") == 0)
+  {
+    strcpy(contype, "text/plain");
+    tracing = 0;
+  }
+
+
+/* Write HTTP header and HTML <HEAD>: */
+
+  printf("Content-type: %s\n\n", contype);
+  if (strcmp(syntax, "html") == 0)
+  {
+    printf("<html><head><title>\n");
+    printf("%s\n", HTML_TITLE);
+    printf("</title></head>\n\n<body bgcolor=\"#ffffbb\">\n");
+  }
+
+
+
+/* Check if metadata in input (source = TEXTAREA) or in URL   */
+
+  if (!textarea && !*url)
+  {
+    printf("1: ");
+    printf("Error: Insufficient input\n");
+    exit(0);
+  }
+
+  else if (textarea)
+    source = TEXTAREA;
+
+  else
+    source = URL;
+
+  if (!textarea && !*url)
+  {
+    printf("2: ");
+    printf("Error: Insufficient input\n");
+    exit(0);
+  }
+
+
+/* Check the marcformat   */
+
+  if (strncasecmp(marcformat, "DAN", 3) == 0)
+    mformat = DANMARC;
+  else if (strncasecmp(marcformat, "FIN", 3) == 0)
+    mformat = FINMARC;
+  else if (strncasecmp(marcformat, "IS", 2) == 0)
+    mformat = ISMARC;
+  else if (strncasecmp(marcformat, "US", 2) == 0)
+    mformat = USMARC;
+  else if (strncasecmp(marcformat, "NOR", 3) == 0)
+    mformat = NORMARC;
+  else if (strncasecmp(marcformat, "SWE", 3) == 0)
+    mformat = SWEMARC;
+  else
+  {
+    printf("Error: This MARC format is not supported!\n");
+    exit(0);
+  }
+
+
+/* Fetch URL if necessary    */
+
+  if (source == URL)
+  {
+    if (strcmp(url, "test") == 0)
+      strcpy(url, D2M_DEFAULT_URL);
+    rc = wfetch(&url, &dfilename);
+    if (!rc)
+    {
+      printf("Error %d: Unable to fetch file %s\n", rc, url);
+      exit(0);
+    }
+    if (rc == 2)
+      marcfile = 1;
+  }
+
+  if (*url && !textarea && ( strcmp(syntax, "html") == 0 ) )
+  {
+    printf("<h2><a href=\"%s\">%s</a></h2>\n", url, url);
+    printf("<h3>%s record:</h3><hr>\n", marcformat);
+  }
+
+   if (strcmp(syntax, "html") == 0)
+     printf("<pre>\n");
+
+   if (tracing)
+     strcpy(tfilename, D2M_TRACEFILE);
+   else
+     *tfilename = 0;
+
+/* Convert to MARC                                                    */
+/* NOTE: M2Mconv() will even convert from MARC 2709 to line format    */
+
+   if (marcfile)
+     rc = M2Mconv((char *) dfilename, (char *) buffer,
+                 (char *) tfilename, mformat);
+   else            
+     rc = D2Mconv((char *) dfilename, (char *) buffer,
+                 (char *) tfilename, (char *) url, mformat);
+
+   remove(dfilename);
+
+
+/* Produce output                                                      */
+
+   if (!rc)
+     printf("Error: Unable to parse data\n");
+
+   else
+   {
+     if (f2709)
+       printf("%s", 
+         (char *) MARC2709(buffer, 0, 6, recstatus, rectype, biblevel));
+     else
+  
+     {
+       l = strtok((char *) buffer, "\n");
+  
+       while (l)
+       {
+         write_field(l, of, linel, llen, slen);
+         l = strtok(NULL, "\n");
+       }
+     }
+   }
+
+   if (*url && !textarea && ( strcmp(syntax, "html") == 0 ) )
+     printf("<hr>\n");
+
+   if (tracing)
+   {
+     printf("</pre>\n");
+     printf("<h3>Parsed DC metadata:</h3>\n");
+     printf("<pre>\n");
+     write_trace(tfilename, of);
+   }
+
+   if (strcmp(syntax, "html") == 0)
+   {
+     printf("</pre>\n");
+     printf("</body></html>\n");
+   }
+}
Index: /gsdl/stable/runtime-src/packages/d2m/D2Mconv.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/D2Mconv.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/D2Mconv.c	(revision 20131)
@@ -0,0 +1,265 @@
+/* ------------------------------------------------------------------- */
+/* D2Mconv   : Converts metadata present in a file to MARC             */
+/*             Writes MARC record in "line format"                     */
+/*                                                                     */
+/* Syntax    : Arguments:                                              */
+/*                                                                     */
+/*       char *dfile : input file                                      */
+/*                     DC metadata must be present in HTML 2.0         */
+/*                     or HTML 4.0 syntax                              */
+/*       char *buffer: output record in line format                    */
+/*                     Must be allocated in calling program!           */
+/*       char *tfile : tracefile                                       */
+/*                     No trace if NULL                                */
+/*       char *url   : URL for use in case no URL in DC.Identifier     */
+/*                                                                     */
+/*       char *format: MARC format (see d2m.h)                         */
+/*                                                                     */
+/* Author    : Ole Husby, BIBSYS                                       */
+/* Updated   : 1998-09-30                                              */
+/* ------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <time.h>
+#include "d2m.h"
+
+
+
+
+/* ------------------------------------------------------------------- */
+/* Checks a new line                                                   */
+/* ------------------------------------------------------------------- */
+/*
+   This is where starting and ending of a meta tag is parsed.
+   The whole metatag (resulting from one ore more lines) is put
+   into the buffer.
+
+   Note: This function is called recursively!
+*/
+
+int mline(char *l, char *buf, int *meta, 
+          struct marcrec *mrec, FILE *tf, int format)
+{
+  char *p, *q, rc;
+  int diff;
+
+  struct metatag *mtag;
+ 
+  if (!l || !*l) return 1;
+
+  q = l;
+
+
+/* Looks for the end of an already started metatag buffer              */
+/* The end is normally '">'                                            */
+
+  if (*meta)
+  {
+     p = strstr(l, "\">");
+
+     if (p) 
+     {
+        if ( (char *) p != (char *) l)
+        {
+           diff = (int)(p - l);
+           if (*buf)
+             strcat(buf, " ");
+           strncat(buf, l, diff);
+        }
+
+/* Parsing the buffer for metadata                                  */
+
+        mtag = dc_parse(buf);
+
+        if (mtag)
+        {
+          if (tf)
+          {
+            fprintf(tf, "Name  : %s\n", mtag->name   );
+            fprintf(tf, "Type  : %s\n", mtag->type   );
+            fprintf(tf, "Scheme: %s\n", mtag->scheme );
+            fprintf(tf, "Value : %s\n", mtag->value  );
+            fprintf(tf, "\n");
+          }
+
+/*        Convert to MARC                                           */
+
+          MARCmake(mtag, mrec, format);
+        }
+        free(mtag);
+
+        *buf = 0;
+        *meta = FALSE;
+        q = p + 2;
+     }
+     else
+     {
+        strcat(buf, l);
+        q = NULL;
+     }
+  }
+
+
+  if (!q) return 1;
+
+  p = (char *) cstr(q, "<meta ");
+
+  if (p)
+  {
+    *meta = TRUE;
+    mline(p + 6, buf, meta, mrec, tf, format);
+  }
+
+  return 1;
+}
+
+
+
+int D2Mconv(char *dfile, char *buffer, char *tfile, char *url, int format)
+{
+  struct marcrec *mrec;
+  struct metatag *mtag;
+  char line[50000], today[32];
+  char *l, *p;
+  time_t d;
+  struct tm *time_struct;
+
+  FILE *df, *tf;
+  int *meta;
+
+  putenv("TZ=NFT-1DFT");
+  d = time(NULL);
+  time_struct = localtime(&d);
+  strftime(today, 16, "%y%m%d", time_struct);
+
+  mrec = malloc(sizeof(*mrec));
+
+  mrec->marcline = malloc(100000);
+  mrec->partitle = malloc(10000);
+  mrec->subtitle = malloc(10000);
+  mrec->year     = malloc(1000);
+  mrec->url      = malloc(1000);
+  mrec->fmat     = malloc(1000);
+  mrec->s008     = malloc(41);
+
+  mrec->ncreators = 0;
+  mrec->ntitles   = 0;
+  *mrec->marcline = 0;
+  *mrec->subtitle = 0;
+  *mrec->partitle = 0;
+  *mrec->year     = 0;
+  *mrec->url      = 0;
+  *mrec->fmat     = 0;
+  strcpy(mrec->s008, "                                        ");
+
+  meta = malloc(sizeof(int));
+
+  tf = (FILE *) NULL;
+
+
+/* Open inputfile */
+
+  df = fopen(dfile, "r");
+  if (!df)
+    return 0;                            /* Error: Unable to read data */
+
+
+
+/* Open tracefile */
+
+   if (*tfile)
+   {
+     tf = fopen(tfile, "w");
+     if (!tf)
+     {
+       fclose(df);
+       return 0;                         /* Error: Unable to create trace */
+     }
+   }
+
+   *meta = FALSE;
+
+
+/* Reads the file */ 
+
+
+   while (l = fgets(line, 9999, df))
+   {
+
+/*   Remove trailing LF and / or CR     */
+
+     while ( (l[strlen(l) - 1] == '\n') || (l[strlen(l) - 1] == '\r') )
+       l[strlen(l) -1] = '\0';
+
+
+/*   printf("... main  %s\n",l);                             */ 
+
+/*   Stops reading file if "</head" or "<body" is encountered  */
+
+     p = cstr(l, (char *) "</head");
+     if (p) break;
+
+     p = cstr(l, (char *) "<body");
+     if (p) break;
+
+     mline(l, (char *) buffer, (int *) meta, mrec, tf, format);
+   }
+
+
+
+/* Check if remaining data in buffer */
+  
+   mtag = dc_parse((char *) buffer);
+
+   if (mtag) 
+   {
+     if (tf)
+     {
+       fprintf(tf, "Name  : %s\n", mtag->name   );
+       fprintf(tf, "Type  : %s\n", mtag->type   );
+       fprintf(tf, "Scheme: %s\n", mtag->scheme );
+       fprintf(tf, "Value : %s\n", mtag->value  );
+       fprintf(tf, "\n");
+     }
+     MARCmake(mtag, mrec, format);
+   }
+   free(mtag);
+
+
+/* Close files */ 
+
+   fclose(df);
+
+   if (tf)
+     fclose(tf);
+
+/* Put URL into mrec (if not present)  */
+
+   if (!*mrec->url)
+     strcpy(mrec->url, url);
+
+/* Put date into 008 */
+
+   put008(mrec->s008, today, F008_DATE_ENTERED);
+   put008(mrec->s008, "s", F008_TYPE_OF_DATE);
+
+   switch (format)
+   {
+     case ISMARC  :
+     {
+       put008(mrec->s008, "k", F008_FORM_OF_PUBLICATION);
+       break;
+     }
+   }
+
+/* Tidy up the MARC buffer                                               */
+
+   MARCtidy(mrec, buffer, format);
+
+   return 1;
+}
Index: /gsdl/stable/runtime-src/packages/d2m/D2Mmain.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/D2Mmain.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/D2Mmain.c	(revision 20131)
@@ -0,0 +1,246 @@
+/* ------------------------------------------------------------------- */
+/* D2Mmain   : standalone program for DC -> MARC conversion            */
+/*                                                                     */
+/* Syntax    : d2main [File] [Options]                                 */
+/*                                                                     */
+/* File      : This may be a local filename, or a URL (which is        */
+/*             recognized by the "http://" prefix). When a URL,        */
+/*             the remote file will be fetched using the builtin       */
+/*             HTTP "client".                                          */
+/*                                                                     */
+/* Options   : -l                       : Format = line format         */
+/*                                        (Default is ISO 2709)        */
+/* Options   : -f [filename]            : Outputfile                   */
+/*                                        (Default is stdout)          */
+/* Options   : -m [marcformat]          : Marcformat (upper case)      */
+/*                                        (Default is NORMARC)         */
+/* Options   : -t [filename]            : Tracefile                    */
+/*                                        (Default is no trace)        */
+/*                                                                     */
+/* Return    : 0 : OK                                                  */
+/*             1 : Syntax error (no parms != 2)                        */
+/*             2 : Illegal MARC format                                 */
+/*             3 : Cannot open output file                             */
+/*             8 : Error in MARC conversion                            */
+/*             9 : URL not found                                       */
+/*                                                                     */
+/* Author    : Ole Husby                                               */
+/* Updated   : 1998-09-30                                              */
+/* ------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <unistd.h>
+#include "d2m.h"
+
+
+
+
+
+/* ------------------------------------------------------------------- */
+/* main() program                                                      */
+/* ------------------------------------------------------------------- */
+
+int main (int argc, char **argv)
+{
+  int rc, i, f2709, tracing, argtype, mformat, marcfile;
+  int linel, llen, slen;
+
+  FILE *df, *of;
+  char dfilename[64], tfilename[64], ofilename[64], line[50000];
+  char *pq, *p, *q, pre[16], *l, *u;
+  char marcformat[64], url[1000];
+  char buffer[50000];
+
+  char recstatus = 'n';
+  char rectype   = 'm';
+  char biblevel  = ' ';
+
+  enum options {OPT_NONE, OPT_FILE, OPT_TRAC, OPT_MARC};
+
+
+/* Initialize */
+
+  of = stdout;
+  *url = *ofilename = 0;
+  strcpy(marcformat, "NORMARC");
+
+  tracing = FALSE;
+  *tfilename = 0;
+  f2709 = TRUE;
+  marcfile = 0;
+
+  *line = 0;
+
+  linel = D2M_LINELEN;
+  if (!linel)
+    linel = 80;
+
+  if (linel > 200)
+    linel = 200;
+
+  llen = linel - 9;
+  slen = linel - 30;
+  if (slen < 10)
+    slen = 10;
+
+
+/* Read command line arguments */
+
+  if (argc < 2)
+  { 
+    printf(" Syntax    : d2main [File] [Options]\n\n");
+    printf(" File      : This may be a local filename, or a URL (which is\n");
+    printf("             recognized by the \"http://\" prefix). When a URL,\n");
+    printf("             the remote file will be fetched using the builtin\n");
+    printf("             HTTP \"client\".\n\n");
+    printf(" Options   : -l                       : Format = line format\n");
+    printf("                                        (Default is ISO 2709)\n");
+    printf(" Options   : -f [filename]            : Outputfile\n");
+    printf("                                        (Default is stdout)\n");
+    printf(" Options   : -m [marcformat]          : Marcformat (upper case)\n");
+    printf("                                        (Default is NORMARC)\n");
+    printf(" Options   : -t [filename]            : Tracefile\n");
+    printf("                                        (Default is no trace)\n\n");
+    printf(" Return    : 0 : OK\n");
+    printf("             1 : Syntax error\n");
+    printf("             2 : Illegal MARC format\n");
+    printf("             3 : Cannot open output file\n");
+    printf("             8 : Error in MARC conversion\n");
+    printf("             9 : URL not found\n");
+    exit(1);
+  }
+
+  strcpy(dfilename, argv[1]);
+
+
+/* Get options                                                         */
+
+  if (argc > 2)
+  {
+    argtype = OPT_NONE;
+
+    for (i = 1; i < argc; i++)
+    {
+      if (argtype == OPT_FILE)
+      {
+        strcpy(ofilename, argv[i]);
+        argtype = OPT_NONE;
+      }
+      else if (argtype == OPT_TRAC)
+      {
+        strcpy(tfilename, argv[i]);
+        tracing = TRUE;
+        argtype = OPT_NONE;
+      }
+      else if (argtype == OPT_MARC)
+      {
+        strcpy(marcformat, argv[i]);
+        argtype = OPT_NONE;
+      }
+      else if (strcmp(argv[i], "-l") == 0)
+      {
+        f2709 = FALSE;
+        argtype = OPT_NONE;
+      }
+      else if (strcmp(argv[i], "-m") == 0)
+         argtype = OPT_MARC;
+      else if (strcmp(argv[i], "-f") == 0)
+         argtype = OPT_FILE;
+      else if (strcmp(argv[i], "-t") == 0)
+         argtype = OPT_TRAC;
+      else
+        argtype = OPT_NONE;
+    }
+  }
+
+/* Verify MARC format */
+
+  if (strncasecmp(marcformat, "US", 2) == 0)
+    mformat = USMARC;
+  else if (strncasecmp(marcformat, "DAN", 3) == 0)
+    mformat = DANMARC;
+  else if (strncasecmp(marcformat, "FIN", 3) == 0)
+    mformat = FINMARC;
+  else if (strncasecmp(marcformat, "IS", 2) == 0)
+    mformat = ISMARC;
+  else if (strncasecmp(marcformat, "NOR", 3) == 0)
+    mformat = NORMARC;
+  else if (strncasecmp(marcformat, "SWE", 3) == 0)
+    mformat = SWEMARC;
+  else 
+    exit(2);
+
+
+/* Fetch URL if remote file  */
+
+  if (strncmp(dfilename, "http://", 7) == 0)
+  {
+    strcpy(url, dfilename);
+    sprintf(dfilename, "%s.%d", D2M_TEMPFILE, getpid());
+    rc = wfetch(&url, &dfilename);
+    if (!rc)
+    {
+      remove(dfilename);
+      exit(9);
+    }
+    if (rc == 2)
+      marcfile = 1;
+  }
+
+
+
+
+/* Convert into buffer (line format)  */
+
+  if (marcfile)
+    rc = M2Mconv((char *) dfilename, (char *) buffer,
+                (char *) tfilename, mformat);
+  else
+    rc = D2Mconv((char *) dfilename, (char *) buffer,
+                (char *) tfilename, (char *) url, mformat);
+
+  if (!rc)
+  {
+    fclose(df);
+    exit(8);
+  }
+
+  if (*url)
+    remove(dfilename);
+
+
+/* Prepare for output      */
+
+   if (*ofilename)
+   {
+     of = fopen(ofilename, "w");
+     if (!of)
+       exit(3);
+   }
+   else
+     of = stdout;
+
+
+/* Write output, if necessary converted to ISO 27809   */
+
+   if (f2709)
+     fprintf(of, "%s", 
+       (char *) MARC2709(buffer, 0, 6, recstatus, rectype, biblevel));
+
+   else
+   {
+     l = strtok((char *) buffer, "\n");
+
+     while (l)
+     {
+       write_field(l, of, linel, llen, slen);
+       l = strtok(NULL, "\n");
+     }
+   }
+
+   if (*ofilename)
+     fclose(of);
+}
Index: /gsdl/stable/runtime-src/packages/d2m/M2Mconv.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/M2Mconv.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/M2Mconv.c	(revision 20131)
@@ -0,0 +1,84 @@
+/* ------------------------------------------------------------------- */
+/* M2Mconv   : Convert an ISO 2709 record into MARC format             */
+/* Author    : Ole Husby, BIBSYS                                       */
+/* Updated   : 1998-09-30                                              */
+/* ------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <unistd.h>
+
+
+
+
+int M2Mconv(char *dfile, char *buffer, char *tfile, int format)
+{
+  char mtype[16], line[50000];
+  char *l, *p, *bf;
+  int lines;
+  FILE *df, *tf;
+
+  tf = (FILE *) NULL;
+  strcpy(mtype, "bibsys");
+
+
+/* Open inputfile */
+
+  df = fopen(dfile, "r");
+  if (!df)
+    return 0;                            /* Error: Unable to read data */
+
+
+
+/* Open tracefile */
+
+   if (*tfile)
+   {
+     tf = fopen(tfile, "w");
+     if (!tf)
+     {
+       fclose(df);
+       return 0;                         /* Error: Unable to create trace */
+     }
+   }
+
+
+/* Reads the file */ 
+
+   lines = 0;
+
+   while (l = fgets(line, 49999, df))
+   {
+/*   Remove trailing lf or cr     */
+
+     while ( (l[strlen(l) - 1] == '\n') || (l[strlen(l) - 1] == '\r') )
+       l[strlen(l) -1] = '\0';
+
+     lines++;
+     if (lines > 1)
+       break;                            /* Error: Not a 2709 file       */
+     p = l;
+   }
+
+
+/* Close files */ 
+
+  fclose(df);
+
+  if (tf)
+    fclose(tf);
+
+  if ( lines > 1 )
+    return 0;
+
+
+/* Convert to line format */
+
+  bf = (char *) marc2line(p, mtype);
+
+  strcpy(buffer, bf);
+
+  return 1;
+}
Index: /gsdl/stable/runtime-src/packages/d2m/MARC2709.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/MARC2709.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/MARC2709.c	(revision 20131)
@@ -0,0 +1,495 @@
+/* ------------------------------------------------------------------- */
+/* MARC2709  : Converts a "line format MARC record" into ISO 2709      */
+/*                                                                     */
+/*             Input string requirements:                              */
+/*             1. New MARC tag is indicated by MARC tag in pos 1-3     */
+/*                (may be preceded by *). Indicator follows in next 2  */
+/*                bytes.                                               */
+/*             2. Continuation line is indicated by blank in col 1     */
+/*             3. End-of-record (^) may or may not be present          */
+/*                                                                     */
+/* author    : Ole Husby                                               */
+/* updated   : 1998-09-30                                              */
+/* ------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#define NORMARC                                12
+
+#define SUBFIELD_CODE                          "\x1f"
+#define FIELD_TERMINATOR                       "\x1e"
+#define RECORD_TERMINATOR                      "\x1d"
+
+#define INDICATOR_COUNT                        '2'
+#define SUBFIELD_CODE_COUNT                    '2'
+#define LENGTH_OF_LENGTH_OF_FIELD              '4'
+#define LENGTH_OF_STARTING_CHARACTER_POSITION  '5'
+#define UNUSED                                 "   "
+#define TAG001                                 "001"
+#define TAG008                                 "008"
+#define SKIP                                     41
+
+static char out_record[10240],
+	      leader[24+1],
+	      directory[10240],
+	      field_001[32], 
+	      field_008[40+2],
+	      data_field[10240];
+
+
+static char logline[128];
+static char rstr[6], dollar, dollarstring[2];
+static int skip;
+
+static char direlem[300][12+1];
+static int dircntr;
+
+union LDR   {
+   char ldr_string[24+1];
+   struct {
+      char record_length[5],
+      record_status,
+      record_type,
+      bibliographic_level,
+      unused1[2],
+      indicator_count,
+      subfield_code_count,
+      base_adress[5],
+      unused2[3],
+      entry1,
+      entry2,
+      entry3,
+      entry4;
+   } ltab;
+ } ldr;
+
+static int startet = 0;
+
+
+
+/* ------------------------------------------------------------------- */
+/* Compare function for qsort                                          */
+/* ------------------------------------------------------------------- */
+
+int cmp(const void *a, const void *b)
+{
+   return strcmp((char*)a, (char*)b);
+}
+
+
+
+
+/* ------------------------------------------------------------------- */
+/* Convert integer to string of fixed length. Right justified padded   */
+/* with zeros. Returns NULL if error                                   */
+/* ------------------------------------------------------------------- */
+
+char *itoal(int n, int len)
+{
+   char *r;
+   r = (char *) rstr;
+
+   switch (len)
+   {
+      case  4 : sprintf(r, "%04d", n); break;
+      case  5 : sprintf(r, "%05d", n); break;
+      default : return NULL;                       
+   }
+
+   r[len] = '\0';
+
+   return r;
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* One 001 subfield is put into field_001                              */
+/* ------------------------------------------------------------------- */
+
+static int make_001(char *data, char subfield)
+{
+   int len;
+
+   startet = 0;
+   switch (subfield)
+   {
+      case ' ' : break;
+      case 'a' : break;
+      default  : return 1;
+   }
+
+   while (data[0] == ' ') data++;
+   strcpy(field_001, data);
+
+   len = strlen(data) + 1;
+   skip = SKIP + len;
+
+   sprintf(directory, "00100%2d000000080041000%2d", len, len);
+   return 1;
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* One subfield string is appended to data_field                       */
+/* ------------------------------------------------------------------- */
+
+static int out_subfield(char *data, char *ftag, char subfield, char nextsubfield)
+{
+   int len, subint;
+   char subreplace, *p, *up;
+
+   while (data[strlen(data) -1] == ' ') 
+          data[strlen(data) -1] = '\0';            /* strip trailing blanks */
+
+   if (subfield == '3')                            /* always discard $3     */
+      return 1;
+
+   if (strcmp(ftag, TAG001) == 0)                  /* 001 data treatment     */
+   {
+      make_001(data, subfield);
+      return 1;
+   }
+   
+   if (strcmp(ftag, TAG008) == 0)                  /* 008 data treatment     */
+   {
+      strncpy(field_008, data, strlen(data)); 
+      return 1;
+   }
+   
+   if (subfield != ' ')                             /* handle subfield code  */
+   {
+      strcat(data_field, SUBFIELD_CODE);
+      len = strlen(data_field);
+      data_field[len] = subfield;
+      data_field[len + 1] = '\0';
+   }
+
+   while(data[0] == ' ') data++;                   /* strip leading blanks   */
+   if (!data) return 0;
+
+   strcat(data_field, data);                       /* append data            */
+   
+   return 1;
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* One MARC field is split into subfields and given to output          */
+/* ------------------------------------------------------------------- */
+
+static int out_field(char *data, char *ftag, char *find)
+{
+   char lnumber[5], snumber[6];
+   int fStart, fLen, moresubs;
+   char subfield[5120], *sub, subcode, *nextsub, nextsubcode;
+   char *v, subfield_v[32];
+
+   if (!startet) return 1;
+
+   if ((strncmp(ftag, "00", 2) == 0) &&
+       (strcmp(ftag, TAG001) != 0) &&
+       (strcmp(ftag, TAG008) != 0))
+      return 1;
+
+   fStart = strlen(data_field);
+   
+   if (strncmp(data, "  $", 3) == 0) data +=2;   /* possible if 008         */
+
+   if (data[0] != dollar)                        /* Dollar sign missing     */
+   {
+      if (strncmp(ftag,"00",2) != 0) return 0;   /* only allowed if tag=00x */
+	 
+      if (strcmp(ftag, TAG001) == 0)             /* 001: skip leading blanks */
+         while (data[0] == ' ') 
+            data++;  
+
+      subcode = ' ';
+      nextsubcode = ' ';
+
+      if (!out_subfield(data, ftag, subcode, nextsubcode)) 
+	 return 0;
+      return 1;
+   }
+
+   else
+   {
+      data++;
+
+      if (!data) return 0;
+
+      if (strncmp(ftag,"00",2) != 0)             /* append indicators       */
+         strcat(data_field, find);
+      
+      sub = strtok(data, dollarstring);          /* first subfield          */
+      if (!sub)
+         return 0;
+
+/*    printf("--- %s\n", sub); */
+
+      subcode = sub[0];
+      sub++;
+
+      moresubs = 1;
+
+      while (moresubs)                           /* loop while more subflds */
+      {  
+         nextsub = strtok(NULL, dollarstring);   /* next subfld             */
+         if (nextsub) 
+         {
+/*          printf("--- %s\n", nextsub); */
+	    nextsubcode = nextsub[0];
+	    nextsub++;
+         }
+         else
+            nextsubcode = ' ';
+
+         if (sub)
+         {
+	    if (!out_subfield(sub, ftag, subcode, nextsubcode)) 
+	       return 0;
+/*          printf("Denne |%c| Neste |%c|\n", subcode, nextsubcode);  */
+         }
+
+         if (nextsub)
+         {
+            subcode = nextsubcode;
+            sub = nextsub;
+         }
+         else
+            moresubs = 0;
+      }
+   }
+
+   if (strcmp(ftag,TAG001) == 0 || strcmp(ftag,TAG008) == 0)              
+      return 1;                                  /* directory ready         */
+
+   strcat(data_field, FIELD_TERMINATOR);         /* terminate data field   */
+   fLen = strlen(data_field) - fStart;           /* length of field        */
+
+   strcpy(lnumber,itoal(fLen,4));                /* convert to 4digit str  */
+   if (!lnumber) return 0;
+   strcpy(snumber,itoal(fStart + skip,5));       /* convert start          */
+   if (!snumber) return 0;
+
+   strcpy(direlem[dircntr], ftag);               /* start direlem with tag */
+   strcat(direlem[dircntr], lnumber);            /* append length to dir   */
+   strcat(direlem[dircntr], snumber);            /* append start to dir    */
+   dircntr++;
+
+   return 1;
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* Main program                                                        */
+/* ------------------------------------------------------------------- */
+
+char *MARC2709(char *record, int last, int first, char recstatus, 
+  char rectype, char biblevel)          
+{
+   static char buffer[10240], field_data[5120], tag[4], ind[3];
+   char        alen[3], *cp, *buf = buffer, *cq, logline[128];
+   int                  prelen, ii; 
+   int                  lastchar, Last, First, x, more;
+   int			SOF, digits, newField;
+
+   char test[6];
+
+   strcpy(buf, record);
+
+   Last = First = 0;                        /* initialize             */
+   if (last > 0)                            /* Last : linelength if   */
+   {                                        /*        fixed           */
+      Last = last;                          /* First: starting col    */
+      First = first;                        /*        for cont. line  */
+   }
+  
+   prelen = 5;
+   dollar = '$';
+   strcpy(dollarstring, "$");
+
+   data_field[0] = '\0';
+   directory[0]  = '\0';
+   strcpy(field_001, "         ");
+   strcpy(field_008, "                                        ");
+   out_record[0] = '\0';
+   dircntr       = 0;
+   startet       = 0;
+
+   /* initialize directory  with 9 bytes for 001 */
+
+   sprintf(directory, "001001000000008004100010", alen, alen);
+   skip = SKIP + 10;
+
+   more = 1; 
+   while (more)                                       /* loop until EOR  */ 
+   {
+      x = 0;                                          /* x counts bytes  */
+
+      for (cp = buf; *cp && *cp != '\n'; cp++) x++;   /* read until LF   */
+
+      if (!*cp)                                       /* EOR             */
+        more = 0; 
+      else
+        cp++;
+
+      SOF = 0;
+
+      if (buf[0] == '^') break;                       /* "EOR-line"      */
+      if (buf[0] == '*')                              /* skip leading *  */
+      {
+	 buf++;
+	 x--;
+         SOF = 1;
+      }
+
+      if (x == 0) continue;                           /* empty line     */
+
+      digits = 1;                                     /* test if first 3     */ 
+      for (ii = 0; ii < 3; ii++)                      /* bytes are digits    */
+         if (!isdigit(buf[ii]))
+         {
+            digits = 0;
+            break;
+         }
+         
+      newField = 0;     
+
+      if (SOF)
+      {
+	if (!digits) continue;                      /* illegal line        */
+        else newField = 1;
+      } 
+      else
+	 if (digits) newField = 1;
+
+
+      if (newField)                                  /* start of new field   */
+      {
+	 if (!out_field(field_data, tag, ind))       /* output prev. field   */
+	    return NULL;
+
+	 startet = 1;
+	 field_data[0] = '\0';                       /* reset field buffer   */
+	 strncpy(tag, buf, 3);                       /* keep MARC tag        */
+	 buf += 3;
+	 x -=3;
+     
+         if (strncmp(tag, "00", 2) != 0) 
+         {
+            strncpy(ind, buf, 2);                 /* keep indicator       */
+            buf += 2;                             /* if not control field */
+            x -= 2;
+         }
+
+	 strncat(field_data, buf, x);             /* keep data               */
+        
+	   					/* strip trailing blanks   */
+	 while (field_data[strlen(field_data) -1] == ' ')
+	 {
+	    field_data[strlen(field_data) -1] = '\0';
+	    x--;
+	 }
+
+	 if (Last && x == (Last - prelen))           /* full line            */
+            lastchar = 1;
+         else 
+            lastchar = 0;
+      }
+
+      else                                     /* continuation line     */
+      {
+	if (Last)
+	{
+	   cq  = buf + First - 1;              /* skip fixed nmbr chars */
+	   x -= (First - 1); 
+	   if (!lastchar && cq[0] != ' '       /* and insert one blank  */
+	       && cq[0] != dollar)
+	      strcat(field_data, " ");         /* if needed             */
+	}
+	else
+	{
+	   for (cq = buf; *cq == ' '; cq++) x--;  /* skip leading blanks   */
+	   strcat(field_data, " ");               /* insert one blank      */
+	}
+
+	strncat(field_data, cq, x);            /* append data           */
+                                               /* strip trail. blanks   */
+        while (field_data[strlen(field_data) -1] == ' ')
+        {
+	   field_data[strlen(field_data) -1] = '\0';
+	   x--;
+	}
+
+	if (Last && x == (Last - 5))           /* full line            */
+	   lastchar = 1;
+        else lastchar = 0;
+        
+      }
+
+      while (field_data[strlen(field_data) -1] == ' ')
+         field_data[strlen(field_data) - 1] = '\0'; /* rm trailing blanks */
+      buf = cp;
+   }
+
+   if (!out_field(field_data, tag, ind))       /* output last field     */
+      return NULL;
+
+                                               /* terminate field_001   */
+   strcat(field_001, FIELD_TERMINATOR); 
+
+   field_008[40] = '\0';                       /* terminate field_008   */
+   strcat(field_008, FIELD_TERMINATOR); 
+
+					       /* sort directory elem.  */
+   qsort ((void *) direlem, dircntr, sizeof(direlem[0]), cmp); 
+   for (ii = 0; ii < dircntr; ii++)
+      strcat(directory, direlem[ii]);          /* append to directory   */
+
+   strcat(directory, FIELD_TERMINATOR);        /* terminate dictionary  */ 
+   
+   strcat(data_field, RECORD_TERMINATOR);      /* terminate data        */
+
+   x = 24 + strlen(directory);                 /* construct leader      */
+   
+   strcpy(test, itoal(x,5));
+
+   strncpy(ldr.ltab.base_adress, test, 5);
+
+   x += (strlen(data_field)
+       + strlen(field_001)
+       + strlen(field_008));
+
+   strcpy(test, itoal(x,5));
+   
+   strncpy(ldr.ltab.record_length, test, 5);
+   
+   ldr.ltab.record_status = recstatus;
+   ldr.ltab.record_type = rectype;
+   ldr.ltab.bibliographic_level = biblevel;
+   ldr.ltab.indicator_count = INDICATOR_COUNT;
+   ldr.ltab.subfield_code_count = SUBFIELD_CODE_COUNT;
+   strncpy(ldr.ltab.unused1,UNUSED,2);
+   strncpy(ldr.ltab.unused2,UNUSED,3);
+   ldr.ltab.entry1 = LENGTH_OF_LENGTH_OF_FIELD;
+   ldr.ltab.entry2 = LENGTH_OF_STARTING_CHARACTER_POSITION;
+   ldr.ltab.entry3 = '0';     
+   ldr.ltab.entry4 = '0';     
+
+   ldr.ldr_string[24] = '\0';
+
+   strcpy(out_record, ldr.ldr_string);          /* put together record  */
+   strcat(out_record, directory);
+   strcat(out_record, field_001);
+   strcat(out_record, field_008);
+   strcat(out_record, data_field);
+ 
+   return out_record; 
+}
Index: /gsdl/stable/runtime-src/packages/d2m/MARCmake.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/MARCmake.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/MARCmake.c	(revision 20131)
@@ -0,0 +1,33 @@
+/* ------------------------------------------------------------------- */
+/* MARCmake  : Convert a metatag struct to MARC and add it to the      */
+/*             marcrecord struct.                                      */
+/*                                                                     */
+/*             This is where the format-dependent conversion           */
+/*             program is selected.                                    */
+/*                                                                     */
+/* Author    : Ole Husby                                               */
+/* Updated   : 1998-09-30                                              */
+/* ------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include "d2m.h" 
+
+
+
+int MARCmake(struct metatag *mt, struct marcrec *mr, int format)
+{
+  char pre[64], creator_tag[4];
+
+  if (format == DANMARC)
+    return danMARC(mt, mr);
+  else if (format == FINMARC)
+    return finMARC(mt, mr);
+  else if (format == ISMARC)
+    return isMARC(mt, mr);
+  else if (format == USMARC)
+    return usMARC(mt, mr);
+  else if (format == SWEMARC)
+    return sweMARC(mt, mr);
+  else
+    return norMARC(mt, mr);
+}
Index: /gsdl/stable/runtime-src/packages/d2m/MARCtidy.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/MARCtidy.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/MARCtidy.c	(revision 20131)
@@ -0,0 +1,147 @@
+/* ------------------------------------------------------------------- */
+/* MARCtidy  : Tidying up of MARC record, building the line format     */
+/*             record.                                                 */
+/*                                                                     */
+/* Syntax    : MARCtidy(marcrec *mrec, char *buf, int format)          */
+/*                                                                     */
+/*             The preliminary MARC data are converted from the        */
+/*             mrec struct to the buf line format buffer.              */
+/*                                                                     */
+/*             The main data is in mrec->marcline, while some          */
+/*             additional data (year, URL ...) are kept in separat     */
+/*             variables to be added in.                               */
+/*                                                                     */
+/* NOTE      : The behaviour of this program i sto some extent         */
+/*             depending on the format argument!                       */
+/*                                                                     */
+/* Author    : Ole Husby, BIBSYS                                       */
+/* Updated   : 1998-09-30                                              */
+/* ------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include "d2m.h"
+
+
+
+void  nline(char *p, char *l, char *buf)
+{
+   strcat(buf, p);
+   if (strncmp(p, "00", 2) != 0)
+     strcat(buf, " ");
+   strcat(buf, l);
+   strcat(buf, "\n");
+}
+
+
+
+void MARCtidy(struct marcrec *mrec, char *buf, int format)
+{
+
+   char *p, *u, *l;
+   char pre[64], line[10000];
+
+   p = (char *) &pre;
+   l = (char *) &line;
+
+   *buf = 0;
+
+   strcpy(p, "008");
+   strcpy(l, mrec->s008);
+   nline(p, l, buf);
+
+   u = strtok(mrec->marcline, "\n");
+   while (u && *u)
+   {
+      if (strlen(u) > 7)
+      {
+        *p = 0;
+        strncat(p, u, 7);
+        strcpy(l, u + 8);
+        nline(p, l, buf);
+
+
+/*      Add 245 subfields after $a */
+
+        if ( (strncmp(p, "245", 3) == 0) && (strncmp(p + 5, "$a", 2) == 0) )
+        {
+          if ( ( format == NORMARC ) && ( *mrec->subtitle) )
+          {
+            strcpy(p, "     $b");
+            strcpy(l, mrec->subtitle);
+            nline(p, l, buf);
+          }
+          if ( *mrec->partitle )
+          {
+            if ( format == FINMARC || format == DANMARC ) 
+            {
+              strcpy(p, "    ");
+              strcpy(l, mrec->partitle);
+              nline(p, l, buf);
+            }
+            if ( format == ISMARC ) 
+            {
+              strcpy(l, mrec->partitle);
+              nline(p, l, buf);
+            }
+          }
+        } 
+
+/*      Add year as 260 $c after $b                                    */
+
+        if ( (strncmp(p, "260", 3) == 0) && (strncmp(p + 5, "$b", 2) == 0) )
+        {
+          if (*mrec->year)
+          {
+            strcpy(p, "     $c");
+            strcpy(l, mrec->year);
+            nline(p, l, buf);
+            *mrec->year = 0;
+          }
+        } 
+      }
+      u = strtok(NULL, "\n");
+   }
+
+/* Add year as 260 $c if not aleady done                               */
+
+   if (*mrec->year)
+   {
+     strcpy(p, "260  $c");
+     strcpy(l, mrec->year);
+     nline(p, l, buf);
+   }
+
+/* Add parallel title in spearate field  */
+
+   if ( *mrec->partitle && ( format == ISMARC ) ) 
+   {
+     strcpy(p, "24630$c");
+     strcpy(l, mrec->partitle);
+     nline(p, l, buf);
+   }
+
+
+/* Add URL as 856 $u                                                 */
+
+   if (*mrec->url)
+   {
+     strcpy(p, "856  $u");
+     strcpy(l, mrec->url);
+     nline(p, l, buf);
+
+/* Add format as $q                                                    */
+
+     if (*mrec->fmat)
+     {
+       strcpy(p, "     $q");
+       strcpy(l, mrec->fmat);
+       nline(p, l, buf);
+     }
+   }
+
+}
Index: /gsdl/stable/runtime-src/packages/d2m/Makefile.in
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/Makefile.in	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/Makefile.in	(revision 20131)
@@ -0,0 +1,45 @@
+# ///////////////// d2m : Dublin Core to MARC converter /////////////////////
+#
+#
+# Modified for Greenstone kjdon May 2005.
+# Used by z3950server
+
+CC = @CC@
+AR = ar
+RANLIB = @RANLIB@
+
+o = .@U@o
+
+# This may have to uncomment this on solaris ???
+# LIBS = -lsocket -lnsl
+
+LIB_OBJS = MARC2709.o MARCtidy.o usMARC.o util.o
+
+all: libd2m.a
+
+libd2m.a: $(LIB_OBJS)
+	rm -f libd2m.a
+	$(AR) cru libd2m.a $(LIB_OBJS)
+	$(RANLIB) libd2m.a
+
+
+MARCtidy.o: MARCtidy.c d2m.h
+	$(CC) -c MARCtidy.c
+
+MARC2709.o: MARC2709.c d2m.h
+	$(CC) -c MARC2709.c
+
+util.o: util.c d2m.h
+	$(CC) -c util.c 
+
+usMARC.o: usMARC.c d2m.h
+	$(CC) -c usMARC.c
+
+install:
+
+clean:
+	rm -f *.o libd2m.a
+
+distclean: clean
+	rm -f Makefile config.h
+
Index: /gsdl/stable/runtime-src/packages/d2m/Makefile.orig
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/Makefile.orig	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/Makefile.orig	(revision 20131)
@@ -0,0 +1,111 @@
+# ///////////////// d2m : Dublin Core to MARC converter /////////////////////
+#
+# The basic conversion (reading a file and producing a MARC record)
+# is performed by D2Mconv.c
+#
+# On top of D2Mconv.c is built 2 applications:
+#
+# d2m   : A CGI version
+#         (See documentation in main program D2Mcgi.c)
+# d2main: A command line (standalone version)
+#         (See documentation in main program D2Mmain.c)
+#
+# Both applications are capable of reading from a local file or a
+# remote file using builtin HTTP client services. 
+#
+# (You can compile a version of d2main without HTTP ability by
+#   make d2main-nosock 
+# )
+#
+# Both applications has the added ability to read a 2709 MARC record
+# instead of DC metadata, using M2Mconv.c to perform the conversion.
+# (This is not a MARC converter with the ability to convert between
+# MARC formats, just between "presentation syntaxes".
+#
+# 1998-10-15 Ole Husby
+#
+
+CC = cc 
+
+# This may have to uncomment this on solaris:
+# LIBS = -lsocket -lnsl
+
+OBJ = D2Mconv.o M2Mconv.o marc2line.o util.o MARC2709.o MARCmake.o MARCtidy.o dc_parse.o
+OBJ_MARC = danMARC.o finMARC.o isMARC.o norMARC.o sweMARC.o usMARC.o
+OBJ_SOCK = wfetch.o htget.o
+OBJ_NOSOCK = wfetch-l.o
+
+all: d2m d2main
+
+d2m: D2Mcgi.o $(OBJ) $(OBJ_MARC) $(OBJ_SOCK) 
+	@echo "------------------- Compiling d2m -------------------------------" 
+	$(CC) D2Mcgi.o $(OBJ) $(OBJ_MARC) $(OBJ_SOCK) -o d2m $(LIBS) 
+
+d2main: D2Mmain.o $(OBJ) $(OBJ_MARC) $(OBJ_SOCK) 
+	@echo "------------------- Compiling d2main ----------------------------" 
+	$(CC) D2Mmain.o $(OBJ) $(OBJ_MARC) $(OBJ_SOCK) -o d2main $(LIBS) 
+
+d2main-nosock: D2Mmain.o $(OBJ) $(OBJ_MARC) $(OBJ_NOSOCK) 
+	@echo "------------------- Compiling d2main (no sockets) ---------------" 
+	$(CC) D2Mmain.o $(OBJ) $(OBJ_MARC) $(OBJ_NOSOCK) -o d2main $(LIBS) 
+
+
+D2Mcgi.o: D2Mcgi.c d2m.h
+	$(CC) -c D2Mcgi.c
+
+D2Mmain.o: D2Mmain.c d2m.h
+	$(CC) -c D2Mmain.c
+
+D2Mconv.o: D2Mconv.c d2m.h
+	$(CC) -c D2Mconv.c
+
+M2Mconv.o: M2Mconv.c
+	$(CC) -c M2Mconv.c
+
+marc2line.o: marc2line.c 
+	$(CC) -c marc2line.c
+
+MARCmake.o: MARCmake.c d2m.h
+	$(CC) -c MARCmake.c
+
+MARCtidy.o: MARCtidy.c d2m.h
+	$(CC) -c MARCtidy.c
+
+MARC2709.o: MARC2709.c d2m.h
+	$(CC) -c MARC2709.c
+
+dc_parse.o: dc_parse.c d2m.h
+	$(CC) -c dc_parse.c
+
+util.o: util.c d2m.h
+	$(CC) -c util.c 
+
+danMARC.o: danMARC.c d2m.h
+	$(CC) -c danMARC.c
+
+finMARC.o: finMARC.c d2m.h
+	$(CC) -c finMARC.c
+
+isMARC.o: isMARC.c d2m.h
+	$(CC) -c isMARC.c
+
+norMARC.o: norMARC.c d2m.h
+	$(CC) -c norMARC.c
+
+sweMARC.o: sweMARC.c d2m.h
+	$(CC) -c sweMARC.c
+
+usMARC.o: usMARC.c d2m.h
+	$(CC) -c usMARC.c
+
+wfetch.o: wfetch.c
+	$(CC) -c wfetch.c
+
+wfetch-l.o: wfetch-l.c
+	$(CC) -c wfetch-l.c
+
+htget.o: htget.c 
+	$(CC) -c htget.c 
+
+clean:
+	rm -f *.o d2m d2main
Index: /gsdl/stable/runtime-src/packages/d2m/README.html
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/README.html	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/README.html	(revision 20131)
@@ -0,0 +1,159 @@
+<html><head><title>
+d2m v0.2
+</title>
+</head>
+
+<body bgcolor="#ffffcc">
+
+<font face="Comic Sans MS">
+<h1 align=center>d2m : A Dublin Core to MARC converter</h1>
+
+<div align=center>
+
+version 0.2<br>
+1998-10-14<br>
+Ole Husby<br>
+BIBSYS<br>
+ole.husby@bibsys.no
+</div>
+</font>
+
+
+<h2>1. Introduction</h2>
+
+This software is part of the results from the Nordic Metadata project.
+(See <a href="http://linnea.helsinki.fi/meta/">
+http://linnea.helsinki.fi/meta/</a>).
+
+<p>
+ 
+This version is a "pre-release". It is not really ready for distribution.
+All the customary disclaimers apply!
+The programs have been compiled on Solaris, AIX and Linux.
+
+
+
+<h2>2. Contents</h2>
+
+The distribution includes the following files:
+
+<table>
+<tr><td><b>README.html </b></td><td>This file</td></tr>
+<tr><td><b>Makefile    </b></td><td>Also includes some documentation</td></tr>
+<tr><td><b>d2m.h       </b></td><td>Common include file</td></tr>
+<tr><td><b>D2Mcgi.c    </b></td><td>Main program for the CGI version</td></tr>
+<tr><td><b>D2Mmain.c   </b></td><td>Main program for the standalone version</td></tr>
+<tr><td><b>D2Mconv.c   </b></td><td>Inputs file with DC metadata, outputs line MARC record</td></tr>
+<tr><td><b>M2Mconv.c   </b></td><td>Inputs file with ISO 2709 MARC record, outputs line MARC record</td></tr>
+<tr><td><b>MARC2709.c  </b></td><td>Converts from line MARC format to ISO 2709 MARC format</td></tr>
+<tr><td><b>MARCmake.c  </b></td><td>Builds a MARC struct from a DC struct. Selects one of the following :</td></tr>
+<tr><td><b>danMARC.c   </b></td><td>&nbsp;</td></tr>
+<tr><td><b>finMARC.c   </b></td><td>&nbsp;</td></tr>
+<tr><td><b>isMARC.c    </b></td><td>&nbsp;</td></tr>
+<tr><td><b>norMARC.c   </b></td><td>&nbsp;</td></tr>
+<tr><td><b>sweMARC.c   </b></td><td>&nbsp;</td></tr>
+<tr><td><b>usMARC.c    </b></td><td>&nbsp;</td></tr>
+<tr><td><b>MARCtidy.c  </b></td><td>Finishes the line MARC record from the MARC struct</td></tr>
+<tr><td><b>marc2line.c </b></td><td>Converts from ISO 2709 MARC format to line MARC format</td></tr>
+<tr><td><b>htget.c     </b></td><td>Fetches a remote file using HTTP</td></tr>
+<tr><td><b>dc_parse.c  </b></td><td>Parses an HTML <META> tag</td></tr>
+<tr><td><b>util.c      </b></td><td>Some utilities</td></tr>
+<tr><td><b>wfetch.c    </b></td><td>Small program on top of htget()</td></tr>
+<tr><td><b>wfetch-l.c  </b></td><td>Dummy version of wfetch.c, does nothing except return 0</td></tr>
+<tr><td><b>test.data   </b></td><td>A simple test file with a <meta> tag.</td></tr>
+</table>
+
+<h2>3. Compilation</h2>
+
+Unpack the d2m-v02.tar file. It will produce a directory <b>d2m-v02/</b>
+with the contents listed above.
+
+<p>
+
+Check the Makefile.
+
+<p>
+
+Type
+
+<pre>
+
+  <b>make all</b>
+
+</pre>
+
+This should produce the programs <b>d2m</b> and <b>d2main</b> . 
+
+<p>
+
+If you do not need access to remote files, or have problems compiling
+socket libraries, try to compile
+  
+<pre>
+
+  <b>make d2main-nosock</b>
+
+</pre>
+
+
+<h2>4. Use of d2main</h2>
+
+<b>d2main</b> should be ready to execute from the command line. No configuration
+or environment variables are needed.
+
+<p>
+
+If you do not enter any arguments, a short instruction will be printed.
+
+<p>
+
+The first test could be 
+
+<pre>
+
+  <b>d2main test.data -l</b>
+
+</pre>
+
+The next test could be (if d2main is not compiled using Makefile-l)
+
+<pre>
+
+  <b>d2main http://linnea.helsinki.fi/meta/ -l -m FINMARC</b>
+
+</pre>
+
+<h2>5. Use of d2m</h2>
+
+<b>d2m</b> should be used as a CGI program.
+
+<p>
+  
+A simple users guide is in D2Mcgi.c
+
+<p>
+
+See an example of use in <a href="http://www.bibsys.no/meta/d2m">
+http://www.bibsys.no/meta/d2m</a>
+
+
+
+<h2>6. Tailoring</h2>
+
+This version is not table-driven. The different MARC formats are
+treated by customized functions (norMARC.c, isMARC.c etc.). The
+selection of conversion program is performed by MARKmake.c .
+
+<p>
+
+The program MARCtidy.c is also to some degree depending of the
+MARC format. In addition there is a small sequence in D2Mconv.c
+with a special treatment for ISMARC. (It should really not be
+done there ...). Apart from this, all programs are independent on
+MARC format.
+
+<p>
+
+The supported formats are introduced in d2m.h .
+
+</body></html>
Index: /gsdl/stable/runtime-src/packages/d2m/README_GS
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/README_GS	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/README_GS	(revision 20131)
@@ -0,0 +1,14 @@
+d2m : Dublin Core to MARC converter
+Software distribution: Prerelease version
+version 0.2
+1998-10-14
+Ole Husby
+BIBSYS
+ole.husby@bibsys.no
+
+http://www.bibsys.no/meta/d2m/distr/
+
+The original Makefile that comes with d2m has been saved as Makefile.orig, and a new Makefile.in and some configure scripts have been generated for use with Greenstone.
+
+We no longer compile up the two executables, instead just compile the source into a library: libd2m.a.
+
Index: /gsdl/stable/runtime-src/packages/d2m/config.h.in
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/config.h.in	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/config.h.in	(revision 20131)
@@ -0,0 +1,107 @@
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define to 1 if you have the `alarm' function. */
+#undef HAVE_ALARM
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `gethostbyname' function. */
+#undef HAVE_GETHOSTBYNAME
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the `socket' function. */
+#undef HAVE_SOCKET
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
Index: /gsdl/stable/runtime-src/packages/d2m/configure
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/configure	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/configure	(revision 20131)
@@ -0,0 +1,4903 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for FULL-PACKAGE-NAME VERSION.
+#
+# Report bugs to <BUG-REPORT-ADDRESS>.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='FULL-PACKAGE-NAME'
+PACKAGE_TARNAME='full-package-name'
+PACKAGE_VERSION='VERSION'
+PACKAGE_STRING='FULL-PACKAGE-NAME VERSION'
+PACKAGE_BUGREPORT='BUG-REPORT-ADDRESS'
+
+ac_unique_file="danMARC.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT RANLIB ac_ct_RANLIB CPP EGREP LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures FULL-PACKAGE-NAME VERSION to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of FULL-PACKAGE-NAME VERSION:";;
+   esac
+  cat <<\_ACEOF
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <BUG-REPORT-ADDRESS>.
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+FULL-PACKAGE-NAME configure VERSION
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by FULL-PACKAGE-NAME $as_me VERSION, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers config.h"
+
+
+# Checks for programs.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+	;;
+    conftest.$ac_ext )
+	# This is the source file.
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
+    * )
+	break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  export ac_cv_exeext
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX 10.20 and later	-Ae
+# HP-UX older versions	-Aa -D_HPUX_SOURCE
+# SVR4			-Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+# Checks for libraries.
+
+# Checks for header files.
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+
+
+
+
+
+for ac_header in fcntl.h malloc.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------- ##
+## Report this to BUG-REPORT-ADDRESS ##
+## --------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((size_t *) 0)
+  return 0;
+if (sizeof (size_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_size_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_size_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+if test $ac_cv_type_size_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5
+echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6
+if test "${ac_cv_struct_tm+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <time.h>
+
+int
+main ()
+{
+struct tm *tp; tp->tm_sec;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_struct_tm=time.h
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5
+echo "${ECHO_T}$ac_cv_struct_tm" >&6
+if test $ac_cv_struct_tm = sys/time.h; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TM_IN_SYS_TIME 1
+_ACEOF
+
+fi
+
+
+# Checks for library functions.
+
+for ac_header in stdlib.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## --------------------------------- ##
+## Report this to BUG-REPORT-ADDRESS ##
+## --------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5
+echo $ECHO_N "checking for GNU libc compatible malloc... $ECHO_C" >&6
+if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_func_malloc_0_nonnull=no
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#if STDC_HEADERS || HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+char *malloc ();
+#endif
+
+int
+main ()
+{
+exit (malloc (0) ? 0 : 1);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_malloc_0_nonnull=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_func_malloc_0_nonnull=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5
+echo "${ECHO_T}$ac_cv_func_malloc_0_nonnull" >&6
+if test $ac_cv_func_malloc_0_nonnull = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MALLOC 1
+_ACEOF
+
+else
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_MALLOC 0
+_ACEOF
+
+   case $LIBOBJS in
+    "malloc.$ac_objext"   | \
+  *" malloc.$ac_objext"   | \
+    "malloc.$ac_objext "* | \
+  *" malloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;;
+esac
+
+
+cat >>confdefs.h <<\_ACEOF
+#define malloc rpl_malloc
+_ACEOF
+
+fi
+
+
+
+echo "$as_me:$LINENO: checking return type of signal handlers" >&5
+echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
+if test "${ac_cv_type_signal+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+# undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_signal=void
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_signal=int
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
+echo "${ECHO_T}$ac_cv_type_signal" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+
+for ac_func in strftime
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  # strftime is in -lintl on SCO UNIX.
+echo "$as_me:$LINENO: checking for strftime in -lintl" >&5
+echo $ECHO_N "checking for strftime in -lintl... $ECHO_C" >&6
+if test "${ac_cv_lib_intl_strftime+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char strftime ();
+int
+main ()
+{
+strftime ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_intl_strftime=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_intl_strftime=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_intl_strftime" >&5
+echo "${ECHO_T}$ac_cv_lib_intl_strftime" >&6
+if test $ac_cv_lib_intl_strftime = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRFTIME 1
+_ACEOF
+
+LIBS="-lintl $LIBS"
+fi
+
+fi
+done
+
+
+
+
+
+
+
+
+
+for ac_func in alarm gethostbyname putenv socket strcasecmp strdup strncasecmp strstr
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+          ac_config_files="$ac_config_files Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by FULL-PACKAGE-NAME $as_me VERSION, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+FULL-PACKAGE-NAME config.status VERSION
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
Index: /gsdl/stable/runtime-src/packages/d2m/configure.in
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/configure.in	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/configure.in	(revision 20131)
@@ -0,0 +1,30 @@
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
+AC_CONFIG_SRCDIR([danMARC.c])
+AC_CONFIG_HEADER([config.h])
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_RANLIB
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([fcntl.h malloc.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_STRUCT_TM
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_TYPE_SIGNAL
+AC_FUNC_STRFTIME
+AC_CHECK_FUNCS([alarm gethostbyname putenv socket strcasecmp strdup strncasecmp strstr])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
Index: /gsdl/stable/runtime-src/packages/d2m/d2m.h
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/d2m.h	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/d2m.h	(revision 20131)
@@ -0,0 +1,76 @@
+#ifndef D2MH
+#define D2MH
+
+#include <stdio.h>
+
+#define  TRUE    1
+#define  FALSE   0
+
+#define  HTML_TITLE           "d2m: Dublin Core to MARC conversion"
+
+#define  D2M_LINELEN          80
+#define  D2M_TEMPFILE         "/tmp/d2m.data"
+#define  D2M_TRACEFILE        "/tmp/d2m.trace"
+#define  D2M_DEFAULT_SYNTAX   "plain"
+#define  D2M_DEFAULT_FORMAT   "NORMARC"        
+#define  D2M_DEFAULT_URL      "http://www.bibsys.no/meta/test.html"
+
+struct metatag {
+   char    *name;
+   char    *type;
+   char    *scheme;
+   char    *value;
+               };
+
+struct marcrec {
+   int     ntitles;
+   int     ncreators;
+   char    *marcline;
+   char    *partitle;
+   char    *subtitle;
+   char    *year;
+   char    *url;
+   char    *fmat;
+   char    *s008;
+               };
+
+enum mformats {
+   USMARC,
+   DANMARC,
+   FINMARC,
+   ISMARC,
+   NORMARC,
+   SWEMARC    };
+
+enum SOURCES { TEXTAREA, URL };
+
+enum fields_in_008 {
+   F008_DATE_ENTERED,
+   F008_TYPE_OF_DATE,
+   F008_DATE1,
+   F008_LANGUAGE,
+   F008_FORM_OF_PUBLICATION };
+              
+enum levels {
+  LNAME,
+  LTYPE,
+  LSCHEME,
+  LOCC,
+  LTAG,
+  LIND,
+  LSUBF,
+  LRULE
+            };
+
+extern void write_field(char *i, FILE *of, int l, int n, int s);
+extern int write_trace(char *n, FILE *of);
+extern struct metatag *dc_parse(char *b); 
+extern char *cstr(char *h, char *n);
+extern void unescape(char *n);
+extern char *poq();
+extern int  put008(char *n, char *s, int p);
+extern int  find_year(char *n);
+extern int  split_name(char *n);
+extern int  split_subj(char *n);
+
+#endif
Index: /gsdl/stable/runtime-src/packages/d2m/d2m4gs.h
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/d2m4gs.h	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/d2m4gs.h	(revision 20131)
@@ -0,0 +1,22 @@
+#ifndef D2M4GSH
+#define D2M4GSH
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "d2m.h"
+
+void MARCtidy(struct marcrec *mrec, char *buf, int format);
+void usMARC(struct metatag *mt, struct marcrec *mr);
+char *MARC2709(char *record, int last, int first, char recstatus, 
+	       char rectype, char biblevel);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /gsdl/stable/runtime-src/packages/d2m/danMARC.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/danMARC.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/danMARC.c	(revision 20131)
@@ -0,0 +1,239 @@
+/* ------------------------------------------------------------------- */
+/* danMARC    : Convert a metatag struct to DANMARC2                   */
+/*                                                                     */
+/* Specs      : http://www.bibsys.no/meta/d2m/dancross.html            */
+/*                                                                     */
+/* Author     : Ole Husby                                              */
+/* Last update: 1998-09-30                                             */
+/* ------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include "d2m.h" 
+
+
+
+/* Splits subject heading on ":". First occurence go into $a, second into $v */ 
+
+int split_dk5(char *str)
+{
+  char *p, *q, subtag[5];
+
+  if (!strstr(str, ":"))
+    return 1;
+
+  p = (char *) malloc(strlen(str) + 50);
+  *p = 0;
+  *subtag = 0;
+
+  q = strtok(str, ":");
+  if (q)
+  {
+    while ( ( q[0] == ' ' ) && ( strlen(q) ) )
+      q++;
+
+    while( ( q[strlen(q) - 1] == ' ' ) && ( strlen(q) ) )
+      q[strlen(q) - 1] = '\0';
+
+    if (*q)
+    {
+      strcat(p, subtag);
+      strcat(p, q);
+      strcpy(subtag, " $v ");
+    }
+  }
+
+  strcpy(str, p);
+  free(p);
+
+  return 1;
+}
+
+
+
+
+int danMARC(struct metatag *mt, struct marcrec *mr)
+{
+  char pre[64], type_tag[4];
+  int i;
+
+  *pre = 0;
+
+  if (strcasecmp(mt->name, "title") == 0)
+  {
+    if ( (!*mt->type)
+         | (strcasecmp(mt->type, "main") == 0)
+         | (strcasecmp(mt->type, "long") == 0) )
+    {
+      if (mr->ntitles)
+      {
+        strcat(mr->partitle, "$a ");
+        strcat(mr->partitle, mt->value);
+
+      }
+      else
+      {
+        mr->ntitles++;
+        strcpy(pre, "245  $a");
+      }
+    }
+  }
+
+  else if (strcasecmp(mt->name, "creator") == 0)
+  {
+    if ( strcasecmp(mt->type, "personal") == 0) 
+    {
+      strcpy(pre, "700  $a");
+      split_name(mt->value);
+    }
+    else if (strcasecmp(mt->type, "corporate") == 0)
+      strcpy(pre, "710  $a");
+  }
+
+
+  else if (strcasecmp(mt->name, "publisher") == 0)
+    strcpy(pre, "260  $b");
+
+  else if (strcasecmp(mt->name, "description") == 0)
+    strcpy(pre, "504  $a");
+
+  else if (strncasecmp(mt->name, "contributor", 11) == 0)   
+  {
+    if ( strcasecmp(mt->type, "personal") == 0 )
+    {
+      strcpy(pre, "700  $a");
+      split_name(mt->value);
+    }
+    else if (strcasecmp(mt->type, "corporate") == 0)
+      strcpy(pre, "710  $a");
+  }
+
+  else if (strcasecmp(mt->name, "coverage") == 0)
+  {
+    if (!*mt->type)
+      strcpy(pre, "559  $a");
+    else if (strcasecmp(mt->type , "spatial") == 0)
+    {
+      strcpy(pre, "633  $a");
+      split_subj(mt->value);
+    }
+    else if (strcasecmp(mt->type,  "temporal") == 0)
+    {
+      strcpy(pre, "334  $b");
+      for (i = 0; i < strlen(mt->value); i++)
+      {
+        if (!isdigit(mt->value[i]))
+        {
+          strcpy(pre, "334  $a");
+        }
+      } 
+    }
+  }
+
+  else if (strcasecmp(mt->name, "source") == 0)
+    strcpy(pre, "523  $a");
+
+  else if (strcasecmp(mt->name, "rights") == 0)
+  {
+    if (strcasecmp(mt->scheme, "url") == 0)
+      strcpy(pre, "856  $3 rights $u");
+    else
+      strcpy(pre, "518  $a");
+  }
+
+  else if (strcasecmp(mt->name, "identifier") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(mr->url, mt->value);
+    else if (strcasecmp(mt->scheme, "url") == 0)
+      strcpy(mr->url, mt->value);
+    else if (strcasecmp(mt->scheme, "urn") == 0)
+      strcpy(pre, "856  $g urn:");
+    else if (strcasecmp(mt->scheme, "isbn") == 0)
+      strcpy(pre, "021  $a");
+    else if (strcasecmp(mt->scheme, "issn") == 0)
+      strcpy(pre, "022  $a");
+    else if (strcasecmp(mt->scheme, "isrc") == 0)
+      strcpy(pre, "024  $a");
+    else if (strcasecmp(mt->scheme, "ismn") == 0)
+      strcpy(pre, "028  $a");
+    else if (strcasecmp(mt->scheme, "isrn") == 0)
+      strcpy(pre, "027  $a");
+  }
+
+  else if (strcasecmp(mt->name, "type") == 0)
+    strcpy(pre, "505  $a");
+
+  else if (strcasecmp(mt->name, "relation") == 0)
+    strcpy(pre, "559  $a");
+
+  else if (strcasecmp(mt->name, "language") == 0)  /* Only if repeated ! */
+  {
+    if (strcasecmp(mt->scheme, "z39.53") == 0)
+    {
+      strcpy(pre, "041  $a");
+      put008(mr->s008, mt->value, F008_LANGUAGE);
+    }
+  }
+
+  else if (strcasecmp(mt->name, "format") == 0)
+  {
+    if ( (!*mt->scheme)
+      || (strcasecmp(mt->scheme, "imt") == 0)
+      || (strcasecmp(mt->scheme, "mime") == 0) )
+      strcpy(mr->fmat, mt->value); 
+  }
+
+  else if (strcasecmp(mt->name, "subject") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(pre, "631  $a");
+    else if (strcasecmp(mt->scheme, "udc") == 0)
+      strcpy(pre, "080  $a");
+    else if (strcasecmp(mt->scheme, "lccs") == 0)
+      strcpy(pre, "050  $a");
+    else if (strcasecmp(mt->scheme, "lcsh") == 0)
+      strcpy(pre, "650  $a");
+    else if (strcasecmp(mt->scheme, "ddc") == 0)
+      strcpy(pre, "082  $a");
+    else if (strcasecmp(mt->scheme, "nlm") == 0)
+      strcpy(pre, "060  $a");
+    else if (strcasecmp(mt->scheme, "agr") == 0)
+      strcpy(pre, "662  $a");
+    else if (strcasecmp(mt->scheme, "eudised") == 0)
+      strcpy(pre, "661  $b");
+    else if (strcasecmp(mt->scheme, "dbc") == 0)
+      strcpy(pre, "666  $f");
+    else if (strcasecmp(mt->scheme, "mesh") == 0)
+      strcpy(pre, "690  $a");
+    else if (strcasecmp(mt->scheme, "dk5") == 0)
+    {
+      strcpy(pre, "652  $m");
+      split_dk5(mt->value);
+    }
+  }
+
+  else if (strcasecmp(mt->name, "date") == 0)
+  {
+    if ( (!*mt->type) || ( strcasecmp(mt->type, "current") == 0) )
+    {
+      if ( (strncasecmp(mt->scheme, "ans", 3) == 0) 
+         || (strncasecmp(mt->scheme, "iso", 3) == 0) )
+      {
+        if (find_year(mt->value))
+        {
+          strcpy(mr->year, mt->value);
+          put008(mr->s008, mt->value, F008_DATE1);
+        }
+      }
+    }
+  }
+
+  if (*pre)
+  {
+    strcat(mr->marcline, pre);
+    strcat(mr->marcline, " ");
+    strcat(mr->marcline, mt->value);
+    strcat(mr->marcline, "\n");
+  }
+}
Index: /gsdl/stable/runtime-src/packages/d2m/dc_parse.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/dc_parse.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/dc_parse.c	(revision 20131)
@@ -0,0 +1,216 @@
+/* ------------------------------------------------------------------- */
+/* dc_parse   : parse the meta tag, build a metatag struct             */
+/* Author     : Ole Husby                                              */
+/* Updated    : 1998-09-30                                             */
+/*                                                                     */
+/* Syntax     : #include "d2m.h"                                       */
+/*              dc_parse(char * string)                                */
+/*                                                                     */
+/*              Returns pointer to struct metatag                      */
+/*                                                                     */
+/*              Memory for the struct is allocated in the program!     */
+/*                                                                     */
+/*              String includes a meta tag, after the initial          */
+/*              "<meta " and the ending ">" are stripped away.         */
+/*                                                                     */
+/*              The program accepts the tag if name starts with "dc."  */
+/*              (case insensitive), else NULL is returned.             */
+/*                                                                     */
+/*              The parsing looks for the HTML attributes "name",      */
+/*              "scheme", and "content" only. Other attributes are     */
+/*              ignored.                                               */
+/*                                                                     */
+/*              The DC "type" will be recognized if suffixed           */
+/*              "name" by "dot notation", or contained within          */
+/*              parentheses within "content" (old notation).           */
+/*              (type = subelement)                                    */
+/*                                                                     */
+/*              The DC "scheme" will be recognized if                  */
+/*              present in "scheme" attribute (HTML 4.0), or if        */
+/*              contained within aprentheses in "content" (HTML 2.0)   */
+/*                                                                     */
+/*              Examples:                                              */
+/*                                                                     */
+/*              meta name="DC.Creator.Personalname"                    */
+/*                content="Smith, John"                                */
+/*                                                                     */
+/*              meta name="dc.Creator"                                 */
+/*                content="(type=Personalname) Smith, John">           */
+/*                                                                     */
+/*              meta name="DC.Subject" scheme="LCSH"                   */
+/*                content="Cataloguing"                                */
+/*                                                                     */
+/*              meta name="DC.Subject"                                 */
+/*                content="(scheme=LCSH) Cataloguing"                  */
+/*                                                                     */
+/*              The values of the DC attributes are NOT validated!     */
+/*                                                                     */
+/* ------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include "d2m.h"
+
+
+
+
+struct metatag *dc_parse(char *buf)
+{
+  int more;
+  char *p, *q;
+  struct metatag *mtag;
+  int strict = TRUE;       /* Indicates that DC. prefix is mandatory */
+  char attrname[16];
+
+/* Allocates and initializes metatag struct */
+
+  mtag = malloc(sizeof(*mtag));
+
+  mtag->name   = malloc(256);
+  mtag->type   = malloc(256);
+  mtag->scheme = malloc(256);
+  mtag->value  = malloc(10000);
+
+  *mtag->name   = 0;
+  *mtag->type   = 0;
+  *mtag->scheme = 0;
+  *mtag->value  = 0;
+
+
+
+
+/* Parse attribute name/value pairs: */ 
+ 
+  if (!buf || !*buf) return NULL;
+
+  p = strtok(buf, "\"");
+
+
+
+  while (p)
+  {
+/*  Look for attribute name  */
+
+    *attrname = 0;
+
+    while (*p && ( p[strlen(p) - 1] == ' ' || p[strlen(p) - 1] == '=')) 
+      p[strlen(p) - 1] = '\0'; 
+
+    if (*p && strlen(p) < 10)
+      strcpy(attrname, p);
+
+/*  Look for attribute value */
+
+    p = strtok(NULL, "\"");
+
+    while(*p && p[0] == ' ')
+      p++;
+
+    if (!p || !*p)
+      break;
+
+    if (strncasecmp(attrname, "name", 4) == 0)
+      strcpy(mtag->name, p);
+    else if (strncasecmp(attrname, "scheme", 6) == 0)
+      strcpy(mtag->scheme, p);
+    else if (strncasecmp(attrname, "content", 7) == 0)
+      strcpy(mtag->value, p);
+    p = strtok(NULL, "\"");
+
+    if (p)
+    {
+      while (*p && p[0] == ' ')
+        p++;
+      if (!*p) p = NULL;      
+    }
+  }
+
+
+
+/* Check the name attribute value */
+
+  p = mtag->name;
+  
+  if (!p || !*p)
+    return NULL;
+
+/* Check for leading "dc." and suffixed type */
+
+  if (strncasecmp(p, "dc.", 3) == 0)
+  {
+    p += 3;
+    q = strstr(p, ".");
+    if (q)
+    {
+      strcpy(mtag->type, q + 1);
+      *q = 0;
+    }
+    mtag->name = p;
+  }
+  else
+  {
+    if (strict)
+      return NULL;
+  }
+
+
+/* Check the content attribute value */
+/* Extracting type and scheme        */
+ 
+
+  p = mtag->value;
+ 
+  more = 1;
+     
+  while (more)
+  {
+    if (strncasecmp(p, "(type=", 6) == 0)
+    {
+       p += 6;
+       q = strtok(p, ")");
+       if (!q)
+         return NULL;
+       else
+       {
+          if (!*mtag->type)
+            strcpy(mtag->type, q);
+          q = strtok(NULL, "\0");
+          p = q;
+          while (p && *p && p[0] == ' ') p++;
+
+       }
+    }
+
+    else if (strncasecmp(p, "(scheme=", 8) == 0)
+    {
+       p += 8;
+       q = strtok(p, ")");
+       if (!q)
+         return NULL;
+       else
+       {
+          if (!*mtag->scheme)
+            strcpy(mtag->scheme, q);
+          q = strtok(NULL, "\0");
+          p = q;
+          while (p && *p && p[0] == ' ') p++;
+       }
+    }
+
+    else
+    {
+      mtag->value = p;
+      more = 0; 
+    }
+
+  }
+
+/* Finished */
+
+  if (!*mtag->value)
+    mtag = (struct metatag *) NULL;
+
+  return mtag;
+}
Index: /gsdl/stable/runtime-src/packages/d2m/finMARC.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/finMARC.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/finMARC.c	(revision 20131)
@@ -0,0 +1,275 @@
+/* ------------------------------------------------------------------- */
+/* finMARC    : Convert a metatag struct to FINMARC                    */
+/*                                                                     */
+/* Author     : Ole Husby                                              */
+/* Last update: 1998-09-30                                             */
+/* ------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include "d2m.h" 
+
+
+/* Decides tag for format                                                    */
+
+int parse_format(char *str, char *format)
+{
+   if (strcasecmp(str, "text/html") == 0)
+     strcpy(format, "HTML"); 
+
+   return 1;
+}
+
+
+/* Decides tag for type                                                      */
+
+int parse_type(char *str, char *tag)
+{
+   strcpy(tag, "500");
+
+   if ( (strcasecmp(str, "diss."             ) == 0) 
+     || (strcasecmp(str, "dissertation"      ) == 0) 
+     || (strcasecmp(str, "phd thesis"        ) == 0) 
+     || (strcasecmp(str, "väitöskirja"       ) == 0) 
+     || (strcasecmp(str, "väitösk."          ) == 0) 
+     || (strcasecmp(str, "avhandling"        ) == 0) ) 
+     strcpy(tag, "502");
+
+   else
+   if ( (strcasecmp(str, "masters thesis"    ) == 0) 
+     || (strcasecmp(str, "honours thesis"    ) == 0) 
+     || (strcasecmp(str, "opinnäyte"         ) == 0) 
+     || (strcasecmp(str, "opinn."            ) == 0) ) 
+     strcpy(tag, "509");
+
+   return 1;
+}
+
+
+int finMARC(struct metatag *mt, struct marcrec *mr)
+{
+  char pre[64], type_tag[4];
+
+  *pre = 0;
+
+  if (strcasecmp(mt->name, "title") == 0)
+  {
+    if ( (!*mt->type)
+         | (strcasecmp(mt->type, "main") == 0)
+         | (strcasecmp(mt->type, "long") == 0) )
+    {
+      if (mr->ntitles)
+      {
+        strcat(mr->partitle, "$r ");
+        strcat(mr->partitle, mt->value);
+
+      }
+      else
+      {
+        mr->ntitles++;
+        strcpy(pre, "245  $a");
+      }
+    }
+  }
+
+  else if (strcasecmp(mt->name, "creator") == 0)
+  {
+    if (!*mt->type)
+    {
+      strcpy(pre, "720  $a");
+      split_name(mt->value);
+    }
+    else if ( (strcasecmp(mt->type, "name") == 0) 
+            || (strcasecmp(mt->type, "personal") == 0) )
+    {
+      strcpy(pre, "100  $a");
+      split_name(mt->value);
+    }
+    else if (strcasecmp(mt->type, "corporate") == 0)
+      strcpy(pre, "110  $a");
+  }
+
+  else if (strcasecmp(mt->name, "publisher") == 0)
+  {
+    if (!*mt->type)
+      strcpy(pre, "260  $b");
+    else if (strcasecmp(mt->type, "name") == 0)
+      strcpy(pre, "260  $b");
+  }
+
+  else if (strcasecmp(mt->name, "description") == 0)
+    strcpy(pre, "519  $a");
+
+  else if (strncasecmp(mt->name, "contributor", 11) == 0)     /* Note both pl and sgl allowed */
+  {
+    if (!*mt->type)
+    {
+      strcpy(pre, "720  $a");
+      split_name(mt->value);
+    }
+    else if ( (strcasecmp(mt->type, "name") == 0) 
+            || (strcasecmp(mt->type, "personal") == 0) )
+    {
+      strcpy(pre, "700  $a");
+      split_name(mt->value);
+    }
+    else if (strcasecmp(mt->type, "corporate") == 0)
+      strcpy(pre, "710  $a");
+  }
+
+  else if (strcasecmp(mt->name, "coverage") == 0)
+  {
+    if (!*mt->type)
+      strcpy(pre, "500  $a");
+    else if (strcasecmp(mt->type , "spatial") == 0)
+    {
+      strcpy(pre, "655  $a");
+      split_subj(mt->value);
+    }
+    else if (strcasecmp(mt->type,  "temporal") == 0)
+    {
+      strcpy(pre, "652  $a");
+      split_subj(mt->value);
+    }
+  }
+
+  else if (strcasecmp(mt->name, "source") == 0)
+    strcpy(pre, "501  $a");
+
+  else if (strcasecmp(mt->name, "rights") == 0)
+  {
+    if (strcasecmp(mt->scheme, "url") == 0)
+      strcpy(pre, "856  $u");
+  }
+
+  else if (strcasecmp(mt->name, "identifier") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(mr->url, mt->value);
+    else if (strcasecmp(mt->scheme, "url") == 0)
+      strcpy(mr->url, mt->value);
+    else if (strcasecmp(mt->scheme, "urn") == 0)
+      strcpy(pre, "856  $g");
+    else if (strcasecmp(mt->scheme, "isbn") == 0)
+      strcpy(pre, "021  $a");
+    else if (strcasecmp(mt->scheme, "issn") == 0)
+      strcpy(pre, "022  $a");
+    else if (strcasecmp(mt->scheme, "nbn") == 0)
+      strcpy(pre, "015  $a");
+    else if (strcasecmp(mt->scheme, "isrc") == 0)
+      strcpy(pre, "015  $a");
+    else if (strcasecmp(mt->scheme, "ismn") == 0)
+      strcpy(pre, "024  $a");
+    else if (strcasecmp(mt->scheme, "isrn") == 0)
+      strcpy(pre, "027  $a");
+  }
+
+  else if (strcasecmp(mt->name, "type") == 0)
+  {
+    parse_type(mt->value, (char *) type_tag);
+    sprintf(pre, "%s  $a", type_tag);
+  }
+
+  else if (strcasecmp(mt->name, "language") == 0)
+  {
+    if (strcasecmp(mt->scheme, "z39.53") == 0)
+    {
+      strcpy(pre, "041  $a");
+      if (strlen(mt->value) == 3)
+        put008(mr->s008, mt->value, F008_LANGUAGE);
+    }
+  }
+
+  else if (strcasecmp(mt->name, "format") == 0)
+  {
+    if ( (!*mt->scheme)
+      || (strcasecmp(mt->scheme, "imt") == 0)
+      || (strcasecmp(mt->scheme, "mime") == 0) )
+      parse_format(mt->value, (char *) mr->fmat);
+  }
+
+  else if (strcasecmp(mt->name, "subject") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(pre, "692  $a");
+    else if (strcasecmp(mt->scheme, "udc") == 0)
+      strcpy(pre, "080  $a");
+    else if (strcasecmp(mt->scheme, "lcsh") == 0)
+      strcpy(pre, "650  $a");
+    else if (strcasecmp(mt->scheme, "ddc") == 0)
+      strcpy(pre, "082  $a");
+    else if (strcasecmp(mt->scheme, "mesh") == 0)
+      strcpy(pre, "690  $a");
+    else if (strcasecmp(mt->scheme, "ykl") == 0)
+      strcpy(pre, "098  $a");
+    else if (strcasecmp(mt->scheme, "ysa") == 0)
+    {
+      strcpy(pre, "652  $a");
+      split_subj(mt->value);
+    }
+    else if (strcasecmp(mt->scheme, "fimu") == 0)
+    {
+      strcpy(pre, "653  $a");
+      split_subj(mt->value);
+    }
+    else if (strcasecmp(mt->scheme, "fige") == 0)
+    {
+      strcpy(pre, "655  $a");
+      split_subj(mt->value);
+    }
+    else if (strcasecmp(mt->scheme, "file") == 0)
+    {
+      strcpy(pre, "665  $a");
+      split_subj(mt->value);
+    }
+    else if (strcasecmp(mt->scheme, "fiso") == 0)
+    {
+      strcpy(pre, "670  $a");
+      split_subj(mt->value);
+    }
+    else if (strcasecmp(mt->scheme, "fire") == 0)
+    {
+      strcpy(pre, "680  $a");
+      split_subj(mt->value);
+    }
+    else if (strcasecmp(mt->scheme, "fifo") == 0)
+    {
+      strcpy(pre, "685  $a");
+      split_subj(mt->value);
+    }
+    else if (strcasecmp(mt->scheme, "fiag") == 0)
+    {
+      strcpy(pre, "686  $a");
+      split_subj(mt->value);
+    }
+    else if (strcasecmp(mt->scheme, "fiep") == 0)
+    {
+      strcpy(pre, "660  $a");
+      split_subj(mt->value);
+    }
+  }
+
+  else if (strcasecmp(mt->name, "date") == 0)
+  {
+    if ( (!*mt->type) || ( strcasecmp(mt->type, "current") == 0) )
+    {
+      if ( (strncasecmp(mt->scheme, "ans", 3) == 0) 
+         || (strncasecmp(mt->scheme, "iso", 3) == 0) )
+      {
+        if (find_year(mt->value))
+        {
+          strcpy(mr->year, mt->value);
+          put008(mr->s008, mt->value, F008_DATE1);
+        }
+      }
+    }
+  }
+
+  if (*pre)
+  {
+    strcat(mr->marcline, pre);
+    strcat(mr->marcline, " ");
+    strcat(mr->marcline, mt->value);
+    strcat(mr->marcline, "\n");
+  }
+}
Index: /gsdl/stable/runtime-src/packages/d2m/htget.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/htget.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/htget.c	(revision 20131)
@@ -0,0 +1,545 @@
+/* ------------------------------------------------------------------- */
+/* htget     : Fetch a file using HTTP protocol                        */
+/*                                                                     */
+/* Author    : Ole Husby, BIBSYS                                       */
+/* Updated   : 1998-09-30                                              */
+/*                                                                     */
+/* ------------------------------------------------------------------- */
+/*                                                                     */
+/* htget(url, type, timeout_seconds, outfile, content_type, location)  */
+/*                                                                     */
+/*   Returns: HTTP statuscode, with additional private:                */
+/*                 0 : OK ( = 200)                                     */
+/*               900 : Error, possible timeout                         */
+/*               901 : Syntax error in url                             */
+/*               902 : Unknown host                                    */
+/*               903 : No response from server (no connection)         */
+/*               904 : File is not text/html                           */
+/*               905 : Statusline > 255 bytes                          */
+/*               906 : Statusline < 4 bytes                            */
+/*               907 : Statusline not starting with "HTTP"             */
+/*               908 : Statuscode not numeric                          */
+/*               909 : Size of header > BUFSIZE                        */
+/*               910 : Unable to open output file                      */
+/*               999 : Unspecified TCP/IP error                        */
+/*                                                                     */
+/*   Writes to outfile, depending on type, if statuscode = 0 | 200 :   */
+/*                                                                     */
+/*   type = 0  : Nothing                                               */
+/*   type = 1  : HTTP header                                           */
+/*   type = 2  : HTTP header + entitybody                              */
+/*   type = 3  : HTTP entitybody                                       */
+/*   type = 4  : HTTP entitybody if text/html                          */
+/*   type = 5  : HTTP <HEAD> part of entitybody if text/html           */
+/*   type = 6  : HTTP <HEAD> part of entitybody if text/html           */
+/*               HTTP entitybody if application/marc                   */
+/*                                                                     */
+/* ------------------------------------------------------------------- */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <signal.h>
+
+#define FALSE               0
+#define TRUE                1
+#define BUFSIZE             10000
+#define TYPE_NONE           0     
+#define TYPE_HTTPHEAD       1     
+#define TYPE_HTTPALL        2     
+#define TYPE_HTTPBODY       3     
+#define TYPE_HTMLALL        4     
+#define TYPE_HTMLHEAD       5     
+#define TYPE_MARC           6     
+
+#define TRACE               0
+
+#define AGENT               "BIBSYS_htget v1.1"
+
+char conType[128];
+int htmlonly, marcrecord;
+
+
+
+void thandler(int i)
+{
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* geteoHEAD: Look for </HEAD> or <BODY                                */
+/*                                                                     */
+/* returns: 0 if not found                                             */
+/*          1 if found. Terminates buf immediately after </HEAD> or    */
+/*            immediately before <BODY                                 */
+/* ------------------------------------------------------------------- */
+
+int geteoHEAD(char *buf)
+{
+  char *p;
+  int i;
+
+  p = (char *) cstr(buf, "<BODY");
+  if (p)
+  {
+    i = p - buf;
+
+    buf[i] = '\n';
+    buf[i+1] = '\0';
+    return 1;
+  }
+
+  p = (char *) cstr(buf, "</HEAD>");
+  if (p)
+  {
+    i = p - buf + 7;
+
+    buf[i] = '\n';
+    buf[i+1] = '\0';
+    return 1;
+  }
+
+  return 0;
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* writeRequest: send request to server                                */
+/*                                                                     */
+/* returns: Number of bytes written                                    */
+/* ------------------------------------------------------------------- */
+
+int writeRequest(char *req, int server)
+{
+   if (TRACE)
+      printf("*** send(): %s\n", req);
+
+   return write(server, req, strlen(req));
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* getBody : Read the Entity-body into the file filename               */
+/*                                                                     */
+/* Open the given file for writing, read data from the                 */
+/* socket until a terminating '\0' is found, write to                  */
+/* the file. Returns 0 if ok, positive if an error results             */
+/* in errno being set, or -1 if other error.                           */
+
+/* Single read()'s blocking for more than TIMEOUT_SECONDS will         */
+/* be interrupted. The read() then returns a negative value, and       */
+/* errno will be set appropriately (EINTR).                            */
+/*                                                                     */
+/* Returns   0 if ok                                                   */
+/*         900 if read error                                           */
+/*                                                                     */
+/* ------------------------------------------------------------------- */
+
+int getBody(int server, int timeout, int fd, char *filename)
+{
+   int i, ef;
+   unsigned char *bf, buf[BUFSIZE + 1];
+   int  bytecount;
+   int  found_end;
+   
+   if (TRACE)
+     printf("*** Read entitybody\n");
+
+/* Loop until the endmark is found                                     */
+
+   found_end = FALSE;
+
+
+   while (!found_end) 
+   {
+      alarm (timeout);
+      bytecount = read (server, buf, BUFSIZE);
+      alarm (0);
+
+      if (bytecount < 0) 
+        return 900;                                 /* error in read() */
+
+      else if (bytecount == 0)
+        break;                                 /* server closed socket */
+
+
+      else
+      {
+       if (buf[bytecount-1] == '\0') 
+         {
+            bytecount--;              /* do not write the '\0' to file */
+            found_end = TRUE;                    /* terminate the loop */
+	 }
+
+/*       Write to file                                                 */
+
+         if (bytecount > 0) 
+         {
+            bf = (unsigned char *) buf;
+            bf[bytecount] = '\0';
+            if ( htmlonly )
+            {
+              ef = geteoHEAD(bf);
+              bytecount = strlen(bf);
+            }
+            else
+              ef = 0;
+            write (fd, bf, bytecount);
+            if (ef)
+              break;
+         }
+      }
+   }
+
+   return 0; 
+}
+      
+
+
+/* ------------------------------------------------------------------- */
+/* getHeader : Access file and read HTTP header                        */
+/*                                                                     */
+/* Returns   0 if ok                                                   */
+/*         904 if Content-type not "text/html"                         */
+/*         905 if Statusline > 255 bytes                               */
+/*         906 if Statusline < 4 bytes                                 */
+/*         907 if Statusline not starting with "HTTP"                  */
+/*         908 if Statuscode not numeric                               */
+/*         909 if size of header > BUFSIZE                             */
+/*         HTTP statuscode if <> 200                                   */
+/*                                                                     */
+/* ------------------------------------------------------------------- */
+
+int getHeader(int server, int timeout, int type, int fd, char *reason, char *loc)
+{
+   char buf[BUFSIZE+1], dummy[8];
+   unsigned char *p,  *cp = buf, *d = dummy;
+   int i, rc, statuscode, plf, rlen = 0;
+
+   reason = (char *) NULL;
+   *conType = 0;
+
+   if (TRACE)
+     printf("*** Read statusline\n");
+
+
+/* Read HTTP statusline (until LF or 0, max 256 byte)                 */
+
+   for ( cp = buf, *buf = 0; 1; cp++ )
+   {
+      alarm (timeout);
+      rc = read ( server, cp, 1 );
+      alarm (0);
+
+      if ( rc < 0 )
+	 return 900;
+
+      if ( *cp == '\r')
+      {
+        cp--;
+        continue;
+      }
+
+      rlen++;
+
+      if (TRACE)
+        printf("%c", *cp);
+
+      if ( *cp == 0 || rlen > 255)
+	 return 905;
+      if ( *cp == '\n')
+      {
+         *cp = 0;
+	 break;
+      }
+   }
+
+/*  Write statusline                                                 */
+
+   if ( ( type == TYPE_HTTPHEAD ) || ( type == TYPE_HTTPALL ) )
+   {
+     write(fd, buf, strlen(buf));
+     write(fd, "\n\n", 2);
+   }
+
+   if (TRACE)
+      printf("*** read() : (%d) %s\n", rlen, buf);
+
+
+/* Parse statusline                                                   */
+
+   if (rlen < 4)
+     return 906;
+
+   if (strncmp(buf, "HTTP", 4) != 0)
+     return 907;
+
+   p = strtok(buf, " ");
+   p = strtok(NULL, " ");
+
+   if (!*p)
+     statuscode = 200;
+   else
+   {
+     for (i = 0; i < strlen(p); i++)
+       if (!isdigit(p[i]))
+         return 908;
+   }
+   statuscode = atoi(p);
+
+   p = strtok(NULL, "\0");
+   if (p)
+     reason = p;
+
+   if (statuscode == 200)
+     statuscode = 0;
+
+   if (!type)
+     return statuscode;
+
+
+/* Read HTTP response header (until 0 or empty line, max BUFSIZE bytes  */
+
+   rlen = 0;
+   plf = FALSE;
+
+   if (TRACE)
+     printf("*** Read responseheader\n");
+
+   for ( cp = buf, *buf = 0; 1; cp++ )
+   {
+      alarm (timeout);
+      rc = read ( server, cp, 1 ); 
+      alarm (0);
+
+      if ( rc < 0 )
+	 return 900;
+
+      if ( *cp == '\r')
+      {
+        cp--;
+        continue;
+      }
+
+      rlen++;
+
+      if ( *cp == 0 || rlen > BUFSIZE)
+	 return 909;
+      else if ( *cp == '\n')
+      {
+         if (plf)
+         {
+           *cp = 0;
+	   break;
+         }
+         else
+           plf = TRUE;
+      }
+      else
+        plf = FALSE;
+   }
+
+/*  Write rest of HTTP header                                         */
+
+   if ( ( type == TYPE_HTTPHEAD ) || ( type == TYPE_HTTPALL ) )
+   {
+     write(fd, buf, strlen(buf));
+     write(fd, "\n", 1);
+   }
+
+   if (TRACE)
+      printf("*** read() : (%d) %s\n", rlen, buf);
+
+
+/* Parse header for Content-Type and Loaction                         */
+
+   rc = 904;
+
+   p = strtok(buf, "\n");
+   while (p)
+   {
+     if (strncasecmp(p, "Content-Type:", 13) == 0)
+     {
+       p += 13;
+       while (p[0] == ' ')
+         p++;
+       strcpy(conType, p);
+
+       if (strncasecmp(p, "text/html", 7) == 0)
+       {
+         if ( ( type == TYPE_HTMLHEAD) || (type == TYPE_MARC ) )
+           htmlonly = 1;
+         rc = 0;
+       }
+
+       else if (strncasecmp(p, "application/marc", 16) == 0)
+       {
+         if ( type == TYPE_MARC )
+         {
+           marcrecord = 1; 
+           rc = 0;
+         }
+       }
+     }
+
+     else if (strncasecmp(p, "Location:", 9) == 0)
+     {
+       p += 9;
+       while (p[0] == ' ')
+         p++;
+       strcpy(loc, p);
+     }
+     p = strtok(NULL, "\n");
+   }
+
+
+/* All OK. Socket is positioned at start of HTTP Entity-Body          */
+
+   if (rc)
+     return rc;
+   else
+     return statuscode;
+}
+
+
+
+
+
+/* ------------------------------------------------------------------- */
+/* htget  : Fetch a URL                                                */
+/* ------------------------------------------------------------------- */
+
+int htget(char *iurl, int type, int timeout, char *outfile, char *h_contype, char *h_location)
+{
+   int i, rc, fd, soc, port;
+   struct sockaddr_in addr; 
+   struct hostent *hp, *gethostbyname();
+   char	uurl[1024], *url = uurl, hostname[256], cport[64], req[1024];
+   char *h, *p, *q, *r;
+   char tfile[256], blank[2];
+
+   *blank = *h_contype = *h_location = 0; 
+   htmlonly = marcrecord = 0;
+
+   strcpy(tfile, "/tmp/geturl.tmp");
+   if (!*outfile)
+     outfile = (char *) tfile;
+
+   if (!*iurl || ( strlen(iurl) > 1023 ) )
+     return 901;
+
+   strcpy(url, iurl);
+
+/* Parse and validate URL                                             */
+
+   if (strncmp(url, "http://", 7) != 0)
+     return 901;
+
+   url += 7;
+
+   q = strtok(url, "/");
+   if (!q)
+     return 901;
+
+   r = strtok(NULL, "\0");
+   if (!r)
+     r = (char *) blank;
+
+   h = strtok(q, ":");
+   if (!*h)
+     return 901;
+
+   strcpy(hostname, h);
+
+   p = strtok(NULL, "\0");
+
+   if (!p || !*p)
+     port = 80;
+   else
+   {
+     for (i = 0; i < strlen(p); i++)
+       if (!isdigit(p[i]))
+         return 901;
+     port = atoi(p);
+   }
+   sprintf(req, "GET /%s HTTP/1.0\r\nUser_Agent: %s\n\n", r, AGENT);
+  
+
+/* Establish handler for the alarm-signal                              */
+
+   signal (SIGALRM, thandler);
+
+
+/* Get IP address                                                      */
+ 
+   hp = gethostbyname(hostname);
+   if (!hp)
+     return 902;
+
+/* Get socket and connect                                              */
+ 
+   soc = socket(AF_INET, SOCK_STREAM, 0);
+ 
+   addr.sin_family = AF_INET;
+   
+   memcpy( &addr.sin_addr.s_addr, hp->h_addr, (size_t) hp->h_length );
+
+   addr.sin_port = htons(port);
+   if (connect(soc, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) < 0)
+      return 903;
+
+
+/* Open the destination file                                           */
+ 
+   if (type)
+   {
+     fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC , 0666);
+     if (fd < 0)  
+     {
+        close(soc);
+        return 910;
+     }
+   }
+
+
+
+
+/* Write HTTP-request                                               */
+ 
+   if (!writeRequest(req, soc))
+   {
+     close(soc);
+     if (type)
+       close(fd);
+     return 999;
+   }
+
+
+/* Read header part of response                                     */
+
+   rc = getHeader(soc, timeout, type, fd, r, h_location);
+   
+   if ( ( rc == 904 ) && (type < 4 ) )
+     rc = 0;
+
+   if ( ( rc == 0 ) && ( type > 1 ) )
+     rc = getBody(soc, timeout, fd, outfile);
+ 
+   close(soc);
+   if (type)
+     close(fd);
+   strcpy(h_contype, conType);
+
+   return rc;
+}
Index: /gsdl/stable/runtime-src/packages/d2m/isMARC.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/isMARC.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/isMARC.c	(revision 20131)
@@ -0,0 +1,333 @@
+/* ------------------------------------------------------------------- */
+/* isMARC     : Convert a metatag struct to ISMARC                     */
+/*              (i.e. UKMARC as used in the National and University    */
+/*              Library of Island).                                    */
+/*                                                                     */
+/* Specs      : http://www.bibsys.no/meta/d2m/iscross.txt              */
+/*                                                                     */
+/* Author     : Ole Husby                                              */
+/* Last update: 1998-09-30                                             */
+/* ------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include "d2m.h" 
+
+
+
+
+/* ------------------------------------------------------------------- */
+/* Splits Icelandig name without a comma                               */
+/* ------------------------------------------------------------------- */
+
+int split_ice2(char *str)
+{
+  char *q, *temp, *suba, *subi, *subb;
+
+  if (!strstr(str, " "))
+    return 1;
+
+  suba = (char *) malloc(strlen(str) + 50);
+  subi = (char *) malloc(strlen(str) + 50);
+  subb = (char *) malloc(strlen(str) + 50);
+  temp = (char *) malloc(strlen(str) + 50);
+
+  *suba = *subi = *subb = *temp = 0;
+
+  q = strtok(str, " ");
+  while (q)
+  {
+    while ( ( q[0] == ' ' ) && ( strlen(q) ) )
+      q++;
+
+    while( ( q[strlen(q) - 1] == ' ' ) && ( strlen(q) ) )
+      q[strlen(q) - 1] = '\0';
+
+    if (*q)
+    {
+      if (!*suba)
+        strcpy(suba, q);
+      else
+      {
+        if (*temp)
+        {
+          if (*subi)
+            strcat(subi, " ");
+          strcat(subi, temp);
+        }
+        strcpy(temp, q);
+      }
+    }
+    q = strtok(NULL, " ");
+  }
+
+  *str = 0;
+
+  if (*temp)
+  {
+    if (*subi)
+      strcpy(subb, temp);
+    else
+      strcpy(subi, temp);
+  }
+
+  if (*suba)
+  {
+    strcpy(str, suba);
+    if (*subi)
+    {
+      strcat(str, " $i ");
+      strcat(str, subi); 
+    }
+    if (*subb)
+    {
+      strcat(str, " $b ");
+      strcat(str, subb); 
+    }
+  }
+
+  free(suba);
+  free(subi);
+  free(subb);
+  free(temp);
+
+  return 40;
+}
+
+
+
+
+
+/* ------------------------------------------------------------------- */
+/* Splits Icelandig name                                               */
+/* ------------------------------------------------------------------- */
+
+int split_icename(char *str, int i2)
+{
+  char *p, *q, subtag[5];
+
+  if (!strstr(str, ","))
+  {
+    if (i2)
+      return split_ice2(str);
+    else
+      return 1;
+  }
+
+  p = (char *) malloc(strlen(str) + 50);
+  *p = 0;
+  *subtag = 0;
+
+  q = strtok(str, ",");
+  if (q)
+  {
+    strcpy(p, q);
+    q = strtok(NULL, "\0");
+    if (q)
+    {
+      while ( ( q[0] == ' ' ) && ( strlen(q) ) )
+        q++;
+      strcat(p, " $h ");
+      strcat(p, q);
+    }
+    strcpy(str, p);
+  }
+
+  free(p);
+
+  return 10;
+}
+
+
+int isMARC(struct metatag *mt, struct marcrec *mr)
+{
+  char pre[64], type_tag[4], creator_tag[4], title_tag[6];
+  int i, ind, ice2;
+
+  *pre = 0;
+
+  if (strcasecmp(mt->name, "title") == 0)
+  {
+    if ( (!*mt->type)
+         | (strcasecmp(mt->type, "main") == 0)
+         | (strcasecmp(mt->type, "long") == 0) )
+    {
+      if (mr->ntitles)
+        strcpy(title_tag, "24630");
+      else
+        strcpy(title_tag, "24510");
+
+      mr->ntitles++;
+
+      sprintf(pre, "%s$a", title_tag);
+    }
+  }
+
+  else if (strcasecmp(mt->name, "creator") == 0)
+  {
+    if ( strcasecmp(mt->type, "personal") == 0) 
+    {
+      if (!mr->ncreators)
+        strcpy(creator_tag, "100");
+      else 
+        strcpy(creator_tag, "700");
+
+      ice2 = 1; 
+      ind = split_icename(mt->value, ice2);
+      sprintf(pre, "%s%2d$a", creator_tag, ind);
+    }
+    else if (strcasecmp(mt->type, "corporate") == 0)
+    {
+      if (!mr->ncreators)
+        strcpy(creator_tag, "110");
+      else 
+        strcpy(creator_tag, "710");
+      sprintf(pre, "%s20$a", creator_tag);
+    }
+    else
+    {
+      ice2 = 0;
+      strcpy(pre, "720  $a");
+      ind = split_icename(mt->value, ice2);
+    }
+    mr->ncreators++;
+  }
+
+  else if (strncasecmp(mt->name, "contributor", 11) == 0)
+  {
+    if ( strcasecmp(mt->type, "personal") == 0) 
+    {
+      ice2 = 1; 
+      ind = split_icename(mt->value, ice2);
+      sprintf(pre, "700%2d$a", ind);
+    }
+    else if (strcasecmp(mt->type, "corporate") == 0)
+    {
+      strcpy(pre, "71020$a");
+    }
+    else
+    {
+      ice2 = 0;
+      strcpy(pre, "720  $a");
+      ind = split_icename(mt->value, ice2);
+    }
+    mr->ncreators++;
+  }
+
+
+  else if (strcasecmp(mt->name, "publisher") == 0)
+    strcpy(pre, "260  $b");
+
+  else if (strcasecmp(mt->name, "description") == 0)
+    strcpy(pre, "513  $a");
+
+  else if (strcasecmp(mt->name, "coverage") == 0)
+  {
+    if (strcasecmp(mt->type , "spatial") == 0)
+    {
+      strcpy(pre, "651  $a");
+      split_subj(mt->value);
+    }
+    else
+      strcpy(pre, "500  $a");
+  }
+
+  else if (strcasecmp(mt->name, "source") == 0)
+    strcpy(pre, "787  $a");
+
+  else if (strcasecmp(mt->name, "rights") == 0)
+  {
+    if (strcasecmp(mt->scheme, "url") == 0)
+      strcpy(pre, "856  $3 rights $u");
+    else
+      strcpy(pre, "500  $a");
+  }
+
+  else if (strcasecmp(mt->name, "identifier") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(mr->url, mt->value);
+    else if (strcasecmp(mt->scheme, "url") == 0)
+      strcpy(mr->url, mt->value);
+    else if (strcasecmp(mt->scheme, "urn") == 0)
+      strcpy(pre, "8567 $u urn:");
+    else if (strcasecmp(mt->scheme, "nbn") == 0)
+      strcpy(pre, "015  $a");
+    else if (strcasecmp(mt->scheme, "isbn") == 0)
+      strcpy(pre, "021  $a");
+    else if (strcasecmp(mt->scheme, "issn") == 0)
+      strcpy(pre, "022  $a");
+    else if (strcasecmp(mt->scheme, "isrc") == 0)
+      strcpy(pre, "024  $a");
+    else if (strcasecmp(mt->scheme, "ismn") == 0)
+      strcpy(pre, "025  $a");
+    else if (strcasecmp(mt->scheme, "isrn") == 0)
+      strcpy(pre, "027  $a");
+  }
+
+  else if (strcasecmp(mt->name, "type") == 0)
+    strcpy(pre, "655  $a");
+
+  else if (strcasecmp(mt->name, "relation") == 0)
+    strcpy(pre, "787  $a");
+
+  else if (strcasecmp(mt->name, "language") == 0)
+  {
+    if (strcasecmp(mt->scheme, "z39.53") == 0)
+    {
+      strcpy(pre, "04109$a");
+      if (strlen(mt->value) == 3) 
+        put008(mr->s008, mt->value, F008_LANGUAGE);
+    }
+    else if (strcasecmp(mt->scheme, "usmarc") == 0)
+      strcpy(pre, "04109$a");
+    else
+      strcpy(pre, "546  $a");
+  }
+
+  else if (strcasecmp(mt->name, "format") == 0)
+    strcpy(mr->fmat, mt->value); 
+
+  else if (strcasecmp(mt->name, "subject") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(pre, "680  $a");
+    else if (strcasecmp(mt->scheme, "udc") == 0)
+      strcpy(pre, "080  $a");
+    else if (strcasecmp(mt->scheme, "lcc") == 0)
+      strcpy(pre, "050  $a");
+    else if (strcasecmp(mt->scheme, "lcsh") == 0)
+      strcpy(pre, "650  $a");
+    else if (strcasecmp(mt->scheme, "ddc") == 0)
+      strcpy(pre, "082  $a");
+    else if (strcasecmp(mt->scheme, "nlm") == 0)
+      strcpy(pre, "060  $a");
+    else if (strcasecmp(mt->scheme, "landslyk") == 0)
+      strcpy(pre, "659  $a");
+    else if (strcasecmp(mt->scheme, "kerfefn") == 0)
+      strcpy(pre, "659  $a");
+    else if (strcasecmp(mt->scheme, "dbc") == 0)
+      strcpy(pre, "65002$a");
+    else if (strcasecmp(mt->scheme, "mesh") == 0)
+      strcpy(pre, "690  $a");
+    else
+      strcpy(pre, "65004$a");
+  }
+
+  else if (strcasecmp(mt->name, "date") == 0)
+  {
+    if (find_year(mt->value))
+    {
+      strcpy(mr->year, mt->value);
+      put008(mr->s008, mt->value, F008_DATE1);
+    }
+  }
+
+  if (*pre)
+  {
+    strcat(mr->marcline, pre);
+    strcat(mr->marcline, " ");
+    strcat(mr->marcline, mt->value);
+    strcat(mr->marcline, "\n");
+  }
+}
Index: /gsdl/stable/runtime-src/packages/d2m/marc2line.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/marc2line.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/marc2line.c	(revision 20131)
@@ -0,0 +1,243 @@
+/* ------------------------------------------------------------------- */
+/* marc2line : Reads an ISO 2709 MARC record, converts to MARC         */
+/*             "Line format"                                           */
+/*                                                                     */
+/* author    : Ole Husby, BIBSYS                                       */
+/* updated   : 1998-09-30                                              */
+/* ------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#define DIRL                                   3600
+
+#define LINEL                                  72 
+#define SUBFIELD_CODE                          '\x1f'
+#define SUBFIELD_STR                           "\x1f" 
+#define FIELD_TERMINATOR                       '\x1e'
+#define RECORD_TERMINATOR                      '\x1d'
+
+#define BIBSYS_TYPE                            0
+#define NORMARC_TYPE                           1
+
+union LDR   {
+   char ldr_string[24+1];
+   struct {
+      char record_length[5],
+      record_status,
+      record_type,
+      bibliographic_level,
+      unused1[2],
+      indicator_count,
+      subfield_code_count,
+      base_adress[5],
+      unused2[3],
+      entry1,
+      entry2,
+      entry3,
+      entry4;
+   } ltab;
+} ldr; 
+
+static char out_record[10240];
+static int out_type;
+
+
+
+/* ------------------------------------------------------------------- */
+/* One subfield string is split into output lines                      */
+/* ------------------------------------------------------------------- */
+
+static void out_subfield(data, prefix, slen)
+char *data, *prefix;
+int slen;
+
+{
+   char lineprefix[7], subprefix[4], *spre;
+   int i, more, len, max;
+
+   if (out_type == BIBSYS_TYPE)
+      strcpy(lineprefix, prefix);
+   else
+   {
+      if (prefix[0] == ' ') strcpy(lineprefix, " ");
+      else                  strcpy(lineprefix, "*");
+      strcat(lineprefix, prefix);
+   }
+
+   max = LINEL;
+
+   if (slen)
+   {
+      spre = (char *) subprefix;
+      strcpy(spre, "$");                       /* Construct subfield    */
+      strncat(spre, data, 1);                  /* prefix                */
+      if (out_type == BIBSYS_TYPE) 
+	 strcat(spre, " ");
+      data++;
+      max = LINEL - 2; 
+      if (out_type == BIBSYS_TYPE) 
+	 max--;
+   }
+   else spre = NULL;  
+
+   more = 1;
+
+   while (more)
+   {
+      if (slen)
+         while (data[0] == ' ') data++;    /* skip leading blanks    */
+
+      strcat(out_record, lineprefix);      /* Start with prefix      */
+      strcpy(lineprefix, "     ");
+      if (out_type == NORMARC_TYPE) 
+	 strcat(lineprefix, " ");
+
+      len = strlen(data);
+      if (len > max)                       /* Must fit into one line */
+      {
+	 len = max;
+	 for (i = max; i > max - 15; i--)
+	 {
+	    if (data[i] == ' ')
+	    {
+	       len = i;
+	       break;
+	    }
+	 }
+      }
+      else more = 0;
+
+      if (spre)
+      {
+	 strcat(out_record, spre);         /* subfield pref needed  */
+	 spre = NULL;                      /* only first line       */
+	 max = LINEL;
+      }
+
+      strncat(out_record, data, len);      /* append data           */
+      if (more) data += len;
+      strcat(out_record, "\n");
+   }
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* One MARC field is split into subfields and given to output          */
+/* ------------------------------------------------------------------- */
+
+static int out_field(data, ftag, find)
+char *data, *ftag, *find;
+
+{
+   char prefix[5];
+   char subfield[5120], *sub = subfield;
+   int subcode = 0;
+
+   strcpy(prefix, ftag);
+
+   if (!find)                                 /* output entire field   */ 
+   {
+      out_subfield(data, prefix, subcode);
+      return 1;
+   }
+
+   strcat(prefix, find);
+
+   if (data[0] != SUBFIELD_CODE) return 0;    /* requires subf code in */
+   data++;                                    /*   first byte          */
+
+   sub = strtok(data, SUBFIELD_STR);          /* find first subfield   */
+   if (!sub) return 0;
+
+   subcode = 1;
+   out_subfield(sub, prefix, subcode);        /* output subfield       */
+   strcpy(prefix, "     ");                   /* reset prefix          */
+
+   while (sub = strtok(NULL, SUBFIELD_STR))   /* find and output rest  */
+      out_subfield(sub, prefix, subcode);     /* of the subfields      */
+
+   return 1;
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* Main program                                                        */
+/* ------------------------------------------------------------------- */
+
+char *marc2line(record, type)          
+char *record, *type;
+{
+   char buffer[10240], tag[4], indicators[3];
+   char *cp, *fld, *buf = buffer, *cq;
+   char directory[DIRL+1], *dir = directory, *ind;
+   char sBase[6], fLen[5], fStart[6];
+   int           dlen, base, x = 0, more = 1, len, start;
+
+   if (!record || !*record)
+     return (char *) NULL;
+
+   strcpy(buf, record);
+   *out_record = 0;                                 /* reset out area     */
+
+   if (strcmp(type, "bibsys") == 0) out_type = BIBSYS_TYPE;
+   else out_type = NORMARC_TYPE;
+
+   strncpy(ldr.ldr_string, buf, 24);                 /* get leader         */
+   ldr.ldr_string[24] = '\0';
+   buf += 24;
+  
+   strncpy(sBase, ldr.ltab.base_adress, 5);
+   sBase[5] = '\0';
+   base = atoi(sBase);
+
+   dlen = base - 24;                                 /* get directory      */
+   strncpy(dir, buf, dlen);
+   dir[dlen] = '\0';
+   buf += dlen;
+
+   cp = dir;
+
+   while (more)                                      /* loop until EOdir   */ 
+   {
+      if (*cp == FIELD_TERMINATOR)  break;
+      if (strlen(cp) < 13) return (char *) NULL;
+
+      strncpy(tag, cp, 3);                           /* get tag            */
+      tag[3] = '\0';
+      cp +=3;
+
+      strncpy(fLen, cp, 4);                         /* get length          */
+      fLen[4] = '\0';
+      len = atoi(fLen) -1;                          /* discard field term. */
+      cp += 4;
+
+      strncpy(fStart, cp, 5);                       /* get start of field  */
+      fStart[5] = '\0';
+      start = atoi(fStart);
+      cp += 5;
+
+      fld = buf + start;                            /* get field           */ 
+      fld[len] = '\0';
+      
+      if (strncmp(tag, "00", 2) != 0)               /* get indicators      */
+      {
+	 indicators[0] = '\0';
+	 strncat(indicators, fld, 2);
+	 ind = (char *) indicators;
+	 fld += 2;
+      }
+      else ind = NULL;
+
+      if (!out_field(fld, tag, ind))                /* output field         */
+	 return (char *) NULL;
+
+   }
+
+   return (char *) out_record;
+
+}
Index: /gsdl/stable/runtime-src/packages/d2m/norMARC.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/norMARC.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/norMARC.c	(revision 20131)
@@ -0,0 +1,194 @@
+/* ------------------------------------------------------------------- */
+/* norMARC   : Convert a metatag struct to NORMARC                     */
+/*                                                                     */
+/* 1998-09-30: Ole Husby                                               */
+/* ------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include "d2m.h" 
+
+
+
+int norMARC(struct metatag *mt, struct marcrec *mr)
+{
+  char pre[64], creator_tag[4], title_tag[4];
+
+  *pre = 0;
+
+  if (strcasecmp(mt->name, "title") == 0)
+  {
+    if ( (!*mt->type)
+         | (strcasecmp(mt->type, "main") == 0)
+         | (strcasecmp(mt->type, "long") == 0) )
+    {
+      if (mr->ntitles)
+        strcpy(title_tag, "246");
+      else
+        strcpy(title_tag, "245");
+
+      mr->ntitles++;
+
+      sprintf(pre, "%s  $a", title_tag);
+    }
+    else if (strcasecmp(mt->type, "subtitle") == 0)
+    {
+      if (mr->ntitles < 2)
+        strcpy(mr->subtitle, mt->value);
+    }
+  }
+
+  else if (strcasecmp(mt->name, "creator") == 0)
+  {
+    if ( (!*mt->type) || (strcasecmp(mt->type, "name") == 0) 
+      || (strcasecmp(mt->type, "personalname") == 0) )
+    {
+      if (mr->ncreators)
+        strcpy(creator_tag, "700");
+      else
+        strcpy(creator_tag, "100");
+
+      mr->ncreators++;
+
+      sprintf(pre, "%s  $a", creator_tag);
+    }
+
+    else if (strcasecmp(mt->type, "corporatename") == 0) 
+    {
+      if (mr->ncreators)
+        strcpy(creator_tag, "710");
+      else
+        strcpy(creator_tag, "110");
+
+      mr->ncreators++;
+
+      sprintf(pre, "%s  $a", creator_tag);
+    }
+  }
+
+  else if (strcasecmp(mt->name, "publisher") == 0)
+  {
+    if (!*mt->type)
+      strcpy(pre, "260  $b");
+    else if (strcasecmp(mt->type, "name") == 0)
+      strcpy(pre, "260  $b");
+  }
+
+  else if (strcasecmp(mt->name, "contributor") == 0)
+  {
+    if ( (!*mt->type)|| (strcasecmp(mt->type, "name") == 0)
+      || (strcasecmp(mt->type, "personalname") == 0) )
+      strcpy(pre, "700  $a");
+    else if (strcasecmp(mt->type, "corporatename") == 0)
+      strcpy(pre, "710  $a");
+  }
+
+  else if (strcasecmp(mt->name, "coverage") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(pre, "500  $a");
+    else if (strcasecmp(mt->scheme, "freetext") == 0)
+      strcpy(pre, "500  $a");
+  }
+
+  else if (strcasecmp(mt->name, "source") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(pre, "500  $a Kilde:");
+    else if (strcasecmp(mt->scheme, "freetext") == 0)
+      strcpy(pre, "500  $a Kilde:");
+    else if (strcasecmp(mt->scheme, "url") == 0)
+      strcpy(pre, "500  $a Kilde: URL:");
+    else if (strcasecmp(mt->scheme, "urn") == 0)
+      strcpy(pre, "500  $a Kilde: URN:");
+    else if (strcasecmp(mt->scheme, "isbn") == 0)
+      strcpy(pre, "500  $a Kilde: ISBN:");
+    else if (strcasecmp(mt->scheme, "issn") == 0)
+      strcpy(pre, "500  $a Kilde: ISSN:");
+  }
+
+  else if (strcasecmp(mt->name, "rights") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(pre, "500  $a Copyright:");
+    else if (strcasecmp(mt->scheme, "freetext") == 0)
+      strcpy(pre, "500  $a Copyright:");
+  }
+
+  else if (strcasecmp(mt->name, "identifier") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(mr->url, mt->value);
+    else if (strcasecmp(mt->scheme, "url") == 0)
+      strcpy(mr->url, mt->value);
+    else if (strcasecmp(mt->scheme, "urn") == 0)
+      strcpy(pre, "856  $u urn:");
+    else if (strcasecmp(mt->scheme, "isbn") == 0)
+      strcpy(pre, "020  $a");
+    else if (strcasecmp(mt->scheme, "issn") == 0)
+      strcpy(pre, "022  $a");
+  }
+
+  else if (strcasecmp(mt->name, "language") == 0)
+  {
+    if (strcasecmp(mt->scheme, "z39.53") == 0)
+    {
+      if (strlen(mt->value) == 3)
+        put008(mr->s008, mt->value, F008_LANGUAGE);
+    }
+  }
+
+  else if (strcasecmp(mt->name, "format") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(mr->fmat, mt->value);
+    else if (strcasecmp(mt->scheme, "imt") == 0)
+      strcpy(mr->fmat, mt->value);
+    else if (strcasecmp(mt->scheme, "mime") == 0)
+      strcpy(mr->fmat, mt->value);
+  }
+
+  else if (strcasecmp(mt->name, "subject") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(pre, "691  $a");
+    else if (strcasecmp(mt->scheme, "internal") == 0)
+      strcpy(pre, "691  $a");
+    else if (strcasecmp(mt->scheme, "udc") == 0)
+      strcpy(pre, "080  $a");
+    else if (strcasecmp(mt->scheme, "lcsh") == 0)
+      strcpy(pre, "650  $a");
+    else if (strcasecmp(mt->scheme, "ddc") == 0)
+      strcpy(pre, "082  $a");
+    else if (strcasecmp(mt->scheme, "mesh") == 0)
+      strcpy(pre, "660  $a");
+    else if (strcasecmp(mt->scheme, "humord") == 0)
+      strcpy(pre, "698  $a");
+    else if (strcasecmp(mt->scheme, "ntub") == 0)
+      strcpy(pre, "699  $a");
+  }
+
+  else if (strcasecmp(mt->name, "date") == 0)
+  {
+    if ( (strncasecmp(mt->scheme, "ans", 3) == 0) ||
+         (strncasecmp(mt->scheme, "iso", 3) == 0) )
+    {
+      if ( (!*mt->type) || ( strcasecmp(mt->type, "current") == 0) )
+      {
+        if (find_year(mt->value))
+        {
+          strcpy(mr->year, mt->value);
+          put008(mr->s008, mt->value, F008_DATE1);
+        }
+      }
+    }
+  }
+
+  if (*pre)
+  {
+    strcat(mr->marcline, pre);
+    strcat(mr->marcline, " ");
+    strcat(mr->marcline, mt->value);
+    strcat(mr->marcline, "\n");
+  }
+}
Index: /gsdl/stable/runtime-src/packages/d2m/strcasecmp.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/strcasecmp.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/strcasecmp.c	(revision 20131)
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of California at Berkeley. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific written prior permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strcasecmp.c	5.5 (Berkeley) 11/24/87";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison.  The mappings are
+ * based upon ascii character sequences.
+ */
+static unsigned char charmap[] = {
+	'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+	'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+	'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+	'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+	'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+	'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+	'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+	'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+	'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+	'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+	'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+	'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+	'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+	'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+	'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+	'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+	'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+	'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+	'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+	'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+	'\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+	'\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
+	'\340', '\341', '\342', '\343', '\344', '\345', '\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',
+};
+
+int
+strcasecmp(s1, s2)
+    char *s1, *s2;
+{
+    register unsigned char u1, u2;
+
+    for (;;) {
+	u1 = (unsigned char) *s1++;
+	u2 = (unsigned char) *s2++;
+	if (charmap[u1] != charmap[u2]) {
+	    return charmap[u1] - charmap[u2];
+	}
+	if (u1 == '\0') {
+	    return 0;
+	}
+    }
+}
+int
+strncasecmp(s1, s2, n)
+    char *s1, *s2;
+    int n;
+{
+    register unsigned char u1, u2;
+    int i;
+    for (i=0;i<n;i++) {
+	u1 = (unsigned char) *s1++;
+	u2 = (unsigned char) *s2++;
+	if (charmap[u1] != charmap[u2]) {
+	    return charmap[u1] - charmap[u2];
+	}
+	if (u1 == '\0') {
+	    return 0;
+	}
+    }
+    return 0;
+}
+
+
+
+
Index: /gsdl/stable/runtime-src/packages/d2m/sweMARC.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/sweMARC.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/sweMARC.c	(revision 20131)
@@ -0,0 +1,259 @@
+/* ------------------------------------------------------------------- */
+/* sweMARC    : Convert a metatag struct to LIBRISMARC                 */
+/*                                                                     */
+/* Author     : Ole Husby                                              */
+/* Last update: 1998-09-30                                             */
+/* ------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "d2m.h" 
+
+
+
+
+/* ---------------------------------------------------------------------- */
+/* Decides on first indicator for personal name                           */
+/*                                                                        */
+/* f : no comma                                                           */
+/* e : comma, with only one word preceeding                               */
+/* s : comma, with more than one word preceeding (delimiter blank or "-") */
+/* ---------------------------------------------------------------------- */
+
+int personal_indicator(char *pname)
+{
+  char *comma, *blank, *hyphen;
+
+  comma = strstr(pname, ",");
+  if (!comma)
+    return (int) 'f';
+
+  blank = strstr(pname, " ");
+  hyphen = strstr(pname, "-");
+
+  if ( (blank && blank < comma) || (hyphen && hyphen < comma) )
+    return (int) 's';
+  else
+    return (int) 'e';
+}
+
+
+
+/* ---------------------------------------------------------------------- */
+/* Decides tag for type                                                   */
+/* ---------------------------------------------------------------------- */
+
+int parse_swetype(char *str, char *tag)
+{
+   if ( (strcasecmp(str, "diss."             ) == 0) 
+     || (strcasecmp(str, "dissertation"      ) == 0) 
+     || (strcasecmp(str, "thesis"            ) == 0) 
+     || (strcasecmp(str, "domkap.avh."       ) == 0) 
+     || (strcasecmp(str, "hab.-schr"         ) == 0) 
+     || (strcasecmp(str, "prästmösteavh."    ) == 0)
+     || (strcasecmp(str, "avhandling"        ) == 0) ) 
+     strcpy(tag, "502");
+   else
+     strcpy(tag, "500");
+
+   return 1;
+}
+
+
+/* ---------------------------------------------------------------------- */
+/* sweMARC()                                                              */
+/* ---------------------------------------------------------------------- */
+
+int sweMARC(struct metatag *mt, struct marcrec *mr)
+{
+  char pre[64], creator_tag[4], type_tag[4];
+  int ind1;
+
+  *pre = 0;
+
+  if (strcasecmp(mt->name, "title") == 0)
+  {
+    if ( (!*mt->type)
+         | (strcasecmp(mt->type, "main") == 0)
+         | (strcasecmp(mt->type, "long") == 0) )
+    {
+      if (mr->ntitles)
+        strcpy(pre, "740  $a");
+      else
+      {
+        mr->ntitles++;
+        strcpy(pre, "245  $a");
+      }
+    }
+  }
+
+
+  else if (strcasecmp(mt->name, "creator") == 0)
+  {
+    if (!*mt->type)
+      strcpy(pre, "720  $a");
+    else if (strcasecmp(mt->type, "personal") == 0) 
+    {
+      ind1 = personal_indicator(mt->value);
+      if (mr->ncreators)
+        strcpy(creator_tag, "700");
+      else
+      {
+        strcpy(creator_tag, "100");
+        mr-> ncreators++;
+      }
+      sprintf(pre, "%s%c $a", creator_tag, ind1);
+    }
+    else if (strcasecmp(mt->type, "corporate") == 0)
+    {
+      if (mr->ncreators)
+        strcpy(creator_tag, "710");
+      else
+      {
+        strcpy(creator_tag, "110");
+        mr-> ncreators++;
+      }
+      sprintf(pre, "%sc $a", creator_tag);
+    }
+  }
+
+
+  else if (strncasecmp(mt->name, "contributor", 11) == 0)     /* Note both pl and sgl allowed */
+  {
+    if (!*mt->type)
+      strcpy(pre, "720  $a");
+    else if (strcasecmp(mt->type, "personal") == 0) 
+    {
+      ind1 = personal_indicator(mt->value);
+      sprintf(pre, "700%cm$a", ind1);
+    }
+    else if (strcasecmp(mt->type, "corporate") == 0)
+      strcpy(pre, "710  $a");
+  }
+
+
+  else if (strcasecmp(mt->name, "publisher") == 0)          /* Note both should go to same tag! */
+  {
+    if (!*mt->type)
+      strcpy(pre, "260  $b");
+    else if (strcasecmp(mt->type, "email") == 0)
+      strcpy(pre, "260  $d");
+  }
+
+
+
+  else if (strcasecmp(mt->name, "description") == 0)
+    strcpy(pre, "520  $a");
+
+
+
+  else if (strcasecmp(mt->name, "coverage") == 0)
+  {
+    if (!*mt->type)
+      strcpy(pre, "500  $a");
+    else if (strcasecmp(mt->type , "spatial") == 0)
+      strcpy(pre, "651  $a");
+    else if (strcasecmp(mt->type,  "temporal") == 0)
+      strcpy(pre, "650  $a");
+  }
+
+  else if (strcasecmp(mt->name, "source") == 0)
+    strcpy(pre, "786  $a");
+
+
+  else if (strcasecmp(mt->name, "relation") == 0)
+    strcpy(pre, "787  $a");
+
+
+  else if (strcasecmp(mt->name, "rights") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(pre, "500  $a");
+    if (strcasecmp(mt->scheme, "url") == 0)
+      strcpy(pre, "856  $u");
+    if (strcasecmp(mt->scheme, "urn") == 0)
+      strcpy(pre, "856  $g");
+  }
+
+  else if (strcasecmp(mt->name, "identifier") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(mr->url, mt->value);
+    else if (strcasecmp(mt->scheme, "url") == 0)
+      strcpy(mr->url, mt->value);
+    else if (strcasecmp(mt->scheme, "urn") == 0)
+      strcpy(pre, "856  $g");
+    else if (strcasecmp(mt->scheme, "ismn") == 0)
+      strcpy(pre, "538  $a ISMN $b");
+    else if (strcasecmp(mt->scheme, "sici") == 0)
+      strcpy(pre, "538  $a SICI $b");
+    else 
+      sprintf(pre, "538  $a %s $b", mt->scheme);
+  }
+
+  else if (strcasecmp(mt->name, "type") == 0)
+  {
+    parse_swetype(mt->value, (char *) type_tag);
+    sprintf(pre, "%s  $a", type_tag);
+  }
+
+  else if (strcasecmp(mt->name, "language") == 0)
+  {
+    strcpy(pre, "506  $a");
+    if (strcasecmp(mt->scheme, "z39.53") == 0)
+      put008(mr->s008, mt->value, F008_LANGUAGE);
+  }
+
+  else if (strcasecmp(mt->name, "format") == 0)
+  {
+    if ( (!*mt->scheme)
+      || (strcasecmp(mt->scheme, "imt") == 0)
+      || (strcasecmp(mt->scheme, "mime") == 0) )
+      strcpy(pre, "856  $q");
+  }
+
+  else if (strcasecmp(mt->name, "subject") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(pre, "697  $a");
+    else if (strcasecmp(mt->scheme, "udc") == 0)
+      strcpy(pre, "080  $a");
+    else if (strcasecmp(mt->scheme, "lcsh") == 0)
+      strcpy(pre, "650  $a");
+    else if (strcasecmp(mt->scheme, "ddc") == 0)
+      strcpy(pre, "082  $a");
+    else if (strcasecmp(mt->scheme, "lcc") == 0)
+      strcpy(pre, "087  $a");
+    else if (strcasecmp(mt->scheme, "sab") == 0)
+      strcpy(pre, "081  $a");
+    else if (strcasecmp(mt->scheme, "mesh") == 0)
+      strcpy(pre, "660  $a");
+    else
+      strcpy(pre, "650  $a");
+  }
+
+  else if (strcasecmp(mt->name, "date") == 0)
+  {
+    if ( (!*mt->type) || ( strcasecmp(mt->type, "current") == 0) )
+    {
+      if ( (strncasecmp(mt->scheme, "ans", 3) == 0) 
+         || (strncasecmp(mt->scheme, "iso", 3) == 0) )
+      {
+        if (find_year(mt->value))
+        {
+          strcpy(mr->year, mt->value);
+          put008(mr->s008, mt->value, F008_DATE1);
+        }
+      }
+    }
+  }
+
+  if (*pre)
+  {
+    strcat(mr->marcline, pre);
+    strcat(mr->marcline, " ");
+    strcat(mr->marcline, mt->value);
+    strcat(mr->marcline, "\n");
+  }
+}
Index: /gsdl/stable/runtime-src/packages/d2m/test.data
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/test.data	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/test.data	(revision 20131)
@@ -0,0 +1,1 @@
+<meta name="DC.title" content="Test file for d2m">
Index: /gsdl/stable/runtime-src/packages/d2m/usMARC.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/usMARC.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/usMARC.c	(revision 20131)
@@ -0,0 +1,165 @@
+/* ------------------------------------------------------------------- */
+/* usMARC   : Convert a metatag struct to USMARC                       */
+/*                                                                     */
+/* 1998-09-30: Ole Husby                                               */
+/* ------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include "d2m.h" 
+
+
+
+void usMARC(struct metatag *mt, struct marcrec *mr)
+{
+  char pre[64], title_tag[4];
+
+  *pre = 0;
+
+  if (strcasecmp(mt->name, "title") == 0)
+  {
+    if ( (!*mt->type)
+         | (strcasecmp(mt->type, "main") == 0)
+         | (strcasecmp(mt->type, "long") == 0) )
+    {
+      if (mr->ntitles)
+        strcpy(title_tag, "2460");
+      else
+        strcpy(title_tag, "245 ");
+
+      mr->ntitles++;
+
+      sprintf(pre, "%s $a", title_tag);
+    }
+  }
+
+  else if (strcasecmp(mt->name, "creator") == 0) 
+  {
+    if (!*mt->type)
+      strcpy(pre, "720  $a");
+    else if ( (strcasecmp(mt->type, "name") == 0)
+            || (strcasecmp(mt->type, "personal") == 0) )
+      strcpy(pre, "700  $a");
+    else if (strcasecmp(mt->type, "corporate") == 0)
+      strcpy(pre, "710  $a");
+  }
+
+
+  else if (strcasecmp(mt->name, "publisher") == 0)
+  {
+    if (!*mt->type)
+      strcpy(pre, "260  $b");
+    else if (strcasecmp(mt->type, "name") == 0)
+      strcpy(pre, "260  $b");
+  }
+
+  else if (strncasecmp(mt->name, "contributor", 11) == 0)     /* Note both pl and sgl allowed */
+  {
+    if (!*mt->type)
+      strcpy(pre, "720  $a");
+    else if ( (strcasecmp(mt->type, "name") == 0)
+            || (strcasecmp(mt->type, "personal") == 0) )
+      strcpy(pre, "700  $a");
+    else if (strcasecmp(mt->type, "corporate") == 0)
+      strcpy(pre, "710  $a");
+  }
+
+
+  else if (strcasecmp(mt->name, "coverage") == 0)
+  {
+    if (!*mt->type)
+      strcpy(pre, "500  $a");
+    else if (strcasecmp(mt->type , "spatial") == 0)
+      strcpy(pre, "255  $c");
+    else if (strcasecmp(mt->type,  "temporal") == 0)
+      strcpy(pre, "513  $b");
+  }
+
+
+  else if (strcasecmp(mt->name, "source") == 0)
+    strcpy(pre, "7860 $n");
+
+  else if (strcasecmp(mt->name, "rights") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(pre, "540  $a");
+    else if (strcasecmp(mt->scheme, "url") == 0)
+      strcpy(pre, "856  $3 rights $a");
+  }
+
+  else if (strcasecmp(mt->name, "identifier") == 0)
+
+/* Not supported: Indicator for urn! (See crosswalk)            */
+
+  {
+    if (!*mt->scheme)
+      strcpy(mr->url, mt->value);
+    else if (strcasecmp(mt->scheme, "url") == 0)
+      strcpy(mr->url, mt->value);
+    else if (strcasecmp(mt->scheme, "urn") == 0)
+      strcpy(pre, "856  $u urn:");
+    else if (strcasecmp(mt->scheme, "isbn") == 0)
+      strcpy(pre, "020  $a");
+    else if (strcasecmp(mt->scheme, "issn") == 0)
+      strcpy(pre, "022  $a");
+    else
+      strcpy(pre, "0248 $a");
+  }
+
+  else if (strcasecmp(mt->name, "format") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(mr->fmat, mt->value);
+    else if (strcasecmp(mt->scheme, "imt") == 0)
+      strcpy(mr->fmat, mt->value);
+    else if (strcasecmp(mt->scheme, "mime") == 0)
+      strcpy(mr->fmat, mt->value);
+  }
+
+  else if (strcasecmp(mt->name, "subject") == 0)
+  {
+    if (!*mt->scheme)
+      strcpy(pre, "653  $a");
+    else if (strcasecmp(mt->scheme, "lcc") == 0)
+      strcpy(pre, "050  $a");
+    else if (strcasecmp(mt->scheme, "lcsh") == 0)
+      strcpy(pre, "650  $a");
+    else if (strcasecmp(mt->scheme, "ddc") == 0)
+      strcpy(pre, "082  $a");
+  }
+
+
+  else if (strcasecmp(mt->name, "language") == 0)
+  {
+    if (strcasecmp(mt->scheme, "z39.53") == 0)
+    {
+      if (strlen(mt->value) == 3)
+        put008(mr->s008, mt->value, F008_LANGUAGE);
+    }
+  }
+
+
+  else if (strcasecmp(mt->name, "date") == 0)
+  {
+    if ( (strncasecmp(mt->scheme, "ans", 3) == 0) ||
+         (strncasecmp(mt->scheme, "iso", 3) == 0) )
+    {
+      if ( (!*mt->type) || ( strcasecmp(mt->type, "current") == 0) )
+      {
+        if (find_year(mt->value))
+        {
+          strcpy(mr->year, mt->value);
+          put008(mr->s008, mt->value, F008_DATE1);
+        }
+      }
+    }
+  }
+
+  if (*pre)
+  {
+    strcat(mr->marcline, pre);
+    strcat(mr->marcline, " ");
+    strcat(mr->marcline, mt->value);
+    strcat(mr->marcline, "\n");
+  }
+}
Index: /gsdl/stable/runtime-src/packages/d2m/util.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/util.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/util.c	(revision 20131)
@@ -0,0 +1,472 @@
+/* ------------------------------------------------------------------- */
+/* util      : Several utilities for the d2m converter                 */
+/*                                                                     */
+/* Author    : Ole Husby                                               */
+/* Updated   : 1998-09-30                                              */
+/* ------------------------------------------------------------------- */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "d2m.h"
+
+
+
+
+/* ------------------------------------------------------------------- */
+/* Produce MARC line-format output                                     */
+/* ------------------------------------------------------------------- */
+
+void write_field(char *l, FILE *of, int linel, int llen, int slen)
+{
+  char pre[64], line[256], *p, *q, *n;
+  int more, i, spos, compact, ctr;
+
+  ctr = 0;
+  *pre = *line = 0;
+  p = strdup(l);
+  q = p;
+
+  more = TRUE;
+  compact = FALSE;  
+
+  while (more)
+  {
+
+    ctr++;
+    if (ctr > 20) more = FALSE;
+
+    if (strlen(q) <= linel - 8)           /* String fits into 1 line  */
+    {
+      if (compact)
+      {
+        fprintf(of, "%s%s\n", pre, q);
+        more = FALSE;
+      }
+      else
+      {
+        n = strstr(q + 6, "$");
+
+        if ( (n - q ) > 5)
+        {
+          spos = (n - q);
+          strncat(line, q, spos);
+          q = n;
+          fprintf(of, "%s%s\n", pre, line);
+          strcpy(pre, "     ");
+          *line = 0;
+        }
+        else
+        {
+          fprintf(of, "%s%s\n", pre, q);
+          more = FALSE;
+        }
+      }
+    }
+
+    else                                  /* Look for splitting point */
+    {
+      spos = 0;
+
+      if (!compact)
+      {
+        for (i = 6; i < linel - 8; i++)
+        {
+          if (q[i] == '$')
+          {
+            spos = i + 1;
+            break;
+          }
+        } 
+      }
+
+ 
+      if (!spos)
+      {
+        for (i = linel - 9; i > slen; i--)
+        {
+          if ( !compact && (q[i] == '$'))
+          {
+            spos = i + 1;
+            break;
+          }
+          else if (q[i] == ' ')
+          {
+            spos = i;
+            break;
+          }
+        }
+      }
+
+      if (spos)
+      {
+         strncat(line, q, spos);
+         q +=  spos + 1;
+      }
+      else
+      {
+         strncat(line, q, llen);
+         strcat(line, "-");
+         q += llen;
+      }
+
+      fprintf(of, "%s%s\n", pre, line);
+      strcpy(pre, "     ");
+      *line = 0;
+    }
+  }
+  free(p);
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* Fetching HTTP POST data                                             */
+/* ------------------------------------------------------------------- */
+
+char *poq() 
+{
+    int m=0, c, cl;
+    char *rec;
+
+    if(strcmp(getenv("REQUEST_METHOD"),"POST"))
+      return NULL;
+
+    cl = atoi(getenv("CONTENT_LENGTH"));
+
+    if (cl)
+      rec = (char*) malloc(cl + 1);
+    else
+      return NULL;
+    
+    while (c = fgetc(stdin))
+    {
+      rec[m] = c;
+      m++;
+      if (m >= cl) break;
+    }
+
+    rec[m] = 0;
+
+    return rec;
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* ------------------------------------------------------------------- */
+
+int unesc (char h, char l)
+{
+   char buf[3];
+   int i;
+
+   buf[0]=h;
+   buf[1]=l;
+   buf[2]='\0';
+   sscanf(buf,"%x",&i);
+   return (i);
+}
+
+
+/* ------------------------------------------------------------------- */
+/* Replace '+' with space and unescape hex coded characters.           */
+/* ------------------------------------------------------------------- */
+
+void unescape (char *s)
+{
+   char *rp, *wp;  /* read position and write position in string */
+   rp=wp=s;
+   while (*rp != '\0') {
+      if (*rp=='+') {
+         *(wp++)=' ';
+         rp++;
+      }
+      else if (*rp=='%') {
+         int a,b;
+         rp++;   /* skip the '%' */
+         a = (unsigned char) *(rp++);
+         b = (unsigned char) *(rp++);
+         *(wp++)=unesc (a,b);
+      } else
+         *(wp++)=*(rp++);
+    }
+    *wp = '\0';
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* Case independent string search.                                     */
+/*                                                                     */
+/* Call syntax like strstr()                                           */
+/* ------------------------------------------------------------------- */
+
+char *cstr(char *h, char *n)
+{
+  char *nn;
+  char *hh;
+  char *p, *s;
+  long i;
+
+
+/* Returns NULL if either of strings are NULL                     */
+
+  if (!*h || !*n)
+    return (char *) NULL;
+
+
+/* Make a copy hh of h and nn of n                                */
+
+  hh = (char *) strdup(h);
+  nn = (char *) strdup(n);
+
+/* Converts hh and nn to lower                                    */
+
+  for (i = 0; i < strlen(nn); i++)
+    nn[i] = tolower(n[i]);
+
+  for (i = 0; i < strlen(hh); i++)
+    hh[i] = tolower(h[i]);
+
+/* Searches for nn in hh using strstr                             */
+
+  p = (char *) strstr(hh, nn);
+
+/* If found, calculates corresponding pointer into h              */
+
+  if (!p)
+    s = (char *) NULL;
+  else
+  {
+    i = strlen(hh) - strlen(p);
+    s = h + i;
+  }
+
+/* Frees string copies and returns                                */
+
+  free(hh);
+  free(nn);
+
+  return s; 
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* Write and remove tracefile                                          */
+/* ------------------------------------------------------------------- */
+
+int write_trace(char *tracefile, FILE *of)
+{
+  char line[10000], *l;
+  FILE *tf;
+
+  tf = fopen(tracefile, "r");
+  if (!tf)
+    return 0;
+
+  while (l = fgets(line, 9999, tf))
+    fprintf(of, "%s", l);
+
+  fclose(tf);
+  remove(tracefile);  
+  return 1;
+}
+
+
+/* ------------------------------------------------------------------- */
+/* Insert field into 008                                               */
+/* ------------------------------------------------------------------- */
+
+int put008(char *s8, char *str, int f8)
+{
+   int i, len, pos, nlen, npos, append=0;
+
+   if (strlen(s8) != 40)
+     return 0;
+
+   switch (f8)
+   {
+     case (F008_DATE_ENTERED) :
+     {
+       pos = 0;
+       len = 6;
+       break;
+     }
+     case (F008_TYPE_OF_DATE) :
+     {
+       pos = 6;
+       len = 1;
+       break;
+     }
+     case (F008_DATE1) :
+     {
+       pos = 7;
+       len = 4;
+       break;
+     }
+     case (F008_FORM_OF_PUBLICATION) :
+     {
+       pos = 24;
+       len = 4;
+       append = 1;
+       break;
+     }
+     case (F008_LANGUAGE) :
+     {
+       pos = 35;
+       len = 3;
+       break;
+     }
+     default :
+       return 0;
+   }
+
+
+   npos = pos;
+   nlen = strlen(str);
+   if (nlen > len)
+     return 0;
+
+   if (nlen < len)
+   {
+     if (append)
+     {
+       npos = 0;
+       for (i = pos; i < pos + len; i++)
+       {
+         if ( s8[i] == ' ' )
+         {
+           npos = i;
+           break; 
+         }
+       }
+       if (npos == 0)
+         return 0;
+       if (npos >= pos + len)
+         return 0;
+       if (npos + nlen > pos + len)
+         return 0;
+     }
+     else
+       return 0;
+   }
+/* printf
+     ("pos %d len %d npos %d nlen %d str %s\n", 
+     pos, len, npos, nlen, str);
+*/
+
+   for (i = 0; i < nlen; i++)
+     s8[npos+i] = str[i];
+
+   return 1;
+}
+
+
+/* ------------------------------------------------------------------- */
+/* Converts date to YYYY                                               */
+/* ------------------------------------------------------------------- */
+
+int find_year(char *str)
+{
+  int i;
+
+  if (strlen(str) < 4)
+    return 0;
+
+  str[4] = 0;
+
+  for (i = 0; i < 4; i++)
+  {
+    if (!isdigit(str[i]))
+      return 0;
+  }
+ 
+  return 1;
+}
+
+
+
+
+/* ------------------------------------------------------------------- */
+/* Splits personal name at first "," into $a and $h                    */
+/* ------------------------------------------------------------------- */
+
+int split_name(char *str)
+{
+  char *p, *q, subtag[5];
+
+  if (!strstr(str, ","))
+    return 1;
+
+  p = (char *) malloc(strlen(str) + 50);
+  *p = 0;
+  *subtag = 0;
+
+  q = strtok(str, ",");
+  if (q)
+  {
+    strcpy(p, q);
+    q = strtok(NULL, "\0");
+    if (q)
+    {
+      while ( ( q[0] == ' ' ) && ( strlen(q) ) )
+        q++;
+      strcat(p, " $h ");
+      strcat(p, q);
+    }
+    strcpy(str, p);
+  }
+
+  free(p);
+
+  return 1;
+}
+
+
+
+/* ------------------------------------------------------------------- */
+/* Splits subject heading on "-". First occurence go into $a, second   */ 
+/* into $b, all the rest into $x                                       */
+/* ------------------------------------------------------------------- */
+
+int split_subj(char *str)
+{
+  char *p, *q, subtag[5];
+
+  if (!strstr(str, "-"))
+    return 1;
+
+  p = (char *) malloc(strlen(str) + 50);
+  *p = 0;
+  *subtag = 0;
+
+  q = strtok(str, "-");
+  while (q)
+  {
+    while ( ( q[0] == ' ' ) && ( strlen(q) ) )
+      q++;
+
+    while( ( q[strlen(q) - 1] == ' ' ) && ( strlen(q) ) )
+      q[strlen(q) - 1] = '\0';
+
+    if (*q)
+    {
+      strcat(p, subtag);
+      strcat(p, q);
+      if (!*subtag)
+        strcpy(subtag, " $b ");
+      else
+        strcpy(subtag, " $x ");
+    }
+    q = strtok(NULL, "-");
+  }
+
+  strcpy(str, p);
+  free(p);
+
+  return 1;
+}
Index: /gsdl/stable/runtime-src/packages/d2m/wfetch-l.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/wfetch-l.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/wfetch-l.c	(revision 20131)
@@ -0,0 +1,19 @@
+/* ------------------------------------------------------------------- */
+/* wfetch    : Fetch a remote file using the htget() "HTTP client"     */
+/*                                                                     */
+/* syntax    : wfatch(char *url, char *filename)                       */
+/*                                                                     */
+/* Returns   : 0 ALWAYS!                                               */
+/*                                                                     */
+/* Author    : Ole Husby, BIBSYS                                       */
+/* Updated   : 1998-10-04                                              */
+/* ------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+int wfetch(char *url, char *filename)
+{
+  return 0;
+}
Index: /gsdl/stable/runtime-src/packages/d2m/wfetch.c
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/wfetch.c	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/wfetch.c	(revision 20131)
@@ -0,0 +1,53 @@
+/* ------------------------------------------------------------------- */
+/* wfetch    : Fetch a remote file using the htget() "HTTP client"     */
+/*                                                                     */
+/* syntax    : wfatch(char *url, char *filename)                       */
+/*                                                                     */
+/*             The file will be written to "filename"                  */
+/*                                                                     */
+/* Returns   : 0 if fail                                               */
+/*           : 1 if HTML file (text/html)                              */
+/*           : 2 if MARC file (application/marc)                       */
+/*                                                                     */
+/* NOTE      : Timeout period (HTTP) is set here.                      */
+/*                                                                     */
+/* Author    : Ole Husby, BIBSYS                                       */
+/* Updated   : 1998-08-11                                              */
+/* ------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define  TIMEOUT_SECONDS       10
+
+int wfetch(char *url, char *filename)
+{
+  int i, type, argtype, timeout, rc, retc;
+  char iurl[1024], content_type[128], location[128];
+
+  retc = 1;
+
+  strcpy(iurl, url);
+  timeout = TIMEOUT_SECONDS;
+
+  type = 6;                           /* Fetch HTML HEAD or MARC      */
+
+  rc = htget(iurl, type, timeout, filename, content_type, location);
+
+
+/* Try again if redirect                                              */
+
+  if ( ( ( rc == 301 ) || ( rc == 302 ) ) && *location )
+  {
+    strcpy(iurl, location);
+    rc = htget(iurl, type, timeout, filename, content_type, location);
+  }
+
+  if (rc)
+    retc = 0;
+  else if (strcmp(content_type, "application/marc") == 0)
+    retc = 2;
+
+  return retc;
+}
Index: /gsdl/stable/runtime-src/packages/d2m/win32.mak
===================================================================
--- /gsdl/stable/runtime-src/packages/d2m/win32.mak	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/d2m/win32.mak	(revision 20131)
@@ -0,0 +1,58 @@
+# ///////////////// d2m : Dublin Core to MARC converter /////////////////////
+#
+#
+# Generated for Greenstone kjdon May 2005.
+# Used by z3950server
+
+GSDLHOME = ..\..\..
+GSDL_VC4 = 0
+CC = cl
+AR = lib
+
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+!IF $(DLL)
+CXXFLAGS = $(CXXFLAGS) -MD 
+!ELSE
+!IF ($(DLLDEBUG))
+CXXFLAGS = $(CXXFLAGS) -MDd
+!ENDIF
+!ENDIF
+
+o = .obj
+
+DEFS=-DHAVE_CONFIG_H -D__WIN32__ -D_CRT_SECURE_NO_DEPRECATE
+INCLUDES= -I"$(GSDLHOME)"
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+
+LIB_OBJS = MARC2709$o MARCtidy$o usMARC$o util$o strcasecmp$o
+
+all: libd2m.lib
+
+libd2m.lib: $(LIB_OBJS)
+	if EXIST libd2m.lib del libd2m.lib
+	$(AR) -nologo /out:libd2m.lib $(LIB_OBJS)
+
+install:
+
+clean:
+	del *$o 
+	del libd2m.lib
+
+distclean: clean
+	rm -f Makefile config.h
+
Index: /gsdl/stable/runtime-src/packages/yaz/GSDL_USAGE.html
===================================================================
--- /gsdl/stable/runtime-src/packages/yaz/GSDL_USAGE.html	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/yaz/GSDL_USAGE.html	(revision 20131)
@@ -0,0 +1,124 @@
+<html>
+<head>
+<title>Using the Z39.50 Client in Greenstone</title>
+</head>
+
+<body>
+<a name=top>
+<h1>Using the Z39.50 Client in Greenstone</h1>
+</a>
+<b>Table of Contents</b><br>
+<a href="#whatis">About: What is Z39.50?</a><br>
+<a href="#config">Configuring Greenstone - Adding Servers</a><br>
+<a href="#todo">Currently known problems, and TODO list</a><br>
+<a href="#contact">Contacting Us</a><br>
+
+
+
+<a name=whatis>
+<h2>What is Z39.50?</h2>
+</a>
+Z39.50 is an international client/server protocol for searching bibliographic
+data. It can use the Internet Protocol (TCP/IP), which makes the databases
+on a server available from almost anywhere around the globe. It is widely
+used, for example, in on-line library catalogues. It allows a user to search
+one or more databases and retrieve the results of the query.
+
+<p>
+Our implementation uses the YAZ z39.50 toolkit, written by
+<a href="http://www.indexdata.dk">Index Data</a>.
+
+
+
+<a name=config>
+<h2>Adding Servers</h2>
+</a>
+The file z3950.cfg in the etc/packages directory contains entries for
+each server. By default, no servers are set up, although the config file
+comes with two (commented out) example Z39.50 servers, both for servers
+of the United States' <b>Library of Congress</b>.
+<p>
+Each entry consists of:
+<ul>
+<li>A unique "short name" for internal use by Greenstone.</li>
+<li>The internet name or address of the server, and optionally the
+port that the server is running on if not the default port 210.</li>
+<li>The name of the database to search on that server.</li>
+<li>A string that provides a meaningful name for the "collection".</li>
+<li>An optional "About" string, providing some information about the database
+and/or server.</li>
+<li>Optional icon fields, which are displayed instead of the text on the
+front page.</li>
+</ul>
+The entries need only be separated by whitespace, but for the purposes of
+clarity the sample entry uses newlines and tabs.
+<p>
+The sample Library of Congress entry looks like this:
+<pre>
+LOC
+        z3950.loc.gov:7090
+        Voyager
+        "Library of Congress z39.50 server"
+        About  en  "This is the z39.50 interface to the US LoC catalogue
+           system. It contains approximately 12 million bibliographic records.
+           For server capabilities, look at
+	   &lt;a href=\"http://lcweb.loc.gov/z3950/lcserver.html\"&gt;their web pages&lt;/a&gt;."
+</pre>
+There is a list at the Library Of Congress website containing some 
+<a href="http://lcweb.loc.gov/z3950/agency/resources/testport.html">servers 
+publicly available for testing</a>.
+
+
+<a name=todo>
+<h2>Known Problems/Issues list</h2>
+</a>
+<ul>
+<li>Because of the open nature of the standard, our client may not work with
+some servers. Please notify the author (contact details below) of any
+such problems.</li>
+<li>Because of the large number of Marc fields, only the most frequently
+used fields have been given explicit names in the results. Furthermore,
+these are currently hard-coded to correspond to the USMARC field names.</li>
+<li><b>The z39.50 client will not work when fast-cgi is used!</b>. Currently,
+the use of the fast-cgi package (off by default) will disable the
+use of the z39.50 client code for Greenstone.</li>
+<li>There are spurious &lt;B&gt; tags in the title of the window when
+viewing an individual record.</li>
+<li>Greenstone will claim there are no collections if there are no
+sub-directories in the "collect" directory, even if there are configured
+z39.50 servers, although it will work if there are unbuilt collections.</li>
+</ul>
+
+<b>History</b><br>
+Jul 2001 - finally tracked down and fixed an annoying bug that caused
+greenstone to segfault when retrieving documents for some queries.<br>
+Jun 2001 - decided to drop href for field 856, as some examples have 
+explanatory text in the field as well as the URI.<br>
+Oct 2000 - cache results from server, so cut down the number of connections for
+a single query/document. Also added href for MARC field 856.<br>
+Aug 2000 - Various bug fixes and minor modifications.<br>
+Fri Aug 4 2000 - The z39.50 code is now "stable" in the main source code (in CVS).<br>
+Tue 1 Aug 2000 - selecting a field from the drop-down box now actually works. 
+This results in both quicker replies and more accurate results.<br>
+Mon 24 Jul 2000 - queries are now "AND"ed - for example, the query "computer 
+science" will now only return records that contain both words.<br>
+May-June 2000 - Code written.<br>
+
+<a name=contact>
+<h2>Contact Details</h2>
+</a>
+For general comments about Greenstone, or suggestions for improvements, send
+email to
+<a href="mailto:greenstone@cs.waikato.ac.nz?subject=z39.50 client in Greenstone">greenstone@cs.waikato.ac.nz</a><br>
+<br>
+For bug reports or questions about the z39.50 code itself, send email to
+the author, John McPherson -
+<a href="mailto:jrm21@cs.waikato.ac.nz?subject=z39.50 client in Greenstone"
+>jrm21@cs.waikato.ac.nz</a>.
+
+<p>
+<a href="#top">Back to top</a>
+<p>
+<address>Last modified: July 12, 2001 by John McPherson</address>
+</body>
+</html>
Index: /gsdl/stable/runtime-src/packages/yaz/README.gsdl
===================================================================
--- /gsdl/stable/runtime-src/packages/yaz/README.gsdl	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/yaz/README.gsdl	(revision 20131)
@@ -0,0 +1,24 @@
+The YAZ toolkit is used by the GSDL receptionist
+when acting as a z39.50 client.
+
+June 2005, kjdon:
+Changed to use yaz version 2.1.4. This is also used by the new z3950server.
+The original yaz download has been added to cvs - this is unzipped and untared by the configure script, then only the src and client directories are compiled.
+Greenstone uses the libyaz.a library. yaz_zclient.o is modified from the sample client.o, and now lives in the colservr directory.
+
+Two files are linked against: 
+ client/yaz_client.o, which was modified from Index Data's sample 
+	client code, and
+
+ lib/libyaz.a, which contains all the z39.50 and MARC formatting code.
+	There is probably a lot of stuff in this library that does
+	not need to be there for our purposes, but for now it is,
+	merely wasting some disk space and some compile-time CPU.
+
+John McPherson
+3 August 2000
+
+yaz version 1.6
+
+September 2000:
+removed "ill" "server" "ztest" and "retrieval" subdirs.
Index: /gsdl/stable/runtime-src/packages/yaz/config.status
===================================================================
--- /gsdl/stable/runtime-src/packages/yaz/config.status	(revision 20131)
+++ /gsdl/stable/runtime-src/packages/yaz/config.status	(revision 20131)
@@ -0,0 +1,159 @@
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host ickenham.mdx.ac.uk:
+#
+# ./configure  --cache-file=/home/George/corbanormal/gsdl/config.cache
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: ./config.status [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running ${CONFIG_SHELL-/bin/sh} ./configure  --cache-file=/home/George/corbanormal/gsdl/config.cache --no-create --no-recursion"
+    exec ${CONFIG_SHELL-/bin/sh} ./configure  --cache-file=/home/George/corbanormal/gsdl/config.cache --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "./config.status generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "$ac_cs_usage"; exit 0 ;;
+  *) echo "$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=.
+
+trap 'rm -fr Makefile util/Makefile odr/Makefile z39.50/Makefile asn/Makefile zutil/Makefile comstack/Makefile ccl/Makefile tab/Makefile include/Makefile include/yaz/Makefile lib/Makefile client/Makefile doc/Makefile conftest*; exit 1' 1 2 15
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\&%]/\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF
+/^[ 	]*VPATH[ 	]*=[^:]*$/d
+
+s%@SHELL@%/bin/sh%g
+s%@CFLAGS@%-g -O2%g
+s%@CPPFLAGS@%%g
+s%@CXXFLAGS@%%g
+s%@FFLAGS@%%g
+s%@DEFS@% -DHAVE_READLINE_READLINE_H=1 -DHAVE_READLINE_HISTORY_H=1 -DSTDC_HEADERS=1 %g
+s%@LDFLAGS@%%g
+s%@LIBS@% -lreadline -lhistory%g
+s%@exec_prefix@%${prefix}%g
+s%@prefix@%/usr/local%g
+s%@program_transform_name@%s,x,x,%g
+s%@bindir@%${exec_prefix}/bin%g
+s%@sbindir@%${exec_prefix}/sbin%g
+s%@libexecdir@%${exec_prefix}/libexec%g
+s%@datadir@%${prefix}/share%g
+s%@sysconfdir@%${prefix}/etc%g
+s%@sharedstatedir@%${prefix}/com%g
+s%@localstatedir@%${prefix}/var%g
+s%@libdir@%${exec_prefix}/lib%g
+s%@includedir@%${prefix}/include%g
+s%@oldincludedir@%/usr/include%g
+s%@infodir@%${prefix}/info%g
+s%@mandir@%${prefix}/man%g
+s%@CC@%gcc%g
+s%@CPP@%gcc -E%g
+s%@RANLIB@%ranlib%g
+s%@have_sgml2txt@%no%g
+s%@have_sgml2latex@%no%g
+s%@have_sgml2html@%no%g
+s%@ASNMODULE@%z39.50%g
+s%@ILLMODULE@%ill%g
+s%@ILLLIB@%../ill/libill.a%g
+s%@SUBDIRS_VAR@%util odr z39.50 zutil comstack ccl tab include lib client %g
+
+CEOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+
+CONFIG_FILES=${CONFIG_FILES-"Makefile util/Makefile odr/Makefile z39.50/Makefile asn/Makefile zutil/Makefile comstack/Makefile ccl/Makefile tab/Makefile include/Makefile include/yaz/Makefile lib/Makefile client/Makefile doc/Makefile"}
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+
+
+exit 0
Index: /gsdl/stable/runtime-src/src/colservr/Makefile.in
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/Makefile.in	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/Makefile.in	(revision 20131)
@@ -0,0 +1,148 @@
+###########################################################################
+#
+# Makefile -- runtime-src/src/colservr
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+
+INDEXERS_DIR = $(COMMON_DIR)/indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+
+
+USE_SQLITE = @USE_SQLITE@
+ifeq ($(USE_SQLITE), 1)
+SQLITE_DEFINES = -DUSE_SQLITE
+SQLITE_INCLUDES = -I$(COMMON_PACKAGES_DIR)/sqlite/include
+else
+SQLITE_DEFINES = 
+SQLITE_INCLUDES = 
+endif
+
+
+AR = ar
+CC = @CC@
+CXX = @CXX@
+CFLAGS = @CFLAGS@ @COMPAT32BITFLAGS@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@ -DNZDL -DQUIET -DSHORT_SUFFIX -DPARADOCNUM -DGSDLSERVER $(SQLITE_DEFINES)
+# Do NOT add the "recpt" directory here: the colserver should be independent of the receptionist!
+INCLUDES = -I. -I$(GSDL_DIR) -I$(COMMON_DIR)/src/lib -I$(COMMON_PACKAGES_DIR)/gdbm/include \
+	-I$(INDEXERS_DIR)/mg -I$(INDEXERS_DIR)/mg/lib -I$(INDEXERS_DIR)/mg/src/text \
+	-I$(INDEXERS_DIR)/mgpp/lib -I$(INDEXERS_DIR)/mgpp/text \
+	-I$(COMMON_PACKAGES_DIR)/expat/include $(SQLITE_INCLUDES)
+RANLIB = @RANLIB@
+
+
+COMPILE = $(CC) -c $(CFLAGS) $(DEFS) $(INCLUDES)
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+
+
+.SUFFIXES:
+.SUFFIXES: .c .o
+.c.o:
+	$(COMPILE) $<
+
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+SOURCES = \
+        browsefilter.cpp \
+	collectserver.cpp \
+	collectset.cpp \
+        colservrconfig.cpp \
+	comtypes.cpp \
+	expat_document.cpp \
+	expat_resultset.cpp \
+	filter.cpp \
+	lucenequeryfilter.cpp \
+	lucenesearch.cpp \
+	lucenesource.cpp \
+	maptools.cpp \
+	mgq.c \
+	mgqueryfilter.cpp \
+	mgsearch.cpp \
+	mgsource.cpp \
+	mgppqueryfilter.cpp \
+	mgppsearch.cpp \
+	phrasequeryfilter.cpp \
+	phrasesearch.cpp \
+	querycache.cpp \
+	queryfilter.cpp \
+	queryinfo.cpp \
+	search.cpp \
+	source.cpp \
+	sqlbrowsefilter.cpp
+
+OBJECTS = \
+        browsefilter.o \
+	collectserver.o \
+	collectset.o \
+        colservrconfig.o \
+	comtypes.o \
+	expat_document.o \
+	expat_resultset.o \
+	filter.o \
+	lucenequeryfilter.o \
+	lucenesearch.o \
+	lucenesource.o \
+	maptools.o \
+	mgq.o \
+	mgqueryfilter.o \
+	mgsearch.o \
+	mgsource.o \
+	mgppqueryfilter.o \
+	mgppsearch.o \
+	phrasequeryfilter.o \
+	phrasesearch.o \
+	querycache.o \
+	queryfilter.o \
+	queryinfo.o \
+	search.o \
+	source.o \
+	sqlbrowsefilter.o
+
+LIBRARY = gsdlcolservr.a
+
+
+# Default target: make gsdlcolservr.a
+all: $(LIBRARY)
+
+gsdlcolservr.a: $(OBJECTS)
+	rm -f $(LIBRARY)
+	$(AR) cru $(LIBRARY) $(OBJECTS)
+	$(RANLIB) $(LIBRARY)
+
+install:
+
+clean:
+	rm -f $(OBJECTS) $(LIBRARY)
+
+distclean:
+	rm -f $(OBJECTS) $(LIBRARY) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/runtime-src/src/colservr/browsefilter.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/browsefilter.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/browsefilter.cpp	(revision 20131)
@@ -0,0 +1,309 @@
+/**********************************************************************
+ *
+ * browsefilter.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "browsefilter.h"
+#include "fileutil.h"
+
+
+browsefilterclass::browsefilterclass () {
+  db_ptr = NULL;
+
+  // -- onePerQuery StartResults   integer
+  FilterOption_t filtopt;
+  filtopt.name = "StartResults";
+  filtopt.type = FilterOption_t::integert;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = "1";
+  filtopt.validValues.push_back("1");
+  filtopt.validValues.push_back("10000");
+  filterOptions["StartResults"] = filtopt;
+
+  // -- onePerQuery EndResults     integer
+  filtopt.clear();
+  filtopt.name = "EndResults";
+  filtopt.type = FilterOption_t::integert;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = "-1";
+  filtopt.validValues.push_back("-1");
+  filtopt.validValues.push_back("10000");
+  filterOptions["EndResults"] = filtopt;
+
+  // -- onePerQuery ParentNode     string ("" will return the browsing available)
+  filtopt.clear();
+  filtopt.name = "ParentNode";
+  filtopt.type = FilterOption_t::stringt;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = g_EmptyText;
+  filterOptions["ParentNode"] = filtopt;
+}
+
+browsefilterclass::~browsefilterclass () {
+}
+
+void browsefilterclass::configure (const text_t &key, const text_tarray &cfgline) {
+  filterclass::configure (key, cfgline);
+  if (key == "indexstem") {
+    indexstem = cfgline[0];
+  }
+}
+
+bool browsefilterclass::init (ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  if (!filterclass::init(logout)) return false;
+
+  if (db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: browsefilter contains a null dbclass\n\n";
+    return false;
+  }
+
+  if (indexstem.empty()) {
+    indexstem = collection;
+  }
+
+  db_filename = resolve_db_filename(indexstem,db_ptr->getfileextension());
+  if (!file_exists(db_filename)) {
+    logout << text_t2ascii
+	   << "warning: database \"" << db_filename << "\" does not exist\n\n";
+    //    return false;
+  }
+
+  return true;
+}
+
+void browsefilterclass::filter (const FilterRequest_t &request,
+				FilterResponse_t &response,
+				comerror_t &err, ostream &logout) {
+  int numDocs = 0;
+  outconvertclass text_t2ascii;
+
+  response.clear ();
+  err = noError;
+  if (db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: browsefilter contains a null dbclass\n\n";
+    err = configurationError;
+    return;
+  }
+
+  // open the database
+  db_ptr->setlogout(&logout);
+  if (!db_ptr->opendatabase (db_filename, DB_READER, 100, false)) {
+    // most likely a system problem (we have already checked that the database exists)
+    logout << text_t2ascii
+	   << "system problem: open on database \""
+	   << db_filename << "\" failed\n\n";
+    err = systemProblem;
+    return;
+  }
+
+  // get the browse parameters
+  int startresults = filterOptions["StartResults"].defaultValue.getint();
+  int endresults = filterOptions["EndResults"].defaultValue.getint();
+  text_t parentnode = filterOptions["ParentNode"].defaultValue;
+  OptionValue_tarray::const_iterator options_here = request.filterOptions.begin();
+  OptionValue_tarray::const_iterator options_end = request.filterOptions.end();
+  while (options_here != options_end) {
+    if ((*options_here).name == "StartResults") 
+      startresults = (*options_here).value.getint();
+    else if ((*options_here).name == "EndResults")
+      endresults = (*options_here).value.getint();
+    else if ((*options_here).name == "ParentNode")
+      parentnode = (*options_here).value;
+    else {
+      logout << text_t2ascii
+	     << "warning: unknown browsefilter option \""
+	     << (*options_here).name
+	     << "\" ignored.\n\n";
+    }
+
+    ++options_here;
+  }
+
+  infodbclass info;
+
+  // translate any ".fc", ".pr" etc. stuff in the parentnode
+  parentnode = db_ptr->translate_OID (parentnode, info);
+
+  // adjust topmost browsing node
+  if (parentnode.empty()) parentnode = "browse";
+
+  // get the node
+  if ((request.filterResultOptions & FROID) ||
+      (request.filterResultOptions & FRmetadata)) {
+    if (!db_ptr->getinfo(parentnode, info)) {
+      // didn't find the node
+      logout << text_t2ascii
+	     << "warning: lookup for node \"" << parentnode 
+	     << "\" failed for browsefilter.\n\n";
+    } else {
+      // found the node
+
+      // replace " with the parent node name and split the contains string
+      // into the result set
+      text_tarray resultset;
+      text_t tmptext;
+      text_t &contains = info["contains"];
+      text_t::iterator contains_here = contains.begin();
+      text_t::iterator contains_end = contains.end();
+      while (contains_here != contains_end) {
+	if (*contains_here == '"') tmptext += parentnode;
+	else if (*contains_here == ';') {
+	  if (!tmptext.empty()) resultset.push_back (tmptext);
+	  tmptext.clear();
+	} else tmptext.push_back(*contains_here);
+	
+	++contains_here;
+      }
+      // insert the last result in the set
+      if (!tmptext.empty()) resultset.push_back (tmptext);
+
+      text_tarray offset_resultset;
+      text_t &md_type = info["mdtype"];
+      if (!md_type.empty())
+	{
+	  text_t &md_offset = info["mdoffset"];
+	  if (!md_offset.empty())
+	    {
+	      text_t offsettext;
+
+	      text_t::iterator offset_here = md_offset.begin();
+	      text_t::iterator offset_end = md_offset.end();
+	      while (offset_here != offset_end) 
+		{
+		  if (*offset_here == ';')
+		    {
+		      if (offsettext.empty())
+			{
+			  offset_resultset.push_back ("0");
+			}
+		      else
+			{
+			  offset_resultset.push_back (offsettext);
+			}
+		      offsettext.clear();
+		    } 
+		  else 
+		    {
+		      offsettext.push_back(*offset_here);
+		    }
+		  
+		  ++offset_here;
+		}
+	      // insert the last result in the set
+	      if (offsettext.empty())
+		{
+		  offset_resultset.push_back ("0");
+		}
+	      else
+		{
+		  offset_resultset.push_back (offsettext);
+		}
+	    }
+	  else
+	    {
+	      // add 0 offset for each 'contains' entry
+	      text_tarray::iterator result_here = resultset.begin();
+	      text_tarray::iterator result_end = resultset.end();
+	      while (result_here != result_end) {
+		offset_resultset.push_back("0");
+		++result_here;
+	      }
+	    }
+
+	  // do an intersection with the input set
+	  if (!request.docSet.empty()) {
+
+	    text_tarray intersect_resultset;
+	    text_tarray intersect_offset_resultset;
+	    
+	    text_tarray::const_iterator resultset_here = resultset.begin();
+	    text_tarray::const_iterator resultset_end = resultset.end();
+	    text_tarray::const_iterator offset_resultset_here = offset_resultset.begin();
+	    
+	    while (resultset_here != resultset_end) {
+	      if (in_set (request.docSet, *resultset_here))
+		{
+		  intersect_resultset.push_back (*resultset_here);
+		  intersect_offset_resultset.push_back (*offset_resultset_here);
+		}
+	      ++resultset_here;
+	      ++offset_resultset_here;
+	    }
+	    resultset = intersect_resultset;
+	    offset_resultset = intersect_offset_resultset;
+	  }
+	}
+      else
+	{
+	  // do an intersection with the input set
+	  if (!request.docSet.empty()) {
+	    intersect (resultset, request.docSet);
+	  }
+
+	  // add 0 offset for each 'contains' entry
+	  text_tarray::iterator result_here = resultset.begin();
+	  text_tarray::iterator result_end = resultset.end();
+	  while (result_here != result_end) {
+	    offset_resultset.push_back("0");
+	    ++result_here;
+	  }
+	}
+
+      // create the response
+      numDocs = resultset.size();
+      int resultnum = 1;
+      ResultDocInfo_t resultdoc;
+      text_tarray::iterator result_here = resultset.begin();
+      text_tarray::iterator result_end = resultset.end();
+      text_tarray::iterator offset_result_here = offset_resultset.begin();
+
+      while (result_here != result_end) {
+	// if endresults is -1 get all results
+	if ((endresults != -1) && (resultnum > endresults)) break;
+	if (resultnum >= startresults) {
+	  resultdoc.OID = (*result_here);
+	  if (!md_type.empty())
+	    {
+	      resultdoc.classifier_metadata_type = md_type;
+	      resultdoc.classifier_metadata_offset = offset_result_here->getint();
+	    }
+	  response.docInfo.push_back(resultdoc);
+	}
+
+	++resultnum;
+	++result_here;
+	if (!md_type.empty()) ++offset_result_here;
+      }
+    }
+  }
+
+  db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+  response.numDocs = numDocs;
+  response.isApprox = Exact;
+}
Index: /gsdl/stable/runtime-src/src/colservr/browsefilter.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/browsefilter.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/browsefilter.h	(revision 20131)
@@ -0,0 +1,64 @@
+/**********************************************************************
+ *
+ * browsefilter.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef BROWSEFILTER_H
+#define BROWSEFILTER_H
+
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "comtypes.h"
+#include "filter.h"
+#include "dbclass.h"
+
+
+class browsefilterclass : public filterclass {
+protected:
+  text_t db_filename;
+  text_t indexstem;
+  dbclass *db_ptr;
+
+public:
+  browsefilterclass ();
+  virtual ~browsefilterclass ();
+
+  // configure should be called once for each configuration line
+  // default configures the default filter options
+  virtual void configure (const text_t &key, const text_tarray &cfgline);
+
+  // the db ptr remains the responsability of the calling code and
+  // should be destroyed after this browsefilter is destroyed
+  void set_db_ptr (dbclass *db_ptr_arg) { db_ptr = db_ptr_arg; }
+
+  bool init (ostream &logout);
+  text_t get_filter_name () {return "BrowseFilter";}
+  void filter (const FilterRequest_t &request,
+	       FilterResponse_t &response,
+	       comerror_t &err, ostream &logout);
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/collectserver.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/collectserver.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/collectserver.cpp	(revision 20131)
@@ -0,0 +1,538 @@
+ 
+/**********************************************************************
+ *
+ * collectserver.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "collectserver.h"
+#include "OIDtools.h"
+#include <assert.h>
+#include "display.h"
+
+
+collectserver::collectserver () {
+  configinfo.collection = "null";
+}
+
+collectserver::~collectserver () {
+
+  // clean up the sources
+  sourcelistclass::iterator source_here = sources.begin();
+  sourcelistclass::iterator source_end = sources.end();
+  while (source_here != source_end) {
+    if ((*source_here).s != NULL)
+      delete (*source_here).s;
+    ++source_here;
+  }
+  sources.clear();
+
+  // clean up the filters
+  filtermapclass::iterator filter_here = filters.begin();
+  filtermapclass::iterator filter_end = filters.end();
+  while (filter_here != filter_end) {
+    if ((*filter_here).second.f != NULL) 
+      delete (*filter_here).second.f;
+    ++filter_here;
+  }
+  filters.clear();
+}
+
+// configure should be called for each line in the
+// configuration files to configure the collection server and everything
+// it contains. The configuration should take place just before initialisation
+void collectserver::configure (const text_t &key, const text_tarray &cfgline) {
+  if (cfgline.size() >= 1) {
+    const text_t &value = cfgline[0];
+    if (key == "plugin")
+    {
+    	//get the plugin name
+	const text_t &name = cfgline[0];
+	
+	if (name == "HTMLPlugin")
+	{
+		for (int hI = 1; hI < cfgline.size(); hI++)
+		{
+			const text_t &plugOption = cfgline[hI];
+			
+			if (plugOption == "-use_realistic_book") 
+			{
+				collectinfo.useBook = true;
+				break;
+			}
+		}
+	}
+    }
+    else if (key == "gsdlhome") configinfo.gsdlhome = value;
+    else if (key == "gdbmhome") configinfo.dbhome = value;
+    else if (key == "collecthome") configinfo.collecthome = value;
+    else if (key == "collection") {
+      configinfo.collection = value;
+      collectinfo.shortInfo.name = value;
+    } 
+    else if (key == "collectdir") configinfo.collectdir = value;
+    else if (key == "host") collectinfo.shortInfo.host = value;
+    else if (key == "port") collectinfo.shortInfo.port = value.getint();
+    else if (key == "public") {
+      if (value == "true") collectinfo.isPublic = true;
+      else collectinfo.isPublic = false;
+    } else if (key == "beta") {
+      if (value == "true") collectinfo.isBeta = true;
+      else collectinfo.isBeta = false;
+    } else if (key == "collectgroup") {
+      if (value == "true") collectinfo.isCollectGroup = true;
+      else collectinfo.isCollectGroup = false;
+    } else if ((key == "ccscols") || (key == "supercollection")) collectinfo.ccsCols = cfgline;
+    else if (key == "supercollectionoptions") {
+      text_tarray::const_iterator begin = cfgline.begin();
+      text_tarray::const_iterator end = cfgline.end();
+      while(begin != end) {
+	
+	if (*begin == "uniform_search_results_formatting") {
+	  collectinfo.ccsOptions |= CCSUniformSearchResultsFormatting;
+	}
+	begin++;
+      }
+    }
+    else if (key == "builddate") collectinfo.buildDate = value.getint();
+    else if (key == "languages") collectinfo.languages = cfgline;
+    else if (key == "numdocs") collectinfo.numDocs = value.getint();
+    else if (key == "numsections") collectinfo.numSections = value.getint();
+    else if (key == "numwords") collectinfo.numWords = value.getint();
+    else if (key == "numbytes") collectinfo.numBytes = value.getint();
+    else if (key == "stemindexes") collectinfo.stemIndexes = value.getint();
+    else if (key == "collectionmeta") {
+      // genuine collmeta get added as collectionmeta and collection_macros
+      // .collmeta just get added as collection_macros
+      text_t params;
+      if (cfgline.size() == 3) {
+	// get the params for later
+	text_t::const_iterator first=cfgline[1].begin()+1;
+	text_t::const_iterator last=cfgline[1].end()-1;
+	params=substr(first, last);
+      }
+      
+      text_t meta_name = cfgline[0];
+      if (*(meta_name.begin())=='.') {
+	// a .xxx collectionmeta. strip off the . and
+	// look it up in the indexmap to get the actual value
+	
+	text_t name = substr(cfgline[0].begin()+1,cfgline[0].end());
+	text_t new_name;
+	if (indexmap.from2to(name, new_name)) {
+	  meta_name = new_name;
+	} 
+      } else {
+	// add them to collectionmeta
+	text_tmap lang_map = collectinfo.collectionmeta[cfgline[0]];
+	if (cfgline.size() == 2) {
+	  lang_map[g_EmptyText] = cfgline[1];
+	} else if (cfgline.size() == 3 ) {
+	  // get the lang out of params
+	  paramhashtype params_hash;
+	  splitparams(params, params_hash);
+	  
+	  text_t lang = params_hash["l"];
+	  lang_map[lang] = cfgline[2];
+	  if (lang_map[g_EmptyText].empty()) {
+	    // want the first one as the default if no default specified
+	    lang_map[g_EmptyText] = cfgline[2];
+	  }
+	}
+	collectinfo.collectionmeta[cfgline[0]] = lang_map;
+	
+      }
+      
+      // add all collectionmeta to macro list
+      text_tmap params_map = collectinfo.collection_macros[meta_name];
+      
+      if (cfgline.size() == 2) {// no params for this macro
+	params_map[g_EmptyText] = cfgline[1];
+      }
+      else if (cfgline.size() == 3) {// has params
+	params_map[params] = cfgline[2];
+	if (params_map[g_EmptyText].empty()) {
+	  params_map[g_EmptyText] = cfgline[2];
+	}
+      }
+      collectinfo.collection_macros[meta_name] = params_map;
+    }
+    else if (key == "collectionmacro") {
+      text_t nobrackets;
+      text_tmap params_map = collectinfo.collection_macros[cfgline[0]];
+      // add all to macro list
+      if (cfgline.size() == 2) { // no params for this macro
+	params_map[g_EmptyText] = cfgline[1];
+      }
+      else if (cfgline.size() == 3) {// has params
+	// strip [ ] brackets from params
+	text_t::const_iterator first=cfgline[1].begin()+1;
+	text_t::const_iterator last=cfgline[1].end()-1;
+	nobrackets=substr(first, last);
+	params_map[nobrackets] = cfgline[2];
+      }
+      collectinfo.collection_macros[cfgline[0]] = params_map;
+      
+    } else if (key == "format" && cfgline.size() == 2)
+      collectinfo.format[cfgline[0]] = cfgline[1];
+    else if (key == "building" && cfgline.size() == 2)
+      collectinfo.building[cfgline[0]] = cfgline[1];
+    else if (key == "httpdomain") collectinfo.httpdomain = value;
+    else if (key == "httpprefix") collectinfo.httpprefix = value;
+    else if (key == "receptionist") collectinfo.receptionist = value;
+    else if (key == "buildtype") collectinfo.buildType = value;
+    // backwards compatibility - searchytpes is now a format statement
+    else if (key == "searchtype") { // means buildtype is mgpp
+      if (collectinfo.buildType.empty()) {
+	collectinfo.buildType = "mgpp";
+      }
+      joinchar(cfgline, ',', collectinfo.format["SearchTypes"]);
+      //collectinfo.searchTypes = cfgline;
+    }
+    else if (key == "separate_cjk") {
+      if (value == "true") collectinfo.isSegmented = true;
+      else collectinfo.isSegmented = false;
+    }
+    // What have we set in our collect.cfg file :  document or collection ?
+    else if (key == "authenticate") collectinfo.authenticate = value;
+
+    // What have we set for our group list
+    else if (key == "auth_group") joinchar(cfgline,',',collectinfo.auth_group);
+
+    // store all the mappings for use when collection meta is read later
+    // (build.cfg read before collect.cfg)
+    else if (key == "indexmap" || key == "indexfieldmap" || key == "subcollectionmap" || key == "languagemap" || key == "levelmap") {
+      indexmap.importmap (cfgline, true);
+      
+    } 
+    // In the map the key-value pair contain the same
+    // data i.e key == data, if key is 2 then data is 2
+    
+    // What have we set for our public_documents ACL
+    else if (key == "public_documents")
+       {
+	  text_tarray::const_iterator begin = cfgline.begin();
+	  text_tarray::const_iterator end = cfgline.end();
+	  while(begin != end)
+	     {
+		// key = data i.e if key is 2 then data is 2
+		// collectinfo.public_documents[*begin] is the key
+		// *begin is the data value
+
+		collectinfo.public_documents[*begin] = *begin;
+		++begin;
+	     }
+       }
+    
+    // What have we set for our private_documents ACL
+    else if (key == "private_documents")
+       {
+	  text_tarray::const_iterator begin = cfgline.begin();
+	  text_tarray::const_iterator end = cfgline.end();
+	  while(begin != end)
+	     {
+		// key = data i.e if key is 2 then data is 2
+		// collectinfo.public_documents[*begin] is the key
+		// *begin is the data value
+		
+		collectinfo.private_documents[*begin] = *begin;
+		++begin;
+	     }
+       }
+
+    // dynamic_classifier <UniqueID> "<Options>"
+    else if (key == "dynamic_classifier")
+    {
+      collectinfo.dynamic_classifiers[cfgline[0]] = cfgline[1];
+    }
+  }
+  
+  // configure the filters
+  filtermapclass::iterator filter_here = filters.begin();
+  filtermapclass::iterator filter_end = filters.end();
+  while (filter_here != filter_end) {
+    assert ((*filter_here).second.f != NULL);
+    if ((*filter_here).second.f != NULL) 
+      (*filter_here).second.f->configure(key, cfgline);
+
+    ++filter_here;
+  }
+
+  // configure the sources
+  sourcelistclass::iterator source_here = sources.begin();
+  sourcelistclass::iterator source_end = sources.end();
+  while (source_here != source_end) {
+    assert ((*source_here).s != NULL);
+    if ((*source_here).s != NULL)
+      (*source_here).s->configure(key, cfgline);
+    
+    ++source_here;
+  }
+}
+
+
+void collectserver::configure (const text_t &key, const text_t &value) {
+  text_tarray cfgline;
+  cfgline.push_back (value);
+  configure(key, cfgline);
+}
+
+void collectserver::ping (bool &wasSuccess, comerror_t &error, ostream &logout) {
+  // if we've not been properly configured, then it is a foregone
+  // conclusion that we cannot be active
+  if (this->configinfo.collection == "null")
+    {
+      wasSuccess = false;
+    }
+  // if no build date exists, then the collection was probably not built;
+  // ditto if the number of documents is zero, then something is pretty
+  // wrong
+  else if (this->collectinfo.buildDate == 0 ||
+      this->collectinfo.numDocs == 0)
+    {
+      wasSuccess =  false;
+    }
+  // it is probably okay
+  else
+    wasSuccess = true;
+}
+
+
+bool collectserver::init (ostream &logout) {
+  // delete the indexmap
+  indexmap.clear();
+
+  // init the filters
+  filtermapclass::iterator filter_here = filters.begin();
+  filtermapclass::iterator filter_end = filters.end();
+  while (filter_here != filter_end) {
+    assert ((*filter_here).second.f != NULL);
+    if (((*filter_here).second.f != NULL) &&
+	!(*filter_here).second.f->init(logout)) return false;
+    
+    ++filter_here;
+  }
+
+  // init the sources
+  sourcelistclass::iterator source_here = sources.begin();
+  sourcelistclass::iterator source_end = sources.end();
+  while (source_here != source_end) {
+    assert ((*source_here).s != NULL);
+    if (((*source_here).s != NULL) &&
+	!(*source_here).s->init(logout)) return false;
+    
+    ++source_here;
+  }
+
+  return true;
+}
+
+
+void collectserver::get_collectinfo (ColInfoResponse_t &reponse,
+		      comerror_t &err, ostream &/*logout*/) {
+  reponse = collectinfo; 
+  err = noError;
+}
+
+void collectserver::get_filterinfo (InfoFiltersResponse_t &response,
+				    comerror_t &err, ostream &/*logout*/) {
+  response.clear ();
+
+  // get a list of filter names
+  filtermapclass::iterator filter_here = filters.begin();
+  filtermapclass::iterator filter_end = filters.end();
+  while (filter_here != filter_end) {
+    response.filterNames.insert ((*filter_here).first);
+    ++filter_here;
+  }
+
+  err = noError;
+}
+
+void collectserver::get_filteroptions (const InfoFilterOptionsRequest_t &request,
+				       InfoFilterOptionsResponse_t &response, 
+				       comerror_t &err, ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  filterclass *thisfilter = filters.getfilter(request.filterName);
+  if (thisfilter != NULL) {
+    thisfilter->get_filteroptions (response, err, logout);
+  } else {
+    response.clear ();
+    err = protocolError;
+    logout << text_t2ascii << "Protocol Error: filter options requested for non-existent\n"
+	   << "filter \"" << request.filterName << "\".\n\n";
+  }
+}
+
+void collectserver::filter (FilterRequest_t &request,
+			    FilterResponse_t &response,
+			    comerror_t &err, ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  // translate any ".fc", ".pr" etc. stuff in the docSet
+  text_t translatedOID;
+  text_tarray translatedOIDs;
+  text_tarray::iterator doc_here = request.docSet.begin();
+  text_tarray::iterator doc_end = request.docSet.end();
+  while (doc_here != doc_end) {
+    if (needs_translating (*doc_here)) {
+      sourcelistclass::iterator source_here = sources.begin();
+      sourcelistclass::iterator source_end = sources.end();
+      while (source_here != source_end) {
+	assert ((*source_here).s != NULL);
+	if (((*source_here).s != NULL) &&
+	    ((*source_here).s->translate_OID (*doc_here, translatedOID, err, logout))) {
+	  if (err != noError) return;
+	  break;
+	}
+	++source_here;
+      }
+      translatedOIDs.push_back (translatedOID);
+    } else {
+      translatedOIDs.push_back (*doc_here);
+    }
+    ++doc_here;
+  }
+  request.docSet = translatedOIDs;
+
+  response.clear();
+
+  filterclass *thisfilter = filters.getfilter(request.filterName);
+  if (thisfilter != NULL) {
+    // filter the data
+    thisfilter->filter (request, response, err, logout);
+    if (err != noError) return;
+    // fill in the metadata for each of the OIDs (if it is requested)
+    if (request.filterResultOptions & FRmetadata) {
+      bool processed = false;
+      ResultDocInfo_tarray::iterator resultdoc_here = response.docInfo.begin();
+      ResultDocInfo_tarray::iterator resultdoc_end = response.docInfo.end();
+      while (resultdoc_here != resultdoc_end) {
+	// try each of the sources in turn
+	sourcelistclass::iterator source_here = sources.begin();
+	sourcelistclass::iterator source_end = sources.end();
+	while (source_here != source_end) {
+	  assert ((*source_here).s != NULL);
+	  if (((*source_here).s != NULL) &&
+	      ((*source_here).s->get_metadata(request.requestParams, request.refParams,
+					      request.getParents, request.fields, 
+					      (*resultdoc_here).OID, (*resultdoc_here).metadata, 
+					      err, logout))) {
+	    if (err != noError) return;
+	    processed = true;
+	    break;
+	  }
+	  ++source_here;
+	}
+	if (!processed) {
+
+	  logout << text_t2ascii << "Protocol Error: nothing processed for "
+	   << "filter \"" << request.filterName << "\".\n\n";
+
+	  err = protocolError;
+	  return;
+	}
+	++resultdoc_here;
+      }
+    }  
+  
+    err = noError;
+  }
+  else
+  {
+    response.clear ();
+    err = protocolError;
+    logout << text_t2ascii << "Protocol Error: filter options requested for non-existent\n"
+	   << "filter \"" << request.filterName << "\".\n\n";
+  }
+}
+
+void collectserver::get_document (const DocumentRequest_t &request,
+				  DocumentResponse_t &response,
+				  comerror_t &err, ostream &logout) {
+
+  sourcelistclass::iterator source_here = sources.begin();
+  sourcelistclass::iterator source_end = sources.end();
+  while (source_here != source_end) {
+    assert ((*source_here).s != NULL);
+    if (((*source_here).s != NULL) &&
+	((*source_here).s->get_document (request.OID, response.doc, err, logout))) {
+      if (err != noError) return;
+      break;
+    }
+    ++source_here;
+  }
+}
+
+void collectserver::is_searchable (bool &issearchable, comerror_t &err,
+				   ostream &logout) {
+
+  sourcelistclass::iterator source_here = sources.begin();
+  sourcelistclass::iterator source_end = sources.end();
+  while (source_here != source_end) {
+    assert ((*source_here).s != NULL);
+    if (((*source_here).s != NULL) &&
+	((*source_here).s->is_searchable (issearchable, err, logout))) {
+      if (err != noError) return;
+      break;
+    }
+    ++source_here;
+  }
+}
+
+
+bool operator==(const collectserverptr &x, const collectserverptr &y) {
+  return (x.c == y.c);
+}
+
+bool operator<(const collectserverptr &x, const collectserverptr &y) {
+  return (x.c < y.c);
+}
+
+
+// thecollectserver remains the property of the calling code but
+// should not be deleted until it is removed from this list.
+void collectservermapclass::addcollectserver (collectserver *thecollectserver) {
+  // can't add a null collection server
+  assert (thecollectserver != NULL);
+  if (thecollectserver == NULL) return;
+  
+  // can't add an collection server with no collection name
+  assert (!(thecollectserver->get_collection_name()).empty());
+  if ((thecollectserver->get_collection_name()).empty()) return;
+
+  collectserverptr cptr;
+  cptr.c = thecollectserver;
+  collectserverptrs[thecollectserver->get_collection_name()] = cptr;
+}
+
+// getcollectserver will return NULL if the collectserver could not be found
+collectserver *collectservermapclass::getcollectserver (const text_t &collection) {
+  // can't find a collection with no name
+  if (collection.empty()) return NULL;
+
+  iterator here = collectserverptrs.find (collection);
+  if (here == collectserverptrs.end()) return NULL;
+  
+  return (*here).second.c;
+}
Index: /gsdl/stable/runtime-src/src/colservr/collectserver.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/collectserver.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/collectserver.h	(revision 20131)
@@ -0,0 +1,201 @@
+/**********************************************************************
+ *
+ * collectserver.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+
+#ifndef COLLECTSERVER_H
+#define COLLECTSERVER_H
+
+// Library header files
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "comtypes.h"
+#include "filter.h"
+#include "source.h"
+#include "cfgread.h"
+#include "cnfgable.h" 
+#include "maptools.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+#endif
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\map>
+#elif defined(GSDL_USE_STL_H)
+#  include <map.h>
+#else
+#  include <map>
+#endif
+
+
+struct colservrconf {
+  text_t gsdlhome;
+  text_t collecthome;
+  text_t dbhome;
+  text_t collection;
+  text_t collectdir;
+};
+
+
+class collectserver : public configurable {
+protected:
+  colservrconf configinfo;
+  ColInfoResponse_t collectinfo;
+
+  filtermapclass filters;
+  sourcelistclass sources;
+
+  // some stuff to remember while we are configuring
+  stringmap indexmap;
+
+public:
+  collectserver ();
+  virtual ~collectserver ();
+
+  // add_filter makes another filter available to the collection server
+  // the filter remains the property of the calling code and that
+  // code should destroy the filter after the collection server has been
+  // destroyed.
+  void add_filter (filterclass *thefilter) {filters.addfilter(thefilter);}
+  filtermapclass *get_filtermap_ptr () {return &filters;}
+
+  // add_source makes another source available to the collection server
+  // the source remains the property of the calling code and that
+  // code should destroy the source after the collection server has been
+  // destroyed.
+  void add_source (sourceclass *thesource) {sources.addsource(thesource);}
+  sourcelistclass *get_sourcelist_ptr () {return &sources;}
+
+  // configure should be called for each line in the
+  // configuration files to configure the collection server and everything
+  // it contains. The configuration should take place just before initialisation.
+  virtual void configure (const text_t &key, const text_tarray &cfgline);
+  void configure (const text_t &key, const text_t &value);
+  const colservrconf &get_configinfo () {return configinfo;}
+  text_t get_collection_name () {return configinfo.collection;}
+  bool is_collection_group () {return collectinfo.isCollectGroup;}
+
+
+  // ping indicates whether the collection has appropriate data structures
+  // to be active or not
+  void ping(bool &wasSuccess, comerror_t &err, ostream &logout);
+
+  // init should be called after the collection name has been set and
+  // all initialisation is done. init returns true if the initialisation
+  // was successful, if false is returned then no other functions
+  // should be called (without producing meaningless output).
+  virtual bool init (ostream &logout);
+
+  void get_collectinfo (ColInfoResponse_t &reponse,
+			comerror_t &err, ostream &logout);
+
+  virtual void get_filterinfo (InfoFiltersResponse_t &response,
+			       comerror_t &err, ostream &logout);
+
+  virtual void get_filteroptions (const InfoFilterOptionsRequest_t &request,
+				  InfoFilterOptionsResponse_t &response, 
+				  comerror_t &err, ostream &logout);
+
+  virtual void filter (FilterRequest_t &request,
+		       FilterResponse_t &response,
+		       comerror_t &err, ostream &logout);
+
+
+  virtual void get_document (const DocumentRequest_t &request,
+			     DocumentResponse_t &response,
+			     comerror_t &err, ostream &logout);
+
+  virtual void is_searchable (bool &issearchable, comerror_t &err,
+			      ostream &logout);
+
+};
+
+
+// The collectserverptr function does not 'own' the collectserver. The
+// collectserver should be deleted by the code which created it.
+class collectserverptr {
+public:
+  collectserver *c;
+
+  collectserverptr () {c=NULL;}
+  ~collectserverptr () {}
+};
+
+bool operator==(const collectserverptr &x, const collectserverptr &y);
+bool operator<(const collectserverptr &x, const collectserverptr &y);
+
+typedef map<text_t, collectserverptr, lttext_t> collectserverptrmap;
+
+// contains a list of collectservers indexed by their name
+class collectservermapclass {
+protected:
+  collectserverptrmap collectserverptrs;
+
+public:
+  // type support for collectserverptrmap
+  typedef collectserverptrmap::iterator iterator;
+  typedef collectserverptrmap::const_iterator const_iterator;
+  typedef collectserverptrmap::reference reference;
+  typedef collectserverptrmap::const_reference const_reference;
+  typedef collectserverptrmap::size_type size_type;
+
+  typedef collectserverptrmap::difference_type difference_type;
+  typedef collectserverptrmap::const_reverse_iterator const_reverse_iterator;
+  typedef collectserverptrmap::reverse_iterator reverse_iterator;
+  
+  // basic container support
+  iterator begin () {return collectserverptrs.begin();}
+  const_iterator begin () const {return collectserverptrs.begin();}
+  iterator end () {return collectserverptrs.end();}
+  const_iterator end () const {return collectserverptrs.end();}
+
+  void erase(iterator pos) {collectserverptrs.erase(pos);}
+  void erase(iterator first, iterator last) {collectserverptrs.erase(first, last);}
+  collectservermapclass &operator=(const collectservermapclass &x) 
+    {collectserverptrs=x.collectserverptrs;return *this;}
+
+  bool empty () const {return collectserverptrs.empty();}
+  size_type size() const {return collectserverptrs.size();}
+
+
+  // added functionality
+  void clear () {collectserverptrs.erase(collectserverptrs.begin(),collectserverptrs.end());}
+
+  // thecollectserver remains the property of the calling code but
+  // should not be deleted until it is removed from this list.
+  void addcollectserver (collectserver *thecollectserver);
+
+  // getcollectserver will return NULL if the collectserver could not be found
+  collectserver *getcollectserver (const text_t &collection);
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/collectset.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/collectset.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/collectset.cpp	(revision 20131)
@@ -0,0 +1,593 @@
+/**********************************************************************
+ *
+ * collectset.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#include "collectset.h"
+#include "collectserver.h"
+#include "colservrconfig.h"
+#include "gsdlsitecfg.h"
+#include "gdbmclass.h"
+#include "gsdltools.h"
+#include "fileutil.h"
+#include "filter.h"
+#include "browsefilter.h"
+#include "sqlbrowsefilter.h"
+#include "queryfilter.h"
+#include "mgqueryfilter.h"
+#include "mgppqueryfilter.h"
+#include "mgsource.h"
+#include "lucenequeryfilter.h"
+#include "lucenesource.h"
+
+#include <assert.h>
+
+#ifdef USE_SQLITE
+#include "sqlitedbclass.h"
+#endif
+
+#ifdef USE_MSSQL
+#include "mssqldbclass.h"
+#endif
+
+
+collectset::collectset (text_t& gsdlhome, text_t& collecthome) 
+{
+  // gsdlhome and collecthome will be set as a result of calling this function
+  // collecthome will default to "<gsdlhome>/collect" if not explicitly
+  // specified in config file
+
+  text_tarray collections;
+
+  mgsearch = NULL;
+  mgppsearch = NULL;
+  lucenesearch = NULL;
+
+  // get gsdlhome (if we fail the error will be picked up later -- in
+  // cgiwrapper)
+
+  if (site_cfg_read (gsdlhome, collecthome, httpdomain, httpprefix)) {
+    if (!gsdlhome.empty() && directory_exists(gsdlhome)) {
+      if (read_dir (collecthome, collections)) {
+    
+	text_tarray::const_iterator thiscol = collections.begin();
+	text_tarray::const_iterator endcol = collections.end();
+
+	while (thiscol != endcol) {
+	  // ignore the modelcol
+	  if (*thiscol == "modelcol") {
+	    ++thiscol;
+	    continue;
+	  }
+
+	  this->add_collection (*thiscol, gsdlhome, collecthome);
+
+	  ++thiscol;
+	}
+
+	this->add_all_collection_groups(gsdlhome, collecthome);
+      }
+    }
+  }
+
+  set_gsdl_env_vars(gsdlhome);
+}
+
+
+collectset::collectset (text_t& httpprefix_arg)
+{
+  httpprefix = httpprefix_arg;
+
+  mgsearch = NULL;
+  mgppsearch = NULL;
+  lucenesearch = NULL;
+
+}
+
+collectset::collectset ()
+{
+  mgsearch = NULL;
+  mgppsearch = NULL;
+  lucenesearch = NULL;
+}
+
+collectset::~collectset () {
+  collectservermapclass::iterator here = cservers.begin();
+  collectservermapclass::iterator end = cservers.end();
+
+  while (here != end) {
+    if ((*here).second.c != NULL) {
+      delete (*here).second.c;
+    }
+    ++here;
+  }
+  cservers.clear();
+}
+
+bool collectset::init (ostream &logout) {
+  collectservermapclass::iterator here = cservers.begin();
+  collectservermapclass::iterator end = cservers.end();
+
+  while (here != end) {
+    assert ((*here).second.c != NULL);
+    if ((*here).second.c != NULL) {
+      const colservrconf &configinfo = (*here).second.c->get_configinfo ();
+
+      // configure this collection server
+
+      // note that we read build.cfg before collect.cfg so that the indexmaps
+      // are available to decode defaultindex, defaultsubcollection, and
+      // defaultlanguage
+
+      bool failed_build_cfg = false;
+      if (!build_cfg_read (*((*here).second.c), configinfo.gsdlhome,
+			   configinfo.collecthome, configinfo.collection)) {
+	failed_build_cfg = true;
+
+	outconvertclass text_t2ascii;
+	logout << text_t2ascii 
+	       << "Warning: couldn't read build.cfg file for collection \"" 
+	       << configinfo.collection << "\""
+	       << "  gsdlhome=\"" << configinfo.gsdlhome << "\"\n"
+	       << "  collecthome=\"" << configinfo.collecthome << "\"\n";
+      }
+
+      bool failed_collect_cfg = false;
+      if (!collect_cfg_read (*((*here).second.c), configinfo.gsdlhome,
+			     configinfo.collecthome, configinfo.collection)) {
+	failed_collect_cfg = true;
+	outconvertclass text_t2ascii;
+	logout << text_t2ascii 
+	       << "Warning: couldn't read collect.cfg file for collection \""
+	       << configinfo.collection << "\""
+	       << "  gsdlhome=\"" << configinfo.gsdlhome << "\"\n"
+	       << "  collecthome=\"" << configinfo.collecthome << "\"\n";
+      }
+
+      
+      bool is_colgroup = (*here).second.c->is_collection_group();
+
+      if (failed_collect_cfg) {
+	++here;
+	continue;
+      }
+
+      if (failed_build_cfg && (!is_colgroup)) {
+	++here;
+	continue;
+      }
+      // let a failed build.cfg through if its 'collect.cfg' marks it as 'collectgroup true'
+
+      if (!(*here).second.c->init (logout)) return false;
+
+      (*here).second.c->configure("httpdomain",httpdomain);
+      (*here).second.c->configure("httpprefix",httpprefix);
+    }
+    ++here;
+  }
+
+  return true;
+}
+
+collectservermapclass collectset::servers()
+{ return cservers;
+}
+
+
+void collectset::add_all_collections(const text_t &gsdlhome, 
+				     const text_t& collecthome) 
+{
+  text_tarray collections;
+
+  if (read_dir(collecthome, collections)) {
+
+    text_tarray::const_iterator thiscol = collections.begin();
+    text_tarray::const_iterator endcol = collections.end();
+
+    while (thiscol != endcol) {
+    
+      // ignore the modelcol
+      if (*thiscol == "modelcol") {
+	++thiscol;
+	continue;
+      }
+    
+      // create collection server for this collection
+      this->add_collection (*thiscol, gsdlhome, collecthome);
+    
+      ++thiscol;
+    }
+
+    this->add_all_collection_groups(gsdlhome,collecthome);
+  }
+}
+
+// add_collection sets up the collectionserver and calls
+// add_collectserver
+void collectset::add_collection (const text_t& collection, 
+				 const text_t& gsdlhome,
+				 const text_t& collecthome) 
+{
+
+  this->remove_collection(collection);
+  
+  // read config file to see if built with mg, mgpp, or lucene
+  text_t buildtype = "mg"; // mg is default
+  text_t infodbtype = "gdbm"; // gdbm is default
+
+  collectserver *cserver = NULL;
+
+  text_tarray cfgline;
+  text_t key;
+
+  text_t build_cfg = filename_cat(collecthome, collection, "index", "build.cfg");
+  if (file_exists (build_cfg)) {
+    char *build_cfgc = build_cfg.getcstr();
+    ifstream confin(build_cfgc);
+    
+    if (confin) {
+      while (read_cfg_line(confin, cfgline) >= 0) {
+	if (cfgline.size() == 2) {
+	  key = cfgline[0];
+	  cfgline.erase(cfgline.begin());
+	  if (key == "buildtype") {
+	    buildtype = cfgline[0];
+	  }
+	  if (key == "infodbtype") {
+	    infodbtype = cfgline[0];
+	  }
+	}
+      }
+      confin.close();
+    }
+    delete []build_cfgc;
+
+    cserver = new collectserver();
+
+    // Create a dbclass of the correct type
+    dbclass *db_ptr = NULL;
+
+#ifdef USE_SQLITE
+    if (infodbtype == "sqlite")
+      {
+	sqlitedbclass *sql_db_ptr = new sqlitedbclass();
+	db_ptr = sql_db_ptr;
+
+	// add a sql browse filter
+	sqlbrowsefilterclass *sqlbrowsefilter = new sqlbrowsefilterclass();
+	sqlbrowsefilter->set_sql_db_ptr(sql_db_ptr);
+	cserver->add_filter (sqlbrowsefilter);  
+      }
+#endif
+  
+#ifdef USE_MSSQL
+    if (infodbtype == "mssql")
+      {
+	mssqldbclass *mssql_db_ptr = new mssqldbclass();
+	db_ptr = mssql_db_ptr;
+
+	// add a sql browse filter
+	sqlbrowsefilterclass *sqlbrowsefilter = new sqlbrowsefilterclass();
+	sqlbrowsefilter->set_sql_db_ptr(mssql_db_ptr);
+	cserver->add_filter (sqlbrowsefilter);  
+      }
+#endif
+  
+    // Use GDBM if the infodb type is empty or not one of the values above
+    if (db_ptr == NULL) {
+      db_ptr = new gdbmclass();
+    }
+
+    // add a null filter
+    filterclass *filter = new filterclass ();
+    cserver->add_filter (filter);
+  
+    // add a browse filter
+    browsefilterclass *browsefilter = new browsefilterclass();
+    browsefilter->set_db_ptr(db_ptr);
+    cserver->add_filter (browsefilter);  
+
+    if (buildtype == "mg") {
+      mgsearch = new mgsearchclass();
+ 
+      // add a query filter
+      mgqueryfilterclass *queryfilter = new mgqueryfilterclass();
+      queryfilter->set_db_ptr(db_ptr);
+      queryfilter->set_textsearchptr (mgsearch);
+      cserver->add_filter (queryfilter);
+    
+      // add a mg source
+      mgsourceclass *mgsource = new mgsourceclass ();
+      mgsource->set_db_ptr(db_ptr);
+      mgsource->set_textsearchptr (mgsearch);
+      cserver->add_source (mgsource);
+    }
+    else if (buildtype == "mgpp") {
+      mgppsearch = new mgppsearchclass();
+
+      // add a query filter
+      mgppqueryfilterclass *queryfilter = new mgppqueryfilterclass();
+      queryfilter->set_db_ptr(db_ptr);
+      queryfilter->set_textsearchptr (mgppsearch);
+      cserver->add_filter (queryfilter);
+      
+      // add a mg source
+      mgsourceclass *mgsource = new mgsourceclass ();
+      mgsource->set_db_ptr(db_ptr);
+      mgsource->set_textsearchptr (mgppsearch);
+      cserver->add_source (mgsource);
+    }
+    else if (buildtype == "lucene") {
+      lucenesearch = new lucenesearchclass();
+      lucenesearch->set_gsdlhome(gsdlhome); 
+
+      // add a query filter
+      lucenequeryfilterclass *queryfilter = new lucenequeryfilterclass();
+      queryfilter->set_db_ptr(db_ptr);
+      queryfilter->set_textsearchptr (lucenesearch);
+      cserver->add_filter (queryfilter);
+      
+      // add a lucene source
+      lucenesourceclass *lucenesource = new lucenesourceclass ();
+      lucenesource->set_db_ptr(db_ptr);
+      lucenesource->set_textsearchptr (lucenesearch);
+      cserver->add_source (lucenesource);
+    }
+    else {
+      cerr << "Warning: unrecognized buildtype" << buildtype << endl;
+    }
+
+  }
+  else {
+    // see if it is a collectgroup col
+
+
+    // This routine essentially exists twice in the code now (see add_collection_group)
+    // factor out as support routine
+
+    text_t collect_cfg = filename_cat(collecthome, collection, "etc", "collect.cfg");
+    if (file_exists (collect_cfg)) {
+      char *collect_cfgc = collect_cfg.getcstr();
+      ifstream confin(collect_cfgc);     
+
+      text_t is_collect_group = "false";
+
+      if (confin) {
+	while (read_cfg_line(confin, cfgline) >= 0) {
+	  if (cfgline.size() == 2) {
+	    key = cfgline[0];
+	    
+	    cfgline.erase(cfgline.begin());
+	    if (key == "collectgroup") {
+	      is_collect_group = cfgline[0];
+	    }
+	  }
+	}
+	confin.close();
+      }
+      delete []collect_cfgc;
+      
+      if (is_collect_group != "true") {
+	// an unbuilt leaf collection
+	return;
+      }
+
+      // by this point we know we will need a cserver
+      cserver = new collectserver();
+
+    }
+    else {
+      // no collect.cfg => filter it out from list of collections added
+      return;
+    }
+  }
+
+  // inform collection server and everything it contains about its
+  // collection name
+  cserver->configure ("collection", collection);
+  cserver->configure ("gsdlhome", gsdlhome);
+  cserver->configure ("collecthome", collecthome); 
+  cservers.addcollectserver (cserver);
+}
+
+void collectset::remove_all_collections () {
+
+  // first unload any cached mg databases
+  if (mgsearch != NULL) {
+    mgsearch->unload_database();
+  }
+
+  // now delete the collection server objects
+  collectservermapclass::iterator here = cservers.begin();
+  collectservermapclass::iterator end = cservers.end();
+
+  while (here != end) {
+    if ((*here).second.c != NULL) {
+      delete (*here).second.c;
+    }
+    ++here;
+  }
+  cservers.clear();
+}
+
+void collectset::add_collection_group(const text_t& collection, 
+				      const text_t& gsdlhome,
+				      const text_t& collecthome)
+{
+  text_tarray group;
+
+  text_t collect_group_dir = filename_cat (collecthome, collection);
+
+  // need to read collect.cfg for 'collectgroup' as class hasn't been initialised through 'init' yet
+  text_t is_collect_group;
+  text_tarray cfgline;
+  text_t key;
+  text_t collect_cfg = filename_cat(collect_group_dir, "etc", "collect.cfg");
+  char *collect_cfgc = collect_cfg.getcstr();
+  ifstream confin(collect_cfgc);
+
+  if (confin) {
+    while (read_cfg_line(confin, cfgline) >= 0) {
+      if (cfgline.size() == 2) {
+	key = cfgline[0];
+	cfgline.erase(cfgline.begin());
+	if (key == "collectgroup") {
+	  is_collect_group = cfgline[0];
+	  break;
+	}
+      }
+    }
+    confin.close();
+  }
+  delete []collect_cfgc;
+
+  if (is_collect_group == "true") {
+    if (read_dir (collect_group_dir, group)) {
+      
+      text_tarray::const_iterator thiscol = group.begin();
+      text_tarray::const_iterator endcol = group.end();
+      
+      while (thiscol != endcol) {
+	// ignore the etc directory
+	if (*thiscol == "etc") {
+	  ++thiscol;
+	  continue;
+	}
+	
+	//text_t group_col = filename_cat(collection,*thiscol);
+	// later we check for / in the name. When this is used in a path (via fileanme_cat) the / will be converted  to \ on windows
+	text_t group_col = collection + "/" + *thiscol;
+	this->add_collection (group_col, gsdlhome, collecthome);
+	
+	++thiscol;
+      }
+    }
+  }
+}
+
+void collectset::add_all_collection_groups (const text_t& gsdlhome,
+					    const text_t& collecthome) 
+
+{
+  collectservermapclass::iterator here = cservers.begin();
+  collectservermapclass::iterator end = cservers.end();
+  
+  while (here != end) {
+    text_t collection = (*here).second.c->get_collection_name();
+    this->add_collection_group(collection,gsdlhome,collecthome);
+
+    ++here;
+  }
+}
+
+
+// remove_collection deletes the collection server of collection.
+// This only needs to be called if a collectionserver is to be
+// removed while the library is running. The destructor function
+// cleans up all collectservers when the program exits.
+void collectset::remove_collection (const text_t &collection) {
+
+  // do nothing if no collection server exists for this collection 
+  if (cservers.getcollectserver(collection) == NULL) return;
+
+  // first unload any cached mg databases - we may need to do something
+  // similar to this for mgpp and lucene too
+  if (mgsearch != NULL) {
+    mgsearch->unload_database();
+  }
+
+  // now delete the collection server object
+  collectservermapclass::iterator here = cservers.begin();
+  collectservermapclass::iterator end = cservers.end();
+
+  while (here != end) {
+    if ((*here).second.c != NULL && (*here).first == collection) {
+      delete (*here).second.c;
+      cservers.erase (here);
+      return;
+    }
+    ++here;
+  }
+}
+
+
+// remove_collection deletes the collection server of collection.
+// This only needs to be called if a collectionserver is to be
+// removed while the library is running. The destructor function
+// cleans up all collectservers when the program exits.
+void collectset::remove_collection (const text_t &collection, ostream &logout) {
+
+  remove_collection(collection);
+
+  outconvertclass text_t2ascii;
+  logout << text_t2ascii << "collectset::remove_collection: failed to remove collectserver for "
+	 << collection << "\n";
+}
+
+void collectset::configure(const text_t &key, const text_tarray &cfgline)
+{
+  if ((key == "collection") || (key == "collectdir")) return;
+
+  collectservermapclass::iterator here = cservers.begin();
+  collectservermapclass::iterator end = cservers.end();
+
+  while (here != end) {
+    assert ((*here).second.c != NULL);
+    if ((*here).second.c != NULL) {
+      if (key == "collectinfo") {
+	if ((*here).first == cfgline[0]) {
+	  if (cfgline.size()==3) {
+	    (*here).second.c->configure ("gsdlhome", cfgline[1]);
+	    (*here).second.c->configure ("gdbmhome", cfgline[2]);
+	  }
+	  else {
+	    (*here).second.c->configure ("gsdlhome", cfgline[1]);
+	    (*here).second.c->configure ("collecthome", cfgline[2]);
+	    (*here).second.c->configure ("gdbmhome", cfgline[3]);
+	  }
+	}
+      } else {
+	(*here).second.c->configure (key, cfgline);
+      }
+    }
+
+    ++here;
+  }
+}
+
+void collectset::getCollectionList (text_tarray &collist) 
+{
+  collist.erase(collist.begin(),collist.end());
+
+  collectservermapclass::iterator here = cservers.begin();
+  collectservermapclass::iterator end = cservers.end();
+  while (here != end) {
+    assert ((*here).second.c != NULL);
+    if ((*here).second.c != NULL) {
+      collist.push_back ((*here).second.c->get_collection_name());
+    }
+    ++here;
+  }
+}
+
Index: /gsdl/stable/runtime-src/src/colservr/collectset.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/collectset.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/collectset.h	(revision 20131)
@@ -0,0 +1,77 @@
+/************************************************************
+ * 
+ * Collection set
+ *
+ ************************************************************/
+
+#ifndef COLLECTSET_H
+#define COLLECTSET_H
+
+#include "collectserver.h"
+#include "cnfgable.h"
+#include "mgsearch.h"
+#include "mgppsearch.h"
+#include "lucenesearch.h"
+
+class collectset : public configurable
+{
+ protected:
+  collectservermapclass cservers;
+  mgsearchclass         *mgsearch;
+  mgppsearchclass       *mgppsearch;
+  lucenesearchclass     *lucenesearch;
+  int                   noofservers;
+  text_t                httpdomain;
+  text_t                httpprefix;
+
+ public:
+  collectset(text_t& gsdlhome, text_t& collecthome);
+
+  // this constructor is used by the Firefox Greenstone
+  collectset(text_t& httpprefix_arg);
+
+  // this constructor is used by the local library
+  collectset();
+
+  ~collectset();
+
+  // initialise the collections
+  bool init(ostream &logout);
+
+  // configure all the servers as supplied
+  void configure (const text_t &key, const text_tarray &cfgline);
+
+  // Add/remove collections
+  void add_all_collections (const text_t &gsdlhome, const text_t& collecthome);
+  void remove_all_collections ();
+ 
+  void remove_collection (const text_t &collection);
+  void remove_collection (const text_t &collection, ostream& logout);
+
+  void add_collection (const text_t &collection, 
+		       const text_t &gsdlhome, 
+		       const text_t& collecthome);
+
+  void add_collection_group(const text_t& collection, 
+			    const text_t& gsdlhome, 
+			    const text_t& collecthome);
+
+  void add_all_collection_groups (const text_t& gsdlhome, 
+				  const text_t& collecthome);
+
+  // return the total number of servers in the set
+  int size();
+
+  void getCollectionList(text_tarray &collist);
+
+  // return the component map
+  collectservermapclass servers();
+
+  // return an individual collection server
+  collectserver *getCollectServer(const text_t &collection)
+    {
+      return cservers.getcollectserver(collection);
+    }
+};
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/colservrconfig.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/colservrconfig.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/colservrconfig.cpp	(revision 20131)
@@ -0,0 +1,78 @@
+/**********************************************************************
+ *
+ * colservrconfig.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+#include "colservrconfig.h"
+#include "fileutil.h"
+#include "cfgread.h"
+
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace/std/iostream>
+#  include <ospace/std/fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#  include <fstream.h>
+#else
+#  include <iostream>
+#  include <fstream>
+#endif
+
+// collect_cfg_read reads collect.cfg returning true on success.
+bool collect_cfg_read (collectserver &cserver, const text_t &gsdlhome,
+		       const text_t& collecthome,
+		       const text_t &collection) 
+{
+  text_t filename = filename_cat (collecthome, collection);
+  filename = filename_cat (filename, "custom",collection,"etc","custom.cfg");
+
+  if (!file_exists (filename)) {
+    filename = filename_cat (collecthome, collection, "etc", "collect.cfg");
+
+    if (!file_exists (filename)) {
+      filename = filename_cat (gsdlhome, "etc", "collect.cfg");
+      if (!file_exists (filename)) return false;
+    }
+  }
+
+  return cserver.read_configfile(filename);
+}
+
+
+// build_cfg_read reads build.cfg and returns true on success.
+bool build_cfg_read (collectserver &cserver, const text_t &gsdlhome,
+		     const text_t& collecthome,
+		     const text_t &collection) {
+  text_t filename = filename_cat (collecthome, collection,"index","build.cfg");
+
+  if (!file_exists (filename)) {
+    filename = filename_cat (gsdlhome, "index", "build.cfg");
+    if (!file_exists (filename)) return false;
+  }
+
+  return cserver.read_configfile(filename);
+
+}
Index: /gsdl/stable/runtime-src/src/colservr/colservrconfig.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/colservrconfig.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/colservrconfig.h	(revision 20131)
@@ -0,0 +1,45 @@
+/**********************************************************************
+ *
+ * colservrconfig.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef COLSERVRCONFIG_H
+#define COLSERVRCONFIG_H
+
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "collectserver.h"
+
+
+// collect_cfg_read reads collect.cfg returning true on success.
+bool collect_cfg_read (collectserver &cserver, const text_t &gsdlhome,
+		       const text_t& collecthome, const text_t &collection);
+
+// build_cfg_read reads build.cfg and returns true on success.
+bool build_cfg_read (collectserver &cserver, const text_t &gsdlhome,
+		     const text_t& collecthome, const text_t &collection);
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/comtypes.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/comtypes.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/comtypes.cpp	(revision 20131)
@@ -0,0 +1,294 @@
+/**********************************************************************
+ *
+ * comtypes.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "comtypes.h"
+
+
+text_t get_comerror_string (comerror_t err) {
+  if (err == noError) return "no error";
+  else if (err == authenticationFailure) return "authentication failure";
+  else if (err == protocolError) return "protocol error";
+  else if (err == configurationError) return "configuration error";
+  else if (err == systemProblem) return "system problem";
+  else if (err == syntaxError) return "query syntax error";
+  return "unknown problem";
+}
+
+
+void ShortColInfo_t::clear() {
+  name.clear();
+  host.clear();
+  port = 0;
+}
+
+/*
+   isPublic now defaults to true  most values are default          
+   similar to a constructor in a class to make some initializations
+*/
+
+void ColInfoResponse_t::clear () {
+  shortInfo.clear();
+  useBook=false;
+  isPublic=true;
+  isBeta=false;
+  isSegmented=false;
+  isCollectGroup=false;
+  languages.erase(languages.begin(), languages.end());
+  ccsCols.erase(ccsCols.begin(), ccsCols.end());
+  ccsOptions = 0;
+  stemIndexes = 3; // old default was both provided
+  buildDate=0;
+  buildType.clear();
+  numDocs=0;
+  numSections=0;
+  numWords=0;
+  numBytes=0;
+  format.erase(format.begin(), format.end());
+  building.erase(building.begin(), building.end());
+  httpdomain.clear();
+  httpprefix.clear();
+  receptionist.clear();
+
+  // Setting some authentication parameters use with
+  // various parts of the code.
+  
+  authenticate.clear();         // turned off by default, individual collection authentication
+  auth_group.clear();              // turned off by default, authentication by groups method
+  public_documents.clear();          // turned off by default, allow access to these documents <list>
+  private_documents.clear();           // turned off by default, disallow access to these documents <list>
+    
+}
+
+text_t ColInfoResponse_t::get_collectionmeta(text_t name, text_t lang) {
+  text_t value = collectionmeta[name][lang];
+  if (value.empty()) {
+    value = collectionmeta[name][g_EmptyText];
+  }
+  return value;
+
+}
+
+void InfoFiltersResponse_t::clear () {
+  filterNames.erase(filterNames.begin(), filterNames.end());
+}
+
+
+void InfoFilterOptionsRequest_t::clear () {
+  filterName.clear();
+}
+
+
+void FilterOption_t::clear () {
+  name.clear();
+  type = booleant;
+  repeatable = onePerQuery;
+  defaultValue.clear();
+  validValues.erase(validValues.begin(), validValues.end());
+}
+
+void FilterOption_t::check_defaultValue () {
+  text_tarray::iterator here, end;
+
+  // how the default is interpreted depends on the option type
+  switch (type) {
+  case booleant: 
+  case enumeratedt: // has to be one of the validValues
+    here = validValues.begin ();
+    end = validValues.end ();
+    while (here != end) {
+      if (*here == defaultValue) return;
+      ++here;
+    }
+    
+    break;
+
+  case integert: // has to be in the validValues range
+    if ((validValues.size() >= 2) &&
+	(validValues[0].getint() <= defaultValue.getint()) &&
+	(validValues[1].getint() >= defaultValue.getint()))
+      return;
+    break;
+
+  case stringt: // any value is valid
+    return; 
+  }
+
+  // did not find the defaultValue
+  if (validValues.empty()) defaultValue.clear();
+  else defaultValue = validValues[0];
+}
+
+
+bool operator==(const FilterOption_t &x, const FilterOption_t &y) {
+  return ((x.name == y.name) &&
+	  (x.type == y.type) &&
+	  (x.repeatable == y.repeatable) &&
+	  (x.defaultValue == y.defaultValue) &&
+	  (x.validValues == y.validValues));
+}
+
+bool operator<(const FilterOption_t &x, const FilterOption_t &y) {
+  return ((x.name < y.name) ||
+	  ((x.name == y.name) &&
+	   ((x.type < y.type) ||
+	    ((x.type == y.type) &&
+	     ((x.repeatable < y.repeatable) ||
+	      ((x.repeatable == y.repeatable) &&
+	       ((x.defaultValue < y.defaultValue) ||
+		((x.defaultValue == y.defaultValue) &&
+		 (x.validValues < y.validValues)))))))));
+}
+
+
+
+void InfoFilterOptionsResponse_t::clear () {
+  filterOptions.erase(filterOptions.begin(), filterOptions.end());
+}
+
+
+void OptionValue_t::clear () {
+  name.clear();
+  value.clear();
+}
+
+
+void FilterRequest_t::clear () {
+  filterName.clear();
+  filterLang.clear();
+  filterOptions.erase(filterOptions.begin(), filterOptions.end());
+  docSet.erase(docSet.begin(), docSet.end());
+  filterResultOptions = 0;
+  requestParams.clear();
+  refParams.clear();
+  fields.erase(fields.begin(), fields.end());
+  getParents = false;
+}
+
+
+void TermInfo_t::clear () {
+  term.clear();
+  freq = 0;
+  matchTerms.erase (matchTerms.begin(), matchTerms.end());
+}
+
+
+void MetadataInfo_t::clear () {
+  params.clear();
+  isRef = false;
+  values.erase(values.begin(), values.end());
+  if (parent != NULL) {
+    delete parent;
+    parent = NULL;
+  }
+}
+
+MetadataInfo_t::MetadataInfo_t () {parent=NULL;clear();}
+
+// copy constructor
+MetadataInfo_t::MetadataInfo_t (const MetadataInfo_t &x) {
+  params = x.params;
+  isRef = x.isRef;
+  values = x.values;
+  if (x.parent == NULL) parent = NULL;
+  else {
+    parent = new MetadataInfo_t ();
+    *parent = *(x.parent);
+  }
+}
+
+MetadataInfo_t::~MetadataInfo_t () {
+  if (parent != NULL) {
+    delete parent;
+    parent = NULL;
+  }
+}
+
+MetadataInfo_t &MetadataInfo_t::operator=(const MetadataInfo_t &x) {
+  if (&x != this) {
+    params = x.params;
+    isRef = x.isRef;
+    values = x.values;
+    if (x.parent == NULL) parent = NULL;
+    else {
+      parent = new MetadataInfo_t ();
+      *parent = *(x.parent);
+    }
+  }
+  return *this;
+}
+
+void ResultDocInfo_t::clear () {
+  OID.clear ();
+  ranking = 0;
+  result_num = 0;
+  num_terms_matched = 0;
+  num_phrase_match = 0;
+  docFreq.erase(docFreq.begin(), docFreq.end());
+  metadata.erase(metadata.begin(), metadata.end());
+  classifier_metadata_type.erase(classifier_metadata_type.begin(), 
+				 classifier_metadata_type.end());
+  classifier_metadata_offset = 0;
+  
+}
+
+ResultDocInfo_t &ResultDocInfo_t::operator=(const ResultDocInfo_t &x) {
+  OID = x.OID; 
+  ranking = x.ranking;
+  result_num = x.result_num;
+  num_terms_matched = x.num_terms_matched;
+  num_phrase_match = x.num_phrase_match;
+  docFreq = x.docFreq; 
+  metadata = x.metadata;
+  return *this;
+}
+
+void FilterResponse_t::clear () {
+  error_message = g_EmptyText;
+  numDocs = 0;
+  isApprox = Exact;
+  termInfo.erase (termInfo.begin(), termInfo.end());
+  docInfo.erase (docInfo.begin(), docInfo.end());
+  stopwords.clear();
+}
+
+FilterResponse_t &FilterResponse_t::operator=(const FilterResponse_t &x) {
+  error_message = x.error_message;
+  numDocs = x.numDocs;
+  isApprox = x.isApprox;
+  termInfo = x.termInfo;
+  docInfo = x.docInfo;
+  stopwords = x.stopwords;
+  return *this;
+}
+
+void DocumentRequest_t::clear () {
+  OID.clear();
+  docType.clear();
+  docFormat.clear();
+}
+
+void DocumentResponse_t::clear () {
+  doc.clear();
+}
Index: /gsdl/stable/runtime-src/src/colservr/comtypes.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/comtypes.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/comtypes.h	(revision 20131)
@@ -0,0 +1,378 @@
+/**********************************************************************
+ *
+ * comtypes.h -- 
+ * Copyright (C) 1999,2004  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef COMTYPES_H
+#define COMTYPES_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\vector>
+#  include <ospace\std\list>
+#  include <ospace\std\memory> // for pair
+#  include <ospace\std\map>
+#elif defined(GSDL_USE_STL_H)
+#  include <vector.h>
+#  include <list.h>
+#  include <memory.h> // for pair
+#  include <map.h>
+#else
+#  include <vector>
+#  include <list>
+#  include <memory> // for pair
+#  include <map>
+#endif
+
+
+enum comerror_t {noError, authenticationFailure, protocolError, 
+		 configurationError, systemProblem, syntaxError};
+text_t get_comerror_string (comerror_t err);
+
+
+// ShortColInfo ::= SEQUENCE {
+//   name GeneralString,
+//   host GeneralString,
+//   port INTEGER
+// }
+struct ShortColInfo_t {
+  void clear ();
+  ShortColInfo_t () {clear();}
+
+  text_t name;
+  text_t host;
+  int port;
+};
+
+// for collection metadata: metadata name -> lang -> value
+// for collection macros: macro name -> params -> value
+typedef map<text_t, text_tmap, lttext_t> collectionmeta_map; 
+
+#define CCSUniformSearchResultsFormatting 1
+
+#define SIcasefold 1
+#define SIstem 2
+#define SIaccentfold 4
+
+struct ColInfoResponse_t {
+  void clear ();
+  ColInfoResponse_t () {clear();} 
+  text_t get_collectionmeta(text_t name, text_t lang);
+  
+  ShortColInfo_t shortInfo;
+  bool useBook;	//whether we want to display the book
+  bool isPublic;
+  bool isBeta;
+  bool isSegmented;
+  bool isCollectGroup; // used to group a set of collections as one item on the home page
+  unsigned long buildDate;
+  text_tarray ccsCols;    // empty if collection does not use cross-collection searching
+  int ccsOptions; // uses CCS #defines from above
+  int stemIndexes; // uses SI #defines from above
+  text_tarray languages;
+  unsigned long numDocs;     // 0 if not known
+  unsigned long numSections; // 0 if not known
+  unsigned long numWords;    // 0 if not known
+  unsigned long numBytes;    // 0 if not known
+  collectionmeta_map  collectionmeta;
+  text_tmap      format;
+  collectionmeta_map	 collection_macros; // for collectionmacro config directive (> gsdl 2.53)
+  text_tmap      building;
+  text_t         httpdomain;      // GRB: could these two http items need removing
+  text_t         httpprefix;
+  text_t         receptionist;
+  text_t         buildType;           // 'mg' or 'mgpp' or 'lucene'
+  text_t         authenticate;      // 'document' or 'collection'
+  text_t         auth_group;          // 'mygroup' 'yourgroup'
+  text_tmap      public_documents;    // the acl to allow access to listed documents
+  text_tmap      private_documents;   // the acl to disallow access to listed documents
+  text_tmap      dynamic_classifiers;
+};
+
+
+// -- filter options which might be supported for the QueryFilter
+// --
+// -- onePerQuery StartResults   integer
+// -- onePerQuery EndResults     integer
+// -- onePerQuery QueryType      enumerated (boolean, ranked)
+// -- onePerTerm  Term           string ???
+// -- onePerTerm  Casefold       boolean
+// -- onePerTerm  Stem           boolean
+// -- onePerTerm  Index          enumerated
+// -- onePerTerm  Subcollection  enumerated
+// --
+// -- filter options which might be supported for the BrowseFilter
+// --
+// -- onePerQuery StartResults   integer
+// -- onePerQuery EndResults     integer
+// -- onePerQuery ParentNode     string ("" will return the browsing available)
+// --
+// -- The NullFilter always returns the set it was given, it doesn't have
+// -- any options
+
+// InfoFiltersResponse ::= SEQUENCE {
+//   filterNames StringSet
+// }
+struct InfoFiltersResponse_t {
+  void clear ();
+
+  text_tset filterNames;
+};
+
+// InfoFilterOptionsRequest ::= SEQUENCE {
+//   filterName GeneralString
+// }
+struct InfoFilterOptionsRequest_t {
+  void clear ();
+
+  text_t filterName;
+};
+
+// FilterOption ::= SEQUENCE {
+//   name         GeneralString,
+//   type         ENUMERATED {booleant(0), integert(1), enumeratedt(2), stringt(3)},
+//   repeatable   ENUMERATED {onePerQuery(0), onePerTerm(1), nPerTerm(2)},
+//   defaultValue GeneralString,
+//   -- the interpretation of the validValues depends on the type
+//   -- for boolean: the first value is the false value, the second is true value
+//   -- for integer: the first value is the minimum, the second the maximum
+//   -- for enumerated: all values a listed
+//   -- for string: this value is ignored
+//   validValues  StringSequence
+// }
+struct FilterOption_t {
+  void clear ();
+  void check_defaultValue ();
+  FilterOption_t () {clear();}
+
+  text_t name;
+
+  enum type_t {booleant=0, integert=1, enumeratedt=2, stringt=3};
+  type_t type;
+
+  enum repeatable_t {onePerQuery=0, onePerTerm=1, nPerTerm=2};
+  repeatable_t repeatable;
+
+  text_t defaultValue;
+  text_tarray validValues;
+};
+
+bool operator==(const FilterOption_t &x, const FilterOption_t &y);
+bool operator<(const FilterOption_t &x, const FilterOption_t &y);
+
+
+typedef map<text_t, FilterOption_t, lttext_t> FilterOption_tmap;
+
+
+// InfoFilterOptionsResponse ::= SEQUENCE {
+//   filterOptions SET OF FilterOption
+// }
+struct InfoFilterOptionsResponse_t {
+  void clear ();
+
+  FilterOption_tmap filterOptions;
+};
+
+
+// OptionValue ::= SEQUENCE {
+//   name  GeneralString,
+//   value GeneralString
+// }
+struct OptionValue_t {
+  void clear ();
+
+  text_t name;
+  text_t value;
+};
+
+typedef vector<OptionValue_t> OptionValue_tarray;
+
+
+// -- Terms are presented in the same order that they are requested,
+// -- any information relating to the terms is in reference to the
+// -- index specified for that term.
+//
+// FilterRequest ::= SEQUENCE {
+//   filterName          [0] GeneralString,
+//   filterOptions       [1] IMPLICIT SEQUENCE OF OptionValue,
+//   docSet              [2] IMPLICIT StringSequence, -- the OID "" represents everything
+//   filterResultOptions [3] IMPLICIT BIT STRING {termFreq(0), matchTerms(1), OID(2), 
+//                                                subCol(3), ranking(4), docFreq(5), 
+//                                                metadata(6)}
+// 
+//   -- the next set of options are for the metadata request, 
+//   -- they can be left blank if metadata is not wanted
+//   requestParams       [4] IMPLICIT GeneralString, -- used to negotiate the metadata content
+//   refParams           [5] IMPLICIT GeneralString, -- used to decide whether to return a 
+//                                                   -- reference to the data or the actual data
+//   fields              [6] IMPLICIT StringSet
+//   getParents          [7] IMPLICIT BOOLEAN        -- gets metadata of all parents too
+// }
+#define FRtermFreq   1
+#define FRmatchTerms 2
+#define FROID        4
+#define FRsubCol     8
+#define FRranking    16
+#define FRdocFreq    32
+#define FRmetadata   64
+// used to indicate a full text browse query for mgpp
+#define FRfullTextBrowse  128
+
+struct FilterRequest_t {
+  void clear ();
+  FilterRequest_t () {clear();}
+
+  text_t filterName;
+  text_t filterLang; // non empty if we want info to be retrived in language specific
+  OptionValue_tarray filterOptions;
+  text_tarray docSet;        // empty if not used
+  int filterResultOptions; // use the FR* defines above
+
+  text_t requestParams; // empty if not used
+  text_t refParams;     // empty if not used
+  text_tset fields;   // empty if not used
+  bool getParents;      // defaults to false
+};
+
+
+// TermInfo ::= SEQUENCE {
+//   term       [0] GeneralString,
+//   freq       [1] IMPLICIT INTEGER,       -- 0 if not requested
+//   matchTerms [2] IMPLICIT StringSequence -- empty if not requested
+// }
+struct TermInfo_t {
+  void clear ();
+  TermInfo_t () {clear();}
+
+  text_t term;
+  int freq; // 0 if not requested
+  text_tarray matchTerms; // empty if not requested
+};
+
+typedef vector<TermInfo_t> TermInfo_tarray;
+
+
+// MetadataInfo ::= SEQUENCE {
+//   params  [0] IMPLICIT GeneralString,
+//   isRef   [1] IMPLICIT BOOLEAN,
+//   values  [3] IMPLICIT SEQUENCE OF GeneralString,
+//   name    [4] IMPLICIT GeneralString
+// }
+struct MetadataInfo_t {
+  text_t params;
+  bool isRef;
+  text_tarray values;
+  MetadataInfo_t *parent;
+
+  void clear ();
+  MetadataInfo_t ();
+  MetadataInfo_t (const MetadataInfo_t &x); // copy constructor
+  ~MetadataInfo_t ();
+  MetadataInfo_t &operator=(const MetadataInfo_t &x);
+};
+
+typedef map<text_t, MetadataInfo_t, lttext_t> MetadataInfo_tmap;
+
+// ResultDocInfo ::= SEQUENCE {
+//   OID      [0] IMPLICIT GeneralString,
+//   ranking  [1] IMPLICIT INTEGER,             -- 0 if not requested, range 0-10000
+//   docFreq  [2] IMPLICIT SEQUENCE OF INTEGER, -- empty if not requested
+//   metadata [3] IMPLICIT SEQUENCE OF MetadataInfo, -- no longer a SEQUENCE (SET maybe??)
+//   classifier_metadata_type   [4] IMPLICIT GeneralString,       -- empty if not requested
+//   classifier_metadata_offset [5] IMPLICIT INTEGER,             -- 0 if not requested
+// }
+struct ResultDocInfo_t {
+  void clear ();
+  ResultDocInfo_t () {clear();}
+
+  text_t OID;
+  int result_num;          // place in results list
+  int ranking;             // 0 if not requested (real ranking*10000)
+  int num_terms_matched;   // not available on all versions of mg
+  int num_phrase_match;    // not available on all versions of mg
+  vector<int> docFreq;           // empty if not requested
+  MetadataInfo_tmap metadata;    // empty if not requested
+  text_t classifier_metadata_type;        // empty if not requested
+  int    classifier_metadata_offset;      // 0 if not requested
+  ResultDocInfo_t &operator=(const ResultDocInfo_t &x);
+};
+
+typedef vector<ResultDocInfo_t> ResultDocInfo_tarray;
+
+
+// FilterResponse ::= SEQUENCE {
+//   numDocs   [0] IMPLICIT INTEGER,
+//   isApprox  [1] ENUMERATED {Exact(0), Approximate(1), MoreThan(2)}, -- whether numDocs is approximate
+//   termInfo  [2] IMPLICIT SEQUENCE OF TermInfo,                      -- empty if not required
+//   docInfo   [3] IMPLICIT SEQUENCE OF ResultDocInfo                  -- empty if not required
+// }
+
+enum isapprox {Exact=0, Approximate=1, MoreThan=2};
+
+struct FilterResponse_t {
+  void clear ();
+  FilterResponse_t () {clear();}
+
+  text_t error_message;  // Currently only used by Lucene
+  int numDocs;
+  isapprox isApprox;
+  TermInfo_tarray termInfo; // empty if not requested
+  ResultDocInfo_tarray docInfo; // empty if not requested
+  text_tset stopwords;
+
+  FilterResponse_t &operator=(const FilterResponse_t &x);
+};
+
+
+// DocumentRequest ::= SEQUENCE {
+//   OID       GeneralString,
+//   docType   GeneralString,
+//   docFormat GeneralString
+// }
+struct DocumentRequest_t {
+  void clear ();
+  DocumentRequest_t () {clear();}
+
+  text_t OID;
+  text_t docType;
+  text_t docFormat;
+};
+
+
+// DocumentResponse ::= SEQUENCE {
+//   doc OCTET STRING
+// }
+
+struct DocumentResponse_t {
+  void clear ();
+  DocumentResponse_t () {clear();}
+
+  text_t doc;
+};
+
+
+#endif
+
Index: /gsdl/stable/runtime-src/src/colservr/expat_document.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/expat_document.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/expat_document.cpp	(revision 20131)
@@ -0,0 +1,101 @@
+
+#include <stdio.h>
+#include <string.h>
+#include <expat.h>
+#include "gsdlunicode.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+using namespace std;
+#endif
+
+#include "queryinfo.h"
+
+#include "expat_document.h"
+
+#include "text_t.h"
+#include "fileutil.h"
+#include "expat_resultset.h"
+
+struct resultpack {
+  text_t *current_text;
+  text_t *section_num;
+  text_t *section_level;
+  bool store_text;
+};
+
+static void XMLCALL 
+startElement(void *userData, const char *name, const char **attributes)
+{
+  resultpack * rpack_ptr = (resultpack*)userData;
+  text_t element_name = (char*)name;
+  if (element_name == *(rpack_ptr->section_level)) {
+    text_t id_att = (char *)get_attribute(attributes,"gs2:id");
+    if (id_att == *(rpack_ptr->section_num)) {
+      rpack_ptr->store_text = true;
+    }
+    
+  }
+}
+
+static void XMLCALL
+endElement(void *userData, const char *name)
+{
+  resultpack * rpack_ptr = (resultpack*)userData;
+  text_t element_name = (char*)name;
+  if (element_name == *(rpack_ptr->section_level)) {
+    if (rpack_ptr->store_text == true) {
+      // we have finished now, can we quit this??
+      rpack_ptr->store_text = false;
+    }
+  }
+  
+}
+
+static void XMLCALL
+characterData(void *userData, const char * text, int len) {
+  resultpack * rpack_ptr = (resultpack*)userData;
+  if  (rpack_ptr->store_text) {
+    rpack_ptr->current_text->appendcarr(text, len);
+  }
+}
+
+
+int expat_document(const text_t &filename, const text_t &sec_level, const text_t &sec_num, text_t & doc_content)
+{
+  text_t current_text;
+  current_text.clear();
+  text_t section_num = sec_num;
+  text_t section_level = sec_level;
+
+  resultpack rpack = { &current_text, &section_num, &section_level, false};
+  //cerr << "sec num = "<<sec_num<<", sec level="<<sec_level<<", filename="<<filename<<endl;
+  text_t doc_text;
+  read_file(filename, doc_text);
+
+  char* c_doc_text = doc_text.getcstr();
+  XML_Parser parser = XML_ParserCreate(NULL);
+  
+  XML_SetUserData(parser, &rpack);
+  XML_SetElementHandler(parser, startElement, endElement);
+  XML_SetCharacterDataHandler(parser, characterData);
+  int return_status = 0;
+  const int parse_status 
+    = XML_Parse(parser, c_doc_text, strlen(c_doc_text), XML_TRUE);
+
+  if (parse_status == XML_STATUS_ERROR) {
+    cerr << "Error: " << XML_ErrorString(XML_GetErrorCode(parser)) << " at line " << XML_GetCurrentLineNumber(parser) << endl;
+    return_status = 1;
+  }
+  
+  XML_ParserFree(parser);
+  free(c_doc_text);
+  doc_content = to_uni(current_text);  // Vital for non-ASCII documents
+  return return_status;
+}
+
+
Index: /gsdl/stable/runtime-src/src/colservr/expat_document.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/expat_document.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/expat_document.h	(revision 20131)
@@ -0,0 +1,9 @@
+#ifndef gs_expat_document_h
+#define gs_expat_document_h
+
+class text_t;
+
+int expat_document(const text_t &filename, const text_t & section_level,
+		   const text_t &section_num, text_t & doc_content);
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/expat_resultset.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/expat_resultset.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/expat_resultset.cpp	(revision 20131)
@@ -0,0 +1,153 @@
+
+#include <stdio.h>
+#include <string.h>
+#include <expat.h>
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+using namespace std;
+#endif
+
+#include "text_t.h"
+#include "queryinfo.h"
+#include "gsdlunicode.h"
+
+struct queryresultpack {
+  queryresultsclass* queryresult_ptr;
+  int match_count;
+};
+
+char* get_attribute(const char** attr, char* att_name)
+{
+  char* att_val = NULL;
+
+  for (int i = 0; attr[i]; i += 2) {
+    if (strcmp(attr[i],att_name)==0) {
+      att_val = strdup(attr[i+1]);
+    }
+  }
+
+  return att_val;
+}
+
+static void XMLCALL 
+startElement(void *userData, const char *name, const char **attributes)
+{
+  queryresultpack* qrpack_ptr = (queryresultpack*)userData;
+  queryresultsclass* queryresult_ptr = qrpack_ptr->queryresult_ptr;
+
+  text_t element_name = (char*)name;
+
+  if (element_name == "ResultSet") {
+    char* cached_attribute_str = get_attribute(attributes, "cached");
+    if (cached_attribute_str != NULL) {
+      cerr << "Cached: " << cached_attribute_str << endl;
+    }
+  }
+
+  if (element_name == "Error") {
+    char* error_type_str = get_attribute(attributes, "type");
+    queryresult_ptr->error_message = error_type_str;
+    if ((text_t) error_type_str == "PARSE_EXCEPTION") {
+      queryresult_ptr->syntax_error = true;
+    }
+  }
+
+  if (element_name == "Term") {
+    char* term_value_str = get_attribute(attributes, "value");
+    char* term_frequency_str = get_attribute(attributes, "freq");
+
+    termfreqclass termfreqobj;
+    termfreqobj.termstr = to_uni(term_value_str);
+
+    termfreqobj.termfreq = atoi(term_frequency_str);
+    queryresult_ptr->orgterms.push_back(termfreqobj);
+  }
+
+  if (element_name == "StopWord") {
+    char* stop_word_value_str = get_attribute(attributes, "value");
+    queryresult_ptr->stopwords.insert((text_t) stop_word_value_str);
+  }
+
+  if (element_name=="MatchingDocsInfo") {
+    char* num_match_docs_str = get_attribute(attributes,"num");
+    if (num_match_docs_str != NULL) {
+      int num_match_docs = atoi(num_match_docs_str);
+
+      queryresult_ptr->docs_matched = num_match_docs;
+      free(num_match_docs_str);
+    }
+    else {
+      queryresult_ptr->docs_matched = 0;
+    }
+  }
+
+
+  if (element_name=="Match") {
+
+    char* id = get_attribute(attributes,"id");
+    if (id != NULL)
+    {
+      docresultclass doc;
+      doc.clear();
+      doc.docid = id;
+      doc.docweight = qrpack_ptr->match_count;
+
+      char* termfreq = get_attribute(attributes, "termfreq");
+      if (termfreq != NULL)
+      {
+	doc.num_query_terms_matched = atoi(termfreq);
+      }
+
+      queryresult_ptr->docs.docset[doc.docid] = doc;
+      queryresult_ptr->docs.docorder.push_back(doc.docid);
+      ++qrpack_ptr->match_count;
+
+      free(id);
+    }
+    
+  }
+}
+
+static void XMLCALL
+endElement(void *userData, const char *name)
+{
+  // no need to do anything
+}
+
+
+
+
+int expat_resultset(text_t& xml_text, queryresultsclass& queryresult)
+{
+  queryresult.clear();
+  queryresultpack qrpack = { &queryresult, 0 };
+
+  char * xml_text_cstr = xml_text.getcstr();
+  
+  XML_Parser parser = XML_ParserCreate(NULL);
+  
+  XML_SetUserData(parser, &qrpack);
+  XML_SetElementHandler(parser, startElement, endElement);
+  
+  int return_status = 0;
+  const int parse_status 
+    = XML_Parse(parser, xml_text_cstr, strlen(xml_text_cstr), XML_TRUE);
+  
+  if (parse_status == XML_STATUS_ERROR) {
+    fprintf(stderr,
+	    "%s at line %d\n",
+	    XML_ErrorString(XML_GetErrorCode(parser)),
+	    XML_GetCurrentLineNumber(parser));
+    return_status = 1;
+  }
+  
+  XML_ParserFree(parser);
+  free(xml_text_cstr);
+  
+  return return_status;
+}
Index: /gsdl/stable/runtime-src/src/colservr/expat_resultset.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/expat_resultset.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/expat_resultset.h	(revision 20131)
@@ -0,0 +1,11 @@
+#ifndef gs_expat_resultset_h
+#define gs_expat_resultset_h
+
+class text_t;
+class queryresultsclass;
+
+char* get_attribute(const char** attr, char* att_name);
+int expat_resultset(text_t& xml_text, queryresultsclass& queryresult);
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/filter.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/filter.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/filter.cpp	(revision 20131)
@@ -0,0 +1,338 @@
+/**********************************************************************
+ *
+ * filter.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "filter.h"
+#include "fileutil.h"
+#include <assert.h>
+
+#include <iostream>
+using namespace std;
+
+
+// default constructor does nothing
+filterclass::filterclass () {
+}
+
+// default destructor does nothing
+filterclass::~filterclass () {
+}
+
+// configure should be called once for each configuration line
+// default configures the default filter options
+void filterclass::configure (const text_t &key, const text_tarray &cfgline) {
+  if (cfgline.size() >= 1) {
+    const text_t &value = cfgline[0];
+
+    if (key == "collection") collection = value;
+    else if (key == "collectdir") collectdir = value;
+    else if (key == "gsdlhome") gsdlhome = value;
+    else if (key == "collecthome") collecthome = value;
+    else if (key == "gdbmhome") dbhome = value;
+    else if ((key == "filteroptdefault") && (cfgline.size() == 2)) {
+      // see if this filter has an option with this name
+      FilterOption_tmap::iterator thisfilteroption = 
+	filterOptions.find(cfgline[0]);
+      if (thisfilteroption != filterOptions.end())
+	(*thisfilteroption).second.defaultValue = cfgline[1];
+    }
+  }
+}
+
+text_t filterclass::resolve_db_filename(const text_t& idx,
+					const text_t& file_ext)
+{
+  text_t resolved_filename;
+
+  if (gsdlhome==dbhome) {
+    // dbhome has defaulted to gsdlhome which we take to means the 
+    // database has been specifically moved out of gsdlhome area.
+    // => it should be whereever collecthome is set to
+    resolved_filename = filename_cat(collecthome, collection, "index", "text", idx);
+  }
+  else {
+    // dbhome is explicitly set to something other than gsdlhome
+    // => use dbhome
+    resolved_filename = filename_cat(dbhome, "collect", collection, "index", "text", idx);
+  }
+
+  resolved_filename += file_ext;
+
+  return resolved_filename;
+}
+
+
+// init should be called after all the configuration is done but
+// before any other methods are called
+// default checks all the filter option defaults
+bool filterclass::init (ostream &/*logout*/) {
+  // check all the filter defaults
+  FilterOption_tmap::iterator filteroption_here = filterOptions.begin();
+  FilterOption_tmap::iterator filteroption_end = filterOptions.end();
+  while (filteroption_here != filteroption_end) {
+    (*filteroption_here).second.check_defaultValue ();
+    
+    ++filteroption_here;
+  }
+
+  if (collecthome.empty()) collecthome = filename_cat(gsdlhome,"collect");
+  if (dbhome.empty()) dbhome = gsdlhome;
+  
+  // get the collection directory name
+  if (collectdir.empty()) {
+    collectdir = filename_cat (collecthome, collection);
+  }
+  
+  return true;
+}
+
+// returns the name of this filter
+// default returns "NullFilter"
+text_t filterclass::get_filter_name () {
+  return "NullFilter";
+}
+
+// returns the current filter options
+void filterclass::get_filteroptions (InfoFilterOptionsResponse_t &response,
+				     comerror_t &err, ostream &/*logout*/) {
+  response.clear();
+  response.filterOptions = filterOptions;
+  err = noError;
+}
+
+// default returns nothing
+void filterclass::filter (const FilterRequest_t &request,
+			  FilterResponse_t &response,
+			  comerror_t &err, ostream &/*logout*/) {
+  ResultDocInfo_t resultdoc;
+
+  response.clear();
+
+  if ((request.filterResultOptions & FROID) ||
+      (request.filterResultOptions & FRmetadata)) {
+    // copy the OIDs from the request to the response
+    text_tarray::const_iterator here = request.docSet.begin();
+    text_tarray::const_iterator end = request.docSet.end();
+    while (here != end) {
+      resultdoc.OID = (*here);
+      response.docInfo.push_back(resultdoc);
+
+      ++here;
+    }
+  }
+
+  response.numDocs = response.docInfo.size();
+  response.isApprox = Exact;
+  err = noError;
+}
+
+
+bool operator==(const filterptr &x, const filterptr &y) {
+  return (x.f == y.f);
+}
+
+bool operator<(const filterptr &x, const filterptr &y) {
+  return (x.f < y.f);
+}
+
+
+// thefilter remains the property of the calling code but
+// should not be deleted until it is removed from this list.
+void filtermapclass::addfilter (filterclass *thefilter) {
+  // can't add a null filter
+  assert (thefilter != NULL);
+  if (thefilter == NULL) return;
+  
+  // can't add an filter with no name
+  assert (!(thefilter->get_filter_name()).empty());
+  if ((thefilter->get_filter_name()).empty()) return;
+
+  filterptr fptr;
+  fptr.f = thefilter;
+  filterptrs[thefilter->get_filter_name()] = fptr;
+}
+
+// getfilter will return NULL if the filter could not be found
+filterclass *filtermapclass::getfilter (const text_t &key) {
+  // can't find an filter with no name
+  assert (!key.empty());
+  if (key.empty()) return NULL;
+
+  iterator here = filterptrs.find (key);
+  if (here == filterptrs.end()) return NULL;
+  
+  return (*here).second.f;
+}
+
+
+
+
+// some useful functions for dealing with document sets
+
+// returns -1 if t1 is a child of t2
+// returns 0  if t1 and t2 are not parent-child related
+// returns 1  if t1 is a parent of t2
+int child_compare (const text_t &t1, const text_t &t2) {
+  text_t::const_iterator t1_here = t1.begin();
+  text_t::const_iterator t1_end = t1.end();
+  text_t::const_iterator t2_here = t2.begin();
+  text_t::const_iterator t2_end = t2.end();
+
+  while ((t1_here != t1_end) && (t2_here != t2_end)) {
+    if (*t1_here != *t2_here) return 0; // unrelated
+    ++t1_here;
+    ++t2_here;
+  }
+
+  if ((t1_here == t1_end) && (t2_here == t2_end)) return 0; // equal
+  if (t1_here != t1_end) {
+    if (*t1_here == '.') return -1; // t1 is child
+    else return 0; // unrelated
+  }
+
+  if (t2_here != t2_end) {
+    if (*t2_here == '.') return 1; // t2 is child
+    else return 0; // unrelated
+  }
+
+  return 0; // shouldn't get here...
+}
+
+// intersect places the result in set1
+void intersect (text_tset &set1, const text_tset &set2) {
+  text_tset resultset;
+  int childcomp = 0;
+
+  text_tset::const_iterator set1_here = set1.begin();
+  text_tset::const_iterator set1_end = set1.end();
+  text_tset::const_iterator set2_here = set2.begin();
+  text_tset::const_iterator set2_end = set2.end();
+  while ((set1_here != set1_end) && (set2_here != set2_end)) {
+    if (*set1_here == *set2_here) {
+      // equal
+      resultset.insert (*set1_here);
+      ++set1_here;
+      ++set2_here;
+
+    } else if ((childcomp=child_compare(*set1_here, *set2_here)) != 0) {
+      if (childcomp < 0) {
+	// set1_here is child
+	resultset.insert (*set1_here);
+	++set1_here;
+      } else {
+	// set2_here is child
+	resultset.insert (*set2_here);
+	++set2_here;
+      }
+
+    } else if (*set1_here < *set2_here) {
+      // set1 is less
+      ++set1_here;
+
+    } else {
+      // set2 is less
+      ++set2_here;
+    }
+  }
+
+  set1 = resultset;
+}
+
+void intersect (text_tarray &set1, const text_tset &set2) {
+  text_tarray resultset;
+
+  text_tarray::const_iterator set1_here = set1.begin();
+  text_tarray::const_iterator set1_end = set1.end();
+
+  while (set1_here != set1_end) {
+    if (in_set (set2, *set1_here))
+      resultset.push_back (*set1_here);
+    ++set1_here;
+  }
+  set1 = resultset;
+}
+
+void intersect (text_tarray &set1, const text_tarray &set2) {
+  text_tarray resultset;
+
+  text_tarray::const_iterator set1_here = set1.begin();
+  text_tarray::const_iterator set1_end = set1.end();
+
+  while (set1_here != set1_end) {
+    if (in_set (set2, *set1_here))
+      resultset.push_back (*set1_here);
+    ++set1_here;
+  }
+  set1 = resultset;
+}
+
+// tests to see if el is in set
+bool in_set (const text_tset &set1, const text_t &el) {
+  text_t::const_iterator here = el.begin();
+  text_t::const_iterator end = el.end();
+  text_t tryel, tryel_add;
+  bool first = true;
+
+  // the element is in the set if any of its parents are
+  // in the set
+  do {
+    // get next possible element to try
+    here = getdelimitstr (here, end, '.', tryel_add);
+    if (!first) tryel += ".";
+    first = false;
+    tryel += tryel_add;
+
+    // see if this element is in the set
+    if (set1.find(tryel) != set1.end()) return true;
+  } while (here != end);
+
+  return false;
+}
+
+bool in_set (const text_tarray &set1, const text_t &el) {
+  text_t::const_iterator here = el.begin();
+  text_t::const_iterator end = el.end();
+  text_t tryel, tryel_add;
+  bool first = true;
+
+  // the element is in the set if any of its parents are
+  // in the set
+  do {
+    // get next possible element to try
+    here = getdelimitstr (here, end, '.', tryel_add);
+    if (!first) tryel += ".";
+    first = false;
+    tryel += tryel_add;
+
+    // see if this element is in the set
+    text_tarray::const_iterator h = set1.begin();
+    text_tarray::const_iterator e = set1.end();
+    while (h != e) {
+      if (*h == tryel) return true;
+      ++h;
+    }
+  } while (here != end);
+
+  return false;
+}
Index: /gsdl/stable/runtime-src/src/colservr/filter.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/filter.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/filter.h	(revision 20131)
@@ -0,0 +1,147 @@
+/**********************************************************************
+ *
+ * filter.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef FILTER_H
+#define FILTER_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "comtypes.h"
+
+
+class filterclass {
+protected:
+  text_t gsdlhome;
+  text_t collecthome;
+  text_t dbhome;
+  text_t collection;
+  text_t collectdir;
+
+  FilterOption_tmap filterOptions;
+
+public:
+  filterclass ();
+  virtual ~filterclass ();
+
+  // configure should be called once for each configuration line
+  // default configures the default filter options
+  virtual void configure (const text_t &key, const text_tarray &cfgline);
+
+  // init should be called after all the configuration is done but
+  // before any other methods are called
+  // default checks all the filter option defaults
+  virtual bool init (ostream &logout);
+
+  // returns the name of this filter
+  virtual text_t get_filter_name ();
+
+  // returns the current filter options
+  virtual void get_filteroptions (InfoFilterOptionsResponse_t &response,
+				  comerror_t &err, ostream &logout);
+
+  virtual void filter (const FilterRequest_t &request,
+		       FilterResponse_t &response,
+		       comerror_t &err, ostream &logout);
+
+ protected:
+  text_t resolve_db_filename(const text_t& idx,const text_t& file_ext);
+
+
+};
+
+
+// The filterptr class does not 'own' the filter. The 
+// filter should be deleted by the code which created it.
+class filterptr {
+public:
+  filterclass *f;
+
+  filterptr () {f=NULL;}
+  ~filterptr () {}
+};
+
+bool operator==(const filterptr &x, const filterptr &y);
+bool operator<(const filterptr &x, const filterptr &y);
+
+
+typedef map<text_t, filterptr, lttext_t> filterptrmap;
+
+// contains a list of filters indexed by their name
+class filtermapclass {
+protected:
+  filterptrmap filterptrs;
+
+public:
+  // type support for filterptrmap
+  typedef filterptrmap::iterator iterator;
+  typedef filterptrmap::const_iterator const_iterator;
+  typedef filterptrmap::reference reference;
+  typedef filterptrmap::const_reference const_reference;
+  typedef filterptrmap::size_type size_type;
+
+  typedef filterptrmap::difference_type difference_type;
+  typedef filterptrmap::const_reverse_iterator const_reverse_iterator;
+  typedef filterptrmap::reverse_iterator reverse_iterator;
+  
+  // basic container support
+  iterator begin () {return filterptrs.begin();}
+  const_iterator begin () const {return filterptrs.begin();}
+  iterator end () {return filterptrs.end();}
+  const_iterator end () const {return filterptrs.end();}
+
+  void erase(iterator pos) {filterptrs.erase(pos);}
+  void erase(iterator first, iterator last) {filterptrs.erase(first, last);}
+  filtermapclass &operator=(const filtermapclass &x) {filterptrs=x.filterptrs;return *this;}
+
+  bool empty () const {return filterptrs.empty();}
+  size_type size() const {return filterptrs.size();}
+
+
+  // added functionality
+  void clear () {filterptrs.erase(filterptrs.begin(),filterptrs.end());}
+
+  // thefilter remains the property of the calling code but
+  // should not be deleted until it is removed from this list.
+  void addfilter (filterclass *thefilter);
+
+  // getfilter will return NULL if the filter could not be found
+  filterclass *getfilter (const text_t &key);
+};
+
+
+
+// some useful functions for dealing with document sets
+
+// intersect places the result in set1
+void intersect (text_tset &set1, const text_tset &set2);
+void intersect (text_tarray &set1, const text_tset &set2);
+void intersect (text_tarray &set1, const text_tarray &set2);
+
+// tests to see if el is in set
+bool in_set (const text_tset &set1, const text_t &el);
+bool in_set (const text_tarray &set1, const text_t &el);
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/lucenequeryfilter.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/lucenequeryfilter.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/lucenequeryfilter.cpp	(revision 20131)
@@ -0,0 +1,384 @@
+/**********************************************************************
+ *
+ * lucenequeryfilter.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "lucenequeryfilter.h"
+#include "fileutil.h"
+#include "lucenesearch.h"
+
+/////////////////////////////////
+// functions for queryfilterclass
+/////////////////////////////////
+
+
+lucenequeryfilterclass::lucenequeryfilterclass () 
+  : queryfilterclass() {
+
+  
+  FilterOption_t filtopt;
+  
+  // -- onePerTerm  Level          enumerated
+  // likely to be Doc, Sec, Para, but we dont assume anything now
+  filtopt.clear();
+  filtopt.name = "Level";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filterOptions["Level"] = filtopt;
+
+  // --  IndexField, enumerated, used to list available fields
+  filtopt.clear();
+  filtopt.name = "IndexField";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filtopt.defaultValue = "";
+  filterOptions["IndexField"] = filtopt;
+
+}
+
+lucenequeryfilterclass::~lucenequeryfilterclass () {
+}
+
+
+//whether a query is a full text browse
+bool lucenequeryfilterclass::full_text_browse (int filterRequestOptions) {
+  return (filterRequestOptions & FRfullTextBrowse);
+}
+
+void lucenequeryfilterclass::configure (const text_t &key, const text_tarray &cfgline) {
+  queryfilterclass::configure(key, cfgline);
+
+  if (key == "indexfieldmap") {
+    indexfieldmap.importmap (cfgline);
+    
+    // update the list of indexes in the filter information
+    text_tarray options;
+    indexfieldmap.gettoarray (options);
+
+    text_tarray::const_iterator here = options.begin();
+    text_tarray::const_iterator end = options.end();
+    bool start = true;
+    while (here !=end) {
+      if (!(*here).empty()) {
+	filterOptions["IndexField"].validValues.push_back(*here);
+	if (start) {
+	  filterOptions["IndexField"].defaultValue = *here;
+	  start = false;
+	}
+      }
+      ++here;
+    }
+  } else if (key == "indexlevels") {
+    text_tarray::const_iterator here = cfgline.begin();
+    text_tarray::const_iterator end = cfgline.end();
+    bool first=true;
+    while (here != end) {
+      if (!(*here).empty()) {
+	if (first) {
+	  first = false;
+	  // the default is the first value
+	  filterOptions["Level"].defaultValue = *here;
+	}
+	filterOptions["Level"].validValues.push_back(*here);
+      }
+      ++here;
+    }
+  } else if (key == "textlevel") {
+      ((lucenesearchclass *)textsearchptr)->set_text_level(cfgline[0]);
+  }
+  
+}
+
+
+void lucenequeryfilterclass::filter(const FilterRequest_t &request,
+				  FilterResponse_t &response,
+				  comerror_t &err, ostream &logout) {  
+
+  outconvertclass text_t2ascii;
+
+  response.clear ();
+  err = noError;
+  if (db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: queryfilter contains a null dbclass\n\n";
+    err = configurationError;
+    return;
+  }
+  if (textsearchptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: queryfilter contains a null textsearchclass (lucene)\n\n";
+    err = configurationError;
+    return;
+  }
+  if (full_text_browse(request.filterResultOptions)) {
+    browsefilter(request, response, err, logout);
+    return;
+  }
+  // open the database
+  db_ptr->setlogout(&logout);
+  if (!db_ptr->opendatabase (db_filename, DB_READER, 100, false)) {
+    // most likely a system problem (we have already checked that the database exists)
+    logout << text_t2ascii
+	   << "system problem: open on database \"" << db_filename << "\" failed\n\n";
+    err = systemProblem;
+    return;
+  }
+
+
+  // get the query parameters
+  int startresults, endresults;
+  text_t phrasematch; // not used here any more
+  vector<queryparamclass> queryfilterparams;
+  parse_query_params (request, queryfilterparams, startresults, 
+		      endresults, phrasematch, logout);  
+ 
+   
+  // do query
+  queryresultsclass queryresults;
+  do_multi_query (request, queryfilterparams, queryresults, err, logout);
+  response.error_message = queryresults.error_message;
+  if (err != noError) return;
+
+  // assemble document results
+  if (need_matching_docs (request.filterResultOptions))
+  {
+    // Loop through the query results (ordered by ranking)
+    int resultnum = 1;
+    vector<text_t>::iterator docorder_iterator = queryresults.docs.docorder.begin();
+    while (docorder_iterator != queryresults.docs.docorder.end())
+    {
+      text_t doc_OID = (*docorder_iterator);
+      // logout << "Matching doc OID: " << doc_OID << endl;
+
+      // Make sure this result is in the docset, and either in the request set or the request set is empty
+      docresultmap::iterator doc_result = queryresults.docs.docset.find (doc_OID);
+      if (doc_result != queryresults.docs.docset.end() && (request.docSet.empty() || in_set(request.docSet, doc_OID)))
+      {
+	// Add the matching document
+	ResultDocInfo_t resultdoc;
+	resultdoc.OID = doc_OID;
+	resultdoc.result_num = resultnum;
+	resultdoc.ranking = (int)((*doc_result).second.docweight * 10000.0 + 0.5);
+	resultdoc.num_terms_matched = (*doc_result).second.num_query_terms_matched;
+	response.docInfo.push_back (resultdoc);
+
+	resultnum++;
+      }
+
+      docorder_iterator++;
+    }
+  }
+  
+  // assemble the term results
+  if (need_term_info(request.filterResultOptions)) {
+    // note: the terms have already been sorted and uniqued - ?? have they??
+
+    TermInfo_t terminfo;
+    bool terms_first = true;
+
+    termfreqclassarray::iterator terms_here = queryresults.terms.begin();
+    termfreqclassarray::iterator terms_end = queryresults.terms.end();
+
+    while (terms_here != terms_end) {
+      terminfo.clear();
+      terminfo.term = (*terms_here).termstr;
+      terminfo.freq = (*terms_here).termfreq;
+      // lucene doesn't return any termvariants at this stage, 
+      // so make sure the original term is set
+      terminfo.matchTerms.push_back(terminfo.term);
+      
+      // this bit gets the matchTerms ie the equivalent (stem/casefold) terms
+      if (terms_first) {
+	text_tset::iterator termvariants_here = queryresults.termvariants.begin();
+	text_tset::iterator termvariants_end = queryresults.termvariants.end();
+	while (termvariants_here != termvariants_end) {
+	  terminfo.matchTerms.push_back (*termvariants_here);
+	  ++termvariants_here;
+	}
+      }
+      terms_first = false;
+      
+      response.termInfo.push_back (terminfo);
+
+      ++terms_here;
+    }
+
+    // add the stop words
+    text_tset::iterator stopwords_here = queryresults.stopwords.begin();
+    text_tset::iterator stopwords_end = queryresults.stopwords.end();
+    while (stopwords_here != stopwords_end) {
+      response.stopwords.insert(*stopwords_here);
+      ++stopwords_here;
+    }
+  }
+
+  db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+  response.numDocs = queryresults.docs_matched;
+  response.isApprox = queryresults.is_approx;
+}
+
+void lucenequeryfilterclass::browsefilter(const FilterRequest_t &request,
+					FilterResponse_t &response,
+					comerror_t &err, ostream &logout) {  
+
+  outconvertclass text_t2ascii;
+
+  // get the query parameters
+  int startresults, endresults;
+  text_t phrasematch; // not used here any more, just have it so can use
+                      // parse_query_params function
+  
+  vector<queryparamclass> queryfilterparams;
+  parse_query_params (request, queryfilterparams, startresults, 
+		      endresults, phrasematch, logout);  
+
+    vector<queryparamclass>::const_iterator query_here = queryfilterparams.begin();
+   
+  // do query
+  queryresultsclass queryresults;
+  queryresults.clear();
+  
+  int numDocs = endresults-startresults;
+  textsearchptr->setcollectdir (collectdir);
+
+  if (!((lucenesearchclass*)textsearchptr)->browse_search((*query_here), startresults, numDocs, queryresults)) {
+    // most likely a system problem
+    logout << text_t2ascii
+	   << "system problem: could not do full text browse with lucene for index \""
+	   << (*query_here).index << (*query_here).subcollection
+	   << (*query_here).language << "\".\n\n";
+    err = systemProblem;
+    return;
+  }
+
+  // assemble the term results
+  TermInfo_t terminfo;
+  
+  termfreqclassarray::iterator terms_here = queryresults.terms.begin();
+  termfreqclassarray::iterator terms_end = queryresults.terms.end();
+
+  while (terms_here != terms_end) {
+    terminfo.clear();
+    terminfo.term = (*terms_here).termstr;
+    terminfo.freq = (*terms_here).termfreq;
+    
+    response.termInfo.push_back (terminfo);
+
+    ++terms_here;
+  }
+  
+
+}
+
+// lucenesearchptr and db_ptr are assumed to be valid
+void lucenequeryfilterclass::do_multi_query (const FilterRequest_t &request,
+					   const vector<queryparamclass> &query_params,
+					   queryresultsclass &multiresults,
+					   comerror_t &err, ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  err = noError;
+  textsearchptr->setcollectdir (collectdir);
+  multiresults.clear();
+  
+  vector<queryparamclass>::const_iterator query_here = query_params.begin();
+  vector<queryparamclass>::const_iterator query_end = query_params.end();
+  while (query_here != query_end) {
+    queryresultsclass thisqueryresults;
+    if (!textsearchptr->search((*query_here), thisqueryresults)) {
+      // most likely a system problem
+      logout << text_t2ascii
+	     << "system problem: could not do search with lucene for index \""
+	     << (*query_here).index << (*query_here).level 
+	     << (*query_here).subcollection
+	     << (*query_here).language << "\".\n\n";
+      err = systemProblem;
+      return;
+    }
+
+    // check for syntax error
+    if (thisqueryresults.syntax_error==true) {
+      logout << text_t2ascii
+	     << "syntax problem: invalid query string \""
+	     << (*query_here).querystring<<"\".\n";
+      err = syntaxError;
+      return;
+    }
+    // combine the results
+    if (need_matching_docs (request.filterResultOptions)) {
+            
+      if (query_params.size() == 1) {
+	multiresults.error_message = thisqueryresults.error_message;
+	multiresults.docs = thisqueryresults.docs; // just one set of results
+	multiresults.docs_matched = thisqueryresults.docs_matched;
+	multiresults.is_approx = thisqueryresults.is_approx;
+	
+      } else {
+	if ((*query_here).combinequery == "and") {
+	  multiresults.docs.combine_and (thisqueryresults.docs);
+	} else if ((*query_here).combinequery == "or") {
+	  multiresults.docs.combine_or (thisqueryresults.docs);
+	} else if ((*query_here).combinequery == "not") {
+	  multiresults.docs.combine_not (thisqueryresults.docs);
+	}
+	multiresults.docs_matched = multiresults.docs.docset.size();
+	multiresults.is_approx = Exact;
+      }
+    }
+
+    // combine the term information 
+    if (need_term_info (request.filterResultOptions)) {
+      // append the terms
+      multiresults.orgterms.insert(multiresults.orgterms.end(),
+				   thisqueryresults.orgterms.begin(),
+				   thisqueryresults.orgterms.end());
+
+      
+      // add the term variants - 
+      text_tset::iterator termvar_here = thisqueryresults.termvariants.begin();
+      text_tset::iterator termvar_end = thisqueryresults.termvariants.end();
+      while (termvar_here != termvar_end) {
+	multiresults.termvariants.insert(*termvar_here);
+	++termvar_here;
+      }
+
+      // add the stop words
+      text_tset::iterator stopwords_here = thisqueryresults.stopwords.begin();
+      text_tset::iterator stopwords_end = thisqueryresults.stopwords.end();
+      while (stopwords_here != stopwords_end) {
+	multiresults.stopwords.insert(*stopwords_here);
+	++stopwords_here;
+      }
+    }
+   
+    ++query_here;
+  }
+
+  // sort and unique the query terms
+  multiresults.sortuniqqueryterms ();
+}
+
+
+
Index: /gsdl/stable/runtime-src/src/colservr/lucenequeryfilter.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/lucenequeryfilter.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/lucenequeryfilter.h	(revision 20131)
@@ -0,0 +1,67 @@
+/**********************************************************************
+ *
+ * lucenequeryfilter.h -- new queryfilter to use lucene 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+
+#ifndef LUCENEQUERYFILTER_H
+#define LUCENEQUERYFILTER_H
+
+#include "queryfilter.h"
+
+class lucenequeryfilterclass : public queryfilterclass {
+protected:
+
+  stringmap indexfieldmap;
+  bool full_text_browse (int filterRequestOptions);
+
+  // mgsearchptr and db_ptr are assumed to be valid
+  void do_multi_query (const FilterRequest_t &request,
+		       const vector<queryparamclass> &query_params,
+		       queryresultsclass &multiresults,
+		       comerror_t &err, ostream &logout);
+
+
+public:
+  lucenequeryfilterclass ();
+  virtual ~lucenequeryfilterclass ();
+
+  void configure (const text_t &key, const text_tarray &cfgline);
+
+  void filter (const FilterRequest_t &request,
+		       FilterResponse_t &response,
+		       comerror_t &err, ostream &logout);
+  
+  void browsefilter(const FilterRequest_t &request,
+		    FilterResponse_t &response,
+		    comerror_t &err, ostream &logout);  
+
+
+};
+
+#endif
+
+
+
Index: /gsdl/stable/runtime-src/src/colservr/lucenesearch.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/lucenesearch.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/lucenesearch.cpp	(revision 20131)
@@ -0,0 +1,250 @@
+/**********************************************************************
+ *
+ * lucenesearch.cpp -- 
+ * Copyright (C) 1999-2002  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+#endif
+
+#include <stdio.h>
+#include <time.h>
+
+#include "gsdlconf.h"
+#include "gsdltools.h"
+#include "lucenesearch.h"
+#include "fileutil.h"
+#include "queryinfo.h"
+#include "gsdlunicode.h"
+
+#include "expat_resultset.h"
+
+text_t lucenesearchclass::getindexsuffix(const queryparamclass &qp) {
+  text_t indexsuffix = "index";
+  // get the first char of the level to be the start of the index name
+  text_t suffix = substr(qp.level.begin(), qp.level.begin()+1);
+  lc(suffix);
+  text_t ind = qp.index;
+  text_t sub = qp.subcollection;
+  text_t lang = qp.language;
+   
+  // collection name not added for Lucene
+  indexsuffix = filename_cat(indexsuffix, suffix +ind + sub + lang);
+  return indexsuffix;
+
+}
+
+////////////////////
+// lucenesearch class //
+////////////////////
+
+lucenesearchclass::lucenesearchclass ()
+  : searchclass() {
+
+  textlevel = "Doc";
+}
+
+lucenesearchclass::~lucenesearchclass () 
+{
+  if (cache != NULL) 
+    {
+      delete cache;
+      cache = NULL;
+    }
+}
+
+void lucenesearchclass::set_text_level(const text_t &textlevel_arg)
+{
+  textlevel = textlevel_arg;
+}
+
+
+bool lucenesearchclass::search(const queryparamclass &queryparams, 
+			       queryresultsclass &queryresult) {
+ 
+#ifdef __WIN32__
+  char basepath[]="";
+#else
+  char basepath[] = "/";
+#endif
+ 
+  char *indexname = (filename_cat(collectdir, getindexsuffix(queryparams))).getcstr(); 
+
+  // set default stem method from values originally set on prefs page
+  int defaultStemMethod = 0;
+  if (queryparams.casefolding) {
+    defaultStemMethod |= 1;
+  }
+  if (queryparams.stemming) {
+    defaultStemMethod |= 2;
+  }
+
+  text_t utf8querystring = to_utf8(queryparams.querystring);
+
+  text_t escaped_utf8querystring = "";
+  text_t::const_iterator here = utf8querystring.begin();
+  while (here != utf8querystring.end()) {
+    if (*here == '"') escaped_utf8querystring.push_back('\\');
+    escaped_utf8querystring.push_back(*here);
+    ++here;
+  }
+
+  // Use this to skip lucene_query.pl and access GS2LuceneQuery directly (Java must be on path)
+  // text_t cmd = "java -classpath \"" + filename_cat(gsdlhome, "bin", "java", "LuceneWrapper.jar") + "\" org.greenstone.LuceneWrapper.GS2LuceneQuery ";
+  text_t cmd = "\"" + filename_cat(gsdlhome, "bin", "script", "lucene_query.pl") + "\"";
+  cmd += (text_t)" \""+indexname + (text_t)"\" \"" + escaped_utf8querystring + (text_t)"\""; 
+
+  if (!queryparams.filterstring.empty()) {
+    cmd += " -filter \"" + queryparams.filterstring + "\"";
+  }
+  if (!queryparams.sortfield.empty()) {
+    cmd += " -sort \"" + queryparams.sortfield + "\"";
+  }
+  if (!queryparams.fuzziness.empty()) {
+    cmd += " -fuzziness " + queryparams.fuzziness;
+  }
+
+  // New code to support configuration of the default conjuction operator
+  // set default Boolean combiner from all/some setting
+  // if match_mode == 1, ie all, default=1 ie AND
+  // if match_mode == 0, ie some, default=0, ie OR
+  if (queryparams.match_mode)
+    {
+      cmd += " -dco AND";
+    }
+
+  // New code to allow Lucene to do paging of search results. This should
+  // substantially improve performance as we don't have to return all 12000
+  // hits if we only need the first 20!
+  if (queryparams.startresults && queryparams.endresults)
+    {
+      cmd += (text_t)" -startresults " + queryparams.startresults;
+      cmd += (text_t)" -endresults " + queryparams.endresults;
+    }
+
+  text_t xml_text = "";
+
+  // I don't want to do this, but I have to.
+  text_t gsdlhome_env = "GSDLHOME=" + gsdlhome;
+  putenv(gsdlhome_env.getcstr());
+
+#ifdef __WIN32__
+  putenv("GSDLOS=windows");
+
+  //FILE *PIN = _popen(cmd.getcstr(), "r"); // didn't seem to work
+  cmd = (text_t)"perl -S "+cmd;
+  // we write the result to a file
+  clock_t this_time = clock();
+  text_t filename = "luc";
+  filename.append(this_time);
+  filename.append(".txt");
+ 
+  text_t out_file = filename_cat(collectdir, filename);
+  cmd += " -out \"" + out_file + "\"";
+  int rv = gsdl_system(cmd, true, cerr);
+  if (rv != 0) {
+    cerr << "tried to run command \""<<cmd<<"\", but it failed\n";
+  } else {
+    read_file(out_file, xml_text);
+    remove(out_file.getcstr()); // now delete it
+  }
+#else
+
+#if defined(MACOS)
+  putenv("GSDLOS=darwin"); 
+#else
+  putenv("GSDLOS=linux"); 
+#endif
+
+  // What about Solaris etc ????
+
+
+  FILE *PIN = popen(cmd.getcstr(), "r");
+
+  if (PIN==NULL) {
+    perror("PIPE");
+    cerr << "Error: unable to open pipe to " << cmd << endl;
+    
+    return false;
+  }
+  while (!feof(PIN)) {
+    char buffer[256];
+    int num_bytes = fread(buffer,1,256,PIN);
+    xml_text.appendcarr(buffer,num_bytes);
+  }
+
+#endif
+
+  expat_resultset(xml_text,queryresult);
+  
+#ifdef __WIN32__
+  //  _pclose(PIN);
+#else
+  pclose(PIN);
+#endif
+
+  return true;
+}
+
+
+bool lucenesearchclass::browse_search(const queryparamclass &queryparams, 
+				      int start, int numDocs,
+				      queryresultsclass &queryresult) {
+
+  cerr << "**** Not sure what this function does!" << endl;
+  return false;
+}
+
+// the document text for 'docnum' is placed in 'output'
+// docTargetDocument returns 'true' if it was able to
+// try to get a document
+// collection is needed to see if an index from the 
+// collection is loaded. THe default index bits are just there cos
+// the mg version needs them
+
+bool lucenesearchclass::docTargetDocument(const text_t &/*defaultindex*/,
+					const text_t &/*defaultsubcollection*/,
+					const text_t &/*defaultlanguage*/,
+					const text_t &collection,
+					int docnum,
+					text_t &output) {
+
+  // we now get the document directly by lucenesource, so don't use this 
+  // method
+  return false;
+}
+
+// used to clear any cached databases for persistent versions of 
+// Greenstone like the Windows local library
+void lucenesearchclass::unload_database () {
+}
+
+void lucenesearchclass::set_gsdlhome (const text_t &gh)
+{
+  gsdlhome = gh;
+}
Index: /gsdl/stable/runtime-src/src/colservr/lucenesearch.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/lucenesearch.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/lucenesearch.h	(revision 20131)
@@ -0,0 +1,96 @@
+/**********************************************************************
+ *
+ * lucenesearch.h -- implementation of search class for lucene
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * 
+ *
+ *********************************************************************/
+
+
+#ifndef LUCENESEARCH_H
+#define LUCENESEARCH_H
+
+#include "search.h"
+
+class lucenesearchclass : public searchclass {
+public:
+  lucenesearchclass ();
+  virtual ~lucenesearchclass ();
+
+  virtual text_t get_textindex_type() {return "lucene";}
+
+  // the search results are returned in queryresults
+  // search returns 'true' if it was able to do a search
+  virtual bool search(const queryparamclass &queryparams, 
+		      queryresultsclass &queryresults);
+  
+  // this returns a list of terms in queryresults - no document info is returned
+  // returns a list of numTerms terms, starting from the query string term (in queryparams)
+  // + start. used for full text browsing
+  virtual bool browse_search(const queryparamclass &queryparams, int start, int numTerms,
+			     queryresultsclass &queryresults);
+
+  // the document text for 'docnum' is placed in 'output'
+  // docTargetDocument returns 'true' if it was able to
+  // try to get a document
+  // collection is needed to see if an index from the 
+  // collection is loaded. If no index has been loaded
+  // defaultindex is needed to load one
+  virtual bool docTargetDocument(const text_t &defaultindex,
+			 const text_t &defaultsubcollection,
+			 const text_t &defaultlanguage,
+			 const text_t &collection,
+			 int docnum,
+			 text_t &output);
+
+  /*  // same as docTargetDocument except the document is returned
+  // in its raw form. UDoc remains the property of mg and may
+  // be destroyed on the next call to mg.
+  // not implemented for lucene
+  virtual bool mgdocument (const text_t &defaultindex,
+		   const text_t &defaultsubcollection,
+		   const text_t &defaultlanguage,
+		   const text_t &collection,
+		   int docnum,
+		   char *&UDoc, int &ULen);
+  */
+
+  void set_text_level(const text_t &textlevel_arg);
+  text_t textlevel;
+
+  // used to clear any cached databases for persistent versions of 
+  // Greenstone like the Windows local library
+  void unload_database ();
+
+  void set_gsdlhome (const text_t &gh);
+
+ protected:
+  text_t getindexsuffix(const queryparamclass &qp);
+
+ private:
+  text_t gsdlhome;
+
+};
+
+
+#endif
+
Index: /gsdl/stable/runtime-src/src/colservr/lucenesource.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/lucenesource.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/lucenesource.cpp	(revision 20131)
@@ -0,0 +1,94 @@
+/**********************************************************************
+ *
+ * lucenesource.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "lucenesource.h"
+#include "fileutil.h"
+#include "OIDtools.h"
+#include "expat_document.h"
+#include "lucenesearch.h"
+
+lucenesourceclass::lucenesourceclass () 
+  : sourceclass()
+{
+  classname = "lucenesource";
+}
+
+lucenesourceclass::~lucenesourceclass () {
+}
+
+bool lucenesourceclass::get_document (const text_t &OID, text_t &doc, 
+				      comerror_t &err, ostream &logout) {
+
+  outconvertclass text_t2ascii;
+  err = noError;
+  if (db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: lucenesource contains a null dbclass\n\n";
+    err = configurationError;
+    return true;
+  }
+
+  // open the database
+  db_ptr->setlogout(&logout);
+  if (!db_ptr->opendatabase (db_filename, DB_READER, 100, false)) {
+    // most likely a system problem (we have already checked that the database exists)
+    logout << text_t2ascii
+	   << "system problem: open on database \"" << db_filename << "\" failed\n\n";
+    err = systemProblem;
+    return true;
+  }
+
+  text_t tOID = OID;
+  if (needs_translating (OID)) 
+    translate_OID (OID, tOID, err, logout);
+  infodbclass info;
+  if (!db_ptr->getinfo(tOID, info)) {
+    db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+    return false;
+  }
+
+  if (info["hastxt"].getint() == 0) { // there is no text for this section
+    return false; // true??
+  }
+  int docnum = info["docnum"].getint();
+
+  // get the parent id
+  text_t parent_OID;
+  get_top(tOID, parent_OID);
+  
+  if (!db_ptr->getinfo(parent_OID, info)) {
+    db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+    return false;
+  }
+
+  text_t archive_dir = info["archivedir"];
+  text_t full_path_to_doc = filename_cat(collectdir, "index", "text", archive_dir, "doc.xml");
+  
+  doc.clear();
+  db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+  expat_document(full_path_to_doc, ((lucenesearchclass*)textsearchptr)->textlevel, text_t(docnum), doc);
+  return true;
+}
Index: /gsdl/stable/runtime-src/src/colservr/lucenesource.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/lucenesource.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/lucenesource.h	(revision 20131)
@@ -0,0 +1,50 @@
+/**********************************************************************
+ *
+ * lucenesource.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef LUCENESOURCE_H
+#define LUCENESOURCE_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "comtypes.h"
+#include "maptools.h"
+#include "search.h"
+#include "source.h"
+
+
+class lucenesourceclass : public sourceclass {
+public:
+  lucenesourceclass ();
+  virtual ~lucenesourceclass ();
+
+  bool get_document (const text_t &OID, text_t &doc, 
+		     comerror_t &err, ostream &logout);
+
+};
+
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/maptools.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/maptools.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/maptools.cpp	(revision 20131)
@@ -0,0 +1,183 @@
+/**********************************************************************
+ *
+ * maptools.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "maptools.h"
+
+
+
+void stringmap::clear () {
+  fromorder.erase (fromorder.begin(), fromorder.end());
+  mapfrom.erase (mapfrom.begin(), mapfrom.end());
+}
+
+void stringmap::importmap (const text_tarray &maparray) {
+  importmap(maparray, false);
+}
+
+void stringmap::importmap (const text_tarray &maparray, bool keepold) {
+  if (!keepold) {
+    clear ();
+  }
+  
+  text_tarray::const_iterator here = maparray.begin();
+  text_tarray::const_iterator end = maparray.end();
+  text_t from;
+  text_t to;
+
+  while (here != end) {
+    splitmapentry (*here, from, to);
+    fromorder.push_back (from);
+    mapfrom[from] = to;
+    ++here;
+  }
+}
+
+void stringmap::exportmap (text_tarray &maparray) const {
+  maparray.erase (maparray.begin(), maparray.end());
+
+  text_tarray::const_iterator here = fromorder.begin();
+  text_tarray::const_iterator end = fromorder.end();
+  text_tmap::const_iterator toptr;
+  text_t tempmap;
+
+  while (here != end) {
+    toptr = mapfrom.find (*here);
+    if (toptr != mapfrom.end()) {
+      joinmapentry ((*toptr).first, (*toptr).second, tempmap);
+      maparray.push_back (tempmap);
+    }
+
+    ++here;
+  }
+}
+
+void stringmap::getfromarray (text_tarray &fromarray) const {
+  fromarray = fromorder;
+}
+
+void stringmap::gettoarray (text_tarray &toarray) const {
+  toarray.erase(toarray.begin(), toarray.end());
+
+  text_tarray::const_iterator here = fromorder.begin();
+  text_tarray::const_iterator end = fromorder.end();
+  text_tmap::const_iterator toptr;
+
+  while (here != end) {
+    toptr = mapfrom.find (*here);
+    if (toptr != mapfrom.end()) {
+      toarray.push_back((*toptr).second);
+    }
+    ++here;
+  }
+}
+
+bool stringmap::fromexists (const text_t &from) const {
+  return (mapfrom.find (from) != mapfrom.end ());
+}
+
+bool stringmap::toexists (const text_t &to) const {
+  text_tarray::const_iterator here = fromorder.begin();
+  text_tarray::const_iterator end = fromorder.end();
+  text_tmap::const_iterator toptr;
+
+  while (here != end) {
+    toptr = mapfrom.find (*here);
+    if (toptr != mapfrom.end() && (*toptr).second == to) return true;
+    ++here;
+  }
+  
+  // it was not found
+  return false;
+}
+
+bool stringmap::from2to (const text_t &from, text_t &to) const {
+  text_tmap::const_iterator toptr = mapfrom.find (from);
+  if (toptr == mapfrom.end()) {
+    to.clear();
+    return false;
+  }
+
+  to = (*toptr).second;
+  return true;
+}
+
+bool stringmap::to2from (const text_t &to, text_t &from) const {
+  text_tarray::const_iterator here = fromorder.begin();
+  text_tarray::const_iterator end = fromorder.end();
+  text_tmap::const_iterator toptr;
+
+  while (here != end) {
+    toptr = mapfrom.find (*here);
+    if (toptr != mapfrom.end() && (*toptr).second == to) {
+      from = (*toptr).first;
+      return true;
+    }
+    ++here;
+  }
+  
+  // it was not found
+  from.clear();
+  return false;
+}
+
+
+
+void splitmapentry (const text_t &mapentry, text_t &from, text_t &to) {
+  from.clear ();
+  to.clear();
+
+  text_t::const_iterator here = mapentry.begin();
+  text_t::const_iterator end = mapentry.end();
+
+  // get the "from" part of the map
+  while (here != end) {
+    if (*here == '-') {
+      ++here;
+      if (here != end && *here == '>') {
+	++here;
+	break; // found "->"
+      }
+
+      // didn't find "->"
+      from.push_back('-');
+
+    } else {
+      from.push_back(*here);
+      ++here;
+    }
+  }
+
+  // get the "to" part of the map
+  while (here != end) {
+    to.push_back(*here);
+    ++here;
+  }
+}
+
+void joinmapentry (const text_t &from, const text_t &to, text_t &mapentry) {
+  mapentry = from;
+  mapentry += "->";
+  mapentry += to;
+}
Index: /gsdl/stable/runtime-src/src/colservr/maptools.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/maptools.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/maptools.h	(revision 20131)
@@ -0,0 +1,66 @@
+/**********************************************************************
+ *
+ * maptools.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef MAPTOOLS_H
+#define MAPTOOLS_H
+
+
+#include "gsdlconf.h"
+#include "text_t.h"
+
+// stringmap is a mapping which remembers the original order 
+// of the map, but is very fast to look up.
+class stringmap {
+protected:
+  text_tarray fromorder;
+  text_tmap mapfrom;
+
+public:
+  void clear ();
+
+  void importmap (const text_tarray &maparray);
+  void importmap (const text_tarray &maparray, bool keepold);
+  void exportmap (text_tarray &maparray) const;
+
+  void getfromarray (text_tarray &fromarray) const;
+  void gettoarray (text_tarray &toarray) const;
+  
+  bool fromexists (const text_t &from) const;
+  bool toexists (const text_t &to) const;
+
+  // from2to and to2from return false if the key (the "from"
+  // field or the "to" field) cannot be found
+  bool from2to (const text_t &from, text_t &to) const;
+  bool to2from (const text_t &to, text_t &from) const;
+};
+
+
+// a few useful functions used by stringmap
+void splitmapentry (const text_t &mapentry, text_t &from, text_t &to);
+void joinmapentry (const text_t &from, const text_t &to, text_t &mapentry);
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/mgppqueryfilter.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/mgppqueryfilter.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/mgppqueryfilter.cpp	(revision 20131)
@@ -0,0 +1,385 @@
+/**********************************************************************
+ *
+ * queryfilter.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "mgppqueryfilter.h"
+#include "fileutil.h"
+#include "mgppsearch.h"
+
+/////////////////////////////////
+// functions for queryfilterclass
+/////////////////////////////////
+
+
+mgppqueryfilterclass::mgppqueryfilterclass () 
+  : queryfilterclass() {
+
+  
+  FilterOption_t filtopt;
+  
+  // -- onePerTerm  Level          enumerated
+  // likely to be Doc, Sec, Para, but we dont assume anything now
+  filtopt.clear();
+  filtopt.name = "Level";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filterOptions["Level"] = filtopt;
+
+  // --  IndexField, enumerated, used to list available fields
+  filtopt.clear();
+  filtopt.name = "IndexField";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filtopt.defaultValue = "";
+  filterOptions["IndexField"] = filtopt;
+
+}
+
+mgppqueryfilterclass::~mgppqueryfilterclass () {
+}
+
+
+//whether a query is a full text browse
+bool mgppqueryfilterclass::full_text_browse (int filterRequestOptions) {
+  return (filterRequestOptions & FRfullTextBrowse);
+}
+
+void mgppqueryfilterclass::configure (const text_t &key, const text_tarray &cfgline) {
+  queryfilterclass::configure(key, cfgline);
+
+  if (key == "indexfieldmap") {
+    indexfieldmap.importmap (cfgline);
+    
+    // update the list of indexes in the filter information
+    text_tarray options;
+    indexfieldmap.gettoarray (options);
+    filterOptions["IndexField"].validValues = options;
+    
+  } else if (key == "indexlevels") {
+    text_tarray::const_iterator here = cfgline.begin();
+    text_tarray::const_iterator end = cfgline.end();
+    bool first=true;
+    filterOptions["Level"].validValues.erase(filterOptions["Level"].validValues.begin(), filterOptions["Level"].validValues.end());
+    while (here != end) {
+      if (!(*here).empty()) {
+	if (first) {
+	  first = false;
+	  // the default is the first value
+	  filterOptions["Level"].defaultValue = *here;
+	}
+	filterOptions["Level"].validValues.push_back(*here);
+      }
+      ++here;
+    }
+  } else if (key == "textlevel") {
+      ((mgppsearchclass *)textsearchptr)->set_text_level(cfgline[0]);
+  } else if (key == "indexstem") {
+    ((mgppsearchclass *)textsearchptr)->set_indexstem (cfgline[0]);
+  } else if (key == "defaultindex") { // used for fields in mgpp
+    indexfieldmap.from2to (cfgline[0], filterOptions["IndexField"].defaultValue);
+  }
+  
+}
+
+bool mgppqueryfilterclass::init (ostream &logout) {
+  
+  if (!queryfilterclass::init(logout)) {
+    return false;
+  }
+  
+  if (filterOptions["IndexField"].defaultValue.empty()) {
+    // use first index in map as default if no default is set explicitly
+    text_tarray fromarray;
+    indexfieldmap.getfromarray(fromarray);
+    if (fromarray.size()) {
+      filterOptions["IndexField"].defaultValue = fromarray[0];
+    }
+  }
+  return true;
+}
+
+void mgppqueryfilterclass::filter(const FilterRequest_t &request,
+				  FilterResponse_t &response,
+				  comerror_t &err, ostream &logout) {  
+
+
+  outconvertclass text_t2ascii;
+
+  response.clear ();
+  err = noError;
+  if (db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: queryfilter contains a null dbclass\n\n";
+    err = configurationError;
+    return;
+  }
+  if (textsearchptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: queryfilter contains a null textsearchclass for mgpp\n\n";
+    err = configurationError;
+    return;
+  }
+  if (full_text_browse(request.filterResultOptions)) {
+    browsefilter(request, response, err, logout);
+    return;
+  }
+  // open the database
+  db_ptr->setlogout(&logout);
+  if (!db_ptr->opendatabase (db_filename, DB_READER, 100, false)) {
+    // most likely a system problem (we have already checked that the database exists)
+    logout << text_t2ascii
+	   << "system problem: open on database \"" << db_filename << "\" failed\n\n";
+    err = systemProblem;
+    return;
+  }
+
+
+  // get the query parameters
+  int startresults, endresults;
+  text_t phrasematch; // not used here any more
+  vector<queryparamclass> queryfilterparams;
+  parse_query_params (request, queryfilterparams, startresults, 
+		      endresults, phrasematch, logout);  
+ 
+   
+  // do query
+  queryresultsclass queryresults;
+  do_multi_query (request, queryfilterparams, queryresults, err, logout);
+  if (err != noError) return;
+  // assemble document results
+  if (need_matching_docs (request.filterResultOptions)) {
+    
+    int resultnum = 1;
+    ResultDocInfo_t resultdoc;
+    text_t trans_OID;
+    vector<text_t>::iterator docorder_here = queryresults.docs.docorder.begin();
+    vector<text_t>::iterator docorder_end = queryresults.docs.docorder.end();
+
+    if (endresults == -1) endresults = MAXNUMDOCS;
+    while (docorder_here != docorder_end) {
+      if (resultnum > endresults) break;
+      
+      // translate the document number
+      if (!translate(db_ptr, *docorder_here, trans_OID)) {
+	logout << text_t2ascii
+	       << "warning: could not translate mgpp document number \""
+	       << *docorder_here << "\"to OID.\n\n";
+	
+      } else {
+	docresultmap::iterator docset_here = queryresults.docs.docset.find (*docorder_here);
+
+	// see if there is a result for this number,
+	// if it is in the request set (or the request set is empty)
+	if (docset_here != queryresults.docs.docset.end() &&
+	    (request.docSet.empty() || in_set(request.docSet, trans_OID))) {
+	  if (resultnum >= startresults) {
+	    // add this document
+	    resultdoc.OID = trans_OID;
+	    resultdoc.result_num = resultnum;
+	    resultdoc.ranking = (int)((*docset_here).second.docweight * 10000.0 + 0.5);
+
+	    response.docInfo.push_back (resultdoc);
+	  }
+	  
+	  ++resultnum;
+	}
+      } // else
+      
+      ++docorder_here;
+    }
+  } // if need matching docs
+
+  // assemble the term results
+  if (need_term_info(request.filterResultOptions)) {
+    // note: the terms have already been sorted and uniqued - ?? have they??
+
+    TermInfo_t terminfo;
+    bool terms_first = true;
+
+    termfreqclassarray::iterator terms_here = queryresults.terms.begin();
+    termfreqclassarray::iterator terms_end = queryresults.terms.end();
+
+    while (terms_here != terms_end) {
+      terminfo.clear();
+      terminfo.term = (*terms_here).termstr;
+      terminfo.freq = (*terms_here).termfreq;
+
+      // this bit gets the matchTerms ie the equivalent (stem/casefold) terms
+      if (terms_first) {
+	text_tset::iterator termvariants_here = queryresults.termvariants.begin();
+	text_tset::iterator termvariants_end = queryresults.termvariants.end();
+	while (termvariants_here != termvariants_end) {
+	  terminfo.matchTerms.push_back (*termvariants_here);
+	  ++termvariants_here;
+	}
+      }
+      terms_first = false;
+      
+      response.termInfo.push_back (terminfo);
+
+      ++terms_here;
+    }
+  }
+
+  db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+  response.numDocs = queryresults.docs_matched;
+  response.isApprox = queryresults.is_approx;
+}
+
+void mgppqueryfilterclass::browsefilter(const FilterRequest_t &request,
+					FilterResponse_t &response,
+					comerror_t &err, ostream &logout) {  
+
+  outconvertclass text_t2ascii;
+
+  // get the query parameters
+  int startresults, endresults;
+  text_t phrasematch; // not used here any more, just have it so can use
+                      // parse_query_params function
+  
+  vector<queryparamclass> queryfilterparams;
+  parse_query_params (request, queryfilterparams, startresults, 
+		      endresults, phrasematch, logout);  
+
+    vector<queryparamclass>::const_iterator query_here = queryfilterparams.begin();
+   
+  // do query
+  queryresultsclass queryresults;
+  queryresults.clear();
+  
+  int numDocs = endresults-startresults;
+  textsearchptr->setcollectdir (collectdir);
+
+  if (!((mgppsearchclass*)textsearchptr)->browse_search((*query_here), startresults, numDocs, queryresults)) {
+    // most likely a system problem
+    logout << text_t2ascii
+	   << "system problem: could not do full text browse with mgpp for index \""
+	   << (*query_here).index << (*query_here).subcollection
+	   << (*query_here).language << "\".\n\n";
+    err = systemProblem;
+    return;
+  }
+
+  // assemble the term results
+  TermInfo_t terminfo;
+  
+  termfreqclassarray::iterator terms_here = queryresults.terms.begin();
+  termfreqclassarray::iterator terms_end = queryresults.terms.end();
+
+  while (terms_here != terms_end) {
+    terminfo.clear();
+    terminfo.term = (*terms_here).termstr;
+    terminfo.freq = (*terms_here).termfreq;
+    
+    response.termInfo.push_back (terminfo);
+
+    ++terms_here;
+  }
+  
+
+}
+
+// textsearchptr and db_ptr are assumed to be valid
+void mgppqueryfilterclass::do_multi_query (const FilterRequest_t &request,
+					   const vector<queryparamclass> &query_params,
+					   queryresultsclass &multiresults,
+					   comerror_t &err, ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  err = noError;
+  textsearchptr->setcollectdir (collectdir);
+  multiresults.clear();
+  
+  vector<queryparamclass>::const_iterator query_here = query_params.begin();
+  vector<queryparamclass>::const_iterator query_end = query_params.end();
+  while (query_here != query_end) {
+    queryresultsclass thisqueryresults;
+    text_t indx((*query_here).index);
+    if (!textsearchptr->search((*query_here), thisqueryresults)) {
+      // most likely a system problem
+      logout << text_t2ascii
+	     << "system problem: could not do search with mgpp for index \""
+	     << (*query_here).index << (*query_here).subcollection
+	     << (*query_here).language << "\".\n\n";
+      err = systemProblem;
+      return;
+    }
+
+    // check for syntax error
+    if (thisqueryresults.syntax_error==true) {
+      logout << text_t2ascii
+	     << "syntax problem: invalid query string \""
+	     << (*query_here).querystring<<"\".\n";
+      err = syntaxError;
+      return;
+    }
+    // combine the results
+    if (need_matching_docs (request.filterResultOptions)) {
+            
+      if (query_params.size() == 1) {
+	multiresults.docs = thisqueryresults.docs; // just one set of results
+	multiresults.docs_matched = thisqueryresults.docs_matched;
+	multiresults.is_approx = thisqueryresults.is_approx;
+	
+      } else {
+	if ((*query_here).combinequery == "and") {
+	  multiresults.docs.combine_and (thisqueryresults.docs);
+	} else if ((*query_here).combinequery == "or") {
+	  multiresults.docs.combine_or (thisqueryresults.docs);
+	} else if ((*query_here).combinequery == "not") {
+	  multiresults.docs.combine_not (thisqueryresults.docs);
+	}
+	multiresults.docs_matched = multiresults.docs.docset.size();
+	multiresults.is_approx = Exact;
+      }
+    }
+
+    // combine the term information 
+    if (need_term_info (request.filterResultOptions)) {
+      // append the terms
+      multiresults.orgterms.insert(multiresults.orgterms.end(),
+				   thisqueryresults.orgterms.begin(),
+				   thisqueryresults.orgterms.end());
+
+      
+      // add the term variants - 
+      text_tset::iterator termvar_here = thisqueryresults.termvariants.begin();
+      text_tset::iterator termvar_end = thisqueryresults.termvariants.end();
+      while (termvar_here != termvar_end) {
+	multiresults.termvariants.insert(*termvar_here);
+	++termvar_here;
+      }
+    }
+   
+    ++query_here;
+  }
+
+  // sort and unique the query terms
+  multiresults.sortuniqqueryterms ();
+}
+
+
+
Index: /gsdl/stable/runtime-src/src/colservr/mgppqueryfilter.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/mgppqueryfilter.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/mgppqueryfilter.h	(revision 20131)
@@ -0,0 +1,63 @@
+/**********************************************************************
+ *
+ * mgppqueryfilter.h -- new queryfilter to use mgpp 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+#ifndef MGPPQUERYFILTER_H
+#define MGPPQUERYFILTER_H
+
+#include "queryfilter.h"
+
+
+class mgppqueryfilterclass : public queryfilterclass {
+protected:
+
+  stringmap indexfieldmap;
+  bool full_text_browse (int filterRequestOptions);
+
+  // textsearchptr and db_ptr are assumed to be valid
+  void do_multi_query (const FilterRequest_t &request,
+		       const vector<queryparamclass> &query_params,
+		       queryresultsclass &multiresults,
+		       comerror_t &err, ostream &logout);
+
+
+public:
+  mgppqueryfilterclass ();
+  virtual ~mgppqueryfilterclass ();
+
+  void configure (const text_t &key, const text_tarray &cfgline);
+  bool init (ostream &logout);
+  void filter (const FilterRequest_t &request,
+		       FilterResponse_t &response,
+		       comerror_t &err, ostream &logout);
+  
+  void browsefilter(const FilterRequest_t &request,
+		    FilterResponse_t &response,
+		    comerror_t &err, ostream &logout);  
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/mgppsearch.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/mgppsearch.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/mgppsearch.cpp	(revision 20131)
@@ -0,0 +1,346 @@
+/**********************************************************************
+ *
+ * mgppsearch.cpp -- 
+ * Copyright (C) 1999-2002  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#include "gsdlconf.h"
+#include "mgppsearch.h"
+#include "fileutil.h"
+#include "GSDLQueryParser.h"
+#include "MGQuery.h"
+#include "TextGet.h"
+#include "queryinfo.h"
+#include "gsdlunicode.h"
+
+
+text_t mgppsearchclass::getindexsuffix(const queryparamclass &qp) {
+  return getindexsuffix(qp.collection, qp.index+qp.subcollection+qp.language);
+
+}
+
+text_t mgppsearchclass::getindexsuffix (const text_t &collection, 
+			      const text_t &index) {
+
+  text_t indexsuffix = "index";  
+  indexsuffix = filename_cat (indexsuffix, index);
+  if (indexstem.empty()) {
+    // no index stem, use the coll name
+    indexsuffix = filename_cat (indexsuffix, collection);
+  } else {
+    indexsuffix = filename_cat (indexsuffix, indexstem);
+  }
+  return indexsuffix;
+}
+
+////////////////////
+// mgppsearch class //
+////////////////////
+
+mgppsearchclass::mgppsearchclass ()
+  : searchclass() {
+
+  textlevel = "Doc";
+  indexData = NULL;
+}
+
+mgppsearchclass::~mgppsearchclass () 
+{
+  if (cache != NULL) 
+    {
+      delete cache;
+      cache = NULL;
+    }
+
+  if (indexData !=NULL) {
+    indexData->UnloadData();
+    delete indexData;
+    indexData = NULL;
+  }
+  
+}
+
+void mgppsearchclass::set_text_level(const text_t &textlevel_arg)
+{
+  textlevel = textlevel_arg;
+}
+
+void mgppsearchclass::set_indexstem(const text_t &stem)
+{
+  indexstem = stem;
+}
+
+
+bool mgppsearchclass::search(const queryparamclass &queryparams, 
+			     queryresultsclass &queryresult) {
+ 
+#ifdef __WIN32__
+  char basepath[]="";
+#else
+  char basepath[] = "/";
+#endif
+ 
+  char *indexname = (filename_cat(collectdir, getindexsuffix(queryparams))).getcstr(); 
+
+ // load index data
+  if (indexData == NULL) {
+    indexData = new IndexData();
+  }
+  if (!indexData->LoadData (basepath, indexname)) {
+    cerr<<"couldn't load index data\n"<<endl;
+    return false;
+  }
+
+  // set default stem method from values originally set on prefs page
+  int defaultStemMethod = 0;
+  if (queryparams.casefolding) {
+    defaultStemMethod |= STEM_CaseFolding;
+  }
+  if (queryparams.stemming) {
+    defaultStemMethod |= STEM_Stemming;
+  }
+  if (queryparams.accentfolding) {
+    defaultStemMethod |= STEM_AccentFolding;
+  }  	
+  
+  // set default Boolean combiner from all/some setting
+  // if match_mode == 1, ie all, default=1 ie AND
+  // if match_mode == 0, ie some, default=0, ie OR
+  int defaultBoolCombine = 0;
+  if (queryparams.match_mode){
+    defaultBoolCombine = 1;
+  }
+
+  // use default query info settings - change to reflect user preferences??
+  QueryInfo queryInfo;
+  
+  SetCStr (queryInfo.docLevel, (queryparams.level.getcstr())); 
+  queryInfo.maxDocs = (unsigned long)queryparams.maxdocs;
+  queryInfo.sortByRank = (queryparams.search_type == 1);
+  queryInfo.exactWeights = false;
+  queryInfo.needRankInfo = true; // used for overall term freq as well as ranking
+  queryInfo.needTermFreqs = true;
+  
+  ExtQueryResult queryResult;
+  
+  UCArray queryArray;
+  // greenstone gives us the query encoded in unicode. We want utf8.
+  char* utf8querystring=to_utf8(queryparams.querystring).getcstr();
+  SetCStr(queryArray, utf8querystring);
+  delete []utf8querystring;
+
+  // create the mgpp query tree
+  QueryNode *queryTree = NULL;
+  queryTree = ParseQuery(queryArray, defaultBoolCombine, defaultStemMethod, queryparams.maxnumeric);
+  if (queryTree == NULL) { // syntax error
+    queryresult.syntax_error = true;
+    return true; // should we return true or false?
+  }
+  UCArray level;
+  UCArrayClear(level);
+  
+  //set the level for results
+  SetCStr(level, textlevel.getcstr());
+
+  
+  // do the query
+  MGQuery(*indexData, queryInfo, queryTree, queryResult, level);
+  
+ 
+  // convert ExtQueryResult to queryresultclass
+  
+  queryresult.docs_matched = (int)queryResult.docs.size();
+
+  if (queryresult.docs_matched == (int)queryResult.actualNumDocs) {
+    queryresult.is_approx = Exact; 
+  }
+  else if (queryresult.docs_matched < (int)queryResult.actualNumDocs) {
+    queryresult.is_approx = MoreThan;
+  }
+  else {
+    queryresult.is_approx = Approximate;
+  }
+
+  docresultclass doc;
+  for (int i=0; i<(int)queryResult.docs.size(); ++i) {
+    doc.clear();
+    doc.docnum = (int)queryResult.levels[i];
+    doc.docweight = queryResult.ranks[i];
+    queryresult.docs.docset[doc.docnum] = doc;
+    queryresult.docs.docorder.push_back(doc.docnum);
+
+  }
+
+  // term info
+  termfreqclass term;
+  for (int k=0; k<(int)queryResult.termFreqs.size(); ++k) {
+    term.clear();
+    char* termfreq_cstr=GetCStr(queryResult.termFreqs[k].term);
+    term.termstr = to_uni(termfreq_cstr);
+    delete []termfreq_cstr;
+    term.termstemstr = term.termstr;
+    // we don't set term.utf8equivterms ?? - jrm21
+    term.termfreq = queryResult.termFreqs[k].termFreq;
+    queryresult.terms.push_back(term);
+    queryresult.orgterms.push_back(term); // should this change??
+    
+    for (int j=0; j<(int)queryResult.termFreqs[k].equivTerms.size(); ++j) {
+      char* equivterm_cstr=GetCStr(queryResult.termFreqs[k].equivTerms[j]);
+      queryresult.termvariants.insert(to_uni(equivterm_cstr));
+      delete []equivterm_cstr;
+    }
+
+  }
+  // clean up
+  unload_database();  // Important that local library doesn't leave any files open
+  delete []indexname;
+  return true;
+
+}
+
+
+bool mgppsearchclass::browse_search(const queryparamclass &queryparams, int start, int numDocs,
+				    queryresultsclass &queryresult) {
+
+#ifdef __WIN32__
+  char basepath[]="";
+#else
+  char basepath[] = "/";
+#endif
+
+  char *indexname = (filename_cat(collectdir, getindexsuffix(queryparams))).getcstr();
+ 
+  if (indexData == NULL) {
+    indexData = new IndexData();
+  }
+  if (!indexData->LoadData (basepath, indexname)) {
+    cerr<<"couldn't load index data\n"<<endl;
+    return false;
+  }
+
+  UCArray level;
+  UCArrayClear(level);
+  
+  //browse always at top level
+  SetCStr(level, "Doc"); // this name may change.
+  
+
+  BrowseQueryNode browseNode;
+  browseNode.startPosition = start;
+  browseNode.numTerms = numDocs;
+
+  BrowseQueryResult browseResult;
+
+  UCArrayClear(browseNode.term);
+  // greenstone gives us the query encoded in unicode. We want utf8.
+  char* utf8querystring=to_utf8(queryparams.querystring).getcstr();
+  SetCStr(browseNode.term, utf8querystring);
+  delete []utf8querystring;
+
+  // do the actual query
+  MGBrowseQuery(*indexData, level, browseNode, browseResult);
+
+  // load results into term info
+  termfreqclass term;
+  for (int i=0; i<(int)browseResult.termFreqs.size(); ++i) {
+    term.clear();
+    char* term_cstr = GetCStr(browseResult.termFreqs[i].term);
+    term.termstr = to_uni(term_cstr);
+    delete []term_cstr;
+    term.termstemstr = term.termstr;
+    term.termfreq = browseResult.termFreqs[i].termFreq;
+    queryresult.terms.push_back(term);
+    queryresult.orgterms.push_back(term);
+  }
+
+  // clean up
+  unload_database();  // Important that local library doesn't leave any files open
+  delete []indexname;
+
+  return true;
+}
+
+// the document text for 'docnum' is placed in 'output'
+// docTargetDocument returns 'true' if it was able to
+// try to get a document
+// collection is needed to see if an index from the 
+// collection is loaded. THe default index bits are just there cos
+// the mg version needs them
+
+bool mgppsearchclass::docTargetDocument(const text_t &/*defaultindex*/,
+					const text_t &/*defaultsubcollection*/,
+					const text_t &/*defaultlanguage*/,
+					const text_t &collection,
+					int docnum,
+					text_t &output) {
+  
+#ifdef __WIN32__
+  char basepath[]="";
+#else
+  char basepath[] = "/";
+#endif
+  char *textname = (filename_cat(collectdir, getindexsuffix(collection, "text"))).getcstr();
+ 
+  TextData textdata;
+  if(!textdata.LoadData(basepath, textname)) {
+    cout<<"couldn't load text data\n"<<endl;
+    return false;
+  }
+  UCArray doctext;
+  UCArray level;
+  SetCStr(level, textlevel.getcstr());
+  if (!GetDocText(textdata, level, (unsigned long)docnum, doctext)) {
+    cout<<"couldn't retrieve document text\n";
+    return false;
+  }
+
+  // convert UCArray to text_t
+  output.clear();
+  char* doctext_cstr = GetCStr(doctext);
+  output = to_uni(doctext_cstr); // convert from utf-8 to unicode
+  delete []doctext_cstr;
+
+  // here need to remove the <Document>, <Section>, <Paragraph> tags
+
+  
+  //clean up
+  textdata.UnloadData ();
+  delete []textname;
+
+  return true;
+
+}
+
+// used to clear any cached databases for persistent versions of 
+// Greenstone like the Windows local library
+void mgppsearchclass::unload_database () {
+
+  if (indexData !=NULL) {
+    indexData->UnloadData();
+  }
+}
+
+
+
+
+
Index: /gsdl/stable/runtime-src/src/colservr/mgppsearch.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/mgppsearch.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/mgppsearch.h	(revision 20131)
@@ -0,0 +1,100 @@
+/**********************************************************************
+ *
+ * mgppsearch.h -- implementation of search class for mgpp
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * 
+ *
+ *********************************************************************/
+
+
+#ifndef MGPPSEARCH_H
+#define MGPPSEARCH_H
+
+#include "search.h"
+#include "IndexData.h"
+
+class mgppsearchclass : public searchclass {
+public:
+  mgppsearchclass ();
+  virtual ~mgppsearchclass ();
+
+  virtual text_t get_textindex_type() {return "mgpp";}
+
+  // the search results are returned in queryresults
+  // search returns 'true' if it was able to do a search
+  virtual bool search(const queryparamclass &queryparams, 
+	      queryresultsclass &queryresults);
+  
+  // this returns a list of terms in queryresults - no document info is returned
+  // returns a list of numTerms terms, starting from the query string term (in queryparams)
+  // + start. used for full text browsing
+  virtual bool browse_search(const queryparamclass &queryparams, int start, int numTerms,
+			     queryresultsclass &queryresults);
+
+  // the document text for 'docnum' is placed in 'output'
+  // docTargetDocument returns 'true' if it was able to
+  // try to get a document
+  // collection is needed to see if an index from the 
+  // collection is loaded. If no index has been loaded
+  // defaultindex is needed to load one
+  virtual bool docTargetDocument(const text_t &defaultindex,
+			 const text_t &defaultsubcollection,
+			 const text_t &defaultlanguage,
+			 const text_t &collection,
+			 int docnum,
+			 text_t &output);
+
+  /*  // same as docTargetDocument except the document is returned
+  // in its raw form. UDoc remains the property of mg and may
+  // be destroyed on the next call to mg.
+  // not implemented for mgpp
+  virtual bool mgdocument (const text_t &defaultindex,
+		   const text_t &defaultsubcollection,
+		   const text_t &defaultlanguage,
+		   const text_t &collection,
+		   int docnum,
+		   char *&UDoc, int &ULen);
+  */
+  
+  void set_text_level(const text_t &textlevel_arg);
+  
+  void set_indexstem(const text_t &indexstem);
+
+  // used to clear any cached databases for persistent versions of 
+  // Greenstone like the Windows local library
+  void unload_database ();
+
+ protected:
+  
+  text_t textlevel;
+  text_t indexstem; // the stem of the index file names
+  IndexData *indexData; // the index data structure needed for MGQuery - keep
+  // as a cache
+  
+  text_t getindexsuffix(const queryparamclass &qp);
+  text_t getindexsuffix (const text_t &collection, const text_t &index);
+
+};
+
+
+#endif
+
Index: /gsdl/stable/runtime-src/src/colservr/mgq.c
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/mgq.c	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/mgq.c	(revision 20131)
@@ -0,0 +1,731 @@
+/**********************************************************************
+ *
+ * mgq.c -- cut-dowm version of mgquery
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "mgq.h"
+
+
+#include <stdio.h>
+#include <string.h>
+/* #include <io.h> */
+#include <fcntl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  
+#include "sysfuncs.h"
+  
+#include "messages.h"
+#include "memlib.h"
+  
+#include "invf.h"
+#include "text.h"
+#include "lists.h"
+#include "backend.h"
+#include "environment.h"
+#include "globals.h"
+#include "mg_errors.h"
+#include "commands.h"
+#include "text_get.h"
+#include "term_lists.h"
+#include "local_strings.h"
+
+#include "words.h"
+#include "stemmer.h"
+#include "stem_search.h"
+  
+#ifdef __cplusplus
+}
+#endif
+
+
+#include "mgq.h"
+
+/* get a reasonable database cache size */
+#ifndef MAXNUMDATABASEINFO
+#  ifdef GSDLSERVER
+#    define MAXNUMDATABASEINFO 10
+#  else
+#    define MAXNUMDATABASEINFO 2
+#  endif
+#endif
+
+#define MAXCOLLECTIONLEN  16
+#define MAXMGDIRLEN       256
+#define MAXGENSUFFIXLEN   256
+#define MAXTEXTSUFFIXLEN  256
+
+typedef struct DatabaseInfo {
+  int accessnum; /* -1 = invalid record */
+  char collection[MAXCOLLECTIONLEN];
+  char mgdir[MAXMGDIRLEN];
+  char gensuffix[MAXGENSUFFIXLEN];
+  char textsuffix[MAXTEXTSUFFIXLEN];
+  query_data *qd;
+} DatabaseInfo;
+
+
+/* globals needed by some vague part of mg... */
+FILE *OutFile = NULL, *InFile = NULL;
+int OutPipe = 0, InPipe = 0;
+int Quitting = 0;
+
+/* globals needed to handle loading of databases */
+static int cur_cachenum = -1;
+
+/* globals needed by the database cache */
+static DatabaseInfo dbcache[MAXNUMDATABASEINFO];
+static int cache_nextaccessnum = 0;
+static int cache_numloaded = 0;
+
+
+
+#if defined(PARADOCNUM) ||  defined(NZDL)
+static int GetDocNumFromParaNum(query_data *qd, int paranum) {
+  int Documents = qd->td->cth.num_of_docs;
+  int *Paragraph = qd->paragraph;
+  int low = 1, high = Documents;
+  int mid = (low+high)/2;
+
+  while ((mid = (low+high)/2) >=1 && mid <= Documents)
+    {
+      if (paranum > Paragraph[mid])
+        low = mid+1;
+      else if (paranum <= Paragraph[mid-1])
+        high = mid-1;
+      else
+        return mid;
+    }
+  FatalError(1, "Bad paragraph number.\n");
+  return 0;
+}
+
+static int GetParaNumFromDocNum(query_data *qd, int docnum) {
+  int Documents = qd->td->cth.num_of_docs;
+  int *Paragraph = qd->paragraph;
+
+  if (docnum > 0 && docnum <= Documents)
+    return Paragraph[docnum-1]+1;
+  return 0;
+}
+#endif
+
+
+/*****************************************************************************/
+
+static void MGQError(char *emsg)
+{
+  fprintf(stderr,"Fatal error: %s\n", emsg);
+  exit(1);
+}
+
+static int ProcessDocs (query_data * qd, int skip, int howmany, 
+			enum result_kinds kind, 
+			int (*sender)(char *,int,int,float,void *), void *ptr) {
+  int max_buf = 0, output_failure = 0;
+  int DocCount = 0;
+  int need_text = (kind == result_docs);
+
+  /* skip the requested number of documents */
+  while (skip > 0) {
+    if (!NextDoc(qd)) return 0;
+    skip--;
+  }
+
+  /* find out the maximum size for the text buffer */
+  if (need_text) max_buf = atoi (GetDefEnv ("buffer", "1048576"));
+
+  /* process each document */
+  do {
+    u_char *UDoc = NULL;
+    unsigned long ULen=0;
+
+#if defined(PARADOCNUM) ||  defined(NZDL)
+    /* adjust the document number for paragraph level result_docs */
+    /* this is a bit of a hack ... */
+    if (kind==result_docs && qd->id->ifh.InvfLevel == 3 &&
+	qd->DL != NULL && (int)qd->doc_pos < (int)qd->DL->num)
+      qd->DL->DE[qd->doc_pos].DocNum = GetParaNumFromDocNum(qd, qd->DL->DE[qd->doc_pos].DocNum);
+#endif
+    
+    if (need_text) {
+      /* load the compressed text */
+      if (LoadCompressedText (qd, max_buf))
+	MGQError("Unable to load compressed text(memory?).");
+
+      /* uncompress the loaded text */
+      UDoc = GetDocText (qd, &ULen);
+      if (UDoc == NULL) MGQError("UDoc is unexpectedly NULL");
+    }
+      
+    if (UDoc != NULL  ||  kind == result_docnums) {
+      int docnum = GetDocNum(qd);
+#if defined(PARADOCNUM) ||  defined(NZDL)
+      if (qd->id->ifh.InvfLevel == 3) docnum = GetDocNumFromParaNum(qd, docnum);
+#endif
+      switch (kind) {
+      case result_docnums:
+	if (sender != NULL)
+	  output_failure = (*sender)("",0,docnum,GetDocWeight(qd),ptr);
+	break;
+      case result_docs:
+	if (sender != NULL)
+	  output_failure = (*sender)((char *)UDoc,ULen,docnum,GetDocWeight(qd),ptr);
+	break;
+      default:
+	break;
+      }
+    }
+    DocCount++;
+      
+  } while (NextDoc (qd) && output_failure == 0 && --howmany > 0);
+  
+  /*  if (need_text) FreeTextBuffer (qd);*/
+  
+  return (DocCount);
+}
+
+
+static void send_query_term_freqs(QueryTermList *qtl,
+				  int (*sender)(char *,int,int,float,void *), void *ptr)
+{
+  int i = 0;
+  for (i = 0; i < qtl->num; i++)
+    if (sender != NULL) {
+      /*      word = word2str(qtl->QTE[i].Term); 
+	      (* sender)(word, strlen(word), qtl->QTE[i].Count, (float)0.0, ptr); */
+      (* sender)((char *)(qtl->QTE[i].Term+1), qtl->QTE[i].Term[0], 
+		 qtl->QTE[i].Count, (float)0.0, ptr);
+    }
+}
+
+
+static void send_terms (TermList * qtl, 
+			int (*sender)(char *,int,int,float,void *), void *ptr)
+{
+  int i = 0;
+  if (sender == NULL) return;
+  for (i = 0; i < qtl->num; i++)
+    {
+      /*      word = word2str(qtl->TE[i].Word);
+	      (* sender)(word, strlen(word), qtl->TE[i].Count, (float)0.0, ptr);*/
+      (* sender)((char *)(qtl->TE[i].Word+1), qtl->TE[i].Word[0], 
+		 qtl->TE[i].Count, (float)0.0, ptr);
+    }
+}
+
+
+/* MoreDocs () */
+/* Displays all documents in list  DocList. */
+/* Documents are fetched, then decompressed and displayed according to the */
+/* format implied in  FormString(). */
+
+static void
+MoreDocs (query_data * qd, enum result_kinds kind, 
+	  int skip, int howmany,
+	  int (*sender)(char *,int,int,float,void *), void *ptr)
+{
+  qd->num_of_ans = qd->DL->num;
+  switch (kind) {
+  case result_docs:
+  case result_docnums:
+    if (qd->num_of_ans > 0)
+      ProcessDocs (qd, skip, howmany, kind, sender, ptr);
+    break;
+  case result_termfreqs:
+    send_query_term_freqs(qd->QTL, sender, ptr);
+    break;
+  case result_terms:
+    send_terms(qd->TL, sender, ptr);
+    break;
+  }
+}
+
+
+
+
+
+
+/******************************************
+ * functions to handle the database cache *
+ ******************************************/
+
+/* init_dbcache should be called at the start of each */
+/* function which deals with the database cache */
+static void init_dbcache (void) {
+  static int dbcacheinited = 0;
+  int i = 0;
+
+  if (dbcacheinited) return;
+
+  cache_numloaded = 0;
+
+  for (i=0; i<MAXNUMDATABASEINFO; i++) {
+    dbcache[i].accessnum = -1;
+    dbcache[i].collection[0] = '\0';
+    dbcache[i].mgdir[0] = '\0';
+    dbcache[i].gensuffix[0] = '\0';
+    dbcache[i].textsuffix[0] = '\0';
+    dbcache[i].qd = NULL;
+  }
+
+  dbcacheinited = 1;
+}
+
+/* returns the next cache access number and increments it */
+static int get_next_accessnum (void) {
+  return cache_nextaccessnum++;
+}
+
+/* get_free_dbcache returns the cache number which */
+/* was used the longest time ago */
+/* init_dbcache should be called before this function */
+static int get_free_dbcache (void) {
+  int i = 0;
+  int minaccessnum = cache_nextaccessnum; /* the current max */
+  int minpos = 0;
+
+  for (i=0; i<MAXNUMDATABASEINFO; i++) {
+    if (dbcache[i].accessnum < minaccessnum) {
+      minaccessnum = dbcache[i].accessnum;
+      minpos = i;
+    }
+  }
+  
+  return minpos;
+}
+
+/* search_collect will search for an index which */
+/* belongs to a certain collection It returns -1 if none could be found. */
+/* init_dbcache should be called before this function */
+static int search_collect (char *collection) {
+  int i = 0;
+
+  for (i=0; i<MAXNUMDATABASEINFO; i++) {
+    if ((dbcache[i].accessnum >= 0) &&
+	(dbcache[i].qd != NULL) &&
+	(strcmp (collection, dbcache[i].collection) == 0)
+	/* && (dbcache[i].qd->id->ifh.InvfLevel == 2)*/
+	) {
+      dbcache[i].accessnum = get_next_accessnum ();
+      return i;
+    }
+  }
+
+  return -1;
+}
+
+/* search_gensuffix will search for an index which */
+/* has a certain gensuffix. It returns -1 if none could be found. */
+/* init_dbcache should be called before this function */
+static int search_gensuffix (char *gensuffix) {
+  int i = 0;
+
+  for (i=0; i<MAXNUMDATABASEINFO; i++) {
+    if ((dbcache[i].accessnum >= 0) &&
+	(dbcache[i].qd != NULL) &&
+	(strcmp (gensuffix, dbcache[i].gensuffix) == 0)) {
+      dbcache[i].accessnum = get_next_accessnum ();
+      return i;
+    }
+  }
+
+  return -1;
+}
+
+/* unload_database will unload a certain entry within */
+/* the database cache, clearing it for furture use. */
+static void unload_database (int i) {
+  /* check to see if it contains anything */
+  if (dbcache[i].accessnum < 0 || dbcache[i].qd == NULL) 
+    return;
+
+  /* unload all the query information  */
+  FinishQuerySystem(dbcache[i].qd);
+  
+  /* reset all the db info */
+  dbcache[i].accessnum = -1;
+  dbcache[i].collection[0] = '\0';
+  dbcache[i].mgdir[0] = '\0';
+  dbcache[i].gensuffix[0] = '\0';
+  dbcache[i].textsuffix[0] = '\0';
+  dbcache[i].qd = NULL;
+
+  cache_numloaded--;
+  if (cache_numloaded < 0) cache_numloaded = 0;
+}
+
+/* cache_database will store the information about */
+/* a database in the database cache. */
+static void cache_database (int i, char *collection, char *mgdir, char *gensuffix,
+			    char *textsuffix, query_data *qd) {
+  /* make sure this entry has been unloaded first */
+  if (dbcache[i].accessnum >= 0 && dbcache[i].qd != NULL) 
+    unload_database (i);
+
+  /* store the db info */
+  dbcache[i].accessnum = get_next_accessnum ();
+  strcpy (dbcache[i].collection, collection);
+  strcpy (dbcache[i].mgdir, mgdir);
+  strcpy (dbcache[i].gensuffix, gensuffix);
+  strcpy (dbcache[i].textsuffix, textsuffix);
+  dbcache[i].qd = qd;
+
+  cache_numloaded++;
+}
+
+static void make_current (int i) {
+  /* see if it is the current index */
+  if (i == cur_cachenum) return;
+ 
+  /* unload the old index */
+  if (cur_cachenum >= 0) UninitEnv ();
+  cur_cachenum = -1;
+
+  /* make sure the new one is ok */
+  if (i < 0 || dbcache[i].accessnum < 0 || dbcache[i].qd == NULL)
+    return;
+
+  /* load the new one */
+
+  /* Initialise the environment with default values */
+  InitEnv ();
+  
+  SetEnv("mgdir",dbcache[i].mgdir,NULL);
+  SetEnv("mgname",dbcache[i].gensuffix,NULL);
+  SetEnv("textname",dbcache[i].textsuffix,NULL);
+  
+  PushEnv ();
+  
+  cur_cachenum = i;
+}
+
+
+
+/********************
+ * public functions *
+ ********************/
+
+int mgq_ask(char *line)
+{
+  query_data *qd = (query_data *)NULL;
+  char QueryType = QUERY_BOOLEAN;
+  char OutputType = QUERY_DOCNUMS;
+  char *LinePtr = (char *)NULL;
+
+  if (cur_cachenum == -1) return 0;
+  qd = dbcache[cur_cachenum].qd;
+  if (qd == NULL) return 0;
+  
+  ResetFileStats (qd);
+  qd->max_mem_in_use = qd->mem_in_use = 0;
+  qd->tot_hops_taken += qd->hops_taken;
+  qd->tot_num_of_ptrs += qd->num_of_ptrs;
+  qd->tot_num_of_accum += qd->num_of_accum;
+  qd->tot_num_of_terms += qd->num_of_terms;
+  qd->tot_num_of_ans += qd->num_of_ans;
+  qd->tot_text_idx_lookups += qd->text_idx_lookups;
+  qd->hops_taken = qd->num_of_ptrs = 0;
+  qd->num_of_accum = qd->num_of_ans = qd->num_of_terms = 0;
+  qd->text_idx_lookups = 0;
+  
+  LinePtr = ProcessCommands (line, qd);
+  if (CommandsErrorStr) {
+    fprintf (stderr, "%s\n", CommandsErrorStr);
+    return 0;
+  }
+  if (*LinePtr == '\0') return 1;
+  
+  FreeQueryDocs (qd);
+  
+  QueryType = get_query_type ();
+  OutputType = get_output_type ();
+  /* No point in hiliting words on a docnum query */
+  if (OutputType == OUTPUT_HILITE && QueryType == QUERY_DOCNUMS)
+    OutputType = OUTPUT_TEXT;
+  
+  switch (QueryType)
+    {
+    case QUERY_BOOLEAN:
+      {
+	char *maxdocs = (char *)NULL;
+	BooleanQueryInfo bqi;
+	maxdocs = GetDefEnv ("maxdocs", "all");
+	bqi.MaxDocsToRetrieve = strcmp (maxdocs, "all") ? atoi (maxdocs) : -1;
+        if (qd->sd->sdh.indexed)
+	  BooleanQuery (qd, line, &bqi, (BooleanEnv (GetEnv ("casefold"), 0) |
+					 (BooleanEnv (GetEnv ("stem"), 0) << 1)));
+	else
+	  BooleanQuery (qd, line, &bqi, qd->sd->sdh.stem_method);
+	/*	if (qd->sd->sdh.indexed) BooleanQuery (qd, line, &bqi, 3);
+	else BooleanQuery (qd, line, &bqi, qd->sd->sdh.stem_method); */
+	break;
+      }
+    case QUERY_APPROX:
+    case QUERY_RANKED:
+      {
+	char *maxdocs = (char *)NULL;
+	char *maxterms = (char *)NULL;
+	char *maxaccum = (char *)NULL;
+	RankedQueryInfo rqi;
+	maxdocs = GetDefEnv ("maxdocs", "all");
+	maxterms = GetDefEnv ("max_terms", "all");
+	maxaccum = GetDefEnv ("max_accumulators", "all");
+	rqi.Sort = BooleanEnv (GetEnv ("sorted_terms"), 0);
+	rqi.QueryFreqs = BooleanEnv (GetEnv ("qfreq"), 1);
+	rqi.Exact = QueryType == QUERY_RANKED;
+	rqi.MaxDocsToRetrieve = strcmp (maxdocs, "all") ? atoi (maxdocs) : -1;
+	rqi.MaxTerms = strcmp (maxterms, "all") ? atoi (maxterms) : -1;
+	rqi.MaxParasToRetrieve = rqi.MaxDocsToRetrieve;
+	if (qd->id->ifh.InvfLevel == 3 && GetEnv ("maxparas"))
+	  rqi.MaxParasToRetrieve = atoi (GetEnv ("maxparas"));
+	rqi.AccumMethod = toupper (*GetDefEnv ("accumulator_method", "A"));
+	rqi.MaxAccums = strcmp (maxaccum, "all") ? atoi (maxaccum) : -1;
+	rqi.HashTblSize = IntEnv (GetEnv ("hash_tbl_size"), 1000);
+	rqi.StopAtMaxAccum = BooleanEnv (GetEnv ("stop_at_max_accum"), 0);
+	rqi.skip_dump = GetEnv ("skip_dump");
+	RankedQuery (qd, line, &rqi);
+	break;
+      }
+    case QUERY_DOCNUMS:
+      {
+	DocnumsQuery (qd, line);
+	break;
+      }
+    }
+
+  return 1;
+}
+
+int mgq_numdocs(void)
+{
+  query_data *qd = NULL;
+  if (cur_cachenum == -1) return 0;
+  qd = dbcache[cur_cachenum].qd;
+  if (qd == NULL) return 0;
+
+  if (qd->DL) return qd->DL->num;
+  else return 0;
+}
+
+int mgq_numterms(void)
+{
+  query_data *qd = NULL;
+  if (cur_cachenum == -1) return 0;
+  qd = dbcache[cur_cachenum].qd;
+  if (qd == NULL) return 0;
+
+  if (qd->QTL) return qd->QTL->num;
+  else return 0;
+}
+
+int mgq_results(enum result_kinds kind,int skip,int howmany, int (*sender)(char *, int, int, float, void *), void *ptr)
+{
+  query_data *qd = NULL;
+  if (cur_cachenum == -1) return 0;
+  qd = dbcache[cur_cachenum].qd;
+  if (qd == NULL) return 0;
+
+  if (qd->DL) {
+    qd->doc_pos = 0;
+    MoreDocs(qd, kind, skip, howmany, sender, ptr);
+  }
+  return 0;
+}
+
+/* get all the terms that match wordstem using the current stemmer and */
+/* stemming method. The callback is the same style used by mgq_results */
+int mgq_equivterms (unsigned char *wordstem, int (*sender)(char *, int, int, float, void *),
+		    void *ptr) {
+  int stem_method = 0;
+  query_data *qd = NULL;
+  TermList *equivterms = NULL;  /* used for equivalent terms */
+
+  if (cur_cachenum == -1) return 0;
+  qd = dbcache[cur_cachenum].qd;
+  if (qd == NULL || wordstem == NULL || sender == NULL) return 0;
+
+  if (qd->sd->sdh.indexed) {
+    stem_method = BooleanEnv(GetEnv("casefold"),0) | (BooleanEnv(GetEnv("stem"),0) << 1);
+  } else {
+    stem_method = qd->sd->sdh.stem_method;
+  }
+
+  /* make the term list */
+  equivterms = MakeTermList (0);
+  
+  /* expand out this word */
+  if (FindWords (qd->sd, wordstem, stem_method, &equivterms) > 0) {
+    int i;
+    for (i=0; i < equivterms->num; i++) {
+      (* sender)((char *)(equivterms->TE[i].Word+1), equivterms->TE[i].Word[0], 
+		 equivterms->TE[i].Count, (float)0.0, ptr);
+    }
+  }
+
+  /* free the term list */
+  if (equivterms != NULL) FreeTermList (&equivterms);
+
+  return 0;
+}
+
+/* gets the total number of documents retrieved. If this is not available */
+/* it will set total_retrieved to 0 (even when it obviously isn't) */
+int mgq_docsretrieved (int *total_retrieved, int *is_approx) {
+  query_data *qd = NULL;
+
+  if (cur_cachenum == -1) return 0;
+  qd = dbcache[cur_cachenum].qd;
+  if (qd == NULL || total_retrieved == NULL || is_approx == NULL) return 0;
+
+  /* set default values */
+  *total_retrieved = 0;
+  *is_approx = 0;
+
+  if (qd->DL == NULL) return 0;
+
+  *total_retrieved = qd->DL->total_retrieved;
+  *is_approx = qd->DL->is_approx;
+
+  return 0;
+}
+
+
+/* use mgq_getmaxstemlen to determine the length of the word stems to pass */
+/* to mgq_stemword */
+int mgq_getmaxstemlen () {
+  return MAXSTEMLEN;
+}
+
+/* note: the stemming method and the stemmer come from the last query */
+/* "word" should be at least maxstemlen+1 long and it is a string that */
+/* starts with the string length */
+void mgq_stemword (unsigned char *word) {
+  int stem_method = 0;
+  query_data *qd = NULL;
+
+  if (cur_cachenum == -1) return;
+  qd = dbcache[cur_cachenum].qd;
+  if (qd == NULL || word == NULL) return;
+
+  if (qd->sd->sdh.indexed) {
+    stem_method = BooleanEnv(GetEnv("casefold"),0) | (BooleanEnv(GetEnv("stem"),0) << 1);
+  } else {
+    stem_method = qd->sd->sdh.stem_method;
+  }
+
+  stemmer (stem_method, qd->sd->sdh.stemmer_num, word);
+}
+
+
+
+int is_dbcache_full (void) {
+  init_dbcache ();
+  if (cache_numloaded >= MAXNUMDATABASEINFO) return 1;
+  return 0;
+}
+
+int load_database (char *collection, char *mgdir, 
+		   char *gensuffix, char *textsuffix) {
+  int i = 0;
+  query_data *qd = NULL;
+  /*  FILE *deb = NULL; */
+  init_dbcache ();
+
+  /* print out some debug information */
+/*  deb = fopen ("/home/rjmcnab/gsdl/etc/deb.txt", "a");
+  fprintf (deb, "\ncache_nextaccessnum: %i\n", cache_nextaccessnum);
+  fprintf (deb, "cache_numloaded: %i\n", cache_numloaded);
+  fprintf (deb, "cur_cachenum: %i\n", cur_cachenum);
+  fprintf (deb, "MAXNUMDATABASEINFO: %i\n\n", MAXNUMDATABASEINFO);
+  for (i=0; i<MAXNUMDATABASEINFO; i++) {
+    fprintf (deb, "Entry %i\n", i);
+    fprintf (deb, "  accessnum: %i\n", dbcache[i].accessnum);
+    fprintf (deb, "  collection: %s\n", dbcache[i].collection);
+    fprintf (deb, "  mgdir: %s\n", dbcache[i].mgdir);
+    fprintf (deb, "  gensuffix: %s\n", dbcache[i].gensuffix);
+    fprintf (deb, "  textsuffix: %s\n", dbcache[i].textsuffix);
+    fprintf (deb, "  qd: %x\n", (int)(dbcache[i].qd));
+  }
+  fclose (deb); */
+
+  /* search for the index */
+  i = search_gensuffix (gensuffix);
+  if (i >= 0) {
+    make_current (i);
+    return 1;
+  }
+
+  /* if there was a current database then the */
+  /* environment needs uninitialising */
+  make_current (-1);
+
+  /* get a free cache number */
+  i = get_free_dbcache ();
+  unload_database (i);
+
+  /* load the index */
+  qd = InitQuerySystem (mgdir, gensuffix, textsuffix, NULL);
+  if (qd == NULL) return 0;
+
+  /* cache this index */
+  cache_database (i, collection, mgdir, gensuffix, textsuffix, qd);
+
+  /* make this index current */
+  make_current (i);
+
+  return 1;
+}
+
+/* load_text_database tries to make an index of the */
+/* specified collection current */
+int load_text_database (char *collection) {
+  int i = 0;
+  init_dbcache ();
+
+  /* search for the index */
+  i = search_collect (collection);
+
+  /* return if none were found */
+  if (i < 0) return 0;
+  
+  /* make this index current */
+  make_current (i);
+  return 1;
+}
+
+void close_all_databases (void) {
+  int i = 0;
+  init_dbcache ();
+  
+  /* unload all active databases */
+  for (i=0; i<MAXNUMDATABASEINFO; i++) {
+    unload_database (i);
+  }
+
+  /* if there was a current database then the */
+  /* environment needs uninitialising */
+  make_current (-1);
+}
Index: /gsdl/stable/runtime-src/src/colservr/mgq.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/mgq.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/mgq.h	(revision 20131)
@@ -0,0 +1,78 @@
+/**********************************************************************
+ *
+ * mgq.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef MGQ_H
+#define MGQ_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  
+enum result_kinds {
+  result_docs,      /* Return the documents found in last search */
+  result_docnums,   /* Return document id numbers and weights */
+  result_termfreqs, /* Return terms and frequencies */
+  result_terms      /* Return matching query terms */
+};
+
+int mgq_ask(char *line);
+int mgq_results(enum result_kinds kind, int skip, int howmany,
+		int (*sender)(char *, int, int, float, void *), void *ptr);
+int mgq_numdocs(void);
+int mgq_numterms(void);
+
+/* get all the terms that match wordstem using the current stemmer and */
+/* stemming method. The callback is the same style used by mgq_results */
+int mgq_equivterms (unsigned char *wordstem, int (*sender)(char *, int, int, float, void *),
+		    void *ptr);
+
+/* gets the total number of documents retrieved. If this is not available */
+/* it will set total_retrieved to 0 (even when it obviously isn't) */
+int mgq_docsretrieved (int *total_retrieved, int *is_approx);
+  
+/* use mgq_getmaxstemlen to determine the length of the word stems to pass */
+/* to mgq_stemword */
+int mgq_getmaxstemlen ();
+
+/* note: the stemming method and the stemmer come from the last query */
+/* "word" should be at least maxstemlen+1 long and it is a string that */
+/* starts with the string length */
+void mgq_stemword (unsigned char *word);
+
+  
+int is_dbcache_full (void);
+int load_database (char *collection, char *mgdir, char *gensuffix, char *textsuffix);
+int load_text_database (char *collection);
+void close_all_databases (void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/mgqueryfilter.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/mgqueryfilter.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/mgqueryfilter.cpp	(revision 20131)
@@ -0,0 +1,533 @@
+/**********************************************************************
+ *
+ * mgqueryfilter.cpp -- implementation of queryfilter for old mg 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "mgqueryfilter.h"
+#include "fileutil.h"
+#include "phrasesearch.h"
+#include "mgsearch.h"
+#include "phrases.h"
+
+///////////////////////////////
+// methods for resultsorderer_t
+///////////////////////////////
+
+resultsorderer_t::resultsorderer_t() {
+  clear ();
+}
+
+void resultsorderer_t::clear() {
+  compare_phrase_match = false;
+  compare_terms_match = false;
+  compare_doc_weight = true;
+
+  docset = NULL;
+}
+
+bool resultsorderer_t::operator()(const text_t &t1, const text_t &t2) const {
+  if (docset == NULL) return t1>t2;
+
+  docresultmap::iterator t1_here = docset->find(t1);
+  docresultmap::iterator t2_here = docset->find(t2);
+  docresultmap::iterator end = docset->end();
+
+  // sort all the document numbers not in the document set to
+  // the end of the list
+  if (t1_here == end) {
+    if (t2_here == end) return t1>t2;
+    else return true;
+  } else if (t2_here == end) return false;
+  
+  if (compare_phrase_match) {
+    if ((*t1_here).second.num_phrase_match > (*t2_here).second.num_phrase_match) return true;
+    if ((*t1_here).second.num_phrase_match < (*t2_here).second.num_phrase_match) return false;
+  }
+
+  if (compare_terms_match) {
+    if ((*t1_here).second.num_query_terms_matched > (*t2_here).second.num_query_terms_matched) return true;
+    if ((*t1_here).second.num_query_terms_matched < (*t2_here).second.num_query_terms_matched) return false;
+  }
+
+  if (compare_doc_weight) {
+    if ((*t1_here).second.docweight > (*t2_here).second.docweight) return true;
+    if ((*t1_here).second.docweight < (*t2_here).second.docweight) return false;
+  }
+
+  return t1>t2;
+}
+
+
+
+
+/////////////////////////////////
+// functions for mgqueryfilterclass
+/////////////////////////////////
+
+
+void mgqueryfilterclass::configure (const text_t &key, const text_tarray &cfgline) {
+  queryfilterclass::configure (key, cfgline);
+
+  if (key == "indexstem") {
+    ((mgsearchclass *)textsearchptr)->set_indexstem (cfgline[0]);
+  }
+  
+}
+
+// loads up phrases data structure with any phrases (that's the quoted bits)
+// occuring in the querystring
+void mgqueryfilterclass::get_phrase_terms (const text_t &querystring, 
+					 const termfreqclassarray &orgterms,
+					 vector<termfreqclassarray> &phrases) {
+
+  text_t::const_iterator here = querystring.begin();
+  text_t::const_iterator end = querystring.end();
+
+  termfreqclassarray tmpterms;
+
+  int termcount = 0;
+  bool foundquote = false;
+  bool foundbreak = false;
+  bool start = true;
+  while (here != end) {
+    if (*here == '\"') {
+      if (foundquote) {
+	if (!foundbreak && !start) {
+	  tmpterms.push_back (orgterms[termcount]);
+	  ++termcount;
+	}
+	if (tmpterms.size() > 1) {
+	  phrases.push_back (tmpterms);
+	}
+	tmpterms.erase (tmpterms.begin(), tmpterms.end());
+	
+	foundquote = false;
+	foundbreak = true;
+      } else foundquote = true;
+    } else if (!is_unicode_letdig(*here)) {
+      // found a break between terms
+      if (!foundbreak && !start) {
+	if (foundquote) {
+	  tmpterms.push_back (orgterms[termcount]);
+	}
+	++termcount;
+      }
+      foundbreak = true;
+    } else {
+      start = false;
+      foundbreak = false;
+    }      
+    ++here;
+  }
+}
+
+// do aditional query processing
+void mgqueryfilterclass::post_process (const queryparamclass &queryparams, 
+				     queryresultsclass &queryresults) {
+
+  // post-process the results if needed
+  if (queryresults.orgterms.size() > 1 && !queryresults.docs.docset.empty()) {
+
+    // get the terms between quotes (if any)
+    vector<termfreqclassarray> phrases;
+    get_phrase_terms (queryparams.querystring, queryresults.orgterms, phrases);
+
+    num_phrases = phrases.size();
+    if (num_phrases > 0) {
+
+      // get the long version of the index
+      text_t longindex;
+      indexmap.to2from (queryparams.index, longindex);
+      
+      vector<termfreqclassarray>::const_iterator this_phrase = phrases.begin();
+      vector<termfreqclassarray>::const_iterator end_phrase = phrases.end();
+
+      while (this_phrase != end_phrase) {
+
+	// process each of the matched documents
+	docresultmap::iterator docs_here = queryresults.docs.docset.begin();
+	docresultmap::iterator docs_end = queryresults.docs.docset.end();
+	while (docs_here != docs_end) {
+	  if (OID_phrase_search (*((mgsearchclass*)textsearchptr), *db_ptr, queryparams.index,
+				 queryparams.subcollection, queryparams.language, 
+				 longindex, queryparams.collection, *this_phrase,
+				 (*docs_here).second.docnum)) {
+	    ++docs_here->second.num_phrase_match;
+	  }
+	
+	  ++docs_here;
+	}
+	++this_phrase;
+      }
+    }
+  }
+}
+
+
+// do query that might involve multiple sub queries
+// textsearchptr and db_ptr are assumed to be valid
+void mgqueryfilterclass::do_multi_query (const FilterRequest_t &request,
+				       const vector<queryparamclass> &query_params,
+				       queryresultsclass &multiresults,
+				       comerror_t &err, ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  err = noError;
+  textsearchptr->setcollectdir (collectdir);
+
+  multiresults.clear();
+  
+  vector<queryparamclass>::const_iterator query_here = query_params.begin();
+  vector<queryparamclass>::const_iterator query_end = query_params.end();
+  while (query_here != query_end) {
+    queryresultsclass thisqueryresults;
+
+    if (!textsearchptr->search(*query_here, thisqueryresults)) {
+      // most likely a system problem
+      logout << text_t2ascii
+	     << "system problem: could not do search with mg for index \""
+	     << (*query_here).index << (*query_here).subcollection
+	     << (*query_here).language << "\".\n\n";
+      err = systemProblem;
+      return;
+    }
+
+    // combine the results
+    if (need_matching_docs (request.filterResultOptions)) {
+      // post-process the results if needed
+      if (!thisqueryresults.postprocessed && thisqueryresults.orgterms.size() > 1 &&
+	  !thisqueryresults.docs.docset.empty()) {
+	post_process (*query_here, thisqueryresults);
+	thisqueryresults.postprocessed = true;
+	multiresults.postprocessed = true;
+      } else {
+	num_phrases = 0;
+      }
+      
+      if (query_params.size() == 1) {
+	multiresults.docs = thisqueryresults.docs; // just one set of results
+	multiresults.docs_matched = thisqueryresults.docs_matched;
+	multiresults.is_approx = thisqueryresults.is_approx;
+	
+      } else {
+	if ((*query_here).combinequery == "and") {
+	  multiresults.docs.combine_and (thisqueryresults.docs);
+	} else if ((*query_here).combinequery == "or") {
+	  multiresults.docs.combine_or (thisqueryresults.docs);
+	} else if ((*query_here).combinequery == "not") {
+	  multiresults.docs.combine_not (thisqueryresults.docs);
+	}
+	multiresults.docs_matched = multiresults.docs.docset.size();
+	multiresults.is_approx = Exact;
+      }
+    }
+
+    // combine the term information 
+    if (need_term_info (request.filterResultOptions)) {
+      // append the terms
+      multiresults.orgterms.insert(multiresults.orgterms.end(),
+				   thisqueryresults.orgterms.begin(),
+				   thisqueryresults.orgterms.end());
+
+      // add the term variants
+      text_tset::iterator termvar_here = thisqueryresults.termvariants.begin();
+      text_tset::iterator termvar_end = thisqueryresults.termvariants.end();
+      while (termvar_here != termvar_end) {
+	multiresults.termvariants.insert(*termvar_here);
+	++termvar_here;
+      }
+    }
+   
+    ++query_here;
+  }
+
+  // sort and unique the query terms
+  multiresults.sortuniqqueryterms ();
+}
+
+
+void mgqueryfilterclass::sort_doc_results (const FilterRequest_t &/*request*/,
+					 docresultsclass &docs) {
+  resultsorderer_t resultsorderer;
+  resultsorderer.compare_phrase_match = true;
+  resultsorderer.docset = &(docs.docset);
+
+  // first get a list of document numbers
+  docs.docnum_order();
+
+  sort (docs.docorder.begin(), docs.docorder.end(), resultsorderer);
+}
+
+
+
+mgqueryfilterclass::mgqueryfilterclass () 
+  :queryfilterclass() {
+
+  num_phrases = 0;
+}
+
+mgqueryfilterclass::~mgqueryfilterclass () {
+}
+
+void mgqueryfilterclass::filter (const FilterRequest_t &request,
+			       FilterResponse_t &response,
+			       comerror_t &err, ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  response.clear ();
+  err = noError;
+  if (db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: mgqueryfilter contains a null dbclass\n\n";
+    err = configurationError;
+    return;
+  }
+  if (textsearchptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: mgqueryfilter contains a null textsearchclass (mg)\n\n";
+    err = configurationError;
+    return;
+  }
+
+  // open the database
+  db_ptr->setlogout(&logout);
+  if (!db_ptr->opendatabase (db_filename, DB_READER, 100, false)) {
+    // most likely a system problem (we have already checked that the database exists)
+    logout << text_t2ascii
+	   << "system problem: open on database \"" << db_filename << "\" failed\n\n";
+    err = systemProblem;
+    return;
+  }
+
+  // get the query parameters
+  int startresults = filterOptions["StartResults"].defaultValue.getint();
+  int endresults = filterOptions["EndResults"].defaultValue.getint();
+  text_t phrasematch = filterOptions["PhraseMatch"].defaultValue;
+
+  vector<queryparamclass> queryfilterparams;
+  parse_query_params (request, queryfilterparams, startresults, 
+		      endresults, phrasematch, logout);
+  // do any mg specific diddling with query parameters that may be required
+  mg_parse_query_params (request, queryfilterparams, startresults, 
+			 endresults, phrasematch, logout);
+
+
+  // do query
+  queryresultsclass queryresults;
+  do_multi_query (request, queryfilterparams, queryresults, err, logout);
+  if (err != noError) return;
+  
+  // assemble document results
+  if (need_matching_docs (request.filterResultOptions)) {
+    // sort the query results
+    // only want to sort the docs if we have done a ranked search or there were phrases
+    if (num_phrases > 0 || (request.filterResultOptions & FRranking)) {
+      sort_doc_results (request, queryresults.docs);
+    }
+    int resultnum = 1;
+    ResultDocInfo_t resultdoc;
+    text_t trans_OID;
+    vector<text_t>::iterator docorder_here = queryresults.docs.docorder.begin();
+    vector<text_t>::iterator docorder_end = queryresults.docs.docorder.end();
+
+    // documents containing matching phrases will be sorted to the top so
+    // we can break out once we're past those that match the PhraseMatch
+    // option -- "all_phrases" = return only those documents containing all
+    //	                     phrases in query string
+    //           "some_phrases" = return only those documents containing 
+    //                            at least 1 of the phrases in the document
+    //           "all_docs" = return all documents regardless
+    if (num_phrases > 0) {
+      int numdocs = 0;
+      while (docorder_here != docorder_end) {
+	docresultmap::iterator docset_here = queryresults.docs.docset.find (*docorder_here);
+	
+	if (((phrasematch == "all_phrases") && ((*docset_here).second.num_phrase_match < num_phrases)) ||
+	    ((phrasematch == "some_phrases") && ((*docset_here).second.num_phrase_match < 1))) {
+	  queryresults.docs_matched = numdocs;
+	  break;
+	}
+	++numdocs;
+	++docorder_here;
+      }
+    }
+
+    if (endresults == -1) endresults = MAXNUMDOCS;
+    docorder_here = queryresults.docs.docorder.begin();
+    while (docorder_here != docorder_end) {
+      if (resultnum > endresults || resultnum > queryresults.docs_matched) break;
+      
+      // translate the document number
+      if (!translate(db_ptr, *docorder_here, trans_OID)) {
+	logout << text_t2ascii
+	       << "warning: could not translate mg document number \""
+	       << *docorder_here << "\"to OID.\n\n";
+	
+      } else {
+	docresultmap::iterator docset_here = queryresults.docs.docset.find (*docorder_here);
+
+	// see if there is a result for this number,
+	// if it is in the request set (or the request set is empty)
+	if (docset_here != queryresults.docs.docset.end() &&
+	    (request.docSet.empty() || in_set(request.docSet, trans_OID))) {
+	  if (resultnum >= startresults) {
+	    // add this document
+	    resultdoc.OID = trans_OID;
+	    resultdoc.result_num = resultnum;
+	    resultdoc.ranking = (int)((*docset_here).second.docweight * 10000.0 + 0.5);
+
+	    // these next two are not available on all versions of mg
+	    resultdoc.num_terms_matched = (*docset_here).second.num_query_terms_matched; 
+	    resultdoc.num_phrase_match = (*docset_here).second.num_phrase_match;
+	    
+	    response.docInfo.push_back (resultdoc);
+	  }
+	  
+	  ++resultnum;
+	}
+      }
+      
+      ++docorder_here;
+    }
+  }
+
+  // assemble the term results
+  if (need_term_info(request.filterResultOptions)) {
+    // note: the terms have already been sorted and uniqued
+
+    TermInfo_t terminfo;
+    bool terms_first = true;
+    termfreqclassarray::iterator terms_here = queryresults.terms.begin();
+    termfreqclassarray::iterator terms_end = queryresults.terms.end();
+
+    while (terms_here != terms_end) {
+      terminfo.clear();
+      terminfo.term = (*terms_here).termstr;
+      terminfo.freq = (*terms_here).termfreq;
+      if (terms_first) {
+	text_tset::iterator termvariants_here = queryresults.termvariants.begin();
+	text_tset::iterator termvariants_end = queryresults.termvariants.end();
+	while (termvariants_here != termvariants_end) {
+	  terminfo.matchTerms.push_back (*termvariants_here);
+	  ++termvariants_here;
+	}
+      }
+      terms_first = false;
+
+      response.termInfo.push_back (terminfo);
+
+      ++terms_here;
+    }
+  }
+
+  db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+  response.numDocs = queryresults.docs_matched;
+  response.isApprox = queryresults.is_approx;
+}
+
+void mgqueryfilterclass::mg_parse_query_params (const FilterRequest_t &/*request*/,
+						vector<queryparamclass> &query_params,
+						int &/*startresults*/, int &/*endresults*/,
+						text_t &/*phrasematch*/, ostream &/*logout*/) {
+
+  //  outconvertclass text_t2ascii;
+  
+  vector<queryparamclass>::iterator query_here = query_params.begin();
+  vector<queryparamclass>::iterator query_end = query_params.end();
+  while (query_here != query_end) {
+
+    // if we're doing a phrase search we want to maximise hits by making it
+    // a boolean search on the index with the finest granularity - we'll
+    // also set maxdocs to "all" (realizing that this will cause searches
+    // like "and the" on a large collection to take a very very long time).
+
+    // we're deciding it's a phrase search based on if the querystring 
+    // contains at least 2 double quotes (not very scientific but 
+    // then neither is the rest of the mg phrase searching functionality :-)
+      //if (countchar ((*query_here).querystring.begin(), (*query_here).querystring.end(), '"') > 1) {
+
+    // [kjdon 12/2005] we don't want to do a phrase search if the only phrases are single words, so we'll parse out the phrases properly here
+    text_tarray phrases;
+    get_phrases((*query_here).querystring, phrases);
+
+    if (phrases.size() > 0) {
+      (*query_here).search_type = 0;
+
+      // set maxdocs to "all"
+      (*query_here).maxdocs = -1;
+
+      // Get the long version of the index and test to see if any indexes with
+      // finer granularity exist. Indexes must be the same type (i.e. same metadata
+      // or "text").
+      text_t longindex; text_tarray splitindex;
+      indexmap.to2from ((*query_here).index, longindex);
+      splitchar (longindex.begin(), longindex.end(), ':', splitindex);
+      text_t &granularity = splitindex[0];
+      text_t &indextype = splitindex[1];
+      bool found = false;
+      // currently supported granularity options are "document", "section" and "paragraph"
+      if (granularity == "document" || granularity == "section") {
+	text_t shortindex;
+	if (indexmap.fromexists ("paragraph:" + indextype)) {
+	  indexmap.from2to ("paragraph:" + indextype, shortindex);
+	  (*query_here).index = shortindex;
+	  found = true;
+	}
+	if (!found && granularity == "document" && indexmap.fromexists ("section:" + indextype)) {
+	  indexmap.from2to ("section:" + indextype, shortindex);
+	  (*query_here).index = shortindex;
+	}
+      }
+    }
+
+#ifdef GSDL_BBC_COLLECTION
+    // This is a special hack for the BBC collection's ProgNumber and zzabn
+    // indexes (they're built this way to prevent mg_perf_hash_build from
+    // dying at build time)
+
+    // if we're searching the ProgNumber index we want to
+    // remove all non-alphanumeric characters from the query string
+    text_t longindex; text_tarray splitindex;
+    indexmap.to2from ((*query_here).index, longindex);
+    splitchar (longindex.begin(), longindex.end(), ':', splitindex);
+    text_t &indextype = splitindex[1];
+    if (indextype == "ProgNumber") {
+      text_t new_querystring;
+      text_t::const_iterator here = (*query_here).querystring.begin();
+      text_t::const_iterator end = (*query_here).querystring.end();
+      while (here != end) {
+        if ((*here >= 'a' && *here <= 'z') || (*here >= 'A' && *here <= 'Z') ||
+            (*here >= '0' && *here <= '9')) {
+          new_querystring.push_back (*here);
+        }
+        ++here;
+      }
+      (*query_here).querystring = new_querystring;
+    }
+#endif
+    ++query_here;
+  }
+}
+    
Index: /gsdl/stable/runtime-src/src/colservr/mgqueryfilter.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/mgqueryfilter.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/mgqueryfilter.h	(revision 20131)
@@ -0,0 +1,89 @@
+/**********************************************************************
+ *
+ * mgqueryfilter.h -- queryfilter for old mg
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+#ifndef MGQUERYFILTER_H
+#define MGQUERYFILTER_H
+
+#include "queryfilter.h"
+
+
+// resultsorderer_t is used to sort the query results
+struct resultsorderer_t {
+  bool compare_phrase_match;
+  bool compare_terms_match;
+  bool compare_doc_weight;
+  docresultmap *docset;
+
+  resultsorderer_t();
+  void clear();
+  bool operator()(const text_t &t1, const text_t &t2) const;
+};
+
+
+
+class mgqueryfilterclass : public queryfilterclass {
+protected:
+  
+  int num_phrases;
+
+  void get_phrase_terms (const text_t &querystring, 
+			 const termfreqclassarray &orgterms,
+			 vector<termfreqclassarray> &phrases);
+
+  // do aditional query processing
+  virtual void post_process (const queryparamclass &queryparams,
+			     queryresultsclass &queryresults);
+
+  // do query that might involve multiple sub queries
+  // mgsearchptr and db_ptr are assumed to be valid
+  void do_multi_query (const FilterRequest_t &request,
+		       const vector<queryparamclass> &query_params,
+		       queryresultsclass &multiresults,
+		       comerror_t &err, ostream &logout);
+
+  virtual void sort_doc_results (const FilterRequest_t &request,
+				 docresultsclass &docs);
+
+  virtual void mg_parse_query_params (const FilterRequest_t &request,
+				      vector<queryparamclass> &query_params,
+				      int &startresults, int &endresults,
+				      text_t &phrasematch, ostream &logout);
+
+  
+public:
+  mgqueryfilterclass ();
+  virtual ~mgqueryfilterclass ();
+
+  virtual void configure (const text_t &key, const text_tarray &cfgline);
+
+  void filter (const FilterRequest_t &request,
+	       FilterResponse_t &response,
+	       comerror_t &err, ostream &logout);
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/mgsearch.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/mgsearch.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/mgsearch.cpp	(revision 20131)
@@ -0,0 +1,569 @@
+/**********************************************************************
+ *
+ * mgsearch.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdlconf.h"
+#include "mgsearch.h"
+#include "fileutil.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+#endif
+
+  
+#include <assert.h>
+
+#include "mgq.h"
+// #include "locateinfo.h"
+#include "gsdlunicode.h"
+#include "unitool.h"
+
+
+/////////////
+// globals //
+/////////////
+
+static char *tempdoc = NULL;
+static int templen = 0;
+
+
+//////////////////////
+// useful functions //
+//////////////////////
+
+
+// input and output are in utf8
+text_t mgsearch_stemword (const text_t &word) {
+  // allocate working stem space
+  int maxstemlen = mgq_getmaxstemlen ();
+  unsigned char *word_stem = new unsigned char [maxstemlen + 2];
+  if (word_stem == NULL) return "";
+
+  // copy word to word_stem
+  int len = 0;
+  text_t::const_iterator here = word.begin();
+  text_t::const_iterator end = word.end();
+  while (len < maxstemlen && here != end) {
+    word_stem[len+1] = (unsigned char)(*here);
+    ++len; ++here;
+  }
+  word_stem[len+1] = '\0';
+  word_stem[0] = len;
+
+  mgq_stemword (word_stem);
+
+  // copy word_stem back to tempstr
+  text_t tempstr;
+  tempstr.setcarr((char *)(&word_stem[1]), word_stem[0]);
+
+  delete [] word_stem;
+  
+  return tempstr;
+}
+
+
+
+////////////////////////
+// callback functions //
+////////////////////////
+
+// This routine is called for each document found in a search
+// it assumes that cache_num is set up correctly to point to
+// a suitable result cache
+int ourquerycallback(char * /*UDoc*/, int /*ULen*/, int DocNum, 
+		     float Weight, void *info) {
+
+  
+  queryresultsclass *queryresults = (queryresultsclass * )info;
+
+  // append this entry to the document results
+  docresultclass docresult;
+  docresult.docnum = DocNum;
+  docresult.num_query_terms_matched = (int)(Weight/100.0); // will always be 0 on some versions of mg...
+  docresult.docweight = Weight - docresult.num_query_terms_matched*100;
+  
+  queryresults->docs.docset[DocNum] = docresult;
+  queryresults->docs.docorder.push_back(DocNum);
+  
+  return 0;
+}
+
+int termequivcallback(char *Word, int ULen,  int /*Freq*/, 
+		      float /*Weight*/,  void *info) {
+  text_tset *equivterms = (text_tset *)info;
+  if (equivterms == NULL) return 0;
+
+  text_t thisterm;
+  thisterm.setcarr(Word, ULen);
+
+  equivterms->insert(thisterm);
+  
+  return 0;
+}
+
+
+void mgsearch_equivterms (const text_t &word, text_tset &equivterms) {
+  // allocate working stem space
+  int maxstemlen = mgq_getmaxstemlen ();
+  unsigned char *word_stem = new unsigned char [maxstemlen + 2];
+  if (word_stem == NULL) return;
+
+  // copy word to word_stem
+  int len = 0;
+  text_t::const_iterator here = word.begin();
+  text_t::const_iterator end = word.end();
+  while (len < maxstemlen && here != end) {
+    word_stem[len+1] = (unsigned char)(*here);
+    ++len; ++here;
+  }
+  word_stem[len+1] = '\0';
+  word_stem[0] = len;
+
+  // get the equivalent terms
+  mgq_equivterms (word_stem, termequivcallback, (void *)(&equivterms));
+  
+  delete [] word_stem;
+
+  return;
+}
+
+  text_tset utf8equivterms; // kept as utf8 string for fast matching
+
+
+// This callback is called once for each term in the query
+int termfreqcallback(char *Word, int ULen,  int Freq, 
+		     float /*Weight*/,  void *info) {
+  queryresultsclass *queryresults = (queryresultsclass *)info;
+  if (queryresults == NULL) return 0;
+
+  text_t term;
+  term.setcarr(Word, ULen);
+  termfreqclass termfreq;
+
+  termfreq.termstr = to_uni(term);
+  text_t utf8termstem = mgsearch_stemword (term);
+  termfreq.termstemstr = to_uni (utf8termstem);
+
+  mgsearch_equivterms (utf8termstem, termfreq.utf8equivterms);
+  
+  termfreq.termfreq = Freq;
+  queryresults->orgterms.push_back(termfreq);
+  
+  return 0;
+}
+
+// this callback is called once for each variation of each term
+int termvariantscallback(char *Word, int ULen, int /*Freq*/,
+			 float /*Weight*/, void *info) {
+
+  text_t term;
+  term.setcarr(Word, ULen);
+  queryresultsclass *queryresults = (queryresultsclass *)info;
+  queryresults->termvariants.insert(to_uni(term));
+
+  return 0;
+}
+
+// This callback is for getting document text
+int doctextcallback(char *Doc, int ULen,  int /*Freq*/, 
+		    float /*Weight*/,  void * /*info*/) {
+  if (Doc != NULL) {
+    // Make a copy of this string so we can unload the database without losing it
+    tempdoc = new char[ULen + 1];
+    strcpy(tempdoc, Doc);
+  }
+  templen = ULen;
+  
+  return 0;
+}
+
+
+text_t mgsearchclass::getindexsuffix (const text_t &collection, 
+			      const text_t &index) {
+
+  text_t indexsuffix = "index";  
+  indexsuffix = filename_cat (indexsuffix, index);
+  if (indexstem.empty()) {
+    // no index stem, use the coll name
+    indexsuffix = filename_cat (indexsuffix, collection);
+  } else {
+    indexsuffix = filename_cat (indexsuffix, indexstem);
+  }
+  return indexsuffix;
+}
+
+
+
+
+////////////////////
+// mgsearch class //
+////////////////////
+
+mgsearchclass::mgsearchclass ()
+  : searchclass() {
+ 
+}
+
+mgsearchclass::~mgsearchclass () 
+{
+  if (cache != NULL) 
+    {
+      delete cache;
+      cache = NULL;
+    }
+}
+
+void mgsearchclass::set_indexstem(const text_t &stem) {
+  indexstem = stem;
+  
+}
+
+// you only need to use this function before doing any stemming
+// casefolding and stemming will be set if values for them are
+// provided (0 or 1).
+// makeindexcurrent returns true if it was able to load the database
+bool mgsearchclass::makeindexcurrent (const text_t &index,
+				      const text_t &subcollection,
+				      const text_t &language,
+				      const text_t &collection,
+				      int casefolding,
+				      int stemming) {
+  bool databaseloaded = true;
+
+  // get the names of the collection, index and text suffixes
+  char *ccollection = collection.getcstr();
+  assert (ccollection != NULL);
+  char *idxsuffix = (getindexsuffix (collection, (index+subcollection+language))).getcstr();
+  assert (idxsuffix != NULL);
+  char *txtsuffix = (getindexsuffix (collection, "text")).getcstr();
+  assert (txtsuffix != NULL);
+#ifdef __WIN32__
+  char *ccollectdir = (collectdir+"\\").getcstr(); assert (ccollectdir != NULL);
+#else
+  char *ccollectdir = collectdir.getcstr(); assert (ccollectdir != NULL);
+#endif
+
+  if (load_database(ccollection, ccollectdir, idxsuffix, txtsuffix)) {
+    if (casefolding == 0) mgq_ask(".set casefold off");
+    else if (casefolding > 0) mgq_ask(".set casefold on");
+    if (stemming == 0) mgq_ask(".set stem off");
+    else if (stemming > 0) mgq_ask(".set stem on");
+    
+  } else databaseloaded = false;
+
+  // free up the c strings
+  delete []ccollection;
+  delete []idxsuffix;
+  delete []txtsuffix;
+  delete []ccollectdir;
+
+  return databaseloaded;
+}
+
+
+// stem word uses the values set in the last call to makeindexcurrent
+// to stem the word. It is assumed that word is in unicode
+text_t mgsearchclass::stemword (const text_t &word) {
+  return to_uni (mgsearch_stemword (to_utf8 (word)));
+}
+
+text_t mgsearchclass::stemword (text_t::const_iterator here, text_t::const_iterator end) {
+  return to_uni (mgsearch_stemword (to_utf8 (here, end)));
+}
+
+/**
+ * search directs the whole execution of the search; a number of other
+ * functions in this class are called as a result, and precondition
+ * checks are also made
+ */
+bool mgsearchclass::search(const queryparamclass &queryparams, 
+			   queryresultsclass &queryresults) {
+  //  assert (cache != NULL);
+
+  // clear any previous results
+  queryresults.clear();
+  // first check the cache
+  if (cache != NULL) {
+    if (cache->find(queryparams, queryresults)) return true;
+  }
+  // make sure there is a query to be processed
+  if (!has_unicode_letdig(queryparams.querystring)) return true;
+
+  if (makeindexcurrent (queryparams.index, queryparams.subcollection,
+			queryparams.language, queryparams.collection)) {
+    // initialise the form of results
+    setsearchmode (queryparams);
+
+    // execute the query
+    submitquery (queryparams);
+
+    // retrieve the results
+    getresults (queryparams, queryresults);
+    unload_database();  // Important that local library doesn't leave any files open
+    return true;
+  }
+
+  return false;
+}
+
+/* accumulator_method has been changed to use array rather than list.
+list appears to be broken somewhat - for some ranked queries, it returned 
+fewer results than it should have (eg 45 instead of 50). The three other
+methods (array, splay_tree, hash_table) all return the same number of 
+documents, in the same order, with the same ranks. list returns what 
+appears to be the same documents (but less of them), but with different ranks,
+and in a different order. Minimal time tests dont show any speed improvement
+of list over array (maybe because its broken??).  [02/2001, kjm18]
+
+... [sjboddie, also 02/2001] turns out that changing the accumulator_method
+introduced a more serious bug than it fixed (i.e. occasionally when doing a
+ranked search for a very common word you get no results at all). I've
+changed it back to list for now, one day we should play with other
+accumulator_methods but for now I don't have time and don't want to risk
+introducing bugs (better the devil you know ;)
+*/
+void mgsearchclass::setsearchmode (const queryparamclass &queryparams)
+{
+  mgq_ask(".set expert true");
+  mgq_ask(".set sorted_terms true");
+  mgq_ask(".set accumulator_method list");
+  mgq_ask(".set max_accumulators 500000");
+  mgq_ask(".set maxparas 500000");
+  mgq_ask(".set verbatim true");
+  mgq_ask(".unset skip_dump");
+  mgq_ask(".set mode docnums");
+
+  switch (queryparams.search_type) 
+    {
+    case 0: mgq_ask(".set query boolean");  break;
+    case 1:  mgq_ask(".set query ranked"); break;
+    }
+  switch (queryparams.casefolding) 
+    {
+    case 1: mgq_ask(".set casefold on");  break;
+    case 0: mgq_ask(".set casefold off"); break;
+    }
+  switch (queryparams.stemming) 
+    {
+    case 1: mgq_ask(".set stem on");  break;
+    case 0: mgq_ask(".set stem off"); break;
+    }
+  mgq_ask(".set heads_length 150");
+  
+  if (queryparams.maxdocs == -1) {
+    mgq_ask(".set maxdocs all");
+  } else {
+    char maxdocstr[32];
+    sprintf(maxdocstr, ".set maxdocs %i", queryparams.maxdocs);
+    mgq_ask(maxdocstr);
+  }
+
+  char maxnumericstr[32];
+  sprintf(maxnumericstr, ".set maxnumeric %i", queryparams.maxnumeric);
+  mgq_ask(maxnumericstr);
+  
+}
+
+/**
+ * submitquery constructs the query string (into UTF8 encoding)
+ * and submits it using mgq_ask to the mg search engine.  Most
+ * of the processing will be done inside Greenstone
+ */
+void mgsearchclass::submitquery (const queryparamclass &queryparams)
+{
+  // sort out the query string; copy it, remove all special characters
+  // and then convert it to a string in UTF8 format
+  text_t ttquerystring = queryparams.querystring;
+  filterquery (ttquerystring);
+  char *querystring = to_utf8(ttquerystring).getcstr();
+
+  // submit the query
+  mgq_ask(querystring);
+
+  // destroy the temporary character array
+  delete []querystring;
+}
+
+/**
+ * getrults is called to retrieve the required data on the docs
+ * which responded to the query submitted in submitquery above.
+ *
+ * It calls the local mgquery (mgq) interface to MG several times,
+ * to obtain the document numbers, term frequencies, term variants
+ * etc.  All processing of the query will be done by Greenstone
+ * thereafter
+ */
+void mgsearchclass::getresults (const queryparamclass &queryparams,
+				queryresultsclass &queryresults) {
+  // get the configuration for the maximum number of documents to
+  // retrieve
+  int howmany = queryparams.maxdocs;
+  if (howmany == -1) howmany = MAXNUMDOCS;
+  mgq_results(result_docnums, 0, howmany, 
+	      ourquerycallback, (void *)(&queryresults));
+  
+  // get the term frequencies
+  mgq_results(result_termfreqs, 0, MAXNUMTERMS, 
+	      termfreqcallback, (void *)(&queryresults));
+  queryresults.sortuniqqueryterms();
+
+  // get term variants 
+  mgq_results(result_terms, 0, MAXNUMTERMS,
+              termvariantscallback, (void *)(&queryresults));
+
+  // get the number of documents retrieved
+  int total_retrieved = 0, is_approx = 0;
+  mgq_docsretrieved (&total_retrieved, &is_approx);
+
+  if (total_retrieved == 0) {
+    // not available (or really was zero)
+    queryresults.docs_matched = queryresults.docs.docset.size();
+    if ((queryparams.maxdocs == -1) ||
+	(queryresults.docs_matched < queryparams.maxdocs))
+      queryresults.is_approx = Exact;
+    else
+      queryresults.is_approx = MoreThan;
+  } else {
+    queryresults.docs_matched = total_retrieved;
+    if (is_approx) queryresults.is_approx = Approximate;
+    else queryresults.is_approx = Exact;
+  }
+}
+
+/**
+ * Tidies the given querystring, removing special characters
+ */
+void mgsearchclass::filterquery (text_t &ttquerystring) {
+  text_t::iterator ithere = ttquerystring.begin ();
+  text_t::iterator itend = ttquerystring.end ();
+  
+  // remove all non alphanumeric characters (except
+  // boolean operators
+  while (ithere != itend) {
+    if ((!is_unicode_letdig(*ithere)) && (*ithere != '!') &&
+	(*ithere != '&') && (*ithere != '|') && (*ithere != '(') &&
+	(*ithere != ')')) (*ithere) = ' ';
+    ++ithere;
+  }
+}
+
+
+// the document text for 'docnum' is placed in 'output'
+// docTargetDocument returns 'true' if it was able to
+// try to get a document
+// collection is needed to see if an index from the 
+// collection is loaded. If no index has been loaded
+// defaultindex is needed to load one
+bool mgsearchclass::docTargetDocument(const text_t &defaultindex,
+				      const text_t &defaultsubcollection,
+				      const text_t &defaultlanguage,
+				      const text_t &collection,
+				      int docnum,
+				      text_t &output) {
+  output.clear();
+
+  // get the mg version of the document
+  char *mgdoc = NULL;
+  int doclen = 0;
+  if (!mgdocument (defaultindex, defaultsubcollection, defaultlanguage,
+		   collection, docnum, mgdoc, doclen)) return false;
+  if (mgdoc == NULL) return false;
+
+  // replace all control-Cs with spaces
+  char *mgdoc_here = mgdoc;
+  char *mgdoc_end = mgdoc + doclen;
+  while (mgdoc_here < mgdoc_end) {
+    if (*mgdoc_here == '\x3') *mgdoc_here = ' ';
+    ++mgdoc_here;
+  }
+
+  // convert this document to unicode
+  utf8inconvertclass inconvert;
+  convertclass::status_t status;
+  inconvert.reset ();
+  inconvert.setinput (mgdoc, doclen);
+  inconvert.convert (output, status);
+
+  delete[] mgdoc;
+  return true;
+}
+
+
+bool mgsearchclass::mgdocument (const text_t &defaultindex, 
+				const text_t &defaultsubcollection,
+				const text_t &defaultlanguage,
+				const text_t &collection,
+				int docnum,
+				char *&UDoc, int &ULen) {
+  int databaseloaded = 0;
+
+  UDoc = NULL; ULen = 0;
+  
+  // see if we can make an appropriate database current
+//    char *ccollection = collection.getcstr();
+//    assert (ccollection != NULL);
+//    databaseloaded = load_text_database (ccollection);
+//    delete []ccollection;
+  
+  // try and load the database
+//    if (!databaseloaded)
+  databaseloaded = makeindexcurrent (defaultindex, defaultsubcollection,
+				     defaultlanguage, collection);
+  
+  if (databaseloaded) {
+    // retrieve the document from mg
+    char docstr[32];
+    sprintf(docstr, "%i", docnum);
+    
+    mgq_ask(".set mode text");
+    mgq_ask(".set query docnums");
+    mgq_ask(docstr);
+
+    tempdoc = NULL;
+    templen = 0;
+    mgq_results (result_docs, 0, 1, doctextcallback, (void *)NULL);
+    UDoc = tempdoc;
+    ULen = templen;
+  }
+
+  unload_database();  // Important that local library doesn't leave any files open
+  return (bool)databaseloaded;
+}
+
+// unload_database simply calls mgq's close_all_databases function to clear
+// any cached databases - this is useful when attempting to completely
+// remove all trace of a collectionserver at runtime (when using a
+// persistent version of Greenstone like the windows local library)
+void mgsearchclass::unload_database () {
+  close_all_databases();
+}
Index: /gsdl/stable/runtime-src/src/colservr/mgsearch.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/mgsearch.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/mgsearch.h	(revision 20131)
@@ -0,0 +1,101 @@
+/**********************************************************************
+ *
+ * mgsearch.h --  implementation of search for old versions of mg
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef MGSEARCH_H
+#define MGSEARCH_H
+
+
+#include "search.h"
+
+class mgsearchclass : public searchclass {
+public:
+  mgsearchclass ();
+  virtual ~mgsearchclass ();
+
+  virtual text_t get_textindex_type() {return "mg";}
+
+  // you only need to use this function before doing any stemming
+  // casefolding and stemming will be set if values for them are
+  // provided (0 or 1).
+  // makeindexcurrent returns true if it was able to load the database
+  bool makeindexcurrent (const text_t &index, const text_t &subcollection,
+			 const text_t &language, const text_t &collection,
+			 int casefolding = -1, int stemming = -1);
+
+  // stem word uses the values set in the last call to makeindexcurrent
+  // to stem the word. It is assumed that word is in unicode
+  text_t stemword (const text_t &word);
+  text_t stemword (text_t::const_iterator here, text_t::const_iterator end);
+  
+  // the search results are returned in queryresults
+  // search returns 'true' if it was able to do a search
+  bool search(const queryparamclass &queryparams, 
+	      queryresultsclass &queryresults);
+  
+  // the document text for 'docnum' is placed in 'output'
+  // docTargetDocument returns 'true' if it was able to
+  // try to get a document
+  // collection is needed to see if an index from the 
+  // collection is loaded. If no index has been loaded
+  // defaultindex is needed to load one
+  bool docTargetDocument(const text_t &defaultindex,
+			 const text_t &defaultsubcollection,
+			 const text_t &defaultlanguage,
+			 const text_t &collection,
+			 int docnum,
+			 text_t &output);
+
+  // same as docTargetDocument except the document is returned
+  // in its raw form. UDoc remains the property of mg and may
+  // be destroyed on the next call to mg.
+  bool mgdocument (const text_t &defaultindex,
+		   const text_t &defaultsubcollection,
+		   const text_t &defaultlanguage,
+		   const text_t &collection,
+		   int docnum,
+		   char *&UDoc, int &ULen);
+
+  // unload_database simply calls mgq's close_all_databases function to
+  // clear any cached databases - this is useful when attempting to
+  // completely remove all trace of a collectionserver at runtime (when
+  // using a persistent version of Greenstone like the windows local
+  // library)
+  void unload_database ();
+
+  void set_indexstem(const text_t &indexstem);
+
+protected:
+
+  text_t indexstem; // the stem of the index files - defaults to the collectionname
+  void setsearchmode (const queryparamclass &queryparams);
+  void submitquery (const queryparamclass &queryparams);
+  void getresults (const queryparamclass &queryparams, queryresultsclass &queryresults);
+  text_t getindexsuffix (const text_t &collection, const text_t &index);
+  virtual void filterquery (text_t &ttquerystring);
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/mgsource.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/mgsource.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/mgsource.cpp	(revision 20131)
@@ -0,0 +1,38 @@
+/**********************************************************************
+ *
+ * mgsource.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "mgsource.h"
+
+
+mgsourceclass::mgsourceclass () 
+  : sourceclass()
+{
+  classname = "mgsource";
+}
+
+mgsourceclass::~mgsourceclass () 
+{
+}
+
Index: /gsdl/stable/runtime-src/src/colservr/mgsource.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/mgsource.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/mgsource.h	(revision 20131)
@@ -0,0 +1,41 @@
+/**********************************************************************
+ *
+ * mgsource.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef MGSOURCE_H
+#define MGSOURCE_H
+
+#include "source.h"
+
+
+class mgsourceclass : public sourceclass {
+public:
+  mgsourceclass ();
+  virtual ~mgsourceclass ();
+
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/phrasequeryfilter.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/phrasequeryfilter.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/phrasequeryfilter.cpp	(revision 20131)
@@ -0,0 +1,84 @@
+/**********************************************************************
+ *
+ * phrasequeryfilter.cpp -- 
+ * Copyright (C) 1999  DigiLib Systems Limited, New Zealand
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "phrasequeryfilter.h"
+#include "queryinfo.h"
+
+#include "phrasesearch.h"
+
+
+
+// do aditional query processing
+void phrasequeryfilterclass::post_process (const queryparamclass &queryparams,
+					   queryresultsclass &queryresults) {
+  bool results_shrunk = false;
+
+  // post-process the results if needed
+  if (queryresults.orgterms.size() > 1 && !queryresults.docs.docset.empty()) {
+    // get the long version of the index
+    text_t longindex;
+    indexmap.to2from (queryparams.index, longindex);
+      
+    // process each of the matched documents
+    docresultmap::iterator docs_here = queryresults.docs.docset.begin();
+    docresultmap::iterator docs_end = queryresults.docs.docset.end();
+    while (docs_here != docs_end) {
+      if ((*docs_here).second.num_query_terms_matched == queryresults.orgterms.size() &&
+	  OID_phrase_search (*(mgsearchclass *)textsearchptr, *db_ptr, queryparams.index,
+			     queryparams.subcollection, queryparams.language, 
+			     longindex, queryparams.collection, queryresults.orgterms,
+			     (*docs_here).second.docnum)) {
+	++docs_here->second.num_phrase_match;
+	++docs_here;
+
+      } else {
+	docresultmap::iterator this_doc_here = docs_here;
+	++docs_here;
+	if (queryparams.match_mode == 1) {
+	  // need to delete this element, there was no exact match
+	  queryresults.docs.docset.erase(this_doc_here);
+	  results_shrunk = true;
+	}
+      }
+    }
+  }
+
+  if (results_shrunk) queryresults.docs_matched = queryresults.docs.docset.size();
+}
+
+
+void phrasequeryfilterclass::sort_doc_results (const FilterRequest_t &/*request*/,
+					 docresultsclass &docs) {
+  resultsorderer_t resultsorderer;
+  resultsorderer.compare_phrase_match = true;
+  resultsorderer.compare_terms_match = true;
+  resultsorderer.compare_doc_weight = true;
+  resultsorderer.docset = &(docs.docset);
+
+  // first get a list of document numbers
+  docs.docnum_order();
+
+  sort (docs.docorder.begin(), docs.docorder.end(), resultsorderer);
+}
Index: /gsdl/stable/runtime-src/src/colservr/phrasequeryfilter.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/phrasequeryfilter.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/phrasequeryfilter.h	(revision 20131)
@@ -0,0 +1,43 @@
+/**********************************************************************
+ *
+ * phrasequeryfilter.h -- 
+ * Copyright (C) 1999  DigiLib Systems Limited, New Zealand
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef PHRASEQUERYFILTER_H
+#define PHRASEQUERYFILTER_H
+
+#include "mgqueryfilter.h"
+
+
+class phrasequeryfilterclass : public mgqueryfilterclass {
+protected:
+  void post_process (const queryparamclass &queryparams,
+		     queryresultsclass &queryresults);
+  void sort_doc_results (const FilterRequest_t &request,
+			 docresultsclass &docs);
+public:
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/phrasesearch.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/phrasesearch.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/phrasesearch.cpp	(revision 20131)
@@ -0,0 +1,259 @@
+/**********************************************************************
+ *
+ * phrasesearch.cpp -- tools to search for a phrase in a larger text
+ * Copyright (C) 1999  DigiLib Systems Limited
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "phrasesearch.h"
+#include "gsdlunicode.h"
+
+inline unsigned char *parse_nonword_word (unsigned char *here, unsigned char *end,
+					  text_t &word) {
+  int c_len = 0;
+  unsigned short c = 0;
+
+  word.clear();
+
+  // parse non word
+  while (here <= end) {
+    c_len = parse_utf8_char (here, end, &c);
+    if (c == '(') {
+      // found a note, look for '}'
+      while (here <= end && c != ')') {
+	c_len = parse_utf8_char (here, end, &c);
+	here += c_len;
+      }
+    }
+    if (c == '{') {
+      // found a composite character, look for '}'
+      while (here <= end && c != '}') {
+	c_len = parse_utf8_char (here, end, &c);
+	here += c_len;
+      }
+    }
+    if (is_unicode_letdig(c)) {
+      while (c_len > 0) {
+	// this is in a word
+	word.push_back(*here);
+	++here; --c_len;
+      }
+      break;
+    }
+    here += c_len;
+  }
+
+  // parse word
+  while (here <= end) {
+    c_len = parse_utf8_char (here, end, &c);
+    if (!is_unicode_letdig(c)) {
+      here += c_len;  // it is ok to skip a nonword character
+      break;
+    }
+    while (c_len > 0) {
+      word.push_back(*here);
+      ++here; --c_len;
+    }
+  }
+
+  return here;
+}
+
+static void get_all_docnums (dbclass &db, text_t OID, vector<int> &docnum_list) {
+
+  infodbclass OID_info;
+  
+  // get OID
+  if (!db.getinfo (OID, OID_info)) return;
+  if (OID_info["hastxt"] == "1" && !OID_info["docnum"].empty()) {
+    docnum_list.push_back (OID_info["docnum"].getint());
+  }
+
+  // get contents set
+  if (OID_info["contains"].empty()) return;
+  text_tarray contains; text_t tmptext;
+  text_t::iterator contains_here = OID_info["contains"].begin();
+  text_t::iterator contains_end = OID_info["contains"].end();
+  while (contains_here != contains_end) {
+    if (*contains_here == '"') tmptext += OID;
+    else if (*contains_here == ';') {
+      if (!tmptext.empty()) contains.push_back (tmptext);
+      tmptext.clear();
+    } else tmptext.push_back(*contains_here);
+    ++contains_here;
+  }
+  if (!tmptext.empty()) contains.push_back (tmptext);
+
+  text_tarray::const_iterator here = contains.begin();
+  text_tarray::const_iterator end = contains.end();
+  while (here != end) {
+    get_all_docnums (db, *here, docnum_list);
+    ++here;
+  }
+}
+
+bool doc_phrase_search (unsigned char *doc, int doclen,
+			const termfreqclassarray &phrase) {
+  // note: this uses the most braindead search routine :-)
+  // however its not so bad as there shouldn't be many partial
+  // matches
+
+  // a null phrase matches anything
+  if (phrase.empty()) return true;
+
+  // if there is nothing then there can't be a match
+  if (doc == NULL || doclen == 0) return false;
+  
+  text_t doc_word;
+  doc_word.reserve (16);
+
+  bool first = true;
+
+  unsigned char *doc_here = doc;
+  unsigned char *doc_herefirstword = doc;
+  unsigned char *doc_end = doc+doclen-1; // unitool conventions :-/
+
+  while (doc_here <= doc_end) {
+    first = true;
+
+    // there will be at least one member of phrase (see above)
+    termfreqclassarray::const_iterator phrase_here = phrase.begin();
+    termfreqclassarray::const_iterator phrase_end = phrase.end();
+    do {
+      // get the next non-word ... and ignore it, then get the next word
+      doc_here = parse_nonword_word (doc_here, doc_end, doc_word);
+      if (first) {doc_herefirstword = doc_here; first = false;}
+
+      // break if this word is not the next in the phrase
+      if ((*phrase_here).utf8equivterms.find (doc_word) ==
+	  (*phrase_here).utf8equivterms.end()) break;
+
+      ++phrase_here;
+    } while (doc_here <= doc_end && phrase_here != phrase_end);
+
+    // see if we found a phrase
+    if (phrase_here == phrase_end) return true;
+    
+    doc_here = doc_herefirstword; // set the counter back
+  }
+
+  return false;
+}
+
+// looks for the stemmed phrase in the metadata or text associated with
+// an OID. This function has not been coded with all situations in mind
+bool OID_phrase_search (mgsearchclass &mgsearch,
+			dbclass &db,
+			const text_t &index,
+			const text_t &subcollection,
+			const text_t &language,
+			const text_t &longindex,
+			const text_t &collection,
+			const termfreqclassarray &phrase,
+			int docnum) {
+
+  // get OID
+  infodbclass docnum_info;
+  if (!db.getinfo (docnum, docnum_info)) return false;
+  text_t &OID = docnum_info["section"];
+  if (OID.empty()) return false;
+
+  // disect the long index to find out where the text should come from
+  text_t gran, type;
+  text_t::const_iterator longindex_here = longindex.begin();
+  text_t::const_iterator longindex_end = longindex.end();
+  longindex_here = getdelimitstr (longindex_here, longindex_end, ':', gran);
+  longindex_here = getdelimitstr (longindex_here, longindex_end, ':', type);
+
+  if (gran.empty()) return false;
+  
+  // note that we're treating indexes of type 'all' (i.e. text,Title,Creator)
+  // or other composite indexes that contain "text" as if they were simply 'text' indexes
+  if ((type == "text") || (type == "all") || (findword(type.begin(),type.end(),"text") != type.end())) {
+    char *doc = NULL;
+    int doclen = 0;
+  
+    // get text from mg.
+    if (gran == "document") {
+
+      // if this is a document level index (which should only happen if
+      // there are no matching indexes with a finer granularity -- see
+      // mgqueryfilterclass::mg_parse_query_params) then we must do the
+      // phrase search on the entire document (i.e. all the sections)
+      // -- this is going to make a slow process even slower
+      vector<int> docnum_list; text_t fulldoc;
+      get_all_docnums (db, OID, docnum_list);
+      vector<int>::const_iterator this_docnum = docnum_list.begin();
+      vector<int>::const_iterator end_docnum = docnum_list.end();
+      while (this_docnum != end_docnum) {
+	if (mgsearch.mgdocument (index, subcollection, language, collection,
+				 *this_docnum, doc, doclen)) {
+	  fulldoc.appendcstr (doc);
+	}
+	++this_docnum;
+      }
+      doc = fulldoc.getcstr();
+      doclen = fulldoc.size();
+      bool rv = doc_phrase_search ((unsigned char *)doc, doclen, phrase);
+      delete []doc;
+      return rv;
+
+    } else {
+
+      if (!mgsearch.mgdocument (index, subcollection, language, collection,
+				docnum, doc, doclen)) return false;
+      return doc_phrase_search ((unsigned char *)doc, doclen, phrase);
+    } 
+  }
+
+  char *metadata = NULL;
+  text_t::size_type metadata_len = 0;
+  infodbclass OID_info;
+  
+  // get field
+  if (!db.getinfo (OID, OID_info)) return false;
+
+  bool result = false;
+
+  // need to look through all the metadata values in the index
+  text_tarray keys;
+  splitchar(type.begin(), type.end(), ',', keys);
+
+  text_tarray::const_iterator keyhere = keys.begin();
+  text_tarray::const_iterator keyend = keys.end();
+  while (keyhere != keyend) {
+    text_tarray *tarr_ptr = OID_info.getmultinfo (*keyhere);
+    if (tarr_ptr != NULL ) {
+      text_tarray::const_iterator subvalue_here = (*tarr_ptr).begin();
+      text_tarray::const_iterator subvalue_end = (*tarr_ptr).end();
+      while (subvalue_here != subvalue_end) {
+	metadata = (to_utf8(*subvalue_here)).getcarr(metadata_len);
+	result = doc_phrase_search ((unsigned char *)metadata, metadata_len, phrase);
+	delete [] metadata;
+	
+	if (result) return true;
+	++subvalue_here;
+      }
+    }
+    ++keyhere;
+  }
+  return result;
+}
Index: /gsdl/stable/runtime-src/src/colservr/phrasesearch.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/phrasesearch.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/phrasesearch.h	(revision 20131)
@@ -0,0 +1,50 @@
+/**********************************************************************
+ *
+ * phrasesearch.h -- tools to search for a phrase in a larger text
+ * Copyright (C) 1999  DigiLib Systems Limited
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef PHRASESEARCH_H
+#define PHRASESEARCH_H
+
+
+#include "text_t.h"
+#include "unitool.h"
+#include "mgsearch.h"
+#include "dbclass.h"
+
+
+// looks for the phrase in the metadata or text associated with
+// a document number. This function has not been coded with all
+// situations in mind and expects mgsearch and db set up ready to go
+bool OID_phrase_search (mgsearchclass &mgsearch,
+			dbclass &db,
+			const text_t &index,
+			const text_t &subcollection,
+			const text_t &language,
+			const text_t &longindex,
+			const text_t &collection,
+			const termfreqclassarray &phrase,
+			int docnum);
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/querycache.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/querycache.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/querycache.cpp	(revision 20131)
@@ -0,0 +1,104 @@
+/**********************************************************************
+ *
+ * querycache.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "querycache.h"
+
+
+
+
+resultcacheel::resultcacheel () 
+{
+  accessnum = -1;
+}
+
+
+
+querycache::querycache (int themaxcachesize)
+{
+  if (themaxcachesize < 1) themaxcachesize = 1;
+  
+  resultcache = new resultcacheel[themaxcachesize];
+
+  maxcachesize = themaxcachesize;
+  nextaccessnum = 1;
+}
+
+querycache::~querycache ()
+{
+  delete [] resultcache;
+}
+
+// returns true if the query was found in the cache
+// if the query was found then queryresults contains
+// the results
+bool querycache::find (const queryparamclass &queryparams, 
+		       queryresultsclass &queryresults)
+{
+  int i;
+
+  for (i=0; i < maxcachesize; ++i)
+    {
+      if (resultcache[i].queryparameters == queryparams)
+	{
+	  queryresults = resultcache[i].queryresults;
+	  resultcache[i].accessnum = getnextaccessnum ();
+	  return true;
+	}
+    }
+
+  return false;
+}
+
+
+void querycache::cache (const queryparamclass &queryparams,
+	  const queryresultsclass &queryresults)
+{
+  int i = getfreecachenum();
+  resultcache[i].queryparameters = queryparams;
+  resultcache[i].queryresults = queryresults;
+  resultcache[i].accessnum = getnextaccessnum ();
+}
+
+int querycache::getnextaccessnum ()
+{
+  return nextaccessnum++;
+}
+
+int querycache::getfreecachenum ()
+{
+  int i;
+  int minaccessnum = 0;
+  int minaccessi = 0;
+  
+  for (i=0; i < maxcachesize; ++i)
+    {
+      if (resultcache[i].accessnum < minaccessnum) {
+	minaccessnum = resultcache[i].accessnum;
+	minaccessi = i;
+      }
+    }
+
+  return minaccessi;
+}
Index: /gsdl/stable/runtime-src/src/colservr/querycache.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/querycache.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/querycache.h	(revision 20131)
@@ -0,0 +1,70 @@
+/**********************************************************************
+ *
+ * querycache.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef QUERYCACHE_H
+#define QUERYCACHE_H
+
+
+#include "text_t.h"
+#include "queryinfo.h"
+
+class resultcacheel
+{
+public:
+  resultcacheel ();
+
+  int accessnum;
+  queryparamclass queryparameters;
+  queryresultsclass queryresults;
+};
+
+
+class querycache {
+public:
+  querycache (int themaxcachesize);
+  ~querycache ();
+
+  // returns true if the query was found in the cache
+  // if the query was found then queryresults contains
+  // the results
+  bool find (const queryparamclass &queryparams, 
+	     queryresultsclass &queryresults);
+
+  void cache (const queryparamclass &queryparams,
+	    const queryresultsclass &queryresults);
+
+protected:
+  resultcacheel *resultcache;
+
+  int maxcachesize;
+  int nextaccessnum;
+  
+  int getnextaccessnum ();
+  int getfreecachenum ();
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/queryfilter.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/queryfilter.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/queryfilter.cpp	(revision 20131)
@@ -0,0 +1,424 @@
+/**********************************************************************
+ *
+ * queryfilter.cpp -- base class for queryfilters
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "queryfilter.h"
+#include "fileutil.h"
+
+
+// translate will return true if successful
+bool queryfilterclass::translate (dbclass *db_ptr, text_t& docnum, text_t &trans_OID) {
+  infodbclass info;
+
+  trans_OID.clear();
+
+  // get the info
+  if (db_ptr == NULL) return false;
+  if (!db_ptr->getinfo(docnum, info)) return false;
+
+  // translate
+  if (info["section"].empty()) return false;
+
+  trans_OID = info["section"];
+  return true;
+}
+
+
+// whether document results are needed
+bool queryfilterclass::need_matching_docs (int filterResultOptions) {
+  return ((filterResultOptions & FROID) || (filterResultOptions & FRranking) ||
+	  (filterResultOptions & FRmetadata));
+}
+
+// whether term information is needed
+bool queryfilterclass::need_term_info (int filterResultOptions) {
+  return ((filterResultOptions & FRtermFreq) || (filterResultOptions & FRmatchTerms));
+}
+
+/////////////////////////////////
+// functions for queryfilterclass
+/////////////////////////////////
+
+// get the query parameters
+void queryfilterclass::parse_query_params (const FilterRequest_t &request,
+					   vector<queryparamclass> &query_params,
+					   int &startresults, int &endresults,
+					   text_t &phrasematch, ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  // set defaults for the return parameters
+  query_params.erase(query_params.begin(), query_params.end());
+  startresults = filterOptions["StartResults"].defaultValue.getint();
+  endresults = filterOptions["EndResults"].defaultValue.getint();
+  phrasematch = filterOptions["PhraseMatch"].defaultValue;
+
+  // set defaults for query parameters
+  queryparamclass query;
+  query.combinequery = "or"; // first one must be "or"
+  query.collection = collection;
+  query.index = filterOptions["Index"].defaultValue;
+  query.subcollection = filterOptions["Subcollection"].defaultValue;
+  query.language = filterOptions["Language"].defaultValue;
+  query.querystring.clear();
+  query.search_type = (filterOptions["QueryType"].defaultValue == "ranked");
+  query.match_mode = (filterOptions["MatchMode"].defaultValue == "all");
+  query.casefolding = (filterOptions["Casefold"].defaultValue == "true");
+  query.stemming = (filterOptions["Stem"].defaultValue == "true");
+  query.accentfolding = (filterOptions["AccentFold"].defaultValue == "true");
+  query.maxdocs = filterOptions["Maxdocs"].defaultValue.getint();
+  query.level = filterOptions["Level"].defaultValue;
+  query.filterstring = filterOptions["FilterString"].defaultValue;  // Lucene specific
+  query.sortfield = filterOptions["SortField"].defaultValue;  // Lucene specific
+  query.fuzziness = filterOptions["Fuzziness"].defaultValue;  // Lucene specific
+  query.maxnumeric = maxnumeric;
+  OptionValue_tarray::const_iterator options_here = request.filterOptions.begin();
+  OptionValue_tarray::const_iterator options_end = request.filterOptions.end();
+  while (options_here != options_end) {
+    if ((*options_here).name == "CombineQuery") {
+      // add this query
+      
+      // "all", needed when combining queries where the document results are needed
+      if (need_matching_docs (request.filterResultOptions)) query.maxdocs = -1; 
+      query_params.push_back (query);
+
+      // start on next query
+      query.clear();
+      query.combinequery = (*options_here).value;
+
+      // set defaults for query parameters
+      query.collection = collection;
+      query.index = filterOptions["Index"].defaultValue;
+      query.subcollection = filterOptions["Subcollection"].defaultValue;
+      query.language = filterOptions["Language"].defaultValue;
+      query.querystring.clear();
+      query.search_type = (filterOptions["QueryType"].defaultValue == "ranked");
+      query.match_mode = (filterOptions["MatchMode"].defaultValue == "all");
+      query.casefolding = (filterOptions["Casefold"].defaultValue == "true");
+      query.stemming = (filterOptions["Stem"].defaultValue == "true");
+      query.accentfolding = (filterOptions["AccentFold"].defaultValue == "true");
+      query.level = filterOptions["Level"].defaultValue;
+      query.filterstring = filterOptions["FilterString"].defaultValue;  // Lucene specific
+      query.sortfield = filterOptions["SortField"].defaultValue;  // Lucene specific
+      query.fuzziness = filterOptions["Fuzziness"].defaultValue;  // Lucene specific
+      query.maxnumeric = maxnumeric;
+      // "all", needed when combining queries where the document results are needed
+      if (need_matching_docs (request.filterResultOptions)) query.maxdocs = -1; 
+      else query.maxdocs = filterOptions["Maxdocs"].defaultValue.getint();
+      
+    } else if ((*options_here).name == "StartResults") {
+      startresults = (*options_here).value.getint();
+    } else if ((*options_here).name == "EndResults") {
+      endresults = (*options_here).value.getint();
+    } else if ((*options_here).name == "QueryType") {
+      query.search_type = ((*options_here).value == "ranked");
+    } else if ((*options_here).name == "MatchMode") {
+      query.match_mode = ((*options_here).value == "all");
+      if (query.match_mode == 1) query.maxdocs = -1;
+    } else if ((*options_here).name == "Term") {
+      query.querystring = (*options_here).value;
+    } else if ((*options_here).name == "Casefold") {
+      query.casefolding = ((*options_here).value == "true");
+    } else if ((*options_here).name == "Stem") {
+      query.stemming = ((*options_here).value == "true");
+    } else if ((*options_here).name == "AccentFold") {
+      query.accentfolding = ((*options_here).value == "true");
+    } else if ((*options_here).name == "Index"&& (*options_here).value !="") {
+      query.index = (*options_here).value;
+    } else if ((*options_here).name == "Subcollection") {
+      query.subcollection = (*options_here).value;
+    } else if ((*options_here).name == "Language") {
+      query.language = (*options_here).value;
+    } else if ((*options_here).name == "Maxdocs") {
+      query.maxdocs = (*options_here).value.getint();
+    } else if ((*options_here).name == "PhraseMatch") {
+      phrasematch = (*options_here).value;
+    } else if ((*options_here).name == "Level") {
+      query.level = (*options_here).value;
+    } else if ((*options_here).name == "FilterString") {
+      query.filterstring = (*options_here).value;
+    } else if ((*options_here).name == "SortField") {
+      query.sortfield = (*options_here).value;
+    } else if ((*options_here).name == "Fuzziness") {
+      query.fuzziness = (*options_here).value;
+    } else {
+      logout << text_t2ascii
+	     << "warning: unknown queryfilter option \""
+	     << (*options_here).name
+	     << "\" ignored.\n\n";
+    }
+
+    ++options_here;
+  }
+
+  // Store the start and end results in the query too, as lucene now needs to
+  // pass them through to the Java
+  query.startresults = startresults;
+  query.endresults = endresults;
+
+  // add the last query
+  query_params.push_back (query);
+}
+
+
+
+
+queryfilterclass::queryfilterclass () {
+  db_ptr = NULL;
+  textsearchptr = NULL;
+  maxnumeric = 4;
+
+  FilterOption_t filtopt;
+  filtopt.name = "CombineQuery";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = "and";
+  filtopt.validValues.push_back("and");
+  filtopt.validValues.push_back("or");
+  filtopt.validValues.push_back("not");
+  filterOptions["CombineQuery"] = filtopt;
+
+  // -- onePerQuery StartResults   integer
+  filtopt.clear();
+  filtopt.name = "StartResults";
+  filtopt.type = FilterOption_t::integert;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = "1";
+  filtopt.validValues.push_back("1");
+  filtopt.validValues.push_back("1000");
+  filterOptions["StartResults"] = filtopt;
+
+  // -- onePerQuery EndResults     integer
+  filtopt.clear();
+  filtopt.name = "EndResults";
+  filtopt.type = FilterOption_t::integert;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = "10";
+  filtopt.validValues.push_back("-1");
+  filtopt.validValues.push_back("1000");
+  filterOptions["EndResults"] = filtopt;
+
+  // -- onePerQuery QueryType      enumerated (boolean, ranked)
+  filtopt.clear();
+  filtopt.name = "QueryType";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = "ranked";
+  filtopt.validValues.push_back("boolean");
+  filtopt.validValues.push_back("ranked");
+  filterOptions["QueryType"] = filtopt;
+
+  // -- onePerQuery MatchMode      enumerated (some, all)
+  filtopt.clear();
+  filtopt.name = "MatchMode";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = "some";
+  filtopt.validValues.push_back("some");
+  filtopt.validValues.push_back("all");
+  filterOptions["MatchMode"] = filtopt;
+
+  // -- onePerTerm  Term           string ???
+  filtopt.clear();
+  filtopt.name = "Term";
+  filtopt.type = FilterOption_t::stringt;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filtopt.defaultValue = "";
+  filterOptions["Term"] = filtopt;
+
+  // -- onePerTerm  Casefold       boolean
+  filtopt.clear();
+  filtopt.name = "Casefold";
+  filtopt.type = FilterOption_t::booleant;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filtopt.defaultValue = "true";
+  filtopt.validValues.push_back("false");
+  filtopt.validValues.push_back("true");
+  filterOptions["Casefold"] = filtopt;
+
+  // -- onePerTerm  Stem           boolean
+  filtopt.clear();
+  filtopt.name = "Stem";
+  filtopt.type = FilterOption_t::booleant;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filtopt.defaultValue = "false";
+  filtopt.validValues.push_back("false");
+  filtopt.validValues.push_back("true");
+  filterOptions["Stem"] = filtopt;
+
+  // -- onePerTerm  AccentFold           boolean
+  filtopt.clear();
+  filtopt.name = "AccentFold";
+  filtopt.type = FilterOption_t::booleant;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filtopt.defaultValue = "false";
+  filtopt.validValues.push_back("false");
+  filtopt.validValues.push_back("true");
+  filterOptions["AccentFold"] = filtopt;
+  
+  // -- onePerTerm  Index          enumerated
+  filtopt.clear();
+  filtopt.name = "Index";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filtopt.defaultValue = "";
+  filterOptions["Index"] = filtopt;
+
+  // -- onePerTerm  Subcollection  enumerated
+  filtopt.clear();
+  filtopt.name = "Subcollection";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filtopt.defaultValue = "";
+  filterOptions["Subcollection"] = filtopt;
+
+  // -- onePerTerm  Language  enumerated
+  filtopt.clear();
+  filtopt.name = "Language";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerTerm;
+  filtopt.defaultValue = "";
+  filterOptions["Language"] = filtopt;
+
+  // -- onePerQuery  Maxdocs  integer
+  filtopt.clear();
+  filtopt.name = "Maxdocs";
+  filtopt.type = FilterOption_t::integert;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = "200";
+  filtopt.validValues.push_back("-1");
+  filtopt.validValues.push_back("1000");
+  filterOptions["Maxdocs"] = filtopt;
+
+  // -- onePerQuery  PhraseMatch  enumerated
+  filtopt.clear();
+  filtopt.name = "PhraseMatch";
+  filtopt.type = FilterOption_t::enumeratedt;
+  filtopt.repeatable = FilterOption_t::onePerQuery;
+  filtopt.defaultValue = "some_phrases";
+  filtopt.validValues.push_back ("all_phrases");
+  filtopt.validValues.push_back ("some_phrases");
+  filtopt.validValues.push_back ("all_docs");
+  filterOptions["PhraseMatch"] = filtopt;
+}
+
+queryfilterclass::~queryfilterclass () {
+  // don't delete db_ptr or textsearchptr here, they'll be cleaned up by the source
+}
+
+void queryfilterclass::configure (const text_t &key, const text_tarray &cfgline) {
+  filterclass::configure (key, cfgline);
+
+  if (key == "indexmap") {
+    indexmap.importmap (cfgline);
+    
+    // update the list of indexes in the filter information
+    text_tarray options;
+    indexmap.gettoarray (options);
+    filterOptions["Index"].validValues = options;
+
+  } else if (key == "defaultindex") {
+    indexmap.from2to (cfgline[0], filterOptions["Index"].defaultValue);
+
+  } else if (key == "subcollectionmap") {
+    subcollectionmap.importmap (cfgline);
+
+    // update the list of subcollections in the filter information
+    text_tarray options;
+    subcollectionmap.gettoarray (options);
+    filterOptions["Subcollection"].validValues = options;
+
+  } else if (key == "defaultsubcollection") {
+    subcollectionmap.from2to (cfgline[0], filterOptions["Subcollection"].defaultValue);
+
+  } else if (key == "languagemap") {
+    languagemap.importmap (cfgline);
+
+    // update the list of languages in the filter information
+    text_tarray options;
+    languagemap.gettoarray (options);
+    filterOptions["Language"].validValues = options;
+
+  } else if (key == "defaultlanguage") {
+    languagemap.from2to (cfgline[0], filterOptions["Language"].defaultValue);
+  } else if (key == "indexstem") {
+    indexstem = cfgline[0];
+  } else if (key == "maxnumeric") {
+    maxnumeric = cfgline[0].getint();
+  }
+  
+}
+
+bool queryfilterclass::init (ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  if (!filterclass::init(logout)) return false;
+
+  if (filterOptions["Index"].defaultValue.empty()) {
+    // use first index in map as default if no default is set explicitly
+    text_tarray fromarray;
+    indexmap.getfromarray(fromarray);
+    if (fromarray.size()) {
+      filterOptions["Index"].defaultValue = fromarray[0];
+    }
+  }
+
+  if (filterOptions["Subcollection"].defaultValue.empty()) {
+    // use first subcollection in map as default if no default is set explicitly
+    text_tarray fromarray;
+    subcollectionmap.getfromarray(fromarray);
+    if (fromarray.size()) {
+      filterOptions["Subcollection"].defaultValue = fromarray[0];
+    }
+  }
+
+  if (filterOptions["Language"].defaultValue.empty()) {
+    // use first language in map as default if no default is set explicitly
+    text_tarray fromarray;
+    languagemap.getfromarray(fromarray);
+    if (fromarray.size()) {
+      filterOptions["Language"].defaultValue = fromarray[0];
+    }
+  }
+
+  if (db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: queryfilter contains a null dbclass\n\n";
+    return false;
+  }
+
+  // get the filename for the database and make sure it exists
+  if (indexstem.empty()) {
+    indexstem = collection;
+  }
+  db_filename = resolve_db_filename(indexstem,db_ptr->getfileextension());
+  if (!file_exists(db_filename)) {
+    logout << text_t2ascii
+	   << "warning: database \"" << db_filename << "\" does not exist\n\n";
+    //return false;
+  }
+
+  return true;
+}
+
Index: /gsdl/stable/runtime-src/src/colservr/queryfilter.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/queryfilter.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/queryfilter.h	(revision 20131)
@@ -0,0 +1,100 @@
+/**********************************************************************
+ *
+ * queryfilter.h -- abstract base class for queryfilters
+ *          mgqueryfilter, mgppqueryfilter and lucenequeryfilter 
+ *          implement this
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef QUERYFILTER_H
+#define QUERYFILTER_H
+
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "comtypes.h"
+#include "filter.h"
+#include "dbclass.h"
+#include "maptools.h"
+#include "search.h"
+#include "queryinfo.h"
+
+
+class queryfilterclass : public filterclass {
+protected:
+
+  stringmap indexmap;
+  stringmap subcollectionmap;
+  stringmap languagemap;
+
+  text_t db_filename;
+  text_t indexstem;
+  dbclass *db_ptr;
+  
+  searchclass *textsearchptr;
+
+  int maxnumeric;
+
+   // get the query parameters
+  void parse_query_params (const FilterRequest_t &request,
+			   vector<queryparamclass> &query_params,
+			   int &startresults, int &endresults,
+			   text_t &phrasematch, ostream &logout);
+
+  // do query that might involve multiple sub queries
+  // textsearchptr and db_ptr are assumed to be valid
+  virtual void do_multi_query (const FilterRequest_t &request,
+		       const vector<queryparamclass> &query_params,
+		       queryresultsclass &multiresults,
+		       comerror_t &err, ostream &logout)=0;
+
+public:
+  queryfilterclass ();
+  virtual ~queryfilterclass ();
+
+  // the db_ptr remains the responsibility of the calling code
+  void set_db_ptr (dbclass *db_ptr_arg) { db_ptr = db_ptr_arg; }
+
+  // the testsearchptr remains the responsability of the calling code
+  void set_textsearchptr (searchclass *thetextsearchptr) {textsearchptr=thetextsearchptr;}
+
+  virtual void configure (const text_t &key, const text_tarray &cfgline);
+  virtual bool init (ostream &logout);
+
+  text_t get_filter_name () {return "QueryFilter";}
+  bool translate(dbclass *db_ptr, text_t& docnum, text_t &trans_OID);
+  bool need_matching_docs (int filterResultOptions);
+  bool need_term_info (int filterResultOptions);
+
+
+  virtual void filter (const FilterRequest_t &request,
+	       FilterResponse_t &response,
+	       comerror_t &err, ostream &logout)=0;
+
+
+
+};
+
+
+#endif
+
Index: /gsdl/stable/runtime-src/src/colservr/queryinfo.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/queryinfo.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/queryinfo.cpp	(revision 20131)
@@ -0,0 +1,431 @@
+/**********************************************************************
+ *
+ * queryinfo.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "queryinfo.h"
+
+
+// query parameters
+
+queryparamclass::queryparamclass () {
+  clear ();
+}
+
+void queryparamclass::clear () {
+  combinequery.clear();
+  collection.clear();
+  index.clear();
+  subcollection.clear();
+  language.clear();
+  level.clear();
+  querystring.clear();
+  search_type = 0; // 0 = boolean, 1 = ranked
+  match_mode = 0; // 0 = some, 1 = all
+  casefolding = 0;
+  stemming = 0;
+  accentfolding = 0;
+  maxdocs = -1;    // all
+  maxnumeric = 4;  // must default to the same value as mg_passes
+  filterstring.clear();
+  sortfield.clear();
+  fuzziness.clear();
+  startresults = 1; // all
+  endresults = 10; // all
+}
+
+
+queryparamclass &queryparamclass::operator=(const queryparamclass &q) {
+  combinequery = q.combinequery;
+  collection = q.collection;
+  index = q.index;
+  subcollection = q.subcollection;
+  language = q.language;
+  level = q.level;
+  querystring = q.querystring;
+  search_type = q.search_type;
+  match_mode = q.match_mode;
+  casefolding = q.casefolding;
+  stemming = q.stemming;
+  accentfolding = q.accentfolding;
+  maxdocs = q.maxdocs;
+  maxnumeric = q.maxnumeric;
+  filterstring = q.filterstring;
+  sortfield = q.sortfield;
+  fuzziness = q.fuzziness;
+  startresults = q.startresults;
+  endresults = q.endresults;
+  return *this;
+}
+
+
+bool operator==(const queryparamclass &x, const queryparamclass &y) {
+  return ((x.combinequery == y.combinequery) &&
+	  (x.collection == y.collection) &&
+	  (x.index == y.index) &&
+	  (x.subcollection == y.subcollection) &&
+	  (x.language == y.language) &&
+	  (x.level == y.level) &&
+	  (x.querystring == y.querystring) &&
+	  (x.search_type == y.search_type) &&
+	  (x.match_mode == y.match_mode) &&
+	  (x.casefolding == y.casefolding) &&
+	  (x.stemming == y.stemming) &&
+	  (x.accentfolding == y.accentfolding) &&
+	  (x.maxdocs == y.maxdocs) &&
+	  (x.maxnumeric == y.maxnumeric) &&
+	  (x.filterstring == y.filterstring) &&
+          (x.sortfield == y.sortfield) &&
+          (x.fuzziness == y.fuzziness) &&
+          (x.startresults == y.startresults) &&
+          (x.startresults == y.startresults));
+}
+
+bool operator!=(const queryparamclass &x, const queryparamclass &y) {
+  return !(x == y);
+}
+
+
+ostream &operator<< (ostream &outs, queryparamclass &q) {
+  outconvertclass text_t2ascii;
+
+  outs << "*** queryparamclass\n";
+  outs << text_t2ascii << " combinequery = \"" << q.combinequery << "\"\n";
+  outs << text_t2ascii << " collection = \"" << q.collection << "\"\n";
+  outs << text_t2ascii << " index = \"" << q.index << "\"\n";
+  outs << text_t2ascii << " level = \"" << q.level << "\"\n";
+  outs << text_t2ascii << " subcollection = \"" << q.subcollection << "\"\n";
+  outs << text_t2ascii << " language = \"" << q.language << "\"\n";
+  outs << text_t2ascii << " querystring = \"" << q.querystring << "\"\n";
+  outs << " search_type = \"" << q.search_type << "\"\n";
+  outs << " match_mode = \"" << q.match_mode << "\"\n";
+  outs << " casefolding = \"" << q.casefolding << "\"\n";
+  outs << " stemming = \"" << q.stemming << "\"\n";
+  outs << " accentfolding = \"" << q.accentfolding << "\"\n";
+  outs << " maxdocs = \"" << q.maxdocs << "\"\n";
+  outs << " maxnumeric = \"" << q.maxnumeric << "\"\n";
+  outs << " filterstring = \"" << q.filterstring << "\"\n";
+  outs << " sortfield = \"" << q.sortfield << "\"\n";
+  outs << " fuzziness = \"" << q.fuzziness << "\"\n";
+  outs << " startresults = \"" << q.startresults << "\"\n";
+  outs << " endresults = \"" << q.endresults << "\"\n";
+  outs << "\n";
+
+  return outs;
+}
+
+
+
+
+// term frequencies
+
+termfreqclass::termfreqclass () {
+  clear();
+}
+
+void termfreqclass::clear() {
+  termstr.clear();
+  termstemstr.clear();
+  utf8equivterms.erase(utf8equivterms.begin(), utf8equivterms.end());
+  termfreq = 0;
+}
+
+termfreqclass &termfreqclass::operator=(const termfreqclass &t)  {
+  termstr = t.termstr;
+  termstemstr = t.termstemstr;
+  utf8equivterms = t.utf8equivterms;
+  termfreq = t.termfreq;
+
+  return *this;
+}
+	
+bool operator==(const termfreqclass &x, const termfreqclass &y) {
+  return ((x.termstr == y.termstr) &&
+	  (x.termstemstr == y.termstemstr) &&
+	  (x.termfreq == y.termfreq));
+}
+
+bool operator!=(const termfreqclass &x, const termfreqclass &y) {
+  return !(x == y);
+}
+
+// ordered by termfreq and then by termstr
+bool operator<(const termfreqclass &x, const termfreqclass &y) {
+  return ((x.termfreq < y.termfreq) ||
+	  ((x.termfreq == y.termfreq) && (x.termstemstr < y.termstemstr)) ||
+	  ((x.termfreq == y.termfreq) && (x.termstemstr == y.termstemstr) && (x.termstr < y.termstr)));
+}
+
+bool operator>(const termfreqclass &x, const termfreqclass &y) {
+  return ((x.termfreq > y.termfreq) ||
+	  ((x.termfreq == y.termfreq) && (x.termstemstr > y.termstemstr)) ||
+	  ((x.termfreq == y.termfreq) && (x.termstemstr == y.termstemstr) && (x.termstr > y.termstr)));
+}
+
+// stream output for debugging purposes
+ostream &operator<< (ostream &outs, termfreqclass &t) {
+  outconvertclass text_t2ascii;
+
+  outs << text_t2ascii << " t:\"" << t.termstr << "\"";
+  outs << text_t2ascii << " s:\"" << t.termstemstr << "\"";
+  outs << " f:" << t.termfreq << "\n";
+
+  return outs;
+}
+
+
+
+// one query result
+
+docresultclass::docresultclass() {
+  clear ();
+}
+
+void docresultclass::clear () {
+  docid="";
+  docnum=-1;
+  docweight=0.0;
+  num_query_terms_matched=0;
+  num_phrase_match=0;
+}
+
+// merges two result classes relating to a single docnum
+docresultclass &docresultclass::combine(const docresultclass &d) {
+  docweight += d.docweight; // budget!
+  num_query_terms_matched += d.num_query_terms_matched;
+  num_phrase_match += d.num_phrase_match;
+
+  return *this;
+}
+
+docresultclass &docresultclass::operator=(const docresultclass &d) {
+  docid = d.docid;
+  docnum = d.docnum;
+  docweight = d.docweight;
+  num_query_terms_matched = d.num_query_terms_matched;
+  num_phrase_match = d.num_phrase_match;
+
+  return *this;
+}
+
+
+bool operator==(const docresultclass &x, const docresultclass &y) {
+  return ((x.docid == y.docid) && (x.docnum == y.docnum) && (x.docweight == y.docweight) &&
+	  (x.num_query_terms_matched == y.num_query_terms_matched) &&
+	  (x.num_phrase_match == y.num_phrase_match));
+}
+
+bool operator<(const docresultclass &x, const docresultclass &y) {
+  return ((x.docid < y.docid) ||
+	  ((x.docid == y.docid) &&
+	   ((x.docnum < y.docnum) ||
+	    ((x.docnum == y.docnum) &&
+	     ((x.docweight < y.docweight) ||
+	      ((x.docweight == y.docweight) &&
+	       ((x.num_query_terms_matched < y.num_query_terms_matched) ||
+		((x.num_query_terms_matched == y.num_query_terms_matched) &&
+		 ((x.num_phrase_match < y.num_phrase_match))))))))));
+}
+
+
+// stream output for debugging purposes
+ostream &operator<< (ostream &outs, docresultclass &a) {
+  outs << " d:" << a.docnum << " w:" << a.docweight << "\n";
+  return outs;
+}
+
+
+
+// many document results
+
+docresultsclass::docresultsclass () {
+  clear ();
+}
+
+void docresultsclass::clear () {
+  docset.erase(docset.begin(), docset.end());
+  docorder.erase(docorder.begin(), docorder.end());
+}
+
+void docresultsclass::docnum_order() {
+  docorder.erase(docorder.begin(), docorder.end());
+  
+  docresultmap::iterator here = docset.begin();
+  docresultmap::iterator end = docset.end();
+  while (here != end) {
+    docorder.push_back ((*here).first);
+    ++here;
+  }
+}
+
+void docresultsclass::combine_and (const docresultsclass &d) {
+  docorder.erase(docorder.begin(), docorder.end());
+
+  // put the resulting set in tempresults
+  docresultmap tempresults;
+  
+  docresultmap::const_iterator d_here = d.docset.begin();
+  docresultmap::const_iterator d_end = d.docset.end();
+  docresultmap::iterator found = docset.end();
+  while (d_here != d_end) {
+    found = docset.find((*d_here).first);
+    if (found != docset.end()) {
+      (*found).second.combine ((*d_here).second);
+      tempresults[(*found).first] = (*found).second;
+    }
+    ++d_here;
+  }
+
+  // then copy it back to docset
+  docset = tempresults;
+}
+
+void docresultsclass::combine_or (const docresultsclass &d) {
+  docorder.erase(docorder.begin(), docorder.end());
+    
+  docresultmap::const_iterator d_here = d.docset.begin();
+  docresultmap::const_iterator d_end = d.docset.end();
+  docresultmap::iterator found = docset.end();
+  while (d_here != d_end) {
+    found = docset.find((*d_here).first);
+    if (found != docset.end()) {
+      (*found).second.combine ((*d_here).second);
+    } else {
+      docset[(*d_here).first] = (*d_here).second;
+    }
+    ++d_here;
+  }
+}
+
+void docresultsclass::combine_not (const docresultsclass &d) {
+  docorder.erase(docorder.begin(), docorder.end());
+
+ docresultmap::const_iterator d_here = d.docset.begin();
+ docresultmap::const_iterator d_end = d.docset.end();
+ docresultmap::iterator found = docset.end();
+ while (d_here != d_end) {
+   found = docset.find((*d_here).first);
+   if (found != docset.end()) docset.erase (found);
+   ++d_here;
+ }
+}
+
+docresultsclass &docresultsclass::operator=(const docresultsclass &d) {
+  docset = d.docset;
+  docorder = d.docorder;
+
+  return *this;
+}
+
+
+
+
+// query results
+
+void queryresultsclass::clear () {
+  error_message = g_EmptyText;
+  docs_matched = 0;
+  is_approx = Exact;
+  syntax_error = false;
+  postprocessed = false;
+
+  docs.clear();
+  orgterms.erase(orgterms.begin(),orgterms.end());
+  terms.erase(terms.begin(),terms.end());
+}
+
+queryresultsclass &queryresultsclass::operator=(const queryresultsclass &q) {
+  error_message = q.error_message;
+  docs_matched = q.docs_matched;
+  is_approx = q.is_approx;
+  syntax_error = q.syntax_error;
+  postprocessed = q.postprocessed;
+
+  docs = q.docs;
+  terms = q.terms;
+  termvariants = q.termvariants;
+
+  return *this;
+}
+
+void queryresultsclass::sortuniqqueryterms() {
+  termfreqclassarray tempterms = orgterms;
+  text_tset seenterms;
+  terms.erase(terms.begin(), terms.end());
+
+  // sort the terms to get the frequencies in ascending order
+  sort (tempterms.begin(), tempterms.end());
+
+  // insert first occurance of each term (maximum)
+  termfreqclassarray::reverse_iterator here = tempterms.rbegin();
+  termfreqclassarray::reverse_iterator end = tempterms.rend();
+  while (here != end) {
+    if (seenterms.find((*here).termstr) == seenterms.end()) {
+      // the termstemstr and utf8equivterms might be different for
+      // different occurances of the term
+      (*here).termstemstr.clear();
+      (*here).utf8equivterms.erase((*here).utf8equivterms.begin(),
+				   (*here).utf8equivterms.end());
+      terms.push_back(*here);
+      seenterms.insert((*here).termstr);
+    }
+    ++here;
+  }
+
+  // now re-sort in ascending order
+  sort (terms.begin(), terms.end());
+}
+
+
+// stream output for debugging purposes
+ostream &operator<< (ostream &outs, queryresultsclass &q) {
+  outs << "*** queryresultsclass\n";
+  outs << "docs\n";
+
+  docresultmap::iterator docshere = q.docs.docset.begin();
+  docresultmap::iterator docsend = q.docs.docset.end();
+  while (docshere != docsend) {
+    outs << (*docshere).second;
+    ++docshere;
+  }
+
+  outs << "orgterms\n";
+  termfreqclassarray::iterator orgtermshere = q.orgterms.begin();
+  termfreqclassarray::iterator orgtermsend = q.orgterms.end();
+  while (orgtermshere != orgtermsend) {
+    outs << (*orgtermshere);
+    ++orgtermshere;
+  }
+
+  outs << "terms\n";
+  termfreqclassarray::iterator termshere = q.terms.begin();
+  termfreqclassarray::iterator termsend = q.terms.end();
+  while (termshere != termsend) {
+    outs << (*termshere);
+    ++termshere;
+  }
+
+  outs << "\n";
+
+  return outs;
+}
Index: /gsdl/stable/runtime-src/src/colservr/queryinfo.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/queryinfo.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/queryinfo.h	(revision 20131)
@@ -0,0 +1,198 @@
+/**********************************************************************
+ *
+ * queryinfo.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef QUERYINFO_H
+#define QUERYINFO_H
+
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "comtypes.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\vector>
+#  include <ospace\std\algorithm>
+#elif defined(GSDL_USE_STL_H)
+#  include <vector.h>
+#  if defined(GSDL_USE_ALGO_H)
+#    include <algo.h>
+#  else
+#    include <algorithm.h>
+#  endif
+#else
+#  include <vector>
+#  include <algorithm>
+#endif
+
+// query parameters
+
+struct queryparamclass {
+  text_t combinequery;
+  text_t collection;
+
+  // search_index = index+subcollection+language
+  text_t index;
+  text_t subcollection;
+  text_t language;
+  text_t level; // for new mg stuff
+  text_t querystring;
+  int search_type; // 0 = boolean, 1 = ranked
+  int match_mode; // 0 = some, 1 = all
+  int casefolding;
+  int stemming;
+  int accentfolding;
+  int maxdocs;
+  int maxnumeric;
+  text_t filterstring; // Filter specified (currently only used by Lucene)
+  text_t sortfield; // Field to use for sorting result set (currently used by lucene)
+  text_t fuzziness; // Search fuzziness amount between 0.0 and 1.0 (only used by Lucene)
+
+  int startresults;
+  int endresults;
+
+  queryparamclass ();
+  void clear ();
+  queryparamclass &operator=(const queryparamclass &q);
+};
+
+bool operator==(const queryparamclass &x, const queryparamclass &y);
+bool operator!=(const queryparamclass &x, const queryparamclass &y);
+
+// stream output for debugging purposes
+ostream &operator<< (ostream &outs, queryparamclass &q);
+
+
+
+// term frequencies
+
+struct termfreqclass {
+  text_t termstr;
+  text_t termstemstr;
+  text_tset utf8equivterms; // kept as utf8 string for fast matching
+  unsigned int termfreq;
+
+  termfreqclass ();
+  void clear();
+  termfreqclass &operator=(const termfreqclass &t);
+};
+
+typedef vector<termfreqclass> termfreqclassarray;
+
+bool operator==(const termfreqclass &x, const termfreqclass &y);
+bool operator!=(const termfreqclass &x, const termfreqclass &y);
+bool operator<(const termfreqclass &x, const termfreqclass &y);
+bool operator>(const termfreqclass &x, const termfreqclass &y);
+
+// stream output for debugging purposes
+ostream &operator<< (ostream &outs, termfreqclass &q);
+
+
+
+// one query result
+
+struct docresultclass {
+  text_t docid;  // currently used by Lucene only
+  int docnum;
+  float docweight;
+  unsigned int num_query_terms_matched;  // not available on all versions of mg
+  int num_phrase_match;                  // not available on all versions of mg
+
+  docresultclass();
+  ~docresultclass() {}
+  void clear ();
+  
+  // merges two result classes relating to a single docnum
+  docresultclass &combine(const docresultclass &d);
+
+  docresultclass &operator=(const docresultclass &d);
+};
+
+bool operator==(const docresultclass &x, const docresultclass &y);
+bool operator<(const docresultclass &x, const docresultclass &y);
+
+
+// stream output for debugging purposes
+ostream &operator<< (ostream &outs, docresultclass &a);
+
+
+struct ltint {
+  bool operator()(const int &t1, const int &t2) const
+  { return t1 < t2; }
+};
+
+typedef map<text_t, docresultclass, lttext_t> docresultmap;
+
+
+
+// many document results
+
+struct docresultsclass {
+  docresultmap docset;
+  vector<text_t> docorder;
+
+  docresultsclass ();
+  void clear ();
+  void docnum_order();
+
+  void combine_and (const docresultsclass &d);
+  void combine_or (const docresultsclass &d);
+  void combine_not (const docresultsclass &d);
+  
+  docresultsclass &operator=(const docresultsclass &d);
+};
+
+
+
+
+// query results
+
+struct queryresultsclass {
+  queryresultsclass () {clear();}
+
+  text_t error_message;  // Currently only used by Lucene
+  int docs_matched; // not available on all versions of mg
+  isapprox is_approx;
+  //  bool is_approx;   // not available on all versions of mg
+  bool syntax_error; // whether the query string was invalid
+  bool postprocessed; // whether this record has been post-processed
+  
+  docresultsclass docs;
+  termfreqclassarray orgterms; // terms before they are sorted and uniqued
+  termfreqclassarray terms;
+  text_tset termvariants;
+  text_tset stopwords;
+
+  void clear ();
+  queryresultsclass &operator=(const queryresultsclass &q);
+  
+  void sortuniqqueryterms();
+};
+
+// stream output for debugging purposes
+ostream &operator<< (ostream &outs, queryresultsclass &q);
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/search.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/search.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/search.cpp	(revision 20131)
@@ -0,0 +1,53 @@
+/**********************************************************************
+ *
+ * search.cpp -- abstract search class for mg
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "search.h"
+
+////////////////////
+// search class //
+////////////////////
+
+searchclass::searchclass ()
+{
+  cache = new querycache (RESULTCACHESIZE);
+ 
+}
+
+searchclass::~searchclass () 
+{
+  if (cache != NULL) 
+    {
+      delete cache;
+      cache = NULL;
+    }
+}
+
+
+void searchclass::setcollectdir (const text_t &thecollectdir)
+{
+  collectdir = thecollectdir;
+}
+
+
Index: /gsdl/stable/runtime-src/src/colservr/search.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/search.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/search.h	(revision 20131)
@@ -0,0 +1,80 @@
+/**********************************************************************
+ *
+ * search.h -- abstract search class for mg systems
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef SEARCH_H
+#define SEARCH_H
+
+#include "text_t.h"
+#include "querycache.h"
+
+#define RESULTCACHESIZE 10
+#define MAXNUMDOCS      1000000
+#define MAXNUMTERMS     100
+
+class searchclass {
+public:
+  searchclass ();
+  virtual ~searchclass ();
+
+  // in subclass, should be over-rided to return "mg" or "mgpp"
+  virtual text_t get_textindex_type()=0;
+  // the index directory must be set before any searching
+  // is done
+  virtual void setcollectdir (const text_t &thecollectdir);
+  
+  // the search results are returned in queryresults
+  // search returns 'true' if it was able to do a search
+   virtual bool search(const queryparamclass &queryparams, 
+	      queryresultsclass &queryresults)=0;
+  
+  // the document text for 'docnum' is placed in 'output'
+  // docTargetDocument returns 'true' if it was able to
+  // try to get a document
+  // collection is needed to see if an index from the 
+  // collection is loaded. If no index has been loaded
+  // defaultindex is needed to load one
+  virtual bool docTargetDocument(const text_t &defaultindex,
+			 const text_t &defaultsubcollection,
+			 const text_t &defaultlanguage,
+			 const text_t &collection,
+			 int docnum,
+			 text_t &output)=0;
+
+  // unload_database clears any cached databases - 
+  // this is useful when attempting to
+  // completely remove all trace of a collectionserver at runtime (when
+  // using a persistent version of Greenstone like the windows local
+  // library)
+  virtual void unload_database ()=0;
+
+protected:
+  querycache *cache;
+  text_t collectdir; // the collection directory
+
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/source.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/source.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/source.cpp	(revision 20131)
@@ -0,0 +1,456 @@
+/**********************************************************************
+ *
+ * source.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "source.h"
+#include "fileutil.h"
+#include "OIDtools.h"
+#include <assert.h>
+
+
+sourceclass::sourceclass ()
+{
+  db_ptr = NULL;
+  textsearchptr = NULL;
+  classname = "source";
+}
+
+sourceclass::~sourceclass ()
+{
+  if (db_ptr != NULL) delete db_ptr;
+  if (textsearchptr != NULL) delete textsearchptr;
+}
+
+// configure should be called once for each configuration line
+void sourceclass::configure (const text_t &key, const text_tarray &cfgline)
+{
+  if (cfgline.size() >= 1) {
+    const text_t &value = cfgline[0];
+
+    if (key == "collection") collection = value;
+    else if (key == "collectdir") collectdir = value;
+    else if (key == "gsdlhome") gsdlhome = value;
+    else if (key == "collecthome") collecthome = value;
+    else if (key == "gdbmhome") dbhome = value;
+  }
+
+  if (key == "indexmap") {
+    indexmap.importmap (cfgline);
+
+  } else if (key == "defaultindex") {
+    indexmap.from2to (cfgline[0], defaultindex);
+
+  } else if (key == "subcollectionmap") {
+    subcollectionmap.importmap (cfgline);
+
+  } else if (key == "defaultsubcollection") {
+    subcollectionmap.from2to (cfgline[0], defaultsubcollection);
+
+  } else if (key == "languagemap") {
+    languagemap.importmap (cfgline);
+
+  } else if (key == "defaultlanguage") {
+    languagemap.from2to (cfgline[0], defaultlanguage);
+  } else if (key == "indexstem") {
+    indexstem = cfgline[0];
+  }
+}
+
+text_t sourceclass::resolve_db_filename(const text_t& idx,
+					const text_t& file_ext)
+{
+  // This is an exact copy of the method (of the same name) in filterclass
+  // Makes sense to merge them, in which either gsdlhome, collecthome,
+  // dbhome, and collection need to also be passed in as parameters,
+  // or else there is some notion of a shared base class that both
+  // filter and source inherit from
+
+  // NB: there is an even greater opportunity to share more code in this
+  // function if sql_db_ptr/db_ptr and db_filename and sql_db_filename
+  // are also drawn from one object
+
+  text_t resolved_filename;
+
+  if (gsdlhome==dbhome) {
+    // dbhome has defaulted to gsdlhome which we take to means the 
+    // database has been specifically moved out of gsdlhome area.
+    // => it should be whereever collecthome is set to
+
+    resolved_filename = filename_cat(collecthome, collection, "index", "text", idx);
+  }
+  else {
+    // dbhome is explicitly set to something other than gsdlhome
+    // => use dbhome
+    resolved_filename = filename_cat(dbhome, "collect", collection, "index", "text", idx);
+  }
+
+  resolved_filename += file_ext;
+
+  return resolved_filename;
+}
+
+
+
+// init should be called after all the configuration is done but
+// before any other methods are called
+bool sourceclass::init (ostream &logout)
+{
+  outconvertclass text_t2ascii;
+  
+  if (collecthome.empty()) collecthome = filename_cat(gsdlhome,"collect");
+  if (dbhome.empty()) dbhome = gsdlhome;
+
+  if (defaultindex.empty()) {
+    // use first index in map as default if no default is set explicitly
+    text_tarray toarray;
+    indexmap.gettoarray(toarray);
+    if (toarray.size()) {
+      defaultindex = toarray[0];
+    }
+  }
+
+  if (defaultsubcollection.empty()) {
+    // use first subcollection in map as default if no default is set explicitly
+    text_tarray toarray;
+    subcollectionmap.gettoarray(toarray);
+    if (toarray.size()) {
+      defaultsubcollection = toarray[0];
+    }
+  }
+
+  if (defaultlanguage.empty()) {
+    // use first language in map as default if no default is set explicitly
+    text_tarray toarray;
+    languagemap.gettoarray(toarray);
+    if (toarray.size()) {
+      defaultlanguage = toarray[0];
+    }
+  }
+  
+  // get the collection directory name
+  if (collectdir.empty()) {
+    collectdir = filename_cat (collecthome, collection);
+  }
+
+  if (db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: queryfilter contains a null dbclass\n\n";
+    return false;
+  }
+
+  // get the filename for the database and make sure it exists
+  if (indexstem.empty()) {
+    indexstem = collection;
+  }
+  db_filename = resolve_db_filename(indexstem, db_ptr->getfileextension());
+  if (!file_exists(db_filename)) {
+    logout << text_t2ascii
+	   << "warning: database \"" << db_filename << "\" does not exist\n\n";
+    // return false;
+  }
+  
+  return true;
+}
+
+
+// translate_OID translates OIDs using ".pr", ."fc" etc.
+bool sourceclass::translate_OID (const text_t &OIDin, text_t &OIDout, 
+				 comerror_t &err, ostream &logout)
+{
+  outconvertclass text_t2ascii;
+
+  err = noError;
+  if (db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: " << classname << " contains a null dbclass\n\n";
+    err = configurationError;
+    return true;
+  }
+
+  // open the database
+  db_ptr->setlogout(&logout);
+  if (!db_ptr->opendatabase (db_filename, DB_READER, 100, false)) {
+    // most likely a system problem (we have already checked that the database exists)
+    logout << text_t2ascii
+	   << "system problem: open on database \"" << db_filename << "\" failed\n\n";
+    err = systemProblem;
+    return true;
+  }
+
+  infodbclass info;
+  OIDout = db_ptr->translate_OID (OIDin, info);
+  db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+  return true;
+}
+
+
+// get_metadata fills out the metadata if possible, if it is not responsable
+// for the given OID then it will return false.
+bool sourceclass::get_metadata (const text_t &requestParams, const text_t &refParams, 
+				bool getParents, const text_tset &fields, 
+				const text_t &OID, MetadataInfo_tmap &metadata, 
+				comerror_t &err, ostream &logout)
+{
+  outconvertclass text_t2ascii;
+
+  metadata.erase(metadata.begin(), metadata.end());
+
+  err = noError;
+  if (db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: " << classname <<" contains a null dbclass\n\n";
+    err = configurationError;
+    return true;
+  }
+
+  // open the database
+  db_ptr->setlogout(&logout);
+  if (!db_ptr->opendatabase (db_filename, DB_READER, 100, false)) {
+    // most likely a system problem (we have already checked that the database exists)
+    logout << text_t2ascii
+	   << "system problem: open on database \"" << db_filename << "\" failed\n\n";
+    err = systemProblem;
+    return true;
+  }
+
+  // get the metadata - if getParents is set we need to get 
+  // info for all parents of OID as well as OID
+  vector<infodbclass> info_array;
+  text_tarray OIDs;
+  if (getParents) get_parents_array (OID, OIDs);
+  OIDs.push_back (OID);
+
+  text_tarray::const_iterator this_OID = OIDs.begin();
+  text_tarray::const_iterator end_OID = OIDs.end();
+
+  while (this_OID != end_OID) {
+    infodbclass info;
+    if (!db_ptr->getinfo(*this_OID, info)) return false;
+
+    // adjust the metadata
+    text_t &contains = info["contains"];
+    if (contains.empty()) info["haschildren"] = 0;
+    else info["haschildren"] = 1;
+    //contains.clear();
+
+    info_array.push_back(info);
+    ++this_OID;
+  }
+
+  // if fields set is empty we want to get all available metadata
+  text_tset tfields = fields;
+  if (tfields.empty() && !info_array.empty()) {
+    infodbclass::iterator t_info = info_array[0].begin(); 
+    infodbclass::iterator e_info = info_array[0].end(); 
+    while (t_info != e_info) {
+      if ((*t_info).first != "contains")
+	tfields.insert ((*t_info).first);
+      ++t_info;
+    }
+    tfields.insert ("hasnext");
+    tfields.insert ("hasprevious");
+  }
+    
+  // collect together the metadata
+  bool donenextprevtest = false;
+  bool hasnext=false, hasprevious=false;
+  MetadataInfo_t this_metadata;
+  text_tarray *pos_metadata;
+  text_tset::const_iterator fields_here = tfields.begin();
+  text_tset::const_iterator fields_end = tfields.end();
+
+  while (fields_here != fields_end) {
+    this_metadata.clear();
+    this_metadata.isRef = false;
+
+    vector<infodbclass>::reverse_iterator this_info = info_array.rbegin(); 
+    vector<infodbclass>::reverse_iterator end_info = info_array.rend(); 
+    MetadataInfo_t *tmetaptr = &this_metadata;
+    while (this_info != end_info) {
+
+      pos_metadata = (*this_info).getmultinfo(*fields_here);
+      if ((*fields_here == "hasnext" || *fields_here == "hasprevious")) {
+	
+	// collect metadata
+	if (!donenextprevtest) {
+	  donenextprevtest = true;
+	  
+	  // cache parent contents array
+	  text_t thisparent = get_parent (OID);
+	  if (!thisparent.empty()) {
+	    if (thisparent != parentOID) {
+	      parentOID = thisparent;
+	      parentcontents.erase(parentcontents.begin(), parentcontents.end());
+	      if (db_ptr->getinfo(parentOID, parentinfo)) {
+		text_t &parentinfocontains = parentinfo["contains"];
+		if (!parentinfocontains.empty())
+		  splitchar (parentinfocontains.begin(), parentinfocontains.end(), 
+			     ';', parentcontents);
+	      }
+	    }
+	    
+	    // do tests
+	    text_tarray::const_iterator parentcontents_here = parentcontents.begin();
+	    text_tarray::const_iterator parentcontents_end = parentcontents.end();
+	    text_t shrunk_OID = OID;
+	    shrink_parent (shrunk_OID);
+	    while (parentcontents_here != parentcontents_end) {
+	      if (*parentcontents_here == shrunk_OID) {
+		if (parentcontents_here == parentcontents.begin()) hasprevious = false;
+		else hasprevious = true;
+		
+		++parentcontents_here;
+		
+		if (parentcontents_here == parentcontents.end()) hasnext = false;
+		else hasnext = true;
+		
+		break;
+	      }  
+	      
+	      ++parentcontents_here;
+	    }
+	 
+	    // fill in metadata
+	    if ((*fields_here == "hasnext" && hasnext) ||
+		(*fields_here == "hasprevious" && hasprevious))
+	      tmetaptr->values.push_back("1");
+	    else
+	      tmetaptr->values.push_back("0");
+	  } else
+	    tmetaptr->values.push_back("0");
+	}
+      }
+      //else if (pos_metadata != NULL && *fields_here != "contains") {
+      else if (pos_metadata != NULL) {
+	tmetaptr->values = *pos_metadata;
+      }
+      else
+	tmetaptr->values.push_back("");
+
+      ++this_info;
+      if (this_info != end_info) {
+	tmetaptr->parent = new MetadataInfo_t();
+	tmetaptr = tmetaptr->parent;
+      }
+    }
+    metadata[*fields_here] = this_metadata;
+    ++fields_here;
+  }
+
+  db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+  return true;
+}
+
+bool sourceclass::get_document (const text_t &OID, text_t &doc, 
+				comerror_t &err, ostream &logout)
+{
+  outconvertclass text_t2ascii;
+
+  err = noError;
+  if (db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii 
+	   << "configuration error: " << classname << " contains a null dbclass\n\n";
+    err = configurationError;
+    return true;
+  }
+
+  // open the database
+  db_ptr->setlogout(&logout);
+  if (!db_ptr->opendatabase (db_filename, DB_READER, 100, false)) {
+    // most likely a system problem (we have already checked that the database exists)
+    logout << text_t2ascii
+	   << "system problem: open on database \"" << db_filename << "\" failed\n\n";
+    err = systemProblem;
+    return true;
+  }
+
+  text_t tOID = OID;
+  if (needs_translating (OID)) 
+    translate_OID (OID, tOID, err, logout);
+  infodbclass info;
+  if (!db_ptr->getinfo(tOID, info)) {
+    db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+    return false;
+  }
+  
+  if (info["hastxt"].getint() == 1) {
+    int docnum = info["docnum"].getint();
+    
+    // set the collection directory
+    textsearchptr->setcollectdir (collectdir);
+    
+    // get the text
+    textsearchptr->docTargetDocument(defaultindex, defaultsubcollection,
+				   defaultlanguage, collection, docnum, doc);
+  }
+
+  db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+  return true;
+}
+
+bool sourceclass::is_searchable(bool &issearchable, comerror_t &err, ostream &logout)
+{
+  err = noError;
+  issearchable = false;
+
+  text_tarray fromarray;
+  indexmap.getfromarray(fromarray);
+  if (fromarray.size() == 0) {
+    return true;
+  } else if (fromarray.size() == 1) {
+    if (fromarray[0] == "dummy:text") {
+      // always return true - issearchable is false here though
+      return true;
+    }
+  }
+  issearchable = true;
+  return true;
+}
+
+
+bool operator==(const sourceptr &x, const sourceptr &y) {
+  return (x.s == y.s);
+}
+
+bool operator<(const sourceptr &x, const sourceptr &y) {
+  return (x.s < y.s);
+}
+
+
+// thesource remains the property of the calling code but
+// should not be deleted until it is removed from this list.
+void sourcelistclass::addsource (sourceclass *thesource) {
+  // can't add a source that doesn't exist
+  assert (thesource != NULL);
+  if (thesource == NULL) return;
+
+  sourceptr sp;
+  sp.s = thesource;
+
+  sourceptrs.push_back(sp);
+}
Index: /gsdl/stable/runtime-src/src/colservr/source.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/source.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/source.h	(revision 20131)
@@ -0,0 +1,164 @@
+/**********************************************************************
+ *
+ * source.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef SOURCE_H
+#define SOURCE_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "dbclass.h"
+#include "search.h"
+#include "comtypes.h"
+#include "maptools.h"
+
+
+class sourceclass {
+protected:
+  text_t classname;
+
+  text_t gsdlhome;
+  text_t collecthome;
+  text_t dbhome;
+  text_t collection;
+  text_t collectdir;
+
+  stringmap indexmap;
+  stringmap subcollectionmap;
+  stringmap languagemap;
+
+  text_t defaultindex;
+  text_t defaultsubcollection;
+  text_t defaultlanguage;
+
+  text_t indexstem;
+
+  text_t parentOID;
+  infodbclass parentinfo;
+  text_tarray parentcontents;
+
+  text_t db_filename;
+  dbclass *db_ptr;
+
+  searchclass *textsearchptr;
+
+public:
+  sourceclass ();
+  virtual ~sourceclass ();
+
+  // the DB ptr remains the responsibility of the calling code
+  void set_db_ptr (dbclass *db_ptr_arg) { db_ptr = db_ptr_arg; }
+
+  // the textsearchptr remains the responsibility of the calling code
+  void set_textsearchptr (searchclass *textsearchptr_arg) { textsearchptr = textsearchptr_arg; }
+
+  // configure should be called once for each configuration line
+  virtual void configure (const text_t &key, const text_tarray &cfgline);
+
+  // init should be called after all the configuration is done but
+  // before any other methods are called
+  virtual bool init (ostream &logout);
+
+  // translate_OID translates OIDs using ".pr", ."fc" etc.
+  virtual bool translate_OID (const text_t &OIDin, text_t &OIDout, 
+			      comerror_t &err, ostream &logout);
+
+  // get_metadata fills out the metadata if possible, if it is not responsable
+  // for the given OID then it will return false.
+  virtual bool get_metadata (const text_t &requestParams, const text_t &refParams, 
+			     bool getParents, const text_tset &fields,
+			     const text_t &OID, MetadataInfo_tmap &metadata, 
+			     comerror_t &err, ostream &logout);
+
+  virtual bool get_document (const text_t &OID, text_t &doc, 
+			     comerror_t &err, ostream &logout);
+
+  virtual bool is_searchable(bool &issearchable, comerror_t &err, ostream &logout);
+
+ protected:
+  text_t resolve_db_filename(const text_t& idx,
+			     const text_t& file_ext);
+
+};
+
+
+// The sourceptr class does not 'own' the source. The 
+// source should be deleted by the code which created it.
+class sourceptr {
+public:
+  sourceclass *s;
+
+  sourceptr () {s=NULL;}
+  ~sourceptr () {}
+};
+
+bool operator==(const sourceptr &x, const sourceptr &y);
+bool operator<(const sourceptr &x, const sourceptr &y);
+
+typedef vector<sourceptr> sourceptrlist;
+
+// contains a list of sources
+class sourcelistclass {
+protected:
+  sourceptrlist sourceptrs;
+
+public:
+  // type support for sourcelistclass
+  typedef sourceptrlist::iterator iterator;
+  typedef sourceptrlist::const_iterator const_iterator;
+  typedef sourceptrlist::reference reference;
+  typedef sourceptrlist::const_reference const_reference;
+  typedef sourceptrlist::size_type size_type;
+
+  typedef sourceptrlist::difference_type difference_type;
+  typedef sourceptrlist::const_reverse_iterator const_reverse_iterator;
+  typedef sourceptrlist::reverse_iterator reverse_iterator;
+  
+  // basic container support
+  iterator begin () {return sourceptrs.begin();}
+  const_iterator begin () const {return sourceptrs.begin();}
+  iterator end () {return sourceptrs.end();}
+  const_iterator end () const {return sourceptrs.end();}
+
+  void erase(iterator pos) {sourceptrs.erase(pos);}
+  void erase(iterator first, iterator last) {sourceptrs.erase(first, last);}
+  sourcelistclass &operator=(const sourcelistclass &x) 
+    {sourceptrs=x.sourceptrs;return *this;}
+
+  bool empty () const {return sourceptrs.empty();}
+  size_type size() const {return sourceptrs.size();}
+
+
+  // added functionality
+  void clear () {sourceptrs.erase(sourceptrs.begin(),sourceptrs.end());}
+
+  // thesource remains the property of the calling code but
+  // should not be deleted until it is removed from this list.
+  void addsource (sourceclass *thesource);
+};
+
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/sqlbrowsefilter.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/sqlbrowsefilter.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/sqlbrowsefilter.cpp	(revision 20131)
@@ -0,0 +1,204 @@
+/**********************************************************************
+ *
+ * sqlbrowsefilter.cpp -- 
+ * Copyright (C) 2008  DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "sqlbrowsefilter.h"
+#include "fileutil.h"
+
+
+sqlbrowsefilterclass::sqlbrowsefilterclass ()
+{
+  sql_db_ptr = NULL;
+}
+
+
+sqlbrowsefilterclass::~sqlbrowsefilterclass ()
+{
+}
+
+
+void sqlbrowsefilterclass::configure (const text_t &key, const text_tarray &cfgline)
+{
+  filterclass::configure (key, cfgline);
+
+  if (key == "indexstem")
+  {
+    indexstem = cfgline[0];
+  }
+}
+
+
+bool sqlbrowsefilterclass::init (ostream &logout)
+{
+  outconvertclass text_t2ascii;
+
+  if (!filterclass::init(logout)) return false;
+
+  if (sql_db_ptr == NULL)
+  {
+    // most likely a configuration problem
+    logout << text_t2ascii << "configuration error: sqlbrowsefilter contains a null sqldbclass\n\n";
+    return false;
+  }
+
+  if (indexstem.empty())
+  {
+    indexstem = collection;
+  }
+
+  // get the filename for the database and make sure it exists
+  sql_db_filename = resolve_db_filename(indexstem,sql_db_ptr->getfileextension());
+  if (!file_exists(sql_db_filename))
+  {
+    logout << text_t2ascii << "warning: database \"" << sql_db_filename << "\" does not exist\n\n";
+    return false;
+  }
+
+  return true;
+}
+
+
+void sqlbrowsefilterclass::filter (const FilterRequest_t &request,
+				   FilterResponse_t &response,
+				   comerror_t &err, ostream &logout)
+{
+  outconvertclass text_t2ascii;
+
+  response.clear();
+  err = noError;
+
+  if (sql_db_ptr == NULL) {
+    // most likely a configuration problem
+    logout << text_t2ascii << "configuration error: sqlbrowsefilter contains a null sqldbclass\n\n";
+    err = configurationError;
+    return;
+  }
+
+  // open the database
+  sql_db_ptr->setlogout (&logout);
+  if (!sql_db_ptr->opendatabase (sql_db_filename, DB_READER, 100, false)) {
+    // most likely a system problem (we have already checked that the database exists)
+    logout << text_t2ascii << "system problem: open on database \"" << sql_db_filename << "\" failed\n\n";
+    err = systemProblem;
+    return;
+  }
+
+  // Request for the metadata values assigned to an element
+  if (request.requestParams == "GetMetadataValues")
+  {
+    text_tarray metadata_element_names;
+    text_t metadata_value_filter = "";
+    text_t metadata_value_grouping_expression = "";
+    OptionValue_tarray::const_iterator options_iterator = request.filterOptions.begin();
+    while (options_iterator != request.filterOptions.end())
+    {
+      if ((*options_iterator).name == "MetadataElements")
+      {
+	splitchar ((*options_iterator).value.begin(), (*options_iterator).value.end(), ',', metadata_element_names);
+      }
+      if ((*options_iterator).name == "MetadataValueFilter")
+      {
+	metadata_value_filter = (*options_iterator).value;
+      }
+      if ((*options_iterator).name == "MetadataValueGroupingExpression")
+      {
+	metadata_value_grouping_expression = (*options_iterator).value;
+      }
+      options_iterator++;
+    }
+
+    text_tarray metadata_values = sql_db_ptr->get_metadata_values (metadata_element_names, metadata_value_filter, metadata_value_grouping_expression);
+
+    // Create a map from metadata value to ResultDocInfo_t, to remove duplicate values and obtain occurrence counts
+    map<text_t, ResultDocInfo_t> unique_metadata_values_map;
+    text_tarray::iterator metadata_value_iterator = metadata_values.begin();
+    while (metadata_value_iterator != metadata_values.end())
+    {
+      text_t metadata_value = *metadata_value_iterator;
+
+      // If no ResultDocInfo_t has already been created for this metadata value, create one now
+      if (unique_metadata_values_map.find(metadata_value) == unique_metadata_values_map.end())
+      {
+	ResultDocInfo_t metadata_value_result_doc;
+	metadata_value_result_doc.OID = metadata_value;
+	metadata_value_result_doc.result_num = 1;
+	unique_metadata_values_map[metadata_value] = metadata_value_result_doc;
+      }
+      // Otherwise we've seen this value before, so just update the occurrence count
+      else
+      {
+	unique_metadata_values_map[metadata_value].result_num++;
+      }
+
+      metadata_value_iterator++;
+    }
+
+    // Fill in response.docInfo with the ResultDocInfo_t objects we've created above
+    map<text_t, ResultDocInfo_t>::iterator unique_metadata_values_iterator = unique_metadata_values_map.begin();
+    while (unique_metadata_values_iterator != unique_metadata_values_map.end())
+    {
+      response.docInfo.push_back ((*unique_metadata_values_iterator).second);
+      unique_metadata_values_iterator++;
+    }
+  }
+
+  // Request for the documents with a certain metadata value assigned
+  else if (request.requestParams == "GetDocumentsWithMetadataValue")
+  {
+    text_tarray metadata_element_names;
+    text_t metadata_value = "";
+    text_t sort_by_metadata_element_name = "";
+    OptionValue_tarray::const_iterator options_iterator = request.filterOptions.begin();
+    while (options_iterator != request.filterOptions.end())
+    {
+      if ((*options_iterator).name == "MetadataElements")
+      {
+	splitchar ((*options_iterator).value.begin(), (*options_iterator).value.end(), ',', metadata_element_names);
+      }
+      if ((*options_iterator).name == "MetadataValue")
+      {
+	metadata_value = (*options_iterator).value;
+      }
+      if ((*options_iterator).name == "SortByMetadataElement")
+      {
+	sort_by_metadata_element_name = (*options_iterator).value;
+      }
+      options_iterator++;
+    }
+
+    text_tarray document_OIDs = sql_db_ptr->get_documents_with_metadata_value (metadata_element_names, metadata_value, sort_by_metadata_element_name);
+
+    // Fill in response.docInfo with the document OIDs
+    text_tarray::iterator document_OID_iterator = document_OIDs.begin();
+    while (document_OID_iterator != document_OIDs.end())
+    {
+      ResultDocInfo_t document_result_doc;
+      document_result_doc.OID = *document_OID_iterator;
+      response.docInfo.push_back (document_result_doc);
+      document_OID_iterator++;
+    }
+  }
+
+  sql_db_ptr->closedatabase();  // Important that local library doesn't leave any files open
+}
Index: /gsdl/stable/runtime-src/src/colservr/sqlbrowsefilter.h
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/sqlbrowsefilter.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/sqlbrowsefilter.h	(revision 20131)
@@ -0,0 +1,63 @@
+/**********************************************************************
+ *
+ * sqlbrowsefilter.h -- 
+ * Copyright (C) 2008  DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef SQLBROWSEFILTER_H
+#define SQLBROWSEFILTER_H
+
+
+#include "filter.h"
+#include "comtypes.h"
+#include "sqldbclass.h"
+#include "text_t.h"
+
+
+class sqlbrowsefilterclass : public filterclass {
+protected:
+  text_t sql_db_filename;
+  text_t indexstem;
+  sqldbclass *sql_db_ptr;
+
+public:
+  sqlbrowsefilterclass ();
+  virtual ~sqlbrowsefilterclass ();
+
+  text_t get_filter_name () { return "SQLBrowseFilter"; }
+
+  // configure should be called once for each configuration line
+  // default configures the default filter options
+  virtual void configure (const text_t &key, const text_tarray &cfgline);
+
+  // the sql db ptr remains the responsibility of the calling code and
+  // should be destroyed after this sqlbrowsefilter is destroyed
+  void set_sql_db_ptr (sqldbclass *sql_db_ptr_arg) { sql_db_ptr = sql_db_ptr_arg; }
+
+  bool init (ostream &logout);
+  void filter (const FilterRequest_t &request,
+	       FilterResponse_t &response,
+	       comerror_t &err, ostream &logout);
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/colservr/win32.mak
===================================================================
--- /gsdl/stable/runtime-src/src/colservr/win32.mak	(revision 20131)
+++ /gsdl/stable/runtime-src/src/colservr/win32.mak	(revision 20131)
@@ -0,0 +1,178 @@
+###########################################################################
+#
+# win32 makefile -- src/colservr
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ..\..\..
+COMMON_DIR = $(GSDL_DIR)\common-src
+RUNTIME_DIR = $(GSDL_DIR)\runtime-src
+
+INDEXERS_DIR = $(COMMON_DIR)\indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)\packages
+PACKAGES_DIR = $(RUNTIME_DIR)\packages
+
+GSDL_VC4 = 0
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+USE_SQLITE = 1
+USE_MSSQL = 0
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+!IF $(DLL)
+CXXFLAGS = $(CXXFLAGS) -MD
+!ELSE
+!IF ($(DLLDEBUG))
+CXXFLAGS = $(CXXFLAGS) -MDd
+!ENDIF
+!ENDIF
+
+!IF $(USE_SQLITE)
+SQLITE_DEFINES = -DUSE_SQLITE
+SQLITE_INCLUDES = -I"$(COMMON_PACKAGES_DIR)\sqlite\include"
+!ELSE
+SQLITE_DEFINES = 
+SQLITE_INCLUDES = 
+!ENDIF
+
+!IF $(USE_MSSQL)
+MSSQL_DEFINES = -DUSE_MSSQL
+!ELSE
+MSSQL_DEFINES = 
+!ENDIF
+
+
+AR = lib
+CC = cl
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H -DPARADOCNUM -D_LITTLE_ENDIAN -DSHORT_SUFFIX -D_CRT_SECURE_NO_DEPRECATE \
+        -DXML_STATIC $(SQLITE_DEFINES) $(MSSQL_DEFINES)
+# Do NOT add the "recpt" directory here: the colserver should be independent of the receptionist!
+INCLUDES = -I"$(GSDL_DIR)" -I"$(COMMON_DIR)\src\lib" \
+	-I"$(INDEXERS_DIR)\mg" -I"$(INDEXERS_DIR)\mg\lib" -I"$(INDEXERS_DIR)\mg\src\text" \
+	-I"$(INDEXERS_DIR)\mgpp\lib" -I"$(INDEXERS_DIR)\mgpp\text" \
+	-I"$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3" -I"$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3\windows" \
+	-I"$(COMMON_PACKAGES_DIR)\windows\expat\expat" $(SQLITE_INCLUDES)
+
+!IF $(GSDL_VC4)
+DEFS=$(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I"$(COMMON_PACKAGES_DIR)\windows\stlport\stlport"
+!ENDIF
+
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+
+
+.SUFFIXES:
+.SUFFIXES: .c .obj
+.c.obj:
+	$(COMPILE) $<
+
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $< 
+
+
+SOURCES = \
+        browsefilter.cpp \
+	collectserver.cpp \
+	collectset.cpp \
+        colservrconfig.cpp \
+	comtypes.cpp \
+	expat_document.cpp \
+	expat_resultset.cpp \
+	filter.cpp \
+	lucenequeryfilter.cpp \
+	lucenesearch.cpp \
+	lucenesource.cpp \
+	maptools.cpp \
+	mgq.c \
+	mgqueryfilter.cpp \
+	mgsearch.cpp \
+	mgsource.cpp \
+	mgppqueryfilter.cpp \
+	mgppsearch.cpp \
+	phrasequeryfilter.cpp \
+	phrasesearch.cpp \
+	querycache.cpp \
+	queryfilter.cpp \
+	queryinfo.cpp \
+	search.cpp \
+	source.cpp \
+	sqlbrowsefilter.cpp
+
+OBJECTS = \
+        browsefilter.obj \
+	collectserver.obj \
+	collectset.obj \
+        colservrconfig.obj \
+	comtypes.obj \
+	expat_document.obj \
+	expat_resultset.obj \
+	filter.obj \
+	lucenequeryfilter.obj \
+	lucenesearch.obj \
+	lucenesource.obj \
+	maptools.obj \
+	mgq.obj \
+	mgqueryfilter.obj \
+	mgsearch.obj \
+	mgsource.obj \
+	mgppqueryfilter.obj \
+	mgppsearch.obj \
+	phrasequeryfilter.obj \
+	phrasesearch.obj \
+	querycache.obj \
+	queryfilter.obj \
+	queryinfo.obj \
+	search.obj \
+	source.obj \
+	sqlbrowsefilter.obj
+
+LIBRARY = gsdlcolservr.lib	
+
+
+# Default target: make gsdlcolservr.lib
+all: $(LIBRARY)
+
+gsdlcolservr.lib: $(OBJECTS) 
+	if EXIST $(LIBRARY) del $(LIBRARY)
+	$(AR) -nologo /out:$(LIBRARY) $(OBJECTS)
+
+install:
+
+clean:
+	del *.obj
+	del $(LIBRARY)
Index: /gsdl/stable/runtime-src/src/corba/Makefile.in
===================================================================
--- /gsdl/stable/runtime-src/src/corba/Makefile.in	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/Makefile.in	(revision 20131)
@@ -0,0 +1,165 @@
+###########################################################################
+#
+# Makefile -- runtime-src/src/corba
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+RUNTIME_DIR = $(GSDL_DIR)/runtime-src
+
+INDEXERS_DIR = $(COMMON_DIR)/indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+RUNTIME_PACKAGES_DIR = $(RUNTIME_DIR)/packages
+COLSERVR_DIR = $(RUNTIME_DIR)/src/colservr
+PROTOCOL_DIR = $(RUNTIME_DIR)/src/protocol
+RECPT_DIR = $(RUNTIME_DIR)/src/recpt
+
+
+ENABLE_ACCENTFOLD = @ENABLE_ACCENTFOLD@
+ifeq ($(ENABLE_ACCENTFOLD), 1)
+ACCENTFOLD_LIBS = $(INDEXERS_DIR)/packages/unac/libunac.a 
+else
+ACCENTFOLD_LIBS = 
+endif
+
+USE_SQLITE = @USE_SQLITE@
+ifeq ($(USE_SQLITE), 1)
+SQLITE_LIBS = $(COMMON_PACKAGES_DIR)/sqlite/lib/libsqlite3.a -ldl -lpthread
+else
+SQLITE_LIBS = 
+endif
+
+MICO_DIR = @MICO_DIR@
+MICO_VER = @MICO_VER@
+ifeq ($(MICO_DIR), default)
+MICO_INCLUDES = -I$(RUNTIME_PACKAGES_DIR)/mico/mico/include
+MICO_PATH = $(RUNTIME_PACKAGES_DIR)/mico/bin/
+else
+ifeq ($(MICO_DIR), yes)
+MICO_INCLUDES =
+else
+MICO_INCLUDES = -I$(MICO_DIR)
+endif
+MICO_PATH =
+endif
+
+USE_CORBA = @USE_CORBA@
+ifeq ($(USE_CORBA), 1)
+AR = ar
+CC = @CC@
+CFLAGS = @CFLAGS@
+DEFS = @DEFS@ -DNZDL -DQUIET -DSHORT_SUFFIX -DPARADOCNUM -DGSDLSERVER
+INCLUDES = -I$(COMMON_DIR)/src/lib -I$(COLSERVR_DIR) -I$(PROTOCOL_DIR) -I$(RECPT_DIR) -I$(INDEXERS_DIR)/mgpp/text \
+	$(MICO_INCLUDES)
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@ $(COMMON_PACKAGES_DIR)/gdbm/lib/libgdbm.a -L$(COMMON_PACKAGES_DIR)/expat/lib -lexpat \
+	$(ACCENTFOLD_LIBS) $(SQLITE_LIBS) -L$(RUNTIME_PACKAGES_DIR)/mico/lib -lmico$(MICO_VER)
+RANLIB = @RANLIB@
+
+
+COMPILE = $(MICO_PATH)mico-c++ -x c++ $(CFLAGS) $(DEFS) $(INCLUDES) -c
+LINK = $(MICO_PATH)mico-ld $(LDFLAGS) -o $@
+
+
+.SUFFIXES: .mpp .o
+.mpp.o:
+	$(COMPILE) $<
+
+
+SOURCES = \
+	corbaconv_text_t.mpp \
+	corbaiface.mpp \
+	corbaiface_skel.mpp \
+	corbaproto.mpp \
+	corbatext_t.mpp
+
+OBJECTS = \
+	corbaconv_text_t.o \
+	corbaiface.o \
+	corbaiface_skel.o \
+	corbaproto.o \
+	corbatext_t.o
+
+CORBASERVER_OBJECTS = \
+	corbaServer.o
+
+CORBARECPT_OBJECTS = \
+	corbaclient.o
+
+GSDL_LIBS = \
+	$(RECPT_DIR)/gsdlrecpt.a \
+	$(PROTOCOL_DIR)/gsdlprotocol.a \
+	$(COLSERVR_DIR)/gsdlcolservr.a \
+	$(INDEXERS_DIR)/mg/src/text/libmgtext.a \
+	$(INDEXERS_DIR)/mg/lib/libmglib.a \
+	$(INDEXERS_DIR)/mgpp/text/libmgpptext.a \
+	$(INDEXERS_DIR)/mgpp/lib/libmgpplib.a \
+	$(COMMON_DIR)/src/lib/gsdllib.a
+
+CORBASERVER_EXECUTABLE_OBJECTS = \
+	$(OBJECTS) \
+	$(CORBASERVER_OBJECTS) \
+	$(GSDL_LIBS)
+
+CORBARECPT_EXECUTABLE_OBJECTS = \
+	$(OBJECTS) \
+	$(CORBARECPT_OBJECTS) \
+	$(GSDL_LIBS)
+
+EXECUTABLES = corbaserver corbarecptldd
+
+
+# Default target: make both corbaserver and corbarecptldd
+all: $(EXECUTABLES)
+
+corbaserver: $(CORBASERVER_EXECUTABLE_OBJECTS)
+	$(LINK) $(CORBASERVER_EXECUTABLE_OBJECTS) $(LIBS)
+
+corbarecptldd: $(CORBARECPT_EXECUTABLE_OBJECTS)
+	$(LINK) $(CORBARECPT_EXECUTABLE_OBJECTS) $(LIBS)
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
+
+install:
+
+clean:
+	rm -f $(OBJECTS) $(CORBASERVER_OBJECTS) $(CORBARECPT_OBJECTS) $(EXECUTABLES)
+
+else
+all:
+depend:
+install:
+clean:
+endif
+
+# Want to do distclean regardless of whether or not been compiled
+# distclean needs to get rid of anything produced by ./configure such
+# as this makefile!
+
+
+distclean: clean
+	rm -f Makefile
+
Index: /gsdl/stable/runtime-src/src/corba/corbaServer.mpp
===================================================================
--- /gsdl/stable/runtime-src/src/corba/corbaServer.mpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/corbaServer.mpp	(revision 20131)
@@ -0,0 +1,491 @@
+// Standard headers
+#include <iostream.h>
+#include <fstream.h>
+
+// protocol headers
+#include "corbaiface.h"
+using namespace gsdlInterface;
+
+#include "corbaconv_text_t.h"
+
+// library headers
+#include "fileutil.h"
+//#include "gsdlhome.h"
+
+// greenstone headers
+#include "comtypes.h"
+#include "recptproto.h"
+#include "nullproto.h"
+
+// local headers
+#include "corbatext_t.h"
+
+void corbatext_setToCorbaArray(text_tset set, corbatext_tset *cset);
+void corbatext_corbaArrayToSet(corbatext_tset cset, text_tset *set);
+void corbatext_mapToCorbaMap(text_tmap map, corbatext_tmap *tm);
+void corbaresponse_resultDocInfoToCorba(ResultDocInfo_tarray docinfo, corbaResultDocInfo_array &corbainfo);
+
+void corbaresponse_termInfoToCorba(TermInfo_tarray terminfo, corbaTermInfo_array &corbainfo) {
+  TermInfo_tarray::iterator here = terminfo.begin();
+  TermInfo_tarray::iterator end  = terminfo.end();
+  unsigned int i;
+	
+  i = 0;
+
+  while (here != end) 
+    {
+      corbainfo.length(i+1);
+      
+      corbainfo[i].frequency = here->freq;
+      corbaconv_text_t::getCorbatext(here->term,corbainfo[i].term);
+      corbatext_arrayToCorbaArray(here->matchTerms, &corbainfo[i].matchTerms);
+
+      i ++;
+      here ++;
+    }
+  cout << "Terminfo " << i << endl;
+}
+
+void corbatext_optionValueArrayToC(corbaOptionValue_array corba, OptionValue_tarray &array)
+{
+  unsigned int i = 0;
+  OptionValue_t option;
+
+  for (i = 0; i < corba.length(); i ++)
+    {
+      corbaconv_text_t::setCorbatext(option.name,corba[i].name);
+      corbaconv_text_t::setCorbatext(option.value,corba[i].value);
+
+      // cout << corbatext_string(corba[i].name) << "?" << option
+
+      array.push_back(option);
+    }
+}
+
+class corbaServer : virtual public corbaiface_skel
+{
+private:
+  text_tarray collections;
+  recptproto *protocol;
+  text_t      gsdlhome;
+
+  void openLogfile(text_t extension, ofstream &out)
+  {
+    char *cfilename;
+    text_t filename;
+
+    filename = filename_cat(gsdlhome, extension);
+    cfilename = filename.getcstr();
+
+    out.open(cfilename);
+    delete cfilename;
+  }
+
+public:
+  corbaServer(recptproto *protocol, text_t home)
+  { 
+    text_t dirname;
+    char * cdirname;
+
+    cout << "CorbaServer: gsdlhome = " << home << endl;
+
+    this->gsdlhome = home;
+    cout << gsdlhome.getcstr() << endl;
+    dirname = filename_cat(gsdlhome, "/collect");
+    cdirname = dirname.getcstr();
+    if (!read_dir (cdirname, collections)) {
+      cout << "Unable to read the gsdl directory; terminating" << endl;
+      exit (1);
+    }
+    delete cdirname;
+
+    cout << "Constructing set list server" << endl;
+    this->protocol = protocol;
+
+  }
+  
+  CORBA::Boolean initialise(corbaComError &err) 
+  {
+      ofstream      logout;
+      int           reply;
+      comerror_t    error = noError;
+
+      this->openLogfile("/etc/corbaout.txt", logout);
+      reply = protocol->init(error, logout);
+      logout.close();
+      return (reply != 0 ? 1 : 0);
+    }
+
+  void configure(const corbatext_t &corbaKey, const corbatext_tarray &corbaCfgline,corbaComError &err)
+    {
+      text_t        key;
+      text_tarray   cfgline;
+      comerror_t    error = noError;
+
+      corbaconv_text_t::setCorbatext(key,corbaKey);
+      corbatext_corbaArrayToArray(corbaCfgline, &cfgline);
+
+
+      // ****
+      cout << "Recieved " << key << " = ";
+      for (int unsigned i=0; i<cfgline.size(); i++)
+	{
+	  cout << cfgline[i] << " ";
+	}
+      cout << endl;
+
+      // DB // ****
+      if (key=="gsdlhome")
+	{  
+	  text_tarray cfgline;
+	  cfgline.push_back (gsdlhome);
+	  cout << "Changing gsdlhome to " << gsdlhome << endl;
+	  protocol->configure(key, cfgline, error);
+	}
+      else if (key=="httpdomain")
+	{
+	  // Only let gsdlhome through !!!! // ****
+	  cout << "Supressing httpdomain" << endl;
+	}
+      else if (key=="httpprefix")
+	{
+	  cout << "Supressing httpprefix" << endl;
+	}
+      else
+	{ 
+	  protocol->configure(key, cfgline,error);
+	}
+    }
+
+  void hasCollection(const corbatext_t &corbaCollect, CORBA::Boolean &has,
+                     corbaComError &error) {
+    // do nowt!
+    corbaconv_text_t *cct;
+    bool    _has;
+    comerror_t err = noError;
+    ofstream logout;
+
+    this->openLogfile("/etc/corbaout.txt", logout);
+
+    cct = new corbaconv_text_t(corbaCollect);
+
+    cout << "Collection: " << cct->getcstr() << endl;
+
+    protocol->has_collection(*cct, _has, err, logout); // 'cct' typecast to text_t
+    if (_has)
+      { 
+	has = 1;
+      }
+    else
+      {
+	has = 0;
+      }
+
+    // cout << "  " << has << endl;
+
+    delete cct;
+
+    error = corbaNoError;
+    logout.close();
+  }
+
+  void ping(const struct corbatext_t &corbaCollect, CORBA::Boolean &wasSuccess, corbaComError &corbaError)
+  { 
+    text_t collection;
+    bool   success;
+    comerror_t error = noError;
+    ofstream logout;
+
+    this->openLogfile("/etc/corbaout.txt", logout);
+
+    corbaconv_text_t::setCorbatext(collection,corbaCollect);
+    protocol->ping(collection, success, error, logout);
+
+    corbaError = (corbaComError) error;
+    wasSuccess = (CORBA::Boolean) success;
+    logout.close();
+  }
+
+  void filter(const struct corbatext_t &corbaCollect,
+	      const struct corbaFilterRequest &corbaRequest,
+	      struct corbaFilterResponse &corbaResponse,
+	      corbaComError &corbaError)
+  {
+    // variables for action
+    FilterRequest_t request;
+    FilterResponse_t response;
+    comerror_t       error = noError;
+    text_t           collection;
+    ofstream         logout;
+
+    this->openLogfile("/etc/corbaout.txt", logout);
+
+    // copy collection id
+    corbaconv_text_t::setCorbatext(collection,corbaCollect);
+
+    // copy request values
+    corbaconv_text_t::setCorbatext(request.filterName,corbaRequest.filter);
+    corbatext_optionValueArrayToC(corbaRequest.filterOptions, request.filterOptions);
+    corbatext_corbaArrayToArray(corbaRequest.docSet, &request.docSet);
+    request.filterResultOptions = corbaRequest.filterResultOptions;
+    corbaconv_text_t::setCorbatext(request.requestParams,corbaRequest.requestParams);
+    corbaconv_text_t::setCorbatext(request.refParams,corbaRequest.refParams);
+    corbatext_corbaArrayToSet(corbaRequest.fields, &request.fields);
+    request.getParents = corbaRequest.getParents;
+
+    protocol->filter(collection, request, response, error, logout);
+
+    // copy response values
+    corbaResponse.numDocs = response.numDocs;
+    corbaResponse.isApprox = (::gsdlInterface::corbaIsApprox) response.isApprox;
+    corbaresponse_termInfoToCorba(response.termInfo, corbaResponse.termInfo);
+    corbaresponse_resultDocInfoToCorba(response.docInfo, corbaResponse.docInfo);
+
+    // tidy up variables
+    logout.close();
+    corbaError = (corbaComError) error;
+    cout << "Filter prepared" << corbaResponse.docInfo.length() << "," << corbaResponse.numDocs << endl;
+  }
+
+  void getCollectInfo(const struct corbatext_t &corbaCollect,
+                      corbaColInfoResponse &corbaResponse,
+                      corbaComError &corbaError)
+  {
+    ColInfoResponse_t response;
+    comerror_t       error = noError;
+    text_t           collection;
+    ofstream logout;
+
+    this->openLogfile("/etc/corbaout.txt", logout);
+
+    corbaconv_text_t::setCorbatext(collection,corbaCollect);
+    protocol->get_collectinfo(collection, response, error, logout);
+
+    cout << "IsPublic  = " << ((response.isPublic)?"True":"False") << endl;
+    cout << "IsBeta    = " << ((response.isBeta)  ?"True":"False") << endl;
+    cout << "BuildDate = " << response.buildDate << endl;
+    cout << "NumDocs   = " << response.numDocs << endl;
+    cout << "NumBytes  = " << response.numBytes << endl;
+    cout << "NumWords  = " << response.numWords << endl;
+    cout << "UseBook   = " << ((response.useBook)  ?"True":"False") << endl;
+    
+    corbaResponse.useBook   = response.useBook;
+    corbaResponse.isPublic  = response.isPublic;
+    corbaResponse.isBeta    = response.isBeta;
+    corbaResponse.buildDate = response.buildDate;
+    corbatext_arrayToCorbaArray(response.languages, &corbaResponse.languages);
+    corbatext_arrayToCorbaArray(response.ccsCols, &corbaResponse.ccsCols);
+    corbaResponse.numDocs   = response.numDocs;
+    corbaResponse.numBytes  = response.numBytes;
+    corbaResponse.numWords  = response.numWords;
+
+    corbatext_mapToCorbaMap(response.collectionmeta, &corbaResponse.collectionMeta);
+    corbatext_mapToCorbaMap(response.format, &corbaResponse.format);
+    corbatext_mapToCorbaMap(response.building, &corbaResponse.building);
+    corbaconv_text_t::getCorbatext(response.httpdomain,corbaResponse.httpdomain);
+
+    corbaconv_text_t::getCorbatext(response.httpprefix,corbaResponse.httpprefix);
+    corbaconv_text_t::getCorbatext(response.receptionist,corbaResponse.receptionist);
+
+    /* text_tmap::iterator f_here = response.format.begin();
+    text_tmap::iterator f_end = response.format.end();
+    while (f_here!=f_end)
+    {
+      cout << "**** format: " << f_here->first << " = " << f_here->second << endl;
+      f_here++;
+    } 
+    */ // ****
+
+    logout.close();
+    corbaError = (corbaComError) error;
+  }
+
+  void getFilterOptions(const struct corbatext_t &corbaCollect,
+			const struct corbatext_t &corbaFilterName,
+			struct corbaFilterOptionsResponse &corbaResponse,
+			enum corbaComError &corbaError)
+  {   
+    text_t collection;
+    InfoFilterOptionsRequest_t request;
+    InfoFilterOptionsResponse_t response;
+    comerror_t error = noError;
+    unsigned int i;
+    ofstream logout;
+
+    this->openLogfile("/etc/corbaout.txt", logout);
+
+    corbaconv_text_t::setCorbatext(collection,corbaCollect);
+    corbaconv_text_t::setCorbatext(request.filterName,corbaFilterName);
+    protocol->get_filteroptions(collection, request, response, error, logout);
+
+    // decode filters back into corba format
+    FilterOption_tmap::iterator here = response.filterOptions.begin();
+    FilterOption_tmap::iterator end = response.filterOptions.end();
+    i = 0;
+    while (here != end)
+      {
+	// set array for name/options to be one bigger
+	corbaResponse.names.length(i+1);
+	corbaResponse.options.length(i+1);
+
+	// get left-hand side of map
+	corbaconv_text_t::getCorbatext((*here).first,corbaResponse.names[i]);
+	
+	// get right-hand side of map
+	corbaconv_text_t::getCorbatext((*here).second.name,corbaResponse.options[i].name);
+	corbaResponse.options[i].type = 
+	  (::gsdlInterface::corbaFilterType)(*here).second.type;
+	corbaResponse.options[i].repeatable = 
+	  (::gsdlInterface::corbaFilterRepeatable)(*here).second.repeatable;
+	corbaconv_text_t::getCorbatext((*here).second.defaultValue,corbaResponse.options[i].defaultValue);
+	corbatext_arrayToCorbaArray((*here).second.validValues, &corbaResponse.options[i].validValues);
+
+	// take next iterators
+	i++;
+	here ++;
+      }
+
+    logout.close();
+    corbaError = (corbaComError) error;
+  }
+
+  void getFilterInfo(const struct corbatext_t &corbaCollect, 
+		     corbatext_tarray &filterNames, 
+		     enum corbaComError &corbaError)
+  { text_tarray ta;
+    comerror_t error = noError;
+    text_t collection;    
+    InfoFiltersResponse_t response;
+    ofstream logout;
+
+    this->openLogfile("/etc/corbaout.txt", logout);
+
+    corbaconv_text_t::setCorbatext(collection,corbaCollect);
+    cout << collection.getcstr() << endl;
+			    
+    protocol->get_filterinfo(collection, response, error, logout);
+    corbatext_setToCorbaArray(response.filterNames, &filterNames);
+
+    corbaError = (corbaComError) error;
+    logout.close();
+  }
+  
+  void getDocument(const struct corbatext_t &corbaCollection, struct corbaDocRequest &corbaRequest, 
+		   struct corbaDocResponse &corbaResponse,  enum corbaComError &corbaError)
+  { DocumentRequest_t request;
+    DocumentResponse_t response;
+    comerror_t         error = noError;
+    text_t             collection;
+    ofstream logout;
+
+    this->openLogfile("/etc/corbaout.txt", logout);
+
+    // set up request
+    corbaconv_text_t::setCorbatext(collection,corbaCollection);
+    corbaconv_text_t::setCorbatext(request.OID,corbaRequest.OID);
+    corbaconv_text_t::setCorbatext(request.docType,corbaRequest.docType);
+    corbaconv_text_t::setCorbatext(request.docFormat,corbaRequest.docFormat);
+
+    // do actual get document
+    protocol->get_document(collection, request, response, error, logout);
+    corbaconv_text_t::getCorbatext(response.doc,corbaResponse.doc);
+
+    // decode response
+    corbaError = (corbaComError) error;
+
+    logout.close();
+  }
+
+  void collectionList(corbatext_tarray &corbalist, corbaComError &error)
+  {
+    /* stringSeq *reply;
+    unsigned int i;
+    char *istring; */
+
+    text_tarray collist;
+    comerror_t  err;
+    ofstream logout;
+
+    cout << "Received collection list request" << endl;
+
+    this->openLogfile("/etc/corbaout.txt", logout);
+
+    protocol->get_collection_list(collist, err, logout);
+
+    /*    reply = new stringSeq(collections.size());
+    
+    (*reply).length(collections.size());
+    for (i = 0; i < collections.size(); i ++)
+      {
+	istring = collections[i].getcstr();
+	(*reply)[i] = CORBA::string_dup(istring);
+	delete istring;
+      }
+    
+    return reply;
+    */
+
+    corbatext_arrayToCorbaArray(collist, &corbalist);
+    cout << "Replying " << collist.size() << ": " << endl;
+
+    for (int unsigned i = 0; i < collist.size(); i ++)
+      {
+	cout << collist[i];
+	if (i<collist.size()-1) cout << ", ";
+      }
+    cout << endl;
+
+    logout.close();
+    // CORBA::string_dup(_listString);
+  }
+};
+
+int main (int argc, char *argv[])
+{
+  nullproto protocol;
+  collectset *cservers;
+  text_t     gsdlhome;
+
+  cservers = new collectset(gsdlhome);
+  protocol.set_collectset(cservers);
+
+  cout << "Started Corba ..." << endl;
+
+  // ORB initialization
+  CORBA::ORB_var orb = CORBA::ORB_init( argc, argv, "mico-local-orb" );
+  CORBA::BOA_var boa = orb->BOA_init( argc, argv, "mico-local-boa" );
+
+  cout << "Initialised ORB and BOA" << endl;
+
+  corbaServer* server = new corbaServer(&protocol, gsdlhome);
+
+  cout << "Initialised server" << endl;
+
+  CORBA::String_var ref = orb->object_to_string( server );
+
+  cout << "Mapped Corba object to string" << endl;
+
+  // write id to "naming service"
+  ofstream out ("/tmp/localcorba.objid");
+	if (out.is_open()) {
+		out << ref << endl;
+		if (out.fail() || out.bad()) {
+			cout << "Failed " << endl;
+		}
+		out.close ();
+	}
+	else {
+		cout << "Unable to write string to file /tmp/localcorba.objid" << endl;
+		cout << "Please check the file permissions/ownership" << endl;
+		return 0;
+	}
+  cout << "Corba string is " << ref << endl;
+
+  // indicate readiness and run
+  boa->impl_is_ready( CORBA::ImplementationDef::_nil() );
+  orb->run ();
+  CORBA::release( server );
+  return 0;
+}
+
+
Index: /gsdl/stable/runtime-src/src/corba/corbaclient.mpp
===================================================================
--- /gsdl/stable/runtime-src/src/corba/corbaclient.mpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/corbaclient.mpp	(revision 20131)
@@ -0,0 +1,161 @@
+/**********************************************************************
+ *
+ * corbaclient.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+#include "receptionist.h"
+#include "cgiwrapper.h"
+#include "corbaproto.h"
+#include "collectserver.h"
+#include "filter.h"
+#include "browsefilter.h"
+#include "queryfilter.h"
+#include "mgsearch.h"
+#include "fileutil.h"
+#include <assert.h>
+
+#include "action.h"
+#include "statusaction.h"
+#include "pageaction.h"
+#include "pingaction.h"
+#include "queryaction.h"
+#include "documentaction.h"
+#include "authenaction.h"
+#include "usersaction.h"
+#include "authenaction.h"
+#include "extlinkaction.h"
+#include "tipaction.h"
+#include "collectoraction.h"
+
+#include "browserclass.h"
+#include "vlistbrowserclass.h"
+#include "hlistbrowserclass.h"
+#include "datelistbrowserclass.h"
+#include "invbrowserclass.h"
+#include "pagedbrowserclass.h"
+#include "htmlbrowserclass.h"
+
+// #include "gsdlhome.h"
+#include "gsdlsitecfg.h"
+
+int main (int argc, char *argv[]) {
+  receptionist recpt;
+  corbaproto*  cproto_array[argc];
+  text_t       gsdlhome;
+  text_t       collecthome;
+  text_t       httpdomain;
+  text_t       httpprefix;
+  
+  cproto_array[0] = NULL; // unused
+
+  if (argc == 1)
+  { cout << "Content-type: text/html" << endl << endl;
+    cout << "Usage: " << argv[0] << "site1.objid [site2.objid ....]" << endl;
+    return 0;
+  }
+
+  // Strictly speaking httpdomain and httpprefix are not needed.
+  // Need to modifiy site_cfg_read to eliminate this dependency. // ****
+  site_cfg_read(gsdlhome, collecthome, httpdomain, httpprefix);
+
+  for (int i=1; i<argc; i ++)
+    {
+      // add the protocol to the receptionist
+      cproto_array[i] = new corbaproto(argv[i]);
+      recpt.add_protocol(cproto_array[i]);
+    }
+
+//  cout << "GRB 2" << endl;
+
+  // the list of actions. Note: these actions will become invalid
+  // at the end of this function.
+  tipaction atipaction;
+  recpt.add_action(&atipaction);
+
+  statusaction astatusaction;
+  astatusaction.set_receptionist (&recpt);
+  recpt.add_action (&astatusaction);
+
+  pageaction apageaction;
+  apageaction.set_receptionist (&recpt);
+  recpt.add_action (&apageaction);
+
+  pingaction apingaction;
+  recpt.add_action (&apingaction);
+
+  queryaction aqueryaction;
+  aqueryaction.set_receptionist (&recpt);
+  recpt.add_action (&aqueryaction);
+
+  documentaction adocumentaction;
+  adocumentaction.set_receptionist (&recpt);
+  recpt.add_action (&adocumentaction);
+
+  usersaction ausersaction;
+  recpt.add_action (&ausersaction);
+
+  extlinkaction anextlinkaction;
+  recpt.add_action (&anextlinkaction);
+
+  authenaction aauthenaction;
+  aauthenaction.set_receptionist(&recpt);
+  recpt.add_action (&aauthenaction);
+
+  collectoraction acollectoraction;
+  acollectoraction.set_receptionist (&recpt);
+  recpt.add_action(&acollectoraction);
+
+//  cout << "GRB 3" << endl;
+
+  // list of browsers
+  vlistbrowserclass avlistbrowserclass;
+  recpt.add_browser (&avlistbrowserclass);
+  recpt.setdefaultbrowser ("VList");
+
+  hlistbrowserclass ahlistbrowserclass;
+  recpt.add_browser (&ahlistbrowserclass);
+
+  datelistbrowserclass adatelistbrowserclass;
+  recpt.add_browser (&adatelistbrowserclass);
+
+  invbrowserclass ainvbrowserclass;
+  recpt.add_browser (&ainvbrowserclass);
+
+  pagedbrowserclass apagedbrowserclass;
+  recpt.add_browser (&apagedbrowserclass);
+
+  htmlbrowserclass ahtmlbrowserclass;
+  recpt.add_browser (&ahtmlbrowserclass);
+
+  cgiwrapper (recpt, "");
+
+  for (int i=1; i< argc; i++)
+    {
+      delete cproto_array[i];
+    }
+
+  return 0;
+}
+
Index: /gsdl/stable/runtime-src/src/corba/corbaconv_text_t.h
===================================================================
--- /gsdl/stable/runtime-src/src/corba/corbaconv_text_t.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/corbaconv_text_t.h	(revision 20131)
@@ -0,0 +1,68 @@
+/**********************************************************************
+ *
+ * corbaconv_text_t.mpp -- conversion support text_t <-> corba_text_t
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+
+#ifndef CORBACONV_TEXT_T_H
+#define CORBACONV_TEXT_T_H
+
+#include "text_t.h"
+
+// Inherit from text_t
+// Provide support to convert from corba_text_t to text_t and vice versa
+
+class corbaconv_text_t : public text_t {
+  
+public:
+  // constructors
+  corbaconv_text_t (corbatext_t t);
+
+  void setCorbatext(corbatext_t ct);
+  void getCorbatext(corbatext_t &ct) const;
+  void fillUsString(usString *us) const;
+
+  static void setCorbatext(text_t& t, corbatext_t ct);
+  static void getCorbatext(const text_t& t, corbatext_t &ct);
+  static void fillUsString(const text_t& t, usString *us);
+};
+
+
+inline void corbaconv_text_t::setCorbatext(corbatext_t ct) 
+{ 
+  setCorbatext(*this,ct); 
+}
+
+inline void corbaconv_text_t::getCorbatext(corbatext_t& ct) const
+{ 
+  getCorbatext(*this,ct); 
+}
+
+inline void corbaconv_text_t::fillUsString(usString *us) const
+{
+  fillUsString(*this,us);
+}
+
+#endif
Index: /gsdl/stable/runtime-src/src/corba/corbaconv_text_t.mpp
===================================================================
--- /gsdl/stable/runtime-src/src/corba/corbaconv_text_t.mpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/corbaconv_text_t.mpp	(revision 20131)
@@ -0,0 +1,109 @@
+/**********************************************************************
+ *
+ * corbaconv_text_t.mpp -- conversion support text_t <-> corba_text_t
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+#if defined(GSDL_USE_STL_H) || defined(__APPLE__)
+#include <vector.h>
+#else
+#include <vector>
+#endif
+
+// protocol header
+#include "corbaiface.h"
+using namespace gsdlInterface;
+
+#include "corbatext_t.h"
+
+#include "corbaconv_text_t.h"
+
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\algorithm>
+#elif defined(GSDL_USE_STL_H)
+#  if defined(GSDL_USE_ALGO_H)
+#    include <algo.h>
+#  else
+#    include <algorithm.h>
+#  endif
+#else
+#  include <algorithm>
+#endif
+
+#ifdef HAVE_CONFIG_H
+# ifdef __WIN32__
+#  include "win32cfg.h"
+# else
+#  include "mico/config.h"
+# endif
+#endif
+
+
+// #include "unitool.h" // ****
+
+////////////////////////////////////
+// corbaconv_text_t methods
+////////////////////////////////////
+
+corbaconv_text_t::corbaconv_text_t (corbatext_t t)
+{ 
+  setCorbatext(t);  
+}
+
+void corbaconv_text_t::getCorbatext(const text_t& t, corbatext_t &ct)
+{
+  ct.encoding = 0;
+  fillUsString(t,&ct.text);
+}
+
+void corbaconv_text_t::setCorbatext(text_t& t, corbatext_t ct)
+{
+  t.setencoding(0);
+  t.clear();
+  corbatext_usvector(ct, t.text_as_usvector());
+}
+
+void corbaconv_text_t::fillUsString(const text_t& t, usString *us)
+{
+  unsigned int i;
+  usvector::const_iterator here = t.text_as_usvector().begin();
+  usvector::const_iterator end = t.text_as_usvector().end();
+
+
+  if (end == here)
+    { 	
+      return;
+    }
+  (*us).length(end - here);
+  i = 0;
+
+  while (here != end)
+    {
+      (*us)[i] = *here;
+      i ++;
+      here ++;
+    }
+  
+}
Index: /gsdl/stable/runtime-src/src/corba/corbaiface.h
===================================================================
--- /gsdl/stable/runtime-src/src/corba/corbaiface.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/corbaiface.h	(revision 20131)
@@ -0,0 +1,614 @@
+/*
+ *  MICO --- a free CORBA implementation
+ *  Copyright (C) 1997-98 Kay Roemer & Arno Puder
+ *
+ *  This file was automatically generated. DO NOT EDIT!
+ */
+
+#if !defined(__CORBAIFACE_H__) || defined(MICO_NO_TOPLEVEL_MODULES)
+#define __CORBAIFACE_H__
+
+#ifndef MICO_NO_TOPLEVEL_MODULES
+#include <CORBA.h>
+#include <mico/throw.h>
+#endif
+
+#ifndef MICO_NO_TOPLEVEL_MODULES
+MICO_NAMESPACE_DECL gsdlInterface {
+#endif
+
+#if !defined(MICO_NO_TOPLEVEL_MODULES) || defined(MICO_MODULE_gsdlInterface)
+
+
+typedef SequenceTmpl<CORBA::UShort,MICO_TID_DEF> usString;
+#ifdef _WINDOWS
+static usString _dummy_usString;
+#endif
+typedef TSeqVar<SequenceTmpl<CORBA::UShort,MICO_TID_DEF> > usString_var;
+typedef TSeqOut<SequenceTmpl<CORBA::UShort,MICO_TID_DEF> > usString_out;
+
+typedef StringSequenceTmpl<CORBA::String_var> stringSeq;
+#ifdef _WINDOWS
+static stringSeq _dummy_stringSeq;
+#endif
+typedef TSeqVar<StringSequenceTmpl<CORBA::String_var> > stringSeq_var;
+typedef TSeqOut<StringSequenceTmpl<CORBA::String_var> > stringSeq_out;
+
+struct corbatext_t;
+typedef TVarVar<corbatext_t> corbatext_t_var;
+typedef TVarOut<corbatext_t> corbatext_t_out;
+
+struct corbatext_t {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbatext_t_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbatext_t();
+  ~corbatext_t();
+  corbatext_t( const corbatext_t& s );
+  corbatext_t& operator=( const corbatext_t& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  usString text;
+  CORBA::UShort encoding;
+  CORBA::ULong length;
+};
+
+typedef SequenceTmpl<corbatext_t,MICO_TID_DEF> corbatext_tarray;
+#ifdef _WINDOWS
+static corbatext_tarray _dummy_corbatext_tarray;
+#endif
+typedef TSeqVar<SequenceTmpl<corbatext_t,MICO_TID_DEF> > corbatext_tarray_var;
+typedef TSeqOut<SequenceTmpl<corbatext_t,MICO_TID_DEF> > corbatext_tarray_out;
+
+typedef corbatext_tarray corbatext_tset;
+#ifdef _WINDOWS
+static corbatext_tset _dummy_corbatext_tset;
+#endif
+typedef TSeqVar<corbatext_tarray > corbatext_tset_var;
+typedef TSeqOut<corbatext_tarray > corbatext_tset_out;
+
+struct corbatext_tmap;
+typedef TVarVar<corbatext_tmap> corbatext_tmap_var;
+typedef TVarOut<corbatext_tmap> corbatext_tmap_out;
+
+struct corbatext_tmap {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbatext_tmap_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbatext_tmap();
+  ~corbatext_tmap();
+  corbatext_tmap( const corbatext_tmap& s );
+  corbatext_tmap& operator=( const corbatext_tmap& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbatext_tarray names;
+  corbatext_tarray values;
+};
+
+enum corbaComError {
+  corbaNoError = 0,
+  corbaAuthenticationFailure,
+  corbaProtocolError,
+  corbaConfigurationError,
+  corbaSystemProblem
+};
+
+typedef corbaComError& corbaComError_out;
+
+struct corbaShortColInfo;
+typedef TVarVar<corbaShortColInfo> corbaShortColInfo_var;
+typedef TVarOut<corbaShortColInfo> corbaShortColInfo_out;
+
+struct corbaShortColInfo {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaShortColInfo_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaShortColInfo();
+  ~corbaShortColInfo();
+  corbaShortColInfo( const corbaShortColInfo& s );
+  corbaShortColInfo& operator=( const corbaShortColInfo& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbatext_t name;
+  corbatext_t host;
+  CORBA::Long response;
+};
+
+struct corbaColInfoResponse;
+typedef TVarVar<corbaColInfoResponse> corbaColInfoResponse_var;
+typedef TVarOut<corbaColInfoResponse> corbaColInfoResponse_out;
+
+struct corbaColInfoResponse {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaColInfoResponse_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaColInfoResponse();
+  ~corbaColInfoResponse();
+  corbaColInfoResponse( const corbaColInfoResponse& s );
+  corbaColInfoResponse& operator=( const corbaColInfoResponse& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbaShortColInfo shoftInfo;
+  CORBA::Boolean useBook;
+  CORBA::Boolean isPublic;
+  CORBA::Boolean isBeta;
+  CORBA::ULong buildDate;
+  corbatext_tarray ccsCols;
+  corbatext_tarray languages;
+  CORBA::ULong numDocs;
+  CORBA::ULong numWords;
+  CORBA::ULong numBytes;
+  corbatext_tmap collectionMeta;
+  corbatext_tmap format;
+  corbatext_tmap building;
+  corbatext_t httpdomain;
+  corbatext_t httpprefix;
+  corbatext_t receptionist;
+};
+
+struct corbaDocRequest;
+typedef TVarVar<corbaDocRequest> corbaDocRequest_var;
+typedef TVarOut<corbaDocRequest> corbaDocRequest_out;
+
+struct corbaDocRequest {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaDocRequest_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaDocRequest();
+  ~corbaDocRequest();
+  corbaDocRequest( const corbaDocRequest& s );
+  corbaDocRequest& operator=( const corbaDocRequest& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbatext_t OID;
+  corbatext_t docType;
+  corbatext_t docFormat;
+};
+
+struct corbaDocResponse;
+typedef TVarVar<corbaDocResponse> corbaDocResponse_var;
+typedef TVarOut<corbaDocResponse> corbaDocResponse_out;
+
+struct corbaDocResponse {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaDocResponse_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaDocResponse();
+  ~corbaDocResponse();
+  corbaDocResponse( const corbaDocResponse& s );
+  corbaDocResponse& operator=( const corbaDocResponse& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbatext_t doc;
+};
+
+enum corbaFilterType {
+  booleanType = 0,
+  integerType,
+  enumeratedType,
+  stringType
+};
+
+typedef corbaFilterType& corbaFilterType_out;
+
+enum corbaFilterRepeatable {
+  onePerQuery = 0,
+  onePerTerm,
+  nPerTerm
+};
+
+typedef corbaFilterRepeatable& corbaFilterRepeatable_out;
+
+struct corbaFilterOption;
+typedef TVarVar<corbaFilterOption> corbaFilterOption_var;
+typedef TVarOut<corbaFilterOption> corbaFilterOption_out;
+
+struct corbaFilterOption {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaFilterOption_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaFilterOption();
+  ~corbaFilterOption();
+  corbaFilterOption( const corbaFilterOption& s );
+  corbaFilterOption& operator=( const corbaFilterOption& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbatext_t name;
+  corbaFilterType type;
+  corbaFilterRepeatable repeatable;
+  corbatext_t defaultValue;
+  corbatext_tarray validValues;
+};
+
+typedef SequenceTmpl<corbaFilterOption,MICO_TID_DEF> corbaFilterOptionList;
+#ifdef _WINDOWS
+static corbaFilterOptionList _dummy_corbaFilterOptionList;
+#endif
+typedef TSeqVar<SequenceTmpl<corbaFilterOption,MICO_TID_DEF> > corbaFilterOptionList_var;
+typedef TSeqOut<SequenceTmpl<corbaFilterOption,MICO_TID_DEF> > corbaFilterOptionList_out;
+
+struct corbaFilterOptionsResponse;
+typedef TVarVar<corbaFilterOptionsResponse> corbaFilterOptionsResponse_var;
+typedef TVarOut<corbaFilterOptionsResponse> corbaFilterOptionsResponse_out;
+
+struct corbaFilterOptionsResponse {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaFilterOptionsResponse_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaFilterOptionsResponse();
+  ~corbaFilterOptionsResponse();
+  corbaFilterOptionsResponse( const corbaFilterOptionsResponse& s );
+  corbaFilterOptionsResponse& operator=( const corbaFilterOptionsResponse& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbaFilterOptionList options;
+  corbatext_tarray names;
+};
+
+struct corbaOptionValue;
+typedef TVarVar<corbaOptionValue> corbaOptionValue_var;
+typedef TVarOut<corbaOptionValue> corbaOptionValue_out;
+
+struct corbaOptionValue {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaOptionValue_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaOptionValue();
+  ~corbaOptionValue();
+  corbaOptionValue( const corbaOptionValue& s );
+  corbaOptionValue& operator=( const corbaOptionValue& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbatext_t name;
+  corbatext_t value;
+};
+
+typedef SequenceTmpl<corbaOptionValue,MICO_TID_DEF> corbaOptionValue_array;
+#ifdef _WINDOWS
+static corbaOptionValue_array _dummy_corbaOptionValue_array;
+#endif
+typedef TSeqVar<SequenceTmpl<corbaOptionValue,MICO_TID_DEF> > corbaOptionValue_array_var;
+typedef TSeqOut<SequenceTmpl<corbaOptionValue,MICO_TID_DEF> > corbaOptionValue_array_out;
+
+struct corbaFilterRequest;
+typedef TVarVar<corbaFilterRequest> corbaFilterRequest_var;
+typedef TVarOut<corbaFilterRequest> corbaFilterRequest_out;
+
+struct corbaFilterRequest {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaFilterRequest_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaFilterRequest();
+  ~corbaFilterRequest();
+  corbaFilterRequest( const corbaFilterRequest& s );
+  corbaFilterRequest& operator=( const corbaFilterRequest& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbatext_t filter;
+  corbaOptionValue_array filterOptions;
+  corbatext_tarray docSet;
+  CORBA::Long filterResultOptions;
+  corbatext_t requestParams;
+  corbatext_t refParams;
+  corbatext_tset fields;
+  CORBA::Boolean getParents;
+};
+
+struct corbaTermInfo;
+typedef TVarVar<corbaTermInfo> corbaTermInfo_var;
+typedef TVarOut<corbaTermInfo> corbaTermInfo_out;
+
+struct corbaTermInfo {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaTermInfo_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaTermInfo();
+  ~corbaTermInfo();
+  corbaTermInfo( const corbaTermInfo& s );
+  corbaTermInfo& operator=( const corbaTermInfo& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbatext_t term;
+  CORBA::Long frequency;
+  corbatext_tarray matchTerms;
+};
+
+typedef SequenceTmpl<corbaTermInfo,MICO_TID_DEF> corbaTermInfo_array;
+#ifdef _WINDOWS
+static corbaTermInfo_array _dummy_corbaTermInfo_array;
+#endif
+typedef TSeqVar<SequenceTmpl<corbaTermInfo,MICO_TID_DEF> > corbaTermInfo_array_var;
+typedef TSeqOut<SequenceTmpl<corbaTermInfo,MICO_TID_DEF> > corbaTermInfo_array_out;
+
+struct corbaMetadataInfo;
+typedef TVarVar<corbaMetadataInfo> corbaMetadataInfo_var;
+typedef TVarOut<corbaMetadataInfo> corbaMetadataInfo_out;
+
+struct corbaMetadataInfo {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaMetadataInfo_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaMetadataInfo();
+  ~corbaMetadataInfo();
+  corbaMetadataInfo( const corbaMetadataInfo& s );
+  corbaMetadataInfo& operator=( const corbaMetadataInfo& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbatext_t params;
+  CORBA::Boolean isRef;
+  corbatext_tarray values;
+  CORBA::Long id;
+  CORBA::Long parentid;
+};
+
+typedef SequenceTmpl<corbaMetadataInfo,MICO_TID_DEF> corbaMetadataInfo_array;
+#ifdef _WINDOWS
+static corbaMetadataInfo_array _dummy_corbaMetadataInfo_array;
+#endif
+typedef TSeqVar<SequenceTmpl<corbaMetadataInfo,MICO_TID_DEF> > corbaMetadataInfo_array_var;
+typedef TSeqOut<SequenceTmpl<corbaMetadataInfo,MICO_TID_DEF> > corbaMetadataInfo_array_out;
+
+struct corbaMetadataInfo_map;
+typedef TVarVar<corbaMetadataInfo_map> corbaMetadataInfo_map_var;
+typedef TVarOut<corbaMetadataInfo_map> corbaMetadataInfo_map_out;
+
+struct corbaMetadataInfo_map {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaMetadataInfo_map_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaMetadataInfo_map();
+  ~corbaMetadataInfo_map();
+  corbaMetadataInfo_map( const corbaMetadataInfo_map& s );
+  corbaMetadataInfo_map& operator=( const corbaMetadataInfo_map& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbatext_tarray names;
+  corbaMetadataInfo_array values;
+};
+
+typedef SequenceTmpl<CORBA::Long,MICO_TID_DEF> corbaDocFreq_array;
+#ifdef _WINDOWS
+static corbaDocFreq_array _dummy_corbaDocFreq_array;
+#endif
+typedef TSeqVar<SequenceTmpl<CORBA::Long,MICO_TID_DEF> > corbaDocFreq_array_var;
+typedef TSeqOut<SequenceTmpl<CORBA::Long,MICO_TID_DEF> > corbaDocFreq_array_out;
+
+struct corbaResultDocInfo;
+typedef TVarVar<corbaResultDocInfo> corbaResultDocInfo_var;
+typedef TVarOut<corbaResultDocInfo> corbaResultDocInfo_out;
+
+struct corbaResultDocInfo {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaResultDocInfo_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaResultDocInfo();
+  ~corbaResultDocInfo();
+  corbaResultDocInfo( const corbaResultDocInfo& s );
+  corbaResultDocInfo& operator=( const corbaResultDocInfo& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  corbatext_t OID;
+  CORBA::Long resultNum;
+  CORBA::Long ranking;
+  CORBA::Long termsMatched;
+  CORBA::Long phraseMatched;
+  corbaDocFreq_array docFreq;
+  corbaMetadataInfo_map metadata;
+  corbatext_t classifierMetadataType;
+  CORBA::Long classifierMetadataOffset;
+  corbaMetadataInfo_array metaparents;
+};
+
+typedef SequenceTmpl<corbaResultDocInfo,MICO_TID_DEF> corbaResultDocInfo_array;
+#ifdef _WINDOWS
+static corbaResultDocInfo_array _dummy_corbaResultDocInfo_array;
+#endif
+typedef TSeqVar<SequenceTmpl<corbaResultDocInfo,MICO_TID_DEF> > corbaResultDocInfo_array_var;
+typedef TSeqOut<SequenceTmpl<corbaResultDocInfo,MICO_TID_DEF> > corbaResultDocInfo_array_out;
+
+enum corbaIsApprox {
+  resultExact = 0,
+  resultApprox,
+  resultMany
+};
+
+typedef corbaIsApprox& corbaIsApprox_out;
+
+struct corbaFilterResponse;
+typedef TVarVar<corbaFilterResponse> corbaFilterResponse_var;
+typedef TVarOut<corbaFilterResponse> corbaFilterResponse_out;
+
+struct corbaFilterResponse {
+  #ifdef HAVE_TYPEDEF_OVERLOAD
+  typedef corbaFilterResponse_var _var_type;
+  #endif
+  #ifdef HAVE_EXPLICIT_STRUCT_OPS
+  corbaFilterResponse();
+  ~corbaFilterResponse();
+  corbaFilterResponse( const corbaFilterResponse& s );
+  corbaFilterResponse& operator=( const corbaFilterResponse& s );
+  #endif //HAVE_EXPLICIT_STRUCT_OPS
+
+  CORBA::Long numDocs;
+  corbaIsApprox isApprox;
+  corbaTermInfo_array termInfo;
+  corbaResultDocInfo_array docInfo;
+};
+
+class corbaiface;
+typedef corbaiface *corbaiface_ptr;
+typedef corbaiface_ptr corbaifaceRef;
+typedef ObjVar<corbaiface> corbaiface_var;
+typedef ObjOut<corbaiface> corbaiface_out;
+
+
+// Common definitions for interface corbaiface
+class corbaiface : 
+  virtual public CORBA::Object
+{
+  public:
+    virtual ~corbaiface();
+
+    #ifdef HAVE_TYPEDEF_OVERLOAD
+    typedef corbaiface_ptr _ptr_type;
+    typedef corbaiface_var _var_type;
+    #endif
+
+    static corbaiface_ptr _narrow( CORBA::Object_ptr obj );
+    static corbaiface_ptr _narrow( CORBA::AbstractBase_ptr obj );
+    static corbaiface_ptr _duplicate( corbaiface_ptr _obj )
+    {
+      CORBA::Object::_duplicate (_obj);
+      return _obj;
+    }
+
+    static corbaiface_ptr _nil()
+    {
+      return 0;
+    }
+
+    virtual void *_narrow_helper( const char *repoid );
+    static vector<CORBA::Narrow_proto> *_narrow_helpers;
+    static bool _narrow_helper2( CORBA::Object_ptr obj );
+
+    virtual CORBA::Boolean initialise( corbaComError& error ) = 0;
+    virtual void configure( const corbatext_t& key, const corbatext_tarray& cfgline, corbaComError& error ) = 0;
+    virtual void collectionList( corbatext_tarray& collist, corbaComError& error ) = 0;
+    virtual void hasCollection( const corbatext_t& corbaCollection, CORBA::Boolean& has, corbaComError& error ) = 0;
+    virtual void ping( const corbatext_t& collection, CORBA::Boolean& wasSuccess, corbaComError& error ) = 0;
+    virtual void getDocument( const corbatext_t& collection, corbaDocRequest& request, corbaDocResponse& response, corbaComError& error ) = 0;
+    virtual void getCollectInfo( const corbatext_t& collection, corbaColInfoResponse& response, corbaComError& error ) = 0;
+    virtual void getFilterInfo( const corbatext_t& collection, corbatext_tarray& filterNames, corbaComError& error ) = 0;
+    virtual void getFilterOptions( const corbatext_t& collection, const corbatext_t& option, corbaFilterOptionsResponse& response, corbaComError& error ) = 0;
+    virtual void filter( const corbatext_t& collection, const corbaFilterRequest& request, corbaFilterResponse& response, corbaComError& error ) = 0;
+
+  protected:
+    corbaiface() {};
+  private:
+    corbaiface( const corbaiface& );
+    void operator=( const corbaiface& );
+};
+
+// Stub for interface corbaiface
+class corbaiface_stub:
+  virtual public corbaiface
+{
+  public:
+    virtual ~corbaiface_stub();
+    CORBA::Boolean initialise( corbaComError& error );
+    void configure( const corbatext_t& key, const corbatext_tarray& cfgline, corbaComError& error );
+    void collectionList( corbatext_tarray& collist, corbaComError& error );
+    void hasCollection( const corbatext_t& corbaCollection, CORBA::Boolean& has, corbaComError& error );
+    void ping( const corbatext_t& collection, CORBA::Boolean& wasSuccess, corbaComError& error );
+    void getDocument( const corbatext_t& collection, corbaDocRequest& request, corbaDocResponse& response, corbaComError& error );
+    void getCollectInfo( const corbatext_t& collection, corbaColInfoResponse& response, corbaComError& error );
+    void getFilterInfo( const corbatext_t& collection, corbatext_tarray& filterNames, corbaComError& error );
+    void getFilterOptions( const corbatext_t& collection, const corbatext_t& option, corbaFilterOptionsResponse& response, corbaComError& error );
+    void filter( const corbatext_t& collection, const corbaFilterRequest& request, corbaFilterResponse& response, corbaComError& error );
+
+  private:
+    void operator=( const corbaiface_stub& );
+};
+
+class corbaiface_skel :
+  virtual public StaticMethodDispatcher,
+  virtual public corbaiface
+{
+  public:
+    corbaiface_skel( const CORBA::BOA::ReferenceData & = CORBA::BOA::ReferenceData() );
+    virtual ~corbaiface_skel();
+    corbaiface_skel( CORBA::Object_ptr obj );
+    virtual bool dispatch( CORBA::StaticServerRequest_ptr _req, CORBA::Environment &_env );
+    corbaiface_ptr _this();
+
+};
+
+#endif // !defined(MICO_NO_TOPLEVEL_MODULES) || defined(MICO_MODULE_gsdlInterface)
+
+#ifndef MICO_NO_TOPLEVEL_MODULES
+
+} MICO_NAMESPACE_END_DECL
+#endif
+
+
+
+#ifndef MICO_CONF_NO_POA
+
+#endif // MICO_CONF_NO_POA
+
+#if !defined(MICO_NO_TOPLEVEL_MODULES) || defined(MICO_MODULE__GLOBAL)
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbatext_t;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbatext_tmap;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaComError;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaShortColInfo;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaColInfoResponse;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaDocRequest;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaDocResponse;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaFilterType;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaFilterRepeatable;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaFilterOption;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaFilterOptionsResponse;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaOptionValue;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaFilterRequest;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaTermInfo;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaMetadataInfo;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaMetadataInfo_map;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaResultDocInfo;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaIsApprox;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaFilterResponse;
+
+extern CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaiface;
+
+extern CORBA::StaticTypeInfo *_marshaller__seq_gsdlInterface_corbatext_t;
+
+extern CORBA::StaticTypeInfo *_marshaller__seq_gsdlInterface_corbaFilterOption;
+
+extern CORBA::StaticTypeInfo *_marshaller__seq_gsdlInterface_corbaOptionValue;
+
+extern CORBA::StaticTypeInfo *_marshaller__seq_gsdlInterface_corbaTermInfo;
+
+extern CORBA::StaticTypeInfo *_marshaller__seq_gsdlInterface_corbaMetadataInfo;
+
+extern CORBA::StaticTypeInfo *_marshaller__seq_gsdlInterface_corbaResultDocInfo;
+
+#endif // !defined(MICO_NO_TOPLEVEL_MODULES) || defined(MICO_MODULE__GLOBAL)
+
+
+#if !defined(MICO_NO_TOPLEVEL_MODULES) && !defined(MICO_IN_GENERATED_CODE)
+#include <mico/template_impl.h>
+#endif
+
+#endif
Index: /gsdl/stable/runtime-src/src/corba/corbaiface.idl
===================================================================
--- /gsdl/stable/runtime-src/src/corba/corbaiface.idl	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/corbaiface.idl	(revision 20131)
@@ -0,0 +1,231 @@
+// basic elements for text
+
+module gsdlInterface {
+
+typedef sequence<unsigned short> usString;
+
+typedef sequence<string> stringSeq;
+
+struct corbatext_t
+{ 
+  usString text;
+  unsigned short encoding;
+  unsigned long  length;
+};
+
+typedef sequence<corbatext_t> corbatext_tarray;
+
+typedef corbatext_tarray corbatext_tset;
+
+struct corbatext_tmap
+{
+  corbatext_tarray names;
+  corbatext_tarray values;
+};
+
+// standard error values
+
+enum corbaComError
+{ corbaNoError, 
+  corbaAuthenticationFailure, 
+  corbaProtocolError, 
+  corbaConfigurationError, 
+  corbaSystemProblem
+};
+
+//
+// getColInfo response
+//
+
+struct corbaShortColInfo
+{
+  corbatext_t name;
+  corbatext_t host;
+  long        response;
+};
+
+struct corbaColInfoResponse
+{
+  boolean       useBook;
+  corbaShortColInfo shoftInfo;
+  boolean           isPublic;
+  boolean           isBeta;
+  unsigned long     buildDate;
+  corbatext_tarray  ccsCols;        // Added 05/04/2000
+  corbatext_tarray  languages;
+  unsigned long     numDocs;
+  unsigned long     numWords;
+  unsigned long     numBytes;
+  corbatext_tmap    collectionMeta;
+  corbatext_tmap    format;
+  corbatext_tmap    building;
+  corbatext_t       httpdomain ;    // Added 27/07/2000
+  corbatext_t       httpprefix;     // Added 27/07/2000
+  corbatext_t       receptionist;
+};
+
+//
+// getDocument request
+//
+
+struct corbaDocRequest
+{ 
+  corbatext_t OID;
+  corbatext_t docType;
+  corbatext_t docFormat;
+};
+
+//
+// getDocument response
+//
+
+struct corbaDocResponse
+{ 
+  corbatext_t doc;
+};
+
+enum corbaFilterType
+{
+  booleanType,
+  integerType,
+  enumeratedType,
+  stringType
+};
+
+enum corbaFilterRepeatable
+{
+  onePerQuery,
+  onePerTerm,
+  nPerTerm
+};
+
+struct corbaFilterOption
+{
+  corbatext_t           name;
+  corbaFilterType       type;
+  corbaFilterRepeatable repeatable;
+  corbatext_t           defaultValue;
+  corbatext_tarray      validValues;
+};
+
+typedef sequence<corbaFilterOption> corbaFilterOptionList;
+
+struct corbaFilterOptionsResponse
+{
+  corbaFilterOptionList options;
+  corbatext_tarray      names;
+};
+
+//
+// structures for filter call
+//
+
+struct corbaOptionValue
+{
+  corbatext_t name;
+  corbatext_t value;
+};
+
+typedef sequence<corbaOptionValue> corbaOptionValue_array;
+
+struct corbaFilterRequest
+{ 
+  corbatext_t            filter;
+  corbaOptionValue_array filterOptions;
+  corbatext_tarray       docSet;
+  long                   filterResultOptions;
+  corbatext_t            requestParams;
+  corbatext_t            refParams;
+  corbatext_tset         fields;
+  boolean                getParents;
+};
+
+struct corbaTermInfo
+{
+  corbatext_t      term;
+  long             frequency;
+  corbatext_tarray matchTerms;
+};
+
+typedef sequence<corbaTermInfo> corbaTermInfo_array;
+
+struct corbaMetadataInfo
+{
+  corbatext_t      params;
+  boolean          isRef;
+  corbatext_tarray values;
+  long             id;
+  long             parentid; // dodge for avoiding pointers for the moment
+};
+
+typedef sequence<corbaMetadataInfo> corbaMetadataInfo_array;
+
+struct corbaMetadataInfo_map
+{ 
+  corbatext_tarray        names;
+  corbaMetadataInfo_array values;
+};
+
+typedef sequence<long> corbaDocFreq_array;
+
+struct corbaResultDocInfo
+{
+  corbatext_t             OID;
+  long                    resultNum;
+  long                    ranking;
+  long                    termsMatched;
+  long                    phraseMatched;
+  corbaDocFreq_array      docFreq;
+  corbaMetadataInfo_map   metadata;
+  corbatext_t             classifierMetadataType;    // Added 05/04/2000
+  long                    classifierMetadataOffset;  // Added 05/04/2000
+  corbaMetadataInfo_array metaparents;
+};
+
+typedef sequence<corbaResultDocInfo> corbaResultDocInfo_array;
+
+enum corbaIsApprox
+{
+  resultExact,
+  resultApprox,
+  resultMany
+};
+
+struct corbaFilterResponse
+{
+  long                     numDocs;
+  corbaIsApprox            isApprox;
+  corbaTermInfo_array      termInfo;
+  corbaResultDocInfo_array docInfo;
+};
+
+interface corbaiface
+{
+  boolean   initialise(inout corbaComError error);
+  void      configure(in corbatext_t key, in corbatext_tarray cfgline,
+		      inout corbaComError error);
+  void      collectionList(inout corbatext_tarray collist,
+			   inout corbaComError error);
+  void      hasCollection(in corbatext_t corbaCollection, inout boolean has,
+		       inout corbaComError error);
+  void      ping(in corbatext_t collection, inout boolean wasSuccess, inout corbaComError error);
+  void      getDocument(in corbatext_t collection,
+			inout corbaDocRequest request, inout corbaDocResponse response,
+			inout corbaComError error);
+  void      getCollectInfo(in corbatext_t collection,
+			   inout corbaColInfoResponse response,
+			   inout corbaComError error);
+  void      getFilterInfo(in corbatext_t collection, 
+                          inout corbatext_tarray filterNames, 
+			  inout corbaComError error);
+  void      getFilterOptions(in corbatext_t collection,
+                             in corbatext_t option,
+                             inout corbaFilterOptionsResponse response,
+			     inout corbaComError error);
+  void      filter(in corbatext_t collection,
+		   in corbaFilterRequest request,
+                   inout corbaFilterResponse response,
+                   inout corbaComError error);
+};
+
+};
Index: /gsdl/stable/runtime-src/src/corba/corbaiface.mpp
===================================================================
--- /gsdl/stable/runtime-src/src/corba/corbaiface.mpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/corbaiface.mpp	(revision 20131)
@@ -0,0 +1,2000 @@
+/*
+ *  MICO --- a free CORBA implementation
+ *  Copyright (C) 1997-98 Kay Roemer & Arno Puder
+ *
+ *  This file was automatically generated. DO NOT EDIT!
+ */
+
+#include "corbaiface.h"
+
+//--------------------------------------------------------
+//  Implementation of stubs
+//--------------------------------------------------------
+
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbatext_t::corbatext_t()
+{
+}
+
+gsdlInterface::corbatext_t::corbatext_t( const corbatext_t& _s )
+{
+  text = ((corbatext_t&)_s).text;
+  encoding = ((corbatext_t&)_s).encoding;
+  length = ((corbatext_t&)_s).length;
+}
+
+gsdlInterface::corbatext_t::~corbatext_t()
+{
+}
+
+gsdlInterface::corbatext_t&
+gsdlInterface::corbatext_t::operator=( const corbatext_t& _s )
+{
+  text = ((corbatext_t&)_s).text;
+  encoding = ((corbatext_t&)_s).encoding;
+  length = ((corbatext_t&)_s).length;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbatext_t : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbatext_t _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbatext_t::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbatext_t::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbatext_t::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbatext_t::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    CORBA::_stcseq_ushort->demarshal( dc, &((_MICO_T*)v)->text ) &&
+    CORBA::_stc_ushort->demarshal( dc, &((_MICO_T*)v)->encoding ) &&
+    CORBA::_stc_ulong->demarshal( dc, &((_MICO_T*)v)->length ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbatext_t::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  CORBA::_stcseq_ushort->marshal( ec, &((_MICO_T*)v)->text );
+  CORBA::_stc_ushort->marshal( ec, &((_MICO_T*)v)->encoding );
+  CORBA::_stc_ulong->marshal( ec, &((_MICO_T*)v)->length );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbatext_t;
+
+
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbatext_tmap::corbatext_tmap()
+{
+}
+
+gsdlInterface::corbatext_tmap::corbatext_tmap( const corbatext_tmap& _s )
+{
+  names = ((corbatext_tmap&)_s).names;
+  values = ((corbatext_tmap&)_s).values;
+}
+
+gsdlInterface::corbatext_tmap::~corbatext_tmap()
+{
+}
+
+gsdlInterface::corbatext_tmap&
+gsdlInterface::corbatext_tmap::operator=( const corbatext_tmap& _s )
+{
+  names = ((corbatext_tmap&)_s).names;
+  values = ((corbatext_tmap&)_s).values;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbatext_tmap : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbatext_tmap _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbatext_tmap::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbatext_tmap::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbatext_tmap::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbatext_tmap::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller__seq_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->names ) &&
+    _marshaller__seq_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->values ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbatext_tmap::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller__seq_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->names );
+  _marshaller__seq_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->values );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbatext_tmap;
+
+
+class _Marshaller_gsdlInterface_corbaComError : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaComError _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaComError::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaComError::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaComError::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaComError::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  CORBA::ULong ul;
+  if( !dc.enumeration( ul ) )
+    return FALSE;
+  *(_MICO_T*) v = (_MICO_T) ul;
+  return TRUE;
+}
+
+void _Marshaller_gsdlInterface_corbaComError::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.enumeration( (CORBA::ULong) *(_MICO_T *) v );
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaComError;
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaShortColInfo::corbaShortColInfo()
+{
+}
+
+gsdlInterface::corbaShortColInfo::corbaShortColInfo( const corbaShortColInfo& _s )
+{
+  name = ((corbaShortColInfo&)_s).name;
+  host = ((corbaShortColInfo&)_s).host;
+  response = ((corbaShortColInfo&)_s).response;
+}
+
+gsdlInterface::corbaShortColInfo::~corbaShortColInfo()
+{
+}
+
+gsdlInterface::corbaShortColInfo&
+gsdlInterface::corbaShortColInfo::operator=( const corbaShortColInfo& _s )
+{
+  name = ((corbaShortColInfo&)_s).name;
+  host = ((corbaShortColInfo&)_s).host;
+  response = ((corbaShortColInfo&)_s).response;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaShortColInfo : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaShortColInfo _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaShortColInfo::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaShortColInfo::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaShortColInfo::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaShortColInfo::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->name ) &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->host ) &&
+    CORBA::_stc_long->demarshal( dc, &((_MICO_T*)v)->response ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaShortColInfo::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->name );
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->host );
+  CORBA::_stc_long->marshal( ec, &((_MICO_T*)v)->response );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaShortColInfo;
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaColInfoResponse::corbaColInfoResponse()
+{
+}
+
+gsdlInterface::corbaColInfoResponse::corbaColInfoResponse( const corbaColInfoResponse& _s )
+{
+  shoftInfo = ((corbaColInfoResponse&)_s).shoftInfo;
+  useBook = ((corbaColInfoResponse&)_s).useBook;
+  isPublic = ((corbaColInfoResponse&)_s).isPublic;
+  isBeta = ((corbaColInfoResponse&)_s).isBeta;
+  buildDate = ((corbaColInfoResponse&)_s).buildDate;
+  ccsCols = ((corbaColInfoResponse&)_s).ccsCols;
+  languages = ((corbaColInfoResponse&)_s).languages;
+  numDocs = ((corbaColInfoResponse&)_s).numDocs;
+  numWords = ((corbaColInfoResponse&)_s).numWords;
+  numBytes = ((corbaColInfoResponse&)_s).numBytes;
+  collectionMeta = ((corbaColInfoResponse&)_s).collectionMeta;
+  format = ((corbaColInfoResponse&)_s).format;
+  building = ((corbaColInfoResponse&)_s).building;
+  httpdomain = ((corbaColInfoResponse&)_s).httpdomain;
+  httpprefix = ((corbaColInfoResponse&)_s).httpprefix;
+  receptionist = ((corbaColInfoResponse&)_s).receptionist;
+}
+
+gsdlInterface::corbaColInfoResponse::~corbaColInfoResponse()
+{
+}
+
+gsdlInterface::corbaColInfoResponse&
+gsdlInterface::corbaColInfoResponse::operator=( const corbaColInfoResponse& _s )
+{
+  shoftInfo = ((corbaColInfoResponse&)_s).shoftInfo;
+  useBook = ((corbaColInfoResponse&)_s).useBook;
+  isPublic = ((corbaColInfoResponse&)_s).isPublic;
+  isBeta = ((corbaColInfoResponse&)_s).isBeta;
+  buildDate = ((corbaColInfoResponse&)_s).buildDate;
+  ccsCols = ((corbaColInfoResponse&)_s).ccsCols;
+  languages = ((corbaColInfoResponse&)_s).languages;
+  numDocs = ((corbaColInfoResponse&)_s).numDocs;
+  numWords = ((corbaColInfoResponse&)_s).numWords;
+  numBytes = ((corbaColInfoResponse&)_s).numBytes;
+  collectionMeta = ((corbaColInfoResponse&)_s).collectionMeta;
+  format = ((corbaColInfoResponse&)_s).format;
+  building = ((corbaColInfoResponse&)_s).building;
+  httpdomain = ((corbaColInfoResponse&)_s).httpdomain;
+  httpprefix = ((corbaColInfoResponse&)_s).httpprefix;
+  receptionist = ((corbaColInfoResponse&)_s).receptionist;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaColInfoResponse : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaColInfoResponse _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaColInfoResponse::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaColInfoResponse::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaColInfoResponse::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaColInfoResponse::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller_gsdlInterface_corbaShortColInfo->demarshal( dc, &((_MICO_T*)v)->shoftInfo ) &&
+    CORBA::_stc_boolean->demarshal( dc, &((_MICO_T*)v)->useBook ) &&
+    CORBA::_stc_boolean->demarshal( dc, &((_MICO_T*)v)->isPublic ) &&
+    CORBA::_stc_boolean->demarshal( dc, &((_MICO_T*)v)->isBeta ) &&
+    CORBA::_stc_ulong->demarshal( dc, &((_MICO_T*)v)->buildDate ) &&
+    _marshaller__seq_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->ccsCols ) &&
+    _marshaller__seq_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->languages ) &&
+    CORBA::_stc_ulong->demarshal( dc, &((_MICO_T*)v)->numDocs ) &&
+    CORBA::_stc_ulong->demarshal( dc, &((_MICO_T*)v)->numWords ) &&
+    CORBA::_stc_ulong->demarshal( dc, &((_MICO_T*)v)->numBytes ) &&
+    _marshaller_gsdlInterface_corbatext_tmap->demarshal( dc, &((_MICO_T*)v)->collectionMeta ) &&
+    _marshaller_gsdlInterface_corbatext_tmap->demarshal( dc, &((_MICO_T*)v)->format ) &&
+    _marshaller_gsdlInterface_corbatext_tmap->demarshal( dc, &((_MICO_T*)v)->building ) &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->httpdomain ) &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->httpprefix ) &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->receptionist ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaColInfoResponse::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller_gsdlInterface_corbaShortColInfo->marshal( ec, &((_MICO_T*)v)->shoftInfo );
+  CORBA::_stc_boolean->marshal( ec, &((_MICO_T*)v)->useBook );
+  CORBA::_stc_boolean->marshal( ec, &((_MICO_T*)v)->isPublic );
+  CORBA::_stc_boolean->marshal( ec, &((_MICO_T*)v)->isBeta );
+  CORBA::_stc_ulong->marshal( ec, &((_MICO_T*)v)->buildDate );
+  _marshaller__seq_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->ccsCols );
+  _marshaller__seq_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->languages );
+  CORBA::_stc_ulong->marshal( ec, &((_MICO_T*)v)->numDocs );
+  CORBA::_stc_ulong->marshal( ec, &((_MICO_T*)v)->numWords );
+  CORBA::_stc_ulong->marshal( ec, &((_MICO_T*)v)->numBytes );
+  _marshaller_gsdlInterface_corbatext_tmap->marshal( ec, &((_MICO_T*)v)->collectionMeta );
+  _marshaller_gsdlInterface_corbatext_tmap->marshal( ec, &((_MICO_T*)v)->format );
+  _marshaller_gsdlInterface_corbatext_tmap->marshal( ec, &((_MICO_T*)v)->building );
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->httpdomain );
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->httpprefix );
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->receptionist );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaColInfoResponse;
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaDocRequest::corbaDocRequest()
+{
+}
+
+gsdlInterface::corbaDocRequest::corbaDocRequest( const corbaDocRequest& _s )
+{
+  OID = ((corbaDocRequest&)_s).OID;
+  docType = ((corbaDocRequest&)_s).docType;
+  docFormat = ((corbaDocRequest&)_s).docFormat;
+}
+
+gsdlInterface::corbaDocRequest::~corbaDocRequest()
+{
+}
+
+gsdlInterface::corbaDocRequest&
+gsdlInterface::corbaDocRequest::operator=( const corbaDocRequest& _s )
+{
+  OID = ((corbaDocRequest&)_s).OID;
+  docType = ((corbaDocRequest&)_s).docType;
+  docFormat = ((corbaDocRequest&)_s).docFormat;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaDocRequest : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaDocRequest _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaDocRequest::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaDocRequest::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaDocRequest::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaDocRequest::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->OID ) &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->docType ) &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->docFormat ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaDocRequest::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->OID );
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->docType );
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->docFormat );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaDocRequest;
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaDocResponse::corbaDocResponse()
+{
+}
+
+gsdlInterface::corbaDocResponse::corbaDocResponse( const corbaDocResponse& _s )
+{
+  doc = ((corbaDocResponse&)_s).doc;
+}
+
+gsdlInterface::corbaDocResponse::~corbaDocResponse()
+{
+}
+
+gsdlInterface::corbaDocResponse&
+gsdlInterface::corbaDocResponse::operator=( const corbaDocResponse& _s )
+{
+  doc = ((corbaDocResponse&)_s).doc;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaDocResponse : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaDocResponse _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaDocResponse::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaDocResponse::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaDocResponse::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaDocResponse::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->doc ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaDocResponse::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->doc );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaDocResponse;
+
+
+class _Marshaller_gsdlInterface_corbaFilterType : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaFilterType _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaFilterType::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterType::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterType::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaFilterType::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  CORBA::ULong ul;
+  if( !dc.enumeration( ul ) )
+    return FALSE;
+  *(_MICO_T*) v = (_MICO_T) ul;
+  return TRUE;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterType::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.enumeration( (CORBA::ULong) *(_MICO_T *) v );
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaFilterType;
+
+
+class _Marshaller_gsdlInterface_corbaFilterRepeatable : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaFilterRepeatable _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaFilterRepeatable::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterRepeatable::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterRepeatable::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaFilterRepeatable::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  CORBA::ULong ul;
+  if( !dc.enumeration( ul ) )
+    return FALSE;
+  *(_MICO_T*) v = (_MICO_T) ul;
+  return TRUE;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterRepeatable::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.enumeration( (CORBA::ULong) *(_MICO_T *) v );
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaFilterRepeatable;
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaFilterOption::corbaFilterOption()
+{
+}
+
+gsdlInterface::corbaFilterOption::corbaFilterOption( const corbaFilterOption& _s )
+{
+  name = ((corbaFilterOption&)_s).name;
+  type = ((corbaFilterOption&)_s).type;
+  repeatable = ((corbaFilterOption&)_s).repeatable;
+  defaultValue = ((corbaFilterOption&)_s).defaultValue;
+  validValues = ((corbaFilterOption&)_s).validValues;
+}
+
+gsdlInterface::corbaFilterOption::~corbaFilterOption()
+{
+}
+
+gsdlInterface::corbaFilterOption&
+gsdlInterface::corbaFilterOption::operator=( const corbaFilterOption& _s )
+{
+  name = ((corbaFilterOption&)_s).name;
+  type = ((corbaFilterOption&)_s).type;
+  repeatable = ((corbaFilterOption&)_s).repeatable;
+  defaultValue = ((corbaFilterOption&)_s).defaultValue;
+  validValues = ((corbaFilterOption&)_s).validValues;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaFilterOption : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaFilterOption _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaFilterOption::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterOption::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterOption::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaFilterOption::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->name ) &&
+    _marshaller_gsdlInterface_corbaFilterType->demarshal( dc, &((_MICO_T*)v)->type ) &&
+    _marshaller_gsdlInterface_corbaFilterRepeatable->demarshal( dc, &((_MICO_T*)v)->repeatable ) &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->defaultValue ) &&
+    _marshaller__seq_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->validValues ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaFilterOption::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->name );
+  _marshaller_gsdlInterface_corbaFilterType->marshal( ec, &((_MICO_T*)v)->type );
+  _marshaller_gsdlInterface_corbaFilterRepeatable->marshal( ec, &((_MICO_T*)v)->repeatable );
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->defaultValue );
+  _marshaller__seq_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->validValues );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaFilterOption;
+
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaFilterOptionsResponse::corbaFilterOptionsResponse()
+{
+}
+
+gsdlInterface::corbaFilterOptionsResponse::corbaFilterOptionsResponse( const corbaFilterOptionsResponse& _s )
+{
+  options = ((corbaFilterOptionsResponse&)_s).options;
+  names = ((corbaFilterOptionsResponse&)_s).names;
+}
+
+gsdlInterface::corbaFilterOptionsResponse::~corbaFilterOptionsResponse()
+{
+}
+
+gsdlInterface::corbaFilterOptionsResponse&
+gsdlInterface::corbaFilterOptionsResponse::operator=( const corbaFilterOptionsResponse& _s )
+{
+  options = ((corbaFilterOptionsResponse&)_s).options;
+  names = ((corbaFilterOptionsResponse&)_s).names;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaFilterOptionsResponse : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaFilterOptionsResponse _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaFilterOptionsResponse::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterOptionsResponse::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterOptionsResponse::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaFilterOptionsResponse::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller__seq_gsdlInterface_corbaFilterOption->demarshal( dc, &((_MICO_T*)v)->options ) &&
+    _marshaller__seq_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->names ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaFilterOptionsResponse::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller__seq_gsdlInterface_corbaFilterOption->marshal( ec, &((_MICO_T*)v)->options );
+  _marshaller__seq_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->names );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaFilterOptionsResponse;
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaOptionValue::corbaOptionValue()
+{
+}
+
+gsdlInterface::corbaOptionValue::corbaOptionValue( const corbaOptionValue& _s )
+{
+  name = ((corbaOptionValue&)_s).name;
+  value = ((corbaOptionValue&)_s).value;
+}
+
+gsdlInterface::corbaOptionValue::~corbaOptionValue()
+{
+}
+
+gsdlInterface::corbaOptionValue&
+gsdlInterface::corbaOptionValue::operator=( const corbaOptionValue& _s )
+{
+  name = ((corbaOptionValue&)_s).name;
+  value = ((corbaOptionValue&)_s).value;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaOptionValue : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaOptionValue _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaOptionValue::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaOptionValue::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaOptionValue::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaOptionValue::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->name ) &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->value ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaOptionValue::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->name );
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->value );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaOptionValue;
+
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaFilterRequest::corbaFilterRequest()
+{
+}
+
+gsdlInterface::corbaFilterRequest::corbaFilterRequest( const corbaFilterRequest& _s )
+{
+  filter = ((corbaFilterRequest&)_s).filter;
+  filterOptions = ((corbaFilterRequest&)_s).filterOptions;
+  docSet = ((corbaFilterRequest&)_s).docSet;
+  filterResultOptions = ((corbaFilterRequest&)_s).filterResultOptions;
+  requestParams = ((corbaFilterRequest&)_s).requestParams;
+  refParams = ((corbaFilterRequest&)_s).refParams;
+  fields = ((corbaFilterRequest&)_s).fields;
+  getParents = ((corbaFilterRequest&)_s).getParents;
+}
+
+gsdlInterface::corbaFilterRequest::~corbaFilterRequest()
+{
+}
+
+gsdlInterface::corbaFilterRequest&
+gsdlInterface::corbaFilterRequest::operator=( const corbaFilterRequest& _s )
+{
+  filter = ((corbaFilterRequest&)_s).filter;
+  filterOptions = ((corbaFilterRequest&)_s).filterOptions;
+  docSet = ((corbaFilterRequest&)_s).docSet;
+  filterResultOptions = ((corbaFilterRequest&)_s).filterResultOptions;
+  requestParams = ((corbaFilterRequest&)_s).requestParams;
+  refParams = ((corbaFilterRequest&)_s).refParams;
+  fields = ((corbaFilterRequest&)_s).fields;
+  getParents = ((corbaFilterRequest&)_s).getParents;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaFilterRequest : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaFilterRequest _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaFilterRequest::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterRequest::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterRequest::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaFilterRequest::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->filter ) &&
+    _marshaller__seq_gsdlInterface_corbaOptionValue->demarshal( dc, &((_MICO_T*)v)->filterOptions ) &&
+    _marshaller__seq_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->docSet ) &&
+    CORBA::_stc_long->demarshal( dc, &((_MICO_T*)v)->filterResultOptions ) &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->requestParams ) &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->refParams ) &&
+    _marshaller__seq_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->fields ) &&
+    CORBA::_stc_boolean->demarshal( dc, &((_MICO_T*)v)->getParents ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaFilterRequest::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->filter );
+  _marshaller__seq_gsdlInterface_corbaOptionValue->marshal( ec, &((_MICO_T*)v)->filterOptions );
+  _marshaller__seq_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->docSet );
+  CORBA::_stc_long->marshal( ec, &((_MICO_T*)v)->filterResultOptions );
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->requestParams );
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->refParams );
+  _marshaller__seq_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->fields );
+  CORBA::_stc_boolean->marshal( ec, &((_MICO_T*)v)->getParents );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaFilterRequest;
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaTermInfo::corbaTermInfo()
+{
+}
+
+gsdlInterface::corbaTermInfo::corbaTermInfo( const corbaTermInfo& _s )
+{
+  term = ((corbaTermInfo&)_s).term;
+  frequency = ((corbaTermInfo&)_s).frequency;
+  matchTerms = ((corbaTermInfo&)_s).matchTerms;
+}
+
+gsdlInterface::corbaTermInfo::~corbaTermInfo()
+{
+}
+
+gsdlInterface::corbaTermInfo&
+gsdlInterface::corbaTermInfo::operator=( const corbaTermInfo& _s )
+{
+  term = ((corbaTermInfo&)_s).term;
+  frequency = ((corbaTermInfo&)_s).frequency;
+  matchTerms = ((corbaTermInfo&)_s).matchTerms;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaTermInfo : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaTermInfo _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaTermInfo::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaTermInfo::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaTermInfo::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaTermInfo::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->term ) &&
+    CORBA::_stc_long->demarshal( dc, &((_MICO_T*)v)->frequency ) &&
+    _marshaller__seq_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->matchTerms ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaTermInfo::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->term );
+  CORBA::_stc_long->marshal( ec, &((_MICO_T*)v)->frequency );
+  _marshaller__seq_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->matchTerms );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaTermInfo;
+
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaMetadataInfo::corbaMetadataInfo()
+{
+}
+
+gsdlInterface::corbaMetadataInfo::corbaMetadataInfo( const corbaMetadataInfo& _s )
+{
+  params = ((corbaMetadataInfo&)_s).params;
+  isRef = ((corbaMetadataInfo&)_s).isRef;
+  values = ((corbaMetadataInfo&)_s).values;
+  id = ((corbaMetadataInfo&)_s).id;
+  parentid = ((corbaMetadataInfo&)_s).parentid;
+}
+
+gsdlInterface::corbaMetadataInfo::~corbaMetadataInfo()
+{
+}
+
+gsdlInterface::corbaMetadataInfo&
+gsdlInterface::corbaMetadataInfo::operator=( const corbaMetadataInfo& _s )
+{
+  params = ((corbaMetadataInfo&)_s).params;
+  isRef = ((corbaMetadataInfo&)_s).isRef;
+  values = ((corbaMetadataInfo&)_s).values;
+  id = ((corbaMetadataInfo&)_s).id;
+  parentid = ((corbaMetadataInfo&)_s).parentid;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaMetadataInfo : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaMetadataInfo _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaMetadataInfo::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaMetadataInfo::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaMetadataInfo::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaMetadataInfo::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->params ) &&
+    CORBA::_stc_boolean->demarshal( dc, &((_MICO_T*)v)->isRef ) &&
+    _marshaller__seq_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->values ) &&
+    CORBA::_stc_long->demarshal( dc, &((_MICO_T*)v)->id ) &&
+    CORBA::_stc_long->demarshal( dc, &((_MICO_T*)v)->parentid ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaMetadataInfo::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->params );
+  CORBA::_stc_boolean->marshal( ec, &((_MICO_T*)v)->isRef );
+  _marshaller__seq_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->values );
+  CORBA::_stc_long->marshal( ec, &((_MICO_T*)v)->id );
+  CORBA::_stc_long->marshal( ec, &((_MICO_T*)v)->parentid );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaMetadataInfo;
+
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaMetadataInfo_map::corbaMetadataInfo_map()
+{
+}
+
+gsdlInterface::corbaMetadataInfo_map::corbaMetadataInfo_map( const corbaMetadataInfo_map& _s )
+{
+  names = ((corbaMetadataInfo_map&)_s).names;
+  values = ((corbaMetadataInfo_map&)_s).values;
+}
+
+gsdlInterface::corbaMetadataInfo_map::~corbaMetadataInfo_map()
+{
+}
+
+gsdlInterface::corbaMetadataInfo_map&
+gsdlInterface::corbaMetadataInfo_map::operator=( const corbaMetadataInfo_map& _s )
+{
+  names = ((corbaMetadataInfo_map&)_s).names;
+  values = ((corbaMetadataInfo_map&)_s).values;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaMetadataInfo_map : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaMetadataInfo_map _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaMetadataInfo_map::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaMetadataInfo_map::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaMetadataInfo_map::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaMetadataInfo_map::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller__seq_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->names ) &&
+    _marshaller__seq_gsdlInterface_corbaMetadataInfo->demarshal( dc, &((_MICO_T*)v)->values ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaMetadataInfo_map::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller__seq_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->names );
+  _marshaller__seq_gsdlInterface_corbaMetadataInfo->marshal( ec, &((_MICO_T*)v)->values );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaMetadataInfo_map;
+
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaResultDocInfo::corbaResultDocInfo()
+{
+}
+
+gsdlInterface::corbaResultDocInfo::corbaResultDocInfo( const corbaResultDocInfo& _s )
+{
+  OID = ((corbaResultDocInfo&)_s).OID;
+  resultNum = ((corbaResultDocInfo&)_s).resultNum;
+  ranking = ((corbaResultDocInfo&)_s).ranking;
+  termsMatched = ((corbaResultDocInfo&)_s).termsMatched;
+  phraseMatched = ((corbaResultDocInfo&)_s).phraseMatched;
+  docFreq = ((corbaResultDocInfo&)_s).docFreq;
+  metadata = ((corbaResultDocInfo&)_s).metadata;
+  classifierMetadataType = ((corbaResultDocInfo&)_s).classifierMetadataType;
+  classifierMetadataOffset = ((corbaResultDocInfo&)_s).classifierMetadataOffset;
+  metaparents = ((corbaResultDocInfo&)_s).metaparents;
+}
+
+gsdlInterface::corbaResultDocInfo::~corbaResultDocInfo()
+{
+}
+
+gsdlInterface::corbaResultDocInfo&
+gsdlInterface::corbaResultDocInfo::operator=( const corbaResultDocInfo& _s )
+{
+  OID = ((corbaResultDocInfo&)_s).OID;
+  resultNum = ((corbaResultDocInfo&)_s).resultNum;
+  ranking = ((corbaResultDocInfo&)_s).ranking;
+  termsMatched = ((corbaResultDocInfo&)_s).termsMatched;
+  phraseMatched = ((corbaResultDocInfo&)_s).phraseMatched;
+  docFreq = ((corbaResultDocInfo&)_s).docFreq;
+  metadata = ((corbaResultDocInfo&)_s).metadata;
+  classifierMetadataType = ((corbaResultDocInfo&)_s).classifierMetadataType;
+  classifierMetadataOffset = ((corbaResultDocInfo&)_s).classifierMetadataOffset;
+  metaparents = ((corbaResultDocInfo&)_s).metaparents;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaResultDocInfo : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaResultDocInfo _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaResultDocInfo::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaResultDocInfo::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaResultDocInfo::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaResultDocInfo::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->OID ) &&
+    CORBA::_stc_long->demarshal( dc, &((_MICO_T*)v)->resultNum ) &&
+    CORBA::_stc_long->demarshal( dc, &((_MICO_T*)v)->ranking ) &&
+    CORBA::_stc_long->demarshal( dc, &((_MICO_T*)v)->termsMatched ) &&
+    CORBA::_stc_long->demarshal( dc, &((_MICO_T*)v)->phraseMatched ) &&
+    CORBA::_stcseq_long->demarshal( dc, &((_MICO_T*)v)->docFreq ) &&
+    _marshaller_gsdlInterface_corbaMetadataInfo_map->demarshal( dc, &((_MICO_T*)v)->metadata ) &&
+    _marshaller_gsdlInterface_corbatext_t->demarshal( dc, &((_MICO_T*)v)->classifierMetadataType ) &&
+    CORBA::_stc_long->demarshal( dc, &((_MICO_T*)v)->classifierMetadataOffset ) &&
+    _marshaller__seq_gsdlInterface_corbaMetadataInfo->demarshal( dc, &((_MICO_T*)v)->metaparents ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaResultDocInfo::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->OID );
+  CORBA::_stc_long->marshal( ec, &((_MICO_T*)v)->resultNum );
+  CORBA::_stc_long->marshal( ec, &((_MICO_T*)v)->ranking );
+  CORBA::_stc_long->marshal( ec, &((_MICO_T*)v)->termsMatched );
+  CORBA::_stc_long->marshal( ec, &((_MICO_T*)v)->phraseMatched );
+  CORBA::_stcseq_long->marshal( ec, &((_MICO_T*)v)->docFreq );
+  _marshaller_gsdlInterface_corbaMetadataInfo_map->marshal( ec, &((_MICO_T*)v)->metadata );
+  _marshaller_gsdlInterface_corbatext_t->marshal( ec, &((_MICO_T*)v)->classifierMetadataType );
+  CORBA::_stc_long->marshal( ec, &((_MICO_T*)v)->classifierMetadataOffset );
+  _marshaller__seq_gsdlInterface_corbaMetadataInfo->marshal( ec, &((_MICO_T*)v)->metaparents );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaResultDocInfo;
+
+
+
+class _Marshaller_gsdlInterface_corbaIsApprox : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaIsApprox _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaIsApprox::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaIsApprox::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaIsApprox::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaIsApprox::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  CORBA::ULong ul;
+  if( !dc.enumeration( ul ) )
+    return FALSE;
+  *(_MICO_T*) v = (_MICO_T) ul;
+  return TRUE;
+}
+
+void _Marshaller_gsdlInterface_corbaIsApprox::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.enumeration( (CORBA::ULong) *(_MICO_T *) v );
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaIsApprox;
+
+#ifdef HAVE_EXPLICIT_STRUCT_OPS
+gsdlInterface::corbaFilterResponse::corbaFilterResponse()
+{
+}
+
+gsdlInterface::corbaFilterResponse::corbaFilterResponse( const corbaFilterResponse& _s )
+{
+  numDocs = ((corbaFilterResponse&)_s).numDocs;
+  isApprox = ((corbaFilterResponse&)_s).isApprox;
+  termInfo = ((corbaFilterResponse&)_s).termInfo;
+  docInfo = ((corbaFilterResponse&)_s).docInfo;
+}
+
+gsdlInterface::corbaFilterResponse::~corbaFilterResponse()
+{
+}
+
+gsdlInterface::corbaFilterResponse&
+gsdlInterface::corbaFilterResponse::operator=( const corbaFilterResponse& _s )
+{
+  numDocs = ((corbaFilterResponse&)_s).numDocs;
+  isApprox = ((corbaFilterResponse&)_s).isApprox;
+  termInfo = ((corbaFilterResponse&)_s).termInfo;
+  docInfo = ((corbaFilterResponse&)_s).docInfo;
+  return *this;
+}
+#endif
+
+class _Marshaller_gsdlInterface_corbaFilterResponse : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaFilterResponse _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaFilterResponse::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterResponse::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller_gsdlInterface_corbaFilterResponse::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaFilterResponse::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  return
+    dc.struct_begin() &&
+    CORBA::_stc_long->demarshal( dc, &((_MICO_T*)v)->numDocs ) &&
+    _marshaller_gsdlInterface_corbaIsApprox->demarshal( dc, &((_MICO_T*)v)->isApprox ) &&
+    _marshaller__seq_gsdlInterface_corbaTermInfo->demarshal( dc, &((_MICO_T*)v)->termInfo ) &&
+    _marshaller__seq_gsdlInterface_corbaResultDocInfo->demarshal( dc, &((_MICO_T*)v)->docInfo ) &&
+    dc.struct_end();
+}
+
+void _Marshaller_gsdlInterface_corbaFilterResponse::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  ec.struct_begin();
+  CORBA::_stc_long->marshal( ec, &((_MICO_T*)v)->numDocs );
+  _marshaller_gsdlInterface_corbaIsApprox->marshal( ec, &((_MICO_T*)v)->isApprox );
+  _marshaller__seq_gsdlInterface_corbaTermInfo->marshal( ec, &((_MICO_T*)v)->termInfo );
+  _marshaller__seq_gsdlInterface_corbaResultDocInfo->marshal( ec, &((_MICO_T*)v)->docInfo );
+  ec.struct_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaFilterResponse;
+
+
+// Stub interface corbaiface
+gsdlInterface::corbaiface::~corbaiface()
+{
+}
+
+void *gsdlInterface::corbaiface::_narrow_helper( const char *_rid )
+{
+  if( strcmp( _rid, "IDL:gsdlInterface/corbaiface:1.0" ) == 0 )
+    return (void *)this;
+  return NULL;
+}
+
+bool gsdlInterface::corbaiface::_narrow_helper2( CORBA::Object_ptr _obj )
+{
+  if( strcmp( _obj->_repoid(), "IDL:gsdlInterface/corbaiface:1.0" ) == 0) {
+    return true;
+  }
+  for( vector<CORBA::Narrow_proto>::size_type _i = 0;
+       _narrow_helpers && _i < _narrow_helpers->size(); _i++ ) {
+    bool _res = (*(*_narrow_helpers)[ _i ])( _obj );
+    if( _res )
+      return true;
+  }
+  return false;
+}
+
+gsdlInterface::corbaiface_ptr gsdlInterface::corbaiface::_narrow( CORBA::Object_ptr _obj )
+{
+  gsdlInterface::corbaiface_ptr _o;
+  if( !CORBA::is_nil( _obj ) ) {
+    void *_p;
+    if( (_p = _obj->_narrow_helper( "IDL:gsdlInterface/corbaiface:1.0" )))
+      return _duplicate( (gsdlInterface::corbaiface_ptr) _p );
+    if( _narrow_helper2( _obj ) ||
+       ( _obj->_is_a_remote( "IDL:gsdlInterface/corbaiface:1.0" ) ) ) {
+      _o = new gsdlInterface::corbaiface_stub;
+      _o->MICO_SCOPE(CORBA,Object::operator=)( *_obj );
+      return _o;
+    }
+  }
+  return _nil();
+}
+
+gsdlInterface::corbaiface_ptr
+gsdlInterface::corbaiface::_narrow( CORBA::AbstractBase_ptr _obj )
+{
+  return _narrow (_obj->_to_object());
+}
+
+gsdlInterface::corbaiface_stub::~corbaiface_stub()
+{
+}
+
+CORBA::Boolean gsdlInterface::corbaiface_stub::initialise( gsdlInterface::corbaComError& error )
+{
+  CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+  CORBA::Boolean _res;
+  CORBA::StaticAny __res( CORBA::_stc_boolean, &_res );
+
+  CORBA::StaticRequest __req( this, "initialise" );
+  __req.add_inout_arg( &_error );
+  __req.set_result( &__res );
+
+  __req.invoke();
+
+  mico_sii_throw( &__req, 
+    0);
+  return _res;
+}
+
+
+void gsdlInterface::corbaiface_stub::configure( const gsdlInterface::corbatext_t& key, const gsdlInterface::corbatext_tarray& cfgline, gsdlInterface::corbaComError& error )
+{
+  CORBA::StaticAny _key( _marshaller_gsdlInterface_corbatext_t, &key );
+  CORBA::StaticAny _cfgline( _marshaller__seq_gsdlInterface_corbatext_t, &cfgline );
+  CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+  CORBA::StaticRequest __req( this, "configure" );
+  __req.add_in_arg( &_key );
+  __req.add_in_arg( &_cfgline );
+  __req.add_inout_arg( &_error );
+
+  __req.invoke();
+
+  mico_sii_throw( &__req, 
+    0);
+}
+
+
+void gsdlInterface::corbaiface_stub::collectionList( gsdlInterface::corbatext_tarray& collist, gsdlInterface::corbaComError& error )
+{
+  CORBA::StaticAny _collist( _marshaller__seq_gsdlInterface_corbatext_t, &collist );
+  CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+  CORBA::StaticRequest __req( this, "collectionList" );
+  __req.add_inout_arg( &_collist );
+  __req.add_inout_arg( &_error );
+
+  __req.invoke();
+
+  mico_sii_throw( &__req, 
+    0);
+}
+
+
+void gsdlInterface::corbaiface_stub::hasCollection( const gsdlInterface::corbatext_t& corbaCollection, CORBA::Boolean& has, gsdlInterface::corbaComError& error )
+{
+  CORBA::StaticAny _corbaCollection( _marshaller_gsdlInterface_corbatext_t, &corbaCollection );
+  CORBA::StaticAny _has( CORBA::_stc_boolean, &has );
+  CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+  CORBA::StaticRequest __req( this, "hasCollection" );
+  __req.add_in_arg( &_corbaCollection );
+  __req.add_inout_arg( &_has );
+  __req.add_inout_arg( &_error );
+
+  __req.invoke();
+
+  mico_sii_throw( &__req, 
+    0);
+}
+
+
+void gsdlInterface::corbaiface_stub::ping( const gsdlInterface::corbatext_t& collection, CORBA::Boolean& wasSuccess, gsdlInterface::corbaComError& error )
+{
+  CORBA::StaticAny _collection( _marshaller_gsdlInterface_corbatext_t, &collection );
+  CORBA::StaticAny _wasSuccess( CORBA::_stc_boolean, &wasSuccess );
+  CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+  CORBA::StaticRequest __req( this, "ping" );
+  __req.add_in_arg( &_collection );
+  __req.add_inout_arg( &_wasSuccess );
+  __req.add_inout_arg( &_error );
+
+  __req.invoke();
+
+  mico_sii_throw( &__req, 
+    0);
+}
+
+
+void gsdlInterface::corbaiface_stub::getDocument( const gsdlInterface::corbatext_t& collection, gsdlInterface::corbaDocRequest& request, gsdlInterface::corbaDocResponse& response, gsdlInterface::corbaComError& error )
+{
+  CORBA::StaticAny _collection( _marshaller_gsdlInterface_corbatext_t, &collection );
+  CORBA::StaticAny _request( _marshaller_gsdlInterface_corbaDocRequest, &request );
+  CORBA::StaticAny _response( _marshaller_gsdlInterface_corbaDocResponse, &response );
+  CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+  CORBA::StaticRequest __req( this, "getDocument" );
+  __req.add_in_arg( &_collection );
+  __req.add_inout_arg( &_request );
+  __req.add_inout_arg( &_response );
+  __req.add_inout_arg( &_error );
+
+  __req.invoke();
+
+  mico_sii_throw( &__req, 
+    0);
+}
+
+
+void gsdlInterface::corbaiface_stub::getCollectInfo( const gsdlInterface::corbatext_t& collection, gsdlInterface::corbaColInfoResponse& response, gsdlInterface::corbaComError& error )
+{
+  CORBA::StaticAny _collection( _marshaller_gsdlInterface_corbatext_t, &collection );
+  CORBA::StaticAny _response( _marshaller_gsdlInterface_corbaColInfoResponse, &response );
+  CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+  CORBA::StaticRequest __req( this, "getCollectInfo" );
+  __req.add_in_arg( &_collection );
+  __req.add_inout_arg( &_response );
+  __req.add_inout_arg( &_error );
+
+  __req.invoke();
+
+  mico_sii_throw( &__req, 
+    0);
+}
+
+
+void gsdlInterface::corbaiface_stub::getFilterInfo( const gsdlInterface::corbatext_t& collection, gsdlInterface::corbatext_tarray& filterNames, gsdlInterface::corbaComError& error )
+{
+  CORBA::StaticAny _collection( _marshaller_gsdlInterface_corbatext_t, &collection );
+  CORBA::StaticAny _filterNames( _marshaller__seq_gsdlInterface_corbatext_t, &filterNames );
+  CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+  CORBA::StaticRequest __req( this, "getFilterInfo" );
+  __req.add_in_arg( &_collection );
+  __req.add_inout_arg( &_filterNames );
+  __req.add_inout_arg( &_error );
+
+  __req.invoke();
+
+  mico_sii_throw( &__req, 
+    0);
+}
+
+
+void gsdlInterface::corbaiface_stub::getFilterOptions( const gsdlInterface::corbatext_t& collection, const gsdlInterface::corbatext_t& option, gsdlInterface::corbaFilterOptionsResponse& response, gsdlInterface::corbaComError& error )
+{
+  CORBA::StaticAny _collection( _marshaller_gsdlInterface_corbatext_t, &collection );
+  CORBA::StaticAny _option( _marshaller_gsdlInterface_corbatext_t, &option );
+  CORBA::StaticAny _response( _marshaller_gsdlInterface_corbaFilterOptionsResponse, &response );
+  CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+  CORBA::StaticRequest __req( this, "getFilterOptions" );
+  __req.add_in_arg( &_collection );
+  __req.add_in_arg( &_option );
+  __req.add_inout_arg( &_response );
+  __req.add_inout_arg( &_error );
+
+  __req.invoke();
+
+  mico_sii_throw( &__req, 
+    0);
+}
+
+
+void gsdlInterface::corbaiface_stub::filter( const gsdlInterface::corbatext_t& collection, const gsdlInterface::corbaFilterRequest& request, gsdlInterface::corbaFilterResponse& response, gsdlInterface::corbaComError& error )
+{
+  CORBA::StaticAny _collection( _marshaller_gsdlInterface_corbatext_t, &collection );
+  CORBA::StaticAny _request( _marshaller_gsdlInterface_corbaFilterRequest, &request );
+  CORBA::StaticAny _response( _marshaller_gsdlInterface_corbaFilterResponse, &response );
+  CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+  CORBA::StaticRequest __req( this, "filter" );
+  __req.add_in_arg( &_collection );
+  __req.add_in_arg( &_request );
+  __req.add_inout_arg( &_response );
+  __req.add_inout_arg( &_error );
+
+  __req.invoke();
+
+  mico_sii_throw( &__req, 
+    0);
+}
+
+
+#ifdef HAVE_NAMESPACE
+namespace gsdlInterface { vector<CORBA::Narrow_proto> * corbaiface::_narrow_helpers; }
+#else
+vector<CORBA::Narrow_proto> * gsdlInterface::corbaiface::_narrow_helpers;
+#endif
+
+class _Marshaller_gsdlInterface_corbaiface : public CORBA::StaticTypeInfo {
+    typedef gsdlInterface::corbaiface_ptr _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller_gsdlInterface_corbaiface::create() const
+{
+  return (StaticValueType) new _MICO_T( 0 );
+}
+
+void _Marshaller_gsdlInterface_corbaiface::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = ::gsdlInterface::corbaiface::_duplicate( *(_MICO_T*) s );
+}
+
+void _Marshaller_gsdlInterface_corbaiface::free( StaticValueType v ) const
+{
+  CORBA::release( *(_MICO_T *) v );
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller_gsdlInterface_corbaiface::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  CORBA::Object_ptr obj;
+  if (!CORBA::_stc_Object->demarshal(dc, &obj))
+    return FALSE;
+  *(_MICO_T *) v = ::gsdlInterface::corbaiface::_narrow( obj );
+  CORBA::Boolean ret = CORBA::is_nil (obj) || !CORBA::is_nil (*(_MICO_T *)v);
+  CORBA::release (obj);
+  return ret;
+}
+
+void _Marshaller_gsdlInterface_corbaiface::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  CORBA::Object_ptr obj = *(_MICO_T *) v;
+  CORBA::_stc_Object->marshal( ec, &obj );
+}
+
+CORBA::StaticTypeInfo *_marshaller_gsdlInterface_corbaiface;
+
+class _Marshaller__seq_gsdlInterface_corbatext_t : public CORBA::StaticTypeInfo {
+    typedef SequenceTmpl<gsdlInterface::corbatext_t,MICO_TID_DEF> _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller__seq_gsdlInterface_corbatext_t::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller__seq_gsdlInterface_corbatext_t::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller__seq_gsdlInterface_corbatext_t::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller__seq_gsdlInterface_corbatext_t::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  CORBA::ULong len;
+  if( !dc.seq_begin( len ) )
+    return FALSE;
+  ((_MICO_T *) v)->length( len );
+  for( CORBA::ULong i = 0; i < len; i++ ) {
+    if( !_marshaller_gsdlInterface_corbatext_t->demarshal( dc, &(*(_MICO_T*)v)[i] ) )
+      return FALSE;
+  }
+  return dc.seq_end();
+}
+
+void _Marshaller__seq_gsdlInterface_corbatext_t::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  CORBA::ULong len = ((_MICO_T *) v)->length();
+  ec.seq_begin( len );
+  for( CORBA::ULong i = 0; i < len; i++ )
+    _marshaller_gsdlInterface_corbatext_t->marshal( ec, &(*(_MICO_T*)v)[i] );
+  ec.seq_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller__seq_gsdlInterface_corbatext_t;
+
+class _Marshaller__seq_gsdlInterface_corbaFilterOption : public CORBA::StaticTypeInfo {
+    typedef SequenceTmpl<gsdlInterface::corbaFilterOption,MICO_TID_DEF> _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller__seq_gsdlInterface_corbaFilterOption::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller__seq_gsdlInterface_corbaFilterOption::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller__seq_gsdlInterface_corbaFilterOption::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller__seq_gsdlInterface_corbaFilterOption::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  CORBA::ULong len;
+  if( !dc.seq_begin( len ) )
+    return FALSE;
+  ((_MICO_T *) v)->length( len );
+  for( CORBA::ULong i = 0; i < len; i++ ) {
+    if( !_marshaller_gsdlInterface_corbaFilterOption->demarshal( dc, &(*(_MICO_T*)v)[i] ) )
+      return FALSE;
+  }
+  return dc.seq_end();
+}
+
+void _Marshaller__seq_gsdlInterface_corbaFilterOption::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  CORBA::ULong len = ((_MICO_T *) v)->length();
+  ec.seq_begin( len );
+  for( CORBA::ULong i = 0; i < len; i++ )
+    _marshaller_gsdlInterface_corbaFilterOption->marshal( ec, &(*(_MICO_T*)v)[i] );
+  ec.seq_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller__seq_gsdlInterface_corbaFilterOption;
+
+class _Marshaller__seq_gsdlInterface_corbaOptionValue : public CORBA::StaticTypeInfo {
+    typedef SequenceTmpl<gsdlInterface::corbaOptionValue,MICO_TID_DEF> _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller__seq_gsdlInterface_corbaOptionValue::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller__seq_gsdlInterface_corbaOptionValue::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller__seq_gsdlInterface_corbaOptionValue::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller__seq_gsdlInterface_corbaOptionValue::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  CORBA::ULong len;
+  if( !dc.seq_begin( len ) )
+    return FALSE;
+  ((_MICO_T *) v)->length( len );
+  for( CORBA::ULong i = 0; i < len; i++ ) {
+    if( !_marshaller_gsdlInterface_corbaOptionValue->demarshal( dc, &(*(_MICO_T*)v)[i] ) )
+      return FALSE;
+  }
+  return dc.seq_end();
+}
+
+void _Marshaller__seq_gsdlInterface_corbaOptionValue::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  CORBA::ULong len = ((_MICO_T *) v)->length();
+  ec.seq_begin( len );
+  for( CORBA::ULong i = 0; i < len; i++ )
+    _marshaller_gsdlInterface_corbaOptionValue->marshal( ec, &(*(_MICO_T*)v)[i] );
+  ec.seq_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller__seq_gsdlInterface_corbaOptionValue;
+
+class _Marshaller__seq_gsdlInterface_corbaTermInfo : public CORBA::StaticTypeInfo {
+    typedef SequenceTmpl<gsdlInterface::corbaTermInfo,MICO_TID_DEF> _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller__seq_gsdlInterface_corbaTermInfo::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller__seq_gsdlInterface_corbaTermInfo::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller__seq_gsdlInterface_corbaTermInfo::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller__seq_gsdlInterface_corbaTermInfo::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  CORBA::ULong len;
+  if( !dc.seq_begin( len ) )
+    return FALSE;
+  ((_MICO_T *) v)->length( len );
+  for( CORBA::ULong i = 0; i < len; i++ ) {
+    if( !_marshaller_gsdlInterface_corbaTermInfo->demarshal( dc, &(*(_MICO_T*)v)[i] ) )
+      return FALSE;
+  }
+  return dc.seq_end();
+}
+
+void _Marshaller__seq_gsdlInterface_corbaTermInfo::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  CORBA::ULong len = ((_MICO_T *) v)->length();
+  ec.seq_begin( len );
+  for( CORBA::ULong i = 0; i < len; i++ )
+    _marshaller_gsdlInterface_corbaTermInfo->marshal( ec, &(*(_MICO_T*)v)[i] );
+  ec.seq_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller__seq_gsdlInterface_corbaTermInfo;
+
+class _Marshaller__seq_gsdlInterface_corbaMetadataInfo : public CORBA::StaticTypeInfo {
+    typedef SequenceTmpl<gsdlInterface::corbaMetadataInfo,MICO_TID_DEF> _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller__seq_gsdlInterface_corbaMetadataInfo::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller__seq_gsdlInterface_corbaMetadataInfo::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller__seq_gsdlInterface_corbaMetadataInfo::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller__seq_gsdlInterface_corbaMetadataInfo::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  CORBA::ULong len;
+  if( !dc.seq_begin( len ) )
+    return FALSE;
+  ((_MICO_T *) v)->length( len );
+  for( CORBA::ULong i = 0; i < len; i++ ) {
+    if( !_marshaller_gsdlInterface_corbaMetadataInfo->demarshal( dc, &(*(_MICO_T*)v)[i] ) )
+      return FALSE;
+  }
+  return dc.seq_end();
+}
+
+void _Marshaller__seq_gsdlInterface_corbaMetadataInfo::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  CORBA::ULong len = ((_MICO_T *) v)->length();
+  ec.seq_begin( len );
+  for( CORBA::ULong i = 0; i < len; i++ )
+    _marshaller_gsdlInterface_corbaMetadataInfo->marshal( ec, &(*(_MICO_T*)v)[i] );
+  ec.seq_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller__seq_gsdlInterface_corbaMetadataInfo;
+
+class _Marshaller__seq_gsdlInterface_corbaResultDocInfo : public CORBA::StaticTypeInfo {
+    typedef SequenceTmpl<gsdlInterface::corbaResultDocInfo,MICO_TID_DEF> _MICO_T;
+  public:
+    StaticValueType create () const;
+    void assign (StaticValueType dst, const StaticValueType src) const;
+    void free (StaticValueType) const;
+    CORBA::Boolean demarshal (CORBA::DataDecoder&, StaticValueType) const;
+    void marshal (CORBA::DataEncoder &, StaticValueType) const;
+};
+
+
+CORBA::StaticValueType _Marshaller__seq_gsdlInterface_corbaResultDocInfo::create() const
+{
+  return (StaticValueType) new _MICO_T;
+}
+
+void _Marshaller__seq_gsdlInterface_corbaResultDocInfo::assign( StaticValueType d, const StaticValueType s ) const
+{
+  *(_MICO_T*) d = *(_MICO_T*) s;
+}
+
+void _Marshaller__seq_gsdlInterface_corbaResultDocInfo::free( StaticValueType v ) const
+{
+  delete (_MICO_T*) v;
+}
+
+CORBA::Boolean _Marshaller__seq_gsdlInterface_corbaResultDocInfo::demarshal( CORBA::DataDecoder &dc, StaticValueType v ) const
+{
+  CORBA::ULong len;
+  if( !dc.seq_begin( len ) )
+    return FALSE;
+  ((_MICO_T *) v)->length( len );
+  for( CORBA::ULong i = 0; i < len; i++ ) {
+    if( !_marshaller_gsdlInterface_corbaResultDocInfo->demarshal( dc, &(*(_MICO_T*)v)[i] ) )
+      return FALSE;
+  }
+  return dc.seq_end();
+}
+
+void _Marshaller__seq_gsdlInterface_corbaResultDocInfo::marshal( CORBA::DataEncoder &ec, StaticValueType v ) const
+{
+  CORBA::ULong len = ((_MICO_T *) v)->length();
+  ec.seq_begin( len );
+  for( CORBA::ULong i = 0; i < len; i++ )
+    _marshaller_gsdlInterface_corbaResultDocInfo->marshal( ec, &(*(_MICO_T*)v)[i] );
+  ec.seq_end();
+}
+
+CORBA::StaticTypeInfo *_marshaller__seq_gsdlInterface_corbaResultDocInfo;
+
+struct __tc_init_CORBAIFACE {
+  __tc_init_CORBAIFACE()
+  {
+    _marshaller_gsdlInterface_corbatext_t = new _Marshaller_gsdlInterface_corbatext_t;
+    _marshaller_gsdlInterface_corbatext_tmap = new _Marshaller_gsdlInterface_corbatext_tmap;
+    _marshaller_gsdlInterface_corbaComError = new _Marshaller_gsdlInterface_corbaComError;
+    _marshaller_gsdlInterface_corbaShortColInfo = new _Marshaller_gsdlInterface_corbaShortColInfo;
+    _marshaller_gsdlInterface_corbaColInfoResponse = new _Marshaller_gsdlInterface_corbaColInfoResponse;
+    _marshaller_gsdlInterface_corbaDocRequest = new _Marshaller_gsdlInterface_corbaDocRequest;
+    _marshaller_gsdlInterface_corbaDocResponse = new _Marshaller_gsdlInterface_corbaDocResponse;
+    _marshaller_gsdlInterface_corbaFilterType = new _Marshaller_gsdlInterface_corbaFilterType;
+    _marshaller_gsdlInterface_corbaFilterRepeatable = new _Marshaller_gsdlInterface_corbaFilterRepeatable;
+    _marshaller_gsdlInterface_corbaFilterOption = new _Marshaller_gsdlInterface_corbaFilterOption;
+    _marshaller_gsdlInterface_corbaFilterOptionsResponse = new _Marshaller_gsdlInterface_corbaFilterOptionsResponse;
+    _marshaller_gsdlInterface_corbaOptionValue = new _Marshaller_gsdlInterface_corbaOptionValue;
+    _marshaller_gsdlInterface_corbaFilterRequest = new _Marshaller_gsdlInterface_corbaFilterRequest;
+    _marshaller_gsdlInterface_corbaTermInfo = new _Marshaller_gsdlInterface_corbaTermInfo;
+    _marshaller_gsdlInterface_corbaMetadataInfo = new _Marshaller_gsdlInterface_corbaMetadataInfo;
+    _marshaller_gsdlInterface_corbaMetadataInfo_map = new _Marshaller_gsdlInterface_corbaMetadataInfo_map;
+    _marshaller_gsdlInterface_corbaResultDocInfo = new _Marshaller_gsdlInterface_corbaResultDocInfo;
+    _marshaller_gsdlInterface_corbaIsApprox = new _Marshaller_gsdlInterface_corbaIsApprox;
+    _marshaller_gsdlInterface_corbaFilterResponse = new _Marshaller_gsdlInterface_corbaFilterResponse;
+    _marshaller_gsdlInterface_corbaiface = new _Marshaller_gsdlInterface_corbaiface;
+    _marshaller__seq_gsdlInterface_corbatext_t = new _Marshaller__seq_gsdlInterface_corbatext_t;
+    _marshaller__seq_gsdlInterface_corbaFilterOption = new _Marshaller__seq_gsdlInterface_corbaFilterOption;
+    _marshaller__seq_gsdlInterface_corbaOptionValue = new _Marshaller__seq_gsdlInterface_corbaOptionValue;
+    _marshaller__seq_gsdlInterface_corbaTermInfo = new _Marshaller__seq_gsdlInterface_corbaTermInfo;
+    _marshaller__seq_gsdlInterface_corbaMetadataInfo = new _Marshaller__seq_gsdlInterface_corbaMetadataInfo;
+    _marshaller__seq_gsdlInterface_corbaResultDocInfo = new _Marshaller__seq_gsdlInterface_corbaResultDocInfo;
+  }
+};
+
+static __tc_init_CORBAIFACE __init_CORBAIFACE;
+
Index: /gsdl/stable/runtime-src/src/corba/corbaiface_skel.mpp
===================================================================
--- /gsdl/stable/runtime-src/src/corba/corbaiface_skel.mpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/corbaiface_skel.mpp	(revision 20131)
@@ -0,0 +1,274 @@
+/*
+ *  MICO --- a free CORBA implementation
+ *  Copyright (C) 1997-98 Kay Roemer & Arno Puder
+ *
+ *  This file was automatically generated. DO NOT EDIT!
+ */
+#include "corbaiface.h"
+
+//--------------------------------------------------------
+//  Implementation of skeletons
+//--------------------------------------------------------
+
+gsdlInterface::corbaiface_skel::corbaiface_skel( const CORBA::BOA::ReferenceData &_id )
+{
+  CORBA::ImplementationDef_var _impl =
+    _find_impl( "IDL:gsdlInterface/corbaiface:1.0", "corbaiface" );
+  assert( !CORBA::is_nil( _impl ) );
+  _create_ref( _id,
+    0,
+    _impl,
+    "IDL:gsdlInterface/corbaiface:1.0" );
+  register_dispatcher( new StaticInterfaceDispatcherWrapper<corbaiface_skel>( this ) );
+}
+
+gsdlInterface::corbaiface_skel::corbaiface_skel( CORBA::Object_ptr _obj )
+{
+  CORBA::ImplementationDef_var _impl =
+    _find_impl( "IDL:gsdlInterface/corbaiface:1.0", "corbaiface" );
+  assert( !CORBA::is_nil( _impl ) );
+  _restore_ref( _obj,
+    CORBA::BOA::ReferenceData(),
+    0,
+    _impl );
+  register_dispatcher( new StaticInterfaceDispatcherWrapper<corbaiface_skel>( this ) );
+}
+
+gsdlInterface::corbaiface_skel::~corbaiface_skel()
+{
+}
+
+bool gsdlInterface::corbaiface_skel::dispatch( CORBA::StaticServerRequest_ptr _req, CORBA::Environment & /*_env*/ )
+{
+  #ifdef HAVE_EXCEPTIONS
+  try {
+  #endif
+    switch (mico_string_hash (_req->op_name(), 17)) {
+    case 0:
+      if( strcmp( _req->op_name(), "collectionList" ) == 0 ) {
+        corbatext_tarray collist;
+        CORBA::StaticAny _collist( _marshaller__seq_gsdlInterface_corbatext_t, &collist );
+        corbaComError error;
+        CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+
+        _req->add_inout_arg( &_collist );
+        _req->add_inout_arg( &_error );
+
+        if( !_req->read_args() )
+          return true;
+
+        collectionList( collist, error );
+        _req->write_results();
+        return true;
+      }
+      break;
+    case 3:
+      if( strcmp( _req->op_name(), "ping" ) == 0 ) {
+        corbatext_t collection;
+        CORBA::StaticAny _collection( _marshaller_gsdlInterface_corbatext_t, &collection );
+        CORBA::Boolean wasSuccess;
+        CORBA::StaticAny _wasSuccess( CORBA::_stc_boolean, &wasSuccess );
+        corbaComError error;
+        CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+
+        _req->add_in_arg( &_collection );
+        _req->add_inout_arg( &_wasSuccess );
+        _req->add_inout_arg( &_error );
+
+        if( !_req->read_args() )
+          return true;
+
+        ping( collection, wasSuccess, error );
+        _req->write_results();
+        return true;
+      }
+      break;
+    case 7:
+      if( strcmp( _req->op_name(), "filter" ) == 0 ) {
+        corbatext_t collection;
+        CORBA::StaticAny _collection( _marshaller_gsdlInterface_corbatext_t, &collection );
+        corbaFilterRequest request;
+        CORBA::StaticAny _request( _marshaller_gsdlInterface_corbaFilterRequest, &request );
+        corbaFilterResponse response;
+        CORBA::StaticAny _response( _marshaller_gsdlInterface_corbaFilterResponse, &response );
+        corbaComError error;
+        CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+
+        _req->add_in_arg( &_collection );
+        _req->add_in_arg( &_request );
+        _req->add_inout_arg( &_response );
+        _req->add_inout_arg( &_error );
+
+        if( !_req->read_args() )
+          return true;
+
+        filter( collection, request, response, error );
+        _req->write_results();
+        return true;
+      }
+      break;
+    case 9:
+      if( strcmp( _req->op_name(), "getFilterOptions" ) == 0 ) {
+        corbatext_t collection;
+        CORBA::StaticAny _collection( _marshaller_gsdlInterface_corbatext_t, &collection );
+        corbatext_t option;
+        CORBA::StaticAny _option( _marshaller_gsdlInterface_corbatext_t, &option );
+        corbaFilterOptionsResponse response;
+        CORBA::StaticAny _response( _marshaller_gsdlInterface_corbaFilterOptionsResponse, &response );
+        corbaComError error;
+        CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+
+        _req->add_in_arg( &_collection );
+        _req->add_in_arg( &_option );
+        _req->add_inout_arg( &_response );
+        _req->add_inout_arg( &_error );
+
+        if( !_req->read_args() )
+          return true;
+
+        getFilterOptions( collection, option, response, error );
+        _req->write_results();
+        return true;
+      }
+      break;
+    case 10:
+      if( strcmp( _req->op_name(), "getCollectInfo" ) == 0 ) {
+        corbatext_t collection;
+        CORBA::StaticAny _collection( _marshaller_gsdlInterface_corbatext_t, &collection );
+        corbaColInfoResponse response;
+        CORBA::StaticAny _response( _marshaller_gsdlInterface_corbaColInfoResponse, &response );
+        corbaComError error;
+        CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+
+        _req->add_in_arg( &_collection );
+        _req->add_inout_arg( &_response );
+        _req->add_inout_arg( &_error );
+
+        if( !_req->read_args() )
+          return true;
+
+        getCollectInfo( collection, response, error );
+        _req->write_results();
+        return true;
+      }
+      break;
+    case 11:
+      if( strcmp( _req->op_name(), "initialise" ) == 0 ) {
+        corbaComError error;
+        CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+
+        CORBA::Boolean _res;
+        CORBA::StaticAny __res( CORBA::_stc_boolean, &_res );
+        _req->add_inout_arg( &_error );
+        _req->set_result( &__res );
+
+        if( !_req->read_args() )
+          return true;
+
+        _res = initialise( error );
+        _req->write_results();
+        return true;
+      }
+      if( strcmp( _req->op_name(), "getFilterInfo" ) == 0 ) {
+        corbatext_t collection;
+        CORBA::StaticAny _collection( _marshaller_gsdlInterface_corbatext_t, &collection );
+        corbatext_tarray filterNames;
+        CORBA::StaticAny _filterNames( _marshaller__seq_gsdlInterface_corbatext_t, &filterNames );
+        corbaComError error;
+        CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+
+        _req->add_in_arg( &_collection );
+        _req->add_inout_arg( &_filterNames );
+        _req->add_inout_arg( &_error );
+
+        if( !_req->read_args() )
+          return true;
+
+        getFilterInfo( collection, filterNames, error );
+        _req->write_results();
+        return true;
+      }
+      break;
+    case 12:
+      if( strcmp( _req->op_name(), "hasCollection" ) == 0 ) {
+        corbatext_t corbaCollection;
+        CORBA::StaticAny _corbaCollection( _marshaller_gsdlInterface_corbatext_t, &corbaCollection );
+        CORBA::Boolean has;
+        CORBA::StaticAny _has( CORBA::_stc_boolean, &has );
+        corbaComError error;
+        CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+
+        _req->add_in_arg( &_corbaCollection );
+        _req->add_inout_arg( &_has );
+        _req->add_inout_arg( &_error );
+
+        if( !_req->read_args() )
+          return true;
+
+        hasCollection( corbaCollection, has, error );
+        _req->write_results();
+        return true;
+      }
+      break;
+    case 13:
+      if( strcmp( _req->op_name(), "configure" ) == 0 ) {
+        corbatext_t key;
+        CORBA::StaticAny _key( _marshaller_gsdlInterface_corbatext_t, &key );
+        corbatext_tarray cfgline;
+        CORBA::StaticAny _cfgline( _marshaller__seq_gsdlInterface_corbatext_t, &cfgline );
+        corbaComError error;
+        CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+
+        _req->add_in_arg( &_key );
+        _req->add_in_arg( &_cfgline );
+        _req->add_inout_arg( &_error );
+
+        if( !_req->read_args() )
+          return true;
+
+        configure( key, cfgline, error );
+        _req->write_results();
+        return true;
+      }
+      if( strcmp( _req->op_name(), "getDocument" ) == 0 ) {
+        corbatext_t collection;
+        CORBA::StaticAny _collection( _marshaller_gsdlInterface_corbatext_t, &collection );
+        corbaDocRequest request;
+        CORBA::StaticAny _request( _marshaller_gsdlInterface_corbaDocRequest, &request );
+        corbaDocResponse response;
+        CORBA::StaticAny _response( _marshaller_gsdlInterface_corbaDocResponse, &response );
+        corbaComError error;
+        CORBA::StaticAny _error( _marshaller_gsdlInterface_corbaComError, &error );
+
+        _req->add_in_arg( &_collection );
+        _req->add_inout_arg( &_request );
+        _req->add_inout_arg( &_response );
+        _req->add_inout_arg( &_error );
+
+        if( !_req->read_args() )
+          return true;
+
+        getDocument( collection, request, response, error );
+        _req->write_results();
+        return true;
+      }
+      break;
+    }
+  #ifdef HAVE_EXCEPTIONS
+  } catch( CORBA::SystemException_catch &_ex ) {
+    _req->set_exception( _ex->_clone() );
+    _req->write_results();
+    return true;
+  } catch( ... ) {
+    assert( 0 );
+    return true;
+  }
+  #endif
+  return false;
+}
+
+gsdlInterface::corbaiface_ptr gsdlInterface::corbaiface_skel::_this()
+{
+  return gsdlInterface::corbaiface::_duplicate( this );
+}
+
Index: /gsdl/stable/runtime-src/src/corba/corbaproto.h
===================================================================
--- /gsdl/stable/runtime-src/src/corba/corbaproto.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/corbaproto.h	(revision 20131)
@@ -0,0 +1,101 @@
+/**********************************************************************
+ *
+ * corbaproto.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef CORBAPROTO_H
+#define CORBAPROTO_H
+
+#include "gsdlconf.h"
+#include "collectserver.h"
+#include "recptproto.h"
+#include "corbaiface.h"
+using namespace gsdlInterface;
+
+class corbaproto : public recptproto {
+ private:
+  corbaiface_var getCorbaClient();
+ protected:
+  collectservermapclass cservers;
+  corbaiface_var        client;
+  CORBA::ORB_var        orb;
+  CORBA::BOA_var        boa;
+  CORBA::Object_var     obj;
+  text_t gsdlhome;
+  text_t site_name;
+
+ public:
+  virtual ~corbaproto() {}
+  corbaproto(char* site_name);
+
+  // add_collectserver should be called for each collection server
+  // before any configuration is done
+  void add_collectserver (collectserver *thecserver) 
+    {cservers.addcollectserver(thecserver);}
+
+  // this configure will configure each of the collection servers
+  void configure (const text_t &key, const text_tarray &cfgline, comerror_t &err);
+
+  // this init will init each of the collection servers
+  bool init (comerror_t &err,ostream &logout);
+
+  // used to check for icons and retrieve them from the collection
+  // site if they are missing
+  void  cache_missing_icons(text_tmap& format_map,
+			    text_t& httpdomain, 
+			    text_t& httpprefix);
+
+  text_t get_site_name (comerror_t &err);
+
+  text_t get_protocol_name (comerror_t &err);
+  void get_collection_list (text_tarray &collist, comerror_t &err, 
+			    ostream &logout);
+  void has_collection (const text_t &collection, bool &hascollection, 
+		       comerror_t &err, ostream &logout);
+  void ping (const text_t &collection, bool &wassuccess, 
+	     comerror_t &err, ostream &logout);
+  void get_collectinfo (const text_t &collection, 
+			ColInfoResponse_t &collectinfo,
+			comerror_t &err, ostream &logout);
+  void get_filterinfo (const text_t &collection,
+		       InfoFiltersResponse_t &response,
+		       comerror_t &err, ostream &logout);
+  void get_filteroptions (const text_t &collection,
+			  const InfoFilterOptionsRequest_t &request,
+			  InfoFilterOptionsResponse_t &response, 
+			  comerror_t &err, ostream &logout);
+  void filter (const text_t &collection,
+	       FilterRequest_t &request,
+	       FilterResponse_t &response,
+	       comerror_t &err, ostream &logout);
+
+  void get_document (const text_t &collection,
+		     const DocumentRequest_t &request,
+		     DocumentResponse_t &response,
+		     comerror_t &err, ostream &logout);
+
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/corba/corbaproto.mpp
===================================================================
--- /gsdl/stable/runtime-src/src/corba/corbaproto.mpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/corbaproto.mpp	(revision 20131)
@@ -0,0 +1,750 @@
+/**********************************************************************
+ *
+ * corbaproto.cpp -- 
+ * Copyright (C) 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+#include <iostream.h>
+#include <fstream.h>
+
+#include "fileutil.h"
+
+// protocol headers for CORBA
+#include "corbaiface.h"
+using namespace gsdlInterface;
+
+// greenstone library headers
+#include "corbaconv_text_t.h"
+
+// greenstone local headers
+#include "corbatext_t.h"
+
+#include "corbaproto.h"
+#include "colservrconfig.h"
+
+// default headers
+#include <assert.h>
+
+void corbatext_optionValueArrayToCorba(OptionValue_tarray array, corbaOptionValue_array &corba)
+{
+  unsigned int i = 0;
+  OptionValue_tarray::iterator here = array.begin();
+  OptionValue_tarray::iterator end = array.end();
+  
+  while (here != end)
+    {
+      corba.length(i+1);
+      
+      corbaconv_text_t::getCorbatext(here->name,corba[i].name);
+      corbaconv_text_t::getCorbatext(here->value,corba[i].value);
+
+      i ++;
+      here ++;
+    }
+  //  cout << "Options " << i << endl;
+}
+
+void corbaresponse_resultMetadataToCorba(MetadataInfo_t &meta, corbaMetadataInfo &corbaMeta)
+{
+  corbaconv_text_t::getCorbatext(meta.params,corbaMeta.params);
+  corbatext_arrayToCorbaArray(meta.values, &corbaMeta.values);
+  corbaMeta.isRef    = meta.isRef;
+}
+
+void corbaresponse_resultMetadataToC(const corbaMetadataInfo &corbaMeta, MetadataInfo_t &meta)
+{
+  corbaconv_text_t::setCorbatext(meta.params,corbaMeta.params);
+  corbatext_corbaArrayToArray(corbaMeta.values, &meta.values);
+  meta.isRef    = corbaMeta.isRef;
+}
+
+int corbaresponse_resultMetaParentToCorba(MetadataInfo_t *parent, corbaMetadataInfo_array &corbaparent)
+{
+  int reply = -1, pid = -1;
+
+  // extend for new parent
+  reply = corbaparent.length();
+  corbaparent.length(reply+1);
+
+  // copy content into new array element
+  corbaresponse_resultMetadataToCorba(*parent, corbaparent[reply]);
+
+  // deal with our own parent
+  if (parent->parent != NULL)
+    {
+      // get offset of new parent and extend parent vector
+
+      pid  = corbaresponse_resultMetaParentToCorba(parent->parent, corbaparent);
+    }
+  corbaparent[reply].parentid = pid;
+
+  // return the parent id from here
+  return reply;
+}
+
+MetadataInfo_t *corbaresponse_resultMetaParentToC(corbaMetadataInfo_array &corbaparent, int pid)
+{
+  MetadataInfo_t *reply;
+
+  reply = new MetadataInfo_t;
+
+  corbaresponse_resultMetadataToC(corbaparent[pid], *reply);
+
+  // deal with our own parent
+  if (corbaparent[pid].parentid >= 0)
+    {
+      // get offset of new parent and extend parent vector
+
+      reply->parent = corbaresponse_resultMetaParentToC(corbaparent, corbaparent[pid].parentid);
+    }
+  else
+    {
+      reply->parent = NULL;
+    }
+
+  // return the parent id from here
+  return reply;
+}
+
+void corbaresponse_resultDocInfoToCorba(ResultDocInfo_tarray docinfo, corbaResultDocInfo_array &corbainfo)
+{
+  ResultDocInfo_tarray::iterator here = docinfo.begin();
+  ResultDocInfo_tarray::iterator end  = docinfo.end();
+  unsigned int i;
+
+  i = 0;
+  while (here != end)
+    {
+      corbainfo.length(i+1);
+
+      // copy the easy bits
+      corbaconv_text_t::getCorbatext(here->OID,corbainfo[i].OID);
+
+      corbainfo[i].resultNum     = here->result_num;
+      corbainfo[i].ranking       = here->ranking;
+      corbainfo[i].termsMatched  = here->num_terms_matched;
+      corbainfo[i].phraseMatched = here->num_phrase_match;
+
+      // copy the docFreq array
+      vector<int>::iterator fhere = here->docFreq.begin();
+      vector<int>::iterator fend  = here->docFreq.end();
+      unsigned int          fi = 0;
+
+      while (fhere != fend)
+	{
+	  corbainfo[i].docFreq.length(fi+1);
+
+	  corbainfo[i].docFreq[fi] = *fhere;
+
+	  fhere ++;
+	  fi ++;
+	}
+
+      // copy the MetadataInfo map
+      MetadataInfo_tmap::iterator mhere = here->metadata.begin();
+      MetadataInfo_tmap::iterator mend  = here->metadata.end();
+      unsigned int mi = 0;
+
+      while (mhere != mend)
+	{
+	  corbainfo[i].metadata.names.length(mi+1);
+	  corbainfo[i].metadata.values.length(mi+1);
+	  
+	  // copy name
+	  corbaconv_text_t::getCorbatext((*mhere).first,corbainfo[i].metadata.names[mi]);
+
+	  // copy metadata
+	  corbaresponse_resultMetadataToCorba((*mhere).second, corbainfo[i].metadata.values[mi]);
+	  if (mhere->second.parent != NULL)
+	    {
+	      int pid;
+
+	      pid = corbaresponse_resultMetaParentToCorba(mhere->second.parent, 
+							      corbainfo[i].metaparents);
+	      corbainfo[i].metadata.values[mi].parentid = pid;
+	    }
+	  else
+	    {
+	      corbainfo[i].metadata.values[mi].parentid = -1;
+	    }
+
+	  cout << "Parent " << mi << " " << (int) &mhere->second << " " << (int) mhere->second.parent << endl;
+
+	  mhere ++;
+	  mi ++;
+	}
+
+      // Copy the classifier variables
+      corbaconv_text_t::getCorbatext(here->classifier_metadata_type, corbainfo[i].classifierMetadataType);
+      corbainfo[i].classifierMetadataOffset = here->classifier_metadata_offset;
+
+      // Get next Docinfo item
+      i++;
+      here ++;
+    }
+}
+
+void corbaresponse_resultDocInfoToC(corbaResultDocInfo_array corbainfo, ResultDocInfo_tarray &docinfo)
+{
+  unsigned int i;
+  ResultDocInfo_t doc;
+
+  for (i = 0; i < corbainfo.length(); i++)
+    {
+      corbaconv_text_t::setCorbatext(doc.OID,corbainfo[i].OID);
+      doc.result_num        = corbainfo[i].resultNum;
+      doc.ranking           = corbainfo[i].ranking;
+      doc.num_terms_matched = corbainfo[i].termsMatched;
+      doc.num_phrase_match  = corbainfo[i].phraseMatched;
+
+      // copy the doc freq array
+      unsigned int fi;
+      for (fi = 0; fi < corbainfo[i].docFreq.length(); fi ++)
+	{
+	  doc.docFreq.push_back(corbainfo[i].docFreq[fi]);
+	}
+
+      // copy the MetadataInfomap
+      unsigned int   mi;
+      text_t         mname;
+      MetadataInfo_t mdata;
+      
+      doc.metadata.clear();
+      for (mi = 0; mi < corbainfo[i].metadata.names.length(); mi ++)
+	{
+	  // get name
+	  corbaconv_text_t::setCorbatext(mname,corbainfo[i].metadata.names[mi]);
+
+	  // get metadata
+	  corbaresponse_resultMetadataToC(corbainfo[i].metadata.values[mi], mdata);
+
+	  if (corbainfo[i].metadata.values[mi].parentid >= 0)
+	    {
+	      mdata.parent = 
+		corbaresponse_resultMetaParentToC(corbainfo[i].metaparents, 
+						  corbainfo[i].metadata.values[mi].parentid);	      
+	    }
+	 
+	  doc.metadata.insert(make_pair(mname, mdata));
+	}
+
+      // GRB: sort out parent data
+      for (mi = 0; mi < corbainfo[i].metadata.names.length(); mi ++)
+	{
+	  if (corbainfo[i].metadata.values[mi].parentid != 0)
+	    { 
+	      int pi;
+
+	      for (pi = 0; pi < corbainfo[i].metadata.names.length(); pi ++)
+		{
+		  if (pi != mi &&
+		      corbainfo[i].metadata.values[mi].parentid ==
+		      corbainfo[i].metadata.values[pi].id)
+		    {
+		      doc.metadata[mi].parent = &doc.metadata[pi];
+		    }
+		}
+	    }
+	}
+      //      doc.metadata
+
+      // convert metadata classifer information
+      corbaconv_text_t::setCorbatext(doc.classifier_metadata_type,corbainfo[i].classifierMetadataType);
+      doc.classifier_metadata_offset = corbainfo[i].classifierMetadataOffset;
+
+      docinfo.push_back(doc); 
+    }
+}
+
+
+// Added 31/1/2001, Michael Dewsnip
+void corbaresponse_resultTermInfoToC(corbaTermInfo_array corbainfo, TermInfo_tarray &terminfo)
+{
+  TermInfo_t ti;
+
+  for (unsigned int i = 0; i < corbainfo.length(); i++) {
+    corbaconv_text_t::setCorbatext(ti.term, corbainfo[i].term);
+    ti.freq = corbainfo[i].frequency;
+
+    for (unsigned int j = 0; j < corbainfo[i].matchTerms.length(); j++) {
+      text_t mt;
+      corbaconv_text_t::setCorbatext(mt, corbainfo[i].matchTerms[j]);
+
+      ti.matchTerms.push_back(mt);
+    }
+
+    terminfo.push_back(ti);
+  }
+}
+
+
+corbaproto::corbaproto(char* _site_name)
+{ char *dummyv[1] = {""};
+  int   dummyc = 0;
+  // CORBA variables
+  /* static CORBA::ORB_var orb = CORBA::ORB_init( dummyc , dummyv, "mico-local-orb" );
+     static CORBA::BOA_var boa = orb->BOA_init( dummyc , dummyv, "mico-local-boa" ); */
+
+  CORBA::ORB_var orb = CORBA::ORB_init( dummyc , dummyv, "mico-local-orb" );
+  CORBA::BOA_var boa = orb->BOA_init( dummyc , dummyv, "mico-local-boa" );
+
+  char objid_filename[256];
+  sprintf(objid_filename,"/tmp/%s.objid",_site_name);
+
+  // Get ref from "naming service"
+  ifstream in (objid_filename);
+  char ref[1000];
+  in >> ref;
+  in.close ();
+
+  // startup corba
+  // static CORBA::Object_var obj = orb->string_to_object (ref);
+  CORBA::Object_var obj = orb->string_to_object (ref);
+
+  client = corbaiface::_narrow( obj ); 
+  // client = NULL; // ****
+
+  gsdlhome.clear();
+  site_name = _site_name;
+}
+
+corbaiface_var corbaproto::getCorbaClient()
+{
+  // This function was written to help corba when ORB and BOA were
+  // not working in "persistent" mode.
+  // Now that persistent mode is working it is not longer needed/used.
+
+  char *dummyv[1] = {""};
+  int   dummyc = 0;
+  // CORBA variables
+//  static CORBA::ORB_var orb = CORBA::ORB_init( dummyc , dummyv, "mico-local-orb" );
+//  static CORBA::BOA_var boa = orb->BOA_init( dummyc , dummyv, "mico-local-boa" );
+
+  // DB // Try this out!! // ****
+  CORBA::ORB_var orb = CORBA::ORB_init( dummyc , dummyv, "mico-local-orb" );
+  CORBA::BOA_var boa = orb->BOA_init( dummyc , dummyv, "mico-local-boa" );
+
+  /*  char* site_name_chars = site_name.getcstr();
+  char objid_filename[256];
+  sprintf(objid_filename,"/tmp/%s.objid",site_name_chars);
+  // delete site_name_chars; */
+
+  text_t objid_filename = "/tmp/" + site_name + ".objid";
+
+  // Get ref from "naming service"
+  ifstream in (objid_filename.getcstr());
+  char ref[1000];
+  in >> ref;
+  in.close ();
+
+  // startup corba
+  // DB // Try this out!! // ****
+  // static CORBA::Object_var obj = orb->string_to_object (ref);
+  CORBA::Object_var obj = orb->string_to_object (ref);
+
+  return corbaiface::_narrow( obj );
+}
+
+
+// this configure will configure each of the collection servers
+void corbaproto::configure (const text_t &key, const text_tarray &cfgline,
+			    comerror_t &err) {
+  // the naming of the collection should not be done here,
+  // it should be done just after the collection server has been 
+  // created
+
+  // cout << "Corbaproto::Configure" << endl;
+  corbatext_t      corbaKey;
+  corbatext_tarray corbaCfgline;
+  gsdlInterface::corbaComError error = corbaNoError;
+
+  // get the corba client reference
+  // corbaiface_var lclient = this->getCorbaClient(); // ****
+  corbaiface_var lclient = client;
+
+  // convert all the requisite structures into their CORBA form
+  corbaconv_text_t::getCorbatext(key,corbaKey);
+  corbatext_arrayToCorbaArray(cfgline, &corbaCfgline);
+
+  // execute the corba transaction
+  lclient->configure(corbaKey, corbaCfgline, error);    
+
+  if (key=="gsdlhome")
+    {
+      // store gsdlhome in corba prototype so it can be used later to
+      // check if icons specified in format statements exist on the
+      // recptionist's side
+      gsdlhome = cfgline[0];
+    }
+  err = (comerror_t) error;
+}
+
+// this init will configure and init each of the collection servers
+bool corbaproto::init (comerror_t &err, ostream &logout) {
+//  cout << "Corbaproto::Init" << endl;
+  gsdlInterface::corbaComError error = corbaNoError;
+
+  // get the corba client reference
+  // corbaiface_var lclient = this->getCorbaClient(); // ****
+  corbaiface_var lclient = client;
+
+  // execute the corba transaction
+  return lclient->initialise(error);
+}
+
+void  corbaproto::cache_missing_icons(text_tmap& format_map,
+				      text_t& httpdomain, 
+				      text_t& httpprefix)
+{
+  // consider making this a member function in the object?
+
+  text_tmap::iterator format_here = format_map.begin();
+  text_tmap::iterator format_end = format_map.end();
+  while (format_here!=format_end)
+    {
+      text_t format_line = format_here->second;
+
+      // cout << "*** format line = " << format_line << endl; // ****
+
+      text_t::iterator fl_begin = format_line.begin();
+      text_t::iterator fl_end = format_line.end();
+
+      text_t::iterator httpimg_find = findword(fl_begin,fl_end,"_httpimg_");
+      text_t::iterator http_find = httpimg_find;
+
+      while (httpimg_find!=fl_end)
+	{
+	  http_find = httpimg_find+5;
+	  httpimg_find += 9;
+
+	  // look for white space " or >
+	  text_t::iterator filename_end = httpimg_find;
+	  while (filename_end != fl_end)
+	    {
+	      if (*filename_end == ' ') break;
+	      if (*filename_end == '\t') break;
+	      if (*filename_end == '\"') break;
+	      if (*filename_end == '>') break;
+	      filename_end++;
+	    }
+
+	  text_t img_filename = substr(httpimg_find,filename_end);
+
+	  text_t site_img_filename = filename_cat(gsdlhome,"images",img_filename);
+
+	  // look to see if img filename exists in images directory
+	  if (!file_exists(site_img_filename))
+	    {
+	      text_t cache_img_dir
+		= filename_cat(gsdlhome,"images",".cache");
+
+	      text_t remote_img_url = "http://" + httpdomain + httpprefix
+		+ "/images" + img_filename;
+
+	      text_t wget_cmd = "wget -q -N --directory-prefix="+cache_img_dir
+		+ " " + remote_img_url;
+
+	      char* wget_cmd_chars = wget_cmd.getcstr();
+
+	      system(wget_cmd_chars);
+	      delete wget_cmd_chars;
+
+	      format_map[format_here->first] 
+		= substr(fl_begin,http_find) + "cache" + substr(http_find,fl_end);
+
+	    }
+
+	  httpimg_find = findword(httpimg_find,fl_end,"_httpimg_");
+	}
+      format_here++;
+    }
+}
+
+text_t corbaproto::get_site_name (comerror_t &err) {
+  return site_name;
+}
+
+text_t corbaproto::get_protocol_name (comerror_t &err) {
+  return "corbaproto";
+}
+
+
+void corbaproto::get_collection_list (text_tarray &collist, comerror_t &err, 
+				     ostream &/*logout*/) {
+
+  // cout << "Corbaproto::Collection list" << endl;
+
+  corbatext_tarray corba_collist;
+  text_tarray      tcollist;
+  gsdlInterface::corbaComError error = corbaNoError;
+
+  // get the corba client reference
+  // corbaiface_var lclient = this->getCorbaClient(); // ****
+  corbaiface_var lclient = client;
+
+  // execute the corba transaction
+  lclient->collectionList(corba_collist,error);
+
+  // convert the response back to normal form
+  corbatext_corbaArrayToArray(corba_collist, &tcollist);
+  collist = tcollist;
+
+  err = (comerror_t) error;
+}
+
+void corbaproto::has_collection (const text_t &collection, bool &hascollection, 
+				comerror_t &err, ostream &/*logout*/) {
+  // cout << "Corbaproto::Has collection" << endl;
+
+  corbatext_t     corbaCollection;
+  corbaComError corbaError = corbaNoError;
+  CORBA::Boolean corbaHas;
+
+  // get the corba client reference
+  // corbaiface_var lclient = this->getCorbaClient(); // ****
+  corbaiface_var lclient = client;
+
+  // convert all the requisite structures into their CORBA form
+  corbaconv_text_t::getCorbatext(collection,corbaCollection);
+  
+  // execute the corba transaction
+  lclient->hasCollection(corbaCollection, corbaHas, corbaError);
+
+  // convert the response back to normal form
+  hascollection = (corbaHas != 0);
+  err = noError;
+}
+
+void corbaproto::ping (const text_t &collection, bool &wassuccess, 
+		      comerror_t &err, ostream &/*logout*/) {
+  // cout << "Corbaproto::Ping" << endl;
+
+  corbatext_t corbaCollect;
+  corbaComError corbaError = corbaNoError;
+  CORBA::Boolean success;
+
+  // get the corba client reference
+  // corbaiface_var lclient = this->getCorbaClient(); // ****
+  corbaiface_var lclient = client;
+
+  // convert all the requisite structures into their CORBA form
+  corbaconv_text_t::getCorbatext(collection,corbaCollect);
+
+  // execute the corba transaction
+  lclient->ping(corbaCollect, success, corbaError);
+  
+  // convert the response back to normal form
+  wassuccess = (success != 0);
+  err = (comerror_t) corbaError;  
+  cout << "Corbaproto::Ping" << err << endl;
+}
+
+
+void corbaproto::get_collectinfo (const text_t &collection, 
+				 ColInfoResponse_t &collectinfo,
+				 comerror_t &err, ostream &logout) {
+  //  cout << "Corbaproto::Collectinfo" << endl;
+
+  corbatext_t          corbaCollection;
+  corbaComError        corbaError = corbaNoError;
+  corbaColInfoResponse corbaCollectInfo;
+
+  // get the corba client reference
+  // corbaiface_var lclient = this->getCorbaClient(); // ****
+  corbaiface_var lclient = client;
+
+  // convert all the requisite structures into their CORBA form
+  corbaconv_text_t::getCorbatext(collection,corbaCollection);
+
+  // execute the corba transaction
+  lclient->getCollectInfo(corbaCollection, corbaCollectInfo, corbaError);
+
+  // convert the response back to normal form
+  collectinfo.useBook = corbaCollectInfo.useBook;
+  collectinfo.isPublic = corbaCollectInfo.isPublic;
+  collectinfo.isBeta   = corbaCollectInfo.isBeta;
+  collectinfo.buildDate = corbaCollectInfo.buildDate;
+  corbatext_corbaArrayToArray(corbaCollectInfo.ccsCols, &collectinfo.ccsCols);
+  corbatext_corbaArrayToArray(corbaCollectInfo.languages, &collectinfo.languages);
+  collectinfo.numDocs   = corbaCollectInfo.numDocs;
+  collectinfo.numWords  = corbaCollectInfo.numWords;
+  collectinfo.numBytes  = corbaCollectInfo.numBytes;
+  corbatext_corbaMapToMap(corbaCollectInfo.collectionMeta, collectinfo.collectionmeta);
+  corbatext_corbaMapToMap(corbaCollectInfo.format, collectinfo.format);
+  corbatext_corbaMapToMap(corbaCollectInfo.building, collectinfo.building);
+  corbaconv_text_t::setCorbatext(collectinfo.httpdomain,corbaCollectInfo.httpdomain);
+  corbaconv_text_t::setCorbatext(collectinfo.httpprefix,corbaCollectInfo.httpprefix);
+  corbaconv_text_t::setCorbatext(collectinfo.receptionist,corbaCollectInfo.receptionist);
+
+  cache_missing_icons(collectinfo.format,collectinfo.httpdomain,
+		      collectinfo.httpprefix);
+
+  err = (comerror_t) corbaError;  
+}
+
+
+void corbaproto::get_filterinfo (const text_t &collection,
+				InfoFiltersResponse_t &response,
+				comerror_t &err, ostream &logout) {
+  //  cout << "Corbaproto::Filterinfo" << endl;
+
+  corbatext_t corbaCollection;
+  corbatext_tset corbaResponse;
+  corbaComError corbaError = corbaNoError;
+  
+  // get the corba client reference
+  // corbaiface_var lclient = this->getCorbaClient(); // ****
+  corbaiface_var lclient = client;
+
+  // convert all the requisite structures into their CORBA form
+  corbaconv_text_t::getCorbatext(collection,corbaCollection);
+
+  // execute the corba transaction
+  lclient->getFilterInfo(corbaCollection, corbaResponse, corbaError);
+
+  // convert the response back to normal form
+  corbatext_corbaArrayToSet(corbaResponse, &response.filterNames);
+
+  err = (comerror_t) corbaError;
+}
+
+void corbaproto::get_filteroptions (const text_t &collection,
+				   const InfoFilterOptionsRequest_t &request,
+				   InfoFilterOptionsResponse_t &response, 
+				   comerror_t &err, ostream &logout) {
+  //  cout << "Corbaproto::Filteroptions" << endl;
+
+  corbatext_t corbaCollection;
+  corbatext_t filterName;
+  corbaFilterOptionsResponse corbaResponse;
+  corbaComError corbaError = corbaNoError;
+  unsigned int i;
+  corbaconv_text_t *cc_name;
+  FilterOption_t *option;
+
+  // get the corba client reference
+  // corbaiface_var lclient = this->getCorbaClient(); // ****
+  corbaiface_var lclient = client;
+
+  // convert all the requisite structures into their CORBA form
+  corbaconv_text_t::getCorbatext(collection,corbaCollection);
+  corbaconv_text_t::getCorbatext(request.filterName,filterName);
+
+  // execute the corba transaction
+  lclient->getFilterOptions(corbaCollection, filterName, corbaResponse, corbaError);
+
+  // convert the response back to normal form
+  for (i = 0; i < corbaResponse.names.length(); i ++)
+    {
+      cc_name = new corbaconv_text_t(corbaResponse.names[i]);
+
+      option = new FilterOption_t;
+      corbaconv_text_t::setCorbatext(option->name,corbaResponse.options[i].name);
+      option->type = (FilterOption_t::type_t) corbaResponse.options[i].type;
+      option->repeatable = (FilterOption_t::repeatable_t) corbaResponse.options[i].repeatable;
+      corbaconv_text_t::setCorbatext(option->defaultValue,corbaResponse.options[i].defaultValue);
+      corbatext_corbaArrayToArray(corbaResponse.options[i].validValues, &option->validValues);
+
+      response.filterOptions.insert(make_pair(*cc_name, *option)); // typecast to text_t
+    }
+
+  err =  (comerror_t) corbaError;
+}
+
+
+void corbaproto::filter (const text_t &collection,
+			  FilterRequest_t &request,
+			  FilterResponse_t &response,
+			  comerror_t &err, ostream &logout) {
+  //  cout << "Corbaproto::Filter" << endl;
+
+  corbaFilterRequest corbaRequest;
+  corbaFilterResponse corbaResponse;
+  corbatext_t     corbaCollection;
+  corbaComError corbaError = corbaNoError;
+
+  // get the corba client reference
+  // corbaiface_var lclient = this->getCorbaClient(); // ****
+  corbaiface_var lclient = client;
+
+  // convert all the requisite structures into their CORBA form
+  corbaconv_text_t::getCorbatext(collection,corbaCollection);
+  corbaconv_text_t::getCorbatext(request.filterName,corbaRequest.filter);
+  corbatext_optionValueArrayToCorba(request.filterOptions, corbaRequest.filterOptions);
+  corbatext_arrayToCorbaArray(request.docSet, &corbaRequest.docSet);
+  corbaRequest.filterResultOptions = request.filterResultOptions;
+  corbaconv_text_t::getCorbatext(request.requestParams,corbaRequest.requestParams);
+  corbaconv_text_t::getCorbatext(request.refParams,corbaRequest.refParams);
+  corbaRequest.getParents = request.getParents;
+  corbatext_setToCorbaArray(request.fields, &corbaRequest.fields);
+
+  corbaResponse.numDocs = response.numDocs;
+  corbaresponse_resultDocInfoToCorba(response.docInfo, corbaResponse.docInfo);
+
+  // execute the corba transaction
+  lclient->filter (corbaCollection, corbaRequest, corbaResponse, corbaError);
+
+  // convert the response back to normal form
+  response.numDocs = corbaResponse.numDocs;
+  response.isApprox = (enum isapprox) corbaResponse.isApprox;
+  corbaresponse_resultDocInfoToC(corbaResponse.docInfo, response.docInfo);
+
+  // Added 31/1/2001, Michael Dewsnip
+  corbaresponse_resultTermInfoToC(corbaResponse.termInfo, response.termInfo);
+
+  err = (comerror_t) corbaError;
+  //  cout << "Corbaproto::Filter" << endl;
+}
+
+
+void corbaproto::get_document (const text_t &collection,
+			       const DocumentRequest_t &request,
+			       DocumentResponse_t &response,
+			       comerror_t &err, ostream &logout) {
+  //  cout << "Corbaproto::Get Document" << endl;
+
+  corbatext_t      corbaCollect;
+  corbaDocRequest  corbaRequest;
+  corbaDocResponse corbaResponse;
+  corbaComError    corbaError = corbaNoError;
+
+  // get the corba client reference
+  // corbaiface_var lclient = this->getCorbaClient(); // ****
+  corbaiface_var lclient = client;
+
+  // convert all the requisite structures into their CORBA form
+  corbaconv_text_t::getCorbatext(collection,corbaCollect);
+  corbaconv_text_t::getCorbatext(request.OID,corbaRequest.OID);
+  corbaconv_text_t::getCorbatext(request.docType,corbaRequest.docType);
+  corbaconv_text_t::getCorbatext(request.docFormat,corbaRequest.docFormat);
+
+  // execute the corba transaction
+  lclient->getDocument(corbaCollect, corbaRequest, corbaResponse, corbaError);
+
+  // convert the response back to normal form
+  corbaconv_text_t::setCorbatext(response.doc,corbaResponse.doc);
+
+  err = (comerror_t) corbaError;
+}
+
Index: /gsdl/stable/runtime-src/src/corba/corbatext_t.h
===================================================================
--- /gsdl/stable/runtime-src/src/corba/corbatext_t.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/corbatext_t.h	(revision 20131)
@@ -0,0 +1,13 @@
+void corbatext_fillChar(corbatext_t *t, char *text);
+void corbatext_usvector(corbatext_t t, vector<unsigned short>& us);
+char *corbatext_string(corbatext_t t);
+#ifdef TEXT_T_H
+void corbatext_arrayToCorbaArray(text_tarray t, corbatext_tarray *ca);
+void corbatext_corbaArrayToArray(corbatext_tarray ca, text_tarray *ta);
+void corbatext_mapToCorbaMap(text_tmap tm, corbatext_tmap *cm);
+void corbatext_corbaMapToMap(corbatext_tmap cm, text_tmap &tm);
+void corbatext_setToCorbaArray(text_tset set, corbatext_tset *cset);
+void corbatext_corbaArrayToSet(corbatext_tset cset, text_tset *set);
+corbatext_t_var corbatext_corbatext(text_t t);
+int corbatext_corbatext(text_t t, corbatext_t_var ct);
+#endif
Index: /gsdl/stable/runtime-src/src/corba/corbatext_t.mpp
===================================================================
--- /gsdl/stable/runtime-src/src/corba/corbatext_t.mpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/corba/corbatext_t.mpp	(revision 20131)
@@ -0,0 +1,179 @@
+// standard headers
+#if defined(GSDL_USE_STL_H)
+#include <iostream.h>
+#include <fstream.h>
+#include <vector.h>
+#else
+#include <iostream>
+#include <fstream>
+#include <vector>
+#endif
+
+// protocol headers
+#include "corbaiface.h"
+using namespace gsdlInterface;
+
+// greenstone headers
+#include "corbaconv_text_t.h"
+
+//local headers
+#include "corbatext_t.h"
+
+void corbatext_fillChar(corbatext_t *t, char *text)
+{
+  unsigned int i;
+
+  t->text.length(0);
+  if (text == NULL)
+      {
+	  return;
+      }
+  for (i = 0; i < strlen(text); i ++)
+      {
+	  t->text[i] = text[i];
+      }  
+  t->encoding = 0;
+}
+
+void corbatext_usvector(corbatext_t t, usvector& us)
+{
+  unsigned int i;
+
+  for (i = 0; i < t.text.length(); i ++)
+    {
+      us.push_back(t.text[i]);
+    }
+}
+
+char *corbatext_string(corbatext_t t)
+{ 
+  char *lcopy;
+  unsigned int i;
+    lcopy = (char *) malloc(t.text.length() + 1);
+    for (i = 0; i < t.text.length(); i ++)
+    {
+      lcopy[i] = (char) t.text[i];
+    }
+    lcopy[i] = '\0';
+    return lcopy;
+}
+
+corbatext_t_var corbatext_corbatext(text_t t)
+{ corbatext_t_var ct;
+// usString_var    us;
+
+  // cout << "Making text\n";
+  ct = new corbatext_t;
+  //  ct->text.length(20);
+  // us = new usString(20);
+  //  cout << ct->text.length() << endl;
+  //  cout << ct->text.maximum() << endl;
+  corbaconv_text_t::fillUsString(t,&ct->text);
+  //t.fillUsString(us);
+  // delete us;
+  // cout << "Encoding text\n";
+  ct->encoding = 0;
+  // cout << "Encoding text\n";
+  return ct;
+}
+
+int corbatext_corbatext(text_t t, corbatext_t_var ct)
+{
+  cout << "A" << endl;
+  corbaconv_text_t::fillUsString(t,&ct->text);
+  cout << "B" << endl;
+  ct->encoding = 0;
+  cout << "C" << endl;
+}
+
+void corbatext_corbaArrayToArray(corbatext_tarray ca, text_tarray *ta)
+{
+  unsigned int i;
+  corbaconv_text_t *cct;
+
+  ta->clear();
+  ta->reserve(ca.length());
+  for (i = 0; i < ca.length(); i ++)
+    {
+      cct = new corbaconv_text_t(ca[i]);
+      ta->push_back(*cct); // cast to text_t
+    }  
+}
+
+void corbatext_arrayToCorbaArray(text_tarray ta, corbatext_tarray *_ca)
+{
+  text_tarray::iterator here = ta.begin();
+  text_tarray::iterator end = ta.end();
+  corbatext_tarray ca(end - here);
+  unsigned int i;
+
+  i = 0;
+  (*_ca).length(end - here);
+
+  while (here != end)
+    {
+      corbatext_t_var ptr;
+      //      cout << "Array: " << (*_ca).maximum() << " " << (*_ca).length() << endl;
+      ptr = corbatext_corbatext(*here);
+      (*_ca)[i] = ptr;
+      here ++;
+      i++;      
+    }
+}
+
+void corbatext_corbaArrayToSet(corbatext_tarray t, text_tset *ts)
+{ unsigned int i;
+ 
+  for (i = 0; i < t.length(); i ++)
+    {
+      ts->insert((corbaconv_text_t) t[i]); // further typecast to text_t
+    } 
+
+  return;
+}
+
+void corbatext_setToCorbaArray(text_tset ts, corbatext_tarray *t)
+{
+  corbatext_t str;
+  text_tset::iterator here = ts.begin();
+  text_tset::iterator end = ts.end();
+  unsigned int i;
+
+  i = 0;
+  while (here != end)
+    {
+      (*t).length(i+1);
+      (*t)[i] = *corbatext_corbatext(*here);
+      here ++;
+      i ++;
+    }
+}
+
+void corbatext_mapToCorbaMap(text_tmap map, corbatext_tmap *cmap)
+{
+  text_tmap::iterator here = map.begin();
+  text_tmap::iterator end  = map.end();
+  unsigned int i = 0;
+
+  while (here != end)
+    {
+      (*cmap).names.length(i+1);
+      (*cmap).values.length(i+1);
+      cmap->names[i] = *corbatext_corbatext((*here).first);
+      cmap->values[i] = *corbatext_corbatext((*here).second);
+      here ++;
+      i ++;
+    }
+}
+
+void corbatext_corbaMapToMap(corbatext_tmap cmap, text_tmap &map)
+{
+  unsigned int i;
+
+  for (i = 0; i < cmap.names.length(); i ++)
+    {
+      map.insert(make_pair(*(new corbaconv_text_t(cmap.names[i])), 
+                           *(new corbaconv_text_t(cmap.values[i])))); // further typecast to text_t
+    }
+}
+
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/CURL.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/CURL.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/CURL.java	(revision 20131)
@@ -0,0 +1,677 @@
+package org.nzdl.gsdl.GsdlCollageApplet;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+/** Examines html pages and extracts all the images and links */
+public class CURL {
+
+    private boolean url_valid = true;
+    private InputStream input = null;
+    private int peek_value = -1;
+    private String buffer = "";
+    private URL url = null;
+    private Vector href_links = null;
+    private Vector src_links = null;
+    private Vector link_links = null;
+    private Vector background_links = null;
+
+    /** Starts processing the given url for images and links
+     *  @param url_str The url to examine */
+    public CURL(String url_str) {
+	href_links = new Vector();
+	src_links = new Vector();
+	link_links = new Vector();
+	background_links = new Vector();
+
+	try {
+	     url = new URL(url_str);
+	     input = url.openStream();
+	     //  int value = 0;
+
+	     //            while ( (value=input.read())!=-1){
+	     //System.err.print((char)value);
+	     //}
+             
+	     //url = new URL(url_str);
+	     //input = url.openStream(); 
+
+	} 
+	catch (MalformedURLException e) {
+          
+	    url_valid = false;
+	} 
+	catch (IOException e) {
+	 
+	    url_valid = false;
+	}
+    }
+
+    /** Checks that a valid connection to the url has been made */
+    public boolean connected_ok()
+    {
+	return url_valid;
+    }
+
+    /** Gets any href links from this url
+     *  @return Vector of href links */
+    public Vector getHrefLinks() {
+	return href_links;
+    }
+    /** Gets any source links from this url
+     *  @return Vector of source links */
+    public Vector getSrcLinks() {
+	return src_links;
+    }
+    /** Gets any other links from this url
+     *  @return Vector of other links */
+    public Vector getLinkLinks() {
+	return link_links;
+    }
+    /** Gets any background links from this url
+     *  @return Vector of background links */
+    public Vector getBackgroundLinks() {
+	return background_links;
+    }
+    
+    /** Gets the url currently being processed */
+    public URL getURL() {
+	return url;
+    }
+    /** Checks that the content of the url is in html */
+    public boolean isHTML() {
+
+         String content_type = guessContentType(url.toString());
+   
+	if(content_type.startsWith("text/html")) {
+	    return true;
+	}
+	return false;
+    }
+    
+    /** Reads a value from the buffer
+     *  @return Value read if successful and -1 if not */
+    public int read() {
+	int value = -1;
+	if(isHTML()) {
+	    if(buffer.length() == 0) {
+		refill();
+	    }
+	    if(buffer.length() != 0) {
+		value = getBuffer();
+	    }
+	} else {
+	    value = getRaw();
+	}
+	return value;
+    }
+    /** Reads the entire URL */
+    public void readAll() {
+	int value;
+	while((value = read()) != -1) {
+	}
+    }
+    
+    // Gets the head of the buffered buffer.
+    private int getBuffer() {
+	if(buffer.length() > 0) {
+	    int value = buffer.charAt(0);
+	    buffer = buffer.substring(1, buffer.length());
+	    return value;
+	} else {
+	    System.err.println("Called getRaw on an empty string");
+	    return -1;
+	}
+    }
+    // Gets the head of the raw buffer.
+    private int getRaw() {
+	int value = -1;
+	if(peek_value != -1) {
+	    value = peek_value;
+	    peek_value = -1;
+	} 
+	else {
+	    try {
+		value = input.read();
+	    } catch (Exception e) {
+		e.printStackTrace();
+	    }
+	}
+	return value;
+    }
+    
+    private int peekRaw() {
+	if(peek_value == -1) {
+	    peek_value = getRaw();
+	}
+	return peek_value;
+    }
+    
+    // Refills the buffered buffer with the next tag or non-tag block
+    // The tag is checked for urls. Note a tag is taken to be < .. > or
+    // < .. < so comments are supported, but comment blocks are still
+    // scanned.
+    private void refill() {
+	int value = getRaw();
+	if(value != -1) {
+           
+	    if(value == '<') {
+		//System.err.println("Parsing a tag starting " + (char)value);
+		// Add opening < to buffer
+		setBuffer(value);
+		String tag = "";
+		value = getRaw();
+		while(value != -1 && peekRaw() != '<' && value != '>') {
+		    //System.err.print((char)value);
+		    tag = tag + (char) value;
+		    value = getRaw();
+		}
+	
+		//System.err.println("Read a " + (char)value);
+		//tag = smartLower(tag);
+		//System.err.println("tag "+tag);
+                tag = findURL(tag);
+		buffer = buffer + tag;
+		// Add closing > to buffer
+		setBuffer(value);
+		//System.err.println("Finished tag");
+	    } else {
+		//System.err.println("Parsing content");
+		//System.err.println("Value = " + value + " = '" + (char)value + "'");
+		while(value != -1 && value != '<') {
+		    //System.err.println("Read a '" + (char)value + "'");
+		    setBuffer(value);
+		    value = getRaw();
+		}
+		// If we've accidently read the '<' push it back in the stream by
+		// setting peek_value to value. Since the peek_value will be returned
+		// on the next read this has the desired effect.
+		if(value == '<') {
+		    peek_value = value;
+		}
+		//System.err.println("Read " + buffer);
+		//System.err.println("Finished Content");
+	    }
+	}
+    }
+    
+    // Sets the tail of the buffered buffer.
+    private void setBuffer(int value) {
+	buffer = buffer + (char) value;
+    }
+    
+    private String smartLower(String tag) {
+	boolean lower = true;
+	String new_tag = "";
+	for(int i = 0; i < tag.length(); i++) {
+				// Disable case lowering for value tags (bound by "")
+	    if (tag.charAt(i) == '"') {
+		if(lower) {
+		    lower = false;
+		} else {
+		    lower = true;
+		}
+	    }
+				// Lower everything else
+	    if(lower) {
+		new_tag = new_tag + Character.toLowerCase(tag.charAt(i));
+	    } else {
+		new_tag = new_tag + tag.charAt(i);
+	    }
+	}
+	return new_tag;
+    }
+    
+    private final static int GROUND           = 0;
+    private final static int COMMENT          = 5;
+    private final static int COMMENT_DASH     = 6;
+    private final static int COMMENT_FINAL    = 7;
+    private final static int H                = 11;
+    private final static int HR               = 12;
+    private final static int HRE              = 13;
+    private final static int HREF             = 14;
+    private final static int HREF_EQUAL       = 15;
+    private final static int HREF_Q           = 16;
+    private final static int HREF_NQ          = 17;
+    private final static int HREF_FINAL       = 18;
+    private final static int S                = 23;
+    private final static int SR               = 24;
+    private final static int SRC              = 25;
+    private final static int SRC_EQUAL        = 26;
+    private final static int SRC_Q            = 27;
+    private final static int SRC_NQ           = 28;
+    private final static int SRC_FINAL        = 29;
+    private final static int L                = 67;
+    private final static int LI               = 68;
+    private final static int LIN              = 69;
+    private final static int LINK             = 70;
+    private final static int LINK_QUOTE       = 72;
+    private final static int LINK_H           = 73;
+    private final static int LINK_HR          = 74;
+    private final static int LINK_HRE         = 75;
+    private final static int LINK_HREF        = 76;
+    private final static int LINK_EQUAL       = 77;
+    private final static int LINK_Q           = 78;
+    private final static int LINK_NQ          = 79;
+    private final static int LINK_FINAL       = 80;
+    private final static int B                = 85;
+    private final static int BA               = 86;
+    private final static int BAC              = 87;
+    private final static int BACK             = 88;
+    private final static int BACKG            = 89;
+    private final static int BACKGR           = 90;
+    private final static int BACKGRO          = 91;
+    private final static int BACKGROU         = 92;
+    private final static int BACKGROUN        = 93;
+    private final static int BACKGROUND       = 94;
+    private final static int BACKGROUND_EQUAL = 95;
+    private final static int BACKGROUND_Q     = 96;
+    private final static int BACKGROUND_NQ    = 97;
+    private final static int BACKGROUND_FINAL = 98;
+    private final static int FINAL            = 99;
+    
+    // Run the finite-state machine on a buffer-load.
+    private String findURL(String tail) {
+	int state = GROUND;
+	String head = "";
+	String url_str = "";
+	// Sift through the tag for urls
+	while(tail.length() > 0 && state != BACKGROUND_FINAL && state != COMMENT_FINAL && state != HREF_FINAL && state != LINK_FINAL && state != SRC_FINAL) {
+	    char ch = tail.charAt(0);
+	    String sch = "" + ch;
+	    sch = sch.toLowerCase();
+	    char lch = sch.charAt(0);
+	    tail = tail.substring(1);
+	    switch (state) {
+		// Initial state.
+	    case GROUND:
+		switch (lch) {
+		case '!': state = COMMENT; break;
+		case 'B': case 'b': state = B; break;
+		case 'H': case 'h': state = H; break;
+		case 'L': case 'l': state = L; break;
+		case 'S': case 's': state = S; break;
+		}
+		head = head + ch;
+		break;
+		// A possible comment
+	    case COMMENT:
+		switch(lch) {
+		case '-': state = COMMENT_DASH; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case COMMENT_DASH:
+		switch(lch) {
+		case '-': state = COMMENT_FINAL; break; // skip comments
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+		// A possible href
+	    case H:
+		switch(lch) {
+		case 'R': case 'r': state = HR; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case HR:
+		switch(lch) {
+		case 'E': case 'e': state = HRE; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case HRE:
+		switch(lch) {
+		case 'F': case 'f': state = HREF; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case HREF:
+		switch(lch) {
+		case ' ': case '\t': case '\n': case '\r': break; // Skip blanks
+		case '=': state = HREF_EQUAL; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case HREF_EQUAL:
+		switch(lch) {
+		case ' ': case '\t': case '\n': case '\r': break; // Skip blanks
+		case '\'': case '\"': state = HREF_Q; break;
+		default: state = HREF_NQ; break;
+		}
+		if(state == HREF_NQ) {
+		    url_str = url_str + ch;
+		} else {
+		    head = head + ch;
+		}
+		break;
+	    case HREF_NQ:
+		switch(lch) {
+		case ' ': case '\t': case '\n': case '\r':
+		    state = HREF_FINAL;
+		    tail = ch + tail;
+		    break;
+		default: url_str = url_str + ch; break;
+		}
+		break;
+	    case HREF_Q:
+		switch(lch) {
+		case '\'': case '\"':
+		    state = HREF_FINAL;
+		    tail = ch + tail;
+		    break;
+		default: url_str = url_str + ch; break;
+		}
+		break;
+		// A possible src
+	    case S:
+		switch(lch) {
+		case 'R': case 'r': state = SR; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case SR:
+		switch(lch) {
+		case 'C': case 'c': state = SRC; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case SRC:
+		switch(lch) {
+		case ' ': case '\t': case '\n': case '\r': break; // Skip blanks
+		case '=': state = SRC_EQUAL; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case SRC_EQUAL:
+		switch(lch) {
+		case ' ': case '\t': case '\n': case '\r': break; // Skip spaces
+		case '\'': case '\"': state = SRC_Q; break;
+		default: state = SRC_NQ; break;
+		}
+		if(state == SRC_NQ) {
+		    url_str = url_str + ch;
+		} else {
+		    head = head + ch;
+		}
+		break;
+	    case SRC_NQ:
+		switch(lch) {
+		case ' ': case '\t': case '\n': case '\r':
+		    state = SRC_FINAL;
+		    tail = ch + tail;
+		    break;
+		default: url_str = url_str + ch; break;
+		}
+		break;
+	    case SRC_Q:
+		switch(lch) {
+		case '\'': case '\"':
+		    state = SRC_FINAL;
+		    tail = ch + tail;
+		    break;
+		default: url_str = url_str + ch; break;
+		}
+		break;
+		// A possible link-src combo
+	    case L:
+		switch(lch) {
+		case 'I': case 'i': state = LI; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case LI:
+		switch(lch) {
+		case 'N': case 'n': state = LIN; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case LIN:
+		switch(lch) {
+		case 'K': case 'k': state = LINK; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case LINK:
+		switch(lch) {
+		case 'H': case 'h': state = LINK_H; break;
+		default: state = LINK; break;
+		}
+		head = head + ch;
+		break;
+	    case LINK_H:
+		switch(lch) {
+		case 'R': case 'r': state = LINK_HR; break;
+		default: state = LINK; break;
+		}
+		head = head + ch;
+		break;
+	    case LINK_HR:
+		switch(lch) {
+		case 'E': case 'e': state = LINK_HRE; break;
+		default: state = LINK; break;
+		}
+		head = head + ch;
+		break;
+	    case LINK_HRE:
+		switch(lch) {
+		case 'F': case 'f': state = LINK_HREF; break;
+		default: state = LINK; break;
+		}
+		head = head + ch;
+		break;
+	    case LINK_HREF:
+		switch(lch) {
+		case ' ': case '\t': case '\n': case '\r': break; // Skip blanks
+		case '=': state = LINK_EQUAL; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case LINK_EQUAL:
+		switch(lch) {
+		case ' ': case '\t': case '\n': case '\r': break; // Skip blanks
+		case '\'': case '\"': state = LINK_Q; break;
+		default: state = LINK_NQ; break;
+		}
+		if(state == LINK_NQ) {
+		    url_str = url_str + ch;
+		} else {
+		    head = head + ch;
+		}
+		break;
+	    case LINK_NQ:
+		switch(lch) {
+		case ' ': case '\t': case '\n': case '\r':
+		    state = LINK_FINAL;
+		    tail = ch + tail;
+		    break;
+		default: url_str = url_str + ch; break;
+		}
+		break;
+	    case LINK_Q:
+		switch(lch) {
+		case '\'': case '\"':
+		    state = LINK_FINAL;
+		    tail = ch + tail;
+		    break;
+		default: url_str = url_str + ch; break;
+		}
+		break;
+		// A possible background
+	    case B:
+		switch(lch) {
+		case 'A': case 'a': state = BA; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case BA:
+		switch(lch) {
+		case 'C': case 'c': state = BAC; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case BAC:
+		switch(lch) {
+		case 'K': case 'k': state = BACK; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case BACK:
+		switch(lch) {
+		case 'G': case 'g': state = BACKG; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case BACKG:
+		switch(lch) {
+		case 'R': case 'r': state = BACKGR; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case BACKGR:
+		switch(lch) {
+		case 'O': case 'o': state = BACKGRO; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case BACKGRO:
+		switch(lch) {
+		case 'U': case 'u': state = BACKGROU; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case BACKGROU:
+		switch(lch) {
+		case 'N': case 'n': state = BACKGROUN; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case BACKGROUN:
+		switch(lch) {
+		case 'D': case 'd': state = BACKGROUND; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case BACKGROUND:
+		switch(lch) {
+		case ' ': case '\t': case '\n': case '\r': break; // Skip blanks
+		case '=': state = BACKGROUND_EQUAL; break;
+		default: state = GROUND; break;
+		}
+		head = head + ch;
+		break;
+	    case BACKGROUND_EQUAL:
+		switch(lch) {
+		case ' ': case '\t': case '\n': case '\r': break; // Skip blanks
+		case '\'': case '\"': state = BACKGROUND_Q; break;
+		default: state = BACKGROUND_NQ; break;
+		}
+		if(state == BACKGROUND_NQ) {
+		    url_str = url_str + ch;
+		} else {
+		    head = head + ch;
+		}
+		break;
+	    case BACKGROUND_NQ:
+		switch(lch) {
+		case ' ': case '\t': case '\n': case '\r':
+		    state = BACKGROUND_FINAL;
+		    tail = ch + tail;
+		    break;
+		default: url_str = url_str + ch; break;
+		}
+		break;
+	    case BACKGROUND_Q:
+		switch(lch) {
+		case '\'': case '\"':
+		    state = BACKGROUND_FINAL;
+		    tail = ch + tail;
+		    break;
+		default: url_str = url_str + ch; break;
+		}
+		break;
+	    }
+	}
+       
+        url_str =   url_str.replaceAll("&amp;","&");
+    
+	if(state == HREF_FINAL ) {
+	    try {
+		URL new_url = new URL(url, url_str);
+		href_links.addElement(new_url);
+	    }
+	    catch (Exception e) {
+		e.printStackTrace();
+	    }
+        }
+
+	if(state == SRC_FINAL ) {
+	    try {
+		URL new_url = new URL(url, url_str);
+		src_links.addElement(new_url);
+	    }
+	    catch (Exception e) {
+		e.printStackTrace();
+	    }
+        }
+
+	if(state == LINK_FINAL ) {
+	    try {
+		URL new_url = new URL(url, url_str);
+		link_links.add(new_url);
+	    }
+	    catch (Exception e) {
+		e.printStackTrace();
+	    }
+        }
+
+	if(state == BACKGROUND_FINAL ) {
+	    try {
+		URL new_url = new URL(url, url_str);
+		background_links.add(new_url);
+	    }
+	    catch (Exception e) {
+		e.printStackTrace();
+	    }
+        }
+
+	return head + url + tail;
+    }
+    
+    static private String guessContentType(String text) {
+	if(text.endsWith("/")) {
+	    return "text/html";
+	} else if (text.endsWith(".html")) {
+	    return "text/html";
+	} else if (text.endsWith(".htm")) {
+	    return "text/html";
+	} else if (text.indexOf("?")>0) {
+	    return "text/html";
+	}
+	return "image/jpeg";
+    }
+    
+}
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/CollageImage.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/CollageImage.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/CollageImage.java	(revision 20131)
@@ -0,0 +1,508 @@
+package org.nzdl.gsdl.GsdlCollageApplet;
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.io.*;
+import java.net.*;
+import java.awt.image.*;
+
+
+/** 
+ *  @author Katrina Edgar
+ *  @author David Bainbridge
+ *
+ *  Data Structure to store an image once it is displayed in the applet.
+ *  This structure remembers the images graphical representation, source url,
+ *  name, width, height, position on the screen and whether or not it has
+ *  previously been displayed. It provides methods to set the dimensions and
+ *  position of the image. It also provides access methods to the translated
+ *  x and y co-ordinates of the image */
+public class CollageImage {
+
+     /** Decrements the alpha value between adjacent rows on the edge of an image<br>
+     *  Used to fade the edges faster than the rest of the image <br>
+     *  Only used when java2 parameter is true and advanced image processing
+     *  techniques may be applied */
+    static final int FADEVALUE = 3;
+
+    /** Defines the shades of white used to colour the backgrounds of white images <br>
+     *  These colours are used because when several white images appear in the collage
+     *  simultaneously it is difficult to distinguish their edges<br>
+     *  Only used when java2 parameter is true and advanced image processing
+     *  techniques may be applied */
+    int colorMask [] = {0xF8FFFF, 0xFFF8FF, 0xFFFFF8, 0xF8F8FF, 0xFFF8F8, 0xF8FFF8, 0xFAFAFA};
+
+      
+    /** Defines the number of shades of white used to colour the backgrounds of white images <br>
+     *  These colours are used because when several white images appear in the collage
+     *  simultaneously it is difficult to distinguish their edges<br>
+     *  Only used when java2 parameter is true and advanced image processing
+     *  techniques may be applied */
+    static final int NO_OF_COLORS = 7;
+
+    /** Will fire a removal operation when 4 images in the collage overlap a single area */
+    static final int NO_IMAGES_OF_OVERLAP = 4;
+
+
+    /** Source url of the image */
+    String from_url_    = null;
+    /** Name of the image */
+    String name_        = null;
+    /** Width of the image */
+    int image_x_dim_    = 0;
+    /** Height of the image */
+    int image_y_dim_    = 0;
+    /** Indicates whether or not the image has been drawn on the applet previously */
+    boolean fresh       = true;
+    
+    URL url_ = null;      
+ 
+    /** Reflects the translation of the image from the origin to its position on the screen */
+    AffineTransform af_ = null;
+    /** Left x co-ordinate */
+    protected int xl_ = 0;
+    /** Top y co-ordinate */
+    protected int yt_ = 0;
+    /** Right x co-ordinate */
+    protected int xr_ = 0;
+    /** Bottom y co-ordinate */
+    protected int yb_ = 0;
+ 
+     /** Refers to applet */
+    GsdlCollageApplet app_ = null;
+
+    boolean isJava2_;
+ 
+    Image image_; 
+   
+    /** Constructs an CollageImage from the three specified parameters
+     *
+     *  @param image The graphical representation of the image
+     *  @param from_url The source url for the image
+     *  @param name The file name of the image */
+    public CollageImage(GsdlCollageApplet app, boolean isJava2, DownloadImages.ImageUrlTriple iutriple)
+    {
+         
+         image_ = iutriple.image();
+	 from_url_ = iutriple.urlString();
+	 name_ = iutriple.name();
+	 url_ =  iutriple.url();
+         
+         isJava2_=isJava2;
+         app_=app;  
+
+	 process();
+    }
+
+    /** Sets the translation for the image from the origin
+     *  And regenerate the image as the scaled version
+     *
+     *  @param af The AffineTransform translation that has been calculated */
+    public void setAffineTransform(MyAffineTransform af, boolean is_java2_)
+    {	
+	image_x_dim_ = (int) (image_x_dim_ * af.scaleX);
+	image_y_dim_ = (int) (image_y_dim_ * af.scaleY);
+        
+	image_ = image_.getScaledInstance(image_x_dim_, image_y_dim_, Image.SCALE_DEFAULT);
+	
+	if (is_java2_) {
+	    af_ = new AffineTransform();
+	    af_.translate(af.translateX, af.translateY);
+	    af_.scale(1.0, 1.0);
+	
+	    calculate_rect();
+	}
+	else {
+	    double trans_x = af.translateX;
+	    double trans_y = af.translateY;
+	    
+	    xl_ = Math.round((float)trans_x);
+	    xr_ = Math.round((float)(trans_x + image_x_dim_)) -1;
+	    yt_ = Math.round((float)trans_y);
+	    yb_ = Math.round((float)(trans_y + image_y_dim_)) -1; 
+	}
+
+    }
+
+    public void expand () {
+	
+	// still expands a little too fast... how to fix this?
+	magnify(new Rectangle((int) (xl_ + (image_x_dim_ * 0.000001)),
+			      (int) (yt_ + (image_y_dim_ * 0.000001)),
+			      (int) (image_x_dim_ * 0.999998),
+			      (int) (image_y_dim_ * 0.999998)));
+	
+    }
+    
+    public void magnify(Rectangle border) {
+	
+	double magX = image_x_dim_/(double)border.width;
+	double magY = image_y_dim_/(double)border.height;
+	int x = border.x + border.width/2;
+	int y = border.y + border.height/2;
+	paintImage(x,y,magX, magY);
+    }
+    
+    public void paintImage(int magCenterX, int magCenterY, double magX, double magY){
+	
+	try {
+	    //Point2D mgp = null;
+	    //mgp = af_.inverseTransform((new Point(magCenterX, magCenterY)),(Point)mgp);
+	    //double x = (mgp.getX()*magX)-mgp.getX();
+	    //double y = (mgp.getY()*magY)-mgp.getY();
+	    //scale(-x,-y, magX, magY);
+	}catch (Exception e) {System.out.println(e); }
+    }
+    
+    public void scale(double magOffsetX, double magOffsetY, double magX, double magY){
+	
+	af_.translate(magOffsetX,magOffsetY);
+	af_.scale(magX, magY);
+    }
+    
+    /** Calculates the new image co-ordinates after translation has occurred */
+    protected void calculate_rect()
+    {
+	double trans_x = af_.getTranslateX();
+	double trans_y = af_.getTranslateY();
+
+	xl_ = Math.round((float)trans_x);
+	xr_ = Math.round((float)(trans_x + image_x_dim_)) -1;
+	yt_ = Math.round((float)trans_y);
+	yb_ = Math.round((float)(trans_y + image_y_dim_)) -1; 
+    }
+
+    /** Determines whether a given co-ordinate is inside this image
+     *
+     *  @param x The x co-ordinate
+     *  @param y The y co-ordinate */
+    public boolean inside(int x, int y)
+    {
+	return ((x>=xl_) && (x<=xr_)) && ((y>=yt_) && (y<=yb_));
+    }
+
+    /** Gets the width of the translated image */
+    public double getX() {
+	return af_.getTranslateX();
+    }
+
+    /** Gets the height of the translated image */
+    public double getY() {
+	return af_.getTranslateY();
+    }
+    
+  
+    /** Fades and colours the image on a pixel-by-pixel basis <br>
+     *  First it grabs the pixels of the entire image and stores them in a 2D array.
+     *  Then a bound is calculated to indicate the point from which edge
+     *  fading should occur. The position of the bound will change in proportion
+     *  to the age of the image so that older images have a larger faded edge.
+     *  The area within the bounds, that forms the center of the image, is processed
+     *  first and faded by a standard alpha value. Then each edge of the image
+     *  is processed separately, creating a gradient fade from the true edge to the
+     *  position of the bound. <br>
+     *  The faded pixel array is then turned into a new image a returned.
+     *
+     *  @param img the image that requires processing
+     *  @param x the x co-ordinate of the image
+     *  @param y the y co-ordinate of the image
+     *  @param w the width of the image
+     *  @param h the height of the image
+     *  @param p the position of the image in the applet (indicates age)
+     *  @param fresh whether the image is being processed for the first time */
+    public int[]  handlepixels(int p) {
+       
+	int h = image_y_dim_;
+	int w = image_x_dim_;       
+	
+	// declare an array to hold the pixels
+	int[] pixels = new int[w * h];
+	// get the pixels of the image into the pixels array
+	PixelGrabber pg = new PixelGrabber(image_, 0, 0, w, h, pixels, 0, w);
+	
+	try {
+	    pg.grabPixels();
+	} catch (InterruptedException e) {
+	    System.err.println("interrupted waiting for pixels!");
+	}
+	
+	    
+	// check for any failures
+	if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
+	    System.err.println("image fetch aborted or errored");
+		
+	}
+	
+   
+	// calculates the bound from which fading should begin
+	double bound = p * 0.01;
+	if (w > h)
+	    bound *= w;
+	else
+	    bound *= h;
+
+	int upperboundheight = h - (int) bound;
+	int upperboundwidth = w - (int) bound;
+	int lowerbound = (int) bound;
+
+      	// loop through every pixel in the picture and handle it
+	for (int j = lowerbound; j < upperboundheight; j++) {
+	    for (int i = lowerbound; i < upperboundwidth; i++) {
+		// width and height: x+i y+j
+		pixels[j * w + i] = handlesinglepixel(pixels[j * w + i], p, fresh, false, 255);
+	    }
+	}
+
+	int fade = 0;
+	int fader = 0;
+	int corealpha = (pixels[(h/2) * w + (w/2)] >> 24) & 0xff;
+	
+	// top edge
+	for (int n = lowerbound; n >= 0; n--) {
+	    fader = corealpha - fade;
+	    if (fader < 0)
+		fader = 0;
+	    
+	    for (int m = 0; m < w; m++){
+		int index = n* w + m;
+		if (index <pixels.length){
+		    pixels[index] = handlesinglepixel(pixels[index], p, fresh, true, fader);
+		    
+		}
+	    }   
+	    
+	    fade+= FADEVALUE;
+	}
+
+	// bottom edge
+	fade = 0;
+	for (int n = upperboundheight; n < h; n++) {
+	    fader = corealpha - fade;
+	    if (fader < 0)
+		fader = 0;
+	    for (int m = 0; m < w; m++){
+		int index = n * w + m;
+		if (index <pixels.length){
+		    pixels[index] = handlesinglepixel(pixels[index], p, fresh, true, fader);
+		    
+		}
+	    }
+	    
+	    fade += FADEVALUE;
+	}
+
+	// left edge
+	fade = 0;
+	for (int n = lowerbound; n >= 0; n--) {
+	    fader = corealpha - fade;
+	    if (fader < 0)
+		fader = 0;
+	    for (int m = 0; m < h; m++) {
+		if ( m < lowerbound && n > m);
+		else if ( m > upperboundheight && n > (h - m));
+		else {
+		    int index = m * w + n;
+                    if (index <pixels.length){
+			pixels[index] = handlesinglepixel(pixels[index], p, fresh, true, fader);
+	
+		    }
+		}
+                   
+	    }
+	    fade += FADEVALUE;    
+	}
+	
+	// right edge
+	fade = 0;
+	for (int n = upperboundwidth; n < w; n++) {
+	    fader = corealpha - fade;
+	    if (fader < 0)
+		fader = 0;
+	    for (int m = 0; m < h; m++) {
+		if ( m < lowerbound && (w - n) > m);
+		else if ( m > upperboundheight && (w - n) > (h - m));
+		else {
+		    int index = m * w + n;
+                    if (index <pixels.length){
+			pixels[index] = handlesinglepixel(pixels[index], p, fresh, true, fader);
+	
+		    }
+		}
+		    
+	    }
+	    
+	    fade += FADEVALUE;
+	}  
+	
+       		// set the pixels of the whole picture to the pixels array
+       	pg.setPixels(0, 0, w, h, pg.getColorModel(), pixels, 0, w);
+
+	image_ =  app_.createImage(new MemoryImageSource(w, h, pixels, 0, w));
+
+	return pixels;
+    }
+
+    
+    /** Adjusts the colour and alpha value of an individual pixel <br>
+     *  If the image is being drawn for the first time, the RGB values are
+     *  extracted. If the pixel is close to white (RGB > 250) then an offwhite
+     *  colour is applied to this pixel.
+     *  This is done because when several white images appear in the collage
+     *  simultaneously it is difficult to distinguish their edges. <br>
+     *  This function also fades the alpha value of the pixel as the image ages.
+     *  The alpha value is more heavily decremented as pixels get closer to the
+     *  edge of the image
+     *
+     *  @param pixel the pixel to manipulate
+     *  @param p the position of the image in collage (representative of age)
+     *  @param fresh indicates whether or not the image is being drawn for the first time
+     *  @param edge indicates whether or not this pixel is near the edge of the image
+     *  @param fade the amount by which to fade this pixel
+     *  @return the adjusted pixel as an int */
+    public int handlesinglepixel(int pixel, int p, boolean fresh, boolean edge, int fade) {
+       	int newpixel = 0;
+
+        //changes the colour of the picture, only when first drawn
+	//and only if the pixel is close to white
+	if (fresh) {
+	    
+	    int red   = (pixel >> 16) & 0xff;
+	    int green = (pixel >>  8) & 0xff;
+	    int blue  = (pixel      ) & 0xff;
+	    
+	    if (red >= 250 && green >= 250 && blue >= 250) {
+		
+		int c = colorMask[((int) (p%NO_OF_COLORS))];
+
+		red = (c >> 16) & 0xff;
+		green = (c >> 8) & 0xff;
+		blue  = (c) & 0xff;
+	    }
+
+	    newpixel |= (red << 16) & 0x00ff0000;
+	    newpixel |= (green << 8) & 0x0000ff00;
+	    newpixel |= blue & 0x000000ff;
+	}
+
+	else {
+	    newpixel |= pixel & 0x00ffffff;
+	}
+
+	int alpha = (pixel >> 24) & 0xff;
+
+	if (edge) {
+	    // fade the edges more...
+	    alpha = fade;
+	}
+	else if (alpha > 10 && !fresh) {
+	    alpha -= 10;
+	}
+	
+	newpixel |= (alpha << 24) & 0xff000000;
+	
+	return (newpixel);
+    }
+
+
+  
+
+    /** Resets the alpha channel of an image so that it appears solid
+     *
+     *  @param img the image to restore
+     *  @param x the x co-ordinate of the image
+     *  @param y the y co-ordinate of the image
+     *  @param w the width of the image
+     *  @param h the height of the image */
+    public void restoreAlpha() {
+       	int h = image_y_dim_;
+	int w = image_x_dim_;       
+
+	// declare an array to hold the pixels
+	int[] pixels = new int[w * h];
+	// get the pixels of the image into the pixels array
+	PixelGrabber pg = new PixelGrabber(image_, 0, 0, w, h, pixels, 0, w);
+	try {
+	    pg.grabPixels();
+	    
+		
+	} catch (InterruptedException e) {
+	    System.err.println("interrupted waiting for pixels!");
+	}
+	
+	
+	// check for any failures
+	if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
+	    System.err.println("image fetch aborted or errored");
+	}
+	
+	
+	    
+	// loop through every pixel in the picture and handle it
+	for (int j = 0; j < h; j++) {
+	    for (int i = 0; i < w; i++) {
+		pixels[j * w + i] |= (255 << 24) & 0xff000000;
+	    }
+	}   
+ 
+	// set the pixels of the whole picture to the pixels array
+	pg.setPixels(0, 0, w, h, pg.getColorModel(), pixels, 0, w);
+
+	image_ =  app_.createImage(new MemoryImageSource(w, h, pixels, 0, w));       
+	
+    }
+    
+    /** Checks whether an image has faded to the point where it must be removed
+     *  from the collage.
+     *
+     *  @param img the image to restore
+     *  @param x the x co-ordinate of the image
+     *  @param y the y co-ordinate of the image
+     *  @param w the width of the image
+     *  @param h the height of the image */
+    public boolean checkFaded (int[] pixels) {
+	int h = image_y_dim_;
+	int w = image_x_dim_;
+
+	// get the alpha value of the middle pixel of the image
+	int corealpha = (pixels[(h/2) * w + (w/2)] >> 24) & 0xff;
+	
+	if (corealpha < 50)
+	    return true;
+	
+	return false;
+	
+    }
+
+    public boolean isValid(){
+	image_x_dim_ = image_.getWidth(app_);
+	image_y_dim_ = image_.getHeight(app_);
+
+	return  (image_x_dim_) >0 && ( image_x_dim_ >0);
+	
+    }
+
+    
+    public void process(){
+
+	// images x and y dimensions
+	image_x_dim_ = image_.getWidth(app_);
+	image_y_dim_ = image_.getHeight(app_);
+	 if (( image_x_dim_ >0) && ( image_x_dim_ >0))
+	     {		
+		 // places and sizes the image
+		 MyAffineTransform af = new MyAffineTransform(image_x_dim_,image_y_dim_);
+		 
+		 // sets location & size of collage image
+		 setAffineTransform(af, isJava2_);
+		 fresh = false;
+		 if (isJava2_ ) {      	 
+		     restoreAlpha(); 
+		 }
+		 	
+	     }
+  
+	
+    }
+
+}	
+
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/Display.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/Display.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/Display.java	(revision 20131)
@@ -0,0 +1,44 @@
+package org.nzdl.gsdl.GsdlCollageApplet;
+
+import java.applet.*;
+import java.awt.*;
+import java.awt.image.*;
+import java.awt.geom.*;
+import java.util.*;
+
+/** 
+ *  @author Katrina Edgar */
+public class Display extends Thread {
+
+    GsdlCollageApplet app_ = null;
+
+     public Display(GsdlCollageApplet app) {
+	super("Display");
+	app_ = app;
+	
+    }
+
+
+    /** Runs display thread by repeatedly calling the next frame,
+     *  waiting for a specified delay period between calls */
+    public void run() {
+	try {
+
+	    System.err.println("Started display thread.");
+
+	    Thread curr_thread = Thread.currentThread();
+	    
+	    while (curr_thread == this) {
+		app_.repaint();
+		// can't make it zero or it hogs the whole processor
+		Thread.sleep(100);
+		curr_thread = Thread.currentThread();
+	    }
+
+	    System.err.println("Stopped display thread.");
+	    
+	} catch (Exception e) {
+	    e.printStackTrace();
+	}
+    }
+}
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/DisplayImages.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/DisplayImages.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/DisplayImages.java	(revision 20131)
@@ -0,0 +1,437 @@
+package org.nzdl.gsdl.GsdlCollageApplet;
+
+import java.applet.*;
+import java.awt.*;
+import java.awt.image.*;
+import java.awt.geom.*;
+import java.util.*;
+
+/** 
+ *  @author Katrina Edgar
+ *  @author David Bainbridge
+ *
+ *  Retrieves images from the download thread, determines an appropriate position
+ *  for thes  images onscreen ensuring maximum whitespace coverage and minimal overlap
+ *  when possible. Draws images using advanced image processing techniques when applicable,
+ *  such as fading the edges of an image and discolouring backgrounds. Also re-uses images
+ *  from those that have previously been displayed, or are aging onscreen, in order to
+ *  to create movement when no new images have been downloaded. */
+public class DisplayImages extends Thread {
+
+
+    /** Will fire a removal operation when 4 images in the collage overlap a single area */
+    static final int NO_IMAGES_OF_OVERLAP = 4;
+    
+    /** To determine if there are several images overlapped, can remove the
+     *  layers underneath to save time in repainting */
+    boolean overlap = false;
+
+    /** Refers to download thread */
+    DownloadImages download_images_ = null;
+
+    /** Refers to applet */
+    GsdlCollageApplet app_ = null;
+
+    /** Applets width on screen */
+    public static int app_x_dim_  = 0;
+
+    /** Applets height on screen */
+    public static int app_y_dim_  = 0;
+    
+    /** Background colour of the applet screen */
+    protected Color bgcolor_        = null;
+
+    /** Indicates whether java2 functionality should be used <br>
+     *  If true will allow advanced image processing techniques to occur, 
+     *  such as fading and colouring using pixel manipulation <br>
+     *  If false, images will maintain an alpha value of 1 (appear solid), 
+     *  newer images will simply be pasted on top of existing images <br> */
+    protected boolean is_java2_     = false;
+
+  
+    /** Holds images currently on display in the applet */
+    protected Vector inuse_    = null;
+    
+     /** Holds images ready to be used */
+    protected Vector inuse_ready_    = null;
+
+    /** Holds previously displayed images for re-use */
+    protected Vector notinuse_ = null;
+   
+    protected Image    screen_buffer_    = null;
+    protected Graphics screen_graphic_   = null;
+    protected Image    finished_buffer_  = null;
+    protected Graphics finished_graphic_ = null;
+ 
+    Thread next_frame_ ;
+
+    String dots[] = new String[]{" ",".","..","...","....",".....","......"};
+    int dots_nums=0;
+    boolean start_paint = false;
+    /** Used to determine where to place new images on the applet to optimize
+     *  whitespace coverage <br>
+     *  A co-ordinate in the applet has a value of zero if it is whitespace,
+     *  one if it is covered by one image, two if it is covered by two images,
+     *  and so on. New images will be placed such that they cover the largest
+     *  area of whitespace (zero valued co-ordinates) */
+    public static int [] [] used_space = null;
+    
+  
+    /**
+     *  Starts the display images thread. Initialises variables using parameters and
+     *  static values. Creates the blank applet screen, initialises the used space
+     *  2D array to indicate that there are no images onscreen
+     *
+     *  @param app the applet to display the images on
+     *  @param download_images thread from which to retrieve downloaded images
+     *  @param is_java2 whether advanced image processing techniques should be used
+     *  @param bgcolor the background colour of the applet screen */
+    public DisplayImages(GsdlCollageApplet app, DownloadImages download_images,
+			 boolean is_java2, Color bgcolor)
+    {
+	super("DisplayImages");
+
+	// parameters saved locally
+	app_             = app;
+	is_java2_        = is_java2;
+	bgcolor_         = bgcolor;
+
+	inuse_    = new Vector();
+      	notinuse_ = new Vector();
+        inuse_ready_ = new Vector();
+	download_images_ = download_images;
+	// sets width and height
+	if (is_java2_)
+	{
+	    app_x_dim_  = app_.getWidth();
+	    app_y_dim_  = app_.getHeight();
+	}
+	else
+	{
+	    app_x_dim_  = 645;
+	    app_y_dim_  = 780;
+	}
+
+	// creates initial screen
+	screen_buffer_ = app_.createImage(app_x_dim_, app_y_dim_); 
+	screen_graphic_ = screen_buffer_.getGraphics();
+	screen_graphic_.setColor(bgcolor_);
+	screen_graphic_.fillRect(0,0,app_x_dim_,app_y_dim_);
+	
+	finished_buffer_  = app_.createImage(app_x_dim_, app_y_dim_);
+	finished_graphic_ = finished_buffer_.getGraphics();
+    
+	// initialises used space array to indicate an empty screen
+	used_space = new int [app_x_dim_][app_y_dim_];	
+	for (int n=0; n < app_x_dim_; n++)
+	    for (int m=0; m < app_y_dim_; m++)
+		used_space[n][m] = 0;
+
+        next_frame_ =  new Thread(new Runnable(){
+                public void run() {
+		  
+		    Thread curr_thread = Thread.currentThread();
+		    
+		    while (curr_thread == next_frame_) {
+			try {	    
+			    Runtime rt = Runtime.getRuntime();
+			    //System.out.println("total: "+rt.totalMemory());
+			    //System.out.println("free:  "+rt.freeMemory());
+			    rt.gc();             
+               		    //System.out.println("**************next frame...");
+			    next_frame();
+			    Thread.sleep(app_. refreshDelay_);
+			   
+			    curr_thread = Thread.currentThread();
+			} catch (Exception e) {
+                            e.printStackTrace(); 
+			    break;
+			}
+		    }
+		    	    
+		   
+		}
+
+
+	    });
+
+	 next_frame_.start();
+
+
+    }
+
+    /** Determines what the user has clicked on in the applet, either an image or whitespace
+     *  @param x the x co-ordinate of the mouse
+     *  @param y the y co-ordinate of the mouse
+     *  @return the image that the user has clicked on or null if the user has clicked whitespace */
+   public CollageImage clickedOnImage(int x, int y)
+    {
+	if (app_.verbosity() > 1)
+	{
+	    System.err.print("Checking for clicked on image: ("+x+","+y+")");
+	}
+
+	
+	// checks from last image down, as last images place will be at the top of the collage
+	for (int i= inuse_.size() - 1; i >= 0; i--)
+	{
+	    CollageImage collage_image = (CollageImage)inuse_.elementAt(i);
+	    if (collage_image.inside(x,y))
+	    {
+		return collage_image;
+	    }
+	}
+	// no image at these co-ordinates, just whitespace
+	return null;
+    }
+
+    /** Generates the images onscreen.
+     *  Loops through the vector of currently displayed images and draws each one in turn.
+     *  If the image is being drawn for the first time, its position will be determined
+     *  and its alpha channel set as solid prior to drawing. <br>
+     *  Drawing of the image will depend on whether or not java2 is enabled. If so then
+     *  the image will be processed so that fading occurs with age, so that the edges 
+     *  fade faster than the rest of the image and so that white images are slightly 
+     *  discoloured to allow distinction. If java2 is not enabled, new images will simply
+     *  be pasted on top of existing images without any special effects occuring<br>
+     *  This function also deletes old images. If java2 is enabled then images are deleted
+     *  once they have faded to a suitably low alpha value. If java2 is not enabled then
+     *  images will be removed once there are greater than 25 images onscreen, to ensure
+     *  the applet cannot be overloaded. */
+    public  void display_collage() 
+    {
+	
+	// if there is nothing new to add
+	if (inuse_.size()==0) return;
+	
+	// otherwise need to re-generate images
+	if (app_.verbosity() >= 2)
+	    {
+		//system.err.println("Regenerating images");
+	    }
+	
+	// get each image currently onscreen inturn
+	for (int i=0; i<inuse_.size();)
+	    {
+		CollageImage collage_image = (CollageImage)inuse_.elementAt(i);
+  
+                if (!collage_image.isValid()){
+		    continue;
+		}	    
+
+                int[] pixels = null;
+		// the first time the image is painted, determine its position and size
+		if (collage_image.fresh == true)
+		    {
+			collage_image.process();
+		    }
+		
+		// advanced image processing may be used
+		if (is_java2_)
+		    {
+			// conducts fading and colouring of image
+			pixels = collage_image.handlepixels(inuse_.size()-i); 
+		    }
+		
+		if (collage_image.fresh) {
+		    collage_image.fresh = false;
+		}
+		
+		
+		// if we remove when images have faded too much
+		if (is_java2_) {
+		    if (collage_image.checkFaded(pixels)|| overlap)
+			{
+			    overlap = false;
+			    
+			    CollageImage removed_image = (CollageImage)inuse_.elementAt(i);
+			    //System.out.println(removed_image.name_ + "is removed");
+			    inuse_.remove(i);
+			    // indicates space for this image is no longer used
+			    for (int n = removed_image.xl_; n < (removed_image.xl_ + removed_image.image_x_dim_); n++)
+				for (int m = removed_image.yt_; m < (removed_image.yt_ + removed_image.image_y_dim_); m++)
+				    if(used_space[n][m] != 0) {
+					used_space[n][m]--;
+					if (used_space[n][m] > NO_IMAGES_OF_OVERLAP)
+					    overlap = true;
+				    }
+			    
+			    // sets the image as fresh and adds it to the vector of images previously seen
+			    removed_image.fresh = true;
+			    notinuse_.addElement(removed_image);
+			}
+		    else{
+			i++;
+		    }
+		}
+		else 
+		    if (inuse_.size() > 25 || overlap) {
+			overlap = false;
+			
+			CollageImage removed_image = (CollageImage)inuse_.elementAt(i);
+			inuse_.remove(i);
+			
+			// indicates space for this image is no longer used
+			for (int n = removed_image.xl_; n < (removed_image.xl_ + removed_image.image_x_dim_); n++)
+			    for (int m = removed_image.yt_; m < (removed_image.yt_ + removed_image.image_y_dim_); m++)
+				if(used_space[n][m] != 0) {
+				    used_space[n][m]--;
+				if (used_space[n][m] > NO_IMAGES_OF_OVERLAP)
+				    overlap = true;
+				}
+			
+			// sets the image as fresh and adds it to the vector of images previously seen
+			removed_image.fresh = true;
+			notinuse_.addElement(removed_image);
+		    }
+		    else{
+			i++;
+		    }    
+		
+	    }
+    }
+    
+  
+    /** Alters the images currently on display in the applet <br>
+     *  Changes are prioritised in the following way:
+     *  1. If there are images that have been downloaded and are yet to be displayed 
+     *  they will be added to the list of images in use. <br>
+     *  2. Otherwise if there are images that have previously been displayed but
+     *  are not currently on the applet screen, re-use one of these images. <br>
+     *  3. Otherwise if there are any images on screen at all, take the oldest and
+     *  repaint it as the newest. <br>
+     *  Then the collage is asked to display and repaint with the new image set. */
+
+     public  void next_frame()
+    {
+	double random = Math.random();
+	
+     
+	 if (inuse_ready_.size() > 0){
+	    int pos = (int) ((inuse_ready_.size() - 1) * random);
+	    CollageImage collage_image = (CollageImage) inuse_ready_.remove(pos);
+	    inuse_.addElement(collage_image);
+ 	}
+	else if (notinuse_.size()>0)
+		{
+		    int position = (int) ((notinuse_.size() - 1) * random);
+		    
+		    CollageImage collage_image = (CollageImage)notinuse_.elementAt(position);
+		    notinuse_.remove(position);
+		    inuse_.addElement(collage_image);
+		    
+		    if (app_.verbosity()>3)
+		    {
+			System.err.println("Re-using an image not on screen");
+		    }
+		}
+	    else{
+		if (app_.verbosity()>=4)
+		    System.err.println("No images in download area");
+	    }
+
+	display_collage();
+	
+    }
+  
+  
+
+    /** Paints the applet on the screen */
+    public void paint(Graphics g)
+    {
+
+	screen_graphic_.setColor(bgcolor_);
+	screen_graphic_.fillRect(0,0,app_x_dim_,app_y_dim_);
+
+	// get each image currently onscreen inturn
+	
+	for (int i=0; i < inuse_.size(); i++)
+	    {
+          
+            CollageImage collage_image =null;
+           try{
+		   collage_image = (CollageImage)inuse_.elementAt(i);
+		   start_paint = true;
+		}
+            catch(Exception e){
+		  System.out.println("exception in paint");					
+              break;
+	     }
+	   // don't paint new images yet
+		if (collage_image.fresh) {
+		  if (app_.verbosity()>=1) {
+			System.err.println("doing nothing...  "+ collage_image.name_ +" is fresh.");
+		   }
+		}
+
+		// advanced image processing may be used
+		else if (is_java2_) {
+		  
+			//the alphacomposite controls the blending of these two images.
+			Graphics2D sg2d = (Graphics2D)screen_graphic_;
+			sg2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
+			sg2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
+					      RenderingHints.VALUE_ANTIALIAS_ON); 
+			collage_image.expand();
+			sg2d.drawImage(collage_image.image_, collage_image.af_, app_);
+		   }
+		// simple image collage
+		else
+		    {			// add the image to the collage
+			
+			screen_graphic_.drawImage(collage_image.image_, 
+						  collage_image.xl_, collage_image.yt_,
+						  collage_image.xr_, collage_image.yb_,
+						  0,0,collage_image.image_x_dim_-1,
+						  collage_image.image_y_dim_-1,  app_);
+	 	    }
+	
+	    }
+	
+        
+	finished_graphic_.drawImage(screen_buffer_,0,0,app_);
+	
+
+	if (finished_buffer_ != null)
+	    {
+		g.drawImage(finished_buffer_, 0, 0, app_);
+		if (!start_paint){
+		    g.setColor(Color.white);
+		    g.setFont(new Font("font",Font.PLAIN+Font.BOLD,30));
+		    g.drawString("Downloading" + dots[(dots_nums++)%dots.length],app_x_dim_/3-20,app_y_dim_/2-2);
+		}
+	    }
+	
+
+    }
+
+    /** Runs display thread by repeatedly calling the next frame,
+     *  waiting for a specified delay period between calls */
+    public void run() {
+	try {
+	    
+	    Thread curr_thread = Thread.currentThread();
+	    
+	    while (curr_thread == this) {
+		if (inuse_ready_.size() >= 1){
+		    Thread.sleep(1000);		    
+		    continue;
+		}    
+		CollageImage collage_image = download_images_.getCollageImage();
+ 	
+		if (collage_image !=null){
+		    inuse_ready_.addElement(collage_image);	
+ 		}
+		curr_thread = Thread.currentThread();
+	    }
+	        
+	} catch (Exception e) {
+	   e.printStackTrace();
+           System.out.println("Display images thread is interrupted");
+	}
+
+	System.out.println("Display images thread stoped");
+          
+    }
+
+}
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/DownloadImages.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/DownloadImages.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/DownloadImages.java	(revision 20131)
@@ -0,0 +1,166 @@
+package org.nzdl.gsdl.GsdlCollageApplet;
+
+import java.awt.*;
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.awt.image.*;
+import java.awt.geom.*;
+
+/** 
+ *  @author Katrina Edgar
+ *  @author David Bainbridge
+ *
+ *  Stores images that are downloaded but have not yet been displayed
+ *  in the applet. Provides methods to add to and remove from this list
+ *  and check it's size. It uses an inner class to store the data for these
+ *  images, comprising of three parts: the image itself, it's source url
+ *  and the name of the image */
+public class DownloadImages {
+
+    /** Data structure to store an image that has been downloaded and is
+     *  waiting to be used. */
+    public class ImageUrlTriple {
+
+	Image image_;
+	String urlString_;
+	String name_;
+        URL url_;
+
+	/** Constructs a downloaded image structure from the given parameters
+	 *  @param image the graphical image
+	 *  @param url the source url for this image
+	 *  @param name the name of the image file */
+	public ImageUrlTriple (Image image, URL url, String urlString, String name)
+	{
+	    image_ = image;
+	    url_ = url;
+            urlString_ = urlString; 
+	    name_ = name;
+	}
+
+	Image image() {
+	    return image_;
+	}
+
+	String urlString() {
+	    return urlString_;
+	}
+
+	String name() {
+	    return name_;
+	}
+
+	URL url(){
+	    return url_;
+	}
+
+    }
+
+   
+    ImageUrlTriple downloaded_image;
+    CollageImage collage_image; 
+
+    /** Refers to applet */
+    GsdlCollageApplet app_ = null;
+    boolean isJava2_;
+    int num_of_downloads = 1;
+    boolean stopDownload;
+
+    MediaTracker tracker_;
+
+    /** Initialises an empty vector to store downloaded images in and sets
+     *  the verbosity for this class */
+    public DownloadImages(GsdlCollageApplet app, int verbosity, boolean isJava2)
+    {
+	
+        app_=app;
+        isJava2_= isJava2;
+    }
+
+    /** Push a new image into the vector of downloaded images
+     *  @param image the graphical image to add
+     *  @param url the source url of the image
+     *  @param name the name of the image to add */
+    public  synchronized int downloadImage(MediaTracker tracker, URL url, String urlString, String name)
+    {
+	
+	tracker_= tracker;
+
+	while (downloaded_image != null ){
+	    System.out.println(Thread.currentThread().getName() + " wait to download..."); 
+	    try{
+		wait();
+	    }
+	    catch(InterruptedException e){
+		return 0;
+	    }
+
+	}
+      
+	Image image = Toolkit.getDefaultToolkit().getImage(url);
+	tracker_.addImage(image,num_of_downloads);
+
+	try{
+	    tracker_.waitForID(num_of_downloads);
+	}
+	catch (InterruptedException e){
+	    notify();
+	    return num_of_downloads;
+	}
+	
+
+	downloaded_image  = new ImageUrlTriple(image,url,urlString,name);
+
+	notify();
+       
+	return num_of_downloads ;
+    }
+ 
+ 
+    /** Remove the image from the specified position in the array of downloaded images
+     *  @return an ImageUrlTriple containing the image, url and image name */
+    public synchronized CollageImage getCollageImage()
+    {
+	if (stopDownload)  return null;   
+
+	while (downloaded_image == null){
+	    System.out.println(Thread.currentThread().getName() + " wait to get Collage image...");
+	    try{
+		wait();
+	    }
+	    catch(InterruptedException e){
+		//e.printStackTrace();
+		downloaded_image = null;
+		notify();
+		return null;
+	    }
+	}
+         
+      	if (tracker_.statusID(num_of_downloads, false) == MediaTracker.COMPLETE){
+	    collage_image = new CollageImage(app_,isJava2_,downloaded_image);
+	    downloaded_image = null; 
+	    num_of_downloads++;
+	    notify();
+	    return collage_image;
+	}
+	else{
+	    if ((tracker_.statusAll(false) & MediaTracker.ERRORED) != 0){
+		//System.out.println(downloaded_image.name_);
+		downloaded_image = null;
+		num_of_downloads++;
+		notify();
+		return null;
+	    }
+	}
+	
+	return null;
+
+    }
+
+    public void stopDownload(){
+        stopDownload = true;
+    }
+
+ 
+}
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/DownloadUrls.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/DownloadUrls.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/DownloadUrls.java	(revision 20131)
@@ -0,0 +1,596 @@
+package org.nzdl.gsdl.GsdlCollageApplet;
+
+import java.awt.*;
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import javax.swing.ImageIcon; //****
+
+
+/** 
+ *  @author Katrina Edgar
+ *  @author David Bainbridge
+ *
+ *  Controls retrieval of images from the specified starting url. Follows appropriate
+ *  links from this starting point, traversing in a tree-like state through several other
+ *  pages. Filters images and links based on specified parameters. Also controls the quantity
+ *  of downloading that occurs by restricting the number of downloaded images that are yet to
+ *  be displayed to 10, and the total number of downloads allowed is also restricted by
+ *  the applet application (to prevent downloading occuring infinitely). */
+
+public class DownloadUrls extends Thread {
+
+    /** Refers to applet */
+    GsdlCollageApplet app_          = null;
+    /** Refers to download thread */
+    DownloadImages download_images_ = null;
+
+    /** The address from which the application should start looking for images */
+    String starting_url_  = null;
+
+    /** the root directory of Greenstone*/  
+    String document_root_ = null;
+
+
+    /** CHRIS - Holds the contents of the collection's assoc directory */
+    //    File[] assocDir_ = null;
+
+    /** Restricts links followed from the starting url to links that contain this string */
+    String href_musthave_ = null;
+    /** Restricts links followed from the starting url to links that do not contain this string. 
+     *  Also prevents image names from containing this string */
+    String image_mustnothave_ = null;
+    /** Ignore images whose names begin with this string */
+    String image_ignore_  = null;
+    /** Restricts the types of images included in the collage, for example jpg, gif, etc. */
+    String image_type_ = null;
+
+    /** A static delay used when attempting to download more images into a full downloading buffer */
+    final int delay_       = 3000;
+    /** The maximum number of images to have downloaded and not yet displayed */ 
+    final int buffer_size_ = 1;
+
+    /** Used in cases where the image maps to a url outside of it's original location.
+     *  When used with Greenstone the collage images will refer to documents in the collections
+     *  from which the images are sourced. When used individually, the images may be saved into
+     *  a user directory and the pages they reference may be external hyperlinks. */
+    Hashtable external_links_ = null;
+
+    /** Records all urls which have already been examined */
+    Hashtable visited_url_  = null;
+    /** Determines whether there are still pages to examine and images to download */
+    boolean thread_running_ = true;
+
+    int verbosity_ = 0;
+
+     /** Records all images which have already been examined */
+    Hashtable visited_images_  = null;
+        
+    MediaTracker tracker;
+
+    /** Constructor to initialise a download thread from which images are found, 
+     *  saves parameters into local variables for use within the class.
+     *
+     *  @param app reference to the applet
+     *  @param download_images class which stores the images retrieved in triplets
+     *  @param starting_url the url from which the search for images should begin
+     *  @param href_musthave restricts links to only those containing this string
+     *  @param image_mustnothave restricts links and image names to only those that don't contain this string
+     *  @param image_ignore restricts the beginning of image names
+     *  @param image_type restricts the type of images included in the collage to those named */
+    public DownloadUrls(GsdlCollageApplet app, 
+			DownloadImages download_images, String starting_url, 
+			String href_musthave, String image_mustnothave, 
+			String image_ignore, String image_type, String document_root,int verbosity, MediaTracker trk)
+    {
+	super("DownloadUrls");
+	app_             = app;
+	download_images_ = download_images;
+
+	starting_url_  = starting_url;
+	href_musthave_ = href_musthave;
+	image_mustnothave_ = image_mustnothave;
+	image_ignore_  = image_ignore;
+	image_type_    = image_type;
+	document_root_ = document_root; 
+	verbosity_ = verbosity;
+        tracker = trk;
+
+	System.err.println("starting_url_ "  + starting_url +"\n"+
+	                   "href_musthave_ " +  href_musthave +"\n"+
+			   "image_mustnothave_ " + image_mustnothave+"\n"+
+			   "image_ignore_ "+  image_ignore+"\n"+
+			   "image_type_ "+ image_type+"\n"+
+			   "document root "+ document_root_
+			       );
+
+
+
+
+    }
+
+  
+    /** Determines whether or not a url has already been examined
+     *
+     *  @param url_string the url to check
+     *  @return true if the url has been visited, false if not */
+    public boolean already_visited(String url_string)
+    {
+	int hash_pos = url_string.indexOf("#");
+	if (hash_pos>0)
+	 {
+	     // strip off #anchor reference
+	     url_string = url_string.substring(0,hash_pos);
+	 }
+
+      	// if the url has been visited before, return true
+	if (visited_url_.containsKey(url_string))
+	{
+	    if (verbosity_ > 3)
+		{
+		    System.err.println("Visited " + url_string + " before!");
+		}
+	    return true;
+	}
+	
+	visited_url_.put(url_string,"visited");
+
+	return false;
+    }
+
+  /** Determines whether or not an images or its screenview has been visited)
+     *  has already been examined
+     *
+     *  @param url_string the url to check
+     *  @param img_name the image to check
+     *  @return true if the url has been visited, false if not */
+    public boolean image_visited(String url_string, String img_name)
+    {
+	String hash_dir = url_string.substring(0,url_string.lastIndexOf("/"));  
+    
+ 	if ( visited_images_.containsKey(hash_dir)){
+	    Hashtable hashed_images = (Hashtable)visited_images_.get(hash_dir);   
+	   
+            if (img_name.startsWith("screenview")){
+		return true;
+	    }
+
+	    if (hashed_images.containsKey(img_name)){
+		return true;
+	    }
+         
+            Enumeration enu = hashed_images.keys();
+            for(;enu.hasMoreElements();){
+		String name = (String)enu.nextElement();
+		if(name.startsWith("screenview")){
+		    return true;
+		}
+	    }
+    
+            hashed_images.put(img_name,"visited");           
+	}
+	else{
+	    Hashtable hashed_images = new Hashtable();
+	    hashed_images.put(img_name,"visited");
+	    visited_images_.put(hash_dir,hashed_images);	    
+	}
+	     
+	return false;
+    }
+
+   
+
+
+
+    /** Restricts the type of images that can be included in the collage
+     *
+     * @param url_string the url to check
+     * @return true if the image is of a specified type, false if not */
+    public boolean image_file_extension(String url_string)
+    {
+	// lower case comparisons
+	String url_lstring = url_string.toLowerCase();
+
+	if (image_type_ == null)
+	    return true;
+
+	String tmp = image_type_;
+	String original_image_type_ = image_type_;
+
+	while (image_type_ != null && image_type_.indexOf("%") >= 0) {
+	    
+	    tmp = image_type_.substring(0, image_type_.indexOf("%"));
+             
+	    if (image_type_.length() > image_type_.indexOf("%") + 1)
+		image_type_ = image_type_.substring(image_type_.indexOf("%") + 1, image_type_.length());                 
+	    else
+		image_type_ = null;
+            
+	    if (!tmp.trim().equals("") && url_lstring.endsWith(tmp)) {
+		image_type_ = original_image_type_;
+		return true;
+	    }
+	}
+
+	if (image_type_ != null && url_lstring.endsWith(image_type_)) {
+		image_type_ = original_image_type_;
+		return true;
+	}
+
+	image_type_ = original_image_type_;
+	return false;
+    }
+
+    /** Restricts images to only those that satisfy several specified conditions
+     *  regarding the content of the image name and url.
+     *
+     *  @param url_string the url to check
+     *  @return true if the image is satisfactory, false if not */
+    public boolean filter_image(String url_string)
+    {
+        
+	if (image_ignore_==null || !url_string.startsWith(image_ignore_))
+	{
+	    if (!already_visited(url_string))
+	    {
+		if (image_mustnothave_ != null) {
+		    
+		    String tmp = image_mustnothave_;
+		    String original_image_mustnothave_ = image_mustnothave_;
+
+		    while (image_mustnothave_ != null && image_mustnothave_.indexOf("%") >= 0) {
+	    
+			tmp = image_mustnothave_.substring(0, image_mustnothave_.indexOf("%"));
+			if (image_mustnothave_.length() > image_mustnothave_.indexOf("%") + 1)
+			    image_mustnothave_ = image_mustnothave_.substring(image_mustnothave_.indexOf("%") + 1, 
+									      image_mustnothave_.length());
+			else
+			    image_mustnothave_ = null;
+                          			
+                     
+                         
+			if (!tmp.trim().equals("") && url_string.indexOf(tmp) >= 0) {
+			   
+			    image_mustnothave_ = original_image_mustnothave_;
+			    return false;
+			}
+       		    }
+
+		    image_mustnothave_ = original_image_mustnothave_;
+                    
+		    if (image_mustnothave_ != null && url_string.indexOf(image_mustnothave_) >= 0) {
+			image_mustnothave_ = original_image_mustnothave_;
+			return false;
+		    }
+
+		    if (verbosity_ > 2) {
+			System.err.println("src url = "+ url_string);
+		    }
+		    
+		    image_mustnothave_ = original_image_mustnothave_;
+		    
+		}
+	
+	    }
+            
+	}
+    
+	return true;
+    }
+
+    /** Restricts links to only those that satisfy several specified conditions
+     *  regarding the address of the link.
+     *
+     *  @param url_string the url to check
+     *  @param new_url_string the url from which this link was found
+     *  @param depth the number of links followed on this path
+     *  @return true if the image is satisfactory, false if not */
+    public boolean filter_href(String url_string, String new_url_string, int depth)
+    {
+	boolean has_href = false;
+	String tmp = href_musthave_;
+	String original_href_musthave_ = href_musthave_;
+
+	// checks that it does contain this content
+	if (href_musthave_ !=  null) {
+
+	    while (href_musthave_ != null && href_musthave_.indexOf("%") >= 0) {
+		
+		tmp = href_musthave_.substring(0, href_musthave_.indexOf("%"));
+		if (href_musthave_.length() > href_musthave_.indexOf("%") + 1)
+		    href_musthave_ = href_musthave_.substring(href_musthave_.indexOf("%") + 1, href_musthave_.length());
+		else
+		    href_musthave_ = null;
+		
+		if (url_string.indexOf(tmp) >= 0)
+		    has_href = true;
+	    }
+	    
+	    if (href_musthave_ != null && url_string.indexOf(href_musthave_) >= 0)
+		has_href = true;
+
+	    href_musthave_ = original_href_musthave_;
+	}
+
+	tmp = image_mustnothave_;
+	String original_image_mustnothave_ = image_mustnothave_;
+
+	// checks that it doesn't contain this content
+	if (image_mustnothave_ != null) {
+
+	    while (image_mustnothave_ != null && image_mustnothave_.indexOf("%") >= 0) {
+		
+		tmp = image_mustnothave_.substring(0, image_mustnothave_.indexOf("%"));
+		if (image_mustnothave_.length() > image_mustnothave_.indexOf("%") + 1)
+		    image_mustnothave_ = image_mustnothave_.substring(image_mustnothave_.indexOf("%") + 1, image_mustnothave_.length());
+		else
+		    image_mustnothave_ = null;
+		
+		if (url_string.indexOf(tmp) >= 0)
+		    has_href = false;
+	    }
+	    if (image_mustnothave_ != null && url_string.indexOf(image_mustnothave_) >= 0)
+		has_href = false;
+	  
+	    image_mustnothave_ = original_image_mustnothave_;
+	}
+
+	// return true if the link is valid and false if not
+	if (href_musthave_==null || has_href)
+	{
+	    // might be another URL
+	    if (depth < app_.maxDepth())
+	    {
+		if (!new_url_string.startsWith(url_string))
+		{
+		    return true;
+		}
+	    }
+	}
+	return false;
+    }
+
+    /** Adds an image to the stored downloaded images as a triplet.
+     *  Ensures that the number of images downloaded but not displayed at
+     *  any one time is controlled by using a buffer. If the buffer is
+     *  full this function will wait until space becomes available before
+     *  continuing. It also restricts the
+     *  total number of images to download as specified by the applet.
+     *
+     *  @param url the image to download
+     *  @param from_url the url that this image was sourced from
+     *  @param img_name the name of the image */
+    public void add_image(URL url, String from_url, String img_name)
+    {
+	    // get the image from the url
+	    if (verbosity_>=2) {
+		System.err.println("  Downloading image URL: " + url.toString());
+	    }
+            
+           if (image_visited(url.toString(),img_name)) return;
+
+	   int size = download_images_.downloadImage(tracker,url, from_url, img_name);
+          
+	   try{
+	       // if have completed the maximum number of downloads for the
+	       // application then stop
+	       if (size == app_.maxDownloads()) {
+		   stop();
+	       }
+	       
+	   }
+	   catch (Exception e) {
+	       thread_running_ = false;
+	       stop();
+	       e.printStackTrace();
+	   }
+    }
+
+    /** Connects to the starting url and looks for all images and links from this
+     *  original page. Image links are processed first, so that any images found can be
+     *  downloaded immediately and placed on the applet. Secondly, the links to other
+     *  pages are recursively processed by this function and treated as a starting url
+     *
+     *  @param new_url the url from which to start searching for images and links
+     *  @param depth the number of links that have been followed on this path */
+    public void rec_add_images(String new_url, int depth)
+    {
+   
+	if (already_visited(new_url)) return;
+
+	// check if there is a scenario where external hyperlinks are being used
+	externalLinks();
+	String img_name = new String();
+
+	// connect to the url
+	CURL curl = new CURL(new_url);
+	if (curl.connected_ok())
+	{
+	    if (verbosity_ >= 1) {
+		System.err.print("Connected OK ... ");
+	    }
+
+	    // read the page
+	    curl.readAll();
+	    if (verbosity_ >= 1) {
+		System.err.println("URL read.");
+	    }
+
+	    // get all the <code><img src=</code> links into a vector
+	    Vector src_links = curl.getSrcLinks();
+
+        	    
+	    if (verbosity_ >= 2) {
+		System.err.println("  Got src links... there are " + src_links.size() + " of them.");
+	    }
+	    // process each of the image links according to the parameters given.
+	    for (int i = 0; i < src_links.size(); i++) 
+	    {
+		URL url = (URL)src_links.get(i);
+		String url_string  = url.toString();
+            
+		//System.err.println(" source links " + i + " ["  + url_string +"]");
+
+		if (verbosity_ >= 4) {
+		    System.err.println("    Unfiltered: src_link[" + i + "] = " + url_string);
+		}
+
+		if (image_file_extension(url_string))
+		    {
+			if (filter_image(url_string))
+			    {
+				img_name = url_string.substring(url_string.lastIndexOf("/") + 1, url_string.length());
+                                
+				if (verbosity_ >= 2) {
+				    System.err.println("    Filtered: src_link[" + i + "] = " + url_string);
+				}
+
+				if ((external_links_ != null) && (!external_links_.isEmpty())) {
+				    String ext = (String) external_links_.get(img_name);
+				          
+				           
+				    if (ext != null){
+					add_image(url, ext, img_name);
+                                       
+				    }
+				    else{
+				
+					add_image(url, new_url, img_name);
+				    }
+				}
+				else {
+				    
+				    add_image(url, new_url, img_name);
+				}
+                           
+				
+			    }
+		
+		    }
+		
+	    }
+
+	    // get all the <code><a href=</code> links into a vector
+	    Vector href_links = curl.getHrefLinks();
+	    
+	  
+	    if (verbosity_ >= 2) {
+		System.err.println("  Got href links... there are " + href_links.size() + " of them.");
+	    }
+	    
+
+	    // process each of the href links according to the parameters given.
+	    for (int i = 0; i < href_links.size(); i++) 
+		{
+           
+		    URL url = (URL)href_links.get(i);
+		    String url_string  = url.toString();
+		    //System.err.println(" href links " + i + "["  + url_string +"]");      
+
+		    if (image_file_extension(url_string))
+			{
+			                      
+			    if (filter_image(url_string))
+
+				{
+				 					    
+				    img_name = url_string.substring(url_string.lastIndexOf("/") + 1, url_string.length());
+
+				    if ((external_links_ != null) && (!external_links_.isEmpty())) {
+					String ext = (String) external_links_.get(img_name);
+
+					if (ext != null) 
+					    add_image(url, ext, img_name);
+					else
+					    add_image(url, new_url, img_name);
+				    }
+				    else {
+					add_image(url, url_string, img_name);
+				    }
+				}
+			}
+		    else
+			{
+			    if (filter_href(url_string,new_url,depth))
+				{
+		
+				    rec_add_images(url_string,depth+1);
+				    
+				}
+			}
+		}
+	}
+   
+	else {
+	    System.err.println("Unable able to download "+new_url);
+	}
+    }
+
+    
+    /** Used in cases where the image maps to a url outside of it's original location.
+     *  When used with Greenstone the collage images will refer to documents in the collections
+     *  from which the images are sourced. When used individually, the images may be saved into
+     *  a user directory and the pages they reference may be external hyperlinks. 
+     *  This function reads that external links file and creates a hash map of the image to
+     *  its external hyperlink. If the file does not exist the download thread will continue
+     *  and assume the first case, that links are internal. */
+    public void externalLinks() {
+	external_links_ = null;
+	try {
+
+	    if (starting_url_ == null || (document_root_ != null && starting_url_.indexOf(document_root_) >= 0) ){ 
+		return;
+	    }
+	    
+	    // open a url to the file written
+	    URL u = new URL(starting_url_ + "externallinks");
+
+	    BufferedReader r = new BufferedReader(new InputStreamReader(u.openStream()));
+	    
+	    external_links_ = new Hashtable();
+
+	    String l = r.readLine();
+	    // split the line of the space, first part is the image, second part the link
+	    while (l != null) {
+	
+		String tmp1 = new String();
+		String tmp2 = new String();
+
+		if (l.indexOf(" ") >= 0) {
+		    
+		    tmp1 = l.substring(0, l.indexOf(" "));
+		    if (l.length() > l.indexOf(" ") + 1)
+			tmp2 = l.substring(l.indexOf(" ") + 1, l.length());
+		    else
+			tmp2 = null;
+		    
+		    if (tmp2 != null) {
+			
+			external_links_.put(tmp1, tmp2);
+			//System.err.println(tmp1 + " " + tmp2);
+		    }
+		}
+		l = r.readLine();
+	    }
+		
+		r.close();
+
+	} catch (Exception e) {
+	    e.printStackTrace();
+	    return;
+	}
+    }
+
+    /** Controls the download thread */
+    public void run () 
+    {
+	System.err.println("Starting download thread.");
+	visited_url_ = new Hashtable();
+	visited_images_ = new Hashtable();
+
+       	rec_add_images(starting_url_,1);
+	download_images_.stopDownload();
+	System.err.println("Download thread finished.");
+    }
+}
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/GsdlCollageApplet.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/GsdlCollageApplet.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/GsdlCollageApplet.java	(revision 20131)
@@ -0,0 +1,406 @@
+package org.nzdl.gsdl.GsdlCollageApplet;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.net.*;
+
+/**
+ * 
+ *  @author Katrina Edgar
+ *  @author David Bainbridge
+ *
+ * Main class for the GsdlCollageApplet<br>
+ * Processes the parameters passed through the Applet<br>
+ * Builds an appropriate starting url from these parameters<br>
+ * Creates a storage class for downloaded images<br>
+ * Starts thread to download images and their associated url<br>
+ * Starts thread to display downloaded images on the applet screen<br>
+ */
+ 
+public class GsdlCollageApplet extends Applet {
+
+
+    /** Amount of error checking output produced <br>
+     *  Ranges from 0 - no output to 3 - maximum output */ 
+    protected int verbosity_     = 0;
+    /** Indicates whether java2 functionality should be used <br>
+     *  If true will allow advanced image processing techniques to occur, 
+     *  such as fading and colouring using pixel manipulation <br>
+     *  If false, images will maintain an alpha value of 1 (appear solid), 
+     *  newer images will simply be pasted on top of existing images <br> */
+    protected boolean isJava2_  = true;
+    /** Number of nested links to follow When used with greenstone,
+     *  controls to which level of the document links will be followed For
+     *  example a maximum depth of 1 will mean only the top page of a
+     *  document will be examined, while a depth of 2 will include sections
+     *  within this document, 3 includes sections within sections, and so
+     *  on */
+    protected int maxDepth_     = 3;
+
+    /** Maximum number of images to display on the canvas */
+    protected int maxDisplay_ = 25;
+
+    /** Maximum number of downloaded images to store <br> Prevents applet
+     *  from using excessive amounts of bandwidth by downloading too many
+     *  images simulataneously*/
+    protected int maxDownloads_ = Integer.MAX_VALUE;
+
+    /** Types of images permitted in the collage, for example gif, jpg,
+     * png... */
+    protected String imageType_ = ".jpg%.png";
+
+    /** Caption of the collage */
+    protected String caption_ = "";
+
+    /** Background color of applet screen */
+    protected Color bgcolor_ = new Color(150, 193, 155);
+
+    /** Time lapse between repainting of the applet */
+    protected int refreshDelay_ = 2000;
+    
+    /** Stores an image and url pair and provides associated methods */
+    protected DownloadImages download_images_ = null;
+    /** Downloads images from a starting url, recursively follows nested
+     * links */
+    protected DownloadUrls download_thread_   = null;
+    /** Image processing and placement on applet screen */
+    protected DisplayImages display_thread_   = null;
+
+   
+
+    /** Gets verbosity */
+    public int verbosity()    { return verbosity_; }
+    /** Gets maximum depth for nested links */
+    public int maxDepth()     { return maxDepth_; }
+
+    /** Gets maximum number of images to display */
+    public int maxDisplay() { return maxDisplay_;}
+
+    /** Gets maximum number of images to store during downloading */
+    public int maxDownloads() { return maxDownloads_; }
+    /** Gets the refresh delay used between repaint */
+    public int refreshDelay() { return refreshDelay_; }
+
+    /** Gets parameters from the applet code and stores locally.
+     * Forms a starting url for image retrieval to begin from.
+     * The starting url is formed either by:
+     *  * Using the image_url parameter as provided, which is assumed to 
+     *     be a complete url
+     *  * If this parameter does not exist, the assumption is that the 
+     *     collage is being incorporated with the Greenstone Digital Library 
+     *     Software. The starting url is formed by concatenating
+     *     the gwcgi, collection and classifier parameters as provided.
+     * Then starts downloading and displaying images */
+
+    Thread paint ;
+
+    public void init() 
+    {	    
+	if (verbosity_ >= 4) { 
+	    System.err.println("Attempting to retrieve parameters...");
+	}
+
+	// gets the parameters specified
+	String verbosity_param      = getParameter("verbosity");
+	String is_java2_param       = getParameter("isJava2");
+	String max_depth_param      = getParameter("maxDepth");
+	String max_downloads_param  = getParameter("maxDownloads");
+	String max_display_param    = getParameter("maxDisplay");
+	String refresh_delay_param  = getParameter("refreshDelay");
+	String image_type_param     = getParameter("imageType");
+	String bgcolor_param        = getParameter("bgcolor");
+	String caption_param        = getParameter("caption");
+        String document_root        = getParameter("documentroot");
+        String gwcgi                = getParameter("gwcgi");        
+
+
+	// Check it isn't null
+	if ((verbosity_param!=null) && (!verbosity_param.startsWith("_"))) {
+	    verbosity_  = Integer.parseInt(verbosity_param);
+	}
+	else {
+	    verbosity_ = 1;
+	}
+
+
+	if (verbosity_ >= 4) { 
+	    System.err.println("Got parameters.");
+	}
+
+	if (caption_param != null && !caption_param.startsWith("_")) {
+	    caption_ = caption_param;
+	}
+	else {
+	    if (verbosity_ >= 4) { 
+		System.err.println("No Caption: setting to a space.");
+	    }
+	    caption_ = " ";
+	}
+
+	if ((bgcolor_param != null) && (!bgcolor_param.startsWith("_"))) {
+	    if (bgcolor_param.startsWith("#")) {
+		bgcolor_ = Color.decode(bgcolor_param);   
+	    }
+	    else {
+		String [] c = bgcolor_param.split(",");
+		if (c.length == 3)
+		    bgcolor_ = new Color(Integer.parseInt(c[0]), Integer.parseInt(c[1]), Integer.parseInt(c[2]));
+	    }
+	    if (verbosity_ >= 4){ 
+		System.err.println("Set BG to be " + bgcolor_.toString());
+	    }
+	}
+	else {
+	    if (verbosity_ >= 4) { 
+		System.err.println("No BG: setting to NZDL green.");
+	    }	   
+	    bgcolor_ = new Color(150, 193, 155);
+	}
+
+	if ((image_type_param != null) && (!image_type_param.startsWith("_"))) {
+	    imageType_ = image_type_param;
+	}
+
+	if ((is_java2_param == null) || (is_java2_param.equals("auto")) || (is_java2_param.startsWith("_"))) {
+	    String version = System.getProperty("java.version");
+	    version = version.substring(0, version.lastIndexOf("."));
+	    System.err.println("VERSION: " + version);
+	    float ver = (new Float(version)).floatValue();
+	    isJava2_ = (ver >= 1.2) ? true : false;
+	}
+	else {
+	    isJava2_ = (is_java2_param.equals("true")) ? true : false;
+	}
+
+	if ((max_depth_param != null) && (!max_depth_param.startsWith("_"))) {
+	    // System.err.println("maxDepth = " + max_depth_param);
+	    maxDepth_ = Integer.parseInt(max_depth_param);
+	}
+
+	if ((max_downloads_param!=null) && (!max_downloads_param.startsWith("_"))) {
+	    maxDownloads_ = Integer.parseInt(max_downloads_param);
+            System.out.println(" maxDownloads " + maxDownloads_ );
+	    maxDownloads_=50;
+	}
+
+	if ((max_display_param!=null) && (!max_display_param.startsWith("_"))) {
+	    maxDisplay_ = Integer.parseInt(max_display_param);
+              
+	}
+
+	if ((refresh_delay_param!=null) && (!refresh_delay_param.startsWith("_"))) {
+	    refreshDelay_ = Integer.parseInt(refresh_delay_param);
+	}
+
+       
+        if (document_root !=null){          
+	    document_root = document_root.substring(1);
+            if (document_root.indexOf("/") > 0 ){
+		document_root = document_root.substring(0, document_root.indexOf("/"));
+	    }
+	    else{
+		document_root = gwcgi; 	
+	    }
+	}
+
+
+	String image_url  = getParameter("imageURL"); 
+	String image_ignore  = getParameter("imageIgnorePrefix"); 
+	String href_musthave  = getParameter("hrefMustHave"); 
+	String image_mustnothave = getParameter("imageMustNotHave");
+
+	// builds starting url when incorporated with Greenstone
+	if (image_url==null)
+	{
+	    String gwcgi_param  = getParameter("gwcgi");
+	    gwcgi_param = tidy_URL(gwcgi_param, true);
+	
+	    String collection_param  = getParameter("collection");
+	    String classifier_param  = getParameter("classifier");
+
+	    image_url = gwcgi_param + "a=d";
+	    image_url += "&c=" + collection_param;
+	    image_url += "&cl=" + classifier_param;
+	}
+
+	MediaTracker trk = new  MediaTracker(this);
+
+	// creates a class to store the image and it's associated url
+	download_images_ = new DownloadImages( this, verbosity_,isJava2_ );
+	// starts the download image thread with the starting url
+
+        download_thread_ = new DownloadUrls(this, download_images_, 
+					    image_url, href_musthave, image_mustnothave, 
+					    image_ignore, imageType_,document_root,verbosity_,trk);
+	// starts the display image thread with the currently downloaded images
+	display_thread_ = new DisplayImages(this, download_images_,isJava2_, bgcolor_);
+	
+    }
+
+ 
+    /** Goes to the url associated with the image that is clicked on screen<br>
+     *  Displays the url containing the image in a new window */
+    public boolean mouseDown(Event event, int x, int y)
+    {
+	// determines which image was clicked on
+	CollageImage cimage = display_thread_.clickedOnImage(x,y);
+	// if they were clicking on an image (as opposed to background)
+	if (cimage != null)
+	{
+	    System.err.println("Click on image: from url = " + cimage.from_url_);
+	    try {
+		// displays the associated url in a new window
+                URL from_url = null;		
+		
+		java.util.regex.Pattern p = java.util.regex.Pattern.compile("cl=CL\\d(\\.\\d)*\\s");
+		java.util.regex.Matcher m = p.matcher(cimage.from_url_.trim()+" ");
+
+                if (m.find() ){
+		    from_url = cimage.url_;
+		}
+		else{
+		    from_url =  new URL(cimage.from_url_  + "#" + cimage.name_);
+		}
+		getAppletContext().showDocument(from_url,"gsdlDoc");
+	    } 
+	    catch (MalformedURLException e) { 
+		e.printStackTrace();
+	    }
+
+	}
+        return true;
+    }
+    
+    /** Start threads for downloading and displaying images */
+    public void start() 
+    {
+	
+	download_thread_.start();	
+
+	display_thread_.start();
+
+         paint =  new Thread(new Runnable(){
+                public void run() {
+		    try {
+
+			Thread curr_thread = Thread.currentThread();
+	    
+			while (curr_thread == paint) {
+	      
+			   repaint();
+			    
+			    Thread.sleep(2000);
+			    curr_thread = Thread.currentThread();
+			}
+
+	    
+		    } catch (Exception e) {
+			
+		    }
+		}
+
+
+	    });
+
+	    paint.start();
+   
+    }
+
+    /** Stops threads for downloading and displaying images */
+    public void stop() 
+    {
+	download_thread_.stop();
+	display_thread_.stop();
+	
+	download_thread_ = null;
+	display_thread_ = null;
+	
+    }
+
+    /** Destroys threads for downloading and displaying images */
+    public void destroyed() 
+    {
+	download_thread_ = null;
+	
+	display_thread_ = null;
+	
+    }
+
+
+    /** Repaints the applet */
+    public void update(Graphics g) 
+    { 
+	// System.err.println("Update called");
+	paint(g); 
+    } 
+    
+    /** Repaints the applet using the paint method of the thread that is
+     * currently displaying images */
+    public void paint(Graphics g) {
+	if (display_thread_!=null)
+	    {	
+	      
+	    	//display_thread_.display_collage();
+	    	  display_thread_.paint(g);
+	    }
+	else
+	    {
+		System.err.println("Applet still trying to paint!!");
+	    }
+
+	
+	
+    }
+
+  
+    
+    /** Ensures a URL address (as string) has a protocol, host, and file.
+     *
+     * If the URL is a CGI script URL, it should be tidied up so that it is
+     * appropriate to tage attrib=value pairs on the end.  This means it
+     * must either end with a "?" or (if it contains a question-mark
+     * internally) end with a "&". */
+    String tidy_URL(String address, boolean isCGI) {
+
+	// System.err.println("tidy URL: " + address);
+	
+	// make sure the URL has protocol, host, and file
+	if (address.startsWith("http")) {
+	    // the address has all the necessary components
+	} else if (address.startsWith("/")) {
+	    // there is not protocol and host
+	    URL document = getDocumentBase();
+	    String port = "";
+	    if (document.getPort()!=-1) {
+		port = ":" + document.getPort();
+	    }
+	    address = "http://" + document.getHost() + port  + address;
+	} else {
+	    // this URL is relative to the directory the document is in
+	    URL document = getDocumentBase();
+	    String directory = document.getFile();
+	    int end = directory.lastIndexOf('/');
+	    String port = "";
+	    if (document.getPort()!=-1) {
+		port = ":" + document.getPort();
+	    }
+	    directory = directory.substring(0,end + 1);
+	    address = "http://" + document.getHost() + port + directory + address;
+
+	}
+
+	// if the URL is a cgi script, make sure it has a "?" in ti,
+	// and that it ends with a "?" or "&"
+	if (isCGI) {
+	    if (address.indexOf((int) '?') == -1) { 
+		address = address + "?";
+	    } else if (!address.endsWith("?")) {
+		address = address + "&";
+	    }
+	}
+
+	return address;
+    }
+
+
+}
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/Makefile
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/Makefile	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/Makefile	(revision 20131)
@@ -0,0 +1,20 @@
+
+
+
+CLASSES = CURL.class CollageImage.class DisplayImages.class \
+          DownloadImages.class DownloadUrls.class GsdlCollageApplet.class \
+          MyAffineTransform.class
+
+all: GsdlCollageApplet.jar
+
+install:
+	cp GsdlCollageApplet.jar ../../../../../../../web/java/
+
+clean:
+	rm -f $(CLASSES) GsdlCollageApplet.jar
+
+GsdlCollageApplet.jar: $(CLASSES)
+	jar cf GsdlCollageApplet.jar org
+
+%.class : %.java
+	javac -d . -classpath ../../../.. $<
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/MyAffineTransform.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/MyAffineTransform.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/GsdlCollageApplet/MyAffineTransform.java	(revision 20131)
@@ -0,0 +1,154 @@
+package org.nzdl.gsdl.GsdlCollageApplet;
+
+public class MyAffineTransform {
+
+    public double scaleX = 0;
+    public double scaleY = 0;
+    public double translateX = 0;
+    public double translateY = 0;
+    public boolean overlap = false;
+
+    public MyAffineTransform (int image_x_dim, int image_y_dim) {
+
+	random_set_pos(image_x_dim, image_y_dim);
+    }
+
+    /** The amount to adjust the size of an image so that it fits into the applet screen
+     *  @param image_x_dim the width of the image to scale
+     *  @param image_y_dim the height of the image to scale
+     *  @return a value by which to scale the image to ensure it will fit in the applet */
+    private double scaleFactor (int image_x_dim, int image_y_dim) {
+
+	double scale_factor = 1.0;
+
+	// three quarters of the application width & height
+	int tol_app_x_dim = 3*DisplayImages.app_x_dim_/4;
+	int tol_app_y_dim = 3*DisplayImages.app_y_dim_/4;
+
+	// if the image is too big, calculate a fraction
+	// by which to reduce the image
+	if (image_x_dim>tol_app_x_dim)
+	{
+	    scale_factor = image_x_dim/tol_app_x_dim + 1;
+	}
+
+	if (image_y_dim>tol_app_y_dim)
+	{
+	    int y_scale_factor = image_y_dim/tol_app_y_dim + 1;
+	    // take the biggest of the two as the same fraction must
+	    // be applied to both the x and y values to keep the image
+	    // in proportion
+	    if (y_scale_factor>scale_factor)
+	    {
+		scale_factor = y_scale_factor;
+	    }
+	}
+
+	return scale_factor;
+    }
+
+    /** Determines the placement of new images on the applet screen <br>
+     *  First the image is scaled, then the function loops until a satisfactory
+     *  image position is found. This is done by randomly selecting an x and y
+     *  co-ordinate for the image, then determining how much whitespace will be
+     *  covered if the image were to be placed at this position in the collage.
+     *  The standards for loop termination are as follows:<br>
+     *  1. On any occasion a whitespace coverage of greater than 70% will result 
+     *  in the loop being terminated.<br>
+     *  2. After three times through the loop, a whitespace coverage of 50% will
+     *  also allow the loop to terminate (a less stringent condition). <br>
+     *  3. After seven times through, the loop will terminate and the best
+     *  position will be used by default.<br>
+     *  This function also updates the used space array after image position has been selected.
+     *  
+     *  @param image_x_dim the width of the image
+     *  @param image_y_dim the height of the image
+     *  @return a transform operation by which to move the image from the origin */
+    protected void random_set_pos(int image_x_dim, int image_y_dim) 
+    {
+
+	double scale_factor = scaleFactor(image_x_dim, image_y_dim);
+
+	// scale the image (will be 1 and therefore no change as a default)
+	image_x_dim/=scale_factor;
+	image_y_dim/=scale_factor;
+	
+	// initialise variables required to determine image placement
+	int image_x_pos = 0;
+	int image_y_pos = 0;
+	int best_x = 0;
+	int best_y = 0;
+	double best_clear = 0;
+	double clear = 100;
+	int stoploop = 0;
+	
+	do {
+	    // increment the loop counter
+	    stoploop++;
+
+	    // the number of positions that the image could occupy on the x axis
+	    int safe_x_dim = DisplayImages.app_x_dim_ - image_x_dim;
+	    double rx = Math.random();
+	    // randomly pick an x co-ordinate for the image
+	    image_x_pos= ((int)(rx*safe_x_dim));
+	    
+	    // same process as for the x co-ordinate
+	    // ensuring the y co-ordinate will fit on the screen
+	    int safe_y_dim = DisplayImages.app_y_dim_ - image_y_dim;
+	    double ry = Math.random();
+	    // randomly pick a y co-ordinate for the image
+	    image_y_pos= ((int)(ry*safe_y_dim));
+	    
+	    double whitespace = 0;
+	    double space = 0;
+	    
+	    // determine how much whitespace the image will cover if placed in the
+	    // current position and how much overlap will occur
+	    for (int n = image_x_pos; n < (image_x_pos + image_x_dim); n++) {
+		for (int m = image_y_pos; m < (image_y_pos + image_y_dim); m++) {
+		    if (DisplayImages.used_space[n][m] == 0)
+			whitespace++;
+		    space++;
+		}
+	    }
+	    
+	    // divide the amount of whitespace covered by the amount of overlap
+	    clear = whitespace/space;
+	    // if this value is better than previous calculations, save these co-ordinates
+	    if (clear > best_clear) {
+		best_x = image_x_pos;
+		best_y = image_y_pos;
+		best_clear = clear;
+	    }
+
+	    if ((image_x_dim > (DisplayImages.app_x_dim_ / 2)) || (image_y_dim > (DisplayImages.app_y_dim_ / 2)))
+		break;
+
+	} while ((clear < 0.70 || (stoploop > 3 && clear < 0.50)) && stoploop < 7);
+	    
+	// if we only terminated because we went through so many times,
+	// then we set the position to the best value possible
+	if (stoploop == 7) {
+	    image_x_pos = best_x;
+	    image_y_pos = best_y;
+	}
+
+	// indicate that the space where the image is to be placed is now used
+	for (int n = image_x_pos; n < (image_x_pos + image_x_dim); n++)
+	    for (int m = image_y_pos; m < (image_y_pos + image_y_dim); m++) {
+		DisplayImages.used_space[n][m]++;
+		if (DisplayImages.used_space[n][m] > DisplayImages.NO_IMAGES_OF_OVERLAP)
+		    overlap = true;
+	    }
+	
+	translateX = image_x_pos;
+	translateY = image_y_pos;
+	
+	// scale the image appropriately
+	scaleX = 1.0/scale_factor;
+	scaleY = 1.0/scale_factor;
+	
+	return;
+    }
+
+}
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/Makefile
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/Makefile	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/Makefile	(revision 20131)
@@ -0,0 +1,21 @@
+
+
+
+CLASSES = Phind.class ResultCanvas.class ResultItemDocument.class \
+          ResultTitle.class PhindTitle.class ResultDisplay.class \
+          ResultItemLink.class ResultBox.class ResultItem.class \
+          ResultItemPhrase.class PhindTitle.class URLUTF8Encoder.class
+
+all: Phind.jar
+
+install:
+	cp Phind.jar ../../../../../../../web/java/
+
+clean:
+	rm -f $(CLASSES) Phind.jar
+
+Phind.jar: $(CLASSES)
+	jar cf Phind.jar org
+
+%.class : %.java
+	javac -target 1.1 -d . -classpath ../../../.. $<
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/Phind.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/Phind.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/Phind.java	(revision 20131)
@@ -0,0 +1,1119 @@
+/**********************************************************************
+ *
+ * Phind.java -- the Phind java applet
+ *
+ * Copyright 1997-2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+/*********************************************************************
+
+To use the applet, you'll need to embed it in a web page like this:
+
+<APPLET CODE="Phind.class" WIDTH=500 HEIGHT=500>
+
+  <PARAM NAME=collection  VALUE="fao.org">
+  <PARAM NAME=classifier  VALUE="1">
+  <PARAM NAME=phindcgi    VALUE="http://kowhai/cgi-bin/phindcgi">
+  <PARAM NAME=library     VALUE="http://kowhai/cgi-bin/library">
+  <PARAM NAME=backdrop    VALUE="http://kowhai/~paynter/transfer/phindtest/green1.jpg">
+  The Phind java applet.
+</APPLET>
+
+There are a bunch of other parameters; these are described in the 
+getParameters method below.  It is all done for you in Greenstone
+in the document.dm macro file (the _phindapplet_ macro).
+
+You may have problems with Java applet security.  Java applet's can only
+open socket connections (including the HTTP connections the applet uses 
+to get data) to the same server the applet was loaded from.  This means
+that your phindcgi, library, and (optional) backdrop URLs must be on the
+same machine that your web page was loaded from.
+
+**********************************************************************
+
+The applet comprises several classes:
+
+1. Phind (this file) is the applet class, loaded by the browser.
+   It also handles network connections.
+2. ResultDisplay is a Panel that sits in the applet and displays 
+   things; displays are connected in a doubly-linked list.
+3. ResultBox holds the results of a query.  Result boxes are shown
+   to the user through ResultDisplays.  Another doubly-linked list.
+4. ResultTitle acts as a caption to a ResultBox describing its contents.
+5. ResultCanvas is what the ResultBox data is drawn on.  It draws the
+   words on the screen, and handles user input from the mouse.
+6. ResultItem represents a single result object (a phrase or document).
+7. PhindTitle is for drawing backdrops in ResultDisplays.
+
+**********************************************************************/
+
+package org.nzdl.gsdl.Phind;
+
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Choice;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Event;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.awt.Image;
+import java.awt.Label;
+import java.awt.Panel;
+import java.awt.TextField;
+
+import java.net.URL;
+import java.net.URLConnection;
+import java.io.DataInputStream;
+import java.io.InputStream;
+
+import java.net.Socket;
+//import java.net.SocketTimeoutException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+import java.util.Vector;
+import java.util.Date;
+
+import org.nzdl.gsdl.Phind.URLUTF8Encoder;
+
+public class Phind extends java.applet.Applet {
+    
+    // What is the collection called?
+    public String collection;
+
+    // Which phind classifier are we using? (There may be more than one.)
+    public String classifier;
+
+    // Internet address of phind resources
+    public String library_address, phindcgi_address;
+
+    // Initial serach term
+    public String initialSearch;
+
+    // Number of phrases to retrieve at any one time
+    public int phraseBlockSize;
+
+    // Appearance parameters
+    public boolean vertical;
+    public int depth;
+
+    // Font
+    public int fontSize;
+    public String fontName;
+    public Font plainFont, boldFont;
+
+    // Do we want a background image in the applet?
+    public boolean showImage;
+    public String backdrop_address;
+    public Image backgroundImage;
+    public boolean showBorder;
+
+    // Colours
+    public Color panel_fg, panel_bg,
+	column_1_fg, column_1_bg, 
+	column_2_fg, column_2_bg,
+	highlight_fg, highlight_bg,
+	thesaurus_fg, thesaurus_bg, thesaurus_bar_fg, thesaurus_bar_bg,
+	expansion_fg, expansion_bg, expansion_bar_fg, expansion_bar_bg,
+	document_fg, document_bg, document_bar_fg, document_bar_bg,
+	message_fg, message_bg;
+    
+    // Column dimensions
+    int column_1_width, column_2_width;
+
+    // Where do we open new windows
+    String searchWindowName, documentWindowName;
+
+    // the mode of operation
+    int mode;
+    final int initMode = 0;
+    final int idleMode = 1;
+    final int searchMode = 2;
+
+    // Elements of the control panel
+    boolean showControlPanel;
+    Label titleLabel;
+    TextField wordField;
+    Button searchButton, prevButton, nextButton;
+
+    // Holders for the downloaded data
+    Panel resultPanel;
+    ResultDisplay firstDisplay, lastDisplay;
+
+    // The time at which the last query finished
+    Date lastQueryEndTime;
+
+    // lastQueryEndTime is stored to ensure a 1 second gap between a query
+    // returning and a new one beginning.  It is needed because the FAO
+    // folks in Rome have a huge lag, and frquently click several times
+    // while they wait; these clicks are turned into new queries, which
+    // they await again.  It is no elegant solution, but it seems like the
+    // easiest, given that I don't know threads.
+    // 1. The search button is easy to disable, and is disabled when a
+    //    socket connection is in progress.
+    // 2. ResutCanvas widgets can'r be similarly disabled because the
+    //    browser hides or wipes them, which looks very bad.
+    // 3. I cannot just ignore clicks on canvasses because the browser
+    //    caches the clicks while the socket connection is going on, and then
+    //    sends them through afterwards, when the canvas is accepting clicks
+    //    again.
+    // 4. Current sequence of events is to record the time the last query
+    //    ends, then whenever a click happens make sure a second has past.  if
+    //    you double-click the the first query is sent, returns, end-tie is
+    //    set, and the second (and any others made during query time) is
+    //    *immediately* processed, but since 1 second hasn't past it is
+    //    ignored.
+
+    /** We're adding a timeout to the loop used to read the result from the
+     *  server - partially because of the 'fails to return anything' death
+     *  spiral - but also because its a good idea anyway. Why DataInputStream
+     *  doesn't have a TimeOutException, given its most often used to get data
+     *  from a URL, I don't know. Lets default it to 60 seconds.
+     *  DLConsulting 12-07-2004
+     */
+    private int timeout = 60;
+
+    public String getAppletInfo() {
+	return "Phind by Gordon Paynter (paynter@cs.waikato.ac.nz). Copyright 1997-2000.";
+    }
+
+
+    public void init() {
+
+	mode = initMode;
+	
+        System.out.println("Java vendor: " + System.getProperty("java.vendor"));
+        System.out.println("Java version: " + System.getProperty("java.version"));
+
+	// Read applet parameters
+	getParameters();
+
+	// Initialise the user interface
+	setBackground(panel_bg);
+	lastQueryEndTime = new Date();
+
+	// fonts used to output text
+	plainFont = new Font(fontName, Font.PLAIN, fontSize);
+	boldFont  = new Font(fontName, Font.BOLD, fontSize);
+
+	// The phind applet layout manager
+	setLayout(new BorderLayout());
+
+	// Panel containing the displays is in the center of the display
+	resultPanel = new Panel();
+	if (vertical) {
+	    resultPanel.setLayout(new GridLayout(depth,1,0,2));
+	} else {
+	    System.out.println("horizontal");
+	    resultPanel.setLayout(new GridLayout(1,depth,2,0));
+	}
+	add("Center", resultPanel);
+
+	// Create ResultDisplays and place into the interface
+	ResultDisplay d1, d2 = null;
+	firstDisplay = new ResultDisplay(this, null);
+	resultPanel.add(firstDisplay);
+
+	if (depth == 1) {
+	    lastDisplay = firstDisplay;
+	} else {
+	    d1 = firstDisplay;
+	    for (int i = 2; i <= depth; i++) {
+		d2 = new ResultDisplay(this, d1);
+		resultPanel.add(d2);
+		d1 = d2;
+	    }
+	    lastDisplay = d2;
+	}
+
+	// The control panel
+	initialiseControlPanel();
+
+	// lets get started then
+	setStatus("Welcome to Phind.");
+	mode = idleMode;
+
+	// Perform initial search, if requested
+	if (initialSearch.length() > 0) {
+	    searchForWord(initialSearch);
+	}
+    }
+
+
+    // Display a message in the status bar
+    void setStatus(String status) {
+	showStatus(status);
+    }
+
+    // The user performs an action in the interface
+    public boolean action(Event evt, Object arg) {
+
+	if (evt.target == searchButton) {
+	    searchForWord(getSearchTerm());
+	} else if (evt.target == wordField) {
+	    searchForWord(getSearchTerm());
+	} else if (evt.target == prevButton) {
+	    shiftPrevious();
+	} else if (evt.target == nextButton) {
+	    shiftNext();
+	} else {
+	    System.out.println("unknown action: " + evt.toString() 
+			       + ", object: " + arg.toString());
+	}
+	return true;
+    }
+
+
+    // Search for a word 
+    //
+    // Called on two occasions:
+    //   when the "Search" Button is pressed, or
+    //   to perform an "initial search"
+    void searchForWord(String searchWord) {
+
+	if (mode == idleMode) {
+	    
+	    setSearchTerm(searchWord);
+
+	    // Convert the String from UTF8 charaters into 
+	    // an encoding that is okay for a URL.
+	    searchWord = URLUTF8Encoder.encode(searchWord);
+
+	    // Look up the word
+	    if (searchWord.length() > 1) {
+		setStatus("searching for \"" + searchWord + "\""); 
+		firstDisplay.emptyContents();
+		ResultBox result = lookupPhraseOnServer(null, false, searchWord, searchWord, 2);
+
+		// if there is an error, return
+		if (result == null) {
+		    setStatus("No results for \"" + searchWord + "\""); 
+		    return;
+		}
+
+		// display the result
+		result.display = firstDisplay.display(result);
+		result.resize(result.display.size());
+		result.paintAll(result.getGraphics());
+	    }
+
+	    enablePreviousAndNext();
+	}
+    }
+  
+
+    // Search for a phrase
+    //
+    // If querymode is 2, the user has clicked on a phrase.
+    // If querymode is 3, the user has requested more phrases.
+    // If querymode is 4, the user has requested more documents.
+    void searchForPhrase(ResultBox source, String key, String phrase, int queryMode) {
+
+	// System.out.println("searchForPhrase: " + key + " " + phrase + " " + queryMode);
+
+	if (mode == idleMode) {
+
+	    // If we are going to replace the first ResultDisplay, then empty it
+	    if (queryMode <= 2) {
+		if (source.display.next != null) source.display.next.emptyContents();
+	    }
+
+	    // look up the word
+	    setStatus("Searching for \"" + phrase + "\""); 
+	    ResultBox result = lookupPhraseOnServer(source, true, key, phrase, queryMode);
+	    if (result == null) {
+		setStatus("No result for \"" + phrase + "\""); 
+		return;
+	    }
+
+	    // If this is not already displayed, display it in the last free spot
+	    if (queryMode <= 2) {
+		result.display = lastDisplay.display(result);
+		result.resize(result.display.size());
+		result.paintAll(result.getGraphics());
+	    }
+
+	    enablePreviousAndNext();
+	}
+    }
+
+
+    // Look up a phrase (or symbol) on the server
+    //
+    // Arguments are the source of the query (a ResultBox, or null if the
+    // query comes from hitting the search button), the key to search for
+    // (the text of a phrase or a symbol number), the phrase as a string, 
+    // and the query mode.
+    // Query modes are: 
+    //   0 = obsolete
+    //   1 = obsolete
+    //   2 = get first N phrases and URLs,
+    //   3 = get another N phrases into same window
+    //   4 = get another N documents into same window
+    //   5 = get another N thesaurus links into same window
+
+    ResultBox lookupPhraseOnServer(ResultBox source, 
+				   boolean keyKnown, String key, String phrase, 
+				   int queryMode) { 
+    	disableSearchButton();
+	mode = searchMode;
+	ResultBox r = null;
+
+	if (queryMode <= 2) {
+	    r = new ResultBox(this, collection, key, phrase, source);
+	} else if ((queryMode == 3) || (queryMode == 4) || (queryMode == 5)) {
+	    r = source;
+	}
+
+	try { 
+	    queryServer(keyKnown, key, queryMode, r);
+	} catch (Exception e) { 
+	    System.out.println("Phind query error: " + e.toString());
+	    setStatus("Query error: " + e.toString());
+	    mode = idleMode;
+	    enableSearchButton();
+	    return null;
+	}
+      
+	// The query is finished
+	setStatus(r.c.numberOfItems + " results for \"" + phrase + "\""); 
+	mode = idleMode;
+	enableSearchButton();
+	lastQueryEndTime = new Date();
+
+	return r;
+    }
+
+
+    // Query the phindcgi program
+    //
+    // Send a query (a word or symbol number) to the server
+    // and pass the response to a ResultBox.
+
+    void queryServer(boolean keyKnown, String word, int queryMode, ResultBox area) 
+	throws IOException {
+
+	// Build the query
+	String query = phindcgi_address + "pxml=1&c=" + collection + "&pc=" + classifier;
+
+	if (keyKnown) {
+	  query = query + "&ppnum=" + word;
+	} else {
+	  query = query + "&pptext=" + word;
+	}
+
+	
+	// Specify the set of results to return 
+	int first_e = 0;
+	int last_e = 0;
+	int first_d = 0;
+	int last_d = 0;
+	int first_l = 0;
+	int last_l = 0;
+
+	// the initial query
+	if (queryMode <= 2) {
+	  last_e = phraseBlockSize;
+	  last_d = phraseBlockSize;
+	  last_l = phraseBlockSize;
+	}
+
+	// add phrases to an existing result set
+	else if (queryMode == 3) {
+	  first_e = area.nextPhraseBlock * phraseBlockSize;
+	  area.nextPhraseBlock++;
+	  last_e = area.nextPhraseBlock * phraseBlockSize;
+	} 
+	
+	// add documents to existing result set
+	else if (queryMode == 4) {
+	  first_d = area.nextDocumentBlock * phraseBlockSize;
+	  area.nextDocumentBlock++;
+	  last_d = area.nextDocumentBlock * phraseBlockSize;
+	}
+
+	// add thesaurus links to existing result set
+	else if (queryMode == 5) {
+	  first_l = area.nextThesaurusLinkBlock * phraseBlockSize;
+	  area.nextThesaurusLinkBlock++;
+	  last_l = area.nextThesaurusLinkBlock * phraseBlockSize;
+	}
+
+	query = query + "&pfe=" + first_e + "&ple=" + last_e
+                      + "&pfd=" + first_d + "&pld=" + last_d
+                      + "&pfl=" + first_l + "&pll=" + last_l;
+
+	// Send the query to the phindcgi program 
+	System.out.println("sending query: " + query);
+	/** Start timeout counter.
+	 *  DLConsulting 12-07-2004
+	 */
+	int time = 0;
+	try {
+	    URL phindcgi = new URL(query);
+            //            DataInputStream in = new DataInputStream(phindcgi.openStream());
+
+            URLConnection conn = phindcgi.openConnection();
+            DataInputStream in = new DataInputStream(conn.getInputStream());
+
+	    byte[] buffer;
+	    int availableBytes = 0;
+
+	    
+	    while (!area.finished) {
+		// Lovely old method, which would work just fine if Sun supported their own API and made
+		// in.available() work.
+
+		/*
+		availableBytes = in.available();
+		if (availableBytes == 0) {
+		    // if i had threads i'd do a wait here for 1 second
+		    /** Ah-ha but we do have threads here - at least one thread 
+		     *  anyway! Note that we want to prevent interrupted 
+		     *  exceptions flinging us out of the read loop.
+		     *  We also check that the time count hasn't reached out
+		     *  timeout threshold yet. If so, make use of the nifty
+		     *  execption handling.
+		     *  DLConsulting 12-07-2004
+		     *  Start...
+		     
+                    System.err.println("No bytes available");
+		    if(time >= timeout) {
+			throw new InterruptedIOException(
+			    "No data recieved in " + time + 
+			    " seconds. Connection timed-out.");
+		    }
+		    try {
+			Thread.sleep(1000);
+		    }
+		    catch(InterruptedException exception) {
+			System.err.println("Unexpected InterruptedException. Non-fatal.");
+			exception.printStackTrace();
+		    }
+		    time++;
+		    /** ...End 
+		} else {
+                    System.err.println("Preparing to read " + availableBytes + " bytes");
+		    buffer = new byte[availableBytes];
+		    in.read(buffer);
+                    System.err.println("Done reading");
+		    area.parseBytes(buffer);
+		}
+		*/
+
+		// New - and hopefully safer - method.
+
+		// Create a new SafeReader, and then wait while it reads
+		// we can watch for timeouts as necessary
+		int timeout = 0;
+		SafeReader reader = new SafeReader(in);
+		reader.start();
+		while(!reader.isComplete()) {
+		    // Wait timeout time.
+		    try {
+			Thread.sleep(1000);
+		    }
+		    catch(InterruptedException exception) {
+			System.err.println("test.init(): Unexpected InterruptedException. Non-fatal.");
+			exception.printStackTrace();
+		    }
+		    // Then see if the readers read anything
+		    if(reader.poll() == 0) {
+			timeout++;
+			// Have we reached timeout?
+			if(timeout > reader.getTimeout()) {
+			    // Nothing been read. Kill the reader
+			    reader.interrupt();
+			    // And throw a hissy fit
+			    throw new InterruptedIOException("No data recieved in " + reader.getTimeout() + 
+							     " seconds. Connection timed-out.");
+			}
+			// Otherwise, wait a little longer.
+		    }
+		    // Otherwise we can continue waiting and polling
+		}
+		// Process the buffer
+		System.err.println("Done reading");
+		area.parseBytes(reader.getBuffer());
+            }
+	    
+	    in.close();
+	} catch (Exception e) {
+	    System.err.println( "Error sending query to phindcgi: " + e);
+	}
+	area.repaint();
+    }
+    
+
+    // Tidy up URLs
+    //
+    // Ensure a URL address (as string) has a protocol, host, and file.
+    //
+    // If the URL is a CGI script URL, it should be tidied up so that it is
+    // appropriate to tage attrib=value pairs on the end.  This means it
+    // must either end with a "?" or (if it contains a question-mark
+    // internally) end with a "&".
+    String tidy_URL(String address, boolean isCGI) {
+
+	// System.err.println("tidy URL: " + address);
+	
+	// make sure the URL has protocol, host, and file
+	if (address.startsWith("http")) {
+	    // the address has all the necessary components
+	} else if (address.startsWith("/")) {
+	    // there is no protocol and host
+	    URL document = getDocumentBase();
+	    String protocol = document.getProtocol();
+	    String host = document.getHost();
+	    String port = "";
+	    if (document.getPort()!=-1) {
+		port = ":" + document.getPort();
+	    }
+	    address = protocol + "://" + host + port + address;
+	} else {
+	    // this URL is relative to the directory the document is in
+	    URL document = getDocumentBase();
+	    String protocol = document.getProtocol();
+	    String host = document.getHost();
+	    String directory = document.getFile();
+	    int end = directory.lastIndexOf('/');
+	    String port = "";
+	    if (document.getPort() != -1) {
+		port = ":" + document.getPort();
+	    }
+	    directory = directory.substring(0, end + 1);
+	    address = protocol + "://" + host + port + directory + address;
+	}
+
+	// if the URL is a cgi script, make sure it has a "?" in it,
+	// and that it ends with a "?" or "&"
+	if (isCGI) {
+	    if (address.indexOf((int) '?') == -1) { 
+		address = address + "?";
+	    } else if (!address.endsWith("?")) {
+		address = address + "&";
+	    }
+	}
+
+	return address;
+    }
+
+
+
+    // Open an arbitrary web page
+    void displayWebPage(String address, String window) {
+	try { 
+	    URL url= new URL(address);
+	    if (window.length() > 0) {
+		getAppletContext().showDocument(url, window);
+	    } else {
+		getAppletContext().showDocument(url);
+	    }
+	} catch (Exception e) { 
+	    System.out.println("Cannot open web page: " + e.toString());
+	}
+    }
+
+
+    // Get the applet parameters
+    void getParameters() {
+
+	// What is this collection called?
+	collection = parameterValue("collection");
+	System.out.println("Phind collection: " + collection);
+
+	// Which of the collection's classifiers are we using?
+	classifier = parameterValue("classifier", "1");
+	System.out.println("Phind classifier: " + classifier);
+
+	// Where is the phind CGI script
+	phindcgi_address = parameterValue("phindcgi");
+	phindcgi_address = tidy_URL(phindcgi_address, true);
+	System.out.println("Phind phindcgi: " + phindcgi_address);
+
+	// Where is the Greenstone library
+	library_address = parameterValue("library");
+	library_address = tidy_URL(library_address, true);
+	System.out.println("Phind library: " + library_address);
+	
+	// Is there a default search term?
+	initialSearch = parameterValue("initial_search", "");
+
+	// Should we display the control panel
+	showControlPanel = true;
+	if (parameterValue("control_panel", "show").toLowerCase().equals("hide")) {
+	    showControlPanel = false;
+	}
+	
+	// Should we show a background image?
+	backdrop_address = parameterValue("backdrop", "");
+	if (backdrop_address.length() > 0) {
+	    backdrop_address = tidy_URL(backdrop_address, false);
+	    System.out.println("Phind backdrop URL: " + backdrop_address);
+
+	    try {
+		URL backdrop_url = new URL(backdrop_address);
+		backgroundImage = getImage(backdrop_url);
+		showImage = true;
+	    } catch (Exception e) { 
+		System.out.println("Phind could not load " + backdrop_address);
+		showImage = false;
+	    }
+	}
+
+	// Should we draw a border?
+	showBorder = parameterValue("border", "on").equals("off");
+
+	// Are the windows arranged vertically or horizontally
+	if (parameterValue("orientation", "vertical").toLowerCase().startsWith("hori")) {
+	    vertical = false;
+	} else {
+	    vertical = true;
+	}
+	
+	// How many phind windows are there?
+	depth = parameterValue("depth", 3);
+
+	// Result sort order
+	// Standard is "LlEeDd", expansion-first is "EeLlDd"
+	String order = parameterValue("resultorder", "standard");
+	if (!order.equals("standard")) {
+	    int next = 20;
+	    ResultItem.sortMessage = next;
+	    for (int x = 0; x < order.length(); x++) {
+		if (order.charAt(x) == ',') {
+		    next--;
+		} else if (order.charAt(x) == 'L') {
+		    ResultItem.sortLinkItem = next;
+		} else if (order.charAt(x) == 'l') {
+		    ResultItem.sortMoreLinks = next;
+		} else if (order.charAt(x) == 'E') {
+		    ResultItem.sortPhraseItem = next;
+		} else if (order.charAt(x) == 'e') {
+		    ResultItem.sortMorePhrases = next;
+		} else if (order.charAt(x) == 'D') {
+		    ResultItem.sortDocumentItem = next;
+		} else if (order.charAt(x) == 'd') {
+		    ResultItem.sortMoreDocuments = next;
+		}
+	    }
+	    System.out.println("link: " + ResultItem.sortLinkItem);
+	    System.out.println("exps: " + ResultItem.sortPhraseItem);
+	    System.out.println("docs: " + ResultItem.sortDocumentItem);
+
+	}
+
+	// How many phrases should we fetch at any given time?
+	phraseBlockSize = parameterValue("blocksize", 10);
+
+	// What font should we use?
+	fontSize = parameterValue("fontsize", 10);
+	fontName = parameterValue("fontname", "Helvetica");
+
+	// Column dimensions
+	column_1_width = parameterValue("first_column_width", 6);
+	column_2_width = parameterValue("second_column_width", column_1_width);
+	
+	// Where do we open new windows
+	searchWindowName = parameterValue("search_window", "phindsearch");
+	documentWindowName = parameterValue("document_window", "phinddoc");
+
+	// Colours
+	panel_fg = parameterValue("panel_fg", Color.black);
+	panel_bg = parameterValue("panel_bg", Color.white);
+
+	highlight_bg = parameterValue("highlight_bg", Color.yellow);
+
+	expansion_fg = parameterValue("expansion_fg", Color.black);
+	thesaurus_fg = parameterValue("thesaurus_fg", new Color(0, 100, 0));
+	document_fg = parameterValue("document_fg", Color.blue);
+
+	thesaurus_bar_fg = parameterValue("thesaurus_bar_fg", Color.black);
+	expansion_bar_fg = parameterValue("expansion_bar_fg", Color.black);
+	document_bar_fg = parameterValue("document_bar_fg", Color.black);
+
+	thesaurus_bar_bg = parameterValue("thesaurus_bar_bg", new Color(160, 160, 190));
+	expansion_bar_bg = parameterValue("expansion_bar_bg", new Color(255, 200, 200));
+	document_bar_bg = parameterValue("document_bar_bg", new Color(150, 193, 156));
+
+	column_1_fg = parameterValue("first_column_fg", Color.black);
+	column_1_bg = parameterValue("first_column_bg", new Color(235, 245, 235));
+	column_2_fg = parameterValue("second_column_fg", Color.black);
+	column_2_bg = parameterValue("second_column_bg", new Color(200, 220, 200));
+
+	message_fg = parameterValue("message_fg", Color.black);
+	message_bg = parameterValue("message_bg", Color.white);
+
+	// Colours I don't use, yet
+	// thesaurus_bg = parameterValue("thesaurus_bg", Color.white);
+	// expansion_bg = parameterValue("expansion_bg", Color.white);
+	// document_bg = parameterValue("document_bg", Color.white);
+
+	/** How long should the read loop wait before timing out?
+	 *  DLConsulting 12-07-2004
+	 */
+	timeout = parameterValue("timeout", 60);
+    }
+
+    // Get the value of a parameter given its name.
+    // There are many types of parameters, hence the variety of functions.
+
+    // Get a REQUIRED string.  Stop the applet if we cannot.
+    String parameterValue(String name) {
+	try { 
+	    return getParameter(name);
+	} catch (Exception e) {
+	    System.err.println("Phind: you must give a parameter for \"" 
+			       + name + "\".  Stopping.");
+	    stop();
+	}
+	return "";
+    }
+
+    // Get an optional parameter.  Return a default if we cannot.
+    String parameterValue(String name, String defaultValue) {
+	String text = getParameter(name);
+	if (text == null) {
+	    return defaultValue;
+	}
+	System.out.println("Phind " + name + ": " + text);
+	return text;
+    }
+
+    int parameterValue(String name, int defaultValue) {
+	int value;
+	try { 
+	    value = Integer.parseInt(getParameter(name));
+	} catch (Exception e) {
+	    return defaultValue;
+	}
+	System.out.println("Phind " + name + ": " + value);
+	return value;
+    }
+
+    Color parameterValue(String name, Color defaultValue) {
+
+	String text = getParameter(name);
+	if (text == null) {
+	    return defaultValue;
+	}
+	text = text.toLowerCase();
+
+	// a number of the form "#ddffee" 
+	if (text.startsWith("#") && (text.length() == 7)) {
+	    text = text.substring(1);
+	    int r, g, b;
+	    try {
+		r = Integer.parseInt(text.substring(0,2), 16);
+		g = Integer.parseInt(text.substring(2,4), 16);
+		b = Integer.parseInt(text.substring(4), 16);
+		return new Color(r, g, b);
+	    }  catch (Exception e) {
+		return defaultValue;
+	    }
+	}
+
+	// a known Java colour string
+	else if (text.equals("black")) { return Color.black; }
+	else if (text.equals("blue")) { return Color.blue; }
+	else if (text.equals("cyan")) { return Color.cyan; }
+	else if (text.equals("darkgray")) { return Color.darkGray; }
+	else if (text.equals("gray")) { return Color.gray; }
+	else if (text.equals("green")) { return Color.green; }
+	else if (text.equals("lightgray")) { return Color.lightGray; }
+	else if (text.equals("magenta")) { return Color.magenta; }
+	else if (text.equals("orange")) { return Color.orange; }
+	else if (text.equals("pink")) { return Color.pink; }
+	else if (text.equals("red")) { return Color.red; }
+	else if (text.equals("white")) { return Color.white; }
+	else if (text.equals("yellow")) { return Color.yellow; }
+
+	return defaultValue;
+    }
+
+
+    // Control panel operations
+
+    // Initialise the control panel
+    void initialiseControlPanel() {
+	
+	if (showControlPanel) {
+	    Panel p1 = new Panel();
+	    add("North", p1);
+	    p1.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
+	    
+	    searchButton = new Button("Search");
+	    searchButton.setFont(boldFont);
+	    p1.add(searchButton);
+	    
+	    Label tempLabel = new Label("  for");
+	    tempLabel.setFont(boldFont);
+	    p1.add(tempLabel);
+	    
+	    wordField = new TextField(12);
+	    wordField.setFont(boldFont);
+	    p1.add(wordField);
+	    
+	    Label temp2 = new Label("          ");
+	    p1.add(temp2);
+	    
+	    prevButton = new Button("Previous");
+	    prevButton.setFont(boldFont);
+	    prevButton.disable();
+	    
+	    p1.add(prevButton);
+	    
+	    nextButton = new Button("  Next  ");
+	    nextButton.setFont(boldFont);
+	    nextButton.disable();
+	    p1.add(nextButton);
+	    
+	}
+    }
+    
+    // Button and field functionality
+    
+    // Enable and disable the word field
+    void enableSearchButton() {
+	if (showControlPanel) {
+	    searchButton.enable();
+	}
+    }
+    void disableSearchButton() {
+	if (showControlPanel) {
+	    searchButton.disable();
+	}
+    }
+
+    // Get and set the search text in the wordField
+    String getSearchTerm() {
+	if (showControlPanel) {
+	    return wordField.getText();
+	} else {
+	    return initialSearch;
+	}
+    }
+    void setSearchTerm(String word) {
+	if (showControlPanel) {
+	    wordField.setText(word);
+	} 
+    }
+
+    // Enable or disable the "Previous" and "Next" buttons
+    void enablePreviousAndNext() {
+	if (showControlPanel) {
+	    Component c = firstDisplay.current;
+	    if (c.getClass().getName().endsWith("ResultBox")) {
+		if (((ResultBox) c).prevBoxExists()) {
+		    prevButton.enable();
+		} else {
+		    prevButton.disable();
+		}
+	    }
+	    
+	    c = lastDisplay.current;
+	    if (c.getClass().getName().endsWith("ResultBox")) {
+		if (((ResultBox) c).nextBoxExists()) {
+		    nextButton.enable();
+		} else {
+		    nextButton.disable();
+		}
+	    }
+	}
+    }
+
+    // Shift to previous box
+    //
+    // If the user clicks "Previous" then scroll up.
+    void shiftPrevious() {
+
+	Component c = firstDisplay.current;
+	if (c.getClass().getName().endsWith("ResultBox")) {
+
+	    ResultBox b = (ResultBox) c;
+	    if (b.prevBoxExists()) {
+		b = b.prev;
+
+		// empty all the displays
+		firstDisplay.emptyContents();
+
+		// add as many result boxes as there are displays
+		for (int i = 1 ; ((i <= depth) && (b != null)); i++) {
+		    lastDisplay.display(b);
+		    b.resize(b.display.size());
+		    b.paintAll(b.getGraphics());
+		    b = b.next;
+		}
+	    }
+	}
+	enablePreviousAndNext();
+    }
+
+    // Shift to next box
+    //
+    // If the user clicks "Next" then scroll down if possible
+    void shiftNext() {
+
+	Component c = lastDisplay.current;
+	if (c.getClass().getName().endsWith("ResultBox")) {
+
+	    ResultBox b = (ResultBox) c;
+	    if (b.nextBoxExists()) {
+
+		// find the new "first" displayed box
+		c = firstDisplay.current;
+		b = (ResultBox) c;
+		b = b.next;
+
+		// empty all the displays
+		firstDisplay.emptyContents();
+
+		// add as many result boxes as there are displays
+		for (int i = 1 ; ((i <= depth) && (b != null)); i++) {
+		    lastDisplay.display(b);
+		    b.resize(b.display.size());
+		    b.paintAll(b.getGraphics());
+		    b = b.next;
+		}
+	    }
+	}
+	enablePreviousAndNext();
+    }
+
+    public class SafeReader 
+	extends Thread {
+	// Has the reader finished reading?
+	private boolean complete;
+	// The buffer in where the data read is stored
+	private byte[] buffer;
+	// The stream this reader reads from
+	private DataInputStream in;
+	// If the bytes_read hasn't changed in this time, then stop this thread
+	// and timeout
+	private int timeout; 
+	// The current buffer size
+	private int buffer_current_size;
+	// The maximum buffer size
+	private int buffer_max_size;
+	// The number of bytes read through this reader since the last poll
+	private int bytes_read;
+
+	/** Default constructor 
+	 *  @param in the DataInputStream to read from
+	 */
+	public SafeReader(DataInputStream in) {
+	    complete = false;
+	    buffer_current_size = 0;
+	    buffer_max_size = 16;
+	    buffer = new byte[buffer_max_size]; // Default size
+	    timeout = 60; // Sixty seconds
+	    bytes_read = 0;
+	    
+	    this.in = in;
+	}
+
+	/** Construct a new SafeReader
+	 *  @param in the DataInputStream to read from
+	 *  @param timeout how long this thread should wait when reading data
+	 */
+	public SafeReader(DataInputStream in, int timeout) {
+	    this(in);
+	    this.timeout = timeout;
+	}
+
+	/** Retrieve the current buffer
+	 *  @return a byte[] buffer trimmed to the appropriate size
+	 */
+	public byte[] getBuffer() {
+	    byte[] final_buffer = new byte[buffer_current_size];
+	    System.arraycopy(buffer, 0, final_buffer, 0, buffer_current_size);
+	    return final_buffer;
+	}
+
+	/** Retrieve the current timeout
+	 *  @return the timeout as an int
+	 */
+	public int getTimeout() {
+	    return timeout;
+	}
+
+	/** See whether the reader has finished reading
+	 *  @return true if the read is complete (-1 bytes read!) or false otherwise
+	 */
+	public synchronized boolean isComplete() {
+	    return complete;
+	}
+
+	/** Poll the reader to determine if it has read any bytes recently
+	 *  @return the number of bytes read
+	 */
+	public long poll() {
+	    // Maybe should test if complete - but its only one second right?
+	    long result = bytes_read;
+	    bytes_read = 0;
+	    return result;
+	}
+
+	/** Try to read bytes from the input stream. Note the caller is responsible for closing the datainputstream
+	 */
+	public void run() {
+	    try {
+		int i = 0;
+		byte[] read_buffer = new byte[8];
+		while ((i = in.read(read_buffer)) != -1) {
+		    // Check our storage buffer is big enough
+		    if(buffer_max_size - (buffer_current_size + i) <= 0) {
+			// Double the size
+			buffer_max_size = 2 * buffer_max_size;
+			byte[] new_buffer = new byte[buffer_max_size];
+			System.arraycopy(buffer, 0, new_buffer, 0, buffer_current_size);
+			buffer = new_buffer;
+		    }
+		    // Then copy in the read buffer
+		    System.arraycopy(read_buffer, 0, buffer, buffer_current_size, i);
+		    buffer_current_size += i;
+		    bytes_read += i;
+		}
+		setComplete(true);
+	    }
+	    catch(IOException exception) {
+		System.err.println("SafeReader.run(): Unexpected IOException. Fatal.");
+		exception.printStackTrace();
+	    }
+	}
+
+	/** Set the complete boolean to the desired state, synchronized to avoid race with isComplete()
+	 *  @param value the desired state
+	 */
+	private synchronized void setComplete(boolean value) {
+	    complete = value;
+	}
+    }
+}
+
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/PhindTitle.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/PhindTitle.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/PhindTitle.java	(revision 20131)
@@ -0,0 +1,84 @@
+/**********************************************************************
+ *
+ * PhindTitle.java -- backdrops to empty ResultDisplay panels.
+ *
+ * Copyright 1997-2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+/*********************************************************************
+
+PhindTitle is for drawing backdrops in empty ResultDisplay panels.
+
+**********************************************************************/
+
+package org.nzdl.gsdl.Phind;
+
+import java.applet.Applet;
+import java.awt.Canvas;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Image;
+
+public class PhindTitle extends Canvas {
+
+    Phind phind;
+    static Image backgroundImage;
+    boolean displayInfo;
+    
+    PhindTitle(Phind p) {
+	phind = p;
+    }
+
+    public void update(Graphics g) {
+	paint(g);
+    }
+
+    public void paint(Graphics g) {
+	Dimension canvasSize = size();
+
+	Color fore = phind.panel_fg;
+	Color back = phind.panel_bg;
+
+	// set the screen background
+	if (phind.showImage)
+	    try {
+		g.drawImage(phind.backgroundImage, 
+			    0, 0, canvasSize.width, canvasSize.height, back, null);
+	    } catch (Exception e) {
+		System.err.println("PhindTitle paint: "  + e);
+	    }
+	else {
+	    g.setColor(back);
+	    g.fillRect(0,0, canvasSize.width, canvasSize.height);
+	}
+    }
+}
+
+ 
+
+
+
+
+
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultBox.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultBox.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultBox.java	(revision 20131)
@@ -0,0 +1,774 @@
+/**********************************************************************
+ *
+ * ResultBox.java -- a list of phrases in the Phind java interface
+ *
+ * Copyright 1997-2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/*********************************************************************
+
+This class is used in the Phind java applet (Phind.java).
+
+A ResultBox holds the results of a query to phindcgi.  They deal mostly
+with the information content of the query, and have methods for parsing the
+input into phrase and document items.  They have little do with display:
+ResultBoxes are shown to the user through "ResultDisplay" panels, and are
+drawn using "ResultCanvas" objects.
+
+**********************************************************************/
+
+package org.nzdl.gsdl.Phind;
+
+import java.awt.Panel;
+import java.awt.BorderLayout;
+import java.awt.Scrollbar;
+
+import java.awt.Label;
+import java.awt.Event;
+
+import java.net.*;
+import java.applet.*;
+
+import java.util.Vector;
+
+
+public class ResultBox extends Panel {
+    
+    // Objects at a "higher" level than this one
+    Phind phind;
+    ResultDisplay display;
+
+    // Surroundig objects
+    ResultBox prev, next;
+
+    // The components contained by this one.
+    ResultCanvas c;
+    ResultTitle t;
+    Scrollbar s;
+    Panel label;
+
+    // The key identifying the phrase displayed, with its text and the
+    // collection from which it is drawn
+    String searchKey, searchPhrase, searchCollection;
+    
+    // The total frequency, expansion frequency, and document frequency
+    // of the phrase
+    int numberOfOccurances;
+    int numberOfExpansions;
+    int numberOfDocuments;
+    int numberOfThesaurusLinks;
+
+    // The number of phrases and documents retrieved, and the number of
+    // times the user has requested more phrases or documents.
+    int expansionsRetrieved;
+    int documentsRetrieved;
+    int thesaurusLinksRetrieved;
+    int nextPhraseBlock;
+    int nextDocumentBlock;
+    int nextThesaurusLinkBlock;
+    
+    int mode;
+    final int initMode = 0;
+    public final int emptyMode = 1;
+    final int loadingMode = 2;
+    final int finishedMode = 3;
+
+    String buffer;
+    boolean finished;
+
+
+    // Create a ResultBox
+    // given details of the search that generated it.
+    ResultBox(Phind p, String collect, String key, String phrase, ResultBox rb) {
+
+	super();
+	mode = initMode;
+
+	phind = p;
+	display = null;
+	next = null;
+	prev = rb;
+	if (prev != null) prev.next = this;
+
+	searchKey = key;
+	searchPhrase = phrase;
+	searchCollection = collect;
+
+	numberOfOccurances = -1;
+	numberOfExpansions = -1;
+	numberOfDocuments = -1;
+	numberOfThesaurusLinks = -1;
+
+	expansionsRetrieved = 0;
+	documentsRetrieved = 0;
+	thesaurusLinksRetrieved = 0;
+
+	nextPhraseBlock = 1;
+	nextDocumentBlock = 1;
+	nextThesaurusLinkBlock = 1;
+
+
+	setLayout(new BorderLayout());
+
+	s = new Scrollbar(Scrollbar.VERTICAL);
+	disableScrollbar();
+	add("East", s);
+
+	c = new ResultCanvas(this);
+	add("Center", c);
+
+	t = new ResultTitle(this);
+	add("North", t);
+
+	buffer = "";
+	finished = false;
+	mode = emptyMode;
+    }
+
+    static String describeContents(String phrase, String c) {
+	return( "\"" + phrase + "\" in " + c + ".");
+    }
+
+    String describeContents() {
+	return( describeContents(searchPhrase, searchCollection) );
+    }
+
+
+    // Reset the contents of the box
+    void resetBox( ) {
+	buffer = "";
+	finished = false;
+	c.resetCanvas();
+	disableScrollbar();
+	mode = emptyMode;
+    
+	numberOfExpansions = -1;
+	numberOfDocuments = -1;
+	numberOfThesaurusLinks = -1;
+
+	expansionsRetrieved = 0;
+	documentsRetrieved = 0;
+	thesaurusLinksRetrieved = 0;
+    }
+
+    void setStatus( String status ) {
+	phind.setStatus(status);
+    }
+
+    void disableScrollbar() {
+	if (s.isEnabled()) {
+	    s.setValues(0, 1, 0, 1);
+	    s.setLineIncrement(1);
+	    s.setPageIncrement(1);
+	    s.disable();
+	}
+    }
+
+    // Are there displays previous to and after this?
+    public boolean prevBoxExists () {
+	return (prev != null);
+    }
+    public boolean nextBoxExists () {
+	return (next != null);
+    }
+
+    
+    // Look up a phrase
+    // Phrase lookups are passed on to the Phind applet itself.
+    void lookupPhrase(String key, String phrase, int queryMode) {
+	buffer = "";
+	finished = false;
+	phind.searchForPhrase(this, key, phrase, queryMode);
+	t.repaint();
+    }
+
+    public boolean handleEvent(Event event) {
+	//    System.out.println("event: " + event.toString());
+	if ( (event.target == s) && 
+	     ( (event.id == Event.SCROLL_ABSOLUTE) ||
+	       (event.id == Event.SCROLL_LINE_DOWN) ||
+	       (event.id == Event.SCROLL_LINE_UP) ||
+	       (event.id == Event.SCROLL_PAGE_DOWN) ||
+	       (event.id == Event.SCROLL_PAGE_UP) ) ) {
+	    c.repaint();
+	    return true;
+	} else {
+	    return super.handleEvent(event);
+	}
+    }    
+
+
+    // a new section of the byte stream is read
+    void parseBytes(byte[] bytes) {
+	mode = loadingMode;
+
+	// update the buffer that holds the bytes read
+	String input;
+	try {
+	    input = new String(bytes, new String("UTF8"));
+	} catch (Exception e) {
+	    System.err.println(e);
+	    input = "";
+	}
+	buffer = buffer.concat(input);
+
+	// Parse each line until there are no more lines to parse
+	while(parseLine());
+
+	if (finished) {
+	    c.updateMarkers();
+	    buffer = "";
+	} else {
+	    // We haven't finished, give some feedback about progress
+	    setStatus("Connected to host, " + c.numberOfItems + " results read");
+	}
+    }
+
+    // Parse a line of XML
+    //
+    // This isn't necessarily real XML.  We assume every tag begins and
+    // ends on one line.  We read one line out of the buffer at a time,
+    // then "add" them to the box with the addLine method.
+    //
+    // Return true if there is a another line here to parse, otherwise false.
+
+    boolean parseLine() {
+
+        // System.out.print("parseLine " + "(length " + buffer.length() + ")");
+	String item;
+	int eol = buffer.indexOf((int) '\n');
+
+	// If there are no carriage returns, the line is incomplete
+	if (eol == -1) {
+	    return false;
+	}
+
+	// The </phinddata> tag concludes the dataset
+	else if (buffer.startsWith("</phinddata>")) {
+	    mode = finishedMode;
+	    finished = true;
+	    return false;
+	}
+	
+	// The <expansion> tag
+	else if (buffer.startsWith("<expansion ")) {
+	    item = buffer.substring(0, eol);
+	    buffer = buffer.substring(eol + 1);
+	    addExpansionTag(item);
+	    return true;
+	}
+ 
+	// The <document> tag
+	else if (buffer.startsWith("<document ")) {
+	    item = buffer.substring(0, eol);
+	    buffer = buffer.substring(eol + 1);
+	    addDocumentTag(item);
+	    return true;
+	}
+ 
+	// The <thesaurus> tag
+	else if (buffer.startsWith("<thesaurus ")) {
+	    item = buffer.substring(0, eol);
+	    buffer = buffer.substring(eol + 1);
+	    addThesaurusTag(item);
+	    return true;
+	}
+ 
+	// The <phinddata> tag introduces the dataset
+	else if (buffer.startsWith("<phinddata ")) {
+	    item = buffer.substring(0, eol);
+	    buffer = buffer.substring(eol + 1);
+	    addPhinddataTag(item);
+	    return true;
+	}
+
+	// The <phinderror> tag contains an error message
+	else if (buffer.startsWith("<phinderror")) {
+	    item = buffer.substring(0, eol);
+	    System.out.println("phind reported an error: " + item);
+	    buffer = buffer.substring(eol + 1);
+	    return true;
+	}
+ 
+	// Ignore the piece we've read
+	item = buffer.substring(0, eol);
+	// System.out.println("discarding: " + item);
+	buffer = buffer.substring(eol + 1);
+	return true;
+    }
+    
+
+
+    // Add a phinddata tag
+    //
+    // Given a string containing an XML phinddata tag of the form:
+    //   <phinddata id="35" text="FOREST" df="797" ef="134">
+    // Read the expansion information from the tag
+    //
+    // Return true if successful, otherwise false.
+
+    boolean addPhinddataTag( String line ) {
+
+	// System.out.println( "addExpansionListTag: " + line);
+
+	String idStr = "", text = "", tfStr = "", efStr = "", dfStr = "", lfStr = "";
+	int tf = 0, ef = 0, df = 0, lf = 0;
+
+	// Break the tag down into its component parts
+	int nextSplit;
+       	while (line.length() > 0) {
+	    line = line.trim();
+
+	    // Read the phrase identifier
+	    if (line.startsWith("id")) {
+		line = line.substring(4);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    idStr = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("addExpansionListTag: error parsing: " + line);
+ 		}
+	    } 
+	    
+	    // Read the total frequency
+	    else if (line.startsWith("tf")) {
+		line = line.substring(4);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    tfStr = line.substring(0, nextSplit);
+		    tf = Integer.valueOf(tfStr).intValue();
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("addExpansionListTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the text of the phrase
+	    else if (line.startsWith("text")) {
+		line = line.substring(6);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    text = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("addExpansionListTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the expansion frequency
+	    else if (line.startsWith("ef")) {
+		line = line.substring(4);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    efStr = line.substring(0, nextSplit);
+		    ef = Integer.valueOf(efStr).intValue();
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("addExpansionListTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the document frequency
+	    else if (line.startsWith("df")) {
+		line = line.substring(4);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    dfStr = line.substring(0, nextSplit);
+		    df = Integer.valueOf(dfStr).intValue();
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("addExpansionListTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the thesaurus link frequency
+	    else if (line.startsWith("lf")) {
+		line = line.substring(4);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    lfStr = line.substring(0, nextSplit);
+		    lf = Integer.valueOf(lfStr).intValue();
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("addExpansionListTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read and ignore some other tag
+	    else {
+		nextSplit = line.indexOf((int) ' ');
+		if (nextSplit >= 1) {
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    line = "";
+		}
+	    }
+	}
+
+	// Add the data to the ResultBox
+	searchKey = idStr;
+	searchPhrase = text;
+	numberOfOccurances = tf;
+	numberOfExpansions = ef;
+	numberOfDocuments = df;
+	numberOfThesaurusLinks = lf;
+	return true;
+    }
+
+
+    // Add an expansion tag
+    //
+    // Given a string containing an XML expansin tag of the form:
+    //   <expansion num="3" id="8421" prefix="PEOPLE and" suffix="" tf="3" df="3"/>
+    //   <expansion num="4" id="8696" prefix="" suffix="products" tf="3" df="3"/>
+    // Create a new ResultItemPhrase for display
+    //
+    // Return true if successful, otherwise false.
+
+    boolean addExpansionTag( String line ) {
+
+	// System.out.println( "addExpansionTag: " + line + " (" + expansionsRetrieved + ")");
+
+	String numStr = "", idStr = "", tfStr = "", dfStr = "", 
+	    prefix = "", body = "", suffix = "";
+
+	body = searchPhrase;
+
+	// Break the tag down into its component parts
+	line = line.substring(11);
+	int nextSplit;
+       	while (line.length() > 0) {
+	    line = line.trim();
+
+	    // Read the expansion number
+	    if (line.startsWith("num")) {
+		line = line.substring(5);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    numStr = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addExpansionTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the phrase ID
+	    else if (line.startsWith("id")) {
+		line = line.substring(4);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    idStr = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addExpansionTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the prefix of the phrase
+	    else if (line.startsWith("prefix")) {
+		line = line.substring(8);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 0) {
+		    prefix = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addExpansionTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the suffix of the phrase
+	    else if (line.startsWith("suffix")) {
+		line = line.substring(8);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 0) {
+		    suffix = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addExpansionTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the frequency
+	    else if (line.startsWith("tf")) {
+		line = line.substring(4);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    tfStr = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addExpansionTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the document frequency
+	    else if (line.startsWith("df")) {
+		line = line.substring(4);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    dfStr = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addExpansionTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read some other tag
+	    else {
+		nextSplit = line.indexOf((int) ' ');
+		if (nextSplit >= 1) {
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    line = "";
+		}
+	    }
+	}
+	
+	// Create a new ResultItem and add it to the display
+	ResultItemPhrase ri = new ResultItemPhrase(idStr, tfStr, dfStr, prefix, body, suffix);
+	
+	if (c.addResultItem(ri)) {
+	    expansionsRetrieved++;
+	    return true;
+	}
+	
+	return false;
+    }
+
+
+    // Add an document tag
+    //
+    // Given a string containing an XML document tag of the form:
+    //   <document num="2" hash="HASH424e64b811fdad933be69c" freq="1" title="CONTENTS"/>
+    //   <document num="3" hash="HASH01f08efd8752ad54ca0a99cf" freq="1" title="Tree mixtures"/>
+    //
+    // Create a new ResultItemDocument for display
+    //
+    // Return true if successful, otherwise false.
+
+    boolean addDocumentTag( String line ) {
+
+	// System.out.println( "addDocumentTag: " + line + " (" + documentsRetrieved + ")");
+	
+	String num = "", hash = "", freq = "", title = "";
+	line = line.substring(9);
+	
+	// Break the tag down into its component parts
+	int nextSplit;
+       	while (line.length() > 0) {
+	    line = line.trim();
+
+	    // Read the expansion number
+	    if (line.startsWith("num")) {
+		line = line.substring(5);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    num = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addDocumentTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the document OID hash
+	    else if (line.startsWith("hash")) {
+		line = line.substring(6);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    hash = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addDocumentTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the document frequency
+	    else if (line.startsWith("freq")) {
+		line = line.substring(6);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    freq = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addDocumentTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the title
+	    else if (line.startsWith("title")) {
+		line = line.substring(7);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    title = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addDocumentTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read some other tag or close the string off
+	    else {
+		nextSplit = line.indexOf((int) ' ');
+		if (nextSplit >= 1) {
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    line = "";
+		}
+	    }
+	}
+	
+	// Create a new ResultItem and add it to the display
+	ResultItemDocument ri = new ResultItemDocument(hash, title, freq);
+	
+	if (c.addResultItem(ri)) {
+	    documentsRetrieved++;
+	    return true;
+	}
+	
+	return false;
+    }
+
+
+    // Add a thesaurus tag
+    //
+    // Given a string containing an XML document tag of the form:
+    //
+    // <thesaurus num="3" id="36506" tf="0" df="0" type="RT" text="ANGLOPHONE AFRICA"/>
+    // <thesaurus num="4" id="28724" tf="0" df="0" type="RT" text="FRANCOPHONE AFRICA"/>
+    //
+    // Create a new ResultItemLink for display
+    //
+    // Return true if successful, otherwise false.
+
+    boolean addThesaurusTag( String line ) {
+    
+	// System.out.println( "addThesaurusTag: " + line + " (" + thesaurusLinksRetrieved + ")");
+
+	String num = "", id = "", tf = "", df = "", type = "", text = "";
+	line = line.substring(10);
+
+	// Break the tag down into its component parts
+	int nextSplit;
+       	while (line.length() > 0) {
+	    line = line.trim();
+
+	    // Read the expansion number
+	    if (line.startsWith("num")) {
+		line = line.substring(5);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    num = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addThesaurusTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the phrase ID
+	    else if (line.startsWith("id")) {
+		line = line.substring(4);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    id = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addThesaurusTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the phrase link type
+	    else if (line.startsWith("type")) {
+		line = line.substring(6);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    type = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addThesaurusTag: error parsing: " + line);
+ 		}
+	    } 
+
+
+	    // Read the phrase text
+	    else if (line.startsWith("text")) {
+		line = line.substring(6);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    text = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addThesaurusTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the frequency
+	    else if (line.startsWith("tf")) {
+		line = line.substring(4);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    tf = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addExpansionTag: error parsing: " + line);
+ 		}
+	    } 
+
+	    // Read the document frequency
+	    else if (line.startsWith("df")) {
+		line = line.substring(4);
+		nextSplit = line.indexOf((int) '"');
+		if (nextSplit >= 1) {
+		    df = line.substring(0, nextSplit);
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    System.err.println("ResultBox addExpansionTag: error parsing: " + line);
+ 		}
+	    } 
+
+
+	    // Read some other tag or close the string off
+	    else {
+		nextSplit = line.indexOf((int) ' ');
+		if (nextSplit >= 1) {
+		    line = line.substring(nextSplit + 1);
+		} else {
+		    line = "";
+		}
+	    }
+	}
+	
+	// Create a new ResultItem and add it to the display
+	ResultItemLink ri = new ResultItemLink(id, text, type, tf, df);
+
+	if (c.addResultItem(ri)) {
+	    thesaurusLinksRetrieved++;
+	    return true;
+	}
+	
+	return false;
+    }
+}
+
+
+
+
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultCanvas.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultCanvas.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultCanvas.java	(revision 20131)
@@ -0,0 +1,557 @@
+/**********************************************************************
+ *
+ * ResultCanvas.java -- a Canvas onto which a phrase list is drawn
+ *
+ * Copyright 1997-2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/*********************************************************************
+
+This class is used in the Phind java applet (Phind.java).
+
+The results of a query are displayed on a ResultCanvas object.  Each 
+entry in the result list is stored in a ResultItem, and the ResultCanvas 
+contains a Vector of ResultItems.
+
+Each ResultCanvas is embedded in a ResultBox alongside a Scrollbar.  
+When the ResultCanvas is drawn, it looks at the scrollbar, calculates 
+which ResultItems are visible, then draws them on the screen.
+
+**********************************************************************/
+
+package org.nzdl.gsdl.Phind;
+
+import java.awt.Canvas;
+import java.awt.Scrollbar;
+import java.awt.Graphics;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Dimension;
+import java.awt.Color;
+import java.util.Vector;
+import java.awt.Image;
+import java.awt.Event;
+
+import java.net.URL;
+import java.applet.Applet;
+import java.util.Date;
+
+public class ResultCanvas extends Canvas {
+
+    // Other objects associated with this 
+    Phind phind;
+    ResultBox parent;
+    Scrollbar scrollbar;
+    
+    // fonts and font spacings to use
+    Font areaPlain, areaBold;
+    int lineSpacing;
+    
+    // The items to display on this canvas
+    int numberOfItems;
+    int firstItemDisplayed;
+    int itemSelected;
+    Vector items;
+    
+    // the background image
+    public static Image backgroundImage;
+    
+    
+    // Create a ResultCanvas from the ResultBox which is its parent.
+    ResultCanvas(ResultBox p) {
+	
+	parent = p;
+	phind = p.phind;
+	scrollbar = p.s;
+	parent.disableScrollbar();
+
+	areaPlain = phind.plainFont;
+	areaBold  = phind.boldFont;
+
+	lineSpacing = phind.fontSize + 2;
+
+	items = new Vector();
+	numberOfItems = 0;
+	firstItemDisplayed = 0;
+	itemSelected = -1;
+    
+	if (backgroundImage == null) {
+	    backgroundImage = p.phind.backgroundImage;
+	}
+
+    }
+
+    void resetCanvas( ) {
+	items.removeAllElements();
+	numberOfItems = 0;
+	repaint();
+    }
+
+
+    // Add a new search result.
+    // Return true if successful, otherwise false.
+    boolean addResultItem( ResultItem item ) {
+ 
+	// Add a new result, in sorted order.
+	// First sort key is item kind (lowest first),
+	// second is frequency (highest first).
+	// This is not efficient, but I don't care right now.
+	int index = 0;
+	while ((index < numberOfItems) &&
+	       ((item.sort < ((ResultItem) items.elementAt(index)).sort) ||
+		((item.sort == ((ResultItem) items.elementAt(index)).sort) &&
+		 (item.frequency <= ((ResultItem) items.elementAt(index)).frequency)))) {
+	    index++;
+	}
+	items.insertElementAt(item,index);
+	numberOfItems++;
+	return true;
+    }
+
+
+    // Update more phrases/documents/links markers
+    void updateMarkers() {
+	updateMorePhrasesMarker();
+	updateMoreDocumentsMarker();
+	updateMoreLinksMarker();
+    }
+
+    // Make sure the more Phrases item only appears in the list
+    // if it is meant to.
+    void updateMorePhrasesMarker() {
+    
+	// System.out.println("updateMorePhrasesMarker() ");
+
+	// look for a marker
+	boolean found = false;
+	int index = 0;
+	while (!found && (index < numberOfItems)) {
+	    if (((ResultItem) items.elementAt(index)).isMorePhrases()) {
+		found = true;
+	    } else {
+		index++;
+	    }
+	}
+
+	if (parent.expansionsRetrieved == parent.numberOfExpansions) {
+	    // there should be no marker
+	    if (found) {
+		items.removeElementAt(index);
+		numberOfItems--;
+	    }
+
+	} else if (parent.expansionsRetrieved < parent.numberOfExpansions) {
+	    if (!found) {
+		ResultItem ri = new ResultItem(ResultItem.morePhrases);
+		addResultItem(ri);
+	    }
+	}
+    }
+
+
+    // Make sure the more documents marker appears when required
+    void updateMoreDocumentsMarker() {
+    
+	// System.out.println("updateMoreDocumentsMarker() ");
+
+	// look for a marker
+	boolean found = false;
+	int index = 0;
+	while (!found && (index < numberOfItems)) {
+	    if (((ResultItem) items.elementAt(index)).isMoreDocuments()) {
+		found = true;
+	    } else {
+		index++;
+	    }
+	}
+
+	if (parent.documentsRetrieved == parent.numberOfDocuments) {
+	    // there should be no marker
+	    if (found) {
+		items.removeElementAt(index);
+		numberOfItems--;
+	    }
+
+	} else if (parent.documentsRetrieved < parent.numberOfDocuments) {
+	    // there should be a marker
+	    if (!found) {
+		ResultItem ri = new ResultItem(ResultItem.moreDocuments);
+		addResultItem(ri);
+	    }
+	}
+    }
+
+      
+    // Make sure the more links marker appears when required
+    void updateMoreLinksMarker() {
+    
+	// System.out.println("updateMoreLinksMarker() ");
+
+	// look for a marker
+	boolean found = false;
+	int index = 0;
+	while (!found && (index < numberOfItems)) {
+	    if (((ResultItem) items.elementAt(index)).isMoreLinks()) {
+		found = true;
+	    } else {
+		index++;
+	    }
+	}
+
+	if (parent.thesaurusLinksRetrieved == parent.numberOfThesaurusLinks) {
+	    // there should be no marker
+	    if (found) {
+		items.removeElementAt(index);
+		numberOfItems--;
+	    }
+
+	} else if (parent.thesaurusLinksRetrieved < parent.numberOfThesaurusLinks) {
+	    // there should be a marker
+	    if (!found) {
+		ResultItem ri = new ResultItem(ResultItem.moreLinks);
+		addResultItem(ri);
+	    }
+	}
+    }
+
+      
+
+ 
+
+
+    public void update(Graphics g) {
+	paint(g);
+    }
+
+    public void paint(Graphics g) {
+
+	// calculate the canvas size, margins, and spacing
+	
+	// Note: the size() method is deprecated, but getSize fails in NetScape 4
+	// Dimension canvasSize = getSize();
+	Dimension canvasSize = size();
+
+	g.setFont(areaPlain);
+	int space = g.getFontMetrics().stringWidth(" ");
+	int nought = g.getFontMetrics().stringWidth("0");
+
+	int firstColumnWidth = phind.column_1_width * nought;
+	int secondColumnWidth = phind.column_2_width * nought;
+	int columnWidth = firstColumnWidth + secondColumnWidth;
+
+	int firstColumnLeft = canvasSize.width - columnWidth;
+	int secondColumnLeft = firstColumnLeft + firstColumnWidth;
+
+	int mainLeftMargin = 0;
+	int mainRightMargin = firstColumnLeft;
+
+	// the number of items that will fit on the canvas
+	int visible = canvasSize.height / lineSpacing;
+
+	// calculate the first item to output
+	int scrollValue = scrollbar.getValue();
+	if (numberOfItems <= visible) {
+	    scrollValue = 0;
+	} else if (scrollValue > (numberOfItems - visible)) {
+	    scrollValue = numberOfItems - visible;
+	} 
+	firstItemDisplayed = scrollValue;
+
+	// Draw the phrase area
+	Color fore = phind.panel_fg;
+	Color back = phind.panel_bg;
+
+
+	// draw the background
+	if (phind.showImage) {
+	    try {
+		g.drawImage(backgroundImage, 
+			    mainLeftMargin, 0, mainRightMargin, canvasSize.height, 
+			    back, null);
+	    } catch (Exception e) {
+		phind.showImage = false;
+		System.err.println("ResultCanvas paint error: " + e); 
+		g.setColor(back);
+		g.fillRect(0, 0, canvasSize.width, canvasSize.height);
+	    }
+	} else {
+	    g.setColor(back);
+	    g.fillRect(0, 0, canvasSize.width, canvasSize.height);
+	}
+    
+	// If there are no phrases, output a brief explanation.
+	if (numberOfItems == 0) {
+	    g.drawString("No phrases match this query.", mainLeftMargin + 10, lineSpacing);
+	}
+
+	// Output each of the visible ResultItems
+	ResultItem result;
+	int tab, i, y = 0;
+	int center = mainLeftMargin 
+	    + ((mainRightMargin - mainLeftMargin 
+		- g.getFontMetrics().stringWidth(parent.searchPhrase)) / 2);
+	int thesColumn = mainLeftMargin + firstColumnWidth 
+	    + g.getFontMetrics().stringWidth("Narrower term");
+
+	String body, prefix, suffix;
+	
+	for (i = scrollValue; 
+	     (i < numberOfItems) && (y + lineSpacing < canvasSize.height); i++) {
+
+	    // Get the resultItem to output
+	    result = (ResultItem) items.elementAt(i);
+	    
+	    // Graphics settings for drawing this line
+	    y += lineSpacing;
+	    g.setFont(areaPlain);
+
+	    // Highlight the selected phrase.
+	    if (i == itemSelected) {
+		g.setColor(phind.highlight_bg);
+		g.fillRect(mainLeftMargin, y-lineSpacing+2, mainRightMargin, lineSpacing);
+	    }
+
+	    // Draw the item
+
+	    // Draw a phrase item
+	    if (result.isPhrase()) {
+		prefix = result.prefixText();
+		body = result.mainText();
+		suffix = result.suffixText();
+		
+		g.setColor(phind.expansion_fg);
+		g.setFont(areaPlain);
+		tab = center - g.getFontMetrics().stringWidth(prefix) - space;
+		g.drawString(prefix, tab, y);
+		
+		g.setFont(areaBold);
+		g.drawString(body, center, y);
+		
+		tab = center + space + g.getFontMetrics().stringWidth(body);
+		g.setFont(areaPlain);
+		g.drawString(suffix, tab, y);
+	
+	    } 
+
+	    // Draw a document item
+	    else if (result.isDocument()){
+		body = result.mainText();
+
+		g.setColor(phind.document_fg);
+		g.setFont(areaPlain);
+		tab = (mainRightMargin - g.getFontMetrics().stringWidth(body)) / 2;
+		g.drawString(body, tab, y);
+      
+	    } 
+	
+	    // Draw a thesaurus link item
+	    else if (result.isLink()){
+		prefix = result.prefixText() + ":";
+		body = result.mainText();
+		tab = thesColumn - g.getFontMetrics().stringWidth(prefix) - space;
+
+		g.setColor(phind.thesaurus_fg);
+		g.setFont(areaPlain);
+		g.drawString(prefix, tab, y);
+		g.setFont(areaBold);
+		g.drawString(body, thesColumn, y);
+	    } 
+	    
+	    // Draw a "more phrases/documents/links" marker
+	    else if (result.isMorePhrases() 
+		     || result.isMoreDocuments() 
+		     || result.isMoreLinks()){
+		body = result.mainText();
+		
+		if (result.isMorePhrases()) {
+		    g.setColor(phind.expansion_bar_bg);
+		} else if (result.isMoreDocuments()) {
+		    g.setColor(phind.document_bar_bg);
+		} else {
+		    g.setColor(phind.thesaurus_bar_bg);		    
+		}
+		g.fillRect(mainLeftMargin, y-lineSpacing+2, mainRightMargin, lineSpacing);
+
+		if (result.isMorePhrases()) {
+		    g.setColor(phind.expansion_bar_fg);
+		} else if (result.isMoreDocuments()) {
+		    g.setColor(phind.document_bar_fg);
+		} else {
+		    g.setColor(phind.thesaurus_bar_fg);		    
+		}
+		g.setFont(areaPlain);
+		tab = (mainRightMargin - g.getFontMetrics().stringWidth(body)) / 2;
+		g.drawString(body, tab, y);
+	    } 
+	}
+
+	// Draw the frequecy columns
+
+	// column backgrounds
+	g.setColor(phind.column_1_bg);
+	g.fillRect(firstColumnLeft, 0, firstColumnWidth, canvasSize.height);
+	g.setColor(phind.column_2_bg);
+	g.fillRect(secondColumnLeft, 0, secondColumnWidth, canvasSize.height);
+
+	// fill in the numbers
+	g.setColor(phind.column_1_fg);
+	g.setFont(areaPlain);
+	y = 0;
+	String docsText, freqText;
+
+	for (i = scrollValue; 
+	     (i < numberOfItems) && (y + lineSpacing < canvasSize.height); i++) {
+	    
+	    // Get the resultItem to output
+	    result = (ResultItem) items.elementAt(i);
+	    docsText = result.docsText();
+	    freqText = result.freqText();
+	    
+	    // Graphics settings for drawing this line
+	    y += lineSpacing;
+
+	    // Write the document frequency
+	    if (docsText.length() > 0) {
+		tab = secondColumnLeft - space - g.getFontMetrics().stringWidth(docsText);
+		g.drawString(docsText, tab, y);
+	    }
+
+	    // Write the term frequency
+	    if (freqText.length() > 0) {
+		tab = secondColumnLeft + secondColumnWidth 
+		    - space - g.getFontMetrics().stringWidth(freqText);
+		g.drawString(freqText, tab, y);
+	    }
+	}
+
+	// Adjust the scrollbar
+	if (visible >= numberOfItems) {
+	    parent.disableScrollbar();
+	} else {
+	    scrollbar.setValues(scrollValue, visible, 0, numberOfItems);
+	    // Deprecated - setPageIncrement() has been replaced by
+	    // setBlockIncrement(), but the latter doesn't work on some
+	    // browsers.  Damn.
+	    // scrollbar.setBlockIncrement(visible - 1);
+	    scrollbar.setPageIncrement(visible - 1);
+	    // Deprecated - more nonsense: enable() has been replaced by
+	    // setEnabled(true), but this doesn't work on some browsers.
+	    //scrollbar.setEnabled(true);
+	    scrollbar.enable();
+	}
+
+	
+	// draw the border
+	if (phind.showBorder) {
+	    g.setColor(phind.panel_fg);
+	    g.drawRect(0,0, canvasSize.width - 1, canvasSize.height - 1);
+	}
+    }
+
+    // User interaction
+    //
+    // All interaction with the ResultCanvas is therough mouse clicks, and
+    // is handles in this method.  Note we ignore clicks that follow
+    // another too closely to avoid problems with slow connections.
+    public boolean handleEvent(Event event) {
+    
+	if (event.id == Event.MOUSE_UP) {
+
+	    // ignore actions that occur within 1 second of the last
+	    Date now = new Date();
+	    // System.out.println("Click time: " + now.toString());
+	    if (now.getTime() < (phind.lastQueryEndTime.getTime() + 1000)) {
+		System.out.println("Ignoring click - too close to last query.");
+		return true;
+	    }
+
+	    // which Item is selected?
+	    int rowSelected = event.y / lineSpacing;
+	    itemSelected = rowSelected + firstItemDisplayed;
+	    ResultItem item = (ResultItem) items.elementAt(itemSelected);
+
+	    if (itemSelected <= numberOfItems) {
+	
+		//User clicks on a phrase
+		if (item.isPhrase()) {
+		    itemSelected = itemSelected;
+		    update(getGraphics());
+		    parent.lookupPhrase(item.hiddenText(), item.toString(), 2);
+
+		    // If meta key is held down, send query to search engine
+		    if (event.metaDown() && !phind.library_address.equals("")) {
+			String address = phind.library_address  
+			    + "a=q&c=" + phind.collection
+			    + "&q=%22" + item.toString().replace(' ', '+') + "%22";
+			phind.displayWebPage(address, phind.searchWindowName);
+		    }
+		} 
+
+		// Click on a thesaurus link
+		else if (item.isLink()) {
+		    itemSelected = itemSelected;
+		    update(getGraphics());
+		    parent.lookupPhrase(item.hiddenText(), item.toString(), 2);
+
+		    // If meta key is held down, send query to search engine
+		    if (event.metaDown() && !phind.library_address.equals("")) {
+			String address = phind.library_address  
+			    + "a=q&c=" + phind.collection
+			    + "&q=%22" + item.toString().replace(' ', '+') + "%22";
+			phind.displayWebPage(address, phind.searchWindowName);
+		    }
+		} 
+
+		// The user clicks on a URL; display it.
+		else if (item.isDocument()) {
+		    itemSelected = itemSelected;
+		    update(getGraphics());
+
+		    String address = phind.library_address 
+			+ "a=d&c=" + phind.collection 
+			+ "&d=" + item.hiddenText()
+			+ "&q=" + parent.searchPhrase.replace(' ', '+');
+		    phind.displayWebPage(address, phind.documentWindowName);
+		}
+		 
+		// When the user clicks on "get more phrases" or other marker,
+		// we have to send a new query to the host
+		else if (item.isMorePhrases()){
+		    parent.lookupPhrase(parent.searchKey, parent.searchPhrase, 3);
+		} else if (item.isMoreDocuments()){
+		    parent.lookupPhrase(parent.searchKey, parent.searchPhrase, 4);
+		} else if (item.isMoreLinks()){
+		    parent.lookupPhrase(parent.searchKey, parent.searchPhrase, 5);
+
+
+		}
+		repaint();
+	    }
+	}
+	return true;
+    }    
+  
+}
+
+
+
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultDisplay.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultDisplay.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultDisplay.java	(revision 20131)
@@ -0,0 +1,126 @@
+/**********************************************************************
+ *
+ * ResultDisplay.java -- Phrase list holder for Phind java applet
+ *
+ * Copyright 1997-2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/*********************************************************************
+
+This class is used in the Phind java applet (Phind.java).
+
+A ResultDisplay is a Panel that can display a single Component, which will
+be a ResultBox or PhindTitle object.
+
+ResultBoxes can be "chained" together with their "prev" and "next" fields,
+allowing us to have an arbitrary number of "displays" in which to show
+phrase lists.
+
+Main methods:
+* emptyContents will remove the component and emptyAll the "next" display
+* display will add an item to the first (ie: most "prev") available box
+
+**********************************************************************/
+
+package org.nzdl.gsdl.Phind;
+
+import java.awt.Panel;
+import java.awt.BorderLayout;
+import java.awt.Component;
+
+class ResultDisplay extends Panel {
+
+  Phind phind;
+  ResultDisplay prev, next;
+  Component current;
+  boolean empty;
+
+  // Create a new Display
+  ResultDisplay(Phind ph, ResultDisplay pr) {
+    phind = ph;
+    prev = pr;
+    next = null;
+    if (prev != null) prev.next = this;
+    setLayout(new BorderLayout());
+
+    empty = true;
+    current = new PhindTitle(ph);
+    add(current);
+  }
+
+  // Empty the contents of the display,
+  // and all the next displays
+  void emptyContents() {
+    if (empty == false) {
+      empty = true;
+      current = new PhindTitle(phind);
+      removeAll();
+      add(current);
+    }
+    if (next != null) next.emptyContents();
+  }
+
+  // Set the contents of this display
+  Component setContents( Component r ) {
+    removeAll();
+    add("Center", r);
+    current = r;
+    empty = false;
+    if (r.getClass().getName().equals("ResultBox")) {
+      ((ResultBox) r).display = this;
+    }
+    return r;
+  }
+
+
+  
+  // Display a component in the "most previous" display
+  ResultDisplay display( Component r ) {
+
+    if (prev == null) {
+      // if there is no previous box, add the component here
+      setContents(r);
+      return this;
+
+    } else if (prev.empty == true) {
+      // if the previous box is empty, add the component to it instead
+      return prev.display(r);
+
+    } else if (empty == true) {
+      // if this box is empty, add the compnent to it
+      setContents(r);
+      return this;
+
+    } else {
+      // if this box is occupied,
+      // shift it's contents prev-wards and add here.
+      prev.display(current);
+      setContents(r);
+      return this;
+    }
+  }
+
+}
+
+
+
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultItem.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultItem.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultItem.java	(revision 20131)
@@ -0,0 +1,128 @@
+/**********************************************************************
+ *
+ * ResultItemDocument.java -- a result in the Phind applet
+ *
+ * Copyright 2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/*********************************************************************
+
+This class is used in the Phind java applet (Phind.java).
+
+A result item holds the data describing a single line returned from a phind
+query.  The complex functionality of phrase and URL items is implemented in
+subclasses; the base class handles simpler cases like the "get more phrases" 
+marker.
+
+**********************************************************************/
+
+package org.nzdl.gsdl.Phind;
+
+public class ResultItem {
+
+    // A text string describing the item
+    String text = "Generic ResultItem";
+
+    // There are several kinds of ResultItem, identified by their
+    // "kind" field, which has an integer value from the list below.
+    final static int message = 8;
+    final static int linkItem = 7;
+    final static int moreLinks = 6;
+    final static int phraseItem = 5;
+    final static int morePhrases = 4;
+    final static int documentItem = 3;
+    final static int moreDocuments = 2;
+    final static int unknownResultItem = 1;
+
+    // The kind of the item
+    int kind = unknownResultItem;
+
+    // When results are displayed, they are loosely sorted by their
+    // kind.  The user can change the sort order numbers with the 
+    // ResultOrder parameter in Phind.java.
+    static int sortMessage = 8;
+    static int sortLinkItem = 7;
+    static int sortMoreLinks = 6;
+    static int sortPhraseItem = 5;
+    static int sortMorePhrases = 4;
+    static int sortDocumentItem = 3;
+    static int sortMoreDocuments = 2;
+    static int sortUnknownResultItem = 1;
+
+    // the primary sort key
+    int sort = 0;
+    
+    // The frequency of the item (secondary sort key)
+    int frequency = 0;
+
+
+    // Create a blank ResultItem
+    ResultItem() {
+	text = "Unknown result type";
+	kind = unknownResultItem;
+	frequency = 0;
+    }
+
+    // Create a new ResultItem of some given kind
+    ResultItem(int newKind) {
+	kind = newKind;
+	frequency = 0;
+
+	if (kind == moreLinks) {
+	    text = "get more thesaurus links";
+	    sort = sortMoreLinks;
+	} else if (kind == morePhrases) {
+	    text = "get more phrases";
+	    sort = sortMorePhrases;
+	} else if (kind == moreDocuments) {
+	    text = "get more documents";
+	    sort = sortMoreDocuments;
+	} else {
+	    text = "Unknown result type";
+	    sort = sortUnknownResultItem;
+	}
+    }
+
+    // Test the type of a ResultItem
+    public boolean isLink() { return false; }
+    public boolean isMoreLinks() { return (kind == moreLinks); }
+    public boolean isPhrase() { return false; }
+    public boolean isMorePhrases() { return (kind == morePhrases); }
+    public boolean isDocument() { return false; }
+    public boolean isMoreDocuments() { return (kind == moreDocuments); }
+
+    // Return the bare text of the item
+    public String toString() { return(text.trim()); }
+
+    // Return the text of the item components
+    public String mainText() { return text; }
+    public String freqText() { 
+	if (frequency > 0) { return Integer.toString(frequency); } 
+	else { return ""; }
+    }
+    public String docsText() { return ""; }
+    public String prefixText() { return ""; }
+    public String suffixText() { return ""; }
+    public String hiddenText() { return ""; }
+}
+
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultItemDocument.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultItemDocument.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultItemDocument.java	(revision 20131)
@@ -0,0 +1,70 @@
+/**********************************************************************
+ *
+ * ResultItemDocument.java -- a document result in the Phind applet
+ *
+ * Copyright 1997-2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/*********************************************************************
+
+This class is used in the Phind java applet (Phind.java).
+
+It contains information describing a document in which a search term 
+occurs.
+
+**********************************************************************/
+
+package org.nzdl.gsdl.Phind;
+
+public class ResultItemDocument extends ResultItem {
+
+    // The document's title is stored in the superclasses 
+    // text variable, and the number of times the phrase occurs
+    // in the frequency variable. 
+
+    // The document's unique object identifier (hash value).
+    String hash;
+
+    // Create a ResultItem for a document
+    ResultItemDocument(String newHash, String newTitle, String newFrequency) {
+	
+	kind = documentItem;
+	text = newTitle;
+
+	sort = sortDocumentItem;
+	frequency = Integer.valueOf(newFrequency).intValue();
+	hash = newHash;
+    }
+
+    // Is this item a document?
+    public boolean isDocument() { return true; }
+
+    // Return the bare text of the item
+    public String toString() { return(text); }
+
+    // Return the text of the item components
+    public String hiddenText() { return hash; }
+ 
+
+}
+
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultItemLink.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultItemLink.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultItemLink.java	(revision 20131)
@@ -0,0 +1,86 @@
+/**********************************************************************
+ *
+ * ResultItemLink.java -- a thesaurus link in the Phind applet
+ *
+ * Copyright 2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/*********************************************************************
+
+This class is used in the Phind java applet (Phind.java).
+
+It contains information describing a thesaurus link.
+
+**********************************************************************/
+
+package org.nzdl.gsdl.Phind;
+
+public class ResultItemLink extends ResultItem {
+
+    // The phrase number, stored as a string and as a number
+    String id;
+    int symbol;
+
+    // The text of the link is stored in the inherited text field.
+
+    // The type of thesaurus link
+    String linkType;
+
+    // The total frequency is stored in the inherited frequency field.
+
+    // The document frequency of the thesaurus item
+    int documentFrequency;
+
+    // Create a ResultItem for a thesaurus link
+    ResultItemLink(String newId, String newText, String newLinkType, 
+		   String tf, String df) { 
+
+	kind = linkItem;
+	id = newId;
+	symbol = Integer.valueOf(newId).intValue();
+	text = newText.trim();
+	sort = sortLinkItem;
+	linkType = newLinkType;
+	frequency = Integer.valueOf(tf).intValue();
+	documentFrequency = Integer.valueOf(df).intValue();
+    }
+
+    // Is this item a phrase?
+    public boolean isLink() { return true; }
+
+    // Return the text of the item components
+    public String hiddenText() { return id; }
+    public String docsText() { 
+	if (documentFrequency <= 0) { return ""; }
+	else { return Integer.toString(documentFrequency); }
+    }
+    public String prefixText() { 
+	if (linkType.equals("RT")) { return "Related term"; }
+	else if (linkType.equals("BT")) { return "Broader term"; }
+	else if (linkType.equals("NT")) { return "Narrower term"; }
+	else if (linkType.equals("USE")) { return "Use"; }
+	else if (linkType.startsWith("UF")) { return "Used for"; }
+	else { return linkType; }
+    }
+}
+
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultItemPhrase.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultItemPhrase.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultItemPhrase.java	(revision 20131)
@@ -0,0 +1,85 @@
+/**********************************************************************
+ *
+ * ResultItemPhrase.java -- a phrase result in the Phind applet
+ *
+ * Copyright 2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/*********************************************************************
+
+This class is used in the Phind java applet (Phind.java).
+
+It contains information describing a phrase.
+
+**********************************************************************/
+
+package org.nzdl.gsdl.Phind;
+
+public class ResultItemPhrase extends ResultItem {
+
+    // The phrase number, stored as a string and as a number
+    String id;
+    int symbol;
+
+    // The text of the phrase is split into a prefix, body, and suffix.
+    // The body is the same as the parent phrase (or search term) and 
+    // the prefix and suffix are the surrounding text.
+    String prefix;
+    String body;
+    String suffix;
+
+    // The document frequency of the phrase
+    int documentFrequency;
+
+    // Create a ResultItem for a phrase
+    ResultItemPhrase(String newId, String tf, String df, 
+		     String p, String b, String s) {
+
+	kind = phraseItem;
+
+	id = newId;
+	symbol = Integer.valueOf(newId).intValue();
+
+	sort = sortPhraseItem;
+	frequency = Integer.valueOf(tf).intValue();
+	documentFrequency = Integer.valueOf(df).intValue();
+
+	prefix = p;
+	body = b;
+	suffix = s;
+	text = (prefix + " " + body + " " + suffix);
+
+    }
+
+    // Is this item a phrase?
+    public boolean isPhrase() { return true; }
+
+    // Return the text of the item components
+    public String mainText() { return body; }
+    public String docsText() { return Integer.toString(documentFrequency); }
+    public String prefixText() { return prefix; }
+    public String suffixText() { return suffix; }
+    public String hiddenText() { return id; }
+
+}
+
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultTitle.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultTitle.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/ResultTitle.java	(revision 20131)
@@ -0,0 +1,163 @@
+/**********************************************************************
+ *
+ * ResultTitle.java -- describe the contents of a ResultBox
+ *
+ * Copyright 1997-2000 Gordon W. Paynter
+ * Copyright 2000 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/*********************************************************************
+
+This class is used in the Phind java applet (Phind.java).
+
+ResultTitle is part of the result list displayed to the user.  It lists the
+phrase in the Result box, the number of expansions it occurs in, and the
+number of documents it occurs in.
+
+**********************************************************************/
+
+package org.nzdl.gsdl.Phind;
+
+import java.awt.Canvas;
+import java.awt.Graphics;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Dimension;
+import java.awt.Color;
+
+
+public class ResultTitle extends Canvas {
+
+  // Other objects associated with this 
+  Phind phind;
+  ResultBox parent;
+  ResultCanvas canvas;
+
+  // fonts and font spacings to use
+  Font plain, bold;
+  Graphics g;
+
+  // Create a ResultTitle from the ResultBox which is its parent.
+  ResultTitle(ResultBox p) {
+
+    parent = p;
+    phind = p.phind;
+    canvas = p.c;
+    g = getGraphics();
+
+    plain = phind.plainFont;
+    bold  = phind.boldFont;
+    
+    // Note: the size() and resize() methods are deprecated, but the newer
+    // getSize() and setSize() methods fail in NetScape 4
+    //Dimension d = getSize();
+    Dimension d = size();
+    d.height = phind.fontSize + 10;
+    //setSize(d);
+    resize(d);
+    
+  }
+
+  public void update(Graphics g) {
+    paint(g);
+  }
+
+  public void paint(Graphics g) {
+
+    // calculate the canvas size, margins, and spacing
+    Dimension canvasSize = size();
+    
+    g.setFont(plain);
+    int margin = g.getFontMetrics().stringWidth(" 8888 ");
+    int y = phind.fontSize + 5;
+
+    int rightMargin = canvas.size().width;
+    int secondColumn = rightMargin - margin;
+    int firstColumn = secondColumn - margin;
+
+    g.setColor(Color.white);
+    g.fillRect(0, 0, canvasSize.width, canvasSize.height);
+    g.setColor(Color.black);
+
+
+    // What is the phrase we are searching for?
+    String phrase = parent.searchPhrase.replace('+', ' ');
+ 
+    // Construct the description phrase
+    String links = "";
+    if (parent.numberOfThesaurusLinks <= 0) {
+	links = "";
+    } else if (parent.numberOfThesaurusLinks == 1) { 
+	links = "1 link";
+    } else if (parent.thesaurusLinksRetrieved == parent.numberOfThesaurusLinks) {
+	links = parent.numberOfThesaurusLinks + " links";
+    } else {
+	links = parent.thesaurusLinksRetrieved + " of " 
+	    + parent.numberOfThesaurusLinks + " links";
+    }
+
+    String expansions = "";
+    if (parent.numberOfExpansions <= 0) {
+	expansions = "no phrases";
+    } else if (parent.numberOfExpansions == 1) { 
+	expansions = "1 phrase";
+    } else if (parent.expansionsRetrieved == parent.numberOfExpansions) {
+	expansions = parent.numberOfExpansions + " phrases";
+    } else {
+	expansions = parent.expansionsRetrieved + " of " 
+	    + parent.numberOfExpansions + " phrases";
+    }
+
+    String documents = "";
+    if (parent.numberOfDocuments <= 0) { 
+	documents = "no documents";
+    } else if (parent.documentsRetrieved == 1) {
+	documents = "1 document";
+    } else if (parent.documentsRetrieved == parent.numberOfDocuments) {
+	documents = parent.numberOfDocuments + " documents";
+    } else {
+	documents = parent.documentsRetrieved + " of " 
+	    + parent.numberOfDocuments + " documents";
+    }
+
+    String status = "(";
+    if (parent.numberOfThesaurusLinks > 0) {
+	status = status + links + ", ";
+    } 
+    status = status + expansions + ", " + documents + ")";
+
+
+    // Draw the text 
+    g.setFont(bold);
+    g.drawString(phrase, 0, y);
+    int tab = g.getFontMetrics().stringWidth(phrase + "  ");
+
+    g.setFont(plain);
+    g.drawString(status, tab, y);
+    tab = tab + g.getFontMetrics().stringWidth(status);
+    
+    if (tab < firstColumn) {
+      g.drawString("docs", firstColumn, y);
+      g.drawString("freq", secondColumn, y);
+    }
+  }
+}
Index: /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/URLUTF8Encoder.java
===================================================================
--- /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/URLUTF8Encoder.java	(revision 20131)
+++ /gsdl/stable/runtime-src/src/java/org/nzdl/gsdl/Phind/URLUTF8Encoder.java	(revision 20131)
@@ -0,0 +1,159 @@
+/**********************************************************************
+ *
+ *
+ * URLUTF8Encoder.java -- encode UTF8 String into a URL form
+ *
+ * W3C® SOFTWARE NOTICE AND LICENSE
+ *
+ * Copyright © 1994-2000 World Wide Web Consortium, 
+ * (Massachusetts Institute of Technology, Institut National de 
+ * Recherche en Informatique et en Automatique, Keio University). 
+ * All Rights Reserved.  http://www.w3.org/Consortium/Legal/
+ * 
+ * This W3C work (including software, documents, or other related items) is
+ * being provided by the copyright holders under the following license. By
+ * obtaining, using and/or copying this work, you (the licensee) agree that
+ * you have read, understood, and will comply with the following terms and
+ * conditions:
+ * 
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation, with or without modification, for any purpose and without
+ * fee or royalty is hereby granted, provided that you include the following
+ * on ALL copies of the software and documentation or portions thereof,
+ * including modifications, that you make:
+ * 
+ *   1. The full text of this NOTICE in a location viewable to users of the
+ *      redistributed or derivative work.
+ * 
+ *   2. Any pre-existing intellectual property disclaimers, notices, or terms
+ *      and conditions. If none exist, a short notice of the following form
+ *      (hypertext is preferred, text is permitted) should be used within the
+ *      body of any redistributed or derivative code: "Copyright ©
+ *      [$date-of-software] World Wide Web Consortium, (Massachusetts
+ *      Institute of Technology, Institut National de Recherche en
+ *      Informatique et en Automatique, Keio University). All Rights
+ *      Reserved. http://www.w3.org/Consortium/Legal/"
+ * 
+ *   3. Notice of any changes or modifications to the W3C files, including the
+ *      date changes were made. (We recommend you provide URIs to the location
+ *      from which the code is derived.)
+ * 
+ * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS
+ * MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
+ * PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE
+ * ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+ * 
+ * COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
+ * CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR
+ * DOCUMENTATION.
+ * 
+ * The name and trademarks of copyright holders may NOT be used in advertising
+ * or publicity pertaining to the software without specific, written prior
+ * permission. Title to copyright in this software and any associated
+ * documentation will at all times remain with copyright holders.
+ *
+ *********************************************************************/
+
+/**
+ * Provides a method to encode any string into a URL-safe
+ * form, the so-called "x-www-form-urlencoded" form.
+ * Non-ASCII characters are first encoded as sequences of
+ * two or three bytes, using the UTF-8 algorithm, before being
+ * encoded in "x-www-form-urlencoded".
+ */
+
+package org.nzdl.gsdl.Phind;
+
+public class URLUTF8Encoder
+{
+
+  final static String[] hex = {
+    "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07",
+    "%08", "%09", "%0a", "%0b", "%0c", "%0d", "%0e", "%0f",
+    "%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17",
+    "%18", "%19", "%1a", "%1b", "%1c", "%1d", "%1e", "%1f",
+    "%20", "%21", "%22", "%23", "%24", "%25", "%26", "%27",
+    "%28", "%29", "%2a", "%2b", "%2c", "%2d", "%2e", "%2f",
+    "%30", "%31", "%32", "%33", "%34", "%35", "%36", "%37",
+    "%38", "%39", "%3a", "%3b", "%3c", "%3d", "%3e", "%3f",
+    "%40", "%41", "%42", "%43", "%44", "%45", "%46", "%47",
+    "%48", "%49", "%4a", "%4b", "%4c", "%4d", "%4e", "%4f",
+    "%50", "%51", "%52", "%53", "%54", "%55", "%56", "%57",
+    "%58", "%59", "%5a", "%5b", "%5c", "%5d", "%5e", "%5f",
+    "%60", "%61", "%62", "%63", "%64", "%65", "%66", "%67",
+    "%68", "%69", "%6a", "%6b", "%6c", "%6d", "%6e", "%6f",
+    "%70", "%71", "%72", "%73", "%74", "%75", "%76", "%77",
+    "%78", "%79", "%7a", "%7b", "%7c", "%7d", "%7e", "%7f",
+    "%80", "%81", "%82", "%83", "%84", "%85", "%86", "%87",
+    "%88", "%89", "%8a", "%8b", "%8c", "%8d", "%8e", "%8f",
+    "%90", "%91", "%92", "%93", "%94", "%95", "%96", "%97",
+    "%98", "%99", "%9a", "%9b", "%9c", "%9d", "%9e", "%9f",
+    "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7",
+    "%a8", "%a9", "%aa", "%ab", "%ac", "%ad", "%ae", "%af",
+    "%b0", "%b1", "%b2", "%b3", "%b4", "%b5", "%b6", "%b7",
+    "%b8", "%b9", "%ba", "%bb", "%bc", "%bd", "%be", "%bf",
+    "%c0", "%c1", "%c2", "%c3", "%c4", "%c5", "%c6", "%c7",
+    "%c8", "%c9", "%ca", "%cb", "%cc", "%cd", "%ce", "%cf",
+    "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
+    "%d8", "%d9", "%da", "%db", "%dc", "%dd", "%de", "%df",
+    "%e0", "%e1", "%e2", "%e3", "%e4", "%e5", "%e6", "%e7",
+    "%e8", "%e9", "%ea", "%eb", "%ec", "%ed", "%ee", "%ef",
+    "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
+    "%f8", "%f9", "%fa", "%fb", "%fc", "%fd", "%fe", "%ff"
+  };
+
+  /**
+   * Encode a string to the "x-www-form-urlencoded" form, enhanced
+   * with the UTF-8-in-URL proposal. This is what happens:
+   *
+   * <ul>
+   * <li><p>The ASCII characters 'a' through 'z', 'A' through 'Z',
+   *        and '0' through '9' remain the same.
+   *
+   * <li><p>The space character ' ' is converted into a plus sign '+'.
+   *
+   * <li><p>All other ASCII characters are converted into the
+   *        3-character string "%xy", where xy is
+   *        the two-digit hexadecimal representation of the character
+   *        code
+   *
+   * <li><p>All non-ASCII characters are encoded in two steps: first
+   *        to a sequence of 2 or 3 bytes, using the UTF-8 algorithm;
+   *        secondly each of these bytes is encoded as "%xx".
+   * </ul>
+   *
+   * @param s The string to be encoded
+   * @return The encoded string
+   */
+  public static String encode(String s)
+  {
+    StringBuffer sbuf = new StringBuffer();
+    int len = s.length();
+    for (int i = 0; i < len; i++) {
+      int ch = s.charAt(i);
+      if ('A' <= ch && ch <= 'Z') {		// 'A'..'Z'
+	sbuf.append((char)ch);
+      } else if ('a' <= ch && ch <= 'z') {	// 'a'..'z'
+	sbuf.append((char)ch);
+      } else if ('0' <= ch && ch <= '9') {	// '0'..'9'
+	sbuf.append((char)ch);
+      } else if (ch == ' ') {			// space
+	sbuf.append('+');
+      } else if (ch <= 0x007f) {		// other ASCII
+	sbuf.append(hex[ch]);
+      } else if (ch <= 0x07FF) {		// non-ASCII <= 0x7FF
+	sbuf.append(hex[0xc0 | (ch >> 6)]);
+	sbuf.append(hex[0x80 | (ch & 0x3F)]);
+      } else {					// 0x7FF < ch <= 0xFFFF
+	sbuf.append(hex[0xe0 | (ch >> 12)]);
+	sbuf.append(hex[0x80 | ((ch >> 6) & 0x3F)]);
+	sbuf.append(hex[0x80 | (ch & 0x3F)]);
+      }
+    }
+    return sbuf.toString();
+  }
+
+}
+
+
Index: /gsdl/stable/runtime-src/src/oaiservr/Makefile.in
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/Makefile.in	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/Makefile.in	(revision 20131)
@@ -0,0 +1,152 @@
+###########################################################################
+#
+# Makefile -- runtime-src/src/oaiservr
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+RUNTIME_DIR = $(GSDL_DIR)/runtime-src
+
+INDEXERS_DIR = $(COMMON_DIR)/indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+COLSERVR_DIR = $(RUNTIME_DIR)/src/colservr
+PROTOCOL_DIR = $(RUNTIME_DIR)/src/protocol
+RECPT_DIR = $(RUNTIME_DIR)/src/recpt
+
+
+ENABLE_ACCENTFOLD = @ENABLE_ACCENTFOLD@
+ifeq ($(ENABLE_ACCENTFOLD), 1)
+ACCENTFOLD_LIBS = $(INDEXERS_DIR)/packages/unac/libunac.a 
+else
+ACCENTFOLD_LIBS = 
+endif
+
+USE_SQLITE = @USE_SQLITE@
+ifeq ($(USE_SQLITE), 1)
+SQLITE_LIBS = $(COMMON_PACKAGES_DIR)/sqlite/lib/libsqlite3.a -ldl -lpthread
+else
+SQLITE_LIBS = 
+endif
+
+
+CC = @CC@
+CFLAGS = @CFLAGS@ @COMPAT32BITFLAGS@
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+INCLUDES = -I$(COMMON_DIR)/src/lib -I$(COLSERVR_DIR) -I$(PROTOCOL_DIR) -I$(RECPT_DIR) -I$(INDEXERS_DIR)/mgpp/text
+LDFLAGS = @LDFLAGS@ @COMPAT32BITFLAGS@
+LIBS = @LIBS@ $(COMMON_PACKAGES_DIR)/gdbm/lib/libgdbm.a -L$(COMMON_PACKAGES_DIR)/expat/lib -lexpat \
+	$(ACCENTFOLD_LIBS) $(SQLITE_LIBS)
+INSTALL = @INSTALL@
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(INCLUDES)
+CXXLINK = $(CXX) $(LDFLAGS) -o $@
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) -o $@ $< 
+
+
+RECPT_OBJECTS = \
+	$(RECPT_DIR)/cgiargs.o \
+	$(RECPT_DIR)/cgiutils.o \
+	$(RECPT_DIR)/htmlutils.o
+
+SOURCES = \
+	abstractlistaction.cpp \
+	dublincore.cpp \
+	qualified_dublincore.cpp \
+	identifyaction.cpp \
+	listidsaction.cpp \
+	listrecsaction.cpp \
+	listsetsaction.cpp \
+	metaformat.cpp \
+	metaformatsaction.cpp \
+	oaiaction.cpp \
+	oaiargs.cpp \
+	oaiconfig.cpp \
+	oaidispatcher.cpp \
+	oaimain.cpp \
+	oaitools.cpp \
+	recordaction.cpp \
+	resumptiontoken.cpp \
+	rfc1807.cpp
+
+OBJECTS = \
+	abstractlistaction.o \
+	dublincore.o \
+	qualified_dublincore.o \
+	identifyaction.o \
+	listidsaction.o \
+	listrecsaction.o \
+	listsetsaction.o \
+	metaformat.o \
+	metaformatsaction.o \
+	oaiaction.o \
+	oaiargs.o \
+	oaiconfig.o \
+	oaidispatcher.o \
+	oaimain.o \
+	oaitools.o \
+	recordaction.o \
+	resumptiontoken.o \
+	rfc1807.o
+
+GSDL_LIBS = \
+	$(PROTOCOL_DIR)/gsdlprotocol.a \
+	$(COLSERVR_DIR)/gsdlcolservr.a \
+	$(INDEXERS_DIR)/mg/src/text/libmgtext.a \
+	$(INDEXERS_DIR)/mg/lib/libmglib.a \
+	$(INDEXERS_DIR)/mgpp/text/libmgpptext.a \
+	$(INDEXERS_DIR)/mgpp/lib/libmgpplib.a \
+	$(COMMON_DIR)/src/lib/gsdllib.a
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS) \
+	$(RECPT_OBJECTS) \
+	$(GSDL_LIBS)
+
+EXECUTABLE = oaiserver.cgi
+
+
+# Default target: make the oaiserver executable
+all: $(EXECUTABLE)
+
+$(EXECUTABLE): $(EXECUTABLE_OBJECTS)
+	$(CXXLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/cgi-bin
+
+clean:
+	rm -f $(OBJECTS) $(EXECUTABLE)
+
+distclean:
+	rm -f $(OBJECTS) $(EXECUTABLE) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/runtime-src/src/oaiservr/README.txt
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/README.txt	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/README.txt	(revision 20131)
@@ -0,0 +1,101 @@
+OAI Server Configuration Instructions
+-------------------------------------
+
+Greenstone needs some configuration before successfully supporting OAI serving.  This consists of three steps:
+
+1) Server-wide configuration to support vital OAI commands such as Identify.
+   This allows the OAI client to obtain information on the maintainer of
+   the server, etc.  See the OAI documentation for further information on
+   the Identify verb.  These configurations are kept in gsdl/etc/oai.cfg.
+
+2) Configuring collections to be 'active' OAI collections; just as collections
+   in Greenstone can be 'private' or 'public', collections can similarly be
+   'visible' or 'invisible' to OAI.  By default, collections are NOT served
+   via OAI - you have to enable them by adding each collection's name to a
+   list in gsdl/etc/oai.cfg.
+
+3) Mapping your collection metadata to a "Namespace" supported by OAI.  At
+   present, Greenstone supports the Dublin Core metadata format alone in OAI,
+   and metadata fields in a Greenstone collection must be mapped into the
+   Dublin Core namespace.  This configuration can be done either server-wide,
+   for all collections, in gsdl/etc/oai.cfg or in the etc/collect.cfg of
+   each individual collection.
+
+This documentation explains how to set up Greenstone's configuration for steps 1-3 above, install, deplay and test OAI on your Greenstone system.
+
+Part 1: Server-Wide Configuration Information
+---------------------------------------------
+
+Your OAI server should provide some basic information on the collections it holds as a whole.  For this purpose, all collections on your server are treated the same: you cannot have different information for each collection.  In this section, we describe what information you should provide, and how to configure Greenstone correctly to provide it.
+
+The basic server-wide information is:
+  * The OAI repository (server) name - this is a human readable form such
+    as "The Research Authority's OAI Server".
+  * The central administrative email address for the OAI repository.
+  * The base URL for the repository.
+  * Which version of OAI the repository supports/delivers.
+  * A free text item of information about the OAI repository - e.g. its
+    purpose, size, origins, etc.
+
+These items are kept in the following items of gsdl/etc/oai.cfg.  The syntax rules for these configuration items are the same as for gsdl/etc/main.cfg -  e.g. strings containing spaces should be enclosed in quotation marks.  See the main Greenstone configuration documentation for further information.
+
+  * repositoryName
+       One item only, free text.
+  * maintainer
+       One item only, as a valid email address
+  * baseURL
+       One item only, see the example in the oai.cfg file.
+  * httpdomain 
+       NB: in the gsdlsite.cfg file, NOT oai.cfg
+       Should not require specific configuration if your Greenstone install
+       is already operational through your web server.
+  * oaiversion
+       One item only, which should be either "1.1 or "2.0"
+  * oaiinfo
+       Numerous items, which are usually in a label and value pair.
+       An example item may be:
+          oaiinfo sponsor "The Big Cheese Corporation"
+
+Sample items are already provided in the default oai.cfg file - please ensure that you complete these in your preferred text editor.
+
+
+Part 2: Enabling Collections
+----------------------------
+
+In addition to the items above, one further sort of item needs to be added to gsdl/etc/oai.cfg - a list of the collections that should be made available to OAI clients.  This list is supplied in one or more lines in gsdl/etc/oai.cfg in the form:
+
+  oaicollection OAIDemo HDL
+
+The first item in each line should be the same - "oaicollection" - followed by one or more collection names.  Each collection name should be the name of the folder/directory in the gsdl/collect directory which holds the collection.
+
+Once these items have been added to gsdl/etc/oai.cfg, the final stage of the OAI configuration can begin: mapping from a collection's own metdata fields into the Dublin Core metadata fields used by OAI.  This will be detailed in the folloowing section of this document.
+
+
+Part 3: Mapping fields
+----------------------
+
+In Greenstone, metadata fields are created by the collection designer.  These may follow an accepted standard - e.g. Dublin Core - be a modification or extension of an accepted standard, or a bespoke format specific to the needs of the particular collection.  As Greenstone installer, you should have decided upon one of these three approaches already.  You may have chosen one of the standard metadata structures incorporated into the Greenstone Librarian Interface (GLI), or created your own using your own metadata files and automatically extracted information from your document files.  Whatever the approach you have used for obtaining the metadata in your collection, or whatever the fields are that you have used in your collection, the approach to linking these fields (mapping them) to the OAI Dublin Core format is the same.
+
+The mapping of fields is done in two ways: first, globally for all collections, and secondly specifically for one collection.  The syntax for the configuration items to achieve these different mappings is the same.  The file in which they are placed determines whether they apply to all collections, are just one.  Global mappings are found with the other OAI configuration items in gsdl/etc/main.cfg whilst collection-specific mappings are placed in the etc/collect.cfg file of the collection itself.
+
+Mapping items in the configuration file take the following format:
+
+  oaimapping <greenstone fieldname> <dublin core fieldname>
+
+The syntax of each of the two fieldnames given above requires a little more detail; we will take the Dubline Core fieldname first.  
+
+The Dublin Core fieldsname should be given in the form "DC:<fieldname>", as OAI can support other metadata formats, and thus we use "DC:" to be clear that we are mapping to Dublin Core.  The fieldnames available for Dublin Core can be found on the central Dublin Core website at http://www.dublincore.org/.
+
+The Greenstone fieldname can be in two formats.  The simpler one is simply the name of the field to map from.  The more complex one has the name of the collection placed in front of the field name, followed by a colon.  e.g. "demo:Title" would mean the metadata field "Title" in the collection called "demo".  Using this, all mappings can be stored in the central gsdl/etc/oai.cfg file if you wish, and we recommend this approach.
+
+Let us recap at this point with a few example items for a gsdl/etc/oai.cfg:
+
+oaimapping Author dc.Creator
+oaimapping dls.Title  dc.Title
+oaimapping Photos:fileformat dc.Format
+
+The first item maps any occurrence of 'Author' in any collection to the Dublin Core 'Creator' field (there is no 'Author' field in DC).  The second item maps 'dls.Title' to 'dc.Title'. Finally, in the specific collection 'Photos', we will map the unique metadata field 'fileformat' to the Dublin Core 'Format' field.
+
+
+Installation and Testing
+------------------------
Index: /gsdl/stable/runtime-src/src/oaiservr/abstractlistaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/abstractlistaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/abstractlistaction.cpp	(revision 20131)
@@ -0,0 +1,337 @@
+#include "abstractlistaction.h"
+#include "recptprototools.h"
+
+#include "oaitools.h"
+
+//--------------------------------------------------------------------------------------------------
+
+bool abstractlistaction::output_content(ostream &output, recptproto *protocol, oaiargs &params)
+{
+  bool   prevDocSeen;
+  ResumptionToken *token = NULL;
+
+  // start the call; clear down the total number of output documents
+  this->outputDocs = 0;
+
+  // We don't actually handle resumptionTokens yet; if we get one, ignore it
+  if (params["resumptionToken"] != "") {
+    token = new ResumptionToken(params["resumptionToken"]);
+  }
+
+  this->replyToken = NULL;
+
+  // if we've been asked for a set, then use it!
+  if (params["set"] != "") {
+    // get the children of this set
+    text_t gsdlSet = params["set"];
+    text_t gsdlCollect = "";
+
+    // given 'demo:CL2', toGSDL returns 'demo' in gsdlCollect and 'CL2' in gsdlSet. If there is no further
+    // set specified after the name of the collection however, then gsdlSet is empty.
+    oaiclassifier::toGSDL(gsdlCollect, gsdlSet);
+
+    // If gsdlSet is empty, then the user is requesting all the identifiers for the collection, so 
+    // we simply output all docs via their oai_id tag. But if a specific subset IS requested, then
+    // use recurse_set() to traverse any sub classifiers to find the relevant docs.
+    if(gsdlSet == ""){
+      ColInfoResponse_t cinfo;
+      comerror_t err;
+      this->output_content_for_col(output, protocol, gsdlCollect, cinfo, err, params);
+    }
+    else {
+      if (this->check_classifier(protocol, gsdlCollect, gsdlSet)) {
+	this->recurse_set(output, protocol, gsdlCollect, gsdlSet, params, token);
+      }
+    }
+  }
+  // output all records in all hierarchies
+  else {
+    this->output_content_for_all(output, protocol, params);
+  }
+
+  // If - regardless of set required - no documents have been seen, throw an error.
+  if (this->configuration->getOAIVersion() >= 200 && this->prevDocSeen == false) {
+    errorType = "noRecordsMatch";
+    this->output_error(output, errorType);
+
+    return false;
+  }
+
+  // do a resumption token if required; errors cancel a token...
+  if (this->replyToken != NULL && this->errorType == "") {
+    // Don't add any whitespace around the resumption token as it can confuse harvesters/validators
+    output << "  <resumptionToken>" << this->replyToken->getToken() << "</resumptionToken>" << endl;
+  }
+
+  return true;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+void abstractlistaction::output_content_for_col(ostream &output, recptproto *protocol, text_t &gsdlCollect,
+						ColInfoResponse_t &cinfo, comerror_t &err, oaiargs &params)
+{ int startDoc = 0;
+
+  text_t metadataPrefix = params["metadataPrefix"];
+
+  // check resumption token
+  if (params["resumptionToken"] != "") {
+    ResumptionToken token(params["resumptionToken"]);
+    if (token.getCollection() == gsdlCollect) {
+      startDoc = token.getPosition() - 1; // first document is said to be 1..
+      metadataPrefix = "oai_dc";  // TO DO: This should come from the resumption token
+    }
+  }
+
+  // Get the OAI nodes from the info db file
+  text_t oai_root_node = "oai";
+  text_tset metadata;  // Must be empty for efficiency
+  FilterResponse_t response;
+  get_children(oai_root_node, gsdlCollect, "", metadata, false, protocol, response, *this->logout);
+  
+  // If numDocs is 0, do nothing - this->prevDocSeen will stay false if this is the only collection
+  // looked at, or will keep whatever value it had prior to this col (ensures that if the flag has
+  // been set to true by a previous collection that this won't overwrite it to be false). 
+  if (response.docInfo.size() > 0) {
+    int errorCount      = 0; // Count the number of errors found in the given collection
+
+    for (long i = startDoc; i < response.docInfo.size(); ++i) {
+      if (errorCount > 3) { // If num errors reaches the cut-off value, bail.
+	cerr << "Error: too many records(" << errorCount << ") in the " << gsdlCollect 
+	     << " collection have invalid or non-existant oai_ids - skipping remainder of collection.\n";
+	return;
+      }
+      
+      text_t oai_id = "oai.";
+      oai_id += i;
+      
+      text_t gsdl_id = oaiclassifier::getGSDL_OID(gsdlCollect, oai_id, protocol, *this->logout);
+      
+      if (gsdl_id == "") { // If the string is empty, then the document didn't have an oai_id, so
+	++errorCount;     // increase error count
+	continue;
+      }
+
+
+      // Check that the item with the 0ID 'gsdl_id' has a lastmodified field that fits within
+      // the required date range (if specified).
+      if (this->inDateRange(params["from"], params["until"], gsdlCollect, gsdl_id, protocol, output)) {
+	if (this->output_document(output, protocol, gsdlCollect, gsdl_id, metadataPrefix)) {
+	  // this should be an IF statement, where prevDocSeen is only set to true if the above
+	  // function call returns true (indicating that the doc supported the metadata prefix) but
+	  // for some reason this is always false. This means that if no doc in the requested set supports
+	  // the metadata format, the "no records match" error that should be thrown won't be...
+	  //
+	  // GRB: the above comment is no longer true; proper checks are made
+	  this->prevDocSeen = true;
+	  ++this->outputDocs;
+	}
+      }
+
+      // if we've output the number of resumption documents; prepare a resumptionToken
+      if (this->outputDocs == this->configuration->resumeAfter()) {
+	this->replyToken = new ResumptionToken(gsdlCollect, "", "");
+	this->replyToken->setPosition("", i+2);
+	break;
+      }
+    }
+
+    cinfo.clear(); // Clear for next collection to use (if there is one).
+  }
+}
+
+//--------------------------------------------------------------------------------------------
+// Returns true if at least one document record is found
+void abstractlistaction::output_content_for_all(ostream &output, recptproto *protocol, oaiargs &params)
+{
+  ColInfoResponse_t cinfo;
+  comerror_t        err;
+  text_tarray       collections;
+  text_t            gsdlCollect = "";
+  ResumptionToken   *token = NULL;
+
+  // get a list of the collections available
+  collections = this->configuration->getCollectionsList();
+  //  protocol->get_collection_list(collections, err, output); 
+  
+  if (params["resumptionToken"] != "") {
+    token = new ResumptionToken(params["resumptionToken"]);
+  }
+
+  for(int current_col = 0; current_col < collections.size(); ++current_col){
+    gsdlCollect = collections[current_col];
+
+    // ignore all leading collections before the one that matches the resumptiontoken
+    if (token != NULL &&
+	token->getCollection() != gsdlCollect)
+    { continue;
+    }
+
+    this->output_content_for_col(output, protocol, gsdlCollect, cinfo, err, params);
+
+    // once we've output at least one collection, continue 
+    // outputting all others until the resumption total hits
+    token = NULL; 
+
+    if (this->outputDocs == this->configuration->resumeAfter()) {
+      break;
+    }
+  }
+}
+
+//-------------------------------------------------------------------------------------------------
+// Check that the requested from/until dates don't include a time, as this would be asking for too
+// fine a level of granularity, one that greenstone doesn't support. An OAI error must be thrown.
+/*
+bool abstractlistaction::granularityTooFine(text_t &from, text_t &until)
+{
+  if (from != "" && from.){
+    
+  }
+  
+}
+*/
+//-------------------------------------------------------------------------------------------------
+
+bool abstractlistaction::check_classifier(recptproto *protocol, const text_t &collection,
+					  const text_t &classifier)
+{ text_t topClass;
+  FilterResponse_t response;
+  text_tset        metadata;
+  ofstream         logout("oai.log", ios::app);
+
+  // exclude false children of a top-level classifier immediately...
+  if (!get_info(classifier, collection, "", metadata, false, protocol, response, logout)) {
+    return false;
+  }
+  
+  // now check the top-level parent
+  metadata.insert("supportsmemberof");
+
+  text_t::const_iterator dot = findchar(classifier.begin(), classifier.end(), '.');
+  if (dot != classifier.end()) {
+    topClass = substr(classifier.begin(), dot);
+  }
+  else {
+    topClass = classifier;
+  }
+
+  if (!get_info(topClass, collection, "", metadata, false, protocol, response, logout)) {
+    return false;
+  }
+  
+  if (response.docInfo[0].metadata["supportsmemberof"].values.size() == 0) {
+    return false;
+  }
+
+  if (response.docInfo[0].metadata["supportsmemberof"].values[0] != "true") {
+    return false;
+  }
+
+  return true;
+}
+
+void abstractlistaction::recurse_set(ostream &output, recptproto *protocol, const text_t &collection, 
+				     const text_t &classifier, oaiargs &params, ResumptionToken *resumptionToken)
+{
+  // metadata for this call
+  FilterResponse_t response;
+  text_tset        metadata;
+  ofstream         logout("oai.log", ios::app);
+  text_t           from = params["from"];
+  text_t           until = params["until"];
+  text_t           metadataPrefix = params["metadataPrefix"];
+  //  ResumptionToken  resumptionToken(params["resumptionToken"]);
+  int              startPos = 0;
+
+  // This is a recursive function, and so just because the current set is empty doesn't mean we necessarily
+  // want to throw a 'noRecordsMatch' error; another set (parent/sibling/child) may have had documents. It
+  // is therefore not enough to check that the response object in the current iteration has no docs - we
+  // must also verify that NO OTHER set has had any documents. This is done with the 'prevDocSeen' flag.
+  // It is set to FALSE initially, but as soon as we see a set that isn't empty, it is set to TRUE. The 
+  // 'noRecordsMatch' error will only be thrown if, after all appropriate sets have been recursed into, 
+  // the 'prevDocSeen' flag is still FALSE. The function returns false if no docs were seen, allowing us to 
+  // throw the noRecordsMatch error.
+  
+  //  bool prevDocSeen = false;
+
+  get_children(classifier, collection, "", metadata, false, protocol, response, *this->logout);
+
+  if (params["resumptionToken"] != "") {
+    // if we're at a resumptionToken
+    if (classifier == resumptionToken->getNode()) {
+      startPos = resumptionToken->getPosition();
+    }
+    else {
+      text_t fullNode = resumptionToken->getNode();
+      text_t::iterator leafIter = fullNode.begin() + classifier.size();
+
+      // if the next character isn't a dot, blow up!
+      if (*leafIter != '.') {
+	// fatal error;
+	exit(1);
+      }
+      
+      // get the first '.' after the current classifier point;
+      text_t::iterator separator = findchar(leafIter + 1, fullNode.end(), '.');
+
+      // now, create a new subpath
+      text_t nextNode = substr(fullNode.begin(), separator);
+
+      // seek forward; TODO: improve performance of this 
+      for (int c = 0; c < response.numDocs; ++c) {
+	if (response.docInfo[c].OID == nextNode) {
+	  startPos = c;
+	  break;
+	}
+      }
+    }
+
+    // We need to subtract one from the startPos value to turn it into an index value
+    startPos--;
+  }
+  
+  for (int c = startPos; c < response.numDocs; ++c) {
+    text_t child = response.docInfo[c].OID;
+    
+    // distinguish classifiers and documents by checking whether OID 
+    // starts with CL or not
+    text_t childHead;
+    text_t::const_iterator start = child.begin();
+    text_t::const_iterator here  = child.begin();
+    here += 2;
+    childHead = substr(start, here);
+    
+    // documents we output now
+    if (childHead != "CL") {
+      // Check that the item with the 0ID 'gsdl_id' has a lastmodified field that fits
+      // within the required date range (if specified)
+      if (this->inDateRange(from, until, collection, child, protocol, output)) {
+	// TODO: check that the document can be disseminated in the required metadataPrefix
+
+	if (this->output_document(output, protocol, collection, child, metadataPrefix)) {
+	  this->prevDocSeen = true;
+	  ++this->outputDocs;
+	}
+      }
+    }
+    // children which are classifiers are recursed
+    else {
+      if (resumptionToken != NULL) {
+	int depth = countchar(classifier.begin(), classifier.end(), '.');
+	resumptionToken->setOffset(depth, c+2);
+      }
+      this->recurse_set(output, protocol, collection, child, params, resumptionToken);
+    }
+
+    if (this->outputDocs == this->configuration->resumeAfter()) {
+      this->replyToken = new ResumptionToken(collection, params["set"], "");
+      this->replyToken->setPosition(classifier, c+2);      
+      break;
+    }
+  }
+}
+
+
+
+
Index: /gsdl/stable/runtime-src/src/oaiservr/abstractlistaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/abstractlistaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/abstractlistaction.h	(revision 20131)
@@ -0,0 +1,25 @@
+#ifndef _ABSTRACTLISTACTION_H_
+#define _ABSTRACTLISTACTION_H_
+
+#include "oaiaction.h"
+#include "resumptiontoken.h"
+
+class abstractlistaction : public oaiaction
+{ 
+ public:
+  abstractlistaction(const text_t &name) : oaiaction(name) {this->prevDocSeen = false;}
+  virtual bool output_document(ostream &output, recptproto *protocol, const text_t &collection, 
+			       const text_t &OID, const text_t &metadataPrefix) = 0;
+  virtual bool output_content(ostream &output, recptproto *protocol, oaiargs &params);
+  virtual void output_content_for_all(ostream &output, recptproto *protocol, oaiargs &params);
+  virtual void output_content_for_col(ostream &output, recptproto *protocol, text_t &gsdlCollect, 
+				      ColInfoResponse_t &cinfo, comerror_t &err, oaiargs &params);
+  virtual void recurse_set(ostream &output, recptproto *protocol, const text_t &collection, 
+			   const text_t &classifier, oaiargs &params, ResumptionToken *resumptionToken);
+ protected:
+  bool prevDocSeen;
+  int  outputDocs;
+  ResumptionToken *replyToken;
+  bool check_classifier(recptproto *protocol, const text_t &collection, const text_t &classifier);
+};
+#endif
Index: /gsdl/stable/runtime-src/src/oaiservr/dublincore.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/dublincore.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/dublincore.cpp	(revision 20131)
@@ -0,0 +1,89 @@
+
+#include "dublincore.h"
+
+dublin_core::dublin_core() : metaformat() {
+  // These element names taken from the schema
+  // http://www.openarchives.org/OAI/2.0/oai_dc.xsd
+  elementSet.insert("contributor");
+  elementSet.insert("coverage");
+  elementSet.insert("creator");
+  elementSet.insert("date");
+  elementSet.insert("description");
+  elementSet.insert("format");
+  elementSet.insert("identifier");
+  elementSet.insert("language");
+  elementSet.insert("publisher");
+  elementSet.insert("relation");
+  elementSet.insert("rights");
+  elementSet.insert("source");
+  elementSet.insert("subject");
+  elementSet.insert("title");
+  elementSet.insert("type");
+ 
+
+}
+
+const text_t dublin_core::formatName() {
+  return "oai_dc";
+}
+
+const text_t dublin_core::formatPrefix() {
+  return "dc";
+}
+
+bool dublin_core::output_record(ostream &output, recptproto *protocol, const text_t &collection, 
+				const text_t &record_OID) 
+{
+  return metaformat::output_record(output, protocol, collection, record_OID);
+}
+
+void dublin_core::output_metadata_header(ostream &output)
+{ 
+  output << "    <metadata>\n";
+  
+  if (this->oaiConfigure->getOAIVersion() <= 110){
+    // output dublin core wrapper for OAI v1.1
+    output << "      <dc xmlns=\"http://purl.org/dc/elements/1.1/\"\n"
+	   << "          xmlns:xsi=\"http://www.w3c.org/2001/XMLSchema-instance\"\n"
+	   << "          xsi:schemaLocation=\"http://purl.org/dc/elements/1.1/\n"
+	   << "                              http://www.openarchives.org/OAI/1.1/dc.xsd\">\n";
+  }
+  else { 
+    output << "      <oai_dc:dc\n"
+	   << "          xmlns:oai_dc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\"\n"
+	   << "          xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n"
+	   << "          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+	   << "          xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai_dc/\n"
+	   << "                              http://www.openarchives.org/OAI/2.0/oai_dc.xsd\">\n";
+  }
+}
+
+void dublin_core::output_metadata_footer(ostream &output)
+{
+  if (this->oaiConfigure->getOAIVersion() <= 110) {
+    output << "      </dc>" << endl;
+  }
+  else {
+    output << "      </oai_dc:dc>" << endl;
+  }
+
+  output << "    </metadata>" << endl; 
+  output.flush();
+}
+
+bool dublin_core::output_formatdata(ostream &output)
+{
+  output << "    <metadataPrefix>oai_dc</metadataPrefix>" << endl;
+
+  if (this->oaiConfigure->getOAIVersion() <= 110) {
+    output << "    <schema>http://www.openarchives.org/OAI/1.1/dc.xsd</schema>" << endl
+	   << "    <metadataNamespace>http://purl.org/dc/elements/1.1/</metadataNamespace>" << endl;
+  }
+  else {
+    output << "    <schema>http://www.openarchives.org/OAI/2.0/oai_dc.xsd</schema>" << endl
+	   << "    <metadataNamespace>http://www.openarchives.org/OAI/2.0/oai_dc/</metadataNamespace>" 
+	   << endl;
+  }
+  return true;
+}
+
Index: /gsdl/stable/runtime-src/src/oaiservr/dublincore.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/dublincore.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/dublincore.h	(revision 20131)
@@ -0,0 +1,18 @@
+#include "metaformat.h"
+
+class dublin_core : public metaformat
+{
+ protected:
+  virtual void output_metadata_header(ostream &output);
+  virtual void output_metadata_footer(ostream &output);
+
+ public:
+  dublin_core(); 
+  virtual const text_t formatName();
+  virtual const text_t formatPrefix();
+  virtual bool output_record(ostream &output, recptproto *protocol, const text_t &collection, 
+			     const text_t &record_OID);
+  virtual bool output_formatdata(ostream &output);
+};
+
+
Index: /gsdl/stable/runtime-src/src/oaiservr/identifyaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/identifyaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/identifyaction.cpp	(revision 20131)
@@ -0,0 +1,90 @@
+#include "identifyaction.h"
+
+bool identifyaction::validateAction(recptproto *protocol, oaiargs &params)
+{ 
+  // ----------------------------------------------------------------------------
+  //  1. Check for invalid arguments
+  // ----------------------------------------------------------------------------
+  bool invalid_argument_supplied = false;
+  text_tmap::const_iterator param_iterator = params.begin();
+  while (param_iterator != params.end())
+  {
+    // Check for arguments that aren't valid for this action
+    if (param_iterator->first != "verb")
+    {
+      // We've found an invalid argument
+      invalid_argument_supplied = true;
+
+      // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
+      params.erase(param_iterator->first);
+    }
+
+    param_iterator++;
+  }
+
+  // If we found an invalid argument it's an error, so don't go any further 
+  if (invalid_argument_supplied)
+  {
+    this->errorType = "badArgument";
+    return false;
+  }
+
+  // ----------------------------------------------------------------------------
+  //  2. Handle any exclusive arguments
+  // ----------------------------------------------------------------------------
+
+  // None!
+
+  // ----------------------------------------------------------------------------
+  //  3. Handle any required arguments
+  // ----------------------------------------------------------------------------
+
+  // None!
+
+  // ----------------------------------------------------------------------------
+  // 4. Check any remaining arguments
+  // ----------------------------------------------------------------------------
+
+  // None!
+
+  // If we've reached here everything must be fine
+  this->errorType = "";
+  return true;
+}
+
+bool identifyaction::output_content(ostream &output, recptproto *protocol, oaiargs &params)
+{
+  // Get the repository name (some human-readable name for the site, or superset of collections)
+  text_t repositoryName = this->configuration->getCollectionConfig("", "repositoryName");
+  // Get admin's email address (i.e. the site maintainer)
+  text_t maintainer = this->configuration->getCollectionConfig("", "maintainer");
+  text_t version = (this->configuration->getOAIVersion() <= 110) ? (text_t)"1.1":(text_t)"2.0";
+
+  text_t baseURL = this->configuration->getCollectionConfig("", "baseURL");
+  
+  output << "  <repositoryName>"  << repositoryName << "</repositoryName>" << endl;
+  output << "  <baseURL>"         << baseURL     << "</baseURL>" << endl; // Tack on the app name
+  output << "  <protocolVersion>" << version        << "</protocolVersion>" << endl;
+  output << "  <adminEmail>"      << maintainer     << "</adminEmail>" << endl;
+
+  if(version == "2.0"){
+    // earliestDatestamp *should* be the YYYY-MM-DD format of the oldest lastmodified record in the
+    // repository, but we're just setting it to be the default oldest possible date - ugly, but judged
+    // not to be worth the effort of trolling through all the lastmodified dates (by others with more 
+    // say than me)
+    output << "  <earliestDatestamp>1970-01-01</earliestDatestamp>\n"
+	   << "  <deletedRecord>no</deletedRecord>\n"
+	   << "  <granularity>YYYY-MM-DD</granularity>\n";
+  }
+  // list all configuration information
+  text_tmap::iterator here = this->configuration->getInformation()->begin();
+  text_tmap::iterator end  = this->configuration->getInformation()->end();
+  while (here != end) {
+    output << "  <" << here->first << ">" << here->second;
+    output << "  </" << here->first << ">" << endl;
+    ++here;
+  }
+  
+  return true;
+}
+
Index: /gsdl/stable/runtime-src/src/oaiservr/identifyaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/identifyaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/identifyaction.h	(revision 20131)
@@ -0,0 +1,13 @@
+#include "oaiaction.h"
+
+#include "oaiconfig.h"
+
+class identifyaction : public oaiaction
+{
+ public:
+  identifyaction() : oaiaction("Identify") {}
+  virtual bool validateAction(recptproto *protocol, oaiargs &params);
+ protected:
+  bool output_content(ostream &output, recptproto *protocol, oaiargs &params);
+};
+
Index: /gsdl/stable/runtime-src/src/oaiservr/listidsaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/listidsaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/listidsaction.cpp	(revision 20131)
@@ -0,0 +1,228 @@
+#include "listidsaction.h"
+#include "recptprototools.h"
+#include "oaitools.h"
+
+//--------------------------------------------------------------------------------------------------
+
+bool listidsaction::validateAction(recptproto *protocol, oaiargs &params)
+{
+  // ----------------------------------------------------------------------------
+  //  1. Check for invalid arguments
+  // ----------------------------------------------------------------------------
+  bool invalid_argument_supplied = false;
+  text_tmap::const_iterator param_iterator = params.begin();
+  while (param_iterator != params.end())
+  {
+    // Check for arguments that aren't valid for this action
+    if (param_iterator->first != "verb" &&
+	param_iterator->first != "from" &&
+	param_iterator->first != "until" &&
+	param_iterator->first != "set" &&
+	param_iterator->first != "resumptionToken" &&
+	param_iterator->first != "metadataPrefix")
+    {
+      // We've found an invalid argument
+      invalid_argument_supplied = true;
+
+      // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
+      params.erase(param_iterator->first);
+    }
+
+    // The metadataPrefix argument is not allowed in OAI v1.1
+    else if (param_iterator->first == "metadataPrefix" && this->configuration->getOAIVersion() <= 110)
+    {
+      // We've found an invalid argument
+      invalid_argument_supplied = true;
+
+      // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
+      params.erase(param_iterator->first);
+    }
+
+    param_iterator++;
+  }
+
+  // If we found an invalid argument it's an error, so don't go any further 
+  if (invalid_argument_supplied)
+  {
+    this->errorType = "badArgument";
+    return false;
+  }
+
+  // ----------------------------------------------------------------------------
+  //  2. Handle any exclusive arguments
+  // ----------------------------------------------------------------------------
+
+  //  The resumptionToken argument is exclusive
+  if (params["resumptionToken"] != "")
+  {
+    // This argument is exclusive, so no other arguments are allowed (except "verb" of course)
+    if (params.getSize() != 2)
+    {
+      this->errorType = "badArgument";
+      return false;
+    }
+
+    // Check the resumption token is valid
+    ResumptionToken token(params["resumptionToken"]);
+    if (token.isValid())
+    {
+      // Everything is fine, and we don't continue further because this is an exclusive argument
+      this->errorType = "";
+      return true;
+    }
+    else
+    {
+      // There was an error with the resumption token
+      this->errorType = "badResumptionToken";
+      return false;
+    }
+  }
+
+  // ----------------------------------------------------------------------------
+  //  3. Handle any required arguments
+  // ----------------------------------------------------------------------------
+
+  // OAI v2.0 requires metadataPrefix
+  if (this->configuration->getOAIVersion() > 110)
+  {
+    text_t metadataPrefix = params["metadataPrefix"];
+
+    // Check that the metadataPrefix argument exists
+    if (metadataPrefix == "")
+    {
+      this->errorType = "badArgument";
+      return false;
+    }
+
+    // Check that the metadataPrefix is a format we support
+    if (this->formatNotSupported(metadataPrefix))
+    {
+      this->errorType = "cannotDisseminateFormat";
+      return false;
+    }
+  }
+
+  // ----------------------------------------------------------------------------
+  // 4. Check any remaining arguments
+  // ----------------------------------------------------------------------------
+
+  // Check "from" and "until" arguments
+  if (params["from"] != "" || params["until"] != "")
+  {
+    text_t from  = params["from"];
+    text_t until = params["until"];
+
+    // Check the from date is in the correct format: YYYY-MM-DD
+    if (from != "")
+    {
+      // Must be in the form YYYY-MM-DD
+      if (from.size() != 10 || from[4] != '-' || from[7] != '-')
+      {
+	this->errorType = "badArgument";
+	params.erase("from");
+      }
+    }
+    // Check the until date is in the correct format: YYYY-MM-DD
+    if (until != "")
+    {
+      // Must be in the form YYYY-MM-DD
+      if (until.size() != 10 || until[4] != '-' || until[7] != '-')
+      {
+	this->errorType = "badArgument";
+	params.erase("until");
+      }
+    }
+
+    if (this->errorType == "badArgument")
+    {
+      return false;
+    }
+
+    // If both arguments are supplied the from date must be less than or equal to the until date
+    if (from != "" && until != "" && !(from <= until))
+    {
+      this->errorType = "badArgument";
+      return false;
+    }
+  }
+
+  // Check "set" argument
+  if (params["set"] != "")
+  {
+    // Example set specification: "demo:CL2"
+    text_t set = params["set"];
+
+    // Extract the collection name from the set specification
+    text_t collection = "";
+    oaiclassifier::toGSDL(collection, set);
+
+    // Check that the collection is accessible
+    ColInfoResponse_t cinfo;
+    comerror_t err;
+    protocol->get_collectinfo(collection, cinfo, err, cerr);
+    if (err != noError)
+    {
+      this->errorType = "badArgument";
+      return false;
+    }
+
+    // Check the collection is one that is in the list in the oai.cfg file
+    text_tarray &collections = this->configuration->getCollectionsList();
+    bool collection_found = false;
+    for (int c = 0; c < collections.size(); c++)
+    {
+      if (collections[c] == collection)
+      {
+	collection_found = true;
+	break;
+      }
+    }
+
+    // The collection was not found
+    if (!collection_found)
+    {
+      this->errorType = "badArgument";
+      return false;
+    }
+
+    // Check the child set if it was given
+    if (set != "" && !this->check_classifier(protocol, collection, set))
+    {
+      this->errorType = "badArgument";
+      return false;
+    }
+  }
+
+  // If we've reached here everything must be fine
+  this->errorType = "";
+  return true;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+bool listidsaction::output_document(ostream& output, recptproto *protocol, const text_t &collection, 
+				    const text_t &OID, const text_t &metadataPrefix /* ignored */)
+{
+  FilterResponse_t response;
+  ResultDocInfo_t  doc_info;
+  text_tset        metadata;
+  ofstream         logout("oai.log", ios::app);
+  text_t           lastModified;
+  int              oaiVersion = this->configuration->getOAIVersion();
+
+  get_info(OID, collection, "", metadata, false, protocol, response, logout);
+  doc_info = response.docInfo[0];
+  this->getLastModifiedDate(doc_info, lastModified);
+  
+  // output the record for this document
+  text_t oaiLabel = OID;
+  oaiclassifier::toOAI(collection, oaiLabel);
+
+  if(oaiVersion <= 110)
+    output << "  <identifier>" << oaiLabel << "</identifier>\n";
+  else
+    this->output_record_header(output, oaiLabel, lastModified, 
+			       doc_info.metadata["memberof"].values, oaiVersion);
+
+  return true;
+}
Index: /gsdl/stable/runtime-src/src/oaiservr/listidsaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/listidsaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/listidsaction.h	(revision 20131)
@@ -0,0 +1,12 @@
+#include "abstractlistaction.h"
+
+class listidsaction : public abstractlistaction
+{
+ public:
+  listidsaction() : abstractlistaction("ListIdentifiers") { };
+ protected:
+  bool validateAction(recptproto *protocol, oaiargs &params);
+  bool output_document(ostream &output, recptproto *protocol, const text_t &collection, const text_t &OID,
+		       const text_t &metadataPrefix = "");
+};
+
Index: /gsdl/stable/runtime-src/src/oaiservr/listrecsaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/listrecsaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/listrecsaction.cpp	(revision 20131)
@@ -0,0 +1,199 @@
+#include "listrecsaction.h"
+
+#include "oaitools.h"
+#include "recordaction.h"
+
+bool listrecsaction::validateAction(recptproto *protocol, oaiargs &params)
+{ 
+  // ----------------------------------------------------------------------------
+  //  1. Check for invalid arguments
+  // ----------------------------------------------------------------------------
+  bool invalid_argument_supplied = false;
+  text_tmap::const_iterator param_iterator = params.begin();
+  while (param_iterator != params.end())
+  {
+    // Check for arguments that aren't valid for this action
+    if (param_iterator->first != "verb" &&
+	param_iterator->first != "from" &&
+	param_iterator->first != "until" &&
+	param_iterator->first != "set" &&
+	param_iterator->first != "resumptionToken" &&
+	param_iterator->first != "metadataPrefix")
+    {
+      // We've found an invalid argument
+      invalid_argument_supplied = true;
+
+      // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
+      params.erase(param_iterator->first);
+    }
+
+    param_iterator++;
+  }
+
+  // If we found an invalid argument it's an error, so don't go any further 
+  if (invalid_argument_supplied)
+  {
+    this->errorType = "badArgument";
+    return false;
+  }
+
+  // ----------------------------------------------------------------------------
+  //  2. Handle any exclusive arguments
+  // ----------------------------------------------------------------------------
+
+  //  The resumptionToken argument is exclusive
+  if (params["resumptionToken"] != "")
+  {
+    // This argument is exclusive, so no other arguments are allowed (except "verb" of course)
+    if (params.getSize() != 2)
+    {
+      this->errorType = "badArgument";
+      return false;
+    }
+
+    // Check the resumption token is valid
+    ResumptionToken token(params["resumptionToken"]);
+    if (token.isValid())
+    {
+      // Everything is fine, and we don't continue further because this is an exclusive argument
+      this->errorType = "";
+      return true;
+    }
+    else
+    {
+      // There was an error with the resumption token
+      this->errorType = "badResumptionToken";
+      return false;
+    }
+  }
+
+  // ----------------------------------------------------------------------------
+  //  3. Handle any required arguments
+  // ----------------------------------------------------------------------------
+
+  // The metadataPrefix is required
+  text_t metadataPrefix = params["metadataPrefix"];
+
+  // Check that the metadataPrefix argument exists
+  if (metadataPrefix == "")
+  {
+    this->errorType = "badArgument";
+    return false;
+  }
+
+  // Check that the metadataPrefix is a format we support
+  if (this->formatNotSupported(metadataPrefix))
+  {
+    this->errorType = "cannotDisseminateFormat";
+    return false;
+  }
+
+  // ----------------------------------------------------------------------------
+  // 4. Check any remaining arguments
+  // ----------------------------------------------------------------------------
+
+  // Check "from" and "until" arguments
+  if (params["from"] != "" || params["until"] != "")
+  {
+    text_t from  = params["from"];
+    text_t until = params["until"];
+
+    // Check the from date is in the correct format: YYYY-MM-DD
+    if (from != "")
+    {
+      // Must be in the form YYYY-MM-DD
+      if (from.size() != 10 || from[4] != '-' || from[7] != '-')
+      {
+	this->errorType = "badArgument";
+	params.erase("from");
+      }
+    }
+    // Check the until date is in the correct format: YYYY-MM-DD
+    if (until != "")
+    {
+      // Must be in the form YYYY-MM-DD
+      if (until.size() != 10 || until[4] != '-' || until[7] != '-')
+      {
+	this->errorType = "badArgument";
+	params.erase("until");
+      }
+    }
+
+    if (this->errorType == "badArgument")
+    {
+      return false;
+    }
+
+    // If both arguments are supplied the from date must be less than or equal to the until date
+    if (from != "" && until != "" && !(from <= until))
+    {
+      this->errorType = "badArgument";
+      return false;
+    }
+  }
+
+  // Check "set" argument
+  if (params["set"] != "")
+  {
+    // Example set specification: "demo:CL2"
+    text_t set = params["set"];
+
+    // Extract the collection name from the set specification
+    text_t collection = "";
+    oaiclassifier::toGSDL(collection, set);
+
+    // Check that the collection is accessible
+    ColInfoResponse_t cinfo;
+    comerror_t err;
+    protocol->get_collectinfo(collection, cinfo, err, cerr);
+    if (err != noError)
+    {
+      this->errorType = "badArgument";
+      return false;
+    }
+
+    // Check the collection is one that is in the list in the oai.cfg file
+    text_tarray &collections = this->configuration->getCollectionsList();
+    bool collection_found = false;
+    for (int c = 0; c < collections.size(); c++)
+    {
+      if (collections[c] == collection)
+      {
+	collection_found = true;
+	break;
+      }
+    }
+
+    // The collection was not found
+    if (!collection_found)
+    {
+      this->errorType = "badArgument";
+      return false;
+    }
+
+    // Check the child set if it was given
+    if (set != "" && !this->check_classifier(protocol, collection, set))
+    {
+      this->errorType = "badArgument";
+      return false;
+    }
+  }
+
+  // If we've reached here everything must be fine
+  this->errorType = "";
+  return true;
+}
+
+//-----------------------------------------------------------------------------------------------
+
+bool listrecsaction::output_document(ostream &output, recptproto *protocol, const text_t &collection, 
+		     const text_t &OID, const text_t &metadataPrefix)
+{
+  this->record_action->output_record(output, protocol, collection, OID, metadataPrefix);
+  return true;
+}
+  
+//-----------------------------------------------------------------------------------------------
+
+
+
Index: /gsdl/stable/runtime-src/src/oaiservr/listrecsaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/listrecsaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/listrecsaction.h	(revision 20131)
@@ -0,0 +1,16 @@
+#include "abstractlistaction.h"
+
+#include "recordaction.h"
+
+class listrecsaction : public abstractlistaction
+{
+ public:
+  void set_recordMaker(recordaction *ptr) { this->record_action = ptr; }
+  listrecsaction() : abstractlistaction("ListRecords") { };
+  
+ protected:
+  recordaction *record_action;
+  virtual bool validateAction(recptproto *protocol, oaiargs &params);
+  bool output_document(ostream &output, recptproto *protocol, const text_t &collection, 
+		     const text_t &OID, const text_t &metadataPrefix);
+};
Index: /gsdl/stable/runtime-src/src/oaiservr/listsetsaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/listsetsaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/listsetsaction.cpp	(revision 20131)
@@ -0,0 +1,271 @@
+#include "listsetsaction.h"
+
+#if defined(GSDL_USE_STL_H)
+#include <fstream.h>
+#else
+#include <fstream>
+#endif
+
+#include "recptprototools.h"
+#include "oaitools.h"
+
+bool listsetsaction::validateAction(recptproto *protocol, oaiargs &params)
+{
+  // ----------------------------------------------------------------------------
+  //  1. Check for invalid arguments
+  // ----------------------------------------------------------------------------
+  bool invalid_argument_supplied = false;
+  text_tmap::const_iterator param_iterator = params.begin();
+  while (param_iterator != params.end())
+  {
+    // Check for arguments that aren't valid for this action
+    if (param_iterator->first != "verb" &&
+	param_iterator->first != "resumptionToken")
+    {
+      // We've found an invalid argument
+      invalid_argument_supplied = true;
+
+      // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
+      params.erase(param_iterator->first);
+    }
+
+    param_iterator++;
+  }
+
+  // If we found an invalid argument it's an error, so don't go any further 
+  if (invalid_argument_supplied)
+  {
+    this->errorType = "badArgument";
+    return false;
+  }
+
+  // ----------------------------------------------------------------------------
+  //  2. Handle any exclusive arguments
+  // ----------------------------------------------------------------------------
+
+  //  The resumptionToken argument is exclusive
+  if (params["resumptionToken"] != "")
+  {
+    // This argument is exclusive, so no other arguments are allowed (except "verb" of course)
+    if (params.getSize() != 2)
+    {
+      this->errorType = "badArgument";
+      return false;
+    }
+
+    // Check the resumption token is valid
+    ResumptionToken token(params["resumptionToken"]);
+    if (true)  // TO DO: Fix this (the token.isValid() function is useless for ListSets)
+    {
+      // Everything is fine, and we don't continue further because this is an exclusive argument
+      this->errorType = "";
+      return true;
+    }
+    else
+    {
+      // There was an error with the resumption token
+      this->errorType = "badResumptionToken";
+      return false;
+    }
+  }
+
+  // ----------------------------------------------------------------------------
+  //  3. Handle any required arguments
+  // ----------------------------------------------------------------------------
+
+  // None!
+
+  // ----------------------------------------------------------------------------
+  // 4. Check any remaining arguments
+  // ----------------------------------------------------------------------------
+
+  // None!
+
+  // If we've reached here everything must be fine
+  this->errorType = "";
+  return true;
+}
+
+bool listsetsaction::output_content(ostream &output, recptproto *protocol, text_tset &collections, oaiargs &params)
+{
+  text_tset::iterator here = collections.begin();
+  text_tset::iterator end  = collections.end();
+  while (here != end) {
+    text_t collect = *here;
+    this->output_content(output, protocol, params);
+    ++here;
+  }
+  return true;
+}
+
+bool listsetsaction::output_content(ostream &output, recptproto *protocol, oaiargs &params)
+{
+  // output the total list of classifier points
+
+  // variables required
+  text_t browseOID = "browse";
+  FilterResponse_t response;
+  comerror_t       err;
+  text_tarray &    collections = this->configuration->getCollectionsList();
+  text_tset        metadata;
+  ofstream         logout("oai.log", ios::app);
+  
+  // get a list of the collections available
+  //  protocol->get_collection_list(collections, err, output); 
+  if (collections.size() == 0) {
+    logout << "Found *no* OAI collections - check main.cfg for oaicollection items and read the OAI documentation.\n";
+  }
+
+  // check resumption token
+  int startSet = 0;
+  if (params["resumptionToken"] != "") {
+    ResumptionToken token(params["resumptionToken"]);
+    startSet = token.getPosition() - 1; // first document is said to be 1..
+  }
+  this->replyToken = NULL;
+
+  this->setNumber = 0;
+  this->setsOutput = 0;
+  for(int current_col = 0; current_col < collections.size(); ++current_col) {
+    // output the collection as a set, first, then its children
+    text_t gsdlCollect = collections[current_col];
+
+    if (this->setsOutput == this->configuration->resumeAfter())
+    {
+      this->replyToken = new ResumptionToken("", "", "");
+      this->replyToken->setPosition("", this->setNumber+1);
+      break;
+    }
+
+    if (this->setNumber >= startSet)
+    {
+      output << "  <set>" << endl;
+      output << "    <setSpec>" << gsdlCollect << "</setSpec>" << endl;;
+      output << "    <setName>" << gsdlCollect << "</setName>" << endl;
+      output << "  </set>" << endl;
+      this->setsOutput++;
+    }
+    setNumber++;
+
+    // get all the children of the (relevant) classifier data structures
+    get_children(browseOID, gsdlCollect, "", metadata, false, protocol, response, logout);
+    // and send them to the "recurse_content" list
+    for (int c = 0; c < response.numDocs; ++c) {
+      this->recurse_content(output, protocol, gsdlCollect, response.docInfo[c].OID, gsdlCollect, startSet);
+    }
+  }
+
+  // do a resumption token if required; errors cancel a token...
+  if (this->replyToken != NULL && this->errorType == "") {
+    // Don't add any whitespace around the resumption token as it can confuse harvesters/validators
+    output << "  <resumptionToken>" << this->replyToken->getToken() << "</resumptionToken>" << endl;
+  }
+
+  return true;
+}
+
+void listsetsaction::recurse_content(ostream &output, recptproto *protocol, text_t &collection, 
+				     const text_t &classifier, text_t setHierarchy, int startSet)
+{
+  // metadata for this call
+  FilterResponse_t response;
+  text_tset        metadata;
+  ofstream         logout("oai.log", ios::app);
+
+  if (this->setsOutput == this->configuration->resumeAfter())
+  {
+    this->replyToken = new ResumptionToken("", "", "");
+    this->replyToken->setPosition("", this->setNumber+1);
+    return;
+  }
+
+  metadata.insert("contains");
+  metadata.insert("Title");
+  metadata.insert("supportsmemberof");
+
+  // get the document information
+  if (!get_info(classifier, collection, "", metadata, false, protocol, response, logout)) {
+    //cerr << "recurse content: Bad identifier or protocol " << classifier << endl;
+    return;
+  }
+
+  // check for top-level classifiers, check if the set name includes a '.'; if 
+  // not, it is a top-level classifier: check for memberof support.  Those without
+  // memberof support will not be supported on OAI
+  if (findchar(classifier.begin(), classifier.end(), '.') == classifier.end()) {
+    if (response.docInfo[0].metadata["supportsmemberof"].values.size() > 0) {
+      text_t memberOf = response.docInfo[0].metadata["supportsmemberof"].values[0];
+      if (memberOf != "true") {
+	return;
+      }
+    }
+    else {
+      return;
+    }
+  }
+
+  MetadataInfo_tmap::iterator here = response.docInfo[0].metadata.begin();
+  MetadataInfo_tmap::iterator end  = response.docInfo[0].metadata.end();
+  text_t title;
+
+  while (here != end)
+  {
+    // Each set should only have one title - hence we only output one title here
+    // (it is a set title, not a collection)
+    if (here->first == "Title" && here->second.values.size() > 0) {	
+      title = here->second.values[0];
+    }
+
+    ++here;
+  }
+
+  // output the xml for this set; use the classifier id for the name
+  // if the title is blank
+  // curSet holds the colon-separated sequence of parent sets of the current set
+  text_t curSet;
+  if (this->setNumber >= startSet)
+  {
+    output << "  <set>" << endl;
+    text_t oai_classifier = classifier;
+    oaiclassifier::toOAI(collection, oai_classifier);
+    output << "    <setSpec>" << oai_classifier << "</setSpec>" << endl;
+    output << "    <setName>";
+    if (!title.empty()) {
+      curSet = setHierarchy + ":" + title;
+    }
+    else {
+      curSet = classifier; // Pretty much never gets here (shouldn't, at least)
+    }
+    output << curSet;
+    output << "</setName>" << endl;
+    output << "  </set>" << endl;
+    this->setsOutput++;
+  }
+  this->setNumber++;
+
+  // get the children of this classifier and iterate them
+  get_children(classifier, collection, "", metadata, false, protocol, response, logout);
+  for (int c = 0; c < response.numDocs; ++c) {
+    text_t child = response.docInfo[c].OID;
+
+    if (child == classifier)
+      continue;
+
+    // check for non classifier items and exclude them
+    text_t childHead;
+    text_t::const_iterator start = child.begin();
+    text_t::const_iterator here  = child.begin();
+    here += 2;
+    childHead = substr(start, here);
+
+    if (childHead != "CL")
+      continue;
+
+    // Recurse for "proper" classifier children. Pass curSet, the colon-separated list of 
+    // parent sets. curSet is pass-by-value, so that as we step out of recursion we remember
+    // old set hierarchies.
+    this->recurse_content(output, protocol, collection, child, curSet, startSet);
+  }
+  
+  return;
+}
Index: /gsdl/stable/runtime-src/src/oaiservr/listsetsaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/listsetsaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/listsetsaction.h	(revision 20131)
@@ -0,0 +1,17 @@
+#include "oaiaction.h"
+#include "resumptiontoken.h"
+
+class listsetsaction : public oaiaction
+{
+ public:
+  listsetsaction() : oaiaction("ListSets") { };
+  virtual bool validateAction(recptproto *protocol, oaiargs &params);
+  bool output_content(ostream &output, recptproto *protocol, text_tset &collections, oaiargs &params);
+ protected:
+  int  setNumber;
+  int  setsOutput;
+  ResumptionToken *replyToken;
+  bool output_content(ostream &output, recptproto *protocol, oaiargs &params);
+  void recurse_content(ostream &output, recptproto *protocol, text_t &collection, const text_t &classifier, 
+		       text_t setHierarchy, int startSet);
+};
Index: /gsdl/stable/runtime-src/src/oaiservr/metaformat.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/metaformat.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/metaformat.cpp	(revision 20131)
@@ -0,0 +1,191 @@
+#include <fstream>
+#include "metaformat.h"
+#include "gsdltools.h"
+#include "gsdlunicode.h"
+#include "recptprototools.h"
+
+
+metaformat::metaformat()
+{
+}
+
+text_t metaformat::get_mapping(const text_t &collection, const text_t &collectionField)
+{
+  if (this->oaiConfigure == NULL) {
+    return "";
+  }
+
+  return this->oaiConfigure->getMapping(collection, collectionField, this->formatName());
+}
+
+void metaformat::output_item(ostream &output, outconvertclass &outconvert, 
+			     bool &headerDone, const text_t &label, 
+			     const text_tarray &values)
+{ 
+
+  if (!headerDone && (values.size() > 0)) {
+    this->output_metadata_header(output);
+    headerDone = true;
+  }
+
+  for (int item = 0; item < values.size(); ++item) {
+    if (this->oaiConfigure->getOAIVersion() >= 200) { // TODO: GRB: This code may need to be subclassed by dc for 200 and later...
+      output << outconvert << "        <" << this->formatPrefix() << ":" << label << ">" << xml_safe(values[item]) << "</" << this->formatPrefix() << ":" << label << ">\n";
+    }
+    else {
+      output << outconvert << "        <" << label << ">" << xml_safe(values[item]) << "</" << label << ">\n";
+    }
+  }
+}
+
+bool metaformat::scan_metadata(ostream &output, const text_t &collection, ResultDocInfo_t &docInfo,
+			       bool doOutput) 
+{ 
+  bool headerDone = false;
+  MetadataInfo_tmap::iterator here = docInfo.metadata.begin();
+  MetadataInfo_tmap::iterator end = docInfo.metadata.end();
+
+  utf8outconvertclass utf8convert; // we want to output metadata in utf8
+
+  // metaItem is used initially to identify the rfc1807 (etc) metadata items. It is 
+  // then used to hold the name of the metadata item, such as "title" or "subject".
+  text_t metaItem;
+  text_t::const_iterator start, last; // Use two iterators to go through metaItem
+
+  while (here != end) {
+    start = last = here->first.begin();
+
+    if (here->first.size() < this->formatPrefix().size() ||
+	here->first[this->formatPrefix().size()] != '.') {
+      metaItem == "";
+    }
+    else {
+      last += this->formatPrefix().size(); // Move last so that it is at the
+      // '.' 
+      metaItem = substr(start, last);          // Gets the substring starting at start and going up to (but
+                                               // not including) last. This should be "dc" (for example)
+    }
+
+    if (metaItem == this->formatPrefix()) {
+      metaItem = substr(last+1, here->first.end()); // Get the rest of the metadata tag (it's name) but without the '.'
+      // remove xxx^ eg Coverage^Spatial becomes spatial
+      // this is for qualified dublin core. May affect other sets later if they
+      // validly have ^ in them.
+      text_t::iterator hat = findchar(metaItem.begin(), metaItem.end(), '^');
+      if (hat != metaItem.end()) {
+	metaItem = substr(hat+1, metaItem.end());
+      }
+      lc(metaItem.begin(),metaItem.begin()+1); // We want lowercase, but some of the fields in qualified dublin core have internal upper case, eg instructionalMethod. So we assume that lowercasing the first letter is enough
+      if (doOutput) {
+	if (this->is_valid_element(metaItem)) {
+	  
+	  this->output_item(output, utf8convert, headerDone, metaItem, here->second.values);
+	}
+      }
+      else {
+	if (here->second.values.size() > 0) {
+	  return true;
+	}
+      }
+    }  
+    else {
+      text_t mapTo = this->get_mapping(collection, here->first);
+      if (mapTo != "") {
+	// Do we actually want to do anything here? Doesn't getting here imply that this 
+	// particular metadata is stuff we don't want?
+	if (doOutput) {
+	  if (this->is_valid_element(mapTo)) {
+	    this->output_item(output, utf8convert, headerDone, mapTo, here->second.values);
+	  }
+	}
+	else {
+	  if (here->second.values.size() > 0) {
+	    return true;
+	  }
+	}
+      }
+    }
+
+    ++here;
+  }
+
+  if (!doOutput) {
+    return false;
+  }
+  
+  if (headerDone) {
+    this->output_metadata_footer(output);
+  }
+  
+  return headerDone;
+}
+
+
+bool metaformat::is_available(const text_t &collection, ResultDocInfo_t &docInfo)
+{ 
+  ofstream o("dummy", ios::out);
+  return this->scan_metadata(o, collection, docInfo, false);
+}
+
+bool metaformat::is_valid_element(text_t &meta_name)
+{
+  if (elementSet.count(meta_name)==1) return true;
+  return false;
+  
+}
+
+bool metaformat::output_metadata(ostream &output, const text_t &collection, ResultDocInfo_t &docInfo) 
+{ 
+  return this->scan_metadata(output, collection, docInfo, true);
+}
+
+bool metaformat::output_record(ostream &output, recptproto *protocol, const text_t &collection, 
+			       const text_t &OID) 
+{
+  FilterResponse_t response;
+  text_tset        metadata;
+  ofstream         logout("oai.log", ios::app);
+
+  // get the document information
+  if (!get_info(OID, collection, "", metadata, false, protocol, response, logout)) {
+    // TODO: error, bad request
+    //   cerr << "Bad identifier or protocol " << OID << endl;
+    return false;
+  }
+
+  // check to see if it's a classifier
+  text_t childHead;
+  //  int oaiVersion = this->oaiConfigure->getOAIVersion();
+  text_t::const_iterator start = OID.begin();
+  text_t::const_iterator here  = OID.begin();
+  here += 2;
+  childHead = substr(start, here);
+
+  // if it isn't a document, kill it now
+  if (childHead == "CL") {
+    //    cerr << "Not a document" << endl;
+    return false;
+  }
+
+  // output record header
+  output << "<record>\n";
+
+  // output header part of oai response
+  output << "<header>" << endl;
+  output << "  <identifier>" << OID << "</identifier>" << endl;
+  // TODO: add modified date
+
+  output << "</header>" << endl;
+
+  // output metadata part of oai response
+  this->output_metadata(output, collection, response.docInfo[0]);
+
+  // output the description of the document
+  //  output << "<about>\n";
+  //  output << "</about>\n";
+
+  // close record
+  output << "</record>\n";
+    
+  return true;
+}
Index: /gsdl/stable/runtime-src/src/oaiservr/metaformat.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/metaformat.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/metaformat.h	(revision 20131)
@@ -0,0 +1,64 @@
+/**
+ *  A framework class for metadata formats.
+ *
+ *  Example child classes include oaimeta and rfc8507meta
+ */
+
+#ifndef _METAFORMAT_H_
+#define _METAFORMAT_H_
+#include <stdio.h>
+
+#include "text_t.h"
+#include "comtypes.h"
+#include "recptproto.h"
+
+#include "oaiconfig.h"
+
+class metaformat
+{  
+ protected:
+  virtual void output_metadata_header(ostream &output) = 0;
+  virtual void output_item(ostream &output, outconvertclass &outconvert, 
+			   bool &headerDone, const text_t &label, 
+			   const text_tarray &values);
+  virtual void output_metadata_footer(ostream &output) = 0;
+  virtual bool is_valid_element(text_t &meta_name);
+  virtual bool scan_metadata(ostream &output, const text_t &collection,  
+			     ResultDocInfo_t &docInfo, bool doOutput);
+  oaiconfig *    oaiConfigure;
+
+  // a set containing all the valid element names for the set. Must be 
+  // initialized by each metadata class
+  text_tset elementSet; 
+
+ public:
+  metaformat(); // Must be given the desired oai version when created 
+  virtual const text_t formatName() = 0;
+  virtual const text_t formatPrefix() = 0;
+  virtual bool output_record(ostream &output, recptproto *protocol, 
+			     const text_t &collection, 
+			     const text_t &record_OID);
+  virtual bool is_available(const text_t &collection, ResultDocInfo_t &docInfo);
+  virtual bool output_metadata(ostream &output, const text_t &collection,  
+			       ResultDocInfo_t &docInfo);
+  virtual bool output_formatdata(ostream &output) = 0;
+  void    set_configuration(oaiconfig *config) { this->oaiConfigure = config; }
+  text_t  get_mapping(const text_t &collection, const text_t &collectionField);
+  virtual ~metaformat() { this->oaiConfigure = NULL; }
+};
+
+class metaformatptr
+{
+ public:
+  metaformat *ptr;
+
+  metaformatptr() { this->ptr = NULL; }
+  metaformat *get_class() { return this->ptr; }
+  void set_class(metaformat *ptr) { this->ptr = ptr; }
+  void set_configuration(oaiconfig *config) { this->ptr->set_configuration(config);}
+  void clear() { delete this->ptr; this->ptr = NULL; }
+};
+
+typedef	map<text_t, metaformatptr, lttext_t> metaformat_map;
+
+#endif
Index: /gsdl/stable/runtime-src/src/oaiservr/metaformatsaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/metaformatsaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/metaformatsaction.cpp	(revision 20131)
@@ -0,0 +1,138 @@
+#include "metaformatsaction.h"
+#include "metaformat.h"
+#include "recptprototools.h"
+#include "oaitools.h"
+
+bool metaformatsaction::validateAction(recptproto *protocol, oaiargs &params)
+{ 
+  // ----------------------------------------------------------------------------
+  //  1. Check for invalid arguments
+  // ----------------------------------------------------------------------------
+  bool invalid_argument_supplied = false;
+  text_tmap::const_iterator param_iterator = params.begin();
+  while (param_iterator != params.end())
+  {
+    // Check for arguments that aren't valid for this action
+    if (param_iterator->first != "verb" &&
+	param_iterator->first != "identifier")
+    {
+      // We've found an invalid argument
+      invalid_argument_supplied = true;
+
+      // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
+      params.erase(param_iterator->first);
+    }
+
+    param_iterator++;
+  }
+
+  // If we found an invalid argument it's an error, so don't go any further 
+  if (invalid_argument_supplied)
+  {
+    this->errorType = "badArgument";
+    return false;
+  }
+
+  // ----------------------------------------------------------------------------
+  //  2. Handle any exclusive arguments
+  // ----------------------------------------------------------------------------
+
+  // None!
+
+  // ----------------------------------------------------------------------------
+  //  3. Handle any required arguments
+  // ----------------------------------------------------------------------------
+
+  // None!
+
+  // ----------------------------------------------------------------------------
+  // 4. Check any remaining arguments
+  // ----------------------------------------------------------------------------
+
+  // Check "identifier" argument
+  if (params["identifier"] != "")
+  {
+    text_t identifier = params["identifier"];
+
+    // Extract the collection name from the identifier specification
+    text_t collection = "";
+    oaiclassifier::toGSDL(collection, identifier);
+  
+    // Check a document with the specified identifier exists
+    text_tset metadata;
+    if (!get_info(identifier, collection, "", metadata, false, protocol, this->gsdlResponse, *logout))
+    {
+      this->errorType = "idDoesNotExist";
+
+      // Only throw an error if we're using v2.0. 
+      // v1.1 should simply return a response without a metadataFormat container. 1.1
+      // should still set the errorType so we know that the error was encountered
+      // the information retrieved here is retained for the output_content function below
+      if (this->configuration->getOAIVersion() >= 200)
+      {
+	return false;
+      }
+    }
+  }
+
+  // If we've reached here everything must be fine
+  this->errorType = "";
+  return true;
+}
+
+bool metaformatsaction::output_content(ostream &output, recptproto *protocol, oaiargs &params)
+{
+  // if an identifier parameter is being used, then respond to it - currently we reject anything other
+  // than dublin core (unqualified)
+  //
+  // TODO: only return the selected identifier (if given) and don't validate the entry; just
+  //       return nothing if an invalid or unknown metadata format is given
+  
+  // give the required xml response
+
+  text_t gsdlId = params["identifier"];
+  text_t gsdlCollect;
+
+  // convert record identifier into GSDL format from OAI
+  if (gsdlId != "") {
+    oaiclassifier::toGSDL(gsdlCollect, gsdlId);
+  }
+  
+  metaformat_map::iterator here = this->formats->begin();
+  metaformat_map::iterator end  = this->formats->end();
+
+  // v1.1 should check that the id - if supplied - didn't cause an error. If it did,
+  // don't output the metadataFormat tags. OAI v2.0 should already have bailed.
+  if(this->errorType != "idDoesNotExist"){
+    while (here != end) { // Loop through the repository's supported metadata formats
+      bool doOutput = true;
+      
+      // if we were given an identifier, then check if it supports the metadata format in question
+      if (gsdlId != "") {
+	doOutput = here->second.get_class()->is_available(gsdlCollect, this->gsdlResponse.docInfo[0]);
+      }
+
+      if (doOutput) {
+	output << "  <metadataFormat>" << endl;
+	here->second.get_class()->output_formatdata(output);
+	output << "  </metadataFormat>\n";
+      }
+      ++here;
+    }
+  }
+
+  return true;
+}
+
+void metaformatsaction::setConfiguration(oaiconfig *configuration)
+{
+  this->configuration = configuration;
+
+  metaformat_map::iterator here = this->formats->begin();
+  metaformat_map::iterator end  = this->formats->end();
+  while (here != end) {    
+    here->second.set_configuration((oaiconfig *) configuration);
+    ++here;
+  }
+}
+
Index: /gsdl/stable/runtime-src/src/oaiservr/metaformatsaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/metaformatsaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/metaformatsaction.h	(revision 20131)
@@ -0,0 +1,15 @@
+#include "oaiaction.h"
+#include "metaformat.h"
+
+class metaformatsaction : public oaiaction
+{
+ public:
+  metaformatsaction() : oaiaction("ListMetadataFormats") { };
+  void set_formats(metaformat_map *formats) { this->formats = formats; }
+  virtual void setConfiguration(oaiconfig *configuration);
+  virtual bool validateAction(recptproto *protocol, oaiargs &params);
+ protected:
+  metaformat_map * formats;
+  FilterResponse_t gsdlResponse;
+  bool output_content(ostream &output, recptproto *protocol, oaiargs &params);
+};
Index: /gsdl/stable/runtime-src/src/oaiservr/oaiaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/oaiaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/oaiaction.cpp	(revision 20131)
@@ -0,0 +1,467 @@
+#include "oaiaction.h"
+#include "oaitools.h"
+#include "recptprototools.h"
+
+#include <string>
+#if defined(GSDL_USE_IOS_H)
+#  if defined(__WIN32__)
+#    include <strstrea.h> // vc4
+#  else
+#    include <strstream.h>
+#  endif
+#else
+#  include <sstream>
+#endif
+
+#include <time.h>
+
+oaiaction::oaiaction(const text_t &name)
+{
+  this->logout = new ofstream("oai.log", ios::app);
+  this->configuration = NULL;
+  this->name = name;
+}
+
+//----------------------------------------------------------------------------------------------
+
+// Over-ridden by child classes
+bool oaiaction::validateAction(recptproto *protocol, oaiargs &params)
+{ 
+  this->errorType = ""; 
+  return true;
+}
+
+//----------------------------------------------------------------------------------------------
+
+/**********
+ * Compare the supplied metadataPrefix to all those that
+ * are supported. If there is NO match, return true. If 
+ * it DOES match one, return false.
+ */
+bool oaiaction::formatNotSupported(text_t &metaFormat)
+{
+  // is it in our list?
+  if (this->configuration->getMetadataSet().count(metaFormat) == 0) return true;
+  return false;
+}
+
+//----------------------------------------------------------------------------------------------
+
+/**********
+ * Function for outputting the appropriate error(s) with the (version 2.0) request.
+ * The error(s) MUST be included in the response, and take the form:
+ * <error code="errorType">Description of error</error>
+ */
+void oaiaction::output_error(ostream &output, text_t &errorType)
+{
+  text_t description = "";
+
+  if(errorType == "badArgument"){
+    description = "The request includes illegal arguments, is missing required arguments, repeats arguments or the value for an argument has an illegal syntax";
+  }
+  else if(errorType == "noRecordsMatch"){
+    description = "No record matches all the requested parameters";
+  }
+  else if(errorType == "cannotDisseminateFormat"){
+    description = "The metadata format specified is not supported by the item or by the repository";
+  }
+  else if(errorType == "idDoesNotExist"){
+    description = "The value of the identifier is unknown or illegal in this repository";
+  }
+  else if(errorType == "badVerb"){
+    description = "Value of the verb argument is illegal, missing, or repeated";
+  }
+  else if(errorType == "noMetadataFormats"){
+    description = "There are no metadata formats available for the item";
+  }
+  else if(errorType == "badResumptionToken"){
+    description = "The value of the resumptionToken argument is invalid or expired";
+  }
+  else if(errorType == "noSetHierarchy"){
+    description = "The repository does not support sets";
+  }
+
+  output << "  <error code=\"" << errorType << "\">" << description << "</error>\n";
+}
+
+//----------------------------------------------------------------------------------------------
+
+text_t oaiaction::getName()
+{
+  return this->name;
+}
+
+//----------------------------------------------------------------------------------------------
+
+/**********
+ * Used in version 2.0 to provide the <datestamp> tag for each document. The function is passed
+ * the 'last modified' date of the file in epoch time (time in seconds since 1970-01-01 on Unix 
+ * systems) and converts it to YYYY-MM-DD format. 
+ */
+text_t oaiaction::parseDatestamp(time_t &rawtime)
+{
+  text_t year, month, day, lastModified;
+  tm *ptm;
+  ptm = gmtime(&rawtime);
+  int raw_month = ptm->tm_mon + 1;
+  int raw_day = ptm->tm_mday;
+
+  year = (ptm->tm_year + 1900); // Takes off 1900 for year by default, so replace it to get YYYY format
+
+  // Need the month in MM format, so if month is 1..9, add a 0 to the front
+  if(raw_month < 10){    
+    month = "0";
+    month += raw_month;
+  }
+  else month = raw_month;
+
+  if(raw_day < 10){    
+    day  = "0";
+    day += raw_day;
+  }
+  else day = raw_day;
+  
+  lastModified = year + "-" + month + "-" + day;
+
+  return lastModified;
+}
+
+//----------------------------------------------------------------------------------------------
+/**********
+ * Used by both versions to get the date & time of the client's request. The <responseDate> tag is
+ * in the format YYYY-MM-DDTHH:MM:SSZ, where T is simply the letter 'T' and Z is the local offset from
+ * GMT (now UTC). Examples of Z are +12:00 (NZ) or -03:00 for version 1.1. In version 2.0, the time
+ * is expected to be in UTC, and Z should simply be the character 'Z'.
+ */
+void oaiaction::getResponseDate(text_t &date)
+{
+  time_t rawtime;
+  tm    *ptm;
+
+  time(&rawtime);         // Get the epoch time
+
+  ptm = gmtime(&rawtime); // Convert to UTC-time formatted tm object
+
+  text_t month, day, hour, minute, second;
+  int    raw_month  = ptm->tm_mon + 1;  // Note Jan = 0 ... Dec = 11, so add 1
+  int    raw_day    = ptm->tm_mday;
+  int    raw_hour   = ptm->tm_hour;
+  int    raw_minute = ptm->tm_min;
+  int    raw_second = ptm->tm_sec;
+
+  // Need the month in MM format, so if month is 1..9, add a 0 to the front
+  if(raw_month < 10){    
+    month = "0";
+  }
+  month += raw_month;
+  
+  // Same for days, hours, minutes and seconds
+  if(raw_day < 10){    
+    day = "0";
+  }
+  day += raw_day;
+
+  if(raw_hour < 10){    
+    hour = "0";
+  }
+  hour += raw_hour;
+
+  if(raw_minute < 10){    
+    minute = "0";
+  }
+  minute += raw_minute;
+  
+  if(raw_second < 10){    
+    second = "0";
+  }
+  second += raw_second;
+ 
+  // Want YYYY-MM-DDTHH:MM:SS+UTC, where UTC is num hours from UTC(GMT) to localtime
+  date += (ptm->tm_year + 1900); // Takes off 1900 for year, so replace it to get YYYY format
+  date += "-";
+  date += month;
+  date += "-";
+  date += day;
+  date += "T";
+  date += hour;
+  date += ":";
+  date += minute;
+  date += ":";
+  date += second;
+  // If we're using v1.1, then tack on local time offset, otherwise don't
+  if(this->configuration->getOAIVersion() == 110){
+    date += _LOCALTIME_; // Defined in oaiaction.h. States how many hours localtime is from 
+                         // UTC (GMT), e.g. "+8:00", "-5:00"
+  }
+  else
+    date += "Z";         // If v2.0, we put 'Z' on the end rather than the localtime offset
+}
+
+//----------------------------------------------------------------------------------------------
+/**********
+ * Does different request tags depending on the version of the OAI protocol running
+ */
+void oaiaction::getRequestURL(oaiargs &params, text_t &requestURL)
+{
+  // Iterators for moving through the list of parameters (keys) specified
+  text_tmap::const_iterator here;
+  text_tmap::const_iterator end;
+  int numArgs = params.getSize();
+
+  here = params.begin();
+  end  = params.end();
+  
+  text_t baseURL = this->configuration->getCollectionConfig("", "baseURL");
+
+  int version = this->configuration->getOAIVersion();
+  
+  switch(version){
+  case 110:
+    /* Takes the form:
+     * <requestURL>http://baseURL.com/oaimain?verb="someVerb"&amp;key=value</requestURL>
+     */
+    requestURL = "  <requestURL>" + baseURL;
+    
+    if(numArgs == 0) break; // If no args, all done - the error will be picked up later 
+    
+    // The following lines will give us the "label=value" syntax
+    requestURL += "?";
+    requestURL += here->first;
+    requestURL += "=";
+    requestURL += html_safe(here->second); // parse the argument to ensure it is URL-encoding compliant
+    ++here;
+    
+    while(here != end){
+      requestURL +="&amp;"; // Stick in the ampersand in URL encoding
+      requestURL += (here->first + "=" + html_safe(here->second));
+      ++here;
+    }
+    requestURL += "</requestURL>\n";
+    break;
+  
+  case 200:
+  default:
+    /* Takes the form:
+     * <request verb="someVerb" key="value" key="value">
+     *          http://baseURL.com/oaimain</request>
+     */
+    if(numArgs == 0) {
+      requestURL = "  <request>" + baseURL + "</request>\n";
+      break;
+    }
+    requestURL = "  <request " + here->first + "=\"" + html_safe(here->second) + "\"";
+    ++here;
+    while(here != end){
+      requestURL += (" " + here->first + "=\"" + html_safe(here->second) + "\"");      
+      ++here;
+    }
+    requestURL += ">\n           " + baseURL + "</request>\n";
+    break;
+  }
+}
+
+//----------------------------------------------------------------------------------------------
+/**********
+ * Send the (OAI version-dependent) response text to the output stream
+ */
+void oaiaction::getResponse(ostream &output, recptproto *protocol, oaiargs &params)
+{
+  bool   error;
+  text_t date, requestURL;
+
+  // Write the response date & time into 'date'
+  this->getResponseDate(date);
+  int version = this->configuration->getOAIVersion();
+
+  // validate the action
+  error = !this->validateAction(protocol, params);
+
+  // raise an error for duplicated arguments and set the
+  // error type "manually" here...
+  if (params.hasDuplicateArg() && !error) {
+    this->errorType = "badArgument";
+    error = true;
+  }
+
+  // start with the required http header
+  if (version <= 110 && error){
+    output << "Status: 400 " << this->errorType << "\n";
+    output << "Content-Type: text/xml\n\n";
+    return;
+  }
+  
+  output << "Status: 200\n";
+  output << "Content-Type: text/xml\n\n";
+  
+  // output xml header parts
+  output << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+
+  if(version <= 110){
+    // output OAI v1.1 action header tag
+    output << "<" << this->name;
+    output << "\n       xmlns=\"http://www.openarchives.org/OAI/1.1/OAI_" << this->name << "\" ";
+    output << "\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
+    output << "\n       xsi:schemaLocation=\"http://www.openarchives.org/OAI/1.1/OAI_" << this->name;
+    output << "\n           http://www.openarchives.org/OAI/1.1/OAI_" << this->name << ".xsd\">\n";
+  }
+  else { 
+    text_t baseDocRoot = this->configuration->getCollectionConfig("", "baseDocRoot");
+    output << "<?xml-stylesheet type=\"text/xsl\" href=\""<<baseDocRoot<<"/web/style/oai2.xsl\" ?>\n";
+    // output OAI v2.0 action header tag
+    output << "<OAI-PMH xmlns=\"http://www.openarchives.org/OAI/2.0/\"\n"
+	   << "         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+	   << "         xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/\n"
+	   << "             http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd\">\n";
+  }
+  // output current time for response
+  output << "  <responseDate>" << date << "</responseDate>\n";
+ 
+  // output request URL. This differs depending on the OAI protocol version currently running, so
+  // the entire field - including tags - must be put into the text_t variable by getRequestURL()
+  this->getRequestURL(params, requestURL);
+
+  output << requestURL ;
+
+  if (error == false) {
+    // a string stream to write the content of the action to; this is done so that we can
+    // avoid outputting the action tag if the action's body is unsuccessful, in which
+    // case the leading tag must be suppressed
+#if defined(GSDL_USE_IOS_H)
+    ostrstream outstream;
+#else
+    ostringstream outstream;
+#endif
+
+    // Version 2.0 needs an <Identify>, etc. tag after the OAI-PMH header, IF there is no error
+    //
+    // An action that outputs no content should raise an error state to suppress the 
+    // matching opening and close tags if it outputs no content in OAI 2.0
+    error = !this->output_content(outstream, protocol, params);
+
+    // output the leading tag if no error occurred
+    if (error == false) {
+      if (version >= 200) {
+	this->output_action_tag(output, true);
+      }
+    }
+
+    // now output the body of the action content
+#if defined(GSDL_USE_IOS_H)
+    outstream << ends;  // Ensure outstream is null-terminated correctly
+#endif
+    output << outstream.str();
+  }
+  else {
+    if (version >= 200) {
+      this->output_error(output, this->errorType);
+    }
+  }
+
+  // close out our response - both versions need this line, but v2.0 only needs it if there was no error
+  if((version == 110) || (version >= 200 && error == false)){
+    this->output_action_tag(output, false);
+  }
+  if(version >= 200){
+    output << "</OAI-PMH>\n";
+  }
+}
+
+void oaiaction::output_action_tag(ostream &output, bool openTag)
+{
+  output << " <";
+  if (!openTag) {
+    output << "/";
+  }
+  output << this->name << ">" << endl;
+}
+
+void oaiaction::output_record_header(ostream &output, const text_t &oaiLabel, const text_t &lastModified, 
+				     const text_tarray &memberOf, int oaiVersion)
+{
+    output << "    <header>" << endl;
+    output << "      <identifier>" << oaiLabel     << "</identifier>" << endl;
+    output << "      <datestamp>"  << lastModified << "</datestamp>" << endl;
+    
+    // copy the collection name off the front of oaiLabel
+    text_t::const_iterator colon = findchar(oaiLabel.begin(), oaiLabel.end(), ':');
+    text_t collection = substr(oaiLabel.begin(), colon);
+    
+    if(oaiVersion >= 200){
+      text_tarray::const_iterator member = memberOf.begin();
+      text_tarray::const_iterator memEnd = memberOf.end();
+
+      // As well as all the subsets that a doc appears in, it is also a member of the 'collection' set
+      output << "      <setSpec>" << collection << "</setSpec>" << endl;
+      while (member != memEnd) {
+	text_t oaiSet = *member;
+	oaiclassifier::toOAI(collection, oaiSet);
+	output << "      <setSpec>" << oaiSet << "</setSpec>" << endl;
+	++member;
+      }
+    }
+    output << "    </header>" << endl;
+}
+
+void oaiaction::getLastModifiedDate(ResultDocInfo_t &doc_info, text_t &lastModified)
+{
+  text_t temp;
+
+  
+  MetadataInfo_tmap::iterator current = doc_info.metadata.begin();
+  MetadataInfo_tmap::iterator end = doc_info.metadata.end();
+
+  while(current != end){
+    temp = current->first;
+    lc(temp);
+    if(temp == "dc.date"){
+      lastModified = current->second.values[0];
+      return;
+    }
+    else{ 
+      if (temp == "lastmodified" && lastModified == "" && current->second.values.size() >= 1) {
+	lastModified = current->second.values[0];
+	time_t raw_time = (time_t)lastModified.getint();
+	lastModified = this->parseDatestamp(raw_time);
+	return;
+      }
+    }
+    ++current;
+  }  
+}
+
+bool oaiaction::inDateRange(const text_t &from, const text_t &until, const text_t &collection, 
+			    const text_t &OID, recptproto *protocol, ostream &logout)
+{
+  FilterResponse_t response;
+  text_tset        metadata;
+  bool status_ok = get_info(OID, collection, "", metadata, false, protocol, response, logout);
+  bool not_too_early = false, not_too_recent = false;
+
+  if(status_ok) {
+    ResultDocInfo_t doc_info = response.docInfo[0];
+    text_t lastModDate;
+    this->getLastModifiedDate(doc_info, lastModDate);
+    
+    // All date fields should be in the form YYYY-MM-DD, which allows for a direct comparison
+    if(from != ""){
+      if(from <= lastModDate)
+	not_too_early = true;
+    }
+    else 
+      not_too_early = true; // If there's no FROM field, then the record can't be too early
+
+    if(until != ""){
+      if(lastModDate <= until)
+	not_too_recent = true;
+    }
+    else 
+      not_too_recent = true; // If there's no UNTIL field, then the record can't be too recent    
+    
+    if(not_too_early && not_too_recent)
+      return true;
+    else
+      return false;
+  }
+  else
+    return false;
+}
Index: /gsdl/stable/runtime-src/src/oaiservr/oaiaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/oaiaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/oaiaction.h	(revision 20131)
@@ -0,0 +1,64 @@
+#ifndef _oaiaction_h_
+#define _oaiaction_h_
+// standard c++ includes
+//#include <ostream.h>
+
+// generic gsdl stuff
+#include "text_t.h"
+#include "htmlutils.h" // For converting characters in a string to URL encoding. 
+
+// connection to a receptionist
+#include "receptionist.h"
+
+// oaistuff
+#include "oaiargs.h"
+#include "oaiconfig.h"
+#include <time.h>
+
+// Define hours & mins that separate local time from UTC (GMT) time; +ve is ahead of UTC, -ve behind
+#define _LOCALTIME_ "+12:00"
+
+class oaiaction
+{
+ public:
+  oaiaction(const text_t &name);
+
+  virtual void setConfiguration(oaiconfig *config) { this->configuration = config; }
+  text_t getName();
+  text_t parseDatestamp(time_t &rawtime);// Convert date from raw time_t format to the string YYYY-MM-DD
+  void   getResponseDate(text_t &date);  // Get the response date in UTC (GMT) time, plus local offset
+  void   getRequestURL(oaiargs &params, text_t &requestURL); // Get the URL of the request
+  void   getResponse(ostream &output, recptproto *protocol, oaiargs &params);
+  void   output_action_tag(ostream &output, bool openTag);
+  void   output_record_header(ostream &output, const text_t &oaiLabel, const text_t &lastModified, 
+			      const text_tarray &memberOf, int oaiVersion);
+  void   output_error(ostream &output, text_t &errorType); // Output any error conditions
+  bool   formatNotSupported(text_t &metaFormat);           // Return true if the supplied metadataPrefix
+                                                           // format is not supported
+  void   setErrorType(text_t &err){this->errorType = err;};
+  text_t getErrorType(){return this->errorType;};
+  void   getLastModifiedDate(ResultDocInfo_t &doc_info, text_t &lastModified);
+  bool   inDateRange(const text_t &from, const text_t &until, const text_t &collection, 
+		     const text_t &OID, recptproto *protocol, ostream &logout);
+  /******
+   * The following function sets the isInnerObject flag. It is used by the nested recordaction
+   * object in the listrecs object. This flag provides a means for identifying whether the 
+   * recordaction object is acting on its own or through a listrecsaction object. This is 
+   * to allow for appropriate handling of errors regarding unsupported metadata formats. If 
+   * we are using verb=GetRecord and the supplied metadata format is not supported by this 
+   * particular item, then an error must be thrown. But if were using verb=ListRecords, we only
+   * want to exclude the item in question from the list, not throw an error.
+   */
+  void       setAsInnerObject() { this->isInnerObject = true;}
+
+ protected:
+  oaiconfig *configuration;
+  virtual    bool validateAction(recptproto *protocol, oaiargs &params); // Check that this is a valid action
+  virtual    bool output_content(ostream &output, recptproto *protocol, oaiargs &params) = 0;
+  bool       isInnerObject;
+  text_t     name;
+  text_t     errorType;
+  ostream  * logout;
+};
+#endif
+
Index: /gsdl/stable/runtime-src/src/oaiservr/oaiargs.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/oaiargs.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/oaiargs.cpp	(revision 20131)
@@ -0,0 +1,100 @@
+#include "oaiargs.h"
+#include "cgiutils.h"
+
+// read the arguments from a stream for an OAI action
+void oaiargs::readArgs(istream &in)
+{
+  unsigned char  buffer[256];
+  unsigned char *end = buffer + 256;
+  unsigned char *here = end;
+  unsigned char *start, *equals;
+
+  // if no parameters, return now.
+  if (in.eof()) {
+    cerr << "Aborting on EOF" << endl;
+    return;
+  }
+
+  // fill the buffer with the stream
+  this->fillBuffer(in, buffer, &here, end);
+
+  // start at the beginning of the buffer, read
+  // the stream until exhausted
+  here = buffer;
+  while (*here != '\0')
+  {
+    // each iteration of the outer loop reads a single argument
+
+    // we start an argument and continue until the buffer is
+    // exhausted or the next argument is found
+    start = here;
+    equals = NULL;
+    while (*here != '&' && *here != '\0') {
+      // remember where the equals sign was if necessary
+      if (equals == NULL && *here == '=') {
+	equals = here;
+      }
+
+      // move to the next character
+      ++here;
+
+      // and refill the buffer as necessary
+      if (here == end) {
+	this->fillBuffer(in, buffer, &here, end);
+      }
+    }
+    
+    // we've now got the scope of one argument, where it begins, ends
+    // and where the equals sign is; we now split it up accordingly
+    // to create the actual text_t type elements for the label and the
+    // value.
+    text_t label, value;
+    if (equals == NULL) {
+      label.setcarr((char *) start, (int) here - (int) start);
+      value = label;
+    }
+    else {
+      label.setcarr((char *) start, (int) equals - (int) start);
+      ++equals;
+      value.setcarr((char *) equals, (int) here - (int) equals);
+    }
+
+    decode_cgi_arg(value);
+    
+    // output to the screen for tracing purposes
+    // cerr << label << "?" << value << endl;
+
+    // if the argument already exists, raise an error
+    if (this->arguments.count(label) > 0) {
+      this->duplicateArg = true;
+    }
+    else {
+      // add this argument to the argument map
+      this->arguments[label] = value;
+    }
+
+    // don't choke on an argument separator; swallow it so we don't get
+    // inifinite loops above
+    if (*here == '&') {
+      ++here;
+    }
+  }
+}
+
+void oaiargs::fillBuffer(istream &in, unsigned char *buffer, unsigned char **currentPtr, unsigned char *end)
+{
+  unsigned char *fill = buffer;
+
+  // copy out the remaining buffer space
+  while (*currentPtr != end) {
+    *fill = **currentPtr;
+    *currentPtr++;
+  }
+
+  // set the buffer appropriately
+  *currentPtr = fill;
+
+  // refill the buffer
+  in.get((char *)*currentPtr, (char *)end - (char *)*currentPtr);
+}
+
Index: /gsdl/stable/runtime-src/src/oaiservr/oaiargs.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/oaiargs.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/oaiargs.h	(revision 20131)
@@ -0,0 +1,32 @@
+#include <map>
+
+#include "text_t.h"
+
+class oaiargs
+{
+ private:
+  text_tmap arguments;
+  text_t    dummy;
+  bool      duplicateArg;
+  // fill the input buffer to parse the arguments
+  void fillBuffer(istream &stream, unsigned char *buffer, unsigned char **currentPtr, unsigned char *end);
+ public:
+  oaiargs() { this->duplicateArg = false; }
+
+  const text_t &operator [](const text_t &label) { 
+    if (this->arguments.count(label) > 0) {
+      return this->arguments[label]; 
+    }
+    return dummy; // Dodgy, but text_t's are initialised to "", so should be fine
+  };
+
+  void erase(const text_t &label) {
+    this->arguments.erase(label);
+  }
+
+  void readArgs(istream &stream);
+  bool hasDuplicateArg() { return this->duplicateArg; }
+  int getSize(){return arguments.size();}
+  text_tmap::const_iterator begin(){return arguments.begin();};
+  text_tmap::const_iterator end(){return arguments.end();};
+};
Index: /gsdl/stable/runtime-src/src/oaiservr/oaiconfig.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/oaiconfig.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/oaiconfig.cpp	(revision 20131)
@@ -0,0 +1,393 @@
+#include "oaiconfig.h"
+
+#include <algorithm>
+#include <iostream>
+
+#include "fileutil.h"
+
+/**
+ *  The mapping works as follows in the oai.cfg or collect.cfg file.
+ *
+ *  A line is in the format oaimapping <collection field> <oai field>
+ *
+ *  The map here is used to look up the "Greenstone" name which is mapped from
+ *  a given OAI field name, the reverse direction to that given in the 
+ *  Greenstone collect.cfg file.  The oairecordaction class instance which
+ *  produces output for an OAI record information request thus uses the map
+ *  to work from the field in the collection it has on hand which OAI
+ *  record name it should use instead.
+ *
+ *  An extension is to be used for this in which the OAI field name in the
+ *  collect.cfg file can be made specific for a particular record format.
+ *  This is done using the OAI field name in the format of 
+ *    <OAI format>.<OAI field name>
+ *  Thus, an rfc1807 Title field would be referred to as rfc1807.Title
+ *
+ *  A collection-level mapping can be provided in oai.cfg by prepending 
+ *  collname to collection field:
+ *  <collname:field> <oai field>
+
+ *  In the absence of a particular format name, the mapping is taken to be
+ *  universal.
+ */
+
+oaiconfig::oaiconfig() : configurable () {
+  this->resumptionSize = -1; // Default = do not use resumption tokens
+}
+
+oaiconfig::oaiconfig(text_t &gsdlhome, text_t &gsdlcollect) 
+{
+  // read main configuration file (oai.cfg) to get oai collections
+  text_t mainconfig = filename_cat(gsdlhome, "etc", "oai.cfg");
+  this->collection = "";
+  this->resumptionSize = -1;
+  this->read_configfile(mainconfig);
+
+  // then if we've not got a specified collection in the gsdlcollect
+  // parameter, read in all the collection's individual configurations
+  if (gsdlcollect == "") {
+    text_tarray::iterator start = this->collectList.begin();
+    text_tarray::iterator here  = this->collectList.end()-1;
+    while (here != start) {		
+      if (!this->configureCollection(gsdlhome, *here)) {
+	this->collectList.erase(here);
+      }
+      --here;
+    }
+    // and do the first one
+    if (!this->configureCollection(gsdlhome, *here)) {
+      this->collectList.erase(here);
+    }
+    
+  }
+  else {
+    // what do we do if this fails?
+    this->configureCollection(gsdlhome, gsdlcollect);
+  }
+}
+
+oaiconfig::~oaiconfig() 
+{
+  oaicollectmap::iterator here = this->collectMap.begin();
+  oaicollectmap::iterator end  = this->collectMap.end();
+  while (here != end) {
+    delete here->second;
+    ++here;
+  }	
+}
+
+int oaiconfig::resumeAfter()
+{ return this->resumptionSize;
+}
+
+int oaiconfig::getOAIVersion()
+{ 
+  if (this->oaiVersion == "1.1") {
+    return 110;
+  }
+  return 200; 
+}
+
+bool oaiconfig::configureCollection(const text_t &gsdlhome, const text_t &gsdlcollect)
+{
+  text_t cnfgfile = filename_cat(gsdlhome, "collect", gsdlcollect, "etc", "collect.cfg");
+  if (!file_exists(cnfgfile)) {
+    return false;
+  }
+  this->collection = gsdlcollect;
+  this->read_configfile(cnfgfile);
+
+  return true;
+}
+void oaiconfig::configure (const text_t &key, const text_tarray &cfgline)
+{
+  // we've got an oai mapping item, and at least two fields
+  if (key == "oaimapping" && cfgline.size() > 1) {
+    text_t::const_iterator colonAt;
+    text_t index, name, configCollection;
+
+    // Take a default collection as being whatever the collection being configured is...
+    configCollection = this->collection;
+    
+    // get the name of the (collection) field to map; this may actually
+    // be in a colon separated format of the type 
+    // <collection name>:<field name>
+    index = cfgline[0];
+    if ((colonAt = find(index.begin(), index.end(), ':')) != index.end()) {
+      configCollection = substr(index.begin(), colonAt);
+
+      if (this->collection != "" && configCollection != this->collection) {
+	cerr << "Attempt to configure OAI mappings for " << configCollection << " in " << this->collection << endl;
+      }
+
+      colonAt += 1;
+      index = substr(colonAt, index.end());
+    }
+    
+    // the second parameter is the metadata field to map the collection
+    // field onto.  It may be provided with a metadata protocol (which
+    // will be given first and separated by a period or full stop).  In 
+    // the case of format.field name, the splitting is done here.
+    if ((colonAt = find(cfgline[1].begin(), cfgline[1].end(), '.')) != cfgline[1].end()) {
+      text_t stub = substr(cfgline[1].begin(), colonAt);
+      colonAt += 1;
+      name = substr(colonAt, cfgline[1].end());
+      index.append(":");
+      index.append(stub);
+    }
+    else {
+      name = cfgline[1];
+    }
+    
+    // now 'index' is in the form <collectionfield>:(formatname) 
+    //     'name' is simply the fieldname within the format
+    //     'configCollection' is the collection to be configured
+    
+    // now simply map the field name (index) onto the collection name (name)
+    if (this->collectMap[configCollection] == NULL) {
+      this->collectMap[configCollection] = new oaicollectconfig(configCollection);
+    }
+    this->collectMap[configCollection]->fieldMap[index] = name;
+    
+    //    cerr << "Mapping " << index << " to " << name << " in " << configCollection << endl;
+    
+    // TODO: check that the mapped field is actually in use
+  }
+  else if (key == "oaicollection" && cfgline.size() >= 1) {
+    // Configure a collection to be used as part of the OAI archive.
+    // This line should read:
+    //
+    // oaicollection <collectionname>
+    //
+    // Where <collectionname> is the name of the directory inside the
+    // gsdl/collect folder which contains the collection.
+    //
+    // To configure several collections, merely repeat this line,
+    // or alternatively use additional collection names after the
+    // first one.
+    //
+    // This configuration should only appear in oai.cfg
+    //
+    if (this->collection != "") {
+      cerr << "Attempt to configure an oai collection outside of oai.cfg" << endl;
+      cerr << "Configuration attempted in " << this->collection << " collection." << endl;
+      exit(1);
+    }
+    for (int c = 0; c < cfgline.size(); ++c) {
+      this->collectList.push_back(cfgline[c]);
+    }
+  }
+  else if (key == "oaimetadata" && cfgline.size() >= 1) {
+    // List of metadata prefixes to suuport
+    // This line should read:
+    //
+    // oaicollection <metadataname> <metadataname>...
+    //
+    //
+    // This configuration should only appear in oai.cfg
+    //
+    if (this->collection != "") {
+      cerr << "Attempt to configure oai metadata outside of oai.cfg" << endl;
+      cerr << "Configuration attempted in " << this->collection << " collection." << endl;
+      exit(1);
+    }
+    for (int c = 0; c < cfgline.size(); ++c) {
+      // todo: check that the set name is valid
+      this->metadataSet.insert(cfgline[c]);
+    }
+  }
+  else if (key == "oaiinfo" && cfgline.size() >= 1) {
+    // Get a piece of information for the oai repository information
+    // request.  The line should read:
+    //
+    // oaiinfo <information field name> <value>
+    //
+    // This configuration should only be attempted in oai.cfg
+    //
+    if (this->collection != "") {
+      cerr << "Attempt to set oai information outside of oai.cfg" << endl;
+      cerr << "Configuration attempted in " << this->collection << " collection." << endl;
+      exit(1);
+    }
+    
+    // if no second parameter is given, then the first parameter
+    if (cfgline.size() == 1) {
+      this->infoMap[cfgline[0]] = cfgline[0];
+    }
+    else {
+      this->infoMap[cfgline[0]] = cfgline[1];
+    }
+  }
+  else if (key == "oaiversion" && cfgline.size() >= 1) {
+    this->oaiVersion = cfgline[0];
+  }
+  else if (key == "resumeafter" && cfgline.size() >= 1) {
+    this->resumptionSize = cfgline[0].getint();
+  }
+  // get and note a maintainer item to support the Identify Verb of OAI
+  else if (key == "maintainer" && cfgline.size() >= 1) {
+    int line = 0;
+    
+    // TODO: exhaustive checks for empty or default values of maintainer
+    while (line < cfgline.size()) {
+      if (cfgline[line] != "NULL" &&
+	  cfgline[line] != "") {
+	// do something
+	break;
+      }
+      else {
+	++line;
+      }
+    }
+    
+    // Only try to set the configuration if we have a legitimate value ...
+    if (line < cfgline.size()) {
+      // ensure we have a map to write to
+      if (this->collectMap[this->collection] == NULL) {
+	this->collectMap[this->collection] = new oaicollectconfig(this->collection);
+      }
+      this->collectMap[this->collection]->maintainer = cfgline[line];
+    }
+  }
+  else if (key == "repositoryName" && cfgline.size() >= 1) {
+    int line = 0;
+    
+    // TODO: exhaustive checks for empty or default values of repositoryName
+    while (line < cfgline.size()) {
+      if (cfgline[line] != "NULL" &&
+	  cfgline[line] != "") {
+	// do something
+	break;
+      }
+      else {
+	++line;
+      }
+    }
+    
+    // Only try to set the configuration if we have a legitimate value ...
+    if (line < cfgline.size()) {
+      // ensure we have a map to write to
+      if (this->collectMap[this->collection] == NULL) {
+	this->collectMap[this->collection] = new oaicollectconfig(this->collection);
+      }
+      this->collectMap[this->collection]->repositoryName = cfgline[line];
+    }
+  }
+  else if (key == "baseURL" && cfgline.size() >= 1) {
+    int line = 0;
+    
+    while (line < cfgline.size()) {
+      if (cfgline[line] != "NULL" &&
+	  cfgline[line] != "") {
+	// do something
+	break;
+      }
+      else {
+	++line;
+      }
+    }
+    
+    // Only try to set the configuration if we have a legitimate value ...
+    if (line < cfgline.size()) {
+      // ensure we have a map to write to
+      if (this->collectMap[this->collection] == NULL) {
+	this->collectMap[this->collection] = new oaicollectconfig(this->collection);
+      }
+      this->collectMap[this->collection]->baseURL = cfgline[line];
+    }
+  }
+  else if (key == "baseDocRoot" && cfgline.size() >= 1) {
+    int line = 0;
+    
+    while (line < cfgline.size()) {
+      if (cfgline[line] != "NULL" &&
+	  cfgline[line] != "") {
+	// do something
+	break;
+      }
+      else {
+	++line;
+      }
+    }
+    
+    // Only try to set the configuration if we have a legitimate value ...
+    if (line < cfgline.size()) {
+      // ensure we have a map to write to
+      if (this->collectMap[this->collection] == NULL) {
+	this->collectMap[this->collection] = new oaicollectconfig(this->collection);
+      }
+      this->collectMap[this->collection]->baseDocRoot = cfgline[line];
+    }
+  }
+}
+
+/** 
+ *  TODO: store all field values in a map per collection
+ */
+text_t oaiconfig::getCollectionConfig(const text_t &collection, const text_t &field)
+{
+  if (this->collectMap[collection] == NULL) {
+    return "";
+  }
+  if (field == "maintainer") {
+    return this->collectMap[collection]->maintainer;
+  }
+
+  if (field == "repositoryName") {
+    return this->collectMap[collection]->repositoryName;
+  }
+
+  if (field == "baseURL") {
+    return this->collectMap[collection]->baseURL;
+  }
+
+  if (field == "baseDocRoot") {
+    return this->collectMap[collection]->baseDocRoot;
+  }
+
+  return "";
+}
+
+text_t oaiconfig::getMapping(const text_t &collection, const text_t &collectfield)
+{
+  if (this->collectMap[collection] == NULL) {
+    return "";
+  }
+  return this->collectMap[collection]->fieldMap[collectfield];
+}
+
+/**
+ *  Get the mapping for a field in a given collection; if no mapping
+ *  exists, the result will be a blank string.
+ */
+text_t oaiconfig::getMapping(const text_t &collection, const text_t &collectfield, const text_t &formatname)
+{
+  text_t fullName = collectfield;
+  fullName.append(":");
+  fullName.append(formatname);
+
+  // try the collection-specific options first
+  if (this->collectMap[collection] != NULL) {
+    // first try the most specific item - this collection, and given that protocol
+    if (this->collectMap[collection]->fieldMap.count(fullName) >= 1) {
+      return this->collectMap[collection]->fieldMap[fullName];
+    }
+    // otherwise, fall back to this collection, and all protocols
+    else if (this->collectMap[collection]->fieldMap.count(collectfield) >= 1) {
+      return this->collectMap[collection]->fieldMap[collectfield];
+    }
+  }
+
+  // if no mappings exist, return an empty item
+  if (this->collectMap[""] == NULL) {
+    return "";
+  }
+
+  // then try generic rules
+  if (this->collectMap[""]->fieldMap.count(fullName) >= 1) {
+    return this->collectMap[""]->fieldMap[fullName];
+  }
+  else {
+    return this->collectMap[""]->fieldMap[collectfield];
+  }
+}
Index: /gsdl/stable/runtime-src/src/oaiservr/oaiconfig.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/oaiconfig.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/oaiconfig.h	(revision 20131)
@@ -0,0 +1,52 @@
+#ifndef _OAICONFIG_H_
+#define _OAICONFIG_H_
+
+#include "cnfgable.h"
+
+#include <map>
+
+// TODO: sort out the members of oaicollectconfig as private/public and add
+//       corresponding set/get functions
+
+class oaicollectconfig {
+ public:
+  oaicollectconfig(const text_t &collectname) { this->collection = collectname; }
+  text_t    collection;
+  text_t    maintainer;
+  text_t    repositoryName;
+  text_t    baseURL; // URL of oaiserver.cgi
+  text_t    baseDocRoot; // Base URL for gsdl directory 
+  text_tmap fieldMap;    // maps from OAI name to GSDL name
+};
+
+typedef map<text_t, oaicollectconfig *, lttext_t> oaicollectmap;
+
+class oaiconfig : configurable {
+ public:
+  oaiconfig();
+  oaiconfig(text_t &gsdlhome, text_t &gsdlcollect);
+  ~oaiconfig();
+  virtual void  configure(const text_t &key, const text_tarray &cfgline);
+  text_t        getCollectionConfig(const text_t &collection, const text_t &field);
+  text_tarray & getCollectionsList() { return this->collectList; }
+  text_tset & getMetadataSet() { return this->metadataSet; }
+  text_t        getMapping(const text_t &collection, const text_t &collectfield);
+  text_t        getMapping(const text_t &collection, const text_t &collectfield, const text_t &format);
+  text_tmap   * getInformation() { return &this->infoMap; }
+  int           getOAIVersion();
+  int           resumeAfter();
+ private:
+  bool configureCollection(const text_t &gsdlhome, const text_t &collection);
+  
+  text_tarray collectList;  // The list of collections to be taken in hand
+  text_tset metadataSet; // The list of metadata sets to be supported
+  text_tmap infoMap;        // Holds the information to be given in the case
+                            // of an OAI identify request
+  oaicollectmap collectMap; // The configuration of collections
+  text_t collection;        // Used to track which collection is being configured
+  text_t oaiVersion;        // The version of OAI running
+  int    resumptionSize;    // The number of items to produce before spitting out a
+                            // resumptionToken
+  
+};
+#endif
Index: /gsdl/stable/runtime-src/src/oaiservr/oaidispatcher.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/oaidispatcher.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/oaidispatcher.cpp	(revision 20131)
@@ -0,0 +1,80 @@
+#include "oaidispatcher.h"
+
+oaidispatcher::oaidispatcher()
+{ this->configuration = NULL;
+}
+
+oaidispatcher::~oaidispatcher()
+{
+  oaiactionmap::iterator here = this->actions.begin();
+  oaiactionmap::iterator end  = this->actions.end();
+
+  while (here != end) {
+    delete here->second;
+    ++here;
+  }
+}
+
+void oaidispatcher::addAction(oaiaction *thisAction) {
+  thisAction->setConfiguration(this->configuration);
+  this->actions[thisAction->getName()] = thisAction;
+}
+
+void oaidispatcher::doAction(ostream &output, recptproto *protocol, oaiargs &args) {
+
+  text_t verb = args["Verb"];
+  if(verb == "") verb = args["verb"];
+  
+  oaiaction *action = actions[verb];
+  
+  if (action != NULL) {
+    action->getResponse(output, protocol, args);
+  }
+  else {  
+    // If the verb isn't correct, send an error.
+    action = actions["Identify"];
+    text_t responseDate, requestURL;
+    int version = this->configuration->getOAIVersion();
+    action->getResponseDate(responseDate);
+    oaiargs emptySet;
+    action->getRequestURL(emptySet, requestURL);
+
+    // Bad verb is signified by a status 400 response for OAI 1.1
+    if (version <= 110) {
+      output << "Status: 400\n";
+    }
+    else {
+      output << "Status: 200\n";
+    }
+    output << "Content-type: text/xml" << endl << endl;
+    output << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+    
+    if(version <= 110){
+      // output OAI v1.1 action header tag - nil, as there is no valid heeader for the action
+      /*
+	output << "<" << action->name;
+	output << "\n       xmlns=\"http://www.openarchives.org/OAI/1.1/OAI_" << action->name << "\" ";
+	output << "\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
+	output << "\n       xsi:schemaLocation=\"http://www.openarchives.org/OAI/1.1/OAI_" << action->name;
+	output << "\n           http://www.openarchives.org/OAI/1.1/OAI_" << action->name << ".xsd\">\n";
+      */    
+    }
+    else { 
+      // output OAI v2.0 action header tag
+      output << "<OAI-PMH xmlns=\"http://www.openarchives.org/OAI/2.0/\"\n"
+	     << "         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+	     << "         xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/\n"
+	     << "             http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd\">\n"
+	     << "  <responseDate>" << responseDate << "</responseDate>\n"
+	     << requestURL 
+	     << "  <error code=\"badVerb\">Illegal OAI verb</error>\n"
+	     << "</OAI-PMH>\n";
+    }
+
+    /*
+      cout << "<title>Bad OAI request</title>" << endl;
+      cout << "<h1>Bad OAI request</h1>" << endl;
+    */
+  }
+  output.flush();
+}
Index: /gsdl/stable/runtime-src/src/oaiservr/oaidispatcher.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/oaidispatcher.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/oaidispatcher.h	(revision 20131)
@@ -0,0 +1,24 @@
+#include "oaiaction.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\map>
+#elif defined(GSDL_USE_STL_H)
+#  include <map.h>
+#else
+#  include <map>
+#endif
+
+typedef map<text_t, oaiaction *, lttext_t> oaiactionmap;
+
+class oaidispatcher
+{
+ private:
+  oaiactionmap actions;
+  oaiconfig   *configuration;
+ public:
+  oaidispatcher();
+  ~oaidispatcher();
+  void setConfiguration(oaiconfig *configuration) { this->configuration = configuration; }
+  void addAction(oaiaction *thisAction);
+  void doAction(ostream &stream, recptproto *protocol, oaiargs &args);
+};
Index: /gsdl/stable/runtime-src/src/oaiservr/oaimain.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/oaimain.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/oaimain.cpp	(revision 20131)
@@ -0,0 +1,165 @@
+#include "oaimain.h"
+
+/**********************************************************************
+ *
+ * oaimain.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdlconf.h"
+
+#if defined(GSDL_USE_IOS_H)
+#  include <fstream.h>
+#  if defined(__WIN32__)
+#    include <strstrea.h> // vc4
+#  else
+#    include <strstream.h>
+#  endif
+#else
+#  include <fstream>
+#  include <sstream>
+#endif
+
+#include "fileutil.h"
+#include "nullproto.h"
+#include "collectset.h"
+#include "cgiargs.h"
+
+#include "identifyaction.h"
+#include "recordaction.h"
+#include "listsetsaction.h"
+#include "listrecsaction.h"
+#include "listidsaction.h"
+#include "metaformatsaction.h"
+#include "oaidispatcher.h"
+#include "oaiconfig.h"
+
+void get_cgi_args(text_t &argstring)
+{
+  // get the query string if it is not being run as a fastcgi
+  // script
+  text_t argstr = "";
+  char *aURIStr;
+  char *request_method_str = getenv("REQUEST_METHOD");
+  char *content_length_str = getenv("CONTENT_LENGTH");
+  if (request_method_str != NULL && strcmp(request_method_str, "POST") == 0 &&
+      content_length_str != NULL)  {
+    // POST form data
+    int content_length = text_t(content_length_str).getint();
+    if (content_length > 0) {
+      char c;
+      do {
+	cin.get(c);
+	if (cin.eof()) 
+	  break;
+	argstr.push_back (c);
+	--content_length;
+      } while (content_length > 0);
+    }
+    
+  } else {
+    aURIStr = getenv("QUERY_STRING");
+    if ((request_method_str != NULL && strcmp(request_method_str, "GET") == 0)
+	|| aURIStr != NULL) {
+      // GET form data
+      if (aURIStr != NULL) 
+	argstr = aURIStr;
+    } else {
+      // debugging from command line
+      // debug = true;
+      char inStr[1024];
+      
+      cin.get(inStr, 1024);
+      argstr = inStr;
+    }
+  }
+  argstring = argstr;
+}
+
+
+int main(int argc, char *argv[])
+{
+  text_t        cgiargstring;
+  nullproto     nproto;
+  collectset   *cservers;
+  text_t        gsdlhome;
+  text_t        collecthome;
+  text_t        gsdlcollect = "";
+  oaiargs       args;
+  ofstream      logout("oai.log", ios::app);
+  
+  // convert cgi to oai map
+  get_cgi_args(cgiargstring);
+  
+  char *cstr = cgiargstring.getcstr();
+#if defined(GSDL_USE_IOS_H)
+  istrstream cgi_in(cstr, cgiargstring.size());
+#else
+  istringstream cgi_in(cstr);
+#endif
+
+  // parse the arguments
+  args.readArgs(cgi_in);
+
+  delete []cstr;
+  
+  cservers = new collectset(gsdlhome,collecthome);
+
+  // set up the null protocol
+  nproto.set_collectset(cservers);
+  
+  // get the oai configuration
+  oaiconfig config(gsdlhome, gsdlcollect);
+
+  // set up the dispatcher
+  oaidispatcher dispatcher;
+  dispatcher.setConfiguration(&config);
+
+  identifyaction *id   = new identifyaction;
+  recordaction   *rec  = new recordaction(config.getMetadataSet());
+  listsetsaction *sets = new listsetsaction;
+  listrecsaction *records = new listrecsaction;
+  records->set_recordMaker(rec);
+
+  listidsaction  *ids     = new listidsaction;
+  metaformatsaction *formats = new metaformatsaction;
+  formats->set_formats(rec->get_formats());
+
+  dispatcher.addAction(id);
+  dispatcher.addAction(rec);
+  dispatcher.addAction(sets);
+  dispatcher.addAction(records);
+  dispatcher.addAction(ids);
+  dispatcher.addAction(formats);
+
+  // deal with this request
+  comerror_t error;
+  nproto.init(error, logout);
+
+  // GRB: any checks that a collection exists would be done here
+  //      At present, I foresee no useful application of that requirement.
+
+  dispatcher.doAction(cout, &nproto, args);
+  
+  delete cservers;
+  return 0;
+}
Index: /gsdl/stable/runtime-src/src/oaiservr/oaimain.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/oaimain.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/oaimain.h	(revision 20131)
@@ -0,0 +1,1 @@
+// nothing
Index: /gsdl/stable/runtime-src/src/oaiservr/oaitools.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/oaitools.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/oaitools.cpp	(revision 20131)
@@ -0,0 +1,82 @@
+#include "oaitools.h"
+
+#include <algorithm>
+
+#include "recptprototools.h"
+
+void oaiclassifier::swapColonsAndPeriods(text_t &classifier)
+{
+  for (int i = 1; i <= classifier.size(); ++i) {
+    if (classifier[i] == '.') {
+      classifier[i] = ':';
+    }
+    else if (classifier[i] == ':') {
+      classifier[i] = '.';
+    }
+  }
+
+}
+
+text_t oaiclassifier::getGSDL_OID(const text_t &collection, const text_t& oai_id, 
+				  recptproto *protocol, ostream &logout)
+{
+  FilterResponse_t response;
+  text_tset        metadata;
+
+  // metadata.insert("gsdl_id");
+
+  bool status_ok = get_children(oai_id, collection, "", metadata, false, protocol, response, logout);
+  text_t gsdl_id = "";
+  if (status_ok) {
+    if(response.docInfo.size() > 0){
+      gsdl_id = response.docInfo[0].OID;
+    }
+    else {
+      // Response.docInfo is empty, meaning the doc in question didn't have an oai_id number.
+      return gsdl_id; // Return the empty string to indicate this.
+    }
+  }
+
+  return gsdl_id;
+}
+
+/**
+ *  Called to convert GS classifier/document identifiers that use
+ *  a '.' to separate levels in the hierarchy into OAI identifiers
+ *  that use ':' instead.
+ */
+void oaiclassifier::toOAI(const text_t &collection, text_t &classifier)
+{
+  oaiclassifier::swapColonsAndPeriods(classifier);
+
+  // prepend the collection identifier to the beginning of the
+  // OAI identifier.
+  text_t tmp = collection;
+  tmp.append(":");
+  tmp.append(classifier);
+  
+  classifier = tmp;
+}
+
+/**
+ *  Called to convert OAI classifier/document identifiers that use
+ *  a ':' to separate levels in the hierarchy into GS identifiers
+ *  that use '.' instead.
+ */
+void oaiclassifier::toGSDL(text_t &collection, text_t &classifier)
+{
+  oaiclassifier::swapColonsAndPeriods(classifier);
+
+  // separate out the collection identifier that should be
+  // found at the beginning of the OAI identifier from the
+  // item identifier within the collection
+  text_t::iterator colon = find(classifier.begin(), classifier.end(), '.');
+  if (colon != classifier.end()) {
+    collection = substr(classifier.begin(), colon);
+    classifier = substr(colon + 1, classifier.end());
+  }
+  else{
+    collection = classifier;
+    classifier = "";
+  }
+}
Index: /gsdl/stable/runtime-src/src/oaiservr/oaitools.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/oaitools.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/oaitools.h	(revision 20131)
@@ -0,0 +1,17 @@
+
+#ifndef _OAITOOLS_H_
+#define _OAITOOLS_H_
+
+#include "text_t.h"
+#include "receptionist.h"
+
+class oaiclassifier {
+ public:
+  static text_t getGSDL_OID(const text_t &collection, const text_t& oai_id, recptproto *protocol, 
+			    ostream &logout);
+  static void   toOAI(const text_t &collection, text_t &classifier);
+  static void   toGSDL(text_t &collection, text_t &classifier);
+ private:
+  static void   swapColonsAndPeriods(text_t &classifier);
+};
+#endif
Index: /gsdl/stable/runtime-src/src/oaiservr/qualified_dublincore.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/qualified_dublincore.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/qualified_dublincore.cpp	(revision 20131)
@@ -0,0 +1,118 @@
+
+#include "qualified_dublincore.h"
+
+qualified_dublin_core::qualified_dublin_core() : metaformat() {
+  // These element names taken from the schema
+  //http://www.greenstone.org/namespace/gsdl_qdc/1.0/gsdl_qdc.xsd
+
+  elementSet.insert("title");
+   elementSet.insert("creator");
+   elementSet.insert("subject");
+   elementSet.insert("description");
+   elementSet.insert("publisher");
+   elementSet.insert("contributor");
+   elementSet.insert("date");
+   elementSet.insert("type");
+   elementSet.insert("format");
+   elementSet.insert("identifier");
+   elementSet.insert("source");
+   elementSet.insert("language");
+   elementSet.insert("relation");
+   elementSet.insert("coverage");
+   elementSet.insert("rights");
+   elementSet.insert("alternative");
+   elementSet.insert("tableOfContents");
+   elementSet.insert("abstract");
+   elementSet.insert("created");
+   elementSet.insert("valid");
+   elementSet.insert("available");
+   elementSet.insert("issued"); 
+   elementSet.insert("modified");
+   elementSet.insert("dateAccepted");
+   elementSet.insert("dateCopyrighted");
+   elementSet.insert("dateSubmitted");
+   elementSet.insert("extent");
+   elementSet.insert("medium");
+   elementSet.insert("isVersionOf");
+   elementSet.insert("hasVersion");
+   elementSet.insert("isReplacedBy");
+   elementSet.insert("replaces"); 
+   elementSet.insert("isRequiredBy");
+   elementSet.insert("requires"); 
+   elementSet.insert("isPartOf");
+   elementSet.insert("hasPart"); 
+   elementSet.insert("isReferencedBy");
+   elementSet.insert("references");
+   elementSet.insert("isFormatOf");
+   elementSet.insert("hasFormat");
+   elementSet.insert("conformsTo");
+   elementSet.insert("spatial");
+   elementSet.insert("temporal");
+   elementSet.insert("audience");
+   elementSet.insert("accrualMethod");
+   elementSet.insert("accrualPeriodicity");
+   elementSet.insert("accrualPolicy");
+   elementSet.insert("instructionalMethod");
+   elementSet.insert("provenance");
+   elementSet.insert("rightsHolder");
+   elementSet.insert("mediator");
+   elementSet.insert("educationLevel");
+   elementSet.insert("accessRights");
+   elementSet.insert("license"); 
+   elementSet.insert("bibliographicCitation");
+}
+const text_t qualified_dublin_core::formatName() {
+  return "gsdl_qdc";
+}
+
+const text_t qualified_dublin_core::formatPrefix() {
+  return "dc";
+}
+
+bool qualified_dublin_core::output_record(ostream &output, recptproto *protocol, const text_t &collection, 
+				const text_t &record_OID) 
+{
+  return metaformat::output_record(output, protocol, collection, record_OID);
+}
+
+void qualified_dublin_core::output_metadata_header(ostream &output)
+{ 
+  output << "    <metadata>\n";
+  
+  if (this->oaiConfigure->getOAIVersion() <= 110){
+    // output dublin core wrapper for OAI v1.1
+    output << "      <gsdl_qdc xmlns=\"http://greenstone.org/namespace/gsdl_qdc/1.0/\"\n"
+	   << "          xmlns:xsi=\"http://www.w3c.org/2001/XMLSchema-instance\"\n"
+	   << "          xsi:schemaLocation=\"http://greenstone.org/namespace/gsdl_qdc/1.0/ \n"
+	   << "                              http://greenstone.org/namespace/gsdl_qdc/1.0/gsdl_qdc.xsd\">\n";
+  }
+  else { 
+    output << "      <gsdl_qdc:gsdl_qdc\n"
+	   << "          xmlns:gsdl_qdc=\"http://greenstone.org/namespace/gsdl_qdc/1.0/\"\n"
+	   << "          xmlns:dc=\"http://purl.org/dc/terms/\"\n"
+	   << "          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+	   << "          xsi:schemaLocation=\"http://greenstone.org/namespace/gsdl_qdc/1.0/ \n"
+	   << "                              http://greenstone.org/namespace/gsdl_qdc/1.0/gsdl_qdc.xsd\">\n";
+  }
+}
+
+void qualified_dublin_core::output_metadata_footer(ostream &output)
+{
+  if (this->oaiConfigure->getOAIVersion() <= 110) {
+    output << "      </gsdl_qdc>" << endl;
+  }
+  else {
+    output << "      </gsdl_qdc:gsdl_qdc>" << endl;
+  }
+
+  output << "    </metadata>" << endl; 
+  output.flush();
+}
+
+bool qualified_dublin_core::output_formatdata(ostream &output)
+{
+  output << "    <metadataPrefix>gsdl_qdc</metadataPrefix>" << endl;
+  output << "    <schema>http://greenstone.org/namespace/gsdl_qdc/1.0/gsdl_qdc.xsd</schema>" << endl;
+  output << "    <metadataNamespace>http://greenstone.org/namespace/gsdl_qdc/1.0/</metadataNamespace>"<<endl;
+  return true;
+}
Index: /gsdl/stable/runtime-src/src/oaiservr/qualified_dublincore.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/qualified_dublincore.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/qualified_dublincore.h	(revision 20131)
@@ -0,0 +1,18 @@
+#include "metaformat.h"
+
+class qualified_dublin_core : public metaformat
+{
+ protected:
+  virtual void output_metadata_header(ostream &output);
+  virtual void output_metadata_footer(ostream &output);
+ public:
+  qualified_dublin_core();
+  virtual const text_t formatName();
+  virtual const text_t formatPrefix();
+  virtual bool output_record(ostream &output, recptproto *protocol, const text_t &collection, 
+			     const text_t &record_OID);
+  virtual bool output_formatdata(ostream &output);
+  virtual ~qualified_dublin_core() {}
+};
+
+
Index: /gsdl/stable/runtime-src/src/oaiservr/recordaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/recordaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/recordaction.cpp	(revision 20131)
@@ -0,0 +1,220 @@
+#include "recordaction.h"
+#include "recptprototools.h"
+#include "dublincore.h"
+#include "qualified_dublincore.h"
+#include "rfc1807.h"
+#include "oaitools.h"
+#include <time.h>
+
+
+recordaction::recordaction(text_tset &metadataset) : oaiaction("GetRecord") {
+  metaformatptr fptr;
+
+  if (metadataset.count("oai_dc") > 0) {
+    fptr.set_class(new dublin_core());  
+    this->formatMap[fptr.get_class()->formatName()] = fptr;
+  }
+  
+  if (metadataset.count("gsdl_qdc") > 0) {
+    fptr.set_class(new qualified_dublin_core());  
+    this->formatMap[fptr.get_class()->formatName()] = fptr;
+  }
+  
+  if (metadataset.count("rfc1807") > 0) {
+
+    fptr.set_class(new rfc1807());
+    this->formatMap[fptr.get_class()->formatName()] = fptr;
+  }
+}
+
+recordaction::~recordaction() {
+  metaformat_map::iterator here = this->formatMap.begin();
+  metaformat_map::iterator end  = this->formatMap.end();
+
+  while (here != end) {
+    here->second.clear();
+    ++here;
+  }
+}
+
+
+bool recordaction::validateAction(recptproto *protocol, oaiargs &params)
+{
+  // ----------------------------------------------------------------------------
+  //  1. Check for invalid arguments
+  // ----------------------------------------------------------------------------
+  bool invalid_argument_supplied = false;
+  text_tmap::const_iterator param_iterator = params.begin();
+  while (param_iterator != params.end())
+  {
+    // Check for arguments that aren't valid for this action
+    if (param_iterator->first != "verb" &&
+	param_iterator->first != "identifier" &&
+	param_iterator->first != "metadataPrefix")
+    {
+      // We've found an invalid argument
+      invalid_argument_supplied = true;
+
+      // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
+      params.erase(param_iterator->first);
+    }
+
+    param_iterator++;
+  }
+
+  // If we found an invalid argument it's an error, so don't go any further 
+  if (invalid_argument_supplied)
+  {
+    this->errorType = "badArgument";
+    return false;
+  }
+
+  // ----------------------------------------------------------------------------
+  //  2. Handle any exclusive arguments
+  // ----------------------------------------------------------------------------
+
+  // None!
+
+  // ----------------------------------------------------------------------------
+  //  3. Handle any required arguments
+  // ----------------------------------------------------------------------------
+
+  // The "metadataPrefix" argument is required
+  text_t metadataPrefix = params["metadataPrefix"];
+
+  // Check that the metadataPrefix argument exists
+  if (metadataPrefix == "")
+  {
+    this->errorType = "badArgument";
+    return false;
+  }
+
+  // Check that the metadataPrefix is a format we support
+  if (this->formatNotSupported(metadataPrefix))
+  {
+    this->errorType = "cannotDisseminateFormat";
+    return false;
+  }
+
+  // The "identifier" argument is required
+  text_t identifier = params["identifier"];
+
+  // Check that the identifier argument exists
+  if (identifier == "")
+  {
+    this->errorType = "badArgument";
+    return false;
+  }
+
+  // Extract the collection name from the identifier specification
+  text_t collection = "";
+  oaiclassifier::toGSDL(collection, identifier);
+  
+  // Check a document with the specified identifier exists
+  text_tset metadata;
+  if (!get_info(identifier, collection, "", metadata, false, protocol, this->gsdlResponse, *logout))
+  {
+    this->errorType = "idDoesNotExist";
+    return false;
+  }
+
+  // ----------------------------------------------------------------------------
+  // 4. Check any remaining arguments
+  // ----------------------------------------------------------------------------
+
+  // None!
+
+  // If we've reached here everything must be fine
+  this->errorType = "";
+  return true;
+}
+
+//
+// Output the content of a GetRecord request; in this case, the static member 
+// output_record below is used to fulfill most of the request
+//
+bool recordaction::output_content(ostream &output, recptproto *protocol, oaiargs &params)
+{
+  // validateAction will already have set up the correct response content
+  text_t gsdlId = params["identifier"];
+  text_t gsdlCollect;
+
+  // convert record identifier into GSDL format from OAI
+  oaiclassifier::toGSDL(gsdlCollect, gsdlId);
+  
+  // go direct to output_record
+  return output_record(output, gsdlCollect, gsdlId, params["metadataPrefix"]);
+}
+
+//
+// A static member that does everything the output_content method above needs,
+// but can be called when individual records are being output for another 
+// action.
+//
+bool recordaction::output_record(ostream &output, recptproto *protocol, const text_t &collection, const text_t &OID, const text_t &metadataPrefix)
+{
+  text_tset        metadata;
+  ofstream         logout("oai.log", ios::app);
+
+  // get the document information
+  if (!get_info(OID, collection, "", metadata, false, protocol, this->gsdlResponse, logout)) {
+
+    this->errorType = "idDoesNotExist";
+
+    if(this->configuration->getOAIVersion() >= 200) {
+      this->output_error(output, errorType);
+      return false;
+    }
+  }
+
+  return this->output_record(output, collection, OID, metadataPrefix);
+}  
+
+bool recordaction::output_record(ostream &output, const text_t &collection, const text_t &OID, 
+				 const text_t &metadataPrefix)
+{ int oaiVersion = this->configuration->getOAIVersion();
+
+  // check to see if it's a classifier
+  text_t childHead;
+  text_t::const_iterator start = OID.begin();
+  text_t::const_iterator here  = OID.begin();
+  here += 2;
+  childHead = substr(start, here);
+  
+  // if it isn't a document, kill it now
+  if (childHead == "CL") {
+    cerr << "Not a document" << endl;
+    return false;
+  }
+
+  ResultDocInfo_t doc_info = this->gsdlResponse.docInfo[0];
+  text_t lastModified = "";
+
+  // Fills lastModified with the date from the document in doc_info, in the format YYYY-MM-DD
+  this->getLastModifiedDate(doc_info, lastModified);
+
+  // If the ID exists, output record for oai response (OAI v1.1)
+  // OAI v2.0 will already have bailed if ID doesn't exist (yes?)
+  if (this->errorType != "idDoesNotExist") {
+    text_t oaiLabel = OID;
+    oaiclassifier::toOAI(collection, oaiLabel); // Concatenates HASH id to collection, which OAI needs
+    
+    // output a record
+    output << "  <record>\n";
+    
+    // output header part of oai response
+    this->output_record_header(output, oaiLabel, lastModified, 
+			       doc_info.metadata["memberof"].values, oaiVersion);
+    
+    if (this->errorType != "cannotDisseminateFormat"){
+      if (this->formatMap[metadataPrefix].get_class()->output_metadata(output, collection, doc_info)) {
+	//  output 'about' part of oai response - we probably won't ever use this
+	//output << "    <about>\n";
+	//output << "    </about>\n";
+      } 
+    }
+    // close record
+    output << "  </record>\n\n";
+  }
+  return true;
+}
Index: /gsdl/stable/runtime-src/src/oaiservr/recordaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/recordaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/recordaction.h	(revision 20131)
@@ -0,0 +1,29 @@
+#ifndef _RECORDACTION_H_
+#define _RECORDACTION_H_
+#include "oaiaction.h"
+
+#include <map>
+
+#include "comtypes.h"
+
+#include "metaformat.h"
+
+class recordaction : public oaiaction
+{
+ private:
+  metaformat_map formatMap;
+  FilterResponse_t gsdlResponse;
+  
+ public:
+  recordaction(text_tset &metadataset);
+  ~recordaction();
+  
+  virtual bool validateAction(recptproto *protocol, oaiargs &params);
+  bool output_content(ostream &output, recptproto *protocol, oaiargs &params);
+  bool output_record(ostream &output, const text_t &collection, const text_t &OID, 
+		     const text_t &metadataPrefix);
+  bool output_record(ostream &output, recptproto *protocol, const text_t &collection, const text_t &OID, 
+		     const text_t &metadataPrefix);
+  metaformat_map *get_formats() { return &this->formatMap; }
+};
+#endif
Index: /gsdl/stable/runtime-src/src/oaiservr/resumptiontoken.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/resumptiontoken.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/resumptiontoken.cpp	(revision 20131)
@@ -0,0 +1,157 @@
+#include "resumptiontoken.h"
+#include "oaitools.h"
+
+/**
+ *  Generate an initial resumption token from some basic details.
+ *
+ *  TODO: add optional argument to set the server name.
+ */
+ResumptionToken::ResumptionToken(const text_t &collection, const text_t &node,
+				 const text_t &buildDate)
+{ this->collection = collection;
+  this->browseNode = node;
+  this->buildDate  = buildDate;
+  this->startItem  = 0;
+}
+
+/**
+ *  Generate a resumption token from a URN-style format.
+ *
+ *  See getToken() for details of the format.
+ *
+ *  TODO: support inclusion of an optional server name.
+ */
+ResumptionToken::ResumptionToken(const text_t &URN)
+{ text_t::const_iterator first = URN.begin();
+  text_t::const_iterator last = URN.end(); 
+  text_t::const_iterator second;
+
+  this->collection = "";
+  this->browseNode = "";
+  this->startItem  = -1;
+  
+  text_t::const_iterator here = findchar(first, last, ':');
+  if (here == first) {
+    return;
+  }
+  
+  text_t oainamespace = substr(first, here);
+  if (oainamespace != "gsdloai") {
+    return;
+  }
+
+  // increment past the first colon to get the location
+  first = ++here;  
+
+  // get the collection, browseNode
+  here = findchar(first, last, ',');
+  if (here == last) {
+    return;
+  }
+
+  second = findchar(first, here,'.');
+  this->collection = substr(first, second);
+
+  //  cerr << "Collection " << this->collection << endl;
+
+  if (second != here) {
+    // get past the '.'
+    ++second;
+    this->browseNode = substr(second, here);
+  }
+  else {
+    first = here;
+  }
+  // get past the ','
+  first = ++here;
+
+  // find the second ',' to delimit the position stack
+  second = findchar(first, last, ',');
+
+  // if not found, then get build and start item
+  if (second != first) {
+    // extract list and step past it
+    text_t offsetList = substr(first, second);
+    first = ++second;
+    
+    do {
+      second = findchar(offsetList.begin(), offsetList.end(), '.');
+      if (second == offsetList.end()) 
+	break;
+      
+      // extract and push the next position
+      text_t thisPos = substr(offsetList.begin(), second);
+      this->browsePosition.push_back(thisPos.getint());
+
+      // pop the position from the list
+      offsetList = substr(++second, offsetList.end());
+    } while (true);    
+    this->browsePosition.push_back(offsetList.getint());
+  }
+  else {
+    first ++;
+  }
+
+  // now find the build date marker
+  here = findchar(first, last, '-');
+  if (here == first) {
+    this->startItem = substr(first, last).getint();
+  }
+  else {
+    this->startItem = substr(first, here).getint();
+    this->buildDate = substr(++here, last); 
+  }
+}
+
+/**
+ *  Get a resumption token in text_t format.
+ * 
+ *  Resumption tokens are in the format:
+ *
+ *    gsdloai:<serverName>:collectionname.browseNode,startItem-BuildDate
+ *
+ *  The resumption token format does not currently implement the use of
+ *  the optional <serverName> item; it is taken to default to the name of
+ *  the receiving server.
+ *
+ *  TODO: add server identity as an optional argument; also change
+ *        ResumptionToken(text_t &) accordingly.
+ */
+text_t ResumptionToken::getToken()
+{ text_t reply = "gsdloai:";
+  reply = reply + this->collection;
+  if (this->browseNode != "") {
+    reply = reply + "." + this->browseNode;
+  }
+  reply = reply + ",";
+  for (int i = 0; i < this->browsePosition.size(); i++) {
+    if (i != 0) {
+      reply.append(".");
+    }
+    reply.appendint(i);
+  }
+  reply = reply + ",";
+  reply.append(this->startItem);
+  reply = reply + "-" + buildDate;
+
+  return reply;
+}
+
+/**
+ *  Update the position of an existing resumption token
+ */
+void ResumptionToken::setPosition(const text_t &node, int startItem)
+{ this->browseNode = node;
+  this->startItem  = startItem; 
+}
+
+/**
+ *  Check if the resumption token is valid - only a very primitive
+ *  check is done here; one ought to check for an existing collection
+ *  and valid browse Node, build date and startItem
+ *
+ *  TODO: implement improved validation checking.
+ */
+bool ResumptionToken::isValid()
+{ return this->collection != "";
+}
Index: /gsdl/stable/runtime-src/src/oaiservr/resumptiontoken.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/resumptiontoken.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/resumptiontoken.h	(revision 20131)
@@ -0,0 +1,42 @@
+#ifndef _RESUMPTIONTOKEN_H_
+#define _RESUMPTIONTOKEN_H_
+
+#include <vector>
+
+#include "text_t.h"
+
+// use the standard namespace
+#if !defined (GSDL_NAMESPACE_BROKEN)
+#if defined(GSDL_USE_OBJECTSPACE)
+using namespace ospace::std;
+#else
+using namespace std;
+#endif
+#endif
+
+class ResumptionToken
+{ private:
+  text_t  collection;
+  text_t  browseNode;
+  vector<int> browsePosition;
+  int     startItem;
+  text_t  buildDate;
+  // TODO: add a server name to the variables list; see getToken in resumptionToken.cpp
+
+ public:
+  ResumptionToken(const text_t &collection, const text_t &rootNode, const text_t &buildDate);
+  ResumptionToken(const text_t &URN);
+  text_t  getToken();
+
+  void setPosition(const text_t &node, int startItem);
+
+  text_t  getCollection() { return collection; }
+  text_t  getNode() { return browseNode; }
+  int     getPosition() { return startItem; }
+  int     getOffsetDepth() { return this->browsePosition.size(); }
+  void    setOffset(int depth, int position) { this->browsePosition[depth] = position; }
+  int getOffset(int offset) { return this->browsePosition[offset]; }
+  bool isValid();
+};
+
+#endif
Index: /gsdl/stable/runtime-src/src/oaiservr/rfc1807.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/rfc1807.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/rfc1807.cpp	(revision 20131)
@@ -0,0 +1,93 @@
+#include "rfc1807.h"
+
+rfc1807::rfc1807() : metaformat(){
+  // These element names taken from the schema
+  // http://www.openarchives.org/OAI/1.1/rfc1807.xsd
+  elementSet.insert("bib-version");
+  elementSet.insert("id");
+  elementSet.insert("entry"); 
+  elementSet.insert("organization");
+  elementSet.insert("title");
+  elementSet.insert("type");
+  elementSet.insert("revision");
+  elementSet.insert("withdraw");
+  elementSet.insert("author"); 
+  elementSet.insert("corp-author");
+  elementSet.insert("contact"); 
+  elementSet.insert("date");
+  elementSet.insert("pages");
+  elementSet.insert("copyright");
+  elementSet.insert("handle"); 
+  elementSet.insert("other_access");
+  elementSet.insert("retrieval");
+  elementSet.insert("keyword"); 
+  elementSet.insert("cr-category");
+  elementSet.insert("period"); 
+  elementSet.insert("series"); 
+  elementSet.insert("monitoring");
+  elementSet.insert("funding");
+  elementSet.insert("contract");
+  elementSet.insert("grant");
+  elementSet.insert("language");
+  elementSet.insert("notes"); 
+  elementSet.insert("abstract");
+ 
+}; 
+
+const text_t rfc1807::formatName() 
+{
+  return "rfc1807";
+}
+
+const text_t rfc1807::formatPrefix() {
+  return "rfc1807";
+}
+
+bool rfc1807::output_record(ostream &output, recptproto *protocol, const text_t &collection, 
+			    const text_t &record_OID) 
+{
+  return metaformat::output_record(output, protocol, collection, record_OID);
+}
+
+void rfc1807::output_metadata_header(ostream &output)
+{
+  output << "<metadata>\n";
+  
+  if(this->oaiConfigure->getOAIVersion() <= 110){
+  // output rfc1807 wrapper for OAI v1.1
+    output << "<rfc1807 xmlns=\"http://info.internet.isi.edu:80/in-notes/rfc/files/rfc1807.txt\"" << endl;
+    output << "         xmlns:xsi=\"http://www.w3c.org/2001/XMLSchema-instance\"" << endl;
+    output << "         xsi:schemaLocation=\"http://info.internet.isi.edu:80/in-notes/rfc/files/rfc1807.txt" 
+	   << endl;
+    output << "                            http://www.openarchives.org/OAI/1.1/rfc1807.xsd\">" << endl;
+  }
+  else {
+    // TODO: output rfc1807 wrapper for OAI v2.0
+    output << "<rfc1807 xmlns=\"http://info.internet.isi.edu:80/in-notes/rfc/files/rfc1807.txt\"" << endl;
+    output << "         xmlns:xsi=\"http://www.w3c.org/2001/XMLSchema-instance\"" << endl;
+    output << "         xsi:schemaLocation=\"http://info.internet.isi.edu:80/in-notes/rfc/files/rfc1807.txt"
+	   << endl;
+    output << "                            http://www.openarchives.org/OAI/1.1/rfc1807.xsd\">" << endl;
+  } 
+}
+
+void rfc1807::output_metadata_footer(ostream &output)
+{
+  // end rfc1807 wrapper
+  output << "</rfc1807>" << endl;
+    
+  output << "</metadata>\n";
+}
+
+bool rfc1807::output_formatdata(ostream &output)
+{
+  // Both versions of the protocol use the same schema (yes?)
+  output << "    <metadataPrefix>rfc1807</metadataPrefix>" << endl;
+  output << "    <schema>http://www.openarchives.org/OAI/1.1/rfc1807.xsd</schema>" << endl;
+  // N.B.: no namespace for this format
+  output << "    <metadataNamespace></metadataNamespace>" << endl;
+
+  return true;
+}
+
+
Index: /gsdl/stable/runtime-src/src/oaiservr/rfc1807.h
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/rfc1807.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/rfc1807.h	(revision 20131)
@@ -0,0 +1,14 @@
+#include "metaformat.h"
+
+class rfc1807 : public metaformat {
+ protected:
+  void output_metadata_header(ostream &output);
+  virtual void output_metadata_footer(ostream &output);
+ public:
+  rfc1807(); 
+  virtual const text_t formatName();
+  virtual const text_t formatPrefix();
+  virtual bool output_record(ostream &output, recptproto *protocol, const text_t &collection, 
+			     const text_t &record_OID);
+  virtual bool output_formatdata(ostream &output);
+};
Index: /gsdl/stable/runtime-src/src/oaiservr/win32.mak
===================================================================
--- /gsdl/stable/runtime-src/src/oaiservr/win32.mak	(revision 20131)
+++ /gsdl/stable/runtime-src/src/oaiservr/win32.mak	(revision 20131)
@@ -0,0 +1,184 @@
+###########################################################################
+#
+# win32 makefile -- src/oaiserver
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ..\..\..
+COMMON_DIR = $(GSDL_DIR)\common-src
+RUNTIME_DIR = $(GSDL_DIR)\runtime-src
+
+INDEXERS_DIR = $(COMMON_DIR)\indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)\packages
+PACKAGES_DIR = $(RUNTIME_DIR)\packages
+COLSERVR_DIR = $(RUNTIME_DIR)\src\colservr
+PROTOCOL_DIR = $(RUNTIME_DIR)\src\protocol
+RECPT_DIR    = $(RUNTIME_DIR)\src\recpt
+
+
+GSDL_VC4 = 0
+DEBUG = 0
+LOCAL_LIBRARY = 0
+DLL = 0
+DLLDEBUG = 0
+ENABLE_ACCENTFOLD = 1
+USE_SQLITE = 1
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+!IF $(DLL)
+CXXFLAGS = $(CXXFLAGS) -MD
+!ELSE
+!IF ($(DLLDEBUG))
+CXXFLAGS = $(CXXFLAGS) -MDd
+!ENDIF
+!ENDIF
+
+!IF $(ENABLE_ACCENTFOLD)
+ACCENTFOLD_LIBS = "$(INDEXERS_DIR)\packages\unac\libunac.lib" "$(INDEXERS_DIR)\packages\windows\iconv\iconv\lib\iconv.lib"
+!ELSE
+ACCENTFOLD_LIBS = 
+!ENDIF
+
+!IF $(USE_SQLITE)
+SQLITE_LIBS = "$(COMMON_PACKAGES_DIR)\sqlite\lib\sqlite3.lib"
+!ELSE
+SQLITE_LIBS = 
+!ENDIF
+
+
+AR = lib
+CC = cl
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H -DPARADOCNUM -D_LITTLE_ENDIAN -DSHORT_SUFFIX -D_CRT_SECURE_NO_DEPRECATE \
+        -DGSDL_NOCACHE
+INCLUDES = -I"$(COMMON_DIR)\src\lib" -I"$(COLSERVR_DIR)" -I"$(PROTOCOL_DIR)" -I"$(RECPT_DIR)" \
+        -I"$(INDEXERS_DIR)\mgpp\text" -I"$(COMMON_PACKAGES_DIR)\windows\crypt\crypt" \
+	-I"$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3" -I"$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3\windows" \
+	-I"$(COMMON_PACKAGES_DIR)\windows\expat\expat"
+LDFLAGS = 
+LIBS = "$(COMMON_PACKAGES_DIR)\windows\crypt\crypt\crypt.lib" "$(COMMON_PACKAGES_DIR)\windows\expat\expat\libexpat.lib" \
+        "$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3\gdbm.lib" $(ACCENTFOLD_LIBS) $(SQLITE_LIBS)
+
+!IF $(GSDL_VC4)
+DEFS = $(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I"$(COMMON_PACKAGES_DIR)\windows\stlport\stlport"
+!ENDIF
+!IF $(LOCAL_LIBRARY)
+DEFS = $(DEFS) -DGSDL_LOCAL_LIBRARY
+!ENDIF
+
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) -nologo -Fe"$@" 
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $< 
+
+
+RECPT_OBJECTS = \
+	"$(RECPT_DIR)\cgiargs.obj" \
+	"$(RECPT_DIR)\cgiutils.obj" \
+	"$(RECPT_DIR)\htmlutils.obj"
+
+SOURCES = \
+	abstractlistaction.cpp \
+	dublincore.cpp \
+	qualified_dublincore.cpp \
+	identifyaction.cpp \
+	listidsaction.cpp \
+	listrecsaction.cpp \
+	listsetsaction.cpp \
+	metaformat.cpp \
+	metaformatsaction.cpp \
+	oaiaction.cpp \
+	oaiargs.cpp \
+	oaiconfig.cpp \
+	oaidispatcher.cpp \
+	oaimain.cpp \
+	oaitools.cpp \
+	recordaction.cpp \
+	resumptiontoken.cpp \
+	rfc1807.cpp
+
+OBJECTS = \
+	abstractlistaction.obj \
+	dublincore.obj \
+	qualified_dublincore.obj \
+	identifyaction.obj \
+	listidsaction.obj \
+	listrecsaction.obj \
+	listsetsaction.obj \
+	metaformat.obj \
+	metaformatsaction.obj \
+	oaiaction.obj \
+	oaiargs.obj \
+	oaiconfig.obj \
+	oaidispatcher.obj \
+	oaimain.obj \
+	oaitools.obj \
+	recordaction.obj \
+	resumptiontoken.obj \
+	rfc1807.obj
+
+GSDL_LIBS = \
+	"$(PROTOCOL_DIR)\gsdlprotocol.lib" \
+	"$(COLSERVR_DIR)\gsdlcolservr.lib" \
+	"$(INDEXERS_DIR)\mg\src\text\libmgtext.lib" \
+	"$(INDEXERS_DIR)\mg\lib\libmglib.lib" \
+	"$(INDEXERS_DIR)\mgpp\text\libmgpptext.lib" \
+	"$(INDEXERS_DIR)\mgpp\lib\libmgpplib.lib" \
+	"$(COMMON_DIR)\src\lib\gsdllib.lib"
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS) \
+	$(RECPT_OBJECTS) \
+	$(GSDL_LIBS)
+
+EXECUTABLE = oaiserver.cgi
+
+
+# Default target: make the oaiserver executable
+all: $(EXECUTABLE)
+
+oaiserver.cgi: $(EXECUTABLE_OBJECTS)
+	$(LINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	copy $(EXECUTABLE) "$(GSDL_DIR)\cgi-bin"
+
+clean:
+	del *.obj
+	del $(EXECUTABLE)
Index: /gsdl/stable/runtime-src/src/protocol/Makefile.in
===================================================================
--- /gsdl/stable/runtime-src/src/protocol/Makefile.in	(revision 20131)
+++ /gsdl/stable/runtime-src/src/protocol/Makefile.in	(revision 20131)
@@ -0,0 +1,85 @@
+###########################################################################
+#
+# Makefile -- runtime-src/src/protocol
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+RUNTIME_DIR = $(GSDL_DIR)/runtime-src
+
+INDEXERS_DIR = $(COMMON_DIR)/indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+COLSERVR_DIR = $(RUNTIME_DIR)/src/colservr
+
+
+AR = ar
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@ -DNZDL -DQUIET -DSHORT_SUFFIX -DPARADOCNUM -DGSDLSERVER
+# Do NOT add the "recpt" directory here: the protocol should be independent of the receptionist!
+INCLUDES = -I. -I$(GSDL_DIR) -I$(COMMON_DIR)/src/lib -I$(COMMON_PACKAGES_DIR)/gdbm/include \
+	-I$(COLSERVR_DIR) -I$(INDEXERS_DIR)/mgpp/text
+RANLIB = @RANLIB@
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+SOURCES = \
+	nullproto.cpp \
+	recptproto.cpp \
+	recptprototools.cpp
+
+OBJECTS = \
+	nullproto.o \
+	recptproto.o \
+	recptprototools.o
+
+LIBRARY = gsdlprotocol.a
+
+
+# Default target: make gsdlprotocol.a
+all: $(LIBRARY)
+
+gsdlprotocol.a: $(OBJECTS)
+	rm -f $(LIBRARY)
+	$(AR) cru $(LIBRARY) $(OBJECTS)
+	$(RANLIB) $(LIBRARY)
+
+install:
+
+clean:
+	rm -f $(OBJECTS) $(LIBRARY)
+
+distclean:
+	rm -f $(OBJECTS) $(LIBRARY) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/runtime-src/src/protocol/nullproto.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/protocol/nullproto.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/protocol/nullproto.cpp	(revision 20131)
@@ -0,0 +1,164 @@
+/**********************************************************************
+ *
+ * nullproto.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "nullproto.h"
+#include <assert.h>
+
+#include "filter.h"
+#include "browsefilter.h"
+#include "mgqueryfilter.h"
+#include "mgppqueryfilter.h"
+#include "mgsearch.h"
+#include "mgppsearch.h"
+#include "fileutil.h"
+
+nullproto::nullproto() {
+  cset = NULL;
+}
+
+nullproto::~nullproto() {
+}
+
+// add collection to collectset (this should not be called until after the
+// collectset has been added to the protocol with set_collectset()
+void nullproto::add_collection (const text_t &collection, void *recpt, 
+				const text_t &gsdlhome, const text_t& collecthome,
+				const text_t &dbhome) 
+{      
+  
+  if (cset != NULL) {
+    this->cset->add_collection (collection, gsdlhome, collecthome);
+  }
+}
+
+
+// remove_collection deletes the collection server of collection.
+// This only needs to be called if a collectionserver is to be
+// removed while the library is running. The destructor function
+// cleans up all collectservers when the program exits.
+void nullproto::remove_collection (const text_t &collection, ostream &logout) {
+  cset->remove_collection(collection, logout);
+}
+
+// this configure will configure each of the collection servers
+void nullproto::configure (const text_t &key, const text_tarray &cfgline,
+			   comerror_t &err) {
+  // the naming of the collection should not be done here,
+  // it should be done just after the collection server has been 
+  // created
+
+  // the protocol should not configure the collection set; it should be
+  // done direct to the collection server set
+  if (key == "gsdlhome" || key == "gdbmhome"
+      || key == "collecthome" || key == "collectdir") {
+    cset->configure(key, cfgline);
+  }
+}
+
+// this init will configure and init each of the collection servers
+bool nullproto::init (comerror_t &err, ostream &logout) {
+  return cset->init(logout);
+}
+
+text_t nullproto::get_site_name (comerror_t &err) {
+  return "localhost";
+}
+
+text_t nullproto::get_protocol_name (comerror_t &err) {
+  return "nullproto";
+}
+
+
+void nullproto::get_collection_list (text_tarray &collist, comerror_t &err, 
+				     ostream &/*logout*/) {
+  cset->getCollectionList(collist);
+  err = noError; // no error is guaranteed - collection server shouldn't
+                 // about receptionist error states, logout is irrelevant
+}
+
+void nullproto::has_collection (const text_t &collection, bool &hascollection, 
+				comerror_t &err, ostream &/*logout*/) {
+  hascollection = (cset->getCollectServer(collection) != NULL);
+  err = noError;
+}
+
+void nullproto::ping (const text_t &collection, bool &wassuccess, 
+		      comerror_t &err, ostream &logout) {
+  collectserver *cserver = cset->getCollectServer(collection);
+  if (cserver != NULL) cserver->ping(wassuccess, err, logout);
+  else err = protocolError;
+}
+
+void nullproto::get_collectinfo (const text_t &collection, 
+				 ColInfoResponse_t &collectinfo,
+				 comerror_t &err, ostream &logout) {
+  collectserver *cserver = cset->getCollectServer (collection);
+  if (cserver != NULL) cserver->get_collectinfo (collectinfo, err, logout);
+  else err = protocolError;
+}
+
+
+void nullproto::get_filterinfo (const text_t &collection,
+				InfoFiltersResponse_t &response,
+				comerror_t &err, ostream &logout) {
+  collectserver *cserver = cset->getCollectServer (collection);
+  if (cserver != NULL) cserver->get_filterinfo (response, err, logout);
+  else err = protocolError;
+}
+
+void nullproto::get_filteroptions (const text_t &collection,
+				   const InfoFilterOptionsRequest_t &request,
+				   InfoFilterOptionsResponse_t &response, 
+				   comerror_t &err, ostream &logout) {
+  collectserver *cserver = cset->getCollectServer (collection);
+  if (cserver != NULL) cserver->get_filteroptions (request, response, err, logout);
+  else err = protocolError;
+}
+
+void nullproto::filter (const text_t &collection,
+			FilterRequest_t &request,
+			FilterResponse_t &response,
+			comerror_t &err, ostream &logout) {
+  collectserver *cserver = cset->getCollectServer (collection);
+  if (cserver != NULL) cserver->filter (request, response, err, logout);
+  else err = protocolError;
+}
+
+void nullproto::get_document (const text_t &collection,
+			      const DocumentRequest_t &request,
+			      DocumentResponse_t &response,
+			      comerror_t &err, ostream &logout) {
+  collectserver *cserver = cset->getCollectServer (collection);
+  if (cserver != NULL) cserver->get_document (request, response, err, logout);
+  else err = protocolError;
+}
+
+void nullproto::is_searchable (const text_t &collection, bool &issearchable, 
+			       comerror_t &err, ostream &logout) {
+  issearchable = false;
+  collectserver *cserver = cset->getCollectServer (collection);
+  if (cserver != NULL) cserver->is_searchable (issearchable, err, logout);
+  else err = protocolError;
+}
Index: /gsdl/stable/runtime-src/src/protocol/nullproto.h
===================================================================
--- /gsdl/stable/runtime-src/src/protocol/nullproto.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/protocol/nullproto.h	(revision 20131)
@@ -0,0 +1,100 @@
+/**********************************************************************
+ *
+ * nullproto.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef NULLPROTO_H
+#define NULLPROTO_H
+
+#include "gsdlconf.h"
+#include "collectserver.h"
+#include "collectset.h"
+#include "recptproto.h"
+
+
+class nullproto : public recptproto {
+protected:
+  collectset           *cset;
+public:
+  nullproto();
+  virtual ~nullproto();
+
+  // add_collection sets up the collectionserver and calls
+  // add_collectserver
+  virtual void add_collection (const text_t &collection, void *recpt, 
+			       const text_t &gsdlhome, const text_t& collecthome,
+			       const text_t &dbhome);
+
+  void set_collectset(collectset *set) { this->cset = set; }
+
+  // remove_collection deletes the collection server of collection.
+  // This only needs to be called if a collectionserver is to be
+  // removed while the library is running as the destructor function
+  // cleans up all collectservers when the program exits.
+  void remove_collection (const text_t &collection, ostream &logout);
+
+  // this configure will configure each of the collection servers
+  void configure (const text_t &key, const text_tarray &cfgline,
+		  comerror_t &err);
+
+  // this init will init each of the collection servers
+  bool init (comerror_t &err, ostream &logout);
+
+  text_t get_protocol_name (comerror_t &err);
+  text_t get_site_name (comerror_t &err);
+
+  void get_collection_list (text_tarray &collist, comerror_t &err, 
+			    ostream &logout);
+  void has_collection (const text_t &collection, bool &hascollection, 
+		       comerror_t &err, ostream &logout);
+  void ping (const text_t &collection, bool &wassuccess, 
+	     comerror_t &err, ostream &logout);
+  void get_collectinfo (const text_t &collection, 
+			ColInfoResponse_t &collectinfo,
+			comerror_t &err, ostream &logout);
+  void get_filterinfo (const text_t &collection,
+		       InfoFiltersResponse_t &response,
+		       comerror_t &err, ostream &logout);
+  void get_filteroptions (const text_t &collection,
+			  const InfoFilterOptionsRequest_t &request,
+			  InfoFilterOptionsResponse_t &response, 
+			  comerror_t &err, ostream &logout);
+  void filter (const text_t &collection,
+	       FilterRequest_t &request,
+	       FilterResponse_t &response,
+	       comerror_t &err, ostream &logout);
+
+  void get_document (const text_t &collection,
+		     const DocumentRequest_t &request,
+		     DocumentResponse_t &response,
+		     comerror_t &err, ostream &logout);
+
+  void is_searchable (const text_t &collection, bool &issearchable, 
+		      comerror_t &err, ostream &logout);
+
+
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/protocol/recptproto.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/protocol/recptproto.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/protocol/recptproto.cpp	(revision 20131)
@@ -0,0 +1,176 @@
+/**********************************************************************
+ *
+ * recptproto.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "recptproto.h"
+#include <assert.h>
+
+
+// add collection server to protocol
+void recptproto::add_collection (const text_t &/*collection*/, void * /*recpt*/, 
+				 const text_t &/*gsdlhome*/, const text_t& /*collecthome */, 
+				 const text_t &/*dbhome*/) 
+{
+}
+
+void recptproto::remove_collection (const text_t &/*collection*/, ostream &/*logout*/) {
+}
+
+// configure should be called for each line in the configuration file
+void recptproto::configure (const text_t &/*key*/, const text_tarray &/*cfgline*/, comerror_t &) {
+}
+
+// init should be called after the configuration but before any other
+// functions are called. If init returns false a message will be written
+// out to the log file and no other output should be produced.
+bool recptproto::init (comerror_t &err, ostream &/*logout*/) {
+  return true;
+}
+
+// get site name should return the name of the site used.
+// This is trivially empty in the case of a null protocol.  If a remote
+// connection to a site is being used then this should return the name
+// used to label a site
+text_t recptproto::get_site_name(comerror_t &err) {
+  return "localhost";
+}
+
+// get_protocol_name should return the name of this protocol (e.g. recptproto)
+// that can be used to do run time type identification and display information
+// about the protocol.
+text_t recptproto::get_protocol_name (comerror_t &err) {
+  return "recptproto";
+}
+
+// get_collection_list returns the list of collections that
+// this protocol knows about
+void recptproto::get_collection_list (text_tarray &collist, comerror_t &err, 
+				      ostream &/*logout*/) {
+  collist.erase(collist.begin(),collist.end());
+  err = noError;
+}
+
+// has_collection sets 'hascollection' to be true if the protocol
+// can communicate with the collection (i.e. it is within its 
+// collection list). This function should be implemented in as
+// efficient time as possible as it will be called for each page
+// access and for each protocol.
+void recptproto::has_collection (const text_t &/*collection*/, bool &hascollection, 
+				 comerror_t &err, ostream &/*logout*/) {
+  hascollection = false;
+  err = noError;
+}
+
+// sets 'wassuccess' to be true if a successful ping was done to
+// the given collection.
+void recptproto::ping (const text_t &/*collection*/, bool &wassuccess, 
+		       comerror_t &err, ostream &/*logout*/) {
+  wassuccess = false; // no collections are supported by this class
+  err = noError;
+}
+
+// obtains general information about the collection
+void recptproto::get_collectinfo (const text_t &/*collection*/, 
+				  ColInfoResponse_t &/*collectinfo*/,
+				  comerror_t &err, ostream &/*logout*/) {
+  err = protocolError;
+}
+
+// gets a list of all the filters
+void recptproto::get_filterinfo (const text_t &/*collection*/,
+				 InfoFiltersResponse_t &/*reponse*/,
+				 comerror_t &err, ostream &/*logout*/) {
+  err = protocolError;
+}
+
+// gets all the filter options for a particular filter
+void recptproto::get_filteroptions (const text_t &/*collection*/,
+				    const InfoFilterOptionsRequest_t &/*request*/,
+				    InfoFilterOptionsResponse_t &/*response*/, 
+				    comerror_t &err, ostream &/*logout*/) {
+  err = protocolError;
+}
+
+// filters (search or browse) a result set
+void recptproto::filter (const text_t &/*collection*/,
+			 FilterRequest_t &/*request*/,
+			 FilterResponse_t &/*response*/,
+			 comerror_t &err, ostream &/*logout*/) {
+  err = protocolError;
+}
+
+void recptproto::get_document (const text_t &/*collection*/,
+			       const DocumentRequest_t &/*request*/,
+			       DocumentResponse_t &/*response*/,
+			       comerror_t &err, ostream &/*logout*/) {
+  err = protocolError;
+}
+
+// sets issearchable to true if the given colection is searchable
+void recptproto::is_searchable (const text_t &/*collection*/, bool &issearchable, 
+				comerror_t &err, ostream &/*logout*/) {
+  issearchable = false; // no collections are supported by this class
+  err = noError;
+}
+
+
+
+
+
+
+
+// therecptproto remains the property of the calling code but
+// should not be deleted until it is removed from this list.
+void recptprotolistclass::addrecptproto (recptproto *therecptproto) {
+  // can't add a protocol that doesn't exist
+  assert (therecptproto != NULL);
+  if (therecptproto == NULL) return;
+
+  recptprotoptr rpp;
+  rpp.p = therecptproto;
+
+  recptprotoptrs.push_back(rpp);
+}
+
+// getrecptproto will return NULL if a recptproto for the given colelction
+// could not be found
+recptproto *recptprotolistclass::getrecptproto (const text_t &collection, 
+						ostream &logout) {
+  iterator here = recptprotoptrs.begin ();
+  iterator end = recptprotoptrs.end ();
+  bool hascollection;
+  comerror_t err;
+
+  while (here != end) {
+    assert ((*here).p != NULL);
+    if ((*here).p != NULL) {
+      (*here).p->has_collection (collection, hascollection, err, logout);
+      if ((err == noError) && (hascollection == true)) return (*here).p;
+    }
+    
+    ++here;
+  }
+  
+  return NULL;
+}
Index: /gsdl/stable/runtime-src/src/protocol/recptproto.h
===================================================================
--- /gsdl/stable/runtime-src/src/protocol/recptproto.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/protocol/recptproto.h	(revision 20131)
@@ -0,0 +1,194 @@
+/**********************************************************************
+ *
+ * recptproto.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef RECPTPROTO_H
+#define RECPTPROTO_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "comtypes.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\vector>
+#elif defined(GSDL_USE_STL_H)
+#  include <vector.h>
+#else
+#  include <vector>
+#endif
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+#endif
+
+
+// recptproto is a generalisation of a protocol for communicating
+// with a collection server.
+class recptproto {
+public:
+
+  // add collection server to protocol
+  virtual void add_collection (const text_t &collection, void *recpt, 
+			       const text_t &gsdlhome, const text_t& collecthome,
+			       const text_t &dbhome);
+
+  virtual void remove_collection (const text_t &collection, ostream &logout);
+
+  // configure should be called for each line in the configuration file
+  virtual void configure (const text_t &key, const text_tarray &cfgline, comerror_t &err);
+
+  // init should be called after the configuration but before any other
+  // functions are called. If init returns false a message will be written
+  // out to the log file and no other output should be produced.
+  virtual bool init (comerror_t &err, ostream &logout);
+
+  // get_site_name should return the name of the site used.
+  // This is trivially empty in the case of a null protocol.  If a remote
+  // connection to a site is being used then this should return the name
+  // used to label a site
+  virtual text_t get_site_name(comerror_t &err);
+
+  // get_protocol_name should return the name of this protocol (e.g. recptproto)
+  // that can be used to do run time type identification and display information
+  // about the protocol.
+  virtual text_t get_protocol_name (comerror_t &err);
+
+  // get_collection_list returns the list of collections that
+  // this protocol knows about
+  virtual void get_collection_list (text_tarray &collist, comerror_t &err, 
+				    ostream &logout);
+
+  // has_collection sets 'hascollection' to be true if the protocol
+  // can communicate with the collection (i.e. it is within its 
+  // collection list). This function should be implemented in as
+  // efficient time as possible as it will be called for each page
+  // access and for each protocol.
+  virtual void has_collection (const text_t &collection, bool &hascollection, 
+			       comerror_t &err, ostream &logout);
+
+  // sets 'wassuccess' to be true if a successful ping was done to
+  // the given collection.
+  virtual void ping (const text_t &collection, bool &wassuccess, 
+		     comerror_t &err, ostream &logout);
+
+  // obtains general information about the collection
+  virtual void get_collectinfo (const text_t &collection, 
+				ColInfoResponse_t &collectinfo,
+				comerror_t &err, ostream &logout);
+
+  // gets a list of all the filters
+  virtual void get_filterinfo (const text_t &collection,
+			       InfoFiltersResponse_t &response,
+			       comerror_t &err, ostream &logout);
+
+  // gets all the filter options for a particular filter
+  virtual void get_filteroptions (const text_t &collection,
+				  const InfoFilterOptionsRequest_t &request,
+				  InfoFilterOptionsResponse_t &response, 
+				  comerror_t &err, ostream &logout);
+
+  // filters (search or browse) a result set and returns information
+  // about the filtered set including term frequency information and 
+  // metadata
+  virtual void filter (const text_t &collection,
+		       FilterRequest_t &request,
+		       FilterResponse_t &response,
+		       comerror_t &err, ostream &logout);
+
+  // gets a document (duh!)
+  virtual void get_document (const text_t &collection,
+			     const DocumentRequest_t &request,
+			     DocumentResponse_t &response,
+			     comerror_t &err, ostream &logout);
+
+  virtual void is_searchable (const text_t &collection, bool &issearchable, 
+			      comerror_t &err, ostream &logout);
+
+};
+
+
+// The recptprotoptr function does not 'own' the recptproto. The 
+// recptproto should be deleted by the code which created it.
+class recptprotoptr {
+public:
+  recptproto *p;
+
+  recptprotoptr () {p=NULL;}
+  ~recptprotoptr () {}
+};
+
+typedef vector<recptprotoptr> recptprotoptrlist;
+
+
+// contains a list of recptprotos
+class recptprotolistclass {
+protected:
+  recptprotoptrlist recptprotoptrs;
+
+public:
+  // type support for recptprotolistclass
+  typedef recptprotoptrlist::iterator iterator;
+  typedef recptprotoptrlist::const_iterator const_iterator;
+  typedef recptprotoptrlist::reference reference;
+  typedef recptprotoptrlist::const_reference const_reference;
+  typedef recptprotoptrlist::size_type size_type;
+
+  typedef recptprotoptrlist::difference_type difference_type;
+  typedef recptprotoptrlist::const_reverse_iterator const_reverse_iterator;
+  typedef recptprotoptrlist::reverse_iterator reverse_iterator;
+  
+  // basic container support
+  iterator begin () {return recptprotoptrs.begin();}
+  const_iterator begin () const {return recptprotoptrs.begin();}
+  iterator end () {return recptprotoptrs.end();}
+  const_iterator end () const {return recptprotoptrs.end();}
+
+  void erase(iterator pos) {recptprotoptrs.erase(pos);}
+  void erase(iterator first, iterator last) {recptprotoptrs.erase(first, last);}
+  recptprotolistclass &operator=(const recptprotolistclass &x) 
+    {recptprotoptrs=x.recptprotoptrs;return *this;}
+
+  bool empty () const {return recptprotoptrs.empty();}
+  size_type size() const {return recptprotoptrs.size();}
+
+
+  // added functionality
+  void clear () {recptprotoptrs.erase(recptprotoptrs.begin(),recptprotoptrs.end());}
+
+  // therecptproto remains the property of the calling code but
+  // should not be deleted until it is removed from this list.
+  void addrecptproto (recptproto *therecptproto);
+
+  // getrecptproto will return NULL if a recptproto for the given collection
+  // could not be found
+  recptproto *getrecptproto (const text_t &collection, ostream &logout);
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/protocol/recptprototools.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/protocol/recptprototools.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/protocol/recptprototools.cpp	(revision 20131)
@@ -0,0 +1,330 @@
+/**********************************************************************
+ *
+ * recptprototools.cpp -- 
+ * Copyright (C) 1999-2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "recptprototools.h"
+#include <assert.h>
+
+
+// get_info does a protocol call and returns (in response) the metadata 
+// associated with OID. Metadata should be loaded with whatever
+// metadata fields are to be requested.
+
+bool get_info (const text_t &OID, const text_t &collection, const text_t &lang,
+	       const text_tset &metadata, bool getParents,
+	       recptproto *collectproto, FilterResponse_t &response, 
+	       ostream &logout)
+{
+  response.clear();
+
+  comerror_t err = noError;
+  FilterRequest_t request;
+  request.clear();
+
+  request.filterName = "NullFilter";
+  request.filterLang = lang;
+  request.filterResultOptions = FRmetadata;
+  request.getParents = getParents;
+  request.fields = metadata;
+  request.docSet.push_back (OID);
+  assert (collectproto != NULL);
+
+  collectproto->filter (collection, request, response, err, logout);
+  if (err != noError)
+  {
+    outconvertclass text_t2ascii;
+    logout << text_t2ascii
+	   << "Error: call to filter failed for " << OID
+	   << " in recptprototools::get_info (" 
+	   << get_comerror_string (err) << ")\n";
+    return false;
+  }
+  
+  return true;
+}
+
+
+// overloaded, to allow "custom" filter options.
+bool get_info (const text_t &OID, const text_t &collection, const text_t &lang,
+	       const text_tset &metadata, const OptionValue_tarray &options,
+	       bool getParents,
+	       recptproto *collectproto, FilterResponse_t &response, 
+	       ostream &logout)
+{
+  response.clear();
+
+  comerror_t err = noError;
+  FilterRequest_t request;
+
+  request.filterName = "NullFilter";
+  request.filterLang = lang;
+  request.filterResultOptions = FRmetadata;
+  request.getParents = getParents;
+  request.filterOptions = options;
+  request.fields = metadata;
+  request.docSet.push_back (OID);
+
+  assert (collectproto != NULL);
+  collectproto->filter (collection, request, response, err, logout);
+  if (err != noError)
+  {
+    outconvertclass text_t2ascii;
+    logout << text_t2ascii
+	   << "Error: call to filter failed for " << OID
+	   << " in recptprototools::get_info (" 
+	   << get_comerror_string (err) << ")\n";
+    return false;
+  }
+  
+  return true;
+}
+
+
+bool get_info (const text_tarray &OIDs, const text_t &collection, const text_t &lang,
+	       const text_tset &metadata, bool getParents,
+	       recptproto *collectproto, FilterResponse_t &response, 
+	       ostream &logout)
+{
+  response.clear();
+  if (OIDs.empty()) return true;
+
+  comerror_t err = noError;
+  FilterRequest_t request;
+
+  request.filterName = "NullFilter";
+  request.filterLang = lang;
+  request.filterResultOptions = FRmetadata;
+  request.getParents = getParents;
+  request.fields = metadata;
+
+  request.docSet = OIDs;
+  
+  collectproto->filter (collection, request, response, err, logout);
+  if (err != noError)
+  {
+    outconvertclass text_t2ascii;
+    logout << text_t2ascii
+	   << "Error: call to filter failed in recptprototools::get_info (" 
+	   << get_comerror_string (err) << ")\n";
+    return false;
+  }
+
+  return true;
+}
+
+
+// has_children returns true if OID has children
+bool has_children (const text_t &OID, const text_t &collection, const text_t &lang,
+		   recptproto *collectproto, ostream &logout) {
+
+  FilterResponse_t response;
+  text_tset metadata;
+  metadata.insert ("haschildren");
+
+  if (get_info (OID, collection, lang, metadata, false, collectproto,	response, logout))
+  {
+    if (response.docInfo[0].metadata["haschildren"].values[0] == "1")
+    {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+
+// get_children does a protocol call and returns (in response) the OIDs and 
+// metadata of all the children of OID. The metadata set should be loaded
+// with whatever metadata fields are to be requested.
+
+bool get_children (const text_t &OID, const text_t &collection, const text_t &lang,
+		   const text_tset &metadata, bool getParents,
+		   recptproto *collectproto, FilterResponse_t &response, 
+		   ostream &logout)
+{
+  response.clear();
+
+  comerror_t err = noError;
+  FilterRequest_t request;
+  OptionValue_t option;
+
+  option.name = "ParentNode";
+  option.value = OID;
+  request.filterOptions.push_back (option);
+  request.filterName = "BrowseFilter";
+  request.filterLang = lang;
+  request.filterResultOptions = FROID;
+
+  // Efficiency improvement: only get the filter to retrieve metadata if some has been requested
+  // Otherwise, the filter makes an unnecessary request to the database for each child node
+  // By Michael Dewsnip, DL Consulting Ltd
+  if (metadata.size() > 0)
+  {
+    request.filterResultOptions |= FRmetadata;
+  }
+
+  request.fields = metadata;
+  request.getParents = getParents;
+
+  collectproto->filter (collection, request, response, err, logout);
+
+  if (err != noError)
+  {
+    outconvertclass text_t2ascii;
+    logout << text_t2ascii
+	   << "Error: call to filter failed for " << OID 
+	   << " in recptprototools::get_children (" 
+	   << get_comerror_string (err) << ")\n";
+    return false;
+  }
+
+  return true;
+}
+
+
+static void recurse_contents (ResultDocInfo_t section, const bool &is_classify, 
+			      const text_t &collection, const text_t &lang,
+			      const text_tset &metadata, 
+			      recptproto *collectproto, FilterResponse_t &response, 
+			      ostream &logout)
+{
+  int haschildren = section.metadata["haschildren"].values[0].getint();
+  const text_t &doctype = section.metadata["doctype"].values[0];
+
+  if ((haschildren == 1) && ((!is_classify) || (doctype == "classify")))
+  {
+    FilterResponse_t tmp;
+    bool getParents = false;
+    get_children (section.OID, collection, lang, metadata, getParents, collectproto, tmp, logout);
+    ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
+    ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
+    while (thisdoc != lastdoc)
+    {
+      response.docInfo.push_back (*thisdoc);
+      recurse_contents (*thisdoc, is_classify, collection, lang, metadata, collectproto, response, logout);
+      ++thisdoc;
+    }
+  }
+}
+
+
+// get_contents returns OIDs and metadata of all contents 
+// below (and including) OID.
+void get_contents (const text_t &topOID, const bool &is_classify, 
+		   text_tset &metadata, const text_t &collection, const text_t &lang,
+		   recptproto *collectproto, FilterResponse_t &response, 
+		   ostream &logout)
+{
+  if (topOID.empty()) return;
+  response.clear();
+
+  metadata.insert ("haschildren");
+  metadata.insert ("doctype");
+
+  // get topOIDs info
+  if (get_info (topOID, collection, lang, metadata, false, collectproto, response, logout))
+  {
+    recurse_contents (response.docInfo[0], is_classify, collection, lang, metadata, collectproto, response, logout);
+  }
+}
+
+
+bool get_metadata_values (const text_t metadata_elements, const text_t metadata_value_filter,
+			  const text_t metadata_value_grouping_expression, const text_t &collection,
+			  recptproto *collectproto, FilterResponse_t &response, ostream &logout)
+{
+  response.clear();
+
+  comerror_t err = noError;
+  FilterRequest_t request;
+  request.clear();
+
+  request.filterName = "SQLBrowseFilter";
+  request.requestParams = "GetMetadataValues";
+
+  OptionValue_t request_option;
+  request_option.name = "MetadataElements";
+  request_option.value = metadata_elements;
+  request.filterOptions.push_back (request_option);
+  request_option.name = "MetadataValueFilter";
+  request_option.value = metadata_value_filter;
+  request.filterOptions.push_back (request_option);
+  request_option.name = "MetadataValueGroupingExpression";
+  request_option.value = metadata_value_grouping_expression;
+  request.filterOptions.push_back (request_option);
+
+  assert (collectproto != NULL);
+  collectproto->filter (collection, request, response, err, logout);
+  if (err != noError)
+  {
+    outconvertclass text_t2ascii;
+    logout << text_t2ascii
+	   << "Error: call to filter failed for " << metadata_elements
+	   << " in recptprototools::get_metadata_values (" 
+	   << get_comerror_string (err) << ")\n";
+    return false;
+  }
+  
+  return true;
+}
+
+
+bool get_documents_with_metadata_value (const text_t metadata_elements, const text_t metadata_value,
+					const text_t sort_by_metadata_element_name, const text_t &collection,
+					recptproto *collectproto, FilterResponse_t &response, ostream &logout)
+{
+  response.clear();
+
+  comerror_t err = noError;
+  FilterRequest_t request;
+  request.clear();
+
+  request.filterName = "SQLBrowseFilter";
+  request.requestParams = "GetDocumentsWithMetadataValue";
+
+  OptionValue_t request_option;
+  request_option.name = "MetadataElements";
+  request_option.value = metadata_elements;
+  request.filterOptions.push_back (request_option);
+  request_option.name = "MetadataValue";
+  request_option.value = metadata_value;
+  request.filterOptions.push_back (request_option);
+  request_option.name = "SortByMetadataElement";
+  request_option.value = sort_by_metadata_element_name;
+  request.filterOptions.push_back (request_option);
+
+  assert (collectproto != NULL);
+  collectproto->filter (collection, request, response, err, logout);
+  if (err != noError)
+  {
+    outconvertclass text_t2ascii;
+    logout << text_t2ascii
+	   << "Error: call to filter failed for " << metadata_elements << " = " << metadata_value
+	   << " in recptprototools::get_documents_with_metadata_value (" 
+	   << get_comerror_string (err) << ")\n";
+    return false;
+  }
+  
+  return true;
+}
Index: /gsdl/stable/runtime-src/src/protocol/recptprototools.h
===================================================================
--- /gsdl/stable/runtime-src/src/protocol/recptprototools.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/protocol/recptprototools.h	(revision 20131)
@@ -0,0 +1,78 @@
+/**********************************************************************
+ *
+ * recptprototools.h -- 
+ * Copyright (C) 1999-2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef RECPTPROTOTOOLS_H
+#define RECPTPROTOTOOLS_H
+
+
+#include "text_t.h"
+#include "recptproto.h"
+
+
+// get_info does a protocol call and returns (in response) the info 
+// associated with OID. Metadata should be loaded with whatever
+// metadata fields are to be requested
+bool get_info (const text_t &OID, const text_t &collection, const text_t &lang,
+	       const text_tset &metadata, bool getParents,
+	       recptproto *collectproto, FilterResponse_t &response, 
+	       ostream &logout);
+bool get_info (const text_t &OID, const text_t &collection, const text_t &lang,
+	       const text_tset &metadata, const OptionValue_tarray &options,
+	       bool getParents,
+	       recptproto *collectproto, FilterResponse_t &response, 
+	       ostream &logout);
+bool get_info (const text_tarray &OIDs, const text_t &collection, const text_t &lang,
+	       const text_tset &metadata, bool getParents,
+	       recptproto *collectproto, FilterResponse_t &response, 
+	       ostream &logout);
+
+// has_children returns true if OID has children
+bool has_children (const text_t &OID, const text_t &collection, const text_t &lang, 
+		   recptproto *collectproto, ostream &logout);
+
+// get_children does a protocol call and returns (in response) the OIDs and 
+// metadata of all the children of OID. The metadata set should be loaded
+// with whatever metadata fields are to be requested.
+bool get_children (const text_t &OID, const text_t &collection, const text_t &lang, 
+		   const text_tset &metadata, bool getParents,
+		   recptproto *collectproto, FilterResponse_t &response, 
+		   ostream &logout);
+
+// get_contents returns OIDs and metadata of all contents 
+// below (and including) OID.
+void get_contents (const text_t &topOID, const bool &is_classify, 
+		   text_tset &metadata, const text_t &collection, const text_t &lang, 
+		   recptproto *collectproto, FilterResponse_t &response, 
+		   ostream &logout);
+
+bool get_metadata_values (const text_t metadata_elements, const text_t metadata_value_filter,
+			  const text_t metadata_value_grouping_expression, const text_t &collection,
+			  recptproto *collectproto, FilterResponse_t &response, ostream &logout);
+
+bool get_documents_with_metadata_value (const text_t metadata_elements, const text_t metadata_value,
+					const text_t sort_by_metadata_element_name, const text_t &collection,
+					recptproto *collectproto, FilterResponse_t &response, ostream &logout);
+
+#endif
Index: /gsdl/stable/runtime-src/src/protocol/win32.mak
===================================================================
--- /gsdl/stable/runtime-src/src/protocol/win32.mak	(revision 20131)
+++ /gsdl/stable/runtime-src/src/protocol/win32.mak	(revision 20131)
@@ -0,0 +1,108 @@
+###########################################################################
+#
+# win32 makefile -- src/protocol
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ..\..\..
+COMMON_DIR = $(GSDL_DIR)\common-src
+RUNTIME_DIR = $(GSDL_DIR)\runtime-src
+
+INDEXERS_DIR = $(COMMON_DIR)\indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)\packages
+COLSERVR_DIR = $(RUNTIME_DIR)\src\colservr
+
+
+GSDL_VC4 = 0
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+!IF $(DLL)
+CXXFLAGS = $(CXXFLAGS) -MD
+!ELSE
+!IF ($(DLLDEBUG))
+CXXFLAGS = $(CXXFLAGS) -MDd
+!ENDIF
+!ENDIF
+
+
+AR = lib
+CC = cl
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H -DPARADOCNUM -D_LITTLE_ENDIAN -DSHORT_SUFFIX -D_CRT_SECURE_NO_DEPRECATE
+# Do NOT add the "recpt" directory here: the protocol should be independent of the receptionist!
+INCLUDES = -I"$(GSDL_DIR)" -I"$(COMMON_DIR)\src\lib" -I"$(COLSERVR_DIR)" -I"$(INDEXERS_DIR)\mgpp\text" \
+	 -I"$(COMMON_PACKAGES_DIR)\windows\gdbm\gdbm"
+
+!IF $(GSDL_VC4)
+DEFS=$(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I"$(COMMON_PACKAGES_DIR)\windows\stlport\stlport"
+!ENDIF
+
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $< 
+
+
+SOURCES = \
+	nullproto.cpp \
+	recptproto.cpp \
+	recptprototools.cpp
+
+OBJECTS = \
+	nullproto.obj \
+	recptproto.obj \
+	recptprototools.obj
+
+LIBRARY = gsdlprotocol.lib	
+	
+
+# Default target: make gsdlprotocol.lib
+all: $(LIBRARY)
+
+gsdlprotocol.lib: $(OBJECTS) 
+	if EXIST $(LIBRARY) del $(LIBRARY)
+	$(AR) -nologo /out:$(LIBRARY) $(OBJECTS)
+
+install:
+
+clean:
+	del *.obj
+	del $(LIBRARY)
Index: /gsdl/stable/runtime-src/src/recpt/Makefile.in
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/Makefile.in	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/Makefile.in	(revision 20131)
@@ -0,0 +1,265 @@
+###########################################################################
+#
+# Makefile -- runtime-src/src/recpt
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+RUNTIME_DIR = $(GSDL_DIR)/runtime-src
+
+GSDLOS = @gsdlos@
+
+INDEXERS_DIR = $(COMMON_DIR)/indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+RUNTIME_PACKAGES_DIR = $(RUNTIME_DIR)/packages
+COLSERVR_DIR = $(RUNTIME_DIR)/src/colservr
+PROTOCOL_DIR = $(RUNTIME_DIR)/src/protocol
+Z3950_DIR = $(RUNTIME_DIR)/src/z3950
+
+
+ENABLE_ACCENTFOLD = @ENABLE_ACCENTFOLD@
+ifeq ($(ENABLE_ACCENTFOLD), 1)
+ACCENTFOLD_LIBS = $(INDEXERS_DIR)/packages/unac/libunac.a 
+else
+ACCENTFOLD_LIBS = 
+endif
+
+USE_FASTCGI = @USE_FASTCGI@
+ifeq ($(USE_FASTCGI), 1)
+FASTCGI_DEFS = -DUSE_FASTCGI
+FASTCGI_INCLUDES = -I$(RUNTIME_PACKAGES_DIR)/fcgi/include
+FASTCGI_LIBS = $(RUNTIME_PACKAGES_DIR)/fcgi/libfcgi/libfcgi.a
+else
+FASTCGI_DEFS =
+FASTCGI_INCLUDES =
+FASTCGI_LIBS = 
+endif
+
+USE_SQLITE = @USE_SQLITE@
+ifeq ($(USE_SQLITE), 1)
+SQLITE_LIBS = $(COMMON_PACKAGES_DIR)/sqlite/lib/libsqlite3.a -ldl -lpthread
+else
+SQLITE_LIBS = 
+endif
+
+USE_Z3950 = @USE_Z3950@
+ifeq ($(USE_Z3950), 1)
+Z3950_DEFS = -DUSE_Z3950
+Z3950_INCLUDES = -I$(Z3950_DIR)
+Z3950_LIBS = $(Z3950_DIR)/gsdlz3950.a $(RUNTIME_PACKAGES_DIR)/yaz/lib/libyaz.a
+else
+Z3950_DEFS =
+Z3950_INCLUDES = 
+Z3950_LIBS = 
+endif
+
+USE_APACHE_HTTPD=@USE_APACHE_HTTPD@
+#ifeq ($(USE_APACHE_HTTPD), 1)
+ifeq ($(USE_APACHE_HTTPD), "IGNORE_FOR_NOW")
+APACHE_OBJS = string_pool.o mod_gsdl.o
+
+APACHE_INSTDIR=$(GSDL_DIR)/apache-httpd/$(GSDLOS)
+APACHE_SRCLIBDIR=../../packages/apache-httpd/httpd-2.2.11/srclib
+
+APXS_CFLAGS=-I$(APACHE_INSTDIR)/include \
+  -I$(APACHE_SRCLIBDIR)/apr/include -I$(APACHE_SRCLIBDIR)/apr-util/include
+
+APXS_LDFLAGS= -L$(APACHE_INSTDIR)/lib \
+  -L$(APACHE_SRCLIBDIR)/apr/include -L$(APACHE_SRCLIBDIR)/apr-util/include
+
+APACHE_MODULE = mod_gsdl.so
+else
+APACHE_OBJS =
+APACHE_MODULE =
+endif
+
+
+AR = ar
+CC = @CC@
+CFLAGS=@CFLAGS@ @COMPAT32BITFLAGS@
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ @COMPAT32BITFLAGS@
+DEFS = @DEFS@ -DNZDL -DQUIET -DSHORT_SUFFIX -DPARADOCNUM -DHAVE_CONFIG_H $(FASTCGI_DEFS) $(Z3950_DEFS)
+INCLUDES = -I. -I$(GSDL_DIR) -I$(COMMON_DIR)/src/lib -I$(COMMON_PACKAGES_DIR)/gdbm/include \
+        -I$(COLSERVR_DIR) -I$(PROTOCOL_DIR) \
+	-I$(INDEXERS_DIR)/mg -I$(INDEXERS_DIR)/mg/lib -I$(INDEXERS_DIR)/mgpp/text \
+        -I$(COMMON_PACKAGES_DIR)/expat/include $(FASTCGI_INCLUDES) $(Z3950_INCLUDES)
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@ @COMPAT32BITFLAGS@
+LIBS = @LIBS@ $(COMMON_PACKAGES_DIR)/gdbm/lib/libgdbm.a -L$(COMMON_PACKAGES_DIR)/expat/lib -lexpat \
+	$(ACCENTFOLD_LIBS) $(FASTCGI_LIBS) $(SQLITE_LIBS) $(Z3950_LIBS)
+RANLIB = @RANLIB@
+
+
+CXXCOMPILE = $(CXX) -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+CXXLINK = $(CXX) $(LDFLAGS) -o $@
+
+
+SOURCES = \
+	action.cpp \
+	argdb.cpp \
+	authenaction.cpp \
+	browseaction.cpp \
+	browseactiontools.cpp \
+	browserclass.cpp \
+	browsetoolsclass.cpp \
+	cgiargs.cpp \
+	cgiutils.cpp \
+	cgiwrapper.cpp \
+	collectoraction.cpp \
+	configaction.cpp \
+        converter.cpp \
+	datelistbrowserclass.cpp \
+	depositoraction.cpp \
+	documentaction.cpp \
+	dynamicclassifieraction.cpp \
+	extlinkaction.cpp \
+	formattools.cpp \
+	gtiaction.cpp \
+	highlighttext.cpp \
+	historydb.cpp \
+	hlistbrowserclass.cpp \
+	htmlbrowserclass.cpp \
+	htmlutils.cpp \
+	invbrowserclass.cpp \
+	librarymain.cpp \
+	maincfg.cpp \
+	pageaction.cpp \
+	pagedbrowserclass.cpp \
+	phindaction.cpp \
+	phindbrowserclass.cpp \
+	pingaction.cpp \
+	queryaction.cpp \
+	querytools.cpp \
+	receptionist.cpp \
+	statusaction.cpp \
+	summarise.cpp \
+	tipaction.cpp \
+	userdb.cpp \
+	usersaction.cpp \
+	vlistbrowserclass.cpp \
+	wizardaction.cpp
+
+OBJECTS = \
+	action.o \
+	argdb.o \
+	authenaction.o \
+	browseaction.o \
+	browseactiontools.o \
+	browserclass.o \
+	browsetoolsclass.o \
+	cgiargs.o \
+	cgiutils.o \
+	cgiwrapper.o \
+	collectoraction.o \
+	configaction.o \
+        converter.o \
+	datelistbrowserclass.o \
+	depositoraction.o \
+	documentaction.o \
+	dynamicclassifieraction.o \
+	extlinkaction.o \
+	formattools.o \
+	gtiaction.o \
+	highlighttext.o \
+	historydb.o \
+	hlistbrowserclass.o \
+	htmlbrowserclass.o \
+	htmlutils.o \
+	invbrowserclass.o \
+	librarymain.o \
+	maincfg.o \
+	pageaction.o \
+	pagedbrowserclass.o \
+	phindaction.o \
+	phindbrowserclass.o \
+	pingaction.o \
+	queryaction.o \
+	querytools.o \
+	receptionist.o \
+	statusaction.o \
+	summarise.o \
+	tipaction.o \
+	userdb.o \
+	usersaction.o \
+	vlistbrowserclass.o \
+	wizardaction.o 
+
+LIBRARY = gsdlrecpt.a
+
+GSDL_LIBS = \
+	$(PROTOCOL_DIR)/gsdlprotocol.a \
+	$(COLSERVR_DIR)/gsdlcolservr.a \
+	$(INDEXERS_DIR)/mg/src/text/libmgtext.a \
+	$(INDEXERS_DIR)/mg/lib/libmglib.a \
+	$(INDEXERS_DIR)/mgpp/text/libmgpptext.a \
+	$(INDEXERS_DIR)/mgpp/lib/libmgpplib.a \
+	$(COMMON_DIR)/src/lib/gsdllib.a
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS) \
+	$(GSDL_LIBS)
+
+EXECUTABLE = library.cgi
+
+
+# Default target: make both gsdlrecpt.a and the library executable
+all: $(LIBRARY) $(EXECUTABLE) $(APACHE_MODULE)
+
+gsdlrecpt.a: $(OBJECTS)
+	rm -f $(LIBRARY)
+	$(AR) cru $(LIBRARY) $(OBJECTS)
+	$(RANLIB) $(LIBRARY)
+
+$(EXECUTABLE): $(EXECUTABLE_OBJECTS) $(GSDL_LIBS)
+	$(CXXLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+mod_gsdl.o: mod_gsdl.cpp
+	$(CXX) -c  $(CXXFLAGS) $(DEFS) $(INCLUDES) -D_APACHE_MOD=2 -fPIC $(APXS_CFLAGS) -Wall -o $@ $< 
+
+mod_gsdl.so: $(APACHE_OBJS) $(LIBRARY)
+	$(CXX) -fPIC -shared -o $@ $(APACHE_OBJS) $(LIBRARY) $(GSDL_LIBS) $(LIBS)
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CXXCOMPILE) $< 
+
+
+install: $(EXECUTABLE)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/cgi-bin
+#ifeq ($(USE_APACHE_HTTPD), 1)
+ifeq ($(USE_APACHE_HTTPD), "IGNORE_FOR_NOW")
+	$(GSDL_DIR)/apache-httpd/$(GSDLOS)/bin/apxs  -i -n gsdl mod_gsdl.so
+endif
+
+clean:
+	rm -f $(OBJECTS) $(LIBRARY) $(EXECUTABLE) $(APACHE_MODULE) $(APACHE_OBJS)
+
+distclean:
+	rm -f $(OBJECTS) $(LIBRARY) $(EXECUTABLE) Makefile
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CXXFLAGS) -- $(SOURCES)
Index: /gsdl/stable/runtime-src/src/recpt/TODO
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/TODO	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/TODO	(revision 20131)
@@ -0,0 +1,57 @@
+For Z 39.50 Stuff
+
+pageaction.cpp
+--------------
+Macros:
+ * for "about" page, use a custom _textbrowseoptions_ macro (ie
+   create a new macro, maybe create a z3950.dm macro file ??)
+   (also maybe _numbrowseoptions_
+
+(Irrelevant?) (c. line 332)
+    disp.setmacro ("numdocs", "Global", cinfo.numDocs);
+    disp.setmacro ("builddate", "Global", builddate);
+
+That message "This collection contains..." is in the _collectionextra_
+macro.
+could get numdocs from the z39.50 server, as well as any other status
+information.
+
+win32.mak
+---------
+Needs updating for all added files (z*, parse.fl)
+
+yaz
+---
+Maybe put libyaz.a in $GSDLHOME/lib ?
+
+
+DESIGN ISSUES
+for z39.50 (and eventually nullproto when corba allows recept. and
+coll server to be physically separate), if the server is unavailable,
+should this be determined at:
+  * "home page" creation time, in which case the recept. must ping and
+test each collection it knows about, which may cause unacceptable delay, or
+  * "about page" creation time (ie individual collection), in which case
+the collection can not customise the page layout by modifying macros.
+
+Eg currently, the z39.50 collection will not create a TCP connection to the
+"target" (ie z39.50 server somewhere around the world) until it tries to
+get the "About this collection" information for that collection. 
+If the connection fails, the protocol can not change _queryform_ part of
+the page.
+
+
+MULTI-LINGUAL SUPPORT
+Multi-lingual - eg macros - want to set _collectionextra_ using
+metadata["collectionextra"] based on the chosen interface language.
+Should be done by OIDtools.cpp:get_info() and any action that calls
+proto->filter().
+queryaction.cpp (c. line 1097):
+  // add the requested language as an option to the query
+  if (!args["l"].empty()) {
+    OptionValue_t option;
+    option.name="Language";
+    option.value=args["l"];
+    request.filterOptions.push_back(option);
+  }
+
Index: /gsdl/stable/runtime-src/src/recpt/action.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/action.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/action.cpp	(revision 20131)
@@ -0,0 +1,161 @@
+/**********************************************************************
+ *
+ * action.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "fileutil.h"
+
+#include "action.h"
+#include <assert.h>
+
+
+// define all the macros which are related to pages generated
+// by this action
+void action::define_internal_macros (displayclass &/*disp*/, cgiargsclass &/*args*/, 
+				     recptprotolistclass * /*protos*/, ostream &/*logout*/) {
+}
+
+action::action () {
+}
+
+action::~action () {
+}
+
+// configure should be called once for each configuration line
+void action::configure (const text_t &key, const text_tarray &cfgline) {
+  if (key == "gsdlhome") {
+    gsdlhome = cfgline[0];
+    if (collecthome.empty()) collecthome = filename_cat(gsdlhome,"collect");
+    if (dbhome.empty()) dbhome = cfgline[0];
+  }
+  if (key == "collecthome") {collecthome = cfgline[0];}
+  if (key == "gdbmhome") {dbhome = cfgline[0];}
+}
+
+// init should be called after all the configuration is done but
+// before any other methods are called
+bool action::init (ostream &/*logout*/) {
+  return true;
+}
+
+// returns the "a" argument value that will specify this action
+// this name should be short but does not have to be one character
+// long
+text_t action::get_action_name () {
+  return "nzdl";
+}
+
+// check_cgiargs should be called before get_cgihead_info, 
+// define_external_macros, and do_action. If an error is found
+// a message will be written to logout, if the error is severe
+// then the function will return false and no page content
+// should be produced based on the arguments.
+bool action::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &/*args*/, 
+			    recptprotolistclass * /*protos*/, ostream &/*logout*/) {
+  return true;
+}
+
+// check_external_cgiargs should be called after check_cgiargs
+// for all actions. It should only be used to override some other
+// normal behaviour, for example, producing a login page when
+// the requested page needs authentication.
+bool action::check_external_cgiargs (cgiargsinfoclass &/*argsinfo*/,
+				     cgiargsclass &/*args*/,
+				     outconvertclass &/*outconvert*/,
+				     const text_t &/*saveconf*/,
+				     ostream &/*logout*/) {
+  return true;
+}
+
+// get_cgihead_info determines the cgi header information for
+// a set of cgi arguments. If response contains location then
+// response_data contains the redirect address. If reponse
+// contains content then reponse_data contains the content-type.
+// Note that images can now be produced by the receptionist.
+void action::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
+			       response_t &response, text_t &response_data, 
+			       ostream &/*logout*/) {
+  response = location;
+  response_data = "http://www.nzdl.org";
+}
+  
+// uses_display should return true if the receptionist should return
+// true if the display class is needed to output the page content
+// The default is to return true.
+bool action::uses_display (cgiargsclass &/*args*/) {
+  return true;
+}
+
+
+// define all the macros which might be used by other actions
+// to produce pages. These macros should be well documented.
+void action::define_external_macros (displayclass &/*disp*/, cgiargsclass &/*args*/, 
+				     recptprotolistclass * /*protos*/, ostream &/*logout*/) {
+}
+
+// returns false if there was an error which prevented the action
+// from outputing anything.
+bool action::do_action (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/, 
+			browsermapclass * /*browsers*/, displayclass &/*disp*/, 
+			outconvertclass &/*outconvert*/, ostream &/*textout*/, 
+			ostream &/*logout*/) {
+  return true;
+}
+
+
+bool operator==(const actionptr &x, const actionptr &y) {
+  return (x.a == y.a);
+}
+
+bool operator<(const actionptr &x, const actionptr &y) {
+  return (x.a < y.a);
+}
+
+
+// theaction remains the property of the calling code but
+// should not be deleted until it is removed from this list.
+void actionmapclass::addaction (action *theaction) {
+  // can't add a null action
+  assert (theaction != NULL);
+  if (theaction == NULL) return;
+  
+  // can't add an action with no name
+  assert (!(theaction->get_action_name()).empty());
+  if ((theaction->get_action_name()).empty()) return;
+
+  actionptr aptr;
+  aptr.a = theaction;
+  actionptrs[theaction->get_action_name()] = aptr;
+}
+
+// getaction will return NULL if the action could not be found
+action *actionmapclass::getaction (const text_t &key) {
+  // can't find an action with no name
+  assert (!key.empty());
+  if (key.empty()) return NULL;
+
+  iterator here = actionptrs.find (key);
+  if (here == actionptrs.end()) return NULL;
+  
+  return (*here).second.a;
+}
Index: /gsdl/stable/runtime-src/src/recpt/action.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/action.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/action.h	(revision 20131)
@@ -0,0 +1,184 @@
+/**********************************************************************
+ *
+ * action.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef ACTION_H
+#define ACTION_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "cgiargs.h"
+#include "display.h"
+#include "recptproto.h"
+#include "browserclass.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+#endif
+
+
+class action {
+protected:
+  cgiargsinfoclass argsinfo;
+  text_t gsdlhome;
+  text_t collecthome;
+  text_t dbhome;
+
+public:
+  action ();
+  virtual ~action ();
+
+  // configure should be called once for each configuration line
+  virtual void configure (const text_t &key, const text_tarray &cfgline);
+
+  // init should be called after all the configuration is done but
+  // before any other methods are called
+  virtual bool init (ostream &logout);
+
+  // returns the "a" argument value that will specify this action
+  // this name should be short but does not have to be one character
+  // long
+  virtual text_t get_action_name ();
+
+  // check_cgiargs should be called before get_cgihead_info, 
+  // define_external_macros, and do_action. If an error is found
+  // a message will be written to logout, if the error is severe
+  // then the function will return false and no page content
+  // should be produced based on the arguments.
+  virtual bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+			      recptprotolistclass *protos, ostream &logout);
+
+  // check_external_cgiargs should be called after check_cgiargs
+  // for all actions. It should only be used to override some other
+  // normal behaviour, for example, producing a login page when
+  // the requested page needs authentication.
+  virtual bool check_external_cgiargs (cgiargsinfoclass &argsinfo,
+				       cgiargsclass &args,
+				       outconvertclass &outconvert,
+				       const text_t &saveconf,
+				       ostream &logout);
+
+  // get_cgihead_info determines the cgi header information for
+  // a set of cgi arguments. If response contains location then
+  // response_data contains the redirect address. If reponse
+  // contains content then reponse_data contains the content-type.
+  // Note that images can now be produced by the receptionist.
+  virtual void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+				 response_t &response, text_t &response_data, 
+				 ostream &logout);
+  
+  // uses_display should return true if the receptionist should return
+  // true if the display class is needed to output the page content.
+  // The default is to return true.
+  virtual bool uses_display (cgiargsclass &args);
+
+  // define all the macros which are related to pages generated
+  // by this action
+  virtual void define_internal_macros (displayclass &disp, cgiargsclass &args, 
+				       recptprotolistclass *protos, ostream &logout);
+
+  // define all the macros which might be used by other actions
+  // to produce pages. These macros should be well documented.
+  virtual void define_external_macros (displayclass &disp, cgiargsclass &args, 
+				       recptprotolistclass *protos, ostream &logout);
+
+  // returns false if there was an error which prevented the action
+  // from outputing anything.
+  virtual bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+			  browsermapclass *browsers, displayclass &disp, 
+			  outconvertclass &outconvert, ostream &textout, 
+			  ostream &logout);
+
+  // return true if the specified top classifier is handled by this action
+  virtual bool is_my_classifier(const text_t& topcl) { return false; }
+
+  // getargsinfo should be called after all configuration files
+  // have been read
+  cgiargsinfoclass *getargsinfo() {return &argsinfo;};
+};
+
+
+// The actionptr function does not 'own' the action. The 
+// action should be deleted by the code which created it.
+class actionptr {
+public:
+  action *a;
+
+  actionptr () {a=NULL;}
+};
+
+bool operator==(const actionptr &x, const actionptr &y);
+bool operator<(const actionptr &x, const actionptr &y);
+
+typedef map<text_t, actionptr, lttext_t> actionptrmap;
+
+// contains a list of actions indexed by their name
+class actionmapclass {
+protected:
+  actionptrmap actionptrs;
+
+public:
+  // type support for actionptrmap
+  typedef actionptrmap::iterator iterator;
+  typedef actionptrmap::const_iterator const_iterator;
+  typedef actionptrmap::reference reference;
+  typedef actionptrmap::const_reference const_reference;
+  typedef actionptrmap::size_type size_type;
+
+  typedef actionptrmap::difference_type difference_type;
+  typedef actionptrmap::const_reverse_iterator const_reverse_iterator;
+  typedef actionptrmap::reverse_iterator reverse_iterator;
+  
+  // basic container support
+  iterator begin () {return actionptrs.begin();}
+  const_iterator begin () const {return actionptrs.begin();}
+  iterator end () {return actionptrs.end();}
+  const_iterator end () const {return actionptrs.end();}
+
+  void erase(iterator pos) {actionptrs.erase(pos);}
+  void erase(iterator first, iterator last) {actionptrs.erase(first, last);}
+  actionmapclass &operator=(const actionmapclass &x) {actionptrs=x.actionptrs;return *this;}
+
+  bool empty () const {return actionptrs.empty();}
+  size_type size() const {return actionptrs.size();}
+
+
+  // added functionality
+  void clear () {actionptrs.erase(actionptrs.begin(),actionptrs.end());}
+
+  // theaction remains the property of the calling code but
+  // should not be deleted until it is removed from this list.
+  void addaction (action *theaction);
+
+  // getaction will return NULL if the action could not be found
+  action *getaction (const text_t &key);
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/argdb.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/argdb.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/argdb.cpp	(revision 20131)
@@ -0,0 +1,77 @@
+/**********************************************************************
+ *
+ * argdb.cpp -- 
+ * Copyright (C) 2001  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_COLLECTOR_ACTION
+
+// argdb is used by the collector for storing cgi arguments on disk (in a database)
+
+#include "argdb.h"
+#include "gdbmclass.h"
+
+argdb::argdb (const text_t &filename) {
+  dbfile = filename;
+}
+  
+bool argdb::update_args (text_tmap &argmap) {
+  gdbmclass argdb;
+  if (!argdb.opendatabase(dbfile, DB_WRITER_CREATE, 1000, true)) return false;
+  infodbclass info;
+  
+  argdb.getinfo("savedargs", info);
+
+  text_tmap::iterator here = argmap.begin();
+  text_tmap::iterator end = argmap.end();
+  while (here != end) {
+    if (!(*here).second.empty()) {
+      info.setinfo((*here).first, (*here).second);
+    }
+    ++here;
+  }
+
+  bool rv = argdb.setinfo ("savedargs", info);
+  argdb.closedatabase();
+  return rv;
+}
+
+bool argdb::get_args (text_tmap &argmap) {
+  argmap.erase(argmap.begin(), argmap.end());
+  gdbmclass argdb;
+  if (!argdb.opendatabase(dbfile, DB_READER, 1000, true)) return false;
+  infodbclass info;
+  
+  if (!argdb.getinfo("savedargs", info)) return false;
+  
+  infodbclass::const_iterator here = info.begin();
+  infodbclass::const_iterator end = info.end();
+  while (here != end) {
+    argmap[(*here).first] = info[(*here).first];
+    ++here;
+  }
+  argdb.closedatabase();
+  return true;
+}
+
+#endif //GSDL_USE_COLLECTOR_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/argdb.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/argdb.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/argdb.h	(revision 20131)
@@ -0,0 +1,50 @@
+/**********************************************************************
+ *
+ * argdb.h -- 
+ * Copyright (C) 2001  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_COLLECTOR_ACTION
+
+#ifndef ARGDB_H
+#define ARGDB_H
+
+#include "text_t.h"
+
+class argdb {
+
+protected:
+
+  text_t dbfile;
+
+public:
+  
+  argdb (const text_t &filename);
+  virtual ~argdb () {}
+  
+  bool update_args (text_tmap &argmap);
+  bool get_args (text_tmap &argmap);
+};
+
+#endif //!ARGDB_H
+#endif //GSDL_USE_COLLECTOR_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/authenaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/authenaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/authenaction.cpp	(revision 20131)
@@ -0,0 +1,345 @@
+/**********************************************************************
+ *
+ * authenaction.cpp -- authenticating users
+ * Copyright (C) 1999  DigiLib Systems Limited, New Zealand
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_AUTHEN_ACTION
+
+#include "authenaction.h"
+#include "fileutil.h"
+#include "cfgread.h"
+#include "cgiutils.h"
+#include "gsdltimes.h"
+
+
+///////////////
+// authenaction
+///////////////
+
+authenaction::authenaction () {
+  keydecay = 1800; // 30 minutes
+  recpt = NULL;
+
+  // this action uses cgi variable "a"
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "a";
+  arg_ainfo.longname = "action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "a";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "us"
+  arg_ainfo.shortname = "us";
+  arg_ainfo.longname = "user account status";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "invalid";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "ug"
+  arg_ainfo.shortname = "ug";
+  arg_ainfo.longname = "user groups"; // comma seperated list
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "un"
+  arg_ainfo.shortname = "un";
+  arg_ainfo.longname = "user name";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "pw"
+  arg_ainfo.shortname = "pw";
+  arg_ainfo.longname = "password";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "ky" - gives a specific user authentication for a
+  // limited amount of time
+  arg_ainfo.shortname = "ky";
+  arg_ainfo.longname = "user time key";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "ua" - ""=no, "1"=yes 
+  arg_ainfo.shortname = "ua";
+  arg_ainfo.longname = "whether a user has been authenticated";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "er" - compressed arguments for the referer page
+  arg_ainfo.shortname = "er";
+  arg_ainfo.longname = "the compressed args of the refer page";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "uan" - whether user authentication is needed
+  arg_ainfo.shortname = "uan";
+  arg_ainfo.longname = "whether user authentication is needed";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+}
+
+void authenaction::configure (const text_t &key, const text_tarray &cfgline) {
+  action::configure (key, cfgline);
+}
+
+bool authenaction::init (ostream &logout) {
+  if (dbhome.empty()) {
+    logout << "ERROR (authenaction::init) dbhome is not set\n";
+    return false;
+  }
+
+  return action::init (logout);
+}
+
+bool authenaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &/*args*/, 
+				  recptprotolistclass * /*protos*/, ostream &/*logout*/) {
+  return true;
+}
+
+// returns false if there is a major problem with the cgi arguments -- not
+// if authentication fails. If the authentication fails "un" will be empty
+bool authenaction::check_external_cgiargs (cgiargsinfoclass &argsinfo,
+					   cgiargsclass &args,
+					   outconvertclass &outconvert,
+					   const text_t &saveconf,
+					   ostream &logout) {
+
+  // no need to go further unless authentication is
+  // required by this page
+  if (args["uan"].empty()) return true;
+
+  // failure means we have to redirect to this action to get authentication
+  // (if we are not already doing this)
+
+  userinfo_t thisuser;
+
+  text_t &args_uan = args["uan"];  text_t &args_un = args["un"];
+  text_t &args_pw = args["pw"];    text_t &args_us = args["us"];
+  text_t &args_ug = args["ug"];    text_t &args_ky = args["ky"];
+  text_t &args_ua = args["ua"];    text_t &args_a = args["a"];
+
+  // we must have a username and a password or a key to
+  // do any authentication
+  args_ua.clear(); // default = false;
+  if (args_un.empty() || args_pw.empty()) args_us = "invalid";
+  else args_us = "failed";
+
+  // make sure we have a username                                                                                                 
+  int status = user_database->get_user_info (args_un, thisuser);
+  if (!args_un.empty() && (status == ERRNO_SUCCEED)) {
+    if (!args_pw.empty()) {
+      // we are authenticating using a password
+      if (user_database->check_passwd (thisuser.username, args_pw) == ERRNO_SUCCEED) args_ua = "1"; // succeeded
+      
+    } else if (!args_ky.empty()) {
+      // we are authenticating using a key
+      if (key_database->check_key(thisuser, args_ky, args_ug, keydecay)) args_ua = "1";
+      else args_us = "stalekey";
+    }
+  }
+
+  args_pw.clear(); // password goes no further
+  if (!args_ua.empty()) {
+    if (thisuser.enabled) {
+      bool haspermission = true;
+
+      // check to make sure the user is in the required group
+      // one group is available only at the moment.
+      // this is what we are changing !
+      
+      if (!args_ug.empty()) {
+
+	 // Since we recieve a comma seperated list
+	 // of groups like mygroup,yourgroup,ourgroup
+	 // we want to split them into individual groups
+	 // and examine them. This is what is done here.
+	 
+	 text_tset splitgrps;
+	 text_t::const_iterator split_here = args_ug.begin();
+	 text_t::const_iterator split_end = args_ug.end();
+
+	 splitchar(split_here,split_end,',',splitgrps);
+
+	 haspermission = false;
+
+	 // This examines the current user to be authenticated and
+	 // tries to see if he or she is in the group that we have in
+	 // thisuser structure. We compare args_ua contents with that
+	 // of the user database.
+	 
+	 text_t::const_iterator group_here = thisuser.groups.begin();
+	 text_t::const_iterator group_end = thisuser.groups.end();
+	 text_t thisgroup;
+	while (group_here != group_end) {
+	   group_here = getdelimitstr (group_here, group_end, ',', thisgroup);
+	   if (splitgrps.find(thisgroup) != splitgrps.end() )
+	      {
+		 haspermission = true;
+		 break;
+	      }
+	}
+      }
+      
+      if (haspermission) {
+	 // succeeded, get info about this user
+	 // note: we don't need to set "ug" as it is already set to what it needs to be
+	 args_us = "enabled";
+	 args_ky = key_database->generate_key(args_un); // new key
+	
+	// delete old keys around every 50 accesses
+	if (rand()%50 == 1) key_database->remove_old_keys(keydecay);
+	
+      } else {
+	// succeeded, however, the user is not in the correct group
+	 args_ua.clear();
+	 args_us = "permissiondenied";
+	 args_ky.clear();
+      }
+      
+    } else {
+       // succeeded, however, the account is disabled
+      args_ua.clear();
+      args_us = "disabled";
+      args_ky.clear();
+    }
+
+  } else {
+    // failure, reset info about the user
+    args_ky.clear();
+  }
+
+  // we will have to redirect the user if authentication is needed,
+  // it failed, and we weren't on our way to be authenticated anyway
+  if ((!args_uan.empty()) && (args_ua.empty()) && (args_a != "a")) {
+    // need to save the current arguments in "er"
+    text_t &arg_er = args["er"];
+    if (!compress_save_args(argsinfo, saveconf, args, arg_er, outconvert, logout))
+      arg_er.clear();
+    
+    // needs to be decoded for use within forms
+    decode_cgi_arg (arg_er);    
+
+    // redirect to this action
+    args_a = "a";
+  }
+
+  return true;
+}
+
+void authenaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
+				     response_t &response, text_t &response_data, 
+				     ostream &/*logout*/) {
+  response = content;
+  response_data = "text/html";
+}
+
+void authenaction::define_internal_macros (displayclass &disp, cgiargsclass &args, 
+					   recptprotolistclass * /*protos*/, ostream &/*logout*/) {
+  // sets _authen:messageextra_ based on the value of args["us"]
+  //      _authen:hiddenargs_   to contain all the arguments that were
+  //                            explicitly set
+  disp.setmacro ("messagestatus", "authen", ("_authen:message" + args["us"]
+					     + "_"));
+  // change style of header and footer if page is a frame
+  if ((args["p"].empty()) || (args["p"] == "frameset")) {
+    disp.setmacro ("header", "authen", "_status:infoheader_(Log in)");
+    disp.setmacro ("header", "authenok", "_status:infoheader_(Log in)");
+    disp.setmacro ("footer", "authen", "_status:infofooter_(Log in)");
+    disp.setmacro ("footer", "authenok", "_status:infofooter_(Log in)");
+  }
+
+  // get a list of saved configuration arguments (if possible)
+  text_t saveconf;
+  text_tset saveconfset;
+  if (recpt != NULL) {
+    saveconf = recpt->get_configinfo().saveconf;
+    splitchar (saveconf.begin(), saveconf.end(), '-', saveconfset);
+  }
+  
+  text_t hiddenargs;
+  cgiargsclass::const_iterator args_here = args.begin();
+  cgiargsclass::const_iterator args_end = args.end();
+  while (args_here != args_end) {
+    // set this as a hidden argument if it came from the cgi arguments,
+    // its not the compressed arguments, the query string, a user name or
+    // password, or collect.cfg, and if it is not in the compressed arguments
+    if ((*args_here).second.source == cgiarg_t::cgi_arg &&
+	(*args_here).first != "e" && (*args_here).first != "q" &&
+	(*args_here).first != "un" && (*args_here).first != "pw" &&
+	(*args_here).first != "cfgfile" && 
+	saveconfset.find((*args_here).first) == saveconfset.end()) {
+      hiddenargs += "<input type=hidden name=\"" + (*args_here).first +
+	"\" value=\"_cgiarg" + (*args_here).first + "_\">\n";
+    }
+    ++args_here;
+  }
+
+  disp.setmacro ("hiddenargs", "authen", hiddenargs);
+}
+
+bool authenaction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/, 
+			      browsermapclass * /*browsers*/, displayclass &disp, 
+			      outconvertclass &outconvert, ostream &textout, 
+			      ostream &/*logout*/) {
+  if (args["us"] == "enabled") {
+    // have been authenticated
+    textout << outconvert << disp
+	    << "_authenok:header_\n_authenok:content_\n_authenok:footer_\n";
+    return true;
+  }
+  
+  // need to be authenticated
+  textout << outconvert << disp
+	  << "_authen:header_\n_authen:content_\n_authen:footer_\n";
+
+  return true;
+}
+
+#endif //GSDL_USE_AUTHEN_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/authenaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/authenaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/authenaction.h	(revision 20131)
@@ -0,0 +1,89 @@
+/**********************************************************************
+ *
+ * authenaction.h -- authenticating users
+ * Copyright (C) 1999  DigiLib Systems Limited, New Zealand
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_AUTHEN_ACTION
+
+#ifndef AUTHENACTION_H
+#define AUTHENACTION_H
+
+#include "gsdlconf.h"
+#include "action.h"
+#include "text_t.h"
+#include "userdb.h"
+#include "receptionist.h"
+
+
+// note: you need to tell this action about the receptionist
+// using set_receptionist
+
+class authenaction : public action {
+protected:
+  userdbclass *user_database;
+  keydbclass *key_database;
+  int keydecay;
+
+  receptionist *recpt;
+  
+public:
+  authenaction ();
+  virtual ~authenaction () {}
+
+  void set_userdb(userdbclass *udb) {user_database = udb;}
+
+  void set_keydb (keydbclass *kdb) {key_database = kdb;}
+
+  void set_receptionist (receptionist *therecpt) {recpt=therecpt;}
+  
+  void configure (const text_t &key, const text_tarray &cfgline);
+
+  bool init (ostream &logout);
+  
+  text_t get_action_name () {return "a";}
+  
+  bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+		      recptprotolistclass *protos, ostream &logout);
+
+  bool check_external_cgiargs (cgiargsinfoclass &argsinfo,
+			       cgiargsclass &args,
+			       outconvertclass &outconvert,
+			       const text_t &saveconf,
+			       ostream &logout);
+
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response, text_t &response_data, 
+			 ostream &logout);
+  
+  void define_internal_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+  
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+};
+
+#endif //!AUTHENACTION_H
+#endif //GSDL_USE_AUTHEN_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/browseaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/browseaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/browseaction.cpp	(revision 20131)
@@ -0,0 +1,249 @@
+/**********************************************************************
+ *
+ * browseaction.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_BROWSE_ACTION
+
+#include "browseaction.h"
+#include "querytools.h"
+#include "browseactiontools.h"
+#include "recptprototools.h"
+
+browseaction::browseaction(){
+
+ 
+
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "a";
+  arg_ainfo.longname = "action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "br";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  //the first browsing criterion -- collection metadata types
+  arg_ainfo.shortname = "b1";
+  arg_ainfo.longname = "browse criterion 1";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+ 
+  //the second browsing criterion -- collection metadata types + none - meaning
+  //only one browsing criterion.  None is the default.
+  arg_ainfo.shortname = "b2";
+  arg_ainfo.longname = "browse criterion 2";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+  
+  //the number of documents to show per page -- if the box is empty then
+  //only the most basic divisions are made (so, first letter for A-Z, year 
+  //for date).
+  arg_ainfo.shortname = "bnu";
+  arg_ainfo.longname = "browse docs per page";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::good;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  //The text to filter documents for browsing (only documents containing these 
+  //words will be browsed).
+  arg_ainfo.shortname = "bft";
+  arg_ainfo.longname = "browse filter text";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::none;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+
+  //Whether all or just some of the words in the filter box have to be present
+  //0 - any 1- all
+  arg_ainfo.shortname = "bt";
+  arg_ainfo.longname = "browse all or any";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+  
+  
+}
+
+browseaction::~browseaction(){}
+
+bool browseaction::init (ostream &logout){
+  return true;
+}
+
+void browseaction::configure (const text_t &key, const text_tarray &cfgline){
+  action::configure(key, cfgline);
+}
+
+
+
+bool browseaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &/*args*/, 
+				  recptprotolistclass * /*protos*/, ostream &/*logout*/) {
+  // don't want to check anything yet.
+  
+  return true;
+}
+
+  
+void browseaction::get_cgihead_info (cgiargsclass &args, 
+				     recptprotolistclass *protos,
+				     response_t &response, 
+				     text_t &response_data, 
+				     ostream &logout){
+  response = content;
+  response_data = "text/html";
+
+  
+}
+
+void browseaction::define_internal_macros (displayclass &disp, 
+					   cgiargsclass &args, 
+					   recptprotolistclass *protos, 
+					   ostream &logout){
+ 
+}
+
+void browseaction::define_external_macros (displayclass &disp, 
+					   cgiargsclass &args, 
+					   recptprotolistclass *protos, 
+					   ostream &logout){
+  
+}
+
+bool browseaction::do_action (cgiargsclass &args, recptprotolistclass *protos, 
+			      browsermapclass *browsers, displayclass &disp, 
+			      outconvertclass &outconvert, ostream &textout, 
+			      ostream &logout){
+ 
+  if(args["c"].empty()) return false;
+  else if(get_document_list(args, protos, browsers, disp, outconvert, textout,
+			    logout)) return true;
+  else return false;
+}
+
+bool browseaction::get_document_list(cgiargsclass &args, 
+		recptprotolistclass *protos, browsermapclass *browsers, 
+		displayclass &disp, outconvertclass &outconvert, 
+		ostream &textout, ostream &logout){ 
+  
+  text_t collection = args["c"];
+  comerror_t err;
+  text_t list_type = "VList";  //result display type
+
+  //check that the protocol is alive
+  recptproto* colproto = protos->getrecptproto (collection, logout);
+  if(colproto == NULL) {
+    logout << outconvert << "ERROR: Null collection protocol trying to browse "
+	   << collection << "\n";
+    return false;
+  }
+  
+  //check the collection is responding/in place
+  ColInfoResponse_t *colinfo = recpt->get_collectinfo_ptr(colproto, collection,
+							  logout);
+  if(colinfo == NULL){
+    logout << outconvert << "ERROR: Null returned for get_collectinfo_ptr on "
+	   << collection << "in browseaction\n";
+    return false;
+  }
+
+  browserclass* br_ptr = browsers->getbrowser(list_type);
+
+  FilterRequest_t request;
+  FilterResponse_t response;
+
+  //set up browser structure 
+  br_ptr->set_filter_options(request, args);
+  request.filterLang = args["l"];
+  br_ptr->load_metadata_defaults(request.fields);
+
+  //set up format information
+  format_t* formatptr = new format_t();
+  parse_formatstring(br_ptr->get_default_formatstring(), formatptr, 
+		     request.fields, request.getParents);
+
+  request.filterResultOptions = FROID | FRmetadata;
+  
+  text_t bf_string = g_EmptyText;
+  format_browsestring(args["bft"],bf_string,args.getintarg("bt"));
+  
+  set_browsefilter_options(request, bf_string, args);
+  
+  //set up browse filter string;
+  if(!args["bft"].empty()){
+
+    colproto->filter (collection, request, response, err, logout);
+    if (err != noError) {
+      outconvertclass text_t2ascii;
+      logout << text_t2ascii
+	     << "browseaction::get_document_list QueryFilter failed "
+	     << "for " << collection << " collection (" 
+	     << get_comerror_string (err) << ")\n";
+      return false;
+    }// if (err != noError) 
+
+  }// end if(!args["bft"].empty())
+  else {
+    text_tset metadata_items;
+    text_t temp = "Title";
+    metadata_items.insert(temp);
+    temp = "browselist";
+    if (!get_children(temp, args["c"], args["l"], metadata_items, false, colproto,
+		     response,logout)) return false;
+  }
+
+  //get rid of documents that do not have the metadata element classified on
+  if(!remove_no_meta_results("Title",response, outconvert)) {
+    return false;
+    logout<<"ERROR: browseactiontools::remove_no_meta_results failed"<<endl;
+  }
+
+  textout << outconvert << disp << "_browse:header_\n" <<"_browse:content_";
+
+  
+  bool use_table = is_table_content (formatptr);
+  br_ptr->output_section_group (response, args, collection, 0, formatptr, 
+			      use_table, request.fields, request.getParents, 
+			      colproto, disp, outconvert, textout, logout);
+
+  textout << outconvert << disp << "_browse:footer_";
+    
+  
+  
+  return true;
+}
+
+#endif //GSDL_USE_BROWSE_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/browseaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/browseaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/browseaction.h	(revision 20131)
@@ -0,0 +1,77 @@
+/**********************************************************************
+ *
+ * browseaction.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_BROWSE_ACTION
+
+#ifndef BROWSEACTION_H
+#define BROWSEACTION_H
+
+#include "action.h"
+#include "receptionist.h"
+
+class browseaction : public action{
+ protected:
+  receptionist* recpt;
+  bool get_document_list(cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+ public:
+  browseaction();
+  virtual ~browseaction();
+
+  bool init (ostream &logout);
+
+  void configure (const text_t &key, const text_tarray &cfgline);
+
+  text_t get_action_name() {return "br";}
+  
+  void set_receptionist (receptionist *therecpt) {recpt=therecpt;}
+
+  bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+		      recptprotolistclass *protos, ostream &logout);
+
+  
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+				 response_t &response, text_t &response_data, 
+				 ostream &logout);
+
+  void define_internal_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+  
+  void define_external_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+
+  const cgiargsinfoclass& getargsinfo() const {return argsinfo;};
+};
+
+#endif //!BROWSEACTION_H
+#endif //GSDL_USE_BROWSE_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/browseactiontools.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/browseactiontools.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/browseactiontools.cpp	(revision 20131)
@@ -0,0 +1,129 @@
+/**********************************************************************
+ *
+ * browseactiontools.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#include "browseactiontools.h"
+#include <ctype.h>
+
+void format_browsestring(const text_t& orig, text_t& formatted, int and_or)
+{
+  
+ 
+  text_t conj = g_EmptyText;
+  
+  if(and_or == 0){ conj = " | "; }
+  else { conj = " & "; }
+  text_t::const_iterator here = orig.begin();
+  text_t::const_iterator end = orig.end();
+  
+  //while not at the end of the filter string
+  while(here!=end){
+    //if seeing text, add it to the formatted string
+    if(!isspace(*here)){
+      formatted.push_back(*here);
+      ++here;
+    }
+    //else, if seeing spaces, check that there is following text and add
+    //the ncessary conjugation if there is.
+    else if(isspace(*here)){
+      while(isspace(*here) && here!=end) ++here;
+      if(here!=end) formatted += conj;
+    }
+  }
+
+}
+
+// this stuff is all copied from the queryoptions code - don't ask how it all
+// hangs in with the filters - those things are a mystery 
+void set_browsefilter_options(FilterRequest_t &request, const text_t &browsestring,
+			      cgiargsclass &args)
+{
+  request.filterName = "QueryFilter";
+
+   OptionValue_t option;
+
+   option.name = "Term";
+   option.value = browsestring;
+   request.filterOptions.push_back (option);
+   
+   option.name = "QueryType";
+   option.value = "boolean";
+   request.filterOptions.push_back (option);
+  
+   option.name = "MatchMode";
+   option.value = (args.getintarg("bt")) ? "some" : "all";
+   request.filterOptions.push_back (option);
+   
+   option.name = "Casefold";
+   option.value = (args.getintarg("k")) ? "true" : "false";
+   request.filterOptions.push_back (option);
+   
+   option.name = "Stem";
+   option.value = (args.getintarg("s")) ? "true" : "false";
+   request.filterOptions.push_back (option);
+
+   option.name = "Maxdocs";
+   option.value = -1;
+   request.filterOptions.push_back (option);
+   
+   option.name = "Index";
+   option.value = "dtx";
+   request.filterOptions.push_back (option);
+     
+   
+}
+
+bool remove_no_meta_results(const text_t& metaname, FilterResponse_t &response, 
+			    outconvertclass &outconvert)
+{
+  
+  ResultDocInfo_tarray::iterator check = response.docInfo.begin();
+  ResultDocInfo_tarray::iterator done = response.docInfo.end();
+  // look through all the returned documents
+  while(check != response.docInfo.end()){
+   
+    //if the document doesn't have the metadata item classified on 
+    //remove it.
+    text_t title = *((*check).metadata.find(metaname)->second).values.begin();
+    if(title == g_EmptyText)
+      {
+	
+	response.docInfo.erase(check);
+	
+      }
+    else {
+     
+      ++check;
+     
+    }
+ 
+  }
+  return true;
+}
+
+
+
+
+
Index: /gsdl/stable/runtime-src/src/recpt/browseactiontools.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/browseactiontools.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/browseactiontools.h	(revision 20131)
@@ -0,0 +1,48 @@
+/********************************************************************
+ *
+ * browseactiontools.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef BROWSEACTIONTOOLS_H
+#define BROWSEACTIONTOOLS_H
+
+#include "cgiargs.h"
+#include "recptproto.h"
+
+//this puts ands or ors into the querystring as necessary
+void format_browsestring(const text_t& orig, text_t& formatted, int and_or);
+
+//this thing sets up the search associated with a browse.  It's programmed by 
+//witchcraft, so I don't really know how/why it works - I lifted the code from
+//somewhere else.
+void set_browsefilter_options(FilterRequest_t &request, const text_t &browsestring,
+			      cgiargsclass &args);
+
+//this thing filters out all the results of a request to the collection 
+//(whether it be for all documents or just the ones with specified terms)
+//that don't have the required "metaname" metadata element.
+bool remove_no_meta_results(const text_t &metaname, FilterResponse_t &response,
+			    outconvertclass &outconvert);
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/browserclass.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/browserclass.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/browserclass.cpp	(revision 20131)
@@ -0,0 +1,198 @@
+/**********************************************************************
+ *
+ * browserclass.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "browserclass.h"
+#include <assert.h>
+
+
+browserclass::browserclass () {
+}
+
+browserclass::~browserclass () {
+}
+
+// configure should be called once for each configuration line
+// the default version does nothing
+void browserclass::configure (const text_t &/*key*/, const text_tarray &/*cfgline*/) {
+}
+
+// init should be called after all the configuration is done but
+// before any other methods are called
+bool browserclass::init (ostream &/*logout*/) {
+  return true;
+}
+
+// returns the name that specifies the browserclass type
+text_t browserclass::get_browser_name () {
+  return g_EmptyText;
+}
+
+void browserclass::processOID (cgiargsclass &/*args*/, recptproto * /*collectproto*/, ostream &/*logout*/) {
+}
+
+void browserclass::load_metadata_defaults (text_tset &/*metadata*/) {
+}
+
+text_t browserclass::get_default_formatstring () {
+  return g_EmptyText;
+}
+
+void browserclass::set_filter_options (FilterRequest_t &request, cgiargsclass &args) {
+  
+  OptionValue_t option;
+
+  if (args["a"] == "q") {
+    int arg_m = args.getintarg("m");
+    
+    option.name = "StartResults";
+    option.value = args["r"];
+    request.filterOptions.push_back (option);
+    
+    option.name = "EndResults";
+    int endresults = args.getintarg("o") + (args.getintarg("r") - 1);
+    //    int endresults = (args.getintarg("o")*3) + (args.getintarg("r") - 1);
+    if ((endresults > arg_m) && (arg_m != -1)) endresults = arg_m;
+    option.value = endresults;
+    request.filterOptions.push_back (option);
+
+  } else {
+    option.name = "StartResults";
+    option.value = args["r"];
+    request.filterOptions.push_back (option);
+    
+    option.name = "EndResults";
+    int endresults = 20 + (args.getintarg("r") - 1);
+    option.value = endresults;
+    request.filterOptions.push_back (option);
+  }
+}
+
+int browserclass::output_section_group (ResultDocInfo_t &/*section*/, cgiargsclass &/*args*/,
+					const text_t &/*collection*/, int /*colnumber*/, 
+					format_t * /*formatlistptr*/, bool /*use_table*/, 
+					text_tset &/*metadata*/, bool &/*getParents*/,
+					recptproto * /*collectproto*/, displayclass &/*disp*/, 
+					outconvertclass &/*outconvert*/, ostream &/*textout*/, 
+					ostream &/*logout*/) {
+  return 0;
+}
+
+int browserclass::output_section_group (ResultDocInfo_t &/*section*/, cgiargsclass &/*args*/,
+					const text_t &/*labels*/, const text_t &/*collection*/, int /*colnumber*/, 
+					format_t * /*formatlistptr*/, bool /*use_table*/, 
+					text_tset &/*metadata*/, bool &/*getParents*/,
+					recptproto * /*collectproto*/, displayclass &/*disp*/, 
+					outconvertclass &/*outconvert*/, ostream &/*textout*/, 
+					ostream &/*logout*/) {
+  return 0;
+}
+
+int browserclass::output_section_group (FilterResponse_t &/*sections*/, cgiargsclass &/*args*/,
+					const text_t &/*collection*/, int /*colnumber*/, 
+					format_t * /*formatlistptr*/, bool /*use_table*/, 
+					text_tset &/*metadata*/, bool &/*getParents*/,
+					recptproto * /*collectproto*/, displayclass &/*disp*/, 
+					outconvertclass &/*outconvert*/, ostream &/*textout*/, 
+					ostream &/*logout*/) {
+  return 0;
+}
+
+int browserclass::output_section_group (FilterResponse_t &/*sections*/, cgiargsclass &/*args*/,
+					const text_t& /*currentSection*/, const text_t &/*labels*/, const text_t &/*collection*/, int /*colnumber*/, 
+					format_t * /*formatlistptr*/, bool /*use_table*/, 
+					text_tset &/*metadata*/, bool &/*getParents*/,
+					recptproto * /*collectproto*/, displayclass &/*disp*/, 
+					outconvertclass &/*outconvert*/, ostream &/*textout*/, 
+					ostream &/*logout*/)
+{
+  return 0;
+}
+
+bool operator==(const browserptr &x, const browserptr &y) {
+  return (x.b == y.b);
+}
+
+bool operator<(const browserptr &x, const browserptr &y) {
+  return (x.b < y.b);
+}
+
+// thebrowserclass remains the property of the calling code but
+// should not be deleted until it is removed from this list.
+void browsermapclass::addbrowser (browserclass *thebrowserclass) {
+  // can't add a null browserclass
+  assert (thebrowserclass != NULL);
+  if (thebrowserclass == NULL) return;
+  
+  // can't add a browserclass with no name
+  assert (!(thebrowserclass->get_browser_name()).empty());
+  if ((thebrowserclass->get_browser_name()).empty()) return;
+
+  browserptr aptr;
+  aptr.b = thebrowserclass;
+  browserptrs[thebrowserclass->get_browser_name()] = aptr;
+}
+
+// getbrowser will return the default browser if the browser 
+// could not be found
+browserclass *browsermapclass::getbrowser (const text_t &key) {
+  // can't find a browser with no name
+  if (key.empty()) return get_default_browser();
+
+  iterator here = browserptrs.find (key);
+  if (here == browserptrs.end()) return get_default_browser();
+  
+  return (*here).second.b;
+}
+
+browserclass *browsermapclass::clonebrowser (const text_t &key) {
+  browserclass *browser = NULL;
+  if (key.empty()) {
+    browser = get_default_browser();
+  } else {
+    iterator here = browserptrs.find (key);
+    if (here == browserptrs.end()) 
+      browser = get_default_browser();
+    else
+      browser = here->second.b;
+  }
+  if (browser != NULL) {
+    browser = browser->clone();
+  }
+  return browser;
+}
+
+void browsermapclass::setdefaultbrowser (const text_t &browsername) {
+  defaultbrowser = browsername;
+}
+
+browserclass *browsermapclass::get_default_browser () {
+
+  iterator here = browserptrs.find (defaultbrowser);
+  if (here == browserptrs.end())
+    // we'll just take the first in the list if
+    // no valid default was set
+    here = browserptrs.begin();
+  return (*here).second.b;
+}
Index: /gsdl/stable/runtime-src/src/recpt/browserclass.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/browserclass.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/browserclass.h	(revision 20131)
@@ -0,0 +1,187 @@
+/**********************************************************************
+ *
+ * browserclass.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+
+#ifndef BROWSERCLASS_H
+#define BROWSERCLASS_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "cgiargs.h"
+#include "display.h"
+#include "recptproto.h"
+#include "formattools.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+#endif
+
+
+class browserclass {
+protected:
+
+public:
+  browserclass ();
+  virtual ~browserclass ();
+
+  // configure should be called once for each configuration line
+  virtual void configure (const text_t &key, const text_tarray &cfgline);
+
+  // init should be called after all the configuration is done but
+  // before any other methods are called
+  virtual bool init (ostream &logout);
+
+  virtual browserclass* clone() = 0;
+
+  // returns the name that specifies the browserclass type
+  virtual text_t get_browser_name ();
+  
+  virtual void processOID (cgiargsclass &args, recptproto *collectproto, ostream &logout);
+  
+  // load_metadata_defaults should be called before
+  // doing protocol call to get metadata for OID to
+  // be displayed by this browserclass. it adds fields
+  // to the metadata set that are needed by browserclass
+  // during display
+  virtual void load_metadata_defaults (text_tset &metadata);
+
+  virtual text_t get_default_formatstring ();
+
+  void set_filter_options (FilterRequest_t &request, cgiargsclass &args);
+  
+  // output_section_group returns the number of tabs to add before displaying the
+  // next section group
+  // The first version takes one result of a search/query action, the
+  // second takes all the results; ResultDocInfo_t is actually a child struct
+  // of FilterResponse_t items.  The second version tends to output parts of an
+  // abstract structure (e.g. for a table of contents/classifier list, the first
+  // for an individual document
+  virtual int output_section_group (ResultDocInfo_t &section, cgiargsclass &args,
+				    const text_t &collection, int colnumber, 
+				    format_t *formatlistptr, bool use_table, 
+				    text_tset &metadata, bool &getParents,
+				    recptproto *collectproto, displayclass &disp, 
+				    outconvertclass &outconvert, ostream &textout, 
+				    ostream &logout);
+
+  virtual int output_section_group (ResultDocInfo_t &section, cgiargsclass &args,
+				    const text_t &labels, const text_t &collection, int colnumber, 
+				    format_t *formatlistptr, bool use_table, 
+				    text_tset &metadata, bool &getParents,
+				    recptproto *collectproto, displayclass &disp, 
+				    outconvertclass &outconvert, ostream &textout, 
+				    ostream &logout);
+
+  virtual int output_section_group (FilterResponse_t &sections, cgiargsclass &args,
+				    const text_t &collection, int colnumber, 
+				    format_t *formatlistptr, bool use_table, 
+				    text_tset &metadata, bool &getParents,
+				    recptproto *collectproto, displayclass &disp, 
+				    outconvertclass &outconvert, ostream &textout, 
+				    ostream &logout);
+
+  virtual int output_section_group (FilterResponse_t &sections, cgiargsclass &args,
+				    const text_t& currentSection, const text_t &labels,
+				    const text_t &collection, int colnumber, 
+				    format_t *formatlistptr, bool use_table, 
+				    text_tset &metadata, bool &getParents,
+				    recptproto *collectproto, displayclass &disp, 
+				    outconvertclass &outconvert, ostream &textout, 
+				    ostream &logout);
+};
+
+
+// The browserptr function does not 'own' the browser. The 
+// browser should be deleted by the code which created it.
+class browserptr {
+public:
+  browserclass *b;
+
+  browserptr () {b=NULL;}
+};
+
+bool operator==(const browserptr &x, const browserptr &y);
+bool operator<(const browserptr &x, const browserptr &y);
+
+typedef map<text_t, browserptr, lttext_t> browserptrmap;
+
+// contains a list of browsers indexed by their name
+class browsermapclass {
+protected:
+  browserptrmap browserptrs;
+  text_t defaultbrowser;
+
+public:
+  // type support for browserptrmap
+  typedef browserptrmap::iterator iterator;
+  typedef browserptrmap::const_iterator const_iterator;
+  typedef browserptrmap::reference reference;
+  typedef browserptrmap::const_reference const_reference;
+  typedef browserptrmap::size_type size_type;
+
+  typedef browserptrmap::difference_type difference_type;
+  typedef browserptrmap::const_reverse_iterator const_reverse_iterator;
+  typedef browserptrmap::reverse_iterator reverse_iterator;
+  
+  // basic container support
+  iterator begin () {return browserptrs.begin();}
+  const_iterator begin () const {return browserptrs.begin();}
+  iterator end () {return browserptrs.end();}
+  const_iterator end () const {return browserptrs.end();}
+
+  void erase(iterator pos) {browserptrs.erase(pos);}
+  void erase(iterator first, iterator last) {browserptrs.erase(first, last);}
+  browsermapclass &operator=(const browsermapclass &x) {browserptrs=x.browserptrs;return *this;}
+
+  bool empty () const {return browserptrs.empty();}
+  size_type size() const {return browserptrs.size();}
+
+
+  // added functionality
+  void clear () {browserptrs.erase(browserptrs.begin(),browserptrs.end());}
+
+  // thebrowserclass remains the property of the calling code but
+  // should not be deleted until it is removed from this list.
+  void addbrowser (browserclass *thebrowserclass);
+
+  // getbrowser will return NULL if the browser could not be found
+  browserclass *getbrowser (const text_t &key);
+
+  // clone a browser; if not default and browser not found will return NULL
+  browserclass *clonebrowser (const text_t &key);
+
+  void setdefaultbrowser (const text_t &browsername);
+
+  browserclass *get_default_browser ();
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/browsetoolsclass.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/browsetoolsclass.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/browsetoolsclass.cpp	(revision 20131)
@@ -0,0 +1,921 @@
+
+/**********************************************************************
+ *
+ * browsetools.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+#include "browsetoolsclass.h"
+#include "recptprototools.h"
+#include "OIDtools.h"
+#include "gsdlunicode.h"
+
+#if defined(GSDL_USE_IOS_H)
+#  if defined(__WIN32__)
+#    include <strstrea.h> // vc4
+#  else
+#    include <strstream.h>
+#  endif
+#else
+#  include <sstream>
+#endif
+
+
+browsetoolsclass::browsetoolsclass()
+{
+}
+
+browsetoolsclass::~browsetoolsclass()
+{
+}
+
+// output_controls displays the detach, expand/contract contents,
+// expand/contract text and highlighting/no highlighting buttons
+
+void browsetoolsclass::output_controls(cgiargsclass &args, const text_tarray &ibuttons,
+                                       recptproto *collectproto, displayclass &disp, 
+                                       outconvertclass &outconvert, ostream &textout, 
+                                       ostream &logout)
+{
+  if (args["u"] != "1") {
+    
+    FilterResponse_t response;
+    text_tarray metadata;
+    text_tarray buttons;
+    
+    text_tarray::const_iterator here = ibuttons.begin();
+    text_tarray::const_iterator end = ibuttons.end();
+    
+    while (here != end) {
+      
+      if (*here == "Detach")
+	buttons.push_back ("_document:imagedetach_");
+      else if(*here == "Print")
+        buttons.push_back ("_document:imageprint_"); 
+      else if (*here == "Highlight") {
+	if (args["hl"] == "1") 
+	  buttons.push_back ("_document:imagenohighlight_");
+	else 
+	  buttons.push_back ("_document:imagehighlight_");
+      } else if (*here == "Expand Contents") {
+	if (args["gc"] == "1")
+	  buttons.push_back ("_document:imagecontracttoc_");
+	else 
+	  buttons.push_back ("_document:imageexpandtoc_");
+      } else if (*here == "Expand Text") {
+	if (args.getintarg("gt"))
+	  buttons.push_back ("_document:imagecontracttext_");
+	else 
+	  buttons.push_back ("_document:imageexpandtext_");
+      }
+      ++here;
+    }
+    
+    here = buttons.begin();
+    end = buttons.end();
+    while (here != end) {
+      textout << outconvert << disp << *here;
+      ++here;
+    }
+  }
+}
+
+text_t browsetoolsclass::get_cover_image()
+{
+  return "_httpprefix_/collect/[collection]/index/assoc/{Or}{[parent(Top):archivedir],[archivedir]}/cover.jpg";
+}
+
+// at the moment this just writes out the html to display 
+// the cover image (assuming it's called cover.jpg)
+// this whole thing should be done with a call to the collection
+// server which would send a link to the cover image if there
+// was one otherwise send title, author and stuff
+void browsetoolsclass::output_cover_image(cgiargsclass &args, recptproto *collectproto, 
+                                          displayclass &disp, outconvertclass &outconvert, 
+                                          ostream &textout, ostream &logout)
+{
+  if (args["d"].empty()) return;
+  
+  textout << outconvert << disp << "_document:coverimage_";
+}
+
+void browsetoolsclass::output_titles(cgiargsclass &args, recptproto *collectproto, 
+                                     browsermapclass *browsermap, formatinfo_t &formatinfo,
+                                     displayclass &disp, outconvertclass &outconvert,
+                                     ostream &textout, ostream &logout)
+{
+  if (args["d"].empty()) return;
+  
+  text_tset metadata;
+  bool getParents;
+  FilterResponse_t response;
+
+  format_t *formatlistptr = new format_t();
+  parse_formatstring (formatinfo.DocumentHeading, formatlistptr, metadata, getParents);
+
+  if (!get_info (args["d"], args["c"], args["l"], metadata, getParents, collectproto, response, logout))
+    return;
+
+  text_tmap options;
+  if (formatinfo.AllowExtendedOptions) {
+    load_extended_options(options, args, browsermap, formatinfo, 
+			  collectproto, disp, outconvert, logout);
+  }
+  textout << outconvert << disp 
+	  << get_formatted_string (args["c"],collectproto, response.docInfo[0], disp,
+				   formatlistptr, options, logout);
+}
+
+void browsetoolsclass::recurse_contents(ResultDocInfo_t &section, cgiargsclass &args, bool fulltoc,
+                                        browserclass *bptr, text_tset &metadata, bool &getParents, 
+                                        format_t *formatlistptr, format_tmap &formatlistmap, 
+                                        formatinfo_t &formatinfo, browsermapclass *browsermap, 
+                                        int tabcount, recptproto *collectproto, displayclass &disp, 
+                                        outconvertclass &outconvert, ostream &textout, ostream &logout)
+{
+  text_t formatstring;
+
+  bool is_classify = false;
+  if (args["d"].empty() || fulltoc) is_classify = true;
+
+  // output this section 
+  bool use_table = is_table_content (formatlistptr);
+  tabcount += bptr->output_section_group (section, args, args["c"], tabcount, formatlistptr, use_table, 
+					  metadata, getParents, collectproto, disp, outconvert, 
+					  textout, logout);
+
+  text_t classification;
+  if (!is_classify) classification = "Document";
+  else get_top (args["cl"], classification);
+
+  int haschildren = section.metadata["haschildren"].values[0].getint();
+  const text_t &doctype = section.metadata["doctype"].values[0];
+  text_t classifytype = section.metadata["childtype"].values[0];
+  // HLists and DateLists are displayed as VLists when contents 
+  // are expanded, Paged documents are displayed as HLists
+  if (classifytype == "HList" || classifytype == "DateList") classifytype = "VList";
+  if (classifytype == "Paged") classifytype = "HList";
+
+  // recurse through children
+  if ((haschildren == 1) && (!is_classify || fulltoc || doctype == "classify")) {
+
+    // get browser for displaying children
+    bptr = browsermap->getbrowser (classifytype);
+    bptr->load_metadata_defaults (metadata);
+
+    // get the formatstring if there is one 
+    if (!get_formatstring (classification, classifytype, 
+			   formatinfo.formatstrings, formatstring))
+      formatstring = bptr->get_default_formatstring();
+
+    format_tmap::const_iterator it = formatlistmap.find (formatstring);
+    // check if formatlistptr is cached
+    if (it != formatlistmap.end()) formatlistptr = (*it).second;
+    else {
+      formatlistptr = new format_t();
+      parse_formatstring (formatstring, formatlistptr, metadata, getParents);
+      formatlistmap[formatstring] = formatlistptr;
+    }
+
+    FilterResponse_t tmp;
+    get_children (section.OID, args["c"], args["l"], metadata, getParents, collectproto, tmp, logout);
+    ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
+    ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
+
+    while (thisdoc != lastdoc) {
+      recurse_contents (*thisdoc, args, fulltoc, bptr, metadata, getParents, 
+			formatlistptr, formatlistmap, formatinfo, browsermap, 
+			tabcount, collectproto, disp, outconvert, textout, logout);
+      ++thisdoc;
+    }
+  }
+}
+
+
+// expanded_contents recurses through all contents. there's a special case
+// for an HList when contents are expanded (i.e. it's displayed as a VList)
+//
+// if we're inside a document we expand all contents from the top (unless
+// expand_from_current_level is true), if we're at classification level we'll just
+// expand out those contents below the current one
+
+void browsetoolsclass::expanded_contents(cgiargsclass &args, int tabcount, bool fulltoc,
+                                         browsermapclass *browsermap, formatinfo_t &formatinfo, 
+                                         recptproto *collectproto, displayclass &disp, 
+                                         outconvertclass &outconvert, ostream &textout, 
+                                         ostream &logout, bool expand_from_current_level)
+{
+  if (args["d"].empty() && args["cl"].empty()) return;
+  text_t OID;
+  
+  FilterResponse_t response;
+  bool getParents = false;
+  text_tset metadata;
+  text_t classifytype, classification, formatstring;
+
+  if (!args["d"].empty())
+    {
+      // document level
+      if (fulltoc)
+        {
+          get_top(args["cl"], OID);
+          classification = OID;
+        }
+      else 
+        {
+          classification = "Document";
+          if (expand_from_current_level)
+            {
+              OID = args["d"];
+            }
+          else
+            {
+              // Always expand document level from top, unless
+              // expand_from_current_level is true.
+              get_top(args["d"], OID);
+            }
+        }
+    }
+  else
+    {
+      // classification level
+      OID = args["cl"];
+      get_top(args["cl"], classification);
+    }
+
+  // get classifytype of this level
+  text_t tOID;
+  if (is_top(OID)) {
+    classifytype = "thistype";
+    tOID = OID;
+  } else {
+    classifytype = "childtype";
+    tOID = get_parent (OID);
+  }
+  metadata.insert (classifytype);
+
+  if (!get_info (tOID, args["c"], args["l"], metadata, getParents, collectproto, response, logout))
+    return;
+  classifytype = response.docInfo[0].metadata[classifytype].values[0];
+  // if we still don't have a classifytype we'll use the default
+  if (classifytype.empty()) {
+    browserclass *bptr = browsermap->get_default_browser ();
+    classifytype = bptr->get_browser_name ();
+  }
+
+  // HLists are displayed as VLists when contents are expanded,
+  // Paged documents are displayed as HLists
+  if (classifytype == "HList") {
+    classifytype = "VList";
+    text_t pOID = get_parent (OID);
+    if (!pOID.empty()) {
+      OID = pOID;
+      // this is assuming that top levels are always 'Invisible' !!!
+      if (is_top (OID)) classifytype = "Invisible";
+    }
+  }
+  if (classifytype == "Paged") classifytype = "HList";
+
+  metadata.erase (metadata.begin(), metadata.end());
+		  
+  // metadata elements needed by recurse_contents
+  metadata.insert ("childtype");
+  metadata.insert ("doctype");
+  metadata.insert ("haschildren");
+
+  // load up metadata array with browser defaults
+  browserclass *bptr = browsermap->getbrowser (classifytype);
+  bptr->load_metadata_defaults (metadata);
+
+  // get the formatstring if there is one or use the browsers default
+  if (!get_formatstring (classification, classifytype, 
+			 formatinfo.formatstrings, formatstring))
+    formatstring = bptr->get_default_formatstring();
+
+  format_t *formatlistptr = new format_t();
+  parse_formatstring (formatstring, formatlistptr, metadata, getParents);
+
+  // protocol call
+  if (!get_info (OID, args["c"], args["l"], metadata, getParents, collectproto, response, logout))
+    return;
+
+  format_tmap formatlistmap;
+  formatlistmap[formatstring] = formatlistptr;
+
+  recurse_contents (response.docInfo[0], args, fulltoc, bptr, metadata, 
+		    getParents, formatlistptr, formatlistmap, formatinfo, browsermap, 
+		    tabcount, collectproto, disp, outconvert, textout, logout);
+
+  // clean up format list pointers
+  format_tmap::const_iterator here = formatlistmap.begin();
+  format_tmap::const_iterator end = formatlistmap.end();
+  while (here != end) {
+    delete (*here).second;
+    ++here;
+  }
+}
+
+void browsetoolsclass::load_formatstring(const text_t &classifytype, text_tset &metadata,
+                                         bool &getParents, const text_t &classification, 
+                                         browsermapclass *browsermap, formatinfo_t &formatinfo,
+                                         format_tmap &formatlistmap)
+{
+  text_t formatstring;
+
+  // load up metadata array with browser defaults
+  browserclass *bptr = browsermap->getbrowser (classifytype);
+  bptr->load_metadata_defaults (metadata);
+
+  // get the formatstring if there is one or use the browsers default
+  if (!get_formatstring (classification, classifytype, 
+			 formatinfo.formatstrings, formatstring))
+    formatstring = bptr->get_default_formatstring();
+
+  // see if it's cached
+  format_tmap::const_iterator it = formatlistmap.find (formatstring);
+  if (it == formatlistmap.end()) {
+    format_t *formatlistptr = new format_t();
+    parse_formatstring (formatstring, formatlistptr, metadata, getParents);
+    formatlistmap[formatstring] = formatlistptr;
+  }
+}
+
+void browsetoolsclass::load_formatstrings(FilterResponse_t &response, text_tset &metadata,
+                                          bool &getParents, const text_t &classification,
+                                          browsermapclass *browsermap, formatinfo_t &formatinfo, 
+                                          format_tmap &formatlistmap)
+{
+  text_tset cache;
+
+  ResultDocInfo_tarray::iterator thisdoc = response.docInfo.begin();
+  ResultDocInfo_tarray::iterator lastdoc = response.docInfo.end();
+
+  while (thisdoc != lastdoc) {
+
+    if (is_top ((*thisdoc).OID)) {
+      load_formatstring ((*thisdoc).metadata["thistype"].values[0], metadata, 
+			 getParents, classification, browsermap, formatinfo, 
+			 formatlistmap);
+    }
+    
+    // sometimes childtype is not set - why??
+    if ((*thisdoc).metadata.find("childtype") != (*thisdoc).metadata.end()) {
+      text_t &childtype = (*thisdoc).metadata["childtype"].values[0];
+
+      text_tset::const_iterator it = cache.find (childtype);
+      if (it == cache.end()) {
+	load_formatstring (childtype, metadata, getParents, classification,
+			   browsermap, formatinfo, formatlistmap);
+	cache.insert (childtype);
+      }
+    }
+    ++thisdoc;
+  }
+}
+
+void browsetoolsclass::output_parents(FilterResponse_t &response, cgiargsclass &args, 
+                                      browsermapclass *browsermap, formatinfo_t &formatinfo, 
+                                      format_tmap &formatlistmap, const text_t &classification,
+                                      int &tabcount, text_tset &metadata, bool &getParents,
+                                      recptproto *collectproto, displayclass &disp, 
+                                      outconvertclass &outconvert, ostream &textout, 
+                                      ostream &logout)
+{
+  format_t *formatlistptr = NULL;
+  text_t classifytype, formatstring;
+  bool use_table, first = true;
+  ResultDocInfo_tarray::iterator thisparent = response.docInfo.begin();
+  ResultDocInfo_tarray::iterator lastparent = response.docInfo.end();
+  while (thisparent != lastparent) {
+
+    // get classifytype of this level
+    if (is_top ((*thisparent).OID)) classifytype = (*thisparent).metadata["thistype"].values[0];
+    else if (!first && (*(thisparent-1)).metadata.find("childtype") != (*(thisparent-1)).metadata.end()) classifytype = (*(thisparent-1)).metadata["childtype"].values[0];
+    
+    // if we still don't have a classifytype we'll use the default
+    if (classifytype.empty()) {
+      browserclass *bptr = browsermap->get_default_browser ();
+      classifytype = bptr->get_browser_name ();
+    }
+    
+    browserclass *bptr = browsermap->getbrowser (classifytype);
+
+    // get the formatstring if there is one or use the browsers default
+    if (!get_formatstring (classification, classifytype, 
+			   formatinfo.formatstrings, formatstring))
+      formatstring = bptr->get_default_formatstring();
+    
+    // see if it's cached
+    format_tmap::const_iterator it = formatlistmap.find (formatstring);
+    if (it != formatlistmap.end()) formatlistptr = (*it).second;
+    else {
+      logout << "browsetools error\n";
+      return;
+    }
+    
+    use_table = is_table_content (formatlistptr);
+    tabcount += bptr->output_section_group (*thisparent, args, args["c"], tabcount, formatlistptr, 
+					    use_table, metadata, getParents, collectproto, 
+					    disp, outconvert, textout, logout);
+    first = false;
+    ++thisparent;
+  }
+}
+
+void browsetoolsclass::contracted_contents(cgiargsclass &args, int tabcount, bool fulltoc, 
+                                           browsermapclass *browsermap, formatinfo_t &formatinfo, 
+                                           recptproto *collectproto, displayclass &disp, 
+                                           outconvertclass &outconvert, ostream &textout, 
+                                           ostream &logout)
+{
+  FilterResponse_t response;
+  text_tset metadata;
+  bool getParents = false;
+  text_t formatstring;
+  text_tarray parents;
+  text_t OID = args["d"];
+  text_t classification = "Document";
+
+  // if we're not outputting the TOC for a valid OID, then we should be giving
+  // the TOC of a classification
+  if (OID.empty()) {
+    OID = args["cl"];
+    get_top (OID, classification);
+  } 
+  // if we're to give the full TOC of a document, get the parent for the whole
+  // document now
+  else if (fulltoc)
+    get_top (args["cl"], classification);    
+
+  bool haschildren = has_children (OID, args["c"], args["l"], collectproto, logout);
+
+  if ((!args["d"].empty()) && fulltoc)
+    get_parents_array (args["cl"] + ".fc", parents);
+  if (haschildren) get_parents_array (OID + ".fc", parents);
+  else get_parents_array (OID, parents);
+
+  if (!parents.empty()) {
+    // get classifytypes of each parent
+    metadata.insert ("thistype");
+    metadata.insert ("childtype");
+    metadata.insert("mdtype");
+    
+    if (!get_info (parents, args["c"], args["l"], metadata, getParents, collectproto, response, logout))
+      return;
+    
+    // get formatstrings for all parents
+    format_tmap formatlistmap;  
+    load_formatstrings (response, metadata, getParents, classification, 
+			browsermap, formatinfo, formatlistmap);
+
+    if (!get_info (parents, args["c"], args["l"], metadata, getParents, collectproto, response, logout))
+      return;
+    
+    // display each parent
+    output_parents (response, args, browsermap, formatinfo, formatlistmap, 
+		    classification, tabcount, metadata, getParents, 
+		    collectproto, disp, outconvert, textout, logout);
+    
+    metadata.erase (metadata.begin(), metadata.end());
+    
+    // clean up cached format list pointers
+    format_tmap::const_iterator here = formatlistmap.begin();
+    format_tmap::const_iterator end = formatlistmap.end();
+    while (here != end) {
+      delete (*here).second;
+      ++here;
+    }
+  }
+
+  // get childrens classifytype
+  text_t classifytype;
+  int numparents = response.docInfo.size();
+  if (!parents.empty() && (response.docInfo[numparents-1].metadata.find("childtype") != response.docInfo[numparents-1].metadata.end()))
+    classifytype = response.docInfo[numparents-1].metadata["childtype"].values[0];
+  else {
+    // use the default
+    browserclass *bptr = browsermap->get_default_browser ();
+    classifytype = bptr->get_browser_name ();
+  }
+    
+  // load up metadata array with browser defaults
+  browserclass *bptr = browsermap->getbrowser (classifytype);
+  bptr->load_metadata_defaults (metadata);
+
+  if (classifytype == "DateList") {
+    // get the mdtype
+    text_t datelist = "Date";
+    if (!parents.empty() && (response.docInfo[0].metadata.find("mdtype") != response.docInfo[0].metadata.end())) {
+      datelist = response.docInfo[0].metadata["mdtype"].values[0];
+    }
+    args.setarg("dm", datelist);
+    text_tarray dates;
+    splitchar(datelist.begin(), datelist.end(), ',', dates);
+    text_tarray::iterator begin = dates.begin();
+    text_tarray::iterator end = dates.end();
+    while (begin!= end) {
+      metadata.insert(*begin);
+      begin++;
+    }
+    
+  }
+
+  // get the formatstring if there is one or use the browsers default
+  if (!get_formatstring (classification, classifytype, 
+			 formatinfo.formatstrings, formatstring))
+    formatstring = bptr->get_default_formatstring();
+
+  format_t *formatlistptr = new format_t();
+  parse_formatstring (formatstring, formatlistptr, metadata, getParents);
+
+  if (haschildren) 
+    get_children (OID, args["c"], args["l"], metadata, getParents,
+		  collectproto, response, logout);
+  else if (!is_top(OID)) {
+    get_children (OID + ".pr", args["c"], args["l"], metadata, getParents, 
+		  collectproto, response, logout);
+    haschildren = true;
+  }
+
+  // display children
+  if (haschildren) {
+    bool use_table = is_table_content (formatlistptr);
+    bptr->output_section_group (response, args, args["c"], tabcount, formatlistptr, use_table, 
+				metadata, getParents, collectproto, disp, outconvert, 
+				textout, logout);
+  }
+  delete formatlistptr;
+}
+
+/**
+ * This function outputs contents of a classifier to the reader
+ * including parent levels
+ */
+void browsetoolsclass::expand_show_contents(cgiargsclass &args, int tabcount, bool fulltoc,
+                                            browsermapclass *browsermap, formatinfo_t &formatinfo,
+                                            recptproto *collectproto, displayclass &disp,
+                                            outconvertclass &outconvert, ostream &textout, 
+                                            ostream &logout)
+{
+  int coloffset = 0;
+  text_tarray parents;
+  FilterResponse_t response;
+  text_t OID = args["d"];
+  if (OID.empty()) OID = args["cl"];
+
+  bool haschildren = has_children(OID, args["c"], args["l"], collectproto, logout);
+
+  // get parents list
+  if (!is_top(OID)) get_parents_array(OID, parents);
+  if (args["d"].empty() || haschildren || parents.empty()) parents.push_back(OID);
+
+  // if inside a book top title is needed
+  if (!args["d"].empty())
+    {
+      coloffset = 1;
+      text_t classification, classifytype, formatstring, topOID = parents[0];
+      text_tset metadata;
+      format_t *formatlistptr = new format_t();
+      bool use_table, getParents = false;
+		
+      get_top(args["cl"], classification);
+
+      // getting information about top OID
+      metadata.insert("thistype");
+
+      get_info(topOID, args["c"], args["l"], metadata, getParents, collectproto, response, logout);
+      if (!response.docInfo[0].metadata["thistype"].values.empty()) 
+        {
+          classifytype = response.docInfo[0].metadata["thistype"].values[0];
+        }
+
+      browserclass *bptr = browsermap->getbrowser (classifytype);
+
+      if (classifytype.empty())
+        {
+          bptr = browsermap->get_default_browser();
+        }
+
+      // get the formatstring if there is one or use the browsers default
+      if (!get_formatstring(classification, classifytype, formatinfo.formatstrings, formatstring))
+        {
+          formatstring = bptr->get_default_formatstring();
+        }
+
+      parse_formatstring(formatstring, formatlistptr, metadata, getParents);
+
+      metadata.insert("doctype");
+      metadata.insert("haschildren");
+
+      get_info(topOID, args["c"], args["l"], metadata, getParents, collectproto, response, logout);
+
+      // ouput top OID section
+      use_table = is_table_content(formatlistptr);
+      bptr->output_section_group(response.docInfo[0], args, args["c"], tabcount, formatlistptr, use_table,
+                                 metadata, getParents, collectproto, disp, outconvert, textout, logout);
+    }
+
+  recurse_contents_levels(parents, args, coloffset, tabcount, fulltoc, browsermap, 
+                          formatinfo, collectproto, disp, outconvert, textout, logout);
+}
+
+void browsetoolsclass::recurse_contents_levels(text_tarray &parents, cgiargsclass &args, int coloffset, int tabcount,
+                                               bool fulltoc, browsermapclass *browsermap, formatinfo_t &formatinfo,
+                                               recptproto *collectproto, displayclass &disp, outconvertclass &outconvert,
+                                               ostream &textout, ostream &logout)
+{
+  FilterResponse_t response;
+  text_tset metadata;
+  text_t OID, formatstring, classification, classifytype;;
+  bool use_table, getParents = false;
+  int haschildren = 0;
+  format_t *formatlistptr = new format_t();
+
+  // display children for last level
+  if (tabcount == (parents.size() - 1))
+    {
+      // setting metadata fields 
+      metadata.insert ("thistype");
+      metadata.insert ("childtype");
+      metadata.insert ("haschildren");
+
+      OID = parents[tabcount];
+      get_info(OID, args["c"], args["l"], metadata, getParents, collectproto, response, logout);
+      get_top(OID, classification);
+
+      if (!response.docInfo.empty())
+        {
+          haschildren = response.docInfo[0].metadata["haschildren"].values[0].getint();
+        }
+
+      // get childrens classifytype
+      if (!response.docInfo.empty())
+        {
+          classifytype = response.docInfo[0].metadata["childtype"].values[0];
+        }
+      else
+        {
+          // use the default
+          browserclass *bptr = browsermap->get_default_browser();
+          classifytype = bptr->get_browser_name();
+        }
+
+      // load up metadata array with browser defaults
+      browserclass *bptr = browsermap->getbrowser(classifytype);
+      bptr->load_metadata_defaults(metadata);
+
+      // get the formatstring if there is one or use the browsers default
+      if (!get_formatstring(classification, classifytype, formatinfo.formatstrings, formatstring))
+        {
+          formatstring = bptr->get_default_formatstring();
+        }
+
+      parse_formatstring(formatstring, formatlistptr, metadata, getParents);
+
+      if (haschildren) 
+        {
+          get_children(OID, args["c"], args["l"], metadata, getParents,
+                       collectproto, response, logout);
+        }
+      else if (!is_top(OID))
+        {
+          get_children(OID + ".pr", args["c"], args["l"], metadata, getParents, 
+                       collectproto, response, logout);
+          haschildren = true;
+        }
+
+      // display children
+      if (haschildren)
+        {
+          use_table = is_table_content (formatlistptr);
+          bptr->output_section_group(response, args, args["c"], coloffset + tabcount, formatlistptr, use_table, 
+                                     metadata, getParents, collectproto, disp, outconvert, textout, logout);
+        }
+    }
+  else
+    {
+      text_t pOID;
+      OID = parents[tabcount];
+      get_top(OID, classification);
+
+      // load metadata fields
+      metadata.insert("thistype");
+      metadata.insert("childtype");
+      metadata.insert("haschildren");
+      metadata.insert("doctype");
+
+      if (tabcount) pOID = parents[tabcount-1];
+      else pOID = OID;
+      get_info(pOID, args["c"], args["l"], metadata, getParents, collectproto, response, logout);
+
+      // get classifytype of this level
+      if (is_top (pOID)) classifytype = response.docInfo[0].metadata["childtype"].values[0];
+      else classifytype = response.docInfo[0].metadata["thistype"].values[0];
+
+      // if we still don't have a classifytype we'll use the default
+      if (classifytype.empty())
+        {
+          browserclass *bptr = browsermap->get_default_browser();
+          classifytype = bptr->get_browser_name();
+        }
+
+      browserclass *bptr = browsermap->getbrowser (classifytype);
+
+      // get the formatstring if there is one or use the browsers default
+      if (!get_formatstring (classification, classifytype, formatinfo.formatstrings, formatstring))
+        {
+          formatstring = bptr->get_default_formatstring();
+        }
+
+      // parse format string 
+      parse_formatstring(formatstring, formatlistptr, metadata, getParents);
+
+      use_table = is_table_content(formatlistptr);
+
+      get_children(OID, args["c"], args["l"], metadata, getParents, collectproto, response, logout);
+
+      ResultDocInfo_tarray::iterator thissibling = response.docInfo.begin();
+      ResultDocInfo_tarray::iterator lastsibling = response.docInfo.end();
+
+      while (thissibling != lastsibling)
+        {
+          bptr->output_section_group(*thissibling, args, args["c"], coloffset + tabcount, formatlistptr, 
+                                     use_table, metadata, getParents, collectproto, 
+                                     disp, outconvert, textout, logout);
+			
+          if ((*thissibling).OID == parents[tabcount+1])
+            {
+              recurse_contents_levels(parents, args, coloffset, tabcount+1, fulltoc, browsermap,
+                                      formatinfo, collectproto, disp, outconvert,textout, logout);
+            }
+          ++thissibling;
+        }
+    }
+  delete formatlistptr;
+}
+
+/**
+ * This function outputs the contents of a classifier list to the reader - 
+ * the document will in fact be empty, so this does the "real" output
+ */
+void browsetoolsclass::output_toc(cgiargsclass &args, browsermapclass *browsermap,
+                                  formatinfo_t &formatinfo, recptproto *collectproto,
+                                  displayclass &disp, outconvertclass &outconvert,
+                                  ostream &textout, ostream &logout)
+{
+  if (!args["d"].empty() && formatinfo.AllowExtendedOptions) {
+    // If AllowExtendedOptions is set and we're viewing a document,
+    // DocumentButtons, DocumentContent, and DocumentImages are effectively
+    // disabled. We just output the DocumentHeading format string and
+    // return
+    output_titles(args, collectproto, browsermap, formatinfo, disp, outconvert, textout, logout);    
+    return;
+  }
+
+  int tabcount = 0;
+  bool fulltoc = false;
+  text_t cl_top, full_toc;
+  if (args["cl"] != "search") {
+    // see if there's a FullTOC string
+    get_top (args["cl"], cl_top);
+    if (get_formatstring (cl_top, "FullTOC", formatinfo.formatstrings, full_toc))
+      if (full_toc == "true") fulltoc = true;
+  }
+  
+  // get the cover image (if there is one) and the control buttons
+  // if we're inside a book
+  if ((!fulltoc) && (!args["d"].empty())) {
+    if (formatinfo.DocumentImages) {
+      textout << outconvert << "<div class=\"heading_image\">\n";
+      output_cover_image(args, collectproto, disp, outconvert, textout, logout);
+      textout << outconvert << "</div>\n";
+    } else if (formatinfo.DocumentTitles) {
+      textout << outconvert << "<div class=\"heading_title\">\n";
+      output_titles(args, collectproto, browsermap, formatinfo, disp, outconvert, textout, logout);
+      textout << outconvert << "</div>\n";
+    }
+    textout << outconvert << "<div class=\"buttons\" id=\"toc_buttons\">\n"; 
+    if (args["u"] != "1") {
+      output_controls (args, formatinfo.DocumentButtons, collectproto, disp, 
+		       outconvert, textout, logout);
+    }
+    textout << outconvert << "</div>\n\n"; 
+  }
+
+  if (formatinfo.DocumentContents || args["d"].empty()) {
+    if (args["d"].empty()) {
+      disp.setmacro("tocopenextra", "document", "id=\"" + cl_top + "\"");
+    } else {
+      disp.setmacro("tocopenextra", "document", "");
+    }
+
+    textout << outconvert << disp << "_document:tocopen_\n";
+    if (args.getintarg("gc") == 1)
+      {
+        // expanded table of contents
+        expanded_contents(args, tabcount, fulltoc, browsermap, formatinfo, 
+                          collectproto, disp, outconvert, textout, logout, false);
+      }
+    else if (args.getintarg("gc") == 2)
+      {
+        // expand visible levels of table of contents
+        expand_show_contents(args, tabcount, fulltoc, browsermap, formatinfo,
+                             collectproto, disp, outconvert, textout, logout);
+      }
+    else
+      {
+        // contracted table of contents
+        contracted_contents(args, tabcount, fulltoc, browsermap, formatinfo, 
+                            collectproto, disp, outconvert, textout, logout);
+      }
+    textout << outconvert << disp << "_document:tocclose_\n";
+  }
+}
+
+void browsetoolsclass::load_extended_options(text_tmap &options, cgiargsclass &args, browsermapclass *browsers, 
+                                             formatinfo_t &formatinfo, recptproto *collectproto, 
+                                             displayclass &disp, outconvertclass &outconvert, ostream &logout)
+{
+  options["DocImage"] = get_cover_image();
+
+#if defined(GSDL_USE_IOS_H)
+  ostrstream *tmpstr = new ostrstream();
+#else
+  ostringstream *tmpstr = new ostringstream(ostringstream::binary);
+#endif
+
+  if (args["gc"] == "1")
+    {
+      expanded_contents(args, 0, false, browsers, formatinfo, collectproto,
+                        disp, outconvert, *tmpstr, logout, false);
+    }
+  else
+    {
+      contracted_contents(args, 0, false, browsers, formatinfo, 
+                          collectproto, disp, outconvert, *tmpstr, logout);
+    }
+#if defined(GSDL_USE_IOS_H)
+  char *t = tmpstr->str();
+  text_t tmp;
+  tmp.setcarr(t, tmpstr->pcount());
+  delete [] t;
+#else
+  text_t tmp = (char *)(tmpstr->str().c_str());
+#endif
+  int len = tmp.size();
+  char *ctmp = tmp.getcstr();
+  utf8inconvertclass utf82text_t;
+  utf82text_t.setinput(ctmp, len);
+  convertclass::status_t status;
+  utf82text_t.convert(tmp, status);
+  options["DocTOC"] = tmp;
+  delete []ctmp;
+  delete tmpstr;
+
+  options["DocumentButtonDetach"] = "_document:imagedetach_";
+  if (args["hl"] == "1")
+    {
+      options["DocumentButtonHighlight"] = "_document:imagenohighlight_";
+    }
+  else
+    {
+      options["DocumentButtonHighlight"] = "_document:imagehighlight_";
+    }
+  if (args["gc"] == "1")
+    {
+      options["DocumentButtonExpandContents"] = "_document:imagecontracttoc_";
+    }
+  else
+    {
+      options["DocumentButtonExpandContents"] = "_document:imageexpandtoc_";
+    }
+  if (args["gt"] == "1")
+    {
+      options["DocumentButtonExpandText"] = "_document:imagecontracttext_";
+    }
+  else
+    {
+      options["DocumentButtonExpandText"] = "_document:imageexpandtext_";
+    }
+}
Index: /gsdl/stable/runtime-src/src/recpt/browsetoolsclass.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/browsetoolsclass.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/browsetoolsclass.h	(revision 20131)
@@ -0,0 +1,124 @@
+/**********************************************************************
+ *
+ * browsetools.h --
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef BROWSETOOLSCLASS_H
+#define BROWSETOOLSCLASS_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "cgiargs.h"
+#include "display.h"
+#include "recptproto.h"
+#include "formattools.h"
+#include "browserclass.h"
+
+class browsetoolsclass
+{
+public:
+  
+  browsetoolsclass();
+  virtual ~browsetoolsclass();
+
+  virtual void output_toc(cgiargsclass &args, browsermapclass *browsermap,
+                          formatinfo_t &formatinfo, recptproto *collectproto,
+                          displayclass &disp, outconvertclass &outconvert,
+                          ostream &textout, ostream &logout);
+
+  virtual text_t get_cover_image();
+
+  virtual void load_extended_options(text_tmap &options, cgiargsclass &args, browsermapclass *browsers, 
+                                     formatinfo_t &formatinfo, recptproto *collectproto, 
+                                     displayclass &disp, outconvertclass &outconvert, ostream &logout);
+
+  virtual void expanded_contents(cgiargsclass &args, int tabcount, bool fulltoc,
+                                 browsermapclass *browsermap, formatinfo_t &formatinfo, 
+                                 recptproto *collectproto, displayclass &disp, 
+                                 outconvertclass &outconvert, ostream &textout, 
+                                 ostream &logout, bool expand_from_current_level);
+
+  virtual void expand_show_contents(cgiargsclass &args, int tabcount, bool fulltoc,
+                                    browsermapclass *browsermap, formatinfo_t &formatinfo, 
+                                    recptproto *collectproto, displayclass &disp, 
+                                    outconvertclass &outconvert, ostream &textout, 
+                                    ostream &logout);
+
+  virtual void contracted_contents(cgiargsclass &args, int tabcount, bool fulltoc, 
+                                   browsermapclass *browsermap, formatinfo_t &formatinfo, 
+                                   recptproto *collectproto, displayclass &disp, 
+                                   outconvertclass &outconvert, ostream &textout, 
+                                   ostream &logout);
+
+protected:
+
+  typedef map<text_t, format_t*, lttext_t> format_tmap; 
+
+  virtual void recurse_contents_levels(text_tarray &parents, cgiargsclass &args, int coloffset,
+                                       int tabcount, bool fulltoc, browsermapclass *browsermap,
+                                       formatinfo_t &formatinfo, recptproto *collectproto,
+                                       displayclass &disp, outconvertclass &outconvert,
+                                       ostream &textout, ostream &logout);
+
+  virtual void output_titles(cgiargsclass &args, recptproto *collectproto, 
+                             browsermapclass *browsermap, formatinfo_t &formatinfo,
+                             displayclass &disp, outconvertclass &outconvert,
+                             ostream &textout, ostream &logout);
+
+  virtual void output_controls(cgiargsclass &args, const text_tarray &ibuttons,
+                               recptproto *collectproto, displayclass &disp, 
+                               outconvertclass &outconvert, ostream &textout, 
+                               ostream &logout);
+  
+  virtual void output_cover_image(cgiargsclass &args, recptproto *collectproto, 
+                                  displayclass &disp, outconvertclass &outconvert, 
+                                  ostream &textout, ostream &logout);
+
+  virtual void recurse_contents(ResultDocInfo_t &section, cgiargsclass &args, bool fulltoc,
+                                browserclass *bptr, text_tset &metadata, bool &getParents, 
+                                format_t *formatlistptr, format_tmap &formatlistmap, 
+                                formatinfo_t &formatinfo, browsermapclass *browsermap, 
+                                int tabcount, recptproto *collectproto, displayclass &disp, 
+                                outconvertclass &outconvert, ostream &textout, ostream &logout);
+
+  virtual void load_formatstring(const text_t &classifytype, text_tset &metadata,
+                                 bool &getParents, const text_t &classification, 
+                                 browsermapclass *browsermap, formatinfo_t &formatinfo,
+                                 format_tmap &formatlistmap);
+
+  virtual void load_formatstrings(FilterResponse_t &response, text_tset &metadata,
+                                  bool &getParents, const text_t &classification,
+                                  browsermapclass *browsermap, formatinfo_t &formatinfo, 
+                                  format_tmap &formatlistmap);
+
+  virtual void output_parents(FilterResponse_t &response, cgiargsclass &args, 
+                              browsermapclass *browsermap, formatinfo_t &formatinfo, 
+                              format_tmap &formatlistmap, const text_t &classification,
+                              int &tabcount, text_tset &metadata, bool &getParents,
+                              recptproto *collectproto, displayclass &disp, 
+                              outconvertclass &outconvert, ostream &textout, 
+                              ostream &logout);
+};
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/cgiargs.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/cgiargs.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/cgiargs.cpp	(revision 20131)
@@ -0,0 +1,421 @@
+/**********************************************************************
+ *
+ * cgiargs.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "cgiargs.h"
+#include "gsdlunicode.h"
+
+
+
+void cgiarg_t::clear () {
+  value.clear();
+  source = program_arg;
+  fileupload.clear();
+}
+
+cgiarg_t &cgiarg_t::operator=(const cgiarg_t &x) {
+  value=x.value;
+  source=x.source;
+  return *this;
+}
+
+
+bool operator==(const cgiarg_t &x, const cgiarg_t &y) {
+  return ((x.value == y.value) && (x.source == y.source));
+}
+
+bool operator<(const cgiarg_t &x, const cgiarg_t &y) {
+  return ((x.value < y.value) ||
+	  ((x.value == y.value) && (x.source == y.source)));
+}
+
+
+void fileupload_t::clear() {
+  name.clear();
+  type.clear();
+  size = 0;
+  tmp_name.clear();
+}
+
+ostream &operator<<(ostream &outs, const fileupload_t &fu) {
+  utf8outconvertclass text_t2utf8;
+  outs << "*** fileupload\n";
+  
+  outs << text_t2utf8 << "name=" << fu.name << ", type="<< fu.type<<", size="<<fu.size<<", tmp_name="<<fu.tmp_name<<"\n";
+  return outs;
+}
+
+
+
+// constructors
+cgiargsclass::cgiargsclass () {
+}
+
+
+// this returns NULL if there isn't an entry with a value of
+// 'key' already defined
+
+void cgiargsclass::setarg (const text_t &key, const text_t &value,
+			   cgiarg_t::source_t source) {
+  cgiarg_t temparg;
+  temparg.value = value;
+  temparg.source = source;
+  args[key] = temparg;
+}
+
+void cgiargsclass::setdefaultarg (const text_t &key, const text_t &value,
+				  cgiarg_t::source_t source) {
+  if (getarg(key) == NULL) setarg (key, value, source);
+}
+
+void cgiargsclass::setintarg (const text_t &key, int value,
+			      cgiarg_t::source_t source) {
+  setarg (key, value, source);
+}
+
+void cgiargsclass::setdefaultintarg (const text_t &key, int value,
+				     cgiarg_t::source_t source) {
+  if (getarg(key) == NULL) setintarg (key, value, source);
+}
+
+void cgiargsclass::setcarg (const text_t &key, unsigned short c,
+			    cgiarg_t::source_t source) {
+  text_t t; 
+  t.push_back(c);
+  setarg(key,t, source);
+}
+
+void cgiargsclass::setdefaultcarg (const text_t &key, unsigned short c,
+				   cgiarg_t::source_t source) {
+  if (getarg(key) == NULL) setcarg (key, c, source);
+}
+
+void cgiargsclass::setargfile (const text_t &key, const fileupload_t &fileupload) {
+  iterator here = args.find (key);
+  if (here != args.end()) {
+    (*here).second.fileupload = fileupload;
+  }
+}
+
+text_t *cgiargsclass::getarg (const text_t &key) {
+  iterator here = args.find (key);
+  if (here == args.end()) return NULL;
+
+  return &((*here).second.value);
+}
+
+int cgiargsclass::getintarg (const text_t &key) {
+  text_t *text = getarg (key);
+  if (text == NULL) return 0;
+  return text->getint();
+}
+
+fileupload_t *cgiargsclass::getargfile (const text_t &key) {
+  iterator here = args.find (key);
+  if (here == args.end()) return NULL;
+  return &((*here).second.fileupload);
+}
+
+
+
+
+// stream operators to print cgi arguments for debugging purposes
+ostream &operator<<(ostream &outs, const cgiargsclass &args) {
+  utf8outconvertclass text_t2utf8;
+  cgiargsclass::const_iterator here = args.begin ();
+  cgiargsclass::const_iterator end = args.end ();
+
+  outs << "*** cgiargsclass\n";
+  
+  while (here != end) {
+    outs << text_t2utf8 << " \"" << (*here).first << "\"=\"" << 
+      (*here).second.value << "\"\n";
+    ++here;
+  }
+  outs << "\n";
+
+  return outs;
+}
+
+
+
+cgiarginfo::cgiarginfo () {
+  multiplechar = false;
+  multiplevalue = false;
+  fileupload = false;
+  defaultstatus = weak;
+  argdefault.clear();
+  savedarginfo = can;
+}
+
+
+bool operator==(const cgiarginfo &x, const cgiarginfo &y) {
+  return ((x.shortname == y.shortname) &&
+	  (x.longname == y.longname) &&
+	  (x.multiplechar == y.multiplechar) &&
+	  (x.multiplevalue == y.multiplevalue) &&
+	  (x.fileupload == y.fileupload) &&
+	  (x.defaultstatus == y.defaultstatus) &&
+	  (x.argdefault == y.argdefault) &&
+	  (x.savedarginfo == y.savedarginfo));
+}
+
+bool operator<(const cgiarginfo &x, const cgiarginfo &y) {
+  return ((x.shortname < y.shortname) ||
+	  ((x.shortname == y.shortname) &&
+	   ((x.longname < y.longname) ||
+	    ((x.longname == y.longname) &&
+	     ((x.multiplevalue < y.multiplevalue) ||
+	      ((x.multiplevalue == y.multiplevalue) &&
+	       ((x.fileupload == y.fileupload) &&
+		((x.fileupload < y.fileupload) ||
+		 ((x.multiplechar < y.multiplechar) ||
+		  ((x.multiplechar == y.multiplechar) &&
+		   ((x.defaultstatus < y.defaultstatus) ||
+		    ((x.defaultstatus == y.defaultstatus) &&
+		     ((x.argdefault < y.argdefault) ||
+		      ((x.argdefault == y.argdefault) &&
+		       ((x.savedarginfo < y.savedarginfo))))))))))))))));
+}
+
+
+// constructor
+cgiargsinfoclass::cgiargsinfoclass () {
+}
+
+// addarginfo will combine the information with the present
+// information. If name clashes were detected then the information
+// will be written to logout (or stderr) and addarginfo will return false. No
+// processing with the arguments should be done if this happens
+// as the results will be meaningless.
+bool cgiargsinfoclass::addarginfo (ostream *logout, cgiarginfo &info) {
+
+  // if info.fileupload is set certain other fields are implicitly
+  // overridden
+  if (info.fileupload) {
+    info.multiplechar = false;
+    info.defaultstatus = cgiarginfo::weak;
+    info.argdefault = "";
+    info.savedarginfo = cgiarginfo::mustnot;
+  }
+  cgiarginfo *orginfo = getarginfo (info.shortname);
+  if (orginfo == NULL) {
+    argsinfo[info.shortname] = info;
+    return true; // no clashes
+  }
+
+  if (orginfo->longname != info.longname) {
+    outconvertclass text_t2ascii;
+    if (logout != NULL) {
+      (*logout) << text_t2ascii << "Error: cgi argument name clash for argument \""
+		<< info.shortname << "\".\nOne long name was\n  \"" << orginfo->longname 
+		<< "\"\nand the other was\n  \"" << info.longname << "\".\n\n";
+    } else {
+      cerr << text_t2ascii << "Error: cgi argument name clash for argument \""
+	   << info.shortname << "\".\nOne long name was\n  \"" << orginfo->longname 
+	   << "\"\nand the other was\n  \"" << info.longname << "\".\n\n";
+    }
+    return false; // found a clash
+  }
+
+  if (orginfo->multiplevalue != info.multiplevalue) {
+    outconvertclass text_t2ascii;
+    if (logout != NULL) {
+      (*logout) << text_t2ascii << "Error: cgi argument \"" << info.shortname 
+		<< "\" was given as being a single value option\n"
+		<< "and a multiple value option.\n\n";
+    } else {
+      cerr << text_t2ascii << "Error: cgi argument \"" << info.shortname 
+		<< "\" was given as being a single value option\n"
+		<< "and a multiple value option.\n\n";
+    }
+    return false; // found a clash
+  }
+
+  if (orginfo->fileupload != info.fileupload) {
+    outconvertclass text_t2ascii;
+    if (logout != NULL) {
+      (*logout) << text_t2ascii << "Error: cgi argument \"" << info.shortname 
+		<< "\" was given as being a file upload argument\n"
+		<< "and a non file upload argument.\n\n";
+    } else {
+      cerr << text_t2ascii << "Error: cgi argument \"" << info.shortname 
+	   << "\" was given as being a file upload argument\n"
+	   << "and a non file upload argument.\n\n";
+    }
+    return false; // found a clash
+  }
+
+  if (orginfo->multiplechar != info.multiplechar) {
+    outconvertclass text_t2ascii;
+    if (logout != NULL) {
+      (*logout) << text_t2ascii << "Error: cgi argument \"" << info.shortname 
+		<< "\" was given as being a single character option\n"
+		<< "and a multiple character option.\n\n";
+    } else {
+      cerr << text_t2ascii << "Error: cgi argument \"" << info.shortname 
+	   << "\" was given as being a single character option\n"
+	   << "and a multiple character option.\n\n";
+    } 
+    return false; // found a clash
+  }
+  
+  if (!info.multiplechar && info.argdefault.size() > 1) {
+    outconvertclass text_t2ascii;
+    if (logout != NULL) {
+      (*logout) << text_t2ascii << "Error: cgi argument \"" << info.shortname
+		<< "\" was defined as being a single character option\n"
+		<< "but a multiple character default was given.\n\n";
+    } else {
+      cerr << text_t2ascii << "Error: cgi argument \"" << info.shortname
+	   << "\" was defined as being a single character option\n"
+	   << "but a multiple character default was given.\n\n";
+    }
+    return false;  // found a problem
+  }
+
+  // make sure there is no clashes in the savedarginfo
+  if ((orginfo->savedarginfo==cgiarginfo::mustnot && 
+       info.savedarginfo==cgiarginfo::must) ||
+      (orginfo->savedarginfo==cgiarginfo::must && 
+       info.savedarginfo==cgiarginfo::mustnot)) {
+    outconvertclass text_t2ascii;
+    if (logout != NULL) {
+      (*logout) << text_t2ascii << "Error: it was specified that cgi argument \"" 
+		<< info.shortname << "\" should be saved in the state\n"
+		<< "information and that it should not be save in the state information.\n\n";
+    } else {
+      cerr << text_t2ascii << "Error: it was specified that cgi argument \"" 
+	   << info.shortname << "\" should be saved in the state\n"
+	   << "information and that it should not be save in the state information.\n\n";
+    }
+    return false; // found a clash
+  }
+  // the only time orginfo->savedarginfo can change is when it is set
+  // to "can"
+  if (orginfo->savedarginfo == cgiarginfo::can) 
+    orginfo->savedarginfo = info.savedarginfo;
+
+
+  if (orginfo->defaultstatus > info.defaultstatus) {
+    return true;
+  }
+  orginfo->defaultstatus = info.defaultstatus;
+  orginfo->argdefault = info.argdefault;
+
+  return true;
+}
+
+bool cgiargsinfoclass::addarginfo (ostream *logout, cgiargsinfoclass &info) {
+  
+  iterator here = info.begin ();
+  iterator end = info.end ();
+
+  while (here != end) {
+    if (!addarginfo (NULL, (*here).second)) {
+      cerr << "returning false\n";
+      return false;
+    }
+    ++here;
+  }
+  
+  return true; // made it, no clashes
+}
+
+bool cgiargsinfoclass::addarginfo (ostream *logout, const text_t& argshortname, const text_tmap& mapinfo)
+{
+  cgiarginfo *arginfo = getarginfo (argshortname);
+  if (arginfo == NULL) {
+    arginfo = &(argsinfo[argshortname]);
+    arginfo->shortname = argshortname;
+    arginfo->defaultstatus = cgiarginfo::config;
+  }
+  text_tmap::const_iterator thisInfo = mapinfo.begin();
+  text_tmap::const_iterator endInfo = mapinfo.end();
+  while (thisInfo != endInfo) {
+    if (thisInfo->first == "longname") arginfo->longname = thisInfo->second;
+    else if (thisInfo->first == "multiplechar") arginfo->multiplechar = (thisInfo->second == "true");
+    else if (thisInfo->first == "defaultstatus") {
+      if (thisInfo->second == "none") arginfo->defaultstatus = cgiarginfo::none;
+      else if (thisInfo->second == "weak") arginfo->defaultstatus = cgiarginfo::weak;
+      else if (thisInfo->second == "good") arginfo->defaultstatus = cgiarginfo::good;
+      else if (thisInfo->second == "config") arginfo->defaultstatus = cgiarginfo::config;
+      else if (thisInfo->second == "imperative") arginfo->defaultstatus = cgiarginfo::imperative;
+    }
+    else if (thisInfo->first == "argdefault") {
+      arginfo->argdefault = thisInfo->second;
+    }
+    else if (thisInfo->first == "savedarginfo") {
+      if (thisInfo->second == "mustnot") arginfo->savedarginfo = cgiarginfo::mustnot;
+      else if (thisInfo->second == "can") arginfo->savedarginfo = cgiarginfo::can;
+      else if (thisInfo->second == "must") arginfo->savedarginfo = cgiarginfo::must;
+    } else if (logout != NULL) {
+      (*logout) << ("Invalid argument for cgiarg for " + argshortname + " (" + thisInfo->first + ")\n");
+    }
+    ++thisInfo;
+  }
+  return true;
+}
+
+bool cgiargsinfoclass::addarginfo (ostream *logout, confcgiarg_tmap& info)
+{
+  confcgiarg_tmap::const_iterator thisArg = info.begin();
+  confcgiarg_tmap::const_iterator endArg = info.end();
+  while (thisArg != endArg) {
+    if (!addarginfo(logout, thisArg->first, thisArg->second)) return false;
+    ++thisArg;
+  }
+  return true;
+}
+
+cgiarginfo *cgiargsinfoclass::getarginfo (const text_t &key) {
+  iterator here = argsinfo.find (key);
+  if (here == argsinfo.end()) return NULL;
+
+  return &((*here).second);
+}
+
+const cgiarginfo *cgiargsinfoclass::getarginfo (const text_t &key) const {
+  const_iterator here = argsinfo.find (key);
+  if (here == argsinfo.end()) return NULL;
+
+  return &((*here).second);
+}
+
+// stream operators to print cgiarginfo for debugging purposes
+ostream &operator<<(ostream &outs, const cgiargsinfoclass &argsinfo) {
+  utf8outconvertclass text_t2utf8;
+  cgiargsinfoclass::const_iterator here = argsinfo.begin ();
+  cgiargsinfoclass::const_iterator end = argsinfo.end ();
+
+  outs << "*** cgiargsinfoclass\n";
+  
+  while (here != end) {
+    outs << text_t2utf8 << (*here).first << ", ";
+    ++here;
+  }
+  outs << "\n";
+
+  return outs;
+}
Index: /gsdl/stable/runtime-src/src/recpt/cgiargs.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/cgiargs.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/cgiargs.h	(revision 20131)
@@ -0,0 +1,260 @@
+/**********************************************************************
+ *
+ * cgiargs.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef CGIARGS_H
+#define CGIARGS_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+#endif
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\map>
+#elif defined(GSDL_USE_STL_H)
+#  include <map.h>
+#else
+#  include <map>
+#endif
+
+
+// response_t is used to define what type of cgi header 
+// should be produced
+// fullcontent same as content but the action should put content-type as last header.
+enum response_t {location, content, fullcontent, undecided_location};
+
+struct fileupload_t {
+  void clear();
+  fileupload_t() {clear();}
+  
+  text_t name;
+  text_t type;
+  int size;
+  text_t tmp_name;
+};
+
+typedef map<text_t, fileupload_t, lttext_t> fileupload_tmap;
+
+struct cgiarg_t {
+  void clear ();
+  cgiarg_t () {clear();}
+  cgiarg_t &operator=(const cgiarg_t &x);
+  
+  enum source_t {default_arg, compressed_arg, cgi_arg, program_arg};
+  
+  text_t value;
+  source_t source;
+  fileupload_t fileupload;
+};
+
+ostream &operator<<(ostream &outs, const fileupload_t &fu);
+
+bool operator==(const cgiarg_t &x, const cgiarg_t &y);
+bool operator<(const cgiarg_t &x, const cgiarg_t &y);
+
+typedef map<text_t, cgiarg_t, lttext_t> cgiarg_tmap;
+typedef map<text_t, text_tmap, lttext_t> confcgiarg_tmap;
+
+// cgiargsclass is used to store a particular set
+// of cgi arguments.
+class cgiargsclass {
+protected:
+  cgiarg_tmap args;
+
+public:
+  //type support for cgiarg_tmap
+  typedef cgiarg_tmap::iterator iterator;
+  typedef cgiarg_tmap::const_iterator const_iterator;
+  typedef cgiarg_tmap::reference reference;
+  typedef cgiarg_tmap::const_reference const_reference;
+  typedef cgiarg_tmap::size_type size_type;
+  typedef cgiarg_tmap::difference_type difference_type;
+  typedef cgiarg_tmap::const_reverse_iterator const_reverse_iterator;
+  typedef cgiarg_tmap::reverse_iterator reverse_iterator;
+  
+  // constructors
+  cgiargsclass ();
+
+  // basic container support
+  iterator begin () {return args.begin();}
+  const_iterator begin () const {return args.begin();}
+  iterator end () {return args.end();}
+  const_iterator end () const {return args.end();}
+
+  void erase(iterator pos) {args.erase(pos);}
+  void erase(iterator first, iterator last) {args.erase(first, last);}
+  cgiargsclass &operator=(const cgiargsclass &x) {args=x.args;return *this;}
+
+  bool empty () const {return args.empty();}
+  size_type size() const {return args.size();}
+
+
+  // added functionality
+  void clear () {args.erase(args.begin(),args.end());}
+
+  // setdefaultarg, setdefaultintarg, and setdefaultcarg will 
+  // only set the argument if it is not already set
+  // getargs returns NULL if there isn't an entry with
+  // 'key' already defined, getintarg returns 0 if there wasn't an
+  // entry with 'key' defined and operator[] returns "" if
+  // 'key' wasn't already defined (and sets 'key'="").
+  void setarg (const text_t &key, const text_t &value,
+	       cgiarg_t::source_t source=cgiarg_t::program_arg);
+  void setdefaultarg (const text_t &key, const text_t &value,
+		      cgiarg_t::source_t source=cgiarg_t::default_arg);
+  void setintarg (const text_t &key, int value,
+		  cgiarg_t::source_t source=cgiarg_t::program_arg);
+  void setdefaultintarg (const text_t &key, int value,
+			 cgiarg_t::source_t source=cgiarg_t::default_arg);
+  void setcarg (const text_t &key, unsigned short c,
+		cgiarg_t::source_t source=cgiarg_t::program_arg);
+  void setdefaultcarg (const text_t &key, unsigned short c,
+		       cgiarg_t::source_t source=cgiarg_t::default_arg);
+  void setargfile (const text_t &key, const fileupload_t &fileupload);
+  text_t *getarg (const text_t &key);
+  int getintarg (const text_t &key);
+  fileupload_t *getargfile (const text_t &key);
+  text_t &operator[] (const text_t &key) {return args[key].value;}
+  cgiarg_t &lookupcgiarg (const text_t &key) {return args[key];}
+};
+
+// stream operators to print cgi arguments for debugging purposes
+ostream &operator<<(ostream &outs, const cgiargsclass &args);
+
+
+
+// cgiarginfo holds information relating to a cgi argument
+class cgiarginfo {
+public:
+  cgiarginfo ();
+
+  // shortname is the name used in cgi arguments
+  text_t shortname;
+
+  // longname is the name used when giving information 
+  // about the argument and to spot name duplication
+  text_t longname;
+
+  // multiplechar should be set to true if the value can be
+  // more than one character long
+  bool multiplechar;
+
+  // multiplevalue should be set to true the argument may have 
+  // multiple values (as is the case when multiple checkboxes
+  // use the same name)
+  bool multiplevalue;
+
+  // fileupload should be set if the argument is to be used to upload files
+  bool fileupload;
+
+  // defaultstatus_t indicates how good the default is when different
+  // defaults are given for one argument. "none" means there is no default
+  // (a default might be given elsewhere). "weak" is a basic guess that
+  // doesn't hold much weight, "good" is a better guess, "config" was a default
+  // given in a configuration file, and "imperative" means it must not
+  // be overriden at any costs (unless there is another "imperative"...)
+  enum defaultstatus_t {none=0, weak=1, good=2, config=3, imperative=4};
+
+  defaultstatus_t defaultstatus;
+  text_t argdefault;   // a default value
+
+  // savedarginfo_t indicates whether the argument should be saved
+  // between pages (e.g. using the compressed argument) or not. The
+  // value of an argument can change from "can" to "mustnot" and 
+  // "can" to "must" but not "mustnot" to "must" or "must" to "mustnot".
+  enum savedarginfo_t {mustnot, can, must};
+
+  savedarginfo_t savedarginfo;
+};
+
+bool operator==(const cgiarginfo &x, const cgiarginfo &y);
+bool operator<(const cgiarginfo &x, const cgiarginfo &y);
+
+typedef map<text_t, cgiarginfo, lttext_t> argsinfomap;
+
+// contains a list of cgi argument information
+class cgiargsinfoclass {
+protected:
+  argsinfomap argsinfo;
+
+public:
+  // type support for arginfomap
+  typedef argsinfomap::iterator iterator;
+  typedef argsinfomap::const_iterator const_iterator;
+  typedef argsinfomap::reference reference;
+  typedef argsinfomap::const_reference const_reference;
+  typedef argsinfomap::size_type size_type;
+  typedef argsinfomap::difference_type difference_type;
+  typedef argsinfomap::const_reverse_iterator const_reverse_iterator;
+  typedef argsinfomap::reverse_iterator reverse_iterator;
+  
+  // constructors
+  cgiargsinfoclass ();
+
+  // basic container support
+  iterator begin () {return argsinfo.begin();}
+  const_iterator begin () const {return argsinfo.begin();}
+  iterator end () {return argsinfo.end();}
+  const_iterator end () const {return argsinfo.end();}
+
+  void erase(iterator pos) {argsinfo.erase(pos);}
+  void erase(iterator first, iterator last) {argsinfo.erase(first, last);}
+  cgiargsinfoclass &operator=(const cgiargsinfoclass &x) {argsinfo=x.argsinfo;return *this;}
+
+  bool empty () const {return argsinfo.empty();}
+  size_type size() const {return argsinfo.size();}
+
+
+  // added functionality
+  void clear () {argsinfo.erase(argsinfo.begin(),argsinfo.end());}
+
+  // addarginfo will combine the information with the present
+  // information. If name clashes were detected then the information
+  // will be written to logout and addarginfo will return false. No
+  // processing with the arguments should be done if this happens
+  // as the results will be meaningless.
+  bool addarginfo (ostream *logout, cgiarginfo &info);
+  bool addarginfo (ostream *logout, cgiargsinfoclass &info);
+
+  // addarginfo will override args info with info loaded from config files
+  // if the args do not exists will be created
+  bool addarginfo (ostream *logout, const text_t& argshortname, const text_tmap& mapinfo);
+  bool addarginfo (ostream *logout, confcgiarg_tmap& info);
+
+  cgiarginfo *getarginfo (const text_t &key);
+  const cgiarginfo *getarginfo (const text_t &key) const;
+  cgiarginfo &operator[] (const text_t &key) {return argsinfo[key];}
+};
+
+ostream &operator<<(ostream &outs, const cgiargsinfoclass &argsinfo);
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/cgiutils.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/cgiutils.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/cgiutils.cpp	(revision 20131)
@@ -0,0 +1,848 @@
+/**********************************************************************
+ *
+ * cgiutils.cpp -- general cgi utilities
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "cgiutils.h"
+#include "md5.h"
+#include "fileutil.h"
+#include "gsdlunicode.h"
+#include "fileutil.h"
+#include "unitool.h" // in mg, for output_utf8_char
+#include <cstdlib>
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#  include <ospace\std\fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#  include <fstream.h>
+#else
+#  include <iostream>
+#  include <fstream>
+#endif
+
+
+static unsigned short hexdigit (unsigned short c) {
+  if (c >= '0' && c <= '9') return (c-'0');
+  if (c >= 'a' && c <= 'f') return (c-'a'+10);
+  if (c >= 'A' && c <= 'F') return (c-'A'+10);
+  return c;
+}
+
+
+static void c2hex (unsigned short c, text_t &t) {
+  t.clear();
+  
+  if (c >= 256) {
+    t = "20"; // ' '
+    return;
+  }
+  
+  unsigned short o1, o2;
+  
+  o1 = (c/16) % 16;
+  o2 = c % 16;
+  if (o1 >= 10) o1 += 'a' - 10;
+  else o1 += '0';
+  if (o2 >= 10) o2 += 'a' - 10;
+  else o2 += '0';
+  
+  t.push_back(o1);
+  t.push_back(o2);
+}
+
+static text_t::iterator getline (text_t::iterator first, 
+				 text_t::iterator last,
+				 bool include_crlf) {
+  while (first != last) {
+    if (((first+1) != last) && (*first == 13) && (*(first+1) == 10)) {
+      // found <CRLF>
+      if (include_crlf) first += 2;
+      break;
+    }
+
+    first++;
+  }
+
+  return first;
+}
+
+static void process_post_section (text_t &argname, text_t &argdata, text_t &filename, text_t &filedata,
+				  text_t &filetype, bool &isfile, text_t &argstr,
+				  fileupload_tmap &fileuploads, const text_t &gsdlhome) {
+
+  if (!argname.empty()) {
+
+    if (!isfile) {
+      // argdata includes a trailing <CRLF> that we must remove
+      if ((argdata.size() > 1) && (*(argdata.end()-2) == 13) && (*(argdata.end()-1) == 10)) {
+	argdata.erase(argdata.end()-2, argdata.end());
+      }
+      if (!argstr.empty()) argstr += "&";
+      argstr += argname + "=" + argdata;
+
+    } else if (!filename.empty()) {
+      // filedata includes a trailing <CRLF> that we must remove
+      if ((filedata.size() > 1) && (*(filedata.end()-2) == 13) && (*(filedata.end()-1) == 10)) {
+	filedata.erase(filedata.end()-2, filedata.end());
+      }
+
+      // create tmp_name for storing the file on disk
+      text_t tmp_name = md5data(filedata);
+      tmp_name = filename_cat(gsdlhome, "tmp", tmp_name);
+
+      char *tmp_name_c = tmp_name.getcstr();
+
+      // write the file data to disk
+      outconvertclass out;
+      ofstream filestream(tmp_name_c, ios::out | ios::binary);
+      filestream << out << filedata;
+      filestream.close();
+      delete tmp_name_c;
+
+      // populate the fields of a fileupload_t and put it in the
+      // fileuploads map
+      fileupload_t fu;
+      // note that filename currently may or may not include the path since
+      // some browsers (e.g. IE) include the path while others
+      // (e.g. mozilla) do not. we should probably remove the path from
+      // this field here to get a consistent value across all browsers.
+      text_t::iterator slash = findlastchar(filename.begin(), filename.end(), '\\');
+      if (slash != filename.end()) {
+	filename = substr(slash+1, filename.end());
+      }
+      fu.name = filename;
+      fu.type = filetype;
+      // size has yet to be implemented
+      fu.size = filedata.size();
+
+      fu.tmp_name = tmp_name;
+      fileuploads[argname] = fu;
+    }
+  }
+  isfile = false;
+  argname.clear();
+  argdata.clear();
+  filename.clear();
+  filedata.clear();
+  filetype.clear();
+}
+
+// parse data obtained through a CGI POST request
+text_t parse_post_data (text_t &content_type, text_t &raw_post_data, 
+			fileupload_tmap &fileuploads, const text_t &gsdlhome) {
+
+  text_t argstr;
+
+  text_t::iterator content_type_begin = content_type.begin();
+  text_t::iterator content_type_end = content_type.end();
+  if (findword(content_type_begin, content_type_end, "multipart/form-data") == content_type_end) {
+    // a simple post request
+
+    return raw_post_data;
+
+  } else {
+    // multipart/form data - may contain one or more uploaded files
+
+    /*
+      content_type should look something like the following
+        multipart/form-data; boundary=---------------------------7d411e1a50330
+	
+      while raw_post_data will be as follows
+        -----------------------------7d43e73450330CRLF
+	Content-Disposition: form-data; name="e"<CRLF>
+	<CRLF>
+	d-0testss--1-0-00---4----0--0-110--1en-Zz-1---10-about-0--00031-001utfZz-8-0<CRLF>
+	-----------------------------7d43e73450330<CRLF>
+	Content-Disposition: form-data; name="afile"; filename="C:\somedoc.doc"<CRLF>
+	Content-Type: application/msword<CRLF>
+	<CRLF>
+	<Content of file><CRLF>
+	
+    */
+
+    // first get the boundary from content-type
+    text_t::iterator boundary_begin = findword(content_type_begin, content_type_end, "boundary=");
+    if (boundary_begin+9 < content_type_end) 
+      {
+	// skip over "boundary=" part of string
+	boundary_begin += 9;
+      }
+    else {
+      // error
+      cerr << "Error: malformed boundary? '" <<  content_type << "'" << endl;
+      return "";
+    }
+    text_t boundary = substr(boundary_begin, getline(boundary_begin, content_type_end, false));
+    int boundary_len = boundary.size();
+
+
+    text_t argname, argdata, filename, filedata, filetype;
+    bool isfile = false;
+    text_t::iterator data_here = raw_post_data.begin();
+    text_t::iterator data_end = raw_post_data.end();
+    while (data_here != data_end) {
+      
+      // get the next available line (including the trailing <CRLF>
+      text_t line = substr(data_here, getline(data_here, data_end, true));
+
+      data_here += line.size();
+      text_t::iterator line_begin = line.begin();
+      text_t::iterator line_end = line.end();
+      if (findword(line_begin, line_end, boundary) != line_end) {
+	// we've found a boundary
+	process_post_section(argname, argdata, filename, filedata, filetype,
+			     isfile, argstr, fileuploads, gsdlhome);
+
+      } else if (findword(line_begin, line_end, "Content-Disposition: form-data") != line_end) {
+	// we've found the the beginning of a new section
+	argname.clear();
+	argdata.clear();
+
+	// get the name of this piece of form data
+	text_t::iterator it = findword(line_begin, line_end, "name=\"");
+	if (it == line_end) break; // error - this shouldn't happen
+	it = findchar(it, line_end, '"');
+	if ((it != line_end) && (it+1 != line_end)) {
+	  argname = substr(it+1, findchar(it+1, line_end, '"'));
+	}
+
+	// if this piece of form data contains filename="" it's a file
+	// upload and needs to be treated special
+	it = (findword(line_begin, line_end, "filename=\""));
+	if (it != line_end) {
+	  // we've found a file upload
+	  isfile = true;
+	  it = findchar(it, line_end, '"');
+	  if ((it != line_end) && (it+1 != line_end)) {
+	    filename = substr(it+1, findchar(it+1, line_end, '"'));
+	  }
+
+	  // the next line is the content-type of this section
+	  line = substr(data_here, getline(data_here, data_end, true));
+	  data_here += line.size();
+	  line_begin = line.begin();
+	  line_end = line.end();
+	  it = (findword(line_begin, line_end, "Content-Type: "));
+	  if (it != line_end) {
+	    filetype = substr(it+14, getline(it, line_end, false));
+	  }
+	}
+
+	// eat up the next line as it's just a <CRLF> on it's own
+	data_here += 2;
+
+      } else {
+	if (isfile) filedata += line;
+	else argdata += line;
+      }
+
+    }
+
+    // process last section
+    process_post_section(argname, argdata, filename, filedata, filetype,
+			 isfile, argstr, fileuploads, gsdlhome);
+
+    return argstr;
+  }
+}
+
+// convert %xx and + to their appropriate equivalents
+// IE 6.0 and later use "%u" followed by 4 hex digits... MS IIS extension!
+// NOTE: this method is crap. It assumes the input encoding is utf-8. If it 
+// actually was, then this returns utf-8, and needs to_uni on the 
+// result to get it back to unicode. If the encoding wasn't utf-8, then the 
+// output may be crap. Seems to work for 8 bit encodings.
+// Really, this should be given the encoding, and should always return unicode. 
+void decode_cgi_arg (text_t &argstr) {
+  text_t::iterator in = argstr.begin();
+  text_t::iterator out = in;
+  text_t::iterator end = argstr.end();
+  
+  while (in != end) {
+    if (*in == '+') *out = ' ';
+    
+    else if (*in == '%') {
+      unsigned short c = '%';
+      ++in;
+      if (in != end) { // this is an encoding...
+	if (*in == 'u') { // convert %uHHHH to unicode then current encoding
+	  // this assumes a short int is at least 16 bits...
+	  ++in;  
+	  if (in != end)
+	    c=hexdigit(*in++) << 12;
+	  if (in != end)
+	    c+=hexdigit(*in++) << 8;
+	  if (in != end)
+	    c+=hexdigit(*in++) << 4;
+	  if (in != end)
+	    c+=hexdigit(*in);
+	  /* BAD!! The following assumes the interface is using utf-8. But
+	     at this point we don't know what encoding we are using, unless
+	     we can parse it out of the string we are currently decoding... */
+	  text_t uni=" ";
+	  uni[0]=c;
+	  text_t utf8=to_utf8(uni);
+	  int last_byte=utf8.size()-1;
+	  for (int i=0;i<last_byte;++i)
+	    *out++ = utf8[i];
+	  c=utf8[last_byte];
+	} else {  // convert %HH to hex value
+	  c = hexdigit (*in);
+	  ++in;
+	  if (in != end && c < 16) { // sanity check on the previous character
+	    c = c*16 + hexdigit (*in);
+	  }
+	}
+      }
+      *out = c;
+    } else *out = *in;
+    
+    if (in != end) ++in;
+    ++out;
+  }
+  
+  // remove the excess characters
+  argstr.erase (out, end);
+  
+}
+
+
+// split up the cgi arguments
+void split_cgi_args (const cgiargsinfoclass &argsinfo, text_t argstr, 
+		     cgiargsclass &args) {
+  args.clear();
+  
+  text_t::const_iterator here = argstr.begin();
+  text_t::const_iterator end = argstr.end();
+  text_t key, value;
+ 
+  // extract out the key=value pairs
+  while (here != end) {
+    // get the next key and value pair
+    here = getdelimitstr (here, end, '=', key);
+    here = getdelimitstr (here, end, '&', value);
+    
+    // convert %xx and + to their appropriate equivalents
+    decode_cgi_arg (value);
+    value.setencoding(1); // other encoding
+    // store this key=value pair
+    if (!key.empty()) {
+
+      // if arg occurs multiple times (as is the case with multiple
+      // checkboxes using the same name) we'll create a comma separated
+      // list of all the values (this uses a hack that encodes naturally
+      // occurring commas as %2C - values will therefore need to be decoded
+      // again before use) - it should use an array instead
+      const cgiarginfo *info = argsinfo.getarginfo (key);
+      if (info==NULL) {
+	// If info is NULL, we can't tell if the arg is multiple value or not
+	// Because we need to have dynamically named arguments multivalued, we
+	// will always assume multiplevalue = true
+	// If the arg is not multi valued, then you need to decode the commas.
+	if (args.getarg(key)==NULL) {
+	  args.setarg (key, encode_commas(value), cgiarg_t::cgi_arg);
+	}
+	else {
+	  text_t newvalue = args[key];
+
+	  newvalue += "," + encode_commas(value);
+	  args.setarg (key, newvalue, cgiarg_t::cgi_arg);
+	}
+      }
+      else {
+	if (info->multiplevalue) {
+
+	  text_t newvalue = args[key];
+	  if (args.lookupcgiarg(key).source == cgiarg_t::cgi_arg) newvalue += ",";
+	  newvalue += encode_commas(value);
+	  args.setarg (key, newvalue, cgiarg_t::cgi_arg);
+
+	} else {
+	  args.setarg (key, value, cgiarg_t::cgi_arg);
+	}
+      }
+    }
+  }
+}
+
+text_t encode_commas (const text_t &intext) {
+
+  text_t outtext;
+
+  text_t::const_iterator here = intext.begin ();
+  text_t::const_iterator end = intext.end ();
+
+  while (here != end) {
+    if (*here == ',') outtext += "%2C";
+    else outtext.push_back (*here);
+    ++here;
+  }
+  return outtext;
+}
+
+text_t decode_commas (const text_t &intext) {
+
+  text_t outtext;
+  
+  text_t::const_iterator here = intext.begin ();
+  text_t::const_iterator end = intext.end ();
+  
+  while (here != end) {
+    if ((here+2<end) && *here == '%' && *(here+1) == '2' &&
+	(*(here+2) == 'C' || *(here+2) == 'c')) {
+      here += 2;
+      outtext.push_back(',');
+      
+    }else outtext.push_back (*here);
+    ++here;
+  }
+  return outtext;
+}
+
+// set utf8 to true if input is in utf-8, otherwise expects input in unicode
+text_t minus_safe (const text_t &intext, bool utf8) {
+
+  text_t outtext;
+
+  text_t::const_iterator here = intext.begin ();
+  text_t::const_iterator end = intext.end ();
+
+  while (here != end) {
+    if (*here == '-') outtext += "Zz-";
+    else outtext.push_back (*here);
+    ++here;
+  }
+  if (utf8) {
+    outtext = cgi_safe_utf8 (outtext);
+  } else {
+    outtext = cgi_safe_unicode (outtext);
+  }
+  return outtext;
+}
+
+// takes utf-8 input
+text_t cgi_safe_utf8 (const text_t &intext) {
+  text_t outtext;
+  
+  text_t::const_iterator here = intext.begin ();
+  text_t::const_iterator end = intext.end ();
+  unsigned short c;
+  text_t ttmp;
+  
+  while (here != end) {
+    c = *here;
+    if (((c >= 'a') && (c <= 'z')) ||
+	((c >= 'A') && (c <= 'Z')) ||
+	((c >= '0') && (c <= '9')) ||
+	(c == '%') || (c == '-')) {
+      // alphanumeric character
+      outtext.push_back(c);
+    } else if (c == ' ') {
+      // space
+      outtext.push_back('+');
+    } else if (c > 255) { // not utf-8 character
+      cerr << "WARNING: expected utf-8 char, but got unicode!!\n";
+    } else {
+      // everything else
+      outtext.push_back('%');
+      c2hex(c, ttmp);
+      outtext += ttmp;
+    }
+    
+    ++here;
+  }
+  
+  return outtext;
+}
+// takes unicode input
+text_t cgi_safe_unicode (const text_t &intext) {
+  text_t outtext;
+  
+  text_t::const_iterator here = intext.begin ();
+  text_t::const_iterator end = intext.end ();
+  unsigned short c;
+  text_t ttmp;
+  
+  while (here != end) {
+    c = *here;
+    if (((c >= 'a') && (c <= 'z')) ||
+	((c >= 'A') && (c <= 'Z')) ||
+	((c >= '0') && (c <= '9')) ||
+	(c == '%') || (c == '-')) {
+      // alphanumeric character
+      outtext.push_back(c);
+    } else if (c == ' ') {
+      // space
+      outtext.push_back('+');
+    } else if (c > 127) { // unicode character
+      unsigned char buf[3]; // up to 3 bytes
+      buf[0]='\0';buf[1]='\0';buf[2]='\0';
+      output_utf8_char(c,buf, buf+2);
+      outtext.push_back('%');
+      c2hex(buf[0], ttmp);
+      outtext += ttmp;
+      outtext.push_back('%');
+      c2hex(buf[1], ttmp);
+      outtext += ttmp;
+      if (buf[2]) {
+      outtext.push_back('%');
+      c2hex(buf[2], ttmp);
+      outtext += ttmp;
+      }
+    } else {
+      // everything else
+      outtext.push_back('%');
+      c2hex(c, ttmp);
+      outtext += ttmp;
+    }
+    
+    ++here;
+  }
+  
+  return outtext;
+}
+
+
+
+
+static text_t::const_iterator get_next_save_arg (text_t::const_iterator first, 
+					   text_t::const_iterator last,
+					   text_t &argname) {
+  first = getdelimitstr (first, last, '-', argname);
+  return first;
+}
+
+
+// check_save_conf_str checks the configuration string for
+// the saved args and makes sure it does not conflict with
+// the information about the arguments. If an error is encountered
+// it will return false and the program should not produce any
+// output.
+bool check_save_conf_str (const text_t &saveconf, 
+			  const cgiargsinfoclass &argsinfo,
+			  ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  text_tset argsset;
+  text_t::const_iterator saveconfhere = saveconf.begin ();
+  text_t::const_iterator saveconfend = saveconf.end ();
+  text_t argname;
+  const cgiarginfo *info;
+
+  // first check to make sure all saved arguments can be saved
+  
+  while (saveconfhere != saveconfend) {
+    saveconfhere = get_next_save_arg (saveconfhere, saveconfend, argname);
+
+    if (!argname.empty()) {
+      // save the argument name for later
+      argsset.insert (argname);
+
+      // check the argument
+      info =  argsinfo.getarginfo (argname);
+      if (info == NULL) {
+	logout << text_t2ascii << "Error: the cgi argument \"" << argname 
+	       << "\" is used in the configuration string for the\n"
+	       << "saved arguments but does not exist as a valid argument.\n\n";
+	return false;
+      }
+      if (info->savedarginfo == cgiarginfo::mustnot) {
+	logout << text_t2ascii << "Error: the cgi argument \"" << argname
+	       << "\" is used in the configuration string for the\n"
+	       << "saved arguments but has been specified as an argument whose\n"
+	       << "state must not be saved.\n\n";
+	return false;
+      }
+    }
+  }
+
+
+  // next check that all saved arguments that should be saved
+  // are saved
+  cgiargsinfoclass::const_iterator argsinfohere = argsinfo.begin ();
+  cgiargsinfoclass::const_iterator argsinfoend = argsinfo.end ();
+
+  while (argsinfohere != argsinfoend) {
+    if (((*argsinfohere).second.savedarginfo == cgiarginfo::must) &&
+	(argsset.find((*argsinfohere).second.shortname) == argsset.end())) {
+      logout << text_t2ascii << "Error: the cgi argument \"" 
+	     << (*argsinfohere).second.shortname << "\" was specified as needing to\n"
+	     << "be save but was not listed in the saved arguments.\n\n";
+      return false;
+    }
+
+    ++argsinfohere;
+  }
+  
+  return true; // made it, no clashes
+}
+
+
+// create_save_conf_str will create a configuration string
+// based on the information in argsinfo. This method of configuration
+// is not recomended as small changes can produce large changes in
+// the resulting configuration string (for instance a totally different
+// ordering). Only arguments which "must" be saved are included in
+// the resulting string.
+text_t create_save_conf_str (const cgiargsinfoclass &argsinfo,
+			     ostream &/*logout*/) {
+  cgiargsinfoclass::const_iterator argsinfohere = argsinfo.begin ();
+  cgiargsinfoclass::const_iterator argsinfoend = argsinfo.end ();
+  text_t saveconf;
+  bool first = true;
+
+  while (argsinfohere != argsinfoend) {
+    // save this argument if it must be saved
+    if ((*argsinfohere).second.savedarginfo == cgiarginfo::must) {
+      if (!first) saveconf.push_back ('-');
+      else first = false;
+      saveconf += (*argsinfohere).second.shortname;
+    }
+
+    ++argsinfohere;
+  }
+  
+  return saveconf;
+}
+
+
+// expand_save_args will expand the saved arguments based
+// on saveconf placing the results in args if they are not
+// already defined. If it encounters an error it will return false
+// and output more information to logout.
+bool expand_save_args (const cgiargsinfoclass &argsinfo,
+		       const text_t &saveconf, 
+		       cgiargsclass &args,
+		       ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  text_t *arg_e = args.getarg("e");
+  if (arg_e == NULL) return true; // no compressed arguments
+  if (arg_e->empty()) return true; // no compressed arguments
+
+  text_t argname, argvalue;
+  const cgiarginfo *argnameinfo;
+  
+  text_t::const_iterator saveconfhere = saveconf.begin();
+  text_t::const_iterator saveconfend = saveconf.end();
+  
+  text_t::iterator arg_ebegin = arg_e->begin();
+  text_t::iterator arg_eend = arg_e->end();
+  text_t::iterator arg_ehere = arg_ebegin;
+  while (saveconfhere != saveconfend && arg_ehere != arg_eend) {
+    saveconfhere = get_next_save_arg (saveconfhere, saveconfend, argname);
+
+    if (!argname.empty()) {
+      // found another entry
+      argnameinfo = argsinfo.getarginfo (argname);
+
+      if (argnameinfo == NULL) {
+	// no information about the argument could be found
+	// we can't keep going because we don't know whether
+	// this argument is a single or multiple character value
+	logout << text_t2ascii << "Error: the cgi argument \"" << argname
+	       << "\" was specified as being a compressed argument\n"
+	       << "but no information about it could be found within the "
+	       << "cgiargsinfoclass.\n";
+	return false;
+
+      } else {
+
+	// found the argument information
+	if (argnameinfo->multiplechar) {
+	  text_t::const_iterator sav = arg_ehere;
+	  arg_ehere = getdelimitstr (arg_ehere, arg_eend, '-', argvalue);
+	  if (distance(arg_ebegin, arg_ehere) > 2) {
+	    // replace any '-' chars escaped with 'Zz'
+	    bool first = true;
+	    while ((*(arg_ehere-3) == 'Z') && (*(arg_ehere-2) == 'z')) {
+	      if (first) argvalue.clear();
+	      arg_ehere = (findchar (arg_ehere, arg_eend, '-')) + 1;
+	      while (sav != (arg_ehere-1)) {
+		if (!((*sav == 'Z') && (*(sav+1) == 'z') && (*(sav+2) == '-')) &&
+		    !((*(sav-1) == 'Z') && (*sav == 'z') && (*(sav+1) == '-'))) argvalue.push_back (*sav);
+		++sav;
+	      }
+	      first = false;
+	    }
+	  }
+	  argvalue.setencoding(1); // other encoding
+	  if (!argvalue.empty()) args.setdefaultarg (argname, argvalue, cgiarg_t::compressed_arg);
+	} else {
+	  args.setdefaultcarg (argname,*arg_ehere, cgiarg_t::compressed_arg);
+	  ++arg_ehere;
+	}
+      }
+    }
+  }
+
+  return true;
+}
+
+
+// adds the default values for those arguments which have not
+// been specified
+void add_default_args (const cgiargsinfoclass &argsinfo,
+		       cgiargsclass &args,
+		       ostream &/*logout*/) {
+  cgiargsinfoclass::const_iterator argsinfohere = argsinfo.begin ();
+  cgiargsinfoclass::const_iterator argsinfoend = argsinfo.end ();
+
+  while (argsinfohere != argsinfoend) {
+    if ((*argsinfohere).second.defaultstatus != cgiarginfo::none) {
+      args.setdefaultarg ((*argsinfohere).second.shortname,
+			  (*argsinfohere).second.argdefault, cgiarg_t::default_arg);
+    }
+    ++argsinfohere;
+  }
+}
+
+void add_fileupload_args (const cgiargsinfoclass &argsinfo,
+			  cgiargsclass &args,
+			  fileupload_tmap &fileuploads,
+			  ostream &logout) {
+ 
+  const cgiarginfo *info = argsinfo.getarginfo("a");
+  fileupload_tmap::const_iterator this_file = fileuploads.begin();
+  fileupload_tmap::const_iterator end_file = fileuploads.end();
+  while (this_file != end_file) {
+    const cgiarginfo *info = argsinfo.getarginfo((*this_file).first);
+    if (info != NULL) {
+
+      if ((*info).fileupload && (file_exists((*this_file).second.tmp_name))) {
+
+	args.setargfile((*this_file).first, (*this_file).second);
+      }
+    }
+    this_file++;
+  }
+}
+
+// compress_save_args will compress the arguments and return
+// them in compressed_args. If an error was encountered
+// compressed_args will be set to to "", an error will be
+// written to logout, and the function will return false.
+bool compress_save_args (const cgiargsinfoclass &argsinfo,
+			 const text_t &saveconf,
+			 cgiargsclass &args,
+			 text_t &compressed_args,
+			 outconvertclass &outconvert,
+			 ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  compressed_args.clear();
+
+  text_t argname, argvalue;
+  const cgiarginfo *argnameinfo;
+  
+  text_t::const_iterator saveconfhere = saveconf.begin();
+  text_t::const_iterator saveconfend = saveconf.end();
+  
+  while (saveconfhere != saveconfend) {
+    saveconfhere = get_next_save_arg (saveconfhere, saveconfend, argname);
+
+    if (!argname.empty()) {
+      // found another entry
+      argnameinfo = argsinfo.getarginfo (argname);
+
+      if (argnameinfo == NULL) {
+	// no information about the argument could be found
+	// we can't keep going because we don't know whether
+	// this argument is a single or multiple character value
+	logout << text_t2ascii << "Error: the cgi argument \"" << argname
+	       << "\" was specified as being a compressed argument\n"
+	       << "but no information about it could be found within the "
+	       << "cgiargsinfoclass.\n";
+	compressed_args.clear();
+	return false;
+
+      } else {
+	// found the argument information
+	if (argnameinfo->multiplechar) {
+	  // multiple character argument -- sort out any '-' chars
+	  if (args["w"]=="utf-16be") // browsers don't like \0 in urls...
+	    compressed_args += minus_safe (args[argname], false);
+	  else
+	    compressed_args += minus_safe (outconvert.convert(args[argname]), true);
+	  
+	  if (saveconfhere != saveconfend) compressed_args.push_back ('-');
+
+	} else {
+	  // single character argument
+	  if (args[argname].size() == 0) {
+	    logout << text_t2ascii << "Error: the cgi argument \"" << argname
+		   << "\" was specified as being a compressed argument which\n"
+		   << "should have a one character value but it was empty.\n\n";
+	    compressed_args.clear ();
+	    return false;
+
+	  } else if (args[argname].size() > 1) {
+	    logout << text_t2ascii << "Error: the cgi argument \"" << argname
+		   << "\" was specified as being a compressed argument which\n"
+		   << "should have a one character value but it had multiple characters.\n\n";
+	    compressed_args.clear ();
+	    return false;
+	  }
+
+	  // everything is ok
+	  compressed_args += args[argname];
+	}
+      }
+    }
+  }
+
+  return true;
+}
+
+
+// args_tounicode converts any arguments which are not in unicode
+// to unicode using inconvert
+void args_tounicode (cgiargsclass &args, inconvertclass &inconvert) {
+  cgiargsclass::iterator here = args.begin();
+  cgiargsclass::iterator end = args.end();
+
+  while (here != end) {
+    if ((*here).second.value.getencoding() > 0) {
+      (*here).second.value = inconvert.convert((*here).second.value);
+    }
+    
+    ++here;
+  }
+}
+
+// fcgienv will be loaded with environment name-value pairs
+// if using fastcgi (had to do this as getenv doesn't work
+// with our implementation of fastcgi). if fcgienv is empty
+// we'll simply use getenv
+text_t gsdl_getenv (const text_t &name, text_tmap &fcgienv) {
+  if (fcgienv.empty()) {
+    char *n = name.getcstr();
+    char *v = getenv(n);
+    delete []n;
+    if (v != NULL) return v;
+    return g_EmptyText;
+
+  } else return fcgienv[name];
+}
Index: /gsdl/stable/runtime-src/src/recpt/cgiutils.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/cgiutils.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/cgiutils.h	(revision 20131)
@@ -0,0 +1,113 @@
+/**********************************************************************
+ *
+ * cgiutils.h -- general cgi utilities
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef CGIUTILS_H
+#define CGIUTILS_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "cgiargs.h"
+
+// parse data obtained through a CGI POST request
+text_t parse_post_data (text_t &content_type, text_t &raw_post_data, 
+			fileupload_tmap &fileuploads, const text_t &gsdlhome);
+
+// convert %xx and + to their appropriate equivalents
+void decode_cgi_arg (text_t &argstr);
+
+// split up the cgi arguments
+void split_cgi_args (const cgiargsinfoclass &argsinfo, text_t argstr, 
+		     cgiargsclass &args);
+
+text_t encode_commas (const text_t &intext);
+text_t decode_commas (const text_t &intext);
+
+// turns any '-' in a cgi argument into "(-)"
+// set utf8 to true if input is in utf-8, otherwise expects input in unicode
+text_t minus_safe (const text_t &intext, bool utf8);
+
+// returns the encoded version of a cgi argument
+// the original text should be in utf8
+text_t cgi_safe_utf8 (const text_t &intext);
+// the original text should be in unicode
+text_t cgi_safe_unicode (const text_t &intext);
+
+// check_save_conf_str checks the configuration string for
+// the saved args and makes sure it does not conflict with
+// the information about the arguments. If an error is encountered
+// it will return false and the program should not produce any
+// output.
+bool check_save_conf_str (const text_t &saveconf, 
+			  const cgiargsinfoclass &argsinfo,
+			  ostream &logout);
+
+// create_save_conf_str will create a configuration string
+// based on the information in argsinfo. This method of configuration
+// is not recomended as small changes can produce large changes in
+// the resulting configuration string (for instance a totally different
+// ordering). Only arguments which "must" be saved are included in
+// the resulting string.
+text_t create_save_conf_str (const cgiargsinfoclass &argsinfo,
+			     ostream &logout);
+
+// expand_compress_args will expand the compressed arguments based
+// on compressconf placing the results in args if they are not
+// already defined. If it encounters an error it will return false
+// and output more information to logout.
+bool expand_save_args (const cgiargsinfoclass &argsinfo,
+		       const text_t &saveconf, 
+		       cgiargsclass &args,
+		       ostream &logout);
+
+// adds the default values for those arguments which have not
+// been specified
+void add_default_args (const cgiargsinfoclass &argsinfo,
+		       cgiargsclass &args,
+		       ostream &logout);
+
+void add_fileupload_args (const cgiargsinfoclass &argsinfo,
+			  cgiargsclass &args,
+			  fileupload_tmap &fileuploads,
+			  ostream &logout);
+
+// compress_save_args will compress the arguments and return
+// them in compressed_args. If an error was encountered
+// compressed_args will be set to to "", an error will be
+// written to logout, and the function will return false.
+bool compress_save_args (const cgiargsinfoclass &argsinfo,
+			 const text_t &saveconf,
+			 cgiargsclass &args,
+			 text_t &compressed_args,
+			 outconvertclass &outconvert,
+			 ostream &logout);
+
+// args_tounicode converts any arguments which are not in unicode
+// to unicode using inconvert
+void args_tounicode (cgiargsclass &args, inconvertclass &inconvert);
+
+text_t gsdl_getenv (const text_t &name, text_tmap &fcgienv);
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/cgiwrapper.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/cgiwrapper.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/cgiwrapper.cpp	(revision 20131)
@@ -0,0 +1,753 @@
+/**********************************************************************
+ *
+ * cgiwrapper.cpp -- output pages using the cgi protocol
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include <stdio.h>
+#include <cstring>
+#ifdef __WIN32__
+#include <fcntl.h>
+#endif
+
+#include "gsdlconf.h"
+#include "cgiwrapper.h"
+#include "gsdlsitecfg.h"
+#include "maincfg.h"
+#include "fileutil.h"
+#include "cgiutils.h"
+#include <stdlib.h>
+#include <assert.h>
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace/std/iostream>
+#  include <ospace/std/fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#  include <fstream.h>
+#else
+#  include <iostream>
+#  include <fstream>
+#endif
+
+#ifdef USE_FASTCGI
+#include "fcgiapp.h"
+#endif
+
+
+#ifdef USE_FASTCGI
+// used to output the text from receptionist
+class fcgistreambuf : public streambuf {
+public:
+  fcgistreambuf ();
+  int sync ();
+  int overflow (int ch);
+  int underflow () {return EOF;}
+  
+  void fcgisbreset() {fcgx_stream = NULL; other_ostream = NULL;};
+  void set_fcgx_stream(FCGX_Stream *newone) {fcgx_stream=newone;};
+  void set_other_ostream(ostream *newone) {other_ostream=newone;};
+  
+private:
+  FCGX_Stream *fcgx_stream;
+  ostream *other_ostream;
+};
+
+fcgistreambuf::fcgistreambuf() {
+  fcgisbreset();
+  if (base() == ebuf()) allocate();
+  setp (base(), ebuf());
+};
+
+int fcgistreambuf::sync () {
+  if ((fcgx_stream != NULL) &&
+      (FCGX_PutStr (pbase(), out_waiting(), fcgx_stream) < 0)) {
+    fcgx_stream = NULL;
+  }
+
+  if (other_ostream != NULL) {
+    char *thepbase=pbase();
+    for (int i=0;i<out_waiting();++i) (*other_ostream).put(thepbase[i]);
+  }
+  
+  setp (pbase(), epptr());
+  
+  return 0;
+}
+
+int fcgistreambuf::overflow (int ch) {
+  if (sync () == EOF) return EOF;
+  if (ch != EOF) sputc (ch);
+  return 0;
+}
+
+#endif
+
+static void format_error_string (text_t &errorpage, const text_t &errortext, bool debug) {
+
+  errorpage.clear();
+
+  if (debug) {
+    errorpage += "\n";
+    errorpage += "ERROR: " + errortext;
+    errorpage += "\n";
+    
+  } else {
+
+    errorpage += "Content-type: text/html\n\n";
+    
+    errorpage += "<html>\n";
+    errorpage += "<head>\n";
+    errorpage += "<title>Error</title>\n";
+    errorpage += "</head>\n";
+    errorpage += "<body>\n";
+    errorpage += "<h2>Oops!</h2>\n";
+    errorpage += errortext;
+    errorpage += "</body>\n";
+    errorpage += "</html>\n";
+  }
+}
+
+static void page_errorcollect (const text_t &gsdlhome, text_t &errorpage, bool debug) {
+
+  text_t collecthome = filename_cat (gsdlhome, "collect");
+
+  text_t errortext = "No valid collections were found: Check that your collect directory\n";
+  errortext += "(" + collecthome + ") is readable and contains at least one valid collection.\n";
+  errortext += "Note that modelcol is NOT a valid collection.\n";
+  errortext += "If the path to your collect directory is wrong edit the 'gsdlhome' field\n";
+  errortext += "in your gsdlsite.cfg configuration file.\n";
+
+  format_error_string (errorpage, errortext, debug);
+}
+
+static void page_errorsitecfg (text_t &errorpage, bool debug, int mode) {
+
+  text_t errortext;
+
+  if (mode == 0) {
+    errortext += "The gsdlsite.cfg configuration file could not be found. This\n";
+    errortext += "file should contain configuration information relating to this\n";
+    errortext += "site's setup.\n";
+
+  } else if (mode == 1) {
+    errortext += "The gsdlsite.cfg configuration file does not contain a valid\n";
+    errortext += "gsdlhome entry.\n";
+  }
+
+  if (debug) {
+    errortext += "gsdlsite.cfg should reside in the directory from which the\n";
+    errortext += "library executable was run.\n";
+  } else {
+    errortext += "gsdlsite.cfg should reside in the same directory as the library\n";
+    errortext += "executable file.\n";
+  }
+
+  format_error_string (errorpage, errortext, debug);
+}
+
+
+static void page_errormaincfg (const text_t &gsdlhome, const text_t &collection,
+			       bool debug, text_t &errorpage) {
+
+  text_t errortext;
+
+  if (collection.empty()) {
+    text_t main_cfg_file = filename_cat (gsdlhome, "etc", "main.cfg");
+    errortext += "The main.cfg configuration file could not be found. This file\n";
+    errortext += "should contain configuration information relating to the\n";
+    errortext += "setup of the interface. As this receptionist is not being run\n";
+    errortext += "in collection specific mode the file should reside at\n";
+    errortext += main_cfg_file + ".\n";
+  } else {
+    text_t collect_cfg_file = filename_cat (gsdlhome, "collect", collection, "etc", "collect.cfg");
+    text_t main_collect_cfg_file = filename_cat (gsdlhome, "etc", "collect.cfg");
+    text_t main_cfg_file = filename_cat (gsdlhome, "etc", "main.cfg");
+    errortext += "Either the collect.cfg or main.cfg configuration file could\n";
+    errortext += "not be found. This file should contain configuration information\n";
+    errortext += "relating to the setup of the interface. As this receptionist is\n";
+    errortext += "being run in collection specific mode the file should reside\n";
+    errortext += "at either " + collect_cfg_file + ",\n";
+    errortext += main_collect_cfg_file + " or " + main_cfg_file + ".\n";
+  }
+
+  format_error_string (errorpage, errortext, debug);
+}
+
+
+static void page_errorinit (const text_t &gsdlhome, bool debug, text_t &errorpage) {
+
+  text_t errortext = "An error occurred during the initialisation of the Greenstone Digital\n";
+  errortext += "Library software. It is likely that the software has not been setup\n";
+  errortext += "correctly.\n";
+
+  text_t error_file = filename_cat (gsdlhome, "etc", "error.txt");
+  char *efile = error_file.getcstr();
+  ifstream errin (efile);
+  delete []efile;
+  if (errin) {
+    errortext += "The error log, " + error_file + ", contains the\n";
+    errortext += "following information:\n\n";
+    if (!debug) errortext += "<pre>\n";
+
+    char c;
+    errin.get(c);
+    while (!errin.eof ()) {
+      errortext.push_back(c);
+      errin.get(c);
+    }
+    
+    if (!debug) errortext += "</pre>\n";
+
+    errin.close();
+
+  } else {
+    errortext += "Please consult " + error_file + " for more information.\n";
+  }
+
+  format_error_string (errorpage, errortext, debug);
+}
+
+static void page_errorparseargs (const text_t &gsdlhome, bool debug, text_t &errorpage) {
+
+  text_t errortext = "An error occurred during the parsing of the cgi arguments.\n";
+
+  text_t error_file = filename_cat (gsdlhome, "etc", "error.txt");
+  char *efile = error_file.getcstr();
+  ifstream errin (efile);
+  delete []efile;
+  if (errin) {
+    errortext += "The error log, " + error_file + ", contains the\n";
+    errortext += "following information:\n\n";
+    if (!debug) errortext += "<pre>\n";
+
+    char c;
+    errin.get(c);
+    while (!errin.eof ()) {
+      errortext.push_back(c);
+      errin.get(c);
+    }
+    if (!debug) errortext += "</pre>\n";
+    errin.close();
+
+  } else {
+    errortext += "Please consult " + error_file + " for more information.\n";
+  }
+
+  format_error_string (errorpage, errortext, debug);
+}
+
+static void page_errorcgipage (const text_t &gsdlhome, bool debug, text_t &errorpage) {
+
+  text_t errortext = "An error occurred during the construction of the cgi page.\n";
+
+  text_t error_file = filename_cat (gsdlhome, "etc", "error.txt");
+  char *efile = error_file.getcstr();
+  ifstream errin (efile);
+  delete []efile;
+  if (errin) {
+    errortext += "The error log, " + error_file + ", contains the\n";
+    errortext += "following information:\n\n";
+    if (!debug) errortext += "<pre>\n";
+
+    char c;
+    errin.get(c);
+    while (!errin.eof ()) {
+      errortext.push_back(c);
+      errin.get(c);
+    }
+    if (!debug) errortext += "</pre>\n";
+    errin.close();
+
+  } else {
+    errortext += "Please consult " + error_file + " for more information.\n";
+  }
+
+  format_error_string (errorpage, errortext, debug);
+}
+
+static void print_debug_info (receptionist &recpt) {
+
+  outconvertclass text_t2ascii;
+  const recptconf &configinfo = recpt.get_configinfo ();
+  text_t etc_dir = filename_cat (configinfo.gsdlhome, "etc");
+
+  cout << "\n";
+  cout << text_t2ascii
+       << "------------------------------------------------------------\n"
+       << "Configuration and initialization completed successfully.\n"
+       << "  Note that more debug information may be available in the\n"
+       << "  initialization and error log error.txt in " << etc_dir << ".\n"
+       << "------------------------------------------------------------\n\n";
+
+  bool colspec = false;
+  if (configinfo.collection.empty()) {
+    cout << "Receptionist is running in \"general\" (i.e. not \"collection "
+	 << "specific\") mode.\n";
+  } else {
+    cout << text_t2ascii 
+	 << "Receptionist is running in \"collection specific\" mode.\n"
+	 << "  collection=" << configinfo.collection << "\n"
+	 << "  collection directory=" << configinfo.collectdir << "\n";
+    colspec = true;
+  }
+  
+  cout << text_t2ascii << "  gsdlhome=" << configinfo.gsdlhome << "\n";
+  if (!configinfo.collecthome.empty())
+    cout << text_t2ascii << "  collecthome=" << configinfo.collecthome << "\n";
+  if (!configinfo.dbhome.empty())
+    cout << text_t2ascii << "  dbhome=" << configinfo.dbhome << "\n";
+  cout << text_t2ascii << "  httpprefix=" << configinfo.httpprefix << "\n";
+  cout << text_t2ascii << "  httpweb=" << configinfo.httpweb << "\n";
+  cout << text_t2ascii << "  gwcgi=" << configinfo.gwcgi << "\n\n"
+       << "  Note that unless gwcgi has been set from a configuration\n"
+       << "  file it is dependent on environment variables set by your\n"
+       << "  webserver. Therefore it may not have the same value when run\n"
+       << "  from the command line as it would be when run from your\n"
+       << "  web server.\n";
+  if (configinfo.usecookies) 
+    cout << "cookies are enabled\n";
+  else 
+    cout << "cookies are disabled\n";
+  if (configinfo.logcgiargs) 
+    cout << "logging is enabled\n";
+  else 
+    cout << "logging is disabled\n";
+  cout << "------------------------------------------------------------\n\n";
+
+  text_tset::const_iterator this_mfile = configinfo.macrofiles.begin();
+  text_tset::const_iterator end_mfile = configinfo.macrofiles.end();
+  cout << "Macro Files:\n"
+       << "------------\n";
+  text_t mfile;
+  bool found;
+  while (this_mfile != end_mfile) {
+    cout << text_t2ascii << *this_mfile;
+    int spaces = (22 - (*this_mfile).size());
+    if (spaces < 2) spaces = 2;
+    text_t outspaces;
+    for (int i = 0; i < spaces; ++i) outspaces.push_back (' ');
+    cout << text_t2ascii << outspaces;
+
+    found = false;
+    if (colspec) {
+      // collection specific - try collectdir/macros first
+      mfile = filename_cat (configinfo.collectdir, "macros", *this_mfile);
+      if (file_exists (mfile)) {
+	cout << text_t2ascii << "found (" << mfile << ")\n";
+	found = true;
+      }
+    }
+ 
+    if (!found) {
+      // try main macro directory
+      mfile = filename_cat (configinfo.gsdlhome, "macros", *this_mfile);
+      if (file_exists (mfile)) {
+	cout << text_t2ascii << "found (" << mfile << ")\n";
+	found = true;
+      }
+    }
+
+    if (!found)
+      cout << text_t2ascii << "NOT FOUND\n";
+
+    ++this_mfile;
+  }
+
+  cout << "------------------------------------------------------------\n\n"
+       << "Collections:\n"
+       << "------------\n"
+       << "  Note that collections will only appear as \"running\" if\n"
+       << "  their build.cfg files exist, are readable, contain a valid\n"
+       << "  builddate field (i.e. > 0), and are in the collection's\n"
+       << "  index directory (i.e. NOT the building directory)\n\n";
+
+  recptprotolistclass *protos = recpt.get_recptprotolist_ptr();
+  recptprotolistclass::iterator rprotolist_here = protos->begin();
+  recptprotolistclass::iterator rprotolist_end = protos->end();
+
+  bool is_z3950 = false;
+  bool found_valid_col = false;
+
+
+  while (rprotolist_here != rprotolist_end) {
+    comerror_t err;    
+    if ((*rprotolist_here).p == NULL) continue;
+    else if (is_z3950==false &&
+	     (*rprotolist_here).p->get_protocol_name(err) == "z3950proto") {
+      cout << "\nZ39.50 Servers:   (always public)\n"
+	   << "---------------\n";
+      is_z3950=true;
+    }
+
+    text_tarray collist;
+    (*rprotolist_here).p->get_collection_list (collist, err, cerr);
+    if (err == noError) {
+      text_tarray::iterator collist_here = collist.begin();
+      text_tarray::iterator collist_end = collist.end();
+      
+      while (collist_here != collist_end) {
+	
+	cout << text_t2ascii << *collist_here;
+	
+	int spaces = (22 - (*collist_here).size());
+	if (spaces < 2) spaces = 2;
+	text_t outspaces;
+	for (int i = 0; i < spaces; ++i) outspaces.push_back (' ');
+	cout << text_t2ascii << outspaces;
+	
+	  ColInfoResponse_t *cinfo = recpt.get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, cerr);
+	  if (cinfo != NULL) {
+	    if (cinfo->isPublic) cout << "public ";
+	    else cout << "private";
+
+	    if (cinfo->buildDate > 0) {
+	      cout << "   running    ";
+	      found_valid_col = true;
+	    } else {
+	      cout << "   not running";
+	    }
+	  }
+
+	  cout << "\n";
+
+	  ++collist_here;
+      }
+    }
+    is_z3950=false;
+    ++rprotolist_here;
+  } // end of while loop
+
+  if (!found_valid_col) {
+    cout << "WARNING: No \"running\" collections were found. You need to\n";
+    cout << "         build one of the above collections\n";
+  }
+
+  cout << "\n------------------------------------------------------------\n";
+  cout << "------------------------------------------------------------\n\n";
+  cout << "receptionist running in command line debug mode\n";
+  cout << "enter cgi arguments as name=value pairs (e.g. 'a=p&p=home'):\n";
+
+}
+
+// cgiwrapper does everything necessary to output a page
+// using the cgi protocol. If this is being run for a particular
+// collection then "collection" should be set, otherwise it
+// should equal "".
+void cgiwrapper (receptionist &recpt, text_t collection) {
+  int numrequests = 0;
+  bool debug = false;
+  const recptconf &configinfo = recpt.get_configinfo ();
+
+  // find out whether this is being run as a cgi-script
+  // or a fastcgi script
+#ifdef USE_FASTCGI
+  fcgistreambuf outbuf;
+  int isfastcgi = !FCGX_IsCGI();
+  FCGX_Stream *fcgiin, *fcgiout, *fcgierr;
+  FCGX_ParamArray fcgienvp;
+#else
+  int isfastcgi = 0;
+#endif
+
+  // we need gsdlhome to do fileupload stuff, so moved this configure stuff before the get argstr stuff
+  // init stuff - we can't output error pages directly with
+  // fastcgi so the pages are stored until we can output them
+  text_t errorpage;
+  outconvertclass text_t2ascii;
+
+  // set defaults
+  int maxrequests = 10000;
+  recpt.configure ("collection", collection);
+  char *script_name = getenv("SCRIPT_NAME");
+  if (script_name != NULL) recpt.configure("gwcgi", script_name);
+  else recpt.configure("gwcgi", "/gsdl");
+
+  // read in the configuration files.
+  text_t gsdlhome;
+  text_t collecthome;
+  configurator gsdlconfigurator(&recpt);
+  if (!site_cfg_read (gsdlconfigurator, gsdlhome, collecthome, maxrequests)) {
+    // couldn't find the site configuration file
+    page_errorsitecfg (errorpage, debug, 0);
+  } else if (gsdlhome.empty()) {
+    // no gsdlhome in gsdlsite.cfg
+    page_errorsitecfg (errorpage, debug, 1);
+  } else if (!directory_exists(gsdlhome)) {
+    // gsdlhome not a valid directory
+    page_errorsitecfg (errorpage, debug, 1);
+  } else if (!main_cfg_read (recpt, gsdlhome, collecthome, collection)) {
+    // couldn't find the main configuration file
+    page_errormaincfg (gsdlhome, collection, debug, errorpage);
+  } else  if (configinfo.collectinfo.empty() && false) { // commented out for corba
+    // don't have any collections
+    page_errorcollect (gsdlhome, errorpage, debug);
+  }
+
+  // set up the httpweb variable if it hasn't been defined yet
+  if (configinfo.httpweb.empty()) {
+    recpt.configure("httpweb", configinfo.httpprefix+"/web");
+  }
+  
+  // get the query string if it is not being run as a fastcgi
+  // script
+  text_t argstr = g_EmptyText;
+  fileupload_tmap fileuploads;
+  cgiargsclass args;
+  char *aURIStr;
+  if (!isfastcgi) {
+    char *request_method_str = getenv("REQUEST_METHOD");
+    char *content_length_str = getenv("CONTENT_LENGTH");
+    if (request_method_str != NULL && strcmp(request_method_str, "POST") == 0 &&
+	content_length_str != NULL)  {
+      // POST form data
+      long content_length = (content_length_str ? atoi(content_length_str) : 0);
+      if (content_length > 0) {
+#ifdef __WIN32__
+	// On Windows it is important that standard input be read in binary
+	// mode, otherwise end of line "<CR><LF>" is turned into <LF> only
+	// which breaks the MIME standard (and our parsing code!)
+
+	int result = _setmode( _fileno( stdin ), _O_BINARY );
+	if( result == -1 ) {
+	  cerr << "Warning: Failed to set standard input to binary mode." << endl;
+	  cerr << "         Parsing of multi-part MIME will most likely fail" << endl;
+	}
+#endif
+
+	long length = content_length;
+	unsigned char * buffer = new unsigned char[content_length];
+
+	int chars_read = fread(buffer,1,content_length,stdin);
+
+	if (chars_read != content_length) {
+	  cerr << "Warning: mismatch between CONTENT_LENGTH and data read from standard in" << endl;
+	}
+
+	argstr.setcarr((char *)buffer, content_length);     
+
+	text_t content_type;
+	char *content_type_str = getenv("CONTENT_TYPE");
+	if (content_type_str) content_type = content_type_str;
+	argstr = parse_post_data(content_type, argstr, fileuploads, gsdlhome);
+      }
+    } else {
+      aURIStr = getenv("QUERY_STRING");
+      if ((request_method_str != NULL && strcmp(request_method_str, "GET") == 0)
+	  || aURIStr != NULL) {
+	// GET form data
+	if (aURIStr != NULL) argstr = aURIStr;
+      } else {
+	// debugging from command line
+	debug = true;
+      }
+    }
+  }
+
+  if (debug) {
+    cout << "Configuring Greenstone...\n";
+    cout << flush;
+  }
+
+
+  if (errorpage.empty()) {
+
+    // initialise the library software
+    if (debug) {
+      cout << "Initializing...\n";
+      cout << flush;
+    }
+
+    text_t error_file = filename_cat (gsdlhome, "etc", "error.txt");
+    char *eout = error_file.getcstr();
+    ofstream errout (eout, ios::app);
+    delete []eout;
+    if (!recpt.init(errout)) {
+      // an error occurred during the initialisation
+      errout.close();
+      page_errorinit(gsdlhome, debug, errorpage);
+    }
+    errout.close();
+  }
+
+  if (debug && errorpage.empty()) {
+    // get query string from command line
+    print_debug_info (recpt);
+    char cinURIStr[1024];
+    cin.get(cinURIStr, 1024);
+    argstr = cinURIStr;
+  }
+
+  // cgi scripts only deal with one request
+  if (!isfastcgi) maxrequests = 1;
+
+  // Page-request loop. If this is not being run as a fastcgi
+  // process then only one request will be processed and then
+  // the process will exit.
+  while (numrequests < maxrequests) {
+#ifdef USE_FASTCGI
+    if (isfastcgi) {
+      if (FCGX_Accept(&fcgiin, &fcgiout, &fcgierr, &fcgienvp) < 0) break;
+
+      char *request_method_str = FCGX_GetParam ("REQUEST_METHOD", fcgienvp);
+      char *content_length_str = FCGX_GetParam ("CONTENT_LENGTH", fcgienvp);
+
+      if (request_method_str != NULL && strcmp(request_method_str, "POST") == 0 &&
+	  content_length_str != NULL)  {
+	// POST form data
+	int content_length = text_t(content_length_str).getint();
+	if (content_length > 0) {
+	  argstr.clear();
+	  int c;
+	  do {
+	    c = FCGX_GetChar (fcgiin);
+	    if (c < 0) break;
+	    argstr.push_back (c);
+	    --content_length;
+	  } while (content_length > 0);
+	}
+
+      } else {
+	// GET form data
+	aURIStr = FCGX_GetParam("QUERY_STRING", fcgienvp);
+	if (aURIStr != NULL) argstr = aURIStr;
+	else argstr = g_EmptyText;
+      }
+    }
+#endif
+
+    // get output streams ready
+#ifdef USE_FASTCGI
+    outbuf.fcgisbreset ();
+    if (isfastcgi) outbuf.set_fcgx_stream (fcgiout);
+    else outbuf.set_other_ostream (&cout);
+    ostream pageout (&outbuf);
+#else
+#define pageout cout
+#endif
+
+    // if using fastcgi we'll load environment into a map,
+    // otherwise simply pass empty map (can't get environment
+    // variables using getenv() while using FCGX versions
+    // of fastcgi - at least I can't ;-) - Stefan)
+    text_tmap fastcgienv;
+#ifdef USE_FASTCGI
+    if (isfastcgi) {
+      for(; *fcgienvp != NULL; ++fcgienvp) {
+	text_t fvalue = *fcgienvp;
+	text_t::const_iterator begin = fvalue.begin();
+	text_t::const_iterator end = fvalue.end();
+	text_t::const_iterator equals_sign = findchar (begin, end, '=');
+	if (equals_sign != end)
+	  fastcgienv[substr(begin, equals_sign)] = substr(equals_sign+1, end);
+      }
+    }
+#endif
+
+    // temporarily need to configure gwcgi here when using fastcgi as I can't
+    // get it to pass the SCRIPT_NAME environment variable to the initial 
+    // environment (if anyone can work out how to do this using the apache 
+    // server, let me know). Note that this overrides the gwcgi field in 
+    // site.cfg (which it shouldn't do) but I can't at present set gwcgi 
+    // from site.cfg as I have old receptionists laying around that wouldn't
+    // appreciate it. The following 5 lines of code should be deleted once
+    // I either a: get the server to pass SCRIPT_NAME at initialization
+    // time or b: convert all the collections using old receptionists over
+    // to this version and uncomment gwcgi in the site.cfg file -- Stefan.
+#ifdef USE_FASTCGI
+    if (isfastcgi) {
+      recpt.configure("gwcgi", fastcgienv["SCRIPT_NAME"]);
+    }
+#endif
+
+
+    // if there has been no error so far, perform the production of the
+    // output page
+    if (errorpage.empty()) {
+      text_t error_file = filename_cat (gsdlhome, "etc", "error.txt");
+      char *eout = error_file.getcstr();
+      ofstream errout (eout, ios::app);
+      delete []eout;
+
+#if defined(__WIN32__) && defined(GSDL_USE_IOS_H)
+      // old Windows compilers (VC++4.2)
+      cerr = errout;
+#else
+      // can't do this anymore according to c++ standard...
+      // cerr = errout;
+      // ... but can do this instead
+      streambuf* errbuf = cerr.rdbuf(errout.rdbuf());
+#endif
+
+      // parse the cgi arguments and produce the resulting page if there
+      // has been no errors so far
+      if (!recpt.parse_cgi_args (argstr, fileuploads, args, errout, fastcgienv)) {
+	errout.close ();
+	page_errorparseargs(gsdlhome, debug, errorpage);
+      } else {
+	// produce the output page
+
+	if (!recpt.produce_cgi_page (args, pageout, errout, fastcgienv)) {
+	  errout.close ();
+	  page_errorcgipage(gsdlhome, debug, errorpage);
+	}
+	recpt.log_cgi_args (args, errout, fastcgienv);
+	errout.close ();
+      }
+
+#if !defined(__WIN32__) || !defined(GSDL_USE_IOS_H)
+    // restore the cerr buffer
+    cerr.rdbuf(errbuf);
+#endif
+    }
+    // clean up any files that were uploaded 
+    fileupload_tmap::const_iterator this_file = fileuploads.begin();
+    fileupload_tmap::const_iterator end_file = fileuploads.end();
+    while (this_file != end_file)
+      {
+	if (file_exists((*this_file).second.tmp_name)) 
+	  {
+	    char *thefile = (*this_file).second.tmp_name.getcstr();
+	    unlink(thefile);
+	    delete [] thefile;
+	  }
+	++this_file;
+      }
+    
+    // there was an error, output the error page
+    if (!errorpage.empty()) {
+      pageout << text_t2ascii << errorpage;
+      errorpage.clear();
+      numrequests = maxrequests; // make this the last page
+    }
+    pageout << flush;
+    
+    // finish with the output streams
+#ifdef USE_FASTCGI
+    if (isfastcgi) FCGX_Finish();
+#endif
+
+    ++numrequests;
+  }
+
+  return;
+}
Index: /gsdl/stable/runtime-src/src/recpt/cgiwrapper.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/cgiwrapper.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/cgiwrapper.h	(revision 20131)
@@ -0,0 +1,44 @@
+/**********************************************************************
+ *
+ * cgiwrapper.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef CGIWRAPPER_H
+#define CGIWRAPPER_H
+
+
+#include "receptionist.h"
+
+// cgiwrapper does everything necessary to output a page
+// using the cgi protocol. If this is being run for a particular
+// collection then "collection" should be set, otherwise it
+// should equal "".
+//
+// NB: the collectset MAY NOT exist for remote protocols (e.g.
+//     the corba protocol; as references must point to a non-
+//     null instance, we must therefore use a pointer - sorry!
+void cgiwrapper (receptionist &recpt, text_t collection);
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/collectoraction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/collectoraction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/collectoraction.cpp	(revision 20131)
@@ -0,0 +1,1477 @@
+/**********************************************************************
+ *
+ * collectoraction.cpp -- 
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_COLLECTOR_ACTION
+
+// note that the collectoraction relies on having direct access to a
+// collections configuration file. this breaks the separation between
+// receptionist and collection server and so is not suitable (at least
+// in its current form) for use when collection servers are separate 
+// from the receptionist (e.g. when using the CORBA protocol).
+
+// following line required to get fstream.filedesc() on darwin (Mac OS X)
+#define _STREAM_COMPAT  1
+// required for utsname on solaris???
+#define _XOPEN_SOURCE 1
+// This was added for Solaris, but it makes things worse on Solaris for me...
+// #define _XOPEN_SOURCE_EXTENDED 1
+
+#include "collectoraction.h"
+#include "OIDtools.h"
+#include "fileutil.h"
+#include "cfgread.h"
+#include "gsdltools.h"
+#include "gsdltimes.h"
+#include "argdb.h"
+#include "cgiutils.h"
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#if !defined (__WIN32__)
+#include <sys/utsname.h>
+#include <unistd.h>
+#endif
+
+collectoraction::collectoraction () 
+  : wizardaction()
+{
+  macro_prefix = "bc1";
+
+  do_mkcol = false;
+  badsources = false;
+  failedsources.erase(failedsources.begin(), failedsources.end());
+
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "a";
+  arg_ainfo.longname = "action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "collector";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "p";
+  arg_ainfo.longname = "page";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "intro";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // temporary directory name for this collector
+  // session
+  arg_ainfo.shortname = "bc1tmp";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1fullname";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1dirname";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1contactemail";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1aboutdesc";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1clone";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1clonecol";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // set when cloning option has changed
+  arg_ainfo.shortname = "bc1clonechanged";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot; 
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // only set when one of the fields was changed in
+  // the "collection info" page
+  arg_ainfo.shortname = "bc1infochanged";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // only set when cfg file is altered from within
+  // "configure collection" page
+  arg_ainfo.shortname = "bc1cfgchanged";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "cfgfile";
+  arg_ainfo.longname = "configuration file contents";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1dodelete";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // will be set if we arrived at the "configure collection" page
+  // via the "changing an existing collection" page
+  arg_ainfo.shortname = "bc1econf";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // will be set if we arrived at the "source data" page
+  // via the "changing an existing collection" page
+  arg_ainfo.shortname = "bc1esrce";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1inputnum";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "3";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1input";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.multiplevalue = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1inputtype";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.multiplevalue = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // will be set when we've just come from the "source data" page
+  arg_ainfo.shortname = "bc1fromsrce";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.multiplevalue = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+}
+
+collectoraction::~collectoraction () {
+}
+
+
+
+bool collectoraction::check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+				     recptprotolistclass * /*protos*/, ostream &logout) {
+
+  text_t &current_page = args["p"];
+
+  // note that the "bildstatus" and "bildframe1" pages don't actually do anything
+  // functional so we don't need to worry about authenticating them (it's the 
+  // underlying "bild" page that does the building (and creates the frameset))
+  // This helps us overcome a bit of a problem we have with multiple pages trying
+  // to read from the key.gdb database at the same time.
+  if (current_page != "intro" && current_page != "bildstatus" && current_page != "bildframe1") {
+    // authenticate the user if authentication is available
+    args["uan"] = 1;
+    args["ug"] = "all-collections-editor";
+  }
+  
+  if (current_page == "new" || current_page == "existing") {
+
+    // assign (and create) a temporary directory 
+    if (assign_tmpname (args, logout)==false) {
+      // there was an error creating the tmp dir
+      message="tmpfail";
+      return true; // true because we could still parse the arguments
+    }
+
+    // clean up any old builds left laying about in the tmp directory
+    // (note that it's possible this could take some time if there's a huge
+    // partially built collecton laying about so we'll make it an asynchronous
+    // system call)
+    gsdl_system ("perl -S cleantmp.pl", false, logout);
+  }
+
+  if (current_page != "intro" && current_page != "bildstatus" && 
+      current_page != "bildframe1" && current_page != "new") {
+    // update arguments that were saved to the harddrive
+    text_tmap saved_args;
+    saved_args["bc1fullname"] = g_EmptyText;
+    saved_args["bc1contactemail"] = g_EmptyText;
+    saved_args["bc1aboutdesc"] = g_EmptyText;
+    saved_args["bc1clone"] = g_EmptyText;
+    saved_args["bc1clonecol"] = g_EmptyText;
+    saved_args["bc1inputnum"] = g_EmptyText;
+    saved_args["bc1input"] = g_EmptyText;
+    saved_args["bc1inputtype"] = g_EmptyText;
+
+    // update the argdb database with any arguments that were set
+    // by previous page
+    text_tmap::iterator here = saved_args.begin();
+    text_tmap::iterator end = saved_args.end();
+    while (here != end) {
+      if (args.lookupcgiarg((*here).first).source != cgiarg_t::default_arg) {
+	(*here).second = args[(*here).first];
+      }
+      ++here;
+    }
+
+    text_t argfile = filename_cat(gsdlhome, "tmp", args["bc1tmp"], "argdb.gdb");
+    argdb *args_on_disk = new argdb(argfile);
+    if (!args_on_disk->update_args(saved_args)) {
+      // error
+      logout << "collectoraction: argdb::update_args failed (" << argfile << ")\n";
+    }
+
+    // update args from argdb
+    saved_args.erase(saved_args.begin(), saved_args.end());
+    if (!args_on_disk->get_args(saved_args)) {
+      // error
+      logout << "collectoraction: argdb::get_args failed (" << argfile << ")\n";
+    }
+    delete args_on_disk;
+    here = saved_args.begin();
+    end = saved_args.end();
+    while (here != end) {
+      if (!(*here).second.empty()) {
+	args[(*here).first] = (*here).second;
+      }
+      ++here;
+    }
+  }
+
+  if (args["bc1infochanged"] == "1") {
+    
+    if (args["bc1dirname"].empty()) {
+      // we've just come from the "collection information" page for the 
+      // first time so we'll need to create the collection with mkcol.pl
+      // and set up bc1dirname - we do this part here instead of in do_action
+      // because the bc1dirname argument must be set to its new value before
+      // the compressedoptions macros are set.
+      args["bc1dirname"] = get_directory_name (args["bc1fullname"]);
+
+      text_t createfile = filename_cat (gsdlhome, "tmp", args["bc1tmp"], ".create");
+      if (!file_exists (createfile)) {
+	// we could do the mkcol.pl here but I guess it's nicer to do it in do_action()
+	do_mkcol = true; 
+      } else {
+	// .create file already exists but bc1dirname wasn't set ... this should only be
+	// able to occur when the "reload" (and possibly the "back" and "forward" buttons)
+	// have been used to get us here.
+	// we'll check that the bc1dirname directory exists (in case of the unlikely 
+	// possibility that get_directory_name returned a different value this time
+	// than it did originally).
+	text_t coldir = filename_cat (get_collectdir(args), args["bc1dirname"]);
+	if (!directory_exists (coldir)) {
+	  message = "reloaderror";
+	  return true;
+	}
+      }
+    } else {
+      // "collection information" has been changed after collection already exists
+      // so we'll need to update the cfg file.
+      update_cfgfile_partial (args, false, logout);
+    }
+  }
+
+  if (args["bc1cfgchanged"] == "1") {
+    // configuration file has been changed from the "configure collection"
+    // page. we need to update the file on disk and catch bc1 arguments up
+    // with changes.
+    update_cfgfile_complete (args, logout);
+  }
+  
+  if (args["bc1clonechanged"] == "1") {
+    // cloning option has been changed on "source data" page. if it was turned 
+    // on we want to create a new collect.cfg file using the bc1clonecol cfg file
+    // as a model (we'll save the old file as collect.cfg.org). if cloning was
+    // turned off we'll revert to using the collect.cfg.org file (which will need
+    // updating in case the bc1 arguments have been altered since cloning was 
+    // turned on).
+    update_cfgfile_clone (args, logout);
+
+    // if cloning has just been turned on we'll also copy the rest of the files 
+    // (excluding collect.cfg which we've already done) from the cloned collections
+    // etc directory to the new collection.
+    if (args["bc1clone"] == "1") {
+      text_t clone_etc = filename_cat(collecthome, args["bc1clonecol"], "etc");
+      text_t new_etc = filename_cat(get_collectdir(args), args["bc1dirname"], "etc");
+      text_tarray files;
+
+      if (read_dir (clone_etc, files)) {
+	text_tarray::const_iterator here = files.begin();
+	text_tarray::const_iterator end = files.end();
+	while (here != end) {
+	  if (*here != "collect.cfg" && *here != "collect.cfg.org") {
+	    file_copy (filename_cat(clone_etc, *here), filename_cat(new_etc, *here));
+	  }
+	  ++here;
+	}
+      } else {
+	outconvertclass text_t2ascii;
+	logout <<text_t2ascii << "collectoraction::check_cgiargs couldn't read from " 
+	       << clone_etc << " directory\n";
+      }
+    }
+  }
+  
+  if (current_page == "bildstatus" || current_page == "bildcancel") {
+    // if .final file exists then build has finished
+    text_t fbld = filename_cat (gsdlhome, "tmp", args["bc1tmp"], args["bc1dirname"] + ".bld.final");
+    if (file_exists (fbld)) {
+      char *fbldc = fbld.getcstr();
+      ifstream fbld_in (fbldc);
+      if (fbld_in) {
+	failcode = fbld_in.get();
+	fbld_in.close();
+	if (failcode == '0') {
+	  // success - we need to create and configure a collection server for the
+	  // newly built collection (for fastcgi and local library where
+	  // initialization isn't going to be redone when the user clicks the
+	  // "view your new collection" button
+	  create_colserver (args["bc1dirname"], logout);
+	  current_page = "bilddone";
+	}
+	else current_page = "bildfail";
+      } else {
+	// assume build failed (we shouldn't get here though ... right?)
+	current_page = "bildfail";
+      }
+      delete []fbldc;
+    }
+  }
+
+  if (args["bc1fromsrce"] == "1") {
+
+    // we've just come from the "source data" page so we need to check that
+    // input sources are valid
+    if (!check_sources(args, logout)) {
+      args["p"] = "srce";
+    }
+  }
+
+  return true;
+}
+
+void collectoraction::update_cfgfile_clone (cgiargsclass &args, ostream &logout) {
+
+  text_t tmpdir = filename_cat(gsdlhome, "tmp", args["bc1tmp"]);
+  text_t cfgfile = filename_cat(tmpdir, args["bc1dirname"], "etc", "collect.cfg");
+  if (!file_exists (cfgfile)) {
+    message = "tmpfail";
+    return;
+  }
+
+  text_t cfgfile_org = filename_cat (tmpdir, "collect.cfg.org");
+
+  if (args["bc1clone"] == "1") {
+    // cloning was turned on
+
+    text_t cfgfile_clone = filename_cat(collecthome, args["bc1clonecol"], "etc", "collect.cfg");
+    if (file_exists (cfgfile_clone)) {
+      // if .org file doesn't exist already create it
+      if (!file_exists (cfgfile_org)) {
+	if (!file_copy (cfgfile, cfgfile_org)) {
+	  message = "tmpfail";
+	  return;
+	}
+      }
+      // copy clone collections cfg file to new collection
+      if (!file_copy (cfgfile_clone, cfgfile)) {
+	message = "tmpfail";
+	return;
+      }
+      // update the new cfg file
+      update_cfgfile_partial (args, true, logout);
+      
+    } else {
+      // can't clone non-existant or read-protected collection
+      message = "clonefail";
+    }
+
+  } else {
+    // cloning has been turned off having been on at some point. the .org file
+    // should exist, if it doesn't we'll bail out and leave the user with the 
+    // cloned copy
+    if (file_exists (cfgfile_org)) {
+      // copy original back again and update it with any recent changes
+      if (file_copy (cfgfile_org, cfgfile)) {
+	update_cfgfile_partial (args, false, logout);
+      } else {
+	message = "tmpfail";
+      }
+    }
+  }
+}
+
+// update configuration file on disk to match bc1 arguments
+// there's a special case if the clone option is true as certain parts of a
+// config file should not be cloned (e.g. the iconcollection stuff)
+void collectoraction::update_cfgfile_partial (cgiargsclass &args, bool clone, ostream &logout) {
+
+  text_t cfgfile = filename_cat(get_collectdir(args), args["bc1dirname"], "etc", "collect.cfg");
+  char *cfgfilec = cfgfile.getcstr();
+
+#if defined (__WIN32__)
+  // make sure collect.cfg isn't read-only
+  _chmod (cfgfilec, _S_IREAD | _S_IWRITE);
+#endif
+
+  vector<text_tarray> cfgarray;
+
+  // read in cfg file
+  ifstream cfg_in (cfgfilec);
+  if (cfg_in) {
+    text_tarray cfgline;
+    while (read_cfg_line(cfg_in, cfgline) >= 0) {
+      if (cfgline.size () >= 2) {
+	if (cfgline[0] == "creator" || cfgline[0] == "maintainer") {
+	  cfgline[1] = args["bc1contactemail"];
+	} else if (cfgline[0] == "collectionmeta") {
+	  if (cfgline[1] == "collectionname") {
+	    cfgline[2] = args["bc1fullname"];
+	  } else if (cfgline[1] == "collectionextra") {
+	    cfgline[2] = carriage_replace (args["bc1aboutdesc"], 0);
+	  } else if (clone && (cfgline[1] == "iconcollection" ||
+			       cfgline[1] == "iconcollectionsmall")) {
+	    cfgline[2] = g_EmptyText;
+	  }
+	}
+      }
+      cfgarray.push_back (cfgline);
+    }
+    cfg_in.close();
+    
+    // now write cfg file back out
+    int fd=open(cfgfilec, O_WRONLY | O_CREAT | O_TRUNC
+#if defined(__WIN32__)
+		| O_BINARY
+#endif
+		, 432 );
+
+    if (fd != -1) {
+      // lock the file
+      int lock_val = 1;
+      GSDL_LOCK_FILE (fd);
+      if (lock_val != 0) {
+	logout << "Error: Couldn't lock file " << cfgfilec << "\n";
+	close(fd);
+	message = "tmpfail";
+	
+      } else {
+
+	vector<text_tarray>::const_iterator this_line = cfgarray.begin();
+	vector<text_tarray>::const_iterator end_line = cfgarray.end();
+	while (this_line != end_line) {
+	  write_cfg_line (fd, *this_line);
+	  ++this_line;
+	}
+	GSDL_UNLOCK_FILE (fd);
+	close(fd);
+      }
+
+    } else {
+      logout << "collectoraction::update_cfgfile_partial: unable to open "
+	     << cfgfilec << " for output\n";
+      message = "tmpfail";
+    }
+    
+  } else {
+    logout << "collectoraction::update_cfgfile_partial: unable to open "
+	   << cfgfilec << " for input\n";
+    message = "tmpfail";
+  }
+
+  delete []cfgfilec;
+}
+
+// replace configuration file on disk with that in the cfgfile argument and 
+// catch other bc1 arguments up with those the new cfgfile contains
+void collectoraction::update_cfgfile_complete (cgiargsclass &args, ostream &logout) {
+
+  text_t cfgfile = filename_cat(get_collectdir(args), args["bc1dirname"], "etc", "collect.cfg");
+  char *cfgfilec = cfgfile.getcstr();
+
+#ifdef __WIN32__
+  // make sure collect.cfg isn't read-only
+  _chmod (cfgfilec, _S_IREAD | _S_IWRITE);
+#endif
+
+  int fd=open(cfgfilec, O_WRONLY | O_CREAT | O_TRUNC
+#if defined(__WIN32__)
+	      | O_BINARY
+#endif
+	      , 432 );
+
+  if (fd) {
+    // lock the file
+    int lock_val = 1;
+    GSDL_LOCK_FILE (fd);
+    if (lock_val != 0) {
+      logout << "Error: Couldn't lock file " << cfgfilec << "\n";
+      close(fd);
+      message = "tmpfail";
+      
+    } else {
+      
+      outconvertclass text_t2ascii;
+      text_t2ascii.setinput(&args["cfgfile"]);
+      size_t buffersize=args["cfgfile"].size();
+      char *buffer=new char[buffersize];
+      buffer[0]='\n'; // just in case something goes wrong...
+      size_t num_chars;
+      convertclass::status_t status;
+      text_t2ascii.convert(buffer, buffersize, num_chars, status);
+      // ignore status - assume it is "finished" as buffer is big enough
+      write(fd, buffer, num_chars);
+      GSDL_UNLOCK_FILE (fd);
+      close(fd);
+      delete []buffer;
+      
+      // now that we've written the file we'll read it back again and
+      // update our bc1 arguments
+      ifstream cfg_in (cfgfilec);
+      if (cfg_in) {
+	text_tarray cfgline;
+	while (read_cfg_line(cfg_in, cfgline) >= 0) {
+	  if (cfgline.size () >= 2) {
+	    if (cfgline[0] == "creator") {
+	      args["bc1contactemail"] = cfgline[1];
+	    } else if (cfgline[0] == "collectionmeta") {
+	      if (cfgline[1] == "collectionname") {
+		args["bc1fullname"] = cfgline[2];
+	      } else if (cfgline[1] == "collectionextra") {
+		args["bc1aboutdesc"] = carriage_replace (cfgline[2], 1);
+	      }
+	    }
+	  }
+	}
+	cfg_in.close();
+      } else {
+	logout << "collectoraction::update_cfgfile_complete: unable to open " 
+	       << cfgfilec << " for input\n";
+	message = "tmpfail";
+      }
+    }
+  } else {
+    logout << "collectoraction::update_cfgfile_complete: unable to open " 
+	   << cfgfilec << " for output\n";
+    message = "tmpfail";
+  }
+
+  delete []cfgfilec;
+}
+
+
+// return html for buttons used in collector bar
+// color may be "green", "grey", or "yellow"
+// type may be:
+//   "info" --> "collection information" button
+//   "srce" --> "source data" button
+//   "conf" --> "configure collection" button
+//   "bild" --> "build collection" button
+//   "view" --> "view collection" button
+// if enabled is true button will be flashy rollover type and 
+// will be hyperlinked
+
+// Wendy left a comment suggesting this be move, but where to
+// was not specified.  Into wizardaction.cpp?
+
+// set the _fullnamemenu_ macro (and _warnindex_ and _selectedindex_ if
+// we're on the "srce" page)
+void collectoraction::set_fullnamemenu (displayclass &disp, cgiargsclass &args, 
+					recptprotolistclass *protos, ostream &logout) {
+
+  if (recpt == NULL) {
+    logout << "ERROR (collectoraction::set_fullnamemenu): This action does not contain\n"
+	   << "       information about any receptionists. The method set_receptionist was\n"
+	   << "       probably not called from the module which instantiated this action.\n";
+    return;
+  }
+
+  text_t &current_page = args["p"];
+  text_t currentname = args[macro_prefix+"dirname"];
+  if (current_page == "srce") currentname = args[macro_prefix + "clonecol"];
+
+  text_tarray dirnames;
+  text_tarray fullnames;
+  vector<bool> write_protected;
+  bool is_selected = false;
+  int selected_index = 0;
+  int index = 0;
+
+  recptprotolistclass::iterator rprotolist_here = protos->begin();
+  recptprotolistclass::iterator rprotolist_end = protos->end();
+  while (rprotolist_here != rprotolist_end) {
+    if ((*rprotolist_here).p != NULL) {
+
+      // don't include z39.50 collections
+      comerror_t err = noError;
+      if ((*rprotolist_here).p->get_protocol_name (err) == "z3950proto") {
+	++rprotolist_here;
+	continue;
+      }
+
+      text_tarray collist;
+      (*rprotolist_here).p->get_collection_list (collist, err, logout);
+      if (err == noError) {
+	text_tarray::iterator collist_here = collist.begin();
+	text_tarray::iterator collist_end = collist.end();
+	while (collist_here != collist_end) {
+	  ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
+	  if (cinfo != NULL) {
+	    text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]);
+	    if (collectionname.empty()) {
+	      collectionname = *collist_here;
+	    }
+	    dirnames.push_back(*collist_here);
+	    fullnames.push_back(collectionname);
+	    // check to see if the collection is writable
+	    if (collection_protected (*collist_here)) write_protected.push_back(true);
+	    else write_protected.push_back(false);
+
+	    if (*collist_here == currentname) {
+	      is_selected = true;
+	      selected_index = index; 	    
+	    }
+	    ++index;
+	  }
+	  ++collist_here;
+	}
+      }
+    }
+    ++rprotolist_here;
+  }
+
+  bool first = true;
+
+  text_t warnindex;
+  text_t fullnamemenu = "<select name=\""+macro_prefix+"dirname\" onChange=\"menuchange();\">\n";
+
+  if (current_page == "srce") {
+    fullnamemenu = "<select name=\""+macro_prefix+"clonecol\" onChange=\"menuchange();\">\n";
+    fullnamemenu += "<option value=defaultstructure";
+    if (!is_selected) fullnamemenu += " selected>";
+    else fullnamemenu.push_back('>');
+    fullnamemenu += "_collector:textdefaultstructure_\n";
+  }
+
+  fullnamemenu += "<option value=\"\"></option>\n";
+
+  for (int i = 0; i < index; ++i) {
+    // don't want write protected collections in list on "change existing
+    // collection" page
+    if (write_protected[i] && current_page == "existing") continue;
+    fullnamemenu += "<option value=\"" + dirnames[i] + "\"";
+    if ((i == 0 && !is_selected && current_page != "srce") || 
+	(is_selected && i == selected_index)) {
+      fullnamemenu += " selected";
+      ++selected_index;
+      is_selected = false;
+    }
+    fullnamemenu.push_back ('>');
+    fullnamemenu += fullnames[i];
+    fullnamemenu.push_back ('\n');
+    
+    // add to Warnindex if collection uses any dubious plugins 
+    // (if creating clone collection list)
+    if (current_page == "srce") {
+      if (first) warnindex += "0,";
+      else warnindex.push_back(',');
+      if (uses_weird_plugin (dirnames[i])) {
+	warnindex += text_t (1);
+      } else {
+	warnindex += text_t (0);
+      }
+    }
+    first = false;
+  }
+  fullnamemenu += "</select>\n";
+  text_t action_name = get_action_name();
+  disp.setmacro ("fullnamemenu", action_name, fullnamemenu);
+  if (current_page == "srce") {
+    disp.setmacro ("warnindex",action_name , warnindex);
+    disp.setmacro ("selectedindex", action_name, text_t(selected_index));
+  }
+}
+
+
+// set _sourcelist_ and _badsources_ macros
+void collectoraction::set_inputsourceboxes (displayclass &disp, cgiargsclass &args, 
+					    ostream &logout) {
+  
+  if (badsources) disp.setmacro ("badsources", "collector", "1");
+
+  text_t sourcelist = get_source_box(args["bc1input"], args["bc1inputnum"].getint(),
+				     args["bc1inputtype"]);
+
+  disp.setmacro("sourcelist", "collector", sourcelist);
+
+  // reset badsources and failedsources variables
+  badsources = false;
+  failedsources.erase(failedsources.begin(), failedsources.end());
+}
+
+text_t collectoraction::get_source_box (text_t inputarglist, int numboxes,
+					text_t inputtypelist) {
+
+  text_tarray inputvalues;
+  splitchar (inputarglist.begin(), inputarglist.end(), ',', inputvalues);
+  // remove any empty values from the end of the array
+  if (inputvalues.size()) {
+    text_tarray::iterator l = inputvalues.end() - 1;
+    text_tarray::iterator b = inputvalues.begin();
+    while ((*l).empty() && l >= b) {
+      --l;
+    }
+    inputvalues.erase(l+1, inputvalues.end());
+  }
+
+  text_tarray inputtypes;
+  splitchar (inputtypelist.begin(), inputtypelist.end(), ',', inputtypes);
+
+  int numvalues = inputvalues.size();
+  int numtypes = inputtypes.size();
+
+  text_t last = "file://";
+  text_t rv;
+  for (int i = 0; i < numboxes; ++i) {
+    rv += "<nobr><select name=\"bc1inputtype\">\n";
+    rv += "<option value=\"file://\"";
+    if ((i < numtypes && inputtypes[i] == "file://") ||
+	(numboxes == 3 && i == 0 && numvalues == 0) ||
+	(i >= 3 && i >= numvalues && last == "file://")) {
+      rv += " selected";
+      last = "file://";
+    }
+    rv += ">file://\n";
+    rv += "<option value=\"http://\"";
+    if ((i < numtypes && inputtypes[i] == "http://") ||
+	(numboxes == 3 && i == 1 && numvalues == 0) ||
+	(i >= 3 && i >= numvalues && last == "http://")) {
+      rv += " selected";
+      last = "http://";
+    }
+    rv += ">http://\n";
+    rv += "<option value=\"ftp://\"";
+    if ((i < numtypes && inputtypes[i] == "ftp://") ||
+	(numboxes == 3 && i == 2 && numvalues == 0) ||
+	(i >= 3 && i >= numvalues && last == "ftp://")) {
+      rv += " selected";
+      last = "ftp://";
+    }
+    rv += ">ftp://\n";
+    rv += "</select>\n";
+    rv += "<input type=text name=\"bc1input\" value=\"";
+    if (i < numvalues) {
+      rv += dm_safe(decode_commas(inputvalues[i]));
+    }
+    rv += "\" size=50>";
+    if (badsources) {
+      if ((i < numvalues) && (!inputvalues[i].empty())) {
+	if (failedsources[decode_commas(inputvalues[i])] == "1") {
+	  rv += "_iconcross_";
+	} else {
+	  rv += "_icontick_";
+	}
+      } else {
+	rv += "_iconblank_";
+      }
+    }
+    if (i+1 == numboxes) {
+      if (!badsources) rv += "_iconblank_";
+      rv += "_imagemore_</nobr><br>";
+    } else {
+      rv += "</nobr><br>\n";
+    }
+  }
+  
+  return rv;
+}
+
+// set the _cfgfile_ macro
+void collectoraction::set_cfgfile (displayclass &disp, cgiargsclass &args, ostream &logout) {
+
+  text_t &collection = args["bc1dirname"];
+  if (collection.empty()) {
+    message = "nocollection";
+    return;
+  }
+
+  // read in collect.cfg      
+  text_t cfgfile = filename_cat(get_collectdir(args), collection, "etc", "collect.cfg");  
+  char *cfgfilec = cfgfile.getcstr();
+
+#ifdef GSDL_USE_IOS_H
+  ifstream cfg_ifs (cfgfilec, ios::in | ios::nocreate);
+#else
+  ifstream cfg_ifs (cfgfilec, ios::in);
+#endif
+  
+  if (cfg_ifs) {  
+    // read in collect.cfg      
+    text_t cfgtext;
+    char c;
+    cfg_ifs.get(c);
+    while (!cfg_ifs.eof ()) {
+      cfgtext.push_back(c);
+      cfg_ifs.get(c);
+    }
+    cfg_ifs.close();
+    
+    // define it as a macro
+    disp.setmacro("cfgfile", "collector", dm_safe(cfgtext));
+
+  } else {
+    logout << "collectoraction::set_cfgfile: couldn't open configuration file (" 
+	   << cfgfilec << ") for reading\n";
+    message = "tmpfail";
+  }    
+  delete []cfgfilec;
+}
+
+
+void collectoraction::define_internal_macros (displayclass &disp, cgiargsclass &args, 
+					      recptprotolistclass *protos, ostream &logout) {
+
+  // define_internal_macros sets the following macros:
+  // _collectorbar_
+  // _pagescriptextra_
+  // _fullnamemenu_ -- if displaying the "source data" page or the "changing existing 
+  //                   collection" page
+  // _cfgfile_ -- if displaying the "configure collection" page
+  // _statusline_ -- if displaying the bildstatus page
+  // _header_ -- may be set for pages that require it
+  // _textfailmsg_ -- set to different messages depending on failcode returned
+  //                  by build script (if build fails)
+  // _faillog_ - set to last 6 lines of .bld file if build failed
+  // _gsdlhome_ - the gsdlhome path (dm_safe)
+  // _sourcelist_ -- "input source" text boxes
+  // _badsources_ -- will be set to "1" if we've come from the 
+  //                 "source data" page and there's a problem 
+  //                 with the input sources
+
+  text_t &collector_page = args["p"];
+  int esrce = args["bc1esrce"].getint();
+  int econf = args["bc1econf"].getint();
+
+  // set _pagescriptextra_ macro to _cpagescriptextra_
+  disp.setmacro ("pagescriptextra", "collector", "_" + collector_page + "scriptextra_");
+
+  if (collector_page == "bildstatus" || collector_page == "bilddone" || 
+      collector_page == "bildfail" || collector_page == "bildframe1") {
+    disp.setmacro ("header", "collector", "_" + collector_page + "header_");
+  }
+
+  // set the collectorbar macro
+  text_t collectorbar = "<table class=wizardbar border=0 cellspacing=4 cellpadding=0><tr>\n";
+
+  if (collector_page == "new") {
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "green", "info", true);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "grey", "srce", false);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "grey", "conf", false);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "grey", "bild", false);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "grey", "view", false);
+
+  } else if (collector_page == "info") {
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "yellow", "info", false);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "green", "srce", true);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "grey", "conf", false);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "grey", "bild", false);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "grey", "view", false);
+    collectorbar += "</tr><tr><td></td><td align=center>_icongreyuparrow_</td><td colspan=8></td>\n";
+
+  } else if (collector_page == "srce") {
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    if (esrce == 1) {
+      // if we came from the "change an existing collection" page previous button(s)
+      // are disabled
+      collectorbar += get_button (args,collector_page, "grey", "info", false);
+    } else {
+      collectorbar += get_button (args,collector_page, "yellow", "info", true);
+    }
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "yellow", "srce", false);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "green", "conf", true);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "green", "bild", true);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "grey", "view", false);
+    collectorbar += "</tr><tr><td colspan=3></td><td align=center>_icongreyuparrow_</td><td colspan=6></td>\n";
+
+  } else if (collector_page == "conf") {
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    // disable appropriate buttons if we came from "change an existing collection"
+    // page
+    if (esrce == 1 || econf == 1) {
+      collectorbar += get_button (args,collector_page, "grey", "info", false);
+    } else {
+      collectorbar += get_button (args,collector_page, "yellow", "info", true);
+    }
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    if (econf == 1) {
+      collectorbar += get_button (args,collector_page, "grey", "srce", false);
+    } else {
+      collectorbar += get_button (args,collector_page, "yellow", "srce", true);
+    }
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "yellow", "conf", false);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "green", "bild", true);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "grey", "view", false);
+    collectorbar += "</tr><tr><td colspan=5></td><td align=center>_icongreyuparrow_</td><td colspan=4></td>\n";
+
+  } else if (collector_page == "bilddone") {
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    // all previous buttons grey after build was completed
+    collectorbar += get_button (args,collector_page, "grey", "info", false);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "grey", "srce", false);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "grey", "conf", false);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "yellow", "bild", false);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "green", "view", true);
+    collectorbar += "</tr><tr><td colspan=7></td><td align=center>_icongreyuparrow_</td><td colspan=2></td>\n";
+
+  } else if (collector_page == "bildcancel" || collector_page == "bildfail") {
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    // disable appropriate buttons if we came from "change an existing collection"
+    // page
+    if (esrce == 1 || econf == 1) {
+      collectorbar += get_button (args,collector_page, "grey", "info", false);
+    } else {
+      collectorbar += get_button (args,collector_page, "yellow", "info", true);
+    }
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    if (econf == 1) {
+      collectorbar += get_button (args,collector_page, "grey", "srce", false);
+    } else {
+      collectorbar += get_button (args,collector_page, "yellow", "srce", true);
+    }
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "yellow", "conf", true);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "yellow", "bild", true);
+    collectorbar += "<td>_icongreyarrow_</td>\n";
+    collectorbar += get_button (args,collector_page, "grey", "view", false);
+  }
+
+  collectorbar += "</tr></table>\n";
+  disp.setmacro ("collectorbar", "collector", collectorbar);
+
+  if (collector_page == "bildfail") {
+
+    text_t textfailmsg = "_textfailmsg";
+    textfailmsg.push_back(failcode);
+    textfailmsg.push_back('_');
+    disp.setmacro("textfailmsg", "collector", textfailmsg);
+
+    text_t bldlog = filename_cat(gsdlhome, "tmp", args["bc1tmp"], args["bc1dirname"] + ".bld");
+    text_t rawlog = file_tail (bldlog, 6, 0);
+    // we'll shove in some <br> tags where \n's occur
+    text_t faillog;
+    text_t::const_iterator here = rawlog.begin();
+    text_t::const_iterator end = rawlog.end();
+    while (here != end) {
+      if (*here == '\n') faillog += "<br>";
+      faillog.push_back (*here);
+      ++here;
+    }
+    disp.setmacro ("faillog", "collector", dm_safe(faillog));
+  }
+
+  if (collector_page == "srce" || collector_page == "existing") 
+    set_fullnamemenu (disp, args, protos, logout);
+  if (collector_page == "conf") 
+    set_cfgfile (disp, args, logout);
+  if (collector_page == "bildstatus")
+    set_statusline (disp, args, logout);
+  if (collector_page == "srce") {
+    set_inputsourceboxes (disp, args, logout);
+  }
+
+  disp.setmacro ("gsdlhome", "collector", dm_safe(gsdlhome));
+}
+
+
+bool collectoraction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/, 
+				 browsermapclass * /*browsers*/, displayclass &disp, 
+				 outconvertclass &outconvert, ostream &textout, 
+				 ostream &logout) {
+
+  // make sure the collector is enabled
+  if (disabled) {
+    textout << outconvert 
+	    << "<html>\n"
+	    << "<head>\n"
+	    << "<title>Collector disabled</title>\n"
+	    << "</head>\n"
+	    << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
+	    << "alink=\"#cc9900\" vlink=\"#666633\">\n"
+	    << "<h2>Facility disabled</h2>\n" 
+	    << "Sorry, the Collector end-user collection building facility is currently disabled\n"
+	    << "\n</body>\n"
+	    << "</html>\n";
+    return true;
+  }
+
+  text_t &collector_page = args["p"];
+  text_t &collection = args["bc1dirname"];
+
+  // make sure we have perl (we won't bother with this check for the 
+  // building status pages to avoid slowing things down unneccessarily)
+  if (collector_page != "bildstatus" && collector_page != "bildframe1" && !perl_ok(logout)) {
+    textout << outconvert 
+	    << "<html>\n"
+	    << "<head>\n"
+	    << "<title>Perl not found</title>\n"
+	    << "</head>\n"
+	    << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
+	    << "alink=\"#cc9900\" vlink=\"#666633\">\n"
+	    << "<h2>Perl not found</h2>\n" 
+	    << "Greenstone could not detect perl on this system. It is therefore not\n"
+	    << "possible to build a Greenstone collection, either from the Collector or the \n"
+	    << "command-line tools, or to use the Collector for any other task.\n"
+	    << "<p>Please refer to the Greenstone Installer's Guide for details on\n"
+	    << "installing perl on your system.\n"
+	    << "\n</body>\n"
+	    << "</html>\n";
+    return true;
+
+  }
+
+  if (collector_page == "bild") {
+    // do the work (download, import, build)
+    gsdl_build (args, logout);
+
+    if (message.empty()) {
+      // bild page is a frameset so we don't want headers and stuff
+      textout << outconvert << disp << ("_collector:bildcontent_\n");
+    }
+  }
+
+  if (do_mkcol == true) {
+    // execute mkcol.pl (do_mkcol is set from within check_cgiargs)
+    gsdl_mkcol (args, logout);
+    do_mkcol = false; // reset for fast-cgi
+  }
+
+  if (args["bc1dodelete"] == "1") {
+    // delete bcidirname collection
+    if (collection_protected (collection)) {
+      message = "delinvalid";
+	
+    } else {
+
+      const recptconf &rcinfo = recpt->get_configinfo ();
+      bool emailuserevents = rcinfo.EmailUserEvents;
+
+      // get collection maintainer email from collect.cfg before we
+      // delete it
+      text_t colmaintainer;
+      text_t cfgfile = filename_cat(collecthome, collection, "etc", "collect.cfg");
+      char *cfgfilec = cfgfile.getcstr();
+      ifstream cfg_in (cfgfilec);
+      delete []cfgfilec;
+      if (cfg_in) {
+	text_tarray cfgline;
+	while (read_cfg_line(cfg_in, cfgline) >= 0) {
+	  if (cfgline.size () == 2 && cfgline[0] == "maintainer") {
+	    colmaintainer = cfgline[1];
+	    break;
+	  }
+	}
+	cfg_in.close();
+      }
+      if (colmaintainer.empty()) {
+	logout << outconvert 
+	       << "collectoraction::do_action WARNING: Collection being deleted (" 
+	       << collection << ") has no maintainer address. EmailUserEvents "
+	       << "disabled\n";
+	emailuserevents = false;
+      }
+      
+      // first we need to free up the collection's collection server
+      // we must do this for the local library (and I guess when using
+      // fastcgi too) as you can't delete the database file while it's
+      // being kept open by the collection server
+      remove_colservr (collection, logout);
+
+      text_t delete_cmd = "perl -S delcol.pl -f " + collection;
+      int rv = gsdl_system (delete_cmd, true, logout);
+      if (rv != 0) {
+	// deletion failed -- permissions?
+	message = "delpermission";
+      } else {
+	message = "delsuccess";
+      }
+
+      // log the event
+      if (rcinfo.LogEvents == CollectorEvents || rcinfo.LogEvents == AllEvents) {
+	
+	text_t eventlog = filename_cat (gsdlhome, "etc", "events.txt");
+	char *eventlogt = eventlog.getcstr();
+	ofstream eventl (eventlogt, ios::app);
+	delete []eventlogt;
+
+	if (eventl) {
+	  eventl << outconvert << "[Collector Event]\n"
+		 << "Date: " << get_date (true) << "\n"
+		 << "Greenstone Username: " << args["un"] << "\n"
+		 << "Collection: " << collection << "\n"
+		 << "Collection Maintainer: " << colmaintainer << "\n"
+		 << "GSDLHOME: " << gsdlhome << "\n";
+
+	  if (message == "delsuccess") {
+	    eventl << outconvert 
+		   << "The " << collection << " collection was successfully deleted\n\n";
+	  } else {
+	    eventl << outconvert 
+		   << "Attempt to delete the " << collection << " collection failed\n\n";
+	  }
+	  eventl.close();
+
+	} else {
+	  logout << outconvert << "collectoraction::do_action ERROR: Couldn't open "
+		 << "event log file " << eventlog << " for appending during collection "
+		 << "deletion. LogEvents disabled\n";
+	}
+      }
+      
+      if (rcinfo.EmailEvents == CollectorEvents || rcinfo.EmailEvents == AllEvents || emailuserevents) {
+	// use sendmail.pl perl script to send email events
+	text_t tmpmailfile = filename_cat (gsdlhome, "tmp", args["bc1tmp"], "event.txt");
+	char *tmpmailfilec = tmpmailfile.getcstr();
+	ofstream tmpfile (tmpmailfilec);
+	delete []tmpmailfilec;
+	if (tmpfile) {
+	  tmpfile << outconvert << "[Collector Event]\n"
+	    	  << "Date: " << get_date (true) << "\n"
+		  << "Greenstone Username: " << args["un"] << "\n"
+		  << "Collection: " << collection << "\n"
+		  << "Collection Maintainer: " << colmaintainer << "\n"
+		  << "GSDLHOME: " << gsdlhome << "\n";
+	  if (message == "delsuccess") {
+	    tmpfile << outconvert 
+		    << "The " << collection << " collection was successfully deleted\n\n";
+	  } else {
+	    tmpfile << outconvert 
+		    << "Attempt to delete the " << collection << " collection failed\n\n";
+	  }
+	  tmpfile.close();
+	  text_t to;
+	  if (rcinfo.EmailEvents == CollectorEvents || rcinfo.EmailEvents == AllEvents) to += rcinfo.maintainer;
+	  if (emailuserevents) {
+	    if (!to.empty()) to.push_back (',');
+	    to += colmaintainer;
+	  }
+	  text_t sendmail_cmd = "perl -S sendmail.pl -to \"" + to + "\" -from \"" + rcinfo.maintainer;
+	  sendmail_cmd += "\" -smtp \"" + rcinfo.MailServer + "\" -subject \"Greenstone Collector Event\"";
+	  sendmail_cmd += " -msgfile \"" + tmpmailfile + "\"";
+
+	  gsdl_system (sendmail_cmd, false, logout);
+	  
+	} else {
+	  logout << outconvert << "collectoraction::do_action ERROR: Couldn't open "
+		 << "temporary event log file " << tmpmailfile << " during collection "
+		 << "deletion. EmailEvents and EmailUserEvents disabled\n";
+	}
+      }
+    }
+  }
+  
+  if (collector_page == "bildcancel" || collector_page == "bildfail") {
+    // cancel the build (we'll also use the cancel_build script to tidy
+    // up if the build failed)
+    gsdl_cancel_build (args, logout);
+  }
+
+  if (collector_page == "expt") {
+
+    // export the collection - we'll do a synchronous system call to
+    // exportcol.pl as that's the easiest way to do it. if it becomes a
+    // problem that it's taking too long to export a large collection then
+    // we may have to revisit this.
+    text_t tmpfile = filename_cat (gsdlhome, "tmp", collection + "_export.txt");
+    text_t export_cmd = "perl -S exportcol.pl -out \"" + tmpfile + "\" " + collection;
+    gsdl_system (export_cmd, true, logout);
+    if (file_exists (tmpfile)) {
+      text_t returnline = file_tail (tmpfile, 1, 0);
+      if (returnline.size() > 23 && (substr(returnline.begin(), returnline.begin()+23) == "exportcol.pl succeeded:")) {
+	// success
+	message = "exptsuccess";
+      } else {
+	message = "exptfail";
+      }
+    } else {
+      message = "exptfail";
+    }
+  }
+
+  if (message.empty()) {
+    if (collector_page != "bild") {
+      // output page ("bild" page was already output above)
+      textout << outconvert << disp << ("_collector:header_\n")
+	      << ("_collector:" + collector_page + "content_\n")
+	      << ("_collector:footer_\n");
+    }
+  } else {
+    // message was set somewhere (probably an error), output message page
+    textout << outconvert << disp << ("_collector:header_\n")
+	    << ("_collector:" + message + "content_\n")
+	    << ("_collector:footer_\n");
+    message.clear();
+  }
+  return true;
+}
+
+void collectoraction::gsdl_mkcol (cgiargsclass &args, ostream &logout) {
+
+  text_t tmpdir = filename_cat (gsdlhome, "tmp", args["bc1tmp"]);
+  if (!directory_exists (tmpdir)) {
+    message = "tmpfail";
+    cerr << "WE CANNOT CREATE THE DIRECTORY!!! " << endl; 
+    return;
+  }
+
+  text_t &collection = args["bc1dirname"];
+  if (collection.empty()) {
+    message = "nocollection";
+    return;
+  }
+
+  // check for a .create file - if it exists then we've already created the collection
+  text_t createfile = filename_cat (tmpdir, ".create");
+  if (file_exists (createfile)) {
+    return;
+  }
+
+  // set up options
+  text_t options = "-quiet -creator \"" + args["bc1contactemail"] + "\"";
+  options += " -title \"" + args["bc1fullname"] + "\"";
+  options += " -about \"" + carriage_replace (args["bc1aboutdesc"] + "_collectorextra_", 0) + "\"";
+  options += " -collectdir \"" + remove_trailing_slashes(tmpdir) + "\" ";
+
+  text_t optionfile = filename_cat (tmpdir, "mkcol.opt");
+  char *optionfilec = optionfile.getcstr();
+  ofstream ofile_out (optionfilec);
+  delete []optionfilec;
+  if (!ofile_out) {
+    message = "tmpfail";
+    return;
+  }
+  outconvertclass text_t2ascii;
+  ofile_out << text_t2ascii << options << "\n";
+  ofile_out.close();
+
+  // run mkcol.pl
+  text_t mkcol_cmd = "perl -S mkcol.pl -optionfile \"" + optionfile;
+  mkcol_cmd += "\" " + collection;
+
+
+  gsdl_system (mkcol_cmd, true, logout);
+
+  // make sure it went ok
+  text_t cfgfile = filename_cat (tmpdir, collection, "etc", "collect.cfg");
+  if (!file_writable (cfgfile)) {
+    message = "mkcolfail";
+  } else {
+    // create the .create file (this file is just a place holder to let any future
+    // pages know that the collection already exists).
+    char *createfilec = createfile.getcstr();
+    ofstream cfile_out (createfilec);
+    delete []createfilec;
+    if (cfile_out) {
+      cfile_out << "collection created\n";
+      cfile_out.close();
+    } else {
+      message = "tmpfail";
+      return;
+    }
+  }
+}
+
+
+bool collectoraction::check_sources (cgiargsclass &args, ostream &logout) {
+
+  bool found = false;
+
+  text_tarray inputvalues;
+  splitchar (args["bc1input"].begin(), args["bc1input"].end(), ',', inputvalues);
+
+  text_tarray inputtypes;
+  splitchar (args["bc1inputtype"].begin(), args["bc1inputtype"].end(), ',', inputtypes);
+
+  int numvalues = inputvalues.size();
+  int numtypes = inputtypes.size();
+
+  for (int i = 0; i < numvalues; ++i) {
+    text_t value = format_url(decode_commas(inputvalues[i]));
+    text_t type = "file://"; // default
+    if (!value.empty()) {
+      found = true;
+      if (i >= numtypes || inputtypes[i].empty()) {
+	logout << "collectoraction::check_sources: WARNING type not set\n";
+      } else {
+	type = inputtypes[i];
+      }
+      if (type == "file://") {
+	if (!file_exists(value) && !directory_exists(value)) {
+	  failedsources[decode_commas(inputvalues[i])] = "1";
+	  badsources = true;
+	}
+      } else if (type == "http://") {
+	if (gsdl_system ("perl -S ping.pl -quiet http://" + value, true, logout)) {
+	  failedsources[decode_commas(inputvalues[i])] = "1";
+	  badsources = true;
+	}
+      } else if (type == "ftp://") {
+	if (gsdl_system ("perl -S ping.pl -quiet ftp://" + value, true, logout)) {
+	  failedsources[decode_commas(inputvalues[i])] = "1";
+	  badsources = true;
+	}
+      }
+    }
+  }
+
+  // set badsources if there weren't any sources at all
+  if (!found) badsources = true;
+
+  if (badsources) return false;
+  return true;
+}
+
+text_t collectoraction::get_button(cgiargsclass &args, const text_t &thispage, 
+				   const text_t &color, 
+				   const text_t &type, bool enabled) 
+{
+
+  if ((color != "green" && color != "grey" && color != "yellow") ||
+      (type != "info" && type != "srce" && type != "conf" && type != "bild" && type != "view"))
+    return g_EmptyText;
+
+  text_t href = "_http"+type+"_";
+  text_t target = "";
+
+  if (thispage == "info" || thispage == "srce" || thispage == "conf" || 
+      thispage == "bildcancel" || thispage == "bildfail") {
+    // call the check submit macro instead of linking directly to the page
+    href="\"javascript:check_submit('"+type+"');\"";
+  } else if (type == "view") {
+    // view button is special case as it needs a target=_top
+    target = " target=_top";
+  }
+
+  text_t tdclass = "wizardbar"+color; 
+  if (enabled) {
+    // link to the appropriate page
+    return "<td class="+tdclass+"><a href="+href+target+">_text"+type+"_</a></td>";
+  }
+  else {
+    // just display the text
+    return "<td class="+tdclass+">_text"+type+"_</td>";
+  }
+}
+
+#endif //GSDL_USE_COLLECTOR_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/collectoraction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/collectoraction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/collectoraction.h	(revision 20131)
@@ -0,0 +1,95 @@
+/**********************************************************************
+ *
+ * collectoraction.h -- 
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_COLLECTOR_ACTION
+
+#ifndef COLLECTORACTION_H
+#define COLLECTORACTION_H
+
+#include "wizardaction.h"
+#include "receptionist.h"
+
+class collectoraction : public wizardaction {
+  
+protected:
+
+  bool do_mkcol;
+
+  bool badsources;
+  text_tmap failedsources;
+
+  void set_fullnamemenu (displayclass &disp, cgiargsclass &args, 
+			 recptprotolistclass *protos, ostream &logout);
+
+
+  void set_inputsourceboxes (displayclass &disp, cgiargsclass &args, 
+			     ostream &logout);
+
+  text_t get_source_box (text_t inputarglist, int numboxes, 
+			 text_t inputtypelist);
+
+  void set_cfgfile (displayclass &disp, cgiargsclass &args, ostream &logout);
+
+
+  void update_cfgfile_clone (cgiargsclass &args, ostream &logout);
+
+  void update_cfgfile_partial (cgiargsclass &args, bool clone, ostream &logout);
+
+  void update_cfgfile_complete (cgiargsclass &args, ostream &logout);
+
+
+  void gsdl_mkcol (cgiargsclass &args, ostream &logout);
+
+
+
+  bool check_sources (cgiargsclass &args, ostream &logout);
+
+  text_t get_button (cgiargsclass &args, const text_t &thispage, 
+		     const text_t &color, 
+		     const text_t &type, bool enabled);
+
+
+public:
+  collectoraction ();
+  virtual ~collectoraction ();
+
+  text_t get_action_name () {return "collector";}
+
+  bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+		      recptprotolistclass *protos, ostream &logout);
+
+  void define_internal_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+
+};
+
+#endif //!COLLECTORACTION_H
+#endif //GSDL_USE_COLLECTOR_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/comproto.asn
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/comproto.asn	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/comproto.asn	(revision 20131)
@@ -0,0 +1,377 @@
+-- The protocol data unit (PDU) is the
+-- message that is transmitted between receptionists and
+-- collectionservers (colservers?).
+--
+-- Comments in ASN.1 start with two dashes and continue to the end
+-- of a line (or to the next two dashes, whichever is first).
+-- 
+-- Z39.50 has inspired much of this but I have tried to keep
+-- it simple. Its hard to tell if I have succeeded ;-)
+
+
+GSDL-APDU DEFINITIONS ::=
+BEGIN
+
+
+-- PDU is the basic message type. Note: in ASN.1 the
+-- field name comes first and the field type second (opposite
+-- to C). Ignore the numbers in the square brackets (e.g. [0]),
+-- they're just tags to disambiguate certain circumstances and to
+-- make the protocol easier to extend. The keyword 'IMPLICIT' just
+-- makes the tags a little more efficient.
+--
+-- A SEQUENCE is a list of fields where the order is important
+
+PDU ::= SEQUENCE {
+  header  StandardHeader,
+  message Message
+}
+
+
+-- ????? Is there anything else we want in the header ?????
+--
+-- Anonymous transactions should leave out the idAuthentication field
+
+StandardHeader ::= SEQUENCE {
+  protocolVersion       [0] IMPLICIT INTEGER,
+  idAuthentication      [1] IMPLICIT IdAuthentication OPTIONAL
+}
+
+IdAuthentication ::= SEQUENCE {
+  userId   GeneralString,
+  groupId  GeneralString,
+  password GeneralString
+}
+
+
+-- A CHOICE is like a union in C.
+-- 
+-- Short forms: Auth (Authority), Mir (Mirror), Col (Collection),
+--   Doc (Document), Info (Information)
+
+Message ::= CHOICE {
+  -- General
+  error                      [0]  IMPLICIT Error,
+  pingRequest                [1]  IMPLICIT PingRequest,
+  pingResponse               [2]  IMPLICIT PingResponse,
+
+  -- Authority
+--  authListRequest            [12] IMPLICIT AuthListRequest,
+--  authListResponse           [13] IMPLICIT AuthListResponse,
+--  editAuthListRequest        [14] IMPLICIT EditAuthListRequest,
+--  editAuthListResponse       [15] IMPLICIT EditAuthListResponse,
+
+  -- an authority mirror is a mirror of THIS authority
+--  authMirListRequest         [16] IMPLICIT AuthMirListRequest,
+--  authMirListResponse        [17] IMPLICIT AuthMirListResponse,
+--  editAuthMirListRequest     [18] IMPLICIT EditAuthMirListRequest,
+--  editAuthMirListResponse    [19] IMPLICIT EditAuthMirListResponse,
+
+  colListRequest             [20] IMPLICIT ColListRequest,
+  colListResponse            [21] IMPLICIT ColListResponse,
+--  editColListRequest         [22] IMPLICIT EditColListRequest,
+--  editColListResponse        [23] IMPLICIT EditColListResponse,
+
+--  colMirListRequest          [24] IMPLICIT ColMirListRequest,
+--  colMirListResponse         [25] IMPLICIT ColMirListResponse, 
+--  editColMirListRequest      [26] IMPLICIT EditColMirListRequest, 
+--  editColMirListResponse     [27] IMPLICIT EditColMirListResponse,
+
+  -- Collection
+  colInfoRequest             [40] IMPLICIT ColInfoRequest,
+  colInfoResponse            [41] IMPLICIT ColInfoResponse,
+
+  -- Document
+  documentRequest            [52] IMPLICIT DocumentRequest,
+  documentResponse           [53] IMPLICIT DocumentResponse,
+
+  -- Access (searching, browsing, and metadata information)
+  infoFiltersRequest         [60] IMPLICIT InfoFiltersRequest,
+  infoFiltersResponse        [61] IMPLICIT InfoFiltersResponse,
+  infoFilterOptionsRequest   [62] IMPLICIT InfoFilterOptionsRequest,
+  infoFilterOptionsResponse  [63] IMPLICIT InfoFilterOptionsResponse,
+  filterRequest              [64] IMPLICIT FilterRequest,
+  filterResponse             [65] IMPLICIT FilterResponse
+}
+
+
+
+-- ------------------------------
+-- GENERAL
+-- ------------------------------
+
+
+-- The error list is not complete yet ...
+
+Error ::= ENUMERATED {
+  authenticationFailure(0), protocolError(1), systemProblem(2)
+}
+
+
+PingRequest ::= SEQUENCE {
+}
+
+PingResponse ::= SEQUENCE {
+}
+
+
+
+-- ------------------------------
+-- AUTHORITY
+-- ------------------------------
+
+
+-- Support for subscription is optional for both the clients and
+-- the servers. It is recomended that it is not implemented yet
+-- for simplicity.
+
+-- AuthListRequest ::= SEQUENCE {
+-- }
+
+-- AuthListResponse ::= SEQUENCE {
+--   authList  [1] IMPLICIT StringSet
+-- }
+
+
+-- EditAuthListRequest ::= SEQUENCE {
+--   editAction EditAction,
+--   authority  GeneralString
+-- }
+
+-- EditAuthListResponse ::= SEQUENCE {
+-- }
+
+
+-- AuthMirListRequest ::= SEQUENCE {
+--   limitNumber [1] IMPLICIT INTEGER OPTIONAL,
+--   limitDomain [2] IMPLICIT GeneralString OPTIONAL
+-- }
+
+-- AuthMirListResponse ::= SEQUENCE {
+--   authMirList [1] IMPLICIT HostPortSet
+-- }
+
+
+-- EditAuthMirListRequest ::= SEQUENCE {
+--   editAction EditAction,
+--   authMir    HostPort
+-- }
+
+-- EditAuthMirListResponse ::= SEQUENCE {
+-- }
+
+
+ColListRequest ::= SEQUENCE {
+}
+
+ColListResponse ::= SEQUENCE {
+  colList   [1] IMPLICIT ShortColInfoSet
+}
+
+
+-- EditColListRequest ::= SEQUENCE {
+--   editAction EditAction,
+--   colInfo    ShortColInfo
+-- }
+
+-- EditColListResponse ::= SEQUENCE {
+-- }
+
+
+-- ColMirListRequest ::= SEQUENCE {
+--   limitNumber [1] IMPLICIT INTEGER OPTIONAL,
+--   limitDomain [2] IMPLICIT GeneralString OPTIONAL
+-- }
+
+-- ColMirListResponse ::= SEQUENCE {
+--   colMirList [1] IMPLICIT ShortColInfoSet
+-- }
+
+
+-- EditColMirListRequest ::= SEQUENCE {
+--   editAction EditAction,
+--   colMirInfo ShortColInfo
+-- }
+
+-- EditColMirListResponse ::= SEQUENCE {
+-- }
+
+
+
+
+-- ------------------------------
+-- COLLECTION
+-- ------------------------------
+
+
+ColInfoRequest ::= SEQUENCE {
+}
+
+ColInfoResponse ::= SEQUENCE {
+  shortInfo   [0] IMPLICIT ShortCollectionInfo,
+  isPublic    [2] IMPLICIT BOOLEAN,    -- whether has anonymous access
+  isBeta      [3] IMPLICIT BOOLEAN,    -- beta if still under development
+  builddate   [4] IMPLICIT GeneralizedTime,
+  languages   [5] IMPLICIT StringSet,  -- languages in the collection
+  numDocs     [6] IMPLICIT INTEGER,
+  numWords    [7] IMPLICIT INTEGER OPTIONAL,
+  numBytes    [8] IMPLICIT INTEGER OPTIONAL,
+  useBook     [9] IMPLICIT BOOLEAN     -- whether to use book mode
+}
+
+
+
+-- ------------------------------
+-- DOCUMENT
+-- ------------------------------
+
+
+
+DocumentRequest ::= SEQUENCE {
+  OID       GeneralString,
+  docType   GeneralString,
+  docFormat GeneralString
+}
+
+DocumentResponse ::= SEQUENCE {
+  doc OCTET STRING
+}
+
+
+-- ------------------------------
+-- ACCESS (SEARCH AND BROWSE)
+-- ------------------------------
+
+
+-- filter options which might be supported for the QueryFilter
+--
+-- onePerQuery StartResults   integer
+-- onePerQuery EndResults     integer
+-- onePerQuery QueryType      enumerated (boolean, ranked)
+-- onePerTerm  Term           string ???
+-- onePerTerm  Casefold       boolean
+-- onePerTerm  Stem           boolean
+-- onePerTerm  Index          enumerated
+-- onePerTerm  Subcollection  enumerated
+--
+-- filter options which might be supported for the BrowseFilter
+--
+-- onePerQuery StartResults   integer
+-- onePerQuery EndResults     integer
+-- onePerQuery ParentNode     string ("" will return the browsing available)
+--
+-- The NullFilter always returns the set it was given, it doesn't have
+-- any options
+
+InfoFiltersRequest ::= SEQUENCE {
+}
+
+InfoFiltersResponse ::= SEQUENCE {
+  filterNames StringSet
+}
+
+InfoFilterOptionsRequest ::= SEQUENCE {
+  filterName GeneralString
+}
+
+InfoFilterOptionsResponse ::= SEQUENCE {
+  filterOptions SET OF FilterOption
+}
+
+FilterOption ::= SEQUENCE {
+  name         GeneralString,
+  type         ENUMERATED {booleant(0), integert(1), enumeratedt(2), stringt(3)},
+  repeatable   ENUMERATED {onePerQuery(0), onePerTerm(1), nPerTerm(2)},
+  defaultValue GeneralString,
+  -- the interpretation of the validValues depends on the type
+  -- for boolean: the first value is the false value, the second is true value
+  -- for integer: the first value is the minimum, the second the maximum
+  -- for enumerated: all values a listed
+  -- for string: this value is ignored
+  validValues  StringSequence
+}
+
+
+-- Terms are presented in the same order that they are requested,
+-- any information relating to the terms is in reference to the
+-- index specified for that term.
+-- Metadata is presented in the same order that it is requested.
+
+FilterRequest ::= SEQUENCE {
+  filterName          [0] GeneralString,
+  filterOptions       [1] IMPLICIT SEQUENCE OF OptionValue,
+  docSet              [2] IMPLICIT StringSequence, -- the OID "" represents everything
+  filterResultOptions [3] IMPLICIT BIT STRING {termFreq(0), matchTerms(1), OID(2), 
+                                               subCol(3), ranking(4), docFreq(5), 
+                                               metadata(6)}
+
+  -- the next set of options are for the metadata request, 
+  -- they can be left blank if metadata is not wanted
+  requestParams       [4] IMPLICIT GeneralString, -- used to negotiate the metadata content
+  refParams           [5] IMPLICIT GeneralString, -- used to decide whether to return a 
+                                                  -- reference to the data or the actual data
+  fields              [6] IMPLICIT StringSequence
+}
+
+OptionValue ::= SEQUENCE {
+  name  GeneralString,
+  value GeneralString
+}
+
+FilterResponse ::= SEQUENCE {
+  numDocs   [0] IMPLICIT INTEGER,
+  isApprox  [1] IMPLICIT BOOLEAN,                  -- whether numDocs is approximate
+  termInfo  [2] IMPLICIT SEQUENCE OF TermInfo,     -- empty if not required
+  docInfo   [3] IMPLICIT SEQUENCE OF ResultDocInfo -- empty if not required
+}
+
+TermInfo ::= SEQUENCE {
+  term       [0] GeneralString,
+  freq       [1] IMPLICIT INTEGER,       -- 0 if not requested
+  matchTerms [2] IMPLICIT StringSequence -- empty if not requested
+}
+
+ResultDocInfo ::= SEQUENCE {
+  OID      [0] IMPLICIT GeneralString,
+  ranking  [1] IMPLICIT INTEGER,             -- 0 if not requested, range 0-10000
+  docFreq  [2] IMPLICIT SEQUENCE OF INTEGER, -- empty if not requested
+  metadata [3] IMPLICIT SEQUENCE OF MetadataInfo
+}
+
+
+MetadataInfo ::= SEQUENCE {
+  params  [0] IMPLICIT GeneralString,
+  isRef   [1] IMPLICIT BOOLEAN,
+  field   [3] IMPLICIT GeneralString,
+  value   [4] IMPLICIT GeneralString
+}
+
+
+-- ------------------------------
+-- Useful Types
+-- ------------------------------
+
+-- HostPortSet ::= SET OF HostPort
+
+-- HostPort ::= SEQUENCE {
+--   host [0] IMPLICIT GeneralString,
+--   port [1] IMPLICIT INTEGER
+-- }
+
+ShortColInfoSet ::= SET OF ShortColInfo
+
+ShortColInfo ::= SEQUENCE {
+  name GeneralString,
+  host GeneralString,
+  port INTEGER
+}
+
+-- EditAction ::= ENUMERATED {
+--   update(0), delete(1)
+-- }
+
+StringSequence ::= SEQUENCE OF GeneralString
+StringSet ::= SET OF GeneralString
+
+
+END
Index: /gsdl/stable/runtime-src/src/recpt/configaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/configaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/configaction.cpp	(revision 20131)
@@ -0,0 +1,151 @@
+/**********************************************************************
+ *
+ * configaction.cpp -- 
+ * Copyright (C) 2003 DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#include "configaction.h"
+
+#ifdef GSDL_LOCAL_LIBRARY
+// for PostMessage()
+#  include <windows.h>
+#endif
+
+configaction::configaction () {
+
+  recpt = NULL;
+
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "a";
+  arg_ainfo.longname = "action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "config";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  /* 
+     The cmd argument may be one of the following:
+     -- release-collection - release the collection specified by the "c"
+        argument
+     -- add-collection - add and configure a collection server for the
+        collection specified by the "c" argument
+     -- kill - if running as the local library this will kill the server
+  */
+  arg_ainfo.shortname = "cmd";
+  arg_ainfo.longname = "config command";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+}
+
+configaction::~configaction () {
+}
+
+void configaction::get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+				     response_t &response, text_t &response_data, 
+				     ostream &logout) {
+  response = content;
+  response_data = "text/html";
+}
+
+bool configaction::do_action (cgiargsclass &args, recptprotolistclass *protos, 
+			      browsermapclass *browsers, displayclass &disp,
+			      outconvertclass &outconvert, ostream &textout,
+			      ostream &logout) {
+
+  if (recpt == NULL) return false;
+
+  if ((args["cmd"] == "add-collection") && (!args["c"].empty())) {
+    create_colservr(args["c"], logout);
+    textout << "configured add-collection\n";
+
+  } else if ((args["cmd"] == "release-collection") && (!args["c"].empty())) {
+    remove_colservr(args["c"], logout);
+    textout << "configured release-collection\n";
+
+  } else if (args["cmd"] == "kill") {
+    textout << "killed\n";
+#ifdef GSDL_LOCAL_LIBRARY
+    HWND gw = FindWindow("Greenstone Digital Library Software",
+			 "Greenstone Digital Library Software");
+    PostMessage(gw, WM_DESTROY, 0, 0);
+#endif
+  }
+
+  return true;
+}
+
+
+// create and initialize a new collection server and
+// add it to the null protocol.
+void configaction::create_colservr (const text_t &collection, ostream &logout) {
+
+  // just in case we're adding a collection that already exists
+  recpt->uncache_collection(collection);
+
+  recptprotolistclass *protos = recpt->get_recptprotolist_ptr();
+  recptprotolistclass::iterator rprotolist_here = protos->begin();
+  recptprotolistclass::iterator rprotolist_end = protos->end();
+  while (rprotolist_here != rprotolist_end) {
+    comerror_t err = noError;
+    if ((*rprotolist_here).p != NULL) {
+      if ((*rprotolist_here).p->get_protocol_name(err) == "nullproto") {
+	// create collection server and add it to nullproto
+	(*rprotolist_here).p->add_collection(collection, recpt, gsdlhome, collecthome, gsdlhome);
+	// re-initialize the null protocol
+	if (!(*rprotolist_here).p->init(err, logout)) {
+	  logout << "configaction::create_colservr: nullproto init failed\n";
+	}
+	return;
+      }
+    }
+    ++rprotolist_here;
+  }
+
+  logout << "configaction::create_colservr: no valid nullproto found\n";
+}
+
+// delete a collection server from the null protocol
+void configaction::remove_colservr (const text_t &collection, ostream &logout) {
+
+  recpt->uncache_collection(collection);
+
+  recptprotolistclass *protos = recpt->get_recptprotolist_ptr();
+  recptprotolistclass::iterator rprotolist_here = protos->begin();
+  recptprotolistclass::iterator rprotolist_end = protos->end();
+  while (rprotolist_here != rprotolist_end) {
+    comerror_t err = noError;
+    if ((*rprotolist_here).p != NULL) {
+      if ((*rprotolist_here).p->get_protocol_name(err) == "nullproto") {
+	(*rprotolist_here).p->remove_collection(collection, logout);
+	return;
+      }
+    }
+    ++rprotolist_here;
+  }
+
+  logout << "configaction::create_colserver: no valid nullproto found\n";
+}
Index: /gsdl/stable/runtime-src/src/recpt/configaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/configaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/configaction.h	(revision 20131)
@@ -0,0 +1,60 @@
+/**********************************************************************
+ *
+ * configaction.h -- 
+ * Copyright (C) 2003 DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef CONFIGACTION_H
+#define CONFIGACTION_H
+
+#include "action.h"
+#include "receptionist.h"
+
+class configaction : public action {
+
+protected:
+  receptionist *recpt;
+
+  void create_colservr (const text_t &collection, ostream &logout);
+  void remove_colservr (const text_t &collection, ostream &logout);
+
+public:
+  configaction ();
+  virtual ~configaction ();
+
+  void set_receptionist (receptionist *therecpt) {recpt=therecpt;}
+
+  text_t get_action_name () {return "config";}
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response, text_t &response_data, 
+			 ostream &logout);
+
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp,
+		  outconvertclass &outconvert, ostream &textout,
+		  ostream &logout);
+};
+
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/converter.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/converter.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/converter.cpp	(revision 20131)
@@ -0,0 +1,77 @@
+/**********************************************************************
+ *
+ * converter.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "converter.h"
+
+
+
+// the converters within converterinfo become the property of this class
+// after add_converter has been called. The converters remain the
+// responsability of the calling code and will not be deleted by this
+// class.
+void convertinfoclass::add_converter (const text_t &name, inconvertclass *inconverter,
+				      rzwsoutconvertclass *outconverter) {
+  // can't add a null converter or an action with no name
+  if (inconverter == NULL || outconverter == NULL || name.empty()) {
+    return;
+  }
+
+  converterinfo info;
+  info.name = name;
+  info.inconverter = inconverter;
+  info.outconverter = outconverter;
+  converters[name] = info;
+}
+
+
+bool operator==(const converterinfo &x, const converterinfo &y) {
+  return ((x.name == y.name) && (x.inconverter == y.inconverter) &&
+	  (x.outconverter == y.outconverter));
+}
+
+bool operator<(const converterinfo &x, const converterinfo &y) {
+  return ((x.name < y.name) ||
+	  ((x.name == y.name) &&
+	   ((x.inconverter < y.inconverter) ||
+	    ((x.inconverter == y.inconverter) &&
+	     ((x.outconverter < y.outconverter))))));
+}
+
+
+// get_inconverter will return NULL if the convert could not be found
+inconvertclass *convertinfoclass::get_inconverter (const text_t &name) {
+  iterator here = converters.find (name);
+  if (here == converters.end()) return NULL;
+
+  return (*here).second.inconverter;
+}
+
+// get_outconverter will return NULL if the convert could not be found
+rzwsoutconvertclass *convertinfoclass::get_outconverter (const text_t &name) {
+  iterator here = converters.find (name);
+  if (here == converters.end()) return NULL;
+
+  return (*here).second.outconverter;
+}
Index: /gsdl/stable/runtime-src/src/recpt/converter.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/converter.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/converter.h	(revision 20131)
@@ -0,0 +1,122 @@
+/**********************************************************************
+ *
+ * converter.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef CONVERTER_H
+#define CONVERTER_H
+
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "gsdlunicode.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\map>
+#elif defined(GSDL_USE_STL_H)
+#  include <map.h>
+#else
+#  include <map>
+#endif
+
+
+// inconverter and outconverter ARE NOT destroyed by this class
+// they should be destroyed by the code which created them after
+// no more pointers to the class exist.
+//
+// The above condition enables the class to be copied without
+// copying the converters which might contain a lot of data (and
+// be of an unknown derived type).
+class converterinfo {
+public:
+  text_t name;
+  inconvertclass *inconverter;
+  rzwsoutconvertclass *outconverter;
+
+  converterinfo() {inconverter=NULL; outconverter=NULL;}
+};
+
+bool operator==(const converterinfo &x, const converterinfo &y);
+bool operator<(const converterinfo &x, const converterinfo &y);
+
+
+typedef map<text_t, converterinfo, lttext_t> convertmap;
+
+// convertinfoclass is used to store a number of converters
+// indexing them by their name
+class convertinfoclass {
+protected:
+  convertmap converters;
+
+public:
+  // type support for convertmap
+  typedef convertmap::iterator iterator;
+  typedef convertmap::const_iterator const_iterator;
+  typedef convertmap::reference reference;
+  typedef convertmap::const_reference const_reference;
+  typedef convertmap::size_type size_type;
+  typedef convertmap::difference_type difference_type;
+  typedef convertmap::const_reverse_iterator const_reverse_iterator;
+  typedef convertmap::reverse_iterator reverse_iterator;
+  
+  // constructors
+  convertinfoclass () {}
+
+  // basic container support
+  iterator begin () {return converters.begin();}
+  const_iterator begin () const {return converters.begin();}
+  iterator end () {return converters.end();}
+  const_iterator end () const {return converters.end();}
+
+  void erase(iterator pos) {converters.erase(pos);}
+  void erase(iterator first, iterator last) {converters.erase(first, last);}
+  convertinfoclass &operator=(const convertinfoclass &x) 
+    {converters=x.converters;return *this;}
+
+  bool empty () const {return converters.empty();}
+  size_type size() const {return converters.size();}
+
+  const_iterator find(const text_t &key) {return converters.find(key);}
+
+  // added functionality
+  void clear () {converters.erase(converters.begin(),converters.end());}
+
+  // the converters within converterinfo become the property of
+  // of this class after add_converter has been called. The converters
+  // remain the responsability of the calling code and will not be
+  // deleted by this class.
+  void add_converter (const text_t &name, inconvertclass *inconverter,
+		      rzwsoutconvertclass *outconverter);
+
+  // get_inconverter will return NULL if the convert could not be found
+  inconvertclass *get_inconverter (const text_t &name);
+
+  // get_outconverter will return NULL if the convert could not be found
+  rzwsoutconvertclass *get_outconverter (const text_t &name);
+};
+
+
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/datelistbrowserclass.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/datelistbrowserclass.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/datelistbrowserclass.cpp	(revision 20131)
@@ -0,0 +1,186 @@
+/**********************************************************************
+ *
+ * datelistbrowserclass.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_DATELIST_BROWSER
+
+#include "datelistbrowserclass.h"
+#include <assert.h>
+
+
+datelistbrowserclass::datelistbrowserclass () {
+}
+
+datelistbrowserclass::~datelistbrowserclass () {
+}
+
+text_t datelistbrowserclass::get_browser_name () {
+  return "DateList";
+}
+
+browserclass* datelistbrowserclass::clone()
+{
+  return new datelistbrowserclass();
+}
+
+void datelistbrowserclass::load_metadata_defaults (text_tset &metadata) {
+  metadata.insert ("Date");
+  metadata.insert ("doctype");
+}
+
+text_t datelistbrowserclass::get_default_formatstring () {
+  return "<td>[link][icon][/link]</td><td>[highlight]{Or}{[dls.Title],[dc.Title],[Title],Untitled}[/highlight]</td><td>[Date]</td>";
+}
+
+int datelistbrowserclass::output_section_group (ResultDocInfo_t &/*section*/, cgiargsclass &/*args*/,
+						const text_t &/*collection*/, int /*colnumber*/, 
+						format_t * /*formatlistptr*/, bool /*use_table*/, 
+						text_tset &/*metadata*/, bool &/*getParents*/,
+						recptproto * /*collectproto*/, displayclass &/*disp*/, 
+						outconvertclass &/*outconvert*/, ostream &/*textout*/, 
+						ostream &/*logout*/) {
+  return 0;
+}
+
+int datelistbrowserclass::output_section_group (FilterResponse_t &sections, cgiargsclass &args,
+						const text_t &collection, int colnumber, format_t *formatlistptr, 
+						bool use_table, text_tset &/*metadata*/, bool &/*getParents*/,
+						recptproto * collectproto, displayclass &disp, 
+						outconvertclass &outconvert, ostream &textout, ostream &logout) {
+
+  text_t lastyear = "0000";
+  text_t lastmonth = "00";
+  text_t tabbing, endtabbing;
+
+  if (use_table || colnumber > 0) {
+    textout << outconvert << "<table><tr><td>";
+    // get tab size
+    text_t tab; int itab;
+    disp.expandstring (displayclass::defaultpackage, "_tabwidth_", tab);
+    itab = tab.getint();
+    if (colnumber > 0) 
+      textout << outconvert << "<img alt=\"\" src=\"_httpiconspace_\" width=\"" << (itab*colnumber) << "\"/>";
+    textout << outconvert << "</td><td>";
+  }
+
+  textout << outconvert << "<table class=\"date_list\">\n";
+
+  ResultDocInfo_tarray::iterator thissection = sections.docInfo.begin();
+  ResultDocInfo_tarray::iterator endsection = sections.docInfo.end();
+  
+  // use the dm arg as date metadata or else Date
+  text_t date_meta = args["dm"];
+  if (date_meta == "") {
+    date_meta = "Date";
+  }
+  text_tarray dates;
+  splitchar(date_meta.begin(), date_meta.end(), ',', dates);
+
+  while (thissection != endsection) {
+
+    text_t &doctype = (*thissection).metadata["doctype"].values[0];
+
+    text_tarray::iterator begin = dates.begin();
+    text_tarray::iterator end = dates.end();
+    text_t date;
+    while (begin!= end && date.empty()) {
+      date = (*thissection).metadata[*begin].values[0];
+      begin++;
+    }
+    text_t thisyear = "";
+    text_t thismonth = "";
+    if (!date.empty()) {
+      text_t::const_iterator datebegin = date.begin();
+      int datesize = date.size();
+    
+      if (datesize >=4) {
+	thisyear = substr (datebegin, datebegin+4);
+	thismonth = "00";
+	int pos = 4;
+	// allow for yyyy-mm-dd
+	if (date[pos]=='-') {
+	  ++pos;
+	}
+	if (datesize >= pos+2)
+	  thismonth = substr (datebegin+pos, datebegin+pos+2); 
+      }
+    }
+    
+    text_t link = "<a href=\"_httpdocument_&cl=";
+    text_t icon = "_document:iconclosedbook_";
+      
+    if (doctype == "classify") {
+      icon = "_document:iconclosedbookshelf_";
+      link += (*thissection).OID + "\">";
+    } else {
+      link += args["cl"] + "&d=" + (*thissection).OID; // + "\">";
+      // [modification to allow default document detach settings -- kjdon]
+      if (args["xx"]=="1") {
+	// documents should be detached
+	link += "&x=1\" target=\\_blank>";
+      } else {
+	link += "\">";
+      }
+    }
+
+    textout << outconvert << "<tr valign=top>";
+
+    if (thisyear != "" && thisyear != lastyear) {
+      textout << outconvert << "<td><span class=\"date_list_year\">" << thisyear << "</span></td>";
+      lastyear = thisyear;
+    } else {
+      textout << outconvert << "<td></td>";
+    }
+    if (thismonth != "" && thismonth != lastmonth) {
+      textout << outconvert << disp << ("<td><span class=\"date_list_month\">_textmonth" + thismonth + "_</span></td>");
+      lastmonth = thismonth;
+    } else {
+      textout << outconvert << "<td></td>";
+    }
+    if (!use_table) textout << outconvert << "<td>\n";
+
+    text_tmap options;
+    options["link"] = link;
+    options["icon"] = icon;
+    options["highlight"] = "0";
+    textout << outconvert << disp 
+            << get_formatted_string (collection, collectproto,
+				     *thissection, disp, formatlistptr, 
+				     options, logout) << "\n";
+    
+    if (!use_table) textout << outconvert << "</td>";
+    
+    textout << outconvert << "</tr>\n";
+    
+    ++thissection;
+  }
+
+  textout << outconvert << "</table>\n";
+
+  if (use_table  || colnumber > 0) textout << outconvert << "</td></tr></table>\n";
+  return 1;
+}
+
+#endif //GSDL_USE_DATELIST_BROWSER
Index: /gsdl/stable/runtime-src/src/recpt/datelistbrowserclass.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/datelistbrowserclass.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/datelistbrowserclass.h	(revision 20131)
@@ -0,0 +1,63 @@
+/**********************************************************************
+ *
+ * datelistbrowserclass.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_DATELIST_BROWSER
+
+#ifndef DATELISTBROWSERCLASS_H
+#define DATELISTBROWSERCLASS_H
+
+#include "browserclass.h"
+
+class datelistbrowserclass : public browserclass {
+protected:
+
+public:
+  datelistbrowserclass ();
+  virtual ~datelistbrowserclass ();
+
+  text_t get_browser_name ();
+
+  virtual browserclass* clone();
+
+  virtual void load_metadata_defaults (text_tset &metadata);
+
+  virtual text_t get_default_formatstring ();
+
+  virtual int output_section_group (ResultDocInfo_t &section, cgiargsclass &args,
+				    const text_t &collection, int colnumber, format_t *formatlistptr, 
+				    bool use_table, text_tset &metadata, bool &getParents,
+				    recptproto *collectproto, displayclass &disp, 
+				    outconvertclass &outconvert, ostream &textout, ostream &logout);
+  
+  virtual int output_section_group (FilterResponse_t &sections, cgiargsclass &args,
+				    const text_t &collection, int colnumber, format_t *formatlistptr, 
+				    bool use_table, text_tset &metadata, bool &getParents,
+				    recptproto *collectproto, displayclass &disp, 
+				    outconvertclass &outconvert, ostream &textout, ostream &logout);
+};
+
+#endif //DATELISTBROWSERCLASS_H
+#endif //GSDL_USE_DATELIST_BROWSER
Index: /gsdl/stable/runtime-src/src/recpt/depositoraction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/depositoraction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/depositoraction.cpp	(revision 20131)
@@ -0,0 +1,930 @@
+/**********************************************************************
+ *
+ * depositoraction.cpp -- 
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_DEPOSITOR_ACTION
+
+// note that the collectoraction relies on having direct access to a
+// collections configuration file. this breaks the separation between
+// receptionist and collection server and so is not suitable (at least
+// in its current form) for use when collection servers are separate 
+// from the receptionist (e.g. when using the CORBA protocol).
+
+// following line required to get fstream.filedesc() on darwin (Mac OS X)
+#define _STREAM_COMPAT  1
+// required for utsname on solaris???
+#define _XOPEN_SOURCE 1
+// This was added for Solaris, but it makes things worse on Solaris for me...
+// #define _XOPEN_SOURCE_EXTENDED 1
+
+#include "depositoraction.h"
+#include "OIDtools.h"
+#include "fileutil.h"
+#include "cfgread.h"
+#include "gsdltools.h"
+#include "gsdltimes.h"
+#include "argdb.h"
+#include "cgiutils.h"
+
+#include <stdio.h>
+//#include <strings.h> // seems to be needed for gcc 2.95, but not particularly happy it
+#include <fcntl.h>
+#include <time.h>
+
+#if !defined (__WIN32__)
+#include <sys/utsname.h>
+#include <unistd.h>
+#endif
+
+#include <new>
+//#include <string>
+#include <vector>
+#include <stdexcept>
+#include <iostream>
+//#include <cstdlib>
+
+depositoraction::depositoraction () 
+  : wizardaction()
+{
+  macro_prefix = "di1";  //deposit item
+  lastpage = 0; 
+
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "a";
+  arg_ainfo.longname = "action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "depositor";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "p";
+  arg_ainfo.longname = "page";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "select";   
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  //furthest page that has been visited
+  arg_ainfo.shortname = "di1lastpage";
+  arg_ainfo.longname = "depositor specific"; 
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";   
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+  
+  // the fileupload info that cgiwrapper produces - we parse the fileupload_t
+  // and set di1userfile, di1userfilesize
+  arg_ainfo.shortname = "di1userfileinfo";
+  arg_ainfo.longname = "depositor specific"; 
+  arg_ainfo.fileupload = true;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;  
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // essential: reset fileupload to default as we are not setting 
+  // it for each arg
+  arg_ainfo.fileupload = false;
+
+  //the name of the file to be added
+  arg_ainfo.shortname = "di1userfile";
+  arg_ainfo.longname = "depositor specific"; 
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;   
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  //the file size
+  arg_ainfo.shortname = "di1userfilesize";
+  arg_ainfo.longname = "depositor specific"; 
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";   
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+ //the file timestamp
+  arg_ainfo.shortname = "di1timestamp";
+  arg_ainfo.longname = "depositor specific"; 
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";   
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // temporary directory name for this collector
+  // session
+  arg_ainfo.shortname = "di1tmp";
+  arg_ainfo.longname = "depositor specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+//   arg_ainfo.shortname = "di1fullname";
+//   arg_ainfo.longname = "depositor specific";
+//   arg_ainfo.multiplechar = true;
+//   arg_ainfo.defaultstatus = cgiarginfo::weak;
+//   arg_ainfo.argdefault = g_EmptyText;
+//   arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+//   argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "di1dirname";
+  arg_ainfo.longname = "depositor specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "di1contactemail";
+  arg_ainfo.longname = "depositor specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+//   arg_ainfo.shortname = "di1clone";
+//   arg_ainfo.longname = "depositor specific";
+//   arg_ainfo.multiplechar = false;
+//   arg_ainfo.defaultstatus = cgiarginfo::weak;
+//   arg_ainfo.argdefault = "0";
+//   arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+//   argsinfo.addarginfo (NULL, arg_ainfo);
+
+//   arg_ainfo.shortname = "di1clonecol";
+//   arg_ainfo.longname = "depositor specific";
+//   arg_ainfo.multiplechar = true;
+//   arg_ainfo.defaultstatus = cgiarginfo::weak;
+//   arg_ainfo.argdefault = g_EmptyText;
+//   arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+//   argsinfo.addarginfo (NULL, arg_ainfo);
+
+//   arg_ainfo.shortname = "cfgfile";
+//   arg_ainfo.longname = "configuration file contents";
+//   arg_ainfo.multiplechar = true;
+//   arg_ainfo.defaultstatus = cgiarginfo::weak;
+//   arg_ainfo.argdefault = g_EmptyText;
+//   arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+//   argsinfo.addarginfo (NULL, arg_ainfo);
+
+//   // will be set if we arrived at the "configure collection" page
+//   // via the "changing an existing collection" page
+//   arg_ainfo.shortname = "di1econf";
+//   arg_ainfo.longname = "depositor specific";
+//   arg_ainfo.multiplechar = false;
+//   arg_ainfo.defaultstatus = cgiarginfo::weak;
+//   arg_ainfo.argdefault = "0";
+//   arg_ainfo.savedarginfo = cgiarginfo::must;
+//   argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // wizard uses this to see if we are working with an existing collection:
+  // set the default to 1
+  arg_ainfo.shortname = "di1esrce";
+  arg_ainfo.longname = "depositor specific";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "1";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+//   arg_ainfo.shortname = "di1input";
+//   arg_ainfo.longname = "depositor specific";
+//   arg_ainfo.multiplechar = true;
+//   arg_ainfo.multiplevalue = true;
+//   arg_ainfo.defaultstatus = cgiarginfo::weak;
+//   arg_ainfo.argdefault = g_EmptyText;
+//   arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+//   argsinfo.addarginfo (NULL, arg_ainfo);
+
+//   //we don't need this in the depositor
+//   arg_ainfo.shortname = "di1inputtype";
+//   arg_ainfo.longname = "depositor specific";
+//   arg_ainfo.multiplechar = true;
+//   arg_ainfo.multiplevalue = true;
+//   arg_ainfo.defaultstatus = cgiarginfo::weak;
+//   arg_ainfo.argdefault = g_EmptyText;
+//   arg_ainfo.savedarginfo = cgiarginfo::mustnot; // saved on disk
+//   argsinfo.addarginfo (NULL, arg_ainfo);
+
+}
+
+depositoraction::~depositoraction () {
+}
+
+
+bool depositoraction::check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, recptprotolistclass * protos, ostream &logout) {
+
+  wizardaction::check_cgiargs(argsinfo,args,protos,logout);
+
+  text_t &current_page = args["p"];
+
+  // note that the "bildstatus" and "bildframe1" pages don't actually do anything
+  // functional so we don't need to worry about authenticating them (it's the 
+  // underlying "bild" page that does the building (and creates the frameset))
+  // This helps us overcome a bit of a problem we have with multiple pages trying
+  // to read from the key.gdb database at the same time.
+
+  //right now, anyone can do anything until it's time to build
+  if (current_page == "select") {
+    //authenticate the user if authentication is available
+    args["uan"] = 1;
+    args["ug"] = "all-collections-editor";
+  }
+
+
+  //Check to see if a file was specified
+  //if so, upload it and set the di1userfile, di1userfilesize, and 
+  //di1timestamp args.
+  //every time a new file is specified, a new timestamped folder is 
+  //created.  
+
+  // This doesn't create a problem but is inefficient (wasted space)
+  // Consider recoding at some point in the future.
+
+  fileupload_t *fileupload = args.getargfile("di1userfileinfo");
+
+  if (fileupload != NULL) {
+
+    if (!(*fileupload).tmp_name.empty() && file_exists((*fileupload).tmp_name)) {
+      // create the timestamp
+      time_t timestamp = time(NULL);
+      text_t timestamp_str(timestamp); 
+
+      args["di1timestamp"] = timestamp_str;
+
+      // set filename and size from the fileupload struct
+      args["di1userfilesize"] = (*fileupload).size;
+      args["di1userfile"] = (*fileupload).name;
+      // copy the file into its temporary location
+      text_t tmpdir = filename_cat(gsdlhome,"tmp",args["di1tmp"],timestamp_str);
+      bool tflag = mk_dir(tmpdir);
+      text_t tmpfile = filename_cat(tmpdir,(*fileupload).name);
+      if (!file_copy((*fileupload).tmp_name, tmpfile)) {
+	cerr << "Depositor error: cannot save uploaded fileto  "<<tmpfile<<endl;
+      } else {
+	cerr << "Depositor: saved uploaded file to "<<tmpfile<<endl;
+      }
+    } 
+  }
+  
+  if (current_page == "select") {  
+ 
+    //make sure the last page arg is re-set to zero 
+    //since a new collection is being chosen
+    args["di1lastpage"] = "0";
+
+    // assign (and create) a temporary directory This will create a new
+    // tbuild directory every time the user goes back to select a new
+    // collection.  It causes no problems except wasted space.  Should be
+    // addressed in the future
+    if (assign_tmpname (args, logout)==false) {
+      // there was an error creating the tmp dir
+      message="tmpfail";
+      return true; // true because we could still parse the arguments
+    }
+
+    // clean up any old builds left laying about in the tmp directory
+    // (note that it's possible this could take some time if there's a huge
+    // partially built collecton laying about so we'll make it an asynchronous
+    // system call)
+    gsdl_system ("perl -S cleantmp.pl", false, logout);
+
+  }
+
+  if (current_page == "bildstatus" || current_page == "bildcancel") {
+    // if .final file exists then build has finished
+    text_t fbld = filename_cat (gsdlhome, "tmp", args[macro_prefix + "tmp"], args[macro_prefix + "dirname"] + ".bld.final");
+    if (file_exists (fbld)) {
+      char *fbldc = fbld.getcstr();
+      ifstream fbld_in (fbldc);
+      if (fbld_in) {
+	failcode = fbld_in.get();
+	fbld_in.close();
+	if (failcode == '0') {
+	  // success - we need to create and configure a collection server for the
+	  // newly built collection (for fastcgi and local library where
+	  // initialization isn't going to be redone when the user clicks the
+	  // "view your new collection" button
+	  create_colserver (args[macro_prefix + "dirname"], logout);
+	  current_page = "bilddone";
+	}
+	else current_page = "bildfail";
+      } else {
+	// assume build failed (we shouldn't get here though ... right?)
+	current_page = "bildfail";
+      }
+      delete []fbldc;
+    }
+  }
+
+  //is it a step page?
+  text_t::const_iterator here = current_page.begin();
+  text_t::const_iterator end = current_page.end();
+  text_t stepstring = substr(here,here+4);
+
+  //if so, increment the step count 
+  //this should not be going up more than one at a time. 
+  if(stepstring == "step") {
+    text_t currpage_textt = substr(here+4,here+5);
+    int currpage = currpage_textt.getint();
+
+    text_t lastpage_textt = args["di1lastpage"]; 
+    int lastpage = lastpage_textt.getint(); 
+    if (currpage > lastpage) {
+      lastpage++; 
+      text_t lastpage_textt(lastpage); 
+      args["di1lastpage"] = lastpage_textt;      
+    }
+
+    // create cached metadata values
+    text_t cached_metadata_values = "";
+    cgiargsclass::const_iterator args_here = args.begin();
+    cgiargsclass::const_iterator args_end = args.end();
+    while (args_here != args_end) {
+      text_t args_name = (*args_here).first;
+      int prefix_len = macro_prefix.size();
+      text_t args_prefix = substr(args_name.begin(),args_name.begin()+prefix_len+3);
+
+      if (args_prefix == (macro_prefix+"md.")) {     
+	text_t args_val = args[args_name];
+	text_t args_suffix = substr(args_name.begin()+prefix_len+3,args_name.end()); 
+
+	text_tarray mdvalues;
+	splitchar (args_val.begin(), args_val.end(), ',', mdvalues);
+	int numvalues = mdvalues.size();
+
+	for (int i = 0; i < numvalues; ++i) {
+	  if (!mdvalues[i].empty()) {	      
+	    decode_cgi_arg(mdvalues[i]);
+
+	    if (cached_metadata_values == "") {
+	      cached_metadata_values = "var CachedMDValues = new Array(\\{";
+	    } else {
+	      cached_metadata_values += ",";
+	    }
+
+	    cached_metadata_values += "\"" + args_name + "\":\"" + args_val + "\"";
+	  }
+	}	
+      }
+      ++args_here;
+    }
+
+    if (cached_metadata_values != "") {
+      cached_metadata_values += "\\});";
+      args["cachedMDValues"] = cached_metadata_values;
+    }
+  }
+  return true;
+}  
+
+
+void depositoraction::define_internal_macros (displayclass &disp, cgiargsclass &args, 
+					      recptprotolistclass *protos, ostream &logout) {
+
+  // define_internal_macros sets some/all of the following macros (depending
+  // on cgiargs):
+  //
+  // _pagescriptextra_
+  // _header_
+  // _depositorbar_
+  // _textfailmsg_
+  // _di1userfile_
+  // _di1userfilesize_
+
+  text_t &depositor_page = args["p"];
+  
+  // set _pagescriptextra_ macro to _cpagescriptextra_
+  disp.setmacro ("pagescriptextra", "depositor", "_" + depositor_page + "scriptextra_");
+
+  if (depositor_page == "bildstatus" || depositor_page == "bilddone" || 
+      depositor_page == "bildfail" || depositor_page == "bildframe1" || 
+      depositor_page == "select") {
+    disp.setmacro ("header", "depositor", "_" + depositor_page + "header_");
+  }
+
+  if (depositor_page == "bildstatus") {
+    set_statusline (disp, args, logout);
+  }
+
+  if (depositor_page == "select") {
+    set_fullnamemenu (disp, args, protos, logout);
+  }
+
+  //how many pages in collection?
+  //we need a _depositorbar_ for each
+
+  text_t numsteps_str;
+  disp.expandstring("depositor", "_numsteps_", numsteps_str);
+  int numsteps = numsteps_str.getint();
+   
+  //is the page a step page? 
+
+  text_t::const_iterator here = depositor_page.begin();
+  text_t::const_iterator end = depositor_page.end();
+  text_t stepstring = substr(here,here+4);
+
+  if((stepstring) == "step" || (depositor_page == "depositonly") ) {
+    disp.setmacro("di1userfile","depositor",args["di1userfile"]);
+    disp.setmacro("di1userfilesize","depositor",args["di1userfilesize"]);
+  }
+
+  //set up the depositor bar
+  text_t depositorbar = "<table class=wizardbar border=0 cellspacing=4 cellpadding=0><tr>\n";
+
+  if(stepstring == "step") {   
+    // check configured metadata elements
+    if (args["metadataconf"] == "var DepositorMDFields = new Array();" || args["metadataconf"] == "") {
+      text_t cfgfile_name = filename_cat (collecthome, args[macro_prefix + "dirname"], "etc", "collect.cfg");
+      text_t cfgfile_content;
+      text_t metadata_str;
+      
+      if (read_file (cfgfile_name, cfgfile_content)) {
+	text_t::const_iterator here = cfgfile_content.begin();
+	text_t::const_iterator end = cfgfile_content.end();
+	while (here != end) {
+	  here = findchar (here, end, 'd');
+	  if (here == end) break;
+	  if ((here+17 < end) && (substr (here, here+17) == "depositormetadata")) {
+	    here = findchar (here, end, '"');
+	    if (here == end) break;	 
+	    text_t enddelimit = "\"\n";
+	    getdelimitstr (here+1, end, enddelimit, metadata_str);
+	    args["metadataconf"] = "var DepositorMDFields = new Array("+metadata_str+");";	    
+	  }
+	  ++here;
+	}
+      }
+
+      if (metadata_str == "") {
+	args["metadataconf"] = "var DepositorMDFields = new Array({\"name\":\"dc.Title\",\"label\":\"Title\",\"tooltip\":\"dc.Title: A name given to the resource.\",\"type\":\"text\"}, {\"name\":\"dc.Creator\",\"label\":\"Creator\",\"tooltip\":\"dc.Creator: An entity primarily responsible for making the content of the resource.\",\"type\":\"text\"}, {\"name\":\"dc.Description\",\"label\":\"Description\",\"tooltip\":\"dc.Description: An account of the content of the resource.\",\"type\":\"textarea\"});";
+      }
+    }
+
+    here = depositor_page.begin();
+    text_t stepnums = substr(here+4,here+5); 
+    int stepnum = stepnums.getint();
+
+    text_t lastpage_textt = args["di1lastpage"];
+    int lastpage = lastpage_textt.getint(); 
+    
+    // again, begin with the select bar...
+    //the first button - selecting a collection
+    for(int i = 1; i <= numsteps; i++) {
+      text_t numstr(i); 
+      if(i <= lastpage && i == stepnum) {
+	depositorbar += get_button (args,depositor_page, "yellow", "step"+numstr, false);
+      } else if (i <= lastpage) {
+	depositorbar += get_button (args,depositor_page, "yellow", "step"+numstr, true); 
+      } else if((i == lastpage+1)){
+	depositorbar += get_button (args,depositor_page, "green", "step"+numstr, true);       
+      } else { 
+	depositorbar += get_button (args,depositor_page, "grey", "step"+numstr, false);       
+      }
+      depositorbar += "<td>_icongreyarrow_</td>\n";
+
+    }    
+
+    //the build and preview pages are always last
+    if(lastpage == numsteps) {
+      depositorbar += get_button (args,depositor_page, "green", "laststep", true);
+    } else {
+      depositorbar += get_button (args,depositor_page, "grey", "laststep", false);
+    }
+
+    text_t laststep_textt;
+    disp.expandstring("depositor", "_laststep_", laststep_textt);
+    if(laststep_textt == "bild") {
+      depositorbar += "<td>_icongreyarrow_</td>\n";
+      depositorbar += get_button (args,depositor_page, "grey", "view", false);
+    }
+    depositorbar += "</tr><tr>"; 
+
+    for(int j = 1; j <= 2*(stepnum-1); j++) {
+      depositorbar += "<td></td>";
+    }
+    depositorbar += "<td align=center>_icongreyuparrow_</td>\n";    
+
+    depositorbar += "</tr></table>\n";
+
+    // set the javascript so that the metadata form can read the existing values
+    if (args["cachedMDValues"] != "") {
+      disp.setmacro("cachedmetadatavalues", "depositor", args["cachedMDValues"]);
+    }
+    if (args["metadataconf"] != "") {
+      disp.setmacro("metadataconf", "depositor", args["metadataconf"]);
+    }    
+  }
+  
+  if ((depositor_page == "bildcancel") || (depositor_page == "bildfail")) {
+  
+    for(int i = 1; i <= numsteps; i++) {
+
+      text_t numstr(i); 
+      depositorbar += get_button (args,depositor_page, "yellow", "step"+numstr, true);       
+      depositorbar += "<td>_icongreyarrow_</td>\n";
+
+    }
+
+    //the build and preview pages are always last
+    depositorbar += get_button (args,depositor_page, "green", "laststep", true);
+    depositorbar += "<td>_icongreyarrow_</td>\n";
+    depositorbar += get_button (args,depositor_page, "grey", "view", false); 
+
+    depositorbar += "</tr><tr>"; 
+
+    for(int j = 1; j <= 2*numsteps; j++) {
+      depositorbar += "<td></td>";
+    }
+    depositorbar += "<td align=center>_icongreyuparrow_</td>\n";    
+
+    depositorbar += "</tr></table>\n";
+
+  }
+
+  if(depositor_page == "bilddone"){
+    
+    for(int i = 1; i <= numsteps; i++) {
+
+      text_t numstr(i); 
+      depositorbar += get_button (args, depositor_page, "grey", "step"+numstr, false);       
+      depositorbar += "<td>_icongreyarrow_</td>\n";
+
+    }
+
+    //the build and preview pages are always last
+    depositorbar += get_button (args,depositor_page, "yellow", "laststep", false);
+    depositorbar += "<td>_icongreyarrow_</td>\n";
+    depositorbar += get_button (args,depositor_page, "green", "view", true);
+
+    depositorbar += "</tr><tr>"; 
+
+    for(int j = 1; j <= 2*numsteps; j++) {
+      depositorbar += "<td></td>";
+    }
+    depositorbar += "<td align=center>_icongreyuparrow_</td>\n";    
+
+    depositorbar += "</tr></table>\n";
+  }
+  disp.setmacro ("depositorbar", "depositor", depositorbar);
+
+  if (depositor_page == "bildfail") {
+ 
+    text_t textfailmsg = "_textfailmsg";
+    textfailmsg.push_back(failcode);
+    textfailmsg.push_back('_');
+    disp.setmacro("textfailmsg", "depositor", textfailmsg);
+
+    text_t bldlog = filename_cat(gsdlhome, "tmp", args["di1tmp"], args["di1dirname"] + ".bld");
+    text_t rawlog = file_tail (bldlog, 6, 0);
+    // we'll shove in some <br> tags where \n's occur
+    text_t faillog;
+    text_t::const_iterator here = rawlog.begin();
+    text_t::const_iterator end = rawlog.end();
+    while (here != end) {
+      if (*here == '\n') faillog += "<br>";
+      faillog.push_back (*here);
+      ++here;
+    }
+    disp.setmacro ("faillog", "depositor", dm_safe(faillog));
+  }
+}
+
+
+//basic framework
+bool depositoraction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/, 
+				 browsermapclass * /*browsers*/, displayclass &disp, 
+				 outconvertclass &outconvert, ostream &textout, 
+				 ostream &logout) {
+  // make sure the depositor is enabled
+  if (disabled) {
+    textout << outconvert 
+	    << "<html>\n"
+	    << "<head>\n"
+	    << "<title>Depositor disabled</title>\n"
+	    << "</head>\n"
+	    << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
+	    << "alink=\"#cc9900\" vlink=\"#666633\">\n"
+	    << "<h2>Facility disabled</h2>\n" 
+	    << "Sorry, the Depositor end-user collecation update facility is currently disabled\n"
+	    << "\n</body>\n"
+	    << "</html>\n";
+    return true;
+  }
+
+  text_t &depositor_page = args["p"];
+  text_t &collection = args["di1dirname"];
+
+  // make sure we have perl (we won't bother with this check for the 
+  // building status pages to avoid slowing things down unneccessarily)
+  if (depositor_page != "bildstatus" && depositor_page != "bildframe1" && !perl_ok(logout)) {
+    textout << outconvert 
+	    << "<html>\n"
+	    << "<head>\n"
+	    << "<title>Perl not found</title>\n"
+	    << "</head>\n"
+	    << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
+	    << "alink=\"#cc9900\" vlink=\"#666633\">\n"
+	    << "<h2>Perl not found</h2>\n" 
+	    << "Greenstone could not detect perl on this system. It is therefore not\n"
+	    << "possible to build a Greenstone collection, either from the Collector or the \n"
+	    << "command-line tools, or to use the Collector for any other task.\n"
+	    << "<p>Please refer to the Greenstone Installer's Guide for details on\n"
+	    << "installing perl on your system.\n"
+	    << "\n</body>\n"
+	    << "</html>\n";
+    return true;
+
+  }
+
+  text_t::const_iterator here = depositor_page.begin();
+  text_t::const_iterator end = depositor_page.end();
+  text_t stepstring = substr(here,here+4);
+
+  if ((depositor_page == "select") || (stepstring == "step")) {
+          textout << outconvert << disp << ("_depositor:header_\n")
+	      << ("_depositor:" + depositor_page + "content_\n")
+	      << ("_depositor:footer_\n");
+	  
+  }
+
+  if ((depositor_page == "bild") || (depositor_page == "depositonly")) {
+
+    text_t filename_textt = args["di1userfile"];
+    text_t timestamp_str = args["di1timestamp"];
+    //check to make sure a file was uploaded
+    //if more than one upload occurred, the last one is taken
+    if(filename_textt == "") {
+      textout << outconvert << disp << "<p> no file available</p>\n"; 
+    } else {
+    
+      text_t col_dirname = filename_cat(collecthome,args[macro_prefix+"dirname"]);
+      text_t import_dirname = filename_cat(col_dirname,"import");
+      if(!directory_exists(import_dirname)) {
+	bool flag = mk_dir(import_dirname);
+	if(!flag) {
+	  cerr << "Error: unable to make directory " << import_dirname << endl;
+	  return true; 
+	}
+      } 
+
+      text_t dirname = filename_cat(import_dirname,timestamp_str);
+      bool flag = mk_dir(dirname);
+      if(!flag) {
+	cerr << "Error: unable to make timestamp directory " << dirname << endl;
+	return true; 
+      }
+
+      text_t filename_textt = args["di1userfile"]; 
+      text_t tmpdir = filename_cat(gsdlhome,"tmp",args["di1tmp"],timestamp_str);
+      text_t tmpfile = filename_cat(tmpdir,filename_textt);
+      text_t filename = filename_cat(dirname, filename_textt);  
+      if(!file_copy(tmpfile, filename)) {
+	cerr << "Unable to copy " << tmpfile << " to " << filename << endl; 
+      }
+      
+      //write the metadata file
+      write_metadata_file(args, filename_textt, timestamp_str); 
+
+      if(depositor_page == "bild"){
+
+	//create a manifest file 
+	write_manifest_file(args, filename_textt, timestamp_str);
+	
+	// do the work (download, import, build) 
+	gsdl_build (args, logout);
+
+	if (message.empty()) {
+	  // bild page is a frameset so we don't want headers and stuff
+	  textout << outconvert << disp << ("_depositor:bildcontent_\n");
+	}
+      }
+    }
+  }
+
+  if (message.empty()) {
+
+    if (depositor_page != "bild" && stepstring != "step" && depositor_page != "select") {
+      // output page ("bild" page was already output above)
+      textout << outconvert << disp << ("_depositor:header_\n")
+	      << ("_depositor:" + depositor_page + "content_\n")
+	      << ("_depositor:footer_\n");
+    }
+  } else {
+    // message was set somewhere (probably an error), output message page
+    textout << outconvert << disp << ("_depositor:header_\n")
+	    << ("_depositor:" + message + "content_\n")
+	    << ("_depositor:footer_\n");
+    message.clear();
+  }
+ 
+  return true;
+
+}
+
+
+//This function creates a metadata.xml file
+void depositoraction::write_metadata_file(cgiargsclass &args, text_t filename_str, text_t& timestamp_str)
+{
+
+    //build metadata file
+    //the front
+    text_t metadata_file = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+    metadata_file += "<!DOCTYPE DirectoryMetadata SYSTEM \"http://greenstone.org/dtd/DirectoryMetadata/1.0/DirectoryMetadata.dtd\">\n"; 
+    metadata_file += "<DirectoryMetadata>\n";
+    metadata_file += "    <FileSet>\n";
+    metadata_file += "        <FileName>";
+
+    // Generate 'regular expression' save version of filename
+    // for now that means escaping any '.' characters
+    // consider generalising as function in gsdltools.h/cpp?
+
+    text_t filename_re;
+    text_t::const_iterator here = filename_str.begin();
+    text_t::const_iterator end = filename_str.end();
+    while (here != end) {
+      if (*here == '.') {
+	filename_re.push_back('\\');
+      }
+
+      filename_re.push_back(*here);
+      ++here;
+    }
+
+    metadata_file += filename_re;
+
+    metadata_file += "</FileName>\n"; 
+    metadata_file += "        <Description>\n";
+
+    
+    cgiargsclass::const_iterator args_here = args.begin();
+    cgiargsclass::const_iterator args_end = args.end();
+
+    while (args_here != args_end) {
+      text_t args_name = (*args_here).first;
+
+      int prefix_len = macro_prefix.size();
+      
+      text_t args_prefix = substr(args_name.begin(),args_name.begin()+prefix_len+3);
+      
+      if (args_prefix == (macro_prefix+"md.")) {     
+        text_t args_val = args[args_name];
+
+	text_t args_suffix = substr(args_name.begin()+prefix_len+3,args_name.end()); 
+
+	text_tarray mdvalues;
+	splitchar (args_val.begin(), args_val.end(), ',', mdvalues);
+	int numvalues = mdvalues.size();
+
+	for (int i = 0; i < numvalues; ++i) {
+	  if (!mdvalues[i].empty()) {
+
+	    decode_cgi_arg(mdvalues[i]);
+
+	    metadata_file += "            <Metadata mode=\"accumulate\" name=\"";	    
+	    metadata_file += args_suffix;
+	    metadata_file += "\">";
+	    metadata_file += mdvalues[i];
+	    metadata_file += "</Metadata>\n";
+
+	  }
+	}
+      }	      
+
+      ++args_here;
+    }
+    
+    //the end of the file
+    metadata_file += "        </Description>\n"; 
+    metadata_file += "    </FileSet>\n"; 
+    metadata_file += "</DirectoryMetadata>\n"; 
+
+    //create metadata.xml file
+    text_t metadata_path = filename_cat(collecthome, args[macro_prefix+"dirname"], "import", timestamp_str, "metadata.xml");
+    text_t my_path = filename_cat(gsdlhome,"tmp", "metadata.xml");
+
+    ofstream metadata(metadata_path.getcstr());
+    ofstream my_tmp(my_path.getcstr()); 
+
+    if(!metadata.is_open()) {
+      cerr << "Cannot open metadata.xml!" << endl; 
+    } else {
+
+      //write metadata.xml
+      metadata.write(metadata_file.getcstr(), metadata_file.size()); 
+      my_tmp.write(metadata_file.getcstr(), metadata_file.size()); 
+    }
+}
+
+//This function creates a manifest.xml file
+void depositoraction::write_manifest_file(cgiargsclass &args, text_t filename, 
+					  text_t& timestamp_str)
+{
+
+    //build manifest file
+
+    //the front
+    text_t manifest_file = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+    manifest_file += "<Manifest>\n";
+    manifest_file += "    <Import>\n";
+    manifest_file += "        <Filename>\n";
+    manifest_file += "          " + timestamp_str + "\n";
+    manifest_file += "        </Filename>\n"; 
+    
+    //the end of the file
+    manifest_file += "    </Import>\n"; 
+    manifest_file += "</Manifest>\n"; 
+
+    //create manifest.xml file
+    text_t manifest_path = filename_cat(collecthome, args[macro_prefix+"dirname"], "manifest.xml");
+
+    char* manifest_cstr = manifest_path.getcstr();
+
+    ofstream manifest(manifest_cstr);
+
+    if(!manifest.is_open()) {
+      cerr << "Cannot open" << manifest_cstr << endl; 
+    } else {
+
+      //write manifest.xml
+      char *manifest_file_cstr = manifest_file.getcstr();
+      manifest.write(manifest_file_cstr, manifest_file.size()); 
+      delete [] manifest_file_cstr;
+    }
+
+    delete [] manifest_cstr;
+}
+
+
+
+text_t depositoraction::get_button(cgiargsclass &args, const text_t &thispage, 
+				   const text_t &color, 
+				   const text_t &type, bool enabled) 
+{
+
+  text_t::const_iterator here = type.begin();
+  text_t::const_iterator end = type.end();
+  text_t stepstring = substr(here,here+4);
+  if ((color != "green" && color != "grey" && color != "yellow") ||
+      (type != "select" && type != "laststep" && stepstring != "step" && type != "view"))
+    return g_EmptyText;
+
+  text_t href = "_http"+type+"_";
+  text_t target = "";
+
+  here = thispage.begin();
+  stepstring = substr(here,here+4);  
+  if (thispage == "bildcancel" || thispage == "bildfail" || thispage == "select"|| stepstring == "step") {
+    // call the check submit macro instead of linking directly to the page
+
+    if(type == "laststep") {
+      href="\"javascript:check_submit('_"+type+"_');\"";
+    } else {
+      href="\"javascript:check_submit('"+type+"');\"";
+    }
+
+  } else if (type == "view") {
+   //target = " target=_top";
+    target = " target=_blank";
+  }
+
+  text_t tdclass = "wizardbar"+color; 
+  if (enabled) {
+    // link to the appropriate page
+    return "<td class="+tdclass+"><a href="+href+target+">_text"+type+"_</a></td>";
+  }
+  else {
+    // just display the text
+    return "<td class="+tdclass+">_text"+type+"_</td>";
+  }
+}
+
+
+#endif //GSDL_USE_DEPOSITOR_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/depositoraction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/depositoraction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/depositoraction.h	(revision 20131)
@@ -0,0 +1,71 @@
+/**********************************************************************
+ *
+ * depositoraction.h -- 
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_DEPOSITOR_ACTION
+
+#ifndef DEPOSITORACTION_H
+#define DEPOSITORACTION_H
+
+#include "wizardaction.h"
+#include "receptionist.h"
+
+class depositoraction : public wizardaction {
+  
+protected:
+
+  int lastpage; 
+
+public:
+  depositoraction ();
+  virtual ~depositoraction ();
+
+  void write_metadata_file(cgiargsclass &args, text_t filename_str, text_t& timestamp_str);
+
+  void write_manifest_file(cgiargsclass &args, text_t filename, text_t& timestamp_str);
+
+  text_t get_action_name () {return "depositor";}
+
+  bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+		      recptprotolistclass *protos, ostream &logout);
+
+  //we need to redefine this
+  void define_internal_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+
+  //and this
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+
+  text_t get_button(cgiargsclass &args, const text_t &thispage, 
+		    const text_t &color, 
+		    const text_t &type, bool enabled);
+
+};
+
+#endif //!DEPOSITORACTION_H
+#endif //GSDL_USE_DEPOSITOR_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/documentaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/documentaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/documentaction.cpp	(revision 20131)
@@ -0,0 +1,1640 @@
+/**********************************************************************
+ *
+ * documentaction.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include <string.h>
+
+#include "documentaction.h"
+#include "recptprototools.h"
+#include "OIDtools.h"
+#include "querytools.h"
+#include "unitool.h"
+#include "gsdltools.h"
+#include "highlighttext.h"
+#include "browsetoolsclass.h"
+
+documentaction::documentaction () {
+  recpt = NULL;
+
+  // this action uses cgi variables "a", "d", "cl",
+  // "x", "gc", "gt", "gp", and "hl"
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "a";
+  arg_ainfo.longname = "action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "p";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "d";
+  arg_ainfo.longname = "document OID";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::none;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::can;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // whether or not a document should be retrieved from the 
+  // library or the Web.
+  arg_ainfo.shortname = "il";
+  arg_ainfo.longname = "internal link preference";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "l";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "cl";
+  arg_ainfo.longname = "classification OID";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::none;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::can;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // in this action "gc" controls the expand/contract
+  // contents function
+  arg_ainfo.shortname = "gc";
+  arg_ainfo.longname = "expand contents";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::can;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // in this action "gt" controls the expand/contract
+  // text function 0 = not expanded, 1 = expand unless 
+  // there are more than 10 sections containing text,
+  // 2 = expand all
+  arg_ainfo.shortname = "gt";
+  arg_ainfo.longname = "expand text";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::can;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // in this action "gp" is the "go to page" control
+  // used by the Book type of toc
+  arg_ainfo.shortname = "gp";
+  arg_ainfo.longname = "go to page";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::none;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // in this action "hl" is the "highlighting on/
+  // highlighting off control ("hl" == "2" is a
+  // special case that forces phrase highlighting
+  // to be used even if the query string doesn't
+  // appear to be a phrase)
+  arg_ainfo.shortname = "hl";
+  arg_ainfo.longname = "highlighting on/off";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "1";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "x" is 0 normally or 1 if page
+  // has been "detached"
+  arg_ainfo.shortname = "x";
+  arg_ainfo.longname = "detached page";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "xx" is 0 normally or 1 if documents should be detached by default
+  arg_ainfo.shortname = "xx";
+  arg_ainfo.longname = "detach all doc pages";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  
+  // f arg is set to 1 if document is to 
+  // be displayed in a frame
+  arg_ainfo.shortname = "f";
+  arg_ainfo.longname = "frame";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // fc arg is "1" if search bar is to be included (i.e. if "fc" == 1
+  // the httpdocument macro will include "&f=1"
+  arg_ainfo.shortname = "fc";
+  arg_ainfo.longname = "include search bar";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "1";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  //rd is whether a document will be displayed
+  //with a relevant document list
+  arg_ainfo.shortname = "rd";
+  arg_ainfo.longname = "include relevant documents";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  //dm is the metadata that has been used for the datelist
+  arg_ainfo.shortname = "dm";
+  arg_ainfo.longname = "date metadata";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+}
+
+documentaction::~documentaction()
+{
+}
+
+bool documentaction::check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+				    recptprotolistclass *protos, ostream &logout) {
+
+   if(!args["d"].empty())
+      {
+	 text_t docTop;
+	 get_top(args["d"],docTop);
+	 
+	 recptproto* collectproto = protos->getrecptproto (args["c"], logout);
+	 if (collectproto != NULL)
+	    {
+	       ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr (collectproto, args["c"], logout);
+	       
+	       if(cinfo->authenticate == "document") 
+		  {
+		     // both are either commented out or uncomment and are empty
+		     if (cinfo->public_documents.empty() && cinfo->private_documents.empty())
+			{
+			   //deny everything
+			   args["uan"] = "1";
+			   args["ug"] = cinfo->auth_group;
+			}
+
+		     // both public_documents and private_documents are turned on !
+		     else if (!cinfo->public_documents.empty() && !cinfo->private_documents.empty())
+			{
+			   //deny everything
+			   args["uan"] = "1";
+			   args["ug"] = cinfo->auth_group;
+			}
+		     
+		     // if public_documents is set but this document isn't
+		     // listed in it we need to authenticate
+		     else if ((!cinfo->public_documents.empty()) && 
+			      (cinfo->public_documents.find(docTop) == cinfo->public_documents.end()))
+		       {
+			 args["uan"] = "1";
+			 args["ug"] = cinfo->auth_group;
+		       }
+		     
+		     // if private_documents is set and this document is
+		     // listed in it we need to authenticate
+		     else if ((!cinfo->private_documents.empty()) &&
+			      (cinfo->private_documents.find(docTop) != cinfo->private_documents.end()))
+		       {
+			 args["uan"] = "1";
+			 args["ug"] = cinfo->auth_group;
+		       }
+		     
+		  }
+	    }
+      }
+   // check gc argument
+   int arg_gc = args.getintarg("gc");
+  if (arg_gc < 0 || arg_gc > 2) {
+    logout << "Warning: \"gc\" argument out of range (" << arg_gc << ")\n";
+    cgiarginfo *gcinfo = argsinfo.getarginfo ("gc");
+    if (gcinfo != NULL) args["gc"] = gcinfo->argdefault;
+  }
+
+  // check gt argument (may be either 0, 1 or 2)
+  int arg_gt = args.getintarg("gt");
+  if (arg_gt != 0 && arg_gt != 1 && arg_gt != 2) {
+    logout << "Warning: \"gt\" argument out of range (" << arg_gt << ")\n";
+    cgiarginfo *gtinfo = argsinfo.getarginfo ("gt");
+    if (gtinfo != NULL) args["gt"] = gtinfo->argdefault;
+  }
+
+  // check hl argument
+  int arg_hl = args.getintarg("hl");
+  if (arg_hl < 0 || arg_hl > 2) {
+    logout << "Warning: \"hl\" argument out of range (" << arg_hl << ")\n";
+    cgiarginfo *hlinfo = argsinfo.getarginfo ("hl");
+    if (hlinfo != NULL) args["hl"] = hlinfo->argdefault;
+  }
+
+  // check x argument
+  int arg_x = args.getintarg("x");
+  if (arg_x != 0 && arg_x != 1) {
+    logout << "Warning: \"x\" argument out of range (" << arg_x << ")\n";
+    cgiarginfo *xinfo = argsinfo.getarginfo ("x");
+    if (xinfo != NULL) args["x"] = xinfo->argdefault;
+  }
+
+  //checks whether rd arg is valid
+  int arg_rd = args.getintarg("rd");
+  if (arg_rd != 0 && arg_rd != 1) {
+    logout << "Warning: \"rd\" argument out of range (" << arg_rd << ")\n";
+    cgiarginfo *rdinfo = argsinfo.getarginfo ("rd");
+    if (rdinfo != NULL) args["rd"] = rdinfo->argdefault;
+  }
+
+
+  return true;
+}
+
+void documentaction::get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+				       response_t &response,text_t &response_data, 
+				       ostream &logout) {
+
+  if ((args["il"] == "w") && (!args["d"].empty())) {
+
+    recptproto* collectproto = protos->getrecptproto (args["c"], logout);
+    if (collectproto != NULL) {
+      
+      text_tset metadata;
+      FilterResponse_t filt_response;
+      text_t top;
+
+      metadata.insert ("URL");
+      
+      // get metadata for parent document
+      get_top (args["d"], top);
+      if (get_info (top, args["c"], args["l"], metadata, false, collectproto, filt_response, logout)) {
+	text_t url = filt_response.docInfo[0].metadata["URL"].values[0];
+	
+	response = location;
+	response_data = url;
+	return;
+      } else {
+	// error, no URL
+	logout << "Error: documentaction::get_cgihead_info failed on get_info" << endl;
+      }
+    }
+  }
+  response = content;
+  response_data = "text/html";
+}
+
+// set_widthtspace calculates how wide the spaces in the nav bar should
+// be and sets the appropriate macro
+void documentaction::set_spacemacro (displayclass &disp, FilterResponse_t &response,
+				     bool has_search_button) {
+
+  text_t width;
+  int twidth, swidth, iwidth = 0;
+
+  int numc = response.docInfo.size();
+  ResultDocInfo_tarray::iterator dochere = response.docInfo.begin();
+  ResultDocInfo_tarray::iterator docend = response.docInfo.end();
+	
+  disp.expandstring (displayclass::defaultpackage, "_pagewidth_", width);
+  twidth = width.getint();
+
+  if (has_search_button) {
+    disp.expandstring ("query", "_searchwidth_", width);
+    iwidth += width.getint();
+  } else {
+    numc -= 1;
+  }
+  
+  while (dochere != docend) {
+    const text_t &title = (*dochere).metadata["Title"].values[0];
+
+    disp.expandstring ("document", "_" + title + "width_", width);
+    if (width == ("_" + title + "width_")) {
+      disp.expandstring ("document", "_defaultwidth_", width);
+    }
+    iwidth += width.getint();
+    ++dochere;
+  }
+
+  if ((twidth - iwidth) < numc) swidth = 2;
+  else {
+    swidth = twidth - iwidth;
+    if (numc > 0) swidth = swidth / numc;
+  }
+  disp.setmacro ("widthtspace", displayclass::defaultpackage, swidth);
+}
+
+// set_navbarmacros sets _navigationbar_ and _httpbrowseXXX_ macros
+// reponse contains 1 metadata field (Title)
+void documentaction::set_navbarmacros (displayclass &disp, FilterResponse_t &response, 
+				       bool has_search_button, cgiargsclass &args,
+				       ColInfoResponse_t &cinfo) {
+
+
+   bool use_pulldown = false;
+   text_tmap::iterator it = cinfo.format.find("NavigationBar");
+   if (it != cinfo.format.end()) {
+      if (it->second == "pulldown") {
+	 use_pulldown = true;
+      }
+   }
+
+   text_t topparent;
+   text_t &arg_d = args["d"];
+   text_t navigationbar = "<!-- Navigation Bar -->\n";
+
+   get_top (args["cl"], topparent);
+   int numc = response.docInfo.size();
+   ResultDocInfo_tarray::iterator dochere = response.docInfo.begin();
+   ResultDocInfo_tarray::iterator docend = response.docInfo.end();
+
+   if (!use_pulldown) {
+      if (has_search_button) {
+	// search uses its own navtab, as it may be suppressed based on other args
+	navigationbar += "_navtabsearch_";
+	if (args["a"] == "q") {
+	  navigationbar += "(selected)";
+	}
+      }
+      
+      if (has_search_button || numc == 0) navigationbar += "_navbarspacer_";
+      
+      bool first = true;
+      while (dochere != docend) {
+	if (!first) navigationbar += "_navbarspacer_";
+	
+	text_t title = (*dochere).metadata["Title"].values[0];
+	
+	navigationbar += "_navtab_(_httpbrowse"+(*dochere).OID+"_,"+title;
+	// if we are at this classifier
+	if (arg_d.empty() && ((*dochere).OID == topparent)) {
+	   // don't link to this classifier as it is the current one
+	   navigationbar += ",selected";
+	 }
+	 navigationbar += ")";
+
+	// set the _httpbrowseCLX_ macro for this classification
+	disp.setmacro ("httpbrowse" + (*dochere).OID, displayclass::defaultpackage, "_httpdocument_&amp;cl=" + (*dochere).OID);
+	 ++dochere;
+	 first = false;
+      }
+      
+      navigationbar += "_dynamicclassifiernavbarentries_";
+      navigationbar += "\n<!-- End of Navigation Bar -->\n";
+
+   } else {
+
+      navigationbar = "<form method=\"get\" name=\"navform\">\n";
+      navigationbar += "<select name=\"navbar\" onChange=\"location.href=";
+      navigationbar += "document.navform.navbar.options[document.navform.navbar.selectedIndex].value\">\n";
+
+      if (args["a"] != "q" && args["cl"].empty()) {
+	 navigationbar += "<option value=\"\" selected>_textselectpage_</option>\n";
+      }
+      
+      if (has_search_button) {
+	 navigationbar += "<option value=\"_httpquery_\"";
+	 if (args["a"] == "q") {
+	    navigationbar += " selected";
+	 }
+	 navigationbar += ">_labelSearch_</option>\n";
+      }
+
+      while (dochere != docend) {
+	 text_t title = dochere->metadata["Title"].values[0];	 
+
+	 navigationbar += "<option value=\"_httpdocument_&amp;cl=" + dochere->OID + "\"";
+	 if (topparent == dochere->OID) {
+	    navigationbar += " selected";
+	 }
+	 navigationbar += ">_navlinktitle_(" + title + ")</option>\n";
+	 ++dochere;
+      }
+
+      navigationbar += "</select>\n";
+      navigationbar += "</form>\n";
+   }
+
+   disp.setmacro ("navigationbar", displayclass::defaultpackage, navigationbar);
+}
+
+// define all the macros which might be used by other actions
+// to produce pages. 
+void documentaction::define_external_macros (displayclass &disp, cgiargsclass &args, 
+					     recptprotolistclass *protos, ostream &logout) {
+  
+  // define_external_macros sets the following macros:
+
+  // _navigationbar_     this is the navigation bar containing the search button
+  //                     and any classification buttons - it goes at the top of 
+  //                     most pages. for now we're assuming that there'll always 
+  //                     be a search button - we should probably check that there
+  //                     is a query action before making this assumption
+
+  // _httpbrowseXXX_     the http macros for each classification (i.e. if there
+  //                     are Title and Creator classifications _httpbrowseTitle_
+  //                     and _httpbrowseCreator_ will be set
+
+  // _widthtspace_       the width of the spacers between buttons in navigation
+  //                     bar
+  
+  // _httpdocument_      has '&f=1' added if displaying document inside a frame
+
+  // _gsdltop_           macro to replace _top targets with
+
+  // _httppagehome_      overridden home url if html collections have own homepage
+
+  // _usability_         macros for remote usability reporting: if
+  // _usabinterface_     "format Usability [multi|textonly|stepwise]" is in 
+  // _usabilityscript_   collect.cfg
+
+  // _versionnnum_   greenstone version number (hard-coded)
+  // must have a valid collection server to continue
+   
+  text_t &collection = args["c"];
+  if (collection.empty()) return;
+  recptproto *collectproto = protos->getrecptproto (collection, logout);
+  if (collectproto == NULL) return;
+  
+  if (recpt == NULL) {
+    logout << "ERROR (documentaction::define_external_macros): This action does not contain\n"
+	   << "      information about any receptionists. The method set_receptionist was\n"
+	   << "      probably not called from the module which instantiated this action.\n";
+    return;
+  }
+
+  outconvertclass text_t2ascii;
+  comerror_t err;
+  InfoFiltersResponse_t filterinfo;
+  FilterResponse_t response;
+  text_tset metadata;
+
+  // get info on current collection and load up formatinfo
+  // I'd prefer not to do this here as we're getting 
+  // collection info every time (and probably also getting
+  // it in other places some of the time) - One day I'll
+  // fix it ... maybe - Stefan.
+  ColInfoResponse_t cinfo;
+
+  collectproto->get_collectinfo (collection, cinfo, err, logout);
+  load_formatinfo (cinfo.format, args.getintarg("gt"));
+  //  ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr (collectproto, collection, logout);
+  //  if (cinfo == NULL) {
+  //    logout << "ERROR (documentaction::define_external_macros): get_collectinfo_ptr returned NULL\n";
+  //    return;
+  //  }
+  //load_formatinfo (cinfo->format, args.getintarg("gt"));
+
+  if (formatinfo.DocumentUseHTML) {
+
+    // frame stuff
+    if (args["fc"] == "1") {
+      text_t httpdocument;
+      disp.expandstring (displayclass::defaultpackage, "_httpdocument_", httpdocument);
+      httpdocument += "&amp;f=1";
+      disp.setmacro ("httpdocument", displayclass::defaultpackage, httpdocument);
+      disp.setmacro ("gsdltop", displayclass::defaultpackage, "documenttop");
+      formatinfo.DocumentText = "[Text]";
+    }
+    text_tmap::iterator it = cinfo.format.find ("homepage");
+    if (it != cinfo.format.end()) {
+      text_t httppagehome;
+      if (get_link (args, protos, (*it).second, httppagehome, logout))
+	disp.setmacro ("httppagehome", displayclass::defaultpackage, httppagehome);
+    } 
+  }
+
+  // don't want navigation bar if page is 'detached'
+  if (!args.getintarg("x")) {
+
+    collectproto->get_filterinfo (collection, filterinfo, err, logout);
+    if (err == noError) {
+      // check that there's a browse filter
+      if (filterinfo.filterNames.find ("BrowseFilter") != filterinfo.filterNames.end()) {
+	
+	metadata.insert ("Title");
+	bool getParents = false;
+	get_children ("", collection, args["l"], metadata, getParents, collectproto, response, logout);
+	
+	bool has_search_button = true;
+	collectproto->is_searchable(collection, has_search_button, err, logout);
+	if (err != noError) has_search_button = false;
+
+	// calculate width of spacers and set _widthtspace_ macro
+	if (args.getintarg("v") == 0) set_spacemacro (disp, response, has_search_button);
+
+	// set _navigationbar_ macro
+	set_navbarmacros (disp, response, has_search_button, args, cinfo);
+   
+      }
+    } else {
+      logout << text_t2ascii 
+	     << "Error (documentaction::define_external_macros()) in call to get_filterinfo() " 
+	     << get_comerror_string (err);
+    }
+  }
+
+  // send feedback button and pages
+  text_tmap::iterator usability = cinfo.format.find("Usability");
+  if(usability!=cinfo.format.end()){
+    disp.setmacro("usability",displayclass::defaultpackage,"_usablink_");
+    disp.setmacro("usabinterface",displayclass::defaultpackage,("_usab"+(*usability).second+"_"));
+    disp.setmacro("usabilityscript", displayclass::defaultpackage, "_usabshowscript_");
+  }
+
+  // version num
+  disp.setmacro("versionnum", displayclass::defaultpackage, GSDL_VERSION);
+
+}
+
+bool documentaction::get_link (cgiargsclass &args, recptprotolistclass *protos,
+			       const text_t &inlink, text_t &outlink, ostream &logout) {
+
+  FilterResponse_t response;
+  text_tset metadata;
+  metadata.insert ("section");
+  
+  // check current collection first
+  recptproto *collectproto = protos->getrecptproto (args["c"], logout);
+
+  if (get_info (inlink, args["c"], args["l"], metadata, false, collectproto, response, logout)) {
+    if (!response.docInfo[0].metadata["section"].values[0].empty()) {
+#ifndef DOCHANDLE
+      outlink = "_httpdocument_&amp;d=" + response.docInfo[0].metadata["section"].values[0];
+#else
+      outlink = "_httpdocumenthandle_("+args["c"]+","+response.docInfo[0].metadata["section"].values[0]+")";
+#endif
+
+      return true;
+    }
+  }
+
+  // check all the other enabled collections
+
+  if (args["ccs"] == "1" && !args["cc"].empty()) {
+    text_tarray collections;
+    splitchar (args["cc"].begin(), args["cc"].end(), ',', collections);
+    
+    text_tarray::const_iterator col_here = collections.begin();
+    text_tarray::const_iterator col_end = collections.end();
+
+    while (col_here != col_end) {
+	  
+      // don't need to check current collection again
+      if (*col_here == args["c"]) {++col_here; continue;}
+	  
+      collectproto = protos->getrecptproto (*col_here, logout);
+      
+      if (get_info (inlink, *col_here, args["l"], metadata, false, collectproto, response, logout)) {
+	if (!response.docInfo[0].metadata["section"].values[0].empty()) {
+#ifndef DOCHANDLE
+	  outlink = "_httpdocument_&amp;c=" + *col_here + "&amp;d=" +
+	    response.docInfo[0].metadata["section"].values[0];
+#else
+	  outlink = "_httpdocumenthandle_("+*col_here+","+response.docInfo[0].metadata["section"].values[0]+")";
+#endif
+
+	  return true;
+	}
+      }
+      ++col_here;
+    }
+  }
+  return false;
+}
+
+void documentaction::load_formatinfo (const text_tmap &colformat, int gt) {
+
+  formatinfo.clear();
+  text_tmap::const_iterator format_here = colformat.begin();
+  text_tmap::const_iterator format_end = colformat.end();
+
+  while (format_here != format_end) {
+    if (((*format_here).first == "DocumentImages") && 
+	((*format_here).second == "true"))
+      formatinfo.DocumentImages = true;
+    else if (((*format_here).first == "DocumentTitles") && 
+	     ((*format_here).second == "false"))
+      formatinfo.DocumentTitles = false;
+    else if ((*format_here).first == "DocumentHeading") 
+      formatinfo.DocumentHeading = (*format_here).second;
+    else if (((*format_here).first == "DocumentContents") && 
+	     ((*format_here).second == "false"))
+      formatinfo.DocumentContents = false;
+    else if (((*format_here).first == "DocumentArrowsBottom") && 
+	     ((*format_here).second == "false"))
+      formatinfo.DocumentArrowsBottom = false;
+    else if (((*format_here).first == "DocumentArrowsTop") && 
+	     ((*format_here).second == "true"))
+      formatinfo.DocumentArrowsTop = true;
+    else if ((*format_here).first == "DocumentButtons")
+      splitchar ((*format_here).second.begin(), (*format_here).second.end(),
+		 '|', formatinfo.DocumentButtons);
+    else if ((*format_here).first == "DocumentText") 
+      formatinfo.DocumentText = (*format_here).second;  
+    else if ((*format_here).first == "RelatedDocuments")
+      formatinfo.RelatedDocuments = (*format_here).second; 
+    else if (((*format_here).first == "DocumentUseHTML") && 
+	     ((*format_here).second == "true"))
+      formatinfo.DocumentUseHTML = true;
+    else if (((*format_here).first == "AllowExtendedOptions") && 
+	     ((*format_here).second == "true"))
+      formatinfo.AllowExtendedOptions = true;
+    else 
+      formatinfo.formatstrings[(*format_here).first] = (*format_here).second;
+    
+    ++format_here;
+  }
+
+  // never want arrows when text is expanded
+  if (gt) {
+    formatinfo.DocumentArrowsBottom = false;
+    formatinfo.DocumentArrowsTop = false;
+  }
+}
+
+
+// define all the macros which are related to pages generated
+// by this action. we also load up the formatinfo structure 
+// here (it's used in do_action as well as here)
+void documentaction::define_internal_macros (displayclass &disp, cgiargsclass &args, 
+					     recptprotolistclass *protos, ostream &logout) {
+  
+  // define_internal_macros sets the following macros:
+  
+  // _pagetitle_            the title to be displayed at the top of the browser window
+  
+  // _imagethispage_        the title image to be displayed at top right of page
+
+  // _navarrowsbottom_      this may be overridden to "" when format option 
+  //                        DocumentArrowsBottom is false
+
+  // _navarrowstop_         likewise for DocumentArrowsTop
+
+  // _httpprevarrow_        links to next and previous sections of document - used
+  // _httpnextarrow_        by DocumentArrowsBottom
+
+  // _header_               the header macro is overridden if we're not at a top level 
+  //                        classification to remove the title block
+
+  // _thisOID_              the OID (directory) of the current document - this corresponds
+  //                        to the archivedir metadata element
+
+  // _documentheader_       Custom header info for the specified document
+  // must have a valid collection server to continue
+
+   text_t &collection = args["c"];
+  if (collection.empty()) return;
+  recptproto *collectproto = protos->getrecptproto (collection, logout);
+  if (collectproto == NULL) return;
+
+  text_tset metadata;
+  FilterResponse_t response;
+  text_t &arg_d = args["d"];
+  text_t &arg_cl = args["cl"];
+
+  if (!formatinfo.DocumentArrowsBottom) {
+    disp.setmacro("navarrowsbottom", "document", "");
+  } else if (!formatinfo.DocumentArrowsBottom) {
+    disp.setmacro("navarrowstop", "document", "");
+  } 
+
+  if (!arg_d.empty() && (formatinfo.DocumentArrowsBottom || formatinfo.DocumentArrowsTop)) {
+    // set _httpprevarrow_ and _httpnextarrow_
+    set_arrow_macros (args, collectproto, disp, logout);
+  }
+
+  metadata.insert ("Title");
+  metadata.insert ("gs.DocumentHeader");
+  metadata.insert ("DocumentHeader");
+  
+  bool fulltoc = false;
+
+  if (args["cl"] != "search") {
+    // see if there's a FullTOC string
+    text_t cl_top, full_toc;
+    get_top (arg_cl, cl_top);
+    if (get_formatstring (cl_top, "FullTOC", formatinfo.formatstrings, full_toc))
+      if (full_toc == "true") fulltoc = true;
+    disp.setmacro("cltop", "document", cl_top);
+  }
+  
+  if (!arg_d.empty() && !fulltoc) {
+    // we're at document level
+
+    metadata.insert ("archivedir");
+
+    comerror_t err;
+    OptionValue_tarray options;
+    // we need to do the query again for the z3950proto
+    if (collectproto->get_protocol_name(err)=="z3950proto") {
+      OptionValue_t opt;
+      opt.name="Term";opt.value=args["q"];options.push_back(opt);
+      opt.name="QueryType";
+      opt.value=(args.getintarg("t")) ? "ranked" : "boolean";
+      options.push_back(opt);
+      opt.name="Index";opt.value=args["h"];options.push_back(opt);
+    }
+    
+    //do not display relation metadata
+    disp.setmacro ("relateddoc", "document", "");  
+       
+    //if preferences indicate relevant docs should be collected
+    //and there is no particular format specified then display
+    //this default format.
+     if(args["rd"] == "1" && formatinfo.RelatedDocuments.empty()){
+
+       text_t relation = g_EmptyText; //string for displaying relation metadata
+
+       //call function in formattools.cpp which will return the text of the 
+       //related documents in a vertical list. This is the default format.
+
+       if (get_info (arg_d, collection, args["l"], metadata, options, false, collectproto, response, logout)) 
+	 relation += get_related_docs(collection, collectproto, response.docInfo[0], logout);
+       
+       //set macro to be the related document string
+
+       disp.setmacro ("relateddoc", "document", relation); 
+     }
+     
+  
+    // get metadata for this document and it's parents
+    if (get_info (arg_d, collection, args["l"], metadata, options, 
+		  true, collectproto, response, logout)) {
+
+      disp.setmacro ("header", "document", "_textheader_");
+      text_tarray pagetitlearray;
+      if (!response.docInfo[0].metadata["Title"].values[0].empty())
+	pagetitlearray.push_back (response.docInfo[0].metadata["Title"].values[0]);
+      
+      if (args["gt"] != "1") {
+	MetadataInfo_t *parenttitle = response.docInfo[0].metadata["Title"].parent;
+	while (parenttitle != NULL) {
+	  if (!parenttitle->values[0].empty())
+	    pagetitlearray.push_back (parenttitle->values[0]);
+	  parenttitle = parenttitle->parent;
+	}
+      }
+      reverse (pagetitlearray.begin(), pagetitlearray.end());
+      text_t pagetitle;
+      joinchar (pagetitlearray, ": ", pagetitle);
+      // remove html tags from the title
+      text_t::iterator open_tag=pagetitle.begin();
+      while (open_tag < pagetitle.end()) {
+	if (*open_tag == '<') {
+	  text_t::iterator close_tag=open_tag+1;
+	  text_t::iterator donechar=pagetitle.end();
+	  while (close_tag < donechar) {
+	    if (*close_tag == '>')
+	      break;
+	    ++close_tag;
+	  }
+	  if (close_tag < donechar) // remove this html tag, replace with space
+	    *close_tag=' ';
+	  pagetitle.erase(open_tag, close_tag);
+	}
+	++open_tag;
+      }
+      disp.setmacro ("pagetitle", "document", pagetitle);
+
+      // custom header info
+      text_t custom_header;
+      if (is_top (arg_d)) {
+	custom_header = response.docInfo[0].metadata["gs.DocumentHeader"].values[0];
+	if (custom_header.empty()) {
+	  // try ex header
+	  custom_header = response.docInfo[0].metadata["DocumentHeader"].values[0]; 
+	}
+      } else {
+	MetadataInfo_t *parentch = response.docInfo[0].metadata["gs.DocumentHeader"].parent;
+	while (parentch != NULL) {
+	  custom_header = parentch->values[0];
+	  parentch = parentch->parent;
+	}
+	if (custom_header.empty()) {
+	  // try ex header
+	  MetadataInfo_t *parentch = response.docInfo[0].metadata["DocumentHeader"].parent;
+	  while (parentch != NULL) {
+	    custom_header = parentch->values[0];
+	    parentch = parentch->parent;
+	  }
+	}
+      }
+      if (!custom_header.empty()) {
+	disp.setmacro("documentheader", "document", custom_header);
+      }
+	
+      if (is_top (arg_d))
+	disp.setmacro ("thisOID", displayclass::defaultpackage, dm_safe(response.docInfo[0].metadata["archivedir"].values[0]));
+      else {
+	MetadataInfo_t *parentad = response.docInfo[0].metadata["archivedir"].parent;
+	text_t thisOID;
+	while (parentad != NULL) {
+	  thisOID = parentad->values[0];
+	  parentad = parentad->parent;
+	}
+	disp.setmacro ("thisOID", displayclass::defaultpackage, dm_safe(thisOID));
+      }
+    }
+  } else {
+    if (!arg_cl.empty()) {
+	
+      // create the currentnodevalue macro - this is the value of the node
+      // in the hierarchy that is currently open.
+      if (get_info (arg_cl, collection, args["l"], metadata, false, collectproto, response, logout)) {
+	text_t &title = response.docInfo[0].metadata["Title"].values[0];
+	disp.setmacro ("currentnodevalue", "document", title);
+      }
+      // get metadata for top level classification
+      text_t classtop;
+      get_top (arg_cl, classtop);
+      metadata.insert ("childtype");
+      metadata.insert ("parameters");
+
+      if (get_info (classtop, collection, args["l"], metadata, false, collectproto, response, logout)) {
+	  
+	text_t &title = response.docInfo[0].metadata["Title"].values[0];
+	bool unknown = false;
+
+	// test if we have macros defined for this classification's
+	// metadata name - if not we'll just display the name
+	text_t tmp;
+	text_t macroname="_label" + title + "_";
+	disp.expandstring ("Global", macroname, tmp);
+	if (tmp == macroname) unknown = true; // it wasn't expanded
+
+	if (unknown) {
+	  disp.setmacro ("pagetitle", "document", title);
+	} else {
+	  disp.setmacro ("pagetitle", "document", macroname);
+	}
+	/* for ns4/image layout compatibility. when this is no longer
+	 * needed, set imagethispage to _label+title+_ */
+	text_t titlemacroname="_titleimage" + title + "_";
+	disp.expandstring ("Global", titlemacroname, tmp);
+	if (tmp == titlemacroname) { /* _titleimage$META_ isn't defined */
+	  if (!unknown) /* _label$META_ is defined */
+	    disp.setmacro ("imagethispage", "document", macroname);
+	  else
+	    disp.setmacro ("imagethispage", "document", title);
+	} else { /* _titleimage$META_ is defined */
+	  disp.setmacro ("imagethispage", "document", titlemacroname);
+	}
+
+      	//if the document is not a document from a collection
+	//we must set the macro to be an empty string
+	disp.setmacro ("relateddoc", "document", ""); 
+
+	// Add macros specific to the Collage/Phind classifiers 
+	text_t &childtype = response.docInfo[0].metadata["childtype"].values[0];
+	if (childtype == "Collage") {
+
+	  text_t::iterator a = arg_cl.begin();
+	  text_t::iterator b = arg_cl.end();
+
+	  bool collage = true;
+	  while (a != b) {
+	    if (*a == 46) collage = false;
+	    ++a;
+	  }
+
+	  if (collage) {
+	    disp.setmacro ("collageclassifier", "document", "_collageapplet_");
+
+            // Next, macros that control the way the classifier is displayed
+            text_t parameters = response.docInfo[0].metadata["parameters"].values[0];
+
+            // extract key=value pairs and set as macros
+            text_t::iterator here = parameters.begin();
+            text_t::iterator end = parameters.end();
+            text_t key, value;
+
+            while (here != end) {
+              // get the next key and value pair
+              here = getdelimitstr (here, end, '=', key);
+              here = getdelimitstr (here, end, ';', value);
+
+              // store this key=value pair
+              if (!key.empty() && !value.empty()) {
+                disp.setmacro ("collage"+key, "document", value);
+              }
+            }
+
+	    
+	  }
+	}
+
+	if (childtype == "Phind") {
+
+	  // First, a macro to display the phind classifier
+	  disp.setmacro ("phindclassifier", "document", "_phindapplet_");
+
+	  // Next, macros that control the way the classifier is displayed
+	  text_t parameters = response.docInfo[0].metadata["parameters"].values[0];
+
+	  // extract key=value pairs and set as macros
+	  text_t::iterator here = parameters.begin();
+	  text_t::iterator end = parameters.end();
+	  text_t key, value;
+	  
+	  while (here != end) {
+	    // get the next key and value pair
+	    here = getdelimitstr (here, end, '=', key);
+	    here = getdelimitstr (here, end, ';', value);
+
+	    // store this key=value pair
+	    if (!key.empty() && !value.empty()) {
+	      disp.setmacro (key, "document", value);
+	    }
+	  }
+	} // end if (childtype == "Phind")
+      }
+    } // end if (!arg_cl.empty()) {
+  }
+}
+
+
+bool documentaction::do_action(cgiargsclass &args, recptprotolistclass *protos, 
+                               browsermapclass *browsers, displayclass &disp, 
+                               outconvertclass &outconvert, ostream &textout, 
+                               ostream &logout)
+{
+  if ((args["book"] == "flashxml") && (!args["d"].empty()))
+  {
+  	return do_action_flashxml(args,protos,browsers,disp,outconvert,textout,logout);
+  }
+  else if ((args["book"] == "on") && (!args["d"].empty())) 
+  {
+  	return do_action_book(args,protos,browsers,disp,outconvert,textout,logout);
+  }
+  else 
+  {
+   	return do_action_html(args,protos,browsers,disp,outconvert,textout,logout);
+  }
+
+}
+
+//displaying the normal display when bookswitch=0(html)
+bool documentaction::do_action_html(cgiargsclass &args, recptprotolistclass *protos, 
+                               browsermapclass *browsers, displayclass &disp, 
+                               outconvertclass &outconvert, ostream &textout, 
+                               ostream &logout)
+{
+  // must have a valid collection server
+  recptproto *collectproto = protos->getrecptproto (args["c"], logout);
+  if (collectproto == NULL) {
+    logout << "documentaction::do_action called with NULL collectproto\n";
+    textout << outconvert << disp << "_document:header_\n" 
+	    << "Error: Attempt to get document without setting collection\n"
+	    << "_document:footer_\n";
+  } else {  
+    
+    text_t OID = args["d"];
+    if (OID.empty()) OID = args["cl"];
+    if (OID.empty()) {
+      textout << outconvert << disp << "Document contains no data_document:footer_\n";
+      return true;
+    }
+
+  
+    if (formatinfo.DocumentUseHTML && !args["d"].empty()) {
+      
+      if (args["f"] == "1") {
+	textout << outconvert << disp 
+		<< "<html><head></head>\n"
+		<< "<frameset rows=\"68,*\" noresize border=0>\n"
+		<< "<frame scrolling=no frameborder=0 src=\"_gwcgi_?_optsite_e=_compressedoptions_&a=p&p=nav\">\n"
+#ifndef DOCHANDLE
+		<< "<frame name=\"documenttop\" frameborder=0 src=\"_gwcgi_?_optsite_e=_compressedoptions_&a=d&d=" 
+		<< args["d"] << "\">"
+#else
+		<< "<frame name=\"documenttop\" frameborder=0 src=\"_httpdocumenthandle_(" 
+		<< args["c"] << "," << args["d"] << ")\">"
+#endif
+		<< "<noframes>\n"
+		<< "<p>You must have a frame enabled browser to view this.</p>\n"
+		<< "</noframes>\n"
+		<< "</frameset>\n"
+		<< "</html>\n";
+      } else {
+	output_document (OID, args, collectproto, browsers, disp, outconvert, textout, logout);	
+      }
+      return true;
+    }
+
+   
+    textout << outconvert << disp << "_document:header_\n"
+	    << "_document:content_\n";
+      
+    // output the table of contents
+    browsetoolsclass b;
+    b.output_toc(args, browsers, formatinfo, collectproto, 
+                 disp, outconvert, textout, logout);
+   
+    if (formatinfo.DocumentArrowsTop && !args["d"].empty()) {
+      textout << outconvert << disp << "_document:navarrowstop_\n";
+    }
+
+    //output the related documents (may be the empty string)
+    //will not output the docs if a format string is specified
+    textout << outconvert << disp << "_document:relateddoc_\n";
+
+    // output the document text
+    if (!args["d"].empty()) {
+      output_document (OID, args, collectproto, browsers, disp, outconvert, textout, logout);
+    }
+
+    textout << outconvert << disp << "_document:footer_\n";
+  }
+  return true;
+}
+
+//displaying the book display when bookswitch=on
+bool documentaction::do_action_book(cgiargsclass &args, recptprotolistclass *protos, 
+                               browsermapclass *browsers, displayclass &disp, 
+                               outconvertclass &outconvert, ostream &textout, 
+                               ostream &logout)
+{
+  // must have a valid collection server
+  recptproto *collectproto = protos->getrecptproto (args["c"], logout);
+  if (collectproto == NULL) 
+  {
+    	logout << "documentaction::do_action called with NULL collectproto\n";
+    	textout << outconvert << disp << "_document:header_\n" 
+		<< "Error: Attempt to get document without setting collection\n";
+  } 
+  else 
+  {  
+    	text_t OID = args["d"];
+    	if (OID.empty()) OID = args["cl"];
+    	if (OID.empty()) 
+	{
+      		textout << outconvert << disp << "Document contains no data\n";
+      		return true;
+    	}
+
+    	if (formatinfo.DocumentUseHTML && !args["d"].empty()) 
+	{
+      		if (args["f"] == "1") 
+		{
+			textout << outconvert << disp 
+				<< "<html><head></head>\n"
+				<< "<frameset rows=\"68,*\" noresize border=0>\n"
+				<< "<frame scrolling=no frameborder=0 src=\"_gwcgi_?_optsite_e=_compressedoptions_&a=p&p=nav\">\n"
+			#ifndef DOCHANDLE
+				<< "<frame name=\"documenttop\" frameborder=0 src=\"_gwcgi_?_optsite_e=_compressedoptions_&a=d&d=" 
+				<< args["d"] << "\">"
+			#else
+				<< "<frame name=\"documenttop\" frameborder=0 src=\"_httpdocumenthandle_(" 
+				<< args["c"] << "," << args["d"] << ")\">"
+			#endif
+				<< "<noframes>\n"
+				<< "<p>You must have a frame enabled browser to view this.</p>\n"
+				<< "</noframes>\n"
+				<< "</frameset>\n"
+				<< "</html>\n";
+      		} 
+		else 
+		{
+			output_document (OID, args, collectproto, browsers, disp, outconvert, textout, logout);	
+      		}
+      		
+		return true;
+    	}
+
+
+	//the header bit and the navigation button   
+    	textout << outconvert << disp << "_document:header_\n" << "_document:content_\n";
+       
+	//display the book
+	textout << outconvert << disp << "_document:flashbook_\n";
+	
+	//the footer bit without the document arrow
+	textout << outconvert << disp << "</div> <!-- id=document -->\n";
+	textout << outconvert << disp << "_endspacer__htmlfooter_\n";
+  }
+  
+  return true;
+}
+
+//Displaying the xml when bookswitch=flashxml
+bool documentaction::do_action_flashxml(cgiargsclass &args, recptprotolistclass *protos, 
+                               browsermapclass *browsers, displayclass &disp, 
+                               outconvertclass &outconvert, ostream &textout, 
+                               ostream &logout)
+{
+  // must have a valid collection server
+  recptproto *collectproto = protos->getrecptproto (args["c"], logout);
+  if (collectproto == NULL) 
+  {
+    logout << "documentaction::do_action called with NULL collectproto\n";
+    textout << outconvert << disp 
+	    << "<Message>\n"
+	    << "  Error: Attempt to get document without setting collection\n"
+	    << "</Message>\n";
+  } 
+  else 
+  {  
+    text_t OID = args["d"];
+    if (OID.empty()) OID = args["cl"];
+    if (OID.empty()) 
+    {
+      textout << outconvert << disp 
+	      << "<Message>\n"
+	      << "  Document contains no data\n"
+	      << "</Message>\n";
+      return true;
+    }
+
+    if (formatinfo.DocumentUseHTML && !args["d"].empty())
+    {  
+      if (args["f"] == "1") 
+      {
+	textout << outconvert << disp 
+		<< "<Message>\n"
+		<< "  Using frames makes no sense for XML output\n"
+		<< "</Message>\n";
+      } 
+      else 
+      {
+	output_document_flashxml (OID, args, collectproto, browsers, disp, outconvert, textout, logout);	
+      }
+
+      return true;
+    }
+
+    // output the document text
+    if (!args["d"].empty()) 
+    {
+      output_document_flashxml (OID, args, collectproto, browsers, disp, outconvert, textout, logout);
+    }
+  }
+
+  return true;
+}
+
+
+
+void documentaction::output_text (ResultDocInfo_t &docinfo, format_t *formatlistptr,
+				  const TermInfo_tarray &terminfo, const text_t &OID,
+				  bool highlight, int hastxt, int wanttext, 
+				  text_t &collection, recptproto *collectproto,
+				  browsermapclass *browsers, displayclass &disp,
+				  outconvertclass &outconvert, ostream &textout,
+				  ostream &logout, cgiargsclass &args) {
+  
+  DocumentRequest_t docrequest;
+  DocumentResponse_t docresponse;
+  comerror_t err;
+  if (hastxt == 1) {
+
+    if (wanttext) {
+      // get the text
+      docrequest.OID = OID;
+      collectproto->get_document (collection, docrequest, docresponse, err, logout);
+
+      // cut down on overhead by not using formattools if we only want the text
+      // (wanttext will equal 2 if we want text and other stuff too)
+      if (wanttext == 1)
+	if (highlight) {
+	  highlighttext(docresponse.doc, args, terminfo, disp, outconvert, textout);
+	} else {
+	  textout << outconvert << disp << docresponse.doc;
+	}
+    }
+  
+    if (wanttext != 1) {
+      text_tmap options;
+      options["text"] = docresponse.doc;
+
+      if (formatinfo.AllowExtendedOptions) {
+        browsetoolsclass b;
+	b.load_extended_options(options, args, browsers, formatinfo, 
+                                collectproto, disp, outconvert, logout);
+      }
+      
+      text_t doctext 
+	 = get_formatted_string (collection, collectproto, docinfo, disp,
+				 formatlistptr, options, logout); 
+      
+      if (highlight) {
+	highlighttext(doctext, args, terminfo, disp, outconvert, textout);
+      } else {
+	textout << outconvert << disp << doctext;
+      }
+    }
+  }
+}
+
+
+void documentaction::output_document (const text_t &OID, cgiargsclass &args, 
+				      recptproto *collectproto, browsermapclass *browsers,
+				      displayclass &disp, outconvertclass &outconvert,
+				      ostream &textout, ostream &logout) {
+  FilterResponse_t inforesponse;
+  FilterResponse_t queryresponse;
+  text_tset metadata;
+  bool getParents = false;
+  bool highlight = false;
+  int wanttext = 0;
+  int arg_gt = args.getintarg("gt");
+  text_t &collection = args["c"];
+    
+  // if we have a query string and highlighting is turned on we need
+  // to redo the query to get the terms for highlighting
+  
+  if (!args["q"].empty() && args.getintarg("hl")) {
+
+    ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr (collectproto, collection, logout);
+    bool segment = false;
+    if (cinfo != NULL) {
+      segment = cinfo->isSegmented;
+    }
+    FilterRequest_t request;
+    comerror_t err;
+    request.filterResultOptions = FRmatchTerms;
+    text_t formattedstring = args["q"];
+    format_querystring (formattedstring, args.getintarg("b"), segment);
+    set_queryfilter_options (request, formattedstring, args);
+    args["q"] = formattedstring; // need to set this here for phrase 
+                   // highlighting, where we look at the querystring
+    collectproto->filter (args["c"], request, queryresponse, err, logout);
+    if (err != noError) {
+      outconvertclass text_t2ascii;
+      logout << text_t2ascii
+	     << "documentaction::output_document: call to QueryFilter failed "
+	     << "for " << args["c"] << " collection (" << get_comerror_string (err) << ")\n";
+      highlight = false;
+    } else {
+      highlight = true;
+    }
+  }
+
+  format_t *formatlistptr = new format_t();
+  parse_formatstring (formatinfo.DocumentText, formatlistptr, metadata, getParents);
+
+  metadata.insert ("hastxt");
+  metadata.insert ("haschildren");
+
+  if (formatinfo.DocumentText == "[Text]")
+    wanttext = 1;
+  else {
+    char *docformat = formatinfo.DocumentText.getcstr();
+    if (strstr (docformat, "[Text]") != NULL)
+      wanttext = 2;
+    delete []docformat;
+  }
+    
+  textout << outconvert << "<div class=\"documenttext\">\n";
+
+  if (get_info (OID, collection, args["l"], metadata, getParents, collectproto, inforesponse, logout)) {
+    int hastxt = inforesponse.docInfo[0].metadata["hastxt"].values[0].getint();
+    int haschildren = inforesponse.docInfo[0].metadata["haschildren"].values[0].getint();
+    
+    if (arg_gt == 0) {
+      output_text (inforesponse.docInfo[0], formatlistptr, queryresponse.termInfo, 
+		   OID, highlight, hastxt, wanttext, collection, collectproto, 
+		   browsers, disp, outconvert, textout, logout, args);
+
+    } else {
+
+      ResultDocInfo_t thisdocinfo = inforesponse.docInfo[0];
+	
+      // text is to be expanded
+      text_t exOID = OID;
+      if (haschildren != 1) exOID = get_parent (OID);
+      if (exOID.empty()) exOID = OID;
+	
+      // if we're not in a document (i.e. we're in a top level classification)
+      // we need to pass "is_classify = true" to get_contents so that it 
+      // doesn't recurse all the way through each document in the classification
+      bool is_classify = false;
+      if (args["d"].empty()) is_classify = true;
+
+      get_contents (exOID, is_classify, metadata, collection, args["l"], 
+		    collectproto, inforesponse, logout);
+	
+      ResultDocInfo_tarray::iterator sechere = inforesponse.docInfo.begin();
+      ResultDocInfo_tarray::iterator secend = inforesponse.docInfo.end();
+
+      if (arg_gt == 1) {
+	// check if there are more than 10 sections containing text to be expanded - 
+	// if there are output warning message - this isn't a great way to do this
+	// since the sections may be very large or very small - one day I'll fix it 
+	// -- Stefan.
+	int seccount = 0;
+	while (sechere != secend) {
+	  int shastxt = (*sechere).metadata["hastxt"].values[0].getint();
+	  if (shastxt == 1) ++seccount;
+	  if (seccount > 10) break;
+	  ++sechere;
+	}
+	if (seccount > 10) {
+	  // more than 10 sections so output warning message and text 
+	  // for current section only
+	  textout << outconvert << disp << "<div class=\"warning\">_document:textltwarning_</div>\n";
+
+	  output_text (thisdocinfo, formatlistptr, queryresponse.termInfo, 
+		       OID, highlight, hastxt, wanttext, collection, 
+		       collectproto, browsers, disp, outconvert, textout, logout, args);
+	  
+	}
+	else arg_gt = 2;
+      }
+
+      if (arg_gt == 2) {
+	// get the text for each section
+	sechere = inforesponse.docInfo.begin();
+	int count = 0;
+	while (sechere != secend) {
+	  textout << outconvert << disp << "\n<p><a name=" << (*sechere).OID << "></a>\n";
+
+	  int shastxt = (*sechere).metadata["hastxt"].values[0].getint();
+
+	  output_text (*sechere, formatlistptr, queryresponse.termInfo, 
+		       (*sechere).OID, highlight, shastxt, wanttext, collection, 
+		       collectproto, browsers, disp, outconvert, textout, logout, args);
+	  ++count;
+	  ++sechere;
+	}
+      }
+    }
+  }
+  textout << outconvert << "</div>\n";
+  delete formatlistptr;
+}
+
+void documentaction::output_document_flashxml(const text_t &OID, cgiargsclass &args, 
+				      recptproto *collectproto, browsermapclass *browsermap,
+				      displayclass &disp, outconvertclass &outconvert,
+				      ostream &textout, ostream &logout) {
+	//if this is not at the document level --> do Nothing!!
+	if (args["d"].empty())
+		return;
+		
+	//if we have a query string and highlighting is turned on we need
+  	//to redo the query to get the terms for highlighting
+	FilterResponse_t queryresponse;
+  	bool highlight = false;
+	if (!args["q"].empty() && args.getintarg("hl")) 
+	{
+		text_t &collection = args["c"];
+    		ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr (collectproto, collection, logout);
+    		bool segment = false;
+    		if (cinfo != NULL) 
+		{
+      			segment = cinfo->isSegmented;
+    		}
+    		FilterRequest_t request;
+    		comerror_t err;
+    		request.filterResultOptions = FRmatchTerms;
+    		text_t formattedstring = args["q"];
+    		format_querystring (formattedstring, args.getintarg("b"), segment);
+    		set_queryfilter_options (request, formattedstring, args);
+    		args["q"] = formattedstring; 	//need to set this here for phrase 
+                   				//highlighting, where we look at the querystring
+    		collectproto->filter (args["c"], request, queryresponse, err, logout);
+    		if (err != noError)
+		{
+      			outconvertclass text_t2ascii;
+      			logout << text_t2ascii
+	     			<< "documentaction::output_document: call to QueryFilter failed "
+	     			<< "for " << args["c"] << " collection (" << get_comerror_string (err) << ")\n";
+      			highlight = false;
+    		} 
+		else 
+		{
+     			highlight = true;
+    		}
+  	}
+	
+	FilterResponse_t response;
+	bool getParents = false;
+	text_tset metadata;
+	text_t classifytype, classification, formatstring;
+	
+	//metadata elements needed by recurse_contents
+  	metadata.insert ("Title");
+	metadata.insert ("haschildren");
+
+  	//protocol call
+  	if (!get_info (OID, args["c"], args["l"], metadata, getParents, collectproto, response, logout))
+    		return;
+
+  	recurse_contents (response.docInfo[0], args, metadata, 
+			    getParents, collectproto, disp, outconvert, textout, logout, highlight, queryresponse.termInfo);
+}
+
+void documentaction::recurse_contents(ResultDocInfo_t &section, cgiargsclass &args,
+                                        text_tset &metadata, bool &getParents, 
+                                        recptproto *collectproto, displayclass &disp, 
+                                        outconvertclass &outconvert, ostream &textout, ostream &logout, 
+					bool highlight, const TermInfo_tarray &terminfo)
+{
+ 	text_t formatstring;
+
+  	bool is_classify = false;
+  	
+  	//output this section 
+  	text_t classification = "Document";
+  	
+	textout << outconvert << disp << "<Section>\n";
+	
+	//get the title
+	textout << outconvert << disp << "<Description>\n<Metadata name=\"Title\">";
+	text_t t_title = section.metadata["Title"].values[0];
+	//if it is highlighted
+	/*if (highlight == true)
+	{
+		highlighttext(t_title, args, terminfo, disp, outconvert, textout);
+	}
+	else
+	{*/
+		textout << outconvert << disp << t_title;
+	//}
+	textout << outconvert << disp << "</Metadata>\n</Description>\n";
+	
+	//get the text
+	DocumentRequest_t docrequest;
+	DocumentResponse_t docresponse;
+	comerror_t err;
+	docrequest.OID = section.OID;
+	text_t &collection = args["c"];
+	collectproto->get_document(collection, docrequest, docresponse, err, logout);
+	//if it is highlighted
+	if (highlight == true)
+	{
+		highlighttext(docresponse.doc, args, terminfo, disp, outconvert, textout);
+	}
+	else
+	{
+		textout << outconvert << disp << docresponse.doc;
+	}
+	textout << outconvert << disp << "\n";
+	
+  	int haschildren = section.metadata["haschildren"].values[0].getint();
+  	
+  	// recurse through children
+  	if (haschildren == 1)
+	{
+    		FilterResponse_t tmp;
+    		get_children (section.OID, args["c"], args["l"], metadata, getParents, collectproto, tmp, logout);
+    		ResultDocInfo_tarray::iterator thisdoc = tmp.docInfo.begin();
+    		ResultDocInfo_tarray::iterator lastdoc = tmp.docInfo.end();
+
+    		while (thisdoc != lastdoc) 
+		{
+      			recurse_contents (*thisdoc, args, metadata, getParents, collectproto, disp, outconvert, textout, logout, highlight, terminfo);
+      			++thisdoc;
+    		}
+  	}
+	
+	textout << outconvert << disp << "</Section>\n";
+}
+
+void documentaction::set_arrow_macros (cgiargsclass &args, recptproto *collectproto,
+				       displayclass &disp, ostream &logout) {
+
+  text_tset metadata;
+  FilterResponse_t response;
+  FilterResponse_t presponse;
+
+  int haschildren = 0;
+  text_tarray next_siblings;
+  text_t previous_sibling;
+  text_t &arg_d = args["d"];
+
+  // get info on current section
+  metadata.insert("haschildren");
+  if (!get_info(arg_d, args["c"], args["l"], metadata, false, collectproto, response, logout)) {
+    logout << "error 1 in documentaction::set_arrow_macros\n";
+    return;
+  }
+  haschildren = response.docInfo[0].metadata["haschildren"].values[0].getint();
+      
+  // get OIDs of next and previous siblings of current section and
+  // all it's parents
+  int parentcount = countchar(arg_d.begin(), arg_d.end(), '.');
+  text_t thisoid = arg_d;
+  while (parentcount > 0) {
+    get_children (get_parent(thisoid), args["c"], args["l"], metadata, false, 
+		  collectproto, response, logout);
+    ResultDocInfo_tarray::iterator this_sibling = response.docInfo.begin();
+    ResultDocInfo_tarray::iterator last_sibling = response.docInfo.end();
+    bool first = true;
+    while (this_sibling != last_sibling) {
+      if ((*this_sibling).OID == thisoid) {
+	if (!first && next_siblings.empty()) {
+	  previous_sibling = (*(this_sibling-1)).OID;
+	  int section_has_children = (*(this_sibling-1)).metadata["haschildren"].values[0].getint();
+	  // if previous sibling has children we need to recurse
+	  // down to the last descendant
+	  while (section_has_children) {
+	    get_children (previous_sibling, args["c"], args["l"], metadata, false, 
+			  collectproto, presponse, logout);
+	    if (!presponse.docInfo.empty()) {
+	      ResultDocInfo_tarray::iterator it = presponse.docInfo.end() - 1;
+	      previous_sibling = (*it).OID;
+	      section_has_children = (*it).metadata["haschildren"].values[0].getint();
+	    } else {
+	      section_has_children = 0; // this should never happen
+	    }
+	  }
+	}
+	    
+	if ((this_sibling+1) != last_sibling) {
+	  next_siblings.push_back((*(this_sibling+1)).OID);
+	} else {
+	  next_siblings.push_back("");
+	}
+	break;
+      }
+      ++this_sibling;
+      first = false;
+    }
+    thisoid = get_parent(thisoid);
+    --parentcount;
+  }
+
+  // work out values for next link
+  if (haschildren) {
+#ifndef DOCHANLE
+    disp.setmacro ("httpnextarrow", "document", "_httpdocument_&amp;cl=" + args["cl"] +
+		   "&amp;d=" + arg_d + ".fc");
+#else
+    disp.setmacro ("httpnextarrow", "document", "_httpdocumenthandle_("+args["c"]+","+arg_d + ".fc)";
+
+#endif
+
+  } else {
+    text_tarray::const_iterator h = next_siblings.begin();
+    text_tarray::const_iterator e = next_siblings.end();
+    while (h != e) {
+      if (!(*h).empty()) {
+#ifndef DOCHANLE
+	disp.setmacro ("httpnextarrow", "document", "_httpdocument_&amp;cl=" + args["cl"] +
+		       "&amp;d=" + *h);
+#else
+	disp.setmacro ("httpnextarrow", "document", "_httpdocumenthandle_("+args["c"]+","+*h+")";
+
+#endif
+
+	break;
+      }
+      ++h;
+    }
+  }
+
+  // work out value for previous link
+  if (!previous_sibling.empty()) {
+#ifndef DOCHANDLE
+    disp.setmacro ("httpprevarrow", "document", "_httpdocument_&amp;cl=" + args["cl"] +
+		   "&amp;d=" + previous_sibling);
+#else
+    disp.setmacro ("httpprevarrow", "document", "_httpdocumenthandle_("+args["c"]+","+ previous_sibling+")");
+
+#endif
+
+  } else {
+    if (countchar(arg_d.begin(), arg_d.end(), '.')) {
+#ifndef DOCHANDLE
+      disp.setmacro ("httpprevarrow", "document", "_httpdocument_&amp;cl=" + args["cl"] +
+		     "&amp;d=" + get_parent(arg_d));
+#else
+      disp.setmacro ("httpprevarrow", "document", "_httpdocumenthandle_("+args["c"]+","+get_parent(arg_d)+")");
+
+#endif
+
+    }
+  }
+}
Index: /gsdl/stable/runtime-src/src/recpt/documentaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/documentaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/documentaction.h	(revision 20131)
@@ -0,0 +1,129 @@
+/**********************************************************************
+ *
+ * documentaction.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef DOCUMENTACTION_H
+#define DOCUMENTACTION_H
+
+#include "action.h"
+#include "gsdlconf.h"
+#include "formattools.h"
+#include "receptionist.h"
+#include "browserclass.h"
+
+class documentaction : public action {
+
+protected:
+
+  receptionist *recpt;
+
+  formatinfo_t formatinfo;
+  typedef map<text_t, format_t*, lttext_t> format_tmap; 
+  
+  bool get_link (cgiargsclass &args, recptprotolistclass *protos,
+		 const text_t &inlink, text_t &outlink, ostream &logout);
+
+  void load_formatinfo (const text_tmap &colformat, int gt);
+
+  void set_spacemacro (displayclass &disp, FilterResponse_t &response,
+		       bool has_search_button);
+
+  void set_navbarmacros (displayclass &disp, FilterResponse_t &response, 
+			 bool has_search_button, cgiargsclass &args,
+			 ColInfoResponse_t &cinfo);
+
+  virtual void output_text (ResultDocInfo_t &docinfo, format_t *formatlistptr,
+			    const TermInfo_tarray &terminfo, const text_t &OID,
+			    bool highlight, int hastxt, int wanttext, 
+			    text_t &collection, recptproto *collectproto,
+			    browsermapclass *browsers, displayclass &disp,
+			    outconvertclass &outconvert, ostream &textout,
+			    ostream &logout, cgiargsclass &args);
+
+  virtual void output_document (const text_t &OID, cgiargsclass &args, 
+				recptproto *collectproto, browsermapclass *browsers,
+				displayclass &disp,  outconvertclass &outconvert,
+				ostream &textout,  ostream &logout);
+
+
+  virtual void output_document_flashxml (const text_t &OID, cgiargsclass &args, 
+				    recptproto *collectproto, browsermapclass *browsers,
+				    displayclass &disp, outconvertclass &outconvert,
+				    ostream &textout, ostream &logout);
+
+  virtual void recurse_contents(ResultDocInfo_t &section, cgiargsclass &args,
+                                        text_tset &metadata, bool &getParents, 
+                                        recptproto *collectproto, displayclass &disp, 
+                                        outconvertclass &outconvert, ostream &textout, ostream &logout, 
+					bool highlight, const TermInfo_tarray &terminfo);
+				    
+  void set_arrow_macros (cgiargsclass &args, recptproto *collectproto,
+			 displayclass &disp, ostream &logout);
+
+public:
+  documentaction ();
+  virtual ~documentaction ();
+
+  void set_receptionist (receptionist *therecpt) {recpt=therecpt;}
+
+  text_t get_action_name () {return "d";}
+
+  bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+		      recptprotolistclass *protos, ostream &logout);
+
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response,text_t &response_data, 
+			 ostream &logout);
+
+  void define_external_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+
+  virtual void define_internal_macros (displayclass &disp, cgiargsclass &args, 
+				       recptprotolistclass *protos, ostream &logout);
+
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+
+  bool do_action_html(cgiargsclass &args, recptprotolistclass *protos, 
+		      browsermapclass *browsers, displayclass &disp, 
+		      outconvertclass &outconvert, ostream &textout, 
+		      ostream &logout);
+
+  bool do_action_flashxml(cgiargsclass &args, recptprotolistclass *protos, 
+		     browsermapclass *browsers, displayclass &disp, 
+		     outconvertclass &outconvert, ostream &textout, 
+		     ostream &logout);
+
+  bool do_action_book(cgiargsclass &args, recptprotolistclass *protos, 
+                               browsermapclass *browsers, displayclass &disp, 
+                               outconvertclass &outconvert, ostream &textout, 
+                               ostream &logout);
+};
+
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/dynamicclassifieraction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/dynamicclassifieraction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/dynamicclassifieraction.cpp	(revision 20131)
@@ -0,0 +1,623 @@
+/**********************************************************************
+ *
+ * dynamicclassifieraction.cpp -- 
+ * Copyright (C) 2008  DL Consulting Ltd
+ *
+ * By Michael Dewsnip
+ * Please do not edit this file without checking with Michael first!
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "dynamicclassifieraction.h"
+#include "recptprototools.h"
+
+
+dynamicclassifieraction::dynamicclassifieraction ()
+{
+  recpt = NULL;
+
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "dcl";
+  arg_ainfo.longname = "dynamic classifier ID";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "dcn";
+  arg_ainfo.longname = "dynamic classifier node";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+}
+
+
+dynamicclassifieraction::~dynamicclassifieraction()
+{
+}
+
+
+bool dynamicclassifieraction::check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+					     recptprotolistclass *protos, ostream &logout)
+{
+  return true;
+}
+
+
+void dynamicclassifieraction::get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+						response_t &response,text_t &response_data, 
+						ostream &logout)
+{
+  response = content;
+  response_data = "text/html";
+}
+
+
+void dynamicclassifieraction::define_external_macros (displayclass &disp, cgiargsclass &args, 
+						      recptprotolistclass *protos, ostream &logout)
+{
+  // Some pages (e.g. the library home page) are not collection-specific
+  if (args["c"].empty())
+  {
+    return;
+  }
+
+  // A valid collection server is vital
+  recptproto *collectproto = protos->getrecptproto (args["c"], logout);
+  if (collectproto == NULL)
+  {
+    logout << "dynamicclassifieraction::define_external_macros called with NULL collectproto\n";
+    return;
+  }
+
+  // Define _dynamicclassifiernavbarentries_ to add buttons to the navigation bar for the dynamic classifiers
+  text_t navigation_bar_entries = "";
+  ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr (collectproto, args["c"], logout);
+  text_tmap::iterator dynamic_classifier_iterator = cinfo->dynamic_classifiers.begin();
+  while (dynamic_classifier_iterator != cinfo->dynamic_classifiers.end())
+  {
+    text_t dynamic_classifier_id = (*dynamic_classifier_iterator).first;
+    navigation_bar_entries += "_navbarspacer_";
+    navigation_bar_entries += "_navtab_(_gwcgi_?c=" + args["c"] + "&amp;a=dc&amp;dcl=" + dynamic_classifier_id + "," + dynamic_classifier_id;
+    if (args["a"] == "dc" && args["dcl"] == dynamic_classifier_id)
+    {
+      navigation_bar_entries += ",selected";
+    }
+    navigation_bar_entries += ")";
+    dynamic_classifier_iterator++;
+  }
+
+  disp.setmacro("dynamicclassifiernavbarentries", displayclass::defaultpackage, navigation_bar_entries);
+}
+
+
+void dynamicclassifieraction::define_internal_macros (displayclass &disp, cgiargsclass &args, 
+						      recptprotolistclass *protos, ostream &logout)
+{
+  // No internal macros set
+}
+
+
+bool dynamicclassifieraction::do_action(cgiargsclass &args, recptprotolistclass *protos, 
+					browsermapclass *browsers, displayclass &disp, 
+					outconvertclass &outconvert, ostream &textout, 
+					ostream &logout)
+{
+  // A valid collection server is vital
+  recptproto *collectproto = protos->getrecptproto (args["c"], logout);
+  if (collectproto == NULL)
+  {
+    logout << "dynamicclassifieraction::do_action called with NULL collectproto\n";
+    return false;
+  }
+
+  textout << outconvert << disp << "_dynamicclassifier:header_\n";
+  textout << outconvert << disp << "_dynamicclassifier:content_\n";
+
+  // Check a dynamic classifier ID has been specified
+  text_t arg_dcl = args["dcl"];
+  if (arg_dcl.empty())
+  {
+    textout << outconvert << disp << "Error: Missing dcl argument.\n";
+    textout << outconvert << disp << "_dynamicclassifier:footer_\n";
+    return true;
+  }
+
+  // Check the dynamic classifier ID is valid (ie. there is an entry in the collect.cfg file for it)
+  ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr (collectproto, args["c"], logout);
+  if (cinfo->dynamic_classifiers.find(arg_dcl) == cinfo->dynamic_classifiers.end())
+  {
+    textout << outconvert << disp << "Error: Invalid dcl value \"" << arg_dcl << "\".\n";
+    textout << outconvert << disp << "_dynamicclassifier:footer_\n";
+    return true;
+  }
+
+  // Parse the classifier options from the specification
+  text_t classifier_specification = cinfo->dynamic_classifiers[arg_dcl];
+  text_tmap classifier_options = parse_classifier_options (classifier_specification, args);
+
+  // Output the "<ID>Header" format statement if there is one
+  text_t classifier_header_format_statement = "";
+  get_formatstring (arg_dcl + "Header", cinfo->format, classifier_header_format_statement);
+  textout << outconvert << disp << classifier_header_format_statement << "\n";
+
+  // Resolve any ".pr" bits at the end of the "dcn" argument
+  text_t classifier_node_separator = classifier_options["-split_using_hierarchy_separator"];
+  if (ends_with (args["dcn"], ".pr"))
+  {
+    // Change the "dcn" argument to be the OID of the parent of the specified classifier node
+    text_tlist args_dcn_parts;
+    splitword (args["dcn"].begin(), args["dcn"].end(), classifier_node_separator, args_dcn_parts);
+    args_dcn_parts.pop_back();  // Remove the last part
+    joinchar (args_dcn_parts, classifier_node_separator, args["dcn"]);
+  }
+
+  // Prepare to output the dynamic classifier
+  text_t current_classifier_node_OID = "";
+  text_t current_metadata_value_filter = "";
+  int classifier_node_indent = 0;
+
+  // (Optional) Output an hlist to group the classifier nodes into buckets based on the first character
+  if (classifier_options["-group_by_first_character"] == "1")
+  {
+    text_t selected_grouping_node_OID = output_hlist_classifier_nodes (current_classifier_node_OID, current_metadata_value_filter, "substr(value,1,1)", classifier_options, args, collectproto, browsers, disp, outconvert, textout, logout);
+
+    current_classifier_node_OID = selected_grouping_node_OID + ".";
+    current_metadata_value_filter = selected_grouping_node_OID + "*";
+  }
+
+  // (Optional) Output an hlist instead of a vlist at the top level
+  if (classifier_options["-use_hlist_at_top"] == "1")
+  {
+    text_t selected_hlist_node_OID = output_hlist_classifier_nodes (current_classifier_node_OID, current_metadata_value_filter, "", classifier_options, args, collectproto, browsers, disp, outconvert, textout, logout);
+
+    current_classifier_node_OID = selected_hlist_node_OID + classifier_node_separator;
+  }
+
+  // args["dcn"] may have been modified by output_hlist_classifier_nodes() above
+  text_t classifier_node_OID = args["dcn"];
+
+  // If grouping is enabled remove the grouping node bit from the start of the OID
+  text_t classifier_node_OID_sans_grouping = classifier_node_OID;
+  if (classifier_options["-group_by_first_character"] == "1")
+  {
+    text_t::iterator grouping_node_separator = findchar (classifier_node_OID.begin(), classifier_node_OID.end(), '.');
+    if (grouping_node_separator != classifier_node_OID.end())
+    {
+      classifier_node_OID_sans_grouping = substr (grouping_node_separator + 1, classifier_node_OID.end());
+    }
+    else
+    {
+      classifier_node_OID_sans_grouping = "";
+    }
+  }
+
+  // Split the classifier node OID into its hierarchical parts, then remove any we've already dealt with (HLists)
+  text_tlist classifier_node_OID_parts_remaining;
+  splitword (classifier_node_OID_sans_grouping.begin(), classifier_node_OID_sans_grouping.end(), classifier_node_separator, classifier_node_OID_parts_remaining);
+  if (classifier_options["-use_hlist_at_top"] == "1")
+  {
+    classifier_node_OID_parts_remaining.pop_front();
+  }
+
+  text_t classifier_node_metadata_value = classifier_node_OID_sans_grouping;
+  text_t classifier_node_metadata_value_filter = classifier_node_metadata_value + classifier_node_separator + "*";
+
+  // If "-split_greenstone_dates" is on the metadata value and filter doesn't quite match the OID -- fix this
+  if (classifier_options["-split_greenstone_dates"] == "1")
+  {
+    classifier_node_metadata_value.replace (classifier_node_separator, "");
+    classifier_node_metadata_value_filter = classifier_node_metadata_value;
+    if (classifier_node_metadata_value_filter.size() == 8)
+    {
+      classifier_node_metadata_value_filter += classifier_node_separator;
+    }
+    classifier_node_metadata_value_filter += "*";
+  }
+
+  // Simple case at the top level: just output the child classifier nodes
+  if (classifier_node_metadata_value == "")
+  {
+    output_child_classifier_nodes (current_classifier_node_OID, "", current_metadata_value_filter, classifier_node_indent, classifier_options, args, collectproto, browsers, disp, outconvert, textout, logout);
+  }
+
+  // More complex case below the top level
+  else
+  {
+    // Output the parent classifier nodes and the current classifier node
+    output_upper_classifier_nodes (current_classifier_node_OID, classifier_node_OID_parts_remaining, classifier_node_indent, classifier_options, args, collectproto, browsers, disp, outconvert, textout, logout);
+
+    // Output the child classifier nodes
+    current_classifier_node_OID = classifier_node_OID + classifier_node_separator;
+    output_child_classifier_nodes (current_classifier_node_OID, classifier_node_metadata_value, classifier_node_metadata_value_filter, classifier_node_indent, classifier_options, args, collectproto, browsers, disp, outconvert, textout, logout);
+
+    // Get the document nodes at this level
+    text_t metadata_elements = classifier_options["metadata_elements"];
+    text_t sort_documents_by = classifier_options["-sort_documents_by"];
+    FilterResponse_t documents_response;
+    get_documents_with_metadata_value (metadata_elements, classifier_node_metadata_value, sort_documents_by, args["c"], collectproto, documents_response, logout);
+
+    // Display the document nodes
+    display_document_nodes (documents_response, classifier_node_indent, args, collectproto, browsers, disp, outconvert, textout, logout);
+  }
+
+  // Output the "<ID>Footer" format statement if there is one
+  text_t classifier_footer_format_statement = "";
+  get_formatstring (arg_dcl + "Footer", cinfo->format, classifier_footer_format_statement);
+  textout << outconvert << disp << classifier_footer_format_statement << "\n";
+
+  textout << outconvert << disp << "_dynamicclassifier:footer_\n";
+  return true;
+}
+
+
+text_tmap dynamicclassifieraction::parse_classifier_options (text_t classifier_specification, cgiargsclass &args)
+{
+  text_tmap classifier_options;
+
+  // Default values
+  classifier_options["-split_using_hierarchy_separator"] = "|";
+
+  // Split the classifier specification string by spaces
+  text_tlist classifier_specification_parts;
+  splitchar (classifier_specification.begin(), classifier_specification.end(), ' ', classifier_specification_parts);
+
+  // The metadata element(s) to classify by should be the first value
+  classifier_options["metadata_elements"] = classifier_specification_parts.front();
+  classifier_specification_parts.pop_front();
+
+  // Parse options from the remainder of the classifier specification
+  while (!classifier_specification_parts.empty())
+  {
+    // Parse the option name
+    text_t classifier_option_name = classifier_specification_parts.front();
+    classifier_specification_parts.pop_front();
+
+    // Check if the option has a value (it may just be a flag, in which case we use "1" as the value)
+    text_t classifier_option_value = "1";
+    if (!classifier_specification_parts.empty() && !starts_with(classifier_specification_parts.front(), "-"))
+    {
+      classifier_option_value = classifier_specification_parts.front();
+      classifier_specification_parts.pop_front();
+    }
+
+    // Record the option
+    classifier_options[classifier_option_name] = classifier_option_value;
+  }
+
+  return classifier_options;
+}
+
+
+text_t dynamicclassifieraction::output_hlist_classifier_nodes (text_t parent_classifier_node_OID,
+							       text_t metadata_value_filter,
+							       text_t metadata_value_grouping_expression,
+							       text_tmap classifier_options, cgiargsclass &args,
+							       recptproto *collectproto, browsermapclass *browsers,
+							       displayclass &disp, outconvertclass &outconvert,
+							       ostream &textout, ostream &logout)
+{
+  // Get all the metadata values for the specified element(s) that match the filter
+  text_t metadata_elements = classifier_options["metadata_elements"];
+  FilterResponse_t metadata_values_response;
+  bool request_success = get_metadata_values (metadata_elements, metadata_value_filter, metadata_value_grouping_expression, args["c"], collectproto, metadata_values_response, logout);
+
+  // If the request failed then it's probably because the collection isn't using an SQL infodbtype
+  if (request_success == false)
+  {
+    textout << outconvert << disp << "Error: Dynamic classifier functionality is not available. Please check you are using an SQL infodbtype and the collection has been rebuilt.\n";
+    return "";
+  }
+
+  // Check some metadata values were returned
+  if (metadata_values_response.docInfo.empty())
+  {
+    return "";
+  }
+
+  // After processing any hierarchical metadata values we're left with the hlist classifer nodes
+  map<text_t, int, lttext_t> hlist_classifier_nodes;
+  ResultDocInfo_tarray::iterator metadata_value_iterator = metadata_values_response.docInfo.begin();
+  while (metadata_value_iterator != metadata_values_response.docInfo.end())
+  {
+    text_t hierarchical_metadata_value = split_metadata_value ((*metadata_value_iterator).OID, classifier_options);
+
+    // Assume for now we're always at the top
+    text_t hlist_metadata_value = hierarchical_metadata_value;
+
+    // Determine the label for the hlist classifier node from the metadata value
+    text_tlist hlist_metadata_value_parts;
+    text_t hlist_node_separator = classifier_options["-split_using_hierarchy_separator"];
+    splitword (hlist_metadata_value.begin(), hlist_metadata_value.end(), hlist_node_separator, hlist_metadata_value_parts);
+    text_t hlist_classifier_node_label = hlist_metadata_value_parts.front();
+
+    // Create a node for this value if we haven't seen it before
+    if (hlist_classifier_nodes.find(hlist_classifier_node_label) == hlist_classifier_nodes.end())
+    {
+      hlist_classifier_nodes[hlist_classifier_node_label] = 0;
+    }
+
+    // Increment the occurrence count
+    hlist_classifier_nodes[hlist_classifier_node_label] += (*metadata_value_iterator).result_num;
+
+    metadata_value_iterator++;
+  }
+
+  // Add the necessary metadata to the hlist classifier nodes
+  text_t selected_hlist_node_OID = "";
+  FilterResponse_t hlist_classifier_nodes_response;
+  map<text_t, int, lttext_t>::iterator hlist_classifier_nodes_iterator = hlist_classifier_nodes.begin();
+  while (hlist_classifier_nodes_iterator != hlist_classifier_nodes.end())
+  {
+    text_t hlist_classifier_node_OID = parent_classifier_node_OID + (*hlist_classifier_nodes_iterator).first;
+
+    // Is this the hlist node that is currently selected?
+    if (starts_with (args["dcn"], hlist_classifier_node_OID))
+    {
+      selected_hlist_node_OID = hlist_classifier_node_OID;
+    }
+
+    // Add the necessary metadata required to display the hlist nodes correctly
+    ResultDocInfo_t hlist_classifier_node;
+    hlist_classifier_node.OID = hlist_classifier_node_OID;
+    hlist_classifier_node.metadata["doctype"].values.push_back ("classify");
+    hlist_classifier_node.metadata["haschildren"].values.push_back ("1");
+    hlist_classifier_node.metadata["numleafdocs"].values.push_back ("?");  // We can't determine this without more database requests
+    hlist_classifier_node.metadata["Title"].values.push_back ((*hlist_classifier_nodes_iterator).first);
+    hlist_classifier_nodes_response.docInfo.push_back (hlist_classifier_node);
+
+    hlist_classifier_nodes_iterator++;
+  }
+
+  // Automatically select the first hlist node if necessary
+  if (selected_hlist_node_OID == "")
+  {
+    selected_hlist_node_OID = (*hlist_classifier_nodes_response.docInfo.begin()).OID;
+
+    // Don't really like messing with this here, but it needs to be done before display_classifier_nodes() below
+    if (starts_with (parent_classifier_node_OID, args["dcn"]))
+    {
+      args["dcn"] = selected_hlist_node_OID;
+    }
+  }
+
+  // Display the hlist nodes
+  display_classifier_nodes (hlist_classifier_nodes_response, "HList", 0, args, collectproto, browsers, disp, outconvert, textout, logout);
+
+  return selected_hlist_node_OID;
+}
+
+
+void dynamicclassifieraction::output_upper_classifier_nodes (text_t root_classifier_node_OID,
+							     text_tlist upper_classifier_node_labels,
+							     int& classifier_node_indent,
+							     text_tmap classifier_options, cgiargsclass &args,
+							     recptproto *collectproto, browsermapclass *browsers,
+							     displayclass &disp, outconvertclass &outconvert,
+							     ostream &textout, ostream &logout)
+{
+  // Display the upper classifier nodes
+  text_t upper_classifier_node_OID = root_classifier_node_OID;
+  text_tlist::iterator upper_classifier_node_labels_iterator = upper_classifier_node_labels.begin();
+  while (upper_classifier_node_labels_iterator != upper_classifier_node_labels.end())
+  {
+    upper_classifier_node_OID += *upper_classifier_node_labels_iterator;
+
+    ResultDocInfo_t upper_classifier_node;
+    upper_classifier_node.OID = upper_classifier_node_OID;
+    upper_classifier_node.metadata["doctype"].values.push_back ("classify");
+    upper_classifier_node.metadata["haschildren"].values.push_back ("1");
+    upper_classifier_node.metadata["numleafdocs"].values.push_back ("?");  // We can't determine this without more database requests
+    upper_classifier_node.metadata["Title"].values.push_back (*upper_classifier_node_labels_iterator);
+
+    FilterResponse_t upper_classifier_node_response;
+    upper_classifier_node_response.docInfo.push_back(upper_classifier_node);
+    display_classifier_nodes (upper_classifier_node_response, "VList", classifier_node_indent, args, collectproto, browsers, disp, outconvert, textout, logout);
+    classifier_node_indent++;
+
+    upper_classifier_node_OID += classifier_options["-split_using_hierarchy_separator"];
+    upper_classifier_node_labels_iterator++;
+  }
+}
+
+
+void dynamicclassifieraction::output_child_classifier_nodes (text_t classifier_node_OID,
+							     text_t classifier_node_metadata_value,
+							     text_t metadata_value_filter,
+							     int& classifier_node_indent,
+							     text_tmap classifier_options, cgiargsclass &args,
+							     recptproto *collectproto, browsermapclass *browsers,
+							     displayclass &disp, outconvertclass &outconvert,
+							     ostream &textout, ostream &logout)
+{
+  // Get all the metadata values for the specified element(s) that match the filter
+  text_t metadata_elements = classifier_options["metadata_elements"];
+  FilterResponse_t metadata_values_response;
+  bool request_success = get_metadata_values (metadata_elements, metadata_value_filter, "", args["c"], collectproto, metadata_values_response, logout);
+
+  // If the request failed then it's probably because the collection isn't using an SQL infodbtype
+  if (request_success == false)
+  {
+    textout << outconvert << disp << "Error: Dynamic classifier functionality is not available. Please check you are using an SQL infodbtype and the collection has been rebuilt.\n";
+    return;
+  }
+
+  // After processing any hierarchical metadata values we're left with the child classifer nodes
+  map<text_t, int, lttext_t> child_classifier_nodes;
+  ResultDocInfo_tarray::iterator metadata_value_iterator = metadata_values_response.docInfo.begin();
+  while (metadata_value_iterator != metadata_values_response.docInfo.end())
+  {
+    text_t hierarchical_metadata_value = split_metadata_value ((*metadata_value_iterator).OID, classifier_options);
+    text_t classifier_node_hierarchical_metadata_value = split_metadata_value (classifier_node_metadata_value, classifier_options);
+
+    // We need to remove the current position from the metadata value to leave the child metadata value
+    text_t child_metadata_value = hierarchical_metadata_value;
+    text_t child_node_separator = classifier_options["-split_using_hierarchy_separator"];
+    if (starts_with(hierarchical_metadata_value, classifier_node_hierarchical_metadata_value + child_node_separator))
+    {
+      child_metadata_value = substr(hierarchical_metadata_value.begin() + (classifier_node_hierarchical_metadata_value + child_node_separator).size(), hierarchical_metadata_value.end());
+    }
+
+    // Determine the label for the child classifier node from the metadata value
+    text_tlist child_metadata_value_parts;
+    splitword (child_metadata_value.begin(), child_metadata_value.end(), child_node_separator, child_metadata_value_parts);
+    text_t child_classifier_node_label = child_metadata_value_parts.front();
+
+    // Create a node for this value if we haven't seen it before
+    if (child_classifier_nodes.find(child_classifier_node_label) == child_classifier_nodes.end())
+    {
+      child_classifier_nodes[child_classifier_node_label] = 0;
+    }
+
+    // Increment the occurrence count
+    child_classifier_nodes[child_classifier_node_label] += (*metadata_value_iterator).result_num;
+
+    metadata_value_iterator++;
+  }
+
+  // Add the necessary metadata to the child classifier nodes
+  FilterResponse_t child_classifier_nodes_response;
+  map<text_t, int, lttext_t>::iterator child_classifier_nodes_iterator = child_classifier_nodes.begin();
+  while (child_classifier_nodes_iterator != child_classifier_nodes.end())
+  {
+    text_t child_classifier_node_OID = classifier_node_OID + (*child_classifier_nodes_iterator).first;
+
+    ResultDocInfo_t child_classifier_node;
+    child_classifier_node.OID = child_classifier_node_OID;
+    child_classifier_node.metadata["doctype"].values.push_back ("classify");
+    child_classifier_node.metadata["haschildren"].values.push_back ("1");
+    child_classifier_node.metadata["numleafdocs"].values.push_back ((*child_classifier_nodes_iterator).second);
+    child_classifier_node.metadata["Title"].values.push_back ((*child_classifier_nodes_iterator).first);
+    child_classifier_nodes_response.docInfo.push_back (child_classifier_node);
+
+    child_classifier_nodes_iterator++;
+  }
+
+  // Display the child classifier nodes
+  display_classifier_nodes (child_classifier_nodes_response, "VList", classifier_node_indent, args, collectproto, browsers, disp, outconvert, textout, logout);
+}
+
+
+text_t dynamicclassifieraction::split_metadata_value (text_t metadata_value, text_tmap classifier_options)
+{
+  text_t hierarchical_metadata_value = metadata_value;
+  text_t hierarchy_separator = classifier_options["-split_using_hierarchy_separator"];
+
+  // Add hierarchy separators into Greenstone date values (e.g. YYYYMMDD -> YYYY|MM|DD)
+  if (classifier_options["-split_greenstone_dates"] == "1")
+  {
+    if (metadata_value.size() == 4 || metadata_value.size() == 6 || metadata_value.size() == 8)
+    {
+      // Add year
+      hierarchical_metadata_value = substr (metadata_value.begin(), metadata_value.begin() + 4);
+      if (metadata_value.size() == 6 || metadata_value.size() == 8)
+      {
+	// Add month
+	hierarchical_metadata_value += hierarchy_separator;
+	hierarchical_metadata_value += substr (metadata_value.begin() + 4, metadata_value.begin() + 6);
+	if (metadata_value.size() == 8)
+	{
+	  // Add day
+	  hierarchical_metadata_value += hierarchy_separator;
+	  hierarchical_metadata_value += substr (metadata_value.begin() + 6, metadata_value.begin() + 8);
+	}
+      }
+    }
+  }
+
+  return hierarchical_metadata_value;
+}
+
+
+void dynamicclassifieraction::display_classifier_nodes (FilterResponse_t classifier_nodes_response,
+						        text_t classifier_nodes_type,
+							int classifier_nodes_indent,
+							cgiargsclass &args, recptproto *collectproto,
+							browsermapclass *browsers, displayclass &disp,
+							outconvertclass &outconvert, ostream &textout,
+							ostream &logout)
+{
+  // Check there are some classifier nodes to display
+  if (classifier_nodes_response.docInfo.empty()) return;
+
+  // Get the format statement for this classifier if there is one, or use the browser's default otherwise
+  text_t formatstring;
+  browserclass *bptr = browsers->getbrowser (classifier_nodes_type);
+  ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr (collectproto, args["c"], logout);
+  if (!get_formatstring (args["dcl"], classifier_nodes_type, cinfo->format, formatstring))
+  {
+    formatstring = bptr->get_default_formatstring();
+  }
+  format_t *formatlistptr = new format_t();
+  text_tset metadata;
+  bool getParents = false;
+  parse_formatstring (formatstring, formatlistptr, metadata, getParents);
+  bool use_table = is_table_content (formatlistptr);
+
+  // Display the classifier nodes
+  bptr->output_section_group (classifier_nodes_response, args, args["c"], classifier_nodes_indent, formatlistptr, use_table, metadata, getParents, collectproto, disp, outconvert, textout, logout);
+}
+
+
+void dynamicclassifieraction::display_document_nodes (FilterResponse_t documents_response,
+						      int document_nodes_indent,
+						      cgiargsclass &args, recptproto *collectproto,
+						      browsermapclass *browsers, displayclass &disp,
+						      outconvertclass &outconvert, ostream &textout,
+						      ostream &logout)
+{
+  // Check there are some documents to display
+  if (documents_response.docInfo.empty()) return;
+
+  // Get the format statement for the document nodes if there is one, or use the browser's default otherwise
+  text_t formatstring;
+  browserclass *bptr = browsers->getbrowser ("VList");
+  ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr (collectproto, args["c"], logout);
+  if (!get_formatstring (args["dcl"], "DocumentNodes", cinfo->format, formatstring))
+  {
+    if (!get_formatstring (args["dcl"], "VList", cinfo->format, formatstring))
+    {
+      formatstring = bptr->get_default_formatstring();
+    }
+  }
+  format_t *formatlistptr = new format_t();
+  text_tset metadata;
+  bool getParents = false;
+  parse_formatstring (formatstring, formatlistptr, metadata, getParents);
+  bool use_table = is_table_content (formatlistptr);
+
+  // Request the necessary metadata for displaying the documents
+  text_tarray document_OIDs;
+  ResultDocInfo_tarray::iterator document_iterator = documents_response.docInfo.begin();
+  while (document_iterator != documents_response.docInfo.end())
+  {
+    document_OIDs.push_back ((*document_iterator).OID);
+    document_iterator++;
+  }
+  FilterResponse_t document_nodes_response;
+  get_info (document_OIDs, args["c"], args["l"], metadata, getParents, collectproto, document_nodes_response, logout);
+
+  // Display the document nodes
+  bptr->output_section_group (document_nodes_response, args, args["c"], document_nodes_indent, formatlistptr, use_table, metadata, getParents, collectproto, disp, outconvert, textout, logout);
+}
Index: /gsdl/stable/runtime-src/src/recpt/dynamicclassifieraction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/dynamicclassifieraction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/dynamicclassifieraction.h	(revision 20131)
@@ -0,0 +1,111 @@
+/**********************************************************************
+ *
+ * dynamicclassifieraction.h -- 
+ * Copyright (C) 2008  DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef DYNAMICCLASSIFIERACTION_H
+#define DYNAMICCLASSIFIERACTION_H
+
+
+#include "action.h"
+#include "receptionist.h"
+
+
+class dynamicclassifieraction : public action
+{
+protected:
+  receptionist *recpt;
+
+public:
+  dynamicclassifieraction ();
+  virtual ~dynamicclassifieraction ();
+
+  void set_receptionist (receptionist *recpt_arg) { recpt = recpt_arg; }
+
+  text_t get_action_name () { return "dc"; }
+
+  bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+		      recptprotolistclass *protos, ostream &logout);
+
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response,text_t &response_data, 
+			 ostream &logout);
+
+  void define_external_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+
+  virtual void define_internal_macros (displayclass &disp, cgiargsclass &args, 
+				       recptprotolistclass *protos, ostream &logout);
+
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+
+  text_tmap parse_classifier_options (text_t classifier_specification, cgiargsclass &args);
+
+  text_t output_hlist_classifier_nodes (text_t parent_classifier_node_OID,
+					text_t metadata_value_filter,
+					text_t metadata_value_grouping_expression,
+					text_tmap classifier_options, cgiargsclass &args,
+					recptproto *collectproto, browsermapclass *browsers,
+					displayclass &disp, outconvertclass &outconvert,
+					ostream &textout, ostream &logout);
+
+  void output_upper_classifier_nodes (text_t root_classifier_node_OID,
+				      text_tlist parent_classifier_node_labels,
+				      int& classifier_node_indent,
+				      text_tmap classifier_options, cgiargsclass &args,
+				      recptproto *collectproto, browsermapclass *browsers,
+				      displayclass &disp, outconvertclass &outconvert,
+				      ostream &textout, ostream &logout);
+
+  void output_child_classifier_nodes (text_t classifier_node_OID,
+				      text_t classifier_node_metadata_value,
+				      text_t metadata_value_filter,
+				      int& classifier_node_indent,
+				      text_tmap classifier_options, cgiargsclass &args,
+				      recptproto *collectproto, browsermapclass *browsers,
+				      displayclass &disp, outconvertclass &outconvert,
+				      ostream &textout, ostream &logout);
+
+  text_t split_metadata_value (text_t metadata_value, text_tmap classifier_options);
+
+  void display_classifier_nodes (FilterResponse_t classifier_nodes_response,
+				 text_t classifier_nodes_type,
+				 int classifier_nodes_indent,
+				 cgiargsclass &args, recptproto *collectproto,
+				 browsermapclass *browsers, displayclass &disp,
+				 outconvertclass &outconvert, ostream &textout,
+				 ostream &logout);
+
+  void display_document_nodes (FilterResponse_t documents_response,
+			       int document_nodes_indent,
+			       cgiargsclass &args, recptproto *collectproto,
+			       browsermapclass *browsers, displayclass &disp,
+			       outconvertclass &outconvert, ostream &textout,
+			       ostream &logout);
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/extlinkaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/extlinkaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/extlinkaction.cpp	(revision 20131)
@@ -0,0 +1,253 @@
+/**********************************************************************
+ *
+ * extlinkaction.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_EXTLINK_ACTION
+
+#include <string.h>
+#include "extlinkaction.h"
+#include "recptprototools.h"
+#include "cgiutils.h"
+
+extlinkaction::extlinkaction () {
+
+  // this action uses cgi variables "a", "d", and "href"
+
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "a";
+  arg_ainfo.longname = "action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "extlink";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "el";
+  arg_ainfo.longname = "external link preference";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "direct"; // changed from "prompt" - will now directly load external links instead of
+                                   // going through an intermediate page indicating that the link is external
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "d";
+  arg_ainfo.longname = "document OID";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::none;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::can;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "href";
+  arg_ainfo.longname = "URL of external link";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::none;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::can;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "rl";
+  arg_ainfo.longname = "is relative link";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::none;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+}
+
+extlinkaction::~extlinkaction () {
+}
+
+
+void extlinkaction::get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+				      response_t &response, text_t &response_data, 
+				      ostream &logout) {
+
+  text_t link;
+  if (get_link (args, protos, link, logout)) {
+    response = location;
+    response_data = link;
+    return;
+  }
+
+  // external link
+  if (!link.empty()) {
+    if (args["el"] == "direct") {
+      response = location;
+      response_data = link;
+      return;
+    }
+  }
+
+  response = content;
+  response_data = "text/html";
+}
+
+void extlinkaction::define_internal_macros (displayclass &disp, cgiargsclass &args, 
+					    recptprotolistclass * /*protos*/, 
+					    ostream &/*logout*/) {
+  
+  // define_internal_macros sets the following macros:
+
+  // _nexturl_             link to external page
+  // _prevdoc_             link to previous document
+  //  disp.setmacro("nexturl", "extlink", cgi_safe(args["href"]));
+  // problem in whist, above line changed.  Perhaps decode_cgi_arg ??
+  // see also HTML plugin
+  disp.setmacro("nexturl", "extlink", args["href"]);
+  disp.setmacro("prevdoc", "extlink", args["d"]);
+}
+
+
+// if link is found returns true and url in link, otherwise returns
+// false
+bool extlinkaction::get_link (cgiargsclass &args, recptprotolistclass *protos,
+			      text_t &link, ostream &logout) {
+
+    text_t &arg_href = args["href"];
+    text_t &thiscollection = args["c"];
+    if (arg_href.empty()) return false;
+
+    text_t httpdoc = "_gwcgi_?e=_compressedoptions_&a=d";
+    if (args["rl"] == "1") {
+
+      FilterResponse_t response;
+      text_tset metadata;
+      metadata.insert ("section");
+	  
+      recptproto *collectproto = protos->getrecptproto (thiscollection, logout);
+
+      if (get_info (arg_href, thiscollection, args["l"], metadata, false, collectproto, response, logout)) {
+	if (!response.docInfo[0].metadata["section"].values[0].empty()) {
+	  link = httpdoc+"&d=" + response.docInfo[0].metadata["section"].values[0];
+	  return true;
+	}
+      }
+
+      // need to see if link exists in any other collection
+      // if cross-collection searching/browsing is turned on 
+      if (args["ccs"] == "1" && !args["cc"].empty()) {
+	text_tarray collections;
+	splitchar (args["cc"].begin(), args["cc"].end(), ',', collections);
+
+	text_tarray::const_iterator col_here = collections.begin();
+	text_tarray::const_iterator col_end = collections.end();
+
+	while (col_here != col_end) {
+	  
+	  // don't need to check current collection again
+	  if (*col_here == thiscollection) {++col_here; continue;}
+	  
+	  recptproto *collectproto = protos->getrecptproto (*col_here, logout);
+	  if (collectproto == NULL) {++col_here; continue;}
+
+	  if (get_info (arg_href, *col_here, args["l"], metadata, false, collectproto, response, logout)) {
+	    if (!response.docInfo[0].metadata["section"].values[0].empty()) {
+	      link = httpdoc+"&c=" + *col_here + "&d=" +
+		response.docInfo[0].metadata["section"].values[0];
+	      return true;
+	    }
+	  }
+	  ++col_here;
+	}
+      }
+      return false;
+      
+    } else {
+      // link is external 
+      link = arg_href;
+      return false;
+    }
+}
+
+
+bool extlinkaction::do_action (cgiargsclass &args, recptprotolistclass *protos, 
+			       browsermapclass * /*browsers*/, displayclass &disp,
+			       outconvertclass &outconvert, ostream &textout,
+			       ostream &logout) {
+ 
+  if (args["href"].empty()) {
+     // oops, this shouldn't happen
+    textout << outconvert << disp << ("_extlink:header_\n")
+	    << ("_extlink:notfoundcontent_\n")
+	    << ("_extlink:footer_\n");
+    return true;
+  }
+
+  if (args["rl"] == "1") {
+    // need to see if link exists in any other collection
+    // if cross-collection searching/browsing is turned on 
+    if (args["ccs"] == "1" && !args["cc"].empty()) {
+      
+      FilterResponse_t response;
+      text_tset metadata;
+      metadata.insert ("section");
+      text_tarray collections;
+      splitchar (args["cc"].begin(), args["cc"].end(), ',', collections);
+      
+      text_tarray::const_iterator col_here = collections.begin();
+      text_tarray::const_iterator col_end = collections.end();
+      
+      while (col_here != col_end) {
+	
+	// don't need to check current collection
+	if (*col_here == args["c"]) {++col_here; continue;}
+	
+	recptproto *collectproto = protos->getrecptproto (*col_here, logout);
+	if (get_info (args["href"], *col_here, args["l"], metadata, false, collectproto, response, logout)) {
+	  if (!response.docInfo[0].metadata["section"].values[0].empty()) {
+	    ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr (collectproto, *col_here, logout);
+	    text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]); //
+	    if (collectionname.empty()) {
+	      collectionname = *col_here;
+	    }
+	    textout << outconvert << disp << ("_extlink:header_\n")
+		    << ("_extlink:foundintcontent_(" + *col_here + ", " + collectionname + 
+			", " + response.docInfo[0].metadata["section"].values[0] + "\n")
+		    << ("_extlink:footer_\n");
+	    return true;
+	  }
+	}
+	++col_here;
+      }
+    }
+    textout << outconvert << disp << ("_extlink:header_\n")
+	    << ("_extlink:notfoundcontent_\n")
+	    << ("_extlink:footer_\n");
+    
+    
+  } else {
+    // link is external 
+    textout << outconvert << disp << ("_extlink:header_\n")
+	    << ("_extlink:foundcontent_\n")
+	    << ("_extlink:footer_\n");
+  }
+
+  return true;
+}
+
+#endif //GSDL_USE_EXTLINK_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/extlinkaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/extlinkaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/extlinkaction.h	(revision 20131)
@@ -0,0 +1,69 @@
+/**********************************************************************
+ *
+ * extlinkaction.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_EXTLINK_ACTION
+
+#ifndef EXTLINKACTION_H
+#define EXTLINKACTION_H
+
+#include "action.h"
+#include "receptionist.h"
+
+class extlinkaction : public action {
+
+
+public:
+  extlinkaction ();
+  virtual ~extlinkaction ();
+
+  void set_receptionist (receptionist *therecpt) {recpt=therecpt;}
+
+  text_t get_action_name () {return "extlink";}
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response, text_t &response_data, 
+			 ostream &logout);
+
+  void define_internal_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, 
+			       ostream &logout);
+
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp,
+		  outconvertclass &outconvert, ostream &textout,
+		  ostream &logout);
+
+
+protected:
+  
+  receptionist *recpt;
+  
+  bool get_link (cgiargsclass &args, recptprotolistclass *protos,
+		 text_t &link, ostream &logout);
+
+};
+
+#endif //!EXTLINKACTION_H
+#endif //GSDL_USE_EXTLINK_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/formattools.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/formattools.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/formattools.cpp	(revision 20131)
@@ -0,0 +1,1776 @@
+/**********************************************************************
+ *
+ * formattools.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "formattools.h"
+#include "cgiutils.h"
+#include "recptprototools.h"
+#include "OIDtools.h"
+#include "summarise.h"
+
+#include <assert.h>
+
+static bool metadata_spanwrap = false;
+
+// a few function prototypes
+
+static text_t format_string (const text_t& collection, recptproto* collectproto,
+			     ResultDocInfo_t &docinfo, displayclass &disp, 
+			     format_t *formatlistptr, text_tmap &options,
+			     ostream& logout);
+
+static bool parse_action (text_t::const_iterator &here, const text_t::const_iterator &end, 
+			  format_t *formatlistptr, text_tset &metadata, bool &getParents);
+
+static text_t format_summary (const text_t& collection, recptproto* collectproto,
+			      ResultDocInfo_t &docinfo, displayclass &disp, 
+			      text_tmap &options, ostream& logout);
+static text_t format_text (const text_t& collection, recptproto* collectproto,
+			      ResultDocInfo_t &docinfo, displayclass &disp, 
+			      text_tmap &options, ostream& logout);
+
+static text_t expand_metadata(const text_t &metavalue, const text_t& collection,
+			      recptproto* collectproto, ResultDocInfo_t &docinfo,
+			      displayclass &disp, text_tmap &options,
+			      ostream &logout);
+
+
+void metadata_t::clear() {
+  metaname.clear();
+  metacommand = mNone;
+  mqualifier.parent  = pNone;
+  mqualifier.sibling = sNone;
+  mqualifier.child   = cNone;
+  pre_tree_traverse.clear();
+  parentoptions.clear();
+  siblingoptions.clear();
+  childoptions.clear();
+}
+
+void decision_t::clear() {
+  command = dMeta;
+  meta.clear();
+  text.clear();
+}
+
+void format_t::clear() {
+  command = comText;
+  decision.clear();
+  text.clear();
+  meta.clear();
+  nextptr = NULL;
+  ifptr = NULL;
+  elseptr = NULL;
+  orptr = NULL;
+}
+
+void formatinfo_t::clear() {
+  DocumentImages = false;
+  DocumentTitles = true;
+  DocumentHeading = "{Or}{[parent(Top):Title],[Title],untitled}<br>";
+  DocumentContents = true;
+  DocumentArrowsBottom = true; 
+  DocumentArrowsTop = false; 
+  DocumentSearchResultLinks = false;
+  DocumentButtons.erase (DocumentButtons.begin(), DocumentButtons.end());
+  //  DocumentButtons.push_back ("Expand Text");
+  //  DocumentButtons.push_back ("Expand Contents");
+  DocumentButtons.push_back ("Detach");
+  DocumentButtons.push_back ("Highlight");
+  RelatedDocuments = "";
+  DocumentText = "[Text]";
+  formatstrings.erase (formatstrings.begin(), formatstrings.end());
+  DocumentUseHTML = false;
+  AllowExtendedOptions = false;
+}
+
+// simply checks to see if formatstring begins with a <td> tag
+bool is_table_content (const text_t &formatstring) {
+  text_t::const_iterator here = formatstring.begin();
+  text_t::const_iterator end = formatstring.end();
+  
+  while (here != end) {
+    if (*here != ' ') {
+      if ((*here == '<') && ((here+3) < end)) {
+	if ((*(here+1) == 't' || *(here+1) == 'T') &&
+	    (*(here+2) == 'd' || *(here+2) == 'D') &&
+	    (*(here+3) == '>' || *(here+3) == ' '))
+	  return true;
+      } else return false;
+    }
+    ++here;
+  }
+  return false;
+}
+
+bool is_table_content (const format_t *formatlistptr) {
+
+  if (formatlistptr == NULL) return false;
+  
+  if (formatlistptr->command == comText)
+    return is_table_content (formatlistptr->text);
+    
+  return false;
+}
+
+// returns false if key isn't in formatstringmap
+bool get_formatstring (const text_t &key, const text_tmap &formatstringmap,
+		       text_t &formatstring) {
+
+  formatstring.clear();
+  text_tmap::const_iterator it = formatstringmap.find(key);
+  if (it == formatstringmap.end()) return false;
+  formatstring = (*it).second;
+  return true;
+}
+
+// tries to find "key1key2" then "key1" then "key2"
+bool get_formatstring (const text_t &key1, const text_t &key2,  
+		       const text_tmap &formatstringmap,
+		       text_t &formatstring) {
+
+  formatstring.clear();
+  text_tmap::const_iterator it = formatstringmap.find(key1 + key2);
+  if (it != formatstringmap.end()) {
+    formatstring = (*it).second;
+    return true;
+  }
+  it = formatstringmap.find(key1);
+  if (it != formatstringmap.end()) {
+    formatstring = (*it).second;
+    return true;
+  }
+  it = formatstringmap.find(key2);
+  if (it != formatstringmap.end()) {
+    formatstring = (*it).second;
+    return true;
+  }
+  return false;
+}
+
+
+text_t remove_namespace(const text_t &meta_name) {
+  text_t::const_iterator end = meta_name.end();
+  text_t::const_iterator it = findchar(meta_name.begin(), end, '.');
+  if (it != end) {
+    return substr(it+1, end);
+  }
+
+  return meta_name;
+
+}
+// returns a date of form _format:date_(year, month, day)
+// input is date of type yyyy-?mm-?dd
+// at least the year must be present in date
+text_t format_date (const text_t &date) {
+
+  if (date.size() < 4) return "";
+
+  text_t::const_iterator datebegin = date.begin();
+
+  text_t year = substr (datebegin, datebegin+4);
+  int chars_seen_so_far = 4;
+
+  if (date[chars_seen_so_far] == '-') ++chars_seen_so_far ;
+  if (date.size() < chars_seen_so_far+2) return "_format:date_("+year+")";
+ 
+  text_t month = substr (datebegin+chars_seen_so_far, datebegin+chars_seen_so_far+2);
+  int imonth = month.getint();
+  if (imonth <= 0 || imonth > 12) return "_format:date_("+year+")";
+ 
+  chars_seen_so_far += 2;
+  if (date[chars_seen_so_far] == '-') ++chars_seen_so_far ;
+  
+  if (date.size() < chars_seen_so_far+2) return "_format:date_("+year+","+month+")";
+
+  text_t day = substr (datebegin+chars_seen_so_far, datebegin+chars_seen_so_far+2);
+  if (day[0] == '0') day = substr (day.begin()+1, day.end());
+  int iday = day.getint();
+  if (iday <= 0 || iday > 31) return "_format:date_("+year+","+month+")";
+    
+  return "_format:date_("+year+","+month+","+day+")";
+}  
+
+// converts an iso639 language code to its English equivalent
+// should we be checking that the macro exists??
+text_t iso639 (const text_t &langcode) {
+  if (langcode.empty()) return "";
+  return "_iso639:iso639"+langcode+"_";
+}
+
+
+text_t get_href (const text_t &link) {
+
+  text_t href;
+
+  text_t::const_iterator here = findchar(link.begin(), link.end(), '"');
+  text_t::const_iterator end = link.end();
+  if (here == end) return g_EmptyText;
+  
+  ++here;
+  while (here != end) {
+    if (*here == '"') break;
+    href.push_back(*here);
+    ++here;
+  }
+
+  return href;
+}
+
+//this function gets the information associated with the relation
+//metadata for the document associated with 'docinfo'. This relation
+//metadata consists of a line of pairs containing 'collection, document OID'
+//(this is the OID of the document related to the current document, and
+//the collection the related document belongs to). For each of these pairs
+//the title metadata is obtained and then an html link between the title
+//of the related doc and the document's position (the document will be
+//found in "<a href=\"_httpdocument_&c=collection&cl=search&d=OID">
+//(where collection is the related documents collection, and OID is the
+//related documents OID).  A list of these html links are made for as many
+//related documents as there are. This list is then returned. If there are
+//no related documents available for the current document then the string
+//'.. no related documents .. ' is returned.
+text_t get_related_docs(const text_t& collection, recptproto* collectproto,
+			ResultDocInfo_t &docinfo, ostream& logout){
+  
+  text_tset metadata;
+
+  //insert the metadata we wish to collect
+  metadata.insert("dc.Relation"); 
+  metadata.insert("Title");  
+  metadata.insert("Subject"); //for emails, where title data doesn't apply
+ 
+  FilterResponse_t response;
+  text_t relation = ""; //string for displaying relation metadata
+  text_t relationTitle = ""; //the related documents Title (or subject)
+  text_t relationOID = ""; //the related documents OID  
+
+  //get the information associated with the metadata for current doc
+  if (get_info (docinfo.OID, collection, "", metadata, 
+		false, collectproto, response, logout)) {
+    
+    //if the relation metadata exists, store for displaying
+    if(!response.docInfo[0].metadata["dc.Relation"].values.empty()){
+      relationOID += response.docInfo[0].metadata["dc.Relation"].values[0];
+
+      //split relation data into pairs of collectionname,ID number
+      text_tarray relationpairs;
+      splitchar (relationOID.begin(), relationOID.end(), ' ', relationpairs);
+      
+      text_tarray::const_iterator currDoc = relationpairs.begin();  
+      text_tarray::const_iterator lastDoc = relationpairs.end();
+
+      //iterate through the pairs to split and display
+      while(currDoc != lastDoc){
+	
+	//split pairs into collectionname and ID 
+	text_tarray relationdata;
+	splitchar ((*currDoc).begin(), (*currDoc).end(), ',', relationdata);
+	
+	//get first element in the array (collection)
+	text_tarray::const_iterator doc_data = relationdata.begin();
+	text_t document_collection = *doc_data;
+	++doc_data; //increment to get next item in array (oid)
+	text_t document_OID = *doc_data;
+	
+	//create html link to related document
+	relation += "<a href=\"_httpdocument_&c=" + document_collection;
+	relation += "&cl=search&d=" + document_OID;
+	   
+	//get the information associated with the metadata for related doc
+	if (get_info (document_OID, document_collection, "", metadata,
+		      false, collectproto, response, logout)) {
+	  
+	  //if title metadata doesn't exist, collect subject metadata
+	  //if that doesn't exist, just call it 'related document'
+	  if (!response.docInfo[0].metadata["Title"].values[0].empty())
+		relationTitle = response.docInfo[0].metadata["Title"].values[0];
+	  else if (!response.docInfo[0].metadata["Subject"].values.empty())
+	    relationTitle = response.docInfo[0].metadata["Subject"].values[0];
+	  else relationTitle =  "RELATED DOCUMENT";
+	  
+	}
+	
+	//link the related document's title to its page
+	relation += "\">" + relationTitle + "</a>"; 
+	relation += "  (" + document_collection + ")<br>";
+	
+	++currDoc;
+      }
+    }
+    
+  } 
+
+  if(relation.empty()) //no relation data for documnet
+    relation = ".. no related documents .. ";
+
+  return relation;
+}
+
+
+
+static void get_parent_options (text_t &instring, metadata_t &metaoption) {
+
+  assert (instring.size() > 7);
+  if (instring.size() <= 7) return;
+
+  text_t meta, com, op;
+  bool inbraces = false;
+  bool inquotes = false;
+  bool foundcolon = false;
+  text_t::const_iterator here = instring.begin()+6;
+  text_t::const_iterator end = instring.end();
+  while (here != end) {
+    if (foundcolon) meta.push_back (*here);
+    else if (*here == '(') inbraces = true;
+    else if (*here == ')') inbraces = false;
+    else if (*here == '\'' && !inquotes) inquotes = true;
+    else if (*here == '\'' && inquotes) inquotes = false;
+    else if (*here == ':' && !inbraces) foundcolon = true;
+    else if (inquotes) op.push_back (*here);
+    else com.push_back (*here);
+    ++here;
+  }
+
+  instring = meta;
+  if (com.empty())
+    metaoption.mqualifier.parent = pImmediate;
+  else if (com == "Top")
+    metaoption.mqualifier.parent = pTop;
+  else if (com == "All") {
+    metaoption.mqualifier.parent = pAll;
+    metaoption.parentoptions = op;
+  }
+}
+
+
+static void get_sibling_options (text_t &instring, metadata_t &metaoption) {
+
+  assert (instring.size() > 8);
+  if (instring.size() <= 8) return;
+  text_t meta, com, op;
+  bool inbraces = false;
+  bool inquotes = false;
+  bool foundcolon = false;
+  text_t::const_iterator here = instring.begin()+7;
+  text_t::const_iterator end = instring.end();
+  while (here != end) {
+    if (foundcolon) meta.push_back (*here);
+    else if (*here == '(') inbraces = true;
+    else if (*here == ')') inbraces = false;
+    else if (*here == '\'' && !inquotes) inquotes = true;
+    else if (*here == '\'' && inquotes) inquotes = false;
+    else if (*here == ':' && !inbraces) foundcolon = true;    
+    else if (inquotes) op.push_back (*here);
+    else com.push_back (*here);
+    ++here;
+  }
+
+  instring = meta;
+  metaoption.siblingoptions.clear();
+
+  if (com.empty()) {
+    metaoption.mqualifier.sibling = sAll;
+    metaoption.siblingoptions = " ";
+  }
+  else if (com == "first") {
+    metaoption.mqualifier.sibling = sNum;
+    metaoption.siblingoptions = "0";
+  }
+  else if (com == "last") {
+    metaoption.mqualifier.sibling = sNum;
+    metaoption.siblingoptions = "-2"; // == last
+  }
+  else if (com.getint()>0) {
+    metaoption.mqualifier.sibling = sNum;
+    int pos = com.getint()-1;
+    metaoption.siblingoptions +=pos;
+  }
+  else {
+    metaoption.mqualifier.sibling = sAll;
+    metaoption.siblingoptions = op;
+  }
+}
+
+static void get_child_options (text_t &instring, metadata_t &metaoption) {
+
+  assert (instring.size() > 6);
+  if (instring.size() <= 6) return;
+  text_t meta, com, op;
+  bool inbraces = false;
+  bool inquotes = false;
+  bool foundcolon = false;
+  text_t::const_iterator here = instring.begin()+5;
+  text_t::const_iterator end = instring.end();
+  while (here != end) {
+    if (foundcolon) meta.push_back (*here);
+    else if (*here == '(') inbraces = true;
+    else if (*here == ')') inbraces = false;
+    else if (*here == '\'' && !inquotes) inquotes = true;
+    else if (*here == '\'' && inquotes) inquotes = false;
+    else if (*here == ':' && !inbraces) foundcolon = true;
+    else if (inquotes) op.push_back (*here);
+    else com.push_back (*here);
+    ++here;
+  }
+
+  instring = meta;
+  if (com.empty()) {
+    metaoption.mqualifier.child = cAll;
+    metaoption.childoptions = " ";
+  }
+  else if (com == "first") {
+    metaoption.mqualifier.child = cNum;
+    metaoption.childoptions = ".fc";
+  }
+  else if (com == "last") {
+    metaoption.mqualifier.child = cNum;
+    metaoption.childoptions = ".lc";
+  }
+  else if (com.getint()>0) {
+    metaoption.mqualifier.child = cNum;
+    metaoption.childoptions = "."+com;
+  }
+  else {
+    metaoption.mqualifier.child = cAll;
+    metaoption.childoptions = op;
+  }
+}
+
+
+
+static void parse_meta (text_t &meta, metadata_t &metaoption,
+			text_tset &metadata, bool &getParents) {
+
+  if (meta.size() > 8 && (substr(meta.begin(), meta.begin()+8) == "cgisafe:")) {
+    metaoption.metacommand |= mCgiSafe;
+    meta = substr (meta.begin()+8, meta.end());
+  }
+  if (meta.size() > 7 && (substr(meta.begin(), meta.begin()+7) == "format:")) {    
+    metaoption.metacommand |= mSpecial;
+    meta = substr (meta.begin()+7, meta.end());
+  }
+
+  bool had_parent_or_child = true;
+  bool prev_was_parent = false;
+  bool prev_was_child  = false;
+
+  while (had_parent_or_child) {
+    if (meta.size() > 7 
+	&& (substr (meta.begin(), meta.begin()+6) == "parent")) {
+
+      // clear out sibling and child (cmd and options)
+      metaoption.metacommand &= ~(mChild|mSibling);
+      metaoption.childoptions.clear();
+      metaoption.siblingoptions.clear();
+
+      getParents = true;
+      metaoption.metacommand |= mParent;
+      get_parent_options (meta, metaoption);
+
+      if (prev_was_parent) {
+	metaoption.pre_tree_traverse += ".pr";
+      }
+      else if (prev_was_child) {
+	metaoption.pre_tree_traverse += ".fc";
+      }
+
+      prev_was_parent = true;
+      prev_was_child  = false;
+    } 
+    else if (meta.size() > 6 
+	     && (substr (meta.begin(), meta.begin()+5) == "child")) {
+
+      // clear out sibling and parent (cmd and options)
+      metaoption.metacommand &= ~(mParent|mSibling);
+      metaoption.parentoptions.clear();
+      metaoption.siblingoptions.clear();
+
+      metaoption.metacommand |= mChild;
+      get_child_options (meta, metaoption);
+      metadata.insert("contains");
+
+      if (prev_was_parent) {
+	metaoption.pre_tree_traverse += ".pr";
+      }
+      else if (prev_was_child) {
+	metaoption.pre_tree_traverse += ".fc";
+      }
+
+      prev_was_child  = true;
+      prev_was_parent = false;
+    } 
+    else {
+      prev_was_child  = false;
+      prev_was_parent = false;
+      had_parent_or_child = false;
+    }
+  }
+
+  // parent/child can have sibling tacked on end also
+  if (meta.size() > 8 && (substr (meta.begin(), meta.begin()+7) == "sibling")) {
+    metaoption.metacommand |= mSibling;
+    get_sibling_options (meta, metaoption);
+  } 
+  
+  // check for ex. which may occur in format statements
+  if (meta.size()>3 && (substr(meta.begin(), meta.begin()+3) == "ex.")) {
+    meta = substr (meta.begin()+3, meta.end());
+  }
+  metadata.insert (meta);
+  metaoption.metaname = meta;
+}
+
+static void parse_coll_meta(text_t &meta, metadata_t &metaoption) {
+  if (meta == "collection") {
+    // no qualifiers
+    metaoption.metaname = g_EmptyText;
+    return;
+  }
+  meta = substr (meta.begin()+11, meta.end());
+  metaoption.metaname = meta;
+  
+}
+
+static void parse_meta (text_t &meta, format_t *formatlistptr,
+			text_tset &metadata, bool &getParents) {
+  
+  if (meta == "link")
+    formatlistptr->command = comLink;
+  else if (meta == "/link")
+    formatlistptr->command = comEndLink;
+
+  else if (meta == "href")
+    formatlistptr->command = comHref;
+
+  else if (meta == "num")
+    formatlistptr->command = comNum;
+
+  else if (meta == "icon")
+    formatlistptr->command = comIcon;
+
+  else if (meta == "Text")
+    formatlistptr->command = comDoc;
+  
+  else if (meta == "RelatedDocuments")
+   formatlistptr->command = comRel;
+
+  else if (meta == "highlight")
+    formatlistptr->command = comHighlight;
+
+  else if (meta == "/highlight")
+    formatlistptr->command = comEndHighlight;
+
+  else if (meta == "metadata-spanwrap")
+    formatlistptr->command = comMetadataSpanWrap;
+
+  else if (meta == "/metadata-spanwrap")
+    formatlistptr->command = comEndMetadataSpanWrap;
+
+  else if (meta == "Summary")
+    formatlistptr->command = comSummary;
+
+  else if (meta == "DocImage")
+    formatlistptr->command = comImage; 
+
+  else if (meta == "DocTOC")
+    formatlistptr->command = comTOC; 
+
+  else if (meta == "DocumentButtonDetach")
+     formatlistptr->command = comDocumentButtonDetach;
+  
+  else if (meta == "DocumentButtonHighlight")
+     formatlistptr->command = comDocumentButtonHighlight;
+  
+  else if (meta == "DocumentButtonExpandContents")
+    formatlistptr->command = comDocumentButtonExpandContents; 
+
+  else if (meta == "DocumentButtonExpandText")
+     formatlistptr->command = comDocumentButtonExpandText; 
+
+  else if (meta == "DocOID")
+     formatlistptr->command = comOID; 
+  else if (meta == "DocTopOID")
+    formatlistptr->command = comTopOID;
+  else if (meta == "DocRank")
+    formatlistptr->command = comRank;
+  else if (meta == "DocTermsFreqTotal")
+    formatlistptr->command = comDocTermsFreqTotal;
+  else if (meta.size() >= 10 && (substr(meta.begin(), meta.begin()+10) == "collection")) {
+    formatlistptr->command = comCollection;
+    parse_coll_meta(meta, formatlistptr->meta);
+  }
+  else {
+    formatlistptr->command = comMeta;
+    parse_meta (meta, formatlistptr->meta, metadata, getParents);
+  }
+}
+
+
+static bool parse_string (const text_t &formatstring, format_t *formatlistptr, 
+			  text_tset &metadata, bool &getParents) {
+
+  text_t text;
+  text_t::const_iterator here = formatstring.begin();
+  text_t::const_iterator end = formatstring.end();
+
+  while (here != end) {
+
+    if (*here == '\\') {
+      ++here;
+      if (here != end) text.push_back (*here);
+
+    } else if (*here == '{') {
+      if (!text.empty()) {
+	formatlistptr->command = comText;
+	formatlistptr->text = text;
+	formatlistptr->nextptr = new format_t();
+	formatlistptr = formatlistptr->nextptr;
+	
+	text.clear();
+      }
+      if (parse_action (++here, end, formatlistptr, metadata, getParents)) {
+
+	formatlistptr->nextptr = new format_t();
+	formatlistptr = formatlistptr->nextptr;
+	if (here == end) break;
+      }
+    } else if (*here == '[') {
+      if (!text.empty()) {
+	formatlistptr->command = comText;
+	formatlistptr->text = text;
+	formatlistptr->nextptr = new format_t();
+	formatlistptr = formatlistptr->nextptr;
+
+	text.clear();
+      }
+      text_t meta;
+      ++here;
+      while (*here != ']') {
+	if (here == end) return false;
+	meta.push_back (*here);
+	++here;
+      }
+      parse_meta (meta, formatlistptr, metadata, getParents);
+      formatlistptr->nextptr = new format_t();
+      formatlistptr = formatlistptr->nextptr;
+
+    } else 
+      text.push_back (*here);
+
+    if (here != end) ++here;
+  }
+  if (!text.empty()) {
+    formatlistptr->command = comText;
+    formatlistptr->text = text;
+    formatlistptr->nextptr = new format_t();
+    formatlistptr = formatlistptr->nextptr;
+
+  }
+  return true;
+}
+
+
+static bool parse_action (text_t::const_iterator &here, const text_t::const_iterator &end, 
+			  format_t *formatlistptr, text_tset &metadata, bool &getParents) {
+
+  text_t::const_iterator it = findchar (here, end, '}');
+  if (it == end) return false;
+
+  text_t com = substr (here, it);
+  here = findchar (it, end, '{');
+  if (here == end) return false;
+  else ++here;
+
+  if (com == "If" || com == "if" || com == "IF") formatlistptr->command = comIf;
+  else if (com == "Or" || com == "or" || com == "OR") formatlistptr->command = comOr;
+  else return false;
+
+  int commacount = 0;
+  text_t text;
+  while (here != end) {
+
+    if (*here == '\\') {
+      ++here;
+      if (here != end) text.push_back(*here);
+      
+    } 
+  
+    else if (*here == ',' || *here == '}' || *here == '{') {
+
+      if (formatlistptr->command == comOr) {
+	// the {Or}{this, or this, or this, or this} statement
+	format_t *or_ptr;
+	
+	// find the next unused orptr
+	if (formatlistptr->orptr == NULL) {
+	  formatlistptr->orptr = new format_t();
+	  or_ptr = formatlistptr->orptr;
+	} else {
+	  or_ptr = formatlistptr->orptr;
+	  while (or_ptr->nextptr != NULL)
+	    or_ptr = or_ptr->nextptr;
+	  or_ptr->nextptr = new format_t();
+	  or_ptr = or_ptr->nextptr;
+	}
+
+	if (!text.empty())
+	  {
+	    if (!parse_string(text, or_ptr, metadata, getParents)) { return false; }
+	  }
+
+	if (*here == '{')
+	  {
+	    // Supports: {Or}{[Booktitle],[Title],{If}{[XXXX],aaa,bbb}}
+	    // but not : {Or}{[Booktitle],[Title]{If}{[XXXX],aaa,bbb}}
+	    // The latter can always be re-written:
+	    // {Or}{[Booktitle],{If}{[Title],[Title]{If}{[XXXX],aaa,bbb}}}
+	    
+	    if (!text.empty()) // already used up allocated format_t
+	      {
+		// => allocate new one for detected action
+		or_ptr->nextptr = new format_t();
+		or_ptr = or_ptr->nextptr;
+	      }
+	    if (!parse_action(++here, end, or_ptr, metadata, getParents))
+	      { 
+		return false;
+	      }
+	  }
+	else
+	  {
+	    if (*here == '}') break;
+	  }
+	text.clear();
+
+      } 
+
+      // Parse an {If}{decide,do,else} statement
+      else {
+	
+	// Read the decision component.  
+	if (commacount == 0) {
+	  // Decsion can be a metadata element, or a piece of text.
+	  // Originally Stefan's code, updated 25/10/2000 by Gordon.
+
+	  text_t::const_iterator beginbracket = text.begin();
+	  text_t::const_iterator endbracket = (text.end() - 1);
+
+	  // Decision is based on a metadata element
+	  if ((*beginbracket == '[') && (*endbracket == ']')) {
+	    // Ignore the surrounding square brackets
+	    text_t meta = substr (beginbracket+1, endbracket);
+	    parse_meta (meta, formatlistptr->decision.meta, metadata, getParents);
+	    ++commacount;
+	    text.clear();
+	  } 
+
+	  // Decision is a piece of text (probably a macro like _cgiargmode_).
+	  else {
+
+	    // hunt for any metadata in string, which might be uses in
+	    // to test a condition, e.g. [Format] eq 'PDF'
+	    format_t* dummyformat = new format_t();
+	    // update which metadata fields needed 
+	    // (not interested in updatng formatlistptr)
+	    parse_string (text, dummyformat, metadata, getParents);
+	    delete dummyformat;
+
+	    formatlistptr->decision.command = dText;
+	    formatlistptr->decision.text = text;
+	    ++commacount;
+	    text.clear();
+	  }
+	} 
+
+	// Read the "then" and "else" components of the {If} statement.
+	else {
+	  format_t** nextlistptr = NULL;
+	  if (commacount == 1) {
+	    nextlistptr = &formatlistptr->ifptr;
+	  } else if (commacount == 2 ) {
+	    nextlistptr = &formatlistptr->elseptr;
+	  } else {
+	    return false;
+	  }
+
+	  if (!text.empty()) {
+	    if (*nextlistptr == NULL) {
+	      *nextlistptr = new format_t();
+	    } else {
+
+	      // skip to the end of any format_t statements already added
+	      while ((*nextlistptr)->nextptr != NULL)
+	      {
+		nextlistptr = &(*nextlistptr)->nextptr;
+	      }
+
+	      (*nextlistptr)->nextptr = new format_t();
+	      nextlistptr = &(*nextlistptr)->nextptr;
+	    }
+
+	    if (!parse_string (text, *nextlistptr, metadata, getParents)) 
+	      { 
+		return false; 
+	      }
+	    text.clear();
+	  }
+	  
+	  if (*here == '{')
+	    {
+	      if (*nextlistptr == NULL) {
+		*nextlistptr = new format_t();
+	      } else {
+		// skip to the end of any format_t statements already added
+		while ((*nextlistptr)->nextptr != NULL)
+		  {
+		    nextlistptr = &(*nextlistptr)->nextptr;
+		  }
+
+		(*nextlistptr)->nextptr = new format_t();
+		nextlistptr = &(*nextlistptr)->nextptr;
+	      }
+
+	      if (!parse_action(++here, end, *nextlistptr, metadata, getParents))
+		{ 
+		  return false;
+		}
+	    }
+	  else 
+	    { 
+	      if (*here == '}') break;
+	      ++commacount; 
+	    }
+	}
+      }
+      
+    } else text.push_back(*here);
+    
+    if (here != end) ++here;
+  }
+
+  return true;
+}
+
+
+static text_t spanwrap_metatext(const text_t& metatext, const text_t& OID, 
+				const text_t metaname, int metapos=-1)
+{
+
+  text_t tag_type = (metaname == "Text") ? "div" : "span";
+  text_t editable_type = (metaname == "Text") ? "text" : "metadata";
+
+  text_t wrapped_metatext = "<" + tag_type + " ";
+  wrapped_metatext += "class=\"editable-" + editable_type + "\" ";
+
+  wrapped_metatext += "docoid=\"" + OID + "\" ";  
+  wrapped_metatext += "metaname=\"" + metaname + "\"";
+
+  if (metapos>=0) {
+    text_t metapos_str = metapos;
+    wrapped_metatext += " metapos=\"" + metapos_str + "\"";
+  }
+
+  wrapped_metatext += ">" + metatext + "</" + tag_type + ">";
+
+  return wrapped_metatext;
+}
+
+	
+
+bool parse_formatstring (const text_t &formatstring, format_t *formatlistptr, 
+			 text_tset &metadata, bool &getParents) {
+
+  formatlistptr->clear();
+  getParents = false;
+
+  return (parse_string (formatstring, formatlistptr, metadata, getParents));
+}
+
+// position -1 for all, -2 for the last, 0 for the first, or x for a particular piece
+// metainfo has all the values for the metadata, meta has the request metadata name and options, position tells which values to get
+
+static text_t get_formatted_meta_text(const text_t& OID, MetadataInfo_t &metainfo, const metadata_t &meta, int position, bool no_cgisafe = false) 
+{
+  text_t no_ns_metaname = remove_namespace(meta.metaname);
+  text_t formatted_metatext;
+  bool first = true;
+  
+  const int start_i=0;
+  const int end_i = metainfo.values.size()-1;
+  
+  if (position == -1) { // all
+    for (int i=start_i; i<=end_i; ++i) {
+      if (!first) formatted_metatext += meta.siblingoptions;
+      
+      text_t fresh_metatext;
+
+      if (meta.metacommand & mSpecial) {
+	// special formatting
+	if (no_ns_metaname == "Date") fresh_metatext = format_date (metainfo.values[i]);
+	else if (no_ns_metaname == "Language") fresh_metatext = iso639(metainfo.values[i]);
+	else fresh_metatext = "_format:"+meta.metaname+"_("+metainfo.values[i]+")";
+      }
+      else fresh_metatext = metainfo.values[i];
+
+      if (metadata_spanwrap) {
+	fresh_metatext = spanwrap_metatext(fresh_metatext,OID,meta.metaname,i);
+      }
+      formatted_metatext += fresh_metatext;
+
+      first = false;
+      
+    }
+  } else {
+    if (position == -2) { // end
+      position = end_i;
+    } else if (position < start_i || position > end_i) {
+      return "";
+    }
+
+    text_t fresh_metatext;
+    if (meta.metacommand & mSpecial) {
+
+      // special formatting
+      if (no_ns_metaname == "Date") fresh_metatext = format_date (metainfo.values[position]);
+      else if (no_ns_metaname == "Language") fresh_metatext = iso639(metainfo.values[position]);
+      else fresh_metatext = "_format:"+meta.metaname+"_("+metainfo.values[position]+")";
+    } 
+    else fresh_metatext = metainfo.values[position];
+
+    if (metadata_spanwrap) {
+      fresh_metatext = spanwrap_metatext(fresh_metatext,OID,meta.metaname,position);
+    }
+
+    formatted_metatext += fresh_metatext;
+  }
+
+  if (meta.metacommand & mCgiSafe && !no_cgisafe) return cgi_safe_unicode (formatted_metatext);
+  else return formatted_metatext;
+}
+
+static text_t get_parent_meta (ResultDocInfo_t &docinfo, const metadata_t &meta, int siblings_values) 
+{
+  
+  MetadataInfo_t *parent = docinfo.metadata[meta.metaname].parent;
+
+  switch (meta.mqualifier.parent) {
+  case pNone:
+    return "Nothing!!";
+    break;
+
+  case pImmediate:
+    if (parent != NULL) {
+      text_t parent_oid = get_parent(docinfo.OID);
+      return get_formatted_meta_text(parent_oid,*parent, meta, siblings_values);
+    }
+    break;
+
+  case pTop:
+    if (parent != NULL) {
+      text_t parent_oid = get_parent(docinfo.OID);
+
+      while (parent->parent != NULL) {
+	parent = parent->parent;
+	parent_oid = get_parent(parent_oid);
+      }
+      return get_formatted_meta_text(parent_oid,*parent, meta, siblings_values);
+    }
+    break;
+
+  case pAll:
+    MetadataInfo_t *parent = docinfo.metadata[meta.metaname].parent;
+    if (parent != NULL) {
+      text_t parent_oid = get_parent(docinfo.OID);
+
+      text_tarray tmparray;
+      while (parent != NULL) {
+	tmparray.push_back (get_formatted_meta_text(parent_oid,*parent, meta, siblings_values, true)); // set no_cgisafe to true, as we'll do it once we have all the metadata
+	parent = parent->parent;
+	parent_oid = get_parent(parent_oid);
+
+      }
+      // now join them up - use teh parent separator
+      bool first = true;
+      text_t tmp;
+      text_tarray::reverse_iterator here = tmparray.rbegin();
+      text_tarray::reverse_iterator end = tmparray.rend();
+      while (here != end) {
+	if (!first) tmp += meta.parentoptions;
+	tmp += *here;
+	first = false;
+	++here;
+      }
+      if (meta.metacommand & mCgiSafe) return cgi_safe_unicode (tmp);
+      else return tmp;
+    }
+  }
+  return "";
+
+}
+
+static text_t get_child_meta (const text_t& collection, 
+			      recptproto* collectproto,
+			      ResultDocInfo_t &docinfo, displayclass &disp,
+			      const metadata_t &meta, text_tmap &options,
+			      ostream& logout, int siblings_values) 
+{
+  if (docinfo.metadata["contains"].values[0].size()==0) return ""; // no children
+  
+  const text_t& pre_tree_trav = meta.pre_tree_traverse;
+  const text_t& child_metaname = meta.metaname;
+  const text_t& child_field = meta.childoptions;
+  text_tset child_metadata;
+  child_metadata.insert(child_metaname); 
+
+  FilterResponse_t child_response;
+  if (meta.mqualifier.child == cNum) {
+    // just one child
+    //get the information associated with the metadata for child doc
+    if (!get_info (docinfo.OID+pre_tree_trav+child_field, collection, "", 
+		   child_metadata, false, collectproto, child_response, 
+		   logout)) return ""; // invalid child number
+
+      if (child_response.docInfo.empty()) return false; // no info for the child
+  
+      ResultDocInfo_t& child_docinfo = child_response.docInfo[0];
+      MetadataInfo_t& metaname_rec = child_docinfo.metadata[child_metaname];
+  
+      text_t child_metavalue 
+	= get_formatted_meta_text(child_docinfo.OID,metaname_rec,meta,siblings_values);
+      return expand_metadata(child_metavalue,collection,collectproto,
+			 child_docinfo,disp,options,logout);
+  }
+  
+    
+  if (meta.mqualifier.child != cAll) return false; // invalid qualifier
+
+
+  if (!pre_tree_trav.empty()) {
+    // need to get relevant "contains" metadata for new (e.g. pre tree trav) node
+    FilterResponse_t trav_response;
+
+    text_tset trav_metadata;
+    trav_metadata.insert("contains"); 
+
+    if (!get_info (docinfo.OID+pre_tree_trav, collection, "", 
+		   trav_metadata, false, collectproto, trav_response, 
+		   logout)) return ""; // invalid pre_tree_trav
+
+    if (trav_response.docInfo.empty()) return false; // no info for the pre_tree_trav OID
+  
+    ResultDocInfo_t& trav_docinfo = trav_response.docInfo[0];
+    // use this for rest of routine
+    docinfo = trav_docinfo;
+  }
+  
+  // we need to get all children
+  text_t result = "";
+  text_tarray children;
+  text_t contains = docinfo.metadata["contains"].values[0];
+  splitchar (contains.begin(), contains.end(), ';', children);
+  text_tarray::const_iterator here = children.begin();
+  text_tarray::const_iterator end = children.end();
+  bool first = true;
+  while (here !=end) {
+    text_t oid = *here;
+    here++;
+    if (*(oid.begin()) == '"') translate_parent (oid, docinfo.OID);
+    
+    //get the information associated with the metadata for child doc
+    if (!get_info (oid, collection, "", child_metadata, 
+		   false, collectproto, child_response, logout) ||
+	child_response.docInfo.empty()) {
+      first = false;
+      continue;
+    }
+    
+    
+    ResultDocInfo_t& child_docinfo = child_response.docInfo[0];
+    MetadataInfo_t& metaname_rec = child_docinfo.metadata[child_metaname];
+    
+    text_t child_metavalue 
+      = get_formatted_meta_text(child_docinfo.OID,metaname_rec,meta,siblings_values);
+    if (!first) result += child_field;
+    first = false;
+    // need to do this here cos otherwise we are in the wrong document
+    result +=  expand_metadata(child_metavalue,collection,collectproto,
+			       child_docinfo,disp,options,logout);
+  }
+  return result;
+    
+}
+
+static text_t get_meta (const text_t& collection, recptproto* collectproto,
+			ResultDocInfo_t &docinfo, displayclass &disp,
+			const metadata_t &meta, text_tmap &options,
+			ostream& logout) {
+  
+  // make sure we have the requested metadata
+  MetadataInfo_tmap::iterator it = docinfo.metadata.find (meta.metaname);
+  if (it == docinfo.metadata.end()) return "";
+
+  int siblings_values = 0; // default is no siblings, just the first metadata available
+  if (meta.metacommand & mSibling) {
+    if (meta.mqualifier.sibling == sAll) {
+      siblings_values = -1; //all
+    } else if (meta.mqualifier.sibling == sNum) {
+      siblings_values = meta.siblingoptions.getint();
+    }
+  }
+  if (meta.metacommand & mParent) {
+    return get_parent_meta(docinfo,meta,siblings_values);
+  }
+
+  else if (meta.metacommand & mChild) {
+    return get_child_meta(collection,collectproto,docinfo,disp,meta,
+			    options,logout, siblings_values);
+  }
+  else if (meta.metacommand & mSibling) { // only siblings
+    MetadataInfo_t& metaname_rec = docinfo.metadata[meta.metaname];
+    return get_formatted_meta_text(docinfo.OID,docinfo.metadata[meta.metaname],meta, siblings_values);
+  }
+  else {
+	
+    // straightforward metadata request (nothing fancy)
+
+    text_t classifier_metaname = docinfo.classifier_metadata_type;
+    int metaname_index 
+      = (classifier_metaname == meta.metaname) ? docinfo.classifier_metadata_offset : 0;
+    return get_formatted_meta_text(docinfo.OID,docinfo.metadata[meta.metaname], meta, metaname_index);
+  }
+  
+  return "";
+}
+
+static text_t get_or (const text_t& collection, recptproto* collectproto,
+		      ResultDocInfo_t &docinfo, displayclass &disp,
+		      format_t *orptr, text_tmap &options,
+		      ostream& logout) {
+
+  while (orptr != NULL) {
+
+    if (metadata_spanwrap) {
+      // need to be a bit more careful about this
+      // => test for it *without* spanwrap, and if defined, then
+      // got back and generate it again, this time with spanwrap on
+
+      metadata_spanwrap = false;
+      text_t test_tmp = format_string (collection,collectproto,docinfo, disp, orptr, 
+				       options, logout);
+      metadata_spanwrap = true;
+      if (!test_tmp.empty()) {
+
+	return format_string (collection,collectproto,docinfo, disp, orptr, 
+			      options, logout);
+      }
+    }
+    else {
+      text_t tmp = format_string (collection,collectproto,docinfo, disp, orptr, 
+				  options, logout);
+      if (!tmp.empty()) return tmp;
+    }
+
+    orptr = orptr->nextptr;
+  }
+  return "";
+}
+
+static bool char_is_whitespace(const char c) 
+{
+  return ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'));
+
+}
+
+static int scan_over_whitespace(const text_t& outstring, const int start_pos)
+{
+  int pos = start_pos;
+  while (pos<outstring.size()) {
+    if (!char_is_whitespace(outstring[pos])) {
+      break;
+    }
+    ++pos;
+  }
+
+  return pos;
+}
+
+static int rscan_over_whitespace(const text_t& outstring, const int start_pos)
+{
+  int pos = start_pos;
+  while (pos>=0) {
+    if (!char_is_whitespace(outstring[pos])) {
+      break;
+    }
+    --pos;
+  }
+
+  return pos;
+}
+
+static int rscan_for_whitespace(const text_t& outstring, const int start_pos)
+{
+  int pos = start_pos;
+  while (pos>=0) {
+    if (char_is_whitespace(outstring[pos])) {
+      break;
+    }
+    --pos;
+  }
+
+  return pos;
+}
+
+
+static int rscan_for(const text_t& outstring, const int start_pos, 
+		     const char find_c)
+{
+  int pos = start_pos;
+  while (pos>=0) {
+    char c = outstring[pos];
+    if (outstring[pos] == find_c) {
+      break;
+    }
+    --pos;
+  }
+
+  return pos;
+}
+
+text_t extract_substr(const text_t& outstring, const int start_pos,
+		      const int end_pos)
+{
+  text_t extracted_str;
+  extracted_str.clear();
+
+  for (int pos=start_pos; pos<=end_pos; ++pos) {
+    extracted_str.push_back(outstring[pos]);
+  }
+
+  return extracted_str;
+}
+
+
+static text_t expand_potential_metadata(const text_t& collection, 
+					recptproto* collectproto,
+					ResultDocInfo_t &docinfo, 
+					displayclass &disp,
+					const text_t& intext,
+					text_tmap &options,
+					ostream& logout)
+{
+  text_t outtext;
+
+  // decide if dealing with metadata or text
+
+  text_t::const_iterator beginbracket = intext.begin();
+  text_t::const_iterator endbracket = (intext.end() - 1);
+
+  // Decision is based on a metadata element
+  if ((*beginbracket == '[') && (*endbracket == ']')) {
+    // Ignore the surrounding square brackets
+    text_t meta_text = substr (beginbracket+1, endbracket);
+
+    if (meta_text == "Text") {
+      outtext = format_text(collection, collectproto, docinfo, disp, options, logout);
+    } 
+    else {
+
+      text_tset metadata;
+      bool getParents =false;
+      metadata_t meta;
+      
+      parse_meta (meta_text, meta, metadata, getParents);	
+      outtext 
+	= get_meta (collection,collectproto,docinfo,disp,meta,options,logout);
+    }
+
+  }
+  else {
+    outtext = intext;
+  }
+
+  return outtext;
+}
+
+
+
+
+static bool uses_expression(const text_t& collection, recptproto* collectproto,
+			    ResultDocInfo_t &docinfo,
+			    displayclass &disp,
+			    const text_t& outstring, text_t& lhs_expr,
+			    text_t& op_expr, text_t& rhs_expr,
+			    text_tmap &options,
+			    ostream& logout)
+{
+  // Note: the string may not be of the form: str1 op str2, however
+  // to deterine this we have to process it on the assumption it is,
+  // and if at any point an 'erroneous' value is encountered, return
+  // false and let something else have a go at evaluating it
+
+  // Starting at the end of the string and working backwards ..
+
+  const int outstring_len = outstring.size();
+
+  // skip over white space
+  int rhs_end = rscan_over_whitespace(outstring,outstring_len-1);
+
+  if (rhs_end<=0) { 
+    // no meaningful text or (rhs_end==0) no room for operator
+    return false;
+  }
+
+  // check for ' or " and then scan over token
+  const char potential_quote = outstring[rhs_end];
+  int rhs_start=rhs_end;
+  bool quoted = false;
+
+  if ((potential_quote == '\'') || (potential_quote == '\"')) {
+    --rhs_end;
+    rhs_start = rscan_for(outstring,rhs_end-1,potential_quote) +1;
+    quoted = true;
+  }
+  else {
+    rhs_start = rscan_for_whitespace(outstring,rhs_end-1) +1;
+  }
+
+  if ((rhs_end-rhs_start)<0) {
+    // no meaningful rhs expression
+    return false;
+  }
+
+  // form rhs_expr
+  rhs_expr = extract_substr(outstring,rhs_start,rhs_end);
+
+  // skip over white space
+  const int to_whitespace = (quoted) ? 2 : 1;
+
+  int op_end = rscan_over_whitespace(outstring,rhs_start-to_whitespace);
+  int op_start = rscan_for_whitespace(outstring,op_end-1)+1;
+
+  if ((op_end<0) && (op_start<0)) {
+	// no meaningful expression operator
+    return false;
+  }
+
+  if (op_end-op_start<0) {
+    // no meaningful expression operator
+    return false;
+  }
+
+  op_expr = extract_substr(outstring,op_start,op_end);
+
+
+  // check for operator
+  if ((op_expr != "eq") && (op_expr != "ne") && (op_expr != "gt") &&
+     (op_expr != "ge") && (op_expr != "lt") && (op_expr != "le") && (op_expr != "==") && (op_expr != "!=") &&  (op_expr != ">") && (op_expr != ">=") && (op_expr != "<") && (op_expr != "<=") && (op_expr != "sw") && (op_expr != "ew")) {
+
+    // not a valid operator
+    return false;
+  }
+
+  int lhs_end = rscan_over_whitespace(outstring,op_start-1);
+  if (lhs_end<0) {
+    // no meaningful lhs expression
+    return false;
+  }
+
+  int lhs_start = scan_over_whitespace(outstring,0);
+
+  // form lhs_expr from remainder of string
+  lhs_expr = extract_substr(outstring,lhs_start,lhs_end);
+
+  // Now we know we have a valid expression, look up any 
+  // metadata terms
+
+  rhs_expr = expand_potential_metadata(collection,collectproto,docinfo,
+				       disp,rhs_expr,options,logout);
+  lhs_expr = expand_potential_metadata(collection,collectproto,docinfo,
+				       disp,lhs_expr,options,logout);
+
+  return true;
+}
+
+static bool eval_expression_true(const text_t& lhs_expr,const text_t& op_expr,
+				 const text_t& rhs_expr, ostream& logout)
+{
+  if (op_expr == "eq") return (lhs_expr == rhs_expr);
+  else if (op_expr == "ne" ) return (lhs_expr != rhs_expr);
+  else if (op_expr == "gt") return (lhs_expr > rhs_expr);
+  else if (op_expr == "ge") return (lhs_expr >= rhs_expr);
+  else if (op_expr == "lt") return (lhs_expr < rhs_expr);
+  else if (op_expr == "le") return (lhs_expr <= rhs_expr);
+  else if (op_expr == "==") return (lhs_expr.getint() == rhs_expr.getint());
+  else if (op_expr == "!=") return (lhs_expr.getint() != rhs_expr.getint());
+  else if (op_expr == ">") return (lhs_expr.getint() > rhs_expr.getint());
+  else if (op_expr == ">=") return (lhs_expr.getint() >= rhs_expr.getint());
+  else if (op_expr == "<") return (lhs_expr.getint() < rhs_expr.getint());
+  else if (op_expr == "<=") return (lhs_expr.getint() <= rhs_expr.getint());
+  else if (op_expr == "sw") return (starts_with(lhs_expr,rhs_expr));
+  else if (op_expr == "ew") return (ends_with(lhs_expr,rhs_expr));
+  else {
+    logout << "Error: '" << op_expr << "' is not a recognised operator." << endl;
+  }
+  
+  return false;
+}
+
+
+static text_t get_if (const text_t& collection, recptproto* collectproto,
+		      ResultDocInfo_t &docinfo, displayclass &disp, 
+		      const decision_t &decision,
+		      format_t *ifptr, format_t *elseptr,
+		      text_tmap &options, ostream& logout) 
+{
+  // If the decision component is a metadata element, then evaluate it
+  // to see whether we output the "then" or the "else" clause
+  if (decision.command == dMeta) {
+
+    bool store_metadata_spanwrap = metadata_spanwrap;
+    metadata_spanwrap = 0;
+
+    // temporarily suspend metadata-spanwrap (if on) so can test if metadata item really exits or not
+    bool metadata_exists 
+      = (get_meta (collection,collectproto,docinfo,disp,decision.meta,options,
+		   logout) != "");
+
+    metadata_spanwrap = store_metadata_spanwrap;
+
+    if (metadata_exists) {
+      if (ifptr != NULL)
+	return get_formatted_string (collection,collectproto,docinfo, disp, ifptr, 
+				     options, logout);
+    }
+    else {
+      if (elseptr != NULL)
+	return get_formatted_string (collection,collectproto,docinfo, disp, elseptr,
+				     options, logout);
+    }
+  }
+
+  // If the decision component is text, then evaluate it (it is probably a 
+  // macro like _cgiargmode_) to decide what to output.
+  else if (decision.command == dText) {
+
+    text_t outstring;
+    disp.expandstring (decision.text, outstring);
+
+    // Check for if expression in form: str1 op str2 
+    // (such as [x] eq "y")
+    text_t lhs_expr, op_expr, rhs_expr;
+    if (uses_expression(collection,collectproto,docinfo, disp, outstring,lhs_expr,op_expr,rhs_expr, options,logout)) {
+      if (eval_expression_true(lhs_expr,op_expr,rhs_expr,logout)) {
+	if (ifptr != NULL) {
+	  return get_formatted_string (collection, collectproto, docinfo, disp, ifptr, 
+				       options, logout);
+	}
+	else {
+	  return "";
+	}
+      } else {
+	if (elseptr != NULL) {
+	  return get_formatted_string (collection, collectproto, docinfo, disp, elseptr,
+				       options, logout);
+	}
+	else {
+	  return "";
+	}
+      }
+    }
+
+
+    // This is a tad tricky.  When we expand a string like _cgiargmode_, that is
+    // a cgi argument macro that has not been set, it evaluates to itself.
+    // Therefore, were have to say that a piece of text evalautes true if
+    // it is non-empty and if it is a cgi argument evaulating to itself.
+
+    if ((outstring != "") && !((outstring == decision.text) && (outstring[0] == '_'))) {
+      if (ifptr != NULL)
+	return get_formatted_string (collection, collectproto, docinfo, disp, ifptr, 
+				     options, logout);
+    } else {
+      if (elseptr != NULL)
+	return get_formatted_string (collection, collectproto, docinfo, disp, elseptr,
+				     options, logout);
+    }
+  }
+  
+  return "";
+}
+
+bool includes_metadata(const text_t& text)
+{
+  text_t::const_iterator here = text.begin();
+  text_t::const_iterator end = text.end();
+  while (here != end) {
+    if (*here == '[') return true;
+    ++here;
+  }
+
+  return false;
+}
+
+static text_t expand_metadata(const text_t &metavalue, const text_t& collection,
+			      recptproto* collectproto,
+			      ResultDocInfo_t &docinfo,
+			      displayclass &disp, text_tmap &options,
+			      ostream &logout) {
+      
+  if (includes_metadata(metavalue)) {
+    
+    // text has embedded metadata in it => expand it
+    FilterRequest_t request;
+    FilterResponse_t response;
+    
+    request.getParents = false;
+    
+    format_t *expanded_formatlistptr = new format_t();
+    parse_formatstring (metavalue, expanded_formatlistptr, 
+			request.fields, request.getParents);
+    
+    // retrieve metadata
+    get_info(docinfo.OID, collection, "", request.fields, request.getParents,
+	     collectproto, response, logout);
+    
+    if (!response.docInfo.empty()) {
+      
+      text_t expanded_metavalue
+	= get_formatted_string(collection, collectproto,
+			       response.docInfo[0], disp, expanded_formatlistptr, 
+			       options, logout);
+      
+      return expanded_metavalue;
+    }
+    else {
+      return metavalue;
+    }
+  }
+  else {
+    
+    return metavalue;
+  }
+}
+
+text_t get_collection_meta(const text_t& collection, recptproto* collectproto,
+			   displayclass &disp, 
+			   text_t meta_name, ostream& logout) {
+  
+  ColInfoResponse_t collectinfo;
+  comerror_t err;
+  collectproto->get_collectinfo (collection, collectinfo,err,logout);
+  text_t meta_value = "";
+  text_t lang;
+  disp.expandstring("_cgiargl_",lang);
+  if (lang.empty()) {
+    lang = "en";
+  }
+
+  if (err == noError) {
+    meta_value = collectinfo.get_collectionmeta(meta_name, lang);
+  }
+  return meta_value;
+  
+
+}
+text_t format_string (const text_t& collection, recptproto* collectproto,
+		      ResultDocInfo_t &docinfo, displayclass &disp, 
+		      format_t *formatlistptr, text_tmap &options,
+		      ostream& logout) {
+
+  if (formatlistptr == NULL) return "";
+
+  switch (formatlistptr->command) {
+     case comOID:
+	return docinfo.OID;
+  case comTopOID:
+    {
+      text_t top_id;
+      get_top(docinfo.OID, top_id);
+      return top_id;
+    }
+  case comRank:
+    return text_t(docinfo.ranking);
+     case comText:
+	return formatlistptr->text;
+     case comLink:
+	return options["link"];
+     case comEndLink:
+	if (options["link"].empty()) return "";
+	else return "</a>";
+     case comHref:
+	return get_href(options["link"]);
+     case comIcon:
+	return options["icon"];
+     case comNum:
+	return docinfo.result_num;
+     case comRel: //if [RelatedDocuments] appears in format string, collect relation data
+	return get_related_docs(collection, collectproto, docinfo, logout);
+
+     case comSummary:
+       return format_summary(collection, collectproto, docinfo, disp, options, logout);
+
+     case comMeta:
+	{
+	   const text_t& metavalue =  get_meta (collection,collectproto, docinfo, disp,formatlistptr->meta,options,logout);
+	   return expand_metadata(metavalue, collection, collectproto, docinfo, disp, options, logout);
+	}
+
+     case comDoc:
+       return format_text(collection, collectproto, docinfo, disp, options, logout);
+
+     case comImage:
+	return expand_metadata(options["DocImage"], collection, collectproto, docinfo, disp, options, logout);
+     case comTOC:
+	return options["DocTOC"];
+     case comDocumentButtonDetach:
+	return options["DocumentButtonDetach"];
+     case comDocumentButtonHighlight:
+	return options["DocumentButtonHighlight"];
+     case comDocumentButtonExpandContents:
+	return options["DocumentButtonExpandContents"];
+     case comDocumentButtonExpandText:
+	return options["DocumentButtonExpandText"];
+     case comHighlight:
+	if (options["highlight"] == "1") return "<b>";
+	break;
+     case comEndHighlight:
+	if (options["highlight"] == "1") return "</b>";
+	break;
+     case comMetadataSpanWrap:
+        metadata_spanwrap=true;  return "";
+	break;
+     case comEndMetadataSpanWrap:
+	metadata_spanwrap=false; return "";
+	break;
+     case comIf:
+	return get_if (collection, collectproto, docinfo, disp, 
+		       formatlistptr->decision, formatlistptr->ifptr, 
+		       formatlistptr->elseptr, options, logout);
+     case comOr:
+	return get_or (collection,collectproto, docinfo, disp, formatlistptr->orptr, 
+		       options, logout);
+     case comDocTermsFreqTotal:
+       return docinfo.num_terms_matched;
+     case comCollection:
+       if (formatlistptr->meta.metaname == g_EmptyText) {
+	 return collection;
+       }
+       return get_collection_meta(collection, collectproto, disp, formatlistptr->meta.metaname, logout);
+    
+  }
+  return "";
+}
+
+text_t get_formatted_string (const text_t& collection, recptproto* collectproto,
+			     ResultDocInfo_t &docinfo, displayclass &disp,
+			     format_t *formatlistptr, text_tmap &options,
+			     ostream& logout) {
+
+   text_t ft;
+   while (formatlistptr != NULL) 
+      {
+	 ft += format_string (collection, collectproto, docinfo, disp, formatlistptr, 
+			      options, logout);
+	 formatlistptr = formatlistptr->nextptr;
+      }
+   
+   return ft;
+}
+
+
+// we have only preloaded the text in DocumentAction. But you may want to get the text in query. so copy what we have done with format_summary and get the text here. probably is quite expensive?
+text_t format_text (const text_t& collection, recptproto* collectproto,
+		    ResultDocInfo_t &docinfo, displayclass &disp, 
+		    text_tmap &options, ostream& logout) 
+{
+  text_t text;
+
+  if(!options["text"].empty()) { 
+    text = options["text"];
+  }
+  else {
+    // get document text here
+    DocumentRequest_t docrequest;
+    DocumentResponse_t docresponse;
+    comerror_t err;
+    docrequest.OID = docinfo.OID;
+    collectproto->get_document (collection, docrequest, docresponse, err, logout);
+    text = docresponse.doc;
+  }
+
+  if (metadata_spanwrap) {
+    text = spanwrap_metatext(text,docinfo.OID,"Text");
+  }
+
+  return text;
+}
+  
+/* FUNCTION NAME: format_summary
+ * DESC: this is invoked when a [Summary] special metadata is processed.
+ * RETURNS: a query-biased summary for the document */
+
+text_t format_summary (const text_t& collection, recptproto* collectproto,
+		       ResultDocInfo_t &docinfo, displayclass &disp, 
+		       text_tmap &options, ostream& logout) {
+
+  // GRB: added code here to ensure that the cstr (and other collections)
+  //      uses the document metadata item Summary, rather than compressing
+  //      the text of the document, processed via the methods in
+  //      summarise.cpp
+
+  text_t summary;
+
+  if (docinfo.metadata.count("Summary") > 0 &&
+      docinfo.metadata["Summary"].values.size() > 0) {
+    summary = docinfo.metadata["Summary"].values[0];
+  }
+  else {
+  
+    text_t textToSummarise, query;
+
+    if(options["text"].empty()) { // get document text
+      DocumentRequest_t docrequest;
+      DocumentResponse_t docresponse;
+      comerror_t err;
+      docrequest.OID = docinfo.OID;
+      collectproto->get_document (collection, docrequest, docresponse, err, logout);
+      textToSummarise = docresponse.doc;
+    } 
+    else {
+      // in practice, this would not happen, because text is only 
+      // loaded with the [Text] command
+    textToSummarise = options["text"];
+    }
+    
+    disp.expandstring("_cgiargq_",query);
+    summary = summarise(textToSummarise,query,80);
+  }
+
+  if (metadata_spanwrap) {
+    summary = spanwrap_metatext(summary,docinfo.OID,"Summary");
+  }
+
+  return summary;
+}
Index: /gsdl/stable/runtime-src/src/recpt/formattools.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/formattools.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/formattools.h	(revision 20131)
@@ -0,0 +1,149 @@
+/**********************************************************************
+ *
+ * formattools.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef FORMATTOOLS_H
+#define FORMATTOOLS_H
+
+#include "text_t.h"
+#include "recptproto.h"
+#include "display.h"
+
+enum command_t {comIf, comOr, comMeta, comText, comLink, comEndLink, comNum, comIcon, 
+		comDoc, comHighlight, comEndHighlight, 
+		comMetadataSpanWrap, comEndMetadataSpanWrap,
+		comRel, comHref, comSummary,
+		comTOC, comImage, comDocumentButtonDetach, comDocumentButtonHighlight,
+		comDocumentButtonExpandContents, comDocumentButtonExpandText, comOID, comTopOID, comRank,
+		comCollection, comDocTermsFreqTotal};
+
+enum mcommand_t {mNone=0, mCgiSafe=1, mParent=2, mSibling=4, mChild=8, mSpecial=16};
+
+enum pcommand_t {pNone, pImmediate, pTop, pAll};
+enum scommand_t {sNone, sAll, sNum};
+enum ccommand_t {cNone, cAll, cNum};
+enum dcommand_t {dMeta, dText};
+
+struct metadata_t {
+  void clear();
+  metadata_t () {clear();}
+
+  text_t metaname;
+  int metacommand; // used to hold flags from mcommand_t
+  struct {
+    pcommand_t parent;
+    scommand_t sibling;
+    ccommand_t child;
+  } mqualifier;
+
+  text_t pre_tree_traverse;
+  text_t parentoptions;
+  text_t siblingoptions;
+  text_t childoptions;
+};
+
+
+// The decision component of an {If}{decision,true-text,false-text}
+// formatstring.  The decision can be based on metadata or on text;
+// normally that text would be a macro like _cgiargmode_.  --gordon
+struct decision_t {
+  void clear();
+  decision_t () {clear();}
+
+  dcommand_t command;
+  metadata_t meta;
+  text_t text;
+};
+
+struct format_t {
+  void clear();
+  format_t () {clear();}
+
+  command_t command;
+  decision_t decision;
+  text_t text;
+  metadata_t meta;
+  format_t *nextptr;
+  format_t *ifptr;
+  format_t *elseptr;
+  format_t *orptr;
+};
+
+// the format structure used by this receptionist
+struct formatinfo_t {
+  void clear();
+  formatinfo_t () {clear();}
+
+  bool DocumentImages;
+  bool DocumentTitles;
+  text_t DocumentHeading;
+  bool DocumentContents;
+  bool DocumentArrowsBottom;
+  bool DocumentArrowsTop;
+  bool DocumentSearchResultLinks;
+  text_tarray DocumentButtons;
+  text_t DocumentText;
+  //-----------------
+  text_t RelatedDocuments;
+  //----------------
+  text_tmap formatstrings;
+  bool DocumentUseHTML;
+  bool AllowExtendedOptions;
+};
+
+bool is_table_content (const text_t &formatstring);
+bool is_table_content (const format_t *formatlistptr);
+
+bool get_formatstring (const text_t &key, const text_tmap &formatstringmap,
+		       text_t &formatstring);
+bool get_formatstring (const text_t &key1, const text_t &key2,  
+		       const text_tmap &formatstringmap,
+		       text_t &formatstring);
+
+text_t format_date (const text_t &date);
+
+text_t remove_namespace(const text_t &meta_name);
+
+text_t iso639 (const text_t &langcode);
+
+text_t get_href (const text_t &link);
+
+text_t get_related_docs(const text_t& collection, recptproto* collectproto,
+			  ResultDocInfo_t &docinfo, ostream& logout);
+
+
+bool parse_formatstring (const text_t &formatstring, format_t *formatlistptr, 
+			 text_tset &metadata, bool &getParents);
+
+
+
+text_t get_formatted_string (const text_t& collection, recptproto* collectproto,
+			     ResultDocInfo_t &docinfo, displayclass &disp,
+			     format_t *formatlistptr, text_tmap &options,
+			     ostream& logout);
+
+#endif
+
+
Index: /gsdl/stable/runtime-src/src/recpt/gsdl_compatibility_cfg.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/gsdl_compatibility_cfg.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/gsdl_compatibility_cfg.h	(revision 20131)
@@ -0,0 +1,38 @@
+#ifndef GSDL_COMPATIBILITY_CFG__H
+#define GSDL_COMPATIBILITY_CFG__H
+
+/**********************************************************************
+ *
+ * gsdl_compatibility_cfg.h -- 
+ * Copyright (C) 2004  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+//OLD NAME	NEW NAME
+#define __USE_MULTILANGUAGE_INTERFACE_         GSDL_USE_MULTILANGUAGE_INTERFACE
+#define GSDL_USE_GENERATOR_FEATURE             GSDL_USE_GENERATOR_ACTION
+#define GSDL_USE_EXPORT_FEATURE                GSDL_USE_EXPORT_ACTION
+#define __USE_CLASSIFIER_BROWSER_              GSDL_USE_CLASSIFIER_BROWSER
+#define GSDL_USE_CLONEBROWSERCLASS             GSDL_USE_CLONE_BROWSER
+#define __SOURCE_DIRECTORY_                    GSDL_SOURCE_DIRECTORY
+
+
+#endif //!GSDL_COMPATIBILITY_CFG__H
Index: /gsdl/stable/runtime-src/src/recpt/gsdl_modules_cfg.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/gsdl_modules_cfg.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/gsdl_modules_cfg.h	(revision 20131)
@@ -0,0 +1,90 @@
+#ifndef GSDL_MODULES_CFG__H
+#define GSDL_MODULES_CFG__H
+
+/**********************************************************************
+ *
+ * gsdl_modules_cfg.h -- 
+ * Copyright (C) 2004  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+// BASE CONFIG
+#define GSDL_USE_PER_COLLECTION_SETTINGS
+#define GSDL_SOURCE_DIRECTORY            "files"
+
+// FNORD CONFIG
+#define GSDL_USE_MULTILANGUAGE_INTERFACE
+
+//RECEPTIONIST CONFIG
+#define GSDL_USE_SESSIONS
+
+//QUERY CONFIG
+#define GSDL_USE_REMOVE_TAG_TERMS
+#undef  GSDL_USE_SAFEM_QUERY_FORMAT
+
+//DOCUMENT CONFIG
+// ONLY ONE GSDL_SKIP_* option can be enabled
+#define GSDL_SKIP_ONLY_EMPTY_DOC
+#undef  GSDL_SKIP_ALL_EMPTY_DOC_PARTS
+#undef  GSDL_USE_DOCUMENT_ASSOC_LANGS
+#define GSDL_USE_CL_SINGLE_DOCUMENT
+
+
+//ACTION MODULES
+#define GSDL_USE_AUTHEN_ACTION
+#define GSDL_USE_BROWSE_ACTION
+#define GSDL_USE_COLLECTOR_ACTION
+#define GSDL_USE_DEPOSITOR_ACTION
+#define GSDL_USE_EXTLINK_ACTION
+#undef  GSDL_USE_GTI_ACTION
+#define GSDL_USE_PHIND_ACTION
+#define GSDL_USE_PING_ACTION
+#define GSDL_USE_STATUS_ACTION
+#define GSDL_USE_TIP_ACTION
+#define GSDL_USE_USERS_ACTION
+
+#undef  GSDL_USE_CL_DISPLAY_ACTION
+#undef  GSDL_USE_COURSES_ACTION
+#undef  GSDL_USE_DIR_BROWSE_ACTION
+#undef  GSDL_USE_EXPORT_ACTION
+#undef  GSDL_USE_GENERATOR_ACTION
+#undef  GSDL_USE_INDEX_BROWSE_ACTION
+
+
+//BROWSER MODULES
+#undef  GSDL_USE_CLASSIFIER_BROWSER
+#undef  GSDL_USE_TREE_EX_CLASSIFIER_BROWSER
+#undef  GSDL_USE_CLONE_BROWSER
+#define GSDL_USE_DATELIST_BROWSER
+#define GSDL_USE_HTML_BROWSER
+#define GSDL_USE_PAGED_BROWSER
+#define GSDL_USE_PHIND_BROWSER
+
+//FILTERS
+#undef  GSDL_USE_DIR_BROWSEFILTER
+
+//BROWSERS ADD-IN
+#define GSDL_USE_BY_BOOK_MACROS
+#undef  GSDL_USE_FLOAT_TOC
+
+#include "gsdl_compatibility_cfg.h"
+
+#endif //!GSDL_MODULES_CFG__H
Index: /gsdl/stable/runtime-src/src/recpt/gtiaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/gtiaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/gtiaction.cpp	(revision 20131)
@@ -0,0 +1,847 @@
+/**********************************************************************
+ *
+ * gtiaction.cpp -- 
+ * Copyright (C) 2005  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_GTI_ACTION
+
+
+#include <expat.h>
+#include <stdio.h>
+#include <sys/utsname.h>
+#include "gtiaction.h"
+#include "cgiutils.h"
+#include "fileutil.h"
+#include "gsdlunicode.h"
+
+
+
+gtiaction::gtiaction()
+{
+  cgiarginfo arg_ainfo;
+
+  arg_ainfo.shortname = "tlc";
+  arg_ainfo.longname = "translation target language code";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (&cerr, arg_ainfo);
+
+  arg_ainfo.shortname = "tfk";
+  arg_ainfo.longname = "translation file key";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (&cerr, arg_ainfo);
+
+  arg_ainfo.shortname = "ncpp";
+  arg_ainfo.longname = "number of chunks per page";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "1";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (&cerr, arg_ainfo);
+}
+
+
+
+gtiaction::~gtiaction()
+{
+  delete[] set_gsdlhome_cstr;
+  delete[] set_gsdlos_cstr;
+}
+
+
+
+bool gtiaction::init (ostream& /*logout*/)
+{
+  // Set GSDLHOME and GSDLOS environment variables
+  text_t set_gsdlhome = "GSDLHOME=" + gsdlhome;
+  text_t set_gsdlos = "GSDLOS=";
+
+#if defined (__WIN32__)
+  set_gsdlos += "windows";
+#else
+  struct utsname *buf = new struct utsname();
+  if (uname(buf) == -1) {
+    // uname failed, so this must be linux
+    set_gsdlos += "linux";
+  }
+  else {
+    text_t gsdlos = buf->sysname;
+    lc(gsdlos);
+    set_gsdlos += gsdlos;
+  }
+  delete buf;
+#endif
+
+  // These will be cleaned up in the destructor
+  set_gsdlhome_cstr = set_gsdlhome.getcstr();
+  set_gsdlos_cstr = set_gsdlos.getcstr();
+  putenv(set_gsdlhome_cstr);
+  putenv(set_gsdlos_cstr);
+
+  return true;
+}
+
+
+
+bool gtiaction::check_cgiargs(cgiargsinfoclass& /*argsinfo*/, cgiargsclass& args,
+			      recptprotolistclass* /*protos*/, ostream& logout)
+{
+  // Authenticate the user, except for the "home" and "lang" pages
+  if (args["p"] != "home" && args["p"] != "lang" && args["p"] != "status") {
+    args["uan"] = 1;
+    args["ug"] = "langadmin_" + args["tlc"];
+  }
+
+  return true;
+}
+
+
+
+bool gtiaction::do_action(cgiargsclass& args, recptprotolistclass* /*protos*/, 
+			  browsermapclass* /*browsers*/, displayclass& disp, 
+			  outconvertclass& outconvert, ostream& textout, 
+			  ostream& logout)
+{
+  // Special case for producing Excel spreadsheets, as these are downloaded
+  if (args["p"] == "excel") {
+    return produce_excel_spreadsheet(args, logout);
+  }
+
+  textout << outconvert << disp << ("_gti:header_\n") << ("_gti:content_\n") << ("_gti:footer_\n");
+  return true;
+}
+
+
+
+void gtiaction::get_cgihead_info(cgiargsclass& args, recptprotolistclass* /*protos*/,
+				 response_t& response, text_t& response_data, 
+				 ostream& logout)
+{
+  // Special case for producing Excel spreadsheets, as these are downloaded
+  if (args["p"] == "excel") {
+    printf("Content-Disposition: attachment; filename=\"Greenstone-%s-%s.xml\"\n", args["tlc"].getcstr(), args["tfk"].getcstr());
+    response = content;
+    response_data = "text/xml";
+    return;
+  }
+
+  response = content;
+  response_data = "text/html";
+}
+
+
+
+void gtiaction::define_internal_macros(displayclass& disp, cgiargsclass& args, 
+				       recptprotolistclass* protos, ostream& logout)
+{
+  // logout << endl << "Arguments: " << args << endl;
+  logout << endl << "CGI arg p: " << args["p"] << endl;
+
+  // For some reason this must be done as well as setting the macro in gti.dm
+  // is that still true??
+  disp.setmacro("preflink", displayclass::defaultpackage, "_gti:preflink_");
+  
+  // Define the page content for the GTI home page
+  if (args["p"] == "home") {
+    define_gti_home_page(disp, args, logout);
+    return;
+  }
+
+  // Define the page content for the GTI language page
+  if (args["p"] == "lang") {
+    define_gti_lang_page(disp, args, logout);
+    return;
+  }
+
+  // Define the page content for the GTI search page
+  if (args["p"] == "find") {
+    define_gti_find_page(disp, args, logout);
+    return;
+  }
+
+  // Define the page content for the GTI offline page
+  if (args["p"] == "offline") {
+    define_gti_offline_page(disp, args, logout);
+    return;
+  }
+  
+  // Define the page content for the GTI view status page
+  if (args["p"] == "status") {
+    define_gti_status_page(disp, args, logout);
+    return;
+  }
+
+  // Process user translations
+  if (args["p"] == "submit") {
+    process_gti_submissions(disp, args, logout, true);
+  }
+
+  if (args["p"] == "glihelp") {
+    produce_glihelp_zipfile(disp, args, logout);    
+  }
+  	
+  // Define the page content for the GTI core pages (containing the translation input forms)
+  define_gti_core_page(disp, args, logout);
+}
+
+
+
+void gtiaction::define_gti_home_page(displayclass& disp, cgiargsclass& args, ostream& logout)
+{
+  disp.setmacro("gtiformcontent", "gti", "_gti:gtihome_");
+
+  languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
+
+  // Get the languages specified in the main.cfg file, and put them into a map to sort by name
+  text_tmap gti_languages_name_code_mapping;
+  languageinfo_tmap::const_iterator loaded_language = loaded_languages.begin();
+  while (loaded_language != loaded_languages.end()) {
+    // English is not a valid GTI target language, since it is the source language
+    if (loaded_language->first != "en") {
+      gti_languages_name_code_mapping[loaded_language->second.longname] = loaded_language->first;
+    }
+    ++loaded_language;
+  }
+
+  // Set the gtitlcselection macro
+  text_t gti_tlc_selection = "<select name=\"tlc\">\n";
+  text_tmap::iterator gti_language = gti_languages_name_code_mapping.begin();
+  while (gti_language != gti_languages_name_code_mapping.end()) {
+    gti_tlc_selection += "<option value=\"" + gti_language->second + "\">" + gti_language->first + "</option>\n";
+    ++gti_language;
+  }
+  gti_tlc_selection += "</select>";
+  disp.setmacro("gtitlcselection", "gti", gti_tlc_selection);
+}
+
+
+
+void gtiaction::define_gti_lang_page(displayclass& disp, cgiargsclass& args, ostream& logout)
+{
+  // Get the target language code from the CGI arguments
+  text_t target_language_code = args["tlc"];
+
+  disp.setmacro("gtiformcontent", "gti", "_gti:gtilang_");
+
+  // Send a request to gti.pl to get the valid translation files
+  text_t gti_arguments = "get-language-status " + target_language_code;
+  GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout);
+  if (gti_response.error_message != "") {
+    // An error has occurred
+    disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_");
+    disp.setmacro("gtierrormessage", "gti", gti_response.error_message);
+    return;
+  }
+
+  languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
+  disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
+
+  // Set the gtitfkselection macro
+  text_t gti_tfk_selection = "<table>";
+  text_tmap::iterator translation_file = gti_response.translation_files_index_to_key_mapping.begin();
+  while (translation_file != gti_response.translation_files_index_to_key_mapping.end()) {
+    text_t translation_file_key = translation_file->second;
+
+    gti_tfk_selection += "<tr><td>";
+    gti_tfk_selection += "<input type=\"radio\" name=\"tfk\" value=\"" + translation_file_key + "\"></td>\n";
+    gti_tfk_selection += "<td>_textgti" + translation_file_key + "_</td></tr>\n";
+
+    text_t num_chunks_translated = gti_response.translation_files_key_to_num_chunks_translated_mapping[translation_file_key];
+    text_t num_chunks_requiring_translation = gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key];
+    text_t num_chunks_requiring_updating = gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key];
+    gti_tfk_selection += "<tr><td></td><td>_gtitranslationfilestatus_(" + num_chunks_translated + "," + num_chunks_requiring_translation + "," + num_chunks_requiring_updating + ")</td></tr>\n";
+    ++translation_file;
+  }
+  gti_tfk_selection += "</table>";
+  disp.setmacro("gtitfkselection", "gti", gti_tfk_selection);
+}
+
+
+
+void gtiaction::define_gti_status_page(displayclass& disp, cgiargsclass& args, ostream& logout)
+{
+  disp.setmacro("gtiformcontent", "gti", "_gti:gtistatus_");
+
+  languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
+
+  // Get the languages specified in the main.cfg file, and put them into a map to sort by name
+  text_tmap gti_languages_name_code_mapping;
+  languageinfo_tmap::const_iterator loaded_language = loaded_languages.begin();
+  while (loaded_language != loaded_languages.end()) {
+    // English is not a valid GTI target language, since it is the source language
+    if (loaded_language->first != "en") {
+      gti_languages_name_code_mapping[loaded_language->second.longname] = loaded_language->first;
+    }
+    ++loaded_language;
+  }
+
+  // Get the languages, for each language, send a request to gti.pl to get the valid translation files and the current status for each file
+  text_t gti_status_table = "<table class=\"status\">\n";
+  text_tmap::iterator gti_language = gti_languages_name_code_mapping.begin();
+  bool first_lang = true;
+  while (gti_language != gti_languages_name_code_mapping.end()) {    
+    // Send a request to gti.pl to get the valid translation files
+    text_t gti_arguments = "get-language-status " + gti_language->second;
+    GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout);
+    if (gti_response.error_message != "") {
+      // An error has occurred
+      disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_");
+      disp.setmacro("gtierrormessage", "gti", gti_response.error_message);
+      return;
+    }
+
+    text_tmap::iterator translation_file = gti_response.translation_files_index_to_key_mapping.begin();
+        
+    text_t lang_status_temp = "<tr><td class=\"first\">" + gti_language->first + "</td>\n";
+    text_t files_temp = "<tr><th class=\"status\">_textgtilanguage_</th>\n";
+    text_t number_of_strings_temp = "<tr><td class=\"first\"><b>_textgtitotalnumberoftranslations_</b></td>\n";
+    
+    while (translation_file != gti_response.translation_files_index_to_key_mapping.end()) {
+      text_t translation_file_key = translation_file->second;                     
+
+      text_t num_chunks_translated = gti_response.translation_files_key_to_num_chunks_translated_mapping[translation_file_key];
+      text_t num_chunks_requiring_translation = gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key];
+    	text_t num_chunks_requiring_updating = gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key];   		
+    	
+    	lang_status_temp += "<td class=\"status\">";
+    	if(num_chunks_translated.getint() > 0){
+    		lang_status_temp += "<div class=\"nowrap\"><div class=\"done\">";
+    		lang_status_temp += num_chunks_translated+"</div><div class=\"plus\">+</div><div class=\"update\">";
+  	  	lang_status_temp += num_chunks_requiring_updating+"</div><div class=\"plus\">+</div><div class=\"todo\">";
+  	  	lang_status_temp += num_chunks_requiring_translation+"</div></div>";
+    	}
+    	lang_status_temp += "</td>\n";
+    	
+    	
+	//lang_status_temp += "<td valign=\"top\" nowrap>_gtitranslationfilestatus2_(" + num_chunks_translated + "," + num_chunks_requiring_translation + "," + num_chunks_requiring_updating + ")</td>";   		
+   		
+	// List the file names as the first row of the status table 
+	// Add up number of strings need to be translate in each file, as the second line of the status table
+      if (first_lang) {
+        files_temp += "<th class=\"status\">_textgti" + translation_file_key + "_</th>\n";
+        int int_number_of_strings = num_chunks_translated.getint() + num_chunks_requiring_translation.getint();
+        number_of_strings_temp += "<td class=\"status\"><b>";
+        number_of_strings_temp.appendint(int_number_of_strings);
+        number_of_strings_temp += "</b></td>\n";
+      }
+    	++translation_file;
+    }    
+    
+    if(first_lang) {     
+     gti_status_table += files_temp + "</tr>" + number_of_strings_temp + "</tr>";   
+     first_lang = false;
+    }
+    
+    gti_status_table += lang_status_temp + "</tr>";    
+    ++gti_language;
+  }
+  gti_status_table += "\n</table>";
+  disp.setmacro("gtistatustable", "gti", gti_status_table);
+}
+
+
+
+void gtiaction::define_gti_find_page(displayclass& disp, cgiargsclass& args, ostream& logout)
+{
+  // Get the target language code and file to translate from the CGI arguments
+  text_t target_language_code = args["tlc"];
+  text_t translation_file_key = args["tfk"];
+  text_t query_string = to_utf8(args["q"]);
+
+  // Process user corrections
+  if (args["sp"] != "") {
+    process_gti_submissions(disp, args, logout, false);
+  }
+
+  disp.setmacro("gtiformcontent", "gti", "_gti:gtifind_");
+
+  languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
+  disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
+  disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_");
+
+  if (query_string == "") {
+    // No query, so no search results
+    disp.setmacro("gtifindformcontent", "gti", "");
+    return;
+  }
+
+  // Display text right to left if target language is Arabic or Farsi or Urdu
+  if (target_language_code == "ar" || target_language_code == "fa" || target_language_code == "ur") {
+    disp.setmacro("gtitextdirection", "gti", "rtl");
+  }
+  else {
+    disp.setmacro("gtitextdirection", "gti", "ltr");
+  }
+
+  // Send a request to gti.pl to get the valid translation files
+  logout << "Query argument: " << query_string << endl;
+  text_t gti_arguments = "search-chunks " + target_language_code + " " + translation_file_key + " " + query_string;
+  GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout);
+  if (gti_response.error_message != "") {
+    // An error has occurred
+    disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_");
+    disp.setmacro("gtierrormessage", "gti", gti_response.error_message);
+    return;
+  }
+
+  disp.setmacro("gtinumchunksmatchingquery", "gti", gti_response.num_chunks_matching_query);
+
+  // Loop through the chunks returned, displaying them on the page
+  text_t gti_find_form_content = "_gtifindformheader_\n";
+  text_tmap::iterator chunk_key_iterator = gti_response.target_file_chunks_key_to_text_mapping.begin();
+  while (chunk_key_iterator != gti_response.target_file_chunks_key_to_text_mapping.end()) {
+    text_t chunk_key = chunk_key_iterator->first;
+
+    // Need to escape any underscores in the chunk key to show it correctly on the page
+    text_t chunk_key_escaped = escape_all(chunk_key, '_');
+
+    // Need to escape any backslashes, underscores, commas, parentheses, and single quotes in the chunk text
+    text_t target_file_chunk_text = gti_response.target_file_chunks_key_to_text_mapping[chunk_key];
+    text_t target_file_chunk_text_escaped = escape_all(target_file_chunk_text, '\\');
+    target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '_');
+    target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ',');
+    target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '(');
+    target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ')');
+    target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '"');
+    target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '\'');
+
+    // This chunk matches the query
+    gti_find_form_content += "_gtichunkmatchingquery_(" + chunk_key_escaped + "," + target_file_chunk_text_escaped + ")\n";
+
+    chunk_key_iterator++;
+  }
+  gti_find_form_content += "_gtifindformfooter_\n";
+
+  disp.setmacro("gtifindformcontent", "gti", gti_find_form_content);
+}
+
+
+
+void gtiaction::define_gti_offline_page(displayclass& disp, cgiargsclass& args, ostream& logout)
+{
+  // Get the target language code and file to translate from the CGI arguments
+  text_t target_language_code = args["tlc"];
+  text_t translation_file_key = args["tfk"];
+
+  disp.setmacro("gtiformcontent", "gti", "_gti:gtioffline_");
+
+  languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
+  disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
+  disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_");
+}
+
+
+
+void gtiaction::define_gti_core_page(displayclass& disp, cgiargsclass& args, ostream& logout)
+{
+  // Get the target language code and file to translate from the CGI arguments
+  text_t target_language_code = args["tlc"];
+  text_t translation_file_key = args["tfk"];
+  text_t num_chunks_per_page = args["ncpp"];
+  logout << "Num chunks per page: " << num_chunks_per_page << endl;
+
+  disp.setmacro("gtiformcontent", "gti", "_gti:gticore_");
+
+  // Display text right to left if target language is Arabic or Farsi or Urdu
+  if (target_language_code == "ar" || target_language_code == "fa" || target_language_code == "ur") {
+    disp.setmacro("gtitextdirection", "gti", "rtl");
+  }
+  else {
+    disp.setmacro("gtitextdirection", "gti", "ltr");
+  }
+
+  // Send a request to gti.pl to get the first string to translate
+  text_t gti_arguments = "get-first-n-chunks-requiring-work " + target_language_code + " " + translation_file_key + " " + num_chunks_per_page;
+  GTI_Response gti_response = parse_gti_response(do_gti_request(gti_arguments, logout), logout);
+  if (gti_response.error_message != "") {
+    // An error has occurred
+    disp.setmacro("gtiformcontent", "gti", "_gti:gtierror_");
+    disp.setmacro("gtierrormessage", "gti", gti_response.error_message);
+    return;
+  }
+
+  languageinfo_tmap loaded_languages = recpt->get_configinfo().languages;
+  disp.setmacro("gtitargetlanguagename", "gti", loaded_languages[target_language_code].longname);
+  if (translation_file_key == "glihelp") {
+    disp.setmacro("gtitargetfilepath", "gti", "_gtidownloadglihelp_");
+  } else {
+    disp.setmacro("gtitargetfilepath", "gti", gti_response.translation_files_key_to_target_file_path_mapping[translation_file_key]);
+  }
+  disp.setmacro("gtitranslationfiledesc", "gti", "_gti:textgti" + translation_file_key + "_");
+  disp.setmacro("gtiviewtranslationfileinaction", "gti", "_gti:gtiview" + translation_file_key + "inaction_");
+
+  disp.setmacro("gtinumchunkstranslated", "gti", gti_response.translation_files_key_to_num_chunks_translated_mapping[translation_file_key]);
+  disp.setmacro("gtinumchunksrequiringtranslation", "gti", gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key]);
+  disp.setmacro("gtinumchunksrequiringupdating", "gti", gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key]);
+
+  // Check if the translation file is finished
+  if (gti_response.translation_files_key_to_num_chunks_requiring_translation_mapping[translation_file_key] == "0" && gti_response.translation_files_key_to_num_chunks_requiring_updating_mapping[translation_file_key] == "0") {
+    disp.setmacro("gtiformcontent", "gti", "_gti:gtidone_");
+    return;
+  }
+
+  // Loop through the chunks returned, displaying them on the page
+  text_t gti_core_form_content = "";
+  text_tmap::iterator chunk_key_iterator = gti_response.source_file_chunks_key_to_text_mapping.begin();
+  while (chunk_key_iterator != gti_response.source_file_chunks_key_to_text_mapping.end()) {
+    text_t chunk_key = chunk_key_iterator->first;
+
+    // Need to escape any underscores in the chunk key to show it correctly on the page
+    text_t chunk_key_escaped = escape_all(chunk_key, '_');
+
+    // Need to escape any backslashes, underscores, commas, parentheses, and single quotes in the chunk text
+    text_t source_file_chunk_text = gti_response.source_file_chunks_key_to_text_mapping[chunk_key];
+    text_t source_file_chunk_text_escaped = escape_all(source_file_chunk_text, '\\');
+    source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '_');
+    source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, ',');
+    source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '(');
+    source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, ')');
+    source_file_chunk_text_escaped = escape_all(source_file_chunk_text_escaped, '\'');
+    text_t target_file_chunk_text = gti_response.target_file_chunks_key_to_text_mapping[chunk_key];
+    text_t target_file_chunk_text_escaped = escape_all(target_file_chunk_text, '\\');
+    target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '_');
+    target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ',');
+    target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '(');
+    target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, ')');
+    target_file_chunk_text_escaped = escape_all(target_file_chunk_text_escaped, '\'');
+
+    text_t source_file_chunk_date = gti_response.source_file_chunks_key_to_date_mapping[chunk_key];
+    text_t target_file_chunk_date = gti_response.target_file_chunks_key_to_date_mapping[chunk_key];
+
+    // This chunk requires translation
+    if (target_file_chunk_text == "") {
+      gti_core_form_content += "_gtichunkrequiringtranslation_(" + chunk_key_escaped + "," + source_file_chunk_text_escaped + "," + source_file_chunk_date + ")\n";
+    }
+    // This chunk requires updating
+    else {
+      gti_core_form_content += "_gtichunkrequiringupdating_(" + chunk_key_escaped + "," + source_file_chunk_text_escaped + "," + source_file_chunk_date + "," + target_file_chunk_text_escaped + "," + target_file_chunk_date + ")\n";
+    }
+
+    chunk_key_iterator++;
+  }
+
+  disp.setmacro("gticoreformcontent", "gti", gti_core_form_content);
+}
+
+
+
+void gtiaction::process_gti_submissions(displayclass& disp, cgiargsclass& args, ostream& logout, bool force_submission)
+{
+  // Get the target language code and file to translate from the CGI arguments
+  text_t target_language_code = args["tlc"];
+  text_t translation_file_key = args["tfk"];
+  text_t submitter_username = args["un"];
+
+  // Submitted chunk arguments contain the language code followed by "::"
+  char* source_chunk_key_start_cstr = ((text_t) "en" + "%3A%3A").getcstr();
+  char* target_chunk_key_start_cstr = (target_language_code + "%3A%3A").getcstr();
+
+  // Find the cgi arguments with submitted chunk information
+  text_t submission_text;
+  cgiargsclass::const_iterator cgi_argument = args.begin();
+  while (cgi_argument != args.end()) {
+    char* cgi_argument_name_cstr = cgi_argument->first.getcstr();
+
+    // Source file text
+    if (strncmp(cgi_argument_name_cstr, source_chunk_key_start_cstr, strlen(source_chunk_key_start_cstr)) == 0) {
+      submission_text += "<SourceFileText key=\"";
+      text_t source_key = &cgi_argument_name_cstr[strlen(source_chunk_key_start_cstr)];
+      decode_cgi_arg(source_key);
+      submission_text += source_key;
+      //submission_text += &cgi_argument_name_cstr[strlen(source_chunk_key_start_cstr)];
+      submission_text += "\">\n";
+
+      text_t source_value = xml_safe(decode_commas(args[cgi_argument->first]));
+      // if (args["w"] != "utf-8") {
+      // source_value = to_utf8(source_value);
+      // }
+      submission_text += source_value + "\n";
+      submission_text += "</SourceFileText>\n";
+    }
+    // Target file text
+    if (strncmp(cgi_argument_name_cstr, target_chunk_key_start_cstr, strlen(target_chunk_key_start_cstr)) == 0) {
+      submission_text += "<TargetFileText key=\"";
+      text_t target_key = &cgi_argument_name_cstr[strlen(target_chunk_key_start_cstr)];
+      decode_cgi_arg(target_key);
+      submission_text += target_key;
+      //submission_text += &cgi_argument_name_cstr[strlen(target_chunk_key_start_cstr)];
+      submission_text += "\">\n";
+
+      text_t target_value = xml_safe(decode_commas(args[cgi_argument->first]));
+      // if (args["w"] != "utf-8") {
+      // target_value = to_utf8(target_value);
+      // }
+      submission_text += target_value + "\n";
+      submission_text += "</TargetFileText>\n";
+    }
+
+    delete[] cgi_argument_name_cstr;
+    ++cgi_argument;
+  }
+
+  logout << "Submission text: " << submission_text << endl;
+
+  // Send the submission to gti.pl
+  text_t gti_arguments = "submit-translations " + target_language_code + " " + translation_file_key + " " + submitter_username;
+  if (force_submission) {
+    gti_arguments += " -force_submission";
+  }
+  do_gti_submission(gti_arguments, submission_text, logout);
+  logout << "Done." << endl;
+
+  delete[] source_chunk_key_start_cstr;
+  delete[] target_chunk_key_start_cstr;
+}
+
+
+
+bool gtiaction::produce_excel_spreadsheet(cgiargsclass& args, ostream& logout)
+{
+  // Get the target language code and file to translate from the CGI arguments
+  text_t target_language_code = args["tlc"];
+  text_t translation_file_key = args["tfk"];
+  text_t target_chunk_type = args["tct"];
+
+  // Send a request to gti.pl to get the Excel spreadsheet data
+  text_t gti_arguments = "";
+  if (target_chunk_type == "work") {
+    gti_arguments = "get-first-n-chunks-requiring-work " + target_language_code + " " + translation_file_key + " " + "10000" + " | /opt/jdk1.6.0/bin/java -cp /home/nzdl/gti:/home/nzdl/gti/xalan.jar ApplyXSLT /home/nzdl/gti/gti-generate-excel-xml.xsl -";
+  } else {
+    gti_arguments = "get-all-chunks " + target_language_code + " " + translation_file_key + " | /opt/jdk1.6.0/bin/java -cp /home/nzdl/gti:/home/nzdl/gti/xalan.jar ApplyXSLT /home/nzdl/gti/gti-generate-excel-xml.xsl -";
+  }
+  
+  text_t gti_response_xml_text = do_gti_request(gti_arguments, logout);  
+  if (gti_response_xml_text == "") {
+    // An error has occurred
+    return false;
+  }
+
+  // Write the Excel spreadsheet data to the browser
+  char* gti_response_xml_text_cstr = gti_response_xml_text.getcstr();
+  printf(gti_response_xml_text_cstr);
+  delete[] gti_response_xml_text_cstr;
+
+  return true;
+}
+
+bool gtiaction::produce_glihelp_zipfile(displayclass& disp, cgiargsclass& args, ostream& logout)
+{
+ text_t target_language_code = args["tlc"];
+ text_t gti_arguments = "create-glihelp-zip-file " + target_language_code;
+
+ do_gti_request(gti_arguments, logout); 
+
+ disp.setmacro("gtiglihelpzipfilepath", "gti", target_language_code + "_GLIHelp.zip");
+
+ return true;
+}
+
+
+text_t gtiaction::escape_all(text_t text_string, char character_to_escape)
+{
+  text_t text_string_escaped = "";
+
+  text_t::iterator text_string_character = text_string.begin();
+  while (text_string_character != text_string.end()) {
+    if (*text_string_character == character_to_escape) {
+      text_string_escaped += "\\";
+    }
+    text_string_escaped.push_back(*text_string_character);
+    text_string_character++;
+  }
+
+  return text_string_escaped;
+}
+
+
+
+char* xml_get_attribute(const char** attributes, char* attribute_name)
+{
+  for (int i = 0; (attributes[i] != NULL); i += 2) {
+    if (strcmp(attribute_name, attributes[i]) == 0) {
+      return strdup(attributes[i+1]);
+    }
+  }
+
+  return NULL;
+}
+
+
+static void XMLCALL gti_response_xml_start_element(void* user_data, const char* element_name_cstr, const char** attributes)
+{
+  GTI_Response* gti_response = (GTI_Response*) user_data;
+  text_t element_name = element_name_cstr;
+  cerr << "In startElement() for " << element_name << endl;
+
+  if (element_name == "GTIError") {
+    gti_response->recorded_text = "";
+    gti_response->is_recording_text = true;
+  }
+
+  if (element_name == "TranslationFile") {
+    int translation_file_index = gti_response->translation_files_index_to_key_mapping.size();
+    gti_response->translation_file_key = xml_get_attribute(attributes, "key");
+    gti_response->translation_files_index_to_key_mapping[translation_file_index] = gti_response->translation_file_key;
+    gti_response->translation_files_key_to_target_file_path_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "target_file_path");
+    gti_response->translation_files_key_to_num_chunks_translated_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_translated");
+    gti_response->translation_files_key_to_num_chunks_requiring_translation_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_requiring_translation");
+    gti_response->translation_files_key_to_num_chunks_requiring_updating_mapping[gti_response->translation_file_key] = xml_get_attribute(attributes, "num_chunks_requiring_updating");
+  }
+
+  if (element_name == "ChunksMatchingQuery") {
+    gti_response->num_chunks_matching_query = xml_get_attribute(attributes, "size");
+  }
+
+  if (element_name == "Chunk") {
+    gti_response->chunk_key = xml_get_attribute(attributes, "key");
+  }
+
+  if (element_name == "SourceFileText") {
+    gti_response->source_file_chunks_key_to_date_mapping[gti_response->chunk_key] = xml_get_attribute(attributes, "date");
+    gti_response->recorded_text = "";
+    gti_response->is_recording_text = true;
+  }
+
+  if (element_name == "TargetFileText") {
+    if (xml_get_attribute(attributes, "date") != NULL) {
+      gti_response->target_file_chunks_key_to_date_mapping[gti_response->chunk_key] = xml_get_attribute(attributes, "date");
+    }
+    gti_response->recorded_text = "";
+    gti_response->is_recording_text = true;
+  }
+}
+
+
+static void XMLCALL gti_response_xml_end_element(void* user_data, const char* element_name_cstr)
+{
+  GTI_Response* gti_response = (GTI_Response*) user_data;
+  text_t element_name = element_name_cstr;
+
+  if (element_name == "GTIError") {
+    gti_response->error_message = to_uni(gti_response->recorded_text);
+    gti_response->is_recording_text = false;
+  }
+
+  if (element_name == "SourceFileText") {
+    gti_response->source_file_chunks_key_to_text_mapping[gti_response->chunk_key] = to_uni(gti_response->recorded_text);
+    gti_response->is_recording_text = false;
+  }
+
+  if (element_name == "TargetFileText") {
+    gti_response->target_file_chunks_key_to_text_mapping[gti_response->chunk_key] = to_uni(gti_response->recorded_text);
+    gti_response->is_recording_text = false;
+  }
+}
+
+
+static void XMLCALL gti_response_xml_character_data(void *user_data, const char* text_cstr, int text_length)
+{
+  GTI_Response* gti_response = (GTI_Response*) user_data;
+  if (gti_response->is_recording_text) {
+    gti_response->recorded_text.appendcarr(text_cstr, text_length);
+  }
+}
+
+
+
+text_t gtiaction::do_gti_request(text_t gti_arguments, ostream& logout)
+{
+  // Send the request to gti.pl and read the XML output
+  text_t gti_command = "perl -S " + filename_cat(gsdlhome, "bin", "script", "gti.pl") + " " + gti_arguments;
+  char* gti_command_cstr = gti_command.getcstr();
+  FILE *gti_pipe = popen(gti_command_cstr, "r");
+  delete[] gti_command_cstr;
+  if (gti_pipe == NULL) {
+    logout << "Error: Could not open pipe for GTI command " << gti_command << endl;
+    return "";
+  }
+
+  // Read the gti.pl response
+  text_t gti_response_xml_text;
+  while (!feof(gti_pipe)) {
+    char buffer[1024];
+    gti_response_xml_text.appendcarr(buffer, fread(buffer, 1, 1024, gti_pipe));
+  }
+  pclose(gti_pipe);
+
+  return gti_response_xml_text;
+}
+
+
+
+GTI_Response gtiaction::parse_gti_response(text_t gti_response_xml_text, ostream& logout)
+{
+  GTI_Response gti_response;
+  gti_response.is_recording_text = false;
+
+  // Parse the gti.pl response (XML)
+  logout << "Parsing GTI command response: " << gti_response_xml_text << endl;
+  XML_Parser xml_parser = XML_ParserCreate(NULL);
+  XML_SetUserData(xml_parser, &gti_response);
+  XML_SetElementHandler(xml_parser, gti_response_xml_start_element, gti_response_xml_end_element);
+  XML_SetCharacterDataHandler(xml_parser, gti_response_xml_character_data);
+
+  char* gti_response_xml_text_cstr = gti_response_xml_text.getcstr();
+  int parse_status = XML_Parse(xml_parser, gti_response_xml_text_cstr, strlen(gti_response_xml_text_cstr), XML_TRUE);
+  delete[] gti_response_xml_text_cstr;
+  if (parse_status == XML_STATUS_ERROR) {
+    logout << "Parse error " << XML_ErrorString(XML_GetErrorCode(xml_parser)) << " at line " << XML_GetCurrentLineNumber(xml_parser) << endl;
+    return gti_response;
+  }
+
+  XML_ParserFree(xml_parser);
+
+  logout << "Finished parse." << endl;
+  return gti_response;
+}
+
+
+
+void gtiaction::do_gti_submission(text_t gti_arguments, text_t gti_submission, ostream& logout)
+{
+  // Send the submission to gti.pl
+  text_t gti_command = "perl -S " + filename_cat(gsdlhome, "bin", "script", "gti.pl") + " " + gti_arguments;
+  char* gti_command_cstr = gti_command.getcstr();
+  FILE *gti_pipe = popen(gti_command_cstr, "w");
+  delete[] gti_command_cstr;
+  if (gti_pipe == NULL) {
+    logout << "Error: Could not open pipe for GTI command " << gti_command << endl;
+    return;
+  }
+
+  // Write the gti.pl submission
+  char* gti_submission_cstr = gti_submission.getcstr();
+  fwrite(gti_submission_cstr, 1, strlen(gti_submission_cstr), gti_pipe);
+  delete[] gti_submission_cstr;
+
+  pclose(gti_pipe);
+}
+
+
+
+#endif  // GSDL_USE_GTI_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/gtiaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/gtiaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/gtiaction.h	(revision 20131)
@@ -0,0 +1,125 @@
+/**********************************************************************
+ *
+ * gtiaction.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef GTIACTION_H
+#define GTIACTION_H
+
+
+#include "action.h"
+#include "receptionist.h"
+
+
+
+struct GTI_Response
+{
+  text_t translation_file_key;
+  text_tmap translation_files_index_to_key_mapping;
+  text_tmap translation_files_key_to_num_chunks_translated_mapping;
+  text_tmap translation_files_key_to_num_chunks_requiring_translation_mapping;
+  text_tmap translation_files_key_to_num_chunks_requiring_updating_mapping;
+  text_tmap translation_files_key_to_target_file_path_mapping;
+
+  text_t chunk_key;
+  text_tmap source_file_chunks_key_to_text_mapping;
+  text_tmap source_file_chunks_key_to_date_mapping;
+
+  // For chunks requiring updating
+  text_tmap target_file_chunks_key_to_text_mapping;
+  text_tmap target_file_chunks_key_to_date_mapping;
+
+  text_t num_chunks_matching_query;
+
+  bool is_recording_text;
+  text_t recorded_text;
+
+  text_t error_message;
+};
+
+
+class gtiaction : public action {
+
+protected:
+  receptionist *recpt;
+
+  char* set_gsdlhome_cstr;
+  char* set_gsdlos_cstr;
+
+public:
+  gtiaction ();
+  virtual ~gtiaction ();
+
+  void set_receptionist (receptionist *therecpt) {recpt=therecpt;}
+
+  text_t get_action_name () {return "gti";}
+
+  bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+		      recptprotolistclass *protos, ostream &logout);
+
+  void define_internal_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response,text_t &response_data, 
+			 ostream &logout);
+
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+
+  bool init (ostream & /*logout*/);
+
+
+  // The interesting functions
+  void define_gti_home_page(displayclass& disp, cgiargsclass& args, ostream& logout);
+
+  void define_gti_lang_page(displayclass& disp, cgiargsclass& args, ostream& logout);
+
+  void define_gti_find_page(displayclass& disp, cgiargsclass& args, ostream& logout);
+
+  void define_gti_offline_page(displayclass& disp, cgiargsclass& args, ostream& logout);
+
+  void define_gti_core_page(displayclass& disp, cgiargsclass& args, ostream& logout);
+
+  text_t escape_all(text_t source_string, char character_to_escape);
+
+  void process_gti_submissions(displayclass& disp, cgiargsclass& args, ostream& logout, bool force_submission);
+
+  text_t do_gti_request(text_t gti_arguments, ostream& logout);
+
+  GTI_Response parse_gti_response(text_t gti_response_xml_text, ostream& logout);
+
+  void do_gti_submission(text_t gti_arguments, text_t gti_submission, ostream& logout);
+
+  void define_gti_status_page(displayclass& disp, cgiargsclass& args, ostream& logout);
+
+  bool produce_excel_spreadsheet(cgiargsclass& args, ostream& logout);
+
+  bool produce_glihelp_zipfile(displayclass& disp, cgiargsclass& args, ostream& logout);
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/highlighttext.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/highlighttext.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/highlighttext.cpp	(revision 20131)
@@ -0,0 +1,288 @@
+/**********************************************************************
+ *
+ * highlighttext.cpp -- 
+ * Copyright (C) 2002   D L Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "highlighttext.h"
+#include "unitool.h"
+
+
+static void highlight_terms(const text_t &text, const TermInfo_tarray &terms, const text_t &shl,
+			    const text_t &ehl, displayclass &disp, outconvertclass &outconvert,
+			    ostream &textout);
+
+static void highlight_phrases(const text_t &text, const text_t &querystring, const TermInfo_tarray &terms, 
+			      const text_t &shl, const text_t &ehl, displayclass &disp, 
+			      outconvertclass &outconvert, ostream &textout);
+
+static void get_phrase_terms (const text_t &querystring, text_tarray &phrase_terms);
+
+static void remove_space (text_t &qstring);
+
+// highlights text string by adding _starthighlight_ and _endhightlight_
+// around terms and/or phrases that match querystring 
+
+// - at present this only handles phrase searches where the first and last
+// characters are double quotes (i.e. it won't correctly handle a mixture
+// of phrase and non-phrase terms or queries containing multiple phrases) -
+// it also doesn't highlight stemmed variations of terms within a phrase
+// because the terminfo returned by mgqueryfilter doesn't currently tell
+// you which term variants belong to which term
+
+// - this function can be forced to treat the querystring like a phrase
+// even if it isn't one by setting the "hl" cgi argument to "2"
+void highlighttext(const text_t &text, cgiargsclass &args, const TermInfo_tarray &terms, 
+		   displayclass &disp, outconvertclass &outconvert, ostream &textout) {
+
+
+  text_t &querystring = args["q"];
+
+  // get the text to start and end a hightlight
+  text_t shl = "<b><u>";
+  text_t ehl = "</u></b>";
+  if (disp.isdefaultmacro(displayclass::defaultpackage, "starthighlight")) {
+    disp.expandstring(displayclass::defaultpackage, "_starthighlight_", shl);
+  }
+  if (disp.isdefaultmacro(displayclass::defaultpackage, "endhighlight")) {
+    disp.expandstring(displayclass::defaultpackage, "_endhighlight_", ehl);
+  }
+
+  // remove leading and trailing whitespace
+  remove_space(querystring);
+
+  // Expand macros before highlighting -- by Jens Wille
+  text_t text_expanded = "";
+  disp.expandstring(text, text_expanded);
+
+  if ((args["hl"] == 2) || ((*(querystring.begin()) == '"') && (*(querystring.end()-1) == '"'))) {
+    highlight_phrases(text_expanded, querystring, terms, shl, ehl, disp, outconvert, textout);
+  } else {
+    highlight_terms(text_expanded, terms, shl, ehl, disp, outconvert, textout);
+  }
+}
+
+void highlight_terms(const text_t &text, const TermInfo_tarray &terms, const text_t &shl,
+		     const text_t &ehl, displayclass &disp, outconvertclass &outconvert,
+		     ostream &textout) {
+
+  text_tmap allterms;
+  text_tmap::const_iterator it;
+
+  // first load all the term variations into a map
+  TermInfo_tarray::const_iterator this_term = terms.begin();
+  TermInfo_tarray::const_iterator last_term = terms.end();
+  while (this_term != last_term) {
+    text_tarray::const_iterator this_var = (*this_term).matchTerms.begin();
+    text_tarray::const_iterator last_var = (*this_term).matchTerms.end();
+    while (this_var != last_var) {
+      allterms[*this_var] = 1;
+      ++this_var;
+    }
+    ++this_term;
+  }
+
+  text_t::const_iterator here = text.begin();
+  text_t::const_iterator end = text.end();
+
+  text_t word, buffer;
+  while (here != end) {
+    if (is_unicode_letdig(*here)) {
+      // not word boundary
+      word.push_back(*here);
+      ++here;
+
+    } else {
+      // found word boundary
+      // add last word if there was one
+      if (!word.empty()) {
+	it = allterms.find(word);
+	if (it != allterms.end()) {
+	  word = shl + word + ehl;
+	}
+	buffer += word;
+        word.clear();
+      }
+
+      if (*here == '<') {
+        // skip over rest of html tag
+	while ((here != end) && (*here != '>')) {
+	  buffer.push_back(*here);
+	  ++here;
+	}
+      }
+
+      buffer.push_back(*here);
+      ++here;
+
+      if (buffer.size() > 1024) {
+	textout << outconvert << disp << buffer;
+	buffer.clear();
+      }
+    }
+  }
+  textout << outconvert << disp << buffer;
+}
+
+void highlight_phrases(const text_t &text, const text_t &querystring, const TermInfo_tarray &terms, 
+		       const text_t &shl, const text_t &ehl, displayclass &disp, 
+		       outconvertclass &outconvert, ostream &textout) {
+
+  text_tmap allterms;
+  text_tarray phrase_terms;
+  text_tmap::const_iterator it;
+
+  get_phrase_terms(querystring, phrase_terms);
+  int phraselen = phrase_terms.size();
+
+  TermInfo_tarray::const_iterator this_term = terms.begin();
+  TermInfo_tarray::const_iterator last_term = terms.end();
+  bool first = true;
+  while (this_term != last_term) {
+    text_tarray::const_iterator this_var = (*this_term).matchTerms.begin();
+    text_tarray::const_iterator last_var = (*this_term).matchTerms.end();
+    while (this_var != last_var) {
+      allterms[*this_var] = 1;
+      ++this_var;
+    }
+    first = false;
+    ++this_term;
+  }
+
+  text_t::const_iterator here = text.begin();
+  text_t::const_iterator end = text.end();
+
+  text_t word, buffer;
+  int phrasecount = 0;
+  while (here != end) {
+    if (is_unicode_letdig(*here)) {
+      // not word boundary
+      word.push_back(*here);
+      ++here;
+
+    } else {
+      // found word boundary
+      // add last word if there was one
+      if (!word.empty()) {
+	it = allterms.find(word);
+	if (it != allterms.end()) {
+	  // found a word that matches somewhere in the phrase
+
+	  text_t lcword = word; lc(lcword);
+	  if (lcword == phrase_terms[phrasecount]) {
+
+	    if (phrasecount == 0) {
+	      // clear the buffer (from here on buffer will contain the phrase
+	      // as it's built up)
+	      textout << outconvert << disp << buffer;
+	      buffer.clear();
+	    }
+	    ++phrasecount;
+	  } else {
+	    phrasecount = 0;
+	  }
+	} else {
+	  phrasecount = 0;
+	}
+	buffer += word;
+        word.clear();
+	
+	if (phrasecount == phraselen) {
+	  // have found entire phrase
+	  textout << outconvert << disp << shl << buffer << ehl;
+	  buffer.clear();
+	  phrasecount = 0;
+	}
+      }
+
+      if (*here == '<') {
+        // skip over rest of html tag
+	while ((here != end) && (*here != '>')) {
+	  buffer.push_back(*here);
+	  ++here;
+	}
+      }
+
+      buffer.push_back(*here);
+      ++here;
+
+      if (buffer.size() > 1024 && phrasecount == 0) {
+	textout << outconvert << disp << buffer;
+	buffer.clear();
+      }
+    }
+  }
+  textout << outconvert << disp << buffer;
+}
+
+void get_phrase_terms (const text_t &querystring, text_tarray &phrase_terms) {
+
+  phrase_terms.erase(phrase_terms.begin(), phrase_terms.end());
+
+  text_t::const_iterator here = querystring.begin();
+  text_t::const_iterator end = querystring.end();
+
+  text_t word;
+  while (here != end) {
+    if (is_unicode_letdig(*here)) {
+      // not word boundary
+      word.push_back(*here);
+
+    } else {
+      // found word boundary
+      if (!word.empty()) {
+	lc(word);
+	phrase_terms.push_back(word);
+	word.clear();
+      }
+    }
+    ++here;
+  }
+
+  if (!word.empty()) {
+    lc(word);
+    phrase_terms.push_back(word);
+  }
+}
+
+void remove_space (text_t &qstring) {
+
+  text_t altered_string;
+  text_t space;
+
+  text_t::const_iterator here = qstring.begin();
+  text_t::const_iterator end = qstring.end();
+  while (here != end) {
+    if (is_unicode_space(*here)) {
+      space.push_back(*here);
+    } else {
+      if (!altered_string.empty()) {
+	altered_string += space;
+      }
+      space.clear();
+      altered_string.push_back(*here);
+    }
+    ++here;
+  }
+
+  qstring = altered_string;
+}
Index: /gsdl/stable/runtime-src/src/recpt/highlighttext.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/highlighttext.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/highlighttext.h	(revision 20131)
@@ -0,0 +1,46 @@
+/**********************************************************************
+ *
+ * highlighttext.h -- 
+ * Copyright (C) 2002   D L Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef HIGHLIGHTTEXT_H
+#define HIGHLIGHTTEXT_H
+
+#include "text_t.h"
+#include "comtypes.h"
+#include "display.h"
+#include "cgiargs.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#else
+#  include <iostream>
+#endif
+
+void highlighttext(const text_t &text, cgiargsclass &args, const TermInfo_tarray &terms, 
+		   displayclass &disp, outconvertclass &outconvert, ostream &textout);
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/historydb.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/historydb.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/historydb.cpp	(revision 20131)
@@ -0,0 +1,302 @@
+/**********************************************************************
+ *
+ * historydb.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "historydb.h"
+#include "fileutil.h"
+#include "cgiutils.h"
+#include "recptproto.h"
+#include "recptprototools.h"
+#include "gdbmclass.h"
+
+#define MAX_RECORDS 20
+#define HIST_SEP ';'
+
+// returns true on success (in which case historyinfo will contain
+// the information for this history)
+bool get_history_info (const text_t &userid, text_tarray &historyinfo, 
+		       const text_t &gsdlhome, ostream &logout) {
+
+  text_t historyfile = filename_cat(gsdlhome, "etc", "history.gdb");
+  
+  bool result = false;
+  // open the history database  
+  gdbmclass historydb;
+  
+  if (historydb.opendatabase(historyfile, DB_READER, 1000, true)) {
+    // get history list
+    text_t historyresult;
+    
+    historydb.getkeydata(userid, historyresult);
+    
+    if (historyresult != "") { //  there are entries, process them
+      
+      splitchar(historyresult.begin(), historyresult.end(), '\n', historyinfo);
+      result = true;
+    }
+    historydb.closedatabase();
+    
+  } else {
+    outconvertclass text_t2ascii;
+    logout << text_t2ascii << "couldn't open history database " << historyfile << "\n";
+  }
+  return result;
+}
+
+
+// returns true on success
+// changed to only save 20 records per user, numbers not included
+// only save if there are already entries there, or if display=true
+bool set_history_info (const text_t &userid, const text_t &history, const text_t &gsdlhome, bool display) {
+
+  text_t historyfile = filename_cat(gsdlhome, "etc", "history.gdb");
+  
+  bool result = false;
+  // open the history database  
+  gdbmclass historydb;
+  
+  text_t oldhistoryresult;
+  text_t newhistoryresult;
+  int numentries=0;
+
+  if (!historydb.opendatabase(historyfile, DB_READER, 1000, true)) {
+    // not created yet
+    oldhistoryresult="";
+    if (!display) return true; // dont need to save
+  }
+  else {
+
+    // get history list
+   if (! historydb.getkeydata(userid, oldhistoryresult)) {
+     oldhistoryresult="";
+     if (!display) return true; // dont need to save
+   }
+   historydb.closedatabase();
+  }
+
+  text_tarray entries;
+  
+  if (oldhistoryresult!="") {
+    splitchar(oldhistoryresult.begin(), oldhistoryresult.end(), '\n', entries);
+    numentries = entries.size();
+    if (numentries >= MAX_RECORDS) numentries = MAX_RECORDS-1;
+  }
+  
+  // open for writing
+  if (!historydb.opendatabase(historyfile, DB_WRITER_CREATE, 1000, true)) return false;
+  
+  // add on new linethe new record to the front of the list, then add the
+  // appropriate entries from the old stuff 
+  newhistoryresult += history;
+  newhistoryresult += "\n";
+  for (int i=0; i<numentries;++i) {
+    newhistoryresult +=  entries[i]+"\n";
+  }
+  
+  if (historydb.setkeydata(userid, newhistoryresult)) 
+    result=true; 
+  
+  historydb.closedatabase();
+  return result;
+}
+
+// deletes all a users history
+bool delete_all_history_info (const text_t &userid, const text_t &gsdlhome) {
+
+  text_t historyfile = filename_cat(gsdlhome, "etc", "history.gdb");
+  
+  // open the history database  
+  gdbmclass historydb;
+  
+  if (!historydb.opendatabase(historyfile, DB_WRITER, 1000, true)) return false;
+
+  historydb.deletekey(userid);
+  historydb.closedatabase();
+  return true;
+  
+}
+
+// retrieves the value of one of the arguments
+void parse_saved_args(text_t &args, text_t key, text_t &value)
+{
+  text_t::iterator here = args.begin();
+  text_t::iterator end = args.end();
+  text_t::iterator it;
+  while (here != end) {
+    if(*here==key[0]) {
+      it=findchar(here, end, '=');
+      if (it==end) {
+	value=""; return;
+      }
+      text_t entry = substr(here, it);
+      if (entry==key) {
+	here=it+1;
+      	it=findchar(here, end, HIST_SEP);
+	value = substr(here, it);
+	return;
+      }
+    }
+    ++here;
+  }// while
+}
+
+// retrieves the value of all of the arguments
+void parse_saved_args(text_t &args, infodbclass &info)
+{
+  text_t::iterator here = args.begin();
+  text_t::iterator end = args.end();
+  text_t::iterator it;
+  text_tarray values;
+
+  splitchar(here, end, HIST_SEP, values);
+  
+  text_tarray::iterator start = values.begin();
+  text_tarray::iterator stop = values.end();
+
+  text_t key;
+  text_t value;
+  while(start!=stop) {
+
+    here=(*start).begin();
+    end=(*start).end();
+    it=findchar(here, end, '=');
+    if (it!=end) {
+      key = substr(here, it);
+      value = substr(it+1, end);
+      
+      info[key]=value;
+    }
+    ++start;
+  }
+}
+
+
+void split_saved_query(text_t &query, text_t &numdocs, text_t &cgiargs)
+{
+  text_t::iterator begin = query.begin();
+  text_t::iterator end = query.end();
+  
+  while (*begin >='0'&& *begin <='9') { // get the digits for numdocs
+    numdocs.push_back(*begin);
+    ++begin;
+  }          
+                 
+  if (*begin == '+') {  // get the + if there
+    numdocs.push_back(*begin);
+    ++begin;
+  }
+  if (*begin == ':') { // have the old format - previous bit was record number
+    numdocs.clear();
+    ++begin;
+
+    while(*begin >='0' && *begin <='9') { // get the digits
+      numdocs.push_back(*begin);
+      ++begin;
+    }
+    if (*begin == '+') { // get the + if there
+      numdocs.push_back(*begin);
+      ++begin;
+    }
+  }
+  cgiargs += (substr(begin, end));  // put rest of query into cgiargs
+
+}
+
+void format_user_info (text_t &historyargs, text_t &userinfo,  
+		       cgiargsclass &args,
+		       recptprotolistclass *protos, ostream &logout) 
+{
+  text_tset metadata;
+  userinfo.clear();
+
+  infodbclass argsinfo;
+  parse_saved_args(historyargs, argsinfo);
+  text_t collect = argsinfo["c"];
+  if (collect=="") {
+    userinfo="";
+    return;
+  }
+ 
+  if (collect != args["c"]) {
+    userinfo += collect+", ";
+  }
+  
+  if (argsinfo["h"] != args["h"]) {
+  
+    recptproto *collectproto = protos->getrecptproto(collect,logout);
+    if (collectproto == NULL) {
+      userinfo="";
+      return;
+    }
+    metadata.insert(argsinfo["h"]);
+    FilterResponse_t response;
+    
+    get_info("collection", collect, args["l"], metadata, false, collectproto, response, logout);
+    text_t index = response.docInfo[0].metadata[argsinfo["h"]].values[0];
+    if (!index.empty()) {
+      userinfo += index+", ";
+    }
+  }
+
+  if (argsinfo["b"] != args["b"] || argsinfo["t"] != args["t"]) {
+    if (argsinfo["b"]=="0") { // simple mode
+      if (argsinfo["t"]=="0") {
+	userinfo += " _texthallwords_, ";
+      }
+      else if (argsinfo["t"]=="1"){
+	userinfo += " _texthsomewords_, ";
+      }
+      
+    } 
+    else if (argsinfo["b"] == "1") { // advanced mode
+      if (argsinfo["t"]=="0") {
+	userinfo += " _texthboolean_, ";
+      }
+      else if (argsinfo["t"]=="1") {
+	userinfo += " _texthranked_, ";
+      }
+    }
+  }
+  
+  if (argsinfo["k"] != "" && argsinfo["k"] != args["k"]) {
+    text_t options;
+    // the text translations are the wrong way round
+    if (argsinfo["k"]=="1") {
+      userinfo += " _texthcaseoff_, ";
+    }
+    else if (argsinfo["k"]=="0") {
+      userinfo += " _texthcaseon_, ";
+    }
+  }
+
+  if (argsinfo["s"] != "" && argsinfo["s"] != args["s"]) {
+    if (argsinfo["s"]=="0") {
+      userinfo += " _texthstemoff_, ";
+    }
+    else if (argsinfo["s"]=="1") {
+      userinfo += " _texthstemon_, ";
+    }
+  }
+
+}
Index: /gsdl/stable/runtime-src/src/recpt/historydb.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/historydb.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/historydb.h	(revision 20131)
@@ -0,0 +1,77 @@
+/**********************************************************************
+ *
+ * historydb.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef HISTORYDB_H
+#define HISTORYDB_H
+
+#include "text_t.h"
+#include "recptproto.h"
+#include "cgiargs.h"
+
+/*
+struct HistRecord {
+  text_t entry;
+  bool save;
+};
+
+struct ltinttext_t
+{
+  bool operator()(const text_t &t1, const text_t &t2) const
+  { return t1.getint() < t2.getint(); }
+};
+
+
+typedef map<text_t, HistRecord, ltinttext_t> HistRecordmap;
+
+*/
+// returns true on success (in which case historyinfo will contain
+// the information for this history)
+bool get_history_info (const text_t &userid, text_tarray &historyinfo, 
+		       const text_t &gsdlhome, ostream &logout);
+
+// returns true on success
+bool set_history_info (const text_t &userid, const text_t &historyinfo, 
+		       const text_t &gsdlhome, bool display);
+
+// delete all history for one user
+bool delete_all_history_info (const text_t &userid, const text_t &gsdlhome);
+
+// retrieves the value of an arg (key) from a list of cgi args
+// in the form a=q&b=1&...
+void parse_saved_args(text_t &args, text_t key, text_t &value);
+
+// extracts out the components of an entry in the database
+// currently:
+// numdocs cgiargs
+void split_saved_query(text_t &query,  text_t &numdocs, text_t &cgiargs);
+
+// takes the cgiarg string, and outputs it in some form useful
+// to the user
+void format_user_info (text_t &cgiargs, text_t &info, 
+		       cgiargsclass &args,
+		       recptprotolistclass *protos, ostream &logout);
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/hlistbrowserclass.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/hlistbrowserclass.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/hlistbrowserclass.cpp	(revision 20131)
@@ -0,0 +1,221 @@
+/**********************************************************************
+ *
+ * hlistbrowserclass.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "hlistbrowserclass.h"
+#include "OIDtools.h"
+#include "recptprototools.h"
+#include "cgiutils.h"
+
+
+hlistbrowserclass::hlistbrowserclass () {
+}
+
+hlistbrowserclass::~hlistbrowserclass () {
+}
+
+// returns the name that specifies the browserclass type
+text_t hlistbrowserclass::get_browser_name () {
+  return "HList";
+}
+
+browserclass* hlistbrowserclass::clone()
+{
+  return new hlistbrowserclass();
+}
+
+void hlistbrowserclass::load_metadata_defaults (text_tset &metadata) {
+  metadata.insert ("doctype");
+}
+
+text_t hlistbrowserclass::get_default_formatstring () {
+  return "[link][highlight][Title][/highlight][/link]";
+}
+
+// need to change OID to it's child 
+void hlistbrowserclass::processOID (cgiargsclass &args, recptproto *collectproto,
+				    ostream &logout) {
+
+  text_t OID = args["d"];
+  bool is_classify = false;
+  if (OID.empty()) {
+    is_classify = true;
+    OID = args["cl"];
+  }
+
+  FilterResponse_t response;
+  text_tset metadata;
+  metadata.insert ("childtype");
+  text_t classifytype = "Invisible";
+  text_tarray OIDs;
+
+  while (classifytype == "Invisible" || classifytype == "HList") {
+    OIDs.erase (OIDs.begin(), OIDs.end());
+    
+    OIDs.push_back (OID);
+    OIDs.push_back (OID + ".fc");
+
+    get_info (OIDs, args["c"], args["l"], metadata, false, collectproto, response, logout);
+
+    // Avoid infinite loops in strange situations by checking that the OID has changed
+    if (response.docInfo[1].OID == OID) {
+      break;
+    }
+    OID = response.docInfo[1].OID;
+    classifytype = response.docInfo[1].metadata["childtype"].values[0];
+  }
+  if (is_classify) args["cl"] = OID;
+  else args["d"] = OID;
+}
+
+int hlistbrowserclass::output_section_group (ResultDocInfo_t &section, cgiargsclass &args,
+					     const text_t& collection, int colnumber, 
+					     format_t *formatlistptr, bool use_table, 
+					     text_tset &metadata, bool &getParents, 
+					     recptproto *collectproto, displayclass &disp, 
+					     outconvertclass &outconvert, ostream &textout, 
+					     ostream &logout)
+{
+  // expanded contents are going to cause some nasty recursions
+  // so we'll only continue if being passed the current section
+  if ((args["gc"] == 1) && (section.OID != args["d"])) return 0;
+
+  // get all siblings
+  FilterResponse_t response;
+  get_children (section.OID + ".pr", args["c"], args["l"], metadata, getParents, 
+		collectproto, response, logout);
+
+  return output_section_group (response, args, collection, colnumber, formatlistptr, use_table, metadata, getParents, collectproto, disp, outconvert, textout, logout);
+}
+
+int hlistbrowserclass::output_section_group (FilterResponse_t &response, cgiargsclass &args,
+					     const text_t &collection, int colnumber, 
+					     format_t * formatlistptr, bool use_table, 
+					     text_tset &metadata, bool &getParents,
+					     recptproto * collectproto, displayclass &disp, 
+					     outconvertclass &outconvert, ostream &textout, 
+					     ostream &logout)
+{
+  /* use_table is set to true if the format string starts with <td> */
+  if (use_table || colnumber > 0) {
+    textout << outconvert << "<table><tr><td>";
+    // get tab size
+    text_t tab; int itab;
+    disp.expandstring (displayclass::defaultpackage, "_tabwidth_", tab);
+    itab = tab.getint();
+    if (colnumber > 0) textout << outconvert << disp 
+			       << "<img alt=\"\" src=\"_httpiconspace_\" width=\"" 
+			       << (itab*colnumber) << "\"/>";
+    textout << outconvert << "</td>\n";
+  }
+
+  if (use_table)
+    textout << outconvert << "<table class=\"h_list\"><tr>\n";
+  else
+    textout << outconvert << "<div class=\"h_list\">\n";
+
+  ResultDocInfo_tarray::iterator tsibling = response.docInfo.begin();
+  ResultDocInfo_tarray::iterator esibling = response.docInfo.end();
+
+  text_t icon, link;
+  
+  while (tsibling != esibling)
+  {
+    get_link_icon (*tsibling, args, link, icon);
+
+    bool highlight = false;
+    if ((*tsibling).OID == args["cl"] || is_child_of ((*tsibling).OID, args["cl"]) ||
+	(*tsibling).OID == args["dcn"] || starts_with (args["dcn"], (*tsibling).OID))
+    {
+      link.clear();
+      highlight = true;
+    }
+
+    text_tmap options;
+    options["link"] = link;
+    options["icon"] = icon;
+    if (highlight) options["highlight"] = "1";
+    else options["highlight"] = "0";
+    
+    text_t fmt_str=get_formatted_string (collection, collectproto,
+					  *tsibling, disp, formatlistptr,
+					  options, logout);
+
+    text_t span_class = "h_item";
+    if (highlight) {
+      // the current option
+      span_class += " h_item_current";
+    }
+      
+    textout << outconvert << "<span class=\""<<span_class<<"\">" << disp << fmt_str << "</span>\n";
+    ++tsibling;
+  }
+
+  if (use_table)
+    textout << outconvert << "</tr></table>\n";
+  else
+    textout << outconvert << "</div>\n";
+
+  if (use_table  || colnumber > 0) textout << outconvert << "</tr></table>\n";
+
+  return 0;
+}
+
+
+void hlistbrowserclass::get_link_icon (ResultDocInfo_t &section, cgiargsclass &args, text_t &link, text_t &icon)
+{
+  link = "<a href=\"_httpdocument_";
+
+  text_t &doctype = section.metadata["doctype"].values[0];
+  if (doctype == "classify")
+  {
+    // Dynamic classifier nodes
+    if (args["a"] == "dc")
+    {
+      // The node label is going into the URL, so make it CGI-safe
+      text_t classifier_node_dcn_cgi_safe = cgi_safe_utf8(section.OID);
+      link = "<a href=\"_gwcgi_?c=" + args["c"] + "&amp;a=dc&amp;dcl=" + args["dcl"] + "&amp;dcn=" + classifier_node_dcn_cgi_safe + "\">";
+    }
+    // Static classifier nodes
+    else
+    {
+      link += "&amp;cl=" + section.OID + "\">";
+    }
+  }
+  else
+  {
+    link += "&amp;cl=" + args["cl"] + "&amp;d=" + section.OID;
+
+    // [modification to allow default document detach settings -- kjdon]
+    if (args["xx"] == "1")
+    {
+      // documents should be detached
+      link += "&amp;x=1\" target=\"_blank\">";
+    }
+    else
+    {
+      link += "\">";
+    }
+  }
+}
Index: /gsdl/stable/runtime-src/src/recpt/hlistbrowserclass.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/hlistbrowserclass.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/hlistbrowserclass.h	(revision 20131)
@@ -0,0 +1,73 @@
+/**********************************************************************
+ *
+ * hlistbrowserclass.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef HLISTBROWSERCLASS_H
+#define HLISTBROWSERCLASS_H
+
+#include "browserclass.h"
+#include "receptionist.h"
+
+class hlistbrowserclass : public browserclass {
+protected:
+
+public:
+  hlistbrowserclass ();
+  virtual ~hlistbrowserclass ();
+
+  void set_receptionist(receptionist *therecpt) {recpt=therecpt;}
+
+  // returns the name that specifies the browserclass type
+  text_t get_browser_name ();
+
+  virtual browserclass* clone();
+
+  virtual void load_metadata_defaults (text_tset &metadata);
+
+  virtual text_t get_default_formatstring ();
+  
+  virtual void processOID (cgiargsclass &args, recptproto *collectproto,
+			   ostream &logout);
+
+  virtual int output_section_group (ResultDocInfo_t &section, cgiargsclass &args,
+				    const text_t &collection, int colnumber, format_t *formatlistptr, 
+				    bool use_table, text_tset &metadata, bool &getParents,
+				    recptproto *collectproto, displayclass &disp, 
+				    outconvertclass &outconvert, ostream &textout, ostream &logout);
+
+  virtual int output_section_group (FilterResponse_t &sections, cgiargsclass &args,
+				    const text_t &collection, int colnumber, format_t *formatlistptr, 
+				    bool use_table, text_tset &metadata, bool &getParents,
+				    recptproto *collectproto, displayclass &disp, 
+				    outconvertclass &outconvert, ostream &textout, ostream &logout);
+
+protected:
+
+  virtual void get_link_icon (ResultDocInfo_t &section, cgiargsclass &args, text_t &link, text_t &icon);
+
+  receptionist *recpt;
+};
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/htmlbrowserclass.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/htmlbrowserclass.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/htmlbrowserclass.cpp	(revision 20131)
@@ -0,0 +1,73 @@
+/**********************************************************************
+ *
+ * htmlbrowserclass.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_HTML_BROWSER
+
+#include "htmlbrowserclass.h"
+#include <assert.h>
+#include "OIDtools.h"
+
+htmlbrowserclass::htmlbrowserclass () {
+}
+
+htmlbrowserclass::~htmlbrowserclass () {
+}
+
+// returns the name that specifies the browserclass type
+text_t htmlbrowserclass::get_browser_name () {
+  return "HTML";
+}
+
+browserclass* htmlbrowserclass::clone()
+{
+  return new htmlbrowserclass();
+}
+
+// redirect to html page
+void htmlbrowserclass::processOID (cgiargsclass &args, recptproto *collectproto,
+				   ostream &logout) {
+
+  // should only reach here from within a classification
+  if (!args["d"].empty()) return;
+  if (args["cl"].empty()) return;
+
+  FilterRequest_t request;
+  FilterResponse_t response;
+  comerror_t err;
+  request.filterName = "NullFilter";
+  request.filterResultOptions = FROID;
+  request.docSet.push_back (args["cl"] + ".fc");
+  collectproto->filter (args["c"], request, response, err, logout);
+
+  if (err != noError || response.docInfo[0].OID.empty()) return;
+
+  // redirect to html page
+  args["a"] = "p";
+  args["p"] = "html";
+  args["hp"] = response.docInfo[0].OID;
+}
+
+#endif //GSDL_USE_HTML_BROWSER
Index: /gsdl/stable/runtime-src/src/recpt/htmlbrowserclass.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/htmlbrowserclass.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/htmlbrowserclass.h	(revision 20131)
@@ -0,0 +1,52 @@
+/**********************************************************************
+ *
+ * htmlbrowserclass.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_HTML_BROWSER
+
+#ifndef HTMLBROWSERCLASS_H
+#define HTMLBROWSERCLASS_H
+
+#include "browserclass.h"
+
+class htmlbrowserclass : public browserclass {
+protected:
+
+public:
+
+  htmlbrowserclass ();
+  virtual ~htmlbrowserclass ();
+
+  // returns the name that specifies the browserclass type
+  virtual text_t get_browser_name ();
+
+  void processOID (cgiargsclass &args, recptproto *collectproto,
+		   ostream &logout);
+
+  virtual browserclass* clone();
+};
+
+#endif //!HTMLBROWSERCLASS_H
+#endif //GSDL_USE_HTML_BROWSER
Index: /gsdl/stable/runtime-src/src/recpt/htmlutils.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/htmlutils.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/htmlutils.cpp	(revision 20131)
@@ -0,0 +1,58 @@
+/**********************************************************************
+ *
+ * htmlutils.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "htmlutils.h"
+
+text_t html_safe (const text_t &instring) {
+  
+  text_t outstring;
+  text_t::const_iterator here = instring.begin();
+  text_t::const_iterator end = instring.end();
+  while (here != end) {
+    if (*here == '"') outstring += "&quot;";
+    else if (*here == '&') outstring += "&amp;";
+    else if (*here == '<') outstring += "&lt;";
+    else if (*here == '>') outstring += "&gt;";
+    else if (*here == '#') outstring += "&#35;";
+    else outstring.push_back(*here);
+    ++here;
+  }
+  return outstring;
+}
+
+
+text_t javascript_safe (const text_t &instring) {
+
+  text_t outstring;
+  text_t::const_iterator here = instring.begin();
+  text_t::const_iterator end = instring.end();
+  while (here != end) {
+    if (*here == '"') outstring += "&quot;";
+    else if (*here == '\'') outstring += "\\'";
+    else outstring.push_back(*here);
+    ++here;
+  }
+  return outstring;
+}
Index: /gsdl/stable/runtime-src/src/recpt/htmlutils.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/htmlutils.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/htmlutils.h	(revision 20131)
@@ -0,0 +1,36 @@
+/**********************************************************************
+ *
+ * htmlutils.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef HTMLUTILS_H
+#define HTMLUTILS_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+
+text_t html_safe (const text_t &instring);
+text_t javascript_safe (const text_t &instring);
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/invbrowserclass.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/invbrowserclass.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/invbrowserclass.cpp	(revision 20131)
@@ -0,0 +1,44 @@
+/**********************************************************************
+ *
+ * invbrowserclass.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "invbrowserclass.h"
+#include <assert.h>
+#include "OIDtools.h"
+
+invbrowserclass::invbrowserclass () {
+}
+
+invbrowserclass::~invbrowserclass () {
+}
+
+// returns the name that specifies the browserclass type
+text_t invbrowserclass::get_browser_name () {
+  return "Invisible";
+}
+
+browserclass* invbrowserclass::clone()
+{
+  return new invbrowserclass();
+}
Index: /gsdl/stable/runtime-src/src/recpt/invbrowserclass.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/invbrowserclass.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/invbrowserclass.h	(revision 20131)
@@ -0,0 +1,50 @@
+/**********************************************************************
+ *
+ * invbrowserclass.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef INVBROWSERCLASS_H
+#define INVBROWSERCLASS_H
+
+#include "browserclass.h"
+
+class invbrowserclass : public browserclass {
+protected:
+
+public:
+
+  // this browser class does nothing by default - it should
+  // be overridden for receptionists wanting to display 
+  // 'Invisible' classifications in some way
+
+  invbrowserclass ();
+  virtual ~invbrowserclass ();
+
+  // returns the name that specifies the browserclass type
+  text_t get_browser_name ();
+
+  virtual browserclass* clone();
+};
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/librarymain.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/librarymain.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/librarymain.cpp	(revision 20131)
@@ -0,0 +1,253 @@
+/**********************************************************************
+ *
+ * librarymain.cpp -- 
+ * Copyright (C) 1999  The New Zaland Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#include "receptionist.h"
+#include "cgiwrapper.h"
+#include "fileutil.h"
+#include "nullproto.h"
+// z39.50 stuff - johnmcp
+#if defined(USE_Z3950)
+#include "z3950proto.h"
+#endif
+#include "collectset.h"
+
+#include "action.h"
+#include "authenaction.h"
+#include "browseaction.h"
+#include "collectoraction.h"
+#include "depositoraction.h"
+#include "documentaction.h"
+#include "dynamicclassifieraction.h"
+#include "extlinkaction.h"
+#include "pageaction.h"
+#include "phindaction.h"
+#include "pingaction.h"
+#include "queryaction.h"
+#include "tipaction.h"
+#include "statusaction.h"
+#include "usersaction.h"
+
+#include "browserclass.h"
+#include "vlistbrowserclass.h"
+#include "hlistbrowserclass.h"
+#include "datelistbrowserclass.h"
+#include "invbrowserclass.h"
+#include "pagedbrowserclass.h"
+#include "htmlbrowserclass.h"
+#include "phindbrowserclass.h"
+
+
+int main ()
+{
+  receptionist recpt;
+  nullproto    nproto;
+  collectset  *cservers;
+#if defined(USE_Z3950)
+  z3950proto   zproto;
+#endif
+  text_t       gsdlhome;
+  text_t       collecthome;
+
+  cservers = new collectset(gsdlhome,collecthome);
+
+  // configure the receptionist server list
+  text_tarray collection_list;
+  cservers->getCollectionList(collection_list);
+  text_tarray::iterator collection_iterator = collection_list.begin();
+  while (collection_iterator != collection_list.end())
+  {
+    text_tarray colinfo;
+    colinfo.push_back(*collection_iterator);
+    colinfo.push_back(gsdlhome);
+    colinfo.push_back(collecthome);
+    colinfo.push_back(gsdlhome);
+    recpt.configure("collectinfo", colinfo);
+    collection_iterator++;
+  }
+
+  // set up the null protocol
+  nproto.set_collectset(cservers);
+
+  // add the protocol to the receptionist
+  recpt.add_protocol (&nproto);
+
+  // z39.50 stuff - johnmcp
+#if defined(USE_Z3950)
+  // add the z39.50 server information. Read in the file
+  // etc/packages/z3950/z3950.cfg for list of servers and their databases.
+  text_t z3950cfg = filename_cat (gsdlhome, "etc", "packages", "z3950", "z3950.cfg");
+#ifdef USE_FASTCGI
+  // currently can't use z39.50 if fastcgi used
+#warning  "Disabling z39.50 support as fastcgi is in use"
+  if (0) {
+#else
+  if (file_exists(z3950cfg)) {
+#endif
+    text_t z3950err = filename_cat (gsdlhome, "etc", "packages", "z3950", "z3950log.txt");
+    zproto.read_config_file(z3950cfg,z3950err);
+    // only add this protocol if we have any servers configured.
+    if (zproto.getServerCount()>0)
+      recpt.add_protocol (&zproto);
+  }
+#endif
+
+  // the list of actions. Note: these actions will become invalid
+  // at the end of this function. We will clean them.
+
+#ifdef GSDL_USE_TIP_ACTION
+  recpt.add_action (new tipaction());
+#endif
+
+#ifdef GSDL_USE_STATUS_ACTION
+  statusaction *astatusaction = new statusaction();
+  astatusaction->set_receptionist (&recpt);
+  recpt.add_action (astatusaction);
+#endif
+
+  pageaction *apageaction = new pageaction();
+  apageaction->set_receptionist (&recpt);
+  recpt.add_action (apageaction);
+
+#ifdef GSDL_USE_PING_ACTION
+  recpt.add_action (new pingaction());
+#endif
+
+  queryaction *aqueryaction = new queryaction();
+  aqueryaction->set_receptionist (&recpt);
+  recpt.add_action (aqueryaction);
+		
+  documentaction *adocumentaction = new documentaction();
+  adocumentaction->set_receptionist (&recpt);
+  recpt.add_action (adocumentaction);
+
+  text_t userdbfile = filename_cat(gsdlhome, "etc", "users.gdb");
+  userdbclass *udb = new userdbclass(userdbfile);
+
+  text_t keydbfile = filename_cat(gsdlhome, "etc", "key.gdb");
+  keydbclass *kdb = new keydbclass(keydbfile);
+
+#ifdef GSDL_USE_USERS_ACTION
+  usersaction *ausersaction = new usersaction();
+  ausersaction->set_userdb(udb);
+  recpt.add_action (ausersaction);
+#endif
+
+#ifdef GSDL_USE_EXTLINK_ACTION
+  extlinkaction *aextlinkaction = new extlinkaction();
+  aextlinkaction->set_receptionist(&recpt);
+  recpt.add_action (aextlinkaction);
+#endif
+		
+#ifdef GSDL_USE_AUTHEN_ACTION
+  authenaction *aauthenaction = new authenaction();
+  aauthenaction->set_userdb(udb);
+  aauthenaction->set_keydb(kdb);
+  aauthenaction->set_receptionist(&recpt);
+  recpt.add_action (aauthenaction);
+#endif
+
+#ifdef GSDL_USE_COLLECTOR_ACTION
+  collectoraction *acollectoraction = new collectoraction();
+  acollectoraction->set_receptionist (&recpt);
+  recpt.add_action(acollectoraction);
+#endif
+
+#ifdef GSDL_USE_DEPOSITOR_ACTION
+  depositoraction *adepositoraction = new depositoraction();
+  adepositoraction->set_receptionist (&recpt);
+  recpt.add_action(adepositoraction);
+#endif
+
+#ifdef GSDL_USE_BROWSE_ACTION
+  browseaction *abrowseaction = new browseaction();
+  abrowseaction->set_receptionist (&recpt);
+  recpt.add_action(abrowseaction);
+#endif
+
+#ifdef GSDL_USE_PHIND_ACTION
+  recpt.add_action(new phindaction());
+#endif
+
+#ifdef GSDL_USE_GTI_ACTION
+  gtiaction *agtiaction = new gtiaction();
+  agtiaction->set_receptionist(&recpt);
+  recpt.add_action(agtiaction);
+#endif
+
+  dynamicclassifieraction *adynamicclassifieraction = new dynamicclassifieraction();
+  adynamicclassifieraction->set_receptionist(&recpt);
+  recpt.add_action(adynamicclassifieraction);  
+
+  // list of browsers
+  vlistbrowserclass avlistbrowserclass;
+  avlistbrowserclass.set_receptionist(&recpt);
+  recpt.add_browser (&avlistbrowserclass);
+  recpt.setdefaultbrowser ("VList");
+
+  hlistbrowserclass ahlistbrowserclass;
+  ahlistbrowserclass.set_receptionist(&recpt);
+  recpt.add_browser (&ahlistbrowserclass);
+
+#ifdef GSDL_USE_DATELIST_BROWSER
+  datelistbrowserclass adatelistbrowserclass;
+  recpt.add_browser (&adatelistbrowserclass);
+#endif
+
+  invbrowserclass ainvbrowserclass;
+  recpt.add_browser (&ainvbrowserclass);
+
+#ifdef GSDL_USE_PAGED_BROWSER
+  pagedbrowserclass apagedbrowserclass;
+  recpt.add_browser (&apagedbrowserclass);
+#endif
+
+#ifdef GSDL_USE_HTML_BROWSER
+  htmlbrowserclass ahtmlbrowserclass;
+  recpt.add_browser (&ahtmlbrowserclass);
+#endif
+
+#ifdef GSDL_USE_PHIND_BROWSER
+  phindbrowserclass aphindbrowserclass;
+  recpt.add_browser (&aphindbrowserclass);
+#endif
+
+  cgiwrapper (recpt, "");
+  delete cservers;
+  delete udb;
+  delete kdb;
+
+  // clean up the actions
+  actionmapclass::iterator thisAction = recpt.get_actionmap_ptr()->begin();
+  actionmapclass::iterator endAction = recpt.get_actionmap_ptr()->begin();
+  while (thisAction != endAction) {
+    delete thisAction->second.a; thisAction->second.a = NULL;
+    ++thisAction;
+  }
+  thisAction = recpt.get_actionmap_ptr()->begin();
+  recpt.get_actionmap_ptr()->erase(thisAction, endAction);
+
+  return 0;
+}
Index: /gsdl/stable/runtime-src/src/recpt/maincfg.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/maincfg.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/maincfg.cpp	(revision 20131)
@@ -0,0 +1,98 @@
+/**********************************************************************
+ *
+ * maincfg.cpp -- 
+ * Copyright (C) 2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "maincfg.h"
+#include "fileutil.h"
+
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace/std/iostream>
+#  include <ospace/std/fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#  include <fstream.h>
+#else
+#  include <iostream>
+#  include <fstream>
+#endif
+
+
+bool main_cfg_read (receptionist &recpt, const text_t &gsdlhome,
+		    const text_t &collection) 
+{
+
+  cerr << "Warning: Using version of main_cfg_read() that does not support 'collecthome'" << endl;
+
+  text_t collecthome = filename_cat(gsdlhome,"collect");
+
+  cerr << "Setting collecthome to be " << collecthome << endl;
+
+
+  return main_cfg_read(recpt,gsdlhome,collecthome,collection);
+}
+
+
+// main_cfg_read reads both main.cfg and collect.cfg. It attempts
+// to read main.cfg first so values in collect.cfg override those
+// set earlier by main.cfg
+bool main_cfg_read (receptionist &recpt, const text_t &gsdlhome,
+		    const text_t& collecthome, const text_t &collection) {
+
+  // read in the main configuration file
+  bool rv = false;
+
+  text_t key, filename;
+  text_tarray cfgline;
+  filename = filename_cat (gsdlhome, "etc", "main.cfg");
+  if (!collection.empty() && file_exists(filename)) {
+    rv = recpt.read_configfile(filename);
+  } else {
+    if (file_exists (filename)) {
+      rv = recpt.read_configfile(filename);
+    }
+  }
+
+  // Look for collect.cfg in <collecthome>/collection-name/etc directory 
+  // (if this is for a particular collection), and then GSDLHOME/etc.
+  if (!collection.empty()) {
+    filename = filename_cat (collecthome, collection, "etc", "collect.cfg");
+    if (!file_exists (filename)) {
+      filename = filename_cat (gsdlhome, "etc", "collect.cfg");
+      if (!file_exists (filename)) filename.clear();
+    }
+
+    if (!filename.empty()) {
+      rv |= recpt.read_configfile(filename);
+    }
+
+    // Look for custom.cfg in <collecthome>/collection-name/custom/collection-name/etc too
+    filename = filename_cat (collecthome, collection, "custom", collection, "etc", "custom.cfg");
+    if (file_exists(filename))
+    {
+      rv |= recpt.read_configfile(filename);
+    }
+  }
+  return rv;
+}
Index: /gsdl/stable/runtime-src/src/recpt/maincfg.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/maincfg.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/maincfg.h	(revision 20131)
@@ -0,0 +1,48 @@
+/**********************************************************************
+ *
+ * maincfg.h -- 
+ * Copyright (C) 2008  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef MAINCFG_H
+#define MAINCFG_H
+
+
+#include "text_t.h"
+#include "receptionist.h"
+
+
+// read main.cfg for the actions and httpprefix
+void main_cfg_read (const text_t& collection, const text_t &gsdlhome, text_t &httpprefix, text_tset& actions, text_tset& browsers);
+
+// main_cfg_read reads either collect.cfg or main.cfg and returning 
+// true on success. It attempts to read collect.cfg first if a
+// collection is specified and then it tries to read in main.cfg
+bool main_cfg_read (receptionist &recpt, const text_t &gsdlhome,
+		    const text_t& collecthome, const text_t &collection);
+
+bool main_cfg_read (receptionist &recpt, const text_t &gsdlhome,
+		    const text_t &collection);
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/mod_gsdl.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/mod_gsdl.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/mod_gsdl.cpp	(revision 20131)
@@ -0,0 +1,604 @@
+/**********************************************************************
+ *
+ * mod_gsdl.cpp -- front end for apache 1.3 or 2.x module
+ * Copyright (C) 2003 DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "httpd.h"
+#include "http_core.h"
+#include "http_config.h"
+#include "http_protocol.h"
+#include "http_main.h"
+#include "util_script.h"
+#include "ap_config.h"
+#include "http_log.h"
+
+
+#if _APACHE_MOD >= 2
+
+#include "ap_compat.h"
+
+// In addition to the backward compatible features defined in
+// ap_compat.h, define 
+
+typedef apr_pool_t ap_pool; // map old type to new apr_* version
+
+// In Apache 2.x, ap_log_error takes extra parameter -- status code
+// from the previous command; define macro to automatically add in
+// surrogate value of 0 for this
+#define ap_log_error(file,line,level,server,fmt) \
+	ap_log_error(file,line,level,0,server,fmt)
+
+#endif
+
+#if defined(USE_MYSQL)
+#include "mysqlclass.h"
+#endif
+#if defined(USE_ACCESS)
+#include "accessclass.h"
+#endif
+
+#include "maincfg.h"
+#include "string_pool.h"
+
+#include "receptionist.h"
+#include "cgiwrapper.h"
+#include "cgiutils.h"
+#include "fileutil.h"
+#include "nullproto.h"
+#include "collectserver.h"
+#include "filter.h"
+#include "browsefilter.h"
+#include "mgqueryfilter.h"
+#include "infodbclass.h"
+#include "mgsource.h"
+#include "mgsearch.h"
+#include "collectset.h"
+
+#include "gdbmclass.h"
+
+#include "action.h"
+#include "pageaction.h"
+#include "queryaction.h"
+#include "documentaction.h"
+#include "extlinkaction.h"
+#include "phindaction.h"
+#if defined(USE_MYSQL) || defined(USE_ACCESS)
+#include "orderaction.h"
+#endif
+#include "configaction.h"
+
+#include "browserclass.h"
+#include "vlistbrowserclass.h"
+#include "hlistbrowserclass.h"
+#include "datelistbrowserclass.h"
+#include "invbrowserclass.h"
+#include "pagedbrowserclass.h"
+#include "phindbrowserclass.h"
+
+#include <strstream>
+
+receptionist recpt;
+nullproto nproto;
+
+extern "C" module MODULE_VAR_EXPORT gsdl_module;
+
+typedef struct {
+  char *config_gsdlhome;
+  char *config_collecthome;
+  char *config_httpprefix;
+  char *config_httpweb;
+} gsdl_config;
+
+static void *gsdl_create_config(ap_pool *p, server_rec *s) {
+
+#if _APACHE_MOD >= 2
+  gsdl_config *cfg = (gsdl_config *)apr_pcalloc(p, sizeof(gsdl_config));
+#else
+  gsdl_config *cfg = (gsdl_config *)ap_pcalloc(p, sizeof(gsdl_config));
+#endif
+
+  return (void *)cfg;
+}
+
+static void *gsdl_create_dir_config(ap_pool *p, char *path) {
+
+  return (gsdl_config *) gsdl_create_config(p, NULL);
+}
+
+static const char *gsdl_cmd(cmd_parms *cmd, void *mconfig,
+			    char *val) {
+
+  server_rec *s = cmd->server;
+  gsdl_config *cfg = (gsdl_config *) ap_get_module_config(s->module_config, &gsdl_module);
+
+  if (strcmp(cmd->cmd->name, "gsdlhome") == 0) {
+    cfg->config_gsdlhome = val;
+  } else if (strcmp(cmd->cmd->name, "collecthome") == 0) {
+    cfg->config_collecthome = val;
+  } else if (strcmp(cmd->cmd->name, "httpprefix") == 0) {
+    cfg->config_httpprefix = val;
+  } else if (strcmp(cmd->cmd->name, "httpweb") == 0) {
+    cfg->config_httpweb = val;
+  }
+
+  return NULL;
+}
+
+#if _APACHE_MOD < 2
+static void gsdl_exit(void* d) {
+#else
+static apr_status_t gsdl_exit(void* d) {
+#endif
+
+#if defined(USE_ACCESS)
+  // shut down com
+  CoUninitialize();
+#endif  
+
+#if _APACHE_MOD >= 2
+  return APR_SUCCESS; 
+#endif
+}
+
+#if _APACHE_MOD < 2
+static void gsdl_init(server_rec *s, ap_pool *p) {
+#else
+static void gsdl_init(ap_pool *p, server_rec *s) {
+#endif
+
+  // Register gsdl_exit has cleanup operation for when pchild (process id
+  // of child) exits
+#if _APACHE_MOD >= 2
+  apr_pool_cleanup_register(p,s, apr_pool_cleanup_null, gsdl_exit);
+#else
+  ap_register_cleanup(p,s, ap_null_cleanup, gsdl_exit);
+#endif
+
+  recpt.loaded = false;
+
+  gsdl_config *cfg = (gsdl_config *) ap_get_module_config(s->module_config, &gsdl_module);
+
+  if (!cfg->config_gsdlhome) {
+    ap_log_error("", 0, APLOG_ERR, s, "gsdlhome not set\n");
+    return;
+  }
+  text_t gsdlhome = cfg->config_gsdlhome;
+
+  if (!directory_exists(gsdlhome)) {
+    ap_log_error("", 0, APLOG_ERR, s, "gsdlhome directory does not exist\n");
+    return;
+  }
+
+  if (!cfg->config_collecthome) {
+    ap_log_error("", 0, APLOG_ERR, s, "collecthome not set\n");
+    return;
+  }
+  text_t collecthome = cfg->config_collecthome;
+
+  if (!directory_exists(collecthome)) {
+    ap_log_error("", 0, APLOG_ERR, s, "collecthome directory does not exist\n");
+    return;
+  }
+
+
+  if (!cfg->config_httpprefix) {
+    ap_log_error("", 0, APLOG_ERR, s, "httpprefix not set\n");
+    return;
+  }
+
+  if (!cfg->config_httpweb) {
+    ap_log_error("", 0, APLOG_ERR, s, "httpweb not set\n");
+    return;
+  }
+    
+  text_t httpprefix = cfg->config_httpprefix;
+  text_t httpweb = cfg->config_httpweb;
+
+  text_t collection = "";
+
+  collectset *cservers = new collectset();
+
+  cservers->add_all_collections(gsdlhome,collecthome);
+
+  // set up the null protocol
+  nproto.set_collectset(cservers);
+  
+  // add the protocol to the receptionist
+  recpt.add_protocol(&nproto);
+
+  // add database object to receptionist
+#if defined(USE_MYSQL)
+  mysqlclass *db = new mysqlclass();
+#elif defined(USE_ACCESS)
+  // start up com
+  if(FAILED(CoInitialize(NULL))) {
+    cout << "CoInitialize failed\n";
+    exit(-1);
+  }
+  accessclass *db = new accessclass();
+#else
+
+  // not using either mysql or access database - we'll use the gdbmclass
+  // class as a filler (but most likely won't work) - only useful
+  // if creating a binary that doesn't require access to the database
+  dbclass *db = new gdbmclass();
+
+#endif
+
+#if defined(USE_MYSQL) || defined(USE_ACCESS) 
+  recpt.add_dbclass(db);
+#endif
+
+  // the list of actions.
+  pageaction *apageaction = new pageaction();
+  apageaction->set_receptionist(&recpt);
+  recpt.add_action(apageaction);
+  
+  queryaction *aqueryaction = new queryaction();
+  aqueryaction->set_receptionist(&recpt);
+  recpt.add_action(aqueryaction);
+  
+  documentaction *adocumentaction = new documentaction();
+  adocumentaction->set_receptionist(&recpt);
+  recpt.add_action(adocumentaction);
+
+  extlinkaction *anextlinkaction = new extlinkaction();
+  recpt.add_action(anextlinkaction);
+
+  phindaction *aphindaction = new phindaction();
+  recpt.add_action(aphindaction);
+
+#if defined(USE_MYSQL) || defined(USE_ACCESS)
+  orderaction *aorderaction = new orderaction();
+  aorderaction->set_receptionist(&recpt);
+  recpt.add_action(aorderaction);
+#endif
+
+  configaction *aconfigaction = new configaction();
+  aconfigaction->set_receptionist(&recpt);
+  recpt.add_action(aconfigaction);
+
+  // list of browsers
+  vlistbrowserclass *avlistbrowserclass = new vlistbrowserclass();
+  recpt.add_browser(avlistbrowserclass);
+  recpt.setdefaultbrowser("VList");
+
+  hlistbrowserclass *ahlistbrowserclass = new hlistbrowserclass();
+  recpt.add_browser(ahlistbrowserclass);
+
+  datelistbrowserclass *adatelistbrowserclass = new datelistbrowserclass();
+  recpt.add_browser(adatelistbrowserclass);
+
+  invbrowserclass *ainvbrowserclass = new invbrowserclass();
+  recpt.add_browser(ainvbrowserclass);
+
+  pagedbrowserclass *apagedbrowserclass = new pagedbrowserclass();
+  recpt.add_browser(apagedbrowserclass);
+
+  phindbrowserclass *aphindbrowserclass = new phindbrowserclass();;
+  recpt.add_browser(aphindbrowserclass);
+  
+  // configure everything
+  recpt.configure("gsdlhome", gsdlhome);
+  recpt.configure("collecthome", collecthome);
+  recpt.configure("collection", collection);
+  recpt.configure("httpweb", httpweb);
+  recpt.configure("httpprefix", httpprefix);
+  // set httpprefixfull - if httpprefix is a relative path we need to get
+  // the server name and port from the web server environment (note that
+  // gwcgi and gwcgifull will be configured for each page request (in gsdl_handler)
+  // as we need to know that directory info etc.)
+  text_t httpprefixfull = httpprefix;
+  if ((httpprefixfull.size() < 7) || 
+      (substr(httpprefixfull.begin(), httpprefixfull.begin()+7) != "http://")) {
+    if (s->server_hostname && s->port) {
+      httpprefixfull = "http://" + text_t(s->server_hostname) + ":" + text_t(s->port) + httpprefixfull;
+    }
+  }
+  recpt.configure("httpprefixfull", httpprefixfull);
+
+  // read in main.cfg file
+  if (!main_cfg_read(recpt, gsdlhome, collecthome, collection)) {
+    ap_log_error("", 0, APLOG_ERR, s, "failed to read main.cfg file\n");
+    return;
+  }
+
+  text_t error_file = filename_cat (gsdlhome, "etc", "error.txt");
+  char *eout = error_file.getcstr();
+  ofstream errout (eout, ios::app);
+  delete eout;
+
+  // initialise the library software
+  if (!recpt.init(errout)) {
+    ap_log_error("", 0, APLOG_ERR, s, "Greenstone failed to initialize\n");
+    errout.close();
+    return;
+  }
+
+  errout.close();
+
+  // set flag so gsdl_handler can check that everything initialized
+  // successfully
+  recpt.loaded = true;
+}
+
+
+#if _APACHE_MOD < 2
+
+typedef const char *(*CMD_HAND_TYPE) ();
+static command_rec gsdl_cmds[] = {
+  {"gsdlhome", (CMD_HAND_TYPE)gsdl_cmd,
+   (void *)XtOffsetOf(gsdl_config, config_gsdlhome),
+   OR_ALL, TAKE1, "GSDLHOME directory."},
+  {"collecthome", (CMD_HAND_TYPE)gsdl_cmd,
+   (void *)XtOffsetOf(gsdl_config, config_collecthome),
+   OR_ALL, TAKE1, "COLLECTHOME directory."},
+  {"httpprefix", (CMD_HAND_TYPE)gsdl_cmd,
+   (void *)XtOffsetOf(gsdl_config, config_httpprefix),
+   OR_ALL, TAKE1, "GSDLHOME http path."},
+  {"httpweb", (CMD_HAND_TYPE)gsdl_cmd,
+   (void *)XtOffsetOf(gsdl_config, config_httpweb),
+   OR_ALL, TAKE1, "GSDLHOME http web path."},
+  {NULL, NULL, NULL, 0, cmd_how(0), NULL}
+};
+#else
+
+/* 
+static const char 
+*set_max_cache_size(cmd_parms *parms, void *in_struct_ptr, const char *arg)
+{
+    apr_size_t val;
+
+    return NULL;
+}
+
+  AP_INIT_TAKE1("MCacheSize", set_max_cache_size, NULL, RSRC_CONF,
+		"The maximum amount of memory used by the cache in KBytes"),
+
+*/
+
+// const char *(*cmd_func)();
+
+static const command_rec gsdl_cmds[] = {
+  AP_INIT_TAKE1("gsdlhome", (cmd_func)gsdl_cmd, NULL, OR_ALL,"GSDLHOME directory."),
+  AP_INIT_TAKE1("collecthome", (cmd_func)gsdl_cmd, NULL, OR_ALL,"COLLECTHOME directory."),
+  AP_INIT_TAKE1("httpprefix", (cmd_func)gsdl_cmd, NULL, OR_ALL,"GSDLHOME http path."),
+  AP_INIT_TAKE1("httpweb", (cmd_func)gsdl_cmd, NULL, OR_ALL,"GSDLHOME http web path."),
+  {NULL}
+};
+
+
+#endif
+
+static int gsdl_handler(request_rec *r) {
+
+  if (strcmp(r->handler, "gsdl")) {
+    return DECLINED;
+  }
+
+  // check that everything has been initialized
+  if (!recpt.loaded) {
+    ap_log_error("", 0, APLOG_ERR, r->server,  "gsdl_handler: attempt to use uninitialized receptionist - aborting\n");
+    return 500;
+  }
+
+  gsdl_config *cfg = (gsdl_config *) ap_get_module_config(r->server->module_config, &gsdl_module);
+
+  if (!cfg->config_gsdlhome) {
+    ap_log_error("", 0, APLOG_ERR, r->server,  "gsdl_handler: gsdlhome not set\n");
+    return 500;
+  }
+
+  if (!cfg->config_collecthome) {
+    ap_log_error("", 0, APLOG_ERR, r->server,  "gsdl_handler: collecthome not set\n");
+    return 500;
+  }
+
+  // configure gwcgi and gwcgifull
+  recpt.configure("gwcgi", r->uri);
+  recpt.configure("gwcgifull", "http://" + text_t(r->server->server_hostname) + 
+		  ":" + text_t(r->server->port) + r->uri);
+  
+  string_pool str_pool;
+
+  text_t gsdlhome = cfg->config_gsdlhome;
+
+  text_t error_file = filename_cat (gsdlhome, "etc", "error.txt");
+  char *eout = str_pool.get_cstr_from_pool(error_file);
+  ofstream errout (eout, ios::app);
+
+  text_t argstr;
+  fileupload_tmap fileuploads;
+
+  char *request_method_str = getenv("REQUEST_METHOD");
+  char *content_length_str = getenv("CONTENT_LENGTH");
+  if (request_method_str != NULL && strcmp(request_method_str, "POST") == 0 &&
+      content_length_str != NULL)  {
+    // POST form data
+    long content_length = (content_length_str ? atoi(content_length_str) : 0);
+    if (content_length > 0) {
+#ifdef __WIN32__
+      // On Windows it is important that standard input be read in binary
+      // mode, otherwise end of line "<CR><LF>" is turned into <LF> only
+      // which breaks the MIME standard (and our parsing code!)
+      
+      int result = _setmode( _fileno( stdin ), _O_BINARY );
+      if( result == -1 ) {
+	cerr << "Warning: Failed to set standard input to binary mode." << endl;
+	cerr << "         Parsing of multi-part MIME will most likely fail" << endl;
+      }
+#endif
+      
+      long length = content_length;
+      unsigned char * buffer = new unsigned char[content_length];
+      
+      int chars_read = fread(buffer,1,content_length,stdin);
+      
+      if (chars_read != content_length) {
+	cerr << "Warning: mismatch between CONTENT_LENGTH and data read from standard in" << endl;
+      }
+      
+      argstr.setcarr((char *)buffer, content_length);     
+      
+      text_t content_type;
+      char *content_type_str = getenv("CONTENT_TYPE");
+      if (content_type_str) content_type = content_type_str;
+      argstr = parse_post_data(content_type, argstr, fileuploads, gsdlhome);
+    }
+  } else {
+    
+    if (r->args) argstr = r->args;
+  }
+
+  // parse the cgi arguments and produce the resulting page if there
+  // have been no errors so far
+  cgiargsclass args;
+  text_tmap fastcgienv; // Not being used in this case
+  if (!recpt.parse_cgi_args (argstr, fileuploads, args, errout, fastcgienv)) {
+    errout.close();
+    ap_log_error("", 0, APLOG_ERR, r->server,  "parse_cgi_args failed\n");
+    return 500;
+  } 
+
+  ostrstream pageout;
+
+  // get http headers
+  text_tmap headers;
+  recpt.get_cgihead_info(args, headers, errout, fastcgienv);
+
+  if (headers.find("Location") != headers.end()) {
+    // redirect
+    char *val = str_pool.get_cstr_from_pool(headers.find("Location")->second);
+#if _APACHE_MOD >= 2
+    apr_table_set(r->headers_out, "location", val);
+#else
+    ap_table_set(r->headers_out, "location", val);
+#endif
+    return HTTP_MOVED_TEMPORARILY;
+  }
+
+  text_tmap::iterator here = headers.begin();
+  text_tmap::iterator end = headers.end();
+  while (here != end) {
+    text_t namet = (*here).first;
+    lc(namet);
+    char *name = str_pool.get_cstr_from_pool(namet);
+    char *val = str_pool.get_cstr_from_pool((*here).second);
+
+    if ((*here).first == "content-type") {
+#if _APACHE_MOD < 2
+      r->content_type = val;
+#else
+
+      char* val_copy = strdup(val); // if note freed by r->content_type => Memory leak!
+      ap_set_content_type(r, val_copy);
+#endif
+    } else if ((*here).first == "content-encoding") {
+      r->content_encoding = val;
+    } else {
+#if _APACHE_MOD >= 2
+      apr_table_set(r->headers_out, name, val);
+#else
+      ap_table_set(r->headers_out, name, val);
+#endif
+    }
+
+    here++;
+  }
+  ap_send_http_header(r);
+
+  if (!r->header_only) {
+    if (!recpt.produce_content(args, pageout, errout)) {
+      ap_log_error("", 0, APLOG_ERR, r->server,  "produce_content failed\n");
+      return 500;
+    } 
+    char *out = pageout.str();
+    ap_rwrite(out, pageout.pcount(), r);
+    pageout.rdbuf()->freeze(0);
+  }
+
+  errout.close();  
+
+  return OK;
+}
+
+#if _APACHE_MOD < 2
+
+static const handler_rec gsdl_handlers[] = { 
+  { "gsdl", gsdl_handler }, 
+  { NULL, NULL }
+};
+
+
+extern "C" {
+  module MODULE_VAR_EXPORT gsdl_module = {
+    STANDARD_MODULE_STUFF, 
+    NULL,                       /* module \initializer                  */
+    gsdl_create_dir_config,     /* create per-dir    config structures */
+    NULL,                       /* merge  per-dir    config structures */
+    gsdl_create_config,         /* create per-server config structures */
+    NULL,                       /* merge  per-server config structures */
+    gsdl_cmds,                  /* table of config file commands       */
+    gsdl_handlers,              /* [#8] MIME-typed-dispatched handlers */
+    NULL,                       /* [#1] URI to filename translation    */
+    NULL,                       /* [#4] validate user id from request  */
+    NULL,                       /* [#5] check if the user is ok _here_ */
+    NULL,                       /* [#3] check access by host address   */
+    NULL,                       /* [#6] determine MIME type            */
+    NULL,                       /* [#7] pre-run fixups                 */
+    NULL,                       /* [#9] log a transaction              */
+    NULL,                       /* [#2] header parser                  */
+    gsdl_init,                  /* child_init                          */
+    NULL,                       /* child_exit                          */
+    NULL                        /* [#0] post read-request              */
+#ifdef EAPI
+    ,NULL,                      /* EAPI: add_module                    */
+    NULL,                       /* EAPI: remove_module                 */
+    NULL,                       /* EAPI: rewrite_command               */
+    NULL,                       /* EAPI: new_connection                */
+    NULL                        /* EAPI: close_connection              */
+#endif
+  };
+};
+
+#else
+
+static void gsdl_register_hooks(ap_pool *p)
+{
+  ap_hook_child_init(gsdl_init,NULL,NULL,APR_HOOK_MIDDLE);
+  ap_hook_handler(gsdl_handler, NULL, NULL, APR_HOOK_MIDDLE);
+
+}
+
+extern "C" {
+  module AP_MODULE_DECLARE_DATA gsdl_module = {
+    STANDARD20_MODULE_STUFF, 
+    gsdl_create_dir_config,     /* create per-dir    config structures   */
+    NULL,                       /* merge  per-dir    config structures   */
+    gsdl_create_config,         /* create per-server config structures   */
+    NULL,                       /* merge  per-server config structures   */
+    gsdl_cmds,                  /* command handlers                      */
+    gsdl_register_hooks,        /* set up other request processing hooks */
+  };
+};
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/pageaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/pageaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/pageaction.cpp	(revision 20131)
@@ -0,0 +1,1037 @@
+/**********************************************************************
+ *
+ * pageaction.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+// Changelog:
+
+// 11th July 2003:
+
+//   Added 3 functions to deal with the collection style
+//   A deciding function and then 2 functions that actually
+//   do the work for us, either images or pulldown.
+
+
+#include "pageaction.h"
+#include "receptionist.h"
+#include "recptprototools.h"
+#include "fileutil.h"
+#include "gsdltools.h"
+#include "querytools.h"
+#include <time.h>
+
+pageaction::pageaction () {
+
+  status_disabled = true;
+  collector_disabled = true;
+  depositor_disabled = true; 
+  translator_disabled = true;
+  gliapplet_disabled = true;
+  recpt = NULL;
+
+  // this action uses cgi variables "a", "p", and "hp"
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "a";
+  arg_ainfo.longname = "action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "p";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "p";
+  arg_ainfo.longname = "page";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "home";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "hp";
+  arg_ainfo.longname = "html page";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bp";
+  arg_ainfo.longname = "set preferences button";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // the "u" argument will disable the search facility, remove links to the
+  // home and preferences pages, and disable the DocumentButton buttons
+  // (for use when generating static html versions of collections)
+  arg_ainfo.shortname = "u";
+  arg_ainfo.longname = "static page";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "book";
+  arg_ainfo.longname = "book switch";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "off";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+}
+
+pageaction::~pageaction () {
+}
+
+bool pageaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args, 
+				recptprotolistclass * /*protos*/, ostream &/*logout*/) {
+
+  if (args["p"] == "preferences" && !args["bp"].empty()) {
+    if (args["hd"] != "0") args["hd"] = args["hdn"];
+  }
+
+  return true;
+}
+
+void pageaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
+				   response_t &response,text_t &response_data, 
+				   ostream &/*logout*/) {
+  response = content;
+  response_data = "text/html";
+}
+
+// This function helps decide whether we want a
+// images or pulldown style collection display
+// We refer to the macro files for the options
+// for images or pulldown menu and use that to
+// switch to the appropriate function to do the job
+
+// Aly Dharshi
+// 11th July 2003
+
+void pageaction::homepagestyle(displayclass &disp, recptprotolistclass *protos,
+			       cgiargsclass &args, ostream &logout)
+{
+
+  const recptconf &configinfo = recpt->get_configinfo();
+
+  if (configinfo.HomePageType == "images") {
+     home_images(disp, protos, args, configinfo, logout);
+
+  } else
+     {
+	home_pulldown(disp, protos, args, configinfo, logout);
+     }
+}
+
+// This function allows for the Greenstone
+// collection to be displayed in a pull down
+// menu similar to that in documentaction.cpp
+
+// Aly Dharshi
+// 11th July 2003
+
+void pageaction::home_pulldown(displayclass &disp, recptprotolistclass *protos, 
+			       cgiargsclass &args, const recptconf &configinfo,
+			       ostream &logout) {
+
+   text_t homeextra = "<form method=\"get\" name=\"browse\">\n";
+   homeextra += "<select name=\"collections\" onChange=\"location.href=";
+   homeextra += "document.browse.collections.options[document.browse.collections.selectedIndex].value\">\n";
+   homeextra += "<option value=\"\">_textdescrselcol_</option>\n";
+   
+  recptprotolistclass::iterator rprotolist_here = protos->begin();
+  recptprotolistclass::iterator rprotolist_end = protos->end();
+  while (rprotolist_here != rprotolist_end) {
+    if ((*rprotolist_here).p != NULL) {
+
+      text_tarray collist;
+      comerror_t err;
+      (*rprotolist_here).p->get_collection_list (collist, err, logout);
+      if (err == noError) {
+	text_tarray::iterator collist_here = collist.begin();
+	text_tarray::iterator collist_end = collist.end();
+
+	int count = 0;
+	bool first = true;
+	while (collist_here != collist_end) {
+
+	  ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
+	  
+	  if (cinfo != NULL) {
+	    if (cinfo->isPublic && (cinfo->buildDate > 0)) {
+
+	      text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]);
+	      if (collectionname.empty()) {
+		collectionname = *collist_here;
+	      }
+	      
+	      comerror_t err;
+	      text_t optsite = g_EmptyText;
+	      text_t site_name = (*rprotolist_here).p->get_site_name (err);
+	      if (!site_name.empty()) { optsite = "site="+site_name+"&amp;"; }
+	      
+	      text_t link = "_gwcgi_?"+optsite+"a=p&amp;p=about&amp;c=" + *collist_here;
+	      link += "&amp;l=" + args["l"] + "&amp;w=" + args["w"];
+
+	      // We are "dynamically" overriding so to speak the
+	      // link to the collection aka receptionist.
+	      
+	      if (!cinfo->receptionist.empty()) 
+		 link = cinfo->receptionist;
+	      
+	      
+	      homeextra += "<option value=\"" + link + "\"";
+	      homeextra += ">" + collectionname + "</option>\n";
+	      	    
+	    }
+
+	    ++collist_here;
+	    }
+	    
+	  }
+      }
+	++rprotolist_here;
+    }
+    
+    }
+  homeextra += "</select>\n";
+  homeextra += "</form>\n";
+  
+  disp.setmacro ("homeextra", "home", homeextra); 
+}
+  
+// originally called set_homeextra_macro
+// this function displays the Greenstone
+// main page as usual with the graphics for
+// the collections.
+
+// Aly Dharshi
+// 11th July 2003
+
+void pageaction::home_images(displayclass &disp, recptprotolistclass *protos, 
+			     cgiargsclass &args, const recptconf &configinfo,
+			     ostream &logout) {
+  
+  text_t homeextra = "<table class=\"collections\">\n";
+  bool found_valid_col = false;
+  recptprotolistclass::iterator rprotolist_here = protos->begin();
+  recptprotolistclass::iterator rprotolist_end = protos->end();
+  while (rprotolist_here != rprotolist_end) {
+    if ((*rprotolist_here).p != NULL) {
+
+      text_tarray collist;
+      comerror_t err;
+      (*rprotolist_here).p->get_collection_list (collist, err, logout);
+      if (err == noError) {
+	text_tarray::iterator collist_here = collist.begin();
+	text_tarray::iterator collist_end = collist.end();
+
+	int count = 0;
+	while (collist_here != collist_end) {
+
+	  ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
+
+	  text_t arg_g = args["g"];
+	  text_t colname_dir = *collist_here;
+	  
+	  if (arg_g.empty()) {
+	    // normal top-level home page
+	    text_t::const_iterator begin = colname_dir.begin();
+	    text_t::const_iterator end = colname_dir.end();
+
+	    if (findchar(begin,end,'/')!=end) {
+	      // no g argument, so generating top level home page
+	      // => if colname_dir has "/" in collection name, filter it out
+
+	      ++collist_here;
+	      continue;
+	    }
+	  }
+	  else {
+	    // show only collections in the named group
+
+	    
+	    if (colname_dir == arg_g) {
+	      // display about this collect text
+
+	      text_t collectionextra = cinfo->get_collectionmeta("collectionextra", args["l"]);
+	      if (!collectionextra.empty()) {
+		// prepend text on at start
+		homeextra = "<p>" + collectionextra + "</p>" + homeextra;
+	      }
+
+	      ++collist_here;
+	      continue;
+	    }
+
+
+	    // => filter out anything that does not start with the group prefix
+	    
+	    if (!starts_with(colname_dir,arg_g + "/")) {
+	      ++collist_here;
+	      continue;
+	    }
+	  }
+
+
+	  if (cinfo != NULL) {
+	    if (cinfo->isPublic && ((cinfo->buildDate > 0)) || (cinfo->isCollectGroup)) {
+
+	      found_valid_col = true;
+	      text_t collectionname = *collist_here;
+	      text_t alt = cinfo->get_collectionmeta("collectionname", args["l"]);
+	      if (alt.empty()) {
+		alt = collectionname;
+	      }
+
+
+	      comerror_t err;
+	      text_t optsite = g_EmptyText;
+	      text_t site_name = (*rprotolist_here).p->get_site_name (err);
+	      if (!site_name.empty()) { optsite = "site="+site_name+"&amp;"; }
+
+	      text_t link;
+
+	      if (cinfo->isCollectGroup) {
+		link = "<a class=\"collectiontitle\" href=\"_gwcgi_?"+optsite+"a=p&amp;p=home&amp;g=" + *collist_here;
+		link += "&amp;l=" + args["l"] + "&amp;w=" + args["w"] + "\">";
+	      }
+	      else {
+		link = "<a class=\"collectiontitle\" href=\"_gwcgi_?"+optsite+"a=p&amp;p=about&amp;c=" + *collist_here;
+		link += "&amp;l=" + args["l"] + "&amp;w=" + args["w"] + "\">";
+	      }
+	      
+	      if (!cinfo->receptionist.empty()) 
+		link = "<a class=\"collectiontitle\" href=\"" + cinfo->receptionist + "\">";
+	      
+	      
+	      // url to image: try iconcollectionsmall, then iconcollection
+	      text_t iconurl = cinfo->get_collectionmeta("iconcollectionsmall", args["l"]);
+	      if (iconurl.empty()) {
+		iconurl = cinfo->get_collectionmeta("iconcollection", args["l"]);
+	      }
+	      
+	      if (!iconurl.empty()) {
+		
+		// check to see URL is local to colserver
+		text_t::iterator iconurl_head = iconurl.begin();
+		text_t iconhead = substr(iconurl_head,iconurl_head+16);
+		if (iconhead=="_httpcollection_") {
+		  
+		  // local and using _httpcollection_
+		  text_t icontail = substr(iconurl_head+16,iconurl.end());
+		  iconurl = "http://" + cinfo->httpdomain 
+		    + cinfo->httpprefix + "/collect/" 
+		    + *collist_here + "/" + icontail;
+		}
+		else if (iconurl[0]=='/') {
+		  
+		  // local but with full path
+		  iconurl = "http://" + cinfo->httpdomain + iconurl;
+		}
+		
+		collectionname 
+		  = link + "<img width=\"150\" src=\"" + iconurl + "\" alt=\"" + alt + "\">" + "</a>";
+	      } else {		
+
+		collectionname = "<div class=\"collecttitle\" style=\"width: 150px; border: 1px solid; \"><p class=\"collectiontitle\" style=\"font-size: 18px; width: 150px; white-space:normal; text-align: left;\">";
+		collectionname += alt + "</p></div>";
+
+		collectionname = link + collectionname + "</a>";
+
+	      }
+	      
+	      if (count%configinfo.HomePageCols == 0)
+		homeextra += "<tr valign=\"top\">\n";	      
+
+	      homeextra += "<td align=\"center\">" + collectionname + "</td>\n";
+	      
+	      ++count;
+	      if (count%configinfo.HomePageCols == 0)
+		homeextra += "</tr>\n";
+	    }
+	  }
+	  ++collist_here;
+	}
+
+	// Finish off the last row, if necessary
+	if (count%configinfo.HomePageCols != 0) {
+	  while (count%configinfo.HomePageCols != 0) {
+	    homeextra += "<td></td>\n";
+	    ++count;
+	  }
+	  homeextra += "</tr>\n";
+	}
+      }
+    }
+    ++rprotolist_here;
+  }
+
+  if (!found_valid_col) {
+    homeextra += "<tr><td>_textnocollections_</td></tr>\n";
+  }
+  homeextra += "</table>\n";
+  disp.setmacro ("homeextra", "home", homeextra); 
+}
+
+void pageaction::set_collectionlist_macro (displayclass &disp, 
+					   recptprotolistclass *protos, 
+					   cgiargsclass &args, 
+					   ostream &logout) {
+
+  text_t collectionlist;
+  int count = 0;
+  
+  recptprotolistclass::iterator rprotolist_here = protos->begin();
+  recptprotolistclass::iterator rprotolist_end = protos->end();
+  while (rprotolist_here != rprotolist_end) {
+    if ((*rprotolist_here).p != NULL) {
+
+      text_tarray collist;
+      comerror_t err;
+      (*rprotolist_here).p->get_collection_list (collist, err, logout);
+      if (err == noError) {
+	text_tarray::iterator collist_here = collist.begin();
+	text_tarray::iterator collist_end = collist.end();
+
+	while (collist_here != collist_end) {
+	  ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
+	  
+	  if (cinfo != NULL) {
+	    if (cinfo->isPublic && (cinfo->buildDate > 0)) {
+
+	      ++count;
+
+	      text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]);
+	      if (collectionname.empty()) {
+		collectionname = *collist_here;
+	      }
+	      
+	      comerror_t err;
+	      text_t optsite = g_EmptyText;
+	      text_t site_name = (*rprotolist_here).p->get_site_name (err);
+	      if (!site_name.empty()) { optsite = "site="+site_name+"&amp;"; }
+
+	      text_t link = "<a href=\"_gwcgi_?"+optsite+"a=p&p=about&c=" + *collist_here + "\">";
+
+	      if (!cinfo->receptionist.empty()) 
+		link = "<a href=\"" + cinfo->receptionist + "\">";
+	      
+	     collectionlist += "<li>" + link + collectionname + "</a>\n";
+	    }
+	  }
+	  ++collist_here;
+	}
+      }
+    }
+    ++rprotolist_here;
+  }
+
+  if (count == 1) {
+    collectionlist = "<p>_text1coll_\n<ul>" +
+      collectionlist + "</ul>\n";
+  } else if (count > 1) {
+    collectionlist = "<p>_textmorecolls_(" + text_t(count) + 
+      ")\n<ul>" + collectionlist + "</ul>\n";
+  }
+
+  disp.setmacro ("collectionlist", "homehelp", collectionlist); 
+}
+
+void pageaction::set_documentation_macro (displayclass &disp) {
+
+  text_t documentation;
+  text_t docsdir = filename_cat(gsdlhome, "docs");
+  
+  if (file_exists(filename_cat(docsdir, "User.pdf"))) {
+    documentation += "<tr valign=middle><td><a href=\"_httpdocs_/User.pdf\">_iconpdf_"
+      "</a></td><td>_textuserguide_</td></tr>";
+  }
+  
+  if (file_exists(filename_cat(docsdir, "Install.pdf"))) {
+    documentation += "<tr valign=middle><td><a href=\"_httpdocs_/Install.pdf\">_iconpdf_"
+      "</a></td><td>_textinstallerguide_</td></tr>";
+  }
+  
+  if (file_exists(filename_cat(docsdir, "Develop.pdf"))) {
+    documentation += "<tr valign=middle><td><a href=\"_httpdocs_/Develop.pdf\">_iconpdf_"
+      "</a></td><td>_textdeveloperguide_</td></tr>";
+  }
+  
+  if (file_exists(filename_cat(docsdir, "Paper.pdf"))) {
+    documentation += "<tr valign=middle><td><a href=\"_httpdocs_/Paper.pdf\">_iconpdf_"
+      "</a></td><td>_textpaperguide_</td></tr>";
+  }
+  
+  if (file_exists(filename_cat(docsdir, "Organize.pdf"))) {
+    documentation += "<tr valign=middle><td><a href=\"_httpdocs_/Organize.pdf\">_iconpdf_"
+      "</a></td><td>_textorganizerguide_</td></tr>";
+  }
+
+  if (!documentation.empty()) {
+    disp.setmacro("documentation", "docs", "<p>\n<table border=0>\n" + documentation + "\n</table>\n");
+  }
+}
+
+void pageaction::set_macro_to_file_contents (displayclass &disp, const text_t &macroname,
+					     const text_t &packagename, const text_t &filename) {
+
+  text_t filecontent;
+  char *filenamec = filename.getcstr();
+  ifstream file_in (filenamec);
+  delete []filenamec;
+  if (file_in) {
+    char c;
+    file_in.get(c);
+    while (!file_in.eof ()) {
+      if (c == '\n') filecontent += "<br>";
+      filecontent.push_back(c);
+      file_in.get(c);
+    }
+    file_in.close();
+  }
+  disp.setmacro (macroname, packagename, dm_safe(filecontent));
+}
+
+void pageaction::set_language_encoding_macros(displayclass &disp, cgiargsclass &args,
+					      recptprotolistclass *protos, ColInfoResponse_t *cinfo,
+					      ostream &logout) {
+  // _languageoption_
+  // Create the "interface language" selection box for the preferences
+  // pages.  You can use something like "format PreferenceLanguages
+  // en|fr|zn" from within a collect.cfg file to use only a subset of
+  // the available languages for any given collection (for
+  // collection-specific preferences pages). This facility is kind of
+  // ugly though and should be replaced by something better when the
+  // configuration files are tidied up (as should all the other
+  // "format Preference..." options).
+  text_t &arg_l = args["l"];
+  const recptconf &configinfo = recpt->get_configinfo();
+  // put languages in another map to sort them by longname
+  text_tmap languages;
+  languageinfo_tmap::const_iterator thislang = configinfo.languages.begin();
+  languageinfo_tmap::const_iterator endlang = configinfo.languages.end();
+  while (thislang != endlang) {
+    languages[(*thislang).second.longname] = (*thislang).first;
+    ++thislang;
+  }
+  text_tmap::iterator tlang = languages.begin();
+  text_tmap::iterator elang = languages.end();
+
+  text_t languageoption;
+  bool collection_specific = false;
+
+  if (cinfo != NULL) {
+    text_tmap::const_iterator it = cinfo->format.find ("PreferenceLanguages");
+    if ((it != cinfo->format.end()) && (!(*it).second.empty())) {
+      collection_specific = true;
+      text_tset pref_langs;
+      splitchar ((*it).second.begin(), (*it).second.end(), '|', pref_langs);
+      if (pref_langs.size() > 1) {
+	while (tlang != elang) {
+	  if (pref_langs.find((*tlang).second) != pref_langs.end()) {
+	    languageoption += "<option value=\"" + (*tlang).second + "\"";
+	    if ((*tlang).second == arg_l) languageoption += " selected";
+	    languageoption += ">" + (*tlang).first + "</option>\n";
+	  }
+	  ++tlang;
+	}
+      }
+    }
+  }
+
+  if (!collection_specific) {
+    while (tlang != elang) {
+      languageoption += "<option value=\"" + (*tlang).second + "\"";
+      if ((*tlang).second == arg_l) languageoption += " selected";
+      languageoption += ">" + (*tlang).first + "</option>\n";
+      ++tlang;
+    }
+  }
+
+  if (!languageoption.empty()) {
+    languageoption = "<select name=\"l\" onChange=\"updatel();\">\n" + languageoption;
+    languageoption += "</select>\n";
+    disp.setmacro ("languageoption", args["p"], languageoption);
+  }
+
+  // _encodingoption_
+  // create the "encoding" selection box for the preferences page
+  if (configinfo.encodings.size() > 1) {
+    text_t &arg_w = args["w"];
+    text_t encodingoption;
+    text_tmap::const_iterator thisenc = configinfo.encodings.begin();
+    text_tmap::const_iterator endenc = configinfo.encodings.end();
+    while (thisenc != endenc) {
+      encodingoption += "<option value=\"" + (*thisenc).second + "\"";
+      if ((*thisenc).second == arg_w) encodingoption += " selected";
+      encodingoption += ">" + (*thisenc).first + "</option>\n";
+      ++thisenc;
+    }
+
+    encodingoption = "<select name=\"w\" onChange=\"updatew();\">\n" + encodingoption;
+    encodingoption += "</select>\n";
+    disp.setmacro ("encodingoption", args["p"], encodingoption);
+  } else if (configinfo.encodings.size() == 1) {
+    text_t encodingoption;
+    text_tmap::const_iterator thisenc = configinfo.encodings.begin();
+    encodingoption = (*thisenc).first;
+    disp.setmacro ("encodingoption", args["p"], encodingoption);
+  } else { // size == 0. shouldn't really happen, but allow it
+    disp.setmacro ("encodingoption", args["p"], "None");
+  }
+
+}
+
+
+void pageaction::define_internal_macros (displayclass &disp, cgiargsclass &args, 
+					 recptprotolistclass *protos, ostream &logout) {
+
+  // define_internal_macros sets the following macros:
+
+  // _numdocs_             the number of documents in the collection
+
+  // _builddate_           the date last built
+
+  // if page is "home"
+  // _homeextra_           this is the list of available collections and collection info
+  //                       to be displayed on the home page
+
+
+  // if page is "preferences"
+  // _collectionoption_    collections to search/browse (if cross-collection-searching is on)
+
+  // _htmloptions_         set to _htmloptionson_ if DocumentUseHTML is set
+
+  // _PreferencesDocsFromWeb_ set to 1 if corresponding format option is set
+
+
+  // if page is "preferences" or "homepref"
+  // _languageoption_      interface languages to select from (dependant on PreferenceLanguages)
+
+  // _encodingoption_      encodings to select from
+
+
+  // if page is "about"
+  // _textsubcollections_  the text on which subcollections make up the collection (if 
+  //                       cross-collection searching is being used
+
+  // _textbrowseoptions_   the 'how to find information' text in the about and help pages
+
+  // _numbrowseoptions_    the number of browsing options 
+
+  // _prefschanged_        will be set to _textprefschanged_ if the "set preferences" button
+  //                       was pressed
+
+  // _aboutqueryform_      will be set to "" if the collection isn't searchable
+
+  // if page is "help"
+  // _textbrowseoptions_   the 'how to find information' text in the about and help pages
+
+  // _numbrowseoptions_    the number of browsing options 
+
+  // _topicreadingdocs_    this section of the help text differs depending on what type of 
+  // _textreadingdocs_     collection it is (e.g. html collection, bibliographic collection etc.)
+  // _texthelpreadingdocs_ 
+
+  // if page is "home" or "homehelp"
+  // _textgocollector_     set to "" if collector is disabled in main.cfg
+  // _textgodepositor_     set to "" if depositor is disabled in main.cfg
+  // _textgoadmin_         set to "" if status is disabled in main.cfg
+  // _textgotranslator_    set to "" if translator is disabled in main.cfg
+  // _textgogliapplet_     set to "" if gliapplet is disabled in main.cfg
+
+
+  // if page is "homehelp"
+  // _collectionlist_      list of available collections to be displayed on the homehelp page
+
+  
+  // if page is "docs"
+  // _documentation_       links to PDF documents if they're available
+
+
+  // if page is "bsummary"
+  // _importlog_           set to contents of collections import.log file
+  // _faillog_             set to contents of collections fail.log file
+  //_buildlog_             set to contents of collections build.log file
+  
+  if (recpt == NULL) {
+    logout << "ERROR (pageaction::define_internal_macros): This action does not contain\n"
+	   << "      information about any receptionists. The method set_receptionist was\n"
+	   << "      probably not called from the module which instantiated this action.\n";
+    return;
+  }
+  // _versionnnum_   greenstone version number (hard-coded)
+  disp.setmacro("versionnum", displayclass::defaultpackage, GSDL_VERSION);
+
+  text_t &arg_p = args["p"];
+  text_t &arg_c = args["c"];
+  ColInfoResponse_t *cinfo = NULL;
+
+  recptproto* collectproto = protos->getrecptproto (arg_c, logout);
+  if (collectproto != NULL) {
+    cinfo = recpt->get_collectinfo_ptr (collectproto, arg_c, logout);
+    
+    //set the tidyoption
+    if (cinfo->useBook == false)
+    {
+        disp.setmacro ("tidyoption", displayclass::defaultpackage, "untidy");
+    }
+    else
+    {
+        disp.setmacro ("tidyoption", displayclass::defaultpackage, "tidy");
+    }
+    
+    disp.setmacro ("numdocs", displayclass::defaultpackage, cinfo->numDocs);
+    disp.setmacro ("numsections", displayclass::defaultpackage, cinfo->numSections);
+    disp.setmacro ("numwords", displayclass::defaultpackage, cinfo->numWords);
+    unsigned long current_time = time(NULL);
+    unsigned long builddate = (current_time - cinfo->buildDate) / 86400;
+    disp.setmacro ("builddate", displayclass::defaultpackage, builddate);
+    
+    text_t numbytes;
+    if ((cinfo->numBytes/(1024*1024)) > 1) {
+      numbytes = (text_t)(cinfo->numBytes/(1024*1024)) + " Mb";
+    } else if ((cinfo->numBytes/1024) > 1) {
+      numbytes = (text_t)(cinfo->numBytes/1024) + " kb";
+    } else {
+      numbytes = (text_t)cinfo->numBytes + " bytes";
+    }
+    disp.setmacro("numbytes", displayclass::defaultpackage, numbytes);
+
+    // set up ct, qt, qto
+    set_query_type_args(cinfo, args);
+    // set up ks, ss, afs
+    set_stem_index_args(cinfo, args);
+  
+  }
+  
+  //setting _queryformcontent_ so that the query interface is consistent.
+  //also adding usability button if necessary
+  if (arg_p == "about") {
+    if (cinfo == NULL) {
+      disp.setmacro("cvariable", displayclass::defaultpackage, arg_c);
+      disp.setmacro("content", arg_p, "<p>_textbadcollection_<p>");
+      return;
+    }
+    else {
+
+      text_tmap::iterator check = cinfo->format.find("QueryInterface");
+      if(check != cinfo->format.end()){
+	if((*check).second=="DateSearch"){
+	  text_t current = "_datesearch_";
+	  disp.setmacro("optdatesearch","query",current);
+	}
+      }
+      check = cinfo->format.find("Usability");
+      if(check != cinfo->format.end()){
+	disp.setmacro("usability", displayclass::defaultpackage, "_usablink_");
+	disp.setmacro("usabinterface", displayclass::defaultpackage, ("_usab"+(*check).second+"_"));
+	disp.setmacro("usabilityscript", displayclass::defaultpackage, "_usabshowscript_");
+      }
+    }
+  }
+  
+  
+  if (arg_p == "home" || arg_p == "homehelp") {
+    if (status_disabled) disp.setmacro ("textgoadmin", "home", "");
+    if (collector_disabled) disp.setmacro ("textgocollector", "home", "");
+    if (depositor_disabled) disp.setmacro ("textgodepositor", "home", "");
+    if (translator_disabled) disp.setmacro ("textgotranslator", "home", "");
+
+    if (arg_p == "home") {
+      homepagestyle (disp, protos, args, logout);
+    } else if (arg_p == "homehelp") {
+      set_collectionlist_macro (disp, protos, args, logout);
+    }
+
+  } else if (arg_p == "gli") {
+    if (gliapplet_disabled) disp.setmacro ("gliapplet", "gli", "");
+
+  } else if (arg_p == "homepref") {
+  
+    // set _languageoption_ and _encodingoption_
+    set_language_encoding_macros(disp, args, protos, cinfo, logout);
+
+  } else if (arg_p == "preferences") {
+  
+    if (cinfo == NULL) {
+      disp.setmacro("cvariable", displayclass::defaultpackage, arg_c);
+      disp.setmacro("content", arg_p, "<p>_textbadcollection_<p>");
+      return;
+    }
+
+    if (collectproto == NULL) {return;}
+    
+    // set _languageoption_ and _encodingoption_
+    set_language_encoding_macros(disp, args, protos, cinfo, logout);
+
+    // _collectionoption_
+    if ((args["ccs"] == "1") && (cinfo->ccsCols.size() > 1)) {
+      text_t collectionoption = "_textcollectionoption_";
+      text_tarray::const_iterator col_here = cinfo->ccsCols.begin();
+      text_tarray::const_iterator col_end = cinfo->ccsCols.end();
+      int count = 0;
+      while (col_here != col_end) {
+	text_t colname;
+	if (*col_here == arg_c) {
+	    colname = cinfo->get_collectionmeta("collectionname", args["l"]);
+	} else {
+	  ColInfoResponse_t *this_cinfo = recpt->get_collectinfo_ptr (collectproto, *col_here, logout);
+	  if (this_cinfo == NULL) {++col_here; continue;}
+	  colname = this_cinfo->get_collectionmeta("collectionname", args["l"]);
+	}
+	if (colname.empty()) {
+	  colname = *col_here;
+	}
+	++count;
+	collectionoption += "<input type=checkbox name=\"cc\" value=\"" + 
+	  *col_here + "\" onClick=\"updatecc(\'" + *col_here + "\');\"> " +
+	  colname + "<br>\n";
+	++col_here;
+      }
+      
+      if (count > 1)
+	disp.setmacro ("collectionoption", "preferences", collectionoption);
+    }
+
+    // _htmloptions_
+    
+    text_tmap::const_iterator it = cinfo->format.find ("DocumentUseHTML");
+    if ((it != cinfo->format.end()) && ((*it).second == "true")) {
+      disp.setmacro ("htmloptions", "preferences", "_htmloptionson_");
+
+
+      // _PreferenceDocsFromWeb_
+
+      it = cinfo->format.find ("PreferenceDocsFromWeb");
+      if ((it == cinfo->format.end()) || ((*it).second == "true"))
+	disp.setmacro ("PreferenceDocsFromWeb", "preferences", "1");
+    }
+
+    // _prefschanged_
+    if (!args["bp"].empty()) {
+      disp.setmacro ("prefschanged", "preferences", "_textprefschanged_");
+    }
+    
+  } else if (arg_p == "about" || arg_p == "help") {
+    if (collectproto == NULL) return;
+
+    comerror_t err;
+    bool has_search_button = true;
+    collectproto->is_searchable(args["c"], has_search_button, err, logout);
+    if (err != noError) has_search_button = true;
+    
+    // _textbrowseoptions_ and _numbrowseoptions_
+    
+    FilterResponse_t response;
+    text_tset metadata;
+    metadata.insert ("Title");
+    //****************
+    metadata.insert ("childtype");
+    //****************
+    bool getParents = false;
+    get_children ("", args["c"], args["l"], metadata, getParents, collectproto, response, logout);
+
+    int numbrowseoptions = response.docInfo.size();
+    if (has_search_button) numbrowseoptions += 1;
+    disp.setmacro ("numbrowseoptions", "help", numbrowseoptions);
+
+    ResultDocInfo_tarray::iterator here = response.docInfo.begin();
+    ResultDocInfo_tarray::iterator end = response.docInfo.end();
+
+    text_t helptext;
+    if (has_search_button) {
+      helptext = "<ul><li>_textSearchhelp_\n";
+    }
+
+    // ********************************      
+    int classifiernumber = 0;
+    bool collage = false;
+
+    while (here != end) {
+      
+      ++classifiernumber;
+      text_t childtype = (*here).metadata["childtype"].values[0];
+      if (childtype == "Collage" && arg_p == "about") {
+	// get the classifier number
+	disp.setmacro ("classifier", "about", classifiernumber);
+	disp.setmacro ("aboutCollage", "about", "_collageapplet_");
+	collage = true;
+      }
+      ++here;
+    } 
+    if (! collage)
+      disp.setmacro ("aboutCollage", "about", "_collageempty_");
+	
+    // ********************************
+     
+    here = response.docInfo.begin();
+
+    while (here != end) {
+      
+      text_t title = (*here).metadata["Title"].values[0];
+    
+      text_t stext;
+      disp.expandstring ("help", "_text" + title + "help_", stext);
+      if (stext == ("_text" + title + "help_")) {
+	text_t ltext, ttext;
+	disp.expandstring("Global", "_label"+title+"_", ltext);
+	if (ltext == ("_label"+title+"_")) {
+	  ltext = title;
+	}
+	disp.expandstring("Global", "_text"+title+"_", ttext);
+	if (ttext == ("_text"+title+"_")) {
+	  ttext = title;
+	}
+	helptext += "<li>_help:textdefaulthelp_("+ttext+","+ltext+")";
+      } else {
+	helptext += "<li>_help:text" + title + "help_";
+      }
+
+      ++here;
+    }
+    helptext += "</ul>\n";
+    disp.setmacro ("textbrowseoptions", "help", helptext);
+
+    if (arg_p == "help") {
+      // do we need to add in the datesearch help??
+      text_tmap::iterator check = cinfo->format.find("QueryInterface");
+      if(check != cinfo->format.end()){
+	if((*check).second=="DateSearch"){
+	  text_t current = "_datesearch_";
+	  disp.setmacro("optdatesearchhelp","help","_datesearchhelp_");
+	  disp.setmacro("optdatesearchhelpcontents","help","_datesearchhelpcontents_");
+	}
+      }
+      
+    }
+    
+    if (arg_p == "about") {
+
+      // _textsubcollections_
+      if (args["ccs"] == "1" && (cinfo->ccsCols.size() > 1)) {
+	text_t textsubcollections = "_textsubcols1_(" + text_t(cinfo->ccsCols.size()) + ")";
+	text_tarray::const_iterator here = cinfo->ccsCols.begin();
+	text_tarray::const_iterator end = cinfo->ccsCols.end();
+	bool first = true;
+	int count = 0;
+	while (here != end) {
+	  if (*here == arg_c) {
+	    if (!first) textsubcollections += "<br>";
+	    textsubcollections += "\n" + cinfo->get_collectionmeta("collectionname", args["l"]) + "\n";
+	  } else {
+	    ColInfoResponse_t *this_cinfo = recpt->get_collectinfo_ptr (collectproto, *here, logout);
+	    if (this_cinfo == NULL) {++here; continue;}
+	    if (!first) textsubcollections += "<br>";
+	    textsubcollections += "\n" + this_cinfo->get_collectionmeta("collectionname", args["l"]) + "\n";
+	  }
+	  ++count;
+	  first = false;
+	  ++here;
+	}
+	textsubcollections += "_textsubcols2_";
+	if (count > 1) {
+	  disp.setmacro ("textsubcollections", "about", textsubcollections);
+	}
+      }
+
+      comerror_t err;
+      bool issearchable = true;
+      collectproto->is_searchable(args["c"], issearchable, err, logout);
+      if (err != noError) issearchable = true;
+      outconvertclass t;
+      if (!issearchable ) {
+	disp.setmacro ("aboutqueryform", "about", "");
+      }
+    }
+
+  } else if (arg_p == "docs") {
+
+    set_documentation_macro (disp);
+
+  } else if (arg_p == "bsummary" && !arg_c.empty()) {
+
+    set_macro_to_file_contents (disp, "importlog", "bsummary",
+				filename_cat(collecthome, arg_c, "etc", "import.log"));
+    set_macro_to_file_contents (disp, "faillog", "bsummary",
+				filename_cat(collecthome, arg_c, "etc", "fail.log"));
+    set_macro_to_file_contents (disp, "buildlog", "bsummary",
+				filename_cat(collecthome, arg_c, "etc", "build.log"));
+  }
+}
+
+bool pageaction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/, 
+			    browsermapclass * /*browsers*/, displayclass &disp, 
+			    outconvertclass &outconvert, ostream &textout, 
+			    ostream &/*logout*/) {
+
+  text_t &arg_p = args["p"];
+
+  textout << outconvert << disp << ("_" + arg_p + ":header_\n")
+	  << ("_" + arg_p + ":content_\n")
+	  << ("_" + arg_p + ":footer_\n");
+
+  return true;
+}
+
+void pageaction::configure (const text_t &key, const text_tarray &cfgline) {
+  if ((key == "status") && (cfgline.size() == 1) && 
+      (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
+    status_disabled = false;
+  } else if ((key == "collector") && (cfgline.size() == 1) && 
+	     (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
+    collector_disabled = false;
+  }
+ else if ((key == "depositor") && (cfgline.size() == 1) && 
+	     (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
+    depositor_disabled = false;
+  }
+    else if ((key == "translator") && (cfgline.size() == 1) && 
+	     (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
+    translator_disabled = false;
+  } else if ((key == "gliapplet") && (cfgline.size() == 1) && 
+	     (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
+    gliapplet_disabled = false;
+  }
+  else {
+    // call the parent class to deal with the things which
+    // are not dealt with here
+    action::configure (key, cfgline);
+  }
+}
+
+
+
+
+
+
+
+
+
+
Index: /gsdl/stable/runtime-src/src/recpt/pageaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/pageaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/pageaction.h	(revision 20131)
@@ -0,0 +1,104 @@
+/**********************************************************************
+ *
+ * pageaction.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef PAGEACTION_H
+#define PAGEACTION_H
+
+
+#include "gsdlconf.h"
+#include "action.h"
+#include "receptionist.h"
+
+
+class pageaction : public action {
+  
+protected:
+  receptionist *recpt;
+
+  text_tset classify_meta;
+
+public:
+  pageaction ();
+  virtual ~pageaction ();
+
+  void set_receptionist (receptionist *therecpt) {recpt=therecpt;}
+
+  text_t get_action_name () {return "p";}
+  
+  bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+		      recptprotolistclass *protos, ostream &logout);
+
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response,text_t &response_data, 
+			 ostream &logout);
+
+  void define_internal_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+
+  void configure (const text_t &key, const text_tarray &cfgline);
+
+ protected:
+  
+  void home_images (displayclass &disp, recptprotolistclass *protos, 
+		   cgiargsclass &args, const recptconf &configinfo, ostream &logout);
+  
+  void home_pulldown (displayclass &disp, recptprotolistclass *protos, 
+		      cgiargsclass &args, const recptconf &configinfo, ostream &logout);
+  
+  void homepagestyle (displayclass &disp, recptprotolistclass *protos, 
+		      cgiargsclass &args, ostream &logout);
+  
+
+  
+  void set_collectionlist_macro (displayclass &disp, recptprotolistclass *protos, 
+				 cgiargsclass &args, ostream &logout);
+
+  void set_documentation_macro (displayclass &disp);
+
+  void set_macro_to_file_contents (displayclass &disp, const text_t &macroname,
+				   const text_t &packagename, const text_t &filename);
+
+  void set_language_encoding_macros(displayclass &disp, cgiargsclass &args,
+				    recptprotolistclass *protos, ColInfoResponse_t *cinfo,
+				    ostream &logout);
+
+
+  
+  bool status_disabled;
+  bool collector_disabled;
+  bool depositor_disabled;
+  bool translator_disabled;
+  bool gliapplet_disabled;
+
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/pagedbrowserclass.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/pagedbrowserclass.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/pagedbrowserclass.cpp	(revision 20131)
@@ -0,0 +1,212 @@
+/**********************************************************************
+ *
+ * pagedbrowserclass.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_PAGED_BROWSER
+
+#include "pagedbrowserclass.h"
+#include <assert.h>
+#include "recptprototools.h"
+#include "OIDtools.h"
+#include "gsdltools.h"
+
+pagedbrowserclass::pagedbrowserclass () {
+}
+
+pagedbrowserclass::~pagedbrowserclass () {
+}
+
+// returns the name that specifies the browserclass type
+text_t pagedbrowserclass::get_browser_name () {
+  return "Paged";
+}
+
+browserclass* pagedbrowserclass::clone()
+{
+  return new pagedbrowserclass();
+}
+
+void pagedbrowserclass::load_metadata_defaults (text_tset &metadata) {
+  metadata.insert ("Title");
+}
+
+// if the "gp" (go to page) argument is set we need to set
+// the "d" argument to the corresponding page
+// also want to set "d" argument to first child if we're at
+// an 'Invisible' top level
+void pagedbrowserclass::processOID (cgiargsclass &args, recptproto *collectproto,
+                                    ostream &logout) {
+
+  text_t &arg_d = args["d"];
+  text_t &arg_gp = args["gp"];
+  text_tset metadata;
+  bool getParents = false;
+  FilterResponse_t response;
+
+  if (!arg_d.empty() && !arg_gp.empty()) {
+    text_t immediate_parent = get_parent (arg_d);
+
+    metadata.insert("Title");
+    get_children (immediate_parent, args["c"], args["l"], metadata,
+		  getParents, collectproto, response, logout);
+    ResultDocInfo_tarray::iterator dochere = response.docInfo.begin();
+    ResultDocInfo_tarray::iterator docend = response.docInfo.end();
+    while (dochere != docend) {
+      if ((*dochere).metadata["Title"].values[0] == arg_gp) {
+        arg_d = (*dochere).OID;
+        return;
+      }
+      ++dochere;
+    }
+  }
+
+  // The "gp" argument was either empty or invalid, so display the first child if given a document OID
+  if (!arg_d.empty() && is_top(arg_d)) { // if top level doc, check if not invisible
+    metadata.insert("thistype");
+    if (get_info(arg_d, args["c"], args["l"], metadata, getParents, collectproto, response, logout)) {
+      text_t type = response.docInfo[0].metadata["thistype"].values[0];
+      if (type=="Invisible") { // display first child
+        arg_d = arg_d + ".fc";
+      }
+    }
+  }
+}
+
+int pagedbrowserclass::output_section_group (ResultDocInfo_t &section, cgiargsclass &args,
+					     const text_t &/*collection*/, int /*colnumber*/, 
+					     format_t * /*formatlistptr*/, bool /*use_table*/, 
+					     text_tset &/*metadata*/, bool &/*getParents*/,
+					     recptproto * /*collectproto*/, displayclass &disp, 
+					     outconvertclass &outconvert, ostream &textout, 
+					     ostream &/*logout*/) {
+
+  // this browser class only handles document levels
+  if (args["d"].empty()) return 0;
+
+  if (section.OID != args["d"]) {
+    text_t httpprevarrow = "_httpdocument_&cl=" + args["cl"] + "&d=" + dm_safe(section.OID);
+    text_t parentarrow = "<a href=\"" + httpprevarrow + "\">_iconprev_</a>\n";
+    disp.setmacro ("httpprevarrow", "document", httpprevarrow);
+    disp.setmacro ("parentarrow", "document", parentarrow);
+    return 0;
+  }
+
+  // must be at top level to get to here!
+  textout << outconvert << disp << "<b>" << section.metadata["Title"].values[0] 
+	  << "_document:textintro_</b>\n";
+  
+  return 0;
+}
+
+int pagedbrowserclass::output_section_group (FilterResponse_t &sections, cgiargsclass &args,
+					     const text_t &/*collection*/, int /*colnumber*/, 
+					     format_t * /*formatlistptr*/, bool /*use_table*/, 
+					     text_tset &/*metadata*/, bool &/*getParents*/,
+					     recptproto * /*collectproto*/, displayclass &disp, 
+					     outconvertclass &outconvert, ostream &textout, 
+					     ostream &/*logout*/) {
+
+  text_t &arg_d = args["d"];
+
+  // this browser class only handles document levels
+  if (arg_d.empty()) return 0;
+
+  text_t previousOID, previoustitle, nextOID, nexttitle;
+  text_t prevarrow, nextarrow, httpprevarrow, httpnextarrow;
+  bool found = false;
+
+  // this should be our list of pages
+
+  ResultDocInfo_tarray::iterator thissection = sections.docInfo.begin();
+  ResultDocInfo_tarray::iterator endsection = sections.docInfo.end();
+
+  while (thissection != endsection) {
+    if (arg_d == (*thissection).OID) {
+      found = true;
+      textout << outconvert << disp 
+	      << "<table><tr valign=top><td colspan=3><center><b>_page_"
+	      << (*thissection).metadata["Title"].values[0] << "</b>\n";
+      if (thissection != sections.docInfo.begin()) {
+	previousOID = (*(thissection-1)).OID;
+	previoustitle = (*(thissection-1)).metadata["Title"].values[0];
+      } else {
+	prevarrow = "_document:parentarrow_";
+      }
+
+      if ((thissection+1) != endsection) {
+	nextOID = (*(thissection+1)).OID;
+	nexttitle = (*(thissection+1)).metadata["Title"].values[0];
+      }
+      break;
+    }
+    ++thissection;
+  }
+
+  if (!found) {
+    textout << outconvert << disp 
+	    << "<table><tr valign=top> <td colspan=3><center>\n";
+  }
+  int numpages = sections.docInfo.size();
+  textout << outconvert << disp 
+	  << ("_document:textnumpages_(" + text_t(numpages) + ")</center></td></tr>\n");
+
+  disp.setmacro ("numpages", "document", numpages);
+
+  if (!found) {
+    httpnextarrow = "_httpdocument_&cl=" + args["cl"] + "&d=" + sections.docInfo[0].OID;
+    nextarrow = "<a href=\"" + httpnextarrow + "\">" + 
+      sections.docInfo[0].metadata["Title"].values[0] + "_iconnext_</a>\n";
+
+  } else {
+    if (!previousOID.empty()) {
+      httpprevarrow = "_httpdocument_&cl=" + args["cl"] + "&d=" + dm_safe(previousOID);
+      prevarrow = "<a href=\"" + httpprevarrow + "\">_iconprev_" + previoustitle + "</a>\n";
+    }
+    if (!nextOID.empty()) {
+      httpnextarrow = "_httpdocument_&cl=" + args["cl"] + "&d=" + dm_safe(nextOID);
+      nextarrow = "<a href=\"" + httpnextarrow + "\">" + nexttitle + "_iconnext_</a>\n";
+    }
+  }
+
+  if (!httpprevarrow.empty()) disp.setmacro ("httpprevarrow", "document", httpprevarrow);
+  if (!httpnextarrow.empty()) disp.setmacro ("httpnextarrow", "document", httpnextarrow);
+
+  if (!prevarrow.empty()) disp.setmacro ("prevarrow", "document", prevarrow);
+  if (!nextarrow.empty()) disp.setmacro ("nextarrow", "document", nextarrow);
+
+  if (!previoustitle.empty()) disp.setmacro ("prevtitle", "document", previoustitle);
+  if (!nexttitle.empty())     disp.setmacro ("nexttitle", "document", nexttitle);
+
+
+  textout << outconvert << disp << "<tr valign=middle>\n"
+	  << "<td align=right>" << prevarrow << "</td>\n"
+	  << "<td align=center valign=top>_document:gotoform_</td>"
+	  << "<td align=left>" << nextarrow << "</td>\n"
+	  << "</tr></table>\n";
+
+  return 0;
+}
+
+#endif //GSDL_USE_PAGED_BROWSER
Index: /gsdl/stable/runtime-src/src/recpt/pagedbrowserclass.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/pagedbrowserclass.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/pagedbrowserclass.h	(revision 20131)
@@ -0,0 +1,68 @@
+/**********************************************************************
+ *
+ * pagedbrowserclass.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_PAGED_BROWSER
+
+#ifndef PAGEDBROWSERCLASS_H
+#define PAGEDBROWSERCLASS_H
+
+#include "browserclass.h"
+
+class pagedbrowserclass : public browserclass {
+protected:
+
+public:
+
+  pagedbrowserclass ();
+  virtual ~pagedbrowserclass ();
+
+  // returns the name that specifies the browserclass type
+  virtual text_t get_browser_name ();
+
+  virtual browserclass* clone();
+
+  void load_metadata_defaults (text_tset &metadata);
+
+  virtual void processOID (cgiargsclass &args, recptproto *collectproto,
+			   ostream &logout);
+
+
+  virtual int output_section_group (ResultDocInfo_t &section, cgiargsclass &args,
+				    const text_t &collection, int colnumber, format_t *formatlistptr, 
+				    bool use_table, text_tset &metadata, bool &getParents,
+				    recptproto *collectproto, displayclass &disp, 
+				    outconvertclass &outconvert, ostream &textout, ostream &logout);
+
+  virtual int output_section_group (FilterResponse_t &sections, cgiargsclass &args,
+				    const text_t &collection, int colnumber, format_t *formatlistptr, 
+				    bool use_table, text_tset &metadata, bool &getParents,
+				    recptproto *collectproto, displayclass &disp, 
+				    outconvertclass &outconvert, ostream &textout, ostream &logout);
+
+};
+
+#endif //!PAGEDBROWSERCLASS_H
+#endif //GSDL_USE_PAGED_BROWSER
Index: /gsdl/stable/runtime-src/src/recpt/phindaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/phindaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/phindaction.cpp	(revision 20131)
@@ -0,0 +1,1062 @@
+/**********************************************************************
+ *
+ * phindaction.cpp -- 
+ *
+ * Copyright 2001 Gordon W. Paynter
+ * Copyright 2001 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_PHIND_ACTION
+
+// Note that this action uses mgpp to retrieve phind info, calling MGQuery
+// etc. directly, not through the protocol. This breaks our receptionist -
+// collection server separation and should be fixed some day I guess.
+
+#include "phindaction.h"
+#include "fileutil.h"
+
+phindaction::phindaction () {
+
+  cgiarginfo arg_ainfo;
+
+  arg_ainfo.shortname = "pc";
+  arg_ainfo.longname = "phind classifier";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "pxml";
+  arg_ainfo.longname = "phind XML mode";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "ppnum";
+  arg_ainfo.longname = "phind phrase number";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "pptext";
+  arg_ainfo.longname = "phind phrase text";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "pfe";
+  arg_ainfo.longname = "phind first_e";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "ple";
+  arg_ainfo.longname = "phind last_e";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "10";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "pfl";
+  arg_ainfo.longname = "phind first_l";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "pll";
+  arg_ainfo.longname = "phind last_l";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "10";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "pfd";
+  arg_ainfo.longname = "phind first_d";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "pld";
+  arg_ainfo.longname = "phind last_d";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "10";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+}
+
+phindaction::~phindaction () {
+}
+
+void phindaction::get_cgihead_info (cgiargsclass &args, recptprotolistclass * /*protos*/,
+				    response_t &response,text_t &response_data, 
+				    ostream &/*logout*/) {
+  response = content;
+  if (args["pxml"] == "1") {
+    response_data = "text/xml";
+  } else {
+    response_data = "text/html";
+  }
+}
+
+bool phindaction::do_action (cgiargsclass &args, recptprotolistclass *protos, 
+			     browsermapclass * /*browsers*/, displayclass &disp, 
+			     outconvertclass &outconvert, ostream &textout, 
+			     ostream &logout) {
+
+  unsigned long count_l, count_e, count_d;
+  unsigned long phrase = args["ppnum"].getulong();
+  text_t &word = args["pptext"];
+  unsigned long first_e = args["pfe"].getulong();
+  unsigned long last_e = args["ple"].getulong();
+  unsigned long first_l = args["pfl"].getulong();
+  unsigned long last_l = args["pll"].getulong();
+  unsigned long first_d = args["pfd"].getulong();
+  unsigned long last_d = args["pld"].getulong();
+  bool XMLmode = false;
+  if (args["pxml"] == "1") XMLmode = true;
+
+  // must have a valid collection server
+  recptproto *collectproto = protos->getrecptproto (args["c"], logout);
+  if (collectproto == NULL) {
+    output_error("phindaction: ERROR: collection not set", textout, 
+		 outconvert, disp, logout, XMLmode);
+    return true;
+  }
+
+  // the frequency and occurances of the phrase
+  unsigned long tf;
+  vector <unsigned long> el, linkdest, docNums, docfreq;
+  vector <UCArray> linktype;
+
+  // the number of occurances to display
+  unsigned long ef, lf, df;
+  
+  text_t basepath = filename_cat(collecthome, args["c"], 
+				 "index", "phind" + args["pc"]);
+
+  // If we don't know the phrase number, look it up
+  if (phrase == 0) {
+    
+    if (word.empty()) {
+      output_error("phindaction: ERROR: no phrase number or word", textout, 
+		   outconvert, disp, logout, XMLmode);
+      return true;
+    }
+
+    DocNumArray result;
+    /** In order to prevent browser crashing problems, any method which
+     *  previously suffered a silent fatal error, now instead returns false
+     *  to indicate a fatal error has occured. We can then dispatch an
+     *  appropriate error tag to the Phind applet (rather than leave it
+     *  whiling away the milliseconds until the end of existence - or at
+     *  least your browser - in an infinite loop!)
+     *  DLConsulting 12-07-2004
+     */
+    if(!find_phrase_number_from_word(basepath, word, result)) {
+	output_error("phindaction: Fatal Error! Couldn't load index information in find_phrase_number_from_word()",
+		     textout, outconvert, disp, logout, XMLmode);
+	return true;
+    }
+    
+    if (result.empty()) {
+      output_error("phindaction: The search term does not occur in the collection",
+		   textout, outconvert, disp, logout, XMLmode);
+      return true;
+    } else {
+      phrase = result[0];
+    }
+  } 
+
+  // Create a TextData object to read the phrase data (pdata)
+  TextData textdata;
+
+  text_t fullpath = filename_cat(basepath, "pdata");
+  char *fullpathc = fullpath.getcstr();
+#if defined __WIN32__
+  char *base = "";
+#else
+  char *base = "/";
+#endif
+
+  if (!textdata.LoadData (base, fullpathc)) {
+    //    FatalError (1, "Couldn't load text information for \"%s\"", fullpathc);
+    //exit(0);
+    /** We must return something to the client, whether this error is fatal or 
+     *  no, otherwise we risk sending their browser into an infinite loop!
+     *  DLConsulting 12-07-2004
+     */
+    output_error("phindaction: Fatal Error! Couldn't load text information for collection",
+		 textout, outconvert, disp, logout, XMLmode);
+    return true;
+  }
+
+  delete []fullpathc;
+
+  /** Another previously silent method can now cry out.
+   *  DLConsulting 12-07-2004
+   */
+  if(!get_phrase_all_data(textdata, phrase, word, tf, ef, lf, df, el, 
+			  linkdest, linktype, docNums, docfreq)) {
+    output_error(
+      "phindaction: Fatal Error! Couldn't parse phrase in get_phrase_all_data()",
+      textout, outconvert, disp, logout, XMLmode);
+      return true;    
+  }
+
+  // Output the header
+  if (XMLmode) {
+    textout << "<phinddata id=\"" << phrase 
+	    << "\" text=\"" << word 
+	    << "\" tf=\"" << tf 
+	    << "\" ef=\"" << ef 
+	    << "\" df=\"" << df 
+	    << "\" lf=\"" << lf 
+	    << "\">\n";
+  } else {
+    textout << "<html><head><title>" << word << "</title></head>\n"
+	    << "<body><center>\n"
+	    << "<p><h1>" << word << "</h1>\n"
+	    << "<p><b>"<< word << "</b> occurs " 
+	    << tf << " times in " << df << " documents\n";
+  }
+
+  // Output the thesaurus links
+  if ((lf > 0) && (first_l < last_l)) {
+
+    // figure out the number of phrases to output
+    if (last_l > lf) {
+      last_l = lf;
+    }
+    count_l = last_l - first_l;
+    
+    if (XMLmode) {
+      textout << "<thesauruslist length=\"" << lf 
+	      << "\" start=\"" << first_l
+	      << "\" end=\"" << last_l << "\">\n";
+      /** DLConsulting 12-07-2004 */
+      if(!print_thesaurus_links(args["c"], XMLmode, textdata, linkdest, linktype,
+			       first_l, last_l, disp, outconvert, textout)) {
+	output_error(
+		     "phindaction: Fatal Error! Couldn't get phrase in get_phrase_freq_data()",
+		     textout, outconvert, disp, logout, XMLmode);
+	return true;	
+      }
+      textout << "</thesauruslist>\n";
+    }
+
+    // output links as HTML
+    else {
+      if (count_l == lf) {
+	textout << "<p><b> " << count_l << " thesaurus links</b>\n";
+      } else {
+	textout << "<p><b>" << count_l << " of " << lf << " thesaurus links</b>\n";
+      }
+
+      textout << "<p><table border=1><tr><th>type</th><th>topic</th><th>freq</th><th>docs</th></tr>\n";
+      /** DLConsulting 12-07-2004 */
+      if(!print_thesaurus_links(args["c"], XMLmode, textdata, linkdest, linktype, 
+			       first_l, last_l, disp, outconvert, textout)) {
+	output_error(
+		     "phindaction: Fatal Error! Couldn't get phrase in get_phrase_freq_data()",
+		     textout, outconvert, disp, logout, XMLmode);
+	return true;
+      }
+      textout << "</table>\n";
+
+      if (last_l < lf) {
+	if ((last_l + 10) < lf) {
+	  textout << outconvert << disp 
+		  << "<br><a href=\"_gwcgi_?"
+		  << "c=" << args["c"]
+		  << "&ppnum=" << phrase 
+		  << "&pfe=" << first_e 
+		  << "&ple=" << last_e 
+		  << "&pfd=" << first_d 
+		  << "&pld=" << last_d
+		  << "&pfl=" << first_l 
+		  << "&pll=" << (last_l + 10)
+		  << "\">Get more thesaurus links</a>\n"; 
+	}
+	textout << outconvert << disp
+		<< "<br><a href=\"_gwcgi_?"
+		<< "c=" << args["c"]
+		<< "&ppnum=" << phrase 
+		<< "&pfe=" << first_e 
+		<< "&ple=" << last_e 
+		<< "&pfd=" << first_d 
+		<< "&pld=" << last_d 
+		<< "&pfl=" << first_l 
+		<< "&pll=" << lf
+		<< "\">Get every thesaurus link</a>\n" ;
+      }
+    }
+  }
+  
+  // Output the expansions
+  if ((ef > 0) && (first_e < last_e)) {
+
+    // figure out the number of phrases to output
+    if (last_e > el.size()) {
+      last_e = el.size();
+    }
+    count_e = last_e - first_e;
+
+    // output expansions as XML
+    if (XMLmode) {
+      textout << "<expansionlist length=\"" << ef 
+	      << "\" start=\"" << first_e
+	      << "\" end=\"" << last_e << "\">" << endl;
+
+      print_expansions(args["c"], XMLmode, word, textdata, el, first_e,
+		       last_e, disp, outconvert, textout);
+
+      textout << "</expansionlist>\n";
+    }
+
+    // output expansions as HTML
+    else {
+      if (count_e == el.size()) {
+	textout << "<p><b> " << count_e << " expansions</b>\n";
+      } else {
+	textout << "<p><b>" << count_e << " of " << ef << " expansions</b>\n";
+      }
+
+      textout << "<p><table border=1><tr><th colspan=3>phrase</th><th>freq</th><th>docs</th></tr>\n";
+      print_expansions(args["c"], XMLmode, word, textdata, el, first_e, 
+		       last_e, disp, outconvert, textout);
+      textout << "</table>\n";
+
+      if (last_e < ef) {
+	if ((last_e + 10) < ef) {
+	  textout << outconvert << disp 
+		  << "<br><a href=\"_gwcgi_?"
+		  << "c=" << args["c"]
+		  << "&ppnum=" << phrase 
+		  << "&pfe=" << first_e 
+		  << "&ple=" << (last_e + 10) 
+		  << "&pfd=" << first_d 
+		  << "&pld=" << last_d 
+		  << "&pfl=" << first_l 
+		  << "&pll=" << last_l
+		  << "\">Get more expansions</a>\n";
+	}
+	textout << outconvert << disp
+		<< "<br><a href=\"_gwcgi_?"
+		<< "c=" << args["c"]
+		<< "&ppnum=" << phrase 
+		<< "&pfe=" << first_e 
+		<< "&ple=" << ef
+		<< "&pfd=" << first_d 
+		<< "&pld=" << last_d 
+		<< "&pfl=" << first_l 
+		<< "&pll=" << last_l
+		<< "\">Get every expansion</a>\n";
+      }
+    }
+  }
+
+  // Output the document occurances
+  if ((df > 0) && (first_d < last_d)) {
+
+    // figure out the phrases to output
+    if (last_d > docNums.size()) {
+      last_d = docNums.size();
+    }
+    count_d = last_d - first_d;
+
+    // output document list as XML
+    if (XMLmode) {
+      textout << "<documentlist length=\"" << df 
+	      << "\" start=\"" << first_d
+	      << "\" end=\"" << last_d << "\">\n";
+      
+      if(!print_documents(XMLmode, basepath, args["c"], docNums, docfreq,
+			  first_d, last_d, disp, outconvert, textout)) {
+	output_error(
+		     "phindaction: Fatal Error! Couldn't load text information in print_documents() or get_document_all_data()",
+		     textout, outconvert, disp, logout, XMLmode);
+	return true;	
+      }
+
+      textout << "</documentlist>\n";
+    }
+
+    // output document list as HTML 
+    else {
+      
+      if (count_d == docNums.size()) {
+	textout << "<p><b> " << count_d << " documents</b>\n";
+      } else {
+	textout << "<p><b>" << count_d << " of " << df << " documents</b>\n";
+      }
+
+      textout << "<p><table border=1><tr><th align=left>document</th><th>freq</th></tr>\n";
+      if(!print_documents(XMLmode, basepath, args["c"], docNums, docfreq, 
+			  first_d, last_d, disp, outconvert, textout)) {
+	output_error(
+		     "phindaction: Fatal Error! Couldn't load text information in print_documents()",
+		     textout, outconvert, disp, logout, XMLmode);
+	return true;
+      }
+      textout << "</table>\n";
+      
+      if (last_d < df) {
+	if ((last_d + 10) < df) {
+	  textout << outconvert << disp
+		  << "<br><a href=\"_gwcgi_?"
+		  << "c=" << args["c"]
+		  << "&ppnum=" << phrase 
+		  << "&pfe=" << first_e 
+		  << "&ple=" << last_e 
+		  << "&pfd=" << first_d
+		  << "&pld=" << (last_d + 10)  
+		  << "&pfl=" << first_l 
+		  << "&pll=" << last_l
+		  << "\">Get more documents</a>\n";
+	}
+	textout << outconvert << disp 
+		<< "<br><a href=\"_gwcgi_?"
+		<< "c=" << args["c"]
+		<< "&ppnum=" << phrase 
+		<< "&pfe=" << first_e 
+		<< "&ple=" << last_e 
+		<< "&pfd=" << first_d 
+		<< "&pld=" << df
+		<< "&pfl=" << first_l 
+		<< "&pll=" << last_l
+		<< "\">Get every document</a>\n";
+      }
+    }
+  }
+
+  // Close the document
+  if (XMLmode) {
+    textout << "</phinddata>\n";
+  } else {
+    textout << "</center></body></html>\n";
+  }
+
+  textdata.UnloadData ();
+
+  return true;
+}
+
+// Find the phrase number of a word in the index file
+bool phindaction::find_phrase_number_from_word(const text_t &basepath, 
+					       const text_t &query, 
+					       DocNumArray &result) {
+
+  // Open the index file for searching
+  IndexData indexData;
+
+  text_t fullpath = filename_cat(basepath, "pword");
+  char *fullpathc = fullpath.getcstr();
+#if defined __WIN32__
+  char *base = "";
+#else
+  char *base = "/";
+#endif
+
+  if (!indexData.LoadData (base, fullpathc)) {
+    //    FatalError (1, "Couldn't load index information for \"%s\"", fullpathc);
+    //exit(0);
+    /** Don't handle fatal errors here anymore.
+     *  DLConsulting 12-07-2004
+     */
+    return false; // Indicates something very bad has happened
+  }
+
+  delete []fullpathc;
+
+  // set up the query object
+  QueryInfo queryInfo;
+  SetCStr (queryInfo.docLevel, "Document", 8);
+  queryInfo.maxDocs = 5;
+  queryInfo.sortByRank = true;
+  queryInfo.exactWeights = false;
+  queryInfo.needRankInfo = true;
+  queryInfo.needTermFreqs = true;
+  
+  // mode 1 = casefolded, unstemmed search
+  UCArray ucquery;
+  toUCArray(query, ucquery);
+  QueryNode *queryTree = ParseQuery(ucquery, 1, 1, 4);
+      
+  // perform the query
+  ExtQueryResult queryResult;
+  MGQuery (indexData, queryInfo, queryTree, queryResult);
+  // cout << "-- word lookup result -- " << endl << queryResult << endl ;
+
+  result.clear();
+  result = queryResult.docs;
+
+  // delete the query
+  if (queryTree != NULL) delete queryTree;
+
+  indexData.UnloadData();
+
+  /** This method now returns a boolean, so...
+   *  DLConsulting 12-07-2004
+   */
+  return true; // Indicates that what happened is all good, baby.
+}
+
+// Get all the data about a phrase
+//
+// The phrase is stored in textData as record phrase.
+// We retrieve:
+//   word - the text of the phrase
+//   tf - the total frequency of the phrase
+//   ef - the expansion frequency of the phrase
+//   lf - the thesaurus link frequency of the phrase
+//   df - the document frequency of the phrase
+//   el - the list of phrases that are expansions of phrase
+//   ll - the list of phrases that are thesaurus links 
+//   dl - the list of documents that contain phrase
+bool phindaction::get_phrase_all_data(TextData &textdata, unsigned long phrase,
+				      text_t &word, unsigned long &tf, unsigned long &ef,
+				      unsigned long &lf, unsigned long &df,
+				      vector <unsigned long> &el,
+				      vector <unsigned long> &linkdest,
+				      vector <UCArray> &linktype,
+				      vector <unsigned long> &docnum, 
+				      vector <unsigned long> &docfrq) {
+  UCArray text;
+  UCArray docLevel;
+  SetCStr(docLevel, "Document", 8);
+
+  // Look the word up in the textData
+  if (!GetDocText (textdata, docLevel, phrase, text)) {
+    //    FatalError (1, "Error while trying to get phrase %u", phrase);
+    //exit(0);
+    return false; // Something very bad has happened.
+  }
+
+  // Ignore everything up to the first colon
+  UCArray::iterator next = text.begin();
+  while (*next++ != ':');
+
+  // ignore training carriage returns
+  while (text.back() == '\n') {
+    text.pop_back();
+  }
+  
+  // Get the word
+  word.clear();
+  for (; *next != ':'; ++next) {
+    word.push_back(*next);
+  }
+  
+  // Get total frequency
+  tf = 0;
+  for (++next; *next != ':'; ++next) {
+    tf *= 10;
+    tf += (*next - '0');
+  }
+  
+  // Get expansion frequency
+  ef = 0;
+  for (++next; *next != ':'; ++next) {
+    ef *= 10;
+    ef += (*next - '0');
+  }
+  
+  // Get document frequency
+  df = 0;
+  for (++next; *next != ':'; ++next) {
+    df *= 10;
+    df += (*next - '0');
+  }
+  
+  // Get expansion list
+  el.clear();
+  unsigned long e = 0;
+  for (++next; *next != ':'; ++next) {
+    if (*next == ',') {
+      el.push_back(e);
+      e = 0;
+    } else {
+      e *= 10;
+      e += (*next - '0');
+    }
+  }
+
+  // Get document list & the document frequency list
+  docnum.clear();
+  docfrq.clear();
+  bool readnum = false;
+  unsigned long d = 0;
+  for (++next; *next != ':'; ++next) {
+    if (*next == ',') {
+      docnum.push_back(d);
+      readnum = true;
+      d = 0;
+    } else if (*next == ';') {
+      if (readnum) {
+	docfrq.push_back(d);
+      } else {
+	docnum.push_back(d);
+	docfrq.push_back(1);
+      }
+      readnum = false;
+      d = 0;
+    } else {
+      d *= 10;
+      d += (*next - '0');
+    }
+  }
+
+  // Get thesaurus link frequency & link list
+  text.push_back(':');
+  text.push_back(':');
+
+  // link frequency
+  lf = 0;
+  for (++next; *next != ':'; ++next) {
+    lf *= 10;
+    lf += (*next - '0');
+  }
+
+  // two lists of link data
+  linkdest.clear();
+  linktype.clear();
+  
+  UCArray thistype;
+  thistype.clear();
+  bool typedone = false;
+  unsigned long l = 0;
+  for (++next; *next != ':'; ++next) {
+    
+    if (!typedone) {
+      // first read the link type, a charactor string
+      if (*next == ',') {
+	typedone = true;
+      } else {
+	thistype.push_back(*next);
+      }
+    } else {
+      // having read the link type, read the list of link destinations
+      if (*next == ',') {
+	linkdest.push_back(l);
+	linktype.push_back(thistype);
+	l = 0;
+      } else if (*next == ';') {
+	linkdest.push_back(l);
+	linktype.push_back(thistype);
+	l = 0;
+	thistype.clear();
+	typedone = false;
+      } else {
+	l *= 10;
+	l += (*next - '0');
+      }
+    }
+  }
+
+  return true; // Indicates that what happened is all good, baby.
+}
+
+bool phindaction::print_thesaurus_links(const text_t &collection, bool XMLmode, 
+					TextData &textdata, vector <unsigned long> &linkdest,
+					vector <UCArray> &linktype, unsigned long first,
+					unsigned long last, displayclass &disp, 
+					outconvertclass &outconvert, ostream &textout) {
+
+  // information describing each link in the list
+  unsigned long phrase, tf, ef, df;
+  UCArray type, text;
+  
+  for (unsigned long l = first; l < last; ++l) {
+
+    // get the phrase data
+    phrase = linkdest[l];
+    type = linktype[l];
+
+    /** DLConsulting 12-07-2004 */
+    if(!get_phrase_freq_data(textdata, phrase, text, tf, ef, df)) {
+      return false;
+    }
+    
+    if (XMLmode) {
+      textout << "<thesaurus num=\"" << l 
+	      << "\" id=\"" << phrase
+	      << "\" tf=\"" << tf 
+	      << "\" df=\"" << df
+	      << "\" type=\"" << type
+	      << "\" text=\"" << text
+	      << "\"/>\n";
+    } else {
+      textout << "<tr valign=top><td>" << type << "</td><td>";
+      textout << outconvert << disp
+	      << "<a href=\"_gwcgi_?c=" << collection;
+      textout << "&ppnum=" << phrase << "\">" << text << "</a>"
+	      << "</td><td>" << tf << "</td><td>" << df << "</td></tr>\n";
+    }
+  }
+
+  /** DLConsulting 12-07-2004 */
+  return true;
+}
+
+// Get the frequency data about a phrase
+//
+// The phrase is stored in textData as record phrase.
+// We retrieve:
+//   word - the text of the phrase
+//   tf - the total frequency of the phrase
+//   ef - the expansion frequency of the phrase
+//   df - the document frequency of the phrase
+/**
+ *   Returns:
+ *     false if the method suffered a fatal error, true otherwise
+ */
+bool phindaction::get_phrase_freq_data(TextData &textdata, unsigned long phrase,
+				       UCArray &word, unsigned long &tf, 
+				       unsigned long &ef, unsigned long &df) {
+  
+  UCArray text;
+  UCArray docLevel;
+  SetCStr(docLevel, "Document", 8);
+
+  // Look the word up in the textData
+  if (!GetDocText (textdata, docLevel, phrase, text)) {
+    //    FatalError (1, "Error while trying to get phrase %u", phrase);
+    //exit(0);
+    /** DLConsulting 12-07-2004 */
+    return false;
+  }
+
+  // Ignore everything up to the first colon
+  UCArray::iterator next = text.begin();
+  while (*next++ != ':');
+  
+  // Get the word
+  word.clear();
+  for (; *next != ':'; ++next) {
+    word.push_back(*next);
+  }
+  
+  // Get total frequency
+  tf = 0;
+  for (++next; *next != ':'; ++next) {
+    tf *= 10;
+    tf += (*next - '0');
+  }
+  
+  // Get expansion frequency
+  ef = 0;
+  for (++next; *next != ':'; ++next) {
+    ef *= 10;
+    ef += (*next - '0');
+  }
+  
+  // Get document frequency
+  df = 0;
+  for (++next; *next != ':'; ++next) {
+    df *= 10;
+    df += (*next - '0');
+  }
+
+  /** DLConsulting 12-07-2004 */
+  return true;
+}
+
+// Print a list of expansions
+//
+// Given the textData and a list of phrase numbers, print out each of the
+// expansions.
+void phindaction::print_expansions(const text_t &collection, bool XMLmode, 
+				   const text_t &body, TextData &textdata, 
+				   const vector <unsigned long> &elist,
+				   unsigned long first, unsigned long last,
+				   displayclass &disp, outconvertclass &outconvert,
+				   ostream &textout) {
+  
+  UCArray word;
+  unsigned long phrase, tf, df, ef;
+
+  UCArray suffix, prefix, ucbody;
+  
+  toUCArray(body, ucbody);
+
+  for (unsigned long e = first; e < last; ++e) {
+
+    phrase = elist[e];
+    get_phrase_freq_data(textdata, phrase, word, tf, ef, df);
+
+    split_phrase(word, ucbody, prefix, suffix);
+    
+    if (XMLmode) {
+      // body is always the same as the text of the phrase, so no need to send it
+      textout << "<expansion num=\"" << e 
+	      << "\" id=\"" << phrase
+	      << "\" tf=\"" << tf 
+	      << "\" df=\"" << df;
+      if (!prefix.empty()) {
+	textout << "\" prefix=\"" << prefix;
+      }
+      if (!suffix.empty()) {
+	textout << "\" suffix=\"" << suffix;
+      }
+      textout << "\"/>\n";
+    } else {
+      textout << outconvert << disp 
+	      << "<tr valign=top><td align=right><a href=\"_gwcgi_?"
+	      << "c=" << collection << "&ppnum=" << phrase << "\">";
+      textout << prefix << "</a></td>";
+      textout <<outconvert << disp
+	      << "<td align=center><a href=\"_gwcgi_?"
+	      << "c=" << collection << "&ppnum=" << phrase << "\">"
+	      << body << "</a></td>"
+	      << "<td align=left><a href=\"_gwcgi_?"
+	      << "c=" << collection << "&ppnum=" << phrase << "\">";
+      textout << suffix << "</a></td>"
+	      << "<td>" << tf << "</td><td>" << df << "</td></tr>\n";
+    }
+  }
+}
+
+// split an expansion into prefix and suffix
+void phindaction::split_phrase(const UCArray &word, const UCArray &body, 
+			       UCArray &prefix, UCArray &suffix) {
+
+  prefix.clear();
+  suffix.clear();
+
+  bool readingPrefix = true;
+  UCArray::const_iterator here = word.begin();
+  UCArray::const_iterator end = word.end();
+  
+  while (here != end) {
+
+    // if we've not read all the prefix, add the next char to the prefix
+    if (readingPrefix) {
+      if (phrase_match(body, here, end)) {
+	readingPrefix = false;
+	// trim whitespace from end of prefix & start of suffix
+	if (!prefix.empty()) {
+	  prefix.pop_back();
+	}
+	if ((here != end) && (*here == ' ')) {
+	  ++here;
+	}
+      } else {
+	prefix.push_back(*here);
+	++here;
+      }
+    }
+    // if we've finished with the prefix, update the suffix
+    else {
+      suffix.push_back(*here);
+      ++here;
+    }
+  }
+}
+
+// phrase_match
+//
+// compare two strings, one represented as an UCArray, the other as two
+// UCArray iterators.
+//
+// Return true if the UCArray is the same as the phrase the iterators point
+// to for the length of the UCArray.
+bool phindaction::phrase_match(const UCArray &text, UCArray::const_iterator &here, 
+			       UCArray::const_iterator end) {
+
+  UCArray::const_iterator one_here = text.begin();
+  UCArray::const_iterator one_end  = text.end();
+  UCArray::const_iterator two_here = here;
+
+  // iterate over the length of the first string, comparing each element to
+  // the corresponding element in the second string.
+  while (one_here != one_end) {
+   
+      if (two_here == end) {
+	  return false;
+      } else if (*one_here != *two_here) {
+	  return false;
+      }
+      ++one_here;
+      ++two_here;
+  }
+
+  here = two_here;
+  return true;
+}
+
+bool phindaction::print_documents(bool XMLmode, const text_t &basepath, 
+				  const text_t &collection,
+				  const vector <unsigned long> &docNums, 
+				  const vector <unsigned long> &docFreq,
+				  unsigned long first, unsigned long last,
+				  displayclass &disp, outconvertclass &outconvert,
+				  ostream &textout) {
+  
+  // Create a TextData object to read the document data
+  TextData docdata;
+
+  text_t fullpath = filename_cat(basepath, "docs");
+  char *fullpathc = fullpath.getcstr();
+#if defined __WIN32__
+  char *base = "";
+#else
+  char *base = "/";
+#endif
+
+  if (!docdata.LoadData (base, fullpathc)) {
+    //    FatalError (1, "Couldn't load text information for \"%s\"", fullpathc);
+    //exit(0);
+    /** DLConsulting 12-07-2004 */
+    return false;
+  }
+
+  delete []fullpathc;
+
+  UCArray title, hash;
+  unsigned long freq, doc;
+
+  for (unsigned long d = first; d < last; ++d) {
+    doc = docNums[d];
+    freq = docFreq[d];
+
+    /** DLConsulting 13-07-2004 */
+    if(!get_document_all_data(docdata, doc, title, hash)) {
+      return false;
+    }
+
+    if (XMLmode) {
+      textout << "<document num=\"" << d
+	      << "\" hash=\"" << hash 
+	      << "\" freq=\"" << freq 
+	      << "\" title=\"" << title << "\"/>\n";
+    } else {
+      textout << outconvert << disp
+	      << "<tr valign=top><td><a href=\"_gwcgi_?"
+	      << "c=" << collection;
+      textout << "&a=d&d=" << hash << "\">" << title << "</a>"
+	      << "</td><td>" << freq << "</td></tr>\n"; 
+    }
+  }
+
+  docdata.UnloadData();
+
+  /** DLConsulting 12-07-2004 */
+  return true;
+}
+
+// Get all the data about a docment
+//
+// The document's details are stored in docData as record docNum.
+// We retrieve:
+//   title - the document's title
+//   hash - the document's unique OID
+/** Returns:
+ *   false if a fatal error occured, true otherwise
+ *  DLConsulting 12-07-2004
+ */
+bool phindaction::get_document_all_data(TextData &docdata, unsigned long docNum,
+					UCArray &title, UCArray &hash) {
+
+  UCArray text;
+  UCArray docLevel;
+  SetCStr(docLevel, "Document", 8);
+
+  // Look the word up in the textData
+  if (!GetDocText (docdata, docLevel, docNum, text)) {
+    //    FatalError (1, "Error while trying to get document %u", docNum);
+    //exit(0);
+    /** DLConsulting 13-07-2004 */
+    return false;
+  }
+
+  // Ignore everything up to the first colon
+  UCArray::iterator next = text.begin();
+  while (*next++ != '\t');
+  
+  // Get the document OID (hash)
+  hash.clear();
+  for (; *next != '\t'; ++next) {
+    hash.push_back(*next);
+  }
+
+  // Get the title
+  text.push_back('\n');
+  title.clear();
+  for (++next; *next != '\n'; ++next) {
+    title.push_back(*next);
+  }
+
+  /** DLConsulting 13-07-2004 */
+  return true;
+}
+
+void phindaction::toUCArray(const text_t &in, UCArray &out) {
+  out.clear();
+  if (out.capacity() < in.size() + 1) {
+    out.reserve(in.size() + 1);
+  }
+  text_t::const_iterator here = in.begin();
+  text_t::const_iterator end = in.end();
+  while (here != end) {
+    out.push_back((unsigned char) *here);
+    ++here;
+  }
+}
+
+void phindaction::output_error (const text_t &message, ostream &textout, 
+				outconvertclass &outconvert,
+				displayclass & disp, ostream &logout,
+				bool XMLmode) {
+
+  logout << outconvert << message << "\n";
+  if (XMLmode) {
+    textout << outconvert
+	    << "<phinddata>\n"
+	    << "<phinderror>" << message << "</phinderror>\n"
+	    << "</phinddata>\n";
+  } else {
+    textout << outconvert << disp 
+	    << "_header_\n" 
+	    << message
+	    << "_footer_\n";
+  }
+}
+
+#endif //GSDL_USE_PHIND_ACTION
+
Index: /gsdl/stable/runtime-src/src/recpt/phindaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/phindaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/phindaction.h	(revision 20131)
@@ -0,0 +1,122 @@
+/**********************************************************************
+ *
+ * phindaction.h -- 
+ *
+ * Copyright 2001 Gordon W. Paynter
+ * Copyright 2001 The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_PHIND_ACTION
+
+#ifndef PHINDACTION_H
+#define PHINDACTION_H
+
+#include "action.h"
+
+// Include MGPP functionality.
+#include <TextGet.h>
+#include <MGQuery.h>
+#include <Terms.h>
+#include <messages.h>
+#include <GSDLQueryParser.h>
+
+class phindaction : public action {
+  
+protected:
+
+  bool find_phrase_number_from_word(const text_t &basepath, 
+				    const text_t &query, 
+				    DocNumArray &result);
+
+  bool get_phrase_all_data(TextData &textdata, unsigned long phrase,
+			   text_t &word, unsigned long &tf, unsigned long &ef,
+			   unsigned long &lf, unsigned long &df,
+			   vector <unsigned long> &el,
+			   vector <unsigned long> &linkdest,
+			   vector <UCArray> &linktype,
+			   vector <unsigned long> &docnum, 
+			   vector <unsigned long> &docfrq);
+
+  bool print_thesaurus_links(const text_t &collection, bool XMLmode, 
+			     TextData &textdata, vector <unsigned long> &linkdest,
+			     vector <UCArray> &linktype, unsigned long first,
+			     unsigned long last, displayclass &disp, 
+			     outconvertclass &outconvert, ostream &textout);
+
+  bool get_phrase_freq_data(TextData &textdata, unsigned long phrase,
+			    UCArray &word, unsigned long &tf, 
+			    unsigned long &ef, unsigned long &df);
+
+  void print_expansions(const text_t &collection, bool XMLmode, 
+			const text_t &body, TextData &textdata, 
+			const vector <unsigned long> &elist,
+			unsigned long first, unsigned long last,
+			displayclass &disp, outconvertclass &outconvert,
+			ostream &textout);
+
+  void split_phrase(const UCArray &word, const UCArray &body, 
+		    UCArray &prefix, UCArray &suffix);
+
+  bool phrase_match(const UCArray &text, UCArray::const_iterator &here, 
+		    UCArray::const_iterator end);
+
+  bool print_documents(bool XMLmode, const text_t &basepath, 
+		       const text_t &collection,
+		       const vector <unsigned long> &docNums, 
+		       const vector <unsigned long> &docFreq,
+		       unsigned long first, unsigned long last,
+		       displayclass &disp, outconvertclass &outconvert,
+		       ostream &textout);
+
+  bool get_document_all_data(TextData &docdata, unsigned long docNum,
+			     UCArray &title, UCArray &hash);
+
+  void toUCArray(const text_t &in, UCArray &out);
+
+  void output_error (const text_t &message, ostream &textout, 
+		     outconvertclass &outconvert,
+		     displayclass & disp, ostream &logout,
+		     bool XMLmode);
+
+
+public:
+  phindaction ();
+  virtual ~phindaction ();
+
+  text_t get_action_name () {return "phind";}
+
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response,text_t &response_data, 
+			 ostream &logout);
+
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+
+
+};
+
+#endif //!PHINDACTION_H
+#endif //GSDL_USE_PHIND_ACTION
+
Index: /gsdl/stable/runtime-src/src/recpt/phindbrowserclass.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/phindbrowserclass.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/phindbrowserclass.cpp	(revision 20131)
@@ -0,0 +1,51 @@
+/**********************************************************************
+ *
+ * phindbrowserclass.cpp -- 
+ *
+ * Copyright (C) 2000 The New Zealand Digital Library Project
+ *
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_PHIND_BROWSER
+
+#include "phindbrowserclass.h"
+#include <assert.h>
+#include "OIDtools.h"
+
+phindbrowserclass::phindbrowserclass () {
+}
+
+phindbrowserclass::~phindbrowserclass () {
+}
+
+// returns the name that specifies the browserclass type
+text_t phindbrowserclass::get_browser_name () {
+  return "Phind";
+}
+
+browserclass* phindbrowserclass::clone()
+{
+  return new phindbrowserclass();
+}
+
+#endif //GSDL_USE_PHIND_BROWSER
Index: /gsdl/stable/runtime-src/src/recpt/phindbrowserclass.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/phindbrowserclass.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/phindbrowserclass.h	(revision 20131)
@@ -0,0 +1,59 @@
+/**********************************************************************
+ *
+ * phindbrowserclass.h -- 
+ *
+ * Copyright (C) 2000 The New Zealand Digital Library Project
+ *
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_PHIND_BROWSER
+
+// The phindbrowserclass is necessary to add a phind classifier to the user
+// interface and navigation bar, but is basically empty - all the work is
+// done in documentaction.cpp and in the document.dm macro file.  What
+// happens is that documentaction.cpp has a section that sets various
+// macros when the document in question is a phind classifier; thse are in
+// turn used by the macro file to load the applet into the web page.
+
+#ifndef PHINDBROWSERCLASS_H
+#define PHINDBROWSERCLASS_H
+
+#include "browserclass.h"
+
+class phindbrowserclass : public browserclass {
+protected:
+
+public:
+
+  phindbrowserclass ();
+  virtual ~phindbrowserclass ();
+
+  // returns the name that specifies the browserclass type
+  virtual text_t get_browser_name ();
+
+  virtual browserclass* clone();
+
+};
+
+#endif //!PHINDBROWSERCLASS_H
+#endif //GSDL_USE_PHIND_BROWSER
Index: /gsdl/stable/runtime-src/src/recpt/pingaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/pingaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/pingaction.cpp	(revision 20131)
@@ -0,0 +1,87 @@
+/**********************************************************************
+ *
+ * pingaction.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_PING_ACTION
+
+#include "pingaction.h"
+
+pingaction::pingaction () {
+  // this action uses cgi variable "a"
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "a";
+  arg_ainfo.longname = "action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "ping";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+}
+
+void pingaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
+				   response_t &response, text_t &response_data, 
+				   ostream &/*logout*/) {
+  response = content;
+  response_data = "text/html";
+}
+
+
+bool pingaction::do_action (cgiargsclass &args, recptprotolistclass *protos, 
+			    browsermapclass * /*browsers*/, displayclass &/*disp*/, 
+			    outconvertclass &outconvert, ostream &textout, 
+			    ostream &logout) {
+  bool wassuccess = false;
+  comerror_t err;
+  
+  recptproto *collectproto = protos->getrecptproto (args["c"], logout);
+  if (!args["c"].empty() && (collectproto != NULL)) {
+    collectproto->ping (args["c"], wassuccess, err, logout);
+    if (err != noError) wassuccess = false; // a communication error
+  }
+
+  textout << outconvert
+	  << "<html>\n"
+	  << "<head>\n"
+	  << "<title>Ping</title>\n"
+	  << "</head>\n"
+	  << "<body>\n"
+	  << "Ping for \"" << args["c"] << "\" ";
+
+  if (wassuccess) {
+    textout << outconvert << " succeeded.\n";
+  } else {
+    textout << outconvert << " did not succeed.\n";
+  }
+
+  textout << outconvert 
+	  << "</body>\n"
+	  << "</html>\n";
+
+  return true;
+};
+
+#endif //GSDL_USE_PING_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/pingaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/pingaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/pingaction.h	(revision 20131)
@@ -0,0 +1,55 @@
+/**********************************************************************
+ *
+ * pingaction.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_PING_ACTION
+
+#ifndef PINGACTION_H
+#define PINGACTION_H
+
+#include "gsdlconf.h"
+#include "action.h"
+
+
+class pingaction : public action {
+public:
+  pingaction ();
+  virtual ~pingaction () {}
+
+  text_t get_action_name () {return "ping";}
+
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response, text_t &response_data, 
+			 ostream &logout);
+
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+};
+
+
+#endif //!PINGACTION_H
+#endif //GSDL_USE_PING_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/queryaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/queryaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/queryaction.cpp	(revision 20131)
@@ -0,0 +1,1826 @@
+/**********************************************************************
+ *
+ * queryaction.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "queryaction.h"
+#include "querytools.h"
+#include "formattools.h"
+#include "cgiutils.h"
+#include "OIDtools.h"
+#include "fileutil.h"
+#include "text_t.h"
+#include "historydb.h"
+#include "htmlutils.h" // for html_safe in do_action
+#include "gsdltools.h"
+#include "phrases.h" // for get_phrases
+#include <stdlib.h> // for strtol
+#include <assert.h>
+
+void colinfo_t::clear () {
+  formatlistptr = NULL;
+  browserptr = NULL;
+}
+
+void QueryResult_t::clear() {
+  doc.clear();
+  collection.clear();
+}
+
+queryaction::queryaction () {
+
+  recpt = NULL;
+  num_phrases = 0;
+
+  // this action uses cgi variable "a"
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "a";
+  arg_ainfo.longname = "action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "q";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+  
+   // "ct" - 0 = mg, 1 = mgpp, 2=lucene
+  arg_ainfo.shortname = "ct";
+  arg_ainfo.longname = "collection type";
+  arg_ainfo.multiplechar = true; // can be empty or single char
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+ 
+  // "b" - 0 = simple, 1 = advanced
+  arg_ainfo.shortname = "b";
+  arg_ainfo.longname = "query mode";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "h"
+  arg_ainfo.shortname = "h";
+  arg_ainfo.longname = "main index";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "h2"
+  arg_ainfo.shortname = "h2";
+  arg_ainfo.longname = "main index for second query";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "j"
+  arg_ainfo.shortname = "j";
+  arg_ainfo.longname = "sub collection index";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "j2"
+  arg_ainfo.shortname = "j2";
+  arg_ainfo.longname = "sub collection index for second query";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "n"
+  arg_ainfo.shortname = "n";
+  arg_ainfo.longname = "language index";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "n2"
+  arg_ainfo.shortname = "n2";
+  arg_ainfo.longname = "language index for second query";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+
+  // "q"
+  arg_ainfo.shortname = "q";
+  arg_ainfo.longname = "query string";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "q2"
+  arg_ainfo.shortname = "q2";
+  arg_ainfo.longname = "query string for second query";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "cq2" ""=don't combine, "and", "or", "not"
+  arg_ainfo.shortname = "cq2";
+  arg_ainfo.longname = "combine queries";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "t" - 1 = ranked 0 = boolean
+  arg_ainfo.shortname = "t";
+  arg_ainfo.longname = "search type";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "1";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "k"
+  arg_ainfo.shortname = "k";
+  arg_ainfo.longname = "casefolding";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "1";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "ks"
+  arg_ainfo.shortname = "ks";
+  arg_ainfo.longname = "casefolding support";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+  
+  // "s"
+  arg_ainfo.shortname = "s";
+  arg_ainfo.longname = "stemming";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "ss"
+  arg_ainfo.shortname = "ss";
+  arg_ainfo.longname = "stemming support";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "af"
+  arg_ainfo.shortname = "af";
+  arg_ainfo.longname = "accentfolding";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "afs"
+  arg_ainfo.shortname = "afs";
+  arg_ainfo.longname = "accentfolding support";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+ 
+  // "m"
+  arg_ainfo.shortname = "m";
+  arg_ainfo.longname = "maximum number of documents";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "50";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "o"
+  arg_ainfo.shortname = "o";
+  arg_ainfo.longname = "hits per page";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "20";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "r"
+  arg_ainfo.shortname = "r";
+  arg_ainfo.longname = "start results from";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "1";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "ccs"
+  arg_ainfo.shortname = "ccs";
+  arg_ainfo.longname = "cross collection searching";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "ccp"
+  arg_ainfo.shortname = "ccp";
+  arg_ainfo.longname = "cross collection page";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "cc"
+  arg_ainfo.shortname = "cc";
+  arg_ainfo.longname = "collections to search";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.multiplevalue = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "hd" history display  - search history only displayed when
+  // this var set to something other than 0
+  // this number of records is displayed
+  arg_ainfo.shortname = "hd";
+  arg_ainfo.longname = "history display";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.multiplevalue = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+	    
+  // "hs"  save - set to 1 in query form, so only save when submit
+  // query
+  // 0 = no save 1 = save
+  arg_ainfo.shortname = "hs";
+  arg_ainfo.longname = "history save";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "g" - new arg for granularity, for mgpp collections
+  arg_ainfo.shortname = "g";
+  arg_ainfo.longname = "granularity";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText; 
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "ds" - start date
+  arg_ainfo.shortname = "ds";
+  arg_ainfo.longname = "start date";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "de" - end date
+  arg_ainfo.shortname = "de";
+  arg_ainfo.longname = "end date";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "dsbc" - whether or not start date is prechristian
+  arg_ainfo.shortname = "dsbc";
+  arg_ainfo.longname = "start date bc";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "debc" - whether or not end date is prechristian
+  arg_ainfo.shortname = "debc";
+  arg_ainfo.longname = "end date bc";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "qt" - 0 = text, 1 = form
+  arg_ainfo.shortname = "qt";
+  arg_ainfo.longname = "query type";
+  arg_ainfo.multiplechar = true; // can be empty or single char
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "qto" - 1 = text only, 2 = form only, 3 = text and form
+  arg_ainfo.shortname = "qto";
+  arg_ainfo.longname = "query type options";
+  arg_ainfo.multiplechar = true; // can be empty or single char
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+    
+  // "qb" - 0 = regular, 1 = large
+  arg_ainfo.shortname = "qb";
+  arg_ainfo.longname = "query box type";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "fqn" - number of fields in the query form
+  arg_ainfo.shortname = "fqn";
+  arg_ainfo.longname = "form query num fields";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "4";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "fqf" - the list of field names in the form query
+  // - a comma separated list
+  arg_ainfo.shortname = "fqf";
+  arg_ainfo.longname = "form query fields";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+  
+  // "fqv" - the list of values in the form query
+  // - a comma separated list
+  arg_ainfo.shortname = "fqv";
+  arg_ainfo.longname = "form query values";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+  
+
+  // "fqs" - the list of stemming options in the form query
+  // - a comma separated list
+  arg_ainfo.shortname = "fqs";
+  arg_ainfo.longname = "form query stems";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+  
+
+  // "fqk" - the list of casefolding options in the form query
+  // - a comma separated list
+  arg_ainfo.shortname = "fqk";
+  arg_ainfo.longname = "form query casefolds";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+  
+  // "fqc" - the list of boolean operators in the form query
+  // - a comma separated list
+  arg_ainfo.shortname = "fqc";
+  arg_ainfo.longname = "form query combines";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "fqa" - form query advanced - for "run query"
+  arg_ainfo.shortname = "fqa";
+  arg_ainfo.longname = "form query advanced query";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "ifl" - I'm feeling lucky! (Go directly to a matching document)
+  arg_ainfo.shortname = "ifl";
+  arg_ainfo.longname = "i'm feeling lucky";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "ifln" - I'm feeling lucky number (Go directly to the nth matching document)
+  arg_ainfo.shortname = "ifln";
+  arg_ainfo.longname = "i'm feeling lucky number";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "1";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "srn" - the next search result
+  arg_ainfo.shortname = "srn";
+  arg_ainfo.longname = "the next search result number";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "srp" - the previous search result
+  arg_ainfo.shortname = "srp";
+  arg_ainfo.longname = "the previous search result number";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "sf" - Sort field. Set to field to be used for sorting search reult
+  // set (only implemented for lucene collections at present).
+  arg_ainfo.shortname = "sf";
+  arg_ainfo.longname = "sort field";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "fuzziness" controls how closely the search terms must match
+  // 100 = exact match, 0 = very inexact match (only implemented for Lucene)
+  arg_ainfo.shortname = "fuzziness";
+  arg_ainfo.longname = "Lucene fuzziness value";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+}
+
+void queryaction::configure (const text_t &key, const text_tarray &cfgline) {
+  action::configure (key, cfgline);
+}
+
+bool queryaction::init (ostream &logout) {
+  return action::init (logout);
+}
+
+bool queryaction::check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+				 recptprotolistclass * /*protos*/, ostream &logout) {
+
+  // check t argument
+  int arg_t = args.getintarg("t");
+  if (arg_t != 0 && arg_t != 1) {
+    logout << "Warning: \"t\" argument out of range (" << arg_t << ")\n";
+    cgiarginfo *tinfo = argsinfo.getarginfo ("t");
+    if (tinfo != NULL) args["t"] = tinfo->argdefault;
+  }
+
+  // check k argument
+  int arg_k = args.getintarg("k");
+  if (arg_k != 0 && arg_k != 1) {
+    logout << "Warning: \"k\" argument out of range (" << arg_k << ")\n";
+    cgiarginfo *kinfo = argsinfo.getarginfo ("k");
+    if (kinfo != NULL) args["k"] = kinfo->argdefault;
+  }
+
+  // check s argument
+  int arg_s = args.getintarg("s");
+  if (arg_s != 0 && arg_s != 1) {
+    logout << "Warning: \"s\" argument out of range (" << arg_s << ")\n";
+    cgiarginfo *sinfo = argsinfo.getarginfo ("s");
+    if (sinfo != NULL) args["s"] = sinfo->argdefault;
+  }
+
+  // check m argument
+  int arg_m = args.getintarg("m");
+  if (arg_m < -1) {
+    logout << "Warning: \"m\" argument less than -1 (" << arg_m << ")\n";
+    cgiarginfo *minfo = argsinfo.getarginfo ("m");
+    if (minfo != NULL) args["m"] = minfo->argdefault;
+  }
+
+  // check o argument
+  int arg_o = args.getintarg("o");
+  if (arg_o < -1) {
+    logout << "Warning: \"o\" argument less than -1 (" << arg_o << ")\n";
+    cgiarginfo *oinfo = argsinfo.getarginfo ("o");
+    if (oinfo != NULL) args["o"] = oinfo->argdefault;
+  }
+
+  // check r argument
+  int arg_r = args.getintarg("r");
+  if (arg_r < 1) {
+    logout << "Warning: \"r\" argument less than 1 (" << arg_r << ")\n";
+    cgiarginfo *rinfo = argsinfo.getarginfo ("r");
+    if (rinfo != NULL) args["r"] = rinfo->argdefault;
+  }
+  //check hd argument
+  int arg_hd = args.getintarg("hd");
+  if (arg_hd <0 ) {
+    logout << "Warning: \"hd\" argument less than 0 (" << arg_hd << ")\n";
+    cgiarginfo *hdinfo = argsinfo.getarginfo ("hd");
+    if (hdinfo != NULL) args["hd"] = hdinfo->argdefault;
+  }  
+  
+  //check hs argument
+  int arg_hs = args.getintarg("hs");
+  if (arg_hs !=0 && arg_hs !=1) {
+    logout << "Warning: \"hs\" argument out of range (" << arg_hs << ")\n";
+    cgiarginfo *hsinfo = argsinfo.getarginfo ("hs");
+    if (hsinfo != NULL) args["hs"] = hsinfo->argdefault;
+  }
+
+  // check ct argument
+  int arg_ct = args.getintarg("ct");
+  if (arg_ct < 0 || arg_ct > 2) {
+    logout << "Warning: \"ct\" argument out of range (" << arg_ct << ")\n";
+    cgiarginfo *ctinfo = argsinfo.getarginfo ("ct");
+    if (ctinfo != NULL) args["ct"] = ctinfo->argdefault;
+  }
+
+  // check qt argument
+  int arg_qt = args.getintarg("qt");
+  if (arg_qt !=0 && arg_qt !=1) {
+    logout << "Warning: \"qt\" argument out of range (" << arg_qt << ")\n";
+    cgiarginfo *qtinfo = argsinfo.getarginfo ("qt");
+    if (qtinfo != NULL) args["qt"] = qtinfo->argdefault;
+  }
+
+  // check qb argument
+  int arg_qb = args.getintarg("qb");
+  if (arg_qb !=0 && arg_qb !=1) {
+    logout << "Warning: \"qb\" argument out of range (" << arg_qb << ")\n";
+    cgiarginfo *qbinfo = argsinfo.getarginfo ("qb");
+    if (qbinfo != NULL) args["qb"] = qbinfo->argdefault;
+  }
+
+  // check fqa argument
+  int arg_fqa = args.getintarg("fqa");
+  if (arg_fqa !=0 && arg_fqa !=1) {
+    logout << "Warning: \"fqa\" argument out of range (" << arg_fqa << ")\n";
+    cgiarginfo *fqainfo = argsinfo.getarginfo ("fqa");
+    if (fqainfo != NULL) args["fqa"] = fqainfo->argdefault;
+  }
+
+  // check fqn argument
+  int arg_fqn = args.getintarg("fqn");
+  if (arg_fqn < -1) {
+    logout << "Warning: \"fqn\" argument less than -1 (" << arg_fqn << ")\n";
+    cgiarginfo *fqninfo = argsinfo.getarginfo ("fqn");
+    if (fqninfo != NULL) args["fqn"] = fqninfo->argdefault;
+  }
+
+  return true;
+}
+
+void queryaction::get_cgihead_info (cgiargsclass &args, recptprotolistclass * /*protos*/,
+				    response_t &response, text_t &response_data, 
+				    ostream &/*logout*/) {
+  // If this is an "I'm feeling lucky" request, we don't know the target location until later
+  if (!args["ifl"].empty()) {
+    response = undecided_location;
+    return;
+  }
+
+  response = content;
+  response_data = "text/html";
+}
+
+void queryaction::define_internal_macros (displayclass &disp, cgiargsclass &args, 
+					  recptprotolistclass * protos, 
+					  ostream &logout) {
+
+  // define_internal_macros sets the following macros:
+
+  // The following macros are set later (in define_query_macros) as they can't be set until 
+  // the query has been done.
+  // _quotedquery_   the part of the query string that was quoted for post-processing
+  // _freqmsg_      the term frequency string
+
+  // _resultline_   the "x documents matched the query" string
+
+  // _prevfirst_    these are used when setting up the links to previous/next
+  // _prevlast_     pages of results (_thisfirst_ and _thislast_ are used to set
+  // _nextfirst_    the 'results x-x for query: xxxx' string in the title bar)
+  // _nextlast_
+  // _thisfirst_
+  // _thislast_
+
+  
+  define_form_macros(disp, args, protos, logout);
+  
+  define_query_interface(disp, args, protos, logout);
+
+
+}
+
+void queryaction::define_query_interface(displayclass &disp, 
+					 cgiargsclass &args, 
+					 recptprotolistclass * protos, 
+					 ostream &logout){
+  text_t collection = args["c"];
+
+  //check that the protocol is alive
+  recptproto* colproto = protos->getrecptproto (collection, logout);
+  if(colproto == NULL) {
+    logout << "ERROR: Null collection protocol trying to query"
+	   << collection.getcstr() << "\n";
+    return;
+  }
+  
+  //check the collection is responding/in place
+  ColInfoResponse_t *colinfo = recpt->get_collectinfo_ptr(colproto, collection,
+							  logout);
+  if(colinfo == NULL){
+    logout << "ERROR: Null returned for get_collectinfo_ptr on "
+	   << collection.getcstr() << "in queryaction::define_query_interface\n";
+    return;
+  }
+   
+  text_tmap::iterator check = colinfo->format.find("QueryInterface");
+  if(check != colinfo->format.end()){
+    if((*check).second=="DateSearch"){
+      text_t current = "_datesearch_";
+      disp.setmacro("optdatesearch","query",current);
+    }
+  }
+}
+
+
+// sets the selection box macros _hselection_, _jselection_, _nselection_ _gselection_, fqfselection_ 
+void queryaction::set_option_macro (const text_t &macroname, 
+				    text_t current_value, 
+				    bool display_single, 
+				    bool add_js_update,
+				    const FilterOption_t &option, 
+				    displayclass &disp) {
+  
+  if (option.validValues.empty()) return;
+  if (option.validValues.size() == 1) {
+    if (display_single) {
+      disp.setmacro (macroname + "selection", displayclass::defaultpackage, "_" + option.defaultValue + "_");
+    }
+    return;    
+  } 
+  if (option.validValues.size() < 2) return;
+  
+  text_t macrovalue = "<select name=\"" + macroname + "\"";
+  if (add_js_update) {
+    macrovalue += " onChange=\"update"+macroname+"();\"";
+  }
+  macrovalue += ">\n";
+  
+  if (current_value.empty()) current_value = option.defaultValue;
+  
+  text_tarray::const_iterator thisvalue = option.validValues.begin();
+  text_tarray::const_iterator endvalue = option.validValues.end();
+
+  while (thisvalue != endvalue) {
+    macrovalue += "<option value=\"" + *thisvalue + "\"";
+    if (*thisvalue == current_value)
+      macrovalue += " selected";
+    macrovalue += ">_" + *thisvalue + "_\n";
+    ++thisvalue;
+  }
+  macrovalue += "</select>\n";
+  disp.setmacro (macroname + "selection", displayclass::defaultpackage, macrovalue);
+}
+
+
+void queryaction::define_external_macros (displayclass &disp, cgiargsclass &args, 
+					  recptprotolistclass *protos, ostream &logout) {
+
+  // define_external_macros sets the following macros:
+
+  // some or all of these may not be required to be set
+  // _hselection_, _h2selection_  the selection box for the main part of the index
+  // _jselection_, _j2selection_  the selection box for the subcollection part of the index
+  // _nselection_, _n2selection_  the selection box for the language part of the index
+  // _cq2selection                the selection box for combining two queries
+  
+  // _gselection_, the selection box forlevels (mgpp)
+  // _fqfselection_, the selection box for index/fields (mgpp)
+  // can't do anything if collectproto is null (i.e. no collection was specified)
+  recptproto *collectproto = protos->getrecptproto (args["c"], logout);
+  if (collectproto == NULL) return;
+
+  ColInfoResponse_t *colinfo = recpt->get_collectinfo_ptr(collectproto, 
+							  args["c"],
+							  logout);
+  set_query_type_args(colinfo, args);
+  set_stem_index_args(colinfo, args);
+
+  comerror_t err;
+  InfoFilterOptionsResponse_t response;
+  InfoFilterOptionsRequest_t request;
+  request.filterName = "QueryFilter";
+  
+  collectproto->get_filteroptions (args["c"], request, response, err, logout);
+  if (err == noError) {
+    
+    FilterOption_tmap::const_iterator it;
+    FilterOption_tmap::const_iterator end = response.filterOptions.end();
+    
+    // _hselection_ and _h2selection_ (Index)
+    it = response.filterOptions.find ("Index");
+    if (it != end) set_option_macro ("h", args["h"], true, false, (*it).second, disp);
+    if (it != end) set_option_macro ("h2", args["h2"], true,false, (*it).second, disp);
+    
+    // _jselection_ and _j2selection_ (Subcollection)
+    it = response.filterOptions.find ("Subcollection");
+    if (it != end) set_option_macro ("j", args["j"], true,false, (*it).second, disp);
+    if (it != end) set_option_macro ("j2", args["j2"], true,false, (*it).second, disp);
+    
+    // _nselection_ and _n2selection_ (Language)
+    it = response.filterOptions.find ("Language");
+    if (it != end) set_option_macro ("n", args["n"], true,false, (*it).second, disp);
+    if (it != end) set_option_macro ("n2", args["n2"], true,false, (*it).second, disp);
+
+    // _cq2selection_ (CombineQuery)
+    it = response.filterOptions.find ("CombineQuery");
+    if (it != end) set_option_macro ("cq2", args["cq2"], true,false, (*it).second, disp);
+
+    if ((args["ct"] == "1") || (args["ct"] == "2"))  { // mgpp/lucene collections
+      // _gselection_ (Level) 
+      it = response.filterOptions.find("Level");
+      if (it!=end) {
+	set_option_macro("g", args["g"], false, false, (*it).second, disp);
+	if (args["qt"]=="1") { // form search
+	  set_gformselection_macro(args["g"], (*it).second, disp);
+	}
+      }
+      // _fqfselection_ field list
+      it = response.filterOptions.find("IndexField");
+      if (it!=end) {
+	bool form_search = false;
+	if (args["qto"]=="2" || args["qt"]=="1") { 
+	  form_search = true;
+	}
+	set_option_macro ("fqf", args["fqf"], true, form_search, (*it).second, disp);
+	if (args["ct"] == "2") {// lucene
+	  // set the sort field macro
+	  set_sfselection_macro(args["sf"], (*it).second, disp);
+	}
+      }
+    }
+  }
+} // define external macros
+  
+void queryaction::set_sfselection_macro(text_t current_value, 
+				       const FilterOption_t &option, 
+				       displayclass &disp) {
+
+  // we need at least one option here to continue
+  if (option.validValues.size() < 1) {
+    return;
+  }
+
+  text_t macrovalue = "<select name=\"sf\">\n";
+  
+  if (current_value.empty()) current_value = "";
+  
+  // we give a rank option first
+  macrovalue += "<option value=\"\"";
+  if (current_value == "") {
+    macrovalue += " selected";
+  }
+  macrovalue += ">_query:textsortbyrank_\n";
+
+  text_tarray::const_iterator thisvalue = option.validValues.begin();
+  text_tarray::const_iterator endvalue = option.validValues.end();
+  int valid_count = 0;
+  while (thisvalue != endvalue) {
+    if (*thisvalue != "ZZ" && *thisvalue != "TX") {
+      ++valid_count;
+      macrovalue += "<option value=\"by" + *thisvalue + "\"";
+      if (current_value == "by"+*thisvalue)
+	macrovalue += " selected";
+      macrovalue += ">_" + *thisvalue + "_\n";
+    }
+    ++thisvalue;
+  }
+  macrovalue += "</select>";
+  if (valid_count > 0) {
+    disp.setmacro ("sfselection", displayclass::defaultpackage, macrovalue);
+  }
+  
+}
+ 
+// sets the selection box macro _gformselection_.
+// the default for _gformselection_ is _gselection_
+void queryaction::set_gformselection_macro (text_t current_value,
+					const FilterOption_t &option,
+					displayclass &disp) {
+  
+  if (option.validValues.size() <= 1) {
+    return;
+  }
+  // we need to check to see if there is paragraph present
+  text_tarray::const_iterator thisvalue = option.validValues.begin();
+  text_tarray::const_iterator endvalue = option.validValues.end();
+
+  bool has_paras = false;
+  while (thisvalue != endvalue) {
+    if (*thisvalue == "Para") {
+      has_paras = true;
+      break;
+    }
+    ++thisvalue;
+  }
+  if (!has_paras) return; // there is no difference between the form selection and the normal one
+
+  if (option.validValues.size() == 2) {
+    // we will only have one value, but we will still put it in as a text string
+    int opt = 0;
+    if (option.validValues[0] == "Para") {
+      opt = 1;
+    }
+    disp.setmacro ("gformselection", displayclass::defaultpackage, "_"+option.validValues[opt]+"_");
+    return;
+  }
+
+  // there will be a select box
+  text_t macrovalue = "<select name=\"g\">\n";
+
+  if (current_value.empty()) current_value = option.defaultValue;
+  
+  thisvalue = option.validValues.begin();
+  
+  while (thisvalue != endvalue) {
+    if (*thisvalue != "Para") {
+      macrovalue += "<option value=\"" + *thisvalue + "\"";
+      if (*thisvalue == current_value)
+	macrovalue += " selected";
+      macrovalue += ">_" + *thisvalue + "_\n";
+    }
+    ++thisvalue;
+  }
+  macrovalue += "</select>\n";
+  disp.setmacro ("gformselection", displayclass::defaultpackage, macrovalue);
+}
+void queryaction::define_form_macros (displayclass &disp, cgiargsclass &args, 
+			   recptprotolistclass *protos, ostream &logout) {
+
+  // defines the following macros
+  // _regformlist_
+  // _advformlist_
+
+  if (args["ct"]=="0" || args["qto"]=="1" || (args["qto"]=="3" && args["qt"] == "0") ) // mg, or mgpp/lucene with plain only, or mgpp with both, but set to plain
+    return; // dont need these macros
+
+  text_t form = "";
+  int argfqn = args.getintarg("fqn");
+  
+  if (args["b"] == "1") { // advanced form
+    form += "_firstadvformelement_\n";
+    for (int i=1; i<argfqn; ++i) {      
+	form += "_advformelement_\n";
+    }
+    disp.setmacro("advformlist", "query", form);
+  }
+  else { // simple form
+    for (int i=0; i<argfqn; ++i) {
+      form += "_regformelement_\n"; 
+    }
+    disp.setmacro("regformlist", "query", form);
+  }
+  
+}
+
+void queryaction::define_history_macros (displayclass &disp, cgiargsclass &args, 
+					 recptprotolistclass *protos, ostream &logout) {
+
+  // defines the following macros
+  // _searchhistorylist_
+
+  text_t historylist;
+  int arghd = args.getintarg("hd");
+  if (arghd == 0) {
+    historylist="";
+  }
+  else {
+    historylist = "<!-- Search History List -->\n";
+   
+    text_t userid = args["z"];
+    text_tarray entries;
+    if (get_history_info (userid, entries, dbhome, logout)) {
+      int count = 1;
+      text_tarray::iterator here = entries.begin();
+      text_tarray::iterator end = entries.end();
+      int numrecords=(int)entries.size();
+      if (numrecords>arghd) { // only display some of them 
+	numrecords = arghd;
+      }
+      historylist += "<form action=\"_gwcgi_\" name=\"HistoryForm\"><table width=\"537\">\n";
+
+      for (int i=0; i<numrecords;++i) {
+	text_t query;
+	text_t numdocs;
+	text_t cgiargs;
+	text_t userinfo;
+	text_t escquery;
+	split_saved_query(entries[i],numdocs,cgiargs);
+	parse_saved_args(cgiargs, "q", query); // get query string out
+	decode_cgi_arg(query); // un cgisafe it
+	escquery = escape_quotes(query); // escape the quotes and newlines
+	text_t histvalue = "histvalue";
+	histvalue += i;
+	disp.setmacro(histvalue, "query", escquery);
+	format_user_info(cgiargs, userinfo, args, protos, logout);
+	
+	historylist += "<tr><td align=\"right\">_imagehistbutton_(";
+	historylist += i;
+	historylist += ")</td>\n";
+	historylist += "<td><table border=\"1\" cellspacing=\"0\" ";
+	historylist += "cellpadding=\"0\"><tr><td width=\"365\" align=\"left\">"
+	  + query 
+	  + "</td></tr></table></td><td width=\"110\" align=\"center\"><small>"
+	  + numdocs;
+	if (numdocs == 1) historylist += " _texthresult_";
+	else historylist += " _texthresults_";
+	if (!userinfo.empty()) {
+	  historylist += "<br>( "+userinfo+" )";
+	}
+	historylist += "</small></td>\n";
+      }
+      historylist+="</table></form>\n\n";
+     
+    } // if get history info 
+    else {
+      historylist += "_textnohistory_";
+    }
+    historylist += "<! ---- end of history list ----->\n";
+  } // else display list
+  disp.setmacro("searchhistorylist", "query", historylist);
+  
+} // define history macros
+
+void queryaction::output_ccp (cgiargsclass &args, recptprotolistclass *protos,
+			      displayclass &disp, outconvertclass &outconvert,
+			      ostream &textout, ostream &logout) {
+
+  ColInfoResponse_t *cinfo = NULL;
+  comerror_t err;
+  InfoFilterOptionsResponse_t fresponse;
+  InfoFilterOptionsRequest_t frequest;
+  frequest.filterName = "QueryFilter";
+
+  text_t &index = args["h"];
+  text_t &subcollection = args["j"];
+  text_t &language = args["n"];
+
+  text_tset collections;
+  text_t arg_cc = args["cc"];
+  decode_cgi_arg (arg_cc);
+  splitchar (arg_cc.begin(), arg_cc.end(), ',', collections);
+
+  textout << outconvert << disp << "_query:header_\n"
+	  << "<center>_navigationbar_</center><br>\n"
+	  << "<form name=\"QueryForm\" method=\"get\" action=\"_gwcgi_\">\n"
+	  << "<input type=\"hidden\" name=\"a\" value=\"q\">\n"
+          << "<input type=\"hidden\" name=\"site\" value=\"_cgiargsite_\"\n"
+	  << "<input type=\"hidden\" name=\"e\" value=\"_compressedoptions_\">\n"
+	  << "<input type=\"hidden\" name=\"ccp\" value=\"1\">\n"
+	  << "<center><table width=\"_pagewidth_\"><tr valign=\"top\">\n"
+	  << "<td>Select collections to search for \"" << args["q"] 
+	  << "\" <i>(index=" << index << " subcollection=" << subcollection
+	  << " language=" << language << ")</i></td>\n"
+	  << "<td><input type=\"submit\" value=\"_query:textbeginsearch_\"></td>\n"
+	  << "</tr></table></center>\n"
+	  << "<center><table width=\"_pagewidth_\">\n"
+	  << "<tr><td>\n";
+  
+  recptprotolistclass::iterator rprotolist_here = protos->begin();
+  recptprotolistclass::iterator rprotolist_end = protos->end();
+  while (rprotolist_here != rprotolist_end) {
+    if ((*rprotolist_here).p != NULL) {
+      
+      text_tarray collist;
+      (*rprotolist_here).p->get_collection_list (collist, err, logout);
+      if (err == noError) {
+	text_tarray::iterator collist_here = collist.begin();
+	text_tarray::iterator collist_end = collist.end();
+	while (collist_here != collist_end) {
+	  
+	  cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
+	  //	  if (err == noError && cinfo.isPublic && (cinfo.buildDate > 0)) {
+	  if (cinfo != NULL && (cinfo->buildDate > 0)) {
+	    
+	    (*rprotolist_here).p->get_filteroptions (*collist_here, frequest, fresponse, err, logout);
+	    if (err == noError) {
+	      
+	      FilterOption_tmap::const_iterator it;
+	      FilterOption_tmap::const_iterator end = fresponse.filterOptions.end();
+	      if (!index.empty()) {
+		it = fresponse.filterOptions.find ("Index");
+		if (it == end) {++collist_here; continue;}
+		text_tarray::const_iterator there = (*it).second.validValues.begin();
+		text_tarray::const_iterator tend = (*it).second.validValues.end();
+		while (there != tend) {
+		  if (*there == index) break;
+		  ++there;
+		}
+		if (there == tend) {++collist_here; continue;}
+	      }
+	      if (!subcollection.empty()) {
+		it = fresponse.filterOptions.find ("Subcollection");
+		if (it == end) {++collist_here; continue;}
+		text_tarray::const_iterator there = (*it).second.validValues.begin();
+		text_tarray::const_iterator tend = (*it).second.validValues.end();
+		while (there != tend) {
+		  if (*there == subcollection) break;
+		  ++there;
+		}
+		if (there == tend) {++collist_here; continue;}
+	      }
+	      if (!language.empty()) {
+		it = fresponse.filterOptions.find ("Language");
+		if (it == end) {++collist_here; continue;}
+		text_tarray::const_iterator there = (*it).second.validValues.begin();
+		text_tarray::const_iterator tend = (*it).second.validValues.end();
+		while (there != tend) {
+		  if (*there == language) break;
+		  ++there;
+		}
+		if (there == tend) {++collist_here; continue;}
+	      }
+	    
+	      // we've got a matching collection
+	      textout << outconvert << "<input type=\"checkbox\"";
+
+	      text_tset::const_iterator t = collections.find (*collist_here);
+	      if (t != collections.end()) textout << outconvert << " checked";
+	      
+	      text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]);
+	      if (collectionname.empty()) {
+		collectionname = *collist_here;
+	      }
+	      textout << outconvert << disp 
+		      << " name=\"cc\" value=\"" << *collist_here << "\">"
+		      << collectionname << "<br>\n";
+
+	      
+	    }
+	  }
+	  ++collist_here;
+	}
+      }
+    }
+    ++rprotolist_here;
+  }
+  textout << outconvert << disp 
+	  << "</td></tr></table></center>\n"
+	  << "</form>\n"
+	  << "_query:footer_\n";
+  
+}
+
+bool queryaction::do_action (cgiargsclass &args, recptprotolistclass *protos, 
+			     browsermapclass *browsers, displayclass &disp, 
+			     outconvertclass &outconvert, ostream &textout, 
+			     ostream &logout) {
+  
+  if (recpt == NULL) {
+    logout << "ERROR (queryaction::do_action): This action does not contain information\n"
+	   << "      about any receptionists. The method set_receptionist was probably\n"
+	   << "      not called from the module which instantiated this action.\n";
+    return true;
+  }
+
+
+
+  if (args["ccs"] == "1") {
+    if (!args["cc"].empty()) {
+      // query the selected collections
+      text_t::const_iterator b = args["cc"].begin();
+      text_t::const_iterator e = args["cc"].end();
+      if (findchar (b, e, ',') != e) {
+	if (!search_multiple_collections (args, protos, browsers, disp, outconvert,
+					  textout, logout)) return false;
+	return true;
+      } else {
+	if (!search_single_collection (args, args["cc"], protos, browsers, disp, 
+				       outconvert, textout, logout)) return false;
+  	return true;
+      }
+    }
+  }
+
+  // simply query the current collection
+  if (!search_single_collection (args, args["c"], protos, browsers, disp, 
+				 outconvert, textout, logout)) return false;
+  return true;
+}
+
+bool queryaction::search_multiple_collections (cgiargsclass &args, recptprotolistclass *protos,
+					       browsermapclass *browsers, displayclass &disp,
+					       outconvertclass &outconvert, ostream &textout,
+					       ostream &logout) {
+
+  text_tarray collections;
+  
+  text_t arg_cc = args["cc"];
+  decode_cgi_arg (arg_cc);
+  splitchar (arg_cc.begin(), arg_cc.end(), ',', collections);
+
+  if (collections.empty()) {
+    logout << "queryaction::search_multiple_collections: No collections "
+	   << "set for doing multiple query - will search current collection\n";
+    textout << outconvert << disp << "_query:textwarningnocollections_\n";
+    return search_single_collection (args, args["c"], protos, browsers, disp, 
+				     outconvert, textout, logout);
+  }
+
+  // queryaction uses "VList" browser to display results,
+  // a queries clasification is "Search"
+  text_t browsertype = "VList";
+  text_t classification = "Search";
+
+  QueryResult_tset results;
+  map<text_t, colinfo_t, lttext_t> colinfomap;
+
+  ColInfoResponse_t *cinfo = NULL;
+  recptproto *collectproto = NULL;
+  comerror_t err;
+  FilterRequest_t request;
+  FilterResponse_t response;
+  request.filterResultOptions = FROID | FRmetadata | FRtermFreq | FRranking;
+  text_t freqmsg = "_textfreqmsg1_";
+  int numdocs = 0;
+  isapprox isApprox = Exact;
+
+  // what to do about segmentation for multiple colls??
+  bool segment = false;
+  text_t formattedstring = "";
+  get_formatted_query_string(formattedstring, segment, args, disp, logout);
+
+  if (formattedstring.empty()) {
+    // dont bother doing a query if no query string
+    define_history_macros (disp, args, protos, logout);
+    textout << outconvert << disp << "_query:header_\n"
+	  << "_query:content_";
+    textout << outconvert << disp << "_query:footer_";
+
+    return true;
+  }
+  bool syntax_error = false;
+
+  set_queryfilter_options (request, formattedstring, args);
+
+  // need to retrieve maxdocs matches for each collection
+  // (will eventually want to tidy this up, do so caching etc.)
+  OptionValue_t option;
+  option.name = "StartResults";
+  option.value = "1";
+  request.filterOptions.push_back (option);
+  
+  option.name = "EndResults";
+  option.value = args["m"];
+  request.filterOptions.push_back (option);
+
+  text_tarray::iterator col_here = collections.begin();
+  text_tarray::iterator col_end = collections.end();
+
+  map<text_t, int, lttext_t> termfreqs;
+  
+  // just check the main col for formatting info - use individual format statements, or the main one?
+  
+  browserclass *bptr = browsers->getbrowser (browsertype);
+  
+  text_t main_col = args["c"];
+  cinfo = recpt->get_collectinfo_ptr (collectproto, main_col, logout);
+  if (cinfo == NULL) {
+    logout << "ERROR (query_action::search_multiple_collections): get_collectinfo_ptr returned NULL for '"<<main_col<<"'\n";
+    return false;
+  }
+  
+  bool use_main_col_format = false;
+  if (cinfo->ccsOptions & CCSUniformSearchResultsFormatting) {
+    use_main_col_format = true;
+  }
+ 
+  request.fields.erase (request.fields.begin(), request.fields.end());
+  request.getParents = false;
+  bptr->load_metadata_defaults (request.fields);
+  
+  text_t formatstring;
+  format_t *formatlistptr = new format_t();
+  if (use_main_col_format) {
+    // just get one format for main coll and use it for each subcol
+    if (!get_formatstring (classification, browsertype, 
+			   cinfo->format, formatstring)) {
+      formatstring = bptr->get_default_formatstring();
+    }
+    
+    parse_formatstring (formatstring, formatlistptr, request.fields, request.getParents);
+  }
+  
+  while (col_here != col_end) {
+
+    collectproto = protos->getrecptproto (*col_here, logout);
+    if (collectproto == NULL) {
+      logout << outconvert << "queryaction::search_multiple_collections: " << *col_here 
+	     << " collection has a NULL collectproto, ignoring\n";
+      ++col_here;
+      continue;
+    }
+    cinfo = recpt->get_collectinfo_ptr (collectproto, *col_here, logout);
+    if (cinfo == NULL) {
+      logout << "ERROR (query_action::search_multiple_collections): get_collectinfo_ptr returned NULL\n";
+      ++col_here;
+      continue;
+    }
+
+    if (!use_main_col_format) {
+      request.fields.erase (request.fields.begin(), request.fields.end());
+      request.getParents = false;
+      bptr->load_metadata_defaults (request.fields);
+      
+    //browserclass *bptr = browsers->getbrowser (browsertype);
+
+    // get the formatstring if there is one 
+      if (!get_formatstring (classification, browsertype, 
+			     cinfo->format, formatstring)) {
+	formatstring = bptr->get_default_formatstring();
+      }
+
+      formatlistptr = new format_t();
+      parse_formatstring (formatstring, formatlistptr, request.fields, request.getParents);
+    }
+    
+    colinfo_t thiscolinfo;
+    thiscolinfo.formatlistptr = formatlistptr;
+    thiscolinfo.browserptr = bptr;
+    colinfomap[*col_here] = thiscolinfo;
+    
+    // do the query
+    collectproto->filter (*col_here, request, response, err, logout);
+    if (err != noError && err != syntaxError) {
+      outconvertclass text_t2ascii;
+      logout << text_t2ascii
+	     << "queryaction::search_multiple_collections: call to QueryFilter failed "
+	     << "for " << *col_here << " collection (" << get_comerror_string (err) << ")\n";
+      return false;
+    }
+
+    if (err == syntaxError) {
+      syntax_error = true;
+      freqmsg = "_textinvalidquery_";
+      // assume the syntax will be invalid for all colls
+      break;
+    }
+    if (response.error_message == "TOO_MANY_CLAUSES") {
+      freqmsg = "_textlucenetoomanyclauses_";
+      break;
+    }
+    if (isApprox == Exact)
+      isApprox = response.isApprox;
+    else if (isApprox == MoreThan)
+      if (response.isApprox == Approximate)
+	isApprox = response.isApprox;
+
+    TermInfo_tarray::const_iterator this_term = response.termInfo.begin();
+    TermInfo_tarray::const_iterator end_term = response.termInfo.end();
+    while (this_term != end_term) {
+      termfreqs[(*this_term).term] += (*this_term).freq;
+      if ((col_here+1) == col_end) {
+	freqmsg += (*this_term).term + ": " + termfreqs[(*this_term).term];
+	if ((this_term+1) != end_term) freqmsg += ", ";
+      }
+      ++this_term;
+    }
+
+    if (response.numDocs > 0) {
+      numdocs += response.numDocs;
+    
+      QueryResult_t thisresult;
+      thisresult.collection = *col_here;
+      ResultDocInfo_tarray::iterator doc_here = response.docInfo.begin();
+      ResultDocInfo_tarray::iterator doc_end = response.docInfo.end();
+      while (doc_here != doc_end) {
+	thisresult.doc = *doc_here;
+	results.insert (thisresult);
+	++doc_here;
+      }
+    }
+    ++col_here;
+  } // for each coll
+  
+  text_t numdocs_t = numdocs;  
+  args["nmd"] = numdocs_t;
+
+  disp.setmacro ("freqmsg", "query", freqmsg);
+
+  define_query_macros( args, disp, numdocs, isApprox);
+  // save the query if appropriate
+  save_search_history(args, numdocs, isApprox);
+  define_history_macros (disp, args, protos, logout);
+
+  textout << outconvert << disp << "_query:header_\n"
+	  << "_query:content_";
+
+  if (!syntax_error) {
+    
+    // now go through each result and output it
+    QueryResult_tset::iterator res_here = results.begin();
+    QueryResult_tset::iterator res_end = results.end();
+    text_tset metadata; // empty !!
+    bool getParents = false; // don't care !!
+    bool use_table;
+    ResultDocInfo_t thisdoc;
+    format_t *formatlistptr = NULL;
+    browserclass *browserptr = NULL;
+    
+    int count = 1;
+    int firstdoc = args.getintarg("r");
+    int hitsperpage = args.getintarg("o");
+    int thislast = firstdoc + (hitsperpage - 1);
+    
+    // output results
+    while (res_here != res_end) {
+      if (count < firstdoc) {++count; ++res_here; continue;}
+      if (count > thislast) break;
+      
+      formatlistptr = colinfomap[(*res_here).collection].formatlistptr;
+      browserptr = colinfomap[(*res_here).collection].browserptr;
+      thisdoc = (*res_here).doc;
+      use_table = is_table_content (formatlistptr);
+      
+      collectproto = protos->getrecptproto ((*res_here).collection, logout);
+      if (collectproto == NULL) {
+	logout << outconvert << "queryaction::search_multiple_collections: " << (*res_here).collection
+	       << " collection has a NULL collectproto, ignoring results\n";
+	++res_here;
+	continue;
+      }
+      
+      browserptr->output_section_group (thisdoc, args, (*res_here).collection, 0, 
+					formatlistptr, use_table, metadata, getParents, 
+					collectproto, disp, outconvert, textout, logout);
+      //    textout << outconvert << "(ranking: " << (*res_here).doc.ranking << ")\n";
+      ++res_here;
+      ++count;
+    }
+  }
+  textout << outconvert << disp << "_query:footer_";
+  
+  // clean up the format_t pointers
+  map<text_t, colinfo_t, lttext_t>::iterator here =  colinfomap.begin();
+  map<text_t, colinfo_t, lttext_t>::iterator end =  colinfomap.end();
+  while (here != end) {
+    delete ((*here).second.formatlistptr);
+    ++here;
+  }
+  return true;
+}
+
+bool queryaction::search_single_collection (cgiargsclass &args, const text_t &collection,
+					    recptprotolistclass *protos, browsermapclass *browsers, 
+					    displayclass &disp, outconvertclass &outconvert, 
+					    ostream &textout, ostream &logout) {
+
+  recptproto *collectproto = protos->getrecptproto (collection, logout);
+  if (collectproto == NULL) {
+    logout << outconvert << "queryaction::search_single_collection: " << collection
+	   << " collection has a NULL collectproto\n";
+
+    // Display the "this collection is not installed on this system" page
+    disp.setmacro("cvariable", displayclass::defaultpackage, collection);
+    disp.setmacro("content", "query", "<p>_textbadcollection_<p>");
+
+    textout << outconvert << disp << "_query:header_\n"
+	    << "_query:content_\n" << "_query:footer_\n";
+    return true;
+  }
+
+  // queryaction uses "VList" browser to display results,
+  // a queries clasification is "Search"
+  text_t browsertype = "VList";
+  text_t classification = "Search";
+
+  comerror_t err;
+  ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr (collectproto, collection, logout);
+
+  if (cinfo == NULL) {
+    logout << "ERROR (query_action::search_single_collection): get_collectinfo_ptr returned NULL\n";
+    return false;
+  }
+    
+  bool segment = cinfo->isSegmented;
+  browserclass *bptr = browsers->getbrowser (browsertype);
+
+  // get the formatstring if there is one 
+  text_t formatstring;
+  if (!get_formatstring (classification, browsertype, 
+			 cinfo->format, formatstring)) {
+    formatstring = bptr->get_default_formatstring();
+  }
+  FilterRequest_t request;
+  FilterResponse_t response;
+
+  text_t hits_per_page_old = args["o"];
+  text_t start_results_from_old = args["r"];  
+
+  // if the "ifl" argument is set to 1, we only want to get one document
+  // this may be the first search result (from "I feel lucky") or maybe a 
+  // specified search result (from next/prev search result link)
+  if (args["ifl"] == "1") {
+    args["r"] = args["ifln"]; // the document number we want
+    args["o"] = "1";
+  }
+
+  bptr->set_filter_options (request, args);
+  bptr->load_metadata_defaults (request.fields);
+
+  format_t *formatlistptr = new format_t();
+  parse_formatstring (formatstring, formatlistptr, request.fields, request.getParents);
+    
+  // do the query
+  request.filterResultOptions = FROID | FRmetadata | FRtermFreq;
+  text_t formattedstring = "";
+  get_formatted_query_string(formattedstring, segment, args, disp, logout);
+
+
+  if (!formattedstring.empty()) { // do the query
+    // note! formattedstring is in unicode! mg and mgpp must convert!
+    set_queryfilter_options (request, formattedstring, args);
+
+    collectproto->filter (collection, request, response, err, logout);
+
+    if (err != noError) {
+      outconvertclass text_t2ascii;
+      logout << text_t2ascii
+	     << "queryaction::search_single_collections: call to QueryFilter failed "
+	     << "for " << collection << " collection (" << get_comerror_string (err) << ")\n";
+     
+    }
+
+    // Perform the "I'm feeling lucky" trick if the "ifl" argument is set
+    if (err == noError && !args["ifl"].empty()) {
+      //Restore the "r" and "o" arg
+      args["r"] = start_results_from_old;
+      args["o"] = hits_per_page_old;
+      
+      //Find whether DocumentSearchResultLinks is enabled
+      bool show_links = false;
+      text_tmap::const_iterator format_here = cinfo->format.begin();
+      text_tmap::const_iterator format_end = cinfo->format.end();
+      
+      while (format_here != format_end) {
+	if (((*format_here).first == "DocumentSearchResultLinks") && 
+	    ((*format_here).second == "true")){
+	  show_links = true;
+	  break;
+	}
+	++format_here;
+      } 
+      
+      if (args["ifl"] == 1 || (args["ifl"] == 2 && response.numDocs == 1)) {
+	
+	// The first search result is the one we want
+	if (response.docInfo.begin() != response.docInfo.end()) {
+	  
+	  ResultDocInfo_tarray::iterator section = response.docInfo.begin();
+	  
+	  // We still need to set "srn" and "srp" values (next and prev search result numbers) if we are showing them
+	  int srn = 0;
+	  int srp = 0;
+	  if (show_links) {
+	    int ifln = args["ifln"].getint();
+	    srn = ifln + 1;
+	    if (srn > response.numDocs) {
+	      srn = 0;
+	    }
+	    srp = ifln - 1;
+	    if (srp < 0) {
+	      srp = 0;
+	    }
+	  }
+	  
+	  textout << outconvert << disp 
+		  << "Location: _gwcgi_?e=_compressedoptions_&a=d&c=" 
+		  << collection << "&cl=search&d=" << (*section).OID 
+		  << "&srn=" << srn << "&srp=" << srp << "\n\n";
+	  textout << flush;
+	  
+	  return true;
+	}
+      }
+    
+      // There weren't enough (or any) matching documents
+      // We'll just carry on as if ifl wasn't set. The only catch is that get_cgihead_info won't have
+      // done the right thing (because ifl was set), so we need to make sure the output is html
+      textout << "Content-type: text/html\n\n";
+      
+    }
+
+    if (err != noError) {
+      disp.setmacro("resultline", "query", "_textnodocs_");
+      if (err == syntaxError) {
+	disp.setmacro ("freqmsg", "query", "_textinvalidquery_");
+      } else {
+	disp.setmacro ("freqmsg", "query", "");
+      }
+    } else {
+      
+      define_query_macros (args, disp, response.numDocs, response.isApprox);
+      define_single_query_macros(args, disp, response);
+      // save the query if appropriate
+      save_search_history(args, response.numDocs, response.isApprox);
+    }
+
+    // If Lucene threw a TooManyClauses exception, tell the user about it
+    if (args["ct"] == 2 && response.error_message == "TOO_MANY_CLAUSES") {
+      disp.setmacro ("freqmsg", "query", "_textlucenetoomanyclauses_");
+    }
+  }
+  
+  //Restore the "r" and "o" arg in case they have been changed and we still get here
+  args["r"] = start_results_from_old;
+  args["o"] = hits_per_page_old;
+
+  define_history_macros (disp, args, protos, logout);
+
+  textout << outconvert << disp << "_query:header_\n"
+	  << "_query:content_";
+  
+  if (err == noError) {
+    // output the results
+    text_t numdocs_t = response.numDocs;  
+    args["nmd"] = numdocs_t;
+    bool use_table = is_table_content (formatlistptr);
+    bptr->output_section_group (response, args, collection, 0, formatlistptr, 
+				use_table, request.fields, request.getParents, 
+				collectproto, disp, outconvert, textout, logout);
+  }
+
+  textout << outconvert << disp << "_query:footer_";
+  
+  delete (formatlistptr);
+  
+  return true;
+}
+ 
+// does the formatting of the query string - either uses q for a text search
+// or the form values for an form search
+// also adds dates if appropriate in text search
+void queryaction::get_formatted_query_string (text_t &formattedstring, 
+					      bool segment,
+					      cgiargsclass &args, 
+					      displayclass &disp,
+					      ostream &logout) {
+  if (args["qt"]=="0" && args["qto"] != "2") { // normal text search
+    formattedstring = args["q"];
+    // remove & | ! for simple search,do segmentation if necessary
+    format_querystring (formattedstring, args.getintarg("b"), segment);
+    if (args["ct"]!=0) { // mgpp and lucene - need to add in tag info if appropriate
+      format_field_info(formattedstring, args["fqf"], args.getintarg("ct"), 
+			args.getintarg("t"), args.getintarg("b"));
+    }
+
+    add_dates(formattedstring, args.getintarg("ds"), args.getintarg("de"),
+	      args.getintarg("dsbc"), args.getintarg("debc"),
+	      args.getintarg("ct"));
+    args["q"] = formattedstring;
+    
+  }
+  else if (args["qt"]=="1" || args["qto"]=="2"){ // form search
+
+    if (args["b"]=="1" && args["fqa"]=="1") { // explicit query
+      formattedstring = args["q"];
+    }
+    else { // form search
+      if (args["b"]=="0") { // regular form
+	parse_reg_query_form(formattedstring, args, segment);
+      }
+      else  { // advanced form
+	parse_adv_query_form(formattedstring, args, segment);
+      }
+      args["q"] = formattedstring;
+      
+      // reset the cgiargfqv macro - need to escape any quotes in it
+      disp.setmacro("cgiargfqv", "query", escape_quotes(args["fqv"]));
+
+      // also reset the _cgiargq_ macro as it has changed now
+      disp.setmacro("cgiargq", displayclass::defaultpackage, html_safe(args["q"]));
+      
+      // reset the compressed options to include the q arg
+      text_t compressedoptions = recpt->get_compressed_arg(args, logout);
+      if (!compressedoptions.empty()) {
+	disp.setmacro ("compressedoptions", displayclass::defaultpackage, dm_safe(compressedoptions));
+	// need a decoded version of compressedoptions for use within forms
+	// as browsers encode values from forms before sending to server
+	// (e.g. %25 becomes %2525)
+	decode_cgi_arg (compressedoptions); 
+	if (args["w"] == "utf-8") { // if the encoding was utf-8, then compressed options was utf-8, and we need unicode.
+    // if encoding wasn't utf-8, then compressed opotions may be screwed up, but seems to work for 8 bit encodings?
+	  compressedoptions = to_uni(compressedoptions);
+	}
+
+	disp.setmacro ("decodedcompressedoptions", displayclass::defaultpackage, dm_safe(compressedoptions));
+      }
+    } // form search
+  } // args["qt"]=1
+  else {
+    logout << "ERROR (query_action::get_formatted_query_string): querytype not defined\n";
+  }
+}
+
+
+// define_query_macros sets the macros that couldn't be set until the
+// query had been done. Those macros are 
+// _resultline_, _nextfirst_, _nextlast_, _prevfirst_, _prevlast_,
+// _thisfirst_, and _thislast_ and _quotedquery_ 
+// this has been simplified so it can be used with both search_single_coll
+// and search_multiple_coll
+void queryaction::define_query_macros (cgiargsclass &args, displayclass &disp,
+				       int numdocs, isapprox isApprox) {
+  
+  // set up _resultline_ macro
+  text_t resline;
+  int maxdocs = args.getintarg("m");
+  if (num_phrases > 0) isApprox = Exact;
+  if (maxdocs == -1) maxdocs = numdocs;
+  else if (numdocs > maxdocs) {
+    numdocs = maxdocs;
+    isApprox = MoreThan;
+  }
+
+  if (isApprox == Approximate) resline = "_textapprox_";
+  else if (isApprox == MoreThan) resline = "_textmorethan_";
+  
+  if (numdocs == 0) resline = "_textnodocs_";
+  else if (numdocs == 1) resline += "_text1doc_";
+  else resline += text_t(numdocs) + " _textlotsdocs_";
+  
+  disp.setmacro("resultline", "query", resline);
+
+  int firstdoc = args.getintarg("r");
+  int hitsperpage = args.getintarg("o");
+  if (hitsperpage == -1) hitsperpage = numdocs;
+
+  // set up _thisfirst_ and _thislast_ macros
+  disp.setmacro ("thisfirst", "query", firstdoc);
+  int thislast = firstdoc + (hitsperpage - 1);
+  if (thislast > numdocs) thislast = numdocs;
+  disp.setmacro ("thislast", "query", thislast);
+
+  // set up _prevfirst_ and _prevlast_ macros
+  if (firstdoc > 1) {
+    disp.setmacro ("prevlast", "query", firstdoc - 1);
+    int prevfirst = firstdoc - hitsperpage;
+    if (prevfirst < 1) prevfirst = 1;
+    disp.setmacro ("prevfirst", "query", prevfirst);
+  }
+
+  // set up _nextfirst_ and _nextlast_ macros
+  if (thislast < numdocs) {
+    disp.setmacro ("nextfirst", "query", thislast + 1);
+    int nextlast = thislast + hitsperpage;
+    if (nextlast > numdocs) nextlast = numdocs;
+    disp.setmacro ("nextlast", "query", nextlast);
+  }
+
+  // do quoted query here cos we may have added quotes during query pre-processing
+  if (args["ct"]==0) { // mg queries only, not mgpp
+    // get the quoted bits of the query string and set _quotedquery_
+    text_tarray phrases;
+    get_phrases (args["q"], phrases);
+    num_phrases = phrases.size();
+    text_tarray::const_iterator phere = phrases.begin();
+    text_tarray::const_iterator pend = phrases.end();
+    bool first = true;
+    text_t quotedquery;
+    while (phere != pend) {
+      if (!first)
+	if ((phere +1) == pend) quotedquery += " and ";
+	else quotedquery += ", ";
+      
+      quotedquery += "\"" + *phere + "\"";
+      first = false;
+      ++phere;
+    }
+    if (args.getintarg("s") && !quotedquery.empty()) quotedquery += "_textstemon_";
+    disp.setmacro ("quotedquery", "query", quotedquery);
+  }
+
+}
+
+// define_single_query_macros sets the extra macros for search_single_coll 
+// that couldn't be set until the query had been done. Those macros are 
+// _freqmsg_ and _stopwordsmsg_
+void queryaction::define_single_query_macros (cgiargsclass &args, 
+					      displayclass &disp, 
+					      const FilterResponse_t &response) {
+  // set up _freqmsg_ and _stopwordsmsg_ macros
+
+  text_t freqmsg = "";
+  freqmsg = "_textfreqmsg1_";
+  TermInfo_tarray::const_iterator this_term = response.termInfo.begin();
+  TermInfo_tarray::const_iterator end_term = response.termInfo.end();
+  while (this_term != end_term) {
+    freqmsg += (*this_term).term + ": " + (*this_term).freq;
+    if ((this_term + 1) != end_term)
+      freqmsg += ", ";
+    ++this_term;
+  }
+  disp.setmacro ("freqmsg", "query", freqmsg);
+
+  text_tset::const_iterator this_stopword = response.stopwords.begin();
+  text_tset::const_iterator end_stopword = response.stopwords.end();
+  if (this_stopword != end_stopword) {
+    text_t stopwordsmsg = "_textstopwordsmsg_ ";
+    while (this_stopword != end_stopword) {
+      if (stopwordsmsg != "_textstopwordsmsg_ ") {
+	stopwordsmsg += ", ";
+      }
+      stopwordsmsg += (*this_stopword);
+      ++this_stopword;
+    }
+    disp.setmacro("stopwordsmsg", "query", stopwordsmsg);
+  }
+}
+
+// should this change for cross coll search??
+bool queryaction::save_search_history (cgiargsclass &args, int numdocs, 
+				       isapprox isApprox) {
+  if (args["q"]=="") return true; // null query, dont save
+  if (args["hs"]=="0") return true; // only save when submit query pressed
+  
+  // get userid
+  text_t userid = args["z"];
+
+  // the number of docs goes on the front of the query string
+  text_t query = text_t(numdocs);
+  if (isApprox==MoreThan) { // there were more docs found
+    query.push_back('+');
+  }
+  query += "c="+args["c"];
+  query += ";h="+args["h"];
+  query += ";t="+args["t"];
+  query += ";b="+args["b"];
+  query += ";j="+args["j"];
+  query += ";n="+args["n"];
+  query += ";s="+args["s"];
+  query += ";k="+args["k"];
+  query += ";g="+args["g"]; 
+  
+  text_t qstring = args["q"];
+  //text_t formattedquery =cgi_safe(qstring);
+  //query += "&amp;q="+formattedquery;
+  query += ";q="+qstring;
+  bool display=false;
+  int hd = args.getintarg("hd");
+  if (hd > 0) display=true;
+  if (set_history_info(userid, query, dbhome, display)) return true;
+  else return false;
+
+
+}
+
Index: /gsdl/stable/runtime-src/src/recpt/queryaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/queryaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/queryaction.h	(revision 20131)
@@ -0,0 +1,153 @@
+/**********************************************************************
+ *
+ * queryaction.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef QUERYACTION_H
+#define QUERYACTION_H
+
+#include "gsdlconf.h"
+#include "action.h"
+#include "receptionist.h"
+
+struct colinfo_t {
+  void clear();
+  colinfo_t () {clear();}
+
+  format_t *formatlistptr;
+  browserclass *browserptr;
+};
+
+struct QueryResult_t {
+  void clear ();
+  QueryResult_t () {clear();}
+
+  ResultDocInfo_t doc;
+  text_t collection;
+};
+
+struct gteqQueryResult_t 
+{
+  bool operator()(const QueryResult_t &t1, const QueryResult_t &t2) const
+  { return t1.doc.ranking >= t2.doc.ranking; }
+};
+
+typedef set<QueryResult_t, gteqQueryResult_t> QueryResult_tset;
+
+
+class queryaction : public action {
+
+protected:
+
+  receptionist *recpt;
+
+  text_t m_strUseInterfaceLanguageForQuery;
+  text_t formatstring;
+  text_tmap reqfields; // required fields
+  int num_phrases;
+
+  virtual void define_single_query_macros (cgiargsclass &args, 
+					   displayclass &disp, 
+					   const FilterResponse_t &response); 
+  virtual void define_query_macros (cgiargsclass &args, displayclass &disp, 
+			    int numDocs, isapprox isApprox); 
+
+  void get_formatted_query_string (text_t &formattedstring, bool segment, 
+				   cgiargsclass &args, 
+				   displayclass &disp, ostream &logout);
+  void define_query_interface(displayclass &disp, cgiargsclass &args, 
+			      recptprotolistclass *protos, ostream &logout);
+  
+  void define_form_macros (displayclass &disp, cgiargsclass &args, 
+			   recptprotolistclass *protos, ostream &logout);
+
+  void define_history_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+
+  virtual void set_option_macro (const text_t &macroname, text_t current_value,
+				 bool display_single, bool add_js_update,
+			 const FilterOption_t &option, displayclass &disp);
+
+  void set_gformselection_macro (text_t current_value,
+				 const FilterOption_t &option,
+				 displayclass &disp);
+  void set_sfselection_macro (text_t current_value, 
+			      const FilterOption_t &option, 
+			      displayclass &disp);
+
+  void output_ccp (cgiargsclass &args, recptprotolistclass *protos,
+		   displayclass &disp, outconvertclass &outconvert,
+		   ostream &textout, ostream &logout);
+  
+  bool search_multiple_collections (cgiargsclass &args, 
+				    recptprotolistclass *protos,
+				    browsermapclass *browsers, 
+				    displayclass &disp,
+				    outconvertclass &outconvert, 
+				    ostream &textout,
+				    ostream &logout);
+  
+  virtual bool search_single_collection (cgiargsclass &args, 
+					 const text_t &collection,
+					 recptprotolistclass *protos, 
+					 browsermapclass *browsers, 
+					 displayclass &disp, 
+					 outconvertclass &outconvert, 
+					 ostream &textout, ostream &logout);
+
+
+  bool save_search_history(cgiargsclass &args, int numdocs, isapprox isApprox);
+
+public:
+  queryaction ();
+  virtual ~queryaction () {}
+
+  void set_receptionist (receptionist *therecpt) {recpt=therecpt;}
+  
+  void configure (const text_t &key, const text_tarray &cfgline);
+  bool init (ostream &logout);
+  
+  virtual text_t get_action_name () {return "q";}
+  
+  virtual bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+			      recptprotolistclass *protos, ostream &logout);
+
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response, text_t &response_data, 
+			 ostream &logout);
+  
+  virtual void define_internal_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+
+  virtual void define_external_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+  
+  virtual bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+
+};
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/querytools.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/querytools.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/querytools.cpp	(revision 20131)
@@ -0,0 +1,905 @@
+/**********************************************************************
+ *
+ * querytools.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "querytools.h"
+#include <ctype.h>
+#include "unitool.h" // for is_unicode_letdig
+
+// sets the ct, qt, qto arguments
+void set_query_type_args(ColInfoResponse_t *cinfo, cgiargsclass &args) {
+
+  if (args["ct"].empty()) {
+    text_t build_type = cinfo->buildType;
+    if (build_type == "mgpp") {
+      args["ct"] = "1";
+    } else if (build_type == "lucene") {
+      args["ct"] = "2";
+    } else {
+      args["ct"] = "0";
+    }
+  }
+  text_t arg_ct = args["ct"];
+  if (arg_ct == "0") {
+    // mg
+    args["qt"] = "0";
+    args["qto"] = "0";
+    return;
+  }
+
+  if (!args["qt"].empty() && !args["qto"].empty()) {
+    return;
+  }
+  
+  text_tmap::iterator check = cinfo->format.find("SearchTypes");
+  text_t search_types;
+  if(check != cinfo->format.end() && !(*check).second.empty()){
+    search_types = (*check).second;
+  } else {
+    // assume plain,form
+    if (args["qto"].empty()) args["qto"] = "3";
+    if (args["qt"].empty()) {
+      int arg_qto = args.getintarg("qto");
+      if (arg_qto == 2) {
+	args["qt"] = "1";
+      } else {
+	args["qt"] = "0";
+      }
+    }
+    return;
+  }
+  
+  
+  if (args["qto"].empty()) {
+    unsigned int type = 0;
+    if (findword(search_types.begin(), search_types.end(), "form") != search_types.end()) {
+      type |= 2;
+    }
+    if (findword(search_types.begin(), search_types.end(), "plain") != search_types.end()) {
+      type |= 1;
+    }
+    args.setintarg("qto", type);
+  } 
+  
+  if (args["qt"].empty()) {
+    int arg_qto = args.getintarg("qto");
+    if (arg_qto == 2 || (arg_qto == 3 && starts_with(search_types, "form"))) {
+      args["qt"] = "1";
+    } else {
+      args["qt"] = "0";
+    }
+  }
+}
+
+// sets the ks, ss, afs (casesupport, stemsupport, accentfoldsupport) args
+void set_stem_index_args(ColInfoResponse_t *cinfo, cgiargsclass &args) {
+  int stemIndexes = cinfo->stemIndexes;
+
+  if (stemIndexes & SIcasefold) {
+    args["ks"] = 1;
+  }
+  if (stemIndexes & SIstem) {
+    args["ss"] = 1;
+  }
+  if (stemIndexes & SIaccentfold) {
+    args["afs"] = 1;
+  }
+
+}
+
+// request.filterResultOptions and request.fields (if required) should
+// be set from the calling code
+void set_queryfilter_options (FilterRequest_t &request, 
+			      const text_t &querystring,
+			      cgiargsclass &args) {
+
+  request.filterName = "QueryFilter";
+
+  OptionValue_t option;
+
+  option.name = "Term";
+  option.value = querystring;
+  request.filterOptions.push_back (option);
+
+  option.name = "QueryType";
+  option.value = (args.getintarg("t")) ? "ranked" : "boolean";
+  request.filterOptions.push_back (option);
+
+  option.name = "MatchMode";
+  // mgpp in advanced mode, always use some query
+  if (args.getintarg("ct") == 1 && args.getintarg("b") == 1) {
+    option.value = "some";
+  } else {
+    option.value = (args.getintarg("t")) ? "some" : "all";
+  }
+  request.filterOptions.push_back (option);
+
+  option.name = "Casefold";
+  option.value = (args.getintarg("k")) ? "true" : "false";
+  request.filterOptions.push_back (option);
+
+  option.name = "Stem";
+  option.value = (args.getintarg("s")) ? "true" : "false";
+  request.filterOptions.push_back (option);
+
+  option.name = "AccentFold";
+  option.value = (args.getintarg("af")) ? "true" : "false";
+  request.filterOptions.push_back (option);
+  
+  if (!args["h"].empty()) {
+    option.name = "Index";
+    option.value = args["h"];
+    request.filterOptions.push_back (option);
+  }
+
+  if (!args["j"].empty()) {
+    option.name = "Subcollection";
+    option.value = args["j"];
+    request.filterOptions.push_back (option);
+  }
+
+  if (!args["n"].empty()) {
+    option.name = "Language";
+    option.value = args["n"];
+    request.filterOptions.push_back (option);
+  }
+  
+  if (!args["g"].empty()) { // granularity for mgpp
+    option.name = "Level";
+    option.value = args["g"];
+    request.filterOptions.push_back (option);
+  }
+
+  if (!args["fs"].empty()) { // filter string for lucene
+    option.name = "FilterString";
+    option.value = args["fs"];
+    request.filterOptions.push_back (option);
+  }
+
+  if (!args["sf"].empty()) { // sort field for lucene
+    option.name = "SortField";
+    option.value = args["sf"];
+    request.filterOptions.push_back (option);
+  }
+
+  if (!args["fuzziness"].empty() && args["fuzziness"] != "100") { // fuzziness value for lucene
+    option.name = "Fuzziness";
+    option.value = (text_t) "0." + args["fuzziness"];
+    request.filterOptions.push_back (option);
+  }
+
+  set_more_queryfilter_options (request, args);
+}
+
+void set_queryfilter_options (FilterRequest_t &request, 
+			      const text_t &querystring1,
+			      const text_t &querystring2, cgiargsclass &args) {
+
+  set_queryfilter_options (request, querystring1, args);
+
+  // fill in the second query if needed
+  if (!args["cq2"].empty()) {
+    OptionValue_t option;
+
+    option.name = "CombineQuery";
+    option.value = args["cq2"];
+    request.filterOptions.push_back (option);
+    
+    option.name = "Term";
+    option.value = querystring2;
+    request.filterOptions.push_back (option);
+    
+    option.name = "QueryType";
+    option.value = (args.getintarg("t")) ? "ranked" : "boolean";
+    request.filterOptions.push_back (option);
+
+    option.name = "Casefold";
+    option.value = (args.getintarg("k")) ? "true" : "false";
+    request.filterOptions.push_back (option);
+
+    option.name = "Stem";
+    option.value = (args.getintarg("s")) ? "true" : "false";
+    request.filterOptions.push_back (option);
+
+    option.name = "AccentFold";
+    option.value = (args.getintarg("af")) ? "true" : "false";
+    request.filterOptions.push_back (option);
+
+    if (!args["h2"].empty()) {
+      option.name = "Index";
+      option.value = args["h2"];
+      request.filterOptions.push_back (option);
+    }
+
+    if (!args["j2"].empty()) {
+      option.name = "Subcollection";
+      option.value = args["j2"];
+      request.filterOptions.push_back (option);
+    }
+
+    if (!args["n2"].empty()) {
+      option.name = "Language";
+      option.value = args["n2"];
+      request.filterOptions.push_back (option);
+    }
+  }
+  set_more_queryfilter_options (request, args);
+}
+
+void set_more_queryfilter_options (FilterRequest_t &request, 
+				   cgiargsclass &args) {
+
+  OptionValue_t option;
+  int arg_m = args.getintarg("m");
+  
+  option.name = "Maxdocs";
+  option.value = arg_m;
+  request.filterOptions.push_back (option);
+
+  //  option.name = "StartResults";
+  //  option.value = args["r"];
+  //  request.filterOptions.push_back (option);
+
+  //  option.name = "EndResults";
+  //  int endresults = args.getintarg("o") + (args.getintarg("r") - 1);
+  //  if ((endresults > arg_m) && (arg_m != -1)) endresults = arg_m;
+  //  option.value = endresults;
+  //  request.filterOptions.push_back (option);
+}
+
+bool is_special_character(int indexer_type, unsigned short character) {
+  // mgpp
+  if (indexer_type == 1) {
+    return (character == '#' || character == '/' || character == '*');
+  }
+  // lucene
+  else if (indexer_type == 2) {
+    return (character == '?' || character == '*' || character == '~' || 
+	    character == '^');
+  }
+  return false;
+}
+
+// This function removes boolean operators from simple searches, and segments
+// chinese characters if segment=true
+void format_querystring (text_t &querystring, int querymode, bool segment) {
+  text_t formattedstring;
+
+  // advanced search, no segmenting, don't need to do anything
+  if (querymode == 1 && !segment) return;
+  
+  text_t::const_iterator here = querystring.begin();
+  text_t::const_iterator end = querystring.end();
+
+  // space is used to insert spaces between Chinese
+  // characters. No space is needed before the first
+  // Chinese character.
+  bool space = false;
+
+  // want to remove ()|!& from querystring so boolean queries are just
+  // "all the words" queries (unless querymode is advanced)
+  while (here != end) {
+    if ((querymode == 0) && (*here == '(' || *here == ')' || *here == '|' ||
+			     *here == '!' || *here == '&')) {
+      formattedstring.push_back(' ');
+    } else if (segment) {
+      if ((*here >= 0x2e80 && *here <= 0xd7a3) ||
+	  ( *here >= 0xf900 && *here <= 0xfa6a)) {
+	/* text_t not big enough to handle these. */
+	/*	  (*here >= 0x20000 && *here <= 0x2a6d6) ||
+	  (*here >= 0x2f800 && *here <= 0x2fa1d)) { */
+	
+	// CJK character
+	if (!space) formattedstring.push_back (0x200b); // zero width space
+	formattedstring.push_back (*here);
+	formattedstring.push_back (0x200b);
+	space = true;
+      } else {
+	
+	// non-Chinese character
+	formattedstring.push_back (*here);
+	space = false;
+	
+      }
+    
+    } else {
+      formattedstring.push_back (*here);
+    }
+    ++here;
+  }
+  querystring = formattedstring;
+}
+
+
+	
+
+// search history tool 
+// also used for form query macros
+text_t escape_quotes(const text_t &querystring) {
+
+  text_t::const_iterator here = querystring.begin();
+  text_t::const_iterator end = querystring.end();
+ 
+  text_t escquery = "";
+  while (here != end) {
+    if (*here != '\'' && *here != '\"' && *here != '\n' && *here != '\r') escquery.push_back(*here);
+    else if (*here == '\n' || *here == '\r') {
+      escquery.push_back(' ');
+    } else {
+      escquery +="\\\\";
+      escquery.push_back(*here);
+    }
+
+    ++here;
+  }
+  return escquery;
+
+}
+
+// Parses the terms into words, and adds #si if necessary
+text_t addstemcase(const text_t &terms, const text_t &stem, const text_t &fold,
+		   const int indexer_type) {
+  
+  // the default stem and case are set to 0 if this is being used, so we are only adding on qualifiers if stem or fold is 1.
+  if (stem == "0" && fold == "0") {
+    return terms;
+  }
+  // this is only for mgpp collections, shouldn't be called for anything else
+  if (indexer_type != 1) {
+    return terms;
+  }
+  
+  text_t outtext;
+  text_t word;
+
+  text_t::const_iterator here = terms.begin();
+  text_t::const_iterator end = terms.end();
+
+  while (here !=end) {
+
+    if (is_unicode_letdig(*here) || is_special_character(indexer_type, *here)) {
+      // not word boundary
+      word.push_back(*here);
+      ++here;    
+    }
+    else {
+      // found word boundary   
+      if (!word.empty() ) {
+	if (starts_with(word, "NEAR") || starts_with(word, "WITHIN")) {
+	  outtext += word;
+	  word.clear();
+	}
+	else {
+	  word += "#";
+	  if (stem == "1") word += "s";
+	  if (fold == "1") word += "i";
+	  outtext += word;
+	  word.clear();
+	}
+      }
+      // this only used in advanced form, so we leave in boolean operators
+      if (*here == '\"' || *here == '&' || *here == '|' || *here == '!' || 
+	  *here == '(' || *here == ')' || is_unicode_space(*here)) {
+	outtext.push_back(*here);
+      }
+      ++here;
+    }
+  }
+   
+  // get last word
+  if (!word.empty()) {
+    word += "#";
+    if (stem == "1") word += "s";
+    if (fold == "1") word += "i";
+    word += " ";
+    outtext += word;
+  }
+  return outtext;
+}
+
+
+// some query form parsing functions for use with mgpp & lucene
+
+void parse_reg_query_form(text_t &querystring, cgiargsclass &args, bool segment)
+{
+  querystring.clear();
+
+  int argct = args.getintarg("ct");
+  int argt = args.getintarg("t");// t=0 -and, t=1 - or
+  int argb = args.getintarg("b");
+    
+  text_t combine;
+
+  // lucene uses global combine, so only need this for mgpp
+  if (argct==1) {
+    if (argt == 0) combine = "&";
+    else combine = "|";
+  }
+  
+  text_t field = args["fqf"];
+  if (field.empty()) return; // no query
+  text_tarray fields;
+  splitchar(field.begin(), field.end(), ',', fields); 
+  
+  text_t value = args["fqv"];
+  if (value.empty()) return; // somethings wrong
+  text_tarray values;
+  splitchar(value.begin(), value.end(), ',', values);
+
+
+  for (int i=0; i< values.size(); ++i) {
+    if (!values[i].empty()) {
+      text_t this_value = values[i];
+      // remove operators for simple search, segments text if necessary
+      format_querystring(this_value, argb, segment); 
+      // add tag info for this field (and other processing)
+      format_field_info(this_value, fields[i], argct, argt, argb);
+      // add into query string
+      if (argct == 2) {
+	// lucene
+	// we don't worry about AND/OR, cos this is done by defaultcombineoperator
+	querystring += this_value+" ";
+      } else {
+	// mgpp
+	if (!querystring.empty()) {
+	  querystring += " "+ combine+ " ";
+	}
+	querystring += this_value;
+      }
+    }
+  }
+}
+
+
+void parse_adv_query_form(text_t &querystring, cgiargsclass &args, bool segment){
+  querystring.clear();
+
+  const int argct = args.getintarg("ct");
+  int argt = 0;// arg t is either not used (lucene) or used for natural/ranked (mgpp), so we set it to 0 = AND, by default
+  int argb = args.getintarg("b");
+  text_t combine;
+  if (argct==1) {
+    combine = "&";
+  }
+  else { // lucene
+    combine = "AND";
+  }
+
+  text_t field = args["fqf"];
+  if (field.empty()) return; // no query
+  text_tarray fields;
+  splitchar(field.begin(), field.end(), ',', fields); 
+  
+  text_t value = args["fqv"];
+  if (value.empty()) return; // somethings wrong
+  text_tarray values;
+  splitchar(value.begin(), value.end(), ',', values);
+
+  text_t comb = args["fqc"];
+  if (comb.empty()) return; //somethings wrong
+  text_tarray combs;
+  splitchar(comb.begin(), comb.end(), ',', combs);
+
+  text_tarray stems;
+  text_tarray folds;
+  if (argct == 1) {// mgpp - lucene doesn't do stem/case
+    text_t stem = args["fqs"];
+    if (stem.empty()) return; // somethings wrong
+    splitchar(stem.begin(), stem.end(), ',', stems);
+    
+    text_t fold = args["fqk"];
+    if (fold.empty()) return; // somethings wrong
+    splitchar(fold.begin(), fold.end(), ',', folds);
+  }
+  
+  for(int i=0; i< values.size(); ++i) {
+    if (!values[i].empty()) {
+      if (i!=0) {
+	if (argct==1) {
+	  if (combs[i-1]=="and") combine = "&";
+	  else if (combs[i-1]=="or")combine = "|";
+	  else if (combs[i-1]=="not")combine = "!";
+	}
+	else { // lucene
+	  if (combs[i-1]=="and") combine = "AND";
+	  else if (combs[i-1]=="or")combine = "OR";
+	  else if (combs[i-1]=="not")combine = "NOT";
+	}
+      }
+      text_t this_value = values[i];
+      // remove operators for simple search, segments text if necessary
+      format_querystring(this_value, argb, segment); 
+      if (argct == 1) { // mgpp only
+	this_value = addstemcase(this_value, stems[i], folds[i], argct);
+      }
+      // add tag info for this field (and other processing)
+      format_field_info(this_value, fields[i], argct, argt, argb);
+      // add into query string
+      if (!querystring.empty()) {
+	querystring += " "+ combine+ " ";
+      }
+      querystring += this_value;
+      
+    }
+  }
+}
+
+// Extended addqueryelem for Human Info project
+void addqueryelem_ex(text_t &querystring, const text_t &tag, 
+		     const text_t &terms, const text_t &stem, 
+		     const text_t &fold,
+		     const text_t& combine, const text_t& word_combine) {
+
+  if (!querystring.empty()) { // have to put and/or
+    querystring += " " + combine + " ";
+  }
+  text_t outtext; outtext.reserve(512);
+  text_t word; word.reserve(100);
+  //unsigned short c;                                                            
+  text_t::const_iterator here = terms.begin();
+  text_t::const_iterator end = terms.end();
+  bool inquote = false, firstword = true;
+
+  text_t word2; word2.reserve(256);
+	
+  while (here !=end) {
+    if (is_unicode_space(*here)) {
+      if (word2 == "AND") { word2.clear(); word2.push_back(7527); word2.appendcarr("AND", 3); word2.push_back(7527); }
+      else if (word2 == "OR") { word2.clear(); word2.push_back(7527); word2.appendcarr("OR", 2); word2.push_back(7527); }
+      else if (word2 == "NOT") { word2.clear(); word2.push_back(7527); word2.appendcarr("NOT", 3); word2.push_back(7527); }
+      else if (word2 == "NEAR") { word2.clear(); word2.push_back(7527); word2.appendcarr("NEAR", 4); word2.push_back(7527); }
+      else if (word2 == "WITHIN") { word2.clear(); word2.push_back(7527); word2.appendcarr("WITHIN", 6); word2.push_back(7527); }
+      if (inquote) {
+	word2.push_back(*here);
+      }
+      word.append(word2); word2.clear();
+			
+      if (!inquote && !word.empty() ) {
+	// found word boundary   
+				
+	if (stem == "1" || fold =="1") {
+	  word += "#";
+	  if (stem == "1") word += "s";
+	  //else word += "u";
+					
+	  if (fold == "1") word += "i";
+	  //else word += "c";
+	}
+	if (firstword) {
+	  firstword = false;
+	} else {
+	  outtext += " " + word_combine + " ";
+	}
+	outtext += "[" + word + "]:"+tag;
+	word.clear();
+      }
+      ++here;
+    } else if (*here == '\"') {
+      word2.push_back(*here);
+      inquote = !inquote;
+      ++here;
+    } else {
+      // not word boundary
+      word2.push_back(*here);
+      ++here;    
+    }
+  }
+	
+  // get last word
+  if (!word2.empty()) {
+    if (word2 == "AND") { word2.clear(); word2.push_back(7527); word2.appendcarr("AND", 3); word2.push_back(7527); }
+    else if (word2 == "OR") { word2.clear(); word2.push_back(7527); word2.appendcarr("OR", 2); word2.push_back(7527); }
+    else if (word2 == "NOT") { word2.clear(); word2.push_back(7527); word2.appendcarr("NOT", 3); word2.push_back(7527); }
+    else if (word2 == "NEAR") { word2.clear(); word2.push_back(7527); word2.appendcarr("NEAR", 4); word2.push_back(7527); }
+    else if (word2 == "WITHIN") { word2.clear(); word2.push_back(7527); word2.appendcarr("WITHIN", 6); word2.push_back(7527); }
+    word.append(word2); word2.clear();
+		
+    if (stem == "1"|| fold == "1") {
+      word += "#";
+      if (stem == "1") word += "s";
+      //else word += "u";
+			
+      if (fold == "1") word += "i";
+      //else word += "c";
+    }
+    if (!outtext.empty()) outtext += " " + word_combine + " ";
+    outtext += "[" + word + "]:"+tag;
+  }
+  querystring += "(" + outtext + ")";
+}
+
+void add_field_info(text_t &querystring, const text_t &tag, int type) {
+
+  if (tag == "") return; // do nothing
+  if (tag == "ZZ" && type == 1) return;  // mgpp doesn't use ZZ tag internally
+  if (type == 1) { //mgpp
+    querystring = "["+querystring+"]:"+tag;
+  } else if (type == 2) { // lucene
+    querystring = tag+":("+querystring+")";
+  }
+    
+}
+
+
+void format_field_info_lucene(text_t &querystring, text_t &tag, int argt, int argb) {
+
+  int type = 2; //lucene
+
+  if (argb==0) { // simple
+    // there will be no & or | as they should have already been removed
+    // just tag the entire thing
+    if (tag != "") {
+      add_field_info(querystring, tag, type);
+    }
+    return;
+  }
+
+  // need to replace & with &&, | with ||
+  text_t::const_iterator here = querystring.begin();
+  text_t::const_iterator end = querystring.end();
+
+  text_t finalquery = "";
+  while (here != end) {
+    if (*here ==  '&') {
+      finalquery.push_back('&');
+      finalquery.push_back('&');
+      while (*(here+1) == '&') {
+	++here;
+      }
+    } 
+    else if (*here == '|') {
+      finalquery.push_back('|');
+      finalquery.push_back('|');
+      while (*(here+1) == '|') {
+	++here;
+      }
+    } 
+    else {
+      finalquery.push_back(*here);
+    }
+    ++here;
+  }
+  querystring = finalquery;
+  add_field_info(querystring, tag, type);
+}
+
+
+void format_field_info_mgpp(text_t &querystring, text_t tag, int argt, int argb) {
+
+  if (tag == "ZZ") tag = ""; // ZZ is a special tag meaning no tag (all fields)
+  if (tag == "" && argb == 1) {
+    return; // no field specifier, advanced mode, the query stays as written
+  }
+
+  int type = 1; // mgpp
+
+  bool simple_and = (argb==0 && argt==0); 
+  text_t finalquery = "";
+  text_t fieldpart ="";
+  text_t queryelem = "";
+  bool in_phrase = false;
+  bool in_field = false;
+
+  text_t::const_iterator here = querystring.begin();
+  text_t::const_iterator end = querystring.end();
+  while (here != end) {
+    if (is_unicode_letdig(*here)  || *here == '&' || is_special_character(type, *here)) {
+      queryelem.push_back(*here);
+    }
+    else if (*here == '|') {
+      in_field = false;
+    }
+    else if (*here == '!' || *here == '(' || *here == ')') {
+      if (!in_phrase) { // ignore these if in_phrase
+	// output field, then output operator
+	in_field = false;
+	if (!queryelem.empty()) {
+	  if (!simple_and && !fieldpart.empty()) {
+	    add_field_info(fieldpart, tag, type);
+	    finalquery += fieldpart;
+	    finalquery.push_back(' ');
+	    fieldpart.clear();
+	  }
+	  fieldpart += queryelem;
+	}
+	if (!fieldpart.empty()) {
+	  add_field_info(fieldpart, tag, type);
+	  finalquery += fieldpart;
+	  finalquery.push_back(' ');
+	}
+	fieldpart.clear();
+	queryelem.clear();
+	finalquery.push_back(*here);
+	finalquery.push_back(' ');
+      }
+    }
+    else if (*here == '"') {
+      queryelem.push_back(*here);
+      if (in_phrase == false) in_phrase = true;
+      else {
+	in_phrase = false;
+      }
+    }
+
+    // Found word boundary, in a phrase
+    else if (in_phrase) {
+      queryelem.push_back(*here);
+    }
+    // Found a word boundary
+    else {
+      if (!queryelem.empty()) {
+	if (queryelem == "&") {
+	  in_field = true;
+	  queryelem.clear();
+	}
+	else if (starts_with(queryelem, "NEAR") || starts_with(queryelem, "WITHIN")) {
+	  
+	  if (argb==1) {
+	    // simple search, these not allowed
+	    in_field = true;
+	    fieldpart += queryelem;
+	    fieldpart.push_back(' ');
+	  }
+	  queryelem.clear();
+	  
+	} 
+	else {
+	  if (!simple_and && !in_field) {
+	    if (!fieldpart.empty()) {
+	      add_field_info(fieldpart, tag, type);
+	      finalquery += fieldpart;
+	      finalquery.push_back(' ');
+	      fieldpart.clear();
+	    } 
+	  }
+	  
+	  fieldpart += queryelem;
+	  fieldpart.push_back(' ');
+	  queryelem.clear();
+	}
+      }
+    }
+    ++here;
+  }
+  // at the end
+  if (!queryelem.empty()) {
+    if (!simple_and && !in_field && !fieldpart.empty()) {
+      add_field_info(fieldpart, tag, type);
+      finalquery += fieldpart;
+      finalquery.push_back(' '); 
+      fieldpart.clear();
+    }
+    fieldpart += queryelem;
+  }
+  if (!fieldpart.empty()) {
+    add_field_info(fieldpart, tag, type);
+    finalquery += fieldpart;
+    fieldpart.clear();
+
+    // doesn't the following just leave a dangling space at the end ?? (used to make mgpp crash)
+    // consider cutting this line
+    finalquery.push_back(' '); 
+  }
+
+  querystring  = finalquery;
+}
+
+
+void format_field_info(text_t &querystring, text_t tag, int argct, int argt, int argb) {  
+  if (argct == 1) {
+    format_field_info_mgpp(querystring, tag, argt, argb);
+  } else if (argct == 2) {
+    format_field_info_lucene(querystring, tag, argt, argb);
+  }
+}
+
+void mgpp_adddateelem(text_t& querystring, const int date)
+{
+  querystring.appendcstr(" [");
+  if(date<0) {
+      querystring.appendcstr("bc");
+      querystring.appendint((date*-1));
+  }
+  else {
+    querystring.appendint(date);
+  }
+  querystring.appendcstr("]:CV");
+}
+
+void lucene_adddateelem(text_t& querystring, const int date)
+{
+  querystring.appendcstr(" CV:(");
+  if(date<0) {
+      querystring.appendcstr("bc");
+      querystring.appendint((date*-1));
+  }
+  else {
+    querystring.appendint(date);
+  }
+  querystring.appendcstr(")");
+}
+
+
+void add_dates(text_t &querystring, int startdate, int enddate, 
+	       int startbc, int endbc, int ct)
+{
+  if(startdate)
+    {
+      int querystringis = 0;
+      text_t::const_iterator here = querystring.begin();
+      text_t::const_iterator end = querystring.end();
+      while(here!=end)
+	{
+	  if(!(isspace((*here)))){
+	    here = end;
+	    querystringis = 1;
+	  }
+	  else
+	    ++here;
+	}
+      //converting BCE dates
+      if(startbc && startdate > 0)
+	{
+	  startdate *= -1;
+	}
+      if(endbc && enddate > 0)
+	{
+	  enddate *= -1;
+	}
+       if(enddate != 0 && enddate<startdate)
+	{
+	  cout<<"enddate too small"<<endl;
+	  return;
+	}
+       if(querystringis)
+	 querystring.appendcstr(" AND");
+       if(!enddate)
+	 {
+	   if (ct==1) {
+	     mgpp_adddateelem(querystring,startdate);
+	   }
+	   else { // lucene
+	     lucene_adddateelem(querystring,startdate);
+	   }
+	 }
+       else{
+	 int nextdate = startdate;
+	 querystring.appendcstr(" (");
+	 while(nextdate<=enddate)
+	   {
+	     if(nextdate!=0) {
+	       if (ct==1) {
+		 mgpp_adddateelem(querystring,nextdate);
+	       }
+	       else { // lucene
+		 lucene_adddateelem(querystring,nextdate);
+	       }
+	     }
+	     ++nextdate;
+	   }
+	 querystring.appendcstr(" )");
+       }
+    }
+
+}
Index: /gsdl/stable/runtime-src/src/recpt/querytools.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/querytools.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/querytools.h	(revision 20131)
@@ -0,0 +1,65 @@
+/**********************************************************************
+ *
+ * querytools.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef QUERYTOOLS_H
+#define QUERYTOOLS_H
+
+#include "cgiargs.h"
+#include "recptproto.h"
+
+void set_query_type_args(ColInfoResponse_t *cinfo, cgiargsclass &args);
+void set_stem_index_args(ColInfoResponse_t *cinfo, cgiargsclass &args);
+
+void set_queryfilter_options (FilterRequest_t &request, const text_t &querystring,
+			      cgiargsclass &args);
+
+void set_queryfilter_options (FilterRequest_t &request, const text_t &querystring1,
+			      const text_t &querystring2, cgiargsclass &args);
+
+// don't hassle the function name ... it's been a long day ;)
+void set_more_queryfilter_options (FilterRequest_t &request, cgiargsclass &args);
+
+void format_querystring (text_t &querystring, int querymode, bool segment);
+
+void add_dates(text_t &querystring, int startdate, int enddate, 
+	       int startbc, int endbc, int ct);
+
+// search history tool
+text_t escape_quotes(const text_t &querystring);
+
+// some query parsing functions for form processing (only for mgpp/lucene collections)
+void parse_reg_query_form(text_t &formattedstring, cgiargsclass &args, bool segment);
+void parse_adv_query_form(text_t &formattedstring, cgiargsclass &args, bool segment);
+
+// Added for Human Info project
+void addqueryelem_ex(text_t &querystring, const text_t &tag, 
+		     const text_t &terms, const text_t &stem, 
+		     const text_t &fold,
+		     const text_t& combine, const text_t& word_combine);
+
+void format_field_info(text_t &querystring, text_t tag, int argct, int argt, int argb);
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/receptionist.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/receptionist.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/receptionist.cpp	(revision 20131)
@@ -0,0 +1,1765 @@
+/**********************************************************************
+ *
+ * receptionist.cpp -- a web interface for the gsdl
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+// following line required to get fstream.filedesc() on darwin (Mac OS X)
+// gcc 2.91 automatically defines this in stream.h
+#define _STREAM_COMPAT  1
+
+#include "receptionist.h"
+#include "recptprototools.h"
+#include "fileutil.h"
+#include "cgiutils.h"
+#include "htmlutils.h"
+#include "gsdltools.h"
+#include "gsdltimes.h"
+#include "OIDtools.h"
+#include <assert.h>
+#include <time.h>
+#include <stdio.h> // for open()
+#include <fcntl.h> // for open() flags
+// following 2 are for printing Last-Modified http header.
+#include <sys/stat.h>
+#include <time.h>
+
+#if defined (GSDL_USE_IOS_H)
+#include <fstream.h>
+#else 
+#include <fstream>
+#endif
+
+void recptconf::clear () {
+  gsdlhome.clear();
+  collecthome.clear();
+  dbhome.clear();
+  collectinfo.erase(collectinfo.begin(), collectinfo.end());
+  collection.clear();
+  collectdir.clear();
+  httpprefix.clear();
+  httpweb.clear();
+  gwcgi.clear();
+  macrofiles.erase(macrofiles.begin(), macrofiles.end());
+  saveconf.clear();
+  usecookies = false;
+  logcgiargs = false;
+  LogDateFormat = LocalTime;
+
+  maintainer.clear();
+  MailServer.clear();
+  LogEvents = Disabled;
+  EmailEvents = Disabled;
+  EmailUserEvents = false;
+
+  languages.erase(languages.begin(), languages.end());
+  encodings.erase(encodings.begin(), encodings.end());
+
+  site_auth = false;
+  HomePageType = "images";
+  HomePageCols = 3;
+  
+  // these default page parameters can always be overriden
+  // in the configuration file
+  pageparams.erase(pageparams.begin(), pageparams.end());
+  pageparams["c"] = ""; 
+  pageparams["l"] = "en"; 
+
+#ifdef MACROPRECEDENCE
+  macroprecedence = MACROPRECEDENCE;
+#else
+  macroprecedence.clear();
+#endif
+}
+
+
+void collectioninfo_t::clear () {
+  gsdl_gsdlhome.clear();
+  gsdl_dbhome.clear();
+
+  info_loaded = false;
+  info.clear();
+}
+
+void languageinfo_t::clear () {
+  longname.clear();
+  defaultencoding.clear();
+}
+
+receptionist::receptionist () {
+  // create a list of cgi arguments
+  // this must be done before the configuration
+
+  cgiarginfo ainfo;
+
+  ainfo.shortname = "e";
+  ainfo.longname = "compressed arguments";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::good;
+  ainfo.argdefault = g_EmptyText;
+  ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, ainfo);
+
+  ainfo.shortname = "a";
+  ainfo.longname = "action";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::none;
+  ainfo.argdefault = g_EmptyText;
+  ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, ainfo);
+
+  // w=western
+  ainfo.shortname = "w";
+  ainfo.longname = "encoding";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::none;
+  ainfo.argdefault = g_EmptyText;
+  ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, ainfo);
+  
+  ainfo.shortname = "nw";
+  ainfo.longname = "new encoding";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::none;
+  ainfo.argdefault = g_EmptyText;
+  ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, ainfo);
+  
+  ainfo.shortname = "c";
+  ainfo.longname = "collection";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::none;
+  ainfo.argdefault = g_EmptyText;
+  ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, ainfo);
+  
+  // the interface language name should use the ISO 639
+  // standard
+  ainfo.shortname = "l";
+  ainfo.longname = "interface language";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::weak;
+  ainfo.argdefault = "en";
+  ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, ainfo);
+  
+  ainfo.shortname = "nl";
+  ainfo.longname = "new language";
+  ainfo.multiplechar = false;
+  ainfo.defaultstatus = cgiarginfo::none;
+  ainfo.argdefault = "0";
+  ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, ainfo);
+  
+  // the GSDL_UID (cookie)
+  ainfo.shortname = "z";
+  ainfo.longname = "gsdl uid";
+  ainfo.multiplechar = true;
+  ainfo.defaultstatus = cgiarginfo::none;
+  ainfo.argdefault = g_EmptyText;
+  ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, ainfo);
+}
+
+
+void receptionist::add_action (action *theaction) {
+  // make sure we have an action to add
+  if (theaction == NULL) return;
+
+  // add this action to the list of actions
+  actions.addaction(theaction);
+  
+  // add the cgi arguments from this action
+  argsinfo.addarginfo (NULL, *(theaction->getargsinfo()));
+}
+
+
+void receptionist::add_browser (browserclass *thebrowser) {
+  // make sure we have a browser to add
+  if (thebrowser == NULL) return;
+
+  // add this browser to the list of browsers
+  browsers.addbrowser(thebrowser);
+}
+
+
+void receptionist::setdefaultbrowser (const text_t &browsername) {
+  browsers.setdefaultbrowser (browsername);
+}
+
+
+// configure should be called for each line in the
+// configuration files to configure the receptionist and everything
+// it contains. The configuration should take place after everything
+// has been added but before the initialisation.
+
+void receptionist::configure (const text_t &key, const text_tarray &cfgline) {
+  // configure the receptionist
+
+   
+   
+  if (cfgline.size() >= 1) {
+    cgiarginfo *info = NULL;
+    if (key == "gsdlhome") {
+      configinfo.gsdlhome = cfgline[0];
+      if (configinfo.dbhome.empty()) configinfo.dbhome = cfgline[0];
+    }
+    else if (key == "collecthome") configinfo.collecthome = cfgline[0];
+    else if (key == "gdbmhome") configinfo.dbhome = cfgline[0];
+    else if (key == "collection") {
+      configinfo.collection = cfgline[0];
+      // also need to set the default arg to this collection
+      if ((info = argsinfo.getarginfo("c")) != NULL) {
+	info->defaultstatus = cgiarginfo::good;
+	info->argdefault = cfgline[0];
+      }
+      
+    }
+    else if (key == "collectdir") configinfo.collectdir = cfgline[0];
+    else if (key == "httpprefix") configinfo.httpprefix = cfgline[0];
+    else if (key == "httpweb") configinfo.httpweb = cfgline[0];
+    else if (key == "gwcgi") configinfo.gwcgi = cfgline[0];
+    else if (key == "macrofiles") {
+      // want to append to macrofiles (i.e. may be several config files
+      // contributing, maybe from several collections).
+      text_tarray::const_iterator here = cfgline.begin();
+      text_tarray::const_iterator end = cfgline.end();
+      while (here != end) {
+	configinfo.macrofiles.insert (*here);
+	++here;
+      }
+    }
+    else if (key == "saveconf") configinfo.saveconf = cfgline[0];
+    else if (key == "usecookies") configinfo.usecookies = (cfgline[0] == "true");
+    else if (key == "logcgiargs") configinfo.logcgiargs = (cfgline[0] == "true");
+    else if (key == "maintainer") configinfo.maintainer = cfgline[0];
+    else if (key == "MailServer") configinfo.MailServer = cfgline[0];
+    else if (key == "LogDateFormat") {
+      if (cfgline[0] == "UTCTime") configinfo.LogDateFormat = UTCTime;
+      else if (cfgline[0] == "Absolute") configinfo.LogDateFormat = Absolute;
+    } 
+    else if (key == "LogEvents") {
+      if (cfgline[0] == "CollectorEvents") configinfo.LogEvents = CollectorEvents;
+      else if (cfgline[0] == "AllEvents") configinfo.LogEvents = AllEvents;
+    } 
+    else if (key == "EmailEvents") {
+      if (cfgline[0] == "CollectorEvents") configinfo.EmailEvents = CollectorEvents;
+      else if (cfgline[0] == "AllEvents") configinfo.EmailEvents = AllEvents;
+    } 
+    else if (key == "EmailUserEvents") configinfo.EmailUserEvents = (cfgline[0] == "true");
+    else if (key == "pageparam") {
+      if (cfgline.size() >= 2) configinfo.pageparams[cfgline[0]] = cfgline[1];
+      else configinfo.pageparams[cfgline[0]] = "";
+    }
+    else if (key == "macroprecedence") configinfo.macroprecedence = cfgline[0];
+    else if (key == "collectinfo") {
+      if (cfgline.size() == 3) {
+	// for backwards compatability with older collections that only use
+	// gsdlhome and dbhome
+	collectioninfo_t cinfo;
+	cinfo.gsdl_gsdlhome = cfgline[1];
+	cinfo.gsdl_collecthome = filename_cat(cfgline[1],"collect");
+	cinfo.gsdl_dbhome = cfgline[2];
+	configinfo.collectinfo[cfgline[0]] = cinfo;
+      }
+      else if (cfgline.size() >= 4) {
+	collectioninfo_t cinfo;
+	cinfo.gsdl_gsdlhome = cfgline[1];
+	cinfo.gsdl_collecthome = cfgline[2];
+	cinfo.gsdl_dbhome = cfgline[3];
+	configinfo.collectinfo[cfgline[0]] = cinfo;
+      }
+    }
+
+    // Read in the value for the site_auth directive either true or false
+    else if (key == "site_auth") configinfo.site_auth = (cfgline[0] == "true");
+
+    else if (key == "site_group")
+       joinchar(cfgline,',',configinfo.site_group);
+       
+    else if (key == "SiteFormat") {
+       if (cfgline[0] == "HomePageType") {
+	  configinfo.HomePageType = cfgline[1];
+       } else if (cfgline[0] == "HomePageCols") {
+	  configinfo.HomePageCols = cfgline[1].getint();
+       }
+    }
+       
+    else if (key == "cgiarg") {
+      // get shortname
+      bool seen_defaultstatus = false;
+      text_t subkey, subvalue;
+      text_t shortname;
+      text_t::const_iterator cfglinesub_here;
+      text_tarray::const_iterator cfgline_here = cfgline.begin();
+      text_tarray::const_iterator cfgline_end = cfgline.end();
+      while (cfgline_here != cfgline_end) {
+	cfglinesub_here = getdelimitstr((*cfgline_here).begin(),
+					(*cfgline_here).end(), '=', subkey);
+	if (subkey == "shortname") {
+	  shortname = substr (cfglinesub_here, (*cfgline_here).end());
+	}
+	++cfgline_here;
+      }
+
+      // if we found the shortname process the line again filling in values
+      if (!shortname.empty()) {
+	cgiarginfo &chinfo = argsinfo[shortname];
+	chinfo.shortname = shortname; // in case this is a new argument
+	
+	cfgline_here = cfgline.begin();
+	while (cfgline_here != cfgline_end) {
+	  cfglinesub_here = getdelimitstr((*cfgline_here).begin(),
+					  (*cfgline_here).end(), '=', subkey);
+	  subvalue = substr (cfglinesub_here, (*cfgline_here).end());
+
+	  if (subkey == "longname") chinfo.longname = subvalue;
+	  else if (subkey == "multiplechar") chinfo.multiplechar = (subvalue == "true");
+	  else if (subkey == "defaultstatus") {
+	    seen_defaultstatus = true;
+	    if (subvalue == "none") chinfo.defaultstatus = cgiarginfo::none;
+	    else if (subvalue == "weak") chinfo.defaultstatus = cgiarginfo::weak;
+	    else if (subvalue == "good") chinfo.defaultstatus = cgiarginfo::good;
+	    else if (subvalue == "config") chinfo.defaultstatus = cgiarginfo::config;
+	    else if (subvalue == "imperative") chinfo.defaultstatus = cgiarginfo::imperative;
+	  }
+	  else if (subkey == "argdefault") {
+	    chinfo.argdefault = subvalue;
+	    if (!seen_defaultstatus) chinfo.defaultstatus = cgiarginfo::config;
+	  }
+	  else if (subkey == "savedarginfo") {
+	    if (subvalue == "mustnot") chinfo.savedarginfo = cgiarginfo::mustnot;
+	    else if (subvalue == "can") chinfo.savedarginfo = cgiarginfo::can;
+	    else if (subvalue == "must") chinfo.savedarginfo = cgiarginfo::must;
+	  }
+	  
+	  ++cfgline_here;
+	}
+      }
+
+    } else if (key == "Encoding") {
+
+      configure_encoding (cfgline);
+
+    } else if (key == "Language") {
+      text_t subkey, subvalue, shortname;
+      languageinfo_t lang;
+      text_t::const_iterator cfglinesub_here;
+      text_tarray::const_iterator cfgline_here = cfgline.begin();
+      text_tarray::const_iterator cfgline_end = cfgline.end();
+      while (cfgline_here != cfgline_end) {
+	cfglinesub_here = getdelimitstr((*cfgline_here).begin(),
+					(*cfgline_here).end(), '=', subkey);
+	if (subkey == "shortname") {
+	  shortname = substr (cfglinesub_here, (*cfgline_here).end());
+	} else if (subkey == "longname") {
+	  lang.longname = substr (cfglinesub_here, (*cfgline_here).end());
+	} else if (subkey == "default_encoding") {
+	  lang.defaultencoding = substr (cfglinesub_here, (*cfgline_here).end());
+	}
+	++cfgline_here;
+      }
+      if (!shortname.empty()) {
+	if (lang.longname.empty()) lang.longname = shortname;
+	configinfo.languages[shortname] = lang;
+      }
+    }
+  }
+  
+  // configure the actions
+  actionptrmap::iterator actionhere = actions.begin ();
+  actionptrmap::iterator actionend = actions.end ();
+
+  while (actionhere != actionend) {
+    assert ((*actionhere).second.a != NULL);
+    if ((*actionhere).second.a != NULL) 
+      (*actionhere).second.a->configure(key, cfgline);
+
+    ++actionhere;
+  }
+
+  // configure the protocols
+  recptprotolistclass::iterator protohere = protocols.begin ();
+  recptprotolistclass::iterator protoend = protocols.end ();
+
+  while (protohere != protoend) {
+    assert ((*protohere).p != NULL);
+    comerror_t err;
+    if ((*protohere).p != NULL) 
+      (*protohere).p->configure(key, cfgline, err);
+    
+    ++protohere;
+  }
+
+  // configure the browsers
+  browserptrmap::iterator browserhere = browsers.begin ();
+  browserptrmap::iterator browserend = browsers.end ();
+
+  while (browserhere != browserend) {
+    assert ((*browserhere).second.b != NULL);
+    if ((*browserhere).second.b != NULL) 
+      (*browserhere).second.b->configure(key, cfgline);
+    
+    ++browserhere;
+  }
+}
+
+
+void receptionist::configure (const text_t &key, const text_t &value) {
+  text_tarray cfgline;
+  cfgline.push_back (value);
+  configure(key, cfgline);
+}
+
+
+// init should be called after all the actions and protocols have been
+// added to the receptionist and after everything has been configured but
+// before any pages are created.  It returns true on success and false on
+// failure. If false is returned getpage should not be called (without
+// producing meaningless output), instead an error page should be produced
+// by the calling code.
+bool receptionist::init (ostream &logout) {
+
+  // first configure collectdir
+  if (!configinfo.collection.empty()) {
+
+    // collection specific mode
+
+    text_t collectdir = configinfo.gsdlhome;
+
+    if (!configinfo.collectdir.empty()) {
+      // has already been configured
+      collectdir = configinfo.collectdir;
+    } else {
+
+      // decide where collectdir is by searching for collect.cfg
+      // look in $GSDLHOME/collect/collection-name/etc/collect.cfg and
+      // then $GSDLHOME/etc/collect.cfg
+      collectdir = filename_cat (configinfo.gsdlhome, "collect");
+      collectdir = filename_cat (collectdir, configinfo.collection);
+      text_t filename = filename_cat (collectdir, "etc");
+      filename = filename_cat (filename, "collect.cfg");
+      
+      if (!file_exists(filename)) collectdir = configinfo.gsdlhome;
+    }
+
+    configure("collectdir", collectdir);
+
+  }
+  else {
+
+    text_t collecthome;
+    if (configinfo.collecthome.empty()) {
+      collecthome = filename_cat(configinfo.gsdlhome,"collect");
+    }
+    else {
+      collecthome = configinfo.collecthome;
+    }
+
+    configure("collecthome", collecthome);
+
+    // for backwards compatability collectdir set to gsdlhome
+    // (possible it could now be removed)
+    configure("collectdir", configinfo.gsdlhome); 
+  } 
+
+
+  // read in the macro files
+  if (!read_macrofiles (logout)) return false;
+
+  // there must be at least one action defined
+  if (actions.empty()) {
+    logout << "Error: no actions have been added to the receptionist\n";
+    return false;
+  }
+
+  // there must be at least one browser defined
+  if (browsers.empty()) {
+    logout << "Error: no browsers have been added to the receptionist\n";
+    return false;
+  }
+
+  // create a saveconf string if there isn't one already
+  if (configinfo.saveconf.empty())
+    configinfo.saveconf = create_save_conf_str (argsinfo, logout);
+
+  // check the saveconf string
+  if (!check_save_conf_str (configinfo.saveconf, argsinfo, logout))
+    return false;
+
+  // set a random seed
+  srand (time(NULL));
+
+  // if maintainer email address is something dodgy (for now I'll define
+  // dodgy as being anything that doesn't contain '@') disable EmailEvents
+  // and EmailUserEvents (we don't strictly need to disable EmailUserEvents
+  // in this case but we will as it seems likely that MailServer will also
+  // be screwed up if maintainer is).
+  text_t::const_iterator maintainer_end = configinfo.maintainer.end ();
+  text_t::const_iterator maintainer_here = findchar ((text_t::const_iterator)configinfo.maintainer.begin(),
+						     maintainer_end, '@');
+  if (maintainer_here == maintainer_end) {
+    configinfo.EmailEvents = Disabled;
+    configinfo.EmailUserEvents = Disabled;
+  } else {
+    // if MailServer isn't set it should default to mail.maintainer-domain
+    if (configinfo.MailServer.empty()) {
+      configinfo.MailServer = "mail." + substr (maintainer_here+1, maintainer_end);
+    }
+  }
+
+  // init the actions
+  actionptrmap::iterator actionhere = actions.begin ();
+  actionptrmap::iterator actionend = actions.end ();
+  while (actionhere != actionend) {
+    if (((*actionhere).second.a == NULL) || 
+	!(*actionhere).second.a->init(logout)) return false;
+    ++actionhere;
+  }
+
+  // init the protocols
+  recptprotolistclass::iterator protohere = protocols.begin ();
+  recptprotolistclass::iterator protoend = protocols.end ();
+  while (protohere != protoend) {
+    comerror_t err;    
+    if (((*protohere).p == NULL) ||
+	!(*protohere).p->init(err, logout)) return false;
+    ++protohere;
+  }
+
+  // init the browsers
+  browserptrmap::iterator browserhere = browsers.begin ();
+  browserptrmap::iterator browserend = browsers.end ();
+  while (browserhere != browserend) {
+    if (((*browserhere).second.b == NULL) || 
+	!(*browserhere).second.b->init(logout)) return false;
+    ++browserhere;
+  }
+
+  return true;
+}
+
+// get the default encoding for the given language - if it fails for any
+// reason return ""
+text_t receptionist::get_default_encoding (const text_t &language) {
+  
+  // make sure language is valid
+  if (configinfo.languages.find(language) == configinfo.languages.end()) return "";
+
+  text_t default_encoding = configinfo.languages[language].defaultencoding;
+
+  // make sure the encoding is valid
+  if (converters.find(default_encoding) == converters.end()) {
+    // we don't support the encoding specified as default for this language
+    if (configinfo.encodings.size()==1) {
+      // only 1 encoding specified in main.cfg, so use it
+      return configinfo.encodings.begin()->second;
+    }
+    return "";
+  }
+
+  return default_encoding;
+}
+
+// parse_cgi_args parses cgi arguments into an argument class.
+// This function should be called for each page request. It returns false
+// if there was a major problem with the cgi arguments.
+bool receptionist::parse_cgi_args (const text_t &argstr, 
+				   fileupload_tmap &fileuploads, 
+				   cgiargsclass &args, 
+				   ostream &logout, text_tmap &fcgienv) {
+
+  // get an initial list of cgi arguments
+  args.clear();
+  split_cgi_args (argsinfo, argstr, args);
+
+  // expand the compressed argument (if there was one)
+  if (!expand_save_args (argsinfo, configinfo.saveconf, args, logout)) return false;
+
+  // add the defaults
+  add_default_args (argsinfo, args, logout);
+
+  // add any file upload arguments
+  add_fileupload_args(argsinfo, args, fileuploads, logout);
+
+  // get the cookie
+  if (configinfo.usecookies) get_cookie(args["z"], fcgienv);
+  
+  // if we're changing languages, set the encoding to the default for the new language
+  if (args["nl"] == "1") {
+    args["nw"] = get_default_encoding(args["l"]);
+  }
+
+  // get the input encoding
+  // if encoding isn't set, set it to the default for the current language
+  if ((args.getarg("w") == NULL) || args["w"].empty()) {
+    args["w"] = get_default_encoding(args["l"]);
+  }
+
+  text_t &arg_w = args["w"];
+
+  inconvertclass defaultinconvert;
+  inconvertclass *inconvert = converters.get_inconverter (arg_w);
+  if (inconvert == NULL) inconvert = &defaultinconvert;
+
+  // see if the next page will have a different encoding
+  if (args.getarg("nw") != NULL) arg_w = args["nw"];
+
+  // convert arguments which aren't in unicode to unicode
+  args_tounicode (args, *inconvert);
+
+
+  // decide on the output conversion class (needed for checking the external
+  // cgi arguments)
+  rzwsoutconvertclass defaultoutconverter;
+  rzwsoutconvertclass *outconverter = converters.get_outconverter (arg_w);
+  if (outconverter == NULL) outconverter = &defaultoutconverter;
+  outconverter->reset();
+
+  // check the main cgi arguments
+  if (!check_mainargs (args, logout)) return false;
+
+  // check the arguments for the action
+  action *a = actions.getaction (args["a"]);
+  if (a != NULL) {
+    if (!a->check_cgiargs (argsinfo, args, &protocols, logout)) return false;
+  } else {
+    // the action was not found!!
+    outconvertclass text_t2ascii;
+    logout << text_t2ascii << "Error: the action \"" << args["a"] 
+	   << "\" could not be found.\n";
+    return false;
+  }
+
+  // check external cgi arguments for each action
+  actionptrmap::iterator actionhere = actions.begin ();
+  actionptrmap::iterator actionend = actions.end ();
+  while (actionhere != actionend) {
+    assert ((*actionhere).second.a != NULL);
+    if ((*actionhere).second.a != NULL) {
+      if (!(*actionhere).second.a->check_external_cgiargs (argsinfo, args, *outconverter,
+							   configinfo.saveconf, logout))
+	return false;
+    }
+    ++actionhere;
+  }
+
+  // the action might have changed but we will assume that
+  // the cgiargs were checked properly when the change was made
+
+  return true;
+}
+
+// returns true if cookie already existed, false
+// if it was generated
+bool receptionist::get_cookie (text_t &cookie, text_tmap &fcgienv) {
+
+  text_t cookiestring = gsdl_getenv ("HTTP_COOKIE", fcgienv);
+  if (!cookiestring.empty())
+  {
+    text_t::const_iterator end = cookiestring.end();  
+    text_t::const_iterator here = findchar ((text_t::const_iterator)cookiestring.begin(), end, 'G');
+
+    while (here+9 < end) { 
+    
+      if (substr(here, here+8) == "GSDL_UID") {
+	cookie = substr (here+9, findchar (here+9, end, ';')); 
+	return true;
+      }
+      ++here;
+      here = findchar (here, end, 'G');
+    }
+  }
+
+  cookie.clear();
+  text_t host = gsdl_getenv("REMOTE_ADDR", fcgienv);
+  time_t ttime = time(NULL);
+  if (!host.empty()) {
+    cookie += host;
+    cookie.push_back ('-');
+  }
+  cookie += text_t(ttime);
+  
+  return false;
+}
+
+// as above but just tests if cookie exists
+bool receptionist::get_cookie (text_tmap &fcgienv) {
+
+  text_t c = gsdl_getenv("HTTP_COOKIE", fcgienv);
+  if (!c.empty()) {
+    text_t cookiestring = c;
+    
+    text_t::const_iterator end = cookiestring.end();  
+    text_t::const_iterator here = findchar ((text_t::const_iterator)cookiestring.begin(), end, 'G');
+
+    while (here+9 < end) { 
+      if (substr(here, here+8) == "GSDL_UID") return true;
+      ++here;
+      here = findchar (here, end, 'G');
+    }
+  }
+  return false;
+}
+
+bool receptionist::log_cgi_args (cgiargsclass &args, ostream &logout, text_tmap &fcgienv) {
+
+  // see if we want to log the cgi arguments
+  if (!configinfo.logcgiargs) return true;
+  
+  text_t host = gsdl_getenv ("REMOTE_HOST", fcgienv);
+  text_t script_name = gsdl_getenv ("SCRIPT_NAME", fcgienv);
+  if (host.empty()) host = gsdl_getenv ("REMOTE_ADDR", fcgienv);
+  text_t browser = gsdl_getenv ("HTTP_USER_AGENT", fcgienv);
+
+  cgiargsclass::const_iterator args_here = args.begin();
+  cgiargsclass::const_iterator args_end = args.end();
+
+  text_t argstr;
+  bool first = true;
+  while (args_here != args_end) {
+    if (!first) argstr += ", ";
+    argstr += (*args_here).first + "=" + (*args_here).second.value;
+    first = false;
+    ++args_here;
+  }
+
+  text_t logfile = filename_cat (configinfo.dbhome, "etc", "usage.txt");
+
+  text_t logstr = script_name;
+  logstr += " " + host;
+  logstr += " [";
+  if (configinfo.LogDateFormat == UTCTime) {
+    logstr += get_date (false);
+  } else if (configinfo.LogDateFormat == Absolute) {
+    time_t ttime = time(NULL);
+    logstr += ttime;
+  } else {
+    // LocalTime
+    logstr += get_date (true);
+  }
+  logstr += "] (" + argstr + ") \"";
+  logstr += browser;
+  logstr += "\"\n";
+
+  return append_logstr (logfile, logstr, logout);
+}
+
+bool receptionist::append_logstr (const text_t &filename, const text_t &logstr,
+				  ostream &logout) {
+
+  utf8outconvertclass text_t2utf8;
+  char *lfile = filename.getcstr();
+
+  int fd = open(lfile, O_WRONLY | O_APPEND);
+  
+  if (fd == -1) {
+    logout << "Error: Couldn't open file " << lfile << "\n";
+    delete []lfile;
+    return false;
+  }
+
+  // lock_val is set to 0 if file is locked successfully
+  int lock_val = 1;
+  GSDL_LOCK_FILE (fd);
+  if (lock_val == 0) {
+    text_t tmp_log_str(logstr); // so we don't pass a const to setinput...
+    text_t2utf8.setinput(&tmp_log_str);
+    char *buffer=new char[logstr.size()];
+    size_t num_chars;
+    convertclass::status_t status;
+    text_t2utf8.convert(buffer, logstr.size(), num_chars, status);
+    // ignore status - assume it is "finished" as buffer is big enough
+    write(fd, buffer, num_chars);
+    GSDL_UNLOCK_FILE (fd);
+    delete []buffer;
+  } else {
+    logout << "Error: Couldn't lock file " << lfile << "\n";
+    close(fd);
+    delete []lfile;
+    return false;
+  }
+
+  close(fd);
+		
+  delete []lfile;
+  return true;
+}
+
+text_t receptionist::expandmacros (const text_t &astring, cgiargsclass &args, 
+				   ostream &logout) {
+  text_t outstring;
+  outconvertclass text_t2ascii;
+
+  action *a = actions.getaction (args["a"]);
+  prepare_page (a, args, text_t2ascii, logout);
+  disp.expandstring (displayclass::defaultpackage, astring, outstring);
+  return outstring;
+}
+
+// produce_cgi_page will call get_cgihead_info and 
+// produce_content in the appropriate way to output a cgi header and
+// the page content (if needed). If a page could not be created it
+// will return false
+bool receptionist::produce_cgi_page (cgiargsclass &args, ostream &contentout, 
+				     ostream &logout, text_tmap &fcgienv) {
+  outconvertclass text_t2ascii;
+
+  response_t response;
+  text_t response_data;
+
+  // produce cgi header
+  get_cgihead_info (args, response, response_data, logout, fcgienv);
+  if (response == location) {
+    // location response (url may contain macros!!)
+    response_data = expandmacros (response_data, args, logout);
+
+    contentout << text_t2ascii << "Location: " << response_data << "\n\n";
+    contentout << flush;
+
+    return true;
+  } else if (response == content) {
+    // content response
+
+#ifdef GSDL_NOCACHE
+    contentout << "Expires: Mon, 26 Jul 1997 05:00:00 GMT\n"; // date in the past
+    tm *tm_ptr = NULL;
+    time_t t = time(NULL);
+    tm_ptr = gmtime (&t);
+    if (tm_ptr != NULL) {
+      char *timestr = new char[128];
+      strftime (timestr, 128, "%a, %d %b %Y %H:%M:%S", tm_ptr);
+      contentout << "Last-Modified: " << timestr << " GMT\n"; // always modified
+      delete []timestr;
+    }
+    contentout << "Cache-Control: no-cache, must-revalidate\n"; // HTTP/1.1
+    contentout << "Pragma: no-cache\n"; // HTTP/1.0
+
+#else
+
+    // use the later of build.cfg and collect.cfg modification times
+    // as the Last-Modified: header, for caching values
+    struct stat file_info;
+    time_t latest=0;
+
+    text_t collectname="";
+    collectname=args["c"];
+    if (collectname != "") {
+
+      text_t collecthome;
+      if (!configinfo.collecthome.empty()) {
+	collecthome = configinfo.collecthome;
+      }    
+      else {
+	collecthome=filename_cat(configinfo.gsdlhome,"collect");
+      }
+      text_t collectdir=filename_cat(collecthome,collectname);
+      
+      text_t buildcfg=filename_cat(collectdir,"index");
+      buildcfg=filename_cat(buildcfg,"build.cfg");
+      char *buildcfg_ptr=buildcfg.getcstr();
+      text_t collectcfg=filename_cat(collectdir,"etc");
+      collectcfg=filename_cat(collectcfg,"collect.cfg");
+      char *collectcfg_ptr=collectcfg.getcstr();
+
+      if (stat(buildcfg_ptr, &file_info)) {
+	// we got an error. Currently don't handle error :(
+	//	logout << 
+      } else {
+	latest=file_info.st_mtime;
+      }
+    
+      if (stat(collectcfg_ptr, &file_info)) {
+	// error - unhandled for now
+      } else {
+	if (latest<file_info.st_mtime) latest=file_info.st_mtime;
+      }
+      delete []buildcfg_ptr;
+      delete []collectcfg_ptr;
+
+      if (latest>0) {
+	// print out modified time, "DDD, dd MMM YYYY hh:mm:ss" format
+	// c library takes care of mem for this string... (has \n at end!!!!)
+	// latest is currently local time, convert to UTC.
+	struct tm* utc_latest;
+	utc_latest=gmtime(&latest);
+	contentout << "Last-Modified: " << asctime(utc_latest);
+      }
+    } // end of collection != ""
+
+#endif
+
+    contentout << text_t2ascii << "Content-type: " << response_data << "\n\n";
+  }
+  else if (response == undecided_location) {
+    // Wait until later to output the target location
+    // Used for the "I'm feeling lucky" functionality
+  }
+  else {
+    // unknown response
+    logout << "Error: get_cgihead_info returned an unknown response type.\n";
+    return false;
+  }
+
+  // produce cgi page
+  if (!produce_content (args, contentout, logout)) return false;
+
+  // flush contentout
+  contentout << flush;
+  return true;
+}
+
+
+// get_cgihead_info determines the cgi header information for
+// a set of cgi arguments. If response contains location then
+// response_data contains the redirect address. If reponse
+// contains content then reponse_data contains the content-type.
+// Note that images can now be produced by the receptionist.
+// Note also, alternative for get_cgihead_info below which
+// stores the information in a text_tmap so it is more easily digested
+
+void receptionist::get_cgihead_info (cgiargsclass &args, response_t &response,
+				     text_t &response_data, ostream &logout, 
+				     text_tmap &fcgienv) {
+  outconvertclass text_t2ascii;
+
+  // get the action
+  action *a = actions.getaction (args["a"]);
+  if (a != NULL) {
+    a->get_cgihead_info (args, &protocols, response, response_data, logout);
+
+  } else {
+    // the action was not found!!
+    logout << text_t2ascii << "Error receptionist::get_cgihead_info: the action \"" 
+	   << args["a"] << "\" could not be found.\n";
+    response = content;
+    response_data = "text/html";
+  }
+
+  // add the encoding information
+  if (response == content) {
+    if (converters.find(args["w"]) != converters.end()) {
+      response_data += "; charset=" + args["w"];
+    } else {
+      // default to latin 1
+      response_data += "; charset=ISO-8859-1";
+    }
+
+    // add cookie if required
+    if (configinfo.usecookies && !get_cookie(fcgienv))
+      response_data += "\nSet-Cookie: GSDL_UID=" + args["z"]
+	+ "; expires=Fri, 25-Dec-2037 00:00:00 GMT";
+  }
+}
+
+
+// Alternative version of get_cgihead_info, stores fielded infomation
+// in text_tmap rather than concatenated string
+void receptionist::get_cgihead_info (cgiargsclass &args, text_tmap &headers,
+				     ostream &logout, text_tmap &fcgienv) {
+
+  response_t response;
+  text_t response_data;
+
+  // get the action
+  action *a = actions.getaction (args["a"]);
+  if (a != NULL) {
+    a->get_cgihead_info (args, &protocols, response, response_data, logout);
+
+  } else {
+    // the action was not found!!
+    outconvertclass text_t2ascii;
+    logout << text_t2ascii << "Error receptionist::get_cgihead_info: the action \"" 
+	   << args["a"] << "\" could not be found.\n";
+    response = content;
+    response_data = "text/html";
+  }
+
+  if (response == location) {
+    response_data = expandmacros(response_data, args, logout);
+    headers["Location"] = response_data;
+    return;
+  }
+
+  // add the encoding information
+  if (response == content) {
+
+    if (converters.find(args["w"]) != converters.end()) {
+      headers["content-encoding"] = args["w"];
+      response_data += "; charset=" + args["w"];
+    } else {
+      // default to utf-8
+      headers["content-encoding"] = "utf-8";
+      response_data += "; charset=utf-8";
+    }
+
+    headers["content-type"] = response_data;
+
+  }
+
+}
+
+
+
+// produce the page content
+bool receptionist::produce_content (cgiargsclass &args, ostream &contentout,
+				    ostream &logout) {
+
+  // decide on the output conversion class
+  text_t &arg_w = args["w"];
+  rzwsoutconvertclass defaultoutconverter;
+  rzwsoutconvertclass *outconverter = converters.get_outconverter (arg_w);
+  if (outconverter == NULL) outconverter = &defaultoutconverter;
+  outconverter->reset();
+
+  // needed for 16-bit unicode only - big endian marker 0xfeff (RFC 2781)
+  if (arg_w=="utf-16be") {
+    contentout << '\xfe' << '\xff' ;
+  }
+
+  recptproto *collectproto = protocols.getrecptproto (args["c"], logout);
+  if (collectproto != NULL) {
+    // get browsers to process OID
+    text_t OID = args["d"];
+    if (OID.empty()) OID = args["cl"];
+    if (!OID.empty()) {
+      text_tset metadata;
+      text_tarray OIDs;
+      OIDs.push_back (OID);
+      if (!is_top(OID)) OIDs.push_back (OID + ".pr");
+      FilterResponse_t response;
+      metadata.insert ("childtype");
+      if (get_info (OIDs, args["c"], args["l"], metadata, false, collectproto, response, logout)) {
+	text_t classifytype;
+	if (!response.docInfo[0].metadata["childtype"].values[0].empty())
+	  classifytype = response.docInfo[0].metadata["childtype"].values[0];
+	else if (!is_top (OID)) {
+	  // not sure why this is occasionally not set, but it will
+	  // cause a segfault... possibly if built with no_text? jrm21
+	  if (response.docInfo[1].metadata.find("childtype")
+	      == response.docInfo[1].metadata.end()) {
+	    cerr << "receptionist: no childtype element in metadata map!"
+		 << endl;
+	  } else {
+	    if (!response.docInfo[1].metadata["childtype"].values[0].empty())
+	      classifytype = response.docInfo[1].metadata["childtype"].values[0];
+	  }
+	}
+	browserclass *b = browsers.getbrowser (classifytype);
+	b->processOID (args, collectproto, logout);
+      }
+    }
+  
+    // translate "d" and "cl" arguments if required
+    translate_OIDs (args, collectproto, logout);
+  }
+  
+  // produce the page using the desired action
+  action *a = actions.getaction (args["a"]);
+  if (a != NULL) {
+    if (a->uses_display(args)) prepare_page (a, args, (*outconverter), logout);
+    if (!a->do_action (args, &protocols, &browsers, disp, (*outconverter), contentout, logout))
+      return false;
+  } else {
+    // the action was not found!!
+    outconvertclass text_t2ascii;
+
+    logout << text_t2ascii << "Error receptionist::produce_content: the action \"" 
+	   << args["a"] << "\" could not be found.\n";
+    
+    contentout << (*outconverter) 
+	       << "<html>\n"
+	       << "<head>\n"
+	       << "<title>Error</title>\n"
+	       << "</head>\n"
+	       << "<body>\n"
+	       << "<h2>Oops!</h2>\n"
+	       << "Undefined Page. The action \"" 
+	       << args["a"] << "\" could not be found.\n"
+	       << "</body>\n"
+	       << "</html>\n";
+  }
+  return true;
+}
+
+
+// returns the compressed argument ("e") corresponding to the argument
+// list. This can be used to save preferences between sessions.
+text_t receptionist::get_compressed_arg (cgiargsclass &args, ostream &logout) {
+  // decide on the output conversion class
+  text_t &arg_w = args["w"];
+  rzwsoutconvertclass defaultoutconverter;
+  rzwsoutconvertclass *outconverter = converters.get_outconverter (arg_w);
+  if (outconverter == NULL) outconverter = &defaultoutconverter;
+  outconverter->reset();
+
+  text_t compressed_args;
+  if (compress_save_args (argsinfo, configinfo.saveconf, args, 
+			  compressed_args, *outconverter, logout))
+    return compressed_args;
+
+  return g_EmptyText;
+}
+
+
+// will read in all the macro files. If one is not found an
+// error message will be written to logout and the method will
+// return false.
+bool receptionist::read_macrofiles (ostream &logout) {
+  outconvertclass text_t2ascii;
+
+  // redirect the error output to logout
+  ostream *savedlogout = disp.setlogout (&logout);
+
+  // unload any macros that were previously loaded - this allows us to call
+  // this function a second time to reload all the macro files (useful for
+  // reading in changed macro files in server versions of greenstone)
+  disp.unloaddefaultmacros();
+
+  // load up the default macro files, the collection directory
+  // is searched first for the file (if this is being used in
+  // collection specific mode) and then the main directory(s)
+  text_t colmacrodir = filename_cat (configinfo.collectdir, "macros");
+
+  text_tset maindirs;
+  text_t gsdlmacrodir = filename_cat (configinfo.gsdlhome, "macros");
+  maindirs.insert (gsdlmacrodir);
+  colinfo_tmap::iterator colhere = configinfo.collectinfo.begin();
+  colinfo_tmap::iterator colend = configinfo.collectinfo.end();
+  while (colhere != colend) {
+    if (!((*colhere).second.gsdl_gsdlhome).empty()) {
+      gsdlmacrodir = filename_cat ((*colhere).second.gsdl_gsdlhome, "macros");
+      maindirs.insert (gsdlmacrodir);
+    }
+    ++colhere;
+  }
+
+  text_tset::iterator arrhere = configinfo.macrofiles.begin();
+  text_tset::iterator arrend = configinfo.macrofiles.end();
+  text_t filename;
+  while (arrhere != arrend) {
+    bool foundfile = false;
+
+    // try in the collection directory if this is being
+    // run in collection specific mode
+    if (!configinfo.collection.empty()) {
+      filename = filename_cat (colmacrodir, *arrhere);
+      if (file_exists (filename)) {
+	disp.loaddefaultmacros(filename);
+	foundfile = true;
+      }
+    }
+
+    // if we haven't found the macro file yet try in
+    // the main macro directory(s)
+    // if file is found in more than one main directory
+    // we'll load all copies
+    if (!foundfile) {
+      text_tset::const_iterator dirhere = maindirs.begin();
+      text_tset::const_iterator dirend = maindirs.end();
+      while (dirhere != dirend) {
+	filename = filename_cat (*dirhere, *arrhere);
+	if (file_exists (filename)) {
+	  disp.loaddefaultmacros(filename);
+	  foundfile = true;
+	}
+	++dirhere;
+      }
+    }
+
+    // see if we found the file or not
+    if (!foundfile) {
+      logout << text_t2ascii 
+	     << "Error: the macro file \"" << *arrhere << "\" could not be found.\n";
+      if (configinfo.collection.empty()) {
+	text_t dirs;
+	joinchar (maindirs, ", ", dirs);
+	logout << text_t2ascii 
+	       << "It should be in either of the following directories ("
+	       << dirs << ").\n\n";
+
+      } else {
+	logout << text_t2ascii
+	       << "It should be in either " << colmacrodir << " or in " 
+	       << gsdlmacrodir << ".\n\n";
+      }
+      // don't crap out if a macro file is missing
+      //disp.setlogout (savedlogout);
+      //return false;
+    }
+    ++arrhere;
+  }
+
+  // success
+
+  // reset logout to what it was
+  disp.setlogout (savedlogout);
+  return true;
+}
+
+
+
+
+// Go through the list of macro files looking to see
+// if any exist in the collectoin specific area.  If they
+// do then read them in and add them to the set of existing
+// current macros
+
+void receptionist::read_collection_macrofiles (const text_t& collection, ostream &logout) 
+{
+  outconvertclass text_t2ascii;
+
+  // disp.unloadcollectionmacros();
+
+  // redirect the error output to logout
+  ostream *savedlogout = disp.setlogout (&logout);
+
+  text_t colmacrodir 
+    = filename_cat (configinfo.collecthome,collection, "macros");
+
+  if (directory_exists (colmacrodir)) {
+
+    text_tset::iterator arrhere = configinfo.macrofiles.begin();
+    text_tset::iterator arrend = configinfo.macrofiles.end();
+    text_t filename;
+    while (arrhere != arrend) {
+
+      filename = filename_cat (colmacrodir, *arrhere);
+      if (file_exists (filename)) {
+	disp.loadcollectionmacros(filename);
+      }
+      
+      ++arrhere;
+    }
+  }
+
+  // reset logout to what it was
+  disp.setlogout (savedlogout);
+}
+
+
+
+
+// check_mainargs will check all the main arguments. If a major
+// error is found it will return false and no cgi page should
+// be created using the arguments.
+
+bool receptionist::check_mainargs (cgiargsclass &args, ostream &logout) {
+   
+   if(configinfo.site_auth)
+      {
+	 args["uan"] = "1";
+	 args["ug"] = configinfo.site_group;
+      }
+   
+   
+   // if this receptionist is running in collection dependant mode
+   // then it should always set the collection argument to the
+   // collection
+   if (!configinfo.collection.empty()) args["c"] = configinfo.collection;
+   
+   // if current collection uses ccscols make sure
+   // "ccs" argument is set and make "cc" default to
+   // all collections in "ccs"
+   if (args["a"] != "config" && !args["c"].empty()) {
+      
+      text_t &arg_c = args["c"];
+      recptproto *collectproto = protocols.getrecptproto (arg_c, logout);
+      if (collectproto == NULL) {
+	 // oops, this collection isn't valid
+	 outconvertclass text_t2ascii;
+	 logout << text_t2ascii << "ERROR: Invalid collection: " << arg_c << "\n";
+	 // args["c"].clear();
+	 
+      } else {
+	 
+	 ColInfoResponse_t *cinfo = get_collectinfo_ptr (collectproto, arg_c, logout);
+	 
+	 if(cinfo->authenticate == "collection")
+	    {
+	       args["uan"] = "1";
+	       args["ug"] = cinfo->auth_group;
+	    }
+	 
+	 
+      if (cinfo != NULL) {
+	 if (!cinfo->ccsCols.empty()) {
+	    args["ccs"] = 1;
+	    if (args["cc"].empty()) {
+	       text_tarray::const_iterator col_here = cinfo->ccsCols.begin();
+	       text_tarray::const_iterator col_end = cinfo->ccsCols.end();
+	       bool first = true;
+	       while (col_here != col_end) {
+		  // make sure it's a valid collection
+		  if (protocols.getrecptproto (*col_here, logout) != NULL) {
+		     if (!first) args["cc"].push_back (',');
+		     args["cc"] += *col_here;
+		     first = false;
+		  }
+	      ++col_here;
+	    }
+	  }
+	}
+      } else {
+	logout << "ERROR (receptionist::check_mainargs): get_collectinfo_ptr returned NULL\n";
+      }
+    }
+  }
+
+  // argument "v" can only be 0 or 1. Use the default value
+  // if it is out of range
+  int arg_v = args.getintarg ("v");
+  if (arg_v != 0 && arg_v != 1) {
+    cgiarginfo *vinfo = argsinfo.getarginfo ("v");
+    if (vinfo != NULL) args["v"] = vinfo->argdefault;
+  }
+
+  // argument "f" can only be 0 or 1. Use the default value
+  // if it is out of range
+  int arg_f = args.getintarg ("f");
+  if (arg_f != 0 && arg_f != 1) {
+    cgiarginfo *finfo = argsinfo.getarginfo ("f");
+    if (finfo != NULL) args["f"] = finfo->argdefault;
+  }
+
+  return true;
+}
+
+// translate_OIDs translates the "d" and "cl" arguments to their correct values
+// if they use the tricky ".fc", ".lc" type syntax.
+void receptionist::translate_OIDs (cgiargsclass &args, recptproto *collectproto, 
+				   ostream &logout) {
+
+  FilterResponse_t response;
+  FilterRequest_t request;
+  comerror_t err;
+  text_t &arg_d = args["d"];
+  text_t &arg_cl = args["cl"];
+  text_t &collection = args["c"];
+  
+  // do a call to translate OIDs if required
+  request.filterName = "NullFilter";
+  request.filterResultOptions = FROID;
+  if (!arg_d.empty() && needs_translating (arg_d)) {
+    request.docSet.push_back (arg_d);
+    collectproto->filter (collection, request, response, err, logout);
+    arg_d = response.docInfo[0].OID;
+    request.clear();
+  }
+  // we'll also check here that the "cl" argument has a "classify" doctype 
+  // (in case ".fc" or ".lc" have screwed up)
+  if (needs_translating (arg_cl)) {
+    request.fields.insert ("doctype");
+    request.docSet.push_back (arg_cl);
+    request.filterResultOptions = FRmetadata;
+    collectproto->filter (collection, request, response, err, logout);
+    // set to original value (without .xx stuff) if doctype isn't "classify"
+    if (response.docInfo[0].metadata["doctype"].values[0] != "classify")
+      strip_suffix (arg_cl);
+    else
+      arg_cl = response.docInfo[0].OID;
+  }
+}
+
+// prepare_page sets up page parameters, sets display macros
+// and opens the page ready for output 
+void receptionist::prepare_page (action *a, cgiargsclass &args, 
+				 outconvertclass &outconvert, 
+				 ostream &logout) {
+  // set up page parameters
+  text_t pageparams;
+  bool first = true;
+
+  text_tmap::iterator params_here = configinfo.pageparams.begin();
+  text_tmap::iterator params_end = configinfo.pageparams.end();
+  while (params_here != params_end) {
+    // page params are those from main.cfg (eg pageparam v 0) plus
+    // two defaults set in recptconf.clear() (c="" and l=en)
+    // This used to check if the current value of the page param
+    // == the default value, then don't add in it the list
+    // but if l=en, and there is a macro with [l=en], then it doesn't
+    // find it.
+    // so now all page params will go into the list. I assume this will 
+    // mean more attempts to find each macro, but nothing worsee than 
+    // that.  --kjdon
+    //if (args[(*params_here).first] != (*params_here).second) {
+      if (first)
+	first = false;
+      else
+	pageparams += ",";
+
+      pageparams += (*params_here).first;
+      pageparams += "=";
+      pageparams += args[(*params_here).first];
+      // }
+    
+    ++params_here;
+  }
+  
+
+  // open the page
+  disp.openpage(pageparams, configinfo.macroprecedence);
+
+  disp.unloadcollectionmacros();
+
+  text_t collection = args["c"];
+  if (!collection.empty()) {
+    read_collection_macrofiles(collection,logout);
+  }
+
+  // define external macros for each action
+  actionptrmap::iterator actionhere = actions.begin ();
+  actionptrmap::iterator actionend = actions.end ();
+
+  while (actionhere != actionend) {
+    assert ((*actionhere).second.a != NULL);
+    if ((*actionhere).second.a != NULL) {
+      (*actionhere).second.a->define_external_macros (disp, args, &protocols, logout);
+    }
+    ++actionhere;
+  }
+
+
+  // define internal macros for the current action
+  a->define_internal_macros (disp, args, &protocols, logout);
+  
+  // define general macros. the defining of general macros is done here so that
+  // the last possible version of the cgi arguments are used
+  define_general_macros (args, outconvert, logout);
+}
+
+
+void receptionist::define_general_macros (cgiargsclass &args, outconvertclass &/*outconvert*/, 
+					  ostream &logout) {
+
+  text_t &collection = args["c"];
+
+  disp.setmacro ("gsdlhome", displayclass::defaultpackage, dm_safe(configinfo.gsdlhome));
+  disp.setmacro ("gwcgi", displayclass::defaultpackage, configinfo.gwcgi);
+  disp.setmacro ("httpweb", displayclass::defaultpackage, configinfo.httpweb);
+  disp.setmacro ("httpprefix", displayclass::defaultpackage, configinfo.httpprefix);
+
+  text_t compressedoptions = get_compressed_arg(args, logout);
+  disp.setmacro ("compressedoptions", displayclass::defaultpackage, dm_safe(compressedoptions));
+  // need a decoded version of compressedoptions for use within forms
+  // as browsers encode values from forms before sending to server
+  // (e.g. %25 becomes %2525)
+  decode_cgi_arg (compressedoptions); 
+  if (args["w"] == "utf-8") { // if the encoding was utf-8, then compressed options was utf-8, and we need unicode.
+    // if encoding wasn't utf-8, then compressed opotions may be screwed up, but seems to work for 8 bit encodings?
+    compressedoptions = to_uni(compressedoptions);
+  }
+  disp.setmacro ("decodedcompressedoptions", displayclass::defaultpackage, dm_safe(compressedoptions)); 
+
+#if defined (__WIN32__)
+  disp.setmacro ("win32", displayclass::defaultpackage, "1");
+#endif
+
+  // set _cgiargX_ macros for each cgi argument
+  cgiargsclass::const_iterator argshere = args.begin();
+  cgiargsclass::const_iterator argsend = args.end();
+  while (argshere != argsend) {
+    if (((*argshere).first == "q") ||
+	((*argshere).first == "qa") ||
+	((*argshere).first == "qtt") ||
+	((*argshere).first == "qty") ||
+	((*argshere).first == "qp") ||
+	((*argshere).first == "qpl") ||
+	((*argshere).first == "qr") ||
+	((*argshere).first == "q2"))
+      // need to escape special characters from query string
+      disp.setmacro ("cgiarg" + (*argshere).first, 
+		     displayclass::defaultpackage, html_safe((*argshere).second.value));
+    else if ((*argshere).first == "hp") {
+      disp.setmacro ("cgiarg" + (*argshere).first, displayclass::defaultpackage, (*argshere).second.value);
+    } else {
+      disp.setmacro ("cgiarg" + (*argshere).first, displayclass::defaultpackage, dm_safe((*argshere).second.value));
+    }
+    ++argshere;
+  }
+
+  // set collection specific macros
+  if (!collection.empty()) {
+    recptproto *collectproto = protocols.getrecptproto (collection, logout);
+    if (collectproto != NULL) {
+      FilterResponse_t response;
+      text_tset metadata;
+      get_info ("collection", collection, args["l"], metadata, false, 
+		collectproto, response, logout);
+      
+      if (!response.docInfo[0].metadata.empty()) {
+	MetadataInfo_tmap::const_iterator here = response.docInfo[0].metadata.begin();
+	MetadataInfo_tmap::const_iterator end = response.docInfo[0].metadata.end();
+	while (here != end) {
+	  if (((*here).first != "haschildren") && ((*here).first != "hasnext") &&
+	      ((*here).first != "hasprevious")) {
+	    // check for args in form name:lang
+	    text_t name = g_EmptyText;
+	    text_t lang = g_EmptyText;
+	    bool colonfound=false;
+	    text_t::const_iterator a = (*here).first.begin();
+	    text_t::const_iterator b = (*here).first.end();
+	    while (a !=b) {
+	      if (*a==':') {
+		colonfound=true;
+	      }
+	      else {
+		if (colonfound)
+		  lang.push_back(*a);
+		else name.push_back(*a);
+	      }
+	      ++a;
+	    }
+	    if (!lang.empty()) {
+	      if (args["l"]==lang) {
+		disp.setcollectionmacro(displayclass::defaultpackage, name, "", (*here).second.values[0]);
+	      }
+	    }
+	    else { // the default one
+	      disp.setcollectionmacro(displayclass::defaultpackage, (*here).first,  "", (*here).second.values[0]);
+	    }
+	  }
+	  ++here;
+	}
+      }
+
+      text_t iconcollection;
+      disp.expandstring (displayclass::defaultpackage, "_iconcollection_", iconcollection);
+      if (!iconcollection.empty())
+	{
+	  ColInfoResponse_t cinfo;
+	  comerror_t err;
+	  collectproto->get_collectinfo (collection, cinfo, err, logout);
+	  if (iconcollection[0]=='/' && !cinfo.httpdomain.empty())
+	    {
+	      // local but with full path
+	      iconcollection = "http://" + cinfo.httpdomain + iconcollection;
+	      disp.setmacro("iconcollection", displayclass::defaultpackage, iconcollection);
+	    }
+	}
+    }
+  }
+  
+  if (!collection.empty()) {
+    ColInfoResponse_t cinfo;
+    comerror_t err;
+    recptproto *collectproto = protocols.getrecptproto (collection, logout);
+    if (collectproto != NULL) {
+      collectproto->get_collectinfo (collection, cinfo, err, logout);
+
+
+      // This part of the code used to use "cinfo.httpprefix" regardless
+      // of the value it contained.  Since
+      // this can come back with an empty (in the case of gsdl_mod), the
+      // URL produced was invalid.
+      //
+      // Changed to test for empty first, and use configinfo.httpprefix as
+      // a "backup"
+      // 
+      // Point to consider: since configinfo.httpprefix has been offically 
+      // set as "httpprefix" in macros, it seems to make more sense to use
+      // always use that version and not the cinfo version at all.
+
+      text_t httpprefix 
+	= (!cinfo.httpprefix.empty()) ? cinfo.httpprefix : configinfo.httpprefix;
+    
+      text_t httpcollection;
+      if (!cinfo.httpdomain.empty()) httpcollection = "http://";
+      httpcollection += cinfo.httpdomain + httpprefix + "/collect/"
+	+ collection; 
+      disp.setmacro ("httpcollection", displayclass::defaultpackage,
+		     httpcollection); 
+      
+      // as of gsdl 2.53, collect.cfg can specify macros
+      if (cinfo.collection_macros.size() > 0) {
+	collectionmeta_map::const_iterator this_macro=cinfo.collection_macros.begin();
+	collectionmeta_map::const_iterator done_macro=cinfo.collection_macros.end();
+	while (this_macro != done_macro) {
+	  text_t package = "Global";
+	  text_t macroname = this_macro->first;
+	  // if this macro name is AAA:bbb then extract the package name
+	  text_t::const_iterator thischar, donechar;
+	  thischar = macroname.begin();
+	  donechar = macroname.end();
+	  while (thischar < donechar) {
+	    if (*thischar == ':') {
+	      package = substr(macroname.begin(),thischar);
+	      macroname = substr(thischar+1,donechar);
+	      break;
+	    }
+	    ++thischar;
+	  }
+
+	  text_tmap params_map = this_macro->second;
+	  text_tmap::const_iterator this_param = params_map.begin();
+	  text_tmap::const_iterator done_param = params_map.end();
+	  while (this_param != done_param) {
+	    disp.setcollectionmacro(package,
+				    macroname,
+				    this_param->first,
+				    this_param->second);
+	    ++this_param;
+	  }
+	  
+	  ++this_macro;
+	}
+      } // col macros
+    } // collectproto != NULL
+  }
+
+}
+
+// gets collection info from cache if found or 
+// calls collection server (and updates cache)
+// returns NULL if there's an error
+ColInfoResponse_t *receptionist::get_collectinfo_ptr (recptproto *collectproto, 
+						      const text_t &collection, 
+						      ostream &logout) {
+  
+  // check the cache
+  colinfo_tmap::iterator it = configinfo.collectinfo.find (collection);
+  if ((it != configinfo.collectinfo.end()) && ((*it).second.info_loaded)) {
+    // found it
+    return &((*it).second.info);
+  }
+
+  // not cached, get info from collection server
+  if (collectproto == NULL) {
+    logout << "ERROR: receptionist::get_collectinfo_ptr passed null collectproto\n";
+    return NULL;
+  }
+   
+  comerror_t err;
+  if (it == configinfo.collectinfo.end()) {
+    collectioninfo_t cinfo;
+    collectproto->get_collectinfo (collection, cinfo.info, err, logout);
+    if (err != noError) {
+      outconvertclass text_t2ascii;
+      logout << text_t2ascii << "ERROR (receptionist::getcollectinfo_ptr): \""
+	     << get_comerror_string (err) << "\"while getting collectinfo\n";
+      return NULL;
+    }
+    cinfo.info_loaded = true;
+    configinfo.collectinfo[collection] = cinfo;
+    return &(configinfo.collectinfo[collection].info);
+  } else {
+    collectproto->get_collectinfo (collection, (*it).second.info, err, logout);
+    if (err != noError) {
+      outconvertclass text_t2ascii;
+      logout << text_t2ascii << "ERROR (receptionist::getcollectinfo_ptr): \""
+	     << get_comerror_string (err) << "\"while getting collectinfo\n";
+      return NULL;
+    }
+    (*it).second.info_loaded = true;
+    return &((*it).second.info);
+  }
+}
+
+// removes a collection from the cache so that the next
+// call to get_collectinfo_ptr() for that collection will
+// retrieve the collection info from the collection server
+void receptionist::uncache_collection (const text_t &collection) {
+
+  colinfo_tmap::iterator it = configinfo.collectinfo.find (collection);
+  if ((it != configinfo.collectinfo.end()) && ((*it).second.info_loaded)) {
+
+    (*it).second.info_loaded = false;
+
+  }
+}
+
+// Handles an "Encoding" line from a configuration file - note that the
+// configinfo.encodings map is a bit of a hack (to be fixed when the
+// configuration files are tidied up).
+void receptionist::configure_encoding (const text_tarray &cfgline) {
+
+  text_t subkey, subvalue, shortname, longname, mapfile;
+  int multibyte = 0;
+  text_t::const_iterator cfglinesub_here;
+  text_tarray::const_iterator cfgline_here = cfgline.begin();
+  text_tarray::const_iterator cfgline_end = cfgline.end();
+  while (cfgline_here != cfgline_end) {
+    if (*cfgline_here == "multibyte") {
+      multibyte = 1;
+    } else {
+      cfglinesub_here = getdelimitstr((*cfgline_here).begin(),
+				      (*cfgline_here).end(), '=', subkey);
+      if (subkey == "shortname") {
+	shortname = substr (cfglinesub_here, (*cfgline_here).end());
+      } else if (subkey == "longname") {
+	longname = substr (cfglinesub_here, (*cfgline_here).end());
+      } else if (subkey == "map") {
+	mapfile = substr (cfglinesub_here, (*cfgline_here).end());
+      }
+    }
+    ++cfgline_here;
+  }
+  if (!shortname.empty()) {
+    if (longname.empty()) longname = shortname;
+
+    // add the converter
+    if (shortname == "utf-8") {
+      utf8inconvertclass *utf8inconvert = new utf8inconvertclass();
+      utf8outconvertclass *utf8outconvert = new utf8outconvertclass();
+      utf8outconvert->set_rzws(1);
+      add_converter (shortname, utf8inconvert, utf8outconvert);
+      configinfo.encodings[longname] = shortname;
+
+    } else if (shortname == "utf-16be") {
+      // we use the default input converter as this shouldn't ever be used
+      // for converting from unicode...
+      inconvertclass *inconverter = new inconvertclass();
+      utf16outconvertclass *outconverter = new utf16outconvertclass();
+      add_converter (shortname, inconverter, outconverter);
+      configinfo.encodings[longname] = shortname;
+	
+    } else if (!mapfile.empty()) {
+
+      if (mapfile == "8859_1.ump") {
+	// iso-8859-1 is a special case as it'll always be supported by the
+	// standard converter class and therefore doesn't need to use its
+	// mapping file
+	inconvertclass *inconvert = new inconvertclass();
+	rzwsoutconvertclass *outconvert = new rzwsoutconvertclass();
+	outconvert->set_rzws(1);
+	add_converter (shortname, inconvert, outconvert);  
+	configinfo.encodings[longname] = shortname;
+
+      } else {
+	text_t to_uc_map = filename_cat(configinfo.gsdlhome, "mappings", "to_uc", mapfile);
+	text_t from_uc_map = filename_cat(configinfo.gsdlhome, "mappings", "from_uc", mapfile);
+	if (file_exists(to_uc_map) && file_exists(from_uc_map)) {
+
+	  mapinconvertclass *mapinconvert = new mapinconvertclass();
+	  mapinconvert->setmapfile (to_uc_map, 0x003F);
+	  mapinconvert->set_multibyte (multibyte);
+	  mapoutconvertclass *mapoutconvert = new mapoutconvertclass();
+	  mapoutconvert->setmapfile (from_uc_map, 0x3F);
+	  mapoutconvert->set_multibyte (multibyte);
+	  mapoutconvert->set_rzws(1);
+	  add_converter (shortname, mapinconvert, mapoutconvert);
+	  configinfo.encodings[longname] = shortname;
+	}
+      }
+    }
+  }
+}
Index: /gsdl/stable/runtime-src/src/recpt/receptionist.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/receptionist.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/receptionist.h	(revision 20131)
@@ -0,0 +1,285 @@
+/**********************************************************************
+ *
+ * receptionist.h -- a web interface for the gsdl
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef RECEPTIONIST_H
+#define RECEPTIONIST_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "cgiargs.h"
+#include "display.h"
+#include "browserclass.h"
+#include "recptproto.h"
+#include "converter.h"
+#include "cfgread.h"
+#include "action.h"
+#include "cnfgable.h"
+
+// the MACROPRECEDENCE macro is used as a default. override
+// it using something like:
+//
+// macroprecedence c,l
+//
+// in your configuration file
+#ifndef MACROPRECEDENCE
+#define MACROPRECEDENCE "c,l"
+#endif
+
+
+struct collectioninfo_t {
+  void clear ();
+  collectioninfo_t () {clear();}
+
+  text_t gsdl_gsdlhome;
+  text_t gsdl_collecthome;
+  text_t gsdl_dbhome;
+
+  bool info_loaded;
+  ColInfoResponse_t info;
+};
+
+struct languageinfo_t {
+  void clear();
+  languageinfo_t () {clear();}
+
+  text_t longname;
+  text_t defaultencoding;
+};
+
+typedef map<text_t, collectioninfo_t, lttext_t> colinfo_tmap;
+typedef map<text_t, languageinfo_t, lttext_t> languageinfo_tmap;
+
+enum events_t {Disabled, CollectorEvents, AllEvents};
+enum ldformat_t {LocalTime, UTCTime, Absolute};
+
+struct recptconf {
+   text_t gsdlhome;
+   text_t collecthome;
+   text_t dbhome;   // will equal gsdlhome if not set
+   text_t collection; // will equal "" in 'general' mode
+   text_t collectdir; // will equal gsdlhome in 'general' mode
+   colinfo_tmap collectinfo;
+   text_t httpprefix;
+  text_t httpweb; // will be set to httpprefix/web if not set
+   text_t gwcgi;
+   text_tset macrofiles;
+   text_t saveconf;
+   bool usecookies;  // true if we want cookies set
+   bool logcgiargs;  // true if we want to log cgi arguments
+   
+   ldformat_t LogDateFormat;
+   
+   text_t maintainer; // email address of maintainer
+   text_t MailServer; // SMTP mail server to use when sending event messages by email
+                     // defaults to mail.maintainer-domain
+   events_t LogEvents;
+   events_t EmailEvents;
+   bool EmailUserEvents;
+
+   bool    site_auth;   // Complete site authentication, useful to lockout site for example.
+   text_t  site_group;  // Similar to the auth_groups functionality, infact exactly the same
+   
+   text_t HomePageType; 
+   int HomePageCols;
+   
+   text_tmap pageparams;
+   text_t macroprecedence;
+   
+   languageinfo_tmap languages;
+   
+   // encodings is just a simple mapping from encoding longnames to
+   // shortnames.  It's useful for now for creating the pulldown menu of
+   // encodings on the preferences page but isn't intended to be permanent.
+   text_tmap encodings;
+   
+   void clear ();
+   recptconf () {clear();}
+  
+};
+
+class receptionist : public configurable {
+protected:
+
+   recptconf configinfo;
+   
+   cgiargsinfoclass argsinfo;
+   actionmapclass actions;
+   browsermapclass browsers;
+   recptprotolistclass protocols;
+   displayclass disp;
+   convertinfoclass converters;
+   ColInfoResponse_t collectinfo;
+   
+   // prepare_page sets up page parameters, sets display macros
+   // and opens the page ready for output 
+   virtual void prepare_page (action *a, cgiargsclass &args, 
+			      outconvertclass &outconvert, 
+			     ostream &logout);
+   
+   virtual void translate_OIDs (cgiargsclass &args, recptproto *collectproto,
+				ostream &logout);
+   
+   bool get_cookie (text_t &cookie, text_tmap &fcgienv);
+   bool get_cookie (text_tmap &fcgienv);
+   
+   // get the default encoding for the given language - if it fails for any
+   // reason, return ""
+   text_t get_default_encoding (const text_t &language);
+   
+   virtual void define_general_macros (cgiargsclass &args, outconvertclass &outconvert, 
+				       ostream &logout);
+   
+   virtual bool append_logstr (const text_t &filename, const text_t &logstr,
+                               ostream &logout);
+
+   virtual void configure_encoding (const text_tarray &cfgline);
+   
+ public:
+   receptionist ();
+   virtual ~receptionist() {}
+
+#ifdef _APACHE_MOD
+   bool loaded;
+#endif   
+   // add_action makes another action available to the receptionist
+   // the action remains the property of the calling code and that
+   // code should destroy the action after the recptionist has been
+   // destroyed.
+   void add_action (action *theaction);
+   actionmapclass *get_actionmap_ptr () {return &actions;}
+   
+   // add_browser makes another browser available to the receptionist
+   // the browser remains the property of the calling code and that
+   // code should destroy it after the recptionist has been
+   // destroyed.
+   void add_browser (browserclass *thebrowser);
+   browsermapclass *get_browsermap_ptr () {return &browsers;}
+   void setdefaultbrowser (const text_t &browsername);
+   
+   // add_protocol makes another protocol available to the receptionist
+   // without any protocols, no collections will be available. The
+   // protocols remain the property of the calling code.
+   void add_protocol (recptproto *theprotocol) {protocols.addrecptproto(theprotocol);}
+   recptprotolistclass *get_recptprotolist_ptr () {return &protocols;}
+   
+   // add_converter makes another converter available to the receptionist.
+   // Converters are needed to display pages using different encodings.
+   // The converters remain the property of the calling code.
+   void add_converter (const text_t &name, inconvertclass *inconverter,
+		       rzwsoutconvertclass *outconverter) {
+      converters.add_converter(name, inconverter, outconverter);}
+   convertinfoclass *get_convertinfo_ptr () {return &converters;}
+   
+   
+   // configure should be called for each line in the
+  // configuration files to configure the receptionist and everything
+  // it contains. The configuration should take place after everything
+  // has been added but before the initialisation.
+  virtual void configure (const text_t &key, const text_tarray &cfgline);
+  virtual void configure (const text_t &key, const text_t &value);
+  const recptconf &get_configinfo () const {return configinfo;}
+  cgiargsinfoclass *get_cgiargsinfo_ptr () {return &argsinfo;}
+  
+
+  // init should be called after all the actions, protocols, and
+  // converters have been added to the receptionist and after everything
+  // has been configured but before any pages are created.
+  // It returns true on success and false on failure. If false is
+  // returned getpage should not be called (without producing
+  // meaningless output), instead an error page should be
+  // produced by the calling code.
+  virtual bool init (ostream &logout);
+  
+  // There are two ways to produce a page. You can either call parse_cgi_args,
+  // get_cgihead_info, and produce_content or you can just call parse_cgi_args and
+  // produce_cgi_page (which will be satisfactory in most cases). You might want to call
+  // parse_cgi_args, get_cgihead_info, and produce_content when you want to
+  // interface directly with a web server for which the standard header is inappropriate.
+
+  // parse_cgi_args parses cgi arguments into an argument class.
+  // This function should be called for each page request. It returns false
+  // if there was a major problem with the cgi arguments.
+  virtual bool parse_cgi_args (const text_t &argstr, 
+			       fileupload_tmap &fileuploads,
+			       cgiargsclass &args, 
+			       ostream &logout, text_tmap &fcgienv);
+
+  virtual bool log_cgi_args (cgiargsclass &args, ostream &logout, text_tmap &fcgienv);
+
+  text_t expandmacros (const text_t &astring, cgiargsclass &args, 
+		       ostream &logout);
+
+  // produce_cgi_page will call get_cgihead_info and 
+  // produce_content in the appropriate way to output a cgi header and
+  // the page content (if needed). If a page could not be created it
+  // will return false
+  virtual bool produce_cgi_page (cgiargsclass &args, ostream &contentout, 
+				 ostream &logout, text_tmap &fcgienv);
+  
+  // get_cgihead_info determines the cgi header information for
+  // a set of cgi arguments. If response contains location then
+  // response_data contains the redirect address. If reponse
+  // contains content then reponse_data contains the content-type.
+  // Note that images can now be produced by the receptionist.
+  virtual void get_cgihead_info (cgiargsclass &args, response_t &response,
+				 text_t &response_data, ostream &logout,
+				 text_tmap &fcgienv);
+  virtual void get_cgihead_info (cgiargsclass &args, text_tmap &headers,
+				 ostream &logout, text_tmap &fcgienv);
+
+  // produce the page content
+  virtual bool produce_content (cgiargsclass &args, ostream &contentout,
+				ostream &logout);
+  
+  // returns the compressed argument ("e") corresponding to the argument
+  // list. This can be used to save preferences between sessions.
+  virtual text_t get_compressed_arg (cgiargsclass &args, ostream &logout);
+
+  // gets collection info from cache if found or 
+  // calls collection server (and updates cache)
+  // returns NULL if there's an error
+  ColInfoResponse_t *get_collectinfo_ptr (recptproto *collectproto, 
+					  const text_t &collection, 
+					  ostream &logout);
+
+  void uncache_collection (const text_t &collection);
+  
+protected:
+  // will read in all the macro files. If one is not found an
+  // error message will be written to logout and the method will
+  // return false.
+  virtual bool read_macrofiles (ostream &logout);
+  
+  virtual void read_collection_macrofiles (const text_t& collection, ostream &logout);
+
+  // check_mainargs will check all the main arguments. If a major
+  // error is found it will return false and no cgi page should
+  // be created using the arguments.
+  virtual bool check_mainargs (cgiargsclass &args, ostream &logout);
+};
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/recptmain.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/recptmain.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/recptmain.cpp	(revision 20131)
@@ -0,0 +1,35 @@
+/**********************************************************************
+ *
+ * recptmain.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "receptionist.h"
+#include "cgiwrapper.h"
+#include <assert.h>
+
+int main () {
+  receptionist recpt;
+  cgiwrapper (recpt, g_EmptyText);
+  return 0;
+}
+
Index: /gsdl/stable/runtime-src/src/recpt/statusaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/statusaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/statusaction.cpp	(revision 20131)
@@ -0,0 +1,1153 @@
+/**********************************************************************
+ *
+ * statusaction.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_STATUS_ACTION
+
+// following line required to get fstream.filedesc() on darwin (Mac OS X)
+#define _STREAM_COMPAT  1
+
+#include "statusaction.h"
+#include "fileutil.h"
+#include "htmlutils.h"
+#include "gsdltools.h"
+#include <assert.h>
+#include <stdio.h>
+#include <fcntl.h> // for open() stuff
+
+void statusaction::output_frameset (cgiargsclass &/*args*/, displayclass &disp, 
+				    outconvertclass &outconvert, 
+				    ostream &textout, ostream &/*logout*/) {
+  textout << outconvert << disp << "_status:frameset_\n";
+}
+
+void statusaction::output_select (cgiargsclass &/*args*/, displayclass &disp, 
+				  outconvertclass &outconvert, 
+				  ostream &textout, ostream &/*logout*/) {
+  textout << outconvert << disp << "_status:header_(selector)\n"
+    "_status:select_\n"
+    "_status:footer_\n";
+}
+
+void statusaction::output_welcome (cgiargsclass &args, recptprotolistclass *protos, 
+				   displayclass &disp, outconvertclass &outconvert, 
+				   ostream &textout, ostream &logout) {
+
+  if (recpt == NULL) return;
+
+  textout << outconvert << disp 
+	  << "_status:infoheader_(_titlewelcome_)\n"
+	  << "_status:welcome_"
+	  << "<table>\n"
+	  << "<th align=left>abbrev.</th><th align=left>collection</th>"
+	  << "<th align=left>public?</th><th align=left>running?</th></tr>\n";
+
+  recptprotolistclass::iterator rprotolist_here = protos->begin();
+  recptprotolistclass::iterator rprotolist_end = protos->end();
+  while (rprotolist_here != rprotolist_end) {
+    if ((*rprotolist_here).p != NULL) {
+      comerror_t err;
+      text_t protoname = (*rprotolist_here).p->get_protocol_name(err);
+      text_tarray collist;
+      (*rprotolist_here).p->get_collection_list (collist, err, logout);
+      if (err == noError) {
+	text_tarray::iterator collist_here = collist.begin();
+	text_tarray::iterator collist_end = collist.end();
+
+	while (collist_here != collist_end) {
+
+	    textout << outconvert << disp
+		    << "<tr><td><a href=\"_gwcgi_?_optsite_e=_compressedoptions_&a=status&p=collectioninfo&pr="
+		    << protoname
+		    << "&c="
+		    << *collist_here
+		    << "\">"
+		    << *collist_here 
+		    << "</a></td>";
+
+	  ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
+	  if (cinfo != NULL) {
+	    text_t collname = cinfo->get_collectionmeta("collectionname", args["l"]);
+	    if (collname.empty()) {
+	      collname = *collist_here;
+	    }
+
+	    textout << "<td>";
+	    if (cinfo->buildDate > 0)
+	      textout << outconvert << disp 
+		      << "<a href=\"_httppagex_(about)&c=" << *collist_here
+		      << "\" target=\\_top>";
+
+	    textout << outconvert << disp << collname;
+
+	    if (cinfo->buildDate > 0) textout << "</a>";
+
+	    textout << "</td>";
+
+	    if (cinfo->isPublic) textout << "<td>yes</td>";
+	    else textout << "<td>no</td>";
+	    
+	    if (cinfo->buildDate > 0)
+	      textout << outconvert << "<td>yes</td>";
+	    else
+	      textout << "<td>no</td>";
+	    
+	  } else {
+	    textout << "<td></td><td></td><td></td>";
+	  }
+
+	  textout << "</tr>\n";
+	  ++collist_here;
+	}
+      }
+    }
+    ++rprotolist_here;
+  }
+
+  textout << "</table>\n";
+  textout << outconvert << disp << "_status:infofooter_\n";
+}
+
+void statusaction::output_generalinfo (cgiargsclass &/*args*/, displayclass &disp, 
+				       outconvertclass &outconvert, 
+				       ostream &textout, ostream &/*logout*/) {
+  if (recpt == NULL) return;
+  const recptconf &rcinfo = recpt->get_configinfo ();
+  
+  textout << outconvert << disp << "_status:infoheader_(General Information)\n";
+  textout << outconvert 
+	  << "<h2>General information</h2>\n"
+	  << "<table>\n"
+	  << "<tr valign=top><th>gsdlhome</th><td>\"" << rcinfo.gsdlhome
+	  << "\"</td></tr>\n"
+	  << "<tr valign=top><th>collection</th><td>\"" << rcinfo.collection
+	  << "\"</td></tr>\n"
+	  << "<tr valign=top><th>collectdir</th><td>\"" << rcinfo.collectdir
+	  << "\"</td></tr>\n"
+	  << "<tr valign=top><th>httpprefix</th><td>\"" << rcinfo.httpprefix
+	  << "\"</td></tr>\n"
+	  << "<tr valign=top><th>httpweb</th><td>\"" << rcinfo.httpweb
+	  << "\"</td></tr>\n"
+	  << "<tr valign=top><th>gwcgi</th><td>\"" << rcinfo.gwcgi
+	  << "\"</td></tr>\n";
+    
+  // macrofiles
+  textout << outconvert << "<tr valign=top><th>macrofiles</th><td>";
+  text_tset::const_iterator macrohere = rcinfo.macrofiles.begin ();
+  text_tset::const_iterator macroend = rcinfo.macrofiles.end ();
+  bool macrofirst = true;
+  while (macrohere != macroend) {
+    if (!macrofirst) textout << outconvert << ", ";
+    macrofirst = false;
+    textout << outconvert << "\"" << *macrohere << "\"";
+    ++macrohere;
+  }
+  textout << outconvert << "</td></tr>\n";
+  
+  // saveconf
+  textout << outconvert << "<tr valign=top><th>saveconf</th><td>\"" << rcinfo.saveconf
+	  << "\"</td></tr>\n";
+
+  // usecookies
+  textout << outconvert << "<tr valign=top><th>usecookies</th><td>\"";
+  if (rcinfo.usecookies) textout << outconvert << "true";
+  else textout << outconvert << "false";
+  textout << outconvert << "\"</td></tr>\n";
+  
+  // logcgiargs
+  textout << outconvert << "<tr valign=top><th>logcgiargs</th><td>\"";
+  if (rcinfo.logcgiargs) textout << outconvert << "true";
+  else textout << outconvert << "false";
+  textout << outconvert << "\"</td></tr>\n";
+
+  // pageparams
+  textout << outconvert << "<tr valign=top><th>pageparams</th><td>";
+  text_tmap::const_iterator params_here = rcinfo.pageparams.begin();
+  text_tmap::const_iterator params_end = rcinfo.pageparams.end();
+  bool params_first = true;
+  while (params_here != params_end) {
+    if (!params_first) textout << outconvert << ", ";
+    params_first = false;
+    textout << outconvert << "\"" << (*params_here).first << "\" != \""
+	    << (*params_here).second << "\"";
+    
+    ++params_here;
+  }
+  textout << outconvert << "</td></tr>\n";
+
+  // macroprecedence
+  textout << outconvert << "<tr valign=top><th>macroprecedence</th><td>\"" << rcinfo.macroprecedence
+	  << "\"</td></tr>\n";
+
+  // arguments
+  cgiargsinfoclass *rcargsinfo = recpt->get_cgiargsinfo_ptr ();
+  if (rcargsinfo != NULL) {
+    textout << outconvert << "<tr valign=top><th>arguments</th><td>";
+    
+    cgiargsinfoclass::const_iterator argsinfohere = rcargsinfo->begin ();
+    cgiargsinfoclass::const_iterator argsinfoend = rcargsinfo->end ();
+    bool argsinfofirst = true;
+    while (argsinfohere != argsinfoend) {
+      if (!argsinfofirst) textout << outconvert << ", ";
+      argsinfofirst = false;
+      textout << outconvert << "\"" << (*argsinfohere).second.shortname << "\"";
+      ++argsinfohere;
+    }
+    
+    textout << outconvert << "</td></tr>\n";
+  }      
+  
+  // actions
+  actionmapclass *actions = recpt->get_actionmap_ptr();
+  if (actions != NULL) {
+    textout << outconvert << "<tr valign=top><th>actions</th><td>";
+    
+    actionptrmap::iterator actionshere = actions->begin ();
+    actionptrmap::iterator actionsend = actions->end ();
+    bool actionsfirst = true;
+    while (actionshere != actionsend) {
+      if (!actionsfirst) textout << outconvert << ", ";
+      actionsfirst = false;
+      assert ((*actionshere).second.a != NULL);
+      if ((*actionshere).second.a != NULL) {
+	textout << outconvert << "\"" << (*actionshere).second.a->get_action_name() << "\"";
+      }
+      ++actionshere;
+    }
+    
+    textout << outconvert << "</td></tr>\n";
+  }
+  
+  // browsers
+  browsermapclass *browsers = recpt->get_browsermap_ptr();
+  if (browsers != NULL) {
+    textout << outconvert << "<tr valign=top><th>browsers</th><td>";
+    
+    browserptrmap::iterator browsershere = browsers->begin ();
+    browserptrmap::iterator browsersend = browsers->end ();
+    bool browsersfirst = true;
+    while (browsershere != browsersend) {
+      if (!browsersfirst) textout << outconvert << ", ";
+      browsersfirst = false;
+      assert ((*browsershere).second.b != NULL);
+      if ((*browsershere).second.b != NULL) {
+	textout << outconvert << "\"" << (*browsershere).second.b->get_browser_name() << "\"";
+      }
+      ++browsershere;
+    }
+    
+    textout << outconvert << "</td></tr>\n";
+  }
+
+  // protocols
+  recptprotolistclass *protocols = recpt->get_recptprotolist_ptr ();
+  if (protocols != NULL) {
+    textout << outconvert << "<tr valign=top><th>protocols</th><td>";
+    
+    recptprotolistclass::iterator protohere = protocols->begin ();
+    recptprotolistclass::iterator protoend = protocols->end ();
+    bool protofirst = true;
+    while (protohere != protoend) {
+      comerror_t err;
+      if (!protofirst) textout << outconvert << ", ";
+      protofirst = false;
+      if ((*protohere).p != NULL) {
+	textout << outconvert << "\"" << (*protohere).p->get_protocol_name(err) << "\"";
+      }
+      ++protohere;
+    }
+    
+    textout << outconvert << "</td></tr>\n";
+  }
+  
+  // converters
+  convertinfoclass *converters = recpt->get_convertinfo_ptr ();
+  if (converters != NULL) {
+    textout << outconvert << "<tr valign=top><th>converters</th><td>";
+    
+    convertinfoclass::iterator converthere = converters->begin ();
+    convertinfoclass::iterator convertend = converters->end ();
+    bool convertfirst = true;
+    while (converthere != convertend) {
+      if (!convertfirst) textout << outconvert << ", ";
+      convertfirst = false;
+      textout << outconvert << "\"" << (*converthere).second.name << "\"";
+      ++converthere;
+    }
+    
+    textout << outconvert << "</td></tr>\n";
+  }
+  
+  textout << outconvert << disp << "</table>\n_status:infofooter_\n";
+}
+
+void statusaction::output_argumentinfo (cgiargsclass &args, displayclass &disp, 
+					outconvertclass &outconvert, 
+					ostream &textout, ostream &/*logout*/) {
+  if (recpt == NULL) return;
+  cgiargsinfoclass *rcargsinfo = recpt->get_cgiargsinfo_ptr ();
+  if (rcargsinfo == NULL) return;
+
+  textout << outconvert << disp << "_status:infoheader_(Argument Information)\n";
+  textout << outconvert
+	  << "<h2>Argument information</h2>\n"
+	  << "<table>";
+
+  // argument information
+  textout << outconvert << "<tr valign=top><th>short name</th><th>long name</th>"
+	  << "<th>multiple char?</th>"
+	  << "<th>multiple value?</th>"
+	  << "<th>default</th><th>default status</th><th>saved args</th>"
+	  << "<th>current value</th></tr>\n";
+  
+
+  cgiargsinfoclass::const_iterator argsinfohere = rcargsinfo->begin();
+  cgiargsinfoclass::const_iterator argsinfoend = rcargsinfo->end();
+  text_t *arg_value;
+  while (argsinfohere != argsinfoend) {
+    const cgiarginfo &ainfo = (*argsinfohere).second;
+    textout << outconvert 
+	    << "<tr valign=top><td>" << ainfo.shortname << "</td>\n";
+    
+    textout << outconvert << "<td>" << ainfo.longname << "</td>\n";
+    if (ainfo.multiplechar) textout << outconvert << "<td>yes</td>\n";
+    else textout << outconvert << "<td>no</td>\n";
+    if (ainfo.multiplevalue) textout << outconvert << "<td>yes</td>\n";
+    else textout << outconvert << "<td>no</td>\n";
+    textout << outconvert << "<td>" << ainfo.argdefault << "</td>\n";
+    switch (ainfo.defaultstatus) {
+    case cgiarginfo::none: textout << outconvert << "<td>none</td>\n"; break;
+    case cgiarginfo::weak: textout << outconvert << "<td>weak</td>\n"; break;
+    case cgiarginfo::good: textout << outconvert << "<td>good</td>\n"; break;
+    case cgiarginfo::config: textout << outconvert << "<td>config</td>\n"; break;
+    case cgiarginfo::imperative: textout << outconvert << "<td>imperative</td>\n"; break;
+    }
+    switch (ainfo.savedarginfo) {
+    case cgiarginfo::mustnot: textout << outconvert << "<td>mustnot</td>\n"; break;
+    case cgiarginfo::can: textout << outconvert << "<td>can</td>\n"; break;
+    case cgiarginfo::must: textout << outconvert << "<td>must</td>\n"; break;
+    }
+    
+    arg_value = args.getarg (ainfo.shortname);
+    if (arg_value == NULL) textout << outconvert << "<td></td></tr>\n";
+    else textout << outconvert << "<td>\"" << *arg_value << "\"</td></tr>\n";
+    
+    ++argsinfohere;
+  }
+  
+  textout << outconvert << disp << "</table>\n_status:infofooter_\n";
+}
+
+void statusaction::output_actioninfo (cgiargsclass &/*args*/, displayclass &disp, 
+				      outconvertclass &outconvert, 
+				      ostream &textout, ostream &/*logout*/) {
+  if (recpt == NULL) return;
+  actionmapclass *actions = recpt->get_actionmap_ptr();
+
+  textout << outconvert << disp << "_status:infoheader_(Action Information)\n";
+  textout << outconvert
+	  << "<h2>Action information</h2>\n"
+	  << "<table>";
+
+  // action information
+  if (actions != NULL) {
+    textout << outconvert 
+	    << "<tr><th>action name</th><th>cgi arguments</th></tr>\n";
+	
+    actionptrmap::iterator actionshere = actions->begin ();
+    actionptrmap::iterator actionsend = actions->end ();
+    while (actionshere != actionsend) {
+      assert ((*actionshere).second.a != NULL);
+      if ((*actionshere).second.a != NULL) {
+	textout << outconvert 
+		<< "<tr><td>" << (*actionshere).second.a->get_action_name()
+		<< "</td><td>";
+	
+	cgiargsinfoclass *argsinfo = (*actionshere).second.a->getargsinfo();
+	cgiargsinfoclass::const_iterator argsinfohere = argsinfo->begin ();
+	cgiargsinfoclass::const_iterator argsinfoend = argsinfo->end ();
+	bool aifirst = true;
+	while (argsinfohere != argsinfoend) {
+	  if (!aifirst) textout << outconvert << ", ";
+	  aifirst = false;
+	  textout << outconvert << (*argsinfohere).second.shortname;
+	  ++argsinfohere;
+	}
+	
+	textout << outconvert << "</td></tr>\n";
+      }
+      ++actionshere;
+    }
+  }
+  
+  textout << outconvert << disp << "</table>\n_status:infofooter_\n";
+}
+
+void statusaction::output_browserinfo (cgiargsclass &/*args*/, displayclass &disp, 
+				       outconvertclass &outconvert, 
+				       ostream &textout, ostream &/*logout*/) {
+  if (recpt == NULL) return;
+  browsermapclass *browsers = recpt->get_browsermap_ptr();
+
+  textout << outconvert << disp << "_status:infoheader_(Browser Information)\n";
+  textout << outconvert
+	  << "<h2>Browser information</h2>\n"
+	  << "<table>";
+
+  // browser information
+  if (browsers != NULL) {
+    textout << outconvert 
+	    << "<tr><th>browser name</th><th>default formatstring</th></tr>\n";
+	
+    browserptrmap::iterator browsershere = browsers->begin ();
+    browserptrmap::iterator browsersend = browsers->end ();
+    while (browsershere != browsersend) {
+      assert ((*browsershere).second.b != NULL);
+      if ((*browsershere).second.b != NULL) {
+	textout << outconvert 
+		<< "<tr><td>" << (*browsershere).second.b->get_browser_name()
+		<< "</td><td>" << html_safe ((*browsershere).second.b->get_default_formatstring())
+		<< "</td></tr>\n";
+      }
+      ++browsershere;
+    }
+  }
+  
+  textout << outconvert << disp << "</table>\n_status:infofooter_\n";
+}
+
+void statusaction::output_protocolinfo (cgiargsclass &/*args*/, displayclass &disp, 
+					outconvertclass &outconvert, 
+					ostream &textout, ostream &logout) {
+  if (recpt == NULL) return;
+  const recptconf &rcinfo = recpt->get_configinfo ();
+  bool colspecific = !rcinfo.collection.empty();
+  bool unreachablecol = false;
+
+  recptprotolistclass *rprotolist = recpt->get_recptprotolist_ptr ();
+  if (rprotolist == NULL) return;
+
+  textout << outconvert << disp << "_status:infoheader_(Protocol Information)\n";
+  textout << outconvert
+	  << "<h2>Protocol information</h2>\n"
+	  << "<table>\n"
+	  << "<tr><th>protocol</th><th>collections</th></tr>\n";
+
+  text_t protoname;
+  recptprotolistclass::iterator rprotolist_here = rprotolist->begin();
+  recptprotolistclass::iterator rprotolist_end = rprotolist->end();
+  while (rprotolist_here != rprotolist_end) {
+    if ((*rprotolist_here).p != NULL) {
+      comerror_t err;
+      protoname = (*rprotolist_here).p->get_protocol_name(err);
+      textout << outconvert
+	      << "<tr><td>"
+	      << protoname
+	      << "</td><td>";
+
+      text_tarray collist;
+      (*rprotolist_here).p->get_collection_list (collist, err, logout);
+      if (err == noError) {
+	text_tarray::iterator collist_here = collist.begin();
+	text_tarray::iterator collist_end = collist.end();
+	bool first = true;
+	while (collist_here != collist_end) {
+	  if (!first) textout << outconvert << ", ";
+	  first = false;
+
+	  if (colspecific && *collist_here != rcinfo.collection) {
+	    unreachablecol = true;
+	    textout << outconvert << "\"" << *collist_here << "\"";
+	  } else {
+	    textout << outconvert << disp
+		    << "\"<a href=\"_gwcgi_?e=_compressedoptions_&a=status&p=collectioninfo&pr="
+		    << protoname
+		    << "&c="
+		    << *collist_here
+		    << "\">"
+		    << *collist_here 
+		    << "</a>\"";
+	  }
+
+	  ++collist_here;
+	}
+
+      } else {
+	textout << outconvert << "Error (" << get_comerror_string (err) 
+		<< ") while getting collect list\n";
+      }
+
+      textout << outconvert 
+	      << "</td></tr>\n";
+    }
+
+    ++rprotolist_here;
+  }
+
+  textout << outconvert << "</table>\n";
+  if (unreachablecol) {
+    textout << outconvert 
+	    << "<b>Warning:</b> the receptionist is running in collection specific\n"
+	    << "mode making some of the collections unreachable.\n";
+  }
+  textout << outconvert << disp << "_status:infofooter_\n";
+}
+
+void statusaction::output_collectioninfo (cgiargsclass &args, displayclass &disp, 
+					  outconvertclass &outconvert, 
+					  ostream &textout, ostream &logout) {
+  if (recpt == NULL) return;
+
+  textout << outconvert << disp << "_status:infoheader_(Collection info)\n";
+  textout << outconvert << "<h2>Collection info</h2>\n";
+
+  // get the list of protocols
+  recptprotolistclass *rprotolist = recpt->get_recptprotolist_ptr ();
+  if (rprotolist == NULL) return;
+
+  // look for the desired protocol
+  text_t &arg_pr = args["pr"];
+  text_t &arg_c = args["c"];
+  recptproto *rproto = NULL;
+  recptprotolistclass::iterator rprotolist_here = rprotolist->begin();
+  recptprotolistclass::iterator rprotolist_end = rprotolist->end();
+  while (rprotolist_here != rprotolist_end) {
+    rproto = (*rprotolist_here).p;
+    comerror_t err;
+    if (rproto != NULL && rproto->get_protocol_name(err) == arg_pr) {
+      // see if the protocol has the collection
+      bool hascollection;
+      rproto->has_collection (arg_c, hascollection, err, logout);
+      if (err == noError && hascollection) break;
+    }
+    ++rprotolist_here;
+  }
+  
+  if (rprotolist_here == rprotolist_end) {
+    textout << outconvert << "Protocol \"" << arg_pr << "\" with collection \""
+	    << arg_c << "\" was not found\n";
+
+  } else {
+    // rproto can't be NULL to get here
+    ColInfoResponse_t *collectinfo = recpt->get_collectinfo_ptr (rproto, arg_c, logout);
+    if (collectinfo != NULL) {
+      textout << outconvert << "<table>\n"
+	      << "<tr><th>collection name</th><td>\""
+	      << collectinfo->shortInfo.name
+	      << "\"</td></tr>\n"
+
+	      << "<tr><th>host</th><td>\""
+	      << collectinfo->shortInfo.host
+	      << "\"</td></tr>\n"
+
+	      << "<tr><th>port</th><td>\""
+	      << collectinfo->shortInfo.port
+	      << "\"</td></tr>\n"
+
+	      << "<tr><th>is public?</th><td>";
+      if (collectinfo->isPublic) textout << outconvert << "true";
+      else textout << outconvert << "false";
+      textout << outconvert 
+	      << "</td></tr>\n"
+
+	      << "<tr><th>is beta?</th><td>";
+      if (collectinfo->isBeta) textout << outconvert << "true";
+      else textout << outconvert << "false";
+      textout << outconvert 
+	      << "</td></tr>\n"
+
+	      << "<tr><th>use realistic book?</th><td>";
+      if (collectinfo->useBook) textout << outconvert << "true";
+      else textout << outconvert << "false";
+      textout << outconvert 
+	      << "</td></tr>\n"
+		  
+	      << "<tr><th>build date</th><td>\""
+	      << collectinfo->buildDate
+	      << "\"</td></tr>\n"
+
+	      << "<tr><th>interface languages</th><td>";
+      text_tarray::iterator languages_here = collectinfo->languages.begin();
+      text_tarray::iterator languages_end = collectinfo->languages.end();
+      bool languages_first = true;
+      while (languages_here != languages_end) {
+	if (!languages_first) textout << outconvert << ", ";
+	languages_first = false;
+	textout << outconvert << "\"" << *languages_here << "\"";
+	++languages_here;
+      }
+
+      textout << "<tr><th valign=top>collection metadata</th><td><table>\n";
+      collectionmeta_map::iterator meta_here = collectinfo->collectionmeta.begin();
+      collectionmeta_map::iterator meta_end = collectinfo->collectionmeta.end();
+      
+      while (meta_here != meta_end) {
+	textout << outconvert << "<tr><td valign=top>" << (*meta_here).first
+		<< "</td><td><table>" ;
+      	text_tmap lang_map = (*meta_here).second;
+	text_tmap::iterator lang_here = lang_map.begin();
+	text_tmap::iterator lang_end = lang_map.end();
+	while (lang_here != lang_end) {
+	  textout << outconvert << "<tr><td>" << (*lang_here).first
+		    << "</td><td>" << (*lang_here).second << "</td></tr>\n";
+	  
+	  ++lang_here;
+	}
+	textout << outconvert << "</table></td></tr>\n";
+	++meta_here;
+      }
+      textout << "</table></td></tr>\n";
+
+      textout << "<tr><th valign=top>format info</th><td><table>\n";
+      text_tmap::iterator format_here = collectinfo->format.begin();
+      text_tmap::iterator format_end = collectinfo->format.end();
+      while (format_here != format_end) {
+	textout << outconvert << "<tr><td valign=top>" << (*format_here).first
+		<< "</td><td>" << html_safe((*format_here).second) << "</td></tr>\n";
+	++format_here;
+      }
+      textout << "</table></td></tr>\n";
+
+      textout << "<tr><th valign=top>building info</th><td><table>\n";
+      text_tmap::iterator building_here = collectinfo->building.begin();
+      text_tmap::iterator building_end = collectinfo->building.end();
+      while (building_here != building_end) {
+	textout << outconvert << "<tr><td>" << (*building_here).first
+		<< "</td><td>" << (*building_here).second << "</td></tr>\n";
+	++building_here;
+      }
+      textout << "</table></td></tr>\n";
+
+      textout << outconvert 
+	      << "</td></tr>\n"
+
+	      << "<tr><th>number of documents</th><td>\""
+	      << collectinfo->numDocs
+	      << "\"</td></tr>\n"
+
+	      << "<tr><th>number of sections</th><td>\""
+	      << collectinfo->numSections
+	      << "\"</td></tr>\n"
+
+	      << "<tr><th>number of words</th><td>\""
+	      << collectinfo->numWords
+	      << "\"</td></tr>\n"
+
+	      << "<tr><th>number of bytes</th><td>\""
+	      << collectinfo->numBytes
+	      << "\"</td></tr>\n"
+
+	      << "<tr><th>preferred receptionist</th><td>\""
+	      << collectinfo->receptionist
+	      << "\"</td></tr>\n"
+
+	      << "</table>";
+      
+    } else {
+      textout << "ERROR (statusaction::output_collectioninfo): while getting collect information\n";
+    }
+
+
+    InfoFiltersResponse_t filterinfo;
+    InfoFilterOptionsRequest_t filteroptions_request;
+    InfoFilterOptionsResponse_t filteroptions;
+    comerror_t err;
+    rproto->get_filterinfo (arg_c, filterinfo, err, logout);
+    if (err == noError) {
+      text_tset::iterator filternames_here = filterinfo.filterNames.begin();
+      text_tset::iterator filternames_end = filterinfo.filterNames.end();
+      while (filternames_here != filternames_end) {
+	textout << outconvert 
+		<< "<hr>\n"
+		<< "<h3>Filter options for \"" << (*filternames_here) << "\"</h3>\n"
+		<< "<table>\n"
+		<< "<tr><th>option name</th><th>type</th><th>repeatable</th>"
+		<< "<th>default value</th><th>valid values</th></tr>\n";
+
+	filteroptions_request.clear();
+	filteroptions_request.filterName = *filternames_here;
+	rproto->get_filteroptions (arg_c, filteroptions_request,
+				   filteroptions, err, logout);
+	if (err == noError) {
+	  FilterOption_tmap::iterator filteropt_here = 
+	    filteroptions.filterOptions.begin();
+	  FilterOption_tmap::iterator filteropt_end = 
+	    filteroptions.filterOptions.end();
+	  while (filteropt_here != filteropt_end) {
+	    textout << outconvert
+		    << "<tr><td>\""
+		    << (*filteropt_here).second.name
+		    << "\"</td>\n"
+	      
+		    << "<td>";
+	    text_t type_string;
+	    switch ((*filteropt_here).second.type) {
+	    case FilterOption_t::booleant: type_string = "boolean"; break;
+	    case FilterOption_t::integert: type_string = "integer"; break;
+	    case FilterOption_t::enumeratedt: type_string = "enumerated"; break;
+	    case FilterOption_t::stringt: type_string = "string"; break;
+	    }
+	    textout << outconvert
+		    << type_string
+		    << "</td>\n"
+	      
+		    << "<td>";
+	    text_t repeat_string;
+	    switch ((*filteropt_here).second.repeatable) {
+	    case FilterOption_t::onePerQuery: repeat_string = "one per query"; break;
+	    case FilterOption_t::onePerTerm: repeat_string = "one per term"; break;
+	    case FilterOption_t::nPerTerm: repeat_string = "n per term"; break;
+	    }
+	    textout << outconvert
+		    << repeat_string
+		    << "</td>\n"
+	      
+		    << "<td>\""
+		    << (*filteropt_here).second.defaultValue
+		    << "\"</td>\n"
+	      
+		    << "<td>";
+	    
+	    text_tarray::iterator valid_here = 
+	      (*filteropt_here).second.validValues.begin();
+	    text_tarray::iterator valid_end = 
+	      (*filteropt_here).second.validValues.end();
+	    bool valid_first = true;
+	    while (valid_here != valid_end) {
+	      if (!valid_first) textout << outconvert << ", ";
+	      valid_first = false;
+	      textout << outconvert << "\"" << *valid_here << "\"";
+	      ++valid_here;
+	    }
+	    textout << outconvert
+		    << "</td></tr>\n";
+
+	    ++filteropt_here;
+	  }
+
+	  textout << outconvert
+		  << "</table>\n";
+
+	} else {
+	  textout << outconvert << "Error (" << get_comerror_string (err) 
+		  << ") while getting filter option information\n";
+	}
+
+	++filternames_here;
+      }
+
+    } else {
+      textout << outconvert << "Error (" << get_comerror_string (err) 
+	      << ") while getting filter information\n";
+    }
+  }
+  
+  textout << outconvert << disp << "_status:infofooter_\n";
+}
+
+void statusaction::output_usagelog (cgiargsclass &/*args*/, displayclass &disp,
+				    outconvertclass &outconvert, 
+				    ostream &textout, ostream &/*logout*/) {
+
+  // output last 100 lines of usage.txt
+
+  text_t logfilename = filename_cat (gsdlhome, "etc", "usage.txt");
+
+  textout << outconvert << disp << "_status:infoheader_(Usage log)\n";
+  textout << outconvert << "<h2>Usage log</h2>\n";
+
+  textout << outconvert << "<p>The usage log, "
+	  << logfilename << ", contains the\n"
+	  << "following information:\n"
+	  << "<p>(note that if this file is more than 100 lines long only the last 100 lines will\n"
+	  << "be displayed on this page)\n\n"
+	  << "<pre>\n";
+
+  // note that we're expecting lines to be no more than 1500 characters on
+  // average - should fix this file_tail() thing sometime
+  textout << outconvert << file_tail (logfilename, 100, 1500);
+
+  textout << outconvert << disp << "</pre>\n"
+	  << "_status:infofooter_\n";
+}
+
+void statusaction::output_errorlog (cgiargsclass &/*args*/, displayclass &disp, 
+				    outconvertclass &outconvert, 
+				    ostream &textout, ostream &logout) {
+
+  text_t errfilename = filename_cat (gsdlhome, "etc", "error.txt");
+  char *cerrfilename = errfilename.getcstr();
+  if (cerrfilename == NULL) return;
+
+  textout << outconvert << disp << "_status:infoheader_(Error log)\n";
+  textout << outconvert << "<h2>Error log</h2>\n";
+  logout << flush;
+
+#ifdef GSDL_USE_IOS_H
+  ifstream errin (cerrfilename, ios::in | ios::nocreate);
+#else
+  ifstream errin (cerrfilename, ios::in);
+#endif
+
+  delete []cerrfilename;
+  if (errin) {
+    textout << outconvert << "<p>The error log, "
+		<< errfilename << ", contains the\n";
+    textout << outconvert << "following information:\n\n";
+    text_t errorpage = "<p><pre>\n";
+
+    char c;
+    errin.get(c);
+    while (!errin.eof ()) {
+      errorpage.push_back(c);
+      errin.get(c);
+    }
+    
+    errorpage += "</pre>\n";
+    errin.close();
+    textout << outconvert << errorpage;
+
+  } else {
+    textout << outconvert << "Couldn't read error log, " 
+		<< errfilename << ".\n";
+  }
+
+  textout << outconvert << disp << "_status:infofooter_\n";
+}
+
+void statusaction::output_llssite (cgiargsclass &/*args*/, displayclass &disp, 
+				    outconvertclass &outconvert, 
+				    ostream &textout, ostream &logout) {
+
+  textout << outconvert << disp << "_status:infoheader_(llssite.cfg)\n";
+  textout << outconvert << "<h2>llssite.cfg</h2>\n";
+  logout << flush;
+
+#ifdef GSDL_LOCAL_LIBRARY
+  text_t llssite_cfg = filename_cat (gsdlhome, "llssite.cfg");
+#else
+  text_t llssite_cfg = "llssite.cfg";
+#endif
+
+  char *llssite_cfgc = llssite_cfg.getcstr();
+#ifdef GSDL_USE_IOS_H
+  ifstream llssitein (llssite_cfgc, ios::in | ios::nocreate);
+#else
+  ifstream llssitein (llssite_cfgc, ios::in);
+#endif
+
+  delete []llssite_cfgc;
+
+  if (llssitein) {
+    textout << "<p>The llssite.cfg configuration file contains the\n"
+	    << "following information:\n\n";
+    text_t llssite = "<p><pre>\n";
+
+    char c;
+    llssitein.get(c);
+    while (!llssitein.eof ()) {
+      llssite.push_back(c);
+      llssitein.get(c);
+    }
+    
+    llssite += "</pre>\n";
+    llssitein.close();
+    textout << outconvert << llssite;
+
+  } else {
+    textout << "Couldn't read llssite.cfg configuration file\n";
+  }
+
+  textout << outconvert << disp << "_status:infofooter_\n";
+}
+
+void statusaction::output_maincfg (cgiargsclass &/*args*/, displayclass &disp, 
+				   outconvertclass &outconvert, 
+				   ostream &textout, ostream &/*logout*/) {
+
+  text_t maincfgfile = filename_cat (dbhome, "etc", "main.cfg");
+
+  textout << outconvert << disp << "_status:infoheader_(main.cfg)\n"
+	  << "<h2>main.cfg</h2>\n"
+	  << "<p>The main configuration file, "
+	  << dm_safe(maincfgfile) << ", contains the following information:<br>\n\n"
+	  << "(Note that only users belonging to the \"administrator\" group "
+	  << "may edit this file)<br>\n"
+	  << "_status:maincfg_<br>\n"
+	  << "_status:infofooter_\n";
+}
+
+void statusaction::change_maincfg (cgiargsclass &args, displayclass &disp, 
+				   outconvertclass &outconvert, 
+				   ostream &textout, ostream &logout) {
+
+  // write out the contents of the cfgfile argument to main.cfg
+  text_t cfgfile = filename_cat(gsdlhome, "etc", "main.cfg");
+  char *cfgfilec = cfgfile.getcstr();
+
+  int fd=open(cfgfilec, O_WRONLY | O_CREAT | O_TRUNC
+#if defined(__WIN32__)
+	      | O_BINARY
+#endif
+	      , 432);
+
+  if (fd != -1) {
+
+    int lock_val = 1;
+    GSDL_LOCK_FILE (fd);
+    if (lock_val != 0) {
+      logout << "statusaction::change_maincfg: Error: Couldn't lock file " << cfgfilec << "\n";
+      textout << outconvert << disp << "_status:changemaincfgfail_";
+      close (fd);
+    } else {
+      outconvertclass text_t2ascii;
+      text_t2ascii.setinput(&args["cfgfile"]);
+      size_t buffersize=args["cfgfile"].size();
+      char *buffer=new char[buffersize];
+      size_t num_chars;
+      convertclass::status_t status;
+      text_t2ascii.convert(buffer, buffersize, num_chars, status);
+      // ignore status - assume it is "finished" as buffer is big enough
+      write(fd, buffer, num_chars);
+      GSDL_UNLOCK_FILE (fd);
+      delete []buffer;
+      close (fd);
+      textout << outconvert << disp << "_status:changemaincfgsuccess_";
+    }
+  } else {
+    logout << "statusaction::change_maincfg: Error: Couldn't open file " << cfgfilec << "for writing\n";
+    textout << outconvert << disp << "_status:changemaincfgfail_";
+  }
+  delete []cfgfilec;
+}
+
+void statusaction::output_errorpage (outconvertclass &outconvert, 
+				     ostream &textout, ostream &/*logout*/,
+				     text_t message) {
+  textout << outconvert 
+	  << "<html>\n"
+	  << "<head>\n"
+	  << "<title>Error</title>\n"
+	  << "</head>\n"
+	  << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
+	  << "alink=\"#cc9900\" vlink=\"#666633\">\n"
+	  << "<h2>Oops!</h2>\n" 
+	  << message
+	  << "\n</body>\n"
+	  << "</html>\n";
+  return;
+}
+
+
+
+statusaction::statusaction () {
+  disabled = true;
+  recpt = NULL;
+
+  // this action uses cgi variable "a"
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "a";
+  arg_ainfo.longname = "action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "status";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "p" -- status page
+  arg_ainfo.shortname = "p";
+  arg_ainfo.longname = "page";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "frameset";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "pr" -- protocol
+  arg_ainfo.shortname = "pr";
+  arg_ainfo.longname = "protocol";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::none;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::can;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "cfgfile";
+  arg_ainfo.longname = "configuration file contents";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+}
+
+statusaction::~statusaction () {
+}
+
+bool statusaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args, 
+				  recptprotolistclass * /*protos*/, ostream &/*logout*/) {
+
+  // only users belonging to the "administrator" group may edit 
+  // the main.cfg file
+  if (args["p"] == "maincfg" || args["p"] == "changemaincfg") {
+    args["uan"] = "1";
+    args["ug"] = "administrator";
+  }
+  return true;
+}
+
+void statusaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
+				     response_t &response, text_t &response_data, 
+				     ostream &/*logout*/) {
+  response = content;
+  response_data = "text/html";
+}
+
+
+void statusaction::define_internal_macros (displayclass &disp, cgiargsclass &args, 
+					   recptprotolistclass * /*protos*/, ostream &logout) {
+
+  // define_internal_macros sets the following macros:
+  // _maincfgfile_   the contents of the main.cfg configuration file
+
+  // _versionnnum_   greenstone version number (hard-coded)
+
+  disp.setmacro("versionnum", "status", GSDL_VERSION);
+
+  if (args["p"] == "maincfg") {
+
+    // read in main.cfg
+    text_t maincfg = filename_cat(gsdlhome, "etc", "main.cfg");  
+    char *maincfgc = maincfg.getcstr();
+    
+#ifdef GSDL_USE_IOS_H
+    ifstream cfg_ifs (maincfgc, ios::in | ios::nocreate);
+#else
+    ifstream cfg_ifs (maincfgc, ios::in);
+#endif
+    
+    if (cfg_ifs) {  
+      text_t cfgtext;
+      char c;
+      cfg_ifs.get(c);
+      while (!cfg_ifs.eof ()) {
+	cfgtext.push_back(c);
+	cfg_ifs.get(c);
+      }
+      cfg_ifs.close();
+      
+      // define it as a macro
+      disp.setmacro("maincfgfile", "status", dm_safe(cfgtext));
+      
+    } else {
+      logout << "statusaction::define_internal_macros: couldn't open configuration file (" 
+	     << maincfgc << ") for reading\n";
+      disp.setmacro("maincfgfile", "status", g_EmptyText);
+    }    
+    delete []maincfgc;
+  }
+}
+
+bool statusaction::do_action (cgiargsclass &args, recptprotolistclass *protos, 
+			      browsermapclass * /*browsers*/, displayclass &disp, 
+			      outconvertclass &outconvert, ostream &textout, 
+			      ostream &logout) {
+  // make sure the status function is enabled
+  if (disabled) {
+    textout << outconvert 
+	    << "<html>\n"
+	    << "<head>\n"
+	    << "<title>Status disabled</title>\n"
+	    << "</head>\n"
+	    << "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#006666\" "
+	    << "alink=\"#cc9900\" vlink=\"#666633\">\n"
+	    << "<h2>Facility disabled</h2>\n" 
+	    << "Sorry, the Maintenance and Administration facility is currently disabled\n"
+	    << "\n</body>\n"
+	    << "</html>\n";
+    return true;
+  }
+  
+  // make sure we know about a receptionist
+  if (recpt == NULL) {
+    output_errorpage (outconvert, textout, logout, 
+		      "The status action does not contain information\n"
+		      "about any receptionists. The method set_receptionist\n"
+		      "was probably not called from the module which instantiated\n"
+		      "this status action.\n");
+    return true;
+  }
+
+  // check to make sure status.dm was read in
+  const recptconf &rcinfo = recpt->get_configinfo ();
+  text_tset::const_iterator macrohere = rcinfo.macrofiles.begin ();
+  text_tset::const_iterator macroend = rcinfo.macrofiles.end ();
+  while (macrohere != macroend) {
+    if (*macrohere == "status.dm") break;
+    ++macrohere;
+  }
+  if (macrohere == macroend) {
+    output_errorpage (outconvert, textout, logout, 
+		      "The status.dm file was not read in. This macro file is\n" 
+		      "needed to display configuration and status information.\n");
+    return true;
+  }
+
+  // output the required status page
+  text_t &arg_p = args["p"];
+  if (arg_p == "frameset") output_frameset (args, disp, outconvert, textout, logout);
+  else if (arg_p == "select") output_select (args, disp, outconvert, textout, logout);
+  else if (arg_p == "welcome") output_welcome (args, protos, disp, outconvert, textout, logout);
+  else if (arg_p == "generalinfo") output_generalinfo (args, disp, outconvert, textout, logout);
+  else if (arg_p == "argumentinfo") output_argumentinfo (args, disp, outconvert, textout, logout);
+  else if (arg_p == "actioninfo") output_actioninfo (args, disp, outconvert, textout, logout);
+  else if (arg_p == "browserinfo") output_browserinfo (args, disp, outconvert, textout, logout);
+  else if (arg_p == "protocolinfo") output_protocolinfo (args, disp, outconvert, textout, logout);
+  else if (arg_p == "collectioninfo") output_collectioninfo (args, disp, outconvert, textout, logout);
+  else if (arg_p == "usagelog") output_usagelog (args, disp, outconvert, textout, logout);
+  else if (arg_p == "errorlog") output_errorlog (args, disp, outconvert, textout, logout);
+  else if (arg_p == "llssite") output_llssite (args, disp, outconvert, textout, logout);
+  else if (arg_p == "maincfg") output_maincfg (args, disp, outconvert, textout, logout);
+  else if (arg_p == "changemaincfg") change_maincfg (args, disp, outconvert, textout, logout);
+  else {
+    output_errorpage (outconvert, textout, logout, 
+		      "Unknown page \"" + arg_p + "\".\n");
+  }
+
+  return true;
+}
+
+void statusaction::configure (const text_t &key, const text_tarray &cfgline) {
+  if ((key == "status") && (cfgline.size() == 1) && 
+      (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
+    disabled = false;
+  } else {
+    // call the parent class to deal with the things which
+    // are not dealt with here
+    action::configure (key, cfgline);
+  }
+}
+
+#endif //GSDL_USE_STATUS_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/statusaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/statusaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/statusaction.h	(revision 20131)
@@ -0,0 +1,132 @@
+/**********************************************************************
+ *
+ * statusaction.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_STATUS_ACTION
+
+#ifndef STATUSACTION_H
+#define STATUSACTION_H
+
+
+#include "gsdlconf.h"
+#include "action.h"
+#include "receptionist.h"
+
+
+class statusaction : public action {
+protected:
+  bool disabled;
+  receptionist *recpt;
+
+  void output_frameset (cgiargsclass &args, displayclass &disp, 
+			outconvertclass &outconvert, 
+			ostream &textout, ostream &logout);
+
+  void output_select (cgiargsclass &args, displayclass &disp, 
+		      outconvertclass &outconvert, 
+		      ostream &textout, ostream &logout);
+
+  void output_welcome (cgiargsclass &args, recptprotolistclass *protos,
+		       displayclass &disp, outconvertclass &outconvert, 
+		       ostream &textout, ostream &logout);
+
+  void output_generalinfo (cgiargsclass &args, displayclass &disp, 
+			   outconvertclass &outconvert, 
+			   ostream &textout, ostream &logout);
+
+  void output_argumentinfo (cgiargsclass &args, displayclass &disp, 
+			    outconvertclass &outconvert, 
+			    ostream &textout, ostream &logout);
+
+  void output_actioninfo (cgiargsclass &args, displayclass &disp, 
+			  outconvertclass &outconvert, 
+			  ostream &textout, ostream &logout);
+
+  void output_browserinfo (cgiargsclass &args, displayclass &disp, 
+			   outconvertclass &outconvert, 
+			   ostream &textout, ostream &logout);
+
+  void output_protocolinfo (cgiargsclass &args, displayclass &disp, 
+			    outconvertclass &outconvert, 
+			    ostream &textout, ostream &logout);
+
+  void output_collectioninfo (cgiargsclass &args, displayclass &disp, 
+			      outconvertclass &outconvert, 
+			      ostream &textout, ostream &logout);
+
+  void output_usagelog (cgiargsclass &args, displayclass &disp,
+			outconvertclass &outconvert, 
+			ostream &textout, ostream &logout);
+
+  void output_errorlog (cgiargsclass &args, displayclass &disp, 
+			outconvertclass &outconvert, 
+			ostream &textout, ostream &logout);
+
+  void output_llssite (cgiargsclass &args, displayclass &disp, 
+			outconvertclass &outconvert, 
+			ostream &textout, ostream &logout);
+
+  void output_maincfg (cgiargsclass &args, displayclass &disp, 
+		       outconvertclass &outconvert, 
+		       ostream &textout, ostream &logout);
+
+  void change_maincfg (cgiargsclass &args, displayclass &disp, 
+		       outconvertclass &outconvert, 
+		       ostream &textout, ostream &logout);
+
+  void output_errorpage (outconvertclass &outconvert, 
+			 ostream &textout, ostream &logout,
+			 text_t message);
+
+public:
+  statusaction ();
+  virtual ~statusaction ();
+
+  text_t get_action_name () {return "status";}
+
+  void set_receptionist (receptionist *therecpt) {recpt=therecpt;}
+
+  bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+		      recptprotolistclass *protos, ostream &logout);
+
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response, text_t &response_data, 
+			 ostream &logout);
+
+
+  void define_internal_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+
+  void configure (const text_t &key, const text_tarray &cfgline);
+};
+
+
+#endif //!STATUSACTION_H
+#endif //GSDL_USE_STATUS_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/string_pool.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/string_pool.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/string_pool.cpp	(revision 20131)
@@ -0,0 +1,44 @@
+/**********************************************************************
+ *
+ * string_pool.cpp -- 
+ * Copyright (C) 2003 DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "string_pool.h"
+
+string_pool::string_pool () {
+}
+
+string_pool::~string_pool () {
+  vector<char *>::const_iterator here = pool.begin();
+  vector<char *>::const_iterator end = pool.end();
+  while (here != end) {
+    delete(*here);
+    ++here;
+  }
+}
+
+char *string_pool::get_cstr_from_pool(const text_t &str) {
+  char *cstr = str.getcstr();
+  pool.push_back(cstr);
+  return cstr;
+}
Index: /gsdl/stable/runtime-src/src/recpt/string_pool.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/string_pool.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/string_pool.h	(revision 20131)
@@ -0,0 +1,45 @@
+/**********************************************************************
+ *
+ * string_pool.h -- 
+ * Copyright (C) 2003 DL Consulting Ltd
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef STRING_POOL_H
+#define STRING_POOL_H
+
+#include "text_t.h"
+
+class string_pool {
+protected:
+  
+  vector<char *> pool;
+
+public:
+  string_pool();
+  virtual ~string_pool();
+
+  char* get_cstr_from_pool (const text_t &str);
+
+};
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/summarise.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/summarise.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/summarise.cpp	(revision 20131)
@@ -0,0 +1,270 @@
+/**********************************************************************
+ *
+ * summarise.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/* The function 'summarise' produces, given a document text and a query,
+ * a (query-biased) summary. In the future, several types of summaries will
+ * be supported.
+ */
+
+#include "summarise.h"
+#include "unitool.h"
+#include <string.h>
+
+
+/* **************** LOCAL PROTOTYPES **************** */
+
+text_t summarise_startend(text_t &htmlstr, int summaryLength);
+text_t summarise_keywords(text_t &htmlstr, text_t &query, int summaryLength);
+
+text_t next_sentence(text_t::iterator& start, text_t::iterator& end);
+text_t previous_sentence(text_t::iterator& start, text_t::iterator& end);
+bool paragraph_tag(text_t::iterator start);
+
+
+/****************************************************
+ NAME: summarise
+ DESC: produce a summary for a document
+*****************************************************/
+
+text_t summarise(text_t &htmlstr, text_t &query, int summaryLength) {
+  //  return summarise_startend(htmlstr,summaryLength);
+  return summarise_keywords(htmlstr,query,summaryLength);
+}
+
+
+/****************************************************
+ NAME: summarise_startend
+ DESC: return first and last sentences of a document
+*****************************************************/
+
+text_t summarise_startend(text_t &htmlstr, int summaryLength) {
+  text_t::iterator str_start = htmlstr.begin(), str_end = htmlstr.end();
+  text_t answer;
+
+  // add first sentences up to half the summary length
+
+  text_t::iterator str_current = str_start;
+  while(str_current<str_end && answer.size()<(summaryLength/2)) {
+    text_t sentence = next_sentence(str_current,str_end);
+    answer.append(sentence);
+  }
+
+  summaryLength -= answer.size(); // summary length left for last sentences
+  if(summaryLength<0)
+    summaryLength = 0;
+
+  str_end = str_current;
+  str_current = htmlstr.end()-1;
+  text_t lastSentence;
+  while(str_current>str_end && 
+        lastSentence.size()<summaryLength) {
+    text_t sentence = previous_sentence(str_current,str_end);
+    lastSentence = sentence + lastSentence;
+  }
+
+  answer += " ... ";
+  answer += lastSentence;
+
+  return answer;
+}
+
+
+/****************************************************
+ NAME: summarise_keywords
+ DESC: build a summary with sentences containing keyword(s).
+       the sentences with most matching keywords are returned 
+       first.
+*****************************************************/
+
+text_t summarise_keywords(text_t &htmlstr, text_t &query, int summaryLength) {
+
+  text_tarray allterms, terms;
+  splitchar(query.begin(),query.end(),' ',allterms);
+
+  // consider only non-empty terms
+  for(text_tarray::iterator term = allterms.begin();
+      term < allterms.end(); ++term) {
+    if(!(*term).empty())
+      terms.push_back(*term);
+  }
+
+  text_tarray::iterator terms_start = terms.begin(), terms_end = terms.end();
+
+  //text_tarray::iterator terms_current = terms_start;
+  //strstr("merde",*terms_current);
+
+  text_t::iterator str_start = htmlstr.begin(), str_end = htmlstr.end();
+
+  vector<text_tarray> answers(terms.size()); 
+    // an array of array of sentences for the summary:
+    //   answers[0] contains sentences with 1 keyword
+    //   answers[1] contains sentences with 2 keywords, etc.
+  vector<int> answersSize(terms.size());
+    // answersSize[0] is the combined size of sentences with 1 keyword, etc.
+  for(vector<int>::iterator size = answersSize.begin();
+      size<answersSize.end(); ++size)
+    *size = 0; // initialise sentence size
+
+  int totfound  = 0;
+  text_t::iterator str_current = str_start;
+  while(str_current<str_end && answersSize[terms.size()-1]<summaryLength) {
+    // if the size of best sentences is greater than summary, that's enough!
+    text_t sentence = next_sentence(str_current,str_end);
+
+    text_tarray::iterator terms_current = terms_start;
+    int nFound = 0;
+    while(terms_current!=terms_end) {
+      text_t::iterator word = findword(sentence.begin(),sentence.end(),
+				       *terms_current);
+      if(word!=sentence.end())
+	{        ++nFound; ++totfound; }
+      ++terms_current;
+    }
+
+    if(nFound>0 && answersSize[nFound-1]<summaryLength) {
+      answers[nFound-1].push_back(sentence);
+      answersSize[nFound-1] += sentence.size();
+    }
+  }
+
+  text_t answer;
+  for(vector<text_tarray>::iterator sentarray = answers.end()-1;
+      sentarray>=answers.begin(); --sentarray)
+    for(text_tarray::iterator sentence = (*sentarray).begin(); 
+        sentence < (*sentarray).end(); ++sentence) {
+      answer.append(*sentence);
+      if(answer.size()>=summaryLength)
+        return answer;
+    }
+
+  if(!answer.empty())
+    return answer;
+
+  return summarise_startend(htmlstr,summaryLength);
+}
+
+
+/* *********************** LOCAL FUNCTIONS ******************* */
+
+/* NAME: next_sentence
+   DESC: returns next sentence, text-only (ie. HTML markup is removed)
+ */
+
+text_t next_sentence(text_t::iterator& start, text_t::iterator& end) {
+  text_t sentence;                 // the sentence to be returned
+  bool   foundPunctuation = false; // set to true by '.', '!' or '?'
+  while(start<end && !foundPunctuation) {
+    switch (*start) {
+    case '<': // skip over rest of html tag
+      if(paragraph_tag(start) && has_unicode_letdig(sentence))
+        foundPunctuation = true;
+      while ((start<end) && (*start!='>'))
+	++start;
+      if(start<end) ++start;
+      break;
+    case '.':
+    case '!':
+    case '?':
+      sentence.push_back(*start);
+      ++start;
+      if(start>=end || 
+         (is_unicode_space(*start) && (*(start-2)<'A' || *(start-2)>'Z'))) {
+        foundPunctuation = true;
+      }
+      break;
+    default:
+      sentence.push_back(*start);
+      ++start;
+      break;
+    }
+  }
+  return sentence;
+}
+
+
+/* NAME: previous_sentence
+   DESC: returns previous sentence, text-only (ie. HTML markup is removed)
+ */
+
+text_t previous_sentence(text_t::iterator& start, text_t::iterator& end) {
+  text_t sentence;                    // the sentence to be returned
+  bool   found1stPunctuation = false, // set to true by '.', '!' or '?'
+                                      // first punct. is included in results
+         found2ndPunctuation = false; // second punct. is stop condition,
+                                      // and is not included in results
+  while(start>end && !found2ndPunctuation) {
+    switch (*start) {
+    case '>': // skip over rest of html tag
+      while ((start>end) && (*start!='<')) // backtrack to beginning of tag
+	--start;
+      if(start>end) {
+        if(paragraph_tag(start) && has_unicode_letdig(sentence))
+          found2ndPunctuation = true;
+        --start;
+      }
+      break;
+    case '.':
+    case '!':
+    case '?':
+      if(!is_unicode_space(*(start+1)) ||
+         (start-1>end && *(start-1)>='A' && *(start-1)<='Z')) {
+        // if next character is not a blank, or preceding character is
+	// a capital letter, we guess it's an acronym (e.g. "U.S.A.")
+        sentence.text_as_usvector().insert(sentence.text_as_usvector().begin(),
+          start,start+1);
+        --start;
+      } else
+        if(has_unicode_letdig(sentence) || found1stPunctuation)
+          found2ndPunctuation = true;
+        else {
+          sentence.text_as_usvector().insert(
+              sentence.text_as_usvector().begin(),start,start+1);
+          --start;
+          found1stPunctuation = true;
+        }
+      break;
+    default:
+      sentence.text_as_usvector().insert(
+        sentence.text_as_usvector().begin(),start,start+1);
+      --start;
+      break;
+    }
+  }
+  return sentence;
+}
+
+
+// start is positioned on the '<'
+bool paragraph_tag(text_t::iterator start) {
+  if(*start=='<') {
+    ++start;
+    if(*start=='p' || *start=='P') {
+      ++start;
+      if(is_unicode_space(*start) || *start=='>')
+        return true;
+    }
+  }
+  return false;
+}
Index: /gsdl/stable/runtime-src/src/recpt/summarise.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/summarise.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/summarise.h	(revision 20131)
@@ -0,0 +1,34 @@
+/**********************************************************************
+ *
+ * summarise.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef SUMMARISE_H
+#define SUMMARISE_H
+
+#include "text_t.h"
+
+text_t summarise(text_t &htmlstr, text_t &query, int summaryLength);
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/tipaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/tipaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/tipaction.cpp	(revision 20131)
@@ -0,0 +1,73 @@
+/**********************************************************************
+ *
+ * tipaction.cpp -- define random tip macros
+ * Copyright (C) 1999  DigiLib Systems Limited, New Zealand
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_TIP_ACTION
+
+#include "tipaction.h"
+#include <stdlib.h>
+
+
+tipaction::tipaction () {
+  // "st" show tips - "0"=no, "1"=yes
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "st";
+  arg_ainfo.longname = "show tips";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "1";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+}
+
+void tipaction::define_external_macros (displayclass &disp, cgiargsclass &args, 
+					recptprotolistclass * /*protos*/, ostream &logout) {
+
+  // define_external_macros sets the following macros:
+
+  // _tip:thistip_  - a random tip (defined if st == "1")
+
+  if (args["st"].getint()) {
+    // get the maximum tip number (_tip:tipmax_)
+    text_t tipmax_str;
+    disp.expandstring ("tip", "_tipmax_", tipmax_str);
+    if (tipmax_str.empty()) {
+      // don't bother filling up the logs if tip.dm isn't loaded!
+      // logout << "Warning: _tip:tipmax_ not set. This macro is needed for displaying tips.\n";
+      return;
+    }
+    
+    int tipmax = tipmax_str.getint();
+    if (tipmax < 1) {
+      // don't bother filling up the logs if tip.dm isn't loaded!
+      // logout << "Warning: _tip:tipmax_ was less than 1. No tips were set.\n";
+      return;
+    }
+    
+    disp.setmacro("thistip", "tip", "_tip" + text_t((rand()%tipmax) + 1) + "_");
+  }
+}
+
+#endif //GSDL_USE_TIP_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/tipaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/tipaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/tipaction.h	(revision 20131)
@@ -0,0 +1,49 @@
+/**********************************************************************
+ *
+ * tipaction.h -- define tip macros
+ * Copyright (C) 1999  DigiLib Systems Limited, New Zealand
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_TIP_ACTION
+
+#ifndef TIPACTION_H
+#define TIPACTION_H
+
+#include "gsdlconf.h"
+#include "action.h"
+
+
+// tipaction exists just for the benefit of defining external macros
+class tipaction : public action {
+public:
+  tipaction ();
+  virtual ~tipaction () {}
+  text_t get_action_name () {return "tip";}
+  
+  void define_external_macros (displayclass &disp, cgiargsclass &args, 
+			       recptprotolistclass *protos, ostream &logout);
+};
+
+
+#endif //!TIPACTION_H
+#endif //GSDL_USE_TIP_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/userdb.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/userdb.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/userdb.cpp	(revision 20131)
@@ -0,0 +1,525 @@
+/**********************************************************************
+ *
+ * userdb.cpp -- functions to handle a user database
+ * Copyright (C) 1999  DigiLib Systems Limited, New Zealand
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdlconf.h"
+#include "userdb.h"
+#include "gdbmclass.h"
+#include "gsdltimes.h"
+#include "fileutil.h"
+#include <stdlib.h>
+
+// include crypt
+#if defined(__WIN32__)
+#include "crypt.h"
+#else
+#if defined(HAVE_CRYPT_H)
+#include <crypt.h>
+#else 
+#include <unistd.h>
+#endif
+#endif
+
+//==========================================//
+//      userinfo_t functions (Start)        //
+//==========================================//
+userinfo_t::userinfo_t()
+{
+  clear();
+}
+
+userinfo_t::~userinfo_t(){};
+
+void userinfo_t::clear () {
+  username.clear();
+  password.clear();
+  enabled = false;
+  groups.clear();
+  comment.clear();
+}
+
+userinfo_t &userinfo_t::operator=(const userinfo_t &x) {
+  username = x.username;
+  password = x.password;
+  enabled = x.enabled;
+  groups = x.groups;
+  comment = x.comment;
+  
+  return *this;
+}
+//==========================================//
+//       userinfo_t functions (END)         //
+//==========================================//
+
+//==========================================//
+//      userdbclass functions (Start)       //
+//==========================================//
+userdbclass::userdbclass(const text_t &userdbfilename)
+{
+  storeduserdbfilename = userdbfilename;
+  userdb = new gdbmclass();
+  activated = (!userdb->opendatabase(storeduserdbfilename, DB_READER, 1000, true)) ? false : true;
+  if (activated == false) 
+    {
+      activated = (!userdb->opendatabase(storeduserdbfilename, DB_WRITER_CREATE, 1000, true)) ? false : true;
+      if (activated == true)
+        {
+          userdb->closedatabase();
+          activated = (!userdb->opendatabase(storeduserdbfilename, DB_READER, 1000, true)) ? false : true;
+        }
+    }
+    
+  external_db = false;
+}
+
+userdbclass::~userdbclass()
+{
+  if (external_db == false)
+  {
+    userdb->closedatabase();
+    delete userdb;
+  }
+}
+
+// few useful functions
+text_t userdbclass::crypt_text (const text_t &text) 
+{
+  static const char *salt = "Tp";
+  text_t crypt_password;
+  
+  if (text.empty()) return g_EmptyText;
+  
+  // encrypt the password
+  char *text_cstr = text.getcstr();
+  if (text_cstr == NULL) return g_EmptyText;
+  crypt_password = crypt(text_cstr, salt);
+  delete []text_cstr;
+
+  return crypt_password;
+}
+
+// username_ok tests to make sure a username is ok. a username
+// must be at least 2 characters long, but no longer than 30
+// characters long. it can contain the characters a-z A-Z 0-9
+// . and _
+bool userdbclass::username_ok (const text_t &username) 
+{
+  if (username.size() < 2 || username.size() > 30) return false;
+
+  text_t::const_iterator here = username.begin();
+  text_t::const_iterator end = username.end();
+  while (here != end) 
+    {
+      if ((*here >= 'a' && *here <= 'z') ||
+          (*here >= 'A' && *here <= 'Z') ||
+          (*here >= '0' && *here <= '9') ||
+          *here == '.' ||
+          *here == '_') 
+        {
+          // ok
+        } else return false;
+      ++here;
+    }
+  
+  return true;
+}
+
+// password_ok tests to make sure a password is ok. a password
+// must be at least 3 characters long but no longer than 8 characters
+// long. it can contain any character in the range 0x20-0x7e
+bool userdbclass::password_ok (const text_t &password) 
+{
+  // DB: 20/02/08. Why mustn't the password exceed 8 chars, 
+  // windows 3.1 complicance?  Even then this doesn't make sense to me
+  // as storing this in GDBM wouldn't trigger a 8-char limit
+
+  // Have increased this to 128.  Not because I think someone will type
+  // in something that long, but some encryptions schemes (e.g. wireless
+  // networks) work with such lengths and someone one day might like
+  // to use such a generated password in Greenstone.
+  // 
+
+  if (password.size() < 3 || password.size() > 128) return false;
+
+  text_t::const_iterator here = password.begin();
+  text_t::const_iterator end = password.end();
+  while (here != end) {
+    if (*here >= 0x20 && *here <= 0x7e) 
+      {
+        // ok
+      } else return false;
+    ++here;
+  }
+
+  return true;
+}
+
+// removes spaces from user groups
+text_t userdbclass::format_user_groups(const text_t user_groups)
+{
+  text_t new_groups = g_EmptyText;
+  text_t::const_iterator here = user_groups.begin();
+  text_t::const_iterator end = user_groups.end();
+  while (here != end) {
+    if (*here != ' '&& *here != '\t' && *here != '\n') 
+      {
+        new_groups.push_back(*here);
+      }
+    ++here;
+  }
+  return new_groups;
+}
+
+// functions dealing with user databases
+// returns true on success (in which case userinfo will contain
+// the information for this user)
+// @return 0 success
+// @return -1 database is not currently connected
+// @return -2 not defined username
+int userdbclass::get_user_info (const text_t &username, userinfo_t &userinfo) 
+{
+  // Let's make sure the connection has been established.
+  if (activated == true)
+    {
+      userinfo.clear();
+      infodbclass info;
+      // See if we can get the user's infomration
+      if (userdb->getinfo (username, info)) 
+        {
+          userinfo.username = info["username"];
+          userinfo.password = info["password"];
+          userinfo.enabled = (info["enabled"] == "true");
+          userinfo.groups = info["groups"];
+          userinfo.comment = info["comment"];
+          return ERRNO_SUCCEED;
+        }
+      // If we failed to retrieve the users information, we should check if the username is admin or not.
+      // If it is the admin user, let's create a new account for the admin user.
+      else if (username == "admin") 
+        {
+          userinfo.clear();
+          userinfo.username = "admin";
+          userinfo.password = crypt_text("admin");
+          userinfo.enabled = true;
+          userinfo.groups = "administrator,all-collections-editor";
+          userinfo.comment = "change the password for this account as soon as possible";
+          // Return the set result.
+          return set_user_info (username, userinfo);
+        }
+      // The username is not found, return false
+      return ERRNO_USERNOTFOUND;
+    }
+  // Failed to connect to the database, return false.
+  return ERRNO_CONNECTIONFAILED;
+}
+
+// returns true on success
+int userdbclass::set_user_info (const text_t &username, const userinfo_t &userinfo) 
+{
+  // Let's make sure the connection has been established.
+  if (activated == true)
+    {
+      infodbclass info;
+      info["username"] = userinfo.username;
+      info["password"] = userinfo.password;
+      info["enabled"] = userinfo.enabled ? "true" : "false";
+      info["groups"] = userinfo.groups;
+      info["comment"] = userinfo.comment;
+      userdb->closedatabase();
+      userdb->opendatabase(storeduserdbfilename, DB_WRITER_CREATE, 1000, true);
+      int result = (userdb->setinfo (username, info)) ? ERRNO_SUCCEED : ERRNO_DBACTIONFAILED;
+      userdb->closedatabase();
+      userdb->opendatabase(storeduserdbfilename, DB_READER, 1000, true);         
+      return  result;
+    }
+  return ERRNO_CONNECTIONFAILED;
+}
+
+// returns true if the user's password is correct.
+int userdbclass::check_passwd (const text_t &username, const text_t &password) 
+{
+  userinfo_t thisuser;
+  int returned = get_user_info(username, thisuser);
+  if(returned != ERRNO_SUCCEED) return returned;
+  // couple of basic checks
+  if (thisuser.username.empty() || thisuser.password.empty() ||
+      password.empty()) return ERRNO_MISSINGPASSWORD;
+
+  text_t crypt_password = crypt_text(password);
+  return (thisuser.password == crypt_password) ? ERRNO_SUCCEED : ERRNO_PASSWORDMISMATCH;
+}
+
+int userdbclass::add_user (const userinfo_t &userinfo) 
+{
+  // Let's make sure the connection has been established.
+  if (activated == true)
+    {
+      infodbclass info;
+      if (userdb->getinfo (userinfo.username, info)) 
+        {
+          // There is an existing username already
+          return ERRNO_EXISTINGUSERNAME;
+        }
+      else
+        {
+          return set_user_info(userinfo.username, userinfo);
+        }      
+    }
+  return ERRNO_CONNECTIONFAILED;
+}
+
+int userdbclass::edit_user (const userinfo_t &userinfo) 
+{
+  // Let's make sure the connection has been established.
+  if (activated == true)
+    {
+      infodbclass info;
+      if (userdb->getinfo (userinfo.username, info)) 
+        {
+          return set_user_info(userinfo.username, userinfo);
+        }
+      else
+        {
+          // The user does not exist in the database.
+          return ERRNO_USERNOTFOUND;
+        }      
+    }
+  return ERRNO_CONNECTIONFAILED;
+}
+
+int userdbclass::delete_user (const text_t &username) 
+{  
+  // Let's make sure the connection has been established.
+  if (activated == true)
+    {
+      userdb->closedatabase();
+      userdb->opendatabase(storeduserdbfilename, DB_WRITER_CREATE, 1000, true);
+      userdb->deletekey (username);
+      userdb->closedatabase();
+      userdb->opendatabase(storeduserdbfilename, DB_READER, 1000, true);
+      return ERRNO_SUCCEED;
+    }
+  return ERRNO_CONNECTIONFAILED;
+}
+
+// gets all the users' information in the database. returns true
+// on success
+int userdbclass::get_all_users(userinfo_tarray &userinfo_array) 
+{
+  // Let's make sure the connection has been established.
+  if (activated == true)
+    {
+      userinfo_array.erase(userinfo_array.begin(), userinfo_array.end());
+      text_tarray userlist = userdb->getkeys();
+      text_tarray::iterator user_iterator = userlist.begin();
+      while (user_iterator != userlist.end())
+      {
+        userinfo_t one_userinfo;
+        int returned = get_user_info(*user_iterator, one_userinfo);
+        if (returned != ERRNO_SUCCEED) return returned;
+        userinfo_array.push_back(one_userinfo);
+	user_iterator++;
+      }
+      return ERRNO_SUCCEED;
+    }
+  return ERRNO_CONNECTIONFAILED;
+}
+
+// gets a list of all the users in the database. returns true
+// on success
+int userdbclass::get_user_list (text_tarray &userlist) 
+{
+  // Let's make sure the connection has been established.
+  if (activated == true)
+    {
+      userlist.erase (userlist.begin(), userlist.end());
+      userlist = userdb->getkeys();
+      return ERRNO_SUCCEED;
+    }
+  return ERRNO_CONNECTIONFAILED;
+}
+//==========================================//
+//       userdbclass functions (End)        //
+//==========================================//
+
+//==========================================//
+//      keydbclass functions (Start)        //
+//==========================================//
+keydbclass::keydbclass(const text_t &keydbfilename)
+{
+  storedkeydbfilename = keydbfilename;
+  keydb = new gdbmclass();
+  activated = keydb->opendatabase(storedkeydbfilename, DB_READER, 1000, true);
+  if (activated == false) 
+    {
+      activated = keydb->opendatabase(storedkeydbfilename, DB_WRITER_CREATE, 1000, true);
+      if (activated == true)
+        {
+          keydb->closedatabase();
+          activated = keydb->opendatabase(storedkeydbfilename, DB_READER, 1000, true);
+        }
+    }
+  external_db = false;
+}
+
+keydbclass::~keydbclass()
+{
+  if (external_db == false)
+  {
+    keydb->closedatabase();
+    delete keydb;
+  }
+}
+
+// generates a random key for the user, stores it in the database and
+// returns it so that it can be used in page generation
+// returns "" on failure
+text_t keydbclass::generate_key (const text_t &username) 
+{
+  // Let's make sure the connection has been established.
+  if (activated == true)
+    {
+      static const char *numconvert = "0123456789abcdefghijklmnopqrstuvwxyz"
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+      
+      // loop looking for a suitable new key
+      text_t userkey;
+      text_t crypt_userkey;
+      do {
+        // convert to base 62 :-)
+        int userkey_int = rand ();
+        while (userkey_int > 0) 
+          {
+            userkey.push_back (numconvert[userkey_int%62]);
+            userkey_int /= 62;
+          }
+        
+        // make sure this key is not in the database
+        crypt_userkey = userdbclass::crypt_text(userkey);
+        if (keydb->exists (crypt_userkey)) userkey.clear();
+      } while (userkey.empty());
+      
+      // enter the key into the database
+      infodbclass keydata;
+      keydata["user"] = username;
+      keydata["time"] = time2text(time(NULL));
+      
+      keydb->closedatabase();
+      keydb->opendatabase(storedkeydbfilename, DB_WRITER_CREATE, 1000, true);
+      if (!keydb->setinfo (crypt_userkey, keydata)) 
+        {
+          userkey.clear(); // failed
+        }
+      keydb->closedatabase();
+      keydb->opendatabase(storedkeydbfilename, DB_READER, 1000, true); 
+      
+      return userkey;
+    }
+  return "";
+}
+
+// checks to see if there is a key for this particular user in the
+// database that hasn't decayed. a short decay is used when group
+// is set to administrator
+bool keydbclass::check_key (const userinfo_t &thisuser, const text_t &key, const text_t &group, int keydecay) 
+{
+  // Let's make sure the connection has been established.
+  if (activated == true)
+    {
+      if (thisuser.username.empty() || key.empty()) return false;
+      
+      // the keydecay is set to 5 minute for things requiring the
+      // administrator
+      //  if (group == "administrator") keydecay = 300;
+      
+      // success if there is a key in the key database that is owned by this
+      // user whose creation time is less that keydecay
+      text_t crypt_key = userdbclass::crypt_text(key);
+      infodbclass info;
+      if (keydb->getinfo (crypt_key, info))  {
+        if (info["user"] == thisuser.username) {
+          time_t keycreation = text2time (info["time"]);
+          if (keycreation != (time_t)-1 && difftime (text2time(time2text(time(NULL))),
+                                                     keycreation) <= keydecay) {
+            // succeeded, update the key's time
+            info["time"] = time2text(time(NULL));
+            keydb->closedatabase();
+            keydb->opendatabase(storedkeydbfilename, DB_WRITER_CREATE, 1000, true);
+            keydb->setinfo (crypt_key, info);
+            keydb->closedatabase();
+            keydb->opendatabase(storedkeydbfilename, DB_READER, 1000, true); 
+            return true;
+          }
+        }
+      }
+    }
+  return false;
+}
+
+// remove_old_keys will remove all keys created more than keydecay ago.
+// use sparingly, it can be quite an expensive function
+void keydbclass::remove_old_keys (int keydecay) 
+{
+  // Let's make sure the connection has been established.
+  if (activated == true)
+    {  
+      // get a list of keys created more than keydecay seconds agon
+      text_tarray oldkeys;
+      infodbclass info;
+      time_t timenow = text2time(time2text(time(NULL)));
+      time_t keycreation = (time_t)-1;
+
+      text_tarray keylist = keydb->getkeys();
+      text_tarray::iterator key_iterator = keylist.begin();
+      while (key_iterator != keylist.end())
+      {
+        if (keydb->getinfo (*key_iterator, info))  {
+          keycreation = text2time (info["time"]);
+          if (keycreation != (time_t)-1 && difftime (timenow, keycreation) > keydecay) {
+            // found an old key
+            oldkeys.push_back(*key_iterator);
+          }
+        }
+        
+	key_iterator++;
+      }
+      
+      // delete the old keys
+      if (oldkeys.size() > 0) {
+	keydb->closedatabase();
+	keydb->opendatabase(storedkeydbfilename, DB_WRITER_CREATE, 1000, true);
+	text_tarray::iterator keys_here = oldkeys.begin();
+	text_tarray::iterator keys_end = oldkeys.end();
+	while (keys_here != keys_end) {
+	  keydb->deletekey(*keys_here);
+	  ++keys_here;
+	}
+	keydb->closedatabase();
+	keydb->opendatabase(storedkeydbfilename, DB_READER, 1000, true);
+      }
+    }
+}
+//==========================================//
+//       keydbclass functions (End)         //
+//==========================================//
Index: /gsdl/stable/runtime-src/src/recpt/userdb.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/userdb.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/userdb.h	(revision 20131)
@@ -0,0 +1,147 @@
+/**********************************************************************
+ *
+ * userdb.h -- functions to handle a user database
+ * Copyright (C) 1999  DigiLib Systems Limited, New Zealand
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef USERDB_H
+#define USERDB_H
+
+#define ERRNO_SUCCEED           0 
+#define ERRNO_CONNECTIONFAILED -1
+#define ERRNO_USERNOTFOUND     -2
+#define ERRNO_EXISTINGUSERNAME -3
+#define ERRNO_MISSINGPASSWORD  -4
+#define ERRNO_PASSWORDMISMATCH -5
+#define ERRNO_DBACTIONFAILED   -6
+
+
+#include "dbclass.h"
+
+// The user information object and it provides basic functions for the information object, such as clear and copy (=) functions;
+class userinfo_t
+{
+ public:
+  text_t username;
+  text_t password;
+  bool enabled;
+  text_t groups; // comma separated list
+  text_t comment;
+
+  userinfo_t ();
+  virtual ~userinfo_t();
+  userinfo_t &operator=(const userinfo_t &x);
+  void clear ();
+};
+
+typedef vector<userinfo_t> userinfo_tarray; // more space efficient than text_tlist
+
+class userdbclass
+{
+ protected:
+  // The internal storage for the userdbfilename and the userdb object
+  dbclass* userdb;
+  bool external_db;
+  bool activated;
+  text_t storeduserdbfilename; 
+  
+ public:
+  userdbclass (const text_t &userdbfilename);
+  virtual ~userdbclass();
+
+  //======== the static methods========//
+  // the password line in the userinfo_t must be encrypted using
+  // this function
+  static text_t crypt_text (const text_t &text);
+  // username_ok tests to make sure a username is ok. a username
+  // must be at least 2 characters long, but no longer than 30
+  // characters long. it can contain the characters a-z A-Z 0-9
+  // . and _
+  static bool username_ok (const text_t &username);
+  // password_ok tests to make sure a password is ok. a password
+  // must be at least 3 characters long but no longer than 8 characters
+  // long. it can contain any character in the range 0x20-0x7e
+  static bool password_ok (const text_t &password);
+  // removes spaces from user groups
+  static text_t format_user_groups(const text_t user_groups);
+  
+  //======== functions dealing with single user in the user databases ========//
+  // returns true on success (in which case userinfo will contain
+  // the information for this user)
+  int get_user_info (const text_t &username, userinfo_t &userinfo);
+  
+  // returns true on success
+  int set_user_info (const text_t &username, const userinfo_t &userinfo);
+  
+  // returns true if the user's password is correct.
+  int check_passwd (const text_t &username, const text_t &password);
+  
+  // adds a user from the user database -- forever
+  int add_user (const userinfo_t &userinfo);
+  
+  // edits a user from the user database -- forever
+  int edit_user (const userinfo_t &userinfo);
+  
+  // removes a user from the user database -- forever
+  int delete_user (const text_t &username);
+  
+  //======== functions dealing with multiple users in the user databases ========//
+  // gets all the users' information in the database. returns true
+  // on success
+  int get_all_users(userinfo_tarray &userinfo_array);
+  
+  // gets a list of all the users in the database. returns true
+  // on success
+  int get_user_list (text_tarray &userlist);
+};
+
+class keydbclass
+{
+ protected:
+  // The internal storage for the userdbfilename and the userdb object
+  dbclass* keydb;
+  bool external_db;
+  bool activated;
+   text_t storedkeydbfilename; 
+  
+ public:
+  keydbclass (const text_t &keydbfilename);
+  virtual ~keydbclass();
+  // functions dealing with databases of temporary keys
+  
+  // generates a random key for the user, stores it in the database and
+  // returns it so that it can be used in page generation
+  // returns "" on failure
+  text_t generate_key (const text_t &username);
+  
+  // checks to see if there is a key for this particular user in the
+  // database that hasn't decayed. a short decay is used when group
+  // is set to administrator
+  bool check_key (const userinfo_t &thisuser, const text_t &key, const text_t &group, int keydecay);
+  
+  // remove_old_keys will remove all keys created more than keydecay ago.
+  // use sparingly, it can be quite an expensive function
+  void remove_old_keys (int keydecay);
+};
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/usersaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/usersaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/usersaction.cpp	(revision 20131)
@@ -0,0 +1,412 @@
+/**********************************************************************
+ *
+ * usersaction.cpp -- managing users
+ * Copyright (C) 1999  DigiLib Systems Limited, New Zealand
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_USERS_ACTION
+
+#include "usersaction.h"
+#include "fileutil.h"
+
+
+///////////////
+// usersaction
+///////////////
+
+usersaction::usersaction () {
+  // this action uses cgi variable "a"
+  cgiarginfo arg_ainfo;
+  arg_ainfo.shortname = "a";
+  arg_ainfo.longname = "action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "um"; // user management
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "uma"
+  arg_ainfo.shortname = "uma";
+  arg_ainfo.longname = "user management action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "listusers";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "umun"
+  arg_ainfo.shortname = "umun";
+  arg_ainfo.longname = "user management user name";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "umpw"
+  arg_ainfo.shortname = "umpw";
+  arg_ainfo.longname = "user management password";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "umnpw1"
+  arg_ainfo.shortname = "umnpw1";
+  arg_ainfo.longname = "user management new password 1";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "umnpw2"
+  arg_ainfo.shortname = "umnpw2";
+  arg_ainfo.longname = "user management new password 2";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "umus"
+  arg_ainfo.shortname = "umus";
+  arg_ainfo.longname = "user management account status";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "umug"
+  arg_ainfo.shortname = "umug";
+  arg_ainfo.longname = "user management groups"; // comma seperated list
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "umc"
+  arg_ainfo.shortname = "umc";
+  arg_ainfo.longname = "user management comment";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "bcp"
+  arg_ainfo.shortname = "bcp";
+  arg_ainfo.longname = "change password submit button";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "beu"
+  arg_ainfo.shortname = "beu";
+  arg_ainfo.longname = "edit user submit button";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // "cm"
+  arg_ainfo.shortname = "cm";
+  arg_ainfo.longname = "confirm an action";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = g_EmptyText;
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+}
+
+void usersaction::configure (const text_t &key, const text_tarray &cfgline) {
+  action::configure (key, cfgline);
+}
+
+bool usersaction::init (ostream &logout) {
+
+  if (dbhome.empty()) {
+    logout << "ERROR (usersaction::init) dbhome is not set\n";
+    return false;
+  }
+
+  return action::init (logout);
+}
+
+bool usersaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args, 
+				 recptprotolistclass * /*protos*/, ostream &/*logout*/) {
+  args["uan"] = "1"; // user authentication is needed
+
+  if (args["uma"] == "changepasswd") {
+    // no particular group is needed to change a password
+    args["ug"].clear(); 
+  } else {
+    // administrator is needed for all other management tasks
+    args["ug"] = "administrator";
+  }
+  
+  return true;
+}
+
+void usersaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
+				    response_t &response, text_t &response_data, 
+				    ostream &/*logout*/) {
+  response = content;
+  response_data = "text/html";
+}
+
+bool usersaction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/, 
+			     browsermapclass * /*browsers*/, displayclass &disp, 
+			     outconvertclass &outconvert, ostream &textout, 
+			     ostream &logout) {
+
+  if (args["uma"] == "adduser" || args["uma"] == "edituser") {
+    // adduser is handled by edituser
+    return do_edituser (args, disp, outconvert, textout, logout);
+    
+  } else if (args["uma"] == "deleteuser") {
+    return do_deleteuser (args, disp, outconvert, textout, logout);
+    
+  } else if (args["uma"] == "changepasswd") {
+    return do_changepasswd (args, disp, outconvert, textout, logout);  
+  }
+
+  // default
+  return do_listusers (args, disp, outconvert, textout, logout);
+}
+
+bool usersaction::do_listusers (cgiargsclass &/*args*/, displayclass &disp, 
+				outconvertclass &outconvert, ostream &textout, 
+				ostream &/*logout*/) {
+
+  textout << outconvert << disp
+	  << "_userslistusers:header_\n_userslistusers:contentstart_\n";
+
+  text_tarray userlist;
+  // get user list
+  user_database->get_user_list (userlist);
+
+  // sort the list
+  sort(userlist.begin(), userlist.end());
+  
+  // output the information for each user
+  userinfo_t userinfo;
+  text_tarray::iterator users_here = userlist.begin();
+  text_tarray::iterator users_end = userlist.end();
+  while (users_here != users_end) {
+    if (user_database->get_user_info(*users_here, userinfo) == ERRNO_SUCCEED) {
+      textout << outconvert << disp
+	      << "<tr><td bgcolor=\"\\#eeeeee\">" << userinfo.username << "</td>\n"
+       	      << "<td bgcolor=\"\\#eeeeee\">" << (char *) (userinfo.enabled ? "enabled" : "disabled") << "</td>\n"
+	      << "<td bgcolor=\"\\#eeeeee\">" << userinfo.groups << "&nbsp;</td>\n"
+	      << "<td bgcolor=\"\\#eeeeee\">" << userinfo.comment << "&nbsp;</td>\n"
+	      << "<td><a href=\"_httpcurrentdocument_&a=um&uma=edituser&umun="
+	      << userinfo.username << "\">_userslistusers:textedituser_</a> "
+	      << "<a href=\"_httpcurrentdocument_&a=um&uma=deleteuser&umun="
+	      << userinfo.username << "\">_userslistusers:textdeleteuser_</a>"
+	      << "</td></tr>\n\n";
+
+    } else {
+      textout << outconvert << disp
+	      << "<tr><td bgcolor=\"\\#eeeeee\">" << *users_here << "</td>\n"
+	      << "<td bgcolor=\"\\#eeeeee\">&nbsp;</td>\n"
+	      << "<td bgcolor=\"\\#eeeeee\">&nbsp;</td>\n"
+	      << "<td bgcolor=\"\\#eeeeee\">&nbsp;</td>\n"
+	      << "<td>&nbsp;</td></tr>\n\n";
+    }
+    
+    ++users_here;
+  }
+  
+  textout << outconvert << disp
+	  << "_userslistusers:contentend_\n_userslistusers:footer_\n";
+  return true;
+}
+
+void usersaction::define_user_macros (cgiargsclass &args, displayclass &disp) {
+  disp.setmacro ("usersargun", "users", args["umun"]);
+  disp.setmacro ("usersargpw", "users", args["umpw"]);
+  disp.setmacro ("usersargus", "users", args["umus"]);
+  disp.setmacro ("usersargug", "users", args["umug"]);
+  disp.setmacro ("usersargc", "users", args["umc"]);
+}
+
+
+bool usersaction::do_edituser (cgiargsclass &args, displayclass &disp, 
+			       outconvertclass &outconvert, ostream &textout, 
+			       ostream &logout) {
+
+  userinfo_t userinfo;
+  text_t messagestatus;
+  bool noproblems = true;
+  
+  // fill in defaults from user database (if appropriate)
+  if (args["umun"].empty()) {
+    noproblems = false;
+    
+  } else if (!userdbclass::username_ok (args["umun"])) {
+    // problem with username
+    noproblems = false;
+    messagestatus += "_users:messageinvalidusername_";
+    
+  } else if (user_database->get_user_info (args["umun"], userinfo) == ERRNO_SUCCEED) {
+    if (args["uma"] == "adduser") {
+      // must not add a user that has the same name as another user
+      noproblems = false;
+      messagestatus += "_users:messageuserexists_";
+      
+    } else {
+      // only fill in the data if there is no user status defined
+      if (args["umus"].empty()) {
+	args["umus"] = userinfo.enabled ? "enabled" : "disabled";
+	if (args["umug"].empty()) args["umug"] = userinfo.groups;
+	if (args["umc"].empty()) args["umc"] = userinfo.comment;
+      }
+    }
+  }
+
+  // fill in the user status default
+  if (args["umus"].empty()) {
+    noproblems = false;
+    args["umus"] = "enabled";
+  }
+  
+  // make sure the password is ok
+  if (args["umpw"].empty()) {
+    // password must not be empty if none were supplied from database
+    // and we have had no other problems
+    if (userinfo.password.empty() && noproblems) {
+      noproblems = false;
+      messagestatus += "_users:messageemptypassword_";
+    }
+    
+  } else if (!userdbclass::password_ok(args["umpw"])) {
+    noproblems = false;
+    messagestatus += "_users:messageinvalidpassword_";
+  }
+
+  // set this info if no problems have been encounted
+  // and the submit button was pressed
+  if (noproblems && !args["beu"].empty()) {
+    userinfo.username = args["umun"];
+    if (!args["umpw"].empty()) {
+      // only set the password if it is not empty
+      userinfo.password = userdbclass::crypt_text(args["umpw"]);
+    }
+    userinfo.enabled = (args["umus"] == "enabled");    
+    userinfo.groups = userdbclass::format_user_groups(args["umug"]);
+    userinfo.comment = args["umc"];
+    
+    user_database->set_user_info (args["umun"], userinfo);
+    
+    // show list of users
+    return do_listusers (args, disp, outconvert, textout, logout);
+  }
+  
+  // define the macros for the user
+  define_user_macros (args, disp);
+  disp.setmacro ("messagestatus", "users", messagestatus);
+  
+  textout << outconvert << disp
+	  << "_usersedituser:header_\n_usersedituser:content_\n_usersedituser:footer_\n";
+
+  return true;
+}
+
+bool usersaction::do_deleteuser (cgiargsclass &args, displayclass &disp, 
+				 outconvertclass &outconvert, ostream &textout, 
+				 ostream &logout) {
+  if (!args["cm"].empty()) {
+    if (args["cm"] == "yes" && !args["umun"].empty()) {
+      // user confirmed the deletion of the user
+      user_database->delete_user(args["umun"]);
+    }
+    
+    // redirect the user back to the listusers page
+    return do_listusers (args, disp, outconvert, textout, logout);
+  }
+
+  define_user_macros (args, disp);
+  textout << outconvert << disp
+	  << "_usersdeleteuser:header_\n_usersdeleteuser:content_\n_usersdeleteuser:footer_\n";
+  
+  return true;
+}
+
+bool usersaction::do_changepasswd (cgiargsclass &args, displayclass &disp, 
+				   outconvertclass &outconvert, ostream &textout, 
+				   ostream &/*logout*/) {
+  text_t messagestatus;
+  
+  if (!args["bcp"].empty()) {
+    if (args["un"].empty()) {
+      messagestatus = "_users:messageusernameempty_";
+    } else if (args["umpw"].empty()) {
+      messagestatus = "_users:messagepasswordempty_";
+    } else if (args["umnpw1"].empty()) {
+      messagestatus = "_users:messagenewpass1empty_";
+    } else if (args["umnpw2"].empty()) {
+      messagestatus = "_users:messagenewpass2empty_";
+    } else if (args["umnpw1"] != args["umnpw2"]) {
+      messagestatus = "_users:messagenewpassmismatch_";
+    } else if (!userdbclass::password_ok(args["umnpw1"])) {
+      messagestatus = "_users:messageinvalidpassword_";
+    } else {
+      userinfo_t userinfo;
+      if (user_database->get_user_info (args["un"], userinfo) == ERRNO_SUCCEED) {
+	// check old password
+	if (userinfo.password != userdbclass::crypt_text(args["umpw"])) {
+	  messagestatus = "_users:messagefailed_";
+	  
+	} else {
+	  userinfo.password = userdbclass::crypt_text(args["umnpw1"]);
+	  if (user_database->set_user_info (args["un"], userinfo) == ERRNO_SUCCEED) {
+	    // everything is ok
+	    textout << outconvert << disp
+		    << "_userschangepasswdok:header_\n"
+	      "_userschangepasswdok:content_\n"
+	      "_userschangepasswdok:footer_\n";
+	    return true;
+	  }
+	}
+      }
+    }
+  }
+
+  disp.setmacro ("messagestatus", "users", messagestatus);
+
+  textout << outconvert << disp
+	  << "_userschangepasswd:header_\n"
+    "_userschangepasswd:content_\n"
+    "_userschangepasswd:footer_\n";
+
+  return true;
+}
+
+#endif //GSDL_USE_USERS_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/usersaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/usersaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/usersaction.h	(revision 20131)
@@ -0,0 +1,87 @@
+/**********************************************************************
+ *
+ * usersaction.h -- managing users
+ * Copyright (C) 1999  DigiLib Systems Limited, New Zealand
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+#ifdef GSDL_USE_USERS_ACTION
+
+#ifndef USERSACTION_H
+#define USERSACTION_H
+
+#include "gsdlconf.h"
+#include "action.h"
+#include "userdb.h"
+#include "text_t.h"
+
+
+class usersaction : public action {
+protected:
+  userdbclass *user_database;
+
+public:
+  usersaction ();
+  virtual ~usersaction () {}
+
+  void configure (const text_t &key, const text_tarray &cfgline);
+
+  bool init (ostream &logout);
+
+  void set_userdb(userdbclass *udb) {user_database = udb;}
+  
+  text_t get_action_name () {return "um";}
+  
+  bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+		      recptprotolistclass *protos, ostream &logout);
+
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response, text_t &response_data, 
+			 ostream &logout);
+  
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+
+protected:
+  void define_user_macros (cgiargsclass &args, displayclass &disp);
+  
+  bool do_listusers (cgiargsclass &args, displayclass &disp, 
+		     outconvertclass &outconvert, ostream &textout, 
+		     ostream &logout);
+
+  bool do_edituser (cgiargsclass &args, displayclass &disp, 
+		    outconvertclass &outconvert, ostream &textout, 
+		    ostream &logout);
+
+  bool do_deleteuser (cgiargsclass &args, displayclass &disp, 
+		      outconvertclass &outconvert, ostream &textout, 
+		      ostream &logout);
+
+  bool do_changepasswd (cgiargsclass &args, displayclass &disp, 
+			outconvertclass &outconvert, ostream &textout, 
+			ostream &logout);
+};
+
+#endif //!USERSACTION_H
+#endif //GSDL_USE_USERS_ACTION
Index: /gsdl/stable/runtime-src/src/recpt/vlistbrowserclass.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/vlistbrowserclass.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/vlistbrowserclass.cpp	(revision 20131)
@@ -0,0 +1,463 @@
+/**********************************************************************
+ *
+ * vlistbrowserclass.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "vlistbrowserclass.h"
+#include "OIDtools.h"
+#include "browsetoolsclass.h"
+#include "cgiutils.h"
+
+
+vlistbrowserclass::vlistbrowserclass () {
+}
+
+vlistbrowserclass::~vlistbrowserclass () {
+}
+
+// returns the name that specifies the browserclass type
+text_t vlistbrowserclass::get_browser_name () {
+  return "VList";
+}
+
+browserclass* vlistbrowserclass::clone()
+{
+  vlistbrowserclass* browser = new vlistbrowserclass();
+  if (browser != NULL) {
+#ifdef GSDL_USE_BY_BOOK_MACROS
+    browser->m_oByBookMacros.Copy(m_oByBookMacros);
+#endif
+  }
+  return browser;
+}
+
+void vlistbrowserclass::load_metadata_defaults (text_tset &metadata) {
+  metadata.insert ("haschildren");
+  metadata.insert ("doctype");
+}
+
+text_t vlistbrowserclass::get_default_formatstring () {
+  return "<td valign=\"top\">[link][icon][/link]</td>"
+    "<td valign=\"top\">[srclink]{Or}{[thumbicon],[srcicon]}[/srclink]</td>"
+    "<td valign=\"top\">[highlight]{Or}{[dls.Title],[dc.Title],[Title],Untitled}[/highlight]"
+    "{If}{[Source],<br><i>([Source])</i>}</td>";
+}
+
+bool vlistbrowserclass::show_search_result_links(recptproto * collectproto,const text_t &collection,ostream& logout){
+     ColInfoResponse_t cinfo;
+     comerror_t err;
+     collectproto->get_collectinfo (collection, cinfo, err, logout);
+     bool show_links = false;
+
+     text_tmap::const_iterator format_here = cinfo.format.begin();
+     text_tmap::const_iterator format_end = cinfo.format.end();
+     
+     while (format_here != format_end) {
+       if (((*format_here).first == "DocumentSearchResultLinks") && 
+	   ((*format_here).second == "true")){
+	 show_links = true;
+         break;
+       }
+       ++format_here;
+     } 
+     
+     return show_links;
+}
+
+int vlistbrowserclass::output_section_group(ResultDocInfo_t &section, cgiargsclass &args,
+                                            const text_t &collection, int colnumber, 
+                                            format_t *formatlistptr, bool use_table, 
+                                            text_tset &metadata, bool &getParents, 
+                                            recptproto * collectproto, displayclass &disp, 
+                                            outconvertclass &outconvert, ostream &textout, 
+                                            ostream& logout)
+{
+  browsetoolsclass btools;
+  text_t link, icon;
+  text_t collink = collection;
+  bool show_links = show_search_result_links(collectproto,collection,logout);
+
+
+#ifndef DOCHANDLE
+  if (!collink.empty()) collink = "&amp;c=" + collink;
+#endif
+
+  get_link_icon (section, args, collink, link, icon, show_links);
+
+  //get_link_icon (section, args, collink, link, icon);
+
+  bool highlight = false;
+  if (!args["d"].empty()) {
+    if (args["d"] == section.OID) highlight = true;
+  } else 
+    if (args["cl"] == section.OID) highlight = true;
+
+
+  /* use_table is set to true if the format string starts with <td> */
+  if (use_table || colnumber > 0) {
+    if (colnumber > 0 ){
+      textout << outconvert << "<table id=\"toc_top\" class=\"v_list\"><tr valign=\"top\">";
+    }
+    else{
+      textout << outconvert << "<table id=\"toc_top\" class=\"v_list\"><tr valign=\"top\">";
+    }
+
+    // get tab size
+    text_t tab; int itab;
+    disp.expandstring (displayclass::defaultpackage, "_tabwidth_", tab);
+    itab = tab.getint();
+    if (colnumber > 0) textout << outconvert << disp 
+			       << "<td><img alt=\"\" src=\"_httpiconspace_\" width=\"" 
+			       << (itab*colnumber) << "\"/></td>";
+  } else {
+    textout << outconvert << "<div class=\"v_list\">\n";
+  }
+
+  text_tmap options;
+  options["link"] = link;
+  options["icon"] = icon;
+  if (highlight) options["highlight"] = "1";
+  else options["highlight"] = "0";
+  options["DocImage"] = btools.get_cover_image();
+  textout << outconvert << disp 
+	  << get_formatted_string (collection, collectproto, 
+				   section, disp, formatlistptr, 
+				   options, logout);
+  
+  if (use_table  || colnumber > 0) {
+    textout << outconvert << "</tr></table>\n";
+  } else {
+    textout << outconvert << "</div>\n";
+  }
+
+  return 1;
+}
+
+int vlistbrowserclass::output_section_group(FilterResponse_t &sections, cgiargsclass &args,
+                                            const text_t &collection, int colnumber, 
+                                            format_t *formatlistptr, bool use_table, 
+                                            text_tset &/*metadata*/, bool &/*getParents*/, 
+                                            recptproto * collectproto, displayclass &disp, 
+                                            outconvertclass &outconvert, ostream &textout, 
+                                            ostream& logout)
+{
+  browsetoolsclass btools;
+  text_t link, icon;
+  text_t &arg_d = args["d"];
+  text_t &arg_cl = args["cl"];
+  
+  text_t collink = collection;
+  bool show_links = show_search_result_links(collectproto,collection,logout);
+
+#ifndef DOCHANDLE
+  if (!collink.empty()) collink = "&amp;c=" + collink;
+#endif
+
+  if (colnumber > 0) {
+    textout << outconvert << "<table id=\"tabwidth\"><tr valign=\"top\">";
+    // get tab size
+    text_t tab; int itab;
+    disp.expandstring (displayclass::defaultpackage, "_tabwidth_", tab);
+    itab = tab.getint();
+    if (colnumber > 0) textout << outconvert << disp 
+			       << "<td><img alt=\"\" src=\"_httpiconspace_\" width=\"" 
+			       << (itab*colnumber) << "\"/></td>";
+    textout << outconvert << "<td>";
+  }
+
+  /* use table set to true if format string starts with <td> */
+  if (use_table) {
+    textout << outconvert << "<table id=\"group_top\" class=\"v_list\">\n";
+  } else {
+    textout << outconvert << "<div   id=\"group_top\" class=\"v_list\">\n";
+  }
+
+  ResultDocInfo_tarray::iterator thissection = sections.docInfo.begin();
+  ResultDocInfo_tarray::iterator endsection = sections.docInfo.end();
+
+  // ** here lies Alan's hack to get 4 results per table row
+  int item = 0, perline; // set perline to 1 normally
+  text_t fstring;
+
+  text_tmap options;
+  options["link"] = link;
+  options["icon"] = icon;
+  options["highlight"] = "0";
+  options["DocImage"] = btools.get_cover_image();
+  
+  if ( thissection != endsection ) { // only if there are results (else corrupts display)
+    fstring = get_formatted_string (collection, collectproto, *thissection,
+                                    disp, formatlistptr, options, logout);
+    // if format string
+    // has <td><t (e.g. <td><table>) then
+    // we assume it is an image and put it in 4 columns
+    if (fstring[5] == 't') 
+      perline = 4;
+    else
+      perline = 1;
+  }
+
+  int count = 0; 
+
+  while (thissection != endsection) {
+    ++item;
+    get_link_icon (*thissection, args, collink, link, icon,show_links);
+    //get_link_icon (*thissection, args, collink, link, icon);
+    bool highlight = false;
+    if (!arg_d.empty()) {
+      if (arg_d == (*thissection).OID) highlight = true;
+    } else 
+      if (arg_cl == (*thissection).OID) highlight = true;
+
+    if ((item == 1 && use_table) || colnumber > 0 )
+      textout << outconvert << "<tr valign=top>\n";
+
+    options["link"] = link;
+    options["icon"] = icon;
+    if (highlight) options["highlight"] = "1";
+    else options["highlight"] = "0";
+    options["DocImage"] = btools.get_cover_image();
+    
+    textout << outconvert << disp 
+	    << " " << get_formatted_string (collection, collectproto, *thissection, disp,
+					    formatlistptr, options, logout);
+
+    if ((item >= perline && use_table) || colnumber > 0) {
+      textout << outconvert << "\n</tr>";
+      item = 0;
+    }
+    textout << outconvert << "\n";
+    ++thissection;
+  }
+
+  if (use_table)
+    textout << outconvert << "</table>\n";
+  else
+    textout << outconvert << "</div>\n";
+  if (colnumber > 0) textout << outconvert << "</td></tr></table>\n";
+
+  return 1;
+}
+
+
+// get_link_icon attempts to work out what type of icon should be displayed for
+// the given section and what it should link to.
+// [modification to allow default document detach settings -- kjdon]
+void vlistbrowserclass::get_link_icon (ResultDocInfo_t &section, cgiargsclass &args,
+				       const text_t &collink, text_t &link, text_t &icon, bool showresultlinks) {
+
+ 
+
+#ifndef DOCHANDLE
+  link = "<a href=\"_httpdocument_" + collink;
+#else
+  link = "<a href=\"_httpdocumenthandle_(" + collink;
+#endif
+
+  text_t link_end = "\">";
+
+#ifndef DOCHANDLE
+  text_t detach_link_end = "&amp;x=1\" target=\\_blank>"; // to detach the link, and x=1 signifies it is a detached page
+#else
+  text_t detach_link_end = "\" target=\\_blank>"; // to detach the link, and x=1 signifies it is a detached page
+#endif
+
+  icon = "_document:icontext_";
+
+  text_t doctype;
+  int haschildren = 0;
+
+  if (section.metadata.count("haschildren")>0)
+    haschildren = section.metadata["haschildren"].values[0].getint();
+  if (section.metadata.count("doctype")>0)
+    doctype = section.metadata["doctype"].values[0];
+
+  text_t &arg_d = args["d"];
+  text_t &arg_cl = args["cl"];
+
+  if (args["a"] == "q")
+  {
+    // query results list
+#ifndef DOCHANDLE
+    int result_num = section.result_num;
+    int num_docs = args["nmd"].getint();
+    int srn = 0;
+    int srp = 0;
+    if (showresultlinks && result_num < num_docs) {
+      srn = result_num  + 1;
+    }    
+    if (showresultlinks && result_num > 1 ) {
+      srp = result_num  - 1;
+    }    
+        
+    text_t srp_t = srp; 
+    text_t srn_t = srn; 
+    link +="&amp;srp="+srp_t;
+    link +="&amp;srn="+srn_t;
+    link +="&amp;cl=search&amp;d=" + section.OID;
+#else
+    link += "," + section.OID+")";
+#endif
+ 
+    if (args["xx"] == "1") {
+      link += detach_link_end;
+    }
+    else {
+      link += link_end;
+    }
+    if ((is_top (section.OID)) && (haschildren == 1)) icon = "_document:iconclosedbook_";
+    else if (haschildren == 1) icon = "_document:iconclosedfolder_";  
+  }
+  else if (!arg_d.empty()) {
+    // we are in a document - none of the links should be detach links
+    if (is_top(section.OID)) {
+      // we link back to the originating page eg search page or classifier page
+      icon = "_document:iconopenbook_";
+      if (arg_cl == "search") { 
+	link = "<a href=\"_httpquery_\">";
+      }
+      else {
+#ifndef DOCHANDLE
+	link += "&amp;cl=" + arg_cl + "\">";
+#else
+	link += ","+arg_cl + ")\">";
+#endif
+      }
+    }
+    else if (haschildren == 1) {
+      if ((args["gc"] == "1") || 
+	  (is_child_of (section.OID, arg_d)) ||
+	  (section.OID == arg_d)) {
+	icon = "_document:iconopenfolder_";
+#ifndef DOCHANDLE
+	link += "&amp;cl=" + arg_cl + "&amp;d=" + section.OID + ".pr\">";
+#else
+	link += ","+section.OID + ".pr)\">";
+#endif
+      }
+      else {
+	icon = "_document:iconclosedfolder_";
+#ifndef DOCHANDLE
+	link += "&amp;cl=" + arg_cl + "&amp;d=" + section.OID + "\">";
+#else
+	link += ","+section.OID + ")\">";
+#endif
+      }
+    }
+    else {
+      if (args["gt"] == "0") {
+#ifndef DOCHANDLE
+	link += "&amp;cl=" + arg_cl + "&amp;d=" + section.OID + "\">";
+#else
+	link += ","+section.OID + ")\">";
+#endif
+      }
+      else {
+#ifndef DOCHANDLE
+	link += "&amp;cl=" + arg_cl + "&amp;d=" + section.OID + "#" + section.OID + "\">";
+#else
+	link += ","+section.OID + "#" + section.OID + ")\">";
+#endif
+      }
+    }
+  }
+  else {
+    // classification level - links to docs may be detaching
+    if (haschildren == 1) {
+      if (doctype == "classify") {
+	// Dynamic classifier nodes
+	if (args["a"] == "dc")
+	{
+	  // Parent node or current node
+	  text_t classifier_node_dcn = "";
+	  if (!starts_with (section.OID, args["dcn"]) || section.OID == args["dcn"])
+	  {
+	    icon = "_document:iconopenbookshelf_";
+	    classifier_node_dcn = section.OID + ".pr";
+	  }
+	  // Child node
+	  else
+	  {
+	    icon = "_document:iconclosedbookshelf_";
+	    classifier_node_dcn = section.OID;
+	  }
+
+	  // The node label is going into the URL, so make it CGI-safe
+	  text_t classifier_node_dcn_cgi_safe = cgi_safe_utf8(classifier_node_dcn);
+	  link = "<a href=\"_gwcgi_?c=" + args["c"] + "&amp;a=dc&amp;dcl=" + args["dcl"] + "&amp;dcn=" + classifier_node_dcn_cgi_safe + "\">";
+	}
+	// Static classifier nodes
+	else if ((args["gc"] == "1") || 
+	    (is_child_of (section.OID, arg_cl)) || 
+	    (section.OID == arg_cl)) {
+	  icon = "_document:iconopenbookshelf_";
+
+#ifndef DOCHANDLE
+	  link += "&amp;cl=" + section.OID + ".pr\">";
+#else
+	  link += ","+section.OID + ".pr)\">";
+#endif
+	}
+	else {
+	  icon = "_document:iconclosedbookshelf_";
+
+#ifndef DOCHANDLE
+	  link += "&amp;cl=" + section.OID + "\">";
+#else
+	  link += ","+section.OID + ")\">";
+#endif
+	}
+      }
+      else {
+	icon = "_document:iconclosedbook_";
+#ifndef DOCHANDLE
+	link += "&amp;cl=" + arg_cl + "&amp;d=" + section.OID;
+#else
+	link += ","+section.OID+")";
+#endif
+	if (args["xx"] == "1") {
+	  link +=  detach_link_end;
+	}
+	else {
+	  link += link_end;
+	}
+      }
+    }
+    else {
+      if (doctype == "classify") link = "";
+      else {
+#ifndef DOCHANDLE
+	link += "&amp;cl=" + arg_cl + "&amp;d=" + section.OID;
+#else
+	link += "," + section.OID +")";
+#endif
+	if (args["xx"] == "1") {
+	  link +=  detach_link_end;
+	}
+	else {
+	  link += link_end;
+	}
+      }
+    }
+  }
+}
Index: /gsdl/stable/runtime-src/src/recpt/vlistbrowserclass.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/vlistbrowserclass.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/vlistbrowserclass.h	(revision 20131)
@@ -0,0 +1,73 @@
+/**********************************************************************
+ *
+ * vlistbrowserclass.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+
+#ifndef VLISTBROWSERCLASS_H
+#define VLISTBROWSERCLASS_H
+
+#include "browserclass.h"
+#include "receptionist.h"
+
+class vlistbrowserclass : public browserclass {
+protected:
+
+public:
+  vlistbrowserclass ();
+  virtual ~vlistbrowserclass ();
+
+  void set_receptionist(receptionist *therecpt) {recpt=therecpt;}
+
+  text_t get_browser_name ();
+
+  virtual browserclass* clone();
+
+  virtual void load_metadata_defaults (text_tset &metadata);
+
+  virtual text_t get_default_formatstring ();
+
+  virtual int output_section_group (ResultDocInfo_t &section, cgiargsclass &args,
+				    const text_t &collection, int colnumber, format_t *formatlistptr, 
+				    bool use_table, text_tset &metadata, bool &getParents,
+				    recptproto *collectproto, displayclass &disp, 
+				    outconvertclass &outconvert, ostream &textout, ostream &logout);
+
+  virtual int output_section_group (FilterResponse_t &sections, cgiargsclass &args,
+				    const text_t &collection, int colnumber, format_t *formatlistptr, 
+				    bool use_table, text_tset &metadata, bool &getParents,
+				    recptproto *collectproto, displayclass &disp, 
+				    outconvertclass &outconvert, ostream &textout, ostream &logout);
+
+protected:
+
+ 
+  virtual void get_link_icon (ResultDocInfo_t &section, cgiargsclass &args,
+			     const text_t &collink, text_t &link, text_t &icon, bool showresultlinks);
+
+  virtual bool show_search_result_links (recptproto * collectproto,const text_t &collection,ostream& logout);
+
+  receptionist *recpt;
+};
+
+#endif
Index: /gsdl/stable/runtime-src/src/recpt/win32.mak
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/win32.mak	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/win32.mak	(revision 20131)
@@ -0,0 +1,262 @@
+###########################################################################
+#
+# win32 makefile -- src/recpt
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ..\..\..
+COMMON_DIR = $(GSDL_DIR)\common-src
+RUNTIME_DIR = $(GSDL_DIR)\runtime-src
+
+INDEXERS_DIR = $(COMMON_DIR)\indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)\packages
+PACKAGES_DIR = $(RUNTIME_DIR)\packages
+COLSERVR_DIR = $(RUNTIME_DIR)\src\colservr
+PROTOCOL_DIR = $(RUNTIME_DIR)\src\protocol
+Z3950_DIR    = $(RUNTIME_DIR)\src\z3950
+
+
+GSDL_VC4 = 0
+LOCAL_LIBRARY = 0
+USE_Z3950 = 0
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+ENABLE_ACCENTFOLD = 1
+USE_SQLITE = 1
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+!IF $(DLL)
+CXXFLAGS = $(CXXFLAGS) -MD
+!ELSE
+!IF ($(DLLDEBUG))
+CXXFLAGS = $(CXXFLAGS) -MDd
+!ENDIF
+!ENDIF
+
+!IF $(ENABLE_ACCENTFOLD)
+ACCENTFOLD_LIBS = "$(INDEXERS_DIR)\packages\unac\libunac.lib" "$(INDEXERS_DIR)\packages\windows\iconv\iconv\lib\iconv.lib"
+!ELSE
+ACCENTFOLD_LIBS = 
+!ENDIF
+
+!IF $(USE_SQLITE)
+SQLITE_LIBS = "$(COMMON_PACKAGES_DIR)\sqlite\lib\sqlite3.lib"
+!ELSE
+SQLITE_LIBS = 
+!ENDIF
+
+!IF $(USE_Z3950)
+Z3950_DEFS = -DUSE_Z3950
+Z3950_INCLUDES = -I$(Z3950_DIR)
+Z3950_LIBS = $(Z3950_DIR)\gsdlz3950.lib $(PACKAGES_DIR)\yaz\yaz-2.1.4\lib\yaz.lib
+!ELSE
+Z3950_DEFS = 
+Z3950_INCLUDES = 
+Z3950_LIBS = 
+!ENDIF
+
+
+AR = lib
+CC = cl
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H -DPARADOCNUM -D_LITTLE_ENDIAN -DSHORT_SUFFIX -D_CRT_SECURE_NO_DEPRECATE \
+        -DGSDL_NOCACHE $(Z3950_DEFS)
+INCLUDES = -I. -I"$(GSDL_DIR)" -I"$(COMMON_DIR)\src\lib" -I"$(COLSERVR_DIR)" -I"$(PROTOCOL_DIR)" \
+	-I"$(INDEXERS_DIR)\mg" -I"$(INDEXERS_DIR)\mg\lib" -I"$(INDEXERS_DIR)\mgpp\text" \
+	-I"$(COMMON_PACKAGES_DIR)\windows\crypt\crypt" -I"$(COMMON_PACKAGES_DIR)\windows\expat\expat" \
+	-I"$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3" -I"$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3\windows" \
+	$(Z3950_INCLUDES)
+LDFLAGS = 
+LIBS = "$(COMMON_PACKAGES_DIR)\windows\crypt\crypt\crypt.lib" "$(COMMON_PACKAGES_DIR)\windows\expat\expat\libexpat.lib" \
+        "$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3\gdbm.lib" $(ACCENTFOLD_LIBS) $(SQLITE_LIBS) $(Z3950_LIBS)
+
+!IF $(GSDL_VC4)
+DEFS = $(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I"$(COMMON_PACKAGES_DIR)\windows\stlport\stlport"
+!ENDIF
+!IF $(LOCAL_LIBRARY)
+DEFS = $(DEFS) -DGSDL_LOCAL_LIBRARY
+!ENDIF
+
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) -nologo -Fe"$@" $(LDFLAGS)
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $< 
+
+
+SOURCES = \
+	action.cpp \
+	argdb.cpp \
+	authenaction.cpp \
+	browseaction.cpp \
+	browseactiontools.cpp \
+	browserclass.cpp \
+	browsetoolsclass.cpp \
+	cgiargs.cpp \
+	cgiutils.cpp \
+	cgiwrapper.cpp \
+	collectoraction.cpp \
+	configaction.cpp \
+        converter.cpp \
+	datelistbrowserclass.cpp \
+	depositoraction.cpp \
+	documentaction.cpp \
+	dynamicclassifieraction.cpp \
+	extlinkaction.cpp \
+	formattools.cpp \
+	gtiaction.cpp \
+	highlighttext.cpp \
+	historydb.cpp \
+	hlistbrowserclass.cpp \
+	htmlbrowserclass.cpp \
+	htmlutils.cpp \
+	invbrowserclass.cpp \
+	librarymain.cpp \
+	maincfg.cpp \
+	pageaction.cpp \
+	pagedbrowserclass.cpp \
+	phindaction.cpp \
+	phindbrowserclass.cpp \
+	pingaction.cpp \
+	queryaction.cpp \
+	querytools.cpp \
+	receptionist.cpp \
+	statusaction.cpp \
+	summarise.cpp \
+	tipaction.cpp \
+	userdb.cpp \
+	usersaction.cpp \
+	vlistbrowserclass.cpp \
+	wizardaction.cpp
+
+OBJECTS = \
+	action.obj \
+	argdb.obj \
+	authenaction.obj \
+	browseaction.obj \
+	browseactiontools.obj \
+	browserclass.obj \
+	browsetoolsclass.obj \
+	cgiargs.obj \
+	cgiutils.obj \
+	cgiwrapper.obj \
+	collectoraction.obj \
+	configaction.obj \
+        converter.obj \
+	datelistbrowserclass.obj \
+	depositoraction.obj \
+	documentaction.obj \
+	dynamicclassifieraction.obj \
+	extlinkaction.obj \
+	formattools.obj \
+	gtiaction.obj \
+	highlighttext.obj \
+	historydb.obj \
+	hlistbrowserclass.obj \
+	htmlbrowserclass.obj \
+	htmlutils.obj \
+	invbrowserclass.obj \
+	librarymain.obj \
+	maincfg.obj \
+	pageaction.obj \
+	pagedbrowserclass.obj \
+	phindaction.obj \
+	phindbrowserclass.obj \
+	pingaction.obj \
+	queryaction.obj \
+	querytools.obj \
+	receptionist.obj \
+	statusaction.obj \
+	summarise.obj \
+	tipaction.obj \
+	userdb.obj \
+	usersaction.obj \
+	vlistbrowserclass.obj \
+	wizardaction.obj
+
+LIBRARY = gsdlrecpt.lib
+
+GSDL_LIBS = \
+	"$(PROTOCOL_DIR)\gsdlprotocol.lib" \
+	"$(COLSERVR_DIR)\gsdlcolservr.lib" \
+	"$(INDEXERS_DIR)\mg\src\text\libmgtext.lib" \
+	"$(INDEXERS_DIR)\mg\lib\libmglib.lib" \
+	"$(INDEXERS_DIR)\mgpp\text\libmgpptext.lib" \
+	"$(INDEXERS_DIR)\mgpp\lib\libmgpplib.lib" \
+	"$(COMMON_DIR)\src\lib\gsdllib.lib"
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS) \
+	$(GSDL_LIBS)
+
+EXECUTABLE = library.cgi
+
+
+# Default target: make gsdlrecpt.lib if LOCAL_LIBRARY is set, otherwise both gsdlrecpt.lib and library.exe
+!IF $(LOCAL_LIBRARY)
+all: $(LIBRARY)
+!ELSE
+all: $(LIBRARY) $(EXECUTABLE)
+!ENDIF
+
+gsdlrecpt.lib: $(OBJECTS) 
+	if EXIST $(LIBRARY) del $(LIBRARY)
+	$(AR) -nologo /out:$(LIBRARY) $(OBJECTS)
+
+library.cgi: $(EXECUTABLE_OBJECTS)
+	$(LINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+!IF $(LOCAL_LIBRARY)
+install:
+!ELSE
+install: $(EXECUTABLE)
+	copy $(EXECUTABLE) "$(GSDL_DIR)\cgi-bin"
+!ENDIF
+
+clean:
+	del *.obj
+	del $(LIBRARY)
+	del $(EXECUTABLE)
+
+
+# Always recompile configaction and statusaction in case GSDL_LOCAL_LIBRARY has changed
+statusaction.obj: FORCE
+configaction.obj: FORCE
+
+FORCE:
Index: /gsdl/stable/runtime-src/src/recpt/wizardaction.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/wizardaction.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/wizardaction.cpp	(revision 20131)
@@ -0,0 +1,727 @@
+/**********************************************************************
+ *
+ * wizardaction.cpp -- 
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+
+// note that the wizardaction relies on having direct access to a
+// collections configuration file. this breaks the separation between
+// receptionist and collection server and so is not suitable (at least
+// in its current form) for use when collection servers are separate 
+// from the receptionist (e.g. when using the CORBA protocol).
+
+// following line required to get fstream.filedesc() on darwin (Mac OS X)
+#define _STREAM_COMPAT  1
+// required for utsname on solaris???
+#define _XOPEN_SOURCE 1
+// This was added for Solaris, but it makes things worse on Solaris for me...
+// #define _XOPEN_SOURCE_EXTENDED 1
+
+#include "wizardaction.h"
+#include "OIDtools.h"
+#include "fileutil.h"
+#include "cfgread.h"
+#include "gsdltools.h"
+#include "gsdltimes.h"
+#include "argdb.h"
+#include "cgiutils.h"
+#include <stdio.h>
+#include <fcntl.h>
+
+#if !defined (__WIN32__)
+#include <sys/utsname.h>
+#include <unistd.h>
+#endif
+
+wizardaction::wizardaction () {
+
+  recpt = NULL;
+  disabled = true;
+
+  macro_prefix = "";
+}
+
+wizardaction::~wizardaction () {
+}
+
+void wizardaction::configure (const text_t &key, const text_tarray &cfgline) {
+  
+  const text_t& action_name = get_action_name();
+
+  if ((key == action_name) && (cfgline.size() == 1) && 
+      (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
+    disabled = false;
+  } else {
+    // call the parent class to deal with the things which
+    // are not dealt with here
+    action::configure (key, cfgline);
+  }
+}
+
+
+bool wizardaction::init (ostream & /*logout*/) {
+
+  return set_gsdl_env_vars(gsdlhome);
+}
+
+
+void wizardaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
+					response_t &response,text_t &response_data, 
+					ostream &/*logout*/) {
+  response = content;
+  response_data = "text/html";
+}
+
+
+bool wizardaction::check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+				     recptprotolistclass * /*protos*/, ostream &logout) {
+  
+  text_t current_page = args["p"];
+
+  if (current_page != "intro" && 
+      current_page != "bildframe1" && current_page != "new" && current_page != "select") {
+    // update arguments that were saved to the harddrive
+    text_tmap saved_args;
+    
+    // update the argdb database with any arguments that were set
+    // by previous page as denoted by prefix (eg. di1 or bc1)
+
+    cgiargsclass::const_iterator args_here = args.begin();
+    cgiargsclass::const_iterator args_end = args.end();
+
+    while (args_here != args_end) {
+      text_t args_name = (*args_here).first;
+      
+      int prefix_len = macro_prefix.size();
+      
+      text_t args_prefix = substr(args_name.begin(),args_name.begin()+prefix_len);
+      
+      if (args_prefix == macro_prefix) {
+	saved_args[args_name] = args[args_name];
+      }	
+      ++args_here;
+    }
+      
+    text_t argfile = filename_cat(gsdlhome, "tmp", args[macro_prefix+"tmp"], "argdb.gdb");
+    argdb *args_on_disk = new argdb(argfile);
+    if (!args_on_disk->update_args(saved_args)) {
+      // error
+      logout << "wizardaction: argdb::update_args failed (" << argfile << ")\n";
+    }
+    
+    // update args from argdb
+    saved_args.erase(saved_args.begin(), saved_args.end());
+    if (!args_on_disk->get_args(saved_args)) {
+      // error
+      logout << "wizardaction: argdb::get_args failed (" << argfile << ")\n";
+    }
+    delete args_on_disk;
+    
+    text_tmap::iterator sa_here = saved_args.begin();
+    text_tmap::iterator sa_end = saved_args.end();
+    while (sa_here != sa_end) {
+      if (!(*sa_here).second.empty()) {
+	args[(*sa_here).first] = (*sa_here).second;
+      }
+      ++sa_here;
+    }  bool first = true;
+
+  }
+
+  return true;
+}
+
+// tests if collection is write protected (currently just checks if
+// collect.cfg file is writable
+bool wizardaction::collection_protected (const text_t &collection) {
+  text_t cfgfile = filename_cat(collecthome, collection, "etc", "collect.cfg");
+  if (file_writable(cfgfile)) return false;
+  return true;
+}
+
+// set the _statusline_ macro
+void wizardaction::set_statusline (displayclass &disp, cgiargsclass &args, ostream & /*logout*/) {
+
+  // the build command creates .bld.download, .bld.import, and .bld.build files (in that
+  // order) and deletes them (also in that order) when each stage is complete. the .bld
+  // file is the concatenation of all these files.
+  text_t bld_file = filename_cat (gsdlhome, "tmp", args[macro_prefix+"tmp"], args[macro_prefix+"dirname"] + ".bld");
+  text_t statusline;
+
+  if (file_exists (bld_file + ".download")) {
+    statusline = "_collector:textdownloadingfiles_<br>\n";
+    statusline += dm_safe(file_tail(bld_file + ".download", 1, 0));
+  } else if (file_exists (bld_file + ".import")) {
+    statusline = "_collector:textimportingcollection_<br>\n";
+    statusline += dm_safe(file_tail(bld_file + ".import", 1, 0));
+  } else if (file_exists (bld_file + ".build")) {
+    statusline = "_collector:textbuildingcollection_<br>\n";
+    statusline += dm_safe(file_tail(bld_file + ".build", 1, 0));
+  } else {
+    statusline += "_collector:textcreatingcollection_<br>\n";
+    statusline += dm_safe(file_tail(bld_file, 1, 0));
+  }
+
+  disp.setmacro ("statusline", "collector", statusline);
+  disp.setmacro ("statusline", "depositor", statusline); 
+}
+
+
+// if sw = 0 replace all carriage returns in intext with the string "\n"
+// else replace all occurances of "\n" with a carriage return
+text_t wizardaction::carriage_replace (const text_t &intext, int sw) {
+   
+  text_t outtext;
+  text_t::const_iterator here = intext.begin();
+  text_t::const_iterator end = intext.end();
+  while (here != end) {
+    if (sw == 0) {
+      if (*here == '\n') {
+	if ((here+1) != end && *(here+1) == '\r') ++here;
+	outtext += "\\n";
+      } else if (*here == '\r') {
+	if ((here+1) != end && *(here+1) == '\n') ++here;
+	outtext += "\\n";
+      } else {
+	outtext.push_back (*here);
+      }
+    } else if (*here == '\\' && (here+1) != end && *(here+1) == 'n') {
+      outtext.push_back ('\n');
+      ++here;
+    } else {
+      outtext.push_back (*here);
+    }
+    ++here;
+  }
+  return outtext;
+}
+
+
+// create a short directory name from fullname
+text_t wizardaction::get_directory_name (const text_t &fullname) {
+
+  text_t shortname;
+  if (fullname.empty()) {
+    shortname = "coll";
+
+  } else {
+    
+    // first make all lowercase and remove any dodgy characters
+    // (i.e. anything not [a-z]
+    text_t::const_iterator here = fullname.begin();
+    text_t::const_iterator end = fullname.end();
+    while (here != end) {
+      if ((*here >= 'A' && *here <= 'Z') || (*here >= 'a' && *here <= 'z') ||
+	  (*here == ' ')) {
+	if (*here >= 'A' && *here <= 'Z') shortname.push_back (*here+32);
+	else if (*here == ' ') {
+	  while ((*(here+1)) == ' ') ++here;
+	  shortname.push_back (*here);
+	} else shortname.push_back (*here);
+      }
+      ++here;
+    }
+
+    text_tarray words;
+    splitchar (shortname.begin(), shortname.end(), ' ', words);
+    int num_words = words.size();
+
+    if (num_words == 0) {
+      shortname = "coll";
+
+    } else {
+
+      shortname.clear();
+      int use_words = (num_words <= 6) ? num_words : 6;
+      unsigned int substr_len = 6 / use_words;
+      
+      for (int i = 0; i < use_words; ++i) {
+	if (words[i].size() < substr_len) shortname += words[i];
+	else shortname += substr (words[i].begin(), words[i].begin()+substr_len);
+      }
+    }
+  }
+
+  // check to see if shortname is unique
+  text_t fulldirname = filename_cat (collecthome, shortname);
+  if (directory_exists (fulldirname)) {
+    int version = 0;
+    text_t newname;
+    do {
+      ++version;
+      newname = shortname;
+      newname.push_back ('v');
+      newname.appendint (version);
+      fulldirname = filename_cat (collecthome, newname);
+    } while (directory_exists (fulldirname));
+
+    shortname = newname;
+  }
+  
+  return shortname;
+}
+
+// assigns a temporary directory name for this collector session
+// and creates temporary directory
+// returns false if it couldn't create the directory
+bool wizardaction::assign_tmpname (cgiargsclass &args, ostream &logout) {
+
+  int i = 0;
+  text_t tmpname = "tbuild";
+  while (directory_exists (filename_cat (gsdlhome, "tmp", tmpname + text_t(i)))) {
+    ++i;
+  }
+  tmpname.appendint (i);
+
+  text_t fulltmpdir = filename_cat (gsdlhome, "tmp", tmpname);
+  if (!mk_dir (fulltmpdir)) {
+    outconvertclass text_t2ascii;
+    logout << text_t2ascii << "wizardaction::assign_tmpname unable to create directory ("
+	   << fulltmpdir << ")\n";
+    return false;
+  }
+
+  args[macro_prefix + "tmp"] = tmpname;
+  return true;
+}
+
+// set the _fullnamemenu_ macro (and _warnindex_ and _selectedindex_ if
+// we're on the "srce" page)
+void wizardaction::set_fullnamemenu (displayclass &disp, cgiargsclass &args, 
+					recptprotolistclass *protos, ostream &logout) {
+
+  if (recpt == NULL) {
+    logout << "ERROR (wizardaction::set_fullnamemenu): This action does not contain\n"
+	   << "       information about any receptionists. The method set_receptionist was\n"
+	   << "       probably not called from the module which instantiated this action.\n";
+    return;
+  }
+
+  text_t &current_page = args["p"];
+  text_t currentname = args[macro_prefix+"dirname"];
+  if (current_page == "srce") currentname = args[macro_prefix + "clonecol"];
+
+  text_tarray dirnames;
+  text_tarray fullnames;
+  vector<bool> write_protected;
+  text_tarray  build_type;
+
+  bool is_selected = false;
+  int selected_index = 0;
+  int index = 0;
+
+  recptprotolistclass::iterator rprotolist_here = protos->begin();
+  recptprotolistclass::iterator rprotolist_end = protos->end();
+  while (rprotolist_here != rprotolist_end) {
+    if ((*rprotolist_here).p != NULL) {
+
+      // don't include z39.50 collections
+      comerror_t err = noError;
+      if ((*rprotolist_here).p->get_protocol_name (err) == "z3950proto") {
+	++rprotolist_here;
+	continue;
+      }
+
+      text_tarray collist;
+      (*rprotolist_here).p->get_collection_list (collist, err, logout);
+      if (err == noError) {
+	text_tarray::iterator collist_here = collist.begin();
+	text_tarray::iterator collist_end = collist.end();
+	while (collist_here != collist_end) {
+	  ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
+	  if (cinfo != NULL) {
+	    text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]);
+	    if (collectionname.empty()) {
+	      collectionname = *collist_here;
+	    }
+	    dirnames.push_back(*collist_here);
+	    fullnames.push_back(collectionname);
+	    // check to see if the collection is writable
+	    if (collection_protected (*collist_here)) write_protected.push_back(true);
+	    else write_protected.push_back(false);
+
+	    // remember build type for collection (mg, mgpp, lucene, ...)
+	    // used to determine cgi arg 'ct' later on and minus option to 'build'
+	    build_type.push_back(cinfo->buildType);
+
+	    if (*collist_here == currentname) {
+	      is_selected = true;
+	      selected_index = index; 	    
+	    }
+	    ++index;
+	  }
+	  ++collist_here;
+	}
+      }
+    }
+    ++rprotolist_here;
+  }
+
+  bool first = true;
+
+  text_t warnindex;
+  text_t fullnamemenu = "<select name=\""+macro_prefix+"dirname\" onChange=\"menuchange();\">\n";
+  text_t buildtype_jsarray = "var buildtype = new Array(";
+
+  fullnamemenu += "<option value=\"\">_textselectoption_</option>\n";
+  buildtype_jsarray += "\"\" ";
+
+  for (int i = 0; i < index; ++i) {
+    // don't want write protected collections in list on "change existing
+    // collection" page
+    if (write_protected[i] && current_page == "existing") continue;
+    fullnamemenu += "<option value=\"" + dirnames[i] + "\"";
+    if (is_selected && i == selected_index) {
+      fullnamemenu += " selected";
+      ++selected_index;
+      is_selected = false;
+    }
+    fullnamemenu.push_back ('>');
+    fullnamemenu += fullnames[i] + " ("+dirnames[i]+")";
+    fullnamemenu.push_back ('\n');
+
+    buildtype_jsarray += ", \"" + build_type[i] + "\"";
+    
+    first = false;
+  }
+  fullnamemenu += "</select>\n";
+
+  buildtype_jsarray += ");";
+
+  text_t action_name = get_action_name();
+  disp.setmacro ("fullnamemenu", action_name, fullnamemenu);
+  disp.setmacro ("buildtypearray", action_name, buildtype_jsarray);
+}
+
+// checks to see if any of the plugins in pluginset occur in 
+// collections configuration file
+bool wizardaction::uses_weird_plugin (const text_t &collection) {
+
+  text_tset pluginset;
+  pluginset.insert ("HBPlug");
+
+  text_t cfgfile_content;
+  text_t cfgfile_name = filename_cat (collecthome, collection, "etc", "collect.cfg");
+  text_t pluginstr, pluginname;
+
+  if (read_file (cfgfile_name, cfgfile_content)) {
+    text_t::const_iterator here = cfgfile_content.begin();
+    text_t::const_iterator end = cfgfile_content.end();
+    while (here != end) {
+      here = findchar (here, end, 'p');
+      if (here == end) break;
+      if ((here+6 < end) && (substr (here, here+6) == "plugin")) {
+	getdelimitstr (here+6, end, '\n', pluginstr);
+	text_t::const_iterator hp = pluginstr.begin();
+	text_t::const_iterator ep = pluginstr.end();
+	bool found = false;
+	// remove any leading whitespace, trailing options etc.
+	while (hp != ep) {
+	  if (*hp == '\t' || *hp == ' ' || *hp == '\n') {
+	    if (found) break;
+	  } else {
+	    pluginname.push_back (*hp);
+	    found = true;
+	  }
+	  ++hp;
+	}
+	text_tset::const_iterator it = pluginset.find (pluginname);
+	if (it != pluginset.end()) return true; // found matching plugin
+	pluginname.clear();
+      }
+      ++here;
+    }
+  }
+  return false;
+}
+
+void wizardaction::gsdl_build (cgiargsclass &args, ostream &logout) {
+
+  outconvertclass text_t2ascii;
+
+  //check to see if the tbuild directory exists
+  text_t tmpdir = filename_cat (gsdlhome, "tmp", args[macro_prefix+"tmp"]);
+  if (!directory_exists (tmpdir)) {
+    message = "tmpfail";
+    return;
+  }
+  
+  //check to see if collection name specified
+  text_t &collection = args[macro_prefix+"dirname"];
+  if (collection.empty()) {
+    message = "nocollection";
+    return;
+  }
+
+  // check for a .build file - if it exists then we've already built
+  // the collection (or are in the process of building it)
+  text_t buildfile = filename_cat (tmpdir, ".build");
+  if (file_exists (buildfile)) {
+    return;
+  } else {
+    // create the .build file (this file is just a place holder to let any future
+    // pages know that we've already been here)
+    char *buildfilec = buildfile.getcstr();
+    ofstream bfile_out (buildfilec);
+    delete []buildfilec;
+    if (bfile_out) {
+      bfile_out << "collection building\n";
+      bfile_out.close();
+    } else {
+      message = "tmpfail";
+      return;
+    }
+  }
+
+  //FLAG!
+  const recptconf &rcinfo = recpt->get_configinfo ();
+
+  // create the event header file if LogEvents, EmailEvents or
+  // EmailUserEvents options are turned on.
+  bool logevents = 
+    (rcinfo.LogEvents == CollectorEvents || rcinfo.LogEvents == AllEvents || 
+     rcinfo.EmailEvents == CollectorEvents || rcinfo.EmailEvents == AllEvents ||
+     rcinfo.EmailUserEvents);
+  text_t ehead_file = filename_cat (tmpdir, "ehead.txt");
+  if (logevents) {
+    if (!create_event_header_file (ehead_file, args, logout)) {
+      logevents = false;
+    }
+  }
+    
+  text_t collectdir = get_collectdir (args);
+
+  // set up build options
+  //text_t options = "-make_writable -remove_import -out \""; 
+  text_t options = "-make_writable  -out \""; 
+  options += filename_cat (tmpdir, collection + ".bld");
+  options += "\" -collectdir \"" + collectdir + "\" -statsfile \"";
+  options += filename_cat(collectdir, collection, "etc", "import.log") + "\"";
+
+  if (args[macro_prefix+"esrce"] == 1) {
+    // we're adding data to an existing collection
+    options += " -save_archives -append -manifest";
+  }
+
+  text_tarray inputvalues, inputtypes;
+  splitchar (args[macro_prefix+"input"].begin(), args[macro_prefix+"input"].end(), ',', inputvalues);
+  splitchar (args[macro_prefix+"inputtype"].begin(), args[macro_prefix+"inputtype"].end(), ',', inputtypes);
+  int numvalues = inputvalues.size();
+  int numtypes = inputtypes.size();
+  for (int i = 0; i < numvalues; ++i) {
+    if (!inputvalues[i].empty()) {
+      text_t type = "file://"; // default
+      if (i < numtypes) type = inputtypes[i];
+      options += " -download \"" + 
+	remove_trailing_slashes(type + format_url(decode_commas(inputvalues[i]))) + "\"";
+    }
+  }
+
+  if (logevents) {
+    if (rcinfo.LogEvents == CollectorEvents || rcinfo.LogEvents == AllEvents) 
+      options += " -log_events";
+    if (rcinfo.EmailEvents == CollectorEvents || rcinfo.EmailEvents == AllEvents) {
+      options += " -mail_server " + rcinfo.MailServer;
+      options += " -email_events " + rcinfo.maintainer;
+      if (rcinfo.EmailUserEvents) options += "," + args[macro_prefix+"contactemail"];
+    } else if (rcinfo.EmailUserEvents) {
+      options += " -mail_server " + rcinfo.MailServer;
+      options += " -email_events " + args[macro_prefix+"contactemail"];
+    }
+    options += " -event_header " + ehead_file;
+  }
+
+  text_t indextype = args[macro_prefix+"buildtype"];
+  if(indextype == "") {
+    indextype = "mg";
+  }
+  options += " -indextype \"" + indextype + "\"";
+
+  text_t optionfile = filename_cat (tmpdir, "build.opt");
+  char *optionfilec = optionfile.getcstr();
+  ofstream ofile_out (optionfilec);
+  delete []optionfilec;
+  if (!ofile_out) {
+    message = "tmpfail";
+    return;
+  }
+  ofile_out << text_t2ascii << options << "\n";
+  ofile_out.close();
+
+  // if we're altering an existing collection we need to kill off
+  // the existing collection server - we do this for the local library
+  // (and any other persistent version of the library) as the existing
+  // database file can't be deleted while the collection server holds it open
+  if ((args[macro_prefix+"econf"] == 1) || (args[macro_prefix+"esrce"] == 1)) {
+    remove_colservr (collection, logout);
+  }    
+
+  // set up the build command - build.bat has some issues with quoting
+  // on win2k when gsdlhome contains spaces so we'll avoid using 
+  // "perl -S" here in favor of calling the "build" perl script explicitly
+  text_t build_cmd = "perl \"" + filename_cat (gsdlhome, "bin", "script", "build");
+  build_cmd += "\" -optionfile \"" + optionfile + "\" " + collection;
+
+  // run build command in background (i.e. asynchronously) 
+  gsdl_system (build_cmd, false, logout);
+
+}
+
+void wizardaction::gsdl_cancel_build (cgiargsclass &args, ostream &logout) {
+  // I really wanted to do what this perl script does from within the library
+  // c++ code. I ran into some problems though (like how do you write a portable
+  // "rm -r" in c++?). One day I'll spend some time sorting it out ... maybe.
+  text_t cancel_cmd = "perl -S cancel_build.pl -collectdir \"";
+  cancel_cmd += filename_cat (gsdlhome, "tmp", args[macro_prefix+"tmp"]) + "\" ";
+  cancel_cmd += args[macro_prefix+"dirname"];
+  // To be on the safe side we'll make this a synchronous call
+  // so that all tidying up is done before the user has a chance
+  // to do anything else (like start rebuilding their collection).
+  // This means that for a big collection where there's lots of 
+  // stuff to delete etc. it might take a while before the "build
+  // cancelled" page appears.
+  gsdl_system (cancel_cmd, true, logout);
+}
+
+text_t wizardaction::get_collectdir (cgiargsclass &args)
+{
+  if ((args[macro_prefix+"econf"] == 1) || (args[macro_prefix+"esrce"] == 1)) {
+    // we're adding to a collection in place
+    return collecthome;
+  }
+  else {
+    return filename_cat (gsdlhome, "tmp", args[macro_prefix+"tmp"]);
+  }
+}
+
+// create and initialize a new collection server and
+// add it to the null protocol.
+void wizardaction::create_colserver (const text_t &collection, ostream &logout) {
+
+  recptprotolistclass *protos = recpt->get_recptprotolist_ptr();
+  recptprotolistclass::iterator rprotolist_here = protos->begin();
+  recptprotolistclass::iterator rprotolist_end = protos->end();
+  while (rprotolist_here != rprotolist_end) {
+    comerror_t err = noError;
+    if ((*rprotolist_here).p != NULL) {
+      if ((*rprotolist_here).p->get_protocol_name (err) == "nullproto") {
+	// create collection server and add it to nullproto
+	(*rprotolist_here).p->add_collection (collection, recpt, gsdlhome, collecthome, dbhome);
+	// make sure gsdlhome is configured
+	text_tarray tmp;
+	tmp.push_back (gsdlhome);
+	(*rprotolist_here).p->configure ("gsdlhome", tmp, err);
+	// re-initialize the null protocol
+	if (!(*rprotolist_here).p->init (err, logout)) {
+	  logout << "wizardaction::create_colserver: nullproto init failed\n";
+	}
+	return;
+      }
+    }
+    ++rprotolist_here;
+  }
+
+  logout << "wizardaction::create_colserver: no valid nullproto found\n";
+}
+
+// delete a collection server from the null protocol
+void wizardaction::remove_colservr (const text_t &collection, ostream &logout) {
+
+  recpt->uncache_collection (collection);
+
+  recptprotolistclass *protos = recpt->get_recptprotolist_ptr();
+  recptprotolistclass::iterator rprotolist_here = protos->begin();
+  recptprotolistclass::iterator rprotolist_end = protos->end();
+  while (rprotolist_here != rprotolist_end) {
+    comerror_t err = noError;
+    if ((*rprotolist_here).p != NULL) {
+      if ((*rprotolist_here).p->get_protocol_name (err) == "nullproto") {
+	(*rprotolist_here).p->remove_collection (collection, logout);
+	return;
+      }
+    }
+    ++rprotolist_here;
+  }
+
+  logout << "wizardaction::create_colserver: no valid nullproto found\n";
+}
+
+bool wizardaction::create_event_header_file (const text_t &filename, cgiargsclass &args, 
+						ostream &logout) {
+
+  outconvertclass text_t2ascii;
+  char *filenamec = filename.getcstr();
+  ofstream eheadfile (filenamec);
+  delete []filenamec;
+
+  if (eheadfile) {
+    eheadfile << text_t2ascii << get_event_header (args);
+    eheadfile.close();
+    return true;
+  }
+   
+  logout << text_t2ascii << "wizardaction::create_event_header ERROR: Couldn't create "
+	 << "Event Header file " << filename << ". Event logging disabled\n";
+  return false;
+}
+
+text_t wizardaction::get_event_header (cgiargsclass &args) {
+  text_t header = "Greenstone Username: " + args["un"] + "\n";
+  header += "Collection: " + args[macro_prefix+"dirname"] + "\n";
+  header += "Collection Creator: " + args[macro_prefix+"contactemail"] + "\n";
+  header += "GSDLHOME: " + gsdlhome + "\n";
+  header += "Build Location: " + get_collectdir(args) + "\n";
+
+  return header;
+}
+
+
+// format_url simply strips "http://", "ftp://", or "file://" off the
+// beginning of url if they're there
+text_t wizardaction::format_url (const text_t &url) {
+  text_t::const_iterator begin = url.begin();
+  text_t::const_iterator end = url.end();
+
+  if (url.size() >= 7) {
+    text_t prefix = substr(begin, begin+7);
+    if (prefix == "http://" || prefix == "file://") {
+      return substr(begin+7, end);
+    }
+  }
+  if (url.size() >= 6) {
+    if (substr(begin, begin+6) == "ftp://") {
+      return substr(begin+6, end);
+    }
+  }
+  return url;
+}
+
+text_t wizardaction::remove_trailing_slashes (text_t str) {
+
+  while (*(str.end()-1) == '\\') {
+    str.pop_back();
+  }
+  return str;
+}
+
Index: /gsdl/stable/runtime-src/src/recpt/wizardaction.h
===================================================================
--- /gsdl/stable/runtime-src/src/recpt/wizardaction.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/recpt/wizardaction.h	(revision 20131)
@@ -0,0 +1,108 @@
+/**********************************************************************
+ *
+ * wizardaction.h -- 
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "gsdl_modules_cfg.h"
+
+#ifndef WIZARDACTION_H
+#define WIZARDACTION_H
+
+#include "action.h"
+#include "receptionist.h"
+
+class wizardaction : public action {
+  
+
+public:
+  wizardaction ();
+  virtual ~wizardaction ();
+
+  void configure (const text_t &key, const text_tarray &cfgline);
+
+  bool init (ostream &logout);
+
+  void set_receptionist (receptionist *therecpt) {recpt=therecpt;}
+
+  text_t get_action_name () {return "wizard";}
+
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response,text_t &response_data, 
+			 ostream &logout);
+
+  bool check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args, 
+		      recptprotolistclass * protos, ostream &logout);
+
+
+protected:
+  bool disabled;
+  receptionist *recpt;
+
+  text_t macro_prefix;
+
+  text_t message;
+  char failcode;
+
+  virtual text_t get_button (cgiargsclass &args, const text_t &thispage, 
+			     const text_t &color, 
+			     const text_t &type, bool enabled)=0;
+			    
+
+  text_t carriage_replace (const text_t &intext, int sw);
+
+  text_t get_directory_name (const text_t &fullname);
+
+  bool collection_protected (const text_t &collection);
+
+  bool assign_tmpname (cgiargsclass &args, ostream &logout);
+
+
+  void set_statusline (displayclass &disp, cgiargsclass &args, ostream &logout);
+  void gsdl_build (cgiargsclass &args, ostream &logout);
+
+  void gsdl_cancel_build (cgiargsclass &args, ostream &logout);
+
+  text_t get_collectdir (cgiargsclass &args);
+
+  void create_colserver (const text_t &collection, ostream &logout);
+
+  void remove_colservr (const text_t &collection, ostream &logout);
+
+  bool create_event_header_file (const text_t &filename, cgiargsclass &args, 
+				 ostream &logout);
+
+  text_t get_event_header (cgiargsclass &args);
+
+  text_t format_url (const text_t &url);
+
+  text_t remove_trailing_slashes (text_t str);
+
+  void set_fullnamemenu (displayclass &disp, cgiargsclass &args,
+			 recptprotolistclass *protos, ostream &logout);
+
+  bool uses_weird_plugin (const text_t &collection);
+
+};
+
+#endif //!WIZARDACTION_H
+
Index: /gsdl/stable/runtime-src/src/w32apachectl/starthttpd.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32apachectl/starthttpd.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32apachectl/starthttpd.cpp	(revision 20131)
@@ -0,0 +1,113 @@
+
+/******************************************************************************
+ Code derived from the following at http://www.microsoft.com/msj/0698/win320698.aspx
+ Module name: MainApp.cpp
+ Written by:  Jeffrey Richter
+ Purpose:     Runs a set of processes with the ability to kill them all.
+******************************************************************************/
+ 
+ //#define UNICODE
+ //#define _UNICODE
+ 
+#define STRICT
+#include <Windows.h>
+#include <process.h>
+#include <tchar.h>
+#include <stdio.h>
+ 
+/******************************************************************************
+  This program launches the httpd.exe process and sets it up with an event
+  to respond to when it is required to terminate.
+*******************************************************************************/
+ 
+///////////////////////////////////////////////////////////////////////////////
+
+// Event used to forcibly kill the spawned Process Group
+// Used to terminate the httpd.exe (upon receiving this event, a Ctrl-C is sent)
+HANDLE g_heventTerminateProcessGroup = NULL;
+ 
+///////////////////////////////////////////////////////////////////////////////
+ 
+unsigned int _stdcall StartProcessGroup(void* pv) 
+{
+  // Construct the path of our spawn-helper application
+  TCHAR szCmdLine[MAX_PATH];
+  GetModuleFileName(NULL, szCmdLine, MAX_PATH);
+  *(_tcsrchr(szCmdLine, __TEXT('\\')) + 1) = 0; // truncate EXE filename
+  _stprintf(_tcschr(szCmdLine, 0), __TEXT("StartHttpdChild.exe %d"), 
+	    g_heventTerminateProcessGroup);
+  
+  // Our command-line arguments indicate the process that we want to run
+  for (int x = 2; x < __argc; x++) {
+    _tcscat(szCmdLine, __TEXT(" ")); 
+    _tcscat(szCmdLine, __targv[x]); 
+  }
+  
+  STARTUPINFO si = { sizeof(si) };
+  si.dwFlags     = STARTF_USESHOWWINDOW;
+  si.wShowWindow = SW_HIDE;  // Processes in the Process Group are hidden
+  
+  PROCESS_INFORMATION pi;
+  
+  // Spawn the process (make sure it inherits our event handle)
+  BOOL f = CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 
+			 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
+  
+  DWORD dw = 0;  // Return value
+  
+  if (f) {
+    // The process was sucessfully spawned, wait for it to terminate
+    CloseHandle(pi.hThread);
+    WaitForSingleObject(pi.hProcess, INFINITE);
+    GetExitCodeProcess(pi.hProcess, &dw);  // Its exit code is ours
+    CloseHandle(pi.hProcess);
+  } else {
+    // Couldn't spawn the process group application
+  }
+  return(dw);
+}
+ 
+////////////////////////////////////////////////////////////////////////////////
+
+// If using the following non-GUI method definition, need to launch
+// the StartHttpd.exe program with: cmd /c StartHttpd.exe
+// int _tmain( int argc, TCHAR *argv[] ) 
+
+
+extern "C" int WINAPI _tWinMain(HINSTANCE hinst, HINSTANCE hinstExePrev, 
+                                 LPTSTR pszCmdLine, int nShowCmd) 
+{
+  if(__argc != 3) {
+    MessageBox(NULL, "Usage: starthttpd.exe <event-name> <httpd.exe program path>",
+	       TEXT("Error"), MB_OK);
+    return(1);
+  }
+  
+  DWORD dwThreadId;
+  
+  // Create an inheritable event handle to use as our IPC mechanism
+  // to terminate the processes in the process group
+  // NOTE: Keep this handle forthe entire lifetime of this application
+  
+  g_heventTerminateProcessGroup = CreateEvent(NULL, TRUE, FALSE, __argv[1]);
+  SetHandleInformation(g_heventTerminateProcessGroup, 
+		       HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
+  
+  // Spawn the processes in the process group.
+  ResetEvent(g_heventTerminateProcessGroup);   // Do this before each spawn
+  HANDLE hThread = (HANDLE) _beginthreadex(NULL, 0, StartProcessGroup, 
+					   NULL, 0, (UINT*) &dwThreadId);
+  
+  WaitForSingleObject(hThread, INFINITE);
+  
+  // The spawned processes have terminated, clean up
+  CloseHandle(hThread);
+  
+  // When this application is terminating, close the event
+  CloseHandle(g_heventTerminateProcessGroup);
+  
+  return(0);
+}
+ 
+//////////////////////////////// End of File //////////////////////////////////
+
Index: /gsdl/stable/runtime-src/src/w32apachectl/starthttpdchild.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32apachectl/starthttpdchild.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32apachectl/starthttpdchild.cpp	(revision 20131)
@@ -0,0 +1,76 @@
+/******************************************************************************
+ Code derived from the following at http://www.microsoft.com/msj/0698/win320698.aspx
+ Module name: SmallApp.cpp
+ Written by:  Jeffrey Richter
+ Purpose:     Spawn helper that kills everything in its Process Group.
+******************************************************************************/
+ 
+//#define UNICODE
+//#define _UNICODE
+ 
+#define STRICT
+#include <Windows.h>
+#include <process.h>
+#include <tchar.h>
+#include <stdio.h>
+ 
+///////////////////////////////////////////////////////////////////////////////
+ 
+/******************************************************************************
+    Sends the Ctrl-C to all processes spawned in this process' own console.
+    (Sends Ctrl-C to the two connected httpd.exe instances launched together)
+*******************************************************************************/
+
+extern "C" int  _tmain(int argc, TCHAR* argv[]) 
+{
+  
+  // Make sure that we've been passed the right number of arguments
+  if (argc < 3) {
+       _tprintf(
+		__TEXT("Usage: %s (InheritableEventHandle) (CommandLineToSpawn)\n"), 
+		argv[0]);
+       return(0);
+  }
+  
+  // Construct the full command line
+  TCHAR szCmdLine[MAX_PATH] = { 0 };
+  for (int x = 2; x < argc; x++) {
+    _tcscat(szCmdLine, argv[x]); 
+    _tcscat(szCmdLine, __TEXT(" ")); 
+  }
+  
+  STARTUPINFO         si = { sizeof(si) };
+  PROCESS_INFORMATION pi = { 0 };
+  DWORD dwExitCode = 0;
+  
+  HANDLE h[2];
+  h[0] = (HANDLE) _ttoi(argv[1]);  // The inherited event handle
+  
+  // Spawn the other processes as part of this Process Group
+  BOOL f = CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 
+			 0, NULL, NULL, &si, &pi);
+  
+  if (f) {
+    CloseHandle(pi.hThread);
+    h[1] = pi.hProcess;
+    
+    // Wait for the spawned-process to die or for the event
+    // indicating that the processes should be forcibly killed.
+    switch (WaitForMultipleObjects(2, h, FALSE, INFINITE)) {
+    case WAIT_OBJECT_0 + 0:  // Force termination
+      GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
+      WaitForSingleObject(pi.hProcess, INFINITE);
+      break;
+      
+    case WAIT_OBJECT_0 + 1:  // App terminated normally
+      // Make its exit code our exit code
+      GetExitCodeProcess(pi.hProcess, &dwExitCode);
+      break;
+    }
+    CloseHandle(pi.hProcess);
+  }
+  CloseHandle(h[0]);   // Close the inherited event handle
+  return(dwExitCode);
+}
+ 
+//////////////////////////////// End of File //////////////////////////////////
Index: /gsdl/stable/runtime-src/src/w32apachectl/stophttpd.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32apachectl/stophttpd.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32apachectl/stophttpd.cpp	(revision 20131)
@@ -0,0 +1,83 @@
+#define STRICT
+#include <Windows.h>
+#include <process.h>
+#include <tchar.h>
+#include <stdio.h>
+
+#ifdef PLATFORM_SDK
+#include <strsafe.h>
+#endif
+
+// Helper function for displaying error codes
+void ErrorExit(char* lpszFunction) 
+{ 
+  // Retrieve the system error message for the last-error code
+  
+  char* lpMsgBuf = NULL;
+  char* lpDisplayBuf = NULL;
+  DWORD dw = GetLastError(); 
+  
+  FormatMessage(
+		FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+		FORMAT_MESSAGE_FROM_SYSTEM |
+		FORMAT_MESSAGE_IGNORE_INSERTS,
+		NULL,
+		dw,
+		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+		(char*) &lpMsgBuf,
+		0, NULL );
+  
+  // Display the error message and exit the process
+  //lpDisplayBuf = new char[(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)];
+  lpDisplayBuf = (char*)LocalAlloc(LMEM_ZEROINIT, 
+				   (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 
+  
+#ifdef PLATFORM_SDK
+  StringCchPrintf((LPTSTR)lpDisplayBuf, 
+		  LocalSize(lpDisplayBuf) / sizeof(TCHAR),
+		  TEXT("%s Failed with error %d: %s"), 
+		  lpszFunction, dw, lpMsgBuf); 
+#else
+  _stprintf(lpDisplayBuf, __TEXT("%s\nFailed with error %d: %s"), lpszFunction, dw, lpMsgBuf);
+#endif
+  
+  MessageBox(NULL, lpDisplayBuf, TEXT("Error"), MB_OK); 
+  
+  fprintf(stderr,"Cleaning up\n");    
+
+  LocalFree(lpMsgBuf);
+  LocalFree(lpDisplayBuf);
+  ExitProcess(dw); 
+}
+
+// If using the following non-GUI method definition, need to launch
+// the StartHttpd.exe program with: cmd /c
+// (which would make it a detached process - with its own console)
+// int _tmain( int argc, TCHAR *argv[] )
+ 
+extern "C" int WINAPI _tWinMain(HINSTANCE hinst, HINSTANCE hinstExePrev, 
+                                 LPTSTR pszCmdLine, int nShowCmd) 
+{
+  if(__argc != 2) {
+    MessageBox(NULL, __TEXT("Usage: stophttpd.exe <event-name>"),
+	       TEXT("Error"), MB_OK);
+    return(1);
+  }
+  
+  // open (get) the existing named event object that the StartHttpd.exe is listening for.
+  // The event object's name is what is given in the command line
+  HANDLE g_heventTerminateProcessGroup = OpenEvent(EVENT_ALL_ACCESS,TRUE, __argv[1]);
+  
+  // send the termination event
+  if (SetEvent(g_heventTerminateProcessGroup)==0) {
+    // do error popup ExitError
+    
+    ErrorExit(TEXT("Failed to send termination event: httpd.exe needs to be terminated manually."));
+    fprintf(stderr, "Failed to send termination event: httpd.exe needs to be terminated manually.\n");
+  }
+  
+  //Sleep(3000);
+  
+  return(0);
+}
+
Index: /gsdl/stable/runtime-src/src/w32apachectl/win32.mak
===================================================================
--- /gsdl/stable/runtime-src/src/w32apachectl/win32.mak	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32apachectl/win32.mak	(revision 20131)
@@ -0,0 +1,116 @@
+###########################################################################
+#
+# win32 makefile -- getgw
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+#
+# To compile all these up on their own, just need a .bat file containing:
+#
+# CL /MT starthttpdchild.cpp kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
+#
+# CL /MT starthttpd.cpp kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
+#
+# CL /MT stophttpd.cpp kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
+#
+# See:
+# http://c.ittoolbox.com/groups/technical-functional/cpp-l/error-c2065-_beginthread-undeclared-identifier-how-to-solve-this-239497
+# http://www.gamedev.net/community/forums/topic.asp?topic_id=304779
+# http://www.codeguru.com/forum/showthread.php?t=179647
+# http://support.microsoft.com/kb/138400
+###########################################################################
+
+GSDLHOME = ..\..\..
+
+
+GSDL_VC4 = 0
+LOCAL_LIBRARY = 0
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+CXXFLAGS = $(CXXFLAGS) -MT 
+
+CC = cl
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H -DPARADOCNUM -D_LITTLE_ENDIAN -DSHORT_SUFFIX -D_CRT_SECURE_NO_DEPRECATE
+WINLIBS = kernel32.lib user32.lib gdi32.lib winspool.lib \
+          comdlg32.lib advapi32.lib shell32.lib ole32.lib \
+          oleaut32.lib uuid.lib
+
+!IF $(GSDL_VC4)
+DEFS = $(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I"$(COMMON_PACKAGES_DIR)\windows\stlport\stlport"
+!ENDIF
+
+!IF $(LOCAL_LIBRARY)
+DEFS = $(DEFS) -DGSDL_LOCAL_LIBRARY
+!ENDIF
+
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) -nologo $(LDFLAGS) -Fe"$@"
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $< 
+
+OBJECTS = starthttpdchild.obj starthttpd.obj stophttpd.obj
+EXEC    = starthttpdchild.exe starthttpd.exe stophttpd.exe
+
+all: $(EXEC)
+
+install: $(EXEC)
+	if NOT EXIST "$(GSDLHOME)\bin\windows" mkdir "$(GSDLHOME)\bin\windows"
+	for %%f in ($(EXEC)) do (copy %%f "$(GSDLHOME)\bin\windows")
+
+clean:
+	del *.obj
+	del $(EXEC)
+
+distclean:
+	del *.obj
+	del $(EXEC)
+	del "$(GSDLHOME)\bin\windows\starthttpdchild.exe"	
+	del "$(GSDLHOME)\bin\windows\starthttpd.exe"
+	del "$(GSDLHOME)\bin\windows\stophttpd.exe"
+
+starthttpdchild.exe: starthttpdchild.obj
+	$(LINK) starthttpdchild.obj $(WINLIBS)
+
+starthttpd.exe: starthttpd.obj
+	$(LINK) starthttpd.obj $(WINLIBS) 
+
+stophttpd.exe: stophttpd.obj
+	$(LINK)  stophttpd.obj $(WINLIBS)
Index: /gsdl/stable/runtime-src/src/w32server/cgiwrapper.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/cgiwrapper.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/cgiwrapper.cpp	(revision 20131)
@@ -0,0 +1,1023 @@
+/**********************************************************************
+ *
+ * cgiwrapper.cpp -- windows local library cgiwrapper
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "text_t.h"
+
+#include <windows.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <direct.h>
+#include "cgiwrapper.h"
+#include "netio.h"
+#include "wincgiutils.h"
+#include "settings.h"
+#include "fileutil.h"
+#include "parse.h"
+
+#include "gsdlconf.h"
+#include "maincfg.h"
+
+#if defined (GSDL_USE_OBJECTSPACE)
+#include <ospace\std\iostream>
+#include <ospace\std\fstream>
+#elif defined (GSDL_USE_IOS_H)
+#include <iostream.h>
+#include <fstream.h>
+#else
+#include <iostream>
+#include <fstream>
+#endif
+
+#include "receptionist.h"
+#include "nullproto.h"
+
+// actions
+#include "statusaction.h"
+#include "pageaction.h"
+#include "pingaction.h"
+#include "queryaction.h"
+#include "documentaction.h"
+#include "dynamicclassifieraction.h"
+#include "tipaction.h"
+#include "authenaction.h"
+#include "usersaction.h"
+#include "userdb.h"
+#include "extlinkaction.h"
+#include "collectoraction.h"
+#include "phindaction.h"
+#include "configaction.h"
+
+// browsers
+#include "vlistbrowserclass.h"
+#include "hlistbrowserclass.h"
+#include "datelistbrowserclass.h"
+#include "invbrowserclass.h"
+#include "pagedbrowserclass.h"
+#include "htmlbrowserclass.h"
+#include "phindbrowserclass.h"
+
+// the number of times the library has been accessed
+int libaccessnum = 0;
+
+// used to output the text from receptionist
+class textstreambuf : public streambuf
+{
+public:
+  textstreambuf ();
+  int sync ();
+  int overflow (int ch);
+  int underflow () {return EOF;}
+  
+  void tsbreset() {RInfo=NULL;casostr=NULL;}
+  void setrequestinfo (RequestInfoT *theRInfo) {RInfo=theRInfo;}
+  void cascadeoutput (ostream *thecasostr) {casostr=thecasostr;}
+  
+private:
+  RequestInfoT *RInfo;
+  ostream *casostr;
+#if !defined (GSDL_USE_IOS_H)
+  char buffer[256];
+#endif
+};
+
+textstreambuf::textstreambuf() {
+  tsbreset();
+#if !defined (GSDL_USE_IOS_H)
+  setp (&buffer[0], &buffer[255]);
+#else
+  if (base() == ebuf()) allocate();
+  setp (base(), ebuf());
+#endif
+};
+
+int textstreambuf::sync () {
+  if ((RInfo != NULL) && 
+      (Send_String_N(pbase(), pptr()-pbase(), RInfo) < 0)) {
+    RInfo = NULL;
+  }
+  
+  if (casostr != NULL) {
+    char *thepbase=pbase();
+    for (int i=0;i<(pptr()-pbase());++i) (*casostr).put(thepbase[i]);
+  }
+  
+  setp (pbase(), epptr());
+  
+  return 0;
+}
+
+int textstreambuf::overflow (int ch) {
+  if (sync () == EOF) return EOF;
+  if (ch != EOF) sputc (ch);
+  return 0;
+}
+
+
+// used to output all the log and error messages
+// from receptionist
+class logstreambuf : public streambuf
+{
+public:
+  logstreambuf ();
+  int sync ();
+  int overflow (int ch);
+  int underflow () {return EOF;}
+
+#if !defined (GSDL_USE_IOS_H)
+private:
+  char buffer[256];
+#endif
+};
+
+logstreambuf::logstreambuf () {
+#if !defined (GSDL_USE_IOS_H)
+  setp (&buffer[0], &buffer[255]);
+#else
+  if (base() == ebuf()) allocate();
+  setp (base(), ebuf());
+#endif
+}
+
+int logstreambuf::sync () {
+  if (gsdl_keep_log || gsdl_show_console) {
+    log_message ("LOCAL LIB MESSAGE: ");
+		log_message_N (pbase(), pptr()-pbase());
+  }
+
+  setp (pbase(), epptr());
+  return 0;
+}
+
+int logstreambuf::overflow (int ch) {
+  if (sync () == EOF) return EOF;
+  if (ch != EOF) sputc (ch);
+  return 0;
+}
+
+static void page_errormaincfg (const text_t &gsdlhome, const text_t &collection) {
+
+  if (collection.empty()) {
+    text_t message = "Error\n\n"
+      "The main.cfg configuration file could not be found. This file\n"
+      "should contain configuration information relating to the\n"
+      "setup of the interface. As this program is not being run\n"
+      "in collection specific mode the file should reside at\n" +
+      gsdlhome + "\\etc\\main.cfg.\n";
+
+    MessageBox(NULL, message.getcstr(),
+	       "Greenstone Digital Library Software"
+	       ,MB_OK|MB_SYSTEMMODAL);
+  } else {
+    text_t message = "Neither the collect.cfg or main.cfg configuration files could\n"
+      "be found. This file should contain configuration information\n"
+      "relating to the setup of the interface. As this cgi script is\n"
+      "being run in collection specific mode the file should reside\n"
+      "at either " + gsdlhome + "\\collect\\" + collection + "\\etc\\collect.cfg,\n" +
+      gsdlhome + "\\etc\\collect.cfg or " + gsdlhome + "\\etc\\main.cfg.\n";
+
+    MessageBox(NULL, message.getcstr(),
+	       "Greenstone Digital Library Software"
+	       ,MB_OK|MB_SYSTEMMODAL);
+  }
+}
+
+static void page_errorinit (const text_t &/*gsdlhome*/) {
+
+  text_t message = "Error\n\n"
+    "An error occurred during the initialisation of the Greenstone Digital\n"
+    "Library software. It is likely that the software has not been setup\n"
+    "correctly.\n";
+
+  MessageBox(NULL, message.getcstr(),
+	     "Greenstone Digital Library Software"
+	     ,MB_OK|MB_SYSTEMMODAL);
+}
+
+static void page_errorparseargs (const text_t &/*gsdlhome*/) {
+
+  text_t message = "Error\n\n"
+    "An error occurred during the parsing of the cgi arguments.\n";
+
+  MessageBox(NULL, message.getcstr(),
+	     "Greenstone Digital Library Software"
+	     ,MB_OK|MB_SYSTEMMODAL);
+}
+
+static void page_errorcgipage (const text_t &/*gsdlhome*/) {
+
+  text_t message = "Error\n\n"
+    "An error occurred during the construction of the cgi page.\n";
+
+  MessageBox(NULL, message.getcstr(),
+	     "Greenstone Digital Library Software"
+	     ,MB_OK|MB_SYSTEMMODAL);
+}
+
+// returns 0 if the directories can't be found
+// and the user wants to quit (it returns 1
+// if everything is ok)
+int checkdir (const text_t &thedir) {
+  UINT curerrormode;
+  int drive = _getdrive();
+  char cwd[1024];
+  char rootpath[4];
+  UINT drivetype;
+  char *cstrthedir = thedir.getcstr();
+  int returnvalue = 1;
+  
+  // make sure no rude error messages are presented to the user
+  curerrormode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+  
+  // get the drive name
+  if (thedir.size() >= 2 && thedir[1] == ':') {
+    if (thedir[0] >= 'a' && thedir[0] <= 'z') {
+      drive = thedir[0] - 'a' + 1;
+      
+    } else if (thedir[0] >= 'A' && thedir[0] <= 'Z') {
+      drive = thedir[0] - 'A' + 1;
+    }
+  }
+  
+  // find the drive type
+  rootpath[0] = drive + 'A' - 1;
+  rootpath[1] = ':';
+  rootpath[2] = '\\';
+  rootpath[3] = '\0';
+  drivetype = GetDriveType (rootpath);
+  
+  // try and set this directory to be the current working
+  // directory
+  _getcwd(cwd, 1024);
+  while (_chdir(cstrthedir) != 0) {
+    // failed
+    if (drivetype == DRIVE_CDROM) {
+      // message to insert the cdrom
+      if (MessageBox (NULL, 
+		      "Please insert the Greenstone Digital Library\n"
+		      "CD-ROM into the CD-ROM drive and press 'OK'.\n\n"
+		      "If you don't have the CD-ROM press 'Cancel' to exit\n"
+		      "this program.", "Greenstone Digital Library Software", 
+		      MB_OKCANCEL | MB_TASKMODAL) == IDCANCEL) {
+	
+	returnvalue = 0;
+	break;
+      }
+      
+    } else {
+      // message saying that the system was unable
+      // to find a certain directory
+      text_t message = "Failed to find the directory:\n\n" + thedir;
+      message += "\n\n"
+	"This directory is needed for the successful operation\n"
+	"of this software. Make sure it hasn't been deleted or\n"
+	"moved, and restart the software. You may need to\n"
+	"reinstall this software to correct the problem.";
+      char *cstrmessage = message.getcstr();
+      
+      MessageBox (NULL, cstrmessage, "Greenstone Digital Library Software",
+		  MB_OK | MB_TASKMODAL);
+      
+      delete []cstrmessage;
+      
+      returnvalue = 0;
+      break;
+    }
+  }
+  
+  // revert to the previous error and cwd states
+  _chdir(cwd);
+  SetErrorMode(curerrormode);
+  
+  // free the allocated C string
+  delete []cstrthedir;
+  
+  return returnvalue;
+}
+
+
+// c-string version of checkdir for the outside
+// world
+int cstrcheckdir (char *cstrthedir) {
+  return checkdir (cstrthedir);
+}
+
+
+receptionist recpt;
+nullproto nproto;
+collectset *cservers = NULL;
+
+textstreambuf textstream;
+logstreambuf logstream;
+DWORD lastlibaccesstime;
+DWORD baseavailvirtual;
+text_t current_gsdlhome;
+text_t current_collecthome;
+colinfo_tmap translated_collectinfo;
+  
+statusaction *astatusaction = NULL;
+pageaction *apageaction = NULL;
+pingaction *apingaction = NULL;
+tipaction *atipaction = NULL;
+queryaction *aqueryaction = NULL;
+documentaction *adocumentaction = NULL;
+dynamicclassifieraction *adynamicclassifieraction = NULL;
+usersaction *ausersaction = NULL;
+extlinkaction *anextlinkaction = NULL;
+collectoraction *acollectoraction = NULL;
+authenaction *aauthenaction = NULL;
+phindaction *aphindaction = NULL;
+configaction *aconfigaction = NULL;
+vlistbrowserclass *avlistbrowserclass = NULL;
+hlistbrowserclass *ahlistbrowserclass = NULL;
+datelistbrowserclass *adatelistbrowserclass = NULL;
+invbrowserclass *ainvbrowserclass = NULL;
+pagedbrowserclass *apagedbrowserclass = NULL;
+htmlbrowserclass *ahtmlbrowserclass = NULL;
+phindbrowserclass *aphindbrowserclass = NULL;
+text_t userdbfile = NULL;
+userdbclass *udb = NULL;
+text_t keydbfile = NULL;
+keydbclass *kdb = NULL;
+
+// returns 1 if successful, 0 if unsuccessful (note that as well as being
+// called when the server first starts up this function is called when the
+// "restart library" button is pressed)
+int gsdl_init (bool atStartup) {
+
+  if (atStartup) {
+#if defined (GSDL_USE_IOS_H)
+    cerr = &logstream;
+    cout = &textstream;
+#else
+    cerr.rdbuf(&logstream);
+    cout.rdbuf(&textstream);
+#endif
+  }
+
+  // collection should be set to "" unless in collection specific mode -
+  // changing this to the name of the collection should be all that's
+  // required to create a collection specific receptionist
+  text_t collection = "";
+  text_tset dbhomes;
+  text_tset clhomes; // collecthome companion for dbhome
+  text_tset collections;
+
+  if (atStartup) {
+    // note the current time
+    lastlibaccesstime = GetTickCount();
+    
+    // before we do the init we should make sure
+    // that we can find the relevant directories
+    if (!checkdir (gsdl_gsdlhome + "\\")) return 0;
+    if (!checkdir (gsdl_collecthome + "\\")) return 0;
+    if (!checkdir (gsdl_gsdlhome + "\\macros\\")) return 0;
+  }    
+
+  // deleting cservers clears all the collection servers 
+  if (cservers != NULL) delete cservers;
+
+  cservers = new collectset();
+
+  // get all collections from each gsdlhome (this relies 
+  // on there not being more than one collection with the same 
+  // name)
+  if (!collection.empty()) {
+    // collection specific receptionist - one collection, one gsdlhome
+    collections.insert (collection);
+    dbhomes.insert (gsdl_dbhome);
+    clhomes.insert (gsdl_collecthome);
+    collectioninfo_t tmp;
+    tmp.gsdl_gsdlhome = gsdl_gsdlhome;
+    tmp.gsdl_collecthome = gsdl_collecthome;
+    tmp.gsdl_dbhome = gsdl_dbhome;
+    translated_collectinfo[collection] = tmp;
+
+  } else {
+
+    text_tset::const_iterator colhere;
+    text_tset::const_iterator colend;
+    text_tset these_collections;
+
+    // first volume gsdlhome's
+    colinfo_tmap::const_iterator this_info = gsdl_collectinfo.begin();
+    colinfo_tmap::const_iterator end_info = gsdl_collectinfo.end();
+    while (this_info != end_info) {
+      if (dbhomes.find ((*this_info).second.gsdl_dbhome) == dbhomes.end()) {
+	these_collections.erase (these_collections.begin(), these_collections.end());
+	read_dir ((*this_info).second.gsdl_collecthome, these_collections);
+	colhere = these_collections.begin();
+	colend = these_collections.end();
+	while (colhere != colend) {
+	  if ((collections.find (*colhere)) == collections.end()) {
+	    // make sure the build.cfg file is at gsdlhome (as it's possible that
+	    // the collection appears at this gsdlhome only because it's gdbm
+	    // file is installed here -- it's real gdbm will therefore be 
+	    // somewhere else).
+	    text_t build_cfg = filename_cat ((*this_info).second.gsdl_collecthome,
+					     *colhere, "index", "build.cfg");
+	    if (file_exists (build_cfg)) {
+	      collections.insert (*colhere);
+
+	      // since gsdl_collectinfo keys will be stuff like collection#1
+	      // for a multiple volume collection we want to translate it
+	      // so that the keys are the actual collection names
+	      translated_collectinfo[*colhere] = (*this_info).second;
+	    }
+	  }
+	  ++colhere;
+	}
+	dbhomes.insert ((*this_info).second.gsdl_dbhome);
+	clhomes.insert ((*this_info).second.gsdl_collecthome);
+      }
+      ++this_info;
+    }
+  
+    // then if necessary the main dbhome (this should only happen if the 
+    // gsdl.ini is a little screwed up and no volume dbhomes occurred)
+    if (dbhomes.find (gsdl_dbhome) == dbhomes.end()) {
+      these_collections.erase (these_collections.begin(), these_collections.end());
+      read_dir (filename_cat (gsdl_dbhome, "collect"), these_collections);
+      colhere = these_collections.begin();
+      colend = these_collections.end();
+      while (colhere != colend) {
+	
+	//text_t build_cfg = filename_cat (gsdl_dbhome,"collect",
+	//			 *colhere, "index", "build.cfg");
+      //if (file_exists (build_cfg)) {
+	  collections.insert (*colhere);
+	  
+	  collectioninfo_t tmp;
+	  tmp.gsdl_gsdlhome = gsdl_gsdlhome;
+	  tmp.gsdl_collecthome = gsdl_collecthome;
+	  tmp.gsdl_dbhome = gsdl_dbhome;
+	  translated_collectinfo[*colhere] = tmp;
+	  //}
+	++colhere;
+      }
+      dbhomes.insert (gsdl_dbhome);
+      clhomes.insert (gsdl_collecthome);
+    }
+  }
+
+  text_tset::const_iterator thiscol = collections.begin();
+  text_tset::const_iterator endcol = collections.end();
+
+  while (thiscol != endcol) {
+    
+    // ignore the modelcol
+    if (*thiscol == "modelcol") {
+      ++thiscol;
+      continue;
+    }
+    
+    // create collection server and add to null protocol
+    text_t this_gsdlhome = gsdl_gsdlhome;
+    text_t this_collecthome = gsdl_collecthome;
+    text_t this_dbhome = gsdl_dbhome;
+    colinfo_tmap::const_iterator it = translated_collectinfo.find (*thiscol);
+    assert (it != translated_collectinfo.end());
+    this_gsdlhome = (*it).second.gsdl_gsdlhome;
+    this_collecthome = (*it).second.gsdl_collecthome;
+    this_dbhome = (*it).second.gsdl_dbhome;
+
+    cservers->add_collection (*thiscol, this_gsdlhome, this_collecthome);
+    // in case it is a collection group
+    cservers->add_collection_group(*thiscol, this_gsdlhome, this_collecthome);
+    
+    ++thiscol;
+  }
+ 
+  // set up the null protocol
+  nproto.set_collectset(cservers);
+  
+  if ((ausersaction == NULL) && (aauthenaction == NULL)){
+    userdbfile = filename_cat(gsdl_gsdlhome, "etc", "users.gdb");
+    udb = new userdbclass(userdbfile);
+    keydbfile = filename_cat(gsdl_gsdlhome, "etc", "key.gdb");
+    kdb = new keydbclass(keydbfile);
+  }
+  // add the protocol to the receptionist
+  if (atStartup) recpt.add_protocol (&nproto);
+  
+  // the list of actions.
+  if (astatusaction == NULL) {
+    astatusaction = new statusaction();
+    astatusaction->set_receptionist (&recpt);
+    recpt.add_action (astatusaction);
+  }
+  
+  if (apageaction == NULL) {
+    apageaction = new pageaction();
+    apageaction->set_receptionist (&recpt);
+    recpt.add_action (apageaction);
+  }
+  
+  if (apingaction == NULL) {
+    apingaction = new pingaction();
+    recpt.add_action (apingaction);
+  }
+  
+  if (atipaction == NULL) {
+    atipaction = new tipaction();
+    recpt.add_action (atipaction);
+  }
+  
+  if (aqueryaction == NULL) {
+    aqueryaction = new queryaction();
+    aqueryaction->set_receptionist (&recpt);
+    recpt.add_action (aqueryaction);
+  }
+  
+  if (adocumentaction == NULL) {
+    adocumentaction = new documentaction();
+    adocumentaction->set_receptionist (&recpt);
+    recpt.add_action (adocumentaction);
+  }
+  
+  if (ausersaction == NULL) {
+    ausersaction = new usersaction();
+    ausersaction->set_userdb(udb);
+    recpt.add_action (ausersaction);
+  }
+
+  if (anextlinkaction == NULL) {
+    anextlinkaction = new extlinkaction();
+    recpt.add_action (anextlinkaction);
+  }
+
+  if (acollectoraction == NULL) {
+    acollectoraction = new collectoraction();
+    acollectoraction->set_receptionist (&recpt);
+    recpt.add_action (acollectoraction);
+  }
+  
+  if (aauthenaction == NULL) {
+    aauthenaction = new authenaction();
+    aauthenaction->set_userdb(udb);
+    aauthenaction->set_keydb(kdb);
+    aauthenaction->set_receptionist(&recpt);
+    recpt.add_action (aauthenaction);
+  }
+
+  if (aphindaction == NULL) {
+    aphindaction = new phindaction();
+    recpt.add_action (aphindaction);
+  }
+  
+  if (aconfigaction == NULL) {
+    aconfigaction = new configaction();
+    aconfigaction->set_receptionist(&recpt);
+    recpt.add_action (aconfigaction);
+  }
+  
+  if (adynamicclassifieraction == NULL) {
+    adynamicclassifieraction = new dynamicclassifieraction();
+    adynamicclassifieraction->set_receptionist(&recpt);
+    recpt.add_action (adynamicclassifieraction);
+  }
+
+
+  // list of browsers
+  if (avlistbrowserclass == NULL) {
+    avlistbrowserclass = new vlistbrowserclass();
+    recpt.add_browser (avlistbrowserclass);
+    recpt.setdefaultbrowser ("VList");
+  }
+
+  if (ahlistbrowserclass == NULL) {
+    ahlistbrowserclass = new hlistbrowserclass();
+    recpt.add_browser (ahlistbrowserclass);
+  }
+
+  if (adatelistbrowserclass == NULL) {
+    adatelistbrowserclass = new datelistbrowserclass();
+    recpt.add_browser (adatelistbrowserclass);
+  }
+
+  if (ainvbrowserclass == NULL) {
+    ainvbrowserclass = new invbrowserclass();
+    recpt.add_browser (ainvbrowserclass);
+  }
+
+  if (apagedbrowserclass == NULL) {
+    apagedbrowserclass = new pagedbrowserclass();
+    recpt.add_browser (apagedbrowserclass);
+  }
+
+  if (ahtmlbrowserclass == NULL) {
+    ahtmlbrowserclass = new htmlbrowserclass();
+    recpt.add_browser (ahtmlbrowserclass);
+  }
+
+  if (aphindbrowserclass == NULL) {
+    aphindbrowserclass = new phindbrowserclass();;
+    recpt.add_browser (aphindbrowserclass);
+  }
+  
+  // set defaults
+  recpt.configure ("gsdlhome", gsdl_gsdlhome);
+  recpt.configure ("collecthome", gsdl_collecthome);
+  recpt.configure ("gdbmhome", gsdl_dbhome);
+  recpt.configure ("collection", collection);
+
+  int maxrequests = 1;
+
+  // configure collections (and receptionist) with collectinfo stuff
+  // different from the default
+  colinfo_tmap::const_iterator this_info = translated_collectinfo.begin();
+  colinfo_tmap::const_iterator end_info = translated_collectinfo.end();
+
+  while (this_info != end_info) {
+    text_tarray tmpconf;
+    tmpconf.push_back ((*this_info).first);
+    tmpconf.push_back ((*this_info).second.gsdl_gsdlhome);
+    tmpconf.push_back ((*this_info).second.gsdl_collecthome);
+    tmpconf.push_back ((*this_info).second.gsdl_dbhome);
+    recpt.configure ("collectinfo", tmpconf);
+    ++this_info;
+  }
+
+  // read in config files of each dbhome (in no particular order)
+  // those read in last will override those read earlier
+  // collections being used together in this way should be 
+  // careful not to have main.cfg files that might 
+  // interfere with each other.
+  text_tset::const_iterator thome = dbhomes.begin();
+  text_tset::const_iterator ehome = dbhomes.end();
+  text_tset::const_iterator tchome = clhomes.begin(); // collecthome companion for dbhome
+
+  while (thome != ehome) {
+    if (!main_cfg_read (recpt, *thome, *tchome, collection)) {
+      // couldn't find the main configuration file
+      page_errormaincfg (*thome, collection);
+      return 0;
+    }
+    ++thome;
+    ++tchome;
+  }
+
+  // w32server relies on gwcgi being set to "gsdl", and httpweb to web
+  recpt.configure ("gwcgi", "gsdl");
+  recpt.configure ("httpweb", "web");
+
+  // initialise the library software
+  if (!recpt.init(cerr)) {
+    // an error occurred during the initialisation
+    page_errorinit(gsdl_gsdlhome);
+    return 0;
+  }
+
+  // get memory information
+  MEMORYSTATUS memstatus;
+  memstatus.dwLength = sizeof(MEMORYSTATUS);
+  GlobalMemoryStatus(&memstatus);
+  baseavailvirtual = memstatus.dwAvailVirtual; // save for later comparison
+
+  return 1;
+}
+
+
+static void rememberpref (const text_t &tailstr) {
+  gsdl_enterlib = tailstr;
+}
+
+
+static void send_file_from_disk(text_t filename,
+                                RequestInfoT *RInfo,
+                                RequestFieldsT *RFields) {
+  
+  // select appropriate mime type from file extension
+  text_t ext;
+  text_t::const_iterator end = filename.end();
+  text_t::const_iterator it = filename.begin();
+  text_t::const_iterator lastdot = end;
+  while ((it = findchar(it, end, '.')) != end) {
+    lastdot = it;
+    ++it;
+  }
+  if (lastdot < end) ext = substr(lastdot+1, end);
+
+  text_t mime = "unknown";
+  int len = ext.size();
+  if (len == 2) {
+    if ((ext[0] == 'p' || ext[0] == 'P') &&
+	(ext[1] == 's' || ext[1] == 'S'))
+      mime = "application/postscript";
+  }  else if (len == 3) {
+    if ((ext[0] == 'g' || ext[0] == 'G') &&
+	(ext[1] == 'i' || ext[1] == 'I') &&
+	(ext[2] == 'f' || ext[2] == 'F')) {
+      mime = "image/gif";
+    } else if ((ext[0] == 'j' || ext[0] == 'J') &&
+	       (ext[1] == 'p' || ext[1] == 'P') &&
+	       (ext[2] == 'g' || ext[2] == 'G')) {
+      mime = "image/jpeg";
+    } else if ((ext[0] == 'h' || ext[0] == 'H') &&
+	       (ext[1] == 't' || ext[1] == 'T') &&
+	       (ext[2] == 'm' || ext[2] == 'M')) {
+      mime = "text/html";
+    } else if ((ext[0] == 'p' || ext[0] == 'P') &&
+	       (ext[1] == 'd' || ext[1] == 'D') &&
+	       (ext[2] == 'f' || ext[2] == 'F')) {
+      mime = "application/pdf";
+    } else if ((ext[0] == 'p' || ext[0] == 'P') &&
+	       (ext[1] == 'n' || ext[1] == 'N') &&
+	       (ext[2] == 'g' || ext[2] == 'G')) {
+      mime = "image/png";
+    } else if ((ext[0] == 'd' || ext[0] == 'D') &&
+	       (ext[1] == 'o' || ext[1] == 'O') &&
+	       (ext[2] == 'c' || ext[2] == 'C')) {
+      mime = "application/msword";
+    } else if ((ext[0] == 'r' || ext[0] == 'R') &&
+	       (ext[1] == 't' || ext[1] == 'T') &&
+	       (ext[2] == 'f' || ext[2] == 'F')) {
+      mime = "application/rtf";
+    } else if ((ext[0] == 'x' || ext[0] == 'X') &&
+	       (ext[1] == 'l' || ext[1] == 'L') &&
+	       (ext[2] == 's' || ext[2] == 'S')) {
+      mime = "application/vnd.ms-excel";
+    } else if ((ext[0] == 'p' || ext[0] == 'P') &&
+	       (ext[1] == 'p' || ext[1] == 'P') &&
+	       (ext[2] == 'T' || ext[2] == 'T')) {
+      mime = "application/vnd.ms-powerpoint";
+    } else if ((ext[0] == 'm' || ext[0] == 'M') &&
+	       (ext[1] == 'p' || ext[1] == 'P') &&
+	       (ext[2] == '3')) {
+      mime = "audio/mpeg";
+    }
+  } else if (len == 4) {
+    if ((ext[0] == 'j' || ext[0] == 'J') &&
+	(ext[1] == 'p' || ext[1] == 'P') &&
+	(ext[2] == 'e' || ext[2] == 'E') &&
+	(ext[3] == 'g' || ext[3] == 'G')) {
+      mime = "image/jpeg";
+    } else if ((ext[0] == 'h' || ext[0] == 'H') &&
+	       (ext[1] == 't' || ext[1] == 'T') &&
+	       (ext[2] == 'm' || ext[2] == 'M') &&
+	       (ext[3] == 'l' || ext[3] == 'L')) {
+      mime = "text/html";
+    }
+  }
+	
+  // try to open the file
+  //cerr << "*** filename = " << filename.getcstr() << endl;
+  //cerr << "**** collect_home = " << current_collecthome.getcstr() << endl;
+
+  if (filename.size()>=9) {
+    text_t prefix = substr(filename.begin(),filename.begin()+9);
+    //cerr << "**** prefix = " << prefix.getcstr() << endl;
+
+    text_t tail = substr(filename.begin()+9,filename.end());
+    //cerr << "**** tail = " << tail.getcstr() << endl;
+
+    if (prefix == "/collect/") {
+      filename = filename_cat (current_collecthome, tail);
+    }
+    else {
+      filename = filename_cat (current_gsdlhome, filename);
+    }
+  }
+
+  cerr << "#### filename = " << filename.getcstr() << endl;
+
+  /* Feb 2002 - handle files with spaces in their name. */
+  text_t::iterator space_start;
+  space_start=findword(filename.begin(),filename.end(),"%20");
+  while (space_start != filename.end()) {
+    // we found a space...
+    text_t::iterator after_space=space_start+3;
+    text_t new_filename=substr(filename.begin(), space_start);
+    new_filename += " ";
+    new_filename += substr(after_space,filename.end());
+    filename=new_filename;
+    space_start=findword(filename.begin(),filename.end(),"%20");
+  }
+
+  char *filenamec = filename.getcstr();
+  TranslateEscapeString(filenamec);  // Resolve any %xx values
+  FILE *thefile = fopen(filenamec, "rb");
+  delete []filenamec;
+  if (thefile == NULL) {
+    log_message("file not found\n");
+    send_retrieve_error(404, "File not found",
+			"Could not find the local file requested", RInfo);
+    return;
+  }
+  int nr;
+  char buffer[2048];
+  // send back required information
+  char *mimec = mime.getcstr();
+  if (send_header(mimec, RInfo) >= 0) {
+    if (RFields->MethodStr != "HEAD") {
+      for (;;) {
+        nr = fread(buffer, 1, 2048, thefile);
+        if (nr <= 0) break;
+        if (SendData(RInfo->ClientSocket,
+                     (BYTE *)buffer, nr,
+		     RInfo->ThreadNum) < 0) break;        
+      }
+    }
+  }
+  delete []mimec;
+  fclose(thefile);
+}
+
+static void handle_library_request(const text_t &argstr, RequestInfoT *RInfo,
+				   RequestFieldsT *RequestFields) {
+
+  // parse the cgi arguments and produce the resulting page if there
+  // have been no errors so far
+  cgiargsclass args;
+  fileupload_tmap fileuploads;
+  text_tmap empty; // don't use this (it's for fastcgi on unix)
+  if (!recpt.parse_cgi_args (argstr, fileuploads, args, cerr, empty)) {
+    page_errorparseargs(gsdl_gsdlhome);
+    return;
+  } 
+
+  colinfo_tmap::const_iterator it = translated_collectinfo.find (args["c"]);
+  if (it != translated_collectinfo.end()) {
+    current_gsdlhome = (*it).second.gsdl_gsdlhome;
+    current_collecthome = (*it).second.gsdl_collecthome;
+  } else {
+    current_gsdlhome = gsdl_gsdlhome;
+    current_collecthome = gsdl_collecthome;
+  }
+
+  // produce cgi header
+  response_t response;
+  text_t response_data;
+
+  recpt.get_cgihead_info (args, response, response_data, cerr, empty);
+
+  if (response == location) {
+    // location response
+    response_data = "@" + recpt.expandmacros (response_data, args, cerr);
+    char *response_data_c = response_data.getcstr();
+    send_header(response_data_c, RInfo);
+    delete []response_data_c;
+    return;
+  } else if (response == content) {
+    // content response
+    char *response_data_c = response_data.getcstr();
+    if (send_header(response_data_c, RInfo) < 0) {
+      delete []response_data_c;
+      return;
+    }
+    delete []response_data_c;
+  }
+  else if (response == undecided_location) {
+    // We know this is a relocation request but at the moment we don't know exactly where to
+    // Just output the start of the header and wait until later to output the target location
+    // Used for the "I'm feeling lucky" functionality
+    cout << "HTTP/1.0 302 Relocation\r\n";
+    cout << "Server: GSDL\r\n";
+    cout << "Content-type: text/html \r\n";
+  }
+  else {
+    // unknown response
+    cerr << "Error: get_cgihead_info returned an unknown response type.\n";
+    return;
+  }
+
+  textstream.tsbreset();
+  textstream.setrequestinfo (RInfo);
+  if (!recpt.produce_content (args, cout, cerr)) {
+    page_errorcgipage(gsdl_gsdlhome);
+    return;
+  } 
+  recpt.log_cgi_args (args, cerr, empty);
+
+  cout << flush;
+  cerr << flush;
+  
+  ++libaccessnum;
+}
+
+static void handle_server_request(text_t &tailstr,
+				  RequestInfoT *RequestInfo,
+				  RequestFieldsT *RequestFields) {
+  
+  text_t argstr;
+
+  // do any url adjustments necessary
+  if (tailstr.empty() || tailstr == "/") {
+    tailstr = "/gsdl";
+  }
+
+  text_t::const_iterator begin = tailstr.begin();
+  text_t::const_iterator end = tailstr.end();
+  
+  // test to see if this is a library request or a local
+  // file request
+  if ((tailstr == "/gsdl") ||
+      ((tailstr.size() > 5) && (substr(begin, begin+6) == "/gsdl?"))) {
+
+    // library request
+    
+    // argstr is the bit after the '?'
+    if (tailstr != "/gsdl") {
+      argstr = substr(begin+6, end);
+    }
+
+    // log the difference in access times
+    DWORD thislibaccesstime = GetTickCount();
+    if (gsdl_keep_log || gsdl_show_console) {
+      char logstr[256];
+      sprintf(logstr, "DELTA LIB ACCESS TIME: %i\n", (int)(thislibaccesstime - lastlibaccesstime));
+      log_message (logstr);
+    }
+    lastlibaccesstime = thislibaccesstime;
+    
+    // log this request
+    if (gsdl_keep_log || gsdl_show_console) {
+      text_t logstr = "LOCAL LIB: " + tailstr + "\n";
+      char *logstrc = logstr.getcstr();
+      log_message (logstrc);
+      delete []logstrc;
+    }
+    
+    handle_library_request (argstr, RequestInfo, RequestFields);
+    
+    // remember the preferences
+    // rememberpref (tailstr);
+    
+    // log memory information
+    if (gsdl_keep_log || gsdl_show_console) {
+      MEMORYSTATUS memstatus;
+      memstatus.dwLength = sizeof(MEMORYSTATUS);
+      GlobalMemoryStatus(&memstatus);
+      char logstr[256];
+      sprintf (logstr, "BDELTA AVAIL VIRTUAL: %i K\n", 
+	       (int)((baseavailvirtual - memstatus.dwAvailVirtual)/1024));
+      log_message (logstr);
+    }
+    
+  } else {
+    // local file
+    if (gsdl_keep_log || gsdl_show_console) {
+      text_t logstr = "LOCAL FILE: " + tailstr + "\n";
+      char *logstrc = logstr.getcstr();
+      log_message (logstrc);
+      delete []logstrc;
+    }
+    send_file_from_disk (tailstr, RequestInfo, RequestFields);
+  }
+}
+
+int ExamineURIStr(text_t &URIStr, RequestInfoT *RequestInfo,
+		  RequestFieldsT *RequestFields)
+{
+  text_t protocol, machine, rest;
+  int port;
+
+  if (RequestFields->ContentLength > 0) {
+    // POST data
+    URIStr.push_back('?');
+    for (int i = 0; i < RequestFields->ContentLength; ++i) {
+      URIStr.push_back(RequestFields->Content[i]);
+    }
+  }
+  
+  if (parse_url(URIStr, protocol, machine, &port, rest)!=http_ok) {
+    // Alter local file request to address 'gsdl'
+    if (*(URIStr.begin()) != '/') URIStr = "http://gsdl/" + URIStr;
+    else URIStr = "http://gsdl" + URIStr;
+    parse_url(URIStr, protocol, machine, &port, rest);
+  }
+
+  if (machine == "gsdl") {
+    // a local file request
+    handle_server_request(rest, RequestInfo, RequestFields);
+    
+  } else {
+    send_retrieve_error(404, "File not found",
+			"Could not find the local file requested", RequestInfo);
+  }
+  
+  return 1;
+}
Index: /gsdl/stable/runtime-src/src/w32server/cgiwrapper.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/cgiwrapper.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/cgiwrapper.h	(revision 20131)
@@ -0,0 +1,49 @@
+/**********************************************************************
+ *
+ * cgiwrapper.h -- windows local library cgiwrapper
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef CGIWRAPPER_H
+#define CGIWRAPPER_H
+
+#include "httpreq.h"
+#include "locate.h"
+#include "receptionist.h"
+
+// the number of times the library has been accessed
+extern int libaccessnum;
+
+int ExamineURIStr(text_t &URIStr,RequestInfoT *RequestInfo,
+		  RequestFieldsT *RequestFields);
+
+// reads any configure file that has been set up and
+// sets up the library
+// returns 1 if successful, 0 if unsuccessful
+int gsdl_init (bool atStartup = true);
+
+// returns 0 if the directories cant be found
+// and the user wants to quit (it returns 1
+// if everything is ok)
+int cstrcheckdir (char *cstrthedir);
+
+#endif
Index: /gsdl/stable/runtime-src/src/w32server/conftools.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/conftools.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/conftools.cpp	(revision 20131)
@@ -0,0 +1,55 @@
+/**********************************************************************
+ *
+ * conftools.cpp
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "text_t.h"
+#include "conftools.h"
+
+int write_confline (ofstream &fileout, const text_t &key, const text_t value) {
+  if (key.empty() || value.empty()) return -1;
+  outconvertclass text_t2ascii;
+  fileout << text_t2ascii << key << "=" << value << "\n";
+  return 0;
+}
+
+int get_confline (ifstream &filein, text_t &key, text_t &value) {
+  if (filein.eof()) return -1;
+
+  key.clear();
+  value.clear();
+  char c;
+  filein.get(c);
+
+  int foundeq = 0;
+  while (!filein.eof() && c != '\n') {
+    if (!foundeq && c == '=') {foundeq = 1; filein.get(c);}
+
+    if (foundeq) value.push_back(c);
+    else key.push_back(c);
+    filein.get(c);
+  }
+  if (key.empty()) return -1;
+  return 0;
+} 
+
Index: /gsdl/stable/runtime-src/src/w32server/conftools.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/conftools.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/conftools.h	(revision 20131)
@@ -0,0 +1,40 @@
+/**********************************************************************
+ *
+ * conftools.h
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef CONFTOOLS_H
+#define CONFTOOLS_H
+
+#if defined (GSDL_USE_OBJECTSPACE)
+#include <ospace/std/fstream>
+#elif defined (GSDL_USE_IOS_H)
+#include <fstream.h>
+#else
+#include <fstream>
+#endif
+
+int write_confline (ofstream &fileout, const text_t &key, const text_t value);
+int get_confline (ifstream &filein, text_t &key, text_t &value);
+
+#endif
Index: /gsdl/stable/runtime-src/src/w32server/d_winsock.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/d_winsock.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/d_winsock.cpp	(revision 20131)
@@ -0,0 +1,669 @@
+/**********************************************************************
+ *
+ * d_winsock.cpp
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include <windows.h>
+#include "d_winsock.h"
+
+
+typedef SOCKET (PASCAL FAR *accept_Type)(SOCKET s, struct sockaddr FAR *addr, 
+					 int FAR *addrlen);
+typedef int (PASCAL FAR *bind_Type)(SOCKET s, const struct sockaddr FAR *addr, int namelen);
+typedef int (PASCAL FAR *closesocket_Type)(SOCKET s);
+typedef int (PASCAL FAR *connect_Type)(SOCKET s, const struct sockaddr FAR *name, 
+				       int namelen);
+typedef int (PASCAL FAR *ioctlsocket_Type)(SOCKET s, long cmd, u_long FAR *argp);
+typedef int (PASCAL FAR *getpeername_Type)(SOCKET s, struct sockaddr FAR *name,
+					   int FAR * namelen);
+typedef int (PASCAL FAR *getsockname_Type)(SOCKET s, struct sockaddr FAR *name,
+					   int FAR * namelen);
+typedef int (PASCAL FAR *getsockopt_Type)(SOCKET s, int level, int optname,
+					  char FAR * optval, int FAR *optlen);
+typedef u_long (PASCAL FAR *htonl_Type)(u_long hostlong);
+typedef u_short (PASCAL FAR *htons_Type)(u_short hostshort);
+typedef unsigned long (PASCAL FAR *inet_addr_Type)(const char FAR * cp);
+typedef char FAR * (PASCAL FAR *inet_ntoa_Type)(struct in_addr in);
+typedef int (PASCAL FAR *listen_Type)(SOCKET s, int backlog);
+typedef u_long (PASCAL FAR *ntohl_Type)(u_long netlong);
+typedef u_short (PASCAL FAR *ntohs_Type)(u_short netshort);
+typedef int (PASCAL FAR *recv_Type)(SOCKET s, char FAR * buf, int len, int flags);
+typedef int (PASCAL FAR *recvfrom_Type)(SOCKET s, char FAR * buf, int len, int flags,
+					struct sockaddr FAR *from, int FAR * fromlen);
+typedef int (PASCAL FAR *select_Type)(int nfds, fd_set FAR *readfds, fd_set FAR *writefds,
+				      fd_set FAR *exceptfds, const struct timeval FAR *timeout);
+typedef int (PASCAL FAR *send_Type)(SOCKET s, const char FAR * buf, int len, int flags);
+typedef int (PASCAL FAR *sendto_Type)(SOCKET s, const char FAR * buf, int len, int flags,
+				      const struct sockaddr FAR *to, int tolen);
+typedef int (PASCAL FAR *setsockopt_Type)(SOCKET s, int level, int optname,
+					  const char FAR * optval, int optlen);
+typedef int (PASCAL FAR *shutdown_Type)(SOCKET s, int how);
+typedef SOCKET (PASCAL FAR *socket_Type)(int af, int type, int protocol);
+typedef struct hostent FAR * (PASCAL FAR *gethostbyaddr_Type)(const char FAR * addr,
+							      int len, int type);
+typedef struct hostent FAR * (PASCAL FAR *gethostbyname_Type)(const char FAR * name);
+typedef int (PASCAL FAR *gethostname_Type) (char FAR * name, int namelen);
+typedef struct servent FAR * (PASCAL FAR *getservbyport_Type)(int port, const char FAR * proto);
+typedef struct servent FAR * (PASCAL FAR *getservbyname_Type)(const char FAR * name,
+							      const char FAR * proto);
+typedef struct protoent FAR * (PASCAL FAR *getprotobynumber_Type)(int proto);
+typedef struct protoent FAR * (PASCAL FAR *getprotobyname_Type)(const char FAR * name);
+typedef int (PASCAL FAR *WSAStartup_Type)(WORD wVersionRequired, LPWSADATA lpWSAData);
+typedef int (PASCAL FAR *WSACleanup_Type)(void);
+typedef void (PASCAL FAR *WSASetLastError_Type)(int iError);
+typedef int (PASCAL FAR *WSAGetLastError_Type)(void);
+typedef BOOL (PASCAL FAR *WSAIsBlocking_Type)(void);
+typedef int (PASCAL FAR *WSAUnhookBlockingHook_Type)(void);
+typedef FARPROC (PASCAL FAR *WSASetBlockingHook_Type)(FARPROC lpBlockFunc);
+typedef int (PASCAL FAR *WSACancelBlockingCall_Type)(void);
+typedef HANDLE (PASCAL FAR *WSAAsyncGetServByName_Type)(HWND hWnd, u_int wMsg,
+							const char FAR * name,
+							const char FAR * proto,
+							char FAR * buf, int buflen);
+typedef HANDLE (PASCAL FAR *WSAAsyncGetServByPort_Type)(HWND hWnd, u_int wMsg, int port,
+							const char FAR * proto, char FAR * buf,
+							int buflen);
+typedef HANDLE (PASCAL FAR *WSAAsyncGetProtoByName_Type)(HWND hWnd, u_int wMsg,
+							 const char FAR * name, char FAR * buf,
+							 int buflen);
+typedef HANDLE (PASCAL FAR *WSAAsyncGetProtoByNumber_Type)(HWND hWnd, u_int wMsg,
+							   int number, char FAR * buf,
+							   int buflen);
+typedef HANDLE (PASCAL FAR *WSAAsyncGetHostByName_Type)(HWND hWnd, u_int wMsg,
+							const char FAR * name, char FAR * buf,
+							int buflen);
+typedef HANDLE (PASCAL FAR *WSAAsyncGetHostByAddr_Type)(HWND hWnd, u_int wMsg,
+							const char FAR * addr, int len, int type,
+							char FAR * buf, int buflen);
+typedef int (PASCAL FAR *WSACancelAsyncRequest_Type)(HANDLE hAsyncTaskHandle);
+typedef int (PASCAL FAR *WSAAsyncSelect_Type)(SOCKET s, HWND hWnd, u_int wMsg,
+					      long lEvent);
+
+
+
+static accept_Type accept_Ptr = NULL;
+static bind_Type bind_Ptr = NULL;
+static closesocket_Type closesocket_Ptr = NULL;
+static connect_Type connect_Ptr = NULL;
+static ioctlsocket_Type ioctlsocket_Ptr = NULL;
+static getpeername_Type getpeername_Ptr = NULL;
+static getsockname_Type getsockname_Ptr = NULL;
+static getsockopt_Type getsockopt_Ptr = NULL;
+static htonl_Type htonl_Ptr = NULL;
+static htons_Type htons_Ptr = NULL;
+static inet_addr_Type inet_addr_Ptr = NULL;
+static inet_ntoa_Type inet_ntoa_Ptr = NULL;
+static listen_Type listen_Ptr = NULL;
+static ntohl_Type ntohl_Ptr = NULL;
+static ntohs_Type ntohs_Ptr = NULL;
+static recv_Type recv_Ptr = NULL;
+static recvfrom_Type recvfrom_Ptr = NULL;
+static select_Type select_Ptr = NULL;
+static send_Type send_Ptr = NULL;
+static sendto_Type sendto_Ptr = NULL;
+static setsockopt_Type setsockopt_Ptr = NULL;
+static shutdown_Type shutdown_Ptr = NULL;
+static socket_Type socket_Ptr = NULL;
+static gethostbyaddr_Type gethostbyaddr_Ptr = NULL;
+static gethostbyname_Type gethostbyname_Ptr = NULL;
+static gethostname_Type gethostname_Ptr = NULL;
+static getservbyport_Type getservbyport_Ptr = NULL;
+static getservbyname_Type getservbyname_Ptr = NULL;
+static getprotobynumber_Type getprotobynumber_Ptr = NULL;
+static getprotobyname_Type getprotobyname_Ptr = NULL;
+static WSAStartup_Type WSAStartup_Ptr = NULL;
+static WSACleanup_Type WSACleanup_Ptr = NULL;
+static WSASetLastError_Type WSASetLastError_Ptr = NULL;
+static WSAGetLastError_Type WSAGetLastError_Ptr = NULL;
+static WSAIsBlocking_Type WSAIsBlocking_Ptr = NULL;
+static WSAUnhookBlockingHook_Type WSAUnhookBlockingHook_Ptr = NULL;
+static WSASetBlockingHook_Type WSASetBlockingHook_Ptr = NULL;
+static WSACancelBlockingCall_Type WSACancelBlockingCall_Ptr = NULL;
+static WSAAsyncGetServByName_Type WSAAsyncGetServByName_Ptr = NULL;
+static WSAAsyncGetServByPort_Type WSAAsyncGetServByPort_Ptr = NULL;
+static WSAAsyncGetProtoByName_Type WSAAsyncGetProtoByName_Ptr = NULL;
+static WSAAsyncGetProtoByNumber_Type WSAAsyncGetProtoByNumber_Ptr = NULL;
+static WSAAsyncGetHostByName_Type WSAAsyncGetHostByName_Ptr = NULL;
+static WSAAsyncGetHostByAddr_Type WSAAsyncGetHostByAddr_Ptr = NULL;
+static WSACancelAsyncRequest_Type WSACancelAsyncRequest_Ptr = NULL;
+static WSAAsyncSelect_Type WSAAsyncSelect_Ptr = NULL;
+
+
+static HINSTANCE wsock32lib = NULL;
+static HINSTANCE winsocklib = NULL;
+
+
+
+// set all the pointers back to null
+static void ResetWSPtrs () {
+  accept_Ptr = NULL;
+  bind_Ptr = NULL;
+  closesocket_Ptr = NULL;
+  connect_Ptr = NULL;
+  ioctlsocket_Ptr = NULL;
+  getpeername_Ptr = NULL;
+  getsockname_Ptr = NULL;
+  getsockopt_Ptr = NULL;
+  htonl_Ptr = NULL;
+  htons_Ptr = NULL;
+  inet_addr_Ptr = NULL;
+  inet_ntoa_Ptr = NULL;
+  listen_Ptr = NULL;
+  ntohl_Ptr = NULL;
+  ntohs_Ptr = NULL;
+  recv_Ptr = NULL;
+  recvfrom_Ptr = NULL;
+  select_Ptr = NULL;
+  send_Ptr = NULL;
+  sendto_Ptr = NULL;
+  setsockopt_Ptr = NULL;
+  shutdown_Ptr = NULL;
+  socket_Ptr = NULL;
+  gethostbyaddr_Ptr = NULL;
+  gethostbyname_Ptr = NULL;
+  gethostname_Ptr = NULL;
+  getservbyport_Ptr = NULL;
+  getservbyname_Ptr = NULL;
+  getprotobynumber_Ptr = NULL;
+  getprotobyname_Ptr = NULL;
+  WSAStartup_Ptr = NULL;
+  WSACleanup_Ptr = NULL;
+  WSASetLastError_Ptr = NULL;
+  WSAGetLastError_Ptr = NULL;
+  WSAIsBlocking_Ptr = NULL;
+  WSAUnhookBlockingHook_Ptr = NULL;
+  WSASetBlockingHook_Ptr = NULL;
+  WSACancelBlockingCall_Ptr = NULL;
+  WSAAsyncGetServByName_Ptr = NULL;
+  WSAAsyncGetServByPort_Ptr = NULL;
+  WSAAsyncGetProtoByName_Ptr = NULL;
+  WSAAsyncGetProtoByNumber_Ptr = NULL;
+  WSAAsyncGetHostByName_Ptr = NULL;
+  WSAAsyncGetHostByAddr_Ptr = NULL;
+  WSACancelAsyncRequest_Ptr = NULL;
+  WSAAsyncSelect_Ptr = NULL;
+}
+
+// get the pointers to all the socket functions
+static void SetupWSPtrs (HINSTANCE socketlib) {
+  if (socketlib == NULL) return;
+
+  accept_Ptr = (accept_Type)GetProcAddress(socketlib,"accept");
+  bind_Ptr = (bind_Type)GetProcAddress(socketlib,"bind");
+  closesocket_Ptr = (closesocket_Type)GetProcAddress(socketlib,"closesocket");
+  connect_Ptr = (connect_Type)GetProcAddress(socketlib,"connect");
+  ioctlsocket_Ptr = (ioctlsocket_Type)GetProcAddress(socketlib,"ioctlsocket");
+  getpeername_Ptr = (getpeername_Type)GetProcAddress(socketlib,"getpeername");
+  getsockname_Ptr = (getsockname_Type)GetProcAddress(socketlib,"getsockname");
+  getsockopt_Ptr = (getsockopt_Type)GetProcAddress(socketlib,"getsockopt");
+  htonl_Ptr = (htonl_Type)GetProcAddress(socketlib,"htonl");
+  htons_Ptr = (htons_Type)GetProcAddress(socketlib,"htons");
+  inet_addr_Ptr = (inet_addr_Type)GetProcAddress(socketlib,"inet_addr");
+  inet_ntoa_Ptr = (inet_ntoa_Type)GetProcAddress(socketlib,"inet_ntoa");
+  listen_Ptr = (listen_Type)GetProcAddress(socketlib,"listen");
+  ntohl_Ptr = (ntohl_Type)GetProcAddress(socketlib,"ntohl");
+  ntohs_Ptr = (ntohs_Type)GetProcAddress(socketlib,"ntohs");
+  recv_Ptr = (recv_Type)GetProcAddress(socketlib,"recv");
+  recvfrom_Ptr = (recvfrom_Type)GetProcAddress(socketlib,"recvfrom");
+  select_Ptr = (select_Type)GetProcAddress(socketlib,"select");
+  send_Ptr = (send_Type)GetProcAddress(socketlib,"send");
+  sendto_Ptr = (sendto_Type)GetProcAddress(socketlib,"sendto");
+  setsockopt_Ptr = (setsockopt_Type)GetProcAddress(socketlib,"setsockopt");
+  shutdown_Ptr = (shutdown_Type)GetProcAddress(socketlib,"shutdown");
+  socket_Ptr = (socket_Type)GetProcAddress(socketlib,"socket");
+  gethostbyaddr_Ptr = (gethostbyaddr_Type)GetProcAddress(socketlib,"gethostbyaddr");
+  gethostbyname_Ptr = (gethostbyname_Type)GetProcAddress(socketlib,"gethostbyname");
+  gethostname_Ptr = (gethostname_Type)GetProcAddress(socketlib,"gethostname");
+  getservbyport_Ptr = (getservbyport_Type)GetProcAddress(socketlib,"getservbyport");
+  getservbyname_Ptr = (getservbyname_Type)GetProcAddress(socketlib,"getservbyname");
+  getprotobynumber_Ptr = (getprotobynumber_Type)GetProcAddress(socketlib,"getprotobynumber");
+  getprotobyname_Ptr = (getprotobyname_Type)GetProcAddress(socketlib,"getprotobyname");
+  WSAStartup_Ptr = (WSAStartup_Type)GetProcAddress(socketlib,"WSAStartup");
+  WSACleanup_Ptr = (WSACleanup_Type)GetProcAddress(socketlib,"WSACleanup");
+  WSASetLastError_Ptr = (WSASetLastError_Type)GetProcAddress(socketlib,"WSASetLastError");
+  WSAGetLastError_Ptr = (WSAGetLastError_Type)GetProcAddress(socketlib,"WSAGetLastError");
+  WSAIsBlocking_Ptr = (WSAIsBlocking_Type)GetProcAddress(socketlib,"WSAIsBlocking");
+  WSAUnhookBlockingHook_Ptr = 
+    (WSAUnhookBlockingHook_Type)GetProcAddress(socketlib,"WSAUnhookBlockingHook");
+  WSASetBlockingHook_Ptr = 
+    (WSASetBlockingHook_Type)GetProcAddress(socketlib,"WSASetBlockingHook");
+  WSACancelBlockingCall_Ptr = 
+    (WSACancelBlockingCall_Type)GetProcAddress(socketlib,"WSACancelBlockingCall");
+  WSAAsyncGetServByName_Ptr = 
+    (WSAAsyncGetServByName_Type)GetProcAddress(socketlib,"WSAAsyncGetServByName");
+  WSAAsyncGetServByPort_Ptr = 
+    (WSAAsyncGetServByPort_Type)GetProcAddress(socketlib,"WSAAsyncGetServByPort");
+  WSAAsyncGetProtoByName_Ptr = 
+    (WSAAsyncGetProtoByName_Type)GetProcAddress(socketlib,"WSAAsyncGetProtoByName");
+  WSAAsyncGetProtoByNumber_Ptr = 
+    (WSAAsyncGetProtoByNumber_Type)GetProcAddress(socketlib,"WSAAsyncGetProtoByNumber");
+  WSAAsyncGetHostByName_Ptr = 
+    (WSAAsyncGetHostByName_Type)GetProcAddress(socketlib,"WSAAsyncGetHostByName");
+  WSAAsyncGetHostByAddr_Ptr = 
+    (WSAAsyncGetHostByAddr_Type)GetProcAddress(socketlib,"WSAAsyncGetHostByAddr");
+  WSACancelAsyncRequest_Ptr = 
+    (WSACancelAsyncRequest_Type)GetProcAddress(socketlib,"WSACancelAsyncRequest");
+  WSAAsyncSelect_Ptr = (WSAAsyncSelect_Type)GetProcAddress(socketlib,"WSAAsyncSelect");
+}
+
+
+
+// expects path to be NULL, a empty string, or a path which ends in a slash
+// returns D_NOERROR on success,
+// D_ERR_UNEXPECTED or D_ERR_LOADFAILED on failure
+int d_LoadWinsock (char *path) {
+  char dllname[2048]; // HARD LIMIT!!!!
+  OSVERSIONINFO osver;
+
+  if ((wsock32lib != NULL) || (winsocklib != NULL)) return D_ERR_UNEXPECTED;
+
+  // set the error mode so that no nasty dialog boxes come
+  // up when things aren't installed
+  int olderrormode = SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
+
+  // get the operating system version information
+  memset(&osver, 0, sizeof(OSVERSIONINFO));
+  osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+  if (!GetVersionEx(&osver)) {
+    SetErrorMode(olderrormode);
+    return D_ERR_UNEXPECTED;
+  }
+
+  // see if we should load winsock before wsock32
+  if ((osver.dwPlatformId == VER_PLATFORM_WIN32s) && (path != NULL)) {
+    strcpy (dllname, path);
+    strcat (dllname, "winsock.dll");
+
+    // attempt to load the library
+    winsocklib = LoadLibrary (dllname);
+    if (winsocklib == NULL) {
+      SetErrorMode(olderrormode);
+      return D_ERR_LOADFAILED;
+    }
+  }
+
+  // attempt to load wsock32
+  int err = D_NOERROR;
+  dllname[0] = '\0';
+  if ((osver.dwPlatformId != VER_PLATFORM_WIN32s) && (path != NULL)) {
+    strcpy (dllname, path);
+  }
+  strcat (dllname, "wsock32.dll");
+  wsock32lib = LoadLibrary (dllname);
+  if (wsock32lib == NULL) err = D_ERR_LOADFAILED;
+  else SetupWSPtrs (wsock32lib);
+
+
+  // perform a few tests
+
+  // first try starting-up (and check the szDescription field)
+  if (err == D_NOERROR) {
+    WSADATA Data;
+    memset(&Data, 0, sizeof(WSADATA));
+    if ((d_WSAStartup(257, &Data) != 0) ||
+	(Data.szDescription == NULL) || 
+	(Data.szDescription[0] == '\0'))
+      err = D_ERR_LOADFAILED;
+  }
+
+  // next try setting and getting an error
+  if (err == D_NOERROR) {
+    d_WSASetLastError (WSAENOTSOCK);
+    if (d_WSAGetLastError () != WSAENOTSOCK) err = D_ERR_LOADFAILED;
+    d_WSASetLastError (0);
+  }
+
+  // last try cleaning up (if an error occurs here we might
+  // not be able to unload anything)
+  if ((err == D_NOERROR) && (d_WSACleanup() == SOCKET_ERROR))
+    err = D_ERR_LOADFAILED;
+
+  // if an error occurred then we need to unload everything
+  if (err != D_NOERROR) d_UnloadWinsock ();
+
+  SetErrorMode(olderrormode);
+  return err;
+}
+
+// returns D_NOERROR on success,
+// D_ERR_FREELIBFAILED on failure
+int d_UnloadWinsock () {
+  int err = D_NOERROR;
+
+  // unload wsock32
+  if ((wsock32lib != NULL) && !FreeLibrary (wsock32lib)) {
+    err = D_ERR_FREELIBFAILED;
+  }
+  wsock32lib = NULL;
+
+  // unload winsock
+  if ((winsocklib != NULL) && !FreeLibrary (winsocklib)) {
+    err = D_ERR_FREELIBFAILED;
+  }
+  winsocklib = NULL;
+  
+  // reset all the function pointers
+  ResetWSPtrs ();
+
+  return err;
+}
+
+
+
+
+// socket functions, these just call the dynamically loaded version
+
+SOCKET d_accept (SOCKET s, struct sockaddr *addr, int *addrlen) {
+  if (accept_Ptr != NULL) 
+    return (*accept_Ptr)(s, addr, addrlen);
+  return INVALID_SOCKET; // error winsock not loaded
+}
+
+int d_bind (SOCKET s, const struct sockaddr *addr, int namelen) {
+  if (bind_Ptr != NULL) 
+    return (*bind_Ptr)(s, addr, namelen);
+  return WSANOTINITIALISED; // error winsock not loaded
+}
+
+int d_closesocket (SOCKET s) {
+  if (closesocket_Ptr != NULL) 
+    return (*closesocket_Ptr)(s);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+int d_connect (SOCKET s, const struct sockaddr *name, int namelen) {
+  if (connect_Ptr != NULL) 
+    return (*connect_Ptr)(s, name, namelen);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+int d_ioctlsocket (SOCKET s, long cmd, u_long *argp) {
+  if (ioctlsocket_Ptr != NULL) 
+    return (*ioctlsocket_Ptr)(s, cmd, argp);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+int d_getpeername (SOCKET s, struct sockaddr *name, int *namelen) {
+  if (getpeername_Ptr != NULL) 
+    return (*getpeername_Ptr)(s, name, namelen);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+int d_getsockname (SOCKET s, struct sockaddr *name, int *namelen) {
+  if (getsockname_Ptr != NULL) 
+    return (*getsockname_Ptr)(s, name, namelen);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+int d_getsockopt (SOCKET s, int level, int optname, char *optval, int *optlen) {
+  if (getsockopt_Ptr != NULL) 
+    return (*getsockopt_Ptr)(s, level, optname, optval, optlen);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+u_long d_htonl (u_long hostlong) {
+  if (htonl_Ptr != NULL) 
+    return (*htonl_Ptr)(hostlong);
+  return hostlong; // error winsock not loaded
+}
+
+u_short d_htons (u_short hostshort) {
+  if (htons_Ptr != NULL) 
+    return (*htons_Ptr)(hostshort);
+  return hostshort; // error winsock not loaded
+}
+
+unsigned long d_inet_addr (const char *cp) {
+  if (inet_addr_Ptr != NULL) 
+    return (*inet_addr_Ptr)(cp);
+  return INADDR_NONE; // error winsock not loaded
+}
+
+char *d_inet_ntoa (struct in_addr in) {
+  if (inet_ntoa_Ptr != NULL) 
+    return (*inet_ntoa_Ptr)(in);
+  return NULL; // error winsock not loaded
+}
+
+int d_listen (SOCKET s, int backlog) {
+  if (listen_Ptr != NULL) 
+    return (*listen_Ptr)(s, backlog);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+u_long d_ntohl (u_long netlong) {
+  if (ntohl_Ptr != NULL) 
+    return (*ntohl_Ptr)(netlong);
+  return netlong; // error winsock not loaded
+}
+
+u_short d_ntohs (u_short netshort) {
+  if (ntohs_Ptr != NULL) 
+    return (*ntohs_Ptr)(netshort);
+  return netshort; // error winsock not loaded
+}
+
+int d_recv (SOCKET s, char *buf, int len, int flags) {
+  if (recv_Ptr != NULL) 
+    return (*recv_Ptr)(s, buf, len, flags);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+int d_recvfrom (SOCKET s, char *buf, int len, int flags,
+		struct sockaddr *from, int *fromlen) {
+  if (recvfrom_Ptr != NULL) 
+    return (*recvfrom_Ptr)(s, buf, len, flags, from, fromlen);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+int d_select (int nfds, fd_set *readfds, fd_set *writefds,
+	      fd_set *exceptfds, const struct timeval *timeout) {
+  if (select_Ptr != NULL) 
+    return (*select_Ptr)(nfds, readfds, writefds, exceptfds, timeout);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+int d_send (SOCKET s, const char *buf, int len, int flags) {
+  if (send_Ptr != NULL) 
+    return (*send_Ptr)(s, buf, len, flags);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+int d_sendto (SOCKET s, const char *buf, int len, int flags,
+	      const struct sockaddr *to, int tolen) {
+  if (sendto_Ptr != NULL) 
+    return (*sendto_Ptr)(s, buf, len, flags, to, tolen);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+int d_setsockopt (SOCKET s, int level, int optname,
+		  const char *optval, int optlen) {
+  if (setsockopt_Ptr != NULL) 
+    return (*setsockopt_Ptr)(s, level, optname, optval, optlen);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+int d_shutdown (SOCKET s, int how) {
+  if (shutdown_Ptr != NULL) 
+    return (*shutdown_Ptr)(s, how);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+SOCKET d_socket (int af, int type, int protocol) {
+  if (socket_Ptr != NULL) 
+    return (*socket_Ptr)(af, type, protocol);
+  return INVALID_SOCKET; // error winsock not loaded
+}
+
+hostent *d_gethostbyaddr(const char *addr, int len, int type) {
+  if (gethostbyaddr_Ptr != NULL) 
+    return (*gethostbyaddr_Ptr)(addr, len, type);
+  return NULL; // error winsock not loaded
+}
+
+hostent *d_gethostbyname(const char *name) {
+  if (gethostbyname_Ptr != NULL) 
+    return (*gethostbyname_Ptr)(name);
+  return NULL; // error winsock not loaded
+}
+
+int d_gethostname (char *name, int namelen) {
+  if (gethostname_Ptr != NULL) 
+    return (*gethostname_Ptr)(name, namelen);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+servent *d_getservbyport(int port, const char *proto) {
+  if (getservbyport_Ptr != NULL) 
+    return (*getservbyport_Ptr)(port, proto);
+  return NULL; // error winsock not loaded
+}
+
+servent *d_getservbyname(const char *name, const char *proto) {
+  if (getservbyname_Ptr != NULL) 
+    return (*getservbyname_Ptr)(name, proto);
+  return NULL; // error winsock not loaded
+}
+
+protoent *d_getprotobynumber(int proto) {
+  if (getprotobynumber_Ptr != NULL) 
+    return (*getprotobynumber_Ptr)(proto);
+  return NULL; // error winsock not loaded
+}
+
+protoent *d_getprotobyname(const char *name) {
+  if (getprotobyname_Ptr != NULL) 
+    return (*getprotobyname_Ptr)(name);
+  return NULL; // error winsock not loaded
+}
+
+int d_WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData) {
+  if (WSAStartup_Ptr != NULL) 
+    return (*WSAStartup_Ptr)(wVersionRequired, lpWSAData);
+  return WSASYSNOTREADY; // error winsock not loaded
+}
+
+int d_WSACleanup(void) {
+  if (WSACleanup_Ptr != NULL) 
+    return (*WSACleanup_Ptr)();
+  return WSANOTINITIALISED; // error winsock not loaded
+}
+
+void d_WSASetLastError(int iError) {
+  if (WSASetLastError_Ptr != NULL) (*WSASetLastError_Ptr)(iError);
+}
+
+int d_WSAGetLastError(void) {
+  if (WSAGetLastError_Ptr != NULL) 
+    return (*WSAGetLastError_Ptr)();
+  return WSANOTINITIALISED; // error winsock not loaded
+}
+
+BOOL d_WSAIsBlocking(void) {
+  if (WSAIsBlocking_Ptr != NULL) 
+    return (*WSAIsBlocking_Ptr)();
+  return FALSE; // error winsock not loaded
+}
+
+int d_WSAUnhookBlockingHook(void) {
+  if (WSAUnhookBlockingHook_Ptr != NULL) 
+    return (*WSAUnhookBlockingHook_Ptr)();
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+FARPROC d_WSASetBlockingHook(FARPROC lpBlockFunc) {
+  if (WSASetBlockingHook_Ptr != NULL) 
+    return (*WSASetBlockingHook_Ptr)(lpBlockFunc);
+  return NULL; // error winsock not loaded
+}
+
+int d_WSACancelBlockingCall(void) {
+  if (WSACancelBlockingCall_Ptr != NULL) 
+    return (*WSACancelBlockingCall_Ptr)();
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+HANDLE d_WSAAsyncGetServByName(HWND hWnd, u_int wMsg,
+			       const char *name,
+			       const char *proto,
+			       char *buf, int buflen) {
+  if (WSAAsyncGetServByName_Ptr != NULL) 
+    return (*WSAAsyncGetServByName_Ptr)(hWnd, wMsg, name, proto, buf, buflen);
+  return NULL; // error winsock not loaded
+}
+
+HANDLE d_WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port,
+			       const char *proto, char *buf,
+			       int buflen) {
+  if (WSAAsyncGetServByPort_Ptr != NULL) 
+    return (*WSAAsyncGetServByPort_Ptr)(hWnd, wMsg, port, proto, buf, buflen);
+  return NULL; // error winsock not loaded
+}
+
+HANDLE d_WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg,
+				const char *name, char *buf,
+				int buflen) {
+  if (WSAAsyncGetProtoByName_Ptr != NULL) 
+    return (*WSAAsyncGetProtoByName_Ptr)(hWnd, wMsg, name, buf, buflen);
+  return NULL; // error winsock not loaded
+}
+
+HANDLE d_WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg,
+				  int number, char *buf,
+				  int buflen) {
+  if (WSAAsyncGetProtoByNumber_Ptr != NULL) 
+    return (*WSAAsyncGetProtoByNumber_Ptr)(hWnd, wMsg, number, buf, buflen);
+  return NULL; // error winsock not loaded
+}
+
+HANDLE d_WSAAsyncGetHostByName(HWND hWnd, u_int wMsg,
+			       const char *name, char *buf,
+			       int buflen) {
+  if (WSAAsyncGetHostByName_Ptr != NULL) 
+    return (*WSAAsyncGetHostByName_Ptr)(hWnd, wMsg, name, buf, buflen);
+  return NULL; // error winsock not loaded
+}
+
+HANDLE d_WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg,
+                                        const char *addr, int len, int type,
+                                        char *buf, int buflen) {
+  if (WSAAsyncGetHostByAddr_Ptr != NULL) 
+    return (*WSAAsyncGetHostByAddr_Ptr)(hWnd, wMsg, addr, len, type, buf, buflen);
+  return NULL; // error winsock not loaded
+}
+
+int d_WSACancelAsyncRequest(HANDLE hAsyncTaskHandle) {
+  if (WSACancelAsyncRequest_Ptr != NULL) 
+    return (*WSACancelAsyncRequest_Ptr)(hAsyncTaskHandle);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
+int d_WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
+                               long lEvent) {
+  if (WSAAsyncSelect_Ptr != NULL) 
+    return (*WSAAsyncSelect_Ptr)(s, hWnd, wMsg, lEvent);
+  return SOCKET_ERROR; // error winsock not loaded
+}
+
Index: /gsdl/stable/runtime-src/src/w32server/d_winsock.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/d_winsock.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/d_winsock.h	(revision 20131)
@@ -0,0 +1,120 @@
+/**********************************************************************
+ *
+ * d_winsock.h
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef D_WINSOCK_H
+#define D_WINSOCK_H
+
+/* get most definitions from the real winsock */
+#include <winsock.h>
+
+#define D_NOERROR           0
+#define D_ERR_UNEXPECTED    1
+#define D_ERR_LOADFAILED    2
+#define D_ERR_FREELIBFAILED 3
+
+// d_LoadWinsock must be called before an normal winsock
+// functions
+
+// expects path to be NULL, a empty string, or a path which ends in a slash
+// returns D_NOERROR on success,
+// D_ERR_UNEXPECTED or D_ERR_LOADFAILED on failure
+int d_LoadWinsock (char *path);
+
+// returns D_NOERROR on success,
+// D_ERR_FREELIBFAILED on failure
+int d_UnloadWinsock ();
+
+// dynamically loaded versions of the winsock functions
+
+SOCKET d_accept (SOCKET s, struct sockaddr *addr, int *addrlen);
+int d_bind (SOCKET s, const struct sockaddr *addr, int namelen);
+int d_closesocket (SOCKET s);
+int d_connect (SOCKET s, const struct sockaddr *name, int namelen);
+int d_ioctlsocket (SOCKET s, long cmd, u_long *argp);
+int d_getpeername (SOCKET s, struct sockaddr *name, int *namelen);
+int d_getsockname (SOCKET s, struct sockaddr *name, int *namelen);
+int d_getsockopt (SOCKET s, int level, int optname, char *optval, int *optlen);
+u_long d_htonl (u_long hostlong);
+u_short d_htons (u_short hostshort);
+unsigned long d_inet_addr (const char *cp);
+char *d_inet_ntoa (struct in_addr in);
+int d_listen (SOCKET s, int backlog);
+u_long d_ntohl (u_long netlong);
+u_short d_ntohs (u_short netshort);
+int d_recv (SOCKET s, char *buf, int len, int flags);
+int d_recvfrom (SOCKET s, char *buf, int len, int flags,
+		struct sockaddr *from, int *fromlen);
+int d_select (int nfds, fd_set *readfds, fd_set *writefds,
+	      fd_set *exceptfds, const struct timeval *timeout);
+int d_send (SOCKET s, const char *buf, int len, int flags);
+int d_sendto (SOCKET s, const char *buf, int len, int flags,
+	      const struct sockaddr *to, int tolen);
+int d_setsockopt (SOCKET s, int level, int optname,
+		  const char *optval, int optlen);
+int d_shutdown (SOCKET s, int how);
+SOCKET d_socket (int af, int type, int protocol);
+
+hostent *d_gethostbyaddr(const char *addr, int len, int type);
+hostent *d_gethostbyname(const char *name);
+int d_gethostname (char *name, int namelen);
+servent *d_getservbyport(int port, const char *proto);
+servent *d_getservbyname(const char *name, const char *proto);
+protoent *d_getprotobynumber(int proto);
+protoent *d_getprotobyname(const char *name);
+
+int d_WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);
+int d_WSACleanup(void);
+void d_WSASetLastError(int iError);
+int d_WSAGetLastError(void);
+BOOL d_WSAIsBlocking(void);
+int d_WSAUnhookBlockingHook(void);
+FARPROC d_WSASetBlockingHook(FARPROC lpBlockFunc);
+int d_WSACancelBlockingCall(void);
+HANDLE d_WSAAsyncGetServByName(HWND hWnd, u_int wMsg,
+			       const char *name,
+			       const char *proto,
+			       char *buf, int buflen);
+HANDLE d_WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port,
+			       const char *proto, char *buf,
+			       int buflen);
+HANDLE d_WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg,
+				const char *name, char *buf,
+				int buflen);
+HANDLE d_WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg,
+				  int number, char *buf,
+				  int buflen);
+HANDLE d_WSAAsyncGetHostByName(HWND hWnd, u_int wMsg,
+			       const char *name, char *buf,
+			       int buflen);
+HANDLE d_WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg,
+			       const char *addr, int len, int type,
+			       char *buf, int buflen);
+int d_WSACancelAsyncRequest(HANDLE hAsyncTaskHandle);
+int d_WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg,
+		     long lEvent);
+
+#endif
Index: /gsdl/stable/runtime-src/src/w32server/fnord.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/fnord.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/fnord.cpp	(revision 20131)
@@ -0,0 +1,1213 @@
+/**********************************************************************
+ *
+ * fnord.cpp
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "text_t.h"
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#pragma hdrstop
+#include "netio.h"
+#include "settings.h"
+#include "httpsrv.h"
+#include "resource.h"
+#include "locate.h"
+#include "cgiwrapper.h"
+#include "startbrowser.h"
+#include "d_winsock.h"
+#include "fileutil.h"
+
+#define MAINWINDOWWIDTH 400
+#define MAINWINDOWHEIGHT 200
+
+#define WASTEHEIGHT 44  // Error in ht due to caption and menu bar
+#define WASTEWIDTH 6
+#define SPACERWIDTH 5
+
+// size and position of the collection title
+#define COLTITLEWIDTH 351
+#define COLTITLEHEIGHT 35
+#define COLTITLEX ((MAINWINDOWWIDTH-COLTITLEWIDTH)/2)
+#define COLTITLEY 10
+
+// size and position of the version string
+#define VERSIONWIDTH MAINWINDOWWIDTH
+#define VERSIONHEIGHT 20
+#define VERSIONX 0
+#define VERSIONY (COLTITLEY+COLTITLEHEIGHT)
+
+// size and position of the Greenstone digital library logo
+#define LOGOWIDTH 135
+#define LOGOHEIGHT 55
+#define LOGOX (MAINWINDOWWIDTH-(LOGOWIDTH+SPACERWIDTH))
+#define LOGOY (MAINWINDOWHEIGHT-(LOGOHEIGHT+SPACERWIDTH))
+
+// size and position of the enter button
+#define ENTERBUTTONWIDTH 160
+#define ENTERBUTTONHEIGHT 30
+#define ENTERBUTTONX SPACERWIDTH
+#define ENTERBUTTONY ((MAINWINDOWHEIGHT-(LOGOHEIGHT+SPACERWIDTH))-(ENTERBUTTONHEIGHT+SPACERWIDTH))
+
+// size and position of the enter string
+#define ENTERSTRINGX (ENTERBUTTONX+ENTERBUTTONWIDTH+SPACERWIDTH)
+#define ENTERSTRINGY ENTERBUTTONY
+#define ENTERSTRINGWIDTH (MAINWINDOWWIDTH-(ENTERBUTTONWIDTH+SPACERWIDTH+SPACERWIDTH+SPACERWIDTH))
+#define ENTERSTRINGHEIGHT ENTERBUTTONHEIGHT
+
+// size and position of the info string
+#define INFOWIDTH MAINWINDOWWIDTH
+#define INFOHEIGHT (MAINWINDOWHEIGHT-INFOY)
+#define INFOX 0
+#define INFOY ENTERBUTTONY
+
+// size and position of restricted buttons
+#define ALTERNATIVEBUTTONWIDTH 160
+#define ALTERNATIVEBUTTONHEIGHT 30
+#define ALTERNATIVEBUTTONX SPACERWIDTH
+#define ALTERNATIVEBUTTONY LOGOY
+
+#define INFOBUTTONWIDTH 30
+
+// size and position of restart button
+#define RESTARTBUTTONWIDTH 160
+#define RESTARTBUTTONHEIGHT 30
+#define RESTARTBUTTONX 50
+#define RESTARTBUTTONY (MAINWINDOWHEIGHT-RESTARTBUTTONHEIGHT-15)
+
+const char versionstring[] = "version " GSDL_VERSION;
+
+const char strnothing[] = "";
+const char strinit[] = "Initialising...";
+const char strsb[] = "Starting browser...";
+const char strrestartlib[] = "Press the 'Restart Library' button to start a browser\n"
+"and enter library";
+const char strenterlib[] = "Press this button to begin using\n"
+"the library";
+const char *enterstring = NULL; // points to the current enter string
+const char *infostring = NULL; // points to the current info string
+
+
+// globals to do with networking and browsers
+int have_networking = 0;
+int netscapeneeded = 0;
+char startbrowserdir[1024] = ""; // HARD LIMIT!!!!!
+
+
+// stats to do with the last time the enter library button was pressed
+// these stats are needed to make suggestions about the proxy
+int enterlib_libaccessnum = -1; // -1 = NA
+DWORD enterlib_time = 0;
+
+
+enum { undefined_window, console_window, plain_window }
+window_state;
+
+HDC coltitledc = NULL;
+HBITMAP defcoltitlebitmap = NULL, coltitlebitmap=NULL;
+
+HDC logodc=NULL;
+HBITMAP deflogobitmap=NULL, logobitmap=NULL;
+
+HWND GoButton = NULL;
+HWND Enter = NULL;
+// HWND EnterRestricted = NULL;
+// HWND InfoRestricted = NULL;
+int init_type = 0;
+int init_done = 0;
+
+
+// Added an argument so you can specify not to do any of the windows orientated clean up - jmt12 18/11/2003
+void finish_up(bool init_only) {
+  // remember the current preferences
+  write_settings("");
+
+  if(init_only) {
+    return;
+  }
+   
+ // Shutdown the HTTP server
+  EndHTTPServer();
+  
+  // Shutdown the main server modules
+  CleanUpNetIO();
+  //    RemoveFnordFromTray();
+  
+  // Unload the wsock32 dll
+  d_UnloadWinsock();
+  
+  // Clean up graphics stuff from window
+  
+  if (defcoltitlebitmap != NULL)
+    SelectObject (coltitledc, defcoltitlebitmap);
+  if (coltitlebitmap != NULL)
+    DeleteObject (coltitlebitmap);
+  if (coltitledc != NULL)
+    DeleteDC (coltitledc);
+  
+  if (deflogobitmap != NULL)
+    SelectObject (logodc, deflogobitmap);
+  if (logobitmap != NULL)
+    DeleteObject (logobitmap);
+  if (logodc != NULL)
+    DeleteDC (logodc);
+  
+  // Shutdown the main window
+  PostQuitMessage(0);
+}
+
+
+int overlap(int left, int top, int right, int bottom,
+            RECT &r2)
+{
+  if (left <= r2.right && r2.left <= right &&
+      top <= r2.bottom && r2.top <= bottom)
+    return 1;
+  else
+    return 0;
+}
+
+
+void paint_window (HDC pdc, RECT &updateRect) {
+  // make sure the various DCs are set up
+  if (coltitledc == NULL) {
+    coltitledc = CreateCompatibleDC(pdc);
+    defcoltitlebitmap = (HBITMAP)SelectObject (coltitledc, coltitlebitmap);
+  }
+  
+  if (logodc == NULL) {
+    logodc = CreateCompatibleDC(pdc);
+    deflogobitmap = (HBITMAP)SelectObject (logodc, logobitmap);
+  }
+
+  // remove any remaining sign of initial buttons
+  if (init_done && (overlap (ENTERBUTTONX, ENTERBUTTONY, ENTERBUTTONX+ENTERBUTTONWIDTH,
+		ALTERNATIVEBUTTONY+ALTERNATIVEBUTTONHEIGHT, updateRect))) {
+    RECT initRect;
+    initRect.left = ENTERBUTTONX;
+    initRect.top = ENTERBUTTONY;
+    initRect.right = ENTERBUTTONX+ENTERBUTTONWIDTH;
+    initRect.bottom = ALTERNATIVEBUTTONY+ALTERNATIVEBUTTONHEIGHT;
+    FillRect(pdc, &initRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
+  }
+
+  // update the collection title if needed
+  if (overlap(COLTITLEX, COLTITLEY,
+	      COLTITLEX+COLTITLEWIDTH, COLTITLEY+COLTITLEHEIGHT, 
+	      updateRect)) {
+    BitBlt (pdc, COLTITLEX, COLTITLEY, 
+	    COLTITLEX+COLTITLEWIDTH, COLTITLEY+COLTITLEHEIGHT,
+	    coltitledc, 0, 0, SRCCOPY);
+  }
+  
+  // update the version string if needed
+  if (overlap (VERSIONX, VERSIONY, 
+	       VERSIONX+VERSIONWIDTH, VERSIONY+VERSIONHEIGHT,
+	       updateRect)) {
+    RECT versionRect;
+    versionRect.left = VERSIONX;
+    versionRect.top = VERSIONY;
+    versionRect.right = VERSIONX+VERSIONWIDTH;
+    versionRect.bottom = VERSIONY+VERSIONHEIGHT;
+    DrawText(pdc, versionstring, -1, &versionRect, DT_CENTER);
+  }
+  
+  // decide what we want to draw
+  if (init_done && gsdl_show_console) {
+    // we want to draw a "console" window
+    if (window_state != console_window ||
+	overlap (text_rect.left, text_rect.top,
+		 text_rect.right, text_rect.bottom,
+		 updateRect)) {
+      refresh_console (pdc);
+    }
+    
+    window_state = console_window;
+    
+  } else {
+    // we want to draw a "plain" window
+    
+    // update the enter string if needed
+    if (overlap (ENTERSTRINGX, ENTERSTRINGY, ENTERSTRINGX+ENTERSTRINGWIDTH, 
+		 ENTERSTRINGY+ENTERSTRINGHEIGHT, updateRect)) {
+
+	RECT enterstringRect;
+	enterstringRect.left = ENTERSTRINGX;
+	enterstringRect.top = ENTERSTRINGY;
+	enterstringRect.right = ENTERSTRINGX+ENTERSTRINGWIDTH;
+	enterstringRect.bottom = ENTERSTRINGY+ENTERSTRINGHEIGHT;
+	FillRect(pdc, &enterstringRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
+
+	if ((enterstring != NULL) && (strlen(enterstring) > 0)) {
+      
+	  int cury = ENTERSTRINGY;
+	  int startline = 0, here = 0;
+	  while (enterstring[here] != '\0') {
+	    if (enterstring[here] < ' ') {
+	      if (here - startline > 0) {
+		// output the text
+		TextOut (pdc, ENTERSTRINGX, cury, 
+			 &enterstring[startline], here-startline);
+		cury += line_spacing;
+	      }
+	      startline = here+1;
+	    }
+	    ++here;
+	  }
+	  // output any remaining text
+	  if (here - startline > 0) {
+	    TextOut (pdc, ENTERSTRINGX, cury, &enterstring[startline], here-startline);
+	  }
+	}
+    }
+    
+    window_state = plain_window;
+  }
+  
+  // update the info string if needed
+  if (init_done && !gsdl_show_console && 
+      ((infostring != NULL) && overlap (INFOX, INFOY, 
+					INFOX+INFOWIDTH, INFOY+INFOHEIGHT,
+					updateRect))) {
+    RECT infoRect;
+    infoRect.left = INFOX;
+    infoRect.top = INFOY;
+    infoRect.right = INFOX+INFOWIDTH;
+    infoRect.bottom = INFOY+INFOHEIGHT;
+    FillRect(pdc, &infoRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
+    DrawText(pdc, infostring, -1, &infoRect, DT_CENTER);
+  }
+
+  // update the logo (always)
+  BitBlt (pdc, LOGOX, LOGOY, LOGOX+LOGOWIDTH, LOGOY+LOGOHEIGHT,
+	  logodc, 0, 0, SRCCOPY);
+}
+
+
+void handle_painting (HWND Window) {
+  HDC pdc;  PAINTSTRUCT ps;
+  pdc = BeginPaint(Window, &ps);
+  
+  paint_window (pdc, ps.rcPaint);
+  
+  EndPaint(Window, &ps);
+}
+
+
+// returns 1 on success, 0 otherwise
+int enter_library (HWND Window) {
+  int res;
+  
+  if (infostring == strrestartlib) {
+
+    // the "restart library" button was pressed so we want to reinitialize
+    // greenstone, read in all the macrofiles again, etc.
+    gsdl_init(false);
+  }
+
+  // get the url and attempt to start a browser
+  if (have_networking) {
+    // There are now four address resolution methods:
+    //   0: Standard -- get local IP then resolve to a name
+    //   1: IP only -- as above, but use IP only -- don't resolve to a name
+    //   2: localhost -- always use localhost
+    //   3: 127.0.0.1 -- always use 127.0.0.1
+    char gsdl_address[100];
+
+    DWORD local_ip = GetLocalIP();
+    if (local_ip == INADDR_ANY || gsdl_address_resolution_method == 3) {
+      local_ip = 127 + (0 << 8) + (0 << 16) + (1 << 24);
+    }
+
+    if (gsdl_address_resolution_method == 1 || gsdl_address_resolution_method == 3) {
+      sprintf(gsdl_address, "%d.%d.%d.%d", local_ip & 0xFF, (local_ip >> 8) & 0xFF, (local_ip >> 16) & 0xFF, (local_ip >> 24) & 0xFF);
+    }
+    else if (gsdl_address_resolution_method == 2) {
+      sprintf(gsdl_address, "localhost");
+    }
+    else {
+      strcpy(gsdl_address, GetLocalName(NULL));
+    }
+
+    text_t url = "http://" + text_t(gsdl_address);
+
+    gsdl_url = url;
+    write_settings(gsdl_url);
+
+    if (gsdl_port_num != 80) {
+      url += ":" + text_t(gsdl_port_num);
+    }
+    url += gsdl_enterlib;
+
+    // add a unique ending so it will always result in a request
+    text_t::const_iterator it = 
+      findchar (gsdl_enterlib.begin(), gsdl_enterlib.end(), '?');
+    if (it == gsdl_enterlib.end()) url.push_back ('?');
+    else url.push_back ('&');
+    int tcount = GetTickCount();
+    url += "uq=" + text_t(tcount);
+    
+    // remember the library access number for later proxy checking
+    enterlib_libaccessnum = libaccessnum;
+    
+    if (gsdl_start_browser) {
+
+      // do a quick check to make sure we're using netscape when
+      // we should be (it might have been just installed)
+      if (netscapeneeded) gsdl_check_browser_settings (netscapeneeded);
+    
+      char *cstr_url = url.getcstr();
+      if (strlen (startbrowserdir) <= 0) {
+	res = startbrowser (cstr_url, gsdl_browser_exe, NULL);
+	
+      } else res = startbrowser (cstr_url, gsdl_browser_exe, startbrowserdir);
+    
+      delete []cstr_url;
+
+    } else {
+      return 1;
+    }
+  }
+  
+  if (res == SB_NOERROR) {
+    // success !!
+    
+    // remember the time the browser was started for later proxy checking
+    if (have_networking) enterlib_time = GetTickCount();
+    
+    return 1;
+  }
+  
+  // no browser was started
+  enterlib_libaccessnum = -1;
+  
+  if ((res == SB_FAIL_BADFORMAT) || (res == SB_FAIL_NOTFOUND)) {
+    if (!netscapeneeded) { // any browser
+      MessageBox(Window,
+		 "Failed to start your chosen browser. It seems that your\n"
+		 "chosen browser has been removed or corrupted.\n"
+		 "Please check your browser choice by going to the\n"
+		 "'Settings...' item under the 'File' menu.",
+		 "Greenstone Digital Library Software", MB_OK);
+    } else { // netscape used
+      MessageBox(Window,
+		 "Failed to start Netscape. It seems that Netscape has\n"
+		 "been removed or corrupted. You need Netscape\n"
+		 "installed to use the Greenstone Digital Library\n"
+		 "software on non-networked machines.",
+		 "Greenstone Digital Library Software", MB_OK);
+    }
+    
+  } else {
+    MessageBox(Window,
+	       "Failed to start your browser. This may have been\n"
+	       "because there was not enough memory available. Shut\n"
+	       "down all other applications you have running, and\n"
+	       "try again.",
+	       "Greenstone Digital Library Software", MB_OK);
+  }
+  
+  return 0; // failed
+}
+
+
+void install_netscape (HWND Window) {
+  char installpath[256];
+  
+  // try to find the browser directory
+  char *gsdlhome = gsdl_gsdlhome.getcstr();
+  strcpy (installpath, gsdlhome); // use gsdlhome to find the CD-ROM drive...
+  delete []gsdlhome;
+  
+  // remove any slashes from the pathname
+  int len = strlen (installpath);
+  while ((len > 0) && ((installpath[len-1] == '\\') || (installpath[len-1] == '/'))) {
+    --len;
+  }
+  // remove '\gsdl'
+  len = len - 5;
+  installpath[len] = '\0';
+  
+  strcat (installpath, "\\netscape\\");
+  
+  // check this directory
+  if (!cstrcheckdir(installpath)) {
+    return;
+  }
+  
+  // get the operating system information
+  OSVERSIONINFO osver;
+  memset(&osver, 0, sizeof(OSVERSIONINFO));
+  osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+  GetVersionEx(&osver);
+
+  // get the install program for this operating system
+  if (osver.dwPlatformId == VER_PLATFORM_WIN32s) {
+    strcat (installpath, "n16e405.exe");
+  } else {
+    strcat (installpath, "n32e405.exe");
+  }
+  
+  // run the install program
+  int res = WinExec (installpath, SW_SHOW);
+  if (res == 0) {
+    // out of resources or memory
+    MessageBox (Window,
+		"Did not have enough resources or memory to run the\n"
+		"install program. Try shutting down all other programs\n"
+		"and trying again.",
+		"Greenstone Digital Library Software",
+		MB_OK|MB_APPLMODAL);
+    
+  } else if (res == ERROR_BAD_FORMAT) {
+    // executable image is corrupt -- ????
+    MessageBox (Window,
+		"The install program seems to be corrupt.",
+		"Greenstone Digital Library Software",
+		MB_OK|MB_APPLMODAL);
+    
+  } else if ((res == ERROR_FILE_NOT_FOUND) || (res == ERROR_PATH_NOT_FOUND)) {
+    // couldn't find the executable -- ????
+    MessageBox (Window,
+		"Could not find the install program. Try installing\n"
+		"Netscape from the Greenstone Digital Library\n"
+		"software's install program.",
+		"Greenstone Digital Library Software",
+		MB_OK|MB_APPLMODAL);
+  }
+}
+
+void open_help () {
+  char topdir[256], cmd[256];
+  
+  // try to find the browser directory
+  char *gsdlhome = gsdl_gsdlhome.getcstr();
+  strcpy (topdir, gsdlhome); // use gsdlhome to find the CD-ROM drive...
+  delete []gsdlhome;
+  strcpy (cmd, "notepad ");
+  
+  // remove any slashes from the pathname
+  int len = strlen (topdir);
+  while ((len > 0) && ((topdir[len-1] == '\\') || (topdir[len-1] == '/'))) {
+    --len;
+  }
+  // remove the '\gsdl'
+  len = len - 5;
+  topdir[len] = '\0';
+
+  strcat (topdir, "\\README.txt");
+  strcat (cmd, topdir);
+  
+  WinExec (cmd, SW_SHOW);
+}
+
+
+long __stdcall WndProc(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam) {
+  switch(Message) {
+    // Constant Messages
+  case WM_CREATE:
+    break;
+    
+  case WM_COMMAND:
+    if ((GoButton != NULL) && ((HWND)LParam == GoButton)) {
+      // attempt to start a browser
+      gsdl_start_browser = 1;
+      if (enter_library (Window) && !gsdl_show_console) 
+    	ShowWindow(Window,SW_MINIMIZE);
+
+    } else if ((Enter != NULL) && ((HWND)LParam == Enter)) {
+      init_done = 1;
+      init_type = 1;
+
+//      } else if ((EnterRestricted != NULL) && ((HWND)LParam == EnterRestricted)) {
+//        init_done = 1;
+//        init_type = 0;
+
+//      } else if ((InfoRestricted != NULL) && ((HWND)LParam == InfoRestricted)) {
+//        MessageBox (NULL, "The Greenstone system automatically determines whether your computer has\n"
+//  		  "network software installed or is connected to a network.  It operates correctly\n"
+//  		  "under any of these conditions.\n\n"
+//  		  "The restricted version is intended for use when the standard one\n\n"
+//  		  "   (a) causes an unwanted telephone dialup operation;\n"
+//  		  "   (b) fails to run because network software is installed, but installed\n"
+//  		  "         incorrectly.\n\n"
+//  		  "The restricted version only works with Netscape (not Internet Explorer).\n\n"
+//  		  "Unless these problems arise, you should always use the standard version\n"
+//  		  "(press the 'Enter Library' button).\n",
+//  		  "Greenstone Digital Library Software", 
+//  		  MB_OK | MB_ICONINFORMATION | MB_APPLMODAL);
+
+    } else {
+      switch (LOWORD(WParam)) {
+      case ID_PROJECT_SETTINGS:
+	Settings_Dialog(Window, netscapeneeded);
+	break;
+      case ID_INSTALL_NETSCAPE:
+	install_netscape(Window);
+	break;
+      case IDHELP:
+	open_help();
+	break;
+      case ID_PROJECT_EXIT:
+        finish_up(false);
+        break;
+      default:
+        break;
+      }
+    }
+    break;
+    
+  case WM_PAINT:
+    handle_painting(Window);
+    break;
+    
+  case HTTP_SERVER_MSG:
+    ProcessHTTPServerMsg(WParam, LParam);
+    break;
+    
+  case WM_DESTROY:
+    finish_up(false);
+    break;
+    
+  default:
+    //Unhandled Messages end up here (DefWindowProc)
+    return DefWindowProc(Window, Message, WParam, LParam);
+  }
+  
+  return(0);
+}
+
+// returns 0 if successful,
+// otherwise a WSA error number
+int tryinitnetwork (HANDLE Instance, HWND MsgWindow, char *path) {
+  // try to load winsock
+  int err = d_LoadWinsock (path);
+  
+  if (err == D_NOERROR) {
+    // next, try to init netio
+    err = InitNetIO();
+    
+    if (err == 0) {
+      // next, try to start the http server
+      err = StartHTTPServer(MsgWindow);
+      
+      if (err == 0) {
+	// finally, get the host name (no error value
+	// is returned from this function)
+	GetLocalName((HINSTANCE)Instance);
+	
+      } else {
+	// couldn't start the http server, 
+	// deinit netio and unload winsock
+	CleanUpNetIO();
+	d_UnloadWinsock();
+      }
+      
+    } else {
+      // couldn't init netio, unload winsock
+      d_UnloadWinsock();
+    }
+    
+  } else {
+    // couldn't load winsock
+    err = WSASYSNOTREADY;
+  }
+  
+  return err;
+}
+
+
+// inits all the network functionality
+// returns 0 if an unrecoverable error occurred,
+// and 1 if everything successfully initialised.
+int initnetwork (HANDLE Instance, HWND MsgWindow) {
+  OSVERSIONINFO osver;
+  
+  // get the operating system information
+  memset(&osver, 0, sizeof(OSVERSIONINFO));
+  osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+  GetVersionEx(&osver);
+  
+  // first try to initialise the network with system installed
+  // networking software
+  startbrowserdir[0] = '\0';
+  netscapeneeded = 0;
+  int err = 1;
+  if (init_type == 1) err = tryinitnetwork (Instance, MsgWindow, NULL);
+  
+  // if an error occurred, try again with billsock
+  if (err != 0) {
+    // get the path of billsock (current directory + ("net16" | "net32"))
+    char winsockpath[1024]; // HARD LIMIT!!!!
+    
+    find_location();
+    char *data_location_c = data_location.getcstr();
+    strcpy (winsockpath, data_location_c);
+    delete []data_location_c;
+    
+    // remove all the slashes at the end of billpath
+    int len = strlen (winsockpath);
+    while ((len > 0) && ((winsockpath[len-1] == '\\') || (winsockpath[len-1] == '/'))) {
+      --len;
+    }
+    winsockpath[len] = '\0';
+    
+    if (osver.dwPlatformId == VER_PLATFORM_WIN32s)
+      strcat (winsockpath, "\\net16\\");
+    else {
+      strcat (winsockpath, "\\net32\\");
+      strcpy (startbrowserdir, winsockpath);
+    }
+    
+    // try again
+    err = tryinitnetwork (Instance, MsgWindow, winsockpath);
+    
+    if (err == 0) {
+      // we will need to use netscape on 95/98/NT machines
+      if (osver.dwPlatformId != VER_PLATFORM_WIN32s) {
+	netscapeneeded = 1;
+	// make sure the browser state is in step with the network condition
+	gsdl_check_browser_settings (netscapeneeded);
+      }
+      
+      // check to see if a browser is running
+      if (browserrunning(gsdl_browser_exe) == NO_ERROR) {
+	MessageBox (NULL, 
+		    "The Greenstone Digital Library software has detected a\n"
+		    "running browser. To let our networking software\n"
+		    "correctly initialize, please shut down your browser\n"
+		    "and restart the Greenstone Digital Library software.",
+		    "Greenstone Digital Library Software", MB_OK|MB_APPLMODAL);
+	PostMessage(MsgWindow,WM_CLOSE,0,0);
+	finish_up(false); // will unload winsock
+	exit(0);      // nothing more to do
+      }
+    }
+  }
+  
+  // if an error occurred display a nice error message
+  if (err != 0) {
+    
+    // WSASYSNOTREADY	Couldn't load winsock
+    // WSAVERNOTSUPPORTED	The version of Windows Sockets support requested 
+    //			is not provided by this particular Windows Sockets implementation.
+    // WSAEINVAL	The Windows Sockets version specified by the application 
+    //			is not supported by this DLL.
+    // WSAEPROTONOSUPPORT	The specified protocol is not supported.
+    // WSAEPROTOTYPE	The specified protocol is the wrong type for this socket.
+    // WSAESOCKTNOSUPPORT	The specified socket type is not supported in 
+    //		this address family.
+    // WSANOTINITIALISED	A successful WSAStartup must occur before 
+    //		using this function.
+    // WSAENETDOWN	The Windows Sockets implementation 
+    //		has detected that the network subsystem has failed.
+    // WSAEADDRINUSE 	The specified address 
+    //		is already in use. (See the SO_REUSEADDR socket option under setsockopt.)
+    // WSAEFAULT	The namelen argument is too small (less 
+    //		than the size of a struct sockaddr).
+    // WSAEINPROGRESS	A blocking Windows Sockets call is in progress.
+    // WSAEAFNOSUPPORT	The specified address family is not supported 
+    //		by this protocol.
+    // WSAENOBUFS	Not enough buffers available, too many connections.
+    // WSAENOTSOCK	The descriptor is not a socket.
+    // WSAEISCONN	The socket is already connected.
+    // WSAEMFILE	No more file descriptors are available.
+    // WSAEOPNOTSUPP	The referenced socket is not of a type that 
+    //		supports the listen operation.
+    
+    // get a text version of the error number
+    char errstr[256];
+    
+    switch (err) {
+    case WSASYSNOTREADY: strcpy(errstr, "WSASYSNOTREADY"); 
+      break;
+    case WSAVERNOTSUPPORTED: strcpy (errstr, "WSAVERNOTSUPPORTED");
+      break;
+    case WSAEINVAL: strcpy (errstr, "WSAEINVAL");
+      break;
+    case WSAEPROTONOSUPPORT: strcpy (errstr, "WSAEPROTONOSUPPORT");
+      break;
+    case WSAEPROTOTYPE: strcpy (errstr, "WSAEPROTOTYPE");
+      break;
+    case WSAESOCKTNOSUPPORT: strcpy (errstr, "WSAESOCKTNOSUPPORT");
+      break;
+    case WSANOTINITIALISED: strcpy (errstr, "WSANOTINITIALISED");
+      break;
+    case WSAEFAULT: strcpy (errstr, "WSAEFAULT");
+      break;
+    case WSAEAFNOSUPPORT: strcpy (errstr, "WSAEAFNOSUPPORT");
+      break;
+    case WSAENOTSOCK: strcpy (errstr, "WSAENOTSOCK");
+      break;
+    case WSAEISCONN: strcpy (errstr, "WSAEISCONN");
+      break;
+    case WSAEOPNOTSUPP: strcpy (errstr, "WSAEOPNOTSUPP");
+      break;
+    case WSAENETDOWN: strcpy (errstr, "WSAENETDOWN");
+      break;
+    case WSAEADDRINUSE: strcpy (errstr, "WSAEADDRINUSE");
+      break;
+    case WSAEINPROGRESS: strcpy (errstr, "WSAEINPROGRESS");
+      break;
+    case WSAENOBUFS: strcpy (errstr, "WSAENOBUFS");
+      break;
+    case WSAEMFILE: strcpy (errstr, "WSAEMFILE");
+      break;
+    default: sprintf (errstr, "WSA ERROR: %i", err);
+      break;
+    }
+    
+    // create a nice error message
+    char message[2048];
+    
+    switch (err) {
+    case WSAEADDRINUSE:
+      // couldn't bind socket
+      sprintf (message, "Could not find a free socket.", errstr);
+      break;
+      
+    default:
+      // cannot init winsock
+      sprintf (message, "Could not initialize the network\n"
+	       " (Reason: %s).", errstr);
+      break;
+    }
+    
+    strcat (message, "\n\n"
+	    "Please submit a bug report using the support.htm file\n"
+	    "on the CD-ROM.");
+    
+    MessageBox (NULL, message, "Greenstone Digital Library Software", MB_OK);
+  }
+  
+  return (err == 0);
+}
+
+
+void log_computer_info () {
+  char tmpstr[1024];
+  
+  // get various information about this computer
+  if (gsdl_keep_log || gsdl_show_console) {
+    // get operating system information
+    OSVERSIONINFO osver;
+    osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    
+    if (GetVersionEx(&osver)) {
+      if (osver.dwPlatformId == VER_PLATFORM_WIN32s) {
+	log_message ("Platform: win32s\n");
+      } else if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
+	log_message ("Platform: windows 95\n");
+      } else if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+	log_message ("Platform: windows NT\n");
+      }
+      
+      sprintf (tmpstr, "MajorVersion: %i\n", (int)osver.dwMajorVersion);
+      log_message(tmpstr);
+      sprintf (tmpstr, "MinorVersion: %i\n", (int)osver.dwMinorVersion);
+      log_message(tmpstr);
+      sprintf (tmpstr, "BuildNumber: %i\n", (int)osver.dwBuildNumber);
+      log_message(tmpstr);
+      sprintf (tmpstr, "CSDVersion: %s\n\n", osver.szCSDVersion);
+      log_message(tmpstr);
+    }
+    
+    // get memory information
+    MEMORYSTATUS memstatus;
+    memstatus.dwLength = sizeof(MEMORYSTATUS);
+    GlobalMemoryStatus(&memstatus);
+    
+    sprintf (tmpstr, "TotalPhys: %i Meg\n", (int)(memstatus.dwTotalPhys/1024/1024));
+    log_message (tmpstr);
+    sprintf (tmpstr, "AvailPhys: %i Meg\n", (int)(memstatus.dwAvailPhys/1024/1024));
+    log_message (tmpstr);
+    sprintf (tmpstr, "TotalPageFile: %i Meg\n", (int)(memstatus.dwTotalPageFile/1024/1024));
+    log_message (tmpstr);
+    sprintf (tmpstr, "AvailPageFile: %i Meg\n", (int)(memstatus.dwAvailPageFile/1024/1024));
+    log_message (tmpstr);
+    sprintf (tmpstr, "TotalVirtual: %i Meg\n", (int)(memstatus.dwTotalVirtual/1024/1024));
+    log_message (tmpstr);
+    sprintf (tmpstr, "AvailVirtual: %i Meg\n\n", (int)(memstatus.dwAvailVirtual/1024/1024));
+    log_message (tmpstr);
+    
+    // log the version number
+    log_message("GSDL version: " GSDL_VERSION "\n");
+  }
+  
+}
+
+// possible command line options are 
+// --location=directory (the path to GSDLHOME which defaults to the
+// directory where server.exe lives)
+// --config=file (the path to the configuration file to use which defaults
+// to GSDLHOME\llssite.cfg)
+// --cmd=init  Used to initialize the llssite.cfg file only - jmt12 18/11/2003
+static void parse_args(const text_t cmdline, text_t &location, text_t &config_file, text_t &command) {
+
+  location.clear();
+  config_file.clear();
+  command.clear(); // jmt12 18/11/2003
+
+  if (cmdline.size() < 3) return;
+
+  text_t name, val;
+  bool foundname = false;
+  text_t::const_iterator here = cmdline.begin();
+  text_t::const_iterator end = cmdline.end();
+  while (here != end) {
+    if (*here == '-' && ((here+1) != end) && (*(here+1) == '-')) {
+      ++here;
+      if (name == "location") {
+	location = val;
+      } else if (name == "config") {
+	config_file = val;
+      } else if(name == "cmd") { // jmt12 18/11/2003
+	command = val;
+      }
+      foundname = false;
+      name.clear();
+      val.clear();
+    } else if (*here == '=') {
+      foundname = true;
+    } else {
+      if (foundname) {
+	val.push_back(*here);
+      } else {
+	name.push_back(*here);
+      }
+    }
+    ++here;
+  }
+  if (name == "location") {
+    location = val;
+  } else if (name == "config") {
+    config_file = val;
+  } else if(name == "cmd") { // jmt12 18/11/2003
+    command = val;
+  }
+}
+
+
+// Tries to generate llssite.cfg from llssite.cfg.in in directory given
+// by location variable (assumes location is GSDLHOME), if llsite.cfg is missing
+void ensure_llssite_cfg(const text_t location) {
+  text_t configfile = location+"\llssite.cfg";
+  text_t configtemplate = location+"\llssite.cfg.in";
+
+  if(!file_exists (configfile)) {
+    
+    if(file_exists (configtemplate)) {
+      // try creating llssite.cfg from the template configfile llssite.cfg.in
+      // by using a straightforward copy
+      file_copy(configtemplate, configfile);
+    }
+  }
+}
+
+
+// Added code to allow for an 'init' run of the server which just creates the llssite.cfg file
+int __stdcall WinMain(HINSTANCE Instance, HINSTANCE /*PrevInstance*/, LPSTR CmdLineStr, int /*CmdShow*/) {
+  HWND MainWindow;  MSG Message;  WNDCLASS MainClass;  
+
+  // One instance of the local library server is quite enough, thank you very much
+  HWND gw = FindWindow("Greenstone Digital Library Software",
+		       "Greenstone Digital Library Software");
+  if (gw != NULL) {
+    exit(1);
+  }
+
+  // parse arguments
+  text_t location, config_file, command;
+  parse_args(CmdLineStr, location, config_file, command);
+  gsdl_conffile = config_file;
+ 
+  // Try to generate the llssite.cfg file if it's missing
+  ensure_llssite_cfg(location);
+
+  // jmt12 18/11/2003
+  if(command == "init") {
+    // init various modules
+    read_settings(0); // don't know if netscape is needed at this point
+    finish_up(true);
+    exit(0);
+  }
+
+  //Create a window class
+  MainClass.style = CS_HREDRAW | CS_VREDRAW;
+  MainClass.lpfnWndProc = WndProc;
+  MainClass.cbClsExtra = 0;
+  MainClass.cbWndExtra = 0;
+  MainClass.hInstance = Instance;
+  MainClass.hIcon     = LoadIcon(Instance, MAKEINTRESOURCE(TRAY_ICON));
+  MainClass.hCursor   = LoadCursor(NULL, IDC_ARROW);
+  MainClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+  MainClass.lpszMenuName = MAKEINTRESOURCE(Main_Menu);
+  MainClass.lpszClassName = "Greenstone Digital Library Software";
+  if (!RegisterClass(&MainClass))
+    return 0;
+  
+  
+  // Load various bitmaps
+  coltitlebitmap = LoadBitmap (Instance, MAKEINTRESOURCE(GSDL_COL_TITLE));
+  logobitmap= LoadBitmap (Instance, MAKEINTRESOURCE(GSDL_LOGO));
+  
+  // Create the main window
+  MainWindow = CreateWindow("Greenstone Digital Library Software", 
+			    "Greenstone Digital Library Software",
+			    WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
+			    WS_MINIMIZEBOX,
+			    CW_USEDEFAULT, CW_USEDEFAULT, 
+			    MAINWINDOWWIDTH + WASTEWIDTH, 
+			    MAINWINDOWHEIGHT + WASTEHEIGHT,
+			    NULL, NULL, Instance, NULL);
+  
+  text_rect.left = 0;  
+  text_rect.top = VERSIONY+VERSIONHEIGHT + 5;
+  text_rect.right = MAINWINDOWWIDTH;
+  text_rect.bottom = LOGOY-SPACERWIDTH;
+  
+  window_state = undefined_window;
+  
+  ShowWindow(MainWindow, SW_SHOW); 
+  set_location(location);
+  
+  // get ready to draw the main window
+  RECT windowRect;
+  GetClientRect (MainWindow, &windowRect);
+  HDC pdc = GetDC (MainWindow);
+  
+  // retrieve and save the text metrics
+  TEXTMETRIC tm;
+  GetTextMetrics(pdc, &tm);
+  line_spacing = tm.tmHeight + tm.tmExternalLeading;
+  GSDL_Window = MainWindow;  
+
+  // init various modules
+  read_settings (0); // don't know if netscape is needed at this point
+  
+  if (!gsdl_auto_enter) {
+    
+    // add the select version checkbox
+    Enter = CreateWindow("BUTTON",             // predefined class 
+			 "Enter Library",      // button text 
+			 WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_DEFPUSHBUTTON,  // styles 
+			 ENTERBUTTONX,         // starting x position 
+			 ENTERBUTTONY,         // starting y position 
+			 ENTERBUTTONWIDTH,     // button width 
+			 ENTERBUTTONHEIGHT,    // button height 
+			 MainWindow,           // parent window 
+			 NULL,                 // No menu 
+			 Instance, 
+			 NULL);                // pointer not needed 
+    
+//      EnterRestricted = CreateWindow("Button",                // predefined class 
+//  				   "Restricted Version",    // button text 
+//  				   WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_PUSHBUTTON,   // styles 
+//  				   ALTERNATIVEBUTTONX,      // starting x position 
+//  				   ALTERNATIVEBUTTONY,      // starting y position 
+//  				   ALTERNATIVEBUTTONWIDTH-(INFOBUTTONWIDTH+SPACERWIDTH),  // button width 
+//  				   ALTERNATIVEBUTTONHEIGHT, // button height 
+//  				   MainWindow,              // parent window 
+//  				   (HMENU)NULL,             // No menu 
+//  				   Instance, 
+//  				   NULL);                   // pointer not needed 
+    
+//      InfoRestricted = CreateWindow("Button",                // predefined class 
+//  				  NULL,
+//  				  WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_BITMAP,   // styles 
+//  				  ALTERNATIVEBUTTONWIDTH-INFOBUTTONWIDTH+SPACERWIDTH, // starting x position 
+//  				  ALTERNATIVEBUTTONY,      // starting y position 
+//  				  INFOBUTTONWIDTH,         // button width 
+//  				  ALTERNATIVEBUTTONHEIGHT, // button height 
+//  				  MainWindow,              // parent window 
+//  				  (HMENU)NULL,             // No menu 
+//  				  Instance, 
+//  				  NULL);                   // pointer not needed 
+    
+//      HANDLE i_icon = LoadImage (Instance, MAKEINTRESOURCE(GSDL_ICBMP), IMAGE_BITMAP, 
+//  			       INFOBUTTONWIDTH-4, ALTERNATIVEBUTTONHEIGHT-4, LR_DEFAULTCOLOR);
+//      SendMessage (InfoRestricted, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)i_icon);
+    
+    SetFocus (Enter);
+        
+    // Since we have not entered the library yet, set the URL in the configfile to pending state
+    gsdl_url = "URL_pending";
+    write_settings(gsdl_url);
+
+    enterstring = strenterlib;
+    paint_window (pdc, windowRect);
+    
+    // message loop for init buttons
+    while (!init_done) {
+      if (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) {
+	if (Message.message == WM_QUIT) return Message.wParam;
+	if (!IsDialogMessage (MainWindow, &Message)) {
+	  TranslateMessage(&Message); /* translate keyboard messages */
+	  DispatchMessage(&Message);  /* return control to Windows NT */
+	}
+      } else {
+	Sleep (1);
+      }
+    }
+    
+    // don't want these buttons anymore
+    DestroyWindow (Enter);
+    // DestroyWindow (EnterRestricted);
+    // DestroyWindow (InfoRestricted);
+    
+    enterstring = strnothing;
+    paint_window (pdc, windowRect);
+    
+  } else {
+    // auto enter is enabled - start up standard version
+    init_type = 1;
+    init_done = 1;
+  }
+  
+  // draw the main window containing an init message
+  infostring = strinit;
+  paint_window (pdc, windowRect);
+  DWORD lastcheck = GetTickCount();
+  
+  have_networking = initnetwork (Instance, MainWindow);
+  if (!have_networking) {
+    MessageBox(NULL,
+	       "Failed to initialize networking.",
+	       "Greenstone Digital Library Software",MB_OK|MB_SYSTEMMODAL);	
+    exit (0);
+  }
+
+  if (!gsdl_init()) // quit if can't initialise the library correctly
+    exit (0);
+  initstartbrowser();
+  log_computer_info ();
+  
+  // show the initialising message for at least 1 second
+  while (DiffTickCounts (lastcheck, GetTickCount()) < 1000) {
+    Sleep (1);
+  }
+  
+  // attempt to start a browser
+  if (gsdl_show_console || !gsdl_start_browser) infostring = strnothing;
+  else infostring = strsb;
+  paint_window (pdc, windowRect);
+  lastcheck = GetTickCount();
+  if (enter_library (MainWindow) && !gsdl_show_console) {
+    // stay maximised for at least 1 second
+    while (DiffTickCounts (lastcheck, GetTickCount()) < 1000) Sleep (1);
+    ShowWindow(MainWindow,SW_MINIMIZE);
+  }
+  
+  // add the "restart library" button
+  GoButton = CreateWindow("BUTTON",              // predefined class 
+			  "Restart Library",     // button text 
+			  WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // styles 
+			  RESTARTBUTTONX,        // starting x position 
+			  RESTARTBUTTONY,        // starting y position 
+			  RESTARTBUTTONWIDTH,    // button width 
+			  RESTARTBUTTONHEIGHT,   // button height 
+			  MainWindow,            // parent window 
+			  NULL,                  // No menu 
+			  Instance, 
+			  NULL);                 // pointer not needed 
+  
+  infostring = strrestartlib;
+  paint_window (pdc, windowRect);
+  
+  // release the DC used to display the init messages
+  ReleaseDC (MainWindow, pdc);
+  
+  //Message loop
+  lastcheck = GetTickCount();
+  int seenbrowser = 0;	// if we see a browser then it disappears
+                        // we will ask if they want to close the
+                        // the library down
+  char last_gsdl_browser_exe[MAX_FILENAME_SIZE]; // need to notice when the
+                                                 // browser setting changes
+  strcpy (last_gsdl_browser_exe, gsdl_browser_exe);
+  
+  for (;;) {
+    if (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) {
+      if (Message.message == WM_QUIT) break;
+      if (!IsDialogMessage (MainWindow, &Message)) {
+	TranslateMessage(&Message); /* translate keyboard messages */
+	DispatchMessage(&Message);  /* return control to Windows NT */
+      }
+      
+    } else {
+      if (DiffTickCounts (lastcheck, GetTickCount()) > 500) {
+	// make sure the browser hasn't changed
+	if (strcmp (last_gsdl_browser_exe, gsdl_browser_exe) != 0) {
+	  seenbrowser = 0;
+	  strcpy (last_gsdl_browser_exe, gsdl_browser_exe);
+	}
+	
+	// do check
+	lastcheck = GetTickCount();
+	if (gsdl_start_browser && browserrunning(gsdl_browser_exe) == NO_ERROR) {
+	  // we were able to connect to a browser
+	  seenbrowser = 1;
+	  
+	  // see if the enter library button has been pressed
+	  // with nothing happening for 20 seconds
+	  if ((enterlib_libaccessnum >= 0) && 
+	      (enterlib_libaccessnum == libaccessnum) &&
+	      (DiffTickCounts (enterlib_time, GetTickCount()) > 20000)) {
+	    // something could be wrong!! (most likely cause is a proxy)
+	    MessageBox(NULL,
+		       "Your browser does not seem to be responding to the 'Enter Library'\n"
+		       "request. Try turning off all proxy servers in your browser settings.\n"
+		       "If you are using Internet Explorer make sure BOTH dialup settings\n"
+		       "AND LAN settings have their proxy servers disabled.",
+		       "Greenstone Digital Library Software",MB_OK|MB_SYSTEMMODAL);
+	    enterlib_libaccessnum = -1;
+	  }
+	  
+	  
+	} else {
+	  // no browser was found
+	  
+	  if (seenbrowser) {
+	    // we have seen a browser in the past
+	    if (MessageBox(NULL,
+			   "The Greenstone Digital Library software has noticed that you\n"
+			   "shut down your browser. Would you also like to shut down the\n"
+			   "Greenstone Digital Library software?",
+			   "Greenstone Digital Library Software",MB_YESNO|MB_SYSTEMMODAL) == IDYES)
+	      PostMessage(MainWindow,WM_CLOSE,0,0);
+	  }
+	  seenbrowser = 0;
+	}
+      }
+      
+      Sleep (1); // millisecond
+    }
+  }
+  
+  return Message.wParam;
+}
+
Index: /gsdl/stable/runtime-src/src/w32server/httpreq.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/httpreq.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/httpreq.cpp	(revision 20131)
@@ -0,0 +1,487 @@
+/**********************************************************************
+ *
+ * httpreq.cpp
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#include "httpreq.h"
+#include "parse.h"
+#include "netio.h"
+#include "settings.h"
+#include "httpsrv.h"
+#include "httpsend.h"
+#include "cgiwrapper.h"
+#include "d_winsock.h"
+
+/*
+Implementation Notes:
+
+HTTP field names, method and version strings are converted to upper case
+right after being read from the client in order to allow case insensitive
+string comparisons to be done on them.  Since these fields are worked with a
+lot, this should help performance.
+*/
+
+//Private Data and declarations
+#define IO_BUFFER_SIZE 16384        //16K IO Buffer
+#define MAX_HTTP_LINE_LEN 1024      //Max length of line in a header of 1024
+
+//Private Function Declarations with Return Contstants
+
+/*
+Function Name: DispatchRequest
+Purpose: Manages having the request parsed, then sent to the right function
+         to send a response or handle an error.
+Parameters:
+         ClientSocket - Socket the client is on
+	 ClientSockAddr - Address of client
+	 AddrLen - Length of address of client
+	 IOBuffer - Pointer to buffer allocated for IO operations
+	 ThreadNum - Number of thread that called this function for debugging purposes
+Notes:   I'm still playing with the keep alive support.  I commented out
+	 the stuff for giving a client a timeout because I was unable to detect
+	 disconnects.
+More Notes: Not sure if this organization will allow me to easily add support
+	    for ISAPI filter DLLs.
+*/
+void DispatchRequest(SOCKET ClientSocket, SOCKADDR_IN ClientSockAddr, int AddrLen, BYTE *IOBuffer);
+
+/*
+Function Name: Get HTTP Headers
+Purpose: Manages having the request parsed, then sent to the right function
+         to send a response or handle an error.
+Parameters:
+	RequestInfo - Request information structure (see httpreq.h)
+	RequestFields - HTTP request fields structure (see httpreq.h)
+Returns: GH_ERROR on error (diconnect, bad data, Windows in a bad mood, etc.)
+			GH_UNKNOWN_VERSION if the version number is not HTTP/0.9 or HTTP/1.x
+			GH_SIMPLE_REQUEST on a properly formated HTTP/0.9 request
+			GH_10_REQUEST on a properly formated HTTP/1.x request
+*/
+int GetHTTPHeaders(RequestInfoT &RequestInfo, RequestFieldsT &RequestFields);
+#define GH_BAD_METHOD	   -2
+#define GH_ERROR           -1
+#define GH_UNKNOWN_VERSION  0
+#define GH_SIMPLE_REQUEST   1
+#define GH_10_REQUEST       2
+
+/*
+Function Name: Clean Up HTTP Headers
+Purpose: Cleans up memory dynamicly allocated for headers
+Parameters:
+	RequestInfo - Request information structure (see httpreq.h)
+	RequestFields - HTTP request fields structure (see httpreq.h)
+Returns: Nothing
+*/
+void CleanUpHTTPHeaders(RequestInfoT &RequestInfo, RequestFieldsT &RequestFields);
+
+/*
+Function Name: Split Query
+Purpose: Splits the file and query part of a URI.  In other words, it
+	 puts the parts before and after the "?" in differnet strings.
+Parameters:
+	 URIStr - The requested URI
+	 FileStr - String to contain the name of the path + file part of the URI
+	 QueryStr - String to contain the query part of the URI
+Returns: TRUE if there is a query, else FALSE
+*/
+BOOL SplitQuery(char *URIStr, char *FileStr, char *QueryStr, int ThreadNum);
+
+/*
+Function Name: Get File
+Purpose: Attempts to find a given file, including looking for index.html.
+	 Updates the given URI string so it points to the true document location
+Parameters:
+	 FilePath - Path of file, may be modified to best reflect the retrived file
+				  or directory
+	 URIStr - URI string, minus the query
+Returns: GF_ERROR on error
+			GF_FILE_FOUND on success
+			GF_INDEX_FOUND if file is a directory with an index.html file in it
+			GF_DIRECTORY if file is a directory
+			GF_FILE_NOT_FOUND if file was found
+*/
+
+/*
+Function Name: Process Simple Request
+Purpose: Sends a reply to a HTTP 0.9 "simple" request
+Parameters:
+	ClientSocket - Socket the client is on
+	RequestInfo - Structure storing the parsed headers
+	IOBuffer - Pointer to buffer allocated for IO operations
+	TheadNum - Number of calling thread for debugging
+Notes: I should really test this and see if it works...
+*/
+void ProcessSimpleRequest(RequestInfoT &RequestInfo, RequestFieldsT &RequestFields);
+
+//Public Functions
+/******************************************************************************/
+void RequestThread(RequestThreadMessageT *Parameters) {
+  SOCKADDR_IN ClientSockAddr;
+  SOCKET ClientSocket;
+  int AddrLen;
+  //Allocate an IO buffer for this thread
+  BYTE *IOBuffer = new BYTE[IO_BUFFER_SIZE];
+
+  //Get the parameters for the request
+  ClientSocket = Parameters->ClientSocket;
+  ClientSockAddr = Parameters->ClientSockAddr;
+  AddrLen = Parameters->AddrLen;
+  DispatchRequest(ClientSocket, ClientSockAddr, AddrLen, IOBuffer);
+}
+/******************************************************************************/
+
+//Private Functions
+
+/******************************************************************************/
+void DispatchRequest(SOCKET ClientSocket, SOCKADDR_IN ClientSockAddr, int AddrLen,  BYTE *IOBuffer) {
+  RequestInfoT RequestInfo;
+  RequestFieldsT RequestFields;
+
+  // TrayAddConnection();
+
+  //Setup the RequestInfo structure
+  memset(&RequestInfo, 0, sizeof(RequestInfoT));
+  RequestInfo.ThreadNum = 0;
+  RequestInfo.IOBuffer = IOBuffer;
+  RequestInfo.IOBufferSize = IO_BUFFER_SIZE;
+  RequestInfo.ClientSocket = ClientSocket;
+  RequestInfo.ClientSockAddr = ClientSockAddr;
+  RequestInfo.AddrLen = AddrLen;
+  RequestInfo.KeepAlive = FALSE;
+  
+  int GetHeadersResult;
+  do {
+    //Get Headers
+    GetHeadersResult = GetHTTPHeaders(RequestInfo, RequestFields);
+
+    //Figure out what version we're dealing with and deal with it
+    switch (GetHeadersResult) {
+    case GH_SIMPLE_REQUEST :
+      SendHTTPError(400, "HTTP Request not supported", "Only 1.x requests supported", RequestInfo, RequestFields);
+      // TrayIncNumServed();
+      break;
+    case GH_10_REQUEST :
+      ExamineURIStr(RequestFields.URIStr,&RequestInfo,&RequestFields);
+      // TrayIncNumServed();
+      break;
+    case GH_UNKNOWN_VERSION :
+      SendHTTPError(400, "HTTP Version not supported", "Only 1.x requests supported", RequestInfo, RequestFields);
+      // TrayIncNumServed();
+      break;
+/* added Feb 2002 to handle stupid MS behaviour */
+    case GH_BAD_METHOD :
+      SendHTTPError(501, "Not implemented", "Only GET and POST currently implemented", RequestInfo, RequestFields);
+      break;
+    case GH_ERROR:
+      //Disconnect
+      RequestInfo.KeepAlive = FALSE;
+      break;
+    }
+    CleanUpHTTPHeaders(RequestInfo, RequestFields);
+  } while (0/*RequestInfo.KeepAlive == TRUE*/);
+  //Close connection
+  CloseSocket(RequestInfo.ClientSocket);
+  // TrayRemoveConnection();
+}
+
+void resetRequestFieldsT(RequestFieldsT& RequestFields)
+{
+  // Can't just 'memset' the text_t fields (as used to be done),
+  // as this could lead to inconsistent state in text_t fields
+  // ultimately resulting in a segmentation fault
+  // => need to go through an explicitly reset them
+
+  //Simple request line info v0.9
+  RequestFields.MethodStr.clear();
+  RequestFields.URIStr.clear();
+  //added v1.0
+  RequestFields.VersionStr.clear();
+  //General Header
+  RequestFields.DateStr.clear();
+  RequestFields.MIMEVerStr.clear();
+  RequestFields.PragmaStr.clear();
+  //Request Header
+  RequestFields.AuthorizationStr.clear();
+  RequestFields.FromStr.clear();
+  RequestFields.IfModSinceStr.clear();
+  RequestFields.RefererStr.clear();
+  RequestFields.UserAgentStr.clear();
+  //Entity Header (Only CGI stuff)
+  RequestFields.ContentEncodingStr.clear();
+  RequestFields.ContentTypeStr.clear();
+  RequestFields.ContentLengthStr.clear();
+  //v1.0 Optional (the more common ones)
+  RequestFields.AcceptStr.clear();
+  RequestFields.AcceptLangStr.clear();
+  //v1.1 Exentions
+  RequestFields.ConnectionStr.clear();
+  
+  //Reset all the non text_t fields 
+  RequestFields.ContentLength = 0;
+  RequestFields.Content = NULL;
+  RequestFields.NumOtherHeaders = 0;
+ 
+  for (int i=0 ; i<MAX_OTHER_HEADERS; i++) {
+	RequestFields.OtherHeaders[i].Var.clear();
+	RequestFields.OtherHeaders[i].Val.clear();
+  }
+}
+
+/******************************************************************************/
+int GetHTTPHeaders(RequestInfoT &RequestInfo, RequestFieldsT &RequestFields) {
+  //Parsing and IO buffers
+  text_t CurLine;
+  text_t NextLine;
+  text_t FieldNameStr;
+  text_t FieldValStr;
+  
+  //Parsing and IO working vars
+  int ReadBufferIndex;
+  int DataInBuffer;
+  text_t::const_iterator next;
+  text_t::const_iterator end;
+
+  resetRequestFieldsT(RequestFields);
+
+  ReadBufferIndex = 0;
+  DataInBuffer = 0;
+  
+  //Get First Line
+  if (GetLine(CurLine, RequestInfo.ClientSocket, RequestInfo.IOBuffer,
+	      RequestInfo.IOBufferSize, ReadBufferIndex, DataInBuffer,
+	      RequestInfo.ThreadNum) != 0) return GH_ERROR;
+  do {//Get Next Line, append it if the first charactor is space
+    if(GetLine(NextLine, RequestInfo.ClientSocket, RequestInfo.IOBuffer,
+	       RequestInfo.IOBufferSize, ReadBufferIndex, DataInBuffer,
+	       RequestInfo.ThreadNum) != 0) return GH_ERROR;
+    if ((*(NextLine.begin()) == ' ') || (*(NextLine.begin()) == '\t')) {
+      CurLine += NextLine;
+    }
+  } while ((*(NextLine.begin()) == ' ') || (*(NextLine.begin()) == '\t'));
+  //Method String (first word)
+  GetWord(RequestFields.MethodStr, CurLine.begin(), CurLine.end(), next);
+  uc(RequestFields.MethodStr);
+
+  /* Added Feb 2002 - IE since about version 5 send stupid frontpage requests
+     for MS Document formats eg "GET /_vti_inf.html" */ 
+  if (RequestFields.MethodStr == "OPTIONS") {
+    return GH_BAD_METHOD;
+  } 
+  //Version String (last word)
+  GetLastWord(RequestFields.VersionStr, CurLine.begin(), CurLine.end(), end);
+  uc(RequestFields.VersionStr);
+  text_t::const_iterator versionbegin = RequestFields.VersionStr.begin();
+
+  if ((RequestFields.VersionStr.size() > 5) && (substr(versionbegin, versionbegin+5) != "HTTP/")) {
+    //No version, assume simple request
+    //part after method is URI
+    RequestFields.URIStr = CurLine;
+    return GH_SIMPLE_REQUEST;
+  }
+
+  //URI String (in between End of first and Start of last)
+  //<Method> <WhiteSpace> <URI> <WhiteSpace> <Version> <CRLF>
+  //                  next^             end^
+  text_t spacebuffer;
+  text_t::const_iterator here = next;
+  while (here != end) {
+    // do this to remove trailing space
+    if (*here == ' ' || *here == '\t') {
+      spacebuffer.push_back(*here);
+    } else {
+      if (!spacebuffer.empty()) {
+	RequestFields.URIStr += spacebuffer;
+	spacebuffer.clear();
+      }
+      RequestFields.URIStr.push_back(*here);
+    }
+    ++here;
+  }
+
+  //Only accept requests from HTTP/0.9 or HTTP/1.X clients, we'll
+  //assume that anything else will require an upgrade or patch
+  if ((RequestFields.VersionStr.size() > 7) && (substr(versionbegin, versionbegin+7) != "HTTP/1.")) {
+    return GH_UNKNOWN_VERSION;
+  }
+  
+  //Get the rest of the lines
+  CurLine = NextLine;
+  
+  while (!CurLine.empty()) {//Blank Line, we're done
+    do {//Get Next Line, append it if the first charactor is space
+      if (GetLine(NextLine, RequestInfo.ClientSocket, RequestInfo.IOBuffer,
+		  RequestInfo.IOBufferSize, ReadBufferIndex, DataInBuffer,
+		  RequestInfo.ThreadNum) != 0)
+	return GH_ERROR;
+      if (NextLine.empty())
+	break;
+      if ((*(NextLine.begin()) == ' ') || (*(NextLine.begin()) == '\t')) {
+	CurLine += NextLine;
+      }
+    } while ((*(NextLine.begin()) == ' ') || (*(NextLine.begin()) == '\t'));
+    
+    GetWord(FieldNameStr, CurLine.begin(), CurLine.end(), next);
+    uc(FieldNameStr);
+    
+    FieldValStr = substr(next, CurLine.end());
+    
+    //Process it
+    //In order of expected commonality
+    //All constants are in canonized, thus in upper case and case sensitive
+    //comparisons are used
+
+    //--Just About Always--
+    if (FieldNameStr == "ACCEPT:") {
+      if (!RequestFields.AcceptStr.empty()) {
+	RequestFields.AcceptStr += ", ";
+      }
+      RequestFields.AcceptStr += FieldValStr;
+    }
+    else if (FieldNameStr == "DATE:") {
+      RequestFields.DateStr = FieldValStr;
+    }
+    else if (FieldNameStr == "USER-AGENT:") {
+      RequestFields.UserAgentStr = FieldValStr;
+    }
+    else if (FieldNameStr == "CONNECTION:") {
+      RequestFields.ConnectionStr = FieldValStr;
+    }
+    //--Sometimes--
+    else if (FieldNameStr == "ACCEPT-LANGUAGE:") {
+      RequestFields.AcceptLangStr = FieldValStr;
+    }
+    else if (FieldNameStr == "REFERER:") {
+      RequestFields.RefererStr = FieldValStr;
+    }
+    else if (FieldNameStr == "IF-MODIFIED-SINCE:") {
+      RequestFields.IfModSinceStr = FieldValStr;
+    }
+    //--Uncommon--
+    else if (FieldNameStr == "FROM:") {
+      RequestFields.FromStr = FieldValStr;
+    }
+    else if (FieldNameStr == "MIME-VERSION:") {
+      RequestFields.MIMEVerStr = FieldValStr;
+    }
+    else if (FieldNameStr == "PRAGMA:") {
+      RequestFields.PragmaStr = FieldValStr;
+    }
+    //--Special case--
+    else if (FieldNameStr == "AUTHORIZATION:") {
+      RequestFields.AuthorizationStr = FieldValStr;
+    }
+    else if (FieldNameStr == "CONTENT-LENGTH:") {
+      RequestFields.ContentLengthStr = FieldValStr;
+    }
+    else if (FieldNameStr == "CONTENT-TYPE:") {
+      RequestFields.ContentTypeStr = FieldValStr;
+    }
+    else if (FieldNameStr == "CONTENT-ENCODING:") {
+      RequestFields.ContentEncodingStr = FieldValStr;
+    }
+    else if (!FieldNameStr.empty()) {
+      //Add it to the other headers
+
+      //Remove the colon
+      if (*(FieldNameStr.end()-1) == ':') {
+	FieldNameStr.pop_back();
+      }
+      RequestFields.OtherHeaders[RequestFields.NumOtherHeaders].Var = FieldNameStr;
+      RequestFields.OtherHeaders[RequestFields.NumOtherHeaders].Val = FieldValStr;
+      ++RequestFields.NumOtherHeaders;
+    }
+    CurLine = NextLine;
+  }
+  
+  if (!RequestFields.ContentLengthStr.empty()) { //Do we have attached data?
+    unsigned int NumRecv;
+    
+    RequestFields.ContentLength = RequestFields.ContentLengthStr.getint();
+    if (RequestFields.ContentLength > 0) {
+
+      //Allocate memory
+      RequestFields.Content = new BYTE[RequestFields.ContentLength];
+      
+      //Get rest of data from get lines
+      NumRecv = DataInBuffer - ReadBufferIndex;
+      
+      if (NumRecv >RequestFields.ContentLength) {
+	//Overflow, only read what they said they'd send
+	NumRecv = RequestFields.ContentLength;
+      }
+      memcpy(RequestFields.Content, RequestInfo.IOBuffer + ReadBufferIndex,
+	     NumRecv);
+      
+      while (NumRecv < RequestFields.ContentLength) {
+	NumRecv += GetData(RequestInfo.ClientSocket,
+			   RequestFields.Content + NumRecv,
+			   RequestFields.ContentLength - NumRecv,
+			   RequestInfo.ThreadNum);
+	if (NumRecv < 0) return GH_ERROR;
+      }
+
+      // It seems to be important on NT that all available data was read
+      // from the socket before the socket is closed (otherwise netscape
+      // throws a "connection reset by peer" error). Since netscape seems
+      // to send a few extra bytes in certain situations we'll make sure we
+      // slurp it all up here.
+      char *tmpbuffer = new char[100]; // this had new char(100)????
+      //      unsigned long int nonblockmode=1;
+      //      ioctlsocket(RequestInfo.ClientSocket, FIONBIO, &nonblockmode);
+      d_recv(RequestInfo.ClientSocket, tmpbuffer, 100, 0);
+      delete []tmpbuffer;
+
+    }
+    else {
+      RequestFields.Content = NULL;
+      RequestFields.ContentLength = 0;
+    }
+  }
+  else {
+    RequestFields.Content = NULL;
+    RequestFields.ContentLength = 0;
+  }
+  
+  return GH_10_REQUEST;
+}
+
+/******************************************************************************/
+void CleanUpHTTPHeaders(RequestInfoT &RequestInfo, RequestFieldsT &RequestFields) {
+  //Clean up memory allocated for the Content
+  if (RequestFields.Content != NULL) {
+    delete[] RequestFields.Content;
+  }
+  
+  // clean up memory allocated for the IOBuffer
+  if (RequestInfo.IOBuffer != NULL) {
+    delete[] RequestInfo.IOBuffer;
+    RequestInfo.IOBuffer = NULL;
+  }
+}
Index: /gsdl/stable/runtime-src/src/w32server/httpreq.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/httpreq.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/httpreq.h	(revision 20131)
@@ -0,0 +1,161 @@
+/**********************************************************************
+ *
+ * httpreq.h
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef HTTPREQ_H
+#define HTTPREQ_H
+
+// need this to avoid bizarre compiler problems under VC++ 6.0
+#if !defined (GSDL_NAMESPACE_BROKEN) && !defined (GSDL_USE_IOS_H)
+# include <iostream>
+# include <fstream>
+using namespace std;
+#endif
+
+#include "locate.h"
+#include "text_t.h"
+
+/*
+Module Name: HTTP Request
+Purpose: Parses HTTP requests and then calls the appropriate function
+	to respond to the request
+Public Functions:
+	Request Thread
+*/
+
+// Public Data Structures
+
+//Used for sending information to the request thread
+struct RequestThreadMessageT {
+  SOCKADDR_IN ClientSockAddr;
+  SOCKET ClientSocket;
+  int AddrLen;
+};
+
+#define MAX_OTHER_HEADERS 100
+
+struct RequestHeaderT {
+  text_t Var;
+  text_t Val;
+
+  RequestHeaderT() 
+  : Var(), Val()
+  {}
+};
+
+struct RequestFieldsT {
+  //Simple request line info v0.9
+  text_t MethodStr;
+  text_t URIStr;
+  //added v1.0
+  text_t VersionStr;
+  //General Header
+  text_t DateStr;
+  text_t MIMEVerStr;
+  text_t PragmaStr;
+  //Request Header
+  text_t AuthorizationStr;
+  text_t FromStr;
+  text_t IfModSinceStr;
+  text_t RefererStr;
+  text_t UserAgentStr;
+  //Entity Header (Only CGI stuff)
+  text_t ContentEncodingStr;
+  text_t ContentTypeStr;
+  text_t ContentLengthStr;
+  //v1.0 Optional (the more common ones)
+  text_t AcceptStr;
+  text_t AcceptLangStr;
+  //v1.1 Exentions
+  text_t ConnectionStr;
+  //Pointer to buffer containing the content
+  DWORD ContentLength;
+  BYTE *Content;
+  
+  //Other Headers
+  int NumOtherHeaders;
+  RequestHeaderT OtherHeaders[MAX_OTHER_HEADERS];
+
+  RequestFieldsT()
+  : MethodStr(), URIStr(), VersionStr(), DateStr(), MIMEVerStr(),
+    PragmaStr(), AuthorizationStr(), FromStr(), IfModSinceStr(),
+    RefererStr(), UserAgentStr(), ContentEncodingStr(),
+    ContentTypeStr(), ContentLengthStr(), AcceptStr(),
+    AcceptLangStr(), ConnectionStr(),
+	OtherHeaders()
+  {
+    ContentLength = 0;
+	Content = NULL;
+	NumOtherHeaders = 0;
+  }
+
+};
+
+struct RequestInfoT {
+  int ThreadNum;
+  
+  //Buffer for IO operations (so we're not constantly reallocating buffers)
+  BYTE *IOBuffer;
+  int IOBufferSize;
+  
+  //Socket the request is on and its address
+  SOCKET ClientSocket;
+  SOCKADDR_IN ClientSockAddr;
+  int AddrLen;
+  
+  //Should we keep the connection alive?
+  BOOL KeepAlive;
+};
+
+
+// Public Functions
+
+/*
+Function Name: RequestThread
+Purpose: Was the HTTP request processing thread
+         Now just a standard procedure called to process a request
+Parameters:
+	       Pointer to packed parameter structure
+*/
+void RequestThread(RequestThreadMessageT *Parameters);
+
+/*
+Function Name: Process 1.0 Request
+Purpose: Sends a HTTP 1.0 (plus some) reply to a HTTP 1.x request
+Parameters:
+	ClientSocket - Socket the client is on
+	ClientSockAddr - Address of client
+	AddrLen - Length of client address
+	RequestInfo - Structure storing the parsed headers
+	KeepAlive - To be set to true if we are maintainig the connection
+	IOBuffer - Pointer to buffer allocated for IO operations
+	TheadNum - Number of calling thread for debugging
+Notes: The function uses "Connection: Keep-Alive" as written in the HTTP/1.1
+	draft and implemented by Netscape and MSIE
+*/
+void Process10Request(RequestInfoT &RequestInfo, RequestFieldsT &RequestFields);
+
+#endif
Index: /gsdl/stable/runtime-src/src/w32server/httpsend.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/httpsend.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/httpsend.cpp	(revision 20131)
@@ -0,0 +1,109 @@
+/**********************************************************************
+ *
+ * httpsend.cpp
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "text_t.h"
+
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#pragma hdrstop
+#include "netio.h"
+#include "httpreq.h"
+#include "httpsend.h"
+
+//Private Function Declarations
+/*
+Function Name: Check IMS Date
+Purpose: Checks the string date of an "If Modified Since" header against
+	a file date stamp.
+Parameters:
+	FileTime - Time stamp on file
+	IMSStr - "If Modified Since" date string
+Returns: TRUE if the file has been modified since the given date or
+	the data can not be resolved (the string to date function will log
+	any errors)
+*/
+BOOL CheckIMSDate(SYSTEMTIME &FileTime, char *IMSStr);
+
+//Public Functions
+/******************************************************************************/
+
+void SendHTTPError(int ErrorNum, char *ErrorTitleStr, char *ErrorDescStr, 
+		   RequestInfoT &RequestInfo, RequestFieldsT &RequestFields) {
+  char Header[512];
+  char Body[512];
+
+  char ErrorNumStr[17];
+  
+  DWORD BodyLength;
+  char BodyLengthStr[17];
+
+  int HeaderLength;
+  
+  itoa(ErrorNum, ErrorNumStr, 10);
+  
+  // Didn't find it, build the message manually
+  Body[0] = 0;
+  strcat(Body, "<HTML><HEAD><TITLE>Server Error</TITLE></HEAD><BODY>\n");
+  strcat(Body, "<H1>Error ");
+  strcat(Body, ErrorNumStr);
+  strcat(Body, ": ");
+  strcat(Body, ErrorTitleStr);
+  strcat(Body, "</H1>\n");
+  strcat(Body, ErrorDescStr);
+  strcat(Body, "\n</BODY></HTML>");
+  BodyLength = (DWORD) strlen(Body);
+
+  //Build Header
+  Header[0] = 0;
+  //Status Line
+  strcat(Header, "HTTP/1.0 ");
+  strcat(Header, ErrorNumStr);
+  strcat(Header, " ");
+  strcat(Header, ErrorDescStr);
+  strcat(Header, "\r\n");
+  //Server
+  strcat(Header, "Server: GSDL\r\n");
+  //Content Type (assume HTML)
+  strcat(Header, "Content-Type: text/html\r\n");
+  //Content Length
+  itoa(BodyLength, BodyLengthStr, 10);
+  strcat(Header, "Content-Length: ");
+  strcat(Header, BodyLengthStr);
+  strcat(Header, "\r\n");
+  //Single CRLF to end header
+  strcat(Header, "\r\n");
+  
+  HeaderLength = strlen(Header);
+  
+  //Send header
+  SendData(RequestInfo.ClientSocket, (BYTE *) Header, strlen(Header), RequestInfo.ThreadNum);
+  //Send generated data
+  SendData(RequestInfo.ClientSocket, (BYTE *) Body, BodyLength, RequestInfo.ThreadNum);
+}
Index: /gsdl/stable/runtime-src/src/w32server/httpsend.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/httpsend.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/httpsend.h	(revision 20131)
@@ -0,0 +1,51 @@
+/**********************************************************************
+ *
+ * httpsend.h
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+/*
+Module Name: HTTP Send
+Purpose: Functions for sending HTTP responses to 1.X requests
+Public Functions:
+	SendHTTPError
+Notes: Considering adding a version number parameter to these functions.  Right
+	now the way people are implementing HTTP/1.1 is by adding the new stuff
+	to 1.0 requests.  I don't know of any browsers sending 1.1 requests yet.
+*/
+
+/*
+Function Name: Send HTTP Error
+Purpose: Sends a given error message to the client with either the error file
+			as a body or a default error message body.  Common and refenece log
+			entries are written, but not to the count log.
+Parameters:
+	ErrorNum - HTTP error number to send
+	ErrorTitleStr - Title of the error
+	ErrorDescStr - String describing the error
+	RequestInfo - HTTP request information (see httpreq.h)
+	RequestFields - Parsed HTTP header info (see httpreq.h)
+*/
+void SendHTTPError(int ErrorNum, char *ErrorTitleStr, char *ErrorDescStr, 
+		   RequestInfoT &RequestInfo, RequestFieldsT &RequestFields);
Index: /gsdl/stable/runtime-src/src/w32server/httpsrv.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/httpsrv.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/httpsrv.cpp	(revision 20131)
@@ -0,0 +1,103 @@
+/**********************************************************************
+ *
+ * httpsrc.cpp
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "text_t.h"
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#pragma hdrstop
+#include "netio.h"
+#include "settings.h"
+#include "httpreq.h"
+#include "httpsrv.h"
+#include "locate.h"
+
+//Private Functions
+
+/*
+Function Name: HTTP Server Answer
+Purpose: Answers messages saying that a connection is ready to start
+*/
+void HTTPServerAnswer();
+
+//Module Vars
+static SOCKET ServerSocket = INVALID_SOCKET;
+
+static HWND MsgWindow;
+
+/******************************************************************************/
+// returns 0 on success, and a WSA error otherwise
+int StartHTTPServer(HWND PassedMsgWindow) {
+  
+  MsgWindow = PassedMsgWindow;
+  //Create the server socket
+  return CreateListeningSocket(gsdl_port_num, MsgWindow, HTTP_SERVER_MSG, ServerSocket);
+}
+
+/******************************************************************************/
+void EndHTTPServer()
+{
+  //Stop the listening socket
+  DestroyListeningSocket(ServerSocket, MsgWindow);
+}
+
+/******************************************************************************/
+void ProcessHTTPServerMsg(WPARAM Socket, LPARAM MsgInfo) {
+  log_message("accept message arrived\n");
+  if (Socket != ServerSocket) {
+    if (gsdl_keep_log || gsdl_show_console) log_message("Incorrect socket sent in message");
+  }
+  switch (WSAGETSELECTEVENT(MsgInfo)) {
+  case FD_ACCEPT:
+    switch (WSAGETSELECTERROR(MsgInfo)) {
+    case WSAENETDOWN:
+      LogCriticalError("1","Network Down");
+      break;
+    default: //No Error
+      HTTPServerAnswer();
+    }
+    break;
+  }
+}
+
+/******************************************************************************/
+void HTTPServerAnswer() {
+  SOCKADDR_IN ClientSockAddr;
+  SOCKET ClientSocket;
+  int AddrLen = sizeof(SOCKADDR_IN);
+  RequestThreadMessageT Parameters;
+  while (AnswerListeningSocket(ServerSocket, ClientSocket, ClientSockAddr, AddrLen) == 0) {
+    log_message("Answering socket\n");
+    //Call the thread procedure to handle the connection
+    Parameters.ClientSockAddr = ClientSockAddr;
+    Parameters.ClientSocket = ClientSocket;
+    Parameters.AddrLen = AddrLen;
+    RequestThread(&Parameters);
+  }
+}
Index: /gsdl/stable/runtime-src/src/w32server/httpsrv.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/httpsrv.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/httpsrv.h	(revision 20131)
@@ -0,0 +1,57 @@
+/**********************************************************************
+ *
+ * httpsrv.h
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#define HTTP_SERVER_MSG WM_USER + 23
+
+/*
+Function Name: Start HTTP Server
+
+Purpose: Starts the HTTP server.  Inits Winsock, MIME, loads registry
+         stuff, etc.
+
+Parameters:
+	PassedMsgWindow - The handle of the window that handles messages.  Needed
+                          to setup WSASelect notification of socket events and
+                          to send a shutdown message on error.  */
+
+// returns 0 on success, and a WSA error otherwise
+int StartHTTPServer(HWND PassedMsgWindow);
+
+/*
+Function Name: End HTTP Server
+Purpose: Ends the HTTP server.  Cleans up MIME, users, etc.
+*/
+void EndHTTPServer();
+
+/*
+Function Name: Process HTTP Server Message
+Purpose: Processes HTTP_SERVER_MSG messages.
+Parameters:
+	Socket - The socket the message is regarding (WPARAM)
+	MsgInfo - The messsage (LPARAM)
+*/
+void ProcessHTTPServerMsg(WPARAM Socket, LPARAM MsgInfo);
Index: /gsdl/stable/runtime-src/src/w32server/locate.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/locate.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/locate.cpp	(revision 20131)
@@ -0,0 +1,274 @@
+/**********************************************************************
+ *
+ * locate.cpp
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "text_t.h"
+#include <windows.h>
+#include <stdio.h>
+#include "locate.h"
+#include "settings.h"
+
+/* The following values are inserted or used by FNORD.CPP */
+HWND GSDL_Window;
+int line_spacing;
+RECT text_rect;
+
+
+static FILE *log_file=NULL;
+
+static int location_found=0;
+text_t data_location;
+
+void set_location(text_t possible)
+{
+  if (location_found != 0) return;
+  if (!possible.empty()) {
+    data_location = possible;
+    if (*(data_location.end()-1) != '\\') {
+      data_location.push_back('\\');
+    }
+    location_found = 1;
+  }
+}
+
+void find_location(void)
+{
+  if (location_found != 0) return;
+  
+  char here[MAX_FILENAME_SIZE];
+  char *send;
+
+  if (GetModuleFileName(NULL,here,MAX_FILENAME_SIZE) <= 0) {
+    // failed
+    data_location.clear();
+  } else {
+    send = strrchr(here,'\\');
+    if (send != NULL) {
+      ++send;
+    } else {
+      send = strchr(here,':');
+      if (send != NULL) {
+        ++send;
+      } else {
+        send = here;
+      }
+    }
+  }
+  *send = 0;
+  data_location.setcstr(here);
+  location_found = 1;
+}
+
+void open_log_file()
+{
+  if (log_file != NULL) fclose(log_file);
+  log_file = fopen(gsdl_log_name, "a");
+  if (log_file != NULL) {
+	  fprintf (log_file, "\n\n-----------\n");
+	  fprintf (log_file, "log started\n");
+	  fprintf (log_file, "-----------\n\n");
+  }
+}
+
+void close_log_file()
+{
+  if (log_file != NULL) {
+    fclose(log_file);
+    log_file = NULL;
+  }
+}
+
+#define CONSOLE_BUFFER_SIZE 2048
+char console_buffer[CONSOLE_BUFFER_SIZE];
+char *next_console, *last_console;
+int console_top, console_y;
+
+void activate_console(void)
+{
+  gsdl_show_console = 1;
+  next_console = console_buffer;
+  *next_console = 0;
+  last_console = next_console;
+  console_y = console_top = text_rect.top +
+    (text_rect.bottom - text_rect.top + 1) % line_spacing / 2;
+  InvalidateRect(GSDL_Window,NULL,TRUE);
+}
+
+void deactivate_console(void)
+{
+  gsdl_show_console = 0;
+  InvalidateRect(GSDL_Window,NULL,TRUE);
+}
+
+void refresh_console(HDC dc)
+{
+  int loc;  char *b, *e;
+  loc = console_top;
+  for (e = console_buffer;;) {
+    b = e;
+    while (*e >= ' ') ++e;
+    TextOut(dc,0,loc,b,e-b);
+    loc += line_spacing;
+    if (*e == 0) break;
+    ++e;
+    if (*e == 0) break;
+    }
+}
+
+void scroll(HDC dc, int nbits)
+{
+  RECT scroll, clip, update;
+
+  scroll.left = clip.left = text_rect.left;
+  scroll.right = clip.right = text_rect.right;
+  clip.top = console_top;
+  clip.bottom = text_rect.bottom;
+  scroll.top = clip.top + nbits;
+  scroll.bottom = text_rect.bottom;
+  ScrollDC(dc,0,-nbits,&scroll,&clip,NULL,&update);
+  FillRect(dc,&update, (HBRUSH)GetStockObject(WHITE_BRUSH));
+}
+
+int remove_line()
+{
+  char *bin, *bout;
+  bin = bout = console_buffer;
+  while (*bin >= ' ') ++bin;
+  if (*bin != 0) {
+    ++bin;
+    if (*bin != 0) {
+      while (*bin != 0) *bout++ = *bin++;
+      *bout = *bin;
+      last_console -= (bin - bout);
+      next_console = bout;
+      return line_spacing;
+      }
+    }
+  next_console = console_buffer;
+  *next_console = 0;
+  last_console = next_console;
+  return 0;
+}
+
+void display_line(HDC dc, char *line, int nch)
+{
+  int scroll_needed = 0;
+  while (next_console + nch + 1 
+         > console_buffer + CONSOLE_BUFFER_SIZE)
+    scroll_needed += remove_line();
+  console_y -= scroll_needed;
+  if (*last_console == '\n') {
+    console_y += line_spacing;
+    if (console_y + line_spacing > text_rect.bottom) {
+      scroll_needed += remove_line();
+      console_y -= line_spacing;
+      }
+    last_console = next_console;
+    }
+  if (scroll_needed != 0) scroll(dc, scroll_needed);
+  while (nch-- > 0) *next_console++ = *line++;
+  TextOut(dc,0,console_y,last_console,next_console-last_console);
+  *next_console = *line;
+  if (*next_console != 0) {
+    last_console = next_console;
+    ++next_console;
+    *next_console = 0;
+    }
+}
+
+void display_text(HDC dc, char *buffer)
+{
+  char *bl, *bp;
+  for (bl = buffer;;) {
+    for (bp = bl;;) {
+      if (*bp == '\t') *bp = ' ';
+      if (*bp < ' ') break;
+      ++bp;
+      }
+    if (*bp != 0) *bp = '\n';
+    display_line(dc, bl, bp-bl);
+    if (*bp == 0) break;
+    bl = bp+1;
+    if (*bl == 0) break;
+    }
+}
+
+void log_message(char *msg)
+{
+  if (log_file != NULL) {
+    fprintf(log_file,"%s",msg);
+    fflush(log_file);
+  }
+  if (gsdl_show_console) {
+    char buffer[1024];  HDC dc;
+    sprintf(buffer,"%s",msg);
+    dc = GetDC(GSDL_Window);
+    display_text(dc,buffer);
+    ReleaseDC(GSDL_Window,dc);
+  }
+}
+
+void log_message_N(char*msg, int n)
+{
+  if (log_file != NULL) {
+    int len = 0;
+    while (len < n) {
+      fputc (msg[len], log_file);
+      ++len;
+    }
+    fflush(log_file);
+  }
+  
+  // these messages are not send to the console
+  if (gsdl_show_console) {
+    HDC dc;
+    dc = GetDC(GSDL_Window);
+    display_text(dc,"message only written to log file\n");
+    ReleaseDC(GSDL_Window,dc);
+  }
+}
+
+void LogCriticalError(char *cderr, char *Msg)
+{
+  char MsgBoxStr[200];
+  
+  strcpy(MsgBoxStr, "Critical Error Number ");
+  strcat(MsgBoxStr, cderr);
+  strcat(MsgBoxStr, "\n");
+  strcat(MsgBoxStr, Msg);
+  strcat(MsgBoxStr, "\nGreenstone Digital Library software\nshutting down");
+  MessageBox(GSDL_Window, MsgBoxStr, "Greenstone Digital Library Software",
+	     MB_OK | MB_ICONERROR);
+  PostMessage(GSDL_Window, WM_DESTROY, 0, 0);
+}
+
+
+/* returns second-first taking into account wrap around */
+DWORD DiffTickCounts (DWORD first, DWORD second) 
+{
+  if (second >= first) return (second-first);
+  return (MAXDWORD-first+1+second);
+}
Index: /gsdl/stable/runtime-src/src/w32server/locate.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/locate.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/locate.h	(revision 20131)
@@ -0,0 +1,56 @@
+/**********************************************************************
+ *
+ * locate.h
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef MAX_FILENAME_SIZE
+#define MAX_FILENAME_SIZE 2048
+#endif
+
+#include "text_t.h"
+
+extern HWND GSDL_Window;
+extern int line_spacing;
+extern RECT text_rect;
+
+void refresh_console(HDC dc);
+
+extern text_t data_location;
+
+extern void set_location(text_t possible);
+extern void find_location(void);
+
+extern void open_log_file(void);
+extern void close_log_file(void);
+extern void log_message(char *msg);
+extern void log_message_N(char*msg, int n);
+
+extern void activate_console(void);
+extern void deactivate_console(void);
+
+extern void LogCriticalError(char *cderr, char *Msg);
+
+/* returns first-second taking into account wrap around */
+extern DWORD DiffTickCounts (DWORD first, DWORD second);
Index: /gsdl/stable/runtime-src/src/w32server/netio.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/netio.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/netio.cpp	(revision 20131)
@@ -0,0 +1,472 @@
+/**********************************************************************
+ *
+ * netio.cpp
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#pragma hdrstop
+#include "netio.h"
+#include "locate.h"
+#include "d_winsock.h"
+#include "settings.h"
+
+//Private Variables and Declarations
+
+//Max string size for a host name
+#define MAXHOSTNAME 100
+
+//Timeout for waiting between "packets" in seconds
+#define NETIO_CONN_TIMEOUT 20 //3 sec  was 180 @@@@@ WJR
+
+#define HTTP_DNS_MSG WM_USER + 1
+int dns_msg_received = 0;
+int dns_msg_error = 0;
+
+DWORD LocalIPNumber;
+char LocalName[MAXHOSTNAME];
+
+//Private Function Declarations
+DWORD GetHostID();
+
+// returns 0 on success,
+// WSASYSNOTREADY, WSAVERNOTSUPPORTED, or WSAEINVAL on failure
+int InitNetIO() {
+  WSADATA Data;
+  
+  // Load Winsock
+  int err = d_WSAStartup(MAKEWORD(1, 1), &Data);
+  
+  // get local IP number
+  if (err == 0) LocalIPNumber = GetHostID();
+  else LocalIPNumber = INADDR_ANY;
+  
+  // set the Local Name to "" for now
+  LocalName[0] = 0;
+  
+  return err;
+}
+
+
+void CleanUpNetIO() {
+  //Experimental, heard this will better clean up, especialy if a call is
+  //blocking....
+  d_WSAUnhookBlockingHook();
+
+  //Clean up Winsock
+  d_WSACleanup();
+}
+
+
+void ResetNetIO() {
+  //Figure out the local name on first querry, set to "" until then...
+  LocalName[0] = 0;
+}
+
+
+DWORD GetLocalIP() {
+  return LocalIPNumber;
+}
+
+long __stdcall DNSWindowProc(HWND hWnd,UINT wMsg, WPARAM wParam, LPARAM lParam) {
+  if (wMsg == HTTP_DNS_MSG) {
+    dns_msg_received = 1;
+    dns_msg_error = WSAGETASYNCERROR(lParam);
+    return 0;
+  }
+  
+  return DefWindowProc(hWnd, wMsg, wParam, lParam);
+}
+
+char *GetLocalName(HINSTANCE hInstance) {
+  // static in case it is written to after the function has finished
+  // (I did not error checking on WSACancelAsyncRequest)
+  static char buf[MAXGETHOSTSTRUCT];
+	
+  if (LocalName[0] == 0) {
+    hostent *DNSResult = NULL;
+    in_addr LocalInAddr;
+    
+    // if we failed to get the local IP number
+    // use the loop-back device
+    if (LocalIPNumber == INADDR_ANY) {
+      strcpy(LocalName, "127.0.0.1"); // loop-back device
+      return LocalName;
+    }
+    
+    //Convert the number to an in_addr struct
+    LocalInAddr.s_addr = LocalIPNumber;
+    
+    // if we fail to find the domain name we will
+    // still want the IP address
+    strcpy(LocalName, d_inet_ntoa(LocalInAddr));
+    
+    // make sure they actually passed in an instance handle
+    if (hInstance == NULL) return LocalName;
+    
+    // do a async domain name lookup so that we
+    // can control the timeout
+    
+    // create a window class and window to handle the async messages
+    WNDCLASS wc; HWND hwndDNS;
+    
+    wc.style = 0;
+    wc.lpfnWndProc = DNSWindowProc;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hInstance = hInstance;
+    wc.hIcon = NULL;
+    wc.hCursor = NULL;
+    wc.hbrBackground = NULL;
+    wc.lpszMenuName = NULL;
+    wc.lpszClassName = "GSDL DNS Window";
+    if (!RegisterClass(&wc)) return LocalName;
+    
+    hwndDNS = CreateWindow("GSDL DNS Window", "", 
+			   WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 
+			   NULL, NULL, hInstance, NULL);
+    if (!hwndDNS) return LocalName;
+    
+    // process all messages currently on the queue
+    MSG Message;
+    while (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) {
+      TranslateMessage(&Message); /* translate keyboard messages */
+      DispatchMessage(&Message);  /* return control to Windows NT */
+    }
+    
+    //Do a async DNS lookup on the IP number
+    dns_msg_received = 0;
+    dns_msg_error = 0;
+    HANDLE asyncGetHostReq = d_WSAAsyncGetHostByAddr(
+						     hwndDNS, HTTP_DNS_MSG, (char *)&(LocalInAddr), 
+						     4, PF_INET, buf, MAXGETHOSTSTRUCT);
+    
+    if (asyncGetHostReq != NULL) {
+      // wait 5 seconds for the request to complete
+      int now = GetTickCount();
+      while ((DiffTickCounts(now, GetTickCount()) < 5000) && !dns_msg_received) {
+	if (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) {
+	  TranslateMessage(&Message); /* translate keyboard messages */
+	  DispatchMessage(&Message);  /* return control to Windows NT */
+	} else {
+	  Sleep(1);
+	}
+      }
+      if (!dns_msg_received)
+	d_WSACancelAsyncRequest(asyncGetHostReq);
+    }
+    
+    DestroyWindow(hwndDNS);
+    
+    if (dns_msg_received && (dns_msg_error == 0)) {
+      //Worked, use the primary name
+      strcpy(LocalName, ((hostent *)(buf))->h_name);
+      //Convert it to lower case for cosmedic reasons
+      CharLower(LocalName);
+    }
+  }
+  return LocalName;
+}
+
+
+// returns 0 on success, and a WSA error message on failure.
+// possible error messages include:
+// WSANOTINITIALISED, WSAENETDOWN, WSAEAFNOSUPPORT, WSAEINPROGRESS, WSAEMFILE,
+// WSAENOBUFS, WSAEPROTONOSUPPORT, WSAEPROTOTYPE, WSAESOCKTNOSUPPORT,
+// WSAEADDRINUSE, WSAEINVAL, WSAEISCONN, WSAENOTSOCK, WSAEOPNOTSUPP
+
+#define MAXBINDCOUNT 4096
+int CreateListeningSocket(int &PortNum, HWND MsgWindow, 
+			  WORD SocketMsg, SOCKET &ServerSocket) {
+  int err = 0;
+  SOCKADDR_IN ServerSockAddr;
+  int bind_port, bind_count;
+  
+  //Create the Server Socket
+  ServerSocket = d_socket(AF_INET, SOCK_STREAM, 0);
+  if (ServerSocket == INVALID_SOCKET) return d_WSAGetLastError();
+  
+  bind_port = PortNum;
+  for (bind_count=0; bind_count < MAXBINDCOUNT; ++bind_count) {
+    // Set up the Server Socket Address
+    memset(&ServerSockAddr, 0, sizeof(ServerSockAddr)); //Needed?
+    ServerSockAddr.sin_port = d_htons( (WORD) bind_port);
+    ServerSockAddr.sin_family = AF_INET;
+    if (gsdl_external_access) {
+      ServerSockAddr.sin_addr.s_addr = d_htonl(INADDR_ANY);
+    }
+    else {
+      ServerSockAddr.sin_addr.s_addr = d_htonl(INADDR_LOOPBACK);
+    }
+
+
+    // Try to bind the socket with the address
+    if (d_bind(ServerSocket, (LPSOCKADDR) &ServerSockAddr,
+	       sizeof(ServerSockAddr)) != SOCKET_ERROR) {
+      PortNum = bind_port;
+      break;
+    }
+    
+    // make sure it failed to bind because it was
+    // already bound
+    err = d_WSAGetLastError ();
+    if (err != WSAEADDRINUSE) return err;
+    
+    // Or choose another port number to try
+    if (bind_port == 80) bind_port = IPPORT_RESERVED+1;
+    else if (bind_count == 0) bind_port = 80;
+    else ++bind_port;
+  }
+  
+  // return an error in we couldn't find a valid port
+  if (bind_count == MAXBINDCOUNT) return WSAEADDRINUSE;
+  
+  // Start listening for connections
+  if (d_listen(ServerSocket, SOMAXCONN) == SOCKET_ERROR)
+    return d_WSAGetLastError ();	
+  
+  // Set up event for new connections
+  if (d_WSAAsyncSelect(ServerSocket, MsgWindow, SocketMsg, FD_ACCEPT) == SOCKET_ERROR)
+    return d_WSAGetLastError ();
+  
+  return 0;
+}
+
+
+int AnswerListeningSocket(SOCKET ServerSocket, SOCKET &ClientSocket, 
+			  SOCKADDR_IN &ClientSockAddr, int AddrLen) {
+  if (d_WSAIsBlocking()) {
+    log_message("rejected connect due blocking\n");
+    return -1;
+  }
+  
+  ClientSocket = d_accept(ServerSocket, (LPSOCKADDR) &ClientSockAddr, &AddrLen);
+  if (ClientSocket == INVALID_SOCKET) {
+    log_message("accept failed - connection lost\n");
+    return -1;
+  }
+  
+  log_message("accept success - connection made\n");
+  return 0;
+}
+
+void DestroyListeningSocket(SOCKET &ServerSocket, HWND MsgWindow) {
+  //Remove any message notification
+  d_WSAAsyncSelect(ServerSocket, MsgWindow, 0, 0);
+  
+  //Close the socket
+  CloseSocket(ServerSocket);
+}
+
+void CloseSocket(SOCKET &TargetSocket) {
+  if (TargetSocket != INVALID_SOCKET) {
+    //Since we're closing the socket, there's not much I can do about errors
+    //now so I'm not gonna bother checking...
+    
+    //Shutdown both ends, assume we have all data...
+    d_shutdown(TargetSocket, 2);
+    
+    d_closesocket(TargetSocket);
+    
+    //Make sure we can't use the old handle again...
+    TargetSocket = INVALID_SOCKET;
+  }
+}
+
+int GetData(SOCKET ClientSocket, BYTE *IOBuffer, int IOBufferSize,
+	    int ThreadNum) {
+  
+  int NumRecv;
+  int Error;
+  struct timeval Timeout;
+  fd_set SocketSet;
+  
+  //Set up a socket set structure with just ClientSocket for  select(..)
+  FD_ZERO(&SocketSet);
+  FD_SET(ClientSocket, &SocketSet);
+  
+  //set timeout
+  Timeout.tv_sec = NETIO_CONN_TIMEOUT;
+  Timeout.tv_usec = 0;
+  
+  do {
+    NumRecv = d_recv(ClientSocket, (char *) IOBuffer, IOBufferSize, 0);
+    if (NumRecv == 0) {
+      //Lost connect
+      return -1;
+      
+    } else if (NumRecv == SOCKET_ERROR) {
+      Error = d_WSAGetLastError();
+      if (Error == WSAEWOULDBLOCK) {
+	NumRecv = 0;
+	//Wait for socket to be readable
+	if (d_select(0, &SocketSet, NULL, NULL, &Timeout) != 1) {
+	  //Timeout
+	  return -1;
+	}
+	
+      } else {
+	//Assume connection terminated
+	return -1;
+      }
+    }
+  } while(NumRecv == 0);
+  return NumRecv;
+}
+
+int GetLine(text_t &OutStr, SOCKET ClientSocket, BYTE *IOBuffer, int IOBufferSize,
+	    int &BufferIndex, int &DataInBuffer, int ThreadNum) {
+
+  OutStr.clear();
+  char CurChar;
+  
+  do {
+    if (BufferIndex == DataInBuffer) { //Need more data
+      DataInBuffer = GetData(ClientSocket, IOBuffer, IOBufferSize, ThreadNum);
+      if (DataInBuffer == -1) {
+	//Lost connect
+	return -1;
+      }
+      BufferIndex = 0;
+    }
+    CurChar = IOBuffer[BufferIndex];
+    ++BufferIndex;
+    if ((CurChar != 10) && (CurChar != 13))  {
+      OutStr.push_back(CurChar);
+    }
+  } while (CurChar != 10);
+  
+  return 0;
+}
+
+int SendData(SOCKET ClientSocket, BYTE *SendBuffer, int NumToSend,
+	     int ThreadNum) {
+  
+  int NumSent = 0;
+  int Error;
+  struct timeval Timeout;
+  fd_set SocketSet;
+  
+  char NumSentStr[50];
+  itoa(NumToSend, NumSentStr, 10);
+  
+  //Set up a socket set structure with just ClientSocket for  select(..)
+  FD_ZERO(&SocketSet);
+  FD_SET(ClientSocket, &SocketSet);
+  //set timeout
+  Timeout.tv_sec = NETIO_CONN_TIMEOUT;
+  Timeout.tv_usec = 0;
+  
+  while (NumToSend > 0) {
+    NumSent = d_send(ClientSocket, (char *) SendBuffer + NumSent, NumToSend, 0);
+    if (NumSent == 0) {
+      //Lost connect
+      return -1;
+    }
+    else if (NumSent == SOCKET_ERROR) {
+      Error = d_WSAGetLastError();
+      if (Error == WSAEWOULDBLOCK) {
+	NumSent = 0;
+	if (d_select(0, NULL, &SocketSet, NULL, &Timeout) != 1) {
+	  //Timeout
+	  return -1;
+	}
+      }
+      else {
+	//Lost Connection
+	return -1;
+      }
+    }
+    NumToSend -= NumSent;
+  }
+  return 0;
+}
+
+
+/******************************************************************************/
+//Private Functions
+/******************************************************************************/
+/*-----------------------------------------------------------
+ * Function: GetHostID()
+ *
+ * Description:
+ *  Get the Local IP address using the following algorithm:
+ *    - get local hostname with gethostname()
+ *    - attempt to resolve local hostname with gethostbyname()
+ *    if that fails:
+ *    - get a UDP socket
+ *    - connect UDP socket to arbitrary address and port
+ *    - use getsockname() to get local address
+ *
+ * Notes: Copyright by Bob Quinn, 1995, taken from his Winsock library
+ *        was removed from its original module unmodified
+ */
+DWORD GetHostID () {
+  char szLclHost [MAXHOSTNAME];
+  LPHOSTENT lpstHostent;
+  SOCKADDR_IN stLclAddr;
+  SOCKADDR_IN stRmtAddr;
+  int nAddrSize = sizeof(SOCKADDR);
+  SOCKET hSock;
+  int nRet;
+  
+  /* Init local address (to zero) */
+  stLclAddr.sin_addr.s_addr = INADDR_ANY;
+  
+  /* Get the local hostname */
+  nRet = d_gethostname(szLclHost, MAXHOSTNAME);
+  if (nRet != SOCKET_ERROR) {
+    /* Resolve hostname for local address */
+    lpstHostent = d_gethostbyname((LPSTR)szLclHost);
+    if (lpstHostent)
+      stLclAddr.sin_addr.s_addr = *((u_long FAR*) (lpstHostent->h_addr));
+  }
+  
+  /* If still not resolved, then try second strategy */
+  if (stLclAddr.sin_addr.s_addr == INADDR_ANY) {
+    /* Get a UDP socket */
+    hSock = d_socket(AF_INET, SOCK_DGRAM, 0);
+    if (hSock != INVALID_SOCKET)  {
+      /* Connect to arbitrary port and address (NOT loopback) */
+      stRmtAddr.sin_family = AF_INET;
+      stRmtAddr.sin_port   = d_htons(IPPORT_ECHO);
+      stRmtAddr.sin_addr.s_addr = d_inet_addr("128.127.50.1");
+      nRet = d_connect(hSock,
+		       (LPSOCKADDR)&stRmtAddr,
+		       sizeof(SOCKADDR));
+      if (nRet != SOCKET_ERROR) {
+	/* Get local address */
+	d_getsockname(hSock,
+		      (LPSOCKADDR)&stLclAddr,
+		      (int FAR*)&nAddrSize);
+      }
+      d_closesocket(hSock);   /* we're done with the socket */
+    }
+  }
+  return (stLclAddr.sin_addr.s_addr);
+}
Index: /gsdl/stable/runtime-src/src/w32server/netio.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/netio.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/netio.h	(revision 20131)
@@ -0,0 +1,160 @@
+/**********************************************************************
+ *
+ * netio.h
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "text_t.h"
+
+/*
+Module Name: Net IO
+Purpose: High level Socket IO and Misc socket routines
+Public Functions:
+	InitNetIO
+   CleanUpNetIO
+
+	GetLocalIP
+	GetLocalName
+
+   CreateListeningSocket
+   AnswerListeningSocket
+   DestroyListeningSocket
+
+   CloseSocket
+
+	GetData
+	GetLine
+
+	SendData
+	SendFile
+*/
+
+//Public Functions
+
+/*
+Function Name: Init Net IO
+Purpose: Initializes the module so calls can be made querying network
+         information for the local macnine.
+Notes: MUST be called before GetLocalIP and GetLocalName
+*/
+
+// returns 0 on success,
+// WSASYSNOTREADY, WSAVERNOTSUPPORTED, or WSAEINVAL on failure
+int InitNetIO();
+
+/*
+Function Name: Cleanup Net IO
+Purpose: Cleans up the module and unloads Winsock
+*/
+void CleanUpNetIO();
+
+/*
+Function Name: Reset Net IO
+Purpose: Resets internal data in NetIO to reflect registry changes, etc.
+*/
+void ResetNetIO();
+
+/*
+Function Name: Get Local IP
+Purpose: Gets the local IP number
+Returns: The local IP number as an double word (4 bytes)
+*/
+DWORD GetLocalIP();
+
+/*
+Function Name: Get Local Name
+Purpose: Gets the local Domain name, or if there is none, then the server
+address in dotted format.
+Returns: A string containing the local address
+*/
+char *GetLocalName(HINSTANCE hInstance);
+
+// returns 0 on success, and a WSA error message on failure.
+// possible error messages include:
+// WSANOTINITIALISED, WSAENETDOWN, WSAEAFNOSUPPORT, WSAEINPROGRESS, WSAEMFILE,
+// WSAENOBUFS, WSAEPROTONOSUPPORT, WSAEPROTOTYPE, WSAESOCKTNOSUPPORT,
+// WSAEADDRINUSE, WSAEINVAL, WSAEISCONN, WSAENOTSOCK, WSAEOPNOTSUPP
+int CreateListeningSocket(int &PortNum, HWND MsgWindow, 
+			  WORD SocketMsg, SOCKET &ServerSocket);
+
+int AnswerListeningSocket(SOCKET ServerSocket, SOCKET &ClientSocket, 
+			  SOCKADDR_IN &ClientSockAddr, int AddrLen);
+
+void DestroyListeningSocket(SOCKET &ServerSocket, HWND MsgWindow);
+
+void CloseSocket(SOCKET &TargetSocket);
+
+/*
+Function Name: Get Data
+Purpose: Gets data from a socket with muli-threaded debugging
+Parameters:
+	ClientSocket - The socket to get data from
+	IOBuffer - A pointer to a chunk of memory to put data in
+	IOBufferSize - Size of the buffer
+	ThreadNum - Number of the thread that called this functions used for debugging
+
+Returns: -1 on error, else the number of bytes received
+
+Notes:
+Removed socket error checking because I was unable to isolate what
+errors I was getting when getting a "rude" disconnect
+*/
+int GetData(SOCKET ClientSocket, BYTE *IOBuffer, int IOBufferSize, int ThreadNum);
+
+/*
+Function Name: Get Line
+Purpose: Gets a line of text (ended by a LF (10)) from a socket with buffered
+			input.  If the buffer is empty this function fills the buffer, else it
+			just changes an index. Also has the ability to do multi-threaded debuging
+Parameters:
+	OutStr - Varible were output is put
+	ClientSocket - The socket to get data from
+	IOBuffer - A pointer to a chunk of memory to put data in
+	IOBufferSize - Size of the buffer
+	BufferIndex - A zero based index of what charactor in the buffer we're at
+	DataInBuffer - Amount of data in the buffer
+	ThreadNum - Number of the thread that called this functions used for debugging
+
+Returns: -1 on disconnect or error (abort connection), 0 on success
+*/
+int GetLine(text_t &OutStr, SOCKET ClientSocket, BYTE *IOBuffer, int IOBufferSize, 
+	    int &BufferIndex, int &DataInBuffer, int ThreadNum);
+
+/*
+Function Name: Send Data
+Purpose: Sends data to a socket with muli-thread debugging
+Parameters:
+	ClientSocket - The socket to get data from
+	SendBuffer - A pointer to a chunk of memory to put data in
+	NumToSend - Number of bytes to send from buffer
+	ThreadNum - Number of the thread that called this functions used for debugging
+
+Returns: -1 on error, 0 on success
+
+Notes:
+Removed socket error checking because I was unable to isolate what
+errors I was getting when getting a "rude" disconnect
+*/
+int SendData(SOCKET ClientSocket, BYTE *SendBuffer, 
+	     int NumToSend, int ThreadNum);
Index: /gsdl/stable/runtime-src/src/w32server/parse.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/parse.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/parse.cpp	(revision 20131)
@@ -0,0 +1,205 @@
+/**********************************************************************
+ *
+ * parse.cpp
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+#pragma hdrstop
+
+#include "parse.h"
+
+//Public Functions
+/******************************************************************************/
+void Left(char *DestStr, const char *SourceStr, const int Len) {
+  memcpy(DestStr, SourceStr, Len);
+  DestStr[Len] = 0;
+}
+/******************************************************************************/
+void Right(char *DestStr, const char *SourceStr, const int Len) {
+  int SourceLen, Offset;
+  
+  SourceLen = strlen(SourceStr);
+  Offset = SourceLen - Len;
+  
+  memcpy(DestStr, SourceStr + Offset, Len + 1);
+  //The null is already copied
+}
+/******************************************************************************/
+void TrimLeft(char *TargetStr) {
+  int i, NewStrSize;
+  
+  i = 0;
+  //Find the first non-space charactor
+  while ( (TargetStr[i] == ' ') || (TargetStr[i] == '\t') ) {
+    ++i;
+  }
+  //If we have space to get rid of, move the string
+  if (i > 0) {
+    NewStrSize = strlen(TargetStr) - i + 1; //Include the NULL in the size
+    memmove(TargetStr, TargetStr + i, NewStrSize);
+  }
+}
+/******************************************************************************/
+void TrimRight(char *TargetStr) {
+  int i;
+  
+  //Find the last non-space charactor (index i)
+  i = strlen(TargetStr) - 1;
+  while ((i >= 0) && ((TargetStr[i] == ' ') || (TargetStr[i] == '\t')) ) {
+    --i;
+  }
+  //Set the NULL 1 after the last non-space charactor
+  TargetStr[i+1] = 0;
+}
+/******************************************************************************/
+void Trim(char *TargetStr) {
+  TrimRight(TargetStr);
+  TrimLeft(TargetStr);
+}
+/******************************************************************************/
+void GetWord(text_t &DestStr, text_t::const_iterator first,
+	     text_t::const_iterator last, text_t::const_iterator &next) {
+
+  DestStr.clear();
+  next = last;
+
+  while (first != last) {
+    if (*first == ' ' || *first == '\t') {
+      ++first;
+      while ((first != last) && ((*first == ' ') || (*first == '\t'))) {
+	++first;
+      }
+      next = first;
+      break;
+    } else {
+      DestStr.push_back(*first);
+    }
+    ++first;
+  }
+}
+/******************************************************************************/
+
+void GetLastWord(text_t &DestStr, text_t::const_iterator first, text_t::const_iterator last, 
+		 text_t::const_iterator &Start) {
+
+  DestStr.clear();
+  Start = first;
+
+  while (first != last) {
+    if ((*first == ' ') || (*first == '\t')) {
+      DestStr.clear();
+      Start = first+1;
+    } else {
+      DestStr.push_back(*first);
+    }
+    ++first;
+  }
+}
+/******************************************************************************/
+void SplitPath(char *Path, char *Dir, char *FileName) {
+  int SplitPoint;
+  SplitPoint = strlen(Path) - 1;
+  while ((SplitPoint > 0) && (Path[SplitPoint] != '\\')) {
+    --SplitPoint;
+  }
+  if ((SplitPoint == 0) && (Path[SplitPoint] != '\\')) {
+    //No directory, just a file name
+    Dir[0] = 0;
+    strcpy(FileName, Path);
+  }
+  else {
+    //Move past the last slash
+    ++SplitPoint;
+    
+    //Directory
+    int i = 0;
+    while (i < SplitPoint) {
+      Dir[i] = Path[i];
+      ++i;
+    }
+    Dir[i] = 0;
+    
+    //File name
+    int j = 0;
+    while (Path[i] != 0) {
+      FileName[j] = Path[i];
+      ++j;
+      ++i;
+    }
+    FileName[j] = 0;
+  }
+}
+/******************************************************************************/
+void GetExtention(char *Path, char *Extention) {
+  int Dot;
+  int PathLen;
+  
+  PathLen = strlen(Path) - 1;
+  Dot = PathLen;
+  while ((Dot > 0) && (Path[Dot] != '.')) {
+    --Dot;
+  }
+  if (Dot > 0) {
+    strcpy(Extention, Path + Dot + 1);
+  }
+  else {
+    Extention[0] = 0;
+  }
+}
+/******************************************************************************/
+void TranslateEscapeString(char *TargetStr) {
+  int i = 0;
+  int j = 0;
+  
+  while (TargetStr[i] != 0) {
+    if ((TargetStr[i] == '%') && (TargetStr[i+1] != 0) && (TargetStr[i+2] != 0)) {
+      //Escaped value (did checking to make sure there are 2 more chars)
+      //         #pragma warn -sig //Suppress significant digit loss warning (BC++)
+      TargetStr[j] = 16 * HexVal(TargetStr[i+1]) + HexVal(TargetStr[i+2]);
+      //         #pragma warn +sig   //Restore significant digit loss warning (BC++)
+      i += 3;
+    }
+    else {
+      TargetStr[j] = TargetStr[i];
+      ++i;
+    }
+    ++j;
+  }
+  TargetStr[j] = 0;
+}
+/******************************************************************************/
+int HexVal(char c) {
+  //   #pragma warn -sig //Suppress significant digit loss warning (BC++)
+  if (c >= '0' && c <= '9') return c - '0';
+  else if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+  else if (c >= 'A' && c <= 'F') return c - 'A' + 10;
+  else return 0;
+  //   #pragma warn +sig   //Restore significant digit loss warning (BC++)
+}
+/******************************************************************************/
Index: /gsdl/stable/runtime-src/src/w32server/parse.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/parse.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/parse.h	(revision 20131)
@@ -0,0 +1,162 @@
+/**********************************************************************
+ *
+ * parse.h
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "text_t.h"
+
+/*
+Module Name: Parse
+Purpose: General string parsing.  These are functions that are not in string.h,
+	but are found in many other libraries and high level languages.
+Public Functions:
+	Left
+	Right
+
+	Trim
+	TrimLeft
+	TrimRight
+
+	GetWord
+	GetLastWord
+
+   Split Path
+   GetExtention
+*/
+
+/*
+Function Name: Left
+Purpose: Copies the leftmost x number of charactors of a string to a buffer
+Parameters:
+	DestStr - Destination buffer for substring
+	SourceStr - Source string to make substing from
+	Len - Length of substring
+
+Notes: If Len is greater than strlen(SourceStr) a memory error may occur.
+*/
+void Left(char *DestStr, const char *SourceStr, const int Len);
+
+/*
+Function Name: Right
+Purpose: Copies the rightmost x number of charactors of a string to a buffer
+Parameters:
+	DestStr - Destination buffer for substring
+	SourceStr - Source string to make substing from
+	Len - Length of substring
+
+Notes: If Len is greater than strlen(SourceStr) then a memory error may
+		 occur.
+*/
+void Right(char *DestStr, const char *SourceStr, const int Len);
+
+/*
+Function Name: TrimLeft
+Purpose: Removes spaces and tabs from the left end of a string.
+Parameters:
+	TargetString - String to be trimmed
+*/
+void TrimLeft(char *TargetStr);
+
+/*
+Function Name: TrimRight
+Purpose: Removes spaces and tabs from the right end of a string.
+Parameters:
+	TargetString - String to be trimmed
+*/
+void TrimRight(char *TargetStr);
+
+/*
+Function Name: Trim
+Purpose: Removes spaces and tabs from both ends of a string.
+Parameters:
+	TargetString - String to be trimmed
+*/
+void Trim(char *TargetStr);
+
+/*
+Function Name: GetWord
+Purpose: Gets leftmost substring without a space in the string between the iterators
+         'here' and 'end'. Sets 'DestStr' to the substring. Sets the 'next' iterator 
+	 to the next non-space charactor in the string.  ' ' and '\t' and considered
+         spaces
+Parameters:
+	 DestString - Destination buffer for substring
+	 first - First character in source string
+	 last - end iterator (one past last character) of source string
+	 next - At end of function call is set to the location of next non-space
+               charactor in source string
+*/
+void GetWord(text_t &DestStr, text_t::const_iterator first,
+	     text_t::const_iterator last, text_t::const_iterator &next);
+
+/*
+Function Name: GetLastWord
+Purpose: Gets rightmost substring without a space sets Start to be the first
+         character of the substring in the original string.
+Parameters:
+	DestString - Destination buffer for substring
+	first and last - Source string to make substing from
+	Start - where the DestString starts at in the source string
+*/
+void GetLastWord(text_t &DestStr, text_t::const_iterator first, text_t::const_iterator last, 
+		 text_t::const_iterator &Start);
+
+
+/*
+Function Name: Split Path
+Purpose: Splits a path string into directory and file name
+Parameters:
+	Path - Path string (example "c:\Fnord\SomeFile.Ext")
+	Dir - Directory part of the Path (example "c:\Fnord\")
+	FileName - File name part of the path (example "SomeFile.Ext")
+*/
+void SplitPath(char *Path, char *Dir, char *FileName);
+
+/*
+Function Name: Get Extention
+Purpose: Splits a path string into directory and file name
+Parameters:
+	Path - Path string or file name (example "c:\Fnord\SomeFile.Ext")
+	Extention - Extention part of the path (example "Ext")
+*/
+void GetExtention(char *Path, char *Extention);
+
+/*
+Function Name: Translate Escape String
+Purpose: Translates all URL escape sequences, such as "%20" where "20" is
+	the resulting charactor in hexidecimal
+Parameters:
+	TargetStr - String that may contain URL escape sequences.  All sequences
+   	are decoded on return.
+*/
+void TranslateEscapeString(char *TargetStr);
+
+/*
+Function Name: Hex Value
+Purpose: Returns the value of a hexidecimal digit character as an integer
+Parameters:
+	c - Charactor to translate
+*/
+int HexVal(char c);
Index: /gsdl/stable/runtime-src/src/w32server/resource.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/resource.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/resource.h	(revision 20131)
@@ -0,0 +1,56 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by server.rc
+//
+#define TRAY_ICON                       101
+#define COMMS_DIALOG                    102
+#define COMMS_DIALOG_DEBUG              102
+#define Main_Menu                       103
+#define COMMS_DIALOG2                   103
+#define GSDL_LOGO                       108
+#define GSDL_COL_TITLE                  109
+#define IDD_DIALOG1                     118
+#define GSDL_ICBMP                      126
+#define APPLY_BUTTON                    1000
+#define REMOTE_CHECK                    1001
+#define PROXY_CHECK                     1002
+#define CONSOLE_CHECK                   1003
+#define PROXY_EDIT_BOX                  1004
+#define PROXY_PORT_EDIT_BOX             1005
+#define TrayID                          1006
+#define LOG_DEBUG_CHECK                 1007
+#define SERVER_PORT_EDIT_BOX            1008
+#define LOG_LOCAL_CHECK                 1009
+#define LOG_REMOTE_CHECK                1010
+#define LOG_NAME_BOX                    1011
+#define LOG_CHECK                       1012
+#define SAVE_NAME_BOX                   1013
+#define SAVE_CHECK                      1014
+#define ID_AUTO_ENTER_LIBRARY           1015
+#define ID_RADIO_NETSCAPE               1016
+#define ID_RADIO_IE                     1017
+#define ID_RADIO_OTHER                  1018
+#define ID_OTHER_NAME                   1019
+#define ID_BROWSE_BUTTON                1020
+#define ID_OK_BUTTON                    1021
+#define ID_CANCEL_BUTTON                1022
+#define ID_RADIO_DEFAULT                1023
+#define ID_ARM_NAME                     1024
+#define ID_ARM_IP                       1025
+#define ID_ARM_127_0_0_1                1026
+#define ID_ARM_LOCALHOST                1027
+#define ID_EXTERNAL_ACCESS              1028
+#define ID_PROJECT_SETTINGS             40001
+#define ID_PROJECT_EXIT                 40002
+#define ID_INSTALL_NETSCAPE             40007
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        127
+#define _APS_NEXT_COMMAND_VALUE         40011
+#define _APS_NEXT_CONTROL_VALUE         1030
+#define _APS_NEXT_SYMED_VALUE           102
+#endif
+#endif
Index: /gsdl/stable/runtime-src/src/w32server/settings.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/settings.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/settings.cpp	(revision 20131)
@@ -0,0 +1,941 @@
+/**********************************************************************
+ *
+ * settings.cpp
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "text_t.h"
+#include "fileutil.h"
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\fstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <fstream.h>
+#else
+#  include <fstream>
+#endif
+
+#include <windows.h>
+#include "httpsrv.h"
+#include "settings.h"
+#include "locate.h"
+#include "resource.h"
+#include "cgiwrapper.h"
+
+// library settings
+text_t gsdl_enterlib;
+text_t gsdl_gsdlhome;
+text_t gsdl_collecthome;
+text_t gsdl_dbhome;
+text_t gsdl_collections;
+colinfo_tmap gsdl_collectinfo;
+
+char gsdl_staticpages[MAX_FILENAME_SIZE];
+
+// debug settings
+char gsdl_log_name[MAX_FILENAME_SIZE] = "c:\\gsdl.log";
+int gsdl_keep_log = 0;
+int gsdl_show_console = 0;
+
+// general settings
+int gsdl_port_num = 80;
+int gsdl_external_access = 0;
+int gsdl_auto_enter = 0;
+int gsdl_browser = GS_DEFAULT;
+char gsdl_browser_exe[MAX_FILENAME_SIZE] = "";
+text_t gsdl_url;
+text_t gsdl_conffile;
+int gsdl_start_browser = 1;
+int gsdl_address_resolution_method = 2;  // use localhost since users may switch between computers
+// The resolution method was previously on 1: Get an IP, but don't resolve to a name
+
+// private data
+
+// pathnames of the latest installed versions of netscape and
+// internet explorer
+static char netscape_exe[MAX_FILENAME_SIZE]="";
+static char iexplore_exe[MAX_FILENAME_SIZE]="";
+
+// pathname of the default browser
+static char default_browser_exe[MAX_FILENAME_SIZE]="";
+
+// whether netscape is needed (used in the settings dialog box)
+static int gsdl_netscapeneeded = 0;
+
+static void remove_end_slashes(char *str) {
+  int len = strlen (str);
+  while ((len > 0) && ((str[len-1] == '\\') || (str[len-1] == '/'))) {
+    --len;
+  }
+  str[len] = '\0';
+}
+
+static void remove_end_slashes (text_t &str) {
+  char *cstr = str.getcstr();
+  remove_end_slashes (cstr);
+  str = cstr;
+  delete []cstr;
+}
+
+// returns 1 if successful, 0 otherwise
+// checks for a file's existence
+static int check_program_exe (char *path) {
+  UINT curerrormode;
+  OFSTRUCT reOpenBuff;
+  int retvalue = 0;
+  
+  reOpenBuff.cBytes = sizeof (OFSTRUCT);
+  
+  curerrormode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+  if (OpenFile(path, &reOpenBuff, OF_EXIST) != HFILE_ERROR) retvalue = 1;
+  SetErrorMode(curerrormode);
+  
+  return retvalue;
+}
+
+
+// returns 1 if successful, 0 otherwise
+static int get_default_browser_path (char *providedhtmltype, char *path, int maxsize) {
+  HKEY hk1, hk2;
+  char htmltype[256];
+  long size;
+  int retval = 0;
+  
+  htmltype[0] = '\0';
+  path[0] = '\0';
+  
+  // try and get information about the default browser from the 
+  // registry
+  
+  if (providedhtmltype != NULL) strcpy (htmltype, providedhtmltype);
+  
+  else if (RegOpenKey(HKEY_CLASSES_ROOT, ".htm", &hk1) == ERROR_SUCCESS) {
+    size = 256;
+    RegQueryValue(hk1, NULL, htmltype, &size);
+    RegCloseKey(hk1);
+  }
+  
+  if (RegOpenKey(HKEY_CLASSES_ROOT, htmltype, &hk1) == ERROR_SUCCESS) {
+    if (RegOpenKey(hk1, "shell\\open", &hk2) == ERROR_SUCCESS) {
+      // look for the command to start the browser
+      size = maxsize;
+      if (RegQueryValue(hk2,"command",path,&size) == ERROR_SUCCESS) {
+				// strip all excess stuff off the command
+	char endchar = ' ';
+	int i = 0, len = 0;
+	int state = 0; // 0=strip initial white-space and quotes, 1=grab path
+	while (path[i] != '\0') {
+	  if (state == 0) {
+	    if (path[i] == ' ') {
+	      // do nothing
+	    } else if (path[i] == '"') {
+	      endchar = '"';
+	      state = 1;
+	    } else {
+	      state = 1;
+	      path[len] = path[i];
+	      ++len;
+	    }
+	  } else {
+	    if (path[i] == endchar) break;
+	    path[len] = path[i];
+	    ++len;
+	  }
+	  ++i;
+	}
+	path[len] = '\0';
+	
+	// check the resulting pathname
+	if (check_program_exe (path)) {
+	  retval = 1; // succeeded
+	} else {
+	  path[0] = '\0'; // failed (must have been deleted or something...)
+	}
+      }
+      RegCloseKey(hk2);
+    }
+    RegCloseKey(hk1);
+  }
+  
+  return retval;
+}
+
+
+// returns 1 if successful, 0 otherwise
+// note that appname should include .exe (e.g. netscape.exe)
+static int registry_get_app_paths (char *appname, char *path, int maxsize) {
+  HKEY hk1;
+  long size;
+  int retval = 0;
+  
+  path[0] = '\0';
+  
+  if (RegOpenKey(HKEY_LOCAL_MACHINE, 
+		 "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths", 
+		 &hk1) == ERROR_SUCCESS) {
+    size = maxsize;
+    if (RegQueryValue (hk1, appname, path, &size) == ERROR_SUCCESS &&
+	check_program_exe (path));
+    retval = 1;
+    
+    RegCloseKey(hk1);
+  }
+  
+  return retval;
+}
+
+static void check_installed_browsers (int netscapeneeded) {
+  netscape_exe[0] = '\0';
+  iexplore_exe[0] = '\0';
+  default_browser_exe[0] = '\0';
+  
+  // update the default browser information (if netscape isn't needed)
+  if (!netscapeneeded) {
+    get_default_browser_path (NULL, default_browser_exe, MAX_FILENAME_SIZE);
+    _strlwr (default_browser_exe);
+  }
+  
+  // look for netscape
+  
+  // first look for netscape in the registry
+  if (!registry_get_app_paths("netscape.exe", netscape_exe, MAX_FILENAME_SIZE)) {
+    // next look for "NetscapeMarkup"
+    if (get_default_browser_path ("NetscapeMarkup", netscape_exe, MAX_FILENAME_SIZE)) {
+      _strlwr (netscape_exe);
+      if (!strstr (netscape_exe, "netscape.exe")) {
+	netscape_exe[0] = '\0';
+	
+	// next look for \netscape\netscape.exe
+	
+	// get drive letter of the windows directory
+	GetWindowsDirectory(netscape_exe, MAX_FILENAME_SIZE);
+	netscape_exe[1] = '\0';
+	strcat (netscape_exe, ":\\netscape\\netscape.exe");
+	
+	if (!check_program_exe (netscape_exe)) {
+	  // lastly look for \netscape\program\netscape.exe
+	  netscape_exe[1] = '\0';
+	  strcat (netscape_exe, ":\\netscape\\program\\netscape.exe");
+	  
+	}
+      }
+    }
+  }
+  _strlwr (netscape_exe);
+  if ((strlen (netscape_exe) > 0) && !check_program_exe (netscape_exe)) {
+    netscape_exe[0] = '\0';  // couldn't find netscape
+  }
+  
+  // look for internet explorer (if netscape isn't needed)
+  
+  // first look for iexplore in the registry
+  if (!netscapeneeded && !registry_get_app_paths("iexplore.exe", 
+						 iexplore_exe, MAX_FILENAME_SIZE)) {
+    // next look for "htmlfile"
+    if (get_default_browser_path ("htmlfile", iexplore_exe, MAX_FILENAME_SIZE)) {
+      _strlwr (iexplore_exe);
+      if (!strstr (iexplore_exe, "iexplore.exe")) {
+	iexplore_exe[0] = '\0';
+	
+	// next look for \iexplore\iexplore.exe
+	
+	// get drive letter of the windows directory
+	GetWindowsDirectory(iexplore_exe, MAX_FILENAME_SIZE);
+	iexplore_exe[1] = '\0';
+	strcat (iexplore_exe, ":\\iexplore\\iexplore.exe");
+      }
+    }
+  }
+  _strlwr (iexplore_exe);
+  if ((strlen (iexplore_exe) > 0) && !check_program_exe (iexplore_exe)) {
+    iexplore_exe[0] = '\0';  // couldn't find internet explorer
+  }
+}
+
+void write_settings (const text_t url) {
+  
+  if (gsdl_conffile.empty()) {
+    find_location();
+    gsdl_conffile = filename_cat(data_location, "llssite.cfg");
+  }
+
+  char *conffile_c = gsdl_conffile.getcstr();
+  ofstream fout (conffile_c);
+  delete []conffile_c;
+  if (fout) {
+    
+    outconvertclass text_t2ascii;
+
+    // top (gsdl) level stuff
+    fout << "[gsdl]\n";
+    
+    if (!url.empty()) {
+      // url entry should only be written to llssite.cfg when the
+      // server is actually running, not when it's stopped (since we
+      // can't be sure what the url is at that stage). That is,
+      // write_settings() is called with the url argument set when the
+      // server first starts up, it's then called without url set as
+      // the server shuts down.
+      write_ini_line(fout, "url", url);      
+    }
+
+    write_ini_line(fout, "enterlib", gsdl_enterlib);
+    write_ini_line(fout, "gsdlhome", gsdl_gsdlhome);
+    write_ini_line(fout, "collecthome", gsdl_collecthome);
+    write_ini_line(fout, "gdbmhome", gsdl_dbhome);
+    
+    write_ini_line(fout, "logfilename", gsdl_log_name);
+    write_ini_line(fout, "keeplog", text_t(gsdl_keep_log));
+    write_ini_line(fout, "consolelog", text_t(gsdl_show_console));
+    
+    write_ini_line(fout, "portnumber", text_t(gsdl_port_num));
+    write_ini_line(fout, "externalaccess", text_t(gsdl_external_access));
+    write_ini_line(fout, "autoenter", text_t(gsdl_auto_enter));
+    write_ini_line(fout, "browser", text_t(gsdl_browser));
+    write_ini_line(fout, "browserexe", gsdl_browser_exe);
+    write_ini_line(fout, "collections", gsdl_collections);
+    write_ini_line(fout, "start_browser", text_t(gsdl_start_browser));
+    write_ini_line(fout, "address_resolution_method", text_t(gsdl_address_resolution_method));
+
+    // collection levels
+    colinfo_tmap::iterator here = gsdl_collectinfo.begin();
+    colinfo_tmap::iterator end = gsdl_collectinfo.end();
+    while (here != end) {
+      fout << text_t2ascii << "[" << (*here).first << "]\n";
+      if (!(*here).second.gsdl_gsdlhome.empty()) 
+	write_ini_line(fout, "gsdlhome", (*here).second.gsdl_gsdlhome);
+      if (!(*here).second.gsdl_collecthome.empty()) 
+	write_ini_line(fout, "collecthome", (*here).second.gsdl_collecthome);
+      if (!(*here).second.gsdl_dbhome.empty()) 
+	write_ini_line(fout, "gdbmhome", (*here).second.gsdl_dbhome);
+      
+      ++here;
+    }
+    fout.close();
+  }
+}
+
+
+// browser_compare assumes that check_exe is in lowercase
+static int browser_compare (char *browser_exe_path, char *check_exe) {
+  char tmp_exe[MAX_FILENAME_SIZE];
+  strcpy (tmp_exe, browser_exe_path);
+  _strlwr (tmp_exe);
+  return (strstr (tmp_exe, check_exe) != NULL);
+}
+
+// This function assumes that check_installed_browsers
+// has been recently called
+// It also assumes that browser_exe is large
+// enough to receive any path names to any browser
+static void check_browser_settings (int &browser, char *browser_exe, 
+				    int netscapeneeded) {
+  // sort out which browser to use
+  if ((browser == GS_NETSCAPE) && (netscape_exe[0] == '\0'))
+    browser = GS_IEXPLORE;
+  if ((browser == GS_IEXPLORE) && (netscapeneeded || (iexplore_exe[0] == '\0'))) {
+    if (netscape_exe[0] != '\0') browser = GS_NETSCAPE;
+    else browser = GS_OTHER;
+  }
+  if ((browser == GS_OTHER) && netscapeneeded && 
+      !browser_compare (browser_exe, "netscape.exe") && (netscape_exe[0] != '\0')) {
+    // this other browser isn't netscape and netscape is available
+    browser = GS_NETSCAPE;
+  }
+  
+  
+  // get the browser's executable
+  if (browser == GS_DEFAULT) {
+    strcpy (browser_exe, default_browser_exe);
+  } else if (browser == GS_NETSCAPE) {
+    strcpy (browser_exe, netscape_exe);
+  } else if (browser == GS_IEXPLORE) {
+    strcpy (browser_exe, iexplore_exe);
+  } else {
+    browser = GS_OTHER;
+    
+    // if the browser should be netscape then check to
+    // make sure it is
+    if (netscapeneeded && !browser_compare (browser_exe, "netscape.exe")) {
+      // not netscape, set to no browser
+      browser_exe[0] = '\0';
+    }
+  }
+}
+
+
+static void revert_defaults (int netscapeneeded) {
+  find_location();
+  
+  // library settings
+  gsdl_enterlib = "/gsdl";
+  gsdl_gsdlhome = data_location;
+  gsdl_collecthome = filename_cat(data_location,"collect");
+  gsdl_dbhome = data_location;
+  
+  // debug settings
+  gsdl_keep_log = 0;
+  char *cstr_value = filename_cat(data_location,"gsdl.log").getcstr();
+  strcpy (gsdl_log_name, cstr_value); //strcpy (gsdl_log_name, "c:\\gsdl.log");
+  delete []cstr_value;
+  gsdl_show_console = 0;
+  
+  // general settings
+  gsdl_port_num = 80;
+  gsdl_external_access = 0;
+  gsdl_auto_enter = 0;
+  gsdl_start_browser = 1;
+
+  check_installed_browsers (netscapeneeded);
+  gsdl_browser = GS_DEFAULT;
+  strcpy (gsdl_browser_exe, default_browser_exe);
+  check_browser_settings (gsdl_browser, gsdl_browser_exe, netscapeneeded);
+}
+
+void read_settings (int netscapeneeded) {
+  
+  if (gsdl_conffile.empty()) {
+    find_location();
+    gsdl_conffile = filename_cat(data_location, "llssite.cfg");
+  }
+  
+  // set up defaults
+  revert_defaults (netscapeneeded);
+  
+  text_t key, value, section;
+  char *cstr_value;
+  char *conffile_c = gsdl_conffile.getcstr();
+#if defined (GSDL_USE_IOS_H)
+  ifstream conf (conffile_c, ios::nocreate);
+#else
+  ifstream conf (conffile_c);
+#endif
+  delete []conffile_c;
+  if (conf) {
+    while (read_ini_line(conf, key, value) >= 0) {
+      if (key.empty()) continue;
+      if (value.empty()) {
+	// should be a section title
+	section = key;
+	// remove square brackets
+	section.erase (section.begin());
+	section.erase (section.end()-1);
+
+      } else {
+
+	cstr_value = value.getcstr ();
+      
+	if (section == "gsdl") {
+
+	  if (key == "enterlib") {
+	    gsdl_enterlib = value;
+	  
+	    // 'logfilename' should occur in the configuration file
+	    // before 'keeplog'
+	  } else if (key == "logfilename") {
+	    strcpy (gsdl_log_name, cstr_value);
+	  
+	  } else if (key == "keeplog") {
+	    gsdl_keep_log = value.getint();
+	    if (gsdl_keep_log) open_log_file();
+	
+	  } else if (key == "consolelog") {
+	    if (value.getint()) activate_console();
+	    else deactivate_console();
+	
+	  } else if (key == "portnumber") {
+	    gsdl_port_num = value.getint();
+
+	  } else if (key == "externalaccess") {
+	    gsdl_external_access = value.getint();
+	    
+	  } else if (key == "autoenter") {
+	    gsdl_auto_enter = value.getint();
+	    
+	  } else if (key == "start_browser") {
+	    gsdl_start_browser = value.getint();
+	
+	  } else if (key == "browser") {
+	    gsdl_browser = value.getint();
+	
+	  } else if (key == "browserexe") {
+	    strcpy (gsdl_browser_exe, cstr_value);
+
+	  } else if (key == "address_resolution_method") {
+	    gsdl_address_resolution_method = value.getint();
+
+	  } else if (key == "collections") {
+	    gsdl_collections = value;
+	  } 
+	  // gsdlhome must occur in file before dbhome	    
+	  else if (key == "gsdlhome") {
+	    gsdl_gsdlhome = value;
+	    gsdl_collecthome = filename_cat(value,"collect");
+	    gsdl_dbhome = value;	  
+	  } 
+	  else if (key == "collecthome") {
+	    gsdl_collecthome = value;
+	  } 
+	  else if (key == "gdbmhome") {
+	    gsdl_dbhome = value;
+	  }
+	} else {
+	  
+	  // gsdlhome must occur in file before dbhome
+	  if (key == "gsdlhome") {
+	    gsdl_collectinfo[section].gsdl_gsdlhome = value;
+	    gsdl_collectinfo[section].gsdl_collecthome = filename_cat(value,"collect");
+	    gsdl_collectinfo[section].gsdl_dbhome = value;
+	  } 
+	  else if (key == "collecthome") {
+	    gsdl_collectinfo[section].gsdl_collecthome = value;
+	  }
+	  else if (key == "gdbmhome") {
+	    gsdl_collectinfo[section].gsdl_dbhome = value;
+	  }
+	}
+	delete []cstr_value;
+      }
+    }
+    conf.close();
+  }
+  
+  // check the homes to make sure they don't contain
+  // extra slashes at the end
+  remove_end_slashes (gsdl_gsdlhome);
+  remove_end_slashes (gsdl_collecthome);
+  remove_end_slashes (gsdl_dbhome);
+  colinfo_tmap::iterator here = gsdl_collectinfo.begin();
+  colinfo_tmap::iterator end = gsdl_collectinfo.end();
+  while (here != end) {
+    remove_end_slashes ((*here).second.gsdl_gsdlhome);
+    remove_end_slashes ((*here).second.gsdl_collecthome);
+    remove_end_slashes ((*here).second.gsdl_dbhome);
+    ++here;
+  }
+
+  // check the browser settings
+  check_browser_settings (gsdl_browser, gsdl_browser_exe, netscapeneeded);
+}
+
+void gsdl_check_browser_settings (int netscapeneeded) {
+  check_installed_browsers (netscapeneeded);
+  check_browser_settings (gsdl_browser, gsdl_browser_exe, netscapeneeded);
+}
+
+
+static void dialog_update_enables (HWND hwndDlg) {
+  int res;
+  
+  // if they want to use another browser, they should be able
+  // edit its filename
+  res = SendDlgItemMessage(hwndDlg, ID_RADIO_OTHER, BM_GETCHECK,0,0);
+  SendDlgItemMessage(hwndDlg, ID_OTHER_NAME, WM_ENABLE, (res == 1), 0);
+}
+
+
+static int read_dialog_browser_field (HWND hwndDlg) {
+  if (SendDlgItemMessage(hwndDlg, ID_RADIO_DEFAULT,
+			 BM_GETCHECK, 0, 0) == 1) return GS_DEFAULT;
+  if (SendDlgItemMessage(hwndDlg, ID_RADIO_NETSCAPE,
+			 BM_GETCHECK, 0, 0) == 1) return GS_NETSCAPE;
+  if (SendDlgItemMessage(hwndDlg, ID_RADIO_IE,
+			 BM_GETCHECK, 0, 0) == 1) return GS_IEXPLORE;
+  if (SendDlgItemMessage(hwndDlg, ID_RADIO_OTHER,
+			 BM_GETCHECK, 0, 0) == 1) return GS_OTHER;
+  return GS_NETSCAPE;
+}
+
+
+static void set_dialog_browser_field (HWND hwndDlg, int browser, char *othername) {
+  // if we are trying to set the browser to default, netscape or
+  // internet explorer and we can't find them, set the browser
+  // to 'other'
+  if ((browser == GS_DEFAULT) && (default_browser_exe[0] == '\0'))
+    browser = GS_NETSCAPE;
+  if ((browser == GS_NETSCAPE) && (netscape_exe[0] == '\0'))
+    browser = GS_IEXPLORE;
+  if ((browser == GS_IEXPLORE) && (iexplore_exe[0] == '\0')) {
+    if (netscape_exe[0] != '\0') browser = GS_NETSCAPE;
+    else browser = GS_OTHER;
+  }
+  
+  // update the radio buttons
+  SendDlgItemMessage(hwndDlg, ID_RADIO_DEFAULT, BM_SETCHECK,
+		     (browser == GS_DEFAULT) ? BST_CHECKED : BST_UNCHECKED, 0);
+  SendDlgItemMessage(hwndDlg, ID_RADIO_NETSCAPE, BM_SETCHECK,
+		     (browser == GS_NETSCAPE) ? BST_CHECKED : BST_UNCHECKED, 0);
+  SendDlgItemMessage(hwndDlg, ID_RADIO_IE, BM_SETCHECK,
+		     (browser == GS_IEXPLORE) ? BST_CHECKED : BST_UNCHECKED, 0);
+  SendDlgItemMessage(hwndDlg, ID_RADIO_OTHER, BM_SETCHECK,
+		     (browser == GS_OTHER) ? BST_CHECKED : BST_UNCHECKED, 0);
+  
+  // update the other name field
+  if (browser == GS_DEFAULT) {
+    SetDlgItemText(hwndDlg, ID_OTHER_NAME, default_browser_exe);
+  } else if (browser == GS_NETSCAPE) {
+    SetDlgItemText(hwndDlg, ID_OTHER_NAME, netscape_exe);
+  } else if (browser == GS_IEXPLORE) {
+    SetDlgItemText(hwndDlg, ID_OTHER_NAME, iexplore_exe);
+  } else if (othername != NULL) {
+    SetDlgItemText(hwndDlg, ID_OTHER_NAME, othername);
+  }
+}
+
+
+static void read_browser_exe_field (HWND hwndDlg, char *filename, int maxsize) {
+  filename[0] = '\0';
+  GetDlgItemText(hwndDlg, ID_OTHER_NAME, filename, maxsize);
+}
+
+static int read_address_resolution_field (HWND hwndDlg) {
+  if (SendDlgItemMessage(hwndDlg, ID_ARM_NAME,
+			 BM_GETCHECK, 0, 0) == 1) return ARM_NAME;
+  if (SendDlgItemMessage(hwndDlg, ID_ARM_IP,
+			 BM_GETCHECK, 0, 0) == 1) return ARM_IP;
+  if (SendDlgItemMessage(hwndDlg, ID_ARM_LOCALHOST,
+			 BM_GETCHECK, 0, 0) == 1) return ARM_LOCALHOST;
+  if (SendDlgItemMessage(hwndDlg, ID_ARM_127_0_0_1,
+			 BM_GETCHECK, 0, 0) == 1) return ARM_127_0_0_1;
+  return ARM_NAME;
+}
+
+static void set_address_resolution_field (HWND hwndDlg, 
+					  int address_res_method) {
+  // update the radio buttons
+  SendDlgItemMessage(hwndDlg, ID_ARM_NAME, BM_SETCHECK,
+		     (address_res_method == ARM_NAME) ? BST_CHECKED : BST_UNCHECKED, 0);
+  SendDlgItemMessage(hwndDlg, ID_ARM_IP, BM_SETCHECK,
+		     (address_res_method == ARM_IP) ? BST_CHECKED : BST_UNCHECKED, 0);
+  SendDlgItemMessage(hwndDlg, ID_ARM_LOCALHOST, BM_SETCHECK,
+		     (address_res_method == ARM_LOCALHOST) ? BST_CHECKED : BST_UNCHECKED, 0);
+  SendDlgItemMessage(hwndDlg, ID_ARM_127_0_0_1, BM_SETCHECK,
+		     (address_res_method == ARM_127_0_0_1) ? BST_CHECKED : BST_UNCHECKED, 0);
+
+}
+
+static void read_dialog_fields (HWND hwndDlg) {
+  int res;  BOOL bres;
+  
+  // port number
+  gsdl_port_num = GetDlgItemInt(hwndDlg, SERVER_PORT_EDIT_BOX, &bres, 0);
+  if (!bres) gsdl_port_num = 80;
+
+  // whether to allow external access or not
+  res = SendDlgItemMessage(hwndDlg, ID_EXTERNAL_ACCESS, BM_GETCHECK, 0, 0);
+  gsdl_external_access = (res == 1);
+    
+  // whether to enter the library automatically on startup
+  res = SendDlgItemMessage(hwndDlg, ID_AUTO_ENTER_LIBRARY, BM_GETCHECK, 0, 0);
+  gsdl_auto_enter = (res == 1);
+
+  // which browser to use
+  gsdl_browser = read_dialog_browser_field (hwndDlg);
+  
+  // find out where the browser exe lives
+  read_browser_exe_field (hwndDlg, gsdl_browser_exe, MAX_FILENAME_SIZE);
+
+  // which address resolution method
+  gsdl_address_resolution_method = read_address_resolution_field(hwndDlg);
+}
+
+
+
+
+static BOOL CALLBACK dialog_proc(HWND hwndDlg, UINT uMsg, 
+				 WPARAM wParam,LPARAM  lParam) {
+  int wNotifyCode = HIWORD(wParam);
+  int wID = LOWORD(wParam);
+  char *filefilter = "Program Files (*.exe)\0*.exe\0All Files (*.*)\0*.*\0\0";
+  OPENFILENAME fname;
+  char filename[MAX_FILENAME_SIZE];
+  
+  switch (uMsg) {
+  case WM_INITDIALOG:
+    // set current values
+    SetDlgItemInt(hwndDlg, SERVER_PORT_EDIT_BOX, gsdl_port_num, FALSE);
+    SendDlgItemMessage(hwndDlg, ID_EXTERNAL_ACCESS, BM_SETCHECK,
+		       gsdl_external_access ? 1 : 0, 0);
+    SendDlgItemMessage(hwndDlg, ID_AUTO_ENTER_LIBRARY, BM_SETCHECK,
+		       gsdl_auto_enter ? 1 : 0, 0);
+    set_dialog_browser_field (hwndDlg, gsdl_browser, gsdl_browser_exe);
+    set_address_resolution_field(hwndDlg, gsdl_address_resolution_method);
+    dialog_update_enables(hwndDlg);
+    
+    // make sure that the default browser, netscape and internet explorer
+    // radio buttons are only enabled if they could be found
+    if (default_browser_exe[0] == '\0')
+      EnableWindow (GetDlgItem (hwndDlg, ID_RADIO_DEFAULT), FALSE);
+    if (netscape_exe[0] == '\0')
+      EnableWindow (GetDlgItem (hwndDlg, ID_RADIO_NETSCAPE), FALSE);
+    if (iexplore_exe[0] == '\0')
+      EnableWindow (GetDlgItem (hwndDlg, ID_RADIO_IE), FALSE);
+    
+    return 1;
+    
+  case WM_COMMAND:
+    if (wNotifyCode == BN_CLICKED) {
+      switch (wID) {
+      case ID_CANCEL_BUTTON:
+	EndDialog(hwndDlg, 0);
+	return 1;
+	
+      case ID_OK_BUTTON:
+	// check to make sure we can find the browser
+	filename[0] = '\0';
+	read_browser_exe_field (hwndDlg, filename, MAX_FILENAME_SIZE);
+	if (check_program_exe (filename)) { 
+	  // the file exists
+	  // if netscape is needed, make sure the browser is netscape
+	  _strlwr(filename);
+	  if (!gsdl_netscapeneeded || strstr (filename, "netscape.exe") != NULL) {
+	    // everything is ok
+	    read_dialog_fields(hwndDlg);
+	    EndDialog(hwndDlg, 1);
+	    
+	  } else {
+	    // message: must use netscape with this version
+	    MessageBox(hwndDlg,
+		       "You are using this software on a machine which\n"
+		       "currently does not have a working TCP/IP network layer.\n"
+		       "To allow the Greenstone Digital Library software to use\n"
+		       "its own TCP/IP network layer you must use a Netscape\n"
+		       "web browser.",
+		       "Greenstone Digital Library Software",
+		       MB_OK|MB_APPLMODAL);
+	  }
+	} else {
+	  // message: the file did not exist
+	  MessageBox(hwndDlg,
+		     "Could not find the selected browser. You must have a\n"
+		     "web browser installed to use the Greenstone Digital\n"
+		     "Library software.",
+		     "Greenstone Digital Library Software",
+		     MB_OK|MB_APPLMODAL);
+	}
+	return 1;
+
+      case ID_RADIO_DEFAULT:
+	set_dialog_browser_field (hwndDlg, GS_DEFAULT, NULL);
+	dialog_update_enables(hwndDlg);
+	return 1;
+	
+      case ID_RADIO_NETSCAPE:
+	set_dialog_browser_field (hwndDlg, GS_NETSCAPE, NULL);
+	dialog_update_enables(hwndDlg);
+	return 1;
+	
+      case ID_RADIO_IE:
+	set_dialog_browser_field (hwndDlg, GS_IEXPLORE, NULL);
+	dialog_update_enables(hwndDlg);
+	return 1;
+	
+      case ID_RADIO_OTHER:
+	set_dialog_browser_field (hwndDlg, GS_OTHER, NULL);
+	dialog_update_enables(hwndDlg);
+	return 1;
+	
+      case ID_BROWSE_BUTTON:
+	filename[0] = '\0';
+	memset(&fname, 0, sizeof(OPENFILENAME));
+	fname.lStructSize = sizeof(OPENFILENAME);
+	fname.hwndOwner = hwndDlg;
+	fname.hInstance = NULL;
+	fname.lpstrFilter = filefilter;
+	fname.lpstrCustomFilter = NULL;
+	fname.nMaxCustFilter = 0;
+	fname.nFilterIndex = 1;
+	fname.lpstrFile = filename;
+	fname.nMaxFile = MAX_FILENAME_SIZE-1;
+	fname.lpstrFileTitle = NULL;
+	fname.nMaxFileTitle = 0;
+	fname.lpstrInitialDir = NULL;
+	fname.lpstrTitle = "Choose Web Browser";
+	fname.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
+	
+	if(GetOpenFileName(&fname)) {
+	  set_dialog_browser_field (hwndDlg, GS_OTHER, filename);
+	  dialog_update_enables(hwndDlg);
+	}
+	return 1;
+
+      case ID_ARM_NAME:
+	set_address_resolution_field (hwndDlg, ARM_NAME);
+	dialog_update_enables(hwndDlg);
+	return 1;
+     case ID_ARM_IP:
+	set_address_resolution_field (hwndDlg, ARM_IP);
+	dialog_update_enables(hwndDlg);
+	return 1;
+    case ID_ARM_LOCALHOST:
+	set_address_resolution_field (hwndDlg, ARM_LOCALHOST);
+	dialog_update_enables(hwndDlg);
+	return 1;
+     case ID_ARM_127_0_0_1:
+	set_address_resolution_field (hwndDlg, ARM_127_0_0_1);
+	dialog_update_enables(hwndDlg);
+	return 1;
+
+      }
+    }
+    return 0;
+    
+  case WM_CLOSE:
+  case WM_DESTROY:
+    EndDialog(hwndDlg, 0);
+    return 1;
+  }
+  
+  return 0;
+}
+
+static void dialog_debug_update_enables (HWND hwndDlg) {
+  int res;
+  
+  // if they want a log of program use allow them to
+  // edit its filename
+  res = SendDlgItemMessage(hwndDlg, LOG_CHECK, BM_GETCHECK,0,0);
+  SendDlgItemMessage(hwndDlg, LOG_NAME_BOX, WM_ENABLE, (res == 1), 0);
+}
+
+
+static void read_dialog_debug_fields (HWND hwndDlg) {
+  int res;
+  
+  // whether to log program use
+  res = SendDlgItemMessage(hwndDlg, LOG_CHECK, BM_GETCHECK,0,0);
+  gsdl_keep_log = (res == 1);
+  
+  // log filename
+  res = SendDlgItemMessage(hwndDlg, LOG_NAME_BOX, EM_GETMODIFY,0,0);
+  if (res != 0) {
+    res = GetDlgItemText(hwndDlg, LOG_NAME_BOX, gsdl_log_name, MAX_FILENAME_SIZE);
+  }
+  
+  // whether to display log information on console
+  res = SendDlgItemMessage(hwndDlg, CONSOLE_CHECK, BM_GETCHECK,0,0);
+  gsdl_show_console = (res == 1);
+}
+
+
+static BOOL CALLBACK dialog_debug_proc(HWND hwndDlg, UINT uMsg, 
+				       WPARAM wParam,LPARAM  lParam) {
+  int wNotifyCode = HIWORD(wParam);
+  int wID = LOWORD(wParam);
+  
+  switch (uMsg) {
+  case WM_INITDIALOG:
+    // set current values
+    SendDlgItemMessage(hwndDlg, LOG_CHECK, BM_SETCHECK,
+		       gsdl_keep_log ? 1 : 0, 0);
+    SetDlgItemText(hwndDlg, LOG_NAME_BOX, gsdl_log_name);
+    SendDlgItemMessage(hwndDlg, CONSOLE_CHECK, BM_SETCHECK,
+		       gsdl_show_console ? 1 : 0, 0);
+    dialog_debug_update_enables(hwndDlg);
+    return 1;
+    
+  case WM_COMMAND:
+    if (wNotifyCode == BN_CLICKED) {
+      switch (wID) {
+      case ID_CANCEL_BUTTON:
+	EndDialog(hwndDlg, 0);
+	return 1;
+	
+      case ID_OK_BUTTON:
+	read_dialog_debug_fields(hwndDlg);
+	EndDialog(hwndDlg, 1);
+	return 1;
+	
+      case LOG_CHECK:
+	dialog_debug_update_enables(hwndDlg);
+	return 1;
+      }
+    }
+    return 0;
+    
+  case WM_CLOSE:
+  case WM_DESTROY:
+    EndDialog(hwndDlg, 0);
+    return 1;
+  }
+  
+  return 0;
+}
+
+
+void Settings_Dialog(HWND window, int netscapeneeded)
+{
+  int old_gsdl_show_console = gsdl_show_console;
+  int old_gsdl_port_num = gsdl_port_num;
+  int old_gsdl_external_access = gsdl_external_access;
+  
+  int res = 0;
+  
+  gsdl_netscapeneeded = netscapeneeded;
+  
+  if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) && 
+      (GetAsyncKeyState(VkKeyScan('d')) & 0x8000)) {
+    // control-D was pressed, display debug settings
+    // dialog box
+    res = DialogBox (NULL, MAKEINTRESOURCE(COMMS_DIALOG_DEBUG),
+		     window, (DLGPROC)dialog_debug_proc);
+    
+    if (res == 1) {
+      // only update if exited via the OK button
+      if (gsdl_keep_log) open_log_file(); 
+      else close_log_file();
+      
+      // turn the console on/off if we need to
+      if (gsdl_show_console != old_gsdl_show_console) {
+	if (gsdl_show_console) activate_console ();
+	else deactivate_console ();
+      }
+    }
+    
+  } else {
+    // display normal settings dialog box
+    
+    // make sure everything is up-to-date
+    gsdl_check_browser_settings (netscapeneeded);
+    
+    res = DialogBox (NULL, MAKEINTRESOURCE(COMMS_DIALOG2),
+		     window, (DLGPROC)dialog_proc);
+
+    if (res == 1) {
+      // only update if exited via the OK button
+      if ((gsdl_port_num != old_gsdl_port_num) 
+	  || (gsdl_external_access != old_gsdl_external_access)) {
+	EndHTTPServer();
+	StartHTTPServer(window);
+      }
+    }
+  }
+  
+  // save the settings if we exited via the ok button
+  if (res == 1) {
+    write_settings(gsdl_url);
+    // reset httpprefix in case port number was changed
+    //    configure_httpprefix ();
+  }
+}
Index: /gsdl/stable/runtime-src/src/w32server/settings.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/settings.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/settings.h	(revision 20131)
@@ -0,0 +1,80 @@
+/**********************************************************************
+ *
+ * settings.h
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#define GS_NETSCAPE 0
+#define GS_IEXPLORE 1
+#define GS_OTHER    2
+#define GS_DEFAULT  3
+
+// address resolution methods
+#define ARM_NAME 0
+#define ARM_IP 1
+#define ARM_LOCALHOST 2
+#define ARM_127_0_0_1 3
+
+#include "text_t.h"
+#include "cfgread.h"
+#include "receptionist.h"
+#include "locate.h"
+
+// library settings
+extern text_t gsdl_enterlib;
+extern text_t gsdl_gsdlhome;
+extern text_t gsdl_collecthome;
+extern text_t gsdl_dbhome;
+extern text_t gsdl_collections;
+extern colinfo_tmap gsdl_collectinfo;
+
+extern char gsdl_staticpages[MAX_FILENAME_SIZE];
+
+// debug settings
+extern char gsdl_log_name[MAX_FILENAME_SIZE];
+extern int gsdl_keep_log;
+extern int gsdl_show_console;
+
+// general settings
+extern int gsdl_port_num;
+extern int gsdl_external_access;
+extern int gsdl_auto_enter;
+extern int gsdl_browser;
+extern char gsdl_browser_exe[MAX_FILENAME_SIZE];
+extern text_t gsdl_url;
+extern text_t gsdl_conffile;
+extern int gsdl_start_browser;
+extern int gsdl_address_resolution_method;
+
+void Settings_Dialog(HWND window, int netscapeneeded);
+
+void read_settings (int netscapeneeded);
+void write_settings (const text_t url);
+
+void gsdl_check_browser_settings (int netscapeneeded);
+
+#endif
Index: /gsdl/stable/runtime-src/src/w32server/startbrowser.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/startbrowser.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/startbrowser.cpp	(revision 20131)
@@ -0,0 +1,287 @@
+/**********************************************************************
+ *
+ * startbrowser.cpp
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "startbrowser.h"
+#include <windows.h>
+#include <DDE.H>
+#include <DDEML.H>
+#include <string.h>
+#include <direct.h>
+#include "locate.h"
+
+#define SB_COMLEN 1024
+#define SB_DDETIMEOUT 60000UL  // One minute in milliseconds
+
+int numbrowserstarted = 0;
+
+static int inited = 0;
+
+static DWORD idInst = 0;
+static HINSTANCE hinst = NULL;
+static HSZ hszNetscapeName = NULL;
+static HSZ hszIExploreName = NULL;
+static HSZ hszOpenURLTopic = NULL;
+static HSZ hszActivateTopic = NULL;
+
+// budget callback
+HDDEDATA CALLBACK DdeCallback(UINT uType,     /* transaction type                 */
+			      UINT uFmt,      /* clipboard data format            */
+			      HCONV hconv,    /* handle of conversation           */
+			      HSZ hsz1,       /* handle of string                 */
+			      HSZ hsz2,       /* handle of string                 */
+			      HDDEDATA hdata, /* handle of global memory object   */
+			      DWORD dwData1,  /* transaction-specific data        */
+			      DWORD dwData2)  /* transaction-specific data        */ 
+{
+  return (HDDEDATA) NULL; 
+}
+
+// returns 0 on failure
+static int talkdde (HSZ hszServName, HSZ hszSysTopic, char *requeststr) {
+  HSZ hszRequest;
+  HCONV hConv;
+  HDDEDATA result;
+  
+  // try to connect to the newly started browser
+  hConv = DdeConnect (idInst, hszServName, hszSysTopic, (PCONVCONTEXT) NULL);
+  if (hConv == NULL) return 0;
+  
+  hszRequest = DdeCreateStringHandle (idInst, requeststr, CP_WINANSI);
+  result = DdeClientTransaction (
+				 NULL,          // pointer to data to pass to server
+				 0,             // length of data
+				 hConv,         // handle to conversation
+				 hszRequest,    // handle to item name string
+				 CF_TEXT,       // clipboard data format
+				 XTYP_REQUEST,  // transaction type
+				 SB_DDETIMEOUT, // time-out duration
+				 NULL           // pointer to transaction result
+				 );
+
+  if (result != NULL) DdeFreeDataHandle (result);
+  DdeDisconnect(hConv);
+  DdeFreeStringHandle (idInst, hszRequest);
+
+  return 1;
+}
+
+// returns 0 on failure
+static int openurl(HSZ hszServName, HSZ hszActivateTopic, HSZ hszOpenURLTopic, char *url) {
+  char requeststr[65600];
+  
+  // bring the browser to the front, don't worry if this fails
+  talkdde (hszServName, hszActivateTopic, "0xFFFFFFFF,0x0");
+  
+  // tell the browser to open a url
+  strcpy (requeststr, "\"");
+  strcat (requeststr, url);
+  strcat (requeststr, "\",,0xFFFFFFFF,0x0,,,");
+  
+  return talkdde (hszServName, hszOpenURLTopic, requeststr);
+}
+
+// returns 0 on failure
+static int tryconnect(HSZ hszServName, HSZ hszSysTopic) {
+  // try to connect to a running browser
+  HCONV hConv = DdeConnect (idInst, hszServName, hszSysTopic, (PCONVCONTEXT) NULL);
+  if (hConv == NULL) return 0;
+  DdeDisconnect(hConv);
+  return 1;
+}
+
+static void freestrings () {
+  // free up any currently allocated strings
+  if (hszNetscapeName != NULL) DdeFreeStringHandle (idInst, hszNetscapeName);
+  hszNetscapeName = NULL;
+  if (hszIExploreName != NULL) DdeFreeStringHandle (idInst, hszIExploreName);
+  hszIExploreName = NULL;
+  if (hszOpenURLTopic != NULL) DdeFreeStringHandle (idInst, hszOpenURLTopic);
+  hszOpenURLTopic = NULL;
+  if (hszActivateTopic != NULL) DdeFreeStringHandle (idInst, hszActivateTopic);
+  hszActivateTopic = NULL;
+}
+
+static void getbrowserinfo() {
+  freestrings();
+  
+  hszNetscapeName = DdeCreateStringHandle(idInst,"NETSCAPE",CP_WINANSI);
+  hszIExploreName = DdeCreateStringHandle(idInst,"IExplore",CP_WINANSI);
+  
+  hszOpenURLTopic = DdeCreateStringHandle(idInst,"WWW_OpenURL",CP_WINANSI);
+  hszActivateTopic = DdeCreateStringHandle(idInst,"WWW_Activate",CP_WINANSI);
+}
+
+// returns SB_NOERROR on success, 
+// SB_ALREADYINIT or SB_DDE_FAILINIT on failure
+int initstartbrowser () {
+  if (inited) return SB_ALREADYINIT;
+  
+  // from nstest if(DdeInitialize(&CDDEObject::m_dwidInst, NstestDdeCallBack, APPCLASS_STANDARD, 0ul))
+  if (DdeInitialize (&idInst, (PFNCALLBACK) DdeCallback, 
+		     APPCLASS_STANDARD, 0)
+      != DMLERR_NO_ERROR) {
+    freestrings();
+    inited = 0;
+    return SB_DDE_FAILINIT;
+  }
+
+  getbrowserinfo();
+  
+  inited = 1;
+  return SB_NOERROR;
+}
+
+
+// returns SB_NOERROR on success,
+// SB_DDE_FAILDEINIT of failure
+int deinitstartbrowser () {
+  // make sure this has been inited
+  // not being inited here, however, is not
+  // important
+  if (!inited) return SB_NOERROR;
+  inited = 0;
+  
+  freestrings();
+  
+  if (DdeUninitialize(idInst)) return SB_NOERROR;
+  
+  return SB_DDE_FAILDEINIT;
+}
+
+
+// startbrowser will try to start a browser (or connect to a running browser).
+//
+// Returns SB_NOERROR on success,
+// SB_NOTINITED, SB_FAIL_BADFORMAT, SB_FAIL_NOTFOUND, SB_FAIL_NORESOURCES, or
+// SB_FAILCONNECTBROWSER on failure
+int startbrowser (char *url, char *browser_exe, char *startdir) {
+  char newcommand[SB_COMLEN];
+  int usingnetscape = 0;
+  int usingiexplore = 0;
+  
+  if (!inited) return SB_NOTINITED; // has to be inited first
+  
+  // find out which browser we are dealing with
+  strcpy (newcommand, browser_exe);
+  _strlwr (newcommand);
+  if (strstr (newcommand, "netscape.exe") != NULL) { 
+    // netscape
+    usingnetscape = 1;
+  } else if (strstr (newcommand, "iexplore.exe") != NULL) { 
+    // internet explorer
+    usingiexplore = 1;
+  }
+  
+  // only try to communicate with a running browser if a startdir
+  // is not specified
+  if (startdir == NULL) {
+    if (usingnetscape && hszNetscapeName != NULL && 
+	openurl(hszNetscapeName, hszActivateTopic, hszOpenURLTopic, url)) {
+      return SB_NOERROR;
+    }
+    if (usingiexplore && hszIExploreName != NULL && 
+	openurl(hszIExploreName, hszActivateTopic, hszOpenURLTopic, url)) {
+      return SB_NOERROR;
+    }
+  }
+  
+  strcpy (newcommand, browser_exe);
+  
+  // don't put the url on the command line for internet explorer
+  if (usingiexplore) {
+    strcat (newcommand, " -nohome");
+    
+  } else {
+    // will have to put the url on the command line
+    strcat (newcommand, " \"");
+    strcat (newcommand, url);
+    strcat (newcommand, "\"");
+  }
+  
+  // change the working directory (if needed)
+  char cwd[1024];
+  cwd[0] = '\0';
+  if (startdir != NULL) {
+    _getcwd(cwd, 1024);
+    _chdir(startdir);
+  }
+  
+  // attempt to start the browser
+  int res = WinExec(newcommand, SW_SHOW);
+  
+  // change the working directory back (if needed)
+  if (startdir != NULL) _chdir(cwd);
+  
+  if (res == ERROR_BAD_FORMAT) return SB_FAIL_BADFORMAT;
+  if ((res == ERROR_FILE_NOT_FOUND) || (res == ERROR_PATH_NOT_FOUND)) 
+    return SB_FAIL_NOTFOUND;
+  if (res <= 31) return SB_FAIL_NORESOURCES;
+  
+  ++numbrowserstarted;
+  
+  // if we aren't using iexplore then the url was
+  // put on the command line and there is nothing left to do
+  if (!usingiexplore) return SB_NOERROR;
+  
+  // connect to the browser and get it to open a page,
+  // time out after 1 minute
+  DWORD lastcheck = GetTickCount ();
+  while (DiffTickCounts (lastcheck, GetTickCount()) <= 60000) {
+    if (usingnetscape && hszNetscapeName != NULL && 
+	openurl(hszNetscapeName, hszActivateTopic, hszOpenURLTopic, url)) {
+      return SB_NOERROR;
+    }
+    if (usingiexplore && hszIExploreName != NULL && 
+	openurl(hszIExploreName, hszActivateTopic, hszOpenURLTopic, url)) {
+      return SB_NOERROR;
+    }
+  }
+  
+  // timed out trying to connect to the browser
+  return SB_FAILCONNECTBROWSER;
+}
+
+// returns SB_NOERROR on success,
+// SB_NOTINITED, SB_FAILCONNECTBROWSER on failure
+int browserrunning (char *browser_exe) {
+  char newcommand[SB_COMLEN];
+  if (!inited) return SB_NOTINITED; // has to be inited first
+  
+  strcpy (newcommand, browser_exe);
+  _strlwr (newcommand);
+  
+  if ((strstr (newcommand, "netscape.exe") != NULL) && (hszNetscapeName != NULL) && 
+      tryconnect(hszNetscapeName, hszOpenURLTopic)) {
+    // succeeded connecting to netscape
+    return SB_NOERROR;
+    
+  } else if ((strstr (newcommand, "iexplore.exe") != NULL) && (hszIExploreName != NULL) && 
+	     tryconnect(hszIExploreName, hszOpenURLTopic)) {
+    // succeeded connecting to internet explorer
+    return SB_NOERROR;
+  }
+  
+  return SB_FAILCONNECTBROWSER;
+}
Index: /gsdl/stable/runtime-src/src/w32server/startbrowser.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/startbrowser.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/startbrowser.h	(revision 20131)
@@ -0,0 +1,58 @@
+/**********************************************************************
+ *
+ * startbrowser.h
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#define SB_NOERROR            0
+#define SB_ALREADYINIT        1
+#define SB_DDE_FAILINIT       2
+#define SB_DDE_FAILDEINIT     3
+#define SB_NOTINITED          4
+#define SB_FAIL_BADFORMAT     5
+#define SB_FAIL_NOTFOUND      6
+#define SB_FAIL_NORESOURCES   7
+#define SB_FAILCONNECTBROWSER 9
+
+
+extern int numbrowserstarted;
+
+// initstartbrowser should be called before startbrowser
+//
+// returns SB_NOERROR on success, 
+// SB_ALREADYINIT or SB_DDE_FAILINIT on failure
+int initstartbrowser ();
+
+// returns SB_NOERROR on success,
+// SB_DDE_FAILDEINIT of failure
+int deinitstartbrowser ();
+
+// startbrowser will try to start a browser (or connect to a running browser).
+//
+// Returns SB_NOERROR on success,
+// SB_NOTINITED, SB_FAIL_BADFORMAT, SB_FAIL_NOTFOUND, or SB_FAIL_NORESOURCES, 
+//  on failure
+int startbrowser (char *url, char *browser_exe, char *startdir);
+
+// returns SB_NOERROR on success,
+// SB_NOTINITED, SB_FAILCONNECTBROWSER on failure
+int browserrunning (char *browser_exe);
Index: /gsdl/stable/runtime-src/src/w32server/win32.mak
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/win32.mak	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/win32.mak	(revision 20131)
@@ -0,0 +1,187 @@
+###########################################################################
+#
+# win32 makefile -- src/w32server
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ..\..\..
+COMMON_DIR = $(GSDL_DIR)\common-src
+RUNTIME_DIR = $(GSDL_DIR)\runtime-src
+
+INDEXERS_DIR = $(COMMON_DIR)\indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)\packages
+PACKAGES_DIR = $(RUNTIME_DIR)\packages
+COLSERVR_DIR = $(RUNTIME_DIR)\src\colservr
+PROTOCOL_DIR = $(RUNTIME_DIR)\src\protocol
+RECPT_DIR    = $(RUNTIME_DIR)\src\recpt
+
+
+GSDL_VC4 = 0
+DEBUG = 0
+ENABLE_ACCENTFOLD = 1
+USE_SQLITE = 1
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+LDFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+LDFLAGS = 
+!ENDIF
+
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+!IF $(ENABLE_ACCENTFOLD)
+ACCENTFOLD_LIBS = "$(INDEXERS_DIR)\packages\unac\libunac.lib" "$(INDEXERS_DIR)\packages\windows\iconv\iconv\lib\iconv.lib"
+!ELSE
+ACCENTFOLD_LIBS = 
+!ENDIF
+
+!IF $(USE_SQLITE)
+SQLITE_LIBS = "$(COMMON_PACKAGES_DIR)\sqlite\lib\sqlite3.lib"
+!ELSE
+SQLITE_LIBS = 
+!ENDIF
+
+
+AR = lib
+CC = cl
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H -D_LITTLE_ENDIAN -DPARADOCNUM -DSHORT_SUFFIX -D_CRT_SECURE_NO_DEPRECATE
+INCLUDES = -I"$(GSDL_DIR)" -I"$(COMMON_DIR)\src\lib" -I"$(COLSERVR_DIR)" -I"$(PROTOCOL_DIR)" -I"$(RECPT_DIR)" \
+	-I"$(COLSERVR_DIR)" -I"$(INDEXERS_DIR)\mg" \
+	-I"$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3" -I"$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3\windows" \
+        -I"$(INDEXERS_DIR)\mg\lib" -I"$(INDEXERS_DIR)\mg\src\text" \
+    	-I"$(INDEXERS_DIR)\mgpp\lib" -I"$(INDEXERS_DIR)\mgpp\text"
+
+LIBS = "$(COMMON_PACKAGES_DIR)\windows\crypt\crypt\crypt.lib" "$(COMMON_PACKAGES_DIR)\windows\expat\expat\libexpat.lib" \
+        "$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3\gdbm.lib" $(ACCENTFOLD_LIBS) $(SQLITE_LIBS)
+RSC = rc
+WINLIBS = kernel32.lib user32.lib gdi32.lib winspool.lib \
+          comdlg32.lib advapi32.lib shell32.lib ole32.lib \
+          oleaut32.lib uuid.lib odbc32.lib odbccp32.lib 
+#wsock32.lib
+
+
+!IF $(GSDL_VC4)
+DEFS = $(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I"$(COMMON_PACKAGES_DIR)\windows\stlport\stlport"
+!ENDIF
+
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) -nologo $(LDFLAGS) -Fe"$@"
+
+
+.SUFFIXES:
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $< 
+
+
+SOURCES = \
+	cgiwrapper.cpp \
+	conftools.cpp \
+	d_winsock.cpp \
+	fnord.cpp \
+	httpreq.cpp \
+	httpsend.cpp \
+        httpsrv.cpp \
+	locate.cpp \
+	netio.cpp \
+	parse.cpp \
+	settings.cpp \
+	startbrowser.cpp \
+	wincgiutils.cpp
+
+OBJECTS = \
+	cgiwrapper.obj \
+	conftools.obj \
+	d_winsock.obj \
+	fnord.obj \
+	httpreq.obj \
+	httpsend.obj \
+        httpsrv.obj \
+	locate.obj \
+	netio.obj \
+	parse.obj \
+	settings.obj \
+	startbrowser.obj \
+	wincgiutils.obj
+
+RESOURCES = \
+	server.res
+
+GSDL_LIBS = \
+	"$(RECPT_DIR)\gsdlrecpt.lib" \
+	"$(PROTOCOL_DIR)\gsdlprotocol.lib" \
+	"$(COLSERVR_DIR)\gsdlcolservr.lib" \
+	"$(INDEXERS_DIR)\mg\src\text\libmgtext.lib" \
+	"$(INDEXERS_DIR)\mg\lib\libmglib.lib" \
+	"$(INDEXERS_DIR)\mgpp\text\libmgpptext.lib" \
+	"$(INDEXERS_DIR)\mgpp\lib\libmgpplib.lib" \
+	"$(COMMON_DIR)\src\lib\gsdllib.lib"
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS) \
+	$(RESOURCES) \
+	$(GSDL_LIBS)
+
+EXECUTABLE = server.exe
+
+
+# Default target: make the local library executable
+all: $(EXECUTABLE)
+
+server.exe: $(EXECUTABLE_OBJECTS)
+	$(LINK) $(EXECUTABLE_OBJECTS) $(LIBS) $(WINLIBS) 
+install:
+	copy $(EXECUTABLE) "$(GSDL_DIR)"
+
+clean:
+	del *.obj
+	del $(EXECUTABLE)
+	if exist *.pdb del *.pdb
+
+# Resources stuff
+SOURCE = "$(RUNTIME_DIR)\src\w32server\newgsdl.bmp"
+SOURCE = "$(RUNTIME_DIR)\src\w32server\resource.h"
+SOURCE = "$(RUNTIME_DIR)\src\w32server\server.ico"
+SOURCE = "$(RUNTIME_DIR)\src\w32server\gsdlcol.bmp"
+SOURCE = "$(RUNTIME_DIR)\src\w32server\server.rc"
+DEP_RSC_SERVE=\
+	"$(RUNTIME_DIR)\src\w32server\gsdlcol.bmp"\
+	"$(RUNTIME_DIR)\src\w32server\newgsdl.bmp"\
+	"$(RUNTIME_DIR)\src\w32server\server.ico"
+
+server.res : $(SOURCE) $(DEP_RSC_SERVE) "$(RUNTIME_DIR)\src\w32server"
+   $(RSC) /l 0x409 /fo"$(RUNTIME_DIR)\src\w32server\server.res" /i "$(RUNTIME_DIR)\src\w32server" \
+ /i "$(VCINSTALLDIR)/include/mfc" /d "NDEBUG" $(SOURCE)
+
+"$(RUNTIME_DIR)\src\w32server\server.res" : $(SOURCE) $(DEP_RSC_SERVE) "$(RUNTIME_DIR)\src\w32server"
+   $(RSC) /l 0x409 /fo"$(RUNTIME_DIR)\src\w32server\server.res" /i "$(RUNTIME_DIR)\src\w32server" \
+ /d "NDEBUG" $(SOURCE)
Index: /gsdl/stable/runtime-src/src/w32server/wincgiutils.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/wincgiutils.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/wincgiutils.cpp	(revision 20131)
@@ -0,0 +1,167 @@
+/**********************************************************************
+ *
+ * wincgiutils.cpp
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "text_t.h"
+#include <windows.h>
+#include <string.h>
+#include "netio.h"
+#include "httpreq.h"
+#include "wincgiutils.h"
+
+#define default_http_port 80
+
+// Attempt to break a url into segments. If the parsing fails, 'name' is
+// left pointing to the unparsed portion.
+int parse_url(const text_t &url, text_t &protocol, text_t &machine, 
+	      int *port, text_t &name) {
+
+  protocol.clear();
+  machine.clear();
+  *port = default_http_port;
+  name.clear();
+  
+  text_t::const_iterator begin = url.begin();
+  text_t::const_iterator end = url.end();
+  text_t::const_iterator it = findchar(begin, end, ':');
+  if (it == end) {name = url; return http_error_url_invalid;}
+  if (substr(it+1, it+3) != "//") {name = url; return http_error_url_invalid;}
+  protocol = substr(begin, it);
+  it += 3;
+  while (it < end) {
+    if (*it == ':') {
+      ++it;
+      text_t portstr;
+      while (it != end && (*it >= '0' && *it <= '9')) {
+	portstr.push_back(*it);
+	++it;
+      }
+      *port = portstr.getint();
+      if (it == end) break;
+    }
+
+    if (*it == '/') {
+      while (it != end) {
+	name.push_back(*it);
+	++it;
+      }
+      break;
+    }
+
+    machine.push_back(*it);
+    ++it;
+  }
+  return http_ok;
+}
+
+int Send_String(char *str, RequestInfoT *RInfo)
+{
+  return
+    SendData(RInfo->ClientSocket, (BYTE *)str, strlen(str), RInfo->ThreadNum);
+}
+
+int Send_String_N(char *str, int n,  RequestInfoT *RInfo)
+{
+  return
+    SendData(RInfo->ClientSocket, (BYTE *)str, n, RInfo->ThreadNum);
+}
+
+int send_header(char *content, RequestInfoT *RequestInfo)
+{
+  char Header[1536];  int len, lenc;
+  //Build Header
+  Header[0] = 0;
+  //Status Line
+  if (content[0] != '@')          /*No redirection needed*/
+    strcat(Header, "HTTP/1.0 200 OK\r\n");
+  else                            /*Redirection*/
+    strcat(Header, "HTTP/1.0 302 Relocation\r\n");
+  //Server
+  strcat(Header, "Server: GSDL\r\n");
+  //Content Type
+  strcat(Header, "Content-type: ");
+  if (content[0] != '@')          /*No redirection needed*/
+    strcat(Header, content);
+  else {                          /*Redirection entry*/
+    strcat(Header, "text/html \r\n");
+    strcat(Header, "Location: ");
+    len = strlen(Header);
+    lenc = strlen(content) - 1;
+    strncpy(&Header[len], &content[1], lenc);
+    Header[len+lenc] = 0;
+  }
+  strcat(Header, " \r\n");
+  //Single CRLF to end header
+  strcat(Header, "\r\n");
+  
+  return Send_String(Header, RequestInfo);
+}
+
+void send_retrieve_error(int error_num, char *msg1, char *msg2, RequestInfoT *RequestInfo)
+{
+  char Header[512], Body[512], ErrorNumStr[17], BodyLengthStr[17];
+  DWORD BodyLength; int HeaderLength;
+  
+  itoa(error_num, ErrorNumStr, 10);
+  
+  //Build Data (so we can determine length for the header)
+  Body[0] = 0;
+  strcat(Body, "<HTML><HEAD><TITLE>Server Error</TITLE></HEAD><BODY>\n");
+  strcat(Body, "<H1>Error ");
+  strcat(Body, ErrorNumStr);
+  strcat(Body, ": ");
+  strcat(Body, msg1);
+  strcat(Body, "</H1>\n");
+  strcat(Body, msg2);
+  strcat(Body, "\n</BODY></HTML>");
+  BodyLength = (DWORD) strlen(Body);
+
+  //Build Header
+  Header[0] = 0;
+  //Status Line
+  strcat(Header, "HTTP/1.0 ");
+  strcat(Header, ErrorNumStr);
+  strcat(Header, " ");
+  strcat(Header, msg1);
+  strcat(Header, "\r\n");
+  //Server
+  strcat(Header, "Server: GSDL\r\n");
+  strcat(Header, "Content-Type: text/html\r\n");
+  //Content Length
+  itoa(BodyLength, BodyLengthStr, 10);
+  strcat(Header, "Content-Length: ");
+  strcat(Header, BodyLengthStr);
+  strcat(Header, "\r\n");
+  //Single CRLF to end header
+  strcat(Header, "\r\n");
+  HeaderLength = strlen(Header);
+
+   //Send the file if we have one (and if it's not a HEAD request)
+  SendData(RequestInfo->ClientSocket, (BYTE *) Header, strlen(Header), RequestInfo->ThreadNum);
+  //   if ((FileFound == FALSE) && (strcmpi(RequestFields.MethodStr, "HEAD") != 0)) {
+  //Send generated data
+  SendData(RequestInfo->ClientSocket, (BYTE *) Body, BodyLength, RequestInfo->ThreadNum);
+}
Index: /gsdl/stable/runtime-src/src/w32server/wincgiutils.h
===================================================================
--- /gsdl/stable/runtime-src/src/w32server/wincgiutils.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/w32server/wincgiutils.h	(revision 20131)
@@ -0,0 +1,62 @@
+/**********************************************************************
+ *
+ * wincgiutils.h
+ * Copyright (C) 1996
+ * 
+ * A component of the fnord webserver written by bmorin@wpi.edu.
+ *
+ * Altered for use with the Greenstone digital library software by the
+ * New Zealand Digital Library Project at the University of Waikato,
+ * New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#define http_ok 0
+#define http_error_url_invalid 11
+
+int parse_url(const text_t &url, text_t &protocol, text_t &machine, 
+	      int *port, text_t &name);
+
+struct param_vals {char *name, *value; int vsize; char *dfault; };
+
+
+int Send_String(char *str, RequestInfoT *RInfo);
+int Send_String_N(char *str, int n,  RequestInfoT *RInfo);
+void send_retrieve_error(int error_num, char *msg1, char *msg2, RequestInfoT *RequestInfo);
+int send_header(char *content, RequestInfoT *RequestInfo);
+void decode(char *st);
+void decode_template(int ntemp, param_vals tmplate[]);
+void parse_query_string(char *qstring, int ntemp, param_vals tmplate[]);
+int mg_sender(char *UDoc, int ULen, int DocNum, float Weight, void *RInfo);
+
+#define OUT_CONST_A(t) \
+{if (Send_String_N(t, sizeof(t), RInfo) < 0) return;}
+
+#define OUT_CONST_B(t) \
+{if (Send_String_N(t, sizeof(t), (RequestInfoT *)RInfo) < 0) return -1;}
+
+#define OUT_STRING_A(t) \
+{if (Send_String(t, RInfo) < 0) return;}
+
+#define OUT_STRING_B(t) \
+{if (Send_String(t, (RequestInfoT *)RInfo) < 0) return -1;}
+
+#define OUT_STRING_N_A(t,n) \
+{if (Send_String_N(t, n, RInfo) < 0) return;}
+
+#define OUT_STRING_N_B(t,n) \
+{if (Send_String_N(t, n, (RequestInfoT *)RInfo) < 0) return -1;}
Index: /gsdl/stable/runtime-src/src/z3950/Makefile.in
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/Makefile.in	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/Makefile.in	(revision 20131)
@@ -0,0 +1,162 @@
+###########################################################################
+#
+# Makefile -- runtime-src/src/z3950
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ../../..
+COMMON_DIR = $(GSDL_DIR)/common-src
+RUNTIME_DIR = $(GSDL_DIR)/runtime-src
+
+INDEXERS_DIR = $(COMMON_DIR)/indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)/packages
+RUNTIME_PACKAGES_DIR = $(RUNTIME_DIR)/packages
+COLSERVR_DIR = $(RUNTIME_DIR)/src/colservr
+PROTOCOL_DIR = $(RUNTIME_DIR)/src/protocol
+
+
+ENABLE_ACCENTFOLD = @ENABLE_ACCENTFOLD@
+ifeq ($(ENABLE_ACCENTFOLD), 1)
+ACCENTFOLD_LIBS = $(INDEXERS_DIR)/packages/unac/libunac.a 
+else
+ACCENTFOLD_LIBS = 
+endif
+
+USE_SQLITE = @USE_SQLITE@
+ifeq ($(USE_SQLITE), 1)
+SQLITE_LIBS = $(COMMON_PACKAGES_DIR)/sqlite/lib/libsqlite3.a -ldl -lpthread
+else
+SQLITE_LIBS = 
+endif
+
+USE_Z3950 = @USE_Z3950@
+ifeq ($(USE_Z3950), 1)
+AR = ar
+CC = @CC@
+CPP = @CXX@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CXXFLAGS@
+DEFS = @DEFS@ -DNZDL -DQUIET -DSHORT_SUFFIX -DPARADOCNUM -DGSDLSERVER
+GSDLOS = @gsdlos@
+# Do NOT add the "recpt" directory here: the z39.50 code should be independent of the receptionist!
+INCLUDES = -I. -I$(GSDL_DIR) -I$(COMMON_DIR)/src/lib -I$(COLSERVR_DIR) -I$(PROTOCOL_DIR) \
+	-I$(INDEXERS_DIR)/mgpp/text -I$(RUNTIME_PACKAGES_DIR)/yaz/yaz-2.1.4/include \
+	-I$(RUNTIME_PACKAGES_DIR)/yaz/yaz-2.1.4/client -I$(RUNTIME_PACKAGES_DIR)/d2m
+INSTALL = @INSTALL@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@ $(COMMON_PACKAGES_DIR)/gdbm/lib/libgdbm.a -L$(COMMON_PACKAGES_DIR)/expat/lib -lexpat \
+	$(ACCENTFOLD_LIBS) $(SQLITE_LIBS) \
+	$(RUNTIME_PACKAGES_DIR)/yaz/lib/libyaz.a $(RUNTIME_PACKAGES_DIR)/d2m/libd2m.a -lxml2
+RANLIB = @RANLIB@
+
+
+COMPILE = $(CC) -c $(CFLAGS) $(DEFS) $(INCLUDES)
+CPPCOMPILE = $(CPP) -c $(CPPFLAGS) $(DEFS) $(INCLUDES)
+CPPLINK = $(CPP) $(LDFLAGS) -o $@
+
+
+.SUFFIXES:
+.SUFFIXES: .c .o
+.c.o:
+	$(COMPILE) $<
+
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(CPPCOMPILE) $< 
+
+
+LIBRARY_SOURCES = \
+	yaz_zclient.c \
+	z3950proto.cpp \
+	z3950proxy.cpp \
+	zparse.tab.c \
+	zparse.yy.c
+
+LIBRARY_OBJECTS = \
+	yaz_zclient.o \
+	z3950proto.o \
+	z3950proxy.o \
+	zparse.tab.o \
+	zparse.yy.o
+
+LIBRARY = gsdlz3950.a
+
+SOURCES = \
+	z3950explain.cpp \
+	z3950parser.cpp \
+	z3950server.cpp \
+	z3950_to_gsdl.cpp
+
+OBJECTS = \
+	z3950explain.o \
+	z3950parser.o \
+	z3950server.o \
+	z3950_to_gsdl.o
+
+GSDL_LIBS = \
+	gsdlz3950.a \
+	$(PROTOCOL_DIR)/gsdlprotocol.a \
+	$(COLSERVR_DIR)/gsdlcolservr.a \
+	$(INDEXERS_DIR)/mg/src/text/libmgtext.a \
+	$(INDEXERS_DIR)/mg/lib/libmglib.a \
+	$(INDEXERS_DIR)/mgpp/text/libmgpptext.a \
+	$(INDEXERS_DIR)/mgpp/lib/libmgpplib.a \
+	$(COMMON_DIR)/src/lib/gsdllib.a
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS) \
+	$(GSDL_LIBS)
+
+EXECUTABLE = z3950server
+
+
+# Default target: make both gsdlz3950.a and the z3950server executable
+all: $(LIBRARY) $(EXECUTABLE)
+
+gsdlz3950.a: $(LIBRARY_OBJECTS)
+	rm -f $(LIBRARY)
+	$(AR) cru $(LIBRARY) $(LIBRARY_OBJECTS) $(RUNTIME_PACKAGES_DIR)/yaz/yaz-2.1.4/client/tabcomplete.o
+	$(RANLIB) $(LIBRARY)
+
+z3950server: $(EXECUTABLE_OBJECTS)
+	$(CPPLINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	$(INSTALL) -m 755 -s $(EXECUTABLE) $(GSDL_DIR)/bin/$(GSDLOS)
+
+clean:
+	rm -f $(OBJECTS) $(LIBRARY) $(EXECUTABLE)
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CPPFLAGS) -- $(SOURCES)
+
+else
+all:
+install:
+clean:
+depend:
+endif
+
+distclean: clean
+	rm -f Makefile
+
Index: /gsdl/stable/runtime-src/src/z3950/win32.mak
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/win32.mak	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/win32.mak	(revision 20131)
@@ -0,0 +1,173 @@
+###########################################################################
+#
+# win32 makefile -- src/z3950
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999-2008  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDL_DIR = ..\..\..
+COMMON_DIR = $(GSDL_DIR)\common-src
+RUNTIME_DIR = $(GSDL_DIR)\runtime-src
+
+INDEXERS_DIR = $(COMMON_DIR)\indexers
+COMMON_PACKAGES_DIR = $(COMMON_DIR)\packages
+PACKAGES_DIR = $(RUNTIME_DIR)\packages
+COLSERVR_DIR = $(RUNTIME_DIR)\src\colservr
+PROTOCOL_DIR = $(RUNTIME_DIR)\src\protocol
+
+
+GSDL_VC4 = 0
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+ENABLE_ACCENTFOLD = 1
+USE_SQLITE = 1
+
+!IF $(DEBUG)
+CXXFLAGS = -DEBUG -Z7 /errorReport:prompt
+!ELSE
+CXXFLAGS =
+!ENDIF
+
+!IF $(GSDL_VC4)
+CXXFLAGS = $(CXXFLAGS) -GX
+!ELSE
+CXXFLAGS = $(CXXFLAGS) -EHsc
+!ENDIF
+
+!IF $(DLL)
+CXXFLAGS = $(CXXFLAGS) -MD
+!ELSE
+!IF ($(DLLDEBUG))
+CXXFLAGS = $(CXXFLAGS) -MDd
+!ENDIF
+!ENDIF
+
+!IF $(ENABLE_ACCENTFOLD)
+ACCENTFOLD_LIBS = "$(INDEXERS_DIR)\packages\unac\libunac.lib" "$(INDEXERS_DIR)\packages\windows\iconv\iconv\lib\iconv.lib"
+!ELSE
+ACCENTFOLD_LIBS = 
+!ENDIF
+
+!IF $(USE_SQLITE)
+SQLITE_LIBS = "$(COMMON_PACKAGES_DIR)\sqlite\lib\sqlite3.lib"
+!ELSE
+SQLITE_LIBS = 
+!ENDIF
+
+
+AR = lib
+CC = cl
+DEFS = -D__WIN32__ -DHAVE_CONFIG_H -DPARADOCNUM -D_LITTLE_ENDIAN -DSHORT_SUFFIX -D_CRT_SECURE_NO_DEPRECATE
+# Do NOT add the "recpt" directory here: the z39.50 code should be independent of the receptionist!
+INCLUDES = -I"$(GSDL_DIR)" -I"$(COMMON_DIR)\src\lib" -I"$(COLSERVR_DIR)" -I"$(PROTOCOL_DIR)" \
+	-I"$(INDEXERS_DIR)\mgpp\text" -I"$(PACKAGES_DIR)\yaz\yaz-2.1.4\include" \
+	-I"$(PACKAGES_DIR)\yaz\yaz-2.1.4\client" -I"$(PACKAGES_DIR)\d2m" \
+	-I"$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3" -I"$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3\windows"
+LDFLAGS = 
+LIBS = "$(COMMON_PACKAGES_DIR)\windows\expat\expat\libexpat.lib" "$(COMMON_PACKAGES_DIR)\gdbm\gdbm-1.8.3\gdbm.lib" \
+        "$(PACKAGES_DIR)\d2m\libd2m.lib" "$(PACKAGES_DIR)\yaz\yaz-2.1.4\lib\yaz.lib" $(ACCENTFOLD_LIBS) \
+	$(SQLITE_LIBS)
+
+!IF $(GSDL_VC4)
+DEFS=$(DEFS) -DGSDL_NAMESPACE_BROKEN -DGSDL_USE_IOS_H -D__STL_NO_NEW_IOSTREAMS
+INCLUDES = $(INCLUDES) -I"$(COMMON_PACKAGES_DIR)\windows\stlport\stlport"
+!ENDIF
+
+
+COMPILE = $(CC) -nologo -c $(CXXFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) -nologo -Fe"$@" $(LDFLAGS)
+
+
+.SUFFIXES:
+.SUFFIXES: .c .obj
+.c.obj:
+	$(COMPILE) $<
+
+.SUFFIXES: .cpp .obj
+.cpp.obj:
+	$(COMPILE) $< 
+
+
+LIBRARY_SOURCES = \
+	yaz_zclient.c \
+	z3950proto.cpp \
+	z3950proxy.cpp \
+	zparse.tab.c \
+	zparse.yy.c
+
+LIBRARY_OBJECTS = \
+	yaz_zclient.obj \
+	z3950proto.obj \
+	z3950proxy.obj \
+	zparse.tab.obj \
+	zparse.yy.obj
+
+LIBRARY = gsdlz3950.lib
+
+
+SOURCES = \
+	z3950explain.cpp \
+	z3950parser.cpp \
+	z3950server.cpp \
+	z3950_to_gsdl.cpp
+
+OBJECTS = \
+	z3950explain.obj \
+	z3950parser.obj \
+	z3950server.obj \
+	z3950_to_gsdl.obj
+
+GSDL_LIBS = \
+	gsdlz3950.lib \
+	$(PROTOCOL_DIR)\gsdlprotocol.lib \
+	$(COLSERVR_DIR)\gsdlcolservr.lib \
+	$(INDEXERS_DIR)\mg/src/text/libmgtext.lib \
+	$(INDEXERS_DIR)\mg/lib/libmglib.lib \
+	$(INDEXERS_DIR)\mgpp/text/libmgpptext.lib \
+	$(INDEXERS_DIR)\mgpp/lib/libmgpplib.lib \
+	$(COMMON_DIR)\src\lib\gsdllib.lib
+
+EXECUTABLE_OBJECTS = \
+	$(OBJECTS) \
+	$(GSDL_LIBS)
+
+EXECUTABLE = z3950server.exe
+
+
+# Default target: make both gsdlz3950.lib and z3950server.exe
+all: $(LIBRARY) $(EXECUTABLE)
+
+gsdlz3950.lib: $(LIBRARY_OBJECTS)
+	if EXIST $(LIBRARY) del $(LIBRARY)
+	$(AR) -nologo /out:$(LIBRARY) $(LIBRARY_OBJECTS) $(PACKAGES_DIR)/yaz/yaz-2.1.4/win/obj/tabcomplete.obj
+
+z3950server.exe: $(EXECUTABLE_OBJECTS)
+	$(LINK) $(EXECUTABLE_OBJECTS) $(LIBS)
+
+install: $(EXECUTABLE)
+	copy $(EXECUTABLE) "$(GSDL_DIR)\bin\windows"
+
+clean:
+	del *.obj
+	del $(LIBRARY)
+	del $(EXECUTABLE)
Index: /gsdl/stable/runtime-src/src/z3950/yaz_zclient.c
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/yaz_zclient.c	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/yaz_zclient.c	(revision 20131)
@@ -0,0 +1,5410 @@
+/* 
+ * Copyright (C) 1995-2005, Index Data 
+ * See the file LICENSE for details.
+ *
+ */
+
+/* Modified for the Greenstone Digital Library project, based on yaz 2's client.c
+ kjdon, copying version 1.6 mods done by johnmcp */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <time.h>
+#include <ctype.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_LOCALE_H
+#include <locale.h>
+#endif
+#if HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+/* this one needs to be there
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+*/
+#include <sys/stat.h>
+
+#if HAVE_OPENSSL_SSL_H
+#include <openssl/bio.h>
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#endif
+
+#ifdef __WIN32__
+#include <sys/stat.h>
+#include <io.h>
+#include <windows.h>
+#define S_ISREG(x) (x & _S_IFREG)
+#define S_ISDIR(x) (x & _S_IFDIR)
+#endif
+
+#include <yaz/yaz-util.h>
+
+#include <yaz/comstack.h>
+
+#include <yaz/proto.h>
+#include <yaz/marcdisp.h>
+#include <yaz/diagbib1.h>
+#include <yaz/otherinfo.h>
+#include <yaz/charneg.h>
+
+#include <yaz/pquery.h>
+#include <yaz/sortspec.h>
+
+#include <yaz/ill.h>
+#include <yaz/srw.h>
+#include <yaz/yaz-ccl.h>
+#include <yaz/cql.h>
+#include <yaz/log.h>
+
+#if HAVE_READLINE_READLINE_H
+#include <readline/readline.h>
+#endif
+#if HAVE_READLINE_HISTORY_H
+#include <readline/history.h>
+#endif
+
+/* these files are from the yaz client */
+#include "tabcomplete.h"
+
+#include "yaz_zclient.h"
+
+#define C_PROMPT "Z> "
+
+static char *codeset = 0;               /* character set for output */
+static int hex_dump = 0;
+static char *dump_file_prefix = 0;
+static ODR out, in, print;              /* encoding and decoding streams */
+#if HAVE_XML2
+static ODR srw_sr_odr_out = 0;
+static Z_SRW_PDU *srw_sr = 0;
+#endif
+static FILE *apdu_file = 0;
+static FILE *ber_file = 0;
+static COMSTACK conn = 0;               /* our z-association */
+static Z_IdAuthentication *auth = 0;    /* our current auth definition */
+char *databaseNames[128];
+int num_databaseNames = 0;
+static Z_External *record_last = 0;
+static int setnumber = -1;              /* current result set number */
+static int smallSetUpperBound = 0;
+static int largeSetLowerBound = 1;
+static int mediumSetPresentNumber = 0;
+static Z_ElementSetNames *elementSetNames = 0; 
+static int setno = 1;                   /* current set offset */
+static enum oid_proto protocol = PROTO_Z3950;      /* current app protocol */
+static enum oid_value recordsyntax = VAL_USMARC;
+static char *record_schema = 0;
+static int sent_close = 0;
+static NMEM session_mem = NULL;         /* memory handle for init-response */
+static Z_InitResponse *session = 0;     /* session parameters */
+static char last_scan_line[512] = "0";
+static char last_scan_query[512] = "0";
+static char ccl_fields[512] = "default.bib";
+/* ### How can I set this path to use wherever YAZ is installed? */
+/* ############## change */
+static char cql_fields[512] = "/research/kjdon/home/z3950/gsdl/packages/yaz2/etc/pqf.properties";
+static char *esPackageName = 0;
+static char *yazProxy = 0;
+static int kilobytes = 1024;
+static char *negotiationCharset = 0;
+static int  negotiationCharsetRecords = 1;
+static int  negotiationCharsetVersion = 3;
+static char *outputCharset = 0;
+static char *marcCharset = 0;
+static char* yazLang = 0;
+static char* http_version = "1.1";
+
+static char last_cmd[32] = "?";
+static FILE *marc_file = 0;
+static char *refid = NULL;
+static char *last_open_command = NULL;
+static int auto_reconnect = 0;
+static Odr_bitmask z3950_options;
+static int z3950_version = 3;
+static int scan_stepSize = 0;
+static int scan_position = 1;
+static int scan_size = 20;
+static char cur_host[200];
+
+typedef enum {
+    QueryType_Prefix,
+    QueryType_CCL,
+    QueryType_CCL2RPN,
+    QueryType_CQL,
+    QueryType_CQL2RPN
+} QueryType;
+
+static QueryType queryType = QueryType_Prefix;
+
+static CCL_bibset bibset;               /* CCL bibset handle */
+static cql_transform_t cqltrans;	/* CQL context-set handle */
+
+#if HAVE_READLINE_COMPLETION_OVER
+
+#else
+/* readline doesn't have this var. Define it ourselves. */
+int rl_attempted_completion_over = 0;
+#endif
+
+/* set this one to 1, to avoid decode of unknown MARCs  */
+#define AVOID_MARC_DECODE 1
+
+#define maxOtherInfosSupported 10
+struct {
+    int oidval;
+    char* value;
+} extraOtherInfos[maxOtherInfosSupported];
+	
+
+void process_cmd_line(char* line);
+char ** readline_completer(char *text, int start, int end);
+char *command_generator(const char *text, int state);
+char** curret_global_list=NULL;
+int cmd_register_tab(const char* arg);
+
+static void close_session (void);
+
+ODR getODROutputStream()
+{
+    return out;
+}
+
+const char* query_type_as_string(QueryType q) 
+{
+    switch (q) { 
+    case QueryType_Prefix: return "prefix (RPN sent to server)";
+    case QueryType_CCL: return "CCL (CCL sent to server) ";
+    case QueryType_CCL2RPN: return "CCL -> RPN (RPN sent to server)";
+    case QueryType_CQL: return "CQL (CQL sent to server)";
+    case QueryType_CQL2RPN: return "CQL -> RPN (RPN sent to server)";
+    default: 
+        return "unknown Query type internal yaz-client error";
+    }
+}
+
+static void do_hex_dump(const char* buf, int len) 
+{
+    if (hex_dump)
+    {
+	int i,x;
+	for( i=0; i<len ; i=i+16 ) 
+	{			
+	    printf(" %4.4d ",i);
+	    for(x=0 ; i+x<len && x<16; ++x) 
+	    {
+		printf("%2.2X ",(unsigned int)((unsigned char)buf[i+x]));
+	    }
+	    printf("\n");
+	}
+    }
+    if (dump_file_prefix)
+    {
+	static int no = 0;
+	if (++no < 1000 && strlen(dump_file_prefix) < 500)
+	{
+	    char fname[1024];
+	    FILE *of;
+	    sprintf (fname, "%s.%03d.raw", dump_file_prefix, no);
+	    of = fopen(fname, "wb");
+	    
+	    fwrite (buf, 1, len, of);
+	    
+	    fclose(of);
+	}
+    }
+}
+
+void add_otherInfos(Z_APDU *a) 
+{
+    Z_OtherInformation **oi;
+    int i;
+		
+    yaz_oi_APDU(a, &oi);
+    for(i=0; i<maxOtherInfosSupported; ++i) 
+    {
+        if(extraOtherInfos[i].oidval != -1) 
+            yaz_oi_set_string_oidval(oi, out, extraOtherInfos[i].oidval,
+                                     1, extraOtherInfos[i].value);
+    }   
+}
+
+int send_apdu(Z_APDU *a)
+{
+    char *buf;
+    int len;
+    
+    add_otherInfos(a);
+    
+    if (apdu_file)
+    {
+        z_APDU(print, &a, 0, 0);
+        odr_reset(print);
+    }
+    if (!z_APDU(out, &a, 0, 0))
+    {
+        odr_perror(out, "Encoding APDU");
+        close_session();
+        return 0;
+    }
+    buf = odr_getbuf(out, &len, 0);
+    if (ber_file)
+        odr_dumpBER(ber_file, buf, len);
+    /* printf ("sending APDU of size %d\n", len); */
+    do_hex_dump(buf, len);
+    if (cs_put(conn, buf, len) < 0)
+    {
+        fprintf(stderr, "cs_put: %s", cs_errmsg(cs_errno(conn)));
+        close_session();
+        return 0;
+    }
+    odr_reset(out); /* release the APDU structure  */
+    return 1;
+}
+
+static void print_stringn(const unsigned char *buf, size_t len)
+{
+    size_t i;
+    for (i = 0; i<len; i++)
+        if ((buf[i] <= 126 && buf[i] >= 32) || strchr ("\n\r\t\f", buf[i]))
+            printf ("%c", buf[i]);
+        else
+            printf ("\\X%02X", buf[i]);
+}
+
+static void print_refid (Z_ReferenceId *id)
+{
+    if (id)
+    {
+        printf ("Reference Id: ");
+        print_stringn (id->buf, id->len);
+        printf ("\n");
+    }
+}
+
+static Z_ReferenceId *set_refid (ODR out)
+{
+    Z_ReferenceId *id;
+    if (!refid)
+        return 0;
+    id = (Z_ReferenceId *) odr_malloc (out, sizeof(*id));
+    id->size = id->len = strlen(refid);
+    id->buf = (unsigned char *) odr_malloc (out, id->len);
+    memcpy (id->buf, refid, id->len);
+    return id;
+}   
+
+/* INIT SERVICE ------------------------------- */
+
+static void send_initRequest(const char* type_and_host)
+{
+    Z_APDU *apdu = zget_APDU(out, Z_APDU_initRequest);
+    Z_InitRequest *req = apdu->u.initRequest;
+    int i;
+
+    req->options = &z3950_options;
+
+    ODR_MASK_ZERO(req->protocolVersion);
+    for (i = 0; i<z3950_version; i++)
+	ODR_MASK_SET(req->protocolVersion, i);
+
+    *req->maximumRecordSize = 1024*kilobytes;
+    *req->preferredMessageSize = 1024*kilobytes;
+
+    req->idAuthentication = auth;
+
+    req->referenceId = set_refid (out);
+
+    if (yazProxy && type_and_host) 
+        yaz_oi_set_string_oidval(&req->otherInfo, out, VAL_PROXY,
+        1, type_and_host);
+    
+    if (negotiationCharset || yazLang) {
+    	Z_OtherInformation **p;
+    	Z_OtherInformationUnit *p0;
+    	
+    	yaz_oi_APDU(apdu, &p);
+    	
+    	if ((p0=yaz_oi_update(p, out, NULL, 0, 0))) {
+	    ODR_MASK_SET(req->options, Z_Options_negotiationModel);
+	    
+	    p0->which = Z_OtherInfo_externallyDefinedInfo;
+	    p0->information.externallyDefinedInfo =
+		yaz_set_proposal_charneg(
+		    out,
+		    (const char**)&negotiationCharset, 
+		    negotiationCharset ? 1 : 0,
+		    (const char**)&yazLang, yazLang ? 1 : 0, 
+		    negotiationCharsetRecords);
+    	}
+    }
+    
+    send_apdu(apdu);
+    /* (send_apdu(apdu))
+	intf("Sent initrequest.\n");*/
+}
+
+/* in old version, John had got rid of process_initResponse, and added
+   z_get_initResponse. I'll add this in but leave the other one alone 
+ this returns the info that is used in the description for the 'collection'*/
+char *z_get_initResponse()
+{
+    
+    char* buffer; /* we are returning some info in this buffer */
+    char *text_id="ID: ";
+    char *text_name="<br>\nName: ";
+    char *text_ver="<br>\nVersion: ";
+    size_t initial_length;
+    
+    if (!*session->result)
+	return NULL; /* no init info to return */
+    
+   
+    initial_length = strlen(text_id)+strlen(text_name)+strlen(text_ver)+
+	(session->implementationId?strlen(session->implementationId):0) +
+	(session->implementationName?strlen(session->implementationName):0) +
+	(session->implementationVersion?strlen(session->implementationVersion)
+	 :0)  + 1; /* for null char */
+    
+    if ((buffer = malloc((sizeof(char *))*initial_length)) == NULL) {
+	fprintf(stderr,"Malloc failed while initialising z39.50 server\n");
+	return (NULL);
+    }
+    /* can't pass NULL to sprintf as a (char *) */
+    sprintf(buffer,"%s%s%s%s%s%s",
+	    session->implementationId?text_id:"",
+	    session->implementationId?session->implementationId:"",
+	    session->implementationName?text_name:"",
+	    session->implementationName?session->implementationName:"",
+	    session->implementationVersion?text_ver:"",
+	    session->implementationVersion?session->implementationVersion:""
+	    );
+    return (buffer);
+    
+}
+
+char *z_get_initResponseOld()
+{
+    char *buffer; 
+    size_t needed_length;
+    char *text_id="ID: ";
+    char *text_name="<br>\nName: ";
+    char *text_ver="<br>\nVersion: ";
+    int counter;
+    
+    buffer=NULL;
+    if (!*session->result)
+	return NULL;
+    
+    /* work out total string length needed. Note strlen(NULL) is a bad thing
+       to do. */
+    needed_length=strlen(text_id)+strlen(text_name)+strlen(text_ver)+
+	(session->implementationId?strlen(session->implementationId):0) +
+	(session->implementationName?strlen(session->implementationName):0) +
+	(session->implementationVersion?strlen(session->implementationVersion)
+	 :0) +
+	(session->userInformationField?
+	 strlen(session->userInformationField->u.octet_aligned->buf):0) +
+	1 /* for null char */ ;
+    if ((buffer=malloc((sizeof(char *)) * needed_length))==NULL) {
+	fprintf(stderr,"Malloc failed while initialising z39.50 server\n");
+	return (NULL);
+    }
+    /* can't pass NULL to sprintf as a (char *) */
+    sprintf(buffer,"%s%s%s%s%s%s",
+	    session->implementationId?text_id:"",
+	    session->implementationId?session->implementationId:"",
+	    session->implementationName?text_name:"",
+	    session->implementationName?session->implementationName:"",
+	    session->implementationVersion?text_ver:"",
+	    session->implementationVersion?session->implementationVersion:""
+	    );
+    
+    /* if version 3, also check the other-information parameter of the
+       response. (But check version is 3 first) */
+    if (session->otherInfo)
+	/**** From prt-proto.h *********** (comment added by johnmcp)
+	      typedef struct Z_OtherInformationUnit
+       .   {  Z_InfoCategory *category;        / * OPTIONAL * /
+       .      int which;
+       #define Z_OtherInfo_characterInfo 0
+       #define Z_OtherInfo_binaryInfo 1
+       #define Z_OtherInfo_externallyDefinedInfo 2
+       #define Z_OtherInfo_oid 3
+       .      union
+       .        {
+       .          char *characterInfo; 
+       .          Odr_oct *binaryInfo;
+       .          Z_External *externallyDefinedInfo;
+       .          Odr_oid *oid;
+       .        } information;
+       .   } Z_OtherInformationUnit;
+       
+       typedef struct Z_OtherInformation
+       {
+       int num_elements;
+       Z_OtherInformationUnit **list;
+       } Z_OtherInformation;
+	************/
+	for (counter=0;counter<session->otherInfo->num_elements;counter++) {
+	    if (session->otherInfo->list[counter]->which ==
+		Z_OtherInfo_characterInfo) {
+		
+		/* add this extra string to our buffer */
+		int where=strlen(buffer);
+		buffer=realloc(buffer,where+
+			       strlen(session->otherInfo->list[counter]->
+				      information.characterInfo));
+		strcpy(buffer+where,
+		       session->otherInfo->list[counter]->
+		       information.characterInfo);
+	    }
+	}
+    return (buffer);
+}
+
+
+/* These two are used only from process_initResponse() */
+static void render_initUserInfo(Z_OtherInformation *ui1);
+static void render_diag(Z_DiagnosticFormat *diag);
+
+static void pr_opt(const char *opt, void *clientData)
+{
+    printf (" %s", opt);
+}
+
+static int process_initResponse(Z_InitResponse *res)
+{
+    int ver = 0;
+    /* save session parameters for later use */
+    session_mem = odr_extract_mem(in);
+    session = res;
+
+    for (ver = 0; ver < 8; ver++)
+        if (!ODR_MASK_GET(res->protocolVersion, ver))
+            break;
+
+    if (!*res->result)
+        printf("Connection rejected by v%d target.\n", ver);
+    else
+        printf("Connection accepted by v%d target.\n", ver);
+    if (res->implementationId)
+        printf("ID     : %s\n", res->implementationId);
+    if (res->implementationName)
+        printf("Name   : %s\n", res->implementationName);
+    if (res->implementationVersion)
+        printf("Version: %s\n", res->implementationVersion);
+    if (res->userInformationField)
+    {
+	Z_External *uif = res->userInformationField;
+	if (uif->which == Z_External_userInfo1) {
+	    render_initUserInfo(uif->u.userInfo1);
+	} else {
+	    printf("UserInformationfield:\n");
+	    if (!z_External(print, (Z_External**)&uif, 0, 0))
+	    {
+		odr_perror(print, "Printing userinfo\n");
+		odr_reset(print);
+	    }
+	    if (uif->which == Z_External_octet) {
+		printf("Guessing visiblestring:\n");
+		printf("'%.*s'\n", uif->u.octet_aligned->len,
+		       uif->u.octet_aligned->buf);
+	    }
+	    else if (uif->which == Z_External_single) 
+	    {
+		Odr_any *sat = uif->u.single_ASN1_type;
+		oident *oid = oid_getentbyoid(uif->direct_reference);
+		if (oid->value == VAL_OCLCUI) {
+		    Z_OCLC_UserInformation *oclc_ui;
+		    ODR decode = odr_createmem(ODR_DECODE);
+		    odr_setbuf(decode, sat->buf, sat->len, 0);
+		    if (!z_OCLC_UserInformation(decode, &oclc_ui, 0, 0))
+			printf ("Bad OCLC UserInformation:\n");
+		    else
+			printf ("OCLC UserInformation:\n");
+		    if (!z_OCLC_UserInformation(print, &oclc_ui, 0, 0))
+			printf ("Bad OCLC UserInformation spec\n");
+		    odr_destroy(decode);
+		}
+		else
+		{
+		    /* Peek at any private Init-diagnostic APDUs */
+		    printf("### NAUGHTY: External is '%.*s'\n",
+			   sat->len, sat->buf);
+		}
+	    }
+	    odr_reset (print);
+	}
+    }
+    printf ("Options:");
+    yaz_init_opt_decode(res->options, pr_opt, 0);
+    printf ("\n");
+
+    if (ODR_MASK_GET(res->options, Z_Options_namedResultSets))
+        setnumber = 0;
+    
+    if (ODR_MASK_GET(res->options, Z_Options_negotiationModel)) {
+    
+    	Z_CharSetandLanguageNegotiation *p =
+    		yaz_get_charneg_record(res->otherInfo);
+    	
+    	if (p) {
+            
+            char *charset=NULL, *lang=NULL;
+
+            int selected;
+            
+            yaz_get_response_charneg(session_mem, p, &charset, &lang,
+                                     &selected);
+
+	    if (outputCharset && negotiationCharset) {
+		    odr_set_charset (out, charset, outputCharset);
+		    odr_set_charset (in, outputCharset, charset);
+	    }
+	    else {
+		    odr_set_charset (out, 0, 0);
+		    odr_set_charset (in, 0, 0);
+	    }
+            
+            printf("Accepted character set : %s\n", charset);
+            printf("Accepted code language : %s\n", lang ? lang : "none");
+            printf("Accepted records in ...: %d\n", selected );
+    	}
+    }
+    fflush (stdout);
+    return 0;
+}
+
+
+static void render_initUserInfo(Z_OtherInformation *ui1) {
+    int i;
+    printf("Init response contains %d otherInfo unit%s:\n",
+	   ui1->num_elements, ui1->num_elements == 1 ? "" : "s");
+
+    for (i = 0; i < ui1->num_elements; i++) {
+	Z_OtherInformationUnit *unit = ui1->list[i];
+	printf("  %d: otherInfo unit contains ", i+1);
+	if (unit->which == Z_OtherInfo_externallyDefinedInfo &&
+	    unit->information.externallyDefinedInfo &&
+	    unit->information.externallyDefinedInfo->which ==
+	    Z_External_diag1) {
+	    render_diag(unit->information.externallyDefinedInfo->u.diag1);
+	} 
+	else if (unit->which != Z_OtherInfo_externallyDefinedInfo)
+	{
+	    printf("unsupported otherInfo unit->which = %d\n", unit->which);
+	}
+	else 
+	{
+	    printf("unsupported otherInfo unit external %d\n",
+		   unit->information.externallyDefinedInfo ? 
+		   unit->information.externallyDefinedInfo->which : -2);
+	}
+    }
+}
+
+
+/* ### should this share code with display_diagrecs()? */
+static void render_diag(Z_DiagnosticFormat *diag) {
+    int i;
+
+    printf("%d diagnostic%s:\n", diag->num, diag->num == 1 ? "" : "s");
+    for (i = 0; i < diag->num; i++) {
+	Z_DiagnosticFormat_s *ds = diag->elements[i];
+	printf("    %d: ", i+1);
+	switch (ds->which) {
+	case Z_DiagnosticFormat_s_defaultDiagRec: {
+	    Z_DefaultDiagFormat *dd = ds->u.defaultDiagRec;
+	    /* ### should check `dd->diagnosticSetId' */
+	    printf("code=%d (%s)", *dd->condition,
+		   diagbib1_str(*dd->condition));
+	    /* Both types of addinfo are the same, so use type-pun */
+	    if (dd->u.v2Addinfo != 0)
+		printf(",\n\taddinfo='%s'", dd->u.v2Addinfo);
+	    break;
+	}
+	case Z_DiagnosticFormat_s_explicitDiagnostic:
+	    printf("Explicit diagnostic (not supported)");
+	    break;
+	default:
+	    printf("Unrecognised diagnostic type %d", ds->which);
+	    break;
+	}
+
+	if (ds->message != 0)
+	    printf(", message='%s'", ds->message);
+	printf("\n");
+    }
+}
+
+
+static int set_base(const char *arg)
+{
+    int i;
+    const char *cp;
+
+    for (i = 0; i<num_databaseNames; i++)
+        xfree (databaseNames[i]);
+    num_databaseNames = 0;
+    while (1)
+    {
+        char *cp1;
+        if (!(cp = strchr(arg, ' ')))
+            cp = arg + strlen(arg);
+        if (cp - arg < 1)
+            break;
+        databaseNames[num_databaseNames] = (char *)xmalloc (1 + cp - arg);
+        memcpy (databaseNames[num_databaseNames], arg, cp - arg);
+        databaseNames[num_databaseNames][cp - arg] = '\0';
+
+        for (cp1 = databaseNames[num_databaseNames]; *cp1 ; cp1++)
+            if (*cp1 == '+')
+                *cp1 = ' ';
+        num_databaseNames++;
+
+        if (!*cp)
+            break;
+        arg = cp+1;
+    }
+    if (num_databaseNames == 0)
+    {
+        num_databaseNames = 1;
+        databaseNames[0] = xstrdup("");
+    }
+    return 1;
+}
+
+static int cmd_base(const char *arg)
+{
+    if (!*arg)
+    {
+        printf("Usage: base <database> <database> ...\n");
+        return 0;
+    }
+    return set_base(arg);
+}
+
+void cmd_open_remember_last_open_command(const char* arg, char* new_open_command)
+{
+    if(last_open_command != arg) 
+    {
+        if(last_open_command) xfree(last_open_command);
+        last_open_command = xstrdup(new_open_command);
+    }
+}
+
+int session_connect(const char *arg)
+{
+    void *add;
+    char type_and_host[101];
+    const char *basep = 0;
+#if HAVE_OPENSSL_SSL_H
+    SSL *ssl;
+#endif
+    if (conn)
+    {
+        cs_close (conn);
+        conn = NULL;
+        if (session_mem)
+        {
+            nmem_destroy (session_mem);
+            session_mem = NULL;
+        }
+    }   
+    cs_get_host_args(arg, &basep);
+
+    strncpy(type_and_host, arg, sizeof(type_and_host)-1);
+    type_and_host[sizeof(type_and_host)-1] = '\0';
+
+    cmd_open_remember_last_open_command(arg, type_and_host);
+
+    if (yazProxy)
+        conn = cs_create_host(yazProxy, 1, &add);
+    else
+        conn = cs_create_host(arg, 1, &add);
+    if (!conn)
+    {
+        printf ("Couldn't create comstack\n");
+        return 0;
+    }
+#if HAVE_XML2
+    if (conn->protocol == PROTO_HTTP)
+	queryType = QueryType_CQL;
+#else
+    if (conn->protocol == PROTO_HTTP)
+    {
+        printf ("SRW/HTTP not enabled in this YAZ\n");
+        cs_close(conn);
+        conn = 0;
+        return 0;
+    }
+#endif
+    protocol = conn->protocol;
+    if (conn->protocol == PROTO_HTTP)
+        set_base("");
+    else
+        set_base("Default");
+    /*intf("Connecting...");*/
+    fflush(stdout);
+    if (cs_connect(conn, add) < 0)
+    {
+        printf ("error = %s\n", cs_strerror(conn));
+        if (conn->cerrno == CSYSERR)
+	{
+	    char msg[256];
+	    yaz_strerror(msg, sizeof(msg));
+	    printf ("%s\n", msg);
+	}
+        cs_close(conn);
+        conn = 0;
+        return 0;
+    }
+    /*intf("OK.\n");*/
+#if HAVE_OPENSSL_SSL_H
+    if ((ssl = (SSL *) cs_get_ssl(conn)))
+    {
+	X509 *server_cert = SSL_get_peer_certificate (ssl);
+
+	if (server_cert)
+	{
+	    char *pem_buf;
+	    int pem_len;
+	    BIO *bio = BIO_new(BIO_s_mem());
+
+	    /* get PEM buffer in memory */
+	    PEM_write_bio_X509(bio, server_cert);
+	    pem_len = BIO_get_mem_data(bio, &pem_buf);
+	    fwrite(pem_buf, pem_len, 1, stdout);
+	
+	    /* print all info on screen .. */
+	    X509_print_fp(stdout, server_cert);
+	    BIO_free(bio);
+
+	    X509_free (server_cert);
+	}
+    }
+#endif
+    if (basep && *basep)
+        set_base (basep);
+    if (protocol == PROTO_Z3950)
+    {
+        send_initRequest(type_and_host);
+        return 2;
+    }
+    return 0;
+}
+
+static int cmd_open(const char *arg)
+{
+    if (arg)
+    {
+        strncpy (cur_host, arg, sizeof(cur_host)-1);
+        cur_host[sizeof(cur_host)-1] = 0;
+    }
+    return session_connect(cur_host);
+}
+
+int z_cmd_open(char *host_and_port, char *base)
+{
+    char * full_command = (char *) xmalloc (strlen(host_and_port)+strlen(base)+6);
+    strcpy(full_command, "tcp:");
+    strcat(full_command, host_and_port);
+    strcat(full_command, "/");
+    strcat(full_command, base);
+    return cmd_open(full_command);
+}
+
+
+void try_reconnect() 
+{
+    char* open_command;
+	
+    if(!( auto_reconnect && last_open_command) ) return ;
+
+    open_command = (char *) xmalloc (strlen(last_open_command)+6);
+    strcpy (open_command, "open ");
+	
+    strcat (open_command, last_open_command);
+
+    process_cmd_line(open_command);
+	
+    xfree(open_command);				
+}
+
+int cmd_authentication(const char *arg)
+{
+    static Z_IdAuthentication au;
+    static char user[40], group[40], pass[40];
+    static Z_IdPass idPass;
+    int r;
+
+    if (!*arg)
+    {
+        printf("Auth field set to null\n");
+        auth = 0;
+        return 1;
+    }
+    r = sscanf (arg, "%39s %39s %39s", user, group, pass);
+    if (r == 0)
+    {
+        printf("Authentication set to null\n");
+        auth = 0;
+    }
+    if (r == 1)
+    {
+        auth = &au;
+	if (!strcmp(user, "-")) {
+	    au.which = Z_IdAuthentication_anonymous;
+	    printf("Authentication set to Anonymous\n");
+	} else {
+	    au.which = Z_IdAuthentication_open;
+	    au.u.open = user;
+	    printf("Authentication set to Open (%s)\n", user);
+	}
+    }
+    if (r == 2)
+    {
+        auth = &au;
+        au.which = Z_IdAuthentication_idPass;
+        au.u.idPass = &idPass;
+        idPass.groupId = NULL;
+        idPass.userId = user;
+        idPass.password = group;
+	printf("Authentication set to User (%s), Pass (%s)\n", user, group);
+    }
+    if (r == 3)
+    {
+        auth = &au;
+        au.which = Z_IdAuthentication_idPass;
+        au.u.idPass = &idPass;
+        idPass.groupId = group;
+        idPass.userId = user;
+        idPass.password = pass;
+	printf("Authentication set to User (%s), Group (%s), Pass (%s)\n",
+	       user, group, pass);
+    }
+    return 1;
+}
+
+/* SEARCH SERVICE ------------------------------ */
+static void display_record(Z_External *r);
+
+static void print_record(const unsigned char *buf, size_t len)
+{
+    size_t i = len;
+    print_stringn (buf, len);
+    /* add newline if not already added ... */
+    if (i <= 0 || buf[i-1] != '\n')
+        printf ("\n");
+}
+
+static void display_record(Z_External *r)
+{
+    oident *ent = oid_getentbyoid(r->direct_reference);
+
+    record_last = r;
+    /*
+     * Tell the user what we got.
+     */
+    if (r->direct_reference)
+    {
+        printf("Record type: ");
+        if (ent)
+            printf("%s\n", ent->desc);
+        else if (!odr_oid(print, &r->direct_reference, 0, 0))
+        {
+            odr_perror(print, "print oid");
+            odr_reset(print);
+        }
+    }
+    /* Check if this is a known, ASN.1 type tucked away in an octet string */
+    if (ent && r->which == Z_External_octet)
+    {
+        Z_ext_typeent *type = z_ext_getentbyref(ent->value);
+        char *rr;
+
+        if (type)
+        {
+            /*
+             * Call the given decoder to process the record.
+             */
+            odr_setbuf(in, (char*)r->u.octet_aligned->buf,
+                r->u.octet_aligned->len, 0);
+            if (!(*type->fun)(in, &rr, 0, 0))
+            {
+                odr_perror(in, "Decoding constructed record.");
+                fprintf(stdout, "[Near %d]\n", odr_offset(in));
+                fprintf(stdout, "Packet dump:\n---------\n");
+                odr_dumpBER(stdout, (char*)r->u.octet_aligned->buf,
+                            r->u.octet_aligned->len);
+                fprintf(stdout, "---------\n");
+                
+		/* note just ignores the error ant print the bytes form the octet_aligned later */
+            } else {
+                /*
+                 * Note: we throw away the original, BER-encoded record here.
+                 * Do something else with it if you want to keep it.
+                 */
+                r->u.sutrs = (Z_SUTRS *) rr; /* we don't actually check the type here. */
+                r->which = type->what;
+            }
+        }
+    }
+    if (ent && ent->value == VAL_SOIF)
+    {
+        print_record((const unsigned char *) r->u.octet_aligned->buf,
+                     r->u.octet_aligned->len);
+        if (marc_file)
+            fwrite (r->u.octet_aligned->buf, 1, r->u.octet_aligned->len, marc_file);
+    }
+    else if (r->which == Z_External_octet)
+    {
+        const char *octet_buf = (char*)r->u.octet_aligned->buf;
+        if (ent->oclass == CLASS_RECSYN && 
+		(ent->value == VAL_TEXT_XML || 
+		 ent->value == VAL_APPLICATION_XML ||
+		 ent->value == VAL_HTML))
+        {
+            print_record((const unsigned char *) octet_buf,
+                         r->u.octet_aligned->len);
+        }
+        else if (ent->value == VAL_POSTSCRIPT)
+        {
+            int size = r->u.octet_aligned->len;
+            if (size > 100)
+                size = 100;
+            print_record((const unsigned char *) octet_buf, size);
+        }
+        else
+        {
+            if ( 
+#if AVOID_MARC_DECODE
+                /* primitive check for a marc OID 5.1-29 except 16 */
+                ent->oidsuffix[0] == 5 && ent->oidsuffix[1] < 30 &&
+                ent->oidsuffix[1] != 16
+#else
+                1
+#endif
+                )
+            {
+                char *result;
+                int rlen;
+                yaz_iconv_t cd = 0;
+                yaz_marc_t mt = yaz_marc_create();
+                    
+                if (yaz_marc_decode_buf(mt, octet_buf,r->u.octet_aligned->len,
+                                        &result, &rlen)> 0)
+                {
+                    char *from = 0;
+                    if (marcCharset && !strcmp(marcCharset, "auto"))
+                    {
+                        if (ent->value == VAL_USMARC)
+                        {
+                            if (octet_buf[9] == 'a')
+                                from = "UTF-8";
+                            else
+                                from = "MARC-8";
+                        }
+                        else
+                            from = "ISO-8859-1";
+                    }
+		    else if (marcCharset)
+			from = marcCharset;
+                    if (outputCharset && from)
+                    {   
+                        cd = yaz_iconv_open(outputCharset, from);
+                        printf ("convert from %s to %s", from, 
+                                outputCharset);
+			if (!cd)
+			    printf (" unsupported\n");
+			else
+			    printf ("\n");
+                    }
+                    if (!cd)
+                        fwrite (result, 1, rlen, stdout);
+                    else
+                    {
+                        char outbuf[6];
+                        size_t inbytesleft = rlen;
+                        const char *inp = result;
+                        
+                        while (inbytesleft)
+                        {
+                            size_t outbytesleft = sizeof(outbuf);
+                            char *outp = outbuf;
+			    size_t r;
+
+                            r = yaz_iconv (cd, (char**) &inp,
+					   &inbytesleft, 
+					   &outp, &outbytesleft);
+                            if (r == (size_t) (-1))
+                            {
+                                int e = yaz_iconv_error(cd);
+                                if (e != YAZ_ICONV_E2BIG)
+                                    break;
+                            }
+                            fwrite (outbuf, outp - outbuf, 1, stdout);
+                        }
+                    }
+                }
+		else
+                {
+                    printf ("bad MARC. Dumping as it is:\n");
+                    print_record((const unsigned char*) octet_buf,
+                                  r->u.octet_aligned->len);
+		}	
+                yaz_marc_destroy(mt);
+                if (cd)
+                    yaz_iconv_close(cd);
+            }
+            else
+            {
+                print_record((const unsigned char*) octet_buf,
+                             r->u.octet_aligned->len);
+            }
+        }
+        if (marc_file)
+            fwrite (octet_buf, 1, r->u.octet_aligned->len, marc_file);
+    }
+    else if (ent && ent->value == VAL_SUTRS)
+    {
+        if (r->which != Z_External_sutrs)
+        {
+            printf("Expecting single SUTRS type for SUTRS.\n");
+            return;
+        }
+        print_record(r->u.sutrs->buf, r->u.sutrs->len);
+        if (marc_file)
+            fwrite (r->u.sutrs->buf, 1, r->u.sutrs->len, marc_file);
+    }
+    else if (ent && ent->value == VAL_GRS1)
+    {
+        WRBUF w;
+        if (r->which != Z_External_grs1)
+        {
+            printf("Expecting single GRS type for GRS.\n");
+            return;
+        }
+        w = wrbuf_alloc();
+        yaz_display_grs1(w, r->u.grs1, 0);
+        puts (wrbuf_buf(w));
+        wrbuf_free(w, 1);
+    }
+    else if (ent && ent->value == VAL_OPAC)
+    {
+	int i;
+	if (r->u.opac->bibliographicRecord)
+	    display_record(r->u.opac->bibliographicRecord);
+	for (i = 0; i<r->u.opac->num_holdingsData; i++)
+	{
+	    Z_HoldingsRecord *h = r->u.opac->holdingsData[i];
+	    if (h->which == Z_HoldingsRecord_marcHoldingsRecord)
+	    {
+		printf ("MARC holdings %d\n", i);
+		display_record(h->u.marcHoldingsRecord);
+	    }
+	    else if (h->which == Z_HoldingsRecord_holdingsAndCirc)
+	    {
+		int j;
+
+		Z_HoldingsAndCircData *data = h->u.holdingsAndCirc;
+
+		printf ("Data holdings %d\n", i);
+		if (data->typeOfRecord)
+		    printf ("typeOfRecord: %s\n", data->typeOfRecord);
+		if (data->encodingLevel)
+		    printf ("encodingLevel: %s\n", data->encodingLevel);
+		if (data->receiptAcqStatus)
+		    printf ("receiptAcqStatus: %s\n", data->receiptAcqStatus);
+		if (data->generalRetention)
+		    printf ("generalRetention: %s\n", data->generalRetention);
+		if (data->completeness)
+		    printf ("completeness: %s\n", data->completeness);
+		if (data->dateOfReport)
+		    printf ("dateOfReport: %s\n", data->dateOfReport);
+		if (data->nucCode)
+		    printf ("nucCode: %s\n", data->nucCode);
+		if (data->localLocation)
+		    printf ("localLocation: %s\n", data->localLocation);
+		if (data->shelvingLocation)
+		    printf ("shelvingLocation: %s\n", data->shelvingLocation);
+		if (data->callNumber)
+		    printf ("callNumber: %s\n", data->callNumber);
+		if (data->shelvingData)
+		    printf ("shelvingData: %s\n", data->shelvingData);
+		if (data->copyNumber)
+		    printf ("copyNumber: %s\n", data->copyNumber);
+		if (data->publicNote)
+		    printf ("publicNote: %s\n", data->publicNote);
+		if (data->reproductionNote)
+		    printf ("reproductionNote: %s\n", data->reproductionNote);
+		if (data->termsUseRepro)
+		    printf ("termsUseRepro: %s\n", data->termsUseRepro);
+		if (data->enumAndChron)
+		    printf ("enumAndChron: %s\n", data->enumAndChron);
+		for (j = 0; j<data->num_volumes; j++)
+		{
+		    printf ("volume %d\n", j);
+		    if (data->volumes[j]->enumeration)
+			printf (" enumeration: %s\n",
+				data->volumes[j]->enumeration);
+		    if (data->volumes[j]->chronology)
+			printf (" chronology: %s\n",
+				data->volumes[j]->chronology);
+		    if (data->volumes[j]->enumAndChron)
+			printf (" enumAndChron: %s\n",
+				data->volumes[j]->enumAndChron);
+		}
+		for (j = 0; j<data->num_circulationData; j++)
+		{
+		    printf ("circulation %d\n", j);
+		    if (data->circulationData[j]->availableNow)
+			printf (" availableNow: %d\n",
+				*data->circulationData[j]->availableNow);
+		    if (data->circulationData[j]->availablityDate)
+			printf (" availabiltyDate: %s\n",
+				data->circulationData[j]->availablityDate);
+		    if (data->circulationData[j]->availableThru)
+			printf (" availableThru: %s\n",
+				data->circulationData[j]->availableThru);
+		    if (data->circulationData[j]->restrictions)
+			printf (" restrictions: %s\n",
+				data->circulationData[j]->restrictions);
+		    if (data->circulationData[j]->itemId)
+			printf (" itemId: %s\n",
+				data->circulationData[j]->itemId);
+		    if (data->circulationData[j]->renewable)
+			printf (" renewable: %d\n",
+				*data->circulationData[j]->renewable);
+		    if (data->circulationData[j]->onHold)
+			printf (" onHold: %d\n",
+				*data->circulationData[j]->onHold);
+		    if (data->circulationData[j]->enumAndChron)
+			printf (" enumAndChron: %s\n",
+				data->circulationData[j]->enumAndChron);
+		    if (data->circulationData[j]->midspine)
+			printf (" midspine: %s\n",
+				data->circulationData[j]->midspine);
+		    if (data->circulationData[j]->temporaryLocation)
+			printf (" temporaryLocation: %s\n",
+				data->circulationData[j]->temporaryLocation);
+		}
+	    }
+	}
+    }
+    else 
+    {
+        printf("Unknown record representation.\n");
+        if (!z_External(print, &r, 0, 0))
+        {
+            odr_perror(print, "Printing external");
+            odr_reset(print);
+        }
+    }
+}
+
+static void display_diagrecs(Z_DiagRec **pp, int num)
+{
+    int i;
+    oident *ent;
+    Z_DefaultDiagFormat *r;
+
+    printf("Diagnostic message(s) from database:\n");
+    for (i = 0; i<num; i++)
+    {
+        Z_DiagRec *p = pp[i];
+        if (p->which != Z_DiagRec_defaultFormat)
+        {
+            printf("Diagnostic record not in default format.\n");
+            return;
+        }
+        else
+            r = p->u.defaultFormat;
+        if (!(ent = oid_getentbyoid(r->diagnosticSetId)) ||
+            ent->oclass != CLASS_DIAGSET || ent->value != VAL_BIB1)
+            printf("Missing or unknown diagset\n");
+        printf("    [%d] %s", *r->condition, diagbib1_str(*r->condition));
+        switch (r->which)
+        {
+        case Z_DefaultDiagFormat_v2Addinfo:
+            printf (" -- v2 addinfo '%s'\n", r->u.v2Addinfo);
+            break;
+        case Z_DefaultDiagFormat_v3Addinfo:
+            printf (" -- v3 addinfo '%s'\n", r->u.v3Addinfo);
+            break;
+        }
+    }
+}
+
+
+static void display_nameplusrecord(Z_NamePlusRecord *p)
+{
+    if (p->databaseName)
+        printf("[%s]", p->databaseName);
+    if (p->which == Z_NamePlusRecord_surrogateDiagnostic)
+        display_diagrecs(&p->u.surrogateDiagnostic, 1);
+    else if (p->which == Z_NamePlusRecord_databaseRecord)
+        display_record(p->u.databaseRecord);
+}
+
+static void display_records(Z_Records *p)
+{
+    int i;
+
+    if (p->which == Z_Records_NSD)
+    {
+        Z_DiagRec dr, *dr_p = &dr;
+        dr.which = Z_DiagRec_defaultFormat;
+        dr.u.defaultFormat = p->u.nonSurrogateDiagnostic;
+        display_diagrecs (&dr_p, 1);
+    }
+    else if (p->which == Z_Records_multipleNSD)
+        display_diagrecs (p->u.multipleNonSurDiagnostics->diagRecs,
+                          p->u.multipleNonSurDiagnostics->num_diagRecs);
+    else 
+    {
+        printf("Records: %d\n", p->u.databaseOrSurDiagnostics->num_records);
+        for (i = 0; i < p->u.databaseOrSurDiagnostics->num_records; i++)
+            display_nameplusrecord(p->u.databaseOrSurDiagnostics->records[i]);
+    }
+}
+
+static int send_deleteResultSetRequest(const char *arg)
+{
+    char names[8][32];
+    int i;
+
+    Z_APDU *apdu = zget_APDU(out, Z_APDU_deleteResultSetRequest);
+    Z_DeleteResultSetRequest *req = apdu->u.deleteResultSetRequest;
+
+    req->referenceId = set_refid (out);
+
+    req->num_resultSetList =
+        sscanf (arg, "%30s %30s %30s %30s %30s %30s %30s %30s",
+                names[0], names[1], names[2], names[3],
+                names[4], names[5], names[6], names[7]);
+
+    req->deleteFunction = (int *)
+        odr_malloc (out, sizeof(*req->deleteFunction));
+    if (req->num_resultSetList > 0)
+    {
+        *req->deleteFunction = Z_DeleteResultSetRequest_list;
+        req->resultSetList = (char **)
+            odr_malloc (out, sizeof(*req->resultSetList)*
+                        req->num_resultSetList);
+        for (i = 0; i<req->num_resultSetList; i++)
+            req->resultSetList[i] = names[i];
+    }
+    else
+    {
+        *req->deleteFunction = Z_DeleteResultSetRequest_all;
+        req->resultSetList = 0;
+    }
+    
+    send_apdu(apdu);
+    printf("Sent deleteResultSetRequest.\n");
+    return 2;
+}
+
+#if HAVE_XML2
+static int send_srw(Z_SRW_PDU *sr)
+{
+    const char *charset = negotiationCharset;
+    const char *host_port = cur_host;
+    char *path = 0;
+    char ctype[50];
+    Z_SOAP_Handler h[2] = {
+        {"http://www.loc.gov/zing/srw/", 0, (Z_SOAP_fun) yaz_srw_codec},
+        {0, 0, 0}
+    };
+    ODR o = odr_createmem(ODR_ENCODE);
+    int ret;
+    Z_SOAP *p = odr_malloc(o, sizeof(*p));
+    Z_GDU *gdu;
+
+    path = odr_malloc(out, strlen(databaseNames[0])+2);
+    *path = '/';
+    strcpy(path+1, databaseNames[0]);
+
+    gdu = z_get_HTTP_Request(out);
+    gdu->u.HTTP_Request->version = http_version;
+    gdu->u.HTTP_Request->path = odr_strdup(out, path);
+
+    if (host_port)
+    {
+        const char *cp0 = strstr(host_port, "://");
+        const char *cp1 = 0;
+        if (cp0)
+            cp0 = cp0+3;
+        else
+            cp0 = host_port;
+
+        cp1 = strchr(cp0, '/');
+        if (!cp1)
+            cp1 = cp0+strlen(cp0);
+
+        if (cp0 && cp1)
+        {
+            char *h = odr_malloc(out, cp1 - cp0 + 1);
+            memcpy (h, cp0, cp1 - cp0);
+            h[cp1-cp0] = '\0';
+            z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers,
+                              "Host", h);
+        }
+    }
+
+    strcpy(ctype, "text/xml");
+    if (charset && strlen(charset) < 20)
+    {
+        strcat(ctype, "; charset=");
+        strcat(ctype, charset);
+    }
+    z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers,
+                      "Content-Type", ctype);
+    z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers,
+                      "SOAPAction", "\"\"");
+    p->which = Z_SOAP_generic;
+    p->u.generic = odr_malloc(o, sizeof(*p->u.generic));
+    p->u.generic->no = 0;
+    p->u.generic->ns = 0;
+    p->u.generic->p = sr;
+    p->ns = "http://schemas.xmlsoap.org/soap/envelope/";
+
+    ret = z_soap_codec_enc(o, &p,
+                           &gdu->u.HTTP_Request->content_buf,
+                           &gdu->u.HTTP_Request->content_len, h,
+                           charset);
+
+    if (z_GDU(out, &gdu, 0, 0))
+    {
+        /* encode OK */
+        char *buf_out;
+        int len_out;
+        int r;
+	if (apdu_file)
+	{
+	    if (!z_GDU(print, &gdu, 0, 0))
+		printf ("Failed to print outgoing APDU\n");
+	    odr_reset(print);
+	}
+        buf_out = odr_getbuf(out, &len_out, 0);
+        
+        /* we don't odr_reset(out), since we may need the buffer again */
+
+	do_hex_dump(buf_out, len_out);
+
+        r = cs_put(conn, buf_out, len_out);
+
+        odr_destroy(o);
+        
+        if (r >= 0)
+            return 2;
+    }
+    return 0;
+}
+#endif
+
+#if HAVE_XML2
+static int send_SRW_scanRequest(const char *arg, int pos, int num)
+{
+    Z_SRW_PDU *sr = 0;
+    
+    /* regular requestse .. */
+    sr = yaz_srw_get(out, Z_SRW_scan_request);
+
+    switch(queryType)
+    {
+    case QueryType_CQL:
+	sr->u.scan_request->query_type = Z_SRW_query_type_cql;
+	sr->u.scan_request->scanClause.cql = odr_strdup(out, arg);
+	break;
+    case QueryType_Prefix:
+	sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
+	sr->u.scan_request->scanClause.pqf = odr_strdup(out, arg);
+	break;
+    default:
+	printf ("Only CQL and PQF supported in SRW\n");
+	return 0;
+    }
+    sr->u.scan_request->responsePosition = odr_intdup(out, pos);
+    sr->u.scan_request->maximumTerms = odr_intdup(out, num);
+    return send_srw(sr);
+}
+
+static int send_SRW_searchRequest(const char *arg)
+{
+    Z_SRW_PDU *sr = 0;
+    
+    if (!srw_sr)
+    {
+        assert(srw_sr_odr_out == 0);
+        srw_sr_odr_out = odr_createmem(ODR_ENCODE);
+    }
+    odr_reset(srw_sr_odr_out);
+
+    setno = 1;
+
+    /* save this for later .. when fetching individual records */
+    srw_sr =  yaz_srw_get(srw_sr_odr_out, Z_SRW_searchRetrieve_request);
+    
+    /* regular request .. */
+    sr = yaz_srw_get(out, Z_SRW_searchRetrieve_request);
+
+    switch(queryType)
+    {
+    case QueryType_CQL:
+	srw_sr->u.request->query_type = Z_SRW_query_type_cql;
+	srw_sr->u.request->query.cql = odr_strdup(srw_sr_odr_out, arg);
+
+	sr->u.request->query_type = Z_SRW_query_type_cql;
+	sr->u.request->query.cql = odr_strdup(out, arg);
+	break;
+    case QueryType_Prefix:
+	srw_sr->u.request->query_type = Z_SRW_query_type_pqf;
+	srw_sr->u.request->query.pqf = odr_strdup(srw_sr_odr_out, arg);
+
+	sr->u.request->query_type = Z_SRW_query_type_pqf;
+	sr->u.request->query.pqf = odr_strdup(out, arg);
+	break;
+    default:
+	printf ("Only CQL and PQF supported in SRW\n");
+	return 0;
+    }
+    sr->u.request->maximumRecords = odr_intdup(out, 0);
+
+    if (record_schema)
+        sr->u.request->recordSchema = record_schema;
+    if (recordsyntax == VAL_TEXT_XML)
+        sr->u.explain_request->recordPacking = "xml";
+    return send_srw(sr);
+}
+#endif
+
+static int send_searchRequest(const char *arg)
+{
+    Z_APDU *apdu = zget_APDU(out, Z_APDU_searchRequest);
+    Z_SearchRequest *req = apdu->u.searchRequest;
+    Z_Query query;
+    struct ccl_rpn_node *rpn = NULL;
+    int error, pos;
+    char setstring[100];
+    Z_RPNQuery *RPNquery;
+    Odr_oct ccl_query;
+    YAZ_PQF_Parser pqf_parser;
+    Z_External *ext;
+    QueryType myQueryType = queryType;
+    char pqfbuf[512];
+
+    if (myQueryType == QueryType_CCL2RPN)
+    {
+        rpn = ccl_find_str(bibset, arg, &error, &pos);
+        if (error)
+        {
+            printf("CCL ERROR: %s\n", ccl_err_msg(error));
+            return 0;
+        }
+    } else if (myQueryType == QueryType_CQL2RPN) {
+	/* ### All this code should be wrapped in a utility function */
+	CQL_parser parser;
+	struct cql_node *node;
+	const char *addinfo;
+	if (cqltrans == 0) {
+            printf("Can't use CQL: no translation file.  Try set_cqlfile\n");
+	    return 0;
+	}
+	parser = cql_parser_create();
+	if ((error = cql_parser_string(parser, arg)) != 0) {
+            printf("Can't parse CQL: must be a syntax error\n");
+            return 0;
+	}
+	node = cql_parser_result(parser);
+	if ((error = cql_transform_buf(cqltrans, node, pqfbuf,
+				       sizeof pqfbuf)) != 0) {
+	    error = cql_transform_error(cqltrans, &addinfo);
+	    printf ("Can't convert CQL to PQF: %s (addinfo=%s)\n",
+		    cql_strerror(error), addinfo);
+            return 0;
+        }
+	arg = pqfbuf;
+	myQueryType = QueryType_Prefix;
+    }
+
+    req->referenceId = set_refid (out);
+    if (!strcmp(arg, "@big")) /* strictly for troublemaking */
+    {
+        static unsigned char big[2100];
+        static Odr_oct bigo;
+
+        /* send a very big referenceid to test transport stack etc. */
+        memset(big, 'A', 2100);
+        bigo.len = bigo.size = 2100;
+        bigo.buf = big;
+        req->referenceId = &bigo;
+    }
+    
+    if (setnumber >= 0)
+    {
+        sprintf(setstring, "%d", ++setnumber);
+        req->resultSetName = setstring;
+    }
+    *req->smallSetUpperBound = smallSetUpperBound;
+    *req->largeSetLowerBound = largeSetLowerBound;
+    *req->mediumSetPresentNumber = mediumSetPresentNumber;
+    if (smallSetUpperBound > 0 || (largeSetLowerBound > 1 &&
+        mediumSetPresentNumber > 0))
+    {
+        req->preferredRecordSyntax =
+            yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax);
+
+        req->smallSetElementSetNames =
+            req->mediumSetElementSetNames = elementSetNames;
+    }
+    req->num_databaseNames = num_databaseNames;
+    req->databaseNames = databaseNames;
+
+    req->query = &query;
+
+    switch (myQueryType)
+    {
+    case QueryType_Prefix:
+        query.which = Z_Query_type_1;
+        pqf_parser = yaz_pqf_create ();
+        RPNquery = yaz_pqf_parse (pqf_parser, out, arg);
+        if (!RPNquery)
+        {
+            const char *pqf_msg;
+            size_t off;
+            int code = yaz_pqf_error (pqf_parser, &pqf_msg, &off);
+            printf("%*s^\n", off+4, "");
+            printf("Prefix query error: %s (code %d)\n", pqf_msg, code);
+            
+            yaz_pqf_destroy (pqf_parser);
+            return 0;
+        }
+        yaz_pqf_destroy (pqf_parser);
+        query.u.type_1 = RPNquery;
+        break;
+    case QueryType_CCL:
+        query.which = Z_Query_type_2;
+        query.u.type_2 = &ccl_query;
+        ccl_query.buf = (unsigned char*) arg;
+        ccl_query.len = strlen(arg);
+        break;
+    case QueryType_CCL2RPN:
+        query.which = Z_Query_type_1;
+        RPNquery = ccl_rpn_query(out, rpn);
+        if (!RPNquery)
+        {
+            printf ("Couldn't convert from CCL to RPN\n");
+            return 0;
+        }
+        query.u.type_1 = RPNquery;
+        ccl_rpn_delete (rpn);
+        break;
+    case QueryType_CQL:
+        query.which = Z_Query_type_104;
+        ext = (Z_External *) odr_malloc(out, sizeof(*ext));
+        ext->direct_reference = odr_getoidbystr(out, "1.2.840.10003.16.2");
+        ext->indirect_reference = 0;
+        ext->descriptor = 0;
+        ext->which = Z_External_CQL;
+        ext->u.cql = odr_strdup(out, arg);
+        query.u.type_104 =  ext;
+        break;
+    default:
+        printf ("Unsupported query type\n");
+        return 0;
+    }
+    send_apdu(apdu);
+    /*
+    if (send_apdu(apdu))
+    printf("Sent searchRequest.\n");*/
+    setno = 1;
+    return 2;
+}
+
+/* display Query Expression as part of searchResult-1 */
+/*
+static void display_queryExpression (Z_QueryExpression *qe)
+{
+    if (!qe)
+        return;
+    if (qe->which == Z_QueryExpression_term)
+    {
+        if (qe->u.term->queryTerm)
+        {
+            Z_Term *term = qe->u.term->queryTerm;
+            switch (term->which)
+            {
+            case Z_Term_general:
+                printf (" %.*s", term->u.general->len, term->u.general->buf);
+                break;
+            case Z_Term_characterString:
+                printf (" %s", term->u.characterString);
+                break;
+            case Z_Term_numeric:
+                printf (" %d", *term->u.numeric);
+                break;
+            case Z_Term_null:
+                printf (" null");
+                break;
+            }
+        }
+    }
+}
+*/
+/* see if we can find USR:SearchResult-1 */
+/*
+static void display_searchResult (Z_OtherInformation *o)
+{
+    int i;
+    if (!o)
+        return ;
+    for (i = 0; i < o->num_elements; i++)
+    {
+        if (o->list[i]->which == Z_OtherInfo_externallyDefinedInfo)
+        {
+            Z_External *ext = o->list[i]->information.externallyDefinedInfo;
+            
+            if (ext->which == Z_External_searchResult1)
+            {
+                int j;
+                Z_SearchInfoReport *sr = ext->u.searchResult1;
+                printf ("SearchResult-1:");
+                for (j = 0; j < sr->num; j++)
+                {
+		if (!sr->elements[j]->subqueryExpression)
+                        printf (" %d", j);
+                    display_queryExpression (
+                        sr->elements[j]->subqueryExpression);
+                    display_queryExpression (
+                        sr->elements[j]->subqueryInterpretation);
+                    display_queryExpression (
+                        sr->elements[j]->subqueryRecommendation);
+                    if (sr->elements[j]->subqueryCount)
+                        printf ("(%d)", *sr->elements[j]->subqueryCount);
+                }
+                printf ("\n");
+            }
+        }
+    }
+}
+*/
+/* kjdon: modified to not print the results, and return the number of hits */
+static int process_searchResponse(Z_SearchResponse *res)
+{
+    print_refid (res->referenceId);
+    if (!(*res->searchStatus)) {
+      /* this should return an error instead of 0 docs found... one day... */
+	return 0;
+    }
+    setno += *res->numberOfRecordsReturned;
+    /* what is this for? */
+    if (res->records)
+        display_records(res->records);
+    return *res->resultCount;
+
+}
+
+static void print_level(int iLevel)
+{
+    int i;
+    for (i = 0; i < iLevel * 4; i++)
+        printf(" ");
+}
+
+static void print_int(int iLevel, const char *pTag, int *pInt)
+{
+    if (pInt != NULL)
+    {
+        print_level(iLevel);
+        printf("%s: %d\n", pTag, *pInt);
+    }
+}
+
+static void print_string(int iLevel, const char *pTag, const char *pString)
+{
+    if (pString != NULL)
+    {
+        print_level(iLevel);
+        printf("%s: %s\n", pTag, pString);
+    }
+}
+
+static void print_oid(int iLevel, const char *pTag, Odr_oid *pOid)
+{
+    if (pOid != NULL)
+    {
+        int *pInt = pOid;
+
+        print_level(iLevel);
+        printf("%s:", pTag);
+        for (; *pInt != -1; pInt++)
+            printf(" %d", *pInt);
+        printf("\n");
+    }
+}
+
+static void print_referenceId(int iLevel, Z_ReferenceId *referenceId)
+{
+    if (referenceId != NULL)
+    {
+        int i;
+
+        print_level(iLevel);
+        printf("Ref Id (%d, %d): ", referenceId->len, referenceId->size);
+        for (i = 0; i < referenceId->len; i++)
+            printf("%c", referenceId->buf[i]);
+        printf("\n");
+    }
+}
+
+static void print_string_or_numeric(int iLevel, const char *pTag, Z_StringOrNumeric *pStringNumeric)
+{
+    if (pStringNumeric != NULL)
+    {
+        switch (pStringNumeric->which)
+        {
+        case Z_StringOrNumeric_string:
+            print_string(iLevel, pTag, pStringNumeric->u.string);
+            break;
+            
+        case Z_StringOrNumeric_numeric:
+            print_int(iLevel, pTag, pStringNumeric->u.numeric);
+            break;
+            
+        default:
+            print_level(iLevel);
+            printf("%s: valid type for Z_StringOrNumeric\n", pTag);
+            break;
+        }
+    }
+}
+
+static void print_universe_report_duplicate(
+    int iLevel,
+    Z_UniverseReportDuplicate *pUniverseReportDuplicate)
+{
+    if (pUniverseReportDuplicate != NULL)
+    {
+        print_level(iLevel);
+        printf("Universe Report Duplicate: \n");
+        iLevel++;
+        print_string_or_numeric(iLevel, "Hit No",
+                                pUniverseReportDuplicate->hitno);
+    }
+}
+
+static void print_universe_report_hits(
+    int iLevel,
+    Z_UniverseReportHits *pUniverseReportHits)
+{
+    if (pUniverseReportHits != NULL)
+    {
+        print_level(iLevel);
+        printf("Universe Report Hits: \n");
+        iLevel++;
+        print_string_or_numeric(iLevel, "Database",
+                                pUniverseReportHits->database);
+        print_string_or_numeric(iLevel, "Hits", pUniverseReportHits->hits);
+    }
+}
+
+static void print_universe_report(int iLevel, Z_UniverseReport *pUniverseReport)
+{
+    if (pUniverseReport != NULL)
+    {
+        print_level(iLevel);
+        printf("Universe Report: \n");
+        iLevel++;
+        print_int(iLevel, "Total Hits", pUniverseReport->totalHits);
+        switch (pUniverseReport->which)
+        {
+        case Z_UniverseReport_databaseHits:
+            print_universe_report_hits(iLevel,
+                                       pUniverseReport->u.databaseHits);
+            break;
+            
+        case Z_UniverseReport_duplicate:
+            print_universe_report_duplicate(iLevel,
+                                            pUniverseReport->u.duplicate);
+            break;
+            
+        default:
+            print_level(iLevel);
+            printf("Type: %d\n", pUniverseReport->which);
+            break;
+        }
+    }
+}
+
+static void print_external(int iLevel, Z_External *pExternal)
+{
+    if (pExternal != NULL)
+    {
+        print_level(iLevel);
+        printf("External: \n");
+        iLevel++;
+        print_oid(iLevel, "Direct Reference", pExternal->direct_reference);
+        print_int(iLevel, "InDirect Reference", pExternal->indirect_reference);
+        print_string(iLevel, "Descriptor", pExternal->descriptor);
+        switch (pExternal->which)
+        {
+        case Z_External_universeReport:
+            print_universe_report(iLevel, pExternal->u.universeReport);
+            break;
+            
+        default:
+            print_level(iLevel);
+            printf("Type: %d\n", pExternal->which);
+            break;
+        }
+    }
+}
+
+static int process_resourceControlRequest (Z_ResourceControlRequest *req)
+{
+    printf ("Received ResourceControlRequest.\n");
+    print_referenceId(1, req->referenceId);
+    print_int(1, "Suspended Flag", req->suspendedFlag);
+    print_int(1, "Partial Results Available", req->partialResultsAvailable);
+    print_int(1, "Response Required", req->responseRequired);
+    print_int(1, "Triggered Request Flag", req->triggeredRequestFlag);
+    print_external(1, req->resourceReport);
+    return 0;
+}
+
+void process_ESResponse(Z_ExtendedServicesResponse *res)
+{
+    printf("Status: ");
+    switch (*res->operationStatus)
+    {
+    case Z_ExtendedServicesResponse_done:
+        printf ("done\n");
+        break;
+    case Z_ExtendedServicesResponse_accepted:
+        printf ("accepted\n");
+        break;
+    case Z_ExtendedServicesResponse_failure:
+        printf ("failure\n");
+        display_diagrecs(res->diagnostics, res->num_diagnostics);
+        break;
+    default:
+        printf ("unknown\n");
+    }
+    if ( (*res->operationStatus != Z_ExtendedServicesResponse_failure) &&
+        (res->num_diagnostics != 0) ) {
+        display_diagrecs(res->diagnostics, res->num_diagnostics);
+    }
+    print_refid (res->referenceId);
+    if (res->taskPackage && 
+        res->taskPackage->which == Z_External_extendedService)
+    {
+        Z_TaskPackage *taskPackage = res->taskPackage->u.extendedService;
+        Odr_oct *id = taskPackage->targetReference;
+        Z_External *ext = taskPackage->taskSpecificParameters;
+        
+        if (id)
+        {
+            printf ("Target Reference: ");
+            print_stringn (id->buf, id->len);
+            printf ("\n");
+        }
+        if (ext->which == Z_External_update)
+        {
+            Z_IUUpdateTaskPackage *utp = ext->u.update->u.taskPackage;
+            if (utp && utp->targetPart)
+            {
+                Z_IUTargetPart *targetPart = utp->targetPart;
+                int i;
+
+                for (i = 0; i<targetPart->num_taskPackageRecords;  i++)
+                {
+
+                    Z_IUTaskPackageRecordStructure *tpr =
+                        targetPart->taskPackageRecords[i];
+                    printf ("task package record %d\n", i+1);
+                    if (tpr->which == Z_IUTaskPackageRecordStructure_record)
+                    {
+                        display_record (tpr->u.record);
+                    }
+                    else
+                    {
+                        printf ("other type\n");
+                    }
+                }
+            }
+        }
+    }
+}
+
+const char *get_ill_element (void *clientData, const char *element)
+{
+    return 0;
+}
+
+static Z_External *create_external_itemRequest()
+{
+    struct ill_get_ctl ctl;
+    ILL_ItemRequest *req;
+    Z_External *r = 0;
+    int item_request_size = 0;
+    char *item_request_buf = 0;
+
+    ctl.odr = out;
+    ctl.clientData = 0;
+    ctl.f = get_ill_element;
+    
+    req = ill_get_ItemRequest(&ctl, "ill", 0);
+    if (!req)
+        printf ("ill_get_ItemRequest failed\n");
+        
+    if (!ill_ItemRequest (out, &req, 0, 0))
+    {
+        if (apdu_file)
+        {
+            ill_ItemRequest(print, &req, 0, 0);
+            odr_reset(print);
+        }
+        item_request_buf = odr_getbuf (out, &item_request_size, 0);
+        if (item_request_buf)
+            odr_setbuf (out, item_request_buf, item_request_size, 1);
+        printf ("Couldn't encode ItemRequest, size %d\n", item_request_size);
+        return 0;
+    }
+    else
+    {
+        oident oid;
+        
+        item_request_buf = odr_getbuf (out, &item_request_size, 0);
+        oid.proto = PROTO_GENERAL;
+        oid.oclass = CLASS_GENERAL;
+        oid.value = VAL_ISO_ILL_1;
+        
+        r = (Z_External *) odr_malloc (out, sizeof(*r));
+        r->direct_reference = odr_oiddup(out,oid_getoidbyent(&oid)); 
+        r->indirect_reference = 0;
+        r->descriptor = 0;
+        r->which = Z_External_single;
+        
+        r->u.single_ASN1_type = (Odr_oct *)
+            odr_malloc (out, sizeof(*r->u.single_ASN1_type));
+        r->u.single_ASN1_type->buf = (unsigned char *)
+        odr_malloc (out, item_request_size);
+        r->u.single_ASN1_type->len = item_request_size;
+        r->u.single_ASN1_type->size = item_request_size;
+        memcpy (r->u.single_ASN1_type->buf, item_request_buf,
+                item_request_size);
+        
+        do_hex_dump(item_request_buf,item_request_size);
+    }
+    return r;
+}
+
+static Z_External *create_external_ILL_APDU(int which)
+{
+    struct ill_get_ctl ctl;
+    ILL_APDU *ill_apdu;
+    Z_External *r = 0;
+    int ill_request_size = 0;
+    char *ill_request_buf = 0;
+        
+    ctl.odr = out;
+    ctl.clientData = 0;
+    ctl.f = get_ill_element;
+
+    ill_apdu = ill_get_APDU(&ctl, "ill", 0);
+
+    if (!ill_APDU (out, &ill_apdu, 0, 0))
+    {
+        if (apdu_file)
+        {
+            printf ("-------------------\n");
+            ill_APDU(print, &ill_apdu, 0, 0);
+            odr_reset(print);
+            printf ("-------------------\n");
+        }
+        ill_request_buf = odr_getbuf (out, &ill_request_size, 0);
+        if (ill_request_buf)
+            odr_setbuf (out, ill_request_buf, ill_request_size, 1);
+        printf ("Couldn't encode ILL-Request, size %d\n", ill_request_size);
+        return 0;
+    }
+    else
+    {
+        oident oid;
+        ill_request_buf = odr_getbuf (out, &ill_request_size, 0);
+        
+        oid.proto = PROTO_GENERAL;
+        oid.oclass = CLASS_GENERAL;
+        oid.value = VAL_ISO_ILL_1;
+        
+        r = (Z_External *) odr_malloc (out, sizeof(*r));
+        r->direct_reference = odr_oiddup(out,oid_getoidbyent(&oid)); 
+        r->indirect_reference = 0;
+        r->descriptor = 0;
+        r->which = Z_External_single;
+        
+        r->u.single_ASN1_type = (Odr_oct *)
+            odr_malloc (out, sizeof(*r->u.single_ASN1_type));
+        r->u.single_ASN1_type->buf = (unsigned char *)
+        odr_malloc (out, ill_request_size);
+        r->u.single_ASN1_type->len = ill_request_size;
+        r->u.single_ASN1_type->size = ill_request_size;
+        memcpy (r->u.single_ASN1_type->buf, ill_request_buf, ill_request_size);
+/*         printf ("len = %d\n", ill_request_size); */
+/* 		do_hex_dump(ill_request_buf,ill_request_size); */
+/* 		printf("--- end of extenal\n"); */
+
+    }
+    return r;
+}
+
+
+static Z_External *create_ItemOrderExternal(const char *type, int itemno)
+{
+    Z_External *r = (Z_External *) odr_malloc(out, sizeof(Z_External));
+    oident ItemOrderRequest;
+  
+    ItemOrderRequest.proto = PROTO_Z3950;
+    ItemOrderRequest.oclass = CLASS_EXTSERV;
+    ItemOrderRequest.value = VAL_ITEMORDER;
+ 
+    r->direct_reference = odr_oiddup(out,oid_getoidbyent(&ItemOrderRequest)); 
+    r->indirect_reference = 0;
+    r->descriptor = 0;
+
+    r->which = Z_External_itemOrder;
+
+    r->u.itemOrder = (Z_ItemOrder *) odr_malloc(out,sizeof(Z_ItemOrder));
+    memset(r->u.itemOrder, 0, sizeof(Z_ItemOrder));
+    r->u.itemOrder->which=Z_IOItemOrder_esRequest;
+
+    r->u.itemOrder->u.esRequest = (Z_IORequest *) 
+        odr_malloc(out,sizeof(Z_IORequest));
+    memset(r->u.itemOrder->u.esRequest, 0, sizeof(Z_IORequest));
+
+    r->u.itemOrder->u.esRequest->toKeep = (Z_IOOriginPartToKeep *)
+        odr_malloc(out,sizeof(Z_IOOriginPartToKeep));
+    memset(r->u.itemOrder->u.esRequest->toKeep, 0, sizeof(Z_IOOriginPartToKeep));
+    r->u.itemOrder->u.esRequest->notToKeep = (Z_IOOriginPartNotToKeep *)
+        odr_malloc(out,sizeof(Z_IOOriginPartNotToKeep));
+    memset(r->u.itemOrder->u.esRequest->notToKeep, 0, sizeof(Z_IOOriginPartNotToKeep));
+
+    r->u.itemOrder->u.esRequest->toKeep->supplDescription = NULL;
+    r->u.itemOrder->u.esRequest->toKeep->contact = NULL;
+    r->u.itemOrder->u.esRequest->toKeep->addlBilling = NULL;
+
+    r->u.itemOrder->u.esRequest->notToKeep->resultSetItem =
+        (Z_IOResultSetItem *) odr_malloc(out, sizeof(Z_IOResultSetItem));
+    memset(r->u.itemOrder->u.esRequest->notToKeep->resultSetItem, 0, sizeof(Z_IOResultSetItem));
+    r->u.itemOrder->u.esRequest->notToKeep->resultSetItem->resultSetId = "1";
+
+    r->u.itemOrder->u.esRequest->notToKeep->resultSetItem->item =
+        (int *) odr_malloc(out, sizeof(int));
+    *r->u.itemOrder->u.esRequest->notToKeep->resultSetItem->item = itemno;
+
+    if (!strcmp (type, "item") || !strcmp(type, "2"))
+    {
+        printf ("using item-request\n");
+        r->u.itemOrder->u.esRequest->notToKeep->itemRequest = 
+            create_external_itemRequest();
+    }
+    else if (!strcmp(type, "ill") || !strcmp(type, "1"))
+    {
+        printf ("using ILL-request\n");
+        r->u.itemOrder->u.esRequest->notToKeep->itemRequest = 
+            create_external_ILL_APDU(ILL_APDU_ILL_Request);
+    }
+    else if (!strcmp(type, "xml") || !strcmp(type, "3"))
+    {
+    const char *xml_buf =
+        "<itemorder>\n"
+        "  <type>request</type>\n"
+        "  <libraryNo>000200</libraryNo>\n"
+        "  <borrowerTicketNo> 1212 </borrowerTicketNo>\n"
+        "</itemorder>";
+        r->u.itemOrder->u.esRequest->notToKeep->itemRequest =
+            z_ext_record (out, VAL_TEXT_XML, xml_buf, strlen(xml_buf));
+    }
+    else
+        r->u.itemOrder->u.esRequest->notToKeep->itemRequest = 0;
+
+    return r;
+}
+
+static int send_itemorder(const char *type, int itemno)
+{
+    Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest);
+    Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
+    oident ItemOrderRequest;
+
+    ItemOrderRequest.proto = PROTO_Z3950;
+    ItemOrderRequest.oclass = CLASS_EXTSERV;
+    ItemOrderRequest.value = VAL_ITEMORDER;
+    req->packageType = odr_oiddup(out,oid_getoidbyent(&ItemOrderRequest));
+    req->packageName = esPackageName;
+
+    req->taskSpecificParameters = create_ItemOrderExternal(type, itemno);
+
+    send_apdu(apdu);
+    return 0;
+}
+
+static int only_z3950()
+{
+    if (protocol == PROTO_HTTP)
+    {
+	printf ("Not supported by SRW\n");
+	return 1;
+    }
+    return 0;
+}
+
+
+static int cmd_update_common(const char *arg, int version);
+
+static int cmd_update(const char *arg)
+{
+    return cmd_update_common(arg, 1);
+}
+
+static int cmd_update0(const char *arg)
+{
+    return cmd_update_common(arg, 0);
+}
+
+static int cmd_update_common(const char *arg, int version)
+{
+    Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest );
+    Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
+    Z_External *r;
+    char action[20], recid[20], fname[80];
+    int action_no;
+    Z_External *record_this = 0;
+
+    if (only_z3950())
+	return 0;
+    *action = 0;
+    *recid = 0;
+    *fname = 0;
+    sscanf (arg, "%19s %19s %79s", action, recid, fname);
+
+    if (!strcmp (action, "insert"))
+        action_no = Z_IUOriginPartToKeep_recordInsert;
+    else if (!strcmp (action, "replace"))
+        action_no = Z_IUOriginPartToKeep_recordReplace;
+    else if (!strcmp (action, "delete"))
+        action_no = Z_IUOriginPartToKeep_recordDelete;
+    else if (!strcmp (action, "update"))
+        action_no = Z_IUOriginPartToKeep_specialUpdate;
+    else 
+    {
+        printf ("Bad action: %s\n", action);
+        printf ("Possible values: insert, replace, delete, update\n");
+        return 0;
+    }
+
+    if (*fname)
+    {
+        FILE *inf;
+        struct stat status;
+        stat (fname, &status);
+        if (S_ISREG(status.st_mode) && (inf = fopen(fname, "rb")))
+        {
+            size_t len = status.st_size;
+            char *buf = (char *) xmalloc (len);
+
+            fread (buf, 1, len, inf);
+
+            fclose (inf);
+            
+            record_this = z_ext_record (out, VAL_TEXT_XML, buf, len);
+            
+            xfree (buf);
+        }
+        else
+        {
+            printf ("File %s doesn't exist\n", fname);
+            return 0;
+        }
+    }
+    else
+    {
+        if (!record_last)
+        {
+            printf ("No last record (update ignored)\n");
+            return 0;
+        }
+        record_this = record_last;
+    }
+
+    req->packageType =
+	yaz_oidval_to_z3950oid(out, CLASS_EXTSERV,
+			       version == 0 ? VAL_DBUPDATE0 : VAL_DBUPDATE);
+
+    req->packageName = esPackageName;
+    
+    req->referenceId = set_refid (out);
+
+    r = req->taskSpecificParameters = (Z_External *)
+        odr_malloc (out, sizeof(*r));
+    r->direct_reference = req->packageType;
+    r->indirect_reference = 0;
+    r->descriptor = 0;
+    if (version == 0)
+    {
+	Z_IU0OriginPartToKeep *toKeep;
+	Z_IU0SuppliedRecords *notToKeep;
+
+	r->which = Z_External_update0;
+	r->u.update0 = (Z_IU0Update *) odr_malloc(out, sizeof(*r->u.update0));
+	r->u.update0->which = Z_IUUpdate_esRequest;
+	r->u.update0->u.esRequest = (Z_IU0UpdateEsRequest *)
+	    odr_malloc(out, sizeof(*r->u.update0->u.esRequest));
+	toKeep = r->u.update0->u.esRequest->toKeep = (Z_IU0OriginPartToKeep *)
+	    odr_malloc(out, sizeof(*r->u.update0->u.esRequest->toKeep));
+	
+	toKeep->databaseName = databaseNames[0];
+	toKeep->schema = 0;
+	toKeep->elementSetName = 0;
+
+	toKeep->action = (int *) odr_malloc(out, sizeof(*toKeep->action));
+	*toKeep->action = action_no;
+	
+	notToKeep = r->u.update0->u.esRequest->notToKeep = (Z_IU0SuppliedRecords *)
+	    odr_malloc(out, sizeof(*r->u.update0->u.esRequest->notToKeep));
+	notToKeep->num = 1;
+	notToKeep->elements = (Z_IU0SuppliedRecords_elem **)
+	    odr_malloc(out, sizeof(*notToKeep->elements));
+	notToKeep->elements[0] = (Z_IU0SuppliedRecords_elem *)
+	    odr_malloc(out, sizeof(**notToKeep->elements));
+	notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque;
+	if (*recid)
+	{
+	    notToKeep->elements[0]->u.opaque = (Odr_oct *)
+		odr_malloc (out, sizeof(Odr_oct));
+	    notToKeep->elements[0]->u.opaque->buf = (unsigned char *) recid;
+	    notToKeep->elements[0]->u.opaque->size = strlen(recid);
+	    notToKeep->elements[0]->u.opaque->len = strlen(recid);
+	}
+	else
+	    notToKeep->elements[0]->u.opaque = 0;
+	notToKeep->elements[0]->supplementalId = 0;
+	notToKeep->elements[0]->correlationInfo = 0;
+	notToKeep->elements[0]->record = record_this;
+    }
+    else
+    {
+	Z_IUOriginPartToKeep *toKeep;
+	Z_IUSuppliedRecords *notToKeep;
+
+	r->which = Z_External_update;
+	r->u.update = (Z_IUUpdate *) odr_malloc(out, sizeof(*r->u.update));
+	r->u.update->which = Z_IUUpdate_esRequest;
+	r->u.update->u.esRequest = (Z_IUUpdateEsRequest *)
+	    odr_malloc(out, sizeof(*r->u.update->u.esRequest));
+	toKeep = r->u.update->u.esRequest->toKeep = (Z_IUOriginPartToKeep *)
+	    odr_malloc(out, sizeof(*r->u.update->u.esRequest->toKeep));
+	
+	toKeep->databaseName = databaseNames[0];
+	toKeep->schema = 0;
+	toKeep->elementSetName = 0;
+	toKeep->actionQualifier = 0;
+	toKeep->action = (int *) odr_malloc(out, sizeof(*toKeep->action));
+	*toKeep->action = action_no;
+
+	notToKeep = r->u.update->u.esRequest->notToKeep = (Z_IUSuppliedRecords *)
+	    odr_malloc(out, sizeof(*r->u.update->u.esRequest->notToKeep));
+	notToKeep->num = 1;
+	notToKeep->elements = (Z_IUSuppliedRecords_elem **)
+	    odr_malloc(out, sizeof(*notToKeep->elements));
+	notToKeep->elements[0] = (Z_IUSuppliedRecords_elem *)
+	    odr_malloc(out, sizeof(**notToKeep->elements));
+	notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque;
+	if (*recid)
+	{
+	    notToKeep->elements[0]->u.opaque = (Odr_oct *)
+		odr_malloc (out, sizeof(Odr_oct));
+	    notToKeep->elements[0]->u.opaque->buf = (unsigned char *) recid;
+	    notToKeep->elements[0]->u.opaque->size = strlen(recid);
+	    notToKeep->elements[0]->u.opaque->len = strlen(recid);
+	}
+	else
+	    notToKeep->elements[0]->u.opaque = 0;
+	notToKeep->elements[0]->supplementalId = 0;
+	notToKeep->elements[0]->correlationInfo = 0;
+	notToKeep->elements[0]->record = record_this;
+    }
+    
+    send_apdu(apdu);
+
+    return 2;
+}
+
+
+static int cmd_itemorder(const char *arg)
+{
+    char type[12];
+    int itemno;
+   
+    if (only_z3950())
+	return 0;
+    if (sscanf (arg, "%10s %d", type, &itemno) != 2)
+        return 0;
+
+    printf("Item order request\n");
+    fflush(stdout);
+    send_itemorder(type, itemno);
+    return 2;
+}
+
+static void show_opt(const char *arg, void *clientData)
+{
+    printf ("%s ", arg);
+}
+
+static int cmd_zversion(const char *arg)
+{
+    if (*arg && arg)
+	z3950_version = atoi(arg);
+    else
+	printf ("version is %d\n", z3950_version);
+    return 0;
+}
+
+static int cmd_options(const char *arg)
+{
+    if (*arg)
+    {
+	int r;
+	int pos;
+	r = yaz_init_opt_encode(&z3950_options, arg, &pos);
+    }
+    else
+    {
+	yaz_init_opt_decode(&z3950_options, show_opt, 0);
+	printf ("\n");
+    }
+    return 0;
+}
+
+static int cmd_explain(const char *arg)
+{
+    if (protocol != PROTO_HTTP)
+	return 0;
+#if HAVE_XML2
+    if (!conn)
+	cmd_open(0);
+    if (conn)
+    {
+	Z_SRW_PDU *sr = 0;
+	
+	setno = 1;
+	
+	/* save this for later .. when fetching individual records */
+	sr = yaz_srw_get(out, Z_SRW_explain_request);
+	if (recordsyntax == VAL_TEXT_XML)
+            sr->u.explain_request->recordPacking = "xml";
+	send_srw(sr);
+	return 2;
+    }
+#endif
+    return 0;
+}
+
+static int cmd_init(const char *arg)
+{
+    if (*arg)
+    {
+        strncpy (cur_host, arg, sizeof(cur_host)-1);
+        cur_host[sizeof(cur_host)-1] = 0;
+    }
+    if (!conn || protocol != PROTO_Z3950)
+       return 0;
+    send_initRequest(cur_host);
+    return 2;
+
+}
+
+static int cmd_find(const char *arg)
+{
+    if (!*arg)
+    {
+        printf("Find what?\n");
+        return 0;
+    }
+    if (protocol == PROTO_HTTP)
+    {
+#if HAVE_XML2
+        if (!conn)
+            cmd_open(0);
+	if (!conn)
+	    return 0;
+        if (!send_SRW_searchRequest(arg))
+            return 0;
+#else
+        return 0;
+#endif
+    }
+    else
+    {
+        if (!conn)
+        {
+            try_reconnect(); 
+            
+            if (!conn) {					
+                printf("Not connected yet\n");
+                return 0;
+            }
+        }
+        if (!send_searchRequest(arg))
+            return 0;
+    }
+    return 2;
+}
+
+static int cmd_delete(const char *arg)
+{
+    if (!conn)
+    {
+        printf("Not connected yet\n");
+        return 0;
+    }
+    if (only_z3950())
+	return 0;
+    if (!send_deleteResultSetRequest(arg))
+        return 0;
+    return 2;
+}
+
+static int cmd_ssub(const char *arg)
+{
+    if (!(smallSetUpperBound = atoi(arg)))
+        return 0;
+    return 1;
+}
+
+static int cmd_lslb(const char *arg)
+{
+    if (only_z3950())
+	return 0;
+    if (!(largeSetLowerBound = atoi(arg)))
+        return 0;
+    return 1;
+}
+
+static int cmd_mspn(const char *arg)
+{
+    if (only_z3950())
+	return 0;
+    if (!(mediumSetPresentNumber = atoi(arg)))
+        return 0;
+    return 1;
+}
+
+static int cmd_status(const char *arg)
+{
+    printf("smallSetUpperBound: %d\n", smallSetUpperBound);
+    printf("largeSetLowerBound: %d\n", largeSetLowerBound);
+    printf("mediumSetPresentNumber: %d\n", mediumSetPresentNumber);
+    return 1;
+}
+
+static int cmd_setnames(const char *arg)
+{
+    if (*arg == '1')         /* enable ? */
+        setnumber = 0;
+    else if (*arg == '0')    /* disable ? */
+        setnumber = -1;
+    else if (setnumber < 0)  /* no args, toggle .. */
+        setnumber = 0;
+    else
+        setnumber = -1;
+   
+    if (setnumber >= 0)
+        printf("Set numbering enabled.\n");
+    else
+        printf("Set numbering disabled.\n");
+    return 1;
+}
+
+/* PRESENT SERVICE ----------------------------- */
+/* this one is based on johnmcps version - pretty much a copy of 
+   send_presentRequest, but passing in separate args, not an arg string */
+int z_send_getbriefrecords(int starting, int set, int howmany) {
+
+    Z_APDU *apdu = zget_APDU(out, Z_APDU_presentRequest);
+    Z_PresentRequest *req = apdu->u.presentRequest;
+    Z_RecordComposition compo;
+    int nos = 1;
+    char setstring[100];
+
+    req->referenceId = set_refid (out);
+    nos = howmany;
+    setno = starting;
+    sprintf(setstring, "%d", setnumber);
+    req->resultSetId = setstring;
+    req->resultSetStartPoint = &setno;
+    req->numberOfRecordsRequested = &nos;
+    
+    req->preferredRecordSyntax =
+        yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax);
+
+    if (record_schema)
+    {
+        req->recordComposition = &compo;
+        compo.which = Z_RecordComp_complex;
+        compo.u.complex = (Z_CompSpec *)
+            odr_malloc(out, sizeof(*compo.u.complex));
+        compo.u.complex->selectAlternativeSyntax = (bool_t *) 
+            odr_malloc(out, sizeof(bool_t));
+        *compo.u.complex->selectAlternativeSyntax = 0;
+
+        compo.u.complex->generic = (Z_Specification *)
+            odr_malloc(out, sizeof(*compo.u.complex->generic));
+        compo.u.complex->generic->which = Z_Schema_oid;
+
+        compo.u.complex->generic->schema.oid =
+	    yaz_str_to_z3950oid(out, CLASS_SCHEMA, record_schema);
+
+        if (!compo.u.complex->generic->schema.oid)
+        {
+            /* OID wasn't a schema! Try record syntax instead. */
+            compo.u.complex->generic->schema.oid = (Odr_oid *)
+		yaz_str_to_z3950oid(out, CLASS_RECSYN, record_schema);
+        }
+        if (!elementSetNames)
+            compo.u.complex->generic->elementSpec = 0;
+        else
+        {
+            compo.u.complex->generic->elementSpec = (Z_ElementSpec *)
+                odr_malloc(out, sizeof(Z_ElementSpec));
+            compo.u.complex->generic->elementSpec->which =
+                Z_ElementSpec_elementSetName;
+            compo.u.complex->generic->elementSpec->u.elementSetName =
+                elementSetNames->u.generic;
+        }
+        compo.u.complex->num_dbSpecific = 0;
+        compo.u.complex->dbSpecific = 0;
+        compo.u.complex->num_recordSyntax = 0;
+        compo.u.complex->recordSyntax = 0;
+    }
+    else if (elementSetNames)
+    {
+        req->recordComposition = &compo;
+        compo.which = Z_RecordComp_simple;
+        compo.u.simple = elementSetNames;
+    }
+    send_apdu(apdu);
+    return 0;
+}
+
+static void parse_show_args(const char *arg_c, char *setstring,
+                            int *start, int *number)
+{
+    char arg[40];
+    char *p;
+
+    strncpy(arg, arg_c, sizeof(arg)-1);
+    arg[sizeof(arg)-1] = '\0';
+
+    if ((p = strchr(arg, '+')))
+    {
+        *number = atoi(p + 1);
+        *p = '\0';
+    }
+    if (*arg)
+        *start = atoi(arg);
+    if (p && (p=strchr(p+1, '+')))
+        strcpy (setstring, p+1);
+    else if (setnumber >= 0)
+        sprintf(setstring, "%d", setnumber);
+    else
+        *setstring = '\0';
+}
+
+static int send_presentRequest(const char *arg)
+{
+    Z_APDU *apdu = zget_APDU(out, Z_APDU_presentRequest);
+    Z_PresentRequest *req = apdu->u.presentRequest;
+    Z_RecordComposition compo;
+    int nos = 1;
+    char setstring[100];
+
+    req->referenceId = set_refid (out);
+
+    parse_show_args(arg, setstring, &setno, &nos);
+    if (*setstring)
+        req->resultSetId = setstring;
+
+    req->resultSetStartPoint = &setno;
+    req->numberOfRecordsRequested = &nos;
+
+    req->preferredRecordSyntax =
+        yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax);
+
+    if (record_schema)
+    {
+        req->recordComposition = &compo;
+        compo.which = Z_RecordComp_complex;
+        compo.u.complex = (Z_CompSpec *)
+            odr_malloc(out, sizeof(*compo.u.complex));
+        compo.u.complex->selectAlternativeSyntax = (bool_t *) 
+            odr_malloc(out, sizeof(bool_t));
+        *compo.u.complex->selectAlternativeSyntax = 0;
+
+        compo.u.complex->generic = (Z_Specification *)
+            odr_malloc(out, sizeof(*compo.u.complex->generic));
+        compo.u.complex->generic->which = Z_Schema_oid;
+
+        compo.u.complex->generic->schema.oid =
+	    yaz_str_to_z3950oid(out, CLASS_SCHEMA, record_schema);
+
+        if (!compo.u.complex->generic->schema.oid)
+        {
+            /* OID wasn't a schema! Try record syntax instead. */
+            compo.u.complex->generic->schema.oid = (Odr_oid *)
+		yaz_str_to_z3950oid(out, CLASS_RECSYN, record_schema);
+        }
+        if (!elementSetNames)
+            compo.u.complex->generic->elementSpec = 0;
+        else
+        {
+            compo.u.complex->generic->elementSpec = (Z_ElementSpec *)
+                odr_malloc(out, sizeof(Z_ElementSpec));
+            compo.u.complex->generic->elementSpec->which =
+                Z_ElementSpec_elementSetName;
+            compo.u.complex->generic->elementSpec->u.elementSetName =
+                elementSetNames->u.generic;
+        }
+        compo.u.complex->num_dbSpecific = 0;
+        compo.u.complex->dbSpecific = 0;
+        compo.u.complex->num_recordSyntax = 0;
+        compo.u.complex->recordSyntax = 0;
+    }
+    else if (elementSetNames)
+    {
+        req->recordComposition = &compo;
+        compo.which = Z_RecordComp_simple;
+        compo.u.simple = elementSetNames;
+    }
+    send_apdu(apdu);
+    printf("Sent presentRequest (%d+%d).\n", setno, nos);
+    return 2;
+}
+
+#if HAVE_XML2
+static int send_SRW_presentRequest(const char *arg)
+{
+    char setstring[100];
+    int nos = 1;
+    Z_SRW_PDU *sr = srw_sr;
+
+    if (!sr)
+        return 0;
+    parse_show_args(arg, setstring, &setno, &nos);
+    sr->u.request->startRecord = odr_intdup(out, setno);
+    sr->u.request->maximumRecords = odr_intdup(out, nos);
+    if (record_schema)
+        sr->u.request->recordSchema = record_schema;
+    if (recordsyntax == VAL_TEXT_XML)
+        sr->u.request->recordPacking = "xml";
+    return send_srw(sr);
+}
+#endif
+
+static void close_session (void)
+{
+    if (conn)
+        cs_close (conn);
+    conn = 0;
+    if (session_mem)
+    {
+        nmem_destroy (session_mem);
+        session_mem = NULL;
+    }
+    sent_close = 0;
+    odr_reset(out);
+    odr_reset(in);
+    odr_reset(print);
+}
+
+void process_close(Z_Close *req)
+{
+    Z_APDU *apdu = zget_APDU(out, Z_APDU_close);
+    Z_Close *res = apdu->u.close;
+
+    static char *reasons[] =
+    {
+        "finished",
+        "shutdown",
+        "system problem",
+        "cost limit reached",
+        "resources",
+        "security violation",
+        "protocolError",
+        "lack of activity",
+        "peer abort",
+        "unspecified"
+    };
+
+    printf("Reason: %s, message: %s\n", reasons[*req->closeReason],
+        req->diagnosticInformation ? req->diagnosticInformation : "NULL");
+    if (sent_close)
+        close_session ();
+    else
+    {
+        *res->closeReason = Z_Close_finished;
+        send_apdu(apdu);
+        printf("Sent response.\n");
+        sent_close = 1;
+    }
+}
+
+static int cmd_show(const char *arg)
+{
+    if (protocol == PROTO_HTTP)
+    {
+#if HAVE_XML2
+        if (!conn)
+            cmd_open(0);
+	if (!conn)
+	    return 0;
+        if (!send_SRW_presentRequest(arg))
+            return 0;
+#else
+        return 0;
+#endif
+    }
+    else
+    {
+        if (!conn)
+        {
+            printf("Not connected yet\n");
+            return 0;
+        }
+        if (!send_presentRequest(arg))
+            return 0;
+    }
+    return 2;
+}
+
+int cmd_quit(const char *arg)
+{
+    printf("See you later, alligator.\n");
+    xmalloc_trav ("");
+    exit(0);
+    return 0;
+}
+
+int cmd_cancel(const char *arg)
+{
+    Z_APDU *apdu = zget_APDU(out, Z_APDU_triggerResourceControlRequest);
+    Z_TriggerResourceControlRequest *req =
+        apdu->u.triggerResourceControlRequest;
+    bool_t rfalse = 0;
+    
+    if (!conn)
+    {
+        printf("Session not initialized yet\n");
+        return 0;
+    }
+    if (only_z3950())
+	return 0;
+    if (!ODR_MASK_GET(session->options, Z_Options_triggerResourceCtrl))
+    {
+        printf("Target doesn't support cancel (trigger resource ctrl)\n");
+        return 0;
+    }
+    *req->requestedAction = Z_TriggerResourceControlRequest_cancel;
+    req->resultSetWanted = &rfalse;
+    req->referenceId = set_refid (out);
+
+    send_apdu(apdu);
+    printf("Sent cancel request\n");
+    return 2;
+}
+
+
+int cmd_cancel_find(const char *arg) {
+    int fres;
+    fres=cmd_find(arg);
+    if( fres > 0 ) {
+	return cmd_cancel("");
+    };
+    return fres;
+}
+
+int send_scanrequest(const char *query, int pp, int num, const char *term)
+{
+    Z_APDU *apdu = zget_APDU(out, Z_APDU_scanRequest);
+    Z_ScanRequest *req = apdu->u.scanRequest;
+    
+    if (only_z3950())
+	return 0;
+    if (queryType == QueryType_CCL2RPN)
+    {
+        int error, pos;
+        struct ccl_rpn_node *rpn;
+
+        rpn = ccl_find_str (bibset,  query, &error, &pos);
+        if (error)
+        {
+            printf("CCL ERROR: %s\n", ccl_err_msg(error));
+            return -1;
+        }
+        req->attributeSet =
+	    yaz_oidval_to_z3950oid(out, CLASS_ATTSET, VAL_BIB1);
+        if (!(req->termListAndStartPoint = ccl_scan_query (out, rpn)))
+        {
+            printf("Couldn't convert CCL to Scan term\n");
+            return -1;
+        }
+        ccl_rpn_delete (rpn);
+    }
+    else
+    {
+        YAZ_PQF_Parser pqf_parser = yaz_pqf_create ();
+
+        if (!(req->termListAndStartPoint =
+              yaz_pqf_scan(pqf_parser, out, &req->attributeSet, query)))
+        {
+            const char *pqf_msg;
+            size_t off;
+            int code = yaz_pqf_error (pqf_parser, &pqf_msg, &off);
+            printf("%*s^\n", off+7, "");
+            printf("Prefix query error: %s (code %d)\n", pqf_msg, code);
+            yaz_pqf_destroy (pqf_parser);
+            return -1;
+        }
+        yaz_pqf_destroy (pqf_parser);
+    }
+    if (term && *term)
+    {
+        if (req->termListAndStartPoint->term &&
+            req->termListAndStartPoint->term->which == Z_Term_general &&
+            req->termListAndStartPoint->term->u.general)
+        {
+            req->termListAndStartPoint->term->u.general->buf =
+                (unsigned char *) odr_strdup(out, term);
+            req->termListAndStartPoint->term->u.general->len =
+                req->termListAndStartPoint->term->u.general->size =
+                strlen(term);
+        }
+    }
+    req->referenceId = set_refid (out);
+    req->num_databaseNames = num_databaseNames;
+    req->databaseNames = databaseNames;
+    req->numberOfTermsRequested = &num;
+    req->preferredPositionInResponse = &pp;
+    req->stepSize = odr_intdup(out, scan_stepSize);
+    send_apdu(apdu);
+    return 2;
+}
+
+int send_sortrequest(const char *arg, int newset)
+{
+    Z_APDU *apdu = zget_APDU(out, Z_APDU_sortRequest);
+    Z_SortRequest *req = apdu->u.sortRequest;
+    Z_SortKeySpecList *sksl = (Z_SortKeySpecList *)
+        odr_malloc (out, sizeof(*sksl));
+    char setstring[32];
+
+    if (only_z3950())
+	return 0;
+    if (setnumber >= 0)
+        sprintf (setstring, "%d", setnumber);
+    else
+        sprintf (setstring, "default");
+
+    req->referenceId = set_refid (out);
+
+    req->num_inputResultSetNames = 1;
+    req->inputResultSetNames = (Z_InternationalString **)
+        odr_malloc (out, sizeof(*req->inputResultSetNames));
+    req->inputResultSetNames[0] = odr_strdup (out, setstring);
+
+    if (newset && setnumber >= 0)
+        sprintf (setstring, "%d", ++setnumber);
+
+    req->sortedResultSetName = odr_strdup (out, setstring);
+
+    req->sortSequence = yaz_sort_spec (out, arg);
+    if (!req->sortSequence)
+    {
+        printf ("Missing sort specifications\n");
+        return -1;
+    }
+    send_apdu(apdu);
+    return 2;
+}
+
+void display_term(Z_TermInfo *t)
+{
+    if (t->displayTerm)
+        printf("%s", t->displayTerm);
+    else if (t->term->which == Z_Term_general)
+    {
+        printf("%.*s", t->term->u.general->len, t->term->u.general->buf);
+        sprintf(last_scan_line, "%.*s", t->term->u.general->len,
+            t->term->u.general->buf);
+    }
+    else
+        printf("Term (not general)");
+    if (t->globalOccurrences)
+        printf (" (%d)\n", *t->globalOccurrences);
+    else
+        printf ("\n");
+}
+
+void process_scanResponse(Z_ScanResponse *res)
+{
+    int i;
+    Z_Entry **entries = NULL;
+    int num_entries = 0;
+   
+    printf("Received ScanResponse\n"); 
+    print_refid (res->referenceId);
+    printf("%d entries", *res->numberOfEntriesReturned);
+    if (res->positionOfTerm)
+        printf (", position=%d", *res->positionOfTerm); 
+    printf ("\n");
+    if (*res->scanStatus != Z_Scan_success)
+        printf("Scan returned code %d\n", *res->scanStatus);
+    if (!res->entries)
+        return;
+    if ((entries = res->entries->entries))
+        num_entries = res->entries->num_entries;
+    for (i = 0; i < num_entries; i++)
+    {
+        int pos_term = res->positionOfTerm ? *res->positionOfTerm : -1;
+        if (entries[i]->which == Z_Entry_termInfo)
+        {
+            printf("%c ", i + 1 == pos_term ? '*' : ' ');
+            display_term(entries[i]->u.termInfo);
+        }
+        else
+            display_diagrecs(&entries[i]->u.surrogateDiagnostic, 1);
+    }
+    if (res->entries->nonsurrogateDiagnostics)
+        display_diagrecs (res->entries->nonsurrogateDiagnostics,
+                          res->entries->num_nonsurrogateDiagnostics);
+}
+
+void process_sortResponse(Z_SortResponse *res)
+{
+    printf("Received SortResponse: status=");
+    switch (*res->sortStatus)
+    {
+    case Z_SortResponse_success:
+        printf ("success"); break;
+    case Z_SortResponse_partial_1:
+        printf ("partial"); break;
+    case Z_SortResponse_failure:
+        printf ("failure"); break;
+    default:
+        printf ("unknown (%d)", *res->sortStatus);
+    }
+    printf ("\n");
+    print_refid (res->referenceId);
+    if (res->diagnostics)
+        display_diagrecs(res->diagnostics,
+                         res->num_diagnostics);
+}
+
+void process_deleteResultSetResponse (Z_DeleteResultSetResponse *res)
+{
+    printf("Got deleteResultSetResponse status=%d\n",
+           *res->deleteOperationStatus);
+    if (res->deleteListStatuses)
+    {
+        int i;
+        for (i = 0; i < res->deleteListStatuses->num; i++)
+        {
+            printf ("%s status=%d\n", res->deleteListStatuses->elements[i]->id,
+                    *res->deleteListStatuses->elements[i]->status);
+        }
+    }
+}
+
+int cmd_sort_generic(const char *arg, int newset)
+{
+    if (!conn)
+    {
+        printf("Session not initialized yet\n");
+        return 0;
+    }
+    if (only_z3950())
+	return 0;
+    if (!ODR_MASK_GET(session->options, Z_Options_sort))
+    {
+        printf("Target doesn't support sort\n");
+        return 0;
+    }
+    if (*arg)
+    {
+        if (send_sortrequest(arg, newset) < 0)
+            return 0;
+        return 2;
+    }
+    return 0;
+}
+
+int cmd_sort(const char *arg)
+{
+    return cmd_sort_generic (arg, 0);
+}
+
+int cmd_sort_newset (const char *arg)
+{
+    return cmd_sort_generic (arg, 1);
+}
+
+int cmd_scanstep(const char *arg)
+{
+    scan_stepSize = atoi(arg);
+    return 0;
+}
+
+int cmd_scanpos(const char *arg)
+{
+    int r = sscanf(arg, "%d", &scan_position);
+    if (r == 0)
+        scan_position = 1;
+    return 0;
+}
+
+int cmd_scansize(const char *arg)
+{
+    int r = sscanf(arg, "%d", &scan_size);
+    if (r == 0)
+        scan_size = 20;
+    return 0;
+}
+
+int cmd_scan(const char *arg)
+{
+    if (protocol == PROTO_HTTP)
+    {
+#if HAVE_XML2
+        if (!conn)
+            cmd_open(0);
+	if (!conn)
+	    return 0;
+	if (*arg)
+	{
+	    if (send_SRW_scanRequest(arg, scan_position, scan_size) < 0)
+		return 0;
+	}
+	else
+	{
+	    if (send_SRW_scanRequest(last_scan_line, 1, scan_size) < 0)
+		return 0;
+	}
+	return 2;
+#else
+        return 0;
+#endif
+    }
+    else
+    {
+	if (!conn)
+	{
+	    try_reconnect();
+	    
+	    if (!conn) {								
+		printf("Session not initialized yet\n");
+		return 0;
+	    }
+	}
+	if (!ODR_MASK_GET(session->options, Z_Options_scan))
+	{
+	    printf("Target doesn't support scan\n");
+	    return 0;
+	}
+	if (*arg)
+	{
+	    strcpy (last_scan_query, arg);
+	    if (send_scanrequest(arg, scan_position, scan_size, 0) < 0)
+		return 0;
+	}
+	else
+	{
+	    if (send_scanrequest(last_scan_query, 1, scan_size, last_scan_line) < 0)
+		return 0;
+	}
+	return 2;
+    }
+}
+
+int cmd_schema(const char *arg)
+{
+    xfree(record_schema);
+    record_schema = 0;
+    if (arg && *arg)
+        record_schema = xstrdup(arg);
+    return 1;
+}
+
+int cmd_format(const char *arg)
+{
+    oid_value nsyntax;
+    if (!arg || !*arg)
+    {
+        printf("Usage: format <recordsyntax>\n");
+        return 0;
+    }
+    nsyntax = oid_getvalbyname (arg);
+    if (strcmp(arg, "none") && nsyntax == VAL_NONE)
+    {
+        printf ("unknown record syntax\n");
+        return 0;
+    }
+    recordsyntax = nsyntax;
+    return 1;
+}
+
+int cmd_elements(const char *arg)
+{
+    static Z_ElementSetNames esn;
+    static char what[100];
+
+    if (!arg || !*arg)
+    {
+        elementSetNames = 0;
+        return 1;
+    }
+    strcpy(what, arg);
+    esn.which = Z_ElementSetNames_generic;
+    esn.u.generic = what;
+    elementSetNames = &esn;
+    return 1;
+}
+
+int cmd_attributeset(const char *arg)
+{
+    char what[100];
+
+    if (!arg || !*arg)
+    {
+        printf("Usage: attributeset <setname>\n");
+        return 0;
+    }
+    sscanf(arg, "%s", what);
+    if (p_query_attset (what))
+    {
+        printf("Unknown attribute set name\n");
+        return 0;
+    }
+    return 1;
+}
+
+int cmd_querytype (const char *arg)
+{
+    if (!strcmp (arg, "ccl"))
+        queryType = QueryType_CCL;
+    else if (!strcmp (arg, "prefix") || !strcmp(arg, "rpn"))
+        queryType = QueryType_Prefix;
+    else if (!strcmp (arg, "ccl2rpn") || !strcmp (arg, "cclrpn"))
+        queryType = QueryType_CCL2RPN;
+    else if (!strcmp(arg, "cql"))
+        queryType = QueryType_CQL;        
+    else if (!strcmp (arg, "cql2rpn") || !strcmp (arg, "cqlrpn"))
+        queryType = QueryType_CQL2RPN;
+    else
+    {
+        printf ("Querytype must be one of:\n");
+        printf (" prefix         - Prefix query\n");
+        printf (" ccl            - CCL query\n");
+        printf (" ccl2rpn        - CCL query converted to RPN\n");
+        printf (" cql            - CQL\n");
+        printf (" cql2rpn        - CQL query converted to RPN\n");
+        return 0;
+    }
+    return 1;
+}
+
+int cmd_refid (const char *arg)
+{
+    xfree (refid);
+    refid = NULL;
+    if (*arg)
+        refid = xstrdup (arg);
+    return 1;
+}
+
+int z_cmd_close(const char *arg)
+{
+    Z_APDU *apdu;
+    Z_Close *req;
+    if (!conn)
+        return 0;
+    if (only_z3950())
+	return 0;
+
+    apdu = zget_APDU(out, Z_APDU_close);
+    req = apdu->u.close;
+    *req->closeReason = Z_Close_finished;
+    send_apdu(apdu);
+    printf("Sent close request.\n");
+    sent_close = 1;
+    return 2;
+}
+
+int cmd_packagename(const char* arg)
+{
+    xfree (esPackageName);
+    esPackageName = NULL;
+    if (*arg)
+        esPackageName = xstrdup(arg);
+    return 1;
+}
+
+int cmd_proxy(const char* arg)
+{
+    xfree (yazProxy);
+    yazProxy = NULL;
+    if (*arg)
+        yazProxy = xstrdup (arg);
+    return 1;
+}
+
+int cmd_marccharset(const char *arg)
+{
+    char l1[30];
+
+    *l1 = 0;
+    if (sscanf(arg, "%29s", l1) < 1)
+    {
+    	printf("MARC character set is `%s'\n", 
+               marcCharset ? marcCharset: "none");
+        return 1;
+    }
+    xfree (marcCharset);
+    marcCharset = 0;
+    if (strcmp(l1, "-"))
+        marcCharset = xstrdup(l1);
+    return 1;
+}
+
+int cmd_displaycharset(const char *arg)
+{
+    char l1[30];
+
+    *l1 = 0;
+    if (sscanf(arg, "%29s", l1) < 1)
+    {
+    	printf("Display character set is `%s'\n", 
+               outputCharset ? outputCharset: "none");
+    }
+    else
+    {
+        xfree (outputCharset);
+        outputCharset = 0;
+        if (!strcmp(l1, "auto") && codeset)
+        {
+            if (codeset)
+            {
+                printf ("Display character set: %s\n", codeset);
+                outputCharset = xstrdup(codeset);
+            }
+            else
+                printf ("No codeset found on this system\n");
+        }
+        else if (strcmp(l1, "-") && strcmp(l1, "none"))
+            outputCharset = xstrdup(l1);
+    } 
+    return 1;
+}
+
+int cmd_negcharset(const char *arg)
+{
+    char l1[30];
+
+    *l1 = 0;
+    if (sscanf(arg, "%29s %d %d", l1, &negotiationCharsetRecords,
+	       &negotiationCharsetVersion) < 1)
+    {
+    	printf("Current negotiation character set is `%s'\n", 
+               negotiationCharset ? negotiationCharset: "none");  
+	printf("Records in charset %s\n", negotiationCharsetRecords ? 
+	       "yes" : "no");
+	printf("Charneg version %d\n", negotiationCharsetVersion);
+    }
+    else
+    {
+	xfree (negotiationCharset);
+	negotiationCharset = NULL;
+	if (*l1 && strcmp(l1, "-") && strcmp(l1, "none"))
+	{
+	    negotiationCharset = xstrdup(l1);
+	    printf ("Character set negotiation : %s\n", negotiationCharset);
+	}
+    }
+    return 1;
+}
+
+int cmd_charset(const char* arg)
+{
+    char l1[30], l2[30], l3[30];
+
+    *l1 = *l2 = *l3 = 0;
+    if (sscanf(arg, "%29s %29s %29s", l1, l2, l3) < 1)
+    {
+	cmd_negcharset("");
+	cmd_displaycharset("");
+	cmd_marccharset("");
+    }
+    else
+    {
+	cmd_negcharset(l1);
+	if (*l2)
+	    cmd_displaycharset(l2);
+	if (*l3)
+	    cmd_marccharset(l3);
+    }
+    return 1;
+}
+
+int cmd_lang(const char* arg)
+{
+    if (*arg == '\0') {
+    	printf("Current language is `%s'\n", (yazLang)?yazLang:NULL);
+    	return 1;
+    }
+    xfree (yazLang);
+    yazLang = NULL;
+    if (*arg)
+        yazLang = xstrdup(arg);
+    return 1;
+}
+
+int cmd_source(const char* arg, int echo ) 
+{
+    /* first should open the file and read one line at a time.. */
+    FILE* includeFile;
+    char line[102400], *cp;
+
+    if(strlen(arg)<1) {
+        fprintf(stderr,"Error in source command use a filename\n");
+        return -1;
+    }
+    
+    includeFile = fopen (arg, "r");
+    
+    if(!includeFile) {
+        fprintf(stderr,"Unable to open file %s for reading\n",arg);
+        return -1;
+    }
+    
+    while(!feof(includeFile)) {
+        memset(line,0,sizeof(line));
+        fgets(line,sizeof(line),includeFile);
+        
+        if(strlen(line) < 2) continue;
+        if(line[0] == '#') continue;
+        
+        if ((cp = strrchr (line, '\n')))
+            *cp = '\0';
+	
+	if( echo ) {
+	    printf( "processing line: %s\n",line );
+	};
+        process_cmd_line(line);
+    }
+    
+    if(fclose(includeFile)<0) {
+        perror("unable to close include file");
+        exit(1);
+    }
+    return 1;
+}
+
+int cmd_source_echo(const char* arg)
+{ 
+    cmd_source(arg, 1);
+    return 1;
+}
+
+int cmd_source_noecho(const char* arg)
+{
+    cmd_source(arg, 0);
+    return 1;
+}
+
+
+int cmd_subshell(const char* args)
+{
+    if(strlen(args)) 
+        system(args);
+    else 
+        system(getenv("SHELL"));
+    
+    printf("\n");
+    return 1;
+}
+
+int cmd_set_berfile(const char *arg)
+{
+    if (ber_file && ber_file != stdout && ber_file != stderr)
+        fclose(ber_file);
+    if (!strcmp(arg, ""))
+        ber_file = 0;
+    else if (!strcmp(arg, "-"))
+        ber_file = stdout;
+    else
+        ber_file = fopen(arg, "a");
+    return 1;
+}
+
+int cmd_set_apdufile(const char *arg)
+{
+    if(apdu_file && apdu_file != stderr && apdu_file != stderr)
+        fclose(apdu_file);
+    if (!strcmp(arg, ""))
+        apdu_file = 0;
+    else if (!strcmp(arg, "-"))
+        apdu_file = stderr;
+    else
+    {
+        apdu_file = fopen(arg, "a");
+        if (!apdu_file)
+            perror("unable to open apdu log file");
+    }
+    if (apdu_file)
+        odr_setprint(print, apdu_file);
+    return 1;
+}
+
+int cmd_set_cclfile(const char* arg)
+{  
+    FILE *inf;
+
+    bibset = ccl_qual_mk (); 
+    inf = fopen (arg, "r");
+    if (!inf)
+        perror("unable to open CCL file");
+    else
+    {
+        ccl_qual_file (bibset, inf);
+        fclose (inf);
+    }
+    strcpy(ccl_fields,arg);
+    return 0;
+}
+
+int cmd_set_cqlfile(const char* arg)
+{
+    cql_transform_t newcqltrans;
+
+    if ((newcqltrans = cql_transform_open_fname(arg)) == 0) {
+        perror("unable to open CQL file");
+	return 0;
+    }
+    if (cqltrans != 0)
+	cql_transform_close(cqltrans);
+
+    cqltrans = newcqltrans;
+    strcpy(cql_fields, arg);
+    return 0;
+}
+
+int cmd_set_auto_reconnect(const char* arg)
+{  
+    if(strlen(arg)==0) {
+        auto_reconnect = ! auto_reconnect;
+    } else if(strcmp(arg,"on")==0) {
+        auto_reconnect = 1;
+    } else if(strcmp(arg,"off")==0) {
+        auto_reconnect = 0;		
+    } else {
+        printf("Error use on or off\n");
+        return 1;
+    }
+    
+    if (auto_reconnect)
+        printf("Set auto reconnect enabled.\n");
+    else
+        printf("Set auto reconnect disabled.\n");
+    
+    return 0;
+}
+
+int cmd_set_marcdump(const char* arg)
+{
+    if(marc_file && marc_file != stderr) { /* don't close stdout*/
+        fclose(marc_file);
+    }
+
+    if (!strcmp(arg, ""))
+        marc_file = 0;
+    else if (!strcmp(arg, "-"))
+        marc_file = stderr;
+    else
+    {
+        marc_file = fopen(arg, "a");
+        if (!marc_file)
+            perror("unable to open marc log file");
+    }
+    return 1;
+}
+
+/* 
+   this command takes 3 arge {name class oid} 
+*/
+int cmd_register_oid(const char* args) {
+    static struct {
+        char* className;
+        oid_class oclass;
+    } oid_classes[] = {
+        {"appctx",CLASS_APPCTX},
+        {"absyn",CLASS_ABSYN},
+        {"attset",CLASS_ATTSET},
+        {"transyn",CLASS_TRANSYN},
+        {"diagset",CLASS_DIAGSET},
+        {"recsyn",CLASS_RECSYN},
+        {"resform",CLASS_RESFORM},
+        {"accform",CLASS_ACCFORM},
+        {"extserv",CLASS_EXTSERV},
+        {"userinfo",CLASS_USERINFO},
+        {"elemspec",CLASS_ELEMSPEC},
+        {"varset",CLASS_VARSET},
+        {"schema",CLASS_SCHEMA},
+        {"tagset",CLASS_TAGSET},
+        {"general",CLASS_GENERAL},
+        {0,(enum oid_class) 0}
+    };
+    char oname_str[101], oclass_str[101], oid_str[101];  
+    char* name;
+    int i;
+    oid_class oidclass = CLASS_GENERAL;
+    int val = 0, oid[OID_SIZE];
+    struct oident * new_oident=NULL;
+    
+    if (sscanf (args, "%100[^ ] %100[^ ] %100s",
+                oname_str,oclass_str, oid_str) < 1) {
+        printf("Error in register command \n");
+        return 0;
+    }
+    
+    for (i = 0; oid_classes[i].className; i++) {
+        if (!strcmp(oid_classes[i].className, oclass_str))
+        {
+            oidclass=oid_classes[i].oclass;
+            break;
+        }
+    }
+    
+    if(!(oid_classes[i].className)) {
+        printf("Unknown oid class %s\n",oclass_str);
+        return 0;
+    }
+    
+    i = 0;
+    name = oid_str;
+    val = 0;
+    
+    while (isdigit (*(unsigned char *) name))
+    {
+        val = val*10 + (*name - '0');
+        name++;
+        if (*name == '.')
+        {
+            if (i < OID_SIZE-1)
+                oid[i++] = val;
+            val = 0;
+            name++;
+        }
+    }
+    oid[i] = val;
+    oid[i+1] = -1;
+    
+    new_oident = oid_addent (oid, PROTO_GENERAL, oidclass, oname_str,
+			     VAL_DYNAMIC);  
+    if(strcmp(new_oident->desc,oname_str))
+    {
+        fprintf(stderr,"oid is already named as %s, registration failed\n",
+                new_oident->desc);
+    }
+    return 1;  
+}
+
+int cmd_push_command(const char* arg) 
+{
+    
+#if HAVE_READLINE_HISTORY_H
+    if(strlen(arg)>1) 
+        add_history(arg);
+#else 
+    fprintf(stderr,"Not compiled with the readline/history module\n");
+#endif
+    return 1;
+}
+
+void source_rcfile() 
+{
+    /*  Look for a $HOME/.yazclientrc and source it if it exists */
+    struct stat statbuf;
+    char buffer[1000];
+    char* homedir=getenv("HOME");
+
+    if( homedir ) {
+	
+	sprintf(buffer,"%s/.yazclientrc",homedir);
+
+	if(stat(buffer,&statbuf)==0) {
+	    cmd_source(buffer, 0 );
+	}
+	
+    };
+    
+    if(stat(".yazclientrc",&statbuf)==0) {
+        cmd_source(".yazclientrc", 0 );
+    }
+}
+
+
+void z_initialize(void)
+{
+    FILE *inf;
+    int i;
+    
+    if (!(out = odr_createmem(ODR_ENCODE)) ||
+        !(in = odr_createmem(ODR_DECODE)) ||
+        !(print = odr_createmem(ODR_PRINT)))
+    {
+        fprintf(stderr, "failed to allocate ODR streams\n");
+        exit(1);
+    }
+    oid_init();
+    
+    setvbuf(stdout, 0, _IONBF, 0);
+    if (apdu_file)
+        odr_setprint(print, apdu_file);
+
+    bibset = ccl_qual_mk (); 
+    inf = fopen (ccl_fields, "r");
+    if (inf)
+    {
+        ccl_qual_file (bibset, inf);
+        fclose (inf);
+    }
+
+    cqltrans = cql_transform_open_fname(cql_fields);
+    /* If this fails, no problem: we detect cqltrans == 0 later */
+
+#if HAVE_READLINE_READLINE_H
+    rl_attempted_completion_function = (CPPFunction*)readline_completer;
+#endif
+    
+    
+    for(i=0; i<maxOtherInfosSupported; ++i) {
+        extraOtherInfos[i].oidval = -1;
+    }
+    
+    source_rcfile();
+}
+
+
+#if HAVE_GETTIMEOFDAY
+struct timeval tv_start, tv_end;
+#endif
+
+#if HAVE_XML2
+static void handle_srw_record(Z_SRW_record *rec)
+{
+    if (rec->recordPosition)
+    {
+	printf ("pos=%d", *rec->recordPosition);
+	setno = *rec->recordPosition + 1;
+    }
+    if (rec->recordSchema)
+	printf (" schema=%s", rec->recordSchema);
+    printf ("\n");
+    if (rec->recordData_buf && rec->recordData_len)
+    {
+	fwrite(rec->recordData_buf, 1, rec->recordData_len, stdout);
+	if (marc_file)
+	    fwrite (rec->recordData_buf, 1, rec->recordData_len, marc_file);
+    }
+    else
+	printf ("No data!");
+    printf("\n");
+}
+
+static void handle_srw_explain_response(Z_SRW_explainResponse *res)
+{
+    handle_srw_record(&res->record);
+}
+
+static void handle_srw_response(Z_SRW_searchRetrieveResponse *res)
+{
+    int i;
+
+    printf ("Received SRW SearchRetrieve Response\n");
+    
+    for (i = 0; i<res->num_diagnostics; i++)
+    {
+	if (res->diagnostics[i].uri)
+	    printf ("SRW diagnostic %s\n",
+		    res->diagnostics[i].uri);
+	else
+	    printf ("SRW diagnostic missing or could not be decoded\n");
+	if (res->diagnostics[i].message)
+            printf ("Message: %s\n", res->diagnostics[i].message);
+	if (res->diagnostics[i].details)
+            printf ("Details: %s\n", res->diagnostics[i].details);
+    }
+    if (res->numberOfRecords)
+        printf ("Number of hits: %d\n", *res->numberOfRecords);
+    for (i = 0; i<res->num_records; i++)
+	handle_srw_record(res->records + i);
+}
+
+static void handle_srw_scan_term(Z_SRW_scanTerm *term)
+{
+    if (term->displayTerm)
+	printf("%s:", term->displayTerm);
+    else if (term->value)
+	printf("%s:", term->value);
+    else
+	printf("No value:");
+    if (term->numberOfRecords)
+	printf(" %d", *term->numberOfRecords);
+    if (term->whereInList)
+	printf(" %s", term->whereInList);
+    if (term->value && term->displayTerm)
+	printf(" %s", term->value);
+
+    strcpy(last_scan_line, term->value);
+    printf("\n");
+}
+
+static void handle_srw_scan_response(Z_SRW_scanResponse *res)
+{
+    int i;
+
+    printf ("Received SRW Scan Response\n");
+    
+    for (i = 0; i<res->num_diagnostics; i++)
+    {
+	if (res->diagnostics[i].uri)
+	    printf ("SRW diagnostic %s\n",
+		    res->diagnostics[i].uri);
+	else
+	    printf ("SRW diagnostic missing or could not be decoded\n");
+	if (res->diagnostics[i].message)
+            printf ("Message: %s\n", res->diagnostics[i].message);
+	if (res->diagnostics[i].details)
+            printf ("Details: %s\n", res->diagnostics[i].details);
+    }
+    if (res->terms)
+	for (i = 0; i<res->num_terms; i++)
+	    handle_srw_scan_term(res->terms + i);
+}
+
+static void http_response(Z_HTTP_Response *hres)
+{
+    int ret = -1;
+    const char *content_type = z_HTTP_header_lookup(hres->headers,
+                                                    "Content-Type");
+    const char *connection_head = z_HTTP_header_lookup(hres->headers,
+                                                       "Connection");
+    if (content_type && !yaz_strcmp_del("text/xml", content_type, "; "))
+    {
+        Z_SOAP *soap_package = 0;
+        ODR o = odr_createmem(ODR_DECODE);
+        Z_SOAP_Handler soap_handlers[2] = {
+            {"http://www.loc.gov/zing/srw/", 0,
+             (Z_SOAP_fun) yaz_srw_codec},
+            {0, 0, 0}
+        };
+        ret = z_soap_codec(o, &soap_package,
+                           &hres->content_buf, &hres->content_len,
+                           soap_handlers);
+        if (!ret && soap_package->which == Z_SOAP_generic &&
+            soap_package->u.generic->no == 0)
+        {
+            Z_SRW_PDU *sr = soap_package->u.generic->p;
+            if (sr->which == Z_SRW_searchRetrieve_response)
+                handle_srw_response(sr->u.response);
+            else if (sr->which == Z_SRW_explain_response)
+                handle_srw_explain_response(sr->u.explain_response);
+            else if (sr->which == Z_SRW_scan_response)
+                handle_srw_scan_response(sr->u.scan_response);
+            else
+                ret = -1;
+        }
+        else if (soap_package && (soap_package->which == Z_SOAP_fault
+                          || soap_package->which == Z_SOAP_error))
+        {
+            printf ("HTTP Error Status=%d\n", hres->code);
+            printf ("SOAP Fault code %s\n",
+                    soap_package->u.fault->fault_code);
+            printf ("SOAP Fault string %s\n", 
+                    soap_package->u.fault->fault_string);
+	    if (soap_package->u.fault->details)
+		printf ("SOAP Details %s\n", 
+			soap_package->u.fault->details);
+        }
+        else
+            ret = -1;
+        odr_destroy(o);
+    }
+    if (ret)
+    {
+        if (hres->code != 200)
+        {
+	    printf ("HTTP Error Status=%d\n", hres->code);
+        }
+        else
+        {
+            printf ("Decoding of SRW package failed\n");
+        }
+        close_session();
+    }
+    else
+    {
+	if (!strcmp(hres->version, "1.0"))
+	{
+	    /* HTTP 1.0: only if Keep-Alive we stay alive.. */
+	    if (!connection_head || strcmp(connection_head, "Keep-Alive"))
+		close_session();
+	}
+	else 
+	{
+	    /* HTTP 1.1: only if no close we stay alive .. */
+	    if (connection_head && !strcmp(connection_head, "close"))
+		close_session();
+	}
+    }
+}
+#endif
+
+void wait_and_handle_response() 
+{
+    int reconnect_ok = 1;
+    int res;
+    char *netbuffer= 0;
+    int netbufferlen = 0;
+    Z_GDU *gdu;
+    
+    while(conn)
+    {
+        res = cs_get(conn, &netbuffer, &netbufferlen);
+        if (reconnect_ok && res <= 0 && protocol == PROTO_HTTP)
+        {
+            cs_close(conn);
+            conn = 0;
+            cmd_open(0);
+            reconnect_ok = 0;
+            if (conn)
+            {
+                char *buf_out;
+                int len_out;
+                
+                buf_out = odr_getbuf(out, &len_out, 0);
+                
+		do_hex_dump(buf_out, len_out);
+
+                cs_put(conn, buf_out, len_out);
+                
+                odr_reset(out);
+                continue;
+            }
+        }
+        else if (res <= 0)
+        {
+            printf("Target closed connection\n");
+            close_session();
+            break;
+        }
+        odr_reset(out);
+        odr_reset(in); /* release APDU from last round */
+        record_last = 0;
+        do_hex_dump(netbuffer, res);
+        odr_setbuf(in, netbuffer, res, 0);
+        
+        if (!z_GDU(in, &gdu, 0, 0))
+        {
+            FILE *f = ber_file ? ber_file : stdout;
+            odr_perror(in, "Decoding incoming APDU");
+            fprintf(f, "[Near %d]\n", odr_offset(in));
+            fprintf(f, "Packet dump:\n---------\n");
+            odr_dumpBER(f, netbuffer, res);
+            fprintf(f, "---------\n");
+            if (apdu_file)
+	    {
+                z_GDU(print, &gdu, 0, 0);
+		odr_reset(print);
+	    }
+            if (conn && cs_more(conn))
+                continue;
+	    break;
+        }
+        if (ber_file)
+            odr_dumpBER(ber_file, netbuffer, res);
+        if (apdu_file && !z_GDU(print, &gdu, 0, 0))
+        {
+            odr_perror(print, "Failed to print incoming APDU");
+            odr_reset(print);
+	    continue;
+        }
+        if (gdu->which == Z_GDU_Z3950)
+        {
+            Z_APDU *apdu = gdu->u.z3950;
+            switch(apdu->which)
+            {
+            case Z_APDU_initResponse:
+		// kjdon copying johnmcp
+		/* save session parameters for later use */
+		session_mem = odr_extract_mem(in);
+		session = apdu->u.initResponse;
+		// greenstone will call z_get_initResponse to get the info
+		// about what happened with the connection
+                //process_initResponse(apdu->u.initResponse);
+                break;
+            case Z_APDU_searchResponse:
+                process_searchResponse(apdu->u.searchResponse);
+                break;
+            case Z_APDU_scanResponse:
+                process_scanResponse(apdu->u.scanResponse);
+                break;
+            case Z_APDU_presentResponse:
+                print_refid (apdu->u.presentResponse->referenceId);
+                setno +=
+                    *apdu->u.presentResponse->numberOfRecordsReturned;
+                if (apdu->u.presentResponse->records)
+                    display_records(apdu->u.presentResponse->records);
+                else
+                    printf("No records.\n");
+                printf ("nextResultSetPosition = %d\n",
+                        *apdu->u.presentResponse->nextResultSetPosition);
+                break;
+            case Z_APDU_sortResponse:
+                process_sortResponse(apdu->u.sortResponse);
+                break;
+            case Z_APDU_extendedServicesResponse:
+                printf("Got extended services response\n");
+                process_ESResponse(apdu->u.extendedServicesResponse);
+                break;
+            case Z_APDU_close:
+                printf("Target has closed the association.\n");
+                process_close(apdu->u.close);
+                break;
+            case Z_APDU_resourceControlRequest:
+                process_resourceControlRequest
+                    (apdu->u.resourceControlRequest);
+                break;
+            case Z_APDU_deleteResultSetResponse:
+                process_deleteResultSetResponse(apdu->u.
+                                                deleteResultSetResponse);
+                break;
+            default:
+                printf("Received unknown APDU type (%d).\n", 
+                       apdu->which);
+                close_session ();
+            }
+        }
+#if HAVE_XML2
+        else if (gdu->which == Z_GDU_HTTP_Response)
+        {
+            http_response(gdu->u.HTTP_Response);
+        }
+#endif
+        if (conn && !cs_more(conn))
+            break;
+    } // while conn
+    if (conn)
+    {
+#if HAVE_GETTIMEOFDAY
+        gettimeofday (&tv_end, 0);
+#if 0
+        printf ("S/U S/U=%ld/%ld %ld/%ld",
+                (long) tv_start.tv_sec,
+                (long) tv_start.tv_usec,
+                (long) tv_end.tv_sec,
+                (long) tv_end.tv_usec);
+#endif
+        printf ("Elapsed: %.6f\n",
+                (double) tv_end.tv_usec / 1e6 + tv_end.tv_sec -
+                ((double) tv_start.tv_usec / 1e6 + tv_start.tv_sec));
+#endif
+    }
+    xfree (netbuffer);
+}
+
+
+int cmd_cclparse(const char* arg) 
+{
+    int error, pos;
+    struct ccl_rpn_node *rpn=NULL;
+    
+    
+    rpn = ccl_find_str (bibset, arg, &error, &pos);
+    
+    if (error) {
+        printf ("%*s^ - ", 3+strlen(last_cmd)+1+pos, " ");
+        printf ("%s\n", ccl_err_msg (error));
+    }
+    else
+    {
+        if (rpn)
+        {	
+            ccl_pr_tree(rpn, stdout); 
+        }
+    }
+    if (rpn)
+        ccl_rpn_delete(rpn);
+    
+    printf ("\n");
+    
+    return 0;
+}
+
+
+int cmd_set_otherinfo(const char* args)
+{
+    char oidstr[101], otherinfoString[101];
+    int otherinfoNo;
+    int sscan_res;
+    int oidval;
+    
+    sscan_res = sscanf (args, "%d %100[^ ] %100s", &otherinfoNo, oidstr, otherinfoString);
+    if (sscan_res==1) {
+        /* reset this otherinfo */
+        if(otherinfoNo>=maxOtherInfosSupported) {
+            printf("Error otherinfo index to large (%d>%d)\n",
+		   otherinfoNo,maxOtherInfosSupported);
+        }
+        extraOtherInfos[otherinfoNo].oidval = -1;
+        if (extraOtherInfos[otherinfoNo].value)
+	    free(extraOtherInfos[otherinfoNo].value);	 		
+        return 0;
+    }
+    if (sscan_res<3) {
+        printf("Error in set_otherinfo command \n");
+        return 0;
+    }
+    
+    if (otherinfoNo>=maxOtherInfosSupported) {
+        printf("Error otherinfo index to large (%d>%d)\n",
+	       otherinfoNo,maxOtherInfosSupported);
+    }
+    
+    oidval = oid_getvalbyname (oidstr);
+    if (oidval == -1 ) {
+        printf("Error in set_otherinfo command unknown oid %s \n",oidstr);
+        return 0;
+    }
+    extraOtherInfos[otherinfoNo].oidval = oidval;
+    if(extraOtherInfos[otherinfoNo].value) free(extraOtherInfos[otherinfoNo].value);
+    extraOtherInfos[otherinfoNo].value = strdup(otherinfoString);
+    
+    return 0;
+}
+
+int cmd_sleep(const char* args ) 
+{
+    int sec=atoi(args);
+    if( sec > 0 ) {
+#ifdef WIN32
+	Sleep(sec*1000);
+#else
+	sleep(sec);
+#endif
+	printf("Done sleeping %d seconds\n", sec);	
+    }
+    return 1;    
+}
+
+int cmd_list_otherinfo(const char* args)
+{
+    int i;	   
+    
+    if(strlen(args)>0) {
+        i = atoi(args);
+        if( i >= maxOtherInfosSupported ) {
+            printf("Error otherinfo index to large (%d>%d)\n",i,maxOtherInfosSupported);
+            return 0;
+        }
+
+        if(extraOtherInfos[i].oidval != -1) 
+            printf("  otherinfo %d %s %s\n",
+                   i,
+                   yaz_z3950_oid_value_to_str(
+                       (enum oid_value) extraOtherInfos[i].oidval,
+                       CLASS_RECSYN),
+                   extraOtherInfos[i].value);
+        
+    } else {		
+        for(i=0; i<maxOtherInfosSupported; ++i) {
+            if(extraOtherInfos[i].oidval != -1) 
+                printf("  otherinfo %d %s %s\n",
+                       i,
+                       yaz_z3950_oid_value_to_str(
+                           (enum oid_value) extraOtherInfos[i].oidval,
+                           CLASS_RECSYN),
+                       extraOtherInfos[i].value);
+        }
+        
+    }
+    return 0;
+}
+
+
+int cmd_list_all(const char* args) {
+    int i;
+    
+    /* connection options */
+    if(conn) {
+        printf("Connected to         : %s\n",last_open_command);
+    } else {
+        if(last_open_command) 
+            printf("Not connected to     : %s\n",last_open_command);
+        else 
+            printf("Not connected        : \n");
+        
+    }
+    if(yazProxy) printf("using proxy          : %s\n",yazProxy);		
+    
+    printf("auto_reconnect       : %s\n",auto_reconnect?"on":"off");
+    
+    if (!auth) {
+        printf("Authentication       : none\n");
+    } else {
+        switch(auth->which) {
+        case Z_IdAuthentication_idPass:
+            printf("Authentication       : IdPass\n"); 
+            printf("    Login User       : %s\n",auth->u.idPass->userId?auth->u.idPass->userId:"");
+            printf("    Login Group      : %s\n",auth->u.idPass->groupId?auth->u.idPass->groupId:"");
+            printf("    Password         : %s\n",auth->u.idPass->password?auth->u.idPass->password:"");
+            break;
+        case Z_IdAuthentication_open:
+            printf("Authentication       : psOpen\n");			
+            printf("    Open string      : %s\n",auth->u.open);	
+            break;
+        default:
+            printf("Authentication       : Unknown\n");
+        }
+    }
+    if (negotiationCharset)
+        printf("Neg. Character set   : `%s'\n", negotiationCharset);
+    
+    /* bases */
+    printf("Bases                : ");
+    for (i = 0; i<num_databaseNames; i++) printf("%s ",databaseNames[i]);
+    printf("\n");
+    
+    /* Query options */
+    printf("CCL file             : %s\n",ccl_fields);
+    printf("CQL file             : %s\n",cql_fields);
+    printf("Query type           : %s\n",query_type_as_string(queryType));
+    
+    printf("Named Result Sets    : %s\n",setnumber==-1?"off":"on");
+    
+    /* piggy back options */
+    printf("ssub/lslb/mspn       : %d/%d/%d\n",smallSetUpperBound,largeSetLowerBound,mediumSetPresentNumber);
+    
+    /* print present related options */
+    printf("Format               : %s\n",yaz_z3950_oid_value_to_str(recordsyntax,CLASS_RECSYN));
+    printf("Schema               : %s\n",record_schema ? record_schema : "not set");
+    printf("Elements             : %s\n",elementSetNames?elementSetNames->u.generic:"");
+    
+    /* loging options */
+    printf("APDU log             : %s\n",apdu_file?"on":"off");
+    printf("Record log           : %s\n",marc_file?"on":"off");
+    
+    /* other infos */
+    printf("Other Info: \n");
+    cmd_list_otherinfo("");
+    
+    return 0;
+}
+
+int cmd_clear_otherinfo(const char* args) 
+{
+    if(strlen(args)>0) {
+        int otherinfoNo;
+        otherinfoNo = atoi(args);
+        if( otherinfoNo >= maxOtherInfosSupported ) {
+            printf("Error otherinfo index to large (%d>%d)\n",otherinfoNo,maxOtherInfosSupported);
+            return 0;
+        }
+        
+        if(extraOtherInfos[otherinfoNo].oidval != -1) {			
+            /* only clear if set. */
+            extraOtherInfos[otherinfoNo].oidval=-1;
+            free(extraOtherInfos[otherinfoNo].value);
+        }
+    } else {
+        int i;
+	
+        for(i=0; i<maxOtherInfosSupported; ++i) {
+            if (extraOtherInfos[i].oidval!=-1 ) {				
+                extraOtherInfos[i].oidval=-1;
+                free(extraOtherInfos[i].value);
+            }
+        }
+    }
+    return 0;
+}
+
+static int cmd_help (const char *line);
+
+typedef char *(*completerFunctionType)(const char *text, int state);
+
+static struct {
+    char *cmd;
+    int (*fun)(const char *arg);
+    char *ad;
+    completerFunctionType rl_completerfunction;
+    int complete_filenames;
+    char **local_tabcompletes;
+} cmd_array[] = {
+    {"open", cmd_open, "('tcp'|'ssl')':<host>[':'<port>][/<db>]",NULL,0,NULL},
+    {"quit", cmd_quit, "",NULL,0,NULL},
+    {"find", cmd_find, "<query>",NULL,0,NULL},
+    {"delete", cmd_delete, "<setname>",NULL,0,NULL},
+    {"base", cmd_base, "<base-name>",NULL,0,NULL},
+    {"show", cmd_show, "<rec#>['+'<#recs>['+'<setname>]]",NULL,0,NULL},
+    {"scan", cmd_scan, "<term>",NULL,0,NULL},
+    {"scanstep", cmd_scanstep, "<size>",NULL,0,NULL},
+    {"scanpos", cmd_scanpos, "<size>",NULL,0,NULL},
+    {"scansize", cmd_scansize, "<size>",NULL,0,NULL},
+    {"sort", cmd_sort, "<sortkey> <flag> <sortkey> <flag> ...",NULL,0,NULL},
+    {"sort+", cmd_sort_newset, "<sortkey> <flag> <sortkey> <flag> ...",NULL,0,NULL},
+    {"authentication", cmd_authentication, "<acctstring>",NULL,0,NULL},
+    {"lslb", cmd_lslb, "<largeSetLowerBound>",NULL,0,NULL},
+    {"ssub", cmd_ssub, "<smallSetUpperBound>",NULL,0,NULL},
+    {"mspn", cmd_mspn, "<mediumSetPresentNumber>",NULL,0,NULL},
+    {"status", cmd_status, "",NULL,0,NULL},
+    {"setnames", cmd_setnames, "",NULL,0,NULL},
+    {"cancel", cmd_cancel, "",NULL,0,NULL},
+    {"cancel_find", cmd_cancel_find, "<query>",NULL,0,NULL},
+    {"format", cmd_format, "<recordsyntax>",complete_format,0,NULL},
+    {"schema", cmd_schema, "<schema>",complete_schema,0,NULL},
+    {"elements", cmd_elements, "<elementSetName>",NULL,0,NULL},
+    {"close", z_cmd_close, "",NULL,0,NULL},
+    {"attributeset", cmd_attributeset, "<attrset>",complete_attributeset,0,NULL},
+    {"querytype", cmd_querytype, "<type>",complete_querytype,0,NULL},
+    {"refid", cmd_refid, "<id>",NULL,0,NULL},
+    {"itemorder", cmd_itemorder, "ill|item <itemno>",NULL,0,NULL},
+    {"update", cmd_update, "<action> <recid> [<file>]",NULL,0,NULL},
+    {"update0", cmd_update0, "<action> <recid> [<file>]",NULL,0,NULL},
+    {"packagename", cmd_packagename, "<packagename>",NULL,0,NULL},
+    {"proxy", cmd_proxy, "[('tcp'|'ssl')]<host>[':'<port>]",NULL,0,NULL},
+    {"charset", cmd_charset, "<nego_charset> <output_charset>",NULL,0,NULL},
+    {"negcharset", cmd_negcharset, "<nego_charset>",NULL,0,NULL},
+    {"displaycharset", cmd_displaycharset, "<output_charset>",NULL,0,NULL},
+    {"marccharset", cmd_marccharset, "<charset_name>",NULL,0,NULL},
+    {"lang", cmd_lang, "<language_code>",NULL,0,NULL},
+    {".", cmd_source_echo, "<filename>",NULL,1,NULL},
+    {"!", cmd_subshell, "Subshell command",NULL,1,NULL},
+    {"set_apdufile", cmd_set_apdufile, "<filename>",NULL,1,NULL},
+    {"set_berfile", cmd_set_berfile, "<filename>",NULL,1,NULL},
+    {"set_marcdump", cmd_set_marcdump," <filename>",NULL,1,NULL},
+    {"set_cclfile", cmd_set_cclfile," <filename>",NULL,1,NULL},
+    {"set_cqlfile", cmd_set_cqlfile," <filename>",NULL,1,NULL},
+    {"set_auto_reconnect", cmd_set_auto_reconnect," on|off",complete_auto_reconnect,1,NULL},
+    {"set_otherinfo", cmd_set_otherinfo,"<otherinfoinddex> <oid> <string>",NULL,0,NULL},
+    {"sleep", cmd_sleep,"<seconds>",NULL,0,NULL},
+    {"register_oid", cmd_register_oid,"<name> <class> <oid>",NULL,0,NULL},
+    {"push_command", cmd_push_command,"<command>",command_generator,0,NULL},
+    {"register_tab", cmd_register_tab,"<commandname> <tab>",command_generator,0,NULL},
+    {"cclparse", cmd_cclparse,"<ccl find command>",NULL,0,NULL},
+    {"list_otherinfo",cmd_list_otherinfo,"[otherinfoinddex]",NULL,0,NULL},
+    {"list_all",cmd_list_all,"",NULL,0,NULL},
+    {"clear_otherinfo",cmd_clear_otherinfo,"",NULL,0,NULL},
+    /* Server Admin Functions */
+    /*    {"adm-reindex", cmd_adm_reindex, "<database-name>",NULL,0,NULL},
+    {"adm-truncate", cmd_adm_truncate, "('database'|'index')<object-name>",NULL,0,NULL},
+    {"adm-create", cmd_adm_create, "",NULL,0,NULL},
+    {"adm-drop", cmd_adm_drop, "('database'|'index')<object-name>",NULL,0,NULL},
+    {"adm-import", cmd_adm_import, "<record-type> <dir> <pattern>",NULL,0,NULL},
+    {"adm-refresh", cmd_adm_refresh, "",NULL,0,NULL},
+    {"adm-commit", cmd_adm_commit, "",NULL,0,NULL},
+    {"adm-shutdown", cmd_adm_shutdown, "",NULL,0,NULL},
+    {"adm-startup", cmd_adm_startup, "",NULL,0,NULL},*/
+    {"explain", cmd_explain, "", NULL, 0, NULL},
+    {"options", cmd_options, "", NULL, 0, NULL},
+    {"zversion", cmd_zversion, "", NULL, 0, NULL},
+    {"help", cmd_help, "", NULL,0,NULL},
+    {"init", cmd_init, "", NULL,0,NULL},
+    {0,0,0,0,0,0}
+};
+
+static int cmd_help (const char *line)
+{
+    int i;
+    char topic[21];
+    
+    *topic = 0;
+    sscanf (line, "%20s", topic);
+
+    if (*topic == 0)
+        printf("Commands:\n");
+    for (i = 0; cmd_array[i].cmd; i++)
+        if (*topic == 0 || strcmp (topic, cmd_array[i].cmd) == 0)
+            printf("   %s %s\n", cmd_array[i].cmd, cmd_array[i].ad);
+    if (strcmp (topic, "find") == 0)
+    {
+        printf ("RPN:\n");
+        printf (" \"term\"                        Simple Term\n");
+        printf (" @attr [attset] type=value op  Attribute\n");
+        printf (" @and opl opr                  And\n");
+        printf (" @or opl opr                   Or\n");
+        printf (" @not opl opr                  And-Not\n");
+        printf (" @set set                      Result set\n");
+        printf ("\n");
+        printf ("Bib-1 attribute types\n");
+        printf ("1=Use:         ");
+        printf ("4=Title 7=ISBN 8=ISSN 30=Date 62=Abstract 1003=Author 1016=Any\n");
+        printf ("2=Relation:    ");
+        printf ("1<   2<=  3=  4>=  5>  6!=  102=Relevance\n");
+        printf ("3=Position:    ");
+        printf ("1=First in Field  2=First in subfield  3=Any position\n");
+        printf ("4=Structure:   ");
+        printf ("1=Phrase  2=Word  3=Key  4=Year  5=Date  6=WordList\n");
+        printf ("5=Truncation:  ");
+        printf ("1=Right  2=Left  3=L&R  100=No  101=#  102=Re-1  103=Re-2\n");
+        printf ("6=Completeness:");
+        printf ("1=Incomplete subfield  2=Complete subfield  3=Complete field\n");
+    }
+    return 1;
+}
+
+int cmd_register_tab(const char* arg) {
+	
+    char command[101], tabargument[101];
+    int i;
+    int num_of_tabs;
+    char** tabslist;
+    
+    if (sscanf (arg, "%100s %100s", command, tabargument) < 1) {
+        return 0;
+    }
+    
+    /* locate the amdn in the list */
+    for (i = 0; cmd_array[i].cmd; i++) {
+        if (!strncmp(cmd_array[i].cmd, command, strlen(command))) {
+            break;
+        }
+    }
+    
+    if(!cmd_array[i].cmd) { 
+        fprintf(stderr,"Unknown command %s\n",command);
+        return 1;
+    }
+    
+        
+    if(!cmd_array[i].local_tabcompletes)
+        cmd_array[i].local_tabcompletes = (char **) calloc(1,sizeof(char**));
+    
+    num_of_tabs=0;		
+    
+    tabslist = cmd_array[i].local_tabcompletes;
+    for(;tabslist && *tabslist;tabslist++) {
+        num_of_tabs++;
+    }
+    
+    cmd_array[i].local_tabcompletes =  (char **)
+        realloc(cmd_array[i].local_tabcompletes,(num_of_tabs+2)*sizeof(char**));
+    tabslist=cmd_array[i].local_tabcompletes;
+    tabslist[num_of_tabs]=strdup(tabargument);
+    tabslist[num_of_tabs+1]=NULL;
+    return 1;
+}
+
+
+void process_cmd_line(char* line)
+{  
+    int i,res;
+    char word[32], arg[10240];
+    
+#if HAVE_GETTIMEOFDAY
+    gettimeofday (&tv_start, 0);
+#endif
+    
+    if ((res = sscanf(line, "%31s %10239[^;]", word, arg)) <= 0)
+    {
+        strcpy(word, last_cmd);
+        *arg = '\0';
+    }
+    else if (res == 1)
+        *arg = 0;
+    strcpy(last_cmd, word);
+    
+    /* removed tailing spaces from the arg command */
+    { 
+        char* p = arg;
+        char* lastnonspace=NULL;
+        
+        for(;*p; ++p) {
+            if(!isspace(*(unsigned char *) p)) {
+                lastnonspace = p;
+            }
+        }
+        if(lastnonspace) 
+            *(++lastnonspace) = 0;
+    }
+    
+    for (i = 0; cmd_array[i].cmd; i++)
+        if (!strncmp(cmd_array[i].cmd, word, strlen(word)))
+        {
+            res = (*cmd_array[i].fun)(arg);
+            break;
+        }
+    
+    if (!cmd_array[i].cmd) /* dump our help-screen */
+    {
+        printf("Unknown command: %s.\n", word);
+        printf("use help for list of commands\n");
+        /* cmd_help (""); */
+        res = 1;
+    }
+    
+    if(apdu_file) fflush(apdu_file);
+    
+    if (res >= 2)
+        wait_and_handle_response();
+    
+    if(apdu_file)
+        fflush(apdu_file);
+    if(marc_file)
+        fflush(marc_file);
+}
+
+
+char *command_generator(const char *text, int state) 
+{
+    static int idx; 
+    if (state==0) {
+        idx = 0;
+    }
+    for( ; cmd_array[idx].cmd; ++idx) {
+        if (!strncmp(cmd_array[idx].cmd,text,strlen(text))) {
+            ++idx;  /* skip this entry on the next run */
+            return strdup(cmd_array[idx-1].cmd);
+        }
+    }
+    return NULL;
+}
+
+
+/* 
+   This function only known how to complete on the first word
+*/
+char ** readline_completer(char *text, int start, int end) {
+#if HAVE_READLINE_READLINE_H
+
+	completerFunctionType completerToUse;
+	
+    if(start == 0) {
+#if HAVE_READLINE_RL_COMPLETION_MATCHES
+        char** res=rl_completion_matches(text,
+                                      command_generator); 
+#else
+        char** res=completion_matches(text,
+                                      (CPFunction*)command_generator); 
+#endif
+        rl_attempted_completion_over = 1;
+        return res;
+    } else {
+        char arg[10240],word[32];
+        int i=0 ,res;
+        if ((res = sscanf(rl_line_buffer, "%31s %10239[^;]", word, arg)) <= 0) {     
+            rl_attempted_completion_over = 1;
+            return NULL;
+        }
+        
+        for (i = 0; cmd_array[i].cmd; i++) {
+            if (!strncmp(cmd_array[i].cmd, word, strlen(word))) {
+                break;
+            }
+        }
+        
+        if(!cmd_array[i].cmd) return NULL;
+        
+        curret_global_list = cmd_array[i].local_tabcompletes;
+        
+        completerToUse = cmd_array[i].rl_completerfunction;
+        if(completerToUse==NULL)  /* if no pr. command completer is defined use the default completer */
+            completerToUse = default_completer;
+        
+        if(completerToUse) {
+#ifdef HAVE_READLINE_RL_COMPLETION_MATCHES
+            char** res=
+                rl_completion_matches(text,
+                                      completerToUse);
+#else
+            char** res=
+                completion_matches(text,
+                                   (CPFunction*)completerToUse);
+#endif
+            if(!cmd_array[i].complete_filenames) 
+                rl_attempted_completion_over = 1;
+            return res;
+        } else {
+            if(!cmd_array[i].complete_filenames) 
+                rl_attempted_completion_over = 1;
+            return 0;
+        }
+    }
+#else 
+    return 0;
+#endif 
+}
+
+
+static void client(void)
+{
+    char line[10240];
+
+    line[10239] = '\0';
+
+#if HAVE_GETTIMEOFDAY
+    gettimeofday (&tv_start, 0);
+#endif
+
+    while (1)
+    {
+        char *line_in = NULL;
+#if HAVE_READLINE_READLINE_H
+        if (isatty(0))
+        {
+            line_in=readline(C_PROMPT);
+            if (!line_in)
+                break;
+#if HAVE_READLINE_HISTORY_H
+            if (*line_in)
+                add_history(line_in);
+#endif
+            strncpy(line, line_in, 10239);
+            free (line_in);
+        }
+#endif 
+        if (!line_in)
+        {
+            char *end_p;
+            printf (C_PROMPT);
+            fflush(stdout);
+            if (!fgets(line, 10239, stdin))
+                break;
+            if ((end_p = strchr (line, '\n')))
+                *end_p = '\0';
+        }
+        process_cmd_line(line);
+    }
+}
+
+static void show_version(void)
+{
+    char vstr[20];
+
+    yaz_version(vstr, 0);
+    printf ("YAZ version: %s\n", YAZ_VERSION);
+    if (strcmp(vstr, YAZ_VERSION))
+	printf ("YAZ DLL/SO: %s\n", vstr);
+    exit(0);
+}
+
+/*
+int main(int argc, char **argv)
+{
+    char *prog = *argv;
+    char *open_command = 0;
+    char *auth_command = 0;
+    char *arg;
+    int ret;
+    
+#if HAVE_LOCALE_H
+    if (!setlocale(LC_CTYPE, ""))
+        fprintf (stderr, "setlocale failed\n");
+#endif
+#if HAVE_LANGINFO_H
+#ifdef CODESET
+    codeset = nl_langinfo(CODESET);
+#endif
+#endif
+    if (codeset)
+	outputCharset = xstrdup(codeset);
+    
+    ODR_MASK_SET(&z3950_options, Z_Options_search);
+    ODR_MASK_SET(&z3950_options, Z_Options_present);
+    ODR_MASK_SET(&z3950_options, Z_Options_namedResultSets);
+    ODR_MASK_SET(&z3950_options, Z_Options_triggerResourceCtrl);
+    ODR_MASK_SET(&z3950_options, Z_Options_scan);
+    ODR_MASK_SET(&z3950_options, Z_Options_sort);
+    ODR_MASK_SET(&z3950_options, Z_Options_extendedServices);
+    ODR_MASK_SET(&z3950_options, Z_Options_delSet);
+
+    while ((ret = options("k:c:q:a:b:m:v:p:u:t:Vxd:", argv, argc, &arg)) != -2)
+    {
+        switch (ret)
+        {
+        case 0:
+            if (!open_command)
+            {
+                open_command = (char *) xmalloc (strlen(arg)+6);
+                strcpy (open_command, "open ");
+                strcat (open_command, arg);
+            }
+	    else
+	    {
+		fprintf(stderr, "%s: Specify at most one server address\n",
+			prog);
+		exit(1);
+	    }
+            break;
+	case 'd':
+	    dump_file_prefix = arg;
+	    break;
+        case 'k':
+            kilobytes = atoi(arg);
+            break;
+        case 'm':
+            if (!(marc_file = fopen (arg, "a")))
+            {
+                perror (arg);
+                exit (1);
+            }
+            break;
+        case 't':
+            outputCharset = xstrdup(arg);
+            break;
+        case 'c':
+            strncpy (ccl_fields, arg, sizeof(ccl_fields)-1);
+            ccl_fields[sizeof(ccl_fields)-1] = '\0';
+            break;
+        case 'q':
+            strncpy (cql_fields, arg, sizeof(cql_fields)-1);
+            cql_fields[sizeof(cql_fields)-1] = '\0';
+            break;
+        case 'b':
+            if (!strcmp(arg, "-"))
+                ber_file=stderr;
+            else
+                ber_file=fopen(arg, "a");
+            break;
+        case 'a':
+            if (!strcmp(arg, "-"))
+                apdu_file=stderr;
+            else
+                apdu_file=fopen(arg, "a");
+            break;
+	case 'x':
+	    hex_dump = 1;
+	    break;
+        case 'p':
+            yazProxy=strdup(arg);
+            break;
+        case 'u':
+            if (!auth_command)
+            {
+                auth_command = (char *) xmalloc (strlen(arg)+6);
+                strcpy (auth_command, "auth ");
+                strcat (auth_command, arg);
+            }
+            break;
+        case 'v':
+            yaz_log_init(yaz_log_mask_str(arg), "", 0);
+            break;
+        case 'V':
+	    show_version();
+            break;
+        default:
+            fprintf (stderr, "Usage: %s [-m <marclog>] [ -a <apdulog>] "
+                     "[-b berdump] [-c cclfields] \n"
+		     "[-q cqlfields] [-p <proxy-addr>] [-u <auth>] "
+                     "[-k size] [-d dump] [-V] [<server-addr>]\n",
+                     prog);
+            exit (1);
+        }      
+    }
+    z_initialize();
+    if (auth_command)
+    {
+#ifdef HAVE_GETTIMEOFDAY
+        gettimeofday (&tv_start, 0);
+#endif
+        process_cmd_line (auth_command);
+#if HAVE_READLINE_HISTORY_H
+        add_history(auth_command);
+#endif
+        xfree(auth_command);
+    }
+    if (open_command)
+    {
+#ifdef HAVE_GETTIMEOFDAY
+        gettimeofday (&tv_start, 0);
+#endif
+        process_cmd_line (open_command);
+#if HAVE_READLINE_HISTORY_H
+        add_history(open_command);
+#endif
+        xfree(open_command);
+    }
+    client ();
+    exit (0);
+}
+*/
+/*
+ * Local variables:
+ * tab-width: 8
+ * c-basic-offset: 4
+ * End:
+ * vim600: sw=4 ts=8 fdm=marker
+ * vim<600: sw=4 ts=8
+ */
+
+static int z_getAPDU (Z_APDU **ret_apdu) {
+    int res;
+
+    char *netbuffer= 0;
+    int netbufferlen = 0;
+    Z_APDU *apdu;
+    Z_GDU *gdu;
+    
+    if ((res = cs_get(conn, &netbuffer, &netbufferlen)) < 0) {
+	close_session();
+	perror("cs_get");
+	exit(1);
+    }
+    if (!res) {
+	printf("Target closed connection.\n");
+	close_session();
+	exit(1);
+    }
+    odr_reset(in); /* release APDU from last round */
+    record_last = 0;
+    do_hex_dump(netbuffer, res);
+    odr_setbuf(in, netbuffer, res, 0);
+    
+    if (!z_GDU(in, &gdu, 0, 0)) {
+	
+	odr_perror(in, "Decoding incoming APDU");
+	fprintf(stderr, "[Near %d]\n", odr_offset(in));
+	fprintf(stderr, "Packet dump:\n---------\n");
+	odr_dumpBER(stderr, netbuffer, res);
+	fprintf(stderr, "---------\n");
+	if (apdu_file) {
+	    z_GDU(print, &gdu, 0, 0);
+	    odr_reset(print);
+	}
+	xfree(netbuffer);
+	exit(1); /* was break */
+    }
+    xfree(netbuffer);
+    if (apdu_file && !z_GDU(print, &gdu, 0, 0)) {
+	
+	odr_perror(print, "Failed to print incoming APDU");
+	odr_reset(print);
+	return -1; /* was continue */
+    }
+    if (gdu->which == Z_GDU_Z3950) {
+        
+	Z_APDU *apdu = gdu->u.z3950;
+	(*ret_apdu)=apdu;
+	return 0;
+    }
+    /* else a differnet kind of response, which we don't handle */
+    return -1;
+}
+
+/* gets a generic response from the server */
+int z_getnextAPDU () {
+  Z_APDU *apdu;
+  apdu=NULL;
+  
+  z_getAPDU(&apdu);
+
+  switch(apdu->which) {
+      
+  case Z_APDU_initResponse:
+      // kjdon copying johnmcp
+      /* save session parameters for later use */
+      session_mem = odr_extract_mem(in);
+      session = apdu->u.initResponse;
+      // greenstone will call z_get_initResponse to get the info
+      // about what happened with the connection
+      //process_initResponse(apdu->u.initResponse);
+      break;
+  case Z_APDU_searchResponse:
+      process_searchResponse(apdu->u.searchResponse);
+      break;
+  case Z_APDU_scanResponse:
+      process_scanResponse(apdu->u.scanResponse);
+      break;
+  case Z_APDU_presentResponse:
+      print_refid (apdu->u.presentResponse->referenceId);
+      setno +=
+	  *apdu->u.presentResponse->numberOfRecordsReturned;
+      if (apdu->u.presentResponse->records) {
+	  display_records(apdu->u.presentResponse->records);
+	  printf ("nextResultSetPosition = %d\n",
+		  *apdu->u.presentResponse->nextResultSetPosition);
+      }
+      else {
+	  printf("No records.\n");
+      }
+      break;
+  case Z_APDU_sortResponse:
+      process_sortResponse(apdu->u.sortResponse);
+      break;
+  case Z_APDU_extendedServicesResponse:
+      printf("Got extended services response\n");
+      process_ESResponse(apdu->u.extendedServicesResponse);
+      break;
+  case Z_APDU_close:
+      printf("Target has closed the association.\n");
+      process_close(apdu->u.close);
+      break;
+  case Z_APDU_resourceControlRequest:
+      process_resourceControlRequest
+	  (apdu->u.resourceControlRequest);
+      break;
+  case Z_APDU_deleteResultSetResponse:
+      process_deleteResultSetResponse(apdu->u.
+				      deleteResultSetResponse);
+      break;
+  default:
+      printf("Received unknown APDU type (%d).\n", 
+	     apdu->which);
+      close_session ();
+  }
+  return 0;
+ 
+}
+
+/* returns number of records found */
+/*int z_cmd_dosearch(char *search){
+
+}
+*/
+/* returns an array of strings containing record titles. The first element
+   is an int, saying how many titles follow (can be zero). NULL on error. */
+/*char **z_getrecordTitles(int start,int count){
+
+}
+*/
+/* returns a string containing the whole marc record */
+/*char *z_getfullRecord(int record){
+
+}
+*/
+
+
+/* returns number found, arg is query string */
+int z_cmd_dosearch(char *arg)
+{
+  Z_APDU *apdu;
+  int matching;
+  int ret_val;
+  ret_val=send_searchRequest(arg);
+  if (ret_val==-1) {
+    /* prefix query error */
+    return (-1);
+  }
+  z_getAPDU(&apdu);
+  /* check return value??? */
+  if (apdu->which != Z_APDU_searchResponse)
+    {
+      printf("sendsearchRequest() was not replied with a searchResponse!\n");
+      return (-2);
+    }
+  /* let's keep going anyway... */
+  matching=process_searchResponse(apdu->u.searchResponse);
+  /* this assumes we want to take action on failure (-1) here rather than
+     whereever we were called from */
+  return (matching);
+}
+
+/* src must be NULL-terminated */
+static char *safeappendstr(char *dest, size_t *allocsize, 
+			  size_t *offset, char *src) {
+  /* allocsize is the amount of space currently allocated to dest,
+     offset is how far into dest we want to append src */
+  if (*offset + strlen(src) >= *allocsize) {
+    *allocsize+=strlen(src)+64; /* add some extra space to save on reallocs */
+    if ((dest=realloc(dest,*allocsize))==NULL) {
+      fprintf(stderr, "malloc failed while decoding marc record.\n");
+      return (NULL);
+    }
+  }
+  strcpy(dest+(*offset), src);
+  *offset+=strlen(src);
+  return (dest);
+}
+
+static char *getmarcfields(Z_External *p, int titleonly) {
+  /* this code is based on marc_display(), with a couple of lines taken from
+     display_record() in the original client. */
+  /* if titleonly is non-zero, we only get a (the?) title field, otherwise
+     return the whole thing */
+  const char *buf=(char *)p->u.octet_aligned->buf;
+  char *title;      /* our string to return */
+  int title_maxlen=0; /* amount of space currently allocated */
+  int title_curlen=0;    /* amount of space actually used */
+  int entry_p;
+  int record_length;
+  int indicator_length;
+  int identifier_length;
+  int base_address;
+  int length_data_entry;
+  int length_starting;
+  int length_implementation;
+  FILE *outf;
+
+  /*  if (!outf) */
+  outf = stdout;
+
+  /* initialise our title. Start with 64 chars */
+  title_maxlen=64;
+  if((title=malloc(title_maxlen))==NULL) {
+    /* not quite sure where stderr will be going, but.... */
+    fprintf(stderr,"Malloc failed while decoding marc record\n");
+    return NULL;
+  }
+
+  if (!titleonly) {
+    strcpy(title,"<table border=1>\n");
+    title_curlen=strlen(title);
+  }
+  else  title_curlen=0;
+
+  record_length = atoi_n (buf, 5);
+  if (record_length < 25)
+    return (NULL); /* -1 */
+  if (isdigit(buf[10]))
+    indicator_length = atoi_n (buf+10, 1);
+  else
+    indicator_length = 2;
+  if (isdigit(buf[11]))
+    identifier_length = atoi_n (buf+11, 1);
+  else
+    identifier_length = 2;
+  base_address = atoi_n (buf+12, 4);
+  
+  length_data_entry = atoi_n (buf+20, 1);
+  length_starting = atoi_n (buf+21, 1);
+  length_implementation = atoi_n (buf+22, 1);
+  
+  if (0) /* debug */
+    {
+      fprintf (outf, "Record length         %5d\n", record_length);
+      fprintf (outf, "Indicator length      %5d\n", indicator_length);
+      fprintf (outf, "Identifier length     %5d\n", identifier_length);
+      fprintf (outf, "Base address          %5d\n", base_address);
+      fprintf (outf, "Length data entry     %5d\n", length_data_entry);
+      fprintf (outf, "Length starting       %5d\n", length_starting);
+      fprintf (outf, "Length implementation %5d\n", length_implementation);
+    }
+  for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
+    {
+      entry_p += 3+length_data_entry+length_starting;
+      if (entry_p >= record_length)
+	return (NULL); /* -1 */
+    }
+  base_address = entry_p+1;
+  for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
+    {
+      int data_length;
+      int data_offset;
+      int end_offset;
+      int i /*, j*/ ;
+      int startofstring;
+      int whichtag;
+      short int abbrtitle=0;
+      char tag[4];
+      memcpy (tag, buf+entry_p, 3);
+      entry_p += 3;
+      tag[3] = '\0';
+      whichtag=atoi(tag);
+      if (0) /* debug */
+	fprintf (outf, "Tag: ");
+      /* johnmcp 
+	 Relevant tags (for "main entry") - assume only one of these is set,
+	 as we will only return the first one found.
+	 100=personal name
+	 110=corporate name
+	 111=meeting name
+	 130=uniform title
+	 subfields: $a=personal name, $c=title/other, $d=date
+
+	 210=Abbreviated Title
+	 222=Key title
+	 240=uniform title
+	 243=collective uniform title
+	 245=title statement
+	 246=varying form of title
+	 247=former title or title variations
+	 subfields: $a=abbrev. title $b=qualifying info $2=source
+	 .          $6=linkage $8=link field and sequence number.
+      */
+      /*fprintf (outf, "%s ", tag); */
+      data_length = atoi_n (buf+entry_p, length_data_entry);
+      entry_p += length_data_entry;
+      data_offset = atoi_n (buf+entry_p, length_starting);
+      entry_p += length_starting;
+      i = data_offset + base_address;
+      end_offset = i+data_length-1;
+
+      if (0) /* debug */
+	fprintf (outf, " Ind: ");
+
+      /* memcmp (tag,"00",2) is true, then we DON'T have a control tag
+	 ie less than 10. */
+      /*if (memcmp (tag, "00", 2) && indicator_length)
+	{
+	for (j = 0; j<indicator_length; j++)
+	fprintf (outf, "%c", buf[i++]);
+	}
+      */
+      if (whichtag>=10) i+=indicator_length;
+      /* the control fields (<10) don't have leading chars. */
+
+
+      if (0) /* debug */
+	fprintf (outf, " Fields: ");
+
+      /* If we only want the title, then skip other fields */
+      if (titleonly &&(whichtag<200||whichtag>249)) {
+	/* skip this record */
+	continue;
+	i=end_offset;
+      }
+      
+      /* either titleonly is 0, or titleonly is 1 and whichtag is between
+	 200 and 249... */
+      if (!titleonly) {
+	/* This should probably be read in from a separate file.
+	   This is also hard-coded for USMARC/MARC21 fieldnames!!! */
+
+	/* print out what kind of tag this is */
+	char *tagname;
+	char *field_control1="<tr><td>Marc Control Number:</td><td>";
+	char *field_control3="<tr><td>Marc Organisation Code:</td><td>";
+	char *field_control5="<tr><td>Marc record Date Info.:</td><td>";
+	char *field_control8="<tr><td>Control Field (Marc info):</td><td>";
+	char *field_loc_nr="<tr><td>Lib. of Congress control #:</td><td>";
+	char *field_issn="<tr><td>ISSN Number:</td><td>";
+	char *field_catalog="<tr><td>Catalog agency:</td><td>";
+	char *field_lang="<tr><td>3-letter language code(s):</td><td>";
+	char *field_areacode="<tr><td>Geographic Area code:</td><td>";
+	char *field_cn_loc="<tr><td>Lib. of Congress Call #:</td><td>";
+	char *field_cn_dewdec="<tr><td>Dewey Decimal Call #:</td><td>";
+	char *field_cn_other="<tr><td>Other Classification Info.:</td><td>";
+	char *field_cn_gd="<tr><td>Govt. Document Call #:</td><td>";
+	char *field_personalname="<tr><td>Personal Name:</td><td>";
+	char *field_meetingname="<tr><td>Meeting Name:</td><td>";
+	char *field_maintitle="<tr><td>Title:</td><td>";
+	char *field_edition="<tr><td><Edition Information:</td><td>";
+	char *field_publication="<tr><td>Publication Info.:</td><td>";
+	char *field_physdesc="<tr><td>Physical Description:</td><td>";
+	char *field_series_title="<tr><td>Series Title:</td><td>";
+	char *field_series_statement="<tr><td>Series Statement:</td><td>";
+	char *field_note_general="<tr><td>Note:</td><td>";
+	char *field_note_bib="<tr><td>Bibliographic Note:</td><td>";
+	char *field_note_summary="<tr><td>Summary Note:</td><td>";
+	char *field_sub_note="<tr><td>Subject Notes:</td><td>";
+	char *field_sub_topic="<tr><td>Subject - Topic:</td><td>";
+	char *field_sub_geog="<tr><td>Subject - Location:</td><td>";
+	char *field_added_persname="<tr><td>Author Note - Name:</td><td>";
+	char *field_added_corpname="<tr><td>Author - Organisation:</td><td>";
+	char *field_uniform_title="<tr><td>Extra Title Information:</td><td>";
+	char *field_host_item="<tr><td>In:</td><td>";
+	char *field_series_corpname="<tr><td>Series - Organisation:</td><td>";
+	/*char *field_url="<tr><td>Electronic Access</td><td><a href=\"";*/
+	char *field_url="<tr><td>Electronic Access</td><td>";
+	/*char *field_other="<tr><td>(other field):</td><td>";*/
+	char tag_num[100];
+	switch (whichtag) {
+	case (1): {tagname=field_control1;break;}
+	case (3): {tagname=field_control3;break;}
+	case (5): {tagname=field_control5;break;}
+	case (8): {tagname=field_control8;break;}
+	case (10): {tagname=field_loc_nr;break;}
+	case (20): {tagname=field_issn;break;}
+	case (40): {tagname=field_catalog;break;}
+	case (41): {tagname=field_lang;break;}
+	case (43): {tagname=field_areacode;break;}
+	case (50): {tagname=field_cn_loc;break;}
+	case (82): {tagname=field_cn_dewdec;break;}
+	case (84): {tagname=field_cn_other;break;}
+	case (86): {tagname=field_cn_gd;break;}
+	case (100): {tagname=field_personalname;break;}
+	case (111): {tagname=field_meetingname;break;}
+	case (245): {tagname=field_maintitle;break;}
+	case (250): {tagname=field_edition;break;}
+	case (260): {tagname=field_publication;break;}
+	case (300): {tagname=field_physdesc;break;}
+	case (440): {tagname=field_series_title;break;}
+	case (490): {tagname=field_series_statement;break;}
+	case (500): {tagname=field_note_general;break;}
+	case (504): {tagname=field_note_bib;break;}
+	case (520): {tagname=field_note_summary;break;}
+	case (630): {tagname=field_sub_note;break;}
+	case (650): {tagname=field_sub_topic;break;}
+	case (651): {tagname=field_sub_geog;break;}
+	case (700): {tagname=field_added_persname;break;}
+	case (710): {tagname=field_added_corpname;break;}
+	case (730): {tagname=field_uniform_title;break;}
+	case (773): {tagname=field_host_item;break;}
+	case (810): {tagname=field_series_corpname;break;}
+	case (856): {tagname=field_url;break;}
+	default: 
+	  if (whichtag>=90&&whichtag<=99)
+	    tagname="<tr><td>Local Call #:</td><td>";
+	  else {
+	    /*tagname=field_other;*/
+	    
+	    /* The trailing '\0' seems to be necessary...?!? */
+	    sprintf(tag_num,"<tr><td>(field %d)</td><td>\n\0",whichtag);
+	    tagname=tag_num;
+	  }
+	}
+
+	/* add the field type */
+	title=safeappendstr(title, &title_maxlen, &title_curlen, tagname);
+      }
+
+      /* go through current field in current record */
+      while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset)
+	{
+	  /* this loop goes through byte by byte, to find end-of-field or
+	     end-of-record separator tags */
+
+	  /*	  if (memcmp (tag, "00", 2) && identifier_length)*/
+	  if ( ((titleonly==1&&whichtag==245)||(titleonly==0))
+	       && identifier_length)
+	    {
+	      if (buf[i]==ISO2709_IDFS) {
+		/*  this implies sub-fields for this field */
+		/* skip sub-field tag, but wrap $a sub-field with <b> & </b> 
+		   for HTML if titleonly==1 */
+		if (buf[i+1]=='a' && titleonly) {
+		  abbrtitle=1;
+		  title=safeappendstr(title,&title_maxlen,&title_curlen,"<b>");
+		}
+		i+=identifier_length; 
+	      }
+	      /* find end of this (sub-)field */
+	      startofstring=i;
+	      while (buf[i] != ISO2709_RS && buf[i] != ISO2709_IDFS &&
+		     buf[i] != ISO2709_FS && i < end_offset)
+		i++;
+		/*fprintf (outf, "%c", buf[i++]);*/
+
+	      /* this only happens the first time around */
+	      if (i==startofstring) continue;
+
+	      /* now put from $startofstring$ until $i$ into our 
+		 string to return */
+
+	      if (title_curlen+(i-startofstring)>=title_maxlen) {
+		/* we need to make more room - add max(64,needed) bytes */
+		if (title_curlen+(i-startofstring)-title_maxlen>63)
+		  title_maxlen+=(i-startofstring)+1;/*+1 for trailing \0 */
+		else
+		  title_maxlen+=64;
+		if ((title=realloc(title,title_maxlen))==NULL) {
+		  fprintf(stderr,"malloc failed decoding marc record\n");
+		  return (NULL);
+		}
+	      }
+
+	      strncpy(title+title_curlen,buf+startofstring,i-startofstring);
+	      title_curlen+=(i-startofstring);
+	      *(title+title_curlen)='\0';
+	      /* overwrite ISO2709_?S with \0 */
+	      /* *(title+title_curlen+i-startofstring)='\0';*/
+	      /*safeappendstr(title,&title_maxlen,
+		&title_curlen,buf+startofstring);*/
+
+	      /* if 'main' title, close HTML </B> tag */
+	      if (abbrtitle) {
+		title=safeappendstr(title,&title_maxlen,&title_curlen,"</b>");
+		abbrtitle=0;
+	      } 
+	      /* end of this marc sub--field                 
+		 buf[i]==ISO2709_RS if end of  record.
+		 buf[i]==ISO2709_FS if end of  field,
+		 buf[i]==ISO2709_IDFS if end of sub-field. */
+	      if (titleonly==0) {
+		if (buf[i]==ISO2709_IDFS) {
+		  /* there is a following sub-field, so only add whitespace */
+		  title=safeappendstr(title,&title_maxlen,&title_curlen," ");
+		}
+		else {
+		  /* end of record, so close HTML table row */
+#if 0
+		  if (whichtag==856) /* special case: this is a url! */
+		    title=safeappendstr(title,&title_maxlen,&title_curlen,
+					"\">Uniform Resource Locator</a>");
+#endif
+		  title=safeappendstr(title, &title_maxlen, &title_curlen,
+				      "</td></tr>\n");
+		}
+	      }  /* end of  if (titleonly==0)                */
+	    }    /* end of  if ( ((titleonly==1&&.......     */
+	  else { /* whichtag not matched  (if titleonly)     */
+	    /*fprintf (outf, "%c", buf[i++]);*/
+	    /* skip this char for now - should ideally skip whole field */
+	    i++;
+	  }
+	} /* end of while loop - at end of field or record */
+      /*fprintf (outf, "\n");*/
+      /*if (i < end_offset)
+	fprintf (outf, "-- separator but not at end of field\n");
+	if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
+	fprintf (outf, "-- no separator at end of field\n");
+      */
+    }
+
+  /* at end of whole record. */
+  if (!titleonly) 
+    title=safeappendstr(title, &title_maxlen, &title_curlen, "</table>\n");
+  return (title);
+
+}
+static char *getrecordtitle(Z_External *record) {
+  return(getmarcfields(record,1));
+}
+
+char *z_getfullRecord(int start) {
+  Z_APDU *apdu;
+  Z_External *record;
+  char *fullrecord;
+
+  fullrecord=NULL;
+  z_send_getbriefrecords(start,1,1); /* for now, use getbriefrecords */
+  z_getAPDU(&apdu);
+  
+  if (apdu->which != Z_APDU_presentResponse) {
+    /* out-of-order packets.... */
+    fprintf(stderr,"Not a present response to present request\n");
+    return NULL;
+  }
+  
+  /* just do some double checking */
+  if (*apdu->u.presentResponse->numberOfRecordsReturned!=1 ||
+      !apdu->u.presentResponse->records ) {
+    /* something bad has happened... johnmcp */
+    fprintf (stderr,"Error occured in yaz while getting record (GSDL)\n");
+  }
+
+  switch (apdu->u.presentResponse->records->which) {
+  case Z_Records_DBOSD: break; /* do nothing - this is a record */
+
+    /* otherwise we got a diagnostic message... */
+  case Z_Records_NSD:
+    switch (apdu->u.presentResponse->records->u.nonSurrogateDiagnostic->which){
+      /* these are both represented as char* in yaz, so either is OK */
+      /*    case Z_DefaultDiagForm_v2Addinfo:
+	    case Z_DefaultDiagForm_v3Addinfo: --wrong names*/
+    case Z_DiagnosticFormat_s_defaultDiagRec:
+    case Z_DiagnosticFormat_s_explicitDiagnostic:
+      return apdu->u.presentResponse->records->u.nonSurrogateDiagnostic
+	->u.v2Addinfo; /* return the error message */
+    default: ; /* this should happen for v3 of the spec... */
+    }
+  case Z_Records_multipleNSD: ; /* should handle one day... */
+  }
+
+  record=apdu->u.presentResponse->records->u.databaseOrSurDiagnostics->
+    records[0]->u.databaseRecord;
+
+  return(getmarcfields(record,0));
+}
+
+char **z_getrecordTitles(/*int resultset,*/ int starting, int howmany) {
+  Z_APDU *apdu;
+  char **titles;
+  /* titles will be an array of strings. The first element will really
+     be an int, saying how many strings follow. Ie 1st string in titles[1] */
+  int count;
+  int i;
+
+  titles=NULL;
+
+  /* WE SHOULD SET THE RECORD FORMAT SOMEWHERE..... USMARC (default)
+     but may also want SUTRS support. */
+
+  /* sends a presentRequest - we need to know the set number - johnmcp */
+  z_send_getbriefrecords(starting, 1, howmany);
+  /* CHECK RETURN VALUE (currently only 0) */
+  
+
+  z_getAPDU(&apdu);
+  if (apdu->which != Z_APDU_presentResponse) {
+    /* we got out-of-sync.... */
+    fprintf(stderr,"Not a present response to present request\n");
+    return NULL;
+  }
+  
+  print_refid (apdu->u.presentResponse->referenceId);
+  count=*apdu->u.presentResponse->numberOfRecordsReturned;
+  setno += count;
+  if (apdu->u.presentResponse->records) {
+    /* extract the titles from each record, and return it as an array of 
+       strings */
+    if (count==1 &&
+	apdu->u.presentResponse->records->which!=Z_Records_DBOSD) {
+	fprintf(stderr,"only one returned");
+      /* apdu->u.presentResponse->records->which gives a type:
+	 1=databaseOrSurDiagnostics | 2=nonSurrogateDiagnostic | 
+	 3=multipleNonSurDiagnostics.
+	 Type 1 implies it is a database record. FROM z-core.h,
+      NOT prt-proto.h!!!!! */
+
+      /* for type 2:
+	 apdu->u.presentResponse->records->u.nonSurrogateDiagnostic->which:
+	 1=v2Addinfo | 2=v3Addinfo, and u.v[23]Addinfo is a (char *).
+
+      */
+      titles=malloc(sizeof(char *));
+      titles[0]=(char *)0;
+      /* could put error message and titles[1], and set titles[0] to -1. */
+
+
+    }
+    else /* more than 1 rec returned, so ?has? to be db records (dblcheck!!)*/
+      {
+	  fprintf(stderr,"more than one rec returned, count=%d\n", count);
+	titles=malloc(sizeof(char *)*count + 1);
+	/* check malloc succeeded... */
+	titles[0]=(char *)count;
+	for (i=1;i<=count;i++) {
+	  titles[i]=getrecordtitle(apdu->u.presentResponse->records->
+				   u.databaseOrSurDiagnostics->records[i-1]->
+				   u.databaseRecord);
+	}
+      } 
+  }
+  else {
+      fprintf(stderr,"no records retruend");
+    titles=malloc(sizeof(char *));
+    titles[0]=(char *)0;
+  }
+  /*  printf ("nextResultSetPosition = %d\n",
+   *apdu->u.presentResponse->nextResultSetPosition); */
+  return (titles);
+}
+
Index: /gsdl/stable/runtime-src/src/z3950/yaz_zclient.h
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/yaz_zclient.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/yaz_zclient.h	(revision 20131)
@@ -0,0 +1,32 @@
+#ifndef YAZ_ZCLIENT_H
+#define YAZ_ZCLIENT_H
+/*#include "../include/yaz/z-core.h"*/
+
+
+/* the new yaz_zclient made for use with Greenstone. Based on client.c 
+ * (version 2.1.4) and the old yaz_zclient (version 1.6 for greenstone)
+ */
+void z_initialize(void);
+
+/* creates a connection, given a host and port, and database name */
+int z_cmd_open(char *host_and_port, char *base);
+
+/* returns number of records found */
+int z_cmd_dosearch(char *search);
+
+/* returns an array of strings containing record titles. The first element
+   is an int, saying how many titles follow (can be zero). NULL on error. */
+char **z_getrecordTitles(int start,int count);
+
+/* returns a string containing the whole marc record */
+char *z_getfullRecord(int record);
+
+/* close the connection */
+int z_cmd_close(const char *arg);
+
+/* returns a string containing name, ID, etc, or NULL if not connected */
+char *z_get_initResponse(); 
+
+/* gets a generic response from the server */
+int z_getnextAPDU ();
+#endif 
Index: /gsdl/stable/runtime-src/src/z3950/z3950_to_gsdl.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950_to_gsdl.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950_to_gsdl.cpp	(revision 20131)
@@ -0,0 +1,341 @@
+/**********************************************************************
+ *
+ * z3950_to_gsdl.cpp --
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "z3950parser.h"
+#include "z3950server.h"
+#include "z3950_to_gsdl.h"
+
+// converts a char* to uppercase, I wouldn't be
+// writing this if I could find an existing
+// function to do it
+void toUpperString(char *&text)
+{
+  for (int i = 0; text[i] != '\0'; i++) {
+    text[i] = toupper(text[i]);
+  }
+}
+
+
+text_t gsdlCollection::getName() 
+{
+  return name;
+}
+
+bool gsdlCollection::z3950Capeable() const
+{
+  return z3950ready;
+}
+
+
+bool gsdlCollection::bib1_to_dc_mapping(text_t& filename)
+{
+    ifstream inFile;
+    int input_Bib1;
+    text_t input_DCES;
+    text_t input_Short;
+
+    char* filename_cstr = filename.getcstr();
+    inFile.open(filename_cstr, ios::in);
+    delete [] filename_cstr;
+
+    if (!inFile) {
+      return false;
+    }
+
+    const int BUFFERSIZE = 1024;
+    char buffer[BUFFERSIZE];
+
+    // read in pairs of values (mappings from Bib-1 to DCES)
+    while (!inFile.eof()) {
+      char input_DCES_tmp[BUFFERSIZE];
+
+      inFile.getline(buffer, BUFFERSIZE, '\n');
+      if (buffer[0] == '#') {
+	// ignore comments (# ...)
+	continue;
+      }
+
+      sscanf(buffer,"%d %s",&input_Bib1, input_DCES_tmp);
+
+      input_DCES = input_DCES_tmp;
+
+      Bib1_to_DCES[input_Bib1] = input_DCES;
+
+      if (z3950_verbosity_>2) {
+	cerr << "(" << input_Bib1 << "/" << input_DCES << ") ";
+      }
+    }
+
+    if (z3950_verbosity_>2) {
+      cerr << endl;
+    }
+    inFile.close();
+
+    return true;
+}
+
+
+bool gsdlCollection::dc_to_short_mapping(text_t& filename, 
+					 text_t& collectionName) 
+{
+    ifstream inFileBuild;
+    text_t input_DCES;
+    text_t input_Short;
+  
+    char* filename_cstr = filename.getcstr();
+    inFileBuild.open(filename_cstr, ios::in);
+    delete [] filename_cstr;
+
+    if (!inFileBuild) {
+      if (z3950_verbosity_>2) {
+	cerr << "Warning: Unable to open: " << filename << endl;
+	cerr << "         Collection " << collectionName << " might not be built" << endl;
+      }
+      return false;
+    }
+
+    const int BUFFERSIZE = 1024;
+    char buffer[BUFFERSIZE];
+
+    // find the indexfieldmap line
+    do {
+      inFileBuild >> buffer;
+      if (inFileBuild.eof()) {
+	if (z3950_verbosity_>1) {
+	  cerr << "Warning: Did not find indexfieldmap in build.cfg for " 
+	       << collectionName << endl;
+	}
+	return false;
+      }
+    } while (strcmp(buffer, "indexfieldmap") != 0);
+
+    // at this stage, buffer contains "indexfieldmap",
+    // if the file didn't contain it, would have returned above
+    inFileBuild >> buffer;
+    while (strstr(buffer, "->") != NULL) {
+      // buffer contains a DCES->Short mapping
+      input_DCES.clear();
+      input_Short.clear();
+
+      // copy in DCES
+      int i;
+      for (i = 0; buffer[i] != '-'; i++) {
+	input_DCES.appendcarr(&(buffer[i]), 1);
+      }
+
+      // skip over "->"
+      i+=2;
+
+      // copy in Short
+      for (; isalpha(buffer[i]); i++) {
+	input_Short.appendcarr(&(buffer[i]), 1);
+      }
+
+      // add to map
+      DCES_to_Short[input_DCES] = input_Short;
+
+      if (z3950_verbosity_>1) {
+	cerr << "<" << input_DCES << "/" << input_Short << "> ";
+      }
+
+      inFileBuild >> buffer;
+    }
+
+    inFileBuild.close();
+
+    if (z3950_verbosity_>1) {
+      cerr << endl;
+    }
+
+    return true;
+}    
+
+
+
+
+  // converts a Bib1 field number to a short index name,
+  // returns true if a mapping existed, false otherwise
+bool gsdlCollection::getFieldArg(int Bib1, text_t &Short) 
+{
+    if (Bib1_to_DCES.count(Bib1) < 1) return false;
+    if (DCES_to_Short.count(Bib1_to_DCES[Bib1]) < 1) return false;
+    Short = DCES_to_Short[Bib1_to_DCES[Bib1]];
+    return true;
+}
+  
+gsdlCollection::~gsdlCollection(void) 
+{
+    //cerr << "gsdlCollection destructor called" << endl;
+}
+
+gsdlCollection::gsdlCollection(void) 
+{
+    //cerr << "gsdlCollection void constructor called" << endl;
+}
+ 
+gsdlCollection::gsdlCollection(text_t collectionName, text_t gsdlhome) 
+{
+
+    //char *filename_cstr;
+    //ifstream inFile;
+    //int inFileSize = 0;
+    z3950ready = true;
+
+    // int input_Bib1;
+    //text_t input_DCES;
+    //text_t input_Short;
+
+    name = collectionName;
+
+    // read in the cfg file for Bib1_to_DCES
+    text_t col_filename = gsdlhome;
+    col_filename = filename_cat(gsdlhome, "collect", collectionName, "etc", "bib1-mapping.txt"); 
+
+    if (!bib1_to_dc_mapping(col_filename)) {
+      text_t site_filename = filename_cat(gsdlhome, "etc", "packages", "z3950", "bib1-mapping.txt");
+
+      if (!bib1_to_dc_mapping(site_filename)) {
+	cerr << "Unable to find bib1 attribute mapping for " 
+	     << collectionName << endl;
+	cerr << "Looked for:\n  " << col_filename << "\n  " 
+	     << site_filename << endl;
+	z3950ready = false;
+	return;
+      }
+    }
+
+    // read in the cfg file for mapping Dublin Core to Short (internal name)
+    text_t build_filename = filename_cat(gsdlhome, "collect", collectionName, "index", "build.cfg");
+
+    if (!dc_to_short_mapping(build_filename,collectionName)) {
+      // explicitly check for error (in case in future more work is done after
+      // this
+      z3950ready = false;
+      return;
+    }
+
+}
+
+
+void z3950Server::openLogfile(text_t extension, ofstream &out)
+{
+    char *cfilename;
+    text_t filename;
+
+    filename = filename_cat(gsdlhome, extension);
+    cfilename = filename.getcstr();
+
+    out.open(cfilename);
+    delete cfilename;
+}
+
+z3950Server::z3950Server(nullproto *protocol, text_t home)
+{ 
+
+    text_t dirname;
+    char * cdirname;
+    if (home.empty()) {
+      cerr  << "Z3950Server Error: gsdlhome not set. \nPlease make sure"
+	    << " you have a valid gsdlsite.cfg file in the directory \n"
+	    << "you are running z3950server\n";
+      cerr << "Exiting..."<<endl;
+      exit(1);
+    } 
+    cerr << "Z3950Server: gsdlhome = " << home << endl;
+
+    this->gsdlhome = home;
+    //cerr << gsdlhome.getcstr() << endl;
+    dirname = filename_cat(gsdlhome, "collect");
+    cdirname = dirname.getcstr();
+    if (!read_dir (cdirname, collections)) { 
+      cerr << "Z3950Server Error: could not read directory "<<cdirname<<endl;
+      cerr << "Exiting..."<<endl;
+      exit (1);
+    }
+    delete cdirname;
+
+    cerr << "Constructing set list server" << endl;
+    this->protocol = protocol;
+
+    // initialise Yaz stuff for z39.50 server 
+}
+  
+bool z3950Server::initialise() 
+{
+      ofstream      logout;
+      int           reply;
+      comerror_t    error = noError;
+
+      // openLogfile does a filename_cat with this path, changing 
+      // the / appropriately.
+      this->openLogfile("/etc/packages/z3950/z3950out.txt", logout);
+      reply = protocol->init(error, logout);
+      logout.close();
+      return (reply != 0 ? 1 : 0);
+}
+
+void z3950Server::configure(const text_t &key, const text_tarray &cfgline, 
+			    comerror_t &err)
+{
+      err = noError;
+
+      // ****
+      cerr << "Recieved " << key << " = ";
+      for (int unsigned i=0; i<cfgline.size(); i++)
+	{
+	  cout << cfgline[i] << " ";
+	}
+      cout << endl;
+
+      // DB // ****
+      if (key=="gsdlhome")
+	{  
+	  text_tarray cfgline;
+	  cfgline.push_back (gsdlhome);
+	  cerr << "Changing gsdlhome to " << gsdlhome << endl;
+	  protocol->configure(key, cfgline, err);
+	}
+      else if (key=="httpdomain")
+	{
+	  // Only let gsdlhome through !!!! // ****
+	  cerr << "Supressing httpdomain" << endl;
+	}
+      else if (key=="httpprefix")
+	{
+	  cerr << "Supressing httpprefix" << endl;
+	}
+      else
+	{ 
+	  protocol->configure(key, cfgline,err);
+	}
+}
+
+int z3950Server::run_z3950( int argc, char **argv ) 
+{
+
+    const int statserv_var =  statserv_main(argc, argv, bend_init, bend_close);
+    cerr << "statserv_main returns: " << statserv_var << endl;
+    return statserv_var;
+}
Index: /gsdl/stable/runtime-src/src/z3950/z3950_to_gsdl.h
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950_to_gsdl.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950_to_gsdl.h	(revision 20131)
@@ -0,0 +1,87 @@
+/**********************************************************************
+ *
+ * z3950_to_gsdl.h --
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef Z3950_TO_GSDL_H
+#define Z3950_TO_GSDL_H
+
+
+void toUpperString(char *&text);
+
+class gsdlCollection
+{
+ public:
+  gsdlCollection(); 
+  gsdlCollection(text_t collectionName, text_t gsdlhome);
+  ~gsdlCollection(void);
+
+  bool z3950Capeable() const;
+
+  // converts a Bib1 field number to a short index name,
+  // returns true if a mapping existed, false otherwise
+  bool getFieldArg(int Bib1, text_t &Short);
+
+  text_t getName(); // returns the name of the collection in short form
+  
+ protected:
+
+
+  bool bib1_to_dc_mapping(text_t& filename);
+  bool dc_to_short_mapping(text_t& filename, text_t& collectionName);
+
+ protected:
+  text_t name;
+  map<int, text_t>    Bib1_to_DCES;  // Bib-1 to DC metadata names
+  map<text_t, text_t> DCES_to_Short; // DC to short (2-3 letter) internal name
+
+  bool z3950ready; // is the collection Z39.50-ready ?
+                   // (i.e. does it have the cfg files for mappings)
+
+
+};
+
+class z3950Server 
+{
+protected:
+  text_tarray collections;
+  nullproto *protocol;
+  text_t      gsdlhome;
+
+  // save particular YAZ variables ...
+
+  void openLogfile(text_t extension, ofstream &out);
+
+
+public:
+  z3950Server(nullproto *protocol, text_t home);
+  
+  bool initialise();
+
+  void configure(const text_t &key, const text_tarray &cfgline, comerror_t &err);
+
+  int run_z3950( int argc, char **argv );
+
+};
+
+#endif
Index: /gsdl/stable/runtime-src/src/z3950/z3950cfg.h
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950cfg.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950cfg.h	(revision 20131)
@@ -0,0 +1,47 @@
+/*
+  This defines a data structure shared between:
+  * the C++ z3950proto class defined in z3950proto.cpp, and
+  * the C function yyparse() created by bison from the file zparse.fl
+  */
+
+#ifndef _Z3950CFG_H
+#define _Z3950CFG_H
+
+#include <stdio.h> // for FILE* type
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct z3950aboutlist {
+  char *lang;
+  char *text;
+  struct z3950aboutlist *next;
+};
+struct z3950cfg {
+  char *shortname;
+  char *hostname;
+  int port;
+  char *dbname;
+  char *longname;
+  char *icon;
+  char *smallicon;
+  struct z3950aboutlist *about;
+  struct z3950cfg *next;
+};
+extern struct z3950cfg *zserver_list;
+extern FILE *errfile;
+
+/* can't use default yyparse(), as this name is used elsewhere (eg mg)*/
+#define yyin	zconfigin
+#define yyout	zconfigout
+#define yyparse	zconfigparse
+#define yylex	zconfiglex
+
+int yyparse ();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /gsdl/stable/runtime-src/src/z3950/z3950explain.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950explain.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950explain.cpp	(revision 20131)
@@ -0,0 +1,209 @@
+/**********************************************************************
+ *
+ * z3950explain.cpp --
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "z3950explain.h"
+
+void getExplainInfo(bend_search_rr *rr, FilterResponse_t &response, comerror_t &err)
+{
+  text_t GSQuery = ZQueryToGSQuery(rr);
+  char *GSQuery_char = GSQuery.getcstr(); 
+
+  int i;
+  if (strstr(GSQuery_char, "TargetInfo") != NULL) {
+    // should be one only
+    // real-life example:
+    /*
+      62
+      explain-category targetInfo
+      date-of-info Sep 22, 1999
+      language eng
+    */
+    ResultDocInfo_t docinfo;
+    docinfo.metadata["explain-category"].values.push_back("TargetInfo");
+    docinfo.metadata["name"].values.push_back("Greenstone");
+    docinfo.metadata["namedResultSets"].values.push_back("false");
+    docinfo.metadata["multipleDBsearch"].values.push_back("true");
+    docinfo.metadata["language"].values.push_back("eng");
+    response.docInfo.push_back(docinfo);
+    response.numDocs++;
+  }
+  if (strstr(GSQuery_char, "DatabaseInfo") != NULL) {
+    // should be one per collection
+    // real-life example:
+    /*
+      3
+      dbnum 0
+      explain-category DatabaseInfo
+      database-name.1 0
+      title Z39.50 EXPLAIN DB
+      database-name.2 ir-explain-1
+      date-of-info Sep 22, 1999
+      language eng
+      dbpath /usr/wald/z39.50root/explain
+      dbname explain
+    */
+    ResultDocInfo_t docinfo;
+    docinfo.metadata["explain-category"].values.push_back("DatabaseInfo");
+    docinfo.metadata["database-name"].values.push_back("IR-Explain-1");
+    docinfo.metadata["title"].values.push_back("Z39.50 EXPLAIN DB");
+    docinfo.metadata["language"].values.push_back("eng");
+    docinfo.metadata["dbname"].values.push_back("explain");
+    response.docInfo.push_back(docinfo);
+    response.numDocs++;
+    // now get the info for each collection
+    text_tarray collectlist;
+    Protocol->get_collection_list(collectlist, err, cerr);
+    text_tarray::iterator COLHERE = collectlist.begin();
+    text_tarray::iterator COLEND = collectlist.end();
+    while (COLHERE != COLEND) {
+      // don't include information for non-active collections
+      bool collection_active;
+      Protocol->ping(*COLHERE, collection_active, err, cerr);
+      if (collection_active != true) {
+	COLHERE++;
+	continue;
+      }
+      ColInfoResponse_t collectinfo;
+      Protocol->get_collectinfo(*COLHERE, collectinfo, err, cerr);
+      docinfo.clear();
+      docinfo.metadata["name"].values.push_back(collectinfo.shortInfo.name);
+      docinfo.metadata["host"].values.push_back(collectinfo.shortInfo.host);
+      if (collectinfo.isPublic) {
+	docinfo.metadata["isPublic"].values.push_back("true");
+      } else {
+	docinfo.metadata["isPublic"].values.push_back("false");
+      }
+      if (collectinfo.isBeta) {
+	docinfo.metadata["isBeta"].values.push_back("true");
+      } else {
+	docinfo.metadata["isBeta"].values.push_back("false");
+      }
+      if (collectinfo.useBook == true) {
+	docinfo.metadata["useBook"].values.push_back("true");
+      } else {
+	docinfo.metadata["useBook"].values.push_back("false");
+      }
+      docinfo.metadata["buildDate"].values.push_back(collectinfo.buildDate);
+      text_tarray::iterator TEXTT_HERE = collectinfo.ccsCols.begin();
+      text_tarray::iterator TEXTT_END = collectinfo.ccsCols.end();
+      for (i = 1; TEXTT_HERE != TEXTT_END; i++, TEXTT_HERE++) {
+	text_t tmp = "ccsCols.";
+	tmp.appendint(i);
+	docinfo.metadata[tmp].values.push_back(*TEXTT_HERE);
+      }
+      TEXTT_HERE = collectinfo.languages.begin();
+      TEXTT_END = collectinfo.languages.end();
+      for (i = 1; TEXTT_HERE != TEXTT_END; i++, TEXTT_HERE++) {
+	text_t tmp = "languages.";
+	tmp.appendint(i);
+	docinfo.metadata[tmp].values.push_back(*TEXTT_HERE);
+      }
+      docinfo.metadata["numDocs"].values.push_back(collectinfo.numDocs);
+      docinfo.metadata["numSections"].values.push_back(collectinfo.numSections);
+      docinfo.metadata["numWords"].values.push_back(collectinfo.numWords);
+      docinfo.metadata["numBytes"].values.push_back(collectinfo.numBytes);
+
+      collectionmeta_map::iterator COLLMETA_MAP_HERE = collectinfo.collectionmeta.begin();
+      collectionmeta_map::iterator COLLMETA_MAP_END = collectinfo.collectionmeta.end();
+      for (i = 1; COLLMETA_MAP_HERE != COLLMETA_MAP_END; i++, COLLMETA_MAP_HERE++) {
+	text_t tmp = "collectionmeta.";
+	tmp.appendint(i);
+	text_t tmp2 = COLLMETA_MAP_HERE->first;
+	tmp2.appendcstr(" -> ");
+	tmp2.append(COLLMETA_MAP_HERE->second[g_EmptyText]);
+	docinfo.metadata[tmp].values.push_back(tmp2);
+      }
+      text_tmap::iterator TEXTT_MAP_HERE;
+      text_tmap::iterator TEXTT_MAP_END;
+      // uncomment if you want to include this in the explain record,
+      // it's a bit messy to include by default
+      /*
+      TEXTT_MAP_HERE = collectinfo.format.begin();
+      TEXTT_MAP_END = collectinfo.format.end();
+      for (i = 1; TEXTT_MAP_HERE != TEXTT_MAP_END; i++, TEXTT_MAP_HERE++) {
+	text_t tmp = "format.";
+	tmp.appendint(i);
+	text_t tmp2 = TEXTT_MAP_HERE->first;
+	tmp2.appendcstr(" -> ");
+	tmp2.append(TEXTT_MAP_HERE->second);
+	docinfo.metadata[tmp].values.push_back(tmp2);
+      }
+      */
+      TEXTT_MAP_HERE = collectinfo.building.begin();
+      TEXTT_MAP_END = collectinfo.building.end();
+      for (i = 1; TEXTT_MAP_HERE != TEXTT_MAP_END; i++, TEXTT_MAP_HERE++) {
+	text_t tmp = "building.";
+	tmp.appendint(i);
+	text_t tmp2 = TEXTT_MAP_HERE->first;
+	tmp2.appendcstr(" -> ");
+	tmp2.append(TEXTT_MAP_HERE->second);
+	docinfo.metadata[tmp].values.push_back(tmp2);
+      }
+      docinfo.metadata["receptionist"].values.push_back(collectinfo.receptionist);
+      docinfo.metadata["buildType"].values.push_back(collectinfo.buildType);
+      response.docInfo.push_back(docinfo);
+      response.numDocs++;
+      COLHERE++;
+    }
+  }
+  if (strstr(GSQuery_char, "SchemaInfo") != NULL) {
+    // should be one per collection
+    // real-life example:
+    /*
+      10
+      dbnum 1
+      explain-category schemaInfo
+      database-name.1 1
+      database-name.2 books
+      database-name.3 default
+      database-name.4 cat
+      date-of-info Sep 22, 1999
+      language eng
+      schema.1 1.2.840.10003.13.1000.3.1
+      dbpath /usr/wald/z39.50root/books
+      dbname books
+     */
+  }
+  if (strstr(GSQuery_char, "AttributeSetInfo") != NULL) {
+    // should be one per collection
+    // real-life example:
+    /*
+      9
+      dbnum 1
+      explain-category AttributeSetInfo
+      database-name.1 1
+      database-name.2 books
+      database-name.3 default
+      database-name.4 cat
+      date-of-info Sep 22, 1999
+      language eng
+      attribute-set.1 1.2.840.10003.13.1000.3.1
+      dbpath /usr/wald/z39.50root/books
+      dbname books
+    */
+  }
+}
+
+
Index: /gsdl/stable/runtime-src/src/z3950/z3950explain.h
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950explain.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950explain.h	(revision 20131)
@@ -0,0 +1,35 @@
+/**********************************************************************
+ *
+ * z3950proto.h --
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef Z3950EXPLAIN_H
+#define Z3950EXPLAIN_H
+
+
+#include "z3950parser.h"
+
+void getExplainInfo(bend_search_rr *rr, FilterResponse_t &response, comerror_t &err);
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/z3950/z3950parser.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950parser.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950parser.cpp	(revision 20131)
@@ -0,0 +1,371 @@
+
+#include "z3950parser.h"
+
+void Z_AttributeList_parse(bend_search_rr *rr, Z_AttributeList *Z, text_t &GSQuery)
+{
+  /*
+    struct Z_AttributeList {
+    int num_attributes;
+    Z_AttributeElement **attributes;
+    };
+  */
+
+  /*
+    struct Z_AttributeElement {
+    Z_AttributeSetId *attributeSet; // OPT
+    int *attributeType;
+    int which;
+    union {
+    int *numeric;
+    Z_ComplexAttribute *complex;
+    #define Z_AttributeValue_numeric 1
+    #define Z_AttributeValue_complex 2
+    } value;
+    };
+  */
+
+  
+
+}
+
+void Z_Term_parse(bend_search_rr *rr, Z_Term *Z, text_t &GSQuery)
+{
+  /*
+    struct Z_Term {
+    int which;
+    union {
+    Odr_oct *general;
+    int *numeric;
+    Z_InternationalString *characterString;
+    Odr_oid *oid;
+    char *dateTime;
+    Z_External *external;
+    Z_IntUnit *integerAndUnit;
+    Odr_null *null;
+    #define Z_Term_general 1
+    #define Z_Term_numeric 2
+    #define Z_Term_characterString 3
+    #define Z_Term_oid 4
+    #define Z_Term_dateTime 5
+    #define Z_Term_external 6
+    #define Z_Term_integerAndUnit 7
+    #define Z_Term_null 8
+    } u;
+    };
+  */
+
+  char *term;
+
+  switch(Z->which){
+  case Z_Term_general: {
+    // must copy no more than len bytes from buf, or else previous query terms may be included
+    int buflen = Z->u.general->len;
+    term = new char[buflen+1];
+    memset(term, '\0', buflen+1);
+    strncpy(term, (const char*)(Z->u.general->buf), buflen);
+    GSQuery += term;
+    break; }
+  case Z_Term_numeric:
+    GSQuery += *(Z->u.numeric); // int*
+    break;
+  case Z_Term_characterString:
+    GSQuery += Z->u.characterString; // what is this type?
+    break;
+  case Z_Term_oid:
+    GSQuery += *(Z->u.oid); // int*
+    break;
+  case Z_Term_dateTime:
+    GSQuery += Z->u.dateTime; // char*
+    break;
+  case Z_Term_external:
+    GSQuery += " "; // ignore this for now
+    break;
+  case Z_Term_integerAndUnit:
+    GSQuery += " "; // ignore this for now
+    break;
+  case Z_Term_null:
+    GSQuery += " "; // void
+    break;
+  default:
+    cerr << "Error in Z_Term_parse" << endl;
+    exit(1);
+  }
+}
+
+void Z_ProximityOperator_parse(bend_search_rr *rr, Z_ProximityOperator *Z, text_t &GSQuery)
+{
+  /*
+    struct Z_ProximityOperator {
+    bool_t *exclusion; // OPT
+    int *distance;
+    bool_t *ordered;
+    #define Z_ProximityOperator_Prox_lessThan 1
+    #define Z_ProximityOperator_Prox_lessThanOrEqual 2
+    #define Z_ProximityOperator_Prox_equal 3
+    #define Z_ProximityOperator_Prox_greaterThanOrEqual 4
+    #define Z_ProximityOperator_Prox_greaterThan 5
+    #define Z_ProximityOperator_Prox_notEqual 6
+    int *relationType;
+    int which;
+    union {
+    Z_ProxUnit *known;
+    int *zprivate;
+    #define Z_ProximityOperator_known 1
+    #define Z_ProximityOperator_private 2
+    } u;
+    };
+    
+    #define Z_ProxUnit_character 1
+    #define Z_ProxUnit_word 2
+    #define Z_ProxUnit_sentence 3
+    #define Z_ProxUnit_paragraph 4
+    #define Z_ProxUnit_section 5
+    #define Z_ProxUnit_chapter 6
+    #define Z_ProxUnit_document 7
+    #define Z_ProxUnit_element 8
+    #define Z_ProxUnit_subelement 9
+    #define Z_ProxUnit_elementType 10
+    #define Z_ProxUnit_byte 11
+  */
+
+  // Greenstone (actually mgpp) supports proximity, but only 
+  // to n words either side.
+  // A more complete implementation of proximity can be added
+  // by parsing the other fields in Z_ProximityOperator.
+  // Note: this only works properly with MGPP collections
+  
+  GSQuery += " NEAR"; 
+  GSQuery += *(Z->distance);
+  GSQuery += " ";
+}
+
+void Z_Operator_parse(bend_search_rr *rr, Z_Operator *Z, text_t &GSQuery)
+{
+  /*
+    struct Z_Operator {
+    int which;
+    union {
+    Odr_null *and;
+    Odr_null *or;
+    Odr_null *and_not;
+    Z_ProximityOperator *prox;
+    #define Z_Operator_and 1
+    #define Z_Operator_or 2
+    #define Z_Operator_and_not 3
+    #define Z_Operator_prox 4
+    } u;
+    };
+  */
+  
+  switch(Z->which){
+  case Z_Operator_and:
+    GSQuery += " & ";
+    break;
+  case Z_Operator_or:
+    GSQuery += " | ";
+    break;
+  case Z_Operator_and_not:
+    GSQuery += " ! ";
+    break;
+  case Z_Operator_prox:
+    Z_ProximityOperator_parse(rr, Z->u.prox, GSQuery);
+    break;
+  default:
+    cerr << "Error in Z_Operator_parse" << endl;
+    exit(1);
+  }
+}
+
+void Z_Operand_parse(bend_search_rr *rr, Z_Operand *Z, text_t &GSQuery)
+{
+    /*
+      struct Z_Operand {
+      int which;
+      union {
+      Z_AttributesPlusTerm *attributesPlusTerm;
+      Z_ResultSetId *resultSetId;
+      Z_ResultSetPlusAttributes *resultAttr;
+      #define Z_Operand_APT 1
+      #define Z_Operand_resultSetId 2
+      #define Z_Operand_resultAttr 3
+      } u;
+      };
+    */
+  
+  switch(Z->which) {
+  case Z_Operand_APT: {
+    /*
+      struct Z_AttributesPlusTerm {
+      Z_AttributeList *attributes;
+      Z_Term *term;
+      };
+    */
+    
+    /*
+      struct Z_AttributeList {
+      int num_attributes;
+      Z_AttributeElement **attributes;
+      };
+    */
+    
+    /*
+      struct Z_AttributeElement {
+      Z_AttributeSetId *attributeSet; // OPT
+      int *attributeType;
+      int which;
+      union {
+      int *numeric;
+      Z_ComplexAttribute *complex;
+      #define Z_AttributeValue_numeric 1
+      #define Z_AttributeValue_complex 2
+      } value;
+      };
+    */
+    
+    char *term;
+    
+    if (Z->u.attributesPlusTerm->attributes->num_attributes > 0) {
+      int Bib1_relation = *(Z->u.attributesPlusTerm->attributes->attributes[0]->attributeType);
+      int Bib1_use = *(Z->u.attributesPlusTerm->attributes->attributes[0]->value.numeric);
+
+      // if use value is 1010 ("Body of text"), is not a fielded search
+      if (Bib1_use == 1010) {
+	// if relation value is 6 ("not"), add a "not" to GSQuery
+	if (Bib1_relation == 6) {
+	  GSQuery += "! ";
+	}
+	Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
+      }
+      // for other use values, is a fielded search
+      else {
+	text_t Short;
+	// only add [ ]: if the index exists in the collection,
+	// note: only the index names in the first collection of a
+	// multi-collection search are used at the moment
+	if ((Collection_map[rr->basenames[0]]).getFieldArg(Bib1_use, Short)) {
+	  GSQuery += "[";
+	  Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
+	  GSQuery += "]";
+	  GSQuery += ":";
+	  GSQuery += Short;
+	}
+	// if it doesn't, add it as an unfielded search term
+	else {
+	  cerr << "[" << rr->basenames[0] << "]: failed to find field index for " <<Bib1_use<<", adding term unfielded" << endl;
+	  Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
+	}
+      }
+    }
+    else {
+      Z_Term_parse(rr, Z->u.attributesPlusTerm->term, GSQuery);
+    }
+    break;
+  }
+  case Z_Operand_resultSetId: {
+    GSQuery += "(";
+    GSQuery += Resultsets[Z->u.resultSetId];
+    GSQuery += ")";
+    break; 
+  }
+  case Z_Operand_resultAttr:
+    GSQuery += " "; // ignore this for now
+    break;
+  default:
+    cerr << "Error in Z_Operand_parse" << endl;
+    exit(1);
+  } 
+}
+
+void Z_RPNStructure_parse(bend_search_rr *rr, Z_RPNStructure *Z, text_t &GSQuery)
+{
+  /*
+    struct Z_RPNStructure {
+    int which;
+    union {
+    Z_Operand *simple;
+    Z_Complex *complex;
+    #define Z_RPNStructure_simple 1
+    #define Z_RPNStructure_complex 2
+    } u;
+    };
+  */
+
+  switch(Z->which){
+  case Z_RPNStructure_simple:
+    Z_Operand_parse(rr, Z->u.simple, GSQuery);
+    break;
+  case Z_RPNStructure_complex:
+    GSQuery += "(";
+    Z_RPNStructure_parse(rr, Z->u.complex->s1, GSQuery);
+    Z_Operator_parse(rr, Z->u.complex->roperator, GSQuery);
+    Z_RPNStructure_parse(rr, Z->u.complex->s2, GSQuery);
+    GSQuery += ")";
+    break;
+  default:
+    cerr << "Error in Z_RPNStructure_parse" << endl;
+    exit(1);
+  }
+}
+
+text_t ZQueryToGSQuery(bend_search_rr *rr)
+{
+  text_t GSQuery;
+
+  switch(rr->query->which){
+  case Z_Query_type_0:
+    cerr << "querytype = 0" << endl;
+    // this is a void*, pretend it's a Greenstone-type query
+    GSQuery += (char*)(rr->query->u.type_0);
+    break;
+  case Z_Query_type_1: {
+    cerr << "querytype = 1" << endl;
+    /*
+      struct Z_RPNQuery {
+      Z_AttributeSetId *attributeSetId;
+      Z_RPNStructure *RPNStructure;
+      };
+    */
+    // parse attributeSetId
+    cerr << "attributeSetId = ";
+    int c, d = 0;
+    do {
+      c = rr->query->u.type_1->attributeSetId[d];
+      cerr << c;
+      d++;
+    } while (c >= 0);
+    cerr << endl;
+
+    Z_RPNStructure_parse(rr, rr->query->u.type_1->RPNStructure, GSQuery);
+    break; }
+  case Z_Query_type_2: {
+    cerr << "querytype = 2" << endl;
+    // this is just a buf (unsigned char*), pretend it's a Greenstone-type query
+    GSQuery += (char*)(rr->query->u.type_2->buf);
+    break; }
+  case Z_Query_type_100: {
+    cerr << "querytype = 100" << endl;
+     // this is just a buf (unsigned char*), pretend it's a Greenstone-type query
+    GSQuery += (char*)(rr->query->u.type_100->buf);
+    break; }
+  case Z_Query_type_101: {
+    cerr << "querytype = 101" << endl;
+    // check: is this really the same as a type 1 query?
+    Z_RPNStructure_parse(rr, rr->query->u.type_101->RPNStructure, GSQuery);
+    break; }
+  case Z_Query_type_102: {
+    cerr << "querytype = 102" << endl;
+     // this is just a buf (unsigned char*), pretend it's a Greenstone-type query
+    GSQuery += (char*)(rr->query->u.type_102->buf);
+    break; }
+  default: {
+    cerr << "Error in ZQueryToGSQuery" << endl;
+    exit(1); }
+  }
+
+  // override GSQuery (test code)
+  //GSQuery = "[the]:TX";
+
+  cerr << "GSQuery = `" << GSQuery << "'" << endl;
+  return GSQuery;
+}
+
Index: /gsdl/stable/runtime-src/src/z3950/z3950parser.h
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950parser.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950parser.h	(revision 20131)
@@ -0,0 +1,77 @@
+/**********************************************************************
+ *
+ * z3950parser.h -- convert Z39.50's RPN query syntax into Greenstone
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef Z3950PARSER_H
+#define Z3950PARSER_H
+
+
+#include <string>
+#include <list>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <time.h>
+
+// Greenstone headers
+#include "fileutil.h"
+#include "comtypes.h"
+#include "nullproto.h"
+#include "z3950_to_gsdl.h"
+
+// YAZ headers
+extern "C" {
+#include <yaz/backend.h>
+#include <yaz/log.h>
+#ifdef ASN_COMPILED
+#include <yaz/ill.h>
+#endif
+}
+
+extern text_t gsdlhome;
+extern list<FilterResponse_t> Response_tlist;
+extern list<text_t> Response_tlist_colnames;
+extern list<int> Response_tlist_sizes;
+extern z3950Server *Server;
+extern collectset *Cservers;
+extern nullproto *Protocol;
+extern map<text_t, gsdlCollection> Collection_map;
+extern map<text_t, text_t> Resultsets;
+
+void Z_AttributeList_parse(bend_search_rr *rr, Z_AttributeList *Z, text_t &GSQuery);
+
+void Z_Term_parse(bend_search_rr *rr, Z_Term *Z, text_t &GSQuery);
+
+void Z_ProximityOperator_parse(bend_search_rr *rr, Z_ProximityOperator *Z, text_t &GSQuery);
+
+void Z_Operator_parse(bend_search_rr *rr, Z_Operator *Z, text_t &GSQuery);
+
+void Z_Operand_parse(bend_search_rr *rr, Z_Operand *Z, text_t &GSQuery);
+
+void Z_RPNStructure_parse(bend_search_rr *rr, Z_RPNStructure *Z, text_t &GSQuery);
+
+text_t ZQueryToGSQuery(bend_search_rr *rr);
+
+#endif
Index: /gsdl/stable/runtime-src/src/z3950/z3950proto.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950proto.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950proto.cpp	(revision 20131)
@@ -0,0 +1,612 @@
+/**********************************************************************
+ *
+ * z3950proto.cpp --
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "z3950proto.h"
+#include "comtypes.h"
+#include "browsefilter.h"
+#include "queryfilter.h"
+#include "filter.h"
+// z39.50 yaz stuff
+
+#include "z3950cfg.h" // for reading in config files - 
+// defines "struct z3950cfg *zserver_list" as the head of the list.
+
+// note! yyin is hash-defined in z3950cfg.h to something else, to avoid
+// name conflicts with "other" yyins.
+extern FILE *yyin;
+extern FILE *yyout; // redirect for `errors' (unmatched tokens in flex)
+
+
+
+z3950proto::z3950proto() {
+  zserver_count=0;
+}
+
+z3950proto::~z3950proto() {
+}
+
+void z3950proto::add_server (z3950_proxy& zserver) {
+
+  // append the new server
+  ++zserver_count;
+  zservers.push_back(&zserver);
+}
+
+void z3950proto::read_config_file(const text_t &filename, const text_t &errf) {
+  struct z3950cfg *here;
+  struct z3950cfg *oldhere;
+  z3950_proxy *zserver;
+  ShortColInfo_t *tempinfo;
+
+  //  FILE *errfile declared in z3950cfg.h, defined in zparse.y
+
+  char *errf_str=errf.getcstr();
+  if ((errfile=fopen(errf_str,"a"))==NULL) {
+    // what do we do if we can't open the error file?
+    // this means that errors will go to stderr, which may stuff up 
+    // any cgi headers and the page.
+    errfile=stderr;
+  }
+  delete []errf_str;
+  yyout=errfile;
+
+  
+  char *filename_str=filename.getcstr();
+  yyin=fopen(filename_str,"r");
+  if (yyin==NULL) {
+    cerr << "Could not open "<<filename_str<<" for reading.\n";
+    delete []filename_str;
+    return;
+  }
+  delete []filename_str;
+
+  // this is in zparse.tab.c,
+  // which is the bison output of zparse.y
+  yyparse();
+
+  if (errfile!=stderr)
+    fclose(errfile);
+
+  // we now have the config files in the ptr zserver_list
+  if (zserver_list==NULL)
+    return; // no valid servers found in the config file - note that
+  // the parser will have already spat out any errors.
+
+  // now create z3950 proxies for each structure in server_list
+  here=zserver_list;
+  while (here!=NULL) {
+    zserver=new z3950_proxy;
+    tempinfo=new ShortColInfo_t;
+
+    tempinfo->host.setcstr(here->hostname);
+    tempinfo->port=here->port;
+    tempinfo->name.setcstr(here->dbname);
+    zserver->setInfo(tempinfo);
+    zserver->setName(here->shortname);
+    // now collection metadata.
+    zserver->setMeta("collectionname",here->longname);
+    if (here->icon!=NULL)
+      zserver->setMeta("iconcollection",here->icon);
+    if (here->smallicon!=NULL)
+      zserver->setMeta("iconcollectionsmall",here->smallicon);
+    
+    /*    filterclass *filter = new filterclass ();
+	  zserver->add_filter (filter);
+	  browsefilterclass *browsefilter = new browsefilterclass();
+	  zserver->add_filter (browsefilter);
+	  queryfilterclass *queryfilter = new queryfilterclass();
+	  zserver->add_filter (queryfilter);
+    */
+
+    // About list
+    if (here->about!=NULL) {
+      struct z3950aboutlist *about_here=here->about;
+      struct z3950aboutlist *oldabout;
+
+      while (about_here!=NULL) {
+	// problem with default lang (null): can't add ("",..)
+	if (about_here->lang==NULL)
+	  zserver->addcfgAbout("en",about_here->text);
+	else
+	  zserver->addcfgAbout(about_here->lang, about_here->text);
+	oldabout=about_here;
+	about_here=about_here->next;
+	free(oldabout->lang);
+	free(oldabout->text);
+	free(oldabout);
+      }
+    }
+
+    oldhere=here;
+    here=here->next;
+    free(oldhere->shortname); // these 4 strings should all be non-NULL...
+    free(oldhere->hostname);
+    free(oldhere->dbname);
+    free(oldhere->longname);
+    if (oldhere->icon) free(oldhere->icon);     // these 2 may be NULL
+    if (oldhere->smallicon) free(oldhere->smallicon);
+    free(oldhere);
+
+    add_server(*zserver);
+  } // end of while loop.
+
+}
+
+void z3950proto::configure (const text_t &/*key*/,
+			    const text_tarray &/*cfgline*/) {
+  // this is called for each line in the gsdlsite.cfg file
+}
+
+
+bool z3950proto::init (ostream &/*logout*/) {
+  // set up tcp connection to server here?
+  // we might also read in the config file here (instead of librarymain.cpp)
+
+  // 
+
+  // logout goes to initout.txt
+  //  logout <<"zdebug:init:Number of z3950 servers: "<< zserver_count << "\n";
+  //logout << "\t1st server name: " << zservers[0].getName().getcstr() << "\n";
+  return true;
+
+}
+
+/*text_t z3950proto::get_protocol_name () {
+  return "z3950proto";
+}
+*/
+
+void z3950proto::get_collection_list (text_tarray &collist, 
+				      comerror_t &/*err*/,
+				      ostream &/*logout*/) {
+
+  z3950_proxy_array::iterator here = zservers.begin();
+  z3950_proxy_array::iterator end = zservers.end();
+  while (here != end) {
+    collist.push_back((*here)->getName());
+    ++here;
+  }
+}
+
+void z3950proto::has_collection (const text_t &collection, bool &hascollection,
+				 comerror_t &/*err*/, ostream &/*logout*/) {
+  z3950_proxy_array::iterator here = zservers.begin();
+  z3950_proxy_array::iterator end = zservers.end();
+  while (here != end) {
+    if((*here)->getName()==collection) {
+      hascollection=true;
+      return;
+    }
+    ++here;
+  }
+  hascollection=false;
+}
+
+void z3950proto::ping (const text_t &/*collection*/, bool &wassuccess, 
+		       comerror_t &/*err*/, ostream &/*logout*/) {
+  // should we just ping the server, or actually create a connection
+  // to the z39.50 server process on the machine ?
+  wassuccess = true;
+}
+
+void z3950proto::get_collectinfo (const text_t &collection,
+				  ColInfoResponse_t &collectinfo,
+				  comerror_t &err, ostream &logout) {
+
+  // set err to protocolError if something goes wrong...
+  err=noError;
+
+  z3950_proxy_array::iterator here = zservers.begin();
+  z3950_proxy_array::iterator end = zservers.end();
+  while (here != end) {
+    if((*here)->getName()==collection) {
+      break;
+    }
+    ++here;
+  }
+
+  if (here==end) {
+    err=protocolError;
+    char *coll_str=collection.getcstr();
+    logout << "z39.50: couldn't find collection" 
+	   << coll_str
+	   << endl;
+    delete []coll_str;
+    return;
+  }
+
+  const ShortColInfo_t *colinfo=(*here)->getInfo();
+  collectinfo.shortInfo.name=colinfo->name;
+  collectinfo.shortInfo.host=colinfo->host;
+  collectinfo.shortInfo.port=colinfo->port;
+
+  collectinfo.isPublic=true;
+  // don't use beta field
+  /*collectinfo.isBeta=false;*/
+  collectinfo.useBook=false;
+  collectinfo.buildDate=1;
+  // leave ccsCols empty (no cross-coll. searching - for now)
+  /*collectinfo.ccsCols=(text_tarray);*/ //not like this!!!
+  // This info is available from the config file -- johnmcp
+  /*******collectinfo.languages.push_back("en");
+	  collectinfo.languages.push_back("fr");********/
+  collectinfo.numDocs=0;
+  collectinfo.numWords=0;
+  collectinfo.numBytes=0;
+  // copy the text maps over.
+  //  collectinfo.collectionmeta; // text_tmap
+  text_tmap collmeta = *((*here)->getMeta());
+  text_tmap::iterator mhere = collmeta.begin();
+  text_tmap::iterator mend = collmeta.end();
+  while (mhere != mend) {
+    collectinfo.collectionmeta[(*mhere).first][g_EmptyText] = (*mhere).second;
+    mhere ++;
+  }
+  //collectinfo.collectionmeta=*((*here)->getMeta());
+  collectinfo.format=*((*here)->getFormat()); //text_tmap
+  /*    collectinfo.building; //text_tmap  */
+
+  ////collectinfo.receptionist="z3950"; 
+  /* for now... this is a url,  relative to .../cgi-bin.
+     NOTE: if this is empty, it defaults to _gwcgi_?a=p&p=about&c=<colname>
+  */
+}
+
+void z3950proto::get_filterinfo (const text_t &/*collection*/,
+				 InfoFiltersResponse_t &response,
+				 comerror_t &/*err*/, ostream &/*logout*/) {
+  // we'll fake it here, and say we have set up some filters
+  response.filterNames.insert("BrowseFilter");
+  response.filterNames.insert("QueryFilter");
+  response.filterNames.insert("NullFilter");
+
+}
+
+void z3950proto::get_filteroptions (const text_t &/*collection*/,
+				    const InfoFilterOptionsRequest_t &/*req*/,
+				    InfoFilterOptionsResponse_t &response, 
+				    comerror_t &err, ostream &/*logout*/) {
+  // for now, assume all servers have the same characteristics
+  /*  if (request.filterName=="QueryFilter") { } 
+      else if (request.filterName=="BrowseFilter") { } 
+      else if (request.filterName=="NullFilter") {  } */
+  response.filterOptions["Index"].type=FilterOption_t::stringt;
+  response.filterOptions["Index"].repeatable=FilterOption_t::onePerQuery;
+  response.filterOptions["Index"].defaultValue="any";
+  response.filterOptions["Index"].validValues.push_back(".any");
+  response.filterOptions["Index"].validValues.push_back(".title");
+  response.filterOptions["Index"].validValues.push_back(".author");
+  // and maybe ["Language"] option as well?
+  err=noError;
+}
+
+void z3950proto::filter (const text_t &collection,
+			 FilterRequest_t &request,
+			 FilterResponse_t &response,
+			 comerror_t &err, ostream &logout) {
+  // this function is called when:
+  //  *  creating the title page,(looking for iconcoll* & collectname metadata)
+  //  *  creating the about page (looking for "Title" metadata)
+  //  * doing the query - (note that a request for metadata comes first, then
+  // filterOptions = FRmetadata | FROID | FRtermFreq (64+4+1)
+
+  // metadata-only requests have filterName="NullFilter", else "QueryFilter".
+  // For the title page, we should not create a connection to the target
+  // (target means the actual z39.50 server, origin means us), but
+  // for the about page and query pages, we need to get information from the
+  // origin. (eg for the about page, we will print out some info such as ID,
+  // name and version.
+
+  // cerr now goes to errout.txt in etc directory
+  err=noError;
+
+  // get relevant "collection"
+  z3950_proxy_array::iterator zserver = zservers.begin();
+  z3950_proxy_array::iterator zend = zservers.end();
+  while (zserver != zend) {
+    if((*zserver)->getName()==collection) {
+      break;
+    }
+    ++zserver;
+  }
+  // now have collection in zserver.
+  
+  ColInfoResponse_t info;
+  ResultDocInfo_t *docInfo;
+  
+  // leave response.termInfo empty
+  // response.termInfo.push_back(g_EmptyText); ??????? (should be empty if not req.)
+
+  // See if this is for a query action
+  if (request.filterName=="QueryFilter") {
+    /* Sample OptionValue pairs
+      `StartResults'=`1'
+      `EndResults'=`20'
+      `Term'=`firstword secondword' (term is just whatever the user typed in)
+      `QueryType'=ranked|boolean   -> OR|AND
+      //`MatchMode'=`some' => 'OR'
+      //`MatchMode' = `all' => 'AND'
+      `Casefold'=`true'
+      `Stem'=`false'
+      `Maxdocs'=`50'
+     */
+    // go through options
+    text_t opt_term;            // the term(s) that the user entered 
+    int opt_querytype=0;        // 1=>ranked (or), 2=>boolean (and)
+    text_t opt_fields;          // which fields to search on
+    int opt_start=1, opt_end=20; // default values
+    int nummatches=0, maxdocs=50; // default values
+    OptionValue_tarray::iterator ov_here=request.filterOptions.begin();
+    OptionValue_tarray::iterator ov_end=request.filterOptions.end();
+    while (ov_here != ov_end) {
+      if (ov_here->name=="Term") {
+	opt_term=ov_here->value;
+      } else if (ov_here->name=="QueryType") {
+	if (ov_here->value=="ranked") opt_querytype=1;
+	else if (ov_here->value=="boolean") opt_querytype=2;
+	else { /* error - shouldn't happen */
+	  /* currently unhandled */
+	}
+      } else if (ov_here->name=="Index") {
+	opt_fields=ov_here->value;
+      } else if (ov_here->name=="StartResults") {
+	opt_start=ov_here->value.getint();
+      } else if (ov_here->name=="EndResults") {
+	opt_end=ov_here->value.getint(); 
+      } else if (ov_here->name=="Maxdocs") {
+	maxdocs=ov_here->value.getint();
+      } 
+      ++ov_here;
+    }
+    err=noError;
+    text_tarray *titles=(*zserver)->getrecordTitles(opt_term,
+						    opt_querytype,
+						    opt_fields,
+						    opt_start, // first to get
+						    opt_end-opt_start, //count
+						    &nummatches,err);
+    if (err!=noError) {
+      // can we return an err msg in a response, or just use
+      // the more drastic Greenstone error mechanism?
+      docInfo=new ResultDocInfo_t;
+      response.docInfo.push_back(*docInfo);
+      docInfo->metadata["Title"].values.push_back("Error - query err?");
+      logout << "\nz3950 filter query: error connecting to server\n";
+      // for now, DON'T use GSDL protocol err.
+      err=noError;
+      return;
+    }
+    // check if (titles==NULL) - only happens on error?
+    if (nummatches>0) {
+      text_tarray::iterator titles_here=titles->begin();
+      text_tarray::iterator titles_end=titles->end();
+      int counter=1;
+      while (titles_here!=titles_end) {
+	docInfo=new ResultDocInfo_t; 
+	docInfo->metadata["Title"].values.push_back(*titles_here);
+	docInfo->result_num=counter;
+	// we need to give some OID, so we'll just use counter for now...
+	// make it the number into the whole possible retrieved set.
+	docInfo->OID=counter+opt_start-1;
+	response.docInfo.push_back(*docInfo);
+	++counter;
+	++titles_here;
+      }
+    }
+
+    if (request.filterResultOptions & FRtermFreq) {
+      if (nummatches>maxdocs) {
+      	response.numDocs=maxdocs; // eg "more than 50" (if Maxdocs==50)
+	response.isApprox=MoreThan;
+      } else {
+	response.numDocs=nummatches; // eg "36 documents"
+	response.isApprox=Exact; // Exact | Approximate | MoreThan
+      }
+    } // end of if (... & FRtermFreq)
+    
+  } // end of if (... == "QueryFilter")
+  else {
+    // this wasn't a query action
+
+    if (request.filterOptions.size()>0 &&
+	request.filterOptions[0].name=="ParentNode") {
+      // don't want to return anything
+      return;
+      /*    } else if (request.docSet.size() &&
+	    request.docSet[0]!="collection") {
+	    // documentaction
+	    // if docSet is not empty, it is either "collection", or an array
+	    // of OIDs 
+	    docInfo=new ResultDocInfo_t;
+	    response.docInfo.push_back(*docInfo);
+      */
+    } else {
+      // in case we need to return only metadata
+      docInfo=new ResultDocInfo_t;
+      response.docInfo.push_back(*docInfo); 
+    }
+  } // end of not a query action
+
+
+
+  // Fill in metadata for each response.docInfo (if wanted)
+  if (request.filterResultOptions & FRmetadata) {
+    get_collectinfo (collection, info, err, logout);
+    // should check err returned here....
+
+    if (!request.fields.empty()) {
+      // currently, this is only true for NullFilter when getting the "Title"
+      // for a documentaction.
+
+      // loop on each document being returned
+      ResultDocInfo_tarray::iterator docs_here=response.docInfo.begin();
+      ResultDocInfo_tarray::iterator docs_end=response.docInfo.end();
+      while (docs_here!=docs_end) {
+	// loop on all the metadata fields in request.fields (type text_tset)
+	text_tset::iterator fields_here=request.fields.begin();
+	text_tset::iterator fields_end=request.fields.end();
+	//text_tmap::iterator it;
+	collectionmeta_map::iterator it;
+	while (fields_here!=fields_end) {
+	  it=info.collectionmeta.find(*fields_here);
+	  if (it!=info.collectionmeta.end())
+	    docs_here->metadata[*fields_here].values.push_back(((*it).second)[g_EmptyText]);
+	  else if (*fields_here=="Title" && !request.docSet.empty()) { 
+	    // We only do this for a document action.
+	    // (This comes through as a NullQuery).
+	    // hopefully docSet is only not empty for documentaction...
+	    text_t doctitle;
+	    int i;
+	    // check that docSet isn't empty first!!!!!!
+	    i=request.docSet[0].getint();
+	    text_t doctext="unneeded";
+	    /* following variables aren't used, as our query result has been
+	       cached in z3950proxy.cpp (but really we shouldn't know that
+	       here...) But for the NullFilter, we don't get given these
+	       again in the request, so for now we'll take advantage of this.*/
+
+	    int querytype=0; text_t field=g_EmptyText;
+
+	    // get the Query out of the filterOptions. (we need get the Title)
+	    text_t query=g_EmptyText;
+	    OptionValue_tarray::iterator opthere=request.filterOptions.begin();
+	    OptionValue_tarray::iterator opt_end=request.filterOptions.end();
+	    while (opthere!=opt_end) {
+	      if (opthere->name=="Term") {
+		query=opthere->value;
+	      } else if (opthere->name=="Index") {
+		field=opthere->value;
+	      } else if (opthere->name=="QueryType") {
+		if (opthere->value=="ranked") querytype=1;
+		else if (opthere->value=="boolean") querytype=2;
+		else { /* error - shouldn't happen */
+		  /* currently unhandled */
+		}
+	      }
+	      ++opthere;
+	    }
+	    (*zserver)->getfullrecord(query, querytype, field, i, doctitle, doctext, err);
+	    // check err value!
+	    docs_here->metadata["Title"].values.push_back(doctitle);	    
+	  } else {
+	    docs_here->metadata[*fields_here].values.push_back(g_EmptyText);
+	  }
+	  ++fields_here;
+	} // end of inner while loop
+	++docs_here;
+      } // end of outer while loop
+    } // end of if (!request.fields.empty())
+    
+    else { // request.fields empty: return all metadata for about page or query
+      // we'll only put it in the first docInfo.
+      collectionmeta_map::iterator colmeta_here=info.collectionmeta.begin();
+      collectionmeta_map::iterator colmeta_end=info.collectionmeta.end();
+      while (colmeta_here!=colmeta_end) {
+	response.docInfo[0].metadata[(*colmeta_here).first].
+	  values.push_back(((*colmeta_here).second)[g_EmptyText]);
+	++colmeta_here;
+      }
+
+      // check if "collectionextra" metadata is set. If it isn't, we should
+      // create connection to target to get it.
+      if (info.collectionmeta.find("collectionextra")==colmeta_end) {
+	// it hasn't been set yet...
+	text_t abouttext="<B>Server Online</B><br>\n";
+	abouttext+=(*zserver)->getzAbout();
+	// add in the "About" text we read in from config file.
+	// how do we incorporate multi-lingual metadata?
+	abouttext+="<P>\n";
+	text_t tmpabout;
+
+	if ((*zserver)->getcfgAbout("en", tmpabout)==true)
+	  abouttext+=tmpabout;
+	
+	(*zserver)->setMeta("collectionextra",abouttext);
+	response.docInfo[0].metadata["collectionextra"].values.push_back(abouttext);
+      }
+    } // end of else
+
+    // do indices' names, regardless of whether asked for or not...
+    if (!response.docInfo.empty()) {
+     response.docInfo[0].metadata[".author"].values.push_back("author fields");
+      response.docInfo[0].metadata[".title"].values.push_back("title fields");
+      response.docInfo[0].metadata[".any"].values.push_back("any fields");
+    }
+  } //end of  if (... & FRmetadata) ...
+}
+
+
+
+void z3950proto::get_document (const text_t &collection,
+			       const DocumentRequest_t &request,
+			       DocumentResponse_t &response,
+			       comerror_t &err, ostream &logout) {
+
+  err=noError;
+
+  // get relevant "collection"
+  z3950_proxy_array::iterator zserver = zservers.begin();
+  z3950_proxy_array::iterator zend = zservers.end();
+  while (zserver != zend) {
+    if((*zserver)->getName()==collection) {
+      break;
+    }
+    ++zserver;
+  }
+  // now have collection in zserver.
+
+  /* docresponse consists of
+     text_t response.doc */
+  text_t title="unneeded";
+  text_t doctext;
+  text_t query; // this should not be needed, as we have already connected to 
+  // get the  title....
+  int querytype = 1; //ditto...
+  text_t field;  // ditto...
+  (*zserver)->getfullrecord(query,querytype,field,request.OID.getint(),
+			    title,doctext,err);
+  // check return value of above? (false=>not connected) 
+  if (err==noError)
+    response.doc=doctext;
+  else {
+    // could print out different messages based on error type....
+    response.doc="<h2>Error</h2>There was an error while connecting to the ";
+    response.doc+="z39.50 server (ie target). Most likely this was a \n";
+    response.doc+="\"Connection Refused\" error.\n";
+
+  }
+  if (0) {
+    err=protocolError;
+    logout << "Some error\n";
+  }
+}
+
+// sets issearchable to true if the given colection is searchable
+void z3950proto::is_searchable (const text_t &/*collection*/, bool &issearchable, 
+				comerror_t &err, ostream &/*logout*/) {
+  issearchable = true; // assume all collections are searchable?
+  err = noError;
+}
+
Index: /gsdl/stable/runtime-src/src/z3950/z3950proto.h
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950proto.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950proto.h	(revision 20131)
@@ -0,0 +1,98 @@
+/**********************************************************************
+ *
+ * z3950proto.h --
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef Z3950PROTO_H
+#define Z3950PROTO_H
+
+#include "recptproto.h"
+#include "z3950proxy.h"
+
+class z3950proto : public recptproto {
+protected:
+  int zserver_count;
+  z3950_proxy_array zservers;
+public:
+  z3950proto();
+  virtual ~z3950proto();
+
+  int getServerCount() { return zserver_count;}
+  /*
+  void add_collectserver (collectserver *thecserver) 
+        {cservers.addcollectserver(thecserver);}
+  */
+  
+  void add_server(z3950_proxy& zserver);
+
+  void read_config_file(const text_t &filename, const text_t &errfile);
+
+  void configure (const text_t &key, const text_tarray &cfgline);
+
+  bool init (ostream &logout);
+
+  text_t get_protocol_name (comerror_t &/*err*/) {return "z3950proto";}
+
+  void get_collection_list (text_tarray &collist, comerror_t &err, 
+			    ostream &logout);
+
+  void has_collection (const text_t &collection, bool &hascollection, 
+		       comerror_t &err, ostream &logout);
+  
+  void ping (const text_t &collection, bool &wassuccess, 
+	     comerror_t &err, ostream &logout);
+  
+  void get_collectinfo (const text_t &collection, 
+			ColInfoResponse_t &collectinfo,
+			comerror_t &err, ostream &logout);
+  
+  void get_filterinfo (const text_t &collection,
+		       InfoFiltersResponse_t &response,
+		       comerror_t &err, ostream &logout);
+  
+  /*  void get_info (const text_t &collection, const text_tset &metadata,
+      FilterResponse_t &response, ostream &logout);
+  */
+
+  void get_filteroptions (const text_t &collection,
+                          const InfoFilterOptionsRequest_t &request,
+                          InfoFilterOptionsResponse_t &response, 
+                          comerror_t &err, ostream &logout);
+  
+  void filter (const text_t &collection,
+	       FilterRequest_t &request,
+	       FilterResponse_t &response,
+	       comerror_t &err, ostream &logout);
+  
+  void get_document (const text_t &collection,
+		     const DocumentRequest_t &request,
+		     DocumentResponse_t &response,
+		     comerror_t &err, ostream &logout);
+  
+  void is_searchable (const text_t &collection, 
+			      bool &issearchable, 
+			      comerror_t &err, ostream &logout);
+
+};
+
+#endif
Index: /gsdl/stable/runtime-src/src/z3950/z3950proxy.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950proxy.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950proxy.cpp	(revision 20131)
@@ -0,0 +1,365 @@
+/**********************************************************************
+ *
+ * z3950proxy.cpp --
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#include "z3950proxy.h"
+#include "comtypes.h"
+#include <stdio.h>
+
+// z39.50 yaz stuff
+#define min(a,b) (((a)<(b))?(a):(b))
+
+extern "C" {
+#include "yaz_zclient.h"
+}
+
+/*** 
+     each z39.50 server+database pair is a GSDL collection.
+***/
+
+z3950_proxy::z3950_proxy() {
+  info=NULL;
+  connected=false;
+  titles=NULL;
+  gotsinglerecord=false;
+  // for now, assume that all records will have text associated with them.
+  meta["hastxt"]="1";
+  // for now, assume we don't want ANY DocumentButtons.
+  format["DocumentButtons"]=g_EmptyText;
+}
+
+z3950_proxy::~z3950_proxy() {
+}
+
+void z3950_proxy::setMeta(const text_t &key, const text_t &value) {
+  meta[key]=value;
+}
+
+void z3950_proxy::setName(const text_t &newname) {
+  title=newname;
+  meta["collectionname"]=newname;
+}
+
+void z3950_proxy::addcfgAbout(const text_t &lang, const text_t &abouttext) {
+    about[lang]=abouttext;
+}
+
+bool z3950_proxy::getcfgAbout(const text_t &lang, text_t &abouttxt) {
+  text_tmap::iterator it;
+  it=about.find(lang);
+  if (it==about.end()) return (false);
+  abouttxt=((*it).second);
+  return (true);
+}
+
+
+// now functions that actually talk over the tcp connection.
+
+// create a tcp connection to the associated target. Currently, this will
+// re-initialise if we are already connected.
+bool z3950_proxy::connect() {
+  text_t server_and_port;
+  char *zserverinfo;
+
+  server_and_port=info->host+":"+info->port;
+  // remember that info.name is the database name
+
+  z_initialize();
+  char* serv_str=server_and_port.getcstr();
+  char* name_str=info->name.getcstr();
+  int retval=z_cmd_open(serv_str,name_str);
+  delete []serv_str;
+  delete []name_str;
+  if (retval==1)
+    // we got a connection error
+    return false;
+
+  // get initialisation response.
+  z_getnextAPDU();
+  zserverinfo=z_get_initResponse();
+  if (zserverinfo!=NULL) {
+    z_initstr.appendcstr(zserverinfo);
+  }
+  free(zserverinfo);
+
+  connected=true;
+  return true;
+}
+
+void z3950_proxy::parseQuery(const text_t &query, 
+			      const int querytype,
+			      const text_t &fields,
+			      text_t &parsed_query) {
+  /****** FIXME *****/
+  // We need to format the query string into RPN - 
+  // by just passing it like this, it will only work for simple queries.
+  // This will require us to actually come up with a query syntax and 
+  // a parser. For now, we'll just do an "AND" query for all terms
+  // But look at Common Command Language (CCL) query syntax (ISO 8777).
+
+  // need to remove " chars from the query. We should really tell the server
+  // to do a phrase search on the terms that are between the "s, but we
+  // can't (easily) tell if the server can do that or not, 
+  // so we'll currently just do a query and then post-process. (not yet
+  // implemented........)
+
+  // we need to count number of terms separated by a space
+  char *ptr=query.getcstr();
+  int strlength=strlen(ptr);
+  bool inword=false;
+  int num_terms=0;
+
+
+  for (int i=0;i<strlength;++i) {
+    if (*(ptr+i)=='"') { // convert " to SPACE...
+      *(ptr+i)=' '; 
+    }
+    if (*(ptr+i)!=' ') {
+      if (inword==false) {
+	inword=true;
+	++num_terms;
+      }
+    }
+    else { // ptr+i is a space
+      inword=false;
+      }
+  }
+  
+  // set the field(s) to search on - main ones include:
+  //  1016  => Any
+  //  1     => (Personal) Name
+  //  4     => Title
+  //  21    => Subject Heading
+  //  45    => Subject precis
+  // Note I have no idea how these actually work - I think some servers
+  // only have limited fields, and map all subject-type requests into that
+  // subject field, etc.
+
+  parsed_query="@attr 1=";
+  if (fields==".author")
+    parsed_query+="1 ";
+  else if (fields==".title")
+    parsed_query+="4 ";
+  else // fields==".any"
+    parsed_query+="1016 ";
+
+  // querytype=1 => ranked/or,  =2 => boolean/and
+  // append "@and" for each term after the first
+  {
+    char and_str[]="@and ";
+    char or_str[]="@or ";
+    char *q_type;
+    if (querytype==1) q_type=or_str; else q_type=and_str;
+    for (int i=1;i<num_terms;++i)
+      parsed_query+=q_type;
+    // append the actual query
+    parsed_query+=ptr;
+  }
+  delete []ptr;
+}
+
+text_tarray *z3950_proxy::getrecordTitles(const text_t &query, 
+					   const int querytype,
+					   const text_t &fields,
+					   int first, int count,
+					   int *nummatches, comerror_t &err) {
+  /* NOTE!!!!!! Because this code currently only works in cgi-bin mode,
+     we only ever do one request. Therefore, it is CURRENTLY OK to store
+     (cache) the retrieved titles, because if this function is ever called
+     more than once, the arguments will be the same each time.
+     (I think :)
+  */
+
+  char **c_str_titles; 
+  int i;
+  int last;
+
+  if (gotsinglerecord==true) {
+    /* If true, then this whole execution was done to retrieve a single
+       document. Therefore, the list of titles of all records matching the
+       query isn't actually required. It's just that for some reason our
+       filter (z3950proto::filter) gets called at least 7 times, with the
+       7th being a "QueryFilter" for some reason... */
+    nummatches=0;
+    return NULL; /* shouldn't really return NULL, but nummatches is checked
+		    first (I hope) */
+  }
+
+  //  if (titles!=NULL) delete (titles);
+  if (titles!=NULL) return titles;
+  titles=new text_tarray;
+
+  /* check if connected */
+  if (connected==false) 
+    if (connect()==false) {
+      // we could not connect.
+      err=protocolError;
+      return (NULL);
+    }
+  
+
+  text_t expanded_query=g_EmptyText;
+  parseQuery(query,querytype,fields,expanded_query);
+
+  char* query_str=expanded_query.getcstr();
+  // following functions defined in yaz_zclient.c
+  *nummatches=z_cmd_dosearch(query_str); // returns # found, -1 on err.
+  delete []query_str;
+  if (*nummatches<=0) {
+    if (*nummatches==0) {
+      // no matches
+      return (NULL);
+    } else  if (*nummatches==-1) {
+      // prefix query error
+      err=protocolError;
+      return (NULL);
+    }  else if (*nummatches==-2) {
+      // sendsearchRequest not answered by searchResponse
+      err=protocolError;
+      return (NULL);
+    }
+  }
+  // could do a sort eventually, eg on date, title, etc.
+  // (non-existent function)    z_sort(field, asc|desc);
+  /* min of (count, first + (*nummatches) ) */
+  // z_getrecordTitles ( first, howmany )
+  c_str_titles=z_getrecordTitles(first,min(count,*nummatches-first+1));
+  if (c_str_titles==NULL) {
+    // an error occurred. we need a logout/err as an arg
+    return (NULL);
+  }
+  if (c_str_titles[0]==0) {
+    // no matches.
+    return (NULL);
+  }
+  last=(int)c_str_titles[0];
+  for (i=1;i<=last;++i) {
+    titles->push_back(c_str_titles[i]);
+    free(c_str_titles[i]);
+  }
+  free(c_str_titles);
+  return (titles);
+  
+}
+
+bool z3950_proxy::getfullrecord(const text_t &query, 
+				 const int querytype,
+				 const text_t &fields,
+				 const int ID, 
+				 text_t &rettitle, 
+				 text_t &rettext, comerror_t &err) {
+
+  static char **c_str_titles=NULL;
+  static char *fulltext=NULL;
+  /* NOTE!!!!!! Because this code currently only works in cgi-bin mode,
+     we only ever do one request. Therefore, it is CURRENTLY OK to store
+     (cache) the retrieved titles, because if this function is ever called
+     more than once, the arguments will be the same each time.
+     (I think :)
+  */
+
+  gotsinglerecord=true; // well, not yet, but we've been called...
+
+  if (connected==false) {
+    if (connect()==false) {
+      // error connecting...
+      err=protocolError;
+      return (false);
+    }
+    // since we have just re-connected, we need to do the
+    // query again.
+
+    text_t expanded_query=g_EmptyText;
+    parseQuery(query,querytype,fields,expanded_query);
+
+    char* query_str=expanded_query.getcstr();
+    int returned=z_cmd_dosearch(query_str);
+    delete []query_str;
+    if (returned<=0) {
+      // 0 => none.
+      // <0 => error
+      err=protocolError;
+      return (false);
+    }
+  }
+
+  if (c_str_titles==NULL)
+    c_str_titles=z_getrecordTitles(ID,1); // check this return value.
+  
+  if (rettitle!="unneeded") {
+    //int dummy;
+    if (c_str_titles!=NULL && (int)c_str_titles[0]==1) {
+      rettitle.setcstr(c_str_titles[1]); // and check this 
+      //////      free (c_str_titles); - we want to "cache" it
+    } else {
+      // we didn't get something....
+      rettitle="Nothing Returned...";
+    }
+  }
+
+  if (fulltext==NULL)
+    // get the text
+    fulltext=z_getfullRecord(ID);
+
+  if (rettext!="unneeded") {
+    rettext.setcstr(fulltext);
+  }
+  return (true);
+  }
+
+text_t &z3950_proxy::getzAbout() {
+  text_t zserverresp;
+
+  // Assume we have not yet connected, so that must be done here.
+  if (connected==true)
+    return (z_initstr);
+  
+  // we need to create the tcp connection to the target (server)  
+  //  z_initstr=new text_t;
+  
+  if (connect()==false) {
+    z_initstr.setcstr("<H2>Server offline</H2>Error - could not connect to server <B>");
+    z_initstr += info->host;
+    z_initstr += "</B> on port ";
+    z_initstr += info->port;
+    z_initstr += "\n";
+    return (z_initstr);
+  }
+  
+  // z_initstr currently contains the target's response. We want to
+  // PREPEND the following information.
+  zserverresp=z_initstr;
+  z_initstr="Internet server: <b>";
+  z_initstr+=info->host;
+  z_initstr+="</b> on port ";
+  z_initstr+=info->port;
+  z_initstr+=".<br>\n";
+  z_initstr+=zserverresp;
+
+  // should close /******* WHAT IF DOING A QUERY!??!?!? ********/
+  // z_cmd_close(0);
+  // connected=false;
+  return (z_initstr);
+}
+
Index: /gsdl/stable/runtime-src/src/z3950/z3950proxy.h
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950proxy.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950proxy.h	(revision 20131)
@@ -0,0 +1,79 @@
+/**********************************************************************
+ *
+ * z3950proxy.h --
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef Z3950PROXY_H
+#define Z3050PROXY_H
+
+#include "comtypes.h"
+
+// each "proxy to server" (i.e. collection) consists of a {z39.50 server + database} pair.
+class z3950_proxy {
+ protected:
+  text_t title;    // Descriptive name
+  text_t z_initstr; // a string returned when the connection is initialised.
+  text_tmap meta;  // metadata for this collection (ie server/database pair)
+  text_tmap format;
+  text_tmap about; // langauge/abouttext pair for collection.
+  ShortColInfo_t *info; // has  (database) name, host and port
+  text_tarray *titles; 
+  bool connect();
+  bool connected; // tcp connection to the z39.50 server (target)
+  bool gotsinglerecord; // if we do, then we don't need all titles...
+
+ public:
+  z3950_proxy();
+  ~z3950_proxy();
+  void setName(const text_t &newname);
+  const text_t getName() {return title;}
+  void setMeta(const text_t &key, const text_t &value);
+  const text_tmap *getMeta() {return &meta;}
+  const text_tmap *getFormat() {return &format;}
+  void setInfo(ShortColInfo_t *newinfo) {info=newinfo;}
+  const ShortColInfo_t *getInfo() {return info;}
+  void addcfgAbout(const text_t &lang, const text_t &abouttext);
+  bool getcfgAbout(const text_t &lang, text_t &abouttext);
+  // now the functions that actually talk to the target (ie zserver) over tcp
+  text_t &getzAbout(); // gets any name, id, MOTD, etc from server.
+  text_tarray *getrecordTitles(const text_t &query,
+			       const int andor_querytype,
+			       const text_t &fields,
+			       const int first, const int count,
+			       int *nummatches, comerror_t &err);
+  /* only get one record at a time? (Eventually we could buffer them, but
+     for now... */
+  bool getfullrecord(const text_t &query, const int andor_querytype,
+		     const text_t &fields,
+		     const int ID, text_t &rettitle, 
+		     text_t &rettext,comerror_t &err);
+ private:
+  void parseQuery(const text_t &query, const int andor_querytype, 
+		  const text_t &fields, 
+		  text_t &parsed_query);
+  text_t previousquery; // for caching purposes
+};
+
+typedef  vector<z3950_proxy *>  z3950_proxy_array;
+
+#endif
Index: /gsdl/stable/runtime-src/src/z3950/z3950server.cpp
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950server.cpp	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950server.cpp	(revision 20131)
@@ -0,0 +1,942 @@
+
+
+// Standard headers
+
+#if defined(GSDL_USE_OBJECTSPACE)
+#  include <ospace\std\iostream>
+#  include <ospace\std\fstream>
+#  include <ospace\std\sstream>
+#elif defined(GSDL_USE_IOS_H)
+#  include <iostream.h>
+#  include <fstream.h>
+#  include <strstream.h>
+#else
+#  include <iostream>
+#  include <fstream>
+#  include <sstream>
+#endif
+
+#include <string>
+#include <list>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <time.h>
+
+// Greenstone headers
+#include "fileutil.h"
+#include "comtypes.h"
+#include "nullproto.h"
+
+// Z39.50 server headers
+#include "z3950parser.h"
+#include "z3950explain.h"
+
+#include "z3950server.h"
+
+// Dublin Core -> MARC (d2m) headers and source files
+#include "d2m4gs.h"
+
+// these globals are local to each thread,
+// one Z39.50 connection = one thread.
+text_t gsdlhome; // this is set by the collectset object from the gsdlsite.cfg file
+text_t collecthome; // this is set by the collectset object
+list<FilterResponse_t> Response_tlist; // list of response sets
+list<text_t> Response_tlist_colnames;  // collection names for the above
+list<int> Response_tlist_sizes;        // sizes (number of records) for the above
+z3950Server *Server   = NULL;
+collectset  *Cservers = NULL;
+nullproto   *Protocol = NULL;
+
+map<text_t, gsdlCollection> Collection_map; // info and tools for collections
+map<text_t, text_t> Resultsets;             // mapping from ResultSetId to GSQuery 
+
+int z3950_verbosity_ = 3;
+
+// *** initialize things here ***
+bend_initresult *bend_init(bend_initrequest *q)
+{
+  // *** called when client connects to the server ***
+  if (z3950_verbosity_ > 1) {
+    cerr << "Entering bend_init" << endl;
+  }
+
+  Protocol = new nullproto();  
+  Cservers = new collectset(gsdlhome, collecthome);
+  Protocol->set_collectset(Cservers);
+  
+  cerr << "Starting Z39.50 Server ..." << endl;
+  
+  Server = new z3950Server(Protocol, gsdlhome);
+  cerr << "Server constructed" << endl;
+  
+  const bool status = Server->initialise();
+  cerr << "Initialised server: return status = " << status << endl;
+  
+  text_tarray collist;
+  comerror_t err;
+  Protocol->get_collection_list( collist, err, cout );
+
+  // display the list of available Greenstone collections
+  text_tarray::iterator cols_here=collist.begin();
+  text_tarray::iterator cols_end=collist.end();
+  while (cols_here != cols_end) {
+    gsdlCollection tmpcol(*cols_here, gsdlhome);
+    
+    Collection_map[*cols_here] = tmpcol;
+    
+    if (tmpcol.z3950Capeable()) {
+      cerr << "  " << tmpcol.getName() << "\tis Z39.50 capable" << endl;
+    }
+    cols_here++;
+  }
+
+    
+  bend_initresult *r = (bend_initresult *) odr_malloc (q->stream, sizeof(*r));
+  //static char *dummy = "Hej fister"; // what's this for?
+  
+  r->errcode = 0;
+  r->errstring = 0;
+  r->handle = Protocol;
+  q->bend_sort = ztest_sort;       /* register sort handler */
+  q->bend_search = ztest_search;   /* register search handler */
+  q->bend_present = ztest_present; /* register present handle */
+  q->bend_esrequest = ztest_esrequest;
+  q->bend_delete = ztest_delete;
+  q->bend_fetch = ztest_fetch;
+  q->bend_scan = ztest_scan;
+
+  return r;
+}
+
+// *** perform query, get number of hits ***
+int ztest_search (void *handle, bend_search_rr *rr)
+{
+  // *** called when client issues a "find" command
+  if (z3950_verbosity_>1) {
+    cerr << "Entering ztest_search" << endl;
+  }
+
+  Response_tlist.clear();
+  Response_tlist_colnames.clear();
+  Response_tlist_sizes.clear();
+ 
+  comerror_t err;
+  FilterRequest_t request;
+
+  request.filterName = "QueryFilter";
+  request.filterResultOptions = FROID | FRtermFreq | FRmetadata;  
+
+  OptionValue_t option;
+
+  // how many results to get. grouping all results together into
+  // one set instead of breaking up into "pages". 
+  // note: see if Z39.50 has a concept of pages.
+  option.name = "StartResults";
+  option.value = "1";
+  request.filterOptions.push_back (option);
+  option.name = "EndResults";
+  option.value = MAXHITS;
+  request.filterOptions.push_back (option);
+  option.name = "Maxdocs";
+  option.value = MAXHITS;
+  request.filterOptions.push_back (option);
+
+  text_t GSQuery = ZQueryToGSQuery(rr);
+  option.name = "Term";
+  option.value = GSQuery;
+  request.filterOptions.push_back (option);
+  Resultsets[Resultsets.size()+1] = GSQuery;
+
+  option.name = "QueryType";
+  option.value = "boolean";
+  request.filterOptions.push_back (option);
+
+  option.name = "MatchMode";
+  option.value = "all";
+  request.filterOptions.push_back (option);
+
+  option.name = "Casefold";
+  option.value = "true";
+  request.filterOptions.push_back (option);
+
+  option.name = "Stem";
+  option.value = "false";
+  request.filterOptions.push_back (option);
+
+  option.name = "AccentFold";
+  option.value = "false";
+  request.filterOptions.push_back (option);
+  
+  // MG queries don't need this, MGPP queries do.
+  // doesn't do any harm to include it anyway.
+  // note: not all collections have document-level granularity...
+  option.name = "Level";
+  option.value = "Doc";
+  request.filterOptions.push_back (option);
+
+  // Z39.50 supports the searching of multiple databases
+  rr->hits = 0;
+  for (int i = 0; i < rr->num_bases; i++) {
+    FilterResponse_t response;
+    cerr << "Searching basename = " << rr->basenames[i] << endl;
+    // intercept Explain requests
+    if (strcmp(rr->basenames[i], "IR-Explain-1")==0) {
+      //ColInfoResponse_t collectinfo;
+      //Protocol->get_collectinfo("csbib", collectinfo, err, cerr);
+      //response.numDocs = 1;
+      //ResultDocInfo_t docinfo;
+      //docinfo.metadata["foo"].values.push_back("bar");
+      getExplainInfo(rr, response, err);
+      //response.docInfo.push_back(docinfo);
+    } else {
+      cerr << "calling filter..." << endl;
+      Protocol->filter(rr->basenames[i], request, response, err, cerr);
+      cerr << "returned from filter." << endl;
+      if (response.numDocs > MAXHITS) {
+	response.numDocs = MAXHITS;
+      }
+    }
+    rr->hits += response.numDocs;
+    Response_tlist.push_back(response);
+    text_t basename = rr->basenames[i];
+    Response_tlist_colnames.push_back(basename);
+    Response_tlist_sizes.push_back(response.numDocs);
+    cerr << "search complete." << endl;
+  }    
+
+  if (rr->hits > MAXHITS) rr->hits = MAXHITS;
+  return 0;
+}
+
+// *** extra code for showing results, not needed ***
+int ztest_present (void *handle, bend_present_rr *rr)
+{
+  // *** called when client issues a "show" command, 1st of 5
+  if (z3950_verbosity_>1) {
+    cerr << "entering ztest_present" << endl;
+  }
+  return 0;
+}
+
+int ztest_esrequest (void *handle, bend_esrequest_rr *rr)
+{
+
+    if (z3950_verbosity_>1) {
+      cerr << "Entering ztest_esrequest" << endl;
+    }
+    yaz_log(LOG_LOG, "function: %d", *rr->esr->function);
+    if (rr->esr->packageName)
+    	yaz_log(LOG_LOG, "packagename: %s", rr->esr->packageName);
+    yaz_log(LOG_LOG, "Waitaction: %d", *rr->esr->waitAction);
+
+    if (!rr->esr->taskSpecificParameters)
+    {
+        yaz_log (LOG_WARN, "No task specific parameters");
+    }
+    else if (rr->esr->taskSpecificParameters->which == Z_External_itemOrder)
+    {
+    	Z_ItemOrder *it = rr->esr->taskSpecificParameters->u.itemOrder;
+	yaz_log (LOG_LOG, "Received ItemOrder");
+	switch (it->which)
+	{
+#ifdef ASN_COMPILED
+	case Z_IOItemOrder_esRequest:
+#else
+	case Z_ItemOrder_esRequest:
+#endif
+	{
+	    Z_IORequest *ir = it->u.esRequest;
+	    Z_IOOriginPartToKeep *k = ir->toKeep;
+	    Z_IOOriginPartNotToKeep *n = ir->notToKeep;
+	    
+	    if (k && k->contact)
+	    {
+	        if (k->contact->name)
+		    yaz_log(LOG_LOG, "contact name %s", k->contact->name);
+		if (k->contact->phone)
+		    yaz_log(LOG_LOG, "contact phone %s", k->contact->phone);
+		if (k->contact->email)
+		    yaz_log(LOG_LOG, "contact email %s", k->contact->email);
+	    }
+	    if (k->addlBilling)
+	    {
+	        yaz_log(LOG_LOG, "Billing info (not shown)");
+	    }
+	    
+	    if (n->resultSetItem)
+	    {
+	        yaz_log(LOG_LOG, "resultsetItem");
+		yaz_log(LOG_LOG, "setId: %s", n->resultSetItem->resultSetId);
+		yaz_log(LOG_LOG, "item: %d", *n->resultSetItem->item);
+	    }
+#ifdef ASN_COMPILED
+	    if (n->itemRequest)
+	    {
+		Z_External *r = (Z_External*) n->itemRequest;
+		ILL_ItemRequest *item_req = 0;
+		ILL_Request *ill_req = 0;
+		if (r->direct_reference)
+		{
+		    oident *ent = oid_getentbyoid(r->direct_reference);
+		    if (ent)
+			yaz_log(LOG_LOG, "OID %s", ent->desc);
+		    if (ent && ent->value == VAL_ISO_ILL_1)
+		    {
+			yaz_log (LOG_LOG, "ItemRequest");
+			if (r->which == ODR_EXTERNAL_single)
+			{
+			    odr_setbuf(rr->decode,
+				       (char*)(r->u.single_ASN1_type->buf),
+				       r->u.single_ASN1_type->len, 0);
+			    
+			    if (!ill_ItemRequest (rr->decode, &item_req, 0, 0))
+			    {
+				yaz_log (LOG_LOG,
+                                    "Couldn't decode ItemRequest %s near %d",
+                                       odr_errmsg(odr_geterror(rr->decode)),
+                                       odr_offset(rr->decode));
+                                yaz_log(LOG_LOG, "PDU dump:");
+                                odr_dumpBER(yaz_log_file(),
+                                     (const char*)(r->u.single_ASN1_type->buf),
+                                     r->u.single_ASN1_type->len);
+                            }
+			    if (rr->print)
+			    {
+				ill_ItemRequest (rr->print, &item_req, 0,
+                                    "ItemRequest");
+				odr_reset (rr->print);
+ 			    }
+			}
+			if (!item_req && r->which == ODR_EXTERNAL_single)
+			{
+			    yaz_log (LOG_LOG, "ILLRequest");
+			    odr_setbuf(rr->decode,
+				       (char*)(r->u.single_ASN1_type->buf),
+				       r->u.single_ASN1_type->len, 0);
+			    
+			    if (!ill_Request (rr->decode, &ill_req, 0, 0))
+			    {
+				yaz_log (LOG_LOG,
+                                    "Couldn't decode ILLRequest %s near %d",
+                                       odr_errmsg(odr_geterror(rr->decode)),
+                                       odr_offset(rr->decode));
+                                yaz_log(LOG_LOG, "PDU dump:");
+                                odr_dumpBER(yaz_log_file(),
+                                     (const char*)(r->u.single_ASN1_type->buf),
+                                     r->u.single_ASN1_type->len);
+                            }
+			    if (rr->print)
+                            {
+				ill_Request (rr->print, &ill_req, 0,
+                                    "ILLRequest");
+				odr_reset (rr->print);
+			    }
+			}
+		    }
+		}
+		if (item_req)
+		{
+		    yaz_log (LOG_LOG, "ILL protocol version = %d",
+			     *item_req->protocol_version_num);
+		}
+	    }
+#endif
+	}
+	break;
+	}
+    }
+    else if (rr->esr->taskSpecificParameters->which == Z_External_update)
+    {
+    	Z_IUUpdate *up = rr->esr->taskSpecificParameters->u.update;
+	yaz_log (LOG_LOG, "Received DB Update");
+	if (up->which == Z_IUUpdate_esRequest)
+	{
+	    Z_IUUpdateEsRequest *esRequest = up->u.esRequest;
+	    Z_IUOriginPartToKeep *toKeep = esRequest->toKeep;
+	    Z_IUSuppliedRecords *notToKeep = esRequest->notToKeep;
+	    
+	    yaz_log (LOG_LOG, "action");
+	    if (toKeep->action)
+	    {
+		switch (*toKeep->action)
+		{
+		case Z_IUOriginPartToKeep_recordInsert:
+		    yaz_log (LOG_LOG, " recordInsert");
+		    break;
+		case Z_IUOriginPartToKeep_recordReplace:
+		    yaz_log (LOG_LOG, " recordUpdate");
+		    break;
+		case Z_IUOriginPartToKeep_recordDelete:
+		    yaz_log (LOG_LOG, " recordDelete");
+		    break;
+		case Z_IUOriginPartToKeep_elementUpdate:
+		    yaz_log (LOG_LOG, " elementUpdate");
+		    break;
+		case Z_IUOriginPartToKeep_specialUpdate:
+		    yaz_log (LOG_LOG, " specialUpdate");
+		    break;
+		default:
+		    yaz_log (LOG_LOG, " unknown (%d)", *toKeep->action);
+		}
+	    }
+	    if (toKeep->databaseName)
+	    {
+		yaz_log (LOG_LOG, "database: %s", toKeep->databaseName);
+		if (!strcmp(toKeep->databaseName, "fault"))
+		{
+		    rr->errcode = 109;
+		    rr->errstring = toKeep->databaseName;
+		}
+		if (!strcmp(toKeep->databaseName, "accept"))
+		    rr->errcode = -1;
+	    }
+	    if (notToKeep)
+	    {
+		int i;
+		for (i = 0; i < notToKeep->num; i++)
+		{
+		    Z_External *rec = notToKeep->elements[i]->record;
+
+		    if (rec->direct_reference)
+		    {
+			struct oident *oident;
+			oident = oid_getentbyoid(rec->direct_reference);
+			if (oident)
+			    yaz_log (LOG_LOG, "record %d type %s", i,
+				     oident->desc);
+		    }
+		    switch (rec->which)
+		    {
+		    case Z_External_sutrs:
+			if (rec->u.octet_aligned->len > 170)
+			    yaz_log (LOG_LOG, "%d bytes:\n%.168s ...",
+				     rec->u.sutrs->len,
+				     rec->u.sutrs->buf);
+			else
+			    yaz_log (LOG_LOG, "%d bytes:\n%s",
+				     rec->u.sutrs->len,
+				     rec->u.sutrs->buf);
+                        break;
+		    case Z_External_octet        :
+			if (rec->u.octet_aligned->len > 170)
+			    yaz_log (LOG_LOG, "%d bytes:\n%.168s ...",
+				     rec->u.octet_aligned->len,
+				     rec->u.octet_aligned->buf);
+			else
+			    yaz_log (LOG_LOG, "%d bytes\n%s",
+				     rec->u.octet_aligned->len,
+				     rec->u.octet_aligned->buf);
+		    }
+		}
+	    }
+	}
+    }
+    else
+    {
+        yaz_log (LOG_WARN, "Unknown Extended Service(%d)",
+		 rr->esr->taskSpecificParameters->which);
+	
+    }
+    return 0;
+}
+
+int ztest_delete (void *handle, bend_delete_rr *rr)
+{
+  // *** called when client issues a "delete" command
+  if (z3950_verbosity_>1) {
+    cerr << "Entering ztest_delete" << endl;
+  }
+  if (rr->num_setnames == 1 && !strcmp (rr->setnames[0], "1"))
+    rr->delete_status = Z_DeleteStatus_success;
+  else
+    rr->delete_status = Z_DeleteStatus_resultSetDidNotExist;
+  return 0;
+}
+
+// *** do we want to sort the results? ***
+/* Our sort handler really doesn't sort... */
+int ztest_sort (void *handle, bend_sort_rr *rr)
+{
+  if (z3950_verbosity_>1) {
+    cerr << "entering ztest_sort" << endl;
+  }
+  rr->errcode = 0;
+  rr->sort_status = Z_SortStatus_success;
+  return 0;
+}
+
+static int atoin (const char *buf, int n)
+{
+  // *** called when client issues a "show" command, 5th of 5
+  // *** NOT called if the "show" command has an invalid argument
+    if (z3950_verbosity_>1) {
+      cerr << "Entering atoin" << endl;
+    }
+    int val = 0;
+    while (--n >= 0)
+    {
+        if (isdigit(*buf))
+            val = val*10 + (*buf - '0');
+        buf++;
+    }
+    return val;
+}
+
+
+bool get_sutrs_record (int recnum, text_t &MetadataResult, text_t &CollectionName)
+{
+  if (z3950_verbosity_>1) {
+    cerr << "Entering get_sutrs_record" << endl;
+  }
+  int total_records = 0;
+
+  list<FilterResponse_t>::iterator RESPONSE_here = Response_tlist.begin();
+  list<FilterResponse_t>::iterator RESPONSE_end = Response_tlist.end();
+  list<text_t>::iterator RESPONSE_COLNAMES_here = Response_tlist_colnames.begin();
+  list<text_t>::iterator RESPONSE_COLNAMES_end = Response_tlist_colnames.end();
+  list<int>::iterator RESPONSE_SIZES_here = Response_tlist_sizes.begin();
+  list<int>::iterator RESPONSE_SIZES_end = Response_tlist_sizes.end();
+
+  RESPONSE_here = Response_tlist.begin();
+  RESPONSE_end = Response_tlist.end();
+  while (RESPONSE_here != RESPONSE_end) {
+    total_records += (*RESPONSE_here).numDocs;
+    RESPONSE_here++;
+  }
+
+  // check that the index is within bounds
+  if (recnum < 1 || recnum > total_records) {
+    cerr << "get_sutrs_record failed" << endl;
+    return false; // failed
+  } else {
+    FilterResponse_t response;
+    // iterate through Response_tlist to find the right response
+    RESPONSE_here = Response_tlist.begin();
+    RESPONSE_end = Response_tlist.end();
+    RESPONSE_COLNAMES_here = Response_tlist_colnames.begin();
+    RESPONSE_COLNAMES_end = Response_tlist_colnames.end();
+    RESPONSE_SIZES_here = Response_tlist_sizes.begin();
+    RESPONSE_SIZES_end = Response_tlist_sizes.end();
+    int n = 0;
+
+    while (RESPONSE_here != RESPONSE_end) {
+      n += *RESPONSE_SIZES_here;
+      if (n >= recnum) {
+	response = *RESPONSE_here;
+	CollectionName = *RESPONSE_COLNAMES_here;
+	recnum = *RESPONSE_SIZES_here - (n - recnum);
+	break;
+      }
+      // these should all have the same number of elements,
+      // so only need to check that one is within bounds.
+      // may want to combine these into a larger data structure later.
+      RESPONSE_here++;
+      RESPONSE_COLNAMES_here++;
+      RESPONSE_SIZES_here++;
+    }
+
+    // locate the desired record in the response 
+   
+    MetadataInfo_tmap::iterator METAFIELD_here = response.docInfo[recnum-1].metadata.begin();
+    MetadataInfo_tmap::iterator METAFIELD_end = response.docInfo[recnum-1].metadata.end();
+
+    while (METAFIELD_here!=METAFIELD_end) {
+      text_tarray::iterator METAVALUE_here = METAFIELD_here->second.values.begin();
+      text_tarray::iterator METAVALUE_end = METAFIELD_here->second.values.end();
+      while (METAVALUE_here!=METAVALUE_end) {
+	// construct a text_t containing the record:
+	// there are multiple metadata fields,
+	// each field can have multiple values.
+	/*
+	// don't include fields starting with a lowercase letter,
+	// these are system fields.
+	// later: include these anyway, since Explain fields start with lowercase letters
+	if (METAFIELD_here->first[0] >= 'A' &&
+	    METAFIELD_here->first[0] <= 'Z') {
+	*/
+	  MetadataResult += METAFIELD_here->first; // field name
+	  MetadataResult += " ";
+	  MetadataResult += *METAVALUE_here; // field contents
+	  MetadataResult += "\n";
+	  //}
+	METAVALUE_here++;
+      }
+      METAFIELD_here++;
+    }
+    return true; // succeeded
+  }
+}
+
+bool get_marc_record (int recnum, list<metatag*> &Metatag_list, text_t &CollectionName)
+{
+  if (z3950_verbosity_>1) {
+    cerr << "Entering get_marc_record" << endl;
+  }
+  int total_records = 0;
+
+  list<FilterResponse_t>::iterator RESPONSE_here = Response_tlist.begin();
+  list<FilterResponse_t>::iterator RESPONSE_end = Response_tlist.end();
+  list<text_t>::iterator RESPONSE_COLNAMES_here = Response_tlist_colnames.begin();
+  list<text_t>::iterator RESPONSE_COLNAMES_end = Response_tlist_colnames.end();
+  list<int>::iterator RESPONSE_SIZES_here = Response_tlist_sizes.begin();
+  list<int>::iterator RESPONSE_SIZES_end = Response_tlist_sizes.end();
+
+  RESPONSE_here = Response_tlist.begin();
+  RESPONSE_end = Response_tlist.end();
+  while (RESPONSE_here != RESPONSE_end) {
+    total_records += (*RESPONSE_here).numDocs;
+    RESPONSE_here++;
+  }
+
+  // check that the index is within bounds
+  if (recnum < 1 || recnum > total_records) {
+    cerr << "get_marc_record failed" << endl;
+    return false; // failed
+  }
+   
+  FilterResponse_t response;
+  // iterate through Response_tlist to find the right response
+  RESPONSE_here = Response_tlist.begin();
+  RESPONSE_end = Response_tlist.end();
+  RESPONSE_COLNAMES_here = Response_tlist_colnames.begin();
+  RESPONSE_COLNAMES_end = Response_tlist_colnames.end();
+  RESPONSE_SIZES_here = Response_tlist_sizes.begin();
+  RESPONSE_SIZES_end = Response_tlist_sizes.end();
+  int n = 0;
+  while (RESPONSE_here != RESPONSE_end) {
+    n += *RESPONSE_SIZES_here;
+    if (n >= recnum) {
+      response = *RESPONSE_here;
+      CollectionName = *RESPONSE_COLNAMES_here;
+      recnum = *RESPONSE_SIZES_here - (n - recnum);
+      break;
+    }
+    // these should all have the same number of elements,
+    // so only need to check that one is within bounds.
+    // may want to combine these into a larger data structure later.
+    RESPONSE_here++;
+    RESPONSE_COLNAMES_here++;
+    RESPONSE_SIZES_here++;
+  }
+
+  // locate the desired record in the response and gather all the metadata
+    
+  MetadataInfo_tmap::iterator METAFIELD_here = response.docInfo[recnum-1].metadata.begin();
+  MetadataInfo_tmap::iterator METAFIELD_end = response.docInfo[recnum-1].metadata.end();
+  
+  while (METAFIELD_here!=METAFIELD_end) {
+    text_t meta_name = METAFIELD_here->first;
+    text_t::const_iterator pos = findchar(meta_name.begin(), meta_name.end(), '.');
+    // strip off namespace and subfield
+    if (pos != meta_name.end()) {
+      meta_name = substr(pos+1, meta_name.end());
+    }
+    pos = findchar(meta_name.begin(), meta_name.end(), '^');
+    if (pos != meta_name.end()) {
+      meta_name = substr(meta_name.begin(), pos);
+    }
+    if (meta_name[0] >= 'A' &&
+	meta_name[0] <= 'Z') {
+      text_tarray::iterator METAVALUE_here = METAFIELD_here->second.values.begin();
+      text_tarray::iterator METAVALUE_end = METAFIELD_here->second.values.end();
+      while (METAVALUE_here!=METAVALUE_end) {
+	
+	metatag *tmptag = new metatag();
+	tmptag->name = meta_name.getcstr();
+	tmptag->type = "";
+	tmptag->scheme = "";
+	tmptag->value = (*METAVALUE_here).getcstr();
+	Metatag_list.push_back(tmptag);
+	
+	METAVALUE_here++;
+      }
+    }
+    
+    METAFIELD_here++;
+  }
+  return true; // succeeded
+
+}
+
+// *** implement this ***
+int ztest_fetch(void *handle, bend_fetch_rr *r)
+{
+  // *** called when client issues a "show" command, 2nd of 5
+    if (z3950_verbosity_>1) {
+      cerr << "Entering ztest_fetch" << endl;
+    }
+    char *cp;
+    r->errstring = 0;
+    r->last_in_set = 0;
+    r->basename = "DUMMY"; // this is set below
+    r->output_format = r->request_format;
+
+    // *** use this until found a good way of mapping Greenstone
+    // *** metadata fields to USMARC fields
+    if (r->request_format == VAL_SUTRS)
+    {
+      // copies record into r, errcode will be 13 if fails
+      text_t MetadataResult;
+      text_t CollectionName;
+      if (!get_sutrs_record(r->number, MetadataResult, CollectionName)) {
+	r->errcode = 13;
+	return 0;
+      } else {			
+	r->len = MetadataResult.size();
+	r->record = (char*) odr_malloc(r->stream, r->len+1);
+	char *tmptxt = MetadataResult.getcstr();
+	strcpy(r->record, tmptxt);
+	delete tmptxt;
+	r->basename = (char*) odr_malloc(r->stream, CollectionName.size()+1);
+	tmptxt = CollectionName.getcstr();
+	strcpy(r->basename, tmptxt);
+	delete tmptxt;
+      }
+    }
+    // *** do we want to use this format? ***
+    else if (r->request_format == VAL_GRS1)
+    {
+      // bail out, since we don't support grs (yet?)
+      r->errcode = 107; // "Query type not supported"
+      return 0;
+      
+    } 
+    // assume that here on in is some sort of MARC format
+    else {
+      marcrec *mrec = new marcrec;
+
+      mrec = (marcrec*) malloc(sizeof(*mrec));
+      
+      mrec->marcline = (char*) malloc(100000);
+      mrec->partitle = (char*) malloc(10000);
+      mrec->subtitle = (char*) malloc(10000);
+      mrec->year     = (char*) malloc(1000);
+      mrec->url      = (char*) malloc(1000);
+      mrec->fmat     = (char*) malloc(1000);
+      mrec->s008     = (char*) malloc(41);
+      
+      mrec->ncreators = 0;
+      mrec->ntitles   = 0;
+      *mrec->marcline = 0;
+      *mrec->subtitle = 0;
+      *mrec->partitle = 0;
+      *mrec->year     = 0;
+      *mrec->url      = 0;
+      *mrec->fmat     = 0;
+      strcpy(mrec->s008, "                                        ");
+
+      text_t CollectionName;
+      list<metatag*> Metatag_list;
+
+      if (!get_marc_record(r->number, Metatag_list, CollectionName)) {
+	r->errcode = 13;
+	return 0;
+      } else {
+	list<metatag*>::iterator METATAG_here = Metatag_list.begin();
+	list<metatag*>::iterator METATAG_end = Metatag_list.end();
+	while (METATAG_here != METATAG_end) {
+	  usMARC(*METATAG_here, mrec);
+	  METATAG_here++;
+	}
+
+	// set the date in the marc record to the current date
+	char today[32];
+	time_t d;
+	struct tm *time_struct;
+	//putenv("TZ=NFT-1DFT");
+	d = time(NULL);
+	time_struct = localtime(&d);
+	strftime(today, 16, "%y%m%d", time_struct);
+	put008(mrec->s008, today, F008_DATE_ENTERED);
+	put008(mrec->s008, "s", F008_TYPE_OF_DATE);
+
+	// to do: make this safer + more efficient
+	cp = new char[1000000];
+	char *cp2 = new char[1000000];
+	
+	switch(r->request_format) {
+	case VAL_DANMARC: {
+	  MARCtidy(mrec, cp, DANMARC);
+	  r->output_format = VAL_DANMARC;
+	  break; }
+	case VAL_FINMARC: {
+	  MARCtidy(mrec, cp, FINMARC);
+	  r->output_format = VAL_FINMARC;
+	  break; }
+	// YAZ doesn't know about ISMARC
+	/*
+	case VAL_ISMARC: {
+	  put008(mrec->s008, "k", F008_FORM_OF_PUBLICATION);
+	  MARCtidy(mrec, cp, ISMARC);
+	  r->output_format = VAL_ISMARC;
+	  break; }
+	*/
+	case VAL_NORMARC: {
+	  MARCtidy(mrec, cp, NORMARC);
+	  r->output_format = VAL_NORMARC;
+	  break; }
+	case VAL_SWEMARC: {
+	  MARCtidy(mrec, cp, SWEMARC);
+	  r->output_format = VAL_SWEMARC;
+	  break; }
+	default: {
+	  MARCtidy(mrec, cp, USMARC);
+	  r->output_format = VAL_USMARC;
+	  break; }
+	}
+	
+	sprintf(cp2, "%s", (char*) MARC2709(cp, 0, 6, 'n', 'm', ' '));
+	r->len = strlen(cp2);
+	r->record = (char*) odr_malloc(r->stream, r->len+1);
+	strcpy(r->record, cp2);     
+	r->basename = (char*) odr_malloc(r->stream, CollectionName.size()+1);
+	char *tmptxt;
+	tmptxt = CollectionName.getcstr();
+	strcpy(r->basename, tmptxt);
+	delete tmptxt;
+	delete cp2;      
+	cerr << "dumping record:`" << cp << "'" << endl;
+	delete cp;
+      }
+    }
+
+    r->errcode = 0;
+    return 0;
+}
+
+/*
+ * silly dummy-scan what reads words from a file.
+ */
+int ztest_scan(void *handle, bend_scan_rr *q)
+{
+  // *** called when client issues a "scan" command
+  if (z3950_verbosity_>1) {
+    cerr << "Entering ztest_scan" << endl;
+  }
+    
+  // bail out, since we don't support scan (yet?)
+  q->errcode = 107; // "Query type not supported"
+  return 0;
+
+    static FILE *f = 0;
+    static struct scan_entry list[200];
+    static char entries[200][80];
+    int hits[200];
+    char term[80], *p;
+    int i, pos;
+    int term_position_req = q->term_position;
+    int num_entries_req = q->num_entries;
+
+    q->errcode = 0;
+    q->errstring = 0;
+    q->entries = list;
+    q->status = BEND_SCAN_SUCCESS;
+    if (!f && !(f = fopen("dummy-words", "r")))
+    {
+	perror("dummy-words");
+	exit(1);
+    }
+    if (q->term->term->which != Z_Term_general)
+    {
+    	q->errcode = 229; /* unsupported term type */
+	return 0;
+    }
+    if (*q->step_size != 0)
+    {
+	q->errcode = 205; /*Only zero step size supported for Scan */
+	return 0;
+    }
+    if (q->term->term->u.general->len >= 80)
+    {
+    	q->errcode = 11; /* term too long */
+	return 0;
+    }
+    if (q->num_entries > 200)
+    {
+    	q->errcode = 31;
+	return 0;
+    }
+    memcpy(term, q->term->term->u.general->buf, q->term->term->u.general->len);
+    term[q->term->term->u.general->len] = '\0';
+    for (p = term; *p; p++)
+    	if (islower(*p))
+	    *p = toupper(*p);
+
+    fseek(f, 0, SEEK_SET);
+    q->num_entries = 0;
+
+    for (i = 0, pos = 0; fscanf(f, " %79[^:]:%d", entries[pos], &hits[pos]) == 2;
+	i++, pos < 199 ? pos++ : (pos = 0))
+    {
+    	if (!q->num_entries && strcmp(entries[pos], term) >= 0) /* s-point fnd */
+	{
+	    if ((q->term_position = term_position_req) > i + 1)
+	    {
+	    	q->term_position = i + 1;
+		q->status = BEND_SCAN_PARTIAL;
+	    }
+	    for (; q->num_entries < q->term_position; q->num_entries++)
+	    {
+	    	int po;
+
+		po = pos - q->term_position + q->num_entries+1; /* find pos */
+		if (po < 0)
+		    po += 200;
+
+		if (!strcmp (term, "SD") && q->num_entries == 2)
+		{
+		    list[q->num_entries].term = entries[pos];
+		    list[q->num_entries].occurrences = -1;
+		    list[q->num_entries].errcode = 233;
+		    list[q->num_entries].errstring = "SD for Scan Term";
+		}
+		else
+		{
+		    list[q->num_entries].term = entries[po];
+		    list[q->num_entries].occurrences = hits[po];
+		}
+	    }
+	}
+	else if (q->num_entries)
+	{
+	    list[q->num_entries].term = entries[pos];
+	    list[q->num_entries].occurrences = hits[pos];
+	    q->num_entries++;
+	}
+	if (q->num_entries >= num_entries_req)
+	    break;
+    }
+    if (feof(f))
+    	q->status = BEND_SCAN_PARTIAL;
+    return 0;
+}
+
+
+
+void bend_close(void *handle)
+{
+  if (z3950_verbosity_>1) {
+    cerr << "Entering bend_close" << endl;
+  }
+  delete Server;
+  delete Cservers;
+  delete Protocol;
+  if (z3950_verbosity_>1) {
+    cerr << "heap cleaned up, exiting bend_close" << endl;
+  }
+  return;
+}
+
+int main (int argc, char *argv[])
+{
+  
+  const int statserv_var =  statserv_main(argc, argv, bend_init, bend_close);
+  cerr << "statserv_main returns: " << statserv_var << endl;
+  return statserv_var;
+  
+  return 0;
+}
+
+
Index: /gsdl/stable/runtime-src/src/z3950/z3950server.h
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/z3950server.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/z3950server.h	(revision 20131)
@@ -0,0 +1,71 @@
+/**********************************************************************
+ *
+ * z3950server.h --
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+#ifndef Z3950SERVER_H
+#define Z3950ESRVER_H
+
+#include <string>
+#include <list>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <time.h>
+
+// Greenstone headers
+#include "fileutil.h"
+
+// the maximum number of hits allowed
+#define MAXHITS 10000
+
+// These globals are local to each thread: one Z39.50 connection = one thread.
+
+extern text_t gsdlhome; // this is specified externally when Greenstone is installed
+extern list<FilterResponse_t> Response_tlist; // list of response sets
+extern list<text_t> Response_tlist_colnames;  // collection names for the above
+extern list<int> Response_tlist_sizes;        // sizes (number of records) for the above
+extern z3950Server *Server;
+extern collectset *Cservers;
+extern nullproto *Protocol;
+extern map<text_t, gsdlCollection> Collection_map; // info and tools for collections
+extern map<text_t, text_t> Resultsets;             // mapping from ResultSetId to GSQuery 
+
+extern int z3950_verbosity_;
+
+bend_initresult *bend_init(bend_initrequest *q);
+void bend_close(void *handle);
+
+Z_GenericRecord *read_grs1(FILE *f, ODR o);
+
+int ztest_search (void *handle, bend_search_rr *rr);
+int ztest_sort (void *handle, bend_sort_rr *rr);
+int ztest_present (void *handle, bend_present_rr *rr);
+int ztest_esrequest (void *handle, bend_esrequest_rr *rr);
+int ztest_delete (void *handle, bend_delete_rr *rr);
+int ztest_fetch(void *handle, bend_fetch_rr *r);
+int ztest_scan(void *handle, bend_scan_rr *q);
+
+
+#endif
Index: /gsdl/stable/runtime-src/src/z3950/zparse.fl
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/zparse.fl	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/zparse.fl	(revision 20131)
@@ -0,0 +1,112 @@
+/* This is the lexical analyser - it returns tokens to the parsers.
+   This is used by both parsers - one for the build-time config files
+   and one for the run-time config files. Note the included file "parse.h"
+   is a symlink to the relevant header file. */
+
+%{
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/*#define YYSTYPE char * - YYSTYPE is defined in zparse.tab.h */
+#include "zparse.tab.h"
+
+/* forward declarations for std functions not picked up. */
+/*int fileno(FILE *);*/
+/*char *strdup(char *);*/
+
+int lineno=1;
+%}
+
+%option noyywrap
+
+COMMENT  \#.*(\n|\r)
+
+%x  STRINGCOND
+%%
+	char *string;
+	int string_len;
+
+{COMMENT}		lineno++;/*yylval.string=yytext;*/yyleng=0;
+,			return (',');
+:			return (':');
+\_			return ('_');
+\[GSDL[0-9]+\.[0-9]+\] yylval.string=yytext;return(GSDLVERSION);
+\[General\]		return (GENERAL_SECTION);
+\[Search\ [fF]ields\]	return (SEARCH_SECTION);
+\[Browse\ [fF]ields\]	return (BROWSE_SECTION);
+\[Macros\]		return (MACROS_SECTION);
+maintainer		return (MAINTAINER);
+Languages		return(LANGUAGES);
+About			return(ABOUT);
+Browse			return(BROWSE);
+Date[lL]ist		return(DATELIST);
+Document[aA]rrows[bB]ottom return(DOCUMENTARROWSBOTTOM);
+Document[bB]uttons	return(DOCUMENTBUTTONS);
+Document[hH]eader	return(DOCUMENTHEADER);
+Document[iI]mages	return(DOCUMENTIMAGES);
+Document[tT]ext		return(DOCUMENTTEXT);
+Icon[lL]ink		return(ICONLINK);
+List			return(LIST);
+Format			return(FORMAT);
+Name			return(NAME);
+Search[tT]ext		return(SEARCHTEXT);
+Section[lL]ist		return(SECTIONLIST);
+Sorted[lL]ist		return(SORTEDLIST);
+Sorted[sS]ection[lL]ist	return(SORTEDSECTIONLIST);
+Text[lL]ink		return(TEXTLINK);
+Type			return(TYPE);
+public			return (PUBLIC);
+true			return (TRUE);
+false			return (FALSE);
+^document		return (DOCUMENT);
+^section		return (SECTION);
+[iI]con			return (ICON);
+[sS]mall[iI]con		return (SMALLICON);
+\"			{string=NULL;BEGIN(STRINGCOND);}
+<STRINGCOND>{
+  ([^\"\\\n])*		{/* append this to our current string EXC NEWLINE */
+			if (string==NULL) string_len=0; else
+			string_len=strlen(string);
+			string=realloc(string,string_len+strlen(yytext)+1);
+			/* +1 is for trailing \0 */
+			strcpy(string+string_len,yytext);
+			}
+  ([^\"\\])*\n		{/* append this to our current string - INC NEWLINE */
+			lineno++;
+			if (string==NULL) string_len=0; else
+			string_len=strlen(string);
+			string=realloc(string,string_len+strlen(yytext)+1);
+			/* +1 is for trailing \0 */
+			strcpy(string+string_len,yytext);
+			}
+  "\\"\"		|
+  \"\"		{       /*replace quoted quote with one quote*/
+			string_len=strlen(string);
+			string=realloc(string,string_len+2);
+			string[string_len]='\"';
+			string[string_len+1]='\0';
+			}
+  \"		{
+			BEGIN(INITIAL);
+			yylval.string=string;
+			return(STRING);
+			  /* note that the string may have long bits of 
+			     whitespace in it that we could remove. */
+			}
+}
+[[:alnum:]@\.-]+	yylval.string=strdup(yytext);return (DATA);
+(" "|\t)		;
+(\n|\r)			lineno++;
+%%
+/******** deleted rules: *******
+en			return(EN);
+fr			return(FR);
+mi			return(MI);
+zh			return(ZH);
+de			return(DE);
+***************/
+
+
+
+
Index: /gsdl/stable/runtime-src/src/z3950/zparse.tab.c
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/zparse.tab.c	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/zparse.tab.c	(revision 20131)
@@ -0,0 +1,1531 @@
+/* A Bison parser, made by GNU Bison 1.875.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Written by Richard Stallman by simplifying the original so called
+   ``semantic'' parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     GSDLVERSION = 257,
+     GENERAL_SECTION = 258,
+     SEARCH_SECTION = 259,
+     BROWSE_SECTION = 260,
+     MACROS_SECTION = 261,
+     MAINTAINER = 262,
+     PUBLIC = 263,
+     TRUE = 264,
+     FALSE = 265,
+     LANGUAGES = 266,
+     EN = 267,
+     FR = 268,
+     MI = 269,
+     ZH = 270,
+     DE = 271,
+     NAME = 272,
+     STRING = 273,
+     ICON = 274,
+     SMALLICON = 275,
+     ABOUT = 276,
+     SEARCHTEXT = 277,
+     DOCUMENT = 278,
+     SECTION = 279,
+     BROWSE = 280,
+     TYPE = 281,
+     FORMAT = 282,
+     LIST = 283,
+     SORTEDLIST = 284,
+     SECTIONLIST = 285,
+     SORTEDSECTIONLIST = 286,
+     DATELIST = 287,
+     ICONLINK = 288,
+     TEXTLINK = 289,
+     DOCUMENTIMAGES = 290,
+     DOCUMENTHEADER = 291,
+     DOCUMENTTEXT = 292,
+     DOCUMENTBUTTONS = 293,
+     DOCUMENTARROWSBOTTOM = 294,
+     DATA = 295
+   };
+#endif
+#define GSDLVERSION 257
+#define GENERAL_SECTION 258
+#define SEARCH_SECTION 259
+#define BROWSE_SECTION 260
+#define MACROS_SECTION 261
+#define MAINTAINER 262
+#define PUBLIC 263
+#define TRUE 264
+#define FALSE 265
+#define LANGUAGES 266
+#define EN 267
+#define FR 268
+#define MI 269
+#define ZH 270
+#define DE 271
+#define NAME 272
+#define STRING 273
+#define ICON 274
+#define SMALLICON 275
+#define ABOUT 276
+#define SEARCHTEXT 277
+#define DOCUMENT 278
+#define SECTION 279
+#define BROWSE 280
+#define TYPE 281
+#define FORMAT 282
+#define LIST 283
+#define SORTEDLIST 284
+#define SECTIONLIST 285
+#define SORTEDSECTIONLIST 286
+#define DATELIST 287
+#define ICONLINK 288
+#define TEXTLINK 289
+#define DOCUMENTIMAGES 290
+#define DOCUMENTHEADER 291
+#define DOCUMENTTEXT 292
+#define DOCUMENTBUTTONS 293
+#define DOCUMENTARROWSBOTTOM 294
+#define DATA 295
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 27 "zparse.y"
+
+  /* verbatim C code - functions, etc */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "z3950cfg.h" /* structure types, and #define of yyin/yyparse */
+
+#define YYDEBUG 1
+#define YYERROR_VERBOSE 1
+char defLanguage=0;
+
+/* defined in parse.fl */
+extern int lineno;
+
+#ifndef YYRECOVERING
+int YYRECOVERING=0; /* this is supposed to already be defined as a macro */
+#endif
+
+/* defined in z3950proto.cpp */
+struct z3950cfg *zserver_list=NULL;
+
+/* this is set in z3950proto.cpp */
+FILE *errfile;
+
+int yylex(void);
+
+int yyerror(char *string);
+
+void errormsg(char *str);
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 61 "zparse.y"
+typedef union YYSTYPE {
+  char *string;
+  struct z3950cfg *cfg;
+  struct z3950aboutlist *about;
+  int number;
+} YYSTYPE;
+/* Line 191 of yacc.c.  */
+#line 197 "zparse.tab.c"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 214 of yacc.c.  */
+#line 209 "zparse.tab.c"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# if YYSTACK_USE_ALLOCA
+#  define YYSTACK_ALLOC alloca
+# else
+#  ifndef YYSTACK_USE_ALLOCA
+#   if defined (alloca) || defined (_ALLOCA_H)
+#    define YYSTACK_ALLOC alloca
+#   else
+#    ifdef __GNUC__
+#     define YYSTACK_ALLOC __builtin_alloca
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+#  if defined (__STDC__) || defined (__cplusplus)
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   define YYSIZE_T size_t
+#  endif
+#  define YYSTACK_ALLOC malloc
+#  define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+	 || (YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE))				\
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  register YYSIZE_T yyi;		\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+   typedef signed char yysigned_char;
+#else
+   typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL  4
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   44
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS  44
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS  13
+/* YYNRULES -- Number of rules. */
+#define YYNRULES  28
+/* YYNRULES -- Number of states. */
+#define YYNSTATES  37
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   296
+
+#define YYTRANSLATE(YYX) 						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const unsigned char yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    42,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,    43,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     3,     4,     5,
+       6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
+      26,    27,    28,    29,    30,    31,    32,    33,    34,    35,
+      36,    37,    38,    39,    40,    41,     2
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const unsigned char yyprhs[] =
+{
+       0,     0,     3,     6,     8,    10,    11,    14,    16,    25,
+      27,    29,    30,    33,    34,    37,    40,    41,    44,    47,
+      48,    50,    51,    53,    56,    60,    63,    67,    69
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+      45,     0,    -1,    46,    47,    -1,    46,    -1,     3,    -1,
+      -1,    47,    48,    -1,    48,    -1,    41,    41,    50,    41,
+      49,    51,    52,    53,    -1,     1,    -1,    19,    -1,    -1,
+      42,    41,    -1,    -1,    20,    19,    -1,    20,    41,    -1,
+      -1,    21,    19,    -1,    21,    41,    -1,    -1,    54,    -1,
+      -1,    55,    -1,    54,    55,    -1,    22,    56,    19,    -1,
+      22,    19,    -1,    41,    43,    41,    -1,    41,    -1,     1,
+      -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const unsigned char yyrline[] =
+{
+       0,   106,   106,   107,   110,   111,   113,   114,   116,   137,
+     141,   142,   147,   148,   151,   152,   155,   156,   157,   162,
+     164,   165,   167,   169,   172,   183,   205,   213,   221
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "GSDLVERSION", "GENERAL_SECTION", 
+  "SEARCH_SECTION", "BROWSE_SECTION", "MACROS_SECTION", "MAINTAINER", 
+  "PUBLIC", "TRUE", "FALSE", "LANGUAGES", "EN", "FR", "MI", "ZH", "DE", 
+  "NAME", "STRING", "ICON", "SMALLICON", "ABOUT", "SEARCHTEXT", 
+  "DOCUMENT", "SECTION", "BROWSE", "TYPE", "FORMAT", "LIST", "SORTEDLIST", 
+  "SECTIONLIST", "SORTEDSECTIONLIST", "DATELIST", "ICONLINK", "TEXTLINK", 
+  "DOCUMENTIMAGES", "DOCUMENTHEADER", "DOCUMENTTEXT", "DOCUMENTBUTTONS", 
+  "DOCUMENTARROWSBOTTOM", "DATA", "':'", "'_'", "$accept", "z3950", 
+  "version", "zserverlist", "zserver", "name", "port", "icon", 
+  "smallicon", "about", "aboutList", "aboutLang", "lang", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const unsigned short yytoknum[] =
+{
+       0,   256,   296,   257,   258,   259,   260,   261,   262,   263,
+     264,   265,   266,   267,   268,   269,   270,   271,   272,   273,
+     274,   275,   276,   277,   278,   279,   280,   281,   282,   283,
+     284,   285,   286,   287,   288,   289,   290,   291,   292,   293,
+     294,   295,    58,    95
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const unsigned char yyr1[] =
+{
+       0,    44,    45,    45,    46,    46,    47,    47,    48,    48,
+      49,    49,    50,    50,    51,    51,    51,    52,    52,    52,
+      53,    53,    54,    54,    55,    55,    56,    56,    56
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const unsigned char yyr2[] =
+{
+       0,     2,     2,     1,     1,     0,     2,     1,     8,     1,
+       1,     0,     2,     0,     2,     2,     0,     2,     2,     0,
+       1,     0,     1,     2,     3,     2,     3,     1,     1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const unsigned char yydefact[] =
+{
+       5,     4,     0,     0,     1,     9,     0,     0,     7,    13,
+       6,     0,     0,    12,    11,    10,    16,     0,    19,    14,
+      15,     0,    21,    17,    18,     0,     8,    20,    22,    28,
+      25,    27,     0,    23,     0,    24,    26
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yysigned_char yydefgoto[] =
+{
+      -1,     2,     3,     7,     8,    16,    12,    18,    22,    26,
+      27,    28,    32
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -33
+static const yysigned_char yypact[] =
+{
+       4,   -33,     8,     0,   -33,   -33,   -32,     2,   -33,   -31,
+     -33,   -29,   -28,   -33,    -9,   -33,    -6,   -14,    -5,   -33,
+     -33,   -13,    -7,   -33,   -33,     3,   -33,    -7,   -33,   -33,
+     -33,   -26,    -1,   -33,   -22,   -33,   -33
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yysigned_char yypgoto[] =
+{
+     -33,   -33,   -33,   -33,    13,   -33,   -33,   -33,   -33,   -33,
+     -33,    -4,   -33
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -4
+static const yysigned_char yytable[] =
+{
+      -3,     5,    -2,     5,    29,    19,    23,     1,     4,     9,
+      15,    11,    13,    14,    17,    25,    21,    34,    35,    36,
+      10,     0,    30,    33,     0,     0,     0,    20,    24,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     6,     0,     6,    31
+};
+
+static const yysigned_char yycheck[] =
+{
+       0,     1,     0,     1,     1,    19,    19,     3,     0,    41,
+      19,    42,    41,    41,    20,    22,    21,    43,    19,    41,
+       7,    -1,    19,    27,    -1,    -1,    -1,    41,    41,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    41,    -1,    41,    41
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const unsigned char yystos[] =
+{
+       0,     3,    45,    46,     0,     1,    41,    47,    48,    41,
+      48,    42,    50,    41,    41,    19,    49,    20,    51,    19,
+      41,    21,    52,    19,    41,    22,    53,    54,    55,     1,
+      19,    41,    56,    55,    43,    19,    41
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrlab1
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    { 								\
+      yyerror ("syntax error: cannot back up");\
+      YYERROR;							\
+    }								\
+while (0)
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+   are run).  */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)         \
+  Current.first_line   = Rhs[1].first_line;      \
+  Current.first_column = Rhs[1].first_column;    \
+  Current.last_line    = Rhs[N].last_line;       \
+  Current.last_column  = Rhs[N].last_column;
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (0)
+
+# define YYDSYMPRINT(Args)			\
+do {						\
+  if (yydebug)					\
+    yysymprint Args;				\
+} while (0)
+
+# define YYDSYMPRINTF(Title, Token, Value, Location)		\
+do {								\
+  if (yydebug)							\
+    {								\
+      YYFPRINTF (stderr, "%s ", Title);				\
+      yysymprint (stderr, 					\
+                  Token, Value);	\
+      YYFPRINTF (stderr, "\n");					\
+    }								\
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (cinluded).                                                   |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short *bottom, short *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    short *bottom;
+    short *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (/* Nothing. */; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+    int yyrule;
+#endif
+{
+  int yyi;
+  unsigned int yylineno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+             yyrule - 1, yylineno);
+  /* Print the symbols being reduced, and their result.  */
+  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+    YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+  YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (Rule);		\
+} while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
+{
+  register const char *yys = yystr;
+
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
+{
+  register char *yyd = yydest;
+  register const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  if (yytype < YYNTOKENS)
+    {
+      YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+      YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+    }
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+  YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yytype, yyvaluep)
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  switch (yytype)
+    {
+
+      default:
+        break;
+    }
+}
+
+
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The lookahead symbol.  */
+int yychar;
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+  void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
+  register int yystate;
+  register int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  short	yyssa[YYINITDEPTH];
+  short *yyss = yyssa;
+  register short *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule.  */
+  int yylen;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack. Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	short *yyss1 = yyss;
+
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow ("parser stack overflow",
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+
+		    &yystacksize);
+
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyoverflowlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyoverflowlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	short *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyoverflowlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+  YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 106 "zparse.y"
+    {zserver_list=yyvsp[0].cfg;}
+    break;
+
+  case 3:
+#line 107 "zparse.y"
+    {zserver_list=NULL;}
+    break;
+
+  case 4:
+#line 110 "zparse.y"
+    {;}
+    break;
+
+  case 5:
+#line 111 "zparse.y"
+    {fprintf(errfile,"No version - not GSDL config file?\n");return(1);}
+    break;
+
+  case 6:
+#line 113 "zparse.y"
+    {if (yyvsp[0].cfg!=NULL) {yyvsp[0].cfg->next=yyvsp[-1].cfg;yyval.cfg=yyvsp[0].cfg;}}
+    break;
+
+  case 8:
+#line 117 "zparse.y"
+    {
+		     if (YYRECOVERING)
+		       {yyval.cfg=NULL;YYRECOVERING=0;} 
+		     else {
+		       if((yyval.cfg=malloc(sizeof(struct z3950cfg)))==NULL)
+			 {
+			   fprintf(errfile,"malloc failed\n");
+			   return(1);
+			 }
+		       yyval.cfg->shortname=yyvsp[-7].string;
+		       yyval.cfg->hostname=yyvsp[-6].string;
+		       yyval.cfg->port=yyvsp[-5].number;
+		       yyval.cfg->dbname=yyvsp[-4].string;
+		       yyval.cfg->longname=yyvsp[-3].string;
+		       yyval.cfg->icon=yyvsp[-2].string;
+		       yyval.cfg->smallicon=yyvsp[-1].string;
+		       yyval.cfg->about=yyvsp[0].about;
+		       yyval.cfg->next=NULL;
+		     }
+		   }
+    break;
+
+  case 9:
+#line 137 "zparse.y"
+    {yyval.cfg=NULL;
+	      fprintf(errfile,"discarding zserver (line %d)\n",lineno);}
+    break;
+
+  case 10:
+#line 141 "zparse.y"
+    {;}
+    break;
+
+  case 11:
+#line 142 "zparse.y"
+    {errormsg("Database name needs to be followed by a short "
+			  "descriptive name (enclosed in \" marks)");
+	         yyval.string=NULL;
+	         YYRECOVERING=1;}
+    break;
+
+  case 12:
+#line 147 "zparse.y"
+    {yyval.number=atoi(yyvsp[0].string);}
+    break;
+
+  case 13:
+#line 148 "zparse.y"
+    {yyval.number=210;}
+    break;
+
+  case 14:
+#line 151 "zparse.y"
+    {yyval.string=yyvsp[0].string;}
+    break;
+
+  case 15:
+#line 152 "zparse.y"
+    {yyval.string=yyvsp[0].string;
+                  errormsg("Icon must be enclosed in quotes");
+	      yylex();yylex();}
+    break;
+
+  case 16:
+#line 155 "zparse.y"
+    {yyval.string=NULL;}
+    break;
+
+  case 17:
+#line 156 "zparse.y"
+    {yyval.string=yyvsp[0].string;}
+    break;
+
+  case 18:
+#line 157 "zparse.y"
+    {yyval.string=yyvsp[0].string;
+	      /* this is because of the ':' */
+              errormsg("Smallicon must be enclosed in quotes.\n");
+	      yylex();yylex();
+	      }
+    break;
+
+  case 19:
+#line 162 "zparse.y"
+    {yyval.string=NULL;}
+    break;
+
+  case 20:
+#line 164 "zparse.y"
+    {defLanguage=0;}
+    break;
+
+  case 21:
+#line 165 "zparse.y"
+    {yyval.about=NULL;}
+    break;
+
+  case 22:
+#line 167 "zparse.y"
+    {;}
+    break;
+
+  case 23:
+#line 169 "zparse.y"
+    {yyval.about=yyvsp[0].about;yyvsp[0].about->next=yyvsp[-1].about;}
+    break;
+
+  case 24:
+#line 173 "zparse.y"
+    {
+			       if((yyval.about=malloc(sizeof(struct z3950aboutlist)))
+				  ==NULL) {
+				 fprintf(errfile,"Malloc failed\n");
+				 return(1);
+			       }
+			       yyval.about->lang=yyvsp[-1].string;
+			       yyval.about->text=yyvsp[0].string;
+			       yyval.about->next=NULL;
+			     }
+    break;
+
+  case 25:
+#line 184 "zparse.y"
+    {
+			       if (defLanguage)
+		                 {
+				   fprintf(errfile,"warning: (line %d): already have a default language in config file\n",lineno);
+				 }
+			       else defLanguage=1;
+			       
+			       if((yyval.about=malloc(sizeof(struct z3950aboutlist)))
+				  ==NULL) {
+				 fprintf(errfile,"Malloc failed\n");
+				 return(1);
+			       }
+			       yyval.about->lang=NULL; /* default lang... */
+			       yyval.about->text=yyvsp[0].string;
+			       yyval.about->next=NULL;
+			     }
+    break;
+
+  case 26:
+#line 206 "zparse.y"
+    {
+			       yyval.string=malloc(strlen(yyvsp[-2].string)+strlen(yyvsp[0].string)+1);
+			       strncpy(yyval.string,yyvsp[-2].string,strlen(yyvsp[-2].string));
+			       yyval.string[strlen(yyvsp[-2].string)]='_';
+			       strncpy(yyval.string+strlen(yyvsp[-2].string)+1,yyvsp[0].string,strlen(yyvsp[0].string));
+			       free(yyvsp[-2].string);free(yyvsp[0].string);
+			     }
+    break;
+
+  case 27:
+#line 213 "zparse.y"
+    {;}
+    break;
+
+  case 28:
+#line 221 "zparse.y"
+    {errormsg("missing language");}
+    break;
+
+
+    }
+
+/* Line 999 of yacc.c.  */
+#line 1309 "zparse.tab.c"
+
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+
+
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (YYPACT_NINF < yyn && yyn < YYLAST)
+	{
+	  YYSIZE_T yysize = 0;
+	  int yytype = YYTRANSLATE (yychar);
+	  char *yymsg;
+	  int yyx, yycount;
+
+	  yycount = 0;
+	  /* Start YYX at -YYN if negative to avoid negative indexes in
+	     YYCHECK.  */
+	  for (yyx = yyn < 0 ? -yyn : 0;
+	       yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+	    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	      yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+	  yysize += yystrlen ("syntax error, unexpected ") + 1;
+	  yysize += yystrlen (yytname[yytype]);
+	  yymsg = (char *) YYSTACK_ALLOC (yysize);
+	  if (yymsg != 0)
+	    {
+	      char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+	      yyp = yystpcpy (yyp, yytname[yytype]);
+
+	      if (yycount < 5)
+		{
+		  yycount = 0;
+		  for (yyx = yyn < 0 ? -yyn : 0;
+		       yyx < (int) (sizeof (yytname) / sizeof (char *));
+		       yyx++)
+		    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+		      {
+			const char *yyq = ! yycount ? ", expecting " : " or ";
+			yyp = yystpcpy (yyp, yyq);
+			yyp = yystpcpy (yyp, yytname[yyx]);
+			yycount++;
+		      }
+		}
+	      yyerror (yymsg);
+	      YYSTACK_FREE (yymsg);
+	    }
+	  else
+	    yyerror ("syntax error; also virtual memory exhausted");
+	}
+      else
+#endif /* YYERROR_VERBOSE */
+	yyerror ("syntax error");
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+	 error, discard it.  */
+
+      /* Return failure if at end of input.  */
+      if (yychar == YYEOF)
+        {
+	  /* Pop the error token.  */
+          YYPOPSTACK;
+	  /* Pop the rest of the stack.  */
+	  while (yyss < yyssp)
+	    {
+	      YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+	      yydestruct (yystos[*yyssp], yyvsp);
+	      YYPOPSTACK;
+	    }
+	  YYABORT;
+        }
+
+      YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
+      yydestruct (yytoken, &yylval);
+      yychar = YYEMPTY;
+
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*----------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action.  |
+`----------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+      YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+      yydestruct (yystos[yystate], yyvsp);
+      yyvsp--;
+      yystate = *--yyssp;
+
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  YYDPRINTF ((stderr, "Shifting error token, "));
+
+  *++yyvsp = yylval;
+
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here.  |
+`----------------------------------------------*/
+yyoverflowlab:
+  yyerror ("parser stack overflow");
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+  return yyresult;
+}
+
+
+#line 106 "zparse.y"
+
+/*int strncasecmp (const char *, const char *,size_t);*/
+int yyerror(char *string) {
+  fprintf(errfile,"Parse error (line %d) near \n\"%s\"<---:%s\n",lineno,
+	  yylval.string,string);
+  return(1);
+}
+
+void errormsg(char *str) {
+  fprintf(errfile,"Err (line %d, near \"%s\"): %s.\n",lineno,
+	  yylval.string,str);
+}
+
+/* *
+int main (int argc, char *argv[]) {
+  if (argc==2)
+    if (argv[1][0]=='-'&&argv[1][1]=='d')
+      yydebug=1;
+
+  yyparse();
+  return(0);
+}
+* */
+
Index: /gsdl/stable/runtime-src/src/z3950/zparse.tab.h
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/zparse.tab.h	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/zparse.tab.h	(revision 20131)
@@ -0,0 +1,134 @@
+/* A Bison parser, made by GNU Bison 1.875.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     GSDLVERSION = 257,
+     GENERAL_SECTION = 258,
+     SEARCH_SECTION = 259,
+     BROWSE_SECTION = 260,
+     MACROS_SECTION = 261,
+     MAINTAINER = 262,
+     PUBLIC = 263,
+     TRUE = 264,
+     FALSE = 265,
+     LANGUAGES = 266,
+     EN = 267,
+     FR = 268,
+     MI = 269,
+     ZH = 270,
+     DE = 271,
+     NAME = 272,
+     STRING = 273,
+     ICON = 274,
+     SMALLICON = 275,
+     ABOUT = 276,
+     SEARCHTEXT = 277,
+     DOCUMENT = 278,
+     SECTION = 279,
+     BROWSE = 280,
+     TYPE = 281,
+     FORMAT = 282,
+     LIST = 283,
+     SORTEDLIST = 284,
+     SECTIONLIST = 285,
+     SORTEDSECTIONLIST = 286,
+     DATELIST = 287,
+     ICONLINK = 288,
+     TEXTLINK = 289,
+     DOCUMENTIMAGES = 290,
+     DOCUMENTHEADER = 291,
+     DOCUMENTTEXT = 292,
+     DOCUMENTBUTTONS = 293,
+     DOCUMENTARROWSBOTTOM = 294,
+     DATA = 295
+   };
+#endif
+#define GSDLVERSION 257
+#define GENERAL_SECTION 258
+#define SEARCH_SECTION 259
+#define BROWSE_SECTION 260
+#define MACROS_SECTION 261
+#define MAINTAINER 262
+#define PUBLIC 263
+#define TRUE 264
+#define FALSE 265
+#define LANGUAGES 266
+#define EN 267
+#define FR 268
+#define MI 269
+#define ZH 270
+#define DE 271
+#define NAME 272
+#define STRING 273
+#define ICON 274
+#define SMALLICON 275
+#define ABOUT 276
+#define SEARCHTEXT 277
+#define DOCUMENT 278
+#define SECTION 279
+#define BROWSE 280
+#define TYPE 281
+#define FORMAT 282
+#define LIST 283
+#define SORTEDLIST 284
+#define SECTIONLIST 285
+#define SORTEDSECTIONLIST 286
+#define DATELIST 287
+#define ICONLINK 288
+#define TEXTLINK 289
+#define DOCUMENTIMAGES 290
+#define DOCUMENTHEADER 291
+#define DOCUMENTTEXT 292
+#define DOCUMENTBUTTONS 293
+#define DOCUMENTARROWSBOTTOM 294
+#define DATA 295
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 61 "zparse.y"
+typedef union YYSTYPE {
+  char *string;
+  struct z3950cfg *cfg;
+  struct z3950aboutlist *about;
+  int number;
+} YYSTYPE;
+/* Line 1240 of yacc.c.  */
+#line 125 "zparse.tab.h"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE yylval;
+
+
+
Index: /gsdl/stable/runtime-src/src/z3950/zparse.y
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/zparse.y	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/zparse.y	(revision 20131)
@@ -0,0 +1,252 @@
+/* RUN-TIME CONFIGURATION FILE PARSER */
+/**********************************************************************
+ *
+ * zparse.y --
+ * Copyright (C) 2000  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *********************************************************************/
+
+%{
+  /* verbatim C code - functions, etc */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "z3950cfg.h" /* structure types, and #define of yyin/yyparse */
+
+#define YYDEBUG 1
+#define YYERROR_VERBOSE 1
+char defLanguage=0;
+
+/* defined in parse.fl */
+extern int lineno;
+
+#ifndef YYRECOVERING
+int YYRECOVERING=0; /* this is supposed to already be defined as a macro */
+#endif
+
+/* defined in z3950proto.cpp */
+struct z3950cfg *zserver_list=NULL;
+
+/* this is set in z3950proto.cpp */
+FILE *errfile;
+
+int yylex(void);
+
+int yyerror(char *string);
+
+void errormsg(char *str);
+
+%}
+
+
+%union {
+  char *string;
+  struct z3950cfg *cfg;
+  struct z3950aboutlist *about;
+  int number;
+}
+
+
+/* keywords */
+/***** NOTE: can explicitly give values for each token, AND
+give a string for the token name eg 
+%token GSDLVERSION 257  "Version"
+*******/
+%token GSDLVERSION 257
+%token GENERAL_SECTION 258 SEARCH_SECTION 259 
+%token BROWSE_SECTION 260 MACROS_SECTION 261
+%token MAINTAINER 262
+%token PUBLIC 263
+%token TRUE 264 FALSE 265
+%token LANGUAGES 266 EN 267 FR 268 MI 269 ZH 270 DE 271
+%token NAME 272
+%token <string> STRING 273
+%token ICON 274 SMALLICON 275
+%token ABOUT 276
+%token SEARCHTEXT 277
+%token DOCUMENT 278 SECTION 279
+%token BROWSE 280 TYPE 281 FORMAT 282
+/* classifiers */
+%token  LIST 283 SORTEDLIST 284 SECTIONLIST 285 SORTEDSECTIONLIST 286 
+%token DATELIST 287
+/* formats */
+%token  ICONLINK 288 TEXTLINK 289
+/* layouts */
+%token  DOCUMENTIMAGES 290 DOCUMENTHEADER 291 DOCUMENTTEXT 292
+%token  DOCUMENTBUTTONS 293 DOCUMENTARROWSBOTTOM 294
+
+/* all other text */
+%token <string> DATA 295
+
+%type <cfg>      zserver zserverlist
+%type <number>  port
+%type <string>   icon smallicon lang name
+%type <about>    about aboutLang aboutList
+%%
+/* grammar */
+z3950         : version zserverlist {zserver_list=$2;}
+              | version {zserver_list=NULL;} /* if all commented out or none... */
+
+
+version       : GSDLVERSION {;}
+              | {fprintf(errfile,"No version - not GSDL config file?\n");return(1);}
+
+zserverlist   : zserverlist zserver {if ($2!=NULL) {$2->next=$1;$$=$2;}}
+              | zserver ;
+
+zserver       : DATA DATA port DATA name icon smallicon about 
+                   {
+		     if (YYRECOVERING)
+		       {$$=NULL;YYRECOVERING=0;} 
+		     else {
+		       if(($$=malloc(sizeof(struct z3950cfg)))==NULL)
+			 {
+			   fprintf(errfile,"malloc failed\n");
+			   return(1);
+			 }
+		       $$->shortname=$1;
+		       $$->hostname=$2;
+		       $$->port=$3;
+		       $$->dbname=$4;
+		       $$->longname=$5;
+		       $$->icon=$6;
+		       $$->smallicon=$7;
+		       $$->about=$8;
+		       $$->next=NULL;
+		     }
+		   }
+              | error {$$=NULL;
+	      fprintf(errfile,"discarding zserver (line %d)\n",lineno);}
+              ;
+
+name          : STRING {;}
+              | {errormsg("Database name needs to be followed by a short "
+			  "descriptive name (enclosed in \" marks)");
+	         $$=NULL;
+	         YYRECOVERING=1;} /* we should scrap this server */
+
+port          : ':' DATA {$$=atoi($2);}
+              | {$$=210;} /* default z39.50 server port */
+              ;
+
+icon          : ICON STRING {$$=$2;}
+              | ICON DATA {$$=$2;
+                  errormsg("Icon must be enclosed in quotes");
+	      yylex();yylex();}
+              | {$$=NULL;}
+smallicon     : SMALLICON STRING {$$=$2;}
+              | SMALLICON DATA {$$=$2;
+	      /* this is because of the ':' */
+              errormsg("Smallicon must be enclosed in quotes.\n");
+	      yylex();yylex();
+	      }
+              | {$$=NULL;}
+
+about         : aboutList {defLanguage=0;}
+              | {$$=NULL;}
+
+aboutList     : aboutLang {;}
+                      /* note this action reverses the order of the list */
+              | aboutList aboutLang {$$=$2;$2->next=$1;} 
+
+
+aboutLang     : ABOUT lang STRING 
+                             {
+			       if(($$=malloc(sizeof(struct z3950aboutlist)))
+				  ==NULL) {
+				 fprintf(errfile,"Malloc failed\n");
+				 return(1);
+			       }
+			       $$->lang=$2;
+			       $$->text=$3;
+			       $$->next=NULL;
+			     }
+              | ABOUT STRING 
+                             {
+			       if (defLanguage)
+		                 {
+				   fprintf(errfile,"warning: (line %d): already have a default language in config file\n",lineno);
+				 }
+			       else defLanguage=1;
+			       
+			       if(($$=malloc(sizeof(struct z3950aboutlist)))
+				  ==NULL) {
+				 fprintf(errfile,"Malloc failed\n");
+				 return(1);
+			       }
+			       $$->lang=NULL; /* default lang... */
+			       $$->text=$2;
+			       $$->next=NULL;
+			     }
+/* this can only happen once (default lang) */
+
+
+/* languages should be done using a lookup, rather than hard-coding 
+   them as tokens. Also '_' token for en_BR */
+lang          : DATA '_' DATA 
+                             {
+			       $$=malloc(strlen($1)+strlen($3)+1);
+			       strncpy($$,$1,strlen($1));
+			       $$[strlen($1)]='_';
+			       strncpy($$+strlen($1)+1,$3,strlen($3));
+			       free($1);free($3);
+			     }
+              | DATA {;}
+/*lang '_' DATA {;} */
+/*              | EN {;}
+		| FR {;}
+		| MI {;}
+		| ZH {;}
+		| DE {;}
+		| DATA {errormsg("unknown language");}*/
+              | error {errormsg("missing language");}
+
+/*documentHeader : DOCUMENTHEADER STRING {;}
+              | {;}
+
+documentText  : DOCUMENTTEXT STRING {;}
+              | {;}
+*/
+
+%%
+/*int strncasecmp (const char *, const char *,size_t);*/
+int yyerror(char *string) {
+  fprintf(errfile,"Parse error (line %d) near \n\"%s\"<---:%s\n",lineno,
+	  yylval.string,string);
+  return(1);
+}
+
+void errormsg(char *str) {
+  fprintf(errfile,"Err (line %d, near \"%s\"): %s.\n",lineno,
+	  yylval.string,str);
+}
+
+/* *
+int main (int argc, char *argv[]) {
+  if (argc==2)
+    if (argv[1][0]=='-'&&argv[1][1]=='d')
+      yydebug=1;
+
+  yyparse();
+  return(0);
+}
+* */
Index: /gsdl/stable/runtime-src/src/z3950/zparse.yy.c
===================================================================
--- /gsdl/stable/runtime-src/src/z3950/zparse.yy.c	(revision 20131)
+++ /gsdl/stable/runtime-src/src/z3950/zparse.yy.c	(revision 20131)
@@ -0,0 +1,1969 @@
+#define yy_create_buffer zconfig_create_buffer
+#define yy_delete_buffer zconfig_delete_buffer
+#define yy_scan_buffer zconfig_scan_buffer
+#define yy_scan_string zconfig_scan_string
+#define yy_scan_bytes zconfig_scan_bytes
+#define yy_flex_debug zconfig_flex_debug
+#define yy_init_buffer zconfig_init_buffer
+#define yy_flush_buffer zconfig_flush_buffer
+#define yy_load_buffer_state zconfig_load_buffer_state
+#define yy_switch_to_buffer zconfig_switch_to_buffer
+#define yyin zconfigin
+#define yyleng zconfigleng
+#define yylex zconfiglex
+#define yyout zconfigout
+#define yyrestart zconfigrestart
+#define yytext zconfigtext
+
+#line 19 "zparse.yy.c"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header$
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ * 	if ( condition_holds )
+ *		yyless( 5 );
+ *	else
+ *		do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		*yy_cp = yy_hold_char; \
+		YY_RESTORE_YY_MORE_OFFSET \
+		yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+	};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	yytext_ptr = yy_bp; \
+	yyleng = (int) (yy_cp - yy_bp); \
+	yy_hold_char = *yy_cp; \
+	*yy_cp = '\0'; \
+	yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 46
+#define YY_END_OF_BUFFER 47
+static yyconst short int yy_accept[274] =
+    {   0,
+        0,    0,   38,   38,   47,   46,   44,   45,   37,   46,
+        2,   43,    3,   43,   43,   43,   43,   43,   43,   43,
+       43,   43,   46,    4,   43,   43,   43,   43,   43,   43,
+       43,   43,   38,   39,   42,   46,    0,    1,    1,   43,
+       43,   43,   43,   43,   43,   43,   43,   43,   43,   43,
+       43,   43,   43,   43,    0,    0,    0,    0,   43,   43,
+       43,   43,   43,   43,   43,   38,   39,    0,   41,   40,
+       43,   43,   43,   43,   43,   43,   43,   43,   43,   43,
+       43,   43,   43,   43,   43,    0,    0,    0,    0,    0,
+       43,   43,   43,   43,   43,   43,   43,   43,   43,   43,
+
+       43,   43,   35,   43,   21,   23,   43,   43,   43,   43,
+       43,   29,    0,    0,    0,    0,    0,   43,   35,   43,
+       43,   31,   43,   43,   12,   43,   43,   43,   43,   43,
+       43,   43,   43,   43,   43,   43,    0,    0,    0,    0,
+        0,   32,   43,   43,   43,   43,   13,   43,   43,   22,
+       43,   43,   43,   43,   43,   43,   43,    0,    0,    0,
+        0,    0,   43,   30,   43,   43,   43,   43,   43,   43,
+       43,   43,   43,   43,   43,   43,    0,    0,    0,    0,
+        0,   43,   43,   34,   14,   43,   20,   43,   43,   43,
+       43,   43,   43,   28,    0,    0,    0,    9,    0,   43,
+
+       33,   43,   43,   43,   43,   43,   11,   43,   43,   36,
+       43,   43,    0,    5,    6,    0,   43,   43,   43,   43,
+       43,   43,   24,   43,   26,   43,    0,    0,   10,   43,
+       43,   43,   43,   43,   25,   43,    0,    0,   43,   43,
+       43,   43,   19,   43,    0,    0,   43,   43,   43,   43,
+       43,    0,    0,   43,   43,   17,   18,   43,    0,    0,
+       43,   16,   43,    8,    7,   43,   43,   43,   27,   43,
+       43,   15,    0
+    } ;
+
+static yyconst int yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    5,    1,    6,    7,    1,    1,    1,    1,    1,
+        1,    1,    1,    8,    9,   10,    1,   11,   11,   11,
+       11,   11,   11,   11,   11,   11,   11,   12,    1,    1,
+        1,    1,    1,    9,   13,   14,    9,   15,    9,   16,
+       17,   18,   19,    9,    9,   20,   21,   22,    9,    9,
+        9,    9,   23,   24,    9,    9,    9,    9,    9,    9,
+       25,   26,   27,    1,   28,    1,   29,   30,   31,   32,
+
+       33,   34,   35,   36,   37,    9,   38,   39,   40,   41,
+       42,   43,    9,   44,   45,   46,   47,    9,   48,   49,
+       50,    9,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst int yy_meta[51] =
+    {   0,
+        1,    1,    1,    1,    1,    2,    1,    1,    3,    3,
+        3,    1,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    1,    2,    1,    1,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3
+    } ;
+
+static yyconst short int yy_base[279] =
+    {   0,
+        0,   19,   49,   50,  331,  332,  332,  332,  332,   54,
+      332,    0,  332,  300,  285,   25,  286,  296,   31,  297,
+       29,   28,   49,  332,  296,  293,  294,  275,  281,  276,
+      277,   40,  315,  314,  310,  309,   78,  332,   80,    0,
+      272,  271,  266,  280,  266,  267,  267,  262,  266,   48,
+      276,  260,  254,  259,  257,   62,  271,  266,  259,  255,
+      259,  265,  247,  262,  261,  288,  287,  286,  332,  332,
+      241,  239,  253,  238,  244,  242,  247,  235,  247,  235,
+      232,  238,  230,  229,  241,  231,  257,  230,  239,  240,
+      223,  226,  225,  226,  231,  216,  216,  215,  215,   54,
+
+      219,  229,   66,  210,    0,    0,  225,  218,  215,  220,
+       67,    0,  204,  231,  217,  205,  204,  214,    0,  200,
+      208,    0,  204,  206,    0,  209,  204,  207,  193,  201,
+      208,  200,  193,   70,  202,  196,  187,  220,  186,  187,
+      197,    0,  198,  195,  192,  182,    0,  178,  181,    0,
+      180,  185,   64,  178,  187,   74,  176,  183,   80,  186,
+      169,  177,  175,    0,  170,  169,  163,  162,  169,  173,
+      172,   72,  162,  166,  169,  163,  195,  188,  159,  170,
+      191,  154,  148,    0,    0,  107,    0,  148,  143,  154,
+      149,  144,  157,    0,   80,   88,  160,  332,   82,  153,
+
+        0,  141,  137,  150,  142,  148,    0,  134,  134,    0,
+      132,  131,  139,  332,  332,  138,  130,  129,  126,  142,
+      141,  120,    0,  122,    0,  130,  133,  131,    0,  119,
+      106,  119,  115,  103,    0,  106,  108,  107,   97,  100,
+      108,  107,    0,   98,  106,  103,   89,   92,   88,   85,
+       83,   84,   83,   87,   82,    0,    0,   87,   96,   91,
+       70,    0,   64,  332,  332,   62,   58,   56,    0,   58,
+       25,    0,  332,  153,  156,   56,  159,  162
+    } ;
+
+static yyconst short int yy_def[279] =
+    {   0,
+      273,    1,  274,  274,  273,  273,  273,  273,  273,  275,
+      273,  276,  273,  276,  276,  276,  276,  276,  276,  276,
+      276,  276,  273,  273,  276,  276,  276,  276,  276,  276,
+      276,  276,  277,  278,  273,  273,  275,  273,  275,  276,
+      276,  276,  276,  276,  276,  276,  276,  276,  276,  276,
+      276,  276,  276,  276,  273,  273,  273,  273,  276,  276,
+      276,  276,  276,  276,  276,  277,  278,  278,  273,  273,
+      276,  276,  276,  276,  276,  276,  276,  276,  276,  276,
+      276,  276,  276,  276,  276,  273,  273,  273,  273,  273,
+      276,  276,  276,  276,  276,  276,  276,  276,  276,  276,
+
+      276,  276,  276,  276,  276,  276,  276,  276,  276,  276,
+      276,  276,  273,  273,  273,  273,  273,  276,  276,  276,
+      276,  276,  276,  276,  276,  276,  276,  276,  276,  276,
+      276,  276,  276,  276,  276,  276,  273,  273,  273,  273,
+      273,  276,  276,  276,  276,  276,  276,  276,  276,  276,
+      276,  276,  276,  276,  276,  276,  276,  273,  273,  273,
+      273,  273,  276,  276,  276,  276,  276,  276,  276,  276,
+      276,  276,  276,  276,  276,  276,  273,  273,  273,  273,
+      273,  276,  276,  276,  276,  276,  276,  276,  276,  276,
+      276,  276,  276,  276,  273,  273,  273,  273,  273,  276,
+
+      276,  276,  276,  276,  276,  276,  276,  276,  276,  276,
+      276,  276,  273,  273,  273,  273,  276,  276,  276,  276,
+      276,  276,  276,  276,  276,  276,  273,  273,  276,  276,
+      276,  276,  276,  276,  276,  276,  273,  273,  276,  276,
+      276,  276,  276,  276,  273,  273,  276,  276,  276,  276,
+      276,  273,  273,  276,  276,  276,  276,  276,  273,  273,
+      276,  276,  276,  273,  273,  276,  276,  276,  276,  276,
+      276,  276,    0,  273,  273,  273,  273,  273
+    } ;
+
+static yyconst short int yy_nxt[383] =
+    {   0,
+        6,    7,    8,    8,    7,    9,   10,   11,   12,   12,
+       12,   13,   14,   15,   16,   17,   12,   12,   18,   19,
+       12,   20,   21,   22,   23,    6,    6,   24,   12,   12,
+       12,   12,   12,   25,   12,   12,   26,   12,   12,   27,
+       12,   12,   28,   12,   29,   30,   12,   12,   12,   12,
+       31,   34,   34,   43,   35,   35,   38,   39,   40,   47,
+       53,   50,   55,   32,  272,   56,   44,   48,   51,   57,
+       52,   58,   65,  127,   36,   36,   80,   54,   81,   51,
+       38,   39,   38,   39,   87,  130,  136,  171,  155,  178,
+      159,  190,  127,  174,   88,  213,  175,  216,  196,  271,
+
+      261,  270,  258,  269,  130,  136,  155,  268,  267,  171,
+      190,  266,  174,  213,  214,  216,  261,  265,  175,  202,
+      203,  258,  264,  263,  204,  205,  262,  260,  259,  257,
+      206,  256,  255,  254,  253,  202,  203,  252,  251,  250,
+      249,  248,  204,  205,  247,  246,  245,  244,  243,  242,
+      241,  240,  206,   33,   33,   33,   37,   37,   37,   66,
+      239,   66,   68,  238,   68,  237,  236,  235,  234,  233,
+      232,  231,  230,  229,  228,  227,  226,  225,  224,  223,
+      222,  221,  220,  219,  218,  217,  215,  212,  211,  210,
+      209,  208,  207,  201,  200,  199,  198,  197,  196,  195,
+
+      194,  193,  192,  191,  189,  188,  187,  186,  185,  184,
+      183,  182,  181,  180,  179,  177,  176,  173,  172,  170,
+      169,  168,  167,  166,  165,  164,  163,  162,  161,  160,
+      159,  158,  157,  156,  154,  153,  152,  151,  150,  149,
+      148,  147,  146,  145,  144,  143,  142,  141,  140,  139,
+      138,  137,  135,  134,  133,  132,  131,  129,  128,  126,
+      125,  124,  123,  122,  121,  120,  119,  118,  117,  116,
+      115,  114,  113,  112,  111,  110,  109,  108,  107,  106,
+      105,  104,  103,  102,  101,  100,   99,   98,   67,   67,
+       67,   97,   96,   95,   94,   93,   92,   91,   90,   89,
+
+       86,   85,   84,   83,   82,   79,   78,   77,   76,   75,
+       74,   73,   72,   71,   70,   69,   67,   67,   64,   63,
+       51,   62,   61,   60,   59,   49,   46,   45,   42,   41,
+      273,    5,  273,  273,  273,  273,  273,  273,  273,  273,
+      273,  273,  273,  273,  273,  273,  273,  273,  273,  273,
+      273,  273,  273,  273,  273,  273,  273,  273,  273,  273,
+      273,  273,  273,  273,  273,  273,  273,  273,  273,  273,
+      273,  273,  273,  273,  273,  273,  273,  273,  273,  273,
+      273,  273
+    } ;
+
+static yyconst short int yy_chk[383] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        2,    3,    4,   16,    3,    4,   10,   10,  276,   19,
+       22,   21,   23,    2,  271,   23,   16,   19,   21,   23,
+       21,   23,   32,  100,    3,    4,   50,   22,   50,   32,
+       37,   37,   39,   39,   56,  103,  111,  153,  134,  159,
+      159,  172,  100,  156,   56,  195,  156,  199,  196,  270,
+
+      254,  268,  251,  267,  103,  111,  134,  266,  263,  153,
+      172,  261,  156,  195,  196,  199,  254,  260,  156,  186,
+      186,  251,  259,  258,  186,  186,  255,  253,  252,  250,
+      186,  249,  248,  247,  246,  186,  186,  245,  244,  242,
+      241,  240,  186,  186,  239,  238,  237,  236,  234,  233,
+      232,  231,  186,  274,  274,  274,  275,  275,  275,  277,
+      230,  277,  278,  228,  278,  227,  226,  224,  222,  221,
+      220,  219,  218,  217,  216,  213,  212,  211,  209,  208,
+      206,  205,  204,  203,  202,  200,  197,  193,  192,  191,
+      190,  189,  188,  183,  182,  181,  180,  179,  178,  177,
+
+      176,  175,  174,  173,  171,  170,  169,  168,  167,  166,
+      165,  163,  162,  161,  160,  158,  157,  155,  154,  152,
+      151,  149,  148,  146,  145,  144,  143,  141,  140,  139,
+      138,  137,  136,  135,  133,  132,  131,  130,  129,  128,
+      127,  126,  124,  123,  121,  120,  118,  117,  116,  115,
+      114,  113,  110,  109,  108,  107,  104,  102,  101,   99,
+       98,   97,   96,   95,   94,   93,   92,   91,   90,   89,
+       88,   87,   86,   85,   84,   83,   82,   81,   80,   79,
+       78,   77,   76,   75,   74,   73,   72,   71,   68,   67,
+       66,   65,   64,   63,   62,   61,   60,   59,   58,   57,
+
+       55,   54,   53,   52,   51,   49,   48,   47,   46,   45,
+       44,   43,   42,   41,   36,   35,   34,   33,   31,   30,
+       29,   28,   27,   26,   25,   20,   18,   17,   15,   14,
+        5,  273,  273,  273,  273,  273,  273,  273,  273,  273,
+      273,  273,  273,  273,  273,  273,  273,  273,  273,  273,
+      273,  273,  273,  273,  273,  273,  273,  273,  273,  273,
+      273,  273,  273,  273,  273,  273,  273,  273,  273,  273,
+      273,  273,  273,  273,  273,  273,  273,  273,  273,  273,
+      273,  273
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "zparse.fl"
+#define INITIAL 0
+/* This is the lexical analyser - it returns tokens to the parsers.
+   This is used by both parsers - one for the build-time config files
+   and one for the run-time config files. Note the included file "parse.h"
+   is a symlink to the relevant header file. */
+#line 7 "zparse.fl"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/*#define YYSTYPE char * - YYSTYPE is defined in zparse.tab.h */
+#include "zparse.tab.h"
+
+/* forward declarations for std functions not picked up. */
+/*int fileno(FILE *);*/
+/*char *strdup(char *);*/
+
+int lineno=1;
+#define STRINGCOND 1
+
+#line 576 "zparse.yy.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( yy_current_buffer->yy_is_interactive ) \
+		{ \
+		int c = '*', n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+		  && ferror( yyin ) ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	if ( yyleng > 0 ) \
+		yy_current_buffer->yy_at_bol = \
+				(yytext[yyleng - 1] == '\n'); \
+	YY_USER_ACTION
+
+YY_DECL
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp = NULL, *yy_bp = NULL;
+	register int yy_act;
+
+#line 26 "zparse.fl"
+
+	char *string;
+	int string_len;
+
+#line 735 "zparse.yy.c"
+
+	if ( yy_init )
+		{
+		yy_init = 0;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! yy_start )
+			yy_start = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! yy_current_buffer )
+			yy_current_buffer =
+				yy_create_buffer( yyin, YY_BUF_SIZE );
+
+		yy_load_buffer_state();
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = yy_c_buf_p;
+
+		/* Support of yytext. */
+		*yy_cp = yy_hold_char;
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = yy_start;
+		yy_current_state += YY_AT_BOL();
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				yy_last_accepting_state = yy_current_state;
+				yy_last_accepting_cpos = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 274 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 332 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+
+do_action:	/* This label is used only to access EOF actions. */
+
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = yy_hold_char;
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 30 "zparse.fl"
+lineno++;/*yylval.string=yytext;*/yyleng=0;
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 31 "zparse.fl"
+return (',');
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 32 "zparse.fl"
+return (':');
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 33 "zparse.fl"
+return ('_');
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 34 "zparse.fl"
+yylval.string=yytext;return(GSDLVERSION);
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 35 "zparse.fl"
+return (GENERAL_SECTION);
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 36 "zparse.fl"
+return (SEARCH_SECTION);
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 37 "zparse.fl"
+return (BROWSE_SECTION);
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 38 "zparse.fl"
+return (MACROS_SECTION);
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 39 "zparse.fl"
+return (MAINTAINER);
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 40 "zparse.fl"
+return(LANGUAGES);
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 41 "zparse.fl"
+return(ABOUT);
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 42 "zparse.fl"
+return(BROWSE);
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 43 "zparse.fl"
+return(DATELIST);
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 44 "zparse.fl"
+return(DOCUMENTARROWSBOTTOM);
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 45 "zparse.fl"
+return(DOCUMENTBUTTONS);
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 46 "zparse.fl"
+return(DOCUMENTHEADER);
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 47 "zparse.fl"
+return(DOCUMENTIMAGES);
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 48 "zparse.fl"
+return(DOCUMENTTEXT);
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 49 "zparse.fl"
+return(ICONLINK);
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 50 "zparse.fl"
+return(LIST);
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 51 "zparse.fl"
+return(FORMAT);
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 52 "zparse.fl"
+return(NAME);
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 53 "zparse.fl"
+return(SEARCHTEXT);
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 54 "zparse.fl"
+return(SECTIONLIST);
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 55 "zparse.fl"
+return(SORTEDLIST);
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 56 "zparse.fl"
+return(SORTEDSECTIONLIST);
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 57 "zparse.fl"
+return(TEXTLINK);
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 58 "zparse.fl"
+return(TYPE);
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 59 "zparse.fl"
+return (PUBLIC);
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 60 "zparse.fl"
+return (TRUE);
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 61 "zparse.fl"
+return (FALSE);
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 62 "zparse.fl"
+return (DOCUMENT);
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 63 "zparse.fl"
+return (SECTION);
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 64 "zparse.fl"
+return (ICON);
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 65 "zparse.fl"
+return (SMALLICON);
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 66 "zparse.fl"
+{string=NULL;BEGIN(STRINGCOND);}
+	YY_BREAK
+
+case 38:
+YY_RULE_SETUP
+#line 68 "zparse.fl"
+{/* append this to our current string EXC NEWLINE */
+			if (string==NULL) string_len=0; else
+			string_len=strlen(string);
+			string=realloc(string,string_len+strlen(yytext)+1);
+			/* +1 is for trailing \0 */
+			strcpy(string+string_len,yytext);
+			}
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 75 "zparse.fl"
+{/* append this to our current string - INC NEWLINE */
+			lineno++;
+			if (string==NULL) string_len=0; else
+			string_len=strlen(string);
+			string=realloc(string,string_len+strlen(yytext)+1);
+			/* +1 is for trailing \0 */
+			strcpy(string+string_len,yytext);
+			}
+	YY_BREAK
+case 40:
+#line 84 "zparse.fl"
+case 41:
+YY_RULE_SETUP
+#line 84 "zparse.fl"
+{       /*replace quoted quote with one quote*/
+			string_len=strlen(string);
+			string=realloc(string,string_len+2);
+			string[string_len]='\"';
+			string[string_len+1]='\0';
+			}
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 90 "zparse.fl"
+{
+			BEGIN(INITIAL);
+			yylval.string=string;
+			return(STRING);
+			  /* note that the string may have long bits of 
+			     whitespace in it that we could remove. */
+			}
+	YY_BREAK
+
+case 43:
+YY_RULE_SETUP
+#line 98 "zparse.fl"
+yylval.string=strdup(yytext);return (DATA);
+	YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 99 "zparse.fl"
+;
+	YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 100 "zparse.fl"
+lineno++;
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 101 "zparse.fl"
+ECHO;
+	YY_BREAK
+#line 1072 "zparse.yy.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(STRINGCOND):
+	yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = yy_hold_char;
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between yy_current_buffer and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			yy_n_chars = yy_current_buffer->yy_n_chars;
+			yy_current_buffer->yy_input_file = yyin;
+			yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state();
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++yy_c_buf_p;
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = yy_c_buf_p;
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer() )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				yy_did_buffer_switch_on_eof = 0;
+
+				if ( yywrap() )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				yy_c_buf_p =
+					yytext_ptr + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				yy_c_buf_p =
+				&yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+	} /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+	{
+	register char *dest = yy_current_buffer->yy_ch_buf;
+	register char *source = yytext_ptr;
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( yy_current_buffer->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+	else
+		{
+		int num_to_read =
+			yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+			YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = yy_current_buffer;
+
+			int yy_c_buf_p_offset =
+				(int) (yy_c_buf_p - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yy_flex_realloc( (void *) b->yy_ch_buf,
+							 b->yy_buf_size + 2 );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = yy_current_buffer->yy_buf_size -
+						number_to_move - 1;
+#endif
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+			yy_n_chars, num_to_read );
+
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	if ( yy_n_chars == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart( yyin );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			yy_current_buffer->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	yy_n_chars += number_to_move;
+	yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+	yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+	yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+	return ret_val;
+	}
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+
+	yy_current_state = yy_start;
+	yy_current_state += YY_AT_BOL();
+
+	for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			yy_last_accepting_state = yy_current_state;
+			yy_last_accepting_cpos = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 274 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+	}
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+	{
+	register int yy_is_jam;
+	register char *yy_cp = yy_c_buf_p;
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		yy_last_accepting_state = yy_current_state;
+		yy_last_accepting_cpos = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 274 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 273);
+
+	return yy_is_jam ? 0 : yy_current_state;
+	}
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+	{
+	register char *yy_cp = yy_c_buf_p;
+
+	/* undo effects of setting up yytext */
+	*yy_cp = yy_hold_char;
+
+	if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = yy_n_chars + 2;
+		register char *dest = &yy_current_buffer->yy_ch_buf[
+					yy_current_buffer->yy_buf_size + 2];
+		register char *source =
+				&yy_current_buffer->yy_ch_buf[number_to_move];
+
+		while ( source > yy_current_buffer->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		yy_current_buffer->yy_n_chars =
+			yy_n_chars = yy_current_buffer->yy_buf_size;
+
+		if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+
+	yytext_ptr = yy_bp;
+	yy_hold_char = *yy_cp;
+	yy_c_buf_p = yy_cp;
+	}
+#endif	/* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+	{
+	int c;
+
+	*yy_c_buf_p = yy_hold_char;
+
+	if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			/* This was really a NUL. */
+			*yy_c_buf_p = '\0';
+
+		else
+			{ /* need more input */
+			int offset = yy_c_buf_p - yytext_ptr;
+			++yy_c_buf_p;
+
+			switch ( yy_get_next_buffer() )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart( yyin );
+
+					/* fall through */
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap() )
+						return EOF;
+
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					yy_c_buf_p = yytext_ptr + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) yy_c_buf_p;	/* cast for 8-bit char's */
+	*yy_c_buf_p = '\0';	/* preserve yytext */
+	yy_hold_char = *++yy_c_buf_p;
+
+	yy_current_buffer->yy_at_bol = (c == '\n');
+
+	return c;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+	{
+	if ( ! yy_current_buffer )
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+	yy_init_buffer( yy_current_buffer, input_file );
+	yy_load_buffer_state();
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+	{
+	if ( yy_current_buffer == new_buffer )
+		return;
+
+	if ( yy_current_buffer )
+		{
+		/* Flush out information for old buffer. */
+		*yy_c_buf_p = yy_hold_char;
+		yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	yy_current_buffer = new_buffer;
+	yy_load_buffer_state();
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	yy_did_buffer_switch_on_eof = 1;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+	{
+	yy_n_chars = yy_current_buffer->yy_n_chars;
+	yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+	yyin = yy_current_buffer->yy_input_file;
+	yy_hold_char = *yy_c_buf_p;
+	}
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer( b, file );
+
+	return b;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+	{
+	if ( ! b )
+		return;
+
+	if ( b == yy_current_buffer )
+		yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yy_flex_free( (void *) b->yy_ch_buf );
+
+	yy_flex_free( (void *) b );
+	}
+
+
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+	{
+	yy_flush_buffer( b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+	b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+	b->yy_is_interactive = 0;
+#else
+	b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+	{
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == yy_current_buffer )
+		yy_load_buffer_state();
+	}
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer( b );
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+	{
+	int len;
+	for ( len = 0; yy_str[len]; ++len )
+		;
+
+	return yy_scan_bytes( yy_str, len );
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+	{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = len + 2;
+	buf = (char *) yy_flex_alloc( n );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < len; ++i )
+		buf[i] = bytes[i];
+
+	buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer( buf, n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+	{
+	if ( yy_start_stack_ptr >= yy_start_stack_depth )
+		{
+		yy_size_t new_size;
+
+		yy_start_stack_depth += YY_START_STACK_INCR;
+		new_size = yy_start_stack_depth * sizeof( int );
+
+		if ( ! yy_start_stack )
+			yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+		else
+			yy_start_stack = (int *) yy_flex_realloc(
+					(void *) yy_start_stack, new_size );
+
+		if ( ! yy_start_stack )
+			YY_FATAL_ERROR(
+			"out of memory expanding start-condition stack" );
+		}
+
+	yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+	BEGIN(new_state);
+	}
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+	{
+	if ( --yy_start_stack_ptr < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
+
+	BEGIN(yy_start_stack[yy_start_stack_ptr]);
+	}
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+	{
+	return yy_start_stack[yy_start_stack_ptr - 1];
+	}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+	{
+	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+	}
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		yytext[yyleng] = yy_hold_char; \
+		yy_c_buf_p = yytext + n; \
+		yy_hold_char = *yy_c_buf_p; \
+		*yy_c_buf_p = '\0'; \
+		yyleng = n; \
+		} \
+	while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+	{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+	}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+	{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+	}
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+	{
+	return (void *) malloc( size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+	{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+	{
+	free( ptr );
+	}
+
+#if YY_MAIN
+int main()
+	{
+	yylex();
+	return 0;
+	}
+#endif
+#line 101 "zparse.fl"
+
+/******** deleted rules: *******
+en			return(EN);
+fr			return(FR);
+mi			return(MI);
+zh			return(ZH);
+de			return(DE);
+***************/
+
+
+
+
Index: /gsdl/stable/runtime-src/win32.mak
===================================================================
--- /gsdl/stable/runtime-src/win32.mak	(revision 20131)
+++ /gsdl/stable/runtime-src/win32.mak	(revision 20131)
@@ -0,0 +1,129 @@
+###########################################################################
+#
+# win32 makefile -- gsdl runtime code
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDLHOME = $(GSDLHOME)
+RUNTIMEHOME = $(MAKEDIR)
+
+GSDL_VC4 = 0
+LOCAL_LIBRARY = 0
+APACHE_HTTPD = 0
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+USE_SQLITE = 1
+USE_MSSQL = 0
+USE_Z3950 = 0
+
+MDEFINES = /f win32.mak
+
+COMPILEDIRS = src\colservr src\protocol
+
+INSTALLDIRS = src\recpt src\oaiservr 
+
+PACKAGEDIRS = 
+
+YAZ_DIR = packages\yaz\yaz-2.1.4\win
+
+MAKECMD = $(MAKE) $(MDEFINES) GSDLHOME="$(GSDLHOME)"
+!IF $(GSDL_VC4)
+MAKECMD = $(MAKECMD) GSDL_VC4=1
+!ENDIF
+!IF $(LOCAL_LIBRARY)
+MAKECMD = $(MAKECMD) LOCAL_LIBRARY=1
+INSTALLDIRS = $(INSTALLDIRS) src\w32server src\w32apachectl
+!ENDIF
+!IF $(APACHE_HTTPD)
+MAKECMD = $(MAKECMD) APACHE_HTTPD=1
+INSTALLDIRS = $(INSTALLDIRS) packages\apache-httpd
+!ENDIF
+!IF $(DEBUG)
+MAKECMD = $(MAKECMD) DEBUG=1
+!ENDIF
+!IF $(DLL)
+MAKECMD = $(MAKECMD) DLL=1
+!ENDIF
+!IF $(DLLDEBUG)
+MAKECMD = $(MAKECMD) DLLDEBUG=1
+!ENDIF
+!IF $(USE_SQLITE)
+MAKECMD = $(MAKECMD) USE_SQLITE=1
+!ENDIF
+!IF $(USE_MSSQL)
+MAKECMD = $(MAKECMD) USE_MSSQL=1
+!ENDIF
+!IF $(USE_Z3950)
+MAKECMD = $(MAKECMD) USE_Z3950=1
+INSTALLDIRS = src\z3950 $(INSTALLDIRS) 
+PACKAGEDIRS = $(PACKAGEDIRS) packages\d2m $(YAZ_DIR)
+!ENDIF
+
+MAKECLEANCMD = $(MAKE) $(MDEFINES) GSDLHOME="$(GSDLHOME)" clean
+
+all: win32.mak $(PACKAGEDIRS) $(COMPILEDIRS) $(INSTALLDIRS) 
+
+install: win32.mak $(INSTALLDIRS)
+
+clean:
+	cd "$(RUNTIMEHOME)"
+	cd src\colservr
+	$(MAKECLEANCMD)
+	cd "$(RUNTIMEHOME)"
+	cd src\protocol
+	$(MAKECLEANCMD)
+	cd "$(RUNTIMEHOME)"
+	cd src\recpt
+	$(MAKECLEANCMD)
+	cd "$(RUNTIMEHOME)"
+	cd src\oaiservr
+	$(MAKECLEANCMD)
+	cd "$(RUNTIMEHOME)"
+	cd src\w32server
+	$(MAKECLEANCMD)
+	cd "$(RUNTIMEHOME)"
+	cd src\w32apachectl
+	$(MAKECLEANCMD)
+	cd "$(GSDLHOME)"
+
+$(COMPILEDIRS): FORCE
+	cd "$(RUNTIMEHOME)"
+	cd "$@"
+	$(MAKECMD)
+	cd "$(GSDLHOME)"
+
+$(INSTALLDIRS): FORCE
+	cd "$(RUNTIMEHOME)"
+	cd "$@"
+	$(MAKECMD)
+	$(MAKECMD) install
+	cd "$(GSDLHOME)"
+
+$(YAZ_DIR): FORCE
+	cd "$@"
+	nmake HAVE_ICONV=0 HAVE_LIBXML2=0
+	cd "$(GSDLHOME)"
+
+FORCE:
+
Index: /gsdl/stable/setup.bash
===================================================================
--- /gsdl/stable/setup.bash	(revision 20131)
+++ /gsdl/stable/setup.bash	(revision 20131)
@@ -0,0 +1,264 @@
+#!/bin/bash
+# if this file is executed, /bin/sh is used, as we don't start with #!
+# this should work under ash, bash, zsh, ksh, sh style shells.
+gsdllang=""
+# encoding inputs and outputs
+gsdltoenc=""
+gsdlfromenc=""
+
+# see if the shell has any language environment variables set
+# see locale(7) manpage for this ordering.
+if test ! -z "$LC_ALL" ; then
+  gsdllang="$LC_ALL"
+elif test ! -z "$LANG"; then
+  gsdllang="$LANG"
+fi
+
+
+# note... all our output strings have the charset hard-coded, but
+# people may be using a different encoding in their terminal. LANG
+# strings look like "en_NZ.UTF-8".
+
+# Determine the requested output encoding
+case $gsdllang in
+  *.*)
+    gsdltoenc=`echo $gsdllang | sed 's/.*\.//'`
+    ;;
+esac
+
+# Our french and spanish strings are currently in iso-8859-1 encoding.
+case $gsdllang in
+  fr*|FR*)
+    gsdllang=fr
+    gsdlfromenc="iso-8859-1"
+  ;;
+  es*|ES*)
+    gsdllang=es
+    gsdlfromenc="iso-8859-1"
+  ;;
+  ru*|RU*)
+    gsdllang=ru
+    gsdlfromenc="koi8r"
+  ;;
+  *) # default
+    gsdllang=en
+    gsdlfromenc="iso-8859-1"
+  ;;
+esac  
+
+# "iconv" is the program for converting text between encodings.
+gsdliconv=`which iconv 2>/dev/null`
+if test $? -ne 0 || test ! -x "$gsdliconv" || test -z "$gsdlfromenc" || test -z "$gsdltoenc"; then
+# we can't convert encodings from some reason
+  gsdliconv="cat"
+else
+# add the encodings
+  gsdliconv="$gsdliconv -f $gsdlfromenc -t $gsdltoenc"
+fi
+
+# make sure we are sourced, and not run
+
+if test "$0" != "`echo $0 | sed s/setup\.bash//`" ; then
+# if $0 contains "setup.bash" we've been run... $0 is shellname if sourced.
+# One exception is zsh has an option to set it temporarily to the script name
+  if test -z "$ZSH_NAME" ; then
+  # we aren't using zsh
+  gsdl_not_sourced=true
+  fi
+fi
+
+if test -n "$gsdl_not_sourced" ; then
+  case "$gsdllang" in
+ "es")
+eval $gsdliconv <<EOF
+      Error: Asegúrese de compilar este guión, no de ejecutarlo. P. ej.:
+         $ source setup.bash
+      o
+         $ . ./setup.bash
+      no
+         $ ./setup.bash
+EOF
+  ;;
+  "fr")
+eval $gsdliconv <<EOF
+      Erreur: Assurez-vous de "sourcer" le script, plutôt que de l'exécuter. Ex:
+         $ source setup.bash
+      ou
+         $ . ./setup.bash
+      pas
+         $ ./setup.bash
+EOF
+  ;;
+  "ru")
+eval $gsdliconv <<EOF
+      ïÛÉÂËÁ: õÄÏÓÔÏ×ÅÒØÔÅÓØ × ÉÓÔÏÞÎÉËÅ ÜÔÏÇÏ ÓËÒÉÐÔÁ. îÅ ÉÓÐÏÌÎÑÊÔÅ ÅÇÏ.
+      îÁÐÒÉÍÅÒ:
+         $ source setup.bash
+      ÉÌÉ
+         $ . ./setup.bash
+      ÎÅÔ
+         $ ./setup.bash
+EOF
+  ;;
+  *)
+eval $gsdliconv <<EOF
+	Error: Make sure you source this script, not execute it. Eg:
+		$ source setup.bash
+	or
+		$ . ./setup.bash
+	not
+		$ ./setup.bash
+EOF
+  ;;
+  esac
+elif test -n "$GSDLHOME" ; then
+  case "$gsdllang" in
+  "es")
+    echo '¡Su ambiente ya está listo para Greenstone!' | eval $gsdliconv
+  ;;
+  "fr")
+    echo 'Votre environnement est déjà préparé pour Greenstone!' | eval $gsdliconv
+ ;;
+  "ru")
+    echo '÷ÁÛÅ ÏËÒÕÖÅÎÉÅ ÕÖÅ ÎÁÓÔÒÏÅÎÏ ÄÌÑ Greenstone!' | eval $gsdliconv
+  ;;
+  *)
+    echo 'Your environment is already set up for Greenstone!'
+  ;;
+  esac
+elif test ! -f setup.bash ; then
+  case "$gsdllang" in
+    "es")
+eval $gsdliconv <<EOF
+Usted debe compilar el guión desde el interior del directorio de inicio
+de Greenstone.
+EOF
+  ;;
+  "fr")
+echo 'Vous devez trouver la source du script dans le répertoire de base de Greenstone' | eval $gsdliconv
+  ;;
+  "ru")
+eval $gsdliconv <<EOF
+÷ÁÍ ÎÅÏÂÈÏÄÉÍ ÉÓÔÏÞÎÉË ÓËÒÉÐÔÁ ÉÚ ÂÁÚÏ×ÏÊ ÄÉÒÅËÔÏÒÉÉ Greenstone
+EOF
+  ;;
+  *)
+    echo 'You must source the script from within the Greenstone home directory'
+  ;;
+  esac
+else
+  GSDLHOME=`pwd`
+  export GSDLHOME
+  GSDLOS=`uname -s | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+  # check for running bash under cygwin
+  if test "`echo $GSDLOS | sed 's/cygwin//'`" != "$GSDLOS" ;
+  then
+    GSDLOS=windows
+  fi
+  export GSDLOS
+
+  PATH=$GSDLHOME/bin/$GSDLOS/wv/bin:$GSDLHOME/bin/script:$GSDLHOME/bin/$GSDLOS:$PATH
+  export PATH
+  
+  # Allow wvWare binary to find the required libraries.
+		if test "$GSDLOS" = "linux" ; then
+			LD_LIBRARY_PATH="$GSDLHOME/bin/$GSDLOS/wv/lib:$LD_LIBRARY_PATH"
+			export LD_LIBRARY_PATH
+		
+		elif test "$GSDLOS" = "darwin" ; then
+			DYLD_LIBRARY_PATH="$GSDLHOME/bin/$GSDLOS/wv/lib:$DYLD_LIBRARY_PATH"
+			export DYLD_LIBRARY_PATH
+		fi
+
+  
+  
+  # Override Imagemagick and Ghostscript paths to the bundled applications shipped with greenstone if they exists otherwise use default environment variables.
+
+if test -d "$GSDLHOME/bin/$GSDLOS/imagemagick" ; then
+	PATH="$GSDLHOME/bin/$GSDLOS/imagemagick/bin:$PATH"
+	export PATH
+  
+	MAGICK_HOME="$GSDLHOME/bin/$GSDLOS/imagemagick"
+	export MAGICK_HOME
+  
+		if test "$GSDLOS" = "linux" ; then
+			LD_LIBRARY_PATH="$GSDLHOME/bin/$GSDLOS/imagemagick/lib:$LD_LIBRARY_PATH"
+			export LD_LIBRARY_PATH
+		
+		elif test "$GSDLOS" = "darwin" ; then
+			DYLD_LIBRARY_PATH="$GSDLHOME/bin/$GSDLOS/imagemagick/lib:$DYLD_LIBRARY_PATH"
+			export DYLD_LIBRARY_PATH
+		fi
+fi
+
+
+  # Note: Ghostscript is only bundled with Greenstone on Mac and Windows, not on Linux. The code below should be used only for the Darwin platform
+  # for Windows please see setup.bat
+if test -d "$GSDLHOME/bin/$GSDLOS/ghostscript" ; then
+	PATH="$GSDLHOME/bin/$GSDLOS/ghostscript/bin":"$PATH"
+	export PATH
+  
+	GS_LIB="$GSDLHOME/bin/$GSDLOS/ghostscript/share/ghostscript/8.63/lib"
+	export GS_LIB
+
+	GS_FONTPATH="$GSDLHOME/bin/$GSDLOS/ghostscript/share/ghostscript/8.63/Resource/Font"
+	export GS_FONTPATH
+fi
+  
+  
+  
+  MANPATH=$MANPATH:$GSDLHOME/packages/mg/man
+  export MANPATH
+  case "$gsdllang" in
+    "es")
+      echo 'Su ambiente ha sido configurado para correr los programas Greenstone.' | eval $gsdliconv
+    ;;
+    "fr")
+      echo 'Votre environnement a été configuére avec succès pour exécuter Greenstone' | eval $gsdliconv
+    ;;
+    "ru")
+eval $gsdliconv <<EOF
+÷ÁÛÅ ÏËÒÕÖÅÎÉÅ ÂÙÌÏ ÕÓÐÅÛÎÏ ÎÁÓÔÒÏÅÎÏ, ÞÔÏÂÙ ÕÓÔÁÎÏ×ÉÔØ Greenstone
+EOF
+    ;;
+    *)
+      echo 'Your environment has successfully been set up to run Greenstone'
+    ;;
+  esac
+fi
+unset gsdl_not_sourced
+unset gsdliconv
+unset gsdlfromenc
+unset gsdltoenc
+
+if test -e ext ; then
+  for gsdl_ext in ext/* ; do
+    cd $gsdl_ext > /dev/null
+    if test -e setup.bash ; then 
+      source ./setup.bash 
+    fi 
+    cd ../..  
+  done
+fi
+
+if test -e apache-httpd ; then
+  echo "Adding in executable path for apache-httpd"
+  PATH=$GSDLHOME/apache-httpd/$GSDLOS/bin:$PATH
+  export PATH
+fi
+
+
+if test -e local ; then
+  if test -e local/setup.bash ; then 
+    echo "Sourcing local/setup.bash"
+    cd local ; source setup.bash ; cd ..
+  fi
+
+  PATH=$GSDLHOME/local/bin:$PATH
+  export PATH
+  LD_LIBRARY_PATH=$GSDLHOME/local/lib:$LD_LIBRARY_PATH
+  export LD_LIBRARY_PATH
+fi
+
+
+
Index: /gsdl/stable/setup.bat
===================================================================
--- /gsdl/stable/setup.bat	(revision 20131)
+++ /gsdl/stable/setup.bat	(revision 20131)
@@ -0,0 +1,122 @@
+@echo off
+pushd "%CD%"
+CD /D "%~dp0"
+set GSDLLANG=en
+
+echo.
+echo.
+echo  ####                        #
+echo ##                           #
+echo #     ###  ##   ##  ### ### ###  ##  ###  ##
+echo #   # #   #### #### # # ##   #  #  # # # ####
+echo ##  # #   #    #    # #   #  #  #  # # # #
+echo  #### #    ###  ### # # ###  ##  ##  # #  ###
+echo (C) 2008, New Zealand Digital Library Project
+echo.
+echo.
+echo.
+
+if "%OS%" == "Windows_NT" goto WinNT
+if "%OS%" == "" goto Win95
+if "%GSDLLANG%" == "en" echo Setup failed - your PATH has not been set
+if "%GSDLLANG%" == "es" echo No se pudo realizar la configuraci¢n - no se ha establecido la RUTA.
+if "%GSDLLANG%" == "fr" echo Echc de l'installation - votre variable PATH n'a pas t ajuste
+if "%GSDLLANG%" == "ru" echo áâ ­®¢ª  ­¥ ã€ « áì -  ­¥ ¡ë« ãáâ ­®¢«¥­
+goto End
+
+:WinNT
+set GSDLHOME=%CD%
+set GSDLOS=windows
+
+REM Override Imagemagick and Ghostscript paths to the bundled applications shipped with greenstone if they exists otherwise use default environment variables.
+if exist "%GSDLHOME%\bin\windows\ghostscript\bin\gsdll32.dll" set GS_DLL=%GSDLHOME%\bin\windows\ghostscript\bin\gsdll32.dll
+if exist "%GSDLHOME%\bin\windows\ghostscript\lib\*.*" set GS_LIB=%GSDLHOME%\bin\windows\ghostscript\lib
+if exist "%GSDLHOME%\bin\windows\ghostscript\bin\*.*" set PATH=%GSDLHOME%\bin\windows\ghostscript\bin;%PATH%
+if exist "%GSDLHOME%\bin\windows\imagemagick\*.*" set PATH=%GSDLHOME%\bin\windows\imagemagick;%PATH%
+
+if "%GS_CP_SET%" == "yes" goto Success
+set PATH=%GSDLHOME%\bin\windows\perl\bin;%GSDLHOME%\bin\windows;%GSDLHOME%\bin\script;%PATH%
+set GS_CP_SET=yes
+goto Success
+
+:Win95
+if "%1" == "SetEnv" goto Win95Env
+REM We'll invoke a second copy of the command processor to make
+REM sure there's enough environment space
+COMMAND /E:2048 /K %0 SetEnv
+goto End
+
+:Win95Env
+set GSDLHOME=%CD%
+set GSDLOS=windows
+
+REM Override Imagemagick and Ghostscript paths to the bundled applications shipped with greenstone if they exists otherwise use default environment variables.
+if exist "%GSDLHOME%\bin\windows\ghostscript\bin\gsdll32.dll" set GS_DLL="%GSDLHOME%\bin\windows\ghostscript\bin\gsdll32.dll"
+if exist "%GSDLHOME%\bin\windows\ghostscript\lib\*.*" set GS_LIB="%GSDLHOME%\bin\windows\ghostscript\lib"
+if exist "%GSDLHOME%\bin\windows\ghostscript\bin\*.*" set PATH="%GSDLHOME%\bin\windows\ghostscript\bin";"%PATH%"
+if exist "%GSDLHOME%\bin\windows\imagemagick\*.*" set PATH="%GSDLHOME%\bin\windows\imagemagick";"%PATH%"
+
+if "%GS_CP_SET%" == "yes" goto Success
+set PATH="%GSDLHOME%\bin\windows\perl\bin";"%GSDLHOME%\bin\windows";"%GSDLHOME%\bin\script";"%PATH%"
+set GS_CP_SET=yes
+goto Success
+
+
+:Success
+if "%GSDLLANG%" == "en" echo.
+if "%GSDLLANG%" == "en" echo Your environment has successfully been set up to run Greenstone.
+if "%GSDLLANG%" == "en" echo Note that these settings will only have effect within this MS-DOS
+if "%GSDLLANG%" == "en" echo session. You will therefore need to rerun setup.bat if you want
+if "%GSDLLANG%" == "en" echo to run Greenstone programs from a different MS-DOS session.
+if "%GSDLLANG%" == "en" echo.
+
+if "%GSDLLANG%" == "es" echo.
+if "%GSDLLANG%" == "es" echo Su ambiente ha sido configurado para correr los programas Greenstone.
+if "%GSDLLANG%" == "es" echo Recuerde que estos ajustes £nicamente tendr n efecto dentro de esta sesi¢n
+if "%GSDLLANG%" == "es" echo MS-DOS. Por lo tanto deber  ejecutar nuevamente setup.bat si desea
+if "%GSDLLANG%" == "es" echo correr los programas de Greenstone desde una sesi¢n MS-DOS diferente.
+if "%GSDLLANG%" == "es" echo.
+
+if "%GSDLLANG%" == "fr" echo.
+if "%GSDLLANG%" == "fr" echo Votre environnement a t configure avec succs pour excuter Greenstone
+if "%GSDLLANG%" == "fr" echo Notez que ces paramtrages n'auront d'effet que dans cette session MS-DOS.
+if "%GSDLLANG%" == "fr" echo Vous devrez par consquent rexcuter setup.bat si vous voulez faire
+if "%GSDLLANG%" == "fr" echo lancer des programmes Greenstone dans une autre session MS-DOS.
+if "%GSDLLANG%" == "fr" echo.
+
+if "%GSDLLANG%" == "ru" echo.
+if "%GSDLLANG%" == "ru" echo  è¥ ®ªàãŠ¥­š¥ ¡ë«® ãá¯¥è­® ­ áâà®¥­®, çâ®¡ë ãáâ ­®¢šâì Greenstone ¡à âšâ¥
+if "%GSDLLANG%" == "ru" echo ¢­š¬ ­š¥, çâ® íâš ­ §­ ç¥­šï ¡ã€ãâ â®«ìª® š¬¥âì íää¥ªâ ¢ ¯à¥€¥« å íâ®£® MS DOS
+if "%GSDLLANG%" == "ru" echo á¥áášï. ë ¡ã€¥â¥ ¯®íâ®¬ã €®«Š­ë ¯®¢â®à­® ã¯à ¢«ïâì setup.bat, ¥á«š ë å®âšâ¥
+if "%GSDLLANG%" == "ru" echo ã¯à ¢«ïâì ¯à®£à ¬¬ ¬š ¥«ñ­ëå š§¢¥àŠ¥­­ëå ¯®à®€ ®â à §«šç­®© á¥áášš MS DOS.
+if "%GSDLLANG%" == "ru" echo.
+
+:End
+
+if exist ext (
+    for /D %%e IN ("ext/*") do (
+        cd ext\%%e
+        if EXIST setup.bat call setup.bat
+        cd ..\..
+    )
+)
+
+if exist apache-httpd (
+  echo Adding in executable path for apache-httpd
+  set PATH=%GSDLHOME%\apache-httpd\%GSDLOS%\bin;%PATH%
+)
+
+if exist local (
+  if exist local\setup.bat (
+    echo.
+    echo Running local\setup.bat
+    cd local
+    call setup.bat 
+    cd ..
+  )
+  set PATH=%GSDLHOME%\local\bin;%PATH%
+)
+
+:: test writability of GSDLHOME
+@call "%GSDLHOME%\bin\script\checkwritability.bat"
+popd
Index: /gsdl/stable/setup.csh
===================================================================
--- /gsdl/stable/setup.csh	(revision 20131)
+++ /gsdl/stable/setup.csh	(revision 20131)
@@ -0,0 +1,18 @@
+setenv GSDLLANG en
+setenv GSDLHOME `pwd`
+setenv GSDLOS `uname -s | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+setenv PATH $PATH\:$GSDLHOME/bin/script\:$GSDLHOME/bin/$GSDLOS
+if ($?MANPATH) then
+  setenv MANPATH $MANPATH\:$GSDLHOME/packages/mg/man
+else
+  setenv MANPATH $GSDLHOME/packages/mg/man
+endif
+if ("$GSDLLANG" == "es") then
+  echo "Su ambiente ha sido configurado para correr los programas Greenstone."
+else if ("$GSDLLANG" == "fr") then
+  echo "Votre environnement a été configuére avec succès pour exécuter Greenstone"
+else if ("$GSDLLANG" == "ru") then
+  echo "÷ÁÛÅ ÏËÒÕÖÅÎÉÅ ÂÙÌÏ ÕÓÐÅÛÎÏ ÎÁÓÔÒÏÅÎÏ, ÞÔÏÂÙ ÕÓÔÁÎÏ×ÉÔØ Greenstone"
+else
+  echo "Your environment has successfully been set up to run Greenstone"
+endif
Index: /gsdl/stable/web/style/oai2.xsl
===================================================================
--- /gsdl/stable/web/style/oai2.xsl	(revision 20131)
+++ /gsdl/stable/web/style/oai2.xsl	(revision 20131)
@@ -0,0 +1,659 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+  XSL Transform to convert OAI 2.0 responses into XHTML
+
+  By Christopher Gutteridge, University of Southampton
+
+-->
+
+<!-- 
+  
+Copyright (c) 2000-2004 University of Southampton, UK. SO17 1BJ.
+
+EPrints 2 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+EPrints 2 is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with EPrints 2; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+-->
+
+   
+<!--
+  
+  All the elements really needed for EPrints are done but if
+  you want to use this XSL for other OAI archive you may want
+  to make some minor changes or additions.
+
+  Not Done
+    The 'about' section of 'record'
+    The 'compession' part of 'identify'
+    The optional attributes of 'resumptionToken'
+    The optional 'setDescription' container of 'set'
+
+  All the links just link to oai_dc versions of records.
+
+-->
+<xsl:stylesheet
+    version="1.0"
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+    xmlns:oai="http://www.openarchives.org/OAI/2.0/"
+>
+
+<xsl:output method="html"/>
+
+
+
+<xsl:template name="style">
+td.value {
+	vertical-align: top;
+	padding-left: 1em;
+	padding: 3px;
+}
+td.key {
+	background-color: #e0e0ff;
+	padding: 3px;
+	text-align: right;
+	border: 1px solid #c0c0c0;
+	white-space: nowrap;
+	font-weight: bold;
+	vertical-align: top;
+}
+.dcdata td.key {
+	background-color: #ffffe0;
+}
+body { 
+	margin: 1em 2em 1em 2em;
+}
+h1, h2, h3 {
+	font-family: sans-serif;
+	clear: left;
+}
+h1 {
+	padding-bottom: 4px;
+	margin-bottom: 0px;
+}
+h2 {
+	margin-bottom: 0.5em;
+}
+h3 {
+	margin-bottom: 0.3em;
+	font-size: medium;
+}
+.link {
+	border: 1px outset #88f;
+	background-color: #c0c0ff;
+	padding: 1px 4px 1px 4px;
+	font-size: 80%;
+	text-decoration: none;
+	font-weight: bold;
+	font-family: sans-serif;
+	color: black;
+}
+.link:hover {
+	color: red;
+}
+.link:active {
+	color: red;
+	border: 1px inset #88f;
+	background-color: #a0a0df;
+}
+.oaiRecord, .oaiRecordTitle {
+	background-color: #f0f0ff;
+	border-style: solid;
+	border-color: #d0d0d0;
+}
+h2.oaiRecordTitle {
+	background-color: #e0e0ff;
+	font-size: medium;
+	font-weight: bold;
+	padding: 10px;
+	border-width: 2px 2px 0px 2px;
+	margin: 0px;
+}
+.oaiRecord {
+	margin-bottom: 3em;
+	border-width: 2px;
+	padding: 10px;
+}
+
+.results {
+	margin-bottom: 1.5em;
+}
+ul.quicklinks {
+	margin-top: 2px;
+	padding: 4px;
+	text-align: left;
+	border-bottom: 2px solid #ccc;
+	border-top: 2px solid #ccc;
+	clear: left;
+}
+ul.quicklinks li {
+	font-size: 80%;
+	display: inline;
+	list-stlye: none;
+	font-family: sans-serif;
+}
+p.intro {
+	font-size: 80%;
+}
+<xsl:call-template name='xmlstyle' />
+</xsl:template>
+
+<xsl:variable name='identifier' select="substring-before(concat(substring-after(/oai:OAI-PMH/oai:request,'identifier='),'&amp;'),'&amp;')" />
+
+<xsl:template match="/">
+<html>
+  <head>
+    <title>OAI 2.0 Request Results</title>
+    <style><xsl:call-template name="style"/></style>
+  </head>
+  <body>
+    <h1>OAI 2.0 Request Results</h1>
+    <xsl:call-template name="quicklinks"/>
+    <p class="intro">You are viewing an HTML version of the XML OAI response. To see the underlying XML use your web browsers view source option. More information about this XSLT is at the <a href="#moreinfo">bottom of the page</a>.</p>
+    <xsl:apply-templates select="/oai:OAI-PMH" />
+    <xsl:call-template name="quicklinks"/>
+    <h2><a name="moreinfo">About the XSLT</a></h2>
+    <p>An XSLT file has converted the <a href="http://www.openarchives.org">OAI-PMH 2.0</a> responses into XHTML which looks nice in a browser which supports XSLT such as Mozilla, Firebird and Internet Explorer. The XSLT file was created by <a href="http://www.ecs.soton.ac.uk/people/cjg">Christopher Gutteridge</a> at the University of Southampton as part of the <a href="http://software.eprints.org">GNU EPrints system</a>, and is freely redistributable under the <a href="http://www.gnu.org">GPL</a>.</p><p>If you want to use the XSL file on your own OAI interface you may but due to the way XSLT works you must install the XSL file on the same server as the OAI script, you can't just link to this copy.</p><p>For more information or to download the XSL file please see the <a href="http://software.eprints.org/xslt.php">OAI to XHTML XSLT homepage</a>.</p>
+
+  </body>
+</html>
+</xsl:template>
+
+<xsl:template name="quicklinks">
+    <ul class="quicklinks">
+      <li><a href="?verb=Identify">Identify</a> | </li> 
+      <li><a href="?verb=ListRecords&amp;metadataPrefix=oai_dc">ListRecords</a> | </li>
+      <li><a href="?verb=ListSets">ListSets</a> | </li>
+      <li><a href="?verb=ListMetadataFormats">ListMetadataFormats</a> | </li>
+      <li><a href="?verb=ListIdentifiers&amp;metadataPrefix=oai_dc">ListIdentifiers</a></li>
+    </ul>
+</xsl:template>
+
+
+<xsl:template match="/oai:OAI-PMH">
+  <table class="values">
+    <tr><td class="key">Datestamp of response</td>
+    <td class="value"><xsl:value-of select="oai:responseDate"/></td></tr>
+    <tr><td class="key">Request URL</td>
+    <td class="value"><xsl:value-of select="oai:request"/></td></tr>
+  </table>
+<!--  verb: [<xsl:value-of select="oai:request/@verb" />]<br /> -->
+  <xsl:choose>
+    <xsl:when test="oai:error">
+      <h2>OAI Error(s)</h2>
+      <p>The request could not be completed due to the following error or errors.</p>
+      <div class="results">
+        <xsl:apply-templates select="oai:error"/>
+      </div>
+    </xsl:when>
+    <xsl:otherwise>
+      <p>Request was of type <xsl:value-of select="oai:request/@verb"/>.</p>
+      <div class="results">
+        <xsl:apply-templates select="oai:Identify" />
+        <xsl:apply-templates select="oai:GetRecord"/>
+        <xsl:apply-templates select="oai:ListRecords"/>
+        <xsl:apply-templates select="oai:ListSets"/>
+        <xsl:apply-templates select="oai:ListMetadataFormats"/>
+        <xsl:apply-templates select="oai:ListIdentifiers"/>
+      </div>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+
+<!-- ERROR -->
+
+<xsl:template match="/oai:OAI-PMH/oai:error">
+  <table class="values">
+    <tr><td class="key">Error Code</td>
+    <td class="value"><xsl:value-of select="@code"/></td></tr>
+  </table>
+  <p class="error"><xsl:value-of select="." /></p>
+</xsl:template>
+
+<!-- IDENTIFY -->
+
+<xsl:template match="/oai:OAI-PMH/oai:Identify">
+  <table class="values">
+    <tr><td class="key">Repository Name</td>
+    <td class="value"><xsl:value-of select="oai:repositoryName"/></td></tr>
+    <tr><td class="key">Base URL</td>
+    <td class="value"><xsl:value-of select="oai:baseURL"/></td></tr>
+    <tr><td class="key">Protocol Version</td>
+    <td class="value"><xsl:value-of select="oai:protocolVersion"/></td></tr>
+    <tr><td class="key">Earliest Datestamp</td>
+    <td class="value"><xsl:value-of select="oai:earliestDatestamp"/></td></tr>
+    <tr><td class="key">Deleted Record Policy</td>
+    <td class="value"><xsl:value-of select="oai:deletedRecord"/></td></tr>
+    <tr><td class="key">Granularity</td>
+    <td class="value"><xsl:value-of select="oai:granularity"/></td></tr>
+    <xsl:apply-templates select="oai:adminEmail"/>
+  </table>
+  <xsl:apply-templates select="oai:description"/>
+<!--no warning about unsupported descriptions -->
+</xsl:template>
+
+<xsl:template match="/oai:OAI-PMH/oai:Identify/oai:adminEmail">
+    <tr><td class="key">Admin Email</td>
+    <td class="value"><xsl:value-of select="."/></td></tr>
+</xsl:template>
+
+<!--
+   Identify / Unsupported Description
+-->
+
+<xsl:template match="oai:description/*" priority="-100">
+  <h2>Unsupported Description Type</h2>
+  <p>The XSL currently does not support this type of description.</p>
+  <div class="xmlSource">
+    <xsl:apply-templates select="." mode='xmlMarkup' />
+  </div>
+</xsl:template>
+
+
+<!--
+   Identify / OAI-Identifier
+-->
+
+<xsl:template match="id:oai-identifier" xmlns:id="http://www.openarchives.org/OAI/2.0/oai-identifier">
+  <h2>OAI-Identifier</h2>
+  <table class="values">
+    <tr><td class="key">Scheme</td>
+    <td class="value"><xsl:value-of select="id:scheme"/></td></tr>
+    <tr><td class="key">Repository Identifier</td>
+    <td class="value"><xsl:value-of select="id:repositoryIdentifier"/></td></tr>
+    <tr><td class="key">Delimiter</td>
+    <td class="value"><xsl:value-of select="id:delimiter"/></td></tr>
+    <tr><td class="key">Sample OAI Identifier</td>
+    <td class="value"><xsl:value-of select="id:sampleIdentifier"/></td></tr>
+  </table>
+</xsl:template>
+
+
+<!--
+   Identify / EPrints
+-->
+
+<xsl:template match="ep:eprints" xmlns:ep="http://www.openarchives.org/OAI/1.1/eprints">
+  <h2>EPrints Description</h2>
+  <h3>Content</h3>
+  <xsl:apply-templates select="ep:content"/>
+  <xsl:if test="ep:submissionPolicy">
+    <h3>Submission Policy</h3>
+    <xsl:apply-templates select="ep:submissionPolicy"/>
+  </xsl:if>
+  <h3>Metadata Policy</h3>
+  <xsl:apply-templates select="ep:metadataPolicy"/>
+  <h3>Data Policy</h3>
+  <xsl:apply-templates select="ep:dataPolicy"/>
+  <xsl:if test="ep:content">
+    <h3>Content</h3>
+    <xsl:apply-templates select="ep:content"/>
+  </xsl:if>
+  <xsl:apply-templates select="ep:comment"/>
+</xsl:template>
+
+<xsl:template match="ep:content|ep:dataPolicy|ep:metadataPolicy|ep:submissionPolicy" xmlns:ep="http://www.openarchives.org/OAI/1.1/eprints">
+  <xsl:if test="ep:text">
+    <p><xsl:value-of select="ep:text" /></p>
+  </xsl:if>
+  <xsl:if test="ep:URL">
+    <div><a href="{ep:URL}"><xsl:value-of select="ep:URL" /></a></div>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="ep:comment" xmlns:ep="http://www.openarchives.org/OAI/1.1/eprints">
+  <h3>Comment</h3>
+  <div><xsl:value-of select="."/></div>
+</xsl:template>
+
+
+<!--
+   Identify / Friends
+-->
+
+<xsl:template match="fr:friends" xmlns:fr="http://www.openarchives.org/OAI/2.0/friends/">
+  <h2>Friends</h2>
+  <ul>
+    <xsl:apply-templates select="fr:baseURL"/>
+  </ul>
+</xsl:template>
+
+<xsl:template match="fr:baseURL" xmlns:fr="http://www.openarchives.org/OAI/2.0/friends/">
+  <li><xsl:value-of select="."/> 
+<xsl:text> </xsl:text>
+<a class="link" href="{.}?verb=Identify">Identify</a></li>
+</xsl:template>
+
+
+<!--
+   Identify / Branding
+-->
+
+<xsl:template match="br:branding" xmlns:br="http://www.openarchives.org/OAI/2.0/branding/">
+  <h2>Branding</h2>
+  <xsl:apply-templates select="br:collectionIcon"/>
+  <xsl:apply-templates select="br:metadataRendering"/>
+</xsl:template>
+
+<xsl:template match="br:collectionIcon" xmlns:br="http://www.openarchives.org/OAI/2.0/branding/">
+  <h3>Icon</h3>
+  <xsl:choose>
+    <xsl:when test="link!=''">
+      <a href="{br:link}"><img src="{br:url}" alt="{br:title}" width="{br:width}" height="{br:height}" border="0" /></a>
+    </xsl:when>
+    <xsl:otherwise>
+      <img src="{br:url}" alt="{br:title}" width="{br:width}" height="{br:height}" border="0" />
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:template>
+
+<xsl:template match="br:metadataRendering" xmlns:br="http://www.openarchives.org/OAI/2.0/branding/">
+  <h3>Metadata Rendering Rule</h3>
+  <table class="values">
+    <tr><td class="key">URL</td>
+    <td class="value"><xsl:value-of select="."/></td></tr>
+    <tr><td class="key">Namespace</td>
+    <td class="value"><xsl:value-of select="@metadataNamespace"/></td></tr>
+    <tr><td class="key">Mime Type</td>
+    <td class="value"><xsl:value-of select="@mimetype"/></td></tr>
+  </table>
+</xsl:template>
+
+
+
+<!--
+   Identify / Gateway
+-->
+
+<xsl:template match="gw:gateway" xmlns:gw="http://www.openarchives.org/OAI/2.0/gateway/x">
+  <h2>Gateway Information</h2>
+  <table class="values">
+    <tr><td class="key">Source</td>
+    <td class="value"><xsl:value-of select="gw:source"/></td></tr>
+    <tr><td class="key">Description</td>
+    <td class="value"><xsl:value-of select="gw:gatewayDescription"/></td></tr>
+    <xsl:apply-templates select="gw:gatewayAdmin"/>
+    <xsl:if test="gw:gatewayURL">
+      <tr><td class="key">URL</td>
+      <td class="value"><xsl:value-of select="gw:gatewayURL"/></td></tr>
+    </xsl:if>
+    <xsl:if test="gw:gatewayNotes">
+      <tr><td class="key">Notes</td>
+      <td class="value"><xsl:value-of select="gw:gatewayNotes"/></td></tr>
+    </xsl:if>
+  </table>
+</xsl:template>
+
+<xsl:template match="gw:gatewayAdmin" xmlns:gw="http://www.openarchives.org/OAI/2.0/gateway/">
+  <tr><td class="key">Admin</td>
+  <td class="value"><xsl:value-of select="."/></td></tr>
+</xsl:template>
+
+
+<!-- GetRecord -->
+
+<xsl:template match="oai:GetRecord">
+  <xsl:apply-templates select="oai:record" />
+</xsl:template>
+
+<!-- ListRecords -->
+
+<xsl:template match="oai:ListRecords">
+  <xsl:apply-templates select="oai:record" />
+  <xsl:apply-templates select="oai:resumptionToken" />
+</xsl:template>
+
+<!-- ListIdentifiers -->
+
+<xsl:template match="oai:ListIdentifiers">
+  <xsl:apply-templates select="oai:header" />
+  <xsl:apply-templates select="oai:resumptionToken" />
+</xsl:template>
+
+<!-- ListSets -->
+
+<xsl:template match="oai:ListSets">
+  <xsl:apply-templates select="oai:set" />
+  <xsl:apply-templates select="oai:resumptionToken" />
+</xsl:template>
+
+<xsl:template match="oai:set">
+  <h2>Set</h2>
+  <table class="values">
+    <tr><td class="key">setName</td>
+    <td class="value"><xsl:value-of select="oai:setName"/></td></tr>
+    <xsl:apply-templates select="oai:setSpec" />
+  </table>
+</xsl:template>
+
+<!-- ListMetadataFormats -->
+
+<xsl:template match="oai:ListMetadataFormats">
+  <xsl:choose>
+    <xsl:when test="$identifier">
+      <p>This is a list of metadata formats available for the record "<xsl:value-of select='$identifier' />". Use these links to view the metadata: <xsl:apply-templates select="oai:metadataFormat/oai:metadataPrefix" /></p>
+    </xsl:when>
+    <xsl:otherwise>
+      <p>This is a list of metadata formats available from this archive.</p>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:apply-templates select="oai:metadataFormat" />
+</xsl:template>
+
+<xsl:template match="oai:metadataFormat">
+  <h2>Metadata Format</h2>
+  <table class="values">
+    <tr><td class="key">metadataPrefix</td>
+    <td class="value"><xsl:value-of select="oai:metadataPrefix"/></td></tr>
+    <tr><td class="key">metadataNamespace</td>
+    <td class="value"><xsl:value-of select="oai:metadataNamespace"/></td></tr>
+    <tr><td class="key">schema</td>
+    <td class="value"><a href="{oai:schema}"><xsl:value-of select="oai:schema"/></a></td></tr>
+  </table>
+</xsl:template>
+
+<xsl:template match="oai:metadataPrefix">
+      <xsl:text> </xsl:text><a class="link" href="?verb=GetRecord&amp;metadataPrefix={.}&amp;identifier={$identifier}"><xsl:value-of select='.' /></a>
+</xsl:template>
+
+<!-- record object -->
+
+<xsl:template match="oai:record">
+  <h2 class="oaiRecordTitle">OAI Record: <xsl:value-of select="oai:header/oai:identifier"/></h2>
+  <div class="oaiRecord">
+    <xsl:apply-templates select="oai:header" />
+    <xsl:apply-templates select="oai:metadata" />
+    <xsl:apply-templates select="oai:about" />
+  </div>
+</xsl:template>
+
+<xsl:template match="oai:header">
+  <h3>OAI Record Header</h3>
+  <table class="values">
+    <tr><td class="key">OAI Identifier</td>
+    <td class="value">
+      <xsl:value-of select="oai:identifier"/>
+      <xsl:text> </xsl:text><a class="link" href="?verb=GetRecord&amp;metadataPrefix=oai_dc&amp;identifier={oai:identifier}">oai_dc</a>
+      <xsl:text> </xsl:text><a class="link" href="?verb=ListMetadataFormats&amp;identifier={oai:identifier}">formats</a>
+    </td></tr>
+    <tr><td class="key">Datestamp</td>
+    <td class="value"><xsl:value-of select="oai:datestamp"/></td></tr>
+  <xsl:apply-templates select="oai:setSpec" />
+  </table>
+  <xsl:if test="@status='deleted'">
+    <p>This record has been deleted.</p>
+  </xsl:if>
+</xsl:template>
+
+
+<xsl:template match="oai:about">
+  <p>"about" part of record container not supported by the XSL</p>
+</xsl:template>
+
+<xsl:template match="oai:metadata">
+  &#160;
+  <div class="metadata">
+    <xsl:apply-templates select="*" />
+  </div>
+</xsl:template>
+
+
+
+
+<!-- oai setSpec object -->
+
+<xsl:template match="oai:setSpec">
+  <tr><td class="key">setSpec</td>
+  <td class="value"><xsl:value-of select="."/>
+    <xsl:text> </xsl:text><a class="link" href="?verb=ListIdentifiers&amp;metadataPrefix=oai_dc&amp;set={.}">Identifiers</a>
+    <xsl:text> </xsl:text><a class="link" href="?verb=ListRecords&amp;metadataPrefix=oai_dc&amp;set={.}">Records</a>
+  </td></tr>
+</xsl:template>
+
+
+
+<!-- oai resumptionToken -->
+
+<xsl:template match="oai:resumptionToken">
+   <p>There are more results.</p>
+   <table class="values">
+     <tr><td class="key">resumptionToken:</td>
+     <td class="value"><xsl:value-of select="."/>
+<xsl:text> </xsl:text>
+<a class="link" href="?verb={/oai:OAI-PMH/oai:request/@verb}&amp;resumptionToken={.}">Resume</a></td></tr>
+   </table>
+</xsl:template>
+
+<!-- unknown metadata format -->
+
+<xsl:template match="oai:metadata/*" priority='-100'>
+  <h3>Unknown Metadata Format</h3>
+  <div class="xmlSource">
+    <xsl:apply-templates select="." mode='xmlMarkup' />
+  </div>
+</xsl:template>
+
+<!-- oai_dc record -->
+
+<xsl:template match="oai_dc:dc"  xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" >
+  <div class="dcdata">
+    <h3>Dublin Core Metadata (oai_dc)</h3>
+    <table class="dcdata">
+      <xsl:apply-templates select="*" />
+    </table>
+  </div>
+</xsl:template>
+
+<xsl:template match="dc:title" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Title</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:creator" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Author or Creator</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:subject" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Subject and Keywords</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:description" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Description</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:publisher" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Publisher</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:contributor" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Other Contributor</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:date" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Date</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:type" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Resource Type</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:format" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Format</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:identifier" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Resource Identifier</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:source" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Source</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:language" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Language</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:relation" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Relation</td><td class="value">
+  <xsl:choose>
+    <xsl:when test='starts-with(.,"http" )'>
+      <xsl:choose>
+        <xsl:when test='string-length(.) &gt; 50'>
+          <a class="link" href="{.}">URL</a>
+          <i> URL not shown as it is very long.</i>
+        </xsl:when>
+        <xsl:otherwise>
+          <a href="{.}"><xsl:value-of select="."/></a>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:value-of select="."/>
+    </xsl:otherwise>
+  </xsl:choose>
+</td></tr></xsl:template>
+
+<xsl:template match="dc:coverage" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Coverage</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<xsl:template match="dc:rights" xmlns:dc="http://purl.org/dc/elements/1.1/">
+<tr><td class="key">Rights Management</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
+
+<!-- XML Pretty Maker -->
+
+<xsl:template match="node()" mode='xmlMarkup'>
+  <div class="xmlBlock">
+    &lt;<span class="xmlTagName"><xsl:value-of select='name(.)' /></span><xsl:apply-templates select="@*" mode='xmlMarkup'/>&gt;<xsl:apply-templates select="node()" mode='xmlMarkup' />&lt;/<span class="xmlTagName"><xsl:value-of select='name(.)' /></span>&gt;
+  </div>
+</xsl:template>
+
+<xsl:template match="text()" mode='xmlMarkup'><span class="xmlText"><xsl:value-of select='.' /></span></xsl:template>
+
+<xsl:template match="@*" mode='xmlMarkup'>
+  <xsl:text> </xsl:text><span class="xmlAttrName"><xsl:value-of select='name()' /></span>="<span class="xmlAttrValue"><xsl:value-of select='.' /></span>"
+</xsl:template>
+
+<xsl:template name="xmlstyle">
+.xmlSource {
+	font-size: 70%;
+	border: solid #c0c0a0 1px;
+	background-color: #ffffe0;
+	padding: 2em 2em 2em 0em;
+}
+.xmlBlock {
+	padding-left: 2em;
+}
+.xmlTagName {
+	color: #800000;
+	font-weight: bold;
+}
+.xmlAttrName {
+	font-weight: bold;
+}
+.xmlAttrValue {
+	color: #0000c0;
+}
+</xsl:template>
+
+</xsl:stylesheet>
+
Index: /gsdl/stable/web/style/preview-document.css
===================================================================
--- /gsdl/stable/web/style/preview-document.css	(revision 20131)
+++ /gsdl/stable/web/style/preview-document.css	(revision 20131)
@@ -0,0 +1,55 @@
+/* print document stylesheet for greenstone. */
+
+/* black text on white */
+body {
+  background: #ffffff;
+  color: #000000;
+}
+
+
+a { border: 0; }
+
+img.link { border: 0; }
+
+/* this contains everything - all the other divs */
+#page {
+  margin: 0 2em 0 2em;  
+}
+
+/* the collection image and home/help/prefs links at the top */
+div#banner, div.navbar, div.searchresults,div.heading_image,div.buttons,div.navarrowsbottom{
+  display:none;
+}
+
+ul.printmessage{
+  margin: 1em 0 1em 0;
+  padding:0;
+  color: blue;
+  font-family: sans-serif, arial, helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  list-style-type:none; 
+  text-decoration:underline;
+  width: 30%;
+}
+
+ul.printmessage li{
+  margin: .3em 0 .3em 0;
+  padding:0;
+  cursor:pointer;
+}
+
+
+table.v_list img.icon {
+   border: none;
+   padding:0;
+   margin:0;
+}
+
+table.v_list {
+ font-size: 16px;
+ font-family:arial, helvetica;
+}
+
+
+
Index: /gsdl/stable/web/style/print-document.css
===================================================================
--- /gsdl/stable/web/style/print-document.css	(revision 20131)
+++ /gsdl/stable/web/style/print-document.css	(revision 20131)
@@ -0,0 +1,10 @@
+/* print document stylesheet for greenstone. */
+
+@import "preview-document.css";
+
+ul.printmessage{
+  display:none; 
+}
+
+
+
Index: /gsdl/stable/web/style/style-print.css
===================================================================
--- /gsdl/stable/web/style/style-print.css	(revision 20131)
+++ /gsdl/stable/web/style/style-print.css	(revision 20131)
@@ -0,0 +1,97 @@
+/* printer stylesheet for greenstone. */
+
+/* black text on white */
+body {
+  background: #ffffff;
+  color: #000000;
+}
+
+/* a:visited { color: #666633; } */
+
+a { border: 0; }
+
+img.link { border: 0; }
+
+/* for unesco/human info etc logos on home page */
+img.logo {
+  border: 0;
+  float: right;
+  margin-left: 10px;
+}
+
+/* this contains everything - all the other divs */
+#page {
+/*  width: 537px; */
+  margin-left: 80px;
+  margin-right: 30px;
+}
+
+/* the collection image and home/help/prefs links at the top */
+#banner {
+  display: none;
+}
+
+/* blankiconbar */
+div.section p.bar {
+  text-align: center;
+}
+p.bar img {
+  text-align: center;
+  height: 17px;
+/* can't do this, it will stretch the "select a collection" text */
+/*  width: 90%; */
+}
+div.navbar {
+  display: none;
+}
+p.navbar {
+  text-align: center;
+  font-family: arial;
+  font-size: 10pt;
+  font-weight: bold;
+}
+span.navlink {
+  vertical-align: top;
+  background-image: url("/web/images/bg_off.png");
+  padding: 0 10px;
+}
+span.navlink_sel {
+  vertical-align: top;
+  background-image: url("/web/images/bg_selected.png");
+  padding: 0 10px;
+}
+span.navlink:hover {
+  background-image: url("/web/images/bg_on.png");
+}
+
+span.navlink a {
+  color: blue; /* for debugging... set to black */
+  text-decoration: none;
+}
+
+div.queryform {
+  text-align: center;
+}
+span.textselect { white-space: nowrap; }
+
+
+div.section p {
+  text-align: justify;
+/*  border: solid blue 2px; /* */
+}
+
+/* for a=d (document) */
+div.doc_buttons {
+  display: none;
+}
+
+/* for the home page - auto-generated _homeextra_ macro */
+table.collections {
+  width: 100%;
+  max-width: 800px;
+  text-align: center;
+  /* centres a block element for gecko and opera. (IE 5.5 needs parent
+   * text-align) */
+  margin-left:auto; margin-right:auto;
+}
+
Index: /gsdl/stable/web/style/style.css
===================================================================
--- /gsdl/stable/web/style/style.css	(revision 20131)
+++ /gsdl/stable/web/style/style.css	(revision 20131)
@@ -0,0 +1,329 @@
+/* default stylesheet for greenstone. */
+
+body {
+  background-color: #ffffff;
+}
+
+/* bg image set in style macro */
+body.bgimage { }
+
+a:link { color: #006666; } 
+
+a:hover { color: #cc9900; }
+
+a:visited { color: #666633; } 
+
+img.link { border: 0; }
+
+/* for unesco/human info etc logos on home page */
+img.logo {
+  border: 0;
+  float: right;
+  margin-left: 10px;
+}
+
+
+/* this contains everything - all the other divs */
+#page {
+  margin-left: 80px;
+  margin-right: 30px;
+}
+
+
+#banner {
+  margin: 0 0 5px 0;
+  padding:0;
+ 
+}
+
+/* this div contains the bannerlinks and bannertitle paragraphs */
+div.pageinfo {
+  float: right;
+  text-align: right;
+  padding: 0;
+  margin:0 0 3px 0;	
+  width: 50%;
+}
+
+/* home, help, preferences links */
+p.bannerlinks {
+  font-family: sans-serif, arial, helvetica;
+  font-size: 10pt;
+  font-weight: bold;
+  margin:0;
+  padding:0;
+}
+
+/* the title set by the receptionist based on the page action */
+p.bannertitle {
+  font-family: sans-serif, arial, helvetica;
+  font-size: 24px;
+  font-weight: bold;
+  margin: 10px 0 0 0;
+  text-transform: lowercase;
+  white-space: nowrap;
+  padding: 6px 2px 10px 0px;
+  background-repeat: repeat-y;
+  background-position: top right; 
+ }
+
+p.collectiontitle {
+  font-family: sans-serif, arial, helvetica;
+  font-size: 24px;
+  font-weight: bold;
+  white-space: nowrap;
+  padding: 8px 0px 12px 2px;
+  background-repeat: repeat-y;
+  background-position: top left; 
+  margin:0;
+}
+
+a.collectiontitle {
+  color: black;
+  text-decoration: none;
+}
+
+/* the image for the collection, shown in the banner */
+div.collectimage {
+  text-align: left;
+  float: left;
+  width: 45%;
+  padding:0;
+  margin:0;
+}
+/* make sure this is shown under the other divs (which may be floating) */
+div.bannerextra {
+   clear: both;
+}
+
+/* blankiconbar */
+div.section p.bar {
+  text-align: center;
+}
+
+
+
+/* bg image set in style macro */
+div.navbar {
+  min-width: 500px;
+  white-space: nowrap;
+  font-family: sans-serif, arial, helvetica;
+  font-size: 10pt;
+  font-weight: bold;
+  text-transform: lowercase;
+  border: 0;
+  width: 100%; /* for ns4 */
+}
+
+
+/* bg image set in style macro */
+div.divbar { /* for "select a collection" */
+  font-family: arial;
+  font-size: 10pt;
+  font-weight: bold;
+  border: 0;
+  width: 100%; /* for ns4 */
+}
+
+
+p.navbar { /* opt navbar text inside a divbar div */
+  text-align: center; 
+  margin: 0;
+}
+
+/* bg image set in style macro */
+a.navlink {
+  vertical-align: top; 
+  padding: 0 10px; 
+  color: black;
+  text-decoration: none;
+}
+
+/* bg image set in style macro */
+a.navlink_sel {
+  vertical-align: top;
+  padding: 0 10px;
+  color: black;
+  text-decoration: none;
+}
+
+a.navlink:visited {
+  color: black;
+}
+
+/* for the nav_ns4.dm macro only (for netscape4 support) */
+a.navlink_ns4 {
+  background-color: #e8d9b1;
+}
+
+a.navlink_sel_ns4 {
+  background-color: #96c19b;
+}
+
+span.highlight {
+  background: #ffff77;
+}
+
+/* content inside the pages */
+img.icon { border: 0; }
+
+span.textselect { 
+  white-space: nowrap;
+}
+
+span.textselect select { 
+  text-transform: lowercase;
+}
+
+div.document {
+ padding: .2em 0 0 0;
+ clear: both;
+}
+
+div.documenttext { clear: both; } /* come after any floating divs */
+
+ul#searchresults{
+  list-style-type: none;
+  margin: 0 0 .2em 0;
+  padding:0;
+  overflow: hidden;
+}
+
+ul#searchresults li{
+  margin: 0; 
+  padding: 2px 0 2px 0;
+  font-size: 11px;
+  font-weight: bold;	
+  width: 160px;
+  background-color:#f7e7c5;
+  text-align:center; 
+}
+ 
+li#nextresult{
+  float:right;
+}
+
+li#prevresult{
+  float:left;
+}
+
+
+ul#searchresults li a {
+  margin:0;	 
+  padding:0;
+  text-decoration: none;
+  color: black;
+}
+
+
+div.warning { /* eg expanding more than 10 sections in table of contents */
+}
+div.warning div.buttons { float: right; } /* continue button */
+
+div.heading_image {
+ float: left;
+
+ } /* optional cover image */
+
+div.heading_title {
+ font-size: 14pt;
+ } /* alternate to cover image */
+
+div.document div.buttons {
+   /* anything that holds buttons... toc_buttons but also continue button */
+   width: 100px; /* each button (inside its own div) can overflow this */
+}
+div#toc_buttons { /* expand/contract etc "buttons" */
+  clear: left; /* don't put next to another float on our left-hand side */
+  float: left;
+  margin: 0 15px 5px 0; 
+}
+
+div.button {
+  font-size: 11px;
+  font-weight: bold;
+  background: #f7e7c5;
+  margin: 1px;
+  border: 1px solid #eeddbb;
+  text-align: center;
+  vertical-align: middle;
+  width: 110px;
+}
+
+*>div.button { /* for other browsers - IE6 doesn't apply this */
+  height: auto;
+  width: auto;
+  min-width: 110px;
+}
+
+span.button {}
+span.button a { text-decoration: none; color: black; }
+span.button a:hover { /* IE6 doesn't do :hover for things that aren't <A> */
+  background: #eeddbb;
+}
+
+div.homebutton {
+  font-size: 11px;
+  font-weight: bold;
+  background: #f7e7c5;
+  margin: 1px;
+  border: 1px solid #eeddbb;
+  text-align: center;
+  vertical-align: middle;
+  width: 110px;
+  height: 30px;
+}
+
+div.section p {
+  text-align: justify;
+}
+
+/* for the home page - auto-generated _homeextra_ macro */
+table.collections {
+  width: 100%;
+  max-width: 800px;
+  text-align: center;
+  /* centres a block element for gecko and opera. (IE 5.5 needs parent
+   * text-align) */
+  margin-left:auto; margin-right:auto;
+}
+
+/* collections that have a logo should have a border around them */
+table.collections img {
+  border: 1px solid;
+}
+
+/* collector bar */
+table.wizardbar {
+   text-align: center;
+   vertical-align: middle;
+}
+		       
+td.wizardbargreen {
+   background-color: #96BE9C;
+}
+td.wizardbaryellow {
+   background-color: #EEE8AA;
+}
+td.wizardbargrey {
+   background-color: #D3D3D3;
+}
+
+table.wizardbar a {
+  color: black;
+  text-decoration: none;
+}
+
+table.wizardbar a:visited {
+  color: black;
+}
+
+
+span.date_list_year {
+  font-weight: bold;
+}
+span.date_list_month {
+  font-weight: bold;
+}
+
+
Index: /gsdl/stable/win32.mak
===================================================================
--- /gsdl/stable/win32.mak	(revision 20131)
+++ /gsdl/stable/win32.mak	(revision 20131)
@@ -0,0 +1,97 @@
+###########################################################################
+#
+# win32 makefile -- gsdl
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999  The New Zealand Digital Library Project
+#
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GSDLHOME = $(MAKEDIR)
+GSDL_VC4 = 0
+LOCAL_LIBRARY = 0
+APACHE_HTTPD = 0
+DEBUG = 0
+DLL = 0
+DLLDEBUG = 0
+USE_SQLITE = 1
+USE_MSSQL = 0
+USE_Z3950 = 0
+
+MDEFINES = /f win32.mak
+
+INSTALLDIRS = common-src build-src runtime-src 
+
+
+MAKECMD = $(MAKE) $(MDEFINES) GSDLHOME="$(GSDLHOME)"
+
+!IF $(GSDL_VC4)
+MAKECMD = $(MAKECMD) GSDL_VC4=1
+!ENDIF
+!IF $(LOCAL_LIBRARY)
+MAKECMD = $(MAKECMD) LOCAL_LIBRARY=1
+!ENDIF
+!IF $(APACHE_HTTPD)
+MAKECMD = $(MAKECMD) APACHE_HTTPD=1
+!ENDIF
+!IF $(DEBUG)
+MAKECMD = $(MAKECMD) DEBUG=1
+!ENDIF
+!IF $(DLL)
+MAKECMD = $(MAKECMD) DLL=1
+!ENDIF
+!IF $(DLLDEBUG)
+MAKECMD = $(MAKECMD) DLLDEBUG=1
+!ENDIF
+!IF $(USE_SQLITE)
+MAKECMD = $(MAKECMD) USE_SQLITE=1
+!ENDIF
+!IF $(USE_MSSQL)
+MAKECMD = $(MAKECMD) USE_MSSQL=1
+!ENDIF
+!IF $(USE_Z3950)
+MAKECMD = $(MAKECMD) USE_Z3950=1
+!ENDIF
+
+MAKECLEANCMD = $(MAKE) $(MDEFINES) GSDLHOME="$(GSDLHOME)" clean
+
+all: win32.mak $(INSTALLDIRS) 
+
+install: win32.mak $(INSTALLDIRS)
+
+clean:
+	cd common-src
+	$(MAKECLEANCMD)
+	cd "$(GSDLHOME)"
+	cd build-src
+	$(MAKECLEANCMD)
+	cd "$(GSDLHOME)"
+	cd runtime-src
+	$(MAKECLEANCMD)
+	cd "$(GSDLHOME)"
+
+$(INSTALLDIRS): FORCE
+	cd "$@"
+	$(MAKECMD)
+	$(MAKECMD) install
+	cd "$(GSDLHOME)"
+
+FORCE:
+
Index: /gsdl/stable/win32cfg.h
===================================================================
--- /gsdl/stable/win32cfg.h	(revision 20131)
+++ /gsdl/stable/win32cfg.h	(revision 20131)
@@ -0,0 +1,169 @@
+/* config.h.  Generated automatically by configure.  */
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+/* #undef _ALL_SOURCE */
+#endif
+
+/* Define if using alloca.c.  */
+/* #undef C_ALLOCA */
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+   This function is required for alloca.c support on those systems.  */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define if you have alloca, as a function or macro.  */
+#define HAVE_ALLOCA 1
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
+/* #define HAVE_ALLOCA_H 1 */
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+/* #undef HAVE_DOPRNT */
+
+/* Define if you have the vprintf function.  */
+#define HAVE_VPRINTF 1
+
+/* Define if on MINIX.  */
+/* #undef _MINIX */
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+/* #undef off_t */
+
+/* Define if the system does not provide POSIX.1 features except
+   with this defined.  */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define if you need to in order for stat and other things to work.  */
+/* #undef _POSIX_SOURCE */
+
+/* Define as the return type of signal handlers (int or void).  */
+#define RETSIGTYPE void
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+/* #define TIME_WITH_SYS_TIME 1 */
+
+/* Define if your <sys/time.h> declares struct tm.  */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define to the name of the distribution.  */
+#define PACKAGE "mg"
+
+/* Define to the version of the distribution.  */
+#define VERSION "1.2"
+
+/* Define to 1 if you have the valloc function.  */
+/* #define HAVE_VALLOC 1 */
+
+/* Define to 1 if ANSI function prototypes are usable.  */
+#define PROTOTYPES 1
+
+ 
+/* Define to 1 for better use of the debugging malloc library.  See
+   site ftp.antaire.com in antaire/src, file dmalloc/dmalloc.tar.gz.  */
+/* #undef WITH_DMALLOC */
+
+ 
+/* Define to 1 if GNU regex should be used instead of GNU rx.  */
+/* #undef WITH_REGEX */
+
+/* Some braindead header files do not have the requ'd function declarations */
+#define HAVE_FGETC_DECL 1
+#define HAVE_FREAD_DECL 1
+
+/* See if have this field in the prstatus_t structure */
+/* It stores the size of the process heap */
+/* #define HAVE_PR_BRKSIZE 1 */
+
+/* Define if you have the ftime function.  */
+/* #undef HAVE_FTIME */
+
+/* Define if you have the getpagesize function.  */
+/* #undef HAVE_GETPAGESIZE */
+
+/* Define if you have the getrusage function.  */
+/* #undef HAVE_GETRUSAGE */
+
+/* Define if you have the mallinfo function.  */
+/* #undef HAVE_MALLINFO */
+
+/* Define if you have the select function.  */
+#define HAVE_SELECT 1
+
+/* Define if you have the setbuffer function.  */
+/* #undef HAVE_SETBUFFER */
+
+/* Define if you have the strerror function.  */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strftime function.  */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the strstr function.  */
+#define HAVE_STRSTR 1
+
+/* Define if you have the strtol function.  */
+#define HAVE_STRTOL 1
+
+/* Define if you have the times function.  */
+/* #define HAVE_TIMES 1 */
+
+/* Define if you have the valloc function.  */
+/* #define HAVE_VALLOC 1 */
+
+/* Define if you have the <dirent.h> header file.  */
+/* #define HAVE_DIRENT_H 1 */
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <limits.h> header file.  */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <memory.h> header file.  */
+#define HAVE_MEMORY_H 1
+
+/* Define if you have the <ndir.h> header file.  */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <string.h> header file.  */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/dir.h> header file.  */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/ndir.h> header file.  */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <sys/procfs.h> header file.  */
+/* #define HAVE_SYS_PROCFS_H 1 */
+
+/* Define if you have the <sys/time.h> header file.  */
+/* #define HAVE_SYS_TIME_H 1 */
+
+/* Define if you have the <unistd.h> header file.  */
+/* #define HAVE_UNISTD_H 1 */
+
+/* Define if you have the m library (-lm).  */
+#define HAVE_LIBM 1
